ZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9BY2NlbFRhYmxlLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vQWNjZWxUYWJsZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVjODUwYTgKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vQWNjZWxUYWJsZS5oCkBAIC0wLDAgKzEsMzczIEBACisvLz09LSBpbmNsdWRlL2xsdm0vQ29kZUdlbi9BY2NlbFRhYmxlLmggLSBBY2NlbGVyYXRvciBUYWJsZXMgLS0tLS0qLSBDKysgLSotPT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBjb250YWlucyBzdXBwb3J0IGZvciB3cml0aW5nIGFjY2VsZXJhdG9yIHRhYmxlcy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9EV0FSRkFDQ0VMVEFCTEVfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fRFdBUkZBQ0NFTFRBQkxFX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0FycmF5UmVmLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TdHJpbmdNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TdHJpbmdSZWYuaCIKKyNpbmNsdWRlICJsbHZtL0JpbmFyeUZvcm1hdC9Ed2FyZi5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9ESUUuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vRHdhcmZTdHJpbmdQb29sRW50cnkuaCIKKyNpbmNsdWRlICJsbHZtL01DL01DU3ltYm9sLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0FsbG9jYXRvci5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9ESkIuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvRGVidWcuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvRm9ybWF0LmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L3Jhd19vc3RyZWFtLmgiCisjaW5jbHVkZSA8Y3N0ZGRlZj4KKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworLy8vIFRoZSBEV0FSRiBhbmQgQXBwbGUgYWNjZWxlcmF0b3IgdGFibGVzIGFyZSBhbiBpbmRpcmVjdCBoYXNoIHRhYmxlIG9wdGltaXplZAorLy8vIGZvciBudWxsIGxvb2t1cCByYXRoZXIgdGhhbiBhY2Nlc3MgdG8ga25vd24gZGF0YS4gVGhlIEFwcGxlIGFjY2VsZXJhdG9yCisvLy8gdGFibGVzIGFyZSBhIHByZWN1cnNvciBvZiB0aGUgbmV3ZXIgRFdBUkYgdjUgYWNjZWxlcmF0b3IgdGFibGVzLiBCb3RoCisvLy8gZm9ybWF0cyBzaGFyZSBjb21tb24gZGVzaWduIGlkZWFzLgorLy8vCisvLy8gVGhlIEFwcGxlIGFjY2VsZXJhdG9yIHRhYmxlIGFyZSBvdXRwdXQgaW50byBhbiBvbi1kaXNrIGZvcm1hdCB0aGF0IGxvb2tzCisvLy8gbGlrZSB0aGlzOgorLy8vCisvLy8gLi0tLS0tLS0tLS0tLS0tLS0tLS4KKy8vLyB8ICBIRUFERVIgICAgICAgICAgfAorLy8vIHwtLS0tLS0tLS0tLS0tLS0tLS18CisvLy8gfCAgQlVDS0VUUyAgICAgICAgIHwKKy8vLyB8LS0tLS0tLS0tLS0tLS0tLS0tfAorLy8vIHwgIEhBU0hFUyAgICAgICAgICB8CisvLy8gfC0tLS0tLS0tLS0tLS0tLS0tLXwKKy8vLyB8ICBPRkZTRVRTICAgICAgICAgfAorLy8vIHwtLS0tLS0tLS0tLS0tLS0tLS18CisvLy8gfCAgREFUQSAgICAgICAgICAgIHwKKy8vLyBgLS0tLS0tLS0tLS0tLS0tLS0tJworLy8vCisvLy8gVGhlIGhlYWRlciBjb250YWlucyBhIG1hZ2ljIG51bWJlciwgdmVyc2lvbiwgdHlwZSBvZiBoYXNoIGZ1bmN0aW9uLAorLy8vIHRoZSBudW1iZXIgb2YgYnVja2V0cywgdG90YWwgbnVtYmVyIG9mIGhhc2hlcywgYW5kIHJvb20gZm9yIGEgc3BlY2lhbCBzdHJ1Y3QKKy8vLyBvZiBkYXRhIGFuZCB0aGUgbGVuZ3RoIG9mIHRoYXQgc3RydWN0LgorLy8vCisvLy8gVGhlIGJ1Y2tldHMgY29udGFpbiBhbiBpbmRleCAoZS5nLiA2KSBpbnRvIHRoZSBoYXNoZXMgYXJyYXkuIFRoZSBoYXNoZXMKKy8vLyBzZWN0aW9uIGNvbnRhaW5zIGFsbCBvZiB0aGUgMzItYml0IGhhc2ggdmFsdWVzIGluIGNvbnRpZ3VvdXMgbWVtb3J5LCBhbmQgdGhlCisvLy8gb2Zmc2V0cyBjb250YWluIHRoZSBvZmZzZXQgaW50byB0aGUgZGF0YSBhcmVhIGZvciB0aGUgcGFydGljdWxhciBoYXNoLgorLy8vCisvLy8gRm9yIGEgbG9va3VwIGV4YW1wbGUsIHdlIGNvdWxkIGhhc2ggYSBmdW5jdGlvbiBuYW1lIGFuZCB0YWtlIGl0IG1vZHVsbyB0aGUKKy8vLyBudW1iZXIgb2YgYnVja2V0cyBnaXZpbmcgdXMgb3VyIGJ1Y2tldC4gRnJvbSB0aGVyZSB3ZSB0YWtlIHRoZSBidWNrZXQgdmFsdWUKKy8vLyBhcyBhbiBpbmRleCBpbnRvIHRoZSBoYXNoZXMgdGFibGUgYW5kIGxvb2sgYXQgZWFjaCBzdWNjZXNzaXZlIGhhc2ggYXMgbG9uZworLy8vIGFzIHRoZSBoYXNoIHZhbHVlIGlzIHN0aWxsIHRoZSBzYW1lIG1vZHVsbyByZXN1bHQgKGJ1Y2tldCB2YWx1ZSkgYXMgZWFybGllci4KKy8vLyBJZiB3ZSBoYXZlIGEgbWF0Y2ggd2UgbG9vayBhdCB0aGF0IHNhbWUgZW50cnkgaW4gdGhlIG9mZnNldHMgdGFibGUgYW5kIGdyYWIKKy8vLyB0aGUgb2Zmc2V0IGluIHRoZSBkYXRhIGZvciBvdXIgZmluYWwgbWF0Y2guCisvLy8KKy8vLyBUaGUgRFdBUkYgdjUgYWNjZWxlcmF0b3IgdGFibGUgY29uc2lzdHMgb2YgemVybyBvciBtb3JlIG5hbWUgaW5kaWNlcyB0aGF0CisvLy8gYXJlIG91dHB1dCBpbnRvIGFuIG9uLWRpc2sgZm9ybWF0IHRoYXQgbG9va3MgbGlrZSB0aGlzOgorLy8vCisvLy8gLi0tLS0tLS0tLS0tLS0tLS0tLS4KKy8vLyB8ICBIRUFERVIgICAgICAgICAgfAorLy8vIHwtLS0tLS0tLS0tLS0tLS0tLS18CisvLy8gfCAgQ1UgTElTVCAgICAgICAgIHwKKy8vLyB8LS0tLS0tLS0tLS0tLS0tLS0tfAorLy8vIHwgIExPQ0FMIFRVIExJU1QgICB8CisvLy8gfC0tLS0tLS0tLS0tLS0tLS0tLXwKKy8vLyB8ICBGT1JFSUdOIFRVIExJU1QgfAorLy8vIHwtLS0tLS0tLS0tLS0tLS0tLS18CisvLy8gfCAgSEFTSCBUQUJMRSAgICAgIHwKKy8vLyB8LS0tLS0tLS0tLS0tLS0tLS0tfAorLy8vIHwgIE5BTUUgVEFCTEUgICAgICB8CisvLy8gfC0tLS0tLS0tLS0tLS0tLS0tLXwKKy8vLyB8ICBBQkJSRVYgVEFCTEUgICAgfAorLy8vIHwtLS0tLS0tLS0tLS0tLS0tLS18CisvLy8gfCAgRU5UUlkgUE9PTCAgICAgIHwKKy8vLyBgLS0tLS0tLS0tLS0tLS0tLS0tJworLy8vCisvLy8gRm9yIHRoZSBmdWxsIGRvY3VtZW50YXRpb24gcGxlYXNlIHJlZmVyIHRvIHRoZSBEV0FSRiA1IHN0YW5kYXJkLgorLy8vCisvLy8KKy8vLyBUaGlzIGZpbGUgZGVmaW5lcyB0aGUgY2xhc3MgdGVtcGxhdGUgQWNjZWxUYWJsZSwgd2hpY2ggaXMgcmVwcmVzZW50cyBhbgorLy8vIGFic3RyYWN0IHZpZXcgb2YgYW4gQWNjZWxlcmF0b3IgdGFibGUsIHdpdGhvdXQgYW55IG5vdGlvbiBvZiBhbiBvbi1kaXNrCisvLy8gbGF5b3V0LiBUaGlzIGNsYXNzIGlzIHBhcmFtZXRlcml6ZWQgYnkgYW4gZW50cnkgdHlwZSwgd2hpY2ggc2hvdWxkIGRlcml2ZQorLy8vIGZyb20gQWNjZWxUYWJsZURhdGEuIFRoaXMgaXMgdGhlIHR5cGUgb2YgaW5kaXZpZHVhbCBlbnRyaWVzIGluIHRoZSB0YWJsZSwKKy8vLyBhbmQgaXQgc2hvdWxkIHN0b3JlIHRoZSBkYXRhIG5lY2Vzc2FyeSB0byBlbWl0IHRoZW0uIEFwcGxlQWNjZWxUYWJsZURhdGEgaXMKKy8vLyB0aGUgYmFzZSBjbGFzcyBmb3IgQXBwbGUgQWNjZWxlcmF0b3IgVGFibGUgZW50cmllcywgd2hpY2ggaGF2ZSBhIHVuaWZvcm0KKy8vLyBzdHJ1Y3R1cmUgYmFzZWQgb24gYSBzZXF1ZW5jZSBvZiBBdG9tcy4gVGhlcmUgYXJlIGRpZmZlcmVudCBzdWItY2xhc3NlcworLy8vIGRlcml2ZWQgZnJvbSBBcHBsZUFjY2VsVGFibGUsIHdoaWNoIGRpZmZlciBpbiB0aGUgc2V0IG9mIEF0b21zIGFuZCBob3cgdGhleQorLy8vIG9idGFpbiB0aGVpciB2YWx1ZXMuCisvLy8KKy8vLyBBbiBBcHBsZSBBY2NlbGVyYXRvciBUYWJsZSBjYW4gYmUgc2VyaWFsaXplZCBieSBjYWxsaW5nIGVtaXRBcHBsZUFjY2VsVGFibGUKKy8vLyBmdW5jdGlvbi4KKy8vLworLy8vIFRPRE86IEFkZCBEV0FSRiB2NSBlbWlzc2lvbiBjb2RlLgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIEFzbVByaW50ZXI7CisKKy8vLyBJbnRlcmZhY2Ugd2hpY2ggdGhlIGRpZmZlcmVudCB0eXBlcyBvZiBhY2NlbGVyYXRvciB0YWJsZSBkYXRhIGhhdmUgdG8KKy8vLyBjb25mb3JtLiBJdCBzZXJ2ZXMgYXMgYSBiYXNlIGNsYXNzIGZvciBkaWZmZXJlbnQgdmFsdWVzIG9mIHRoZSB0ZW1wbGF0ZQorLy8vIGFyZ3VtZW50IG9mIHRoZSBBY2NlbFRhYmxlIGNsYXNzIHRlbXBsYXRlLgorY2xhc3MgQWNjZWxUYWJsZURhdGEgeworcHVibGljOgorICB2aXJ0dWFsIH5BY2NlbFRhYmxlRGF0YSgpID0gZGVmYXVsdDsKKworICBib29sIG9wZXJhdG9yPChjb25zdCBBY2NlbFRhYmxlRGF0YSAmT3RoZXIpIGNvbnN0IHsKKyAgICByZXR1cm4gb3JkZXIoKSA8IE90aGVyLm9yZGVyKCk7CisgIH0KKworICAvLyBTdWJjbGFzc2VzIHNob3VsZCBpbXBsZW1lbnQ6CisgIC8vIHN0YXRpYyB1aW50MzJfdCBoYXNoKFN0cmluZ1JlZiBOYW1lKTsKKworI2lmbmRlZiBOREVCVUcKKyAgdmlydHVhbCB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUykgY29uc3QgPSAwOworI2VuZGlmCitwcm90ZWN0ZWQ6CisgIHZpcnR1YWwgdWludDY0X3Qgb3JkZXIoKSBjb25zdCA9IDA7Cit9OworCisvLy8gQSBiYXNlIGNsYXNzIGhvbGRpbmcgbm9uLXRlbXBsYXRlLWRlcGVuZGFudCBmdW5jdGlvbmFsaXR5IG9mIHRoZSBBY2NlbFRhYmxlCisvLy8gY2xhc3MuIENsaWVudHMgc2hvdWxkIG5vdCB1c2UgdGhpcyBjbGFzcyBkaXJlY3RseSBidXQgcmF0aGVyIGluc3RhbnRpYXRlCisvLy8gQWNjZWxUYWJsZSB3aXRoIGEgdHlwZSBkZXJpdmVkIGZyb20gQWNjZWxUYWJsZURhdGEuCitjbGFzcyBBY2NlbFRhYmxlQmFzZSB7CitwdWJsaWM6CisgIHVzaW5nIEhhc2hGbiA9IHVpbnQzMl90KFN0cmluZ1JlZik7CisKKyAgLy8vIFJlcHJlc2VudHMgYSBncm91cCBvZiBlbnRyaWVzIHdpdGggaWRlbnRpY2FsIG5hbWUgKGFuZCBoZW5jZSwgaGFzaCB2YWx1ZSkuCisgIHN0cnVjdCBIYXNoRGF0YSB7CisgICAgRHdhcmZTdHJpbmdQb29sRW50cnlSZWYgTmFtZTsKKyAgICB1aW50MzJfdCBIYXNoVmFsdWU7CisgICAgc3RkOjp2ZWN0b3I8QWNjZWxUYWJsZURhdGEgKj4gVmFsdWVzOworICAgIE1DU3ltYm9sICpTeW07CisKKyAgICBIYXNoRGF0YShEd2FyZlN0cmluZ1Bvb2xFbnRyeVJlZiBOYW1lLCBIYXNoRm4gKkhhc2gpCisgICAgICAgIDogTmFtZShOYW1lKSwgSGFzaFZhbHVlKEhhc2goTmFtZS5nZXRTdHJpbmcoKSkpIHt9CisKKyNpZm5kZWYgTkRFQlVHCisgICAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MpIGNvbnN0OworICAgIHZvaWQgZHVtcCgpIGNvbnN0IHsgcHJpbnQoZGJncygpKTsgfQorI2VuZGlmCisgIH07CisgIHVzaW5nIEhhc2hMaXN0ID0gc3RkOjp2ZWN0b3I8SGFzaERhdGEgKj47CisgIHVzaW5nIEJ1Y2tldExpc3QgPSBzdGQ6OnZlY3RvcjxIYXNoTGlzdD47CisKK3Byb3RlY3RlZDoKKyAgLy8vIEFsbG9jYXRvciBmb3IgSGFzaERhdGEgYW5kIFZhbHVlcy4KKyAgQnVtcFB0ckFsbG9jYXRvciBBbGxvY2F0b3I7CisKKyAgdXNpbmcgU3RyaW5nRW50cmllcyA9IFN0cmluZ01hcDxIYXNoRGF0YSwgQnVtcFB0ckFsbG9jYXRvciAmPjsKKyAgU3RyaW5nRW50cmllcyBFbnRyaWVzOworCisgIEhhc2hGbiAqSGFzaDsKKyAgdWludDMyX3QgQnVja2V0Q291bnQ7CisgIHVpbnQzMl90IFVuaXF1ZUhhc2hDb3VudDsKKworICBIYXNoTGlzdCBIYXNoZXM7CisgIEJ1Y2tldExpc3QgQnVja2V0czsKKworICB2b2lkIGNvbXB1dGVCdWNrZXRDb3VudCgpOworCisgIEFjY2VsVGFibGVCYXNlKEhhc2hGbiAqSGFzaCkgOiBFbnRyaWVzKEFsbG9jYXRvciksIEhhc2goSGFzaCkge30KKworcHVibGljOgorICB2b2lkIGZpbmFsaXplKEFzbVByaW50ZXIgKkFzbSwgU3RyaW5nUmVmIFByZWZpeCk7CisgIEFycmF5UmVmPEhhc2hMaXN0PiBnZXRCdWNrZXRzKCkgY29uc3QgeyByZXR1cm4gQnVja2V0czsgfQorICB1aW50MzJfdCBnZXRCdWNrZXRDb3VudCgpIGNvbnN0IHsgcmV0dXJuIEJ1Y2tldENvdW50OyB9CisgIHVpbnQzMl90IGdldFVuaXF1ZUhhc2hDb3VudCgpIGNvbnN0IHsgcmV0dXJuIFVuaXF1ZUhhc2hDb3VudDsgfQorICB1aW50MzJfdCBnZXRVbmlxdWVOYW1lQ291bnQoKSBjb25zdCB7IHJldHVybiBFbnRyaWVzLnNpemUoKTsgfQorCisjaWZuZGVmIE5ERUJVRworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUykgY29uc3Q7CisgIHZvaWQgZHVtcCgpIGNvbnN0IHsgcHJpbnQoZGJncygpKTsgfQorI2VuZGlmCisKKyAgQWNjZWxUYWJsZUJhc2UoY29uc3QgQWNjZWxUYWJsZUJhc2UgJikgPSBkZWxldGU7CisgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IEFjY2VsVGFibGVCYXNlICYpID0gZGVsZXRlOworfTsKKworLy8vIFRoaXMgY2xhc3MgaG9sZHMgYW4gYWJzdHJhY3QgcmVwcmVzZW50YXRpb24gb2YgYW4gQWNjZWxlcmF0b3IgVGFibGUsCisvLy8gY29uc2lzdGluZyBvZiBhIHNlcXVlbmNlIG9mIGJ1Y2tldHMsIGVhY2ggYnVja2V0IGNvbnRhaW5pbnQgYSBzZXF1ZW5jZSBvZgorLy8vIEhhc2hEYXRhIGVudHJpZXMuIFRoZSBjbGFzcyBpcyBwYXJhbWV0ZXJpemVkIGJ5IHRoZSB0eXBlIG9mIGVudHJpZXMgaXQKKy8vLyBob2xkcy4gVGhlIHR5cGUgdGVtcGxhdGUgcGFyYW1ldGVyIGFsc28gZGVmaW5lcyB0aGUgaGFzaCBmdW5jdGlvbiB0byB1c2UgZm9yCisvLy8gaGFzaGluZyBuYW1lcy4KK3RlbXBsYXRlIDx0eXBlbmFtZSBEYXRhVD4gY2xhc3MgQWNjZWxUYWJsZSA6IHB1YmxpYyBBY2NlbFRhYmxlQmFzZSB7CitwdWJsaWM6CisgIEFjY2VsVGFibGUoKSA6IEFjY2VsVGFibGVCYXNlKERhdGFUOjpoYXNoKSB7fQorCisgIHRlbXBsYXRlIDx0eXBlbmFtZS4uLiBUeXBlcz4KKyAgdm9pZCBhZGROYW1lKER3YXJmU3RyaW5nUG9vbEVudHJ5UmVmIE5hbWUsIFR5cGVzICYmLi4uIEFyZ3MpOworfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIEFjY2VsVGFibGVEYXRhVD4KK3RlbXBsYXRlIDx0eXBlbmFtZS4uLiBUeXBlcz4KK3ZvaWQgQWNjZWxUYWJsZTxBY2NlbFRhYmxlRGF0YVQ+OjphZGROYW1lKER3YXJmU3RyaW5nUG9vbEVudHJ5UmVmIE5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlcyAmJi4uLiBBcmdzKSB7CisgIGFzc2VydChCdWNrZXRzLmVtcHR5KCkgJiYgIkFscmVhZHkgZmluYWxpemVkISIpOworICAvLyBJZiB0aGUgc3RyaW5nIGlzIGluIHRoZSBsaXN0IGFscmVhZHkgdGhlbiBhZGQgdGhpcyBkaWUgdG8gdGhlIGxpc3QKKyAgLy8gb3RoZXJ3aXNlIGFkZCBhIG5ldyBvbmUuCisgIGF1dG8gSXRlciA9IEVudHJpZXMudHJ5X2VtcGxhY2UoTmFtZS5nZXRTdHJpbmcoKSwgTmFtZSwgSGFzaCkuZmlyc3Q7CisgIGFzc2VydChJdGVyLT5zZWNvbmQuTmFtZSA9PSBOYW1lKTsKKyAgSXRlci0+c2Vjb25kLlZhbHVlcy5wdXNoX2JhY2soCisgICAgICBuZXcgKEFsbG9jYXRvcikgQWNjZWxUYWJsZURhdGFUKHN0ZDo6Zm9yd2FyZDxUeXBlcz4oQXJncykuLi4pKTsKK30KKworLy8vIEEgYmFzZSBjbGFzcyBmb3IgZGlmZmVyZW50IGltcGxlbWVudGF0aW9ucyBvZiBEYXRhIGNsYXNzZXMgZm9yIEFwcGxlCisvLy8gQWNjZWxlcmF0b3IgVGFibGVzLiBUaGUgY29sdW1ucyBpbiB0aGUgdGFibGUgYXJlIGRlZmluZWQgYnkgdGhlIHN0YXRpYyBBdG9tcworLy8vIHZhcmlhYmxlIGRlZmluZWQgb24gdGhlIHN1YmNsYXNzZXMuCitjbGFzcyBBcHBsZUFjY2VsVGFibGVEYXRhIDogcHVibGljIEFjY2VsVGFibGVEYXRhIHsKK3B1YmxpYzoKKyAgLy8vIEFuIEF0b20gZGVmaW5lcyB0aGUgZm9ybSBvZiB0aGUgZGF0YSBpbiBhbiBBcHBsZSBhY2NlbGVyYXRvciB0YWJsZS4KKyAgLy8vIENvbmNlcHR1YWxseSBpdCBpcyBhIGNvbHVtbiBpbiB0aGUgYWNjZWxlcmF0b3IgY29uc2lzdGluZyBvZiBhIHR5cGUgYW5kIGEKKyAgLy8vIHNwZWNpZmljYXRpb24gb2YgdGhlIGZvcm0gb2YgaXRzIGRhdGEuCisgIHN0cnVjdCBBdG9tIHsKKyAgICAvLy8gQXRvbSBUeXBlLgorICAgIGNvbnN0IHVpbnQxNl90IFR5cGU7CisgICAgLy8vIERXQVJGIEZvcm0uCisgICAgY29uc3QgdWludDE2X3QgRm9ybTsKKworICAgIGNvbnN0ZXhwciBBdG9tKHVpbnQxNl90IFR5cGUsIHVpbnQxNl90IEZvcm0pIDogVHlwZShUeXBlKSwgRm9ybShGb3JtKSB7fQorCisjaWZuZGVmIE5ERUJVRworICAgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk9TKSBjb25zdDsKKyAgICB2b2lkIGR1bXAoKSBjb25zdCB7IHByaW50KGRiZ3MoKSk7IH0KKyNlbmRpZgorICB9OworICAvLyBTdWJjbGFzc2VzIHNob3VsZCBkZWZpbmU6CisgIC8vIHN0YXRpYyBjb25zdGV4cHIgQXRvbSBBdG9tc1tdOworCisgIHZpcnR1YWwgdm9pZCBlbWl0KEFzbVByaW50ZXIgKkFzbSkgY29uc3QgPSAwOworCisgIHN0YXRpYyB1aW50MzJfdCBoYXNoKFN0cmluZ1JlZiBCdWZmZXIpIHsgcmV0dXJuIGRqYkhhc2goQnVmZmVyKTsgfQorfTsKKwordm9pZCBlbWl0QXBwbGVBY2NlbFRhYmxlSW1wbChBc21QcmludGVyICpBc20sIEFjY2VsVGFibGVCYXNlICZDb250ZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUmVmIFByZWZpeCwgY29uc3QgTUNTeW1ib2wgKlNlY0JlZ2luLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjxBcHBsZUFjY2VsVGFibGVEYXRhOjpBdG9tPiBBdG9tcyk7CisKKy8vLyBFbWl0IGFuIEFwcGxlIEFjY2VsZXJhdG9yIFRhYmxlIGNvbnNpc3Rpbmcgb2YgZW50cmllcyBpbiB0aGUgc3BlY2lmaWVkCisvLy8gQWNjZWxUYWJsZS4gVGhlIERhdGFUIHRlbXBsYXRlIHBhcmFtZXRlciBzaG91bGQgYmUgZGVyaXZlZCBmcm9tCisvLy8gQXBwbGVBY2NlbFRhYmxlRGF0YS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBEYXRhVD4KK3ZvaWQgZW1pdEFwcGxlQWNjZWxUYWJsZShBc21QcmludGVyICpBc20sIEFjY2VsVGFibGU8RGF0YVQ+ICZDb250ZW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdSZWYgUHJlZml4LCBjb25zdCBNQ1N5bWJvbCAqU2VjQmVnaW4pIHsKKyAgc3RhdGljX2Fzc2VydChzdGQ6OmlzX2NvbnZlcnRpYmxlPERhdGFUICosIEFwcGxlQWNjZWxUYWJsZURhdGEgKj46OnZhbHVlLCAiIik7CisgIGVtaXRBcHBsZUFjY2VsVGFibGVJbXBsKEFzbSwgQ29udGVudHMsIFByZWZpeCwgU2VjQmVnaW4sIERhdGFUOjpBdG9tcyk7Cit9CisKKy8vLyBBY2NlbGVyYXRvciB0YWJsZSBkYXRhIGltcGxlbWVudGF0aW9uIGZvciBzaW1wbGUgQXBwbGUgYWNjZWxlcmF0b3IgdGFibGVzCisvLy8gd2l0aCBqdXN0IGEgRElFIHJlZmVyZW5jZS4KK2NsYXNzIEFwcGxlQWNjZWxUYWJsZU9mZnNldERhdGEgOiBwdWJsaWMgQXBwbGVBY2NlbFRhYmxlRGF0YSB7CitwdWJsaWM6CisgIEFwcGxlQWNjZWxUYWJsZU9mZnNldERhdGEoY29uc3QgRElFICpEKSA6IERpZShEKSB7fQorCisgIHZvaWQgZW1pdChBc21QcmludGVyICpBc20pIGNvbnN0IG92ZXJyaWRlOworCisjaWZuZGVmIF9NU0NfVkVSCisgIC8vIFRoZSBsaW5lIGJlbG93IGlzIHJlamVjdGVkIGJ5IG9sZGVyIHZlcnNpb25zIChUQkQpIG9mIE1TVkMuCisgIHN0YXRpYyBjb25zdGV4cHIgQXRvbSBBdG9tc1tdID0geworICAgICAgQXRvbShkd2FyZjo6RFdfQVRPTV9kaWVfb2Zmc2V0LCBkd2FyZjo6RFdfRk9STV9kYXRhNCl9OworI2Vsc2UKKyAgLy8gRklYTUU6IEVyYXNlIHRoaXMgcGF0aCBvbmNlIHRoZSBtaW5pbXVtIE1TQ1YgdmVyc2lvbiBoYXMgYmVlbiBidW1wZWQuCisgIHN0YXRpYyBjb25zdCBTbWFsbFZlY3RvcjxBdG9tLCA0PiBBdG9tczsKKyNlbmRpZgorCisjaWZuZGVmIE5ERUJVRworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUykgY29uc3Qgb3ZlcnJpZGU7CisjZW5kaWYKK3Byb3RlY3RlZDoKKyAgdWludDY0X3Qgb3JkZXIoKSBjb25zdCBvdmVycmlkZSB7IHJldHVybiBEaWUtPmdldE9mZnNldCgpOyB9CisKKyAgY29uc3QgRElFICpEaWU7Cit9OworCisvLy8gQWNjZWxlcmF0b3IgdGFibGUgZGF0YSBpbXBsZW1lbnRhdGlvbiBmb3IgQXBwbGUgdHlwZSBhY2NlbGVyYXRvciB0YWJsZXMuCitjbGFzcyBBcHBsZUFjY2VsVGFibGVUeXBlRGF0YSA6IHB1YmxpYyBBcHBsZUFjY2VsVGFibGVPZmZzZXREYXRhIHsKK3B1YmxpYzoKKyAgQXBwbGVBY2NlbFRhYmxlVHlwZURhdGEoY29uc3QgRElFICpEKSA6IEFwcGxlQWNjZWxUYWJsZU9mZnNldERhdGEoRCkge30KKworICB2b2lkIGVtaXQoQXNtUHJpbnRlciAqQXNtKSBjb25zdCBvdmVycmlkZTsKKworI2lmbmRlZiBfTVNDX1ZFUgorICAvLyBUaGUgbGluZSBiZWxvdyBpcyByZWplY3RlZCBieSBvbGRlciB2ZXJzaW9ucyAoVEJEKSBvZiBNU1ZDLgorICBzdGF0aWMgY29uc3RleHByIEF0b20gQXRvbXNbXSA9IHsKKyAgICAgIEF0b20oZHdhcmY6OkRXX0FUT01fZGllX29mZnNldCwgZHdhcmY6OkRXX0ZPUk1fZGF0YTQpLAorICAgICAgQXRvbShkd2FyZjo6RFdfQVRPTV9kaWVfdGFnLCBkd2FyZjo6RFdfRk9STV9kYXRhMiksCisgICAgICBBdG9tKGR3YXJmOjpEV19BVE9NX3R5cGVfZmxhZ3MsIGR3YXJmOjpEV19GT1JNX2RhdGExKX07CisjZWxzZQorICAvLyBGSVhNRTogRXJhc2UgdGhpcyBwYXRoIG9uY2UgdGhlIG1pbmltdW0gTVNDViB2ZXJzaW9uIGhhcyBiZWVuIGJ1bXBlZC4KKyAgc3RhdGljIGNvbnN0IFNtYWxsVmVjdG9yPEF0b20sIDQ+IEF0b21zOworI2VuZGlmCisKKyNpZm5kZWYgTkRFQlVHCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk9TKSBjb25zdCBvdmVycmlkZTsKKyNlbmRpZgorfTsKKworLy8vIEFjY2VsZXJhdG9yIHRhYmxlIGRhdGEgaW1wbGVtZW50YXRpb24gZm9yIHNpbXBsZSBBcHBsZSBhY2NlbGVyYXRvciB0YWJsZXMKKy8vLyB3aXRoIGEgRElFIG9mZnNldCBidXQgbm8gYWN0dWFsIERJRSBwb2ludGVyLgorY2xhc3MgQXBwbGVBY2NlbFRhYmxlU3RhdGljT2Zmc2V0RGF0YSA6IHB1YmxpYyBBcHBsZUFjY2VsVGFibGVEYXRhIHsKK3B1YmxpYzoKKyAgQXBwbGVBY2NlbFRhYmxlU3RhdGljT2Zmc2V0RGF0YSh1aW50MzJfdCBPZmZzZXQpIDogT2Zmc2V0KE9mZnNldCkge30KKworICB2b2lkIGVtaXQoQXNtUHJpbnRlciAqQXNtKSBjb25zdCBvdmVycmlkZTsKKworI2lmbmRlZiBfTVNDX1ZFUgorICAvLyBUaGUgbGluZSBiZWxvdyBpcyByZWplY3RlZCBieSBvbGRlciB2ZXJzaW9ucyAoVEJEKSBvZiBNU1ZDLgorICBzdGF0aWMgY29uc3RleHByIEF0b20gQXRvbXNbXSA9IHsKKyAgICAgIEF0b20oZHdhcmY6OkRXX0FUT01fZGllX29mZnNldCwgZHdhcmY6OkRXX0ZPUk1fZGF0YTQpfTsKKyNlbHNlCisgIC8vIEZJWE1FOiBFcmFzZSB0aGlzIHBhdGggb25jZSB0aGUgbWluaW11bSBNU0NWIHZlcnNpb24gaGFzIGJlZW4gYnVtcGVkLgorICBzdGF0aWMgY29uc3QgU21hbGxWZWN0b3I8QXRvbSwgND4gQXRvbXM7CisjZW5kaWYKKworI2lmbmRlZiBOREVCVUcKKyAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MpIGNvbnN0IG92ZXJyaWRlOworI2VuZGlmCitwcm90ZWN0ZWQ6CisgIHVpbnQ2NF90IG9yZGVyKCkgY29uc3Qgb3ZlcnJpZGUgeyByZXR1cm4gT2Zmc2V0OyB9CisKKyAgdWludDMyX3QgT2Zmc2V0OworfTsKKworLy8vIEFjY2VsZXJhdG9yIHRhYmxlIGRhdGEgaW1wbGVtZW50YXRpb24gZm9yIHR5cGUgYWNjZWxlcmF0b3IgdGFibGVzIHdpdGgKKy8vLyBhIERJRSBvZmZzZXQgYnV0IG5vIGFjdHVhbCBESUUgcG9pbnRlci4KK2NsYXNzIEFwcGxlQWNjZWxUYWJsZVN0YXRpY1R5cGVEYXRhIDogcHVibGljIEFwcGxlQWNjZWxUYWJsZVN0YXRpY09mZnNldERhdGEgeworcHVibGljOgorICBBcHBsZUFjY2VsVGFibGVTdGF0aWNUeXBlRGF0YSh1aW50MzJfdCBPZmZzZXQsIHVpbnQxNl90IFRhZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBPYmpDQ2xhc3NJc0ltcGxlbWVudGF0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBRdWFsaWZpZWROYW1lSGFzaCkKKyAgICAgIDogQXBwbGVBY2NlbFRhYmxlU3RhdGljT2Zmc2V0RGF0YShPZmZzZXQpLAorICAgICAgICBRdWFsaWZpZWROYW1lSGFzaChRdWFsaWZpZWROYW1lSGFzaCksIFRhZyhUYWcpLAorICAgICAgICBPYmpDQ2xhc3NJc0ltcGxlbWVudGF0aW9uKE9iakNDbGFzc0lzSW1wbGVtZW50YXRpb24pIHt9CisKKyAgdm9pZCBlbWl0KEFzbVByaW50ZXIgKkFzbSkgY29uc3Qgb3ZlcnJpZGU7CisKKyNpZm5kZWYgX01TQ19WRVIKKyAgLy8gVGhlIGxpbmUgYmVsb3cgaXMgcmVqZWN0ZWQgYnkgb2xkZXIgdmVyc2lvbnMgKFRCRCkgb2YgTVNWQy4KKyAgc3RhdGljIGNvbnN0ZXhwciBBdG9tIEF0b21zW10gPSB7CisgICAgICBBdG9tKGR3YXJmOjpEV19BVE9NX2RpZV9vZmZzZXQsIGR3YXJmOjpEV19GT1JNX2RhdGE0KSwKKyAgICAgIEF0b20oZHdhcmY6OkRXX0FUT01fZGllX3RhZywgZHdhcmY6OkRXX0ZPUk1fZGF0YTIpLAorICAgICAgQXRvbSg1LCBkd2FyZjo6RFdfRk9STV9kYXRhMSksIEF0b20oNiwgZHdhcmY6OkRXX0ZPUk1fZGF0YTQpfTsKKyNlbHNlCisgIC8vIEZJWE1FOiBFcmFzZSB0aGlzIHBhdGggb25jZSB0aGUgbWluaW11bSBNU0NWIHZlcnNpb24gaGFzIGJlZW4gYnVtcGVkLgorICBzdGF0aWMgY29uc3QgU21hbGxWZWN0b3I8QXRvbSwgND4gQXRvbXM7CisjZW5kaWYKKworI2lmbmRlZiBOREVCVUcKKyAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MpIGNvbnN0IG92ZXJyaWRlOworI2VuZGlmCitwcm90ZWN0ZWQ6CisgIHVpbnQ2NF90IG9yZGVyKCkgY29uc3Qgb3ZlcnJpZGUgeyByZXR1cm4gT2Zmc2V0OyB9CisKKyAgdWludDMyX3QgUXVhbGlmaWVkTmFtZUhhc2g7CisgIHVpbnQxNl90IFRhZzsKKyAgYm9vbCBPYmpDQ2xhc3NJc0ltcGxlbWVudGF0aW9uOworfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9EV0FSRkFDQ0VMVEFCTEVfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0FuYWx5c2lzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vQW5hbHlzaXMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYTg4ZjFmCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0FuYWx5c2lzLmgKQEAgLTAsMCArMSwxMzEgQEAKKy8vPT09LSBDb2RlR2VuL0FuYWx5c2lzLmggLSBDb2RlR2VuIExMVk0gSVIgQW5hbHlzaXMgVXRpbGl0aWVzIC0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlY2xhcmVzIHNldmVyYWwgQ29kZUdlbi1zcGVjaWZpYyBMTFZNIElSIGFuYWx5c2lzIHV0aWxpdGllcy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9BTkFMWVNJU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9BTkFMWVNJU19ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9BcnJheVJlZi5oIgorI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9UcmlwbGUuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vSVNET3Bjb2Rlcy5oIgorI2luY2x1ZGUgImxsdm0vSVIvQ2FsbFNpdGUuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0lubGluZUFzbS5oIgorI2luY2x1ZGUgImxsdm0vSVIvSW5zdHJ1Y3Rpb25zLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0NvZGVHZW4uaCIKKworbmFtZXNwYWNlIGxsdm0geworY2xhc3MgR2xvYmFsVmFsdWU7CitjbGFzcyBNYWNoaW5lQmFzaWNCbG9jazsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIFRhcmdldExvd2VyaW5nQmFzZTsKK2NsYXNzIFRhcmdldExvd2VyaW5nOworY2xhc3MgVGFyZ2V0TWFjaGluZTsKK2NsYXNzIFNETm9kZTsKK2NsYXNzIFNEVmFsdWU7CitjbGFzcyBTZWxlY3Rpb25EQUc7CitzdHJ1Y3QgRVZUOworCisvLy8gXGJyaWVmIENvbXB1dGUgdGhlIGxpbmVhcml6ZWQgaW5kZXggb2YgYSBtZW1iZXIgaW4gYSBuZXN0ZWQKKy8vLyBhZ2dyZWdhdGUvc3RydWN0L2FycmF5LgorLy8vCisvLy8gR2l2ZW4gYW4gTExWTSBJUiBhZ2dyZWdhdGUgdHlwZSBhbmQgYSBzZXF1ZW5jZSBvZiBpbnNlcnR2YWx1ZSBvcgorLy8vIGV4dHJhY3R2YWx1ZSBpbmRpY2VzIHRoYXQgaWRlbnRpZnkgYSBtZW1iZXIsIHJldHVybiB0aGUgbGluZWFyaXplZCBpbmRleCBvZgorLy8vIHRoZSBzdGFydCBvZiB0aGUgbWVtYmVyLCBpLmUgdGhlIG51bWJlciBvZiBlbGVtZW50IGluIG1lbW9yeSBiZWZvcmUgdGhlCisvLy8gc291Z2h0IG9uZS4gVGhpcyBpcyBkaXNjb25uZWN0ZWQgZnJvbSB0aGUgbnVtYmVyIG9mIGJ5dGVzLgorLy8vCisvLy8gXHBhcmFtIFR5IGlzIHRoZSB0eXBlIGluZGV4ZWQgYnkgXHAgSW5kaWNlcy4KKy8vLyBccGFyYW0gSW5kaWNlcyBpcyBhbiBvcHRpb25hbCBwb2ludGVyIGluIHRoZSBpbmRpY2VzIGxpc3QgdG8gdGhlIGN1cnJlbnQKKy8vLyBpbmRleC4KKy8vLyBccGFyYW0gSW5kaWNlc0VuZCBpcyB0aGUgZW5kIG9mIHRoZSBpbmRpY2VzIGxpc3QuCisvLy8gXHBhcmFtIEN1ckluZGV4IGlzIHRoZSBjdXJyZW50IGluZGV4IGluIHRoZSByZWN1cnNpb24uCisvLy8KKy8vLyBccmV0dXJucyBccCBDdXJJbmRleCBwbHVzIHRoZSBsaW5lYXIgaW5kZXggaW4gXHAgVHkgIHRoZSBpbmRpY2VzIGxpc3QuCit1bnNpZ25lZCBDb21wdXRlTGluZWFySW5kZXgoVHlwZSAqVHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgKkluZGljZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgKkluZGljZXNFbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgQ3VySW5kZXggPSAwKTsKKworaW5saW5lIHVuc2lnbmVkIENvbXB1dGVMaW5lYXJJbmRleChUeXBlICpUeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8dW5zaWduZWQ+IEluZGljZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIEN1ckluZGV4ID0gMCkgeworICByZXR1cm4gQ29tcHV0ZUxpbmVhckluZGV4KFR5LCBJbmRpY2VzLmJlZ2luKCksIEluZGljZXMuZW5kKCksIEN1ckluZGV4KTsKK30KKworLy8vIENvbXB1dGVWYWx1ZVZUcyAtIEdpdmVuIGFuIExMVk0gSVIgdHlwZSwgY29tcHV0ZSBhIHNlcXVlbmNlIG9mCisvLy8gRVZUcyB0aGF0IHJlcHJlc2VudCBhbGwgdGhlIGluZGl2aWR1YWwgdW5kZXJseWluZworLy8vIG5vbi1hZ2dyZWdhdGUgdHlwZXMgdGhhdCBjb21wcmlzZSBpdC4KKy8vLworLy8vIElmIE9mZnNldHMgaXMgbm9uLW51bGwsIGl0IHBvaW50cyB0byBhIHZlY3RvciB0byBiZSBmaWxsZWQgaW4KKy8vLyB3aXRoIHRoZSBpbi1tZW1vcnkgb2Zmc2V0cyBvZiBlYWNoIG9mIHRoZSBpbmRpdmlkdWFsIHZhbHVlcy4KKy8vLwordm9pZCBDb21wdXRlVmFsdWVWVHMoY29uc3QgVGFyZ2V0TG93ZXJpbmcgJlRMSSwgY29uc3QgRGF0YUxheW91dCAmREwsIFR5cGUgKlR5LAorICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPEVWVD4gJlZhbHVlVlRzLAorICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPHVpbnQ2NF90PiAqT2Zmc2V0cyA9IG51bGxwdHIsCisgICAgICAgICAgICAgICAgICAgICB1aW50NjRfdCBTdGFydGluZ09mZnNldCA9IDApOworCisvLy8gRXh0cmFjdFR5cGVJbmZvIC0gUmV0dXJucyB0aGUgdHlwZSBpbmZvLCBwb3NzaWJseSBiaXRjYXN0LCBlbmNvZGVkIGluIFYuCitHbG9iYWxWYWx1ZSAqRXh0cmFjdFR5cGVJbmZvKFZhbHVlICpWKTsKKworLy8vIGhhc0lubGluZUFzbU1lbUNvbnN0cmFpbnQgLSBSZXR1cm4gdHJ1ZSBpZiB0aGUgaW5saW5lIGFzbSBpbnN0cnVjdGlvbiBiZWluZworLy8vIHByb2Nlc3NlZCB1c2VzIGEgbWVtb3J5ICdtJyBjb25zdHJhaW50LgorYm9vbCBoYXNJbmxpbmVBc21NZW1Db25zdHJhaW50KElubGluZUFzbTo6Q29uc3RyYWludEluZm9WZWN0b3IgJkNJbmZvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRMb3dlcmluZyAmVExJKTsKKworLy8vIGdldEZDbXBDb25kQ29kZSAtIFJldHVybiB0aGUgSVNEIGNvbmRpdGlvbiBjb2RlIGNvcnJlc3BvbmRpbmcgdG8KKy8vLyB0aGUgZ2l2ZW4gTExWTSBJUiBmbG9hdGluZy1wb2ludCBjb25kaXRpb24gY29kZS4gIFRoaXMgaW5jbHVkZXMKKy8vLyBjb25zaWRlcmF0aW9uIG9mIGdsb2JhbCBmbG9hdGluZy1wb2ludCBtYXRoIGZsYWdzLgorLy8vCitJU0Q6OkNvbmRDb2RlIGdldEZDbXBDb25kQ29kZShGQ21wSW5zdDo6UHJlZGljYXRlIFByZWQpOworCisvLy8gZ2V0RkNtcENvZGVXaXRob3V0TmFOIC0gR2l2ZW4gYW4gSVNEIGNvbmRpdGlvbiBjb2RlIGNvbXBhcmluZyBmbG9hdHMsCisvLy8gcmV0dXJuIHRoZSBlcXVpdmFsZW50IGNvZGUgaWYgd2UncmUgYWxsb3dlZCB0byBhc3N1bWUgdGhhdCBOYU5zIHdvbid0IG9jY3VyLgorSVNEOjpDb25kQ29kZSBnZXRGQ21wQ29kZVdpdGhvdXROYU4oSVNEOjpDb25kQ29kZSBDQyk7CisKKy8vLyBnZXRJQ21wQ29uZENvZGUgLSBSZXR1cm4gdGhlIElTRCBjb25kaXRpb24gY29kZSBjb3JyZXNwb25kaW5nIHRvCisvLy8gdGhlIGdpdmVuIExMVk0gSVIgaW50ZWdlciBjb25kaXRpb24gY29kZS4KKy8vLworSVNEOjpDb25kQ29kZSBnZXRJQ21wQ29uZENvZGUoSUNtcEluc3Q6OlByZWRpY2F0ZSBQcmVkKTsKKworLy8vIFRlc3QgaWYgdGhlIGdpdmVuIGluc3RydWN0aW9uIGlzIGluIGEgcG9zaXRpb24gdG8gYmUgb3B0aW1pemVkCisvLy8gd2l0aCBhIHRhaWwtY2FsbC4gVGhpcyByb3VnaGx5IG1lYW5zIHRoYXQgaXQncyBpbiBhIGJsb2NrIHdpdGgKKy8vLyBhIHJldHVybiBhbmQgdGhlcmUncyBub3RoaW5nIHRoYXQgbmVlZHMgdG8gYmUgc2NoZWR1bGVkCisvLy8gYmV0d2VlbiBpdCBhbmQgdGhlIHJldHVybi4KKy8vLworLy8vIFRoaXMgZnVuY3Rpb24gb25seSB0ZXN0cyB0YXJnZXQtaW5kZXBlbmRlbnQgcmVxdWlyZW1lbnRzLgorYm9vbCBpc0luVGFpbENhbGxQb3NpdGlvbihJbW11dGFibGVDYWxsU2l0ZSBDUywgY29uc3QgVGFyZ2V0TWFjaGluZSAmVE0pOworCisvLy8gVGVzdCBpZiBnaXZlbiB0aGF0IHRoZSBpbnB1dCBpbnN0cnVjdGlvbiBpcyBpbiB0aGUgdGFpbCBjYWxsIHBvc2l0aW9uLCBpZgorLy8vIHRoZXJlIGlzIGFuIGF0dHJpYnV0ZSBtaXNtYXRjaCBiZXR3ZWVuIHRoZSBjYWxsZXIgYW5kIHRoZSBjYWxsZWUgdGhhdCB3aWxsCisvLy8gaW5oaWJpdCB0YWlsIGNhbGwgb3B0aW1pemF0aW9ucy4KKy8vLyBccCBBbGxvd0RpZmZlcmluZ1NpemVzIGlzIGFuIG91dHB1dCBwYXJhbWV0ZXIgd2hpY2gsIGlmIGZvcm1pbmcgYSB0YWlsIGNhbGwKKy8vLyBpcyBwZXJtaXR0ZWQsIGRldGVybWluZXMgd2hldGhlciBpdCdzIHBlcm1pdHRlZCBvbmx5IGlmIHRoZSBzaXplIG9mIHRoZQorLy8vIGNhbGxlcidzIGFuZCBjYWxsZWUncyByZXR1cm4gdHlwZXMgbWF0Y2ggZXhhY3RseS4KK2Jvb2wgYXR0cmlidXRlc1Blcm1pdFRhaWxDYWxsKGNvbnN0IEZ1bmN0aW9uICpGLCBjb25zdCBJbnN0cnVjdGlvbiAqSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJldHVybkluc3QgKlJldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldExvd2VyaW5nQmFzZSAmVExJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCAqQWxsb3dEaWZmZXJpbmdTaXplcyA9IG51bGxwdHIpOworCisvLy8gVGVzdCBpZiBnaXZlbiB0aGF0IHRoZSBpbnB1dCBpbnN0cnVjdGlvbiBpcyBpbiB0aGUgdGFpbCBjYWxsIHBvc2l0aW9uIGlmIHRoZQorLy8vIHJldHVybiB0eXBlIG9yIGFueSBhdHRyaWJ1dGVzIG9mIHRoZSBmdW5jdGlvbiB3aWxsIGluaGliaXQgdGFpbCBjYWxsCisvLy8gb3B0aW1pemF0aW9uLgorYm9vbCByZXR1cm5UeXBlSXNFbGlnaWJsZUZvclRhaWxDYWxsKGNvbnN0IEZ1bmN0aW9uICpGLCBjb25zdCBJbnN0cnVjdGlvbiAqSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZXR1cm5JbnN0ICpSZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0TG93ZXJpbmdCYXNlICZUTEkpOworCitEZW5zZU1hcDxjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqLCBpbnQ+CitnZXRGdW5jbGV0TWVtYmVyc2hpcChjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKTsKKworfSAvLyBFbmQgbGx2bSBuYW1lc3BhY2UKKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vQXNtUHJpbnRlci5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0FzbVByaW50ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZDNiZDNhCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0FzbVByaW50ZXIuaApAQCAtMCwwICsxLDY0NSBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9Bc21QcmludGVyLmggLSBBc21QcmludGVyIEZyYW1ld29yayAtLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgY29udGFpbnMgYSBjbGFzcyB0byBiZSB1c2VkIGFzIHRoZSBiYXNlIGNsYXNzIGZvciB0YXJnZXQgc3BlY2lmaWMKKy8vIGFzbSB3cml0ZXJzLiAgVGhpcyBjbGFzcyBwcmltYXJpbHkgaGFuZGxlcyBjb21tb24gZnVuY3Rpb25hbGl0eSB1c2VkIGJ5CisvLyBhbGwgYXNtIHdyaXRlcnMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fQVNNUFJJTlRFUl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9BU01QUklOVEVSX0gKKworI2luY2x1ZGUgImxsdm0vQURUL01hcFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU3RyaW5nUmVmLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvVHdpbmUuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vRHdhcmZTdHJpbmdQb29sRW50cnkuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uUGFzcy5oIgorI2luY2x1ZGUgImxsdm0vSVIvSW5saW5lQXNtLmgiCisjaW5jbHVkZSAibGx2bS9JUi9MTFZNQ29udGV4dC5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9FcnJvckhhbmRsaW5nLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L1NvdXJjZU1nci5oIgorI2luY2x1ZGUgPGNzdGRpbnQ+CisjaW5jbHVkZSA8bWVtb3J5PgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8dmVjdG9yPgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIEFzbVByaW50ZXJIYW5kbGVyOworY2xhc3MgQmFzaWNCbG9jazsKK2NsYXNzIEJsb2NrQWRkcmVzczsKK2NsYXNzIENvbnN0YW50OworY2xhc3MgQ29uc3RhbnRBcnJheTsKK2NsYXNzIERhdGFMYXlvdXQ7CitjbGFzcyBESUU7CitjbGFzcyBESUVBYmJyZXY7CitjbGFzcyBEd2FyZkRlYnVnOworY2xhc3MgR0NNZXRhZGF0YVByaW50ZXI7CitjbGFzcyBHQ1N0cmF0ZWd5OworY2xhc3MgR2xvYmFsSW5kaXJlY3RTeW1ib2w7CitjbGFzcyBHbG9iYWxPYmplY3Q7CitjbGFzcyBHbG9iYWxWYWx1ZTsKK2NsYXNzIEdsb2JhbFZhcmlhYmxlOworY2xhc3MgTWFjaGluZUJhc2ljQmxvY2s7CitjbGFzcyBNYWNoaW5lQ29uc3RhbnRQb29sVmFsdWU7CitjbGFzcyBNYWNoaW5lRnVuY3Rpb247CitjbGFzcyBNYWNoaW5lSW5zdHI7CitjbGFzcyBNYWNoaW5lSnVtcFRhYmxlSW5mbzsKK2NsYXNzIE1hY2hpbmVMb29wSW5mbzsKK2NsYXNzIE1hY2hpbmVNb2R1bGVJbmZvOworY2xhc3MgTWFjaGluZU9wdGltaXphdGlvblJlbWFya0VtaXR0ZXI7CitjbGFzcyBNQ0FzbUluZm87CitjbGFzcyBNQ0NGSUluc3RydWN0aW9uOworc3RydWN0IE1DQ29kZVBhZGRpbmdDb250ZXh0OworY2xhc3MgTUNDb250ZXh0OworY2xhc3MgTUNFeHByOworY2xhc3MgTUNJbnN0OworY2xhc3MgTUNTZWN0aW9uOworY2xhc3MgTUNTdHJlYW1lcjsKK2NsYXNzIE1DU3VidGFyZ2V0SW5mbzsKK2NsYXNzIE1DU3ltYm9sOworY2xhc3MgTUNUYXJnZXRPcHRpb25zOworY2xhc3MgTUROb2RlOworY2xhc3MgTW9kdWxlOworY2xhc3MgcmF3X29zdHJlYW07CitjbGFzcyBUYXJnZXRMb3dlcmluZ09iamVjdEZpbGU7CitjbGFzcyBUYXJnZXRNYWNoaW5lOworCisvLy8gVGhpcyBjbGFzcyBpcyBpbnRlbmRlZCB0byBiZSB1c2VkIGFzIGEgZHJpdmluZyBjbGFzcyBmb3IgYWxsIGFzbSB3cml0ZXJzLgorY2xhc3MgQXNtUHJpbnRlciA6IHB1YmxpYyBNYWNoaW5lRnVuY3Rpb25QYXNzIHsKK3B1YmxpYzoKKyAgLy8vIFRhcmdldCBtYWNoaW5lIGRlc2NyaXB0aW9uLgorICBUYXJnZXRNYWNoaW5lICZUTTsKKworICAvLy8gVGFyZ2V0IEFzbSBQcmludGVyIGluZm9ybWF0aW9uLgorICBjb25zdCBNQ0FzbUluZm8gKk1BSTsKKworICAvLy8gVGhpcyBpcyB0aGUgY29udGV4dCBmb3IgdGhlIG91dHB1dCBmaWxlIHRoYXQgd2UgYXJlIHN0cmVhbWluZy4gVGhpcyBvd25zCisgIC8vLyBhbGwgb2YgdGhlIGdsb2JhbCBNQy1yZWxhdGVkIG9iamVjdHMgZm9yIHRoZSBnZW5lcmF0ZWQgdHJhbnNsYXRpb24gdW5pdC4KKyAgTUNDb250ZXh0ICZPdXRDb250ZXh0OworCisgIC8vLyBUaGlzIGlzIHRoZSBNQ1N0cmVhbWVyIG9iamVjdCBmb3IgdGhlIGZpbGUgd2UgYXJlIGdlbmVyYXRpbmcuIFRoaXMKKyAgLy8vIGNvbnRhaW5zIHRoZSB0cmFuc2llbnQgc3RhdGUgZm9yIHRoZSBjdXJyZW50IHRyYW5zbGF0aW9uIHVuaXQgdGhhdCB3ZSBhcmUKKyAgLy8vIGdlbmVyYXRpbmcgKHN1Y2ggYXMgdGhlIGN1cnJlbnQgc2VjdGlvbiBldGMpLgorICBzdGQ6OnVuaXF1ZV9wdHI8TUNTdHJlYW1lcj4gT3V0U3RyZWFtZXI7CisKKyAgLy8vIFRoZSBjdXJyZW50IG1hY2hpbmUgZnVuY3Rpb24uCisgIGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAqTUYgPSBudWxscHRyOworCisgIC8vLyBUaGlzIGlzIGEgcG9pbnRlciB0byB0aGUgY3VycmVudCBNYWNoaW5lTW9kdWxlSW5mby4KKyAgTWFjaGluZU1vZHVsZUluZm8gKk1NSSA9IG51bGxwdHI7CisKKyAgLy8vIE9wdGltaXphdGlvbiByZW1hcmsgZW1pdHRlci4KKyAgTWFjaGluZU9wdGltaXphdGlvblJlbWFya0VtaXR0ZXIgKk9SRTsKKworICAvLy8gVGhlIHN5bWJvbCBmb3IgdGhlIGN1cnJlbnQgZnVuY3Rpb24uIFRoaXMgaXMgcmVjYWxjdWxhdGVkIGF0IHRoZSBiZWdpbm5pbmcKKyAgLy8vIG9mIGVhY2ggY2FsbCB0byBydW5Pbk1hY2hpbmVGdW5jdGlvbigpLgorICBNQ1N5bWJvbCAqQ3VycmVudEZuU3ltID0gbnVsbHB0cjsKKworICAvLy8gVGhlIHN5bWJvbCB1c2VkIHRvIHJlcHJlc2VudCB0aGUgc3RhcnQgb2YgdGhlIGN1cnJlbnQgZnVuY3Rpb24gZm9yIHRoZQorICAvLy8gcHVycG9zZSBvZiBjYWxjdWxhdGluZyBpdHMgc2l6ZSAoZS5nLiB1c2luZyB0aGUgLnNpemUgZGlyZWN0aXZlKS4gQnkKKyAgLy8vIGRlZmF1bHQsIHRoaXMgaXMgZXF1YWwgdG8gQ3VycmVudEZuU3ltLgorICBNQ1N5bWJvbCAqQ3VycmVudEZuU3ltRm9yU2l6ZSA9IG51bGxwdHI7CisKKyAgLy8vIE1hcCBnbG9iYWwgR09UIGVxdWl2YWxlbnQgTUNTeW1ib2xzIHRvIEdsb2JhbFZhcmlhYmxlcyBhbmQga2VlcCB0cmFjayBvZgorICAvLy8gaXRzIG51bWJlciBvZiB1c2VzIGJ5IG90aGVyIGdsb2JhbHMuCisgIHVzaW5nIEdPVEVxdWl2VXNlUGFpciA9IHN0ZDo6cGFpcjxjb25zdCBHbG9iYWxWYXJpYWJsZSAqLCB1bnNpZ25lZD47CisgIE1hcFZlY3Rvcjxjb25zdCBNQ1N5bWJvbCAqLCBHT1RFcXVpdlVzZVBhaXI+IEdsb2JhbEdPVEVxdWl2czsKKworICAvLy8gRW5hYmxlIHByaW50IFtsYXRlbmN5OnRocm91Z2hwdXRdIGluIG91dHB1dC4KKyAgYm9vbCBFbmFibGVQcmludFNjaGVkSW5mbyA9IGZhbHNlOworCitwcml2YXRlOgorICBNQ1N5bWJvbCAqQ3VycmVudEZuQmVnaW4gPSBudWxscHRyOworICBNQ1N5bWJvbCAqQ3VycmVudEZuRW5kID0gbnVsbHB0cjsKKyAgTUNTeW1ib2wgKkN1ckV4Y2VwdGlvblN5bSA9IG51bGxwdHI7CisKKyAgLy8gVGhlIGdhcmJhZ2UgY29sbGVjdGlvbiBtZXRhZGF0YSBwcmludGVyIHRhYmxlLgorICB2b2lkICpHQ01ldGFkYXRhUHJpbnRlcnMgPSBudWxscHRyOyAvLyBSZWFsbHkgYSBEZW5zZU1hcC4KKworICAvLy8gRW1pdCBjb21tZW50cyBpbiBhc3NlbWJseSBvdXRwdXQgaWYgdGhpcyBpcyB0cnVlLgorICBib29sIFZlcmJvc2VBc207CisKKyAgc3RhdGljIGNoYXIgSUQ7CisKKyAgLy8vIElmIFZlcmJvc2VBc20gaXMgc2V0LCBhIHBvaW50ZXIgdG8gdGhlIGxvb3AgaW5mbyBmb3IgdGhpcyBmdW5jdGlvbi4KKyAgTWFjaGluZUxvb3BJbmZvICpMSSA9IG51bGxwdHI7CisKKyAgc3RydWN0IEhhbmRsZXJJbmZvIHsKKyAgICBBc21QcmludGVySGFuZGxlciAqSGFuZGxlcjsKKyAgICBjb25zdCBjaGFyICpUaW1lck5hbWU7CisgICAgY29uc3QgY2hhciAqVGltZXJEZXNjcmlwdGlvbjsKKyAgICBjb25zdCBjaGFyICpUaW1lckdyb3VwTmFtZTsKKyAgICBjb25zdCBjaGFyICpUaW1lckdyb3VwRGVzY3JpcHRpb247CisKKyAgICBIYW5kbGVySW5mbyhBc21QcmludGVySGFuZGxlciAqSGFuZGxlciwgY29uc3QgY2hhciAqVGltZXJOYW1lLAorICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKlRpbWVyRGVzY3JpcHRpb24sIGNvbnN0IGNoYXIgKlRpbWVyR3JvdXBOYW1lLAorICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKlRpbWVyR3JvdXBEZXNjcmlwdGlvbikKKyAgICAgICAgOiBIYW5kbGVyKEhhbmRsZXIpLCBUaW1lck5hbWUoVGltZXJOYW1lKSwKKyAgICAgICAgICBUaW1lckRlc2NyaXB0aW9uKFRpbWVyRGVzY3JpcHRpb24pLCBUaW1lckdyb3VwTmFtZShUaW1lckdyb3VwTmFtZSksCisgICAgICAgICAgVGltZXJHcm91cERlc2NyaXB0aW9uKFRpbWVyR3JvdXBEZXNjcmlwdGlvbikge30KKyAgfTsKKworICAvLy8gQSB2ZWN0b3Igb2YgYWxsIGRlYnVnL0VIIGluZm8gZW1pdHRlcnMgd2Ugc2hvdWxkIHVzZS4gVGhpcyB2ZWN0b3IKKyAgLy8vIG1haW50YWlucyBvd25lcnNoaXAgb2YgdGhlIGVtaXR0ZXJzLgorICBTbWFsbFZlY3RvcjxIYW5kbGVySW5mbywgMT4gSGFuZGxlcnM7CisKK3B1YmxpYzoKKyAgc3RydWN0IFNyY01nckRpYWdJbmZvIHsKKyAgICBTb3VyY2VNZ3IgU3JjTWdyOworICAgIHN0ZDo6dmVjdG9yPGNvbnN0IE1ETm9kZSAqPiBMb2NJbmZvczsKKyAgICBMTFZNQ29udGV4dDo6SW5saW5lQXNtRGlhZ0hhbmRsZXJUeSBEaWFnSGFuZGxlcjsKKyAgICB2b2lkICpEaWFnQ29udGV4dDsKKyAgfTsKKworcHJpdmF0ZToKKyAgLy8vIFN0cnVjdHVyZSBmb3IgZ2VuZXJhdGluZyBkaWFnbm9zdGljcyBmb3IgaW5saW5lIGFzc2VtYmx5LiBPbmx5IGluaXRpYWxpc2VkCisgIC8vLyB3aGVuIG5lY2Vzc2FyeS4KKyAgbXV0YWJsZSBzdGQ6OnVuaXF1ZV9wdHI8U3JjTWdyRGlhZ0luZm8+IERpYWdJbmZvOworCisgIC8vLyBJZiB0aGUgdGFyZ2V0IHN1cHBvcnRzIGR3YXJmIGRlYnVnIGluZm8sIHRoaXMgcG9pbnRlciBpcyBub24tbnVsbC4KKyAgRHdhcmZEZWJ1ZyAqREQgPSBudWxscHRyOworCisgIC8vLyBJZiB0aGUgY3VycmVudCBtb2R1bGUgdXNlcyBkd2FyZiBDRkkgYW5ub3RhdGlvbnMgc3RyaWN0bHkgZm9yIGRlYnVnZ2luZy4KKyAgYm9vbCBpc0NGSU1vdmVGb3JEZWJ1Z2dpbmcgPSBmYWxzZTsKKworcHJvdGVjdGVkOgorICBleHBsaWNpdCBBc21QcmludGVyKFRhcmdldE1hY2hpbmUgJlRNLCBzdGQ6OnVuaXF1ZV9wdHI8TUNTdHJlYW1lcj4gU3RyZWFtZXIpOworCitwdWJsaWM6CisgIH5Bc21QcmludGVyKCkgb3ZlcnJpZGU7CisKKyAgRHdhcmZEZWJ1ZyAqZ2V0RHdhcmZEZWJ1ZygpIHsgcmV0dXJuIEREOyB9CisgIER3YXJmRGVidWcgKmdldER3YXJmRGVidWcoKSBjb25zdCB7IHJldHVybiBERDsgfQorCisgIHVpbnQxNl90IGdldER3YXJmVmVyc2lvbigpIGNvbnN0OworICB2b2lkIHNldER3YXJmVmVyc2lvbih1aW50MTZfdCBWZXJzaW9uKTsKKworICBib29sIGlzUG9zaXRpb25JbmRlcGVuZGVudCgpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBhc3NlbWJseSBvdXRwdXQgc2hvdWxkIGNvbnRhaW4gY29tbWVudHMuCisgIGJvb2wgaXNWZXJib3NlKCkgY29uc3QgeyByZXR1cm4gVmVyYm9zZUFzbTsgfQorCisgIC8vLyBSZXR1cm4gYSB1bmlxdWUgSUQgZm9yIHRoZSBjdXJyZW50IGZ1bmN0aW9uLgorICB1bnNpZ25lZCBnZXRGdW5jdGlvbk51bWJlcigpIGNvbnN0OworCisgIE1DU3ltYm9sICpnZXRGdW5jdGlvbkJlZ2luKCkgY29uc3QgeyByZXR1cm4gQ3VycmVudEZuQmVnaW47IH0KKyAgTUNTeW1ib2wgKmdldEZ1bmN0aW9uRW5kKCkgY29uc3QgeyByZXR1cm4gQ3VycmVudEZuRW5kOyB9CisgIE1DU3ltYm9sICpnZXRDdXJFeGNlcHRpb25TeW0oKTsKKworICAvLy8gUmV0dXJuIGluZm9ybWF0aW9uIGFib3V0IG9iamVjdCBmaWxlIGxvd2VyaW5nLgorICBjb25zdCBUYXJnZXRMb3dlcmluZ09iamVjdEZpbGUgJmdldE9iakZpbGVMb3dlcmluZygpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gaW5mb3JtYXRpb24gYWJvdXQgZGF0YSBsYXlvdXQuCisgIGNvbnN0IERhdGFMYXlvdXQgJmdldERhdGFMYXlvdXQoKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRoZSBwb2ludGVyIHNpemUgZnJvbSB0aGUgVGFyZ2V0TWFjaGluZQorICB1bnNpZ25lZCBnZXRQb2ludGVyU2l6ZSgpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gaW5mb3JtYXRpb24gYWJvdXQgc3VidGFyZ2V0LgorICBjb25zdCBNQ1N1YnRhcmdldEluZm8gJmdldFN1YnRhcmdldEluZm8oKSBjb25zdDsKKworICB2b2lkIEVtaXRUb1N0cmVhbWVyKE1DU3RyZWFtZXIgJlMsIGNvbnN0IE1DSW5zdCAmSW5zdCk7CisKKyAgLy8vIFJldHVybiB0aGUgY3VycmVudCBzZWN0aW9uIHdlIGFyZSBlbWl0dGluZyB0by4KKyAgY29uc3QgTUNTZWN0aW9uICpnZXRDdXJyZW50U2VjdGlvbigpIGNvbnN0OworCisgIHZvaWQgZ2V0TmFtZVdpdGhQcmVmaXgoU21hbGxWZWN0b3JJbXBsPGNoYXI+ICZOYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEdsb2JhbFZhbHVlICpHVikgY29uc3Q7CisKKyAgTUNTeW1ib2wgKmdldFN5bWJvbChjb25zdCBHbG9iYWxWYWx1ZSAqR1YpIGNvbnN0OworCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gWFJheSBpbnN0cnVtZW50YXRpb24gaW1wbGVtZW50YXRpb24uCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KK3B1YmxpYzoKKyAgLy8gVGhpcyBkZXNjcmliZXMgdGhlIGtpbmQgb2Ygc2xlZCB3ZSdyZSBzdG9yaW5nIGluIHRoZSBYUmF5IHRhYmxlLgorICBlbnVtIGNsYXNzIFNsZWRLaW5kIDogdWludDhfdCB7CisgICAgRlVOQ1RJT05fRU5URVIgPSAwLAorICAgIEZVTkNUSU9OX0VYSVQgPSAxLAorICAgIFRBSUxfQ0FMTCA9IDIsCisgICAgTE9HX0FSR1NfRU5URVIgPSAzLAorICAgIENVU1RPTV9FVkVOVCA9IDQsCisgIH07CisKKyAgLy8gVGhlIHRhYmxlIHdpbGwgY29udGFpbiB0aGVzZSBzdHJ1Y3RzIHRoYXQgcG9pbnQgdG8gdGhlIHNsZWQsIHRoZSBmdW5jdGlvbgorICAvLyBjb250YWluaW5nIHRoZSBzbGVkLCBhbmQgd2hhdCBraW5kIG9mIHNsZWQgKGFuZCB3aGV0aGVyIHRoZXkgc2hvdWxkIGFsd2F5cworICAvLyBiZSBpbnN0cnVtZW50ZWQpLiBXZSBhbHNvIHVzZSBhIHZlcnNpb24gaWRlbnRpZmllciB0aGF0IHRoZSBydW50aW1lIGNhbiB1c2UKKyAgLy8gdG8gZGVjaWRlIHdoYXQgdG8gZG8gd2l0aCB0aGUgc2xlZCwgZGVwZW5kaW5nIG9uIHRoZSB2ZXJzaW9uIG9mIHRoZSBzbGVkLgorICBzdHJ1Y3QgWFJheUZ1bmN0aW9uRW50cnkgeworICAgIGNvbnN0IE1DU3ltYm9sICpTbGVkOworICAgIGNvbnN0IE1DU3ltYm9sICpGdW5jdGlvbjsKKyAgICBTbGVkS2luZCBLaW5kOworICAgIGJvb2wgQWx3YXlzSW5zdHJ1bWVudDsKKyAgICBjb25zdCBjbGFzcyBGdW5jdGlvbiAqRm47CisgICAgdWludDhfdCBWZXJzaW9uOworCisgICAgdm9pZCBlbWl0KGludCwgTUNTdHJlYW1lciAqLCBjb25zdCBNQ1N5bWJvbCAqKSBjb25zdDsKKyAgfTsKKworICAvLyBBbGwgdGhlIHNsZWRzIHRvIGJlIGVtaXR0ZWQuCisgIFNtYWxsVmVjdG9yPFhSYXlGdW5jdGlvbkVudHJ5LCA0PiBTbGVkczsKKworICAvLyBBIHVuaXF1ZSBJRCB1c2VkIGZvciBFTEYgc2VjdGlvbnMgYXNzb2NpYXRlZCB3aXRoIGEgcGFydGljdWxhciBmdW5jdGlvbi4KKyAgdW5zaWduZWQgWFJheUZuVW5pcXVlSUQgPSAwOworCisgIC8vIEhlbHBlciBmdW5jdGlvbiB0byByZWNvcmQgYSBnaXZlbiBYUmF5IHNsZWQuCisgIHZvaWQgcmVjb3JkU2xlZChNQ1N5bWJvbCAqU2xlZCwgY29uc3QgTWFjaGluZUluc3RyICZNSSwgU2xlZEtpbmQgS2luZCwKKyAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgVmVyc2lvbiA9IDApOworCisgIC8vLyBFbWl0IGEgdGFibGUgd2l0aCBhbGwgWFJheSBpbnN0cnVtZW50YXRpb24gcG9pbnRzLgorICB2b2lkIGVtaXRYUmF5VGFibGUoKTsKKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIE1hY2hpbmVGdW5jdGlvblBhc3MgSW1wbGVtZW50YXRpb24uCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworICAvLy8gUmVjb3JkIGFuYWx5c2lzIHVzYWdlLgorICB2b2lkIGdldEFuYWx5c2lzVXNhZ2UoQW5hbHlzaXNVc2FnZSAmQVUpIGNvbnN0IG92ZXJyaWRlOworCisgIC8vLyBTZXQgdXAgdGhlIEFzbVByaW50ZXIgd2hlbiB3ZSBhcmUgd29ya2luZyBvbiBhIG5ldyBtb2R1bGUuIElmIHlvdXIgcGFzcworICAvLy8gb3ZlcnJpZGVzIHRoaXMsIGl0IG11c3QgbWFrZSBzdXJlIHRvIGV4cGxpY2l0bHkgY2FsbCB0aGlzIGltcGxlbWVudGF0aW9uLgorICBib29sIGRvSW5pdGlhbGl6YXRpb24oTW9kdWxlICZNKSBvdmVycmlkZTsKKworICAvLy8gU2h1dCBkb3duIHRoZSBhc21wcmludGVyLiBJZiB5b3Ugb3ZlcnJpZGUgdGhpcyBpbiB5b3VyIHBhc3MsIHlvdSBtdXN0IG1ha2UKKyAgLy8vIHN1cmUgdG8gY2FsbCBpdCBleHBsaWNpdGx5LgorICBib29sIGRvRmluYWxpemF0aW9uKE1vZHVsZSAmTSkgb3ZlcnJpZGU7CisKKyAgLy8vIEVtaXQgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBvdXQgdG8gdGhlIE91dFN0cmVhbWVyLgorICBib29sIHJ1bk9uTWFjaGluZUZ1bmN0aW9uKE1hY2hpbmVGdW5jdGlvbiAmTUYpIG92ZXJyaWRlIHsKKyAgICBTZXR1cE1hY2hpbmVGdW5jdGlvbihNRik7CisgICAgRW1pdEZ1bmN0aW9uQm9keSgpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gQ29hcnNlIGdyYWluZWQgSVIgbG93ZXJpbmcgcm91dGluZXMuCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworICAvLy8gVGhpcyBzaG91bGQgYmUgY2FsbGVkIHdoZW4gYSBuZXcgTWFjaGluZUZ1bmN0aW9uIGlzIGJlaW5nIHByb2Nlc3NlZCBmcm9tCisgIC8vLyBydW5Pbk1hY2hpbmVGdW5jdGlvbi4KKyAgdm9pZCBTZXR1cE1hY2hpbmVGdW5jdGlvbihNYWNoaW5lRnVuY3Rpb24gJk1GKTsKKworICAvLy8gVGhpcyBtZXRob2QgZW1pdHMgdGhlIGJvZHkgYW5kIHRyYWlsZXIgZm9yIGEgZnVuY3Rpb24uCisgIHZvaWQgRW1pdEZ1bmN0aW9uQm9keSgpOworCisgIHZvaWQgZW1pdENGSUluc3RydWN0aW9uKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpOworCisgIHZvaWQgZW1pdEZyYW1lQWxsb2MoY29uc3QgTWFjaGluZUluc3RyICZNSSk7CisKKyAgdm9pZCBlbWl0U3RhY2tTaXplU2VjdGlvbihjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKTsKKworICBlbnVtIENGSU1vdmVUeXBlIHsgQ0ZJX01fTm9uZSwgQ0ZJX01fRUgsIENGSV9NX0RlYnVnIH07CisgIENGSU1vdmVUeXBlIG5lZWRzQ0ZJTW92ZXMoKSBjb25zdDsKKworICAvLy8gUmV0dXJucyBmYWxzZSBpZiBuZWVkc0NGSU1vdmVzKCkgPT0gQ0ZJX01fRUggZm9yIGFueSBmdW5jdGlvbgorICAvLy8gaW4gdGhlIG1vZHVsZS4KKyAgYm9vbCBuZWVkc09ubHlEZWJ1Z0NGSU1vdmVzKCkgY29uc3QgeyByZXR1cm4gaXNDRklNb3ZlRm9yRGVidWdnaW5nOyB9CisKKyAgYm9vbCBuZWVkc1NFSE1vdmVzKCk7CisKKyAgLy8vIFByaW50IHRvIHRoZSBjdXJyZW50IG91dHB1dCBzdHJlYW0gYXNzZW1ibHkgcmVwcmVzZW50YXRpb25zIG9mIHRoZQorICAvLy8gY29uc3RhbnRzIGluIHRoZSBjb25zdGFudCBwb29sIE1DUC4gVGhpcyBpcyB1c2VkIHRvIHByaW50IG91dCBjb25zdGFudHMKKyAgLy8vIHdoaWNoIGhhdmUgYmVlbiAic3BpbGxlZCB0byBtZW1vcnkiIGJ5IHRoZSBjb2RlIGdlbmVyYXRvci4KKyAgdmlydHVhbCB2b2lkIEVtaXRDb25zdGFudFBvb2woKTsKKworICAvLy8gUHJpbnQgYXNzZW1ibHkgcmVwcmVzZW50YXRpb25zIG9mIHRoZSBqdW1wIHRhYmxlcyB1c2VkIGJ5IHRoZSBjdXJyZW50CisgIC8vLyBmdW5jdGlvbiB0byB0aGUgY3VycmVudCBvdXRwdXQgc3RyZWFtLgorICB2aXJ0dWFsIHZvaWQgRW1pdEp1bXBUYWJsZUluZm8oKTsKKworICAvLy8gRW1pdCB0aGUgc3BlY2lmaWVkIGdsb2JhbCB2YXJpYWJsZSB0byB0aGUgLnMgZmlsZS4KKyAgdmlydHVhbCB2b2lkIEVtaXRHbG9iYWxWYXJpYWJsZShjb25zdCBHbG9iYWxWYXJpYWJsZSAqR1YpOworCisgIC8vLyBDaGVjayB0byBzZWUgaWYgdGhlIHNwZWNpZmllZCBnbG9iYWwgaXMgYSBzcGVjaWFsIGdsb2JhbCB1c2VkIGJ5IExMVk0uIElmCisgIC8vLyBzbywgZW1pdCBpdCBhbmQgcmV0dXJuIHRydWUsIG90aGVyd2lzZSBkbyBub3RoaW5nIGFuZCByZXR1cm4gZmFsc2UuCisgIGJvb2wgRW1pdFNwZWNpYWxMTFZNR2xvYmFsKGNvbnN0IEdsb2JhbFZhcmlhYmxlICpHVik7CisKKyAgLy8vIEVtaXQgYW4gYWxpZ25tZW50IGRpcmVjdGl2ZSB0byB0aGUgc3BlY2lmaWVkIHBvd2VyIG9mIHR3byBib3VuZGFyeS4gRm9yCisgIC8vLyBleGFtcGxlLCBpZiB5b3UgcGFzcyBpbiAzIGhlcmUsIHlvdSB3aWxsIGdldCBhbiA4IGJ5dGUgYWxpZ25tZW50LiBJZiBhCisgIC8vLyBnbG9iYWwgdmFsdWUgaXMgc3BlY2lmaWVkLCBhbmQgaWYgdGhhdCBnbG9iYWwgaGFzIGFuIGV4cGxpY2l0IGFsaWdubWVudAorICAvLy8gcmVxdWVzdGVkLCBpdCB3aWxsIG92ZXJyaWRlIHRoZSBhbGlnbm1lbnQgcmVxdWVzdCBpZiByZXF1aXJlZCBmb3IKKyAgLy8vIGNvcnJlY3RuZXNzLgorICB2b2lkIEVtaXRBbGlnbm1lbnQodW5zaWduZWQgTnVtQml0cywgY29uc3QgR2xvYmFsT2JqZWN0ICpHTyA9IG51bGxwdHIpIGNvbnN0OworCisgIC8vLyBMb3dlciB0aGUgc3BlY2lmaWVkIExMVk0gQ29uc3RhbnQgdG8gYW4gTUNFeHByLgorICB2aXJ0dWFsIGNvbnN0IE1DRXhwciAqbG93ZXJDb25zdGFudChjb25zdCBDb25zdGFudCAqQ1YpOworCisgIC8vLyBcYnJpZWYgUHJpbnQgYSBnZW5lcmFsIExMVk0gY29uc3RhbnQgdG8gdGhlIC5zIGZpbGUuCisgIHZvaWQgRW1pdEdsb2JhbENvbnN0YW50KGNvbnN0IERhdGFMYXlvdXQgJkRMLCBjb25zdCBDb25zdGFudCAqQ1YpOworCisgIC8vLyBcYnJpZWYgVW5uYW1lZCBjb25zdGFudCBnbG9iYWwgdmFyaWFibGVzIHNvbGVseSBjb250YW5pbmcgYSBwb2ludGVyIHRvCisgIC8vLyBhbm90aGVyIGdsb2JhbHMgdmFyaWFibGUgYWN0IGxpa2UgYSBnbG9iYWwgdmFyaWFibGUgInByb3h5Iiwgb3IgR09UCisgIC8vLyBlcXVpdmFsZW50cywgaS5lLiwgaXQncyBvbmx5IHVzZWQgdG8gaG9sZCB0aGUgYWRkcmVzcyBvZiB0aGUgbGF0dGVyLiBPbmUKKyAgLy8vIG9wdGltaXphdGlvbiBpcyB0byByZXBsYWNlIGFjY2Vzc2VzIHRvIHRoZXNlIHByb3hpZXMgYnkgdXNpbmcgdGhlIEdPVAorICAvLy8gZW50cnkgZm9yIHRoZSBmaW5hbCBnbG9iYWwgaW5zdGVhZC4gSGVuY2UsIHdlIHNlbGVjdCBHT1QgZXF1aXZhbGVudAorICAvLy8gY2FuZGlkYXRlcyBhbW9uZyBhbGwgdGhlIG1vZHVsZSBnbG9iYWwgdmFyaWFibGVzLCBhdm9pZCBlbWl0dGluZyB0aGVtCisgIC8vLyB1bm5lY2Vzc2FyaWx5IGFuZCBmaW5hbGx5IHJlcGxhY2UgcmVmZXJlbmNlcyB0byB0aGVtIGJ5IHBjIHJlbGF0aXZlCisgIC8vLyBhY2Nlc3NlcyB0byBHT1QgZW50cmllcy4KKyAgdm9pZCBjb21wdXRlR2xvYmFsR09URXF1aXZzKE1vZHVsZSAmTSk7CisKKyAgLy8vIFxicmllZiBDb25zdGFudCBleHByZXNzaW9ucyB1c2luZyBHT1QgZXF1aXZhbGVudCBnbG9iYWxzIG1heSBub3QgYmUKKyAgLy8vIGVsaWdpYmxlIGZvciBQQyByZWxhdGl2ZSBHT1QgZW50cnkgY29udmVyc2lvbiwgaW4gc3VjaCBjYXNlcyB3ZSBuZWVkIHRvCisgIC8vLyBlbWl0IHRoZSBwcm94aWVzIHdlIHByZXZpb3VzbHkgb21pdHRlZCBpbiBFbWl0R2xvYmFsVmFyaWFibGUuCisgIHZvaWQgZW1pdEdsb2JhbEdPVEVxdWl2cygpOworCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gT3ZlcnJpZGFibGUgSG9va3MKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisgIC8vIFRhcmdldHMgY2FuLCBvciBpbiB0aGUgY2FzZSBvZiBFbWl0SW5zdHJ1Y3Rpb24sIG11c3QgaW1wbGVtZW50IHRoZXNlIHRvCisgIC8vIGN1c3RvbWl6ZSBvdXRwdXQuCisKKyAgLy8vIFRoaXMgdmlydHVhbCBtZXRob2QgY2FuIGJlIG92ZXJyaWRkZW4gYnkgdGFyZ2V0cyB0aGF0IHdhbnQgdG8gZW1pdAorICAvLy8gc29tZXRoaW5nIGF0IHRoZSBzdGFydCBvZiB0aGVpciBmaWxlLgorICB2aXJ0dWFsIHZvaWQgRW1pdFN0YXJ0T2ZBc21GaWxlKE1vZHVsZSAmKSB7fQorCisgIC8vLyBUaGlzIHZpcnR1YWwgbWV0aG9kIGNhbiBiZSBvdmVycmlkZGVuIGJ5IHRhcmdldHMgdGhhdCB3YW50IHRvIGVtaXQKKyAgLy8vIHNvbWV0aGluZyBhdCB0aGUgZW5kIG9mIHRoZWlyIGZpbGUuCisgIHZpcnR1YWwgdm9pZCBFbWl0RW5kT2ZBc21GaWxlKE1vZHVsZSAmKSB7fQorCisgIC8vLyBUYXJnZXRzIGNhbiBvdmVycmlkZSB0aGlzIHRvIGVtaXQgc3R1ZmYgYmVmb3JlIHRoZSBmaXJzdCBiYXNpYyBibG9jayBpbgorICAvLy8gdGhlIGZ1bmN0aW9uLgorICB2aXJ0dWFsIHZvaWQgRW1pdEZ1bmN0aW9uQm9keVN0YXJ0KCkge30KKworICAvLy8gVGFyZ2V0cyBjYW4gb3ZlcnJpZGUgdGhpcyB0byBlbWl0IHN0dWZmIGFmdGVyIHRoZSBsYXN0IGJhc2ljIGJsb2NrIGluIHRoZQorICAvLy8gZnVuY3Rpb24uCisgIHZpcnR1YWwgdm9pZCBFbWl0RnVuY3Rpb25Cb2R5RW5kKCkge30KKworICAvLy8gVGFyZ2V0cyBjYW4gb3ZlcnJpZGUgdGhpcyB0byBlbWl0IHN0dWZmIGF0IHRoZSBzdGFydCBvZiBhIGJhc2ljIGJsb2NrLgorICAvLy8gQnkgZGVmYXVsdCwgdGhpcyBtZXRob2QgcHJpbnRzIHRoZSBsYWJlbCBmb3IgdGhlIHNwZWNpZmllZAorICAvLy8gTWFjaGluZUJhc2ljQmxvY2ssIGFuIGFsaWdubWVudCAoaWYgcHJlc2VudCkgYW5kIGEgY29tbWVudCBkZXNjcmliaW5nIGl0CisgIC8vLyBpZiBhcHByb3ByaWF0ZS4KKyAgdmlydHVhbCB2b2lkIEVtaXRCYXNpY0Jsb2NrU3RhcnQoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgJk1CQikgY29uc3Q7CisKKyAgLy8vIFRhcmdldHMgY2FuIG92ZXJyaWRlIHRoaXMgdG8gZW1pdCBzdHVmZiBhdCB0aGUgZW5kIG9mIGEgYmFzaWMgYmxvY2suCisgIHZpcnR1YWwgdm9pZCBFbWl0QmFzaWNCbG9ja0VuZChjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAmTUJCKTsKKworICAvLy8gVGFyZ2V0cyBzaG91bGQgaW1wbGVtZW50IHRoaXMgdG8gZW1pdCBpbnN0cnVjdGlvbnMuCisgIHZpcnR1YWwgdm9pZCBFbWl0SW5zdHJ1Y3Rpb24oY29uc3QgTWFjaGluZUluc3RyICopIHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJFbWl0SW5zdHJ1Y3Rpb24gbm90IGltcGxlbWVudGVkIik7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBzeW1ib2wgZm9yIHRoZSBzcGVjaWZpZWQgY29uc3RhbnQgcG9vbCBlbnRyeS4KKyAgdmlydHVhbCBNQ1N5bWJvbCAqR2V0Q1BJU3ltYm9sKHVuc2lnbmVkIENQSUQpIGNvbnN0OworCisgIHZpcnR1YWwgdm9pZCBFbWl0RnVuY3Rpb25FbnRyeUxhYmVsKCk7CisKKyAgdmlydHVhbCB2b2lkIEVtaXRNYWNoaW5lQ29uc3RhbnRQb29sVmFsdWUoTWFjaGluZUNvbnN0YW50UG9vbFZhbHVlICpNQ1BWKTsKKworICAvLy8gVGFyZ2V0cyBjYW4gb3ZlcnJpZGUgdGhpcyB0byBjaGFuZ2UgaG93IGdsb2JhbCBjb25zdGFudHMgdGhhdCBhcmUgcGFydCBvZgorICAvLy8gYSBDKysgc3RhdGljL2dsb2JhbCBjb25zdHJ1Y3RvciBsaXN0IGFyZSBlbWl0dGVkLgorICB2aXJ0dWFsIHZvaWQgRW1pdFhYU3RydWN0b3IoY29uc3QgRGF0YUxheW91dCAmREwsIGNvbnN0IENvbnN0YW50ICpDVikgeworICAgIEVtaXRHbG9iYWxDb25zdGFudChETCwgQ1YpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBiYXNpYyBibG9jayBoYXMgZXhhY3RseSBvbmUgcHJlZGVjZXNzb3IgYW5kIHRoZSBjb250cm9sCisgIC8vLyB0cmFuc2ZlciBtZWNoYW5pc20gYmV0d2VlbiB0aGUgcHJlZGVjZXNzb3IgYW5kIHRoaXMgYmxvY2sgaXMgYQorICAvLy8gZmFsbC10aHJvdWdoLgorICB2aXJ0dWFsIGJvb2wKKyAgaXNCbG9ja09ubHlSZWFjaGFibGVCeUZhbGx0aHJvdWdoKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpIGNvbnN0OworCisgIC8vLyBUYXJnZXRzIGNhbiBvdmVycmlkZSB0aGlzIHRvIGN1c3RvbWl6ZSB0aGUgb3V0cHV0IG9mIElNUExJQ0lUX0RFRgorICAvLy8gaW5zdHJ1Y3Rpb25zIGluIHZlcmJvc2UgbW9kZS4KKyAgdmlydHVhbCB2b2lkIGVtaXRJbXBsaWNpdERlZihjb25zdCBNYWNoaW5lSW5zdHIgKk1JKSBjb25zdDsKKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIFN5bWJvbCBMb3dlcmluZyBSb3V0aW5lcy4KKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisgIE1DU3ltYm9sICpjcmVhdGVUZW1wU3ltYm9sKGNvbnN0IFR3aW5lICZOYW1lKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRoZSBNQ1N5bWJvbCBmb3IgYSBwcml2YXRlIHN5bWJvbCB3aXRoIGdsb2JhbCB2YWx1ZSBuYW1lIGFzIGl0cworICAvLy8gYmFzZSwgd2l0aCB0aGUgc3BlY2lmaWVkIHN1ZmZpeC4KKyAgTUNTeW1ib2wgKmdldFN5bWJvbFdpdGhHbG9iYWxWYWx1ZUJhc2UoY29uc3QgR2xvYmFsVmFsdWUgKkdWLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdSZWYgU3VmZml4KSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRoZSBNQ1N5bWJvbCBmb3IgdGhlIHNwZWNpZmllZCBFeHRlcm5hbFN5bWJvbC4KKyAgTUNTeW1ib2wgKkdldEV4dGVybmFsU3ltYm9sU3ltYm9sKFN0cmluZ1JlZiBTeW0pIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdGhlIHN5bWJvbCBmb3IgdGhlIHNwZWNpZmllZCBqdW1wIHRhYmxlIGVudHJ5LgorICBNQ1N5bWJvbCAqR2V0SlRJU3ltYm9sKHVuc2lnbmVkIEpUSUQsIGJvb2wgaXNMaW5rZXJQcml2YXRlID0gZmFsc2UpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdGhlIHN5bWJvbCBmb3IgdGhlIHNwZWNpZmllZCBqdW1wIHRhYmxlIC5zZXQKKyAgLy8vIEZJWE1FOiBwcml2YXRpemUgdG8gQXNtUHJpbnRlci4KKyAgTUNTeW1ib2wgKkdldEpUU2V0U3ltYm9sKHVuc2lnbmVkIFVJRCwgdW5zaWduZWQgTUJCSUQpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdGhlIE1DU3ltYm9sIHVzZWQgdG8gc2F0aXNmeSBCbG9ja0FkZHJlc3MgdXNlcyBvZiB0aGUgc3BlY2lmaWVkCisgIC8vLyBiYXNpYyBibG9jay4KKyAgTUNTeW1ib2wgKkdldEJsb2NrQWRkcmVzc1N5bWJvbChjb25zdCBCbG9ja0FkZHJlc3MgKkJBKSBjb25zdDsKKyAgTUNTeW1ib2wgKkdldEJsb2NrQWRkcmVzc1N5bWJvbChjb25zdCBCYXNpY0Jsb2NrICpCQikgY29uc3Q7CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLyBFbWlzc2lvbiBIZWxwZXIgUm91dGluZXMuCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworICAvLy8gVGhpcyBpcyBqdXN0IGNvbnZlbmllbnQgaGFuZGxlciBmb3IgcHJpbnRpbmcgb2Zmc2V0cy4KKyAgdm9pZCBwcmludE9mZnNldChpbnQ2NF90IE9mZnNldCwgcmF3X29zdHJlYW0gJk9TKSBjb25zdDsKKworICAvLy8gRW1pdCBhIGJ5dGUgZGlyZWN0aXZlIGFuZCB2YWx1ZS4KKyAgdm9pZCBlbWl0SW50OChpbnQgVmFsdWUpIGNvbnN0OworCisgIC8vLyBFbWl0IGEgc2hvcnQgZGlyZWN0aXZlIGFuZCB2YWx1ZS4KKyAgdm9pZCBlbWl0SW50MTYoaW50IFZhbHVlKSBjb25zdDsKKworICAvLy8gRW1pdCBhIGxvbmcgZGlyZWN0aXZlIGFuZCB2YWx1ZS4KKyAgdm9pZCBlbWl0SW50MzIoaW50IFZhbHVlKSBjb25zdDsKKworICAvLy8gRW1pdCBzb21ldGhpbmcgbGlrZSAiLmxvbmcgSGktTG8iIHdoZXJlIHRoZSBzaXplIGluIGJ5dGVzIG9mIHRoZSBkaXJlY3RpdmUKKyAgLy8vIGlzIHNwZWNpZmllZCBieSBTaXplIGFuZCBIaS9MbyBzcGVjaWZ5IHRoZSBsYWJlbHMuICBUaGlzIGltcGxpY2l0bHkgdXNlcworICAvLy8gLnNldCBpZiBpdCBpcyBhdmFpbGFibGUuCisgIHZvaWQgRW1pdExhYmVsRGlmZmVyZW5jZShjb25zdCBNQ1N5bWJvbCAqSGksIGNvbnN0IE1DU3ltYm9sICpMbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFNpemUpIGNvbnN0OworCisgIC8vLyBFbWl0IHNvbWV0aGluZyBsaWtlICIudWxlYjEyOCBIaS1MbyIuCisgIHZvaWQgRW1pdExhYmVsRGlmZmVyZW5jZUFzVUxFQjEyOChjb25zdCBNQ1N5bWJvbCAqSGksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNQ1N5bWJvbCAqTG8pIGNvbnN0OworCisgIC8vLyBFbWl0IHNvbWV0aGluZyBsaWtlICIubG9uZyBMYWJlbCtPZmZzZXQiIHdoZXJlIHRoZSBzaXplIGluIGJ5dGVzIG9mIHRoZQorICAvLy8gZGlyZWN0aXZlIGlzIHNwZWNpZmllZCBieSBTaXplIGFuZCBMYWJlbCBzcGVjaWZpZXMgdGhlIGxhYmVsLiAgVGhpcworICAvLy8gaW1wbGljaXRseSB1c2VzIC5zZXQgaWYgaXQgaXMgYXZhaWxhYmxlLgorICB2b2lkIEVtaXRMYWJlbFBsdXNPZmZzZXQoY29uc3QgTUNTeW1ib2wgKkxhYmVsLCB1aW50NjRfdCBPZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBTaXplLCBib29sIElzU2VjdGlvblJlbGF0aXZlID0gZmFsc2UpIGNvbnN0OworCisgIC8vLyBFbWl0IHNvbWV0aGluZyBsaWtlICIubG9uZyBMYWJlbCIgd2hlcmUgdGhlIHNpemUgaW4gYnl0ZXMgb2YgdGhlIGRpcmVjdGl2ZQorICAvLy8gaXMgc3BlY2lmaWVkIGJ5IFNpemUgYW5kIExhYmVsIHNwZWNpZmllcyB0aGUgbGFiZWwuCisgIHZvaWQgRW1pdExhYmVsUmVmZXJlbmNlKGNvbnN0IE1DU3ltYm9sICpMYWJlbCwgdW5zaWduZWQgU2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBJc1NlY3Rpb25SZWxhdGl2ZSA9IGZhbHNlKSBjb25zdCB7CisgICAgRW1pdExhYmVsUGx1c09mZnNldChMYWJlbCwgMCwgU2l6ZSwgSXNTZWN0aW9uUmVsYXRpdmUpOworICB9CisKKyAgLy8vIEVtaXQgc29tZXRoaW5nIGxpa2UgIi5sb25nIExhYmVsICsgT2Zmc2V0Ii4KKyAgdm9pZCBFbWl0RHdhcmZPZmZzZXQoY29uc3QgTUNTeW1ib2wgKkxhYmVsLCB1aW50NjRfdCBPZmZzZXQpIGNvbnN0OworCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gRHdhcmYgRW1pc3Npb24gSGVscGVyIFJvdXRpbmVzCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworICAvLy8gRW1pdCB0aGUgc3BlY2lmaWVkIHNpZ25lZCBsZWIxMjggdmFsdWUuCisgIHZvaWQgRW1pdFNMRUIxMjgoaW50NjRfdCBWYWx1ZSwgY29uc3QgY2hhciAqRGVzYyA9IG51bGxwdHIpIGNvbnN0OworCisgIC8vLyBFbWl0IHRoZSBzcGVjaWZpZWQgdW5zaWduZWQgbGViMTI4IHZhbHVlLgorICB2b2lkIEVtaXRVTEVCMTI4KHVpbnQ2NF90IFZhbHVlLCBjb25zdCBjaGFyICpEZXNjID0gbnVsbHB0cikgY29uc3Q7CisKKyAgLy8vIEVtaXQgYSAuYnl0ZSA0MiBkaXJlY3RpdmUgdGhhdCBjb3JyZXNwb25kcyB0byBhbiBlbmNvZGluZy4gIElmIHZlcmJvc2UKKyAgLy8vIGFzc2VtYmx5IG91dHB1dCBpcyBlbmFibGVkLCB3ZSBvdXRwdXQgY29tbWVudHMgZGVzY3JpYmluZyB0aGUgZW5jb2RpbmcuCisgIC8vLyBEZXNjIGlzIGEgc3RyaW5nIHNheWluZyB3aGF0IHRoZSBlbmNvZGluZyBpcyBzcGVjaWZ5aW5nIChlLmcuICJMU0RBIikuCisgIHZvaWQgRW1pdEVuY29kaW5nQnl0ZSh1bnNpZ25lZCBWYWwsIGNvbnN0IGNoYXIgKkRlc2MgPSBudWxscHRyKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRoZSBzaXplIG9mIHRoZSBlbmNvZGluZyBpbiBieXRlcy4KKyAgdW5zaWduZWQgR2V0U2l6ZU9mRW5jb2RlZFZhbHVlKHVuc2lnbmVkIEVuY29kaW5nKSBjb25zdDsKKworICAvLy8gRW1pdCByZWZlcmVuY2UgdG8gYSB0dHlwZSBnbG9iYWwgd2l0aCBhIHNwZWNpZmllZCBlbmNvZGluZy4KKyAgdm9pZCBFbWl0VFR5cGVSZWZlcmVuY2UoY29uc3QgR2xvYmFsVmFsdWUgKkdWLCB1bnNpZ25lZCBFbmNvZGluZykgY29uc3Q7CisKKyAgLy8vIEVtaXQgYSByZWZlcmVuY2UgdG8gYSBzeW1ib2wgZm9yIHVzZSBpbiBkd2FyZi4gRGlmZmVyZW50IG9iamVjdCBmb3JtYXRzCisgIC8vLyByZXByZXNlbnQgdGhpcyBpbiBkaWZmZXJlbnQgd2F5cy4gU29tZSB1c2UgYSByZWxvY2F0aW9uIG90aGVycyBlbmNvZGUKKyAgLy8vIHRoZSBsYWJlbCBvZmZzZXQgaW4gaXRzIHNlY3Rpb24uCisgIHZvaWQgZW1pdER3YXJmU3ltYm9sUmVmZXJlbmNlKGNvbnN0IE1DU3ltYm9sICpMYWJlbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBGb3JjZU9mZnNldCA9IGZhbHNlKSBjb25zdDsKKworICAvLy8gRW1pdCB0aGUgNC1ieXRlIG9mZnNldCBvZiBhIHN0cmluZyBmcm9tIHRoZSBzdGFydCBvZiBpdHMgc2VjdGlvbi4KKyAgLy8vCisgIC8vLyBXaGVuIHBvc3NpYmxlLCBlbWl0IGEgRHdhcmZTdHJpbmdQb29sIHNlY3Rpb24gb2Zmc2V0IHdpdGhvdXQgYW55CisgIC8vLyByZWxvY2F0aW9ucywgYW5kIHdpdGhvdXQgdXNpbmcgdGhlIHN5bWJvbC4gIE90aGVyd2lzZSwgZGVmZXJzIHRvIFxhCisgIC8vLyBlbWl0RHdhcmZTeW1ib2xSZWZlcmVuY2UoKS4KKyAgdm9pZCBlbWl0RHdhcmZTdHJpbmdPZmZzZXQoRHdhcmZTdHJpbmdQb29sRW50cnkgUykgY29uc3Q7CisKKyAgLy8vIEVtaXQgdGhlIDQtYnl0ZSBvZmZzZXQgb2YgYSBzdHJpbmcgZnJvbSB0aGUgc3RhcnQgb2YgaXRzIHNlY3Rpb24uCisgIHZvaWQgZW1pdER3YXJmU3RyaW5nT2Zmc2V0KER3YXJmU3RyaW5nUG9vbEVudHJ5UmVmIFMpIGNvbnN0IHsKKyAgICBlbWl0RHdhcmZTdHJpbmdPZmZzZXQoUy5nZXRFbnRyeSgpKTsKKyAgfQorCisgIC8vLyBHZXQgdGhlIHZhbHVlIGZvciBEV19BVF9BUFBMRV9pc2EuIFplcm8gaWYgbm8gaXNhIGVuY29kaW5nIHNwZWNpZmllZC4KKyAgdmlydHVhbCB1bnNpZ25lZCBnZXRJU0FFbmNvZGluZygpIHsgcmV0dXJuIDA7IH0KKworICAvLy8gRW1pdCB0aGUgZGlyZWN0aXZlIGFuZCB2YWx1ZSBmb3IgZGVidWcgdGhyZWFkIGxvY2FsIGV4cHJlc3Npb24KKyAgLy8vCisgIC8vLyBccCBWYWx1ZSAtIFRoZSB2YWx1ZSB0byBlbWl0LgorICAvLy8gXHAgU2l6ZSAtIFRoZSBzaXplIG9mIHRoZSBpbnRlZ2VyIChpbiBieXRlcykgdG8gZW1pdC4KKyAgdmlydHVhbCB2b2lkIEVtaXREZWJ1Z1RocmVhZExvY2FsKGNvbnN0IE1DRXhwciAqVmFsdWUsIHVuc2lnbmVkIFNpemUpIGNvbnN0OworCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gRHdhcmYgTG93ZXJpbmcgUm91dGluZXMKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisgIC8vLyBcYnJpZWYgRW1pdCBmcmFtZSBpbnN0cnVjdGlvbiB0byBkZXNjcmliZSB0aGUgbGF5b3V0IG9mIHRoZSBmcmFtZS4KKyAgdm9pZCBlbWl0Q0ZJSW5zdHJ1Y3Rpb24oY29uc3QgTUNDRklJbnN0cnVjdGlvbiAmSW5zdCkgY29uc3Q7CisKKyAgLy8vIFxicmllZiBFbWl0IER3YXJmIGFiYnJldmlhdGlvbiB0YWJsZS4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHZvaWQgZW1pdER3YXJmQWJicmV2cyhjb25zdCBUICZBYmJyZXZzKSBjb25zdCB7CisgICAgLy8gRm9yIGVhY2ggYWJicmV2aWF0aW9uLgorICAgIGZvciAoY29uc3QgYXV0byAmQWJicmV2IDogQWJicmV2cykKKyAgICAgIGVtaXREd2FyZkFiYnJldigqQWJicmV2KTsKKworICAgIC8vIE1hcmsgZW5kIG9mIGFiYnJldmlhdGlvbnMuCisgICAgRW1pdFVMRUIxMjgoMCwgIkVPTSgzKSIpOworICB9CisKKyAgdm9pZCBlbWl0RHdhcmZBYmJyZXYoY29uc3QgRElFQWJicmV2ICZBYmJyZXYpIGNvbnN0OworCisgIC8vLyBcYnJpZWYgUmVjdXJzaXZlbHkgZW1pdCBEd2FyZiBESUUgdHJlZS4KKyAgdm9pZCBlbWl0RHdhcmZESUUoY29uc3QgRElFICZEaWUpIGNvbnN0OworCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gSW5saW5lIEFzbSBTdXBwb3J0CisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworICAvLyBUaGVzZSBhcmUgaG9va3MgdGhhdCB0YXJnZXRzIGNhbiBvdmVycmlkZSB0byBpbXBsZW1lbnQgaW5saW5lIGFzbQorICAvLyBzdXBwb3J0LiAgVGhlc2Ugc2hvdWxkIHByb2JhYmx5IGJlIG1vdmVkIG91dCBvZiBBc21QcmludGVyIHNvbWVkYXkuCisKKyAgLy8vIFByaW50IGluZm9ybWF0aW9uIHJlbGF0ZWQgdG8gdGhlIHNwZWNpZmllZCBtYWNoaW5lIGluc3RyIHRoYXQgaXMKKyAgLy8vIGluZGVwZW5kZW50IG9mIHRoZSBvcGVyYW5kLCBhbmQgbWF5IGJlIGluZGVwZW5kZW50IG9mIHRoZSBpbnN0ciBpdHNlbGYuCisgIC8vLyBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHBvcnRhYmx5IGVuY29kaW5nIHRoZSBjb21tZW50IGNoYXJhY3RlciBvciBvdGhlcgorICAvLy8gYml0cyBvZiB0YXJnZXQtc3BlY2lmaWMga25vd2xlZGdlIGludG8gdGhlIGFzbXN0cmluZ3MuICBUaGUgc3ludGF4IHVzZWQgaXMKKyAgLy8vICR7OmNvbW1lbnR9LiAgVGFyZ2V0cyBjYW4gb3ZlcnJpZGUgdGhpcyB0byBhZGQgc3VwcG9ydCBmb3IgdGhlaXIgb3duCisgIC8vLyBzdHJhbmdlIGNvZGVzLgorICB2aXJ0dWFsIHZvaWQgUHJpbnRTcGVjaWFsKGNvbnN0IE1hY2hpbmVJbnN0ciAqTUksIHJhd19vc3RyZWFtICZPUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpDb2RlKSBjb25zdDsKKworICAvLy8gUHJpbnQgdGhlIHNwZWNpZmllZCBvcGVyYW5kIG9mIE1JLCBhbiBJTkxJTkVBU00gaW5zdHJ1Y3Rpb24sIHVzaW5nIHRoZQorICAvLy8gc3BlY2lmaWVkIGFzc2VtYmxlciB2YXJpYW50LiAgVGFyZ2V0cyBzaG91bGQgb3ZlcnJpZGUgdGhpcyB0byBmb3JtYXQgYXMKKyAgLy8vIGFwcHJvcHJpYXRlLiAgVGhpcyBtZXRob2QgY2FuIHJldHVybiB0cnVlIGlmIHRoZSBvcGVyYW5kIGlzIGVycm9uZW91cy4KKyAgdmlydHVhbCBib29sIFByaW50QXNtT3BlcmFuZChjb25zdCBNYWNoaW5lSW5zdHIgKk1JLCB1bnNpZ25lZCBPcE5vLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIEFzbVZhcmlhbnQsIGNvbnN0IGNoYXIgKkV4dHJhQ29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfb3N0cmVhbSAmT1MpOworCisgIC8vLyBQcmludCB0aGUgc3BlY2lmaWVkIG9wZXJhbmQgb2YgTUksIGFuIElOTElORUFTTSBpbnN0cnVjdGlvbiwgdXNpbmcgdGhlCisgIC8vLyBzcGVjaWZpZWQgYXNzZW1ibGVyIHZhcmlhbnQgYXMgYW4gYWRkcmVzcy4gVGFyZ2V0cyBzaG91bGQgb3ZlcnJpZGUgdGhpcyB0bworICAvLy8gZm9ybWF0IGFzIGFwcHJvcHJpYXRlLiAgVGhpcyBtZXRob2QgY2FuIHJldHVybiB0cnVlIGlmIHRoZSBvcGVyYW5kIGlzCisgIC8vLyBlcnJvbmVvdXMuCisgIHZpcnR1YWwgYm9vbCBQcmludEFzbU1lbW9yeU9wZXJhbmQoY29uc3QgTWFjaGluZUluc3RyICpNSSwgdW5zaWduZWQgT3BObywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBBc21WYXJpYW50LCBjb25zdCBjaGFyICpFeHRyYUNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X29zdHJlYW0gJk9TKTsKKworICAvLy8gTGV0IHRoZSB0YXJnZXQgZG8gYW55dGhpbmcgaXQgbmVlZHMgdG8gZG8gYmVmb3JlIGVtaXR0aW5nIGlubGluZWFzbS4KKyAgLy8vIFxwIFN0YXJ0SW5mbyAtIHRoZSBzdWJ0YXJnZXQgaW5mbyBiZWZvcmUgcGFyc2luZyBpbmxpbmUgYXNtCisgIHZpcnR1YWwgdm9pZCBlbWl0SW5saW5lQXNtU3RhcnQoKSBjb25zdDsKKworICAvLy8gTGV0IHRoZSB0YXJnZXQgZG8gYW55dGhpbmcgaXQgbmVlZHMgdG8gZG8gYWZ0ZXIgZW1pdHRpbmcgaW5saW5lYXNtLgorICAvLy8gVGhpcyBjYWxsYmFjayBjYW4gYmUgdXNlZCByZXN0b3JlIHRoZSBvcmlnaW5hbCBtb2RlIGluIGNhc2UgdGhlCisgIC8vLyBpbmxpbmVhc20gY29udGFpbnMgZGlyZWN0aXZlcyB0byBzd2l0Y2ggbW9kZXMuCisgIC8vLyBccCBTdGFydEluZm8gLSB0aGUgb3JpZ2luYWwgc3VidGFyZ2V0IGluZm8gYmVmb3JlIGlubGluZSBhc20KKyAgLy8vIFxwIEVuZEluZm8gICAtIHRoZSBmaW5hbCBzdWJ0YXJnZXQgaW5mbyBhZnRlciBwYXJzaW5nIHRoZSBpbmxpbmUgYXNtLAorICAvLy8gICAgICAgICAgICAgICAgb3IgTlVMTCBpZiB0aGUgdmFsdWUgaXMgdW5rbm93bi4KKyAgdmlydHVhbCB2b2lkIGVtaXRJbmxpbmVBc21FbmQoY29uc3QgTUNTdWJ0YXJnZXRJbmZvICZTdGFydEluZm8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1DU3VidGFyZ2V0SW5mbyAqRW5kSW5mbykgY29uc3Q7CisKK3ByaXZhdGU6CisgIC8vLyBQcml2YXRlIHN0YXRlIGZvciBQcmludFNwZWNpYWwoKQorICAvLyBBc3NpZ24gYSB1bmlxdWUgSUQgdG8gdGhpcyBtYWNoaW5lIGluc3RydWN0aW9uLgorICBtdXRhYmxlIGNvbnN0IE1hY2hpbmVJbnN0ciAqTGFzdE1JID0gbnVsbHB0cjsKKyAgbXV0YWJsZSB1bnNpZ25lZCBMYXN0Rm4gPSAwOworICBtdXRhYmxlIHVuc2lnbmVkIENvdW50ZXIgPSB+MFU7CisKKyAgLy8vIFRoaXMgbWV0aG9kIGVtaXRzIHRoZSBoZWFkZXIgZm9yIHRoZSBjdXJyZW50IGZ1bmN0aW9uLgorICB2aXJ0dWFsIHZvaWQgRW1pdEZ1bmN0aW9uSGVhZGVyKCk7CisKKyAgLy8vIEVtaXQgYSBibG9iIG9mIGlubGluZSBhc20gdG8gdGhlIG91dHB1dCBzdHJlYW1lci4KKyAgdm9pZAorICBFbWl0SW5saW5lQXNtKFN0cmluZ1JlZiBTdHIsIGNvbnN0IE1DU3VidGFyZ2V0SW5mbyAmU1RJLAorICAgICAgICAgICAgICAgIGNvbnN0IE1DVGFyZ2V0T3B0aW9ucyAmTUNPcHRpb25zLAorICAgICAgICAgICAgICAgIGNvbnN0IE1ETm9kZSAqTG9jTUROb2RlID0gbnVsbHB0ciwKKyAgICAgICAgICAgICAgICBJbmxpbmVBc206OkFzbURpYWxlY3QgQXNtRGlhbGVjdCA9IElubGluZUFzbTo6QURfQVRUKSBjb25zdDsKKworICAvLy8gVGhpcyBtZXRob2QgZm9ybWF0cyBhbmQgZW1pdHMgdGhlIHNwZWNpZmllZCBtYWNoaW5lIGluc3RydWN0aW9uIHRoYXQgaXMgYW4KKyAgLy8vIGlubGluZSBhc20uCisgIHZvaWQgRW1pdElubGluZUFzbShjb25zdCBNYWNoaW5lSW5zdHIgKk1JKSBjb25zdDsKKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIEludGVybmFsIEltcGxlbWVudGF0aW9uIERldGFpbHMKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisgIC8vLyBUaGlzIGVtaXRzIHZpc2liaWxpdHkgaW5mb3JtYXRpb24gYWJvdXQgc3ltYm9sLCBpZiB0aGlzIGlzIHN1cHBvcnRlZCBieQorICAvLy8gdGhlIHRhcmdldC4KKyAgdm9pZCBFbWl0VmlzaWJpbGl0eShNQ1N5bWJvbCAqU3ltLCB1bnNpZ25lZCBWaXNpYmlsaXR5LAorICAgICAgICAgICAgICAgICAgICAgIGJvb2wgSXNEZWZpbml0aW9uID0gdHJ1ZSkgY29uc3Q7CisKKyAgdm9pZCBFbWl0TGlua2FnZShjb25zdCBHbG9iYWxWYWx1ZSAqR1YsIE1DU3ltYm9sICpHVlN5bSkgY29uc3Q7CisKKyAgdm9pZCBFbWl0SnVtcFRhYmxlRW50cnkoY29uc3QgTWFjaGluZUp1bXBUYWJsZUluZm8gKk1KVEksCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIsIHVuc2lnbmVkIHVpZCkgY29uc3Q7CisgIHZvaWQgRW1pdExMVk1Vc2VkTGlzdChjb25zdCBDb25zdGFudEFycmF5ICpJbml0TGlzdCk7CisgIC8vLyBFbWl0IGxsdm0uaWRlbnQgbWV0YWRhdGEgaW4gYW4gJy5pZGVudCcgZGlyZWN0aXZlLgorICB2b2lkIEVtaXRNb2R1bGVJZGVudHMoTW9kdWxlICZNKTsKKyAgdm9pZCBFbWl0WFhTdHJ1Y3Rvckxpc3QoY29uc3QgRGF0YUxheW91dCAmREwsIGNvbnN0IENvbnN0YW50ICpMaXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzQ3Rvcik7CisKKyAgR0NNZXRhZGF0YVByaW50ZXIgKkdldE9yQ3JlYXRlR0NQcmludGVyKEdDU3RyYXRlZ3kgJkMpOworICAvLy8gRW1pdCBHbG9iYWxBbGlhcyBvciBHbG9iYWxJRnVuYy4KKyAgdm9pZCBlbWl0R2xvYmFsSW5kaXJlY3RTeW1ib2woTW9kdWxlICZNLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBHbG9iYWxJbmRpcmVjdFN5bWJvbCYgR0lTKTsKKyAgdm9pZCBzZXR1cENvZGVQYWRkaW5nQ29udGV4dChjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAmTUJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1DQ29kZVBhZGRpbmdDb250ZXh0ICZDb250ZXh0KSBjb25zdDsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fQVNNUFJJTlRFUl9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vQXRvbWljRXhwYW5kVXRpbHMuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9BdG9taWNFeHBhbmRVdGlscy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFmOWM5NmIKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vQXRvbWljRXhwYW5kVXRpbHMuaApAQCAtMCwwICsxLDY1IEBACisvLz09PS0gQXRvbWljRXhwYW5kVXRpbHMuaCAtIFV0aWxpdGllcyBmb3IgZXhwYW5kaW5nIGF0b21pYyBpbnN0cnVjdGlvbnMgLS09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9BVE9NSUNFWFBBTkRVVElMU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9BVE9NSUNFWFBBTkRVVElMU19ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9TVExFeHRyYXMuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0lSQnVpbGRlci5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9BdG9taWNPcmRlcmluZy5oIgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIEF0b21pY1JNV0luc3Q7CitjbGFzcyBWYWx1ZTsKKworLy8vIFBhcmFtZXRlcnMgKHNlZSB0aGUgZXhwYW5zaW9uIGV4YW1wbGUgYmVsb3cpOgorLy8vICh0aGUgYnVpbGRlciwgJWFkZHIsICVsb2FkZWQsICVuZXdfdmFsLCBvcmRlcmluZywKKy8vLyAgLyogT1VUICovICVzdWNjZXNzLCAvKiBPVVQgKi8gJW5ld19sb2FkZWQpCit1c2luZyBDcmVhdGVDbXBYY2hnSW5zdEZ1biA9CisgICAgZnVuY3Rpb25fcmVmPHZvaWQoSVJCdWlsZGVyPD4gJiwgVmFsdWUgKiwgVmFsdWUgKiwgVmFsdWUgKiwgQXRvbWljT3JkZXJpbmcsCisgICAgICAgICAgICAgICAgICAgICAgVmFsdWUgKiYsIFZhbHVlIComKT47CisKKy8vLyBcYnJpZWYgRXhwYW5kIGFuIGF0b21pYyBSTVcgaW5zdHJ1Y3Rpb24gaW50byBhIGxvb3AgdXRpbGl6aW5nCisvLy8gY21weGNoZy4gWW91J2xsIHdhbnQgdG8gbWFrZSBzdXJlIHlvdXIgdGFyZ2V0IG1hY2hpbmUgbGlrZXMgY21weGNoZworLy8vIGluc3RydWN0aW9ucyBpbiB0aGUgZmlyc3QgcGxhY2UgYW5kIHRoYXQgdGhlcmUgaXNuJ3QgYW5vdGhlciwgYmV0dGVyLAorLy8vIHRyYW5zZm9ybWF0aW9uIGF2YWlsYWJsZSAoZm9yIGV4YW1wbGUgQUFyY2gzMi9BQXJjaDY0IGhhdmUgbGlua2VkIGxvYWRzKS4KKy8vLworLy8vIFRoaXMgaXMgdXNlZnVsIGluIHBhc3NlcyB3aGljaCBjYW4ndCByZXdyaXRlIHRoZSBtb3JlIGV4b3RpYyBSTVcKKy8vLyBpbnN0cnVjdGlvbnMgZGlyZWN0bHkgaW50byBhIHBsYXRmb3JtIHNwZWNpZmljIGludHJpbnNpY3MgKGJlY2F1c2UsIHNheSwKKy8vLyB0aG9zZSBpbnRyaW5zaWNzIGRvbid0IGV4aXN0KS4gSWYgc3VjaCBhIHBhc3MgaXMgYWJsZSB0byBleHBhbmQgY21weGNoZworLy8vIGluc3RydWN0aW9ucyBkaXJlY3RseSBob3dldmVyLCB0aGVuLCB3aXRoIHRoaXMgZnVuY3Rpb24sIGl0IGNvdWxkIGF2b2lkIHR3bworLy8vIGV4dHJhIG1vZHVsZSBwYXNzZXMgKGF2b2lkaW5nIHBhc3NlcyBieSBgLWF0b21pYy1leHBhbmRgIGFuZCBpdHNlbGYpLiBBCisvLy8gc3BlY2lmaWMgZXhhbXBsZSB3b3VsZCBiZSBQTmFDbCdzIGBSZXdyaXRlQXRvbWljc2AgcGFzcy4KKy8vLworLy8vIEdpdmVuOiBhdG9taWNybXcgc29tZV9vcCBpTiogJWFkZHIsIGlOICVpbmNyIG9yZGVyaW5nCisvLy8KKy8vLyBUaGUgc3RhbmRhcmQgZXhwYW5zaW9uIHdlIHByb2R1Y2UgaXM6CisvLy8gICAgIFsuLi5dCisvLy8gICAgICVpbml0X2xvYWRlZCA9IGxvYWQgYXRvbWljIGlOKiAlYWRkcgorLy8vICAgICBiciBsYWJlbCAlbG9vcAorLy8vIGxvb3A6CisvLy8gICAgICVsb2FkZWQgPSBwaGkgaU4gWyAlaW5pdF9sb2FkZWQsICVlbnRyeSBdLCBbICVuZXdfbG9hZGVkLCAlbG9vcCBdCisvLy8gICAgICVuZXcgPSBzb21lX29wIGlOICVsb2FkZWQsICVpbmNyCisvLy8gOyBUaGlzIGlzIHdoYXQgLWF0b21pYy1leHBhbmQgd2lsbCBwcm9kdWNlIHVzaW5nIHRoaXMgZnVuY3Rpb24gb24gaTY4NgorLy8vIHRhcmdldHM6CisvLy8gICAgICVwYWlyID0gY21weGNoZyBpTiogJWFkZHIsIGlOICVsb2FkZWQsIGlOICVuZXdfdmFsCisvLy8gICAgICVuZXdfbG9hZGVkID0gZXh0cmFjdHZhbHVlIHsgaU4sIGkxIH0gJXBhaXIsIDAKKy8vLyAgICAgJXN1Y2Nlc3MgPSBleHRyYWN0dmFsdWUgeyBpTiwgaTEgfSAlcGFpciwgMQorLy8vIDsgRW5kIGNhbGxiYWNrIHByb2R1Y2VkIElSCisvLy8gICAgIGJyIGkxICVzdWNjZXNzLCBsYWJlbCAlYXRvbWljcm13LmVuZCwgbGFiZWwgJWxvb3AKKy8vLyBhdG9taWNybXcuZW5kOgorLy8vICAgICBbLi4uXQorLy8vCisvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBjb250YWluaW5nIGZ1bmN0aW9uIHdhcyBtb2RpZmllZC4KK2Jvb2wgZXhwYW5kQXRvbWljUk1XVG9DbXBYY2hnKEF0b21pY1JNV0luc3QgKkFJLCBDcmVhdGVDbXBYY2hnSW5zdEZ1biBGYWN0b3J5KTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9BVE9NSUNFWFBBTkRVVElMU19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vQmFzaWNUVElJbXBsLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vQmFzaWNUVElJbXBsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTA5NjI2MwotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9CYXNpY1RUSUltcGwuaApAQCAtMCwwICsxLDEzODMgQEAKKy8vPT09LSBCYXNpY1RUSUltcGwuaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8vIFxmaWxlCisvLy8gVGhpcyBmaWxlIHByb3ZpZGVzIGEgaGVscGVyIHRoYXQgaW1wbGVtZW50cyBtdWNoIG9mIHRoZSBUVEkgaW50ZXJmYWNlIGluCisvLy8gdGVybXMgb2YgdGhlIHRhcmdldC1pbmRlcGVuZGVudCBjb2RlIGdlbmVyYXRvciBhbmQgVGFyZ2V0TG93ZXJpbmcKKy8vLyBpbnRlcmZhY2VzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0JBU0lDVFRJSU1QTF9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9CQVNJQ1RUSUlNUExfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvQVBJbnQuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9BcnJheVJlZi5oIgorI2luY2x1ZGUgImxsdm0vQURUL0JpdFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsUHRyU2V0LmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FuYWx5c2lzL0xvb3BJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9BbmFseXNpcy9UYXJnZXRUcmFuc2Zvcm1JbmZvLmgiCisjaW5jbHVkZSAibGx2bS9BbmFseXNpcy9UYXJnZXRUcmFuc2Zvcm1JbmZvSW1wbC5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9JU0RPcGNvZGVzLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1RhcmdldExvd2VyaW5nLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1RhcmdldFN1YnRhcmdldEluZm8uaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVmFsdWVUeXBlcy5oIgorI2luY2x1ZGUgImxsdm0vSVIvQmFzaWNCbG9jay5oIgorI2luY2x1ZGUgImxsdm0vSVIvQ2FsbFNpdGUuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0NvbnN0YW50LmgiCisjaW5jbHVkZSAibGx2bS9JUi9Db25zdGFudHMuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0RhdGFMYXlvdXQuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0Rlcml2ZWRUeXBlcy5oIgorI2luY2x1ZGUgImxsdm0vSVIvSW5zdHJUeXBlcy5oIgorI2luY2x1ZGUgImxsdm0vSVIvSW5zdHJ1Y3Rpb24uaCIKKyNpbmNsdWRlICJsbHZtL0lSL0luc3RydWN0aW9ucy5oIgorI2luY2x1ZGUgImxsdm0vSVIvSW50cmluc2ljcy5oIgorI2luY2x1ZGUgImxsdm0vSVIvT3BlcmF0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0lSL1R5cGUuaCIKKyNpbmNsdWRlICJsbHZtL0lSL1ZhbHVlLmgiCisjaW5jbHVkZSAibGx2bS9NQy9NQ1NjaGVkdWxlLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0Nhc3RpbmcuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvQ29tbWFuZExpbmUuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvRXJyb3JIYW5kbGluZy5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9NYWNoaW5lVmFsdWVUeXBlLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L01hdGhFeHRyYXMuaCIKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPGxpbWl0cz4KKyNpbmNsdWRlIDx1dGlsaXR5PgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIEZ1bmN0aW9uOworY2xhc3MgR2xvYmFsVmFsdWU7CitjbGFzcyBMTFZNQ29udGV4dDsKK2NsYXNzIFNjYWxhckV2b2x1dGlvbjsKK2NsYXNzIFNDRVY7CitjbGFzcyBUYXJnZXRNYWNoaW5lOworCitleHRlcm4gY2w6Om9wdDx1bnNpZ25lZD4gUGFydGlhbFVucm9sbGluZ1RocmVzaG9sZDsKKworLy8vIFxicmllZiBCYXNlIGNsYXNzIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGhlbHAgYnVpbGQgYSBUVEkgaW1wbGVtZW50YXRpb24uCisvLy8KKy8vLyBUaGlzIGNsYXNzIHByb3ZpZGVzIGFzIG11Y2ggaW1wbGVtZW50YXRpb24gb2YgdGhlIFRUSSBpbnRlcmZhY2UgYXMgaXMKKy8vLyBwb3NzaWJsZSB1c2luZyB0aGUgdGFyZ2V0IGluZGVwZW5kZW50IHBhcnRzIG9mIHRoZSBjb2RlIGdlbmVyYXRvci4KKy8vLworLy8vIEluIG9yZGVyIHRvIHN1YmNsYXNzIGl0LCB5b3VyIGNsYXNzIG11c3QgaW1wbGVtZW50IGEgZ2V0U1QoKSBtZXRob2QgdG8KKy8vLyByZXR1cm4gdGhlIHN1YnRhcmdldCwgYW5kIGEgZ2V0VExJKCkgbWV0aG9kIHRvIHJldHVybiB0aGUgdGFyZ2V0IGxvd2VyaW5nLgorLy8vIFdlIG5lZWQgdGhlc2UgbWV0aG9kcyBpbXBsZW1lbnRlZCBpbiB0aGUgZGVyaXZlZCBjbGFzcyBzbyB0aGF0IHRoaXMgY2xhc3MKKy8vLyBkb2Vzbid0IGhhdmUgdG8gZHVwbGljYXRlIHN0b3JhZ2UgZm9yIHRoZW0uCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KK2NsYXNzIEJhc2ljVFRJSW1wbEJhc2UgOiBwdWJsaWMgVGFyZ2V0VHJhbnNmb3JtSW5mb0ltcGxDUlRQQmFzZTxUPiB7Citwcml2YXRlOgorICB1c2luZyBCYXNlVCA9IFRhcmdldFRyYW5zZm9ybUluZm9JbXBsQ1JUUEJhc2U8VD47CisgIHVzaW5nIFRUSSA9IFRhcmdldFRyYW5zZm9ybUluZm87CisKKyAgLy8vIEVzdGltYXRlIGEgY29zdCBvZiBzaHVmZmxlIGFzIGEgc2VxdWVuY2Ugb2YgZXh0cmFjdCBhbmQgaW5zZXJ0CisgIC8vLyBvcGVyYXRpb25zLgorICB1bnNpZ25lZCBnZXRQZXJtdXRlU2h1ZmZsZU92ZXJoZWFkKFR5cGUgKlR5KSB7CisgICAgYXNzZXJ0KFR5LT5pc1ZlY3RvclR5KCkgJiYgIkNhbiBvbmx5IHNodWZmbGUgdmVjdG9ycyIpOworICAgIHVuc2lnbmVkIENvc3QgPSAwOworICAgIC8vIFNodWZmbGUgY29zdCBpcyBlcXVhbCB0byB0aGUgY29zdCBvZiBleHRyYWN0aW5nIGVsZW1lbnQgZnJvbSBpdHMgYXJndW1lbnQKKyAgICAvLyBwbHVzIHRoZSBjb3N0IG9mIGluc2VydGluZyB0aGVtIG9udG8gdGhlIHJlc3VsdCB2ZWN0b3IuCisKKyAgICAvLyBlLmcuIDw0IHggZmxvYXQ+IGhhcyBhIG1hc2sgb2YgPDAsNSwyLDc+IGkuZSB3ZSBuZWVkIHRvIGV4dHJhY3QgZnJvbQorICAgIC8vIGluZGV4IDAgb2YgZmlyc3QgdmVjdG9yLCBpbmRleCAxIG9mIHNlY29uZCB2ZWN0b3IsaW5kZXggMiBvZiBmaXJzdAorICAgIC8vIHZlY3RvciBhbmQgZmluYWxseSBpbmRleCAzIG9mIHNlY29uZCB2ZWN0b3IgYW5kIGluc2VydCB0aGVtIGF0IGluZGV4CisgICAgLy8gPDAsMSwyLDM+IG9mIHJlc3VsdCB2ZWN0b3IuCisgICAgZm9yIChpbnQgaSA9IDAsIGUgPSBUeS0+Z2V0VmVjdG9yTnVtRWxlbWVudHMoKTsgaSA8IGU7ICsraSkgeworICAgICAgQ29zdCArPSBzdGF0aWNfY2FzdDxUICo+KHRoaXMpCisgICAgICAgICAgICAgICAgICAtPmdldFZlY3Rvckluc3RyQ29zdChJbnN0cnVjdGlvbjo6SW5zZXJ0RWxlbWVudCwgVHksIGkpOworICAgICAgQ29zdCArPSBzdGF0aWNfY2FzdDxUICo+KHRoaXMpCisgICAgICAgICAgICAgICAgICAtPmdldFZlY3Rvckluc3RyQ29zdChJbnN0cnVjdGlvbjo6RXh0cmFjdEVsZW1lbnQsIFR5LCBpKTsKKyAgICB9CisgICAgcmV0dXJuIENvc3Q7CisgIH0KKworICAvLy8gXGJyaWVmIExvY2FsIHF1ZXJ5IG1ldGhvZCBkZWxlZ2F0ZXMgdXAgdG8gVCB3aGljaCAqbXVzdCogaW1wbGVtZW50IHRoaXMhCisgIGNvbnN0IFRhcmdldFN1YnRhcmdldEluZm8gKmdldFNUKCkgY29uc3QgeworICAgIHJldHVybiBzdGF0aWNfY2FzdDxjb25zdCBUICo+KHRoaXMpLT5nZXRTVCgpOworICB9CisKKyAgLy8vIFxicmllZiBMb2NhbCBxdWVyeSBtZXRob2QgZGVsZWdhdGVzIHVwIHRvIFQgd2hpY2ggKm11c3QqIGltcGxlbWVudCB0aGlzIQorICBjb25zdCBUYXJnZXRMb3dlcmluZ0Jhc2UgKmdldFRMSSgpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8Y29uc3QgVCAqPih0aGlzKS0+Z2V0VExJKCk7CisgIH0KKworICBzdGF0aWMgSVNEOjpNZW1JbmRleGVkTW9kZSBnZXRJU0RJbmRleGVkTW9kZShUVEk6Ok1lbUluZGV4ZWRNb2RlIE0pIHsKKyAgICBzd2l0Y2ggKE0pIHsKKyAgICAgIGNhc2UgVFRJOjpNSU1fVW5pbmRleGVkOgorICAgICAgICByZXR1cm4gSVNEOjpVTklOREVYRUQ7CisgICAgICBjYXNlIFRUSTo6TUlNX1ByZUluYzoKKyAgICAgICAgcmV0dXJuIElTRDo6UFJFX0lOQzsKKyAgICAgIGNhc2UgVFRJOjpNSU1fUHJlRGVjOgorICAgICAgICByZXR1cm4gSVNEOjpQUkVfREVDOworICAgICAgY2FzZSBUVEk6Ok1JTV9Qb3N0SW5jOgorICAgICAgICByZXR1cm4gSVNEOjpQT1NUX0lOQzsKKyAgICAgIGNhc2UgVFRJOjpNSU1fUG9zdERlYzoKKyAgICAgICAgcmV0dXJuIElTRDo6UE9TVF9ERUM7CisgICAgfQorICAgIGxsdm1fdW5yZWFjaGFibGUoIlVuZXhwZWN0ZWQgTWVtSW5kZXhlZE1vZGUiKTsKKyAgfQorCitwcm90ZWN0ZWQ6CisgIGV4cGxpY2l0IEJhc2ljVFRJSW1wbEJhc2UoY29uc3QgVGFyZ2V0TWFjaGluZSAqVE0sIGNvbnN0IERhdGFMYXlvdXQgJkRMKQorICAgICAgOiBCYXNlVChETCkge30KKworICB1c2luZyBUYXJnZXRUcmFuc2Zvcm1JbmZvSW1wbEJhc2U6OkRMOworCitwdWJsaWM6CisgIC8vLyBcbmFtZSBTY2FsYXIgVFRJIEltcGxlbWVudGF0aW9ucworICAvLy8gQHsKKyAgYm9vbCBhbGxvd3NNaXNhbGlnbmVkTWVtb3J5QWNjZXNzZXMoTExWTUNvbnRleHQgJkNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIEJpdFdpZHRoLCB1bnNpZ25lZCBBZGRyZXNzU3BhY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIEFsaWdubWVudCwgYm9vbCAqRmFzdCkgY29uc3QgeworICAgIEVWVCBFID0gRVZUOjpnZXRJbnRlZ2VyVlQoQ29udGV4dCwgQml0V2lkdGgpOworICAgIHJldHVybiBnZXRUTEkoKS0+YWxsb3dzTWlzYWxpZ25lZE1lbW9yeUFjY2Vzc2VzKEUsIEFkZHJlc3NTcGFjZSwgQWxpZ25tZW50LCBGYXN0KTsKKyAgfQorCisgIGJvb2wgaGFzQnJhbmNoRGl2ZXJnZW5jZSgpIHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgYm9vbCBpc1NvdXJjZU9mRGl2ZXJnZW5jZShjb25zdCBWYWx1ZSAqVikgeyByZXR1cm4gZmFsc2U7IH0KKworICBib29sIGlzQWx3YXlzVW5pZm9ybShjb25zdCBWYWx1ZSAqVikgeyByZXR1cm4gZmFsc2U7IH0KKworICB1bnNpZ25lZCBnZXRGbGF0QWRkcmVzc1NwYWNlKCkgeworICAgIC8vIFJldHVybiBhbiBpbnZhbGlkIGFkZHJlc3Mgc3BhY2UuCisgICAgcmV0dXJuIC0xOworICB9CisKKyAgYm9vbCBpc0xlZ2FsQWRkSW1tZWRpYXRlKGludDY0X3QgaW1tKSB7CisgICAgcmV0dXJuIGdldFRMSSgpLT5pc0xlZ2FsQWRkSW1tZWRpYXRlKGltbSk7CisgIH0KKworICBib29sIGlzTGVnYWxJQ21wSW1tZWRpYXRlKGludDY0X3QgaW1tKSB7CisgICAgcmV0dXJuIGdldFRMSSgpLT5pc0xlZ2FsSUNtcEltbWVkaWF0ZShpbW0pOworICB9CisKKyAgYm9vbCBpc0xlZ2FsQWRkcmVzc2luZ01vZGUoVHlwZSAqVHksIEdsb2JhbFZhbHVlICpCYXNlR1YsIGludDY0X3QgQmFzZU9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBIYXNCYXNlUmVnLCBpbnQ2NF90IFNjYWxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBBZGRyU3BhY2UsIEluc3RydWN0aW9uICpJID0gbnVsbHB0cikgeworICAgIFRhcmdldExvd2VyaW5nQmFzZTo6QWRkck1vZGUgQU07CisgICAgQU0uQmFzZUdWID0gQmFzZUdWOworICAgIEFNLkJhc2VPZmZzID0gQmFzZU9mZnNldDsKKyAgICBBTS5IYXNCYXNlUmVnID0gSGFzQmFzZVJlZzsKKyAgICBBTS5TY2FsZSA9IFNjYWxlOworICAgIHJldHVybiBnZXRUTEkoKS0+aXNMZWdhbEFkZHJlc3NpbmdNb2RlKERMLCBBTSwgVHksIEFkZHJTcGFjZSwgSSk7CisgIH0KKworICBib29sIGlzSW5kZXhlZExvYWRMZWdhbChUVEk6Ok1lbUluZGV4ZWRNb2RlIE0sIFR5cGUgKlR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEYXRhTGF5b3V0ICZETCkgY29uc3QgeworICAgIEVWVCBWVCA9IGdldFRMSSgpLT5nZXRWYWx1ZVR5cGUoREwsIFR5KTsKKyAgICByZXR1cm4gZ2V0VExJKCktPmlzSW5kZXhlZExvYWRMZWdhbChnZXRJU0RJbmRleGVkTW9kZShNKSwgVlQpOworICB9CisKKyAgYm9vbCBpc0luZGV4ZWRTdG9yZUxlZ2FsKFRUSTo6TWVtSW5kZXhlZE1vZGUgTSwgVHlwZSAqVHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEYXRhTGF5b3V0ICZETCkgY29uc3QgeworICAgIEVWVCBWVCA9IGdldFRMSSgpLT5nZXRWYWx1ZVR5cGUoREwsIFR5KTsKKyAgICByZXR1cm4gZ2V0VExJKCktPmlzSW5kZXhlZFN0b3JlTGVnYWwoZ2V0SVNESW5kZXhlZE1vZGUoTSksIFZUKTsKKyAgfQorCisgIGJvb2wgaXNMU1JDb3N0TGVzcyhUVEk6OkxTUkNvc3QgQzEsIFRUSTo6TFNSQ29zdCBDMikgeworICAgIHJldHVybiBUYXJnZXRUcmFuc2Zvcm1JbmZvSW1wbEJhc2U6OmlzTFNSQ29zdExlc3MoQzEsIEMyKTsKKyAgfQorCisgIGludCBnZXRTY2FsaW5nRmFjdG9yQ29zdChUeXBlICpUeSwgR2xvYmFsVmFsdWUgKkJhc2VHViwgaW50NjRfdCBCYXNlT2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBIYXNCYXNlUmVnLCBpbnQ2NF90IFNjYWxlLCB1bnNpZ25lZCBBZGRyU3BhY2UpIHsKKyAgICBUYXJnZXRMb3dlcmluZ0Jhc2U6OkFkZHJNb2RlIEFNOworICAgIEFNLkJhc2VHViA9IEJhc2VHVjsKKyAgICBBTS5CYXNlT2ZmcyA9IEJhc2VPZmZzZXQ7CisgICAgQU0uSGFzQmFzZVJlZyA9IEhhc0Jhc2VSZWc7CisgICAgQU0uU2NhbGUgPSBTY2FsZTsKKyAgICByZXR1cm4gZ2V0VExJKCktPmdldFNjYWxpbmdGYWN0b3JDb3N0KERMLCBBTSwgVHksIEFkZHJTcGFjZSk7CisgIH0KKworICBib29sIGlzVHJ1bmNhdGVGcmVlKFR5cGUgKlR5MSwgVHlwZSAqVHkyKSB7CisgICAgcmV0dXJuIGdldFRMSSgpLT5pc1RydW5jYXRlRnJlZShUeTEsIFR5Mik7CisgIH0KKworICBib29sIGlzUHJvZml0YWJsZVRvSG9pc3QoSW5zdHJ1Y3Rpb24gKkkpIHsKKyAgICByZXR1cm4gZ2V0VExJKCktPmlzUHJvZml0YWJsZVRvSG9pc3QoSSk7CisgIH0KKworICBib29sIHVzZUFBKCkgY29uc3QgeyByZXR1cm4gZ2V0U1QoKS0+dXNlQUEoKTsgfQorCisgIGJvb2wgaXNUeXBlTGVnYWwoVHlwZSAqVHkpIHsKKyAgICBFVlQgVlQgPSBnZXRUTEkoKS0+Z2V0VmFsdWVUeXBlKERMLCBUeSk7CisgICAgcmV0dXJuIGdldFRMSSgpLT5pc1R5cGVMZWdhbChWVCk7CisgIH0KKworICBpbnQgZ2V0R0VQQ29zdChUeXBlICpQb2ludGVlVHlwZSwgY29uc3QgVmFsdWUgKlB0ciwKKyAgICAgICAgICAgICAgICAgQXJyYXlSZWY8Y29uc3QgVmFsdWUgKj4gT3BlcmFuZHMpIHsKKyAgICByZXR1cm4gQmFzZVQ6OmdldEdFUENvc3QoUG9pbnRlZVR5cGUsIFB0ciwgT3BlcmFuZHMpOworICB9CisKKyAgaW50IGdldEV4dENvc3QoY29uc3QgSW5zdHJ1Y3Rpb24gKkksIGNvbnN0IFZhbHVlICpTcmMpIHsKKyAgICBpZiAoZ2V0VExJKCktPmlzRXh0RnJlZShJKSkKKyAgICAgIHJldHVybiBUYXJnZXRUcmFuc2Zvcm1JbmZvOjpUQ0NfRnJlZTsKKworICAgIGlmIChpc2E8WkV4dEluc3Q+KEkpIHx8IGlzYTxTRXh0SW5zdD4oSSkpCisgICAgICBpZiAoY29uc3QgTG9hZEluc3QgKkxJID0gZHluX2Nhc3Q8TG9hZEluc3Q+KFNyYykpCisgICAgICAgIGlmIChnZXRUTEkoKS0+aXNFeHRMb2FkKExJLCBJLCBETCkpCisgICAgICAgICAgcmV0dXJuIFRhcmdldFRyYW5zZm9ybUluZm86OlRDQ19GcmVlOworCisgICAgcmV0dXJuIFRhcmdldFRyYW5zZm9ybUluZm86OlRDQ19CYXNpYzsKKyAgfQorCisgIHVuc2lnbmVkIGdldEludHJpbnNpY0Nvc3QoSW50cmluc2ljOjpJRCBJSUQsIFR5cGUgKlJldFR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPGNvbnN0IFZhbHVlICo+IEFyZ3VtZW50cykgeworICAgIHJldHVybiBCYXNlVDo6Z2V0SW50cmluc2ljQ29zdChJSUQsIFJldFR5LCBBcmd1bWVudHMpOworICB9CisKKyAgdW5zaWduZWQgZ2V0SW50cmluc2ljQ29zdChJbnRyaW5zaWM6OklEIElJRCwgVHlwZSAqUmV0VHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8VHlwZSAqPiBQYXJhbVR5cykgeworICAgIGlmIChJSUQgPT0gSW50cmluc2ljOjpjdHR6KSB7CisgICAgICBpZiAoZ2V0VExJKCktPmlzQ2hlYXBUb1NwZWN1bGF0ZUN0dHooKSkKKyAgICAgICAgcmV0dXJuIFRhcmdldFRyYW5zZm9ybUluZm86OlRDQ19CYXNpYzsKKyAgICAgIHJldHVybiBUYXJnZXRUcmFuc2Zvcm1JbmZvOjpUQ0NfRXhwZW5zaXZlOworICAgIH0KKworICAgIGlmIChJSUQgPT0gSW50cmluc2ljOjpjdGx6KSB7CisgICAgICBpZiAoZ2V0VExJKCktPmlzQ2hlYXBUb1NwZWN1bGF0ZUN0bHooKSkKKyAgICAgICAgcmV0dXJuIFRhcmdldFRyYW5zZm9ybUluZm86OlRDQ19CYXNpYzsKKyAgICAgIHJldHVybiBUYXJnZXRUcmFuc2Zvcm1JbmZvOjpUQ0NfRXhwZW5zaXZlOworICAgIH0KKworICAgIHJldHVybiBCYXNlVDo6Z2V0SW50cmluc2ljQ29zdChJSUQsIFJldFR5LCBQYXJhbVR5cyk7CisgIH0KKworICB1bnNpZ25lZCBnZXRFc3RpbWF0ZWROdW1iZXJPZkNhc2VDbHVzdGVycyhjb25zdCBTd2l0Y2hJbnN0ICZTSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgJkp1bXBUYWJsZVNpemUpIHsKKyAgICAvLy8gVHJ5IHRvIGZpbmQgdGhlIGVzdGltYXRlZCBudW1iZXIgb2YgY2x1c3RlcnMuIE5vdGUgdGhhdCB0aGUgbnVtYmVyIG9mCisgICAgLy8vIGNsdXN0ZXJzIGlkZW50aWZpZWQgaW4gdGhpcyBmdW5jdGlvbiBjb3VsZCBiZSBkaWZmZXJlbnQgZnJvbSB0aGUgYWN0dXJhbAorICAgIC8vLyBudW1iZXJzIGZvdW5kIGluIGxvd2VyaW5nLiBUaGlzIGZ1bmN0aW9uIGlnbm9yZSBzd2l0Y2hlcyB0aGF0IGFyZQorICAgIC8vLyBsb3dlcmVkIHdpdGggYSBtaXggb2YganVtcCB0YWJsZSAvIGJpdCB0ZXN0IC8gQlRyZWUuIFRoaXMgZnVuY3Rpb24gd2FzCisgICAgLy8vIGluaXRpYWxseSBpbnRlbmRlZCB0byBiZSB1c2VkIHdoZW4gZXN0aW1hdGluZyB0aGUgY29zdCBvZiBzd2l0Y2ggaW4KKyAgICAvLy8gaW5saW5lIGNvc3QgaGV1cmlzdGljLCBidXQgaXQncyBhIGdlbmVyaWMgY29zdCBtb2RlbCB0byBiZSB1c2VkIGluIG90aGVyCisgICAgLy8vIHBsYWNlcyAoZS5nLiwgaW4gbG9vcCB1bnJvbGxpbmcpLgorICAgIHVuc2lnbmVkIE4gPSBTSS5nZXROdW1DYXNlcygpOworICAgIGNvbnN0IFRhcmdldExvd2VyaW5nQmFzZSAqVExJID0gZ2V0VExJKCk7CisgICAgY29uc3QgRGF0YUxheW91dCAmREwgPSB0aGlzLT5nZXREYXRhTGF5b3V0KCk7CisKKyAgICBKdW1wVGFibGVTaXplID0gMDsKKyAgICBib29sIElzSlRBbGxvd2VkID0gVExJLT5hcmVKVHNBbGxvd2VkKFNJLmdldFBhcmVudCgpLT5nZXRQYXJlbnQoKSk7CisKKyAgICAvLyBFYXJseSBleGl0IGlmIGJvdGggYSBqdW1wIHRhYmxlIGFuZCBiaXQgdGVzdCBhcmUgbm90IGFsbG93ZWQuCisgICAgaWYgKE4gPCAxIHx8ICghSXNKVEFsbG93ZWQgJiYgREwuZ2V0SW5kZXhTaXplSW5CaXRzKDB1KSA8IE4pKQorICAgICAgcmV0dXJuIE47CisKKyAgICBBUEludCBNYXhDYXNlVmFsID0gU0kuY2FzZV9iZWdpbigpLT5nZXRDYXNlVmFsdWUoKS0+Z2V0VmFsdWUoKTsKKyAgICBBUEludCBNaW5DYXNlVmFsID0gTWF4Q2FzZVZhbDsKKyAgICBmb3IgKGF1dG8gQ0kgOiBTSS5jYXNlcygpKSB7CisgICAgICBjb25zdCBBUEludCAmQ2FzZVZhbCA9IENJLmdldENhc2VWYWx1ZSgpLT5nZXRWYWx1ZSgpOworICAgICAgaWYgKENhc2VWYWwuc2d0KE1heENhc2VWYWwpKQorICAgICAgICBNYXhDYXNlVmFsID0gQ2FzZVZhbDsKKyAgICAgIGlmIChDYXNlVmFsLnNsdChNaW5DYXNlVmFsKSkKKyAgICAgICAgTWluQ2FzZVZhbCA9IENhc2VWYWw7CisgICAgfQorCisgICAgLy8gQ2hlY2sgaWYgc3VpdGFibGUgZm9yIGEgYml0IHRlc3QKKyAgICBpZiAoTiA8PSBETC5nZXRJbmRleFNpemVJbkJpdHMoMHUpKSB7CisgICAgICBTbWFsbFB0clNldDxjb25zdCBCYXNpY0Jsb2NrICosIDQ+IERlc3RzOworICAgICAgZm9yIChhdXRvIEkgOiBTSS5jYXNlcygpKQorICAgICAgICBEZXN0cy5pbnNlcnQoSS5nZXRDYXNlU3VjY2Vzc29yKCkpOworCisgICAgICBpZiAoVExJLT5pc1N1aXRhYmxlRm9yQml0VGVzdHMoRGVzdHMuc2l6ZSgpLCBOLCBNaW5DYXNlVmFsLCBNYXhDYXNlVmFsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERMKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgLy8gQ2hlY2sgaWYgc3VpdGFibGUgZm9yIGEganVtcCB0YWJsZS4KKyAgICBpZiAoSXNKVEFsbG93ZWQpIHsKKyAgICAgIGlmIChOIDwgMiB8fCBOIDwgVExJLT5nZXRNaW5pbXVtSnVtcFRhYmxlRW50cmllcygpKQorICAgICAgICByZXR1cm4gTjsKKyAgICAgIHVpbnQ2NF90IFJhbmdlID0KKyAgICAgICAgICAoTWF4Q2FzZVZhbCAtIE1pbkNhc2VWYWwpCisgICAgICAgICAgICAgIC5nZXRMaW1pdGVkVmFsdWUoc3RkOjpudW1lcmljX2xpbWl0czx1aW50NjRfdD46Om1heCgpIC0gMSkgKyAxOworICAgICAgLy8gQ2hlY2sgd2hldGhlciBhIHJhbmdlIG9mIGNsdXN0ZXJzIGlzIGRlbnNlIGVub3VnaCBmb3IgYSBqdW1wIHRhYmxlCisgICAgICBpZiAoVExJLT5pc1N1aXRhYmxlRm9ySnVtcFRhYmxlKCZTSSwgTiwgUmFuZ2UpKSB7CisgICAgICAgIEp1bXBUYWJsZVNpemUgPSBSYW5nZTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBOOworICB9CisKKyAgdW5zaWduZWQgZ2V0SnVtcEJ1ZkFsaWdubWVudCgpIHsgcmV0dXJuIGdldFRMSSgpLT5nZXRKdW1wQnVmQWxpZ25tZW50KCk7IH0KKworICB1bnNpZ25lZCBnZXRKdW1wQnVmU2l6ZSgpIHsgcmV0dXJuIGdldFRMSSgpLT5nZXRKdW1wQnVmU2l6ZSgpOyB9CisKKyAgYm9vbCBzaG91bGRCdWlsZExvb2t1cFRhYmxlcygpIHsKKyAgICBjb25zdCBUYXJnZXRMb3dlcmluZ0Jhc2UgKlRMSSA9IGdldFRMSSgpOworICAgIHJldHVybiBUTEktPmlzT3BlcmF0aW9uTGVnYWxPckN1c3RvbShJU0Q6OkJSX0pULCBNVlQ6Ok90aGVyKSB8fAorICAgICAgICAgICBUTEktPmlzT3BlcmF0aW9uTGVnYWxPckN1c3RvbShJU0Q6OkJSSU5ELCBNVlQ6Ok90aGVyKTsKKyAgfQorCisgIGJvb2wgaGF2ZUZhc3RTcXJ0KFR5cGUgKlR5KSB7CisgICAgY29uc3QgVGFyZ2V0TG93ZXJpbmdCYXNlICpUTEkgPSBnZXRUTEkoKTsKKyAgICBFVlQgVlQgPSBUTEktPmdldFZhbHVlVHlwZShETCwgVHkpOworICAgIHJldHVybiBUTEktPmlzVHlwZUxlZ2FsKFZUKSAmJgorICAgICAgICAgICBUTEktPmlzT3BlcmF0aW9uTGVnYWxPckN1c3RvbShJU0Q6OkZTUVJULCBWVCk7CisgIH0KKworICBib29sIGlzRkNtcE9yZENoZWFwZXJUaGFuRkNtcFplcm8oVHlwZSAqVHkpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIHVuc2lnbmVkIGdldEZQT3BDb3N0KFR5cGUgKlR5KSB7CisgICAgLy8gQ2hlY2sgd2hldGhlciBGQUREIGlzIGF2YWlsYWJsZSwgYXMgYSBwcm94eSBmb3IgZmxvYXRpbmctcG9pbnQgaW4KKyAgICAvLyBnZW5lcmFsLgorICAgIGNvbnN0IFRhcmdldExvd2VyaW5nQmFzZSAqVExJID0gZ2V0VExJKCk7CisgICAgRVZUIFZUID0gVExJLT5nZXRWYWx1ZVR5cGUoREwsIFR5KTsKKyAgICBpZiAoVExJLT5pc09wZXJhdGlvbkxlZ2FsT3JDdXN0b21PclByb21vdGUoSVNEOjpGQURELCBWVCkpCisgICAgICByZXR1cm4gVGFyZ2V0VHJhbnNmb3JtSW5mbzo6VENDX0Jhc2ljOworICAgIHJldHVybiBUYXJnZXRUcmFuc2Zvcm1JbmZvOjpUQ0NfRXhwZW5zaXZlOworICB9CisKKyAgdW5zaWduZWQgZ2V0T3BlcmF0aW9uQ29zdCh1bnNpZ25lZCBPcGNvZGUsIFR5cGUgKlR5LCBUeXBlICpPcFR5KSB7CisgICAgY29uc3QgVGFyZ2V0TG93ZXJpbmdCYXNlICpUTEkgPSBnZXRUTEkoKTsKKyAgICBzd2l0Y2ggKE9wY29kZSkgeworICAgIGRlZmF1bHQ6IGJyZWFrOworICAgIGNhc2UgSW5zdHJ1Y3Rpb246OlRydW5jOgorICAgICAgaWYgKFRMSS0+aXNUcnVuY2F0ZUZyZWUoT3BUeSwgVHkpKQorICAgICAgICByZXR1cm4gVGFyZ2V0VHJhbnNmb3JtSW5mbzo6VENDX0ZyZWU7CisgICAgICByZXR1cm4gVGFyZ2V0VHJhbnNmb3JtSW5mbzo6VENDX0Jhc2ljOworICAgIGNhc2UgSW5zdHJ1Y3Rpb246OlpFeHQ6CisgICAgICBpZiAoVExJLT5pc1pFeHRGcmVlKE9wVHksIFR5KSkKKyAgICAgICAgcmV0dXJuIFRhcmdldFRyYW5zZm9ybUluZm86OlRDQ19GcmVlOworICAgICAgcmV0dXJuIFRhcmdldFRyYW5zZm9ybUluZm86OlRDQ19CYXNpYzsKKyAgICB9CisKKyAgICByZXR1cm4gQmFzZVQ6OmdldE9wZXJhdGlvbkNvc3QoT3Bjb2RlLCBUeSwgT3BUeSk7CisgIH0KKworICB1bnNpZ25lZCBnZXRJbmxpbmluZ1RocmVzaG9sZE11bHRpcGxpZXIoKSB7IHJldHVybiAxOyB9CisKKyAgdm9pZCBnZXRVbnJvbGxpbmdQcmVmZXJlbmNlcyhMb29wICpMLCBTY2FsYXJFdm9sdXRpb24gJlNFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRUSTo6VW5yb2xsaW5nUHJlZmVyZW5jZXMgJlVQKSB7CisgICAgLy8gVGhpcyB1bnJvbGxpbmcgZnVuY3Rpb25hbGl0eSBpcyB0YXJnZXQgaW5kZXBlbmRlbnQsIGJ1dCB0byBwcm92aWRlIHNvbWUKKyAgICAvLyBtb3RpdmF0aW9uIGZvciBpdHMgaW50ZW5kZWQgdXNlLCBmb3IgeDg2OgorCisgICAgLy8gQWNjb3JkaW5nIHRvIHRoZSBJbnRlbCA2NCBhbmQgSUEtMzIgQXJjaGl0ZWN0dXJlcyBPcHRpbWl6YXRpb24gUmVmZXJlbmNlCisgICAgLy8gTWFudWFsLCBJbnRlbCBDb3JlIG1vZGVscyBhbmQgbGF0ZXIgaGF2ZSBhIGxvb3Agc3RyZWFtIGRldGVjdG9yIChhbmQKKyAgICAvLyBhc3NvY2lhdGVkIHVvcCBxdWV1ZSkgdGhhdCBjYW4gYmVuZWZpdCBmcm9tIHBhcnRpYWwgdW5yb2xsaW5nLgorICAgIC8vIFRoZSByZWxldmFudCByZXF1aXJlbWVudHMgYXJlOgorICAgIC8vICAtIFRoZSBsb29wIG11c3QgaGF2ZSBubyBtb3JlIHRoYW4gNCAoOCBmb3IgTmVoYWxlbSBhbmQgbGF0ZXIpIGJyYW5jaGVzCisgICAgLy8gICAgdGFrZW4sIGFuZCBub25lIG9mIHRoZW0gbWF5IGJlIGNhbGxzLgorICAgIC8vICAtIFRoZSBsb29wIGNhbiBoYXZlIG5vIG1vcmUgdGhhbiAxOCAoMjggZm9yIE5laGFsZW0gYW5kIGxhdGVyKSB1b3BzLgorCisgICAgLy8gQWNjb3JkaW5nIHRvIHRoZSBTb2Z0d2FyZSBPcHRpbWl6YXRpb24gR3VpZGUgZm9yIEFNRCBGYW1pbHkgMTVoCisgICAgLy8gUHJvY2Vzc29ycywgbW9kZWxzIDMwaC00ZmggKFN0ZWFtcm9sbGVyIGFuZCBsYXRlcikgaGF2ZSBhIGxvb3AgcHJlZGljdG9yCisgICAgLy8gYW5kIGxvb3AgYnVmZmVyIHdoaWNoIGNhbiBiZW5lZml0IGZyb20gcGFydGlhbCB1bnJvbGxpbmcuCisgICAgLy8gVGhlIHJlbGV2YW50IHJlcXVpcmVtZW50cyBhcmU6CisgICAgLy8gIC0gVGhlIGxvb3AgbXVzdCBoYXZlIGZld2VyIHRoYW4gMTYgYnJhbmNoZXMKKyAgICAvLyAgLSBUaGUgbG9vcCBtdXN0IGhhdmUgbGVzcyB0aGFuIDQwIHVvcHMgaW4gYWxsIGV4ZWN1dGVkIGxvb3AgYnJhbmNoZXMKKworICAgIC8vIFRoZSBudW1iZXIgb2YgdGFrZW4gYnJhbmNoZXMgaW4gYSBsb29wIGlzIGhhcmQgdG8gZXN0aW1hdGUgaGVyZSwgYW5kCisgICAgLy8gYmVuY2htYXJraW5nIGhhcyByZXZlYWxlZCB0aGF0IGl0IGlzIGJldHRlciBub3QgdG8gYmUgY29uc2VydmF0aXZlIHdoZW4KKyAgICAvLyBlc3RpbWF0aW5nIHRoZSBicmFuY2ggY291bnQuIEFzIGEgcmVzdWx0LCB3ZSdsbCBpZ25vcmUgdGhlIGJyYW5jaCBsaW1pdHMKKyAgICAvLyB1bnRpbCBzb21lb25lIGZpbmRzIGEgY2FzZSB3aGVyZSBpdCBtYXR0ZXJzIGluIHByYWN0aWNlLgorCisgICAgdW5zaWduZWQgTWF4T3BzOworICAgIGNvbnN0IFRhcmdldFN1YnRhcmdldEluZm8gKlNUID0gZ2V0U1QoKTsKKyAgICBpZiAoUGFydGlhbFVucm9sbGluZ1RocmVzaG9sZC5nZXROdW1PY2N1cnJlbmNlcygpID4gMCkKKyAgICAgIE1heE9wcyA9IFBhcnRpYWxVbnJvbGxpbmdUaHJlc2hvbGQ7CisgICAgZWxzZSBpZiAoU1QtPmdldFNjaGVkTW9kZWwoKS5Mb29wTWljcm9PcEJ1ZmZlclNpemUgPiAwKQorICAgICAgTWF4T3BzID0gU1QtPmdldFNjaGVkTW9kZWwoKS5Mb29wTWljcm9PcEJ1ZmZlclNpemU7CisgICAgZWxzZQorICAgICAgcmV0dXJuOworCisgICAgLy8gU2NhbiB0aGUgbG9vcDogZG9uJ3QgdW5yb2xsIGxvb3BzIHdpdGggY2FsbHMuCisgICAgZm9yIChMb29wOjpibG9ja19pdGVyYXRvciBJID0gTC0+YmxvY2tfYmVnaW4oKSwgRSA9IEwtPmJsb2NrX2VuZCgpOyBJICE9IEU7CisgICAgICAgICArK0kpIHsKKyAgICAgIEJhc2ljQmxvY2sgKkJCID0gKkk7CisKKyAgICAgIGZvciAoQmFzaWNCbG9jazo6aXRlcmF0b3IgSiA9IEJCLT5iZWdpbigpLCBKRSA9IEJCLT5lbmQoKTsgSiAhPSBKRTsgKytKKQorICAgICAgICBpZiAoaXNhPENhbGxJbnN0PihKKSB8fCBpc2E8SW52b2tlSW5zdD4oSikpIHsKKyAgICAgICAgICBJbW11dGFibGVDYWxsU2l0ZSBDUygmKkopOworICAgICAgICAgIGlmIChjb25zdCBGdW5jdGlvbiAqRiA9IENTLmdldENhbGxlZEZ1bmN0aW9uKCkpIHsKKyAgICAgICAgICAgIGlmICghc3RhdGljX2Nhc3Q8VCAqPih0aGlzKS0+aXNMb3dlcmVkVG9DYWxsKEYpKQorICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICB9CisKKyAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBFbmFibGUgcnVudGltZSBhbmQgcGFydGlhbCB1bnJvbGxpbmcgdXAgdG8gdGhlIHNwZWNpZmllZCBzaXplLgorICAgIC8vIEVuYWJsZSB1c2luZyB0cmlwIGNvdW50IHVwcGVyIGJvdW5kIHRvIHVucm9sbCBsb29wcy4KKyAgICBVUC5QYXJ0aWFsID0gVVAuUnVudGltZSA9IFVQLlVwcGVyQm91bmQgPSB0cnVlOworICAgIFVQLlBhcnRpYWxUaHJlc2hvbGQgPSBNYXhPcHM7CisKKyAgICAvLyBBdm9pZCB1bnJvbGxpbmcgd2hlbiBvcHRpbWl6aW5nIGZvciBzaXplLgorICAgIFVQLk9wdFNpemVUaHJlc2hvbGQgPSAwOworICAgIFVQLlBhcnRpYWxPcHRTaXplVGhyZXNob2xkID0gMDsKKworICAgIC8vIFNldCBudW1iZXIgb2YgaW5zdHJ1Y3Rpb25zIG9wdGltaXplZCB3aGVuICJiYWNrIGVkZ2UiCisgICAgLy8gYmVjb21lcyAiZmFsbCB0aHJvdWdoIiB0byBkZWZhdWx0IHZhbHVlIG9mIDIuCisgICAgVVAuQkVJbnNucyA9IDI7CisgIH0KKworICBpbnQgZ2V0SW5zdHJ1Y3Rpb25MYXRlbmN5KGNvbnN0IEluc3RydWN0aW9uICpJKSB7CisgICAgaWYgKGlzYTxMb2FkSW5zdD4oSSkpCisgICAgICByZXR1cm4gZ2V0U1QoKS0+Z2V0U2NoZWRNb2RlbCgpLkRlZmF1bHRMb2FkTGF0ZW5jeTsKKworICAgIHJldHVybiBCYXNlVDo6Z2V0SW5zdHJ1Y3Rpb25MYXRlbmN5KEkpOworICB9CisKKyAgLy8vIEB9CisKKyAgLy8vIFxuYW1lIFZlY3RvciBUVEkgSW1wbGVtZW50YXRpb25zCisgIC8vLyBAeworCisgIHVuc2lnbmVkIGdldE51bWJlck9mUmVnaXN0ZXJzKGJvb2wgVmVjdG9yKSB7IHJldHVybiBWZWN0b3IgPyAwIDogMTsgfQorCisgIHVuc2lnbmVkIGdldFJlZ2lzdGVyQml0V2lkdGgoYm9vbCBWZWN0b3IpIGNvbnN0IHsgcmV0dXJuIDMyOyB9CisKKyAgLy8vIEVzdGltYXRlIHRoZSBvdmVyaGVhZCBvZiBzY2FsYXJpemluZyBhbiBpbnN0cnVjdGlvbi4gSW5zZXJ0IGFuZCBFeHRyYWN0CisgIC8vLyBhcmUgc2V0IGlmIHRoZSByZXN1bHQgbmVlZHMgdG8gYmUgaW5zZXJ0ZWQgYW5kL29yIGV4dHJhY3RlZCBmcm9tIHZlY3RvcnMuCisgIHVuc2lnbmVkIGdldFNjYWxhcml6YXRpb25PdmVyaGVhZChUeXBlICpUeSwgYm9vbCBJbnNlcnQsIGJvb2wgRXh0cmFjdCkgeworICAgIGFzc2VydChUeS0+aXNWZWN0b3JUeSgpICYmICJDYW4gb25seSBzY2FsYXJpemUgdmVjdG9ycyIpOworICAgIHVuc2lnbmVkIENvc3QgPSAwOworCisgICAgZm9yIChpbnQgaSA9IDAsIGUgPSBUeS0+Z2V0VmVjdG9yTnVtRWxlbWVudHMoKTsgaSA8IGU7ICsraSkgeworICAgICAgaWYgKEluc2VydCkKKyAgICAgICAgQ29zdCArPSBzdGF0aWNfY2FzdDxUICo+KHRoaXMpCisgICAgICAgICAgICAgICAgICAgIC0+Z2V0VmVjdG9ySW5zdHJDb3N0KEluc3RydWN0aW9uOjpJbnNlcnRFbGVtZW50LCBUeSwgaSk7CisgICAgICBpZiAoRXh0cmFjdCkKKyAgICAgICAgQ29zdCArPSBzdGF0aWNfY2FzdDxUICo+KHRoaXMpCisgICAgICAgICAgICAgICAgICAgIC0+Z2V0VmVjdG9ySW5zdHJDb3N0KEluc3RydWN0aW9uOjpFeHRyYWN0RWxlbWVudCwgVHksIGkpOworICAgIH0KKworICAgIHJldHVybiBDb3N0OworICB9CisKKyAgLy8vIEVzdGltYXRlIHRoZSBvdmVyaGVhZCBvZiBzY2FsYXJpemluZyBhbiBpbnN0cnVjdGlvbnMgdW5pcXVlCisgIC8vLyBub24tY29uc3RhbnQgb3BlcmFuZHMuIFRoZSB0eXBlcyBvZiB0aGUgYXJndW1lbnRzIGFyZSBvcmRpbmFyaWx5CisgIC8vLyBzY2FsYXIsIGluIHdoaWNoIGNhc2UgdGhlIGNvc3RzIGFyZSBtdWx0aXBsaWVkIHdpdGggVkYuCisgIHVuc2lnbmVkIGdldE9wZXJhbmRzU2NhbGFyaXphdGlvbk92ZXJoZWFkKEFycmF5UmVmPGNvbnN0IFZhbHVlICo+IEFyZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFZGKSB7CisgICAgdW5zaWduZWQgQ29zdCA9IDA7CisgICAgU21hbGxQdHJTZXQ8Y29uc3QgVmFsdWUqLCA0PiBVbmlxdWVPcGVyYW5kczsKKyAgICBmb3IgKGNvbnN0IFZhbHVlICpBIDogQXJncykgeworICAgICAgaWYgKCFpc2E8Q29uc3RhbnQ+KEEpICYmIFVuaXF1ZU9wZXJhbmRzLmluc2VydChBKS5zZWNvbmQpIHsKKyAgICAgICAgVHlwZSAqVmVjVHkgPSBudWxscHRyOworICAgICAgICBpZiAoQS0+Z2V0VHlwZSgpLT5pc1ZlY3RvclR5KCkpIHsKKyAgICAgICAgICBWZWNUeSA9IEEtPmdldFR5cGUoKTsKKyAgICAgICAgICAvLyBJZiBBIGlzIGEgdmVjdG9yIG9wZXJhbmQsIFZGIHNob3VsZCBiZSAxIG9yIGNvcnJlc3BvbmQgdG8gQS4KKyAgICAgICAgICBhc3NlcnQoKFZGID09IDEgfHwgVkYgPT0gVmVjVHktPmdldFZlY3Rvck51bUVsZW1lbnRzKCkpICYmCisgICAgICAgICAgICAgICAgICJWZWN0b3IgYXJndW1lbnQgZG9lcyBub3QgbWF0Y2ggVkYiKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgVmVjVHkgPSBWZWN0b3JUeXBlOjpnZXQoQS0+Z2V0VHlwZSgpLCBWRik7CisKKyAgICAgICAgQ29zdCArPSBnZXRTY2FsYXJpemF0aW9uT3ZlcmhlYWQoVmVjVHksIGZhbHNlLCB0cnVlKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gQ29zdDsKKyAgfQorCisgIHVuc2lnbmVkIGdldFNjYWxhcml6YXRpb25PdmVyaGVhZChUeXBlICpWZWNUeSwgQXJyYXlSZWY8Y29uc3QgVmFsdWUgKj4gQXJncykgeworICAgIGFzc2VydChWZWNUeS0+aXNWZWN0b3JUeSgpKTsKKworICAgIHVuc2lnbmVkIENvc3QgPSAwOworCisgICAgQ29zdCArPSBnZXRTY2FsYXJpemF0aW9uT3ZlcmhlYWQoVmVjVHksIHRydWUsIGZhbHNlKTsKKyAgICBpZiAoIUFyZ3MuZW1wdHkoKSkKKyAgICAgIENvc3QgKz0gZ2V0T3BlcmFuZHNTY2FsYXJpemF0aW9uT3ZlcmhlYWQoQXJncywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVjVHktPmdldFZlY3Rvck51bUVsZW1lbnRzKCkpOworICAgIGVsc2UKKyAgICAgIC8vIFdoZW4gbm8gaW5mb3JtYXRpb24gb24gYXJndW1lbnRzIGlzIHByb3ZpZGVkLCB3ZSBhZGQgdGhlIGNvc3QKKyAgICAgIC8vIGFzc29jaWF0ZWQgd2l0aCBvbmUgYXJndW1lbnQgYXMgYSBoZXVyaXN0aWMuCisgICAgICBDb3N0ICs9IGdldFNjYWxhcml6YXRpb25PdmVyaGVhZChWZWNUeSwgZmFsc2UsIHRydWUpOworCisgICAgcmV0dXJuIENvc3Q7CisgIH0KKworICB1bnNpZ25lZCBnZXRNYXhJbnRlcmxlYXZlRmFjdG9yKHVuc2lnbmVkIFZGKSB7IHJldHVybiAxOyB9CisKKyAgdW5zaWduZWQgZ2V0QXJpdGhtZXRpY0luc3RyQ29zdCgKKyAgICAgIHVuc2lnbmVkIE9wY29kZSwgVHlwZSAqVHksCisgICAgICBUVEk6Ok9wZXJhbmRWYWx1ZUtpbmQgT3BkMUluZm8gPSBUVEk6Ok9LX0FueVZhbHVlLAorICAgICAgVFRJOjpPcGVyYW5kVmFsdWVLaW5kIE9wZDJJbmZvID0gVFRJOjpPS19BbnlWYWx1ZSwKKyAgICAgIFRUSTo6T3BlcmFuZFZhbHVlUHJvcGVydGllcyBPcGQxUHJvcEluZm8gPSBUVEk6Ok9QX05vbmUsCisgICAgICBUVEk6Ok9wZXJhbmRWYWx1ZVByb3BlcnRpZXMgT3BkMlByb3BJbmZvID0gVFRJOjpPUF9Ob25lLAorICAgICAgQXJyYXlSZWY8Y29uc3QgVmFsdWUgKj4gQXJncyA9IEFycmF5UmVmPGNvbnN0IFZhbHVlICo+KCkpIHsKKyAgICAvLyBDaGVjayBpZiBhbnkgb2YgdGhlIG9wZXJhbmRzIGFyZSB2ZWN0b3Igb3BlcmFuZHMuCisgICAgY29uc3QgVGFyZ2V0TG93ZXJpbmdCYXNlICpUTEkgPSBnZXRUTEkoKTsKKyAgICBpbnQgSVNEID0gVExJLT5JbnN0cnVjdGlvbk9wY29kZVRvSVNEKE9wY29kZSk7CisgICAgYXNzZXJ0KElTRCAmJiAiSW52YWxpZCBvcGNvZGUiKTsKKworICAgIHN0ZDo6cGFpcjx1bnNpZ25lZCwgTVZUPiBMVCA9IFRMSS0+Z2V0VHlwZUxlZ2FsaXphdGlvbkNvc3QoREwsIFR5KTsKKworICAgIGJvb2wgSXNGbG9hdCA9IFR5LT5pc0ZQT3JGUFZlY3RvclR5KCk7CisgICAgLy8gQXNzdW1lIHRoYXQgZmxvYXRpbmcgcG9pbnQgYXJpdGhtZXRpYyBvcGVyYXRpb25zIGNvc3QgdHdpY2UgYXMgbXVjaCBhcworICAgIC8vIGludGVnZXIgb3BlcmF0aW9ucy4KKyAgICB1bnNpZ25lZCBPcENvc3QgPSAoSXNGbG9hdCA/IDIgOiAxKTsKKworICAgIGlmIChUTEktPmlzT3BlcmF0aW9uTGVnYWxPclByb21vdGUoSVNELCBMVC5zZWNvbmQpKSB7CisgICAgICAvLyBUaGUgb3BlcmF0aW9uIGlzIGxlZ2FsLiBBc3N1bWUgaXQgY29zdHMgMS4KKyAgICAgIC8vIFRPRE86IE9uY2Ugd2UgaGF2ZSBleHRyYWN0L2luc2VydCBzdWJ2ZWN0b3IgY29zdCB3ZSBuZWVkIHRvIHVzZSB0aGVtLgorICAgICAgcmV0dXJuIExULmZpcnN0ICogT3BDb3N0OworICAgIH0KKworICAgIGlmICghVExJLT5pc09wZXJhdGlvbkV4cGFuZChJU0QsIExULnNlY29uZCkpIHsKKyAgICAgIC8vIElmIHRoZSBvcGVyYXRpb24gaXMgY3VzdG9tIGxvd2VyZWQsIHRoZW4gYXNzdW1lIHRoYXQgdGhlIGNvZGUgaXMgdHdpY2UKKyAgICAgIC8vIGFzIGV4cGVuc2l2ZS4KKyAgICAgIHJldHVybiBMVC5maXJzdCAqIDIgKiBPcENvc3Q7CisgICAgfQorCisgICAgLy8gRWxzZSwgYXNzdW1lIHRoYXQgd2UgbmVlZCB0byBzY2FsYXJpemUgdGhpcyBvcC4KKyAgICAvLyBUT0RPOiBJZiBvbmUgb2YgdGhlIHR5cGVzIGdldCBsZWdhbGl6ZWQgYnkgc3BsaXR0aW5nLCBoYW5kbGUgdGhpcworICAgIC8vIHNpbWlsYXJseSB0byB3aGF0IGdldENhc3RJbnN0ckNvc3QoKSBkb2VzLgorICAgIGlmIChUeS0+aXNWZWN0b3JUeSgpKSB7CisgICAgICB1bnNpZ25lZCBOdW0gPSBUeS0+Z2V0VmVjdG9yTnVtRWxlbWVudHMoKTsKKyAgICAgIHVuc2lnbmVkIENvc3QgPSBzdGF0aWNfY2FzdDxUICo+KHRoaXMpCisgICAgICAgICAgICAgICAgICAgICAgICAgIC0+Z2V0QXJpdGhtZXRpY0luc3RyQ29zdChPcGNvZGUsIFR5LT5nZXRTY2FsYXJUeXBlKCkpOworICAgICAgLy8gUmV0dXJuIHRoZSBjb3N0IG9mIG11bHRpcGxlIHNjYWxhciBpbnZvY2F0aW9uIHBsdXMgdGhlIGNvc3Qgb2YKKyAgICAgIC8vIGluc2VydGluZyBhbmQgZXh0cmFjdGluZyB0aGUgdmFsdWVzLgorICAgICAgcmV0dXJuIGdldFNjYWxhcml6YXRpb25PdmVyaGVhZChUeSwgQXJncykgKyBOdW0gKiBDb3N0OworICAgIH0KKworICAgIC8vIFdlIGRvbid0IGtub3cgYW55dGhpbmcgYWJvdXQgdGhpcyBzY2FsYXIgaW5zdHJ1Y3Rpb24uCisgICAgcmV0dXJuIE9wQ29zdDsKKyAgfQorCisgIHVuc2lnbmVkIGdldFNodWZmbGVDb3N0KFRUSTo6U2h1ZmZsZUtpbmQgS2luZCwgVHlwZSAqVHAsIGludCBJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSAqU3ViVHApIHsKKyAgICBpZiAoS2luZCA9PSBUVEk6OlNLX0FsdGVybmF0ZSB8fCBLaW5kID09IFRUSTo6U0tfUGVybXV0ZVR3b1NyYyB8fAorICAgICAgICBLaW5kID09IFRUSTo6U0tfUGVybXV0ZVNpbmdsZVNyYykgeworICAgICAgcmV0dXJuIGdldFBlcm11dGVTaHVmZmxlT3ZlcmhlYWQoVHApOworICAgIH0KKyAgICByZXR1cm4gMTsKKyAgfQorCisgIHVuc2lnbmVkIGdldENhc3RJbnN0ckNvc3QodW5zaWduZWQgT3Bjb2RlLCBUeXBlICpEc3QsIFR5cGUgKlNyYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJbnN0cnVjdGlvbiAqSSA9IG51bGxwdHIpIHsKKyAgICBjb25zdCBUYXJnZXRMb3dlcmluZ0Jhc2UgKlRMSSA9IGdldFRMSSgpOworICAgIGludCBJU0QgPSBUTEktPkluc3RydWN0aW9uT3Bjb2RlVG9JU0QoT3Bjb2RlKTsKKyAgICBhc3NlcnQoSVNEICYmICJJbnZhbGlkIG9wY29kZSIpOworICAgIHN0ZDo6cGFpcjx1bnNpZ25lZCwgTVZUPiBTcmNMVCA9IFRMSS0+Z2V0VHlwZUxlZ2FsaXphdGlvbkNvc3QoREwsIFNyYyk7CisgICAgc3RkOjpwYWlyPHVuc2lnbmVkLCBNVlQ+IERzdExUID0gVExJLT5nZXRUeXBlTGVnYWxpemF0aW9uQ29zdChETCwgRHN0KTsKKworICAgIC8vIENoZWNrIGZvciBOT09QIGNvbnZlcnNpb25zLgorICAgIGlmIChTcmNMVC5maXJzdCA9PSBEc3RMVC5maXJzdCAmJgorICAgICAgICBTcmNMVC5zZWNvbmQuZ2V0U2l6ZUluQml0cygpID09IERzdExULnNlY29uZC5nZXRTaXplSW5CaXRzKCkpIHsKKworICAgICAgLy8gQml0Y2FzdCBiZXR3ZWVuIHR5cGVzIHRoYXQgYXJlIGxlZ2FsaXplZCB0byB0aGUgc2FtZSB0eXBlIGFyZSBmcmVlLgorICAgICAgaWYgKE9wY29kZSA9PSBJbnN0cnVjdGlvbjo6Qml0Q2FzdCB8fCBPcGNvZGUgPT0gSW5zdHJ1Y3Rpb246OlRydW5jKQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBpZiAoT3Bjb2RlID09IEluc3RydWN0aW9uOjpUcnVuYyAmJgorICAgICAgICBUTEktPmlzVHJ1bmNhdGVGcmVlKFNyY0xULnNlY29uZCwgRHN0TFQuc2Vjb25kKSkKKyAgICAgIHJldHVybiAwOworCisgICAgaWYgKE9wY29kZSA9PSBJbnN0cnVjdGlvbjo6WkV4dCAmJgorICAgICAgICBUTEktPmlzWkV4dEZyZWUoU3JjTFQuc2Vjb25kLCBEc3RMVC5zZWNvbmQpKQorICAgICAgcmV0dXJuIDA7CisKKyAgICBpZiAoT3Bjb2RlID09IEluc3RydWN0aW9uOjpBZGRyU3BhY2VDYXN0ICYmCisgICAgICAgIFRMSS0+aXNOb29wQWRkclNwYWNlQ2FzdChTcmMtPmdldFBvaW50ZXJBZGRyZXNzU3BhY2UoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERzdC0+Z2V0UG9pbnRlckFkZHJlc3NTcGFjZSgpKSkKKyAgICAgIHJldHVybiAwOworCisgICAgLy8gSWYgdGhpcyBpcyBhIHpleHQvc2V4dCBvZiBhIGxvYWQsIHJldHVybiAwIGlmIHRoZSBjb3JyZXNwb25kaW5nCisgICAgLy8gZXh0ZW5kaW5nIGxvYWQgZXhpc3RzIG9uIHRhcmdldC4KKyAgICBpZiAoKE9wY29kZSA9PSBJbnN0cnVjdGlvbjo6WkV4dCB8fCBPcGNvZGUgPT0gSW5zdHJ1Y3Rpb246OlNFeHQpICYmCisgICAgICAgIEkgJiYgaXNhPExvYWRJbnN0PihJLT5nZXRPcGVyYW5kKDApKSkgeworICAgICAgICBFVlQgRXh0VlQgPSBFVlQ6OmdldEVWVChEc3QpOworICAgICAgICBFVlQgTG9hZFZUID0gRVZUOjpnZXRFVlQoU3JjKTsKKyAgICAgICAgdW5zaWduZWQgTFR5cGUgPQorICAgICAgICAgICgoT3Bjb2RlID09IEluc3RydWN0aW9uOjpaRXh0KSA/IElTRDo6WkVYVExPQUQgOiBJU0Q6OlNFWFRMT0FEKTsKKyAgICAgICAgaWYgKFRMSS0+aXNMb2FkRXh0TGVnYWwoTFR5cGUsIEV4dFZULCBMb2FkVlQpKQorICAgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8vIElmIHRoZSBjYXN0IGlzIG1hcmtlZCBhcyBsZWdhbCAob3IgcHJvbW90ZSkgdGhlbiBhc3N1bWUgbG93IGNvc3QuCisgICAgaWYgKFNyY0xULmZpcnN0ID09IERzdExULmZpcnN0ICYmCisgICAgICAgIFRMSS0+aXNPcGVyYXRpb25MZWdhbE9yUHJvbW90ZShJU0QsIERzdExULnNlY29uZCkpCisgICAgICByZXR1cm4gMTsKKworICAgIC8vIEhhbmRsZSBzY2FsYXIgY29udmVyc2lvbnMuCisgICAgaWYgKCFTcmMtPmlzVmVjdG9yVHkoKSAmJiAhRHN0LT5pc1ZlY3RvclR5KCkpIHsKKyAgICAgIC8vIFNjYWxhciBiaXRjYXN0cyBhcmUgdXN1YWxseSBmcmVlLgorICAgICAgaWYgKE9wY29kZSA9PSBJbnN0cnVjdGlvbjo6Qml0Q2FzdCkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICAgIC8vIEp1c3QgY2hlY2sgdGhlIG9wIGNvc3QuIElmIHRoZSBvcGVyYXRpb24gaXMgbGVnYWwgdGhlbiBhc3N1bWUgaXQgY29zdHMKKyAgICAgIC8vIDEuCisgICAgICBpZiAoIVRMSS0+aXNPcGVyYXRpb25FeHBhbmQoSVNELCBEc3RMVC5zZWNvbmQpKQorICAgICAgICByZXR1cm4gMTsKKworICAgICAgLy8gQXNzdW1lIHRoYXQgaWxsZWdhbCBzY2FsYXIgaW5zdHJ1Y3Rpb24gYXJlIGV4cGVuc2l2ZS4KKyAgICAgIHJldHVybiA0OworICAgIH0KKworICAgIC8vIENoZWNrIHZlY3Rvci10by12ZWN0b3IgY2FzdHMuCisgICAgaWYgKERzdC0+aXNWZWN0b3JUeSgpICYmIFNyYy0+aXNWZWN0b3JUeSgpKSB7CisgICAgICAvLyBJZiB0aGUgY2FzdCBpcyBiZXR3ZWVuIHNhbWUtc2l6ZWQgcmVnaXN0ZXJzLCB0aGVuIHRoZSBjaGVjayBpcyBzaW1wbGUuCisgICAgICBpZiAoU3JjTFQuZmlyc3QgPT0gRHN0TFQuZmlyc3QgJiYKKyAgICAgICAgICBTcmNMVC5zZWNvbmQuZ2V0U2l6ZUluQml0cygpID09IERzdExULnNlY29uZC5nZXRTaXplSW5CaXRzKCkpIHsKKworICAgICAgICAvLyBBc3N1bWUgdGhhdCBaZXh0IGlzIGRvbmUgdXNpbmcgQU5ELgorICAgICAgICBpZiAoT3Bjb2RlID09IEluc3RydWN0aW9uOjpaRXh0KQorICAgICAgICAgIHJldHVybiAxOworCisgICAgICAgIC8vIEFzc3VtZSB0aGF0IHNleHQgaXMgZG9uZSB1c2luZyBTSEwgYW5kIFNSQS4KKyAgICAgICAgaWYgKE9wY29kZSA9PSBJbnN0cnVjdGlvbjo6U0V4dCkKKyAgICAgICAgICByZXR1cm4gMjsKKworICAgICAgICAvLyBKdXN0IGNoZWNrIHRoZSBvcCBjb3N0LiBJZiB0aGUgb3BlcmF0aW9uIGlzIGxlZ2FsIHRoZW4gYXNzdW1lIGl0CisgICAgICAgIC8vIGNvc3RzCisgICAgICAgIC8vIDEgYW5kIG11bHRpcGx5IGJ5IHRoZSB0eXBlLWxlZ2FsaXphdGlvbiBvdmVyaGVhZC4KKyAgICAgICAgaWYgKCFUTEktPmlzT3BlcmF0aW9uRXhwYW5kKElTRCwgRHN0TFQuc2Vjb25kKSkKKyAgICAgICAgICByZXR1cm4gU3JjTFQuZmlyc3QgKiAxOworICAgICAgfQorCisgICAgICAvLyBJZiB3ZSBhcmUgbGVnYWxpemluZyBieSBzcGxpdHRpbmcsIHF1ZXJ5IHRoZSBjb25jcmV0ZSBUVEkgZm9yIHRoZSBjb3N0CisgICAgICAvLyBvZiBjYXN0aW5nIHRoZSBvcmlnaW5hbCB2ZWN0b3IgdHdpY2UuIFdlIGFsc28gbmVlZCB0byBmYWN0b3IgaW4gdGhlCisgICAgICAvLyBjb3N0IG9mIHRoZSBzcGxpdCBpdHNlbGYuIENvdW50IHRoYXQgYXMgMSwgdG8gYmUgY29uc2lzdGVudCB3aXRoCisgICAgICAvLyBUTEktPmdldFR5cGVMZWdhbGl6YXRpb25Db3N0KCkuCisgICAgICBpZiAoKFRMSS0+Z2V0VHlwZUFjdGlvbihTcmMtPmdldENvbnRleHQoKSwgVExJLT5nZXRWYWx1ZVR5cGUoREwsIFNyYykpID09CisgICAgICAgICAgIFRhcmdldExvd2VyaW5nOjpUeXBlU3BsaXRWZWN0b3IpIHx8CisgICAgICAgICAgKFRMSS0+Z2V0VHlwZUFjdGlvbihEc3QtPmdldENvbnRleHQoKSwgVExJLT5nZXRWYWx1ZVR5cGUoREwsIERzdCkpID09CisgICAgICAgICAgIFRhcmdldExvd2VyaW5nOjpUeXBlU3BsaXRWZWN0b3IpKSB7CisgICAgICAgIFR5cGUgKlNwbGl0RHN0ID0gVmVjdG9yVHlwZTo6Z2V0KERzdC0+Z2V0VmVjdG9yRWxlbWVudFR5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRHN0LT5nZXRWZWN0b3JOdW1FbGVtZW50cygpIC8gMik7CisgICAgICAgIFR5cGUgKlNwbGl0U3JjID0gVmVjdG9yVHlwZTo6Z2V0KFNyYy0+Z2V0VmVjdG9yRWxlbWVudFR5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3JjLT5nZXRWZWN0b3JOdW1FbGVtZW50cygpIC8gMik7CisgICAgICAgIFQgKlRUSSA9IHN0YXRpY19jYXN0PFQgKj4odGhpcyk7CisgICAgICAgIHJldHVybiBUVEktPmdldFZlY3RvclNwbGl0Q29zdCgpICsKKyAgICAgICAgICAgICAgICgyICogVFRJLT5nZXRDYXN0SW5zdHJDb3N0KE9wY29kZSwgU3BsaXREc3QsIFNwbGl0U3JjLCBJKSk7CisgICAgICB9CisKKyAgICAgIC8vIEluIG90aGVyIGNhc2VzIHdoZXJlIHRoZSBzb3VyY2Ugb3IgZGVzdGluYXRpb24gYXJlIGlsbGVnYWwsIGFzc3VtZQorICAgICAgLy8gdGhlIG9wZXJhdGlvbiB3aWxsIGdldCBzY2FsYXJpemVkLgorICAgICAgdW5zaWduZWQgTnVtID0gRHN0LT5nZXRWZWN0b3JOdW1FbGVtZW50cygpOworICAgICAgdW5zaWduZWQgQ29zdCA9IHN0YXRpY19jYXN0PFQgKj4odGhpcyktPmdldENhc3RJbnN0ckNvc3QoCisgICAgICAgICAgT3Bjb2RlLCBEc3QtPmdldFNjYWxhclR5cGUoKSwgU3JjLT5nZXRTY2FsYXJUeXBlKCksIEkpOworCisgICAgICAvLyBSZXR1cm4gdGhlIGNvc3Qgb2YgbXVsdGlwbGUgc2NhbGFyIGludm9jYXRpb24gcGx1cyB0aGUgY29zdCBvZgorICAgICAgLy8gaW5zZXJ0aW5nIGFuZCBleHRyYWN0aW5nIHRoZSB2YWx1ZXMuCisgICAgICByZXR1cm4gZ2V0U2NhbGFyaXphdGlvbk92ZXJoZWFkKERzdCwgdHJ1ZSwgdHJ1ZSkgKyBOdW0gKiBDb3N0OworICAgIH0KKworICAgIC8vIFdlIGFscmVhZHkgaGFuZGxlZCB2ZWN0b3ItdG8tdmVjdG9yIGFuZCBzY2FsYXItdG8tc2NhbGFyIGNvbnZlcnNpb25zLgorICAgIC8vIFRoaXMKKyAgICAvLyBpcyB3aGVyZSB3ZSBoYW5kbGUgYml0Y2FzdCBiZXR3ZWVuIHZlY3RvcnMgYW5kIHNjYWxhcnMuIFdlIG5lZWQgdG8gYXNzdW1lCisgICAgLy8gIHRoYXQgdGhlIGNvbnZlcnNpb24gaXMgc2NhbGFyaXplZCBpbiBvbmUgd2F5IG9yIGFub3RoZXIuCisgICAgaWYgKE9wY29kZSA9PSBJbnN0cnVjdGlvbjo6Qml0Q2FzdCkKKyAgICAgIC8vIElsbGVnYWwgYml0Y2FzdHMgYXJlIGRvbmUgYnkgc3RvcmluZyBhbmQgbG9hZGluZyBmcm9tIGEgc3RhY2sgc2xvdC4KKyAgICAgIHJldHVybiAoU3JjLT5pc1ZlY3RvclR5KCkgPyBnZXRTY2FsYXJpemF0aW9uT3ZlcmhlYWQoU3JjLCBmYWxzZSwgdHJ1ZSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAwKSArCisgICAgICAgICAgICAgKERzdC0+aXNWZWN0b3JUeSgpID8gZ2V0U2NhbGFyaXphdGlvbk92ZXJoZWFkKERzdCwgdHJ1ZSwgZmFsc2UpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogMCk7CisKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJVbmhhbmRsZWQgY2FzdCIpOworICB9CisKKyAgdW5zaWduZWQgZ2V0RXh0cmFjdFdpdGhFeHRlbmRDb3N0KHVuc2lnbmVkIE9wY29kZSwgVHlwZSAqRHN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVjdG9yVHlwZSAqVmVjVHksIHVuc2lnbmVkIEluZGV4KSB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PFQgKj4odGhpcyktPmdldFZlY3Rvckluc3RyQ29zdCgKKyAgICAgICAgICAgICAgIEluc3RydWN0aW9uOjpFeHRyYWN0RWxlbWVudCwgVmVjVHksIEluZGV4KSArCisgICAgICAgICAgIHN0YXRpY19jYXN0PFQgKj4odGhpcyktPmdldENhc3RJbnN0ckNvc3QoT3Bjb2RlLCBEc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVjVHktPmdldEVsZW1lbnRUeXBlKCkpOworICB9CisKKyAgdW5zaWduZWQgZ2V0Q0ZJbnN0ckNvc3QodW5zaWduZWQgT3Bjb2RlKSB7CisgICAgLy8gQnJhbmNoZXMgYXJlIGFzc3VtZWQgdG8gYmUgcHJlZGljdGVkLgorICAgIHJldHVybiAwOworICB9CisKKyAgdW5zaWduZWQgZ2V0Q21wU2VsSW5zdHJDb3N0KHVuc2lnbmVkIE9wY29kZSwgVHlwZSAqVmFsVHksIFR5cGUgKkNvbmRUeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEluc3RydWN0aW9uICpJKSB7CisgICAgY29uc3QgVGFyZ2V0TG93ZXJpbmdCYXNlICpUTEkgPSBnZXRUTEkoKTsKKyAgICBpbnQgSVNEID0gVExJLT5JbnN0cnVjdGlvbk9wY29kZVRvSVNEKE9wY29kZSk7CisgICAgYXNzZXJ0KElTRCAmJiAiSW52YWxpZCBvcGNvZGUiKTsKKworICAgIC8vIFNlbGVjdHMgb24gdmVjdG9ycyBhcmUgYWN0dWFsbHkgdmVjdG9yIHNlbGVjdHMuCisgICAgaWYgKElTRCA9PSBJU0Q6OlNFTEVDVCkgeworICAgICAgYXNzZXJ0KENvbmRUeSAmJiAiQ29uZFR5IG11c3QgZXhpc3QiKTsKKyAgICAgIGlmIChDb25kVHktPmlzVmVjdG9yVHkoKSkKKyAgICAgICAgSVNEID0gSVNEOjpWU0VMRUNUOworICAgIH0KKyAgICBzdGQ6OnBhaXI8dW5zaWduZWQsIE1WVD4gTFQgPSBUTEktPmdldFR5cGVMZWdhbGl6YXRpb25Db3N0KERMLCBWYWxUeSk7CisKKyAgICBpZiAoIShWYWxUeS0+aXNWZWN0b3JUeSgpICYmICFMVC5zZWNvbmQuaXNWZWN0b3IoKSkgJiYKKyAgICAgICAgIVRMSS0+aXNPcGVyYXRpb25FeHBhbmQoSVNELCBMVC5zZWNvbmQpKSB7CisgICAgICAvLyBUaGUgb3BlcmF0aW9uIGlzIGxlZ2FsLiBBc3N1bWUgaXQgY29zdHMgMS4gTXVsdGlwbHkKKyAgICAgIC8vIGJ5IHRoZSB0eXBlLWxlZ2FsaXphdGlvbiBvdmVyaGVhZC4KKyAgICAgIHJldHVybiBMVC5maXJzdCAqIDE7CisgICAgfQorCisgICAgLy8gT3RoZXJ3aXNlLCBhc3N1bWUgdGhhdCB0aGUgY2FzdCBpcyBzY2FsYXJpemVkLgorICAgIC8vIFRPRE86IElmIG9uZSBvZiB0aGUgdHlwZXMgZ2V0IGxlZ2FsaXplZCBieSBzcGxpdHRpbmcsIGhhbmRsZSB0aGlzCisgICAgLy8gc2ltaWxhcmx5IHRvIHdoYXQgZ2V0Q2FzdEluc3RyQ29zdCgpIGRvZXMuCisgICAgaWYgKFZhbFR5LT5pc1ZlY3RvclR5KCkpIHsKKyAgICAgIHVuc2lnbmVkIE51bSA9IFZhbFR5LT5nZXRWZWN0b3JOdW1FbGVtZW50cygpOworICAgICAgaWYgKENvbmRUeSkKKyAgICAgICAgQ29uZFR5ID0gQ29uZFR5LT5nZXRTY2FsYXJUeXBlKCk7CisgICAgICB1bnNpZ25lZCBDb3N0ID0gc3RhdGljX2Nhc3Q8VCAqPih0aGlzKS0+Z2V0Q21wU2VsSW5zdHJDb3N0KAorICAgICAgICAgIE9wY29kZSwgVmFsVHktPmdldFNjYWxhclR5cGUoKSwgQ29uZFR5LCBJKTsKKworICAgICAgLy8gUmV0dXJuIHRoZSBjb3N0IG9mIG11bHRpcGxlIHNjYWxhciBpbnZvY2F0aW9uIHBsdXMgdGhlIGNvc3Qgb2YKKyAgICAgIC8vIGluc2VydGluZyBhbmQgZXh0cmFjdGluZyB0aGUgdmFsdWVzLgorICAgICAgcmV0dXJuIGdldFNjYWxhcml6YXRpb25PdmVyaGVhZChWYWxUeSwgdHJ1ZSwgZmFsc2UpICsgTnVtICogQ29zdDsKKyAgICB9CisKKyAgICAvLyBVbmtub3duIHNjYWxhciBvcGNvZGUuCisgICAgcmV0dXJuIDE7CisgIH0KKworICB1bnNpZ25lZCBnZXRWZWN0b3JJbnN0ckNvc3QodW5zaWduZWQgT3Bjb2RlLCBUeXBlICpWYWwsIHVuc2lnbmVkIEluZGV4KSB7CisgICAgc3RkOjpwYWlyPHVuc2lnbmVkLCBNVlQ+IExUID0KKyAgICAgICAgZ2V0VExJKCktPmdldFR5cGVMZWdhbGl6YXRpb25Db3N0KERMLCBWYWwtPmdldFNjYWxhclR5cGUoKSk7CisKKyAgICByZXR1cm4gTFQuZmlyc3Q7CisgIH0KKworICB1bnNpZ25lZCBnZXRNZW1vcnlPcENvc3QodW5zaWduZWQgT3Bjb2RlLCBUeXBlICpTcmMsIHVuc2lnbmVkIEFsaWdubWVudCwKKyAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgQWRkcmVzc1NwYWNlLCBjb25zdCBJbnN0cnVjdGlvbiAqSSA9IG51bGxwdHIpIHsKKyAgICBhc3NlcnQoIVNyYy0+aXNWb2lkVHkoKSAmJiAiSW52YWxpZCB0eXBlIik7CisgICAgc3RkOjpwYWlyPHVuc2lnbmVkLCBNVlQ+IExUID0gZ2V0VExJKCktPmdldFR5cGVMZWdhbGl6YXRpb25Db3N0KERMLCBTcmMpOworCisgICAgLy8gQXNzdW1pbmcgdGhhdCBhbGwgbG9hZHMgb2YgbGVnYWwgdHlwZXMgY29zdCAxLgorICAgIHVuc2lnbmVkIENvc3QgPSBMVC5maXJzdDsKKworICAgIGlmIChTcmMtPmlzVmVjdG9yVHkoKSAmJgorICAgICAgICBTcmMtPmdldFByaW1pdGl2ZVNpemVJbkJpdHMoKSA8IExULnNlY29uZC5nZXRTaXplSW5CaXRzKCkpIHsKKyAgICAgIC8vIFRoaXMgaXMgYSB2ZWN0b3IgbG9hZCB0aGF0IGxlZ2FsaXplcyB0byBhIGxhcmdlciB0eXBlIHRoYW4gdGhlIHZlY3RvcgorICAgICAgLy8gaXRzZWxmLiBVbmxlc3MgdGhlIGNvcnJlc3BvbmRpbmcgZXh0ZW5kaW5nIGxvYWQgb3IgdHJ1bmNhdGluZyBzdG9yZSBpcworICAgICAgLy8gbGVnYWwsIHRoZW4gdGhpcyB3aWxsIHNjYWxhcml6ZS4KKyAgICAgIFRhcmdldExvd2VyaW5nOjpMZWdhbGl6ZUFjdGlvbiBMQSA9IFRhcmdldExvd2VyaW5nOjpFeHBhbmQ7CisgICAgICBFVlQgTWVtVlQgPSBnZXRUTEkoKS0+Z2V0VmFsdWVUeXBlKERMLCBTcmMpOworICAgICAgaWYgKE9wY29kZSA9PSBJbnN0cnVjdGlvbjo6U3RvcmUpCisgICAgICAgIExBID0gZ2V0VExJKCktPmdldFRydW5jU3RvcmVBY3Rpb24oTFQuc2Vjb25kLCBNZW1WVCk7CisgICAgICBlbHNlCisgICAgICAgIExBID0gZ2V0VExJKCktPmdldExvYWRFeHRBY3Rpb24oSVNEOjpFWFRMT0FELCBMVC5zZWNvbmQsIE1lbVZUKTsKKworICAgICAgaWYgKExBICE9IFRhcmdldExvd2VyaW5nOjpMZWdhbCAmJiBMQSAhPSBUYXJnZXRMb3dlcmluZzo6Q3VzdG9tKSB7CisgICAgICAgIC8vIFRoaXMgaXMgYSB2ZWN0b3IgbG9hZC9zdG9yZSBmb3Igc29tZSBpbGxlZ2FsIHR5cGUgdGhhdCBpcyBzY2FsYXJpemVkLgorICAgICAgICAvLyBXZSBtdXN0IGFjY291bnQgZm9yIHRoZSBjb3N0IG9mIGJ1aWxkaW5nIG9yIGRlY29tcG9zaW5nIHRoZSB2ZWN0b3IuCisgICAgICAgIENvc3QgKz0gZ2V0U2NhbGFyaXphdGlvbk92ZXJoZWFkKFNyYywgT3Bjb2RlICE9IEluc3RydWN0aW9uOjpTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3Bjb2RlID09IEluc3RydWN0aW9uOjpTdG9yZSk7CisgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIENvc3Q7CisgIH0KKworICB1bnNpZ25lZCBnZXRJbnRlcmxlYXZlZE1lbW9yeU9wQ29zdCh1bnNpZ25lZCBPcGNvZGUsIFR5cGUgKlZlY1R5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBGYWN0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPHVuc2lnbmVkPiBJbmRpY2VzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBBbGlnbm1lbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIEFkZHJlc3NTcGFjZSkgeworICAgIFZlY3RvclR5cGUgKlZUID0gZHluX2Nhc3Q8VmVjdG9yVHlwZT4oVmVjVHkpOworICAgIGFzc2VydChWVCAmJiAiRXhwZWN0IGEgdmVjdG9yIHR5cGUgZm9yIGludGVybGVhdmVkIG1lbW9yeSBvcCIpOworCisgICAgdW5zaWduZWQgTnVtRWx0cyA9IFZULT5nZXROdW1FbGVtZW50cygpOworICAgIGFzc2VydChGYWN0b3IgPiAxICYmIE51bUVsdHMgJSBGYWN0b3IgPT0gMCAmJiAiSW52YWxpZCBpbnRlcmxlYXZlIGZhY3RvciIpOworCisgICAgdW5zaWduZWQgTnVtU3ViRWx0cyA9IE51bUVsdHMgLyBGYWN0b3I7CisgICAgVmVjdG9yVHlwZSAqU3ViVlQgPSBWZWN0b3JUeXBlOjpnZXQoVlQtPmdldEVsZW1lbnRUeXBlKCksIE51bVN1YkVsdHMpOworCisgICAgLy8gRmlyc3RseSwgdGhlIGNvc3Qgb2YgbG9hZC9zdG9yZSBvcGVyYXRpb24uCisgICAgdW5zaWduZWQgQ29zdCA9IHN0YXRpY19jYXN0PFQgKj4odGhpcyktPmdldE1lbW9yeU9wQ29zdCgKKyAgICAgICAgT3Bjb2RlLCBWZWNUeSwgQWxpZ25tZW50LCBBZGRyZXNzU3BhY2UpOworCisgICAgLy8gTGVnYWxpemUgdGhlIHZlY3RvciB0eXBlLCBhbmQgZ2V0IHRoZSBsZWdhbGl6ZWQgYW5kIHVubGVnYWxpemVkIHR5cGUKKyAgICAvLyBzaXplcy4KKyAgICBNVlQgVmVjVHlMVCA9IGdldFRMSSgpLT5nZXRUeXBlTGVnYWxpemF0aW9uQ29zdChETCwgVmVjVHkpLnNlY29uZDsKKyAgICB1bnNpZ25lZCBWZWNUeVNpemUgPQorICAgICAgICBzdGF0aWNfY2FzdDxUICo+KHRoaXMpLT5nZXREYXRhTGF5b3V0KCkuZ2V0VHlwZVN0b3JlU2l6ZShWZWNUeSk7CisgICAgdW5zaWduZWQgVmVjVHlMVFNpemUgPSBWZWNUeUxULmdldFN0b3JlU2l6ZSgpOworCisgICAgLy8gUmV0dXJuIHRoZSBjZWlsaW5nIG9mIGRpdmlkaW5nIEEgYnkgQi4KKyAgICBhdXRvIGNlaWwgPSBbXSh1bnNpZ25lZCBBLCB1bnNpZ25lZCBCKSB7IHJldHVybiAoQSArIEIgLSAxKSAvIEI7IH07CisKKyAgICAvLyBTY2FsZSB0aGUgY29zdCBvZiB0aGUgbWVtb3J5IG9wZXJhdGlvbiBieSB0aGUgZnJhY3Rpb24gb2YgbGVnYWxpemVkCisgICAgLy8gaW5zdHJ1Y3Rpb25zIHRoYXQgd2lsbCBhY3R1YWxseSBiZSB1c2VkLiBXZSBzaG91bGRuJ3QgYWNjb3VudCBmb3IgdGhlCisgICAgLy8gY29zdCBvZiBkZWFkIGluc3RydWN0aW9ucyBzaW5jZSB0aGV5IHdpbGwgYmUgcmVtb3ZlZC4KKyAgICAvLworICAgIC8vIEUuZy4sIEFuIGludGVybGVhdmVkIGxvYWQgb2YgZmFjdG9yIDg6CisgICAgLy8gICAgICAgJXZlYyA9IGxvYWQgPDE2IHggaTY0PiwgPDE2IHggaTY0PiogJXB0cgorICAgIC8vICAgICAgICV2MCA9IHNodWZmbGV2ZWN0b3IgJXZlYywgdW5kZWYsIDwwLCA4PgorICAgIC8vCisgICAgLy8gSWYgPDE2IHggaTY0PiBpcyBsZWdhbGl6ZWQgdG8gOCB2Mmk2NCBsb2Fkcywgb25seSAyIG9mIHRoZSBsb2FkcyB3aWxsIGJlCisgICAgLy8gdXNlZCAodGhvc2UgY29ycmVzcG9uZGluZyB0byBlbGVtZW50cyBbMDoxXSBhbmQgWzg6OV0gb2YgdGhlIHVubGVnYWxpemVkCisgICAgLy8gdHlwZSkuIFRoZSBvdGhlciBsb2FkcyBhcmUgdW51c2VkLgorICAgIC8vCisgICAgLy8gV2Ugb25seSBzY2FsZSB0aGUgY29zdCBvZiBsb2FkcyBzaW5jZSBpbnRlcmxlYXZlZCBzdG9yZSBncm91cHMgYXJlbid0CisgICAgLy8gYWxsb3dlZCB0byBoYXZlIGdhcHMuCisgICAgaWYgKE9wY29kZSA9PSBJbnN0cnVjdGlvbjo6TG9hZCAmJiBWZWNUeVNpemUgPiBWZWNUeUxUU2l6ZSkgeworICAgICAgLy8gVGhlIG51bWJlciBvZiBsb2FkcyBvZiBhIGxlZ2FsIHR5cGUgaXQgd2lsbCB0YWtlIHRvIHJlcHJlc2VudCBhIGxvYWQKKyAgICAgIC8vIG9mIHRoZSB1bmxlZ2FsaXplZCB2ZWN0b3IgdHlwZS4KKyAgICAgIHVuc2lnbmVkIE51bUxlZ2FsSW5zdHMgPSBjZWlsKFZlY1R5U2l6ZSwgVmVjVHlMVFNpemUpOworCisgICAgICAvLyBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIG9mIHRoZSB1bmxlZ2FsaXplZCB0eXBlIHRoYXQgY29ycmVzcG9uZCB0byBhCisgICAgICAvLyBzaW5nbGUgbGVnYWwgaW5zdHJ1Y3Rpb24uCisgICAgICB1bnNpZ25lZCBOdW1FbHRzUGVyTGVnYWxJbnN0ID0gY2VpbChOdW1FbHRzLCBOdW1MZWdhbEluc3RzKTsKKworICAgICAgLy8gRGV0ZXJtaW5lIHdoaWNoIGxlZ2FsIGluc3RydWN0aW9ucyB3aWxsIGJlIHVzZWQuCisgICAgICBCaXRWZWN0b3IgVXNlZEluc3RzKE51bUxlZ2FsSW5zdHMsIGZhbHNlKTsKKyAgICAgIGZvciAodW5zaWduZWQgSW5kZXggOiBJbmRpY2VzKQorICAgICAgICBmb3IgKHVuc2lnbmVkIEVsdCA9IDA7IEVsdCA8IE51bVN1YkVsdHM7ICsrRWx0KQorICAgICAgICAgIFVzZWRJbnN0cy5zZXQoKEluZGV4ICsgRWx0ICogRmFjdG9yKSAvIE51bUVsdHNQZXJMZWdhbEluc3QpOworCisgICAgICAvLyBTY2FsZSB0aGUgY29zdCBvZiB0aGUgbG9hZCBieSB0aGUgZnJhY3Rpb24gb2YgbGVnYWwgaW5zdHJ1Y3Rpb25zIHRoYXQKKyAgICAgIC8vIHdpbGwgYmUgdXNlZC4KKyAgICAgIENvc3QgKj0gVXNlZEluc3RzLmNvdW50KCkgLyBOdW1MZWdhbEluc3RzOworICAgIH0KKworICAgIC8vIFRoZW4gcGx1cyB0aGUgY29zdCBvZiBpbnRlcmxlYXZlIG9wZXJhdGlvbi4KKyAgICBpZiAoT3Bjb2RlID09IEluc3RydWN0aW9uOjpMb2FkKSB7CisgICAgICAvLyBUaGUgaW50ZXJsZWF2ZSBjb3N0IGlzIHNpbWlsYXIgdG8gZXh0cmFjdCBzdWIgdmVjdG9ycycgZWxlbWVudHMKKyAgICAgIC8vIGZyb20gdGhlIHdpZGUgdmVjdG9yLCBhbmQgaW5zZXJ0IHRoZW0gaW50byBzdWIgdmVjdG9ycy4KKyAgICAgIC8vCisgICAgICAvLyBFLmcuIEFuIGludGVybGVhdmVkIGxvYWQgb2YgZmFjdG9yIDIgKHdpdGggb25lIG1lbWJlciBvZiBpbmRleCAwKToKKyAgICAgIC8vICAgICAgJXZlYyA9IGxvYWQgPDggeCBpMzI+LCA8OCB4IGkzMj4qICVwdHIKKyAgICAgIC8vICAgICAgJXYwID0gc2h1ZmZsZSAldmVjLCB1bmRlZiwgPDAsIDIsIDQsIDY+ICAgICAgICAgOyBJbmRleCAwCisgICAgICAvLyBUaGUgY29zdCBpcyBlc3RpbWF0ZWQgYXMgZXh0cmFjdCBlbGVtZW50cyBhdCAwLCAyLCA0LCA2IGZyb20gdGhlCisgICAgICAvLyA8OCB4IGkzMj4gdmVjdG9yIGFuZCBpbnNlcnQgdGhlbSBpbnRvIGEgPDQgeCBpMzI+IHZlY3Rvci4KKworICAgICAgYXNzZXJ0KEluZGljZXMuc2l6ZSgpIDw9IEZhY3RvciAmJgorICAgICAgICAgICAgICJJbnRlcmxlYXZlZCBtZW1vcnkgb3AgaGFzIHRvbyBtYW55IG1lbWJlcnMiKTsKKworICAgICAgZm9yICh1bnNpZ25lZCBJbmRleCA6IEluZGljZXMpIHsKKyAgICAgICAgYXNzZXJ0KEluZGV4IDwgRmFjdG9yICYmICJJbnZhbGlkIGluZGV4IGZvciBpbnRlcmxlYXZlZCBtZW1vcnkgb3AiKTsKKworICAgICAgICAvLyBFeHRyYWN0IGVsZW1lbnRzIGZyb20gbG9hZGVkIHZlY3RvciBmb3IgZWFjaCBzdWIgdmVjdG9yLgorICAgICAgICBmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgTnVtU3ViRWx0czsgaSsrKQorICAgICAgICAgIENvc3QgKz0gc3RhdGljX2Nhc3Q8VCAqPih0aGlzKS0+Z2V0VmVjdG9ySW5zdHJDb3N0KAorICAgICAgICAgICAgICBJbnN0cnVjdGlvbjo6RXh0cmFjdEVsZW1lbnQsIFZULCBJbmRleCArIGkgKiBGYWN0b3IpOworICAgICAgfQorCisgICAgICB1bnNpZ25lZCBJbnNTdWJDb3N0ID0gMDsKKyAgICAgIGZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBOdW1TdWJFbHRzOyBpKyspCisgICAgICAgIEluc1N1YkNvc3QgKz0gc3RhdGljX2Nhc3Q8VCAqPih0aGlzKS0+Z2V0VmVjdG9ySW5zdHJDb3N0KAorICAgICAgICAgICAgSW5zdHJ1Y3Rpb246Okluc2VydEVsZW1lbnQsIFN1YlZULCBpKTsKKworICAgICAgQ29zdCArPSBJbmRpY2VzLnNpemUoKSAqIEluc1N1YkNvc3Q7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFRoZSBpbnRlcmxlYXZlIGNvc3QgaXMgZXh0cmFjdCBhbGwgZWxlbWVudHMgZnJvbSBzdWIgdmVjdG9ycywgYW5kCisgICAgICAvLyBpbnNlcnQgdGhlbSBpbnRvIHRoZSB3aWRlIHZlY3Rvci4KKyAgICAgIC8vCisgICAgICAvLyBFLmcuIEFuIGludGVybGVhdmVkIHN0b3JlIG9mIGZhY3RvciAyOgorICAgICAgLy8gICAgICAldjBfdjEgPSBzaHVmZmxlICV2MCwgJXYxLCA8MCwgNCwgMSwgNSwgMiwgNiwgMywgNz4KKyAgICAgIC8vICAgICAgc3RvcmUgPDggeCBpMzI+ICVpbnRlcmxlYXZlZC52ZWMsIDw4IHggaTMyPiogJXB0cgorICAgICAgLy8gVGhlIGNvc3QgaXMgZXN0aW1hdGVkIGFzIGV4dHJhY3QgYWxsIGVsZW1lbnRzIGZyb20gYm90aCA8NCB4IGkzMj4KKyAgICAgIC8vIHZlY3RvcnMgYW5kIGluc2VydCBpbnRvIHRoZSA8OCB4IGkzMj4gdmVjdG9yLgorCisgICAgICB1bnNpZ25lZCBFeHRTdWJDb3N0ID0gMDsKKyAgICAgIGZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBOdW1TdWJFbHRzOyBpKyspCisgICAgICAgIEV4dFN1YkNvc3QgKz0gc3RhdGljX2Nhc3Q8VCAqPih0aGlzKS0+Z2V0VmVjdG9ySW5zdHJDb3N0KAorICAgICAgICAgICAgSW5zdHJ1Y3Rpb246OkV4dHJhY3RFbGVtZW50LCBTdWJWVCwgaSk7CisgICAgICBDb3N0ICs9IEV4dFN1YkNvc3QgKiBGYWN0b3I7CisKKyAgICAgIGZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBOdW1FbHRzOyBpKyspCisgICAgICAgIENvc3QgKz0gc3RhdGljX2Nhc3Q8VCAqPih0aGlzKQorICAgICAgICAgICAgICAgICAgICAtPmdldFZlY3Rvckluc3RyQ29zdChJbnN0cnVjdGlvbjo6SW5zZXJ0RWxlbWVudCwgVlQsIGkpOworICAgIH0KKworICAgIHJldHVybiBDb3N0OworICB9CisKKyAgLy8vIEdldCBpbnRyaW5zaWMgY29zdCBiYXNlZCBvbiBhcmd1bWVudHMuCisgIHVuc2lnbmVkIGdldEludHJpbnNpY0luc3RyQ29zdChJbnRyaW5zaWM6OklEIElJRCwgVHlwZSAqUmV0VHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjxWYWx1ZSAqPiBBcmdzLCBGYXN0TWF0aEZsYWdzIEZNRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFZGID0gMSkgeworICAgIHVuc2lnbmVkIFJldFZGID0gKFJldFR5LT5pc1ZlY3RvclR5KCkgPyBSZXRUeS0+Z2V0VmVjdG9yTnVtRWxlbWVudHMoKSA6IDEpOworICAgIGFzc2VydCgoUmV0VkYgPT0gMSB8fCBWRiA9PSAxKSAmJiAiVkYgPiAxIGFuZCBSZXRWRiBpcyBhIHZlY3RvciB0eXBlIik7CisKKyAgICBzd2l0Y2ggKElJRCkgeworICAgIGRlZmF1bHQ6IHsKKyAgICAgIC8vIEFzc3VtZSB0aGF0IHdlIG5lZWQgdG8gc2NhbGFyaXplIHRoaXMgaW50cmluc2ljLgorICAgICAgU21hbGxWZWN0b3I8VHlwZSAqLCA0PiBUeXBlczsKKyAgICAgIGZvciAoVmFsdWUgKk9wIDogQXJncykgeworICAgICAgICBUeXBlICpPcFR5ID0gT3AtPmdldFR5cGUoKTsKKyAgICAgICAgYXNzZXJ0KFZGID09IDEgfHwgIU9wVHktPmlzVmVjdG9yVHkoKSk7CisgICAgICAgIFR5cGVzLnB1c2hfYmFjayhWRiA9PSAxID8gT3BUeSA6IFZlY3RvclR5cGU6OmdldChPcFR5LCBWRikpOworICAgICAgfQorCisgICAgICBpZiAoVkYgPiAxICYmICFSZXRUeS0+aXNWb2lkVHkoKSkKKyAgICAgICAgUmV0VHkgPSBWZWN0b3JUeXBlOjpnZXQoUmV0VHksIFZGKTsKKworICAgICAgLy8gQ29tcHV0ZSB0aGUgc2NhbGFyaXphdGlvbiBvdmVyaGVhZCBiYXNlZCBvbiBBcmdzIGZvciBhIHZlY3RvcgorICAgICAgLy8gaW50cmluc2ljLiBBIHZlY3Rvcml6ZXIgd2lsbCBwYXNzIGEgc2NhbGFyIFJldFR5IGFuZCBWRiA+IDEsIHdoaWxlCisgICAgICAvLyBDb3N0TW9kZWwgd2lsbCBwYXNzIGEgdmVjdG9yIFJldFR5IGFuZCBWRiBpcyAxLgorICAgICAgdW5zaWduZWQgU2NhbGFyaXphdGlvbkNvc3QgPSBzdGQ6Om51bWVyaWNfbGltaXRzPHVuc2lnbmVkPjo6bWF4KCk7CisgICAgICBpZiAoUmV0VkYgPiAxIHx8IFZGID4gMSkgeworICAgICAgICBTY2FsYXJpemF0aW9uQ29zdCA9IDA7CisgICAgICAgIGlmICghUmV0VHktPmlzVm9pZFR5KCkpCisgICAgICAgICAgU2NhbGFyaXphdGlvbkNvc3QgKz0gZ2V0U2NhbGFyaXphdGlvbk92ZXJoZWFkKFJldFR5LCB0cnVlLCBmYWxzZSk7CisgICAgICAgIFNjYWxhcml6YXRpb25Db3N0ICs9IGdldE9wZXJhbmRzU2NhbGFyaXphdGlvbk92ZXJoZWFkKEFyZ3MsIFZGKTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PFQgKj4odGhpcyktPgorICAgICAgICBnZXRJbnRyaW5zaWNJbnN0ckNvc3QoSUlELCBSZXRUeSwgVHlwZXMsIEZNRiwgU2NhbGFyaXphdGlvbkNvc3QpOworICAgIH0KKyAgICBjYXNlIEludHJpbnNpYzo6bWFza2VkX3NjYXR0ZXI6IHsKKyAgICAgIGFzc2VydChWRiA9PSAxICYmICJDYW4ndCB2ZWN0b3JpemUgdHlwZXMgaGVyZS4iKTsKKyAgICAgIFZhbHVlICpNYXNrID0gQXJnc1szXTsKKyAgICAgIGJvb2wgVmFyTWFzayA9ICFpc2E8Q29uc3RhbnQ+KE1hc2spOworICAgICAgdW5zaWduZWQgQWxpZ25tZW50ID0gY2FzdDxDb25zdGFudEludD4oQXJnc1syXSktPmdldFpFeHRWYWx1ZSgpOworICAgICAgcmV0dXJuCisgICAgICAgIHN0YXRpY19jYXN0PFQgKj4odGhpcyktPmdldEdhdGhlclNjYXR0ZXJPcENvc3QoSW5zdHJ1Y3Rpb246OlN0b3JlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFyZ3NbMF0tPmdldFR5cGUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmdzWzFdLCBWYXJNYXNrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFsaWdubWVudCk7CisgICAgfQorICAgIGNhc2UgSW50cmluc2ljOjptYXNrZWRfZ2F0aGVyOiB7CisgICAgICBhc3NlcnQoVkYgPT0gMSAmJiAiQ2FuJ3QgdmVjdG9yaXplIHR5cGVzIGhlcmUuIik7CisgICAgICBWYWx1ZSAqTWFzayA9IEFyZ3NbMl07CisgICAgICBib29sIFZhck1hc2sgPSAhaXNhPENvbnN0YW50PihNYXNrKTsKKyAgICAgIHVuc2lnbmVkIEFsaWdubWVudCA9IGNhc3Q8Q29uc3RhbnRJbnQ+KEFyZ3NbMV0pLT5nZXRaRXh0VmFsdWUoKTsKKyAgICAgIHJldHVybgorICAgICAgICBzdGF0aWNfY2FzdDxUICo+KHRoaXMpLT5nZXRHYXRoZXJTY2F0dGVyT3BDb3N0KEluc3RydWN0aW9uOjpMb2FkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJldFR5LCBBcmdzWzBdLCBWYXJNYXNrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFsaWdubWVudCk7CisgICAgfQorICAgIGNhc2UgSW50cmluc2ljOjpleHBlcmltZW50YWxfdmVjdG9yX3JlZHVjZV9hZGQ6CisgICAgY2FzZSBJbnRyaW5zaWM6OmV4cGVyaW1lbnRhbF92ZWN0b3JfcmVkdWNlX211bDoKKyAgICBjYXNlIEludHJpbnNpYzo6ZXhwZXJpbWVudGFsX3ZlY3Rvcl9yZWR1Y2VfYW5kOgorICAgIGNhc2UgSW50cmluc2ljOjpleHBlcmltZW50YWxfdmVjdG9yX3JlZHVjZV9vcjoKKyAgICBjYXNlIEludHJpbnNpYzo6ZXhwZXJpbWVudGFsX3ZlY3Rvcl9yZWR1Y2VfeG9yOgorICAgIGNhc2UgSW50cmluc2ljOjpleHBlcmltZW50YWxfdmVjdG9yX3JlZHVjZV9mYWRkOgorICAgIGNhc2UgSW50cmluc2ljOjpleHBlcmltZW50YWxfdmVjdG9yX3JlZHVjZV9mbXVsOgorICAgIGNhc2UgSW50cmluc2ljOjpleHBlcmltZW50YWxfdmVjdG9yX3JlZHVjZV9zbWF4OgorICAgIGNhc2UgSW50cmluc2ljOjpleHBlcmltZW50YWxfdmVjdG9yX3JlZHVjZV9zbWluOgorICAgIGNhc2UgSW50cmluc2ljOjpleHBlcmltZW50YWxfdmVjdG9yX3JlZHVjZV9mbWF4OgorICAgIGNhc2UgSW50cmluc2ljOjpleHBlcmltZW50YWxfdmVjdG9yX3JlZHVjZV9mbWluOgorICAgIGNhc2UgSW50cmluc2ljOjpleHBlcmltZW50YWxfdmVjdG9yX3JlZHVjZV91bWF4OgorICAgIGNhc2UgSW50cmluc2ljOjpleHBlcmltZW50YWxfdmVjdG9yX3JlZHVjZV91bWluOgorICAgICAgcmV0dXJuIGdldEludHJpbnNpY0luc3RyQ29zdChJSUQsIFJldFR5LCBBcmdzWzBdLT5nZXRUeXBlKCksIEZNRik7CisgICAgfQorICB9CisKKyAgLy8vIEdldCBpbnRyaW5zaWMgY29zdCBiYXNlZCBvbiBhcmd1bWVudCB0eXBlcy4KKyAgLy8vIElmIFNjYWxhcml6YXRpb25Db3N0UGFzc2VkIGlzIHN0ZDo6bnVtZXJpY19saW1pdHM8dW5zaWduZWQ+OjptYXgoKSwgdGhlCisgIC8vLyBjb3N0IG9mIHNjYWxhcml6aW5nIHRoZSBhcmd1bWVudHMgYW5kIHRoZSByZXR1cm4gdmFsdWUgd2lsbCBiZSBjb21wdXRlZAorICAvLy8gYmFzZWQgb24gdHlwZXMuCisgIHVuc2lnbmVkIGdldEludHJpbnNpY0luc3RyQ29zdCgKKyAgICAgIEludHJpbnNpYzo6SUQgSUlELCBUeXBlICpSZXRUeSwgQXJyYXlSZWY8VHlwZSAqPiBUeXMsIEZhc3RNYXRoRmxhZ3MgRk1GLAorICAgICAgdW5zaWduZWQgU2NhbGFyaXphdGlvbkNvc3RQYXNzZWQgPSBzdGQ6Om51bWVyaWNfbGltaXRzPHVuc2lnbmVkPjo6bWF4KCkpIHsKKyAgICBTbWFsbFZlY3Rvcjx1bnNpZ25lZCwgMj4gSVNEczsKKyAgICB1bnNpZ25lZCBTaW5nbGVDYWxsQ29zdCA9IDEwOyAvLyBMaWJyYXJ5IGNhbGwgY29zdC4gTWFrZSBpdCBleHBlbnNpdmUuCisgICAgc3dpdGNoIChJSUQpIHsKKyAgICBkZWZhdWx0OiB7CisgICAgICAvLyBBc3N1bWUgdGhhdCB3ZSBuZWVkIHRvIHNjYWxhcml6ZSB0aGlzIGludHJpbnNpYy4KKyAgICAgIHVuc2lnbmVkIFNjYWxhcml6YXRpb25Db3N0ID0gU2NhbGFyaXphdGlvbkNvc3RQYXNzZWQ7CisgICAgICB1bnNpZ25lZCBTY2FsYXJDYWxscyA9IDE7CisgICAgICBUeXBlICpTY2FsYXJSZXRUeSA9IFJldFR5OworICAgICAgaWYgKFJldFR5LT5pc1ZlY3RvclR5KCkpIHsKKyAgICAgICAgaWYgKFNjYWxhcml6YXRpb25Db3N0UGFzc2VkID09IHN0ZDo6bnVtZXJpY19saW1pdHM8dW5zaWduZWQ+OjptYXgoKSkKKyAgICAgICAgICBTY2FsYXJpemF0aW9uQ29zdCA9IGdldFNjYWxhcml6YXRpb25PdmVyaGVhZChSZXRUeSwgdHJ1ZSwgZmFsc2UpOworICAgICAgICBTY2FsYXJDYWxscyA9IHN0ZDo6bWF4KFNjYWxhckNhbGxzLCBSZXRUeS0+Z2V0VmVjdG9yTnVtRWxlbWVudHMoKSk7CisgICAgICAgIFNjYWxhclJldFR5ID0gUmV0VHktPmdldFNjYWxhclR5cGUoKTsKKyAgICAgIH0KKyAgICAgIFNtYWxsVmVjdG9yPFR5cGUgKiwgND4gU2NhbGFyVHlzOworICAgICAgZm9yICh1bnNpZ25lZCBpID0gMCwgaWUgPSBUeXMuc2l6ZSgpOyBpICE9IGllOyArK2kpIHsKKyAgICAgICAgVHlwZSAqVHkgPSBUeXNbaV07CisgICAgICAgIGlmIChUeS0+aXNWZWN0b3JUeSgpKSB7CisgICAgICAgICAgaWYgKFNjYWxhcml6YXRpb25Db3N0UGFzc2VkID09IHN0ZDo6bnVtZXJpY19saW1pdHM8dW5zaWduZWQ+OjptYXgoKSkKKyAgICAgICAgICAgIFNjYWxhcml6YXRpb25Db3N0ICs9IGdldFNjYWxhcml6YXRpb25PdmVyaGVhZChUeSwgZmFsc2UsIHRydWUpOworICAgICAgICAgIFNjYWxhckNhbGxzID0gc3RkOjptYXgoU2NhbGFyQ2FsbHMsIFR5LT5nZXRWZWN0b3JOdW1FbGVtZW50cygpKTsKKyAgICAgICAgICBUeSA9IFR5LT5nZXRTY2FsYXJUeXBlKCk7CisgICAgICAgIH0KKyAgICAgICAgU2NhbGFyVHlzLnB1c2hfYmFjayhUeSk7CisgICAgICB9CisgICAgICBpZiAoU2NhbGFyQ2FsbHMgPT0gMSkKKyAgICAgICAgcmV0dXJuIDE7IC8vIFJldHVybiBjb3N0IG9mIGEgc2NhbGFyIGludHJpbnNpYy4gQXNzdW1lIGl0IHRvIGJlIGNoZWFwLgorCisgICAgICB1bnNpZ25lZCBTY2FsYXJDb3N0ID0gc3RhdGljX2Nhc3Q8VCAqPih0aGlzKS0+Z2V0SW50cmluc2ljSW5zdHJDb3N0KAorICAgICAgICAgIElJRCwgU2NhbGFyUmV0VHksIFNjYWxhclR5cywgRk1GKTsKKworICAgICAgcmV0dXJuIFNjYWxhckNhbGxzICogU2NhbGFyQ29zdCArIFNjYWxhcml6YXRpb25Db3N0OworICAgIH0KKyAgICAvLyBMb29rIGZvciBpbnRyaW5zaWNzIHRoYXQgY2FuIGJlIGxvd2VyZWQgZGlyZWN0bHkgb3IgdHVybmVkIGludG8gYSBzY2FsYXIKKyAgICAvLyBpbnRyaW5zaWMgY2FsbC4KKyAgICBjYXNlIEludHJpbnNpYzo6c3FydDoKKyAgICAgIElTRHMucHVzaF9iYWNrKElTRDo6RlNRUlQpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBJbnRyaW5zaWM6OnNpbjoKKyAgICAgIElTRHMucHVzaF9iYWNrKElTRDo6RlNJTik7CisgICAgICBicmVhazsKKyAgICBjYXNlIEludHJpbnNpYzo6Y29zOgorICAgICAgSVNEcy5wdXNoX2JhY2soSVNEOjpGQ09TKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSW50cmluc2ljOjpleHA6CisgICAgICBJU0RzLnB1c2hfYmFjayhJU0Q6OkZFWFApOworICAgICAgYnJlYWs7CisgICAgY2FzZSBJbnRyaW5zaWM6OmV4cDI6CisgICAgICBJU0RzLnB1c2hfYmFjayhJU0Q6OkZFWFAyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSW50cmluc2ljOjpsb2c6CisgICAgICBJU0RzLnB1c2hfYmFjayhJU0Q6OkZMT0cpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBJbnRyaW5zaWM6OmxvZzEwOgorICAgICAgSVNEcy5wdXNoX2JhY2soSVNEOjpGTE9HMTApOworICAgICAgYnJlYWs7CisgICAgY2FzZSBJbnRyaW5zaWM6OmxvZzI6CisgICAgICBJU0RzLnB1c2hfYmFjayhJU0Q6OkZMT0cyKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSW50cmluc2ljOjpmYWJzOgorICAgICAgSVNEcy5wdXNoX2JhY2soSVNEOjpGQUJTKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSW50cmluc2ljOjptaW5udW06CisgICAgICBJU0RzLnB1c2hfYmFjayhJU0Q6OkZNSU5OVU0pOworICAgICAgaWYgKEZNRi5ub05hTnMoKSkKKyAgICAgICAgSVNEcy5wdXNoX2JhY2soSVNEOjpGTUlOTkFOKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSW50cmluc2ljOjptYXhudW06CisgICAgICBJU0RzLnB1c2hfYmFjayhJU0Q6OkZNQVhOVU0pOworICAgICAgaWYgKEZNRi5ub05hTnMoKSkKKyAgICAgICAgSVNEcy5wdXNoX2JhY2soSVNEOjpGTUFYTkFOKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSW50cmluc2ljOjpjb3B5c2lnbjoKKyAgICAgIElTRHMucHVzaF9iYWNrKElTRDo6RkNPUFlTSUdOKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSW50cmluc2ljOjpmbG9vcjoKKyAgICAgIElTRHMucHVzaF9iYWNrKElTRDo6RkZMT09SKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSW50cmluc2ljOjpjZWlsOgorICAgICAgSVNEcy5wdXNoX2JhY2soSVNEOjpGQ0VJTCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIEludHJpbnNpYzo6dHJ1bmM6CisgICAgICBJU0RzLnB1c2hfYmFjayhJU0Q6OkZUUlVOQyk7CisgICAgICBicmVhazsKKyAgICBjYXNlIEludHJpbnNpYzo6bmVhcmJ5aW50OgorICAgICAgSVNEcy5wdXNoX2JhY2soSVNEOjpGTkVBUkJZSU5UKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSW50cmluc2ljOjpyaW50OgorICAgICAgSVNEcy5wdXNoX2JhY2soSVNEOjpGUklOVCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIEludHJpbnNpYzo6cm91bmQ6CisgICAgICBJU0RzLnB1c2hfYmFjayhJU0Q6OkZST1VORCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIEludHJpbnNpYzo6cG93OgorICAgICAgSVNEcy5wdXNoX2JhY2soSVNEOjpGUE9XKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSW50cmluc2ljOjpmbWE6CisgICAgICBJU0RzLnB1c2hfYmFjayhJU0Q6OkZNQSk7CisgICAgICBicmVhazsKKyAgICBjYXNlIEludHJpbnNpYzo6Zm11bGFkZDoKKyAgICAgIElTRHMucHVzaF9iYWNrKElTRDo6Rk1BKTsKKyAgICAgIGJyZWFrOworICAgIC8vIEZJWE1FOiBXZSBzaG91bGQgcmV0dXJuIDAgd2hlbmV2ZXIgZ2V0SW50cmluc2ljQ29zdCA9PSBUQ0NfRnJlZS4KKyAgICBjYXNlIEludHJpbnNpYzo6bGlmZXRpbWVfc3RhcnQ6CisgICAgY2FzZSBJbnRyaW5zaWM6OmxpZmV0aW1lX2VuZDoKKyAgICBjYXNlIEludHJpbnNpYzo6c2lkZWVmZmVjdDoKKyAgICAgIHJldHVybiAwOworICAgIGNhc2UgSW50cmluc2ljOjptYXNrZWRfc3RvcmU6CisgICAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VCAqPih0aGlzKQorICAgICAgICAgIC0+Z2V0TWFza2VkTWVtb3J5T3BDb3N0KEluc3RydWN0aW9uOjpTdG9yZSwgVHlzWzBdLCAwLCAwKTsKKyAgICBjYXNlIEludHJpbnNpYzo6bWFza2VkX2xvYWQ6CisgICAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VCAqPih0aGlzKQorICAgICAgICAgIC0+Z2V0TWFza2VkTWVtb3J5T3BDb3N0KEluc3RydWN0aW9uOjpMb2FkLCBSZXRUeSwgMCwgMCk7CisgICAgY2FzZSBJbnRyaW5zaWM6OmV4cGVyaW1lbnRhbF92ZWN0b3JfcmVkdWNlX2FkZDoKKyAgICAgIHJldHVybiBzdGF0aWNfY2FzdDxUICo+KHRoaXMpLT5nZXRBcml0aG1ldGljUmVkdWN0aW9uQ29zdCgKKyAgICAgICAgICBJbnN0cnVjdGlvbjo6QWRkLCBUeXNbMF0sIC8qSXNQYWlyd2lzZUZvcm09Ki9mYWxzZSk7CisgICAgY2FzZSBJbnRyaW5zaWM6OmV4cGVyaW1lbnRhbF92ZWN0b3JfcmVkdWNlX211bDoKKyAgICAgIHJldHVybiBzdGF0aWNfY2FzdDxUICo+KHRoaXMpLT5nZXRBcml0aG1ldGljUmVkdWN0aW9uQ29zdCgKKyAgICAgICAgICBJbnN0cnVjdGlvbjo6TXVsLCBUeXNbMF0sIC8qSXNQYWlyd2lzZUZvcm09Ki9mYWxzZSk7CisgICAgY2FzZSBJbnRyaW5zaWM6OmV4cGVyaW1lbnRhbF92ZWN0b3JfcmVkdWNlX2FuZDoKKyAgICAgIHJldHVybiBzdGF0aWNfY2FzdDxUICo+KHRoaXMpLT5nZXRBcml0aG1ldGljUmVkdWN0aW9uQ29zdCgKKyAgICAgICAgICBJbnN0cnVjdGlvbjo6QW5kLCBUeXNbMF0sIC8qSXNQYWlyd2lzZUZvcm09Ki9mYWxzZSk7CisgICAgY2FzZSBJbnRyaW5zaWM6OmV4cGVyaW1lbnRhbF92ZWN0b3JfcmVkdWNlX29yOgorICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PFQgKj4odGhpcyktPmdldEFyaXRobWV0aWNSZWR1Y3Rpb25Db3N0KAorICAgICAgICAgIEluc3RydWN0aW9uOjpPciwgVHlzWzBdLCAvKklzUGFpcndpc2VGb3JtPSovZmFsc2UpOworICAgIGNhc2UgSW50cmluc2ljOjpleHBlcmltZW50YWxfdmVjdG9yX3JlZHVjZV94b3I6CisgICAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VCAqPih0aGlzKS0+Z2V0QXJpdGhtZXRpY1JlZHVjdGlvbkNvc3QoCisgICAgICAgICAgSW5zdHJ1Y3Rpb246OlhvciwgVHlzWzBdLCAvKklzUGFpcndpc2VGb3JtPSovZmFsc2UpOworICAgIGNhc2UgSW50cmluc2ljOjpleHBlcmltZW50YWxfdmVjdG9yX3JlZHVjZV9mYWRkOgorICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PFQgKj4odGhpcyktPmdldEFyaXRobWV0aWNSZWR1Y3Rpb25Db3N0KAorICAgICAgICAgIEluc3RydWN0aW9uOjpGQWRkLCBUeXNbMF0sIC8qSXNQYWlyd2lzZUZvcm09Ki9mYWxzZSk7CisgICAgY2FzZSBJbnRyaW5zaWM6OmV4cGVyaW1lbnRhbF92ZWN0b3JfcmVkdWNlX2ZtdWw6CisgICAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VCAqPih0aGlzKS0+Z2V0QXJpdGhtZXRpY1JlZHVjdGlvbkNvc3QoCisgICAgICAgICAgSW5zdHJ1Y3Rpb246OkZNdWwsIFR5c1swXSwgLypJc1BhaXJ3aXNlRm9ybT0qL2ZhbHNlKTsKKyAgICBjYXNlIEludHJpbnNpYzo6ZXhwZXJpbWVudGFsX3ZlY3Rvcl9yZWR1Y2Vfc21heDoKKyAgICBjYXNlIEludHJpbnNpYzo6ZXhwZXJpbWVudGFsX3ZlY3Rvcl9yZWR1Y2Vfc21pbjoKKyAgICBjYXNlIEludHJpbnNpYzo6ZXhwZXJpbWVudGFsX3ZlY3Rvcl9yZWR1Y2VfZm1heDoKKyAgICBjYXNlIEludHJpbnNpYzo6ZXhwZXJpbWVudGFsX3ZlY3Rvcl9yZWR1Y2VfZm1pbjoKKyAgICAgIHJldHVybiBzdGF0aWNfY2FzdDxUICo+KHRoaXMpLT5nZXRNaW5NYXhSZWR1Y3Rpb25Db3N0KAorICAgICAgICAgIFR5c1swXSwgQ21wSW5zdDo6bWFrZUNtcFJlc3VsdFR5cGUoVHlzWzBdKSwgLypJc1BhaXJ3aXNlRm9ybT0qL2ZhbHNlLAorICAgICAgICAgIC8qSXNTaWduZWQ9Ki90cnVlKTsKKyAgICBjYXNlIEludHJpbnNpYzo6ZXhwZXJpbWVudGFsX3ZlY3Rvcl9yZWR1Y2VfdW1heDoKKyAgICBjYXNlIEludHJpbnNpYzo6ZXhwZXJpbWVudGFsX3ZlY3Rvcl9yZWR1Y2VfdW1pbjoKKyAgICAgIHJldHVybiBzdGF0aWNfY2FzdDxUICo+KHRoaXMpLT5nZXRNaW5NYXhSZWR1Y3Rpb25Db3N0KAorICAgICAgICAgIFR5c1swXSwgQ21wSW5zdDo6bWFrZUNtcFJlc3VsdFR5cGUoVHlzWzBdKSwgLypJc1BhaXJ3aXNlRm9ybT0qL2ZhbHNlLAorICAgICAgICAgIC8qSXNTaWduZWQ9Ki9mYWxzZSk7CisgICAgY2FzZSBJbnRyaW5zaWM6OmN0cG9wOgorICAgICAgSVNEcy5wdXNoX2JhY2soSVNEOjpDVFBPUCk7CisgICAgICAvLyBJbiBjYXNlIG9mIGxlZ2FsaXphdGlvbiB1c2UgVENDX0V4cGVuc2l2ZS4gVGhpcyBpcyBjaGVhcGVyIHRoYW4gYQorICAgICAgLy8gbGlicmFyeSBjYWxsIGJ1dCBzdGlsbCBub3QgYSBjaGVhcCBpbnN0cnVjdGlvbi4KKyAgICAgIFNpbmdsZUNhbGxDb3N0ID0gVGFyZ2V0VHJhbnNmb3JtSW5mbzo6VENDX0V4cGVuc2l2ZTsKKyAgICAgIGJyZWFrOworICAgIC8vIEZJWE1FOiBjdGx6LCBjdHR6LCAuLi4KKyAgICB9CisKKyAgICBjb25zdCBUYXJnZXRMb3dlcmluZ0Jhc2UgKlRMSSA9IGdldFRMSSgpOworICAgIHN0ZDo6cGFpcjx1bnNpZ25lZCwgTVZUPiBMVCA9IFRMSS0+Z2V0VHlwZUxlZ2FsaXphdGlvbkNvc3QoREwsIFJldFR5KTsKKworICAgIFNtYWxsVmVjdG9yPHVuc2lnbmVkLCAyPiBMZWdhbENvc3Q7CisgICAgU21hbGxWZWN0b3I8dW5zaWduZWQsIDI+IEN1c3RvbUNvc3Q7CisgICAgZm9yICh1bnNpZ25lZCBJU0QgOiBJU0RzKSB7CisgICAgICBpZiAoVExJLT5pc09wZXJhdGlvbkxlZ2FsT3JQcm9tb3RlKElTRCwgTFQuc2Vjb25kKSkgeworICAgICAgICBpZiAoSUlEID09IEludHJpbnNpYzo6ZmFicyAmJiBUTEktPmlzRkFic0ZyZWUoTFQuc2Vjb25kKSkgeworICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisKKyAgICAgICAgLy8gVGhlIG9wZXJhdGlvbiBpcyBsZWdhbC4gQXNzdW1lIGl0IGNvc3RzIDEuCisgICAgICAgIC8vIElmIHRoZSB0eXBlIGlzIHNwbGl0IHRvIG11bHRpcGxlIHJlZ2lzdGVycywgYXNzdW1lIHRoYXQgdGhlcmUgaXMgc29tZQorICAgICAgICAvLyBvdmVyaGVhZCB0byB0aGlzLgorICAgICAgICAvLyBUT0RPOiBPbmNlIHdlIGhhdmUgZXh0cmFjdC9pbnNlcnQgc3VidmVjdG9yIGNvc3Qgd2UgbmVlZCB0byB1c2UgdGhlbS4KKyAgICAgICAgaWYgKExULmZpcnN0ID4gMSkKKyAgICAgICAgICBMZWdhbENvc3QucHVzaF9iYWNrKExULmZpcnN0ICogMik7CisgICAgICAgIGVsc2UKKyAgICAgICAgICBMZWdhbENvc3QucHVzaF9iYWNrKExULmZpcnN0ICogMSk7CisgICAgICB9IGVsc2UgaWYgKCFUTEktPmlzT3BlcmF0aW9uRXhwYW5kKElTRCwgTFQuc2Vjb25kKSkgeworICAgICAgICAvLyBJZiB0aGUgb3BlcmF0aW9uIGlzIGN1c3RvbSBsb3dlcmVkIHRoZW4gYXNzdW1lCisgICAgICAgIC8vIHRoYXQgdGhlIGNvZGUgaXMgdHdpY2UgYXMgZXhwZW5zaXZlLgorICAgICAgICBDdXN0b21Db3N0LnB1c2hfYmFjayhMVC5maXJzdCAqIDIpOworICAgICAgfQorICAgIH0KKworICAgIGF1dG8gTWluTGVnYWxDb3N0SSA9IHN0ZDo6bWluX2VsZW1lbnQoTGVnYWxDb3N0LmJlZ2luKCksIExlZ2FsQ29zdC5lbmQoKSk7CisgICAgaWYgKE1pbkxlZ2FsQ29zdEkgIT0gTGVnYWxDb3N0LmVuZCgpKQorICAgICAgcmV0dXJuICpNaW5MZWdhbENvc3RJOworCisgICAgYXV0byBNaW5DdXN0b21Db3N0SSA9IHN0ZDo6bWluX2VsZW1lbnQoQ3VzdG9tQ29zdC5iZWdpbigpLCBDdXN0b21Db3N0LmVuZCgpKTsKKyAgICBpZiAoTWluQ3VzdG9tQ29zdEkgIT0gQ3VzdG9tQ29zdC5lbmQoKSkKKyAgICAgIHJldHVybiAqTWluQ3VzdG9tQ29zdEk7CisKKyAgICAvLyBJZiB3ZSBjYW4ndCBsb3dlciBmbXVsYWRkIGludG8gYW4gRk1BIGVzdGltYXRlIHRoZSBjb3N0IGFzIGEgZmxvYXRpbmcKKyAgICAvLyBwb2ludCBtdWwgZm9sbG93ZWQgYnkgYW4gYWRkLgorICAgIGlmIChJSUQgPT0gSW50cmluc2ljOjpmbXVsYWRkKQorICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PFQgKj4odGhpcykKKyAgICAgICAgICAgICAgICAgLT5nZXRBcml0aG1ldGljSW5zdHJDb3N0KEJpbmFyeU9wZXJhdG9yOjpGTXVsLCBSZXRUeSkgKworICAgICAgICAgICAgIHN0YXRpY19jYXN0PFQgKj4odGhpcykKKyAgICAgICAgICAgICAgICAgLT5nZXRBcml0aG1ldGljSW5zdHJDb3N0KEJpbmFyeU9wZXJhdG9yOjpGQWRkLCBSZXRUeSk7CisKKyAgICAvLyBFbHNlLCBhc3N1bWUgdGhhdCB3ZSBuZWVkIHRvIHNjYWxhcml6ZSB0aGlzIGludHJpbnNpYy4gRm9yIG1hdGggYnVpbHRpbnMKKyAgICAvLyB0aGlzIHdpbGwgZW1pdCBhIGNvc3RseSBsaWJjYWxsLCBhZGRpbmcgY2FsbCBvdmVyaGVhZCBhbmQgc3BpbGxzLiBNYWtlIGl0CisgICAgLy8gdmVyeSBleHBlbnNpdmUuCisgICAgaWYgKFJldFR5LT5pc1ZlY3RvclR5KCkpIHsKKyAgICAgIHVuc2lnbmVkIFNjYWxhcml6YXRpb25Db3N0ID0KKyAgICAgICAgICAoKFNjYWxhcml6YXRpb25Db3N0UGFzc2VkICE9IHN0ZDo6bnVtZXJpY19saW1pdHM8dW5zaWduZWQ+OjptYXgoKSkKKyAgICAgICAgICAgICAgID8gU2NhbGFyaXphdGlvbkNvc3RQYXNzZWQKKyAgICAgICAgICAgICAgIDogZ2V0U2NhbGFyaXphdGlvbk92ZXJoZWFkKFJldFR5LCB0cnVlLCBmYWxzZSkpOworICAgICAgdW5zaWduZWQgU2NhbGFyQ2FsbHMgPSBSZXRUeS0+Z2V0VmVjdG9yTnVtRWxlbWVudHMoKTsKKyAgICAgIFNtYWxsVmVjdG9yPFR5cGUgKiwgND4gU2NhbGFyVHlzOworICAgICAgZm9yICh1bnNpZ25lZCBpID0gMCwgaWUgPSBUeXMuc2l6ZSgpOyBpICE9IGllOyArK2kpIHsKKyAgICAgICAgVHlwZSAqVHkgPSBUeXNbaV07CisgICAgICAgIGlmIChUeS0+aXNWZWN0b3JUeSgpKQorICAgICAgICAgIFR5ID0gVHktPmdldFNjYWxhclR5cGUoKTsKKyAgICAgICAgU2NhbGFyVHlzLnB1c2hfYmFjayhUeSk7CisgICAgICB9CisgICAgICB1bnNpZ25lZCBTY2FsYXJDb3N0ID0gc3RhdGljX2Nhc3Q8VCAqPih0aGlzKS0+Z2V0SW50cmluc2ljSW5zdHJDb3N0KAorICAgICAgICAgIElJRCwgUmV0VHktPmdldFNjYWxhclR5cGUoKSwgU2NhbGFyVHlzLCBGTUYpOworICAgICAgZm9yICh1bnNpZ25lZCBpID0gMCwgaWUgPSBUeXMuc2l6ZSgpOyBpICE9IGllOyArK2kpIHsKKyAgICAgICAgaWYgKFR5c1tpXS0+aXNWZWN0b3JUeSgpKSB7CisgICAgICAgICAgaWYgKFNjYWxhcml6YXRpb25Db3N0UGFzc2VkID09IHN0ZDo6bnVtZXJpY19saW1pdHM8dW5zaWduZWQ+OjptYXgoKSkKKyAgICAgICAgICAgIFNjYWxhcml6YXRpb25Db3N0ICs9IGdldFNjYWxhcml6YXRpb25PdmVyaGVhZChUeXNbaV0sIGZhbHNlLCB0cnVlKTsKKyAgICAgICAgICBTY2FsYXJDYWxscyA9IHN0ZDo6bWF4KFNjYWxhckNhbGxzLCBUeXNbaV0tPmdldFZlY3Rvck51bUVsZW1lbnRzKCkpOworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIHJldHVybiBTY2FsYXJDYWxscyAqIFNjYWxhckNvc3QgKyBTY2FsYXJpemF0aW9uQ29zdDsKKyAgICB9CisKKyAgICAvLyBUaGlzIGlzIGdvaW5nIHRvIGJlIHR1cm5lZCBpbnRvIGEgbGlicmFyeSBjYWxsLCBtYWtlIGl0IGV4cGVuc2l2ZS4KKyAgICByZXR1cm4gU2luZ2xlQ2FsbENvc3Q7CisgIH0KKworICAvLy8gXGJyaWVmIENvbXB1dGUgYSBjb3N0IG9mIHRoZSBnaXZlbiBjYWxsIGluc3RydWN0aW9uLgorICAvLy8KKyAgLy8vIENvbXB1dGUgdGhlIGNvc3Qgb2YgY2FsbGluZyBmdW5jdGlvbiBGIHdpdGggcmV0dXJuIHR5cGUgUmV0VHkgYW5kCisgIC8vLyBhcmd1bWVudCB0eXBlcyBUeXMuIEYgbWlnaHQgYmUgbnVsbHB0ciwgaW4gdGhpcyBjYXNlIHRoZSBjb3N0IG9mIGFuCisgIC8vLyBhcmJpdHJhcnkgY2FsbCB3aXRoIHRoZSBzcGVjaWZpZWQgc2lnbmF0dXJlIHdpbGwgYmUgcmV0dXJuZWQuCisgIC8vLyBUaGlzIGlzIHVzZWQsIGZvciBpbnN0YW5jZSwgIHdoZW4gd2UgZXN0aW1hdGUgY2FsbCBvZiBhIHZlY3RvcgorICAvLy8gY291bnRlcnBhcnQgb2YgdGhlIGdpdmVuIGZ1bmN0aW9uLgorICAvLy8gXHBhcmFtIEYgQ2FsbGVkIGZ1bmN0aW9uLCBtaWdodCBiZSBudWxscHRyLgorICAvLy8gXHBhcmFtIFJldFR5IFJldHVybiB2YWx1ZSB0eXBlcy4KKyAgLy8vIFxwYXJhbSBUeXMgQXJndW1lbnQgdHlwZXMuCisgIC8vLyBccmV0dXJucyBUaGUgY29zdCBvZiBDYWxsIGluc3RydWN0aW9uLgorICB1bnNpZ25lZCBnZXRDYWxsSW5zdHJDb3N0KEZ1bmN0aW9uICpGLCBUeXBlICpSZXRUeSwgQXJyYXlSZWY8VHlwZSAqPiBUeXMpIHsKKyAgICByZXR1cm4gMTA7CisgIH0KKworICB1bnNpZ25lZCBnZXROdW1iZXJPZlBhcnRzKFR5cGUgKlRwKSB7CisgICAgc3RkOjpwYWlyPHVuc2lnbmVkLCBNVlQ+IExUID0gZ2V0VExJKCktPmdldFR5cGVMZWdhbGl6YXRpb25Db3N0KERMLCBUcCk7CisgICAgcmV0dXJuIExULmZpcnN0OworICB9CisKKyAgdW5zaWduZWQgZ2V0QWRkcmVzc0NvbXB1dGF0aW9uQ29zdChUeXBlICpUeSwgU2NhbGFyRXZvbHV0aW9uICosCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU0NFViAqKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICAvLy8gVHJ5IHRvIGNhbGN1bGF0ZSBhcml0aG1ldGljIGFuZCBzaHVmZmxlIG9wIGNvc3RzIGZvciByZWR1Y3Rpb24gb3BlcmF0aW9ucy4KKyAgLy8vIFdlJ3JlIGFzc3VtaW5nIHRoYXQgcmVkdWN0aW9uIG9wZXJhdGlvbiBhcmUgcGVyZm9ybWluZyB0aGUgZm9sbG93aW5nIHdheToKKyAgLy8vIDEuIE5vbi1wYWlyd2lzZSByZWR1Y3Rpb24KKyAgLy8vICV2YWwxID0gc2h1ZmZsZXZlY3RvcjxuIHggdD4gJXZhbCwgPG4geCB0PiAldW5kZWYsCisgIC8vLyA8biB4IGkzMj4gPGkzMiBuLzIsIGkzMiBuLzIgKyAxLCAuLi4sIGkzMiBuLCBpMzIgdW5kZWYsIC4uLiwgaTMyIHVuZGVmPgorICAvLy8gICAgICAgICAgICBcLS0tLS0tLS0tLS0tLS0tLXYtLS0tLS0tLS0tLS0tLyAgXC0tLS0tLS0tLS12LS0tLS0tLS0tLS0tLworICAvLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgbi8yIGVsZW1lbnRzICAgICAgICAgICAgICAgbi8yIGVsZW1lbnRzCisgIC8vLyAlcmVkMSA9IG9wIDxuIHggdD4gJXZhbCwgPG4geCB0PiB2YWwxCisgIC8vLyBBZnRlciB0aGlzIG9wZXJhdGlvbiB3ZSBoYXZlIGEgdmVjdG9yICVyZWQxIHdoZXJlIG9ubHkgdGhlIGZpcnN0IG4vMgorICAvLy8gZWxlbWVudHMgYXJlIG1lYW5pbmdmdWwsIHRoZSBzZWNvbmQgbi8yIGVsZW1lbnRzIGFyZSB1bmRlZmluZWQgYW5kIGNhbiBiZQorICAvLy8gZHJvcHBlZC4gQWxsIG90aGVyIG9wZXJhdGlvbnMgYXJlIGFjdHVhbGx5IHdvcmtpbmcgd2l0aCB0aGUgdmVjdG9yIG9mCisgIC8vLyBsZW5ndGggbi8yLCBub3QgbiwgdGhvdWdoIHRoZSByZWFsIHZlY3RvciBsZW5ndGggaXMgc3RpbGwgbi4KKyAgLy8vICV2YWwyID0gc2h1ZmZsZXZlY3RvcjxuIHggdD4gJXJlZDEsIDxuIHggdD4gJXVuZGVmLAorICAvLy8gPG4geCBpMzI+IDxpMzIgbi80LCBpMzIgbi80ICsgMSwgLi4uLCBpMzIgbi8yLCBpMzIgdW5kZWYsIC4uLiwgaTMyIHVuZGVmPgorICAvLy8gICAgICAgICAgICBcLS0tLS0tLS0tLS0tLS0tLXYtLS0tLS0tLS0tLS0tLyAgXC0tLS0tLS0tLS12LS0tLS0tLS0tLS0tLworICAvLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgbi80IGVsZW1lbnRzICAgICAgICAgICAgICAgMypuLzQgZWxlbWVudHMKKyAgLy8vICVyZWQyID0gb3AgPG4geCB0PiAlcmVkMSwgPG4geCB0PiB2YWwyICAtIHdvcmtpbmcgd2l0aCB0aGUgdmVjdG9yIG9mCisgIC8vLyBsZW5ndGggbi8yLCB0aGUgcmVzdWx0aW5nIHZlY3RvciBoYXMgbGVuZ3RoIG4vNCBldGMuCisgIC8vLyAyLiBQYWlyd2lzZSByZWR1Y3Rpb246CisgIC8vLyBFdmVyeXRoaW5nIGlzIHRoZSBzYW1lIGV4Y2VwdCBmb3IgYW4gYWRkaXRpb25hbCBzaHVmZmxlIG9wZXJhdGlvbiB3aGljaAorICAvLy8gaXMgdXNlZCB0byBwcm9kdWNlIG9wZXJhbmRzIGZvciBwYWlyd2lzZSBraW5kIG9mIHJlZHVjdGlvbnMuCisgIC8vLyAldmFsMSA9IHNodWZmbGV2ZWN0b3I8biB4IHQ+ICV2YWwsIDxuIHggdD4gJXVuZGVmLAorICAvLy8gPG4geCBpMzI+IDxpMzIgMCwgaTMyIDIsIC4uLiwgaTMyIG4tMiwgaTMyIHVuZGVmLCAuLi4sIGkzMiB1bmRlZj4KKyAgLy8vICAgICAgICAgICAgXC0tLS0tLS0tLS0tLS12LS0tLS0tLS0tLS8gIFwtLS0tLS0tLS0tdi0tLS0tLS0tLS0tLS8KKyAgLy8vICAgICAgICAgICAgICAgICAgIG4vMiBlbGVtZW50cyAgICAgICAgICAgICAgIG4vMiBlbGVtZW50cworICAvLy8gJXZhbDIgPSBzaHVmZmxldmVjdG9yPG4geCB0PiAldmFsLCA8biB4IHQ+ICV1bmRlZiwKKyAgLy8vIDxuIHggaTMyPiA8aTMyIDEsIGkzMiAzLCAuLi4sIGkzMiBuLTEsIGkzMiB1bmRlZiwgLi4uLCBpMzIgdW5kZWY+CisgIC8vLyAgICAgICAgICAgIFwtLS0tLS0tLS0tLS0tdi0tLS0tLS0tLS0vICBcLS0tLS0tLS0tLXYtLS0tLS0tLS0tLS0vCisgIC8vLyAgICAgICAgICAgICAgICAgICBuLzIgZWxlbWVudHMgICAgICAgICAgICAgICBuLzIgZWxlbWVudHMKKyAgLy8vICVyZWQxID0gb3AgPG4geCB0PiAldmFsMSwgPG4geCB0PiB2YWwyCisgIC8vLyBBZ2FpbiwgdGhlIG9wZXJhdGlvbiBpcyBwZXJmb3JtZWQgb24gPG4geCB0PiB2ZWN0b3IsIGJ1dCB0aGUgcmVzdWx0aW5nCisgIC8vLyB2ZWN0b3IgJXJlZDEgaXMgPG4vMiB4IHQ+IHZlY3Rvci4KKyAgLy8vCisgIC8vLyBUaGUgY29zdCBtb2RlbCBzaG91bGQgdGFrZSBpbnRvIGFjY291bnQgdGhhdCB0aGUgYWN0dWFsIGxlbmd0aCBvZiB0aGUKKyAgLy8vIHZlY3RvciBpcyByZWR1Y2VkIG9uIGVhY2ggaXRlcmF0aW9uLgorICB1bnNpZ25lZCBnZXRBcml0aG1ldGljUmVkdWN0aW9uQ29zdCh1bnNpZ25lZCBPcGNvZGUsIFR5cGUgKlR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIElzUGFpcndpc2UpIHsKKyAgICBhc3NlcnQoVHktPmlzVmVjdG9yVHkoKSAmJiAiRXhwZWN0IGEgdmVjdG9yIHR5cGUiKTsKKyAgICBUeXBlICpTY2FsYXJUeSA9IFR5LT5nZXRWZWN0b3JFbGVtZW50VHlwZSgpOworICAgIHVuc2lnbmVkIE51bVZlY0VsdHMgPSBUeS0+Z2V0VmVjdG9yTnVtRWxlbWVudHMoKTsKKyAgICB1bnNpZ25lZCBOdW1SZWR1eExldmVscyA9IExvZzJfMzIoTnVtVmVjRWx0cyk7CisgICAgdW5zaWduZWQgQXJpdGhDb3N0ID0gMDsKKyAgICB1bnNpZ25lZCBTaHVmZmxlQ29zdCA9IDA7CisgICAgYXV0byAqQ29uY3JldGVUVEkgPSBzdGF0aWNfY2FzdDxUICo+KHRoaXMpOworICAgIHN0ZDo6cGFpcjx1bnNpZ25lZCwgTVZUPiBMVCA9CisgICAgICAgIENvbmNyZXRlVFRJLT5nZXRUTEkoKS0+Z2V0VHlwZUxlZ2FsaXphdGlvbkNvc3QoREwsIFR5KTsKKyAgICB1bnNpZ25lZCBMb25nVmVjdG9yQ291bnQgPSAwOworICAgIHVuc2lnbmVkIE1WVExlbiA9CisgICAgICAgIExULnNlY29uZC5pc1ZlY3RvcigpID8gTFQuc2Vjb25kLmdldFZlY3Rvck51bUVsZW1lbnRzKCkgOiAxOworICAgIHdoaWxlIChOdW1WZWNFbHRzID4gTVZUTGVuKSB7CisgICAgICBOdW1WZWNFbHRzIC89IDI7CisgICAgICAvLyBBc3N1bWUgdGhlIHBhaXJ3aXNlIHNodWZmbGVzIGFkZCBhIGNvc3QuCisgICAgICBTaHVmZmxlQ29zdCArPSAoSXNQYWlyd2lzZSArIDEpICoKKyAgICAgICAgICAgICAgICAgICAgIENvbmNyZXRlVFRJLT5nZXRTaHVmZmxlQ29zdChUVEk6OlNLX0V4dHJhY3RTdWJ2ZWN0b3IsIFR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bVZlY0VsdHMsIFR5KTsKKyAgICAgIEFyaXRoQ29zdCArPSBDb25jcmV0ZVRUSS0+Z2V0QXJpdGhtZXRpY0luc3RyQ29zdChPcGNvZGUsIFR5KTsKKyAgICAgIFR5ID0gVmVjdG9yVHlwZTo6Z2V0KFNjYWxhclR5LCBOdW1WZWNFbHRzKTsKKyAgICAgICsrTG9uZ1ZlY3RvckNvdW50OworICAgIH0KKyAgICAvLyBUaGUgbWluaW1hbCBsZW5ndGggb2YgdGhlIHZlY3RvciBpcyBsaW1pdGVkIGJ5IHRoZSByZWFsIGxlbmd0aCBvZiB2ZWN0b3IKKyAgICAvLyBvcGVyYXRpb25zIHBlcmZvcm1lZCBvbiB0aGUgY3VycmVudCBwbGF0Zm9ybS4gVGhhdCdzIHdoeSBzZXZlcmFsIGZpbmFsCisgICAgLy8gcmVkdWN0aW9uIG9wZXJhdGlvbnMgYXJlIHBlcmZvcm1lZCBvbiB0aGUgdmVjdG9ycyB3aXRoIHRoZSBzYW1lCisgICAgLy8gYXJjaGl0ZWN0dXJlLWRlcGVuZGVudCBsZW5ndGguCisgICAgU2h1ZmZsZUNvc3QgKz0gKE51bVJlZHV4TGV2ZWxzIC0gTG9uZ1ZlY3RvckNvdW50KSAqIChJc1BhaXJ3aXNlICsgMSkgKgorICAgICAgICAgICAgICAgICAgIENvbmNyZXRlVFRJLT5nZXRTaHVmZmxlQ29zdChUVEk6OlNLX0V4dHJhY3RTdWJ2ZWN0b3IsIFR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdW1WZWNFbHRzLCBUeSk7CisgICAgQXJpdGhDb3N0ICs9IChOdW1SZWR1eExldmVscyAtIExvbmdWZWN0b3JDb3VudCkgKgorICAgICAgICAgICAgICAgICBDb25jcmV0ZVRUSS0+Z2V0QXJpdGhtZXRpY0luc3RyQ29zdChPcGNvZGUsIFR5KTsKKyAgICByZXR1cm4gU2h1ZmZsZUNvc3QgKyBBcml0aENvc3QgKyBnZXRTY2FsYXJpemF0aW9uT3ZlcmhlYWQoVHksIGZhbHNlLCB0cnVlKTsKKyAgfQorCisgIC8vLyBUcnkgdG8gY2FsY3VsYXRlIG9wIGNvc3RzIGZvciBtaW4vbWF4IHJlZHVjdGlvbiBvcGVyYXRpb25zLgorICAvLy8gXHBhcmFtIENvbmRUeSBDb25kaXRpb25hbCB0eXBlIGZvciB0aGUgU2VsZWN0IGluc3RydWN0aW9uLgorICB1bnNpZ25lZCBnZXRNaW5NYXhSZWR1Y3Rpb25Db3N0KFR5cGUgKlR5LCBUeXBlICpDb25kVHksIGJvb2wgSXNQYWlyd2lzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sKSB7CisgICAgYXNzZXJ0KFR5LT5pc1ZlY3RvclR5KCkgJiYgIkV4cGVjdCBhIHZlY3RvciB0eXBlIik7CisgICAgVHlwZSAqU2NhbGFyVHkgPSBUeS0+Z2V0VmVjdG9yRWxlbWVudFR5cGUoKTsKKyAgICBUeXBlICpTY2FsYXJDb25kVHkgPSBDb25kVHktPmdldFZlY3RvckVsZW1lbnRUeXBlKCk7CisgICAgdW5zaWduZWQgTnVtVmVjRWx0cyA9IFR5LT5nZXRWZWN0b3JOdW1FbGVtZW50cygpOworICAgIHVuc2lnbmVkIE51bVJlZHV4TGV2ZWxzID0gTG9nMl8zMihOdW1WZWNFbHRzKTsKKyAgICB1bnNpZ25lZCBDbXBPcGNvZGU7CisgICAgaWYgKFR5LT5pc0ZQT3JGUFZlY3RvclR5KCkpIHsKKyAgICAgIENtcE9wY29kZSA9IEluc3RydWN0aW9uOjpGQ21wOworICAgIH0gZWxzZSB7CisgICAgICBhc3NlcnQoVHktPmlzSW50T3JJbnRWZWN0b3JUeSgpICYmCisgICAgICAgICAgICAgImV4cGVjdGluZyBmbG9hdGluZyBwb2ludCBvciBpbnRlZ2VyIHR5cGUgZm9yIG1pbi9tYXggcmVkdWN0aW9uIik7CisgICAgICBDbXBPcGNvZGUgPSBJbnN0cnVjdGlvbjo6SUNtcDsKKyAgICB9CisgICAgdW5zaWduZWQgTWluTWF4Q29zdCA9IDA7CisgICAgdW5zaWduZWQgU2h1ZmZsZUNvc3QgPSAwOworICAgIGF1dG8gKkNvbmNyZXRlVFRJID0gc3RhdGljX2Nhc3Q8VCAqPih0aGlzKTsKKyAgICBzdGQ6OnBhaXI8dW5zaWduZWQsIE1WVD4gTFQgPQorICAgICAgICBDb25jcmV0ZVRUSS0+Z2V0VExJKCktPmdldFR5cGVMZWdhbGl6YXRpb25Db3N0KERMLCBUeSk7CisgICAgdW5zaWduZWQgTG9uZ1ZlY3RvckNvdW50ID0gMDsKKyAgICB1bnNpZ25lZCBNVlRMZW4gPQorICAgICAgICBMVC5zZWNvbmQuaXNWZWN0b3IoKSA/IExULnNlY29uZC5nZXRWZWN0b3JOdW1FbGVtZW50cygpIDogMTsKKyAgICB3aGlsZSAoTnVtVmVjRWx0cyA+IE1WVExlbikgeworICAgICAgTnVtVmVjRWx0cyAvPSAyOworICAgICAgLy8gQXNzdW1lIHRoZSBwYWlyd2lzZSBzaHVmZmxlcyBhZGQgYSBjb3N0LgorICAgICAgU2h1ZmZsZUNvc3QgKz0gKElzUGFpcndpc2UgKyAxKSAqCisgICAgICAgICAgICAgICAgICAgICBDb25jcmV0ZVRUSS0+Z2V0U2h1ZmZsZUNvc3QoVFRJOjpTS19FeHRyYWN0U3VidmVjdG9yLCBUeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdW1WZWNFbHRzLCBUeSk7CisgICAgICBNaW5NYXhDb3N0ICs9CisgICAgICAgICAgQ29uY3JldGVUVEktPmdldENtcFNlbEluc3RyQ29zdChDbXBPcGNvZGUsIFR5LCBDb25kVHksIG51bGxwdHIpICsKKyAgICAgICAgICBDb25jcmV0ZVRUSS0+Z2V0Q21wU2VsSW5zdHJDb3N0KEluc3RydWN0aW9uOjpTZWxlY3QsIFR5LCBDb25kVHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudWxscHRyKTsKKyAgICAgIFR5ID0gVmVjdG9yVHlwZTo6Z2V0KFNjYWxhclR5LCBOdW1WZWNFbHRzKTsKKyAgICAgIENvbmRUeSA9IFZlY3RvclR5cGU6OmdldChTY2FsYXJDb25kVHksIE51bVZlY0VsdHMpOworICAgICAgKytMb25nVmVjdG9yQ291bnQ7CisgICAgfQorICAgIC8vIFRoZSBtaW5pbWFsIGxlbmd0aCBvZiB0aGUgdmVjdG9yIGlzIGxpbWl0ZWQgYnkgdGhlIHJlYWwgbGVuZ3RoIG9mIHZlY3RvcgorICAgIC8vIG9wZXJhdGlvbnMgcGVyZm9ybWVkIG9uIHRoZSBjdXJyZW50IHBsYXRmb3JtLiBUaGF0J3Mgd2h5IHNldmVyYWwgZmluYWwKKyAgICAvLyByZWR1Y3Rpb24gb3BlcnRpb25zIGFyZSBwZXJmb21lZCBvbiB0aGUgdmVjdG9ycyB3aXRoIHRoZSBzYW1lCisgICAgLy8gYXJjaGl0ZWN0dXJlLWRlcGVuZGVudCBsZW5ndGguCisgICAgU2h1ZmZsZUNvc3QgKz0gKE51bVJlZHV4TGV2ZWxzIC0gTG9uZ1ZlY3RvckNvdW50KSAqIChJc1BhaXJ3aXNlICsgMSkgKgorICAgICAgICAgICAgICAgICAgIENvbmNyZXRlVFRJLT5nZXRTaHVmZmxlQ29zdChUVEk6OlNLX0V4dHJhY3RTdWJ2ZWN0b3IsIFR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdW1WZWNFbHRzLCBUeSk7CisgICAgTWluTWF4Q29zdCArPQorICAgICAgICAoTnVtUmVkdXhMZXZlbHMgLSBMb25nVmVjdG9yQ291bnQpICoKKyAgICAgICAgKENvbmNyZXRlVFRJLT5nZXRDbXBTZWxJbnN0ckNvc3QoQ21wT3Bjb2RlLCBUeSwgQ29uZFR5LCBudWxscHRyKSArCisgICAgICAgICBDb25jcmV0ZVRUSS0+Z2V0Q21wU2VsSW5zdHJDb3N0KEluc3RydWN0aW9uOjpTZWxlY3QsIFR5LCBDb25kVHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGxwdHIpKTsKKyAgICAvLyBOZWVkIDMgZXh0cmFjdGVsZW1lbnQgaW5zdHJ1Y3Rpb25zIGZvciBzY2FsYXJpemF0aW9uICsgYW4gYWRkaXRpb25hbAorICAgIC8vIHNjYWxhciBzZWxlY3QgaW5zdHJ1Y3Rpb24uCisgICAgcmV0dXJuIFNodWZmbGVDb3N0ICsgTWluTWF4Q29zdCArCisgICAgICAgICAgIDMgKiBnZXRTY2FsYXJpemF0aW9uT3ZlcmhlYWQoVHksIC8qSW5zZXJ0PSovZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypFeHRyYWN0PSovdHJ1ZSkgKworICAgICAgICAgICBDb25jcmV0ZVRUSS0+Z2V0Q21wU2VsSW5zdHJDb3N0KEluc3RydWN0aW9uOjpTZWxlY3QsIFNjYWxhclR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNjYWxhckNvbmRUeSwgbnVsbHB0cik7CisgIH0KKworICB1bnNpZ25lZCBnZXRWZWN0b3JTcGxpdENvc3QoKSB7IHJldHVybiAxOyB9CisKKyAgLy8vIEB9Cit9OworCisvLy8gXGJyaWVmIENvbmNyZXRlIEJhc2ljVFRJSW1wbCB0aGF0IGNhbiBiZSB1c2VkIGlmIG5vIGZ1cnRoZXIgY3VzdG9taXphdGlvbgorLy8vIGlzIG5lZWRlZC4KK2NsYXNzIEJhc2ljVFRJSW1wbCA6IHB1YmxpYyBCYXNpY1RUSUltcGxCYXNlPEJhc2ljVFRJSW1wbD4geworICB1c2luZyBCYXNlVCA9IEJhc2ljVFRJSW1wbEJhc2U8QmFzaWNUVElJbXBsPjsKKworICBmcmllbmQgY2xhc3MgQmFzaWNUVElJbXBsQmFzZTxCYXNpY1RUSUltcGw+OworCisgIGNvbnN0IFRhcmdldFN1YnRhcmdldEluZm8gKlNUOworICBjb25zdCBUYXJnZXRMb3dlcmluZ0Jhc2UgKlRMSTsKKworICBjb25zdCBUYXJnZXRTdWJ0YXJnZXRJbmZvICpnZXRTVCgpIGNvbnN0IHsgcmV0dXJuIFNUOyB9CisgIGNvbnN0IFRhcmdldExvd2VyaW5nQmFzZSAqZ2V0VExJKCkgY29uc3QgeyByZXR1cm4gVExJOyB9CisKK3B1YmxpYzoKKyAgZXhwbGljaXQgQmFzaWNUVElJbXBsKGNvbnN0IFRhcmdldE1hY2hpbmUgKlNULCBjb25zdCBGdW5jdGlvbiAmRik7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0JBU0lDVFRJSU1QTF9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vQ2FsY1NwaWxsV2VpZ2h0cy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0NhbGNTcGlsbFdlaWdodHMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kOWU4MjA2Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0NhbGNTcGlsbFdlaWdodHMuaApAQCAtMCwwICsxLDEwOCBAQAorLy89PT0tIGxpYi9Db2RlR2VuL0NhbGNTcGlsbFdlaWdodHMuaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fQ0FMQ1NQSUxMV0VJR0hUU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9DQUxDU1BJTExXRUlHSFRTX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1Nsb3RJbmRleGVzLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgTGl2ZUludGVydmFsOworY2xhc3MgTGl2ZUludGVydmFsczsKK2NsYXNzIE1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm87CitjbGFzcyBNYWNoaW5lRnVuY3Rpb247CitjbGFzcyBNYWNoaW5lTG9vcEluZm87CitjbGFzcyBWaXJ0UmVnTWFwOworCisgIC8vLyBcYnJpZWYgTm9ybWFsaXplIHRoZSBzcGlsbCB3ZWlnaHQgb2YgYSBsaXZlIGludGVydmFsCisgIC8vLworICAvLy8gVGhlIHNwaWxsIHdlaWdodCBvZiBhIGxpdmUgaW50ZXJ2YWwgaXMgY29tcHV0ZWQgYXM6CisgIC8vLworICAvLy8gICAoc3VtKHVzZSBmcmVxKSArIHN1bShkZWYgZnJlcSkpIC8gKEsgKyBzaXplKQorICAvLy8KKyAgLy8vIEBwYXJhbSBVc2VEZWZGcmVxIEV4cGVjdGVkIG51bWJlciBvZiBleGVjdXRlZCB1c2UgYW5kIGRlZiBpbnN0cnVjdGlvbnMKKyAgLy8vICAgICAgICAgICAgICAgICAgIHBlciBmdW5jdGlvbiBjYWxsLiBEZXJpdmVkIGZyb20gYmxvY2sgZnJlcXVlbmNpZXMuCisgIC8vLyBAcGFyYW0gU2l6ZSAgICAgICBTaXplIG9mIGxpdmUgaW50ZXJ2YWwgYXMgcmV0dXJuZXhkIGJ5IGdldFNpemUoKQorICAvLy8gQHBhcmFtIE51bUluc3RyICAgTnVtYmVyIG9mIGluc3RydWN0aW9ucyB1c2luZyB0aGlzIGxpdmUgaW50ZXJ2YWwKKyAgc3RhdGljIGlubGluZSBmbG9hdCBub3JtYWxpemVTcGlsbFdlaWdodChmbG9hdCBVc2VEZWZGcmVxLCB1bnNpZ25lZCBTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIE51bUluc3RyKSB7CisgICAgLy8gVGhlIGNvbnN0YW50IDI1IGluc3RydWN0aW9ucyBpcyBhZGRlZCB0byBhdm9pZCBkZXBlbmRpbmcgdG9vIG11Y2ggb24KKyAgICAvLyBhY2NpZGVudGFsIFNsb3RJbmRleCBnYXBzIGZvciBzbWFsbCBpbnRlcnZhbHMuIFRoZSBlZmZlY3QgaXMgdGhhdCBzbWFsbAorICAgIC8vIGludGVydmFscyBoYXZlIGEgc3BpbGwgd2VpZ2h0IHRoYXQgaXMgbW9zdGx5IHByb3BvcnRpb25hbCB0byB0aGUgbnVtYmVyCisgICAgLy8gb2YgdXNlcywgd2hpbGUgbGFyZ2UgaW50ZXJ2YWxzIGdldCBhIHNwaWxsIHdlaWdodCB0aGF0IGlzIGNsb3NlciB0byBhIHVzZQorICAgIC8vIGRlbnNpdHkuCisgICAgcmV0dXJuIFVzZURlZkZyZXEgLyAoU2l6ZSArIDI1KlNsb3RJbmRleDo6SW5zdHJEaXN0KTsKKyAgfQorCisgIC8vLyBcYnJpZWYgQ2FsY3VsYXRlIGF1eGlsaWFyeSBpbmZvcm1hdGlvbiBmb3IgYSB2aXJ0dWFsIHJlZ2lzdGVyIHN1Y2ggYXMgaXRzCisgIC8vLyBzcGlsbCB3ZWlnaHQgYW5kIGFsbG9jYXRpb24gaGludC4KKyAgY2xhc3MgVmlydFJlZ0F1eEluZm8geworICBwdWJsaWM6CisgICAgdXNpbmcgTm9ybWFsaXppbmdGbiA9IGZsb2F0ICgqKShmbG9hdCwgdW5zaWduZWQsIHVuc2lnbmVkKTsKKworICBwcml2YXRlOgorICAgIE1hY2hpbmVGdW5jdGlvbiAmTUY7CisgICAgTGl2ZUludGVydmFscyAmTElTOworICAgIFZpcnRSZWdNYXAgKlZSTTsKKyAgICBjb25zdCBNYWNoaW5lTG9vcEluZm8gJkxvb3BzOworICAgIGNvbnN0IE1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm8gJk1CRkk7CisgICAgRGVuc2VNYXA8dW5zaWduZWQsIGZsb2F0PiBIaW50OworICAgIE5vcm1hbGl6aW5nRm4gbm9ybWFsaXplOworCisgIHB1YmxpYzoKKyAgICBWaXJ0UmVnQXV4SW5mbyhNYWNoaW5lRnVuY3Rpb24gJm1mLCBMaXZlSW50ZXJ2YWxzICZsaXMsCisgICAgICAgICAgICAgICAgICAgVmlydFJlZ01hcCAqdnJtLCBjb25zdCBNYWNoaW5lTG9vcEluZm8gJmxvb3BzLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm8gJm1iZmksCisgICAgICAgICAgICAgICAgICAgTm9ybWFsaXppbmdGbiBub3JtID0gbm9ybWFsaXplU3BpbGxXZWlnaHQpCisgICAgICAgIDogTUYobWYpLCBMSVMobGlzKSwgVlJNKHZybSksIExvb3BzKGxvb3BzKSwgTUJGSShtYmZpKSwgbm9ybWFsaXplKG5vcm0pIHt9CisKKyAgICAvLy8gXGJyaWVmIChyZSljb21wdXRlIGxpJ3Mgc3BpbGwgd2VpZ2h0IGFuZCBhbGxvY2F0aW9uIGhpbnQuCisgICAgdm9pZCBjYWxjdWxhdGVTcGlsbFdlaWdodEFuZEhpbnQoTGl2ZUludGVydmFsICZsaSk7CisKKyAgICAvLy8gXGJyaWVmIENvbXB1dGUgZnV0dXJlIGV4cGVjdGVkIHNwaWxsIHdlaWdodCBvZiBhIHNwbGl0IGFydGlmYWN0IG9mIGxpCisgICAgLy8vIHRoYXQgd2lsbCBzcGFuIGJldHdlZW4gc3RhcnQgYW5kIGVuZCBzbG90IGluZGV4ZXMuCisgICAgLy8vIFxwYXJhbSBsaSAgICAgVGhlIGxpdmUgaW50ZXJ2YWwgdG8gYmUgc3BsaXQuCisgICAgLy8vIFxwYXJhbSBzdGFydCAgVGhlIGV4cGVjdGVkIGJlZ2luaW5nIG9mIHRoZSBzcGxpdCBhcnRpZmFjdC4gSW5zdHJ1Y3Rpb25zCisgICAgLy8vICAgICAgICAgICAgICAgYmVmb3JlIHN0YXJ0IHdpbGwgbm90IGFmZmVjdCB0aGUgd2VpZ2h0LgorICAgIC8vLyBccGFyYW0gZW5kICAgIFRoZSBleHBlY3RlZCBlbmQgb2YgdGhlIHNwbGl0IGFydGlmYWN0LiBJbnN0cnVjdGlvbnMKKyAgICAvLy8gICAgICAgICAgICAgICBhZnRlciBlbmQgd2lsbCBub3QgYWZmZWN0IHRoZSB3ZWlnaHQuCisgICAgLy8vIFxyZXR1cm4gVGhlIGV4cGVjdGVkIHNwaWxsIHdlaWdodCBvZiB0aGUgc3BsaXQgYXJ0aWZhY3QuIFJldHVybnMKKyAgICAvLy8gbmVnYXRpdmUgd2VpZ2h0IGZvciB1bnNwaWxsYWJsZSBsaS4KKyAgICBmbG9hdCBmdXR1cmVXZWlnaHQoTGl2ZUludGVydmFsICZsaSwgU2xvdEluZGV4IHN0YXJ0LCBTbG90SW5kZXggZW5kKTsKKworICAgIC8vLyBcYnJpZWYgSGVscGVyIGZ1bmN0aW9uIGZvciB3ZWlnaHQgY2FsY3VsYXRpb25zLgorICAgIC8vLyAoUmUpY29tcHV0ZSBsaSdzIHNwaWxsIHdlaWdodCBhbmQgYWxsb2NhdGlvbiBoaW50LCBvciwgZm9yIG5vbiBudWxsCisgICAgLy8vIHN0YXJ0IGFuZCBlbmQgLSBjb21wdXRlIGZ1dHVyZSBleHBlY3RlZCBzcGlsbCB3ZWlnaHQgb2YgYSBzcGxpdAorICAgIC8vLyBhcnRpZmFjdCBvZiBsaSB0aGF0IHdpbGwgc3BhbiBiZXR3ZWVuIHN0YXJ0IGFuZCBlbmQgc2xvdCBpbmRleGVzLgorICAgIC8vLyBccGFyYW0gbGkgICAgIFRoZSBsaXZlIGludGVydmFsIGZvciB3aGljaCB0byBjb21wdXRlIHRoZSB3ZWlnaHQuCisgICAgLy8vIFxwYXJhbSBzdGFydCAgVGhlIGV4cGVjdGVkIGJlZ2luaW5nIG9mIHRoZSBzcGxpdCBhcnRpZmFjdC4gSW5zdHJ1Y3Rpb25zCisgICAgLy8vICAgICAgICAgICAgICAgYmVmb3JlIHN0YXJ0IHdpbGwgbm90IGFmZmVjdCB0aGUgd2VpZ2h0LiBSZWxldmFudCBmb3IKKyAgICAvLy8gICAgICAgICAgICAgICB3ZWlnaHQgY2FsY3VsYXRpb24gb2YgZnV0dXJlIHNwbGl0IGFydGlmYWN0LgorICAgIC8vLyBccGFyYW0gZW5kICAgIFRoZSBleHBlY3RlZCBlbmQgb2YgdGhlIHNwbGl0IGFydGlmYWN0LiBJbnN0cnVjdGlvbnMKKyAgICAvLy8gICAgICAgICAgICAgICBhZnRlciBlbmQgd2lsbCBub3QgYWZmZWN0IHRoZSB3ZWlnaHQuIFJlbGV2YW50IGZvcgorICAgIC8vLyAgICAgICAgICAgICAgIHdlaWdodCBjYWxjdWxhdGlvbiBvZiBmdXR1cmUgc3BsaXQgYXJ0aWZhY3QuCisgICAgLy8vIFxyZXR1cm4gVGhlIHNwaWxsIHdlaWdodC4gUmV0dXJucyBuZWdhdGl2ZSB3ZWlnaHQgZm9yIHVuc3BpbGxhYmxlIGxpLgorICAgIGZsb2F0IHdlaWdodENhbGNIZWxwZXIoTGl2ZUludGVydmFsICZsaSwgU2xvdEluZGV4ICpzdGFydCA9IG51bGxwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBTbG90SW5kZXggKmVuZCA9IG51bGxwdHIpOworICB9OworCisgIC8vLyBcYnJpZWYgQ29tcHV0ZSBzcGlsbCB3ZWlnaHRzIGFuZCBhbGxvY2F0aW9uIGhpbnRzIGZvciBhbGwgdmlydHVhbCByZWdpc3RlcgorICAvLy8gbGl2ZSBpbnRlcnZhbHMuCisgIHZvaWQgY2FsY3VsYXRlU3BpbGxXZWlnaHRzQW5kSGludHMoTGl2ZUludGVydmFscyAmTElTLCBNYWNoaW5lRnVuY3Rpb24gJk1GLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZpcnRSZWdNYXAgKlZSTSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lTG9vcEluZm8gJk1MSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lQmxvY2tGcmVxdWVuY3lJbmZvICZNQkZJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZpcnRSZWdBdXhJbmZvOjpOb3JtYWxpemluZ0ZuIG5vcm0gPQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVTcGlsbFdlaWdodCk7CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fQ0FMQ1NQSUxMV0VJR0hUU19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vQ2FsbGluZ0NvbnZMb3dlci5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0NhbGxpbmdDb252TG93ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMzBhMjczCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0NhbGxpbmdDb252TG93ZXIuaApAQCAtMCwwICsxLDU3NiBAQAorLy89PT0tIGxsdm0vQ2FsbGluZ0NvbnZMb3dlci5oIC0gQ2FsbGluZyBDb252ZW50aW9ucyAtLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgZGVjbGFyZXMgdGhlIENDU3RhdGUgYW5kIENDVmFsQXNzaWduIGNsYXNzZXMsIHVzZWQgZm9yIGxvd2VyaW5nCisvLyBhbmQgaW1wbGVtZW50aW5nIGNhbGxpbmcgY29udmVudGlvbnMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fQ0FMTElOR0NPTlZMT1dFUl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9DQUxMSU5HQ09OVkxPV0VSX0gKKworI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVGcmFtZUluZm8uaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1RhcmdldENhbGxpbmdDb252LmgiCisjaW5jbHVkZSAibGx2bS9JUi9DYWxsaW5nQ29udi5oIgorI2luY2x1ZGUgImxsdm0vTUMvTUNSZWdpc3RlckluZm8uaCIKKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBDQ1N0YXRlOworY2xhc3MgTVZUOworY2xhc3MgVGFyZ2V0TWFjaGluZTsKK2NsYXNzIFRhcmdldFJlZ2lzdGVySW5mbzsKKworLy8vIENDVmFsQXNzaWduIC0gUmVwcmVzZW50IGFzc2lnbm1lbnQgb2Ygb25lIGFyZy9yZXR2YWwgdG8gYSBsb2NhdGlvbi4KK2NsYXNzIENDVmFsQXNzaWduIHsKK3B1YmxpYzoKKyAgZW51bSBMb2NJbmZvIHsKKyAgICBGdWxsLCAgICAgIC8vIFRoZSB2YWx1ZSBmaWxscyB0aGUgZnVsbCBsb2NhdGlvbi4KKyAgICBTRXh0LCAgICAgIC8vIFRoZSB2YWx1ZSBpcyBzaWduIGV4dGVuZGVkIGluIHRoZSBsb2NhdGlvbi4KKyAgICBaRXh0LCAgICAgIC8vIFRoZSB2YWx1ZSBpcyB6ZXJvIGV4dGVuZGVkIGluIHRoZSBsb2NhdGlvbi4KKyAgICBBRXh0LCAgICAgIC8vIFRoZSB2YWx1ZSBpcyBleHRlbmRlZCB3aXRoIHVuZGVmaW5lZCB1cHBlciBiaXRzLgorICAgIFNFeHRVcHBlciwgLy8gVGhlIHZhbHVlIGlzIGluIHRoZSB1cHBlciBiaXRzIG9mIHRoZSBsb2NhdGlvbiBhbmQgc2hvdWxkIGJlCisgICAgICAgICAgICAgICAvLyBzaWduIGV4dGVuZGVkIHdoZW4gcmV0cmlldmVkLgorICAgIFpFeHRVcHBlciwgLy8gVGhlIHZhbHVlIGlzIGluIHRoZSB1cHBlciBiaXRzIG9mIHRoZSBsb2NhdGlvbiBhbmQgc2hvdWxkIGJlCisgICAgICAgICAgICAgICAvLyB6ZXJvIGV4dGVuZGVkIHdoZW4gcmV0cmlldmVkLgorICAgIEFFeHRVcHBlciwgLy8gVGhlIHZhbHVlIGlzIGluIHRoZSB1cHBlciBiaXRzIG9mIHRoZSBsb2NhdGlvbiBhbmQgc2hvdWxkIGJlCisgICAgICAgICAgICAgICAvLyBleHRlbmRlZCB3aXRoIHVuZGVmaW5lZCB1cHBlciBiaXRzIHdoZW4gcmV0cmlldmVkLgorICAgIEJDdnQsICAgICAgLy8gVGhlIHZhbHVlIGlzIGJpdC1jb252ZXJ0ZWQgaW4gdGhlIGxvY2F0aW9uLgorICAgIFZFeHQsICAgICAgLy8gVGhlIHZhbHVlIGlzIHZlY3Rvci13aWRlbmVkIGluIHRoZSBsb2NhdGlvbi4KKyAgICAgICAgICAgICAgIC8vIEZJWE1FOiBOb3QgaW1wbGVtZW50ZWQgeWV0LiBDb2RlIHRoYXQgdXNlcyBBRXh0IHRvIG1lYW4KKyAgICAgICAgICAgICAgIC8vIHZlY3Rvci13aWRlbiBzaG91bGQgYmUgZml4ZWQgdG8gdXNlIFZFeHQgaW5zdGVhZC4KKyAgICBGUEV4dCwgICAgIC8vIFRoZSBmbG9hdGluZy1wb2ludCB2YWx1ZSBpcyBmcC1leHRlbmRlZCBpbiB0aGUgbG9jYXRpb24uCisgICAgSW5kaXJlY3QgICAvLyBUaGUgbG9jYXRpb24gY29udGFpbnMgcG9pbnRlciB0byB0aGUgdmFsdWUuCisgICAgLy8gVE9ETzogYSBzdWJzZXQgb2YgdGhlIHZhbHVlIGlzIGluIHRoZSBsb2NhdGlvbi4KKyAgfTsKKworcHJpdmF0ZToKKyAgLy8vIFZhbE5vIC0gVGhpcyBpcyB0aGUgdmFsdWUgbnVtYmVyIGJlZ2luIGFzc2lnbmVkIChlLmcuIGFuIGFyZ3VtZW50IG51bWJlcikuCisgIHVuc2lnbmVkIFZhbE5vOworCisgIC8vLyBMb2MgaXMgZWl0aGVyIGEgc3RhY2sgb2Zmc2V0IG9yIGEgcmVnaXN0ZXIgbnVtYmVyLgorICB1bnNpZ25lZCBMb2M7CisKKyAgLy8vIGlzTWVtIC0gVHJ1ZSBpZiB0aGlzIGlzIGEgbWVtb3J5IGxvYywgZmFsc2UgaWYgaXQgaXMgYSByZWdpc3RlciBsb2MuCisgIHVuc2lnbmVkIGlzTWVtIDogMTsKKworICAvLy8gaXNDdXN0b20gLSBUcnVlIGlmIHRoaXMgYXJnL3JldHZhbCByZXF1aXJlcyBzcGVjaWFsIGhhbmRsaW5nLgorICB1bnNpZ25lZCBpc0N1c3RvbSA6IDE7CisKKyAgLy8vIEluZm9ybWF0aW9uIGFib3V0IGhvdyB0aGUgdmFsdWUgaXMgYXNzaWduZWQuCisgIExvY0luZm8gSFRQIDogNjsKKworICAvLy8gVmFsVlQgLSBUaGUgdHlwZSBvZiB0aGUgdmFsdWUgYmVpbmcgYXNzaWduZWQuCisgIE1WVCBWYWxWVDsKKworICAvLy8gTG9jVlQgLSBUaGUgdHlwZSBvZiB0aGUgbG9jYXRpb24gYmVpbmcgYXNzaWduZWQgdG8uCisgIE1WVCBMb2NWVDsKK3B1YmxpYzoKKworICBzdGF0aWMgQ0NWYWxBc3NpZ24gZ2V0UmVnKHVuc2lnbmVkIFZhbE5vLCBNVlQgVmFsVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgUmVnTm8sIE1WVCBMb2NWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NJbmZvIEhUUCkgeworICAgIENDVmFsQXNzaWduIFJldDsKKyAgICBSZXQuVmFsTm8gPSBWYWxObzsKKyAgICBSZXQuTG9jID0gUmVnTm87CisgICAgUmV0LmlzTWVtID0gZmFsc2U7CisgICAgUmV0LmlzQ3VzdG9tID0gZmFsc2U7CisgICAgUmV0LkhUUCA9IEhUUDsKKyAgICBSZXQuVmFsVlQgPSBWYWxWVDsKKyAgICBSZXQuTG9jVlQgPSBMb2NWVDsKKyAgICByZXR1cm4gUmV0OworICB9CisKKyAgc3RhdGljIENDVmFsQXNzaWduIGdldEN1c3RvbVJlZyh1bnNpZ25lZCBWYWxObywgTVZUIFZhbFZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFJlZ05vLCBNVlQgTG9jVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9jSW5mbyBIVFApIHsKKyAgICBDQ1ZhbEFzc2lnbiBSZXQ7CisgICAgUmV0ID0gZ2V0UmVnKFZhbE5vLCBWYWxWVCwgUmVnTm8sIExvY1ZULCBIVFApOworICAgIFJldC5pc0N1c3RvbSA9IHRydWU7CisgICAgcmV0dXJuIFJldDsKKyAgfQorCisgIHN0YXRpYyBDQ1ZhbEFzc2lnbiBnZXRNZW0odW5zaWduZWQgVmFsTm8sIE1WVCBWYWxWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBPZmZzZXQsIE1WVCBMb2NWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NJbmZvIEhUUCkgeworICAgIENDVmFsQXNzaWduIFJldDsKKyAgICBSZXQuVmFsTm8gPSBWYWxObzsKKyAgICBSZXQuTG9jID0gT2Zmc2V0OworICAgIFJldC5pc01lbSA9IHRydWU7CisgICAgUmV0LmlzQ3VzdG9tID0gZmFsc2U7CisgICAgUmV0LkhUUCA9IEhUUDsKKyAgICBSZXQuVmFsVlQgPSBWYWxWVDsKKyAgICBSZXQuTG9jVlQgPSBMb2NWVDsKKyAgICByZXR1cm4gUmV0OworICB9CisKKyAgc3RhdGljIENDVmFsQXNzaWduIGdldEN1c3RvbU1lbSh1bnNpZ25lZCBWYWxObywgTVZUIFZhbFZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIE9mZnNldCwgTVZUIExvY1ZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvY0luZm8gSFRQKSB7CisgICAgQ0NWYWxBc3NpZ24gUmV0OworICAgIFJldCA9IGdldE1lbShWYWxObywgVmFsVlQsIE9mZnNldCwgTG9jVlQsIEhUUCk7CisgICAgUmV0LmlzQ3VzdG9tID0gdHJ1ZTsKKyAgICByZXR1cm4gUmV0OworICB9CisKKyAgLy8gVGhlcmUgaXMgbm8gbmVlZCB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gYSBwZW5kaW5nIENDVmFsQXNzaWduIGFuZCBvdGhlcgorICAvLyBraW5kcywgYXMgdGhleSBhcmUgc3RvcmVkIGluIGEgZGlmZmVyZW50IGxpc3QuCisgIHN0YXRpYyBDQ1ZhbEFzc2lnbiBnZXRQZW5kaW5nKHVuc2lnbmVkIFZhbE5vLCBNVlQgVmFsVlQsIE1WVCBMb2NWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9jSW5mbyBIVFAsIHVuc2lnbmVkIEV4dHJhSW5mbyA9IDApIHsKKyAgICByZXR1cm4gZ2V0UmVnKFZhbE5vLCBWYWxWVCwgRXh0cmFJbmZvLCBMb2NWVCwgSFRQKTsKKyAgfQorCisgIHZvaWQgY29udmVydFRvUmVnKHVuc2lnbmVkIFJlZ05vKSB7CisgICAgTG9jID0gUmVnTm87CisgICAgaXNNZW0gPSBmYWxzZTsKKyAgfQorCisgIHZvaWQgY29udmVydFRvTWVtKHVuc2lnbmVkIE9mZnNldCkgeworICAgIExvYyA9IE9mZnNldDsKKyAgICBpc01lbSA9IHRydWU7CisgIH0KKworICB1bnNpZ25lZCBnZXRWYWxObygpIGNvbnN0IHsgcmV0dXJuIFZhbE5vOyB9CisgIE1WVCBnZXRWYWxWVCgpIGNvbnN0IHsgcmV0dXJuIFZhbFZUOyB9CisKKyAgYm9vbCBpc1JlZ0xvYygpIGNvbnN0IHsgcmV0dXJuICFpc01lbTsgfQorICBib29sIGlzTWVtTG9jKCkgY29uc3QgeyByZXR1cm4gaXNNZW07IH0KKworICBib29sIG5lZWRzQ3VzdG9tKCkgY29uc3QgeyByZXR1cm4gaXNDdXN0b207IH0KKworICB1bnNpZ25lZCBnZXRMb2NSZWcoKSBjb25zdCB7IGFzc2VydChpc1JlZ0xvYygpKTsgcmV0dXJuIExvYzsgfQorICB1bnNpZ25lZCBnZXRMb2NNZW1PZmZzZXQoKSBjb25zdCB7IGFzc2VydChpc01lbUxvYygpKTsgcmV0dXJuIExvYzsgfQorICB1bnNpZ25lZCBnZXRFeHRyYUluZm8oKSBjb25zdCB7IHJldHVybiBMb2M7IH0KKyAgTVZUIGdldExvY1ZUKCkgY29uc3QgeyByZXR1cm4gTG9jVlQ7IH0KKworICBMb2NJbmZvIGdldExvY0luZm8oKSBjb25zdCB7IHJldHVybiBIVFA7IH0KKyAgYm9vbCBpc0V4dEluTG9jKCkgY29uc3QgeworICAgIHJldHVybiAoSFRQID09IEFFeHQgfHwgSFRQID09IFNFeHQgfHwgSFRQID09IFpFeHQpOworICB9CisKKyAgYm9vbCBpc1VwcGVyQml0c0luTG9jKCkgY29uc3QgeworICAgIHJldHVybiBIVFAgPT0gQUV4dFVwcGVyIHx8IEhUUCA9PSBTRXh0VXBwZXIgfHwgSFRQID09IFpFeHRVcHBlcjsKKyAgfQorfTsKKworLy8vIERlc2NyaWJlcyBhIHJlZ2lzdGVyIHRoYXQgbmVlZHMgdG8gYmUgZm9yd2FyZGVkIGZyb20gdGhlIHByb2xvZ3VlIHRvIGEKKy8vLyBtdXN0dGFpbCBjYWxsLgorc3RydWN0IEZvcndhcmRlZFJlZ2lzdGVyIHsKKyAgRm9yd2FyZGVkUmVnaXN0ZXIodW5zaWduZWQgVlJlZywgTUNQaHlzUmVnIFBSZWcsIE1WVCBWVCkKKyAgICAgIDogVlJlZyhWUmVnKSwgUFJlZyhQUmVnKSwgVlQoVlQpIHt9CisgIHVuc2lnbmVkIFZSZWc7CisgIE1DUGh5c1JlZyBQUmVnOworICBNVlQgVlQ7Cit9OworCisvLy8gQ0NBc3NpZ25GbiAtIFRoaXMgZnVuY3Rpb24gYXNzaWducyBhIGxvY2F0aW9uIGZvciBWYWwsIHVwZGF0aW5nIFN0YXRlIHRvCisvLy8gcmVmbGVjdCB0aGUgY2hhbmdlLiAgSXQgcmV0dXJucyAndHJ1ZScgaWYgaXQgZmFpbGVkIHRvIGhhbmRsZSBWYWwuCit0eXBlZGVmIGJvb2wgQ0NBc3NpZ25Gbih1bnNpZ25lZCBWYWxObywgTVZUIFZhbFZULAorICAgICAgICAgICAgICAgICAgICAgICAgTVZUIExvY1ZULCBDQ1ZhbEFzc2lnbjo6TG9jSW5mbyBMb2NJbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgSVNEOjpBcmdGbGFnc1R5IEFyZ0ZsYWdzLCBDQ1N0YXRlICZTdGF0ZSk7CisKKy8vLyBDQ0N1c3RvbUZuIC0gVGhpcyBmdW5jdGlvbiBhc3NpZ25zIGEgbG9jYXRpb24gZm9yIFZhbCwgcG9zc2libHkgdXBkYXRpbmcKKy8vLyBhbGwgYXJncyB0byByZWZsZWN0IGNoYW5nZXMgYW5kIGluZGljYXRlcyBpZiBpdCBoYW5kbGVkIGl0LiBJdCBtdXN0IHNldAorLy8vIGlzQ3VzdG9tIGlmIGl0IGhhbmRsZXMgdGhlIGFyZyBhbmQgcmV0dXJucyB0cnVlLgordHlwZWRlZiBib29sIENDQ3VzdG9tRm4odW5zaWduZWQgJlZhbE5vLCBNVlQgJlZhbFZULAorICAgICAgICAgICAgICAgICAgICAgICAgTVZUICZMb2NWVCwgQ0NWYWxBc3NpZ246OkxvY0luZm8gJkxvY0luZm8sCisgICAgICAgICAgICAgICAgICAgICAgICBJU0Q6OkFyZ0ZsYWdzVHkgJkFyZ0ZsYWdzLCBDQ1N0YXRlICZTdGF0ZSk7CisKKy8vLyBDQ1N0YXRlIC0gVGhpcyBjbGFzcyBob2xkcyBpbmZvcm1hdGlvbiBuZWVkZWQgd2hpbGUgbG93ZXJpbmcgYXJndW1lbnRzIGFuZAorLy8vIHJldHVybiB2YWx1ZXMuICBJdCBjYXB0dXJlcyB3aGljaCByZWdpc3RlcnMgYXJlIGFscmVhZHkgYXNzaWduZWQgYW5kIHdoaWNoCisvLy8gc3RhY2sgc2xvdHMgYXJlIHVzZWQuICBJdCBwcm92aWRlcyBhY2Nlc3NvcnMgdG8gYWxsb2NhdGUgdGhlc2UgdmFsdWVzLgorY2xhc3MgQ0NTdGF0ZSB7Citwcml2YXRlOgorICBDYWxsaW5nQ29udjo6SUQgQ2FsbGluZ0NvbnY7CisgIGJvb2wgSXNWYXJBcmc7CisgIGJvb2wgQW5hbHl6aW5nTXVzdFRhaWxGb3J3YXJkZWRSZWdzID0gZmFsc2U7CisgIE1hY2hpbmVGdW5jdGlvbiAmTUY7CisgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAmVFJJOworICBTbWFsbFZlY3RvckltcGw8Q0NWYWxBc3NpZ24+ICZMb2NzOworICBMTFZNQ29udGV4dCAmQ29udGV4dDsKKworICB1bnNpZ25lZCBTdGFja09mZnNldDsKKyAgdW5zaWduZWQgTWF4U3RhY2tBcmdBbGlnbjsKKyAgU21hbGxWZWN0b3I8dWludDMyX3QsIDE2PiBVc2VkUmVnczsKKyAgU21hbGxWZWN0b3I8Q0NWYWxBc3NpZ24sIDQ+IFBlbmRpbmdMb2NzOworICBTbWFsbFZlY3RvcjxJU0Q6OkFyZ0ZsYWdzVHksIDQ+IFBlbmRpbmdBcmdGbGFnczsKKworICAvLyBCeVZhbEluZm8gYW5kIFNtYWxsVmVjdG9yPEJ5VmFsSW5mbywgND4gQnlWYWxSZWdzOgorICAvLworICAvLyBWZWN0b3Igb2YgQnlWYWxJbmZvIGluc3RhbmNlcyAoQnlWYWxSZWdzKSBpcyBpbnRyb2R1Y2VkIGZvciBieXZhbCByZWdpc3RlcnMKKyAgLy8gdHJhY2tpbmcuCisgIC8vIE9yLCBpbiBhbm90aGVyIHdvcmRzIGl0IHRyYWNrcyBieXZhbCBwYXJhbWV0ZXJzIHRoYXQgYXJlIHN0b3JlZCBpbgorICAvLyBnZW5lcmFsIHB1cnBvc2UgcmVnaXN0ZXJzLgorICAvLworICAvLyBGb3IgNCBieXRlIHN0YWNrIGFsaWdubWVudCwKKyAgLy8gaW5zdGFuY2UgaW5kZXggbWVhbnMgYnl2YWwgcGFyYW1ldGVyIG51bWJlciBpbiBmb3JtYWwKKyAgLy8gYXJndW1lbnRzIHNldC4gQXNzdW1lLCB3ZSBoYXZlIHNvbWUgInN0cnVjdF90eXBlIiB3aXRoIHNpemUgPSA0IGJ5dGVzLAorICAvLyB0aGVuLCBmb3IgZnVuY3Rpb24gImZvbyI6CisgIC8vCisgIC8vIGkzMiBmb28oaTMyICVwLCAlc3RydWN0X3R5cGUqICVyLCBpMzIgJXMsICVzdHJ1Y3RfdHlwZSogJXQpCisgIC8vCisgIC8vIEJ5VmFsUmVnc1swXSBkZXNjcmliZXMgaG93ICIlciIgaXMgc3RvcmVkIChCZWdpbiA9PSByMSwgRW5kID09IHIyKQorICAvLyBCeVZhbFJlZ3NbMV0gZGVzY3JpYmVzIGhvdyAiJXQiIGlzIHN0b3JlZCAoQmVnaW4gPT0gcjMsIEVuZCA9PSByNCkuCisgIC8vCisgIC8vIEluIGNhc2Ugb2YgOCBieXRlcyBzdGFjayBhbGlnbm1lbnQsCisgIC8vIEJ5VmFsUmVncyBtYXkgYWxzbyBjb250YWluIGluZm9ybWF0aW9uIGFib3V0IHdhc3RlZCByZWdpc3RlcnMuCisgIC8vIEluIGZ1bmN0aW9uIHNob3duIGFib3ZlLCByMyB3b3VsZCBiZSB3YXN0ZWQgYWNjb3JkaW5nIHRvIEFBUENTIHJ1bGVzLgorICAvLyBBbmQgaW4gdGhhdCBjYXNlIEJ5VmFsUmVnc1sxXS5XYXN0ZSB3b3VsZCBiZSAidHJ1ZSIuCisgIC8vIEJ5VmFsUmVncyB2ZWN0b3Igc2l6ZSBzdGlsbCB3b3VsZCBiZSAyLAorICAvLyB3aGlsZSAiJXQiIGdvZXMgdG8gdGhlIHN0YWNrOiBpdCB3b3VsZG4ndCBiZSBkZXNjcmliZWQgaW4gQnlWYWxSZWdzLgorICAvLworICAvLyBTdXBwb3NlZCB1c2UtY2FzZSBmb3IgdGhpcyBjb2xsZWN0aW9uOgorICAvLyAxLiBJbml0aWFsbHkgQnlWYWxSZWdzIGlzIGVtcHR5LCBJblJlZ3NQYXJhbXNQcm9jZXNzZWQgaXMgMC4KKyAgLy8gMi4gSGFuZGxlQnlWYWwgZmlsbHVwcyBCeVZhbFJlZ3MuCisgIC8vIDMuIEFyZ3VtZW50IGFuYWx5c2lzIChMb3dlckZvcm1hdEFyZ3VtZW50cywgZm9yIGV4YW1wbGUpLiBBZnRlcgorICAvLyBzb21lIGJ5dmFsIGFyZ3VtZW50IHdhcyBhbmFseXplZCwgSW5SZWdzUGFyYW1zUHJvY2Vzc2VkIGlzIGluY3JlYXNlZC4KKyAgc3RydWN0IEJ5VmFsSW5mbyB7CisgICAgQnlWYWxJbmZvKHVuc2lnbmVkIEIsIHVuc2lnbmVkIEUsIGJvb2wgSXNXYXN0ZSA9IGZhbHNlKSA6CisgICAgICBCZWdpbihCKSwgRW5kKEUpLCBXYXN0ZShJc1dhc3RlKSB7fQorICAgIC8vIEZpcnN0IHJlZ2lzdGVyIGFsbG9jYXRlZCBmb3IgY3VycmVudCBwYXJhbWV0ZXIuCisgICAgdW5zaWduZWQgQmVnaW47CisKKyAgICAvLyBGaXJzdCBhZnRlciBsYXN0IHJlZ2lzdGVyIGFsbG9jYXRlZCBmb3IgY3VycmVudCBwYXJhbWV0ZXIuCisgICAgdW5zaWduZWQgRW5kOworCisgICAgLy8gTWVhbnMgdGhhdCBjdXJyZW50IHJhbmdlIG9mIHJlZ2lzdGVycyBkb2Vzbid0IGJlbG9uZyB0byBhbnkKKyAgICAvLyBwYXJhbWV0ZXJzLiBJdCB3YXMgd2FzdGVkIGR1ZSB0byBzdGFjayBhbGlnbm1lbnQgcnVsZXMuCisgICAgLy8gRm9yIG1vcmUgaW5mb3JtYXRpb24gc2VlOgorICAgIC8vIEFBUENTLCA1LjUgUGFyYW1ldGVyIFBhc3NpbmcsIFN0YWdlIEMsIEMuMy4KKyAgICBib29sIFdhc3RlOworICB9OworICBTbWFsbFZlY3RvcjxCeVZhbEluZm8sIDQgPiBCeVZhbFJlZ3M7CisKKyAgLy8gSW5SZWdzUGFyYW1zUHJvY2Vzc2VkIC0gc2hvd3MgaG93IG1hbnkgaW5zdGFuY2VzIG9mIEJ5VmFsUmVncyB3YXMgcHJvY2VlZAorICAvLyBkdXJpbmcgYXJndW1lbnQgYW5hbHlzaXMuCisgIHVuc2lnbmVkIEluUmVnc1BhcmFtc1Byb2Nlc3NlZDsKKworcHVibGljOgorICBDQ1N0YXRlKENhbGxpbmdDb252OjpJRCBDQywgYm9vbCBpc1ZhckFyZywgTWFjaGluZUZ1bmN0aW9uICZNRiwKKyAgICAgICAgICBTbWFsbFZlY3RvckltcGw8Q0NWYWxBc3NpZ24+ICZsb2NzLCBMTFZNQ29udGV4dCAmQyk7CisKKyAgdm9pZCBhZGRMb2MoY29uc3QgQ0NWYWxBc3NpZ24gJlYpIHsKKyAgICBMb2NzLnB1c2hfYmFjayhWKTsKKyAgfQorCisgIExMVk1Db250ZXh0ICZnZXRDb250ZXh0KCkgY29uc3QgeyByZXR1cm4gQ29udGV4dDsgfQorICBNYWNoaW5lRnVuY3Rpb24gJmdldE1hY2hpbmVGdW5jdGlvbigpIGNvbnN0IHsgcmV0dXJuIE1GOyB9CisgIENhbGxpbmdDb252OjpJRCBnZXRDYWxsaW5nQ29udigpIGNvbnN0IHsgcmV0dXJuIENhbGxpbmdDb252OyB9CisgIGJvb2wgaXNWYXJBcmcoKSBjb25zdCB7IHJldHVybiBJc1ZhckFyZzsgfQorCisgIC8vLyBnZXROZXh0U3RhY2tPZmZzZXQgLSBSZXR1cm4gdGhlIG5leHQgc3RhY2sgb2Zmc2V0IHN1Y2ggdGhhdCBhbGwgc3RhY2sKKyAgLy8vIHNsb3RzIHNhdGlzZnkgdGhlaXIgYWxpZ25tZW50IHJlcXVpcmVtZW50cy4KKyAgdW5zaWduZWQgZ2V0TmV4dFN0YWNrT2Zmc2V0KCkgY29uc3QgeworICAgIHJldHVybiBTdGFja09mZnNldDsKKyAgfQorCisgIC8vLyBnZXRBbGlnbmVkQ2FsbEZyYW1lU2l6ZSAtIFJldHVybiB0aGUgc2l6ZSBvZiB0aGUgY2FsbCBmcmFtZSBuZWVkZWQgdG8KKyAgLy8vIGJlIGFibGUgdG8gc3RvcmUgYWxsIGFyZ3VtZW50cyBhbmQgc3VjaCB0aGF0IHRoZSBhbGlnbm1lbnQgcmVxdWlyZW1lbnQKKyAgLy8vIG9mIGVhY2ggb2YgdGhlIGFyZ3VtZW50cyBpcyBzYXRpc2ZpZWQuCisgIHVuc2lnbmVkIGdldEFsaWduZWRDYWxsRnJhbWVTaXplKCkgY29uc3QgeworICAgIHJldHVybiBhbGlnblRvKFN0YWNrT2Zmc2V0LCBNYXhTdGFja0FyZ0FsaWduKTsKKyAgfQorCisgIC8vLyBpc0FsbG9jYXRlZCAtIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIgKG9yIGFuIGFsaWFzKSBpcworICAvLy8gYWxsb2NhdGVkLgorICBib29sIGlzQWxsb2NhdGVkKHVuc2lnbmVkIFJlZykgY29uc3QgeworICAgIHJldHVybiBVc2VkUmVnc1tSZWcvMzJdICYgKDEgPDwgKFJlZyYzMSkpOworICB9CisKKyAgLy8vIEFuYWx5emVGb3JtYWxBcmd1bWVudHMgLSBBbmFseXplIGFuIGFycmF5IG9mIGFyZ3VtZW50IHZhbHVlcywKKyAgLy8vIGluY29ycG9yYXRpbmcgaW5mbyBhYm91dCB0aGUgZm9ybWFscyBpbnRvIHRoaXMgc3RhdGUuCisgIHZvaWQgQW5hbHl6ZUZvcm1hbEFyZ3VtZW50cyhjb25zdCBTbWFsbFZlY3RvckltcGw8SVNEOjpJbnB1dEFyZz4gJklucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENDQXNzaWduRm4gRm4pOworCisgIC8vLyBUaGUgZnVuY3Rpb24gd2lsbCBpbnZva2UgQW5hbHl6ZUZvcm1hbEFyZ3VtZW50cy4KKyAgdm9pZCBBbmFseXplQXJndW1lbnRzKGNvbnN0IFNtYWxsVmVjdG9ySW1wbDxJU0Q6OklucHV0QXJnPiAmSW5zLAorICAgICAgICAgICAgICAgICAgICAgICAgQ0NBc3NpZ25GbiBGbikgeworICAgIEFuYWx5emVGb3JtYWxBcmd1bWVudHMoSW5zLCBGbik7CisgIH0KKworICAvLy8gQW5hbHl6ZVJldHVybiAtIEFuYWx5emUgdGhlIHJldHVybmVkIHZhbHVlcyBvZiBhIHJldHVybiwKKyAgLy8vIGluY29ycG9yYXRpbmcgaW5mbyBhYm91dCB0aGUgcmVzdWx0IHZhbHVlcyBpbnRvIHRoaXMgc3RhdGUuCisgIHZvaWQgQW5hbHl6ZVJldHVybihjb25zdCBTbWFsbFZlY3RvckltcGw8SVNEOjpPdXRwdXRBcmc+ICZPdXRzLAorICAgICAgICAgICAgICAgICAgICAgQ0NBc3NpZ25GbiBGbik7CisKKyAgLy8vIENoZWNrUmV0dXJuIC0gQW5hbHl6ZSB0aGUgcmV0dXJuIHZhbHVlcyBvZiBhIGZ1bmN0aW9uLCByZXR1cm5pbmcKKyAgLy8vIHRydWUgaWYgdGhlIHJldHVybiBjYW4gYmUgcGVyZm9ybWVkIHdpdGhvdXQgc3JldC1kZW1vdGlvbiwgYW5kCisgIC8vLyBmYWxzZSBvdGhlcndpc2UuCisgIGJvb2wgQ2hlY2tSZXR1cm4oY29uc3QgU21hbGxWZWN0b3JJbXBsPElTRDo6T3V0cHV0QXJnPiAmQXJnc0ZsYWdzLAorICAgICAgICAgICAgICAgICAgIENDQXNzaWduRm4gRm4pOworCisgIC8vLyBBbmFseXplQ2FsbE9wZXJhbmRzIC0gQW5hbHl6ZSB0aGUgb3V0Z29pbmcgYXJndW1lbnRzIHRvIGEgY2FsbCwKKyAgLy8vIGluY29ycG9yYXRpbmcgaW5mbyBhYm91dCB0aGUgcGFzc2VkIHZhbHVlcyBpbnRvIHRoaXMgc3RhdGUuCisgIHZvaWQgQW5hbHl6ZUNhbGxPcGVyYW5kcyhjb25zdCBTbWFsbFZlY3RvckltcGw8SVNEOjpPdXRwdXRBcmc+ICZPdXRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0NBc3NpZ25GbiBGbik7CisKKyAgLy8vIEFuYWx5emVDYWxsT3BlcmFuZHMgLSBTYW1lIGFzIGFib3ZlIGV4Y2VwdCBpdCB0YWtlcyB2ZWN0b3JzIG9mIHR5cGVzCisgIC8vLyBhbmQgYXJndW1lbnQgZmxhZ3MuCisgIHZvaWQgQW5hbHl6ZUNhbGxPcGVyYW5kcyhTbWFsbFZlY3RvckltcGw8TVZUPiAmQXJnVlRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPElTRDo6QXJnRmxhZ3NUeT4gJkZsYWdzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0NBc3NpZ25GbiBGbik7CisKKyAgLy8vIFRoZSBmdW5jdGlvbiB3aWxsIGludm9rZSBBbmFseXplQ2FsbE9wZXJhbmRzLgorICB2b2lkIEFuYWx5emVBcmd1bWVudHMoY29uc3QgU21hbGxWZWN0b3JJbXBsPElTRDo6T3V0cHV0QXJnPiAmT3V0cywKKyAgICAgICAgICAgICAgICAgICAgICAgIENDQXNzaWduRm4gRm4pIHsKKyAgICBBbmFseXplQ2FsbE9wZXJhbmRzKE91dHMsIEZuKTsKKyAgfQorCisgIC8vLyBBbmFseXplQ2FsbFJlc3VsdCAtIEFuYWx5emUgdGhlIHJldHVybiB2YWx1ZXMgb2YgYSBjYWxsLAorICAvLy8gaW5jb3Jwb3JhdGluZyBpbmZvIGFib3V0IHRoZSBwYXNzZWQgdmFsdWVzIGludG8gdGhpcyBzdGF0ZS4KKyAgdm9pZCBBbmFseXplQ2FsbFJlc3VsdChjb25zdCBTbWFsbFZlY3RvckltcGw8SVNEOjpJbnB1dEFyZz4gJklucywKKyAgICAgICAgICAgICAgICAgICAgICAgICBDQ0Fzc2lnbkZuIEZuKTsKKworICAvLy8gQSBzaGFkb3cgYWxsb2NhdGVkIHJlZ2lzdGVyIGlzIGEgcmVnaXN0ZXIgdGhhdCB3YXMgYWxsb2NhdGVkCisgIC8vLyBidXQgd2Fzbid0IGFkZGVkIHRvIHRoZSBsb2NhdGlvbiBsaXN0IChMb2NzKS4KKyAgLy8vIFxyZXR1cm5zIHRydWUgaWYgdGhlIHJlZ2lzdGVyIHdhcyBhbGxvY2F0ZWQgYXMgc2hhZG93IG9yIGZhbHNlIG90aGVyd2lzZS4KKyAgYm9vbCBJc1NoYWRvd0FsbG9jYXRlZFJlZyh1bnNpZ25lZCBSZWcpIGNvbnN0OworCisgIC8vLyBBbmFseXplQ2FsbFJlc3VsdCAtIFNhbWUgYXMgYWJvdmUgZXhjZXB0IGl0J3Mgc3BlY2lhbGl6ZWQgZm9yIGNhbGxzIHdoaWNoCisgIC8vLyBwcm9kdWNlIGEgc2luZ2xlIHZhbHVlLgorICB2b2lkIEFuYWx5emVDYWxsUmVzdWx0KE1WVCBWVCwgQ0NBc3NpZ25GbiBGbik7CisKKyAgLy8vIGdldEZpcnN0VW5hbGxvY2F0ZWQgLSBSZXR1cm4gdGhlIGluZGV4IG9mIHRoZSBmaXJzdCB1bmFsbG9jYXRlZCByZWdpc3RlcgorICAvLy8gaW4gdGhlIHNldCwgb3IgUmVncy5zaXplKCkgaWYgdGhleSBhcmUgYWxsIGFsbG9jYXRlZC4KKyAgdW5zaWduZWQgZ2V0Rmlyc3RVbmFsbG9jYXRlZChBcnJheVJlZjxNQ1BoeXNSZWc+IFJlZ3MpIGNvbnN0IHsKKyAgICBmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgUmVncy5zaXplKCk7ICsraSkKKyAgICAgIGlmICghaXNBbGxvY2F0ZWQoUmVnc1tpXSkpCisgICAgICAgIHJldHVybiBpOworICAgIHJldHVybiBSZWdzLnNpemUoKTsKKyAgfQorCisgIC8vLyBBbGxvY2F0ZVJlZyAtIEF0dGVtcHQgdG8gYWxsb2NhdGUgb25lIHJlZ2lzdGVyLiAgSWYgaXQgaXMgbm90IGF2YWlsYWJsZSwKKyAgLy8vIHJldHVybiB6ZXJvLiAgT3RoZXJ3aXNlLCByZXR1cm4gdGhlIHJlZ2lzdGVyLCBtYXJraW5nIGl0IGFuZCBhbnkgYWxpYXNlcworICAvLy8gYXMgYWxsb2NhdGVkLgorICB1bnNpZ25lZCBBbGxvY2F0ZVJlZyh1bnNpZ25lZCBSZWcpIHsKKyAgICBpZiAoaXNBbGxvY2F0ZWQoUmVnKSkgcmV0dXJuIDA7CisgICAgTWFya0FsbG9jYXRlZChSZWcpOworICAgIHJldHVybiBSZWc7CisgIH0KKworICAvLy8gVmVyc2lvbiBvZiBBbGxvY2F0ZVJlZyB3aXRoIGV4dHJhIHJlZ2lzdGVyIHRvIGJlIHNoYWRvd2VkLgorICB1bnNpZ25lZCBBbGxvY2F0ZVJlZyh1bnNpZ25lZCBSZWcsIHVuc2lnbmVkIFNoYWRvd1JlZykgeworICAgIGlmIChpc0FsbG9jYXRlZChSZWcpKSByZXR1cm4gMDsKKyAgICBNYXJrQWxsb2NhdGVkKFJlZyk7CisgICAgTWFya0FsbG9jYXRlZChTaGFkb3dSZWcpOworICAgIHJldHVybiBSZWc7CisgIH0KKworICAvLy8gQWxsb2NhdGVSZWcgLSBBdHRlbXB0IHRvIGFsbG9jYXRlIG9uZSBvZiB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVycy4gIElmIG5vbmUKKyAgLy8vIGFyZSBhdmFpbGFibGUsIHJldHVybiB6ZXJvLiAgT3RoZXJ3aXNlLCByZXR1cm4gdGhlIGZpcnN0IG9uZSBhdmFpbGFibGUsCisgIC8vLyBtYXJraW5nIGl0IGFuZCBhbnkgYWxpYXNlcyBhcyBhbGxvY2F0ZWQuCisgIHVuc2lnbmVkIEFsbG9jYXRlUmVnKEFycmF5UmVmPE1DUGh5c1JlZz4gUmVncykgeworICAgIHVuc2lnbmVkIEZpcnN0VW5hbGxvYyA9IGdldEZpcnN0VW5hbGxvY2F0ZWQoUmVncyk7CisgICAgaWYgKEZpcnN0VW5hbGxvYyA9PSBSZWdzLnNpemUoKSkKKyAgICAgIHJldHVybiAwOyAgICAvLyBEaWRuJ3QgZmluZCB0aGUgcmVnLgorCisgICAgLy8gTWFyayB0aGUgcmVnaXN0ZXIgYW5kIGFueSBhbGlhc2VzIGFzIGFsbG9jYXRlZC4KKyAgICB1bnNpZ25lZCBSZWcgPSBSZWdzW0ZpcnN0VW5hbGxvY107CisgICAgTWFya0FsbG9jYXRlZChSZWcpOworICAgIHJldHVybiBSZWc7CisgIH0KKworICAvLy8gQWxsb2NhdGVSZWdCbG9jayAtIEF0dGVtcHQgdG8gYWxsb2NhdGUgYSBibG9jayBvZiBSZWdzUmVxdWlyZWQgY29uc2VjdXRpdmUKKyAgLy8vIHJlZ2lzdGVycy4gSWYgdGhpcyBpcyBub3QgcG9zc2libGUsIHJldHVybiB6ZXJvLiBPdGhlcndpc2UsIHJldHVybiB0aGUgZmlyc3QKKyAgLy8vIHJlZ2lzdGVyIG9mIHRoZSBibG9jayB0aGF0IHdlcmUgYWxsb2NhdGVkLCBtYXJraW5nIHRoZSBlbnRpcmUgYmxvY2sgYXMgYWxsb2NhdGVkLgorICB1bnNpZ25lZCBBbGxvY2F0ZVJlZ0Jsb2NrKEFycmF5UmVmPE1DUGh5c1JlZz4gUmVncywgdW5zaWduZWQgUmVnc1JlcXVpcmVkKSB7CisgICAgaWYgKFJlZ3NSZXF1aXJlZCA+IFJlZ3Muc2l6ZSgpKQorICAgICAgcmV0dXJuIDA7CisKKyAgICBmb3IgKHVuc2lnbmVkIFN0YXJ0SWR4ID0gMDsgU3RhcnRJZHggPD0gUmVncy5zaXplKCkgLSBSZWdzUmVxdWlyZWQ7CisgICAgICAgICArK1N0YXJ0SWR4KSB7CisgICAgICBib29sIEJsb2NrQXZhaWxhYmxlID0gdHJ1ZTsKKyAgICAgIC8vIENoZWNrIGZvciBhbHJlYWR5LWFsbG9jYXRlZCByZWdzIGluIHRoaXMgYmxvY2sKKyAgICAgIGZvciAodW5zaWduZWQgQmxvY2tJZHggPSAwOyBCbG9ja0lkeCA8IFJlZ3NSZXF1aXJlZDsgKytCbG9ja0lkeCkgeworICAgICAgICBpZiAoaXNBbGxvY2F0ZWQoUmVnc1tTdGFydElkeCArIEJsb2NrSWR4XSkpIHsKKyAgICAgICAgICBCbG9ja0F2YWlsYWJsZSA9IGZhbHNlOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgICBpZiAoQmxvY2tBdmFpbGFibGUpIHsKKyAgICAgICAgLy8gTWFyayB0aGUgZW50aXJlIGJsb2NrIGFzIGFsbG9jYXRlZAorICAgICAgICBmb3IgKHVuc2lnbmVkIEJsb2NrSWR4ID0gMDsgQmxvY2tJZHggPCBSZWdzUmVxdWlyZWQ7ICsrQmxvY2tJZHgpIHsKKyAgICAgICAgICBNYXJrQWxsb2NhdGVkKFJlZ3NbU3RhcnRJZHggKyBCbG9ja0lkeF0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiBSZWdzW1N0YXJ0SWR4XTsKKyAgICAgIH0KKyAgICB9CisgICAgLy8gTm8gYmxvY2sgd2FzIGF2YWlsYWJsZQorICAgIHJldHVybiAwOworICB9CisKKyAgLy8vIFZlcnNpb24gb2YgQWxsb2NhdGVSZWcgd2l0aCBsaXN0IG9mIHJlZ2lzdGVycyB0byBiZSBzaGFkb3dlZC4KKyAgdW5zaWduZWQgQWxsb2NhdGVSZWcoQXJyYXlSZWY8TUNQaHlzUmVnPiBSZWdzLCBjb25zdCBNQ1BoeXNSZWcgKlNoYWRvd1JlZ3MpIHsKKyAgICB1bnNpZ25lZCBGaXJzdFVuYWxsb2MgPSBnZXRGaXJzdFVuYWxsb2NhdGVkKFJlZ3MpOworICAgIGlmIChGaXJzdFVuYWxsb2MgPT0gUmVncy5zaXplKCkpCisgICAgICByZXR1cm4gMDsgICAgLy8gRGlkbid0IGZpbmQgdGhlIHJlZy4KKworICAgIC8vIE1hcmsgdGhlIHJlZ2lzdGVyIGFuZCBhbnkgYWxpYXNlcyBhcyBhbGxvY2F0ZWQuCisgICAgdW5zaWduZWQgUmVnID0gUmVnc1tGaXJzdFVuYWxsb2NdLCBTaGFkb3dSZWcgPSBTaGFkb3dSZWdzW0ZpcnN0VW5hbGxvY107CisgICAgTWFya0FsbG9jYXRlZChSZWcpOworICAgIE1hcmtBbGxvY2F0ZWQoU2hhZG93UmVnKTsKKyAgICByZXR1cm4gUmVnOworICB9CisKKyAgLy8vIEFsbG9jYXRlU3RhY2sgLSBBbGxvY2F0ZSBhIGNodW5rIG9mIHN0YWNrIHNwYWNlIHdpdGggdGhlIHNwZWNpZmllZCBzaXplCisgIC8vLyBhbmQgYWxpZ25tZW50LgorICB1bnNpZ25lZCBBbGxvY2F0ZVN0YWNrKHVuc2lnbmVkIFNpemUsIHVuc2lnbmVkIEFsaWduKSB7CisgICAgYXNzZXJ0KEFsaWduICYmICgoQWxpZ24gLSAxKSAmIEFsaWduKSA9PSAwKTsgLy8gQWxpZ24gaXMgcG93ZXIgb2YgMi4KKyAgICBTdGFja09mZnNldCA9IGFsaWduVG8oU3RhY2tPZmZzZXQsIEFsaWduKTsKKyAgICB1bnNpZ25lZCBSZXN1bHQgPSBTdGFja09mZnNldDsKKyAgICBTdGFja09mZnNldCArPSBTaXplOworICAgIE1heFN0YWNrQXJnQWxpZ24gPSBzdGQ6Om1heChBbGlnbiwgTWF4U3RhY2tBcmdBbGlnbik7CisgICAgZW5zdXJlTWF4QWxpZ25tZW50KEFsaWduKTsKKyAgICByZXR1cm4gUmVzdWx0OworICB9CisKKyAgdm9pZCBlbnN1cmVNYXhBbGlnbm1lbnQodW5zaWduZWQgQWxpZ24pIHsKKyAgICBpZiAoIUFuYWx5emluZ011c3RUYWlsRm9yd2FyZGVkUmVncykKKyAgICAgIE1GLmdldEZyYW1lSW5mbygpLmVuc3VyZU1heEFsaWdubWVudChBbGlnbik7CisgIH0KKworICAvLy8gVmVyc2lvbiBvZiBBbGxvY2F0ZVN0YWNrIHdpdGggZXh0cmEgcmVnaXN0ZXIgdG8gYmUgc2hhZG93ZWQuCisgIHVuc2lnbmVkIEFsbG9jYXRlU3RhY2sodW5zaWduZWQgU2l6ZSwgdW5zaWduZWQgQWxpZ24sIHVuc2lnbmVkIFNoYWRvd1JlZykgeworICAgIE1hcmtBbGxvY2F0ZWQoU2hhZG93UmVnKTsKKyAgICByZXR1cm4gQWxsb2NhdGVTdGFjayhTaXplLCBBbGlnbik7CisgIH0KKworICAvLy8gVmVyc2lvbiBvZiBBbGxvY2F0ZVN0YWNrIHdpdGggbGlzdCBvZiBleHRyYSByZWdpc3RlcnMgdG8gYmUgc2hhZG93ZWQuCisgIC8vLyBOb3RlIHRoYXQsIHVubGlrZSBBbGxvY2F0ZVJlZywgdGhpcyBzaGFkb3dzIEFMTCBvZiB0aGUgc2hhZG93IHJlZ2lzdGVycy4KKyAgdW5zaWduZWQgQWxsb2NhdGVTdGFjayh1bnNpZ25lZCBTaXplLCB1bnNpZ25lZCBBbGlnbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjxNQ1BoeXNSZWc+IFNoYWRvd1JlZ3MpIHsKKyAgICBmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgU2hhZG93UmVncy5zaXplKCk7ICsraSkKKyAgICAgIE1hcmtBbGxvY2F0ZWQoU2hhZG93UmVnc1tpXSk7CisgICAgcmV0dXJuIEFsbG9jYXRlU3RhY2soU2l6ZSwgQWxpZ24pOworICB9CisKKyAgLy8gSGFuZGxlQnlWYWwgLSBBbGxvY2F0ZSBhIHN0YWNrIHNsb3QgbGFyZ2UgZW5vdWdoIHRvIHBhc3MgYW4gYXJndW1lbnQgYnkKKyAgLy8gdmFsdWUuIFRoZSBzaXplIGFuZCBhbGlnbm1lbnQgaW5mb3JtYXRpb24gb2YgdGhlIGFyZ3VtZW50IGlzIGVuY29kZWQgaW4gaXRzCisgIC8vIHBhcmFtZXRlciBhdHRyaWJ1dGUuCisgIHZvaWQgSGFuZGxlQnlWYWwodW5zaWduZWQgVmFsTm8sIE1WVCBWYWxWVCwKKyAgICAgICAgICAgICAgICAgICBNVlQgTG9jVlQsIENDVmFsQXNzaWduOjpMb2NJbmZvIExvY0luZm8sCisgICAgICAgICAgICAgICAgICAgaW50IE1pblNpemUsIGludCBNaW5BbGlnbiwgSVNEOjpBcmdGbGFnc1R5IEFyZ0ZsYWdzKTsKKworICAvLyBSZXR1cm5zIGNvdW50IG9mIGJ5dmFsIGFyZ3VtZW50cyB0aGF0IGFyZSB0byBiZSBzdG9yZWQgKGV2ZW4gcGFydGx5KQorICAvLyBpbiByZWdpc3RlcnMuCisgIHVuc2lnbmVkIGdldEluUmVnc1BhcmFtc0NvdW50KCkgY29uc3QgeyByZXR1cm4gQnlWYWxSZWdzLnNpemUoKTsgfQorCisgIC8vIFJldHVybnMgY291bnQgb2YgYnl2YWwgaW4tcmVncyBhcmd1bWVudHMgcHJvY2VlZC4KKyAgdW5zaWduZWQgZ2V0SW5SZWdzUGFyYW1zUHJvY2Vzc2VkKCkgY29uc3QgeyByZXR1cm4gSW5SZWdzUGFyYW1zUHJvY2Vzc2VkOyB9CisKKyAgLy8gR2V0IGluZm9ybWF0aW9uIGFib3V0IE4tdGggYnl2YWwgcGFyYW1ldGVyIHRoYXQgaXMgc3RvcmVkIGluIHJlZ2lzdGVycy4KKyAgLy8gSGVyZSAiQnlWYWxQYXJhbUluZGV4IiBpcyBOLgorICB2b2lkIGdldEluUmVnc1BhcmFtSW5mbyh1bnNpZ25lZCBJblJlZ3NQYXJhbVJlY29yZEluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCYgQmVnaW5SZWcsIHVuc2lnbmVkJiBFbmRSZWcpIGNvbnN0IHsKKyAgICBhc3NlcnQoSW5SZWdzUGFyYW1SZWNvcmRJbmRleCA8IEJ5VmFsUmVncy5zaXplKCkgJiYKKyAgICAgICAgICAgIldyb25nIEJ5VmFsIHBhcmFtZXRlciBpbmRleCIpOworCisgICAgY29uc3QgQnlWYWxJbmZvJiBpbmZvID0gQnlWYWxSZWdzW0luUmVnc1BhcmFtUmVjb3JkSW5kZXhdOworICAgIEJlZ2luUmVnID0gaW5mby5CZWdpbjsKKyAgICBFbmRSZWcgPSBpbmZvLkVuZDsKKyAgfQorCisgIC8vIEFkZCBpbmZvcm1hdGlvbiBhYm91dCBwYXJhbWV0ZXIgdGhhdCBpcyBrZXB0IGluIHJlZ2lzdGVycy4KKyAgdm9pZCBhZGRJblJlZ3NQYXJhbUluZm8odW5zaWduZWQgUmVnQmVnaW4sIHVuc2lnbmVkIFJlZ0VuZCkgeworICAgIEJ5VmFsUmVncy5wdXNoX2JhY2soQnlWYWxJbmZvKFJlZ0JlZ2luLCBSZWdFbmQpKTsKKyAgfQorCisgIC8vIEdvZXMgZWl0aGVyIHRvIG5leHQgYnl2YWwgcGFyYW1ldGVyIChleGNsdWRpbmcgIndhc3RlIiByZWNvcmQpLCBvcgorICAvLyB0byB0aGUgZW5kIG9mIGNvbGxlY3Rpb24uCisgIC8vIFJldHVybnMgZmFsc2UsIGlmIGVuZCBpcyByZWFjaGVkLgorICBib29sIG5leHRJblJlZ3NQYXJhbSgpIHsKKyAgICB1bnNpZ25lZCBlID0gQnlWYWxSZWdzLnNpemUoKTsKKyAgICBpZiAoSW5SZWdzUGFyYW1zUHJvY2Vzc2VkIDwgZSkKKyAgICAgICsrSW5SZWdzUGFyYW1zUHJvY2Vzc2VkOworICAgIHJldHVybiBJblJlZ3NQYXJhbXNQcm9jZXNzZWQgPCBlOworICB9CisKKyAgLy8gQ2xlYXIgYnl2YWwgcmVnaXN0ZXJzIHRyYWNraW5nIGluZm8uCisgIHZvaWQgY2xlYXJCeVZhbFJlZ3NJbmZvKCkgeworICAgIEluUmVnc1BhcmFtc1Byb2Nlc3NlZCA9IDA7CisgICAgQnlWYWxSZWdzLmNsZWFyKCk7CisgIH0KKworICAvLyBSZXdpbmQgYnl2YWwgcmVnaXN0ZXJzIHRyYWNraW5nIGluZm8uCisgIHZvaWQgcmV3aW5kQnlWYWxSZWdzSW5mbygpIHsKKyAgICBJblJlZ3NQYXJhbXNQcm9jZXNzZWQgPSAwOworICB9CisKKyAgLy8gR2V0IGxpc3Qgb2YgcGVuZGluZyBhc3NpZ25tZW50cworICBTbWFsbFZlY3RvckltcGw8Q0NWYWxBc3NpZ24+ICZnZXRQZW5kaW5nTG9jcygpIHsKKyAgICByZXR1cm4gUGVuZGluZ0xvY3M7CisgIH0KKworICAvLyBHZXQgYSBsaXN0IG9mIGFyZ2ZsYWdzIGZvciBwZW5kaW5nIGFzc2lnbm1lbnRzLgorICBTbWFsbFZlY3RvckltcGw8SVNEOjpBcmdGbGFnc1R5PiAmZ2V0UGVuZGluZ0FyZ0ZsYWdzKCkgeworICAgIHJldHVybiBQZW5kaW5nQXJnRmxhZ3M7CisgIH0KKworICAvLy8gQ29tcHV0ZSB0aGUgcmVtYWluaW5nIHVudXNlZCByZWdpc3RlciBwYXJhbWV0ZXJzIHRoYXQgd291bGQgYmUgdXNlZCBmb3IKKyAgLy8vIHRoZSBnaXZlbiB2YWx1ZSB0eXBlLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHZhcmFyZ3MgYXJlIHBhc3NlZCBpbiB0aGUKKyAgLy8vIHJlZ2lzdGVycyB0aGF0IG5vcm1hbCBwcm90b3R5cGVkIHBhcmFtZXRlcnMgd291bGQgYmUgcGFzc2VkIGluLCBvciBmb3IKKyAgLy8vIGltcGxlbWVudGluZyBwZXJmZWN0IGZvcndhcmRpbmcuCisgIHZvaWQgZ2V0UmVtYWluaW5nUmVnUGFybXNGb3JUeXBlKFNtYWxsVmVjdG9ySW1wbDxNQ1BoeXNSZWc+ICZSZWdzLCBNVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENDQXNzaWduRm4gRm4pOworCisgIC8vLyBDb21wdXRlIHRoZSBzZXQgb2YgcmVnaXN0ZXJzIHRoYXQgbmVlZCB0byBiZSBwcmVzZXJ2ZWQgYW5kIGZvcndhcmRlZCB0bworICAvLy8gYW55IG11c3R0YWlsIGNhbGxzLgorICB2b2lkIGFuYWx5emVNdXN0VGFpbEZvcndhcmRlZFJlZ2lzdGVycygKKyAgICAgIFNtYWxsVmVjdG9ySW1wbDxGb3J3YXJkZWRSZWdpc3Rlcj4gJkZvcndhcmRzLCBBcnJheVJlZjxNVlQ+IFJlZ1Bhcm1UeXBlcywKKyAgICAgIENDQXNzaWduRm4gRm4pOworCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIHJlc3VsdHMgb2YgdGhlIHR3byBjYWxsaW5nIGNvbnZlbnRpb25zIGFyZSBjb21wYXRpYmxlLgorICAvLy8gVGhpcyBpcyB1c3VhbGx5IHBhcnQgb2YgdGhlIGNoZWNrIGZvciB0YWlsY2FsbCBlbGlnaWJpbGl0eS4KKyAgc3RhdGljIGJvb2wgcmVzdWx0c0NvbXBhdGlibGUoQ2FsbGluZ0NvbnY6OklEIENhbGxlZUNDLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDYWxsaW5nQ29udjo6SUQgQ2FsbGVyQ0MsIE1hY2hpbmVGdW5jdGlvbiAmTUYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExMVk1Db250ZXh0ICZDLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTbWFsbFZlY3RvckltcGw8SVNEOjpJbnB1dEFyZz4gJklucywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0NBc3NpZ25GbiBDYWxsZWVGbiwgQ0NBc3NpZ25GbiBDYWxsZXJGbik7CisKKyAgLy8vIFRoZSBmdW5jdGlvbiBydW5zIGFuIGFkZGl0aW9uYWwgYW5hbHlzaXMgcGFzcyBvdmVyIGZ1bmN0aW9uIGFyZ3VtZW50cy4KKyAgLy8vIEl0IHdpbGwgbWFyayBlYWNoIGFyZ3VtZW50IHdpdGggdGhlIGF0dHJpYnV0ZSBmbGFnIFNlY0FyZ1Bhc3MuCisgIC8vLyBBZnRlciBydW5uaW5nLCBpdCB3aWxsIHNvcnQgdGhlIGxvY3MgbGlzdC4KKyAgdGVtcGxhdGUgPGNsYXNzIFQ+CisgIHZvaWQgQW5hbHl6ZUFyZ3VtZW50c1NlY29uZFBhc3MoY29uc3QgU21hbGxWZWN0b3JJbXBsPFQ+ICZBcmdzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENDQXNzaWduRm4gRm4pIHsKKyAgICB1bnNpZ25lZCBOdW1GaXJzdFBhc3NMb2NzID0gTG9jcy5zaXplKCk7CisKKyAgICAvLy8gQ3JlYXRlcyBzaW1pbGFyIGFyZ3VtZW50IGxpc3QgdG8gXHAgQXJncyBpbiB3aGljaCBlYWNoIGFyZ3VtZW50IGlzCisgICAgLy8vIG1hcmtlZCB1c2luZyBTZWNBcmdQYXNzIGZsYWcuCisgICAgU21hbGxWZWN0b3I8VCwgMTY+IFNlY1Bhc3NBcmc7CisgICAgLy8gU21hbGxWZWN0b3I8SVNEOjpJbnB1dEFyZywgMTY+IFNlY1Bhc3NBcmc7CisgICAgZm9yIChhdXRvIEFyZyA6IEFyZ3MpIHsKKyAgICAgIEFyZy5GbGFncy5zZXRTZWNBcmdQYXNzKCk7CisgICAgICBTZWNQYXNzQXJnLnB1c2hfYmFjayhBcmcpOworICAgIH0KKworICAgIC8vIFJ1biB0aGUgc2Vjb25kIGFyZ3VtZW50IHBhc3MKKyAgICBBbmFseXplQXJndW1lbnRzKFNlY1Bhc3NBcmcsIEZuKTsKKworICAgIC8vIFNvcnQgdGhlIGxvY2F0aW9ucyBvZiB0aGUgYXJndW1lbnRzIGFjY29yZGluZyB0byB0aGVpciBvcmlnaW5hbCBwb3NpdGlvbi4KKyAgICBTbWFsbFZlY3RvcjxDQ1ZhbEFzc2lnbiwgMTY+IFRtcEFyZ0xvY3M7CisgICAgc3RkOjpzd2FwKFRtcEFyZ0xvY3MsIExvY3MpOworICAgIGF1dG8gQiA9IFRtcEFyZ0xvY3MuYmVnaW4oKSwgRSA9IFRtcEFyZ0xvY3MuZW5kKCk7CisgICAgc3RkOjptZXJnZShCLCBCICsgTnVtRmlyc3RQYXNzTG9jcywgQiArIE51bUZpcnN0UGFzc0xvY3MsIEUsCisgICAgICAgICAgICAgICBzdGQ6OmJhY2tfaW5zZXJ0ZXIoTG9jcyksCisgICAgICAgICAgICAgICBbXShjb25zdCBDQ1ZhbEFzc2lnbiAmQSwgY29uc3QgQ0NWYWxBc3NpZ24gJkIpIC0+IGJvb2wgeworICAgICAgICAgICAgICAgICByZXR1cm4gQS5nZXRWYWxObygpIDwgQi5nZXRWYWxObygpOworICAgICAgICAgICAgICAgfSk7CisgIH0KKworcHJpdmF0ZToKKyAgLy8vIE1hcmtBbGxvY2F0ZWQgLSBNYXJrIGEgcmVnaXN0ZXIgYW5kIGFsbCBvZiBpdHMgYWxpYXNlcyBhcyBhbGxvY2F0ZWQuCisgIHZvaWQgTWFya0FsbG9jYXRlZCh1bnNpZ25lZCBSZWcpOworfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9DQUxMSU5HQ09OVkxPV0VSX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9Db21tYW5kRmxhZ3MuZGVmIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0NvbW1hbmRGbGFncy5kZWYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzcwOGMwNAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9Db21tYW5kRmxhZ3MuZGVmCkBAIC0wLDAgKzEsMzg5IEBACisvLz09PS0tIENvbW1hbmRGbGFncy5oIC0gQ29tbWFuZCBMaW5lIEZsYWdzIEludGVyZmFjZSAtLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBjb250YWlucyBjb2RlZ2VuLXNwZWNpZmljIGZsYWdzIHRoYXQgYXJlIHNoYXJlZCBiZXR3ZWVuIGRpZmZlcmVudAorLy8gY29tbWFuZCBsaW5lIHRvb2xzLiBUaGUgdG9vbHMgImxsYyIgYW5kICJvcHQiIGJvdGggdXNlIHRoaXMgZmlsZSB0byBwcmV2ZW50CisvLyBmbGFnIGR1cGxpY2F0aW9uLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpbmNsdWRlICJsbHZtL0FEVC9TdHJpbmdFeHRyYXMuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0luc3RydWN0aW9ucy5oIgorI2luY2x1ZGUgImxsdm0vSVIvSW50cmluc2ljcy5oIgorI2luY2x1ZGUgImxsdm0vSVIvTW9kdWxlLmgiCisjaW5jbHVkZSAibGx2bS9NQy9NQ1RhcmdldE9wdGlvbnNDb21tYW5kRmxhZ3MuZGVmIgorI2luY2x1ZGUgImxsdm0vTUMvU3VidGFyZ2V0RmVhdHVyZS5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9Db2RlR2VuLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0NvbW1hbmRMaW5lLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0hvc3QuaCIKKyNpbmNsdWRlICJsbHZtL1RhcmdldC9UYXJnZXRNYWNoaW5lLmgiCisjaW5jbHVkZSAibGx2bS9UYXJnZXQvVGFyZ2V0T3B0aW9ucy5oIgorI2luY2x1ZGUgPHN0cmluZz4KK3VzaW5nIG5hbWVzcGFjZSBsbHZtOworCitzdGF0aWMgY2w6Om9wdDxzdGQ6OnN0cmluZz4KKyAgICBNQXJjaCgibWFyY2giLAorICAgICAgICAgIGNsOjpkZXNjKCJBcmNoaXRlY3R1cmUgdG8gZ2VuZXJhdGUgY29kZSBmb3IgKHNlZSAtLXZlcnNpb24pIikpOworCitzdGF0aWMgY2w6Om9wdDxzdGQ6OnN0cmluZz4KKyAgICBNQ1BVKCJtY3B1IiwKKyAgICAgICAgIGNsOjpkZXNjKCJUYXJnZXQgYSBzcGVjaWZpYyBjcHUgdHlwZSAoLW1jcHU9aGVscCBmb3IgZGV0YWlscykiKSwKKyAgICAgICAgIGNsOjp2YWx1ZV9kZXNjKCJjcHUtbmFtZSIpLCBjbDo6aW5pdCgiIikpOworCitzdGF0aWMgY2w6Omxpc3Q8c3RkOjpzdHJpbmc+CisgICAgTUF0dHJzKCJtYXR0ciIsIGNsOjpDb21tYVNlcGFyYXRlZCwKKyAgICAgICAgICAgY2w6OmRlc2MoIlRhcmdldCBzcGVjaWZpYyBhdHRyaWJ1dGVzICgtbWF0dHI9aGVscCBmb3IgZGV0YWlscykiKSwKKyAgICAgICAgICAgY2w6OnZhbHVlX2Rlc2MoImExLCthMiwtYTMsLi4uIikpOworCitzdGF0aWMgY2w6Om9wdDxSZWxvYzo6TW9kZWw+IFJlbG9jTW9kZWwoCisgICAgInJlbG9jYXRpb24tbW9kZWwiLCBjbDo6ZGVzYygiQ2hvb3NlIHJlbG9jYXRpb24gbW9kZWwiKSwKKyAgICBjbDo6dmFsdWVzKAorICAgICAgICBjbEVudW1WYWxOKFJlbG9jOjpTdGF0aWMsICJzdGF0aWMiLCAiTm9uLXJlbG9jYXRhYmxlIGNvZGUiKSwKKyAgICAgICAgY2xFbnVtVmFsTihSZWxvYzo6UElDXywgInBpYyIsCisgICAgICAgICAgICAgICAgICAgIkZ1bGx5IHJlbG9jYXRhYmxlLCBwb3NpdGlvbiBpbmRlcGVuZGVudCBjb2RlIiksCisgICAgICAgIGNsRW51bVZhbE4oUmVsb2M6OkR5bmFtaWNOb1BJQywgImR5bmFtaWMtbm8tcGljIiwKKyAgICAgICAgICAgICAgICAgICAiUmVsb2NhdGFibGUgZXh0ZXJuYWwgcmVmZXJlbmNlcywgbm9uLXJlbG9jYXRhYmxlIGNvZGUiKSwKKyAgICAgICAgY2xFbnVtVmFsTihSZWxvYzo6Uk9QSSwgInJvcGkiLAorICAgICAgICAgICAgICAgICAgICJDb2RlIGFuZCByZWFkLW9ubHkgZGF0YSByZWxvY2F0YWJsZSwgYWNjZXNzZWQgUEMtcmVsYXRpdmUiKSwKKyAgICAgICAgY2xFbnVtVmFsTigKKyAgICAgICAgICAgIFJlbG9jOjpSV1BJLCAicndwaSIsCisgICAgICAgICAgICAiUmVhZC13cml0ZSBkYXRhIHJlbG9jYXRhYmxlLCBhY2Nlc3NlZCByZWxhdGl2ZSB0byBzdGF0aWMgYmFzZSIpLAorICAgICAgICBjbEVudW1WYWxOKFJlbG9jOjpST1BJX1JXUEksICJyb3BpLXJ3cGkiLAorICAgICAgICAgICAgICAgICAgICJDb21iaW5hdGlvbiBvZiByb3BpIGFuZCByd3BpIikpKTsKKworTExWTV9BVFRSSUJVVEVfVU5VU0VEIHN0YXRpYyBPcHRpb25hbDxSZWxvYzo6TW9kZWw+IGdldFJlbG9jTW9kZWwoKSB7CisgIGlmIChSZWxvY01vZGVsLmdldE51bU9jY3VycmVuY2VzKCkpIHsKKyAgICBSZWxvYzo6TW9kZWwgUiA9IFJlbG9jTW9kZWw7CisgICAgcmV0dXJuIFI7CisgIH0KKyAgcmV0dXJuIE5vbmU7Cit9CisKK3N0YXRpYyBjbDo6b3B0PFRocmVhZE1vZGVsOjpNb2RlbD4gVE1Nb2RlbCgKKyAgICAidGhyZWFkLW1vZGVsIiwgY2w6OmRlc2MoIkNob29zZSB0aHJlYWRpbmcgbW9kZWwiKSwKKyAgICBjbDo6aW5pdChUaHJlYWRNb2RlbDo6UE9TSVgpLAorICAgIGNsOjp2YWx1ZXMoY2xFbnVtVmFsTihUaHJlYWRNb2RlbDo6UE9TSVgsICJwb3NpeCIsICJQT1NJWCB0aHJlYWQgbW9kZWwiKSwKKyAgICAgICAgICAgICAgIGNsRW51bVZhbE4oVGhyZWFkTW9kZWw6OlNpbmdsZSwgInNpbmdsZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICJTaW5nbGUgdGhyZWFkIG1vZGVsIikpKTsKKworc3RhdGljIGNsOjpvcHQ8bGx2bTo6Q29kZU1vZGVsOjpNb2RlbD4gQ01Nb2RlbCgKKyAgICAiY29kZS1tb2RlbCIsIGNsOjpkZXNjKCJDaG9vc2UgY29kZSBtb2RlbCIpLAorICAgIGNsOjp2YWx1ZXMoY2xFbnVtVmFsTihDb2RlTW9kZWw6OlNtYWxsLCAic21hbGwiLCAiU21hbGwgY29kZSBtb2RlbCIpLAorICAgICAgICAgICAgICAgY2xFbnVtVmFsTihDb2RlTW9kZWw6Oktlcm5lbCwgImtlcm5lbCIsICJLZXJuZWwgY29kZSBtb2RlbCIpLAorICAgICAgICAgICAgICAgY2xFbnVtVmFsTihDb2RlTW9kZWw6Ok1lZGl1bSwgIm1lZGl1bSIsICJNZWRpdW0gY29kZSBtb2RlbCIpLAorICAgICAgICAgICAgICAgY2xFbnVtVmFsTihDb2RlTW9kZWw6OkxhcmdlLCAibGFyZ2UiLCAiTGFyZ2UgY29kZSBtb2RlbCIpKSk7CisKK0xMVk1fQVRUUklCVVRFX1VOVVNFRCBzdGF0aWMgT3B0aW9uYWw8Q29kZU1vZGVsOjpNb2RlbD4gZ2V0Q29kZU1vZGVsKCkgeworICBpZiAoQ01Nb2RlbC5nZXROdW1PY2N1cnJlbmNlcygpKSB7CisgICAgQ29kZU1vZGVsOjpNb2RlbCBNID0gQ01Nb2RlbDsKKyAgICByZXR1cm4gTTsKKyAgfQorICByZXR1cm4gTm9uZTsKK30KKworc3RhdGljIGNsOjpvcHQ8bGx2bTo6RXhjZXB0aW9uSGFuZGxpbmc+IEV4Y2VwdGlvbk1vZGVsKAorICAgICJleGNlcHRpb24tbW9kZWwiLCBjbDo6ZGVzYygiZXhjZXB0aW9uIG1vZGVsIiksCisgICAgY2w6OmluaXQoRXhjZXB0aW9uSGFuZGxpbmc6Ok5vbmUpLAorICAgIGNsOjp2YWx1ZXMoCisgICAgICAgIGNsRW51bVZhbE4oRXhjZXB0aW9uSGFuZGxpbmc6Ok5vbmUsICJkZWZhdWx0IiwKKyAgICAgICAgICAgICAgICAgICAiZGVmYXVsdCBleGNlcHRpb24gaGFuZGxpbmcgbW9kZWwiKSwKKyAgICAgICAgY2xFbnVtVmFsTihFeGNlcHRpb25IYW5kbGluZzo6RHdhcmZDRkksICJkd2FyZiIsCisgICAgICAgICAgICAgICAgICAgIkRXQVJGLWxpa2UgQ0ZJIGJhc2VkIGV4Y2VwdGlvbiBoYW5kbGluZyIpLAorICAgICAgICBjbEVudW1WYWxOKEV4Y2VwdGlvbkhhbmRsaW5nOjpTakxqLCAic2psaiIsICJTakxqIGV4Y2VwdGlvbiBoYW5kbGluZyIpLAorICAgICAgICBjbEVudW1WYWxOKEV4Y2VwdGlvbkhhbmRsaW5nOjpBUk0sICJhcm0iLCAiQVJNIEVIQUJJIGV4Y2VwdGlvbnMiKSwKKyAgICAgICAgY2xFbnVtVmFsTihFeGNlcHRpb25IYW5kbGluZzo6V2luRUgsICJ3aW5laCIsCisgICAgICAgICAgICAgICAgICAgIldpbmRvd3MgZXhjZXB0aW9uIG1vZGVsIiksCisgICAgICAgIGNsRW51bVZhbE4oRXhjZXB0aW9uSGFuZGxpbmc6Oldhc20sICJ3YXNtIiwKKyAgICAgICAgICAgICAgICAgICAiV2ViQXNzZW1ibHkgZXhjZXB0aW9uIGhhbmRsaW5nIikpKTsKKworc3RhdGljIGNsOjpvcHQ8VGFyZ2V0TWFjaGluZTo6Q29kZUdlbkZpbGVUeXBlPiBGaWxlVHlwZSgKKyAgICAiZmlsZXR5cGUiLCBjbDo6aW5pdChUYXJnZXRNYWNoaW5lOjpDR0ZUX0Fzc2VtYmx5RmlsZSksCisgICAgY2w6OmRlc2MoCisgICAgICAgICJDaG9vc2UgYSBmaWxlIHR5cGUgKG5vdCBhbGwgdHlwZXMgYXJlIHN1cHBvcnRlZCBieSBhbGwgdGFyZ2V0cyk6IiksCisgICAgY2w6OnZhbHVlcyhjbEVudW1WYWxOKFRhcmdldE1hY2hpbmU6OkNHRlRfQXNzZW1ibHlGaWxlLCAiYXNtIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIkVtaXQgYW4gYXNzZW1ibHkgKCcucycpIGZpbGUiKSwKKyAgICAgICAgICAgICAgIGNsRW51bVZhbE4oVGFyZ2V0TWFjaGluZTo6Q0dGVF9PYmplY3RGaWxlLCAib2JqIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIkVtaXQgYSBuYXRpdmUgb2JqZWN0ICgnLm8nKSBmaWxlIiksCisgICAgICAgICAgICAgICBjbEVudW1WYWxOKFRhcmdldE1hY2hpbmU6OkNHRlRfTnVsbCwgIm51bGwiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiRW1pdCBub3RoaW5nLCBmb3IgcGVyZm9ybWFuY2UgdGVzdGluZyIpKSk7CisKK3N0YXRpYyBjbDo6b3B0PGJvb2w+CisgICAgRGlzYWJsZUZQRWxpbSgiZGlzYWJsZS1mcC1lbGltIiwKKyAgICAgICAgICAgICAgICAgIGNsOjpkZXNjKCJEaXNhYmxlIGZyYW1lIHBvaW50ZXIgZWxpbWluYXRpb24gb3B0aW1pemF0aW9uIiksCisgICAgICAgICAgICAgICAgICBjbDo6aW5pdChmYWxzZSkpOworCitzdGF0aWMgY2w6Om9wdDxib29sPiBFbmFibGVVbnNhZmVGUE1hdGgoCisgICAgImVuYWJsZS11bnNhZmUtZnAtbWF0aCIsCisgICAgY2w6OmRlc2MoIkVuYWJsZSBvcHRpbWl6YXRpb25zIHRoYXQgbWF5IGRlY3JlYXNlIEZQIHByZWNpc2lvbiIpLAorICAgIGNsOjppbml0KGZhbHNlKSk7CisKK3N0YXRpYyBjbDo6b3B0PGJvb2w+IEVuYWJsZU5vSW5mc0ZQTWF0aCgKKyAgICAiZW5hYmxlLW5vLWluZnMtZnAtbWF0aCIsCisgICAgY2w6OmRlc2MoIkVuYWJsZSBGUCBtYXRoIG9wdGltaXphdGlvbnMgdGhhdCBhc3N1bWUgbm8gKy1JbmZzIiksCisgICAgY2w6OmluaXQoZmFsc2UpKTsKKworc3RhdGljIGNsOjpvcHQ8Ym9vbD4gRW5hYmxlTm9OYU5zRlBNYXRoKAorICAgICJlbmFibGUtbm8tbmFucy1mcC1tYXRoIiwKKyAgICBjbDo6ZGVzYygiRW5hYmxlIEZQIG1hdGggb3B0aW1pemF0aW9ucyB0aGF0IGFzc3VtZSBubyBOYU5zIiksCisgICAgY2w6OmluaXQoZmFsc2UpKTsKKworc3RhdGljIGNsOjpvcHQ8Ym9vbD4gRW5hYmxlTm9TaWduZWRaZXJvc0ZQTWF0aCgKKyAgICAiZW5hYmxlLW5vLXNpZ25lZC16ZXJvcy1mcC1tYXRoIiwKKyAgICBjbDo6ZGVzYygiRW5hYmxlIEZQIG1hdGggb3B0aW1pemF0aW9ucyB0aGF0IGFzc3VtZSAiCisgICAgICAgICAgICAgInRoZSBzaWduIG9mIDAgaXMgaW5zaWduaWZpY2FudCIpLAorICAgIGNsOjppbml0KGZhbHNlKSk7CisKK3N0YXRpYyBjbDo6b3B0PGJvb2w+CisgICAgRW5hYmxlTm9UcmFwcGluZ0ZQTWF0aCgiZW5hYmxlLW5vLXRyYXBwaW5nLWZwLW1hdGgiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY2w6OmRlc2MoIkVuYWJsZSBzZXR0aW5nIHRoZSBGUCBleGNlcHRpb25zIGJ1aWxkICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhdHRyaWJ1dGUgbm90IHRvIHVzZSBleGNlcHRpb25zIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjbDo6aW5pdChmYWxzZSkpOworCitzdGF0aWMgY2w6Om9wdDxsbHZtOjpGUERlbm9ybWFsOjpEZW5vcm1hbE1vZGU+IERlbm9ybWFsTW9kZSgKKyAgICAiZGVub3JtYWwtZnAtbWF0aCIsCisgICAgY2w6OmRlc2MoIlNlbGVjdCB3aGljaCBkZW5vcm1hbCBudW1iZXJzIHRoZSBjb2RlIGlzIHBlcm1pdHRlZCB0byByZXF1aXJlIiksCisgICAgY2w6OmluaXQoRlBEZW5vcm1hbDo6SUVFRSksCisgICAgY2w6OnZhbHVlcyhjbEVudW1WYWxOKEZQRGVub3JtYWw6OklFRUUsICJpZWVlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIklFRUUgNzU0IGRlbm9ybWFsIG51bWJlcnMiKSwKKyAgICAgICAgICAgICAgIGNsRW51bVZhbE4oRlBEZW5vcm1hbDo6UHJlc2VydmVTaWduLCAicHJlc2VydmUtc2lnbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICJ0aGUgc2lnbiBvZiBhICBmbHVzaGVkLXRvLXplcm8gbnVtYmVyIGlzIHByZXNlcnZlZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICJpbiB0aGUgc2lnbiBvZiAwIiksCisgICAgICAgICAgICAgICBjbEVudW1WYWxOKEZQRGVub3JtYWw6OlBvc2l0aXZlWmVybywgInBvc2l0aXZlLXplcm8iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVub3JtYWxzIGFyZSBmbHVzaGVkIHRvIHBvc2l0aXZlIHplcm8iKSkpOworCitzdGF0aWMgY2w6Om9wdDxib29sPiBFbmFibGVIb25vclNpZ25EZXBlbmRlbnRSb3VuZGluZ0ZQTWF0aCgKKyAgICAiZW5hYmxlLXNpZ24tZGVwZW5kZW50LXJvdW5kaW5nLWZwLW1hdGgiLCBjbDo6SGlkZGVuLAorICAgIGNsOjpkZXNjKCJGb3JjZSBjb2RlZ2VuIHRvIGFzc3VtZSByb3VuZGluZyBtb2RlIGNhbiBjaGFuZ2UgZHluYW1pY2FsbHkiKSwKKyAgICBjbDo6aW5pdChmYWxzZSkpOworCitzdGF0aWMgY2w6Om9wdDxsbHZtOjpGbG9hdEFCSTo6QUJJVHlwZT4gRmxvYXRBQklGb3JDYWxscygKKyAgICAiZmxvYXQtYWJpIiwgY2w6OmRlc2MoIkNob29zZSBmbG9hdCBBQkkgdHlwZSIpLCBjbDo6aW5pdChGbG9hdEFCSTo6RGVmYXVsdCksCisgICAgY2w6OnZhbHVlcyhjbEVudW1WYWxOKEZsb2F0QUJJOjpEZWZhdWx0LCAiZGVmYXVsdCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICJUYXJnZXQgZGVmYXVsdCBmbG9hdCBBQkkgdHlwZSIpLAorICAgICAgICAgICAgICAgY2xFbnVtVmFsTihGbG9hdEFCSTo6U29mdCwgInNvZnQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiU29mdCBmbG9hdCBBQkkgKGltcGxpZWQgYnkgLXNvZnQtZmxvYXQpIiksCisgICAgICAgICAgICAgICBjbEVudW1WYWxOKEZsb2F0QUJJOjpIYXJkLCAiaGFyZCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICJIYXJkIGZsb2F0IEFCSSAodXNlcyBGUCByZWdpc3RlcnMpIikpKTsKKworc3RhdGljIGNsOjpvcHQ8bGx2bTo6RlBPcEZ1c2lvbjo6RlBPcEZ1c2lvbk1vZGU+IEZ1c2VGUE9wcygKKyAgICAiZnAtY29udHJhY3QiLCBjbDo6ZGVzYygiRW5hYmxlIGFnZ3Jlc3NpdmUgZm9ybWF0aW9uIG9mIGZ1c2VkIEZQIG9wcyIpLAorICAgIGNsOjppbml0KEZQT3BGdXNpb246OlN0YW5kYXJkKSwKKyAgICBjbDo6dmFsdWVzKAorICAgICAgICBjbEVudW1WYWxOKEZQT3BGdXNpb246OkZhc3QsICJmYXN0IiwgIkZ1c2UgRlAgb3BzIHdoZW5ldmVyIHByb2ZpdGFibGUiKSwKKyAgICAgICAgY2xFbnVtVmFsTihGUE9wRnVzaW9uOjpTdGFuZGFyZCwgIm9uIiwgIk9ubHkgZnVzZSAnYmxlc3NlZCcgRlAgb3BzLiIpLAorICAgICAgICBjbEVudW1WYWxOKEZQT3BGdXNpb246OlN0cmljdCwgIm9mZiIsCisgICAgICAgICAgICAgICAgICAgIk9ubHkgZnVzZSBGUCBvcHMgd2hlbiB0aGUgcmVzdWx0IHdvbid0IGJlIGFmZmVjdGVkLiIpKSk7CisKK3N0YXRpYyBjbDo6b3B0PGJvb2w+IERvbnRQbGFjZVplcm9zSW5CU1MoCisgICAgIm5vemVyby1pbml0aWFsaXplZC1pbi1ic3MiLAorICAgIGNsOjpkZXNjKCJEb24ndCBwbGFjZSB6ZXJvLWluaXRpYWxpemVkIHN5bWJvbHMgaW50byBic3Mgc2VjdGlvbiIpLAorICAgIGNsOjppbml0KGZhbHNlKSk7CisKK3N0YXRpYyBjbDo6b3B0PGJvb2w+IEVuYWJsZUd1YXJhbnRlZWRUYWlsQ2FsbE9wdCgKKyAgICAidGFpbGNhbGxvcHQiLAorICAgIGNsOjpkZXNjKAorICAgICAgICAiVHVybiBmYXN0Y2MgY2FsbHMgaW50byB0YWlsIGNhbGxzIGJ5IChwb3RlbnRpYWxseSkgY2hhbmdpbmcgQUJJLiIpLAorICAgIGNsOjppbml0KGZhbHNlKSk7CisKK3N0YXRpYyBjbDo6b3B0PGJvb2w+IERpc2FibGVUYWlsQ2FsbHMoImRpc2FibGUtdGFpbC1jYWxscyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsOjpkZXNjKCJOZXZlciBlbWl0IHRhaWwgY2FsbHMiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2w6OmluaXQoZmFsc2UpKTsKKworc3RhdGljIGNsOjpvcHQ8Ym9vbD4gU3RhY2tTeW1ib2xPcmRlcmluZygic3RhY2stc3ltYm9sLW9yZGVyaW5nIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2w6OmRlc2MoIk9yZGVyIGxvY2FsIHN0YWNrIHN5bWJvbHMuIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsOjppbml0KHRydWUpKTsKKworc3RhdGljIGNsOjpvcHQ8dW5zaWduZWQ+CisgICAgT3ZlcnJpZGVTdGFja0FsaWdubWVudCgic3RhY2stYWxpZ25tZW50IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsOjpkZXNjKCJPdmVycmlkZSBkZWZhdWx0IHN0YWNrIGFsaWdubWVudCIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY2w6OmluaXQoMCkpOworCitzdGF0aWMgY2w6Om9wdDxib29sPgorICAgIFN0YWNrUmVhbGlnbigic3RhY2tyZWFsaWduIiwKKyAgICAgICAgICAgICAgICAgY2w6OmRlc2MoIkZvcmNlIGFsaWduIHRoZSBzdGFjayB0byB0aGUgbWluaW11bSBhbGlnbm1lbnQiKSwKKyAgICAgICAgICAgICAgICAgY2w6OmluaXQoZmFsc2UpKTsKKworc3RhdGljIGNsOjpvcHQ8c3RkOjpzdHJpbmc+IFRyYXBGdW5jTmFtZSgKKyAgICAidHJhcC1mdW5jIiwgY2w6OkhpZGRlbiwKKyAgICBjbDo6ZGVzYygiRW1pdCBhIGNhbGwgdG8gdHJhcCBmdW5jdGlvbiByYXRoZXIgdGhhbiBhIHRyYXAgaW5zdHJ1Y3Rpb24iKSwKKyAgICBjbDo6aW5pdCgiIikpOworCitzdGF0aWMgY2w6Om9wdDxib29sPiBVc2VDdG9ycygidXNlLWN0b3JzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsOjpkZXNjKCJVc2UgLmN0b3JzIGluc3RlYWQgb2YgLmluaXRfYXJyYXkuIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbDo6aW5pdChmYWxzZSkpOworCitzdGF0aWMgY2w6Om9wdDxib29sPiBSZWxheEVMRlJlbG9jYXRpb25zKAorICAgICJyZWxheC1lbGYtcmVsb2NhdGlvbnMiLAorICAgIGNsOjpkZXNjKCJFbWl0IEdPVFBDUkVMWC9SRVhfR09UUENSRUxYIGluc3RlYWQgb2YgR09UUENSRUwgb24geDg2LTY0IEVMRiIpLAorICAgIGNsOjppbml0KGZhbHNlKSk7CisKK3N0YXRpYyBjbDo6b3B0PGJvb2w+IERhdGFTZWN0aW9ucygiZGF0YS1zZWN0aW9ucyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2w6OmRlc2MoIkVtaXQgZGF0YSBpbnRvIHNlcGFyYXRlIHNlY3Rpb25zIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2w6OmluaXQoZmFsc2UpKTsKKworc3RhdGljIGNsOjpvcHQ8Ym9vbD4KKyAgICBGdW5jdGlvblNlY3Rpb25zKCJmdW5jdGlvbi1zZWN0aW9ucyIsCisgICAgICAgICAgICAgICAgICAgICBjbDo6ZGVzYygiRW1pdCBmdW5jdGlvbnMgaW50byBzZXBhcmF0ZSBzZWN0aW9ucyIpLAorICAgICAgICAgICAgICAgICAgICAgY2w6OmluaXQoZmFsc2UpKTsKKworc3RhdGljIGNsOjpvcHQ8Ym9vbD4gRW11bGF0ZWRUTFMoImVtdWxhdGVkLXRscyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbDo6ZGVzYygiVXNlIGVtdWxhdGVkIFRMUyBtb2RlbCIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2w6OmluaXQoZmFsc2UpKTsKKworc3RhdGljIGNsOjpvcHQ8Ym9vbD4KKyAgICBVbmlxdWVTZWN0aW9uTmFtZXMoInVuaXF1ZS1zZWN0aW9uLW5hbWVzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgY2w6OmRlc2MoIkdpdmUgdW5pcXVlIG5hbWVzIHRvIGV2ZXJ5IHNlY3Rpb24iKSwKKyAgICAgICAgICAgICAgICAgICAgICAgY2w6OmluaXQodHJ1ZSkpOworCitzdGF0aWMgY2w6Om9wdDxsbHZtOjpFQUJJPgorICAgIEVBQklWZXJzaW9uKCJtZWFiaSIsIGNsOjpkZXNjKCJTZXQgRUFCSSB0eXBlIChkZWZhdWx0IGRlcGVuZHMgb24gdHJpcGxlKToiKSwKKyAgICAgICAgICAgICAgICBjbDo6aW5pdChFQUJJOjpEZWZhdWx0KSwKKyAgICAgICAgICAgICAgICBjbDo6dmFsdWVzKGNsRW51bVZhbE4oRUFCSTo6RGVmYXVsdCwgImRlZmF1bHQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVHJpcGxlIGRlZmF1bHQgRUFCSSB2ZXJzaW9uIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjbEVudW1WYWxOKEVBQkk6OkVBQkk0LCAiNCIsICJFQUJJIHZlcnNpb24gNCIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xFbnVtVmFsTihFQUJJOjpFQUJJNSwgIjUiLCAiRUFCSSB2ZXJzaW9uIDUiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsRW51bVZhbE4oRUFCSTo6R05VLCAiZ251IiwgIkVBQkkgR05VIikpKTsKKworc3RhdGljIGNsOjpvcHQ8RGVidWdnZXJLaW5kPiBEZWJ1Z2dlclR1bmluZ09wdCgKKyAgICAiZGVidWdnZXItdHVuZSIsIGNsOjpkZXNjKCJUdW5lIGRlYnVnIGluZm8gZm9yIGEgcGFydGljdWxhciBkZWJ1Z2dlciIpLAorICAgIGNsOjppbml0KERlYnVnZ2VyS2luZDo6RGVmYXVsdCksCisgICAgY2w6OnZhbHVlcyhjbEVudW1WYWxOKERlYnVnZ2VyS2luZDo6R0RCLCAiZ2RiIiwgImdkYiIpLAorICAgICAgICAgICAgICAgY2xFbnVtVmFsTihEZWJ1Z2dlcktpbmQ6OkxMREIsICJsbGRiIiwgImxsZGIiKSwKKyAgICAgICAgICAgICAgIGNsRW51bVZhbE4oRGVidWdnZXJLaW5kOjpTQ0UsICJzY2UiLCAiU0NFIHRhcmdldHMgKGUuZy4gUFM0KSIpKSk7CisKK3N0YXRpYyBjbDo6b3B0PGJvb2w+IEVuYWJsZVN0YWNrU2l6ZVNlY3Rpb24oCisgICAgInN0YWNrLXNpemUtc2VjdGlvbiIsCisgICAgY2w6OmRlc2MoIkVtaXQgYSBzZWN0aW9uIGNvbnRhaW5pbmcgc3RhY2sgc2l6ZSBtZXRhZGF0YSIpLCBjbDo6aW5pdChmYWxzZSkpOworCisvLyBDb21tb24gdXRpbGl0eSBmdW5jdGlvbiB0aWdodGx5IHRpZWQgdG8gdGhlIG9wdGlvbnMgbGlzdGVkIGhlcmUuIEluaXRpYWxpemVzCisvLyBhIFRhcmdldE9wdGlvbnMgb2JqZWN0IHdpdGggQ29kZUdlbiBmbGFncyBhbmQgcmV0dXJucyBpdC4KK3N0YXRpYyBUYXJnZXRPcHRpb25zIEluaXRUYXJnZXRPcHRpb25zRnJvbUNvZGVHZW5GbGFncygpIHsKKyAgVGFyZ2V0T3B0aW9ucyBPcHRpb25zOworICBPcHRpb25zLkFsbG93RlBPcEZ1c2lvbiA9IEZ1c2VGUE9wczsKKyAgT3B0aW9ucy5VbnNhZmVGUE1hdGggPSBFbmFibGVVbnNhZmVGUE1hdGg7CisgIE9wdGlvbnMuTm9JbmZzRlBNYXRoID0gRW5hYmxlTm9JbmZzRlBNYXRoOworICBPcHRpb25zLk5vTmFOc0ZQTWF0aCA9IEVuYWJsZU5vTmFOc0ZQTWF0aDsKKyAgT3B0aW9ucy5Ob1NpZ25lZFplcm9zRlBNYXRoID0gRW5hYmxlTm9TaWduZWRaZXJvc0ZQTWF0aDsKKyAgT3B0aW9ucy5Ob1RyYXBwaW5nRlBNYXRoID0gRW5hYmxlTm9UcmFwcGluZ0ZQTWF0aDsKKyAgT3B0aW9ucy5GUERlbm9ybWFsTW9kZSA9IERlbm9ybWFsTW9kZTsKKyAgT3B0aW9ucy5Ib25vclNpZ25EZXBlbmRlbnRSb3VuZGluZ0ZQTWF0aE9wdGlvbiA9CisgICAgICBFbmFibGVIb25vclNpZ25EZXBlbmRlbnRSb3VuZGluZ0ZQTWF0aDsKKyAgaWYgKEZsb2F0QUJJRm9yQ2FsbHMgIT0gRmxvYXRBQkk6OkRlZmF1bHQpCisgICAgT3B0aW9ucy5GbG9hdEFCSVR5cGUgPSBGbG9hdEFCSUZvckNhbGxzOworICBPcHRpb25zLk5vWmVyb3NJbkJTUyA9IERvbnRQbGFjZVplcm9zSW5CU1M7CisgIE9wdGlvbnMuR3VhcmFudGVlZFRhaWxDYWxsT3B0ID0gRW5hYmxlR3VhcmFudGVlZFRhaWxDYWxsT3B0OworICBPcHRpb25zLlN0YWNrQWxpZ25tZW50T3ZlcnJpZGUgPSBPdmVycmlkZVN0YWNrQWxpZ25tZW50OworICBPcHRpb25zLlN0YWNrU3ltYm9sT3JkZXJpbmcgPSBTdGFja1N5bWJvbE9yZGVyaW5nOworICBPcHRpb25zLlVzZUluaXRBcnJheSA9ICFVc2VDdG9yczsKKyAgT3B0aW9ucy5SZWxheEVMRlJlbG9jYXRpb25zID0gUmVsYXhFTEZSZWxvY2F0aW9uczsKKyAgT3B0aW9ucy5EYXRhU2VjdGlvbnMgPSBEYXRhU2VjdGlvbnM7CisgIE9wdGlvbnMuRnVuY3Rpb25TZWN0aW9ucyA9IEZ1bmN0aW9uU2VjdGlvbnM7CisgIE9wdGlvbnMuVW5pcXVlU2VjdGlvbk5hbWVzID0gVW5pcXVlU2VjdGlvbk5hbWVzOworICBPcHRpb25zLkVtdWxhdGVkVExTID0gRW11bGF0ZWRUTFM7CisgIE9wdGlvbnMuRXhwbGljaXRFbXVsYXRlZFRMUyA9IEVtdWxhdGVkVExTLmdldE51bU9jY3VycmVuY2VzKCkgPiAwOworICBPcHRpb25zLkV4Y2VwdGlvbk1vZGVsID0gRXhjZXB0aW9uTW9kZWw7CisgIE9wdGlvbnMuRW1pdFN0YWNrU2l6ZVNlY3Rpb24gPSBFbmFibGVTdGFja1NpemVTZWN0aW9uOworCisgIE9wdGlvbnMuTUNPcHRpb25zID0gSW5pdE1DVGFyZ2V0T3B0aW9uc0Zyb21GbGFncygpOworCisgIE9wdGlvbnMuVGhyZWFkTW9kZWwgPSBUTU1vZGVsOworICBPcHRpb25zLkVBQklWZXJzaW9uID0gRUFCSVZlcnNpb247CisgIE9wdGlvbnMuRGVidWdnZXJUdW5pbmcgPSBEZWJ1Z2dlclR1bmluZ09wdDsKKworICByZXR1cm4gT3B0aW9uczsKK30KKworTExWTV9BVFRSSUJVVEVfVU5VU0VEIHN0YXRpYyBzdGQ6OnN0cmluZyBnZXRDUFVTdHIoKSB7CisgIC8vIElmIHVzZXIgYXNrZWQgZm9yIHRoZSAnbmF0aXZlJyBDUFUsIGF1dG9kZXRlY3QgaGVyZS4gSWYgYXV0b2RlY3Rpb24gZmFpbHMsCisgIC8vIHRoaXMgd2lsbCBzZXQgdGhlIENQVSB0byBhbiBlbXB0eSBzdHJpbmcgd2hpY2ggdGVsbHMgdGhlIHRhcmdldCB0bworICAvLyBwaWNrIGEgYmFzaWMgZGVmYXVsdC4KKyAgaWYgKE1DUFUgPT0gIm5hdGl2ZSIpCisgICAgcmV0dXJuIHN5czo6Z2V0SG9zdENQVU5hbWUoKTsKKworICByZXR1cm4gTUNQVTsKK30KKworTExWTV9BVFRSSUJVVEVfVU5VU0VEIHN0YXRpYyBzdGQ6OnN0cmluZyBnZXRGZWF0dXJlc1N0cigpIHsKKyAgU3VidGFyZ2V0RmVhdHVyZXMgRmVhdHVyZXM7CisKKyAgLy8gSWYgdXNlciBhc2tlZCBmb3IgdGhlICduYXRpdmUnIENQVSwgd2UgbmVlZCB0byBhdXRvZGV0ZWN0IGZlYXR1cmVzLgorICAvLyBUaGlzIGlzIG5lY2Vzc2FyeSBmb3IgeDg2IHdoZXJlIHRoZSBDUFUgbWlnaHQgbm90IHN1cHBvcnQgYWxsIHRoZQorICAvLyBmZWF0dXJlcyB0aGUgYXV0b2RldGVjdGVkIENQVSBuYW1lIGxpc3RzIGluIHRoZSB0YXJnZXQuIEZvciBleGFtcGxlLAorICAvLyBub3QgYWxsIFNhbmR5YnJpZGdlIHByb2Nlc3NvcnMgc3VwcG9ydCBBVlguCisgIGlmIChNQ1BVID09ICJuYXRpdmUiKSB7CisgICAgU3RyaW5nTWFwPGJvb2w+IEhvc3RGZWF0dXJlczsKKyAgICBpZiAoc3lzOjpnZXRIb3N0Q1BVRmVhdHVyZXMoSG9zdEZlYXR1cmVzKSkKKyAgICAgIGZvciAoYXV0byAmRiA6IEhvc3RGZWF0dXJlcykKKyAgICAgICAgRmVhdHVyZXMuQWRkRmVhdHVyZShGLmZpcnN0KCksIEYuc2Vjb25kKTsKKyAgfQorCisgIGZvciAodW5zaWduZWQgaSA9IDA7IGkgIT0gTUF0dHJzLnNpemUoKTsgKytpKQorICAgIEZlYXR1cmVzLkFkZEZlYXR1cmUoTUF0dHJzW2ldKTsKKworICByZXR1cm4gRmVhdHVyZXMuZ2V0U3RyaW5nKCk7Cit9CisKK0xMVk1fQVRUUklCVVRFX1VOVVNFRCBzdGF0aWMgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IGdldEZlYXR1cmVMaXN0KCkgeworICBTdWJ0YXJnZXRGZWF0dXJlcyBGZWF0dXJlczsKKworICAvLyBJZiB1c2VyIGFza2VkIGZvciB0aGUgJ25hdGl2ZScgQ1BVLCB3ZSBuZWVkIHRvIGF1dG9kZXRlY3QgZmVhdHVyZXMuCisgIC8vIFRoaXMgaXMgbmVjZXNzYXJ5IGZvciB4ODYgd2hlcmUgdGhlIENQVSBtaWdodCBub3Qgc3VwcG9ydCBhbGwgdGhlCisgIC8vIGZlYXR1cmVzIHRoZSBhdXRvZGV0ZWN0ZWQgQ1BVIG5hbWUgbGlzdHMgaW4gdGhlIHRhcmdldC4gRm9yIGV4YW1wbGUsCisgIC8vIG5vdCBhbGwgU2FuZHlicmlkZ2UgcHJvY2Vzc29ycyBzdXBwb3J0IEFWWC4KKyAgaWYgKE1DUFUgPT0gIm5hdGl2ZSIpIHsKKyAgICBTdHJpbmdNYXA8Ym9vbD4gSG9zdEZlYXR1cmVzOworICAgIGlmIChzeXM6OmdldEhvc3RDUFVGZWF0dXJlcyhIb3N0RmVhdHVyZXMpKQorICAgICAgZm9yIChhdXRvICZGIDogSG9zdEZlYXR1cmVzKQorICAgICAgICBGZWF0dXJlcy5BZGRGZWF0dXJlKEYuZmlyc3QoKSwgRi5zZWNvbmQpOworICB9CisKKyAgZm9yICh1bnNpZ25lZCBpID0gMDsgaSAhPSBNQXR0cnMuc2l6ZSgpOyArK2kpCisgICAgRmVhdHVyZXMuQWRkRmVhdHVyZShNQXR0cnNbaV0pOworCisgIHJldHVybiBGZWF0dXJlcy5nZXRGZWF0dXJlcygpOworfQorCisvLy8gXGJyaWVmIFNldCBmdW5jdGlvbiBhdHRyaWJ1dGVzIG9mIGZ1bmN0aW9ucyBpbiBNb2R1bGUgTSBiYXNlZCBvbiBDUFUsCisvLy8gRmVhdHVyZXMsIGFuZCBjb21tYW5kIGxpbmUgZmxhZ3MuCitMTFZNX0FUVFJJQlVURV9VTlVTRUQgc3RhdGljIHZvaWQKK3NldEZ1bmN0aW9uQXR0cmlidXRlcyhTdHJpbmdSZWYgQ1BVLCBTdHJpbmdSZWYgRmVhdHVyZXMsIE1vZHVsZSAmTSkgeworICBmb3IgKGF1dG8gJkYgOiBNKSB7CisgICAgYXV0byAmQ3R4ID0gRi5nZXRDb250ZXh0KCk7CisgICAgQXR0cmlidXRlTGlzdCBBdHRycyA9IEYuZ2V0QXR0cmlidXRlcygpOworICAgIEF0dHJCdWlsZGVyIE5ld0F0dHJzOworCisgICAgaWYgKCFDUFUuZW1wdHkoKSkKKyAgICAgIE5ld0F0dHJzLmFkZEF0dHJpYnV0ZSgidGFyZ2V0LWNwdSIsIENQVSk7CisgICAgaWYgKCFGZWF0dXJlcy5lbXB0eSgpKQorICAgICAgTmV3QXR0cnMuYWRkQXR0cmlidXRlKCJ0YXJnZXQtZmVhdHVyZXMiLCBGZWF0dXJlcyk7CisgICAgaWYgKERpc2FibGVGUEVsaW0uZ2V0TnVtT2NjdXJyZW5jZXMoKSA+IDApCisgICAgICBOZXdBdHRycy5hZGRBdHRyaWJ1dGUoIm5vLWZyYW1lLXBvaW50ZXItZWxpbSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGlzYWJsZUZQRWxpbSA/ICJ0cnVlIiA6ICJmYWxzZSIpOworICAgIGlmIChEaXNhYmxlVGFpbENhbGxzLmdldE51bU9jY3VycmVuY2VzKCkgPiAwKQorICAgICAgTmV3QXR0cnMuYWRkQXR0cmlidXRlKCJkaXNhYmxlLXRhaWwtY2FsbHMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvU3RyaW5nUmVmKERpc2FibGVUYWlsQ2FsbHMpKTsKKyAgICBpZiAoU3RhY2tSZWFsaWduKQorICAgICAgTmV3QXR0cnMuYWRkQXR0cmlidXRlKCJzdGFja3JlYWxpZ24iKTsKKworICAgIGlmIChUcmFwRnVuY05hbWUuZ2V0TnVtT2NjdXJyZW5jZXMoKSA+IDApCisgICAgICBmb3IgKGF1dG8gJkIgOiBGKQorICAgICAgICBmb3IgKGF1dG8gJkkgOiBCKQorICAgICAgICAgIGlmIChhdXRvICpDYWxsID0gZHluX2Nhc3Q8Q2FsbEluc3Q+KCZJKSkKKyAgICAgICAgICAgIGlmIChjb25zdCBhdXRvICpGID0gQ2FsbC0+Z2V0Q2FsbGVkRnVuY3Rpb24oKSkKKyAgICAgICAgICAgICAgaWYgKEYtPmdldEludHJpbnNpY0lEKCkgPT0gSW50cmluc2ljOjpkZWJ1Z3RyYXAgfHwKKyAgICAgICAgICAgICAgICAgIEYtPmdldEludHJpbnNpY0lEKCkgPT0gSW50cmluc2ljOjp0cmFwKQorICAgICAgICAgICAgICAgIENhbGwtPmFkZEF0dHJpYnV0ZSgKKyAgICAgICAgICAgICAgICAgICAgbGx2bTo6QXR0cmlidXRlTGlzdDo6RnVuY3Rpb25JbmRleCwKKyAgICAgICAgICAgICAgICAgICAgQXR0cmlidXRlOjpnZXQoQ3R4LCAidHJhcC1mdW5jLW5hbWUiLCBUcmFwRnVuY05hbWUpKTsKKworICAgIC8vIExldCBOZXdBdHRycyBvdmVycmlkZSBBdHRycy4KKyAgICBGLnNldEF0dHJpYnV0ZXMoCisgICAgICAgIEF0dHJzLmFkZEF0dHJpYnV0ZXMoQ3R4LCBBdHRyaWJ1dGVMaXN0OjpGdW5jdGlvbkluZGV4LCBOZXdBdHRycykpOworICB9Cit9CmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vQ29zdFRhYmxlLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vQ29zdFRhYmxlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGZjMTZkMwotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9Db3N0VGFibGUuaApAQCAtMCwwICsxLDY5IEBACisvLz09PS0tIENvc3RUYWJsZS5oIC0gSW5zdHJ1Y3Rpb24gQ29zdCBUYWJsZSBoYW5kbGluZyAtLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vCisvLy8gXGZpbGUKKy8vLyBcYnJpZWYgQ29zdCB0YWJsZXMgYW5kIHNpbXBsZSBsb29rdXAgZnVuY3Rpb25zCisvLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0NPU1RUQUJMRV9IXworI2RlZmluZSBMTFZNX0NPREVHRU5fQ09TVFRBQkxFX0hfCisKKyNpbmNsdWRlICJsbHZtL0FEVC9BcnJheVJlZi5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NUTEV4dHJhcy5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9NYWNoaW5lVmFsdWVUeXBlLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKworLy8vIENvc3QgVGFibGUgRW50cnkKK3N0cnVjdCBDb3N0VGJsRW50cnkgeworICBpbnQgSVNEOworICBNVlQ6OlNpbXBsZVZhbHVlVHlwZSBUeXBlOworICB1bnNpZ25lZCBDb3N0OworfTsKKworLy8vIEZpbmQgaW4gY29zdCB0YWJsZSwgVHlwZVR5IG11c3QgYmUgY29tcGFyYWJsZSB0byBDb21wYXJlVHkgYnkgPT0KK2lubGluZSBjb25zdCBDb3N0VGJsRW50cnkgKkNvc3RUYWJsZUxvb2t1cChBcnJheVJlZjxDb3N0VGJsRW50cnk+IFRibCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgSVNELCBNVlQgVHkpIHsKKyAgYXV0byBJID0gZmluZF9pZihUYmwsIFs9XShjb25zdCBDb3N0VGJsRW50cnkgJkVudHJ5KSB7CisgICAgcmV0dXJuIElTRCA9PSBFbnRyeS5JU0QgJiYgVHkgPT0gRW50cnkuVHlwZTsKKyAgfSk7CisgIGlmIChJICE9IFRibC5lbmQoKSkKKyAgICByZXR1cm4gSTsKKworICAvLyBDb3VsZCBub3QgZmluZCBhbiBlbnRyeS4KKyAgcmV0dXJuIG51bGxwdHI7Cit9CisKKy8vLyBUeXBlIENvbnZlcnNpb24gQ29zdCBUYWJsZQorc3RydWN0IFR5cGVDb252ZXJzaW9uQ29zdFRibEVudHJ5IHsKKyAgaW50IElTRDsKKyAgTVZUOjpTaW1wbGVWYWx1ZVR5cGUgRHN0OworICBNVlQ6OlNpbXBsZVZhbHVlVHlwZSBTcmM7CisgIHVuc2lnbmVkIENvc3Q7Cit9OworCisvLy8gRmluZCBpbiB0eXBlIGNvbnZlcnNpb24gY29zdCB0YWJsZSwgVHlwZVR5IG11c3QgYmUgY29tcGFyYWJsZSB0byBDb21wYXJlVHkKKy8vLyBieSA9PQoraW5saW5lIGNvbnN0IFR5cGVDb252ZXJzaW9uQ29zdFRibEVudHJ5ICoKK0NvbnZlcnRDb3N0VGFibGVMb29rdXAoQXJyYXlSZWY8VHlwZUNvbnZlcnNpb25Db3N0VGJsRW50cnk+IFRibCwKKyAgICAgICAgICAgICAgICAgICAgICAgaW50IElTRCwgTVZUIERzdCwgTVZUIFNyYykgeworICBhdXRvIEkgPSBmaW5kX2lmKFRibCwgWz1dKGNvbnN0IFR5cGVDb252ZXJzaW9uQ29zdFRibEVudHJ5ICZFbnRyeSkgeworICAgIHJldHVybiBJU0QgPT0gRW50cnkuSVNEICYmIFNyYyA9PSBFbnRyeS5TcmMgJiYgRHN0ID09IEVudHJ5LkRzdDsKKyAgfSk7CisgIGlmIChJICE9IFRibC5lbmQoKSkKKyAgICByZXR1cm4gSTsKKworICAvLyBDb3VsZCBub3QgZmluZCBhbiBlbnRyeS4KKyAgcmV0dXJuIG51bGxwdHI7Cit9CisKK30gLy8gbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8qIExMVk1fQ09ERUdFTl9DT1NUVEFCTEVfSF8gKi8KZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9EQUdDb21iaW5lLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vREFHQ29tYmluZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhiNTkxOTAKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vREFHQ29tYmluZS5oCkBAIC0wLDAgKzEsMjUgQEAKKy8vPT09LS0gbGx2bS9Db2RlR2VuL0RBR0NvbWJpbmUuaCAgLS0tLS0tLSBTZWxlY3Rpb25EQUcgTm9kZXMgLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9EQUdDT01CSU5FX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0RBR0NPTUJJTkVfSAorCituYW1lc3BhY2UgbGx2bSB7CisKK2VudW0gQ29tYmluZUxldmVsIHsKKyAgQmVmb3JlTGVnYWxpemVUeXBlcywKKyAgQWZ0ZXJMZWdhbGl6ZVR5cGVzLAorICBBZnRlckxlZ2FsaXplVmVjdG9yT3BzLAorICBBZnRlckxlZ2FsaXplREFHCit9OworCit9IC8vIGVuZCBsbHZtIG5hbWVzcGFjZQorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9ERkFQYWNrZXRpemVyLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vREZBUGFja2V0aXplci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQzYWFiZTIKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vREZBUGFja2V0aXplci5oCkBAIC0wLDAgKzEsMjIyIEBACisvLz09PS0gbGx2bS9Db2RlR2VuL0RGQVBhY2tldGl6ZXIuaCAtIERGQSBQYWNrZXRpemVyIGZvciBWTElXIC0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8gVGhpcyBjbGFzcyBpbXBsZW1lbnRzIGEgZGV0ZXJtaW5pc3RpYyBmaW5pdGUgYXV0b21hdG9uIChERkEpIGJhc2VkCisvLyBwYWNrZXRpemluZyBtZWNoYW5pc20gZm9yIFZMSVcgYXJjaGl0ZWN0dXJlcy4gSXQgcHJvdmlkZXMgQVBJcyB0bworLy8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlcmUgZXhpc3RzIGEgbGVnYWwgbWFwcGluZyBvZiBpbnN0cnVjdGlvbnMgdG8KKy8vIGZ1bmN0aW9uYWwgdW5pdCBhc3NpZ25tZW50cyBpbiBhIHBhY2tldC4gVGhlIERGQSBpcyBhdXRvLWdlbmVyYXRlZCBmcm9tCisvLyB0aGUgdGFyZ2V0J3MgU2NoZWR1bGUudGQgZmlsZS4KKy8vCisvLyBBIERGQSBjb25zaXN0cyBvZiAzIG1ham9yIGVsZW1lbnRzOiBzdGF0ZXMsIGlucHV0cywgYW5kIHRyYW5zaXRpb25zLiBGb3IKKy8vIHRoZSBwYWNrZXRpemluZyBtZWNoYW5pc20sIHRoZSBpbnB1dCBpcyB0aGUgc2V0IG9mIGluc3RydWN0aW9uIGNsYXNzZXMgZm9yCisvLyBhIHRhcmdldC4gVGhlIHN0YXRlIG1vZGVscyBhbGwgcG9zc2libGUgY29tYmluYXRpb25zIG9mIGZ1bmN0aW9uYWwgdW5pdAorLy8gY29uc3VtcHRpb24gZm9yIGEgZ2l2ZW4gc2V0IG9mIGluc3RydWN0aW9ucyBpbiBhIHBhY2tldC4gQSB0cmFuc2l0aW9uCisvLyBtb2RlbHMgdGhlIGFkZGl0aW9uIG9mIGFuIGluc3RydWN0aW9uIHRvIGEgcGFja2V0LiBJbiB0aGUgREZBIGNvbnN0cnVjdGVkCisvLyBieSB0aGlzIGNsYXNzLCBpZiBhbiBpbnN0cnVjdGlvbiBjYW4gYmUgYWRkZWQgdG8gYSBwYWNrZXQsIHRoZW4gYSB2YWxpZAorLy8gdHJhbnNpdGlvbiBleGlzdHMgZnJvbSB0aGUgY29ycmVzcG9uZGluZyBzdGF0ZS4gSW52YWxpZCB0cmFuc2l0aW9ucworLy8gaW5kaWNhdGUgdGhhdCB0aGUgaW5zdHJ1Y3Rpb24gY2Fubm90IGJlIGFkZGVkIHRvIHRoZSBjdXJyZW50IHBhY2tldC4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9ERkFQQUNLRVRJWkVSX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0RGQVBBQ0tFVElaRVJfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2NoZWR1bGVEQUdNdXRhdGlvbi5oIgorI2luY2x1ZGUgPGNzdGRpbnQ+CisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpbmNsdWRlIDx1dGlsaXR5PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBEZWZhdWx0VkxJV1NjaGVkdWxlcjsKK2NsYXNzIEluc3RySXRpbmVyYXJ5RGF0YTsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIE1hY2hpbmVJbnN0cjsKK2NsYXNzIE1hY2hpbmVMb29wSW5mbzsKK2NsYXNzIE1DSW5zdHJEZXNjOworY2xhc3MgU1VuaXQ7CitjbGFzcyBUYXJnZXRJbnN0ckluZm87CisKKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyBEZWZpbml0aW9ucyBzaGFyZWQgYmV0d2VlbiBERkFQYWNrZXRpemVyLmNwcCBhbmQgREZBUGFja2V0aXplckVtaXR0ZXIuY3BwCisKKy8vIERGQV9NQVhfUkVTVEVSTVMgKiBERkFfTUFYX1JFU09VUkNFUyBtdXN0IGZpdCB3aXRoaW4gc2l6ZW9mIERGQUlucHV0LgorLy8gVGhpcyBpcyB2ZXJpZmllZCBpbiBERkFQYWNrZXRpemVyLmNwcDpERkFQYWNrZXRpemVyOjpERkFQYWNrZXRpemVyLgorLy8KKy8vIGUuZy4gdGVybXMgeCByZXNvdXJjZSBiaXQgY29tYmluYXRpb25zIHRoYXQgZml0IGluIHVpbnQzMl90OgorLy8gICAgICA0IHRlcm1zIHggOCAgYml0cyA9IDMyIGJpdHMKKy8vICAgICAgMyB0ZXJtcyB4IDEwIGJpdHMgPSAzMCBiaXRzCisvLyAgICAgIDIgdGVybXMgeCAxNiBiaXRzID0gMzIgYml0cworLy8KKy8vIGUuZy4gdGVybXMgeCByZXNvdXJjZSBiaXQgY29tYmluYXRpb25zIHRoYXQgZml0IGluIHVpbnQ2NF90OgorLy8gICAgICA4IHRlcm1zIHggOCAgYml0cyA9IDY0IGJpdHMKKy8vICAgICAgNyB0ZXJtcyB4IDkgIGJpdHMgPSA2MyBiaXRzCisvLyAgICAgIDYgdGVybXMgeCAxMCBiaXRzID0gNjAgYml0cworLy8gICAgICA1IHRlcm1zIHggMTIgYml0cyA9IDYwIGJpdHMKKy8vICAgICAgNCB0ZXJtcyB4IDE2IGJpdHMgPSA2NCBiaXRzIDwtLS0gY3VycmVudAorLy8gICAgICAzIHRlcm1zIHggMjEgYml0cyA9IDYzIGJpdHMKKy8vICAgICAgMiB0ZXJtcyB4IDMyIGJpdHMgPSA2NCBiaXRzCisvLworI2RlZmluZSBERkFfTUFYX1JFU1RFUk1TICAgICAgICA0ICAgLy8gVGhlIG1heCAjIG9mIEFORCdlZCByZXNvdXJjZSB0ZXJtcy4KKyNkZWZpbmUgREZBX01BWF9SRVNPVVJDRVMgICAgICAgMTYgIC8vIFRoZSBtYXggIyBvZiByZXNvdXJjZSBiaXRzIGluIG9uZSB0ZXJtLgorCit1c2luZyBERkFJbnB1dCA9IHVpbnQ2NF90OwordXNpbmcgREZBU3RhdGVJbnB1dCA9IGludDY0X3Q7CisKKyNkZWZpbmUgREZBX1RCTFRZUEUgICAgICAgICAgICAgImludDY0X3QiIC8vIEZvciBnZW5lcmF0aW5nIERGQVN0YXRlSW5wdXRUYWJsZS4KKy8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK2NsYXNzIERGQVBhY2tldGl6ZXIgeworcHJpdmF0ZToKKyAgdXNpbmcgVW5zaWduUGFpciA9IHN0ZDo6cGFpcjx1bnNpZ25lZCwgREZBSW5wdXQ+OworCisgIGNvbnN0IEluc3RySXRpbmVyYXJ5RGF0YSAqSW5zdHJJdGluczsKKyAgaW50IEN1cnJlbnRTdGF0ZSA9IDA7CisgIGNvbnN0IERGQVN0YXRlSW5wdXQgKCpERkFTdGF0ZUlucHV0VGFibGUpWzJdOworICBjb25zdCB1bnNpZ25lZCAqREZBU3RhdGVFbnRyeVRhYmxlOworCisgIC8vIENhY2hlZFRhYmxlIGlzIGEgbWFwIGZyb20gPEZyb21TdGF0ZSwgSW5wdXQ+IHRvIFRvU3RhdGUuCisgIERlbnNlTWFwPFVuc2lnblBhaXIsIHVuc2lnbmVkPiBDYWNoZWRUYWJsZTsKKworICAvLyBSZWFkIHRoZSBERkEgdHJhbnNpdGlvbiB0YWJsZSBhbmQgdXBkYXRlIENhY2hlZFRhYmxlLgorICB2b2lkIFJlYWRUYWJsZSh1bnNpZ25lZCBzdGF0ZSk7CisKK3B1YmxpYzoKKyAgREZBUGFja2V0aXplcihjb25zdCBJbnN0ckl0aW5lcmFyeURhdGEgKkksIGNvbnN0IERGQVN0YXRlSW5wdXQgKCpTSVQpWzJdLAorICAgICAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkICpTRVQpOworCisgIC8vIFJlc2V0IHRoZSBjdXJyZW50IHN0YXRlIHRvIG1ha2UgYWxsIHJlc291cmNlcyBhdmFpbGFibGUuCisgIHZvaWQgY2xlYXJSZXNvdXJjZXMoKSB7CisgICAgQ3VycmVudFN0YXRlID0gMDsKKyAgfQorCisgIC8vIFJldHVybiB0aGUgREZBSW5wdXQgZm9yIGFuIGluc3RydWN0aW9uIGNsYXNzLgorICBERkFJbnB1dCBnZXRJbnNuSW5wdXQodW5zaWduZWQgSW5zbkNsYXNzKTsKKworICAvLyBSZXR1cm4gdGhlIERGQUlucHV0IGZvciBhbiBpbnN0cnVjdGlvbiBjbGFzcyBpbnB1dCB2ZWN0b3IuCisgIHN0YXRpYyBERkFJbnB1dCBnZXRJbnNuSW5wdXQoY29uc3Qgc3RkOjp2ZWN0b3I8dW5zaWduZWQ+ICZJbnNuQ2xhc3MpOworCisgIC8vIENoZWNrIGlmIHRoZSByZXNvdXJjZXMgb2NjdXBpZWQgYnkgYSBNQ0luc3RyRGVzYyBhcmUgYXZhaWxhYmxlIGluCisgIC8vIHRoZSBjdXJyZW50IHN0YXRlLgorICBib29sIGNhblJlc2VydmVSZXNvdXJjZXMoY29uc3QgTUNJbnN0ckRlc2MgKk1JRCk7CisKKyAgLy8gUmVzZXJ2ZSB0aGUgcmVzb3VyY2VzIG9jY3VwaWVkIGJ5IGEgTUNJbnN0ckRlc2MgYW5kIGNoYW5nZSB0aGUgY3VycmVudAorICAvLyBzdGF0ZSB0byByZWZsZWN0IHRoYXQgY2hhbmdlLgorICB2b2lkIHJlc2VydmVSZXNvdXJjZXMoY29uc3QgTUNJbnN0ckRlc2MgKk1JRCk7CisKKyAgLy8gQ2hlY2sgaWYgdGhlIHJlc291cmNlcyBvY2N1cGllZCBieSBhIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gYXJlIGF2YWlsYWJsZQorICAvLyBpbiB0aGUgY3VycmVudCBzdGF0ZS4KKyAgYm9vbCBjYW5SZXNlcnZlUmVzb3VyY2VzKE1hY2hpbmVJbnN0ciAmTUkpOworCisgIC8vIFJlc2VydmUgdGhlIHJlc291cmNlcyBvY2N1cGllZCBieSBhIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gYW5kIGNoYW5nZSB0aGUKKyAgLy8gY3VycmVudCBzdGF0ZSB0byByZWZsZWN0IHRoYXQgY2hhbmdlLgorICB2b2lkIHJlc2VydmVSZXNvdXJjZXMoTWFjaGluZUluc3RyICZNSSk7CisKKyAgY29uc3QgSW5zdHJJdGluZXJhcnlEYXRhICpnZXRJbnN0ckl0aW5zKCkgY29uc3QgeyByZXR1cm4gSW5zdHJJdGluczsgfQorfTsKKworLy8gVkxJV1BhY2tldGl6ZXJMaXN0IGltcGxlbWVudHMgYSBzaW1wbGUgVkxJVyBwYWNrZXRpemVyIHVzaW5nIERGQS4gVGhlCisvLyBwYWNrZXRpemVyIHdvcmtzIG9uIG1hY2hpbmUgYmFzaWMgYmxvY2tzLiBGb3IgZWFjaCBpbnN0cnVjdGlvbiBJIGluIEJCLAorLy8gdGhlIHBhY2tldGl6ZXIgY29uc3VsdHMgdGhlIERGQSB0byBzZWUgaWYgbWFjaGluZSByZXNvdXJjZXMgYXJlIGF2YWlsYWJsZQorLy8gdG8gZXhlY3V0ZSBJLiBJZiBzbywgdGhlIHBhY2tldGl6ZXIgY2hlY2tzIGlmIEkgZGVwZW5kcyBvbiBhbnkgaW5zdHJ1Y3Rpb24KKy8vIGluIHRoZSBjdXJyZW50IHBhY2tldC4gSWYgbm8gZGVwZW5kZW5jeSBpcyBmb3VuZCwgSSBpcyBhZGRlZCB0byBjdXJyZW50CisvLyBwYWNrZXQgYW5kIHRoZSBtYWNoaW5lIHJlc291cmNlIGlzIG1hcmtlZCBhcyB0YWtlbi4gSWYgYW55IGRlcGVuZGVuY3kgaXMKKy8vIGZvdW5kLCBhIHRhcmdldCBBUEkgY2FsbCBpcyBtYWRlIHRvIHBydW5lIHRoZSBkZXBlbmRlbmNlLgorY2xhc3MgVkxJV1BhY2tldGl6ZXJMaXN0IHsKK3Byb3RlY3RlZDoKKyAgTWFjaGluZUZ1bmN0aW9uICZNRjsKKyAgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICpUSUk7CisgIEFsaWFzQW5hbHlzaXMgKkFBOworCisgIC8vIFRoZSBWTElXIFNjaGVkdWxlci4KKyAgRGVmYXVsdFZMSVdTY2hlZHVsZXIgKlZMSVdTY2hlZHVsZXI7CisgIC8vIFZlY3RvciBvZiBpbnN0cnVjdGlvbnMgYXNzaWduZWQgdG8gdGhlIGN1cnJlbnQgcGFja2V0LgorICBzdGQ6OnZlY3RvcjxNYWNoaW5lSW5zdHIqPiBDdXJyZW50UGFja2V0TUlzOworICAvLyBERkEgcmVzb3VyY2UgdHJhY2tlci4KKyAgREZBUGFja2V0aXplciAqUmVzb3VyY2VUcmFja2VyOworICAvLyBNYXA6IE1JIC0+IFNVLgorICBzdGQ6Om1hcDxNYWNoaW5lSW5zdHIqLCBTVW5pdCo+IE1JVG9TVW5pdDsKKworcHVibGljOgorICAvLyBUaGUgQWxpYXNBbmFseXNpcyBwYXJhbWV0ZXIgY2FuIGJlIG51bGxwdHIuCisgIFZMSVdQYWNrZXRpemVyTGlzdChNYWNoaW5lRnVuY3Rpb24gJk1GLCBNYWNoaW5lTG9vcEluZm8gJk1MSSwKKyAgICAgICAgICAgICAgICAgICAgIEFsaWFzQW5hbHlzaXMgKkFBKTsKKworICB2aXJ0dWFsIH5WTElXUGFja2V0aXplckxpc3QoKTsKKworICAvLyBJbXBsZW1lbnQgdGhpcyBBUEkgaW4gdGhlIGJhY2tlbmQgdG8gYnVuZGxlIGluc3RydWN0aW9ucy4KKyAgdm9pZCBQYWNrZXRpemVNSXMoTWFjaGluZUJhc2ljQmxvY2sgKk1CQiwKKyAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEJlZ2luSXRyLAorICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgRW5kSXRyKTsKKworICAvLyBSZXR1cm4gdGhlIFJlc291cmNlVHJhY2tlci4KKyAgREZBUGFja2V0aXplciAqZ2V0UmVzb3VyY2VUcmFja2VyKCkge3JldHVybiBSZXNvdXJjZVRyYWNrZXI7fQorCisgIC8vIGFkZFRvUGFja2V0IC0gQWRkIE1JIHRvIHRoZSBjdXJyZW50IHBhY2tldC4KKyAgdmlydHVhbCBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgYWRkVG9QYWNrZXQoTWFjaGluZUluc3RyICZNSSkgeworICAgIEN1cnJlbnRQYWNrZXRNSXMucHVzaF9iYWNrKCZNSSk7CisgICAgUmVzb3VyY2VUcmFja2VyLT5yZXNlcnZlUmVzb3VyY2VzKE1JKTsKKyAgICByZXR1cm4gTUk7CisgIH0KKworICAvLyBFbmQgdGhlIGN1cnJlbnQgcGFja2V0IGFuZCByZXNldCB0aGUgc3RhdGUgb2YgdGhlIHBhY2tldGl6ZXIuCisgIC8vIE92ZXJyaWRpbmcgdGhpcyBmdW5jdGlvbiBhbGxvd3MgdGhlIHRhcmdldC1zcGVjaWZpYyBwYWNrZXRpemVyCisgIC8vIHRvIHBlcmZvcm0gY3VzdG9tIGZpbmFsaXphdGlvbi4KKyAgdmlydHVhbCB2b2lkIGVuZFBhY2tldChNYWNoaW5lQmFzaWNCbG9jayAqTUJCLAorICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBNSSk7CisKKyAgLy8gUGVyZm9ybSBpbml0aWFsaXphdGlvbiBiZWZvcmUgcGFja2V0aXppbmcgYW4gaW5zdHJ1Y3Rpb24uIFRoaXMKKyAgLy8gZnVuY3Rpb24gaXMgc3VwcG9zZWQgdG8gYmUgb3ZlcnJpZGVkIGJ5IHRoZSB0YXJnZXQgZGVwZW5kZW50IHBhY2tldGl6ZXIuCisgIHZpcnR1YWwgdm9pZCBpbml0UGFja2V0aXplclN0YXRlKCkge30KKworICAvLyBDaGVjayBpZiB0aGUgZ2l2ZW4gaW5zdHJ1Y3Rpb24gSSBzaG91bGQgYmUgaWdub3JlZCBieSB0aGUgcGFja2V0aXplci4KKyAgdmlydHVhbCBib29sIGlnbm9yZVBzZXVkb0luc3RydWN0aW9uKGNvbnN0IE1hY2hpbmVJbnN0ciAmSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLyBSZXR1cm4gdHJ1ZSBpZiBpbnN0cnVjdGlvbiBNSSBjYW4gbm90IGJlIHBhY2tldGl6ZWQgd2l0aCBhbnkgb3RoZXIKKyAgLy8gaW5zdHJ1Y3Rpb24sIHdoaWNoIG1lYW5zIHRoYXQgTUkgaXRzZWxmIGlzIGEgcGFja2V0LgorICB2aXJ0dWFsIGJvb2wgaXNTb2xvSW5zdHJ1Y3Rpb24oY29uc3QgTWFjaGluZUluc3RyICZNSSkgeyByZXR1cm4gdHJ1ZTsgfQorCisgIC8vIENoZWNrIGlmIHRoZSBwYWNrZXRpemVyIHNob3VsZCB0cnkgdG8gYWRkIHRoZSBnaXZlbiBpbnN0cnVjdGlvbiB0bworICAvLyB0aGUgY3VycmVudCBwYWNrZXQuIE9uZSByZWFzb25zIGZvciB3aGljaCBpdCBtYXkgbm90IGJlIGRlc2lyYWJsZQorICAvLyB0byBpbmNsdWRlIGFuIGluc3RydWN0aW9uIGluIHRoZSBjdXJyZW50IHBhY2tldCBjb3VsZCBiZSB0aGF0IGl0CisgIC8vIHdvdWxkIGNhdXNlIGEgc3RhbGwuCisgIC8vIElmIHRoaXMgZnVuY3Rpb24gcmV0dXJucyAiZmFsc2UiLCB0aGUgY3VycmVudCBwYWNrZXQgd2lsbCBiZSBlbmRlZCwKKyAgLy8gYW5kIHRoZSBpbnN0cnVjdGlvbiB3aWxsIGJlIGFkZGVkIHRvIHRoZSBuZXh0IHBhY2tldC4KKyAgdmlydHVhbCBib29sIHNob3VsZEFkZFRvUGFja2V0KGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIHsgcmV0dXJuIHRydWU7IH0KKworICAvLyBDaGVjayBpZiBpdCBpcyBsZWdhbCB0byBwYWNrZXRpemUgU1VJIGFuZCBTVUogdG9nZXRoZXIuCisgIHZpcnR1YWwgYm9vbCBpc0xlZ2FsVG9QYWNrZXRpemVUb2dldGhlcihTVW5pdCAqU1VJLCBTVW5pdCAqU1VKKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gQ2hlY2sgaWYgaXQgaXMgbGVnYWwgdG8gcHJ1bmUgZGVwZW5kZWNlIGJldHdlZW4gU1VJIGFuZCBTVUouCisgIHZpcnR1YWwgYm9vbCBpc0xlZ2FsVG9QcnVuZURlcGVuZGVuY2llcyhTVW5pdCAqU1VJLCBTVW5pdCAqU1VKKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gQWRkIGEgREFHIG11dGF0aW9uIHRvIGJlIGRvbmUgYmVmb3JlIHRoZSBwYWNrZXRpemF0aW9uIGJlZ2lucy4KKyAgdm9pZCBhZGRNdXRhdGlvbihzdGQ6OnVuaXF1ZV9wdHI8U2NoZWR1bGVEQUdNdXRhdGlvbj4gTXV0YXRpb24pOworCisgIGJvb2wgYWxpYXMoY29uc3QgTWFjaGluZUluc3RyICZNSTEsIGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkyLAorICAgICAgICAgICAgIGJvb2wgVXNlVEJBQSA9IHRydWUpIGNvbnN0OworCitwcml2YXRlOgorICBib29sIGFsaWFzKGNvbnN0IE1hY2hpbmVNZW1PcGVyYW5kICZPcDEsIGNvbnN0IE1hY2hpbmVNZW1PcGVyYW5kICZPcDIsCisgICAgICAgICAgICAgYm9vbCBVc2VUQkFBID0gdHJ1ZSkgY29uc3Q7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0RGQVBBQ0tFVElaRVJfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0RJRS5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0RJRS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY4MDlmYzkKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vRElFLmgKQEAgLTAsMCArMSw5MTAgQEAKKy8vPT09LSBsaWIvQ29kZUdlbi9ESUUuaCAtIERXQVJGIEluZm8gRW50cmllcyAtLS0tLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gRGF0YSBzdHJ1Y3R1cmVzIGZvciBEV0FSRiBpbmZvIGVudHJpZXMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0xJQl9DT0RFR0VOX0FTTVBSSU5URVJfRElFX0gKKyNkZWZpbmUgTExWTV9MSUJfQ09ERUdFTl9BU01QUklOVEVSX0RJRV9ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9Gb2xkaW5nU2V0LmgiCisjaW5jbHVkZSAibGx2bS9BRFQvUG9pbnRlckludFBhaXIuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9Qb2ludGVyVW5pb24uaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQURUL1N0cmluZ1JlZi5oIgorI2luY2x1ZGUgImxsdm0vQURUL2l0ZXJhdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvaXRlcmF0b3JfcmFuZ2UuaCIKKyNpbmNsdWRlICJsbHZtL0JpbmFyeUZvcm1hdC9Ed2FyZi5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9Ed2FyZlN0cmluZ1Bvb2xFbnRyeS5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9BbGlnbk9mLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0FsbG9jYXRvci5oIgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8Y3N0ZGRlZj4KKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPGl0ZXJhdG9yPgorI2luY2x1ZGUgPG5ldz4KKyNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KKyNpbmNsdWRlIDx1dGlsaXR5PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBBc21QcmludGVyOworY2xhc3MgRElFOworY2xhc3MgRElFVW5pdDsKK2NsYXNzIE1DRXhwcjsKK2NsYXNzIE1DU2VjdGlvbjsKK2NsYXNzIE1DU3ltYm9sOworY2xhc3MgcmF3X29zdHJlYW07CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vIER3YXJmIGFiYnJldmlhdGlvbiBkYXRhLCBkZXNjcmliZXMgb25lIGF0dHJpYnV0ZSBvZiBhIER3YXJmIGFiYnJldmlhdGlvbi4KK2NsYXNzIERJRUFiYnJldkRhdGEgeworICAvLy8gRHdhcmYgYXR0cmlidXRlIGNvZGUuCisgIGR3YXJmOjpBdHRyaWJ1dGUgQXR0cmlidXRlOworCisgIC8vLyBEd2FyZiBmb3JtIGNvZGUuCisgIGR3YXJmOjpGb3JtIEZvcm07CisKKyAgLy8vIER3YXJmIGF0dHJpYnV0ZSB2YWx1ZSBmb3IgRFdfRk9STV9pbXBsaWNpdF9jb25zdAorICBpbnQ2NF90IFZhbHVlID0gMDsKKworcHVibGljOgorICBESUVBYmJyZXZEYXRhKGR3YXJmOjpBdHRyaWJ1dGUgQSwgZHdhcmY6OkZvcm0gRikKKyAgICAgIDogQXR0cmlidXRlKEEpLCBGb3JtKEYpIHt9CisgIERJRUFiYnJldkRhdGEoZHdhcmY6OkF0dHJpYnV0ZSBBLCBpbnQ2NF90IFYpCisgICAgICA6IEF0dHJpYnV0ZShBKSwgRm9ybShkd2FyZjo6RFdfRk9STV9pbXBsaWNpdF9jb25zdCksIFZhbHVlKFYpIHt9CisKKyAgLy8vIEFjY2Vzc29ycy4KKyAgLy8vIEB7CisgIGR3YXJmOjpBdHRyaWJ1dGUgZ2V0QXR0cmlidXRlKCkgY29uc3QgeyByZXR1cm4gQXR0cmlidXRlOyB9CisgIGR3YXJmOjpGb3JtIGdldEZvcm0oKSBjb25zdCB7IHJldHVybiBGb3JtOyB9CisgIGludDY0X3QgZ2V0VmFsdWUoKSBjb25zdCB7IHJldHVybiBWYWx1ZTsgfQorICAvLy8gQH0KKworICAvLy8gVXNlZCB0byBnYXRoZXIgdW5pcXVlIGRhdGEgZm9yIHRoZSBhYmJyZXZpYXRpb24gZm9sZGluZyBzZXQuCisgIHZvaWQgUHJvZmlsZShGb2xkaW5nU2V0Tm9kZUlEICZJRCkgY29uc3Q7Cit9OworCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLyBEd2FyZiBhYmJyZXZpYXRpb24sIGRlc2NyaWJlcyB0aGUgb3JnYW5pemF0aW9uIG9mIGEgZGVidWcgaW5mb3JtYXRpb24KKy8vLyBvYmplY3QuCitjbGFzcyBESUVBYmJyZXYgOiBwdWJsaWMgRm9sZGluZ1NldE5vZGUgeworICAvLy8gVW5pcXVlIG51bWJlciBmb3Igbm9kZS4KKyAgdW5zaWduZWQgTnVtYmVyOworCisgIC8vLyBEd2FyZiB0YWcgY29kZS4KKyAgZHdhcmY6OlRhZyBUYWc7CisKKyAgLy8vIFdoZXRoZXIgb3Igbm90IHRoaXMgbm9kZSBoYXMgY2hpbGRyZW4uCisgIC8vLworICAvLy8gVGhpcyBjaGVhdHMgYSBiaXQgaW4gYWxsIG9mIHRoZSB1c2VzIHNpbmNlIHRoZSB2YWx1ZXMgaW4gdGhlIHN0YW5kYXJkCisgIC8vLyBhcmUgMCBhbmQgMSBmb3Igbm8gY2hpbGRyZW4gYW5kIGNoaWxkcmVuIHJlc3BlY3RpdmVseS4KKyAgYm9vbCBDaGlsZHJlbjsKKworICAvLy8gUmF3IGRhdGEgYnl0ZXMgZm9yIGFiYnJldmlhdGlvbi4KKyAgU21hbGxWZWN0b3I8RElFQWJicmV2RGF0YSwgMTI+IERhdGE7CisKK3B1YmxpYzoKKyAgRElFQWJicmV2KGR3YXJmOjpUYWcgVCwgYm9vbCBDKSA6IFRhZyhUKSwgQ2hpbGRyZW4oQykge30KKworICAvLy8gQWNjZXNzb3JzLgorICAvLy8gQHsKKyAgZHdhcmY6OlRhZyBnZXRUYWcoKSBjb25zdCB7IHJldHVybiBUYWc7IH0KKyAgdW5zaWduZWQgZ2V0TnVtYmVyKCkgY29uc3QgeyByZXR1cm4gTnVtYmVyOyB9CisgIGJvb2wgaGFzQ2hpbGRyZW4oKSBjb25zdCB7IHJldHVybiBDaGlsZHJlbjsgfQorICBjb25zdCBTbWFsbFZlY3RvckltcGw8RElFQWJicmV2RGF0YT4gJmdldERhdGEoKSBjb25zdCB7IHJldHVybiBEYXRhOyB9CisgIHZvaWQgc2V0Q2hpbGRyZW5GbGFnKGJvb2wgaGFzQ2hpbGQpIHsgQ2hpbGRyZW4gPSBoYXNDaGlsZDsgfQorICB2b2lkIHNldE51bWJlcih1bnNpZ25lZCBOKSB7IE51bWJlciA9IE47IH0KKyAgLy8vIEB9CisKKyAgLy8vIEFkZHMgYW5vdGhlciBzZXQgb2YgYXR0cmlidXRlIGluZm9ybWF0aW9uIHRvIHRoZSBhYmJyZXZpYXRpb24uCisgIHZvaWQgQWRkQXR0cmlidXRlKGR3YXJmOjpBdHRyaWJ1dGUgQXR0cmlidXRlLCBkd2FyZjo6Rm9ybSBGb3JtKSB7CisgICAgRGF0YS5wdXNoX2JhY2soRElFQWJicmV2RGF0YShBdHRyaWJ1dGUsIEZvcm0pKTsKKyAgfQorCisgIC8vLyBBZGRzIGF0dHJpYnV0ZSB3aXRoIERXX0ZPUk1faW1wbGljaXRfY29uc3QgdmFsdWUKKyAgdm9pZCBBZGRJbXBsaWNpdENvbnN0QXR0cmlidXRlKGR3YXJmOjpBdHRyaWJ1dGUgQXR0cmlidXRlLCBpbnQ2NF90IFZhbHVlKSB7CisgICAgRGF0YS5wdXNoX2JhY2soRElFQWJicmV2RGF0YShBdHRyaWJ1dGUsIFZhbHVlKSk7CisgIH0KKworICAvLy8gVXNlZCB0byBnYXRoZXIgdW5pcXVlIGRhdGEgZm9yIHRoZSBhYmJyZXZpYXRpb24gZm9sZGluZyBzZXQuCisgIHZvaWQgUHJvZmlsZShGb2xkaW5nU2V0Tm9kZUlEICZJRCkgY29uc3Q7CisKKyAgLy8vIFByaW50IHRoZSBhYmJyZXZpYXRpb24gdXNpbmcgdGhlIHNwZWNpZmllZCBhc20gcHJpbnRlci4KKyAgdm9pZCBFbWl0KGNvbnN0IEFzbVByaW50ZXIgKkFQKSBjb25zdDsKKworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPKSBjb25zdDsKKyAgdm9pZCBkdW1wKCkgY29uc3Q7Cit9OworCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLyBIZWxwcyB1bmlxdWUgRElFQWJicmV2IG9iamVjdHMgYW5kIGFzc2lnbnMgYWJicmV2aWF0aW9uIG51bWJlcnMuCisvLy8KKy8vLyBUaGlzIGNsYXNzIHdpbGwgdW5pcXVlIHRoZSBESUUgYWJicmV2aWF0aW9ucyBmb3IgYSBsbHZtOjpESUUgb2JqZWN0IGFuZAorLy8vIGFzc2lnbiBhIHVuaXF1ZSBhYmJyZXZpYXRpb24gbnVtYmVyIHRvIGVhY2ggdW5pcXVlIERJRUFiYnJldiBvYmplY3QgaXQKKy8vLyBmaW5kcy4gVGhlIHJlc3VsdGluZyBjb2xsZWN0aW9uIG9mIERJRUFiYnJldiBvYmplY3RzIGNhbiB0aGVuIGJlIGVtaXR0ZWQKKy8vLyBpbnRvIHRoZSAuZGVidWdfYWJicmV2IHNlY3Rpb24uCitjbGFzcyBESUVBYmJyZXZTZXQgeworICAvLy8gVGhlIGJ1bXAgYWxsb2NhdG9yIHRvIHVzZSB3aGVuIGNyZWF0aW5nIERJRUFiYnJldiBvYmplY3RzIGluIHRoZSB1bmlxdWVkCisgIC8vLyBzdG9yYWdlIGNvbnRhaW5lci4KKyAgQnVtcFB0ckFsbG9jYXRvciAmQWxsb2M7CisgIC8vLyBcYnJpZWYgRm9sZGluZ1NldCB0aGF0IHVuaXF1ZXMgdGhlIGFiYnJldmlhdGlvbnMuCisgIEZvbGRpbmdTZXQ8RElFQWJicmV2PiBBYmJyZXZpYXRpb25zU2V0OworICAvLy8gQSBsaXN0IG9mIGFsbCB0aGUgdW5pcXVlIGFiYnJldmlhdGlvbnMgaW4gdXNlLgorICBzdGQ6OnZlY3RvcjxESUVBYmJyZXYgKj4gQWJicmV2aWF0aW9uczsKKworcHVibGljOgorICBESUVBYmJyZXZTZXQoQnVtcFB0ckFsbG9jYXRvciAmQSkgOiBBbGxvYyhBKSB7fQorICB+RElFQWJicmV2U2V0KCk7CisKKyAgLy8vIEdlbmVyYXRlIHRoZSBhYmJyZXZpYXRpb24gZGVjbGFyYXRpb24gZm9yIGEgRElFIGFuZCByZXR1cm4gYSBwb2ludGVyIHRvCisgIC8vLyB0aGUgZ2VuZXJhdGVkIGFiYnJldmlhdGlvbi4KKyAgLy8vCisgIC8vLyBccGFyYW0gRGllIHRoZSBkZWJ1ZyBpbmZvIGVudHJ5IHRvIGdlbmVyYXRlIHRoZSBhYmJyZXZpYXRpb24gZm9yLgorICAvLy8gXHJldHVybnMgQSByZWZlcmVuY2UgdG8gdGhlIHVuaXF1ZWQgYWJicmV2aWF0aW9uIGRlY2xhcmF0aW9uIHRoYXQgaXMKKyAgLy8vIG93bmVkIGJ5IHRoaXMgY2xhc3MuCisgIERJRUFiYnJldiAmdW5pcXVlQWJicmV2aWF0aW9uKERJRSAmRGllKTsKKworICAvLy8gUHJpbnQgYWxsIGFiYnJldmlhdGlvbnMgdXNpbmcgdGhlIHNwZWNpZmllZCBhc20gcHJpbnRlci4KKyAgdm9pZCBFbWl0KGNvbnN0IEFzbVByaW50ZXIgKkFQLCBNQ1NlY3Rpb24gKlNlY3Rpb24pIGNvbnN0OworfTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gQW4gaW50ZWdlciB2YWx1ZSBESUUuCisvLy8KK2NsYXNzIERJRUludGVnZXIgeworICB1aW50NjRfdCBJbnRlZ2VyOworCitwdWJsaWM6CisgIGV4cGxpY2l0IERJRUludGVnZXIodWludDY0X3QgSSkgOiBJbnRlZ2VyKEkpIHt9CisKKyAgLy8vIENob29zZSB0aGUgYmVzdCBmb3JtIGZvciBpbnRlZ2VyLgorICBzdGF0aWMgZHdhcmY6OkZvcm0gQmVzdEZvcm0oYm9vbCBJc1NpZ25lZCwgdWludDY0X3QgSW50KSB7CisgICAgaWYgKElzU2lnbmVkKSB7CisgICAgICBjb25zdCBpbnQ2NF90IFNpZ25lZEludCA9IEludDsKKyAgICAgIGlmICgoY2hhcilJbnQgPT0gU2lnbmVkSW50KQorICAgICAgICByZXR1cm4gZHdhcmY6OkRXX0ZPUk1fZGF0YTE7CisgICAgICBpZiAoKHNob3J0KUludCA9PSBTaWduZWRJbnQpCisgICAgICAgIHJldHVybiBkd2FyZjo6RFdfRk9STV9kYXRhMjsKKyAgICAgIGlmICgoaW50KUludCA9PSBTaWduZWRJbnQpCisgICAgICAgIHJldHVybiBkd2FyZjo6RFdfRk9STV9kYXRhNDsKKyAgICB9IGVsc2UgeworICAgICAgaWYgKCh1bnNpZ25lZCBjaGFyKUludCA9PSBJbnQpCisgICAgICAgIHJldHVybiBkd2FyZjo6RFdfRk9STV9kYXRhMTsKKyAgICAgIGlmICgodW5zaWduZWQgc2hvcnQpSW50ID09IEludCkKKyAgICAgICAgcmV0dXJuIGR3YXJmOjpEV19GT1JNX2RhdGEyOworICAgICAgaWYgKCh1bnNpZ25lZCBpbnQpSW50ID09IEludCkKKyAgICAgICAgcmV0dXJuIGR3YXJmOjpEV19GT1JNX2RhdGE0OworICAgIH0KKyAgICByZXR1cm4gZHdhcmY6OkRXX0ZPUk1fZGF0YTg7CisgIH0KKworICB1aW50NjRfdCBnZXRWYWx1ZSgpIGNvbnN0IHsgcmV0dXJuIEludGVnZXI7IH0KKyAgdm9pZCBzZXRWYWx1ZSh1aW50NjRfdCBWYWwpIHsgSW50ZWdlciA9IFZhbDsgfQorCisgIHZvaWQgRW1pdFZhbHVlKGNvbnN0IEFzbVByaW50ZXIgKkFQLCBkd2FyZjo6Rm9ybSBGb3JtKSBjb25zdDsKKyAgdW5zaWduZWQgU2l6ZU9mKGNvbnN0IEFzbVByaW50ZXIgKkFQLCBkd2FyZjo6Rm9ybSBGb3JtKSBjb25zdDsKKworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPKSBjb25zdDsKK307CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vIEFuIGV4cHJlc3Npb24gRElFLgorY2xhc3MgRElFRXhwciB7CisgIGNvbnN0IE1DRXhwciAqRXhwcjsKKworcHVibGljOgorICBleHBsaWNpdCBESUVFeHByKGNvbnN0IE1DRXhwciAqRSkgOiBFeHByKEUpIHt9CisKKyAgLy8vIEdldCBNQ0V4cHIuCisgIGNvbnN0IE1DRXhwciAqZ2V0VmFsdWUoKSBjb25zdCB7IHJldHVybiBFeHByOyB9CisKKyAgdm9pZCBFbWl0VmFsdWUoY29uc3QgQXNtUHJpbnRlciAqQVAsIGR3YXJmOjpGb3JtIEZvcm0pIGNvbnN0OworICB1bnNpZ25lZCBTaXplT2YoY29uc3QgQXNtUHJpbnRlciAqQVAsIGR3YXJmOjpGb3JtIEZvcm0pIGNvbnN0OworCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk8pIGNvbnN0OworfTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gQSBsYWJlbCBESUUuCitjbGFzcyBESUVMYWJlbCB7CisgIGNvbnN0IE1DU3ltYm9sICpMYWJlbDsKKworcHVibGljOgorICBleHBsaWNpdCBESUVMYWJlbChjb25zdCBNQ1N5bWJvbCAqTCkgOiBMYWJlbChMKSB7fQorCisgIC8vLyBHZXQgTUNTeW1ib2wuCisgIGNvbnN0IE1DU3ltYm9sICpnZXRWYWx1ZSgpIGNvbnN0IHsgcmV0dXJuIExhYmVsOyB9CisKKyAgdm9pZCBFbWl0VmFsdWUoY29uc3QgQXNtUHJpbnRlciAqQVAsIGR3YXJmOjpGb3JtIEZvcm0pIGNvbnN0OworICB1bnNpZ25lZCBTaXplT2YoY29uc3QgQXNtUHJpbnRlciAqQVAsIGR3YXJmOjpGb3JtIEZvcm0pIGNvbnN0OworCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk8pIGNvbnN0OworfTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gQSBzaW1wbGUgbGFiZWwgZGlmZmVyZW5jZSBESUUuCisvLy8KK2NsYXNzIERJRURlbHRhIHsKKyAgY29uc3QgTUNTeW1ib2wgKkxhYmVsSGk7CisgIGNvbnN0IE1DU3ltYm9sICpMYWJlbExvOworCitwdWJsaWM6CisgIERJRURlbHRhKGNvbnN0IE1DU3ltYm9sICpIaSwgY29uc3QgTUNTeW1ib2wgKkxvKSA6IExhYmVsSGkoSGkpLCBMYWJlbExvKExvKSB7fQorCisgIHZvaWQgRW1pdFZhbHVlKGNvbnN0IEFzbVByaW50ZXIgKkFQLCBkd2FyZjo6Rm9ybSBGb3JtKSBjb25zdDsKKyAgdW5zaWduZWQgU2l6ZU9mKGNvbnN0IEFzbVByaW50ZXIgKkFQLCBkd2FyZjo6Rm9ybSBGb3JtKSBjb25zdDsKKworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPKSBjb25zdDsKK307CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vIEEgY29udGFpbmVyIGZvciBzdHJpbmcgcG9vbCBzdHJpbmcgdmFsdWVzLgorLy8vCisvLy8gVGhpcyBjbGFzcyBpcyB1c2VkIHdpdGggdGhlIERXX0ZPUk1fc3RycCBhbmQgRFdfRk9STV9HTlVfc3RyX2luZGV4IGZvcm1zLgorY2xhc3MgRElFU3RyaW5nIHsKKyAgRHdhcmZTdHJpbmdQb29sRW50cnlSZWYgUzsKKworcHVibGljOgorICBESUVTdHJpbmcoRHdhcmZTdHJpbmdQb29sRW50cnlSZWYgUykgOiBTKFMpIHt9CisKKyAgLy8vIEdyYWIgdGhlIHN0cmluZyBvdXQgb2YgdGhlIG9iamVjdC4KKyAgU3RyaW5nUmVmIGdldFN0cmluZygpIGNvbnN0IHsgcmV0dXJuIFMuZ2V0U3RyaW5nKCk7IH0KKworICB2b2lkIEVtaXRWYWx1ZShjb25zdCBBc21QcmludGVyICpBUCwgZHdhcmY6OkZvcm0gRm9ybSkgY29uc3Q7CisgIHVuc2lnbmVkIFNpemVPZihjb25zdCBBc21QcmludGVyICpBUCwgZHdhcmY6OkZvcm0gRm9ybSkgY29uc3Q7CisKKyAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmTykgY29uc3Q7Cit9OworCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLyBBIGNvbnRhaW5lciBmb3IgaW5saW5lIHN0cmluZyB2YWx1ZXMuCisvLy8KKy8vLyBUaGlzIGNsYXNzIGlzIHVzZWQgd2l0aCB0aGUgRFdfRk9STV9zdHJpbmcgZm9ybS4KK2NsYXNzIERJRUlubGluZVN0cmluZyB7CisgIFN0cmluZ1JlZiBTOworCitwdWJsaWM6CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBBbGxvY2F0b3I+CisgIGV4cGxpY2l0IERJRUlubGluZVN0cmluZyhTdHJpbmdSZWYgU3RyLCBBbGxvY2F0b3IgJkEpIDogUyhTdHIuY29weShBKSkge30KKworICB+RElFSW5saW5lU3RyaW5nKCkgPSBkZWZhdWx0OworCisgIC8vLyBHcmFiIHRoZSBzdHJpbmcgb3V0IG9mIHRoZSBvYmplY3QuCisgIFN0cmluZ1JlZiBnZXRTdHJpbmcoKSBjb25zdCB7IHJldHVybiBTOyB9CisKKyAgdm9pZCBFbWl0VmFsdWUoY29uc3QgQXNtUHJpbnRlciAqQVAsIGR3YXJmOjpGb3JtIEZvcm0pIGNvbnN0OworICB1bnNpZ25lZCBTaXplT2YoY29uc3QgQXNtUHJpbnRlciAqQVAsIGR3YXJmOjpGb3JtIEZvcm0pIGNvbnN0OworCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk8pIGNvbnN0OworfTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gQSBwb2ludGVyIHRvIGFub3RoZXIgZGVidWcgaW5mb3JtYXRpb24gZW50cnkuICBBbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzIGNhbgorLy8vIGFsc28gYmUgdXNlZCBhcyBhIHByb3h5IGZvciBhIGRlYnVnIGluZm9ybWF0aW9uIGVudHJ5IG5vdCB5ZXQgZGVmaW5lZAorLy8vIChpZS4gdHlwZXMuKQorY2xhc3MgRElFRW50cnkgeworICBESUUgKkVudHJ5OworCitwdWJsaWM6CisgIERJRUVudHJ5KCkgPSBkZWxldGU7CisgIGV4cGxpY2l0IERJRUVudHJ5KERJRSAmRSkgOiBFbnRyeSgmRSkge30KKworICBESUUgJmdldEVudHJ5KCkgY29uc3QgeyByZXR1cm4gKkVudHJ5OyB9CisKKyAgdm9pZCBFbWl0VmFsdWUoY29uc3QgQXNtUHJpbnRlciAqQVAsIGR3YXJmOjpGb3JtIEZvcm0pIGNvbnN0OworICB1bnNpZ25lZCBTaXplT2YoY29uc3QgQXNtUHJpbnRlciAqQVAsIGR3YXJmOjpGb3JtIEZvcm0pIGNvbnN0OworCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk8pIGNvbnN0OworfTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gUmVwcmVzZW50cyBhIHBvaW50ZXIgdG8gYSBsb2NhdGlvbiBsaXN0IGluIHRoZSBkZWJ1Z19sb2MKKy8vLyBzZWN0aW9uLgorY2xhc3MgRElFTG9jTGlzdCB7CisgIC8vLyBJbmRleCBpbnRvIHRoZSAuZGVidWdfbG9jIHZlY3Rvci4KKyAgc2l6ZV90IEluZGV4OworCitwdWJsaWM6CisgIERJRUxvY0xpc3Qoc2l6ZV90IEkpIDogSW5kZXgoSSkge30KKworICAvLy8gR3JhYiB0aGUgY3VycmVudCBpbmRleCBvdXQuCisgIHNpemVfdCBnZXRWYWx1ZSgpIGNvbnN0IHsgcmV0dXJuIEluZGV4OyB9CisKKyAgdm9pZCBFbWl0VmFsdWUoY29uc3QgQXNtUHJpbnRlciAqQVAsIGR3YXJmOjpGb3JtIEZvcm0pIGNvbnN0OworICB1bnNpZ25lZCBTaXplT2YoY29uc3QgQXNtUHJpbnRlciAqQVAsIGR3YXJmOjpGb3JtIEZvcm0pIGNvbnN0OworCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk8pIGNvbnN0OworfTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gQSBkZWJ1ZyBpbmZvcm1hdGlvbiBlbnRyeSB2YWx1ZS4gU29tZSBvZiB0aGVzZSByb3VnaGx5IGNvcnJlbGF0ZQorLy8vIHRvIERXQVJGIGF0dHJpYnV0ZSBjbGFzc2VzLgorY2xhc3MgRElFQmxvY2s7CitjbGFzcyBESUVMb2M7CitjbGFzcyBESUVWYWx1ZSB7CitwdWJsaWM6CisgIGVudW0gVHlwZSB7CisgICAgaXNOb25lLAorI2RlZmluZSBIQU5ETEVfRElFVkFMVUUoVCkgaXMjI1QsCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0RJRVZhbHVlLmRlZiIKKyAgfTsKKworcHJpdmF0ZToKKyAgLy8vIFR5cGUgb2YgZGF0YSBzdG9yZWQgaW4gdGhlIHZhbHVlLgorICBUeXBlIFR5ID0gaXNOb25lOworICBkd2FyZjo6QXR0cmlidXRlIEF0dHJpYnV0ZSA9IChkd2FyZjo6QXR0cmlidXRlKTA7CisgIGR3YXJmOjpGb3JtIEZvcm0gPSAoZHdhcmY6OkZvcm0pMDsKKworICAvLy8gU3RvcmFnZSBmb3IgdGhlIHZhbHVlLgorICAvLy8KKyAgLy8vIEFsbCB2YWx1ZXMgdGhhdCBhcmVuJ3Qgc3RhbmRhcmQgbGF5b3V0IChvciBhcmUgbGFyZ2VyIHRoYW4gOCBieXRlcykKKyAgLy8vIHNob3VsZCBiZSBzdG9yZWQgYnkgcmVmZXJlbmNlIGluc3RlYWQgb2YgYnkgdmFsdWUuCisgIHVzaW5nIFZhbFR5ID0gQWxpZ25lZENoYXJBcnJheVVuaW9uPERJRUludGVnZXIsIERJRVN0cmluZywgRElFRXhwciwgRElFTGFiZWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERJRURlbHRhICosIERJRUVudHJ5LCBESUVCbG9jayAqLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBESUVMb2MgKiwgRElFTG9jTGlzdD47CisKKyAgc3RhdGljX2Fzc2VydChzaXplb2YoVmFsVHkpIDw9IHNpemVvZih1aW50NjRfdCkgfHwKKyAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKFZhbFR5KSA8PSBzaXplb2Yodm9pZCAqKSwKKyAgICAgICAgICAgICAgICAiRXhwZWN0ZWQgYWxsIGxhcmdlIHR5cGVzIHRvIGJlIHN0b3JlZCB2aWEgcG9pbnRlciIpOworCisgIC8vLyBVbmRlcmx5aW5nIHN0b3JlZCB2YWx1ZS4KKyAgVmFsVHkgVmFsOworCisgIHRlbXBsYXRlIDxjbGFzcyBUPiB2b2lkIGNvbnN0cnVjdChUIFYpIHsKKyAgICBzdGF0aWNfYXNzZXJ0KHN0ZDo6aXNfc3RhbmRhcmRfbGF5b3V0PFQ+Ojp2YWx1ZSB8fAorICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6aXNfcG9pbnRlcjxUPjo6dmFsdWUsCisgICAgICAgICAgICAgICAgICAiRXhwZWN0ZWQgc3RhbmRhcmQgbGF5b3V0IG9yIHBvaW50ZXIiKTsKKyAgICBuZXcgKHJlaW50ZXJwcmV0X2Nhc3Q8dm9pZCAqPihWYWwuYnVmZmVyKSkgVChWKTsKKyAgfQorCisgIHRlbXBsYXRlIDxjbGFzcyBUPiBUICpnZXQoKSB7IHJldHVybiByZWludGVycHJldF9jYXN0PFQgKj4oVmFsLmJ1ZmZlcik7IH0KKyAgdGVtcGxhdGUgPGNsYXNzIFQ+IGNvbnN0IFQgKmdldCgpIGNvbnN0IHsKKyAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBUICo+KFZhbC5idWZmZXIpOworICB9CisgIHRlbXBsYXRlIDxjbGFzcyBUPiB2b2lkIGRlc3RydWN0KCkgeyBnZXQ8VD4oKS0+flQoKTsgfQorCisgIC8vLyBEZXN0cm95IHRoZSB1bmRlcmx5aW5nIHZhbHVlLgorICAvLy8KKyAgLy8vIFRoaXMgc2hvdWxkIGdldCBvcHRpbWl6ZWQgZG93biB0byBhIG5vLW9wLiAgV2UgY291bGQgc2tpcCBpdCBpZiB3ZSBjb3VsZAorICAvLy8gYWRkIGEgc3RhdGljIGFzc2VydCBvbiBcYSBzdGQ6OmlzX3RyaXZpYWxseV9jb3B5YWJsZSgpLCBidXQgd2UgY3VycmVudGx5CisgIC8vLyBzdXBwb3J0IHZlcnNpb25zIG9mIEdDQyB0aGF0IGRvbid0IHVuZGVyc3RhbmQgdGhhdC4KKyAgdm9pZCBkZXN0cm95VmFsKCkgeworICAgIHN3aXRjaCAoVHkpIHsKKyAgICBjYXNlIGlzTm9uZToKKyAgICAgIHJldHVybjsKKyNkZWZpbmUgSEFORExFX0RJRVZBTFVFX1NNQUxMKFQpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNhc2UgaXMjI1Q6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGRlc3RydWN0PERJRSMjVD4oKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm47CisjZGVmaW5lIEhBTkRMRV9ESUVWQUxVRV9MQVJHRShUKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBjYXNlIGlzIyNUOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBkZXN0cnVjdDxjb25zdCBESUUjI1QgKj4oKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuOworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9ESUVWYWx1ZS5kZWYiCisgICAgfQorICB9CisKKyAgLy8vIENvcHkgdGhlIHVuZGVybHlpbmcgdmFsdWUuCisgIC8vLworICAvLy8gVGhpcyBzaG91bGQgZ2V0IG9wdGltaXplZCBkb3duIHRvIGEgc2ltcGxlIGNvcHkuICBXZSBuZWVkIHRvIGFjdHVhbGx5CisgIC8vLyBjb25zdHJ1Y3QgdGhlIHZhbHVlLCByYXRoZXIgdGhhbiBjYWxsaW5nIG1lbWNweSwgdG8gc2F0aXNmeSBzdHJpY3QKKyAgLy8vIGFsaWFzaW5nIHJ1bGVzLgorICB2b2lkIGNvcHlWYWwoY29uc3QgRElFVmFsdWUgJlgpIHsKKyAgICBzd2l0Y2ggKFR5KSB7CisgICAgY2FzZSBpc05vbmU6CisgICAgICByZXR1cm47CisjZGVmaW5lIEhBTkRMRV9ESUVWQUxVRV9TTUFMTChUKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICBjYXNlIGlzIyNUOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBjb25zdHJ1Y3Q8RElFIyNUPigqWC5nZXQ8RElFIyNUPigpKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgcmV0dXJuOworI2RlZmluZSBIQU5ETEVfRElFVkFMVUVfTEFSR0UoVCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgY2FzZSBpcyMjVDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY29uc3RydWN0PGNvbnN0IERJRSMjVCAqPigqWC5nZXQ8Y29uc3QgRElFIyNUICo+KCkpOyAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIHJldHVybjsKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vRElFVmFsdWUuZGVmIgorICAgIH0KKyAgfQorCitwdWJsaWM6CisgIERJRVZhbHVlKCkgPSBkZWZhdWx0OworCisgIERJRVZhbHVlKGNvbnN0IERJRVZhbHVlICZYKSA6IFR5KFguVHkpLCBBdHRyaWJ1dGUoWC5BdHRyaWJ1dGUpLCBGb3JtKFguRm9ybSkgeworICAgIGNvcHlWYWwoWCk7CisgIH0KKworICBESUVWYWx1ZSAmb3BlcmF0b3I9KGNvbnN0IERJRVZhbHVlICZYKSB7CisgICAgZGVzdHJveVZhbCgpOworICAgIFR5ID0gWC5UeTsKKyAgICBBdHRyaWJ1dGUgPSBYLkF0dHJpYnV0ZTsKKyAgICBGb3JtID0gWC5Gb3JtOworICAgIGNvcHlWYWwoWCk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgfkRJRVZhbHVlKCkgeyBkZXN0cm95VmFsKCk7IH0KKworI2RlZmluZSBIQU5ETEVfRElFVkFMVUVfU01BTEwoVCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgRElFVmFsdWUoZHdhcmY6OkF0dHJpYnV0ZSBBdHRyaWJ1dGUsIGR3YXJmOjpGb3JtIEZvcm0sIGNvbnN0IERJRSMjVCAmVikgICAgICBcCisgICAgICA6IFR5KGlzIyNUKSwgQXR0cmlidXRlKEF0dHJpYnV0ZSksIEZvcm0oRm9ybSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGNvbnN0cnVjdDxESUUjI1Q+KFYpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgfQorI2RlZmluZSBIQU5ETEVfRElFVkFMVUVfTEFSR0UoVCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgRElFVmFsdWUoZHdhcmY6OkF0dHJpYnV0ZSBBdHRyaWJ1dGUsIGR3YXJmOjpGb3JtIEZvcm0sIGNvbnN0IERJRSMjVCAqVikgICAgICBcCisgICAgICA6IFR5KGlzIyNUKSwgQXR0cmlidXRlKEF0dHJpYnV0ZSksIEZvcm0oRm9ybSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGFzc2VydChWICYmICJFeHBlY3RlZCB2YWxpZCB2YWx1ZSIpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBjb25zdHJ1Y3Q8Y29uc3QgRElFIyNUICo+KFYpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0KKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vRElFVmFsdWUuZGVmIgorCisgIC8vLyBBY2Nlc3NvcnMuCisgIC8vLyBAeworICBUeXBlIGdldFR5cGUoKSBjb25zdCB7IHJldHVybiBUeTsgfQorICBkd2FyZjo6QXR0cmlidXRlIGdldEF0dHJpYnV0ZSgpIGNvbnN0IHsgcmV0dXJuIEF0dHJpYnV0ZTsgfQorICBkd2FyZjo6Rm9ybSBnZXRGb3JtKCkgY29uc3QgeyByZXR1cm4gRm9ybTsgfQorICBleHBsaWNpdCBvcGVyYXRvciBib29sKCkgY29uc3QgeyByZXR1cm4gVHk7IH0KKyAgLy8vIEB9CisKKyNkZWZpbmUgSEFORExFX0RJRVZBTFVFX1NNQUxMKFQpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNvbnN0IERJRSMjVCAmZ2V0RElFIyNUKCkgY29uc3QgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGFzc2VydChnZXRUeXBlKCkgPT0gaXMjI1QgJiYgIkV4cGVjdGVkICIgI1QpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gKmdldDxESUUjI1Q+KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0KKyNkZWZpbmUgSEFORExFX0RJRVZBTFVFX0xBUkdFKFQpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIGNvbnN0IERJRSMjVCAmZ2V0RElFIyNUKCkgY29uc3QgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGFzc2VydChnZXRUeXBlKCkgPT0gaXMjI1QgJiYgIkV4cGVjdGVkICIgI1QpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICByZXR1cm4gKipnZXQ8Y29uc3QgRElFIyNUICo+KCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgIH0KKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vRElFVmFsdWUuZGVmIgorCisgIC8vLyBFbWl0IHZhbHVlIHZpYSB0aGUgRHdhcmYgd3JpdGVyLgorICB2b2lkIEVtaXRWYWx1ZShjb25zdCBBc21QcmludGVyICpBUCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0aGUgc2l6ZSBvZiBhIHZhbHVlIGluIGJ5dGVzLgorICB1bnNpZ25lZCBTaXplT2YoY29uc3QgQXNtUHJpbnRlciAqQVApIGNvbnN0OworCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk8pIGNvbnN0OworICB2b2lkIGR1bXAoKSBjb25zdDsKK307CisKK3N0cnVjdCBJbnRydXNpdmVCYWNrTGlzdE5vZGUgeworICBQb2ludGVySW50UGFpcjxJbnRydXNpdmVCYWNrTGlzdE5vZGUgKiwgMT4gTmV4dDsKKworICBJbnRydXNpdmVCYWNrTGlzdE5vZGUoKSA6IE5leHQodGhpcywgdHJ1ZSkge30KKworICBJbnRydXNpdmVCYWNrTGlzdE5vZGUgKmdldE5leHQoKSBjb25zdCB7CisgICAgcmV0dXJuIE5leHQuZ2V0SW50KCkgPyBudWxscHRyIDogTmV4dC5nZXRQb2ludGVyKCk7CisgIH0KK307CisKK3N0cnVjdCBJbnRydXNpdmVCYWNrTGlzdEJhc2UgeworICB1c2luZyBOb2RlID0gSW50cnVzaXZlQmFja0xpc3ROb2RlOworCisgIE5vZGUgKkxhc3QgPSBudWxscHRyOworCisgIGJvb2wgZW1wdHkoKSBjb25zdCB7IHJldHVybiAhTGFzdDsgfQorCisgIHZvaWQgcHVzaF9iYWNrKE5vZGUgJk4pIHsKKyAgICBhc3NlcnQoTi5OZXh0LmdldFBvaW50ZXIoKSA9PSAmTiAmJiAiRXhwZWN0ZWQgdW5saW5rZWQgbm9kZSIpOworICAgIGFzc2VydChOLk5leHQuZ2V0SW50KCkgPT0gdHJ1ZSAmJiAiRXhwZWN0ZWQgdW5saW5rZWQgbm9kZSIpOworCisgICAgaWYgKExhc3QpIHsKKyAgICAgIE4uTmV4dCA9IExhc3QtPk5leHQ7CisgICAgICBMYXN0LT5OZXh0LnNldFBvaW50ZXJBbmRJbnQoJk4sIGZhbHNlKTsKKyAgICB9CisgICAgTGFzdCA9ICZOOworICB9Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgVD4gY2xhc3MgSW50cnVzaXZlQmFja0xpc3QgOiBJbnRydXNpdmVCYWNrTGlzdEJhc2UgeworcHVibGljOgorICB1c2luZyBJbnRydXNpdmVCYWNrTGlzdEJhc2U6OmVtcHR5OworCisgIHZvaWQgcHVzaF9iYWNrKFQgJk4pIHsgSW50cnVzaXZlQmFja0xpc3RCYXNlOjpwdXNoX2JhY2soTik7IH0KKyAgVCAmYmFjaygpIHsgcmV0dXJuICpzdGF0aWNfY2FzdDxUICo+KExhc3QpOyB9CisgIGNvbnN0IFQgJmJhY2soKSBjb25zdCB7IHJldHVybiAqc3RhdGljX2Nhc3Q8VCAqPihMYXN0KTsgfQorCisgIGNsYXNzIGNvbnN0X2l0ZXJhdG9yOworICBjbGFzcyBpdGVyYXRvcgorICAgICAgOiBwdWJsaWMgaXRlcmF0b3JfZmFjYWRlX2Jhc2U8aXRlcmF0b3IsIHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsIFQ+IHsKKyAgICBmcmllbmQgY2xhc3MgY29uc3RfaXRlcmF0b3I7CisKKyAgICBOb2RlICpOID0gbnVsbHB0cjsKKworICBwdWJsaWM6CisgICAgaXRlcmF0b3IoKSA9IGRlZmF1bHQ7CisgICAgZXhwbGljaXQgaXRlcmF0b3IoVCAqTikgOiBOKE4pIHt9CisKKyAgICBpdGVyYXRvciAmb3BlcmF0b3IrKygpIHsKKyAgICAgIE4gPSBOLT5nZXROZXh0KCk7CisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorCisgICAgZXhwbGljaXQgb3BlcmF0b3IgYm9vbCgpIGNvbnN0IHsgcmV0dXJuIE47IH0KKyAgICBUICZvcGVyYXRvciooKSBjb25zdCB7IHJldHVybiAqc3RhdGljX2Nhc3Q8VCAqPihOKTsgfQorCisgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IGl0ZXJhdG9yICZYKSBjb25zdCB7IHJldHVybiBOID09IFguTjsgfQorICAgIGJvb2wgb3BlcmF0b3IhPShjb25zdCBpdGVyYXRvciAmWCkgY29uc3QgeyByZXR1cm4gTiAhPSBYLk47IH0KKyAgfTsKKworICBjbGFzcyBjb25zdF9pdGVyYXRvcgorICAgICAgOiBwdWJsaWMgaXRlcmF0b3JfZmFjYWRlX2Jhc2U8Y29uc3RfaXRlcmF0b3IsIHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUPiB7CisgICAgY29uc3QgTm9kZSAqTiA9IG51bGxwdHI7CisKKyAgcHVibGljOgorICAgIGNvbnN0X2l0ZXJhdG9yKCkgPSBkZWZhdWx0OworICAgIC8vIFBsYWNhdGUgTVNWQyBieSBleHBsaWNpdGx5IHNjb3BpbmcgJ2l0ZXJhdG9yJy4KKyAgICBjb25zdF9pdGVyYXRvcih0eXBlbmFtZSBJbnRydXNpdmVCYWNrTGlzdDxUPjo6aXRlcmF0b3IgWCkgOiBOKFguTikge30KKyAgICBleHBsaWNpdCBjb25zdF9pdGVyYXRvcihjb25zdCBUICpOKSA6IE4oTikge30KKworICAgIGNvbnN0X2l0ZXJhdG9yICZvcGVyYXRvcisrKCkgeworICAgICAgTiA9IE4tPmdldE5leHQoKTsKKyAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisKKyAgICBleHBsaWNpdCBvcGVyYXRvciBib29sKCkgY29uc3QgeyByZXR1cm4gTjsgfQorICAgIGNvbnN0IFQgJm9wZXJhdG9yKigpIGNvbnN0IHsgcmV0dXJuICpzdGF0aWNfY2FzdDxjb25zdCBUICo+KE4pOyB9CisKKyAgICBib29sIG9wZXJhdG9yPT0oY29uc3QgY29uc3RfaXRlcmF0b3IgJlgpIGNvbnN0IHsgcmV0dXJuIE4gPT0gWC5OOyB9CisgICAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IGNvbnN0X2l0ZXJhdG9yICZYKSBjb25zdCB7IHJldHVybiBOICE9IFguTjsgfQorICB9OworCisgIGl0ZXJhdG9yIGJlZ2luKCkgeworICAgIHJldHVybiBMYXN0ID8gaXRlcmF0b3Ioc3RhdGljX2Nhc3Q8VCAqPihMYXN0LT5OZXh0LmdldFBvaW50ZXIoKSkpIDogZW5kKCk7CisgIH0KKyAgY29uc3RfaXRlcmF0b3IgYmVnaW4oKSBjb25zdCB7CisgICAgcmV0dXJuIGNvbnN0X2Nhc3Q8SW50cnVzaXZlQmFja0xpc3QgKj4odGhpcyktPmJlZ2luKCk7CisgIH0KKyAgaXRlcmF0b3IgZW5kKCkgeyByZXR1cm4gaXRlcmF0b3IoKTsgfQorICBjb25zdF9pdGVyYXRvciBlbmQoKSBjb25zdCB7IHJldHVybiBjb25zdF9pdGVyYXRvcigpOyB9CisKKyAgc3RhdGljIGl0ZXJhdG9yIHRvSXRlcmF0b3IoVCAmTikgeyByZXR1cm4gaXRlcmF0b3IoJk4pOyB9CisgIHN0YXRpYyBjb25zdF9pdGVyYXRvciB0b0l0ZXJhdG9yKGNvbnN0IFQgJk4pIHsgcmV0dXJuIGNvbnN0X2l0ZXJhdG9yKCZOKTsgfQorfTsKKworLy8vIEEgbGlzdCBvZiBESUUgdmFsdWVzLgorLy8vCisvLy8gVGhpcyBpcyBhIHNpbmdseS1saW5rZWQgbGlzdCwgYnV0IGluc3RlYWQgb2YgcmV2ZXJzaW5nIHRoZSBvcmRlciBvZgorLy8vIGluc2VydGlvbiwgd2Uga2VlcCBhIHBvaW50ZXIgdG8gdGhlIGJhY2sgb2YgdGhlIGxpc3Qgc28gd2UgY2FuIHB1c2ggaW4KKy8vLyBvcmRlci4KKy8vLworLy8vIFRoZXJlIGFyZSB0d28gbWFpbiByZWFzb25zIHRvIGNob29zZSBhIGxpbmtlZCBsaXN0IG92ZXIgYSBjdXN0b21pemVkCisvLy8gdmVjdG9yLWxpa2UgZGF0YSBzdHJ1Y3R1cmUuCisvLy8KKy8vLyAgMS4gRm9yIHRlYXJkb3duIGVmZmljaWVuY3ksIHdlIHdhbnQgRElFcyB0byBiZSBCdW1wUHRyQWxsb2NhdGVkLiAgVXNpbmcgYQorLy8vICAgICBsaW5rZWQgbGlzdCBoZXJlIG1ha2VzIHRoaXMgd2F5IGVhc2llciB0byBhY2NvbXBsaXNoLgorLy8vICAyLiBDYXJyeWluZyBhbiBleHRyYSBwb2ludGVyIHBlciBcYSBESUVWYWx1ZSBpc24ndCBleHBlbnNpdmUuICA0NSUgb2YgRElFcworLy8vICAgICBoYXZlIDIgb3IgZmV3ZXIgdmFsdWVzLCBhbmQgOTAlIGhhdmUgNSBvciBmZXdlci4gIEEgdmVjdG9yIHdvdWxkIGJlCisvLy8gICAgIG92ZXItYWxsb2NhdGVkIGJ5IDUwJSBvbiBhdmVyYWdlIGFueXdheSwgdGhlIHNhbWUgY29zdCBhcyB0aGUKKy8vLyAgICAgbGlua2VkLWxpc3Qgbm9kZS4KK2NsYXNzIERJRVZhbHVlTGlzdCB7CisgIHN0cnVjdCBOb2RlIDogSW50cnVzaXZlQmFja0xpc3ROb2RlIHsKKyAgICBESUVWYWx1ZSBWOworCisgICAgZXhwbGljaXQgTm9kZShESUVWYWx1ZSBWKSA6IFYoVikge30KKyAgfTsKKworICB1c2luZyBMaXN0VHkgPSBJbnRydXNpdmVCYWNrTGlzdDxOb2RlPjsKKworICBMaXN0VHkgTGlzdDsKKworcHVibGljOgorICBjbGFzcyBjb25zdF92YWx1ZV9pdGVyYXRvcjsKKyAgY2xhc3MgdmFsdWVfaXRlcmF0b3IKKyAgICAgIDogcHVibGljIGl0ZXJhdG9yX2FkYXB0b3JfYmFzZTx2YWx1ZV9pdGVyYXRvciwgTGlzdFR5OjppdGVyYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OmZvcndhcmRfaXRlcmF0b3JfdGFnLCBESUVWYWx1ZT4geworICAgIGZyaWVuZCBjbGFzcyBjb25zdF92YWx1ZV9pdGVyYXRvcjsKKworICAgIHVzaW5nIGl0ZXJhdG9yX2FkYXB0b3IgPQorICAgICAgICBpdGVyYXRvcl9hZGFwdG9yX2Jhc2U8dmFsdWVfaXRlcmF0b3IsIExpc3RUeTo6aXRlcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OmZvcndhcmRfaXRlcmF0b3JfdGFnLCBESUVWYWx1ZT47CisKKyAgcHVibGljOgorICAgIHZhbHVlX2l0ZXJhdG9yKCkgPSBkZWZhdWx0OworICAgIGV4cGxpY2l0IHZhbHVlX2l0ZXJhdG9yKExpc3RUeTo6aXRlcmF0b3IgWCkgOiBpdGVyYXRvcl9hZGFwdG9yKFgpIHt9CisKKyAgICBleHBsaWNpdCBvcGVyYXRvciBib29sKCkgY29uc3QgeyByZXR1cm4gYm9vbCh3cmFwcGVkKCkpOyB9CisgICAgRElFVmFsdWUgJm9wZXJhdG9yKigpIGNvbnN0IHsgcmV0dXJuIHdyYXBwZWQoKS0+VjsgfQorICB9OworCisgIGNsYXNzIGNvbnN0X3ZhbHVlX2l0ZXJhdG9yIDogcHVibGljIGl0ZXJhdG9yX2FkYXB0b3JfYmFzZTwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RfdmFsdWVfaXRlcmF0b3IsIExpc3RUeTo6Y29uc3RfaXRlcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsIGNvbnN0IERJRVZhbHVlPiB7CisgICAgdXNpbmcgaXRlcmF0b3JfYWRhcHRvciA9CisgICAgICAgIGl0ZXJhdG9yX2FkYXB0b3JfYmFzZTxjb25zdF92YWx1ZV9pdGVyYXRvciwgTGlzdFR5Ojpjb25zdF9pdGVyYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsIGNvbnN0IERJRVZhbHVlPjsKKworICBwdWJsaWM6CisgICAgY29uc3RfdmFsdWVfaXRlcmF0b3IoKSA9IGRlZmF1bHQ7CisgICAgY29uc3RfdmFsdWVfaXRlcmF0b3IoRElFVmFsdWVMaXN0Ojp2YWx1ZV9pdGVyYXRvciBYKQorICAgICAgICA6IGl0ZXJhdG9yX2FkYXB0b3IoWC53cmFwcGVkKCkpIHt9CisgICAgZXhwbGljaXQgY29uc3RfdmFsdWVfaXRlcmF0b3IoTGlzdFR5Ojpjb25zdF9pdGVyYXRvciBYKQorICAgICAgICA6IGl0ZXJhdG9yX2FkYXB0b3IoWCkge30KKworICAgIGV4cGxpY2l0IG9wZXJhdG9yIGJvb2woKSBjb25zdCB7IHJldHVybiBib29sKHdyYXBwZWQoKSk7IH0KKyAgICBjb25zdCBESUVWYWx1ZSAmb3BlcmF0b3IqKCkgY29uc3QgeyByZXR1cm4gd3JhcHBlZCgpLT5WOyB9CisgIH07CisKKyAgdXNpbmcgdmFsdWVfcmFuZ2UgPSBpdGVyYXRvcl9yYW5nZTx2YWx1ZV9pdGVyYXRvcj47CisgIHVzaW5nIGNvbnN0X3ZhbHVlX3JhbmdlID0gaXRlcmF0b3JfcmFuZ2U8Y29uc3RfdmFsdWVfaXRlcmF0b3I+OworCisgIHZhbHVlX2l0ZXJhdG9yIGFkZFZhbHVlKEJ1bXBQdHJBbGxvY2F0b3IgJkFsbG9jLCBjb25zdCBESUVWYWx1ZSAmVikgeworICAgIExpc3QucHVzaF9iYWNrKCpuZXcgKEFsbG9jKSBOb2RlKFYpKTsKKyAgICByZXR1cm4gdmFsdWVfaXRlcmF0b3IoTGlzdFR5Ojp0b0l0ZXJhdG9yKExpc3QuYmFjaygpKSk7CisgIH0KKyAgdGVtcGxhdGUgPGNsYXNzIFQ+CisgIHZhbHVlX2l0ZXJhdG9yIGFkZFZhbHVlKEJ1bXBQdHJBbGxvY2F0b3IgJkFsbG9jLCBkd2FyZjo6QXR0cmlidXRlIEF0dHJpYnV0ZSwKKyAgICAgICAgICAgICAgICAgICAgZHdhcmY6OkZvcm0gRm9ybSwgVCAmJlZhbHVlKSB7CisgICAgcmV0dXJuIGFkZFZhbHVlKEFsbG9jLCBESUVWYWx1ZShBdHRyaWJ1dGUsIEZvcm0sIHN0ZDo6Zm9yd2FyZDxUPihWYWx1ZSkpKTsKKyAgfQorCisgIHZhbHVlX3JhbmdlIHZhbHVlcygpIHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZSh2YWx1ZV9pdGVyYXRvcihMaXN0LmJlZ2luKCkpLCB2YWx1ZV9pdGVyYXRvcihMaXN0LmVuZCgpKSk7CisgIH0KKyAgY29uc3RfdmFsdWVfcmFuZ2UgdmFsdWVzKCkgY29uc3QgeworICAgIHJldHVybiBtYWtlX3JhbmdlKGNvbnN0X3ZhbHVlX2l0ZXJhdG9yKExpc3QuYmVnaW4oKSksCisgICAgICAgICAgICAgICAgICAgICAgY29uc3RfdmFsdWVfaXRlcmF0b3IoTGlzdC5lbmQoKSkpOworICB9Cit9OworCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLyBBIHN0cnVjdHVyZWQgZGVidWcgaW5mb3JtYXRpb24gZW50cnkuICBIYXMgYW4gYWJicmV2aWF0aW9uIHdoaWNoCisvLy8gZGVzY3JpYmVzIGl0cyBvcmdhbml6YXRpb24uCitjbGFzcyBESUUgOiBJbnRydXNpdmVCYWNrTGlzdE5vZGUsIHB1YmxpYyBESUVWYWx1ZUxpc3QgeworICBmcmllbmQgY2xhc3MgSW50cnVzaXZlQmFja0xpc3Q8RElFPjsKKyAgZnJpZW5kIGNsYXNzIERJRVVuaXQ7CisKKyAgLy8vIER3YXJmIHVuaXQgcmVsYXRpdmUgb2Zmc2V0LgorICB1bnNpZ25lZCBPZmZzZXQgPSAwOworICAvLy8gU2l6ZSBvZiBpbnN0YW5jZSArIGNoaWxkcmVuLgorICB1bnNpZ25lZCBTaXplID0gMDsKKyAgdW5zaWduZWQgQWJicmV2TnVtYmVyID0gfjB1OworICAvLy8gRHdhcmYgdGFnIGNvZGUuCisgIGR3YXJmOjpUYWcgVGFnID0gKGR3YXJmOjpUYWcpMDsKKyAgLy8vIFNldCB0byB0cnVlIHRvIGZvcmNlIGEgRElFIHRvIGVtaXQgYW4gYWJicmV2aWF0aW9uIHRoYXQgc2F5cyBpdCBoYXMKKyAgLy8vIGNoaWxkcmVuIGV2ZW4gd2hlbiBpdCBkb2Vzbid0LiBUaGlzIGlzIHVzZWQgZm9yIHVuaXQgdGVzdGluZyBwdXJwb3Nlcy4KKyAgYm9vbCBGb3JjZUNoaWxkcmVuID0gZmFsc2U7CisgIC8vLyBDaGlsZHJlbiBESUVzLgorICBJbnRydXNpdmVCYWNrTGlzdDxESUU+IENoaWxkcmVuOworCisgIC8vLyBUaGUgb3duZXIgaXMgZWl0aGVyIHRoZSBwYXJlbnQgRElFIGZvciBjaGlsZHJlbiBvZiBvdGhlciBESUVzLCBvciBhCisgIC8vLyBESUVVbml0IHdoaWNoIGNvbnRhaW5zIHRoaXMgRElFIGFzIGl0cyB1bml0IERJRS4KKyAgUG9pbnRlclVuaW9uPERJRSAqLCBESUVVbml0ICo+IE93bmVyOworCisgIGV4cGxpY2l0IERJRShkd2FyZjo6VGFnIFRhZykgOiBUYWcoVGFnKSB7fQorCitwdWJsaWM6CisgIERJRSgpID0gZGVsZXRlOworICBESUUoY29uc3QgRElFICZSSFMpID0gZGVsZXRlOworICBESUUoRElFICYmUkhTKSA9IGRlbGV0ZTsKKyAgRElFICZvcGVyYXRvcj0oY29uc3QgRElFICZSSFMpID0gZGVsZXRlOworICBESUUgJm9wZXJhdG9yPShjb25zdCBESUUgJiZSSFMpID0gZGVsZXRlOworCisgIHN0YXRpYyBESUUgKmdldChCdW1wUHRyQWxsb2NhdG9yICZBbGxvYywgZHdhcmY6OlRhZyBUYWcpIHsKKyAgICByZXR1cm4gbmV3IChBbGxvYykgRElFKFRhZyk7CisgIH0KKworICAvLyBBY2Nlc3NvcnMuCisgIHVuc2lnbmVkIGdldEFiYnJldk51bWJlcigpIGNvbnN0IHsgcmV0dXJuIEFiYnJldk51bWJlcjsgfQorICBkd2FyZjo6VGFnIGdldFRhZygpIGNvbnN0IHsgcmV0dXJuIFRhZzsgfQorICAvLy8gR2V0IHRoZSBjb21waWxlL3R5cGUgdW5pdCByZWxhdGl2ZSBvZmZzZXQgb2YgdGhpcyBESUUuCisgIHVuc2lnbmVkIGdldE9mZnNldCgpIGNvbnN0IHsgcmV0dXJuIE9mZnNldDsgfQorICB1bnNpZ25lZCBnZXRTaXplKCkgY29uc3QgeyByZXR1cm4gU2l6ZTsgfQorICBib29sIGhhc0NoaWxkcmVuKCkgY29uc3QgeyByZXR1cm4gRm9yY2VDaGlsZHJlbiB8fCAhQ2hpbGRyZW4uZW1wdHkoKTsgfQorICB2b2lkIHNldEZvcmNlQ2hpbGRyZW4oYm9vbCBCKSB7IEZvcmNlQ2hpbGRyZW4gPSBCOyB9CisKKyAgdXNpbmcgY2hpbGRfaXRlcmF0b3IgPSBJbnRydXNpdmVCYWNrTGlzdDxESUU+OjppdGVyYXRvcjsKKyAgdXNpbmcgY29uc3RfY2hpbGRfaXRlcmF0b3IgPSBJbnRydXNpdmVCYWNrTGlzdDxESUU+Ojpjb25zdF9pdGVyYXRvcjsKKyAgdXNpbmcgY2hpbGRfcmFuZ2UgPSBpdGVyYXRvcl9yYW5nZTxjaGlsZF9pdGVyYXRvcj47CisgIHVzaW5nIGNvbnN0X2NoaWxkX3JhbmdlID0gaXRlcmF0b3JfcmFuZ2U8Y29uc3RfY2hpbGRfaXRlcmF0b3I+OworCisgIGNoaWxkX3JhbmdlIGNoaWxkcmVuKCkgeworICAgIHJldHVybiBtYWtlX3JhbmdlKENoaWxkcmVuLmJlZ2luKCksIENoaWxkcmVuLmVuZCgpKTsKKyAgfQorICBjb25zdF9jaGlsZF9yYW5nZSBjaGlsZHJlbigpIGNvbnN0IHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZShDaGlsZHJlbi5iZWdpbigpLCBDaGlsZHJlbi5lbmQoKSk7CisgIH0KKworICBESUUgKmdldFBhcmVudCgpIGNvbnN0OworCisgIC8vLyBHZW5lcmF0ZSB0aGUgYWJicmV2aWF0aW9uIGZvciB0aGlzIERJRS4KKyAgLy8vCisgIC8vLyBDYWxjdWxhdGUgdGhlIGFiYnJldmlhdGlvbiBmb3IgdGhpcywgd2hpY2ggc2hvdWxkIGJlIHVuaXF1ZWQgYW5kCisgIC8vLyBldmVudHVhbGx5IHVzZWQgdG8gY2FsbCBcYSBzZXRBYmJyZXZOdW1iZXIoKS4KKyAgRElFQWJicmV2IGdlbmVyYXRlQWJicmV2KCkgY29uc3Q7CisKKyAgLy8vIFNldCB0aGUgYWJicmV2aWF0aW9uIG51bWJlciBmb3IgdGhpcyBESUUuCisgIHZvaWQgc2V0QWJicmV2TnVtYmVyKHVuc2lnbmVkIEkpIHsgQWJicmV2TnVtYmVyID0gSTsgfQorCisgIC8vLyBHZXQgdGhlIGFic29sdXRlIG9mZnNldCB3aXRoaW4gdGhlIC5kZWJ1Z19pbmZvIG9yIC5kZWJ1Z190eXBlcyBzZWN0aW9uCisgIC8vLyBmb3IgdGhpcyBESUUuCisgIHVuc2lnbmVkIGdldERlYnVnU2VjdGlvbk9mZnNldCgpIGNvbnN0OworCisgIC8vLyBDb21wdXRlIHRoZSBvZmZzZXQgb2YgdGhpcyBESUUgYW5kIGFsbCBpdHMgY2hpbGRyZW4uCisgIC8vLworICAvLy8gVGhpcyBmdW5jdGlvbiBnZXRzIGNhbGxlZCBqdXN0IGJlZm9yZSB3ZSBhcmUgZ29pbmcgdG8gZ2VuZXJhdGUgdGhlIGRlYnVnCisgIC8vLyBpbmZvcm1hdGlvbiBhbmQgZ2l2ZXMgZWFjaCBESUUgYSBjaGFuY2UgdG8gZmlndXJlIG91dCBpdHMgQ1UgcmVsYXRpdmUgRElFCisgIC8vLyBvZmZzZXQsIHVuaXF1ZSBpdHMgYWJicmV2aWF0aW9uIGFuZCBmaWxsIGluIHRoZSBhYmJyZXZpYXRpb24gY29kZSwgYW5kCisgIC8vLyByZXR1cm4gdGhlIHVuaXQgb2Zmc2V0IHRoYXQgcG9pbnRzIHRvIHdoZXJlIHRoZSBuZXh0IERJRSB3aWxsIGJlIGVtaXR0ZWQKKyAgLy8vIHdpdGhpbiB0aGUgZGVidWcgdW5pdCBzZWN0aW9uLiBBZnRlciB0aGlzIGZ1bmN0aW9uIGhhcyBiZWVuIGNhbGxlZCBmb3IgYWxsCisgIC8vLyBESUUgb2JqZWN0cywgdGhlIERXQVJGIGNhbiBiZSBnZW5lcmF0ZWQgc2luY2UgYWxsIERJRXMgd2lsbCBiZSBhYmxlIHRvCisgIC8vLyBwcm9wZXJseSByZWZlciB0byBvdGhlciBESUUgb2JqZWN0cyBzaW5jZSBhbGwgRElFcyBoYXZlIGNhbGN1bGF0ZWQgdGhlaXIKKyAgLy8vIG9mZnNldHMuCisgIC8vLworICAvLy8gXHBhcmFtIEFQIEFzbVByaW50ZXIgdG8gdXNlIHdoZW4gY2FsY3VsYXRpbmcgc2l6ZXMuCisgIC8vLyBccGFyYW0gQWJicmV2U2V0IHRoZSBhYmJyZXZpYXRpb24gdXNlZCB0byB1bmlxdWUgRElFIGFiYnJldmlhdGlvbnMuCisgIC8vLyBccGFyYW0gQ1VPZmZzZXQgdGhlIGNvbXBpbGUvdHlwZSB1bml0IHJlbGF0aXZlIG9mZnNldCBpbiBieXRlcy4KKyAgLy8vIFxyZXR1cm5zIHRoZSBvZmZzZXQgZm9yIHRoZSBESUUgdGhhdCBmb2xsb3dzIHRoaXMgRElFIHdpdGhpbiB0aGUKKyAgLy8vIGN1cnJlbnQgY29tcGlsZS90eXBlIHVuaXQuCisgIHVuc2lnbmVkIGNvbXB1dGVPZmZzZXRzQW5kQWJicmV2cyhjb25zdCBBc21QcmludGVyICpBUCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERJRUFiYnJldlNldCAmQWJicmV2U2V0LCB1bnNpZ25lZCBDVU9mZnNldCk7CisKKyAgLy8vIENsaW1iIHVwIHRoZSBwYXJlbnQgY2hhaW4gdG8gZ2V0IHRoZSBjb21waWxlIHVuaXQgb3IgdHlwZSB1bml0IERJRSB0aGF0CisgIC8vLyB0aGlzIERJRSBiZWxvbmdzIHRvLgorICAvLy8KKyAgLy8vIFxyZXR1cm5zIHRoZSBjb21waWxlIG9yIHR5cGUgdW5pdCBESUUgdGhhdCBvd25zIHRoaXMgRElFLCBvciBOVUxMIGlmCisgIC8vLyB0aGlzIERJRSBoYXNuJ3QgYmVlbiBhZGRlZCB0byBhIHVuaXQgRElFLgorICBjb25zdCBESUUgKmdldFVuaXREaWUoKSBjb25zdDsKKworICAvLy8gQ2xpbWIgdXAgdGhlIHBhcmVudCBjaGFpbiB0byBnZXQgdGhlIGNvbXBpbGUgdW5pdCBvciB0eXBlIHVuaXQgdGhhdCB0aGlzCisgIC8vLyBESUUgYmVsb25ncyB0by4KKyAgLy8vCisgIC8vLyBccmV0dXJucyB0aGUgRElFVW5pdCB0aGF0IHJlcHJlc2VudHMgdGhlIGNvbXBpbGUgb3IgdHlwZSB1bml0IHRoYXQgb3ducworICAvLy8gdGhpcyBESUUsIG9yIE5VTEwgaWYgdGhpcyBESUUgaGFzbid0IGJlZW4gYWRkZWQgdG8gYSB1bml0IERJRS4KKyAgY29uc3QgRElFVW5pdCAqZ2V0VW5pdCgpIGNvbnN0OworCisgIHZvaWQgc2V0T2Zmc2V0KHVuc2lnbmVkIE8pIHsgT2Zmc2V0ID0gTzsgfQorICB2b2lkIHNldFNpemUodW5zaWduZWQgUykgeyBTaXplID0gUzsgfQorCisgIC8vLyBBZGQgYSBjaGlsZCB0byB0aGUgRElFLgorICBESUUgJmFkZENoaWxkKERJRSAqQ2hpbGQpIHsKKyAgICBhc3NlcnQoIUNoaWxkLT5nZXRQYXJlbnQoKSAmJiAiQ2hpbGQgc2hvdWxkIGJlIG9ycGhhbmVkIik7CisgICAgQ2hpbGQtPk93bmVyID0gdGhpczsKKyAgICBDaGlsZHJlbi5wdXNoX2JhY2soKkNoaWxkKTsKKyAgICByZXR1cm4gQ2hpbGRyZW4uYmFjaygpOworICB9CisKKyAgLy8vIEZpbmQgYSB2YWx1ZSBpbiB0aGUgRElFIHdpdGggdGhlIGF0dHJpYnV0ZSBnaXZlbi4KKyAgLy8vCisgIC8vLyBSZXR1cm5zIGEgZGVmYXVsdC1jb25zdHJ1Y3RlZCBESUVWYWx1ZSAod2hlcmUgXGEgRElFVmFsdWU6OmdldFR5cGUoKQorICAvLy8gZ2l2ZXMgXGEgRElFVmFsdWU6OmlzTm9uZSkgaWYgbm8gc3VjaCBhdHRyaWJ1dGUgZXhpc3RzLgorICBESUVWYWx1ZSBmaW5kQXR0cmlidXRlKGR3YXJmOjpBdHRyaWJ1dGUgQXR0cmlidXRlKSBjb25zdDsKKworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPLCB1bnNpZ25lZCBJbmRlbnRDb3VudCA9IDApIGNvbnN0OworICB2b2lkIGR1bXAoKSBjb25zdDsKK307CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vIFJlcHJlc2VudHMgYSBjb21waWxlIG9yIHR5cGUgdW5pdC4KK2NsYXNzIERJRVVuaXQgeworICAvLy8gVGhlIGNvbXBpbGUgdW5pdCBvciB0eXBlIHVuaXQgRElFLiBUaGlzIHZhcmlhYmxlIG11c3QgYmUgYW4gaW5zdGFuY2Ugb2YKKyAgLy8vIERJRSBzbyB0aGF0IHdlIGNhbiBjYWxjdWxhdGUgdGhlIERJRVVuaXQgZnJvbSBhbnkgRElFIGJ5IHRyYXZlcnNpbmcgdGhlCisgIC8vLyBwYXJlbnQgYmFja2NoYWluIGFuZCBnZXR0aW5nIHRoZSBVbml0IERJRSwgYW5kIHRoZW4gY2FzdGluZyBpdHNlbGYgdG8gYQorICAvLy8gRElFVW5pdC4gVGhpcyBhbGxvd3MgdXMgdG8gYmUgYWJsZSB0byBmaW5kIHRoZSBESUVVbml0IGZvciBhbnkgRElFIHdpdGhvdXQKKyAgLy8vIGhhdmluZyB0byBzdG9yZSBhIHBvaW50ZXIgdG8gdGhlIERJRVVuaXQgaW4gZWFjaCBESUUgaW5zdGFuY2UuCisgIERJRSBEaWU7CisgIC8vLyBUaGUgc2VjdGlvbiB0aGlzIHVuaXQgd2lsbCBiZSBlbWl0dGVkIGluLiBUaGlzIG1heSBvciBtYXkgbm90IGJlIHNldCB0bworICAvLy8gYSB2YWxpZCBzZWN0aW9uIGRlcGVuZGluZyBvbiB0aGUgY2xpZW50IHRoYXQgaXMgZW1pdHRpbmcgRFdBUkYuCisgIE1DU2VjdGlvbiAqU2VjdGlvbjsKKyAgdWludDY0X3QgT2Zmc2V0OyAvLy8gLmRlYnVnX2luZm8gb3IgLmRlYnVnX3R5cGVzIGFic29sdXRlIHNlY3Rpb24gb2Zmc2V0LgorICB1aW50MzJfdCBMZW5ndGg7IC8vLyBUaGUgbGVuZ3RoIGluIGJ5dGVzIG9mIGFsbCBvZiB0aGUgRElFcyBpbiB0aGlzIHVuaXQuCisgIGNvbnN0IHVpbnQxNl90IFZlcnNpb247IC8vLyBUaGUgRHdhcmYgdmVyc2lvbiBudW1iZXIgZm9yIHRoaXMgdW5pdC4KKyAgY29uc3QgdWludDhfdCBBZGRyU2l6ZTsgLy8vIFRoZSBzaXplIGluIGJ5dGVzIG9mIGFuIGFkZHJlc3MgZm9yIHRoaXMgdW5pdC4KK3Byb3RlY3RlZDoKKyAgfkRJRVVuaXQoKSA9IGRlZmF1bHQ7CisKK3B1YmxpYzoKKyAgRElFVW5pdCh1aW50MTZfdCBWZXJzaW9uLCB1aW50OF90IEFkZHJTaXplLCBkd2FyZjo6VGFnIFVuaXRUYWcpOworICBESUVVbml0KGNvbnN0IERJRVVuaXQgJlJIUykgPSBkZWxldGU7CisgIERJRVVuaXQoRElFVW5pdCAmJlJIUykgPSBkZWxldGU7CisgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IERJRVVuaXQgJlJIUykgPSBkZWxldGU7CisgIHZvaWQgb3BlcmF0b3I9KGNvbnN0IERJRVVuaXQgJiZSSFMpID0gZGVsZXRlOworICAvLy8gU2V0IHRoZSBzZWN0aW9uIHRoYXQgdGhpcyBESUVVbml0IHdpbGwgYmUgZW1pdHRlZCBpbnRvLgorICAvLy8KKyAgLy8vIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBieSBzb21lIGNsaWVudHMgdG8gc2V0IHRoZSBzZWN0aW9uLiBOb3QgYWxsIGNsaWVudHMKKyAgLy8vIHRoYXQgZW1pdCBEV0FSRiB1c2UgdGhpcyBzZWN0aW9uIHZhcmlhYmxlLgorICB2b2lkIHNldFNlY3Rpb24oTUNTZWN0aW9uICpTZWN0aW9uKSB7CisgICAgYXNzZXJ0KCF0aGlzLT5TZWN0aW9uKTsKKyAgICB0aGlzLT5TZWN0aW9uID0gU2VjdGlvbjsKKyAgfQorCisgIHZpcnR1YWwgY29uc3QgTUNTeW1ib2wgKmdldENyb3NzU2VjdGlvblJlbGF0aXZlQmFzZUFkZHJlc3MoKSBjb25zdCB7CisgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBzZWN0aW9uIHRoYXQgdGhpcyBESUVVbml0IHdpbGwgYmUgZW1pdHRlZCBpbnRvLgorICAvLy8KKyAgLy8vIFxyZXR1cm5zIFNlY3Rpb24gcG9pbnRlciB3aGljaCBjYW4gYmUgTlVMTC4KKyAgTUNTZWN0aW9uICpnZXRTZWN0aW9uKCkgY29uc3QgeyByZXR1cm4gU2VjdGlvbjsgfQorICB2b2lkIHNldERlYnVnU2VjdGlvbk9mZnNldCh1bnNpZ25lZCBPKSB7IE9mZnNldCA9IE87IH0KKyAgdW5zaWduZWQgZ2V0RGVidWdTZWN0aW9uT2Zmc2V0KCkgY29uc3QgeyByZXR1cm4gT2Zmc2V0OyB9CisgIHZvaWQgc2V0TGVuZ3RoKHVpbnQ2NF90IEwpIHsgTGVuZ3RoID0gTDsgfQorICB1aW50NjRfdCBnZXRMZW5ndGgoKSBjb25zdCB7IHJldHVybiBMZW5ndGg7IH0KKyAgdWludDE2X3QgZ2V0RHdhcmZWZXJzaW9uKCkgY29uc3QgeyByZXR1cm4gVmVyc2lvbjsgfQorICB1aW50MTZfdCBnZXRBZGRyZXNzU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIEFkZHJTaXplOyB9CisgIERJRSAmZ2V0VW5pdERpZSgpIHsgcmV0dXJuIERpZTsgfQorICBjb25zdCBESUUgJmdldFVuaXREaWUoKSBjb25zdCB7IHJldHVybiBEaWU7IH0KK307CisKK3N0cnVjdCBCYXNpY0RJRVVuaXQgZmluYWwgOiBESUVVbml0IHsKKyAgQmFzaWNESUVVbml0KHVpbnQxNl90IFZlcnNpb24sIHVpbnQ4X3QgQWRkclNpemUsIGR3YXJmOjpUYWcgVW5pdFRhZykKKyAgICAgIDogRElFVW5pdChWZXJzaW9uLCBBZGRyU2l6ZSwgVW5pdFRhZykge30KK307CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vIERJRUxvYyAtIFJlcHJlc2VudHMgYW4gZXhwcmVzc2lvbiBsb2NhdGlvbi4KKy8vCitjbGFzcyBESUVMb2MgOiBwdWJsaWMgRElFVmFsdWVMaXN0IHsKKyAgbXV0YWJsZSB1bnNpZ25lZCBTaXplID0gMDsgLy8gU2l6ZSBpbiBieXRlcyBleGNsdWRpbmcgc2l6ZSBoZWFkZXIuCisKK3B1YmxpYzoKKyAgRElFTG9jKCkgPSBkZWZhdWx0OworCisgIC8vLyBDb21wdXRlU2l6ZSAtIENhbGN1bGF0ZSB0aGUgc2l6ZSBvZiB0aGUgbG9jYXRpb24gZXhwcmVzc2lvbi4KKyAgLy8vCisgIHVuc2lnbmVkIENvbXB1dGVTaXplKGNvbnN0IEFzbVByaW50ZXIgKkFQKSBjb25zdDsKKworICAvLy8gQmVzdEZvcm0gLSBDaG9vc2UgdGhlIGJlc3QgZm9ybSBmb3IgZGF0YS4KKyAgLy8vCisgIGR3YXJmOjpGb3JtIEJlc3RGb3JtKHVuc2lnbmVkIER3YXJmVmVyc2lvbikgY29uc3QgeworICAgIGlmIChEd2FyZlZlcnNpb24gPiAzKQorICAgICAgcmV0dXJuIGR3YXJmOjpEV19GT1JNX2V4cHJsb2M7CisgICAgLy8gUHJlLURXQVJGNCBsb2NhdGlvbiBleHByZXNzaW9ucyB3ZXJlIGJsb2NrcyBhbmQgbm90IGV4cHJsb2MuCisgICAgaWYgKCh1bnNpZ25lZCBjaGFyKVNpemUgPT0gU2l6ZSkKKyAgICAgIHJldHVybiBkd2FyZjo6RFdfRk9STV9ibG9jazE7CisgICAgaWYgKCh1bnNpZ25lZCBzaG9ydClTaXplID09IFNpemUpCisgICAgICByZXR1cm4gZHdhcmY6OkRXX0ZPUk1fYmxvY2syOworICAgIGlmICgodW5zaWduZWQgaW50KVNpemUgPT0gU2l6ZSkKKyAgICAgIHJldHVybiBkd2FyZjo6RFdfRk9STV9ibG9jazQ7CisgICAgcmV0dXJuIGR3YXJmOjpEV19GT1JNX2Jsb2NrOworICB9CisKKyAgdm9pZCBFbWl0VmFsdWUoY29uc3QgQXNtUHJpbnRlciAqQVAsIGR3YXJmOjpGb3JtIEZvcm0pIGNvbnN0OworICB1bnNpZ25lZCBTaXplT2YoY29uc3QgQXNtUHJpbnRlciAqQVAsIGR3YXJmOjpGb3JtIEZvcm0pIGNvbnN0OworCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk8pIGNvbnN0OworfTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gRElFQmxvY2sgLSBSZXByZXNlbnRzIGEgYmxvY2sgb2YgdmFsdWVzLgorLy8KK2NsYXNzIERJRUJsb2NrIDogcHVibGljIERJRVZhbHVlTGlzdCB7CisgIG11dGFibGUgdW5zaWduZWQgU2l6ZSA9IDA7IC8vIFNpemUgaW4gYnl0ZXMgZXhjbHVkaW5nIHNpemUgaGVhZGVyLgorCitwdWJsaWM6CisgIERJRUJsb2NrKCkgPSBkZWZhdWx0OworCisgIC8vLyBDb21wdXRlU2l6ZSAtIENhbGN1bGF0ZSB0aGUgc2l6ZSBvZiB0aGUgbG9jYXRpb24gZXhwcmVzc2lvbi4KKyAgLy8vCisgIHVuc2lnbmVkIENvbXB1dGVTaXplKGNvbnN0IEFzbVByaW50ZXIgKkFQKSBjb25zdDsKKworICAvLy8gQmVzdEZvcm0gLSBDaG9vc2UgdGhlIGJlc3QgZm9ybSBmb3IgZGF0YS4KKyAgLy8vCisgIGR3YXJmOjpGb3JtIEJlc3RGb3JtKCkgY29uc3QgeworICAgIGlmICgodW5zaWduZWQgY2hhcilTaXplID09IFNpemUpCisgICAgICByZXR1cm4gZHdhcmY6OkRXX0ZPUk1fYmxvY2sxOworICAgIGlmICgodW5zaWduZWQgc2hvcnQpU2l6ZSA9PSBTaXplKQorICAgICAgcmV0dXJuIGR3YXJmOjpEV19GT1JNX2Jsb2NrMjsKKyAgICBpZiAoKHVuc2lnbmVkIGludClTaXplID09IFNpemUpCisgICAgICByZXR1cm4gZHdhcmY6OkRXX0ZPUk1fYmxvY2s0OworICAgIHJldHVybiBkd2FyZjo6RFdfRk9STV9ibG9jazsKKyAgfQorCisgIHZvaWQgRW1pdFZhbHVlKGNvbnN0IEFzbVByaW50ZXIgKkFQLCBkd2FyZjo6Rm9ybSBGb3JtKSBjb25zdDsKKyAgdW5zaWduZWQgU2l6ZU9mKGNvbnN0IEFzbVByaW50ZXIgKkFQLCBkd2FyZjo6Rm9ybSBGb3JtKSBjb25zdDsKKworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPKSBjb25zdDsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0xJQl9DT0RFR0VOX0FTTVBSSU5URVJfRElFX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9ESUVWYWx1ZS5kZWYgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vRElFVmFsdWUuZGVmCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmEzZmNlOWIKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vRElFVmFsdWUuZGVmCkBAIC0wLDAgKzEsNDcgQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vRElFVmFsdWUuZGVmIC0gRElFVmFsdWUgdHlwZXMgLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gTWFjcm9zIGZvciBydW5uaW5nIHRocm91Z2ggYWxsIHR5cGVzIG9mIERJRVZhbHVlLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZiAhKGRlZmluZWQgSEFORExFX0RJRVZBTFVFIHx8IGRlZmluZWQgSEFORExFX0RJRVZBTFVFX1NNQUxMIHx8ICAgICAgICAgICAgICBcCisgICAgICBkZWZpbmVkIEhBTkRMRV9ESUVWQUxVRV9MQVJHRSkKKyNlcnJvciAiTWlzc2luZyBtYWNybyBkZWZpbml0aW9uIG9mIEhBTkRMRV9ESUVWQUxVRSIKKyNlbmRpZgorCisvLyBIYW5kbGVyIGZvciBhbGwgdmFsdWVzLgorI2lmbmRlZiBIQU5ETEVfRElFVkFMVUUKKyNkZWZpbmUgSEFORExFX0RJRVZBTFVFKFQpCisjZW5kaWYKKworLy8gSGFuZGxlciBmb3Igc21hbGwgdmFsdWVzLgorI2lmbmRlZiBIQU5ETEVfRElFVkFMVUVfU01BTEwKKyNkZWZpbmUgSEFORExFX0RJRVZBTFVFX1NNQUxMKFQpIEhBTkRMRV9ESUVWQUxVRShUKQorI2VuZGlmCisKKy8vIEhhbmRsZXIgZm9yIGxhcmdlIHZhbHVlcy4KKyNpZm5kZWYgSEFORExFX0RJRVZBTFVFX0xBUkdFCisjZGVmaW5lIEhBTkRMRV9ESUVWQUxVRV9MQVJHRShUKSBIQU5ETEVfRElFVkFMVUUoVCkKKyNlbmRpZgorCitIQU5ETEVfRElFVkFMVUVfU01BTEwoSW50ZWdlcikKK0hBTkRMRV9ESUVWQUxVRV9TTUFMTChTdHJpbmcpCitIQU5ETEVfRElFVkFMVUVfU01BTEwoRXhwcikKK0hBTkRMRV9ESUVWQUxVRV9TTUFMTChMYWJlbCkKK0hBTkRMRV9ESUVWQUxVRV9MQVJHRShEZWx0YSkKK0hBTkRMRV9ESUVWQUxVRV9TTUFMTChFbnRyeSkKK0hBTkRMRV9ESUVWQUxVRV9MQVJHRShCbG9jaykKK0hBTkRMRV9ESUVWQUxVRV9MQVJHRShMb2MpCitIQU5ETEVfRElFVkFMVUVfU01BTEwoTG9jTGlzdCkKK0hBTkRMRV9ESUVWQUxVRV9MQVJHRShJbmxpbmVTdHJpbmcpCisKKyN1bmRlZiBIQU5ETEVfRElFVkFMVUUKKyN1bmRlZiBIQU5ETEVfRElFVkFMVUVfU01BTEwKKyN1bmRlZiBIQU5ETEVfRElFVkFMVUVfTEFSR0UKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9Ed2FyZlN0cmluZ1Bvb2xFbnRyeS5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0R3YXJmU3RyaW5nUG9vbEVudHJ5LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTZjMDQ4MwotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9Ed2FyZlN0cmluZ1Bvb2xFbnRyeS5oCkBAIC0wLDAgKzEsNTMgQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vRHdhcmZTdHJpbmdQb29sRW50cnkuaCAtIFN0cmluZyBwb29sIGVudHJ5IC0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0RXQVJGU1RSSU5HUE9PTEVOVFJZX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0RXQVJGU1RSSU5HUE9PTEVOVFJZX0gKKworI2luY2x1ZGUgImxsdm0vQURUL1N0cmluZ01hcC5oIgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIE1DU3ltYm9sOworCisvLy8gRGF0YSBmb3IgYSBzdHJpbmcgcG9vbCBlbnRyeS4KK3N0cnVjdCBEd2FyZlN0cmluZ1Bvb2xFbnRyeSB7CisgIE1DU3ltYm9sICpTeW1ib2w7CisgIHVuc2lnbmVkIE9mZnNldDsKKyAgdW5zaWduZWQgSW5kZXg7Cit9OworCisvLy8gU3RyaW5nIHBvb2wgZW50cnkgcmVmZXJlbmNlLgorc3RydWN0IER3YXJmU3RyaW5nUG9vbEVudHJ5UmVmIHsKKyAgY29uc3QgU3RyaW5nTWFwRW50cnk8RHdhcmZTdHJpbmdQb29sRW50cnk+ICpJID0gbnVsbHB0cjsKKworcHVibGljOgorICBEd2FyZlN0cmluZ1Bvb2xFbnRyeVJlZigpID0gZGVmYXVsdDsKKyAgZXhwbGljaXQgRHdhcmZTdHJpbmdQb29sRW50cnlSZWYoCisgICAgICBjb25zdCBTdHJpbmdNYXBFbnRyeTxEd2FyZlN0cmluZ1Bvb2xFbnRyeT4gJkkpCisgICAgICA6IEkoJkkpIHt9CisKKyAgZXhwbGljaXQgb3BlcmF0b3IgYm9vbCgpIGNvbnN0IHsgcmV0dXJuIEk7IH0KKyAgTUNTeW1ib2wgKmdldFN5bWJvbCgpIGNvbnN0IHsKKyAgICBhc3NlcnQoSS0+c2Vjb25kLlN5bWJvbCAmJiAiTm8gc3ltYm9sIGF2YWlsYWJsZSEiKTsKKyAgICByZXR1cm4gSS0+c2Vjb25kLlN5bWJvbDsKKyAgfQorICB1bnNpZ25lZCBnZXRPZmZzZXQoKSBjb25zdCB7IHJldHVybiBJLT5zZWNvbmQuT2Zmc2V0OyB9CisgIHVuc2lnbmVkIGdldEluZGV4KCkgY29uc3QgeyByZXR1cm4gSS0+c2Vjb25kLkluZGV4OyB9CisgIFN0cmluZ1JlZiBnZXRTdHJpbmcoKSBjb25zdCB7IHJldHVybiBJLT5maXJzdCgpOyB9CisgIC8vLyBSZXR1cm4gdGhlIGVudGlyZSBzdHJpbmcgcG9vbCBlbnRyeSBmb3IgY29udmVuaWVuY2UuCisgIER3YXJmU3RyaW5nUG9vbEVudHJ5IGdldEVudHJ5KCkgY29uc3QgeyByZXR1cm4gSS0+Z2V0VmFsdWUoKTsgfQorCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBEd2FyZlN0cmluZ1Bvb2xFbnRyeVJlZiAmWCkgY29uc3QgeyByZXR1cm4gSSA9PSBYLkk7IH0KKyAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IER3YXJmU3RyaW5nUG9vbEVudHJ5UmVmICZYKSBjb25zdCB7IHJldHVybiBJICE9IFguSTsgfQorfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vRWRnZUJ1bmRsZXMuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9FZGdlQnVuZGxlcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMzMWZhZDIKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vRWRnZUJ1bmRsZXMuaApAQCAtMCwwICsxLDY0IEBACisvLz09PS0tLS0tLS0tIEVkZ2VCdW5kbGVzLmggLSBCdW5kbGVzIG9mIENGRyBlZGdlcyAtLS0tLS0tLS0tLS0tLSotIGMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoZSBFZGdlQnVuZGxlcyBhbmFseXNpcyBmb3JtcyBlcXVpdmFsZW5jZSBjbGFzc2VzIG9mIENGRyBlZGdlcyBzdWNoIHRoYXQgYWxsCisvLyBlZGdlcyBsZWF2aW5nIGEgbWFjaGluZSBiYXNpYyBibG9jayBhcmUgaW4gdGhlIHNhbWUgYnVuZGxlLCBhbmQgYWxsIGVkZ2VzCisvLyBsZWF2aW5nIGEgYmFzaWMgYmxvY2sgYXJlIGluIHRoZSBzYW1lIGJ1bmRsZS4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9FREdFQlVORExFU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9FREdFQlVORExFU19ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9BcnJheVJlZi5oIgorI2luY2x1ZGUgImxsdm0vQURUL0ludEVxQ2xhc3Nlcy5oIgorI2luY2x1ZGUgImxsdm0vQURUL1R3aW5lLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvblBhc3MuaCIKKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBFZGdlQnVuZGxlcyA6IHB1YmxpYyBNYWNoaW5lRnVuY3Rpb25QYXNzIHsKKyAgY29uc3QgTWFjaGluZUZ1bmN0aW9uICpNRjsKKworICAvLy8gRUMgLSBFYWNoIGVkZ2UgYnVuZGxlIGlzIGFuIGVxdWl2YWxlbmNlIGNsYXNzLiBUaGUga2V5cyBhcmU6CisgIC8vLyAgIDIqQkItPmdldE51bWJlcigpICAgLT4gSW5nb2luZyBidW5kbGUuCisgIC8vLyAgIDIqQkItPmdldE51bWJlcigpKzEgLT4gT3V0Z29pbmcgYnVuZGxlLgorICBJbnRFcUNsYXNzZXMgRUM7CisKKyAgLy8vIEJsb2NrcyAtIE1hcCBlYWNoIGJ1bmRsZSB0byBhIGxpc3Qgb2YgYmFzaWMgYmxvY2sgbnVtYmVycy4KKyAgU21hbGxWZWN0b3I8U21hbGxWZWN0b3I8dW5zaWduZWQsIDg+LCA0PiBCbG9ja3M7CisKK3B1YmxpYzoKKyAgc3RhdGljIGNoYXIgSUQ7CisgIEVkZ2VCdW5kbGVzKCkgOiBNYWNoaW5lRnVuY3Rpb25QYXNzKElEKSB7fQorCisgIC8vLyBnZXRCdW5kbGUgLSBSZXR1cm4gdGhlIGluZ29pbmcgKE91dCA9IGZhbHNlKSBvciBvdXRnb2luZyAoT3V0ID0gdHJ1ZSkKKyAgLy8vIGJ1bmRsZSBudW1iZXIgZm9yIGJhc2ljIGJsb2NrICNOCisgIHVuc2lnbmVkIGdldEJ1bmRsZSh1bnNpZ25lZCBOLCBib29sIE91dCkgY29uc3QgeyByZXR1cm4gRUNbMiAqIE4gKyBPdXRdOyB9CisKKyAgLy8vIGdldE51bUJ1bmRsZXMgLSBSZXR1cm4gdGhlIHRvdGFsIG51bWJlciBvZiBidW5kbGVzIGluIHRoZSBDRkcuCisgIHVuc2lnbmVkIGdldE51bUJ1bmRsZXMoKSBjb25zdCB7IHJldHVybiBFQy5nZXROdW1DbGFzc2VzKCk7IH0KKworICAvLy8gZ2V0QmxvY2tzIC0gUmV0dXJuIGFuIGFycmF5IG9mIGJsb2NrcyB0aGF0IGFyZSBjb25uZWN0ZWQgdG8gQnVuZGxlLgorICBBcnJheVJlZjx1bnNpZ25lZD4gZ2V0QmxvY2tzKHVuc2lnbmVkIEJ1bmRsZSkgY29uc3QgeyByZXR1cm4gQmxvY2tzW0J1bmRsZV07IH0KKworICAvLy8gZ2V0TWFjaGluZUZ1bmN0aW9uIC0gUmV0dXJuIHRoZSBsYXN0IG1hY2hpbmUgZnVuY3Rpb24gY29tcHV0ZWQuCisgIGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAqZ2V0TWFjaGluZUZ1bmN0aW9uKCkgY29uc3QgeyByZXR1cm4gTUY7IH0KKworICAvLy8gdmlldyAtIFZpc3VhbGl6ZSB0aGUgYW5ub3RhdGVkIGJpcGFydGl0ZSBDRkcgd2l0aCBHcmFwaHZpei4KKyAgdm9pZCB2aWV3KCkgY29uc3Q7CisKK3ByaXZhdGU6CisgIGJvb2wgcnVuT25NYWNoaW5lRnVuY3Rpb24oTWFjaGluZUZ1bmN0aW9uJikgb3ZlcnJpZGU7CisgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlJikgY29uc3Qgb3ZlcnJpZGU7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9FeGVjdXRpb25Eb21haW5GaXguaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9FeGVjdXRpb25Eb21haW5GaXguaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMzhjMjE0Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0V4ZWN1dGlvbkRvbWFpbkZpeC5oCkBAIC0wLDAgKzEsMjEzIEBACisvLz09LS0gbGx2bS9Db2RlR2VuL0V4ZWN1dGlvbkRvbWFpbkZpeC5oIC0gRXhlY3V0aW9uIERvbWFpbiBGaXggLSotIEMrKyAtKi0tPT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vLyBcZmlsZSBFeGVjdXRpb24gRG9tYWluIEZpeCBwYXNzLgorLy8vCisvLy8gU29tZSBYODYgU1NFIGluc3RydWN0aW9ucyBsaWtlIG1vdiwgYW5kLCBvciwgeG9yIGFyZSBhdmFpbGFibGUgaW4gZGlmZmVyZW50CisvLy8gdmFyaWFudHMgZm9yIGRpZmZlcmVudCBvcGVyYW5kIHR5cGVzLiBUaGVzZSB2YXJpYW50IGluc3RydWN0aW9ucyBhcmUKKy8vLyBlcXVpdmFsZW50LCBidXQgb24gTmVoYWxlbSBhbmQgbmV3ZXIgY3B1cyB0aGVyZSBpcyBleHRyYSBsYXRlbmN5CisvLy8gdHJhbnNmZXJyaW5nIGRhdGEgYmV0d2VlbiBpbnRlZ2VyIGFuZCBmbG9hdGluZyBwb2ludCBkb21haW5zLiAgQVJNIGNvcmVzCisvLy8gaGF2ZSBzaW1pbGFyIGlzc3VlcyB3aGVuIHRoZXkgYXJlIGNvbmZpZ3VyZWQgd2l0aCBib3RoIFZGUCBhbmQgTkVPTgorLy8vIHBpcGVsaW5lcy4KKy8vLworLy8vIFRoaXMgcGFzcyBjaGFuZ2VzIHRoZSB2YXJpYW50IGluc3RydWN0aW9ucyB0byBtaW5pbWl6ZSBkb21haW4gY3Jvc3NpbmdzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0VYRUNVVElPTkRPTUFJTkZJWF9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9FWEVDVVRJT05ET01BSU5GSVhfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTG9vcFRyYXZlcnNhbC5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lRnVuY3Rpb25QYXNzLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1JlYWNoaW5nRGVmQW5hbHlzaXMuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0UmVnaXN0ZXJJbmZvLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgTWFjaGluZUJhc2ljQmxvY2s7CitjbGFzcyBNYWNoaW5lSW5zdHI7CitjbGFzcyBUYXJnZXRJbnN0ckluZm87CisKKy8vLyBBIERvbWFpblZhbHVlIGlzIGEgYml0IGxpa2UgTGl2ZUludGVydmFscycgVmFsTm8sIGJ1dCBpdCBhbHNvIGtlZXBzIHRyYWNrCisvLy8gb2YgZXhlY3V0aW9uIGRvbWFpbnMuCisvLy8KKy8vLyBBbiBvcGVuIERvbWFpblZhbHVlIHJlcHJlc2VudHMgYSBzZXQgb2YgaW5zdHJ1Y3Rpb25zIHRoYXQgY2FuIHN0aWxsIHN3aXRjaAorLy8vIGV4ZWN1dGlvbiBkb21haW4uIE11bHRpcGxlIHJlZ2lzdGVycyBtYXkgcmVmZXIgdG8gdGhlIHNhbWUgb3BlbgorLy8vIERvbWFpblZhbHVlIC0gdGhleSB3aWxsIGV2ZW50dWFsbHkgYmUgY29sbGFwc2VkIHRvIHRoZSBzYW1lIGV4ZWN1dGlvbgorLy8vIGRvbWFpbi4KKy8vLworLy8vIEEgY29sbGFwc2VkIERvbWFpblZhbHVlIHJlcHJlc2VudHMgYSBzaW5nbGUgcmVnaXN0ZXIgdGhhdCBoYXMgYmVlbiBmb3JjZWQKKy8vLyBpbnRvIG9uZSBvZiBtb3JlIGV4ZWN1dGlvbiBkb21haW5zLiBUaGVyZSBpcyBhIHNlcGFyYXRlIGNvbGxhcHNlZAorLy8vIERvbWFpblZhbHVlIGZvciBlYWNoIHJlZ2lzdGVyLCBidXQgaXQgbWF5IGNvbnRhaW4gbXVsdGlwbGUgZXhlY3V0aW9uCisvLy8gZG9tYWlucy4gQSByZWdpc3RlciB2YWx1ZSBpcyBpbml0aWFsbHkgY3JlYXRlZCBpbiBhIHNpbmdsZSBleGVjdXRpb24KKy8vLyBkb21haW4sIGJ1dCBpZiB3ZSB3ZXJlIGZvcmNlZCB0byBwYXkgdGhlIHBlbmFsdHkgb2YgYSBkb21haW4gY3Jvc3NpbmcsIHdlCisvLy8ga2VlcCB0cmFjayBvZiB0aGUgZmFjdCB0aGF0IHRoZSByZWdpc3RlciBpcyBub3cgYXZhaWxhYmxlIGluIG11bHRpcGxlCisvLy8gZG9tYWlucy4KK3N0cnVjdCBEb21haW5WYWx1ZSB7CisgIC8vLyBCYXNpYyByZWZlcmVuY2UgY291bnRpbmcuCisgIHVuc2lnbmVkIFJlZnMgPSAwOworCisgIC8vLyBCaXRtYXNrIG9mIGF2YWlsYWJsZSBkb21haW5zLiBGb3IgYW4gb3BlbiBEb21haW5WYWx1ZSwgaXQgaXMgdGhlIHN0aWxsCisgIC8vLyBwb3NzaWJsZSBkb21haW5zIGZvciBjb2xsYXBzaW5nLiBGb3IgYSBjb2xsYXBzZWQgRG9tYWluVmFsdWUgaXQgaXMgdGhlCisgIC8vLyBkb21haW5zIHdoZXJlIHRoZSByZWdpc3RlciBpcyBhdmFpbGFibGUgZm9yIGZyZWUuCisgIHVuc2lnbmVkIEF2YWlsYWJsZURvbWFpbnM7CisKKyAgLy8vIFBvaW50ZXIgdG8gdGhlIG5leHQgRG9tYWluVmFsdWUgaW4gYSBjaGFpbi4gIFdoZW4gdHdvIERvbWFpblZhbHVlcyBhcmUKKyAgLy8vIG1lcmdlZCwgVmljdGltLk5leHQgaXMgc2V0IHRvIHBvaW50IHRvIFZpY3Rvciwgc28gb2xkIERvbWFpblZhbHVlCisgIC8vLyByZWZlcmVuY2VzIGNhbiBiZSB1cGRhdGVkIGJ5IGZvbGxvd2luZyB0aGUgY2hhaW4uCisgIERvbWFpblZhbHVlICpOZXh0OworCisgIC8vLyBUd2lkZGxlYWJsZSBpbnN0cnVjdGlvbnMgdXNpbmcgb3IgZGVmaW5pbmcgdGhlc2UgcmVnaXN0ZXJzLgorICBTbWFsbFZlY3RvcjxNYWNoaW5lSW5zdHIgKiwgOD4gSW5zdHJzOworCisgIERvbWFpblZhbHVlKCkgeyBjbGVhcigpOyB9CisKKyAgLy8vIEEgY29sbGFwc2VkIERvbWFpblZhbHVlIGhhcyBubyBpbnN0cnVjdGlvbnMgdG8gdHdpZGRsZSAtIGl0IHNpbXBseSBrZWVwcworICAvLy8gdHJhY2sgb2YgdGhlIGRvbWFpbnMgd2hlcmUgdGhlIHJlZ2lzdGVycyBhcmUgYWxyZWFkeSBhdmFpbGFibGUuCisgIGJvb2wgaXNDb2xsYXBzZWQoKSBjb25zdCB7IHJldHVybiBJbnN0cnMuZW1wdHkoKTsgfQorCisgIC8vLyBJcyBkb21haW4gYXZhaWxhYmxlPworICBib29sIGhhc0RvbWFpbih1bnNpZ25lZCBkb21haW4pIGNvbnN0IHsKKyAgICBhc3NlcnQoZG9tYWluIDwKKyAgICAgICAgICAgICAgIHN0YXRpY19jYXN0PHVuc2lnbmVkPihzdGQ6Om51bWVyaWNfbGltaXRzPHVuc2lnbmVkPjo6ZGlnaXRzKSAmJgorICAgICAgICAgICAidW5kZWZpbmVkIGJlaGF2aW9yIik7CisgICAgcmV0dXJuIEF2YWlsYWJsZURvbWFpbnMgJiAoMXUgPDwgZG9tYWluKTsKKyAgfQorCisgIC8vLyBNYXJrIGRvbWFpbiBhcyBhdmFpbGFibGUuCisgIHZvaWQgYWRkRG9tYWluKHVuc2lnbmVkIGRvbWFpbikgeyBBdmFpbGFibGVEb21haW5zIHw9IDF1IDw8IGRvbWFpbjsgfQorCisgIC8vIFJlc3RyaWN0IHRvIGEgc2luZ2xlIGRvbWFpbiBhdmFpbGFibGUuCisgIHZvaWQgc2V0U2luZ2xlRG9tYWluKHVuc2lnbmVkIGRvbWFpbikgeyBBdmFpbGFibGVEb21haW5zID0gMXUgPDwgZG9tYWluOyB9CisKKyAgLy8vIFJldHVybiBiaXRtYXNrIG9mIGRvbWFpbnMgdGhhdCBhcmUgYXZhaWxhYmxlIGFuZCBpbiBtYXNrLgorICB1bnNpZ25lZCBnZXRDb21tb25Eb21haW5zKHVuc2lnbmVkIG1hc2spIGNvbnN0IHsKKyAgICByZXR1cm4gQXZhaWxhYmxlRG9tYWlucyAmIG1hc2s7CisgIH0KKworICAvLy8gRmlyc3QgZG9tYWluIGF2YWlsYWJsZS4KKyAgdW5zaWduZWQgZ2V0Rmlyc3REb21haW4oKSBjb25zdCB7CisgICAgcmV0dXJuIGNvdW50VHJhaWxpbmdaZXJvcyhBdmFpbGFibGVEb21haW5zKTsKKyAgfQorCisgIC8vLyBDbGVhciB0aGlzIERvbWFpblZhbHVlIGFuZCBwb2ludCB0byBuZXh0IHdoaWNoIGhhcyBhbGwgaXRzIGRhdGEuCisgIHZvaWQgY2xlYXIoKSB7CisgICAgQXZhaWxhYmxlRG9tYWlucyA9IDA7CisgICAgTmV4dCA9IG51bGxwdHI7CisgICAgSW5zdHJzLmNsZWFyKCk7CisgIH0KK307CisKK2NsYXNzIEV4ZWN1dGlvbkRvbWFpbkZpeCA6IHB1YmxpYyBNYWNoaW5lRnVuY3Rpb25QYXNzIHsKKyAgU3BlY2lmaWNCdW1wUHRyQWxsb2NhdG9yPERvbWFpblZhbHVlPiBBbGxvY2F0b3I7CisgIFNtYWxsVmVjdG9yPERvbWFpblZhbHVlICosIDE2PiBBdmFpbDsKKworICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpjb25zdCBSQzsKKyAgTWFjaGluZUZ1bmN0aW9uICpNRjsKKyAgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICpUSUk7CisgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJOworICBzdGQ6OnZlY3RvcjxTbWFsbFZlY3RvcjxpbnQsIDE+PiBBbGlhc01hcDsKKyAgY29uc3QgdW5zaWduZWQgTnVtUmVnczsKKyAgLy8vIFZhbHVlIGN1cnJlbnRseSBpbiBlYWNoIHJlZ2lzdGVyLCBvciBOVUxMIHdoZW4gbm8gdmFsdWUgaXMgYmVpbmcgdHJhY2tlZC4KKyAgLy8vIFRoaXMgY291bnRzIGFzIGEgRG9tYWluVmFsdWUgcmVmZXJlbmNlLgorICB1c2luZyBMaXZlUmVnc0RWSW5mbyA9IHN0ZDo6dmVjdG9yPERvbWFpblZhbHVlICo+OworICBMaXZlUmVnc0RWSW5mbyBMaXZlUmVnczsKKyAgLy8vIEtlZXBzIGRvbWFpbiBpbmZvcm1hdGlvbiBmb3IgYWxsIHJlZ2lzdGVycy4gTm90ZSB0aGF0IHRoaXMKKyAgLy8vIGlzIGRpZmZlcmVudCBmcm9tIHRoZSB1c3VhbCBkZWZpbml0aW9uIG5vdGlvbiBvZiBsaXZlbmVzcy4gVGhlIENQVQorICAvLy8gZG9lc24ndCBjYXJlIHdoZXRoZXIgb3Igbm90IHdlIGNvbnNpZGVyIGEgcmVnaXN0ZXIga2lsbGVkLgorICB1c2luZyBPdXRSZWdzSW5mb01hcCA9IFNtYWxsVmVjdG9yPExpdmVSZWdzRFZJbmZvLCA0PjsKKyAgT3V0UmVnc0luZm9NYXAgTUJCT3V0UmVnc0luZm9zOworCisgIFJlYWNoaW5nRGVmQW5hbHlzaXMgKlJEQTsKKworcHVibGljOgorICBFeGVjdXRpb25Eb21haW5GaXgoY2hhciAmUGFzc0lELCBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICZSQykKKyAgICAgIDogTWFjaGluZUZ1bmN0aW9uUGFzcyhQYXNzSUQpLCBSQygmUkMpLCBOdW1SZWdzKFJDLmdldE51bVJlZ3MoKSkge30KKworICB2b2lkIGdldEFuYWx5c2lzVXNhZ2UoQW5hbHlzaXNVc2FnZSAmQVUpIGNvbnN0IG92ZXJyaWRlIHsKKyAgICBBVS5zZXRQcmVzZXJ2ZXNBbGwoKTsKKyAgICBBVS5hZGRSZXF1aXJlZDxSZWFjaGluZ0RlZkFuYWx5c2lzPigpOworICAgIE1hY2hpbmVGdW5jdGlvblBhc3M6OmdldEFuYWx5c2lzVXNhZ2UoQVUpOworICB9CisKKyAgYm9vbCBydW5Pbk1hY2hpbmVGdW5jdGlvbihNYWNoaW5lRnVuY3Rpb24gJk1GKSBvdmVycmlkZTsKKworICBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzIGdldFJlcXVpcmVkUHJvcGVydGllcygpIGNvbnN0IG92ZXJyaWRlIHsKKyAgICByZXR1cm4gTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcygpLnNldCgKKyAgICAgICAgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllczo6UHJvcGVydHk6Ok5vVlJlZ3MpOworICB9CisKK3ByaXZhdGU6CisgIC8vLyBUcmFuc2xhdGUgVFJJIHJlZ2lzdGVyIG51bWJlciB0byBhIGxpc3Qgb2YgaW5kaWNlcyBpbnRvIG91ciBzbWFsbGVyIHRhYmxlcworICAvLy8gb2YgaW50ZXJlc3RpbmcgcmVnaXN0ZXJzLgorICBpdGVyYXRvcl9yYW5nZTxTbWFsbFZlY3RvckltcGw8aW50Pjo6Y29uc3RfaXRlcmF0b3I+CisgIHJlZ0luZGljZXModW5zaWduZWQgUmVnKSBjb25zdDsKKworICAvLy8gRG9tYWluVmFsdWUgYWxsb2NhdGlvbi4KKyAgRG9tYWluVmFsdWUgKmFsbG9jKGludCBkb21haW4gPSAtMSk7CisKKyAgLy8vIEFkZCByZWZlcmVuY2UgdG8gRFYuCisgIERvbWFpblZhbHVlICpyZXRhaW4oRG9tYWluVmFsdWUgKkRWKSB7CisgICAgaWYgKERWKQorICAgICAgKytEVi0+UmVmczsKKyAgICByZXR1cm4gRFY7CisgIH0KKworICAvLy8gUmVsZWFzZSBhIHJlZmVyZW5jZSB0byBEVi4gIFdoZW4gdGhlIGxhc3QgcmVmZXJlbmNlIGlzIHJlbGVhc2VkLAorICAvLy8gY29sbGFwc2UgaWYgbmVlZGVkLgorICB2b2lkIHJlbGVhc2UoRG9tYWluVmFsdWUgKik7CisKKyAgLy8vIEZvbGxvdyB0aGUgY2hhaW4gb2YgZGVhZCBEb21haW5WYWx1ZXMgdW50aWwgYSBsaXZlIERvbWFpblZhbHVlIGlzIHJlYWNoZWQuCisgIC8vLyBVcGRhdGUgdGhlIHJlZmVyZW5jZWQgcG9pbnRlciB3aGVuIG5lY2Vzc2FyeS4KKyAgRG9tYWluVmFsdWUgKnJlc29sdmUoRG9tYWluVmFsdWUgKiYpOworCisgIC8vLyBTZXQgTGl2ZVJlZ3NbcnhdID0gZHYsIHVwZGF0aW5nIHJlZmVyZW5jZSBjb3VudHMuCisgIHZvaWQgc2V0TGl2ZVJlZyhpbnQgcngsIERvbWFpblZhbHVlICpEVik7CisKKyAgLy8vIEtpbGwgcmVnaXN0ZXIgcngsIHJlY3ljbGUgb3IgY29sbGFwc2UgYW55IERvbWFpblZhbHVlLgorICB2b2lkIGtpbGwoaW50IHJ4KTsKKworICAvLy8gRm9yY2UgcmVnaXN0ZXIgcnggaW50byBkb21haW4uCisgIHZvaWQgZm9yY2UoaW50IHJ4LCB1bnNpZ25lZCBkb21haW4pOworCisgIC8vLyBDb2xsYXBzZSBvcGVuIERvbWFpblZhbHVlIGludG8gZ2l2ZW4gZG9tYWluLiBJZiB0aGVyZSBhcmUgbXVsdGlwbGUKKyAgLy8vIHJlZ2lzdGVycyB1c2luZyBkdiwgdGhleSBlYWNoIGdldCBhIHVuaXF1ZSBjb2xsYXBzZWQgRG9tYWluVmFsdWUuCisgIHZvaWQgY29sbGFwc2UoRG9tYWluVmFsdWUgKmR2LCB1bnNpZ25lZCBkb21haW4pOworCisgIC8vLyBBbGwgaW5zdHJ1Y3Rpb25zIGFuZCByZWdpc3RlcnMgaW4gQiBhcmUgbW92ZWQgdG8gQSwgYW5kIEIgaXMgcmVsZWFzZWQuCisgIGJvb2wgbWVyZ2UoRG9tYWluVmFsdWUgKkEsIERvbWFpblZhbHVlICpCKTsKKworICAvLy8gU2V0IHVwIExpdmVSZWdzIGJ5IG1lcmdpbmcgcHJlZGVjZXNzb3IgbGl2ZS1vdXQgdmFsdWVzLgorICB2b2lkIGVudGVyQmFzaWNCbG9jayhjb25zdCBMb29wVHJhdmVyc2FsOjpUcmF2ZXJzZWRNQkJJbmZvICZUcmF2ZXJzZWRNQkIpOworCisgIC8vLyBVcGRhdGUgbGl2ZS1vdXQgdmFsdWVzLgorICB2b2lkIGxlYXZlQmFzaWNCbG9jayhjb25zdCBMb29wVHJhdmVyc2FsOjpUcmF2ZXJzZWRNQkJJbmZvICZUcmF2ZXJzZWRNQkIpOworCisgIC8vLyBQcm9jZXNzIGhlIGdpdmVuIGJhc2ljIGJsb2NrLgorICB2b2lkIHByb2Nlc3NCYXNpY0Jsb2NrKGNvbnN0IExvb3BUcmF2ZXJzYWw6OlRyYXZlcnNlZE1CQkluZm8gJlRyYXZlcnNlZE1CQik7CisKKyAgLy8vIFZpc2l0IGdpdmVuIGluc3R1cmNpb24uCisgIGJvb2wgdmlzaXRJbnN0cihNYWNoaW5lSW5zdHIgKik7CisKKyAgLy8vIFVwZGF0ZSBkZWYtYWdlcyBmb3IgcmVnaXN0ZXJzIGRlZmluZWQgYnkgTUkuCisgIC8vLyBJZiBLaWxsIGlzIHNldCwgYWxzbyBraWxsIG9mZiBEb21haW5WYWx1ZXMgY2xvYmJlcmVkIGJ5IHRoZSBkZWZzLgorICB2b2lkIHByb2Nlc3NEZWZzKE1hY2hpbmVJbnN0ciAqLCBib29sIEtpbGwpOworCisgIC8vLyBBIHNvZnQgaW5zdHJ1Y3Rpb24gY2FuIGJlIGNoYW5nZWQgdG8gd29yayBpbiBvdGhlciBkb21haW5zIGdpdmVuIGJ5IG1hc2suCisgIHZvaWQgdmlzaXRTb2Z0SW5zdHIoTWFjaGluZUluc3RyICosIHVuc2lnbmVkIG1hc2spOworCisgIC8vLyBBIGhhcmQgaW5zdHJ1Y3Rpb24gb25seSB3b3JrcyBpbiBvbmUgZG9tYWluLiBBbGwgaW5wdXQgcmVnaXN0ZXJzIHdpbGwgYmUKKyAgLy8vIGZvcmNlZCBpbnRvIHRoYXQgZG9tYWluLgorICB2b2lkIHZpc2l0SGFyZEluc3RyKE1hY2hpbmVJbnN0ciAqLCB1bnNpZ25lZCBkb21haW4pOworfTsKKworfSAvLyBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0VYRUNVVElPTkRPTUFJTkZJWF9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vRXhwYW5kUmVkdWN0aW9ucy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0V4cGFuZFJlZHVjdGlvbnMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNmFhYWFkCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0V4cGFuZFJlZHVjdGlvbnMuaApAQCAtMCwwICsxLDI0IEBACisvLz09PS0tLS0tIEV4cGFuZFJlZHVjdGlvbnMuaCAtIEV4cGFuZCBleHBlcmltZW50YWwgcmVkdWN0aW9uIGludHJpbnNpY3MgLS09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9FWFBBTkRSRURVQ1RJT05TX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0VYUEFORFJFRFVDVElPTlNfSAorCisjaW5jbHVkZSAibGx2bS9JUi9QYXNzTWFuYWdlci5oIgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIEV4cGFuZFJlZHVjdGlvbnNQYXNzCisgICAgOiBwdWJsaWMgUGFzc0luZm9NaXhpbjxFeHBhbmRSZWR1Y3Rpb25zUGFzcz4geworcHVibGljOgorICBQcmVzZXJ2ZWRBbmFseXNlcyBydW4oRnVuY3Rpb24gJkYsIEZ1bmN0aW9uQW5hbHlzaXNNYW5hZ2VyICZBTSk7Cit9OworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9FWFBBTkRSRURVQ1RJT05TX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9GYXN0SVNlbC5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0Zhc3RJU2VsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzcyYmQ2YwotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9GYXN0SVNlbC5oCkBAIC0wLDAgKzEsNTkzIEBACisvLz09PS0gRmFzdElTZWwuaCAtIERlZmluaXRpb24gb2YgdGhlIEZhc3RJU2VsIGNsYXNzIC0tLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vCisvLy8gXGZpbGUKKy8vLyBUaGlzIGZpbGUgZGVmaW5lcyB0aGUgRmFzdElTZWwgY2xhc3MuCisvLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0ZBU1RJU0VMX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0ZBU1RJU0VMX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TdHJpbmdSZWYuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0TG93ZXJpbmcuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0F0dHJpYnV0ZXMuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0NhbGxTaXRlLmgiCisjaW5jbHVkZSAibGx2bS9JUi9DYWxsaW5nQ29udi5oIgorI2luY2x1ZGUgImxsdm0vSVIvRGVidWdMb2MuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0Rlcml2ZWRUeXBlcy5oIgorI2luY2x1ZGUgImxsdm0vSVIvSW5zdHJUeXBlcy5oIgorI2luY2x1ZGUgImxsdm0vSVIvSW50cmluc2ljSW5zdC5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9NYWNoaW5lVmFsdWVUeXBlLmgiCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGNzdGRpbnQ+CisjaW5jbHVkZSA8dXRpbGl0eT4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBBbGxvY2FJbnN0OworY2xhc3MgQmFzaWNCbG9jazsKK2NsYXNzIENhbGxJbnN0OworY2xhc3MgQ29uc3RhbnQ7CitjbGFzcyBDb25zdGFudEZQOworY2xhc3MgRGF0YUxheW91dDsKK2NsYXNzIEZ1bmN0aW9uTG93ZXJpbmdJbmZvOworY2xhc3MgTG9hZEluc3Q7CitjbGFzcyBNYWNoaW5lQ29uc3RhbnRQb29sOworY2xhc3MgTWFjaGluZUZyYW1lSW5mbzsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIE1hY2hpbmVJbnN0cjsKK2NsYXNzIE1hY2hpbmVNZW1PcGVyYW5kOworY2xhc3MgTWFjaGluZU9wZXJhbmQ7CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworY2xhc3MgTUNDb250ZXh0OworY2xhc3MgTUNJbnN0ckRlc2M7CitjbGFzcyBNQ1N5bWJvbDsKK2NsYXNzIFRhcmdldEluc3RySW5mbzsKK2NsYXNzIFRhcmdldExpYnJhcnlJbmZvOworY2xhc3MgVGFyZ2V0TWFjaGluZTsKK2NsYXNzIFRhcmdldFJlZ2lzdGVyQ2xhc3M7CitjbGFzcyBUYXJnZXRSZWdpc3RlckluZm87CitjbGFzcyBUeXBlOworY2xhc3MgVXNlcjsKK2NsYXNzIFZhbHVlOworCisvLy8gXGJyaWVmIFRoaXMgaXMgYSBmYXN0LXBhdGggaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uIGNsYXNzIHRoYXQgZ2VuZXJhdGVzIHBvb3IKKy8vLyBjb2RlIGFuZCBkb2Vzbid0IHN1cHBvcnQgaWxsZWdhbCB0eXBlcyBvciBub24tdHJpdmlhbCBsb3dlcmluZywgYnV0IHJ1bnMKKy8vLyBxdWlja2x5LgorY2xhc3MgRmFzdElTZWwgeworcHVibGljOgorICB1c2luZyBBcmdMaXN0RW50cnkgPSBUYXJnZXRMb3dlcmluZ0Jhc2U6OkFyZ0xpc3RFbnRyeTsKKyAgdXNpbmcgQXJnTGlzdFR5ID0gVGFyZ2V0TG93ZXJpbmdCYXNlOjpBcmdMaXN0VHk7CisgIHN0cnVjdCBDYWxsTG93ZXJpbmdJbmZvIHsKKyAgICBUeXBlICpSZXRUeSA9IG51bGxwdHI7CisgICAgYm9vbCBSZXRTRXh0IDogMTsKKyAgICBib29sIFJldFpFeHQgOiAxOworICAgIGJvb2wgSXNWYXJBcmcgOiAxOworICAgIGJvb2wgSXNJblJlZyA6IDE7CisgICAgYm9vbCBEb2VzTm90UmV0dXJuIDogMTsKKyAgICBib29sIElzUmV0dXJuVmFsdWVVc2VkIDogMTsKKyAgICBib29sIElzUGF0Y2hQb2ludCA6IDE7CisKKyAgICAvLyBcYnJpZWYgSXNUYWlsQ2FsbCBTaG91bGQgYmUgbW9kaWZpZWQgYnkgaW1wbGVtZW50YXRpb25zIG9mIEZhc3RMb3dlckNhbGwKKyAgICAvLyB0aGF0IHBlcmZvcm0gdGFpbCBjYWxsIGNvbnZlcnNpb25zLgorICAgIGJvb2wgSXNUYWlsQ2FsbCA9IGZhbHNlOworCisgICAgdW5zaWduZWQgTnVtRml4ZWRBcmdzID0gLTE7CisgICAgQ2FsbGluZ0NvbnY6OklEIENhbGxDb252ID0gQ2FsbGluZ0NvbnY6OkM7CisgICAgY29uc3QgVmFsdWUgKkNhbGxlZSA9IG51bGxwdHI7CisgICAgTUNTeW1ib2wgKlN5bWJvbCA9IG51bGxwdHI7CisgICAgQXJnTGlzdFR5IEFyZ3M7CisgICAgSW1tdXRhYmxlQ2FsbFNpdGUgKkNTID0gbnVsbHB0cjsKKyAgICBNYWNoaW5lSW5zdHIgKkNhbGwgPSBudWxscHRyOworICAgIHVuc2lnbmVkIFJlc3VsdFJlZyA9IDA7CisgICAgdW5zaWduZWQgTnVtUmVzdWx0UmVncyA9IDA7CisKKyAgICBTbWFsbFZlY3RvcjxWYWx1ZSAqLCAxNj4gT3V0VmFsczsKKyAgICBTbWFsbFZlY3RvcjxJU0Q6OkFyZ0ZsYWdzVHksIDE2PiBPdXRGbGFnczsKKyAgICBTbWFsbFZlY3Rvcjx1bnNpZ25lZCwgMTY+IE91dFJlZ3M7CisgICAgU21hbGxWZWN0b3I8SVNEOjpJbnB1dEFyZywgND4gSW5zOworICAgIFNtYWxsVmVjdG9yPHVuc2lnbmVkLCA0PiBJblJlZ3M7CisKKyAgICBDYWxsTG93ZXJpbmdJbmZvKCkKKyAgICAgICAgOiBSZXRTRXh0KGZhbHNlKSwgUmV0WkV4dChmYWxzZSksIElzVmFyQXJnKGZhbHNlKSwgSXNJblJlZyhmYWxzZSksCisgICAgICAgICAgRG9lc05vdFJldHVybihmYWxzZSksIElzUmV0dXJuVmFsdWVVc2VkKHRydWUpLCBJc1BhdGNoUG9pbnQoZmFsc2UpIHt9CisKKyAgICBDYWxsTG93ZXJpbmdJbmZvICZzZXRDYWxsZWUoVHlwZSAqUmVzdWx0VHksIEZ1bmN0aW9uVHlwZSAqRnVuY1R5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBWYWx1ZSAqVGFyZ2V0LCBBcmdMaXN0VHkgJiZBcmdzTGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW1tdXRhYmxlQ2FsbFNpdGUgJkNhbGwpIHsKKyAgICAgIFJldFR5ID0gUmVzdWx0VHk7CisgICAgICBDYWxsZWUgPSBUYXJnZXQ7CisKKyAgICAgIElzSW5SZWcgPSBDYWxsLmhhc1JldEF0dHIoQXR0cmlidXRlOjpJblJlZyk7CisgICAgICBEb2VzTm90UmV0dXJuID0gQ2FsbC5kb2VzTm90UmV0dXJuKCk7CisgICAgICBJc1ZhckFyZyA9IEZ1bmNUeS0+aXNWYXJBcmcoKTsKKyAgICAgIElzUmV0dXJuVmFsdWVVc2VkID0gIUNhbGwuZ2V0SW5zdHJ1Y3Rpb24oKS0+dXNlX2VtcHR5KCk7CisgICAgICBSZXRTRXh0ID0gQ2FsbC5oYXNSZXRBdHRyKEF0dHJpYnV0ZTo6U0V4dCk7CisgICAgICBSZXRaRXh0ID0gQ2FsbC5oYXNSZXRBdHRyKEF0dHJpYnV0ZTo6WkV4dCk7CisKKyAgICAgIENhbGxDb252ID0gQ2FsbC5nZXRDYWxsaW5nQ29udigpOworICAgICAgQXJncyA9IHN0ZDo6bW92ZShBcmdzTGlzdCk7CisgICAgICBOdW1GaXhlZEFyZ3MgPSBGdW5jVHktPmdldE51bVBhcmFtcygpOworCisgICAgICBDUyA9ICZDYWxsOworCisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorCisgICAgQ2FsbExvd2VyaW5nSW5mbyAmc2V0Q2FsbGVlKFR5cGUgKlJlc3VsdFR5LCBGdW5jdGlvblR5cGUgKkZ1bmNUeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUNTeW1ib2wgKlRhcmdldCwgQXJnTGlzdFR5ICYmQXJnc0xpc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEltbXV0YWJsZUNhbGxTaXRlICZDYWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBGaXhlZEFyZ3MgPSB+MFUpIHsKKyAgICAgIFJldFR5ID0gUmVzdWx0VHk7CisgICAgICBDYWxsZWUgPSBDYWxsLmdldENhbGxlZFZhbHVlKCk7CisgICAgICBTeW1ib2wgPSBUYXJnZXQ7CisKKyAgICAgIElzSW5SZWcgPSBDYWxsLmhhc1JldEF0dHIoQXR0cmlidXRlOjpJblJlZyk7CisgICAgICBEb2VzTm90UmV0dXJuID0gQ2FsbC5kb2VzTm90UmV0dXJuKCk7CisgICAgICBJc1ZhckFyZyA9IEZ1bmNUeS0+aXNWYXJBcmcoKTsKKyAgICAgIElzUmV0dXJuVmFsdWVVc2VkID0gIUNhbGwuZ2V0SW5zdHJ1Y3Rpb24oKS0+dXNlX2VtcHR5KCk7CisgICAgICBSZXRTRXh0ID0gQ2FsbC5oYXNSZXRBdHRyKEF0dHJpYnV0ZTo6U0V4dCk7CisgICAgICBSZXRaRXh0ID0gQ2FsbC5oYXNSZXRBdHRyKEF0dHJpYnV0ZTo6WkV4dCk7CisKKyAgICAgIENhbGxDb252ID0gQ2FsbC5nZXRDYWxsaW5nQ29udigpOworICAgICAgQXJncyA9IHN0ZDo6bW92ZShBcmdzTGlzdCk7CisgICAgICBOdW1GaXhlZEFyZ3MgPSAoRml4ZWRBcmdzID09IH4wVSkgPyBGdW5jVHktPmdldE51bVBhcmFtcygpIDogRml4ZWRBcmdzOworCisgICAgICBDUyA9ICZDYWxsOworCisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorCisgICAgQ2FsbExvd2VyaW5nSW5mbyAmc2V0Q2FsbGVlKENhbGxpbmdDb252OjpJRCBDQywgVHlwZSAqUmVzdWx0VHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFZhbHVlICpUYXJnZXQsIEFyZ0xpc3RUeSAmJkFyZ3NMaXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBGaXhlZEFyZ3MgPSB+MFUpIHsKKyAgICAgIFJldFR5ID0gUmVzdWx0VHk7CisgICAgICBDYWxsZWUgPSBUYXJnZXQ7CisgICAgICBDYWxsQ29udiA9IENDOworICAgICAgQXJncyA9IHN0ZDo6bW92ZShBcmdzTGlzdCk7CisgICAgICBOdW1GaXhlZEFyZ3MgPSAoRml4ZWRBcmdzID09IH4wVSkgPyBBcmdzLnNpemUoKSA6IEZpeGVkQXJnczsKKyAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisKKyAgICBDYWxsTG93ZXJpbmdJbmZvICZzZXRDYWxsZWUoY29uc3QgRGF0YUxheW91dCAmREwsIE1DQ29udGV4dCAmQ3R4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDYWxsaW5nQ29udjo6SUQgQ0MsIFR5cGUgKlJlc3VsdFR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdSZWYgVGFyZ2V0LCBBcmdMaXN0VHkgJiZBcmdzTGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgRml4ZWRBcmdzID0gfjBVKTsKKworICAgIENhbGxMb3dlcmluZ0luZm8gJnNldENhbGxlZShDYWxsaW5nQ29udjo6SUQgQ0MsIFR5cGUgKlJlc3VsdFR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQ1N5bWJvbCAqVGFyZ2V0LCBBcmdMaXN0VHkgJiZBcmdzTGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgRml4ZWRBcmdzID0gfjBVKSB7CisgICAgICBSZXRUeSA9IFJlc3VsdFR5OworICAgICAgU3ltYm9sID0gVGFyZ2V0OworICAgICAgQ2FsbENvbnYgPSBDQzsKKyAgICAgIEFyZ3MgPSBzdGQ6Om1vdmUoQXJnc0xpc3QpOworICAgICAgTnVtRml4ZWRBcmdzID0gKEZpeGVkQXJncyA9PSB+MFUpID8gQXJncy5zaXplKCkgOiBGaXhlZEFyZ3M7CisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorCisgICAgQ2FsbExvd2VyaW5nSW5mbyAmc2V0VGFpbENhbGwoYm9vbCBWYWx1ZSA9IHRydWUpIHsKKyAgICAgIElzVGFpbENhbGwgPSBWYWx1ZTsKKyAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisKKyAgICBDYWxsTG93ZXJpbmdJbmZvICZzZXRJc1BhdGNoUG9pbnQoYm9vbCBWYWx1ZSA9IHRydWUpIHsKKyAgICAgIElzUGF0Y2hQb2ludCA9IFZhbHVlOworICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KKworICAgIEFyZ0xpc3RUeSAmZ2V0QXJncygpIHsgcmV0dXJuIEFyZ3M7IH0KKworICAgIHZvaWQgY2xlYXJPdXRzKCkgeworICAgICAgT3V0VmFscy5jbGVhcigpOworICAgICAgT3V0RmxhZ3MuY2xlYXIoKTsKKyAgICAgIE91dFJlZ3MuY2xlYXIoKTsKKyAgICB9CisKKyAgICB2b2lkIGNsZWFySW5zKCkgeworICAgICAgSW5zLmNsZWFyKCk7CisgICAgICBJblJlZ3MuY2xlYXIoKTsKKyAgICB9CisgIH07CisKK3Byb3RlY3RlZDoKKyAgRGVuc2VNYXA8Y29uc3QgVmFsdWUgKiwgdW5zaWduZWQ+IExvY2FsVmFsdWVNYXA7CisgIEZ1bmN0aW9uTG93ZXJpbmdJbmZvICZGdW5jSW5mbzsKKyAgTWFjaGluZUZ1bmN0aW9uICpNRjsKKyAgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJOworICBNYWNoaW5lRnJhbWVJbmZvICZNRkk7CisgIE1hY2hpbmVDb25zdGFudFBvb2wgJk1DUDsKKyAgRGVidWdMb2MgRGJnTG9jOworICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTTsKKyAgY29uc3QgRGF0YUxheW91dCAmREw7CisgIGNvbnN0IFRhcmdldEluc3RySW5mbyAmVElJOworICBjb25zdCBUYXJnZXRMb3dlcmluZyAmVExJOworICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gJlRSSTsKKyAgY29uc3QgVGFyZ2V0TGlicmFyeUluZm8gKkxpYkluZm87CisgIGJvb2wgU2tpcFRhcmdldEluZGVwZW5kZW50SVNlbDsKKworICAvLy8gXGJyaWVmIFRoZSBwb3NpdGlvbiBvZiB0aGUgbGFzdCBpbnN0cnVjdGlvbiBmb3IgbWF0ZXJpYWxpemluZyBjb25zdGFudHMKKyAgLy8vIGZvciB1c2UgaW4gdGhlIGN1cnJlbnQgYmxvY2suIEl0IHJlc2V0cyB0byBFbWl0U3RhcnRQdCB3aGVuIGl0IG1ha2VzIHNlbnNlCisgIC8vLyAoZm9yIGV4YW1wbGUsIGl0J3MgdXN1YWxseSBwcm9maXRhYmxlIHRvIGF2b2lkIGZ1bmN0aW9uIGNhbGxzIGJldHdlZW4gdGhlCisgIC8vLyBkZWZpbml0aW9uIGFuZCB0aGUgdXNlKQorICBNYWNoaW5lSW5zdHIgKkxhc3RMb2NhbFZhbHVlOworCisgIC8vLyBcYnJpZWYgVGhlIHRvcCBtb3N0IGluc3RydWN0aW9uIGluIHRoZSBjdXJyZW50IGJsb2NrIHRoYXQgaXMgYWxsb3dlZCBmb3IKKyAgLy8vIGVtaXR0aW5nIGxvY2FsIHZhcmlhYmxlcy4gTGFzdExvY2FsVmFsdWUgcmVzZXRzIHRvIEVtaXRTdGFydFB0IHdoZW4gaXQKKyAgLy8vIG1ha2VzIHNlbnNlIChmb3IgZXhhbXBsZSwgb24gZnVuY3Rpb24gY2FsbHMpCisgIE1hY2hpbmVJbnN0ciAqRW1pdFN0YXJ0UHQ7CisKK3B1YmxpYzoKKyAgdmlydHVhbCB+RmFzdElTZWwoKTsKKworICAvLy8gXGJyaWVmIFJldHVybiB0aGUgcG9zaXRpb24gb2YgdGhlIGxhc3QgaW5zdHJ1Y3Rpb24gZW1pdHRlZCBmb3IKKyAgLy8vIG1hdGVyaWFsaXppbmcgY29uc3RhbnRzIGZvciB1c2UgaW4gdGhlIGN1cnJlbnQgYmxvY2suCisgIE1hY2hpbmVJbnN0ciAqZ2V0TGFzdExvY2FsVmFsdWUoKSB7IHJldHVybiBMYXN0TG9jYWxWYWx1ZTsgfQorCisgIC8vLyBcYnJpZWYgVXBkYXRlIHRoZSBwb3NpdGlvbiBvZiB0aGUgbGFzdCBpbnN0cnVjdGlvbiBlbWl0dGVkIGZvcgorICAvLy8gbWF0ZXJpYWxpemluZyBjb25zdGFudHMgZm9yIHVzZSBpbiB0aGUgY3VycmVudCBibG9jay4KKyAgdm9pZCBzZXRMYXN0TG9jYWxWYWx1ZShNYWNoaW5lSW5zdHIgKkkpIHsKKyAgICBFbWl0U3RhcnRQdCA9IEk7CisgICAgTGFzdExvY2FsVmFsdWUgPSBJOworICB9CisKKyAgLy8vIFxicmllZiBTZXQgdGhlIGN1cnJlbnQgYmxvY2sgdG8gd2hpY2ggZ2VuZXJhdGVkIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zIHdpbGwKKyAgLy8vIGJlIGFwcGVuZGVkLgorICB2b2lkIHN0YXJ0TmV3QmxvY2soKTsKKworICAvLy8gRmx1c2ggdGhlIGxvY2FsIHZhbHVlIG1hcCBhbmQgc2luayBsb2NhbCB2YWx1ZXMgaWYgcG9zc2libGUuCisgIHZvaWQgZmluaXNoQmFzaWNCbG9jaygpOworCisgIC8vLyBcYnJpZWYgUmV0dXJuIGN1cnJlbnQgZGVidWcgbG9jYXRpb24gaW5mb3JtYXRpb24uCisgIERlYnVnTG9jIGdldEN1ckRlYnVnTG9jKCkgY29uc3QgeyByZXR1cm4gRGJnTG9jOyB9CisKKyAgLy8vIFxicmllZiBEbyAiZmFzdCIgaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uIGZvciBmdW5jdGlvbiBhcmd1bWVudHMgYW5kIGFwcGVuZAorICAvLy8gdGhlIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zIHRvIHRoZSBjdXJyZW50IGJsb2NrLiBSZXR1cm5zIHRydWUgd2hlbgorICAvLy8gc3VjY2Vzc2Z1bC4KKyAgYm9vbCBsb3dlckFyZ3VtZW50cygpOworCisgIC8vLyBcYnJpZWYgRG8gImZhc3QiIGluc3RydWN0aW9uIHNlbGVjdGlvbiBmb3IgdGhlIGdpdmVuIExMVk0gSVIgaW5zdHJ1Y3Rpb24KKyAgLy8vIGFuZCBhcHBlbmQgdGhlIGdlbmVyYXRlZCBtYWNoaW5lIGluc3RydWN0aW9ucyB0byB0aGUgY3VycmVudCBibG9jay4KKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiBzZWxlY3Rpb24gd2FzIHN1Y2Nlc3NmdWwuCisgIGJvb2wgc2VsZWN0SW5zdHJ1Y3Rpb24oY29uc3QgSW5zdHJ1Y3Rpb24gKkkpOworCisgIC8vLyBcYnJpZWYgRG8gImZhc3QiIGluc3RydWN0aW9uIHNlbGVjdGlvbiBmb3IgdGhlIGdpdmVuIExMVk0gSVIgb3BlcmF0b3IKKyAgLy8vIChJbnN0cnVjdGlvbiBvciBDb25zdGFudEV4cHIpLCBhbmQgYXBwZW5kIGdlbmVyYXRlZCBtYWNoaW5lIGluc3RydWN0aW9ucworICAvLy8gdG8gdGhlIGN1cnJlbnQgYmxvY2suIFJldHVybiB0cnVlIGlmIHNlbGVjdGlvbiB3YXMgc3VjY2Vzc2Z1bC4KKyAgYm9vbCBzZWxlY3RPcGVyYXRvcihjb25zdCBVc2VyICpJLCB1bnNpZ25lZCBPcGNvZGUpOworCisgIC8vLyBcYnJpZWYgQ3JlYXRlIGEgdmlydHVhbCByZWdpc3RlciBhbmQgYXJyYW5nZSBmb3IgaXQgdG8gYmUgYXNzaWduZWQgdGhlCisgIC8vLyB2YWx1ZSBmb3IgdGhlIGdpdmVuIExMVk0gdmFsdWUuCisgIHVuc2lnbmVkIGdldFJlZ0ZvclZhbHVlKGNvbnN0IFZhbHVlICpWKTsKKworICAvLy8gXGJyaWVmIExvb2sgdXAgdGhlIHZhbHVlIHRvIHNlZSBpZiBpdHMgdmFsdWUgaXMgYWxyZWFkeSBjYWNoZWQgaW4gYQorICAvLy8gcmVnaXN0ZXIuIEl0IG1heSBiZSBkZWZpbmVkIGJ5IGluc3RydWN0aW9ucyBhY3Jvc3MgYmxvY2tzIG9yIGRlZmluZWQKKyAgLy8vIGxvY2FsbHkuCisgIHVuc2lnbmVkIGxvb2tVcFJlZ0ZvclZhbHVlKGNvbnN0IFZhbHVlICpWKTsKKworICAvLy8gXGJyaWVmIFRoaXMgaXMgYSB3cmFwcGVyIGFyb3VuZCBnZXRSZWdGb3JWYWx1ZSB0aGF0IGFsc28gdGFrZXMgY2FyZSBvZgorICAvLy8gdHJ1bmNhdGluZyBvciBzaWduLWV4dGVuZGluZyB0aGUgZ2l2ZW4gZ2V0ZWxlbWVudHB0ciBpbmRleCB2YWx1ZS4KKyAgc3RkOjpwYWlyPHVuc2lnbmVkLCBib29sPiBnZXRSZWdGb3JHRVBJbmRleChjb25zdCBWYWx1ZSAqVik7CisKKyAgLy8vIFxicmllZiBXZSdyZSBjaGVja2luZyB0byBzZWUgaWYgd2UgY2FuIGZvbGQgXHAgTEkgaW50byBccCBGb2xkSW5zdC4gTm90ZQorICAvLy8gdGhhdCB3ZSBjb3VsZCBoYXZlIGEgc2VxdWVuY2Ugd2hlcmUgbXVsdGlwbGUgTExWTSBJUiBpbnN0cnVjdGlvbnMgYXJlCisgIC8vLyBmb2xkZWQgaW50byB0aGUgc2FtZSBtYWNoaW5laW5zdHIuICBGb3IgZXhhbXBsZSB3ZSBjb3VsZCBoYXZlOgorICAvLy8KKyAgLy8vICAgQTogeCA9IGxvYWQgaTMyICpQCisgIC8vLyAgIEI6IHkgPSBpY21wIEEsIDQyCisgIC8vLyAgIEM6IGJyIHksIC4uLgorICAvLy8KKyAgLy8vIEluIHRoaXMgc2NlbmFyaW8sIFxwIExJIGlzICJBIiwgYW5kIFxwIEZvbGRJbnN0IGlzICJDIi4gIFdlIGtub3cgYWJvdXQgIkIiCisgIC8vLyAoYW5kIGFueSBvdGhlciBmb2xkZWQgaW5zdHJ1Y3Rpb25zKSBiZWNhdXNlIGl0IGlzIGJldHdlZW4gQSBhbmQgQy4KKyAgLy8vCisgIC8vLyBJZiB3ZSBzdWNjZWVkIGZvbGRpbmcsIHJldHVybiB0cnVlLgorICBib29sIHRyeVRvRm9sZExvYWQoY29uc3QgTG9hZEluc3QgKkxJLCBjb25zdCBJbnN0cnVjdGlvbiAqRm9sZEluc3QpOworCisgIC8vLyBcYnJpZWYgVGhlIHNwZWNpZmllZCBtYWNoaW5lIGluc3RyIG9wZXJhbmQgaXMgYSB2cmVnLCBhbmQgdGhhdCB2cmVnIGlzCisgIC8vLyBiZWluZyBwcm92aWRlZCBieSB0aGUgc3BlY2lmaWVkIGxvYWQgaW5zdHJ1Y3Rpb24uICBJZiBwb3NzaWJsZSwgdHJ5IHRvCisgIC8vLyBmb2xkIHRoZSBsb2FkIGFzIGFuIG9wZXJhbmQgdG8gdGhlIGluc3RydWN0aW9uLCByZXR1cm5pbmcgdHJ1ZSBpZgorICAvLy8gcG9zc2libGUuCisgIC8vLworICAvLy8gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIGltcGxlbWVudGVkIGJ5IHRhcmdldHMuCisgIHZpcnR1YWwgYm9vbCB0cnlUb0ZvbGRMb2FkSW50b01JKE1hY2hpbmVJbnN0ciAqIC8qTUkqLywgdW5zaWduZWQgLypPcE5vKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvYWRJbnN0ICogLypMSSovKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFxicmllZiBSZXNldCBJbnNlcnRQdCB0byBwcmVwYXJlIGZvciBpbnNlcnRpbmcgaW5zdHJ1Y3Rpb25zIGludG8gdGhlCisgIC8vLyBjdXJyZW50IGJsb2NrLgorICB2b2lkIHJlY29tcHV0ZUluc2VydFB0KCk7CisKKyAgLy8vIFxicmllZiBSZW1vdmUgYWxsIGRlYWQgaW5zdHJ1Y3Rpb25zIGJldHdlZW4gdGhlIEkgYW5kIEUuCisgIHZvaWQgcmVtb3ZlRGVhZENvZGUoTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEksCisgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEUpOworCisgIHN0cnVjdCBTYXZlUG9pbnQgeworICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBJbnNlcnRQdDsKKyAgICBEZWJ1Z0xvYyBETDsKKyAgfTsKKworICAvLy8gXGJyaWVmIFByZXBhcmUgSW5zZXJ0UHQgdG8gYmVnaW4gaW5zZXJ0aW5nIGluc3RydWN0aW9ucyBpbnRvIHRoZSBsb2NhbAorICAvLy8gdmFsdWUgYXJlYSBhbmQgcmV0dXJuIHRoZSBvbGQgaW5zZXJ0IHBvc2l0aW9uLgorICBTYXZlUG9pbnQgZW50ZXJMb2NhbFZhbHVlQXJlYSgpOworCisgIC8vLyBcYnJpZWYgUmVzZXQgSW5zZXJ0UHQgdG8gdGhlIGdpdmVuIG9sZCBpbnNlcnQgcG9zaXRpb24uCisgIHZvaWQgbGVhdmVMb2NhbFZhbHVlQXJlYShTYXZlUG9pbnQgT2xkKTsKKworcHJvdGVjdGVkOgorICBleHBsaWNpdCBGYXN0SVNlbChGdW5jdGlvbkxvd2VyaW5nSW5mbyAmRnVuY0luZm8sCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldExpYnJhcnlJbmZvICpMaWJJbmZvLAorICAgICAgICAgICAgICAgICAgICBib29sIFNraXBUYXJnZXRJbmRlcGVuZGVudElTZWwgPSBmYWxzZSk7CisKKyAgLy8vIFxicmllZiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGFyZ2V0LWluZGVwZW5kZW50IGNvZGUgd2hlbiB0aGUgbm9ybWFsCisgIC8vLyBGYXN0SVNlbCBwcm9jZXNzIGZhaWxzIHRvIHNlbGVjdCBhbiBpbnN0cnVjdGlvbi4gVGhpcyBnaXZlcyB0YXJnZXRzIGEKKyAgLy8vIGNoYW5jZSB0byBlbWl0IGNvZGUgZm9yIGFueXRoaW5nIHRoYXQgZG9lc24ndCBmaXQgaW50byBGYXN0SVNlbCdzCisgIC8vLyBmcmFtZXdvcmsuIEl0IHJldHVybnMgdHJ1ZSBpZiBpdCB3YXMgc3VjY2Vzc2Z1bC4KKyAgdmlydHVhbCBib29sIGZhc3RTZWxlY3RJbnN0cnVjdGlvbihjb25zdCBJbnN0cnVjdGlvbiAqSSkgPSAwOworCisgIC8vLyBcYnJpZWYgVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRhcmdldC1pbmRlcGVuZGVudCBjb2RlIHRvIGRvIHRhcmdldC0KKyAgLy8vIHNwZWNpZmljIGFyZ3VtZW50IGxvd2VyaW5nLiBJdCByZXR1cm5zIHRydWUgaWYgaXQgd2FzIHN1Y2Nlc3NmdWwuCisgIHZpcnR1YWwgYm9vbCBmYXN0TG93ZXJBcmd1bWVudHMoKTsKKworICAvLy8gXGJyaWVmIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0YXJnZXQtaW5kZXBlbmRlbnQgY29kZSB0byBkbyB0YXJnZXQtCisgIC8vLyBzcGVjaWZpYyBjYWxsIGxvd2VyaW5nLiBJdCByZXR1cm5zIHRydWUgaWYgaXQgd2FzIHN1Y2Nlc3NmdWwuCisgIHZpcnR1YWwgYm9vbCBmYXN0TG93ZXJDYWxsKENhbGxMb3dlcmluZ0luZm8gJkNMSSk7CisKKyAgLy8vIFxicmllZiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGFyZ2V0LWluZGVwZW5kZW50IGNvZGUgdG8gZG8gdGFyZ2V0LQorICAvLy8gc3BlY2lmaWMgaW50cmluc2ljIGxvd2VyaW5nLiBJdCByZXR1cm5zIHRydWUgaWYgaXQgd2FzIHN1Y2Nlc3NmdWwuCisgIHZpcnR1YWwgYm9vbCBmYXN0TG93ZXJJbnRyaW5zaWNDYWxsKGNvbnN0IEludHJpbnNpY0luc3QgKklJKTsKKworICAvLy8gXGJyaWVmIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0YXJnZXQtaW5kZXBlbmRlbnQgY29kZSB0byByZXF1ZXN0IHRoYXQgYW4KKyAgLy8vIGluc3RydWN0aW9uIHdpdGggdGhlIGdpdmVuIHR5cGUgYW5kIG9wY29kZSBiZSBlbWl0dGVkLgorICB2aXJ0dWFsIHVuc2lnbmVkIGZhc3RFbWl0XyhNVlQgVlQsIE1WVCBSZXRWVCwgdW5zaWduZWQgT3Bjb2RlKTsKKworICAvLy8gXGJyaWVmIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0YXJnZXQtaW5kZXBlbmRlbnQgY29kZSB0byByZXF1ZXN0IHRoYXQgYW4KKyAgLy8vIGluc3RydWN0aW9uIHdpdGggdGhlIGdpdmVuIHR5cGUsIG9wY29kZSwgYW5kIHJlZ2lzdGVyIG9wZXJhbmQgYmUgZW1pdHRlZC4KKyAgdmlydHVhbCB1bnNpZ25lZCBmYXN0RW1pdF9yKE1WVCBWVCwgTVZUIFJldFZULCB1bnNpZ25lZCBPcGNvZGUsIHVuc2lnbmVkIE9wMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgT3AwSXNLaWxsKTsKKworICAvLy8gXGJyaWVmIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0YXJnZXQtaW5kZXBlbmRlbnQgY29kZSB0byByZXF1ZXN0IHRoYXQgYW4KKyAgLy8vIGluc3RydWN0aW9uIHdpdGggdGhlIGdpdmVuIHR5cGUsIG9wY29kZSwgYW5kIHJlZ2lzdGVyIG9wZXJhbmRzIGJlIGVtaXR0ZWQuCisgIHZpcnR1YWwgdW5zaWduZWQgZmFzdEVtaXRfcnIoTVZUIFZULCBNVlQgUmV0VlQsIHVuc2lnbmVkIE9wY29kZSwgdW5zaWduZWQgT3AwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgT3AwSXNLaWxsLCB1bnNpZ25lZCBPcDEsIGJvb2wgT3AxSXNLaWxsKTsKKworICAvLy8gXGJyaWVmIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0YXJnZXQtaW5kZXBlbmRlbnQgY29kZSB0byByZXF1ZXN0IHRoYXQgYW4KKyAgLy8vIGluc3RydWN0aW9uIHdpdGggdGhlIGdpdmVuIHR5cGUsIG9wY29kZSwgYW5kIHJlZ2lzdGVyIGFuZCBpbW1lZGlhdGUKKyAgLy8vIG9wZXJhbmRzIGJlIGVtaXR0ZWQuCisgIHZpcnR1YWwgdW5zaWduZWQgZmFzdEVtaXRfcmkoTVZUIFZULCBNVlQgUmV0VlQsIHVuc2lnbmVkIE9wY29kZSwgdW5zaWduZWQgT3AwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgT3AwSXNLaWxsLCB1aW50NjRfdCBJbW0pOworCisgIC8vLyBcYnJpZWYgVGhpcyBtZXRob2QgaXMgYSB3cmFwcGVyIG9mIGZhc3RFbWl0X3JpLgorICAvLy8KKyAgLy8vIEl0IGZpcnN0IHRyaWVzIHRvIGVtaXQgYW4gaW5zdHJ1Y3Rpb24gd2l0aCBhbiBpbW1lZGlhdGUgb3BlcmFuZCB1c2luZworICAvLy8gZmFzdEVtaXRfcmkuICBJZiB0aGF0IGZhaWxzLCBpdCBtYXRlcmlhbGl6ZXMgdGhlIGltbWVkaWF0ZSBpbnRvIGEgcmVnaXN0ZXIKKyAgLy8vIGFuZCB0cnkgZmFzdEVtaXRfcnIgaW5zdGVhZC4KKyAgdW5zaWduZWQgZmFzdEVtaXRfcmlfKE1WVCBWVCwgdW5zaWduZWQgT3Bjb2RlLCB1bnNpZ25lZCBPcDAsIGJvb2wgT3AwSXNLaWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgdWludDY0X3QgSW1tLCBNVlQgSW1tVHlwZSk7CisKKyAgLy8vIFxicmllZiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgYnkgdGFyZ2V0LWluZGVwZW5kZW50IGNvZGUgdG8gcmVxdWVzdCB0aGF0IGFuCisgIC8vLyBpbnN0cnVjdGlvbiB3aXRoIHRoZSBnaXZlbiB0eXBlLCBvcGNvZGUsIGFuZCBpbW1lZGlhdGUgb3BlcmFuZCBiZSBlbWl0dGVkLgorICB2aXJ0dWFsIHVuc2lnbmVkIGZhc3RFbWl0X2koTVZUIFZULCBNVlQgUmV0VlQsIHVuc2lnbmVkIE9wY29kZSwgdWludDY0X3QgSW1tKTsKKworICAvLy8gXGJyaWVmIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0YXJnZXQtaW5kZXBlbmRlbnQgY29kZSB0byByZXF1ZXN0IHRoYXQgYW4KKyAgLy8vIGluc3RydWN0aW9uIHdpdGggdGhlIGdpdmVuIHR5cGUsIG9wY29kZSwgYW5kIGZsb2F0aW5nLXBvaW50IGltbWVkaWF0ZQorICAvLy8gb3BlcmFuZCBiZSBlbWl0dGVkLgorICB2aXJ0dWFsIHVuc2lnbmVkIGZhc3RFbWl0X2YoTVZUIFZULCBNVlQgUmV0VlQsIHVuc2lnbmVkIE9wY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENvbnN0YW50RlAgKkZQSW1tKTsKKworICAvLy8gXGJyaWVmIEVtaXQgYSBNYWNoaW5lSW5zdHIgd2l0aCBubyBvcGVyYW5kcyBhbmQgYSByZXN1bHQgcmVnaXN0ZXIgaW4gdGhlCisgIC8vLyBnaXZlbiByZWdpc3RlciBjbGFzcy4KKyAgdW5zaWduZWQgZmFzdEVtaXRJbnN0Xyh1bnNpZ25lZCBNYWNoaW5lSW5zdE9wY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQyk7CisKKyAgLy8vIFxicmllZiBFbWl0IGEgTWFjaGluZUluc3RyIHdpdGggb25lIHJlZ2lzdGVyIG9wZXJhbmQgYW5kIGEgcmVzdWx0IHJlZ2lzdGVyCisgIC8vLyBpbiB0aGUgZ2l2ZW4gcmVnaXN0ZXIgY2xhc3MuCisgIHVuc2lnbmVkIGZhc3RFbWl0SW5zdF9yKHVuc2lnbmVkIE1hY2hpbmVJbnN0T3Bjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQywgdW5zaWduZWQgT3AwLAorICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIE9wMElzS2lsbCk7CisKKyAgLy8vIFxicmllZiBFbWl0IGEgTWFjaGluZUluc3RyIHdpdGggdHdvIHJlZ2lzdGVyIG9wZXJhbmRzIGFuZCBhIHJlc3VsdAorICAvLy8gcmVnaXN0ZXIgaW4gdGhlIGdpdmVuIHJlZ2lzdGVyIGNsYXNzLgorICB1bnNpZ25lZCBmYXN0RW1pdEluc3RfcnIodW5zaWduZWQgTWFjaGluZUluc3RPcGNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQywgdW5zaWduZWQgT3AwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBPcDBJc0tpbGwsIHVuc2lnbmVkIE9wMSwgYm9vbCBPcDFJc0tpbGwpOworCisgIC8vLyBcYnJpZWYgRW1pdCBhIE1hY2hpbmVJbnN0ciB3aXRoIHRocmVlIHJlZ2lzdGVyIG9wZXJhbmRzIGFuZCBhIHJlc3VsdAorICAvLy8gcmVnaXN0ZXIgaW4gdGhlIGdpdmVuIHJlZ2lzdGVyIGNsYXNzLgorICB1bnNpZ25lZCBmYXN0RW1pdEluc3RfcnJyKHVuc2lnbmVkIE1hY2hpbmVJbnN0T3Bjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDLCB1bnNpZ25lZCBPcDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBPcDBJc0tpbGwsIHVuc2lnbmVkIE9wMSwgYm9vbCBPcDFJc0tpbGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgT3AyLCBib29sIE9wMklzS2lsbCk7CisKKyAgLy8vIFxicmllZiBFbWl0IGEgTWFjaGluZUluc3RyIHdpdGggYSByZWdpc3RlciBvcGVyYW5kLCBhbiBpbW1lZGlhdGUsIGFuZCBhCisgIC8vLyByZXN1bHQgcmVnaXN0ZXIgaW4gdGhlIGdpdmVuIHJlZ2lzdGVyIGNsYXNzLgorICB1bnNpZ25lZCBmYXN0RW1pdEluc3RfcmkodW5zaWduZWQgTWFjaGluZUluc3RPcGNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQywgdW5zaWduZWQgT3AwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBPcDBJc0tpbGwsIHVpbnQ2NF90IEltbSk7CisKKyAgLy8vIFxicmllZiBFbWl0IGEgTWFjaGluZUluc3RyIHdpdGggb25lIHJlZ2lzdGVyIG9wZXJhbmQgYW5kIHR3byBpbW1lZGlhdGUKKyAgLy8vIG9wZXJhbmRzLgorICB1bnNpZ25lZCBmYXN0RW1pdEluc3RfcmlpKHVuc2lnbmVkIE1hY2hpbmVJbnN0T3Bjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDLCB1bnNpZ25lZCBPcDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBPcDBJc0tpbGwsIHVpbnQ2NF90IEltbTEsIHVpbnQ2NF90IEltbTIpOworCisgIC8vLyBcYnJpZWYgRW1pdCBhIE1hY2hpbmVJbnN0ciB3aXRoIGEgZmxvYXRpbmcgcG9pbnQgaW1tZWRpYXRlLCBhbmQgYSByZXN1bHQKKyAgLy8vIHJlZ2lzdGVyIGluIHRoZSBnaXZlbiByZWdpc3RlciBjbGFzcy4KKyAgdW5zaWduZWQgZmFzdEVtaXRJbnN0X2YodW5zaWduZWQgTWFjaGluZUluc3RPcGNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDb25zdGFudEZQICpGUEltbSk7CisKKyAgLy8vIFxicmllZiBFbWl0IGEgTWFjaGluZUluc3RyIHdpdGggdHdvIHJlZ2lzdGVyIG9wZXJhbmRzLCBhbiBpbW1lZGlhdGUsIGFuZCBhCisgIC8vLyByZXN1bHQgcmVnaXN0ZXIgaW4gdGhlIGdpdmVuIHJlZ2lzdGVyIGNsYXNzLgorICB1bnNpZ25lZCBmYXN0RW1pdEluc3RfcnJpKHVuc2lnbmVkIE1hY2hpbmVJbnN0T3Bjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDLCB1bnNpZ25lZCBPcDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBPcDBJc0tpbGwsIHVuc2lnbmVkIE9wMSwgYm9vbCBPcDFJc0tpbGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDY0X3QgSW1tKTsKKworICAvLy8gXGJyaWVmIEVtaXQgYSBNYWNoaW5lSW5zdHIgd2l0aCBhIHNpbmdsZSBpbW1lZGlhdGUgb3BlcmFuZCwgYW5kIGEgcmVzdWx0CisgIC8vLyByZWdpc3RlciBpbiB0aGUgZ2l2ZW4gcmVnaXN0ZXIgY2xhc3MuCisgIHVuc2lnbmVkIGZhc3RFbWl0SW5zdF9pKHVuc2lnbmVkIE1hY2hpbmVJbnN0ck9wY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUkMsIHVpbnQ2NF90IEltbSk7CisKKyAgLy8vIFxicmllZiBFbWl0IGEgTWFjaGluZUluc3RyIGZvciBhbiBleHRyYWN0X3N1YnJlZyBmcm9tIGEgc3BlY2lmaWVkIGluZGV4IG9mCisgIC8vLyBhIHN1cGVycmVnaXN0ZXIgdG8gYSBzcGVjaWZpZWQgdHlwZS4KKyAgdW5zaWduZWQgZmFzdEVtaXRJbnN0X2V4dHJhY3RzdWJyZWcoTVZUIFJldFZULCB1bnNpZ25lZCBPcDAsIGJvb2wgT3AwSXNLaWxsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBJZHgpOworCisgIC8vLyBcYnJpZWYgRW1pdCBNYWNoaW5lSW5zdHJzIHRvIGNvbXB1dGUgdGhlIHZhbHVlIG9mIE9wIHdpdGggYWxsIGJ1dCB0aGUKKyAgLy8vIGxlYXN0IHNpZ25pZmljYW50IGJpdCBzZXQgdG8gemVyby4KKyAgdW5zaWduZWQgZmFzdEVtaXRaRXh0RnJvbUkxKE1WVCBWVCwgdW5zaWduZWQgT3AwLCBib29sIE9wMElzS2lsbCk7CisKKyAgLy8vIFxicmllZiBFbWl0IGFuIHVuY29uZGl0aW9uYWwgYnJhbmNoIHRvIHRoZSBnaXZlbiBibG9jaywgdW5sZXNzIGl0IGlzIHRoZQorICAvLy8gaW1tZWRpYXRlIChmYWxsLXRocm91Z2gpIHN1Y2Nlc3NvciwgYW5kIHVwZGF0ZSB0aGUgQ0ZHLgorICB2b2lkIGZhc3RFbWl0QnJhbmNoKE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIsIGNvbnN0IERlYnVnTG9jICZETCk7CisKKyAgLy8vIEVtaXQgYW4gdW5jb25kaXRpb25hbCBicmFuY2ggdG8gXHAgRmFsc2VNQkIsIG9idGFpbnMgdGhlIGJyYW5jaCB3ZWlnaHQKKyAgLy8vIGFuZCBhZGRzIFRydWVNQkIgYW5kIEZhbHNlTUJCIHRvIHRoZSBzdWNjZXNzb3IgbGlzdC4KKyAgdm9pZCBmaW5pc2hDb25kQnJhbmNoKGNvbnN0IEJhc2ljQmxvY2sgKkJyYW5jaEJCLCBNYWNoaW5lQmFzaWNCbG9jayAqVHJ1ZU1CQiwKKyAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpGYWxzZU1CQik7CisKKyAgLy8vIFxicmllZiBVcGRhdGUgdGhlIHZhbHVlIG1hcCB0byBpbmNsdWRlIHRoZSBuZXcgbWFwcGluZyBmb3IgdGhpcworICAvLy8gaW5zdHJ1Y3Rpb24sIG9yIGluc2VydCBhbiBleHRyYSBjb3B5IHRvIGdldCB0aGUgcmVzdWx0IGluIGEgcHJldmlvdXMKKyAgLy8vIGRldGVybWluZWQgcmVnaXN0ZXIuCisgIC8vLworICAvLy8gTk9URTogVGhpcyBpcyBvbmx5IG5lY2Vzc2FyeSBiZWNhdXNlIHdlIG1pZ2h0IHNlbGVjdCBhIGJsb2NrIHRoYXQgdXNlcyBhCisgIC8vLyB2YWx1ZSBiZWZvcmUgd2Ugc2VsZWN0IHRoZSBibG9jayB0aGF0IGRlZmluZXMgdGhlIHZhbHVlLiBJdCBtaWdodCBiZQorICAvLy8gcG9zc2libGUgdG8gZml4IHRoaXMgYnkgc2VsZWN0aW5nIGJsb2NrcyBpbiByZXZlcnNlIHBvc3RvcmRlci4KKyAgdm9pZCB1cGRhdGVWYWx1ZU1hcChjb25zdCBWYWx1ZSAqSSwgdW5zaWduZWQgUmVnLCB1bnNpZ25lZCBOdW1SZWdzID0gMSk7CisKKyAgdW5zaWduZWQgY3JlYXRlUmVzdWx0UmVnKGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKTsKKworICAvLy8gXGJyaWVmIFRyeSB0byBjb25zdHJhaW4gT3Agc28gdGhhdCBpdCBpcyB1c2FibGUgYnkgYXJndW1lbnQgT3BOdW0gb2YgdGhlCisgIC8vLyBwcm92aWRlZCBNQ0luc3RyRGVzYy4gSWYgdGhpcyBmYWlscywgY3JlYXRlIGEgbmV3IHZpcnR1YWwgcmVnaXN0ZXIgaW4gdGhlCisgIC8vLyBjb3JyZWN0IGNsYXNzIGFuZCBDT1BZIHRoZSB2YWx1ZSB0aGVyZS4KKyAgdW5zaWduZWQgY29uc3RyYWluT3BlcmFuZFJlZ0NsYXNzKGNvbnN0IE1DSW5zdHJEZXNjICZJSSwgdW5zaWduZWQgT3AsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBPcE51bSk7CisKKyAgLy8vIFxicmllZiBFbWl0IGEgY29uc3RhbnQgaW4gYSByZWdpc3RlciB1c2luZyB0YXJnZXQtc3BlY2lmaWMgbG9naWMsIHN1Y2ggYXMKKyAgLy8vIGNvbnN0YW50IHBvb2wgbG9hZHMuCisgIHZpcnR1YWwgdW5zaWduZWQgZmFzdE1hdGVyaWFsaXplQ29uc3RhbnQoY29uc3QgQ29uc3RhbnQgKkMpIHsgcmV0dXJuIDA7IH0KKworICAvLy8gXGJyaWVmIEVtaXQgYW4gYWxsb2NhIGFkZHJlc3MgaW4gYSByZWdpc3RlciB1c2luZyB0YXJnZXQtc3BlY2lmaWMgbG9naWMuCisgIHZpcnR1YWwgdW5zaWduZWQgZmFzdE1hdGVyaWFsaXplQWxsb2NhKGNvbnN0IEFsbG9jYUluc3QgKkMpIHsgcmV0dXJuIDA7IH0KKworICAvLy8gXGJyaWVmIEVtaXQgdGhlIGZsb2F0aW5nLXBvaW50IGNvbnN0YW50ICswLjAgaW4gYSByZWdpc3RlciB1c2luZyB0YXJnZXQtCisgIC8vLyBzcGVjaWZpYyBsb2dpYy4KKyAgdmlydHVhbCB1bnNpZ25lZCBmYXN0TWF0ZXJpYWxpemVGbG9hdFplcm8oY29uc3QgQ29uc3RhbnRGUCAqQ0YpIHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIC8vLyBcYnJpZWYgQ2hlY2sgaWYgXGMgQWRkIGlzIGFuIGFkZCB0aGF0IGNhbiBiZSBzYWZlbHkgZm9sZGVkIGludG8gXGMgR0VQLgorICAvLy8KKyAgLy8vIFxjIEFkZCBjYW4gYmUgZm9sZGVkIGludG8gXGMgR0VQIGlmOgorICAvLy8gLSBcYyBBZGQgaXMgYW4gYWRkLAorICAvLy8gLSBcYyBBZGQncyBzaXplIG1hdGNoZXMgXGMgR0VQJ3MsCisgIC8vLyAtIFxjIEFkZCBpcyBpbiB0aGUgc2FtZSBiYXNpYyBibG9jayBhcyBcYyBHRVAsIGFuZAorICAvLy8gLSBcYyBBZGQgaGFzIGEgY29uc3RhbnQgb3BlcmFuZC4KKyAgYm9vbCBjYW5Gb2xkQWRkSW50b0dFUChjb25zdCBVc2VyICpHRVAsIGNvbnN0IFZhbHVlICpBZGQpOworCisgIC8vLyBcYnJpZWYgVGVzdCB3aGV0aGVyIHRoZSBnaXZlbiB2YWx1ZSBoYXMgZXhhY3RseSBvbmUgdXNlLgorICBib29sIGhhc1RyaXZpYWxLaWxsKGNvbnN0IFZhbHVlICpWKTsKKworICAvLy8gXGJyaWVmIENyZWF0ZSBhIG1hY2hpbmUgbWVtIG9wZXJhbmQgZnJvbSB0aGUgZ2l2ZW4gaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVNZW1PcGVyYW5kICpjcmVhdGVNYWNoaW5lTWVtT3BlcmFuZEZvcihjb25zdCBJbnN0cnVjdGlvbiAqSSkgY29uc3Q7CisKKyAgQ21wSW5zdDo6UHJlZGljYXRlIG9wdGltaXplQ21wUHJlZGljYXRlKGNvbnN0IENtcEluc3QgKkNJKSBjb25zdDsKKworICBib29sIGxvd2VyQ2FsbFRvKGNvbnN0IENhbGxJbnN0ICpDSSwgTUNTeW1ib2wgKlN5bWJvbCwgdW5zaWduZWQgTnVtQXJncyk7CisgIGJvb2wgbG93ZXJDYWxsVG8oY29uc3QgQ2FsbEluc3QgKkNJLCBjb25zdCBjaGFyICpTeW1ib2xOYW1lLAorICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIE51bUFyZ3MpOworICBib29sIGxvd2VyQ2FsbFRvKENhbGxMb3dlcmluZ0luZm8gJkNMSSk7CisKKyAgYm9vbCBpc0NvbW11dGF0aXZlSW50cmluc2ljKEludHJpbnNpY0luc3QgY29uc3QgKklJKSB7CisgICAgc3dpdGNoIChJSS0+Z2V0SW50cmluc2ljSUQoKSkgeworICAgIGNhc2UgSW50cmluc2ljOjpzYWRkX3dpdGhfb3ZlcmZsb3c6CisgICAgY2FzZSBJbnRyaW5zaWM6OnVhZGRfd2l0aF9vdmVyZmxvdzoKKyAgICBjYXNlIEludHJpbnNpYzo6c211bF93aXRoX292ZXJmbG93OgorICAgIGNhc2UgSW50cmluc2ljOjp1bXVsX3dpdGhfb3ZlcmZsb3c6CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKyAgfQorCisgIGJvb2wgbG93ZXJDYWxsKGNvbnN0IENhbGxJbnN0ICpJKTsKKyAgLy8vIFxicmllZiBTZWxlY3QgYW5kIGVtaXQgY29kZSBmb3IgYSBiaW5hcnkgb3BlcmF0b3IgaW5zdHJ1Y3Rpb24sIHdoaWNoIGhhcworICAvLy8gYW4gb3Bjb2RlIHdoaWNoIGRpcmVjdGx5IGNvcnJlc3BvbmRzIHRvIHRoZSBnaXZlbiBJU0Qgb3Bjb2RlLgorICBib29sIHNlbGVjdEJpbmFyeU9wKGNvbnN0IFVzZXIgKkksIHVuc2lnbmVkIElTRE9wY29kZSk7CisgIGJvb2wgc2VsZWN0Rk5lZyhjb25zdCBVc2VyICpJKTsKKyAgYm9vbCBzZWxlY3RHZXRFbGVtZW50UHRyKGNvbnN0IFVzZXIgKkkpOworICBib29sIHNlbGVjdFN0YWNrbWFwKGNvbnN0IENhbGxJbnN0ICpJKTsKKyAgYm9vbCBzZWxlY3RQYXRjaHBvaW50KGNvbnN0IENhbGxJbnN0ICpJKTsKKyAgYm9vbCBzZWxlY3RDYWxsKGNvbnN0IFVzZXIgKkNhbGwpOworICBib29sIHNlbGVjdEludHJpbnNpY0NhbGwoY29uc3QgSW50cmluc2ljSW5zdCAqSUkpOworICBib29sIHNlbGVjdEJpdENhc3QoY29uc3QgVXNlciAqSSk7CisgIGJvb2wgc2VsZWN0Q2FzdChjb25zdCBVc2VyICpJLCB1bnNpZ25lZCBPcGNvZGUpOworICBib29sIHNlbGVjdEV4dHJhY3RWYWx1ZShjb25zdCBVc2VyICpJKTsKKyAgYm9vbCBzZWxlY3RJbnNlcnRWYWx1ZShjb25zdCBVc2VyICpJKTsKKyAgYm9vbCBzZWxlY3RYUmF5Q3VzdG9tRXZlbnQoY29uc3QgQ2FsbEluc3QgKklJKTsKKworcHJpdmF0ZToKKyAgLy8vIFxicmllZiBIYW5kbGUgUEhJIG5vZGVzIGluIHN1Y2Nlc3NvciBibG9ja3MuCisgIC8vLworICAvLy8gRW1pdCBjb2RlIHRvIGVuc3VyZSBjb25zdGFudHMgYXJlIGNvcGllZCBpbnRvIHJlZ2lzdGVycyB3aGVuIG5lZWRlZC4KKyAgLy8vIFJlbWVtYmVyIHRoZSB2aXJ0dWFsIHJlZ2lzdGVycyB0aGF0IG5lZWQgdG8gYmUgYWRkZWQgdG8gdGhlIE1hY2hpbmUgUEhJCisgIC8vLyBub2RlcyBhcyBpbnB1dC4gIFdlIGNhbm5vdCBqdXN0IGRpcmVjdGx5IGFkZCB0aGVtLCBiZWNhdXNlIGV4cGFuc2lvbiBtaWdodAorICAvLy8gcmVzdWx0IGluIG11bHRpcGxlIE1CQidzIGZvciBvbmUgQkIuICBBcyBzdWNoLCB0aGUgc3RhcnQgb2YgdGhlIEJCIG1pZ2h0CisgIC8vLyBjb3JyZXNwb25kIHRvIGEgZGlmZmVyZW50IE1CQiB0aGFuIHRoZSBlbmQuCisgIGJvb2wgaGFuZGxlUEhJTm9kZXNJblN1Y2Nlc3NvckJsb2Nrcyhjb25zdCBCYXNpY0Jsb2NrICpMTFZNQkIpOworCisgIC8vLyBcYnJpZWYgSGVscGVyIGZvciBtYXRlcmlhbGl6ZVJlZ0ZvclZhbHVlIHRvIG1hdGVyaWFsaXplIGEgY29uc3RhbnQgaW4gYQorICAvLy8gdGFyZ2V0LWluZGVwZW5kZW50IHdheS4KKyAgdW5zaWduZWQgbWF0ZXJpYWxpemVDb25zdGFudChjb25zdCBWYWx1ZSAqViwgTVZUIFZUKTsKKworICAvLy8gXGJyaWVmIEhlbHBlciBmb3IgZ2V0UmVnRm9yVmFsZS4gVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgd2hlbiB0aGUgdmFsdWUKKyAgLy8vIGlzbid0IGFscmVhZHkgYXZhaWxhYmxlIGluIGEgcmVnaXN0ZXIgYW5kIG11c3QgYmUgbWF0ZXJpYWxpemVkIHdpdGggbmV3CisgIC8vLyBpbnN0cnVjdGlvbnMuCisgIHVuc2lnbmVkIG1hdGVyaWFsaXplUmVnRm9yVmFsdWUoY29uc3QgVmFsdWUgKlYsIE1WVCBWVCk7CisKKyAgLy8vIFxicmllZiBDbGVhcnMgTG9jYWxWYWx1ZU1hcCBhbmQgbW92ZXMgdGhlIGFyZWEgZm9yIHRoZSBuZXcgbG9jYWwgdmFyaWFibGVzCisgIC8vLyB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBibG9jay4gSXQgaGVscHMgdG8gYXZvaWQgc3BpbGxpbmcgY2FjaGVkIHZhcmlhYmxlcworICAvLy8gYWNyb3NzIGhlYXZ5IGluc3RydWN0aW9ucyBsaWtlIGNhbGxzLgorICB2b2lkIGZsdXNoTG9jYWxWYWx1ZU1hcCgpOworCisgIC8vLyBcYnJpZWYgUmVtb3ZlcyBkZWFkIGxvY2FsIHZhbHVlIGluc3RydWN0aW9ucyBhZnRlciBTYXZlZExhc3RMb2NhbHZhbHVlLgorICB2b2lkIHJlbW92ZURlYWRMb2NhbFZhbHVlQ29kZShNYWNoaW5lSW5zdHIgKlNhdmVkTGFzdExvY2FsVmFsdWUpOworCisgIHN0cnVjdCBJbnN0T3JkZXJNYXAgeworICAgIERlbnNlTWFwPE1hY2hpbmVJbnN0ciAqLCB1bnNpZ25lZD4gT3JkZXJzOworICAgIE1hY2hpbmVJbnN0ciAqRmlyc3RUZXJtaW5hdG9yID0gbnVsbHB0cjsKKyAgICB1bnNpZ25lZCBGaXJzdFRlcm1pbmF0b3JPcmRlciA9IHN0ZDo6bnVtZXJpY19saW1pdHM8dW5zaWduZWQ+OjptYXgoKTsKKworICAgIHZvaWQgaW5pdGlhbGl6ZShNYWNoaW5lQmFzaWNCbG9jayAqTUJCKTsKKyAgfTsKKworICAvLy8gU2lua3MgdGhlIGxvY2FsIHZhbHVlIG1hdGVyaWFsaXphdGlvbiBpbnN0cnVjdGlvbiBMb2NhbE1JIHRvIGl0cyBmaXJzdCB1c2UKKyAgLy8vIGluIHRoZSBiYXNpYyBibG9jaywgb3IgZGVsZXRlcyBpdCBpZiBpdCBpcyBub3QgdXNlZC4KKyAgdm9pZCBzaW5rTG9jYWxWYWx1ZU1hdGVyaWFsaXphdGlvbihNYWNoaW5lSW5zdHIgJkxvY2FsTUksIHVuc2lnbmVkIERlZlJlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0T3JkZXJNYXAgJk9yZGVyTWFwKTsKKworICAvLy8gXGJyaWVmIEluc2VydGlvbiBwb2ludCBiZWZvcmUgdHJ5aW5nIHRvIHNlbGVjdCB0aGUgY3VycmVudCBpbnN0cnVjdGlvbi4KKyAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIFNhdmVkSW5zZXJ0UHQ7CisKKyAgLy8vIFxicmllZiBBZGQgYSBzdGFja21hcCBvciBwYXRjaHBvaW50IGludHJpbnNpYyBjYWxsJ3MgbGl2ZSB2YXJpYWJsZQorICAvLy8gb3BlcmFuZHMgdG8gYSBzdGFja21hcCBvciBwYXRjaHBvaW50IG1hY2hpbmUgaW5zdHJ1Y3Rpb24uCisgIGJvb2wgYWRkU3RhY2tNYXBMaXZlVmFycyhTbWFsbFZlY3RvckltcGw8TWFjaGluZU9wZXJhbmQ+ICZPcHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDYWxsSW5zdCAqQ0ksIHVuc2lnbmVkIFN0YXJ0SWR4KTsKKyAgYm9vbCBsb3dlckNhbGxPcGVyYW5kcyhjb25zdCBDYWxsSW5zdCAqQ0ksIHVuc2lnbmVkIEFyZ0lkeCwgdW5zaWduZWQgTnVtQXJncywKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBWYWx1ZSAqQ2FsbGVlLCBib29sIEZvcmNlUmV0Vm9pZFR5LAorICAgICAgICAgICAgICAgICAgICAgICAgIENhbGxMb3dlcmluZ0luZm8gJkNMSSk7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0ZBU1RJU0VMX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9GYXVsdE1hcHMuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9GYXVsdE1hcHMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41NWUyNWM5Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0ZhdWx0TWFwcy5oCkBAIC0wLDAgKzEsMjE4IEBACisvLz09PS0gRmF1bHRNYXBzLmggLSBUaGUgIkZhdWx0TWFwcyIgc2VjdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9GQVVMVE1BUFNfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fRkFVTFRNQVBTX0gKKworI2luY2x1ZGUgImxsdm0vTUMvTUNTeW1ib2wuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvRW5kaWFuLmgiCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkZGVmPgorI2luY2x1ZGUgPGNzdGRpbnQ+CisjaW5jbHVkZSA8bWFwPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBBc21QcmludGVyOworY2xhc3MgTUNFeHByOworY2xhc3MgcmF3X29zdHJlYW07CisKK2NsYXNzIEZhdWx0TWFwcyB7CitwdWJsaWM6CisgIGVudW0gRmF1bHRLaW5kIHsKKyAgICBGYXVsdGluZ0xvYWQgPSAxLAorICAgIEZhdWx0aW5nTG9hZFN0b3JlLAorICAgIEZhdWx0aW5nU3RvcmUsCisgICAgRmF1bHRLaW5kTWF4CisgIH07CisKKyAgZXhwbGljaXQgRmF1bHRNYXBzKEFzbVByaW50ZXIgJkFQKTsKKworICBzdGF0aWMgY29uc3QgY2hhciAqZmF1bHRUeXBlVG9TdHJpbmcoRmF1bHRLaW5kKTsKKworICB2b2lkIHJlY29yZEZhdWx0aW5nT3AoRmF1bHRLaW5kIEZhdWx0VHksIGNvbnN0IE1DU3ltYm9sICpIYW5kbGVyTGFiZWwpOworICB2b2lkIHNlcmlhbGl6ZVRvRmF1bHRNYXBTZWN0aW9uKCk7CisgIHZvaWQgcmVzZXQoKSB7CisgICAgRnVuY3Rpb25JbmZvcy5jbGVhcigpOworICB9CisKK3ByaXZhdGU6CisgIHN0YXRpYyBjb25zdCBjaGFyICpXRk1QOworCisgIHN0cnVjdCBGYXVsdEluZm8geworICAgIEZhdWx0S2luZCBLaW5kID0gRmF1bHRLaW5kTWF4OworICAgIGNvbnN0IE1DRXhwciAqRmF1bHRpbmdPZmZzZXRFeHByID0gbnVsbHB0cjsKKyAgICBjb25zdCBNQ0V4cHIgKkhhbmRsZXJPZmZzZXRFeHByID0gbnVsbHB0cjsKKworICAgIEZhdWx0SW5mbygpID0gZGVmYXVsdDsKKworICAgIGV4cGxpY2l0IEZhdWx0SW5mbyhGYXVsdE1hcHM6OkZhdWx0S2luZCBLaW5kLCBjb25zdCBNQ0V4cHIgKkZhdWx0aW5nT2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNQ0V4cHIgKkhhbmRsZXJPZmZzZXQpCisgICAgICAgIDogS2luZChLaW5kKSwgRmF1bHRpbmdPZmZzZXRFeHByKEZhdWx0aW5nT2Zmc2V0KSwKKyAgICAgICAgICBIYW5kbGVyT2Zmc2V0RXhwcihIYW5kbGVyT2Zmc2V0KSB7fQorICB9OworCisgIHVzaW5nIEZ1bmN0aW9uRmF1bHRJbmZvcyA9IHN0ZDo6dmVjdG9yPEZhdWx0SW5mbz47CisKKyAgLy8gV2UnZCBsaWtlIHRvIGtlZXAgYSBzdGFibGUgaXRlcmF0aW9uIG9yZGVyIGZvciBGdW5jdGlvbkluZm9zIHRvIGhlbHAKKyAgLy8gRmlsZUNoZWNrIGJhc2VkIHRlc3RpbmcuCisgIHN0cnVjdCBNQ1N5bWJvbENvbXBhcmF0b3IgeworICAgIGJvb2wgb3BlcmF0b3IoKShjb25zdCBNQ1N5bWJvbCAqTEhTLCBjb25zdCBNQ1N5bWJvbCAqUkhTKSBjb25zdCB7CisgICAgICByZXR1cm4gTEhTLT5nZXROYW1lKCkgPCBSSFMtPmdldE5hbWUoKTsKKyAgICB9CisgIH07CisKKyAgc3RkOjptYXA8Y29uc3QgTUNTeW1ib2wgKiwgRnVuY3Rpb25GYXVsdEluZm9zLCBNQ1N5bWJvbENvbXBhcmF0b3I+CisgICAgICBGdW5jdGlvbkluZm9zOworICBBc21QcmludGVyICZBUDsKKworICB2b2lkIGVtaXRGdW5jdGlvbkluZm8oY29uc3QgTUNTeW1ib2wgKkZuTGFiZWwsIGNvbnN0IEZ1bmN0aW9uRmF1bHRJbmZvcyAmRkZJKTsKK307CisKKy8vLyBBIHBhcnNlciBmb3IgdGhlIF9fbGx2bV9mYXVsdG1hcHMgc2VjdGlvbiBnZW5lcmF0ZWQgYnkgdGhlIEZhdWx0TWFwcyBjbGFzcworLy8vIGFib3ZlLiAgVGhpcyBwYXJzZXIgaXMgdmVyc2lvbiBsb2NrZWQgd2l0aCB3aXRoIHRoZSBfX2xsdm1fZmF1bHRtYXBzIHNlY3Rpb24KKy8vLyBnZW5lcmF0ZWQgYnkgdGhlIHZlcnNpb24gb2YgTExWTSB0aGF0IGluY2x1ZGVzIGl0LiAgTm8gZ3VhcmFudGVlcyBhcmUgbWFkZQorLy8vIHdpdGggcmVzcGVjdCB0byBmb3J3YXJkIG9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuCitjbGFzcyBGYXVsdE1hcFBhcnNlciB7CisgIHVzaW5nIEZhdWx0TWFwVmVyc2lvblR5cGUgPSB1aW50OF90OworICB1c2luZyBSZXNlcnZlZDBUeXBlID0gdWludDhfdDsKKyAgdXNpbmcgUmVzZXJ2ZWQxVHlwZSA9IHVpbnQxNl90OworICB1c2luZyBOdW1GdW5jdGlvbnNUeXBlID0gdWludDMyX3Q7CisKKyAgc3RhdGljIGNvbnN0IHNpemVfdCBGYXVsdE1hcFZlcnNpb25PZmZzZXQgPSAwOworICBzdGF0aWMgY29uc3Qgc2l6ZV90IFJlc2VydmVkME9mZnNldCA9CisgICAgICBGYXVsdE1hcFZlcnNpb25PZmZzZXQgKyBzaXplb2YoRmF1bHRNYXBWZXJzaW9uVHlwZSk7CisgIHN0YXRpYyBjb25zdCBzaXplX3QgUmVzZXJ2ZWQxT2Zmc2V0ID0gUmVzZXJ2ZWQwT2Zmc2V0ICsgc2l6ZW9mKFJlc2VydmVkMFR5cGUpOworICBzdGF0aWMgY29uc3Qgc2l6ZV90IE51bUZ1bmN0aW9uc09mZnNldCA9CisgICAgICBSZXNlcnZlZDFPZmZzZXQgKyBzaXplb2YoUmVzZXJ2ZWQxVHlwZSk7CisgIHN0YXRpYyBjb25zdCBzaXplX3QgRnVuY3Rpb25JbmZvc09mZnNldCA9CisgICAgICBOdW1GdW5jdGlvbnNPZmZzZXQgKyBzaXplb2YoTnVtRnVuY3Rpb25zVHlwZSk7CisKKyAgY29uc3QgdWludDhfdCAqUDsKKyAgY29uc3QgdWludDhfdCAqRTsKKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gc3RhdGljIFQgcmVhZChjb25zdCB1aW50OF90ICpQLCBjb25zdCB1aW50OF90ICpFKSB7CisgICAgYXNzZXJ0KFAgKyBzaXplb2YoVCkgPD0gRSAmJiAib3V0IG9mIGJvdW5kcyByZWFkISIpOworICAgIHJldHVybiBzdXBwb3J0OjplbmRpYW46OnJlYWQ8VCwgc3VwcG9ydDo6bGl0dGxlLCAxPihQKTsKKyAgfQorCitwdWJsaWM6CisgIGNsYXNzIEZ1bmN0aW9uRmF1bHRJbmZvQWNjZXNzb3IgeworICAgIHVzaW5nIEZhdWx0S2luZFR5cGUgPSB1aW50MzJfdDsKKyAgICB1c2luZyBGYXVsdGluZ1BDT2Zmc2V0VHlwZSA9IHVpbnQzMl90OworICAgIHVzaW5nIEhhbmRsZXJQQ09mZnNldFR5cGUgPSB1aW50MzJfdDsKKworICAgIHN0YXRpYyBjb25zdCBzaXplX3QgRmF1bHRLaW5kT2Zmc2V0ID0gMDsKKyAgICBzdGF0aWMgY29uc3Qgc2l6ZV90IEZhdWx0aW5nUENPZmZzZXRPZmZzZXQgPQorICAgICAgICBGYXVsdEtpbmRPZmZzZXQgKyBzaXplb2YoRmF1bHRLaW5kVHlwZSk7CisgICAgc3RhdGljIGNvbnN0IHNpemVfdCBIYW5kbGVyUENPZmZzZXRPZmZzZXQgPQorICAgICAgICBGYXVsdGluZ1BDT2Zmc2V0T2Zmc2V0ICsgc2l6ZW9mKEZhdWx0aW5nUENPZmZzZXRUeXBlKTsKKworICAgIGNvbnN0IHVpbnQ4X3QgKlA7CisgICAgY29uc3QgdWludDhfdCAqRTsKKworICBwdWJsaWM6CisgICAgc3RhdGljIGNvbnN0IHNpemVfdCBTaXplID0KKyAgICAgICAgSGFuZGxlclBDT2Zmc2V0T2Zmc2V0ICsgc2l6ZW9mKEhhbmRsZXJQQ09mZnNldFR5cGUpOworCisgICAgZXhwbGljaXQgRnVuY3Rpb25GYXVsdEluZm9BY2Nlc3Nvcihjb25zdCB1aW50OF90ICpQLCBjb25zdCB1aW50OF90ICpFKQorICAgICAgICA6IFAoUCksIEUoRSkge30KKworICAgIEZhdWx0S2luZFR5cGUgZ2V0RmF1bHRLaW5kKCkgY29uc3QgeworICAgICAgcmV0dXJuIHJlYWQ8RmF1bHRLaW5kVHlwZT4oUCArIEZhdWx0S2luZE9mZnNldCwgRSk7CisgICAgfQorCisgICAgRmF1bHRpbmdQQ09mZnNldFR5cGUgZ2V0RmF1bHRpbmdQQ09mZnNldCgpIGNvbnN0IHsKKyAgICAgIHJldHVybiByZWFkPEZhdWx0aW5nUENPZmZzZXRUeXBlPihQICsgRmF1bHRpbmdQQ09mZnNldE9mZnNldCwgRSk7CisgICAgfQorCisgICAgSGFuZGxlclBDT2Zmc2V0VHlwZSBnZXRIYW5kbGVyUENPZmZzZXQoKSBjb25zdCB7CisgICAgICByZXR1cm4gcmVhZDxIYW5kbGVyUENPZmZzZXRUeXBlPihQICsgSGFuZGxlclBDT2Zmc2V0T2Zmc2V0LCBFKTsKKyAgICB9CisgIH07CisKKyAgY2xhc3MgRnVuY3Rpb25JbmZvQWNjZXNzb3IgeworICAgIHVzaW5nIEZ1bmN0aW9uQWRkclR5cGUgPSB1aW50NjRfdDsKKyAgICB1c2luZyBOdW1GYXVsdGluZ1BDc1R5cGUgPSB1aW50MzJfdDsKKyAgICB1c2luZyBSZXNlcnZlZFR5cGUgPSB1aW50MzJfdDsKKworICAgIHN0YXRpYyBjb25zdCBzaXplX3QgRnVuY3Rpb25BZGRyT2Zmc2V0ID0gMDsKKyAgICBzdGF0aWMgY29uc3Qgc2l6ZV90IE51bUZhdWx0aW5nUENzT2Zmc2V0ID0KKyAgICAgICAgRnVuY3Rpb25BZGRyT2Zmc2V0ICsgc2l6ZW9mKEZ1bmN0aW9uQWRkclR5cGUpOworICAgIHN0YXRpYyBjb25zdCBzaXplX3QgUmVzZXJ2ZWRPZmZzZXQgPQorICAgICAgICBOdW1GYXVsdGluZ1BDc09mZnNldCArIHNpemVvZihOdW1GYXVsdGluZ1BDc1R5cGUpOworICAgIHN0YXRpYyBjb25zdCBzaXplX3QgRnVuY3Rpb25GYXVsdEluZm9zT2Zmc2V0ID0KKyAgICAgICAgUmVzZXJ2ZWRPZmZzZXQgKyBzaXplb2YoUmVzZXJ2ZWRUeXBlKTsKKyAgICBzdGF0aWMgY29uc3Qgc2l6ZV90IEZ1bmN0aW9uSW5mb0hlYWRlclNpemUgPSBGdW5jdGlvbkZhdWx0SW5mb3NPZmZzZXQ7CisKKyAgICBjb25zdCB1aW50OF90ICpQID0gbnVsbHB0cjsKKyAgICBjb25zdCB1aW50OF90ICpFID0gbnVsbHB0cjsKKworICBwdWJsaWM6CisgICAgRnVuY3Rpb25JbmZvQWNjZXNzb3IoKSA9IGRlZmF1bHQ7CisKKyAgICBleHBsaWNpdCBGdW5jdGlvbkluZm9BY2Nlc3Nvcihjb25zdCB1aW50OF90ICpQLCBjb25zdCB1aW50OF90ICpFKQorICAgICAgICA6IFAoUCksIEUoRSkge30KKworICAgIEZ1bmN0aW9uQWRkclR5cGUgZ2V0RnVuY3Rpb25BZGRyKCkgY29uc3QgeworICAgICAgcmV0dXJuIHJlYWQ8RnVuY3Rpb25BZGRyVHlwZT4oUCArIEZ1bmN0aW9uQWRkck9mZnNldCwgRSk7CisgICAgfQorCisgICAgTnVtRmF1bHRpbmdQQ3NUeXBlIGdldE51bUZhdWx0aW5nUENzKCkgY29uc3QgeworICAgICAgcmV0dXJuIHJlYWQ8TnVtRmF1bHRpbmdQQ3NUeXBlPihQICsgTnVtRmF1bHRpbmdQQ3NPZmZzZXQsIEUpOworICAgIH0KKworICAgIEZ1bmN0aW9uRmF1bHRJbmZvQWNjZXNzb3IgZ2V0RnVuY3Rpb25GYXVsdEluZm9BdCh1aW50MzJfdCBJbmRleCkgY29uc3QgeworICAgICAgYXNzZXJ0KEluZGV4IDwgZ2V0TnVtRmF1bHRpbmdQQ3MoKSAmJiAiaW5kZXggb3V0IG9mIGJvdW5kcyEiKTsKKyAgICAgIGNvbnN0IHVpbnQ4X3QgKkJlZ2luID0gUCArIEZ1bmN0aW9uRmF1bHRJbmZvc09mZnNldCArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZ1bmN0aW9uRmF1bHRJbmZvQWNjZXNzb3I6OlNpemUgKiBJbmRleDsKKyAgICAgIHJldHVybiBGdW5jdGlvbkZhdWx0SW5mb0FjY2Vzc29yKEJlZ2luLCBFKTsKKyAgICB9CisKKyAgICBGdW5jdGlvbkluZm9BY2Nlc3NvciBnZXROZXh0RnVuY3Rpb25JbmZvKCkgY29uc3QgeworICAgICAgc2l6ZV90IE15U2l6ZSA9IEZ1bmN0aW9uSW5mb0hlYWRlclNpemUgKworICAgICAgICAgICAgICAgICAgICAgIGdldE51bUZhdWx0aW5nUENzKCkgKiBGdW5jdGlvbkZhdWx0SW5mb0FjY2Vzc29yOjpTaXplOworCisgICAgICBjb25zdCB1aW50OF90ICpCZWdpbiA9IFAgKyBNeVNpemU7CisgICAgICBhc3NlcnQoQmVnaW4gPCBFICYmICJvdXQgb2YgYm91bmRzISIpOworICAgICAgcmV0dXJuIEZ1bmN0aW9uSW5mb0FjY2Vzc29yKEJlZ2luLCBFKTsKKyAgICB9CisgIH07CisKKyAgZXhwbGljaXQgRmF1bHRNYXBQYXJzZXIoY29uc3QgdWludDhfdCAqQmVnaW4sIGNvbnN0IHVpbnQ4X3QgKkVuZCkKKyAgICAgIDogUChCZWdpbiksIEUoRW5kKSB7fQorCisgIEZhdWx0TWFwVmVyc2lvblR5cGUgZ2V0RmF1bHRNYXBWZXJzaW9uKCkgY29uc3QgeworICAgIGF1dG8gVmVyc2lvbiA9IHJlYWQ8RmF1bHRNYXBWZXJzaW9uVHlwZT4oUCArIEZhdWx0TWFwVmVyc2lvbk9mZnNldCwgRSk7CisgICAgYXNzZXJ0KFZlcnNpb24gPT0gMSAmJiAib25seSB2ZXJzaW9uIDEgc3VwcG9ydGVkISIpOworICAgIHJldHVybiBWZXJzaW9uOworICB9CisKKyAgTnVtRnVuY3Rpb25zVHlwZSBnZXROdW1GdW5jdGlvbnMoKSBjb25zdCB7CisgICAgcmV0dXJuIHJlYWQ8TnVtRnVuY3Rpb25zVHlwZT4oUCArIE51bUZ1bmN0aW9uc09mZnNldCwgRSk7CisgIH0KKworICBGdW5jdGlvbkluZm9BY2Nlc3NvciBnZXRGaXJzdEZ1bmN0aW9uSW5mbygpIGNvbnN0IHsKKyAgICBjb25zdCB1aW50OF90ICpCZWdpbiA9IFAgKyBGdW5jdGlvbkluZm9zT2Zmc2V0OworICAgIHJldHVybiBGdW5jdGlvbkluZm9BY2Nlc3NvcihCZWdpbiwgRSk7CisgIH0KK307CisKK3Jhd19vc3RyZWFtICYKK29wZXJhdG9yPDwocmF3X29zdHJlYW0gJk9TLCBjb25zdCBGYXVsdE1hcFBhcnNlcjo6RnVuY3Rpb25GYXVsdEluZm9BY2Nlc3NvciAmKTsKKworcmF3X29zdHJlYW0gJm9wZXJhdG9yPDwocmF3X29zdHJlYW0gJk9TLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRmF1bHRNYXBQYXJzZXI6OkZ1bmN0aW9uSW5mb0FjY2Vzc29yICYpOworCityYXdfb3N0cmVhbSAmb3BlcmF0b3I8PChyYXdfb3N0cmVhbSAmT1MsIGNvbnN0IEZhdWx0TWFwUGFyc2VyICYpOworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0ZBVUxUTUFQU19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vRnVuY3Rpb25Mb3dlcmluZ0luZm8uaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9GdW5jdGlvbkxvd2VyaW5nSW5mby5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJkYTAwYjcKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vRnVuY3Rpb25Mb3dlcmluZ0luZm8uaApAQCAtMCwwICsxLDMyNSBAQAorLy89PT0tIEZ1bmN0aW9uTG93ZXJpbmdJbmZvLmggLSBMb3dlciBmdW5jdGlvbnMgZnJvbSBMTFZNIElSIHRvIENvZGVHZW4gLS0tPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGltcGxlbWVudHMgcm91dGluZXMgZm9yIHRyYW5zbGF0aW5nIGZ1bmN0aW9ucyBmcm9tIExMVk0gSVIgaW50bworLy8gTWFjaGluZSBJUi4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9GVU5DVElPTkxPV0VSSU5HSU5GT19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9GVU5DVElPTkxPV0VSSU5HSU5GT19ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9BUEludC5oIgorI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvSW5kZXhlZE1hcC5oIgorI2luY2x1ZGUgImxsdm0vQURUL09wdGlvbmFsLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxQdHJTZXQuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9JU0RPcGNvZGVzLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVCYXNpY0Jsb2NrLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1RhcmdldFJlZ2lzdGVySW5mby5oIgorI2luY2x1ZGUgImxsdm0vSVIvSW5zdHJ1Y3Rpb25zLmgiCisjaW5jbHVkZSAibGx2bS9JUi9UeXBlLmgiCisjaW5jbHVkZSAibGx2bS9JUi9WYWx1ZS5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9Lbm93bkJpdHMuaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8dmVjdG9yPgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIEFyZ3VtZW50OworY2xhc3MgQmFzaWNCbG9jazsKK2NsYXNzIEJyYW5jaFByb2JhYmlsaXR5SW5mbzsKK2NsYXNzIEZ1bmN0aW9uOworY2xhc3MgSW5zdHJ1Y3Rpb247CitjbGFzcyBNYWNoaW5lRnVuY3Rpb247CitjbGFzcyBNYWNoaW5lSW5zdHI7CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworY2xhc3MgTVZUOworY2xhc3MgU2VsZWN0aW9uREFHOworY2xhc3MgVGFyZ2V0TG93ZXJpbmc7CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vIEZ1bmN0aW9uTG93ZXJpbmdJbmZvIC0gVGhpcyBjb250YWlucyBpbmZvcm1hdGlvbiB0aGF0IGlzIGdsb2JhbCB0byBhCisvLy8gZnVuY3Rpb24gdGhhdCBpcyB1c2VkIHdoZW4gbG93ZXJpbmcgYSByZWdpb24gb2YgdGhlIGZ1bmN0aW9uLgorLy8vCitjbGFzcyBGdW5jdGlvbkxvd2VyaW5nSW5mbyB7CitwdWJsaWM6CisgIGNvbnN0IEZ1bmN0aW9uICpGbjsKKyAgTWFjaGluZUZ1bmN0aW9uICpNRjsKKyAgY29uc3QgVGFyZ2V0TG93ZXJpbmcgKlRMSTsKKyAgTWFjaGluZVJlZ2lzdGVySW5mbyAqUmVnSW5mbzsKKyAgQnJhbmNoUHJvYmFiaWxpdHlJbmZvICpCUEk7CisgIC8vLyBDYW5Mb3dlclJldHVybiAtIHRydWUgaWZmIHRoZSBmdW5jdGlvbidzIHJldHVybiB2YWx1ZSBjYW4gYmUgbG93ZXJlZCB0bworICAvLy8gcmVnaXN0ZXJzLgorICBib29sIENhbkxvd2VyUmV0dXJuOworCisgIC8vLyBUcnVlIGlmIHBhcnQgb2YgdGhlIENTUnMgd2lsbCBiZSBoYW5kbGVkIHZpYSBleHBsaWNpdCBjb3BpZXMuCisgIGJvb2wgU3BsaXRDU1I7CisKKyAgLy8vIERlbW90ZVJlZ2lzdGVyIC0gaWYgQ2FuTG93ZXJSZXR1cm4gaXMgZmFsc2UsIERlbW90ZVJlZ2lzdGVyIGlzIGEgdnJlZworICAvLy8gYWxsb2NhdGVkIHRvIGhvbGQgYSBwb2ludGVyIHRvIHRoZSBoaWRkZW4gc3JldCBwYXJhbWV0ZXIuCisgIHVuc2lnbmVkIERlbW90ZVJlZ2lzdGVyOworCisgIC8vLyBNQkJNYXAgLSBBIG1hcHBpbmcgZnJvbSBMTFZNIGJhc2ljIGJsb2NrcyB0byB0aGVpciBtYWNoaW5lIGNvZGUgZW50cnkuCisgIERlbnNlTWFwPGNvbnN0IEJhc2ljQmxvY2sqLCBNYWNoaW5lQmFzaWNCbG9jayAqPiBNQkJNYXA7CisKKyAgLy8vIEEgbWFwIGZyb20gc3dpZnRlcnJvciB2YWx1ZSBpbiBhIGJhc2ljIGJsb2NrIHRvIHRoZSB2aXJ0dWFsIHJlZ2lzdGVyIGl0IGlzCisgIC8vLyBjdXJyZW50bHkgcmVwcmVzZW50ZWQgYnkuCisgIERlbnNlTWFwPHN0ZDo6cGFpcjxjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqLCBjb25zdCBWYWx1ZSAqPiwgdW5zaWduZWQ+CisgICAgICBTd2lmdEVycm9yVlJlZ0RlZk1hcDsKKworICAvLy8gQSBsaXN0IG9mIHVwd2FyZCBleHBvc2VkIHZyZWcgdXNlcyB0aGF0IG5lZWQgdG8gYmUgc2F0aXNmaWVkIGJ5IGVpdGhlciBhCisgIC8vLyBjb3B5IGRlZiBvciBhIHBoaSBub2RlIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGJhc2ljIGJsb2NrIHJlcHJlc2VudGluZworICAvLy8gdGhlIHByZWRlY2Vzc29yKHMpIHN3aWZ0ZXJyb3IgdmFsdWUuCisgIERlbnNlTWFwPHN0ZDo6cGFpcjxjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqLCBjb25zdCBWYWx1ZSAqPiwgdW5zaWduZWQ+CisgICAgICBTd2lmdEVycm9yVlJlZ1Vwd2FyZHNVc2U7CisKKyAgLy8vIEEgbWFwIGZyb20gaW5zdHJ1Y3Rpb25zIHRoYXQgZGVmaW5lL3VzZSBhIHN3aWZ0ZXJyb3IgdmFsdWUgdG8gdGhlIHZpcnR1YWwKKyAgLy8vIHJlZ2lzdGVyIHRoYXQgcmVwcmVzZW50cyB0aGF0IGRlZi91c2UuCisgIGxsdm06OkRlbnNlTWFwPFBvaW50ZXJJbnRQYWlyPGNvbnN0IEluc3RydWN0aW9uICosIDEsIGJvb2w+LCB1bnNpZ25lZD4KKyAgICAgIFN3aWZ0RXJyb3JWUmVnRGVmVXNlczsKKworICAvLy8gVGhlIHN3aWZ0ZXJyb3IgYXJndW1lbnQgb2YgdGhlIGN1cnJlbnQgZnVuY3Rpb24uCisgIGNvbnN0IFZhbHVlICpTd2lmdEVycm9yQXJnOworCisgIHVzaW5nIFN3aWZ0RXJyb3JWYWx1ZXMgPSBTbWFsbFZlY3Rvcjxjb25zdCBWYWx1ZSosIDE+OworICAvLy8gQSBmdW5jdGlvbiBjYW4gb25seSBoYXZlIGEgc2luZ2xlIHN3aWZ0ZXJyb3IgYXJndW1lbnQuIEFuZCBpZiBpdCBkb2VzCisgIC8vLyBoYXZlIGEgc3dpZnRlcnJvciBhcmd1bWVudCwgaXQgbXVzdCBiZSB0aGUgZmlyc3QgZW50cnkgaW4KKyAgLy8vIFN3aWZ0RXJyb3JWYWxzLgorICBTd2lmdEVycm9yVmFsdWVzIFN3aWZ0RXJyb3JWYWxzOworCisgIC8vLyBHZXQgb3IgY3JlYXRlIHRoZSBzd2lmdGVycm9yIHZhbHVlIHZpcnR1YWwgcmVnaXN0ZXIgaW4KKyAgLy8vIFN3aWZ0RXJyb3JWUmVnRGVmTWFwIGZvciB0aGlzIGJhc2ljIGJsb2NrLgorICB1bnNpZ25lZCBnZXRPckNyZWF0ZVN3aWZ0RXJyb3JWUmVnKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICosCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVmFsdWUgKik7CisKKyAgLy8vIFNldCB0aGUgc3dpZnRlcnJvciB2aXJ0dWFsIHJlZ2lzdGVyIGluIHRoZSBTd2lmdEVycm9yVlJlZ0RlZk1hcCBmb3IgdGhpcworICAvLy8gYmFzaWMgYmxvY2suCisgIHZvaWQgc2V0Q3VycmVudFN3aWZ0RXJyb3JWUmVnKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIsIGNvbnN0IFZhbHVlICosCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkKTsKKworICAvLy8gR2V0IG9yIGNyZWF0ZSB0aGUgc3dpZnRlcnJvciB2YWx1ZSB2aXJ0dWFsIHJlZ2lzdGVyIGZvciBhIGRlZiBvZiBhCisgIC8vLyBzd2lmdGVycm9yIGJ5IGFuIGluc3RydWN0aW9uLgorICBzdGQ6OnBhaXI8dW5zaWduZWQsIGJvb2w+IGdldE9yQ3JlYXRlU3dpZnRFcnJvclZSZWdEZWZBdChjb25zdCBJbnN0cnVjdGlvbiAqKTsKKyAgc3RkOjpwYWlyPHVuc2lnbmVkLCBib29sPgorICBnZXRPckNyZWF0ZVN3aWZ0RXJyb3JWUmVnVXNlQXQoY29uc3QgSW5zdHJ1Y3Rpb24gKiwgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFZhbHVlICopOworCisgIC8vLyBWYWx1ZU1hcCAtIFNpbmNlIHdlIGVtaXQgY29kZSBmb3IgdGhlIGZ1bmN0aW9uIGEgYmFzaWMgYmxvY2sgYXQgYSB0aW1lLAorICAvLy8gd2UgbXVzdCByZW1lbWJlciB3aGljaCB2aXJ0dWFsIHJlZ2lzdGVycyBob2xkIHRoZSB2YWx1ZXMgZm9yCisgIC8vLyBjcm9zcy1iYXNpYy1ibG9jayB2YWx1ZXMuCisgIERlbnNlTWFwPGNvbnN0IFZhbHVlICosIHVuc2lnbmVkPiBWYWx1ZU1hcDsKKworICAvLy8gVmlydFJlZzJWYWx1ZSBtYXAgaXMgbmVlZGVkIGJ5IHRoZSBEaXZlcmdlbmNlIEFuYWx5c2lzIGRyaXZlbgorICAvLy8gaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uLiBJdCBpcyByZXZlcnRlZCBWYWx1ZU1hcC4gSXQgaXMgY29tcHV0ZWQKKyAgLy8vIGluIGxhenkgc3R5bGUgLSBvbiBkZW1hbmQuIEl0IGlzIHVzZWQgdG8gZ2V0IHRoZSBWYWx1ZSBjb3JyZXNwb25kaW5nCisgIC8vLyB0byB0aGUgbGl2ZSBpbiB2aXJ0dWFsIHJlZ2lzdGVyIGFuZCBpcyBjYWxsZWQgZnJvbSB0aGUKKyAgLy8vIFRhcmdldExvd2VyaW5JbmZvOjppc1NETm9kZVNvdXJjZU9mRGl2ZXJnZW5jZS4KKyAgRGVuc2VNYXA8dW5zaWduZWQsIGNvbnN0IFZhbHVlKj4gVmlydFJlZzJWYWx1ZTsKKworICAvLy8gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGZyb20gVGFyZ2V0TG93ZXJpbkluZm86OmlzU0ROb2RlU291cmNlT2ZEaXZlcmdlbmNlCisgIC8vLyB0byBnZXQgdGhlIFZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGxpdmUtaW4gdmlydHVhbCByZWdpc3Rlci4KKyAgY29uc3QgVmFsdWUgKiBnZXRWYWx1ZUZyb21WaXJ0dWFsUmVnKHVuc2lnbmVkIFZyZWcpOworCisgIC8vLyBUcmFjayB2aXJ0dWFsIHJlZ2lzdGVycyBjcmVhdGVkIGZvciBleGNlcHRpb24gcG9pbnRlcnMuCisgIERlbnNlTWFwPGNvbnN0IFZhbHVlICosIHVuc2lnbmVkPiBDYXRjaFBhZEV4Y2VwdGlvblBvaW50ZXJzOworCisgIC8vLyBLZWVwIHRyYWNrIG9mIGZyYW1lIGluZGljZXMgYWxsb2NhdGVkIGZvciBzdGF0ZXBvaW50cyBhcyB0aGV5IGNvdWxkIGJlCisgIC8vLyB1c2VkIGFjcm9zcyBiYXNpYyBibG9jayBib3VuZGFyaWVzLiAgVGhpcyBzdHJ1Y3QgaXMgbW9yZSBjb21wbGV4IHRoYW4gYQorICAvLy8gc2ltcGxlIG1hcCBiZWNhdXNlIHRoZSBzdGF0ZW9waW50IGxvd2VyaW5nIGNvZGUgZGUtZHVwbGljYXRlcyBnYyBwb2ludGVycworICAvLy8gYmFzZWQgb24gdGhlaXIgU0RWYWx1ZSAoc28gJXAgYW5kIChiaXRjYXN0ICVwIHRvIFQpIHdpbGwgZ2V0IHRoZSBzYW1lCisgIC8vLyBzbG90KSwgYW5kIHdlIHRyYWNrIHRoYXQgaGVyZS4KKworICBzdHJ1Y3QgU3RhdGVwb2ludFNwaWxsTWFwIHsKKyAgICB1c2luZyBTbG90TWFwVHkgPSBEZW5zZU1hcDxjb25zdCBWYWx1ZSAqLCBPcHRpb25hbDxpbnQ+PjsKKworICAgIC8vLyBNYXBzIHVuaXF1ZWQgbGx2bSBJUiB2YWx1ZXMgdG8gdGhlIHNsb3RzIHRoZXkgd2VyZSBzcGlsbGVkIGluLiAgSWYgYQorICAgIC8vLyB2YWx1ZSBpcyBtYXBwZWQgdG8gTm9uZSBpdCBtZWFucyB3ZSB2aXNpdGVkIHRoZSB2YWx1ZSBidXQgZGlkbid0IHNwaWxsCisgICAgLy8vIGl0IChiZWNhdXNlIGl0IHdhcyBhIGNvbnN0YW50LCBmb3IgaW5zdGFuY2UpLgorICAgIFNsb3RNYXBUeSBTbG90TWFwOworCisgICAgLy8vIE1hcHMgbGx2bSBJUiB2YWx1ZXMgdG8gdGhlIHZhbHVlcyB0aGV5IHdlcmUgZGUtZHVwbGljYXRlZCB0by4KKyAgICBEZW5zZU1hcDxjb25zdCBWYWx1ZSAqLCBjb25zdCBWYWx1ZSAqPiBEdXBsaWNhdGVNYXA7CisKKyAgICBTbG90TWFwVHk6OmNvbnN0X2l0ZXJhdG9yIGZpbmQoY29uc3QgVmFsdWUgKlYpIGNvbnN0IHsKKyAgICAgIGF1dG8gRHVwbEl0ID0gRHVwbGljYXRlTWFwLmZpbmQoVik7CisgICAgICBpZiAoRHVwbEl0ICE9IER1cGxpY2F0ZU1hcC5lbmQoKSkKKyAgICAgICAgViA9IER1cGxJdC0+c2Vjb25kOworICAgICAgcmV0dXJuIFNsb3RNYXAuZmluZChWKTsKKyAgICB9CisKKyAgICBTbG90TWFwVHk6OmNvbnN0X2l0ZXJhdG9yIGVuZCgpIGNvbnN0IHsgcmV0dXJuIFNsb3RNYXAuZW5kKCk7IH0KKyAgfTsKKworICAvLy8gTWFwcyBnYy5zdGF0ZXBvaW50IGluc3RydWN0aW9ucyB0byB0aGVpciBjb3JyZXNwb25kaW5nIFN0YXRlcG9pbnRTcGlsbE1hcAorICAvLy8gaW5zdGFuY2VzLgorICBEZW5zZU1hcDxjb25zdCBJbnN0cnVjdGlvbiAqLCBTdGF0ZXBvaW50U3BpbGxNYXA+IFN0YXRlcG9pbnRTcGlsbE1hcHM7CisKKyAgLy8vIFN0YXRpY0FsbG9jYU1hcCAtIEtlZXAgdHJhY2sgb2YgZnJhbWUgaW5kaWNlcyBmb3IgZml4ZWQgc2l6ZWQgYWxsb2NhcyBpbgorICAvLy8gdGhlIGVudHJ5IGJsb2NrLiAgVGhpcyBhbGxvd3MgdGhlIGFsbG9jYXMgdG8gYmUgZWZmaWNpZW50bHkgcmVmZXJlbmNlZAorICAvLy8gYW55d2hlcmUgaW4gdGhlIGZ1bmN0aW9uLgorICBEZW5zZU1hcDxjb25zdCBBbGxvY2FJbnN0KiwgaW50PiBTdGF0aWNBbGxvY2FNYXA7CisKKyAgLy8vIEJ5VmFsQXJnRnJhbWVJbmRleE1hcCAtIEtlZXAgdHJhY2sgb2YgZnJhbWUgaW5kaWNlcyBmb3IgYnl2YWwgYXJndW1lbnRzLgorICBEZW5zZU1hcDxjb25zdCBBcmd1bWVudCosIGludD4gQnlWYWxBcmdGcmFtZUluZGV4TWFwOworCisgIC8vLyBBcmdEYmdWYWx1ZXMgLSBBIGxpc3Qgb2YgREJHX1ZBTFVFIGluc3RydWN0aW9ucyBjcmVhdGVkIGR1cmluZyBpc2VsIGZvcgorICAvLy8gZnVuY3Rpb24gYXJndW1lbnRzIHRoYXQgYXJlIGluc2VydGVkIGFmdGVyIHNjaGVkdWxpbmcgaXMgY29tcGxldGVkLgorICBTbWFsbFZlY3RvcjxNYWNoaW5lSW5zdHIqLCA4PiBBcmdEYmdWYWx1ZXM7CisKKyAgLy8vIFJlZ0ZpeHVwcyAtIFJlZ2lzdGVycyB3aGljaCBuZWVkIHRvIGJlIHJlcGxhY2VkIGFmdGVyIGlzZWwgaXMgZG9uZS4KKyAgRGVuc2VNYXA8dW5zaWduZWQsIHVuc2lnbmVkPiBSZWdGaXh1cHM7CisKKyAgRGVuc2VTZXQ8dW5zaWduZWQ+IFJlZ3NXaXRoRml4dXBzOworCisgIC8vLyBTdGF0ZXBvaW50U3RhY2tTbG90cyAtIEEgbGlzdCBvZiB0ZW1wb3Jhcnkgc3RhY2sgc2xvdHMgKGZyYW1lIGluZGljZXMpCisgIC8vLyB1c2VkIHRvIHNwaWxsIHZhbHVlcyBhdCBhIHN0YXRlcG9pbnQuICBXZSBzdG9yZSB0aGVtIGhlcmUgdG8gZW5hYmxlCisgIC8vLyByZXVzZSBvZiB0aGUgc2FtZSBzdGFjayBzbG90cyBhY3Jvc3MgZGlmZmVyZW50IHN0YXRlcG9pbnRzIGluIGRpZmZlcmVudAorICAvLy8gYmFzaWMgYmxvY2tzLgorICBTbWFsbFZlY3Rvcjx1bnNpZ25lZCwgNTA+IFN0YXRlcG9pbnRTdGFja1Nsb3RzOworCisgIC8vLyBNQkIgLSBUaGUgY3VycmVudCBibG9jay4KKyAgTWFjaGluZUJhc2ljQmxvY2sgKk1CQjsKKworICAvLy8gTUJCIC0gVGhlIGN1cnJlbnQgaW5zZXJ0IHBvc2l0aW9uIGluc2lkZSB0aGUgY3VycmVudCBibG9jay4KKyAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEluc2VydFB0OworCisgIHN0cnVjdCBMaXZlT3V0SW5mbyB7CisgICAgdW5zaWduZWQgTnVtU2lnbkJpdHMgOiAzMTsKKyAgICB1bnNpZ25lZCBJc1ZhbGlkIDogMTsKKyAgICBLbm93bkJpdHMgS25vd24gPSAxOworCisgICAgTGl2ZU91dEluZm8oKSA6IE51bVNpZ25CaXRzKDApLCBJc1ZhbGlkKHRydWUpIHt9CisgIH07CisKKyAgLy8vIFJlY29yZCB0aGUgcHJlZmVycmVkIGV4dGVuZCB0eXBlIChJU0Q6OlNJR05fRVhURU5EIG9yIElTRDo6WkVST19FWFRFTkQpCisgIC8vLyBmb3IgYSB2YWx1ZS4KKyAgRGVuc2VNYXA8Y29uc3QgVmFsdWUgKiwgSVNEOjpOb2RlVHlwZT4gUHJlZmVycmVkRXh0ZW5kVHlwZTsKKworICAvLy8gVmlzaXRlZEJCcyAtIFRoZSBzZXQgb2YgYmFzaWMgYmxvY2tzIHZpc2l0ZWQgdGh1cyBmYXIgYnkgaW5zdHJ1Y3Rpb24KKyAgLy8vIHNlbGVjdGlvbi4KKyAgU21hbGxQdHJTZXQ8Y29uc3QgQmFzaWNCbG9jayosIDQ+IFZpc2l0ZWRCQnM7CisKKyAgLy8vIFBISU5vZGVzVG9VcGRhdGUgLSBBIGxpc3Qgb2YgcGhpIGluc3RydWN0aW9ucyB3aG9zZSBvcGVyYW5kIGxpc3Qgd2lsbAorICAvLy8gYmUgdXBkYXRlZCBhZnRlciBwcm9jZXNzaW5nIHRoZSBjdXJyZW50IGJhc2ljIGJsb2NrLgorICAvLy8gVE9ETzogVGhpcyBpc24ndCBwZXItZnVuY3Rpb24gc3RhdGUsIGl0J3MgcGVyLWJhc2ljLWJsb2NrIHN0YXRlLiBCdXQKKyAgLy8vIHRoZXJlJ3Mgbm8gb3RoZXIgY29udmVuaWVudCBwbGFjZSBmb3IgaXQgdG8gbGl2ZSByaWdodCBub3cuCisgIHN0ZDo6dmVjdG9yPHN0ZDo6cGFpcjxNYWNoaW5lSW5zdHIqLCB1bnNpZ25lZD4gPiBQSElOb2Rlc1RvVXBkYXRlOworICB1bnNpZ25lZCBPcmlnTnVtUEhJTm9kZXNUb1VwZGF0ZTsKKworICAvLy8gSWYgdGhlIGN1cnJlbnQgTUJCIGlzIGEgbGFuZGluZyBwYWQsIHRoZSBleGNlcHRpb24gcG9pbnRlciBhbmQgZXhjZXB0aW9uCisgIC8vLyBzZWxlY3RvciByZWdpc3RlcnMgYXJlIGNvcGllZCBpbnRvIHRoZXNlIHZpcnR1YWwgcmVnaXN0ZXJzIGJ5CisgIC8vLyBTZWxlY3Rpb25EQUdJU2VsOjpQcmVwYXJlRUhMYW5kaW5nUGFkKCkuCisgIHVuc2lnbmVkIEV4Y2VwdGlvblBvaW50ZXJWaXJ0UmVnLCBFeGNlcHRpb25TZWxlY3RvclZpcnRSZWc7CisKKyAgLy8vIHNldCAtIEluaXRpYWxpemUgdGhpcyBGdW5jdGlvbkxvd2VyaW5nSW5mbyB3aXRoIHRoZSBnaXZlbiBGdW5jdGlvbgorICAvLy8gYW5kIGl0cyBhc3NvY2lhdGVkIE1hY2hpbmVGdW5jdGlvbi4KKyAgLy8vCisgIHZvaWQgc2V0KGNvbnN0IEZ1bmN0aW9uICZGbiwgTWFjaGluZUZ1bmN0aW9uICZNRiwgU2VsZWN0aW9uREFHICpEQUcpOworCisgIC8vLyBjbGVhciAtIENsZWFyIG91dCBhbGwgdGhlIGZ1bmN0aW9uLXNwZWNpZmljIHN0YXRlLiBUaGlzIHJldHVybnMgdGhpcworICAvLy8gRnVuY3Rpb25Mb3dlcmluZ0luZm8gdG8gYW4gZW1wdHkgc3RhdGUsIHJlYWR5IHRvIGJlIHVzZWQgZm9yIGEKKyAgLy8vIGRpZmZlcmVudCBmdW5jdGlvbi4KKyAgdm9pZCBjbGVhcigpOworCisgIC8vLyBpc0V4cG9ydGVkSW5zdCAtIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgYW4gaW5zdHJ1Y3Rpb24KKyAgLy8vIGV4cG9ydGVkIGZyb20gaXRzIGJsb2NrLgorICBib29sIGlzRXhwb3J0ZWRJbnN0KGNvbnN0IFZhbHVlICpWKSB7CisgICAgcmV0dXJuIFZhbHVlTWFwLmNvdW50KFYpOworICB9CisKKyAgdW5zaWduZWQgQ3JlYXRlUmVnKE1WVCBWVCk7CisKKyAgdW5zaWduZWQgQ3JlYXRlUmVncyhUeXBlICpUeSk7CisKKyAgdW5zaWduZWQgSW5pdGlhbGl6ZVJlZ0ZvclZhbHVlKGNvbnN0IFZhbHVlICpWKSB7CisgICAgLy8gVG9rZW5zIG5ldmVyIGxpdmUgaW4gdnJlZ3MuCisgICAgaWYgKFYtPmdldFR5cGUoKS0+aXNUb2tlblR5KCkpCisgICAgICByZXR1cm4gMDsKKyAgICB1bnNpZ25lZCAmUiA9IFZhbHVlTWFwW1ZdOworICAgIGFzc2VydChSID09IDAgJiYgIkFscmVhZHkgaW5pdGlhbGl6ZWQgdGhpcyB2YWx1ZSByZWdpc3RlciEiKTsKKyAgICByZXR1cm4gUiA9IENyZWF0ZVJlZ3MoVi0+Z2V0VHlwZSgpKTsKKyAgfQorCisgIC8vLyBHZXRMaXZlT3V0UmVnSW5mbyAtIEdldHMgTGl2ZU91dEluZm8gZm9yIGEgcmVnaXN0ZXIsIHJldHVybmluZyBOVUxMIGlmIHRoZQorICAvLy8gcmVnaXN0ZXIgaXMgYSBQSEkgZGVzdGluYXRpb24gYW5kIHRoZSBQSEkncyBMaXZlT3V0SW5mbyBpcyBub3QgdmFsaWQuCisgIGNvbnN0IExpdmVPdXRJbmZvICpHZXRMaXZlT3V0UmVnSW5mbyh1bnNpZ25lZCBSZWcpIHsKKyAgICBpZiAoIUxpdmVPdXRSZWdJbmZvLmluQm91bmRzKFJlZykpCisgICAgICByZXR1cm4gbnVsbHB0cjsKKworICAgIGNvbnN0IExpdmVPdXRJbmZvICpMT0kgPSAmTGl2ZU91dFJlZ0luZm9bUmVnXTsKKyAgICBpZiAoIUxPSS0+SXNWYWxpZCkKKyAgICAgIHJldHVybiBudWxscHRyOworCisgICAgcmV0dXJuIExPSTsKKyAgfQorCisgIC8vLyBHZXRMaXZlT3V0UmVnSW5mbyAtIEdldHMgTGl2ZU91dEluZm8gZm9yIGEgcmVnaXN0ZXIsIHJldHVybmluZyBOVUxMIGlmIHRoZQorICAvLy8gcmVnaXN0ZXIgaXMgYSBQSEkgZGVzdGluYXRpb24gYW5kIHRoZSBQSEkncyBMaXZlT3V0SW5mbyBpcyBub3QgdmFsaWQuIElmCisgIC8vLyB0aGUgcmVnaXN0ZXIncyBMaXZlT3V0SW5mbyBpcyBmb3IgYSBzbWFsbGVyIGJpdCB3aWR0aCwgaXQgaXMgZXh0ZW5kZWQgdG8KKyAgLy8vIHRoZSBsYXJnZXIgYml0IHdpZHRoIGJ5IHplcm8gZXh0ZW5zaW9uLiBUaGUgYml0IHdpZHRoIG11c3QgYmUgbm8gc21hbGxlcgorICAvLy8gdGhhbiB0aGUgTGl2ZU91dEluZm8ncyBleGlzdGluZyBiaXQgd2lkdGguCisgIGNvbnN0IExpdmVPdXRJbmZvICpHZXRMaXZlT3V0UmVnSW5mbyh1bnNpZ25lZCBSZWcsIHVuc2lnbmVkIEJpdFdpZHRoKTsKKworICAvLy8gQWRkTGl2ZU91dFJlZ0luZm8gLSBBZGRzIExpdmVPdXRJbmZvIGZvciBhIHJlZ2lzdGVyLgorICB2b2lkIEFkZExpdmVPdXRSZWdJbmZvKHVuc2lnbmVkIFJlZywgdW5zaWduZWQgTnVtU2lnbkJpdHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgS25vd25CaXRzICZLbm93bikgeworICAgIC8vIE9ubHkgaW5zdGFsbCB0aGlzIGluZm9ybWF0aW9uIGlmIGl0IHRlbGxzIHVzIHNvbWV0aGluZy4KKyAgICBpZiAoTnVtU2lnbkJpdHMgPT0gMSAmJiBLbm93bi5pc1Vua25vd24oKSkKKyAgICAgIHJldHVybjsKKworICAgIExpdmVPdXRSZWdJbmZvLmdyb3coUmVnKTsKKyAgICBMaXZlT3V0SW5mbyAmTE9JID0gTGl2ZU91dFJlZ0luZm9bUmVnXTsKKyAgICBMT0kuTnVtU2lnbkJpdHMgPSBOdW1TaWduQml0czsKKyAgICBMT0kuS25vd24uT25lID0gS25vd24uT25lOworICAgIExPSS5Lbm93bi5aZXJvID0gS25vd24uWmVybzsKKyAgfQorCisgIC8vLyBDb21wdXRlUEhJTGl2ZU91dFJlZ0luZm8gLSBDb21wdXRlIExpdmVPdXRJbmZvIGZvciBhIFBISSdzIGRlc3RpbmF0aW9uCisgIC8vLyByZWdpc3RlciBiYXNlZCBvbiB0aGUgTGl2ZU91dEluZm8gb2YgaXRzIG9wZXJhbmRzLgorICB2b2lkIENvbXB1dGVQSElMaXZlT3V0UmVnSW5mbyhjb25zdCBQSElOb2RlKik7CisKKyAgLy8vIEludmFsaWRhdGVQSElMaXZlT3V0UmVnSW5mbyAtIEludmFsaWRhdGVzIGEgUEhJJ3MgTGl2ZU91dEluZm8sIHRvIGJlCisgIC8vLyBjYWxsZWQgd2hlbiBhIGJsb2NrIGlzIHZpc2l0ZWQgYmVmb3JlIGFsbCBvZiBpdHMgcHJlZGVjZXNzb3JzLgorICB2b2lkIEludmFsaWRhdGVQSElMaXZlT3V0UmVnSW5mbyhjb25zdCBQSElOb2RlICpQTikgeworICAgIC8vIFBISXMgd2l0aCBubyB1c2VzIGhhdmUgbm8gVmFsdWVNYXAgZW50cnkuCisgICAgRGVuc2VNYXA8Y29uc3QgVmFsdWUqLCB1bnNpZ25lZD46OmNvbnN0X2l0ZXJhdG9yIEl0ID0gVmFsdWVNYXAuZmluZChQTik7CisgICAgaWYgKEl0ID09IFZhbHVlTWFwLmVuZCgpKQorICAgICAgcmV0dXJuOworCisgICAgdW5zaWduZWQgUmVnID0gSXQtPnNlY29uZDsKKyAgICBpZiAoUmVnID09IDApCisgICAgICByZXR1cm47CisKKyAgICBMaXZlT3V0UmVnSW5mby5ncm93KFJlZyk7CisgICAgTGl2ZU91dFJlZ0luZm9bUmVnXS5Jc1ZhbGlkID0gZmFsc2U7CisgIH0KKworICAvLy8gc2V0QXJndW1lbnRGcmFtZUluZGV4IC0gUmVjb3JkIGZyYW1lIGluZGV4IGZvciB0aGUgYnl2YWwKKyAgLy8vIGFyZ3VtZW50LgorICB2b2lkIHNldEFyZ3VtZW50RnJhbWVJbmRleChjb25zdCBBcmd1bWVudCAqQSwgaW50IEZJKTsKKworICAvLy8gZ2V0QXJndW1lbnRGcmFtZUluZGV4IC0gR2V0IGZyYW1lIGluZGV4IGZvciB0aGUgYnl2YWwgYXJndW1lbnQuCisgIGludCBnZXRBcmd1bWVudEZyYW1lSW5kZXgoY29uc3QgQXJndW1lbnQgKkEpOworCisgIHVuc2lnbmVkIGdldENhdGNoUGFkRXhjZXB0aW9uUG9pbnRlclZSZWcoY29uc3QgVmFsdWUgKkNQSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQyk7CisKK3ByaXZhdGU6CisgIHZvaWQgYWRkU0VISGFuZGxlcnNGb3JMUGFkcyhBcnJheVJlZjxjb25zdCBMYW5kaW5nUGFkSW5zdCAqPiBMUGFkcyk7CisKKyAgLy8vIExpdmVPdXRSZWdJbmZvIC0gSW5mb3JtYXRpb24gYWJvdXQgbGl2ZSBvdXQgdnJlZ3MuCisgIEluZGV4ZWRNYXA8TGl2ZU91dEluZm8sIFZpcnRSZWcySW5kZXhGdW5jdG9yPiBMaXZlT3V0UmVnSW5mbzsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fRlVOQ1RJT05MT1dFUklOR0lORk9fSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dDTWV0YWRhdGEuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HQ01ldGFkYXRhLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWQyNTk5ZgotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HQ01ldGFkYXRhLmgKQEAgLTAsMCArMSwyMDcgQEAKKy8vPT09LSBHQ01ldGFkYXRhLmggLSBHYXJiYWdlIGNvbGxlY3RvciBtZXRhZGF0YSAtLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlY2xhcmVzIHRoZSBHQ0Z1bmN0aW9uSW5mbyBhbmQgR0NNb2R1bGVJbmZvIGNsYXNzZXMsIHdoaWNoIGFyZQorLy8gdXNlZCBhcyBhIGNvbW11bmljYXRpb24gY2hhbm5lbCBmcm9tIHRoZSB0YXJnZXQgY29kZSBnZW5lcmF0b3IgdG8gdGhlIHRhcmdldAorLy8gZ2FyYmFnZSBjb2xsZWN0b3JzLiBUaGlzIGludGVyZmFjZSBhbGxvd3MgY29kZSBnZW5lcmF0b3JzIGFuZCBnYXJiYWdlCisvLyBjb2xsZWN0b3JzIHRvIGJlIGRldmVsb3BlZCBpbmRlcGVuZGVudGx5LgorLy8KKy8vIFRoZSBHQ0Z1bmN0aW9uSW5mbyBjbGFzcyBsb2dzIHRoZSBkYXRhIG5lY2Vzc2FyeSB0byBidWlsZCBhIHR5cGUgYWNjdXJhdGUKKy8vIHN0YWNrIG1hcC4gVGhlIGNvZGUgZ2VuZXJhdG9yIG91dHB1dHM6CisvLworLy8gICAtIFNhZmUgcG9pbnRzIGFzIHNwZWNpZmllZCBieSB0aGUgR0NTdHJhdGVneSdzIE5lZWRlZFNhZmVQb2ludHMuCisvLyAgIC0gU3RhY2sgb2Zmc2V0cyBmb3IgR0Mgcm9vdHMsIGFzIHNwZWNpZmllZCBieSBjYWxscyB0byBsbHZtLmdjcm9vdAorLy8KKy8vIEFzIGEgcmVmaW5lbWVudCwgbGl2ZW5lc3MgYW5hbHlzaXMgY2FsY3VsYXRlcyB0aGUgc2V0IG9mIGxpdmUgcm9vdHMgYXQgZWFjaAorLy8gc2FmZSBwb2ludC4gTGl2ZW5lc3MgYW5hbHlzaXMgaXMgbm90IHByZXNlbnRseSBwZXJmb3JtZWQgYnkgdGhlIGNvZGUKKy8vIGdlbmVyYXRvciwgc28gYWxsIHJvb3RzIGFyZSBhc3N1bWVkIGxpdmUuCisvLworLy8gR0NNb2R1bGVJbmZvIHNpbXBseSBjb2xsZWN0cyBHQ0Z1bmN0aW9uSW5mbyBpbnN0YW5jZXMgZm9yIGVhY2ggRnVuY3Rpb24gYXMKKy8vIHRoZXkgYXJlIGNvbXBpbGVkLiBUaGlzIGFjY3JldGlvbiBpcyBuZWNlc3NhcnkgZm9yIGNvbGxlY3RvcnMgd2hpY2ggbXVzdCBlbWl0CisvLyBhIHN0YWNrIG1hcCBmb3IgdGhlIGNvbXBpbGF0aW9uIHVuaXQgYXMgYSB3aG9sZS4gVGhlcmVmb3JlLCBHQ0Z1bmN0aW9uSW5mbworLy8gb3V0bGl2ZXMgdGhlIE1hY2hpbmVGdW5jdGlvbiBmcm9tIHdoaWNoIGl0IGlzIGRlcml2ZWQgYW5kIG11c3Qgbm90IHJlZmVyIHRvCisvLyBhbnkgY29kZSBnZW5lcmF0b3IgZGF0YSBzdHJ1Y3R1cmVzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0dDTUVUQURBVEFfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fR0NNRVRBREFUQV9ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9EZW5zZU1hcC5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU3RyaW5nTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU3RyaW5nUmVmLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0dDU3RyYXRlZ3kuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0RlYnVnTG9jLmgiCisjaW5jbHVkZSAibGx2bS9QYXNzLmgiCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGNzdGRkZWY+CisjaW5jbHVkZSA8Y3N0ZGludD4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaW5jbHVkZSA8dmVjdG9yPgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIENvbnN0YW50OworY2xhc3MgRnVuY3Rpb247CitjbGFzcyBNQ1N5bWJvbDsKKworLy8vIEdDUG9pbnQgLSBNZXRhZGF0YSBmb3IgYSBjb2xsZWN0b3Itc2FmZSBwb2ludCBpbiBtYWNoaW5lIGNvZGUuCisvLy8KK3N0cnVjdCBHQ1BvaW50IHsKKyAgR0M6OlBvaW50S2luZCBLaW5kOyAvLy88IFRoZSBraW5kIG9mIHRoZSBzYWZlIHBvaW50LgorICBNQ1N5bWJvbCAqTGFiZWw7ICAgIC8vLzwgQSBsYWJlbC4KKyAgRGVidWdMb2MgTG9jOworCisgIEdDUG9pbnQoR0M6OlBvaW50S2luZCBLLCBNQ1N5bWJvbCAqTCwgRGVidWdMb2MgREwpCisgICAgICA6IEtpbmQoSyksIExhYmVsKEwpLCBMb2Moc3RkOjptb3ZlKERMKSkge30KK307CisKKy8vLyBHQ1Jvb3QgLSBNZXRhZGF0YSBmb3IgYSBwb2ludGVyIHRvIGFuIG9iamVjdCBtYW5hZ2VkIGJ5IHRoZSBnYXJiYWdlCisvLy8gY29sbGVjdG9yLgorc3RydWN0IEdDUm9vdCB7CisgIGludCBOdW07ICAgICAgICAgICAgICAgICAgLy8vPCBVc3VhbGx5IGEgZnJhbWUgaW5kZXguCisgIGludCBTdGFja09mZnNldCA9IC0xOyAgICAgLy8vPCBPZmZzZXQgZnJvbSB0aGUgc3RhY2sgcG9pbnRlci4KKyAgY29uc3QgQ29uc3RhbnQgKk1ldGFkYXRhOyAvLy88IE1ldGFkYXRhIHN0cmFpZ2h0IGZyb20gdGhlIGNhbGwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLy88IHRvIGxsdm0uZ2Nyb290LgorCisgIEdDUm9vdChpbnQgTiwgY29uc3QgQ29uc3RhbnQgKk1EKSA6IE51bShOKSwgTWV0YWRhdGEoTUQpIHt9Cit9OworCisvLy8gR2FyYmFnZSBjb2xsZWN0aW9uIG1ldGFkYXRhIGZvciBhIHNpbmdsZSBmdW5jdGlvbi4gIEN1cnJlbnRseSwgdGhpcworLy8vIGluZm9ybWF0aW9uIG9ubHkgYXBwbGllcyB0byBHQ1N0cmF0ZWdpZXMgd2hpY2ggdXNlIEdDUm9vdC4KK2NsYXNzIEdDRnVuY3Rpb25JbmZvIHsKK3B1YmxpYzoKKyAgdXNpbmcgaXRlcmF0b3IgPSBzdGQ6OnZlY3RvcjxHQ1BvaW50Pjo6aXRlcmF0b3I7CisgIHVzaW5nIHJvb3RzX2l0ZXJhdG9yID0gc3RkOjp2ZWN0b3I8R0NSb290Pjo6aXRlcmF0b3I7CisgIHVzaW5nIGxpdmVfaXRlcmF0b3IgPSBzdGQ6OnZlY3RvcjxHQ1Jvb3Q+Ojpjb25zdF9pdGVyYXRvcjsKKworcHJpdmF0ZToKKyAgY29uc3QgRnVuY3Rpb24gJkY7CisgIEdDU3RyYXRlZ3kgJlM7CisgIHVpbnQ2NF90IEZyYW1lU2l6ZTsKKyAgc3RkOjp2ZWN0b3I8R0NSb290PiBSb290czsKKyAgc3RkOjp2ZWN0b3I8R0NQb2ludD4gU2FmZVBvaW50czsKKworICAvLyBGSVhNRTogTGl2ZW5lc3MuIEEgMkQgQml0VmVjdG9yLCBwZXJoYXBzPworICAvLworICAvLyAgIEJpdFZlY3RvciBMaXZlbmVzczsKKyAgLy8KKyAgLy8gICBib29sIGlzbGl2ZShpbnQgcG9pbnQsIGludCByb290KSA9CisgIC8vICAgICBMaXZlbmVzc1twb2ludCAqIFNhZmVQb2ludHMuc2l6ZSgpICsgcm9vdF0KKyAgLy8KKyAgLy8gVGhlIGJpdCB2ZWN0b3IgaXMgdGhlIG1vcmUgY29tcGFjdCByZXByZXNlbnRhdGlvbiB3aGVyZSA+My4yJSBvZiByb290cworICAvLyBhcmUgbGl2ZSBwZXIgc2FmZSBwb2ludCAoMS41JSBvbiA2NC1iaXQgaG9zdHMpLgorCitwdWJsaWM6CisgIEdDRnVuY3Rpb25JbmZvKGNvbnN0IEZ1bmN0aW9uICZGLCBHQ1N0cmF0ZWd5ICZTKTsKKyAgfkdDRnVuY3Rpb25JbmZvKCk7CisKKyAgLy8vIGdldEZ1bmN0aW9uIC0gUmV0dXJuIHRoZSBmdW5jdGlvbiB0byB3aGljaCB0aGlzIG1ldGFkYXRhIGFwcGxpZXMuCisgIGNvbnN0IEZ1bmN0aW9uICZnZXRGdW5jdGlvbigpIGNvbnN0IHsgcmV0dXJuIEY7IH0KKworICAvLy8gZ2V0U3RyYXRlZ3kgLSBSZXR1cm4gdGhlIEdDIHN0cmF0ZWd5IGZvciB0aGUgZnVuY3Rpb24uCisgIEdDU3RyYXRlZ3kgJmdldFN0cmF0ZWd5KCkgeyByZXR1cm4gUzsgfQorCisgIC8vLyBhZGRTdGFja1Jvb3QgLSBSZWdpc3RlcnMgYSByb290IHRoYXQgbGl2ZXMgb24gdGhlIHN0YWNrLiBOdW0gaXMgdGhlCisgIC8vLyAgICAgICAgICAgICAgICBzdGFjayBvYmplY3QgSUQgZm9yIHRoZSBhbGxvY2EgKGlmIHRoZSBjb2RlIGdlbmVyYXRvciBpcworICAvLyAgICAgICAgICAgICAgICAgdXNpbmcgIE1hY2hpbmVGcmFtZUluZm8pLgorICB2b2lkIGFkZFN0YWNrUm9vdChpbnQgTnVtLCBjb25zdCBDb25zdGFudCAqTWV0YWRhdGEpIHsKKyAgICBSb290cy5wdXNoX2JhY2soR0NSb290KE51bSwgTWV0YWRhdGEpKTsKKyAgfQorCisgIC8vLyByZW1vdmVTdGFja1Jvb3QgLSBSZW1vdmVzIGEgcm9vdC4KKyAgcm9vdHNfaXRlcmF0b3IgcmVtb3ZlU3RhY2tSb290KHJvb3RzX2l0ZXJhdG9yIHBvc2l0aW9uKSB7CisgICAgcmV0dXJuIFJvb3RzLmVyYXNlKHBvc2l0aW9uKTsKKyAgfQorCisgIC8vLyBhZGRTYWZlUG9pbnQgLSBOb3RlcyB0aGUgZXhpc3RlbmNlIG9mIGEgc2FmZSBwb2ludC4gTnVtIGlzIHRoZSBJRCBvZiB0aGUKKyAgLy8vIGxhYmVsIGp1c3QgcHJpb3IgdG8gdGhlIHNhZmUgcG9pbnQgKGlmIHRoZSBjb2RlIGdlbmVyYXRvciBpcyB1c2luZworICAvLy8gTWFjaGluZU1vZHVsZUluZm8pLgorICB2b2lkIGFkZFNhZmVQb2ludChHQzo6UG9pbnRLaW5kIEtpbmQsIE1DU3ltYm9sICpMYWJlbCwgY29uc3QgRGVidWdMb2MgJkRMKSB7CisgICAgU2FmZVBvaW50cy5lbXBsYWNlX2JhY2soS2luZCwgTGFiZWwsIERMKTsKKyAgfQorCisgIC8vLyBnZXRGcmFtZVNpemUvc2V0RnJhbWVTaXplIC0gUmVjb3JkcyB0aGUgZnVuY3Rpb24ncyBmcmFtZSBzaXplLgorICB1aW50NjRfdCBnZXRGcmFtZVNpemUoKSBjb25zdCB7IHJldHVybiBGcmFtZVNpemU7IH0KKyAgdm9pZCBzZXRGcmFtZVNpemUodWludDY0X3QgUykgeyBGcmFtZVNpemUgPSBTOyB9CisKKyAgLy8vIGJlZ2luL2VuZCAtIEl0ZXJhdG9ycyBmb3Igc2FmZSBwb2ludHMuCisgIGl0ZXJhdG9yIGJlZ2luKCkgeyByZXR1cm4gU2FmZVBvaW50cy5iZWdpbigpOyB9CisgIGl0ZXJhdG9yIGVuZCgpIHsgcmV0dXJuIFNhZmVQb2ludHMuZW5kKCk7IH0KKyAgc2l6ZV90IHNpemUoKSBjb25zdCB7IHJldHVybiBTYWZlUG9pbnRzLnNpemUoKTsgfQorCisgIC8vLyByb290c19iZWdpbi9yb290c19lbmQgLSBJdGVyYXRvcnMgZm9yIGFsbCByb290cyBpbiB0aGUgZnVuY3Rpb24uCisgIHJvb3RzX2l0ZXJhdG9yIHJvb3RzX2JlZ2luKCkgeyByZXR1cm4gUm9vdHMuYmVnaW4oKTsgfQorICByb290c19pdGVyYXRvciByb290c19lbmQoKSB7IHJldHVybiBSb290cy5lbmQoKTsgfQorICBzaXplX3Qgcm9vdHNfc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIFJvb3RzLnNpemUoKTsgfQorCisgIC8vLyBsaXZlX2JlZ2luL2xpdmVfZW5kIC0gSXRlcmF0b3JzIGZvciBsaXZlIHJvb3RzIGF0IGEgZ2l2ZW4gc2FmZSBwb2ludC4KKyAgbGl2ZV9pdGVyYXRvciBsaXZlX2JlZ2luKGNvbnN0IGl0ZXJhdG9yICZwKSB7IHJldHVybiByb290c19iZWdpbigpOyB9CisgIGxpdmVfaXRlcmF0b3IgbGl2ZV9lbmQoY29uc3QgaXRlcmF0b3IgJnApIHsgcmV0dXJuIHJvb3RzX2VuZCgpOyB9CisgIHNpemVfdCBsaXZlX3NpemUoY29uc3QgaXRlcmF0b3IgJnApIGNvbnN0IHsgcmV0dXJuIHJvb3RzX3NpemUoKTsgfQorfTsKKworLy8vIEFuIGFuYWx5c2lzIHBhc3Mgd2hpY2ggY2FjaGVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBlbnRpcmUgTW9kdWxlLgorLy8vIFJlY29yZHMgYm90aCB0aGUgZnVuY3Rpb24gbGV2ZWwgaW5mb3JtYXRpb24gdXNlZCBieSBHQ1Jvb3RzIGFuZCBhCisvLy8gY2FjaGUgb2YgdGhlICdhY3RpdmUnIGdjIHN0cmF0ZWd5IG9iamVjdHMgZm9yIHRoZSBjdXJyZW50IE1vZHVsZS4KK2NsYXNzIEdDTW9kdWxlSW5mbyA6IHB1YmxpYyBJbW11dGFibGVQYXNzIHsKKyAgLy8vIEFuIG93bmluZyBsaXN0IG9mIGFsbCBHQ1N0cmF0ZWdpZXMgd2hpY2ggaGF2ZSBiZWVuIGNyZWF0ZWQKKyAgU21hbGxWZWN0b3I8c3RkOjp1bmlxdWVfcHRyPEdDU3RyYXRlZ3k+LCAxPiBHQ1N0cmF0ZWd5TGlzdDsKKyAgLy8vIEEgaGVscGVyIG1hcCB0byBzcGVlZHVwIGxvb2t1cHMgaW50byB0aGUgYWJvdmUgbGlzdAorICBTdHJpbmdNYXA8R0NTdHJhdGVneSo+IEdDU3RyYXRlZ3lNYXA7CisKK3B1YmxpYzoKKyAgLy8vIExvb2t1cCB0aGUgR0NTdHJhdGVneSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBnYyBuYW1lLgorICAvLy8gT2JqZWN0cyBhcmUgb3duZWQgaW50ZXJuYWxseTsgTm8gY2FsbGVyIHNob3VsZCBhdHRlbXB0IHRvIGRlbGV0ZSB0aGUKKyAgLy8vIHJldHVybmVkIG9iamVjdHMuCisgIEdDU3RyYXRlZ3kgKmdldEdDU3RyYXRlZ3koY29uc3QgU3RyaW5nUmVmIE5hbWUpOworCisgIC8vLyBMaXN0IG9mIHBlciBmdW5jdGlvbiBpbmZvIG9iamVjdHMuICBJbiB0aGVvcnksIEVhY2ggb2YgdGhlc2UKKyAgLy8vIG1heSBiZSBhc3NvY2lhdGVkIHdpdGggYSBkaWZmZXJlbnQgR0MuCisgIHVzaW5nIEZ1bmNJbmZvVmVjID0gc3RkOjp2ZWN0b3I8c3RkOjp1bmlxdWVfcHRyPEdDRnVuY3Rpb25JbmZvPj47CisKKyAgRnVuY0luZm9WZWM6Oml0ZXJhdG9yIGZ1bmNpbmZvX2JlZ2luKCkgeyByZXR1cm4gRnVuY3Rpb25zLmJlZ2luKCk7IH0KKyAgRnVuY0luZm9WZWM6Oml0ZXJhdG9yIGZ1bmNpbmZvX2VuZCgpIHsgcmV0dXJuIEZ1bmN0aW9ucy5lbmQoKTsgfQorCitwcml2YXRlOgorICAvLy8gT3duaW5nIGxpc3Qgb2YgYWxsIEdDRnVuY3Rpb25JbmZvcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBNb2R1bGUKKyAgRnVuY0luZm9WZWMgRnVuY3Rpb25zOworCisgIC8vLyBOb24tb3duaW5nIG1hcCB0byBieXBhc3MgbGluZWFyIHNlYXJjaCB3aGVuIGZpbmRpbmcgdGhlIEdDRnVuY3Rpb25JbmZvCisgIC8vLyBhc3NvY2lhdGVkIHdpdGggYSBwYXJ0aWN1bGFyIEZ1bmN0aW9uLgorICB1c2luZyBmaW5mb19tYXBfdHlwZSA9IERlbnNlTWFwPGNvbnN0IEZ1bmN0aW9uICosIEdDRnVuY3Rpb25JbmZvICo+OworICBmaW5mb19tYXBfdHlwZSBGSW5mb01hcDsKKworcHVibGljOgorICB1c2luZyBpdGVyYXRvciA9IFNtYWxsVmVjdG9yPHN0ZDo6dW5pcXVlX3B0cjxHQ1N0cmF0ZWd5PiwgMT46OmNvbnN0X2l0ZXJhdG9yOworCisgIHN0YXRpYyBjaGFyIElEOworCisgIEdDTW9kdWxlSW5mbygpOworCisgIC8vLyBjbGVhciAtIFJlc2V0cyB0aGUgcGFzcy4gQW55IHBhc3MsIHdoaWNoIHVzZXMgR0NNb2R1bGVJbmZvLCBzaG91bGQKKyAgLy8vIGNhbGwgaXQgaW4gZG9GaW5hbGl6YXRpb24oKS4KKyAgLy8vCisgIHZvaWQgY2xlYXIoKTsKKworICAvLy8gYmVnaW4vZW5kIC0gSXRlcmF0b3JzIGZvciB1c2VkIHN0cmF0ZWdpZXMuCisgIC8vLworICBpdGVyYXRvciBiZWdpbigpIGNvbnN0IHsgcmV0dXJuIEdDU3RyYXRlZ3lMaXN0LmJlZ2luKCk7IH0KKyAgaXRlcmF0b3IgZW5kKCkgY29uc3QgeyByZXR1cm4gR0NTdHJhdGVneUxpc3QuZW5kKCk7IH0KKworICAvLy8gZ2V0IC0gTG9vayB1cCBmdW5jdGlvbiBtZXRhZGF0YS4gIFRoaXMgaXMgY3VycmVudGx5IGFzc3VtZWQKKyAgLy8vIGhhdmUgdGhlIHNpZGUgZWZmZWN0IG9mIGluaXRpYWxpemluZyB0aGUgYXNzb2NpYXRlZCBHQ1N0cmF0ZWd5LiAgVGhhdAorICAvLy8gd2lsbCBzb29uIGNoYW5nZS4KKyAgR0NGdW5jdGlvbkluZm8gJmdldEZ1bmN0aW9uSW5mbyhjb25zdCBGdW5jdGlvbiAmRik7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0dDTUVUQURBVEFfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dDTWV0YWRhdGFQcmludGVyLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR0NNZXRhZGF0YVByaW50ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xY2M2OWE3Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dDTWV0YWRhdGFQcmludGVyLmgKQEAgLTAsMCArMSw2NyBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9HQ01ldGFkYXRhUHJpbnRlci5oIC0gUHJpbnRzIGFzbSBHQyB0YWJsZXMgLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGUgYWJzdHJhY3QgYmFzZSBjbGFzcyBHQ01ldGFkYXRhUHJpbnRlciBzdXBwb3J0cyB3cml0aW5nIEdDIG1ldGFkYXRhIHRhYmxlcworLy8gYXMgYXNzZW1ibHkgY29kZS4gVGhpcyBpcyBhIHNlcGFyYXRlIGNsYXNzIGZyb20gR0NTdHJhdGVneSBpbiBvcmRlciB0byBhbGxvdworLy8gdXNlcnMgb2YgdGhlIExMVk0gSklUIHRvIGF2b2lkIGxpbmtpbmcgd2l0aCB0aGUgQXNtV3JpdGVyLgorLy8KKy8vIFN1YmNsYXNzZXMgb2YgR0NNZXRhZGF0YVByaW50ZXIgbXVzdCBiZSByZWdpc3RlcmVkIHVzaW5nIHRoZQorLy8gR0NNZXRhZGF0YVByaW50ZXJSZWdpc3RyeS4gVGhpcyBpcyBzZXBhcmF0ZSBmcm9tIHRoZSBHQ1N0cmF0ZWd5IGl0c2VsZgorLy8gYmVjYXVzZSB0aGVzZSBzdWJjbGFzc2VzIGFyZSBsb2dpY2FsbHkgcGx1Z2lucyBmb3IgdGhlIEFzbVdyaXRlci4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9HQ01FVEFEQVRBUFJJTlRFUl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9HQ01FVEFEQVRBUFJJTlRFUl9ICisKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvUmVnaXN0cnkuaCIKKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBBc21QcmludGVyOworY2xhc3MgR0NNZXRhZGF0YVByaW50ZXI7CitjbGFzcyBHQ01vZHVsZUluZm87CitjbGFzcyBHQ1N0cmF0ZWd5OworY2xhc3MgTW9kdWxlOworCisvLy8gR0NNZXRhZGF0YVByaW50ZXJSZWdpc3RyeSAtIFRoZSBHQyBhc3NlbWJseSBwcmludGVyIHJlZ2lzdHJ5IHVzZXMgYWxsIHRoZQorLy8vIGRlZmF1bHRzIGZyb20gUmVnaXN0cnkuCit1c2luZyBHQ01ldGFkYXRhUHJpbnRlclJlZ2lzdHJ5ID0gUmVnaXN0cnk8R0NNZXRhZGF0YVByaW50ZXI+OworCisvLy8gR0NNZXRhZGF0YVByaW50ZXIgLSBFbWl0cyBHQyBtZXRhZGF0YSBhcyBhc3NlbWJseSBjb2RlLiAgSW5zdGFuY2VzIGFyZQorLy8vIGNyZWF0ZWQsIG1hbmFnZWQsIGFuZCBvd25lZCBieSB0aGUgQXNtUHJpbnRlci4KK2NsYXNzIEdDTWV0YWRhdGFQcmludGVyIHsKK3ByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBBc21QcmludGVyOworCisgIEdDU3RyYXRlZ3kgKlM7CisKK3Byb3RlY3RlZDoKKyAgLy8gTWF5IG9ubHkgYmUgc3ViY2xhc3NlZC4KKyAgR0NNZXRhZGF0YVByaW50ZXIoKTsKKworcHVibGljOgorICBHQ01ldGFkYXRhUHJpbnRlcihjb25zdCBHQ01ldGFkYXRhUHJpbnRlciAmKSA9IGRlbGV0ZTsKKyAgR0NNZXRhZGF0YVByaW50ZXIgJm9wZXJhdG9yPShjb25zdCBHQ01ldGFkYXRhUHJpbnRlciAmKSA9IGRlbGV0ZTsKKyAgdmlydHVhbCB+R0NNZXRhZGF0YVByaW50ZXIoKTsKKworICBHQ1N0cmF0ZWd5ICZnZXRTdHJhdGVneSgpIHsgcmV0dXJuICpTOyB9CisKKyAgLy8vIENhbGxlZCBiZWZvcmUgdGhlIGFzc2VtYmx5IGZvciB0aGUgbW9kdWxlIGlzIGdlbmVyYXRlZCBieQorICAvLy8gdGhlIEFzbVByaW50ZXIgKGJ1dCBhZnRlciB0YXJnZXQgc3BlY2lmaWMgaG9va3MuKQorICB2aXJ0dWFsIHZvaWQgYmVnaW5Bc3NlbWJseShNb2R1bGUgJk0sIEdDTW9kdWxlSW5mbyAmSW5mbywgQXNtUHJpbnRlciAmQVApIHt9CisKKyAgLy8vIENhbGxlZCBhZnRlciB0aGUgYXNzZW1ibHkgZm9yIHRoZSBtb2R1bGUgaXMgZ2VuZXJhdGVkIGJ5CisgIC8vLyB0aGUgQXNtUHJpbnRlciAoYnV0IGJlZm9yZSB0YXJnZXQgc3BlY2lmaWMgaG9va3MpCisgIHZpcnR1YWwgdm9pZCBmaW5pc2hBc3NlbWJseShNb2R1bGUgJk0sIEdDTW9kdWxlSW5mbyAmSW5mbywgQXNtUHJpbnRlciAmQVApIHt9Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0dDTUVUQURBVEFQUklOVEVSX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HQ1N0cmF0ZWd5LmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR0NTdHJhdGVneS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjE2MTY4ZTcKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR0NTdHJhdGVneS5oCkBAIC0wLDAgKzEsMTgxIEBACisvLz09PS0gbGx2bS9Db2RlR2VuL0dDU3RyYXRlZ3kuaCAtIEdhcmJhZ2UgY29sbGVjdGlvbiAtLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIEdDU3RyYXRlZ3kgY29vcmRpbmF0ZXMgY29kZSBnZW5lcmF0aW9uIGFsZ29yaXRobXMgYW5kIGltcGxlbWVudHMgc29tZSBpdHNlbGYKKy8vIGluIG9yZGVyIHRvIGdlbmVyYXRlIGNvZGUgY29tcGF0aWJsZSB3aXRoIGEgdGFyZ2V0IGNvZGUgZ2VuZXJhdG9yIGFzCisvLyBzcGVjaWZpZWQgaW4gYSBmdW5jdGlvbidzICdnYycgYXR0cmlidXRlLiBBbGdvcml0aG1zIGFyZSBlbmFibGVkIGJ5IHNldHRpbmcKKy8vIGZsYWdzIGluIGEgc3ViY2xhc3MncyBjb25zdHJ1Y3RvciwgYW5kIHNvbWUgdmlydHVhbCBtZXRob2RzIGNhbiBiZQorLy8gb3ZlcnJpZGRlbi4KKy8vCisvLyBHQ1N0cmF0ZWd5IGlzIHJlbGV2YW50IGZvciBpbXBsZW1lbnRhdGlvbnMgdXNpbmcgZWl0aGVyIGdjLnJvb3Qgb3IKKy8vIGdjLnN0YXRlcG9pbnQgYmFzZWQgbG93ZXJpbmcgc3RyYXRlZ2llcywgYnV0IGlzIGN1cnJlbnRseSBmb2N1c2VkIG1vc3RseSBvbgorLy8gb3B0aW9ucyBmb3IgZ2Mucm9vdC4gIFRoaXMgd2lsbCBjaGFuZ2Ugb3ZlciB0aW1lLgorLy8KKy8vIFdoZW4gcmVxdWVzdGVkIGJ5IGEgc3ViY2xhc3Mgb2YgR0NTdHJhdGVneSwgdGhlIGdjLnJvb3QgaW1wbGVtZW50YXRpb24gd2lsbAorLy8gcG9wdWxhdGUgR0NNb2R1bGVJbmZvIGFuZCBHQ0Z1bmN0aW9uSW5mbyB3aXRoIHRoYXQgYWJvdXQgZWFjaCBGdW5jdGlvbiBpbgorLy8gdGhlIE1vZHVsZSB0aGF0IG9wdHMgaW4gdG8gZ2FyYmFnZSBjb2xsZWN0aW9uLiAgU3BlY2lmaWNhbGx5OgorLy8KKy8vIC0gU2FmZSBwb2ludHMKKy8vICAgR2FyYmFnZSBjb2xsZWN0aW9uIGlzIGdlbmVyYWxseSBvbmx5IHBvc3NpYmxlIGF0IGNlcnRhaW4gcG9pbnRzIGluIGNvZGUuCisvLyAgIEdDU3RyYXRlZ3kgY2FuIHJlcXVlc3QgdGhhdCB0aGUgY29sbGVjdG9yIGluc2VydCBzdWNoIHBvaW50czoKKy8vCisvLyAgICAgLSBBdCBhbmQgYWZ0ZXIgYW55IGNhbGwgdG8gYSBzdWJyb3V0aW5lCisvLyAgICAgLSBCZWZvcmUgcmV0dXJuaW5nIGZyb20gdGhlIGN1cnJlbnQgZnVuY3Rpb24KKy8vICAgICAtIEJlZm9yZSBiYWNrd2FyZHMgYnJhbmNoZXMgKGxvb3BzKQorLy8KKy8vIC0gUm9vdHMKKy8vICAgV2hlbiBhIHJlZmVyZW5jZSB0byBhIEdDLWFsbG9jYXRlZCBvYmplY3QgZXhpc3RzIG9uIHRoZSBzdGFjaywgaXQgbXVzdCBiZQorLy8gICBzdG9yZWQgaW4gYW4gYWxsb2NhIHJlZ2lzdGVyZWQgd2l0aCBsbHZtLmdjb290LgorLy8KKy8vIFRoaXMgaW5mb3JtYXRpb24gY2FuIHVzZWQgdG8gZW1pdCB0aGUgbWV0YWRhdGEgdGFibGVzIHdoaWNoIGFyZSByZXF1aXJlZCBieQorLy8gdGhlIHRhcmdldCBnYXJiYWdlIGNvbGxlY3RvciBydW50aW1lLgorLy8KKy8vIFdoZW4gdXNlZCB3aXRoIGdjLnN0YXRlcG9pbnQsIGluZm9ybWF0aW9uIGFib3V0IHNhZmVwb2ludCBhbmQgcm9vdHMgY2FuIGJlCisvLyBmb3VuZCBpbiB0aGUgYmluYXJ5IFN0YWNrTWFwIHNlY3Rpb24gYWZ0ZXIgY29kZSBnZW5lcmF0aW9uLiAgU2FmZXBvaW50CisvLyBwbGFjZW1lbnQgaXMgY3VycmVudGx5IHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgZnJvbnRlbmQsIHRob3VnaCBsYXRlCisvLyBpbnNlcnRpb24gc3VwcG9ydCBpcyBwbGFubmVkLiAgZ2Muc3RhdGVwb2ludCBkb2VzIG5vdCBjdXJyZW50bHkgc3VwcG9ydAorLy8gY3VzdG9tIHN0YWNrIG1hcCBmb3JtYXRzOyBzdWNoIGNhbiBiZSBnZW5lcmF0ZWQgYnkgcGFyc2luZyB0aGUgc3RhbmRhcmQKKy8vIHN0YWNrIG1hcCBzZWN0aW9uIGlmIGRlc2lyZWQuCisvLworLy8gVGhlIHJlYWQgYW5kIHdyaXRlIGJhcnJpZXIgc3VwcG9ydCBjYW4gYmUgdXNlZCB3aXRoIGVpdGhlciBpbXBsZW1lbnRhdGlvbi4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9HQ1NUUkFURUdZX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0dDU1RSQVRFR1lfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvTm9uZS5oIgorI2luY2x1ZGUgImxsdm0vQURUL09wdGlvbmFsLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L1JlZ2lzdHJ5LmgiCisjaW5jbHVkZSA8c3RyaW5nPgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIFR5cGU7CisKK25hbWVzcGFjZSBHQyB7CisKKy8vLyBQb2ludEtpbmQgLSBVc2VkIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlIGFkZHJlc3Mgb2YgdGhlIGNhbGwgaW5zdHJ1Y3Rpb24KKy8vLyBvciB0aGUgYWRkcmVzcyBhZnRlciB0aGUgY2FsbCBpbnN0cnVjdGlvbiBpcyBsaXN0ZWQgaW4gdGhlIHN0YWNrbWFwLiAgRm9yCisvLy8gbW9zdCBydW50aW1lcywgUG9zdENhbGwgc2FmZXBvaW50cyBhcmUgYXBwcm9wcmlhdGUuCisvLy8KK2VudW0gUG9pbnRLaW5kIHsKKyAgUHJlQ2FsbCwgLy8vPCBJbnN0ciBpcyBhIGNhbGwgaW5zdHJ1Y3Rpb24uCisgIFBvc3RDYWxsIC8vLzwgSW5zdHIgaXMgdGhlIHJldHVybiBhZGRyZXNzIG9mIGEgY2FsbC4KK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBHQworCisvLy8gR0NTdHJhdGVneSBkZXNjcmliZXMgYSBnYXJiYWdlIGNvbGxlY3RvciBhbGdvcml0aG0ncyBjb2RlIGdlbmVyYXRpb24KKy8vLyByZXF1aXJlbWVudHMsIGFuZCBwcm92aWRlcyBvdmVycmlkYWJsZSBob29rcyBmb3IgdGhvc2UgbmVlZHMgd2hpY2ggY2Fubm90CisvLy8gYmUgYWJzdHJhY3RseSBkZXNjcmliZWQuICBHQ1N0cmF0ZWd5IG9iamVjdHMgbXVzdCBiZSBsb29rZWQgdXAgdGhyb3VnaAorLy8vIHRoZSBGdW5jdGlvbi4gIFRoZSBvYmplY3RzIHRoZW1zZWx2ZXMgYXJlIG93bmVkIGJ5IHRoZSBDb250ZXh0IGFuZCBtdXN0CisvLy8gYmUgaW1tdXRhYmxlLgorY2xhc3MgR0NTdHJhdGVneSB7Citwcml2YXRlOgorICBmcmllbmQgY2xhc3MgR0NNb2R1bGVJbmZvOworCisgIHN0ZDo6c3RyaW5nIE5hbWU7CisKK3Byb3RlY3RlZDoKKyAgYm9vbCBVc2VTdGF0ZXBvaW50cyA9IGZhbHNlOyAvLy8gVXNlcyBnYy5zdGF0ZXBvaW50cyBhcyBvcHBvc2VkIHRvIGdjLnJvb3RzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vLyBpZiBzZXQsIG5vbmUgb2YgdGhlIG90aGVyIG9wdGlvbnMgY2FuIGJlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8vIGFueXRoaW5nIGJ1dCB0aGVpciBkZWZhdWx0IHZhbHVlcy4KKworICB1bnNpZ25lZCBOZWVkZWRTYWZlUG9pbnRzID0gMDsgICAgLy8vPCBCaXRtYXNrIG9mIHJlcXVpcmVkIHNhZmUgcG9pbnRzLgorICBib29sIEN1c3RvbVJlYWRCYXJyaWVycyA9IGZhbHNlOyAgLy8vPCBEZWZhdWx0IGlzIHRvIGluc2VydCBsb2Fkcy4KKyAgYm9vbCBDdXN0b21Xcml0ZUJhcnJpZXJzID0gZmFsc2U7IC8vLzwgRGVmYXVsdCBpcyB0byBpbnNlcnQgc3RvcmVzLgorICBib29sIEN1c3RvbVJvb3RzID0gZmFsc2U7ICAgICAgLy8vPCBEZWZhdWx0IGlzIHRvIHBhc3MgdGhyb3VnaCB0byBiYWNrZW5kLgorICBib29sIEluaXRSb290cz0gdHJ1ZTsgICAgICAgICAgLy8vPCBJZiBzZXQsIHJvb3RzIGFyZSBudWxsZWQgZHVyaW5nIGxvd2VyaW5nLgorICBib29sIFVzZXNNZXRhZGF0YSA9IGZhbHNlOyAgICAgLy8vPCBJZiBzZXQsIGJhY2tlbmQgbXVzdCBlbWl0IG1ldGFkYXRhIHRhYmxlcy4KKworcHVibGljOgorICBHQ1N0cmF0ZWd5KCk7CisgIHZpcnR1YWwgfkdDU3RyYXRlZ3koKSA9IGRlZmF1bHQ7CisKKyAgLy8vIFJldHVybiB0aGUgbmFtZSBvZiB0aGUgR0Mgc3RyYXRlZ3kuICBUaGlzIGlzIHRoZSB2YWx1ZSBvZiB0aGUgY29sbGVjdG9yCisgIC8vLyBuYW1lIHN0cmluZyBzcGVjaWZpZWQgb24gZnVuY3Rpb25zIHdoaWNoIHVzZSB0aGlzIHN0cmF0ZWd5LgorICBjb25zdCBzdGQ6OnN0cmluZyAmZ2V0TmFtZSgpIGNvbnN0IHsgcmV0dXJuIE5hbWU7IH0KKworICAvLy8gQnkgZGVmYXVsdCwgd3JpdGUgYmFycmllcnMgYXJlIHJlcGxhY2VkIHdpdGggc2ltcGxlIHN0b3JlCisgIC8vLyBpbnN0cnVjdGlvbnMuIElmIHRydWUsIHlvdSBtdXN0IHByb3ZpZGUgYSBjdXN0b20gcGFzcyB0byBsb3dlciAKKyAgLy8vIGNhbGxzIHRvIEBsbHZtLmdjd3JpdGUuCisgIGJvb2wgY3VzdG9tV3JpdGVCYXJyaWVyKCkgY29uc3QgeyByZXR1cm4gQ3VzdG9tV3JpdGVCYXJyaWVyczsgfQorCisgIC8vLyBCeSBkZWZhdWx0LCByZWFkIGJhcnJpZXJzIGFyZSByZXBsYWNlZCB3aXRoIHNpbXBsZSBsb2FkCisgIC8vLyBpbnN0cnVjdGlvbnMuIElmIHRydWUsIHlvdSBtdXN0IHByb3ZpZGUgYSBjdXN0b20gcGFzcyB0byBsb3dlciAKKyAgLy8vIGNhbGxzIHRvIEBsbHZtLmdjcmVhZC4KKyAgYm9vbCBjdXN0b21SZWFkQmFycmllcigpIGNvbnN0IHsgcmV0dXJuIEN1c3RvbVJlYWRCYXJyaWVyczsgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBzdHJhdGVneSBpcyBleHBlY3RpbmcgdGhlIHVzZSBvZiBnYy5zdGF0ZXBvaW50cywKKyAgLy8vIGFuZCBmYWxzZSBvdGhlcndpc2UuCisgIGJvb2wgdXNlU3RhdGVwb2ludHMoKSBjb25zdCB7IHJldHVybiBVc2VTdGF0ZXBvaW50czsgfQorCisgIC8qKiBAbmFtZSBTdGF0ZXBvaW50IFNwZWNpZmljIFByb3BlcnRpZXMgKi8KKyAgLy8vQHsKKworICAvLy8gSWYgdGhlIHR5cGUgc3BlY2lmaWVkIGNhbiBiZSByZWxpYWJseSBkaXN0aW5ndWlzaGVkLCByZXR1cm5zIHRydWUgZm9yCisgIC8vLyBwb2ludGVycyB0byBHQyBtYW5hZ2VkIGxvY2F0aW9ucyBhbmQgZmFsc2UgZm9yIHBvaW50ZXJzIHRvIG5vbi1HQworICAvLy8gbWFuYWdlZCBsb2NhdGlvbnMuICBOb3RlIGEgR0NTdHJhdGVneSBjYW4gYWx3YXlzIHJldHVybiAnTm9uZScgKGkuZS4gYW4KKyAgLy8vIGVtcHR5IG9wdGlvbmFsIGluZGljYXRpbmcgaXQgY2FuJ3QgcmVsaWFibHkgZGlzdGluZ3Vpc2guCisgIHZpcnR1YWwgT3B0aW9uYWw8Ym9vbD4gaXNHQ01hbmFnZWRQb2ludGVyKGNvbnN0IFR5cGUgKlR5KSBjb25zdCB7CisgICAgcmV0dXJuIE5vbmU7CisgIH0KKyAgLy8vQH0KKworICAvKiogQG5hbWUgR0NSb290IFNwZWNpZmljIFByb3BlcnRpZXMKKyAgICogVGhlc2UgcHJvcGVydGllcyBhbmQgb3ZlcnJpZGVzIG9ubHkgYXBwbHkgdG8gY29sbGVjdG9yIHN0cmF0ZWdpZXMgdXNpbmcKKyAgICogR0NSb290LgorICAgKi8KKyAgLy8vQHsKKworICAvLy8gVHJ1ZSBpZiBzYWZlIHBvaW50cyBvZiBhbnkga2luZCBhcmUgcmVxdWlyZWQuIEJ5IGRlZmF1bHQsIG5vbmUgYXJlCisgIC8vLyByZWNvcmRlZC4KKyAgYm9vbCBuZWVkc1NhZmVQb2ludHMoKSBjb25zdCB7IHJldHVybiBOZWVkZWRTYWZlUG9pbnRzICE9IDA7IH0KKworICAvLy8gVHJ1ZSBpZiB0aGUgZ2l2ZW4ga2luZCBvZiBzYWZlIHBvaW50IGlzIHJlcXVpcmVkLiBCeSBkZWZhdWx0LCBub25lIGFyZQorICAvLy8gcmVjb3JkZWQuCisgIGJvb2wgbmVlZHNTYWZlUG9pbnQoR0M6OlBvaW50S2luZCBLaW5kKSBjb25zdCB7CisgICAgcmV0dXJuIChOZWVkZWRTYWZlUG9pbnRzICYgMSA8PCBLaW5kKSAhPSAwOworICB9CisKKyAgLy8vIEJ5IGRlZmF1bHQsIHJvb3RzIGFyZSBsZWZ0IGZvciB0aGUgY29kZSBnZW5lcmF0b3Igc28gaXQgY2FuIGdlbmVyYXRlIGEKKyAgLy8vIHN0YWNrIG1hcC4gSWYgdHJ1ZSwgeW91IG11c3QgcHJvdmlkZSBhIGN1c3RvbSBwYXNzIHRvIGxvd2VyIAorICAvLy8gY2FsbHMgdG8gQGxsdm0uZ2Nyb290LgorICBib29sIGN1c3RvbVJvb3RzKCkgY29uc3QgeyByZXR1cm4gQ3VzdG9tUm9vdHM7IH0KKworICAvLy8gSWYgc2V0LCBnY3Jvb3QgaW50cmluc2ljcyBzaG91bGQgaW5pdGlhbGl6ZSB0aGVpciBhbGxvY2FzIHRvIG51bGwKKyAgLy8vIGJlZm9yZSB0aGUgZmlyc3QgdXNlLiBUaGlzIGlzIG5lY2Vzc2FyeSBmb3IgbW9zdCBHQ3MgYW5kIGlzIGVuYWJsZWQgYnkKKyAgLy8vIGRlZmF1bHQuCisgIGJvb2wgaW5pdGlhbGl6ZVJvb3RzKCkgY29uc3QgeyByZXR1cm4gSW5pdFJvb3RzOyB9CisKKyAgLy8vIElmIHNldCwgYXBwcm9wcmlhdGUgbWV0YWRhdGEgdGFibGVzIG11c3QgYmUgZW1pdHRlZCBieSB0aGUgYmFjay1lbmQKKyAgLy8vIChhc3NlbWJsZXIsIEpJVCwgb3Igb3RoZXJ3aXNlKS4gRm9yIHN0YXRlcG9pbnQsIHRoaXMgbWV0aG9kIGlzCisgIC8vLyBjdXJyZW50bHkgdW5zdXBwb3J0ZWQuICBUaGUgc3RhY2ttYXAgaW5mb3JtYXRpb24gY2FuIGJlIGZvdW5kIGluIHRoZQorICAvLy8gU3RhY2tNYXAgc2VjdGlvbiBhcyBkZXNjcmliZWQgaW4gdGhlIGRvY3VtZW50YXRpb24uCisgIGJvb2wgdXNlc01ldGFkYXRhKCkgY29uc3QgeyByZXR1cm4gVXNlc01ldGFkYXRhOyB9CisKKyAgLy8vQH0KK307CisKKy8vLyBTdWJjbGFzc2VzIG9mIEdDU3RyYXRlZ3kgYXJlIG1hZGUgYXZhaWxhYmxlIGZvciB1c2UgZHVyaW5nIGNvbXBpbGF0aW9uIGJ5CisvLy8gYWRkaW5nIHRoZW0gdG8gdGhlIGdsb2JhbCBHQ1JlZ2lzdHJ5LiAgVGhpcyBjYW4gZG9uZSBlaXRoZXIgd2l0aGluIHRoZQorLy8vIExMVk0gc291cmNlIHRyZWUgb3IgdmlhIGEgbG9hZGFibGUgcGx1Z2luLiAgQW4gZXhhbXBsZSByZWdpc3RlcmF0aW9uCisvLy8gd291bGQgYmU6CisvLy8gc3RhdGljIEdDUmVnaXN0cnk6OkFkZDxDdXN0b21HQz4gWCgiY3VzdG9tLW5hbWUiLAorLy8vICAgICAgICAibXkgY3VzdG9tIHN1cHBlciBmYW5jeSBnYyBzdHJhdGVneSIpOworLy8vCisvLy8gTm90ZSB0aGF0IHRvIHVzZSBhIGN1c3RvbSBHQ01ldGFkYXRhUHJpbnRlciB3L2djLnJvb3RzLCB5b3UgbXVzdCBhbHNvCisvLy8gcmVnaXN0ZXIgeW91ciBHQ01ldGFkYXRhUHJpbnRlciBzdWJjbGFzcyB3aXRoIHRoZQorLy8vIEdDTWV0YWRhdGFQcmludGVyUmVnaXN0ZXJ5IGFzIHdlbGwuCit1c2luZyBHQ1JlZ2lzdHJ5ID0gUmVnaXN0cnk8R0NTdHJhdGVneT47CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fR0NTVFJBVEVHWV9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR0NzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR0NzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTIwN2Y4MAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HQ3MuaApAQCAtMCwwICsxLDQ2IEBACisvLz09PS0tIEdDcy5oIC0gR2FyYmFnZSBjb2xsZWN0b3IgbGlua2FnZSBoYWNrcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBjb250YWlucyBoYWNrIGZ1bmN0aW9ucyB0byBmb3JjZSBsaW5raW5nIGluIHRoZSBHQyBjb21wb25lbnRzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0dDU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9HQ1NfSAorCituYW1lc3BhY2UgbGx2bSB7CitjbGFzcyBHQ1N0cmF0ZWd5OworY2xhc3MgR0NNZXRhZGF0YVByaW50ZXI7CisKKy8vLyBGSVhNRTogQ29sbGVjdG9yIGluc3RhbmNlcyBhcmUgbm90IHVzZWZ1bCBvbiB0aGVpciBvd24uIFRoZXNlIG5vIGxvbmdlcgorLy8vICAgICAgICBzZXJ2ZSBhbnkgcHVycG9zZSBleGNlcHQgdG8gbGluayBpbiB0aGUgcGx1Z2lucy4KKworLy8vIENyZWF0ZXMgYSBDb3JlQ0xSLWNvbXBhdGlibGUgZ2FyYmFnZSBjb2xsZWN0b3IuCit2b2lkIGxpbmtDb3JlQ0xSR0MoKTsKKworLy8vIENyZWF0ZXMgYW4gb2NhbWwtY29tcGF0aWJsZSBnYXJiYWdlIGNvbGxlY3Rvci4KK3ZvaWQgbGlua09jYW1sR0MoKTsKKworLy8vIENyZWF0ZXMgYW4gb2NhbWwtY29tcGF0aWJsZSBtZXRhZGF0YSBwcmludGVyLgordm9pZCBsaW5rT2NhbWxHQ1ByaW50ZXIoKTsKKworLy8vIENyZWF0ZXMgYW4gZXJsYW5nLWNvbXBhdGlibGUgZ2FyYmFnZSBjb2xsZWN0b3IuCit2b2lkIGxpbmtFcmxhbmdHQygpOworCisvLy8gQ3JlYXRlcyBhbiBlcmxhbmctY29tcGF0aWJsZSBtZXRhZGF0YSBwcmludGVyLgordm9pZCBsaW5rRXJsYW5nR0NQcmludGVyKCk7CisKKy8vLyBDcmVhdGVzIGEgc2hhZG93IHN0YWNrIGdhcmJhZ2UgY29sbGVjdG9yLiBUaGlzIGNvbGxlY3RvciByZXF1aXJlcyBubyBjb2RlCisvLy8gZ2VuZXJhdG9yIHN1cHBvcnQuCit2b2lkIGxpbmtTaGFkb3dTdGFja0dDKCk7CisKK3ZvaWQgbGlua1N0YXRlcG9pbnRFeGFtcGxlR0MoKTsKK30KKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9DYWxsTG93ZXJpbmcuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0NhbGxMb3dlcmluZy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhkOTFjYzQKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9DYWxsTG93ZXJpbmcuaApAQCAtMCwwICsxLDIxNSBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0NhbGxMb3dlcmluZy5oIC0gQ2FsbCBsb3dlcmluZyAtLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLworLy8vIFxmaWxlCisvLy8gVGhpcyBmaWxlIGRlc2NyaWJlcyBob3cgdG8gbG93ZXIgTExWTSBjYWxscyB0byBtYWNoaW5lIGNvZGUgY2FsbHMuCisvLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfQ0FMTExPV0VSSU5HX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfQ0FMTExPV0VSSU5HX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0FycmF5UmVmLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0NhbGxpbmdDb252TG93ZXIuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0Q2FsbGluZ0NvbnYuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0NhbGxTaXRlLmgiCisjaW5jbHVkZSAibGx2bS9JUi9DYWxsaW5nQ29udi5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9FcnJvckhhbmRsaW5nLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L01hY2hpbmVWYWx1ZVR5cGUuaCIKKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgRGF0YUxheW91dDsKK2NsYXNzIEZ1bmN0aW9uOworY2xhc3MgTWFjaGluZUlSQnVpbGRlcjsKK2NsYXNzIE1hY2hpbmVPcGVyYW5kOworc3RydWN0IE1hY2hpbmVQb2ludGVySW5mbzsKK2NsYXNzIE1hY2hpbmVSZWdpc3RlckluZm87CitjbGFzcyBUYXJnZXRMb3dlcmluZzsKK2NsYXNzIFR5cGU7CitjbGFzcyBWYWx1ZTsKKworY2xhc3MgQ2FsbExvd2VyaW5nIHsKKyAgY29uc3QgVGFyZ2V0TG93ZXJpbmcgKlRMSTsKKworcHVibGljOgorICBzdHJ1Y3QgQXJnSW5mbyB7CisgICAgdW5zaWduZWQgUmVnOworICAgIFR5cGUgKlR5OworICAgIElTRDo6QXJnRmxhZ3NUeSBGbGFnczsKKyAgICBib29sIElzRml4ZWQ7CisKKyAgICBBcmdJbmZvKHVuc2lnbmVkIFJlZywgVHlwZSAqVHksIElTRDo6QXJnRmxhZ3NUeSBGbGFncyA9IElTRDo6QXJnRmxhZ3NUeXt9LAorICAgICAgICAgICAgYm9vbCBJc0ZpeGVkID0gdHJ1ZSkKKyAgICAgICAgOiBSZWcoUmVnKSwgVHkoVHkpLCBGbGFncyhGbGFncyksIElzRml4ZWQoSXNGaXhlZCkge30KKyAgfTsKKworICAvLy8gQXJndW1lbnQgaGFuZGxpbmcgaXMgbW9zdGx5IHVuaWZvcm0gYmV0d2VlbiB0aGUgZm91ciBwbGFjZXMgdGhhdAorICAvLy8gbWFrZSB0aGVzZSBkZWNpc2lvbnM6IGZ1bmN0aW9uIGZvcm1hbCBhcmd1bWVudHMsIGNhbGwKKyAgLy8vIGluc3RydWN0aW9uIGFyZ3MsIGNhbGwgaW5zdHJ1Y3Rpb24gcmV0dXJucyBhbmQgZnVuY3Rpb24KKyAgLy8vIHJldHVybnMuIEhvd2V2ZXIsIG9uY2UgYSBkZWNpc2lvbiBoYXMgYmVlbiBtYWRlIG9uIHdoZXJlIGFuCisgIC8vLyBhcnVnbWVudCBzaG91bGQgZ28sIGV4YWN0bHkgd2hhdCBoYXBwZW5zIGNhbiB2YXJ5IHNsaWdodGx5LiBUaGlzCisgIC8vLyBjbGFzcyBhYnN0cmFjdHMgdGhlIGRpZmZlcmVuY2VzLgorICBzdHJ1Y3QgVmFsdWVIYW5kbGVyIHsKKyAgICBWYWx1ZUhhbmRsZXIoTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlciwgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJLAorICAgICAgICAgICAgICAgICBDQ0Fzc2lnbkZuICpBc3NpZ25GbikKKyAgICAgIDogTUlSQnVpbGRlcihNSVJCdWlsZGVyKSwgTVJJKE1SSSksIEFzc2lnbkZuKEFzc2lnbkZuKSB7fQorCisgICAgdmlydHVhbCB+VmFsdWVIYW5kbGVyKCkgPSBkZWZhdWx0OworCisgICAgLy8vIE1hdGVyaWFsaXplIGEgVlJlZyBjb250YWluaW5nIHRoZSBhZGRyZXNzIG9mIHRoZSBzcGVjaWZpZWQKKyAgICAvLy8gc3RhY2stYmFzZWQgb2JqZWN0LiBUaGlzIGlzIGVpdGhlciBiYXNlZCBvbiBhIEZyYW1lSW5kZXggb3IKKyAgICAvLy8gZGlyZWN0IFNQIG1hbmlwdWxhdGlvbiwgZGVwZW5kaW5nIG9uIHRoZSBjb250ZXh0LiBccCBNUE8KKyAgICAvLy8gc2hvdWxkIGJlIGluaXRpYWxpemVkIHRvIGFuIGFwcHJvcHJpYXRlIGRlc2NyaXB0aW9uIG9mIHRoZQorICAgIC8vLyBhZGRyZXNzIGNyZWF0ZWQuCisgICAgdmlydHVhbCB1bnNpZ25lZCBnZXRTdGFja0FkZHJlc3ModWludDY0X3QgU2l6ZSwgaW50NjRfdCBPZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZVBvaW50ZXJJbmZvICZNUE8pID0gMDsKKworICAgIC8vLyBUaGUgc3BlY2lmaWVkIHZhbHVlIGhhcyBiZWVuIGFzc2lnbmVkIHRvIGEgcGh5c2ljYWwgcmVnaXN0ZXIsCisgICAgLy8vIGhhbmRsZSB0aGUgYXBwcm9wcmlhdGUgQ09QWSAoZWl0aGVyIHRvIG9yIGZyb20pIGFuZCBtYXJrIGFueQorICAgIC8vLyByZWxldmFudCB1c2VzL2RlZmluZXMgYXMgbmVlZGVkLgorICAgIHZpcnR1YWwgdm9pZCBhc3NpZ25WYWx1ZVRvUmVnKHVuc2lnbmVkIFZhbFZSZWcsIHVuc2lnbmVkIFBoeXNSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0NWYWxBc3NpZ24gJlZBKSA9IDA7CisKKyAgICAvLy8gVGhlIHNwZWNpZmllZCB2YWx1ZSBoYXMgYmVlbiBhc3NpZ25lZCB0byBhIHN0YWNrCisgICAgLy8vIGxvY2F0aW9uLiBMb2FkIG9yIHN0b3JlIGl0IHRoZXJlLCB3aXRoIGFwcHJvcHJpYXRlIGV4dGVuc2lvbgorICAgIC8vLyBpZiBuZWNlc3NhcnkuCisgICAgdmlydHVhbCB2b2lkIGFzc2lnblZhbHVlVG9BZGRyZXNzKHVuc2lnbmVkIFZhbFZSZWcsIHVuc2lnbmVkIEFkZHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ2NF90IFNpemUsIE1hY2hpbmVQb2ludGVySW5mbyAmTVBPLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQ1ZhbEFzc2lnbiAmVkEpID0gMDsKKworICAgIC8vLyBIYW5kbGUgY3VzdG9tIHZhbHVlcywgd2hpY2ggbWF5IGJlIHBhc3NlZCBpbnRvIG9uZSBvciBtb3JlIG9mIFxwIFZBcy4KKyAgICAvLy8gXHJldHVybiBUaGUgbnVtYmVyIG9mIFxwIFZBcyB0aGF0IGhhdmUgYmVlbiBhc3NpZ25lZCBhZnRlciB0aGUgZmlyc3QKKyAgICAvLy8gICAgICAgICBvbmUsIGFuZCB3aGljaCBzaG91bGQgdGhlcmVmb3JlIGJlIHNraXBwZWQgZnJvbSBmdXJ0aGVyCisgICAgLy8vICAgICAgICAgcHJvY2Vzc2luZy4KKyAgICB2aXJ0dWFsIHVuc2lnbmVkIGFzc2lnbkN1c3RvbVZhbHVlKGNvbnN0IEFyZ0luZm8gJkFyZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPENDVmFsQXNzaWduPiBWQXMpIHsKKyAgICAgIC8vIFRoaXMgaXMgbm90IGEgcHVyZSB2aXJ0dWFsIG1ldGhvZCBiZWNhdXNlIG5vdCBhbGwgdGFyZ2V0cyBuZWVkIHRvIHdvcnJ5CisgICAgICAvLyBhYm91dCBjdXN0b20gdmFsdWVzLgorICAgICAgbGx2bV91bnJlYWNoYWJsZSgiQ3VzdG9tIHZhbHVlcyBub3Qgc3VwcG9ydGVkIik7CisgICAgfQorCisgICAgdW5zaWduZWQgZXh0ZW5kUmVnaXN0ZXIodW5zaWduZWQgVmFsUmVnLCBDQ1ZhbEFzc2lnbiAmVkEpOworCisgICAgdmlydHVhbCBib29sIGFzc2lnbkFyZyh1bnNpZ25lZCBWYWxObywgTVZUIFZhbFZULCBNVlQgTG9jVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBDQ1ZhbEFzc2lnbjo6TG9jSW5mbyBMb2NJbmZvLCBjb25zdCBBcmdJbmZvICZJbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0NTdGF0ZSAmU3RhdGUpIHsKKyAgICAgIHJldHVybiBBc3NpZ25GbihWYWxObywgVmFsVlQsIExvY1ZULCBMb2NJbmZvLCBJbmZvLkZsYWdzLCBTdGF0ZSk7CisgICAgfQorCisgICAgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcjsKKyAgICBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkk7CisgICAgQ0NBc3NpZ25GbiAqQXNzaWduRm47CisgIH07CisKK3Byb3RlY3RlZDoKKyAgLy8vIEdldHRlciBmb3IgZ2VuZXJpYyBUYXJnZXRMb3dlcmluZyBjbGFzcy4KKyAgY29uc3QgVGFyZ2V0TG93ZXJpbmcgKmdldFRMSSgpIGNvbnN0IHsKKyAgICByZXR1cm4gVExJOworICB9CisKKyAgLy8vIEdldHRlciBmb3IgdGFyZ2V0IHNwZWNpZmljIFRhcmdldExvd2VyaW5nIGNsYXNzLgorICB0ZW1wbGF0ZSA8Y2xhc3MgWFhYVGFyZ2V0TG93ZXJpbmc+CisgICAgY29uc3QgWFhYVGFyZ2V0TG93ZXJpbmcgKmdldFRMSSgpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8Y29uc3QgWFhYVGFyZ2V0TG93ZXJpbmcgKj4oVExJKTsKKyAgfQorCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBGdW5jSW5mb1R5PgorICB2b2lkIHNldEFyZ0ZsYWdzKEFyZ0luZm8gJkFyZywgdW5zaWduZWQgT3BOdW0sIGNvbnN0IERhdGFMYXlvdXQgJkRMLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IEZ1bmNJbmZvVHkgJkZ1bmNJbmZvKSBjb25zdDsKKworICAvLy8gSW52b2tlIEhhbmRsZXI6OmFzc2lnbkFyZyBvbiBlYWNoIG9mIHRoZSBnaXZlbiBccCBBcmdzIGFuZCB0aGVuIHVzZQorICAvLy8gXHAgQ2FsbGJhY2sgdG8gbW92ZSB0aGVtIHRvIHRoZSBhc3NpZ25lZCBsb2NhdGlvbnMuCisgIC8vLworICAvLy8gXHJldHVybiBUcnVlIGlmIGV2ZXJ5dGhpbmcgaGFzIHN1Y2NlZWRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICBib29sIGhhbmRsZUFzc2lnbm1lbnRzKE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIsIEFycmF5UmVmPEFyZ0luZm8+IEFyZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgVmFsdWVIYW5kbGVyICZDYWxsYmFjaykgY29uc3Q7CisKK3B1YmxpYzoKKyAgQ2FsbExvd2VyaW5nKGNvbnN0IFRhcmdldExvd2VyaW5nICpUTEkpIDogVExJKFRMSSkge30KKyAgdmlydHVhbCB+Q2FsbExvd2VyaW5nKCkgPSBkZWZhdWx0OworCisgIC8vLyBUaGlzIGhvb2sgbXVzdCBiZSBpbXBsZW1lbnRlZCB0byBsb3dlciBvdXRnb2luZyByZXR1cm4gdmFsdWVzLCBkZXNjcmliZWQKKyAgLy8vIGJ5IFxwIFZhbCwgaW50byB0aGUgc3BlY2lmaWVkIHZpcnR1YWwgcmVnaXN0ZXIgXHAgVlJlZy4KKyAgLy8vIFRoaXMgaG9vayBpcyB1c2VkIGJ5IEdsb2JhbElTZWwuCisgIC8vLworICAvLy8gXHJldHVybiBUcnVlIGlmIHRoZSBsb3dlcmluZyBzdWNjZWVkcywgZmFsc2Ugb3RoZXJ3aXNlLgorICB2aXJ0dWFsIGJvb2wgbG93ZXJSZXR1cm4oTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFZhbHVlICpWYWwsIHVuc2lnbmVkIFZSZWcpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gVGhpcyBob29rIG11c3QgYmUgaW1wbGVtZW50ZWQgdG8gbG93ZXIgdGhlIGluY29taW5nIChmb3JtYWwpCisgIC8vLyBhcmd1bWVudHMsIGRlc2NyaWJlZCBieSBccCBBcmdzLCBmb3IgR2xvYmFsSVNlbC4gRWFjaCBhcmd1bWVudAorICAvLy8gbXVzdCBlbmQgdXAgaW4gdGhlIHJlbGF0ZWQgdmlydHVhbCByZWdpc3RlciBkZXNjcmliZWQgYnkgVlJlZ3MuCisgIC8vLyBJbiBvdGhlciB3b3JkcywgdGhlIGZpcnN0IGFyZ3VtZW50IHNob3VsZCBlbmQgdXAgaW4gVlJlZ3NbMF0sCisgIC8vLyB0aGUgc2Vjb25kIGluIFZSZWdzWzFdLCBhbmQgc28gb24uCisgIC8vLyBccCBNSVJCdWlsZGVyIGlzIHNldCB0byB0aGUgcHJvcGVyIGluc2VydGlvbiBmb3IgdGhlIGFyZ3VtZW50CisgIC8vLyBsb3dlcmluZy4KKyAgLy8vCisgIC8vLyBccmV0dXJuIFRydWUgaWYgdGhlIGxvd2VyaW5nIHN1Y2NlZWRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICB2aXJ0dWFsIGJvb2wgbG93ZXJGb3JtYWxBcmd1bWVudHMoTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEZ1bmN0aW9uICZGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8dW5zaWduZWQ+IFZSZWdzKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFRoaXMgaG9vayBtdXN0IGJlIGltcGxlbWVudGVkIHRvIGxvd2VyIHRoZSBnaXZlbiBjYWxsIGluc3RydWN0aW9uLAorICAvLy8gaW5jbHVkaW5nIGFyZ3VtZW50IGFuZCByZXR1cm4gdmFsdWUgbWFyc2hhbGxpbmcuCisgIC8vLworICAvLy8gXHAgQ2FsbENvbnYgaXMgdGhlIGNhbGxpbmcgY29udmVudGlvbiB0byBiZSB1c2VkIGZvciB0aGUgY2FsbC4KKyAgLy8vCisgIC8vLyBccCBDYWxsZWUgaXMgdGhlIGRlc3RpbmF0aW9uIG9mIHRoZSBjYWxsLiBJdCBzaG91bGQgYmUgZWl0aGVyIGEgcmVnaXN0ZXIsCisgIC8vLyBnbG9iYWxhZGRyZXNzLCBvciBleHRlcm5hbHN5bWJvbC4KKyAgLy8vCisgIC8vLyBccCBSZXNUeSBpcyB0aGUgdHlwZSByZXR1cm5lZCBieSB0aGUgZnVuY3Rpb24KKyAgLy8vCisgIC8vLyBccCBSZXNSZWcgaXMgdGhlIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB0aGF0IHRoZSByZXR1cm5lZAorICAvLy8gdmFsdWUgc2hvdWxkIGJlIGxvd2VyZWQgaW50by4KKyAgLy8vCisgIC8vLyBccCBBcmdUeXMgaXMgYSBsaXN0IG9mIHRoZSB0eXBlcyBlYWNoIG1lbWJlciBvZiBccCBBcmdSZWdzIGhhczsgdXNlZCBieQorICAvLy8gdGhlIHRhcmdldCB0byBkZWNpZGUgd2hpY2ggcmVnaXN0ZXIvc3RhY2sgc2xvdCBzaG91bGQgYmUgYWxsb2NhdGVkLgorICAvLy8KKyAgLy8vIFxwIEFyZ1JlZ3MgaXMgYSBsaXN0IG9mIHZpcnR1YWwgcmVnaXN0ZXJzIGNvbnRhaW5pbmcgZWFjaCBhcmd1bWVudCB0aGF0CisgIC8vLyBuZWVkcyB0byBiZSBwYXNzZWQuCisgIC8vLworICAvLy8gXHJldHVybiB0cnVlIGlmIHRoZSBsb3dlcmluZyBzdWNjZWVkZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgdmlydHVhbCBib29sIGxvd2VyQ2FsbChNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyLCBDYWxsaW5nQ29udjo6SUQgQ2FsbENvbnYsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZU9wZXJhbmQgJkNhbGxlZSwgY29uc3QgQXJnSW5mbyAmT3JpZ1JldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjxBcmdJbmZvPiBPcmlnQXJncykgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBMb3dlciB0aGUgZ2l2ZW4gY2FsbCBpbnN0cnVjdGlvbiwgaW5jbHVkaW5nIGFyZ3VtZW50IGFuZCByZXR1cm4gdmFsdWUKKyAgLy8vIG1hcnNoYWxsaW5nLgorICAvLy8KKyAgLy8vIFxwIENJIGlzIHRoZSBjYWxsL2ludm9rZSBpbnN0cnVjdGlvbi4KKyAgLy8vCisgIC8vLyBccCBSZXNSZWcgaXMgYSByZWdpc3RlciB3aGVyZSB0aGUgY2FsbCdzIHJldHVybiB2YWx1ZSBzaG91bGQgYmUgc3RvcmVkIChvcgorICAvLy8gMCBpZiB0aGVyZSBpcyBubyByZXR1cm4gdmFsdWUpLgorICAvLy8KKyAgLy8vIFxwIEFyZ1JlZ3MgaXMgYSBsaXN0IG9mIHZpcnR1YWwgcmVnaXN0ZXJzIGNvbnRhaW5pbmcgZWFjaCBhcmd1bWVudCB0aGF0CisgIC8vLyBuZWVkcyB0byBiZSBwYXNzZWQuCisgIC8vLworICAvLy8gXHAgR2V0Q2FsbGVlUmVnIGlzIGEgY2FsbGJhY2sgdG8gbWF0ZXJpYWxpemUgYSByZWdpc3RlciBmb3IgdGhlIGNhbGxlZSBpZgorICAvLy8gdGhlIHRhcmdldCBkZXRlcm1pbmVzIGl0IGNhbm5vdCBqdW1wIHRvIHRoZSBkZXN0aW5hdGlvbiBiYXNlZCBwdXJlbHkgb24gXHAKKyAgLy8vIENJLiBUaGlzIG1pZ2h0IGJlIGJlY2F1c2UgXHAgQ0kgaXMgaW5kaXJlY3QsIG9yIGJlY2F1c2Ugb2YgdGhlIGxpbWl0ZWQKKyAgLy8vIHJhbmdlIG9mIGFuIGltbWVkaWF0ZSBqdW1wLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gdHJ1ZSBpZiB0aGUgbG93ZXJpbmcgc3VjY2VlZGVkLCBmYWxzZSBvdGhlcndpc2UuCisgIGJvb2wgbG93ZXJDYWxsKE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIsIEltbXV0YWJsZUNhbGxTaXRlIENTLAorICAgICAgICAgICAgICAgICB1bnNpZ25lZCBSZXNSZWcsIEFycmF5UmVmPHVuc2lnbmVkPiBBcmdSZWdzLAorICAgICAgICAgICAgICAgICBzdGQ6OmZ1bmN0aW9uPHVuc2lnbmVkKCk+IEdldENhbGxlZVJlZykgY29uc3Q7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfQ0FMTExPV0VSSU5HX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0NvbWJpbmVyLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9Db21iaW5lci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2YTMzZGUKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9Db21iaW5lci5oCkBAIC0wLDAgKzEsNDMgQEAKKy8vPT0gLS0tLS0gbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvQ29tYmluZXIuaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0gPT0gLy8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLy8gVGhpcyBjb250YWlucyBjb21tb24gY29kZSB0byBkcml2ZSBjb21iaW5lcy4gQ29tYmluZXIgUGFzc2VzIHdpbGwgbmVlZCB0bworLy8vIHNldHVwIGEgQ29tYmluZXJJbmZvIGFuZCBjYWxsIGNvbWJpbmVNYWNoaW5lRnVuY3Rpb24uCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fR0xPQkFMSVNFTF9DT01CSU5FUl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX0NPTUJJTkVSX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL01hY2hpbmVJUkJ1aWxkZXIuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uUGFzcy5oIgorCituYW1lc3BhY2UgbGx2bSB7CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworY2xhc3MgQ29tYmluZXJJbmZvOworY2xhc3MgVGFyZ2V0UGFzc0NvbmZpZzsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKKworY2xhc3MgQ29tYmluZXIgeworcHVibGljOgorICBDb21iaW5lcihDb21iaW5lckluZm8gJkNvbWJpbmVySW5mbywgY29uc3QgVGFyZ2V0UGFzc0NvbmZpZyAqVFBDKTsKKworICBib29sIGNvbWJpbmVNYWNoaW5lSW5zdHJzKE1hY2hpbmVGdW5jdGlvbiAmTUYpOworCitwcm90ZWN0ZWQ6CisgIENvbWJpbmVySW5mbyAmQ0luZm87CisKKyAgTWFjaGluZVJlZ2lzdGVySW5mbyAqTVJJID0gbnVsbHB0cjsKKyAgY29uc3QgVGFyZ2V0UGFzc0NvbmZpZyAqVFBDOworICBNYWNoaW5lSVJCdWlsZGVyIEJ1aWxkZXI7Cit9OworCit9IC8vIEVuZCBuYW1lc3BhY2UgbGx2bS4KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX0dJQ09NQklORVJfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvQ29tYmluZXJIZWxwZXIuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0NvbWJpbmVySGVscGVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWQ1YjgzOQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0NvbWJpbmVySGVscGVyLmgKQEAgLTAsMCArMSw0NCBAQAorLy89PSBsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9Db21iaW5lckhlbHBlci5oIC0tLS0tLS0tLS0tLS0tIC0qLSBDKysgLSotPT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLy8gVGhpcyBjb250YWlucyBjb21tb24gY29tYmluZSB0cmFuc2Zvcm1hdGlvbnMgdGhhdCBtYXkgYmUgdXNlZCBpbiBhIGNvbWJpbmUKKy8vLyBwYXNzLG9yIGJ5IHRoZSB0YXJnZXQgZWxzZXdoZXJlLgorLy8vIFRhcmdldHMgY2FuIHBpY2sgaW5kaXZpZHVhbCBvcGNvZGUgdHJhbnNmb3JtYXRpb25zIGZyb20gdGhlIGhlbHBlciBvciB1c2UKKy8vLyB0cnlDb21iaW5lIHdoaWNoIGludm9rZXMgYWxsIHRyYW5zZm9ybWF0aW9ucy4gQWxsIG9mIHRoZSB0cmFuc2Zvcm1hdGlvbnMKKy8vLyByZXR1cm4gdHJ1ZSBpZiB0aGUgTWFjaGluZUluc3RydWN0aW9uIGNoYW5nZWQgYW5kIGZhbHNlIG90aGVyd2lzZS4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fR0xPQkFMSVNFTF9DT01CSU5FUl9IRUxQRVJfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fR0xPQkFMSVNFTF9DT01CSU5FUl9IRUxQRVJfSAorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIE1hY2hpbmVJUkJ1aWxkZXI7CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworY2xhc3MgTWFjaGluZUluc3RyOworCitjbGFzcyBDb21iaW5lckhlbHBlciB7CisgIE1hY2hpbmVJUkJ1aWxkZXIgJkJ1aWxkZXI7CisgIE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSTsKKworcHVibGljOgorICBDb21iaW5lckhlbHBlcihNYWNoaW5lSVJCdWlsZGVyICZCKTsKKworICAvLy8gSWYgXHAgTUkgaXMgQ09QWSwgdHJ5IHRvIGNvbWJpbmUgaXQuCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgTUkgY2hhbmdlZC4KKyAgYm9vbCB0cnlDb21iaW5lQ29weShNYWNoaW5lSW5zdHIgJk1JKTsKKworICAvLy8gVHJ5IHRvIHRyYW5zZm9ybSBccCBNSSBieSB1c2luZyBhbGwgb2YgdGhlIGFib3ZlCisgIC8vLyBjb21iaW5lIGZ1bmN0aW9ucy4gUmV0dXJucyB0cnVlIGlmIGNoYW5nZWQuCisgIGJvb2wgdHJ5Q29tYmluZShNYWNoaW5lSW5zdHIgJk1JKTsKK307Cit9IC8vIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvQ29tYmluZXJJbmZvLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9Db21iaW5lckluZm8uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZDI0ODU0Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvQ29tYmluZXJJbmZvLmgKQEAgLTAsMCArMSw0OCBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0NvbWJpbmVySW5mby5oIC0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vLyBJbnRlcmZhY2UgZm9yIFRhcmdldHMgdG8gc3BlY2lmeSB3aGljaCBvcGVyYXRpb25zIGFyZSBjb21iaW5lZCBob3cgYW5kIHdoZW4uCisvLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfQ09NQklORVJfSU5GT19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX0NPTUJJTkVSX0lORk9fSAorCisjaW5jbHVkZSA8Y2Fzc2VydD4KK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgTGVnYWxpemVySW5mbzsKK2NsYXNzIE1hY2hpbmVJbnN0cjsKK2NsYXNzIE1hY2hpbmVJUkJ1aWxkZXI7CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworLy8gQ29udGFpbnMgaW5mb3JtYXRpb24gcmVsZXZhbnQgdG8gZW5hYmxpbmcvZGlzYWJsaW5nIHZhcmlvdXMgY29tYmluZXMgZm9yIGEKKy8vIHBhc3MuCitjbGFzcyBDb21iaW5lckluZm8geworcHVibGljOgorICBDb21iaW5lckluZm8oYm9vbCBBbGxvd0lsbGVnYWxPcHMsIGJvb2wgU2hvdWxkTGVnYWxpemVJbGxlZ2FsLAorICAgICAgICAgICAgICAgTGVnYWxpemVySW5mbyAqTEluZm8pCisgICAgICA6IElsbGVnYWxPcHNBbGxvd2VkKEFsbG93SWxsZWdhbE9wcyksCisgICAgICAgIExlZ2FsaXplSWxsZWdhbE9wcyhTaG91bGRMZWdhbGl6ZUlsbGVnYWwpLCBMSW5mbyhMSW5mbykgeworICAgIGFzc2VydCgoKEFsbG93SWxsZWdhbE9wcyB8fCAhTGVnYWxpemVJbGxlZ2FsT3BzKSB8fCBMSW5mbykgJiYKKyAgICAgICAgICAgIkV4cGVjdGluZyBsZWdhbGl6ZXJJbmZvIHdoZW4gaWxsZWdhbG9wcyBub3QgYWxsb3dlZCIpOworICB9CisgIHZpcnR1YWwgfkNvbWJpbmVySW5mbygpID0gZGVmYXVsdDsKKyAgLy8vIElmIFxwIElsbGVnYWxPcHNBbGxvd2VkIGlzIGZhbHNlLCB0aGUgQ29tYmluZXJIZWxwZXIgd2lsbCBtYWtlIHVzZSBvZgorICAvLy8gdGhlIGxlZ2FsaXplckluZm8gdG8gY2hlY2sgZm9yIGxlZ2FsaXR5IGJlZm9yZSBlYWNoIHRyYW5zZm9ybWF0aW9uLgorICBib29sIElsbGVnYWxPcHNBbGxvd2VkOyAvLyBUT0RPOiBNYWtlIHVzZSBvZiB0aGlzLgorCisgIC8vLyBJZiBccCBMZWdhbGl6ZUlsbGVnYWxPcHMgaXMgdHJ1ZSwgdGhlIENvbWJpbmVyIHdpbGwgYWxzbyBsZWdhbGl6ZSB0aGUKKyAgLy8vIGlsbGVnYWwgb3BzIHRoYXQgYXJlIGNyZWF0ZWQuCisgIGJvb2wgTGVnYWxpemVJbGxlZ2FsT3BzOyAvLyBUT0RPOiBNYWtlIHVzZSBvZiB0aGlzLgorICBjb25zdCBMZWdhbGl6ZXJJbmZvICpMSW5mbzsKKyAgdmlydHVhbCBib29sIGNvbWJpbmUoTWFjaGluZUluc3RyICZNSSwgTWFjaGluZUlSQnVpbGRlciAmQikgY29uc3QgPSAwOworfTsKK30gLy8gbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9HSVNlbFdvcmtMaXN0LmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9HSVNlbFdvcmtMaXN0LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTY3OTA1ZAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0dJU2VsV29ya0xpc3QuaApAQCAtMCwwICsxLDY5IEBACisvLz09PS0gR0lTZWxXb3JrTGlzdC5oIC0gV29ya2xpc3QgZm9yIEdJU2VsIHBhc3NlcyAtLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9HSVNFTF9XT1JLTElTVF9ICisjZGVmaW5lIExMVk1fR0lTRUxfV09SS0xJU1RfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9EZWJ1Zy5oIgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIE1hY2hpbmVJbnN0cjsKKworLy8gV29ya2xpc3Qgd2hpY2ggbW9zdGx5IHdvcmtzIHNpbWlsYXIgdG8gSW5zdENvbWJpbmVXb3JrTGlzdCwgYnV0IG9uIE1hY2hpbmVJbnN0cnMuCisvLyBUaGUgbWFpbiBkaWZmZXJlbmNlIHdpdGggc29tZXRoaW5nIGxpa2UgYSBTZXRWZWN0b3IgaXMgdGhhdCBlcmFzaW5nIGFuIGVsZW1lbnQgZG9lc24ndAorLy8gbW92ZSBhbGwgZWxlbWVudHMgb3ZlciBvbmUgcGxhY2UgLSBpbnN0ZWFkIGp1c3QgbnVsbHMgb3V0IHRoZSBlbGVtZW50IG9mIHRoZSB2ZWN0b3IuCisvLyBGSVhNRTogRG9lcyBpdCBtYWtlIHNlbnNlIHRvIGZhY3RvciBvdXQgY29tbW9uIGNvZGUgd2l0aCB0aGUgaW5zdGNvbWJpbmVyV29ya0xpc3Q/Cit0ZW1wbGF0ZTx1bnNpZ25lZCBOPgorY2xhc3MgR0lTZWxXb3JrTGlzdCB7CisgIFNtYWxsVmVjdG9yPE1hY2hpbmVJbnN0ciosIE4+IFdvcmtsaXN0OworICBEZW5zZU1hcDxNYWNoaW5lSW5zdHIqLCB1bnNpZ25lZD4gV29ya2xpc3RNYXA7CisKK3B1YmxpYzoKKyAgR0lTZWxXb3JrTGlzdCgpID0gZGVmYXVsdDsKKworICBib29sIGVtcHR5KCkgY29uc3QgeyByZXR1cm4gV29ya2xpc3RNYXAuZW1wdHkoKTsgfQorCisgIHVuc2lnbmVkIHNpemUoKSBjb25zdCB7IHJldHVybiBXb3JrbGlzdE1hcC5zaXplKCk7IH0KKworICAvLy8gQWRkIC0gQWRkIHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24gdG8gdGhlIHdvcmtsaXN0IGlmIGl0IGlzbid0IGFscmVhZHkKKyAgLy8vIGluIGl0LgorICB2b2lkIGluc2VydChNYWNoaW5lSW5zdHIgKkkpIHsKKyAgICBpZiAoV29ya2xpc3RNYXAudHJ5X2VtcGxhY2UoSSwgV29ya2xpc3Quc2l6ZSgpKS5zZWNvbmQpIHsKKyAgICAgIFdvcmtsaXN0LnB1c2hfYmFjayhJKTsKKyAgICB9CisgIH0KKworICAvLy8gUmVtb3ZlIC0gcmVtb3ZlIEkgZnJvbSB0aGUgd29ya2xpc3QgaWYgaXQgZXhpc3RzLgorICB2b2lkIHJlbW92ZShNYWNoaW5lSW5zdHIgKkkpIHsKKyAgICBhdXRvIEl0ID0gV29ya2xpc3RNYXAuZmluZChJKTsKKyAgICBpZiAoSXQgPT0gV29ya2xpc3RNYXAuZW5kKCkpIHJldHVybjsgLy8gTm90IGluIHdvcmtsaXN0LgorCisgICAgLy8gRG9uJ3QgYm90aGVyIG1vdmluZyBldmVyeXRoaW5nIGRvd24sIGp1c3QgbnVsbCBvdXQgdGhlIHNsb3QuCisgICAgV29ya2xpc3RbSXQtPnNlY29uZF0gPSBudWxscHRyOworCisgICAgV29ya2xpc3RNYXAuZXJhc2UoSXQpOworICB9CisKKyAgTWFjaGluZUluc3RyICpwb3BfYmFja192YWwoKSB7CisgICAgTWFjaGluZUluc3RyICpJOworICAgIGRvIHsKKyAgICAgIEkgPSBXb3JrbGlzdC5wb3BfYmFja192YWwoKTsKKyAgICB9IHdoaWxlKCFJKTsKKyAgICBhc3NlcnQoSSAmJiAiUG9wIGJhY2sgb24gZW1wdHkgd29ya2xpc3QiKTsKKyAgICBXb3JrbGlzdE1hcC5lcmFzZShJKTsKKyAgICByZXR1cm4gSTsKKyAgfQorfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0uCisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvSVJUcmFuc2xhdG9yLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9JUlRyYW5zbGF0b3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43MDYxYzAxCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvSVJUcmFuc2xhdG9yLmgKQEAgLTAsMCArMSw0NDQgQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9JUlRyYW5zbGF0b3IuaCAtIElSVHJhbnNsYXRvciAtLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gXGZpbGUKKy8vLyBUaGlzIGZpbGUgZGVjbGFyZXMgdGhlIElSVHJhbnNsYXRvciBwYXNzLgorLy8vIFRoaXMgcGFzcyBpcyByZXNwb25zaWJsZSBmb3IgdHJhbnNsYXRpbmcgTExWTSBJUiBpbnRvIE1hY2hpbmVJbnN0ci4KKy8vLyBJdCB1c2VzIHRhcmdldCBob29rcyB0byBsb3dlciB0aGUgQUJJIGJ1dCBhc2lkZSBmcm9tIHRoYXQsIHRoZSBwYXNzCisvLy8gZ2VuZXJhdGVkIGNvZGUgaXMgZ2VuZXJpYy4gVGhpcyBpcyB0aGUgZGVmYXVsdCB0cmFuc2xhdG9yIHVzZWQgZm9yCisvLy8gR2xvYmFsSVNlbC4KKy8vLworLy8vIFx0b2RvIFJlcGxhY2UgdGhlIGNvbW1lbnRzIHdpdGggYWN0dWFsIGRveHlnZW4gY29tbWVudHMuCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX0lSVFJBTlNMQVRPUl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX0lSVFJBTlNMQVRPUl9ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9EZW5zZU1hcC5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTWFjaGluZUlSQnVpbGRlci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL1R5cGVzLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvblBhc3MuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0ludHJpbnNpY3MuaCIKKyNpbmNsdWRlIDxtZW1vcnk+CisjaW5jbHVkZSA8dXRpbGl0eT4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBBbGxvY2FJbnN0OworY2xhc3MgQmFzaWNCbG9jazsKK2NsYXNzIENhbGxJbnN0OworY2xhc3MgQ2FsbExvd2VyaW5nOworY2xhc3MgQ29uc3RhbnQ7CitjbGFzcyBEYXRhTGF5b3V0OworY2xhc3MgSW5zdHJ1Y3Rpb247CitjbGFzcyBNYWNoaW5lQmFzaWNCbG9jazsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIE1hY2hpbmVJbnN0cjsKK2NsYXNzIE1hY2hpbmVSZWdpc3RlckluZm87CitjbGFzcyBPcHRpbWl6YXRpb25SZW1hcmtFbWl0dGVyOworY2xhc3MgUEhJTm9kZTsKK2NsYXNzIFRhcmdldFBhc3NDb25maWc7CitjbGFzcyBVc2VyOworY2xhc3MgVmFsdWU7CisKKy8vIFRlY2huaWNhbGx5IHRoZSBwYXNzIHNob3VsZCBydW4gb24gYW4gaHlwb3RoZXRpY2FsIE1hY2hpbmVNb2R1bGUsCisvLyBzaW5jZSBpdCBzaG91bGQgdHJhbnNsYXRlIEdsb2JhbCBpbnRvIHNvbWUgc29ydCBvZiBNYWNoaW5lR2xvYmFsLgorLy8gVGhlIE1hY2hpbmVHbG9iYWwgc2hvdWxkIHVsdGltYXRlbHkganVzdCBiZSBhIHRyYW5zZmVyIG9mIG93bmVyc2hpcCBvZgorLy8gdGhlIGludGVyZXN0aW5nIGJpdHMgdGhhdCBhcmUgcmVsZXZhbnQgdG8gcmVwcmVzZW50IGEgZ2xvYmFsIHZhbHVlLgorLy8gVGhhdCBiZWluZyBzYWlkLCB3ZSBjb3VsZCBpbnZlc3RpZ2F0ZSB3aGF0IHdvdWxkIGl0IGNvc3QgdG8ganVzdCBkdXBsaWNhdGUKKy8vIHRoZSBpbmZvcm1hdGlvbiBmcm9tIHRoZSBMTFZNIElSLgorLy8gVGhlIGlkZWEgaXMgdGhhdCB1bHRpbWF0ZWx5IHdlIHdvdWxkIGJlIGFibGUgdG8gZnJlZSB1cCB0aGUgbWVtb3J5IHVzZWQKKy8vIGJ5IHRoZSBMTFZNIElSIGFzIHNvb24gYXMgdGhlIHRyYW5zbGF0aW9uIGlzIG92ZXIuCitjbGFzcyBJUlRyYW5zbGF0b3IgOiBwdWJsaWMgTWFjaGluZUZ1bmN0aW9uUGFzcyB7CitwdWJsaWM6CisgIHN0YXRpYyBjaGFyIElEOworCitwcml2YXRlOgorICAvLy8gSW50ZXJmYWNlIHVzZWQgdG8gbG93ZXIgdGhlIGV2ZXJ5dGhpbmcgcmVsYXRlZCB0byBjYWxscy4KKyAgY29uc3QgQ2FsbExvd2VyaW5nICpDTEk7CisKKyAgLy8vIE1hcHBpbmcgb2YgdGhlIHZhbHVlcyBvZiB0aGUgY3VycmVudCBMTFZNIElSIGZ1bmN0aW9uCisgIC8vLyB0byB0aGUgcmVsYXRlZCB2aXJ0dWFsIHJlZ2lzdGVycy4KKyAgVmFsdWVUb1ZSZWcgVmFsVG9WUmVnOworCisgIC8vIE4uYi4gaXQncyBub3QgY29tcGxldGVseSBvYnZpb3VzIHRoYXQgdGhpcyB3aWxsIGJlIHN1ZmZpY2llbnQgZm9yIGV2ZXJ5CisgIC8vIExMVk0gSVIgY29uc3RydWN0ICh3aXRoICJpbnZva2UiIGJlaW5nIHRoZSBvYnZpb3VzIGNhbmRpZGF0ZSB0byBtZXNzIHVwIG91cgorICAvLyBsaXZlcy4KKyAgRGVuc2VNYXA8Y29uc3QgQmFzaWNCbG9jayAqLCBNYWNoaW5lQmFzaWNCbG9jayAqPiBCQlRvTUJCOworCisgIC8vIE9uZSBCYXNpY0Jsb2NrIGNhbiBiZSB0cmFuc2xhdGVkIHRvIG11bHRpcGxlIE1hY2hpbmVCYXNpY0Jsb2Nrcy4gIEZvciBzdWNoCisgIC8vIEJhc2ljQmxvY2tzIHRyYW5zbGF0ZWQgdG8gbXVsdGlwbGUgTWFjaGluZUJhc2ljQmxvY2tzLCBNYWNoaW5lUHJlZHMgcmV0YWlucworICAvLyBhIG1hcHBpbmcgYmV0d2VlbiB0aGUgZWRnZXMgYXJyaXZpbmcgYXQgdGhlIEJhc2ljQmxvY2sgdG8gdGhlIGNvcnJlc3BvbmRpbmcKKyAgLy8gY3JlYXRlZCBNYWNoaW5lQmFzaWNCbG9ja3MuIFNvbWUgQmFzaWNCbG9ja3MgdGhhdCBnZXQgdHJhbnNsYXRlZCB0byBhCisgIC8vIHNpbmdsZSBNYWNoaW5lQmFzaWNCbG9jayBtYXkgYWxzbyBlbmQgdXAgaW4gdGhpcyBNYXAuCisgIHVzaW5nIENGR0VkZ2UgPSBzdGQ6OnBhaXI8Y29uc3QgQmFzaWNCbG9jayAqLCBjb25zdCBCYXNpY0Jsb2NrICo+OworICBEZW5zZU1hcDxDRkdFZGdlLCBTbWFsbFZlY3RvcjxNYWNoaW5lQmFzaWNCbG9jayAqLCAxPj4gTWFjaGluZVByZWRzOworCisgIC8vIExpc3Qgb2Ygc3R1YmJlZCBQSEkgaW5zdHJ1Y3Rpb25zLCBmb3IgdmFsdWVzIGFuZCBiYXNpYyBibG9ja3MgdG8gYmUgZmlsbGVkCisgIC8vIGluIG9uY2UgYWxsIE1hY2hpbmVCYXNpY0Jsb2NrcyBoYXZlIGJlZW4gY3JlYXRlZC4KKyAgU21hbGxWZWN0b3I8c3RkOjpwYWlyPGNvbnN0IFBISU5vZGUgKiwgTWFjaGluZUluc3RyICo+LCA0PiBQZW5kaW5nUEhJczsKKworICAvLy8gUmVjb3JkIG9mIHdoYXQgZnJhbWUgaW5kZXggaGFzIGJlZW4gYWxsb2NhdGVkIHRvIHNwZWNpZmllZCBhbGxvY2FzIGZvcgorICAvLy8gdGhpcyBmdW5jdGlvbi4KKyAgRGVuc2VNYXA8Y29uc3QgQWxsb2NhSW5zdCAqLCBpbnQ+IEZyYW1lSW5kaWNlczsKKworICAvLy8gXG5hbWUgTWV0aG9kcyBmb3IgdHJhbnNsYXRpbmcgZm9ybSBMTFZNIElSIHRvIE1hY2hpbmVJbnN0ci4KKyAgLy8vIFxzZWUgOjp0cmFuc2xhdGUgZm9yIGdlbmVyYWwgaW5mb3JtYXRpb24gb24gdGhlIHRyYW5zbGF0ZSBtZXRob2RzLgorICAvLy8gQHsKKworICAvLy8gVHJhbnNsYXRlIFxwIEluc3QgaW50byBpdHMgY29ycmVzcG9uZGluZyBNYWNoaW5lSW5zdHIgaW5zdHJ1Y3Rpb24ocykuCisgIC8vLyBJbnNlcnQgdGhlIG5ld2x5IHRyYW5zbGF0ZWQgaW5zdHJ1Y3Rpb24ocykgcmlnaHQgd2hlcmUgdGhlIEN1ckJ1aWxkZXIKKyAgLy8vIGlzIHNldC4KKyAgLy8vCisgIC8vLyBUaGUgZ2VuZXJhbCBhbGdvcml0aG0gaXM6CisgIC8vLyAxLiBMb29rIGZvciBhIHZpcnR1YWwgcmVnaXN0ZXIgZm9yIGVhY2ggb3BlcmFuZCBvcgorICAvLy8gICAgY3JlYXRlIG9uZS4KKyAgLy8vIDIgVXBkYXRlIHRoZSBWYWxUb1ZSZWcgYWNjb3JkaW5nbHkuCisgIC8vLyAyLmFsdC4gRm9yIGNvbnN0YW50IGFyZ3VtZW50cywgaWYgdGhleSBhcmUgY29tcGlsZSB0aW1lIGNvbnN0YW50cywKKyAgLy8vICAgcHJvZHVjZSBhbiBpbW1lZGlhdGUgaW4gdGhlIHJpZ2h0IG9wZXJhbmQgYW5kIGRvIG5vdCB0b3VjaAorICAvLy8gICBWYWxUb1JlZy4gQWN0dWFsbHkgd2Ugd2lsbCBnbyB3aXRoIGEgdmlydHVhbCByZWdpc3RlciBmb3IgZWFjaAorICAvLy8gICBjb25zdGFudHMgYmVjYXVzZSBpdCBtYXkgYmUgZXhwZW5zaXZlIHRvIGFjdHVhbGx5IG1hdGVyaWFsaXplIHRoZQorICAvLy8gICBjb25zdGFudC4gTW9yZW92ZXIsIGlmIHRoZSBjb25zdGFudCBzcGFucyBvbiBzZXZlcmFsIGluc3RydWN0aW9ucywKKyAgLy8vICAgQ1NFIG1heSBub3QgY2F0Y2ggdGhlbS4KKyAgLy8vICAgPT4gVXBkYXRlIFZhbFRvVlJlZyBhbmQgcmVtZW1iZXIgdGhhdCB3ZSBzYXcgYSBjb25zdGFudCBpbiBDb25zdGFudHMuCisgIC8vLyAgIFdlIHdpbGwgbWF0ZXJpYWxpemUgYWxsIHRoZSBjb25zdGFudHMgaW4gZmluYWxpemUuCisgIC8vLyBOb3RlOiB3ZSB3b3VsZCBuZWVkIHRvIGRvIHNvbWV0aGluZyBzbyB0aGF0IHdlIGNhbiByZWNvZ25pemUgc3VjaCBvcGVyYW5kCisgIC8vLyAgICAgICBhcyBjb25zdGFudHMuCisgIC8vLyAzLiBDcmVhdGUgdGhlIGdlbmVyaWMgaW5zdHJ1Y3Rpb24uCisgIC8vLworICAvLy8gXHJldHVybiB0cnVlIGlmIHRoZSB0cmFuc2xhdGlvbiBzdWNjZWVkZWQuCisgIGJvb2wgdHJhbnNsYXRlKGNvbnN0IEluc3RydWN0aW9uICZJbnN0KTsKKworICAvLy8gTWF0ZXJpYWxpemUgXHAgQyBpbnRvIHZpcnR1YWwtcmVnaXN0ZXIgXHAgUmVnLiBUaGUgZ2VuZXJpYyBpbnN0cnVjdGlvbnMKKyAgLy8vIHBlcmZvcm1pbmcgdGhpcyBtYXRlcmlhbGl6YXRpb24gd2lsbCBiZSBpbnNlcnRlZCBpbnRvIHRoZSBlbnRyeSBibG9jayBvZgorICAvLy8gdGhlIGZ1bmN0aW9uLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gdHJ1ZSBpZiB0aGUgbWF0ZXJpYWxpemF0aW9uIHN1Y2NlZWRlZC4KKyAgYm9vbCB0cmFuc2xhdGUoY29uc3QgQ29uc3RhbnQgJkMsIHVuc2lnbmVkIFJlZyk7CisKKyAgLy8vIFRyYW5zbGF0ZSBhbiBMTFZNIGJpdGNhc3QgaW50byBnZW5lcmljIElSLiBFaXRoZXIgYSBDT1BZIG9yIGEgR19CSVRDQVNUIGlzCisgIC8vLyBlbWl0dGVkLgorICBib29sIHRyYW5zbGF0ZUJpdENhc3QoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcik7CisKKyAgLy8vIFRyYW5zbGF0ZSBhbiBMTFZNIGxvYWQgaW5zdHJ1Y3Rpb24gaW50byBnZW5lcmljIElSLgorICBib29sIHRyYW5zbGF0ZUxvYWQoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcik7CisKKyAgLy8vIFRyYW5zbGF0ZSBhbiBMTFZNIHN0b3JlIGluc3RydWN0aW9uIGludG8gZ2VuZXJpYyBJUi4KKyAgYm9vbCB0cmFuc2xhdGVTdG9yZShjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKTsKKworICAvLy8gVHJhbnNsYXRlIGFuIExMVk0gc3RyaW5nIGludHJpbnNpYyAobWVtY3B5LCBtZW1zZXQsIC4uLikuCisgIGJvb2wgdHJhbnNsYXRlTWVtZnVuYyhjb25zdCBDYWxsSW5zdCAmQ0ksIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBJbnRyaW5zaWMpOworCisgIHZvaWQgZ2V0U3RhY2tHdWFyZCh1bnNpZ25lZCBEc3RSZWcsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpOworCisgIGJvb2wgdHJhbnNsYXRlT3ZlcmZsb3dJbnRyaW5zaWMoY29uc3QgQ2FsbEluc3QgJkNJLCB1bnNpZ25lZCBPcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKTsKKworICBib29sIHRyYW5zbGF0ZUtub3duSW50cmluc2ljKGNvbnN0IENhbGxJbnN0ICZDSSwgSW50cmluc2ljOjpJRCBJRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKTsKKworICBib29sIHRyYW5zbGF0ZUlubGluZUFzbShjb25zdCBDYWxsSW5zdCAmQ0ksIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpOworCisgIC8vLyBUcmFuc2xhdGUgY2FsbCBpbnN0cnVjdGlvbi4KKyAgLy8vIFxwcmUgXHAgVSBpcyBhIGNhbGwgaW5zdHJ1Y3Rpb24uCisgIGJvb2wgdHJhbnNsYXRlQ2FsbChjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKTsKKworICBib29sIHRyYW5zbGF0ZUludm9rZShjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKTsKKworICBib29sIHRyYW5zbGF0ZUxhbmRpbmdQYWQoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcik7CisKKyAgLy8vIFRyYW5zbGF0ZSBvbmUgb2YgTExWTSdzIGNhc3QgaW5zdHJ1Y3Rpb25zIGludG8gTWFjaGluZUluc3Rycywgd2l0aCB0aGUKKyAgLy8vIGdpdmVuIGdlbmVyaWMgT3Bjb2RlLgorICBib29sIHRyYW5zbGF0ZUNhc3QodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBVc2VyICZVLAorICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcik7CisKKyAgLy8vIFRyYW5zbGF0ZSBhIHBoaSBpbnN0cnVjdGlvbi4KKyAgYm9vbCB0cmFuc2xhdGVQSEkoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcik7CisKKyAgLy8vIFRyYW5zbGF0ZSBhIGNvbXBhcmlzb24gKGljbXAgb3IgZmNtcCkgaW5zdHJ1Y3Rpb24gb3IgY29uc3RhbnQuCisgIGJvb2wgdHJhbnNsYXRlQ29tcGFyZShjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKTsKKworICAvLy8gVHJhbnNsYXRlIGFuIGludGVnZXIgY29tcGFyZSBpbnN0cnVjdGlvbiAob3IgY29uc3RhbnQpLgorICBib29sIHRyYW5zbGF0ZUlDbXAoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiB0cmFuc2xhdGVDb21wYXJlKFUsIE1JUkJ1aWxkZXIpOworICB9CisKKyAgLy8vIFRyYW5zbGF0ZSBhIGZsb2F0aW5nLXBvaW50IGNvbXBhcmUgaW5zdHJ1Y3Rpb24gKG9yIGNvbnN0YW50KS4KKyAgYm9vbCB0cmFuc2xhdGVGQ21wKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gdHJhbnNsYXRlQ29tcGFyZShVLCBNSVJCdWlsZGVyKTsKKyAgfQorCisgIC8vLyBBZGQgcmVtYWluaW5nIG9wZXJhbmRzIG9udG8gcGhpcyB3ZSd2ZSB0cmFuc2xhdGVkLiBFeGVjdXRlZCBhZnRlciBhbGwKKyAgLy8vIE1hY2hpbmVCYXNpY0Jsb2NrcyBmb3IgdGhlIGZ1bmN0aW9uIGhhdmUgYmVlbiBjcmVhdGVkLgorICB2b2lkIGZpbmlzaFBlbmRpbmdQaGlzKCk7CisKKyAgLy8vIFRyYW5zbGF0ZSBccCBJbnN0IGludG8gYSBiaW5hcnkgb3BlcmF0aW9uIFxwIE9wY29kZS4KKyAgLy8vIFxwcmUgXHAgVSBpcyBhIGJpbmFyeSBvcGVyYXRpb24uCisgIGJvb2wgdHJhbnNsYXRlQmluYXJ5T3AodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBVc2VyICZVLAorICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpOworCisgIC8vLyBUcmFuc2xhdGUgYnJhbmNoIChicikgaW5zdHJ1Y3Rpb24uCisgIC8vLyBccHJlIFxwIFUgaXMgYSBicmFuY2ggaW5zdHJ1Y3Rpb24uCisgIGJvb2wgdHJhbnNsYXRlQnIoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcik7CisKKyAgYm9vbCB0cmFuc2xhdGVTd2l0Y2goY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcik7CisKKyAgYm9vbCB0cmFuc2xhdGVJbmRpcmVjdEJyKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpOworCisgIGJvb2wgdHJhbnNsYXRlRXh0cmFjdFZhbHVlKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpOworCisgIGJvb2wgdHJhbnNsYXRlSW5zZXJ0VmFsdWUoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcik7CisKKyAgYm9vbCB0cmFuc2xhdGVTZWxlY3QoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcik7CisKKyAgYm9vbCB0cmFuc2xhdGVHZXRFbGVtZW50UHRyKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpOworCisgIGJvb2wgdHJhbnNsYXRlQWxsb2NhKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpOworCisgIC8vLyBUcmFuc2xhdGUgcmV0dXJuIChyZXQpIGluc3RydWN0aW9uLgorICAvLy8gVGhlIHRhcmdldCBuZWVkcyB0byBpbXBsZW1lbnQgQ2FsbExvd2VyaW5nOjpsb3dlclJldHVybiBmb3IKKyAgLy8vIHRoaXMgdG8gc3VjY2VlZC4KKyAgLy8vIFxwcmUgXHAgVSBpcyBhIHJldHVybiBpbnN0cnVjdGlvbi4KKyAgYm9vbCB0cmFuc2xhdGVSZXQoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcik7CisKKyAgYm9vbCB0cmFuc2xhdGVGU3ViKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpOworCisgIGJvb2wgdHJhbnNsYXRlQWRkKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gdHJhbnNsYXRlQmluYXJ5T3AoVGFyZ2V0T3Bjb2RlOjpHX0FERCwgVSwgTUlSQnVpbGRlcik7CisgIH0KKyAgYm9vbCB0cmFuc2xhdGVTdWIoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiB0cmFuc2xhdGVCaW5hcnlPcChUYXJnZXRPcGNvZGU6OkdfU1VCLCBVLCBNSVJCdWlsZGVyKTsKKyAgfQorICBib29sIHRyYW5zbGF0ZUFuZChjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSB7CisgICAgcmV0dXJuIHRyYW5zbGF0ZUJpbmFyeU9wKFRhcmdldE9wY29kZTo6R19BTkQsIFUsIE1JUkJ1aWxkZXIpOworICB9CisgIGJvb2wgdHJhbnNsYXRlTXVsKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gdHJhbnNsYXRlQmluYXJ5T3AoVGFyZ2V0T3Bjb2RlOjpHX01VTCwgVSwgTUlSQnVpbGRlcik7CisgIH0KKyAgYm9vbCB0cmFuc2xhdGVPcihjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSB7CisgICAgcmV0dXJuIHRyYW5zbGF0ZUJpbmFyeU9wKFRhcmdldE9wY29kZTo6R19PUiwgVSwgTUlSQnVpbGRlcik7CisgIH0KKyAgYm9vbCB0cmFuc2xhdGVYb3IoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiB0cmFuc2xhdGVCaW5hcnlPcChUYXJnZXRPcGNvZGU6OkdfWE9SLCBVLCBNSVJCdWlsZGVyKTsKKyAgfQorCisgIGJvb2wgdHJhbnNsYXRlVURpdihjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSB7CisgICAgcmV0dXJuIHRyYW5zbGF0ZUJpbmFyeU9wKFRhcmdldE9wY29kZTo6R19VRElWLCBVLCBNSVJCdWlsZGVyKTsKKyAgfQorICBib29sIHRyYW5zbGF0ZVNEaXYoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiB0cmFuc2xhdGVCaW5hcnlPcChUYXJnZXRPcGNvZGU6OkdfU0RJViwgVSwgTUlSQnVpbGRlcik7CisgIH0KKyAgYm9vbCB0cmFuc2xhdGVVUmVtKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gdHJhbnNsYXRlQmluYXJ5T3AoVGFyZ2V0T3Bjb2RlOjpHX1VSRU0sIFUsIE1JUkJ1aWxkZXIpOworICB9CisgIGJvb2wgdHJhbnNsYXRlU1JlbShjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSB7CisgICAgcmV0dXJuIHRyYW5zbGF0ZUJpbmFyeU9wKFRhcmdldE9wY29kZTo6R19TUkVNLCBVLCBNSVJCdWlsZGVyKTsKKyAgfQorICBib29sIHRyYW5zbGF0ZUludFRvUHRyKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gdHJhbnNsYXRlQ2FzdChUYXJnZXRPcGNvZGU6OkdfSU5UVE9QVFIsIFUsIE1JUkJ1aWxkZXIpOworICB9CisgIGJvb2wgdHJhbnNsYXRlUHRyVG9JbnQoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiB0cmFuc2xhdGVDYXN0KFRhcmdldE9wY29kZTo6R19QVFJUT0lOVCwgVSwgTUlSQnVpbGRlcik7CisgIH0KKyAgYm9vbCB0cmFuc2xhdGVUcnVuYyhjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSB7CisgICAgcmV0dXJuIHRyYW5zbGF0ZUNhc3QoVGFyZ2V0T3Bjb2RlOjpHX1RSVU5DLCBVLCBNSVJCdWlsZGVyKTsKKyAgfQorICBib29sIHRyYW5zbGF0ZUZQVHJ1bmMoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiB0cmFuc2xhdGVDYXN0KFRhcmdldE9wY29kZTo6R19GUFRSVU5DLCBVLCBNSVJCdWlsZGVyKTsKKyAgfQorICBib29sIHRyYW5zbGF0ZUZQRXh0KGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gdHJhbnNsYXRlQ2FzdChUYXJnZXRPcGNvZGU6OkdfRlBFWFQsIFUsIE1JUkJ1aWxkZXIpOworICB9CisgIGJvb2wgdHJhbnNsYXRlRlBUb1VJKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gdHJhbnNsYXRlQ2FzdChUYXJnZXRPcGNvZGU6OkdfRlBUT1VJLCBVLCBNSVJCdWlsZGVyKTsKKyAgfQorICBib29sIHRyYW5zbGF0ZUZQVG9TSShjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSB7CisgICAgcmV0dXJuIHRyYW5zbGF0ZUNhc3QoVGFyZ2V0T3Bjb2RlOjpHX0ZQVE9TSSwgVSwgTUlSQnVpbGRlcik7CisgIH0KKyAgYm9vbCB0cmFuc2xhdGVVSVRvRlAoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiB0cmFuc2xhdGVDYXN0KFRhcmdldE9wY29kZTo6R19VSVRPRlAsIFUsIE1JUkJ1aWxkZXIpOworICB9CisgIGJvb2wgdHJhbnNsYXRlU0lUb0ZQKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gdHJhbnNsYXRlQ2FzdChUYXJnZXRPcGNvZGU6OkdfU0lUT0ZQLCBVLCBNSVJCdWlsZGVyKTsKKyAgfQorICBib29sIHRyYW5zbGF0ZVVucmVhY2hhYmxlKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorICBib29sIHRyYW5zbGF0ZVNFeHQoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiB0cmFuc2xhdGVDYXN0KFRhcmdldE9wY29kZTo6R19TRVhULCBVLCBNSVJCdWlsZGVyKTsKKyAgfQorCisgIGJvb2wgdHJhbnNsYXRlWkV4dChjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSB7CisgICAgcmV0dXJuIHRyYW5zbGF0ZUNhc3QoVGFyZ2V0T3Bjb2RlOjpHX1pFWFQsIFUsIE1JUkJ1aWxkZXIpOworICB9CisKKyAgYm9vbCB0cmFuc2xhdGVTaGwoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiB0cmFuc2xhdGVCaW5hcnlPcChUYXJnZXRPcGNvZGU6OkdfU0hMLCBVLCBNSVJCdWlsZGVyKTsKKyAgfQorICBib29sIHRyYW5zbGF0ZUxTaHIoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiB0cmFuc2xhdGVCaW5hcnlPcChUYXJnZXRPcGNvZGU6OkdfTFNIUiwgVSwgTUlSQnVpbGRlcik7CisgIH0KKyAgYm9vbCB0cmFuc2xhdGVBU2hyKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gdHJhbnNsYXRlQmluYXJ5T3AoVGFyZ2V0T3Bjb2RlOjpHX0FTSFIsIFUsIE1JUkJ1aWxkZXIpOworICB9CisKKyAgYm9vbCB0cmFuc2xhdGVGQWRkKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gdHJhbnNsYXRlQmluYXJ5T3AoVGFyZ2V0T3Bjb2RlOjpHX0ZBREQsIFUsIE1JUkJ1aWxkZXIpOworICB9CisgIGJvb2wgdHJhbnNsYXRlRk11bChjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSB7CisgICAgcmV0dXJuIHRyYW5zbGF0ZUJpbmFyeU9wKFRhcmdldE9wY29kZTo6R19GTVVMLCBVLCBNSVJCdWlsZGVyKTsKKyAgfQorICBib29sIHRyYW5zbGF0ZUZEaXYoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiB0cmFuc2xhdGVCaW5hcnlPcChUYXJnZXRPcGNvZGU6OkdfRkRJViwgVSwgTUlSQnVpbGRlcik7CisgIH0KKyAgYm9vbCB0cmFuc2xhdGVGUmVtKGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gdHJhbnNsYXRlQmluYXJ5T3AoVGFyZ2V0T3Bjb2RlOjpHX0ZSRU0sIFUsIE1JUkJ1aWxkZXIpOworICB9CisKKyAgYm9vbCB0cmFuc2xhdGVWQUFyZyhjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKTsKKworICBib29sIHRyYW5zbGF0ZUluc2VydEVsZW1lbnQoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcik7CisKKyAgYm9vbCB0cmFuc2xhdGVFeHRyYWN0RWxlbWVudChjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKTsKKworICBib29sIHRyYW5zbGF0ZVNodWZmbGVWZWN0b3IoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcik7CisKKyAgLy8gU3R1YnMgdG8ga2VlcCB0aGUgY29tcGlsZXIgaGFwcHkgd2hpbGUgd2UgaW1wbGVtZW50IHRoZSByZXN0IG9mIHRoZQorICAvLyB0cmFuc2xhdGlvbi4KKyAgYm9vbCB0cmFuc2xhdGVSZXN1bWUoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBib29sIHRyYW5zbGF0ZUNsZWFudXBSZXQoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBib29sIHRyYW5zbGF0ZUNhdGNoUmV0KGNvbnN0IFVzZXIgJlUsIE1hY2hpbmVJUkJ1aWxkZXIgJk1JUkJ1aWxkZXIpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKyAgYm9vbCB0cmFuc2xhdGVDYXRjaFN3aXRjaChjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGJvb2wgdHJhbnNsYXRlRmVuY2UoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBib29sIHRyYW5zbGF0ZUF0b21pY0NtcFhjaGcoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBib29sIHRyYW5zbGF0ZUF0b21pY1JNVyhjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGJvb2wgdHJhbnNsYXRlQWRkclNwYWNlQ2FzdChjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGJvb2wgdHJhbnNsYXRlQ2xlYW51cFBhZChjb25zdCBVc2VyICZVLCBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisgIGJvb2wgdHJhbnNsYXRlQ2F0Y2hQYWQoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBib29sIHRyYW5zbGF0ZVVzZXJPcDEoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICBib29sIHRyYW5zbGF0ZVVzZXJPcDIoY29uc3QgVXNlciAmVSwgTWFjaGluZUlSQnVpbGRlciAmTUlSQnVpbGRlcikgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBAfQorCisgIC8vIEJ1aWxkZXIgZm9yIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gYSBsYSBJUkJ1aWxkZXIuCisgIC8vIEkuZS4sIGNvbXBhcmVkIHRvIHJlZ3VsYXIgTUlCdWlsZGVyLCB0aGlzIG9uZSBhbHNvIGluc2VydHMgdGhlIGluc3RydWN0aW9uCisgIC8vIGluIHRoZSBjdXJyZW50IGJsb2NrLCBpdCBjYW4gY3JlYXRlcyBibG9jaywgZXRjLiwgYmFzaWNhbGx5IGEga2luZCBvZgorICAvLyBJUkJ1aWxkZXIsIGJ1dCBmb3IgTWFjaGluZSBJUi4KKyAgTWFjaGluZUlSQnVpbGRlciBDdXJCdWlsZGVyOworCisgIC8vIEJ1aWxkZXIgc2V0IHRvIHRoZSBlbnRyeSBibG9jayAoanVzdCBhZnRlciBBQkkgbG93ZXJpbmcgaW5zdHJ1Y3Rpb25zKS4gVXNlZAorICAvLyBhcyBhIGNvbnZlbmllbnQgbG9jYXRpb24gZm9yIENvbnN0YW50cy4KKyAgTWFjaGluZUlSQnVpbGRlciBFbnRyeUJ1aWxkZXI7CisKKyAgLy8gVGhlIE1hY2hpbmVGdW5jdGlvbiBjdXJyZW50bHkgYmVpbmcgdHJhbnNsYXRlZC4KKyAgTWFjaGluZUZ1bmN0aW9uICpNRjsKKworICAvLy8gTWFjaGluZVJlZ2lzdGVySW5mbyB1c2VkIHRvIGNyZWF0ZSB2aXJ0dWFsIHJlZ2lzdGVycy4KKyAgTWFjaGluZVJlZ2lzdGVySW5mbyAqTVJJID0gbnVsbHB0cjsKKworICBjb25zdCBEYXRhTGF5b3V0ICpETDsKKworICAvLy8gQ3VycmVudCB0YXJnZXQgY29uZmlndXJhdGlvbi4gQ29udHJvbHMgaG93IHRoZSBwYXNzIGhhbmRsZXMgZXJyb3JzLgorICBjb25zdCBUYXJnZXRQYXNzQ29uZmlnICpUUEM7CisKKyAgLy8vIEN1cnJlbnQgb3B0aW1pemF0aW9uIHJlbWFyayBlbWl0dGVyLiBVc2VkIHRvIHJlcG9ydCBmYWlsdXJlcy4KKyAgc3RkOjp1bmlxdWVfcHRyPE9wdGltaXphdGlvblJlbWFya0VtaXR0ZXI+IE9SRTsKKworICAvLyAqIEluc2VydCBhbGwgdGhlIGNvZGUgbmVlZGVkIHRvIG1hdGVyaWFsaXplIHRoZSBjb25zdGFudHMKKyAgLy8gYXQgdGhlIHByb3BlciBwbGFjZS4gRS5nLiwgRW50cnkgYmxvY2sgb3IgZG9taW5hdG9yIGJsb2NrCisgIC8vIG9mIGVhY2ggY29uc3RhbnQgZGVwZW5kaW5nIG9uIGhvdyBmYW5jeSB3ZSB3YW50IHRvIGJlLgorICAvLyAqIENsZWFyIHRoZSBkaWZmZXJlbnQgbWFwcy4KKyAgdm9pZCBmaW5hbGl6ZUZ1bmN0aW9uKCk7CisKKyAgLy8vIEdldCB0aGUgVlJlZyB0aGF0IHJlcHJlc2VudHMgXHAgVmFsLgorICAvLy8gSWYgc3VjaCBWUmVnIGRvZXMgbm90IGV4aXN0LCBpdCBpcyBjcmVhdGVkLgorICB1bnNpZ25lZCBnZXRPckNyZWF0ZVZSZWcoY29uc3QgVmFsdWUgJlZhbCk7CisKKyAgLy8vIEdldCB0aGUgZnJhbWUgaW5kZXggdGhhdCByZXByZXNlbnRzIFxwIFZhbC4KKyAgLy8vIElmIHN1Y2ggVlJlZyBkb2VzIG5vdCBleGlzdCwgaXQgaXMgY3JlYXRlZC4KKyAgaW50IGdldE9yQ3JlYXRlRnJhbWVJbmRleChjb25zdCBBbGxvY2FJbnN0ICZBSSk7CisKKyAgLy8vIEdldCB0aGUgYWxpZ25tZW50IG9mIHRoZSBnaXZlbiBtZW1vcnkgb3BlcmF0aW9uIGluc3RydWN0aW9uLiBUaGlzIHdpbGwKKyAgLy8vIGVpdGhlciBiZSB0aGUgZXhwbGljaXRseSBzcGVjaWZpZWQgdmFsdWUgb3IgdGhlIEFCSS1yZXF1aXJlZCBhbGlnbm1lbnQgZm9yCisgIC8vLyB0aGUgdHlwZSBiZWluZyBhY2Nlc3NlZCAoYWNjb3JkaW5nIHRvIHRoZSBNb2R1bGUncyBEYXRhTGF5b3V0KS4KKyAgdW5zaWduZWQgZ2V0TWVtT3BBbGlnbm1lbnQoY29uc3QgSW5zdHJ1Y3Rpb24gJkkpOworCisgIC8vLyBHZXQgdGhlIE1hY2hpbmVCYXNpY0Jsb2NrIHRoYXQgcmVwcmVzZW50cyBccCBCQi4gU3BlY2lmaWNhbGx5LCB0aGUgYmxvY2sKKyAgLy8vIHJldHVybmVkIHdpbGwgYmUgdGhlIGhlYWQgb2YgdGhlIHRyYW5zbGF0ZWQgYmxvY2sgKHN1aXRhYmxlIGZvciBicmFuY2gKKyAgLy8vIGRlc3RpbmF0aW9ucykuCisgIE1hY2hpbmVCYXNpY0Jsb2NrICZnZXRNQkIoY29uc3QgQmFzaWNCbG9jayAmQkIpOworCisgIC8vLyBSZWNvcmQgXHAgTmV3UHJlZCBhcyBhIE1hY2hpbmUgcHJlZGVjZXNzb3IgdG8gYEVkZ2Uuc2Vjb25kYCwgY29ycmVzcG9uZGluZworICAvLy8gdG8gYEVkZ2UuZmlyc3RgIGF0IHRoZSBJUiBsZXZlbC4gVGhpcyBpcyB1c2VkIHdoZW4gSVJUcmFuc2xhdGlvbiBjcmVhdGVzCisgIC8vLyBtdWx0aXBsZSBNYWNoaW5lQmFzaWNCbG9ja3MgZm9yIGEgZ2l2ZW4gSVIgYmxvY2sgYW5kIHRoZSBDRkcgaXMgbm8gbG9uZ2VyCisgIC8vLyByZXByZXNlbnRlZCBzaW1wbHkgYnkgdGhlIElSLWxldmVsIENGRy4KKyAgdm9pZCBhZGRNYWNoaW5lQ0ZHUHJlZChDRkdFZGdlIEVkZ2UsIE1hY2hpbmVCYXNpY0Jsb2NrICpOZXdQcmVkKTsKKworICAvLy8gUmV0dXJucyB0aGUgTWFjaGluZSBJUiBwcmVkZWNlc3NvcnMgZm9yIHRoZSBnaXZlbiBJUiBDRkcgZWRnZS4gVXN1YWxseQorICAvLy8gdGhpcyBpcyBqdXN0IHRoZSBzaW5nbGUgTWFjaGluZUJhc2ljQmxvY2sgY29ycmVzcG9uZGluZyB0byB0aGUgcHJlZGVjZXNzb3IKKyAgLy8vIGluIHRoZSBJUi4gTW9yZSBjb21wbGV4IGxvd2VyaW5nIGNhbiByZXN1bHQgaW4gbXVsdGlwbGUgTWFjaGluZUJhc2ljQmxvY2tzCisgIC8vLyBwcmVjZWRpbmcgdGhlIG9yaWdpbmFsIHRob3VnaCAoZS5nLiBzd2l0Y2ggaW5zdHJ1Y3Rpb25zKS4KKyAgU21hbGxWZWN0b3I8TWFjaGluZUJhc2ljQmxvY2sgKiwgMT4gZ2V0TWFjaGluZVByZWRCQnMoQ0ZHRWRnZSBFZGdlKSB7CisgICAgYXV0byBSZW1hcHBlZEVkZ2UgPSBNYWNoaW5lUHJlZHMuZmluZChFZGdlKTsKKyAgICBpZiAoUmVtYXBwZWRFZGdlICE9IE1hY2hpbmVQcmVkcy5lbmQoKSkKKyAgICAgIHJldHVybiBSZW1hcHBlZEVkZ2UtPnNlY29uZDsKKyAgICByZXR1cm4gU21hbGxWZWN0b3I8TWFjaGluZUJhc2ljQmxvY2sgKiwgND4oMSwgJmdldE1CQigqRWRnZS5maXJzdCkpOworICB9CisKK3B1YmxpYzoKKyAgLy8gQ3Rvciwgbm90aGluZyBmYW5jeS4KKyAgSVJUcmFuc2xhdG9yKCk7CisKKyAgU3RyaW5nUmVmIGdldFBhc3NOYW1lKCkgY29uc3Qgb3ZlcnJpZGUgeyByZXR1cm4gIklSVHJhbnNsYXRvciI7IH0KKworICB2b2lkIGdldEFuYWx5c2lzVXNhZ2UoQW5hbHlzaXNVc2FnZSAmQVUpIGNvbnN0IG92ZXJyaWRlOworCisgIC8vIEFsZ286CisgIC8vICAgQ2FsbExvd2VyaW5nID0gTUYuc3VidGFyZ2V0LmdldENhbGxMb3dlcmluZygpCisgIC8vICAgRiA9IE1GLmdldFBhcmVudCgpCisgIC8vICAgTUlSQnVpbGRlci5yZXNldChNRikKKyAgLy8gICBnZXRNQkIoRi5nZXRFbnRyeUJCKCkpCisgIC8vICAgQ2FsbExvd2VyaW5nLT50cmFuc2xhdGVBcmd1bWVudHMoTUlSQnVpbGRlciwgRiwgVmFsVG9WUmVnKQorICAvLyAgIGZvciBlYWNoIGJiIGluIEYKKyAgLy8gICAgIGdldE1CQihiYikKKyAgLy8gICAgIGZvciBlYWNoIGluc3QgaW4gYmIKKyAgLy8gICAgICAgaWYgKCF0cmFuc2xhdGUoTUlSQnVpbGRlciwgaW5zdCwgVmFsVG9WUmVnLCBDb25zdGFudFRvU2VxdWVuY2UpKQorICAvLyAgICAgICAgIHJlcG9ydF9mYXRhbF9lcnJvcigiRG9uJ3Qga25vdyBob3cgdG8gdHJhbnNsYXRlIGlucHV0Iik7CisgIC8vICAgZmluYWxpemUoKQorICBib29sIHJ1bk9uTWFjaGluZUZ1bmN0aW9uKE1hY2hpbmVGdW5jdGlvbiAmTUYpIG92ZXJyaWRlOworfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX0lSVFJBTlNMQVRPUl9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9JbnN0cnVjdGlvblNlbGVjdC5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvSW5zdHJ1Y3Rpb25TZWxlY3QuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMTUyMWM0Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvSW5zdHJ1Y3Rpb25TZWxlY3QuaApAQCAtMCwwICsxLDUzIEBACisvLz09IGxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0luc3RydWN0aW9uU2VsZWN0LmggLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vIFxmaWxlIFRoaXMgZmlsZSBkZXNjcmliZXMgdGhlIGludGVyZmFjZSBvZiB0aGUgTWFjaGluZUZ1bmN0aW9uUGFzcworLy8vIHJlc3BvbnNpYmxlIGZvciBzZWxlY3RpbmcgKHBvc3NpYmx5IGdlbmVyaWMpIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zIHRvCisvLy8gdGFyZ2V0LXNwZWNpZmljIGluc3RydWN0aW9ucy4KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfSU5TVFJVQ1RJT05TRUxFQ1RfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fR0xPQkFMSVNFTF9JTlNUUlVDVElPTlNFTEVDVF9ICisKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9JbnN0cnVjdGlvblNlbGVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvblBhc3MuaCIKKworbmFtZXNwYWNlIGxsdm0geworLy8vIFRoaXMgcGFzcyBpcyByZXNwb25zaWJsZSBmb3Igc2VsZWN0aW5nIGdlbmVyaWMgbWFjaGluZSBpbnN0cnVjdGlvbnMgdG8KKy8vLyB0YXJnZXQtc3BlY2lmaWMgaW5zdHJ1Y3Rpb25zLiAgSXQgcmVsaWVzIG9uIHRoZSBJbnN0cnVjdGlvblNlbGVjdG9yIHByb3ZpZGVkCisvLy8gYnkgdGhlIHRhcmdldC4KKy8vLyBTZWxlY3Rpb24gaXMgZG9uZSBieSBleGFtaW5pbmcgYmxvY2tzIGluIHBvc3Qtb3JkZXIsIGFuZCBpbnN0cnVjdGlvbnMgaW4KKy8vLyByZXZlcnNlIG9yZGVyLgorLy8vCisvLy8gXHBvc3QgZm9yIGFsbCBpbnN0IGluIE1GOiBub3QgaXNQcmVJU2VsR2VuZXJpY09wY29kZShpbnN0Lm9wY29kZSkKK2NsYXNzIEluc3RydWN0aW9uU2VsZWN0IDogcHVibGljIE1hY2hpbmVGdW5jdGlvblBhc3MgeworcHVibGljOgorICBzdGF0aWMgY2hhciBJRDsKKyAgU3RyaW5nUmVmIGdldFBhc3NOYW1lKCkgY29uc3Qgb3ZlcnJpZGUgeyByZXR1cm4gIkluc3RydWN0aW9uU2VsZWN0IjsgfQorCisgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlICZBVSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcyBnZXRSZXF1aXJlZFByb3BlcnRpZXMoKSBjb25zdCBvdmVycmlkZSB7CisgICAgcmV0dXJuIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMoKQorICAgICAgICAuc2V0KE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXM6OlByb3BlcnR5OjpJc1NTQSkKKyAgICAgICAgLnNldChNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzOjpQcm9wZXJ0eTo6TGVnYWxpemVkKQorICAgICAgICAuc2V0KE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXM6OlByb3BlcnR5OjpSZWdCYW5rU2VsZWN0ZWQpOworICB9CisKKyAgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcyBnZXRTZXRQcm9wZXJ0aWVzKCkgY29uc3Qgb3ZlcnJpZGUgeworICAgIHJldHVybiBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzKCkuc2V0KAorICAgICAgICBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzOjpQcm9wZXJ0eTo6U2VsZWN0ZWQpOworICB9CisKKyAgSW5zdHJ1Y3Rpb25TZWxlY3QoKTsKKworICBib29sIHJ1bk9uTWFjaGluZUZ1bmN0aW9uKE1hY2hpbmVGdW5jdGlvbiAmTUYpIG92ZXJyaWRlOworfTsKK30gLy8gRW5kIG5hbWVzcGFjZSBsbHZtLgorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0luc3RydWN0aW9uU2VsZWN0b3IuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0luc3RydWN0aW9uU2VsZWN0b3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYWNkMTM1Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvSW5zdHJ1Y3Rpb25TZWxlY3Rvci5oCkBAIC0wLDAgKzEsMzgxIEBACisvLz09PS0gbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvSW5zdHJ1Y3Rpb25TZWxlY3Rvci5oIC0tLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vLyBcZmlsZSBUaGlzIGZpbGUgZGVjbGFyZXMgdGhlIEFQSSBmb3IgdGhlIGluc3RydWN0aW9uIHNlbGVjdG9yLgorLy8vIFRoaXMgY2xhc3MgaXMgcmVzcG9uc2libGUgZm9yIHNlbGVjdGluZyBtYWNoaW5lIGluc3RydWN0aW9ucy4KKy8vLyBJdCdzIGltcGxlbWVudGVkIGJ5IHRoZSB0YXJnZXQuIEl0J3MgdXNlZCBieSB0aGUgSW5zdHJ1Y3Rpb25TZWxlY3QgcGFzcy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX0lOU1RSVUNUSU9OU0VMRUNUT1JfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fR0xPQkFMSVNFTF9JTlNUUlVDVElPTlNFTEVDVE9SX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvT3B0aW9uYWwuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9Db2RlR2VuQ292ZXJhZ2UuaCIKKyNpbmNsdWRlIDxiaXRzZXQ+CisjaW5jbHVkZSA8Y3N0ZGRlZj4KKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CisjaW5jbHVkZSA8aW5pdGlhbGl6ZXJfbGlzdD4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgQVBJbnQ7CitjbGFzcyBBUEZsb2F0OworY2xhc3MgTExUOworY2xhc3MgTWFjaGluZUluc3RyOworY2xhc3MgTWFjaGluZUluc3RyQnVpbGRlcjsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIE1hY2hpbmVPcGVyYW5kOworY2xhc3MgTWFjaGluZVJlZ2lzdGVySW5mbzsKK2NsYXNzIFJlZ2lzdGVyQmFua0luZm87CitjbGFzcyBUYXJnZXRJbnN0ckluZm87CitjbGFzcyBUYXJnZXRSZWdpc3RlckNsYXNzOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJJbmZvOworCisvLy8gQ29udGFpbmVyIGNsYXNzIGZvciBDb2RlR2VuIHByZWRpY2F0ZSByZXN1bHRzLgorLy8vIFRoaXMgaXMgY29udmVuaWVudCBiZWNhdXNlIHN0ZDo6Yml0c2V0IGRvZXMgbm90IGhhdmUgYSBjb25zdHJ1Y3RvcgorLy8vIHdpdGggYW4gaW5pdGlhbGl6ZXIgbGlzdCBvZiBzZXQgYml0cy4KKy8vLworLy8vIEVhY2ggSW5zdHJ1Y3Rpb25TZWxlY3RvciBzdWJjbGFzcyBzaG91bGQgZGVmaW5lIGEgUHJlZGljYXRlQml0c2V0IGNsYXNzCisvLy8gd2l0aDoKKy8vLyAgIGNvbnN0IHVuc2lnbmVkIE1BWF9TVUJUQVJHRVRfUFJFRElDQVRFUyA9IDE5MjsKKy8vLyAgIHVzaW5nIFByZWRpY2F0ZUJpdHNldCA9IFByZWRpY2F0ZUJpdHNldEltcGw8TUFYX1NVQlRBUkdFVF9QUkVESUNBVEVTPjsKKy8vLyBhbmQgdXBkYXRpbmcgdGhlIGNvbnN0YW50IHRvIHN1aXQgdGhlIHRhcmdldC4gVGFibGVnZW4gcHJvdmlkZXMgYSBzdWl0YWJsZQorLy8vIGRlZmluaXRpb24gZm9yIHRoZSBwcmVkaWNhdGVzIGluIHVzZSBpbiA8VGFyZ2V0Pkdlbkdsb2JhbElTZWwuaW5jIHdoZW4KKy8vLyBHRVRfR0xPQkFMSVNFTF9QUkVESUNBVEVfQklUU0VUIGlzIGRlZmluZWQuCit0ZW1wbGF0ZSA8c3RkOjpzaXplX3QgTWF4UHJlZGljYXRlcz4KK2NsYXNzIFByZWRpY2F0ZUJpdHNldEltcGwgOiBwdWJsaWMgc3RkOjpiaXRzZXQ8TWF4UHJlZGljYXRlcz4geworcHVibGljOgorICAvLyBDYW5ub3QgaW5oZXJpdCBjb25zdHJ1Y3RvcnMgYmVjYXVzZSBpdCdzIG5vdCBzdXBwb3J0ZWQgYnkgVkMrKy4uCisgIFByZWRpY2F0ZUJpdHNldEltcGwoKSA9IGRlZmF1bHQ7CisKKyAgUHJlZGljYXRlQml0c2V0SW1wbChjb25zdCBzdGQ6OmJpdHNldDxNYXhQcmVkaWNhdGVzPiAmQikKKyAgICAgIDogc3RkOjpiaXRzZXQ8TWF4UHJlZGljYXRlcz4oQikge30KKworICBQcmVkaWNhdGVCaXRzZXRJbXBsKHN0ZDo6aW5pdGlhbGl6ZXJfbGlzdDx1bnNpZ25lZD4gSW5pdCkgeworICAgIGZvciAoYXV0byBJIDogSW5pdCkKKyAgICAgIHN0ZDo6Yml0c2V0PE1heFByZWRpY2F0ZXM+OjpzZXQoSSk7CisgIH0KK307CisKK2VudW0geworICAvLy8gQmVnaW4gYSB0cnktYmxvY2sgdG8gYXR0ZW1wdCBhIG1hdGNoIGFuZCBqdW1wIHRvIE9uRmFpbCBpZiBpdCBpcworICAvLy8gdW5zdWNjZXNzZnVsLgorICAvLy8gLSBPbkZhaWwgLSBUaGUgTWF0Y2hUYWJsZSBlbnRyeSBhdCB3aGljaCB0byByZXN1bWUgaWYgdGhlIG1hdGNoIGZhaWxzLgorICAvLy8KKyAgLy8vIEZJWE1FOiBUaGlzIG91Z2h0IHRvIHRha2UgYW4gYXJndW1lbnQgaW5kaWNhdGluZyB0aGUgbnVtYmVyIG9mIHRyeS1ibG9ja3MKKyAgLy8vICAgICAgICB0byBleGl0IG9uIGZhaWx1cmUuIEl0J3MgdXN1YWxseSBvbmUgYnV0IHRoZSBsYXN0IG1hdGNoIGF0dGVtcHQgb2YKKyAgLy8vICAgICAgICBhIGJsb2NrIHdpbGwgbmVlZCBtb3JlLiBUaGUgKGltcGxlbWVudGVkKSBhbHRlcm5hdGl2ZSBpcyB0byB0YWNrIGEKKyAgLy8vICAgICAgICBHSU1fUmVqZWN0IG9uIHRoZSBlbmQgb2YgZWFjaCB0cnktYmxvY2sgd2hpY2ggaXMgc2ltcGxlciBidXQKKyAgLy8vICAgICAgICByZXF1aXJlcyBhbiBleHRyYSBvcGNvZGUgYW5kIGl0ZXJhdGlvbiBpbiB0aGUgaW50ZXJwcmV0ZXIgb24gZWFjaAorICAvLy8gICAgICAgIGZhaWxlZCBtYXRjaC4KKyAgR0lNX1RyeSwKKworICAvLy8gUmVjb3JkIHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24KKyAgLy8vIC0gTmV3SW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQgdG8gZGVmaW5lCisgIC8vLyAtIEluc25JRCAtIEluc3RydWN0aW9uIElECisgIC8vLyAtIE9wSWR4IC0gT3BlcmFuZCBpbmRleAorICBHSU1fUmVjb3JkSW5zbiwKKworICAvLy8gQ2hlY2sgdGhlIGZlYXR1cmUgYml0cworICAvLy8gLSBFeHBlY3RlZCBmZWF0dXJlcworICBHSU1fQ2hlY2tGZWF0dXJlcywKKworICAvLy8gQ2hlY2sgdGhlIG9wY29kZSBvbiB0aGUgc3BlY2lmaWVkIGluc3RydWN0aW9uCisgIC8vLyAtIEluc25JRCAtIEluc3RydWN0aW9uIElECisgIC8vLyAtIEV4cGVjdGVkIG9wY29kZQorICBHSU1fQ2hlY2tPcGNvZGUsCisgIC8vLyBDaGVjayB0aGUgaW5zdHJ1Y3Rpb24gaGFzIHRoZSByaWdodCBudW1iZXIgb2Ygb3BlcmFuZHMKKyAgLy8vIC0gSW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQKKyAgLy8vIC0gRXhwZWN0ZWQgbnVtYmVyIG9mIG9wZXJhbmRzCisgIEdJTV9DaGVja051bU9wZXJhbmRzLAorICAvLy8gQ2hlY2sgYW4gaW1tZWRpYXRlIHByZWRpY2F0ZSBvbiB0aGUgc3BlY2lmaWVkIGluc3RydWN0aW9uCisgIC8vLyAtIEluc25JRCAtIEluc3RydWN0aW9uIElECisgIC8vLyAtIFRoZSBwcmVkaWNhdGUgdG8gdGVzdAorICBHSU1fQ2hlY2tJNjRJbW1QcmVkaWNhdGUsCisgIC8vLyBDaGVjayBhbiBpbW1lZGlhdGUgcHJlZGljYXRlIG9uIHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24gdmlhIGFuIEFQSW50LgorICAvLy8gLSBJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRAorICAvLy8gLSBUaGUgcHJlZGljYXRlIHRvIHRlc3QKKyAgR0lNX0NoZWNrQVBJbnRJbW1QcmVkaWNhdGUsCisgIC8vLyBDaGVjayBhIGZsb2F0aW5nIHBvaW50IGltbWVkaWF0ZSBwcmVkaWNhdGUgb24gdGhlIHNwZWNpZmllZCBpbnN0cnVjdGlvbi4KKyAgLy8vIC0gSW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQKKyAgLy8vIC0gVGhlIHByZWRpY2F0ZSB0byB0ZXN0CisgIEdJTV9DaGVja0FQRmxvYXRJbW1QcmVkaWNhdGUsCisgIC8vLyBDaGVjayBhIG1lbW9yeSBvcGVyYXRpb24gaGFzIHRoZSBzcGVjaWZpZWQgYXRvbWljIG9yZGVyaW5nLgorICAvLy8gLSBJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRAorICAvLy8gLSBPcmRlcmluZyAtIFRoZSBBdG9taWNPcmRlcmluZyB2YWx1ZQorICBHSU1fQ2hlY2tBdG9taWNPcmRlcmluZywKKyAgR0lNX0NoZWNrQXRvbWljT3JkZXJpbmdPclN0cm9uZ2VyVGhhbiwKKyAgR0lNX0NoZWNrQXRvbWljT3JkZXJpbmdXZWFrZXJUaGFuLAorCisgIC8vLyBDaGVjayB0aGUgdHlwZSBmb3IgdGhlIHNwZWNpZmllZCBvcGVyYW5kCisgIC8vLyAtIEluc25JRCAtIEluc3RydWN0aW9uIElECisgIC8vLyAtIE9wSWR4IC0gT3BlcmFuZCBpbmRleAorICAvLy8gLSBFeHBlY3RlZCB0eXBlCisgIEdJTV9DaGVja1R5cGUsCisgIC8vLyBDaGVjayB0aGUgdHlwZSBvZiBhIHBvaW50ZXIgdG8gYW55IGFkZHJlc3Mgc3BhY2UuCisgIC8vLyAtIEluc25JRCAtIEluc3RydWN0aW9uIElECisgIC8vLyAtIE9wSWR4IC0gT3BlcmFuZCBpbmRleAorICAvLy8gLSBTaXplSW5CaXRzIC0gVGhlIHNpemUgb2YgdGhlIHBvaW50ZXIgdmFsdWUgaW4gYml0cy4KKyAgR0lNX0NoZWNrUG9pbnRlclRvQW55LAorICAvLy8gQ2hlY2sgdGhlIHJlZ2lzdGVyIGJhbmsgZm9yIHRoZSBzcGVjaWZpZWQgb3BlcmFuZAorICAvLy8gLSBJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRAorICAvLy8gLSBPcElkeCAtIE9wZXJhbmQgaW5kZXgKKyAgLy8vIC0gRXhwZWN0ZWQgcmVnaXN0ZXIgYmFuayAoc3BlY2lmaWVkIGFzIGEgcmVnaXN0ZXIgY2xhc3MpCisgIEdJTV9DaGVja1JlZ0JhbmtGb3JDbGFzcywKKyAgLy8vIENoZWNrIHRoZSBvcGVyYW5kIG1hdGNoZXMgYSBjb21wbGV4IHByZWRpY2F0ZQorICAvLy8gLSBJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRAorICAvLy8gLSBPcElkeCAtIE9wZXJhbmQgaW5kZXgKKyAgLy8vIC0gUmVuZGVyZXJJRCAtIFRoZSByZW5kZXJlciB0byBob2xkIHRoZSByZXN1bHQKKyAgLy8vIC0gQ29tcGxleCBwcmVkaWNhdGUgSUQKKyAgR0lNX0NoZWNrQ29tcGxleFBhdHRlcm4sCisgIC8vLyBDaGVjayB0aGUgb3BlcmFuZCBpcyBhIHNwZWNpZmljIGludGVnZXIKKyAgLy8vIC0gSW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQKKyAgLy8vIC0gT3BJZHggLSBPcGVyYW5kIGluZGV4CisgIC8vLyAtIEV4cGVjdGVkIGludGVnZXIKKyAgR0lNX0NoZWNrQ29uc3RhbnRJbnQsCisgIC8vLyBDaGVjayB0aGUgb3BlcmFuZCBpcyBhIHNwZWNpZmljIGxpdGVyYWwgaW50ZWdlciAoaS5lLiBNTy5pc0ltbSgpIG9yCisgIC8vLyBNTy5pc0NJbW0oKSBpcyB0cnVlKS4KKyAgLy8vIC0gSW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQKKyAgLy8vIC0gT3BJZHggLSBPcGVyYW5kIGluZGV4CisgIC8vLyAtIEV4cGVjdGVkIGludGVnZXIKKyAgR0lNX0NoZWNrTGl0ZXJhbEludCwKKyAgLy8vIENoZWNrIHRoZSBvcGVyYW5kIGlzIGEgc3BlY2lmaWMgaW50cmluc2ljIElECisgIC8vLyAtIEluc25JRCAtIEluc3RydWN0aW9uIElECisgIC8vLyAtIE9wSWR4IC0gT3BlcmFuZCBpbmRleAorICAvLy8gLSBFeHBlY3RlZCBJbnRyaW5zaWMgSUQKKyAgR0lNX0NoZWNrSW50cmluc2ljSUQsCisgIC8vLyBDaGVjayB0aGUgc3BlY2lmaWVkIG9wZXJhbmQgaXMgYW4gTUJCCisgIC8vLyAtIEluc25JRCAtIEluc3RydWN0aW9uIElECisgIC8vLyAtIE9wSWR4IC0gT3BlcmFuZCBpbmRleAorICBHSU1fQ2hlY2tJc01CQiwKKworICAvLy8gQ2hlY2sgaWYgdGhlIHNwZWNpZmllZCBvcGVyYW5kIGlzIHNhZmUgdG8gZm9sZCBpbnRvIHRoZSBjdXJyZW50CisgIC8vLyBpbnN0cnVjdGlvbi4KKyAgLy8vIC0gSW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQKKyAgR0lNX0NoZWNrSXNTYWZlVG9Gb2xkLAorCisgIC8vLyBDaGVjayB0aGUgc3BlY2lmaWVkIG9wZXJhbmRzIGFyZSBpZGVudGljYWwuCisgIC8vLyAtIEluc25JRCAtIEluc3RydWN0aW9uIElECisgIC8vLyAtIE9wSWR4IC0gT3BlcmFuZCBpbmRleAorICAvLy8gLSBPdGhlckluc25JRCAtIE90aGVyIGluc3RydWN0aW9uIElECisgIC8vLyAtIE90aGVyT3BJZHggLSBPdGhlciBvcGVyYW5kIGluZGV4CisgIEdJTV9DaGVja0lzU2FtZU9wZXJhbmQsCisKKyAgLy8vIEZhaWwgdGhlIGN1cnJlbnQgdHJ5LWJsb2NrLCBvciBjb21wbGV0ZWx5IGZhaWwgdG8gbWF0Y2ggaWYgdGhlcmUgaXMgbm8KKyAgLy8vIGN1cnJlbnQgdHJ5LWJsb2NrLgorICBHSU1fUmVqZWN0LAorCisgIC8vPT09IFJlbmRlcmVycyA9PT0KKworICAvLy8gTXV0YXRlIGFuIGluc3RydWN0aW9uCisgIC8vLyAtIE5ld0luc25JRCAtIEluc3RydWN0aW9uIElEIHRvIGRlZmluZQorICAvLy8gLSBPbGRJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRCB0byBtdXRhdGUKKyAgLy8vIC0gTmV3T3Bjb2RlIC0gVGhlIG5ldyBvcGNvZGUgdG8gdXNlCisgIEdJUl9NdXRhdGVPcGNvZGUsCisgIC8vLyBCdWlsZCBhIG5ldyBpbnN0cnVjdGlvbgorICAvLy8gLSBJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRCB0byBkZWZpbmUKKyAgLy8vIC0gT3Bjb2RlIC0gVGhlIG5ldyBvcGNvZGUgdG8gdXNlCisgIEdJUl9CdWlsZE1JLAorCisgIC8vLyBDb3B5IGFuIG9wZXJhbmQgdG8gdGhlIHNwZWNpZmllZCBpbnN0cnVjdGlvbgorICAvLy8gLSBOZXdJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRCB0byBtb2RpZnkKKyAgLy8vIC0gT2xkSW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQgdG8gY29weSBmcm9tCisgIC8vLyAtIE9wSWR4IC0gVGhlIG9wZXJhbmQgdG8gY29weQorICBHSVJfQ29weSwKKyAgLy8vIENvcHkgYW4gb3BlcmFuZCB0byB0aGUgc3BlY2lmaWVkIGluc3RydWN0aW9uIG9yIGFkZCBhIHplcm8gcmVnaXN0ZXIgaWYgdGhlCisgIC8vLyBvcGVyYW5kIGlzIGEgemVybyBpbW1lZGlhdGUuCisgIC8vLyAtIE5ld0luc25JRCAtIEluc3RydWN0aW9uIElEIHRvIG1vZGlmeQorICAvLy8gLSBPbGRJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRCB0byBjb3B5IGZyb20KKyAgLy8vIC0gT3BJZHggLSBUaGUgb3BlcmFuZCB0byBjb3B5CisgIC8vLyAtIFplcm9SZWcgLSBUaGUgemVybyByZWdpc3RlciB0byB1c2UKKyAgR0lSX0NvcHlPckFkZFplcm9SZWcsCisgIC8vLyBDb3B5IGFuIG9wZXJhbmQgdG8gdGhlIHNwZWNpZmllZCBpbnN0cnVjdGlvbgorICAvLy8gLSBOZXdJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRCB0byBtb2RpZnkKKyAgLy8vIC0gT2xkSW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQgdG8gY29weSBmcm9tCisgIC8vLyAtIE9wSWR4IC0gVGhlIG9wZXJhbmQgdG8gY29weQorICAvLy8gLSBTdWJSZWdJZHggLSBUaGUgc3VicmVnaXN0ZXIgdG8gY29weQorICBHSVJfQ29weVN1YlJlZywKKyAgLy8vIEFkZCBhbiBpbXBsaWNpdCByZWdpc3RlciBkZWYgdG8gdGhlIHNwZWNpZmllZCBpbnN0cnVjdGlvbgorICAvLy8gLSBJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRCB0byBtb2RpZnkKKyAgLy8vIC0gUmVnTnVtIC0gVGhlIHJlZ2lzdGVyIHRvIGFkZAorICBHSVJfQWRkSW1wbGljaXREZWYsCisgIC8vLyBBZGQgYW4gaW1wbGljaXQgcmVnaXN0ZXIgdXNlIHRvIHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24KKyAgLy8vIC0gSW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQgdG8gbW9kaWZ5CisgIC8vLyAtIFJlZ051bSAtIFRoZSByZWdpc3RlciB0byBhZGQKKyAgR0lSX0FkZEltcGxpY2l0VXNlLAorICAvLy8gQWRkIGFuIHJlZ2lzdGVyIHRvIHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24KKyAgLy8vIC0gSW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQgdG8gbW9kaWZ5CisgIC8vLyAtIFJlZ051bSAtIFRoZSByZWdpc3RlciB0byBhZGQKKyAgR0lSX0FkZFJlZ2lzdGVyLAorICAvLy8gQWRkIGEgdGVtcG9yYXJ5IHJlZ2lzdGVyIHRvIHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24KKyAgLy8vIC0gSW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQgdG8gbW9kaWZ5CisgIC8vLyAtIFRlbXBSZWdJRCAtIFRoZSB0ZW1wb3JhcnkgcmVnaXN0ZXIgSUQgdG8gYWRkCisgIEdJUl9BZGRUZW1wUmVnaXN0ZXIsCisgIC8vLyBBZGQgYW4gaW1tZWRpYXRlIHRvIHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24KKyAgLy8vIC0gSW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQgdG8gbW9kaWZ5CisgIC8vLyAtIEltbSAtIFRoZSBpbW1lZGlhdGUgdG8gYWRkCisgIEdJUl9BZGRJbW0sCisgIC8vLyBSZW5kZXIgY29tcGxleCBvcGVyYW5kcyB0byB0aGUgc3BlY2lmaWVkIGluc3RydWN0aW9uCisgIC8vLyAtIEluc25JRCAtIEluc3RydWN0aW9uIElEIHRvIG1vZGlmeQorICAvLy8gLSBSZW5kZXJlcklEIC0gVGhlIHJlbmRlcmVyIHRvIGNhbGwKKyAgR0lSX0NvbXBsZXhSZW5kZXJlciwKKyAgLy8vIFJlbmRlciBzdWItb3BlcmFuZHMgb2YgY29tcGxleCBvcGVyYW5kcyB0byB0aGUgc3BlY2lmaWVkIGluc3RydWN0aW9uCisgIC8vLyAtIEluc25JRCAtIEluc3RydWN0aW9uIElEIHRvIG1vZGlmeQorICAvLy8gLSBSZW5kZXJlcklEIC0gVGhlIHJlbmRlcmVyIHRvIGNhbGwKKyAgLy8vIC0gUmVuZGVyT3BJRCAtIFRoZSBzdWJvcGVyYW5kIHRvIHJlbmRlci4KKyAgR0lSX0NvbXBsZXhTdWJPcGVyYW5kUmVuZGVyZXIsCisgIC8vLyBSZW5kZXIgb3BlcmFuZHMgdG8gdGhlIHNwZWNpZmllZCBpbnN0cnVjdGlvbiB1c2luZyBhIGN1c3RvbSBmdW5jdGlvbgorICAvLy8gLSBJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRCB0byBtb2RpZnkKKyAgLy8vIC0gT2xkSW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQgdG8gZ2V0IHRoZSBtYXRjaGVkIG9wZXJhbmQgZnJvbQorICAvLy8gLSBSZW5kZXJlckZuSUQgLSBDdXN0b20gcmVuZGVyZXIgZnVuY3Rpb24gdG8gY2FsbAorICBHSVJfQ3VzdG9tUmVuZGVyZXIsCisKKyAgLy8vIFJlbmRlciBhIEdfQ09OU1RBTlQgb3BlcmF0b3IgYXMgYSBzaWduLWV4dGVuZGVkIGltbWVkaWF0ZS4KKyAgLy8vIC0gTmV3SW5zbklEIC0gSW5zdHJ1Y3Rpb24gSUQgdG8gbW9kaWZ5CisgIC8vLyAtIE9sZEluc25JRCAtIEluc3RydWN0aW9uIElEIHRvIGNvcHkgZnJvbQorICAvLy8gVGhlIG9wZXJhbmQgaW5kZXggaXMgaW1wbGljaXRseSAxLgorICBHSVJfQ29weUNvbnN0YW50QXNTSW1tLAorCisgIC8vLyBDb25zdHJhaW4gYW4gaW5zdHJ1Y3Rpb24gb3BlcmFuZCB0byBhIHJlZ2lzdGVyIGNsYXNzLgorICAvLy8gLSBJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRCB0byBtb2RpZnkKKyAgLy8vIC0gT3BJZHggLSBPcGVyYW5kIGluZGV4CisgIC8vLyAtIFJDRW51bSAtIFJlZ2lzdGVyIGNsYXNzIGVudW1lcmF0aW9uIHZhbHVlCisgIEdJUl9Db25zdHJhaW5PcGVyYW5kUkMsCisgIC8vLyBDb25zdHJhaW4gYW4gaW5zdHJ1Y3Rpb25zIG9wZXJhbmRzIGFjY29yZGluZyB0byB0aGUgaW5zdHJ1Y3Rpb24KKyAgLy8vIGRlc2NyaXB0aW9uLgorICAvLy8gLSBJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRCB0byBtb2RpZnkKKyAgR0lSX0NvbnN0cmFpblNlbGVjdGVkSW5zdE9wZXJhbmRzLAorICAvLy8gTWVyZ2UgYWxsIG1lbW9yeSBvcGVyYW5kcyBpbnRvIGluc3RydWN0aW9uLgorICAvLy8gLSBJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRCB0byBtb2RpZnkKKyAgLy8vIC0gTWVyZ2VJbnNuSUQuLi4gLSBPbmUgb3IgbW9yZSBJbnN0cnVjdGlvbiBJRCB0byBtZXJnZSBpbnRvIHRoZSByZXN1bHQuCisgIC8vLyAtIEdJVV9NZXJnZU1lbU9wZXJhbmRzX0VuZE9mTGlzdCAtIFRlcm1pbmF0ZXMgdGhlIGxpc3Qgb2YgaW5zdHJ1Y3Rpb25zIHRvCisgIC8vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlLgorICBHSVJfTWVyZ2VNZW1PcGVyYW5kcywKKyAgLy8vIEVyYXNlIGZyb20gcGFyZW50LgorICAvLy8gLSBJbnNuSUQgLSBJbnN0cnVjdGlvbiBJRCB0byBlcmFzZQorICBHSVJfRXJhc2VGcm9tUGFyZW50LAorICAvLy8gQ3JlYXRlIGEgbmV3IHRlbXBvcmFyeSByZWdpc3RlciB0aGF0J3Mgbm90IGNvbnN0cmFpbmVkLgorICAvLy8gLSBUZW1wUmVnSUQgLSBUaGUgdGVtcG9yYXJ5IHJlZ2lzdGVyIElEIHRvIGluaXRpYWxpemUuCisgIC8vLyAtIEV4cGVjdGVkIHR5cGUKKyAgR0lSX01ha2VUZW1wUmVnLAorCisgIC8vLyBBIHN1Y2Nlc3NmdWwgZW1pc3Npb24KKyAgR0lSX0RvbmUsCisKKyAgLy8vIEluY3JlbWVudCB0aGUgcnVsZSBjb3ZlcmFnZSBjb3VudGVyLgorICAvLy8gLSBSdWxlSUQgLSBUaGUgSUQgb2YgdGhlIHJ1bGUgdGhhdCB3YXMgY292ZXJlZC4KKyAgR0lSX0NvdmVyYWdlLAorfTsKKworZW51bSB7CisgIC8vLyBJbmRpY2F0ZXMgdGhlIGVuZCBvZiB0aGUgdmFyaWFibGUtbGVuZ3RoIE1lcmdlSW5zbklEIGxpc3QgaW4gYQorICAvLy8gR0lSX01lcmdlTWVtT3BlcmFuZHMgb3Bjb2RlLgorICBHSVVfTWVyZ2VNZW1PcGVyYW5kc19FbmRPZkxpc3QgPSAtMSwKK307CisKKy8vLyBQcm92aWRlcyB0aGUgbG9naWMgdG8gc2VsZWN0IGdlbmVyaWMgbWFjaGluZSBpbnN0cnVjdGlvbnMuCitjbGFzcyBJbnN0cnVjdGlvblNlbGVjdG9yIHsKK3B1YmxpYzoKKyAgdmlydHVhbCB+SW5zdHJ1Y3Rpb25TZWxlY3RvcigpID0gZGVmYXVsdDsKKworICAvLy8gU2VsZWN0IHRoZSAocG9zc2libHkgZ2VuZXJpYykgaW5zdHJ1Y3Rpb24gXHAgSSB0byBvbmx5IHVzZSB0YXJnZXQtc3BlY2lmaWMKKyAgLy8vIG9wY29kZXMuIEl0IGlzIE9LIHRvIGluc2VydCBtdWx0aXBsZSBpbnN0cnVjdGlvbnMsIGJ1dCB0aGV5IGNhbm5vdCBiZQorICAvLy8gZ2VuZXJpYyBwcmUtaXNlbCBpbnN0cnVjdGlvbnMuCisgIC8vLworICAvLy8gXHJldHVybnMgd2hldGhlciBzZWxlY3Rpb24gc3VjY2VlZGVkLgorICAvLy8gXHByZSAgSS5nZXRQYXJlbnQoKSAmJiBJLmdldFBhcmVudCgpLT5nZXRQYXJlbnQoKQorICAvLy8gXHBvc3QKKyAgLy8vICAgaWYgcmV0dXJucyB0cnVlOgorICAvLy8gICAgIGZvciBJIGluIGFsbCBtdXRhdGVkL2luc2VydGVkIGluc3RydWN0aW9uczoKKyAgLy8vICAgICAgICFpc1ByZUlTZWxHZW5lcmljT3Bjb2RlKEkuZ2V0T3Bjb2RlKCkpCisgIHZpcnR1YWwgYm9vbCBzZWxlY3QoTWFjaGluZUluc3RyICZJLCBDb2RlR2VuQ292ZXJhZ2UgJkNvdmVyYWdlSW5mbykgY29uc3QgPSAwOworCitwcm90ZWN0ZWQ6CisgIHVzaW5nIENvbXBsZXhSZW5kZXJlckZucyA9CisgICAgICBPcHRpb25hbDxTbWFsbFZlY3RvcjxzdGQ6OmZ1bmN0aW9uPHZvaWQoTWFjaGluZUluc3RyQnVpbGRlciAmKT4sIDQ+PjsKKyAgdXNpbmcgUmVjb3JkZWRNSVZlY3RvciA9IFNtYWxsVmVjdG9yPE1hY2hpbmVJbnN0ciAqLCA0PjsKKyAgdXNpbmcgTmV3TUlWZWN0b3IgPSBTbWFsbFZlY3RvcjxNYWNoaW5lSW5zdHJCdWlsZGVyLCA0PjsKKworICBzdHJ1Y3QgTWF0Y2hlclN0YXRlIHsKKyAgICBzdGQ6OnZlY3RvcjxDb21wbGV4UmVuZGVyZXJGbnM6OnZhbHVlX3R5cGU+IFJlbmRlcmVyczsKKyAgICBSZWNvcmRlZE1JVmVjdG9yIE1JczsKKyAgICBEZW5zZU1hcDx1bnNpZ25lZCwgdW5zaWduZWQ+IFRlbXBSZWdpc3RlcnM7CisKKyAgICBNYXRjaGVyU3RhdGUodW5zaWduZWQgTWF4UmVuZGVyZXJzKTsKKyAgfTsKKworcHVibGljOgorICB0ZW1wbGF0ZSA8Y2xhc3MgUHJlZGljYXRlQml0c2V0LCBjbGFzcyBDb21wbGV4TWF0Y2hlck1lbUZuLAorICAgICAgICAgICAgY2xhc3MgQ3VzdG9tUmVuZGVyZXJGbj4KKyAgc3RydWN0IElTZWxJbmZvVHkgeworICAgIGNvbnN0IExMVCAqVHlwZU9iamVjdHM7CisgICAgY29uc3QgUHJlZGljYXRlQml0c2V0ICpGZWF0dXJlQml0c2V0czsKKyAgICBjb25zdCBDb21wbGV4TWF0Y2hlck1lbUZuICpDb21wbGV4UHJlZGljYXRlczsKKyAgICBjb25zdCBDdXN0b21SZW5kZXJlckZuICpDdXN0b21SZW5kZXJlcnM7CisgIH07CisKK3Byb3RlY3RlZDoKKyAgSW5zdHJ1Y3Rpb25TZWxlY3RvcigpOworCisgIC8vLyBFeGVjdXRlIGEgZ2l2ZW4gbWF0Y2hlciB0YWJsZSBhbmQgcmV0dXJuIHRydWUgaWYgdGhlIG1hdGNoIHdhcyBzdWNjZXNzZnVsCisgIC8vLyBhbmQgZmFsc2Ugb3RoZXJ3aXNlLgorICB0ZW1wbGF0ZSA8Y2xhc3MgVGd0SW5zdHJ1Y3Rpb25TZWxlY3RvciwgY2xhc3MgUHJlZGljYXRlQml0c2V0LAorICAgICAgICAgICAgY2xhc3MgQ29tcGxleE1hdGNoZXJNZW1GbiwgY2xhc3MgQ3VzdG9tUmVuZGVyZXJGbj4KKyAgYm9vbCBleGVjdXRlTWF0Y2hUYWJsZSgKKyAgICAgIFRndEluc3RydWN0aW9uU2VsZWN0b3IgJklTZWwsIE5ld01JVmVjdG9yICZPdXRNSXMsIE1hdGNoZXJTdGF0ZSAmU3RhdGUsCisgICAgICBjb25zdCBJU2VsSW5mb1R5PFByZWRpY2F0ZUJpdHNldCwgQ29tcGxleE1hdGNoZXJNZW1GbiwgQ3VzdG9tUmVuZGVyZXJGbj4KKyAgICAgICAgICAmSVNlbEluZm8sCisgICAgICBjb25zdCBpbnQ2NF90ICpNYXRjaFRhYmxlLCBjb25zdCBUYXJnZXRJbnN0ckluZm8gJlRJSSwKKyAgICAgIE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSwgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICZUUkksCisgICAgICBjb25zdCBSZWdpc3RlckJhbmtJbmZvICZSQkksIGNvbnN0IFByZWRpY2F0ZUJpdHNldCAmQXZhaWxhYmxlRmVhdHVyZXMsCisgICAgICBDb2RlR2VuQ292ZXJhZ2UgJkNvdmVyYWdlSW5mbykgY29uc3Q7CisKKyAgdmlydHVhbCBib29sIHRlc3RJbW1QcmVkaWNhdGVfSTY0KHVuc2lnbmVkLCBpbnQ2NF90KSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgiU3ViY2xhc3NlcyBtdXN0IG92ZXJyaWRlIHRoaXMgdG8gdXNlIHRhYmxlZ2VuIik7CisgIH0KKyAgdmlydHVhbCBib29sIHRlc3RJbW1QcmVkaWNhdGVfQVBJbnQodW5zaWduZWQsIGNvbnN0IEFQSW50ICYpIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJTdWJjbGFzc2VzIG11c3Qgb3ZlcnJpZGUgdGhpcyB0byB1c2UgdGFibGVnZW4iKTsKKyAgfQorICB2aXJ0dWFsIGJvb2wgdGVzdEltbVByZWRpY2F0ZV9BUEZsb2F0KHVuc2lnbmVkLCBjb25zdCBBUEZsb2F0ICYpIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJTdWJjbGFzc2VzIG11c3Qgb3ZlcnJpZGUgdGhpcyB0byB1c2UgdGFibGVnZW4iKTsKKyAgfQorCisgIC8vLyBDb25zdHJhaW4gYSByZWdpc3RlciBvcGVyYW5kIG9mIGFuIGluc3RydWN0aW9uIFxwIEkgdG8gYSBzcGVjaWZpZWQKKyAgLy8vIHJlZ2lzdGVyIGNsYXNzLiBUaGlzIGNvdWxkIGludm9sdmUgaW5zZXJ0aW5nIENPUFlzIGJlZm9yZSAoZm9yIHVzZXMpIG9yCisgIC8vLyBhZnRlciAoZm9yIGRlZnMpIGFuZCBtYXkgcmVwbGFjZSB0aGUgb3BlcmFuZCBvZiBccCBJLgorICAvLy8gXHJldHVybnMgd2hldGhlciBvcGVyYW5kIHJlZ2NsYXNzIGNvbnN0cmFpbmluZyBzdWNjZWVkZWQuCisgIGJvb2wgY29uc3RyYWluT3BlcmFuZFJlZ1RvUmVnQ2xhc3MoTWFjaGluZUluc3RyICZJLCB1bnNpZ25lZCBPcElkeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICZSQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRJbnN0ckluZm8gJlRJSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gJlRSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZWdpc3RlckJhbmtJbmZvICZSQkkpIGNvbnN0OworCisgIGJvb2wgaXNPcGVyYW5kSW1tRXF1YWwoY29uc3QgTWFjaGluZU9wZXJhbmQgJk1PLCBpbnQ2NF90IFZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgb3BlcmFuZCBpcyBhIEdfR0VQIHdpdGggYSBHX0NPTlNUQU5UIG9uIHRoZQorICAvLy8gcmlnaHQtaGFuZCBzaWRlLiBHbG9iYWxJU2VsJ3Mgc2VwYXJhdGlvbiBvZiBwb2ludGVyIGFuZCBpbnRlZ2VyIHR5cGVzCisgIC8vLyBtZWFucyB0aGF0IHdlIGRvbid0IG5lZWQgdG8gd29ycnkgYWJvdXQgR19PUiB3aXRoIGVxdWl2YWxlbnQgc2VtYW50aWNzLgorICBib29sIGlzQmFzZVdpdGhDb25zdGFudE9mZnNldChjb25zdCBNYWNoaW5lT3BlcmFuZCAmUm9vdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgTUkgY2FuIG9idmlvdXNseSBiZSBmb2xkZWQgaW50byBJbnRvTUkuCisgIC8vLyBNSSBhbmQgSW50b01JIGRvIG5vdCBuZWVkIHRvIGJlIGluIHRoZSBzYW1lIGJhc2ljIGJsb2NrcywgYnV0IE1JIG11c3QKKyAgLy8vIHByZWNlZWQgSW50b01JLgorICBib29sIGlzT2J2aW91c2x5U2FmZVRvRm9sZChNYWNoaW5lSW5zdHIgJk1JLCBNYWNoaW5lSW5zdHIgJkludG9NSSkgY29uc3Q7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfSU5TVFJVQ1RJT05TRUxFQ1RPUl9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9JbnN0cnVjdGlvblNlbGVjdG9ySW1wbC5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvSW5zdHJ1Y3Rpb25TZWxlY3RvckltcGwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzU5M2JhCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvSW5zdHJ1Y3Rpb25TZWxlY3RvckltcGwuaApAQCAtMCwwICsxLDc2OSBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0luc3RydWN0aW9uU2VsZWN0b3JJbXBsLmggLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLy8gXGZpbGUgVGhpcyBmaWxlIGRlY2xhcmVzIHRoZSBBUEkgZm9yIHRoZSBpbnN0cnVjdGlvbiBzZWxlY3Rvci4KKy8vLyBUaGlzIGNsYXNzIGlzIHJlc3BvbnNpYmxlIGZvciBzZWxlY3RpbmcgbWFjaGluZSBpbnN0cnVjdGlvbnMuCisvLy8gSXQncyBpbXBsZW1lbnRlZCBieSB0aGUgdGFyZ2V0LiBJdCdzIHVzZWQgYnkgdGhlIEluc3RydWN0aW9uU2VsZWN0IHBhc3MuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fR0xPQkFMSVNFTF9JTlNUUlVDVElPTlNFTEVDVE9SSU1QTF9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX0lOU1RSVUNUSU9OU0VMRUNUT1JJTVBMX0gKKworI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvSW5zdHJ1Y3Rpb25TZWxlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL1JlZ2lzdGVyQmFua0luZm8uaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9VdGlscy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lSW5zdHJCdWlsZGVyLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVPcGVyYW5kLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVSZWdpc3RlckluZm8uaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0SW5zdHJJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1RhcmdldE9wY29kZXMuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0UmVnaXN0ZXJJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9JUi9Db25zdGFudHMuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvRGVidWcuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvRXJyb3JIYW5kbGluZy5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9yYXdfb3N0cmVhbS5oIgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8Y3N0ZGRlZj4KKyNpbmNsdWRlIDxjc3RkaW50PgorCituYW1lc3BhY2UgbGx2bSB7CisKKy8vLyBHbG9iYWxJU2VsIFBhdEZyYWcgUHJlZGljYXRlcworZW51bSB7CisgIEdJUEZQX0k2NF9JbnZhbGlkID0gMCwKKyAgR0lQRlBfQVBJbnRfSW52YWxpZCA9IDAsCisgIEdJUEZQX0FQRmxvYXRfSW52YWxpZCA9IDAsCit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgVGd0SW5zdHJ1Y3Rpb25TZWxlY3RvciwgY2xhc3MgUHJlZGljYXRlQml0c2V0LAorICAgICAgICAgIGNsYXNzIENvbXBsZXhNYXRjaGVyTWVtRm4sIGNsYXNzIEN1c3RvbVJlbmRlcmVyRm4+Citib29sIEluc3RydWN0aW9uU2VsZWN0b3I6OmV4ZWN1dGVNYXRjaFRhYmxlKAorICAgIFRndEluc3RydWN0aW9uU2VsZWN0b3IgJklTZWwsIE5ld01JVmVjdG9yICZPdXRNSXMsIE1hdGNoZXJTdGF0ZSAmU3RhdGUsCisgICAgY29uc3QgSVNlbEluZm9UeTxQcmVkaWNhdGVCaXRzZXQsIENvbXBsZXhNYXRjaGVyTWVtRm4sIEN1c3RvbVJlbmRlcmVyRm4+CisgICAgICAgICZJU2VsSW5mbywKKyAgICBjb25zdCBpbnQ2NF90ICpNYXRjaFRhYmxlLCBjb25zdCBUYXJnZXRJbnN0ckluZm8gJlRJSSwKKyAgICBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkksIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAmVFJJLAorICAgIGNvbnN0IFJlZ2lzdGVyQmFua0luZm8gJlJCSSwgY29uc3QgUHJlZGljYXRlQml0c2V0ICZBdmFpbGFibGVGZWF0dXJlcywKKyAgICBDb2RlR2VuQ292ZXJhZ2UgJkNvdmVyYWdlSW5mbykgY29uc3QgeworICB1aW50NjRfdCBDdXJyZW50SWR4ID0gMDsKKyAgU21hbGxWZWN0b3I8dWludDY0X3QsIDg+IE9uRmFpbFJlc3VtZUF0OworCisgIGVudW0gUmVqZWN0QWN0aW9uIHsgUmVqZWN0QW5kR2l2ZVVwLCBSZWplY3RBbmRSZXN1bWUgfTsKKyAgYXV0byBoYW5kbGVSZWplY3QgPSBbJl0oKSAtPiBSZWplY3RBY3Rpb24geworICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IFJlamVjdGVkXG4iKTsKKyAgICBpZiAoT25GYWlsUmVzdW1lQXQuZW1wdHkoKSkKKyAgICAgIHJldHVybiBSZWplY3RBbmRHaXZlVXA7CisgICAgQ3VycmVudElkeCA9IE9uRmFpbFJlc3VtZUF0LmJhY2soKTsKKyAgICBPbkZhaWxSZXN1bWVBdC5wb3BfYmFjaygpOworICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IFJlc3VtZSBhdCAiIDw8IEN1cnJlbnRJZHggPDwgIiAoIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgT25GYWlsUmVzdW1lQXQuc2l6ZSgpIDw8ICIgdHJ5LWJsb2NrcyByZW1haW4pXG4iKTsKKyAgICByZXR1cm4gUmVqZWN0QW5kUmVzdW1lOworICB9OworCisgIHdoaWxlICh0cnVlKSB7CisgICAgYXNzZXJ0KEN1cnJlbnRJZHggIT0gfjB1ICYmICJJbnZhbGlkIE1hdGNoVGFibGUgaW5kZXgiKTsKKyAgICBzd2l0Y2ggKE1hdGNoVGFibGVbQ3VycmVudElkeCsrXSkgeworICAgIGNhc2UgR0lNX1RyeTogeworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBCZWdpbiB0cnktYmxvY2tcbiIpOworICAgICAgT25GYWlsUmVzdW1lQXQucHVzaF9iYWNrKE1hdGNoVGFibGVbQ3VycmVudElkeCsrXSk7CisgICAgICBicmVhazsKKyAgICB9CisKKyAgICBjYXNlIEdJTV9SZWNvcmRJbnNuOiB7CisgICAgICBpbnQ2NF90IE5ld0luc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBPcElkeCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKworICAgICAgLy8gQXMgYW4gb3B0aW1pc2F0aW9uIHdlIHJlcXVpcmUgdGhhdCBNSXNbMF0gaXMgYWx3YXlzIHRoZSByb290LiBSZWZ1c2UKKyAgICAgIC8vIGFueSBhdHRlbXB0IHRvIG1vZGlmeSBpdC4KKyAgICAgIGFzc2VydChOZXdJbnNuSUQgIT0gMCAmJiAiUmVmdXNpbmcgdG8gbW9kaWZ5IE1Jc1swXSIpOworCisgICAgICBNYWNoaW5lT3BlcmFuZCAmTU8gPSBTdGF0ZS5NSXNbSW5zbklEXS0+Z2V0T3BlcmFuZChPcElkeCk7CisgICAgICBpZiAoIU1PLmlzUmVnKCkpIHsKKyAgICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IE5vdCBhIHJlZ2lzdGVyXG4iKTsKKyAgICAgICAgaWYgKGhhbmRsZVJlamVjdCgpID09IFJlamVjdEFuZEdpdmVVcCkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaWYgKFRSSS5pc1BoeXNpY2FsUmVnaXN0ZXIoTU8uZ2V0UmVnKCkpKSB7CisgICAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBJcyBhIHBoeXNpY2FsIHJlZ2lzdGVyXG4iKTsKKyAgICAgICAgaWYgKGhhbmRsZVJlamVjdCgpID09IFJlamVjdEFuZEdpdmVVcCkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICAgIGJyZWFrOworICAgICAgfQorCisgICAgICBNYWNoaW5lSW5zdHIgKk5ld01JID0gTVJJLmdldFZSZWdEZWYoTU8uZ2V0UmVnKCkpOworICAgICAgaWYgKChzaXplX3QpTmV3SW5zbklEIDwgU3RhdGUuTUlzLnNpemUoKSkKKyAgICAgICAgU3RhdGUuTUlzW05ld0luc25JRF0gPSBOZXdNSTsKKyAgICAgIGVsc2UgeworICAgICAgICBhc3NlcnQoKHNpemVfdClOZXdJbnNuSUQgPT0gU3RhdGUuTUlzLnNpemUoKSAmJgorICAgICAgICAgICAgICAgIkV4cGVjdGVkIHRvIHN0b3JlIE1JcyBpbiBvcmRlciIpOworICAgICAgICBTdGF0ZS5NSXMucHVzaF9iYWNrKE5ld01JKTsKKyAgICAgIH0KKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpIDw8IEN1cnJlbnRJZHggPDwgIjogTUlzWyIgPDwgTmV3SW5zbklECisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8ICJdID0gR0lNX1JlY29yZEluc24oIiA8PCBJbnNuSUQgPDwgIiwgIiA8PCBPcElkeAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiKVxuIik7CisgICAgICBicmVhazsKKyAgICB9CisKKyAgICBjYXNlIEdJTV9DaGVja0ZlYXR1cmVzOiB7CisgICAgICBpbnQ2NF90IEV4cGVjdGVkQml0c2V0SUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8ICI6IEdJTV9DaGVja0ZlYXR1cmVzKEV4cGVjdGVkQml0c2V0SUQ9IgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCBFeHBlY3RlZEJpdHNldElEIDw8ICIpXG4iKTsKKyAgICAgIGlmICgoQXZhaWxhYmxlRmVhdHVyZXMgJiBJU2VsSW5mby5GZWF0dXJlQml0c2V0c1tFeHBlY3RlZEJpdHNldElEXSkgIT0KKyAgICAgICAgICBJU2VsSW5mby5GZWF0dXJlQml0c2V0c1tFeHBlY3RlZEJpdHNldElEXSkgeworICAgICAgICBpZiAoaGFuZGxlUmVqZWN0KCkgPT0gUmVqZWN0QW5kR2l2ZVVwKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgR0lNX0NoZWNrT3Bjb2RlOiB7CisgICAgICBpbnQ2NF90IEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgRXhwZWN0ZWQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisKKyAgICAgIHVuc2lnbmVkIE9wY29kZSA9IFN0YXRlLk1Jc1tJbnNuSURdLT5nZXRPcGNvZGUoKTsKKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpIDw8IEN1cnJlbnRJZHggPDwgIjogR0lNX0NoZWNrT3Bjb2RlKE1Jc1siIDw8IEluc25JRAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiXSwgRXhwZWN0ZWRPcGNvZGU9IiA8PCBFeHBlY3RlZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiKSAvLyBHb3Q9IiA8PCBPcGNvZGUgPDwgIlxuIik7CisgICAgICBhc3NlcnQoU3RhdGUuTUlzW0luc25JRF0gIT0gbnVsbHB0ciAmJiAiVXNlZCBpbnNuIGJlZm9yZSBkZWZpbmVkIik7CisgICAgICBpZiAoT3Bjb2RlICE9IEV4cGVjdGVkKSB7CisgICAgICAgIGlmIChoYW5kbGVSZWplY3QoKSA9PSBSZWplY3RBbmRHaXZlVXApCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBHSU1fQ2hlY2tOdW1PcGVyYW5kczogeworICAgICAgaW50NjRfdCBJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IEV4cGVjdGVkID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBHSU1fQ2hlY2tOdW1PcGVyYW5kcyhNSXNbIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCBJbnNuSUQgPDwgIl0sIEV4cGVjdGVkPSIgPDwgRXhwZWN0ZWQgPDwgIilcbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICE9IG51bGxwdHIgJiYgIlVzZWQgaW5zbiBiZWZvcmUgZGVmaW5lZCIpOworICAgICAgaWYgKFN0YXRlLk1Jc1tJbnNuSURdLT5nZXROdW1PcGVyYW5kcygpICE9IEV4cGVjdGVkKSB7CisgICAgICAgIGlmIChoYW5kbGVSZWplY3QoKSA9PSBSZWplY3RBbmRHaXZlVXApCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgR0lNX0NoZWNrSTY0SW1tUHJlZGljYXRlOiB7CisgICAgICBpbnQ2NF90IEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgUHJlZGljYXRlID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgQ3VycmVudElkeCA8PCAiOiBHSU1fQ2hlY2tJNjRJbW1QcmVkaWNhdGUoTUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgSW5zbklEIDw8ICJdLCBQcmVkaWNhdGU9IiA8PCBQcmVkaWNhdGUgPDwgIilcbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICE9IG51bGxwdHIgJiYgIlVzZWQgaW5zbiBiZWZvcmUgZGVmaW5lZCIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdLT5nZXRPcGNvZGUoKSA9PSBUYXJnZXRPcGNvZGU6OkdfQ09OU1RBTlQgJiYKKyAgICAgICAgICAgICAiRXhwZWN0ZWQgR19DT05TVEFOVCIpOworICAgICAgYXNzZXJ0KFByZWRpY2F0ZSA+IEdJUEZQX0k2NF9JbnZhbGlkICYmICJFeHBlY3RlZCBhIHZhbGlkIHByZWRpY2F0ZSIpOworICAgICAgaW50NjRfdCBWYWx1ZSA9IDA7CisgICAgICBpZiAoU3RhdGUuTUlzW0luc25JRF0tPmdldE9wZXJhbmQoMSkuaXNDSW1tKCkpCisgICAgICAgIFZhbHVlID0gU3RhdGUuTUlzW0luc25JRF0tPmdldE9wZXJhbmQoMSkuZ2V0Q0ltbSgpLT5nZXRTRXh0VmFsdWUoKTsKKyAgICAgIGVsc2UgaWYgKFN0YXRlLk1Jc1tJbnNuSURdLT5nZXRPcGVyYW5kKDEpLmlzSW1tKCkpCisgICAgICAgIFZhbHVlID0gU3RhdGUuTUlzW0luc25JRF0tPmdldE9wZXJhbmQoMSkuZ2V0SW1tKCk7CisgICAgICBlbHNlCisgICAgICAgIGxsdm1fdW5yZWFjaGFibGUoIkV4cGVjdGVkIEltbSBvciBDSW1tIG9wZXJhbmQiKTsKKworICAgICAgaWYgKCF0ZXN0SW1tUHJlZGljYXRlX0k2NChQcmVkaWNhdGUsIFZhbHVlKSkKKyAgICAgICAgaWYgKGhhbmRsZVJlamVjdCgpID09IFJlamVjdEFuZEdpdmVVcCkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBHSU1fQ2hlY2tBUEludEltbVByZWRpY2F0ZTogeworICAgICAgaW50NjRfdCBJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IFByZWRpY2F0ZSA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpCisgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IEN1cnJlbnRJZHggPDwgIjogR0lNX0NoZWNrQVBJbnRJbW1QcmVkaWNhdGUoTUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgSW5zbklEIDw8ICJdLCBQcmVkaWNhdGU9IiA8PCBQcmVkaWNhdGUgPDwgIilcbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICE9IG51bGxwdHIgJiYgIlVzZWQgaW5zbiBiZWZvcmUgZGVmaW5lZCIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdLT5nZXRPcGNvZGUoKSAmJiAiRXhwZWN0ZWQgR19DT05TVEFOVCIpOworICAgICAgYXNzZXJ0KFByZWRpY2F0ZSA+IEdJUEZQX0FQSW50X0ludmFsaWQgJiYgIkV4cGVjdGVkIGEgdmFsaWQgcHJlZGljYXRlIik7CisgICAgICBBUEludCBWYWx1ZTsKKyAgICAgIGlmIChTdGF0ZS5NSXNbSW5zbklEXS0+Z2V0T3BlcmFuZCgxKS5pc0NJbW0oKSkKKyAgICAgICAgVmFsdWUgPSBTdGF0ZS5NSXNbSW5zbklEXS0+Z2V0T3BlcmFuZCgxKS5nZXRDSW1tKCktPmdldFZhbHVlKCk7CisgICAgICBlbHNlCisgICAgICAgIGxsdm1fdW5yZWFjaGFibGUoIkV4cGVjdGVkIEltbSBvciBDSW1tIG9wZXJhbmQiKTsKKworICAgICAgaWYgKCF0ZXN0SW1tUHJlZGljYXRlX0FQSW50KFByZWRpY2F0ZSwgVmFsdWUpKQorICAgICAgICBpZiAoaGFuZGxlUmVqZWN0KCkgPT0gUmVqZWN0QW5kR2l2ZVVwKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEdJTV9DaGVja0FQRmxvYXRJbW1QcmVkaWNhdGU6IHsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBQcmVkaWNhdGUgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKQorICAgICAgICAgICAgICAgICAgICAgICAgICA8PCBDdXJyZW50SWR4IDw8ICI6IEdJTV9DaGVja0FQRmxvYXRJbW1QcmVkaWNhdGUoTUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgSW5zbklEIDw8ICJdLCBQcmVkaWNhdGU9IiA8PCBQcmVkaWNhdGUgPDwgIilcbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICE9IG51bGxwdHIgJiYgIlVzZWQgaW5zbiBiZWZvcmUgZGVmaW5lZCIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdLT5nZXRPcGNvZGUoKSA9PSBUYXJnZXRPcGNvZGU6OkdfRkNPTlNUQU5UICYmCisgICAgICAgICAgICAgIkV4cGVjdGVkIEdfRkNPTlNUQU5UIik7CisgICAgICBhc3NlcnQoU3RhdGUuTUlzW0luc25JRF0tPmdldE9wZXJhbmQoMSkuaXNGUEltbSgpICYmICJFeHBlY3RlZCBGUEltbSBvcGVyYW5kIik7CisgICAgICBhc3NlcnQoUHJlZGljYXRlID4gR0lQRlBfQVBGbG9hdF9JbnZhbGlkICYmICJFeHBlY3RlZCBhIHZhbGlkIHByZWRpY2F0ZSIpOworICAgICAgQVBGbG9hdCBWYWx1ZSA9IFN0YXRlLk1Jc1tJbnNuSURdLT5nZXRPcGVyYW5kKDEpLmdldEZQSW1tKCktPmdldFZhbHVlQVBGKCk7CisKKyAgICAgIGlmICghdGVzdEltbVByZWRpY2F0ZV9BUEZsb2F0KFByZWRpY2F0ZSwgVmFsdWUpKQorICAgICAgICBpZiAoaGFuZGxlUmVqZWN0KCkgPT0gUmVqZWN0QW5kR2l2ZVVwKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEdJTV9DaGVja0F0b21pY09yZGVyaW5nOiB7CisgICAgICBpbnQ2NF90IEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIEF0b21pY09yZGVyaW5nIE9yZGVyaW5nID0gKEF0b21pY09yZGVyaW5nKU1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpIDw8IEN1cnJlbnRJZHggPDwgIjogR0lNX0NoZWNrQXRvbWljT3JkZXJpbmcoTUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgSW5zbklEIDw8ICJdLCAiIDw8ICh1aW50NjRfdClPcmRlcmluZyA8PCAiKVxuIik7CisgICAgICBhc3NlcnQoU3RhdGUuTUlzW0luc25JRF0gIT0gbnVsbHB0ciAmJiAiVXNlZCBpbnNuIGJlZm9yZSBkZWZpbmVkIik7CisKKyAgICAgIGlmICghU3RhdGUuTUlzW0luc25JRF0tPmhhc09uZU1lbU9wZXJhbmQoKSkKKyAgICAgICAgaWYgKGhhbmRsZVJlamVjdCgpID09IFJlamVjdEFuZEdpdmVVcCkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGZvciAoY29uc3QgYXV0byAmTU1PIDogU3RhdGUuTUlzW0luc25JRF0tPm1lbW9wZXJhbmRzKCkpCisgICAgICAgIGlmIChNTU8tPmdldE9yZGVyaW5nKCkgIT0gT3JkZXJpbmcpCisgICAgICAgICAgaWYgKGhhbmRsZVJlamVjdCgpID09IFJlamVjdEFuZEdpdmVVcCkKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEdJTV9DaGVja0F0b21pY09yZGVyaW5nT3JTdHJvbmdlclRoYW46IHsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgQXRvbWljT3JkZXJpbmcgT3JkZXJpbmcgPSAoQXRvbWljT3JkZXJpbmcpTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiOiBHSU1fQ2hlY2tBdG9taWNPcmRlcmluZ09yU3Ryb25nZXJUaGFuKE1Jc1siCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IEluc25JRCA8PCAiXSwgIiA8PCAodWludDY0X3QpT3JkZXJpbmcgPDwgIilcbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICE9IG51bGxwdHIgJiYgIlVzZWQgaW5zbiBiZWZvcmUgZGVmaW5lZCIpOworCisgICAgICBpZiAoIVN0YXRlLk1Jc1tJbnNuSURdLT5oYXNPbmVNZW1PcGVyYW5kKCkpCisgICAgICAgIGlmIChoYW5kbGVSZWplY3QoKSA9PSBSZWplY3RBbmRHaXZlVXApCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgICBmb3IgKGNvbnN0IGF1dG8gJk1NTyA6IFN0YXRlLk1Jc1tJbnNuSURdLT5tZW1vcGVyYW5kcygpKQorICAgICAgICBpZiAoIWlzQXRMZWFzdE9yU3Ryb25nZXJUaGFuKE1NTy0+Z2V0T3JkZXJpbmcoKSwgT3JkZXJpbmcpKQorICAgICAgICAgIGlmIChoYW5kbGVSZWplY3QoKSA9PSBSZWplY3RBbmRHaXZlVXApCisgICAgICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBHSU1fQ2hlY2tBdG9taWNPcmRlcmluZ1dlYWtlclRoYW46IHsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgQXRvbWljT3JkZXJpbmcgT3JkZXJpbmcgPSAoQXRvbWljT3JkZXJpbmcpTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiOiBHSU1fQ2hlY2tBdG9taWNPcmRlcmluZ1dlYWtlclRoYW4oTUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgSW5zbklEIDw8ICJdLCAiIDw8ICh1aW50NjRfdClPcmRlcmluZyA8PCAiKVxuIik7CisgICAgICBhc3NlcnQoU3RhdGUuTUlzW0luc25JRF0gIT0gbnVsbHB0ciAmJiAiVXNlZCBpbnNuIGJlZm9yZSBkZWZpbmVkIik7CisKKyAgICAgIGlmICghU3RhdGUuTUlzW0luc25JRF0tPmhhc09uZU1lbU9wZXJhbmQoKSkKKyAgICAgICAgaWYgKGhhbmRsZVJlamVjdCgpID09IFJlamVjdEFuZEdpdmVVcCkKKyAgICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIGZvciAoY29uc3QgYXV0byAmTU1PIDogU3RhdGUuTUlzW0luc25JRF0tPm1lbW9wZXJhbmRzKCkpCisgICAgICAgIGlmICghaXNTdHJvbmdlclRoYW4oT3JkZXJpbmcsIE1NTy0+Z2V0T3JkZXJpbmcoKSkpCisgICAgICAgICAgaWYgKGhhbmRsZVJlamVjdCgpID09IFJlamVjdEFuZEdpdmVVcCkKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEdJTV9DaGVja1R5cGU6IHsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBPcElkeCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgVHlwZUlEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBHSU1fQ2hlY2tUeXBlKE1Jc1siIDw8IEluc25JRAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiXS0+Z2V0T3BlcmFuZCgiIDw8IE9wSWR4CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8ICIpLCBUeXBlSUQ9IiA8PCBUeXBlSUQgPDwgIilcbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICE9IG51bGxwdHIgJiYgIlVzZWQgaW5zbiBiZWZvcmUgZGVmaW5lZCIpOworCisgICAgICBNYWNoaW5lT3BlcmFuZCAmTU8gPSBTdGF0ZS5NSXNbSW5zbklEXS0+Z2V0T3BlcmFuZChPcElkeCk7CisgICAgICBpZiAoIU1PLmlzUmVnKCkgfHwKKyAgICAgICAgICBNUkkuZ2V0VHlwZShNTy5nZXRSZWcoKSkgIT0gSVNlbEluZm8uVHlwZU9iamVjdHNbVHlwZUlEXSkgeworICAgICAgICBpZiAoaGFuZGxlUmVqZWN0KCkgPT0gUmVqZWN0QW5kR2l2ZVVwKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEdJTV9DaGVja1BvaW50ZXJUb0FueTogeworICAgICAgaW50NjRfdCBJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IE9wSWR4ID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBTaXplSW5CaXRzID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworCisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IEdJTV9DaGVja1BvaW50ZXJUb0FueShNSXNbIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCBJbnNuSUQgPDwgIl0tPmdldE9wZXJhbmQoIiA8PCBPcElkeAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiKSwgU2l6ZUluQml0cz0iIDw8IFNpemVJbkJpdHMgPDwgIilcbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICE9IG51bGxwdHIgJiYgIlVzZWQgaW5zbiBiZWZvcmUgZGVmaW5lZCIpOworCisgICAgICAvLyBpUFRSIG11c3QgYmUgbG9va2VkIHVwIGluIHRoZSB0YXJnZXQuCisgICAgICBpZiAoU2l6ZUluQml0cyA9PSAwKSB7CisgICAgICAgIE1hY2hpbmVGdW5jdGlvbiAqTUYgPSBTdGF0ZS5NSXNbSW5zbklEXS0+Z2V0UGFyZW50KCktPmdldFBhcmVudCgpOworICAgICAgICBTaXplSW5CaXRzID0gTUYtPmdldERhdGFMYXlvdXQoKS5nZXRQb2ludGVyU2l6ZUluQml0cygwKTsKKyAgICAgIH0KKworICAgICAgYXNzZXJ0KFNpemVJbkJpdHMgIT0gMCAmJiAiUG9pbnRlciBzaXplIG11c3QgYmUga25vd24iKTsKKworICAgICAgTWFjaGluZU9wZXJhbmQgJk1PID0gU3RhdGUuTUlzW0luc25JRF0tPmdldE9wZXJhbmQoT3BJZHgpOworICAgICAgaWYgKE1PLmlzUmVnKCkpIHsKKyAgICAgICAgY29uc3QgTExUICZUeSA9IE1SSS5nZXRUeXBlKE1PLmdldFJlZygpKTsKKyAgICAgICAgaWYgKCFUeS5pc1BvaW50ZXIoKSB8fCBUeS5nZXRTaXplSW5CaXRzKCkgIT0gU2l6ZUluQml0cykKKyAgICAgICAgICBpZiAoaGFuZGxlUmVqZWN0KCkgPT0gUmVqZWN0QW5kR2l2ZVVwKQorICAgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgfSBlbHNlIGlmIChoYW5kbGVSZWplY3QoKSA9PSBSZWplY3RBbmRHaXZlVXApCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYnJlYWs7CisgICAgfQorICAgIGNhc2UgR0lNX0NoZWNrUmVnQmFua0ZvckNsYXNzOiB7CisgICAgICBpbnQ2NF90IEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgT3BJZHggPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IFJDRW51bSA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpIDw8IEN1cnJlbnRJZHggPDwgIjogR0lNX0NoZWNrUmVnQmFua0ZvckNsYXNzKE1Jc1siCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IEluc25JRCA8PCAiXS0+Z2V0T3BlcmFuZCgiIDw8IE9wSWR4CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8ICIpLCBSQ0VudW09IiA8PCBSQ0VudW0gPDwgIilcbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICE9IG51bGxwdHIgJiYgIlVzZWQgaW5zbiBiZWZvcmUgZGVmaW5lZCIpOworICAgICAgTWFjaGluZU9wZXJhbmQgJk1PID0gU3RhdGUuTUlzW0luc25JRF0tPmdldE9wZXJhbmQoT3BJZHgpOworICAgICAgaWYgKCFNTy5pc1JlZygpIHx8CisgICAgICAgICAgJlJCSS5nZXRSZWdCYW5rRnJvbVJlZ0NsYXNzKCpUUkkuZ2V0UmVnQ2xhc3MoUkNFbnVtKSkgIT0KKyAgICAgICAgICAgICAgUkJJLmdldFJlZ0JhbmsoTU8uZ2V0UmVnKCksIE1SSSwgVFJJKSkgeworICAgICAgICBpZiAoaGFuZGxlUmVqZWN0KCkgPT0gUmVqZWN0QW5kR2l2ZVVwKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgR0lNX0NoZWNrQ29tcGxleFBhdHRlcm46IHsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBPcElkeCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgUmVuZGVyZXJJRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgQ29tcGxleFByZWRpY2F0ZUlEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBTdGF0ZS5SZW5kZXJlcnNbIiA8PCBSZW5kZXJlcklECisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8ICJdID0gR0lNX0NoZWNrQ29tcGxleFBhdHRlcm4oTUlzWyIgPDwgSW5zbklECisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8ICJdLT5nZXRPcGVyYW5kKCIgPDwgT3BJZHgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgIiksIENvbXBsZXhQcmVkaWNhdGVJRD0iIDw8IENvbXBsZXhQcmVkaWNhdGVJRAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiKVxuIik7CisgICAgICBhc3NlcnQoU3RhdGUuTUlzW0luc25JRF0gIT0gbnVsbHB0ciAmJiAiVXNlZCBpbnNuIGJlZm9yZSBkZWZpbmVkIik7CisgICAgICAvLyBGSVhNRTogVXNlIHN0ZDo6aW52b2tlKCkgd2hlbiBpdCdzIGF2YWlsYWJsZS4KKyAgICAgIENvbXBsZXhSZW5kZXJlckZucyBSZW5kZXJlciA9CisgICAgICAgICAgKElTZWwuKklTZWxJbmZvLkNvbXBsZXhQcmVkaWNhdGVzW0NvbXBsZXhQcmVkaWNhdGVJRF0pKAorICAgICAgICAgICAgICBTdGF0ZS5NSXNbSW5zbklEXS0+Z2V0T3BlcmFuZChPcElkeCkpOworICAgICAgaWYgKFJlbmRlcmVyLmhhc1ZhbHVlKCkpCisgICAgICAgIFN0YXRlLlJlbmRlcmVyc1tSZW5kZXJlcklEXSA9IFJlbmRlcmVyLmdldFZhbHVlKCk7CisgICAgICBlbHNlCisgICAgICAgIGlmIChoYW5kbGVSZWplY3QoKSA9PSBSZWplY3RBbmRHaXZlVXApCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBHSU1fQ2hlY2tDb25zdGFudEludDogeworICAgICAgaW50NjRfdCBJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IE9wSWR4ID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBWYWx1ZSA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpIDw8IEN1cnJlbnRJZHggPDwgIjogR0lNX0NoZWNrQ29uc3RhbnRJbnQoTUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgSW5zbklEIDw8ICJdLT5nZXRPcGVyYW5kKCIgPDwgT3BJZHgKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgIiksIFZhbHVlPSIgPDwgVmFsdWUgPDwgIilcbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICE9IG51bGxwdHIgJiYgIlVzZWQgaW5zbiBiZWZvcmUgZGVmaW5lZCIpOworCisgICAgICBNYWNoaW5lT3BlcmFuZCAmTU8gPSBTdGF0ZS5NSXNbSW5zbklEXS0+Z2V0T3BlcmFuZChPcElkeCk7CisgICAgICBpZiAoTU8uaXNSZWcoKSkgeworICAgICAgICAvLyBpc09wZXJhbmRJbW1FcXVhbCgpIHdpbGwgc2lnbi1leHRlbmQgdG8gNjQtYml0cywgc28gc2hvdWxkIHdlLgorICAgICAgICBMTFQgVHkgPSBNUkkuZ2V0VHlwZShNTy5nZXRSZWcoKSk7CisgICAgICAgIFZhbHVlID0gU2lnbkV4dGVuZDY0KFZhbHVlLCBUeS5nZXRTaXplSW5CaXRzKCkpOworCisgICAgICAgIGlmICghaXNPcGVyYW5kSW1tRXF1YWwoTU8sIFZhbHVlLCBNUkkpKSB7CisgICAgICAgICAgaWYgKGhhbmRsZVJlamVjdCgpID09IFJlamVjdEFuZEdpdmVVcCkKKyAgICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIGlmIChoYW5kbGVSZWplY3QoKSA9PSBSZWplY3RBbmRHaXZlVXApCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBHSU1fQ2hlY2tMaXRlcmFsSW50OiB7CisgICAgICBpbnQ2NF90IEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgT3BJZHggPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IFZhbHVlID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBHSU1fQ2hlY2tMaXRlcmFsSW50KE1Jc1siCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IEluc25JRCA8PCAiXS0+Z2V0T3BlcmFuZCgiIDw8IE9wSWR4CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8ICIpLCBWYWx1ZT0iIDw8IFZhbHVlIDw8ICIpXG4iKTsKKyAgICAgIGFzc2VydChTdGF0ZS5NSXNbSW5zbklEXSAhPSBudWxscHRyICYmICJVc2VkIGluc24gYmVmb3JlIGRlZmluZWQiKTsKKyAgICAgIE1hY2hpbmVPcGVyYW5kICZNTyA9IFN0YXRlLk1Jc1tJbnNuSURdLT5nZXRPcGVyYW5kKE9wSWR4KTsKKyAgICAgIGlmICghTU8uaXNDSW1tKCkgfHwgIU1PLmdldENJbW0oKS0+ZXF1YWxzSW50KFZhbHVlKSkgeworICAgICAgICBpZiAoaGFuZGxlUmVqZWN0KCkgPT0gUmVqZWN0QW5kR2l2ZVVwKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgR0lNX0NoZWNrSW50cmluc2ljSUQ6IHsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBPcElkeCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgVmFsdWUgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IEdJTV9DaGVja0ludHJpbnNpY0lEKE1Jc1siCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IEluc25JRCA8PCAiXS0+Z2V0T3BlcmFuZCgiIDw8IE9wSWR4CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8ICIpLCBWYWx1ZT0iIDw8IFZhbHVlIDw8ICIpXG4iKTsKKyAgICAgIGFzc2VydChTdGF0ZS5NSXNbSW5zbklEXSAhPSBudWxscHRyICYmICJVc2VkIGluc24gYmVmb3JlIGRlZmluZWQiKTsKKyAgICAgIE1hY2hpbmVPcGVyYW5kICZNTyA9IFN0YXRlLk1Jc1tJbnNuSURdLT5nZXRPcGVyYW5kKE9wSWR4KTsKKyAgICAgIGlmICghTU8uaXNJbnRyaW5zaWNJRCgpIHx8IE1PLmdldEludHJpbnNpY0lEKCkgIT0gVmFsdWUpCisgICAgICAgIGlmIChoYW5kbGVSZWplY3QoKSA9PSBSZWplY3RBbmRHaXZlVXApCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBHSU1fQ2hlY2tJc01CQjogeworICAgICAgaW50NjRfdCBJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IE9wSWR4ID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBHSU1fQ2hlY2tJc01CQihNSXNbIiA8PCBJbnNuSUQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgIl0tPmdldE9wZXJhbmQoIiA8PCBPcElkeCA8PCAiKSlcbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICE9IG51bGxwdHIgJiYgIlVzZWQgaW5zbiBiZWZvcmUgZGVmaW5lZCIpOworICAgICAgaWYgKCFTdGF0ZS5NSXNbSW5zbklEXS0+Z2V0T3BlcmFuZChPcElkeCkuaXNNQkIoKSkgeworICAgICAgICBpZiAoaGFuZGxlUmVqZWN0KCkgPT0gUmVqZWN0QW5kR2l2ZVVwKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgR0lNX0NoZWNrSXNTYWZlVG9Gb2xkOiB7CisgICAgICBpbnQ2NF90IEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpIDw8IEN1cnJlbnRJZHggPDwgIjogR0lNX0NoZWNrSXNTYWZlVG9Gb2xkKE1Jc1siCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IEluc25JRCA8PCAiXSlcbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICE9IG51bGxwdHIgJiYgIlVzZWQgaW5zbiBiZWZvcmUgZGVmaW5lZCIpOworICAgICAgaWYgKCFpc09idmlvdXNseVNhZmVUb0ZvbGQoKlN0YXRlLk1Jc1tJbnNuSURdLCAqU3RhdGUuTUlzWzBdKSkgeworICAgICAgICBpZiAoaGFuZGxlUmVqZWN0KCkgPT0gUmVqZWN0QW5kR2l2ZVVwKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEdJTV9DaGVja0lzU2FtZU9wZXJhbmQ6IHsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBPcElkeCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgT3RoZXJJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IE90aGVyT3BJZHggPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IEdJTV9DaGVja0lzU2FtZU9wZXJhbmQoTUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgSW5zbklEIDw8ICJdWyIgPDwgT3BJZHggPDwgIl0sIE1Jc1siCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IE90aGVySW5zbklEIDw8ICJdWyIgPDwgT3RoZXJPcElkeCA8PCAiXSlcbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICE9IG51bGxwdHIgJiYgIlVzZWQgaW5zbiBiZWZvcmUgZGVmaW5lZCIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tPdGhlckluc25JRF0gIT0gbnVsbHB0ciAmJiAiVXNlZCBpbnNuIGJlZm9yZSBkZWZpbmVkIik7CisgICAgICBpZiAoIVN0YXRlLk1Jc1tJbnNuSURdLT5nZXRPcGVyYW5kKE9wSWR4KS5pc0lkZW50aWNhbFRvKAorICAgICAgICAgICAgICBTdGF0ZS5NSXNbT3RoZXJJbnNuSURdLT5nZXRPcGVyYW5kKE90aGVyT3BJZHgpKSkgeworICAgICAgICBpZiAoaGFuZGxlUmVqZWN0KCkgPT0gUmVqZWN0QW5kR2l2ZVVwKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIH0KKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBjYXNlIEdJTV9SZWplY3Q6CisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IEdJTV9SZWplY3QiKTsKKyAgICAgIGlmIChoYW5kbGVSZWplY3QoKSA9PSBSZWplY3RBbmRHaXZlVXApCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSBHSVJfTXV0YXRlT3Bjb2RlOiB7CisgICAgICBpbnQ2NF90IE9sZEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIHVpbnQ2NF90IE5ld0luc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgTmV3T3Bjb2RlID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaWYgKE5ld0luc25JRCA+PSBPdXRNSXMuc2l6ZSgpKQorICAgICAgICBPdXRNSXMucmVzaXplKE5ld0luc25JRCArIDEpOworCisgICAgICBPdXRNSXNbTmV3SW5zbklEXSA9IE1hY2hpbmVJbnN0ckJ1aWxkZXIoKlN0YXRlLk1Jc1tPbGRJbnNuSURdLT5nZXRNRigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXRlLk1Jc1tPbGRJbnNuSURdKTsKKyAgICAgIE91dE1Jc1tOZXdJbnNuSURdLT5zZXREZXNjKFRJSS5nZXQoTmV3T3Bjb2RlKSk7CisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IEdJUl9NdXRhdGVPcGNvZGUoT3V0TUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgTmV3SW5zbklEIDw8ICJdLCBNSXNbIiA8PCBPbGRJbnNuSUQgPDwgIl0sICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgTmV3T3Bjb2RlIDw8ICIpXG4iKTsKKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgR0lSX0J1aWxkTUk6IHsKKyAgICAgIHVpbnQ2NF90IE5ld0luc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgT3Bjb2RlID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaWYgKE5ld0luc25JRCA+PSBPdXRNSXMuc2l6ZSgpKQorICAgICAgICBPdXRNSXMucmVzaXplKE5ld0luc25JRCArIDEpOworCisgICAgICBPdXRNSXNbTmV3SW5zbklEXSA9IEJ1aWxkTUkoKlN0YXRlLk1Jc1swXS0+Z2V0UGFyZW50KCksIFN0YXRlLk1Jc1swXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZS5NSXNbMF0tPmdldERlYnVnTG9jKCksIFRJSS5nZXQoT3Bjb2RlKSk7CisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IEdJUl9CdWlsZE1JKE91dE1Jc1siCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IE5ld0luc25JRCA8PCAiXSwgIiA8PCBPcGNvZGUgPDwgIilcbiIpOworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBHSVJfQ29weTogeworICAgICAgaW50NjRfdCBOZXdJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IE9sZEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgT3BJZHggPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBhc3NlcnQoT3V0TUlzW05ld0luc25JRF0gJiYgIkF0dGVtcHRlZCB0byBhZGQgdG8gdW5kZWZpbmVkIGluc3RydWN0aW9uIik7CisgICAgICBPdXRNSXNbTmV3SW5zbklEXS5hZGQoU3RhdGUuTUlzW09sZEluc25JRF0tPmdldE9wZXJhbmQoT3BJZHgpKTsKKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpCisgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IEN1cnJlbnRJZHggPDwgIjogR0lSX0NvcHkoT3V0TUlzWyIgPDwgTmV3SW5zbklECisgICAgICAgICAgICAgICAgICAgICAgICAgIDw8ICJdLCBNSXNbIiA8PCBPbGRJbnNuSUQgPDwgIl0sICIgPDwgT3BJZHggPDwgIilcbiIpOworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBHSVJfQ29weU9yQWRkWmVyb1JlZzogeworICAgICAgaW50NjRfdCBOZXdJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IE9sZEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgT3BJZHggPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IFplcm9SZWcgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBhc3NlcnQoT3V0TUlzW05ld0luc25JRF0gJiYgIkF0dGVtcHRlZCB0byBhZGQgdG8gdW5kZWZpbmVkIGluc3RydWN0aW9uIik7CisgICAgICBNYWNoaW5lT3BlcmFuZCAmTU8gPSBTdGF0ZS5NSXNbT2xkSW5zbklEXS0+Z2V0T3BlcmFuZChPcElkeCk7CisgICAgICBpZiAoaXNPcGVyYW5kSW1tRXF1YWwoTU8sIDAsIE1SSSkpCisgICAgICAgIE91dE1Jc1tOZXdJbnNuSURdLmFkZFJlZyhaZXJvUmVnKTsKKyAgICAgIGVsc2UKKyAgICAgICAgT3V0TUlzW05ld0luc25JRF0uYWRkKE1PKTsKKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpIDw8IEN1cnJlbnRJZHggPDwgIjogR0lSX0NvcHlPckFkZFplcm9SZWcoT3V0TUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgTmV3SW5zbklEIDw8ICJdLCBNSXNbIiA8PCBPbGRJbnNuSUQgPDwgIl0sICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgT3BJZHggPDwgIiwgIiA8PCBaZXJvUmVnIDw8ICIpXG4iKTsKKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgR0lSX0NvcHlTdWJSZWc6IHsKKyAgICAgIGludDY0X3QgTmV3SW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBPbGRJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IE9wSWR4ID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBTdWJSZWdJZHggPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBhc3NlcnQoT3V0TUlzW05ld0luc25JRF0gJiYgIkF0dGVtcHRlZCB0byBhZGQgdG8gdW5kZWZpbmVkIGluc3RydWN0aW9uIik7CisgICAgICBPdXRNSXNbTmV3SW5zbklEXS5hZGRSZWcoU3RhdGUuTUlzW09sZEluc25JRF0tPmdldE9wZXJhbmQoT3BJZHgpLmdldFJlZygpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIFN1YlJlZ0lkeCk7CisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IEdJUl9Db3B5U3ViUmVnKE91dE1Jc1siCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IE5ld0luc25JRCA8PCAiXSwgTUlzWyIgPDwgT2xkSW5zbklEIDw8ICJdLCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IE9wSWR4IDw8ICIsICIgPDwgU3ViUmVnSWR4IDw8ICIpXG4iKTsKKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgR0lSX0FkZEltcGxpY2l0RGVmOiB7CisgICAgICBpbnQ2NF90IEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgUmVnTnVtID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgYXNzZXJ0KE91dE1Jc1tJbnNuSURdICYmICJBdHRlbXB0ZWQgdG8gYWRkIHRvIHVuZGVmaW5lZCBpbnN0cnVjdGlvbiIpOworICAgICAgT3V0TUlzW0luc25JRF0uYWRkRGVmKFJlZ051bSwgUmVnU3RhdGU6OkltcGxpY2l0KTsKKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpIDw8IEN1cnJlbnRJZHggPDwgIjogR0lSX0FkZEltcGxpY2l0RGVmKE91dE1Jc1siCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IEluc25JRCA8PCAiXSwgIiA8PCBSZWdOdW0gPDwgIilcbiIpOworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBHSVJfQWRkSW1wbGljaXRVc2U6IHsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBSZWdOdW0gPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBhc3NlcnQoT3V0TUlzW0luc25JRF0gJiYgIkF0dGVtcHRlZCB0byBhZGQgdG8gdW5kZWZpbmVkIGluc3RydWN0aW9uIik7CisgICAgICBPdXRNSXNbSW5zbklEXS5hZGRVc2UoUmVnTnVtLCBSZWdTdGF0ZTo6SW1wbGljaXQpOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBHSVJfQWRkSW1wbGljaXRVc2UoT3V0TUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgSW5zbklEIDw8ICJdLCAiIDw8IFJlZ051bSA8PCAiKVxuIik7CisgICAgICBicmVhazsKKyAgICB9CisKKyAgICBjYXNlIEdJUl9BZGRSZWdpc3RlcjogeworICAgICAgaW50NjRfdCBJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IFJlZ051bSA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGFzc2VydChPdXRNSXNbSW5zbklEXSAmJiAiQXR0ZW1wdGVkIHRvIGFkZCB0byB1bmRlZmluZWQgaW5zdHJ1Y3Rpb24iKTsKKyAgICAgIE91dE1Jc1tJbnNuSURdLmFkZFJlZyhSZWdOdW0pOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBHSVJfQWRkUmVnaXN0ZXIoT3V0TUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgSW5zbklEIDw8ICJdLCAiIDw8IFJlZ051bSA8PCAiKVxuIik7CisgICAgICBicmVhazsKKyAgICB9CisKKyAgICBjYXNlIEdJUl9BZGRUZW1wUmVnaXN0ZXI6IHsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBUZW1wUmVnSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICB1aW50NjRfdCBUZW1wUmVnRmxhZ3MgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBhc3NlcnQoT3V0TUlzW0luc25JRF0gJiYgIkF0dGVtcHRlZCB0byBhZGQgdG8gdW5kZWZpbmVkIGluc3RydWN0aW9uIik7CisgICAgICBPdXRNSXNbSW5zbklEXS5hZGRSZWcoU3RhdGUuVGVtcFJlZ2lzdGVyc1tUZW1wUmVnSURdLCBUZW1wUmVnRmxhZ3MpOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBHSVJfQWRkVGVtcFJlZ2lzdGVyKE91dE1Jc1siCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IEluc25JRCA8PCAiXSwgVGVtcFJlZ2lzdGVyc1siIDw8IFRlbXBSZWdJRAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiXSwgIiA8PCBUZW1wUmVnRmxhZ3MgPDwgIilcbiIpOworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBHSVJfQWRkSW1tOiB7CisgICAgICBpbnQ2NF90IEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgSW1tID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgYXNzZXJ0KE91dE1Jc1tJbnNuSURdICYmICJBdHRlbXB0ZWQgdG8gYWRkIHRvIHVuZGVmaW5lZCBpbnN0cnVjdGlvbiIpOworICAgICAgT3V0TUlzW0luc25JRF0uYWRkSW1tKEltbSk7CisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IEdJUl9BZGRJbW0oT3V0TUlzWyIgPDwgSW5zbklECisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8ICJdLCAiIDw8IEltbSA8PCAiKVxuIik7CisgICAgICBicmVhazsKKyAgICB9CisKKyAgICBjYXNlIEdJUl9Db21wbGV4UmVuZGVyZXI6IHsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgaW50NjRfdCBSZW5kZXJlcklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgYXNzZXJ0KE91dE1Jc1tJbnNuSURdICYmICJBdHRlbXB0ZWQgdG8gYWRkIHRvIHVuZGVmaW5lZCBpbnN0cnVjdGlvbiIpOworICAgICAgZm9yIChjb25zdCBhdXRvICZSZW5kZXJPcEZuIDogU3RhdGUuUmVuZGVyZXJzW1JlbmRlcmVySURdKQorICAgICAgICBSZW5kZXJPcEZuKE91dE1Jc1tJbnNuSURdKTsKKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpIDw8IEN1cnJlbnRJZHggPDwgIjogR0lSX0NvbXBsZXhSZW5kZXJlcihPdXRNSXNbIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCBJbnNuSUQgPDwgIl0sICIgPDwgUmVuZGVyZXJJRCA8PCAiKVxuIik7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBHSVJfQ29tcGxleFN1Yk9wZXJhbmRSZW5kZXJlcjogeworICAgICAgaW50NjRfdCBJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IFJlbmRlcmVySUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IFJlbmRlck9wSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBhc3NlcnQoT3V0TUlzW0luc25JRF0gJiYgIkF0dGVtcHRlZCB0byBhZGQgdG8gdW5kZWZpbmVkIGluc3RydWN0aW9uIik7CisgICAgICBTdGF0ZS5SZW5kZXJlcnNbUmVuZGVyZXJJRF1bUmVuZGVyT3BJRF0oT3V0TUlzW0luc25JRF0pOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiOiBHSVJfQ29tcGxleFN1Yk9wZXJhbmRSZW5kZXJlcihPdXRNSXNbIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCBJbnNuSUQgPDwgIl0sICIgPDwgUmVuZGVyZXJJRCA8PCAiLCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IFJlbmRlck9wSUQgPDwgIilcbiIpOworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBHSVJfQ29weUNvbnN0YW50QXNTSW1tOiB7CisgICAgICBpbnQ2NF90IE5ld0luc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgT2xkSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgYXNzZXJ0KE91dE1Jc1tOZXdJbnNuSURdICYmICJBdHRlbXB0ZWQgdG8gYWRkIHRvIHVuZGVmaW5lZCBpbnN0cnVjdGlvbiIpOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tPbGRJbnNuSURdLT5nZXRPcGNvZGUoKSA9PSBUYXJnZXRPcGNvZGU6OkdfQ09OU1RBTlQgJiYgIkV4cGVjdGVkIEdfQ09OU1RBTlQiKTsKKyAgICAgIGlmIChTdGF0ZS5NSXNbT2xkSW5zbklEXS0+Z2V0T3BlcmFuZCgxKS5pc0NJbW0oKSkgeworICAgICAgICBPdXRNSXNbTmV3SW5zbklEXS5hZGRJbW0oCisgICAgICAgICAgICBTdGF0ZS5NSXNbT2xkSW5zbklEXS0+Z2V0T3BlcmFuZCgxKS5nZXRDSW1tKCktPmdldFNFeHRWYWx1ZSgpKTsKKyAgICAgIH0gZWxzZSBpZiAoU3RhdGUuTUlzW09sZEluc25JRF0tPmdldE9wZXJhbmQoMSkuaXNJbW0oKSkKKyAgICAgICAgT3V0TUlzW05ld0luc25JRF0uYWRkKFN0YXRlLk1Jc1tPbGRJbnNuSURdLT5nZXRPcGVyYW5kKDEpKTsKKyAgICAgIGVsc2UKKyAgICAgICAgbGx2bV91bnJlYWNoYWJsZSgiRXhwZWN0ZWQgSW1tIG9yIENJbW0gb3BlcmFuZCIpOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBHSVJfQ29weUNvbnN0YW50QXNTSW1tKE91dE1Jc1siCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IE5ld0luc25JRCA8PCAiXSwgTUlzWyIgPDwgT2xkSW5zbklEIDw8ICJdKVxuIik7CisgICAgICBicmVhazsKKyAgICB9CisKKyAgICBjYXNlIEdJUl9DdXN0b21SZW5kZXJlcjogeworICAgICAgaW50NjRfdCBJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IE9sZEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgUmVuZGVyZXJGbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgYXNzZXJ0KE91dE1Jc1tJbnNuSURdICYmICJBdHRlbXB0ZWQgdG8gYWRkIHRvIHVuZGVmaW5lZCBpbnN0cnVjdGlvbiIpOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBHSVJfQ3VzdG9tUmVuZGVyZXIoT3V0TUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgSW5zbklEIDw8ICJdLCBNSXNbIiA8PCBPbGRJbnNuSUQgPDwgIl0sICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgUmVuZGVyZXJGbklEIDw8ICIpXG4iKTsKKyAgICAgIChJU2VsLipJU2VsSW5mby5DdXN0b21SZW5kZXJlcnNbUmVuZGVyZXJGbklEXSkoT3V0TUlzW0luc25JRF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpTdGF0ZS5NSXNbT2xkSW5zbklEXSk7CisgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBHSVJfQ29uc3RyYWluT3BlcmFuZFJDOiB7CisgICAgICBpbnQ2NF90IEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgT3BJZHggPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBpbnQ2NF90IFJDRW51bSA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGFzc2VydChPdXRNSXNbSW5zbklEXSAmJiAiQXR0ZW1wdGVkIHRvIGFkZCB0byB1bmRlZmluZWQgaW5zdHJ1Y3Rpb24iKTsKKyAgICAgIGNvbnN0cmFpbk9wZXJhbmRSZWdUb1JlZ0NsYXNzKCpPdXRNSXNbSW5zbklEXS5nZXRJbnN0cigpLCBPcElkeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpUUkkuZ2V0UmVnQ2xhc3MoUkNFbnVtKSwgVElJLCBUUkksIFJCSSk7CisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IEdJUl9Db25zdHJhaW5PcGVyYW5kUkMoT3V0TUlzWyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPDwgSW5zbklEIDw8ICJdLCAiIDw8IE9wSWR4IDw8ICIsICIgPDwgUkNFbnVtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8ICIpXG4iKTsKKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgR0lSX0NvbnN0cmFpblNlbGVjdGVkSW5zdE9wZXJhbmRzOiB7CisgICAgICBpbnQ2NF90IEluc25JRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGFzc2VydChPdXRNSXNbSW5zbklEXSAmJiAiQXR0ZW1wdGVkIHRvIGFkZCB0byB1bmRlZmluZWQgaW5zdHJ1Y3Rpb24iKTsKKyAgICAgIGNvbnN0cmFpblNlbGVjdGVkSW5zdFJlZ09wZXJhbmRzKCpPdXRNSXNbSW5zbklEXS5nZXRJbnN0cigpLCBUSUksIFRSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJCSSk7CisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8ICI6IEdJUl9Db25zdHJhaW5TZWxlY3RlZEluc3RPcGVyYW5kcyhPdXRNSXNbIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCBJbnNuSUQgPDwgIl0pXG4iKTsKKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgR0lSX01lcmdlTWVtT3BlcmFuZHM6IHsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgYXNzZXJ0KE91dE1Jc1tJbnNuSURdICYmICJBdHRlbXB0ZWQgdG8gYWRkIHRvIHVuZGVmaW5lZCBpbnN0cnVjdGlvbiIpOworCisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKSA8PCBDdXJyZW50SWR4IDw8ICI6IEdJUl9NZXJnZU1lbU9wZXJhbmRzKE91dE1Jc1siCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw8IEluc25JRCA8PCAiXSIpOworICAgICAgaW50NjRfdCBNZXJnZUluc25JRCA9IEdJVV9NZXJnZU1lbU9wZXJhbmRzX0VuZE9mTGlzdDsKKyAgICAgIHdoaWxlICgoTWVyZ2VJbnNuSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK10pICE9CisgICAgICAgICAgICAgR0lVX01lcmdlTWVtT3BlcmFuZHNfRW5kT2ZMaXN0KSB7CisgICAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgIiwgTUlzWyIgPDwgTWVyZ2VJbnNuSUQgPDwgIl0iKTsKKyAgICAgICAgZm9yIChjb25zdCBhdXRvICZNTU8gOiBTdGF0ZS5NSXNbTWVyZ2VJbnNuSURdLT5tZW1vcGVyYW5kcygpKQorICAgICAgICAgIE91dE1Jc1tJbnNuSURdLmFkZE1lbU9wZXJhbmQoTU1PKTsKKyAgICAgIH0KKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksIGRiZ3MoKSA8PCAiKVxuIik7CisgICAgICBicmVhazsKKyAgICB9CisKKyAgICBjYXNlIEdJUl9FcmFzZUZyb21QYXJlbnQ6IHsKKyAgICAgIGludDY0X3QgSW5zbklEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworICAgICAgYXNzZXJ0KFN0YXRlLk1Jc1tJbnNuSURdICYmCisgICAgICAgICAgICAgIkF0dGVtcHRlZCB0byBlcmFzZSBhbiB1bmRlZmluZWQgaW5zdHJ1Y3Rpb24iKTsKKyAgICAgIFN0YXRlLk1Jc1tJbnNuSURdLT5lcmFzZUZyb21QYXJlbnQoKTsKKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpIDw8IEN1cnJlbnRJZHggPDwgIjogR0lSX0VyYXNlRnJvbVBhcmVudChNSXNbIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCBJbnNuSUQgPDwgIl0pXG4iKTsKKyAgICAgIGJyZWFrOworICAgIH0KKworICAgIGNhc2UgR0lSX01ha2VUZW1wUmVnOiB7CisgICAgICBpbnQ2NF90IFRlbXBSZWdJRCA9IE1hdGNoVGFibGVbQ3VycmVudElkeCsrXTsKKyAgICAgIGludDY0X3QgVHlwZUlEID0gTWF0Y2hUYWJsZVtDdXJyZW50SWR4KytdOworCisgICAgICBTdGF0ZS5UZW1wUmVnaXN0ZXJzW1RlbXBSZWdJRF0gPQorICAgICAgICAgIE1SSS5jcmVhdGVHZW5lcmljVmlydHVhbFJlZ2lzdGVyKElTZWxJbmZvLlR5cGVPYmplY3RzW1R5cGVJRF0pOworICAgICAgREVCVUdfV0lUSF9UWVBFKFRndEluc3RydWN0aW9uU2VsZWN0b3I6OmdldE5hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICBkYmdzKCkgPDwgQ3VycmVudElkeCA8PCAiOiBUZW1wUmVnc1siIDw8IFRlbXBSZWdJRAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCAiXSA9IEdJUl9NYWtlVGVtcFJlZygiIDw8IFR5cGVJRCA8PCAiKVxuIik7CisgICAgICBicmVhazsKKyAgICB9CisKKyAgICBjYXNlIEdJUl9Db3ZlcmFnZTogeworICAgICAgaW50NjRfdCBSdWxlSUQgPSBNYXRjaFRhYmxlW0N1cnJlbnRJZHgrK107CisgICAgICBDb3ZlcmFnZUluZm8uc2V0Q292ZXJlZChSdWxlSUQpOworCisgICAgICBERUJVR19XSVRIX1RZUEUoVGd0SW5zdHJ1Y3Rpb25TZWxlY3Rvcjo6Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgIGRiZ3MoKQorICAgICAgICAgICAgICAgICAgICAgICAgICA8PCBDdXJyZW50SWR4IDw8ICI6IEdJUl9Db3ZlcmFnZSgiIDw8IFJ1bGVJRCA8PCAiKSIpOworICAgICAgYnJlYWs7CisgICAgfQorCisgICAgY2FzZSBHSVJfRG9uZToKKyAgICAgIERFQlVHX1dJVEhfVFlQRShUZ3RJbnN0cnVjdGlvblNlbGVjdG9yOjpnZXROYW1lKCksCisgICAgICAgICAgICAgICAgICAgICAgZGJncygpIDw8IEN1cnJlbnRJZHggPDwgIjogR0lSX0RvbmUiKTsKKyAgICAgIHJldHVybiB0cnVlOworCisgICAgZGVmYXVsdDoKKyAgICAgIGxsdm1fdW5yZWFjaGFibGUoIlVuZXhwZWN0ZWQgY29tbWFuZCIpOworICAgIH0KKyAgfQorfQorCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfSU5TVFJVQ1RJT05TRUxFQ1RPUklNUExfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTGVnYWxpemF0aW9uQXJ0aWZhY3RDb21iaW5lci5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTGVnYWxpemF0aW9uQXJ0aWZhY3RDb21iaW5lci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmExZjU2NGIKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9MZWdhbGl6YXRpb25BcnRpZmFjdENvbWJpbmVyLmgKQEAgLTAsMCArMSwyODcgQEAKKy8vPT09LS0gbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTGVnYWxpemF0aW9uQXJ0aWZhY3RDb21iaW5lci5oIC0tPT09PT09PT09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIHNvbWUgaGVscGVyIGZ1bmN0aW9ucyB3aGljaCB0cnkgdG8gY2xlYW51cCBhcnRpZmFjdHMKKy8vIHN1Y2ggYXMgR19UUlVOQ3MvR19bWlNBXUVYVEVORFMgdGhhdCB3ZXJlIGNyZWF0ZWQgZHVyaW5nIGxlZ2FsaXphdGlvbiB0byBtYWtlCisvLyB0aGUgdHlwZXMgbWF0Y2guIFRoaXMgZmlsZSBhbHNvIGNvbnRhaW5zIHNvbWUgY29tYmluZXMgb2YgbWVyZ2VzIHRoYXQgaGFwcGVucworLy8gYXQgdGhlIGVuZCBvZiB0aGUgbGVnYWxpemF0aW9uLgorLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0xlZ2FsaXplci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0xlZ2FsaXplckluZm8uaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9NYWNoaW5lSVJCdWlsZGVyLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvVXRpbHMuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZVJlZ2lzdGVySW5mby5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9EZWJ1Zy5oIgorCisjZGVmaW5lIERFQlVHX1RZUEUgImxlZ2FsaXplciIKKworbmFtZXNwYWNlIGxsdm0geworY2xhc3MgTGVnYWxpemF0aW9uQXJ0aWZhY3RDb21iaW5lciB7CisgIE1hY2hpbmVJUkJ1aWxkZXIgJkJ1aWxkZXI7CisgIE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSTsKKyAgY29uc3QgTGVnYWxpemVySW5mbyAmTEk7CisKK3B1YmxpYzoKKyAgTGVnYWxpemF0aW9uQXJ0aWZhY3RDb21iaW5lcihNYWNoaW5lSVJCdWlsZGVyICZCLCBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkksCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IExlZ2FsaXplckluZm8gJkxJKQorICAgICAgOiBCdWlsZGVyKEIpLCBNUkkoTVJJKSwgTEkoTEkpIHt9CisKKyAgYm9vbCB0cnlDb21iaW5lQW55RXh0KE1hY2hpbmVJbnN0ciAmTUksCisgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8TWFjaGluZUluc3RyICo+ICZEZWFkSW5zdHMpIHsKKyAgICBpZiAoTUkuZ2V0T3Bjb2RlKCkgIT0gVGFyZ2V0T3Bjb2RlOjpHX0FOWUVYVCkKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICBpZiAoTWFjaGluZUluc3RyICpEZWZNSSA9IGdldE9wY29kZURlZihUYXJnZXRPcGNvZGU6OkdfVFJVTkMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUkuZ2V0T3BlcmFuZCgxKS5nZXRSZWcoKSwgTVJJKSkgeworICAgICAgREVCVUcoZGJncygpIDw8ICIuLiBDb21iaW5lIE1JOiAiIDw8IE1JOyk7CisgICAgICB1bnNpZ25lZCBEc3RSZWcgPSBNSS5nZXRPcGVyYW5kKDApLmdldFJlZygpOworICAgICAgdW5zaWduZWQgU3JjUmVnID0gRGVmTUktPmdldE9wZXJhbmQoMSkuZ2V0UmVnKCk7CisgICAgICBCdWlsZGVyLnNldEluc3RyKE1JKTsKKyAgICAgIC8vIFdlIGdldCBhIGNvcHkvdHJ1bmMvZXh0ZW5kIGRlcGVuZGluZyBvbiB0aGUgc2l6ZXMKKyAgICAgIEJ1aWxkZXIuYnVpbGRBbnlFeHRPclRydW5jKERzdFJlZywgU3JjUmVnKTsKKyAgICAgIG1hcmtJbnN0QW5kRGVmRGVhZChNSSwgKkRlZk1JLCBEZWFkSW5zdHMpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiB0cnlGb2xkSW1wbGljaXREZWYoTUksIERlYWRJbnN0cyk7CisgIH0KKworICBib29sIHRyeUNvbWJpbmVaRXh0KE1hY2hpbmVJbnN0ciAmTUksCisgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVJbnN0ciAqPiAmRGVhZEluc3RzKSB7CisKKyAgICBpZiAoTUkuZ2V0T3Bjb2RlKCkgIT0gVGFyZ2V0T3Bjb2RlOjpHX1pFWFQpCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgaWYgKE1hY2hpbmVJbnN0ciAqRGVmTUkgPSBnZXRPcGNvZGVEZWYoVGFyZ2V0T3Bjb2RlOjpHX1RSVU5DLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1JLmdldE9wZXJhbmQoMSkuZ2V0UmVnKCksIE1SSSkpIHsKKyAgICAgIHVuc2lnbmVkIERzdFJlZyA9IE1JLmdldE9wZXJhbmQoMCkuZ2V0UmVnKCk7CisgICAgICBMTFQgRHN0VHkgPSBNUkkuZ2V0VHlwZShEc3RSZWcpOworICAgICAgaWYgKGlzSW5zdFVuc3VwcG9ydGVkKHtUYXJnZXRPcGNvZGU6OkdfQU5ELCB7RHN0VHl9fSkgfHwKKyAgICAgICAgICBpc0luc3RVbnN1cHBvcnRlZCh7VGFyZ2V0T3Bjb2RlOjpHX0NPTlNUQU5ULCB7RHN0VHl9fSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIERFQlVHKGRiZ3MoKSA8PCAiLi4gQ29tYmluZSBNSTogIiA8PCBNSTspOworICAgICAgQnVpbGRlci5zZXRJbnN0cihNSSk7CisgICAgICB1bnNpZ25lZCBaRXh0U3JjID0gTUkuZ2V0T3BlcmFuZCgxKS5nZXRSZWcoKTsKKyAgICAgIExMVCBaRXh0U3JjVHkgPSBNUkkuZ2V0VHlwZShaRXh0U3JjKTsKKyAgICAgIEFQSW50IE1hc2sgPSBBUEludDo6Z2V0QWxsT25lc1ZhbHVlKFpFeHRTcmNUeS5nZXRTaXplSW5CaXRzKCkpOworICAgICAgYXV0byBNYXNrQ3N0TUlCID0gQnVpbGRlci5idWlsZENvbnN0YW50KERzdFR5LCBNYXNrLmdldFpFeHRWYWx1ZSgpKTsKKyAgICAgIHVuc2lnbmVkIFRydW5jU3JjID0gRGVmTUktPmdldE9wZXJhbmQoMSkuZ2V0UmVnKCk7CisgICAgICAvLyBXZSBnZXQgYSBjb3B5L3RydW5jL2V4dGVuZCBkZXBlbmRpbmcgb24gdGhlIHNpemVzCisgICAgICBhdXRvIFNyY0NvcHlPclRydW5jID0gQnVpbGRlci5idWlsZEFueUV4dE9yVHJ1bmMoRHN0VHksIFRydW5jU3JjKTsKKyAgICAgIEJ1aWxkZXIuYnVpbGRBbmQoRHN0UmVnLCBTcmNDb3B5T3JUcnVuYywgTWFza0NzdE1JQik7CisgICAgICBtYXJrSW5zdEFuZERlZkRlYWQoTUksICpEZWZNSSwgRGVhZEluc3RzKTsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICByZXR1cm4gdHJ5Rm9sZEltcGxpY2l0RGVmKE1JLCBEZWFkSW5zdHMpOworICB9CisKKyAgYm9vbCB0cnlDb21iaW5lU0V4dChNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxNYWNoaW5lSW5zdHIgKj4gJkRlYWRJbnN0cykgeworCisgICAgaWYgKE1JLmdldE9wY29kZSgpICE9IFRhcmdldE9wY29kZTo6R19TRVhUKQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIGlmIChNYWNoaW5lSW5zdHIgKkRlZk1JID0gZ2V0T3Bjb2RlRGVmKFRhcmdldE9wY29kZTo6R19UUlVOQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNSS5nZXRPcGVyYW5kKDEpLmdldFJlZygpLCBNUkkpKSB7CisgICAgICB1bnNpZ25lZCBEc3RSZWcgPSBNSS5nZXRPcGVyYW5kKDApLmdldFJlZygpOworICAgICAgTExUIERzdFR5ID0gTVJJLmdldFR5cGUoRHN0UmVnKTsKKyAgICAgIGlmIChpc0luc3RVbnN1cHBvcnRlZCh7VGFyZ2V0T3Bjb2RlOjpHX1NITCwge0RzdFR5fX0pIHx8CisgICAgICAgICAgaXNJbnN0VW5zdXBwb3J0ZWQoe1RhcmdldE9wY29kZTo6R19BU0hSLCB7RHN0VHl9fSkgfHwKKyAgICAgICAgICBpc0luc3RVbnN1cHBvcnRlZCh7VGFyZ2V0T3Bjb2RlOjpHX0NPTlNUQU5ULCB7RHN0VHl9fSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIERFQlVHKGRiZ3MoKSA8PCAiLi4gQ29tYmluZSBNSTogIiA8PCBNSTspOworICAgICAgQnVpbGRlci5zZXRJbnN0cihNSSk7CisgICAgICB1bnNpZ25lZCBTRXh0U3JjID0gTUkuZ2V0T3BlcmFuZCgxKS5nZXRSZWcoKTsKKyAgICAgIExMVCBTRXh0U3JjVHkgPSBNUkkuZ2V0VHlwZShTRXh0U3JjKTsKKyAgICAgIHVuc2lnbmVkIFNpemVEaWZmID0gRHN0VHkuZ2V0U2l6ZUluQml0cygpIC0gU0V4dFNyY1R5LmdldFNpemVJbkJpdHMoKTsKKyAgICAgIGF1dG8gU2l6ZURpZmZNSUIgPSBCdWlsZGVyLmJ1aWxkQ29uc3RhbnQoRHN0VHksIFNpemVEaWZmKTsKKyAgICAgIHVuc2lnbmVkIFRydW5jU3JjUmVnID0gRGVmTUktPmdldE9wZXJhbmQoMSkuZ2V0UmVnKCk7CisgICAgICAvLyBXZSBnZXQgYSBjb3B5L3RydW5jL2V4dGVuZCBkZXBlbmRpbmcgb24gdGhlIHNpemVzCisgICAgICBhdXRvIFNyY0NvcHlFeHRPclRydW5jID0gQnVpbGRlci5idWlsZEFueUV4dE9yVHJ1bmMoRHN0VHksIFRydW5jU3JjUmVnKTsKKyAgICAgIGF1dG8gU2hsTUlCID0gQnVpbGRlci5idWlsZEluc3RyKFRhcmdldE9wY29kZTo6R19TSEwsIERzdFR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3JjQ29weUV4dE9yVHJ1bmMsIFNpemVEaWZmTUlCKTsKKyAgICAgIEJ1aWxkZXIuYnVpbGRJbnN0cihUYXJnZXRPcGNvZGU6OkdfQVNIUiwgRHN0UmVnLCBTaGxNSUIsIFNpemVEaWZmTUlCKTsKKyAgICAgIG1hcmtJbnN0QW5kRGVmRGVhZChNSSwgKkRlZk1JLCBEZWFkSW5zdHMpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiB0cnlGb2xkSW1wbGljaXREZWYoTUksIERlYWRJbnN0cyk7CisgIH0KKworICAvLy8gVHJ5IHRvIGZvbGQgc2IgPSBFWFRFTkQgKEdfSU1QTElDSVRfREVGIHNhKSAtPiBzYiA9IEdfSU1QTElDSVRfREVGCisgIGJvb2wgdHJ5Rm9sZEltcGxpY2l0RGVmKE1hY2hpbmVJbnN0ciAmTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxNYWNoaW5lSW5zdHIgKj4gJkRlYWRJbnN0cykgeworICAgIHVuc2lnbmVkIE9wY29kZSA9IE1JLmdldE9wY29kZSgpOworICAgIGlmIChPcGNvZGUgIT0gVGFyZ2V0T3Bjb2RlOjpHX0FOWUVYVCAmJiBPcGNvZGUgIT0gVGFyZ2V0T3Bjb2RlOjpHX1pFWFQgJiYKKyAgICAgICAgT3Bjb2RlICE9IFRhcmdldE9wY29kZTo6R19TRVhUKQorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgaWYgKE1hY2hpbmVJbnN0ciAqRGVmTUkgPSBnZXRPcGNvZGVEZWYoVGFyZ2V0T3Bjb2RlOjpHX0lNUExJQ0lUX0RFRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNSS5nZXRPcGVyYW5kKDEpLmdldFJlZygpLCBNUkkpKSB7CisgICAgICB1bnNpZ25lZCBEc3RSZWcgPSBNSS5nZXRPcGVyYW5kKDApLmdldFJlZygpOworICAgICAgTExUIERzdFR5ID0gTVJJLmdldFR5cGUoRHN0UmVnKTsKKyAgICAgIGlmIChpc0luc3RVbnN1cHBvcnRlZCh7VGFyZ2V0T3Bjb2RlOjpHX0lNUExJQ0lUX0RFRiwge0RzdFR5fX0pKQorICAgICAgICByZXR1cm4gZmFsc2U7CisgICAgICBERUJVRyhkYmdzKCkgPDwgIi4uIENvbWJpbmUgRVhUKElNUExJQ0lUX0RFRikgIiA8PCBNSTspOworICAgICAgQnVpbGRlci5zZXRJbnN0cihNSSk7CisgICAgICBCdWlsZGVyLmJ1aWxkSW5zdHIoVGFyZ2V0T3Bjb2RlOjpHX0lNUExJQ0lUX0RFRiwgRHN0UmVnKTsKKyAgICAgIG1hcmtJbnN0QW5kRGVmRGVhZChNSSwgKkRlZk1JLCBEZWFkSW5zdHMpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIGJvb2wgdHJ5Q29tYmluZU1lcmdlcyhNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVJbnN0ciAqPiAmRGVhZEluc3RzKSB7CisKKyAgICBpZiAoTUkuZ2V0T3Bjb2RlKCkgIT0gVGFyZ2V0T3Bjb2RlOjpHX1VOTUVSR0VfVkFMVUVTKQorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgdW5zaWduZWQgTnVtRGVmcyA9IE1JLmdldE51bU9wZXJhbmRzKCkgLSAxOworICAgIHVuc2lnbmVkIFNyY1JlZyA9IE1JLmdldE9wZXJhbmQoTnVtRGVmcykuZ2V0UmVnKCk7CisgICAgTWFjaGluZUluc3RyICpNZXJnZUkgPSBNUkkuZ2V0VlJlZ0RlZihTcmNSZWcpOworICAgIGlmICghTWVyZ2VJIHx8IChNZXJnZUktPmdldE9wY29kZSgpICE9IFRhcmdldE9wY29kZTo6R19NRVJHRV9WQUxVRVMpKQorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgY29uc3QgdW5zaWduZWQgTnVtTWVyZ2VSZWdzID0gTWVyZ2VJLT5nZXROdW1PcGVyYW5kcygpIC0gMTsKKworICAgIGlmIChOdW1NZXJnZVJlZ3MgPCBOdW1EZWZzKSB7CisgICAgICBpZiAoTnVtRGVmcyAlIE51bU1lcmdlUmVncyAhPSAwKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAgIEJ1aWxkZXIuc2V0SW5zdHIoTUkpOworICAgICAgLy8gVHJhbnNmb3JtIHRvIFVOTUVSR0VzLCBmb3IgZXhhbXBsZQorICAgICAgLy8gICAlMSA9IEdfTUVSR0VfVkFMVUVTICU0LCAlNQorICAgICAgLy8gICAlOSwgJTEwLCAlMTEsICUxMiA9IEdfVU5NRVJHRV9WQUxVRVMgJTEKKyAgICAgIC8vIHRvCisgICAgICAvLyAgICU5LCAlMTAgPSBHX1VOTUVSR0VfVkFMVUVTICU0CisgICAgICAvLyAgICUxMSwgJTEyID0gR19VTk1FUkdFX1ZBTFVFUyAlNQorCisgICAgICBjb25zdCB1bnNpZ25lZCBOZXdOdW1EZWZzID0gTnVtRGVmcyAvIE51bU1lcmdlUmVnczsKKyAgICAgIGZvciAodW5zaWduZWQgSWR4ID0gMDsgSWR4IDwgTnVtTWVyZ2VSZWdzOyArK0lkeCkgeworICAgICAgICBTbWFsbFZlY3Rvcjx1bnNpZ25lZCwgMj4gRHN0UmVnczsKKyAgICAgICAgZm9yICh1bnNpZ25lZCBqID0gMCwgRGVmSWR4ID0gSWR4ICogTmV3TnVtRGVmczsgaiA8IE5ld051bURlZnM7CisgICAgICAgICAgICAgKytqLCArK0RlZklkeCkKKyAgICAgICAgICBEc3RSZWdzLnB1c2hfYmFjayhNSS5nZXRPcGVyYW5kKERlZklkeCkuZ2V0UmVnKCkpOworCisgICAgICAgIEJ1aWxkZXIuYnVpbGRVbm1lcmdlKERzdFJlZ3MsIE1lcmdlSS0+Z2V0T3BlcmFuZChJZHggKyAxKS5nZXRSZWcoKSk7CisgICAgICB9CisKKyAgICB9IGVsc2UgaWYgKE51bU1lcmdlUmVncyA+IE51bURlZnMpIHsKKyAgICAgIGlmIChOdW1NZXJnZVJlZ3MgJSBOdW1EZWZzICE9IDApCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgQnVpbGRlci5zZXRJbnN0cihNSSk7CisgICAgICAvLyBUcmFuc2Zvcm0gdG8gTUVSR0VzCisgICAgICAvLyAgICU2ID0gR19NRVJHRV9WQUxVRVMgJTE3LCAlMTgsICUxOSwgJTIwCisgICAgICAvLyAgICU3LCAlOCA9IEdfVU5NRVJHRV9WQUxVRVMgJTYKKyAgICAgIC8vIHRvCisgICAgICAvLyAgICU3ID0gR19NRVJHRV9WQUxVRVMgJTE3LCAlMTgKKyAgICAgIC8vICAgJTggPSBHX01FUkdFX1ZBTFVFUyAlMTksICUyMAorCisgICAgICBjb25zdCB1bnNpZ25lZCBOdW1SZWdzID0gTnVtTWVyZ2VSZWdzIC8gTnVtRGVmczsKKyAgICAgIGZvciAodW5zaWduZWQgRGVmSWR4ID0gMDsgRGVmSWR4IDwgTnVtRGVmczsgKytEZWZJZHgpIHsKKyAgICAgICAgU21hbGxWZWN0b3I8dW5zaWduZWQsIDI+IFJlZ3M7CisgICAgICAgIGZvciAodW5zaWduZWQgaiA9IDAsIElkeCA9IE51bVJlZ3MgKiBEZWZJZHggKyAxOyBqIDwgTnVtUmVnczsKKyAgICAgICAgICAgICArK2osICsrSWR4KQorICAgICAgICAgIFJlZ3MucHVzaF9iYWNrKE1lcmdlSS0+Z2V0T3BlcmFuZChJZHgpLmdldFJlZygpKTsKKworICAgICAgICBCdWlsZGVyLmJ1aWxkTWVyZ2UoTUkuZ2V0T3BlcmFuZChEZWZJZHgpLmdldFJlZygpLCBSZWdzKTsKKyAgICAgIH0KKworICAgIH0gZWxzZSB7CisgICAgICAvLyBGSVhNRTogaXMgYSBDT1BZIGFwcHJvcHJpYXRlIGlmIHRoZSB0eXBlcyBtaXNtYXRjaD8gV2Uga25vdyBib3RoCisgICAgICAvLyByZWdpc3RlcnMgYXJlIGFsbG9jYXRhYmxlIGJ5IG5vdy4KKyAgICAgIGlmIChNUkkuZ2V0VHlwZShNSS5nZXRPcGVyYW5kKDApLmdldFJlZygpKSAhPQorICAgICAgICAgIE1SSS5nZXRUeXBlKE1lcmdlSS0+Z2V0T3BlcmFuZCgxKS5nZXRSZWcoKSkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKworICAgICAgZm9yICh1bnNpZ25lZCBJZHggPSAwOyBJZHggPCBOdW1EZWZzOyArK0lkeCkKKyAgICAgICAgTVJJLnJlcGxhY2VSZWdXaXRoKE1JLmdldE9wZXJhbmQoSWR4KS5nZXRSZWcoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lcmdlSS0+Z2V0T3BlcmFuZChJZHggKyAxKS5nZXRSZWcoKSk7CisgICAgfQorCisgICAgbWFya0luc3RBbmREZWZEZWFkKE1JLCAqTWVyZ2VJLCBEZWFkSW5zdHMpOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8vIFRyeSB0byBjb21iaW5lIGF3YXkgTUkuCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgaXQgY29tYmluZWQgYXdheSB0aGUgTUkuCisgIC8vLyBBZGRzIGluc3RydWN0aW9ucyB0aGF0IGFyZSBkZWFkIGFzIGEgcmVzdWx0IG9mIHRoZSBjb21iaW5lCisgIC8vLyBpbnRvIERlYWRJbnN0cywgd2hpY2ggY2FuIGluY2x1ZGUgTUkuCisgIGJvb2wgdHJ5Q29tYmluZUluc3RydWN0aW9uKE1hY2hpbmVJbnN0ciAmTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxNYWNoaW5lSW5zdHIgKj4gJkRlYWRJbnN0cykgeworICAgIHN3aXRjaCAoTUkuZ2V0T3Bjb2RlKCkpIHsKKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuIGZhbHNlOworICAgIGNhc2UgVGFyZ2V0T3Bjb2RlOjpHX0FOWUVYVDoKKyAgICAgIHJldHVybiB0cnlDb21iaW5lQW55RXh0KE1JLCBEZWFkSW5zdHMpOworICAgIGNhc2UgVGFyZ2V0T3Bjb2RlOjpHX1pFWFQ6CisgICAgICByZXR1cm4gdHJ5Q29tYmluZVpFeHQoTUksIERlYWRJbnN0cyk7CisgICAgY2FzZSBUYXJnZXRPcGNvZGU6OkdfU0VYVDoKKyAgICAgIHJldHVybiB0cnlDb21iaW5lU0V4dChNSSwgRGVhZEluc3RzKTsKKyAgICBjYXNlIFRhcmdldE9wY29kZTo6R19VTk1FUkdFX1ZBTFVFUzoKKyAgICAgIHJldHVybiB0cnlDb21iaW5lTWVyZ2VzKE1JLCBEZWFkSW5zdHMpOworICAgIGNhc2UgVGFyZ2V0T3Bjb2RlOjpHX1RSVU5DOiB7CisgICAgICBib29sIENoYW5nZWQgPSBmYWxzZTsKKyAgICAgIGZvciAoYXV0byAmVXNlIDogTVJJLnVzZV9pbnN0cnVjdGlvbnMoTUkuZ2V0T3BlcmFuZCgwKS5nZXRSZWcoKSkpCisgICAgICAgIENoYW5nZWQgfD0gdHJ5Q29tYmluZUluc3RydWN0aW9uKFVzZSwgRGVhZEluc3RzKTsKKyAgICAgIHJldHVybiBDaGFuZ2VkOworICAgIH0KKyAgICB9CisgIH0KKworcHJpdmF0ZToKKyAgLy8vIE1hcmsgTUkgYXMgZGVhZC4gSWYgYSBkZWYgb2Ygb25lIG9mIE1JJ3Mgb3BlcmFuZHMsIERlZk1JLCB3b3VsZCBhbHNvIGJlCisgIC8vLyBkZWFkIGR1ZSB0byBNSSBiZWluZyBraWxsZWQsIHRoZW4gbWFyayBEZWZNSSBhcyBkZWFkIHRvby4KKyAgLy8vIFNvbWUgb2YgdGhlIGNvbWJpbmVzIChleHRlbmRzKHRydW5jKSksIHRyeSB0byB3YWxrIHRocm91Z2ggcmVkdW5kYW50CisgIC8vLyBjb3BpZXMgaW4gYmV0d2VlbiB0aGUgZXh0ZW5kcyBhbmQgdGhlIHRydW5jcywgYW5kIHRoaXMgYXR0ZW1wdHMgdG8gY29sbGVjdAorICAvLy8gdGhlIGluIGJldHdlZW4gY29waWVzIGlmIHRoZXkncmUgZGVhZC4KKyAgdm9pZCBtYXJrSW5zdEFuZERlZkRlYWQoTWFjaGluZUluc3RyICZNSSwgTWFjaGluZUluc3RyICZEZWZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVJbnN0ciAqPiAmRGVhZEluc3RzKSB7CisgICAgRGVhZEluc3RzLnB1c2hfYmFjaygmTUkpOworCisgICAgLy8gQ29sbGVjdCBhbGwgdGhlIGNvcHkgaW5zdHJ1Y3Rpb25zIHRoYXQgYXJlIG1hZGUgZGVhZCwgZHVlIHRvIGRlbGV0aW5nCisgICAgLy8gdGhpcyBpbnN0cnVjdGlvbi4gQ29sbGVjdCBhbGwgb2YgdGhlbSB1bnRpbCB0aGUgVHJ1bmMoRGVmTUkpLgorICAgIC8vIEVnLAorICAgIC8vICUxKHMxKSA9IEdfVFJVTkMgJTAoczMyKQorICAgIC8vICUyKHMxKSA9IENPUFkgJTEoczEpCisgICAgLy8gJTMoczEpID0gQ09QWSAlMihzMSkKKyAgICAvLyAlNChzMzIpID0gR19BTllFWFQgJTMoczEpCisgICAgLy8gSW4gdGhpcyBjYXNlLCB3ZSB3b3VsZCBoYXZlIHJlcGxhY2VkICU0IHdpdGggYSBjb3B5IG9mICUwLAorICAgIC8vIGFuZCBhcyBhIHJlc3VsdCwgJTMsICUyLCAlMSBhcmUgZGVhZC4KKyAgICBNYWNoaW5lSW5zdHIgKlByZXZNSSA9ICZNSTsKKyAgICB3aGlsZSAoUHJldk1JICE9ICZEZWZNSSkgeworICAgICAgLy8gSWYgd2UncmUgZGVhbGluZyB3aXRoIEdfVU5NRVJHRV9WQUxVRVMsIHRyeUNvbWJpbmVNZXJnZXMgZG9lc24ndCByZWFsbHkgdHJ5CisgICAgICAvLyB0byBmb2xkIGNvcGllcyBpbiBiZXR3ZWVuIGFuZCB3ZSBjYW4gaWdub3JlIHRoZW0gaGVyZS4KKyAgICAgIGlmIChQcmV2TUktPmdldE9wY29kZSgpID09IFRhcmdldE9wY29kZTo6R19VTk1FUkdFX1ZBTFVFUykKKyAgICAgICAgYnJlYWs7CisgICAgICB1bnNpZ25lZCBQcmV2UmVnU3JjID0gUHJldk1JLT5nZXRPcGVyYW5kKDEpLmdldFJlZygpOworICAgICAgTWFjaGluZUluc3RyICpUbXBEZWYgPSBNUkkuZ2V0VlJlZ0RlZihQcmV2UmVnU3JjKTsKKyAgICAgIGlmIChNUkkuaGFzT25lVXNlKFByZXZSZWdTcmMpKSB7CisgICAgICAgIGlmIChUbXBEZWYgIT0gJkRlZk1JKSB7CisgICAgICAgICAgYXNzZXJ0KFRtcERlZi0+Z2V0T3Bjb2RlKCkgPT0gVGFyZ2V0T3Bjb2RlOjpDT1BZICYmCisgICAgICAgICAgICAgICAgICJFeHBlY3RpbmcgY29weSBoZXJlIik7CisgICAgICAgICAgRGVhZEluc3RzLnB1c2hfYmFjayhUbXBEZWYpOworICAgICAgICB9CisgICAgICB9IGVsc2UKKyAgICAgICAgYnJlYWs7CisgICAgICBQcmV2TUkgPSBUbXBEZWY7CisgICAgfQorICAgIGlmICgoUHJldk1JID09ICZEZWZNSSB8fAorICAgICAgICAgRGVmTUkuZ2V0T3Bjb2RlKCkgPT0gVGFyZ2V0T3Bjb2RlOjpHX01FUkdFX1ZBTFVFUykgJiYKKyAgICAgICAgTVJJLmhhc09uZVVzZShEZWZNSS5nZXRPcGVyYW5kKDApLmdldFJlZygpKSkKKyAgICAgIERlYWRJbnN0cy5wdXNoX2JhY2soJkRlZk1JKTsKKyAgfQorCisgIC8vLyBDaGVja3MgaWYgdGhlIHRhcmdldCBsZWdhbGl6ZXIgaW5mbyBoYXMgc3BlY2lmaWVkIGFueXRoaW5nIGFib3V0IHRoZQorICAvLy8gaW5zdHJ1Y3Rpb24sIG9yIGlmIHVuc3VwcG9ydGVkLgorICBib29sIGlzSW5zdFVuc3VwcG9ydGVkKGNvbnN0IExlZ2FsaXR5UXVlcnkgJlF1ZXJ5KSBjb25zdCB7CisgICAgdXNpbmcgbmFtZXNwYWNlIExlZ2FsaXplQWN0aW9uczsKKyAgICBhdXRvIFN0ZXAgPSBMSS5nZXRBY3Rpb24oUXVlcnkpOworICAgIHJldHVybiBTdGVwLkFjdGlvbiA9PSBVbnN1cHBvcnRlZCB8fCBTdGVwLkFjdGlvbiA9PSBOb3RGb3VuZDsKKyAgfQorfTsKKworfSAvLyBuYW1lc3BhY2UgbGx2bQpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTGVnYWxpemVyLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9MZWdhbGl6ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44Mjg0YWI2Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTGVnYWxpemVyLmgKQEAgLTAsMCArMSw2NSBAQAorLy89PSBsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9MZWdhbGl6ZVBhc3MuaCAtLS0tLS0tLS0tLS0tIC0qLSBDKysgLSotPT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vLyBcZmlsZSBBIHBhc3MgdG8gY29udmVydCB0aGUgdGFyZ2V0LWlsbGVnYWwgb3BlcmF0aW9ucyBjcmVhdGVkIGJ5IElSIC0+IE1JUgorLy8vIHRyYW5zbGF0aW9uIGludG8gb25lcyB0aGUgdGFyZ2V0IGV4cGVjdHMgdG8gYmUgYWJsZSB0byBzZWxlY3QuIFRoaXMgbWF5CisvLy8gb2NjdXIgaW4gbXVsdGlwbGUgcGhhc2VzLCBmb3IgZXhhbXBsZSBHX0FERCA8MiB4IGk4PiAtPiBHX0FERCA8MiB4IGkxNj4gLT4KKy8vLyBHX0FERCA8NCB4IGkxNj4uCisvLy8KKy8vLyBUaGUgTGVnYWxpemVIZWxwZXIgY2xhc3MgaXMgd2hlcmUgbW9zdCBvZiB0aGUgd29yayBoYXBwZW5zLCBhbmQgaXMgZGVzaWduZWQKKy8vLyB0byBiZSBjYWxsYWJsZSBmcm9tIG90aGVyIHBhc3NlcyB0aGF0IGZpbmQgdGhlbXNlbHZlcyB3aXRoIGFuIGlsbGVnYWwKKy8vLyBpbnN0cnVjdGlvbi4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX0xFR0FMSVpFTUFDSElORUlSUEFTU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX0xFR0FMSVpFTUFDSElORUlSUEFTU19ICisKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9NYWNoaW5lSVJCdWlsZGVyLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvblBhc3MuaCIKKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworCitjbGFzcyBMZWdhbGl6ZXIgOiBwdWJsaWMgTWFjaGluZUZ1bmN0aW9uUGFzcyB7CitwdWJsaWM6CisgIHN0YXRpYyBjaGFyIElEOworCitwcml2YXRlOgorCisgIC8vLyBJbml0aWFsaXplIHRoZSBmaWVsZCBtZW1iZXJzIHVzaW5nIFxwIE1GLgorICB2b2lkIGluaXQoTWFjaGluZUZ1bmN0aW9uICZNRik7CisKK3B1YmxpYzoKKyAgLy8gQ3Rvciwgbm90aGluZyBmYW5jeS4KKyAgTGVnYWxpemVyKCk7CisKKyAgU3RyaW5nUmVmIGdldFBhc3NOYW1lKCkgY29uc3Qgb3ZlcnJpZGUgeyByZXR1cm4gIkxlZ2FsaXplciI7IH0KKworICB2b2lkIGdldEFuYWx5c2lzVXNhZ2UoQW5hbHlzaXNVc2FnZSAmQVUpIGNvbnN0IG92ZXJyaWRlOworCisgIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMgZ2V0UmVxdWlyZWRQcm9wZXJ0aWVzKCkgY29uc3Qgb3ZlcnJpZGUgeworICAgIHJldHVybiBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzKCkuc2V0KAorICAgICAgICBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzOjpQcm9wZXJ0eTo6SXNTU0EpOworICB9CisKKyAgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcyBnZXRTZXRQcm9wZXJ0aWVzKCkgY29uc3Qgb3ZlcnJpZGUgeworICAgIHJldHVybiBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzKCkuc2V0KAorICAgICAgICBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzOjpQcm9wZXJ0eTo6TGVnYWxpemVkKTsKKyAgfQorCisgIGJvb2wgY29tYmluZUV4dHJhY3RzKE1hY2hpbmVJbnN0ciAmTUksIE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSwKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICZUSUkpOworCisgIGJvb2wgcnVuT25NYWNoaW5lRnVuY3Rpb24oTWFjaGluZUZ1bmN0aW9uICZNRikgb3ZlcnJpZGU7Cit9OworfSAvLyBFbmQgbmFtZXNwYWNlIGxsdm0uCisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTGVnYWxpemVySGVscGVyLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9MZWdhbGl6ZXJIZWxwZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YmQ4YTlkCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTGVnYWxpemVySGVscGVyLmgKQEAgLTAsMCArMSwxMTUgQEAKKy8vPT0gbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTGVnYWxpemVySGVscGVyLmggLS0tLS0tLS0tLS0tLS0tLSAtKi0gQysrIC0qLT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLy8gXGZpbGUgQSBwYXNzIHRvIGNvbnZlcnQgdGhlIHRhcmdldC1pbGxlZ2FsIG9wZXJhdGlvbnMgY3JlYXRlZCBieSBJUiAtPiBNSVIKKy8vLyB0cmFuc2xhdGlvbiBpbnRvIG9uZXMgdGhlIHRhcmdldCBleHBlY3RzIHRvIGJlIGFibGUgdG8gc2VsZWN0LiBUaGlzIG1heQorLy8vIG9jY3VyIGluIG11bHRpcGxlIHBoYXNlcywgZm9yIGV4YW1wbGUgR19BREQgPDIgeCBpOD4gLT4gR19BREQgPDIgeCBpMTY+IC0+CisvLy8gR19BREQgPDQgeCBpMTY+LgorLy8vCisvLy8gVGhlIExlZ2FsaXplckhlbHBlciBjbGFzcyBpcyB3aGVyZSBtb3N0IG9mIHRoZSB3b3JrIGhhcHBlbnMsIGFuZCBpcworLy8vIGRlc2lnbmVkIHRvIGJlIGNhbGxhYmxlIGZyb20gb3RoZXIgcGFzc2VzIHRoYXQgZmluZCB0aGVtc2VsdmVzIHdpdGggYW4KKy8vLyBpbGxlZ2FsIGluc3RydWN0aW9uLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfTUFDSElORUxFR0FMSVpFSEVMUEVSX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfTUFDSElORUxFR0FMSVpFSEVMUEVSX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0NhbGxMb3dlcmluZy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL01hY2hpbmVJUkJ1aWxkZXIuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTG93TGV2ZWxUeXBlLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvblBhc3MuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vUnVudGltZUxpYmNhbGxzLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKy8vIEZvcndhcmQgZGVjbGFyYXRpb25zLgorY2xhc3MgTGVnYWxpemVySW5mbzsKK2NsYXNzIExlZ2FsaXplcjsKK2NsYXNzIE1hY2hpbmVSZWdpc3RlckluZm87CisKK2NsYXNzIExlZ2FsaXplckhlbHBlciB7CitwdWJsaWM6CisgIGVudW0gTGVnYWxpemVSZXN1bHQgeworICAgIC8vLyBJbnN0cnVjdGlvbiB3YXMgYWxyZWFkeSBsZWdhbCBhbmQgbm8gY2hhbmdlIHdhcyBtYWRlIHRvIHRoZQorICAgIC8vLyBNYWNoaW5lRnVuY3Rpb24uCisgICAgQWxyZWFkeUxlZ2FsLAorCisgICAgLy8vIEluc3RydWN0aW9uIGhhcyBiZWVuIGxlZ2FsaXplZCBhbmQgdGhlIE1hY2hpbmVGdW5jdGlvbiBjaGFuZ2VkLgorICAgIExlZ2FsaXplZCwKKworICAgIC8vLyBTb21lIGtpbmQgb2YgZXJyb3IgaGFzIG9jY3VycmVkIGFuZCB3ZSBjb3VsZCBub3QgbGVnYWxpemUgdGhpcworICAgIC8vLyBpbnN0cnVjdGlvbi4KKyAgICBVbmFibGVUb0xlZ2FsaXplLAorICB9OworCisgIExlZ2FsaXplckhlbHBlcihNYWNoaW5lRnVuY3Rpb24gJk1GKTsKKworICAvLy8gUmVwbGFjZSBccCBNSSBieSBhIHNlcXVlbmNlIG9mIGxlZ2FsIGluc3RydWN0aW9ucyB0aGF0IGNhbiBpbXBsZW1lbnQgdGhlCisgIC8vLyBzYW1lIG9wZXJhdGlvbi4gTm90ZSB0aGF0IHRoaXMgbWVhbnMgXHAgTUkgbWF5IGJlIGRlbGV0ZWQsIHNvIGFueSBpdGVyYXRvcgorICAvLy8gc3RlcHMgc2hvdWxkIGJlIHBlcmZvcm1lZCBiZWZvcmUgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLiBccCBIZWxwZXIgc2hvdWxkCisgIC8vLyBiZSBpbml0aWFsaXplZCB0byB0aGUgTWFjaGluZUZ1bmN0aW9uIGNvbnRhaW5pbmcgXHAgTUkuCisgIC8vLworICAvLy8gQ29uc2lkZXJlZCBhcyBhbiBvcGFxdWUgYmxvYiwgdGhlIGxlZ2FsIGNvZGUgd2lsbCB1c2UgYW5kIGRlZmluZSB0aGUgc2FtZQorICAvLy8gcmVnaXN0ZXJzIGFzIFxwIE1JLgorICBMZWdhbGl6ZVJlc3VsdCBsZWdhbGl6ZUluc3RyU3RlcChNYWNoaW5lSW5zdHIgJk1JKTsKKworICAvLy8gTGVnYWxpemUgYW4gaW5zdHJ1Y3Rpb24gYnkgZW1pdGluZyBhIHJ1bnRpbWUgbGlicmFyeSBjYWxsIGluc3RlYWQuCisgIExlZ2FsaXplUmVzdWx0IGxpYmNhbGwoTWFjaGluZUluc3RyICZNSSk7CisKKyAgLy8vIExlZ2FsaXplIGFuIGluc3RydWN0aW9uIGJ5IHJlZHVjaW5nIHRoZSB3aWR0aCBvZiB0aGUgdW5kZXJseWluZyBzY2FsYXIKKyAgLy8vIHR5cGUuCisgIExlZ2FsaXplUmVzdWx0IG5hcnJvd1NjYWxhcihNYWNoaW5lSW5zdHIgJk1JLCB1bnNpZ25lZCBUeXBlSWR4LCBMTFQgTmFycm93VHkpOworCisgIC8vLyBMZWdhbGl6ZSBhbiBpbnN0cnVjdGlvbiBieSBwZXJmb3JtaW5nIHRoZSBvcGVyYXRpb24gb24gYSB3aWRlciBzY2FsYXIgdHlwZQorICAvLy8gKGZvciBleGFtcGxlIGEgMTYtYml0IGFkZGl0aW9uIGNhbiBiZSBzYWZlbHkgcGVyZm9ybWVkIGF0IDMyLWJpdHMKKyAgLy8vIHByZWNpc2lvbiwgaWdub3JpbmcgdGhlIHVudXNlZCBiaXRzKS4KKyAgTGVnYWxpemVSZXN1bHQgd2lkZW5TY2FsYXIoTWFjaGluZUluc3RyICZNSSwgdW5zaWduZWQgVHlwZUlkeCwgTExUIFdpZGVUeSk7CisKKyAgLy8vIExlZ2FsaXplIGFuIGluc3RydWN0aW9uIGJ5IHNwbGl0dGluZyBpdCBpbnRvIHNpbXBsZXIgcGFydHMsIGhvcGVmdWxseQorICAvLy8gdW5kZXJzdG9vZCBieSB0aGUgdGFyZ2V0LgorICBMZWdhbGl6ZVJlc3VsdCBsb3dlcihNYWNoaW5lSW5zdHIgJk1JLCB1bnNpZ25lZCBUeXBlSWR4LCBMTFQgVHkpOworCisgIC8vLyBMZWdhbGl6ZSBhIHZlY3RvciBpbnN0cnVjdGlvbiBieSBzcGxpdHRpbmcgaW50byBtdWx0aXBsZSBjb21wb25lbnRzLCBlYWNoCisgIC8vLyBhY3Rpbmcgb24gdGhlIHNhbWUgc2NhbGFyIHR5cGUgYXMgdGhlIG9yaWdpbmFsIGJ1dCB3aXRoIGZld2VyIGVsZW1lbnRzLgorICBMZWdhbGl6ZVJlc3VsdCBmZXdlckVsZW1lbnRzVmVjdG9yKE1hY2hpbmVJbnN0ciAmTUksIHVuc2lnbmVkIFR5cGVJZHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTExUIE5hcnJvd1R5KTsKKworICAvLy8gTGVnYWxpemUgYSB2ZWN0b3IgaW5zdHJ1Y3Rpb24gYnkgaW5jcmVhc2luZyB0aGUgbnVtYmVyIG9mIHZlY3RvciBlbGVtZW50cworICAvLy8gaW52b2x2ZWQgYW5kIGlnbm9yaW5nIHRoZSBhZGRlZCBlbGVtZW50cyBsYXRlci4KKyAgTGVnYWxpemVSZXN1bHQgbW9yZUVsZW1lbnRzVmVjdG9yKE1hY2hpbmVJbnN0ciAmTUksIHVuc2lnbmVkIFR5cGVJZHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMTFQgV2lkZVR5KTsKKworICAvLy8gRXhwb3NlIE1JUkJ1aWxkZXIgc28gY2xpZW50cyBjYW4gc2V0IHRoZWlyIG93biBSZWNvcmRJbnNlcnRJbnN0cnVjdGlvbgorICAvLy8gZnVuY3Rpb25zCisgIE1hY2hpbmVJUkJ1aWxkZXIgTUlSQnVpbGRlcjsKKworICAvLy8gRXhwb3NlIExlZ2FsaXplckluZm8gc28gdGhlIGNsaWVudHMgY2FuIHJlLXVzZS4KKyAgY29uc3QgTGVnYWxpemVySW5mbyAmZ2V0TGVnYWxpemVySW5mbygpIGNvbnN0IHsgcmV0dXJuIExJOyB9CisKK3ByaXZhdGU6CisKKyAgLy8vIEhlbHBlciBmdW5jdGlvbiB0byBzcGxpdCBhIHdpZGUgZ2VuZXJpYyByZWdpc3RlciBpbnRvIGJpdHdpc2UgYmxvY2tzIHdpdGgKKyAgLy8vIHRoZSBnaXZlbiBUeXBlICh3aGljaCBpbXBsaWVzIHRoZSBudW1iZXIgb2YgYmxvY2tzIG5lZWRlZCkuIFRoZSBnZW5lcmljCisgIC8vLyByZWdpc3RlcnMgY3JlYXRlZCBhcmUgYXBwZW5kZWQgdG8gT3BzLCBzdGFydGluZyBhdCBiaXQgMCBvZiBSZWcuCisgIHZvaWQgZXh0cmFjdFBhcnRzKHVuc2lnbmVkIFJlZywgTExUIFR5LCBpbnQgTnVtUGFydHMsCisgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDx1bnNpZ25lZD4gJk9wcyk7CisKKyAgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJOworICBjb25zdCBMZWdhbGl6ZXJJbmZvICZMSTsKK307CisKKy8vLyBIZWxwZXIgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIHRoZSBnaXZlbiBsaWJjYWxsLgorTGVnYWxpemVySGVscGVyOjpMZWdhbGl6ZVJlc3VsdAorY3JlYXRlTGliY2FsbChNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyLCBSVExJQjo6TGliY2FsbCBMaWJjYWxsLAorICAgICAgICAgICAgICBjb25zdCBDYWxsTG93ZXJpbmc6OkFyZ0luZm8gJlJlc3VsdCwKKyAgICAgICAgICAgICAgQXJyYXlSZWY8Q2FsbExvd2VyaW5nOjpBcmdJbmZvPiBBcmdzKTsKKworfSAvLyBFbmQgbmFtZXNwYWNlIGxsdm0uCisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTGVnYWxpemVySW5mby5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTGVnYWxpemVySW5mby5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjExN2M3OTEKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9MZWdhbGl6ZXJJbmZvLmgKQEAgLTAsMCArMSw5MjAgQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9MZWdhbGl6ZXJJbmZvLmggLS0tLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8vIEludGVyZmFjZSBmb3IgVGFyZ2V0cyB0byBzcGVjaWZ5IHdoaWNoIG9wZXJhdGlvbnMgdGhleSBjYW4gc3VjY2Vzc2Z1bGx5CisvLy8gc2VsZWN0IGFuZCBob3cgdGhlIG90aGVycyBzaG91bGQgYmUgZXhwYW5kZWQgbW9zdCBlZmZpY2llbnRseS4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX0xFR0FMSVpFUklORk9fSAorI2RlZmluZSBMTFZNX0NPREVHRU5fR0xPQkFMSVNFTF9MRUdBTElaRVJJTkZPX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvTm9uZS5oIgorI2luY2x1ZGUgImxsdm0vQURUL09wdGlvbmFsLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU1RMRXh0cmFzLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1RhcmdldE9wY29kZXMuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvcmF3X29zdHJlYW0uaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvTG93TGV2ZWxUeXBlSW1wbC5oIgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8Y3N0ZGludD4KKyNpbmNsdWRlIDx0dXBsZT4KKyNpbmNsdWRlIDx1bm9yZGVyZWRfbWFwPgorI2luY2x1ZGUgPHV0aWxpdHk+CisKK25hbWVzcGFjZSBsbHZtIHsKKworZXh0ZXJuIGNsOjpvcHQ8Ym9vbD4gRGlzYWJsZUdJU2VsTGVnYWxpdHlDaGVjazsKKworY2xhc3MgTWFjaGluZUluc3RyOworY2xhc3MgTWFjaGluZUlSQnVpbGRlcjsKK2NsYXNzIE1hY2hpbmVSZWdpc3RlckluZm87CisKK25hbWVzcGFjZSBMZWdhbGl6ZUFjdGlvbnMgeworZW51bSBMZWdhbGl6ZUFjdGlvbiA6IHN0ZDo6dWludDhfdCB7CisgIC8vLyBUaGUgb3BlcmF0aW9uIGlzIGV4cGVjdGVkIHRvIGJlIHNlbGVjdGFibGUgZGlyZWN0bHkgYnkgdGhlIHRhcmdldCwgYW5kCisgIC8vLyBubyB0cmFuc2Zvcm1hdGlvbiBpcyBuZWNlc3NhcnkuCisgIExlZ2FsLAorCisgIC8vLyBUaGUgb3BlcmF0aW9uIHNob3VsZCBiZSBzeW50aGVzaXplZCBmcm9tIG11bHRpcGxlIGluc3RydWN0aW9ucyBhY3Rpbmcgb24KKyAgLy8vIGEgbmFycm93ZXIgc2NhbGFyIGJhc2UtdHlwZS4gRm9yIGV4YW1wbGUgYSA2NC1iaXQgYWRkIG1pZ2h0IGJlCisgIC8vLyBpbXBsZW1lbnRlZCBpbiB0ZXJtcyBvZiAzMi1iaXQgYWRkLXdpdGgtY2FycnkuCisgIE5hcnJvd1NjYWxhciwKKworICAvLy8gVGhlIG9wZXJhdGlvbiBzaG91bGQgYmUgaW1wbGVtZW50ZWQgaW4gdGVybXMgb2YgYSB3aWRlciBzY2FsYXIKKyAgLy8vIGJhc2UtdHlwZS4gRm9yIGV4YW1wbGUgYSA8MiB4IHM4PiBhZGQgY291bGQgYmUgaW1wbGVtZW50ZWQgYXMgYSA8MgorICAvLy8geCBzMzI+IGFkZCAoaWdub3JpbmcgdGhlIGhpZ2ggYml0cykuCisgIFdpZGVuU2NhbGFyLAorCisgIC8vLyBUaGUgKHZlY3Rvcikgb3BlcmF0aW9uIHNob3VsZCBiZSBpbXBsZW1lbnRlZCBieSBzcGxpdHRpbmcgaXQgaW50bworICAvLy8gc3ViLXZlY3RvcnMgd2hlcmUgdGhlIG9wZXJhdGlvbiBpcyBsZWdhbC4gRm9yIGV4YW1wbGUgYSA8OCB4IHM2ND4gYWRkCisgIC8vLyBtaWdodCBiZSBpbXBsZW1lbnRlZCBhcyA0IHNlcGFyYXRlIDwyIHggczY0PiBhZGRzLgorICBGZXdlckVsZW1lbnRzLAorCisgIC8vLyBUaGUgKHZlY3Rvcikgb3BlcmF0aW9uIHNob3VsZCBiZSBpbXBsZW1lbnRlZCBieSB3aWRlbmluZyB0aGUgaW5wdXQKKyAgLy8vIHZlY3RvciBhbmQgaWdub3JpbmcgdGhlIGxhbmVzIGFkZGVkIGJ5IGRvaW5nIHNvLiBGb3IgZXhhbXBsZSA8MiB4IGk4PiBpcworICAvLy8gcmFyZWx5IGxlZ2FsLCBidXQgeW91IG1pZ2h0IHBlcmZvcm0gYW4gPDggeCBpOD4gYW5kIHRoZW4gb25seSBsb29rIGF0CisgIC8vLyB0aGUgZmlyc3QgdHdvIHJlc3VsdHMuCisgIE1vcmVFbGVtZW50cywKKworICAvLy8gVGhlIG9wZXJhdGlvbiBpdHNlbGYgbXVzdCBiZSBleHByZXNzZWQgaW4gdGVybXMgb2Ygc2ltcGxlciBhY3Rpb25zIG9uCisgIC8vLyB0aGlzIHRhcmdldC4gRS5nLiBhIFNSRU0gcmVwbGFjZWQgYnkgYW4gU0RJViBhbmQgc3VidHJhY3Rpb24uCisgIExvd2VyLAorCisgIC8vLyBUaGUgb3BlcmF0aW9uIHNob3VsZCBiZSBpbXBsZW1lbnRlZCBhcyBhIGNhbGwgdG8gc29tZSBraW5kIG9mIHJ1bnRpbWUKKyAgLy8vIHN1cHBvcnQgbGlicmFyeS4gRm9yIGV4YW1wbGUgdGhpcyB1c3VhbGx5IGhhcHBlbnMgb24gbWFjaGluZXMgdGhhdCBkb24ndAorICAvLy8gc3VwcG9ydCBmbG9hdGluZy1wb2ludCBvcGVyYXRpb25zIG5hdGl2ZWx5LgorICBMaWJjYWxsLAorCisgIC8vLyBUaGUgdGFyZ2V0IHdhbnRzIHRvIGRvIHNvbWV0aGluZyBzcGVjaWFsIHdpdGggdGhpcyBjb21iaW5hdGlvbiBvZgorICAvLy8gb3BlcmFuZCBhbmQgdHlwZS4gQSBjYWxsYmFjayB3aWxsIGJlIGlzc3VlZCB3aGVuIGl0IGlzIG5lZWRlZC4KKyAgQ3VzdG9tLAorCisgIC8vLyBUaGlzIG9wZXJhdGlvbiBpcyBjb21wbGV0ZWx5IHVuc3VwcG9ydGVkIG9uIHRoZSB0YXJnZXQuIEEgcHJvZ3JhbW1pbmcKKyAgLy8vIGVycm9yIGhhcyBvY2N1cnJlZC4KKyAgVW5zdXBwb3J0ZWQsCisKKyAgLy8vIFNlbnRpbmVsIHZhbHVlIGZvciB3aGVuIG5vIGFjdGlvbiB3YXMgZm91bmQgaW4gdGhlIHNwZWNpZmllZCB0YWJsZS4KKyAgTm90Rm91bmQsCisKKyAgLy8vIEZhbGwgYmFjayBvbnRvIHRoZSBvbGQgcnVsZXMuCisgIC8vLyBUT0RPOiBSZW1vdmUgdGhpcyBvbmNlIHdlJ3ZlIG1pZ3JhdGVkCisgIFVzZUxlZ2FjeVJ1bGVzLAorfTsKK30gLy8gZW5kIG5hbWVzcGFjZSBMZWdhbGl6ZUFjdGlvbnMKKwordXNpbmcgTGVnYWxpemVBY3Rpb25zOjpMZWdhbGl6ZUFjdGlvbjsKKworLy8vIExlZ2FsaXphdGlvbiBpcyBkZWNpZGVkIGJhc2VkIG9uIGFuIGluc3RydWN0aW9uJ3Mgb3Bjb2RlLCB3aGljaCB0eXBlIHNsb3QKKy8vLyB3ZSdyZSBjb25zaWRlcmluZywgYW5kIHdoYXQgdGhlIGV4aXN0aW5nIHR5cGUgaXMuIFRoZXNlIGFzcGVjdHMgYXJlIGdhdGhlcmVkCisvLy8gdG9nZXRoZXIgZm9yIGNvbnZlbmllbmNlIGluIHRoZSBJbnN0ckFzcGVjdCBjbGFzcy4KK3N0cnVjdCBJbnN0ckFzcGVjdCB7CisgIHVuc2lnbmVkIE9wY29kZTsKKyAgdW5zaWduZWQgSWR4ID0gMDsKKyAgTExUIFR5cGU7CisKKyAgSW5zdHJBc3BlY3QodW5zaWduZWQgT3Bjb2RlLCBMTFQgVHlwZSkgOiBPcGNvZGUoT3Bjb2RlKSwgVHlwZShUeXBlKSB7fQorICBJbnN0ckFzcGVjdCh1bnNpZ25lZCBPcGNvZGUsIHVuc2lnbmVkIElkeCwgTExUIFR5cGUpCisgICAgICA6IE9wY29kZShPcGNvZGUpLCBJZHgoSWR4KSwgVHlwZShUeXBlKSB7fQorCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBJbnN0ckFzcGVjdCAmUkhTKSBjb25zdCB7CisgICAgcmV0dXJuIE9wY29kZSA9PSBSSFMuT3Bjb2RlICYmIElkeCA9PSBSSFMuSWR4ICYmIFR5cGUgPT0gUkhTLlR5cGU7CisgIH0KK307CisKKy8vLyBUaGUgTGVnYWxpdHlRdWVyeSBvYmplY3QgYnVuZGxlcyB0b2dldGhlciBhbGwgdGhlIGluZm9ybWF0aW9uIHRoYXQncyBuZWVkZWQKKy8vLyB0byBkZWNpZGUgd2hldGhlciBhIGdpdmVuIG9wZXJhdGlvbiBpcyBsZWdhbCBvciBub3QuCisvLy8gRm9yIGVmZmljaWVuY3ksIGl0IGRvZXNuJ3QgbWFrZSBhIGNvcHkgb2YgVHlwZXMgc28gY2FyZSBtdXN0IGJlIHRha2VuIG5vdAorLy8vIHRvIGZyZWUgaXQgYmVmb3JlIHVzaW5nIHRoZSBxdWVyeS4KK3N0cnVjdCBMZWdhbGl0eVF1ZXJ5IHsKKyAgdW5zaWduZWQgT3Bjb2RlOworICBBcnJheVJlZjxMTFQ+IFR5cGVzOworCisgIHJhd19vc3RyZWFtICZwcmludChyYXdfb3N0cmVhbSAmT1MpIGNvbnN0OworfTsKKworLy8vIFRoZSByZXN1bHQgb2YgYSBxdWVyeS4gSXQgZWl0aGVyIGluZGljYXRlcyBhIGZpbmFsIGFuc3dlciBvZiBMZWdhbCBvcgorLy8vIFVuc3VwcG9ydGVkIG9yIGRlc2NyaWJlcyBhbiBhY3Rpb24gdGhhdCBtdXN0IGJlIHRha2VuIHRvIG1ha2UgYW4gb3BlcmF0aW9uCisvLy8gbW9yZSBsZWdhbC4KK3N0cnVjdCBMZWdhbGl6ZUFjdGlvblN0ZXAgeworICAvLy8gVGhlIGFjdGlvbiB0byB0YWtlIG9yIHRoZSBmaW5hbCBhbnN3ZXIuCisgIExlZ2FsaXplQWN0aW9uIEFjdGlvbjsKKyAgLy8vIElmIGRlc2NyaWJpbmcgYW4gYWN0aW9uLCB0aGUgdHlwZSBpbmRleCB0byBjaGFuZ2UuIE90aGVyd2lzZSB6ZXJvLgorICB1bnNpZ25lZCBUeXBlSWR4OworICAvLy8gSWYgZGVzY3JpYmluZyBhbiBhY3Rpb24sIHRoZSBuZXcgdHlwZSBmb3IgVHlwZUlkeC4gT3RoZXJ3aXNlIExMVHt9LgorICBMTFQgTmV3VHlwZTsKKworICBMZWdhbGl6ZUFjdGlvblN0ZXAoTGVnYWxpemVBY3Rpb24gQWN0aW9uLCB1bnNpZ25lZCBUeXBlSWR4LAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgTExUICZOZXdUeXBlKQorICAgICAgOiBBY3Rpb24oQWN0aW9uKSwgVHlwZUlkeChUeXBlSWR4KSwgTmV3VHlwZShOZXdUeXBlKSB7fQorCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBMZWdhbGl6ZUFjdGlvblN0ZXAgJlJIUykgY29uc3QgeworICAgIHJldHVybiBzdGQ6OnRpZShBY3Rpb24sIFR5cGVJZHgsIE5ld1R5cGUpID09CisgICAgICAgIHN0ZDo6dGllKFJIUy5BY3Rpb24sIFJIUy5UeXBlSWR4LCBSSFMuTmV3VHlwZSk7CisgIH0KK307CisKK3VzaW5nIExlZ2FsaXR5UHJlZGljYXRlID0gc3RkOjpmdW5jdGlvbjxib29sIChjb25zdCBMZWdhbGl0eVF1ZXJ5ICYpPjsKK3VzaW5nIExlZ2FsaXplTXV0YXRpb24gPQorICAgIHN0ZDo6ZnVuY3Rpb248c3RkOjpwYWlyPHVuc2lnbmVkLCBMTFQ+KGNvbnN0IExlZ2FsaXR5UXVlcnkgJik+OworCituYW1lc3BhY2UgTGVnYWxpdHlQcmVkaWNhdGVzIHsKKy8vLyBUcnVlIGlmZiBQMCBhbmQgUDEgYXJlIHRydWUuCitMZWdhbGl0eVByZWRpY2F0ZSBhbGwoTGVnYWxpdHlQcmVkaWNhdGUgUDAsIExlZ2FsaXR5UHJlZGljYXRlIFAxKTsKKy8vLyBUcnVlIGlmZiB0aGUgZ2l2ZW4gdHlwZSBpbmRleCBpcyBvbmUgb2YgdGhlIHNwZWNpZmllZCB0eXBlcy4KK0xlZ2FsaXR5UHJlZGljYXRlIHR5cGVJblNldCh1bnNpZ25lZCBUeXBlSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6aW5pdGlhbGl6ZXJfbGlzdDxMTFQ+IFR5cGVzSW5pdCk7CisvLy8gVHJ1ZSBpZmYgdGhlIGdpdmVuIHR5cGVzIGZvciB0aGUgZ2l2ZW4gcGFpciBvZiB0eXBlIGluZGV4ZXMgaXMgb25lIG9mIHRoZQorLy8vIHNwZWNpZmllZCB0eXBlIHBhaXJzLgorTGVnYWxpdHlQcmVkaWNhdGUKK3R5cGVQYWlySW5TZXQodW5zaWduZWQgVHlwZUlkeDAsIHVuc2lnbmVkIFR5cGVJZHgxLAorICAgICAgICAgICAgICBzdGQ6OmluaXRpYWxpemVyX2xpc3Q8c3RkOjpwYWlyPExMVCwgTExUPj4gVHlwZXNJbml0KTsKKy8vLyBUcnVlIGlmZiB0aGUgc3BlY2lmaWVkIHR5cGUgaW5kZXggaXMgYSBzY2FsYXIuCitMZWdhbGl0eVByZWRpY2F0ZSBpc1NjYWxhcih1bnNpZ25lZCBUeXBlSWR4KTsKKy8vLyBUcnVlIGlmZiB0aGUgc3BlY2lmaWVkIHR5cGUgaW5kZXggaXMgYSBzY2FsYXIgdGhhdCdzIG5hcnJvd2VyIHRoYW4gdGhlIGdpdmVuCisvLy8gc2l6ZS4KK0xlZ2FsaXR5UHJlZGljYXRlIG5hcnJvd2VyVGhhbih1bnNpZ25lZCBUeXBlSWR4LCB1bnNpZ25lZCBTaXplKTsKKy8vLyBUcnVlIGlmZiB0aGUgc3BlY2lmaWVkIHR5cGUgaW5kZXggaXMgYSBzY2FsYXIgdGhhdCdzIHdpZGVyIHRoYW4gdGhlIGdpdmVuCisvLy8gc2l6ZS4KK0xlZ2FsaXR5UHJlZGljYXRlIHdpZGVyVGhhbih1bnNpZ25lZCBUeXBlSWR4LCB1bnNpZ25lZCBTaXplKTsKKy8vLyBUcnVlIGlmZiB0aGUgc3BlY2lmaWVkIHR5cGUgaW5kZXggaXMgYSBzY2FsYXIgd2hvc2Ugc2l6ZSBpcyBub3QgYSBwb3dlciBvZgorLy8vIDIuCitMZWdhbGl0eVByZWRpY2F0ZSBzaXplTm90UG93Mih1bnNpZ25lZCBUeXBlSWR4KTsKKy8vLyBUcnVlIGlmZiB0aGUgc3BlY2lmaWVkIHR5cGUgaW5kZXggaXMgYSB2ZWN0b3Igd2hvc2UgZWxlbWVudCBjb3VudCBpcyBub3QgYQorLy8vIHBvd2VyIG9mIDIuCitMZWdhbGl0eVByZWRpY2F0ZSBudW1FbGVtZW50c05vdFBvdzIodW5zaWduZWQgVHlwZUlkeCk7Cit9IC8vIGVuZCBuYW1lc3BhY2UgTGVnYWxpdHlQcmVkaWNhdGVzCisKK25hbWVzcGFjZSBMZWdhbGl6ZU11dGF0aW9ucyB7CisvLy8gU2VsZWN0IHRoaXMgc3BlY2lmaWMgdHlwZSBmb3IgdGhlIGdpdmVuIHR5cGUgaW5kZXguCitMZWdhbGl6ZU11dGF0aW9uIGNoYW5nZVRvKHVuc2lnbmVkIFR5cGVJZHgsIExMVCBUeSk7CisvLy8gV2lkZW4gdGhlIHR5cGUgZm9yIHRoZSBnaXZlbiB0eXBlIGluZGV4IHRvIHRoZSBuZXh0IHBvd2VyIG9mIDIuCitMZWdhbGl6ZU11dGF0aW9uIHdpZGVuU2NhbGFyVG9OZXh0UG93Mih1bnNpZ25lZCBUeXBlSWR4LCB1bnNpZ25lZCBNaW4gPSAwKTsKKy8vLyBBZGQgbW9yZSBlbGVtZW50cyB0byB0aGUgdHlwZSBmb3IgdGhlIGdpdmVuIHR5cGUgaW5kZXggdG8gdGhlIG5leHQgcG93ZXIgb2YKKy8vLyAyLgorTGVnYWxpemVNdXRhdGlvbiBtb3JlRWxlbWVudHNUb05leHRQb3cyKHVuc2lnbmVkIFR5cGVJZHgsIHVuc2lnbmVkIE1pbiA9IDApOworfSAvLyBlbmQgbmFtZXNwYWNlIExlZ2FsaXplTXV0YXRpb25zCisKKy8vLyBBIHNpbmdsZSBydWxlIGluIGEgbGVnYWxpemVyIGluZm8gcnVsZXNldC4KKy8vLyBUaGUgc3BlY2lmaWVkIGFjdGlvbiBpcyBjaG9zZW4gd2hlbiB0aGUgcHJlZGljYXRlIGlzIHRydWUuIFdoZXJlIGFwcHJvcHJpYXRlCisvLy8gZm9yIHRoZSBhY3Rpb24gKGUuZy4gZm9yIFdpZGVuU2NhbGFyKSB0aGUgbmV3IHR5cGUgaXMgc2VsZWN0ZWQgdXNpbmcgdGhlCisvLy8gZ2l2ZW4gbXV0YXRvci4KK2NsYXNzIExlZ2FsaXplUnVsZSB7CisgIExlZ2FsaXR5UHJlZGljYXRlIFByZWRpY2F0ZTsKKyAgTGVnYWxpemVBY3Rpb24gQWN0aW9uOworICBMZWdhbGl6ZU11dGF0aW9uIE11dGF0aW9uOworCitwdWJsaWM6CisgIExlZ2FsaXplUnVsZShMZWdhbGl0eVByZWRpY2F0ZSBQcmVkaWNhdGUsIExlZ2FsaXplQWN0aW9uIEFjdGlvbiwKKyAgICAgICAgICAgICAgIExlZ2FsaXplTXV0YXRpb24gTXV0YXRpb24gPSBudWxscHRyKQorICAgICAgOiBQcmVkaWNhdGUoUHJlZGljYXRlKSwgQWN0aW9uKEFjdGlvbiksIE11dGF0aW9uKE11dGF0aW9uKSB7fQorCisgIC8vLyBUZXN0IHdoZXRoZXIgdGhlIExlZ2FsaXR5UXVlcnkgbWF0Y2hlcy4KKyAgYm9vbCBtYXRjaChjb25zdCBMZWdhbGl0eVF1ZXJ5ICZRdWVyeSkgY29uc3QgeworICAgIHJldHVybiBQcmVkaWNhdGUoUXVlcnkpOworICB9CisKKyAgTGVnYWxpemVBY3Rpb24gZ2V0QWN0aW9uKCkgY29uc3QgeyByZXR1cm4gQWN0aW9uOyB9CisKKyAgLy8vIERldGVybWluZSB0aGUgY2hhbmdlIHRvIG1ha2UuCisgIHN0ZDo6cGFpcjx1bnNpZ25lZCwgTExUPiBkZXRlcm1pbmVNdXRhdGlvbihjb25zdCBMZWdhbGl0eVF1ZXJ5ICZRdWVyeSkgY29uc3QgeworICAgIGlmIChNdXRhdGlvbikKKyAgICAgIHJldHVybiBNdXRhdGlvbihRdWVyeSk7CisgICAgcmV0dXJuIHN0ZDo6bWFrZV9wYWlyKDAsIExMVHt9KTsKKyAgfQorfTsKKworY2xhc3MgTGVnYWxpemVSdWxlU2V0IHsKKyAgLy8vIFdoZW4gbm9uLXplcm8sIHRoZSBvcGNvZGUgd2UgYXJlIGFuIGFsaWFzIG9mCisgIHVuc2lnbmVkIEFsaWFzT2Y7CisgIC8vLyBJZiB0cnVlLCB0aGVyZSBpcyBhbm90aGVyIG9wY29kZSB0aGF0IGFsaWFzZXMgdGhpcyBvbmUKKyAgYm9vbCBJc0FsaWFzZWRCeUFub3RoZXI7CisgIFNtYWxsVmVjdG9yPExlZ2FsaXplUnVsZSwgMj4gUnVsZXM7CisKKyAgdm9pZCBhZGQoY29uc3QgTGVnYWxpemVSdWxlICZSdWxlKSB7CisgICAgYXNzZXJ0KEFsaWFzT2YgPT0gMCAmJgorICAgICAgICAgICAiUnVsZVNldCBpcyBhbGlhc2VkLCBjaGFuZ2UgdGhlIHJlcHJlc2VudGF0aXZlIG9wY29kZSBpbnN0ZWFkIik7CisgICAgUnVsZXMucHVzaF9iYWNrKFJ1bGUpOworICB9CisKKyAgc3RhdGljIGJvb2wgYWx3YXlzKGNvbnN0IExlZ2FsaXR5UXVlcnkgJikgeyByZXR1cm4gdHJ1ZTsgfQorCisgIC8vLyBVc2UgdGhlIGdpdmVuIGFjdGlvbiB3aGVuIHRoZSBwcmVkaWNhdGUgaXMgdHJ1ZS4KKyAgLy8vIEFjdGlvbiBzaG91bGQgbm90IGJlIGFuIGFjdGlvbiB0aGF0IHJlcXVpcmVzIG11dGF0aW9uLgorICBMZWdhbGl6ZVJ1bGVTZXQgJmFjdGlvbklmKExlZ2FsaXplQWN0aW9uIEFjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBMZWdhbGl0eVByZWRpY2F0ZSBQcmVkaWNhdGUpIHsKKyAgICBhZGQoe1ByZWRpY2F0ZSwgQWN0aW9ufSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIC8vLyBVc2UgdGhlIGdpdmVuIGFjdGlvbiB3aGVuIHRoZSBwcmVkaWNhdGUgaXMgdHJ1ZS4KKyAgLy8vIEFjdGlvbiBzaG91bGQgbm90IGJlIGFuIGFjdGlvbiB0aGF0IHJlcXVpcmVzIG11dGF0aW9uLgorICBMZWdhbGl6ZVJ1bGVTZXQgJmFjdGlvbklmKExlZ2FsaXplQWN0aW9uIEFjdGlvbiwgTGVnYWxpdHlQcmVkaWNhdGUgUHJlZGljYXRlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIExlZ2FsaXplTXV0YXRpb24gTXV0YXRpb24pIHsKKyAgICBhZGQoe1ByZWRpY2F0ZSwgQWN0aW9uLCBNdXRhdGlvbn0pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorICAvLy8gVXNlIHRoZSBnaXZlbiBhY3Rpb24gd2hlbiB0eXBlIGluZGV4IDAgaXMgYW55IHR5cGUgaW4gdGhlIGdpdmVuIGxpc3QuCisgIC8vLyBBY3Rpb24gc2hvdWxkIG5vdCBiZSBhbiBhY3Rpb24gdGhhdCByZXF1aXJlcyBtdXRhdGlvbi4KKyAgTGVnYWxpemVSdWxlU2V0ICZhY3Rpb25Gb3IoTGVnYWxpemVBY3Rpb24gQWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OmluaXRpYWxpemVyX2xpc3Q8TExUPiBUeXBlcykgeworICAgIHVzaW5nIG5hbWVzcGFjZSBMZWdhbGl0eVByZWRpY2F0ZXM7CisgICAgcmV0dXJuIGFjdGlvbklmKEFjdGlvbiwgdHlwZUluU2V0KDAsIFR5cGVzKSk7CisgIH0KKyAgLy8vIFVzZSB0aGUgZ2l2ZW4gYWN0aW9uIHdoZW4gdHlwZSBpbmRleGVzIDAgYW5kIDEgaXMgYW55IHR5cGUgcGFpciBpbiB0aGUKKyAgLy8vIGdpdmVuIGxpc3QuCisgIC8vLyBBY3Rpb24gc2hvdWxkIG5vdCBiZSBhbiBhY3Rpb24gdGhhdCByZXF1aXJlcyBtdXRhdGlvbi4KKyAgTGVnYWxpemVSdWxlU2V0ICYKKyAgYWN0aW9uRm9yKExlZ2FsaXplQWN0aW9uIEFjdGlvbiwKKyAgICAgICAgICAgIHN0ZDo6aW5pdGlhbGl6ZXJfbGlzdDxzdGQ6OnBhaXI8TExULCBMTFQ+PiBUeXBlcykgeworICAgIHVzaW5nIG5hbWVzcGFjZSBMZWdhbGl0eVByZWRpY2F0ZXM7CisgICAgcmV0dXJuIGFjdGlvbklmKEFjdGlvbiwgdHlwZVBhaXJJblNldCgwLCAxLCBUeXBlcykpOworICB9CisgIC8vLyBVc2UgdGhlIGdpdmVuIGFjdGlvbiB3aGVuIHR5cGUgaW5kZXhlcyAwIGFuZCAxIGFyZSBib3RoIGluIHRoZSBnaXZlbiBsaXN0LgorICAvLy8gVGhhdCBpcywgdGhlIHR5cGUgcGFpciBpcyBpbiB0aGUgY2FydGVzaWFuIHByb2R1Y3Qgb2YgdGhlIGxpc3QuCisgIC8vLyBBY3Rpb24gc2hvdWxkIG5vdCBiZSBhbiBhY3Rpb24gdGhhdCByZXF1aXJlcyBtdXRhdGlvbi4KKyAgTGVnYWxpemVSdWxlU2V0ICZhY3Rpb25Gb3JDYXJ0ZXNpYW5Qcm9kdWN0KExlZ2FsaXplQWN0aW9uIEFjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6aW5pdGlhbGl6ZXJfbGlzdDxMTFQ+IFR5cGVzKSB7CisgICAgdXNpbmcgbmFtZXNwYWNlIExlZ2FsaXR5UHJlZGljYXRlczsKKyAgICByZXR1cm4gYWN0aW9uSWYoQWN0aW9uLCBhbGwodHlwZUluU2V0KDAsIFR5cGVzKSwgdHlwZUluU2V0KDEsIFR5cGVzKSkpOworICB9CisgIC8vLyBVc2UgdGhlIGdpdmVuIGFjdGlvbiB3aGVuIHR5cGUgaW5kZXhlcyAwIGFuZCAxIGFyZSBib3RoIHRoZWlyIHJlc3BlY3RpdmUKKyAgLy8vIGxpc3RzLgorICAvLy8gVGhhdCBpcywgdGhlIHR5cGUgcGFpciBpcyBpbiB0aGUgY2FydGVzaWFuIHByb2R1Y3Qgb2YgdGhlIGxpc3RzCisgIC8vLyBBY3Rpb24gc2hvdWxkIG5vdCBiZSBhbiBhY3Rpb24gdGhhdCByZXF1aXJlcyBtdXRhdGlvbi4KKyAgTGVnYWxpemVSdWxlU2V0ICYKKyAgYWN0aW9uRm9yQ2FydGVzaWFuUHJvZHVjdChMZWdhbGl6ZUFjdGlvbiBBY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjppbml0aWFsaXplcl9saXN0PExMVD4gVHlwZXMwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6aW5pdGlhbGl6ZXJfbGlzdDxMTFQ+IFR5cGVzMSkgeworICAgIHVzaW5nIG5hbWVzcGFjZSBMZWdhbGl0eVByZWRpY2F0ZXM7CisgICAgcmV0dXJuIGFjdGlvbklmKEFjdGlvbiwgYWxsKHR5cGVJblNldCgwLCBUeXBlczApLCB0eXBlSW5TZXQoMSwgVHlwZXMxKSkpOworICB9CisKK3B1YmxpYzoKKyAgTGVnYWxpemVSdWxlU2V0KCkgOiBBbGlhc09mKDApLCBJc0FsaWFzZWRCeUFub3RoZXIoZmFsc2UpLCBSdWxlcygpIHt9CisKKyAgYm9vbCBpc0FsaWFzZWRCeUFub3RoZXIoKSB7IHJldHVybiBJc0FsaWFzZWRCeUFub3RoZXI7IH0KKyAgdm9pZCBzZXRJc0FsaWFzZWRCeUFub3RoZXIoKSB7IElzQWxpYXNlZEJ5QW5vdGhlciA9IHRydWU7IH0KKyAgdm9pZCBhbGlhc1RvKHVuc2lnbmVkIE9wY29kZSkgeworICAgIGFzc2VydCgoQWxpYXNPZiA9PSAwIHx8IEFsaWFzT2YgPT0gT3Bjb2RlKSAmJgorICAgICAgICAgICAiT3Bjb2RlIGlzIGFscmVhZHkgYWxpYXNlZCB0byBhbm90aGVyIG9wY29kZSIpOworICAgIGFzc2VydChSdWxlcy5lbXB0eSgpICYmICJBbGlhc2luZyB3aWxsIGRpc2NhcmQgcnVsZXMiKTsKKyAgICBBbGlhc09mID0gT3Bjb2RlOworICB9CisgIHVuc2lnbmVkIGdldEFsaWFzKCkgY29uc3QgeyByZXR1cm4gQWxpYXNPZjsgfQorCisgIC8vLyBUaGUgaW5zdHJ1Y3Rpb24gaXMgbGVnYWwgaWYgcHJlZGljYXRlIGlzIHRydWUuCisgIExlZ2FsaXplUnVsZVNldCAmbGVnYWxJZihMZWdhbGl0eVByZWRpY2F0ZSBQcmVkaWNhdGUpIHsKKyAgICByZXR1cm4gYWN0aW9uSWYoTGVnYWxpemVBY3Rpb246OkxlZ2FsLCBQcmVkaWNhdGUpOworICB9CisgIC8vLyBUaGUgaW5zdHJ1Y3Rpb24gaXMgbGVnYWwgd2hlbiB0eXBlIGluZGV4IDAgaXMgYW55IHR5cGUgaW4gdGhlIGdpdmVuIGxpc3QuCisgIExlZ2FsaXplUnVsZVNldCAmbGVnYWxGb3Ioc3RkOjppbml0aWFsaXplcl9saXN0PExMVD4gVHlwZXMpIHsKKyAgICByZXR1cm4gYWN0aW9uRm9yKExlZ2FsaXplQWN0aW9uOjpMZWdhbCwgVHlwZXMpOworICB9CisgIC8vLyBUaGUgaW5zdHJ1Y3Rpb24gaXMgbGVnYWwgd2hlbiB0eXBlIGluZGV4ZXMgMCBhbmQgMSBpcyBhbnkgdHlwZSBwYWlyIGluIHRoZQorICAvLy8gZ2l2ZW4gbGlzdC4KKyAgTGVnYWxpemVSdWxlU2V0ICZsZWdhbEZvcihzdGQ6OmluaXRpYWxpemVyX2xpc3Q8c3RkOjpwYWlyPExMVCwgTExUPj4gVHlwZXMpIHsKKyAgICByZXR1cm4gYWN0aW9uRm9yKExlZ2FsaXplQWN0aW9uOjpMZWdhbCwgVHlwZXMpOworICB9CisgIC8vLyBUaGUgaW5zdHJ1Y3Rpb24gaXMgbGVnYWwgd2hlbiB0eXBlIGluZGV4ZXMgMCBhbmQgMSBhcmUgYm90aCBpbiB0aGUgZ2l2ZW4KKyAgLy8vIGxpc3QuIFRoYXQgaXMsIHRoZSB0eXBlIHBhaXIgaXMgaW4gdGhlIGNhcnRlc2lhbiBwcm9kdWN0IG9mIHRoZSBsaXN0LgorICBMZWdhbGl6ZVJ1bGVTZXQgJmxlZ2FsRm9yQ2FydGVzaWFuUHJvZHVjdChzdGQ6OmluaXRpYWxpemVyX2xpc3Q8TExUPiBUeXBlcykgeworICAgIHJldHVybiBhY3Rpb25Gb3JDYXJ0ZXNpYW5Qcm9kdWN0KExlZ2FsaXplQWN0aW9uOjpMZWdhbCwgVHlwZXMpOworICB9CisgIC8vLyBUaGUgaW5zdHJ1Y3Rpb24gaXMgbGVnYWwgd2hlbiB0eXBlIGluZGV4ZXMgMCBhbmQgMSBhcmUgYm90aCB0aGVpcgorICAvLy8gcmVzcGVjdGl2ZSBsaXN0cy4KKyAgTGVnYWxpemVSdWxlU2V0ICZsZWdhbEZvckNhcnRlc2lhblByb2R1Y3Qoc3RkOjppbml0aWFsaXplcl9saXN0PExMVD4gVHlwZXMwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OmluaXRpYWxpemVyX2xpc3Q8TExUPiBUeXBlczEpIHsKKyAgICByZXR1cm4gYWN0aW9uRm9yQ2FydGVzaWFuUHJvZHVjdChMZWdhbGl6ZUFjdGlvbjo6TGVnYWwsIFR5cGVzMCwgVHlwZXMxKTsKKyAgfQorCisgIC8vLyBMaWtlIGxlZ2FsSWYsIGJ1dCBmb3IgdGhlIExpYmNhbGwgYWN0aW9uLgorICBMZWdhbGl6ZVJ1bGVTZXQgJmxpYmNhbGxJZihMZWdhbGl0eVByZWRpY2F0ZSBQcmVkaWNhdGUpIHsKKyAgICByZXR1cm4gYWN0aW9uSWYoTGVnYWxpemVBY3Rpb246OkxpYmNhbGwsIFByZWRpY2F0ZSk7CisgIH0KKyAgTGVnYWxpemVSdWxlU2V0ICZsaWJjYWxsRm9yKHN0ZDo6aW5pdGlhbGl6ZXJfbGlzdDxMTFQ+IFR5cGVzKSB7CisgICAgcmV0dXJuIGFjdGlvbkZvcihMZWdhbGl6ZUFjdGlvbjo6TGliY2FsbCwgVHlwZXMpOworICB9CisgIExlZ2FsaXplUnVsZVNldCAmCisgIGxpYmNhbGxGb3Ioc3RkOjppbml0aWFsaXplcl9saXN0PHN0ZDo6cGFpcjxMTFQsIExMVD4+IFR5cGVzKSB7CisgICAgcmV0dXJuIGFjdGlvbkZvcihMZWdhbGl6ZUFjdGlvbjo6TGliY2FsbCwgVHlwZXMpOworICB9CisgIExlZ2FsaXplUnVsZVNldCAmCisgIGxpYmNhbGxGb3JDYXJ0ZXNpYW5Qcm9kdWN0KHN0ZDo6aW5pdGlhbGl6ZXJfbGlzdDxMTFQ+IFR5cGVzKSB7CisgICAgcmV0dXJuIGFjdGlvbkZvckNhcnRlc2lhblByb2R1Y3QoTGVnYWxpemVBY3Rpb246OkxpYmNhbGwsIFR5cGVzKTsKKyAgfQorICBMZWdhbGl6ZVJ1bGVTZXQgJgorICBsaWJjYWxsRm9yQ2FydGVzaWFuUHJvZHVjdChzdGQ6OmluaXRpYWxpemVyX2xpc3Q8TExUPiBUeXBlczAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6aW5pdGlhbGl6ZXJfbGlzdDxMTFQ+IFR5cGVzMSkgeworICAgIHJldHVybiBhY3Rpb25Gb3JDYXJ0ZXNpYW5Qcm9kdWN0KExlZ2FsaXplQWN0aW9uOjpMaWJjYWxsLCBUeXBlczAsIFR5cGVzMSk7CisgIH0KKworICAvLy8gV2lkZW4gdGhlIHNjYWxhciB0byB0aGUgb25lIHNlbGVjdGVkIGJ5IHRoZSBtdXRhdGlvbiBpZiB0aGUgcHJlZGljYXRlIGlzCisgIC8vLyB0cnVlLgorICBMZWdhbGl6ZVJ1bGVTZXQgJndpZGVuU2NhbGFySWYoTGVnYWxpdHlQcmVkaWNhdGUgUHJlZGljYXRlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGVnYWxpemVNdXRhdGlvbiBNdXRhdGlvbikgeworICAgIHJldHVybiBhY3Rpb25JZihMZWdhbGl6ZUFjdGlvbjo6V2lkZW5TY2FsYXIsIFByZWRpY2F0ZSwgTXV0YXRpb24pOworICB9CisgIC8vLyBOYXJyb3cgdGhlIHNjYWxhciB0byB0aGUgb25lIHNlbGVjdGVkIGJ5IHRoZSBtdXRhdGlvbiBpZiB0aGUgcHJlZGljYXRlIGlzCisgIC8vLyB0cnVlLgorICBMZWdhbGl6ZVJ1bGVTZXQgJm5hcnJvd1NjYWxhcklmKExlZ2FsaXR5UHJlZGljYXRlIFByZWRpY2F0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMZWdhbGl6ZU11dGF0aW9uIE11dGF0aW9uKSB7CisgICAgcmV0dXJuIGFjdGlvbklmKExlZ2FsaXplQWN0aW9uOjpOYXJyb3dTY2FsYXIsIFByZWRpY2F0ZSwgTXV0YXRpb24pOworICB9CisKKyAgLy8vIEFkZCBtb3JlIGVsZW1lbnRzIHRvIHJlYWNoIHRoZSB0eXBlIHNlbGVjdGVkIGJ5IHRoZSBtdXRhdGlvbiBpZiB0aGUKKyAgLy8vIHByZWRpY2F0ZSBpcyB0cnVlLgorICBMZWdhbGl6ZVJ1bGVTZXQgJm1vcmVFbGVtZW50c0lmKExlZ2FsaXR5UHJlZGljYXRlIFByZWRpY2F0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMZWdhbGl6ZU11dGF0aW9uIE11dGF0aW9uKSB7CisgICAgcmV0dXJuIGFjdGlvbklmKExlZ2FsaXplQWN0aW9uOjpNb3JlRWxlbWVudHMsIFByZWRpY2F0ZSwgTXV0YXRpb24pOworICB9CisgIC8vLyBSZW1vdmUgZWxlbWVudHMgdG8gcmVhY2ggdGhlIHR5cGUgc2VsZWN0ZWQgYnkgdGhlIG11dGF0aW9uIGlmIHRoZQorICAvLy8gcHJlZGljYXRlIGlzIHRydWUuCisgIExlZ2FsaXplUnVsZVNldCAmZmV3ZXJFbGVtZW50c0lmKExlZ2FsaXR5UHJlZGljYXRlIFByZWRpY2F0ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGVnYWxpemVNdXRhdGlvbiBNdXRhdGlvbikgeworICAgIHJldHVybiBhY3Rpb25JZihMZWdhbGl6ZUFjdGlvbjo6RmV3ZXJFbGVtZW50cywgUHJlZGljYXRlLCBNdXRhdGlvbik7CisgIH0KKworICAvLy8gVGhlIGluc3RydWN0aW9uIGlzIHVuc3VwcG9ydGVkLgorICBMZWdhbGl6ZVJ1bGVTZXQgJnVuc3VwcG9ydGVkKCkgeworICAgIHJldHVybiBhY3Rpb25JZihMZWdhbGl6ZUFjdGlvbjo6VW5zdXBwb3J0ZWQsIGFsd2F5cyk7CisgIH0KKyAgTGVnYWxpemVSdWxlU2V0ICZ1bnN1cHBvcnRlZElmKExlZ2FsaXR5UHJlZGljYXRlIFByZWRpY2F0ZSkgeworICAgIHJldHVybiBhY3Rpb25JZihMZWdhbGl6ZUFjdGlvbjo6VW5zdXBwb3J0ZWQsIFByZWRpY2F0ZSk7CisgIH0KKworICBMZWdhbGl6ZVJ1bGVTZXQgJmN1c3RvbUlmKExlZ2FsaXR5UHJlZGljYXRlIFByZWRpY2F0ZSkgeworICAgIHJldHVybiBhY3Rpb25JZihMZWdhbGl6ZUFjdGlvbjo6Q3VzdG9tLCBQcmVkaWNhdGUpOworICB9CisgIExlZ2FsaXplUnVsZVNldCAmY3VzdG9tRm9yKHN0ZDo6aW5pdGlhbGl6ZXJfbGlzdDxMTFQ+IFR5cGVzKSB7CisgICAgcmV0dXJuIGFjdGlvbkZvcihMZWdhbGl6ZUFjdGlvbjo6Q3VzdG9tLCBUeXBlcyk7CisgIH0KKyAgTGVnYWxpemVSdWxlU2V0ICZjdXN0b21Gb3JDYXJ0ZXNpYW5Qcm9kdWN0KHN0ZDo6aW5pdGlhbGl6ZXJfbGlzdDxMTFQ+IFR5cGVzKSB7CisgICAgcmV0dXJuIGFjdGlvbkZvckNhcnRlc2lhblByb2R1Y3QoTGVnYWxpemVBY3Rpb246OkN1c3RvbSwgVHlwZXMpOworICB9CisgIExlZ2FsaXplUnVsZVNldCAmCisgIGN1c3RvbUZvckNhcnRlc2lhblByb2R1Y3Qoc3RkOjppbml0aWFsaXplcl9saXN0PExMVD4gVHlwZXMwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6aW5pdGlhbGl6ZXJfbGlzdDxMTFQ+IFR5cGVzMSkgeworICAgIHJldHVybiBhY3Rpb25Gb3JDYXJ0ZXNpYW5Qcm9kdWN0KExlZ2FsaXplQWN0aW9uOjpDdXN0b20sIFR5cGVzMCwgVHlwZXMxKTsKKyAgfQorCisgIC8vLyBXaWRlbiB0aGUgc2NhbGFyIHRvIHRoZSBuZXh0IHBvd2VyIG9mIHR3byB0aGF0IGlzIGF0IGxlYXN0IE1pblNpemUuCisgIC8vLyBObyBlZmZlY3QgaWYgdGhlIHR5cGUgaXMgbm90IGEgc2NhbGFyIG9yIGlzIGEgcG93ZXIgb2YgdHdvLgorICBMZWdhbGl6ZVJ1bGVTZXQgJndpZGVuU2NhbGFyVG9OZXh0UG93Mih1bnNpZ25lZCBUeXBlSWR4LCB1bnNpZ25lZCBNaW5TaXplID0gMCkgeworICAgIHVzaW5nIG5hbWVzcGFjZSBMZWdhbGl0eVByZWRpY2F0ZXM7CisgICAgcmV0dXJuIHdpZGVuU2NhbGFySWYoCisgICAgICAgIHNpemVOb3RQb3cyKFR5cGVJZHgpLAorICAgICAgICBMZWdhbGl6ZU11dGF0aW9uczo6d2lkZW5TY2FsYXJUb05leHRQb3cyKFR5cGVJZHgsIE1pblNpemUpKTsKKyAgfQorCisgIExlZ2FsaXplUnVsZVNldCAmbmFycm93U2NhbGFyKHVuc2lnbmVkIFR5cGVJZHgsIExlZ2FsaXplTXV0YXRpb24gTXV0YXRpb24pIHsKKyAgICB1c2luZyBuYW1lc3BhY2UgTGVnYWxpdHlQcmVkaWNhdGVzOworICAgIHJldHVybiBuYXJyb3dTY2FsYXJJZihpc1NjYWxhcihUeXBlSWR4KSwgTXV0YXRpb24pOworICB9CisKKyAgLy8vIEVuc3VyZSB0aGUgc2NhbGFyIGlzIGF0IGxlYXN0IGFzIHdpZGUgYXMgVHkuCisgIExlZ2FsaXplUnVsZVNldCAmbWluU2NhbGFyKHVuc2lnbmVkIFR5cGVJZHgsIGNvbnN0IExMVCAmVHkpIHsKKyAgICB1c2luZyBuYW1lc3BhY2UgTGVnYWxpdHlQcmVkaWNhdGVzOworICAgIHVzaW5nIG5hbWVzcGFjZSBMZWdhbGl6ZU11dGF0aW9uczsKKyAgICByZXR1cm4gd2lkZW5TY2FsYXJJZihuYXJyb3dlclRoYW4oVHlwZUlkeCwgVHkuZ2V0U2l6ZUluQml0cygpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VUbyhUeXBlSWR4LCBUeSkpOworICB9CisKKyAgLy8vIEVuc3VyZSB0aGUgc2NhbGFyIGlzIGF0IG1vc3QgYXMgd2lkZSBhcyBUeS4KKyAgTGVnYWxpemVSdWxlU2V0ICZtYXhTY2FsYXIodW5zaWduZWQgVHlwZUlkeCwgY29uc3QgTExUICZUeSkgeworICAgIHVzaW5nIG5hbWVzcGFjZSBMZWdhbGl0eVByZWRpY2F0ZXM7CisgICAgdXNpbmcgbmFtZXNwYWNlIExlZ2FsaXplTXV0YXRpb25zOworICAgIHJldHVybiBuYXJyb3dTY2FsYXJJZih3aWRlclRoYW4oVHlwZUlkeCwgVHkuZ2V0U2l6ZUluQml0cygpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlVG8oVHlwZUlkeCwgVHkpKTsKKyAgfQorCisgIC8vLyBDb25kaXRpb25hbGx5IGxpbWl0IHRoZSBtYXhpbXVtIHNpemUgb2YgdGhlIHNjYWxhci4KKyAgLy8vIEZvciBleGFtcGxlLCB3aGVuIHRoZSBtYXhpbXVtIHNpemUgb2Ygb25lIHR5cGUgZGVwZW5kcyBvbiB0aGUgc2l6ZSBvZgorICAvLy8gYW5vdGhlciBzdWNoIGFzIGV4dHJhY3RpbmcgTiBiaXRzIGZyb20gYW4gTSBiaXQgY29udGFpbmVyLgorICBMZWdhbGl6ZVJ1bGVTZXQgJm1heFNjYWxhcklmKExlZ2FsaXR5UHJlZGljYXRlIFByZWRpY2F0ZSwgdW5zaWduZWQgVHlwZUlkeCwgY29uc3QgTExUICZUeSkgeworICAgIHVzaW5nIG5hbWVzcGFjZSBMZWdhbGl0eVByZWRpY2F0ZXM7CisgICAgdXNpbmcgbmFtZXNwYWNlIExlZ2FsaXplTXV0YXRpb25zOworICAgIHJldHVybiBuYXJyb3dTY2FsYXJJZigKKyAgICAgICAgWz1dKGNvbnN0IExlZ2FsaXR5UXVlcnkgJlF1ZXJ5KSB7CisgICAgICAgICAgcmV0dXJuIHdpZGVyVGhhbihUeXBlSWR4LCBUeS5nZXRTaXplSW5CaXRzKCkpICYmCisgICAgICAgICAgICAgICAgIFByZWRpY2F0ZShRdWVyeSk7CisgICAgICAgIH0sCisgICAgICAgIGNoYW5nZVRvKFR5cGVJZHgsIFR5KSk7CisgIH0KKworICAvLy8gTGltaXQgdGhlIHJhbmdlIG9mIHNjYWxhciBzaXplcyB0byBNaW5UeSBhbmQgTWF4VHkuCisgIExlZ2FsaXplUnVsZVNldCAmY2xhbXBTY2FsYXIodW5zaWduZWQgVHlwZUlkeCwgY29uc3QgTExUICZNaW5UeSwgY29uc3QgTExUICZNYXhUeSkgeworICAgIGFzc2VydChNaW5UeS5pc1NjYWxhcigpICYmIE1heFR5LmlzU2NhbGFyKCkgJiYgIkV4cGVjdGVkIHNjYWxhciB0eXBlcyIpOworCisgICAgcmV0dXJuIG1pblNjYWxhcihUeXBlSWR4LCBNaW5UeSkKKyAgICAgICAgLm1heFNjYWxhcihUeXBlSWR4LCBNYXhUeSk7CisgIH0KKworICAvLy8gQWRkIG1vcmUgZWxlbWVudHMgdG8gdGhlIHZlY3RvciB0byByZWFjaCB0aGUgbmV4dCBwb3dlciBvZiB0d28uCisgIC8vLyBObyBlZmZlY3QgaWYgdGhlIHR5cGUgaXMgbm90IGEgdmVjdG9yIG9yIHRoZSBlbGVtZW50IGNvdW50IGlzIGEgcG93ZXIgb2YKKyAgLy8vIHR3by4KKyAgTGVnYWxpemVSdWxlU2V0ICZtb3JlRWxlbWVudHNUb05leHRQb3cyKHVuc2lnbmVkIFR5cGVJZHgpIHsKKyAgICB1c2luZyBuYW1lc3BhY2UgTGVnYWxpdHlQcmVkaWNhdGVzOworICAgIHJldHVybiBtb3JlRWxlbWVudHNJZihudW1FbGVtZW50c05vdFBvdzIoVHlwZUlkeCksCisgICAgICAgICAgICAgICAgICAgICAgICAgIExlZ2FsaXplTXV0YXRpb25zOjptb3JlRWxlbWVudHNUb05leHRQb3cyKFR5cGVJZHgpKTsKKyAgfQorCisgIC8vLyBMaW1pdCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIEVsdFR5IHZlY3RvcnMgdG8gYXQgbGVhc3QgTWluRWxlbWVudHMuCisgIExlZ2FsaXplUnVsZVNldCAmY2xhbXBNaW5OdW1FbGVtZW50cyh1bnNpZ25lZCBUeXBlSWR4LCBjb25zdCBMTFQgJkVsdFR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgTWluRWxlbWVudHMpIHsKKyAgICByZXR1cm4gbW9yZUVsZW1lbnRzSWYoCisgICAgICAgIFs9XShjb25zdCBMZWdhbGl0eVF1ZXJ5ICZRdWVyeSkgeworICAgICAgICAgIExMVCBWZWNUeSA9IFF1ZXJ5LlR5cGVzW1R5cGVJZHhdOworICAgICAgICAgIHJldHVybiBWZWNUeS5nZXRFbGVtZW50VHlwZSgpID09IEVsdFR5ICYmCisgICAgICAgICAgICAgICAgIFZlY1R5LmdldE51bUVsZW1lbnRzKCkgPCBNaW5FbGVtZW50czsKKyAgICAgICAgfSwKKyAgICAgICAgWz1dKGNvbnN0IExlZ2FsaXR5UXVlcnkgJlF1ZXJ5KSB7CisgICAgICAgICAgTExUIFZlY1R5ID0gUXVlcnkuVHlwZXNbVHlwZUlkeF07CisgICAgICAgICAgcmV0dXJuIHN0ZDo6bWFrZV9wYWlyKAorICAgICAgICAgICAgICBUeXBlSWR4LCBMTFQ6OnZlY3RvcihNaW5FbGVtZW50cywgVmVjVHkuZ2V0U2NhbGFyU2l6ZUluQml0cygpKSk7CisgICAgICAgIH0pOworICB9CisgIC8vLyBMaW1pdCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIEVsdFR5IHZlY3RvcnMgdG8gYXQgbW9zdCBNYXhFbGVtZW50cy4KKyAgTGVnYWxpemVSdWxlU2V0ICZjbGFtcE1heE51bUVsZW1lbnRzKHVuc2lnbmVkIFR5cGVJZHgsIGNvbnN0IExMVCAmRWx0VHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBNYXhFbGVtZW50cykgeworICAgIHJldHVybiBmZXdlckVsZW1lbnRzSWYoCisgICAgICAgIFs9XShjb25zdCBMZWdhbGl0eVF1ZXJ5ICZRdWVyeSkgeworICAgICAgICAgIExMVCBWZWNUeSA9IFF1ZXJ5LlR5cGVzW1R5cGVJZHhdOworICAgICAgICAgIHJldHVybiBWZWNUeS5nZXRFbGVtZW50VHlwZSgpID09IEVsdFR5ICYmCisgICAgICAgICAgICAgICAgIFZlY1R5LmdldE51bUVsZW1lbnRzKCkgPiBNYXhFbGVtZW50czsKKyAgICAgICAgfSwKKyAgICAgICAgWz1dKGNvbnN0IExlZ2FsaXR5UXVlcnkgJlF1ZXJ5KSB7CisgICAgICAgICAgTExUIFZlY1R5ID0gUXVlcnkuVHlwZXNbVHlwZUlkeF07CisgICAgICAgICAgcmV0dXJuIHN0ZDo6bWFrZV9wYWlyKAorICAgICAgICAgICAgICBUeXBlSWR4LCBMTFQ6OnZlY3RvcihNYXhFbGVtZW50cywgVmVjVHkuZ2V0U2NhbGFyU2l6ZUluQml0cygpKSk7CisgICAgICAgIH0pOworICB9CisgIC8vLyBMaW1pdCB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGZvciB0aGUgZ2l2ZW4gdmVjdG9ycyB0byBhdCBsZWFzdCBNaW5UeSdzCisgIC8vLyBudW1iZXIgb2YgZWxlbWVudHMgYW5kIGF0IG1vc3QgTWF4VHkncyBudW1iZXIgb2YgZWxlbWVudHMuCisgIC8vLworICAvLy8gTm8gZWZmZWN0IGlmIHRoZSB0eXBlIGlzIG5vdCBhIHZlY3RvciBvciBkb2VzIG5vdCBoYXZlIHRoZSBzYW1lIGVsZW1lbnQKKyAgLy8vIHR5cGUgYXMgdGhlIGNvbnN0cmFpbnRzLgorICAvLy8gVGhlIGVsZW1lbnQgdHlwZSBvZiBNaW5UeSBhbmQgTWF4VHkgbXVzdCBtYXRjaC4KKyAgTGVnYWxpemVSdWxlU2V0ICZjbGFtcE51bUVsZW1lbnRzKHVuc2lnbmVkIFR5cGVJZHgsIGNvbnN0IExMVCAmTWluVHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMTFQgJk1heFR5KSB7CisgICAgYXNzZXJ0KE1pblR5LmdldEVsZW1lbnRUeXBlKCkgPT0gTWF4VHkuZ2V0RWxlbWVudFR5cGUoKSAmJgorICAgICAgICAgICAiRXhwZWN0ZWQgZWxlbWVudCB0eXBlcyB0byBhZ3JlZSIpOworCisgICAgY29uc3QgTExUICZFbHRUeSA9IE1pblR5LmdldEVsZW1lbnRUeXBlKCk7CisgICAgcmV0dXJuIGNsYW1wTWluTnVtRWxlbWVudHMoVHlwZUlkeCwgRWx0VHksIE1pblR5LmdldE51bUVsZW1lbnRzKCkpCisgICAgICAgIC5jbGFtcE1heE51bUVsZW1lbnRzKFR5cGVJZHgsIEVsdFR5LCBNYXhUeS5nZXROdW1FbGVtZW50cygpKTsKKyAgfQorCisgIC8vLyBGYWxsYmFjayBvbiB0aGUgcHJldmlvdXMgaW1wbGVtZW50YXRpb24uIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCB3aGlsZQorICAvLy8gcG9ydGluZyBhIHJ1bGUuCisgIExlZ2FsaXplUnVsZVNldCAmZmFsbGJhY2soKSB7CisgICAgYWRkKHthbHdheXMsIExlZ2FsaXplQWN0aW9uOjpVc2VMZWdhY3lSdWxlc30pOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIC8vLyBBcHBseSB0aGUgcnVsZXNldCB0byB0aGUgZ2l2ZW4gTGVnYWxpdHlRdWVyeS4KKyAgTGVnYWxpemVBY3Rpb25TdGVwIGFwcGx5KGNvbnN0IExlZ2FsaXR5UXVlcnkgJlF1ZXJ5KSBjb25zdDsKK307CisKK2NsYXNzIExlZ2FsaXplckluZm8geworcHVibGljOgorICBMZWdhbGl6ZXJJbmZvKCk7CisgIHZpcnR1YWwgfkxlZ2FsaXplckluZm8oKSA9IGRlZmF1bHQ7CisKKyAgdW5zaWduZWQgZ2V0T3Bjb2RlSWR4Rm9yT3Bjb2RlKHVuc2lnbmVkIE9wY29kZSkgY29uc3Q7CisgIHVuc2lnbmVkIGdldEFjdGlvbkRlZmluaXRpb25zSWR4KHVuc2lnbmVkIE9wY29kZSkgY29uc3Q7CisKKyAgLy8vIENvbXB1dGUgYW55IGFuY2lsbGFyeSB0YWJsZXMgbmVlZGVkIHRvIHF1aWNrbHkgZGVjaWRlIGhvdyBhbiBvcGVyYXRpb24KKyAgLy8vIHNob3VsZCBiZSBoYW5kbGVkLiBUaGlzIG11c3QgYmUgY2FsbGVkIGFmdGVyIGFsbCAic2V0KkFjdGlvbiJtZXRob2RzIGJ1dAorICAvLy8gYmVmb3JlIGFueSBxdWVyeSBpcyBtYWRlIG9yIGluY29ycmVjdCByZXN1bHRzIG1heSBiZSByZXR1cm5lZC4KKyAgdm9pZCBjb21wdXRlVGFibGVzKCk7CisKKyAgc3RhdGljIGJvb2wgbmVlZHNMZWdhbGl6aW5nVG9EaWZmZXJlbnRTaXplKGNvbnN0IExlZ2FsaXplQWN0aW9uIEFjdGlvbikgeworICAgIHVzaW5nIG5hbWVzcGFjZSBMZWdhbGl6ZUFjdGlvbnM7CisgICAgc3dpdGNoIChBY3Rpb24pIHsKKyAgICBjYXNlIE5hcnJvd1NjYWxhcjoKKyAgICBjYXNlIFdpZGVuU2NhbGFyOgorICAgIGNhc2UgRmV3ZXJFbGVtZW50czoKKyAgICBjYXNlIE1vcmVFbGVtZW50czoKKyAgICBjYXNlIFVuc3VwcG9ydGVkOgorICAgICAgcmV0dXJuIHRydWU7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgIH0KKworICB1c2luZyBTaXplQW5kQWN0aW9uID0gc3RkOjpwYWlyPHVpbnQxNl90LCBMZWdhbGl6ZUFjdGlvbj47CisgIHVzaW5nIFNpemVBbmRBY3Rpb25zVmVjID0gc3RkOjp2ZWN0b3I8U2l6ZUFuZEFjdGlvbj47CisgIHVzaW5nIFNpemVDaGFuZ2VTdHJhdGVneSA9CisgICAgICBzdGQ6OmZ1bmN0aW9uPFNpemVBbmRBY3Rpb25zVmVjKGNvbnN0IFNpemVBbmRBY3Rpb25zVmVjICZ2KT47CisKKyAgLy8vIE1vcmUgZnJpZW5kbHkgd2F5IHRvIHNldCBhbiBhY3Rpb24gZm9yIGNvbW1vbiB0eXBlcyB0aGF0IGhhdmUgYW4gTExUCisgIC8vLyByZXByZXNlbnRhdGlvbi4KKyAgLy8vIFRoZSBMZWdhbGl6ZUFjdGlvbiBtdXN0IGJlIG9uZSBmb3Igd2hpY2ggTmVlZHNMZWdhbGl6aW5nVG9EaWZmZXJlbnRTaXplCisgIC8vLyByZXR1cm5zIGZhbHNlLgorICB2b2lkIHNldEFjdGlvbihjb25zdCBJbnN0ckFzcGVjdCAmQXNwZWN0LCBMZWdhbGl6ZUFjdGlvbiBBY3Rpb24pIHsKKyAgICBhc3NlcnQoIW5lZWRzTGVnYWxpemluZ1RvRGlmZmVyZW50U2l6ZShBY3Rpb24pKTsKKyAgICBUYWJsZXNJbml0aWFsaXplZCA9IGZhbHNlOworICAgIGNvbnN0IHVuc2lnbmVkIE9wY29kZUlkeCA9IEFzcGVjdC5PcGNvZGUgLSBGaXJzdE9wOworICAgIGlmIChTcGVjaWZpZWRBY3Rpb25zW09wY29kZUlkeF0uc2l6ZSgpIDw9IEFzcGVjdC5JZHgpCisgICAgICBTcGVjaWZpZWRBY3Rpb25zW09wY29kZUlkeF0ucmVzaXplKEFzcGVjdC5JZHggKyAxKTsKKyAgICBTcGVjaWZpZWRBY3Rpb25zW09wY29kZUlkeF1bQXNwZWN0LklkeF1bQXNwZWN0LlR5cGVdID0gQWN0aW9uOworICB9CisKKyAgLy8vIFRoZSBzZXRBY3Rpb24gY2FsbHMgcmVjb3JkIHRoZSBub24tc2l6ZS1jaGFuZ2luZyBsZWdhbGl6YXRpb24gYWN0aW9ucworICAvLy8gdG8gdGFrZSBvbiBzcGVjaWZpY2x5LXNpemVkIHR5cGVzLiBUaGUgU2l6ZUNoYW5nZVN0cmF0ZWd5IGRlZmluZXMgd2hhdAorICAvLy8gdG8gZG8gd2hlbiB0aGUgc2l6ZSBvZiB0aGUgdHlwZSBuZWVkcyB0byBiZSBjaGFuZ2VkIHRvIHJlYWNoIGEgbGVnYWxseQorICAvLy8gc2l6ZWQgdHlwZSAoaS5lLiwgb25lIHRoYXQgd2FzIGRlZmluZWQgdGhyb3VnaCBhIHNldEFjdGlvbiBjYWxsKS4KKyAgLy8vIGUuZy4KKyAgLy8vIHNldEFjdGlvbiAoe0dfQURELCAwLCBMTFQ6OnNjYWxhcigzMil9LCBMZWdhbCk7CisgIC8vLyBzZXRMZWdhbGl6ZVNjYWxhclRvRGlmZmVyZW50U2l6ZVN0cmF0ZWd5KAorICAvLy8gICBHX0FERCwgMCwgd2lkZW5Ub0xhcmdlclR5cGVzQW5kTmFycm93VG9MYXJnZXN0KTsKKyAgLy8vIHdpbGwgZW5kIHVwIGRlZmluaW5nIGdldEFjdGlvbih7R19BREQsIDAsIFR9KSB0byByZXR1cm4gdGhlIGZvbGxvd2luZyAKKyAgLy8vIGFjdGlvbnMgZm9yIGRpZmZlcmVudCBzY2FsYXIgdHlwZXMgVDoKKyAgLy8vICBMTFQ6OnNjYWxhcigxKS4uTExUOjpzY2FsYXIoMzEpOiB7V2lkZW5TY2FsYXIsIDAsIExMVDo6c2NhbGFyKDMyKX0KKyAgLy8vICBMTFQ6OnNjYWxhcigzMik6ICAgICAgICAgICAgICAgICB7TGVnYWwsIDAsIExMVDo6c2NhbGFyKDMyKX0KKyAgLy8vICBMTFQ6OnNjYWxhcigzMykuLjogICAgICAgICAgICAgICB7TmFycm93U2NhbGFyLCAwLCBMTFQ6OnNjYWxhcigzMil9CisgIC8vLworICAvLy8gSWYgbm8gU2l6ZUNoYW5nZUFjdGlvbiBnZXRzIGRlZmluZWQsIHRocm91Z2ggdGhpcyBmdW5jdGlvbiwKKyAgLy8vIHRoZSBkZWZhdWx0IGlzIHVuc3VwcG9ydGVkRm9yRGlmZmVyZW50U2l6ZXMuCisgIHZvaWQgc2V0TGVnYWxpemVTY2FsYXJUb0RpZmZlcmVudFNpemVTdHJhdGVneShjb25zdCB1bnNpZ25lZCBPcGNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBUeXBlSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2l6ZUNoYW5nZVN0cmF0ZWd5IFMpIHsKKyAgICBjb25zdCB1bnNpZ25lZCBPcGNvZGVJZHggPSBPcGNvZGUgLSBGaXJzdE9wOworICAgIGlmIChTY2FsYXJTaXplQ2hhbmdlU3RyYXRlZ2llc1tPcGNvZGVJZHhdLnNpemUoKSA8PSBUeXBlSWR4KQorICAgICAgU2NhbGFyU2l6ZUNoYW5nZVN0cmF0ZWdpZXNbT3Bjb2RlSWR4XS5yZXNpemUoVHlwZUlkeCArIDEpOworICAgIFNjYWxhclNpemVDaGFuZ2VTdHJhdGVnaWVzW09wY29kZUlkeF1bVHlwZUlkeF0gPSBTOworICB9CisKKyAgLy8vIFNlZSBhbHNvIHNldExlZ2FsaXplU2NhbGFyVG9EaWZmZXJlbnRTaXplU3RyYXRlZ3kuCisgIC8vLyBUaGlzIGZ1bmN0aW9uIGFsbG93cyB0byBzZXQgdGhlIFNpemVDaGFuZ2VTdHJhdGVneSBmb3IgdmVjdG9yIGVsZW1lbnRzLgorICB2b2lkIHNldExlZ2FsaXplVmVjdG9yRWxlbWVudFRvRGlmZmVyZW50U2l6ZVN0cmF0ZWd5KGNvbnN0IHVuc2lnbmVkIE9wY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBUeXBlSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNpemVDaGFuZ2VTdHJhdGVneSBTKSB7CisgICAgY29uc3QgdW5zaWduZWQgT3Bjb2RlSWR4ID0gT3Bjb2RlIC0gRmlyc3RPcDsKKyAgICBpZiAoVmVjdG9yRWxlbWVudFNpemVDaGFuZ2VTdHJhdGVnaWVzW09wY29kZUlkeF0uc2l6ZSgpIDw9IFR5cGVJZHgpCisgICAgICBWZWN0b3JFbGVtZW50U2l6ZUNoYW5nZVN0cmF0ZWdpZXNbT3Bjb2RlSWR4XS5yZXNpemUoVHlwZUlkeCArIDEpOworICAgIFZlY3RvckVsZW1lbnRTaXplQ2hhbmdlU3RyYXRlZ2llc1tPcGNvZGVJZHhdW1R5cGVJZHhdID0gUzsKKyAgfQorCisgIC8vLyBBIFNpemVDaGFuZ2VTdHJhdGVneSBmb3IgdGhlIGNvbW1vbiBjYXNlIHdoZXJlIGxlZ2FsaXphdGlvbiBmb3IgYSAKKyAgLy8vIHBhcnRpY3VsYXIgb3BlcmF0aW9uIGNvbnNpc3RzIG9mIG9ubHkgc3VwcG9ydGluZyBhIHNwZWNpZmljIHNldCBvZiB0eXBlCisgIC8vLyBzaXplcy4gRS5nLgorICAvLy8gICBzZXRBY3Rpb24gKHtHX0RJViwgMCwgTExUOjpzY2FsYXIoMzIpfSwgTGVnYWwpOworICAvLy8gICBzZXRBY3Rpb24gKHtHX0RJViwgMCwgTExUOjpzY2FsYXIoNjQpfSwgTGVnYWwpOworICAvLy8gICBzZXRMZWdhbGl6ZVNjYWxhclRvRGlmZmVyZW50U2l6ZVN0cmF0ZWd5KAorICAvLy8gICAgIEdfRElWLCAwLCB1bnN1cHBvcnRlZEZvckRpZmZlcmVudFNpemVzKTsKKyAgLy8vIHdpbGwgcmVzdWx0IGluIGdldEFjdGlvbih7R19ESVYsIDAsIFR9KSB0byByZXR1cm4gTGVnYWwgZm9yIHMzMiBhbmQgczY0LAorICAvLy8gYW5kIFVuc3VwcG9ydGVkIGZvciBhbGwgb3RoZXIgc2NhbGFyIHR5cGVzIFQuCisgIHN0YXRpYyBTaXplQW5kQWN0aW9uc1ZlYworICB1bnN1cHBvcnRlZEZvckRpZmZlcmVudFNpemVzKGNvbnN0IFNpemVBbmRBY3Rpb25zVmVjICZ2KSB7CisgICAgdXNpbmcgbmFtZXNwYWNlIExlZ2FsaXplQWN0aW9uczsKKyAgICByZXR1cm4gaW5jcmVhc2VUb0xhcmdlclR5cGVzQW5kRGVjcmVhc2VUb0xhcmdlc3QodiwgVW5zdXBwb3J0ZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuc3VwcG9ydGVkKTsKKyAgfQorCisgIC8vLyBBIFNpemVDaGFuZ2VTdHJhdGVneSBmb3IgdGhlIGNvbW1vbiBjYXNlIHdoZXJlIGxlZ2FsaXphdGlvbiBmb3IgYQorICAvLy8gcGFydGljdWxhciBvcGVyYXRpb24gY29uc2lzdHMgb2Ygd2lkZW5pbmcgdGhlIHR5cGUgdG8gYSBsYXJnZSBsZWdhbCB0eXBlLAorICAvLy8gdW5sZXNzIHRoZXJlIGlzIG5vIHN1Y2ggdHlwZSBhbmQgdGhlbiBpbnN0ZWFkIGl0IHNob3VsZCBiZSBuYXJyb3dlZCB0byB0aGUKKyAgLy8vIGxhcmdlc3QgbGVnYWwgdHlwZS4KKyAgc3RhdGljIFNpemVBbmRBY3Rpb25zVmVjCisgIHdpZGVuVG9MYXJnZXJUeXBlc0FuZE5hcnJvd1RvTGFyZ2VzdChjb25zdCBTaXplQW5kQWN0aW9uc1ZlYyAmdikgeworICAgIHVzaW5nIG5hbWVzcGFjZSBMZWdhbGl6ZUFjdGlvbnM7CisgICAgYXNzZXJ0KHYuc2l6ZSgpID4gMCAmJgorICAgICAgICAgICAiQXQgbGVhc3Qgb25lIHNpemUgdGhhdCBjYW4gYmUgbGVnYWxpemVkIHRvd2FyZHMgaXMgbmVlZGVkIgorICAgICAgICAgICAiIGZvciB0aGlzIFNpemVDaGFuZ2VTdHJhdGVneSIpOworICAgIHJldHVybiBpbmNyZWFzZVRvTGFyZ2VyVHlwZXNBbmREZWNyZWFzZVRvTGFyZ2VzdCh2LCBXaWRlblNjYWxhciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFycm93U2NhbGFyKTsKKyAgfQorCisgIHN0YXRpYyBTaXplQW5kQWN0aW9uc1ZlYworICB3aWRlblRvTGFyZ2VyVHlwZXNVbnN1cHBvcnRlZE90aGVyd2lzZShjb25zdCBTaXplQW5kQWN0aW9uc1ZlYyAmdikgeworICAgIHVzaW5nIG5hbWVzcGFjZSBMZWdhbGl6ZUFjdGlvbnM7CisgICAgcmV0dXJuIGluY3JlYXNlVG9MYXJnZXJUeXBlc0FuZERlY3JlYXNlVG9MYXJnZXN0KHYsIFdpZGVuU2NhbGFyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbnN1cHBvcnRlZCk7CisgIH0KKworICBzdGF0aWMgU2l6ZUFuZEFjdGlvbnNWZWMKKyAgbmFycm93VG9TbWFsbGVyQW5kVW5zdXBwb3J0ZWRJZlRvb1NtYWxsKGNvbnN0IFNpemVBbmRBY3Rpb25zVmVjICZ2KSB7CisgICAgdXNpbmcgbmFtZXNwYWNlIExlZ2FsaXplQWN0aW9uczsKKyAgICByZXR1cm4gZGVjcmVhc2VUb1NtYWxsZXJUeXBlc0FuZEluY3JlYXNlVG9TbWFsbGVzdCh2LCBOYXJyb3dTY2FsYXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5zdXBwb3J0ZWQpOworICB9CisKKyAgc3RhdGljIFNpemVBbmRBY3Rpb25zVmVjCisgIG5hcnJvd1RvU21hbGxlckFuZFdpZGVuVG9TbWFsbGVzdChjb25zdCBTaXplQW5kQWN0aW9uc1ZlYyAmdikgeworICAgIHVzaW5nIG5hbWVzcGFjZSBMZWdhbGl6ZUFjdGlvbnM7CisgICAgYXNzZXJ0KHYuc2l6ZSgpID4gMCAmJgorICAgICAgICAgICAiQXQgbGVhc3Qgb25lIHNpemUgdGhhdCBjYW4gYmUgbGVnYWxpemVkIHRvd2FyZHMgaXMgbmVlZGVkIgorICAgICAgICAgICAiIGZvciB0aGlzIFNpemVDaGFuZ2VTdHJhdGVneSIpOworICAgIHJldHVybiBkZWNyZWFzZVRvU21hbGxlclR5cGVzQW5kSW5jcmVhc2VUb1NtYWxsZXN0KHYsIE5hcnJvd1NjYWxhciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaWRlblNjYWxhcik7CisgIH0KKworICAvLy8gQSBTaXplQ2hhbmdlU3RyYXRlZ3kgZm9yIHRoZSBjb21tb24gY2FzZSB3aGVyZSBsZWdhbGl6YXRpb24gZm9yIGEKKyAgLy8vIHBhcnRpY3VsYXIgdmVjdG9yIG9wZXJhdGlvbiBjb25zaXN0cyBvZiBoYXZpbmcgbW9yZSBlbGVtZW50cyBpbiB0aGUKKyAgLy8vIHZlY3RvciwgdG8gYSB0eXBlIHRoYXQgaXMgbGVnYWwuIFVubGVzcyB0aGVyZSBpcyBubyBzdWNoIHR5cGUgYW5kIHRoZW4KKyAgLy8vIGluc3RlYWQgaXQgc2hvdWxkIGJlIGxlZ2FsaXplZCB0b3dhcmRzIHRoZSB3aWRlc3QgdmVjdG9yIHRoYXQncyBzdGlsbAorICAvLy8gbGVnYWwuIEUuZy4KKyAgLy8vICAgc2V0QWN0aW9uKHtHX0FERCwgTExUOjp2ZWN0b3IoOCwgOCl9LCBMZWdhbCk7CisgIC8vLyAgIHNldEFjdGlvbih7R19BREQsIExMVDo6dmVjdG9yKDE2LCA4KX0sIExlZ2FsKTsKKyAgLy8vICAgc2V0QWN0aW9uKHtHX0FERCwgTExUOjp2ZWN0b3IoMiwgMzIpfSwgTGVnYWwpOworICAvLy8gICBzZXRBY3Rpb24oe0dfQURELCBMTFQ6OnZlY3Rvcig0LCAzMil9LCBMZWdhbCk7CisgIC8vLyAgIHNldExlZ2FsaXplVmVjdG9yRWxlbWVudFRvRGlmZmVyZW50U2l6ZVN0cmF0ZWd5KAorICAvLy8gICAgIEdfQURELCAwLCBtb3JlVG9XaWRlclR5cGVzQW5kTGVzc1RvV2lkZXN0KTsKKyAgLy8vIHdpbGwgcmVzdWx0IGluIHRoZSBmb2xsb3dpbmcgZ2V0QWN0aW9uIHJlc3VsdHM6CisgIC8vLyAgICogZ2V0QWN0aW9uKHtHX0FERCwgTExUOjp2ZWN0b3IoOCw4KX0pIHJldHVybnMKKyAgLy8vICAgICAgIChMZWdhbCwgdmVjdG9yKDgsOCkpLgorICAvLy8gICAqIGdldEFjdGlvbih7R19BREQsIExMVDo6dmVjdG9yKDksOCl9KSByZXR1cm5zCisgIC8vLyAgICAgICAoTW9yZUVsZW1lbnRzLCB2ZWN0b3IoMTYsOCkpLgorICAvLy8gICAqIGdldEFjdGlvbih7R19BREQsIExMVDo6dmVjdG9yKDgsMzIpfSkgcmV0dXJucworICAvLy8gICAgICAgKEZld2VyRWxlbWVudHMsIHZlY3Rvcig0LDMyKSkuCisgIHN0YXRpYyBTaXplQW5kQWN0aW9uc1ZlYworICBtb3JlVG9XaWRlclR5cGVzQW5kTGVzc1RvV2lkZXN0KGNvbnN0IFNpemVBbmRBY3Rpb25zVmVjICZ2KSB7CisgICAgdXNpbmcgbmFtZXNwYWNlIExlZ2FsaXplQWN0aW9uczsKKyAgICByZXR1cm4gaW5jcmVhc2VUb0xhcmdlclR5cGVzQW5kRGVjcmVhc2VUb0xhcmdlc3QodiwgTW9yZUVsZW1lbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGZXdlckVsZW1lbnRzKTsKKyAgfQorCisgIC8vLyBIZWxwZXIgZnVuY3Rpb24gdG8gaW1wbGVtZW50IG1hbnkgdHlwaWNhbCBTaXplQ2hhbmdlU3RyYXRlZ3kgZnVuY3Rpb25zLgorICBzdGF0aWMgU2l6ZUFuZEFjdGlvbnNWZWMKKyAgaW5jcmVhc2VUb0xhcmdlclR5cGVzQW5kRGVjcmVhc2VUb0xhcmdlc3QoY29uc3QgU2l6ZUFuZEFjdGlvbnNWZWMgJnYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExlZ2FsaXplQWN0aW9uIEluY3JlYXNlQWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMZWdhbGl6ZUFjdGlvbiBEZWNyZWFzZUFjdGlvbik7CisgIC8vLyBIZWxwZXIgZnVuY3Rpb24gdG8gaW1wbGVtZW50IG1hbnkgdHlwaWNhbCBTaXplQ2hhbmdlU3RyYXRlZ3kgZnVuY3Rpb25zLgorICBzdGF0aWMgU2l6ZUFuZEFjdGlvbnNWZWMKKyAgZGVjcmVhc2VUb1NtYWxsZXJUeXBlc0FuZEluY3JlYXNlVG9TbWFsbGVzdChjb25zdCBTaXplQW5kQWN0aW9uc1ZlYyAmdiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMZWdhbGl6ZUFjdGlvbiBEZWNyZWFzZUFjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMZWdhbGl6ZUFjdGlvbiBJbmNyZWFzZUFjdGlvbik7CisKKyAgLy8vIEdldCB0aGUgYWN0aW9uIGRlZmluaXRpb25zIGZvciB0aGUgZ2l2ZW4gb3Bjb2RlLiBVc2UgdGhpcyB0byBydW4gYQorICAvLy8gTGVnYWxpdHlRdWVyeSB0aHJvdWdoIHRoZSBkZWZpbml0aW9ucy4KKyAgY29uc3QgTGVnYWxpemVSdWxlU2V0ICZnZXRBY3Rpb25EZWZpbml0aW9ucyh1bnNpZ25lZCBPcGNvZGUpIGNvbnN0OworCisgIC8vLyBHZXQgdGhlIGFjdGlvbiBkZWZpbml0aW9uIGJ1aWxkZXIgZm9yIHRoZSBnaXZlbiBvcGNvZGUuIFVzZSB0aGlzIHRvIGRlZmluZQorICAvLy8gdGhlIGFjdGlvbiBkZWZpbml0aW9ucy4KKyAgLy8vCisgIC8vLyBJdCBpcyBhbiBlcnJvciB0byByZXF1ZXN0IGFuIG9wY29kZSB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gcmVxdWVzdGVkIGJ5IHRoZQorICAvLy8gbXVsdGlwbGUtb3Bjb2RlIHZhcmlhbnQuCisgIExlZ2FsaXplUnVsZVNldCAmZ2V0QWN0aW9uRGVmaW5pdGlvbnNCdWlsZGVyKHVuc2lnbmVkIE9wY29kZSk7CisKKyAgLy8vIEdldCB0aGUgYWN0aW9uIGRlZmluaXRpb24gYnVpbGRlciBmb3IgdGhlIGdpdmVuIHNldCBvZiBvcGNvZGVzLiBVc2UgdGhpcworICAvLy8gdG8gZGVmaW5lIHRoZSBhY3Rpb24gZGVmaW5pdGlvbnMgZm9yIG11bHRpcGxlIG9wY29kZXMgYXQgb25jZS4gVGhlIGZpcnN0CisgIC8vLyBvcGNvZGUgZ2l2ZW4gd2lsbCBiZSBjb25zaWRlcmVkIHRoZSByZXByZXNlbnRhdGl2ZSBvcGNvZGUgYW5kIHdpbGwgaG9sZAorICAvLy8gdGhlIGRlZmluaXRpb25zIHdoZXJlYXMgdGhlIG90aGVyIG9wY29kZXMgd2lsbCBiZSBjb25maWd1cmVkIHRvIHJlZmVyIHRvCisgIC8vLyB0aGUgcmVwcmVzZW50YXRpdmUgb3Bjb2RlLiBUaGlzIGxvd2VycyBtZW1vcnkgcmVxdWlyZW1lbnRzIGFuZCB2ZXJ5CisgIC8vLyBzbGlnaHRseSBpbXByb3ZlcyBwZXJmb3JtYW5jZS4KKyAgLy8vCisgIC8vLyBJdCB3b3VsZCBiZSB2ZXJ5IGVhc3kgdG8gaW50cm9kdWNlIHVuZXhwZWN0ZWQgc2lkZS1lZmZlY3RzIGFzIGEgcmVzdWx0IG9mCisgIC8vLyB0aGlzIGFsaWFzaW5nIGlmIGl0IHdlcmUgcGVybWl0dGVkIHRvIHJlcXVlc3QgZGlmZmVyZW50IGJ1dCBpbnRlcnNlY3RpbmcKKyAgLy8vIHNldHMgb2Ygb3Bjb2RlcyBidXQgdGhhdCBpcyBkaWZmaWN1bHQgdG8ga2VlcCB0cmFjayBvZi4gSXQgaXMgdGhlcmVmb3JlIGFuCisgIC8vLyBlcnJvciB0byByZXF1ZXN0IHRoZSBzYW1lIG9wY29kZSB0d2ljZSB1c2luZyB0aGlzIEFQSSwgdG8gcmVxdWVzdCBhbgorICAvLy8gb3Bjb2RlIHRoYXQgYWxyZWFkeSBoYXMgZGVmaW5pdGlvbnMsIG9yIHRvIHVzZSB0aGUgc2luZ2xlLW9wY29kZSBBUEkgb24gYW4KKyAgLy8vIG9wY29kZSB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gcmVxdWVzdGVkIGJ5IHRoaXMgQVBJLgorICBMZWdhbGl6ZVJ1bGVTZXQgJgorICBnZXRBY3Rpb25EZWZpbml0aW9uc0J1aWxkZXIoc3RkOjppbml0aWFsaXplcl9saXN0PHVuc2lnbmVkPiBPcGNvZGVzKTsKKyAgdm9pZCBhbGlhc0FjdGlvbkRlZmluaXRpb25zKHVuc2lnbmVkIE9wY29kZVRvLCB1bnNpZ25lZCBPcGNvZGVGcm9tKTsKKworICAvLy8gRGV0ZXJtaW5lIHdoYXQgYWN0aW9uIHNob3VsZCBiZSB0YWtlbiB0byBsZWdhbGl6ZSB0aGUgZGVzY3JpYmVkCisgIC8vLyBpbnN0cnVjdGlvbi4gUmVxdWlyZXMgY29tcHV0ZVRhYmxlcyB0byBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8KKyAgLy8vIFxyZXR1cm5zIGEgZGVzY3JpcHRpb24gb2YgdGhlIG5leHQgbGVnYWxpemF0aW9uIHN0ZXAgdG8gcGVyZm9ybS4KKyAgTGVnYWxpemVBY3Rpb25TdGVwIGdldEFjdGlvbihjb25zdCBMZWdhbGl0eVF1ZXJ5ICZRdWVyeSkgY29uc3Q7CisKKyAgLy8vIERldGVybWluZSB3aGF0IGFjdGlvbiBzaG91bGQgYmUgdGFrZW4gdG8gbGVnYWxpemUgdGhlIGdpdmVuIGdlbmVyaWMKKyAgLy8vIGluc3RydWN0aW9uLgorICAvLy8KKyAgLy8vIFxyZXR1cm5zIGEgZGVzY3JpcHRpb24gb2YgdGhlIG5leHQgbGVnYWxpemF0aW9uIHN0ZXAgdG8gcGVyZm9ybS4KKyAgTGVnYWxpemVBY3Rpb25TdGVwIGdldEFjdGlvbihjb25zdCBNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSkgY29uc3Q7CisKKyAgYm9vbCBpc0xlZ2FsKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUksIGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSkgY29uc3Q7CisKKyAgdmlydHVhbCBib29sIGxlZ2FsaXplQ3VzdG9tKE1hY2hpbmVJbnN0ciAmTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSVJCdWlsZGVyICZNSVJCdWlsZGVyKSBjb25zdDsKKworcHJpdmF0ZToKKyAgLy8vIERldGVybWluZSB3aGF0IGFjdGlvbiBzaG91bGQgYmUgdGFrZW4gdG8gbGVnYWxpemUgdGhlIGdpdmVuIGdlbmVyaWMKKyAgLy8vIGluc3RydWN0aW9uIG9wY29kZSwgdHlwZS1pbmRleCBhbmQgdHlwZS4gUmVxdWlyZXMgY29tcHV0ZVRhYmxlcyB0byBoYXZlCisgIC8vLyBiZWVuIGNhbGxlZC4KKyAgLy8vCisgIC8vLyBccmV0dXJucyBhIHBhaXIgY29uc2lzdGluZyBvZiB0aGUga2luZCBvZiBsZWdhbGl6YXRpb24gdGhhdCBzaG91bGQgYmUKKyAgLy8vIHBlcmZvcm1lZCBhbmQgdGhlIGRlc3RpbmF0aW9uIHR5cGUuCisgIHN0ZDo6cGFpcjxMZWdhbGl6ZUFjdGlvbiwgTExUPgorICBnZXRBc3BlY3RBY3Rpb24oY29uc3QgSW5zdHJBc3BlY3QgJkFzcGVjdCkgY29uc3Q7CisKKyAgLy8vIFRoZSBTaXplQW5kQWN0aW9uc1ZlYyBpcyBhIHJlcHJlc2VudGF0aW9uIG1hcHBpbmcgYmV0d2VlbiBhbGwgbmF0dXJhbAorICAvLy8gbnVtYmVycyBhbmQgYW4gQWN0aW9uLiBUaGUgbmF0dXJhbCBudW1iZXIgcmVwcmVzZW50cyB0aGUgYml0IHNpemUgb2YKKyAgLy8vIHRoZSBJbnN0ckFzcGVjdC4gRm9yIGV4YW1wbGUsIGZvciBhIHRhcmdldCB3aXRoIG5hdGl2ZSBzdXBwb3J0IGZvciAzMi1iaXQKKyAgLy8vIGFuZCA2NC1iaXQgYWRkaXRpb25zLCB5b3UnZCBleHByZXNzIHRoYXQgYXM6CisgIC8vLyBzZXRTY2FsYXJBY3Rpb24oR19BREQsIDAsCisgIC8vLyAgICAgICAgICAge3sxLCBXaWRlblNjYWxhcn0sICAvLyBiaXQgc2l6ZXMgWyAxLCAzMVsKKyAgLy8vICAgICAgICAgICAgezMyLCBMZWdhbH0sICAgICAgIC8vIGJpdCBzaXplcyBbMzIsIDMzWworICAvLy8gICAgICAgICAgICB7MzMsIFdpZGVuU2NhbGFyfSwgLy8gYml0IHNpemVzIFszMywgNjRbCisgIC8vLyAgICAgICAgICAgIHs2NCwgTGVnYWx9LCAgICAgICAvLyBiaXQgc2l6ZXMgWzY0LCA2NVsKKyAgLy8vICAgICAgICAgICAgezY1LCBOYXJyb3dTY2FsYXJ9IC8vIGJpdCBzaXplcyBbNjUsICtpbmZbCisgIC8vLyAgICAgICAgICAgfSk7CisgIC8vLyBJdCBtYXkgYmUgdGhhdCBvbmx5IDY0LWJpdCBwb2ludGVycyBhcmUgc3VwcG9ydGVkIG9uIHlvdXIgdGFyZ2V0OgorICAvLy8gc2V0UG9pbnRlckFjdGlvbihHX0dFUCwgMCwgTExUOnBvaW50ZXIoMSksCisgIC8vLyAgICAgICAgICAge3sxLCBVbnN1cHBvcnRlZH0sICAvLyBiaXQgc2l6ZXMgWyAxLCA2M1sKKyAgLy8vICAgICAgICAgICAgezY0LCBMZWdhbH0sICAgICAgIC8vIGJpdCBzaXplcyBbNjQsIDY1WworICAvLy8gICAgICAgICAgICB7NjUsIFVuc3VwcG9ydGVkfSwgLy8gYml0IHNpemVzIFs2NSwgK2luZlsKKyAgLy8vICAgICAgICAgICB9KTsKKyAgdm9pZCBzZXRTY2FsYXJBY3Rpb24oY29uc3QgdW5zaWduZWQgT3Bjb2RlLCBjb25zdCB1bnNpZ25lZCBUeXBlSW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNpemVBbmRBY3Rpb25zVmVjICZTaXplQW5kQWN0aW9ucykgeworICAgIGNvbnN0IHVuc2lnbmVkIE9wY29kZUlkeCA9IE9wY29kZSAtIEZpcnN0T3A7CisgICAgU21hbGxWZWN0b3I8U2l6ZUFuZEFjdGlvbnNWZWMsIDE+ICZBY3Rpb25zID0gU2NhbGFyQWN0aW9uc1tPcGNvZGVJZHhdOworICAgIHNldEFjdGlvbnMoVHlwZUluZGV4LCBBY3Rpb25zLCBTaXplQW5kQWN0aW9ucyk7CisgIH0KKyAgdm9pZCBzZXRQb2ludGVyQWN0aW9uKGNvbnN0IHVuc2lnbmVkIE9wY29kZSwgY29uc3QgdW5zaWduZWQgVHlwZUluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgQWRkcmVzc1NwYWNlLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2l6ZUFuZEFjdGlvbnNWZWMgJlNpemVBbmRBY3Rpb25zKSB7CisgICAgY29uc3QgdW5zaWduZWQgT3Bjb2RlSWR4ID0gT3Bjb2RlIC0gRmlyc3RPcDsKKyAgICBpZiAoQWRkclNwYWNlMlBvaW50ZXJBY3Rpb25zW09wY29kZUlkeF0uZmluZChBZGRyZXNzU3BhY2UpID09CisgICAgICAgIEFkZHJTcGFjZTJQb2ludGVyQWN0aW9uc1tPcGNvZGVJZHhdLmVuZCgpKQorICAgICAgQWRkclNwYWNlMlBvaW50ZXJBY3Rpb25zW09wY29kZUlkeF1bQWRkcmVzc1NwYWNlXSA9IHt7fX07CisgICAgU21hbGxWZWN0b3I8U2l6ZUFuZEFjdGlvbnNWZWMsIDE+ICZBY3Rpb25zID0KKyAgICAgICAgQWRkclNwYWNlMlBvaW50ZXJBY3Rpb25zW09wY29kZUlkeF0uZmluZChBZGRyZXNzU3BhY2UpLT5zZWNvbmQ7CisgICAgc2V0QWN0aW9ucyhUeXBlSW5kZXgsIEFjdGlvbnMsIFNpemVBbmRBY3Rpb25zKTsKKyAgfQorCisgIC8vLyBJZiBhbiBvcGVyYXRpb24gb24gYSBnaXZlbiB2ZWN0b3IgdHlwZSAoc2F5IDxNIHggaU4+KSBpc24ndCBleHBsaWNpdGx5CisgIC8vLyBzcGVjaWZpZWQsIHdlIHByb2NlZWQgaW4gMiBzdGFnZXMuIEZpcnN0IHdlIGxlZ2FsaXplIHRoZSB1bmRlcmx5aW5nIHNjYWxhcgorICAvLy8gKHNvIHRoYXQgdGhlcmUncyBhdCBsZWFzdCBvbmUgbGVnYWwgdmVjdG9yIHdpdGggdGhhdCBzY2FsYXIpLCB0aGVuIHdlCisgIC8vLyBhZGp1c3QgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgdmVjdG9yIHNvIHRoYXQgaXQgaXMgbGVnYWwuIFRoZQorICAvLy8gZGVzaXJlZCBhY3Rpb24gaW4gdGhlIGZpcnN0IHN0ZXAgaXMgY29udHJvbGxlZCBieSB0aGlzIGZ1bmN0aW9uLgorICB2b2lkIHNldFNjYWxhckluVmVjdG9yQWN0aW9uKGNvbnN0IHVuc2lnbmVkIE9wY29kZSwgY29uc3QgdW5zaWduZWQgVHlwZUluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNpemVBbmRBY3Rpb25zVmVjICZTaXplQW5kQWN0aW9ucykgeworICAgIHVuc2lnbmVkIE9wY29kZUlkeCA9IE9wY29kZSAtIEZpcnN0T3A7CisgICAgU21hbGxWZWN0b3I8U2l6ZUFuZEFjdGlvbnNWZWMsIDE+ICZBY3Rpb25zID0KKyAgICAgICAgU2NhbGFySW5WZWN0b3JBY3Rpb25zW09wY29kZUlkeF07CisgICAgc2V0QWN0aW9ucyhUeXBlSW5kZXgsIEFjdGlvbnMsIFNpemVBbmRBY3Rpb25zKTsKKyAgfQorCisgIC8vLyBTZWUgYWxzbyBzZXRTY2FsYXJJblZlY3RvckFjdGlvbi4KKyAgLy8vIFRoaXMgZnVuY3Rpb24gbGV0J3MgeW91IHNwZWNpZnkgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiBhIHZlY3RvciB0aGF0CisgIC8vLyBhcmUgbGVnYWwgZm9yIGEgbGVnYWwgZWxlbWVudCBzaXplLgorICB2b2lkIHNldFZlY3Rvck51bUVsZW1lbnRBY3Rpb24oY29uc3QgdW5zaWduZWQgT3Bjb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgVHlwZUluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgRWxlbWVudFNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTaXplQW5kQWN0aW9uc1ZlYyAmU2l6ZUFuZEFjdGlvbnMpIHsKKyAgICBjb25zdCB1bnNpZ25lZCBPcGNvZGVJZHggPSBPcGNvZGUgLSBGaXJzdE9wOworICAgIGlmIChOdW1FbGVtZW50czJBY3Rpb25zW09wY29kZUlkeF0uZmluZChFbGVtZW50U2l6ZSkgPT0KKyAgICAgICAgTnVtRWxlbWVudHMyQWN0aW9uc1tPcGNvZGVJZHhdLmVuZCgpKQorICAgICAgTnVtRWxlbWVudHMyQWN0aW9uc1tPcGNvZGVJZHhdW0VsZW1lbnRTaXplXSA9IHt7fX07CisgICAgU21hbGxWZWN0b3I8U2l6ZUFuZEFjdGlvbnNWZWMsIDE+ICZBY3Rpb25zID0KKyAgICAgICAgTnVtRWxlbWVudHMyQWN0aW9uc1tPcGNvZGVJZHhdLmZpbmQoRWxlbWVudFNpemUpLT5zZWNvbmQ7CisgICAgc2V0QWN0aW9ucyhUeXBlSW5kZXgsIEFjdGlvbnMsIFNpemVBbmRBY3Rpb25zKTsKKyAgfQorCisgIC8vLyBBIHBhcnRpYWwgU2l6ZUFuZEFjdGlvbnNWZWMgcG90ZW50aWFsbHkgZG9lc24ndCBjb3ZlciBhbGwgYml0IHNpemVzLAorICAvLy8gaS5lLiBpdCdzIE9LIGlmIGl0IGRvZXNuJ3Qgc3RhcnQgZnJvbSBzaXplIDEuCisgIHN0YXRpYyB2b2lkIGNoZWNrUGFydGlhbFNpemVBbmRBY3Rpb25zVmVjdG9yKGNvbnN0IFNpemVBbmRBY3Rpb25zVmVjJiB2KSB7CisgICAgdXNpbmcgbmFtZXNwYWNlIExlZ2FsaXplQWN0aW9uczsKKyNpZm5kZWYgTkRFQlVHCisgICAgLy8gVGhlIHNpemVzIHNob3VsZCBiZSBpbiBpbmNyZWFzaW5nIG9yZGVyCisgICAgaW50IHByZXZfc2l6ZSA9IC0xOworICAgIGZvcihhdXRvIFNpemVBbmRBY3Rpb246IHYpIHsKKyAgICAgIGFzc2VydChTaXplQW5kQWN0aW9uLmZpcnN0ID4gcHJldl9zaXplKTsKKyAgICAgIHByZXZfc2l6ZSA9IFNpemVBbmRBY3Rpb24uZmlyc3Q7CisgICAgfQorICAgIC8vIC0gZm9yIGV2ZXJ5IFdpZGVuIGFjdGlvbiwgdGhlcmUgc2hvdWxkIGJlIGEgbGFyZ2VyIGJpdHNpemUgdGhhdAorICAgIC8vICAgY2FuIGJlIGxlZ2FsaXplZCB0b3dhcmRzIChlLmcuIExlZ2FsLCBMb3dlciwgTGliY2FsbCBvciBDdXN0b20KKyAgICAvLyAgIGFjdGlvbikuCisgICAgLy8gLSBmb3IgZXZlcnkgTmFycm93IGFjdGlvbiwgdGhlcmUgc2hvdWxkIGJlIGEgc21hbGxlciBiaXRzaXplIHRoYXQKKyAgICAvLyAgIGNhbiBiZSBsZWdhbGl6ZWQgdG93YXJkcy4KKyAgICBpbnQgU21hbGxlc3ROYXJyb3dJZHggPSAtMTsKKyAgICBpbnQgTGFyZ2VzdFdpZGVuSWR4ID0gLTE7CisgICAgaW50IFNtYWxsZXN0TGVnYWxpemFibGVUb1NhbWVTaXplSWR4ID0gLTE7CisgICAgaW50IExhcmdlc3RMZWdhbGl6YWJsZVRvU2FtZVNpemVJZHggPSAtMTsKKyAgICBmb3Ioc2l6ZV90IGk9MDsgaTx2LnNpemUoKTsgKytpKSB7CisgICAgICBzd2l0Y2ggKHZbaV0uc2Vjb25kKSB7CisgICAgICAgIGNhc2UgRmV3ZXJFbGVtZW50czoKKyAgICAgICAgY2FzZSBOYXJyb3dTY2FsYXI6CisgICAgICAgICAgaWYgKFNtYWxsZXN0TmFycm93SWR4ID09IC0xKQorICAgICAgICAgICAgU21hbGxlc3ROYXJyb3dJZHggPSBpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFdpZGVuU2NhbGFyOgorICAgICAgICBjYXNlIE1vcmVFbGVtZW50czoKKyAgICAgICAgICBMYXJnZXN0V2lkZW5JZHggPSBpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFVuc3VwcG9ydGVkOgorICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgIGlmIChTbWFsbGVzdExlZ2FsaXphYmxlVG9TYW1lU2l6ZUlkeCA9PSAtMSkKKyAgICAgICAgICAgIFNtYWxsZXN0TGVnYWxpemFibGVUb1NhbWVTaXplSWR4ID0gaTsKKyAgICAgICAgICBMYXJnZXN0TGVnYWxpemFibGVUb1NhbWVTaXplSWR4ID0gaTsKKyAgICAgIH0KKyAgICB9CisgICAgaWYgKFNtYWxsZXN0TmFycm93SWR4ICE9IC0xKSB7CisgICAgICBhc3NlcnQoU21hbGxlc3RMZWdhbGl6YWJsZVRvU2FtZVNpemVJZHggIT0gLTEpOworICAgICAgYXNzZXJ0KFNtYWxsZXN0TmFycm93SWR4ID4gU21hbGxlc3RMZWdhbGl6YWJsZVRvU2FtZVNpemVJZHgpOworICAgIH0KKyAgICBpZiAoTGFyZ2VzdFdpZGVuSWR4ICE9IC0xKQorICAgICAgYXNzZXJ0KExhcmdlc3RXaWRlbklkeCA8IExhcmdlc3RMZWdhbGl6YWJsZVRvU2FtZVNpemVJZHgpOworI2VuZGlmCisgIH0KKworICAvLy8gQSBmdWxsIFNpemVBbmRBY3Rpb25zVmVjIG11c3QgY292ZXIgYWxsIGJpdCBzaXplcywgaS5lLiBtdXN0IHN0YXJ0IHdpdGgKKyAgLy8vIGZyb20gc2l6ZSAxLgorICBzdGF0aWMgdm9pZCBjaGVja0Z1bGxTaXplQW5kQWN0aW9uc1ZlY3Rvcihjb25zdCBTaXplQW5kQWN0aW9uc1ZlYyYgdikgeworI2lmbmRlZiBOREVCVUcKKyAgICAvLyBEYXRhIHN0cnVjdHVyZSBpbnZhcmlhbnQ6IFRoZSBmaXJzdCBiaXQgc2l6ZSBtdXN0IGJlIHNpemUgMS4KKyAgICBhc3NlcnQodi5zaXplKCkgPj0gMSk7CisgICAgYXNzZXJ0KHZbMF0uZmlyc3QgPT0gMSk7CisgICAgY2hlY2tQYXJ0aWFsU2l6ZUFuZEFjdGlvbnNWZWN0b3Iodik7CisjZW5kaWYKKyAgfQorCisgIC8vLyBTZXRzIGFjdGlvbnMgZm9yIGFsbCBiaXQgc2l6ZXMgb24gYSBwYXJ0aWN1bGFyIGdlbmVyaWMgb3Bjb2RlLCB0eXBlCisgIC8vLyBpbmRleCBhbmQgc2NhbGFyIG9yIHBvaW50ZXIgdHlwZS4KKyAgdm9pZCBzZXRBY3Rpb25zKHVuc2lnbmVkIFR5cGVJbmRleCwKKyAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9yPFNpemVBbmRBY3Rpb25zVmVjLCAxPiAmQWN0aW9ucywKKyAgICAgICAgICAgICAgICAgIGNvbnN0IFNpemVBbmRBY3Rpb25zVmVjICZTaXplQW5kQWN0aW9ucykgeworICAgIGNoZWNrRnVsbFNpemVBbmRBY3Rpb25zVmVjdG9yKFNpemVBbmRBY3Rpb25zKTsKKyAgICBpZiAoQWN0aW9ucy5zaXplKCkgPD0gVHlwZUluZGV4KQorICAgICAgQWN0aW9ucy5yZXNpemUoVHlwZUluZGV4ICsgMSk7CisgICAgQWN0aW9uc1tUeXBlSW5kZXhdID0gU2l6ZUFuZEFjdGlvbnM7CisgIH0KKworICBzdGF0aWMgU2l6ZUFuZEFjdGlvbiBmaW5kQWN0aW9uKGNvbnN0IFNpemVBbmRBY3Rpb25zVmVjICZWZWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdWludDMyX3QgU2l6ZSk7CisKKyAgLy8vIFJldHVybnMgdGhlIG5leHQgYWN0aW9uIG5lZWRlZCB0byBnZXQgdGhlIHNjYWxhciBvciBwb2ludGVyIHR5cGUgY2xvc2VyCisgIC8vLyB0byBiZWluZyBsZWdhbAorICAvLy8gRS5nLiBmaW5kTGVnYWxBY3Rpb24oe0dfUkVNLCAxM30pIHNob3VsZCByZXR1cm4KKyAgLy8vIChXaWRlblNjYWxhciwgMzIpLiBBZnRlciB0aGF0LCBmaW5kTGVnYWxBY3Rpb24oe0dfUkVNLCAzMn0pIHdpbGwKKyAgLy8vIHByb2JhYmx5IGJlIGNhbGxlZCwgd2hpY2ggc2hvdWxkIHJldHVybiAoTG93ZXIsIDMyKS4KKyAgLy8vIFRoaXMgaXMgYXNzdW1pbmcgdGhlIHNldFNjYWxhckFjdGlvbiBvbiBHX1JFTSB3YXMgc29tZXRoaW5nIGxpa2U6CisgIC8vLyBzZXRTY2FsYXJBY3Rpb24oR19SRU0sIDAsCisgIC8vLyAgICAgICAgICAge3sxLCBXaWRlblNjYWxhcn0sICAvLyBiaXQgc2l6ZXMgWyAxLCAzMVsKKyAgLy8vICAgICAgICAgICAgezMyLCBMb3dlcn0sICAgICAgIC8vIGJpdCBzaXplcyBbMzIsIDMzWworICAvLy8gICAgICAgICAgICB7MzMsIE5hcnJvd1NjYWxhcn0gLy8gYml0IHNpemVzIFs2NSwgK2luZlsKKyAgLy8vICAgICAgICAgICB9KTsKKyAgc3RkOjpwYWlyPExlZ2FsaXplQWN0aW9uLCBMTFQ+CisgIGZpbmRTY2FsYXJMZWdhbEFjdGlvbihjb25zdCBJbnN0ckFzcGVjdCAmQXNwZWN0KSBjb25zdDsKKworICAvLy8gUmV0dXJucyB0aGUgbmV4dCBhY3Rpb24gbmVlZGVkIHRvd2FyZHMgbGVnYWxpemluZyB0aGUgdmVjdG9yIHR5cGUuCisgIHN0ZDo6cGFpcjxMZWdhbGl6ZUFjdGlvbiwgTExUPgorICBmaW5kVmVjdG9yTGVnYWxBY3Rpb24oY29uc3QgSW5zdHJBc3BlY3QgJkFzcGVjdCkgY29uc3Q7CisKKyAgc3RhdGljIGNvbnN0IGludCBGaXJzdE9wID0gVGFyZ2V0T3Bjb2RlOjpQUkVfSVNFTF9HRU5FUklDX09QQ09ERV9TVEFSVDsKKyAgc3RhdGljIGNvbnN0IGludCBMYXN0T3AgPSBUYXJnZXRPcGNvZGU6OlBSRV9JU0VMX0dFTkVSSUNfT1BDT0RFX0VORDsKKworICAvLyBEYXRhIHN0cnVjdHVyZXMgdXNlZCB0ZW1wb3JhcmlseSBkdXJpbmcgY29uc3RydWN0aW9uIG9mIGxlZ2FsaXR5IGRhdGE6CisgIHVzaW5nIFR5cGVNYXAgPSBEZW5zZU1hcDxMTFQsIExlZ2FsaXplQWN0aW9uPjsKKyAgU21hbGxWZWN0b3I8VHlwZU1hcCwgMT4gU3BlY2lmaWVkQWN0aW9uc1tMYXN0T3AgLSBGaXJzdE9wICsgMV07CisgIFNtYWxsVmVjdG9yPFNpemVDaGFuZ2VTdHJhdGVneSwgMT4KKyAgICAgIFNjYWxhclNpemVDaGFuZ2VTdHJhdGVnaWVzW0xhc3RPcCAtIEZpcnN0T3AgKyAxXTsKKyAgU21hbGxWZWN0b3I8U2l6ZUNoYW5nZVN0cmF0ZWd5LCAxPgorICAgICAgVmVjdG9yRWxlbWVudFNpemVDaGFuZ2VTdHJhdGVnaWVzW0xhc3RPcCAtIEZpcnN0T3AgKyAxXTsKKyAgYm9vbCBUYWJsZXNJbml0aWFsaXplZDsKKworICAvLyBEYXRhIHN0cnVjdHVyZXMgdXNlZCBieSBnZXRBY3Rpb246CisgIFNtYWxsVmVjdG9yPFNpemVBbmRBY3Rpb25zVmVjLCAxPiBTY2FsYXJBY3Rpb25zW0xhc3RPcCAtIEZpcnN0T3AgKyAxXTsKKyAgU21hbGxWZWN0b3I8U2l6ZUFuZEFjdGlvbnNWZWMsIDE+IFNjYWxhckluVmVjdG9yQWN0aW9uc1tMYXN0T3AgLSBGaXJzdE9wICsgMV07CisgIHN0ZDo6dW5vcmRlcmVkX21hcDx1aW50MTZfdCwgU21hbGxWZWN0b3I8U2l6ZUFuZEFjdGlvbnNWZWMsIDE+PgorICAgICAgQWRkclNwYWNlMlBvaW50ZXJBY3Rpb25zW0xhc3RPcCAtIEZpcnN0T3AgKyAxXTsKKyAgc3RkOjp1bm9yZGVyZWRfbWFwPHVpbnQxNl90LCBTbWFsbFZlY3RvcjxTaXplQW5kQWN0aW9uc1ZlYywgMT4+CisgICAgICBOdW1FbGVtZW50czJBY3Rpb25zW0xhc3RPcCAtIEZpcnN0T3AgKyAxXTsKKworICBMZWdhbGl6ZVJ1bGVTZXQgUnVsZXNGb3JPcGNvZGVbTGFzdE9wIC0gRmlyc3RPcCArIDFdOworfTsKKworI2lmbmRlZiBOREVCVUcKKy8vLyBDaGVja3MgdGhhdCBNSVIgaXMgZnVsbHkgbGVnYWwsIHJldHVybnMgYW4gaWxsZWdhbCBpbnN0cnVjdGlvbiBpZiBpdCdzIG5vdCwKKy8vLyBudWxscHRyIG90aGVyd2lzZQorY29uc3QgTWFjaGluZUluc3RyICptYWNoaW5lRnVuY3Rpb25Jc0lsbGVnYWwoY29uc3QgTWFjaGluZUZ1bmN0aW9uICZNRik7CisjZW5kaWYKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0uCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fR0xPQkFMSVNFTF9MRUdBTElaRVJJTkZPX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0xvY2FsaXplci5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTG9jYWxpemVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGE0NmViOQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL0xvY2FsaXplci5oCkBAIC0wLDAgKzEsNzggQEAKKy8vPT0gbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTG9jYWxpemVyLmggLSBMb2NhbGl6ZXIgLS0tLS0tLS0tLS0tLSotIEMrKyAtKi09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8vIFxmaWxlIFRoaXMgZmlsZSBkZXNjcmliZXMgdGhlIGludGVyZmFjZSBvZiB0aGUgTG9jYWxpemVyIHBhc3MuCisvLy8gVGhpcyBwYXNzIG1vdmVzL2R1cGxpY2F0ZXMgY29uc3RhbnQtbGlrZSBpbnN0cnVjdGlvbnMgY2xvc2UgdG8gdGhlaXIgdXNlcy4KKy8vLyBJdHMgcHJpbWFyaWx5IGdvYWwgaXMgdG8gd29ya2Fyb3VuZCB0aGUgZGVmaWNpZW5jaWVzIG9mIHRoZSBmYXN0IHJlZ2lzdGVyCisvLy8gYWxsb2NhdG9yLgorLy8vIFdpdGggR2xvYmFsSVNlbCBjb25zdGFudHMgYXJlIGFsbCBtYXRlcmlhbGl6ZWQgaW4gdGhlIGVudHJ5IGJsb2NrIG9mCisvLy8gYSBmdW5jdGlvbi4gSG93ZXZlciwgdGhlIGZhc3QgYWxsb2NhdG9yIGNhbm5vdCByZW1hdGVyaWFsaXplIGNvbnN0YW50cyBhbmQKKy8vLyBoYXMgYSBsb3QgbW9yZSBsaXZlLXJhbmdlcyB0byBkZWFsIHdpdGggYW5kIHdpbGwgbW9zdCBsaWtlbHkgZW5kIHVwCisvLy8gc3BpbGxpbmcgYSBsb3QuCisvLy8gQnkgcHVzaGluZyB0aGUgY29uc3RhbnRzIGNsb3NlIHRvIHRoZWlyIHVzZSwgd2Ugb25seSBjcmVhdGUgc21hbGwKKy8vLyBsaXZlLXJhbmdlcy4KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfTE9DQUxJWkVSX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfTE9DQUxJWkVSX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL01hY2hpbmVJUkJ1aWxkZXIuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uUGFzcy5oIgorCituYW1lc3BhY2UgbGx2bSB7CisvLyBGb3J3YXJkIGRlY2xhcmF0aW9ucy4KK2NsYXNzIE1hY2hpbmVSZWdpc3RlckluZm87CisKKy8vLyBUaGlzIHBhc3MgaW1wbGVtZW50cyB0aGUgbG9jYWxpemF0aW9uIG1lY2hhbmlzbSBkZXNjcmliZWQgYXQgdGhlCisvLy8gdG9wIG9mIHRoaXMgZmlsZS4gT25lIHNwZWNpZmljaXR5IG9mIHRoZSBpbXBsZW1lbnRhdGlvbiBpcyB0aGF0CisvLy8gaXQgd2lsbCBtYXRlcmlhbGl6ZSBvbmUgYW5kIG9ubHkgb25lIGluc3RhbmNlIG9mIGEgY29uc3RhbnQgcGVyCisvLy8gYmFzaWMgYmxvY2ssIHRodXMgZW5hYmxpbmcgcmV1c2Ugb2YgdGhhdCBjb25zdGFudCB3aXRoaW4gdGhhdCBibG9jay4KKy8vLyBNb3Jlb3ZlciwgaXQgb25seSBtYXRlcmlhbGl6ZXMgY29uc3RhbnRzIGluIGJsb2NrcyB3aGVyZSB0aGV5CisvLy8gYXJlIHVzZWQuIFBISSB1c2VzIGFyZSBjb25zaWRlcmVkIGhhcHBlbmluZyBhdCB0aGUgZW5kIG9mIHRoZQorLy8vIHJlbGF0ZWQgcHJlZGVjZXNzb3IuCitjbGFzcyBMb2NhbGl6ZXIgOiBwdWJsaWMgTWFjaGluZUZ1bmN0aW9uUGFzcyB7CitwdWJsaWM6CisgIHN0YXRpYyBjaGFyIElEOworCitwcml2YXRlOgorICAvLy8gTVJJIGNvbnRhaW5zIGFsbCB0aGUgcmVnaXN0ZXIgY2xhc3MvYmFuayBpbmZvcm1hdGlvbiB0aGF0IHRoaXMKKyAgLy8vIHBhc3MgdXNlcyBhbmQgdXBkYXRlcy4KKyAgTWFjaGluZVJlZ2lzdGVySW5mbyAqTVJJOworCisgIC8vLyBDaGVjayB3aGV0aGVyIG9yIG5vdCBccCBNSSBuZWVkcyB0byBiZSBtb3ZlZCBjbG9zZSB0byBpdHMgdXNlcy4KKyAgc3RhdGljIGJvb2wgc2hvdWxkTG9jYWxpemUoY29uc3QgTWFjaGluZUluc3RyICZNSSk7CisKKyAgLy8vIENoZWNrIGlmIFxwIE1PVXNlIGlzIHVzZWQgaW4gdGhlIHNhbWUgYmFzaWMgYmxvY2sgYXMgXHAgRGVmLgorICAvLy8gSWYgdGhlIHVzZSBpcyBpbiB0aGUgc2FtZSBibG9jaywgd2Ugc2F5IGl0IGlzIGxvY2FsLgorICAvLy8gV2hlbiB0aGUgdXNlIGlzIG5vdCBsb2NhbCwgXHAgSW5zZXJ0TUJCIHdpbGwgY29udGFpbiB0aGUgYmFzaWMKKyAgLy8vIGJsb2NrIHdoZW4gdG8gaW5zZXJ0IFxwIERlZiB0byBoYXZlIGEgbG9jYWwgdXNlLgorICBzdGF0aWMgYm9vbCBpc0xvY2FsVXNlKE1hY2hpbmVPcGVyYW5kICZNT1VzZSwgY29uc3QgTWFjaGluZUluc3RyICZEZWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2sgKiZJbnNlcnRNQkIpOworCisgIC8vLyBJbml0aWFsaXplIHRoZSBmaWVsZCBtZW1iZXJzIHVzaW5nIFxwIE1GLgorICB2b2lkIGluaXQoTWFjaGluZUZ1bmN0aW9uICZNRik7CisKK3B1YmxpYzoKKyAgTG9jYWxpemVyKCk7CisKKyAgU3RyaW5nUmVmIGdldFBhc3NOYW1lKCkgY29uc3Qgb3ZlcnJpZGUgeyByZXR1cm4gIkxvY2FsaXplciI7IH0KKworICBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzIGdldFJlcXVpcmVkUHJvcGVydGllcygpIGNvbnN0IG92ZXJyaWRlIHsKKyAgICByZXR1cm4gTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcygpCisgICAgICAgIC5zZXQoTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllczo6UHJvcGVydHk6OklzU1NBKQorICAgICAgICAuc2V0KE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXM6OlByb3BlcnR5OjpMZWdhbGl6ZWQpCisgICAgICAgIC5zZXQoTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllczo6UHJvcGVydHk6OlJlZ0JhbmtTZWxlY3RlZCk7CisgIH0KKworICBib29sIHJ1bk9uTWFjaGluZUZ1bmN0aW9uKE1hY2hpbmVGdW5jdGlvbiAmTUYpIG92ZXJyaWRlOworfTsKKworfSAvLyBFbmQgbmFtZXNwYWNlIGxsdm0uCisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTUlQYXR0ZXJuTWF0Y2guaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL01JUGF0dGVybk1hdGNoLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzk3ZjVlNQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL01JUGF0dGVybk1hdGNoLmgKQEAgLTAsMCArMSwzMjcgQEAKKy8vPT0gLS0tLS0gbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTUlQYXR0ZXJuTWF0Y2guaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0gPT0gLy8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLy8gQ29udGFpbnMgbWF0Y2hlcnMgZm9yIG1hdGNoaW5nIFNTQSBNYWNoaW5lIEluc3RydWN0aW9ucy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworI2lmbmRlZiBMTFZNX0dNSVJfUEFUVEVSTk1BVENIX0gKKyNkZWZpbmUgTExWTV9HTUlSX1BBVFRFUk5NQVRDSF9ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9BUEZsb2F0LmgiCisjaW5jbHVkZSAibGx2bS9BRFQvQVBJbnQuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9VdGlscy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lUmVnaXN0ZXJJbmZvLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKK25hbWVzcGFjZSBNSVBhdHRlcm5NYXRjaCB7CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBSZWcsIHR5cGVuYW1lIFBhdHRlcm4+Citib29sIG1pX21hdGNoKFJlZyBSLCBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkksIFBhdHRlcm4gJiZQKSB7CisgIHJldHVybiBQLm1hdGNoKE1SSSwgUik7Cit9CisKKy8vIFRPRE86IEV4dGVuZCBmb3IgTiB1c2UuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgU3ViUGF0dGVyblQ+IHN0cnVjdCBPbmVVc2VfbWF0Y2ggeworICBTdWJQYXR0ZXJuVCBTdWJQYXQ7CisgIE9uZVVzZV9tYXRjaChjb25zdCBTdWJQYXR0ZXJuVCAmU1ApIDogU3ViUGF0KFNQKSB7fQorCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBPcFR5PgorICBib29sIG1hdGNoKGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSwgdW5zaWduZWQgUmVnKSB7CisgICAgcmV0dXJuIE1SSS5oYXNPbmVVc2UoUmVnKSAmJiBTdWJQYXQubWF0Y2goTVJJLCBSZWcpOworICB9Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgU3ViUGF0PgoraW5saW5lIE9uZVVzZV9tYXRjaDxTdWJQYXQ+IG1fT25lVXNlKGNvbnN0IFN1YlBhdCAmU1ApIHsKKyAgcmV0dXJuIFNQOworfQorCitzdHJ1Y3QgQ29uc3RhbnRNYXRjaCB7CisgIGludDY0X3QgJkNSOworICBDb25zdGFudE1hdGNoKGludDY0X3QgJkMpIDogQ1IoQykge30KKyAgYm9vbCBtYXRjaChjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkksIHVuc2lnbmVkIFJlZykgeworICAgIGlmIChhdXRvIE1heWJlQ3N0ID0gZ2V0Q29uc3RhbnRWUmVnVmFsKFJlZywgTVJJKSkgeworICAgICAgQ1IgPSAqTWF5YmVDc3Q7CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9OworCitpbmxpbmUgQ29uc3RhbnRNYXRjaCBtX0lDc3QoaW50NjRfdCAmQ3N0KSB7IHJldHVybiBDb25zdGFudE1hdGNoKENzdCk7IH0KKworLy8gVE9ETzogUmV3b3JrIHRoaXMgZm9yIGRpZmZlcmVudCBraW5kcyBvZiBNYWNoaW5lT3BlcmFuZC4KKy8vIEN1cnJlbnRseSBhc3N1bWVzIHRoZSBTcmMgZm9yIGEgbWF0Y2ggaXMgYSByZWdpc3Rlci4KKy8vIFdlIG1pZ2h0IHdhbnQgdG8gc3VwcG9ydCB0YWtpbmcgaW4gc29tZSBNYWNoaW5lT3BlcmFuZHMgYW5kIGNhbGwgZ2V0UmVnIG9uCisvLyB0aGF0LgorCitzdHJ1Y3Qgb3BlcmFuZF90eXBlX21hdGNoIHsKKyAgYm9vbCBtYXRjaChjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkksIHVuc2lnbmVkIFJlZykgeyByZXR1cm4gdHJ1ZTsgfQorICBib29sIG1hdGNoKGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSwgTWFjaGluZU9wZXJhbmQgKk1PKSB7CisgICAgcmV0dXJuIE1PLT5pc1JlZygpOworICB9Cit9OworCitpbmxpbmUgb3BlcmFuZF90eXBlX21hdGNoIG1fUmVnKCkgeyByZXR1cm4gb3BlcmFuZF90eXBlX21hdGNoKCk7IH0KKworLy8vIE1hdGNoaW5nIGNvbWJpbmF0b3JzLgordGVtcGxhdGUgPHR5cGVuYW1lLi4uIFByZWRzPiBzdHJ1Y3QgQW5kIHsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIE1hdGNoU3JjPgorICBib29sIG1hdGNoKE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSwgTWF0Y2hTcmMgJiZzcmMpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFByZWQsIHR5cGVuYW1lLi4uIFByZWRzPgorc3RydWN0IEFuZDxQcmVkLCBQcmVkcy4uLj4gOiBBbmQ8UHJlZHMuLi4+IHsKKyAgUHJlZCBQOworICBBbmQoUHJlZCAmJnAsIFByZWRzICYmLi4uIHByZWRzKQorICAgICAgOiBBbmQ8UHJlZHMuLi4+KHN0ZDo6Zm9yd2FyZDxQcmVkcz4ocHJlZHMpLi4uKSwgUChzdGQ6OmZvcndhcmQ8UHJlZD4ocCkpIHsKKyAgfQorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgTWF0Y2hTcmM+CisgIGJvb2wgbWF0Y2goTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJLCBNYXRjaFNyYyAmJnNyYykgeworICAgIHJldHVybiBQLm1hdGNoKE1SSSwgc3JjKSAmJiBBbmQ8UHJlZHMuLi4+OjptYXRjaChNUkksIHNyYyk7CisgIH0KK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZS4uLiBQcmVkcz4gc3RydWN0IE9yIHsKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIE1hdGNoU3JjPgorICBib29sIG1hdGNoKE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSwgTWF0Y2hTcmMgJiZzcmMpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBQcmVkLCB0eXBlbmFtZS4uLiBQcmVkcz4KK3N0cnVjdCBPcjxQcmVkLCBQcmVkcy4uLj4gOiBPcjxQcmVkcy4uLj4geworICBQcmVkIFA7CisgIE9yKFByZWQgJiZwLCBQcmVkcyAmJi4uLiBwcmVkcykKKyAgICAgIDogT3I8UHJlZHMuLi4+KHN0ZDo6Zm9yd2FyZDxQcmVkcz4ocHJlZHMpLi4uKSwgUChzdGQ6OmZvcndhcmQ8UHJlZD4ocCkpIHt9CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBNYXRjaFNyYz4KKyAgYm9vbCBtYXRjaChNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkksIE1hdGNoU3JjICYmc3JjKSB7CisgICAgcmV0dXJuIFAubWF0Y2goTVJJLCBzcmMpIHx8IE9yPFByZWRzLi4uPjo6bWF0Y2goTVJJLCBzcmMpOworICB9Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gUHJlZHM+IEFuZDxQcmVkcy4uLj4gbV9hbGxfb2YoUHJlZHMgJiYuLi4gcHJlZHMpIHsKKyAgcmV0dXJuIEFuZDxQcmVkcy4uLj4oc3RkOjpmb3J3YXJkPFByZWRzPihwcmVkcykuLi4pOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gUHJlZHM+IE9yPFByZWRzLi4uPiBtX2FueV9vZihQcmVkcyAmJi4uLiBwcmVkcykgeworICByZXR1cm4gT3I8UHJlZHMuLi4+KHN0ZDo6Zm9yd2FyZDxQcmVkcz4ocHJlZHMpLi4uKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIEJpbmRUeT4gc3RydWN0IGJpbmRfaGVscGVyIHsKKyAgc3RhdGljIGJvb2wgYmluZChjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkksIEJpbmRUeSAmVlIsIEJpbmRUeSAmVikgeworICAgIFZSID0gVjsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IGJpbmRfaGVscGVyPE1hY2hpbmVJbnN0ciAqPiB7CisgIHN0YXRpYyBib29sIGJpbmQoY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJLCBNYWNoaW5lSW5zdHIgKiZNSSwKKyAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBSZWcpIHsKKyAgICBNSSA9IE1SSS5nZXRWUmVnRGVmKFJlZyk7CisgICAgaWYgKE1JKQorICAgICAgcmV0dXJuIHRydWU7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9OworCit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgYmluZF9oZWxwZXI8TExUPiB7CisgIHN0YXRpYyBib29sIGJpbmQoY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJLCBMTFQgJlR5LCB1bnNpZ25lZCBSZWcpIHsKKyAgICBUeSA9IE1SSS5nZXRUeXBlKFJlZyk7CisgICAgaWYgKFR5LmlzVmFsaWQoKSkKKyAgICAgIHJldHVybiB0cnVlOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IGJpbmRfaGVscGVyPGNvbnN0IENvbnN0YW50RlAgKj4geworICBzdGF0aWMgYm9vbCBiaW5kKGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSwgY29uc3QgQ29uc3RhbnRGUCAqJkYsCisgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgUmVnKSB7CisgICAgRiA9IGdldENvbnN0YW50RlBWUmVnVmFsKFJlZywgTVJJKTsKKyAgICBpZiAoRikKKyAgICAgIHJldHVybiB0cnVlOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIENsYXNzPiBzdHJ1Y3QgYmluZF90eSB7CisgIENsYXNzICZWUjsKKworICBiaW5kX3R5KENsYXNzICZWKSA6IFZSKFYpIHt9CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIElUeT4gYm9vbCBtYXRjaChjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkksIElUeSAmJlYpIHsKKyAgICByZXR1cm4gYmluZF9oZWxwZXI8Q2xhc3M+OjpiaW5kKE1SSSwgVlIsIFYpOworICB9Cit9OworCitpbmxpbmUgYmluZF90eTx1bnNpZ25lZD4gbV9SZWcodW5zaWduZWQgJlIpIHsgcmV0dXJuIFI7IH0KK2lubGluZSBiaW5kX3R5PE1hY2hpbmVJbnN0ciAqPiBtX01JbnN0cihNYWNoaW5lSW5zdHIgKiZNSSkgeyByZXR1cm4gTUk7IH0KK2lubGluZSBiaW5kX3R5PExMVD4gbV9UeXBlKExMVCAmVHkpIHsgcmV0dXJuIFR5OyB9CisKKy8vIEhlbHBlciBmb3IgbWF0Y2hpbmcgR19GQ09OU1RBTlQKK2lubGluZSBiaW5kX3R5PGNvbnN0IENvbnN0YW50RlAgKj4gbV9HRkNzdChjb25zdCBDb25zdGFudEZQIComQykgeyByZXR1cm4gQzsgfQorCisvLyBHZW5lcmFsIGhlbHBlciBmb3IgYWxsIHRoZSBiaW5hcnkgZ2VuZXJpYyBNSSBzdWNoIGFzIEdfQUREL0dfU1VCIGV0YwordGVtcGxhdGUgPHR5cGVuYW1lIExIU19QLCB0eXBlbmFtZSBSSFNfUCwgdW5zaWduZWQgT3Bjb2RlLAorICAgICAgICAgIGJvb2wgQ29tbXV0YWJsZSA9IGZhbHNlPgorc3RydWN0IEJpbmFyeU9wX21hdGNoIHsKKyAgTEhTX1AgTDsKKyAgUkhTX1AgUjsKKworICBCaW5hcnlPcF9tYXRjaChjb25zdCBMSFNfUCAmTEhTLCBjb25zdCBSSFNfUCAmUkhTKSA6IEwoTEhTKSwgUihSSFMpIHt9CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBPcFR5PiBib29sIG1hdGNoKE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSwgT3BUeSAmJk9wKSB7CisgICAgTWFjaGluZUluc3RyICpUbXBNSTsKKyAgICBpZiAobWlfbWF0Y2goT3AsIE1SSSwgbV9NSW5zdHIoVG1wTUkpKSkgeworICAgICAgaWYgKFRtcE1JLT5nZXRPcGNvZGUoKSA9PSBPcGNvZGUgJiYgVG1wTUktPmdldE51bU9wZXJhbmRzKCkgPT0gMykgeworICAgICAgICByZXR1cm4gKEwubWF0Y2goTVJJLCBUbXBNSS0+Z2V0T3BlcmFuZCgxKS5nZXRSZWcoKSkgJiYKKyAgICAgICAgICAgICAgICBSLm1hdGNoKE1SSSwgVG1wTUktPmdldE9wZXJhbmQoMikuZ2V0UmVnKCkpKSB8fAorICAgICAgICAgICAgICAgKENvbW11dGFibGUgJiYgKFIubWF0Y2goTVJJLCBUbXBNSS0+Z2V0T3BlcmFuZCgxKS5nZXRSZWcoKSkgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMLm1hdGNoKE1SSSwgVG1wTUktPmdldE9wZXJhbmQoMikuZ2V0UmVnKCkpKSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIExIUywgdHlwZW5hbWUgUkhTPgoraW5saW5lIEJpbmFyeU9wX21hdGNoPExIUywgUkhTLCBUYXJnZXRPcGNvZGU6OkdfQURELCB0cnVlPgorbV9HQWRkKGNvbnN0IExIUyAmTCwgY29uc3QgUkhTICZSKSB7CisgIHJldHVybiBCaW5hcnlPcF9tYXRjaDxMSFMsIFJIUywgVGFyZ2V0T3Bjb2RlOjpHX0FERCwgdHJ1ZT4oTCwgUik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBMSFMsIHR5cGVuYW1lIFJIUz4KK2lubGluZSBCaW5hcnlPcF9tYXRjaDxMSFMsIFJIUywgVGFyZ2V0T3Bjb2RlOjpHX1NVQj4gbV9HU3ViKGNvbnN0IExIUyAmTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJIUyAmUikgeworICByZXR1cm4gQmluYXJ5T3BfbWF0Y2g8TEhTLCBSSFMsIFRhcmdldE9wY29kZTo6R19TVUI+KEwsIFIpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgTEhTLCB0eXBlbmFtZSBSSFM+CitpbmxpbmUgQmluYXJ5T3BfbWF0Y2g8TEhTLCBSSFMsIFRhcmdldE9wY29kZTo6R19NVUwsIHRydWU+CittX0dNdWwoY29uc3QgTEhTICZMLCBjb25zdCBSSFMgJlIpIHsKKyAgcmV0dXJuIEJpbmFyeU9wX21hdGNoPExIUywgUkhTLCBUYXJnZXRPcGNvZGU6OkdfTVVMLCB0cnVlPihMLCBSKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIExIUywgdHlwZW5hbWUgUkhTPgoraW5saW5lIEJpbmFyeU9wX21hdGNoPExIUywgUkhTLCBUYXJnZXRPcGNvZGU6OkdfRkFERCwgdHJ1ZT4KK21fR0ZBZGQoY29uc3QgTEhTICZMLCBjb25zdCBSSFMgJlIpIHsKKyAgcmV0dXJuIEJpbmFyeU9wX21hdGNoPExIUywgUkhTLCBUYXJnZXRPcGNvZGU6OkdfRkFERCwgdHJ1ZT4oTCwgUik7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBMSFMsIHR5cGVuYW1lIFJIUz4KK2lubGluZSBCaW5hcnlPcF9tYXRjaDxMSFMsIFJIUywgVGFyZ2V0T3Bjb2RlOjpHX0ZNVUwsIHRydWU+CittX0dGTXVsKGNvbnN0IExIUyAmTCwgY29uc3QgUkhTICZSKSB7CisgIHJldHVybiBCaW5hcnlPcF9tYXRjaDxMSFMsIFJIUywgVGFyZ2V0T3Bjb2RlOjpHX0ZNVUwsIHRydWU+KEwsIFIpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgTEhTLCB0eXBlbmFtZSBSSFM+CitpbmxpbmUgQmluYXJ5T3BfbWF0Y2g8TEhTLCBSSFMsIFRhcmdldE9wY29kZTo6R19BTkQsIHRydWU+CittX0dBbmQoY29uc3QgTEhTICZMLCBjb25zdCBSSFMgJlIpIHsKKyAgcmV0dXJuIEJpbmFyeU9wX21hdGNoPExIUywgUkhTLCBUYXJnZXRPcGNvZGU6OkdfQU5ELCB0cnVlPihMLCBSKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIExIUywgdHlwZW5hbWUgUkhTPgoraW5saW5lIEJpbmFyeU9wX21hdGNoPExIUywgUkhTLCBUYXJnZXRPcGNvZGU6OkdfT1IsIHRydWU+IG1fR09yKGNvbnN0IExIUyAmTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSSFMgJlIpIHsKKyAgcmV0dXJuIEJpbmFyeU9wX21hdGNoPExIUywgUkhTLCBUYXJnZXRPcGNvZGU6OkdfT1IsIHRydWU+KEwsIFIpOworfQorCisvLyBIZWxwZXIgZm9yIHVuYXJ5IGluc3RydWN0aW9ucyAoR19bWlNBXUVYVC9HX1RSVU5DKSBldGMKK3RlbXBsYXRlIDx0eXBlbmFtZSBTcmNUeSwgdW5zaWduZWQgT3Bjb2RlPiBzdHJ1Y3QgVW5hcnlPcF9tYXRjaCB7CisgIFNyY1R5IEw7CisKKyAgVW5hcnlPcF9tYXRjaChjb25zdCBTcmNUeSAmTEhTKSA6IEwoTEhTKSB7fQorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgT3BUeT4gYm9vbCBtYXRjaChNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkksIE9wVHkgJiZPcCkgeworICAgIE1hY2hpbmVJbnN0ciAqVG1wTUk7CisgICAgaWYgKG1pX21hdGNoKE9wLCBNUkksIG1fTUluc3RyKFRtcE1JKSkpIHsKKyAgICAgIGlmIChUbXBNSS0+Z2V0T3Bjb2RlKCkgPT0gT3Bjb2RlICYmIFRtcE1JLT5nZXROdW1PcGVyYW5kcygpID09IDIpIHsKKyAgICAgICAgcmV0dXJuIEwubWF0Y2goTVJJLCBUbXBNSS0+Z2V0T3BlcmFuZCgxKS5nZXRSZWcoKSk7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBmYWxzZTsKKyAgfQorfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFNyY1R5PgoraW5saW5lIFVuYXJ5T3BfbWF0Y2g8U3JjVHksIFRhcmdldE9wY29kZTo6R19BTllFWFQ+CittX0dBbnlFeHQoY29uc3QgU3JjVHkgJlNyYykgeworICByZXR1cm4gVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpHX0FOWUVYVD4oU3JjKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFNyY1R5PgoraW5saW5lIFVuYXJ5T3BfbWF0Y2g8U3JjVHksIFRhcmdldE9wY29kZTo6R19TRVhUPiBtX0dTRXh0KGNvbnN0IFNyY1R5ICZTcmMpIHsKKyAgcmV0dXJuIFVuYXJ5T3BfbWF0Y2g8U3JjVHksIFRhcmdldE9wY29kZTo6R19TRVhUPihTcmMpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgU3JjVHk+CitpbmxpbmUgVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpHX1pFWFQ+IG1fR1pFeHQoY29uc3QgU3JjVHkgJlNyYykgeworICByZXR1cm4gVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpHX1pFWFQ+KFNyYyk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBTcmNUeT4KK2lubGluZSBVbmFyeU9wX21hdGNoPFNyY1R5LCBUYXJnZXRPcGNvZGU6OkdfRlBFWFQ+IG1fR0ZQRXh0KGNvbnN0IFNyY1R5ICZTcmMpIHsKKyAgcmV0dXJuIFVuYXJ5T3BfbWF0Y2g8U3JjVHksIFRhcmdldE9wY29kZTo6R19GUEVYVD4oU3JjKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIFNyY1R5PgoraW5saW5lIFVuYXJ5T3BfbWF0Y2g8U3JjVHksIFRhcmdldE9wY29kZTo6R19UUlVOQz4gbV9HVHJ1bmMoY29uc3QgU3JjVHkgJlNyYykgeworICByZXR1cm4gVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpHX1RSVU5DPihTcmMpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgU3JjVHk+CitpbmxpbmUgVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpHX0JJVENBU1Q+CittX0dCaXRjYXN0KGNvbnN0IFNyY1R5ICZTcmMpIHsKKyAgcmV0dXJuIFVuYXJ5T3BfbWF0Y2g8U3JjVHksIFRhcmdldE9wY29kZTo6R19CSVRDQVNUPihTcmMpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgU3JjVHk+CitpbmxpbmUgVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpHX1BUUlRPSU5UPgorbV9HUHRyVG9JbnQoY29uc3QgU3JjVHkgJlNyYykgeworICByZXR1cm4gVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpHX1BUUlRPSU5UPihTcmMpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgU3JjVHk+CitpbmxpbmUgVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpHX0lOVFRPUFRSPgorbV9HSW50VG9QdHIoY29uc3QgU3JjVHkgJlNyYykgeworICByZXR1cm4gVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpHX0lOVFRPUFRSPihTcmMpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgU3JjVHk+CitpbmxpbmUgVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpHX0ZQVFJVTkM+CittX0dGUFRydW5jKGNvbnN0IFNyY1R5ICZTcmMpIHsKKyAgcmV0dXJuIFVuYXJ5T3BfbWF0Y2g8U3JjVHksIFRhcmdldE9wY29kZTo6R19GUFRSVU5DPihTcmMpOworfQorCit0ZW1wbGF0ZSA8dHlwZW5hbWUgU3JjVHk+CitpbmxpbmUgVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpHX0ZBQlM+IG1fR0ZhYnMoY29uc3QgU3JjVHkgJlNyYykgeworICByZXR1cm4gVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpHX0ZBQlM+KFNyYyk7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBTcmNUeT4KK2lubGluZSBVbmFyeU9wX21hdGNoPFNyY1R5LCBUYXJnZXRPcGNvZGU6OkNPUFk+IG1fQ29weShTcmNUeSAmJlNyYykgeworICByZXR1cm4gVW5hcnlPcF9tYXRjaDxTcmNUeSwgVGFyZ2V0T3Bjb2RlOjpDT1BZPihzdGQ6OmZvcndhcmQ8U3JjVHk+KFNyYykpOworfQorCisvLyBIZWxwZXIgZm9yIGNoZWNraW5nIGlmIGEgUmVnIGlzIG9mIHNwZWNpZmljIHR5cGUuCitzdHJ1Y3QgQ2hlY2tUeXBlIHsKKyAgTExUIFR5OworICBDaGVja1R5cGUoY29uc3QgTExUICZUeSkgOiBUeShUeSkge30KKworICBib29sIG1hdGNoKE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSwgdW5zaWduZWQgUmVnKSB7CisgICAgcmV0dXJuIE1SSS5nZXRUeXBlKFJlZykgPT0gVHk7CisgIH0KK307CisKK2lubGluZSBDaGVja1R5cGUgbV9TcGVjaWZpY1R5cGUoTExUIFR5KSB7IHJldHVybiBUeTsgfQorCit9IC8vIG5hbWVzcGFjZSBHTUlQYXR0ZXJuTWF0Y2gKK30gLy8gbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9NYWNoaW5lSVJCdWlsZGVyLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9NYWNoaW5lSVJCdWlsZGVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWY0ZTBhZAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL01hY2hpbmVJUkJ1aWxkZXIuaApAQCAtMCwwICsxLDgwOCBAQAorLy89PT0tLSBsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9NYWNoaW5lSVJCdWlsZGVyLmggLSBNSUJ1aWxkZXIgLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLyBcZmlsZQorLy8vIFRoaXMgZmlsZSBkZWNsYXJlcyB0aGUgTWFjaGluZUlSQnVpbGRlciBjbGFzcy4KKy8vLyBUaGlzIGlzIGEgaGVscGVyIGNsYXNzIHRvIGJ1aWxkIE1hY2hpbmVJbnN0ci4KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfTUFDSElORUlSQlVJTERFUl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX01BQ0hJTkVJUkJVSUxERVJfSAorCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvVHlwZXMuaCIKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9Mb3dMZXZlbFR5cGUuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUluc3RyQnVpbGRlci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lUmVnaXN0ZXJJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9JUi9Db25zdGFudHMuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0RlYnVnTG9jLmgiCisKKworbmFtZXNwYWNlIGxsdm0geworCisvLyBGb3J3YXJkIGRlY2xhcmF0aW9ucy4KK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIE1hY2hpbmVJbnN0cjsKK2NsYXNzIFRhcmdldEluc3RySW5mbzsKKworLy8vIEhlbHBlciBjbGFzcyB0byBidWlsZCBNYWNoaW5lSW5zdHIuCisvLy8gSXQga2VlcHMgaW50ZXJuYWxseSB0aGUgaW5zZXJ0aW9uIHBvaW50IGFuZCBkZWJ1ZyBsb2NhdGlvbiBmb3IgYWxsCisvLy8gdGhlIG5ldyBpbnN0cnVjdGlvbnMgd2Ugd2FudCB0byBjcmVhdGUuCisvLy8gVGhpcyBpbmZvcm1hdGlvbiBjYW4gYmUgbW9kaWZ5IHZpYSB0aGUgcmVsYXRlZCBzZXR0ZXJzLgorY2xhc3MgTWFjaGluZUlSQnVpbGRlciB7CisgIC8vLyBNYWNoaW5lRnVuY3Rpb24gdW5kZXIgY29uc3RydWN0aW9uLgorICBNYWNoaW5lRnVuY3Rpb24gKk1GOworICAvLy8gSW5mb3JtYXRpb24gdXNlZCB0byBhY2Nlc3MgdGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBvcGNvZGVzLgorICBjb25zdCBUYXJnZXRJbnN0ckluZm8gKlRJSTsKKyAgLy8vIEluZm9ybWF0aW9uIHVzZWQgdG8gdmVyaWZ5IHR5cGVzIGFyZSBjb25zaXN0ZW50IGFuZCB0byBjcmVhdGUgdmlydHVhbCByZWdpc3RlcnMuCisgIE1hY2hpbmVSZWdpc3RlckluZm8gKk1SSTsKKyAgLy8vIERlYnVnIGxvY2F0aW9uIHRvIGJlIHNldCB0byBhbnkgaW5zdHJ1Y3Rpb24gd2UgY3JlYXRlLgorICBEZWJ1Z0xvYyBETDsKKworICAvLy8gXG5hbWUgRmllbGRzIGRlc2NyaWJpbmcgdGhlIGluc2VydGlvbiBwb2ludC4KKyAgLy8vIEB7CisgIE1hY2hpbmVCYXNpY0Jsb2NrICpNQkI7CisgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBJSTsKKyAgLy8vIEB9CisKKyAgc3RkOjpmdW5jdGlvbjx2b2lkKE1hY2hpbmVJbnN0ciAqKT4gSW5zZXJ0ZWRJbnN0cjsKKworICBjb25zdCBUYXJnZXRJbnN0ckluZm8gJmdldFRJSSgpIHsKKyAgICBhc3NlcnQoVElJICYmICJUYXJnZXRJbnN0ckluZm8gaXMgbm90IHNldCIpOworICAgIHJldHVybiAqVElJOworICB9CisKKyAgdm9pZCB2YWxpZGF0ZVRydW5jRXh0KHVuc2lnbmVkIERzdCwgdW5zaWduZWQgU3JjLCBib29sIElzRXh0ZW5kKTsKKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZEJpbmFyeU9wKHVuc2lnbmVkIE9wY29kZSwgdW5zaWduZWQgUmVzLCB1bnNpZ25lZCBPcDAsIHVuc2lnbmVkIE9wMSk7CisKKyAgdW5zaWduZWQgZ2V0RGVzdEZyb21BcmcodW5zaWduZWQgUmVnKSB7IHJldHVybiBSZWc7IH0KKyAgdW5zaWduZWQgZ2V0RGVzdEZyb21BcmcoTExUIFR5KSB7CisgICAgcmV0dXJuIGdldE1GKCkuZ2V0UmVnSW5mbygpLmNyZWF0ZUdlbmVyaWNWaXJ0dWFsUmVnaXN0ZXIoVHkpOworICB9CisgIHVuc2lnbmVkIGdldERlc3RGcm9tQXJnKGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKSB7CisgICAgcmV0dXJuIGdldE1GKCkuZ2V0UmVnSW5mbygpLmNyZWF0ZVZpcnR1YWxSZWdpc3RlcihSQyk7CisgIH0KKworICB2b2lkIGFkZFVzZUZyb21BcmcoTWFjaGluZUluc3RyQnVpbGRlciAmTUlCLCB1bnNpZ25lZCBSZWcpIHsKKyAgICBNSUIuYWRkVXNlKFJlZyk7CisgIH0KKworICB2b2lkIGFkZFVzZUZyb21BcmcoTWFjaGluZUluc3RyQnVpbGRlciAmTUlCLCBjb25zdCBNYWNoaW5lSW5zdHJCdWlsZGVyICZVc2VNSUIpIHsKKyAgICBNSUIuYWRkVXNlKFVzZU1JQi0+Z2V0T3BlcmFuZCgwKS5nZXRSZWcoKSk7CisgIH0KKworICB2b2lkIGFkZFVzZXNGcm9tQXJncyhNYWNoaW5lSW5zdHJCdWlsZGVyICZNSUIpIHsgfQorICB0ZW1wbGF0ZTx0eXBlbmFtZSBVc2VBcmdUeSwgdHlwZW5hbWUgLi4uIFVzZUFyZ3NUeT4KKyAgdm9pZCBhZGRVc2VzRnJvbUFyZ3MoTWFjaGluZUluc3RyQnVpbGRlciAmTUlCLCBVc2VBcmdUeSAmJkFyZzEsIFVzZUFyZ3NUeSAmJi4uLiBBcmdzKSB7CisgICAgYWRkVXNlRnJvbUFyZyhNSUIsIEFyZzEpOworICAgIGFkZFVzZXNGcm9tQXJncyhNSUIsIHN0ZDo6Zm9yd2FyZDxVc2VBcmdzVHk+KEFyZ3MpLi4uKTsKKyAgfQorICB1bnNpZ25lZCBnZXRSZWdGcm9tQXJnKHVuc2lnbmVkIFJlZykgeyByZXR1cm4gUmVnOyB9CisgIHVuc2lnbmVkIGdldFJlZ0Zyb21BcmcoY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmTUlCKSB7CisgICAgcmV0dXJuIE1JQi0+Z2V0T3BlcmFuZCgwKS5nZXRSZWcoKTsKKyAgfQorCitwdWJsaWM6CisgIC8vLyBTb21lIGNvbnN0cnVjdG9ycyBmb3IgZWFzeSB1c2UuCisgIE1hY2hpbmVJUkJ1aWxkZXIoKSA9IGRlZmF1bHQ7CisgIE1hY2hpbmVJUkJ1aWxkZXIoTWFjaGluZUZ1bmN0aW9uICZNRikgeyBzZXRNRihNRik7IH0KKyAgTWFjaGluZUlSQnVpbGRlcihNYWNoaW5lSW5zdHIgJk1JKSA6IE1hY2hpbmVJUkJ1aWxkZXIoKk1JLmdldE1GKCkpIHsKKyAgICBzZXRJbnN0cihNSSk7CisgIH0KKworICAvLy8gR2V0dGVyIGZvciB0aGUgZnVuY3Rpb24gd2UgY3VycmVudGx5IGJ1aWxkLgorICBNYWNoaW5lRnVuY3Rpb24gJmdldE1GKCkgeworICAgIGFzc2VydChNRiAmJiAiTWFjaGluZUZ1bmN0aW9uIGlzIG5vdCBzZXQiKTsKKyAgICByZXR1cm4gKk1GOworICB9CisKKyAgLy8vIEdldHRlciBmb3IgdGhlIGJhc2ljIGJsb2NrIHdlIGN1cnJlbnRseSBidWlsZC4KKyAgTWFjaGluZUJhc2ljQmxvY2sgJmdldE1CQigpIHsKKyAgICBhc3NlcnQoTUJCICYmICJNYWNoaW5lQmFzaWNCbG9jayBpcyBub3Qgc2V0Iik7CisgICAgcmV0dXJuICpNQkI7CisgIH0KKworICAvLy8gQ3VycmVudCBpbnNlcnRpb24gcG9pbnQgZm9yIG5ldyBpbnN0cnVjdGlvbnMuCisgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBnZXRJbnNlcnRQdCgpIHsKKyAgICByZXR1cm4gSUk7CisgIH0KKworICAvLy8gU2V0IHRoZSBpbnNlcnRpb24gcG9pbnQgYmVmb3JlIHRoZSBzcGVjaWZpZWQgcG9zaXRpb24uCisgIC8vLyBccHJlIE1CQiBtdXN0IGJlIGluIGdldE1GKCkuCisgIC8vLyBccHJlIElJIG11c3QgYmUgYSB2YWxpZCBpdGVyYXRvciBpbiBNQkIuCisgIHZvaWQgc2V0SW5zZXJ0UHQoTWFjaGluZUJhc2ljQmxvY2sgJk1CQiwgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIElJKTsKKyAgLy8vIEB9CisKKyAgLy8vIFxuYW1lIFNldHRlcnMgZm9yIHRoZSBpbnNlcnRpb24gcG9pbnQuCisgIC8vLyBAeworICAvLy8gU2V0IHRoZSBNYWNoaW5lRnVuY3Rpb24gd2hlcmUgdG8gYnVpbGQgaW5zdHJ1Y3Rpb25zLgorICB2b2lkIHNldE1GKE1hY2hpbmVGdW5jdGlvbiAmKTsKKworICAvLy8gU2V0IHRoZSBpbnNlcnRpb24gcG9pbnQgdG8gdGhlICBlbmQgb2YgXHAgTUJCLgorICAvLy8gXHByZSBccCBNQkIgbXVzdCBiZSBjb250YWluZWQgYnkgZ2V0TUYoKS4KKyAgdm9pZCBzZXRNQkIoTWFjaGluZUJhc2ljQmxvY2sgJk1CQik7CisKKyAgLy8vIFNldCB0aGUgaW5zZXJ0aW9uIHBvaW50IHRvIGJlZm9yZSBNSS4KKyAgLy8vIFxwcmUgTUkgbXVzdCBiZSBpbiBnZXRNRigpLgorICB2b2lkIHNldEluc3RyKE1hY2hpbmVJbnN0ciAmTUkpOworICAvLy8gQH0KKworICAvLy8gXG5hbWUgQ29udHJvbCB3aGVyZSBpbnN0cnVjdGlvbnMgd2UgY3JlYXRlIGFyZSByZWNvcmRlZCAodHlwaWNhbGx5IGZvcgorICAvLy8gdmlzaXRpbmcgYWdhaW4gbGF0ZXIgZHVyaW5nIGxlZ2FsaXphdGlvbikuCisgIC8vLyBAeworICB2b2lkIHJlY29yZEluc2VydGlvbnMoc3RkOjpmdW5jdGlvbjx2b2lkKE1hY2hpbmVJbnN0ciAqKT4gSW5zZXJ0ZWRJbnN0cik7CisgIHZvaWQgc3RvcFJlY29yZGluZ0luc2VydGlvbnMoKTsKKyAgLy8vIEB9CisKKyAgLy8vIFNldCB0aGUgZGVidWcgbG9jYXRpb24gdG8gXHAgREwgZm9yIGFsbCB0aGUgbmV4dCBidWlsZCBpbnN0cnVjdGlvbnMuCisgIHZvaWQgc2V0RGVidWdMb2MoY29uc3QgRGVidWdMb2MgJkRMKSB7IHRoaXMtPkRMID0gREw7IH0KKworICAvLy8gR2V0IHRoZSBjdXJyZW50IGluc3RydWN0aW9uJ3MgZGVidWcgbG9jYXRpb24uCisgIERlYnVnTG9jIGdldERlYnVnTG9jKCkgeyByZXR1cm4gREw7IH0KKworICAvLy8gQnVpbGQgYW5kIGluc2VydCA8ZW1wdHk+ID0gXHAgT3Bjb2RlIDxlbXB0eT4uCisgIC8vLyBUaGUgaW5zZXJ0aW9uIHBvaW50IGlzIHRoZSBvbmUgc2V0IGJ5IHRoZSBsYXN0IGNhbGwgb2YgZWl0aGVyCisgIC8vLyBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JLgorICAvLy8KKyAgLy8vIFxwcmUgc2V0QmFzaWNCbG9jayBvciBzZXRNSSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQuCisgIC8vLworICAvLy8gXHJldHVybiBhIE1hY2hpbmVJbnN0ckJ1aWxkZXIgZm9yIHRoZSBuZXdseSBjcmVhdGVkIGluc3RydWN0aW9uLgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkSW5zdHIodW5zaWduZWQgT3Bjb2RlKTsKKworICAvLy8gREFHIGxpa2UgR2VuZXJpYyBtZXRob2QgZm9yIGJ1aWxkaW5nIGFyYml0cmFyeSBpbnN0cnVjdGlvbnMgYXMgYWJvdmUuCisgIC8vLyBcT3BjIG9wY29kZSBmb3IgdGhlIGluc3RydWN0aW9uLgorICAvLy8gXFR5IEVpdGhlciBMTFQvVGFyZ2V0UmVnaXN0ZXJDbGFzcy91bnNpZ25lZCB0eXBlcyBmb3IgRHN0CisgIC8vLyBcQXJncyBWYXJpYWRpYyBsaXN0IG9mIHVzZXMgb2YgdHlwZXModW5zaWduZWQvTWFjaGluZUluc3RyQnVpbGRlcikKKyAgLy8vIFVzZXMgb2YgdHlwZSBNYWNoaW5lSW5zdHJCdWlsZGVyIHdpbGwgcGVyZm9ybQorICAvLy8gZ2V0T3BlcmFuZCgwKS5nZXRSZWcoKSB0byBjb252ZXJ0IHRvIHJlZ2lzdGVyLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRHN0VHksIHR5cGVuYW1lLi4uIFVzZUFyZ3NUeT4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZEluc3RyKHVuc2lnbmVkIE9wYywgRHN0VHkgJiZUeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzZUFyZ3NUeSAmJi4uLiBBcmdzKSB7CisgICAgYXV0byBNSUIgPSBidWlsZEluc3RyKE9wYykuYWRkRGVmKGdldERlc3RGcm9tQXJnKFR5KSk7CisgICAgYWRkVXNlc0Zyb21BcmdzKE1JQiwgc3RkOjpmb3J3YXJkPFVzZUFyZ3NUeT4oQXJncykuLi4pOworICAgIHJldHVybiBNSUI7CisgIH0KKworICAvLy8gQnVpbGQgYnV0IGRvbid0IGluc2VydCA8ZW1wdHk+ID0gXHAgT3Bjb2RlIDxlbXB0eT4uCisgIC8vLworICAvLy8gXHByZSBzZXRNRiwgc2V0QmFzaWNCbG9jayBvciBzZXRNSSAgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gYSBNYWNoaW5lSW5zdHJCdWlsZGVyIGZvciB0aGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZEluc3RyTm9JbnNlcnQodW5zaWduZWQgT3Bjb2RlKTsKKworICAvLy8gSW5zZXJ0IGFuIGV4aXN0aW5nIGluc3RydWN0aW9uIGF0IHRoZSBpbnNlcnRpb24gcG9pbnQuCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgaW5zZXJ0SW5zdHIoTWFjaGluZUluc3RyQnVpbGRlciBNSUIpOworCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IGEgREJHX1ZBTFVFIGluc3RydWN0aW9uIGV4cHJlc3NpbmcgdGhlIGZhY3QgdGhhdCB0aGUKKyAgLy8vIGFzc29jaWF0ZWQgXHAgVmFyaWFibGUgbGl2ZXMgaW4gXHAgUmVnIChzdWl0YWJseSBtb2RpZmllZCBieSBccCBFeHByKS4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZERpcmVjdERiZ1ZhbHVlKHVuc2lnbmVkIFJlZywgY29uc3QgTUROb2RlICpWYXJpYWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1ETm9kZSAqRXhwcik7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgYSBEQkdfVkFMVUUgaW5zdHJ1Y3Rpb24gZXhwcmVzc2luZyB0aGUgZmFjdCB0aGF0IHRoZQorICAvLy8gYXNzb2NpYXRlZCBccCBWYXJpYWJsZSBsaXZlcyBpbiBtZW1vcnkgYXQgXHAgUmVnIChzdWl0YWJseSBtb2RpZmllZCBieSBccAorICAvLy8gRXhwcikuCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRJbmRpcmVjdERiZ1ZhbHVlKHVuc2lnbmVkIFJlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTUROb2RlICpWYXJpYWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTUROb2RlICpFeHByKTsKKworICAvLy8gQnVpbGQgYW5kIGluc2VydCBhIERCR19WQUxVRSBpbnN0cnVjdGlvbiBleHByZXNzaW5nIHRoZSBmYWN0IHRoYXQgdGhlCisgIC8vLyBhc3NvY2lhdGVkIFxwIFZhcmlhYmxlIGxpdmVzIGluIHRoZSBzdGFjayBzbG90IHNwZWNpZmllZCBieSBccCBGSQorICAvLy8gKHN1aXRhYmx5IG1vZGlmaWVkIGJ5IFxwIEV4cHIpLgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkRklEYmdWYWx1ZShpbnQgRkksIGNvbnN0IE1ETm9kZSAqVmFyaWFibGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1ETm9kZSAqRXhwcik7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgYSBEQkdfVkFMVUUgaW5zdHJ1Y3Rpb25zIHNwZWNpZnlpbmcgdGhhdCBccCBWYXJpYWJsZSBpcworICAvLy8gZ2l2ZW4gYnkgXHAgQyAoc3VpdGFibHkgbW9kaWZpZWQgYnkgXHAgRXhwcikuCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRDb25zdERiZ1ZhbHVlKGNvbnN0IENvbnN0YW50ICZDLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNRE5vZGUgKlZhcmlhYmxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNRE5vZGUgKkV4cHIpOworCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IFxwIFJlcyA9IEdfRlJBTUVfSU5ERVggXHAgSWR4CisgIC8vLworICAvLy8gR19GUkFNRV9JTkRFWCBtYXRlcmlhbGl6ZXMgdGhlIGFkZHJlc3Mgb2YgYW4gYWxsb2NhIHZhbHVlIG9yIG90aGVyCisgIC8vLyBzdGFjay1iYXNlZCBvYmplY3QuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgXHAgUmVzIG11c3QgYmUgYSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXIgd2l0aCBwb2ludGVyIHR5cGUuCisgIC8vLworICAvLy8gXHJldHVybiBhIE1hY2hpbmVJbnN0ckJ1aWxkZXIgZm9yIHRoZSBuZXdseSBjcmVhdGVkIGluc3RydWN0aW9uLgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkRnJhbWVJbmRleCh1bnNpZ25lZCBSZXMsIGludCBJZHgpOworCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IFxwIFJlcyA9IEdfR0xPQkFMX1ZBTFVFIFxwIEdWCisgIC8vLworICAvLy8gR19HTE9CQUxfVkFMVUUgbWF0ZXJpYWxpemVzIHRoZSBhZGRyZXNzIG9mIHRoZSBzcGVjaWZpZWQgZ2xvYmFsCisgIC8vLyBpbnRvIFxwIFJlcy4KKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBccCBSZXMgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHBvaW50ZXIgdHlwZQorICAvLy8gICAgICBpbiB0aGUgc2FtZSBhZGRyZXNzIHNwYWNlIGFzIFxwIEdWLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gYSBNYWNoaW5lSW5zdHJCdWlsZGVyIGZvciB0aGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZEdsb2JhbFZhbHVlKHVuc2lnbmVkIFJlcywgY29uc3QgR2xvYmFsVmFsdWUgKkdWKTsKKworICAvLy8gQnVpbGQgYW5kIGluc2VydCBccCBSZXMgPSBHX0FERCBccCBPcDAsIFxwIE9wMQorICAvLy8KKyAgLy8vIEdfQUREIHNldHMgXHAgUmVzIHRvIHRoZSBzdW0gb2YgaW50ZWdlciBwYXJhbWV0ZXJzIFxwIE9wMCBhbmQgXHAgT3AxLAorICAvLy8gdHJ1bmNhdGVkIHRvIHRoZWlyIHdpZHRoLgorICAvLy8KKyAgLy8vIFxwcmUgc2V0QmFzaWNCbG9jayBvciBzZXRNSSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQuCisgIC8vLyBccHJlIFxwIFJlcywgXHAgT3AwIGFuZCBccCBPcDEgbXVzdCBiZSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXJzCisgIC8vLyAgICAgIHdpdGggdGhlIHNhbWUgKHNjYWxhciBvciB2ZWN0b3IpIHR5cGUpLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gYSBNYWNoaW5lSW5zdHJCdWlsZGVyIGZvciB0aGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZEFkZCh1bnNpZ25lZCBSZXMsIHVuc2lnbmVkIE9wMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBPcDEpOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRHN0VHksIHR5cGVuYW1lLi4uIFVzZUFyZ3NUeT4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZEFkZChEc3RUeSAmJlR5LCBVc2VBcmdzVHkgJiYuLi4gVXNlQXJncykgeworICAgIHVuc2lnbmVkIFJlcyA9IGdldERlc3RGcm9tQXJnKFR5KTsKKyAgICByZXR1cm4gYnVpbGRBZGQoUmVzLCAoZ2V0UmVnRnJvbUFyZyhVc2VBcmdzKSkuLi4pOworICB9CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgXHAgUmVzID0gR19TVUIgXHAgT3AwLCBccCBPcDEKKyAgLy8vCisgIC8vLyBHX1NVQiBzZXRzIFxwIFJlcyB0byB0aGUgc3VtIG9mIGludGVnZXIgcGFyYW1ldGVycyBccCBPcDAgYW5kIFxwIE9wMSwKKyAgLy8vIHRydW5jYXRlZCB0byB0aGVpciB3aWR0aC4KKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBccCBSZXMsIFxwIE9wMCBhbmQgXHAgT3AxIG11c3QgYmUgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVycworICAvLy8gICAgICB3aXRoIHRoZSBzYW1lIChzY2FsYXIgb3IgdmVjdG9yKSB0eXBlKS4KKyAgLy8vCisgIC8vLyBccmV0dXJuIGEgTWFjaGluZUluc3RyQnVpbGRlciBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBEc3RUeSwgdHlwZW5hbWUuLi4gVXNlQXJnc1R5PgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkU3ViKERzdFR5ICYmVHksIFVzZUFyZ3NUeSAmJi4uLiBVc2VBcmdzKSB7CisgICAgdW5zaWduZWQgUmVzID0gZ2V0RGVzdEZyb21BcmcoVHkpOworICAgIHJldHVybiBidWlsZFN1YihSZXMsIChnZXRSZWdGcm9tQXJnKFVzZUFyZ3MpKS4uLik7CisgIH0KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZFN1Yih1bnNpZ25lZCBSZXMsIHVuc2lnbmVkIE9wMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBPcDEpOworCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IFxwIFJlcyA9IEdfTVVMIFxwIE9wMCwgXHAgT3AxCisgIC8vLworICAvLy8gR19NVUwgc2V0cyBccCBSZXMgdG8gdGhlIHN1bSBvZiBpbnRlZ2VyIHBhcmFtZXRlcnMgXHAgT3AwIGFuZCBccCBPcDEsCisgIC8vLyB0cnVuY2F0ZWQgdG8gdGhlaXIgd2lkdGguCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgXHAgUmVzLCBccCBPcDAgYW5kIFxwIE9wMSBtdXN0IGJlIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlcnMKKyAgLy8vICAgICAgd2l0aCB0aGUgc2FtZSAoc2NhbGFyIG9yIHZlY3RvcikgdHlwZSkuCisgIC8vLworICAvLy8gXHJldHVybiBhIE1hY2hpbmVJbnN0ckJ1aWxkZXIgZm9yIHRoZSBuZXdseSBjcmVhdGVkIGluc3RydWN0aW9uLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRHN0VHksIHR5cGVuYW1lLi4uIFVzZUFyZ3NUeT4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZE11bChEc3RUeSAmJlR5LCBVc2VBcmdzVHkgJiYuLi4gVXNlQXJncykgeworICAgIHVuc2lnbmVkIFJlcyA9IGdldERlc3RGcm9tQXJnKFR5KTsKKyAgICByZXR1cm4gYnVpbGRNdWwoUmVzLCAoZ2V0UmVnRnJvbUFyZyhVc2VBcmdzKSkuLi4pOworICB9CisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRNdWwodW5zaWduZWQgUmVzLCB1bnNpZ25lZCBPcDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgT3AxKTsKKworICAvLy8gQnVpbGQgYW5kIGluc2VydCBccCBSZXMgPSBHX0dFUCBccCBPcDAsIFxwIE9wMQorICAvLy8KKyAgLy8vIEdfR0VQIGFkZHMgXHAgT3AxIGJ5dGVzIHRvIHRoZSBwb2ludGVyIHNwZWNpZmllZCBieSBccCBPcDAsCisgIC8vLyBzdG9yaW5nIHRoZSByZXN1bHRpbmcgcG9pbnRlciBpbiBccCBSZXMuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgXHAgUmVzIGFuZCBccCBPcDAgbXVzdCBiZSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXJzIHdpdGggcG9pbnRlcgorICAvLy8gICAgICB0eXBlLgorICAvLy8gXHByZSBccCBPcDEgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciB0eXBlLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gYSBNYWNoaW5lSW5zdHJCdWlsZGVyIGZvciB0aGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZEdFUCh1bnNpZ25lZCBSZXMsIHVuc2lnbmVkIE9wMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBPcDEpOworCisgIC8vLyBNYXRlcmlhbGl6ZSBhbmQgaW5zZXJ0IFxwIFJlcyA9IEdfR0VQIFxwIE9wMCwgKEdfQ09OU1RBTlQgXHAgVmFsdWUpCisgIC8vLworICAvLy8gR19HRVAgYWRkcyBccCBWYWx1ZSBieXRlcyB0byB0aGUgcG9pbnRlciBzcGVjaWZpZWQgYnkgXHAgT3AwLAorICAvLy8gc3RvcmluZyB0aGUgcmVzdWx0aW5nIHBvaW50ZXIgaW4gXHAgUmVzLiBJZiBccCBWYWx1ZSBpcyB6ZXJvIHRoZW4gbm8KKyAgLy8vIEdfR0VQIG9yIEdfQ09OU1RBTlQgd2lsbCBiZSBjcmVhdGVkIGFuZCBccHJlIE9wMCB3aWxsIGJlIGFzc2lnbmVkIHRvCisgIC8vLyBccCBSZXMuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgXHAgT3AwIG11c3QgYmUgYSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXIgd2l0aCBwb2ludGVyIHR5cGUuCisgIC8vLyBccHJlIFxwIFZhbHVlVHkgbXVzdCBiZSBhIHNjYWxhciB0eXBlLgorICAvLy8gXHByZSBccCBSZXMgbXVzdCBiZSAwLiBUaGlzIGlzIHRvIGRldGVjdCBjb25mdXNpb24gYmV0d2VlbgorICAvLy8gICAgICBtYXRlcmlhbGl6ZUdFUCgpIGFuZCBidWlsZEdFUCgpLgorICAvLy8gXHBvc3QgXHAgUmVzIHdpbGwgZWl0aGVyIGJlIGEgbmV3IGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciBvZiB0aGUgc2FtZQorICAvLy8gICAgICAgdHlwZSBhcyBccCBPcDAgb3IgXHAgT3AwIGl0c2VsZi4KKyAgLy8vCisgIC8vLyBccmV0dXJuIGEgTWFjaGluZUluc3RyQnVpbGRlciBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE9wdGlvbmFsPE1hY2hpbmVJbnN0ckJ1aWxkZXI+IG1hdGVyaWFsaXplR0VQKHVuc2lnbmVkICZSZXMsIHVuc2lnbmVkIE9wMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTExUICZWYWx1ZVR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50NjRfdCBWYWx1ZSk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgXHAgUmVzID0gR19QVFJfTUFTSyBccCBPcDAsIFxwIE51bUJpdHMKKyAgLy8vCisgIC8vLyBHX1BUUl9NQVNLIGNsZWFycyB0aGUgbG93IGJpdHMgb2YgYSBwb2ludGVyIG9wZXJhbmQgd2l0aG91dCBkZXN0cm95aW5nIGl0cworICAvLy8gcG9pbnRlciBwcm9wZXJ0aWVzLiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIHJvdW5kaW5nIHRoZSBhZGRyZXNzICpkb3duKiB0bworICAvLy8gYSBzcGVjaWZpZWQgYWxpZ25tZW50IGluIGJpdHMuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgXHAgUmVzIGFuZCBccCBPcDAgbXVzdCBiZSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXJzIHdpdGggcG9pbnRlcgorICAvLy8gICAgICB0eXBlLgorICAvLy8gXHByZSBccCBOdW1CaXRzIG11c3QgYmUgYW4gaW50ZWdlciByZXByZXNlbnRpbmcgdGhlIG51bWJlciBvZiBsb3cgYml0cyB0bworICAvLy8gICAgICBiZSBjbGVhcmVkIGluIFxwIE9wMC4KKyAgLy8vCisgIC8vLyBccmV0dXJuIGEgTWFjaGluZUluc3RyQnVpbGRlciBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRQdHJNYXNrKHVuc2lnbmVkIFJlcywgdW5zaWduZWQgT3AwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBOdW1CaXRzKTsKKworICAvLy8gQnVpbGQgYW5kIGluc2VydCBccCBSZXMsIFxwIENhcnJ5T3V0ID0gR19VQURERSBccCBPcDAsCisgIC8vLyBccCBPcDEsIFxwIENhcnJ5SW4KKyAgLy8vCisgIC8vLyBHX1VBRERFIHNldHMgXHAgUmVzIHRvIFxwIE9wMCArIFxwIE9wMSArIFxwIENhcnJ5SW4gKHRydW5jYXRlZCB0byB0aGUgYml0CisgIC8vLyB3aWR0aCkgYW5kIHNldHMgXHAgQ2FycnlPdXQgdG8gMSBpZiB0aGUgcmVzdWx0IG92ZXJmbG93ZWQgaW4gdW5zaWduZWQKKyAgLy8vIGFyaXRobWV0aWMuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgXHAgUmVzLCBccCBPcDAgYW5kIFxwIE9wMSBtdXN0IGJlIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlcnMKKyAgLy8vICAgICAgd2l0aCB0aGUgc2FtZSBzY2FsYXIgdHlwZS4KKyAgLy8vIFxwcmUgXHAgQ2FycnlPdXQgYW5kIFxwIENhcnJ5SW4gbXVzdCBiZSBnZW5lcmljIHZpcnR1YWwKKyAgLy8vICAgICAgcmVnaXN0ZXJzIHdpdGggdGhlIHNhbWUgc2NhbGFyIHR5cGUgKHR5cGljYWxseSBzMSkKKyAgLy8vCisgIC8vLyBccmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIGluc3RydWN0aW9uLgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkVUFkZGUodW5zaWduZWQgUmVzLCB1bnNpZ25lZCBDYXJyeU91dCwgdW5zaWduZWQgT3AwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgT3AxLCB1bnNpZ25lZCBDYXJyeUluKTsKKworICAvLy8gQnVpbGQgYW5kIGluc2VydCBccCBSZXMgPSBHX0FORCBccCBPcDAsIFxwIE9wMQorICAvLy8KKyAgLy8vIEdfQU5EIHNldHMgXHAgUmVzIHRvIHRoZSBiaXR3aXNlIGFuZCBvZiBpbnRlZ2VyIHBhcmFtZXRlcnMgXHAgT3AwIGFuZCBccAorICAvLy8gT3AxLgorICAvLy8KKyAgLy8vIFxwcmUgc2V0QmFzaWNCbG9jayBvciBzZXRNSSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQuCisgIC8vLyBccHJlIFxwIFJlcywgXHAgT3AwIGFuZCBccCBPcDEgbXVzdCBiZSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXJzCisgIC8vLyAgICAgIHdpdGggdGhlIHNhbWUgKHNjYWxhciBvciB2ZWN0b3IpIHR5cGUpLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gYSBNYWNoaW5lSW5zdHJCdWlsZGVyIGZvciB0aGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIERzdFR5LCB0eXBlbmFtZS4uLiBVc2VBcmdzVHk+CisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRBbmQoRHN0VHkgJiZEc3QsIFVzZUFyZ3NUeSAmJi4uLiBVc2VBcmdzKSB7CisgICAgcmV0dXJuIGJ1aWxkQW5kKGdldERlc3RGcm9tQXJnKERzdCksIGdldFJlZ0Zyb21BcmcoVXNlQXJncykuLi4pOworICB9CisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRBbmQodW5zaWduZWQgUmVzLCB1bnNpZ25lZCBPcDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgT3AxKTsKKworICAvLy8gQnVpbGQgYW5kIGluc2VydCBccCBSZXMgPSBHX09SIFxwIE9wMCwgXHAgT3AxCisgIC8vLworICAvLy8gR19PUiBzZXRzIFxwIFJlcyB0byB0aGUgYml0d2lzZSBvciBvZiBpbnRlZ2VyIHBhcmFtZXRlcnMgXHAgT3AwIGFuZCBccAorICAvLy8gT3AxLgorICAvLy8KKyAgLy8vIFxwcmUgc2V0QmFzaWNCbG9jayBvciBzZXRNSSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQuCisgIC8vLyBccHJlIFxwIFJlcywgXHAgT3AwIGFuZCBccCBPcDEgbXVzdCBiZSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXJzCisgIC8vLyAgICAgIHdpdGggdGhlIHNhbWUgKHNjYWxhciBvciB2ZWN0b3IpIHR5cGUpLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gYSBNYWNoaW5lSW5zdHJCdWlsZGVyIGZvciB0aGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIERzdFR5LCB0eXBlbmFtZS4uLiBVc2VBcmdzVHk+CisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRPcihEc3RUeSAmJkRzdCwgVXNlQXJnc1R5ICYmLi4uIFVzZUFyZ3MpIHsKKyAgICByZXR1cm4gYnVpbGRPcihnZXREZXN0RnJvbUFyZyhEc3QpLCBnZXRSZWdGcm9tQXJnKFVzZUFyZ3MpLi4uKTsKKyAgfQorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkT3IodW5zaWduZWQgUmVzLCB1bnNpZ25lZCBPcDAsIHVuc2lnbmVkIE9wMSk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgXHAgUmVzID0gR19BTllFWFQgXHAgT3AwCisgIC8vLworICAvLy8gR19BTllFWFQgcHJvZHVjZXMgYSByZWdpc3RlciBvZiB0aGUgc3BlY2lmaWVkIHdpZHRoLCB3aXRoIGJpdHMgMCB0bworICAvLy8gc2l6ZW9mKFxwIFR5KSAqIDggc2V0IHRvIFxwIE9wLiBUaGUgcmVtYWluaW5nIGJpdHMgYXJlIHVuc3BlY2lmaWVkCisgIC8vLyAoaS5lLiB0aGlzIGlzIG5laXRoZXIgemVybyBub3Igc2lnbi1leHRlbnNpb24pLiBGb3IgYSB2ZWN0b3IgcmVnaXN0ZXIsCisgIC8vLyBlYWNoIGVsZW1lbnQgaXMgZXh0ZW5kZWQgaW5kaXZpZHVhbGx5LgorICAvLy8KKyAgLy8vIFxwcmUgc2V0QmFzaWNCbG9jayBvciBzZXRNSSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQuCisgIC8vLyBccHJlIFxwIFJlcyBtdXN0IGJlIGEgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVyIHdpdGggc2NhbGFyIG9yIHZlY3RvciB0eXBlLgorICAvLy8gXHByZSBccCBPcCBtdXN0IGJlIGEgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVyIHdpdGggc2NhbGFyIG9yIHZlY3RvciB0eXBlLgorICAvLy8gXHByZSBccCBPcCBtdXN0IGJlIHNtYWxsZXIgdGhhbiBccCBSZXMKKyAgLy8vCisgIC8vLyBccmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIGluc3RydWN0aW9uLgorCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRBbnlFeHQodW5zaWduZWQgUmVzLCB1bnNpZ25lZCBPcCk7CisgIHRlbXBsYXRlIDx0eXBlbmFtZSBEc3RUeXBlLCB0eXBlbmFtZSBBcmdUeXBlPgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkQW55RXh0KERzdFR5cGUgJiZSZXMsIEFyZ1R5cGUgJiZBcmcpIHsKKyAgICByZXR1cm4gYnVpbGRBbnlFeHQoZ2V0RGVzdEZyb21BcmcoUmVzKSwgZ2V0UmVnRnJvbUFyZyhBcmcpKTsKKyAgfQorCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IFxwIFJlcyA9IEdfU0VYVCBccCBPcAorICAvLy8KKyAgLy8vIEdfU0VYVCBwcm9kdWNlcyBhIHJlZ2lzdGVyIG9mIHRoZSBzcGVjaWZpZWQgd2lkdGgsIHdpdGggYml0cyAwIHRvCisgIC8vLyBzaXplb2YoXHAgVHkpICogOCBzZXQgdG8gXHAgT3AuIFRoZSByZW1haW5pbmcgYml0cyBhcmUgZHVwbGljYXRlZCBmcm9tIHRoZQorICAvLy8gaGlnaCBiaXQgb2YgXHAgT3AgKGkuZS4gMnMtY29tcGxlbWVudCBzaWduIGV4dGVuZGVkKS4KKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBccCBSZXMgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciBvciB2ZWN0b3IgdHlwZS4KKyAgLy8vIFxwcmUgXHAgT3AgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciBvciB2ZWN0b3IgdHlwZS4KKyAgLy8vIFxwcmUgXHAgT3AgbXVzdCBiZSBzbWFsbGVyIHRoYW4gXHAgUmVzCisgIC8vLworICAvLy8gXHJldHVybiBUaGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIERzdFR5cGUsIHR5cGVuYW1lIEFyZ1R5cGU+CisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRTRXh0KERzdFR5cGUgJiZSZXMsIEFyZ1R5cGUgJiZBcmcpIHsKKyAgICByZXR1cm4gYnVpbGRTRXh0KGdldERlc3RGcm9tQXJnKFJlcyksIGdldFJlZ0Zyb21BcmcoQXJnKSk7CisgIH0KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZFNFeHQodW5zaWduZWQgUmVzLCB1bnNpZ25lZCBPcCk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgXHAgUmVzID0gR19aRVhUIFxwIE9wCisgIC8vLworICAvLy8gR19aRVhUIHByb2R1Y2VzIGEgcmVnaXN0ZXIgb2YgdGhlIHNwZWNpZmllZCB3aWR0aCwgd2l0aCBiaXRzIDAgdG8KKyAgLy8vIHNpemVvZihccCBUeSkgKiA4IHNldCB0byBccCBPcC4gVGhlIHJlbWFpbmluZyBiaXRzIGFyZSAwLiBGb3IgYSB2ZWN0b3IKKyAgLy8vIHJlZ2lzdGVyLCBlYWNoIGVsZW1lbnQgaXMgZXh0ZW5kZWQgaW5kaXZpZHVhbGx5LgorICAvLy8KKyAgLy8vIFxwcmUgc2V0QmFzaWNCbG9jayBvciBzZXRNSSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQuCisgIC8vLyBccHJlIFxwIFJlcyBtdXN0IGJlIGEgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVyIHdpdGggc2NhbGFyIG9yIHZlY3RvciB0eXBlLgorICAvLy8gXHByZSBccCBPcCBtdXN0IGJlIGEgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVyIHdpdGggc2NhbGFyIG9yIHZlY3RvciB0eXBlLgorICAvLy8gXHByZSBccCBPcCBtdXN0IGJlIHNtYWxsZXIgdGhhbiBccCBSZXMKKyAgLy8vCisgIC8vLyBccmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIGluc3RydWN0aW9uLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRHN0VHlwZSwgdHlwZW5hbWUgQXJnVHlwZT4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZFpFeHQoRHN0VHlwZSAmJlJlcywgQXJnVHlwZSAmJkFyZykgeworICAgIHJldHVybiBidWlsZFpFeHQoZ2V0RGVzdEZyb21BcmcoUmVzKSwgZ2V0UmVnRnJvbUFyZyhBcmcpKTsKKyAgfQorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkWkV4dCh1bnNpZ25lZCBSZXMsIHVuc2lnbmVkIE9wKTsKKworICAvLy8gQnVpbGQgYW5kIGluc2VydCBccCBSZXMgPSBHX1NFWFQgXHAgT3AsIFxwIFJlcyA9IEdfVFJVTkMgXHAgT3AsIG9yCisgIC8vLyBccCBSZXMgPSBDT1BZIFxwIE9wIGRlcGVuZGluZyBvbiB0aGUgZGlmZmVyaW5nIHNpemVzIG9mIFxwIFJlcyBhbmQgXHAgT3AuCisgIC8vLyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBccCBSZXMgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciBvciB2ZWN0b3IgdHlwZS4KKyAgLy8vIFxwcmUgXHAgT3AgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciBvciB2ZWN0b3IgdHlwZS4KKyAgLy8vCisgIC8vLyBccmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIGluc3RydWN0aW9uLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRHN0VHksIHR5cGVuYW1lIFVzZUFyZ1R5PgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkU0V4dE9yVHJ1bmMoRHN0VHkgJiZEc3QsIFVzZUFyZ1R5ICYmVXNlKSB7CisgICAgcmV0dXJuIGJ1aWxkU0V4dE9yVHJ1bmMoZ2V0RGVzdEZyb21BcmcoRHN0KSwgZ2V0UmVnRnJvbUFyZyhVc2UpKTsKKyAgfQorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkU0V4dE9yVHJ1bmModW5zaWduZWQgUmVzLCB1bnNpZ25lZCBPcCk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgXHAgUmVzID0gR19aRVhUIFxwIE9wLCBccCBSZXMgPSBHX1RSVU5DIFxwIE9wLCBvcgorICAvLy8gXHAgUmVzID0gQ09QWSBccCBPcCBkZXBlbmRpbmcgb24gdGhlIGRpZmZlcmluZyBzaXplcyBvZiBccCBSZXMgYW5kIFxwIE9wLgorICAvLy8gIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgXHAgUmVzIG11c3QgYmUgYSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXIgd2l0aCBzY2FsYXIgb3IgdmVjdG9yIHR5cGUuCisgIC8vLyBccHJlIFxwIE9wIG11c3QgYmUgYSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXIgd2l0aCBzY2FsYXIgb3IgdmVjdG9yIHR5cGUuCisgIC8vLworICAvLy8gXHJldHVybiBUaGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIERzdFR5LCB0eXBlbmFtZSBVc2VBcmdUeT4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZFpFeHRPclRydW5jKERzdFR5ICYmRHN0LCBVc2VBcmdUeSAmJlVzZSkgeworICAgIHJldHVybiBidWlsZFpFeHRPclRydW5jKGdldERlc3RGcm9tQXJnKERzdCksIGdldFJlZ0Zyb21BcmcoVXNlKSk7CisgIH0KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZFpFeHRPclRydW5jKHVuc2lnbmVkIFJlcywgdW5zaWduZWQgT3ApOworCisgIC8vIEJ1aWxkIGFuZCBpbnNlcnQgXHAgUmVzID0gR19BTllFWFQgXHAgT3AsIFxwIFJlcyA9IEdfVFJVTkMgXHAgT3AsIG9yCisgIC8vLyBccCBSZXMgPSBDT1BZIFxwIE9wIGRlcGVuZGluZyBvbiB0aGUgZGlmZmVyaW5nIHNpemVzIG9mIFxwIFJlcyBhbmQgXHAgT3AuCisgIC8vLyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBccCBSZXMgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciBvciB2ZWN0b3IgdHlwZS4KKyAgLy8vIFxwcmUgXHAgT3AgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciBvciB2ZWN0b3IgdHlwZS4KKyAgLy8vCisgIC8vLyBccmV0dXJuIFRoZSBuZXdseSBjcmVhdGVkIGluc3RydWN0aW9uLgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRHN0VHksIHR5cGVuYW1lIFVzZUFyZ1R5PgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkQW55RXh0T3JUcnVuYyhEc3RUeSAmJkRzdCwgVXNlQXJnVHkgJiZVc2UpIHsKKyAgICByZXR1cm4gYnVpbGRBbnlFeHRPclRydW5jKGdldERlc3RGcm9tQXJnKERzdCksIGdldFJlZ0Zyb21BcmcoVXNlKSk7CisgIH0KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZEFueUV4dE9yVHJ1bmModW5zaWduZWQgUmVzLCB1bnNpZ25lZCBPcCk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgXHAgUmVzID0gXHAgRXh0T3BjLCBccCBSZXMgPSBHX1RSVU5DIFxwCisgIC8vLyBPcCwgb3IgXHAgUmVzID0gQ09QWSBccCBPcCBkZXBlbmRpbmcgb24gdGhlIGRpZmZlcmluZyBzaXplcyBvZiBccCBSZXMgYW5kCisgIC8vLyBccCBPcC4KKyAgLy8vICAvLy8KKyAgLy8vIFxwcmUgc2V0QmFzaWNCbG9jayBvciBzZXRNSSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQuCisgIC8vLyBccHJlIFxwIFJlcyBtdXN0IGJlIGEgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVyIHdpdGggc2NhbGFyIG9yIHZlY3RvciB0eXBlLgorICAvLy8gXHByZSBccCBPcCBtdXN0IGJlIGEgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVyIHdpdGggc2NhbGFyIG9yIHZlY3RvciB0eXBlLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRFeHRPclRydW5jKHVuc2lnbmVkIEV4dE9wYywgdW5zaWduZWQgUmVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBPcCk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgYW4gYXBwcm9wcmlhdGUgY2FzdCBiZXR3ZWVuIHR3byByZWdpc3RlcnMgb2YgZXF1YWwgc2l6ZS4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIERzdFR5cGUsIHR5cGVuYW1lIEFyZ1R5cGU+CisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRDYXN0KERzdFR5cGUgJiZSZXMsIEFyZ1R5cGUgJiZBcmcpIHsKKyAgICByZXR1cm4gYnVpbGRDYXN0KGdldERlc3RGcm9tQXJnKFJlcyksIGdldFJlZ0Zyb21BcmcoQXJnKSk7CisgIH0KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZENhc3QodW5zaWduZWQgRHN0LCB1bnNpZ25lZCBTcmMpOworCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IEdfQlIgXHAgRGVzdAorICAvLy8KKyAgLy8vIEdfQlIgaXMgYW4gdW5jb25kaXRpb25hbCBicmFuY2ggdG8gXHAgRGVzdC4KKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gYSBNYWNoaW5lSW5zdHJCdWlsZGVyIGZvciB0aGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZEJyKE1hY2hpbmVCYXNpY0Jsb2NrICZCQik7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgR19CUkNPTkQgXHAgVHN0LCBccCBEZXN0CisgIC8vLworICAvLy8gR19CUkNPTkQgaXMgYSBjb25kaXRpb25hbCBicmFuY2ggdG8gXHAgRGVzdC4KKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBccCBUc3QgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhcgorICAvLy8gICAgICB0eXBlLiBBdCB0aGUgYmVnaW5uaW5nIG9mIGxlZ2FsaXphdGlvbiwgdGhpcyB3aWxsIGJlIGEgc2luZ2xlCisgIC8vLyAgICAgIGJpdCAoczEpLiBUYXJnZXRzIHdpdGggaW50ZXJlc3RpbmcgZmxhZ3MgcmVnaXN0ZXJzIG1heSBjaGFuZ2UKKyAgLy8vICAgICAgdGhpcy4gRm9yIGEgd2lkZXIgdHlwZSwgd2hldGhlciB0aGUgYnJhbmNoIGlzIHRha2VuIG11c3Qgb25seQorICAvLy8gICAgICBkZXBlbmQgb24gYml0IDAgKGZvciBub3cpLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRCckNvbmQodW5zaWduZWQgVHN0LCBNYWNoaW5lQmFzaWNCbG9jayAmQkIpOworCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IEdfQlJJTkRJUkVDVCBccCBUZ3QKKyAgLy8vCisgIC8vLyBHX0JSSU5ESVJFQ1QgaXMgYW4gaW5kaXJlY3QgYnJhbmNoIHRvIFxwIFRndC4KKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBccCBUZ3QgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHBvaW50ZXIgdHlwZS4KKyAgLy8vCisgIC8vLyBccmV0dXJuIGEgTWFjaGluZUluc3RyQnVpbGRlciBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRCckluZGlyZWN0KHVuc2lnbmVkIFRndCk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgXHAgUmVzID0gR19DT05TVEFOVCBccCBWYWwKKyAgLy8vCisgIC8vLyBHX0NPTlNUQU5UIGlzIGFuIGludGVnZXIgY29uc3RhbnQgd2l0aCB0aGUgc3BlY2lmaWVkIHNpemUgYW5kIHZhbHVlLiBccAorICAvLy8gVmFsIHdpbGwgYmUgZXh0ZW5kZWQgb3IgdHJ1bmNhdGVkIHRvIHRoZSBzaXplIG9mIFxwIFJlZy4KKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBccCBSZXMgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciBvciBwb2ludGVyCisgIC8vLyAgICAgIHR5cGUuCisgIC8vLworICAvLy8gXHJldHVybiBUaGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZENvbnN0YW50KHVuc2lnbmVkIFJlcywgY29uc3QgQ29uc3RhbnRJbnQgJlZhbCk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgXHAgUmVzID0gR19DT05TVEFOVCBccCBWYWwKKyAgLy8vCisgIC8vLyBHX0NPTlNUQU5UIGlzIGFuIGludGVnZXIgY29uc3RhbnQgd2l0aCB0aGUgc3BlY2lmaWVkIHNpemUgYW5kIHZhbHVlLgorICAvLy8KKyAgLy8vIFxwcmUgc2V0QmFzaWNCbG9jayBvciBzZXRNSSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQuCisgIC8vLyBccHJlIFxwIFJlcyBtdXN0IGJlIGEgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVyIHdpdGggc2NhbGFyIHR5cGUuCisgIC8vLworICAvLy8gXHJldHVybiBUaGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZENvbnN0YW50KHVuc2lnbmVkIFJlcywgaW50NjRfdCBWYWwpOworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBEc3RUeXBlPgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkQ29uc3RhbnQoRHN0VHlwZSAmJlJlcywgaW50NjRfdCBWYWwpIHsKKyAgICByZXR1cm4gYnVpbGRDb25zdGFudChnZXREZXN0RnJvbUFyZyhSZXMpLCBWYWwpOworICB9CisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IFxwIFJlcyA9IEdfRkNPTlNUQU5UIFxwIFZhbAorICAvLy8KKyAgLy8vIEdfRkNPTlNUQU5UIGlzIGEgZmxvYXRpbmctcG9pbnQgY29uc3RhbnQgd2l0aCB0aGUgc3BlY2lmaWVkIHNpemUgYW5kCisgIC8vLyB2YWx1ZS4KKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBccCBSZXMgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciB0eXBlLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBEc3RUeXBlPgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkRkNvbnN0YW50KERzdFR5cGUgJiZSZXMsIGNvbnN0IENvbnN0YW50RlAgJlZhbCkgeworICAgIHJldHVybiBidWlsZEZDb25zdGFudChnZXREZXN0RnJvbUFyZyhSZXMpLCBWYWwpOworICB9CisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRGQ29uc3RhbnQodW5zaWduZWQgUmVzLCBjb25zdCBDb25zdGFudEZQICZWYWwpOworCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBEc3RUeXBlPgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkRkNvbnN0YW50KERzdFR5cGUgJiZSZXMsIGRvdWJsZSBWYWwpIHsKKyAgICByZXR1cm4gYnVpbGRGQ29uc3RhbnQoZ2V0RGVzdEZyb21BcmcoUmVzKSwgVmFsKTsKKyAgfQorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkRkNvbnN0YW50KHVuc2lnbmVkIFJlcywgZG91YmxlIFZhbCk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgXHAgUmVzID0gQ09QWSBPcAorICAvLy8KKyAgLy8vIFJlZ2lzdGVyLXRvLXJlZ2lzdGVyIENPUFkgc2V0cyBccCBSZXMgdG8gXHAgT3AuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vCisgIC8vLyBccmV0dXJuIGEgTWFjaGluZUluc3RyQnVpbGRlciBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRDb3B5KHVuc2lnbmVkIFJlcywgdW5zaWduZWQgT3ApOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRHN0VHlwZSwgdHlwZW5hbWUgU3JjVHlwZT4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZENvcHkoRHN0VHlwZSAmJlJlcywgU3JjVHlwZSAmJlNyYykgeworICAgIHJldHVybiBidWlsZENvcHkoZ2V0RGVzdEZyb21BcmcoUmVzKSwgZ2V0UmVnRnJvbUFyZyhTcmMpKTsKKyAgfQorCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IGBSZXMgPSBHX0xPQUQgQWRkciwgTU1PYC4KKyAgLy8vCisgIC8vLyBMb2FkcyB0aGUgdmFsdWUgc3RvcmVkIGF0IFxwIEFkZHIuIFB1dHMgdGhlIHJlc3VsdCBpbiBccCBSZXMuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgXHAgUmVzIG11c3QgYmUgYSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXIuCisgIC8vLyBccHJlIFxwIEFkZHIgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHBvaW50ZXIgdHlwZS4KKyAgLy8vCisgIC8vLyBccmV0dXJuIGEgTWFjaGluZUluc3RyQnVpbGRlciBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRMb2FkKHVuc2lnbmVkIFJlcywgdW5zaWduZWQgQWRkciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQgJk1NTyk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgYEdfU1RPUkUgVmFsLCBBZGRyLCBNTU9gLgorICAvLy8KKyAgLy8vIFN0b3JlcyB0aGUgdmFsdWUgXHAgVmFsIHRvIFxwIEFkZHIuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgXHAgVmFsIG11c3QgYmUgYSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXIuCisgIC8vLyBccHJlIFxwIEFkZHIgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHBvaW50ZXIgdHlwZS4KKyAgLy8vCisgIC8vLyBccmV0dXJuIGEgTWFjaGluZUluc3RyQnVpbGRlciBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRTdG9yZSh1bnNpZ25lZCBWYWwsIHVuc2lnbmVkIEFkZHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lTWVtT3BlcmFuZCAmTU1PKTsKKworICAvLy8gQnVpbGQgYW5kIGluc2VydCBgUmVzMCwgLi4uID0gR19FWFRSQUNUIFNyYywgSWR4MGAuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgXHAgUmVzIGFuZCBccCBTcmMgbXVzdCBiZSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXJzLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gYSBNYWNoaW5lSW5zdHJCdWlsZGVyIGZvciB0aGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZEV4dHJhY3QodW5zaWduZWQgUmVzLCB1bnNpZ25lZCBTcmMsIHVpbnQ2NF90IEluZGV4KTsKKworICAvLy8gQnVpbGQgYW5kIGluc2VydCBccCBSZXMgPSBJTVBMSUNJVF9ERUYuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBEc3RUeXBlPiBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkVW5kZWYoRHN0VHlwZSAmJlJlcykgeworICAgIHJldHVybiBidWlsZFVuZGVmKGdldERlc3RGcm9tQXJnKFJlcykpOworICB9CisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRVbmRlZih1bnNpZ25lZCBEc3QpOworCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IGluc3RydWN0aW9ucyB0byBwdXQgXHAgT3BzIHRvZ2V0aGVyIGF0IHRoZSBzcGVjaWZpZWQgcAorICAvLy8gSW5kaWNlcyB0byBmb3JtIGEgbGFyZ2VyIHJlZ2lzdGVyLgorICAvLy8KKyAgLy8vIElmIHRoZSB0eXBlcyBvZiB0aGUgaW5wdXQgcmVnaXN0ZXJzIGFyZSB1bmlmb3JtIGFuZCBjb3ZlciB0aGUgZW50aXJpdHkgb2YKKyAgLy8vIFxwIFJlcyB0aGVuIGEgR19NRVJHRV9WQUxVRVMgd2lsbCBiZSBwcm9kdWNlZC4gT3RoZXJ3aXNlIGFuIElNUExJQ0lUX0RFRgorICAvLy8gZm9sbG93ZWQgYnkgYSBzZXF1ZW5jZSBvZiBHX0lOU0VSVCBpbnN0cnVjdGlvbnMuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgVGhlIGZpbmFsIGVsZW1lbnQgb2YgdGhlIHNlcXVlbmNlIG11c3Qgbm90IGV4dGVuZCBwYXN0IHRoZSBlbmQgb2YgdGhlCisgIC8vLyAgICAgIGRlc3RpbmF0aW9uIHJlZ2lzdGVyLgorICAvLy8gXHByZSBUaGUgYml0cyBkZWZpbmVkIGJ5IGVhY2ggT3AgKGRlcml2ZWQgZnJvbSBpbmRleCBhbmQgc2NhbGFyIHNpemUpIG11c3QKKyAgLy8vICAgICAgbm90IG92ZXJsYXAuCisgIC8vLyBccHJlIFxwIEluZGljZXMgbXVzdCBiZSBpbiBhc2NlbmRpbmcgb3JkZXIgb2YgYml0IHBvc2l0aW9uLgorICB2b2lkIGJ1aWxkU2VxdWVuY2UodW5zaWduZWQgUmVzLCBBcnJheVJlZjx1bnNpZ25lZD4gT3BzLAorICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8dWludDY0X3Q+IEluZGljZXMpOworCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IFxwIFJlcyA9IEdfTUVSR0VfVkFMVUVTIFxwIE9wMCwgLi4uCisgIC8vLworICAvLy8gR19NRVJHRV9WQUxVRVMgY29tYmluZXMgdGhlIGlucHV0IGVsZW1lbnRzIGNvbnRpZ3VvdXNseSBpbnRvIGEgbGFyZ2VyCisgIC8vLyByZWdpc3Rlci4KKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBUaGUgZW50aXJlIHJlZ2lzdGVyIFxwIFJlcyAoYW5kIG5vIG1vcmUpIG11c3QgYmUgY292ZXJlZCBieSB0aGUgaW5wdXQKKyAgLy8vICAgICAgcmVnaXN0ZXJzLgorICAvLy8gXHByZSBUaGUgdHlwZSBvZiBhbGwgXHAgT3BzIHJlZ2lzdGVycyBtdXN0IGJlIGlkZW50aWNhbC4KKyAgLy8vCisgIC8vLyBccmV0dXJuIGEgTWFjaGluZUluc3RyQnVpbGRlciBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRNZXJnZSh1bnNpZ25lZCBSZXMsIEFycmF5UmVmPHVuc2lnbmVkPiBPcHMpOworCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IFxwIFJlczAsIC4uLiA9IEdfVU5NRVJHRV9WQUxVRVMgXHAgT3AKKyAgLy8vCisgIC8vLyBHX1VOTUVSR0VfVkFMVUVTIHNwbGl0cyBjb250aWd1b3VzIGJpdHMgb2YgdGhlIGlucHV0IGludG8gbXVsdGlwbGUKKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBUaGUgZW50aXJlIHJlZ2lzdGVyIFxwIFJlcyAoYW5kIG5vIG1vcmUpIG11c3QgYmUgY292ZXJlZCBieSB0aGUgaW5wdXQKKyAgLy8vICAgICAgcmVnaXN0ZXJzLgorICAvLy8gXHByZSBUaGUgdHlwZSBvZiBhbGwgXHAgUmVzIHJlZ2lzdGVycyBtdXN0IGJlIGlkZW50aWNhbC4KKyAgLy8vCisgIC8vLyBccmV0dXJuIGEgTWFjaGluZUluc3RyQnVpbGRlciBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRVbm1lcmdlKEFycmF5UmVmPHVuc2lnbmVkPiBSZXMsIHVuc2lnbmVkIE9wKTsKKworICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkSW5zZXJ0KHVuc2lnbmVkIFJlcywgdW5zaWduZWQgU3JjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIE9wLCB1bnNpZ25lZCBJbmRleCk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgZWl0aGVyIGEgR19JTlRSSU5TSUMgKGlmIFxwIEhhc1NpZGVFZmZlY3RzIGlzIGZhbHNlKSBvcgorICAvLy8gR19JTlRSSU5TSUNfV19TSURFX0VGRkVDVFMgaW5zdHJ1Y3Rpb24uIEl0cyBmaXJzdCBvcGVyYW5kIHdpbGwgYmUgdGhlCisgIC8vLyByZXN1bHQgcmVnaXN0ZXIgZGVmaW5pdGlvbiB1bmxlc3MgXHAgUmVnIGlzIE5vUmVnICg9PSAwKS4gVGhlIHNlY29uZAorICAvLy8gb3BlcmFuZCB3aWxsIGJlIHRoZSBpbnRyaW5zaWMncyBJRC4KKyAgLy8vCisgIC8vLyBDYWxsZXJzIGFyZSBleHBlY3RlZCB0byBhZGQgdGhlIHJlcXVpcmVkIGRlZmluaXRpb25zIGFuZCB1c2VzIGFmdGVyd2FyZHMuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vCisgIC8vLyBccmV0dXJuIGEgTWFjaGluZUluc3RyQnVpbGRlciBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRJbnRyaW5zaWMoSW50cmluc2ljOjpJRCBJRCwgdW5zaWduZWQgUmVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgSGFzU2lkZUVmZmVjdHMpOworCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IFxwIFJlcyA9IEdfRlBUUlVOQyBccCBPcAorICAvLy8KKyAgLy8vIEdfRlBUUlVOQyBjb252ZXJ0cyBhIGZsb2F0aW5nLXBvaW50IHZhbHVlIGludG8gb25lIHdpdGggYSBzbWFsbGVyIHR5cGUuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgXHAgUmVzIG11c3QgYmUgYSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXIgd2l0aCBzY2FsYXIgb3IgdmVjdG9yIHR5cGUuCisgIC8vLyBccHJlIFxwIE9wIG11c3QgYmUgYSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXIgd2l0aCBzY2FsYXIgb3IgdmVjdG9yIHR5cGUuCisgIC8vLyBccHJlIFxwIFJlcyBtdXN0IGJlIHNtYWxsZXIgdGhhbiBccCBPcAorICAvLy8KKyAgLy8vIFxyZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBEc3RUeXBlLCB0eXBlbmFtZSBTcmNUeXBlPgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkRlBUcnVuYyhEc3RUeXBlICYmUmVzLCBTcmNUeXBlICYmU3JjKSB7CisgICAgcmV0dXJuIGJ1aWxkRlBUcnVuYyhnZXREZXN0RnJvbUFyZyhSZXMpLCBnZXRSZWdGcm9tQXJnKFNyYykpOworICB9CisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRGUFRydW5jKHVuc2lnbmVkIFJlcywgdW5zaWduZWQgT3ApOworCisgIC8vLyBCdWlsZCBhbmQgaW5zZXJ0IFxwIFJlcyA9IEdfVFJVTkMgXHAgT3AKKyAgLy8vCisgIC8vLyBHX1RSVU5DIGV4dHJhY3RzIHRoZSBsb3cgYml0cyBvZiBhIHR5cGUuIEZvciBhIHZlY3RvciB0eXBlIGVhY2ggZWxlbWVudCBpcworICAvLy8gdHJ1bmNhdGVkIGluZGVwZW5kZW50bHkgYmVmb3JlIGJlaW5nIHBhY2tlZCBpbnRvIHRoZSBkZXN0aW5hdGlvbi4KKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBccCBSZXMgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciBvciB2ZWN0b3IgdHlwZS4KKyAgLy8vIFxwcmUgXHAgT3AgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciBvciB2ZWN0b3IgdHlwZS4KKyAgLy8vIFxwcmUgXHAgUmVzIG11c3QgYmUgc21hbGxlciB0aGFuIFxwIE9wCisgIC8vLworICAvLy8gXHJldHVybiBUaGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZFRydW5jKHVuc2lnbmVkIFJlcywgdW5zaWduZWQgT3ApOworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgRHN0VHlwZSwgdHlwZW5hbWUgU3JjVHlwZT4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZFRydW5jKERzdFR5cGUgJiZSZXMsIFNyY1R5cGUgJiZTcmMpIHsKKyAgICByZXR1cm4gYnVpbGRUcnVuYyhnZXREZXN0RnJvbUFyZyhSZXMpLCBnZXRSZWdGcm9tQXJnKFNyYykpOworICB9CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgYSBccCBSZXMgPSBHX0lDTVAgXHAgUHJlZCwgXHAgT3AwLCBccCBPcDEKKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorCisgIC8vLyBccHJlIFxwIFJlcyBtdXN0IGJlIGEgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVyIHdpdGggc2NhbGFyIG9yCisgIC8vLyAgICAgIHZlY3RvciB0eXBlLiBUeXBpY2FsbHkgdGhpcyBzdGFydHMgYXMgczEgb3IgPE4geCBzMT4uCisgIC8vLyBccHJlIFxwIE9wMCBhbmQgT3AxIG11c3QgYmUgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVycyB3aXRoIHRoZQorICAvLy8gICAgICBzYW1lIG51bWJlciBvZiBlbGVtZW50cyBhcyBccCBSZXMuIElmIFxwIFJlcyBpcyBhIHNjYWxhciwKKyAgLy8vICAgICAgXHAgT3AwIG11c3QgYmUgZWl0aGVyIGEgc2NhbGFyIG9yIHBvaW50ZXIuCisgIC8vLyBccHJlIFxwIFByZWQgbXVzdCBiZSBhbiBpbnRlZ2VyIHByZWRpY2F0ZS4KKyAgLy8vCisgIC8vLyBccmV0dXJuIGEgTWFjaGluZUluc3RyQnVpbGRlciBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRJQ21wKENtcEluc3Q6OlByZWRpY2F0ZSBQcmVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBSZXMsIHVuc2lnbmVkIE9wMCwgdW5zaWduZWQgT3AxKTsKKworICAvLy8gQnVpbGQgYW5kIGluc2VydCBhIFxwIFJlcyA9IEdfRkNNUCBccCBQcmVkXHAgT3AwLCBccCBPcDEKKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorCisgIC8vLyBccHJlIFxwIFJlcyBtdXN0IGJlIGEgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVyIHdpdGggc2NhbGFyIG9yCisgIC8vLyAgICAgIHZlY3RvciB0eXBlLiBUeXBpY2FsbHkgdGhpcyBzdGFydHMgYXMgczEgb3IgPE4geCBzMT4uCisgIC8vLyBccHJlIFxwIE9wMCBhbmQgT3AxIG11c3QgYmUgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVycyB3aXRoIHRoZQorICAvLy8gICAgICBzYW1lIG51bWJlciBvZiBlbGVtZW50cyBhcyBccCBSZXMgKG9yIHNjYWxhciwgaWYgXHAgUmVzIGlzCisgIC8vLyAgICAgIHNjYWxhcikuCisgIC8vLyBccHJlIFxwIFByZWQgbXVzdCBiZSBhIGZsb2F0aW5nLXBvaW50IHByZWRpY2F0ZS4KKyAgLy8vCisgIC8vLyBccmV0dXJuIGEgTWFjaGluZUluc3RyQnVpbGRlciBmb3IgdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRGQ21wKENtcEluc3Q6OlByZWRpY2F0ZSBQcmVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBSZXMsIHVuc2lnbmVkIE9wMCwgdW5zaWduZWQgT3AxKTsKKworICAvLy8gQnVpbGQgYW5kIGluc2VydCBhIFxwIFJlcyA9IEdfU0VMRUNUIFxwIFRzdCwgXHAgT3AwLCBccCBPcDEKKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBccCBSZXMsIFxwIE9wMCBhbmQgXHAgT3AxIG11c3QgYmUgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVycworICAvLy8gICAgICB3aXRoIHRoZSBzYW1lIHR5cGUuCisgIC8vLyBccHJlIFxwIFRzdCBtdXN0IGJlIGEgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVyIHdpdGggc2NhbGFyLCBwb2ludGVyIG9yCisgIC8vLyAgICAgIHZlY3RvciB0eXBlLiBJZiB2ZWN0b3IgdGhlbiBpdCBtdXN0IGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mCisgIC8vLyAgICAgIGVsZW1lbnRzIGFzIHRoZSBvdGhlciBwYXJhbWV0ZXJzLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gYSBNYWNoaW5lSW5zdHJCdWlsZGVyIGZvciB0aGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgTWFjaGluZUluc3RyQnVpbGRlciBidWlsZFNlbGVjdCh1bnNpZ25lZCBSZXMsIHVuc2lnbmVkIFRzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBPcDAsIHVuc2lnbmVkIE9wMSk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgXHAgUmVzID0gR19JTlNFUlRfVkVDVE9SX0VMVCBccCBWYWwsCisgIC8vLyBccCBFbHQsIFxwIElkeAorICAvLy8KKyAgLy8vIFxwcmUgc2V0QmFzaWNCbG9jayBvciBzZXRNSSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQuCisgIC8vLyBccHJlIFxwIFJlcyBhbmQgXHAgVmFsIG11c3QgYmUgYSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXIKKyAgLy8gICAgICAgd2l0aCB0aGUgc2FtZSB2ZWN0b3IgdHlwZS4KKyAgLy8vIFxwcmUgXHAgRWx0IGFuZCBccCBJZHggbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlcgorICAvLy8gICAgICB3aXRoIHNjYWxhciB0eXBlLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRJbnNlcnRWZWN0b3JFbGVtZW50KHVuc2lnbmVkIFJlcywgdW5zaWduZWQgVmFsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBFbHQsIHVuc2lnbmVkIElkeCk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgXHAgUmVzID0gR19FWFRSQUNUX1ZFQ1RPUl9FTFQgXHAgVmFsLCBccCBJZHgKKyAgLy8vCisgIC8vLyBccHJlIHNldEJhc2ljQmxvY2sgb3Igc2V0TUkgbXVzdCBoYXZlIGJlZW4gY2FsbGVkLgorICAvLy8gXHByZSBccCBSZXMgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciB0eXBlLgorICAvLy8gXHByZSBccCBWYWwgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHZlY3RvciB0eXBlLgorICAvLy8gXHByZSBccCBJZHggbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHNjYWxhciB0eXBlLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gVGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ckJ1aWxkZXIgYnVpbGRFeHRyYWN0VmVjdG9yRWxlbWVudCh1bnNpZ25lZCBSZXMsIHVuc2lnbmVkIFZhbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIElkeCk7CisKKyAgLy8vIEJ1aWxkIGFuZCBpbnNlcnQgYE9sZFZhbFJlcyA9IEdfQVRPTUlDX0NNUFhDSEcgQWRkciwgQ21wVmFsLCBOZXdWYWwsCisgIC8vLyBNTU9gLgorICAvLy8KKyAgLy8vIEF0b21pY2FsbHkgcmVwbGFjZSB0aGUgdmFsdWUgYXQgXHAgQWRkciB3aXRoIFxwIE5ld1ZhbCBpZiBpdCBpcyBjdXJyZW50bHkKKyAgLy8vIFxwIENtcFZhbCBvdGhlcndpc2UgbGVhdmVzIGl0IHVuY2hhbmdlZC4gUHV0cyB0aGUgb3JpZ2luYWwgdmFsdWUgZnJvbSBccAorICAvLy8gQWRkciBpbiBccCBSZXMuCisgIC8vLworICAvLy8gXHByZSBzZXRCYXNpY0Jsb2NrIG9yIHNldE1JIG11c3QgaGF2ZSBiZWVuIGNhbGxlZC4KKyAgLy8vIFxwcmUgXHAgT2xkVmFsUmVzIG11c3QgYmUgYSBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXIgb2Ygc2NhbGFyIHR5cGUuCisgIC8vLyBccHJlIFxwIEFkZHIgbXVzdCBiZSBhIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlciB3aXRoIHBvaW50ZXIgdHlwZS4KKyAgLy8vIFxwcmUgXHAgT2xkVmFsUmVzLCBccCBDbXBWYWwsIGFuZCBccCBOZXdWYWwgbXVzdCBiZSBnZW5lcmljIHZpcnR1YWwKKyAgLy8vICAgICAgcmVnaXN0ZXJzIG9mIHRoZSBzYW1lIHR5cGUuCisgIC8vLworICAvLy8gXHJldHVybiBhIE1hY2hpbmVJbnN0ckJ1aWxkZXIgZm9yIHRoZSBuZXdseSBjcmVhdGVkIGluc3RydWN0aW9uLgorICBNYWNoaW5lSW5zdHJCdWlsZGVyIGJ1aWxkQXRvbWljQ21wWGNoZyh1bnNpZ25lZCBPbGRWYWxSZXMsIHVuc2lnbmVkIEFkZHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIENtcFZhbCwgdW5zaWduZWQgTmV3VmFsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lTWVtT3BlcmFuZCAmTU1PKTsKK307CisKK30gLy8gRW5kIG5hbWVzcGFjZSBsbHZtLgorI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX01BQ0hJTkVJUkJVSUxERVJfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvUmVnQmFua1NlbGVjdC5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvUmVnQmFua1NlbGVjdC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM1M2FlNDEKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9SZWdCYW5rU2VsZWN0LmgKQEAgLTAsMCArMSw2NjUgQEAKKy8vPS0gbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvUmVnQmFua1NlbGVjdC5oIC0gUmVnIEJhbmsgU2VsZWN0b3IgLS0qLSBDKysgLSotPS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8vIFxmaWxlIFRoaXMgZmlsZSBkZXNjcmliZXMgdGhlIGludGVyZmFjZSBvZiB0aGUgTWFjaGluZUZ1bmN0aW9uUGFzcworLy8vIHJlc3BvbnNpYmxlIGZvciBhc3NpZ25pbmcgdGhlIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlcnMgdG8gcmVnaXN0ZXIgYmFuay4KKworLy8vIEJ5IGRlZmF1bHQsIHRoZSByZWcgYmFuayBzZWxlY3RvciByZWxpZXMgb24gbG9jYWwgZGVjaXNpb25zIHRvCisvLy8gYXNzaWduIHRoZSByZWdpc3RlciBiYW5rLiBJbiBvdGhlciB3b3JkcywgaXQgbG9va3MgYXQgb25lIGluc3RydWN0aW9uCisvLy8gYXQgYSB0aW1lIHRvIGRlY2lkZSB3aGVyZSB0aGUgb3BlcmFuZCBvZiB0aGF0IGluc3RydWN0aW9uIHNob3VsZCBsaXZlLgorLy8vCisvLy8gQXQgaGlnaGVyIG9wdGltaXphdGlvbiBsZXZlbCwgd2UgY291bGQgaW1hZ2luZSB0aGF0IHRoZSByZWcgYmFuayBzZWxlY3RvcgorLy8vIHdvdWxkIHVzZSBtb3JlIGdsb2JhbCBhbmFseXNpcyBhbmQgZG8gY3JhemllciB0aGluZyBsaWtlIGR1cGxpY2F0aW5nCisvLy8gaW5zdHJ1Y3Rpb25zIGFuZCBzbyBvbi4gVGhpcyBpcyBmdXR1cmUgd29yay4KKy8vLworLy8vIEZvciBub3csIHRoZSBwYXNzIHVzZXMgYSBncmVlZHkgYWxnb3JpdGhtIHRvIGRlY2lkZSB3aGVyZSB0aGUgb3BlcmFuZAorLy8vIG9mIGFuIGluc3RydWN0aW9uIHNob3VsZCBsaXZlLiBJdCBhc2tzIHRoZSB0YXJnZXQgd2hpY2ggYmFua3MgbWF5IGJlCisvLy8gdXNlZCBmb3IgZWFjaCBvcGVyYW5kIG9mIHRoZSBpbnN0cnVjdGlvbiBhbmQgd2hhdCBpcyB0aGUgY29zdC4gVGhlbiwKKy8vLyBpdCBjaG9vc2VzIHRoZSBzb2x1dGlvbiB3aGljaCBtaW5pbWl6ZSB0aGUgY29zdCBvZiB0aGUgaW5zdHJ1Y3Rpb24gcGx1cworLy8vIHRoZSBjb3N0IG9mIGFueSBtb3ZlIHRoYXQgbWF5IGJlIG5lZWRlZCB0byB0aGUgdmFsdWVzIGludG8gdGhlIHJpZ2h0CisvLy8gcmVnaXN0ZXIgYmFuay4KKy8vLyBJbiBvdGhlciB3b3JkcywgdGhlIGNvc3QgZm9yIGFuIGluc3RydWN0aW9uIG9uIGEgcmVnaXN0ZXIgYmFuayBSZWdCYW5rCisvLy8gaXM6IENvc3Qgb2YgSSBvbiBSZWdCYW5rIHBsdXMgdGhlIHN1bSBvZiB0aGUgY29zdCBmb3IgYnJpbmdpbmcgdGhlCisvLy8gaW5wdXQgb3BlcmFuZHMgZnJvbSB0aGVpciBjdXJyZW50IHJlZ2lzdGVyIGJhbmsgdG8gUmVnQmFuay4KKy8vLyBUaHVzLCB0aGUgZm9sbG93aW5nIGZvcm11bGE6CisvLy8gY29zdChJLCBSZWdCYW5rKSA9IGNvc3QoSS5PcGNvZGUsIFJlZ0JhbmspICsKKy8vLyAgICBzdW0oZm9yIGVhY2ggYXJnIGluIEkuYXJndW1lbnRzOiBjb3N0Q3Jvc3NDb3B5KGFyZy5SZWdCYW5rLCBSZWdCYW5rKSkKKy8vLworLy8vIEUuZy4sIExldCBzYXkgd2UgYXJlIGFzc2lnbmluZyB0aGUgcmVnaXN0ZXIgYmFuayBmb3IgdGhlIGluc3RydWN0aW9uCisvLy8gZGVmaW5pbmcgdjIuCisvLy8gdjAoQV9SRUdCQU5LKSA9IC4uLgorLy8vIHYxKEFfUkVHQkFOSykgPSAuLi4KKy8vLyB2MiA9IEdfQUREIGkzMiB2MCwgdjEgPC0tIE1JCisvLy8KKy8vLyBUaGUgdGFyZ2V0IG1heSBzYXkgaXQgY2FuIGdlbmVyYXRlIEdfQUREIGkzMiBvbiByZWdpc3RlciBiYW5rIEEgYW5kIEIKKy8vLyB3aXRoIGEgY29zdCBvZiByZXNwZWN0aXZlbHkgNSBhbmQgMS4KKy8vLyBUaGVuLCBsZXQgc2F5IHRoZSBjb3N0IG9mIGEgY3Jvc3MgcmVnaXN0ZXIgYmFuayBjb3BpZXMgZnJvbSBBIHRvIEIgaXMgMS4KKy8vLyBUaGUgcmVnIGJhbmsgc2VsZWN0b3Igd291bGQgY29tcGFyZSB0aGUgZm9sbG93aW5nIHR3byBjb3N0czoKKy8vLyBjb3N0KE1JLCBBX1JFR0JBTkspID0gY29zdChHX0FERCwgQV9SRUdCQU5LKSArIGNvc3QodjAuUmVnQmFuaywgQV9SRUdCQU5LKSArCisvLy8gICAgY29zdCh2MS5SZWdCYW5rLCBBX1JFR0JBTkspCisvLy8gICAgICAgICAgICAgICAgICAgICA9IDUgKyBjb3N0KEFfUkVHQkFOSywgQV9SRUdCQU5LKSArIGNvc3QoQV9SRUdCQU5LLAorLy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFfUkVHQkFOSykKKy8vLyAgICAgICAgICAgICAgICAgICAgID0gNSArIDAgKyAwID0gNQorLy8vIGNvc3QoTUksIEJfUkVHQkFOSykgPSBjb3N0KEdfQURELCBCX1JFR0JBTkspICsgY29zdCh2MC5SZWdCYW5rLCBCX1JFR0JBTkspICsKKy8vLyAgICBjb3N0KHYxLlJlZ0JhbmssIEJfUkVHQkFOSykKKy8vLyAgICAgICAgICAgICAgICAgICAgID0gMSArIGNvc3QoQV9SRUdCQU5LLCBCX1JFR0JBTkspICsgY29zdChBX1JFR0JBTkssCisvLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQl9SRUdCQU5LKQorLy8vICAgICAgICAgICAgICAgICAgICAgPSAxICsgMSArIDEgPSAzCisvLy8gVGhlcmVmb3JlLCBpbiB0aGlzIHNwZWNpZmljIGV4YW1wbGUsIHRoZSByZWcgYmFuayBzZWxlY3RvciB3b3VsZCBjaG9vc2UKKy8vLyBiYW5rIEIgZm9yIE1JLgorLy8vIHYwKEFfUkVHQkFOSykgPSAuLi4KKy8vLyB2MShBX1JFR0JBTkspID0gLi4uCisvLy8gdG1wMChCX1JFR0JBTkspID0gQ09QWSB2MAorLy8vIHRtcDEoQl9SRUdCQU5LKSA9IENPUFkgdjEKKy8vLyB2MihCX1JFR0JBTkspID0gR19BREQgaTMyIHRtcDAsIHRtcDEKKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX1JFR0JBTktTRUxFQ1RfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fR0xPQkFMSVNFTF9SRUdCQU5LU0VMRUNUX0gKKworI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvTWFjaGluZUlSQnVpbGRlci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL1JlZ2lzdGVyQmFua0luZm8uaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uUGFzcy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lT3B0aW1pemF0aW9uUmVtYXJrRW1pdHRlci5oIgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8Y3N0ZGludD4KKyNpbmNsdWRlIDxtZW1vcnk+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgQmxvY2tGcmVxdWVuY3k7CitjbGFzcyBNYWNoaW5lQmxvY2tGcmVxdWVuY3lJbmZvOworY2xhc3MgTWFjaGluZUJyYW5jaFByb2JhYmlsaXR5SW5mbzsKK2NsYXNzIE1hY2hpbmVPcGVyYW5kOworY2xhc3MgTWFjaGluZVJlZ2lzdGVySW5mbzsKK2NsYXNzIFBhc3M7CitjbGFzcyByYXdfb3N0cmVhbTsKK2NsYXNzIFRhcmdldFBhc3NDb25maWc7CitjbGFzcyBUYXJnZXRSZWdpc3RlckluZm87CisKKy8vLyBUaGlzIHBhc3MgaW1wbGVtZW50cyB0aGUgcmVnIGJhbmsgc2VsZWN0b3IgcGFzcyB1c2VkIGluIHRoZSBHbG9iYWxJU2VsCisvLy8gcGlwZWxpbmUuIEF0IHRoZSBlbmQgb2YgdGhpcyBwYXNzLCBhbGwgcmVnaXN0ZXIgb3BlcmFuZHMgaGF2ZSBiZWVuIGFzc2lnbmVkCitjbGFzcyBSZWdCYW5rU2VsZWN0IDogcHVibGljIE1hY2hpbmVGdW5jdGlvblBhc3MgeworcHVibGljOgorICBzdGF0aWMgY2hhciBJRDsKKworICAvLy8gTGlzdCBvZiB0aGUgbW9kZXMgc3VwcG9ydGVkIGJ5IHRoZSBSZWdCYW5rU2VsZWN0IHBhc3MuCisgIGVudW0gTW9kZSB7CisgICAgLy8vIEFzc2lnbiB0aGUgcmVnaXN0ZXIgYmFua3MgYXMgZmFzdCBhcyBwb3NzaWJsZSAoZGVmYXVsdCkuCisgICAgRmFzdCwKKyAgICAvLy8gR3JlZWRpbHkgbWluaW1pemUgdGhlIGNvc3Qgb2YgYXNzaWduaW5nIHJlZ2lzdGVyIGJhbmtzLgorICAgIC8vLyBUaGlzIHNob3VsZCBwcm9kdWNlIGNvZGUgb2YgZ3JlYXRlciBxdWFsaXR5LCBidXQgd2lsbAorICAgIC8vLyByZXF1aXJlIG1vcmUgY29tcGlsZSB0aW1lLgorICAgIEdyZWVkeQorICB9OworCisgIC8vLyBBYnN0cmFjdCBjbGFzcyB1c2VkIHRvIHJlcHJlc2VudCBhbiBpbnNlcnRpb24gcG9pbnQgaW4gYSBDRkcuCisgIC8vLyBUaGlzIGNsYXNzIHJlY29yZHMgYW4gaW5zZXJ0aW9uIHBvaW50IGFuZCBtYXRlcmlhbGl6ZXMgaXQgb24KKyAgLy8vIGRlbWFuZC4KKyAgLy8vIEl0IGFsbG93cyB0byByZWFzb24gYWJvdXQgdGhlIGZyZXF1ZW5jeSBvZiB0aGlzIGluc2VydGlvbiBwb2ludCwKKyAgLy8vIHdpdGhvdXQgaGF2aW5nIHRvIGxvZ2ljYWxseSBtYXRlcmlhbGl6ZSBpdCAoZS5nLiwgb24gYW4gZWRnZSksCisgIC8vLyBiZWZvcmUgd2UgYWN0dWFsbHkgbmVlZCB0byBpbnNlcnQgc29tZXRoaW5nLgorICBjbGFzcyBJbnNlcnRQb2ludCB7CisgIHByb3RlY3RlZDoKKyAgICAvLy8gVGVsbCBpZiB0aGUgaW5zZXJ0IHBvaW50IGhhcyBhbHJlYWR5IGJlZW4gbWF0ZXJpYWxpemVkLgorICAgIGJvb2wgV2FzTWF0ZXJpYWxpemVkID0gZmFsc2U7CisKKyAgICAvLy8gTWF0ZXJpYWxpemUgdGhlIGluc2VydGlvbiBwb2ludC4KKyAgICAvLy8KKyAgICAvLy8gSWYgaXNTcGxpdCgpIGlzIHRydWUsIHRoaXMgaW52b2x2ZXMgYWN0dWFsbHkgc3BsaXR0aW5nCisgICAgLy8vIHRoZSBibG9jayBvciBlZGdlLgorICAgIC8vLworICAgIC8vLyBccG9zdCBnZXRQb2ludEltcGwoKSByZXR1cm5zIGEgdmFsaWQgaXRlcmF0b3IuCisgICAgLy8vIFxwb3N0IGdldEluc2VydE1CQkltcGwoKSByZXR1cm5zIGEgdmFsaWQgYmFzaWMgYmxvY2suCisgICAgLy8vIFxwb3N0IGlzU3BsaXQoKSA9PSBmYWxzZSA7IG5vIG1vcmUgc3BsaXR0aW5nIHNob3VsZCBiZSByZXF1aXJlZC4KKyAgICB2aXJ0dWFsIHZvaWQgbWF0ZXJpYWxpemUoKSA9IDA7CisKKyAgICAvLy8gUmV0dXJuIHRoZSBtYXRlcmlhbGl6ZWQgaW5zZXJ0aW9uIGJhc2ljIGJsb2NrLgorICAgIC8vLyBDb2RlIHdpbGwgYmUgaW5zZXJ0ZWQgaW50byB0aGF0IGJhc2ljIGJsb2NrLgorICAgIC8vLworICAgIC8vLyBccHJlIDo6bWF0ZXJpYWxpemUgaGFzIGJlZW4gY2FsbGVkLgorICAgIHZpcnR1YWwgTWFjaGluZUJhc2ljQmxvY2sgJmdldEluc2VydE1CQkltcGwoKSA9IDA7CisKKyAgICAvLy8gUmV0dXJuIHRoZSBtYXRlcmlhbGl6ZWQgaW5zZXJ0aW9uIHBvaW50LgorICAgIC8vLyBDb2RlIHdpbGwgYmUgaW5zZXJ0ZWQgYmVmb3JlIHRoYXQgcG9pbnQuCisgICAgLy8vCisgICAgLy8vIFxwcmUgOjptYXRlcmlhbGl6ZSBoYXMgYmVlbiBjYWxsZWQuCisgICAgdmlydHVhbCBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgZ2V0UG9pbnRJbXBsKCkgPSAwOworCisgIHB1YmxpYzoKKyAgICB2aXJ0dWFsIH5JbnNlcnRQb2ludCgpID0gZGVmYXVsdDsKKworICAgIC8vLyBUaGUgZmlyc3QgY2FsbCB0byB0aGlzIG1ldGhvZCB3aWxsIGNhdXNlIHRoZSBzcGxpdHRpbmcgdG8KKyAgICAvLy8gaGFwcGVuIGlmIG5lZWQgYmUsIHRoZW4gc3ViIHNlcXVlbnQgY2FsbHMganVzdCByZXR1cm4KKyAgICAvLy8gdGhlIGl0ZXJhdG9yIHRvIHRoYXQgcG9pbnQuIEkuZS4sIG5vIG1vcmUgc3BsaXR0aW5nIHdpbGwKKyAgICAvLy8gb2NjdXIuCisgICAgLy8vCisgICAgLy8vIFxyZXR1cm4gVGhlIGl0ZXJhdG9yIHRoYXQgc2hvdWxkIGJlIHVzZWQgd2l0aAorICAgIC8vLyBNYWNoaW5lQmFzaWNCbG9jazo6aW5zZXJ0LiBJLmUuLCBhZGRpdGlvbmFsIGNvZGUgaGFwcGVucworICAgIC8vLyBiZWZvcmUgdGhhdCBwb2ludC4KKyAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgZ2V0UG9pbnQoKSB7CisgICAgICBpZiAoIVdhc01hdGVyaWFsaXplZCkgeworICAgICAgICBXYXNNYXRlcmlhbGl6ZWQgPSB0cnVlOworICAgICAgICBhc3NlcnQoY2FuTWF0ZXJpYWxpemUoKSAmJiAiSW1wb3NzaWJsZSB0byBtYXRlcmlhbGl6ZSB0aGlzIHBvaW50Iik7CisgICAgICAgIG1hdGVyaWFsaXplKCk7CisgICAgICB9CisgICAgICAvLyBXaGVuIHdlIG1hdGVyaWFsaXplZCB0aGUgcG9pbnQgd2Ugc2hvdWxkIGhhdmUgZG9uZSB0aGUgc3BsaXR0aW5nLgorICAgICAgYXNzZXJ0KCFpc1NwbGl0KCkgJiYgIldyb25nIHByZS1jb25kaXRpb24iKTsKKyAgICAgIHJldHVybiBnZXRQb2ludEltcGwoKTsKKyAgICB9CisKKyAgICAvLy8gVGhlIGZpcnN0IGNhbGwgdG8gdGhpcyBtZXRob2Qgd2lsbCBjYXVzZSB0aGUgc3BsaXR0aW5nIHRvCisgICAgLy8vIGhhcHBlbiBpZiBuZWVkIGJlLCB0aGVuIHN1YiBzZXF1ZW50IGNhbGxzIGp1c3QgcmV0dXJuCisgICAgLy8vIHRoZSBiYXNpYyBibG9jayB0aGF0IGNvbnRhaW5zIHRoZSBpbnNlcnRpb24gcG9pbnQuCisgICAgLy8vIEkuZS4sIG5vIG1vcmUgc3BsaXR0aW5nIHdpbGwgb2NjdXIuCisgICAgLy8vCisgICAgLy8vIFxyZXR1cm4gVGhlIGJhc2ljIGJsb2NrIHNob3VsZCBiZSB1c2VkIHdpdGgKKyAgICAvLy8gTWFjaGluZUJhc2ljQmxvY2s6Omluc2VydCBhbmQgOjpnZXRQb2ludC4gVGhlIG5ldyBjb2RlIHNob3VsZAorICAgIC8vLyBoYXBwZW4gYmVmb3JlIHRoYXQgcG9pbnQuCisgICAgTWFjaGluZUJhc2ljQmxvY2sgJmdldEluc2VydE1CQigpIHsKKyAgICAgIGlmICghV2FzTWF0ZXJpYWxpemVkKSB7CisgICAgICAgIFdhc01hdGVyaWFsaXplZCA9IHRydWU7CisgICAgICAgIGFzc2VydChjYW5NYXRlcmlhbGl6ZSgpICYmICJJbXBvc3NpYmxlIHRvIG1hdGVyaWFsaXplIHRoaXMgcG9pbnQiKTsKKyAgICAgICAgbWF0ZXJpYWxpemUoKTsKKyAgICAgIH0KKyAgICAgIC8vIFdoZW4gd2UgbWF0ZXJpYWxpemVkIHRoZSBwb2ludCB3ZSBzaG91bGQgaGF2ZSBkb25lIHRoZSBzcGxpdHRpbmcuCisgICAgICBhc3NlcnQoIWlzU3BsaXQoKSAmJiAiV3JvbmcgcHJlLWNvbmRpdGlvbiIpOworICAgICAgcmV0dXJuIGdldEluc2VydE1CQkltcGwoKTsKKyAgICB9CisKKyAgICAvLy8gSW5zZXJ0IFxwIE1JIGluIHRoZSBqdXN0IGJlZm9yZSA6OmdldFBvaW50KCkKKyAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgaW5zZXJ0KE1hY2hpbmVJbnN0ciAmTUkpIHsKKyAgICAgIHJldHVybiBnZXRJbnNlcnRNQkIoKS5pbnNlcnQoZ2V0UG9pbnQoKSwgJk1JKTsKKyAgICB9CisKKyAgICAvLy8gRG9lcyB0aGlzIHBvaW50IGludm9sdmUgc3BsaXR0aW5nIGFuIGVkZ2Ugb3IgYmxvY2s/CisgICAgLy8vIEFzIHNvb24gYXMgOjpnZXRQb2ludCBpcyBjYWxsZWQgYW5kIHRodXMsIHRoZSBwb2ludAorICAgIC8vLyBtYXRlcmlhbGl6ZWQsIHRoZSBwb2ludCB3aWxsIG5vdCByZXF1aXJlIHNwbGl0dGluZyBhbnltb3JlLAorICAgIC8vLyBpLmUuLCB0aGlzIHdpbGwgcmV0dXJuIGZhbHNlLgorICAgIHZpcnR1YWwgYm9vbCBpc1NwbGl0KCkgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KKworICAgIC8vLyBGcmVxdWVuY3kgb2YgdGhlIGluc2VydGlvbiBwb2ludC4KKyAgICAvLy8gXHAgUCBpcyB1c2VkIHRvIGFjY2VzcyB0aGUgdmFyaW91cyBhbmFseXNpcyB0aGF0IHdpbGwgaGVscCB0bworICAgIC8vLyBnZXQgdGhhdCBpbmZvcm1hdGlvbiwgbGlrZSBNYWNoaW5lQmxvY2tGcmVxdWVuY3lJbmZvLiAgSWYgXHAgUAorICAgIC8vLyBkb2VzIG5vdCBjb250YWluIGVub3VnaCBlbm91Z2ggdG8gcmV0dXJuIHRoZSBhY3R1YWwgZnJlcXVlbmN5LAorICAgIC8vLyB0aGlzIHJldHVybnMgMS4KKyAgICB2aXJ0dWFsIHVpbnQ2NF90IGZyZXF1ZW5jeShjb25zdCBQYXNzICZQKSBjb25zdCB7IHJldHVybiAxOyB9CisKKyAgICAvLy8gQ2hlY2sgd2hldGhlciB0aGlzIGluc2VydGlvbiBwb2ludCBjYW4gYmUgbWF0ZXJpYWxpemVkLgorICAgIC8vLyBBcyBzb29uIGFzIDo6Z2V0UG9pbnQgaXMgY2FsbGVkIGFuZCB0aHVzLCB0aGUgcG9pbnQgbWF0ZXJpYWxpemVkCisgICAgLy8vIGNhbGxpbmcgdGhpcyBtZXRob2QgZG9lcyBub3QgbWFrZSBzZW5zZS4KKyAgICB2aXJ0dWFsIGJvb2wgY2FuTWF0ZXJpYWxpemUoKSBjb25zdCB7IHJldHVybiBmYWxzZTsgfQorICB9OworCisgIC8vLyBJbnNlcnRpb24gcG9pbnQgYmVmb3JlIG9yIGFmdGVyIGFuIGluc3RydWN0aW9uLgorICBjbGFzcyBJbnN0ckluc2VydFBvaW50IDogcHVibGljIEluc2VydFBvaW50IHsKKyAgcHJpdmF0ZToKKyAgICAvLy8gSW5zZXJ0aW9uIHBvaW50LgorICAgIE1hY2hpbmVJbnN0ciAmSW5zdHI7CisKKyAgICAvLy8gRG9lcyB0aGUgaW5zZXJ0aW9uIHBvaW50IGlzIGJlZm9yZSBvciBhZnRlciBJbnN0ci4KKyAgICBib29sIEJlZm9yZTsKKworICAgIHZvaWQgbWF0ZXJpYWxpemUoKSBvdmVycmlkZTsKKworICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBnZXRQb2ludEltcGwoKSBvdmVycmlkZSB7CisgICAgICBpZiAoQmVmb3JlKQorICAgICAgICByZXR1cm4gSW5zdHI7CisgICAgICByZXR1cm4gSW5zdHIuZ2V0TmV4dE5vZGUoKSA/ICpJbnN0ci5nZXROZXh0Tm9kZSgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IEluc3RyLmdldFBhcmVudCgpLT5lbmQoKTsKKyAgICB9CisKKyAgICBNYWNoaW5lQmFzaWNCbG9jayAmZ2V0SW5zZXJ0TUJCSW1wbCgpIG92ZXJyaWRlIHsKKyAgICAgIHJldHVybiAqSW5zdHIuZ2V0UGFyZW50KCk7CisgICAgfQorCisgIHB1YmxpYzoKKyAgICAvLy8gQ3JlYXRlIGFuIGluc2VydGlvbiBwb2ludCBiZWZvcmUgKFxwIEJlZm9yZT10cnVlKSBvciBhZnRlciBccCBJbnN0ci4KKyAgICBJbnN0ckluc2VydFBvaW50KE1hY2hpbmVJbnN0ciAmSW5zdHIsIGJvb2wgQmVmb3JlID0gdHJ1ZSk7CisKKyAgICBib29sIGlzU3BsaXQoKSBjb25zdCBvdmVycmlkZTsKKyAgICB1aW50NjRfdCBmcmVxdWVuY3koY29uc3QgUGFzcyAmUCkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgICAvLyBXb3JzdCBjYXNlLCB3ZSBuZWVkIHRvIHNsaWNlIHRoZSBiYXNpYyBibG9jaywgYnV0IHRoYXQgaXMgc3RpbGwgZG9hYmxlLgorICAgIGJvb2wgY2FuTWF0ZXJpYWxpemUoKSBjb25zdCBvdmVycmlkZSB7IHJldHVybiB0cnVlOyB9CisgIH07CisKKyAgLy8vIEluc2VydGlvbiBwb2ludCBhdCB0aGUgYmVnaW5uaW5nIG9yIGVuZCBvZiBhIGJhc2ljIGJsb2NrLgorICBjbGFzcyBNQkJJbnNlcnRQb2ludCA6IHB1YmxpYyBJbnNlcnRQb2ludCB7CisgIHByaXZhdGU6CisgICAgLy8vIEluc2VydGlvbiBwb2ludC4KKyAgICBNYWNoaW5lQmFzaWNCbG9jayAmTUJCOworCisgICAgLy8vIERvZXMgdGhlIGluc2VydGlvbiBwb2ludCBpcyBhdCB0aGUgYmVnaW5uaW5nIG9yIGVuZCBvZiBNQkIuCisgICAgYm9vbCBCZWdpbm5pbmc7CisKKyAgICB2b2lkIG1hdGVyaWFsaXplKCkgb3ZlcnJpZGUgeyAvKk5vdGhpbmcgdG8gZG8gdG8gbWF0ZXJpYWxpemUqLworICAgIH0KKworICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBnZXRQb2ludEltcGwoKSBvdmVycmlkZSB7CisgICAgICByZXR1cm4gQmVnaW5uaW5nID8gTUJCLmJlZ2luKCkgOiBNQkIuZW5kKCk7CisgICAgfQorCisgICAgTWFjaGluZUJhc2ljQmxvY2sgJmdldEluc2VydE1CQkltcGwoKSBvdmVycmlkZSB7IHJldHVybiBNQkI7IH0KKworICBwdWJsaWM6CisgICAgTUJCSW5zZXJ0UG9pbnQoTWFjaGluZUJhc2ljQmxvY2sgJk1CQiwgYm9vbCBCZWdpbm5pbmcgPSB0cnVlKQorICAgICAgICA6IEluc2VydFBvaW50KCksIE1CQihNQkIpLCBCZWdpbm5pbmcoQmVnaW5uaW5nKSB7CisgICAgICAvLyBJZiB3ZSB0cnkgdG8gaW5zZXJ0IGJlZm9yZSBwaGlzLCB3ZSBzaG91bGQgdXNlIHRoZSBpbnNlcnRpb24KKyAgICAgIC8vIHBvaW50cyBvbiB0aGUgaW5jb21pbmcgZWRnZXMuCisgICAgICBhc3NlcnQoKCFCZWdpbm5pbmcgfHwgTUJCLmdldEZpcnN0Tm9uUEhJKCkgPT0gTUJCLmJlZ2luKCkpICYmCisgICAgICAgICAgICAgIkludmFsaWQgYmVnaW5uaW5nIHBvaW50Iik7CisgICAgICAvLyBJZiB3ZSB0cnkgdG8gaW5zZXJ0IGFmdGVyIHRoZSB0ZXJtaW5hdG9ycywgd2Ugc2hvdWxkIHVzZSB0aGUKKyAgICAgIC8vIHBvaW50cyBvbiB0aGUgb3V0Y29taW5nIGVkZ2VzLgorICAgICAgYXNzZXJ0KChCZWdpbm5pbmcgfHwgTUJCLmdldEZpcnN0VGVybWluYXRvcigpID09IE1CQi5lbmQoKSkgJiYKKyAgICAgICAgICAgICAiSW52YWxpZCBlbmQgcG9pbnQiKTsKKyAgICB9CisKKyAgICBib29sIGlzU3BsaXQoKSBjb25zdCBvdmVycmlkZSB7IHJldHVybiBmYWxzZTsgfQorICAgIHVpbnQ2NF90IGZyZXF1ZW5jeShjb25zdCBQYXNzICZQKSBjb25zdCBvdmVycmlkZTsKKyAgICBib29sIGNhbk1hdGVyaWFsaXplKCkgY29uc3Qgb3ZlcnJpZGUgeyByZXR1cm4gdHJ1ZTsgfTsKKyAgfTsKKworICAvLy8gSW5zZXJ0aW9uIHBvaW50IG9uIGFuIGVkZ2UuCisgIGNsYXNzIEVkZ2VJbnNlcnRQb2ludCA6IHB1YmxpYyBJbnNlcnRQb2ludCB7CisgIHByaXZhdGU6CisgICAgLy8vIFNvdXJjZSBvZiB0aGUgZWRnZS4KKyAgICBNYWNoaW5lQmFzaWNCbG9jayAmU3JjOworCisgICAgLy8vIERlc3RpbmF0aW9uIG9mIHRoZSBlZGdlLgorICAgIC8vLyBBZnRlciB0aGUgbWF0ZXJpYWxpemF0aW9uIGlzIGRvbmUsIHRoaXMgaG9sZCB0aGUgYmFzaWMgYmxvY2sKKyAgICAvLy8gdGhhdCByZXN1bHRlZCBmcm9tIHRoZSBzcGxpdHRpbmcuCisgICAgTWFjaGluZUJhc2ljQmxvY2sgKkRzdE9yU3BsaXQ7CisKKyAgICAvLy8gUCBpcyB1c2VkIHRvIHVwZGF0ZSB0aGUgYW5hbHlzaXMgcGFzc2VzIGFzIGFwcGxpY2FibGUuCisgICAgUGFzcyAmUDsKKworICAgIHZvaWQgbWF0ZXJpYWxpemUoKSBvdmVycmlkZTsKKworICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBnZXRQb2ludEltcGwoKSBvdmVycmlkZSB7CisgICAgICAvLyBEc3RPclNwbGl0IHNob3VsZCBiZSB0aGUgU3BsaXQgYmxvY2sgYXQgdGhpcyBwb2ludC4KKyAgICAgIC8vIEkuZS4sIGl0IHNob3VsZCBoYXZlIG9uZSBwcmVkZWNlc3NvciwgU3JjLCBhbmQgb25lIHN1Y2Nlc3NvciwKKyAgICAgIC8vIHRoZSBvcmlnaW5hbCBEc3QuCisgICAgICBhc3NlcnQoRHN0T3JTcGxpdCAmJiBEc3RPclNwbGl0LT5pc1ByZWRlY2Vzc29yKCZTcmMpICYmCisgICAgICAgICAgICAgRHN0T3JTcGxpdC0+cHJlZF9zaXplKCkgPT0gMSAmJiBEc3RPclNwbGl0LT5zdWNjX3NpemUoKSA9PSAxICYmCisgICAgICAgICAgICAgIkRpZCBub3Qgc3BsaXQ/ISIpOworICAgICAgcmV0dXJuIERzdE9yU3BsaXQtPmJlZ2luKCk7CisgICAgfQorCisgICAgTWFjaGluZUJhc2ljQmxvY2sgJmdldEluc2VydE1CQkltcGwoKSBvdmVycmlkZSB7IHJldHVybiAqRHN0T3JTcGxpdDsgfQorCisgIHB1YmxpYzoKKyAgICBFZGdlSW5zZXJ0UG9pbnQoTWFjaGluZUJhc2ljQmxvY2sgJlNyYywgTWFjaGluZUJhc2ljQmxvY2sgJkRzdCwgUGFzcyAmUCkKKyAgICAgICAgOiBJbnNlcnRQb2ludCgpLCBTcmMoU3JjKSwgRHN0T3JTcGxpdCgmRHN0KSwgUChQKSB7fQorCisgICAgYm9vbCBpc1NwbGl0KCkgY29uc3Qgb3ZlcnJpZGUgeworICAgICAgcmV0dXJuIFNyYy5zdWNjX3NpemUoKSA+IDEgJiYgRHN0T3JTcGxpdC0+cHJlZF9zaXplKCkgPiAxOworICAgIH0KKworICAgIHVpbnQ2NF90IGZyZXF1ZW5jeShjb25zdCBQYXNzICZQKSBjb25zdCBvdmVycmlkZTsKKyAgICBib29sIGNhbk1hdGVyaWFsaXplKCkgY29uc3Qgb3ZlcnJpZGU7CisgIH07CisKKyAgLy8vIFN0cnVjdCB1c2VkIHRvIHJlcHJlc2VudCB0aGUgcGxhY2VtZW50IG9mIGEgcmVwYWlyaW5nIHBvaW50IGZvcgorICAvLy8gYSBnaXZlbiBvcGVyYW5kLgorICBjbGFzcyBSZXBhaXJpbmdQbGFjZW1lbnQgeworICBwdWJsaWM6CisgICAgLy8vIERlZmluZSB0aGUga2luZCBvZiBhY3Rpb24gdGhpcyByZXBhaXJpbmcgbmVlZHMuCisgICAgZW51bSBSZXBhaXJpbmdLaW5kIHsKKyAgICAgIC8vLyBOb3RoaW5nIHRvIHJlcGFpciwganVzdCBkcm9wIHRoaXMgYWN0aW9uLgorICAgICAgTm9uZSwKKyAgICAgIC8vLyBSZXBhcmluZyBjb2RlIG5lZWRzIHRvIGhhcHBlbiBiZWZvcmUgSW5zZXJ0UG9pbnRzLgorICAgICAgSW5zZXJ0LAorICAgICAgLy8vIChSZSlhc3NpZ24gdGhlIHJlZ2lzdGVyIGJhbmsgb2YgdGhlIG9wZXJhbmQuCisgICAgICBSZWFzc2lnbiwKKyAgICAgIC8vLyBNYXJrIHRoaXMgcmVwYWlyaW5nIHBsYWNlbWVudCBhcyBpbXBvc3NpYmxlLgorICAgICAgSW1wb3NzaWJsZQorICAgIH07CisKKyAgICAvLy8gXG5hbWUgQ29udmVuaWVudCB0eXBlcyBmb3IgYSBsaXN0IG9mIGluc2VydGlvbiBwb2ludHMuCisgICAgLy8vIEB7CisgICAgdXNpbmcgSW5zZXJ0aW9uUG9pbnRzID0gU21hbGxWZWN0b3I8c3RkOjp1bmlxdWVfcHRyPEluc2VydFBvaW50PiwgMj47CisgICAgdXNpbmcgaW5zZXJ0cHRfaXRlcmF0b3IgPSBJbnNlcnRpb25Qb2ludHM6Oml0ZXJhdG9yOworICAgIHVzaW5nIGNvbnN0X2luc2VydHB0X2l0ZXJhdG9yID0gSW5zZXJ0aW9uUG9pbnRzOjpjb25zdF9pdGVyYXRvcjsKKyAgICAvLy8gQH0KKworICBwcml2YXRlOgorICAgIC8vLyBLaW5kIG9mIHJlcGFpcmluZy4KKyAgICBSZXBhaXJpbmdLaW5kIEtpbmQ7CisgICAgLy8vIEluZGV4IG9mIHRoZSBvcGVyYW5kIHRoYXQgd2lsbCBiZSByZXBhaXJlZC4KKyAgICB1bnNpZ25lZCBPcElkeDsKKyAgICAvLy8gQXJlIGFsbCB0aGUgaW5zZXJ0IHBvaW50cyBtYXRlcmlhbGl6ZWFibGU/CisgICAgYm9vbCBDYW5NYXRlcmlhbGl6ZTsKKyAgICAvLy8gSXMgdGhlcmUgYW55IG9mIHRoZSBpbnNlcnQgcG9pbnRzIG5lZWRpbmcgc3BsaXR0aW5nPworICAgIGJvb2wgSGFzU3BsaXQgPSBmYWxzZTsKKyAgICAvLy8gSW5zZXJ0aW9uIHBvaW50IGZvciB0aGUgcmVwYWlyIGNvZGUuCisgICAgLy8vIFRoZSByZXBhaXJpbmcgY29kZSBuZWVkcyB0byBoYXBwZW4ganVzdCBiZWZvcmUgdGhlc2UgcG9pbnRzLgorICAgIEluc2VydGlvblBvaW50cyBJbnNlcnRQb2ludHM7CisgICAgLy8vIFNvbWUgaW5zZXJ0aW9uIHBvaW50cyBtYXkgbmVlZCB0byB1cGRhdGUgdGhlIGxpdmVuZXNzIGFuZCBzdWNoLgorICAgIFBhc3MgJlA7CisKKyAgcHVibGljOgorICAgIC8vLyBDcmVhdGUgYSByZXBhaXJpbmcgcGxhY2VtZW50IGZvciB0aGUgXHAgT3BJZHgtdGggb3BlcmFuZCBvZgorICAgIC8vLyBccCBNSS4gXHAgVFJJIGlzIHVzZWQgdG8gbWFrZSBzb21lIGNoZWNrcyBvbiB0aGUgcmVnaXN0ZXIgYWxpYXNlcworICAgIC8vLyBpZiB0aGUgbWFjaGluZSBvcGVyYW5kIGlzIGEgcGh5c2ljYWwgcmVnaXN0ZXIuIFxwIFAgaXMgdXNlZCB0bworICAgIC8vLyB0byB1cGRhdGUgbGl2ZW5lc3MgaW5mb3JtYXRpb24gYW5kIHN1Y2ggd2hlbiBtYXRlcmlhbGl6aW5nIHRoZQorICAgIC8vLyBwb2ludHMuCisgICAgUmVwYWlyaW5nUGxhY2VtZW50KE1hY2hpbmVJbnN0ciAmTUksIHVuc2lnbmVkIE9wSWR4LAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gJlRSSSwgUGFzcyAmUCwKKyAgICAgICAgICAgICAgICAgICAgICAgUmVwYWlyaW5nS2luZCBLaW5kID0gUmVwYWlyaW5nS2luZDo6SW5zZXJ0KTsKKworICAgIC8vLyBcbmFtZSBHZXR0ZXJzLgorICAgIC8vLyBAeworICAgIFJlcGFpcmluZ0tpbmQgZ2V0S2luZCgpIGNvbnN0IHsgcmV0dXJuIEtpbmQ7IH0KKyAgICB1bnNpZ25lZCBnZXRPcElkeCgpIGNvbnN0IHsgcmV0dXJuIE9wSWR4OyB9CisgICAgYm9vbCBjYW5NYXRlcmlhbGl6ZSgpIGNvbnN0IHsgcmV0dXJuIENhbk1hdGVyaWFsaXplOyB9CisgICAgYm9vbCBoYXNTcGxpdCgpIHsgcmV0dXJuIEhhc1NwbGl0OyB9CisgICAgLy8vIEB9CisKKyAgICAvLy8gXG5hbWUgT3ZlcmxvYWRlZCBtZXRob2RzIHRvIGFkZCBhbiBpbnNlcnRpb24gcG9pbnQuCisgICAgLy8vIEB7CisgICAgLy8vIEFkZCBhIE1CQkluc2VydGlvblBvaW50IHRvIHRoZSBsaXN0IG9mIEluc2VydFBvaW50cy4KKyAgICB2b2lkIGFkZEluc2VydFBvaW50KE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsIGJvb2wgQmVnaW5uaW5nKTsKKyAgICAvLy8gQWRkIGEgSW5zdHJJbnNlcnRpb25Qb2ludCB0byB0aGUgbGlzdCBvZiBJbnNlcnRQb2ludHMuCisgICAgdm9pZCBhZGRJbnNlcnRQb2ludChNYWNoaW5lSW5zdHIgJk1JLCBib29sIEJlZm9yZSk7CisgICAgLy8vIEFkZCBhbiBFZGdlSW5zZXJ0aW9uUG9pbnQgKFxwIFNyYywgXHAgRHN0KSB0byB0aGUgbGlzdCBvZiBJbnNlcnRQb2ludHMuCisgICAgdm9pZCBhZGRJbnNlcnRQb2ludChNYWNoaW5lQmFzaWNCbG9jayAmU3JjLCBNYWNoaW5lQmFzaWNCbG9jayAmRHN0KTsKKyAgICAvLy8gQWRkIGFuIEluc2VydFBvaW50IHRvIHRoZSBsaXN0IG9mIGluc2VydCBwb2ludHMuCisgICAgLy8vIFRoaXMgbWV0aG9kIHRha2VzIHRoZSBvd25lcnNoaXAgb2YgJlxwIFBvaW50LgorICAgIHZvaWQgYWRkSW5zZXJ0UG9pbnQoSW5zZXJ0UG9pbnQgJlBvaW50KTsKKyAgICAvLy8gQH0KKworICAgIC8vLyBcbmFtZSBBY2Nlc3NvcnMgcmVsYXRlZCB0byB0aGUgaW5zZXJ0aW9uIHBvaW50cy4KKyAgICAvLy8gQHsKKyAgICBpbnNlcnRwdF9pdGVyYXRvciBiZWdpbigpIHsgcmV0dXJuIEluc2VydFBvaW50cy5iZWdpbigpOyB9CisgICAgaW5zZXJ0cHRfaXRlcmF0b3IgZW5kKCkgeyByZXR1cm4gSW5zZXJ0UG9pbnRzLmVuZCgpOyB9CisKKyAgICBjb25zdF9pbnNlcnRwdF9pdGVyYXRvciBiZWdpbigpIGNvbnN0IHsgcmV0dXJuIEluc2VydFBvaW50cy5iZWdpbigpOyB9CisgICAgY29uc3RfaW5zZXJ0cHRfaXRlcmF0b3IgZW5kKCkgY29uc3QgeyByZXR1cm4gSW5zZXJ0UG9pbnRzLmVuZCgpOyB9CisKKyAgICB1bnNpZ25lZCBnZXROdW1JbnNlcnRQb2ludHMoKSBjb25zdCB7IHJldHVybiBJbnNlcnRQb2ludHMuc2l6ZSgpOyB9CisgICAgLy8vIEB9CisKKyAgICAvLy8gQ2hhbmdlIHRoZSB0eXBlIG9mIHRoaXMgcmVwYWlyaW5nIHBsYWNlbWVudCB0byBccCBOZXdLaW5kLgorICAgIC8vLyBJdCBpcyBub3QgcG9zc2libGUgdG8gc3dpdGNoIGEgcmVwYWlyaW5nIHBsYWNlbWVudCB0byB0aGUKKyAgICAvLy8gUmVwYWlyaW5nS2luZDo6SW5zZXJ0LiBUaGVyZSBpcyBubyBmdW5kYW1lbnRhbCBwcm9ibGVtIHdpdGgKKyAgICAvLy8gdGhhdCwgYnV0IG5vIHVzZXMgYXMgd2VsbCwgc28gZG8gbm90IHN1cHBvcnQgaXQgZm9yIG5vdy4KKyAgICAvLy8KKyAgICAvLy8gXHByZSBOZXdLaW5kICE9IFJlcGFpcmluZ0tpbmQ6Okluc2VydAorICAgIC8vLyBccG9zdCBnZXRLaW5kKCkgPT0gTmV3S2luZAorICAgIHZvaWQgc3dpdGNoVG8oUmVwYWlyaW5nS2luZCBOZXdLaW5kKSB7CisgICAgICBhc3NlcnQoTmV3S2luZCAhPSBLaW5kICYmICJBbHJlYWR5IG9mIHRoZSByaWdodCBLaW5kIik7CisgICAgICBLaW5kID0gTmV3S2luZDsKKyAgICAgIEluc2VydFBvaW50cy5jbGVhcigpOworICAgICAgQ2FuTWF0ZXJpYWxpemUgPSBOZXdLaW5kICE9IFJlcGFpcmluZ0tpbmQ6OkltcG9zc2libGU7CisgICAgICBIYXNTcGxpdCA9IGZhbHNlOworICAgICAgYXNzZXJ0KE5ld0tpbmQgIT0gUmVwYWlyaW5nS2luZDo6SW5zZXJ0ICYmCisgICAgICAgICAgICAgIldlIHdvdWxkIG5lZWQgbW9yZSBNSSB0byBzd2l0Y2ggdG8gSW5zZXJ0Iik7CisgICAgfQorICB9OworCitwcml2YXRlOgorICAvLy8gSGVscGVyIGNsYXNzIHVzZWQgdG8gcmVwcmVzZW50IHRoZSBjb3N0IGZvciBtYXBwaW5nIGFuIGluc3RydWN0aW9uLgorICAvLy8gV2hlbiBtYXBwaW5nIGFuIGluc3RydWN0aW9uLCB3ZSBtYXkgaW50cm9kdWNlIHNvbWUgcmVwYWlyaW5nIGNvZGUuCisgIC8vLyBJbiBtb3N0IGNhc2VzLCB0aGUgcmVwYWlyaW5nIGNvZGUgaXMgbG9jYWwgdG8gdGhlIGluc3RydWN0aW9uLAorICAvLy8gdGh1cywgd2UgY2FuIG9taXQgdGhlIGJhc2ljIGJsb2NrIGZyZXF1ZW5jeSBmcm9tIHRoZSBjb3N0LgorICAvLy8gSG93ZXZlciwgc29tZSBhbHRlcm5hdGl2ZXMgbWF5IHByb2R1Y2Ugbm9uLWxvY2FsIGNvc3QsIGUuZy4sIHdoZW4KKyAgLy8vIHJlcGFpcmluZyBhIHBoaSwgYW5kIHRodXMgd2UgdGhlbiBuZWVkIHRvIHNjYWxlIHRoZSBsb2NhbCBjb3N0CisgIC8vLyB0byB0aGUgbm9uLWxvY2FsIGNvc3QuIFRoaXMgY2xhc3MgZG9lcyB0aGlzIGZvciB1cy4KKyAgLy8vIFxub3RlOiBXZSBjb3VsZCBzaW1wbHkgYWx3YXlzIHNjYWxlIHRoZSBjb3N0LiBUaGUgcHJvYmxlbSBpcyB0aGF0CisgIC8vLyB0aGVyZSBhcmUgaGlnaGVyIGNoYW5jZXMgdGhhdCB3ZSBzYXR1cmF0ZSB0aGUgY29zdCBlYXNpZXIgYW5kIGVuZAorICAvLy8gdXAgaGF2aW5nIHRoZSBzYW1lIGNvc3QgZm9yIGFjdHVhbGx5IGRpZmZlcmVudCBhbHRlcm5hdGl2ZXMuCisgIC8vLyBBbm90aGVyIG9wdGlvbiB3b3VsZCBiZSB0byB1c2UgQVBJbnQgZXZlcnl3aGVyZS4KKyAgY2xhc3MgTWFwcGluZ0Nvc3QgeworICBwcml2YXRlOgorICAgIC8vLyBDb3N0IG9mIHRoZSBsb2NhbCBpbnN0cnVjdGlvbnMuCisgICAgLy8vIFRoaXMgY29zdCBpcyBmcmVlIG9mIGJhc2ljIGJsb2NrIGZyZXF1ZW5jeS4KKyAgICB1aW50NjRfdCBMb2NhbENvc3QgPSAwOworICAgIC8vLyBDb3N0IG9mIHRoZSBub24tbG9jYWwgaW5zdHJ1Y3Rpb25zLgorICAgIC8vLyBUaGlzIGNvc3Qgc2hvdWxkIGluY2x1ZGUgdGhlIGZyZXF1ZW5jeSBvZiB0aGUgcmVsYXRlZCBibG9ja3MuCisgICAgdWludDY0X3QgTm9uTG9jYWxDb3N0ID0gMDsKKyAgICAvLy8gRnJlcXVlbmN5IG9mIHRoZSBibG9jayB3aGVyZSB0aGUgbG9jYWwgaW5zdHJ1Y3Rpb25zIGxpdmUuCisgICAgdWludDY0X3QgTG9jYWxGcmVxOworCisgICAgTWFwcGluZ0Nvc3QodWludDY0X3QgTG9jYWxDb3N0LCB1aW50NjRfdCBOb25Mb2NhbENvc3QsIHVpbnQ2NF90IExvY2FsRnJlcSkKKyAgICAgICAgOiBMb2NhbENvc3QoTG9jYWxDb3N0KSwgTm9uTG9jYWxDb3N0KE5vbkxvY2FsQ29zdCksCisgICAgICAgICAgTG9jYWxGcmVxKExvY2FsRnJlcSkge30KKworICAgIC8vLyBDaGVjayBpZiB0aGlzIGNvc3QgaXMgc2F0dXJhdGVkLgorICAgIGJvb2wgaXNTYXR1cmF0ZWQoKSBjb25zdDsKKworICBwdWJsaWM6CisgICAgLy8vIENyZWF0ZSBhIE1hcHBpbmdDb3N0IGFzc3VtaW5nIHRoYXQgbW9zdCBvZiB0aGUgaW5zdHJ1Y3Rpb25zCisgICAgLy8vIHdpbGwgb2NjdXIgaW4gYSBiYXNpYyBibG9jayB3aXRoIFxwIExvY2FsRnJlcSBmcmVxdWVuY3kuCisgICAgTWFwcGluZ0Nvc3QoY29uc3QgQmxvY2tGcmVxdWVuY3kgJkxvY2FsRnJlcSk7CisKKyAgICAvLy8gQWRkIFxwIENvc3QgdG8gdGhlIGxvY2FsIGNvc3QuCisgICAgLy8vIFxyZXR1cm4gdHJ1ZSBpZiB0aGlzIGNvc3QgaXMgc2F0dXJhdGVkLCBmYWxzZSBvdGhlcndpc2UuCisgICAgYm9vbCBhZGRMb2NhbENvc3QodWludDY0X3QgQ29zdCk7CisKKyAgICAvLy8gQWRkIFxwIENvc3QgdG8gdGhlIG5vbi1sb2NhbCBjb3N0LgorICAgIC8vLyBOb24tbG9jYWwgY29zdCBzaG91bGQgcmVmbGVjdCB0aGUgZnJlcXVlbmN5IG9mIHRoZWlyIHBsYWNlbWVudC4KKyAgICAvLy8gXHJldHVybiB0cnVlIGlmIHRoaXMgY29zdCBpcyBzYXR1cmF0ZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgICBib29sIGFkZE5vbkxvY2FsQ29zdCh1aW50NjRfdCBDb3N0KTsKKworICAgIC8vLyBTYXR1cmF0ZSB0aGUgY29zdCB0byB0aGUgbWF4aW1hbCByZXByZXNlbnRhYmxlIHZhbHVlLgorICAgIHZvaWQgc2F0dXJhdGUoKTsKKworICAgIC8vLyBSZXR1cm4gYW4gaW5zdGFuY2Ugb2YgTWFwcGluZ0Nvc3QgdGhhdCByZXByZXNlbnRzIGFuCisgICAgLy8vIGltcG9zc2libGUgbWFwcGluZy4KKyAgICBzdGF0aWMgTWFwcGluZ0Nvc3QgSW1wb3NzaWJsZUNvc3QoKTsKKworICAgIC8vLyBDaGVjayBpZiB0aGlzIGlzIGxlc3MgdGhhbiBccCBDb3N0LgorICAgIGJvb2wgb3BlcmF0b3I8KGNvbnN0IE1hcHBpbmdDb3N0ICZDb3N0KSBjb25zdDsKKyAgICAvLy8gQ2hlY2sgaWYgdGhpcyBpcyBlcXVhbCB0byBccCBDb3N0LgorICAgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBNYXBwaW5nQ29zdCAmQ29zdCkgY29uc3Q7CisgICAgLy8vIENoZWNrIGlmIHRoaXMgaXMgbm90IGVxdWFsIHRvIFxwIENvc3QuCisgICAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IE1hcHBpbmdDb3N0ICZDb3N0KSBjb25zdCB7IHJldHVybiAhKCp0aGlzID09IENvc3QpOyB9CisgICAgLy8vIENoZWNrIGlmIHRoaXMgaXMgZ3JlYXRlciB0aGFuIFxwIENvc3QuCisgICAgYm9vbCBvcGVyYXRvcj4oY29uc3QgTWFwcGluZ0Nvc3QgJkNvc3QpIGNvbnN0IHsKKyAgICAgIHJldHVybiAqdGhpcyAhPSBDb3N0ICYmIENvc3QgPCAqdGhpczsKKyAgICB9CisKKyAgICAvLy8gUHJpbnQgdGhpcyBvbiBkYmdzKCkgc3RyZWFtLgorICAgIHZvaWQgZHVtcCgpIGNvbnN0OworCisgICAgLy8vIFByaW50IHRoaXMgb24gXHAgT1M7CisgICAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MpIGNvbnN0OworCisgICAgLy8vIE92ZXJsb2FkIHRoZSBzdHJlYW0gb3BlcmF0b3IgZm9yIGVhc3kgZGVidWcgcHJpbnRpbmcuCisgICAgZnJpZW5kIHJhd19vc3RyZWFtICZvcGVyYXRvcjw8KHJhd19vc3RyZWFtICZPUywgY29uc3QgTWFwcGluZ0Nvc3QgJkNvc3QpIHsKKyAgICAgIENvc3QucHJpbnQoT1MpOworICAgICAgcmV0dXJuIE9TOworICAgIH0KKyAgfTsKKworICAvLy8gSW50ZXJmYWNlIHRvIHRoZSB0YXJnZXQgbG93ZXJpbmcgaW5mbyByZWxhdGVkCisgIC8vLyB0byByZWdpc3RlciBiYW5rcy4KKyAgY29uc3QgUmVnaXN0ZXJCYW5rSW5mbyAqUkJJID0gbnVsbHB0cjsKKworICAvLy8gTVJJIGNvbnRhaW5zIGFsbCB0aGUgcmVnaXN0ZXIgY2xhc3MvYmFuayBpbmZvcm1hdGlvbiB0aGF0IHRoaXMKKyAgLy8vIHBhc3MgdXNlcyBhbmQgdXBkYXRlcy4KKyAgTWFjaGluZVJlZ2lzdGVySW5mbyAqTVJJID0gbnVsbHB0cjsKKworICAvLy8gSW5mb3JtYXRpb24gb24gdGhlIHJlZ2lzdGVyIGNsYXNzZXMgZm9yIHRoZSBjdXJyZW50IGZ1bmN0aW9uLgorICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSA9IG51bGxwdHI7CisKKyAgLy8vIEdldCB0aGUgZnJlcXVlbmN5IG9mIGJsb2Nrcy4KKyAgLy8vIFRoaXMgaXMgcmVxdWlyZWQgZm9yIG5vbi1mYXN0IG1vZGUuCisgIE1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm8gKk1CRkkgPSBudWxscHRyOworCisgIC8vLyBHZXQgdGhlIGZyZXF1ZW5jeSBvZiB0aGUgZWRnZXMuCisgIC8vLyBUaGlzIGlzIHJlcXVpcmVkIGZvciBub24tZmFzdCBtb2RlLgorICBNYWNoaW5lQnJhbmNoUHJvYmFiaWxpdHlJbmZvICpNQlBJID0gbnVsbHB0cjsKKworICAvLy8gQ3VycmVudCBvcHRpbWl6YXRpb24gcmVtYXJrIGVtaXR0ZXIuIFVzZWQgdG8gcmVwb3J0IGZhaWx1cmVzLgorICBzdGQ6OnVuaXF1ZV9wdHI8TWFjaGluZU9wdGltaXphdGlvblJlbWFya0VtaXR0ZXI+IE1PUkU7CisKKyAgLy8vIEhlbHBlciBjbGFzcyB1c2VkIGZvciBldmVyeSBjb2RlIG1vcnBoaW5nLgorICBNYWNoaW5lSVJCdWlsZGVyIE1JUkJ1aWxkZXI7CisKKyAgLy8vIE9wdGltaXphdGlvbiBtb2RlIG9mIHRoZSBwYXNzLgorICBNb2RlIE9wdE1vZGU7CisKKyAgLy8vIEN1cnJlbnQgdGFyZ2V0IGNvbmZpZ3VyYXRpb24uIENvbnRyb2xzIGhvdyB0aGUgcGFzcyBoYW5kbGVzIGVycm9ycy4KKyAgY29uc3QgVGFyZ2V0UGFzc0NvbmZpZyAqVFBDOworCisgIC8vLyBBc3NpZ24gdGhlIHJlZ2lzdGVyIGJhbmsgb2YgZWFjaCBvcGVyYW5kIG9mIFxwIE1JLgorICAvLy8gXHJldHVybiBUcnVlIG9uIHN1Y2Nlc3MsIGZhbHNlIG90aGVyd2lzZS4KKyAgYm9vbCBhc3NpZ25JbnN0cihNYWNoaW5lSW5zdHIgJk1JKTsKKworICAvLy8gSW5pdGlhbGl6ZSB0aGUgZmllbGQgbWVtYmVycyB1c2luZyBccCBNRi4KKyAgdm9pZCBpbml0KE1hY2hpbmVGdW5jdGlvbiAmTUYpOworCisgIC8vLyBDaGVjayBpZiBccCBSZWcgaXMgYWxyZWFkeSBhc3NpZ25lZCB3aGF0IGlzIGRlc2NyaWJlZCBieSBccCBWYWxNYXBwaW5nLgorICAvLy8gXHAgT25seUFzc2lnbiA9PSB0cnVlIG1lYW5zIHRoYXQgXHAgUmVnIGp1c3QgbmVlZHMgdG8gYmUgYXNzaWduZWQgYQorICAvLy8gcmVnaXN0ZXIgYmFuay4gIEkuZS4sIG5vIHJlcGFpcmluZyBpcyBuZWNlc3NhcnkgdG8gaGF2ZSB0aGUKKyAgLy8vIGFzc2lnbm1lbnQgbWF0Y2guCisgIGJvb2wgYXNzaWdubWVudE1hdGNoKHVuc2lnbmVkIFJlZywKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVnaXN0ZXJCYW5rSW5mbzo6VmFsdWVNYXBwaW5nICZWYWxNYXBwaW5nLAorICAgICAgICAgICAgICAgICAgICAgICBib29sICZPbmx5QXNzaWduKSBjb25zdDsKKworICAvLy8gSW5zZXJ0IHJlcGFpcmluZyBjb2RlIGZvciBccCBSZWcgYXMgc3BlY2lmaWVkIGJ5IFxwIFZhbE1hcHBpbmcuCisgIC8vLyBUaGUgcmVwYWlyaW5nIHBsYWNlbWVudCBpcyBzcGVjaWZpZWQgYnkgXHAgUmVwYWlyUHQuCisgIC8vLyBccCBOZXdWUmVncyBjb250YWlucyBhbGwgdGhlIHJlZ2lzdGVycyByZXF1aXJlZCB0byByZW1hcCBccCBSZWcuCisgIC8vLyBJbiBvdGhlciB3b3JkcywgdGhlIG51bWJlciBvZiByZWdpc3RlcnMgaW4gTmV3VlJlZ3MgbXVzdCBiZSBlcXVhbAorICAvLy8gdG8gVmFsTWFwcGluZy5CcmVha0Rvd24uc2l6ZSgpLgorICAvLy8KKyAgLy8vIFRoZSB0cmFuc2Zvcm1hdGlvbiBjb3VsZCBiZSBza2V0Y2hlZCBhczoKKyAgLy8vIFxjb2RlCisgIC8vLyAuLi4gPSBvcCBSZWcKKyAgLy8vIFxlbmRjb2RlCisgIC8vLyBCZWNvbWVzCisgIC8vLyBcY29kZQorICAvLy8gPE5ld1JlZ3M+ID0gQ09QWSBvciBleHRyYWN0IFJlZworICAvLy8gLi4uID0gb3AgUmVnCisgIC8vLyBcZW5kY29kZQorICAvLy8KKyAgLy8vIGFuZAorICAvLy8gXGNvZGUKKyAgLy8vIFJlZyA9IG9wIC4uLgorICAvLy8gXGVuZGNvZGUKKyAgLy8vIEJlY29tZXMKKyAgLy8vIFxjb2RlCisgIC8vLyBSZWcgPSBvcCAuLi4KKyAgLy8vIFJlZyA9IENPUFkgb3IgYnVpbGRfc2VxdWVuY2UgPE5ld1JlZ3M+CisgIC8vLyBcZW5kY29kZQorICAvLy8KKyAgLy8vIFxwcmUgTmV3VlJlZ3Muc2l6ZSgpID09IFZhbE1hcHBpbmcuQnJlYWtEb3duLnNpemUoKQorICAvLy8KKyAgLy8vIFxub3RlIFRoZSBjYWxsZXIgaXMgc3VwcG9zZWQgdG8gZG8gdGhlIHJld3JpdGluZyBvZiBvcCBpZiBuZWVkIGJlLgorICAvLy8gSS5lLiwgUmVnID0gb3AgLi4uID0+IDxOZXdSZWdzPiA9IE5ld09wIC4uLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gVHJ1ZSBpZiB0aGUgcmVwYWlyaW5nIHdvcmtlZCwgZmFsc2Ugb3RoZXJ3aXNlLgorICBib29sIHJlcGFpclJlZyhNYWNoaW5lT3BlcmFuZCAmTU8sCisgICAgICAgICAgICAgICAgIGNvbnN0IFJlZ2lzdGVyQmFua0luZm86OlZhbHVlTWFwcGluZyAmVmFsTWFwcGluZywKKyAgICAgICAgICAgICAgICAgUmVnQmFua1NlbGVjdDo6UmVwYWlyaW5nUGxhY2VtZW50ICZSZXBhaXJQdCwKKyAgICAgICAgICAgICAgICAgY29uc3QgaXRlcmF0b3JfcmFuZ2U8U21hbGxWZWN0b3JJbXBsPHVuc2lnbmVkPjo6Y29uc3RfaXRlcmF0b3I+CisgICAgICAgICAgICAgICAgICAgICAmTmV3VlJlZ3MpOworCisgIC8vLyBSZXR1cm4gdGhlIGNvc3Qgb2YgdGhlIGluc3RydWN0aW9uIG5lZWRlZCB0byBtYXAgXHAgTU8gdG8gXHAgVmFsTWFwcGluZy4KKyAgLy8vIFRoZSBjb3N0IGlzIGZyZWUgb2YgYmFzaWMgYmxvY2sgZnJlcXVlbmNpZXMuCisgIC8vLyBccHJlIE1PLmlzUmVnKCkKKyAgLy8vIFxwcmUgTU8gaXMgYXNzaWduZWQgdG8gYSByZWdpc3RlciBiYW5rLgorICAvLy8gXHByZSBWYWxNYXBwaW5nIGlzIGEgdmFsaWQgbWFwcGluZyBmb3IgTU8uCisgIHVpbnQ2NF90CisgIGdldFJlcGFpckNvc3QoY29uc3QgTWFjaGluZU9wZXJhbmQgJk1PLAorICAgICAgICAgICAgICAgIGNvbnN0IFJlZ2lzdGVyQmFua0luZm86OlZhbHVlTWFwcGluZyAmVmFsTWFwcGluZykgY29uc3Q7CisKKyAgLy8vIEZpbmQgdGhlIGJlc3QgbWFwcGluZyBmb3IgXHAgTUkgZnJvbSBccCBQb3NzaWJsZU1hcHBpbmdzLgorICAvLy8gXHJldHVybiBhIHJlZmVyZW5jZSBvbiB0aGUgYmVzdCBtYXBwaW5nIGluIFxwIFBvc3NpYmxlTWFwcGluZ3MuCisgIGNvbnN0IFJlZ2lzdGVyQmFua0luZm86Okluc3RydWN0aW9uTWFwcGluZyAmCisgIGZpbmRCZXN0TWFwcGluZyhNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgUmVnaXN0ZXJCYW5rSW5mbzo6SW5zdHJ1Y3Rpb25NYXBwaW5ncyAmUG9zc2libGVNYXBwaW5ncywKKyAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxSZXBhaXJpbmdQbGFjZW1lbnQ+ICZSZXBhaXJQdHMpOworCisgIC8vLyBDb21wdXRlIHRoZSBjb3N0IG9mIG1hcHBpbmcgXHAgTUkgd2l0aCBccCBJbnN0ck1hcHBpbmcgYW5kCisgIC8vLyBjb21wdXRlIHRoZSByZXBhaXJpbmcgcGxhY2VtZW50IGZvciBzdWNoIG1hcHBpbmcgaW4gXHAKKyAgLy8vIFJlcGFpclB0cy4KKyAgLy8vIFxwIEJlc3RDb3N0IGlzIHVzZWQgdG8gc3BlY2lmeSB3aGVuIHRoZSBjb3N0IGJlY29tZXMgdG9vIGhpZ2gKKyAgLy8vIGFuZCB0aHVzIGl0IGlzIG5vdCB3b3J0aCBjb21wdXRpbmcgdGhlIFJlcGFpclB0cy4gIE1vcmVvdmVyIGlmCisgIC8vLyBccCBCZXN0Q29zdCA9PSBudWxscHRyLCB0aGUgbWFwcGluZyBjb3N0IGlzIGFjdHVhbGx5IG5vdAorICAvLy8gY29tcHV0ZWQuCisgIE1hcHBpbmdDb3N0CisgIGNvbXB1dGVNYXBwaW5nKE1hY2hpbmVJbnN0ciAmTUksCisgICAgICAgICAgICAgICAgIGNvbnN0IFJlZ2lzdGVyQmFua0luZm86Okluc3RydWN0aW9uTWFwcGluZyAmSW5zdHJNYXBwaW5nLAorICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8UmVwYWlyaW5nUGxhY2VtZW50PiAmUmVwYWlyUHRzLAorICAgICAgICAgICAgICAgICBjb25zdCBNYXBwaW5nQ29zdCAqQmVzdENvc3QgPSBudWxscHRyKTsKKworICAvLy8gV2hlbiBccCBSZXBhaXJQdCBpbnZvbHZlcyBzcGxpdHRpbmcgdG8gcmVwYWlyIFxwIE1PIGZvciB0aGUKKyAgLy8vIGdpdmVuIFxwIFZhbE1hcHBpbmcsIHRyeSB0byBjaGFuZ2UgdGhlIHdheSB3ZSByZXBhaXIgc3VjaCB0aGF0CisgIC8vLyB0aGUgc3BsaXR0aW5nIGlzIG5vdCByZXF1aXJlZCBhbnltb3JlLgorICAvLy8KKyAgLy8vIFxwcmUgXHAgUmVwYWlyUHQuaGFzU3BsaXQoKQorICAvLy8gXHByZSBccCBNTyA9PSBNTy5nZXRQYXJlbnQoKS0+Z2V0T3BlcmFuZChccCBSZXBhaXJQdC5nZXRPcElkeCgpKQorICAvLy8gXHByZSBccCBWYWxNYXBwaW5nIGlzIHRoZSBtYXBwaW5nIG9mIFxwIE1PIGZvciBNTy5nZXRQYXJlbnQoKQorICAvLy8gICAgICB0aGF0IGltcGxpZWQgXHAgUmVwYWlyUHQuCisgIHZvaWQgdHJ5QXZvaWRpbmdTcGxpdChSZWdCYW5rU2VsZWN0OjpSZXBhaXJpbmdQbGFjZW1lbnQgJlJlcGFpclB0LAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZU9wZXJhbmQgJk1PLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVnaXN0ZXJCYW5rSW5mbzo6VmFsdWVNYXBwaW5nICZWYWxNYXBwaW5nKSBjb25zdDsKKworICAvLy8gQXBwbHkgXHAgTWFwcGluZyB0byBccCBNSS4gXHAgUmVwYWlyUHRzIHJlcHJlc2VudHMgdGhlIGRpZmZlcmVudAorICAvLy8gbWFwcGluZyBhY3Rpb24gdGhhdCBuZWVkIHRvIGhhcHBlbiBmb3IgdGhlIG1hcHBpbmcgdG8gYmUKKyAgLy8vIGFwcGxpZWQuCisgIC8vLyBccmV0dXJuIFRydWUgaWYgdGhlIG1hcHBpbmcgd2FzIGFwcGxpZWQgc3VjZXNzZnVsbHksIGZhbHNlIG90aGVyd2lzZS4KKyAgYm9vbCBhcHBseU1hcHBpbmcoTWFjaGluZUluc3RyICZNSSwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVnaXN0ZXJCYW5rSW5mbzo6SW5zdHJ1Y3Rpb25NYXBwaW5nICZJbnN0ck1hcHBpbmcsCisgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxSZXBhaXJpbmdQbGFjZW1lbnQ+ICZSZXBhaXJQdHMpOworCitwdWJsaWM6CisgIC8vLyBDcmVhdGUgYSBSZWdCYW5rU2VsZWN0IHBhc3Mgd2l0aCB0aGUgc3BlY2lmaWVkIFxwIFJ1bm5pbmdNb2RlLgorICBSZWdCYW5rU2VsZWN0KE1vZGUgUnVubmluZ01vZGUgPSBGYXN0KTsKKworICBTdHJpbmdSZWYgZ2V0UGFzc05hbWUoKSBjb25zdCBvdmVycmlkZSB7IHJldHVybiAiUmVnQmFua1NlbGVjdCI7IH0KKworICB2b2lkIGdldEFuYWx5c2lzVXNhZ2UoQW5hbHlzaXNVc2FnZSAmQVUpIGNvbnN0IG92ZXJyaWRlOworCisgIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMgZ2V0UmVxdWlyZWRQcm9wZXJ0aWVzKCkgY29uc3Qgb3ZlcnJpZGUgeworICAgIHJldHVybiBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzKCkKKyAgICAgICAgLnNldChNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzOjpQcm9wZXJ0eTo6SXNTU0EpCisgICAgICAgIC5zZXQoTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllczo6UHJvcGVydHk6OkxlZ2FsaXplZCk7CisgIH0KKworICBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzIGdldFNldFByb3BlcnRpZXMoKSBjb25zdCBvdmVycmlkZSB7CisgICAgcmV0dXJuIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMoKS5zZXQoCisgICAgICAgIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXM6OlByb3BlcnR5OjpSZWdCYW5rU2VsZWN0ZWQpOworICB9CisKKyAgLy8vIFdhbGsgdGhyb3VnaCBccCBNRiBhbmQgYXNzaWduIGEgcmVnaXN0ZXIgYmFuayB0byBldmVyeSB2aXJ0dWFsIHJlZ2lzdGVyCisgIC8vLyB0aGF0IGFyZSBzdGlsbCBtYXBwZWQgdG8gbm90aGluZy4KKyAgLy8vIFRoZSB0YXJnZXQgbmVlZHMgdG8gcHJvdmlkZSBhIFJlZ2lzdGVyQmFua0luZm8gYW5kIGluIHBhcnRpY3VsYXIKKyAgLy8vIG92ZXJyaWRlIFJlZ2lzdGVyQmFua0luZm86OmdldEluc3RyTWFwcGluZy4KKyAgLy8vCisgIC8vLyBTaW1wbGlmaWVkIGFsZ286CisgIC8vLyBcY29kZQorICAvLy8gICBSQkkgPSBNRi5zdWJ0YXJnZXQuZ2V0UmVnQmFua0luZm8oKQorICAvLy8gICBNSVJCdWlsZGVyLnNldE1GKE1GKQorICAvLy8gICBmb3IgZWFjaCBiYiBpbiBNRgorICAvLy8gICAgIGZvciBlYWNoIGluc3QgaW4gYmIKKyAgLy8vICAgICAgIE1JUkJ1aWxkZXIuc2V0SW5zdHIoaW5zdCkKKyAgLy8vICAgICAgIE1hcHBpbmdDb3N0cyA9IFJCSS5nZXRNYXBwaW5nKGluc3QpOworICAvLy8gICAgICAgSWR4ID0gZmluZElkeE9mTWluQ29zdChNYXBwaW5nQ29zdHMpCisgIC8vLyAgICAgICBDdXJSZWdCYW5rID0gTWFwcGluZ0Nvc3RzW0lkeF0uUmVnQmFuaworICAvLy8gICAgICAgTVJJLnNldFJlZ0JhbmsoaW5zdC5nZXRPcGVyYW5kKDApLmdldFJlZygpLCBDdXJSZWdCYW5rKQorICAvLy8gICAgICAgZm9yIGVhY2ggYXJndW1lbnQgaW4gaW5zdAorICAvLy8gICAgICAgICBpZiAoQ3VyUmVnQmFuayAhPSBhcmd1bWVudC5SZWdCYW5rKQorICAvLy8gICAgICAgICAgIEFyZ1JlZyA9IGFyZ3VtZW50LmdldFJlZygpCisgIC8vLyAgICAgICAgICAgVG1wID0gTVJJLmNyZWF0ZU5ld1ZpcnR1YWwoTVJJLmdldFNpemUoQXJnUmVnKSwgQ3VyUmVnQmFuaykKKyAgLy8vICAgICAgICAgICBNSVJCdWlsZGVyLmJ1aWxkSW5zdHIoQ09QWSwgVG1wLCBBcmdSZWcpCisgIC8vLyAgICAgICAgICAgaW5zdC5nZXRPcGVyYW5kKGFyZ3VtZW50LmdldE9wZXJhbmRObygpKS5zZXRSZWcoVG1wKQorICAvLy8gXGVuZGNvZGUKKyAgYm9vbCBydW5Pbk1hY2hpbmVGdW5jdGlvbihNYWNoaW5lRnVuY3Rpb24gJk1GKSBvdmVycmlkZTsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fR0xPQkFMSVNFTF9SRUdCQU5LU0VMRUNUX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL1JlZ2lzdGVyQmFuay5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvUmVnaXN0ZXJCYW5rLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWQ3NTg0MgotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL1JlZ2lzdGVyQmFuay5oCkBAIC0wLDAgKzEsOTkgQEAKKy8vPT0tLSBsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9SZWdpc3RlckJhbmsuaCAtIFJlZ2lzdGVyIEJhbmsgLS0tLSotIEMrKyAtKi09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8vIFxmaWxlIFRoaXMgZmlsZSBkZWNsYXJlcyB0aGUgQVBJIG9mIHJlZ2lzdGVyIGJhbmtzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfUkVHQkFOS19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX1JFR0JBTktfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvQml0VmVjdG9yLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKy8vIEZvcndhcmQgZGVjbGFyYXRpb25zLgorY2xhc3MgUmVnaXN0ZXJCYW5rSW5mbzsKK2NsYXNzIHJhd19vc3RyZWFtOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJDbGFzczsKK2NsYXNzIFRhcmdldFJlZ2lzdGVySW5mbzsKKworLy8vIFRoaXMgY2xhc3MgaW1wbGVtZW50cyB0aGUgcmVnaXN0ZXIgYmFuayBjb25jZXB0LgorLy8vIFR3byBpbnN0YW5jZXMgb2YgUmVnaXN0ZXJCYW5rIG11c3QgaGF2ZSBkaWZmZXJlbnQgSUQuCisvLy8gVGhpcyBwcm9wZXJ0eSBpcyBlbmZvcmNlZCBieSB0aGUgUmVnaXN0ZXJCYW5rSW5mbyBjbGFzcy4KK2NsYXNzIFJlZ2lzdGVyQmFuayB7Citwcml2YXRlOgorICB1bnNpZ25lZCBJRDsKKyAgY29uc3QgY2hhciAqTmFtZTsKKyAgdW5zaWduZWQgU2l6ZTsKKyAgQml0VmVjdG9yIENvbnRhaW5lZFJlZ0NsYXNzZXM7CisKKyAgLy8vIFNlbnRpbmVsIHZhbHVlIHVzZWQgdG8gcmVjb2duaXplIHJlZ2lzdGVyIGJhbmsgbm90IHByb3Blcmx5CisgIC8vLyBpbml0aWFsaXplZCB5ZXQuCisgIHN0YXRpYyBjb25zdCB1bnNpZ25lZCBJbnZhbGlkSUQ7CisKKyAgLy8vIE9ubHkgdGhlIFJlZ2lzdGVyQmFua0luZm8gY2FuIGluaXRpYWxpemUgUmVnaXN0ZXJCYW5rIHByb3Blcmx5LgorICBmcmllbmQgUmVnaXN0ZXJCYW5rSW5mbzsKKworcHVibGljOgorICBSZWdpc3RlckJhbmsodW5zaWduZWQgSUQsIGNvbnN0IGNoYXIgKk5hbWUsIHVuc2lnbmVkIFNpemUsCisgICAgICAgICAgICAgICBjb25zdCB1aW50MzJfdCAqQ29udGFpbmVkUmVnQ2xhc3NlcywgdW5zaWduZWQgTnVtUmVnQ2xhc3Nlcyk7CisKKyAgLy8vIEdldCB0aGUgaWRlbnRpZmllciBvZiB0aGlzIHJlZ2lzdGVyIGJhbmsuCisgIHVuc2lnbmVkIGdldElEKCkgY29uc3QgeyByZXR1cm4gSUQ7IH0KKworICAvLy8gR2V0IGEgdXNlciBmcmllbmRseSBuYW1lIG9mIHRoaXMgcmVnaXN0ZXIgYmFuay4KKyAgLy8vIFNob3VsZCBiZSB1c2VkIG9ubHkgZm9yIGRlYnVnZ2luZyBwdXJwb3Nlcy4KKyAgY29uc3QgY2hhciAqZ2V0TmFtZSgpIGNvbnN0IHsgcmV0dXJuIE5hbWU7IH0KKworICAvLy8gR2V0IHRoZSBtYXhpbWFsIHNpemUgaW4gYml0cyB0aGF0IGZpdHMgaW4gdGhpcyByZWdpc3RlciBiYW5rLgorICB1bnNpZ25lZCBnZXRTaXplKCkgY29uc3QgeyByZXR1cm4gU2l6ZTsgfQorCisgIC8vLyBDaGVjayB3aGV0aGVyIHRoaXMgaW5zdGFuY2UgaXMgcmVhZHkgdG8gYmUgdXNlZC4KKyAgYm9vbCBpc1ZhbGlkKCkgY29uc3Q7CisKKyAgLy8vIENoZWNrIGlmIHRoaXMgcmVnaXN0ZXIgYmFuayBpcyB2YWxpZC4gSW4gb3RoZXIgd29yZHMsCisgIC8vLyBpZiBpdCBoYXMgYmVlbiBwcm9wZXJseSBjb25zdHJ1Y3RlZC4KKyAgLy8vCisgIC8vLyBcbm90ZSBUaGlzIG1ldGhvZCBkb2VzIG5vdCBjaGVjayBhbnl0aGluZyB3aGVuIGFzc2VydGlvbnMgYXJlIGRpc2FibGVkLgorICAvLy8KKyAgLy8vIFxyZXR1cm4gVHJ1ZSBpcyB0aGUgY2hlY2sgd2FzIHN1Y2Nlc3NmdWwuCisgIGJvb2wgdmVyaWZ5KGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAmVFJJKSBjb25zdDsKKworICAvLy8gQ2hlY2sgd2hldGhlciB0aGlzIHJlZ2lzdGVyIGJhbmsgY292ZXJzIFxwIFJDLgorICAvLy8gSW4gb3RoZXIgd29yZHMsIGNoZWNrIGlmIHRoaXMgcmVnaXN0ZXIgYmFuayBmdWxseSBjb3ZlcnMKKyAgLy8vIHRoZSByZWdpc3RlcnMgdGhhdCBccCBSQyBjb250YWlucy4KKyAgLy8vIFxwcmUgaXNWYWxpZCgpCisgIGJvb2wgY292ZXJzKGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgJlJDKSBjb25zdDsKKworICAvLy8gQ2hlY2sgd2hldGhlciBccCBPdGhlclJCIGlzIHRoZSBzYW1lIGFzIHRoaXMuCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBSZWdpc3RlckJhbmsgJk90aGVyUkIpIGNvbnN0OworICBib29sIG9wZXJhdG9yIT0oY29uc3QgUmVnaXN0ZXJCYW5rICZPdGhlclJCKSBjb25zdCB7CisgICAgcmV0dXJuICF0aGlzLT5vcGVyYXRvcj09KE90aGVyUkIpOworICB9CisKKyAgLy8vIER1bXAgdGhlIHJlZ2lzdGVyIG1hc2sgb24gZGJncygpIHN0cmVhbS4KKyAgLy8vIFRoZSBkdW1wIGlzIHZlcmJvc2UuCisgIHZvaWQgZHVtcChjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSA9IG51bGxwdHIpIGNvbnN0OworCisgIC8vLyBQcmludCB0aGUgcmVnaXN0ZXIgbWFzayBvbiBPUy4KKyAgLy8vIElmIElzRm9yRGVidWcgaXMgZmFsc2UsIHRoZW4gb25seSB0aGUgbmFtZSBvZiB0aGUgcmVnaXN0ZXIgYmFuaworICAvLy8gaXMgcHJpbnRlZC4gT3RoZXJ3aXNlLCBhbGwgdGhlIGZpZWxkcyBhcmUgcHJpbnRpbmcuCisgIC8vLyBUUkkgaXMgdGhlbiB1c2VkIHRvIHByaW50IHRoZSBuYW1lIG9mIHRoZSByZWdpc3RlciBjbGFzc2VzIHRoYXQKKyAgLy8vIHRoaXMgcmVnaXN0ZXIgYmFuayBjb3ZlcnMuCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk9TLCBib29sIElzRm9yRGVidWcgPSBmYWxzZSwKKyAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSA9IG51bGxwdHIpIGNvbnN0OworfTsKKworaW5saW5lIHJhd19vc3RyZWFtICZvcGVyYXRvcjw8KHJhd19vc3RyZWFtICZPUywgY29uc3QgUmVnaXN0ZXJCYW5rICZSZWdCYW5rKSB7CisgIFJlZ0JhbmsucHJpbnQoT1MpOworICByZXR1cm4gT1M7Cit9Cit9IC8vIEVuZCBuYW1lc3BhY2UgbGx2bS4KKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9SZWdpc3RlckJhbmtJbmZvLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9SZWdpc3RlckJhbmtJbmZvLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODJmZDdlZAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL1JlZ2lzdGVyQmFua0luZm8uaApAQCAtMCwwICsxLDc1NyBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL1JlZ2lzdGVyQmFua0luZm8uaCAtLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLy8gXGZpbGUgVGhpcyBmaWxlIGRlY2xhcmVzIHRoZSBBUEkgZm9yIHRoZSByZWdpc3RlciBiYW5rIGluZm8uCisvLy8gVGhpcyBBUEkgaXMgcmVzcG9uc2libGUgZm9yIGhhbmRsaW5nIHRoZSByZWdpc3RlciBiYW5rcy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX1JFR0lTVEVSQkFOS0lORk9fSAorI2RlZmluZSBMTFZNX0NPREVHRU5fR0xPQkFMSVNFTF9SRUdJU1RFUkJBTktJTkZPX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvSGFzaGluZy5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvaXRlcmF0b3JfcmFuZ2UuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvRXJyb3JIYW5kbGluZy5oIgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8aW5pdGlhbGl6ZXJfbGlzdD4KKyNpbmNsdWRlIDxtZW1vcnk+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgTWFjaGluZUluc3RyOworY2xhc3MgTWFjaGluZVJlZ2lzdGVySW5mbzsKK2NsYXNzIHJhd19vc3RyZWFtOworY2xhc3MgUmVnaXN0ZXJCYW5rOworY2xhc3MgVGFyZ2V0SW5zdHJJbmZvOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJDbGFzczsKK2NsYXNzIFRhcmdldFJlZ2lzdGVySW5mbzsKKworLy8vIEhvbGRzIGFsbCB0aGUgaW5mb3JtYXRpb24gcmVsYXRlZCB0byByZWdpc3RlciBiYW5rcy4KK2NsYXNzIFJlZ2lzdGVyQmFua0luZm8geworcHVibGljOgorICAvLy8gSGVscGVyIHN0cnVjdCB0aGF0IHJlcHJlc2VudHMgaG93IGEgdmFsdWUgaXMgcGFydGlhbGx5IG1hcHBlZAorICAvLy8gaW50byBhIHJlZ2lzdGVyLgorICAvLy8gVGhlIFN0YXJ0SWR4IGFuZCBMZW5ndGggcmVwcmVzZW50IHdoYXQgcmVnaW9uIG9mIHRoZSBvcmdpbmFsCisgIC8vLyB2YWx1ZSB0aGlzIHBhcnRpYWwgbWFwcGluZyBjb3ZlcnMuCisgIC8vLyBUaGlzIGNhbiBiZSByZXByZXNlbnRlZCBhcyBhIE1hc2sgb2YgY29udGlndW91cyBiaXQgc3RhcnRpbmcKKyAgLy8vIGF0IFN0YXJ0SWR4IGJpdCBhbmQgc3Bhbm5pbmcgTGVuZ3RoIGJpdHMuCisgIC8vLyBTdGFydElkeCBpcyB0aGUgbnVtYmVyIG9mIGJpdHMgZnJvbSB0aGUgbGVzcyBzaWduaWZpY2FudCBiaXRzLgorICBzdHJ1Y3QgUGFydGlhbE1hcHBpbmcgeworICAgIC8vLyBOdW1iZXIgb2YgYml0cyBhdCB3aGljaCB0aGlzIHBhcnRpYWwgbWFwcGluZyBzdGFydHMgaW4gdGhlCisgICAgLy8vIG9yaWdpbmFsIHZhbHVlLiAgVGhlIGJpdHMgYXJlIGNvdW50ZWQgZnJvbSBsZXNzIHNpZ25pZmljYW50CisgICAgLy8vIGJpdHMgdG8gbW9zdCBzaWduaWZpY2FudCBiaXRzLgorICAgIHVuc2lnbmVkIFN0YXJ0SWR4OworCisgICAgLy8vIExlbmd0aCBvZiB0aGlzIG1hcHBpbmcgaW4gYml0cy4gVGhpcyBpcyBob3cgbWFueSBiaXRzIHRoaXMKKyAgICAvLy8gcGFydGlhbCBtYXBwaW5nIGNvdmVycyBpbiB0aGUgb3JpZ2luYWwgdmFsdWU6CisgICAgLy8vIGZyb20gU3RhcnRJZHggdG8gU3RhcnRJZHggKyBMZW5ndGggLTEuCisgICAgdW5zaWduZWQgTGVuZ3RoOworCisgICAgLy8vIFJlZ2lzdGVyIGJhbmsgd2hlcmUgdGhlIHBhcnRpYWwgdmFsdWUgbGl2ZXMuCisgICAgY29uc3QgUmVnaXN0ZXJCYW5rICpSZWdCYW5rOworCisgICAgUGFydGlhbE1hcHBpbmcoKSA9IGRlZmF1bHQ7CisKKyAgICAvLy8gUHJvdmlkZSBhIHNob3J0Y3V0IGZvciBxdWlja2x5IGJ1aWxkaW5nIFBhcnRpYWxNYXBwaW5nLgorICAgIFBhcnRpYWxNYXBwaW5nKHVuc2lnbmVkIFN0YXJ0SWR4LCB1bnNpZ25lZCBMZW5ndGgsCisgICAgICAgICAgICAgICAgICAgY29uc3QgUmVnaXN0ZXJCYW5rICZSZWdCYW5rKQorICAgICAgICA6IFN0YXJ0SWR4KFN0YXJ0SWR4KSwgTGVuZ3RoKExlbmd0aCksIFJlZ0JhbmsoJlJlZ0JhbmspIHt9CisKKyAgICAvLy8gXHJldHVybiB0aGUgaW5kZXggb2YgaW4gdGhlIG9yaWdpbmFsIHZhbHVlIG9mIHRoZSBtb3N0CisgICAgLy8vIHNpZ25pZmljYW50IGJpdCB0aGF0IHRoaXMgcGFydGlhbCBtYXBwaW5nIGNvdmVycy4KKyAgICB1bnNpZ25lZCBnZXRIaWdoQml0SWR4KCkgY29uc3QgeyByZXR1cm4gU3RhcnRJZHggKyBMZW5ndGggLSAxOyB9CisKKyAgICAvLy8gUHJpbnQgdGhpcyBwYXJ0aWFsIG1hcHBpbmcgb24gZGJncygpIHN0cmVhbS4KKyAgICB2b2lkIGR1bXAoKSBjb25zdDsKKworICAgIC8vLyBQcmludCB0aGlzIHBhcnRpYWwgbWFwcGluZyBvbiBccCBPUzsKKyAgICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUykgY29uc3Q7CisKKyAgICAvLy8gQ2hlY2sgdGhhdCB0aGUgTWFzayBpcyBjb21wYXRpYmxlIHdpdGggdGhlIFJlZ0JhbmsuCisgICAgLy8vIEluZGVlZCwgaWYgdGhlIFJlZ0JhbmsgY2Fubm90IGFjY29tYWRhdGUgdGhlICJhY3RpdmUgYml0cyIgb2YgdGhlIG1hc2ssCisgICAgLy8vIHRoZXJlIGlzIG5vIHdheSB0aGlzIG1hcHBpbmcgaXMgdmFsaWQuCisgICAgLy8vCisgICAgLy8vIFxub3RlIFRoaXMgbWV0aG9kIGRvZXMgbm90IGNoZWNrIGFueXRoaW5nIHdoZW4gYXNzZXJ0aW9ucyBhcmUgZGlzYWJsZWQuCisgICAgLy8vCisgICAgLy8vIFxyZXR1cm4gVHJ1ZSBpcyB0aGUgY2hlY2sgd2FzIHN1Y2Nlc3NmdWwuCisgICAgYm9vbCB2ZXJpZnkoKSBjb25zdDsKKyAgfTsKKworICAvLy8gSGVscGVyIHN0cnVjdCB0aGF0IHJlcHJlc2VudHMgaG93IGEgdmFsdWUgaXMgbWFwcGVkIHRocm91Z2gKKyAgLy8vIGRpZmZlcmVudCByZWdpc3RlciBiYW5rcy4KKyAgLy8vCisgIC8vLyBcbm90ZTogU28gZmFyIHdlIGRvIG5vdCBoYXZlIGFueSB1c2VycyBvZiB0aGUgY29tcGxleCBtYXBwaW5ncworICAvLy8gKG1hcHBpbmdzIHdpdGggbW9yZSB0aGFuIG9uZSBwYXJ0aWFsIG1hcHBpbmcpLCBidXQgd2hlbiB3ZSBkbywKKyAgLy8vIHdlIHdvdWxkIGhhdmUgbmVlZGVkIHRvIGR1cGxpY2F0ZSBwYXJ0aWFsIG1hcHBpbmdzLgorICAvLy8gVGhlIGFsdGVybmF0aXZlIGNvdWxkIGJlIHRvIHVzZSBhbiBhcnJheSBvZiBwb2ludGVycyBvZiBwYXJ0aWFsCisgIC8vLyBtYXBwaW5nIChpLmUuLCBQYXJ0aWFsTWFwcGluZyAqKkJyZWFrRG93bikgYW5kIGR1cGxpY2F0ZSB0aGUKKyAgLy8vIHBvaW50ZXJzIGluc3RlYWQuCisgIC8vLworICAvLy8gRS5nLiwKKyAgLy8vIExldCBzYXkgd2UgaGF2ZSBhIDMyLWJpdCBhZGQgYW5kIGEgPDIgeCAzMi1iaXQ+IHZhZGQuIFdlCisgIC8vLyBjYW4gZXhwYW5kIHRoZQorICAvLy8gPDIgeCAzMi1iaXQ+IGFkZCBpbnRvIDIgeCAzMi1iaXQgYWRkLgorICAvLy8KKyAgLy8vIEN1cnJlbnRseSB0aGUgVGFibGVHZW4tbGlrZSBmaWxlIHdvdWxkIGxvb2sgbGlrZToKKyAgLy8vIFxjb2RlCisgIC8vLyBQYXJ0aWFsTWFwcGluZ1tdID0geworICAvLy8gLyozMi1iaXQgYWRkKi8gezAsIDMyLCBHUFJ9LAorICAvLy8gLyoyeDMyLWJpdCBhZGQqLyB7MCwgMzIsIEdQUn0sIHswLCAzMiwgR1BSfSwgLy8gPC0tIFNhbWUgZW50cnkgM3gKKyAgLy8vIC8qPDJ4MzItYml0PiB2YWRkIHswLCA2NCwgVlBSfQorICAvLy8gfTsgLy8gUGFydGlhbE1hcHBpbmcgZHVwbGljYXRlZC4KKyAgLy8vCisgIC8vLyBWYWx1ZU1hcHBpbmdbXSB7CisgIC8vLyAgIC8qcGxhaW4gMzItYml0IGFkZCovIHsmUGFydGlhbE1hcHBpbmdbMF0sIDF9LAorICAvLy8gICAvKmV4cGFuZGVkIHZhZGQgb24gMnhhZGQqLyB7JlBhcnRpYWxNYXBwaW5nWzFdLCAyfSwKKyAgLy8vICAgLypwbGFpbiA8MngzMi1iaXQ+IHZhZGQqLyB7JlBhcnRpYWxNYXBwaW5nWzNdLCAxfQorICAvLy8gfTsKKyAgLy8vIFxlbmRjb2RlCisgIC8vLworICAvLy8gV2l0aCB0aGUgYXJyYXkgb2YgcG9pbnRlciwgd2Ugd291bGQgaGF2ZToKKyAgLy8vIFxjb2RlCisgIC8vLyBQYXJ0aWFsTWFwcGluZ1tdID0geworICAvLy8gLyozMi1iaXQgYWRkKi8gezAsIDMyLCBHUFJ9LAorICAvLy8gLyo8MngzMi1iaXQ+IHZhZGQgezAsIDY0LCBWUFJ9CisgIC8vLyB9OyAvLyBObyBtb3JlIGR1cGxpY2F0aW9uLgorICAvLy8KKyAgLy8vIEJyZWFrRG93bnNbXSA9IHsKKyAgLy8vIC8qQWRkQnJlYWtEb3duKi8gJlBhcnRpYWxNYXBwaW5nWzBdLAorICAvLy8gLyoyeEFkZEJyZWFrRG93biovICZQYXJ0aWFsTWFwcGluZ1swXSwgJlBhcnRpYWxNYXBwaW5nWzBdLAorICAvLy8gLypWQWRkQnJlYWtEb3duKi8gJlBhcnRpYWxNYXBwaW5nWzFdCisgIC8vLyB9OyAvLyBBZGRyZXNzZXMgb2YgUGFydGlhbE1hcHBpbmcgZHVwbGljYXRlZCAoc21hbGxlcikuCisgIC8vLworICAvLy8gVmFsdWVNYXBwaW5nW10geworICAvLy8gICAvKnBsYWluIDMyLWJpdCBhZGQqLyB7JkJyZWFrRG93bnNbMF0sIDF9LAorICAvLy8gICAvKmV4cGFuZGVkIHZhZGQgb24gMnhhZGQqLyB7JkJyZWFrRG93bnNbMV0sIDJ9LAorICAvLy8gICAvKnBsYWluIDwyeDMyLWJpdD4gdmFkZCovIHsmQnJlYWtEb3duc1szXSwgMX0KKyAgLy8vIH07CisgIC8vLyBcZW5kY29kZQorICAvLy8KKyAgLy8vIEdpdmVuIHRoYXQgYSBQYXJ0aWFsTWFwcGluZyBpcyBhY3R1YWxseSBzbWFsbCwgdGhlIGNvZGUgc2l6ZQorICAvLy8gaW1wYWN0IGlzIGFjdHVhbGx5IGEgZGVncmFkYXRpb24uIE1vcmVvdmVyIHRoZSBjb21waWxlIHRpbWUgd2lsbAorICAvLy8gYmUgaGl0IGJ5IHRoZSBhZGRpdGlvbmFsIGluZGlyZWN0aW9uLgorICAvLy8gSWYgUGFydGlhbE1hcHBpbmcgZ2V0cyBiaWdnZXIgd2UgbWF5IHJlY29uc2lkZXIuCisgIHN0cnVjdCBWYWx1ZU1hcHBpbmcgeworICAgIC8vLyBIb3cgdGhlIHZhbHVlIGlzIGJyb2tlbiBkb3duIGJldHdlZW4gdGhlIGRpZmZlcmVudCByZWdpc3RlciBiYW5rcy4KKyAgICBjb25zdCBQYXJ0aWFsTWFwcGluZyAqQnJlYWtEb3duOworCisgICAgLy8vIE51bWJlciBvZiBwYXJ0aWFsIG1hcHBpbmcgdG8gYnJlYWsgZG93biB0aGlzIHZhbHVlLgorICAgIHVuc2lnbmVkIE51bUJyZWFrRG93bnM7CisKKyAgICAvLy8gVGhlIGRlZmF1bHQgY29uc3RydWN0b3IgY3JlYXRlcyBhbiBpbnZhbGlkIChpc1ZhbGlkKCkgPT0gZmFsc2UpCisgICAgLy8vIGluc3RhbmNlLgorICAgIFZhbHVlTWFwcGluZygpIDogVmFsdWVNYXBwaW5nKG51bGxwdHIsIDApIHt9CisKKyAgICAvLy8gSW5pdGlhbGl6ZSBhIFZhbHVlTWFwcGluZyB3aXRoIHRoZSBnaXZlbiBwYXJhbWV0ZXIuCisgICAgLy8vIFxwIEJyZWFrRG93biBuZWVkcyB0byBoYXZlIGEgbGlmZSB0aW1lIGF0IGxlYXN0IGFzIGxvbmcKKyAgICAvLy8gYXMgdGhpcyBpbnN0YW5jZS4KKyAgICBWYWx1ZU1hcHBpbmcoY29uc3QgUGFydGlhbE1hcHBpbmcgKkJyZWFrRG93biwgdW5zaWduZWQgTnVtQnJlYWtEb3ducykKKyAgICAgICAgOiBCcmVha0Rvd24oQnJlYWtEb3duKSwgTnVtQnJlYWtEb3ducyhOdW1CcmVha0Rvd25zKSB7fQorCisgICAgLy8vIEl0ZXJhdG9ycyB0aHJvdWdoIHRoZSBQYXJ0aWFsTWFwcGluZ3MuCisgICAgY29uc3QgUGFydGlhbE1hcHBpbmcgKmJlZ2luKCkgY29uc3QgeyByZXR1cm4gQnJlYWtEb3duOyB9CisgICAgY29uc3QgUGFydGlhbE1hcHBpbmcgKmVuZCgpIGNvbnN0IHsgcmV0dXJuIEJyZWFrRG93biArIE51bUJyZWFrRG93bnM7IH0KKworICAgIC8vLyBDaGVjayBpZiB0aGlzIFZhbHVlTWFwcGluZyBpcyB2YWxpZC4KKyAgICBib29sIGlzVmFsaWQoKSBjb25zdCB7IHJldHVybiBCcmVha0Rvd24gJiYgTnVtQnJlYWtEb3duczsgfQorCisgICAgLy8vIFZlcmlmeSB0aGF0IHRoaXMgbWFwcGluZyBtYWtlcyBzZW5zZSBmb3IgYSB2YWx1ZSBvZgorICAgIC8vLyBccCBNZWFuaW5nZnVsQml0V2lkdGguCisgICAgLy8vIFxub3RlIFRoaXMgbWV0aG9kIGRvZXMgbm90IGNoZWNrIGFueXRoaW5nIHdoZW4gYXNzZXJ0aW9ucyBhcmUgZGlzYWJsZWQuCisgICAgLy8vCisgICAgLy8vIFxyZXR1cm4gVHJ1ZSBpcyB0aGUgY2hlY2sgd2FzIHN1Y2Nlc3NmdWwuCisgICAgYm9vbCB2ZXJpZnkodW5zaWduZWQgTWVhbmluZ2Z1bEJpdFdpZHRoKSBjb25zdDsKKworICAgIC8vLyBQcmludCB0aGlzIG9uIGRiZ3MoKSBzdHJlYW0uCisgICAgdm9pZCBkdW1wKCkgY29uc3Q7CisKKyAgICAvLy8gUHJpbnQgdGhpcyBvbiBccCBPUzsKKyAgICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUykgY29uc3Q7CisgIH07CisKKyAgLy8vIEhlbHBlciBjbGFzcyB0aGF0IHJlcHJlc2VudHMgaG93IHRoZSB2YWx1ZSBvZiBhbiBpbnN0cnVjdGlvbiBtYXkgYmUKKyAgLy8vIG1hcHBlZCBhbmQgd2hhdCBpcyB0aGUgcmVsYXRlZCBjb3N0IG9mIHN1Y2ggbWFwcGluZy4KKyAgY2xhc3MgSW5zdHJ1Y3Rpb25NYXBwaW5nIHsKKyAgICAvLy8gSWRlbnRpZmllciBvZiB0aGUgbWFwcGluZy4KKyAgICAvLy8gVGhpcyBpcyB1c2VkIHRvIGNvbW11bmljYXRlIGJldHdlZW4gdGhlIHRhcmdldCBhbmQgdGhlIG9wdGltaXplcnMKKyAgICAvLy8gd2hpY2ggbWFwcGluZyBzaG91bGQgYmUgcmVhbGl6ZWQuCisgICAgdW5zaWduZWQgSUQgPSBJbnZhbGlkTWFwcGluZ0lEOworCisgICAgLy8vIENvc3Qgb2YgdGhpcyBtYXBwaW5nLgorICAgIHVuc2lnbmVkIENvc3QgPSAwOworCisgICAgLy8vIE1hcHBpbmcgb2YgYWxsIHRoZSBvcGVyYW5kcy4KKyAgICBjb25zdCBWYWx1ZU1hcHBpbmcgKk9wZXJhbmRzTWFwcGluZzsKKworICAgIC8vLyBOdW1iZXIgb2Ygb3BlcmFuZHMuCisgICAgdW5zaWduZWQgTnVtT3BlcmFuZHMgPSAwOworCisgICAgY29uc3QgVmFsdWVNYXBwaW5nICZnZXRPcGVyYW5kTWFwcGluZyh1bnNpZ25lZCBpKSB7CisgICAgICBhc3NlcnQoaSA8IGdldE51bU9wZXJhbmRzKCkgJiYgIk91dCBvZiBib3VuZCBvcGVyYW5kIik7CisgICAgICByZXR1cm4gT3BlcmFuZHNNYXBwaW5nW2ldOworICAgIH0KKworICBwdWJsaWM6CisgICAgLy8vIENvbnN0cnVjdG9yIGZvciB0aGUgbWFwcGluZyBvZiBhbiBpbnN0cnVjdGlvbi4KKyAgICAvLy8gXHAgTnVtT3BlcmFuZHMgbXVzdCBiZSBlcXVhbCB0byBudW1iZXIgb2YgYWxsIHRoZSBvcGVyYW5kcyBvZgorICAgIC8vLyB0aGUgcmVsYXRlZCBpbnN0cnVjdGlvbi4KKyAgICAvLy8gVGhlIHJhdGlvbmFsZSBpcyB0aGF0IGl0IGlzIG1vcmUgZWZmaWNpZW50IGZvciB0aGUgb3B0aW1pemVycworICAgIC8vLyB0byBiZSBhYmxlIHRvIGFzc3VtZSB0aGF0IHRoZSBtYXBwaW5nIG9mIHRoZSBpdGggb3BlcmFuZCBpcworICAgIC8vLyBhdCB0aGUgaW5kZXggaS4KKyAgICAvLy8KKyAgICAvLy8gXHByZSBJRCAhPSBJbnZhbGlkTWFwcGluZ0lECisgICAgSW5zdHJ1Y3Rpb25NYXBwaW5nKHVuc2lnbmVkIElELCB1bnNpZ25lZCBDb3N0LAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBWYWx1ZU1hcHBpbmcgKk9wZXJhbmRzTWFwcGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgTnVtT3BlcmFuZHMpCisgICAgICAgIDogSUQoSUQpLCBDb3N0KENvc3QpLCBPcGVyYW5kc01hcHBpbmcoT3BlcmFuZHNNYXBwaW5nKSwKKyAgICAgICAgICBOdW1PcGVyYW5kcyhOdW1PcGVyYW5kcykgeworICAgICAgYXNzZXJ0KGdldElEKCkgIT0gSW52YWxpZE1hcHBpbmdJRCAmJgorICAgICAgICAgICAgICJVc2UgdGhlIGRlZmF1bHQgY29uc3RydWN0b3IgZm9yIGludmFsaWQgbWFwcGluZyIpOworICAgIH0KKworICAgIC8vLyBEZWZhdWx0IGNvbnN0cnVjdG9yLgorICAgIC8vLyBVc2UgdGhpcyBjb25zdHJ1Y3RvciB0byBleHByZXNzIHRoYXQgdGhlIG1hcHBpbmcgaXMgaW52YWxpZC4KKyAgICBJbnN0cnVjdGlvbk1hcHBpbmcoKSA9IGRlZmF1bHQ7CisKKyAgICAvLy8gR2V0IHRoZSBjb3N0LgorICAgIHVuc2lnbmVkIGdldENvc3QoKSBjb25zdCB7IHJldHVybiBDb3N0OyB9CisKKyAgICAvLy8gR2V0IHRoZSBJRC4KKyAgICB1bnNpZ25lZCBnZXRJRCgpIGNvbnN0IHsgcmV0dXJuIElEOyB9CisKKyAgICAvLy8gR2V0IHRoZSBudW1iZXIgb2Ygb3BlcmFuZHMuCisgICAgdW5zaWduZWQgZ2V0TnVtT3BlcmFuZHMoKSBjb25zdCB7IHJldHVybiBOdW1PcGVyYW5kczsgfQorCisgICAgLy8vIEdldCB0aGUgdmFsdWUgbWFwcGluZyBvZiB0aGUgaXRoIG9wZXJhbmQuCisgICAgLy8vIFxwcmUgVGhlIG1hcHBpbmcgZm9yIHRoZSBpdGggb3BlcmFuZCBoYXMgYmVlbiBzZXQuCisgICAgLy8vIFxwcmUgVGhlIGl0aCBvcGVyYW5kIGlzIGEgcmVnaXN0ZXIuCisgICAgY29uc3QgVmFsdWVNYXBwaW5nICZnZXRPcGVyYW5kTWFwcGluZyh1bnNpZ25lZCBpKSBjb25zdCB7CisgICAgICBjb25zdCBWYWx1ZU1hcHBpbmcgJlZhbE1hcHBpbmcgPQorICAgICAgICAgIGNvbnN0X2Nhc3Q8SW5zdHJ1Y3Rpb25NYXBwaW5nICo+KHRoaXMpLT5nZXRPcGVyYW5kTWFwcGluZyhpKTsKKyAgICAgIHJldHVybiBWYWxNYXBwaW5nOworICAgIH0KKworICAgIC8vLyBTZXQgdGhlIG1hcHBpbmcgZm9yIGFsbCB0aGUgb3BlcmFuZHMuCisgICAgLy8vIEluIG90aGVyIHdvcmRzLCBPcGRzTWFwcGluZyBzaG91bGQgaG9sZCBhdCBsZWFzdCBnZXROdW1PcGVyYW5kcworICAgIC8vLyBWYWx1ZU1hcHBpbmcuCisgICAgdm9pZCBzZXRPcGVyYW5kc01hcHBpbmcoY29uc3QgVmFsdWVNYXBwaW5nICpPcGRzTWFwcGluZykgeworICAgICAgT3BlcmFuZHNNYXBwaW5nID0gT3Bkc01hcHBpbmc7CisgICAgfQorCisgICAgLy8vIENoZWNrIHdoZXRoZXIgdGhpcyBvYmplY3QgaXMgdmFsaWQuCisgICAgLy8vIFRoaXMgaXMgYSBsaWdodHdlaWdodCBjaGVjayBmb3Igb2J2aW91cyB3cm9uZyBpbnN0YW5jZS4KKyAgICBib29sIGlzVmFsaWQoKSBjb25zdCB7CisgICAgICByZXR1cm4gZ2V0SUQoKSAhPSBJbnZhbGlkTWFwcGluZ0lEICYmIE9wZXJhbmRzTWFwcGluZzsKKyAgICB9CisKKyAgICAvLy8gVmVyaWZpeSB0aGF0IHRoaXMgbWFwcGluZyBtYWtlcyBzZW5zZSBmb3IgXHAgTUkuCisgICAgLy8vIFxwcmUgXHAgTUkgbXVzdCBiZSBjb25uZWN0ZWQgdG8gYSBNYWNoaW5lRnVuY3Rpb24uCisgICAgLy8vCisgICAgLy8vIFxub3RlIFRoaXMgbWV0aG9kIGRvZXMgbm90IGNoZWNrIGFueXRoaW5nIHdoZW4gYXNzZXJ0aW9ucyBhcmUgZGlzYWJsZWQuCisgICAgLy8vCisgICAgLy8vIFxyZXR1cm4gVHJ1ZSBpcyB0aGUgY2hlY2sgd2FzIHN1Y2Nlc3NmdWwuCisgICAgYm9vbCB2ZXJpZnkoY29uc3QgTWFjaGluZUluc3RyICZNSSkgY29uc3Q7CisKKyAgICAvLy8gUHJpbnQgdGhpcyBvbiBkYmdzKCkgc3RyZWFtLgorICAgIHZvaWQgZHVtcCgpIGNvbnN0OworCisgICAgLy8vIFByaW50IHRoaXMgb24gXHAgT1M7CisgICAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MpIGNvbnN0OworICB9OworCisgIC8vLyBDb252ZW5pZW50IHR5cGUgdG8gcmVwcmVzZW50IHRoZSBhbHRlcm5hdGl2ZXMgZm9yIG1hcHBpbmcgYW4KKyAgLy8vIGluc3RydWN0aW9uLgorICAvLy8gXHRvZG8gV2hlbiB3ZSBtb3ZlIHRvIFRhYmxlR2VuIHRoaXMgc2hvdWxkIGJlIGFuIGFycmF5IHJlZi4KKyAgdXNpbmcgSW5zdHJ1Y3Rpb25NYXBwaW5ncyA9IFNtYWxsVmVjdG9yPGNvbnN0IEluc3RydWN0aW9uTWFwcGluZyAqLCA0PjsKKworICAvLy8gSGVscGVyIGNsYXNzIHVzZWQgdG8gZ2V0L2NyZWF0ZSB0aGUgdmlydHVhbCByZWdpc3RlcnMgdGhhdCB3aWxsIGJlIHVzZWQKKyAgLy8vIHRvIHJlcGxhY2UgdGhlIE1hY2hpbmVPcGVyYW5kIHdoZW4gYXBwbHlpbmcgYSBtYXBwaW5nLgorICBjbGFzcyBPcGVyYW5kc01hcHBlciB7CisgICAgLy8vIFRoZSBPcElkeC10aCBjZWxsIGNvbnRhaW5zIHRoZSBpbmRleCBpbiBOZXdWUmVncyB3aGVyZSB0aGUgVlJlZ3Mgb2YgdGhlCisgICAgLy8vIE9wSWR4LXRoIG9wZXJhbmQgc3RhcnRzLiAtMSBtZWFucyB3ZSBkbyBub3QgaGF2ZSBzdWNoIG1hcHBpbmcgeWV0LgorICAgIC8vLyBOb3RlOiBXZSB1c2UgYSBTbWFsbFZlY3RvciB0byBhdm9pZCBoZWFwIGFsbG9jYXRpb24gZm9yIG1vc3QgY2FzZXMuCisgICAgU21hbGxWZWN0b3I8aW50LCA4PiBPcFRvTmV3VlJlZ0lkeDsKKworICAgIC8vLyBIb2xkIHRoZSByZWdpc3RlcnMgdGhhdCB3aWxsIGJlIHVzZWQgdG8gbWFwIE1JIHdpdGggSW5zdHJNYXBwaW5nLgorICAgIFNtYWxsVmVjdG9yPHVuc2lnbmVkLCA4PiBOZXdWUmVnczsKKworICAgIC8vLyBDdXJyZW50IE1hY2hpbmVSZWdpc3RlckluZm8sIHVzZWQgdG8gY3JlYXRlIG5ldyB2aXJ0dWFsIHJlZ2lzdGVycy4KKyAgICBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkk7CisKKyAgICAvLy8gSW5zdHJ1Y3Rpb24gYmVpbmcgcmVtYXBwZWQuCisgICAgTWFjaGluZUluc3RyICZNSTsKKworICAgIC8vLyBOZXcgbWFwcGluZyBvZiB0aGUgaW5zdHJ1Y3Rpb24uCisgICAgY29uc3QgSW5zdHJ1Y3Rpb25NYXBwaW5nICZJbnN0ck1hcHBpbmc7CisKKyAgICAvLy8gQ29uc3RhbnQgdmFsdWUgaWRlbnRpZnlpbmcgdGhhdCB0aGUgaW5kZXggaW4gT3BUb05ld1ZSZWdJZHgKKyAgICAvLy8gZm9yIGFuIG9wZXJhbmQgaGFzIG5vdCBiZWVuIHNldCB5ZXQuCisgICAgc3RhdGljIGNvbnN0IGludCBEb250S25vd0lkeDsKKworICAgIC8vLyBHZXQgdGhlIHJhbmdlIGluIE5ld1ZSZWdzIHRvIHN0b3JlIGFsbCB0aGUgcGFydGlhbAorICAgIC8vLyB2YWx1ZXMgZm9yIHRoZSBccCBPcElkeC10aCBvcGVyYW5kLgorICAgIC8vLworICAgIC8vLyBccmV0dXJuIFRoZSBpdGVyYXRvciByYW5nZSBmb3IgdGhlIHNwYWNlIGNyZWF0ZWQuCisgICAgLy8KKyAgICAvLy8gXHByZSBnZXRNSSgpLmdldE9wZXJhbmQoT3BJZHgpLmlzUmVnKCkKKyAgICBpdGVyYXRvcl9yYW5nZTxTbWFsbFZlY3RvckltcGw8dW5zaWduZWQ+OjppdGVyYXRvcj4KKyAgICBnZXRWUmVnc01lbSh1bnNpZ25lZCBPcElkeCk7CisKKyAgICAvLy8gR2V0IHRoZSBlbmQgaXRlcmF0b3IgZm9yIGEgcmFuZ2Ugc3RhcnRpbmcgYXQgXHAgU3RhcnRJZHggYW5kCisgICAgLy8vIHNwYW5uaWcgXHAgTnVtVmFsIGluIE5ld1ZSZWdzLgorICAgIC8vLyBccHJlIFN0YXJ0SWR4ICsgTnVtVmFsIDw9IE5ld1ZSZWdzLnNpemUoKQorICAgIFNtYWxsVmVjdG9ySW1wbDx1bnNpZ25lZD46OmNvbnN0X2l0ZXJhdG9yCisgICAgZ2V0TmV3VlJlZ3NFbmQodW5zaWduZWQgU3RhcnRJZHgsIHVuc2lnbmVkIE51bVZhbCkgY29uc3Q7CisgICAgU21hbGxWZWN0b3JJbXBsPHVuc2lnbmVkPjo6aXRlcmF0b3IgZ2V0TmV3VlJlZ3NFbmQodW5zaWduZWQgU3RhcnRJZHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgTnVtVmFsKTsKKworICBwdWJsaWM6CisgICAgLy8vIENyZWF0ZSBhbiBPcGVyYW5kc01hcHBlciB0aGF0IHdpbGwgaG9sZCB0aGUgaW5mb3JtYXRpb24gdG8gYXBwbHkgXHAKKyAgICAvLy8gSW5zdHJNYXBwaW5nIHRvIFxwIE1JLgorICAgIC8vLyBccHJlIEluc3RyTWFwcGluZy52ZXJpZnkoTUkpCisgICAgT3BlcmFuZHNNYXBwZXIoTWFjaGluZUluc3RyICZNSSwgY29uc3QgSW5zdHJ1Y3Rpb25NYXBwaW5nICZJbnN0ck1hcHBpbmcsCisgICAgICAgICAgICAgICAgICAgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJKTsKKworICAgIC8vLyBcbmFtZSBHZXR0ZXJzLgorICAgIC8vLyBAeworICAgIC8vLyBUaGUgTWFjaGluZUluc3RyIGJlaW5nIHJlbWFwcGVkLgorICAgIE1hY2hpbmVJbnN0ciAmZ2V0TUkoKSBjb25zdCB7IHJldHVybiBNSTsgfQorCisgICAgLy8vIFRoZSBmaW5hbCBtYXBwaW5nIG9mIHRoZSBpbnN0cnVjdGlvbi4KKyAgICBjb25zdCBJbnN0cnVjdGlvbk1hcHBpbmcgJmdldEluc3RyTWFwcGluZygpIGNvbnN0IHsgcmV0dXJuIEluc3RyTWFwcGluZzsgfQorCisgICAgLy8vIFRoZSBNYWNoaW5lUmVnaXN0ZXJJbmZvIHdlIHVzZWQgdG8gcmVhbGl6ZSB0aGUgbWFwcGluZy4KKyAgICBNYWNoaW5lUmVnaXN0ZXJJbmZvICZnZXRNUkkoKSBjb25zdCB7IHJldHVybiBNUkk7IH0KKyAgICAvLy8gQH0KKworICAgIC8vLyBDcmVhdGUgYXMgbWFueSBuZXcgdmlydHVhbCByZWdpc3RlcnMgYXMgbmVlZGVkIGZvciB0aGUgbWFwcGluZyBvZiB0aGUgXHAKKyAgICAvLy8gT3BJZHgtdGggb3BlcmFuZC4KKyAgICAvLy8gVGhlIG51bWJlciBvZiByZWdpc3RlcnMgaXMgZGV0ZXJtaW5lZCBieSB0aGUgbnVtYmVyIG9mIGJyZWFrZG93biBmb3IgdGhlCisgICAgLy8vIHJlbGF0ZWQgb3BlcmFuZCBpbiB0aGUgaW5zdHJ1Y3Rpb24gbWFwcGluZy4KKyAgICAvLy8gVGhlIHR5cGUgb2YgdGhlIG5ldyByZWdpc3RlcnMgaXMgYSBwbGFpbiBzY2FsYXIgb2YgdGhlIHJpZ2h0IHNpemUuCisgICAgLy8vIFRoZSBwcm9wZXIgdHlwZSBpcyBleHBlY3RlZCB0byBiZSBzZXQgd2hlbiB0aGUgbWFwcGluZyBpcyBhcHBsaWVkIHRvCisgICAgLy8vIHRoZSBpbnN0cnVjdGlvbihzKSB0aGF0IHJlYWxpemVzIHRoZSBtYXBwaW5nLgorICAgIC8vLworICAgIC8vLyBccHJlIGdldE1JKCkuZ2V0T3BlcmFuZChPcElkeCkuaXNSZWcoKQorICAgIC8vLworICAgIC8vLyBccG9zdCBBbGwgdGhlIHBhcnRpYWwgbWFwcGluZyBvZiB0aGUgXHAgT3BJZHgtdGggb3BlcmFuZCBoYXZlIGJlZW4KKyAgICAvLy8gYXNzaWduZWQgYSBuZXcgdmlydHVhbCByZWdpc3Rlci4KKyAgICB2b2lkIGNyZWF0ZVZSZWdzKHVuc2lnbmVkIE9wSWR4KTsKKworICAgIC8vLyBTZXQgdGhlIHZpcnR1YWwgcmVnaXN0ZXIgb2YgdGhlIFxwIFBhcnRpYWxNYXBJZHgtdGggcGFydGlhbCBtYXBwaW5nIG9mCisgICAgLy8vIHRoZSBPcElkeC10aCBvcGVyYW5kIHRvIFxwIE5ld1ZSZWcuCisgICAgLy8vCisgICAgLy8vIFxwcmUgZ2V0TUkoKS5nZXRPcGVyYW5kKE9wSWR4KS5pc1JlZygpCisgICAgLy8vIFxwcmUgZ2V0SW5zdHJNYXBwaW5nKCkuZ2V0T3BlcmFuZE1hcHBpbmcoT3BJZHgpLkJyZWFrRG93bi5zaXplKCkgPgorICAgIC8vLyBQYXJ0aWFsTWFwSWR4CisgICAgLy8vIFxwcmUgTmV3UmVnICE9IDAKKyAgICAvLy8KKyAgICAvLy8gXHBvc3QgdGhlIFxwIFBhcnRpYWxNYXBJZHgtdGggcmVnaXN0ZXIgb2YgdGhlIHZhbHVlIG1hcHBpbmcgb2YgdGhlIFxwCisgICAgLy8vIE9wSWR4LXRoIG9wZXJhbmQgaGFzIGJlZW4gc2V0LgorICAgIHZvaWQgc2V0VlJlZ3ModW5zaWduZWQgT3BJZHgsIHVuc2lnbmVkIFBhcnRpYWxNYXBJZHgsIHVuc2lnbmVkIE5ld1ZSZWcpOworCisgICAgLy8vIEdldCBhbGwgdGhlIHZpcnR1YWwgcmVnaXN0ZXJzIHJlcXVpcmVkIHRvIG1hcCB0aGUgXHAgT3BJZHgtdGggb3BlcmFuZCBvZgorICAgIC8vLyB0aGUgaW5zdHJ1Y3Rpb24uCisgICAgLy8vCisgICAgLy8vIFRoaXMgcmV0dXJuIGFuIGVtcHR5IHJhbmdlIHdoZW4gY3JlYXRlVlJlZ3Mgb3Igc2V0VlJlZ3MgaGFzIG5vdCBiZWVuCisgICAgLy8vIGNhbGxlZC4KKyAgICAvLy8gVGhlIGl0ZXJhdG9yIG1heSBiZSBpbnZhbGlkYXRlZCBieSBhIGNhbGwgdG8gc2V0VlJlZ3Mgb3IgY3JlYXRlVlJlZ3MuCisgICAgLy8vCisgICAgLy8vIFdoZW4gXHAgRm9yRGVidWcgaXMgdHJ1ZSwgd2Ugd2lsbCBub3QgY2hlY2sgdGhhdCB0aGUgbGlzdCBvZiBuZXcgdmlydHVhbAorICAgIC8vLyByZWdpc3RlcnMgZG9lcyBub3QgY29udGFpbiB1bmluaXRpYWxpemVkIHZhbHVlcy4KKyAgICAvLy8KKyAgICAvLy8gXHByZSBnZXRNSSgpLmdldE9wZXJhbmQoT3BJZHgpLmlzUmVnKCkKKyAgICAvLy8gXHByZSBGb3JEZWJ1ZyB8fCBBbGwgcGFydGlhbCBtYXBwaW5ncyBoYXZlIGJlZW4gc2V0IGEgcmVnaXN0ZXIKKyAgICBpdGVyYXRvcl9yYW5nZTxTbWFsbFZlY3RvckltcGw8dW5zaWduZWQ+Ojpjb25zdF9pdGVyYXRvcj4KKyAgICBnZXRWUmVncyh1bnNpZ25lZCBPcElkeCwgYm9vbCBGb3JEZWJ1ZyA9IGZhbHNlKSBjb25zdDsKKworICAgIC8vLyBQcmludCB0aGlzIG9wZXJhbmRzIG1hcHBlciBvbiBkYmdzKCkgc3RyZWFtLgorICAgIHZvaWQgZHVtcCgpIGNvbnN0OworCisgICAgLy8vIFByaW50IHRoaXMgb3BlcmFuZHMgbWFwcGVyIG9uIFxwIE9TIHN0cmVhbS4KKyAgICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUywgYm9vbCBGb3JEZWJ1ZyA9IGZhbHNlKSBjb25zdDsKKyAgfTsKKworcHJvdGVjdGVkOgorICAvLy8gSG9sZCB0aGUgc2V0IG9mIHN1cHBvcnRlZCByZWdpc3RlciBiYW5rcy4KKyAgUmVnaXN0ZXJCYW5rICoqUmVnQmFua3M7CisKKyAgLy8vIFRvdGFsIG51bWJlciBvZiByZWdpc3RlciBiYW5rcy4KKyAgdW5zaWduZWQgTnVtUmVnQmFua3M7CisKKyAgLy8vIEtlZXAgZHluYW1pY2FsbHkgYWxsb2NhdGVkIFBhcnRpYWxNYXBwaW5nIGluIGEgc2VwYXJhdGUgbWFwLgorICAvLy8gVGhpcyBzaG91bGRuJ3QgYmUgbmVlZGVkIHdoZW4gZXZlcnl0aGluZyBnZXRzIFRhYmxlR2VuJ2VkLgorICBtdXRhYmxlIERlbnNlTWFwPHVuc2lnbmVkLCBzdGQ6OnVuaXF1ZV9wdHI8Y29uc3QgUGFydGlhbE1hcHBpbmc+PgorICAgICAgTWFwT2ZQYXJ0aWFsTWFwcGluZ3M7CisKKyAgLy8vIEtlZXAgZHluYW1pY2FsbHkgYWxsb2NhdGVkIFZhbHVlTWFwcGluZyBpbiBhIHNlcGFyYXRlIG1hcC4KKyAgLy8vIFRoaXMgc2hvdWxkbid0IGJlIG5lZWRlZCB3aGVuIGV2ZXJ5dGhpbmcgZ2V0cyBUYWJsZUdlbidlZC4KKyAgbXV0YWJsZSBEZW5zZU1hcDx1bnNpZ25lZCwgc3RkOjp1bmlxdWVfcHRyPGNvbnN0IFZhbHVlTWFwcGluZz4+CisgICAgICBNYXBPZlZhbHVlTWFwcGluZ3M7CisKKyAgLy8vIEtlZXAgZHluYW1pY2FsbHkgYWxsb2NhdGVkIGFycmF5IG9mIFZhbHVlTWFwcGluZyBpbiBhIHNlcGFyYXRlIG1hcC4KKyAgLy8vIFRoaXMgc2hvdWxkbid0IGJlIG5lZWRlZCB3aGVuIGV2ZXJ5dGhpbmcgZ2V0cyBUYWJsZUdlbidlZC4KKyAgbXV0YWJsZSBEZW5zZU1hcDx1bnNpZ25lZCwgc3RkOjp1bmlxdWVfcHRyPFZhbHVlTWFwcGluZ1tdPj4KKyAgICAgIE1hcE9mT3BlcmFuZHNNYXBwaW5nczsKKworICAvLy8gS2VlcCBkeW5hbWljYWxseSBhbGxvY2F0ZWQgSW5zdHJ1Y3Rpb25NYXBwaW5nIGluIGEgc2VwYXJhdGUgbWFwLgorICAvLy8gVGhpcyBzaG91bGRuJ3QgYmUgbmVlZGVkIHdoZW4gZXZlcnl0aGluZyBnZXRzIFRhYmxlR2VuJ2VkLgorICBtdXRhYmxlIERlbnNlTWFwPHVuc2lnbmVkLCBzdGQ6OnVuaXF1ZV9wdHI8Y29uc3QgSW5zdHJ1Y3Rpb25NYXBwaW5nPj4KKyAgICAgIE1hcE9mSW5zdHJ1Y3Rpb25NYXBwaW5nczsKKworICAvLy8gR2V0dGluZyB0aGUgbWluaW1hbCByZWdpc3RlciBjbGFzcyBvZiBhIHBoeXNyZWcgaXMgZXhwZW5zaXZlLgorICAvLy8gQ2FjaGUgdGhpcyBpbmZvcm1hdGlvbiBhcyB3ZSBnZXQgaXQuCisgIG11dGFibGUgRGVuc2VNYXA8dW5zaWduZWQsIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKj4gUGh5c1JlZ01pbmltYWxSQ3M7CisKKyAgLy8vIENyZWF0ZSBhIFJlZ2lzdGVyQmFua0luZm8gdGhhdCBjYW4gYWNjb21tb2RhdGUgdXAgdG8gXHAgTnVtUmVnQmFua3MKKyAgLy8vIFJlZ2lzdGVyQmFuayBpbnN0YW5jZXMuCisgIFJlZ2lzdGVyQmFua0luZm8oUmVnaXN0ZXJCYW5rICoqUmVnQmFua3MsIHVuc2lnbmVkIE51bVJlZ0JhbmtzKTsKKworICAvLy8gVGhpcyBjb25zdHJ1Y3RvciBpcyBtZWFuaW5nbGVzcy4KKyAgLy8vIEl0IGp1c3QgcHJvdmlkZXMgYSBkZWZhdWx0IGNvbnN0cnVjdG9yIHRoYXQgY2FuIGJlIHVzZWQgYXQgbGluayB0aW1lCisgIC8vLyB3aGVuIEdsb2JhbElTZWwgaXMgbm90IGJ1aWx0LgorICAvLy8gVGhhdCB3YXksIHRhcmdldHMgY2FuIHN0aWxsIGluaGVyaXQgZnJvbSB0aGlzIGNsYXNzIHdpdGhvdXQgZG9pbmcKKyAgLy8vIGNyYXp5IGd5bW5hc3RpYyB0byBhdm9pZCBsaW5rIHRpbWUgZmFpbHVyZXMuCisgIC8vLyBcbm90ZSBUaGF0IHdvcmtzIGJlY2F1c2UgdGhlIGNvbnN0cnVjdG9yIGlzIGlubGluZWQuCisgIFJlZ2lzdGVyQmFua0luZm8oKSB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgiVGhpcyBjb25zdHJ1Y3RvciBzaG91bGQgbm90IGJlIGV4ZWN1dGVkIik7CisgIH0KKworICAvLy8gR2V0IHRoZSByZWdpc3RlciBiYW5rIGlkZW50aWZpZWQgYnkgXHAgSUQuCisgIFJlZ2lzdGVyQmFuayAmZ2V0UmVnQmFuayh1bnNpZ25lZCBJRCkgeworICAgIGFzc2VydChJRCA8IGdldE51bVJlZ0JhbmtzKCkgJiYgIkFjY2Vzc2luZyBhbiB1bmtub3duIHJlZ2lzdGVyIGJhbmsiKTsKKyAgICByZXR1cm4gKlJlZ0JhbmtzW0lEXTsKKyAgfQorCisgIC8vLyBHZXQgdGhlIE1pbmltYWxQaHlzUmVnQ2xhc3MgZm9yIFJlZy4KKyAgLy8vIFxwcmUgUmVnIGlzIGEgcGh5c2ljYWwgcmVnaXN0ZXIuCisgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgJgorICBnZXRNaW5pbWFsUGh5c1JlZ0NsYXNzKHVuc2lnbmVkIFJlZywgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICZUUkkpIGNvbnN0OworCisgIC8vLyBUcnkgdG8gZ2V0IHRoZSBtYXBwaW5nIG9mIFxwIE1JLgorICAvLy8gU2VlIGdldEluc3RyTWFwcGluZyBmb3IgbW9yZSBkZXRhaWxzIG9uIHdoYXQgYSBtYXBwaW5nIHJlcHJlc2VudHMuCisgIC8vLworICAvLy8gVW5saWtlIGdldEluc3RyTWFwcGluZyB0aGUgcmV0dXJuZWQgSW5zdHJ1Y3Rpb25NYXBwaW5nIG1heSBiZSBpbnZhbGlkCisgIC8vLyAoaXNWYWxpZCgpID09IGZhbHNlKS4KKyAgLy8vIFRoaXMgbWVhbnMgdGhhdCB0aGUgdGFyZ2V0IGluZGVwZW5kZW50IGNvZGUgaXMgbm90IHNtYXJ0IGVub3VnaAorICAvLy8gdG8gZ2V0IHRoZSBtYXBwaW5nIG9mIFxwIE1JIGFuZCB0aHVzLCB0aGUgdGFyZ2V0IGhhcyB0byBwcm92aWRlIHRoZQorICAvLy8gaW5mb3JtYXRpb24gZm9yIFxwIE1JLgorICAvLy8KKyAgLy8vIFRoaXMgaW1wbGVtZW50YXRpb24gaXMgYWJsZSB0byBnZXQgdGhlIG1hcHBpbmcgb2Y6CisgIC8vLyAtIFRhcmdldCBzcGVjaWZpYyBpbnN0cnVjdGlvbnMgYnkgbG9va2luZyBhdCB0aGUgZW5jb2RpbmcgY29uc3RyYWludHMuCisgIC8vLyAtIEFueSBpbnN0cnVjdGlvbiBpZiBhbGwgdGhlIHJlZ2lzdGVyIG9wZXJhbmRzIGhhdmUgYWxyZWFkeSBiZWVuIGFzc2lnbmVkCisgIC8vLyAgIGEgcmVnaXN0ZXIsIGEgcmVnaXN0ZXIgY2xhc3MsIG9yIGEgcmVnaXN0ZXIgYmFuay4KKyAgLy8vIC0gQ29waWVzIGFuZCBwaGlzIGlmIGF0IGxlYXN0IG9uZSBvZiB0aGUgb3BlcmFuZHMgaGFzIGJlZW4gYXNzaWduZWQgYQorICAvLy8gICByZWdpc3RlciwgYSByZWdpc3RlciBjbGFzcywgb3IgYSByZWdpc3RlciBiYW5rLgorICAvLy8gSW4gb3RoZXIgd29yZHMsIHRoaXMgbWV0aG9kIHdpbGwgbGlrZWx5IGZhaWwgdG8gZmluZCBhIG1hcHBpbmcgZm9yCisgIC8vLyBhbnkgZ2VuZXJpYyBvcGNvZGUgdGhhdCBoYXMgbm90IGJlZW4gbG93ZXJlZCBieSB0YXJnZXQgc3BlY2lmaWMgY29kZS4KKyAgY29uc3QgSW5zdHJ1Y3Rpb25NYXBwaW5nICZnZXRJbnN0ck1hcHBpbmdJbXBsKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIGNvbnN0OworCisgIC8vLyBHZXQgdGhlIHVuaXF1ZWx5IGdlbmVyYXRlZCBQYXJ0aWFsTWFwcGluZyBmb3IgdGhlCisgIC8vLyBnaXZlbiBhcmd1bWVudHMuCisgIGNvbnN0IFBhcnRpYWxNYXBwaW5nICZnZXRQYXJ0aWFsTWFwcGluZyh1bnNpZ25lZCBTdGFydElkeCwgdW5zaWduZWQgTGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVnaXN0ZXJCYW5rICZSZWdCYW5rKSBjb25zdDsKKworICAvLy8gXG5hbWUgTWV0aG9kcyB0byBnZXQgYSB1bmlxdWVseSBnZW5lcmF0ZWQgVmFsdWVNYXBwaW5nLgorICAvLy8gQHsKKworICAvLy8gVGhlIG1vc3QgY29tbW9uIFZhbHVlTWFwcGluZyBjb25zaXN0cyBvZiBhIHNpbmdsZSBQYXJ0aWFsTWFwcGluZy4KKyAgLy8vIEZlYXR1cmUgYSBtZXRob2QgZm9yIHRoYXQuCisgIGNvbnN0IFZhbHVlTWFwcGluZyAmZ2V0VmFsdWVNYXBwaW5nKHVuc2lnbmVkIFN0YXJ0SWR4LCB1bnNpZ25lZCBMZW5ndGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlZ2lzdGVyQmFuayAmUmVnQmFuaykgY29uc3Q7CisKKyAgLy8vIEdldCB0aGUgVmFsdWVNYXBwaW5nIGZvciB0aGUgZ2l2ZW4gYXJndW1lbnRzLgorICBjb25zdCBWYWx1ZU1hcHBpbmcgJmdldFZhbHVlTWFwcGluZyhjb25zdCBQYXJ0aWFsTWFwcGluZyAqQnJlYWtEb3duLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBOdW1CcmVha0Rvd25zKSBjb25zdDsKKyAgLy8vIEB9CisKKyAgLy8vIFxuYW1lIE1ldGhvZHMgdG8gZ2V0IGEgdW5pcXVlbHkgZ2VuZXJhdGVkIGFycmF5IG9mIFZhbHVlTWFwcGluZy4KKyAgLy8vIEB7CisKKyAgLy8vIEdldCB0aGUgdW5pcXVlbHkgZ2VuZXJhdGVkIGFycmF5IG9mIFZhbHVlTWFwcGluZyBmb3IgdGhlCisgIC8vLyBlbGVtZW50cyBvZiBiZXR3ZWVuIFxwIEJlZ2luIGFuZCBccCBFbmQuCisgIC8vLworICAvLy8gRWxlbWVudHMgdGhhdCBhcmUgbnVsbHB0ciB3aWxsIGJlIHJlcGxhY2VkIGJ5CisgIC8vLyBpbnZhbGlkIFZhbHVlTWFwcGluZyAoVmFsdWVNYXBwaW5nOjppc1ZhbGlkID09IGZhbHNlKS4KKyAgLy8vCisgIC8vLyBccHJlIFRoZSBwb2ludGVycyBvbiBWYWx1ZU1hcHBpbmcgYmV0d2VlbiBccCBCZWdpbiBhbmQgXHAgRW5kCisgIC8vLyBtdXN0IHVuaXF1ZWx5IGlkZW50aWZ5IGEgVmFsdWVNYXBwaW5nLiBPdGhlcndpc2UsIHRoZXJlIGlzIG5vCisgIC8vLyBndWFyYW50ZWUgdGhhdCB0aGUgcmV0dXJuIGluc3RhbmNlIHdpbGwgYmUgdW5pcXVlLCBpLmUuLCBhbm90aGVyCisgIC8vLyBPcGVyYW5kc01hcHBpbmcgY291bGQgaGF2ZSB0aGUgc2FtZSBjb250ZW50LgorICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcmF0b3I+CisgIGNvbnN0IFZhbHVlTWFwcGluZyAqZ2V0T3BlcmFuZHNNYXBwaW5nKEl0ZXJhdG9yIEJlZ2luLCBJdGVyYXRvciBFbmQpIGNvbnN0OworCisgIC8vLyBHZXQgdGhlIHVuaXF1ZWx5IGdlbmVyYXRlZCBhcnJheSBvZiBWYWx1ZU1hcHBpbmcgZm9yIHRoZQorICAvLy8gZWxlbWVudHMgb2YgXHAgT3Bkc01hcHBpbmcuCisgIC8vLworICAvLy8gRWxlbWVudHMgb2YgXHAgT3Bkc01hcHBpbmcgdGhhdCBhcmUgbnVsbHB0ciB3aWxsIGJlIHJlcGxhY2VkIGJ5CisgIC8vLyBpbnZhbGlkIFZhbHVlTWFwcGluZyAoVmFsdWVNYXBwaW5nOjppc1ZhbGlkID09IGZhbHNlKS4KKyAgY29uc3QgVmFsdWVNYXBwaW5nICpnZXRPcGVyYW5kc01hcHBpbmcoCisgICAgICBjb25zdCBTbWFsbFZlY3RvckltcGw8Y29uc3QgVmFsdWVNYXBwaW5nICo+ICZPcGRzTWFwcGluZykgY29uc3Q7CisKKyAgLy8vIEdldCB0aGUgdW5pcXVlbHkgZ2VuZXJhdGVkIGFycmF5IG9mIFZhbHVlTWFwcGluZyBmb3IgdGhlCisgIC8vLyBnaXZlbiBhcmd1bWVudHMuCisgIC8vLworICAvLy8gQXJndW1lbnRzIHRoYXQgYXJlIG51bGxwdHIgd2lsbCBiZSByZXBsYWNlZCBieSBpbnZhbGlkCisgIC8vLyBWYWx1ZU1hcHBpbmcgKFZhbHVlTWFwcGluZzo6aXNWYWxpZCA9PSBmYWxzZSkuCisgIGNvbnN0IFZhbHVlTWFwcGluZyAqZ2V0T3BlcmFuZHNNYXBwaW5nKAorICAgICAgc3RkOjppbml0aWFsaXplcl9saXN0PGNvbnN0IFZhbHVlTWFwcGluZyAqPiBPcGRzTWFwcGluZykgY29uc3Q7CisgIC8vLyBAfQorCisgIC8vLyBcbmFtZSBNZXRob2RzIHRvIGdldCBhIHVuaXF1ZWx5IGdlbmVyYXRlZCBJbnN0cnVjdGlvbk1hcHBpbmcuCisgIC8vLyBAeworCitwcml2YXRlOgorICAvLy8gTWV0aG9kIHRvIGdldCBhIHVuaXF1ZWx5IGdlbmVyYXRlZCBJbnN0cnVjdGlvbk1hcHBpbmcuCisgIGNvbnN0IEluc3RydWN0aW9uTWFwcGluZyAmCisgIGdldEluc3RydWN0aW9uTWFwcGluZ0ltcGwoYm9vbCBJc0ludmFsaWQsIHVuc2lnbmVkIElEID0gSW52YWxpZE1hcHBpbmdJRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBDb3N0ID0gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBWYWx1ZU1hcHBpbmcgKk9wZXJhbmRzTWFwcGluZyA9IG51bGxwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgTnVtT3BlcmFuZHMgPSAwKSBjb25zdDsKKworcHVibGljOgorICAvLy8gTWV0aG9kIHRvIGdldCBhIHVuaXF1ZWx5IGdlbmVyYXRlZCBJbnN0cnVjdGlvbk1hcHBpbmcuCisgIGNvbnN0IEluc3RydWN0aW9uTWFwcGluZyAmCisgIGdldEluc3RydWN0aW9uTWFwcGluZyh1bnNpZ25lZCBJRCwgdW5zaWduZWQgQ29zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFZhbHVlTWFwcGluZyAqT3BlcmFuZHNNYXBwaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgTnVtT3BlcmFuZHMpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0SW5zdHJ1Y3Rpb25NYXBwaW5nSW1wbCgvKklzSW52YWxpZCovIGZhbHNlLCBJRCwgQ29zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVyYW5kc01hcHBpbmcsIE51bU9wZXJhbmRzKTsKKyAgfQorCisgIC8vLyBNZXRob2QgdG8gZ2V0IGEgdW5pcXVlbHkgZ2VuZXJhdGVkIGludmFsaWQgSW5zdHJ1Y3Rpb25NYXBwaW5nLgorICBjb25zdCBJbnN0cnVjdGlvbk1hcHBpbmcgJmdldEludmFsaWRJbnN0cnVjdGlvbk1hcHBpbmcoKSBjb25zdCB7CisgICAgcmV0dXJuIGdldEluc3RydWN0aW9uTWFwcGluZ0ltcGwoLypJc0ludmFsaWQqLyB0cnVlKTsKKyAgfQorICAvLy8gQH0KKworICAvLy8gR2V0IHRoZSByZWdpc3RlciBiYW5rIGZvciB0aGUgXHAgT3BJZHgtdGggb3BlcmFuZCBvZiBccCBNSSBmb3JtCisgIC8vLyB0aGUgZW5jb2RpbmcgY29uc3RyYWludHMsIGlmIGFueS4KKyAgLy8vCisgIC8vLyBccmV0dXJuIEEgcmVnaXN0ZXIgYmFuayB0aGF0IGNvdmVycyB0aGUgcmVnaXN0ZXIgY2xhc3Mgb2YgdGhlCisgIC8vLyByZWxhdGVkIGVuY29kaW5nIGNvbnN0cmFpbnRzIG9yIG51bGxwdHIgaWYgXHAgTUkgZGlkIG5vdCBwcm92aWRlCisgIC8vLyBlbm91Z2ggaW5mb3JtYXRpb24gdG8gZGVkdWNlIGl0LgorICBjb25zdCBSZWdpc3RlckJhbmsgKgorICBnZXRSZWdCYW5rRnJvbUNvbnN0cmFpbnRzKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUksIHVuc2lnbmVkIE9wSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldEluc3RySW5mbyAmVElJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAmVFJJKSBjb25zdDsKKworICAvLy8gSGVscGVyIG1ldGhvZCB0byBhcHBseSBzb21ldGhpbmcgdGhhdCBpcyBsaWtlIHRoZSBkZWZhdWx0IG1hcHBpbmcuCisgIC8vLyBCYXNpY2FsbHksIHRoYXQgbWVhbnMgdGhhdCBccCBPcGRNYXBwZXIuZ2V0TUkoKSBpcyBsZWZ0IHVudG91Y2hlZAorICAvLy8gYXNpZGUgZnJvbSB0aGUgcmVhc3NpZ25tZW50IG9mIHRoZSByZWdpc3RlciBvcGVyYW5kIHRoYXQgaGF2ZSBiZWVuCisgIC8vLyByZW1hcHBlZC4KKyAgLy8vCisgIC8vLyBUaGUgdHlwZSBvZiBhbGwgdGhlIG5ldyByZWdpc3RlcnMgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZCBieSB0aGUKKyAgLy8vIG1hcHBlciBhcmUgcHJvcGVybHkgcmVtYXBwZWQgdG8gdGhlIHR5cGUgb2YgdGhlIG9yaWdpbmFsIHJlZ2lzdGVycworICAvLy8gdGhleSByZXBsYWNlLiBJbiBvdGhlciB3b3JkcywgdGhlIHNlbWFudGljIG9mIHRoZSBpbnN0cnVjdGlvbiBkb2VzCisgIC8vLyBub3QgY2hhbmdlLCBvbmx5IHRoZSByZWdpc3RlciBiYW5rcy4KKyAgLy8vCisgIC8vLyBJZiB0aGUgbWFwcGluZyBvZiBvbmUgb2YgdGhlIG9wZXJhbmQgc3BhbnMgc2V2ZXJhbCByZWdpc3RlcnMsIHRoaXMKKyAgLy8vIG1ldGhvZCB3aWxsIGFib3J0IGFzIHRoaXMgaXMgbm90IGxpa2UgYSBkZWZhdWx0IG1hcHBpbmcgYW55bW9yZS4KKyAgLy8vCisgIC8vLyBccHJlIEZvciBPcElkeCBpbiB7MC4uXHAgT3BkTWFwcGVyLmdldE1JKCkuZ2V0TnVtT3BlcmFuZHMoKSkKKyAgLy8vICAgICAgICB0aGUgcmFuZ2UgT3BkTWFwcGVyLmdldFZSZWdzKE9wSWR4KSBpcyBlbXB0eSBvciBvZiBzaXplIDEuCisgIHN0YXRpYyB2b2lkIGFwcGx5RGVmYXVsdE1hcHBpbmcoY29uc3QgT3BlcmFuZHNNYXBwZXIgJk9wZE1hcHBlcik7CisKKyAgLy8vIFNlZSA6OmFwcGx5TWFwcGluZy4KKyAgdmlydHVhbCB2b2lkIGFwcGx5TWFwcGluZ0ltcGwoY29uc3QgT3BlcmFuZHNNYXBwZXIgJk9wZE1hcHBlcikgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIlRoZSB0YXJnZXQgaGFzIHRvIGltcGxlbWVudCB0aGF0IHBhcnQiKTsKKyAgfQorCitwdWJsaWM6CisgIHZpcnR1YWwgflJlZ2lzdGVyQmFua0luZm8oKSA9IGRlZmF1bHQ7CisKKyAgLy8vIEdldCB0aGUgcmVnaXN0ZXIgYmFuayBpZGVudGlmaWVkIGJ5IFxwIElELgorICBjb25zdCBSZWdpc3RlckJhbmsgJmdldFJlZ0JhbmsodW5zaWduZWQgSUQpIGNvbnN0IHsKKyAgICByZXR1cm4gY29uc3RfY2FzdDxSZWdpc3RlckJhbmtJbmZvICo+KHRoaXMpLT5nZXRSZWdCYW5rKElEKTsKKyAgfQorCisgIC8vLyBHZXQgdGhlIHJlZ2lzdGVyIGJhbmsgb2YgXHAgUmVnLgorICAvLy8gSWYgUmVnIGhhcyBub3QgYmVlbiBhc3NpZ25lZCBhIHJlZ2lzdGVyLCBhIHJlZ2lzdGVyIGNsYXNzLAorICAvLy8gb3IgYSByZWdpc3RlciBiYW5rLCB0aGVuIHRoaXMgcmV0dXJucyBudWxscHRyLgorICAvLy8KKyAgLy8vIFxwcmUgUmVnICE9IDAgKE5vUmVnaXN0ZXIpCisgIGNvbnN0IFJlZ2lzdGVyQmFuayAqZ2V0UmVnQmFuayh1bnNpZ25lZCBSZWcsIGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAmVFJJKSBjb25zdDsKKworICAvLy8gR2V0IHRoZSB0b3RhbCBudW1iZXIgb2YgcmVnaXN0ZXIgYmFua3MuCisgIHVuc2lnbmVkIGdldE51bVJlZ0JhbmtzKCkgY29uc3QgeyByZXR1cm4gTnVtUmVnQmFua3M7IH0KKworICAvLy8gR2V0IGEgcmVnaXN0ZXIgYmFuayB0aGF0IGNvdmVycyBccCBSQy4KKyAgLy8vCisgIC8vLyBccHJlIFxwIFJDIGlzIGEgdXNlci1kZWZpbmVkIHJlZ2lzdGVyIGNsYXNzIChhcyBvcHBvc2VkIGFzIG9uZQorICAvLy8gZ2VuZXJhdGVkIGJ5IFRhYmxlR2VuKS4KKyAgLy8vCisgIC8vLyBcbm90ZSBUaGUgbWFwcGluZyBSQyAtPiBSZWdCYW5rIGNvdWxkIGJlIGJ1aWx0IHdoaWxlIGFkZGluZyB0aGUKKyAgLy8vIGNvdmVyYWdlIGZvciB0aGUgcmVnaXN0ZXIgYmFua3MuIEhvd2V2ZXIsIHdlIGRvIG5vdCBkbyBpdCwgYmVjYXVzZSwKKyAgLy8vIGF0IGxlYXN0IGZvciBub3csIHdlIG9ubHkgbmVlZCB0aGlzIGluZm9ybWF0aW9uIGZvciByZWdpc3RlciBjbGFzc2VzCisgIC8vLyB0aGF0IGFyZSB1c2VkIGluIHRoZSBkZXNjcmlwdGlvbiBvZiBpbnN0cnVjdGlvbi4gSW4gb3RoZXIgd29yZHMsCisgIC8vLyB0aGVyZSBhcmUganVzdCBhIGhhbmRmdWwgb2YgdGhlbSBhbmQgd2UgZG8gbm90IHdhbnQgdG8gd2FzdGUgc3BhY2UuCisgIC8vLworICAvLy8gXHRvZG8gVGhpcyBzaG91bGQgYmUgVGFibGVHZW4nZWQuCisgIHZpcnR1YWwgY29uc3QgUmVnaXN0ZXJCYW5rICYKKyAgZ2V0UmVnQmFua0Zyb21SZWdDbGFzcyhjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICZSQykgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIlRoZSB0YXJnZXQgbXVzdCBvdmVycmlkZSB0aGlzIG1ldGhvZCIpOworICB9CisKKyAgLy8vIEdldCB0aGUgY29zdCBvZiBhIGNvcHkgZnJvbSBccCBCIHRvIFxwIEEsIG9yIHB1dCBkaWZmZXJlbnRseSwKKyAgLy8vIGdldCB0aGUgY29zdCBvZiBBID0gQ09QWSBCLiBTaW5jZSByZWdpc3RlciBiYW5rcyBtYXkgY292ZXIKKyAgLy8vIGRpZmZlcmVudCBzaXplLCBccCBTaXplIHNwZWNpZmllcyB3aGF0IHdpbGwgYmUgdGhlIHNpemUgaW4gYml0cworICAvLy8gdGhhdCB3aWxsIGJlIGNvcGllZCBhcm91bmQuCisgIC8vLworICAvLy8gXG5vdGUgU2luY2UgdGhpcyBpcyBhIGNvcHksIGJvdGggcmVnaXN0ZXJzIGhhdmUgdGhlIHNhbWUgc2l6ZS4KKyAgdmlydHVhbCB1bnNpZ25lZCBjb3B5Q29zdChjb25zdCBSZWdpc3RlckJhbmsgJkEsIGNvbnN0IFJlZ2lzdGVyQmFuayAmQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBTaXplKSBjb25zdCB7CisgICAgLy8gT3B0aW1pc3RpY2FsbHkgYXNzdW1lIHRoYXQgY29waWVzIGFyZSBjb2FsZXNjZWQuIEkuZS4sIHdoZW4KKyAgICAvLyB0aGV5IGFyZSBvbiB0aGUgc2FtZSBiYW5rLCB0aGV5IGFyZSBmcmVlLgorICAgIC8vIE90aGVyd2lzZSBhc3N1bWUgYSBub24temVybyBjb3N0IG9mIDEuIFRoZSB0YXJnZXRzIGFyZSBzdXBwb3NlZAorICAgIC8vIHRvIG92ZXJyaWRlIHRoYXQgcHJvcGVybHkgYW55d2F5IGlmIHRoZXkgY2FyZS4KKyAgICByZXR1cm4gJkEgIT0gJkI7CisgIH0KKworICAvLy8gQ29uc3RyYWluIHRoZSAocG9zc2libHkgZ2VuZXJpYykgdmlydHVhbCByZWdpc3RlciBccCBSZWcgdG8gXHAgUkMuCisgIC8vLworICAvLy8gXHByZSBccCBSZWcgaXMgYSB2aXJ0dWFsIHJlZ2lzdGVyIHRoYXQgZWl0aGVyIGhhcyBhIGJhbmsgb3IgYSBjbGFzcy4KKyAgLy8vIFxyZXR1cm5zIFRoZSBjb25zdHJhaW5lZCByZWdpc3RlciBjbGFzcywgb3IgbnVsbHB0ciBpZiB0aGVyZSBpcyBub25lLgorICAvLy8gXG5vdGUgVGhpcyBpcyBhIGdlbmVyaWMgdmFyaWFudCBvZiBNYWNoaW5lUmVnaXN0ZXJJbmZvOjpjb25zdHJhaW5SZWdDbGFzcworICAvLy8gXG5vdGUgVXNlIE1hY2hpbmVSZWdpc3RlckluZm86OmNvbnN0cmFpblJlZ0F0dHJzIGluc3RlYWQgZm9yIGFueSBub24taXNlbAorICAvLy8gcHVycG9zZSwgaW5jbHVkaW5nIG5vbi1zZWxlY3QgcGFzc2VzIG9mIEdsb2JhbElTZWwKKyAgc3RhdGljIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKgorICBjb25zdHJhaW5HZW5lcmljUmVnaXN0ZXIodW5zaWduZWQgUmVnLCBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICZSQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSk7CisKKyAgLy8vIElkZW50aWZpZXIgdXNlZCB3aGVuIHRoZSByZWxhdGVkIGluc3RydWN0aW9uIG1hcHBpbmcgaW5zdGFuY2UKKyAgLy8vIGlzIGdlbmVyYXRlZCBieSB0YXJnZXQgaW5kZXBlbmRlbnQgY29kZS4KKyAgLy8vIE1ha2Ugc3VyZSBub3QgdG8gdXNlIHRoYXQgaWRlbnRpZmllciB0byBhdm9pZCBwb3NzaWJsZSBjb2xsaXNpb24uCisgIHN0YXRpYyBjb25zdCB1bnNpZ25lZCBEZWZhdWx0TWFwcGluZ0lEOworCisgIC8vLyBJZGVudGlmaWVyIHVzZWQgd2hlbiB0aGUgcmVsYXRlZCBpbnN0cnVjdGlvbiBtYXBwaW5nIGluc3RhbmNlCisgIC8vLyBpcyBnZW5lcmF0ZWQgYnkgdGhlIGRlZmF1bHQgY29uc3RydWN0b3IuCisgIC8vLyBNYWtlIHN1cmUgbm90IHRvIHVzZSB0aGF0IGlkZW50aWZpZXIuCisgIHN0YXRpYyBjb25zdCB1bnNpZ25lZCBJbnZhbGlkTWFwcGluZ0lEOworCisgIC8vLyBHZXQgdGhlIG1hcHBpbmcgb2YgdGhlIGRpZmZlcmVudCBvcGVyYW5kcyBvZiBccCBNSQorICAvLy8gb24gdGhlIHJlZ2lzdGVyIGJhbmsuCisgIC8vLyBUaGlzIG1hcHBpbmcgc2hvdWxkIGJlIHRoZSBkaXJlY3QgdHJhbnNsYXRpb24gb2YgXHAgTUkuCisgIC8vLyBJbiBvdGhlciB3b3Jkcywgd2hlbiBccCBNSSBpcyBtYXBwZWQgd2l0aCB0aGUgcmV0dXJuZWQgbWFwcGluZywKKyAgLy8vIG9ubHkgdGhlIHJlZ2lzdGVyIGJhbmtzIG9mIHRoZSBvcGVyYW5kcyBvZiBccCBNSSBuZWVkIHRvIGJlIHVwZGF0ZWQuCisgIC8vLyBJbiBwYXJ0aWN1bGFyLCBuZWl0aGVyIHRoZSBvcGNvZGUgbm9yIHRoZSB0eXBlIG9mIFxwIE1JIG5lZWRzIHRvIGJlCisgIC8vLyB1cGRhdGVkIGZvciB0aGlzIGRpcmVjdCBtYXBwaW5nLgorICAvLy8KKyAgLy8vIFRoZSB0YXJnZXQgaW5kZXBlbmRlbnQgaW1wbGVtZW50YXRpb24gZ2l2ZXMgYSBtYXBwaW5nIGJhc2VkIG9uCisgIC8vLyB0aGUgcmVnaXN0ZXIgY2xhc3NlcyBmb3IgdGhlIHRhcmdldCBzcGVjaWZpYyBvcGNvZGUuCisgIC8vLyBJdCB1c2VzIHRoZSBJRCBSZWdpc3RlckJhbmtJbmZvOjpEZWZhdWx0TWFwcGluZ0lEIGZvciB0aGF0IG1hcHBpbmcuCisgIC8vLyBNYWtlIHN1cmUgeW91IGRvIG5vdCB1c2UgdGhhdCBJRCBmb3IgdGhlIGFsdGVybmF0aXZlIG1hcHBpbmcKKyAgLy8vIGZvciBNSS4gU2VlIGdldEluc3RyQWx0ZXJuYXRpdmVNYXBwaW5ncyBmb3IgdGhlIGFsdGVybmF0aXZlCisgIC8vLyBtYXBwaW5ncy4KKyAgLy8vCisgIC8vLyBGb3IgaW5zdGFuY2UsIGlmIFxwIE1JIGlzIGEgdmVjdG9yIGFkZCwgdGhlIG1hcHBpbmcgc2hvdWxkCisgIC8vLyBub3QgYmUgYSBzY2FsYXJpemF0aW9uIG9mIHRoZSBhZGQuCisgIC8vLworICAvLy8gXHBvc3QgcmV0dXJuZWRWYWwudmVyaWZ5KE1JKS4KKyAgLy8vCisgIC8vLyBcbm90ZSBJZiByZXR1cm5lZFZhbCBkb2VzIG5vdCB2ZXJpZnkgTUksIHRoaXMgd291bGQgcHJvYmFibHkgbWVhbgorICAvLy8gdGhhdCB0aGUgdGFyZ2V0IGRvZXMgbm90IHN1cHBvcnQgdGhhdCBpbnN0cnVjdGlvbi4KKyAgdmlydHVhbCBjb25zdCBJbnN0cnVjdGlvbk1hcHBpbmcgJgorICBnZXRJbnN0ck1hcHBpbmcoY29uc3QgTWFjaGluZUluc3RyICZNSSkgY29uc3Q7CisKKyAgLy8vIEdldCB0aGUgYWx0ZXJuYXRpdmUgbWFwcGluZ3MgZm9yIFxwIE1JLgorICAvLy8gQWx0ZXJuYXRpdmUgaW4gdGhlIHNlbnNlIGRpZmZlcmVudCBmcm9tIGdldEluc3RyTWFwcGluZy4KKyAgdmlydHVhbCBJbnN0cnVjdGlvbk1hcHBpbmdzCisgIGdldEluc3RyQWx0ZXJuYXRpdmVNYXBwaW5ncyhjb25zdCBNYWNoaW5lSW5zdHIgJk1JKSBjb25zdDsKKworICAvLy8gR2V0IHRoZSBwb3NzaWJsZSBtYXBwaW5nIGZvciBccCBNSS4KKyAgLy8vIEEgbWFwcGluZyBkZWZpbmVzIHdoZXJlIHRoZSBkaWZmZXJlbnQgb3BlcmFuZHMgbWF5IGxpdmUgYW5kIGF0IHdoYXQgY29zdC4KKyAgLy8vIEZvciBpbnN0YW5jZSwgbGV0IHVzIGNvbnNpZGVyOgorICAvLy8gdjAoMTYpID0gR19BREQgPDIgeCBpOD4gdjEsIHYyCisgIC8vLyBUaGUgcG9zc2libGUgbWFwcGluZyBjb3VsZCBiZToKKyAgLy8vCisgIC8vLyB7LypJRCovVmVjdG9yQWRkLCAvKkNvc3QqLzEsIC8qdjAqL3soMHhGRkZGLCBWUFIpfSwgLyp2MSoveygweEZGRkYsIFZQUil9LAorICAvLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKnYyKi97KDB4RkZGRiwgVlBSKX19CisgIC8vLyB7LypJRCovU2NhbGFyQWRkeDIsIC8qQ29zdCovMiwgLyp2MCoveygweDAwRkYsIEdQUiksKDB4RkYwMCwgR1BSKX0sCisgIC8vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyp2MSoveygweDAwRkYsIEdQUiksKDB4RkYwMCwgR1BSKX0sCisgIC8vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyp2MioveygweDAwRkYsIEdQUiksKDB4RkYwMCwgR1BSKX19CisgIC8vLworICAvLy8gXG5vdGUgVGhlIGZpcnN0IGFsdGVybmF0aXZlIG9mIHRoZSByZXR1cm5lZCBtYXBwaW5nIHNob3VsZCBiZSB0aGUKKyAgLy8vIGRpcmVjdCB0cmFuc2xhdGlvbiBvZiBccCBNSSBjdXJyZW50IGZvcm0uCisgIC8vLworICAvLy8gXHBvc3QgIXJldHVybmVkVmFsLmVtcHR5KCkuCisgIEluc3RydWN0aW9uTWFwcGluZ3MgZ2V0SW5zdHJQb3NzaWJsZU1hcHBpbmdzKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIGNvbnN0OworCisgIC8vLyBBcHBseSBccCBPcGRNYXBwZXIuZ2V0SW5zdHJNYXBwaW5nKCkgdG8gXHAgT3BkTWFwcGVyLmdldE1JKCkuCisgIC8vLyBBZnRlciB0aGlzIGNhbGwgXHAgT3BkTWFwcGVyLmdldE1JKCkgbWF5IG5vdCBiZSB2YWxpZCBhbnltb3JlLgorICAvLy8gXHAgT3BkTWFwcGVyLmdldEluc3RyTWFwcGluZygpLmdldElEKCkgY2FycmllcyB0aGUgaW5mb3JtYXRpb24gb2YKKyAgLy8vIHdoYXQgaGFzIGJlZW4gY2hvc2VuIHRvIG1hcCBccCBPcGRNYXBwZXIuZ2V0TUkoKS4gVGhpcyBJRCBpcyBzZXQKKyAgLy8vIGJ5IHRoZSB2YXJpb3VzIGdldEluc3RyWFhYTWFwcGluZyBtZXRob2QuCisgIC8vLworICAvLy8gVGhlcmVmb3JlLCBnZXR0aW5nIHRoZSBtYXBwaW5nIGFuZCBhcHBseWluZyBpdCBzaG91bGQgYmUga2VwdCBpbgorICAvLy8gc3luYy4KKyAgdm9pZCBhcHBseU1hcHBpbmcoY29uc3QgT3BlcmFuZHNNYXBwZXIgJk9wZE1hcHBlcikgY29uc3QgeworICAgIC8vIFRoZSBvbmx5IG1hcHBpbmcgd2Uga25vdyBob3cgdG8gaGFuZGxlIGlzIHRoZSBkZWZhdWx0IG1hcHBpbmcuCisgICAgaWYgKE9wZE1hcHBlci5nZXRJbnN0ck1hcHBpbmcoKS5nZXRJRCgpID09IERlZmF1bHRNYXBwaW5nSUQpCisgICAgICByZXR1cm4gYXBwbHlEZWZhdWx0TWFwcGluZyhPcGRNYXBwZXIpOworICAgIC8vIEZvciBvdGhlciBtYXBwaW5nLCB0aGUgdGFyZ2V0IG5lZWRzIHRvIGRvIHRoZSByaWdodCB0aGluZy4KKyAgICAvLyBJZiB0aGF0IG1lYW5zIGNhbGxpbmcgYXBwbHlEZWZhdWx0TWFwcGluZywgZmluZSwgYnV0IHRoaXMKKyAgICAvLyBtdXN0IGJlIGV4cGxpY2l0bHkgc3RhdGVkLgorICAgIGFwcGx5TWFwcGluZ0ltcGwoT3BkTWFwcGVyKTsKKyAgfQorCisgIC8vLyBHZXQgdGhlIHNpemUgaW4gYml0cyBvZiBccCBSZWcuCisgIC8vLyBVdGlsaXR5IG1ldGhvZCB0byBnZXQgdGhlIHNpemUgb2YgYW55IHJlZ2lzdGVycy4gVW5saWtlCisgIC8vLyBNYWNoaW5lUmVnaXN0ZXJJbmZvOjpnZXRTaXplLCB0aGUgcmVnaXN0ZXIgZG9lcyBub3QgbmVlZCB0byBiZSBhCisgIC8vLyB2aXJ0dWFsIHJlZ2lzdGVyLgorICAvLy8KKyAgLy8vIFxwcmUgXHAgUmVnICE9IDAgKE5vUmVnaXN0ZXIpLgorICB1bnNpZ25lZCBnZXRTaXplSW5CaXRzKHVuc2lnbmVkIFJlZywgY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAmVFJJKSBjb25zdDsKKworICAvLy8gQ2hlY2sgdGhhdCBpbmZvcm1hdGlvbiBob2xkIGJ5IHRoaXMgaW5zdGFuY2UgbWFrZSBzZW5zZSBmb3IgdGhlCisgIC8vLyBnaXZlbiBccCBUUkkuCisgIC8vLworICAvLy8gXG5vdGUgVGhpcyBtZXRob2QgZG9lcyBub3QgY2hlY2sgYW55dGhpbmcgd2hlbiBhc3NlcnRpb25zIGFyZSBkaXNhYmxlZC4KKyAgLy8vCisgIC8vLyBccmV0dXJuIFRydWUgaXMgdGhlIGNoZWNrIHdhcyBzdWNjZXNzZnVsLgorICBib29sIHZlcmlmeShjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gJlRSSSkgY29uc3Q7Cit9OworCitpbmxpbmUgcmF3X29zdHJlYW0gJgorb3BlcmF0b3I8PChyYXdfb3N0cmVhbSAmT1MsCisgICAgICAgICAgIGNvbnN0IFJlZ2lzdGVyQmFua0luZm86OlBhcnRpYWxNYXBwaW5nICZQYXJ0TWFwcGluZykgeworICBQYXJ0TWFwcGluZy5wcmludChPUyk7CisgIHJldHVybiBPUzsKK30KKworaW5saW5lIHJhd19vc3RyZWFtICYKK29wZXJhdG9yPDwocmF3X29zdHJlYW0gJk9TLCBjb25zdCBSZWdpc3RlckJhbmtJbmZvOjpWYWx1ZU1hcHBpbmcgJlZhbE1hcHBpbmcpIHsKKyAgVmFsTWFwcGluZy5wcmludChPUyk7CisgIHJldHVybiBPUzsKK30KKworaW5saW5lIHJhd19vc3RyZWFtICYKK29wZXJhdG9yPDwocmF3X29zdHJlYW0gJk9TLAorICAgICAgICAgICBjb25zdCBSZWdpc3RlckJhbmtJbmZvOjpJbnN0cnVjdGlvbk1hcHBpbmcgJkluc3RyTWFwcGluZykgeworICBJbnN0ck1hcHBpbmcucHJpbnQoT1MpOworICByZXR1cm4gT1M7Cit9CisKK2lubGluZSByYXdfb3N0cmVhbSAmCitvcGVyYXRvcjw8KHJhd19vc3RyZWFtICZPUywgY29uc3QgUmVnaXN0ZXJCYW5rSW5mbzo6T3BlcmFuZHNNYXBwZXIgJk9wZE1hcHBlcikgeworICBPcGRNYXBwZXIucHJpbnQoT1MsIC8qRm9yRGVidWcqLyBmYWxzZSk7CisgIHJldHVybiBPUzsKK30KKworLy8vIEhhc2hpbmcgZnVuY3Rpb24gZm9yIFBhcnRpYWxNYXBwaW5nLgorLy8vIEl0IGlzIHJlcXVpcmVkIGZvciB0aGUgaGFzaGluZyBvZiBWYWx1ZU1hcHBpbmcuCitoYXNoX2NvZGUgaGFzaF92YWx1ZShjb25zdCBSZWdpc3RlckJhbmtJbmZvOjpQYXJ0aWFsTWFwcGluZyAmUGFydE1hcHBpbmcpOworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfUkVHSVNURVJCQU5LSU5GT19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9UeXBlcy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvVHlwZXMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YjIyZTM0Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvVHlwZXMuaApAQCAtMCwwICsxLDM0IEBACisvLz09PS0gbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvVHlwZXMuaCAtIFR5cGVzIHVzZWQgYnkgR0lTZWwgLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vCisvLy8gXGZpbGUKKy8vLyBUaGlzIGZpbGUgZGVzY3JpYmVzIGhpZ2ggbGV2ZWwgdHlwZXMgdGhhdCBhcmUgdXNlZCBieSBzZXZlcmFsIHBhc3NlcyBvcgorLy8vIEFQSXMgaW52b2x2ZWQgaW4gdGhlIEdsb2JhbElTZWwgcGlwZWxpbmUuCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX1RZUEVTX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfVFlQRVNfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VNYXAuaCIKKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBWYWx1ZTsKKworLy8vIE1hcCBhIHZhbHVlIHRvIGEgdmlydHVhbCByZWdpc3Rlci4KKy8vLyBGb3Igbm93LCB3ZSBjaG9zZSB0byBtYXAgYWdncmVnYXRlIHR5cGVzIHRvIG9uIHNpbmdsZSB2aXJ0dWFsCisvLy8gcmVnaXN0ZXIuIFRoaXMgbWlnaHQgYmUgcmV2aXNpdGVkIGlmIGl0IHR1cm5zIG91dCB0byBiZSBpbmVmZmljaWVudC4KKy8vLyBQUjI2MTYxIHRyYWNrcyB0aGF0LgorLy8vIE5vdGU6IFdlIG5lZWQgdG8gZXhwb3NlIHRoaXMgdHlwZSB0byB0aGUgdGFyZ2V0IGhvb2tzIGZvciB0aGluZyBsaWtlCisvLy8gQUJJIGxvd2VyaW5nIHRoYXQgd291bGQgYmUgdXNlZCBkdXJpbmcgSVJUcmFuc2xhdGlvbi4KK3VzaW5nIFZhbHVlVG9WUmVnID0gRGVuc2VNYXA8Y29uc3QgVmFsdWUgKiwgdW5zaWduZWQ+OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0dMT0JBTElTRUxfVFlQRVNfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvVXRpbHMuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL1V0aWxzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODM3MDM1ZgotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9HbG9iYWxJU2VsL1V0aWxzLmgKQEAgLTAsMCArMSwxMDYgQEAKKy8vPT0tLSBsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9VdGlscy5oIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSotIEMrKyAtKi09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8vIFxmaWxlIFRoaXMgZmlsZSBkZWNsYXJlcyB0aGUgQVBJIG9mIGhlbHBlciBmdW5jdGlvbnMgdXNlZCB0aHJvdWdob3V0IHRoZQorLy8vIEdsb2JhbElTZWwgcGlwZWxpbmUuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fR0xPQkFMSVNFTF9VVElMU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9HTE9CQUxJU0VMX1VUSUxTX0gKKworI2luY2x1ZGUgImxsdm0vQURUL1N0cmluZ1JlZi5oIgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIE1hY2hpbmVJbnN0cjsKK2NsYXNzIE1hY2hpbmVPcGVyYW5kOworY2xhc3MgTWFjaGluZU9wdGltaXphdGlvblJlbWFya0VtaXR0ZXI7CitjbGFzcyBNYWNoaW5lT3B0aW1pemF0aW9uUmVtYXJrTWlzc2VkOworY2xhc3MgTWFjaGluZVJlZ2lzdGVySW5mbzsKK2NsYXNzIE1DSW5zdHJEZXNjOworY2xhc3MgUmVnaXN0ZXJCYW5rSW5mbzsKK2NsYXNzIFRhcmdldEluc3RySW5mbzsKK2NsYXNzIFRhcmdldFBhc3NDb25maWc7CitjbGFzcyBUYXJnZXRSZWdpc3RlckluZm87CitjbGFzcyBUYXJnZXRSZWdpc3RlckNsYXNzOworY2xhc3MgVHdpbmU7CitjbGFzcyBDb25zdGFudEZQOworY2xhc3MgQVBGbG9hdDsKKworLy8vIFRyeSB0byBjb25zdHJhaW4gUmVnIHRvIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIgY2xhc3MuIElmIHRoaXMgZmFpbHMsCisvLy8gY3JlYXRlIGEgbmV3IHZpcnR1YWwgcmVnaXN0ZXIgaW4gdGhlIGNvcnJlY3QgY2xhc3MgYW5kIGluc2VydCBhIENPUFkgYmVmb3JlCisvLy8gXHAgSW5zZXJ0UHQuIFRoZSBkZWJ1ZyBsb2NhdGlvbiBvZiBccCBJbnNlcnRQdCBpcyB1c2VkIGZvciB0aGUgbmV3IGNvcHkuCisvLy8KKy8vLyBccmV0dXJuIFRoZSB2aXJ0dWFsIHJlZ2lzdGVyIGNvbnN0cmFpbmVkIHRvIHRoZSByaWdodCByZWdpc3RlciBjbGFzcy4KK3Vuc2lnbmVkIGNvbnN0cmFpblJlZ1RvQ2xhc3MoTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRJbnN0ckluZm8gJlRJSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVnaXN0ZXJCYW5rSW5mbyAmUkJJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSW5zdHIgJkluc2VydFB0LCB1bnNpZ25lZCBSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgJlJlZ0NsYXNzKTsKKworLy8vIFRyeSB0byBjb25zdHJhaW4gUmVnIHNvIHRoYXQgaXQgaXMgdXNhYmxlIGJ5IGFyZ3VtZW50IE9wSWR4IG9mIHRoZQorLy8vIHByb3ZpZGVkIE1DSW5zdHJEZXNjIFxwIElJLiBJZiB0aGlzIGZhaWxzLCBjcmVhdGUgYSBuZXcgdmlydHVhbAorLy8vIHJlZ2lzdGVyIGluIHRoZSBjb3JyZWN0IGNsYXNzIGFuZCBpbnNlcnQgYSBDT1BZIGJlZm9yZSBccCBJbnNlcnRQdC4KKy8vLyBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gY29uc3RyYWluUmVnVG9DbGFzcygpIHdpdGggUmVnQ2xhc3Mgb2J0YWluZWQgZnJvbSB0aGUKKy8vLyBNQ0luc3RyRGVzYy4gVGhlIGRlYnVnIGxvY2F0aW9uIG9mIFxwIEluc2VydFB0IGlzIHVzZWQgZm9yIHRoZSBuZXcgY29weS4KKy8vLworLy8vIFxyZXR1cm4gVGhlIHZpcnR1YWwgcmVnaXN0ZXIgY29uc3RyYWluZWQgdG8gdGhlIHJpZ2h0IHJlZ2lzdGVyIGNsYXNzLgordW5zaWduZWQgY29uc3RyYWluT3BlcmFuZFJlZ0NsYXNzKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICZUUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldEluc3RySW5mbyAmVElJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlZ2lzdGVyQmFua0luZm8gJlJCSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSW5zdHIgJkluc2VydFB0LCBjb25zdCBNQ0luc3RyRGVzYyAmSUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZU9wZXJhbmQgJlJlZ01PLCB1bnNpZ25lZCBPcElkeCk7CisKKy8vLyBNdXRhdGUgdGhlIG5ld2x5LXNlbGVjdGVkIGluc3RydWN0aW9uIFxwIEkgdG8gY29uc3RyYWluIGl0cyAocG9zc2libHkKKy8vLyBnZW5lcmljKSB2aXJ0dWFsIHJlZ2lzdGVyIG9wZXJhbmRzIHRvIHRoZSBpbnN0cnVjdGlvbidzIHJlZ2lzdGVyIGNsYXNzLgorLy8vIFRoaXMgY291bGQgaW52b2x2ZSBpbnNlcnRpbmcgQ09QWXMgYmVmb3JlIChmb3IgdXNlcykgb3IgYWZ0ZXIgKGZvciBkZWZzKS4KKy8vLyBUaGlzIHJlcXVpcmVzIHRoZSBudW1iZXIgb2Ygb3BlcmFuZHMgdG8gbWF0Y2ggdGhlIGluc3RydWN0aW9uIGRlc2NyaXB0aW9uLgorLy8vIFxyZXR1cm5zIHdoZXRoZXIgb3BlcmFuZCByZWdjbGFzcyBjb25zdHJhaW5pbmcgc3VjY2VlZGVkLgorLy8vCisvLyBGSVhNRTogTm90IGFsbCBpbnN0cnVjdGlvbnMgaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2Ygb3BlcmFuZHMuIFdlIHNob3VsZAorLy8gcHJvYmFibHkgZXhwb3NlIGEgY29uc3RyYWluIGhlbHBlciBwZXIgb3BlcmFuZCBhbmQgbGV0IHRoZSB0YXJnZXQgc2VsZWN0b3IKKy8vIGNvbnN0cmFpbiBpbmRpdmlkdWFsIHJlZ2lzdGVycywgbGlrZSBmYXN0LWlzZWwuCitib29sIGNvbnN0cmFpblNlbGVjdGVkSW5zdFJlZ09wZXJhbmRzKE1hY2hpbmVJbnN0ciAmSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICZUSUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAmVFJJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZWdpc3RlckJhbmtJbmZvICZSQkkpOworLy8vIENoZWNrIHdoZXRoZXIgYW4gaW5zdHJ1Y3Rpb24gXHAgTUkgaXMgZGVhZDogaXQgb25seSBkZWZpbmVzIGRlYWQgdmlydHVhbAorLy8vIHJlZ2lzdGVycywgYW5kIGRvZXNuJ3QgaGF2ZSBvdGhlciBzaWRlIGVmZmVjdHMuCitib29sIGlzVHJpdmlhbGx5RGVhZChjb25zdCBNYWNoaW5lSW5zdHIgJk1JLCBjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkkpOworCisvLy8gUmVwb3J0IGFuIElTZWwgZXJyb3IgYXMgYSBtaXNzZWQgb3B0aW1pemF0aW9uIHJlbWFyayB0byB0aGUgTExWTUNvbnRleHQncworLy8vIGRpYWdub3N0aWMgc3RyZWFtLiAgU2V0IHRoZSBGYWlsZWRJU2VsIE1hY2hpbmVGdW5jdGlvbiBwcm9wZXJ0eS4KK3ZvaWQgcmVwb3J0R0lTZWxGYWlsdXJlKE1hY2hpbmVGdW5jdGlvbiAmTUYsIGNvbnN0IFRhcmdldFBhc3NDb25maWcgJlRQQywKKyAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVPcHRpbWl6YXRpb25SZW1hcmtFbWl0dGVyICZNT1JFLAorICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZU9wdGltaXphdGlvblJlbWFya01pc3NlZCAmUik7CisKK3ZvaWQgcmVwb3J0R0lTZWxGYWlsdXJlKE1hY2hpbmVGdW5jdGlvbiAmTUYsIGNvbnN0IFRhcmdldFBhc3NDb25maWcgJlRQQywKKyAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVPcHRpbWl6YXRpb25SZW1hcmtFbWl0dGVyICZNT1JFLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqUGFzc05hbWUsIFN0cmluZ1JlZiBNc2csCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lSW5zdHIgJk1JKTsKKworT3B0aW9uYWw8aW50NjRfdD4gZ2V0Q29uc3RhbnRWUmVnVmFsKHVuc2lnbmVkIFZSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJKTsKK2NvbnN0IENvbnN0YW50RlAqIGdldENvbnN0YW50RlBWUmVnVmFsKHVuc2lnbmVkIFZSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkkpOworCisvLy8gU2VlIGlmIFJlZyBpcyBkZWZpbmVkIGJ5IGFuIHNpbmdsZSBkZWYgaW5zdHJ1Y3Rpb24gdGhhdCBpcworLy8vIE9wY29kZS4gQWxzbyB0cnkgdG8gZG8gdHJpdmlhbCBmb2xkaW5nIGlmIGl0J3MgYSBDT1BZIHdpdGgKKy8vLyBzYW1lIHR5cGVzLiBSZXR1cm5zIG51bGwgb3RoZXJ3aXNlLgorTWFjaGluZUluc3RyICpnZXRPcGNvZGVEZWYodW5zaWduZWQgT3Bjb2RlLCB1bnNpZ25lZCBSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkkpOworCisvLy8gUmV0dXJucyBhbiBBUEZsb2F0IGZyb20gVmFsIGNvbnZlcnRlZCB0byB0aGUgYXBwcm9wcmlhdGUgc2l6ZS4KK0FQRmxvYXQgZ2V0QVBGbG9hdEZyb21TaXplKGRvdWJsZSBWYWwsIHVuc2lnbmVkIFNpemUpOworfSAvLyBFbmQgbmFtZXNwYWNlIGxsdm0uCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9JU0RPcGNvZGVzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vSVNET3Bjb2Rlcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhOTQ4NzEKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vSVNET3Bjb2Rlcy5oCkBAIC0wLDAgKzEsOTk3IEBACisvLz09PS0tIGxsdm0vQ29kZUdlbi9JU0RPcGNvZGVzLmggLSBDb2RlR2VuIG9wY29kZXMgLS0tLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZWNsYXJlcyBjb2RlZ2VuIG9wY29kZXMgYW5kIHJlbGF0ZWQgdXRpbGl0aWVzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0lTRE9QQ09ERVNfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fSVNET1BDT0RFU19ICisKK25hbWVzcGFjZSBsbHZtIHsKKworLy8vIElTRCBuYW1lc3BhY2UgLSBUaGlzIG5hbWVzcGFjZSBjb250YWlucyBhbiBlbnVtIHdoaWNoIHJlcHJlc2VudHMgYWxsIG9mIHRoZQorLy8vIFNlbGVjdGlvbkRBRyBub2RlIHR5cGVzIGFuZCB2YWx1ZSB0eXBlcy4KKy8vLworbmFtZXNwYWNlIElTRCB7CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vLyBJU0Q6Ok5vZGVUeXBlIGVudW0gLSBUaGlzIGVudW0gZGVmaW5lcyB0aGUgdGFyZ2V0LWluZGVwZW5kZW50IG9wZXJhdG9ycworICAvLy8gZm9yIGEgU2VsZWN0aW9uREFHLgorICAvLy8KKyAgLy8vIFRhcmdldHMgbWF5IGFsc28gZGVmaW5lIHRhcmdldC1kZXBlbmRlbnQgb3BlcmF0b3IgY29kZXMgZm9yIFNETm9kZXMuIEZvcgorICAvLy8gZXhhbXBsZSwgb24geDg2LCB0aGVzZSBhcmUgdGhlIGVudW0gdmFsdWVzIGluIHRoZSBYODZJU0QgbmFtZXNwYWNlLgorICAvLy8gVGFyZ2V0cyBzaG91bGQgYWltIHRvIHVzZSB0YXJnZXQtaW5kZXBlbmRlbnQgb3BlcmF0b3JzIHRvIG1vZGVsIHRoZWlyCisgIC8vLyBpbnN0cnVjdGlvbiBzZXRzIGFzIG11Y2ggYXMgcG9zc2libGUsIGFuZCBvbmx5IHVzZSB0YXJnZXQtZGVwZW5kZW50CisgIC8vLyBvcGVyYXRvcnMgd2hlbiB0aGV5IGhhdmUgc3BlY2lhbCByZXF1aXJlbWVudHMuCisgIC8vLworICAvLy8gRmluYWxseSwgZHVyaW5nIGFuZCBhZnRlciBzZWxlY3Rpb24gcHJvcGVyLCBTTm9kZXMgbWF5IHVzZSBzcGVjaWFsCisgIC8vLyBvcGVyYXRvciBjb2RlcyB0aGF0IGNvcnJlc3BvbmQgZGlyZWN0bHkgd2l0aCBNYWNoaW5lSW5zdHIgb3Bjb2Rlcy4gVGhlc2UKKyAgLy8vIGFyZSB1c2VkIHRvIHJlcHJlc2VudCBzZWxlY3RlZCBpbnN0cnVjdGlvbnMuIFNlZSB0aGUgaXNNYWNoaW5lT3Bjb2RlKCkKKyAgLy8vIGFuZCBnZXRNYWNoaW5lT3Bjb2RlKCkgbWVtYmVyIGZ1bmN0aW9ucyBvZiBTRE5vZGUuCisgIC8vLworICBlbnVtIE5vZGVUeXBlIHsKKyAgICAvLy8gREVMRVRFRF9OT0RFIC0gVGhpcyBpcyBhbiBpbGxlZ2FsIHZhbHVlIHRoYXQgaXMgdXNlZCB0byBjYXRjaAorICAgIC8vLyBlcnJvcnMuICBUaGlzIG9wY29kZSBpcyBub3QgYSBsZWdhbCBvcGNvZGUgZm9yIGFueSBub2RlLgorICAgIERFTEVURURfTk9ERSwKKworICAgIC8vLyBFbnRyeVRva2VuIC0gVGhpcyBpcyB0aGUgbWFya2VyIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHN0YXJ0IG9mIGEgcmVnaW9uLgorICAgIEVudHJ5VG9rZW4sCisKKyAgICAvLy8gVG9rZW5GYWN0b3IgLSBUaGlzIG5vZGUgdGFrZXMgbXVsdGlwbGUgdG9rZW5zIGFzIGlucHV0IGFuZCBwcm9kdWNlcyBhCisgICAgLy8vIHNpbmdsZSB0b2tlbiByZXN1bHQuIFRoaXMgaXMgdXNlZCB0byByZXByZXNlbnQgdGhlIGZhY3QgdGhhdCB0aGUgb3BlcmFuZAorICAgIC8vLyBvcGVyYXRvcnMgYXJlIGluZGVwZW5kZW50IG9mIGVhY2ggb3RoZXIuCisgICAgVG9rZW5GYWN0b3IsCisKKyAgICAvLy8gQXNzZXJ0U2V4dCwgQXNzZXJ0WmV4dCAtIFRoZXNlIG5vZGVzIHJlY29yZCBpZiBhIHJlZ2lzdGVyIGNvbnRhaW5zIGEKKyAgICAvLy8gdmFsdWUgdGhhdCBoYXMgYWxyZWFkeSBiZWVuIHplcm8gb3Igc2lnbiBleHRlbmRlZCBmcm9tIGEgbmFycm93ZXIgdHlwZS4KKyAgICAvLy8gVGhlc2Ugbm9kZXMgdGFrZSB0d28gb3BlcmFuZHMuICBUaGUgZmlyc3QgaXMgdGhlIG5vZGUgdGhhdCBoYXMgYWxyZWFkeQorICAgIC8vLyBiZWVuIGV4dGVuZGVkLCBhbmQgdGhlIHNlY29uZCBpcyBhIHZhbHVlIHR5cGUgbm9kZSBpbmRpY2F0aW5nIHRoZSB3aWR0aAorICAgIC8vLyBvZiB0aGUgZXh0ZW5zaW9uCisgICAgQXNzZXJ0U2V4dCwgQXNzZXJ0WmV4dCwKKworICAgIC8vLyBWYXJpb3VzIGxlYWYgbm9kZXMuCisgICAgQmFzaWNCbG9jaywgVkFMVUVUWVBFLCBDT05EQ09ERSwgUmVnaXN0ZXIsIFJlZ2lzdGVyTWFzaywKKyAgICBDb25zdGFudCwgQ29uc3RhbnRGUCwKKyAgICBHbG9iYWxBZGRyZXNzLCBHbG9iYWxUTFNBZGRyZXNzLCBGcmFtZUluZGV4LAorICAgIEp1bXBUYWJsZSwgQ29uc3RhbnRQb29sLCBFeHRlcm5hbFN5bWJvbCwgQmxvY2tBZGRyZXNzLAorCisgICAgLy8vIFRoZSBhZGRyZXNzIG9mIHRoZSBHT1QKKyAgICBHTE9CQUxfT0ZGU0VUX1RBQkxFLAorCisgICAgLy8vIEZSQU1FQUREUiwgUkVUVVJOQUREUiAtIFRoZXNlIG5vZGVzIHJlcHJlc2VudCBsbHZtLmZyYW1lYWRkcmVzcyBhbmQKKyAgICAvLy8gbGx2bS5yZXR1cm5hZGRyZXNzIG9uIHRoZSBEQUcuICBUaGVzZSBub2RlcyB0YWtlIG9uZSBvcGVyYW5kLCB0aGUgaW5kZXgKKyAgICAvLy8gb2YgdGhlIGZyYW1lIG9yIHJldHVybiBhZGRyZXNzIHRvIHJldHVybi4gIEFuIGluZGV4IG9mIHplcm8gY29ycmVzcG9uZHMKKyAgICAvLy8gdG8gdGhlIGN1cnJlbnQgZnVuY3Rpb24ncyBmcmFtZSBvciByZXR1cm4gYWRkcmVzcywgYW4gaW5kZXggb2Ygb25lIHRvCisgICAgLy8vIHRoZSBwYXJlbnQncyBmcmFtZSBvciByZXR1cm4gYWRkcmVzcywgYW5kIHNvIG9uLgorICAgIEZSQU1FQUREUiwgUkVUVVJOQUREUiwgQUREUk9GUkVUVVJOQUREUiwKKworICAgIC8vLyBMT0NBTF9SRUNPVkVSIC0gUmVwcmVzZW50cyB0aGUgbGx2bS5sb2NhbHJlY292ZXIgaW50cmluc2ljLgorICAgIC8vLyBNYXRlcmlhbGl6ZXMgdGhlIG9mZnNldCBmcm9tIHRoZSBsb2NhbCBvYmplY3QgcG9pbnRlciBvZiBhbm90aGVyCisgICAgLy8vIGZ1bmN0aW9uIHRvIGEgcGFydGljdWxhciBsb2NhbCBvYmplY3QgcGFzc2VkIHRvIGxsdm0ubG9jYWxlc2NhcGUuIFRoZQorICAgIC8vLyBvcGVyYW5kIGlzIHRoZSBNQ1N5bWJvbCBsYWJlbCB1c2VkIHRvIHJlcHJlc2VudCB0aGlzIG9mZnNldCwgc2luY2UKKyAgICAvLy8gdHlwaWNhbGx5IHRoZSBvZmZzZXQgaXMgbm90IGtub3duIHVudGlsIGFmdGVyIGNvZGUgZ2VuZXJhdGlvbiBvZiB0aGUKKyAgICAvLy8gcGFyZW50LgorICAgIExPQ0FMX1JFQ09WRVIsCisKKyAgICAvLy8gUkVBRF9SRUdJU1RFUiwgV1JJVEVfUkVHSVNURVIgLSBUaGlzIG5vZGUgcmVwcmVzZW50cyBsbHZtLnJlZ2lzdGVyIG9uCisgICAgLy8vIHRoZSBEQUcsIHdoaWNoIGltcGxlbWVudHMgdGhlIG5hbWVkIHJlZ2lzdGVyIGdsb2JhbCB2YXJpYWJsZXMgZXh0ZW5zaW9uLgorICAgIFJFQURfUkVHSVNURVIsCisgICAgV1JJVEVfUkVHSVNURVIsCisKKyAgICAvLy8gRlJBTUVfVE9fQVJHU19PRkZTRVQgLSBUaGlzIG5vZGUgcmVwcmVzZW50cyBvZmZzZXQgZnJvbSBmcmFtZSBwb2ludGVyIHRvCisgICAgLy8vIGZpcnN0IChwb3NzaWJsZSkgb24tc3RhY2sgYXJndW1lbnQuIFRoaXMgaXMgbmVlZGVkIGZvciBjb3JyZWN0IHN0YWNrCisgICAgLy8vIGFkanVzdG1lbnQgZHVyaW5nIHVud2luZC4KKyAgICBGUkFNRV9UT19BUkdTX09GRlNFVCwKKworICAgIC8vLyBFSF9EV0FSRl9DRkEgLSBUaGlzIG5vZGUgcmVwcmVzZW50cyB0aGUgcG9pbnRlciB0byB0aGUgRFdBUkYgQ2Fub25pY2FsCisgICAgLy8vIEZyYW1lIEFkZHJlc3MgKENGQSksIGdlbmVyYWxseSB0aGUgdmFsdWUgb2YgdGhlIHN0YWNrIHBvaW50ZXIgYXQgdGhlCisgICAgLy8vIGNhbGwgc2l0ZSBpbiB0aGUgcHJldmlvdXMgZnJhbWUuCisgICAgRUhfRFdBUkZfQ0ZBLAorCisgICAgLy8vIE9VVENIQUlOID0gRUhfUkVUVVJOKElOQ0hBSU4sIE9GRlNFVCwgSEFORExFUikgLSBUaGlzIG5vZGUgcmVwcmVzZW50cworICAgIC8vLyAnZWhfcmV0dXJuJyBnY2MgZHdhcmYgYnVpbHRpbiwgd2hpY2ggaXMgdXNlZCB0byByZXR1cm4gZnJvbQorICAgIC8vLyBleGNlcHRpb24uIFRoZSBnZW5lcmFsIG1lYW5pbmcgaXM6IGFkanVzdCBzdGFjayBieSBPRkZTRVQgYW5kIHBhc3MKKyAgICAvLy8gZXhlY3V0aW9uIHRvIEhBTkRMRVIuIE1hbnkgcGxhdGZvcm0tcmVsYXRlZCBkZXRhaWxzIGFsc28gOikKKyAgICBFSF9SRVRVUk4sCisKKyAgICAvLy8gUkVTVUxULCBPVVRDSEFJTiA9IEVIX1NKTEpfU0VUSk1QKElOQ0hBSU4sIGJ1ZmZlcikKKyAgICAvLy8gVGhpcyBjb3JyZXNwb25kcyB0byB0aGUgZWguc2psai5zZXRqbXAgaW50cmluc2ljLgorICAgIC8vLyBJdCB0YWtlcyBhbiBpbnB1dCBjaGFpbiBhbmQgYSBwb2ludGVyIHRvIHRoZSBqdW1wIGJ1ZmZlciBhcyBpbnB1dHMKKyAgICAvLy8gYW5kIHJldHVybnMgYW4gb3V0Y2hhaW4uCisgICAgRUhfU0pMSl9TRVRKTVAsCisKKyAgICAvLy8gT1VUQ0hBSU4gPSBFSF9TSkxKX0xPTkdKTVAoSU5DSEFJTiwgYnVmZmVyKQorICAgIC8vLyBUaGlzIGNvcnJlc3BvbmRzIHRvIHRoZSBlaC5zamxqLmxvbmdqbXAgaW50cmluc2ljLgorICAgIC8vLyBJdCB0YWtlcyBhbiBpbnB1dCBjaGFpbiBhbmQgYSBwb2ludGVyIHRvIHRoZSBqdW1wIGJ1ZmZlciBhcyBpbnB1dHMKKyAgICAvLy8gYW5kIHJldHVybnMgYW4gb3V0Y2hhaW4uCisgICAgRUhfU0pMSl9MT05HSk1QLAorCisgICAgLy8vIE9VVENIQUlOID0gRUhfU0pMSl9TRVRVUF9ESVNQQVRDSChJTkNIQUlOKQorICAgIC8vLyBUaGUgdGFyZ2V0IGluaXRpYWxpemVzIHRoZSBkaXNwYXRjaCB0YWJsZSBoZXJlLgorICAgIEVIX1NKTEpfU0VUVVBfRElTUEFUQ0gsCisKKyAgICAvLy8gVGFyZ2V0Q29uc3RhbnQqIC0gTGlrZSBDb25zdGFudCosIGJ1dCB0aGUgREFHIGRvZXMgbm90IGRvIGFueSBmb2xkaW5nLAorICAgIC8vLyBzaW1wbGlmaWNhdGlvbiwgb3IgbG93ZXJpbmcgb2YgdGhlIGNvbnN0YW50LiBUaGV5IGFyZSB1c2VkIGZvciBjb25zdGFudHMKKyAgICAvLy8gd2hpY2ggYXJlIGtub3duIHRvIGZpdCBpbiB0aGUgaW1tZWRpYXRlIGZpZWxkcyBvZiB0aGVpciB1c2Vycywgb3IgZm9yCisgICAgLy8vIGNhcnJ5aW5nIG1hZ2ljIG51bWJlcnMgd2hpY2ggYXJlIG5vdCB2YWx1ZXMgd2hpY2ggbmVlZCB0byBiZQorICAgIC8vLyBtYXRlcmlhbGl6ZWQgaW4gcmVnaXN0ZXJzLgorICAgIFRhcmdldENvbnN0YW50LAorICAgIFRhcmdldENvbnN0YW50RlAsCisKKyAgICAvLy8gVGFyZ2V0R2xvYmFsQWRkcmVzcyAtIExpa2UgR2xvYmFsQWRkcmVzcywgYnV0IHRoZSBEQUcgZG9lcyBubyBmb2xkaW5nIG9yCisgICAgLy8vIGFueXRoaW5nIGVsc2Ugd2l0aCB0aGlzIG5vZGUsIGFuZCB0aGlzIGlzIHZhbGlkIGluIHRoZSB0YXJnZXQtc3BlY2lmaWMKKyAgICAvLy8gZGFnLCB0dXJuaW5nIGludG8gYSBHbG9iYWxBZGRyZXNzIG9wZXJhbmQuCisgICAgVGFyZ2V0R2xvYmFsQWRkcmVzcywKKyAgICBUYXJnZXRHbG9iYWxUTFNBZGRyZXNzLAorICAgIFRhcmdldEZyYW1lSW5kZXgsCisgICAgVGFyZ2V0SnVtcFRhYmxlLAorICAgIFRhcmdldENvbnN0YW50UG9vbCwKKyAgICBUYXJnZXRFeHRlcm5hbFN5bWJvbCwKKyAgICBUYXJnZXRCbG9ja0FkZHJlc3MsCisKKyAgICBNQ1N5bWJvbCwKKworICAgIC8vLyBUYXJnZXRJbmRleCAtIExpa2UgYSBjb25zdGFudCBwb29sIGVudHJ5LCBidXQgd2l0aCBjb21wbGV0ZWx5CisgICAgLy8vIHRhcmdldC1kZXBlbmRlbnQgc2VtYW50aWNzLiBIb2xkcyB0YXJnZXQgZmxhZ3MsIGEgMzItYml0IGluZGV4LCBhbmQgYQorICAgIC8vLyA2NC1iaXQgaW5kZXguIFRhcmdldHMgY2FuIHVzZSB0aGlzIGhvd2V2ZXIgdGhleSBsaWtlLgorICAgIFRhcmdldEluZGV4LAorCisgICAgLy8vIFJFU1VMVCA9IElOVFJJTlNJQ19XT19DSEFJTihJTlRSSU5TSUNJRCwgYXJnMSwgYXJnMiwgLi4uKQorICAgIC8vLyBUaGlzIG5vZGUgcmVwcmVzZW50cyBhIHRhcmdldCBpbnRyaW5zaWMgZnVuY3Rpb24gd2l0aCBubyBzaWRlIGVmZmVjdHMuCisgICAgLy8vIFRoZSBmaXJzdCBvcGVyYW5kIGlzIHRoZSBJRCBudW1iZXIgb2YgdGhlIGludHJpbnNpYyBmcm9tIHRoZQorICAgIC8vLyBsbHZtOjpJbnRyaW5zaWMgbmFtZXNwYWNlLiAgVGhlIG9wZXJhbmRzIHRvIHRoZSBpbnRyaW5zaWMgZm9sbG93LiAgVGhlCisgICAgLy8vIG5vZGUgcmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSBpbnRyaW5zaWMuCisgICAgSU5UUklOU0lDX1dPX0NIQUlOLAorCisgICAgLy8vIFJFU1VMVCxPVVRDSEFJTiA9IElOVFJJTlNJQ19XX0NIQUlOKElOQ0hBSU4sIElOVFJJTlNJQ0lELCBhcmcxLCAuLi4pCisgICAgLy8vIFRoaXMgbm9kZSByZXByZXNlbnRzIGEgdGFyZ2V0IGludHJpbnNpYyBmdW5jdGlvbiB3aXRoIHNpZGUgZWZmZWN0cyB0aGF0CisgICAgLy8vIHJldHVybnMgYSByZXN1bHQuICBUaGUgZmlyc3Qgb3BlcmFuZCBpcyBhIGNoYWluIHBvaW50ZXIuICBUaGUgc2Vjb25kIGlzCisgICAgLy8vIHRoZSBJRCBudW1iZXIgb2YgdGhlIGludHJpbnNpYyBmcm9tIHRoZSBsbHZtOjpJbnRyaW5zaWMgbmFtZXNwYWNlLiAgVGhlCisgICAgLy8vIG9wZXJhbmRzIHRvIHRoZSBpbnRyaW5zaWMgZm9sbG93LiAgVGhlIG5vZGUgaGFzIHR3byByZXN1bHRzLCB0aGUgcmVzdWx0CisgICAgLy8vIG9mIHRoZSBpbnRyaW5zaWMgYW5kIGFuIG91dHB1dCBjaGFpbi4KKyAgICBJTlRSSU5TSUNfV19DSEFJTiwKKworICAgIC8vLyBPVVRDSEFJTiA9IElOVFJJTlNJQ19WT0lEKElOQ0hBSU4sIElOVFJJTlNJQ0lELCBhcmcxLCBhcmcyLCAuLi4pCisgICAgLy8vIFRoaXMgbm9kZSByZXByZXNlbnRzIGEgdGFyZ2V0IGludHJpbnNpYyBmdW5jdGlvbiB3aXRoIHNpZGUgZWZmZWN0cyB0aGF0CisgICAgLy8vIGRvZXMgbm90IHJldHVybiBhIHJlc3VsdC4gIFRoZSBmaXJzdCBvcGVyYW5kIGlzIGEgY2hhaW4gcG9pbnRlci4gIFRoZQorICAgIC8vLyBzZWNvbmQgaXMgdGhlIElEIG51bWJlciBvZiB0aGUgaW50cmluc2ljIGZyb20gdGhlIGxsdm06OkludHJpbnNpYworICAgIC8vLyBuYW1lc3BhY2UuICBUaGUgb3BlcmFuZHMgdG8gdGhlIGludHJpbnNpYyBmb2xsb3cuCisgICAgSU5UUklOU0lDX1ZPSUQsCisKKyAgICAvLy8gQ29weVRvUmVnIC0gVGhpcyBub2RlIGhhcyB0aHJlZSBvcGVyYW5kczogYSBjaGFpbiwgYSByZWdpc3RlciBudW1iZXIgdG8KKyAgICAvLy8gc2V0IHRvIHRoaXMgdmFsdWUsIGFuZCBhIHZhbHVlLgorICAgIENvcHlUb1JlZywKKworICAgIC8vLyBDb3B5RnJvbVJlZyAtIFRoaXMgbm9kZSBpbmRpY2F0ZXMgdGhhdCB0aGUgaW5wdXQgdmFsdWUgaXMgYSB2aXJ0dWFsIG9yCisgICAgLy8vIHBoeXNpY2FsIHJlZ2lzdGVyIHRoYXQgaXMgZGVmaW5lZCBvdXRzaWRlIG9mIHRoZSBzY29wZSBvZiB0aGlzCisgICAgLy8vIFNlbGVjdGlvbkRBRy4gIFRoZSByZWdpc3RlciBpcyBhdmFpbGFibGUgZnJvbSB0aGUgUmVnaXN0ZXJTRE5vZGUgb2JqZWN0LgorICAgIENvcHlGcm9tUmVnLAorCisgICAgLy8vIFVOREVGIC0gQW4gdW5kZWZpbmVkIG5vZGUuCisgICAgVU5ERUYsCisKKyAgICAvLy8gRVhUUkFDVF9FTEVNRU5UIC0gVGhpcyBpcyB1c2VkIHRvIGdldCB0aGUgbG93ZXIgb3IgdXBwZXIgKGRldGVybWluZWQgYnkKKyAgICAvLy8gYSBDb25zdGFudCwgd2hpY2ggaXMgcmVxdWlyZWQgdG8gYmUgb3BlcmFuZCAjMSkgaGFsZiBvZiB0aGUgaW50ZWdlciBvcgorICAgIC8vLyBmbG9hdCB2YWx1ZSBzcGVjaWZpZWQgYXMgb3BlcmFuZCAjMC4gIFRoaXMgaXMgb25seSBmb3IgdXNlIGJlZm9yZQorICAgIC8vLyBsZWdhbGl6YXRpb24sIGZvciB2YWx1ZXMgdGhhdCB3aWxsIGJlIGJyb2tlbiBpbnRvIG11bHRpcGxlIHJlZ2lzdGVycy4KKyAgICBFWFRSQUNUX0VMRU1FTlQsCisKKyAgICAvLy8gQlVJTERfUEFJUiAtIFRoaXMgaXMgdGhlIG9wcG9zaXRlIG9mIEVYVFJBQ1RfRUxFTUVOVCBpbiBzb21lIHdheXMuCisgICAgLy8vIEdpdmVuIHR3byB2YWx1ZXMgb2YgdGhlIHNhbWUgaW50ZWdlciB2YWx1ZSB0eXBlLCB0aGlzIHByb2R1Y2VzIGEgdmFsdWUKKyAgICAvLy8gdHdpY2UgYXMgYmlnLiAgTGlrZSBFWFRSQUNUX0VMRU1FTlQsIHRoaXMgY2FuIG9ubHkgYmUgdXNlZCBiZWZvcmUKKyAgICAvLy8gbGVnYWxpemF0aW9uLiBUaGUgbG93ZXIgcGFydCBvZiB0aGUgY29tcG9zaXRlIHZhbHVlIHNob3VsZCBiZSBpbgorICAgIC8vLyBlbGVtZW50IDAgYW5kIHRoZSB1cHBlciBwYXJ0IHNob3VsZCBiZSBpbiBlbGVtZW50IDEuCisgICAgQlVJTERfUEFJUiwKKworICAgIC8vLyBNRVJHRV9WQUxVRVMgLSBUaGlzIG5vZGUgdGFrZXMgbXVsdGlwbGUgZGlzY3JldGUgb3BlcmFuZHMgYW5kIHJldHVybnMKKyAgICAvLy8gdGhlbSBhbGwgYXMgaXRzIGluZGl2aWR1YWwgcmVzdWx0cy4gIFRoaXMgbm9kZXMgaGFzIGV4YWN0bHkgdGhlIHNhbWUKKyAgICAvLy8gbnVtYmVyIG9mIGlucHV0cyBhbmQgb3V0cHV0cy4gVGhpcyBub2RlIGlzIHVzZWZ1bCBmb3Igc29tZSBwaWVjZXMgb2YgdGhlCisgICAgLy8vIGNvZGUgZ2VuZXJhdG9yIHRoYXQgd2FudCB0byB0aGluayBhYm91dCBhIHNpbmdsZSBub2RlIHdpdGggbXVsdGlwbGUKKyAgICAvLy8gcmVzdWx0cywgbm90IG11bHRpcGxlIG5vZGVzLgorICAgIE1FUkdFX1ZBTFVFUywKKworICAgIC8vLyBTaW1wbGUgaW50ZWdlciBiaW5hcnkgYXJpdGhtZXRpYyBvcGVyYXRvcnMuCisgICAgQURELCBTVUIsIE1VTCwgU0RJViwgVURJViwgU1JFTSwgVVJFTSwKKworICAgIC8vLyBTTVVMX0xPSEkvVU1VTF9MT0hJIC0gTXVsdGlwbHkgdHdvIGludGVnZXJzIG9mIHR5cGUgaU4sIHByb2R1Y2luZworICAgIC8vLyBhIHNpZ25lZC91bnNpZ25lZCB2YWx1ZSBvZiB0eXBlIGlbMipOXSwgYW5kIHJldHVybiB0aGUgZnVsbCB2YWx1ZSBhcworICAgIC8vLyB0d28gcmVzdWx0cywgZWFjaCBvZiB0eXBlIGlOLgorICAgIFNNVUxfTE9ISSwgVU1VTF9MT0hJLAorCisgICAgLy8vIFNESVZSRU0vVURJVlJFTSAtIERpdmlkZSB0d28gaW50ZWdlcnMgYW5kIHByb2R1Y2UgYm90aCBhIHF1b3RpZW50IGFuZAorICAgIC8vLyByZW1haW5kZXIgcmVzdWx0LgorICAgIFNESVZSRU0sIFVESVZSRU0sCisKKyAgICAvLy8gQ0FSUllfRkFMU0UgLSBUaGlzIG5vZGUgaXMgdXNlZCB3aGVuIGZvbGRpbmcgb3RoZXIgbm9kZXMsCisgICAgLy8vIGxpa2UgQUREQy9TVUJDLCB3aGljaCBpbmRpY2F0ZSB0aGUgY2FycnkgcmVzdWx0IGlzIGFsd2F5cyBmYWxzZS4KKyAgICBDQVJSWV9GQUxTRSwKKworICAgIC8vLyBDYXJyeS1zZXR0aW5nIG5vZGVzIGZvciBtdWx0aXBsZSBwcmVjaXNpb24gYWRkaXRpb24gYW5kIHN1YnRyYWN0aW9uLgorICAgIC8vLyBUaGVzZSBub2RlcyB0YWtlIHR3byBvcGVyYW5kcyBvZiB0aGUgc2FtZSB2YWx1ZSB0eXBlLCBhbmQgcHJvZHVjZSB0d28KKyAgICAvLy8gcmVzdWx0cy4gIFRoZSBmaXJzdCByZXN1bHQgaXMgdGhlIG5vcm1hbCBhZGQgb3Igc3ViIHJlc3VsdCwgdGhlIHNlY29uZAorICAgIC8vLyByZXN1bHQgaXMgdGhlIGNhcnJ5IGZsYWcgcmVzdWx0LgorICAgIC8vLyBGSVhNRTogVGhlc2Ugbm9kZXMgYXJlIGRlcHJlY2F0ZWQgaW4gZmF2b3Igb2YgQUREQ0FSUlkgYW5kIFNVQkNBUlJZLgorICAgIC8vLyBUaGV5IGFyZSBrZXB0IGFyb3VuZCBmb3Igbm93IHRvIHByb3ZpZGUgYSBzbW9vdGggdHJhbnNpdGlvbiBwYXRoCisgICAgLy8vIHRvd2FyZCB0aGUgdXNlIG9mIEFERENBUlJZL1NVQkNBUlJZIGFuZCB3aWxsIGV2ZW50dWFsbHkgYmUgcmVtb3ZlZC4KKyAgICBBRERDLCBTVUJDLAorCisgICAgLy8vIENhcnJ5LXVzaW5nIG5vZGVzIGZvciBtdWx0aXBsZSBwcmVjaXNpb24gYWRkaXRpb24gYW5kIHN1YnRyYWN0aW9uLiBUaGVzZQorICAgIC8vLyBub2RlcyB0YWtlIHRocmVlIG9wZXJhbmRzOiBUaGUgZmlyc3QgdHdvIGFyZSB0aGUgbm9ybWFsIGxocyBhbmQgcmhzIHRvCisgICAgLy8vIHRoZSBhZGQgb3Igc3ViLCBhbmQgdGhlIHRoaXJkIGlzIHRoZSBpbnB1dCBjYXJyeSBmbGFnLiAgVGhlc2Ugbm9kZXMKKyAgICAvLy8gcHJvZHVjZSB0d28gcmVzdWx0czsgdGhlIG5vcm1hbCByZXN1bHQgb2YgdGhlIGFkZCBvciBzdWIsIGFuZCB0aGUgb3V0cHV0CisgICAgLy8vIGNhcnJ5IGZsYWcuICBUaGVzZSBub2RlcyBib3RoIHJlYWQgYW5kIHdyaXRlIGEgY2FycnkgZmxhZyB0byBhbGxvdyB0aGVtCisgICAgLy8vIHRvIHRoZW0gdG8gYmUgY2hhaW5lZCB0b2dldGhlciBmb3IgYWRkIGFuZCBzdWIgb2YgYXJiaXRyYXJpbHkgbGFyZ2UKKyAgICAvLy8gdmFsdWVzLgorICAgIEFEREUsIFNVQkUsCisKKyAgICAvLy8gQ2FycnktdXNpbmcgbm9kZXMgZm9yIG11bHRpcGxlIHByZWNpc2lvbiBhZGRpdGlvbiBhbmQgc3VidHJhY3Rpb24uCisgICAgLy8vIFRoZXNlIG5vZGVzIHRha2UgdGhyZWUgb3BlcmFuZHM6IFRoZSBmaXJzdCB0d28gYXJlIHRoZSBub3JtYWwgbGhzIGFuZAorICAgIC8vLyByaHMgdG8gdGhlIGFkZCBvciBzdWIsIGFuZCB0aGUgdGhpcmQgaXMgYSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlcmUKKyAgICAvLy8gaXMgYW4gaW5jb21pbmcgY2FycnkuIFRoZXNlIG5vZGVzIHByb2R1Y2UgdHdvIHJlc3VsdHM6IHRoZSBub3JtYWwKKyAgICAvLy8gcmVzdWx0IG9mIHRoZSBhZGQgb3Igc3ViLCBhbmQgdGhlIG91dHB1dCBjYXJyeSBzbyB0aGV5IGNhbiBiZSBjaGFpbmVkCisgICAgLy8vIHRvZ2V0aGVyLiBUaGUgdXNlIG9mIHRoaXMgb3Bjb2RlIGlzIHByZWZlcmFibGUgdG8gYWRkZS9zdWJlIGlmIHRoZQorICAgIC8vLyB0YXJnZXQgc3VwcG9ydHMgaXQsIGFzIHRoZSBjYXJyeSBpcyBhIHJlZ3VsYXIgdmFsdWUgcmF0aGVyIHRoYW4gYQorICAgIC8vLyBnbHVlLCB3aGljaCBhbGxvd3MgZnVydGhlciBvcHRpbWlzYXRpb24uCisgICAgQUREQ0FSUlksIFNVQkNBUlJZLAorCisgICAgLy8vIFJFU1VMVCwgQk9PTCA9IFtTVV1BRERPKExIUywgUkhTKSAtIE92ZXJmbG93LWF3YXJlIG5vZGVzIGZvciBhZGRpdGlvbi4KKyAgICAvLy8gVGhlc2Ugbm9kZXMgdGFrZSB0d28gb3BlcmFuZHM6IHRoZSBub3JtYWwgTEhTIGFuZCBSSFMgdG8gdGhlIGFkZC4gVGhleQorICAgIC8vLyBwcm9kdWNlIHR3byByZXN1bHRzOiB0aGUgbm9ybWFsIHJlc3VsdCBvZiB0aGUgYWRkLCBhbmQgYSBib29sZWFuIHRoYXQKKyAgICAvLy8gaW5kaWNhdGVzIGlmIGFuIG92ZXJmbG93IG9jY3VycmVkICgqbm90KiBhIGZsYWcsIGJlY2F1c2UgaXQgbWF5IGJlIHN0b3JlCisgICAgLy8vIHRvIG1lbW9yeSwgZXRjLikuICBJZiB0aGUgdHlwZSBvZiB0aGUgYm9vbGVhbiBpcyBub3QgaTEgdGhlbiB0aGUgaGlnaAorICAgIC8vLyBiaXRzIGNvbmZvcm0gdG8gZ2V0Qm9vbGVhbkNvbnRlbnRzLgorICAgIC8vLyBUaGVzZSBub2RlcyBhcmUgZ2VuZXJhdGVkIGZyb20gbGx2bS5bc3VdYWRkLndpdGgub3ZlcmZsb3cgaW50cmluc2ljcy4KKyAgICBTQURETywgVUFERE8sCisKKyAgICAvLy8gU2FtZSBmb3Igc3VidHJhY3Rpb24uCisgICAgU1NVQk8sIFVTVUJPLAorCisgICAgLy8vIFNhbWUgZm9yIG11bHRpcGxpY2F0aW9uLgorICAgIFNNVUxPLCBVTVVMTywKKworICAgIC8vLyBTaW1wbGUgYmluYXJ5IGZsb2F0aW5nIHBvaW50IG9wZXJhdG9ycy4KKyAgICBGQURELCBGU1VCLCBGTVVMLCBGRElWLCBGUkVNLAorCisgICAgLy8vIENvbnN0cmFpbmVkIHZlcnNpb25zIG9mIHRoZSBiaW5hcnkgZmxvYXRpbmcgcG9pbnQgb3BlcmF0b3JzLgorICAgIC8vLyBUaGVzZSB3aWxsIGJlIGxvd2VyZWQgdG8gdGhlIHNpbXBsZSBvcGVyYXRvcnMgYmVmb3JlIGZpbmFsIHNlbGVjdGlvbi4KKyAgICAvLy8gVGhleSBhcmUgdXNlZCB0byBsaW1pdCBvcHRpbWl6YXRpb25zIHdoaWxlIHRoZSBEQUcgaXMgYmVpbmcKKyAgICAvLy8gb3B0aW1pemVkLgorICAgIFNUUklDVF9GQURELCBTVFJJQ1RfRlNVQiwgU1RSSUNUX0ZNVUwsIFNUUklDVF9GRElWLCBTVFJJQ1RfRlJFTSwKKyAgICBTVFJJQ1RfRk1BLAorCisgICAgLy8vIENvbnN0cmFpbmVkIHZlcnNpb25zIG9mIGxpYm0tZXF1aXZhbGVudCBmbG9hdGluZyBwb2ludCBpbnRyaW5zaWNzLgorICAgIC8vLyBUaGVzZSB3aWxsIGJlIGxvd2VyZWQgdG8gdGhlIGVxdWl2YWxlbnQgbm9uLWNvbnN0cmFpbmVkIHBzZXVkby1vcAorICAgIC8vLyAob3IgZXhwYW5kZWQgdG8gdGhlIGVxdWl2YWxlbnQgbGlicmFyeSBjYWxsKSBiZWZvcmUgZmluYWwgc2VsZWN0aW9uLgorICAgIC8vLyBUaGV5IGFyZSB1c2VkIHRvIGxpbWl0IG9wdGltaXphdGlvbnMgd2hpbGUgdGhlIERBRyBpcyBiZWluZyBvcHRpbWl6ZWQuCisgICAgU1RSSUNUX0ZTUVJULCBTVFJJQ1RfRlBPVywgU1RSSUNUX0ZQT1dJLCBTVFJJQ1RfRlNJTiwgU1RSSUNUX0ZDT1MsCisgICAgU1RSSUNUX0ZFWFAsIFNUUklDVF9GRVhQMiwgU1RSSUNUX0ZMT0csIFNUUklDVF9GTE9HMTAsIFNUUklDVF9GTE9HMiwKKyAgICBTVFJJQ1RfRlJJTlQsIFNUUklDVF9GTkVBUkJZSU5ULAorCisgICAgLy8vIEZNQSAtIFBlcmZvcm0gYSAqIGIgKyBjIHdpdGggbm8gaW50ZXJtZWRpYXRlIHJvdW5kaW5nIHN0ZXAuCisgICAgRk1BLAorCisgICAgLy8vIEZNQUQgLSBQZXJmb3JtIGEgKiBiICsgYywgd2hpbGUgZ2V0dGluZyB0aGUgc2FtZSByZXN1bHQgYXMgdGhlCisgICAgLy8vIHNlcGFyYXRlbHkgcm91bmRlZCBvcGVyYXRpb25zLgorICAgIEZNQUQsCisKKyAgICAvLy8gRkNPUFlTSUdOKFgsIFkpIC0gUmV0dXJuIHRoZSB2YWx1ZSBvZiBYIHdpdGggdGhlIHNpZ24gb2YgWS4gIE5PVEU6IFRoaXMKKyAgICAvLy8gREFHIG5vZGUgZG9lcyBub3QgcmVxdWlyZSB0aGF0IFggYW5kIFkgaGF2ZSB0aGUgc2FtZSB0eXBlLCBqdXN0IHRoYXQKKyAgICAvLy8gdGhleSBhcmUgYm90aCBmbG9hdGluZyBwb2ludC4gIFggYW5kIHRoZSByZXN1bHQgbXVzdCBoYXZlIHRoZSBzYW1lIHR5cGUuCisgICAgLy8vIEZDT1BZU0lHTihmMzIsIGY2NCkgaXMgYWxsb3dlZC4KKyAgICBGQ09QWVNJR04sCisKKyAgICAvLy8gSU5UID0gRkdFVFNJR04oRlApIC0gUmV0dXJuIHRoZSBzaWduIGJpdCBvZiB0aGUgc3BlY2lmaWVkIGZsb2F0aW5nIHBvaW50CisgICAgLy8vIHZhbHVlIGFzIGFuIGludGVnZXIgMC8xIHZhbHVlLgorICAgIEZHRVRTSUdOLAorCisgICAgLy8vIFJldHVybnMgcGxhdGZvcm0gc3BlY2lmaWMgY2Fub25pY2FsIGVuY29kaW5nIG9mIGEgZmxvYXRpbmcgcG9pbnQgbnVtYmVyLgorICAgIEZDQU5PTklDQUxJWkUsCisKKyAgICAvLy8gQlVJTERfVkVDVE9SKEVMVDAsIEVMVDEsIEVMVDIsIEVMVDMsLi4uKSAtIFJldHVybiBhIHZlY3RvciB3aXRoIHRoZQorICAgIC8vLyBzcGVjaWZpZWQsIHBvc3NpYmx5IHZhcmlhYmxlLCBlbGVtZW50cy4gIFRoZSBudW1iZXIgb2YgZWxlbWVudHMgaXMKKyAgICAvLy8gcmVxdWlyZWQgdG8gYmUgYSBwb3dlciBvZiB0d28uICBUaGUgdHlwZXMgb2YgdGhlIG9wZXJhbmRzIG11c3QgYWxsIGJlCisgICAgLy8vIHRoZSBzYW1lIGFuZCBtdXN0IG1hdGNoIHRoZSB2ZWN0b3IgZWxlbWVudCB0eXBlLCBleGNlcHQgdGhhdCBpbnRlZ2VyCisgICAgLy8vIHR5cGVzIGFyZSBhbGxvd2VkIHRvIGJlIGxhcmdlciB0aGFuIHRoZSBlbGVtZW50IHR5cGUsIGluIHdoaWNoIGNhc2UKKyAgICAvLy8gdGhlIG9wZXJhbmRzIGFyZSBpbXBsaWNpdGx5IHRydW5jYXRlZC4KKyAgICBCVUlMRF9WRUNUT1IsCisKKyAgICAvLy8gSU5TRVJUX1ZFQ1RPUl9FTFQoVkVDVE9SLCBWQUwsIElEWCkgLSBSZXR1cm5zIFZFQ1RPUiB3aXRoIHRoZSBlbGVtZW50CisgICAgLy8vIGF0IElEWCByZXBsYWNlZCB3aXRoIFZBTC4gIElmIHRoZSB0eXBlIG9mIFZBTCBpcyBsYXJnZXIgdGhhbiB0aGUgdmVjdG9yCisgICAgLy8vIGVsZW1lbnQgdHlwZSB0aGVuIFZBTCBpcyB0cnVuY2F0ZWQgYmVmb3JlIHJlcGxhY2VtZW50LgorICAgIElOU0VSVF9WRUNUT1JfRUxULAorCisgICAgLy8vIEVYVFJBQ1RfVkVDVE9SX0VMVChWRUNUT1IsIElEWCkgLSBSZXR1cm5zIGEgc2luZ2xlIGVsZW1lbnQgZnJvbSBWRUNUT1IKKyAgICAvLy8gaWRlbnRpZmllZCBieSB0aGUgKHBvdGVudGlhbGx5IHZhcmlhYmxlKSBlbGVtZW50IG51bWJlciBJRFguICBJZiB0aGUKKyAgICAvLy8gcmV0dXJuIHR5cGUgaXMgYW4gaW50ZWdlciB0eXBlIGxhcmdlciB0aGFuIHRoZSBlbGVtZW50IHR5cGUgb2YgdGhlCisgICAgLy8vIHZlY3RvciwgdGhlIHJlc3VsdCBpcyBleHRlbmRlZCB0byB0aGUgd2lkdGggb2YgdGhlIHJldHVybiB0eXBlLiBJbgorICAgIC8vLyB0aGF0IGNhc2UsIHRoZSBoaWdoIGJpdHMgYXJlIHVuZGVmaW5lZC4KKyAgICBFWFRSQUNUX1ZFQ1RPUl9FTFQsCisKKyAgICAvLy8gQ09OQ0FUX1ZFQ1RPUlMoVkVDVE9SMCwgVkVDVE9SMSwgLi4uKSAtIEdpdmVuIGEgbnVtYmVyIG9mIHZhbHVlcyBvZgorICAgIC8vLyB2ZWN0b3IgdHlwZSB3aXRoIHRoZSBzYW1lIGxlbmd0aCBhbmQgZWxlbWVudCB0eXBlLCB0aGlzIHByb2R1Y2VzIGEKKyAgICAvLy8gY29uY2F0ZW5hdGVkIHZlY3RvciByZXN1bHQgdmFsdWUsIHdpdGggbGVuZ3RoIGVxdWFsIHRvIHRoZSBzdW0gb2YgdGhlCisgICAgLy8vIGxlbmd0aHMgb2YgdGhlIGlucHV0IHZlY3RvcnMuCisgICAgQ09OQ0FUX1ZFQ1RPUlMsCisKKyAgICAvLy8gSU5TRVJUX1NVQlZFQ1RPUihWRUNUT1IxLCBWRUNUT1IyLCBJRFgpIC0gUmV0dXJucyBhIHZlY3RvcgorICAgIC8vLyB3aXRoIFZFQ1RPUjIgaW5zZXJ0ZWQgaW50byBWRUNUT1IxIGF0IHRoZSAocG90ZW50aWFsbHkKKyAgICAvLy8gdmFyaWFibGUpIGVsZW1lbnQgbnVtYmVyIElEWCwgd2hpY2ggbXVzdCBiZSBhIG11bHRpcGxlIG9mIHRoZQorICAgIC8vLyBWRUNUT1IyIHZlY3RvciBsZW5ndGguICBUaGUgZWxlbWVudHMgb2YgVkVDVE9SMSBzdGFydGluZyBhdAorICAgIC8vLyBJRFggYXJlIG92ZXJ3cml0dGVuIHdpdGggVkVDVE9SMi4gIEVsZW1lbnRzIElEWCB0aHJvdWdoCisgICAgLy8vIHZlY3Rvcl9sZW5ndGgoVkVDVE9SMikgbXVzdCBiZSB2YWxpZCBWRUNUT1IxIGluZGljZXMuCisgICAgSU5TRVJUX1NVQlZFQ1RPUiwKKworICAgIC8vLyBFWFRSQUNUX1NVQlZFQ1RPUihWRUNUT1IsIElEWCkgLSBSZXR1cm5zIGEgc3VidmVjdG9yIGZyb20gVkVDVE9SIChhbgorICAgIC8vLyB2ZWN0b3IgdmFsdWUpIHN0YXJ0aW5nIHdpdGggdGhlIGVsZW1lbnQgbnVtYmVyIElEWCwgd2hpY2ggbXVzdCBiZSBhCisgICAgLy8vIGNvbnN0YW50IG11bHRpcGxlIG9mIHRoZSByZXN1bHQgdmVjdG9yIGxlbmd0aC4KKyAgICBFWFRSQUNUX1NVQlZFQ1RPUiwKKworICAgIC8vLyBWRUNUT1JfU0hVRkZMRShWRUMxLCBWRUMyKSAtIFJldHVybnMgYSB2ZWN0b3IsIG9mIHRoZSBzYW1lIHR5cGUgYXMKKyAgICAvLy8gVkVDMS9WRUMyLiAgQSBWRUNUT1JfU0hVRkZMRSBub2RlIGFsc28gY29udGFpbnMgYW4gYXJyYXkgb2YgY29uc3RhbnQgaW50CisgICAgLy8vIHZhbHVlcyB0aGF0IGluZGljYXRlIHdoaWNoIHZhbHVlIChvciB1bmRlZikgZWFjaCByZXN1bHQgZWxlbWVudCB3aWxsCisgICAgLy8vIGdldC4gIFRoZXNlIGNvbnN0YW50IGludHMgYXJlIGFjY2Vzc2libGUgdGhyb3VnaCB0aGUKKyAgICAvLy8gU2h1ZmZsZVZlY3RvclNETm9kZSBjbGFzcy4gIFRoaXMgaXMgcXVpdGUgc2ltaWxhciB0byB0aGUgQWx0aXZlYworICAgIC8vLyAndnBlcm0nIGluc3RydWN0aW9uLCBleGNlcHQgdGhhdCB0aGUgaW5kaWNlcyBtdXN0IGJlIGNvbnN0YW50cyBhbmQgYXJlCisgICAgLy8vIGluIHRlcm1zIG9mIHRoZSBlbGVtZW50IHNpemUgb2YgVkVDMS9WRUMyLCBub3QgaW4gdGVybXMgb2YgYnl0ZXMuCisgICAgVkVDVE9SX1NIVUZGTEUsCisKKyAgICAvLy8gU0NBTEFSX1RPX1ZFQ1RPUihWQUwpIC0gVGhpcyByZXByZXNlbnRzIHRoZSBvcGVyYXRpb24gb2YgbG9hZGluZyBhCisgICAgLy8vIHNjYWxhciB2YWx1ZSBpbnRvIGVsZW1lbnQgMCBvZiB0aGUgcmVzdWx0YW50IHZlY3RvciB0eXBlLiAgVGhlIHRvcAorICAgIC8vLyBlbGVtZW50cyAxIHRvIE4tMSBvZiB0aGUgTi1lbGVtZW50IHZlY3RvciBhcmUgdW5kZWZpbmVkLiAgVGhlIHR5cGUKKyAgICAvLy8gb2YgdGhlIG9wZXJhbmQgbXVzdCBtYXRjaCB0aGUgdmVjdG9yIGVsZW1lbnQgdHlwZSwgZXhjZXB0IHdoZW4gdGhleQorICAgIC8vLyBhcmUgaW50ZWdlciB0eXBlcy4gIEluIHRoaXMgY2FzZSB0aGUgb3BlcmFuZCBpcyBhbGxvd2VkIHRvIGJlIHdpZGVyCisgICAgLy8vIHRoYW4gdGhlIHZlY3RvciBlbGVtZW50IHR5cGUsIGFuZCBpcyBpbXBsaWNpdGx5IHRydW5jYXRlZCB0byBpdC4KKyAgICBTQ0FMQVJfVE9fVkVDVE9SLAorCisgICAgLy8vIE1VTEhVL01VTEhTIC0gTXVsdGlwbHkgaGlnaCAtIE11bHRpcGx5IHR3byBpbnRlZ2VycyBvZiB0eXBlIGlOLAorICAgIC8vLyBwcm9kdWNpbmcgYW4gdW5zaWduZWQvc2lnbmVkIHZhbHVlIG9mIHR5cGUgaVsyKk5dLCB0aGVuIHJldHVybiB0aGUgdG9wCisgICAgLy8vIHBhcnQuCisgICAgTVVMSFUsIE1VTEhTLAorCisgICAgLy8vIFtVU117TUlOL01BWH0gLSBCaW5hcnkgbWluaW11bSBvciBtYXhpbXVtIG9yIHNpZ25lZCBvciB1bnNpZ25lZAorICAgIC8vLyBpbnRlZ2Vycy4KKyAgICBTTUlOLCBTTUFYLCBVTUlOLCBVTUFYLAorCisgICAgLy8vIEJpdHdpc2Ugb3BlcmF0b3JzIC0gbG9naWNhbCBhbmQsIGxvZ2ljYWwgb3IsIGxvZ2ljYWwgeG9yLgorICAgIEFORCwgT1IsIFhPUiwKKworICAgIC8vLyBBQlMgLSBEZXRlcm1pbmUgdGhlIHVuc2lnbmVkIGFic29sdXRlIHZhbHVlIG9mIGEgc2lnbmVkIGludGVnZXIgdmFsdWUgb2YKKyAgICAvLy8gdGhlIHNhbWUgYml0d2lkdGguCisgICAgLy8vIE5vdGU6IEEgdmFsdWUgb2YgSU5UX01JTiB3aWxsIHJldHVybiBJTlRfTUlOLCBubyBzYXR1cmF0aW9uIG9yIG92ZXJmbG93CisgICAgLy8vIGlzIHBlcmZvcm1lZC4KKyAgICBBQlMsCisKKyAgICAvLy8gU2hpZnQgYW5kIHJvdGF0aW9uIG9wZXJhdGlvbnMuICBBZnRlciBsZWdhbGl6YXRpb24sIHRoZSB0eXBlIG9mIHRoZQorICAgIC8vLyBzaGlmdCBhbW91bnQgaXMga25vd24gdG8gYmUgVExJLmdldFNoaWZ0QW1vdW50VHkoKS4gIEJlZm9yZSBsZWdhbGl6YXRpb24KKyAgICAvLy8gdGhlIHNoaWZ0IGFtb3VudCBjYW4gYmUgYW55IHR5cGUsIGJ1dCBjYXJlIG11c3QgYmUgdGFrZW4gdG8gZW5zdXJlIGl0IGlzCisgICAgLy8vIGxhcmdlIGVub3VnaC4gIFRMSS5nZXRTaGlmdEFtb3VudFR5KCkgaXMgaTggb24gc29tZSB0YXJnZXRzLCBidXQgYmVmb3JlCisgICAgLy8vIGxlZ2FsaXphdGlvbiwgdHlwZXMgbGlrZSBpMTAyNCBjYW4gb2NjdXIgYW5kIGk4IGRvZXNuJ3QgaGF2ZSBlbm91Z2ggYml0cworICAgIC8vLyB0byByZXByZXNlbnQgdGhlIHNoaWZ0IGFtb3VudC4KKyAgICAvLy8gV2hlbiB0aGUgMXN0IG9wZXJhbmQgaXMgYSB2ZWN0b3IsIHRoZSBzaGlmdCBhbW91bnQgbXVzdCBiZSBpbiB0aGUgc2FtZQorICAgIC8vLyB0eXBlLiAoVExJLmdldFNoaWZ0QW1vdW50VHkoKSB3aWxsIHJldHVybiB0aGUgc2FtZSB0eXBlIHdoZW4gdGhlIGlucHV0CisgICAgLy8vIHR5cGUgaXMgYSB2ZWN0b3IuKQorICAgIFNITCwgU1JBLCBTUkwsIFJPVEwsIFJPVFIsCisKKyAgICAvLy8gQnl0ZSBTd2FwIGFuZCBDb3VudGluZyBvcGVyYXRvcnMuCisgICAgQlNXQVAsIENUVFosIENUTFosIENUUE9QLCBCSVRSRVZFUlNFLAorCisgICAgLy8vIEJpdCBjb3VudGluZyBvcGVyYXRvcnMgd2l0aCBhbiB1bmRlZmluZWQgcmVzdWx0IGZvciB6ZXJvIGlucHV0cy4KKyAgICBDVFRaX1pFUk9fVU5ERUYsIENUTFpfWkVST19VTkRFRiwKKworICAgIC8vLyBTZWxlY3QoQ09ORCwgVFJVRVZBTCwgRkFMU0VWQUwpLiAgSWYgdGhlIHR5cGUgb2YgdGhlIGJvb2xlYW4gQ09ORCBpcyBub3QKKyAgICAvLy8gaTEgdGhlbiB0aGUgaGlnaCBiaXRzIG11c3QgY29uZm9ybSB0byBnZXRCb29sZWFuQ29udGVudHMuCisgICAgU0VMRUNULAorCisgICAgLy8vIFNlbGVjdCB3aXRoIGEgdmVjdG9yIGNvbmRpdGlvbiAob3AgIzApIGFuZCB0d28gdmVjdG9yIG9wZXJhbmRzIChvcHMgIzEKKyAgICAvLy8gYW5kICMyKSwgcmV0dXJuaW5nIGEgdmVjdG9yIHJlc3VsdC4gIEFsbCB2ZWN0b3JzIGhhdmUgdGhlIHNhbWUgbGVuZ3RoLgorICAgIC8vLyBNdWNoIGxpa2UgdGhlIHNjYWxhciBzZWxlY3QgYW5kIHNldGNjLCBlYWNoIGJpdCBpbiB0aGUgY29uZGl0aW9uIHNlbGVjdHMKKyAgICAvLy8gd2hldGhlciB0aGUgY29ycmVzcG9uZGluZyByZXN1bHQgZWxlbWVudCBpcyB0YWtlbiBmcm9tIG9wICMxIG9yIG9wICMyLgorICAgIC8vLyBBdCBmaXJzdCwgdGhlIFZTRUxFQ1QgY29uZGl0aW9uIGlzIG9mIHZYaTEgdHlwZS4gTGF0ZXIsIHRhcmdldHMgbWF5CisgICAgLy8vIGNoYW5nZSB0aGUgY29uZGl0aW9uIHR5cGUgaW4gb3JkZXIgdG8gbWF0Y2ggdGhlIFZTRUxFQ1Qgbm9kZSB1c2luZyBhCisgICAgLy8vIHBhdHRlcm4uIFRoZSBjb25kaXRpb24gZm9sbG93cyB0aGUgQm9vbGVhbkNvbnRlbnQgZm9ybWF0IG9mIHRoZSB0YXJnZXQuCisgICAgVlNFTEVDVCwKKworICAgIC8vLyBTZWxlY3Qgd2l0aCBjb25kaXRpb24gb3BlcmF0b3IgLSBUaGlzIHNlbGVjdHMgYmV0d2VlbiBhIHRydWUgdmFsdWUgYW5kCisgICAgLy8vIGEgZmFsc2UgdmFsdWUgKG9wcyAjMiBhbmQgIzMpIGJhc2VkIG9uIHRoZSBib29sZWFuIHJlc3VsdCBvZiBjb21wYXJpbmcKKyAgICAvLy8gdGhlIGxocyBhbmQgcmhzIChvcHMgIzAgYW5kICMxKSBvZiBhIGNvbmRpdGlvbmFsIGV4cHJlc3Npb24gd2l0aCB0aGUKKyAgICAvLy8gY29uZGl0aW9uIGNvZGUgaW4gb3AgIzQsIGEgQ29uZENvZGVTRE5vZGUuCisgICAgU0VMRUNUX0NDLAorCisgICAgLy8vIFNldENDIG9wZXJhdG9yIC0gVGhpcyBldmFsdWF0ZXMgdG8gYSB0cnVlIHZhbHVlIGlmZiB0aGUgY29uZGl0aW9uIGlzCisgICAgLy8vIHRydWUuICBJZiB0aGUgcmVzdWx0IHZhbHVlIHR5cGUgaXMgbm90IGkxIHRoZW4gdGhlIGhpZ2ggYml0cyBjb25mb3JtCisgICAgLy8vIHRvIGdldEJvb2xlYW5Db250ZW50cy4gIFRoZSBvcGVyYW5kcyB0byB0aGlzIGFyZSB0aGUgbGVmdCBhbmQgcmlnaHQKKyAgICAvLy8gb3BlcmFuZHMgdG8gY29tcGFyZSAob3BzICMwLCBhbmQgIzEpIGFuZCB0aGUgY29uZGl0aW9uIGNvZGUgdG8gY29tcGFyZQorICAgIC8vLyB0aGVtIHdpdGggKG9wICMyKSBhcyBhIENvbmRDb2RlU0ROb2RlLiBJZiB0aGUgb3BlcmFuZHMgYXJlIHZlY3RvciB0eXBlcworICAgIC8vLyB0aGVuIHRoZSByZXN1bHQgdHlwZSBtdXN0IGFsc28gYmUgYSB2ZWN0b3IgdHlwZS4KKyAgICBTRVRDQywKKworICAgIC8vLyBMaWtlIFNldENDLCBvcHMgIzAgYW5kICMxIGFyZSB0aGUgTEhTIGFuZCBSSFMgb3BlcmFuZHMgdG8gY29tcGFyZSwgYW5kCisgICAgLy8vIG9wICMyIGlzIGEgKmNhcnJ5IHZhbHVlKi4gVGhpcyBvcGVyYXRvciBjaGVja3MgdGhlIHJlc3VsdCBvZgorICAgIC8vLyAiTEhTIC0gUkhTIC0gQ2FycnkiLCBhbmQgY2FuIGJlIHVzZWQgdG8gY29tcGFyZSB0d28gd2lkZSBpbnRlZ2VyczoKKyAgICAvLy8gKHNldGNjZSBsaHNoaSByaHNoaSAoc3ViYyBsaHNsbyByaHNsbykgY2MpLiBPbmx5IHZhbGlkIGZvciBpbnRlZ2Vycy4KKyAgICAvLy8gRklYTUU6IFRoaXMgbm9kZSBpcyBkZXByZWNhdGVkIGluIGZhdm9yIG9mIFNFVENDQ0FSUlkuCisgICAgLy8vIEl0IGlzIGtlcHQgYXJvdW5kIGZvciBub3cgdG8gcHJvdmlkZSBhIHNtb290aCB0cmFuc2l0aW9uIHBhdGgKKyAgICAvLy8gdG93YXJkIHRoZSB1c2Ugb2YgU0VUQ0NDQVJSWSBhbmQgd2lsbCBldmVudHVhbGx5IGJlIHJlbW92ZWQuCisgICAgU0VUQ0NFLAorCisgICAgLy8vIExpa2UgU2V0Q0MsIG9wcyAjMCBhbmQgIzEgYXJlIHRoZSBMSFMgYW5kIFJIUyBvcGVyYW5kcyB0byBjb21wYXJlLCBidXQKKyAgICAvLy8gb3AgIzIgaXMgYSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlcmUgaXMgYW4gaW5jb21pbmcgY2FycnkuIFRoaXMKKyAgICAvLy8gb3BlcmF0b3IgY2hlY2tzIHRoZSByZXN1bHQgb2YgIkxIUyAtIFJIUyAtIENhcnJ5IiwgYW5kIGNhbiBiZSB1c2VkIHRvCisgICAgLy8vIGNvbXBhcmUgdHdvIHdpZGUgaW50ZWdlcnM6IChzZXRjY2UgbGhzaGkgcmhzaGkgKHN1YmMgbGhzbG8gcmhzbG8pIGNjKS4KKyAgICAvLy8gT25seSB2YWxpZCBmb3IgaW50ZWdlcnMuCisgICAgU0VUQ0NDQVJSWSwKKworICAgIC8vLyBTSExfUEFSVFMvU1JBX1BBUlRTL1NSTF9QQVJUUyAtIFRoZXNlIG9wZXJhdG9ycyBhcmUgdXNlZCBmb3IgZXhwYW5kZWQKKyAgICAvLy8gaW50ZWdlciBzaGlmdCBvcGVyYXRpb25zLiAgVGhlIG9wZXJhdGlvbiBvcmRlcmluZyBpczoKKyAgICAvLy8gICAgICAgW0xvLEhpXSA9IG9wIFtMb0xIUyxIaUxIU10sIEFtdAorICAgIFNITF9QQVJUUywgU1JBX1BBUlRTLCBTUkxfUEFSVFMsCisKKyAgICAvLy8gQ29udmVyc2lvbiBvcGVyYXRvcnMuICBUaGVzZSBhcmUgYWxsIHNpbmdsZSBpbnB1dCBzaW5nbGUgb3V0cHV0CisgICAgLy8vIG9wZXJhdGlvbnMuICBGb3IgYWxsIG9mIHRoZXNlLCB0aGUgcmVzdWx0IHR5cGUgbXVzdCBiZSBzdHJpY3RseQorICAgIC8vLyB3aWRlciBvciBuYXJyb3dlciAoZGVwZW5kaW5nIG9uIHRoZSBvcGVyYXRpb24pIHRoYW4gdGhlIHNvdXJjZQorICAgIC8vLyB0eXBlLgorCisgICAgLy8vIFNJR05fRVhURU5EIC0gVXNlZCBmb3IgaW50ZWdlciB0eXBlcywgcmVwbGljYXRpbmcgdGhlIHNpZ24gYml0CisgICAgLy8vIGludG8gbmV3IGJpdHMuCisgICAgU0lHTl9FWFRFTkQsCisKKyAgICAvLy8gWkVST19FWFRFTkQgLSBVc2VkIGZvciBpbnRlZ2VyIHR5cGVzLCB6ZXJvaW5nIHRoZSBuZXcgYml0cy4KKyAgICBaRVJPX0VYVEVORCwKKworICAgIC8vLyBBTllfRVhURU5EIC0gVXNlZCBmb3IgaW50ZWdlciB0eXBlcy4gIFRoZSBoaWdoIGJpdHMgYXJlIHVuZGVmaW5lZC4KKyAgICBBTllfRVhURU5ELAorCisgICAgLy8vIFRSVU5DQVRFIC0gQ29tcGxldGVseSBkcm9wIHRoZSBoaWdoIGJpdHMuCisgICAgVFJVTkNBVEUsCisKKyAgICAvLy8gW1NVXUlOVF9UT19GUCAtIFRoZXNlIG9wZXJhdG9ycyBjb252ZXJ0IGludGVnZXJzICh3aG9zZSBpbnRlcnByZXRlZCBzaWduCisgICAgLy8vIGRlcGVuZHMgb24gdGhlIGZpcnN0IGxldHRlcikgdG8gZmxvYXRpbmcgcG9pbnQuCisgICAgU0lOVF9UT19GUCwKKyAgICBVSU5UX1RPX0ZQLAorCisgICAgLy8vIFNJR05fRVhURU5EX0lOUkVHIC0gVGhpcyBvcGVyYXRvciBhdG9taWNhbGx5IHBlcmZvcm1zIGEgU0hML1NSQSBwYWlyIHRvCisgICAgLy8vIHNpZ24gZXh0ZW5kIGEgc21hbGwgdmFsdWUgaW4gYSBsYXJnZSBpbnRlZ2VyIHJlZ2lzdGVyIChlLmcuIHNpZ24KKyAgICAvLy8gZXh0ZW5kaW5nIHRoZSBsb3cgOCBiaXRzIG9mIGEgMzItYml0IHJlZ2lzdGVyIHRvIGZpbGwgdGhlIHRvcCAyNCBiaXRzCisgICAgLy8vIHdpdGggdGhlIDd0aCBiaXQpLiAgVGhlIHNpemUgb2YgdGhlIHNtYWxsZXIgdHlwZSBpcyBpbmRpY2F0ZWQgYnkgdGhlIDF0aAorICAgIC8vLyBvcGVyYW5kLCBhIFZhbHVlVHlwZSBub2RlLgorICAgIFNJR05fRVhURU5EX0lOUkVHLAorCisgICAgLy8vIEFOWV9FWFRFTkRfVkVDVE9SX0lOUkVHKFZlY3RvcikgLSBUaGlzIG9wZXJhdG9yIHJlcHJlc2VudHMgYW4KKyAgICAvLy8gaW4tcmVnaXN0ZXIgYW55LWV4dGVuc2lvbiBvZiB0aGUgbG93IGxhbmVzIG9mIGFuIGludGVnZXIgdmVjdG9yLiBUaGUKKyAgICAvLy8gcmVzdWx0IHR5cGUgbXVzdCBoYXZlIGZld2VyIGVsZW1lbnRzIHRoYW4gdGhlIG9wZXJhbmQgdHlwZSwgYW5kIHRob3NlCisgICAgLy8vIGVsZW1lbnRzIG11c3QgYmUgbGFyZ2VyIGludGVnZXIgdHlwZXMgc3VjaCB0aGF0IHRoZSB0b3RhbCBzaXplIG9mIHRoZQorICAgIC8vLyBvcGVyYW5kIHR5cGUgYW5kIHRoZSByZXN1bHQgdHlwZSBtYXRjaC4gRWFjaCBvZiB0aGUgbG93IG9wZXJhbmQKKyAgICAvLy8gZWxlbWVudHMgaXMgYW55LWV4dGVuZGVkIGludG8gdGhlIGNvcnJlc3BvbmRpbmcsIHdpZGVyIHJlc3VsdAorICAgIC8vLyBlbGVtZW50cyB3aXRoIHRoZSBoaWdoIGJpdHMgYmVjb21pbmcgdW5kZWYuCisgICAgQU5ZX0VYVEVORF9WRUNUT1JfSU5SRUcsCisKKyAgICAvLy8gU0lHTl9FWFRFTkRfVkVDVE9SX0lOUkVHKFZlY3RvcikgLSBUaGlzIG9wZXJhdG9yIHJlcHJlc2VudHMgYW4KKyAgICAvLy8gaW4tcmVnaXN0ZXIgc2lnbi1leHRlbnNpb24gb2YgdGhlIGxvdyBsYW5lcyBvZiBhbiBpbnRlZ2VyIHZlY3Rvci4gVGhlCisgICAgLy8vIHJlc3VsdCB0eXBlIG11c3QgaGF2ZSBmZXdlciBlbGVtZW50cyB0aGFuIHRoZSBvcGVyYW5kIHR5cGUsIGFuZCB0aG9zZQorICAgIC8vLyBlbGVtZW50cyBtdXN0IGJlIGxhcmdlciBpbnRlZ2VyIHR5cGVzIHN1Y2ggdGhhdCB0aGUgdG90YWwgc2l6ZSBvZiB0aGUKKyAgICAvLy8gb3BlcmFuZCB0eXBlIGFuZCB0aGUgcmVzdWx0IHR5cGUgbWF0Y2guIEVhY2ggb2YgdGhlIGxvdyBvcGVyYW5kCisgICAgLy8vIGVsZW1lbnRzIGlzIHNpZ24tZXh0ZW5kZWQgaW50byB0aGUgY29ycmVzcG9uZGluZywgd2lkZXIgcmVzdWx0CisgICAgLy8vIGVsZW1lbnRzLgorICAgIC8vIEZJWE1FOiBUaGUgU0lHTl9FWFRFTkRfSU5SRUcgbm9kZSBpc24ndCBzcGVjaWZpY2FsbHkgbGltaXRlZCB0bworICAgIC8vIHNjYWxhcnMsIGJ1dCBpdCBhbHNvIGRvZXNuJ3QgaGFuZGxlIHZlY3RvcnMgd2VsbC4gRWl0aGVyIGl0IHNob3VsZCBiZQorICAgIC8vIHJlc3RyaWN0ZWQgdG8gc2NhbGFycyBvciB0aGlzIG5vZGUgKGFuZCBpdHMgaGFuZGxpbmcpIHNob3VsZCBiZSBtZXJnZWQKKyAgICAvLyBpbnRvIGl0LgorICAgIFNJR05fRVhURU5EX1ZFQ1RPUl9JTlJFRywKKworICAgIC8vLyBaRVJPX0VYVEVORF9WRUNUT1JfSU5SRUcoVmVjdG9yKSAtIFRoaXMgb3BlcmF0b3IgcmVwcmVzZW50cyBhbgorICAgIC8vLyBpbi1yZWdpc3RlciB6ZXJvLWV4dGVuc2lvbiBvZiB0aGUgbG93IGxhbmVzIG9mIGFuIGludGVnZXIgdmVjdG9yLiBUaGUKKyAgICAvLy8gcmVzdWx0IHR5cGUgbXVzdCBoYXZlIGZld2VyIGVsZW1lbnRzIHRoYW4gdGhlIG9wZXJhbmQgdHlwZSwgYW5kIHRob3NlCisgICAgLy8vIGVsZW1lbnRzIG11c3QgYmUgbGFyZ2VyIGludGVnZXIgdHlwZXMgc3VjaCB0aGF0IHRoZSB0b3RhbCBzaXplIG9mIHRoZQorICAgIC8vLyBvcGVyYW5kIHR5cGUgYW5kIHRoZSByZXN1bHQgdHlwZSBtYXRjaC4gRWFjaCBvZiB0aGUgbG93IG9wZXJhbmQKKyAgICAvLy8gZWxlbWVudHMgaXMgemVyby1leHRlbmRlZCBpbnRvIHRoZSBjb3JyZXNwb25kaW5nLCB3aWRlciByZXN1bHQKKyAgICAvLy8gZWxlbWVudHMuCisgICAgWkVST19FWFRFTkRfVkVDVE9SX0lOUkVHLAorCisgICAgLy8vIEZQX1RPX1tVU11JTlQgLSBDb252ZXJ0IGEgZmxvYXRpbmcgcG9pbnQgdmFsdWUgdG8gYSBzaWduZWQgb3IgdW5zaWduZWQKKyAgICAvLy8gaW50ZWdlci4KKyAgICBGUF9UT19TSU5ULAorICAgIEZQX1RPX1VJTlQsCisKKyAgICAvLy8gWCA9IEZQX1JPVU5EKFksIFRSVU5DKSAtIFJvdW5kaW5nICdZJyBmcm9tIGEgbGFyZ2VyIGZsb2F0aW5nIHBvaW50IHR5cGUKKyAgICAvLy8gZG93biB0byB0aGUgcHJlY2lzaW9uIG9mIHRoZSBkZXN0aW5hdGlvbiBWVC4gIFRSVU5DIGlzIGEgZmxhZywgd2hpY2ggaXMKKyAgICAvLy8gYWx3YXlzIGFuIGludGVnZXIgdGhhdCBpcyB6ZXJvIG9yIG9uZS4gIElmIFRSVU5DIGlzIDAsIHRoaXMgaXMgYQorICAgIC8vLyBub3JtYWwgcm91bmRpbmcsIGlmIGl0IGlzIDEsIHRoaXMgRlBfUk9VTkQgaXMga25vd24gdG8gbm90IGNoYW5nZSB0aGUKKyAgICAvLy8gdmFsdWUgb2YgWS4KKyAgICAvLy8KKyAgICAvLy8gVGhlIFRSVU5DID0gMSBjYXNlIGlzIHVzZWQgaW4gY2FzZXMgd2hlcmUgd2Uga25vdyB0aGF0IHRoZSB2YWx1ZSB3aWxsCisgICAgLy8vIG5vdCBiZSBtb2RpZmllZCBieSB0aGUgbm9kZSwgYmVjYXVzZSBZIGlzIG5vdCB1c2luZyBhbnkgb2YgdGhlIGV4dHJhCisgICAgLy8vIHByZWNpc2lvbiBvZiBzb3VyY2UgdHlwZS4gIFRoaXMgYWxsb3dzIGNlcnRhaW4gdHJhbnNmb3JtYXRpb25zIGxpa2UKKyAgICAvLy8gRlBfRVhURU5EKEZQX1JPVU5EKFgsMSkpIC0+IFggd2hpY2ggYXJlIG5vdCBzYWZlIGZvcgorICAgIC8vLyBGUF9FWFRFTkQoRlBfUk9VTkQoWCwwKSkgYmVjYXVzZSB0aGUgZXh0cmEgYml0cyBhcmVuJ3QgcmVtb3ZlZC4KKyAgICBGUF9ST1VORCwKKworICAgIC8vLyBGTFRfUk9VTkRTXyAtIFJldHVybnMgY3VycmVudCByb3VuZGluZyBtb2RlOgorICAgIC8vLyAtMSBVbmRlZmluZWQKKyAgICAvLy8gIDAgUm91bmQgdG8gMAorICAgIC8vLyAgMSBSb3VuZCB0byBuZWFyZXN0CisgICAgLy8vICAyIFJvdW5kIHRvICtpbmYKKyAgICAvLy8gIDMgUm91bmQgdG8gLWluZgorICAgIEZMVF9ST1VORFNfLAorCisgICAgLy8vIFggPSBGUF9ST1VORF9JTlJFRyhZLCBWVCkgLSBUaGlzIG9wZXJhdG9yIHRha2VzIGFuIEZQIHJlZ2lzdGVyLCBhbmQKKyAgICAvLy8gcm91bmRzIGl0IHRvIGEgZmxvYXRpbmcgcG9pbnQgdmFsdWUuICBJdCB0aGVuIHByb21vdGVzIGl0IGFuZCByZXR1cm5zIGl0CisgICAgLy8vIGluIGEgcmVnaXN0ZXIgb2YgdGhlIHNhbWUgc2l6ZS4gIFRoaXMgb3BlcmF0aW9uIGVmZmVjdGl2ZWx5IGp1c3QKKyAgICAvLy8gZGlzY2FyZHMgZXhjZXNzIHByZWNpc2lvbi4gIFRoZSB0eXBlIHRvIHJvdW5kIGRvd24gdG8gaXMgc3BlY2lmaWVkIGJ5CisgICAgLy8vIHRoZSBWVCBvcGVyYW5kLCBhIFZUU0ROb2RlLgorICAgIEZQX1JPVU5EX0lOUkVHLAorCisgICAgLy8vIFggPSBGUF9FWFRFTkQoWSkgLSBFeHRlbmQgYSBzbWFsbGVyIEZQIHR5cGUgaW50byBhIGxhcmdlciBGUCB0eXBlLgorICAgIEZQX0VYVEVORCwKKworICAgIC8vLyBCSVRDQVNUIC0gVGhpcyBvcGVyYXRvciBjb252ZXJ0cyBiZXR3ZWVuIGludGVnZXIsIHZlY3RvciBhbmQgRlAKKyAgICAvLy8gdmFsdWVzLCBhcyBpZiB0aGUgdmFsdWUgd2FzIHN0b3JlZCB0byBtZW1vcnkgd2l0aCBvbmUgdHlwZSBhbmQgbG9hZGVkCisgICAgLy8vIGZyb20gdGhlIHNhbWUgYWRkcmVzcyB3aXRoIHRoZSBvdGhlciB0eXBlIChvciBlcXVpdmFsZW50bHkgZm9yIHZlY3RvcgorICAgIC8vLyBmb3JtYXQgY29udmVyc2lvbnMsIGV0YykuICBUaGUgc291cmNlIGFuZCByZXN1bHQgYXJlIHJlcXVpcmVkIHRvIGhhdmUKKyAgICAvLy8gdGhlIHNhbWUgYml0IHNpemUgKGUuZy4gIGYzMiA8LT4gaTMyKS4gIFRoaXMgY2FuIGFsc28gYmUgdXNlZCBmb3IKKyAgICAvLy8gaW50LXRvLWludCBvciBmcC10by1mcCBjb252ZXJzaW9ucywgYnV0IHRoYXQgaXMgYSBub29wLCBkZWxldGVkIGJ5CisgICAgLy8vIGdldE5vZGUoKS4KKyAgICAvLy8KKyAgICAvLy8gVGhpcyBvcGVyYXRvciBpcyBzdWJ0bHkgZGlmZmVyZW50IGZyb20gdGhlIGJpdGNhc3QgaW5zdHJ1Y3Rpb24gZnJvbQorICAgIC8vLyBMTFZNLUlSIHNpbmNlIHRoaXMgbm9kZSBtYXkgY2hhbmdlIHRoZSBiaXRzIGluIHRoZSByZWdpc3Rlci4gRm9yCisgICAgLy8vIGV4YW1wbGUsIHRoaXMgb2NjdXJzIG9uIGJpZy1lbmRpYW4gTkVPTiBhbmQgYmlnLWVuZGlhbiBNU0Egd2hlcmUgdGhlCisgICAgLy8vIGxheW91dCBvZiB0aGUgYml0cyBpbiB0aGUgcmVnaXN0ZXIgZGVwZW5kcyBvbiB0aGUgdmVjdG9yIHR5cGUgYW5kIHRoaXMKKyAgICAvLy8gb3BlcmF0b3IgYWN0cyBhcyBhIHNodWZmbGUgb3BlcmF0aW9uIGZvciBzb21lIHZlY3RvciB0eXBlIGNvbWJpbmF0aW9ucy4KKyAgICBCSVRDQVNULAorCisgICAgLy8vIEFERFJTUEFDRUNBU1QgLSBUaGlzIG9wZXJhdG9yIGNvbnZlcnRzIGJldHdlZW4gcG9pbnRlcnMgb2YgZGlmZmVyZW50CisgICAgLy8vIGFkZHJlc3Mgc3BhY2VzLgorICAgIEFERFJTUEFDRUNBU1QsCisKKyAgICAvLy8gRlAxNl9UT19GUCwgRlBfVE9fRlAxNiAtIFRoZXNlIG9wZXJhdG9ycyBhcmUgdXNlZCB0byBwZXJmb3JtIHByb21vdGlvbnMKKyAgICAvLy8gYW5kIHRydW5jYXRpb24gZm9yIGhhbGYtcHJlY2lzaW9uICgxNiBiaXQpIGZsb2F0aW5nIG51bWJlcnMuIFRoZXNlIG5vZGVzCisgICAgLy8vIGZvcm0gYSBzZW1pLXNvZnRlbmVkIGludGVyZmFjZSBmb3IgZGVhbGluZyB3aXRoIGYxNiAoYXMgYW4gaTE2KSwgd2hpY2gKKyAgICAvLy8gaXMgb2Z0ZW4gYSBzdG9yYWdlLW9ubHkgdHlwZSBidXQgaGFzIG5hdGl2ZSBjb252ZXJzaW9ucy4KKyAgICBGUDE2X1RPX0ZQLCBGUF9UT19GUDE2LAorCisgICAgLy8vIEZORUcsIEZBQlMsIEZTUVJULCBGU0lOLCBGQ09TLCBGUE9XSSwgRlBPVywKKyAgICAvLy8gRkxPRywgRkxPRzIsIEZMT0cxMCwgRkVYUCwgRkVYUDIsCisgICAgLy8vIEZDRUlMLCBGVFJVTkMsIEZSSU5ULCBGTkVBUkJZSU5ULCBGUk9VTkQsIEZGTE9PUiAtIFBlcmZvcm0gdmFyaW91cyB1bmFyeQorICAgIC8vLyBmbG9hdGluZyBwb2ludCBvcGVyYXRpb25zLiBUaGVzZSBhcmUgaW5zcGlyZWQgYnkgbGlibS4KKyAgICBGTkVHLCBGQUJTLCBGU1FSVCwgRlNJTiwgRkNPUywgRlBPV0ksIEZQT1csCisgICAgRkxPRywgRkxPRzIsIEZMT0cxMCwgRkVYUCwgRkVYUDIsCisgICAgRkNFSUwsIEZUUlVOQywgRlJJTlQsIEZORUFSQllJTlQsIEZST1VORCwgRkZMT09SLAorICAgIC8vLyBGTUlOTlVNL0ZNQVhOVU0gLSBQZXJmb3JtIGZsb2F0aW5nLXBvaW50IG1pbmltdW0gb3IgbWF4aW11bSBvbiB0d28KKyAgICAvLy8gdmFsdWVzLgorICAgIC8vLyBJbiB0aGUgY2FzZSB3aGVyZSBhIHNpbmdsZSBpbnB1dCBpcyBOYU4sIHRoZSBub24tTmFOIGlucHV0IGlzIHJldHVybmVkLgorICAgIC8vLworICAgIC8vLyBUaGUgcmV0dXJuIHZhbHVlIG9mIChGTUlOTlVNIDAuMCwgLTAuMCkgY291bGQgYmUgZWl0aGVyIDAuMCBvciAtMC4wLgorICAgIEZNSU5OVU0sIEZNQVhOVU0sCisgICAgLy8vIEZNSU5OQU4vRk1BWE5BTiAtIEJlaGF2ZSBpZGVudGljYWxseSB0byBGTUlOTlVNL0ZNQVhOVU0sIGV4Y2VwdCB0aGF0CisgICAgLy8vIHdoZW4gYSBzaW5nbGUgaW5wdXQgaXMgTmFOLCBOYU4gaXMgcmV0dXJuZWQuCisgICAgRk1JTk5BTiwgRk1BWE5BTiwKKworICAgIC8vLyBGU0lOQ09TIC0gQ29tcHV0ZSBib3RoIGZzaW4gYW5kIGZjb3MgYXMgYSBzaW5nbGUgb3BlcmF0aW9uLgorICAgIEZTSU5DT1MsCisKKyAgICAvLy8gTE9BRCBhbmQgU1RPUkUgaGF2ZSB0b2tlbiBjaGFpbnMgYXMgdGhlaXIgZmlyc3Qgb3BlcmFuZCwgdGhlbiB0aGUgc2FtZQorICAgIC8vLyBvcGVyYW5kcyBhcyBhbiBMTFZNIGxvYWQvc3RvcmUgaW5zdHJ1Y3Rpb24sIHRoZW4gYW4gb2Zmc2V0IG5vZGUgdGhhdAorICAgIC8vLyBpcyBhZGRlZCAvIHN1YnRyYWN0ZWQgZnJvbSB0aGUgYmFzZSBwb2ludGVyIHRvIGZvcm0gdGhlIGFkZHJlc3MgKGZvcgorICAgIC8vLyBpbmRleGVkIG1lbW9yeSBvcHMpLgorICAgIExPQUQsIFNUT1JFLAorCisgICAgLy8vIERZTkFNSUNfU1RBQ0tBTExPQyAtIEFsbG9jYXRlIHNvbWUgbnVtYmVyIG9mIGJ5dGVzIG9uIHRoZSBzdGFjayBhbGlnbmVkCisgICAgLy8vIHRvIGEgc3BlY2lmaWVkIGJvdW5kYXJ5LiAgVGhpcyBub2RlIGFsd2F5cyBoYXMgdHdvIHJldHVybiB2YWx1ZXM6IGEgbmV3CisgICAgLy8vIHN0YWNrIHBvaW50ZXIgdmFsdWUgYW5kIGEgY2hhaW4uIFRoZSBmaXJzdCBvcGVyYW5kIGlzIHRoZSB0b2tlbiBjaGFpbiwKKyAgICAvLy8gdGhlIHNlY29uZCBpcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGFsbG9jYXRlLCBhbmQgdGhlIHRoaXJkIGlzIHRoZQorICAgIC8vLyBhbGlnbm1lbnQgYm91bmRhcnkuICBUaGUgc2l6ZSBpcyBndWFyYW50ZWVkIHRvIGJlIGEgbXVsdGlwbGUgb2YgdGhlCisgICAgLy8vIHN0YWNrIGFsaWdubWVudCwgYW5kIHRoZSBhbGlnbm1lbnQgaXMgZ3VhcmFudGVlZCB0byBiZSBiaWdnZXIgdGhhbiB0aGUKKyAgICAvLy8gc3RhY2sgYWxpZ25tZW50IChpZiByZXF1aXJlZCkgb3IgMCB0byBnZXQgc3RhbmRhcmQgc3RhY2sgYWxpZ25tZW50LgorICAgIERZTkFNSUNfU1RBQ0tBTExPQywKKworICAgIC8vLyBDb250cm9sIGZsb3cgaW5zdHJ1Y3Rpb25zLiAgVGhlc2UgYWxsIGhhdmUgdG9rZW4gY2hhaW5zLgorCisgICAgLy8vIEJSIC0gVW5jb25kaXRpb25hbCBicmFuY2guICBUaGUgZmlyc3Qgb3BlcmFuZCBpcyB0aGUgY2hhaW4KKyAgICAvLy8gb3BlcmFuZCwgdGhlIHNlY29uZCBpcyB0aGUgTUJCIHRvIGJyYW5jaCB0by4KKyAgICBCUiwKKworICAgIC8vLyBCUklORCAtIEluZGlyZWN0IGJyYW5jaC4gIFRoZSBmaXJzdCBvcGVyYW5kIGlzIHRoZSBjaGFpbiwgdGhlIHNlY29uZAorICAgIC8vLyBpcyB0aGUgdmFsdWUgdG8gYnJhbmNoIHRvLCB3aGljaCBtdXN0IGJlIG9mIHRoZSBzYW1lIHR5cGUgYXMgdGhlCisgICAgLy8vIHRhcmdldCdzIHBvaW50ZXIgdHlwZS4KKyAgICBCUklORCwKKworICAgIC8vLyBCUl9KVCAtIEp1bXB0YWJsZSBicmFuY2guIFRoZSBmaXJzdCBvcGVyYW5kIGlzIHRoZSBjaGFpbiwgdGhlIHNlY29uZAorICAgIC8vLyBpcyB0aGUganVtcHRhYmxlIGluZGV4LCB0aGUgbGFzdCBvbmUgaXMgdGhlIGp1bXB0YWJsZSBlbnRyeSBpbmRleC4KKyAgICBCUl9KVCwKKworICAgIC8vLyBCUkNPTkQgLSBDb25kaXRpb25hbCBicmFuY2guICBUaGUgZmlyc3Qgb3BlcmFuZCBpcyB0aGUgY2hhaW4sIHRoZQorICAgIC8vLyBzZWNvbmQgaXMgdGhlIGNvbmRpdGlvbiwgdGhlIHRoaXJkIGlzIHRoZSBibG9jayB0byBicmFuY2ggdG8gaWYgdGhlCisgICAgLy8vIGNvbmRpdGlvbiBpcyB0cnVlLiAgSWYgdGhlIHR5cGUgb2YgdGhlIGNvbmRpdGlvbiBpcyBub3QgaTEsIHRoZW4gdGhlCisgICAgLy8vIGhpZ2ggYml0cyBtdXN0IGNvbmZvcm0gdG8gZ2V0Qm9vbGVhbkNvbnRlbnRzLgorICAgIEJSQ09ORCwKKworICAgIC8vLyBCUl9DQyAtIENvbmRpdGlvbmFsIGJyYW5jaC4gIFRoZSBiZWhhdmlvciBpcyBsaWtlIHRoYXQgb2YgU0VMRUNUX0NDLCBpbgorICAgIC8vLyB0aGF0IHRoZSBjb25kaXRpb24gaXMgcmVwcmVzZW50ZWQgYXMgY29uZGl0aW9uIGNvZGUsIGFuZCB0d28gbm9kZXMgdG8KKyAgICAvLy8gY29tcGFyZSwgcmF0aGVyIHRoYW4gYXMgYSBjb21iaW5lZCBTZXRDQyBub2RlLiAgVGhlIG9wZXJhbmRzIGluIG9yZGVyCisgICAgLy8vIGFyZSBjaGFpbiwgY2MsIGxocywgcmhzLCBibG9jayB0byBicmFuY2ggdG8gaWYgY29uZGl0aW9uIGlzIHRydWUuCisgICAgQlJfQ0MsCisKKyAgICAvLy8gSU5MSU5FQVNNIC0gUmVwcmVzZW50cyBhbiBpbmxpbmUgYXNtIGJsb2NrLiAgVGhpcyBub2RlIGFsd2F5cyBoYXMgdHdvCisgICAgLy8vIHJldHVybiB2YWx1ZXM6IGEgY2hhaW4gYW5kIGEgZmxhZyByZXN1bHQuICBUaGUgaW5wdXRzIGFyZSBhcyBmb2xsb3dzOgorICAgIC8vLyAgIE9wZXJhbmQgIzAgIDogSW5wdXQgY2hhaW4uCisgICAgLy8vICAgT3BlcmFuZCAjMSAgOiBhIEV4dGVybmFsU3ltYm9sU0ROb2RlIHdpdGggYSBwb2ludGVyIHRvIHRoZSBhc20gc3RyaW5nLgorICAgIC8vLyAgIE9wZXJhbmQgIzIgIDogYSBNRE5vZGVTRE5vZGUgd2l0aCB0aGUgIXNyY2xvYyBtZXRhZGF0YS4KKyAgICAvLy8gICBPcGVyYW5kICMzICA6IEhhc1NpZGVFZmZlY3QsIElzQWxpZ25TdGFjayBiaXRzLgorICAgIC8vLyAgIEFmdGVyIHRoaXMsIGl0IGlzIGZvbGxvd2VkIGJ5IGEgbGlzdCBvZiBvcGVyYW5kcyB3aXRoIHRoaXMgZm9ybWF0OgorICAgIC8vLyAgICAgQ29uc3RhbnRTRE5vZGU6IEZsYWdzIHRoYXQgZW5jb2RlIHdoZXRoZXIgaXQgaXMgYSBtZW0gb3Igbm90LCB0aGUKKyAgICAvLy8gICAgICAgICAgICAgICAgICAgICBvZiBvcGVyYW5kcyB0aGF0IGZvbGxvdywgZXRjLiAgU2VlIElubGluZUFzbS5oLgorICAgIC8vLyAgICAgLi4uIGhvd2V2ZXIgbWFueSBvcGVyYW5kcyAuLi4KKyAgICAvLy8gICBPcGVyYW5kICNsYXN0OiBPcHRpb25hbCwgYW4gaW5jb21pbmcgZmxhZy4KKyAgICAvLy8KKyAgICAvLy8gVGhlIHZhcmlhYmxlIHdpZHRoIG9wZXJhbmRzIGFyZSByZXF1aXJlZCB0byByZXByZXNlbnQgdGFyZ2V0IGFkZHJlc3NpbmcKKyAgICAvLy8gbW9kZXMgYXMgYSBzaW5nbGUgIm9wZXJhbmQiLCBldmVuIHRob3VnaCB0aGV5IG1heSBoYXZlIG11bHRpcGxlCisgICAgLy8vIFNET3BlcmFuZHMuCisgICAgSU5MSU5FQVNNLAorCisgICAgLy8vIEVIX0xBQkVMIC0gUmVwcmVzZW50cyBhIGxhYmVsIGluIG1pZCBiYXNpYyBibG9jayB1c2VkIHRvIHRyYWNrCisgICAgLy8vIGxvY2F0aW9ucyBuZWVkZWQgZm9yIGRlYnVnIGFuZCBleGNlcHRpb24gaGFuZGxpbmcgdGFibGVzLiAgVGhlc2Ugbm9kZXMKKyAgICAvLy8gdGFrZSBhIGNoYWluIGFzIGlucHV0IGFuZCByZXR1cm4gYSBjaGFpbi4KKyAgICBFSF9MQUJFTCwKKworICAgIC8vLyBBTk5PVEFUSU9OX0xBQkVMIC0gUmVwcmVzZW50cyBhIG1pZCBiYXNpYyBibG9jayBsYWJlbCB1c2VkIGJ5CisgICAgLy8vIGFubm90YXRpb25zLiBUaGlzIHNob3VsZCByZW1haW4gd2l0aGluIHRoZSBiYXNpYyBibG9jayBhbmQgYmUgb3JkZXJlZAorICAgIC8vLyB3aXRoIHJlc3BlY3QgdG8gb3RoZXIgY2FsbCBpbnN0cnVjdGlvbnMsIGJ1dCBsb2FkcyBhbmQgc3RvcmVzIG1heSBmbG9hdAorICAgIC8vLyBwYXN0IGl0LgorICAgIEFOTk9UQVRJT05fTEFCRUwsCisKKyAgICAvLy8gQ0FUQ0hQQUQgLSBSZXByZXNlbnRzIGEgY2F0Y2hwYWQgaW5zdHJ1Y3Rpb24uCisgICAgQ0FUQ0hQQUQsCisKKyAgICAvLy8gQ0FUQ0hSRVQgLSBSZXByZXNlbnRzIGEgcmV0dXJuIGZyb20gYSBjYXRjaCBibG9jayBmdW5jbGV0LiBVc2VkIGZvcgorICAgIC8vLyBNU1ZDIGNvbXBhdGlibGUgZXhjZXB0aW9uIGhhbmRsaW5nLiBUYWtlcyBhIGNoYWluIG9wZXJhbmQgYW5kIGEKKyAgICAvLy8gZGVzdGluYXRpb24gYmFzaWMgYmxvY2sgb3BlcmFuZC4KKyAgICBDQVRDSFJFVCwKKworICAgIC8vLyBDTEVBTlVQUkVUIC0gUmVwcmVzZW50cyBhIHJldHVybiBmcm9tIGEgY2xlYW51cCBibG9jayBmdW5jbGV0LiAgVXNlZCBmb3IKKyAgICAvLy8gTVNWQyBjb21wYXRpYmxlIGV4Y2VwdGlvbiBoYW5kbGluZy4gVGFrZXMgb25seSBhIGNoYWluIG9wZXJhbmQuCisgICAgQ0xFQU5VUFJFVCwKKworICAgIC8vLyBTVEFDS1NBVkUgLSBTVEFDS1NBVkUgaGFzIG9uZSBvcGVyYW5kLCBhbiBpbnB1dCBjaGFpbi4gIEl0IHByb2R1Y2VzIGEKKyAgICAvLy8gdmFsdWUsIHRoZSBzYW1lIHR5cGUgYXMgdGhlIHBvaW50ZXIgdHlwZSBmb3IgdGhlIHN5c3RlbSwgYW5kIGFuIG91dHB1dAorICAgIC8vLyBjaGFpbi4KKyAgICBTVEFDS1NBVkUsCisKKyAgICAvLy8gU1RBQ0tSRVNUT1JFIGhhcyB0d28gb3BlcmFuZHMsIGFuIGlucHV0IGNoYWluIGFuZCBhIHBvaW50ZXIgdG8gcmVzdG9yZQorICAgIC8vLyB0byBpdCByZXR1cm5zIGFuIG91dHB1dCBjaGFpbi4KKyAgICBTVEFDS1JFU1RPUkUsCisKKyAgICAvLy8gQ0FMTFNFUV9TVEFSVC9DQUxMU0VRX0VORCAtIFRoZXNlIG9wZXJhdG9ycyBtYXJrIHRoZSBiZWdpbm5pbmcgYW5kIGVuZAorICAgIC8vLyBvZiBhIGNhbGwgc2VxdWVuY2UsIGFuZCBjYXJyeSBhcmJpdHJhcnkgaW5mb3JtYXRpb24gdGhhdCB0YXJnZXQgbWlnaHQKKyAgICAvLy8gd2FudCB0byBrbm93LiAgVGhlIGZpcnN0IG9wZXJhbmQgaXMgYSBjaGFpbiwgdGhlIHJlc3QgYXJlIHNwZWNpZmllZCBieQorICAgIC8vLyB0aGUgdGFyZ2V0IGFuZCBub3QgdG91Y2hlZCBieSB0aGUgREFHIG9wdGltaXplcnMuCisgICAgLy8vIFRhcmdldHMgdGhhdCBtYXkgdXNlIHN0YWNrIHRvIHBhc3MgY2FsbCBhcmd1bWVudHMgZGVmaW5lIGFkZGl0aW9uYWwKKyAgICAvLy8gb3BlcmFuZHM6CisgICAgLy8vIC0gc2l6ZSBvZiB0aGUgY2FsbCBmcmFtZSBwYXJ0IHRoYXQgbXVzdCBiZSBzZXQgdXAgd2l0aGluIHRoZQorICAgIC8vLyAgIENBTExTRVFfU1RBUlQuLkNBTExTRVFfRU5EIHBhaXIsCisgICAgLy8vIC0gcGFydCBvZiB0aGUgY2FsbCBmcmFtZSBwcmVwYXJlZCBwcmlvciB0byBDQUxMU0VRX1NUQVJULgorICAgIC8vLyBCb3RoIHRoZXNlIHBhcmFtZXRlcnMgbXVzdCBiZSBjb25zdGFudHMsIHRoZWlyIHN1bSBpcyB0aGUgdG90YWwgY2FsbAorICAgIC8vLyBmcmFtZSBzaXplLgorICAgIC8vLyBDQUxMU0VRX1NUQVJULi5DQUxMU0VRX0VORCBwYWlycyBtYXkgbm90IGJlIG5lc3RlZC4KKyAgICBDQUxMU0VRX1NUQVJULCAgLy8gQmVnaW5uaW5nIG9mIGEgY2FsbCBzZXF1ZW5jZQorICAgIENBTExTRVFfRU5ELCAgICAvLyBFbmQgb2YgYSBjYWxsIHNlcXVlbmNlCisKKyAgICAvLy8gVkFBUkcgLSBWQUFSRyBoYXMgZm91ciBvcGVyYW5kczogYW4gaW5wdXQgY2hhaW4sIGEgcG9pbnRlciwgYSBTUkNWQUxVRSwKKyAgICAvLy8gYW5kIHRoZSBhbGlnbm1lbnQuIEl0IHJldHVybnMgYSBwYWlyIG9mIHZhbHVlczogdGhlIHZhYXJnIHZhbHVlIGFuZCBhCisgICAgLy8vIG5ldyBjaGFpbi4KKyAgICBWQUFSRywKKworICAgIC8vLyBWQUNPUFkgLSBWQUNPUFkgaGFzIDUgb3BlcmFuZHM6IGFuIGlucHV0IGNoYWluLCBhIGRlc3RpbmF0aW9uIHBvaW50ZXIsCisgICAgLy8vIGEgc291cmNlIHBvaW50ZXIsIGEgU1JDVkFMVUUgZm9yIHRoZSBkZXN0aW5hdGlvbiwgYW5kIGEgU1JDVkFMVUUgZm9yIHRoZQorICAgIC8vLyBzb3VyY2UuCisgICAgVkFDT1BZLAorCisgICAgLy8vIFZBRU5ELCBWQVNUQVJUIC0gVkFFTkQgYW5kIFZBU1RBUlQgaGF2ZSB0aHJlZSBvcGVyYW5kczogYW4gaW5wdXQgY2hhaW4sCisgICAgLy8vIHBvaW50ZXIsIGFuZCBhIFNSQ1ZBTFVFLgorICAgIFZBRU5ELCBWQVNUQVJULAorCisgICAgLy8vIFNSQ1ZBTFVFIC0gVGhpcyBpcyBhIG5vZGUgdHlwZSB0aGF0IGhvbGRzIGEgVmFsdWUqIHRoYXQgaXMgdXNlZCB0bworICAgIC8vLyBtYWtlIHJlZmVyZW5jZSB0byBhIHZhbHVlIGluIHRoZSBMTFZNIElSLgorICAgIFNSQ1ZBTFVFLAorCisgICAgLy8vIE1ETk9ERV9TRE5PREUgLSBUaGlzIGlzIGEgbm9kZSB0aGF0IGhvbGRlcyBhbiBNRE5vZGUqLCB3aGljaCBpcyB1c2VkIHRvCisgICAgLy8vIHJlZmVyZW5jZSBtZXRhZGF0YSBpbiB0aGUgSVIuCisgICAgTUROT0RFX1NETk9ERSwKKworICAgIC8vLyBQQ01BUktFUiAtIFRoaXMgY29ycmVzcG9uZHMgdG8gdGhlIHBjbWFya2VyIGludHJpbnNpYy4KKyAgICBQQ01BUktFUiwKKworICAgIC8vLyBSRUFEQ1lDTEVDT1VOVEVSIC0gVGhpcyBjb3JyZXNwb25kcyB0byB0aGUgcmVhZGN5Y2xlY291bnRlciBpbnRyaW5zaWMuCisgICAgLy8vIEl0IHByb2R1Y2VzIGEgY2hhaW4gYW5kIG9uZSBpNjQgdmFsdWUuIFRoZSBvbmx5IG9wZXJhbmQgaXMgYSBjaGFpbi4KKyAgICAvLy8gSWYgaTY0IGlzIG5vdCBsZWdhbCwgdGhlIHJlc3VsdCB3aWxsIGJlIGV4cGFuZGVkIGludG8gc21hbGxlciB2YWx1ZXMuCisgICAgLy8vIFN0aWxsLCBpdCByZXR1cm5zIGFuIGk2NCwgc28gdGFyZ2V0cyBzaG91bGQgc2V0IGxlZ2FsaXR5IGZvciBpNjQuCisgICAgLy8vIFRoZSByZXN1bHQgaXMgdGhlIGNvbnRlbnQgb2YgdGhlIGFyY2hpdGVjdHVyZS1zcGVjaWZpYyBjeWNsZQorICAgIC8vLyBjb3VudGVyLWxpa2UgcmVnaXN0ZXIgKG9yIG90aGVyIGhpZ2ggYWNjdXJhY3kgbG93IGxhdGVuY3kgY2xvY2sgc291cmNlKS4KKyAgICBSRUFEQ1lDTEVDT1VOVEVSLAorCisgICAgLy8vIEhBTkRMRU5PREUgbm9kZSAtIFVzZWQgYXMgYSBoYW5kbGUgZm9yIHZhcmlvdXMgcHVycG9zZXMuCisgICAgSEFORExFTk9ERSwKKworICAgIC8vLyBJTklUX1RSQU1QT0xJTkUgLSBUaGlzIGNvcnJlc3BvbmRzIHRvIHRoZSBpbml0X3RyYW1wb2xpbmUgaW50cmluc2ljLiAgSXQKKyAgICAvLy8gdGFrZXMgYXMgaW5wdXQgYSB0b2tlbiBjaGFpbiwgdGhlIHBvaW50ZXIgdG8gdGhlIHRyYW1wb2xpbmUsIHRoZSBwb2ludGVyCisgICAgLy8vIHRvIHRoZSBuZXN0ZWQgZnVuY3Rpb24sIHRoZSBwb2ludGVyIHRvIHBhc3MgZm9yIHRoZSAnbmVzdCcgcGFyYW1ldGVyLCBhCisgICAgLy8vIFNSQ1ZBTFVFIGZvciB0aGUgdHJhbXBvbGluZSBhbmQgYW5vdGhlciBmb3IgdGhlIG5lc3RlZCBmdW5jdGlvbgorICAgIC8vLyAoYWxsb3dpbmcgdGFyZ2V0cyB0byBhY2Nlc3MgdGhlIG9yaWdpbmFsIEZ1bmN0aW9uKikuCisgICAgLy8vIEl0IHByb2R1Y2VzIGEgdG9rZW4gY2hhaW4gYXMgb3V0cHV0LgorICAgIElOSVRfVFJBTVBPTElORSwKKworICAgIC8vLyBBREpVU1RfVFJBTVBPTElORSAtIFRoaXMgY29ycmVzcG9uZHMgdG8gdGhlIGFkanVzdF90cmFtcG9saW5lIGludHJpbnNpYy4KKyAgICAvLy8gSXQgdGFrZXMgYSBwb2ludGVyIHRvIHRoZSB0cmFtcG9saW5lIGFuZCBwcm9kdWNlcyBhIChwb3NzaWJseSkgbmV3CisgICAgLy8vIHBvaW50ZXIgdG8gdGhlIHNhbWUgdHJhbXBvbGluZSB3aXRoIHBsYXRmb3JtLXNwZWNpZmljIGFkanVzdG1lbnRzCisgICAgLy8vIGFwcGxpZWQuICBUaGUgcG9pbnRlciBpdCByZXR1cm5zIHBvaW50cyB0byBhbiBleGVjdXRhYmxlIGJsb2NrIG9mIGNvZGUuCisgICAgQURKVVNUX1RSQU1QT0xJTkUsCisKKyAgICAvLy8gVFJBUCAtIFRyYXBwaW5nIGluc3RydWN0aW9uCisgICAgVFJBUCwKKworICAgIC8vLyBERUJVR1RSQVAgLSBUcmFwIGludGVuZGVkIHRvIGdldCB0aGUgYXR0ZW50aW9uIG9mIGEgZGVidWdnZXIuCisgICAgREVCVUdUUkFQLAorCisgICAgLy8vIFBSRUZFVENIIC0gVGhpcyBjb3JyZXNwb25kcyB0byBhIHByZWZldGNoIGludHJpbnNpYy4gVGhlIGZpcnN0IG9wZXJhbmQKKyAgICAvLy8gaXMgdGhlIGNoYWluLiAgVGhlIG90aGVyIG9wZXJhbmRzIGFyZSB0aGUgYWRkcmVzcyB0byBwcmVmZXRjaCwKKyAgICAvLy8gcmVhZCAvIHdyaXRlIHNwZWNpZmllciwgbG9jYWxpdHkgc3BlY2lmaWVyIGFuZCBpbnN0cnVjdGlvbiAvIGRhdGEgY2FjaGUKKyAgICAvLy8gc3BlY2lmaWVyLgorICAgIFBSRUZFVENILAorCisgICAgLy8vIE9VVENIQUlOID0gQVRPTUlDX0ZFTkNFKElOQ0hBSU4sIG9yZGVyaW5nLCBzY29wZSkKKyAgICAvLy8gVGhpcyBjb3JyZXNwb25kcyB0byB0aGUgZmVuY2UgaW5zdHJ1Y3Rpb24uIEl0IHRha2VzIGFuIGlucHV0IGNoYWluLCBhbmQKKyAgICAvLy8gdHdvIGludGVnZXIgY29uc3RhbnRzOiBhbiBBdG9taWNPcmRlcmluZyBhbmQgYSBTeW5jaHJvbml6YXRpb25TY29wZS4KKyAgICBBVE9NSUNfRkVOQ0UsCisKKyAgICAvLy8gVmFsLCBPVVRDSEFJTiA9IEFUT01JQ19MT0FEKElOQ0hBSU4sIHB0cikKKyAgICAvLy8gVGhpcyBjb3JyZXNwb25kcyB0byAibG9hZCBhdG9taWMiIGluc3RydWN0aW9uLgorICAgIEFUT01JQ19MT0FELAorCisgICAgLy8vIE9VVENIQUlOID0gQVRPTUlDX1NUT1JFKElOQ0hBSU4sIHB0ciwgdmFsKQorICAgIC8vLyBUaGlzIGNvcnJlc3BvbmRzIHRvICJzdG9yZSBhdG9taWMiIGluc3RydWN0aW9uLgorICAgIEFUT01JQ19TVE9SRSwKKworICAgIC8vLyBWYWwsIE9VVENIQUlOID0gQVRPTUlDX0NNUF9TV0FQKElOQ0hBSU4sIHB0ciwgY21wLCBzd2FwKQorICAgIC8vLyBGb3IgZG91YmxlLXdvcmQgYXRvbWljIG9wZXJhdGlvbnM6CisgICAgLy8vIFZhbExvLCBWYWxIaSwgT1VUQ0hBSU4gPSBBVE9NSUNfQ01QX1NXQVAoSU5DSEFJTiwgcHRyLCBjbXBMbywgY21wSGksCisgICAgLy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dhcExvLCBzd2FwSGkpCisgICAgLy8vIFRoaXMgY29ycmVzcG9uZHMgdG8gdGhlIGNtcHhjaGcgaW5zdHJ1Y3Rpb24uCisgICAgQVRPTUlDX0NNUF9TV0FQLAorCisgICAgLy8vIFZhbCwgU3VjY2VzcywgT1VUQ0hBSU4KKyAgICAvLy8gICAgID0gQVRPTUlDX0NNUF9TV0FQX1dJVEhfU1VDQ0VTUyhJTkNIQUlOLCBwdHIsIGNtcCwgc3dhcCkKKyAgICAvLy8gTi5iLiB0aGlzIGlzIHN0aWxsIGEgc3Ryb25nIGNtcHhjaGcgb3BlcmF0aW9uLCBzbworICAgIC8vLyBTdWNjZXNzID09ICJWYWwgPT0gY21wIi4KKyAgICBBVE9NSUNfQ01QX1NXQVBfV0lUSF9TVUNDRVNTLAorCisgICAgLy8vIFZhbCwgT1VUQ0hBSU4gPSBBVE9NSUNfU1dBUChJTkNIQUlOLCBwdHIsIGFtdCkKKyAgICAvLy8gVmFsLCBPVVRDSEFJTiA9IEFUT01JQ19MT0FEX1tPcE5hbWVdKElOQ0hBSU4sIHB0ciwgYW10KQorICAgIC8vLyBGb3IgZG91YmxlLXdvcmQgYXRvbWljIG9wZXJhdGlvbnM6CisgICAgLy8vIFZhbExvLCBWYWxIaSwgT1VUQ0hBSU4gPSBBVE9NSUNfU1dBUChJTkNIQUlOLCBwdHIsIGFtdExvLCBhbXRIaSkKKyAgICAvLy8gVmFsTG8sIFZhbEhpLCBPVVRDSEFJTiA9IEFUT01JQ19MT0FEX1tPcE5hbWVdKElOQ0hBSU4sIHB0ciwgYW10TG8sIGFtdEhpKQorICAgIC8vLyBUaGVzZSBjb3JyZXNwb25kIHRvIHRoZSBhdG9taWNybXcgaW5zdHJ1Y3Rpb24uCisgICAgQVRPTUlDX1NXQVAsCisgICAgQVRPTUlDX0xPQURfQURELAorICAgIEFUT01JQ19MT0FEX1NVQiwKKyAgICBBVE9NSUNfTE9BRF9BTkQsCisgICAgQVRPTUlDX0xPQURfQ0xSLAorICAgIEFUT01JQ19MT0FEX09SLAorICAgIEFUT01JQ19MT0FEX1hPUiwKKyAgICBBVE9NSUNfTE9BRF9OQU5ELAorICAgIEFUT01JQ19MT0FEX01JTiwKKyAgICBBVE9NSUNfTE9BRF9NQVgsCisgICAgQVRPTUlDX0xPQURfVU1JTiwKKyAgICBBVE9NSUNfTE9BRF9VTUFYLAorCisgICAgLy8gTWFza2VkIGxvYWQgYW5kIHN0b3JlIC0gY29uc2VjdXRpdmUgdmVjdG9yIGxvYWQgYW5kIHN0b3JlIG9wZXJhdGlvbnMKKyAgICAvLyB3aXRoIGFkZGl0aW9uYWwgbWFzayBvcGVyYW5kIHRoYXQgcHJldmVudHMgbWVtb3J5IGFjY2Vzc2VzIHRvIHRoZQorICAgIC8vIG1hc2tlZC1vZmYgbGFuZXMuCisgICAgTUxPQUQsIE1TVE9SRSwKKworICAgIC8vIE1hc2tlZCBnYXRoZXIgYW5kIHNjYXR0ZXIgLSBsb2FkIGFuZCBzdG9yZSBvcGVyYXRpb25zIGZvciBhIHZlY3RvciBvZgorICAgIC8vIHJhbmRvbSBhZGRyZXNzZXMgd2l0aCBhZGRpdGlvbmFsIG1hc2sgb3BlcmFuZCB0aGF0IHByZXZlbnRzIG1lbW9yeQorICAgIC8vIGFjY2Vzc2VzIHRvIHRoZSBtYXNrZWQtb2ZmIGxhbmVzLgorICAgIE1HQVRIRVIsIE1TQ0FUVEVSLAorCisgICAgLy8vIFRoaXMgY29ycmVzcG9uZHMgdG8gdGhlIGxsdm0ubGlmZXRpbWUuKiBpbnRyaW5zaWNzLiBUaGUgZmlyc3Qgb3BlcmFuZAorICAgIC8vLyBpcyB0aGUgY2hhaW4gYW5kIHRoZSBzZWNvbmQgb3BlcmFuZCBpcyB0aGUgYWxsb2NhIHBvaW50ZXIuCisgICAgTElGRVRJTUVfU1RBUlQsIExJRkVUSU1FX0VORCwKKworICAgIC8vLyBHQ19UUkFOU0lUSU9OX1NUQVJUL0dDX1RSQU5TSVRJT05fRU5EIC0gVGhlc2Ugb3BlcmF0b3JzIG1hcmsgdGhlCisgICAgLy8vIGJlZ2lubmluZyBhbmQgZW5kIG9mIEdDIHRyYW5zaXRpb24gIHNlcXVlbmNlLCBhbmQgY2FycnkgYXJiaXRyYXJ5CisgICAgLy8vIGluZm9ybWF0aW9uIHRoYXQgdGFyZ2V0IG1pZ2h0IG5lZWQgZm9yIGxvd2VyaW5nLiAgVGhlIGZpcnN0IG9wZXJhbmQgaXMKKyAgICAvLy8gYSBjaGFpbiwgdGhlIHJlc3QgYXJlIHNwZWNpZmllZCBieSB0aGUgdGFyZ2V0IGFuZCBub3QgdG91Y2hlZCBieSB0aGUgREFHCisgICAgLy8vIG9wdGltaXplcnMuIEdDX1RSQU5TSVRJT05fU1RBUlQuLkdDX1RSQU5TSVRJT05fRU5EIHBhaXJzIG1heSBub3QgYmUKKyAgICAvLy8gbmVzdGVkLgorICAgIEdDX1RSQU5TSVRJT05fU1RBUlQsCisgICAgR0NfVFJBTlNJVElPTl9FTkQsCisKKyAgICAvLy8gR0VUX0RZTkFNSUNfQVJFQV9PRkZTRVQgLSBnZXQgb2Zmc2V0IGZyb20gbmF0aXZlIFNQIHRvIHRoZSBhZGRyZXNzIG9mCisgICAgLy8vIHRoZSBtb3N0IHJlY2VudCBkeW5hbWljIGFsbG9jYS4gRm9yIG1vc3QgdGFyZ2V0cyB0aGF0IHdvdWxkIGJlIDAsIGJ1dAorICAgIC8vLyBmb3Igc29tZSBvdGhlcnMgKGUuZy4gUG93ZXJQQywgUG93ZXJQQzY0KSB0aGF0IHdvdWxkIGJlIGNvbXBpbGUtdGltZQorICAgIC8vLyBrbm93biBub256ZXJvIGNvbnN0YW50LiBUaGUgb25seSBvcGVyYW5kIGhlcmUgaXMgdGhlIGNoYWluLgorICAgIEdFVF9EWU5BTUlDX0FSRUFfT0ZGU0VULAorCisgICAgLy8vIEdlbmVyaWMgcmVkdWN0aW9uIG5vZGVzLiBUaGVzZSBub2RlcyByZXByZXNlbnQgaG9yaXpvbnRhbCB2ZWN0b3IKKyAgICAvLy8gcmVkdWN0aW9uIG9wZXJhdGlvbnMsIHByb2R1Y2luZyBhIHNjYWxhciByZXN1bHQuCisgICAgLy8vIFRoZSBTVFJJQ1QgdmFyaWFudHMgcGVyZm9ybSByZWR1Y3Rpb25zIGluIHNlcXVlbnRpYWwgb3JkZXIuIFRoZSBmaXJzdAorICAgIC8vLyBvcGVyYW5kIGlzIGFuIGluaXRpYWwgc2NhbGFyIGFjY3VtdWxhdG9yIHZhbHVlLCBhbmQgdGhlIHNlY29uZCBvcGVyYW5kCisgICAgLy8vIGlzIHRoZSB2ZWN0b3IgdG8gcmVkdWNlLgorICAgIFZFQ1JFRFVDRV9TVFJJQ1RfRkFERCwgVkVDUkVEVUNFX1NUUklDVF9GTVVMLAorICAgIC8vLyBUaGVzZSByZWR1Y3Rpb25zIGFyZSBub24tc3RyaWN0LCBhbmQgaGF2ZSBhIHNpbmdsZSB2ZWN0b3Igb3BlcmFuZC4KKyAgICBWRUNSRURVQ0VfRkFERCwgVkVDUkVEVUNFX0ZNVUwsCisgICAgVkVDUkVEVUNFX0FERCwgVkVDUkVEVUNFX01VTCwKKyAgICBWRUNSRURVQ0VfQU5ELCBWRUNSRURVQ0VfT1IsIFZFQ1JFRFVDRV9YT1IsCisgICAgVkVDUkVEVUNFX1NNQVgsIFZFQ1JFRFVDRV9TTUlOLCBWRUNSRURVQ0VfVU1BWCwgVkVDUkVEVUNFX1VNSU4sCisgICAgLy8vIEZNSU4vRk1BWCBub2RlcyBjYW4gaGF2ZSBmbGFncywgZm9yIE5hTi9Ob05hTiB2YXJpYW50cy4KKyAgICBWRUNSRURVQ0VfRk1BWCwgVkVDUkVEVUNFX0ZNSU4sCisKKyAgICAvLy8gQlVJTFRJTl9PUF9FTkQgLSBUaGlzIG11c3QgYmUgdGhlIGxhc3QgZW51bSB2YWx1ZSBpbiB0aGlzIGxpc3QuCisgICAgLy8vIFRoZSB0YXJnZXQtc3BlY2lmaWMgcHJlLWlzZWwgb3Bjb2RlIHZhbHVlcyBzdGFydCBoZXJlLgorICAgIEJVSUxUSU5fT1BfRU5ECisgIH07CisKKyAgLy8vIEZJUlNUX1RBUkdFVF9NRU1PUllfT1BDT0RFIC0gVGFyZ2V0LXNwZWNpZmljIHByZS1pc2VsIG9wZXJhdGlvbnMKKyAgLy8vIHdoaWNoIGRvIG5vdCByZWZlcmVuY2UgYSBzcGVjaWZpYyBtZW1vcnkgbG9jYXRpb24gc2hvdWxkIGJlIGxlc3MgdGhhbgorICAvLy8gdGhpcyB2YWx1ZS4gVGhvc2UgdGhhdCBkbyBtdXN0IG5vdCBiZSBsZXNzIHRoYW4gdGhpcyB2YWx1ZSwgYW5kIGNhbgorICAvLy8gYmUgdXNlZCB3aXRoIFNlbGVjdGlvbkRBRzo6Z2V0TWVtSW50cmluc2ljTm9kZS4KKyAgc3RhdGljIGNvbnN0IGludCBGSVJTVF9UQVJHRVRfTUVNT1JZX09QQ09ERSA9IEJVSUxUSU5fT1BfRU5EKzQwMDsKKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8vIE1lbUluZGV4ZWRNb2RlIGVudW0gLSBUaGlzIGVudW0gZGVmaW5lcyB0aGUgbG9hZCAvIHN0b3JlIGluZGV4ZWQKKyAgLy8vIGFkZHJlc3NpbmcgbW9kZXMuCisgIC8vLworICAvLy8gVU5JTkRFWEVEICAgICJOb3JtYWwiIGxvYWQgLyBzdG9yZS4gVGhlIGVmZmVjdGl2ZSBhZGRyZXNzIGlzIGFscmVhZHkKKyAgLy8vICAgICAgICAgICAgICBjb21wdXRlZCBhbmQgaXMgYXZhaWxhYmxlIGluIHRoZSBiYXNlIHBvaW50ZXIuIFRoZSBvZmZzZXQKKyAgLy8vICAgICAgICAgICAgICBvcGVyYW5kIGlzIGFsd2F5cyB1bmRlZmluZWQuIEluIGFkZGl0aW9uIHRvIHByb2R1Y2luZyBhCisgIC8vLyAgICAgICAgICAgICAgY2hhaW4sIGFuIHVuaW5kZXhlZCBsb2FkIHByb2R1Y2VzIG9uZSB2YWx1ZSAocmVzdWx0IG9mIHRoZQorICAvLy8gICAgICAgICAgICAgIGxvYWQpOyBhbiB1bmluZGV4ZWQgc3RvcmUgZG9lcyBub3QgcHJvZHVjZSBhIHZhbHVlLgorICAvLy8KKyAgLy8vIFBSRV9JTkMgICAgICBTaW1pbGFyIHRvIHRoZSB1bmluZGV4ZWQgbW9kZSB3aGVyZSB0aGUgZWZmZWN0aXZlIGFkZHJlc3MgaXMKKyAgLy8vIFBSRV9ERUMgICAgICB0aGUgdmFsdWUgb2YgdGhlIGJhc2UgcG9pbnRlciBhZGQgLyBzdWJ0cmFjdCB0aGUgb2Zmc2V0LgorICAvLy8gICAgICAgICAgICAgIEl0IGNvbnNpZGVycyB0aGUgY29tcHV0YXRpb24gYXMgYmVpbmcgZm9sZGVkIGludG8gdGhlIGxvYWQgLworICAvLy8gICAgICAgICAgICAgIHN0b3JlIG9wZXJhdGlvbiAoaS5lLiB0aGUgbG9hZCAvIHN0b3JlIGRvZXMgdGhlIGFkZHJlc3MKKyAgLy8vICAgICAgICAgICAgICBjb21wdXRhdGlvbiBhcyB3ZWxsIGFzIHBlcmZvcm1pbmcgdGhlIG1lbW9yeSB0cmFuc2FjdGlvbikuCisgIC8vLyAgICAgICAgICAgICAgVGhlIGJhc2Ugb3BlcmFuZCBpcyBhbHdheXMgdW5kZWZpbmVkLiBJbiBhZGRpdGlvbiB0bworICAvLy8gICAgICAgICAgICAgIHByb2R1Y2luZyBhIGNoYWluLCBwcmUtaW5kZXhlZCBsb2FkIHByb2R1Y2VzIHR3byB2YWx1ZXMKKyAgLy8vICAgICAgICAgICAgICAocmVzdWx0IG9mIHRoZSBsb2FkIGFuZCB0aGUgcmVzdWx0IG9mIHRoZSBhZGRyZXNzCisgIC8vLyAgICAgICAgICAgICAgY29tcHV0YXRpb24pOyBhIHByZS1pbmRleGVkIHN0b3JlIHByb2R1Y2VzIG9uZSB2YWx1ZSAocmVzdWx0CisgIC8vLyAgICAgICAgICAgICAgb2YgdGhlIGFkZHJlc3MgY29tcHV0YXRpb24pLgorICAvLy8KKyAgLy8vIFBPU1RfSU5DICAgICBUaGUgZWZmZWN0aXZlIGFkZHJlc3MgaXMgdGhlIHZhbHVlIG9mIHRoZSBiYXNlIHBvaW50ZXIuIFRoZQorICAvLy8gUE9TVF9ERUMgICAgIHZhbHVlIG9mIHRoZSBvZmZzZXQgb3BlcmFuZCBpcyB0aGVuIGFkZGVkIHRvIC8gc3VidHJhY3RlZAorICAvLy8gICAgICAgICAgICAgIGZyb20gdGhlIGJhc2UgYWZ0ZXIgbWVtb3J5IHRyYW5zYWN0aW9uLiBJbiBhZGRpdGlvbiB0bworICAvLy8gICAgICAgICAgICAgIHByb2R1Y2luZyBhIGNoYWluLCBwb3N0LWluZGV4ZWQgbG9hZCBwcm9kdWNlcyB0d28gdmFsdWVzCisgIC8vLyAgICAgICAgICAgICAgKHRoZSByZXN1bHQgb2YgdGhlIGxvYWQgYW5kIHRoZSByZXN1bHQgb2YgdGhlIGJhc2UgKy8tIG9mZnNldAorICAvLy8gICAgICAgICAgICAgIGNvbXB1dGF0aW9uKTsgYSBwb3N0LWluZGV4ZWQgc3RvcmUgcHJvZHVjZXMgb25lIHZhbHVlICh0aGUKKyAgLy8vICAgICAgICAgICAgICB0aGUgcmVzdWx0IG9mIHRoZSBiYXNlICsvLSBvZmZzZXQgY29tcHV0YXRpb24pLgorICBlbnVtIE1lbUluZGV4ZWRNb2RlIHsKKyAgICBVTklOREVYRUQgPSAwLAorICAgIFBSRV9JTkMsCisgICAgUFJFX0RFQywKKyAgICBQT1NUX0lOQywKKyAgICBQT1NUX0RFQworICB9OworCisgIHN0YXRpYyBjb25zdCBpbnQgTEFTVF9JTkRFWEVEX01PREUgPSBQT1NUX0RFQyArIDE7CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vLyBMb2FkRXh0VHlwZSBlbnVtIC0gVGhpcyBlbnVtIGRlZmluZXMgdGhlIHRocmVlIHZhcmlhbnRzIG9mIExPQURFWFQKKyAgLy8vIChsb2FkIHdpdGggZXh0ZW5zaW9uKS4KKyAgLy8vCisgIC8vLyBTRVhUTE9BRCBsb2FkcyB0aGUgaW50ZWdlciBvcGVyYW5kIGFuZCBzaWduIGV4dGVuZHMgaXQgdG8gYSBsYXJnZXIKKyAgLy8vICAgICAgICAgIGludGVnZXIgcmVzdWx0IHR5cGUuCisgIC8vLyBaRVhUTE9BRCBsb2FkcyB0aGUgaW50ZWdlciBvcGVyYW5kIGFuZCB6ZXJvIGV4dGVuZHMgaXQgdG8gYSBsYXJnZXIKKyAgLy8vICAgICAgICAgIGludGVnZXIgcmVzdWx0IHR5cGUuCisgIC8vLyBFWFRMT0FEICBpcyB1c2VkIGZvciB0d28gdGhpbmdzOiBmbG9hdGluZyBwb2ludCBleHRlbmRpbmcgbG9hZHMgYW5kCisgIC8vLyAgICAgICAgICBpbnRlZ2VyIGV4dGVuZGluZyBsb2FkcyBbdGhlIHRvcCBiaXRzIGFyZSB1bmRlZmluZWRdLgorICBlbnVtIExvYWRFeHRUeXBlIHsKKyAgICBOT05fRVhUTE9BRCA9IDAsCisgICAgRVhUTE9BRCwKKyAgICBTRVhUTE9BRCwKKyAgICBaRVhUTE9BRAorICB9OworCisgIHN0YXRpYyBjb25zdCBpbnQgTEFTVF9MT0FERVhUX1RZUEUgPSBaRVhUTE9BRCArIDE7CisKKyAgTm9kZVR5cGUgZ2V0RXh0Rm9yTG9hZEV4dFR5cGUoYm9vbCBJc0ZQLCBMb2FkRXh0VHlwZSk7CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vLyBJU0Q6OkNvbmRDb2RlIGVudW0gLSBUaGVzZSBhcmUgb3JkZXJlZCBjYXJlZnVsbHkgdG8gbWFrZSB0aGUgYml0ZmllbGRzCisgIC8vLyBiZWxvdyB3b3JrIG91dCwgd2hlbiBjb25zaWRlcmluZyBTRVRGQUxTRSAoc29tZXRoaW5nIHRoYXQgbmV2ZXIgZXhpc3RzCisgIC8vLyBkeW5hbWljYWxseSkgYXMgMC4gICJVIiAtPiBVbnNpZ25lZCAoZm9yIGludGVnZXIgb3BlcmFuZHMpIG9yIFVub3JkZXJlZAorICAvLy8gKGZvciBmbG9hdGluZyBwb2ludCksICJMIiAtPiBMZXNzIHRoYW4sICJHIiAtPiBHcmVhdGVyIHRoYW4sICJFIiAtPiBFcXVhbAorICAvLy8gdG8uICBJZiB0aGUgIk4iIGNvbHVtbiBpcyAxLCB0aGUgcmVzdWx0IG9mIHRoZSBjb21wYXJpc29uIGlzIHVuZGVmaW5lZCBpZgorICAvLy8gdGhlIGlucHV0IGlzIGEgTkFOLgorICAvLy8KKyAgLy8vIEFsbCBvZiB0aGVzZSAoZXhjZXB0IGZvciB0aGUgJ2Fsd2F5cyBmb2xkZWQgb3BzJykgc2hvdWxkIGJlIGhhbmRsZWQgZm9yCisgIC8vLyBmbG9hdGluZyBwb2ludC4gIEZvciBpbnRlZ2VyLCBvbmx5IHRoZSBTRVRFUSxTRVRORSxTRVRMVCxTRVRMRSxTRVRHVCwKKyAgLy8vIFNFVEdFLFNFVFVMVCxTRVRVTEUsU0VUVUdULCBhbmQgU0VUVUdFIG9wY29kZXMgYXJlIHVzZWQuCisgIC8vLworICAvLy8gTm90ZSB0aGF0IHRoZXNlIGFyZSBsYWlkIG91dCBpbiBhIHNwZWNpZmljIG9yZGVyIHRvIGFsbG93IGJpdC10d2lkZGxpbmcKKyAgLy8vIHRvIHRyYW5zZm9ybSBjb25kaXRpb25zLgorICBlbnVtIENvbmRDb2RlIHsKKyAgICAvLyBPcGNvZGUgICAgICAgICAgTiBVIEwgRyBFICAgICAgIEludHVpdGl2ZSBvcGVyYXRpb24KKyAgICBTRVRGQUxTRSwgICAgICAvLyAgICAwIDAgMCAwICAgICAgIEFsd2F5cyBmYWxzZSAoYWx3YXlzIGZvbGRlZCkKKyAgICBTRVRPRVEsICAgICAgICAvLyAgICAwIDAgMCAxICAgICAgIFRydWUgaWYgb3JkZXJlZCBhbmQgZXF1YWwKKyAgICBTRVRPR1QsICAgICAgICAvLyAgICAwIDAgMSAwICAgICAgIFRydWUgaWYgb3JkZXJlZCBhbmQgZ3JlYXRlciB0aGFuCisgICAgU0VUT0dFLCAgICAgICAgLy8gICAgMCAwIDEgMSAgICAgICBUcnVlIGlmIG9yZGVyZWQgYW5kIGdyZWF0ZXIgdGhhbiBvciBlcXVhbAorICAgIFNFVE9MVCwgICAgICAgIC8vICAgIDAgMSAwIDAgICAgICAgVHJ1ZSBpZiBvcmRlcmVkIGFuZCBsZXNzIHRoYW4KKyAgICBTRVRPTEUsICAgICAgICAvLyAgICAwIDEgMCAxICAgICAgIFRydWUgaWYgb3JkZXJlZCBhbmQgbGVzcyB0aGFuIG9yIGVxdWFsCisgICAgU0VUT05FLCAgICAgICAgLy8gICAgMCAxIDEgMCAgICAgICBUcnVlIGlmIG9yZGVyZWQgYW5kIG9wZXJhbmRzIGFyZSB1bmVxdWFsCisgICAgU0VUTywgICAgICAgICAgLy8gICAgMCAxIDEgMSAgICAgICBUcnVlIGlmIG9yZGVyZWQgKG5vIG5hbnMpCisgICAgU0VUVU8sICAgICAgICAgLy8gICAgMSAwIDAgMCAgICAgICBUcnVlIGlmIHVub3JkZXJlZDogaXNuYW4oWCkgfCBpc25hbihZKQorICAgIFNFVFVFUSwgICAgICAgIC8vICAgIDEgMCAwIDEgICAgICAgVHJ1ZSBpZiB1bm9yZGVyZWQgb3IgZXF1YWwKKyAgICBTRVRVR1QsICAgICAgICAvLyAgICAxIDAgMSAwICAgICAgIFRydWUgaWYgdW5vcmRlcmVkIG9yIGdyZWF0ZXIgdGhhbgorICAgIFNFVFVHRSwgICAgICAgIC8vICAgIDEgMCAxIDEgICAgICAgVHJ1ZSBpZiB1bm9yZGVyZWQsIGdyZWF0ZXIgdGhhbiwgb3IgZXF1YWwKKyAgICBTRVRVTFQsICAgICAgICAvLyAgICAxIDEgMCAwICAgICAgIFRydWUgaWYgdW5vcmRlcmVkIG9yIGxlc3MgdGhhbgorICAgIFNFVFVMRSwgICAgICAgIC8vICAgIDEgMSAwIDEgICAgICAgVHJ1ZSBpZiB1bm9yZGVyZWQsIGxlc3MgdGhhbiwgb3IgZXF1YWwKKyAgICBTRVRVTkUsICAgICAgICAvLyAgICAxIDEgMSAwICAgICAgIFRydWUgaWYgdW5vcmRlcmVkIG9yIG5vdCBlcXVhbAorICAgIFNFVFRSVUUsICAgICAgIC8vICAgIDEgMSAxIDEgICAgICAgQWx3YXlzIHRydWUgKGFsd2F5cyBmb2xkZWQpCisgICAgLy8gRG9uJ3QgY2FyZSBvcGVyYXRpb25zOiB1bmRlZmluZWQgaWYgdGhlIGlucHV0IGlzIGEgbmFuLgorICAgIFNFVEZBTFNFMiwgICAgIC8vICAxIFggMCAwIDAgICAgICAgQWx3YXlzIGZhbHNlIChhbHdheXMgZm9sZGVkKQorICAgIFNFVEVRLCAgICAgICAgIC8vICAxIFggMCAwIDEgICAgICAgVHJ1ZSBpZiBlcXVhbAorICAgIFNFVEdULCAgICAgICAgIC8vICAxIFggMCAxIDAgICAgICAgVHJ1ZSBpZiBncmVhdGVyIHRoYW4KKyAgICBTRVRHRSwgICAgICAgICAvLyAgMSBYIDAgMSAxICAgICAgIFRydWUgaWYgZ3JlYXRlciB0aGFuIG9yIGVxdWFsCisgICAgU0VUTFQsICAgICAgICAgLy8gIDEgWCAxIDAgMCAgICAgICBUcnVlIGlmIGxlc3MgdGhhbgorICAgIFNFVExFLCAgICAgICAgIC8vICAxIFggMSAwIDEgICAgICAgVHJ1ZSBpZiBsZXNzIHRoYW4gb3IgZXF1YWwKKyAgICBTRVRORSwgICAgICAgICAvLyAgMSBYIDEgMSAwICAgICAgIFRydWUgaWYgbm90IGVxdWFsCisgICAgU0VUVFJVRTIsICAgICAgLy8gIDEgWCAxIDEgMSAgICAgICBBbHdheXMgdHJ1ZSAoYWx3YXlzIGZvbGRlZCkKKworICAgIFNFVENDX0lOVkFMSUQgICAgICAgLy8gTWFya2VyIHZhbHVlLgorICB9OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGEgc2V0Y2MgaW5zdHJ1Y3Rpb24gdGhhdCBwZXJmb3JtcyBhIHNpZ25lZAorICAvLy8gY29tcGFyaXNvbiB3aGVuIHVzZWQgd2l0aCBpbnRlZ2VyIG9wZXJhbmRzLgorICBpbmxpbmUgYm9vbCBpc1NpZ25lZEludFNldENDKENvbmRDb2RlIENvZGUpIHsKKyAgICByZXR1cm4gQ29kZSA9PSBTRVRHVCB8fCBDb2RlID09IFNFVEdFIHx8IENvZGUgPT0gU0VUTFQgfHwgQ29kZSA9PSBTRVRMRTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGEgc2V0Y2MgaW5zdHJ1Y3Rpb24gdGhhdCBwZXJmb3JtcyBhbiB1bnNpZ25lZAorICAvLy8gY29tcGFyaXNvbiB3aGVuIHVzZWQgd2l0aCBpbnRlZ2VyIG9wZXJhbmRzLgorICBpbmxpbmUgYm9vbCBpc1Vuc2lnbmVkSW50U2V0Q0MoQ29uZENvZGUgQ29kZSkgeworICAgIHJldHVybiBDb2RlID09IFNFVFVHVCB8fCBDb2RlID09IFNFVFVHRSB8fCBDb2RlID09IFNFVFVMVCB8fCBDb2RlID09IFNFVFVMRTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGNvbmRpdGlvbiByZXR1cm5zIHRydWUgaWYgdGhlIHR3byBvcGVyYW5kcyB0bworICAvLy8gdGhlIGNvbmRpdGlvbiBhcmUgZXF1YWwuIE5vdGUgdGhhdCBpZiBvbmUgb2YgdGhlIHR3byBvcGVyYW5kcyBpcyBhIE5hTiwKKyAgLy8vIHRoaXMgdmFsdWUgaXMgbWVhbmluZ2xlc3MuCisgIGlubGluZSBib29sIGlzVHJ1ZVdoZW5FcXVhbChDb25kQ29kZSBDb25kKSB7CisgICAgcmV0dXJuICgoaW50KUNvbmQgJiAxKSAhPSAwOworICB9CisKKyAgLy8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyAwIGlmIHRoZSBjb25kaXRpb24gaXMgYWx3YXlzIGZhbHNlIGlmIGFuIG9wZXJhbmQgaXMKKyAgLy8vIGEgTmFOLCAxIGlmIHRoZSBjb25kaXRpb24gaXMgYWx3YXlzIHRydWUgaWYgdGhlIG9wZXJhbmQgaXMgYSBOYU4sIGFuZCAyIGlmCisgIC8vLyB0aGUgY29uZGl0aW9uIGlzIHVuZGVmaW5lZCBpZiB0aGUgb3BlcmFuZCBpcyBhIE5hTi4KKyAgaW5saW5lIHVuc2lnbmVkIGdldFVub3JkZXJlZEZsYXZvcihDb25kQ29kZSBDb25kKSB7CisgICAgcmV0dXJuICgoaW50KUNvbmQgPj4gMykgJiAzOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgb3BlcmF0aW9uIGNvcnJlc3BvbmRpbmcgdG8gIShYIG9wIFkpLCB3aGVyZSAnb3AnIGlzIGEgdmFsaWQKKyAgLy8vIFNldENDIG9wZXJhdGlvbi4KKyAgQ29uZENvZGUgZ2V0U2V0Q0NJbnZlcnNlKENvbmRDb2RlIE9wZXJhdGlvbiwgYm9vbCBpc0ludGVnZXIpOworCisgIC8vLyBSZXR1cm4gdGhlIG9wZXJhdGlvbiBjb3JyZXNwb25kaW5nIHRvIChZIG9wIFgpIHdoZW4gZ2l2ZW4gdGhlIG9wZXJhdGlvbgorICAvLy8gZm9yIChYIG9wIFkpLgorICBDb25kQ29kZSBnZXRTZXRDQ1N3YXBwZWRPcGVyYW5kcyhDb25kQ29kZSBPcGVyYXRpb24pOworCisgIC8vLyBSZXR1cm4gdGhlIHJlc3VsdCBvZiBhIGxvZ2ljYWwgT1IgYmV0d2VlbiBkaWZmZXJlbnQgY29tcGFyaXNvbnMgb2YKKyAgLy8vIGlkZW50aWNhbCB2YWx1ZXM6ICgoWCBvcDEgWSkgfCAoWCBvcDIgWSkpLiBUaGlzIGZ1bmN0aW9uIHJldHVybnMKKyAgLy8vIFNFVENDX0lOVkFMSUQgaWYgaXQgaXMgbm90IHBvc3NpYmxlIHRvIHJlcHJlc2VudCB0aGUgcmVzdWx0YW50IGNvbXBhcmlzb24uCisgIENvbmRDb2RlIGdldFNldENDT3JPcGVyYXRpb24oQ29uZENvZGUgT3AxLCBDb25kQ29kZSBPcDIsIGJvb2wgaXNJbnRlZ2VyKTsKKworICAvLy8gUmV0dXJuIHRoZSByZXN1bHQgb2YgYSBsb2dpY2FsIEFORCBiZXR3ZWVuIGRpZmZlcmVudCBjb21wYXJpc29ucyBvZgorICAvLy8gaWRlbnRpY2FsIHZhbHVlczogKChYIG9wMSBZKSAmIChYIG9wMiBZKSkuIFRoaXMgZnVuY3Rpb24gcmV0dXJucworICAvLy8gU0VUQ0NfSU5WQUxJRCBpZiBpdCBpcyBub3QgcG9zc2libGUgdG8gcmVwcmVzZW50IHRoZSByZXN1bHRhbnQgY29tcGFyaXNvbi4KKyAgQ29uZENvZGUgZ2V0U2V0Q0NBbmRPcGVyYXRpb24oQ29uZENvZGUgT3AxLCBDb25kQ29kZSBPcDIsIGJvb2wgaXNJbnRlZ2VyKTsKKworfSAvLyBlbmQgbGx2bTo6SVNEIG5hbWVzcGFjZQorCit9IC8vIGVuZCBsbHZtIG5hbWVzcGFjZQorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9JbnRyaW5zaWNMb3dlcmluZy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0ludHJpbnNpY0xvd2VyaW5nLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTk3ZDY4NAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9JbnRyaW5zaWNMb3dlcmluZy5oCkBAIC0wLDAgKzEsNTQgQEAKKy8vPT09LS0gSW50cmluc2ljTG93ZXJpbmcuaCAtIEludHJpbnNpYyBGdW5jdGlvbiBMb3dlcmluZyAtLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlZmluZXMgdGhlIEludHJpbnNpY0xvd2VyaW5nIGludGVyZmFjZS4gIFRoaXMgaW50ZXJmYWNlIGFsbG93cworLy8gYWRkaXRpb24gb2YgZG9tYWluLXNwZWNpZmljIG9yIGZyb250LWVuZCBzcGVjaWZpYyBpbnRyaW5zaWNzIHRvIExMVk0gd2l0aG91dAorLy8gaGF2aW5nIHRvIG1vZGlmeSBhbGwgb2YgdGhlIEMgYmFja2VuZCBvciBpbnRlcnByZXRlci4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9JTlRSSU5TSUNMT1dFUklOR19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9JTlRSSU5TSUNMT1dFUklOR19ICisKKyNpbmNsdWRlICJsbHZtL0lSL0ludHJpbnNpY3MuaCIKKworbmFtZXNwYWNlIGxsdm0geworY2xhc3MgQ2FsbEluc3Q7CitjbGFzcyBNb2R1bGU7CitjbGFzcyBEYXRhTGF5b3V0OworCitjbGFzcyBJbnRyaW5zaWNMb3dlcmluZyB7CisgIGNvbnN0IERhdGFMYXlvdXQgJkRMOworCisgIGJvb2wgV2FybmVkOworCitwdWJsaWM6CisgIGV4cGxpY2l0IEludHJpbnNpY0xvd2VyaW5nKGNvbnN0IERhdGFMYXlvdXQgJkRMKSA6IERMKERMKSwgV2FybmVkKGZhbHNlKSB7fQorCisgIC8vLyBBZGQgYWxsIG9mIHRoZSBwcm90b3R5cGVzIHRoYXQgbWlnaHQgYmUgbmVlZGVkIGJ5IGFuIGludHJpbnNpYyBsb3dlcmluZworICAvLy8gaW1wbGVtZW50YXRpb24gdG8gYmUgaW5zZXJ0ZWQgaW50byB0aGUgbW9kdWxlIHNwZWNpZmllZC4KKyAgdm9pZCBBZGRQcm90b3R5cGVzKE1vZHVsZSAmTSk7CisKKyAgLy8vIFJlcGxhY2UgYSBjYWxsIHRvIHRoZSBzcGVjaWZpZWQgaW50cmluc2ljIGZ1bmN0aW9uLgorICAvLy8gSWYgYW4gaW50cmluc2ljIGZ1bmN0aW9uIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgdGhlIGNvZGUgZ2VuZXJhdG9yCisgIC8vLyAoc3VjaCBhcyB2YV9zdGFydCksIHRoaXMgZnVuY3Rpb24gc2hvdWxkIHByaW50IGEgbWVzc2FnZSBhbmQgYWJvcnQuCisgIC8vLworICAvLy8gT3RoZXJ3aXNlLCBpZiBhbiBpbnRyaW5zaWMgZnVuY3Rpb24gY2FsbCBjYW4gYmUgbG93ZXJlZCwgdGhlIGNvZGUgdG8KKyAgLy8vIGltcGxlbWVudCBpdCAob2Z0ZW4gYSBjYWxsIHRvIGEgbm9uLWludHJpbnNpYyBmdW5jdGlvbikgaXMgaW5zZXJ0ZWQKKyAgLy8vIF9hZnRlcl8gdGhlIGNhbGwgaW5zdHJ1Y3Rpb24gYW5kIHRoZSBjYWxsIGlzIGRlbGV0ZWQuIFRoZSBjYWxsZXIgbXVzdAorICAvLy8gYmUgY2FwYWJsZSBvZiBoYW5kbGluZyB0aGlzIGtpbmQgb2YgY2hhbmdlLgorICB2b2lkIExvd2VySW50cmluc2ljQ2FsbChDYWxsSW5zdCAqQ0kpOworCisgIC8vLyBUcnkgdG8gcmVwbGFjZSBhIGNhbGwgaW5zdHJ1Y3Rpb24gd2l0aCBhIGNhbGwgdG8gYSBic3dhcCBpbnRyaW5zaWMuIFJldHVybgorICAvLy8gZmFsc2UgaWYgdGhlIGNhbGwgaXMgbm90IGEgc2ltcGxlIGludGVnZXIgYnN3YXAuCisgIHN0YXRpYyBib29sIExvd2VyVG9CeXRlU3dhcChDYWxsSW5zdCAqQ0kpOworfTsKK30KKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGF0ZW5jeVByaW9yaXR5UXVldWUuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9MYXRlbmN5UHJpb3JpdHlRdWV1ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk4OGU2ZDYKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGF0ZW5jeVByaW9yaXR5UXVldWUuaApAQCAtMCwwICsxLDk4IEBACisvLz09PS0tLS0gTGF0ZW5jeVByaW9yaXR5UXVldWUuaCAtIEEgbGF0ZW5jeS1vcmllbnRlZCBwcmlvcml0eSBxdWV1ZSAtLS0tLS09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZWNsYXJlcyB0aGUgTGF0ZW5jeVByaW9yaXR5UXVldWUgY2xhc3MsIHdoaWNoIGlzIGEKKy8vIFNjaGVkdWxpbmdQcmlvcml0eVF1ZXVlIHRoYXQgc2NoZWR1bGVzIHVzaW5nIGxhdGVuY3kgaW5mb3JtYXRpb24gdG8KKy8vIHJlZHVjZSB0aGUgbGVuZ3RoIG9mIHRoZSBjcml0aWNhbCBwYXRoIHRocm91Z2ggdGhlIGJhc2ljIGJsb2NrLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0xBVEVOQ1lQUklPUklUWVFVRVVFX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0xBVEVOQ1lQUklPUklUWVFVRVVFX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9TY2hlZHVsZURBRy5oIgorCituYW1lc3BhY2UgbGx2bSB7CisgIGNsYXNzIExhdGVuY3lQcmlvcml0eVF1ZXVlOworCisgIC8vLyBTb3J0aW5nIGZ1bmN0aW9ucyBmb3IgdGhlIEF2YWlsYWJsZSBxdWV1ZS4KKyAgc3RydWN0IGxhdGVuY3lfc29ydCB7CisgICAgTGF0ZW5jeVByaW9yaXR5UXVldWUgKlBROworICAgIGV4cGxpY2l0IGxhdGVuY3lfc29ydChMYXRlbmN5UHJpb3JpdHlRdWV1ZSAqcHEpIDogUFEocHEpIHt9CisKKyAgICBib29sIG9wZXJhdG9yKCkoY29uc3QgU1VuaXQqIGxlZnQsIGNvbnN0IFNVbml0KiByaWdodCkgY29uc3Q7CisgIH07CisKKyAgY2xhc3MgTGF0ZW5jeVByaW9yaXR5UXVldWUgOiBwdWJsaWMgU2NoZWR1bGluZ1ByaW9yaXR5UXVldWUgeworICAgIC8vIFNVbml0cyAtIFRoZSBTVW5pdHMgZm9yIHRoZSBjdXJyZW50IGdyYXBoLgorICAgIHN0ZDo6dmVjdG9yPFNVbml0PiAqU1VuaXRzOworCisgICAgLy8vIE51bU5vZGVzU29sZWx5QmxvY2tpbmcgLSBUaGlzIHZlY3RvciBjb250YWlucywgZm9yIGV2ZXJ5IG5vZGUgaW4gdGhlCisgICAgLy8vIFF1ZXVlLCB0aGUgbnVtYmVyIG9mIG5vZGVzIHRoYXQgdGhlIG5vZGUgaXMgdGhlIHNvbGUgdW5zY2hlZHVsZWQKKyAgICAvLy8gcHJlZGVjZXNzb3IgZm9yLiAgVGhpcyBpcyB1c2VkIGFzIGEgdGllLWJyZWFrZXIgaGV1cmlzdGljIGZvciBiZXR0ZXIKKyAgICAvLy8gbW9iaWxpdHkuCisgICAgc3RkOjp2ZWN0b3I8dW5zaWduZWQ+IE51bU5vZGVzU29sZWx5QmxvY2tpbmc7CisKKyAgICAvLy8gUXVldWUgLSBUaGUgcXVldWUuCisgICAgc3RkOjp2ZWN0b3I8U1VuaXQqPiBRdWV1ZTsKKyAgICBsYXRlbmN5X3NvcnQgUGlja2VyOworCisgIHB1YmxpYzoKKyAgICBMYXRlbmN5UHJpb3JpdHlRdWV1ZSgpIDogUGlja2VyKHRoaXMpIHsKKyAgICB9CisKKyAgICBib29sIGlzQm90dG9tVXAoKSBjb25zdCBvdmVycmlkZSB7IHJldHVybiBmYWxzZTsgfQorCisgICAgdm9pZCBpbml0Tm9kZXMoc3RkOjp2ZWN0b3I8U1VuaXQ+ICZzdW5pdHMpIG92ZXJyaWRlIHsKKyAgICAgIFNVbml0cyA9ICZzdW5pdHM7CisgICAgICBOdW1Ob2Rlc1NvbGVseUJsb2NraW5nLnJlc2l6ZShTVW5pdHMtPnNpemUoKSwgMCk7CisgICAgfQorCisgICAgdm9pZCBhZGROb2RlKGNvbnN0IFNVbml0ICpTVSkgb3ZlcnJpZGUgeworICAgICAgTnVtTm9kZXNTb2xlbHlCbG9ja2luZy5yZXNpemUoU1VuaXRzLT5zaXplKCksIDApOworICAgIH0KKworICAgIHZvaWQgdXBkYXRlTm9kZShjb25zdCBTVW5pdCAqU1UpIG92ZXJyaWRlIHsKKyAgICB9CisKKyAgICB2b2lkIHJlbGVhc2VTdGF0ZSgpIG92ZXJyaWRlIHsKKyAgICAgIFNVbml0cyA9IG51bGxwdHI7CisgICAgfQorCisgICAgdW5zaWduZWQgZ2V0TGF0ZW5jeSh1bnNpZ25lZCBOb2RlTnVtKSBjb25zdCB7CisgICAgICBhc3NlcnQoTm9kZU51bSA8ICgqU1VuaXRzKS5zaXplKCkpOworICAgICAgcmV0dXJuICgqU1VuaXRzKVtOb2RlTnVtXS5nZXRIZWlnaHQoKTsKKyAgICB9CisKKyAgICB1bnNpZ25lZCBnZXROdW1Tb2xlbHlCbG9ja05vZGVzKHVuc2lnbmVkIE5vZGVOdW0pIGNvbnN0IHsKKyAgICAgIGFzc2VydChOb2RlTnVtIDwgTnVtTm9kZXNTb2xlbHlCbG9ja2luZy5zaXplKCkpOworICAgICAgcmV0dXJuIE51bU5vZGVzU29sZWx5QmxvY2tpbmdbTm9kZU51bV07CisgICAgfQorCisgICAgYm9vbCBlbXB0eSgpIGNvbnN0IG92ZXJyaWRlIHsgcmV0dXJuIFF1ZXVlLmVtcHR5KCk7IH0KKworICAgIHZvaWQgcHVzaChTVW5pdCAqVSkgb3ZlcnJpZGU7CisKKyAgICBTVW5pdCAqcG9wKCkgb3ZlcnJpZGU7CisKKyAgICB2b2lkIHJlbW92ZShTVW5pdCAqU1UpIG92ZXJyaWRlOworCisgICAgLy8gc2NoZWR1bGVkTm9kZSAtIEFzIG5vZGVzIGFyZSBzY2hlZHVsZWQsIHdlIGxvb2sgdG8gc2VlIGlmIHRoZXJlIGFyZSBhbnkKKyAgICAvLyBzdWNjZXNzb3Igbm9kZXMgdGhhdCBoYXZlIGEgc2luZ2xlIHVuc2NoZWR1bGVkIHByZWRlY2Vzc29yLiAgSWYgc28sIHRoYXQKKyAgICAvLyBzaW5nbGUgcHJlZGVjZXNzb3IgaGFzIGEgaGlnaGVyIHByaW9yaXR5LCBzaW5jZSBzY2hlZHVsaW5nIGl0IHdpbGwgbWFrZQorICAgIC8vIHRoZSBub2RlIGF2YWlsYWJsZS4KKyAgICB2b2lkIHNjaGVkdWxlZE5vZGUoU1VuaXQgKk5vZGUpIG92ZXJyaWRlOworCitwcml2YXRlOgorICAgIHZvaWQgQWRqdXN0UHJpb3JpdHlPZlVuc2NoZWR1bGVkUHJlZHMoU1VuaXQgKlNVKTsKKyAgICBTVW5pdCAqZ2V0U2luZ2xlVW5zY2hlZHVsZWRQcmVkKFNVbml0ICpTVSk7CisgIH07Cit9CisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xhenlNYWNoaW5lQmxvY2tGcmVxdWVuY3lJbmZvLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGF6eU1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm8uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NDhlZTFkCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xhenlNYWNoaW5lQmxvY2tGcmVxdWVuY3lJbmZvLmgKQEAgLTAsMCArMSw3NiBAQAorLy8vPT09LSBMYXp5TWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mby5oIC0gTGF6eSBCbG9jayBGcmVxdWVuY3kgLSotIEMrKyAtKi0tPT09Ly8KKy8vLworLy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vLworLy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vLworLy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLyBcZmlsZQorLy8vIFRoaXMgaXMgYW4gYWx0ZXJuYXRpdmUgYW5hbHlzaXMgcGFzcyB0byBNYWNoaW5lQmxvY2tGcmVxdWVuY3lJbmZvLiAgVGhlCisvLy8gZGlmZmVyZW5jZSBpcyB0aGF0IHdpdGggdGhpcyBwYXNzIHRoZSBibG9jayBmcmVxdWVuY2llcyBhcmUgbm90IGNvbXB1dGVkCisvLy8gd2hlbiB0aGUgYW5hbHlzaXMgcGFzcyBpcyBleGVjdXRlZCBidXQgcmF0aGVyIHdoZW4gdGhlIEJGSSByZXN1bHQgaXMKKy8vLyBleHBsaWNpdGx5IHJlcXVlc3RlZCBieSB0aGUgYW5hbHlzaXMgY2xpZW50LgorLy8vCisvLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQU5BTFlTSVNfTEFaWU1BQ0hJTkVCTE9DS0ZSRVFVRU5DWUlORk9fSAorI2RlZmluZSBMTFZNX0FOQUxZU0lTX0xBWllNQUNISU5FQkxPQ0tGUkVRVUVOQ1lJTkZPX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lQmxvY2tGcmVxdWVuY3lJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVCcmFuY2hQcm9iYWJpbGl0eUluZm8uaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZURvbWluYXRvcnMuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUxvb3BJbmZvLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKy8vLyBcYnJpZWYgVGhpcyBpcyBhbiBhbHRlcm5hdGl2ZSBhbmFseXNpcyBwYXNzIHRvIE1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm8uCisvLy8gVGhlIGRpZmZlcmVuY2UgaXMgdGhhdCB3aXRoIHRoaXMgcGFzcywgdGhlIGJsb2NrIGZyZXF1ZW5jaWVzIGFyZSBub3QKKy8vLyBjb21wdXRlZCB3aGVuIHRoZSBhbmFseXNpcyBwYXNzIGlzIGV4ZWN1dGVkIGJ1dCByYXRoZXIgd2hlbiB0aGUgQkZJIHJlc3VsdAorLy8vIGlzIGV4cGxpY2l0bHkgcmVxdWVzdGVkIGJ5IHRoZSBhbmFseXNpcyBjbGllbnQuCisvLy8KKy8vLyBUaGlzIHdvcmtzIGJ5IGNoZWNraW5nIHF1ZXJ5aW5nIGlmIE1CRkkgaXMgYXZhaWxhYmxlIGFuZCBvdGhlcndpc2UKKy8vLyBnZW5lcmF0aW5nIE1CRkkgb24gdGhlIGZseS4gIEluIHRoaXMgY2FzZSB0aGUgcGFzc2VzIHJlcXVpcmVkIGZvciAoTEksIERUKQorLy8vIGFyZSBhbHNvIHF1ZXJpZWQgYmVmb3JlIGJlaW5nIGNvbXB1dGVkIG9uIHRoZSBmbHkuCisvLy8KKy8vLyBOb3RlIHRoYXQgaXQgaXMgZXhwZWN0ZWQgdGhhdCB3ZSB3b3VsZG4ndCBuZWVkIHRoaXMgZnVuY3Rpb25hbGl0eSBmb3IgdGhlCisvLy8gbmV3IFBNIHNpbmNlIHdpdGggdGhlIG5ldyBQTSwgYW5hbHlzZXMgYXJlIGV4ZWN1dGVkIG9uIGRlbWFuZC4KKworY2xhc3MgTGF6eU1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm9QYXNzIDogcHVibGljIE1hY2hpbmVGdW5jdGlvblBhc3MgeworcHJpdmF0ZToKKyAgLy8vIElmIGdlbmVyYXRlZCBvbiB0aGUgZmx5IHRoaXMgb3duIHRoZSBpbnN0YW5jZS4KKyAgbXV0YWJsZSBzdGQ6OnVuaXF1ZV9wdHI8TWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mbz4gT3duZWRNQkZJOworCisgIC8vLyBJZiBnZW5lcmF0ZWQgb24gdGhlIGZseSB0aGlzIG93biB0aGUgaW5zdGFuY2UuCisgIG11dGFibGUgc3RkOjp1bmlxdWVfcHRyPE1hY2hpbmVMb29wSW5mbz4gT3duZWRNTEk7CisKKyAgLy8vIElmIGdlbmVyYXRlZCBvbiB0aGUgZmx5IHRoaXMgb3duIHRoZSBpbnN0YW5jZS4KKyAgbXV0YWJsZSBzdGQ6OnVuaXF1ZV9wdHI8TWFjaGluZURvbWluYXRvclRyZWU+IE93bmVkTURUOworCisgIC8vLyBUaGUgZnVuY3Rpb24uCisgIE1hY2hpbmVGdW5jdGlvbiAqTUYgPSBudWxscHRyOworCisgIC8vLyBcYnJpZWYgQ2FsY3VsYXRlIE1CRkkgYW5kIGFsbCBvdGhlciBhbmFseXNlcyB0aGF0J3Mgbm90IGF2YWlsYWJsZSBhbmQKKyAgLy8vIHJlcXVpcmVkIGJ5IEJGSS4KKyAgTWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mbyAmY2FsY3VsYXRlSWZOb3RBdmFpbGFibGUoKSBjb25zdDsKKworcHVibGljOgorICBzdGF0aWMgY2hhciBJRDsKKworICBMYXp5TWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mb1Bhc3MoKTsKKworICAvLy8gXGJyaWVmIENvbXB1dGUgYW5kIHJldHVybiB0aGUgYmxvY2sgZnJlcXVlbmNpZXMuCisgIE1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm8gJmdldEJGSSgpIHsgcmV0dXJuIGNhbGN1bGF0ZUlmTm90QXZhaWxhYmxlKCk7IH0KKworICAvLy8gXGJyaWVmIENvbXB1dGUgYW5kIHJldHVybiB0aGUgYmxvY2sgZnJlcXVlbmNpZXMuCisgIGNvbnN0IE1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm8gJmdldEJGSSgpIGNvbnN0IHsKKyAgICByZXR1cm4gY2FsY3VsYXRlSWZOb3RBdmFpbGFibGUoKTsKKyAgfQorCisgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlICZBVSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgYm9vbCBydW5Pbk1hY2hpbmVGdW5jdGlvbihNYWNoaW5lRnVuY3Rpb24gJkYpIG92ZXJyaWRlOworICB2b2lkIHJlbGVhc2VNZW1vcnkoKSBvdmVycmlkZTsKKyAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MsIGNvbnN0IE1vZHVsZSAqTSkgY29uc3Qgb3ZlcnJpZGU7Cit9OworfQorI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGV4aWNhbFNjb3Blcy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xleGljYWxTY29wZXMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYmE1MDM0Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xleGljYWxTY29wZXMuaApAQCAtMCwwICsxLDI1OCBAQAorLy89PT0tIExleGljYWxTY29wZXMuY3BwIC0gQ29sbGVjdGluZyBsZXhpY2FsIHNjb3BlIGluZm8gLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgaW1wbGVtZW50cyBMZXhpY2FsU2NvcGVzIGFuYWx5c2lzLgorLy8KKy8vIFRoaXMgcGFzcyBjb2xsZWN0cyBsZXhpY2FsIHNjb3BlIGluZm9ybWF0aW9uIGFuZCBtYXBzIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zCisvLyB0byByZXNwZWN0aXZlIGxleGljYWwgc2NvcGVzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0xFWElDQUxTQ09QRVNfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTEVYSUNBTFNDT1BFU19ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9BcnJheVJlZi5oIgorI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxQdHJTZXQuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vSVIvRGVidWdJbmZvTWV0YWRhdGEuaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPHVub3JkZXJlZF9tYXA+CisjaW5jbHVkZSA8dXRpbGl0eT4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNYWNoaW5lQmFzaWNCbG9jazsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIE1hY2hpbmVJbnN0cjsKK2NsYXNzIE1ETm9kZTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLyBJbnNuUmFuZ2UgLSBUaGlzIGlzIHVzZWQgdG8gdHJhY2sgcmFuZ2Ugb2YgaW5zdHJ1Y3Rpb25zIHdpdGggaWRlbnRpY2FsCisvLy8gbGV4aWNhbCBzY29wZS4KKy8vLwordXNpbmcgSW5zblJhbmdlID0gc3RkOjpwYWlyPGNvbnN0IE1hY2hpbmVJbnN0ciAqLCBjb25zdCBNYWNoaW5lSW5zdHIgKj47CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gTGV4aWNhbFNjb3BlIC0gVGhpcyBjbGFzcyBpcyB1c2VkIHRvIHRyYWNrIHNjb3BlIGluZm9ybWF0aW9uLgorLy8vCitjbGFzcyBMZXhpY2FsU2NvcGUgeworcHVibGljOgorICBMZXhpY2FsU2NvcGUoTGV4aWNhbFNjb3BlICpQLCBjb25zdCBESUxvY2FsU2NvcGUgKkQsIGNvbnN0IERJTG9jYXRpb24gKkksCisgICAgICAgICAgICAgICBib29sIEEpCisgICAgICA6IFBhcmVudChQKSwgRGVzYyhEKSwgSW5saW5lZEF0TG9jYXRpb24oSSksIEFic3RyYWN0U2NvcGUoQSkgeworICAgIGFzc2VydChEKTsKKyAgICBhc3NlcnQoRC0+Z2V0U3VicHJvZ3JhbSgpLT5nZXRVbml0KCktPmdldEVtaXNzaW9uS2luZCgpICE9CisgICAgICAgICAgIERJQ29tcGlsZVVuaXQ6Ok5vRGVidWcgJiYKKyAgICAgICAgICAgIkRvbid0IGJ1aWxkIGxleGljYWwgc2NvcGVzIGZvciBub24tZGVidWcgbG9jYXRpb25zIik7CisgICAgYXNzZXJ0KEQtPmlzUmVzb2x2ZWQoKSAmJiAiRXhwZWN0ZWQgcmVzb2x2ZWQgbm9kZSIpOworICAgIGFzc2VydCgoIUkgfHwgSS0+aXNSZXNvbHZlZCgpKSAmJiAiRXhwZWN0ZWQgcmVzb2x2ZWQgbm9kZSIpOworICAgIGlmIChQYXJlbnQpCisgICAgICBQYXJlbnQtPmFkZENoaWxkKHRoaXMpOworICB9CisKKyAgLy8gQWNjZXNzb3JzLgorICBMZXhpY2FsU2NvcGUgKmdldFBhcmVudCgpIGNvbnN0IHsgcmV0dXJuIFBhcmVudDsgfQorICBjb25zdCBNRE5vZGUgKmdldERlc2MoKSBjb25zdCB7IHJldHVybiBEZXNjOyB9CisgIGNvbnN0IERJTG9jYXRpb24gKmdldElubGluZWRBdCgpIGNvbnN0IHsgcmV0dXJuIElubGluZWRBdExvY2F0aW9uOyB9CisgIGNvbnN0IERJTG9jYWxTY29wZSAqZ2V0U2NvcGVOb2RlKCkgY29uc3QgeyByZXR1cm4gRGVzYzsgfQorICBib29sIGlzQWJzdHJhY3RTY29wZSgpIGNvbnN0IHsgcmV0dXJuIEFic3RyYWN0U2NvcGU7IH0KKyAgU21hbGxWZWN0b3JJbXBsPExleGljYWxTY29wZSAqPiAmZ2V0Q2hpbGRyZW4oKSB7IHJldHVybiBDaGlsZHJlbjsgfQorICBTbWFsbFZlY3RvckltcGw8SW5zblJhbmdlPiAmZ2V0UmFuZ2VzKCkgeyByZXR1cm4gUmFuZ2VzOyB9CisKKyAgLy8vIGFkZENoaWxkIC0gQWRkIGEgY2hpbGQgc2NvcGUuCisgIHZvaWQgYWRkQ2hpbGQoTGV4aWNhbFNjb3BlICpTKSB7IENoaWxkcmVuLnB1c2hfYmFjayhTKTsgfQorCisgIC8vLyBvcGVuSW5zblJhbmdlIC0gVGhpcyBzY29wZSBjb3ZlcnMgaW5zdHJ1Y3Rpb24gcmFuZ2Ugc3RhcnRpbmcgZnJvbSBNSS4KKyAgdm9pZCBvcGVuSW5zblJhbmdlKGNvbnN0IE1hY2hpbmVJbnN0ciAqTUkpIHsKKyAgICBpZiAoIUZpcnN0SW5zbikKKyAgICAgIEZpcnN0SW5zbiA9IE1JOworCisgICAgaWYgKFBhcmVudCkKKyAgICAgIFBhcmVudC0+b3Blbkluc25SYW5nZShNSSk7CisgIH0KKworICAvLy8gZXh0ZW5kSW5zblJhbmdlIC0gRXh0ZW5kIHRoZSBjdXJyZW50IGluc3RydWN0aW9uIHJhbmdlIGNvdmVyZWQgYnkKKyAgLy8vIHRoaXMgc2NvcGUuCisgIHZvaWQgZXh0ZW5kSW5zblJhbmdlKGNvbnN0IE1hY2hpbmVJbnN0ciAqTUkpIHsKKyAgICBhc3NlcnQoRmlyc3RJbnNuICYmICJNSSBSYW5nZSBpcyBub3Qgb3BlbiEiKTsKKyAgICBMYXN0SW5zbiA9IE1JOworICAgIGlmIChQYXJlbnQpCisgICAgICBQYXJlbnQtPmV4dGVuZEluc25SYW5nZShNSSk7CisgIH0KKworICAvLy8gY2xvc2VJbnNuUmFuZ2UgLSBDcmVhdGUgYSByYW5nZSBiYXNlZCBvbiBGaXJzdEluc24gYW5kIExhc3RJbnNuIGNvbGxlY3RlZAorICAvLy8gdW50aWwgbm93LiBUaGlzIGlzIHVzZWQgd2hlbiBhIG5ldyBzY29wZSBpcyBlbmNvdW50ZXJlZCB3aGlsZSB3YWxraW5nCisgIC8vLyBtYWNoaW5lIGluc3RydWN0aW9ucy4KKyAgdm9pZCBjbG9zZUluc25SYW5nZShMZXhpY2FsU2NvcGUgKk5ld1Njb3BlID0gbnVsbHB0cikgeworICAgIGFzc2VydChMYXN0SW5zbiAmJiAiTGFzdCBpbnNuIG1pc3NpbmchIik7CisgICAgUmFuZ2VzLnB1c2hfYmFjayhJbnNuUmFuZ2UoRmlyc3RJbnNuLCBMYXN0SW5zbikpOworICAgIEZpcnN0SW5zbiA9IG51bGxwdHI7CisgICAgTGFzdEluc24gPSBudWxscHRyOworICAgIC8vIElmIFBhcmVudCBkb21pbmF0ZXMgTmV3U2NvcGUgdGhlbiBkbyBub3QgY2xvc2UgUGFyZW50J3MgaW5zdHJ1Y3Rpb24KKyAgICAvLyByYW5nZS4KKyAgICBpZiAoUGFyZW50ICYmICghTmV3U2NvcGUgfHwgIVBhcmVudC0+ZG9taW5hdGVzKE5ld1Njb3BlKSkpCisgICAgICBQYXJlbnQtPmNsb3NlSW5zblJhbmdlKE5ld1Njb3BlKTsKKyAgfQorCisgIC8vLyBkb21pbmF0ZXMgLSBSZXR1cm4gdHJ1ZSBpZiBjdXJyZW50IHNjb3BlIGRvbWluYXRlcyBnaXZlbiBsZXhpY2FsIHNjb3BlLgorICBib29sIGRvbWluYXRlcyhjb25zdCBMZXhpY2FsU2NvcGUgKlMpIGNvbnN0IHsKKyAgICBpZiAoUyA9PSB0aGlzKQorICAgICAgcmV0dXJuIHRydWU7CisgICAgaWYgKERGU0luIDwgUy0+Z2V0REZTSW4oKSAmJiBERlNPdXQgPiBTLT5nZXRERlNPdXQoKSkKKyAgICAgIHJldHVybiB0cnVlOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vIERlcHRoIEZpcnN0IFNlYXJjaCBzdXBwb3J0IHRvIHdhbGsgYW5kIG1hbmlwdWxhdGUgTGV4aWNhbFNjb3BlIGhpZXJhcmNoeS4KKyAgdW5zaWduZWQgZ2V0REZTT3V0KCkgY29uc3QgeyByZXR1cm4gREZTT3V0OyB9CisgIHZvaWQgc2V0REZTT3V0KHVuc2lnbmVkIE8pIHsgREZTT3V0ID0gTzsgfQorICB1bnNpZ25lZCBnZXRERlNJbigpIGNvbnN0IHsgcmV0dXJuIERGU0luOyB9CisgIHZvaWQgc2V0REZTSW4odW5zaWduZWQgSSkgeyBERlNJbiA9IEk7IH0KKworICAvLy8gZHVtcCAtIHByaW50IGxleGljYWwgc2NvcGUuCisgIHZvaWQgZHVtcCh1bnNpZ25lZCBJbmRlbnQgPSAwKSBjb25zdDsKKworcHJpdmF0ZToKKyAgTGV4aWNhbFNjb3BlICpQYXJlbnQ7ICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGFyZW50IHRvIHRoaXMgc2NvcGUuCisgIGNvbnN0IERJTG9jYWxTY29wZSAqRGVzYzsgICAgICAgICAgICAgICAgICAgIC8vIERlYnVnIGluZm8gZGVzY3JpcHRvci4KKyAgY29uc3QgRElMb2NhdGlvbiAqSW5saW5lZEF0TG9jYXRpb247ICAgICAgICAgLy8gTG9jYXRpb24gYXQgd2hpY2ggdGhpcworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzY29wZSBpcyBpbmxpbmVkLgorICBib29sIEFic3RyYWN0U2NvcGU7ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBYnN0cmFjdCBTY29wZQorICBTbWFsbFZlY3RvcjxMZXhpY2FsU2NvcGUgKiwgND4gQ2hpbGRyZW47ICAgICAvLyBTY29wZXMgZGVmaW5lZCBpbiBzY29wZS4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29udGVudHMgbm90IG93bmVkLgorICBTbWFsbFZlY3RvcjxJbnNuUmFuZ2UsIDQ+IFJhbmdlczsKKworICBjb25zdCBNYWNoaW5lSW5zdHIgKkxhc3RJbnNuID0gbnVsbHB0cjsgIC8vIExhc3QgaW5zdHJ1Y3Rpb24gb2YgdGhpcyBzY29wZS4KKyAgY29uc3QgTWFjaGluZUluc3RyICpGaXJzdEluc24gPSBudWxscHRyOyAvLyBGaXJzdCBpbnN0cnVjdGlvbiBvZiB0aGlzIHNjb3BlLgorICB1bnNpZ25lZCBERlNJbiA9IDA7IC8vIEluICYgT3V0IERlcHRoIHVzZSB0byBkZXRlcm1pbmUgc2NvcGUgbmVzdGluZy4KKyAgdW5zaWduZWQgREZTT3V0ID0gMDsKK307CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gTGV4aWNhbFNjb3BlcyAtICBUaGlzIGNsYXNzIHByb3ZpZGVzIGludGVyZmFjZSB0byBjb2xsZWN0IGFuZCB1c2UgbGV4aWNhbAorLy8vIHNjb3BpbmcgaW5mb3JtYXRpb24gZnJvbSBtYWNoaW5lIGluc3RydWN0aW9uLgorLy8vCitjbGFzcyBMZXhpY2FsU2NvcGVzIHsKK3B1YmxpYzoKKyAgTGV4aWNhbFNjb3BlcygpID0gZGVmYXVsdDsKKworICAvLy8gaW5pdGlhbGl6ZSAtIFNjYW4gbWFjaGluZSBmdW5jdGlvbiBhbmQgY29uc3R1Y3QgbGV4aWNhbCBzY29wZSBuZXN0LCByZXNldHMKKyAgLy8vIHRoZSBpbnN0YW5jZSBpZiBuZWNlc3NhcnkuCisgIHZvaWQgaW5pdGlhbGl6ZShjb25zdCBNYWNoaW5lRnVuY3Rpb24gJik7CisKKyAgLy8vIHJlbGVhc2VNZW1vcnkgLSByZWxlYXNlIG1lbW9yeS4KKyAgdm9pZCByZXNldCgpOworCisgIC8vLyBlbXB0eSAtIFJldHVybiB0cnVlIGlmIHRoZXJlIGlzIGFueSBsZXhpY2FsIHNjb3BlIGluZm9ybWF0aW9uIGF2YWlsYWJsZS4KKyAgYm9vbCBlbXB0eSgpIHsgcmV0dXJuIEN1cnJlbnRGbkxleGljYWxTY29wZSA9PSBudWxscHRyOyB9CisKKyAgLy8vIGdldEN1cnJlbnRGdW5jdGlvblNjb3BlIC0gUmV0dXJuIGxleGljYWwgc2NvcGUgZm9yIHRoZSBjdXJyZW50IGZ1bmN0aW9uLgorICBMZXhpY2FsU2NvcGUgKmdldEN1cnJlbnRGdW5jdGlvblNjb3BlKCkgY29uc3QgeworICAgIHJldHVybiBDdXJyZW50Rm5MZXhpY2FsU2NvcGU7CisgIH0KKworICAvLy8gZ2V0TWFjaGluZUJhc2ljQmxvY2tzIC0gUG9wdWxhdGUgZ2l2ZW4gc2V0IHVzaW5nIG1hY2hpbmUgYmFzaWMgYmxvY2tzCisgIC8vLyB3aGljaCBoYXZlIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zIHRoYXQgYmVsb25nIHRvIGxleGljYWwgc2NvcGUgaWRlbnRpZmllZCBieQorICAvLy8gRGVidWdMb2MuCisgIHZvaWQgZ2V0TWFjaGluZUJhc2ljQmxvY2tzKGNvbnN0IERJTG9jYXRpb24gKkRMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFB0clNldEltcGw8Y29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKj4gJk1CQnMpOworCisgIC8vLyBkb21pbmF0ZXMgLSBSZXR1cm4gdHJ1ZSBpZiBEZWJ1Z0xvYydzIGxleGljYWwgc2NvcGUgZG9taW5hdGVzIGF0IGxlYXN0IG9uZQorICAvLy8gbWFjaGluZSBpbnN0cnVjdGlvbidzIGxleGljYWwgc2NvcGUgaW4gYSBnaXZlbiBtYWNoaW5lIGJhc2ljIGJsb2NrLgorICBib29sIGRvbWluYXRlcyhjb25zdCBESUxvY2F0aW9uICpETCwgTWFjaGluZUJhc2ljQmxvY2sgKk1CQik7CisKKyAgLy8vIGZpbmRMZXhpY2FsU2NvcGUgLSBGaW5kIGxleGljYWwgc2NvcGUsIGVpdGhlciByZWd1bGFyIG9yIGlubGluZWQsIGZvciB0aGUKKyAgLy8vIGdpdmVuIERlYnVnTG9jLiBSZXR1cm4gTlVMTCBpZiBub3QgZm91bmQuCisgIExleGljYWxTY29wZSAqZmluZExleGljYWxTY29wZShjb25zdCBESUxvY2F0aW9uICpETCk7CisKKyAgLy8vIGdldEFic3RyYWN0U2NvcGVzTGlzdCAtIFJldHVybiBhIHJlZmVyZW5jZSB0byBsaXN0IG9mIGFic3RyYWN0IHNjb3Blcy4KKyAgQXJyYXlSZWY8TGV4aWNhbFNjb3BlICo+IGdldEFic3RyYWN0U2NvcGVzTGlzdCgpIGNvbnN0IHsKKyAgICByZXR1cm4gQWJzdHJhY3RTY29wZXNMaXN0OworICB9CisKKyAgLy8vIGZpbmRBYnN0cmFjdFNjb3BlIC0gRmluZCBhbiBhYnN0cmFjdCBzY29wZSBvciByZXR1cm4gbnVsbC4KKyAgTGV4aWNhbFNjb3BlICpmaW5kQWJzdHJhY3RTY29wZShjb25zdCBESUxvY2FsU2NvcGUgKk4pIHsKKyAgICBhdXRvIEkgPSBBYnN0cmFjdFNjb3BlTWFwLmZpbmQoTik7CisgICAgcmV0dXJuIEkgIT0gQWJzdHJhY3RTY29wZU1hcC5lbmQoKSA/ICZJLT5zZWNvbmQgOiBudWxscHRyOworICB9CisKKyAgLy8vIGZpbmRJbmxpbmVkU2NvcGUgLSBGaW5kIGFuIGlubGluZWQgc2NvcGUgZm9yIHRoZSBnaXZlbiBzY29wZS9pbmxpbmVkLWF0LgorICBMZXhpY2FsU2NvcGUgKmZpbmRJbmxpbmVkU2NvcGUoY29uc3QgRElMb2NhbFNjb3BlICpOLCBjb25zdCBESUxvY2F0aW9uICpJQSkgeworICAgIGF1dG8gSSA9IElubGluZWRMZXhpY2FsU2NvcGVNYXAuZmluZChzdGQ6Om1ha2VfcGFpcihOLCBJQSkpOworICAgIHJldHVybiBJICE9IElubGluZWRMZXhpY2FsU2NvcGVNYXAuZW5kKCkgPyAmSS0+c2Vjb25kIDogbnVsbHB0cjsKKyAgfQorCisgIC8vLyBmaW5kTGV4aWNhbFNjb3BlIC0gRmluZCByZWd1bGFyIGxleGljYWwgc2NvcGUgb3IgcmV0dXJuIG51bGwuCisgIExleGljYWxTY29wZSAqZmluZExleGljYWxTY29wZShjb25zdCBESUxvY2FsU2NvcGUgKk4pIHsKKyAgICBhdXRvIEkgPSBMZXhpY2FsU2NvcGVNYXAuZmluZChOKTsKKyAgICByZXR1cm4gSSAhPSBMZXhpY2FsU2NvcGVNYXAuZW5kKCkgPyAmSS0+c2Vjb25kIDogbnVsbHB0cjsKKyAgfQorCisgIC8vLyBkdW1wIC0gUHJpbnQgZGF0YSBzdHJ1Y3R1cmVzIHRvIGRiZ3MoKS4KKyAgdm9pZCBkdW1wKCkgY29uc3Q7CisKKyAgLy8vIGdldE9yQ3JlYXRlQWJzdHJhY3RTY29wZSAtIEZpbmQgb3IgY3JlYXRlIGFuIGFic3RyYWN0IGxleGljYWwgc2NvcGUuCisgIExleGljYWxTY29wZSAqZ2V0T3JDcmVhdGVBYnN0cmFjdFNjb3BlKGNvbnN0IERJTG9jYWxTY29wZSAqU2NvcGUpOworCitwcml2YXRlOgorICAvLy8gZ2V0T3JDcmVhdGVMZXhpY2FsU2NvcGUgLSBGaW5kIGxleGljYWwgc2NvcGUgZm9yIHRoZSBnaXZlbiBTY29wZS9JQS4gSWYKKyAgLy8vIG5vdCBhdmFpbGFibGUgdGhlbiBjcmVhdGUgbmV3IGxleGljYWwgc2NvcGUuCisgIExleGljYWxTY29wZSAqZ2V0T3JDcmVhdGVMZXhpY2FsU2NvcGUoY29uc3QgRElMb2NhbFNjb3BlICpTY29wZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBESUxvY2F0aW9uICpJQSA9IG51bGxwdHIpOworICBMZXhpY2FsU2NvcGUgKmdldE9yQ3JlYXRlTGV4aWNhbFNjb3BlKGNvbnN0IERJTG9jYXRpb24gKkRMKSB7CisgICAgcmV0dXJuIERMID8gZ2V0T3JDcmVhdGVMZXhpY2FsU2NvcGUoREwtPmdldFNjb3BlKCksIERMLT5nZXRJbmxpbmVkQXQoKSkKKyAgICAgICAgICAgICAgOiBudWxscHRyOworICB9CisKKyAgLy8vIGdldE9yQ3JlYXRlUmVndWxhclNjb3BlIC0gRmluZCBvciBjcmVhdGUgYSByZWd1bGFyIGxleGljYWwgc2NvcGUuCisgIExleGljYWxTY29wZSAqZ2V0T3JDcmVhdGVSZWd1bGFyU2NvcGUoY29uc3QgRElMb2NhbFNjb3BlICpTY29wZSk7CisKKyAgLy8vIGdldE9yQ3JlYXRlSW5saW5lZFNjb3BlIC0gRmluZCBvciBjcmVhdGUgYW4gaW5saW5lZCBsZXhpY2FsIHNjb3BlLgorICBMZXhpY2FsU2NvcGUgKmdldE9yQ3JlYXRlSW5saW5lZFNjb3BlKGNvbnN0IERJTG9jYWxTY29wZSAqU2NvcGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRElMb2NhdGlvbiAqSW5saW5lZEF0KTsKKworICAvLy8gZXh0cmFjdExleGljYWxTY29wZXMgLSBFeHRyYWN0IGluc3RydWN0aW9uIHJhbmdlcyBmb3IgZWFjaCBsZXhpY2FsIHNjb3BlcworICAvLy8gZm9yIHRoZSBnaXZlbiBtYWNoaW5lIGZ1bmN0aW9uLgorICB2b2lkIGV4dHJhY3RMZXhpY2FsU2NvcGVzKFNtYWxsVmVjdG9ySW1wbDxJbnNuUmFuZ2U+ICZNSVJhbmdlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZW5zZU1hcDxjb25zdCBNYWNoaW5lSW5zdHIgKiwgTGV4aWNhbFNjb3BlICo+ICZNKTsKKyAgdm9pZCBjb25zdHJ1Y3RTY29wZU5lc3QoTGV4aWNhbFNjb3BlICpTY29wZSk7CisgIHZvaWQKKyAgYXNzaWduSW5zdHJ1Y3Rpb25SYW5nZXMoU21hbGxWZWN0b3JJbXBsPEluc25SYW5nZT4gJk1JUmFuZ2VzLAorICAgICAgICAgICAgICAgICAgICAgICAgICBEZW5zZU1hcDxjb25zdCBNYWNoaW5lSW5zdHIgKiwgTGV4aWNhbFNjb3BlICo+ICZNKTsKKworICBjb25zdCBNYWNoaW5lRnVuY3Rpb24gKk1GID0gbnVsbHB0cjsKKworICAvLy8gTGV4aWNhbFNjb3BlTWFwIC0gVHJhY2tzIHRoZSBzY29wZXMgaW4gdGhlIGN1cnJlbnQgZnVuY3Rpb24uCisgIC8vIFVzZSBhbiB1bm9yZGVyZWRfbWFwIHRvIGVuc3VyZSB2YWx1ZSBwb2ludGVyIHZhbGlkaXR5IG92ZXIgaW5zZXJ0aW9uLgorICBzdGQ6OnVub3JkZXJlZF9tYXA8Y29uc3QgRElMb2NhbFNjb3BlICosIExleGljYWxTY29wZT4gTGV4aWNhbFNjb3BlTWFwOworCisgIC8vLyBJbmxpbmVkTGV4aWNhbFNjb3BlTWFwIC0gVHJhY2tzIGlubGluZWQgZnVuY3Rpb24gc2NvcGVzIGluIGN1cnJlbnQKKyAgLy8vIGZ1bmN0aW9uLgorICBzdGQ6OnVub3JkZXJlZF9tYXA8c3RkOjpwYWlyPGNvbnN0IERJTG9jYWxTY29wZSAqLCBjb25zdCBESUxvY2F0aW9uICo+LAorICAgICAgICAgICAgICAgICAgICAgTGV4aWNhbFNjb3BlLAorICAgICAgICAgICAgICAgICAgICAgcGFpcl9oYXNoPGNvbnN0IERJTG9jYWxTY29wZSAqLCBjb25zdCBESUxvY2F0aW9uICo+PgorICAgICAgSW5saW5lZExleGljYWxTY29wZU1hcDsKKworICAvLy8gQWJzdHJhY3RTY29wZU1hcCAtIFRoZXNlIHNjb3BlcyBhcmUgIG5vdCBpbmNsdWRlZCBMZXhpY2FsU2NvcGVNYXAuCisgIC8vIFVzZSBhbiB1bm9yZGVyZWRfbWFwIHRvIGVuc3VyZSB2YWx1ZSBwb2ludGVyIHZhbGlkaXR5IG92ZXIgaW5zZXJ0aW9uLgorICBzdGQ6OnVub3JkZXJlZF9tYXA8Y29uc3QgRElMb2NhbFNjb3BlICosIExleGljYWxTY29wZT4gQWJzdHJhY3RTY29wZU1hcDsKKworICAvLy8gQWJzdHJhY3RTY29wZXNMaXN0IC0gVHJhY2tzIGFic3RyYWN0IHNjb3BlcyBjb25zdHJ1Y3RlZCB3aGlsZSBwcm9jZXNzaW5nCisgIC8vLyBhIGZ1bmN0aW9uLgorICBTbWFsbFZlY3RvcjxMZXhpY2FsU2NvcGUgKiwgND4gQWJzdHJhY3RTY29wZXNMaXN0OworCisgIC8vLyBDdXJyZW50Rm5MZXhpY2FsU2NvcGUgLSBUb3AgbGV2ZWwgc2NvcGUgZm9yIHRoZSBjdXJyZW50IGZ1bmN0aW9uLgorICAvLy8KKyAgTGV4aWNhbFNjb3BlICpDdXJyZW50Rm5MZXhpY2FsU2NvcGUgPSBudWxscHRyOworfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9MRVhJQ0FMU0NPUEVTX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9MaW5rQWxsQXNtV3JpdGVyQ29tcG9uZW50cy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xpbmtBbGxBc21Xcml0ZXJDb21wb25lbnRzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzMwNDZkYQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9MaW5rQWxsQXNtV3JpdGVyQ29tcG9uZW50cy5oCkBAIC0wLDAgKzEsMzggQEAKKy8vPT09LSBsbHZtL0NvZGVnZW4vTGlua0FsbEFzbVdyaXRlckNvbXBvbmVudHMuaCAtLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgaGVhZGVyIGZpbGUgcHVsbHMgaW4gYWxsIGFzc2VtYmxlciB3cml0ZXIgcmVsYXRlZCBwYXNzZXMgZm9yIHRvb2xzIGxpa2UKKy8vIGxsYyB0aGF0IG5lZWQgdGhpcyBmdW5jdGlvbmFsaXR5LgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0xJTktBTExBU01XUklURVJDT01QT05FTlRTX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0xJTktBTExBU01XUklURVJDT01QT05FTlRTX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9HQ3MuaCIKKyNpbmNsdWRlIDxjc3RkbGliPgorCituYW1lc3BhY2UgeworICBzdHJ1Y3QgRm9yY2VBc21Xcml0ZXJMaW5raW5nIHsKKyAgICBGb3JjZUFzbVdyaXRlckxpbmtpbmcoKSB7CisgICAgICAvLyBXZSBtdXN0IHJlZmVyZW5jZSB0aGUgcGx1Zy1pbnMgaW4gc3VjaCBhIHdheSB0aGF0IGNvbXBpbGVycyB3aWxsIG5vdAorICAgICAgLy8gZGVsZXRlIGl0IGFsbCBhcyBkZWFkIGNvZGUsIGV2ZW4gd2l0aCB3aG9sZSBwcm9ncmFtIG9wdGltaXphdGlvbiwKKyAgICAgIC8vIHlldCBpcyBlZmZlY3RpdmVseSBhIE5PLU9QLiBBcyB0aGUgY29tcGlsZXIgaXNuJ3Qgc21hcnQgZW5vdWdoCisgICAgICAvLyB0byBrbm93IHRoYXQgZ2V0ZW52KCkgbmV2ZXIgcmV0dXJucyAtMSwgdGhpcyB3aWxsIGRvIHRoZSBqb2IuCisgICAgICBpZiAoc3RkOjpnZXRlbnYoImJhciIpICE9IChjaGFyKikgLTEpCisgICAgICAgIHJldHVybjsKKworICAgICAgbGx2bTo6bGlua09jYW1sR0NQcmludGVyKCk7CisgICAgICBsbHZtOjpsaW5rRXJsYW5nR0NQcmludGVyKCk7CisKKyAgICB9CisgIH0gRm9yY2VBc21Xcml0ZXJMaW5raW5nOyAvLyBGb3JjZSBsaW5rIGJ5IGNyZWF0aW5nIGEgZ2xvYmFsIGRlZmluaXRpb24uCit9CisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTElOS0FMTEFTTVdSSVRFUkNPTVBPTkVOVFNfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xpbmtBbGxDb2RlZ2VuQ29tcG9uZW50cy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xpbmtBbGxDb2RlZ2VuQ29tcG9uZW50cy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZlZTEzMWUKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGlua0FsbENvZGVnZW5Db21wb25lbnRzLmgKQEAgLTAsMCArMSw1OSBAQAorLy89PT0tIGxsdm0vQ29kZWdlbi9MaW5rQWxsQ29kZWdlbkNvbXBvbmVudHMuaCAtLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBoZWFkZXIgZmlsZSBwdWxscyBpbiBhbGwgY29kZWdlbiByZWxhdGVkIHBhc3NlcyBmb3IgdG9vbHMgbGlrZSBsbGkgYW5kCisvLyBsbGMgdGhhdCBuZWVkIHRoaXMgZnVuY3Rpb25hbGl0eS4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9MSU5LQUxMQ09ERUdFTkNPTVBPTkVOVFNfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTElOS0FMTENPREVHRU5DT01QT05FTlRTX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9HQ3MuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vUGFzc2VzLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1NjaGVkdWxlclJlZ2lzdHJ5LmgiCisjaW5jbHVkZSAibGx2bS9UYXJnZXQvVGFyZ2V0TWFjaGluZS5oIgorI2luY2x1ZGUgPGNzdGRsaWI+CisKK25hbWVzcGFjZSB7CisgIHN0cnVjdCBGb3JjZUNvZGVnZW5MaW5raW5nIHsKKyAgICBGb3JjZUNvZGVnZW5MaW5raW5nKCkgeworICAgICAgLy8gV2UgbXVzdCByZWZlcmVuY2UgdGhlIHBhc3NlcyBpbiBzdWNoIGEgd2F5IHRoYXQgY29tcGlsZXJzIHdpbGwgbm90CisgICAgICAvLyBkZWxldGUgaXQgYWxsIGFzIGRlYWQgY29kZSwgZXZlbiB3aXRoIHdob2xlIHByb2dyYW0gb3B0aW1pemF0aW9uLAorICAgICAgLy8geWV0IGlzIGVmZmVjdGl2ZWx5IGEgTk8tT1AuIEFzIHRoZSBjb21waWxlciBpc24ndCBzbWFydCBlbm91Z2gKKyAgICAgIC8vIHRvIGtub3cgdGhhdCBnZXRlbnYoKSBuZXZlciByZXR1cm5zIC0xLCB0aGlzIHdpbGwgZG8gdGhlIGpvYi4KKyAgICAgIGlmIChzdGQ6OmdldGVudigiYmFyIikgIT0gKGNoYXIqKSAtMSkKKyAgICAgICAgcmV0dXJuOworCisgICAgICAodm9pZCkgbGx2bTo6Y3JlYXRlRmFzdFJlZ2lzdGVyQWxsb2NhdG9yKCk7CisgICAgICAodm9pZCkgbGx2bTo6Y3JlYXRlQmFzaWNSZWdpc3RlckFsbG9jYXRvcigpOworICAgICAgKHZvaWQpIGxsdm06OmNyZWF0ZUdyZWVkeVJlZ2lzdGVyQWxsb2NhdG9yKCk7CisgICAgICAodm9pZCkgbGx2bTo6Y3JlYXRlRGVmYXVsdFBCUVBSZWdpc3RlckFsbG9jYXRvcigpOworCisgICAgICBsbHZtOjpsaW5rQ29yZUNMUkdDKCk7CisgICAgICBsbHZtOjpsaW5rT2NhbWxHQygpOworICAgICAgbGx2bTo6bGlua0VybGFuZ0dDKCk7CisgICAgICBsbHZtOjpsaW5rU2hhZG93U3RhY2tHQygpOworICAgICAgbGx2bTo6bGlua1N0YXRlcG9pbnRFeGFtcGxlR0MoKTsKKworICAgICAgKHZvaWQpIGxsdm06OmNyZWF0ZUJVUlJMaXN0REFHU2NoZWR1bGVyKG51bGxwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGx2bTo6Q29kZUdlbk9wdDo6RGVmYXVsdCk7CisgICAgICAodm9pZCkgbGx2bTo6Y3JlYXRlU291cmNlTGlzdERBR1NjaGVkdWxlcihudWxscHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGx2bTo6Q29kZUdlbk9wdDo6RGVmYXVsdCk7CisgICAgICAodm9pZCkgbGx2bTo6Y3JlYXRlSHlicmlkTGlzdERBR1NjaGVkdWxlcihudWxscHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGx2bTo6Q29kZUdlbk9wdDo6RGVmYXVsdCk7CisgICAgICAodm9pZCkgbGx2bTo6Y3JlYXRlRmFzdERBR1NjaGVkdWxlcihudWxscHRyLCBsbHZtOjpDb2RlR2VuT3B0OjpEZWZhdWx0KTsKKyAgICAgICh2b2lkKSBsbHZtOjpjcmVhdGVEZWZhdWx0U2NoZWR1bGVyKG51bGxwdHIsIGxsdm06OkNvZGVHZW5PcHQ6OkRlZmF1bHQpOworICAgICAgKHZvaWQpIGxsdm06OmNyZWF0ZVZMSVdEQUdTY2hlZHVsZXIobnVsbHB0ciwgbGx2bTo6Q29kZUdlbk9wdDo6RGVmYXVsdCk7CisKKyAgICB9CisgIH0gRm9yY2VDb2RlZ2VuTGlua2luZzsgLy8gRm9yY2UgbGluayBieSBjcmVhdGluZyBhIGdsb2JhbCBkZWZpbml0aW9uLgorfQorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9MaXZlSW50ZXJ2YWwuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9MaXZlSW50ZXJ2YWwuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNGZhODcyCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xpdmVJbnRlcnZhbC5oCkBAIC0wLDAgKzEsOTQzIEBACisvLz09PS0gbGx2bS9Db2RlR2VuL0xpdmVJbnRlcnZhbC5oIC0gSW50ZXJ2YWwgcmVwcmVzZW50YXRpb24gLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBpbXBsZW1lbnRzIHRoZSBMaXZlUmFuZ2UgYW5kIExpdmVJbnRlcnZhbCBjbGFzc2VzLiAgR2l2ZW4gc29tZQorLy8gbnVtYmVyaW5nIG9mIGVhY2ggdGhlIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zIGFuIGludGVydmFsIFtpLCBqKSBpcyBzYWlkIHRvIGJlIGEKKy8vIGxpdmUgcmFuZ2UgZm9yIHJlZ2lzdGVyIHYgaWYgdGhlcmUgaXMgbm8gaW5zdHJ1Y3Rpb24gd2l0aCBudW1iZXIgaicgPj0gagorLy8gc3VjaCB0aGF0IHYgaXMgbGl2ZSBhdCBqJyBhbmQgdGhlcmUgaXMgbm8gaW5zdHJ1Y3Rpb24gd2l0aCBudW1iZXIgaScgPCBpIHN1Y2gKKy8vIHRoYXQgdiBpcyBsaXZlIGF0IGknLiBJbiB0aGlzIGltcGxlbWVudGF0aW9uIHJhbmdlcyBjYW4gaGF2ZSBob2xlcywKKy8vIGkuZS4gYSByYW5nZSBtaWdodCBsb29rIGxpa2UgWzEsMjApLCBbNTAsNjUpLCBbMTAwMCwxMDAxKS4gIEVhY2gKKy8vIGluZGl2aWR1YWwgc2VnbWVudCBpcyByZXByZXNlbnRlZCBhcyBhbiBpbnN0YW5jZSBvZiBMaXZlUmFuZ2U6OlNlZ21lbnQsCisvLyBhbmQgdGhlIHdob2xlIHJhbmdlIGlzIHJlcHJlc2VudGVkIGFzIGFuIGluc3RhbmNlIG9mIExpdmVSYW5nZS4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9MSVZFSU5URVJWQUxfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTElWRUlOVEVSVkFMX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0FycmF5UmVmLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvSW50RXFDbGFzc2VzLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU1RMRXh0cmFzLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9pdGVyYXRvcl9yYW5nZS5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9TbG90SW5kZXhlcy5oIgorI2luY2x1ZGUgImxsdm0vTUMvTGFuZUJpdG1hc2suaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvQWxsb2NhdG9yLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L01hdGhFeHRyYXMuaCIKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkZGVmPgorI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CisjaW5jbHVkZSA8bWVtb3J5PgorI2luY2x1ZGUgPHNldD4KKyNpbmNsdWRlIDx0dXBsZT4KKyNpbmNsdWRlIDx1dGlsaXR5PgorCituYW1lc3BhY2UgbGx2bSB7CisKKyAgY2xhc3MgQ29hbGVzY2VyUGFpcjsKKyAgY2xhc3MgTGl2ZUludGVydmFsczsKKyAgY2xhc3MgTWFjaGluZVJlZ2lzdGVySW5mbzsKKyAgY2xhc3MgcmF3X29zdHJlYW07CisKKyAgLy8vIFZOSW5mbyAtIFZhbHVlIE51bWJlciBJbmZvcm1hdGlvbi4KKyAgLy8vIFRoaXMgY2xhc3MgaG9sZHMgaW5mb3JtYXRpb24gYWJvdXQgYSBtYWNoaW5lIGxldmVsIHZhbHVlcywgaW5jbHVkaW5nCisgIC8vLyBkZWZpbml0aW9uIGFuZCB1c2UgcG9pbnRzLgorICAvLy8KKyAgY2xhc3MgVk5JbmZvIHsKKyAgcHVibGljOgorICAgIHVzaW5nIEFsbG9jYXRvciA9IEJ1bXBQdHJBbGxvY2F0b3I7CisKKyAgICAvLy8gVGhlIElEIG51bWJlciBvZiB0aGlzIHZhbHVlLgorICAgIHVuc2lnbmVkIGlkOworCisgICAgLy8vIFRoZSBpbmRleCBvZiB0aGUgZGVmaW5pbmcgaW5zdHJ1Y3Rpb24uCisgICAgU2xvdEluZGV4IGRlZjsKKworICAgIC8vLyBWTkluZm8gY29uc3RydWN0b3IuCisgICAgVk5JbmZvKHVuc2lnbmVkIGksIFNsb3RJbmRleCBkKSA6IGlkKGkpLCBkZWYoZCkge30KKworICAgIC8vLyBWTkluZm8gY29uc3RydWN0b3IsIGNvcGllcyB2YWx1ZXMgZnJvbSBvcmlnLCBleGNlcHQgZm9yIHRoZSB2YWx1ZSBudW1iZXIuCisgICAgVk5JbmZvKHVuc2lnbmVkIGksIGNvbnN0IFZOSW5mbyAmb3JpZykgOiBpZChpKSwgZGVmKG9yaWcuZGVmKSB7fQorCisgICAgLy8vIENvcHkgZnJvbSB0aGUgcGFyYW1ldGVyIGludG8gdGhpcyBWTkluZm8uCisgICAgdm9pZCBjb3B5RnJvbShWTkluZm8gJnNyYykgeworICAgICAgZGVmID0gc3JjLmRlZjsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoaXMgdmFsdWUgaXMgZGVmaW5lZCBieSBhIFBISSBpbnN0cnVjdGlvbiAob3Igd2FzLAorICAgIC8vLyBQSEkgaW5zdHJ1Y3Rpb25zIG1heSBoYXZlIGJlZW4gZWxpbWluYXRlZCkuCisgICAgLy8vIFBISS1kZWZzIGJlZ2luIGF0IGEgYmxvY2sgYm91bmRhcnksIGFsbCBvdGhlciBkZWZzIGJlZ2luIGF0IHJlZ2lzdGVyIG9yCisgICAgLy8vIEVDIHNsb3RzLgorICAgIGJvb2wgaXNQSElEZWYoKSBjb25zdCB7IHJldHVybiBkZWYuaXNCbG9jaygpOyB9CisKKyAgICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoaXMgdmFsdWUgaXMgdW51c2VkLgorICAgIGJvb2wgaXNVbnVzZWQoKSBjb25zdCB7IHJldHVybiAhZGVmLmlzVmFsaWQoKTsgfQorCisgICAgLy8vIE1hcmsgdGhpcyB2YWx1ZSBhcyB1bnVzZWQuCisgICAgdm9pZCBtYXJrVW51c2VkKCkgeyBkZWYgPSBTbG90SW5kZXgoKTsgfQorICB9OworCisgIC8vLyBSZXN1bHQgb2YgYSBMaXZlUmFuZ2UgcXVlcnkuIFRoaXMgY2xhc3MgaGlkZXMgdGhlIGltcGxlbWVudGF0aW9uIGRldGFpbHMKKyAgLy8vIG9mIGxpdmUgcmFuZ2VzLCBhbmQgaXQgc2hvdWxkIGJlIHVzZWQgYXMgdGhlIHByaW1hcnkgaW50ZXJmYWNlIGZvcgorICAvLy8gZXhhbWluaW5nIGxpdmUgcmFuZ2VzIGFyb3VuZCBpbnN0cnVjdGlvbnMuCisgIGNsYXNzIExpdmVRdWVyeVJlc3VsdCB7CisgICAgVk5JbmZvICpjb25zdCBFYXJseVZhbDsKKyAgICBWTkluZm8gKmNvbnN0IExhdGVWYWw7CisgICAgY29uc3QgU2xvdEluZGV4IEVuZFBvaW50OworICAgIGNvbnN0IGJvb2wgS2lsbDsKKworICBwdWJsaWM6CisgICAgTGl2ZVF1ZXJ5UmVzdWx0KFZOSW5mbyAqRWFybHlWYWwsIFZOSW5mbyAqTGF0ZVZhbCwgU2xvdEluZGV4IEVuZFBvaW50LAorICAgICAgICAgICAgICAgICAgICBib29sIEtpbGwpCisgICAgICA6IEVhcmx5VmFsKEVhcmx5VmFsKSwgTGF0ZVZhbChMYXRlVmFsKSwgRW5kUG9pbnQoRW5kUG9pbnQpLCBLaWxsKEtpbGwpCisgICAge30KKworICAgIC8vLyBSZXR1cm4gdGhlIHZhbHVlIHRoYXQgaXMgbGl2ZS1pbiB0byB0aGUgaW5zdHJ1Y3Rpb24uIFRoaXMgaXMgdGhlIHZhbHVlCisgICAgLy8vIHRoYXQgd2lsbCBiZSByZWFkIGJ5IHRoZSBpbnN0cnVjdGlvbidzIHVzZSBvcGVyYW5kcy4gUmV0dXJuIE5VTEwgaWYgbm8KKyAgICAvLy8gdmFsdWUgaXMgbGl2ZS1pbi4KKyAgICBWTkluZm8gKnZhbHVlSW4oKSBjb25zdCB7CisgICAgICByZXR1cm4gRWFybHlWYWw7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBsaXZlLWluIHZhbHVlIGlzIGtpbGxlZCBieSB0aGlzIGluc3RydWN0aW9uLiBUaGlzCisgICAgLy8vIG1lYW5zIHRoYXQgZWl0aGVyIHRoZSBsaXZlIHJhbmdlIGVuZHMgYXQgdGhlIGluc3RydWN0aW9uLCBvciBpdCBjaGFuZ2VzCisgICAgLy8vIHZhbHVlLgorICAgIGJvb2wgaXNLaWxsKCkgY29uc3QgeworICAgICAgcmV0dXJuIEtpbGw7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gaGFzIGEgZGVhZCBkZWYuCisgICAgYm9vbCBpc0RlYWREZWYoKSBjb25zdCB7CisgICAgICByZXR1cm4gRW5kUG9pbnQuaXNEZWFkKCk7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0aGUgdmFsdWUgbGVhdmluZyB0aGUgaW5zdHJ1Y3Rpb24sIGlmIGFueS4gVGhpcyBjYW4gYmUgYQorICAgIC8vLyBsaXZlLXRocm91Z2ggdmFsdWUsIG9yIGEgbGl2ZSBkZWYuIEEgZGVhZCBkZWYgcmV0dXJucyBOVUxMLgorICAgIFZOSW5mbyAqdmFsdWVPdXQoKSBjb25zdCB7CisgICAgICByZXR1cm4gaXNEZWFkRGVmKCkgPyBudWxscHRyIDogTGF0ZVZhbDsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0aGUgdmFsdWUgYWxpdmUgYXQgdGhlIGVuZCBvZiB0aGUgaW5zdHJ1Y3Rpb24sIGlmIGFueS4gVGhpcyBjYW4KKyAgICAvLy8gYmUgYSBsaXZlLXRocm91Z2ggdmFsdWUsIGEgbGl2ZSBkZWYgb3IgYSBkZWFkIGRlZi4KKyAgICBWTkluZm8gKnZhbHVlT3V0T3JEZWFkKCkgY29uc3QgeworICAgICAgcmV0dXJuIExhdGVWYWw7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0aGUgdmFsdWUgZGVmaW5lZCBieSB0aGlzIGluc3RydWN0aW9uLCBpZiBhbnkuIFRoaXMgaW5jbHVkZXMKKyAgICAvLy8gZGVhZCBkZWZzLCBpdCBpcyB0aGUgdmFsdWUgY3JlYXRlZCBieSB0aGUgaW5zdHJ1Y3Rpb24ncyBkZWYgb3BlcmFuZHMuCisgICAgVk5JbmZvICp2YWx1ZURlZmluZWQoKSBjb25zdCB7CisgICAgICByZXR1cm4gRWFybHlWYWwgPT0gTGF0ZVZhbCA/IG51bGxwdHIgOiBMYXRlVmFsOworICAgIH0KKworICAgIC8vLyBSZXR1cm4gdGhlIGVuZCBwb2ludCBvZiB0aGUgbGFzdCBsaXZlIHJhbmdlIHNlZ21lbnQgdG8gaW50ZXJhY3Qgd2l0aAorICAgIC8vLyB0aGUgaW5zdHJ1Y3Rpb24sIGlmIGFueS4KKyAgICAvLy8KKyAgICAvLy8gVGhlIGVuZCBwb2ludCBpcyBhbiBpbnZhbGlkIFNsb3RJbmRleCBvbmx5IGlmIHRoZSBsaXZlIHJhbmdlIGRvZXNuJ3QKKyAgICAvLy8gaW50ZXJzZWN0IHRoZSBpbnN0cnVjdGlvbiBhdCBhbGwuCisgICAgLy8vCisgICAgLy8vIFRoZSBlbmQgcG9pbnQgbWF5IGJlIGF0IG9yIHBhc3QgdGhlIGVuZCBvZiB0aGUgaW5zdHJ1Y3Rpb24ncyBiYXNpYworICAgIC8vLyBibG9jay4gVGhhdCBtZWFucyB0aGUgdmFsdWUgd2FzIGxpdmUgb3V0IG9mIHRoZSBibG9jay4KKyAgICBTbG90SW5kZXggZW5kUG9pbnQoKSBjb25zdCB7CisgICAgICByZXR1cm4gRW5kUG9pbnQ7CisgICAgfQorICB9OworCisgIC8vLyBUaGlzIGNsYXNzIHJlcHJlc2VudHMgdGhlIGxpdmVuZXNzIG9mIGEgcmVnaXN0ZXIsIHN0YWNrIHNsb3QsIGV0Yy4KKyAgLy8vIEl0IG1hbmFnZXMgYW4gb3JkZXJlZCBsaXN0IG9mIFNlZ21lbnQgb2JqZWN0cy4KKyAgLy8vIFRoZSBTZWdtZW50cyBhcmUgb3JnYW5pemVkIGluIGEgc3RhdGljIHNpbmdsZSBhc3NpZ25tZW50IGZvcm06IEF0IHBsYWNlcworICAvLy8gd2hlcmUgYSBuZXcgdmFsdWUgaXMgZGVmaW5lZCBvciBkaWZmZXJlbnQgdmFsdWVzIHJlYWNoIGEgQ0ZHIGpvaW4gYSBuZXcKKyAgLy8vIHNlZ21lbnQgd2l0aCBhIG5ldyB2YWx1ZSBudW1iZXIgaXMgdXNlZC4KKyAgY2xhc3MgTGl2ZVJhbmdlIHsKKyAgcHVibGljOgorICAgIC8vLyBUaGlzIHJlcHJlc2VudHMgYSBzaW1wbGUgY29udGludW91cyBsaXZlbmVzcyBpbnRlcnZhbCBmb3IgYSB2YWx1ZS4KKyAgICAvLy8gVGhlIHN0YXJ0IHBvaW50IGlzIGluY2x1c2l2ZSwgdGhlIGVuZCBwb2ludCBleGNsdXNpdmUuIFRoZXNlIGludGVydmFscworICAgIC8vLyBhcmUgcmVuZGVyZWQgYXMgW3N0YXJ0LGVuZCkuCisgICAgc3RydWN0IFNlZ21lbnQgeworICAgICAgU2xvdEluZGV4IHN0YXJ0OyAgLy8gU3RhcnQgcG9pbnQgb2YgdGhlIGludGVydmFsIChpbmNsdXNpdmUpCisgICAgICBTbG90SW5kZXggZW5kOyAgICAvLyBFbmQgcG9pbnQgb2YgdGhlIGludGVydmFsIChleGNsdXNpdmUpCisgICAgICBWTkluZm8gKnZhbG5vID0gbnVsbHB0cjsgLy8gaWRlbnRpZmllciBmb3IgdGhlIHZhbHVlIGNvbnRhaW5lZCBpbiB0aGlzCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2VnbWVudC4KKworICAgICAgU2VnbWVudCgpID0gZGVmYXVsdDsKKworICAgICAgU2VnbWVudChTbG90SW5kZXggUywgU2xvdEluZGV4IEUsIFZOSW5mbyAqVikKKyAgICAgICAgOiBzdGFydChTKSwgZW5kKEUpLCB2YWxubyhWKSB7CisgICAgICAgIGFzc2VydChTIDwgRSAmJiAiQ2Fubm90IGNyZWF0ZSBlbXB0eSBvciBiYWNrd2FyZHMgc2VnbWVudCIpOworICAgICAgfQorCisgICAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIGluZGV4IGlzIGNvdmVyZWQgYnkgdGhpcyBzZWdtZW50LgorICAgICAgYm9vbCBjb250YWlucyhTbG90SW5kZXggSSkgY29uc3QgeworICAgICAgICByZXR1cm4gc3RhcnQgPD0gSSAmJiBJIDwgZW5kOworICAgICAgfQorCisgICAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIGludGVydmFsLCBbUywgRSksIGlzIGNvdmVyZWQgYnkgdGhpcyBzZWdtZW50LgorICAgICAgYm9vbCBjb250YWluc0ludGVydmFsKFNsb3RJbmRleCBTLCBTbG90SW5kZXggRSkgY29uc3QgeworICAgICAgICBhc3NlcnQoKFMgPCBFKSAmJiAiQmFja3dhcmRzIGludGVydmFsPyIpOworICAgICAgICByZXR1cm4gKHN0YXJ0IDw9IFMgJiYgUyA8IGVuZCkgJiYgKHN0YXJ0IDwgRSAmJiBFIDw9IGVuZCk7CisgICAgICB9CisKKyAgICAgIGJvb2wgb3BlcmF0b3I8KGNvbnN0IFNlZ21lbnQgJk90aGVyKSBjb25zdCB7CisgICAgICAgIHJldHVybiBzdGQ6OnRpZShzdGFydCwgZW5kKSA8IHN0ZDo6dGllKE90aGVyLnN0YXJ0LCBPdGhlci5lbmQpOworICAgICAgfQorICAgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IFNlZ21lbnQgJk90aGVyKSBjb25zdCB7CisgICAgICAgIHJldHVybiBzdGFydCA9PSBPdGhlci5zdGFydCAmJiBlbmQgPT0gT3RoZXIuZW5kOworICAgICAgfQorCisgICAgICB2b2lkIGR1bXAoKSBjb25zdDsKKyAgICB9OworCisgICAgdXNpbmcgU2VnbWVudHMgPSBTbWFsbFZlY3RvcjxTZWdtZW50LCAyPjsKKyAgICB1c2luZyBWTkluZm9MaXN0ID0gU21hbGxWZWN0b3I8Vk5JbmZvICosIDI+OworCisgICAgU2VnbWVudHMgc2VnbWVudHM7ICAgLy8gdGhlIGxpdmVuZXNzIHNlZ21lbnRzCisgICAgVk5JbmZvTGlzdCB2YWxub3M7ICAgLy8gdmFsdWUjJ3MKKworICAgIC8vIFRoZSBzZWdtZW50IHNldCBpcyB1c2VkIHRlbXBvcmFyaWx5IHRvIGFjY2VsZXJhdGUgaW5pdGlhbCBjb21wdXRhdGlvbgorICAgIC8vIG9mIGxpdmUgcmFuZ2VzIG9mIHBoeXNpY2FsIHJlZ2lzdGVycyBpbiBjb21wdXRlUmVnVW5pdFJhbmdlLgorICAgIC8vIEFmdGVyIHRoYXQgdGhlIHNldCBpcyBmbHVzaGVkIHRvIHRoZSBzZWdtZW50IHZlY3RvciBhbmQgZGVsZXRlZC4KKyAgICB1c2luZyBTZWdtZW50U2V0ID0gc3RkOjpzZXQ8U2VnbWVudD47CisgICAgc3RkOjp1bmlxdWVfcHRyPFNlZ21lbnRTZXQ+IHNlZ21lbnRTZXQ7CisKKyAgICB1c2luZyBpdGVyYXRvciA9IFNlZ21lbnRzOjppdGVyYXRvcjsKKyAgICB1c2luZyBjb25zdF9pdGVyYXRvciA9IFNlZ21lbnRzOjpjb25zdF9pdGVyYXRvcjsKKworICAgIGl0ZXJhdG9yIGJlZ2luKCkgeyByZXR1cm4gc2VnbWVudHMuYmVnaW4oKTsgfQorICAgIGl0ZXJhdG9yIGVuZCgpICAgeyByZXR1cm4gc2VnbWVudHMuZW5kKCk7IH0KKworICAgIGNvbnN0X2l0ZXJhdG9yIGJlZ2luKCkgY29uc3QgeyByZXR1cm4gc2VnbWVudHMuYmVnaW4oKTsgfQorICAgIGNvbnN0X2l0ZXJhdG9yIGVuZCgpIGNvbnN0ICB7IHJldHVybiBzZWdtZW50cy5lbmQoKTsgfQorCisgICAgdXNpbmcgdm5pX2l0ZXJhdG9yID0gVk5JbmZvTGlzdDo6aXRlcmF0b3I7CisgICAgdXNpbmcgY29uc3Rfdm5pX2l0ZXJhdG9yID0gVk5JbmZvTGlzdDo6Y29uc3RfaXRlcmF0b3I7CisKKyAgICB2bmlfaXRlcmF0b3Igdm5pX2JlZ2luKCkgeyByZXR1cm4gdmFsbm9zLmJlZ2luKCk7IH0KKyAgICB2bmlfaXRlcmF0b3Igdm5pX2VuZCgpICAgeyByZXR1cm4gdmFsbm9zLmVuZCgpOyB9CisKKyAgICBjb25zdF92bmlfaXRlcmF0b3Igdm5pX2JlZ2luKCkgY29uc3QgeyByZXR1cm4gdmFsbm9zLmJlZ2luKCk7IH0KKyAgICBjb25zdF92bmlfaXRlcmF0b3Igdm5pX2VuZCgpIGNvbnN0ICAgeyByZXR1cm4gdmFsbm9zLmVuZCgpOyB9CisKKyAgICAvLy8gQ29uc3RydWN0cyBhIG5ldyBMaXZlUmFuZ2Ugb2JqZWN0LgorICAgIExpdmVSYW5nZShib29sIFVzZVNlZ21lbnRTZXQgPSBmYWxzZSkKKyAgICAgICAgOiBzZWdtZW50U2V0KFVzZVNlZ21lbnRTZXQgPyBsbHZtOjptYWtlX3VuaXF1ZTxTZWdtZW50U2V0PigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbHB0cikge30KKworICAgIC8vLyBDb25zdHJ1Y3RzIGEgbmV3IExpdmVSYW5nZSBvYmplY3QgYnkgY29weWluZyBzZWdtZW50cyBhbmQgdmFsbm9zIGZyb20KKyAgICAvLy8gYW5vdGhlciBMaXZlUmFuZ2UuCisgICAgTGl2ZVJhbmdlKGNvbnN0IExpdmVSYW5nZSAmT3RoZXIsIEJ1bXBQdHJBbGxvY2F0b3IgJkFsbG9jYXRvcikgeworICAgICAgYXNzZXJ0KE90aGVyLnNlZ21lbnRTZXQgPT0gbnVsbHB0ciAmJgorICAgICAgICAgICAgICJDb3B5aW5nIG9mIExpdmVSYW5nZXMgd2l0aCBhY3RpdmUgU2VnbWVudFNldHMgaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgYXNzaWduKE90aGVyLCBBbGxvY2F0b3IpOworICAgIH0KKworICAgIC8vLyBDb3BpZXMgdmFsdWVzIG51bWJlcnMgYW5kIGxpdmUgc2VnbWVudHMgZnJvbSBccCBPdGhlciBpbnRvIHRoaXMgcmFuZ2UuCisgICAgdm9pZCBhc3NpZ24oY29uc3QgTGl2ZVJhbmdlICZPdGhlciwgQnVtcFB0ckFsbG9jYXRvciAmQWxsb2NhdG9yKSB7CisgICAgICBpZiAodGhpcyA9PSAmT3RoZXIpCisgICAgICAgIHJldHVybjsKKworICAgICAgYXNzZXJ0KE90aGVyLnNlZ21lbnRTZXQgPT0gbnVsbHB0ciAmJgorICAgICAgICAgICAgICJDb3B5aW5nIG9mIExpdmVSYW5nZXMgd2l0aCBhY3RpdmUgU2VnbWVudFNldHMgaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgLy8gRHVwbGljYXRlIHZhbG5vcy4KKyAgICAgIGZvciAoY29uc3QgVk5JbmZvICpWTkkgOiBPdGhlci52YWxub3MpCisgICAgICAgIGNyZWF0ZVZhbHVlQ29weShWTkksIEFsbG9jYXRvcik7CisgICAgICAvLyBOb3cgd2UgY2FuIGNvcHkgc2VnbWVudHMgYW5kIHJlbWFwIHRoZWlyIHZhbG5vcy4KKyAgICAgIGZvciAoY29uc3QgU2VnbWVudCAmUyA6IE90aGVyLnNlZ21lbnRzKQorICAgICAgICBzZWdtZW50cy5wdXNoX2JhY2soU2VnbWVudChTLnN0YXJ0LCBTLmVuZCwgdmFsbm9zW1MudmFsbm8tPmlkXSkpOworICAgIH0KKworICAgIC8vLyBhZHZhbmNlVG8gLSBBZHZhbmNlIHRoZSBzcGVjaWZpZWQgaXRlcmF0b3IgdG8gcG9pbnQgdG8gdGhlIFNlZ21lbnQKKyAgICAvLy8gY29udGFpbmluZyB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLCBvciBlbmQoKSBpZiB0aGUgcG9zaXRpb24gaXMgcGFzdCB0aGUKKyAgICAvLy8gZW5kIG9mIHRoZSByYW5nZS4gIElmIG5vIFNlZ21lbnQgY29udGFpbnMgdGhpcyBwb3NpdGlvbiwgYnV0IHRoZQorICAgIC8vLyBwb3NpdGlvbiBpcyBpbiBhIGhvbGUsIHRoaXMgbWV0aG9kIHJldHVybnMgYW4gaXRlcmF0b3IgcG9pbnRpbmcgdG8gdGhlCisgICAgLy8vIFNlZ21lbnQgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIGhvbGUuCisgICAgaXRlcmF0b3IgYWR2YW5jZVRvKGl0ZXJhdG9yIEksIFNsb3RJbmRleCBQb3MpIHsKKyAgICAgIGFzc2VydChJICE9IGVuZCgpKTsKKyAgICAgIGlmIChQb3MgPj0gZW5kSW5kZXgoKSkKKyAgICAgICAgcmV0dXJuIGVuZCgpOworICAgICAgd2hpbGUgKEktPmVuZCA8PSBQb3MpICsrSTsKKyAgICAgIHJldHVybiBJOworICAgIH0KKworICAgIGNvbnN0X2l0ZXJhdG9yIGFkdmFuY2VUbyhjb25zdF9pdGVyYXRvciBJLCBTbG90SW5kZXggUG9zKSBjb25zdCB7CisgICAgICBhc3NlcnQoSSAhPSBlbmQoKSk7CisgICAgICBpZiAoUG9zID49IGVuZEluZGV4KCkpCisgICAgICAgIHJldHVybiBlbmQoKTsKKyAgICAgIHdoaWxlIChJLT5lbmQgPD0gUG9zKSArK0k7CisgICAgICByZXR1cm4gSTsKKyAgICB9CisKKyAgICAvLy8gZmluZCAtIFJldHVybiBhbiBpdGVyYXRvciBwb2ludGluZyB0byB0aGUgZmlyc3Qgc2VnbWVudCB0aGF0IGVuZHMgYWZ0ZXIKKyAgICAvLy8gUG9zLCBvciBlbmQoKS4gVGhpcyBpcyB0aGUgc2FtZSBhcyBhZHZhbmNlVG8oYmVnaW4oKSwgUG9zKSwgYnV0IGZhc3RlcgorICAgIC8vLyB3aGVuIHNlYXJjaGluZyBsYXJnZSByYW5nZXMuCisgICAgLy8vCisgICAgLy8vIElmIFBvcyBpcyBjb250YWluZWQgaW4gYSBTZWdtZW50LCB0aGF0IHNlZ21lbnQgaXMgcmV0dXJuZWQuCisgICAgLy8vIElmIFBvcyBpcyBpbiBhIGhvbGUsIHRoZSBmb2xsb3dpbmcgU2VnbWVudCBpcyByZXR1cm5lZC4KKyAgICAvLy8gSWYgUG9zIGlzIGJleW9uZCBlbmRJbmRleCwgZW5kKCkgaXMgcmV0dXJuZWQuCisgICAgaXRlcmF0b3IgZmluZChTbG90SW5kZXggUG9zKTsKKworICAgIGNvbnN0X2l0ZXJhdG9yIGZpbmQoU2xvdEluZGV4IFBvcykgY29uc3QgeworICAgICAgcmV0dXJuIGNvbnN0X2Nhc3Q8TGl2ZVJhbmdlKj4odGhpcyktPmZpbmQoUG9zKTsKKyAgICB9CisKKyAgICB2b2lkIGNsZWFyKCkgeworICAgICAgdmFsbm9zLmNsZWFyKCk7CisgICAgICBzZWdtZW50cy5jbGVhcigpOworICAgIH0KKworICAgIHNpemVfdCBzaXplKCkgY29uc3QgeworICAgICAgcmV0dXJuIHNlZ21lbnRzLnNpemUoKTsKKyAgICB9CisKKyAgICBib29sIGhhc0F0TGVhc3RPbmVWYWx1ZSgpIGNvbnN0IHsgcmV0dXJuICF2YWxub3MuZW1wdHkoKTsgfQorCisgICAgYm9vbCBjb250YWluc09uZVZhbHVlKCkgY29uc3QgeyByZXR1cm4gdmFsbm9zLnNpemUoKSA9PSAxOyB9CisKKyAgICB1bnNpZ25lZCBnZXROdW1WYWxOdW1zKCkgY29uc3QgeyByZXR1cm4gKHVuc2lnbmVkKXZhbG5vcy5zaXplKCk7IH0KKworICAgIC8vLyBnZXRWYWxOdW1JbmZvIC0gUmV0dXJucyBwb2ludGVyIHRvIHRoZSBzcGVjaWZpZWQgdmFsIy4KKyAgICAvLy8KKyAgICBpbmxpbmUgVk5JbmZvICpnZXRWYWxOdW1JbmZvKHVuc2lnbmVkIFZhbE5vKSB7CisgICAgICByZXR1cm4gdmFsbm9zW1ZhbE5vXTsKKyAgICB9CisgICAgaW5saW5lIGNvbnN0IFZOSW5mbyAqZ2V0VmFsTnVtSW5mbyh1bnNpZ25lZCBWYWxObykgY29uc3QgeworICAgICAgcmV0dXJuIHZhbG5vc1tWYWxOb107CisgICAgfQorCisgICAgLy8vIGNvbnRhaW5zVmFsdWUgLSBSZXR1cm5zIHRydWUgaWYgVk5JIGJlbG9uZ3MgdG8gdGhpcyByYW5nZS4KKyAgICBib29sIGNvbnRhaW5zVmFsdWUoY29uc3QgVk5JbmZvICpWTkkpIGNvbnN0IHsKKyAgICAgIHJldHVybiBWTkkgJiYgVk5JLT5pZCA8IGdldE51bVZhbE51bXMoKSAmJiBWTkkgPT0gZ2V0VmFsTnVtSW5mbyhWTkktPmlkKTsKKyAgICB9CisKKyAgICAvLy8gZ2V0TmV4dFZhbHVlIC0gQ3JlYXRlIGEgbmV3IHZhbHVlIG51bWJlciBhbmQgcmV0dXJuIGl0LiAgTUlJZHggc3BlY2lmaWVzCisgICAgLy8vIHRoZSBpbnN0cnVjdGlvbiB0aGF0IGRlZmluZXMgdGhlIHZhbHVlIG51bWJlci4KKyAgICBWTkluZm8gKmdldE5leHRWYWx1ZShTbG90SW5kZXggZGVmLCBWTkluZm86OkFsbG9jYXRvciAmVk5JbmZvQWxsb2NhdG9yKSB7CisgICAgICBWTkluZm8gKlZOSSA9CisgICAgICAgIG5ldyAoVk5JbmZvQWxsb2NhdG9yKSBWTkluZm8oKHVuc2lnbmVkKXZhbG5vcy5zaXplKCksIGRlZik7CisgICAgICB2YWxub3MucHVzaF9iYWNrKFZOSSk7CisgICAgICByZXR1cm4gVk5JOworICAgIH0KKworICAgIC8vLyBjcmVhdGVEZWFkRGVmIC0gTWFrZSBzdXJlIHRoZSByYW5nZSBoYXMgYSB2YWx1ZSBkZWZpbmVkIGF0IERlZi4KKyAgICAvLy8gSWYgb25lIGFscmVhZHkgZXhpc3RzLCByZXR1cm4gaXQuIE90aGVyd2lzZSBhbGxvY2F0ZSBhIG5ldyB2YWx1ZSBhbmQKKyAgICAvLy8gYWRkIGxpdmVuZXNzIGZvciBhIGRlYWQgZGVmLgorICAgIFZOSW5mbyAqY3JlYXRlRGVhZERlZihTbG90SW5kZXggRGVmLCBWTkluZm86OkFsbG9jYXRvciAmVk5JbmZvQWxsb2NhdG9yKTsKKworICAgIC8vLyBDcmVhdGUgYSBkZWYgb2YgdmFsdWUgQHAgVk5JLiBSZXR1cm4gQHAgVk5JLiBJZiB0aGVyZSBhbHJlYWR5IGV4aXN0cworICAgIC8vLyBhIGRlZmluaXRpb24gYXQgVk5JLT5kZWYsIHRoZSB2YWx1ZSBkZWZpbmVkIHRoZXJlIG11c3QgYmUgQHAgVk5JLgorICAgIFZOSW5mbyAqY3JlYXRlRGVhZERlZihWTkluZm8gKlZOSSk7CisKKyAgICAvLy8gQ3JlYXRlIGEgY29weSBvZiB0aGUgZ2l2ZW4gdmFsdWUuIFRoZSBuZXcgdmFsdWUgd2lsbCBiZSBpZGVudGljYWwgZXhjZXB0CisgICAgLy8vIGZvciB0aGUgVmFsdWUgbnVtYmVyLgorICAgIFZOSW5mbyAqY3JlYXRlVmFsdWVDb3B5KGNvbnN0IFZOSW5mbyAqb3JpZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBWTkluZm86OkFsbG9jYXRvciAmVk5JbmZvQWxsb2NhdG9yKSB7CisgICAgICBWTkluZm8gKlZOSSA9CisgICAgICAgIG5ldyAoVk5JbmZvQWxsb2NhdG9yKSBWTkluZm8oKHVuc2lnbmVkKXZhbG5vcy5zaXplKCksICpvcmlnKTsKKyAgICAgIHZhbG5vcy5wdXNoX2JhY2soVk5JKTsKKyAgICAgIHJldHVybiBWTkk7CisgICAgfQorCisgICAgLy8vIFJlbnVtYmVyVmFsdWVzIC0gUmVudW1iZXIgYWxsIHZhbHVlcyBpbiBvcmRlciBvZiBhcHBlYXJhbmNlIGFuZCByZW1vdmUKKyAgICAvLy8gdW51c2VkIHZhbHVlcy4KKyAgICB2b2lkIFJlbnVtYmVyVmFsdWVzKCk7CisKKyAgICAvLy8gTWVyZ2VWYWx1ZU51bWJlckludG8gLSBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiB0d28gdmFsdWUgbnVtYmVycworICAgIC8vLyBhcmUgZm91bmQgdG8gYmUgZXF1aXZhbGVudC4gIFRoaXMgZWxpbWluYXRlcyBWMSwgcmVwbGFjaW5nIGFsbAorICAgIC8vLyBzZWdtZW50cyB3aXRoIHRoZSBWMSB2YWx1ZSBudW1iZXIgd2l0aCB0aGUgVjIgdmFsdWUgbnVtYmVyLiAgVGhpcyBjYW4KKyAgICAvLy8gY2F1c2UgbWVyZ2luZyBvZiBWMS9WMiB2YWx1ZXMgbnVtYmVycyBhbmQgY29tcGFjdGlvbiBvZiB0aGUgdmFsdWUgc3BhY2UuCisgICAgVk5JbmZvKiBNZXJnZVZhbHVlTnVtYmVySW50byhWTkluZm8gKlYxLCBWTkluZm8gKlYyKTsKKworICAgIC8vLyBNZXJnZSBhbGwgb2YgdGhlIGxpdmUgc2VnbWVudHMgb2YgYSBzcGVjaWZpYyB2YWwjIGluIFJIUyBpbnRvIHRoaXMgbGl2ZQorICAgIC8vLyByYW5nZSBhcyB0aGUgc3BlY2lmaWVkIHZhbHVlIG51bWJlci4gVGhlIHNlZ21lbnRzIGluIFJIUyBhcmUgYWxsb3dlZAorICAgIC8vLyB0byBvdmVybGFwIHdpdGggc2VnbWVudHMgaW4gdGhlIGN1cnJlbnQgcmFuZ2UsIGl0IHdpbGwgcmVwbGFjZSB0aGUKKyAgICAvLy8gdmFsdWUgbnVtYmVycyBvZiB0aGUgb3ZlcmxhcGVkIGxpdmUgc2VnbWVudHMgd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlCisgICAgLy8vIG51bWJlci4KKyAgICB2b2lkIE1lcmdlU2VnbWVudHNJbkFzVmFsdWUoY29uc3QgTGl2ZVJhbmdlICZSSFMsIFZOSW5mbyAqTEhTVmFsTm8pOworCisgICAgLy8vIE1lcmdlVmFsdWVJbkFzVmFsdWUgLSBNZXJnZSBhbGwgb2YgdGhlIHNlZ21lbnRzIG9mIGEgc3BlY2lmaWMgdmFsIworICAgIC8vLyBpbiBSSFMgaW50byB0aGlzIGxpdmUgcmFuZ2UgYXMgdGhlIHNwZWNpZmllZCB2YWx1ZSBudW1iZXIuCisgICAgLy8vIFRoZSBzZWdtZW50cyBpbiBSSFMgYXJlIGFsbG93ZWQgdG8gb3ZlcmxhcCB3aXRoIHNlZ21lbnRzIGluIHRoZQorICAgIC8vLyBjdXJyZW50IHJhbmdlLCBidXQgb25seSBpZiB0aGUgb3ZlcmxhcHBpbmcgc2VnbWVudHMgaGF2ZSB0aGUKKyAgICAvLy8gc3BlY2lmaWVkIHZhbHVlIG51bWJlci4KKyAgICB2b2lkIE1lcmdlVmFsdWVJbkFzVmFsdWUoY29uc3QgTGl2ZVJhbmdlICZSSFMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFZOSW5mbyAqUkhTVmFsTm8sIFZOSW5mbyAqTEhTVmFsTm8pOworCisgICAgYm9vbCBlbXB0eSgpIGNvbnN0IHsgcmV0dXJuIHNlZ21lbnRzLmVtcHR5KCk7IH0KKworICAgIC8vLyBiZWdpbkluZGV4IC0gUmV0dXJuIHRoZSBsb3dlc3QgbnVtYmVyZWQgc2xvdCBjb3ZlcmVkLgorICAgIFNsb3RJbmRleCBiZWdpbkluZGV4KCkgY29uc3QgeworICAgICAgYXNzZXJ0KCFlbXB0eSgpICYmICJDYWxsIHRvIGJlZ2luSW5kZXgoKSBvbiBlbXB0eSByYW5nZS4iKTsKKyAgICAgIHJldHVybiBzZWdtZW50cy5mcm9udCgpLnN0YXJ0OworICAgIH0KKworICAgIC8vLyBlbmROdW1iZXIgLSByZXR1cm4gdGhlIG1heGltdW0gcG9pbnQgb2YgdGhlIHJhbmdlIG9mIHRoZSB3aG9sZSwKKyAgICAvLy8gZXhjbHVzaXZlLgorICAgIFNsb3RJbmRleCBlbmRJbmRleCgpIGNvbnN0IHsKKyAgICAgIGFzc2VydCghZW1wdHkoKSAmJiAiQ2FsbCB0byBlbmRJbmRleCgpIG9uIGVtcHR5IHJhbmdlLiIpOworICAgICAgcmV0dXJuIHNlZ21lbnRzLmJhY2soKS5lbmQ7CisgICAgfQorCisgICAgYm9vbCBleHBpcmVkQXQoU2xvdEluZGV4IGluZGV4KSBjb25zdCB7CisgICAgICByZXR1cm4gaW5kZXggPj0gZW5kSW5kZXgoKTsKKyAgICB9CisKKyAgICBib29sIGxpdmVBdChTbG90SW5kZXggaW5kZXgpIGNvbnN0IHsKKyAgICAgIGNvbnN0X2l0ZXJhdG9yIHIgPSBmaW5kKGluZGV4KTsKKyAgICAgIHJldHVybiByICE9IGVuZCgpICYmIHItPnN0YXJ0IDw9IGluZGV4OworICAgIH0KKworICAgIC8vLyBSZXR1cm4gdGhlIHNlZ21lbnQgdGhhdCBjb250YWlucyB0aGUgc3BlY2lmaWVkIGluZGV4LCBvciBudWxsIGlmIHRoZXJlCisgICAgLy8vIGlzIG5vbmUuCisgICAgY29uc3QgU2VnbWVudCAqZ2V0U2VnbWVudENvbnRhaW5pbmcoU2xvdEluZGV4IElkeCkgY29uc3QgeworICAgICAgY29uc3RfaXRlcmF0b3IgSSA9IEZpbmRTZWdtZW50Q29udGFpbmluZyhJZHgpOworICAgICAgcmV0dXJuIEkgPT0gZW5kKCkgPyBudWxscHRyIDogJipJOworICAgIH0KKworICAgIC8vLyBSZXR1cm4gdGhlIGxpdmUgc2VnbWVudCB0aGF0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgaW5kZXgsIG9yIG51bGwgaWYKKyAgICAvLy8gdGhlcmUgaXMgbm9uZS4KKyAgICBTZWdtZW50ICpnZXRTZWdtZW50Q29udGFpbmluZyhTbG90SW5kZXggSWR4KSB7CisgICAgICBpdGVyYXRvciBJID0gRmluZFNlZ21lbnRDb250YWluaW5nKElkeCk7CisgICAgICByZXR1cm4gSSA9PSBlbmQoKSA/IG51bGxwdHIgOiAmKkk7CisgICAgfQorCisgICAgLy8vIGdldFZOSW5mb0F0IC0gUmV0dXJuIHRoZSBWTkluZm8gdGhhdCBpcyBsaXZlIGF0IElkeCwgb3IgTlVMTC4KKyAgICBWTkluZm8gKmdldFZOSW5mb0F0KFNsb3RJbmRleCBJZHgpIGNvbnN0IHsKKyAgICAgIGNvbnN0X2l0ZXJhdG9yIEkgPSBGaW5kU2VnbWVudENvbnRhaW5pbmcoSWR4KTsKKyAgICAgIHJldHVybiBJID09IGVuZCgpID8gbnVsbHB0ciA6IEktPnZhbG5vOworICAgIH0KKworICAgIC8vLyBnZXRWTkluZm9CZWZvcmUgLSBSZXR1cm4gdGhlIFZOSW5mbyB0aGF0IGlzIGxpdmUgdXAgdG8gYnV0IG5vdAorICAgIC8vLyBuZWNlc3NhcmlsbHkgaW5jbHVkaW5nIElkeCwgb3IgTlVMTC4gVXNlIHRoaXMgdG8gZmluZCB0aGUgcmVhY2hpbmcgZGVmCisgICAgLy8vIHVzZWQgYnkgYW4gaW5zdHJ1Y3Rpb24gYXQgdGhpcyBTbG90SW5kZXggcG9zaXRpb24uCisgICAgVk5JbmZvICpnZXRWTkluZm9CZWZvcmUoU2xvdEluZGV4IElkeCkgY29uc3QgeworICAgICAgY29uc3RfaXRlcmF0b3IgSSA9IEZpbmRTZWdtZW50Q29udGFpbmluZyhJZHguZ2V0UHJldlNsb3QoKSk7CisgICAgICByZXR1cm4gSSA9PSBlbmQoKSA/IG51bGxwdHIgOiBJLT52YWxubzsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIGFuIGl0ZXJhdG9yIHRvIHRoZSBzZWdtZW50IHRoYXQgY29udGFpbnMgdGhlIHNwZWNpZmllZCBpbmRleCwgb3IKKyAgICAvLy8gZW5kKCkgaWYgdGhlcmUgaXMgbm9uZS4KKyAgICBpdGVyYXRvciBGaW5kU2VnbWVudENvbnRhaW5pbmcoU2xvdEluZGV4IElkeCkgeworICAgICAgaXRlcmF0b3IgSSA9IGZpbmQoSWR4KTsKKyAgICAgIHJldHVybiBJICE9IGVuZCgpICYmIEktPnN0YXJ0IDw9IElkeCA/IEkgOiBlbmQoKTsKKyAgICB9CisKKyAgICBjb25zdF9pdGVyYXRvciBGaW5kU2VnbWVudENvbnRhaW5pbmcoU2xvdEluZGV4IElkeCkgY29uc3QgeworICAgICAgY29uc3RfaXRlcmF0b3IgSSA9IGZpbmQoSWR4KTsKKyAgICAgIHJldHVybiBJICE9IGVuZCgpICYmIEktPnN0YXJ0IDw9IElkeCA/IEkgOiBlbmQoKTsKKyAgICB9CisKKyAgICAvLy8gb3ZlcmxhcHMgLSBSZXR1cm4gdHJ1ZSBpZiB0aGUgaW50ZXJzZWN0aW9uIG9mIHRoZSB0d28gbGl2ZSByYW5nZXMgaXMKKyAgICAvLy8gbm90IGVtcHR5LgorICAgIGJvb2wgb3ZlcmxhcHMoY29uc3QgTGl2ZVJhbmdlICZvdGhlcikgY29uc3QgeworICAgICAgaWYgKG90aGVyLmVtcHR5KCkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIHJldHVybiBvdmVybGFwc0Zyb20ob3RoZXIsIG90aGVyLmJlZ2luKCkpOworICAgIH0KKworICAgIC8vLyBvdmVybGFwcyAtIFJldHVybiB0cnVlIGlmIHRoZSB0d28gcmFuZ2VzIGhhdmUgb3ZlcmxhcHBpbmcgc2VnbWVudHMKKyAgICAvLy8gdGhhdCBhcmUgbm90IGNvYWxlc2NhYmxlIGFjY29yZGluZyB0byBDUC4KKyAgICAvLy8KKyAgICAvLy8gT3ZlcmxhcHBpbmcgc2VnbWVudHMgd2hlcmUgb25lIHJhbmdlIGlzIGRlZmluZWQgYnkgYSBjb2FsZXNjYWJsZQorICAgIC8vLyBjb3B5IGFyZSBhbGxvd2VkLgorICAgIGJvb2wgb3ZlcmxhcHMoY29uc3QgTGl2ZVJhbmdlICZPdGhlciwgY29uc3QgQ29hbGVzY2VyUGFpciAmQ1AsCisgICAgICAgICAgICAgICAgICBjb25zdCBTbG90SW5kZXhlcyYpIGNvbnN0OworCisgICAgLy8vIG92ZXJsYXBzIC0gUmV0dXJuIHRydWUgaWYgdGhlIGxpdmUgcmFuZ2Ugb3ZlcmxhcHMgYW4gaW50ZXJ2YWwgc3BlY2lmaWVkCisgICAgLy8vIGJ5IFtTdGFydCwgRW5kKS4KKyAgICBib29sIG92ZXJsYXBzKFNsb3RJbmRleCBTdGFydCwgU2xvdEluZGV4IEVuZCkgY29uc3Q7CisKKyAgICAvLy8gb3ZlcmxhcHNGcm9tIC0gUmV0dXJuIHRydWUgaWYgdGhlIGludGVyc2VjdGlvbiBvZiB0aGUgdHdvIGxpdmUgcmFuZ2VzCisgICAgLy8vIGlzIG5vdCBlbXB0eS4gIFRoZSBzcGVjaWZpZWQgaXRlcmF0b3IgaXMgYSBoaW50IHRoYXQgd2UgY2FuIGJlZ2luCisgICAgLy8vIHNjYW5uaW5nIHRoZSBPdGhlciByYW5nZSBzdGFydGluZyBhdCBJLgorICAgIGJvb2wgb3ZlcmxhcHNGcm9tKGNvbnN0IExpdmVSYW5nZSAmT3RoZXIsIGNvbnN0X2l0ZXJhdG9yIEkpIGNvbnN0OworCisgICAgLy8vIFJldHVybnMgdHJ1ZSBpZiBhbGwgc2VnbWVudHMgb2YgdGhlIEBwIE90aGVyIGxpdmUgcmFuZ2UgYXJlIGNvbXBsZXRlbHkKKyAgICAvLy8gY292ZXJlZCBieSB0aGlzIGxpdmUgcmFuZ2UuCisgICAgLy8vIEFkamFjZW50IGxpdmUgcmFuZ2VzIGRvIG5vdCBhZmZlY3QgdGhlIGNvdmVyaW5nOnRoZSBsaXZlcmFuZ2UKKyAgICAvLy8gWzEsNV0oNSwxMF0gY292ZXJzICgzLDddLgorICAgIGJvb2wgY292ZXJzKGNvbnN0IExpdmVSYW5nZSAmT3RoZXIpIGNvbnN0OworCisgICAgLy8vIEFkZCB0aGUgc3BlY2lmaWVkIFNlZ21lbnQgdG8gdGhpcyByYW5nZSwgbWVyZ2luZyBzZWdtZW50cyBhcworICAgIC8vLyBhcHByb3ByaWF0ZS4gIFRoaXMgcmV0dXJucyBhbiBpdGVyYXRvciB0byB0aGUgaW5zZXJ0ZWQgc2VnbWVudCAod2hpY2gKKyAgICAvLy8gbWF5IGhhdmUgZ3Jvd24gc2luY2UgaXQgd2FzIGluc2VydGVkKS4KKyAgICBpdGVyYXRvciBhZGRTZWdtZW50KFNlZ21lbnQgUyk7CisKKyAgICAvLy8gQXR0ZW1wdCB0byBleHRlbmQgYSB2YWx1ZSBkZWZpbmVkIGFmdGVyIEBwIFN0YXJ0SWR4IHRvIGluY2x1ZGUgQHAgVXNlLgorICAgIC8vLyBCb3RoIEBwIFN0YXJ0SWR4IGFuZCBAcCBVc2Ugc2hvdWxkIGJlIGluIHRoZSBzYW1lIGJhc2ljIGJsb2NrLiBJbiBjYXNlCisgICAgLy8vIG9mIHN1YnJhbmdlcywgYW4gZXh0ZW5zaW9uIGNvdWxkIGJlIHByZXZlbnRlZCBieSBhbiBleHBsaWNpdCAidW5kZWYiCisgICAgLy8vIGNhdXNlZCBieSBhIDxkZWYscmVhZC11bmRlZj4gb24gYSBub24tb3ZlcmxhcHBpbmcgbGFuZS4gVGhlIGxpc3Qgb2YKKyAgICAvLy8gbG9jYXRpb24gb2Ygc3VjaCAidW5kZWZzIiBzaG91bGQgYmUgcHJvdmlkZWQgaW4gQHAgVW5kZWZzLgorICAgIC8vLyBUaGUgcmV0dXJuIHZhbHVlIGlzIGEgcGFpcjogdGhlIGZpcnN0IGVsZW1lbnQgaXMgVk5JbmZvIG9mIHRoZSB2YWx1ZQorICAgIC8vLyB0aGF0IHdhcyBleHRlbmRlZCAocG9zc2libHkgbnVsbHB0ciksIHRoZSBzZWNvbmQgaXMgYSBib29sZWFuIHZhbHVlCisgICAgLy8vIGluZGljYXRpbmcgd2hldGhlciBhbiAidW5kZWYiIHdhcyBlbmNvdW50ZXJlZC4KKyAgICAvLy8gSWYgdGhpcyByYW5nZSBpcyBsaXZlIGJlZm9yZSBAcCBVc2UgaW4gdGhlIGJhc2ljIGJsb2NrIHRoYXQgc3RhcnRzIGF0CisgICAgLy8vIEBwIFN0YXJ0SWR4LCBhbmQgdGhlcmUgaXMgbm8gaW50ZXJ2ZW5pbmcgInVuZGVmIiwgZXh0ZW5kIGl0IHRvIGJlIGxpdmUKKyAgICAvLy8gdXAgdG8gQHAgVXNlLCBhbmQgcmV0dXJuIHRoZSBwYWlyIHt2YWx1ZSwgZmFsc2V9LiBJZiB0aGVyZSBpcyBubworICAgIC8vLyBzZWdtZW50IGJlZm9yZSBAcCBVc2UgYW5kIHRoZXJlIGlzIG5vICJ1bmRlZiIgYmV0d2VlbiBAcCBTdGFydElkeCBhbmQKKyAgICAvLy8gQHAgVXNlLCByZXR1cm4ge251bGxwdHIsIGZhbHNlfS4gSWYgdGhlcmUgaXMgYW4gInVuZGVmIiBiZWZvcmUgQHAgVXNlLAorICAgIC8vLyByZXR1cm4ge251bGxwdHIsIHRydWV9LgorICAgIHN0ZDo6cGFpcjxWTkluZm8qLGJvb2w+IGV4dGVuZEluQmxvY2soQXJyYXlSZWY8U2xvdEluZGV4PiBVbmRlZnMsCisgICAgICAgIFNsb3RJbmRleCBTdGFydElkeCwgU2xvdEluZGV4IFVzZSk7CisKKyAgICAvLy8gU2ltcGxpZmllZCB2ZXJzaW9uIG9mIHRoZSBhYm92ZSAiZXh0ZW5kSW5CbG9jayIsIHdoaWNoIGFzc3VtZXMgdGhhdAorICAgIC8vLyBubyByZWdpc3RlciBsYW5lcyBhcmUgdW5kZWZpbmVkIGJ5IDxkZWYscmVhZC11bmRlZj4gb3BlcmFuZHMuCisgICAgLy8vIElmIHRoaXMgcmFuZ2UgaXMgbGl2ZSBiZWZvcmUgQHAgVXNlIGluIHRoZSBiYXNpYyBibG9jayB0aGF0IHN0YXJ0cworICAgIC8vLyBhdCBAcCBTdGFydElkeCwgZXh0ZW5kIGl0IHRvIGJlIGxpdmUgdXAgdG8gQHAgVXNlLCBhbmQgcmV0dXJuIHRoZQorICAgIC8vLyB2YWx1ZS4gSWYgdGhlcmUgaXMgbm8gc2VnbWVudCBiZWZvcmUgQHAgVXNlLCByZXR1cm4gbnVsbHB0ci4KKyAgICBWTkluZm8gKmV4dGVuZEluQmxvY2soU2xvdEluZGV4IFN0YXJ0SWR4LCBTbG90SW5kZXggS2lsbCk7CisKKyAgICAvLy8gam9pbiAtIEpvaW4gdHdvIGxpdmUgcmFuZ2VzICh0aGlzLCBhbmQgb3RoZXIpIHRvZ2V0aGVyLiAgVGhpcyBhcHBsaWVzCisgICAgLy8vIG1hcHBpbmdzIHRvIHRoZSB2YWx1ZSBudW1iZXJzIGluIHRoZSBMSFMvUkhTIHJhbmdlcyBhcyBzcGVjaWZpZWQuICBJZgorICAgIC8vLyB0aGUgcmFuZ2VzIGFyZSBub3Qgam9pbmFibGUsIHRoaXMgYWJvcnRzLgorICAgIHZvaWQgam9pbihMaXZlUmFuZ2UgJk90aGVyLAorICAgICAgICAgICAgICBjb25zdCBpbnQgKlZhbE5vQXNzaWdubWVudHMsCisgICAgICAgICAgICAgIGNvbnN0IGludCAqUkhTVmFsTm9Bc3NpZ25tZW50cywKKyAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPFZOSW5mbyAqPiAmTmV3Vk5JbmZvKTsKKworICAgIC8vLyBUcnVlIGlmZiB0aGlzIHNlZ21lbnQgaXMgYSBzaW5nbGUgc2VnbWVudCB0aGF0IGxpZXMgYmV0d2VlbiB0aGUKKyAgICAvLy8gc3BlY2lmaWVkIGJvdW5kYXJpZXMsIGV4Y2x1c2l2ZWx5LiBWcmVncyBsaXZlIGFjcm9zcyBhIGJhY2tlZGdlIGFyZSBub3QKKyAgICAvLy8gY29uc2lkZXJlZCBsb2NhbC4gVGhlIGJvdW5kYXJpZXMgYXJlIGV4cGVjdGVkIHRvIGxpZSB3aXRoaW4gYW4gZXh0ZW5kZWQKKyAgICAvLy8gYmFzaWMgYmxvY2ssIHNvIHZyZWdzIHRoYXQgYXJlIG5vdCBsaXZlIG91dCBzaG91bGQgY29udGFpbiBubyBob2xlcy4KKyAgICBib29sIGlzTG9jYWwoU2xvdEluZGV4IFN0YXJ0LCBTbG90SW5kZXggRW5kKSBjb25zdCB7CisgICAgICByZXR1cm4gYmVnaW5JbmRleCgpID4gU3RhcnQuZ2V0QmFzZUluZGV4KCkgJiYKKyAgICAgICAgZW5kSW5kZXgoKSA8IEVuZC5nZXRCb3VuZGFyeUluZGV4KCk7CisgICAgfQorCisgICAgLy8vIFJlbW92ZSB0aGUgc3BlY2lmaWVkIHNlZ21lbnQgZnJvbSB0aGlzIHJhbmdlLiAgTm90ZSB0aGF0IHRoZSBzZWdtZW50CisgICAgLy8vIG11c3QgYmUgYSBzaW5nbGUgU2VnbWVudCBpbiBpdHMgZW50aXJldHkuCisgICAgdm9pZCByZW1vdmVTZWdtZW50KFNsb3RJbmRleCBTdGFydCwgU2xvdEluZGV4IEVuZCwKKyAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBSZW1vdmVEZWFkVmFsTm8gPSBmYWxzZSk7CisKKyAgICB2b2lkIHJlbW92ZVNlZ21lbnQoU2VnbWVudCBTLCBib29sIFJlbW92ZURlYWRWYWxObyA9IGZhbHNlKSB7CisgICAgICByZW1vdmVTZWdtZW50KFMuc3RhcnQsIFMuZW5kLCBSZW1vdmVEZWFkVmFsTm8pOworICAgIH0KKworICAgIC8vLyBSZW1vdmUgc2VnbWVudCBwb2ludGVkIHRvIGJ5IGl0ZXJhdG9yIEBwIEkgZnJvbSB0aGlzIHJhbmdlLiAgVGhpcyBkb2VzCisgICAgLy8vIG5vdCByZW1vdmUgZGVhZCB2YWx1ZSBudW1iZXJzLgorICAgIGl0ZXJhdG9yIHJlbW92ZVNlZ21lbnQoaXRlcmF0b3IgSSkgeworICAgICAgcmV0dXJuIHNlZ21lbnRzLmVyYXNlKEkpOworICAgIH0KKworICAgIC8vLyBRdWVyeSBMaXZlbmVzcyBhdCBJZHguCisgICAgLy8vIFRoZSBzdWItaW5zdHJ1Y3Rpb24gc2xvdCBvZiBJZHggZG9lc24ndCBtYXR0ZXIsIG9ubHkgdGhlIGluc3RydWN0aW9uCisgICAgLy8vIGl0IHJlZmVycyB0byBpcyBjb25zaWRlcmVkLgorICAgIExpdmVRdWVyeVJlc3VsdCBRdWVyeShTbG90SW5kZXggSWR4KSBjb25zdCB7CisgICAgICAvLyBGaW5kIHRoZSBzZWdtZW50IHRoYXQgZW50ZXJzIHRoZSBpbnN0cnVjdGlvbi4KKyAgICAgIGNvbnN0X2l0ZXJhdG9yIEkgPSBmaW5kKElkeC5nZXRCYXNlSW5kZXgoKSk7CisgICAgICBjb25zdF9pdGVyYXRvciBFID0gZW5kKCk7CisgICAgICBpZiAoSSA9PSBFKQorICAgICAgICByZXR1cm4gTGl2ZVF1ZXJ5UmVzdWx0KG51bGxwdHIsIG51bGxwdHIsIFNsb3RJbmRleCgpLCBmYWxzZSk7CisKKyAgICAgIC8vIElzIHRoaXMgYW4gaW5zdHJ1Y3Rpb24gbGl2ZS1pbiBzZWdtZW50PworICAgICAgLy8gSWYgSWR4IGlzIHRoZSBzdGFydCBpbmRleCBvZiBhIGJhc2ljIGJsb2NrLCBpbmNsdWRlIGxpdmUtaW4gc2VnbWVudHMKKyAgICAgIC8vIHRoYXQgc3RhcnQgYXQgSWR4LmdldEJhc2VJbmRleCgpLgorICAgICAgVk5JbmZvICpFYXJseVZhbCA9IG51bGxwdHI7CisgICAgICBWTkluZm8gKkxhdGVWYWwgID0gbnVsbHB0cjsKKyAgICAgIFNsb3RJbmRleCBFbmRQb2ludDsKKyAgICAgIGJvb2wgS2lsbCA9IGZhbHNlOworICAgICAgaWYgKEktPnN0YXJ0IDw9IElkeC5nZXRCYXNlSW5kZXgoKSkgeworICAgICAgICBFYXJseVZhbCA9IEktPnZhbG5vOworICAgICAgICBFbmRQb2ludCA9IEktPmVuZDsKKyAgICAgICAgLy8gTW92ZSB0byB0aGUgcG90ZW50aWFsbHkgbGl2ZS1vdXQgc2VnbWVudC4KKyAgICAgICAgaWYgKFNsb3RJbmRleDo6aXNTYW1lSW5zdHIoSWR4LCBJLT5lbmQpKSB7CisgICAgICAgICAgS2lsbCA9IHRydWU7CisgICAgICAgICAgaWYgKCsrSSA9PSBFKQorICAgICAgICAgICAgcmV0dXJuIExpdmVRdWVyeVJlc3VsdChFYXJseVZhbCwgTGF0ZVZhbCwgRW5kUG9pbnQsIEtpbGwpOworICAgICAgICB9CisgICAgICAgIC8vIFNwZWNpYWwgY2FzZTogQSBQSElEZWYgdmFsdWUgY2FuIGhhdmUgaXRzIGRlZiBpbiB0aGUgbWlkZGxlIG9mIGEKKyAgICAgICAgLy8gc2VnbWVudCBpZiB0aGUgdmFsdWUgaGFwcGVucyB0byBiZSBsaXZlIG91dCBvZiB0aGUgbGF5b3V0CisgICAgICAgIC8vIHByZWRlY2Vzc29yLgorICAgICAgICAvLyBTdWNoIGEgdmFsdWUgaXMgbm90IGxpdmUtaW4uCisgICAgICAgIGlmIChFYXJseVZhbC0+ZGVmID09IElkeC5nZXRCYXNlSW5kZXgoKSkKKyAgICAgICAgICBFYXJseVZhbCA9IG51bGxwdHI7CisgICAgICB9CisgICAgICAvLyBJIG5vdyBwb2ludHMgdG8gdGhlIHNlZ21lbnQgdGhhdCBtYXkgYmUgbGl2ZS10aHJvdWdoLCBvciBkZWZpbmVkIGJ5CisgICAgICAvLyB0aGlzIGluc3RyLiBJZ25vcmUgc2VnbWVudHMgc3RhcnRpbmcgYWZ0ZXIgdGhlIGN1cnJlbnQgaW5zdHIuCisgICAgICBpZiAoIVNsb3RJbmRleDo6aXNFYXJsaWVySW5zdHIoSWR4LCBJLT5zdGFydCkpIHsKKyAgICAgICAgTGF0ZVZhbCA9IEktPnZhbG5vOworICAgICAgICBFbmRQb2ludCA9IEktPmVuZDsKKyAgICAgIH0KKyAgICAgIHJldHVybiBMaXZlUXVlcnlSZXN1bHQoRWFybHlWYWwsIExhdGVWYWwsIEVuZFBvaW50LCBLaWxsKTsKKyAgICB9CisKKyAgICAvLy8gcmVtb3ZlVmFsTm8gLSBSZW1vdmUgYWxsIHRoZSBzZWdtZW50cyBkZWZpbmVkIGJ5IHRoZSBzcGVjaWZpZWQgdmFsdWUjLgorICAgIC8vLyBBbHNvIHJlbW92ZSB0aGUgdmFsdWUjIGZyb20gdmFsdWUjIGxpc3QuCisgICAgdm9pZCByZW1vdmVWYWxObyhWTkluZm8gKlZhbE5vKTsKKworICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIGxpdmUgcmFuZ2UgaXMgemVybyBsZW5ndGgsIGkuZS4gbm8gbGl2ZSBzZWdtZW50cworICAgIC8vLyBzcGFuIGluc3RydWN0aW9ucy4gSXQgZG9lc24ndCBwYXkgdG8gc3BpbGwgc3VjaCBhIHJhbmdlLgorICAgIGJvb2wgaXNaZXJvTGVuZ3RoKFNsb3RJbmRleGVzICpJbmRleGVzKSBjb25zdCB7CisgICAgICBmb3IgKGNvbnN0IFNlZ21lbnQgJlMgOiBzZWdtZW50cykKKyAgICAgICAgaWYgKEluZGV4ZXMtPmdldE5leHROb25OdWxsSW5kZXgoUy5zdGFydCkuZ2V0QmFzZUluZGV4KCkgPAorICAgICAgICAgICAgUy5lbmQuZ2V0QmFzZUluZGV4KCkpCisgICAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLy8gUmV0dXJucyB0cnVlIGlmIGFueSBzZWdtZW50IGluIHRoZSBsaXZlIHJhbmdlIGNvbnRhaW5zIGFueSBvZiB0aGUKKyAgICAvLyBwcm92aWRlZCBzbG90IGluZGV4ZXMuICBTbG90cyB3aGljaCBvY2N1ciBpbiBob2xlcyBiZXR3ZWVuCisgICAgLy8gc2VnbWVudHMgd2lsbCBub3QgY2F1c2UgdGhlIGZ1bmN0aW9uIHRvIHJldHVybiB0cnVlLgorICAgIGJvb2wgaXNMaXZlQXRJbmRleGVzKEFycmF5UmVmPFNsb3RJbmRleD4gU2xvdHMpIGNvbnN0OworCisgICAgYm9vbCBvcGVyYXRvcjwoY29uc3QgTGl2ZVJhbmdlJiBvdGhlcikgY29uc3QgeworICAgICAgY29uc3QgU2xvdEluZGV4ICZ0aGlzSW5kZXggPSBiZWdpbkluZGV4KCk7CisgICAgICBjb25zdCBTbG90SW5kZXggJm90aGVySW5kZXggPSBvdGhlci5iZWdpbkluZGV4KCk7CisgICAgICByZXR1cm4gdGhpc0luZGV4IDwgb3RoZXJJbmRleDsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZXJlIGlzIGFuIGV4cGxpY2l0ICJ1bmRlZiIgYmV0d2VlbiBAcCBCZWdpbgorICAgIC8vLyBAcCBFbmQuCisgICAgYm9vbCBpc1VuZGVmSW4oQXJyYXlSZWY8U2xvdEluZGV4PiBVbmRlZnMsIFNsb3RJbmRleCBCZWdpbiwKKyAgICAgICAgICAgICAgICAgICBTbG90SW5kZXggRW5kKSBjb25zdCB7CisgICAgICByZXR1cm4gc3RkOjphbnlfb2YoVW5kZWZzLmJlZ2luKCksIFVuZGVmcy5lbmQoKSwKKyAgICAgICAgICAgICAgICBbQmVnaW4sRW5kXSAoU2xvdEluZGV4IElkeCkgLT4gYm9vbCB7CisgICAgICAgICAgICAgICAgICByZXR1cm4gQmVnaW4gPD0gSWR4ICYmIElkeCA8IEVuZDsKKyAgICAgICAgICAgICAgICB9KTsKKyAgICB9CisKKyAgICAvLy8gRmx1c2ggc2VnbWVudCBzZXQgaW50byB0aGUgcmVndWxhciBzZWdtZW50IHZlY3Rvci4KKyAgICAvLy8gVGhlIG1ldGhvZCBpcyB0byBiZSBjYWxsZWQgYWZ0ZXIgdGhlIGxpdmUgcmFuZ2UKKyAgICAvLy8gaGFzIGJlZW4gY3JlYXRlZCwgaWYgdXNlIG9mIHRoZSBzZWdtZW50IHNldCB3YXMKKyAgICAvLy8gYWN0aXZhdGVkIGluIHRoZSBjb25zdHJ1Y3RvciBvZiB0aGUgbGl2ZSByYW5nZS4KKyAgICB2b2lkIGZsdXNoU2VnbWVudFNldCgpOworCisgICAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MpIGNvbnN0OworICAgIHZvaWQgZHVtcCgpIGNvbnN0OworCisgICAgLy8vIFxicmllZiBXYWxrIHRoZSByYW5nZSBhbmQgYXNzZXJ0IGlmIGFueSBpbnZhcmlhbnRzIGZhaWwgdG8gaG9sZC4KKyAgICAvLy8KKyAgICAvLy8gTm90ZSB0aGF0IHRoaXMgaXMgYSBuby1vcCB3aGVuIGFzc2VydHMgYXJlIGRpc2FibGVkLgorI2lmZGVmIE5ERUJVRworICAgIHZvaWQgdmVyaWZ5KCkgY29uc3Qge30KKyNlbHNlCisgICAgdm9pZCB2ZXJpZnkoKSBjb25zdDsKKyNlbmRpZgorCisgIHByb3RlY3RlZDoKKyAgICAvLy8gQXBwZW5kIGEgc2VnbWVudCB0byB0aGUgbGlzdCBvZiBzZWdtZW50cy4KKyAgICB2b2lkIGFwcGVuZChjb25zdCBMaXZlUmFuZ2U6OlNlZ21lbnQgUyk7CisKKyAgcHJpdmF0ZToKKyAgICBmcmllbmQgY2xhc3MgTGl2ZVJhbmdlVXBkYXRlcjsKKyAgICB2b2lkIGFkZFNlZ21lbnRUb1NldChTZWdtZW50IFMpOworICAgIHZvaWQgbWFya1ZhbE5vRm9yRGVsZXRpb24oVk5JbmZvICpWKTsKKyAgfTsKKworICBpbmxpbmUgcmF3X29zdHJlYW0gJm9wZXJhdG9yPDwocmF3X29zdHJlYW0gJk9TLCBjb25zdCBMaXZlUmFuZ2UgJkxSKSB7CisgICAgTFIucHJpbnQoT1MpOworICAgIHJldHVybiBPUzsKKyAgfQorCisgIC8vLyBMaXZlSW50ZXJ2YWwgLSBUaGlzIGNsYXNzIHJlcHJlc2VudHMgdGhlIGxpdmVuZXNzIG9mIGEgcmVnaXN0ZXIsCisgIC8vLyBvciBzdGFjayBzbG90LgorICBjbGFzcyBMaXZlSW50ZXJ2YWwgOiBwdWJsaWMgTGl2ZVJhbmdlIHsKKyAgcHVibGljOgorICAgIHVzaW5nIHN1cGVyID0gTGl2ZVJhbmdlOworCisgICAgLy8vIEEgbGl2ZSByYW5nZSBmb3Igc3VicmVnaXN0ZXJzLiBUaGUgTGFuZU1hc2sgc3BlY2lmaWVzIHdoaWNoIHBhcnRzIG9mIHRoZQorICAgIC8vLyBzdXBlciByZWdpc3RlciBhcmUgY292ZXJlZCBieSB0aGUgaW50ZXJ2YWwuCisgICAgLy8vIChAc2EgVGFyZ2V0UmVnaXN0ZXJJbmZvOjpnZXRTdWJSZWdJbmRleExhbmVNYXNrKCkpLgorICAgIGNsYXNzIFN1YlJhbmdlIDogcHVibGljIExpdmVSYW5nZSB7CisgICAgcHVibGljOgorICAgICAgU3ViUmFuZ2UgKk5leHQgPSBudWxscHRyOworICAgICAgTGFuZUJpdG1hc2sgTGFuZU1hc2s7CisKKyAgICAgIC8vLyBDb25zdHJ1Y3RzIGEgbmV3IFN1YlJhbmdlIG9iamVjdC4KKyAgICAgIFN1YlJhbmdlKExhbmVCaXRtYXNrIExhbmVNYXNrKSA6IExhbmVNYXNrKExhbmVNYXNrKSB7fQorCisgICAgICAvLy8gQ29uc3RydWN0cyBhIG5ldyBTdWJSYW5nZSBvYmplY3QgYnkgY29weWluZyBsaXZlbmVzcyBmcm9tIEBwIE90aGVyLgorICAgICAgU3ViUmFuZ2UoTGFuZUJpdG1hc2sgTGFuZU1hc2ssIGNvbnN0IExpdmVSYW5nZSAmT3RoZXIsCisgICAgICAgICAgICAgICBCdW1wUHRyQWxsb2NhdG9yICZBbGxvY2F0b3IpCisgICAgICAgIDogTGl2ZVJhbmdlKE90aGVyLCBBbGxvY2F0b3IpLCBMYW5lTWFzayhMYW5lTWFzaykge30KKworICAgICAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MpIGNvbnN0OworICAgICAgdm9pZCBkdW1wKCkgY29uc3Q7CisgICAgfTsKKworICBwcml2YXRlOgorICAgIFN1YlJhbmdlICpTdWJSYW5nZXMgPSBudWxscHRyOyAvLy88IFNpbmdsZSBsaW5rZWQgbGlzdCBvZiBzdWJyZWdpc3RlciBsaXZlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vLyByYW5nZXMuCisKKyAgcHVibGljOgorICAgIGNvbnN0IHVuc2lnbmVkIHJlZzsgIC8vIHRoZSByZWdpc3RlciBvciBzdGFjayBzbG90IG9mIHRoaXMgaW50ZXJ2YWwuCisgICAgZmxvYXQgd2VpZ2h0OyAgICAgICAgLy8gd2VpZ2h0IG9mIHRoaXMgaW50ZXJ2YWwKKworICAgIExpdmVJbnRlcnZhbCh1bnNpZ25lZCBSZWcsIGZsb2F0IFdlaWdodCkgOiByZWcoUmVnKSwgd2VpZ2h0KFdlaWdodCkge30KKworICAgIH5MaXZlSW50ZXJ2YWwoKSB7CisgICAgICBjbGVhclN1YlJhbmdlcygpOworICAgIH0KKworICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CisgICAgY2xhc3MgU2luZ2xlTGlua2VkTGlzdEl0ZXJhdG9yIHsKKyAgICAgIFQgKlA7CisKKyAgICBwdWJsaWM6CisgICAgICBTaW5nbGVMaW5rZWRMaXN0SXRlcmF0b3I8VD4oVCAqUCkgOiBQKFApIHt9CisKKyAgICAgIFNpbmdsZUxpbmtlZExpc3RJdGVyYXRvcjxUPiAmb3BlcmF0b3IrKygpIHsKKyAgICAgICAgUCA9IFAtPk5leHQ7CisgICAgICAgIHJldHVybiAqdGhpczsKKyAgICAgIH0KKyAgICAgIFNpbmdsZUxpbmtlZExpc3RJdGVyYXRvcjxUPiBvcGVyYXRvcisrKGludCkgeworICAgICAgICBTaW5nbGVMaW5rZWRMaXN0SXRlcmF0b3IgcmVzID0gKnRoaXM7CisgICAgICAgICsrKnRoaXM7CisgICAgICAgIHJldHVybiByZXM7CisgICAgICB9CisgICAgICBib29sIG9wZXJhdG9yIT0oY29uc3QgU2luZ2xlTGlua2VkTGlzdEl0ZXJhdG9yPFQ+ICZPdGhlcikgeworICAgICAgICByZXR1cm4gUCAhPSBPdGhlci5vcGVyYXRvci0+KCk7CisgICAgICB9CisgICAgICBib29sIG9wZXJhdG9yPT0oY29uc3QgU2luZ2xlTGlua2VkTGlzdEl0ZXJhdG9yPFQ+ICZPdGhlcikgeworICAgICAgICByZXR1cm4gUCA9PSBPdGhlci5vcGVyYXRvci0+KCk7CisgICAgICB9CisgICAgICBUICZvcGVyYXRvciooKSBjb25zdCB7CisgICAgICAgIHJldHVybiAqUDsKKyAgICAgIH0KKyAgICAgIFQgKm9wZXJhdG9yLT4oKSBjb25zdCB7CisgICAgICAgIHJldHVybiBQOworICAgICAgfQorICAgIH07CisKKyAgICB1c2luZyBzdWJyYW5nZV9pdGVyYXRvciA9IFNpbmdsZUxpbmtlZExpc3RJdGVyYXRvcjxTdWJSYW5nZT47CisgICAgdXNpbmcgY29uc3Rfc3VicmFuZ2VfaXRlcmF0b3IgPSBTaW5nbGVMaW5rZWRMaXN0SXRlcmF0b3I8Y29uc3QgU3ViUmFuZ2U+OworCisgICAgc3VicmFuZ2VfaXRlcmF0b3Igc3VicmFuZ2VfYmVnaW4oKSB7CisgICAgICByZXR1cm4gc3VicmFuZ2VfaXRlcmF0b3IoU3ViUmFuZ2VzKTsKKyAgICB9CisgICAgc3VicmFuZ2VfaXRlcmF0b3Igc3VicmFuZ2VfZW5kKCkgeworICAgICAgcmV0dXJuIHN1YnJhbmdlX2l0ZXJhdG9yKG51bGxwdHIpOworICAgIH0KKworICAgIGNvbnN0X3N1YnJhbmdlX2l0ZXJhdG9yIHN1YnJhbmdlX2JlZ2luKCkgY29uc3QgeworICAgICAgcmV0dXJuIGNvbnN0X3N1YnJhbmdlX2l0ZXJhdG9yKFN1YlJhbmdlcyk7CisgICAgfQorICAgIGNvbnN0X3N1YnJhbmdlX2l0ZXJhdG9yIHN1YnJhbmdlX2VuZCgpIGNvbnN0IHsKKyAgICAgIHJldHVybiBjb25zdF9zdWJyYW5nZV9pdGVyYXRvcihudWxscHRyKTsKKyAgICB9CisKKyAgICBpdGVyYXRvcl9yYW5nZTxzdWJyYW5nZV9pdGVyYXRvcj4gc3VicmFuZ2VzKCkgeworICAgICAgcmV0dXJuIG1ha2VfcmFuZ2Uoc3VicmFuZ2VfYmVnaW4oKSwgc3VicmFuZ2VfZW5kKCkpOworICAgIH0KKworICAgIGl0ZXJhdG9yX3JhbmdlPGNvbnN0X3N1YnJhbmdlX2l0ZXJhdG9yPiBzdWJyYW5nZXMoKSBjb25zdCB7CisgICAgICByZXR1cm4gbWFrZV9yYW5nZShzdWJyYW5nZV9iZWdpbigpLCBzdWJyYW5nZV9lbmQoKSk7CisgICAgfQorCisgICAgLy8vIENyZWF0ZXMgYSBuZXcgZW1wdHkgc3VicmVnaXN0ZXIgbGl2ZSByYW5nZS4gVGhlIHJhbmdlIGlzIGFkZGVkIGF0IHRoZQorICAgIC8vLyBiZWdpbm5pbmcgb2YgdGhlIHN1YnJhbmdlIGxpc3Q7IHN1YnJhbmdlIGl0ZXJhdG9ycyBzdGF5IHZhbGlkLgorICAgIFN1YlJhbmdlICpjcmVhdGVTdWJSYW5nZShCdW1wUHRyQWxsb2NhdG9yICZBbGxvY2F0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhbmVCaXRtYXNrIExhbmVNYXNrKSB7CisgICAgICBTdWJSYW5nZSAqUmFuZ2UgPSBuZXcgKEFsbG9jYXRvcikgU3ViUmFuZ2UoTGFuZU1hc2spOworICAgICAgYXBwZW5kU3ViUmFuZ2UoUmFuZ2UpOworICAgICAgcmV0dXJuIFJhbmdlOworICAgIH0KKworICAgIC8vLyBMaWtlIGNyZWF0ZVN1YlJhbmdlKCkgYnV0IHRoZSBuZXcgcmFuZ2UgaXMgZmlsbGVkIHdpdGggYSBjb3B5IG9mIHRoZQorICAgIC8vLyBsaXZlbmVzcyBpbmZvcm1hdGlvbiBpbiBAcCBDb3B5RnJvbS4KKyAgICBTdWJSYW5nZSAqY3JlYXRlU3ViUmFuZ2VGcm9tKEJ1bXBQdHJBbGxvY2F0b3IgJkFsbG9jYXRvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhbmVCaXRtYXNrIExhbmVNYXNrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTGl2ZVJhbmdlICZDb3B5RnJvbSkgeworICAgICAgU3ViUmFuZ2UgKlJhbmdlID0gbmV3IChBbGxvY2F0b3IpIFN1YlJhbmdlKExhbmVNYXNrLCBDb3B5RnJvbSwgQWxsb2NhdG9yKTsKKyAgICAgIGFwcGVuZFN1YlJhbmdlKFJhbmdlKTsKKyAgICAgIHJldHVybiBSYW5nZTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0cnVlIGlmIHN1YnJlZ2lzdGVyIGxpdmVuZXNzIGluZm9ybWF0aW9uIGlzIGF2YWlsYWJsZS4KKyAgICBib29sIGhhc1N1YlJhbmdlcygpIGNvbnN0IHsKKyAgICAgIHJldHVybiBTdWJSYW5nZXMgIT0gbnVsbHB0cjsKKyAgICB9CisKKyAgICAvLy8gUmVtb3ZlcyBhbGwgc3VicmVnaXN0ZXIgbGl2ZW5lc3MgaW5mb3JtYXRpb24uCisgICAgdm9pZCBjbGVhclN1YlJhbmdlcygpOworCisgICAgLy8vIFJlbW92ZXMgYWxsIHN1YnJhbmdlcyB3aXRob3V0IGFueSBzZWdtZW50cyAoc3VicmFuZ2VzIHdpdGhvdXQgc2VnbWVudHMKKyAgICAvLy8gYXJlIG5vdCBjb25zaWRlcmVkIHZhbGlkIGFuZCBzaG91bGQgb25seSBleGlzdCB0ZW1wb3JhcmlseSkuCisgICAgdm9pZCByZW1vdmVFbXB0eVN1YlJhbmdlcygpOworCisgICAgLy8vIGdldFNpemUgLSBSZXR1cm5zIHRoZSBzdW0gb2Ygc2l6ZXMgb2YgYWxsIHRoZSBMaXZlUmFuZ2Uncy4KKyAgICAvLy8KKyAgICB1bnNpZ25lZCBnZXRTaXplKCkgY29uc3Q7CisKKyAgICAvLy8gaXNTcGlsbGFibGUgLSBDYW4gdGhpcyBpbnRlcnZhbCBiZSBzcGlsbGVkPworICAgIGJvb2wgaXNTcGlsbGFibGUoKSBjb25zdCB7CisgICAgICByZXR1cm4gd2VpZ2h0ICE9IGh1Z2VfdmFsZjsKKyAgICB9CisKKyAgICAvLy8gbWFya05vdFNwaWxsYWJsZSAtIE1hcmsgaW50ZXJ2YWwgYXMgbm90IHNwaWxsYWJsZQorICAgIHZvaWQgbWFya05vdFNwaWxsYWJsZSgpIHsKKyAgICAgIHdlaWdodCA9IGh1Z2VfdmFsZjsKKyAgICB9CisKKyAgICAvLy8gRm9yIGEgZ2l2ZW4gbGFuZSBtYXNrIEBwIExhbmVNYXNrLCBjb21wdXRlIGluZGV4ZXMgYXQgd2hpY2ggdGhlCisgICAgLy8vIGxhbmUgaXMgbWFya2VkIHVuZGVmaW5lZCBieSBzdWJyZWdpc3RlciA8ZGVmLHJlYWQtdW5kZWY+IGRlZmluaXRpb25zLgorICAgIHZvaWQgY29tcHV0ZVN1YlJhbmdlVW5kZWZzKFNtYWxsVmVjdG9ySW1wbDxTbG90SW5kZXg+ICZVbmRlZnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGFuZUJpdG1hc2sgTGFuZU1hc2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNsb3RJbmRleGVzICZJbmRleGVzKSBjb25zdDsKKworICAgIC8vLyBSZWZpbmVzIHRoZSBzdWJyYW5nZXMgdG8gc3VwcG9ydCBccCBMYW5lTWFzay4gVGhpcyBtYXkgb25seSBiZSBjYWxsZWQKKyAgICAvLy8gZm9yIExJLmhhc1N1YnJhbmdlKCk9PXRydWUuIFN1YnJlZ2lzdGVyIHJhbmdlcyBhcmUgc3BsaXQgb3IgY3JlYXRlZAorICAgIC8vLyB1bnRpbCBccCBMYW5lTWFzayBjYW4gYmUgbWF0Y2hlZCBleGFjdGx5LiBccCBNb2QgaXMgZXhlY3V0ZWQgb24gdGhlCisgICAgLy8vIG1hdGNoaW5nIHN1YnJhbmdlcy4KKyAgICAvLy8KKyAgICAvLy8gRXhhbXBsZToKKyAgICAvLy8gICAgR2l2ZW4gYW4gaW50ZXJ2YWwgd2l0aCBzdWJyYW5nZXMgd2l0aCBsYW5lbWFza3MgTDBGMDAsIEwwMEYwIGFuZAorICAgIC8vLyAgICBMMDAwRiwgcmVmaW5pbmcgZm9yIG1hc2sgTDAwMTguIFdpbGwgc3BsaXQgdGhlIEwwMEYwIGxhbmUgaW50bworICAgIC8vLyAgICBMMDBFMCBhbmQgTDAwMTAgYW5kIHRoZSBMMDAwRiBsYW5lIGludG8gTDAwMDcgYW5kIEwwMDA4LiBUaGUgTW9kCisgICAgLy8vICAgIGZ1bmN0aW9uIHdpbGwgYmUgYXBwbGllZCB0byB0aGUgTDAwMTAgYW5kIEwwMDA4IHN1YnJhbmdlcy4KKyAgICB2b2lkIHJlZmluZVN1YlJhbmdlcyhCdW1wUHRyQWxsb2NhdG9yICZBbGxvY2F0b3IsIExhbmVCaXRtYXNrIExhbmVNYXNrLAorICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6ZnVuY3Rpb248dm9pZChMaXZlSW50ZXJ2YWw6OlN1YlJhbmdlJik+IE1vZCk7CisKKyAgICBib29sIG9wZXJhdG9yPChjb25zdCBMaXZlSW50ZXJ2YWwmIG90aGVyKSBjb25zdCB7CisgICAgICBjb25zdCBTbG90SW5kZXggJnRoaXNJbmRleCA9IGJlZ2luSW5kZXgoKTsKKyAgICAgIGNvbnN0IFNsb3RJbmRleCAmb3RoZXJJbmRleCA9IG90aGVyLmJlZ2luSW5kZXgoKTsKKyAgICAgIHJldHVybiBzdGQ6OnRpZSh0aGlzSW5kZXgsIHJlZykgPCBzdGQ6OnRpZShvdGhlckluZGV4LCBvdGhlci5yZWcpOworICAgIH0KKworICAgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk9TKSBjb25zdDsKKyAgICB2b2lkIGR1bXAoKSBjb25zdDsKKworICAgIC8vLyBcYnJpZWYgV2Fsa3MgdGhlIGludGVydmFsIGFuZCBhc3NlcnQgaWYgYW55IGludmFyaWFudHMgZmFpbCB0byBob2xkLgorICAgIC8vLworICAgIC8vLyBOb3RlIHRoYXQgdGhpcyBpcyBhIG5vLW9wIHdoZW4gYXNzZXJ0cyBhcmUgZGlzYWJsZWQuCisjaWZkZWYgTkRFQlVHCisgICAgdm9pZCB2ZXJpZnkoY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAqTVJJID0gbnVsbHB0cikgY29uc3Qge30KKyNlbHNlCisgICAgdm9pZCB2ZXJpZnkoY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAqTVJJID0gbnVsbHB0cikgY29uc3Q7CisjZW5kaWYKKworICBwcml2YXRlOgorICAgIC8vLyBBcHBlbmRzIEBwIFJhbmdlIHRvIFN1YlJhbmdlcyBsaXN0LgorICAgIHZvaWQgYXBwZW5kU3ViUmFuZ2UoU3ViUmFuZ2UgKlJhbmdlKSB7CisgICAgICBSYW5nZS0+TmV4dCA9IFN1YlJhbmdlczsKKyAgICAgIFN1YlJhbmdlcyA9IFJhbmdlOworICAgIH0KKworICAgIC8vLyBGcmVlIG1lbW9yeSBoZWxkIGJ5IFN1YlJhbmdlLgorICAgIHZvaWQgZnJlZVN1YlJhbmdlKFN1YlJhbmdlICpTKTsKKyAgfTsKKworICBpbmxpbmUgcmF3X29zdHJlYW0gJm9wZXJhdG9yPDwocmF3X29zdHJlYW0gJk9TLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTGl2ZUludGVydmFsOjpTdWJSYW5nZSAmU1IpIHsKKyAgICBTUi5wcmludChPUyk7CisgICAgcmV0dXJuIE9TOworICB9CisKKyAgaW5saW5lIHJhd19vc3RyZWFtICZvcGVyYXRvcjw8KHJhd19vc3RyZWFtICZPUywgY29uc3QgTGl2ZUludGVydmFsICZMSSkgeworICAgIExJLnByaW50KE9TKTsKKyAgICByZXR1cm4gT1M7CisgIH0KKworICByYXdfb3N0cmVhbSAmb3BlcmF0b3I8PChyYXdfb3N0cmVhbSAmT1MsIGNvbnN0IExpdmVSYW5nZTo6U2VnbWVudCAmUyk7CisKKyAgaW5saW5lIGJvb2wgb3BlcmF0b3I8KFNsb3RJbmRleCBWLCBjb25zdCBMaXZlUmFuZ2U6OlNlZ21lbnQgJlMpIHsKKyAgICByZXR1cm4gViA8IFMuc3RhcnQ7CisgIH0KKworICBpbmxpbmUgYm9vbCBvcGVyYXRvcjwoY29uc3QgTGl2ZVJhbmdlOjpTZWdtZW50ICZTLCBTbG90SW5kZXggVikgeworICAgIHJldHVybiBTLnN0YXJ0IDwgVjsKKyAgfQorCisgIC8vLyBIZWxwZXIgY2xhc3MgZm9yIHBlcmZvcm1hbnQgTGl2ZVJhbmdlIGJ1bGsgdXBkYXRlcy4KKyAgLy8vCisgIC8vLyBDYWxsaW5nIExpdmVSYW5nZTo6YWRkU2VnbWVudCgpIHJlcGVhdGVkbHkgY2FuIGJlIGV4cGVuc2l2ZSBvbiBsYXJnZQorICAvLy8gbGl2ZSByYW5nZXMgYmVjYXVzZSBzZWdtZW50cyBhZnRlciB0aGUgaW5zZXJ0aW9uIHBvaW50IG1heSBuZWVkIHRvIGJlCisgIC8vLyBzaGlmdGVkLiBUaGUgTGl2ZVJhbmdlVXBkYXRlciBjbGFzcyBjYW4gZGVmZXIgdGhlIHNoaWZ0aW5nIHdoZW4gYWRkaW5nCisgIC8vLyBtYW55IHNlZ21lbnRzIGluIG9yZGVyLgorICAvLy8KKyAgLy8vIFRoZSBMaXZlUmFuZ2Ugd2lsbCBiZSBpbiBhbiBpbnZhbGlkIHN0YXRlIHVudGlsIGZsdXNoKCkgaXMgY2FsbGVkLgorICBjbGFzcyBMaXZlUmFuZ2VVcGRhdGVyIHsKKyAgICBMaXZlUmFuZ2UgKkxSOworICAgIFNsb3RJbmRleCBMYXN0U3RhcnQ7CisgICAgTGl2ZVJhbmdlOjppdGVyYXRvciBXcml0ZUk7CisgICAgTGl2ZVJhbmdlOjppdGVyYXRvciBSZWFkSTsKKyAgICBTbWFsbFZlY3RvcjxMaXZlUmFuZ2U6OlNlZ21lbnQsIDE2PiBTcGlsbHM7CisgICAgdm9pZCBtZXJnZVNwaWxscygpOworCisgIHB1YmxpYzoKKyAgICAvLy8gQ3JlYXRlIGEgTGl2ZVJhbmdlVXBkYXRlciBmb3IgYWRkaW5nIHNlZ21lbnRzIHRvIExSLgorICAgIC8vLyBMUiB3aWxsIHRlbXBvcmFyaWx5IGJlIGluIGFuIGludmFsaWQgc3RhdGUgdW50aWwgZmx1c2goKSBpcyBjYWxsZWQuCisgICAgTGl2ZVJhbmdlVXBkYXRlcihMaXZlUmFuZ2UgKmxyID0gbnVsbHB0cikgOiBMUihscikge30KKworICAgIH5MaXZlUmFuZ2VVcGRhdGVyKCkgeyBmbHVzaCgpOyB9CisKKyAgICAvLy8gQWRkIGEgc2VnbWVudCB0byBMUiBhbmQgY29hbGVzY2Ugd2hlbiBwb3NzaWJsZSwganVzdCBsaWtlCisgICAgLy8vIExSLmFkZFNlZ21lbnQoKS4gU2VnbWVudHMgc2hvdWxkIGJlIGFkZGVkIGluIGluY3JlYXNpbmcgc3RhcnQgb3JkZXIgZm9yCisgICAgLy8vIGJlc3QgcGVyZm9ybWFuY2UuCisgICAgdm9pZCBhZGQoTGl2ZVJhbmdlOjpTZWdtZW50KTsKKworICAgIHZvaWQgYWRkKFNsb3RJbmRleCBTdGFydCwgU2xvdEluZGV4IEVuZCwgVk5JbmZvICpWTkkpIHsKKyAgICAgIGFkZChMaXZlUmFuZ2U6OlNlZ21lbnQoU3RhcnQsIEVuZCwgVk5JKSk7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBMUiBpcyBjdXJyZW50bHkgaW4gYW4gaW52YWxpZCBzdGF0ZSwgYW5kIGZsdXNoKCkKKyAgICAvLy8gbmVlZHMgdG8gYmUgY2FsbGVkLgorICAgIGJvb2wgaXNEaXJ0eSgpIGNvbnN0IHsgcmV0dXJuIExhc3RTdGFydC5pc1ZhbGlkKCk7IH0KKworICAgIC8vLyBGbHVzaCB0aGUgdXBkYXRlciBzdGF0ZSB0byBMUiBzbyBpdCBpcyB2YWxpZCBhbmQgY29udGFpbnMgYWxsIGFkZGVkCisgICAgLy8vIHNlZ21lbnRzLgorICAgIHZvaWQgZmx1c2goKTsKKworICAgIC8vLyBTZWxlY3QgYSBkaWZmZXJlbnQgZGVzdGluYXRpb24gbGl2ZSByYW5nZS4KKyAgICB2b2lkIHNldERlc3QoTGl2ZVJhbmdlICpscikgeworICAgICAgaWYgKExSICE9IGxyICYmIGlzRGlydHkoKSkKKyAgICAgICAgZmx1c2goKTsKKyAgICAgIExSID0gbHI7CisgICAgfQorCisgICAgLy8vIEdldCB0aGUgY3VycmVudCBkZXN0aW5hdGlvbiBsaXZlIHJhbmdlLgorICAgIExpdmVSYW5nZSAqZ2V0RGVzdCgpIGNvbnN0IHsgcmV0dXJuIExSOyB9CisKKyAgICB2b2lkIGR1bXAoKSBjb25zdDsKKyAgICB2b2lkIHByaW50KHJhd19vc3RyZWFtJikgY29uc3Q7CisgIH07CisKKyAgaW5saW5lIHJhd19vc3RyZWFtICZvcGVyYXRvcjw8KHJhd19vc3RyZWFtICZPUywgY29uc3QgTGl2ZVJhbmdlVXBkYXRlciAmWCkgeworICAgIFgucHJpbnQoT1MpOworICAgIHJldHVybiBPUzsKKyAgfQorCisgIC8vLyBDb25uZWN0ZWRWTkluZm9FcUNsYXNzZXMgLSBIZWxwZXIgY2xhc3MgdGhhdCBjYW4gZGl2aWRlIFZOSW5mb3MgaW4gYQorICAvLy8gTGl2ZUludGVydmFsIGludG8gZXF1aXZhbGVuY2UgY2xhc2VzIG9mIGNvbm5lY3RlZCBjb21wb25lbnRzLiBBCisgIC8vLyBMaXZlSW50ZXJ2YWwgdGhhdCBoYXMgbXVsdGlwbGUgY29ubmVjdGVkIGNvbXBvbmVudHMgY2FuIGJlIGJyb2tlbiBpbnRvCisgIC8vLyBtdWx0aXBsZSBMaXZlSW50ZXJ2YWxzLgorICAvLy8KKyAgLy8vIEdpdmVuIGEgTGl2ZUludGVydmFsIHRoYXQgbWF5IGhhdmUgbXVsdGlwbGUgY29ubmVjdGVkIGNvbXBvbmVudHMsIHJ1bjoKKyAgLy8vCisgIC8vLyAgIHVuc2lnbmVkIG51bUNvbXBzID0gQ29uRVEuQ2xhc3NpZnkoTEkpOworICAvLy8gICBpZiAobnVtQ29tcHMgPiAxKSB7CisgIC8vLyAgICAgLy8gYWxsb2NhdGUgbnVtQ29tcHMtMSBuZXcgTGl2ZUludGVydmFscyBpbnRvIExJU1sxLi5dCisgIC8vLyAgICAgQ29uRVEuRGlzdHJpYnV0ZShMSVMpOworICAvLy8gfQorCisgIGNsYXNzIENvbm5lY3RlZFZOSW5mb0VxQ2xhc3NlcyB7CisgICAgTGl2ZUludGVydmFscyAmTElTOworICAgIEludEVxQ2xhc3NlcyBFcUNsYXNzOworCisgIHB1YmxpYzoKKyAgICBleHBsaWNpdCBDb25uZWN0ZWRWTkluZm9FcUNsYXNzZXMoTGl2ZUludGVydmFscyAmbGlzKSA6IExJUyhsaXMpIHt9CisKKyAgICAvLy8gQ2xhc3NpZnkgdGhlIHZhbHVlcyBpbiBccCBMUiBpbnRvIGNvbm5lY3RlZCBjb21wb25lbnRzLgorICAgIC8vLyBSZXR1cm5zIHRoZSBudW1iZXIgb2YgY29ubmVjdGVkIGNvbXBvbmVudHMuCisgICAgdW5zaWduZWQgQ2xhc3NpZnkoY29uc3QgTGl2ZVJhbmdlICZMUik7CisKKyAgICAvLy8gZ2V0RXFDbGFzcyAtIENsYXNzaWZ5IGNyZWF0ZXMgZXF1aXZhbGVuY2UgY2xhc3NlcyBudW1iZXJlZCAwLi5OLiBSZXR1cm4KKyAgICAvLy8gdGhlIGVxdWl2YWxlbmNlIGNsYXNzIGFzc2lnbmVkIHRoZSBWTkkuCisgICAgdW5zaWduZWQgZ2V0RXFDbGFzcyhjb25zdCBWTkluZm8gKlZOSSkgY29uc3QgeyByZXR1cm4gRXFDbGFzc1tWTkktPmlkXTsgfQorCisgICAgLy8vIERpc3RyaWJ1dGUgdmFsdWVzIGluIFxwIExJIGludG8gYSBzZXBhcmF0ZSBMaXZlSW50ZXJ2YWxzCisgICAgLy8vIGZvciBlYWNoIGNvbm5lY3RlZCBjb21wb25lbnQuIExJViBtdXN0IGhhdmUgYW4gZW1wdHkgTGl2ZUludGVydmFsIGZvcgorICAgIC8vLyBlYWNoIGFkZGl0aW9uYWwgY29ubmVjdGVkIGNvbXBvbmVudC4gVGhlIGZpcnN0IGNvbm5lY3RlZCBjb21wb25lbnQgaXMKKyAgICAvLy8gbGVmdCBpbiBccCBMSS4KKyAgICB2b2lkIERpc3RyaWJ1dGUoTGl2ZUludGVydmFsICZMSSwgTGl2ZUludGVydmFsICpMSVZbXSwKKyAgICAgICAgICAgICAgICAgICAgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJKTsKKyAgfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9MSVZFSU5URVJWQUxfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xpdmVJbnRlcnZhbFVuaW9uLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGl2ZUludGVydmFsVW5pb24uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTIyZTU0Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xpdmVJbnRlcnZhbFVuaW9uLmgKQEAgLTAsMCArMSwxOTkgQEAKKy8vPT09LSBMaXZlSW50ZXJ2YWxVbmlvbi5oIC0gTGl2ZSBpbnRlcnZhbCB1bmlvbiBkYXRhIHN0cnVjdCAtLS0qLSBDKysgLSotLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gTGl2ZUludGVydmFsVW5pb24gaXMgYSB1bmlvbiBvZiBsaXZlIHNlZ21lbnRzIGFjcm9zcyBtdWx0aXBsZSBsaXZlIHZpcnR1YWwKKy8vIHJlZ2lzdGVycy4gVGhpcyBtYXkgYmUgdXNlZCBkdXJpbmcgY29hbGVzY2luZyB0byByZXByZXNlbnQgYSBjb25ncnVlbmNlCisvLyBjbGFzcywgb3IgZHVyaW5nIHJlZ2lzdGVyIGFsbG9jYXRpb24gdG8gbW9kZWwgbGl2ZW5lc3Mgb2YgYSBwaHlzaWNhbAorLy8gcmVnaXN0ZXIuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTElWRUlOVEVSVkFMVU5JT05fSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTElWRUlOVEVSVkFMVU5JT05fSAorCisjaW5jbHVkZSAibGx2bS9BRFQvSW50ZXJ2YWxNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9MaXZlSW50ZXJ2YWwuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2xvdEluZGV4ZXMuaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPGxpbWl0cz4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyByYXdfb3N0cmVhbTsKK2NsYXNzIFRhcmdldFJlZ2lzdGVySW5mbzsKKworI2lmbmRlZiBOREVCVUcKKy8vIGZvcndhcmQgZGVjbGFyYXRpb24KK3RlbXBsYXRlIDx1bnNpZ25lZCBFbGVtZW50PiBjbGFzcyBTcGFyc2VCaXRWZWN0b3I7CisKK3VzaW5nIExpdmVWaXJ0UmVnQml0U2V0ID0gU3BhcnNlQml0VmVjdG9yPDEyOD47CisjZW5kaWYKKworLy8vIFVuaW9uIG9mIGxpdmUgaW50ZXJ2YWxzIHRoYXQgYXJlIHN0cm9uZyBjYW5kaWRhdGVzIGZvciBjb2FsZXNjaW5nIGludG8gYQorLy8vIHNpbmdsZSByZWdpc3RlciAoZWl0aGVyIHBoeXNpY2FsIG9yIHZpcnR1YWwgZGVwZW5kaW5nIG9uIHRoZSBjb250ZXh0KS4gIFdlCisvLy8gZXhwZWN0IHRoZSBjb25zdGl0dWVudCBsaXZlIGludGVydmFscyB0byBiZSBkaXNqb2ludCwgYWx0aG91Z2ggd2UgbWF5CisvLy8gZXZlbnR1YWxseSBtYWtlIGV4Y2VwdGlvbnMgdG8gaGFuZGxlIHZhbHVlLWJhc2VkIGludGVyZmVyZW5jZS4KK2NsYXNzIExpdmVJbnRlcnZhbFVuaW9uIHsKKyAgLy8gQSBzZXQgb2YgbGl2ZSB2aXJ0dWFsIHJlZ2lzdGVyIHNlZ21lbnRzIHRoYXQgc3VwcG9ydHMgZmFzdCBpbnNlcnRpb24sCisgIC8vIGludGVyc2VjdGlvbiwgYW5kIHJlbW92YWwuCisgIC8vIE1hcHBpbmcgU2xvdEluZGV4IGludGVydmFscyB0byB2aXJ0dWFsIHJlZ2lzdGVyIG51bWJlcnMuCisgIHVzaW5nIExpdmVTZWdtZW50cyA9IEludGVydmFsTWFwPFNsb3RJbmRleCwgTGl2ZUludGVydmFsKj47CisKK3B1YmxpYzoKKyAgLy8gU2VnbWVudEl0ZXIgY2FuIGFkdmFuY2UgdG8gdGhlIG5leHQgc2VnbWVudCBvcmRlcmVkIGJ5IHN0YXJ0aW5nIHBvc2l0aW9uCisgIC8vIHdoaWNoIG1heSBiZWxvbmcgdG8gYSBkaWZmZXJlbnQgbGl2ZSB2aXJ0dWFsIHJlZ2lzdGVyLiBXZSBhbHNvIG11c3QgYmUgYWJsZQorICAvLyB0byByZWFjaCB0aGUgY3VycmVudCBzZWdtZW50J3MgY29udGFpbmluZyB2aXJ0dWFsIHJlZ2lzdGVyLgorICB1c2luZyBTZWdtZW50SXRlciA9IExpdmVTZWdtZW50czo6aXRlcmF0b3I7CisKKyAgLy8vIENvbnN0IHZlcnNpb24gb2YgU2VnbWVudEl0ZXIuCisgIHVzaW5nIENvbnN0U2VnbWVudEl0ZXIgPSBMaXZlU2VnbWVudHM6OmNvbnN0X2l0ZXJhdG9yOworCisgIC8vIExpdmVJbnRlcnZhbFVuaW9ucyBzaGFyZSBhbiBleHRlcm5hbCBhbGxvY2F0b3IuCisgIHVzaW5nIEFsbG9jYXRvciA9IExpdmVTZWdtZW50czo6QWxsb2NhdG9yOworCitwcml2YXRlOgorICB1bnNpZ25lZCBUYWcgPSAwOyAgICAgICAvLyB1bmlxdWUgdGFnIGZvciBjdXJyZW50IGNvbnRlbnRzLgorICBMaXZlU2VnbWVudHMgU2VnbWVudHM7ICAvLyB1bmlvbiBvZiB2aXJ0dWFsIHJlZyBzZWdtZW50cworCitwdWJsaWM6CisgIGV4cGxpY2l0IExpdmVJbnRlcnZhbFVuaW9uKEFsbG9jYXRvciAmYSkgOiBTZWdtZW50cyhhKSB7fQorCisgIC8vIEl0ZXJhdGUgb3ZlciBhbGwgc2VnbWVudHMgaW4gdGhlIHVuaW9uIG9mIGxpdmUgdmlydHVhbCByZWdpc3RlcnMgb3JkZXJlZAorICAvLyBieSB0aGVpciBzdGFydGluZyBwb3NpdGlvbi4KKyAgU2VnbWVudEl0ZXIgYmVnaW4oKSB7IHJldHVybiBTZWdtZW50cy5iZWdpbigpOyB9CisgIFNlZ21lbnRJdGVyIGVuZCgpIHsgcmV0dXJuIFNlZ21lbnRzLmVuZCgpOyB9CisgIFNlZ21lbnRJdGVyIGZpbmQoU2xvdEluZGV4IHgpIHsgcmV0dXJuIFNlZ21lbnRzLmZpbmQoeCk7IH0KKyAgQ29uc3RTZWdtZW50SXRlciBiZWdpbigpIGNvbnN0IHsgcmV0dXJuIFNlZ21lbnRzLmJlZ2luKCk7IH0KKyAgQ29uc3RTZWdtZW50SXRlciBlbmQoKSBjb25zdCB7IHJldHVybiBTZWdtZW50cy5lbmQoKTsgfQorICBDb25zdFNlZ21lbnRJdGVyIGZpbmQoU2xvdEluZGV4IHgpIGNvbnN0IHsgcmV0dXJuIFNlZ21lbnRzLmZpbmQoeCk7IH0KKworICBib29sIGVtcHR5KCkgY29uc3QgeyByZXR1cm4gU2VnbWVudHMuZW1wdHkoKTsgfQorICBTbG90SW5kZXggc3RhcnRJbmRleCgpIGNvbnN0IHsgcmV0dXJuIFNlZ21lbnRzLnN0YXJ0KCk7IH0KKworICAvLyBQcm92aWRlIHB1YmxpYyBhY2Nlc3MgdG8gdGhlIHVuZGVybHlpbmcgbWFwIHRvIGFsbG93IG92ZXJsYXAgaXRlcmF0aW9uLgorICB1c2luZyBNYXAgPSBMaXZlU2VnbWVudHM7CisgIGNvbnN0IE1hcCAmZ2V0TWFwKCkgY29uc3QgeyByZXR1cm4gU2VnbWVudHM7IH0KKworICAvLy8gZ2V0VGFnIC0gUmV0dXJuIGFuIG9wYXF1ZSB0YWcgcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSB1bmlvbi4KKyAgdW5zaWduZWQgZ2V0VGFnKCkgY29uc3QgeyByZXR1cm4gVGFnOyB9CisKKyAgLy8vIGNoYW5nZWRTaW5jZSAtIFJldHVybiB0cnVlIGlmIHRoZSB1bmlvbiBjaGFuZ2Ugc2luY2UgZ2V0VGFnIHJldHVybmVkIHRhZy4KKyAgYm9vbCBjaGFuZ2VkU2luY2UodW5zaWduZWQgdGFnKSBjb25zdCB7IHJldHVybiB0YWcgIT0gVGFnOyB9CisKKyAgLy8gQWRkIGEgbGl2ZSB2aXJ0dWFsIHJlZ2lzdGVyIHRvIHRoaXMgdW5pb24gYW5kIG1lcmdlIGl0cyBzZWdtZW50cy4KKyAgdm9pZCB1bmlmeShMaXZlSW50ZXJ2YWwgJlZpcnRSZWcsIGNvbnN0IExpdmVSYW5nZSAmUmFuZ2UpOworCisgIC8vIFJlbW92ZSBhIGxpdmUgdmlydHVhbCByZWdpc3RlcidzIHNlZ21lbnRzIGZyb20gdGhpcyB1bmlvbi4KKyAgdm9pZCBleHRyYWN0KExpdmVJbnRlcnZhbCAmVmlydFJlZywgY29uc3QgTGl2ZVJhbmdlICZSYW5nZSk7CisKKyAgLy8gUmVtb3ZlIGFsbCBpbnNlcnRlZCB2aXJ0dWFsIHJlZ2lzdGVycy4KKyAgdm9pZCBjbGVhcigpIHsgU2VnbWVudHMuY2xlYXIoKTsgKytUYWc7IH0KKworICAvLyBQcmludCB1bmlvbiwgdXNpbmcgVFJJIHRvIHRyYW5zbGF0ZSByZWdpc3RlciBuYW1lcworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUywgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkpIGNvbnN0OworCisjaWZuZGVmIE5ERUJVRworICAvLyBWZXJpZnkgdGhlIGxpdmUgaW50ZXJ2YWxzIGluIHRoaXMgdW5pb24gYW5kIGFkZCB0aGVtIHRvIHRoZSB2aXNpdGVkIHNldC4KKyAgdm9pZCB2ZXJpZnkoTGl2ZVZpcnRSZWdCaXRTZXQmIFZpc2l0ZWRWUmVncyk7CisjZW5kaWYKKworICAvLy8gUXVlcnkgaW50ZXJmZXJlbmNlcyBiZXR3ZWVuIGEgc2luZ2xlIGxpdmUgdmlydHVhbCByZWdpc3RlciBhbmQgYSBsaXZlCisgIC8vLyBpbnRlcnZhbCB1bmlvbi4KKyAgY2xhc3MgUXVlcnkgeworICAgIGNvbnN0IExpdmVJbnRlcnZhbFVuaW9uICpMaXZlVW5pb24gPSBudWxscHRyOworICAgIGNvbnN0IExpdmVSYW5nZSAqTFIgPSBudWxscHRyOworICAgIExpdmVSYW5nZTo6Y29uc3RfaXRlcmF0b3IgTFJJOyAgLy8vPCBjdXJyZW50IHBvc2l0aW9uIGluIExSCisgICAgQ29uc3RTZWdtZW50SXRlciBMaXZlVW5pb25JOyAgICAvLy88IGN1cnJlbnQgcG9zaXRpb24gaW4gTGl2ZVVuaW9uCisgICAgU21hbGxWZWN0b3I8TGl2ZUludGVydmFsKiw0PiBJbnRlcmZlcmluZ1ZSZWdzOworICAgIGJvb2wgQ2hlY2tlZEZpcnN0SW50ZXJmZXJlbmNlID0gZmFsc2U7CisgICAgYm9vbCBTZWVuQWxsSW50ZXJmZXJlbmNlcyA9IGZhbHNlOworICAgIHVuc2lnbmVkIFRhZyA9IDA7CisgICAgdW5zaWduZWQgVXNlclRhZyA9IDA7CisKKyAgICB2b2lkIHJlc2V0KHVuc2lnbmVkIE5ld1VzZXJUYWcsIGNvbnN0IExpdmVSYW5nZSAmTmV3TFIsCisgICAgICAgICAgICAgICBjb25zdCBMaXZlSW50ZXJ2YWxVbmlvbiAmTmV3TGl2ZVVuaW9uKSB7CisgICAgICBMaXZlVW5pb24gPSAmTmV3TGl2ZVVuaW9uOworICAgICAgTFIgPSAmTmV3TFI7CisgICAgICBJbnRlcmZlcmluZ1ZSZWdzLmNsZWFyKCk7CisgICAgICBDaGVja2VkRmlyc3RJbnRlcmZlcmVuY2UgPSBmYWxzZTsKKyAgICAgIFNlZW5BbGxJbnRlcmZlcmVuY2VzID0gZmFsc2U7CisgICAgICBUYWcgPSBOZXdMaXZlVW5pb24uZ2V0VGFnKCk7CisgICAgICBVc2VyVGFnID0gTmV3VXNlclRhZzsKKyAgICB9CisKKyAgcHVibGljOgorICAgIFF1ZXJ5KCkgPSBkZWZhdWx0OworICAgIFF1ZXJ5KGNvbnN0IExpdmVSYW5nZSAmTFIsIGNvbnN0IExpdmVJbnRlcnZhbFVuaW9uICZMSVUpOgorICAgICAgTGl2ZVVuaW9uKCZMSVUpLCBMUigmTFIpIHt9CisgICAgUXVlcnkoY29uc3QgUXVlcnkgJikgPSBkZWxldGU7CisgICAgUXVlcnkgJm9wZXJhdG9yPShjb25zdCBRdWVyeSAmKSA9IGRlbGV0ZTsKKworICAgIHZvaWQgaW5pdCh1bnNpZ25lZCBOZXdVc2VyVGFnLCBjb25zdCBMaXZlUmFuZ2UgJk5ld0xSLAorICAgICAgICAgICAgICBjb25zdCBMaXZlSW50ZXJ2YWxVbmlvbiAmTmV3TGl2ZVVuaW9uKSB7CisgICAgICBpZiAoVXNlclRhZyA9PSBOZXdVc2VyVGFnICYmIExSID09ICZOZXdMUiAmJiBMaXZlVW5pb24gPT0gJk5ld0xpdmVVbmlvbiAmJgorICAgICAgICAgICFOZXdMaXZlVW5pb24uY2hhbmdlZFNpbmNlKFRhZykpIHsKKyAgICAgICAgLy8gUmV0YWluIGNhY2hlZCByZXN1bHRzLCBlLmcuIGZpcnN0SW50ZXJmZXJlbmNlLgorICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICByZXNldChOZXdVc2VyVGFnLCBOZXdMUiwgTmV3TGl2ZVVuaW9uKTsKKyAgICB9CisKKyAgICAvLyBEb2VzIHRoaXMgbGl2ZSB2aXJ0dWFsIHJlZ2lzdGVyIGludGVyZmVyZSB3aXRoIHRoZSB1bmlvbj8KKyAgICBib29sIGNoZWNrSW50ZXJmZXJlbmNlKCkgeyByZXR1cm4gY29sbGVjdEludGVyZmVyaW5nVlJlZ3MoMSk7IH0KKworICAgIC8vIENvdW50IHRoZSB2aXJ0dWFsIHJlZ2lzdGVycyBpbiB0aGlzIHVuaW9uIHRoYXQgaW50ZXJmZXJlIHdpdGggdGhpcworICAgIC8vIHF1ZXJ5J3MgbGl2ZSB2aXJ0dWFsIHJlZ2lzdGVyLCB1cCB0byBtYXhJbnRlcmZlcmluZ1JlZ3MuCisgICAgdW5zaWduZWQgY29sbGVjdEludGVyZmVyaW5nVlJlZ3MoCisgICAgICAgIHVuc2lnbmVkIE1heEludGVyZmVyaW5nUmVncyA9IHN0ZDo6bnVtZXJpY19saW1pdHM8dW5zaWduZWQ+OjptYXgoKSk7CisKKyAgICAvLyBXYXMgdGhpcyB2aXJ0dWFsIHJlZ2lzdGVyIHZpc2l0ZWQgZHVyaW5nIGNvbGxlY3RJbnRlcmZlcmluZ1ZSZWdzPworICAgIGJvb2wgaXNTZWVuSW50ZXJmZXJlbmNlKExpdmVJbnRlcnZhbCAqVlJlZykgY29uc3Q7CisKKyAgICAvLyBEaWQgY29sbGVjdEludGVyZmVyaW5nVlJlZ3MgY29sbGVjdCBhbGwgaW50ZXJmZXJlbmNlcz8KKyAgICBib29sIHNlZW5BbGxJbnRlcmZlcmVuY2VzKCkgY29uc3QgeyByZXR1cm4gU2VlbkFsbEludGVyZmVyZW5jZXM7IH0KKworICAgIC8vIFZlY3RvciBnZW5lcmF0ZWQgYnkgY29sbGVjdEludGVyZmVyaW5nVlJlZ3MuCisgICAgY29uc3QgU21hbGxWZWN0b3JJbXBsPExpdmVJbnRlcnZhbCo+ICZpbnRlcmZlcmluZ1ZSZWdzKCkgY29uc3QgeworICAgICAgcmV0dXJuIEludGVyZmVyaW5nVlJlZ3M7CisgICAgfQorICB9OworCisgIC8vIEFycmF5IG9mIExpdmVJbnRlcnZhbFVuaW9ucy4KKyAgY2xhc3MgQXJyYXkgeworICAgIHVuc2lnbmVkIFNpemUgPSAwOworICAgIExpdmVJbnRlcnZhbFVuaW9uICpMSVVzID0gbnVsbHB0cjsKKworICBwdWJsaWM6CisgICAgQXJyYXkoKSA9IGRlZmF1bHQ7CisgICAgfkFycmF5KCkgeyBjbGVhcigpOyB9CisKKyAgICAvLyBJbml0aWFsaXplIHRoZSBhcnJheSB0byBoYXZlIFNpemUgZW50cmllcy4KKyAgICAvLyBSZXVzZSBhbiBleGlzdGluZyBhbGxvY2F0aW9uIGlmIHRoZSBzaXplIG1hdGNoZXMuCisgICAgdm9pZCBpbml0KExpdmVJbnRlcnZhbFVuaW9uOjpBbGxvY2F0b3ImLCB1bnNpZ25lZCBTaXplKTsKKworICAgIHVuc2lnbmVkIHNpemUoKSBjb25zdCB7IHJldHVybiBTaXplOyB9CisKKyAgICB2b2lkIGNsZWFyKCk7CisKKyAgICBMaXZlSW50ZXJ2YWxVbmlvbiYgb3BlcmF0b3JbXSh1bnNpZ25lZCBpZHgpIHsKKyAgICAgIGFzc2VydChpZHggPCAgU2l6ZSAmJiAiaWR4IG91dCBvZiBib3VuZHMiKTsKKyAgICAgIHJldHVybiBMSVVzW2lkeF07CisgICAgfQorCisgICAgY29uc3QgTGl2ZUludGVydmFsVW5pb24mIG9wZXJhdG9yW10odW5zaWduZWQgSWR4KSBjb25zdCB7CisgICAgICBhc3NlcnQoSWR4IDwgU2l6ZSAmJiAiSWR4IG91dCBvZiBib3VuZHMiKTsKKyAgICAgIHJldHVybiBMSVVzW0lkeF07CisgICAgfQorICB9OworfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9MSVZFSU5URVJWQUxVTklPTl9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGl2ZUludGVydmFscy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xpdmVJbnRlcnZhbHMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMTUwZjNjCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xpdmVJbnRlcnZhbHMuaApAQCAtMCwwICsxLDQ4MSBAQAorLy89PT0tIExpdmVJbnRlcnZhbHMuaCAtIExpdmUgSW50ZXJ2YWwgQW5hbHlzaXMgLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLy8gXGZpbGUgVGhpcyBmaWxlIGltcGxlbWVudHMgdGhlIExpdmVJbnRlcnZhbCBhbmFseXNpcyBwYXNzLiAgR2l2ZW4gc29tZQorLy8vIG51bWJlcmluZyBvZiBlYWNoIHRoZSBtYWNoaW5lIGluc3RydWN0aW9ucyAoaW4gdGhpcyBpbXBsZW1lbnRpb24gZGVwdGgtZmlyc3QKKy8vLyBvcmRlcikgYW4gaW50ZXJ2YWwgW2ksIGopIGlzIHNhaWQgdG8gYmUgYSBsaXZlIGludGVydmFsIGZvciByZWdpc3RlciB2IGlmCisvLy8gdGhlcmUgaXMgbm8gaW5zdHJ1Y3Rpb24gd2l0aCBudW1iZXIgaicgPiBqIHN1Y2ggdGhhdCB2IGlzIGxpdmUgYXQgaicgYW5kCisvLy8gdGhlcmUgaXMgbm8gaW5zdHJ1Y3Rpb24gd2l0aCBudW1iZXIgaScgPCBpIHN1Y2ggdGhhdCB2IGlzIGxpdmUgYXQgaScuIEluCisvLy8gdGhpcyBpbXBsZW1lbnRhdGlvbiBpbnRlcnZhbHMgY2FuIGhhdmUgaG9sZXMsIGkuZS4gYW4gaW50ZXJ2YWwgbWlnaHQgbG9vaworLy8vIGxpa2UgWzEsMjApLCBbNTAsNjUpLCBbMTAwMCwxMDAxKS4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9MSVZFSU5URVJWQUxTX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0xJVkVJTlRFUlZBTFNfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvQXJyYXlSZWYuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9JbmRleGVkTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FuYWx5c2lzL0FsaWFzQW5hbHlzaXMuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTGl2ZUludGVydmFsLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVCYXNpY0Jsb2NrLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvblBhc3MuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2xvdEluZGV4ZXMuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0UmVnaXN0ZXJJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9NQy9MYW5lQml0bWFzay5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9Db21tYW5kTGluZS5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9Db21waWxlci5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9FcnJvckhhbmRsaW5nLmgiCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPHV0aWxpdHk+CisKK25hbWVzcGFjZSBsbHZtIHsKKworZXh0ZXJuIGNsOjpvcHQ8Ym9vbD4gVXNlU2VnbWVudFNldEZvclBoeXNSZWdzOworCitjbGFzcyBCaXRWZWN0b3I7CitjbGFzcyBMaXZlUmFuZ2VDYWxjOworY2xhc3MgTWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mbzsKK2NsYXNzIE1hY2hpbmVEb21pbmF0b3JUcmVlOworY2xhc3MgTWFjaGluZUZ1bmN0aW9uOworY2xhc3MgTWFjaGluZUluc3RyOworY2xhc3MgTWFjaGluZVJlZ2lzdGVySW5mbzsKK2NsYXNzIHJhd19vc3RyZWFtOworY2xhc3MgVGFyZ2V0SW5zdHJJbmZvOworY2xhc3MgVmlydFJlZ01hcDsKKworICBjbGFzcyBMaXZlSW50ZXJ2YWxzIDogcHVibGljIE1hY2hpbmVGdW5jdGlvblBhc3MgeworICAgIE1hY2hpbmVGdW5jdGlvbiogTUY7CisgICAgTWFjaGluZVJlZ2lzdGVySW5mbyogTVJJOworICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyogVFJJOworICAgIGNvbnN0IFRhcmdldEluc3RySW5mbyogVElJOworICAgIEFsaWFzQW5hbHlzaXMgKkFBOworICAgIFNsb3RJbmRleGVzKiBJbmRleGVzOworICAgIE1hY2hpbmVEb21pbmF0b3JUcmVlICpEb21UcmVlID0gbnVsbHB0cjsKKyAgICBMaXZlUmFuZ2VDYWxjICpMUkNhbGMgPSBudWxscHRyOworCisgICAgLy8vIFNwZWNpYWwgcG9vbCBhbGxvY2F0b3IgZm9yIFZOSW5mbydzIChMaXZlSW50ZXJ2YWwgdmFsIykuCisgICAgVk5JbmZvOjpBbGxvY2F0b3IgVk5JbmZvQWxsb2NhdG9yOworCisgICAgLy8vIExpdmUgaW50ZXJ2YWwgcG9pbnRlcnMgZm9yIGFsbCB0aGUgdmlydHVhbCByZWdpc3RlcnMuCisgICAgSW5kZXhlZE1hcDxMaXZlSW50ZXJ2YWwqLCBWaXJ0UmVnMkluZGV4RnVuY3Rvcj4gVmlydFJlZ0ludGVydmFsczsKKworICAgIC8vLyBTb3J0ZWQgbGlzdCBvZiBpbnN0cnVjdGlvbnMgd2l0aCByZWdpc3RlciBtYXNrIG9wZXJhbmRzLiBBbHdheXMgdXNlIHRoZQorICAgIC8vLyAncicgc2xvdCwgUmVnTWFza3MgYXJlIG5vcm1hbCBjbG9iYmVycywgbm90IGVhcmx5IGNsb2JiZXJzLgorICAgIFNtYWxsVmVjdG9yPFNsb3RJbmRleCwgOD4gUmVnTWFza1Nsb3RzOworCisgICAgLy8vIFRoaXMgdmVjdG9yIGlzIHBhcmFsbGVsIHRvIFJlZ01hc2tTbG90cywgaXQgaG9sZHMgYSBwb2ludGVyIHRvIHRoZQorICAgIC8vLyBjb3JyZXNwb25kaW5nIHJlZ2lzdGVyIG1hc2suICBUaGlzIHBvaW50ZXIgY2FuIGJlIHJlY29tcHV0ZWQgYXM6CisgICAgLy8vCisgICAgLy8vICAgTUkgPSBJbmRleGVzLT5nZXRJbnN0cnVjdGlvbkZyb21JbmRleChSZWdNYXNrU2xvdFtOXSk7CisgICAgLy8vICAgdW5zaWduZWQgT3BOdW0gPSBmaW5kUmVnTWFza09wZXJhbmQoTUkpOworICAgIC8vLyAgIFJlZ01hc2tCaXRzW05dID0gTUktPmdldE9wZXJhbmQoT3BOdW0pLmdldFJlZ01hc2soKTsKKyAgICAvLy8KKyAgICAvLy8gVGhpcyBpcyBrZXB0IGluIGEgc2VwYXJhdGUgdmVjdG9yIHBhcnRseSBiZWNhdXNlIHNvbWUgc3RhbmRhcmQKKyAgICAvLy8gbGlicmFyaWVzIGRvbid0IHN1cHBvcnQgbG93ZXJfYm91bmQoKSB3aXRoIG1peGVkIG9iamVjdHMsIHBhcnRseSB0bworICAgIC8vLyBpbXByb3ZlIGxvY2FsaXR5IHdoZW4gc2VhcmNoaW5nIGluIFJlZ01hc2tTbG90cy4KKyAgICAvLy8gQWxzbyBzZWUgdGhlIGNvbW1lbnQgaW4gTGl2ZUludGVydmFsOjpmaW5kKCkuCisgICAgU21hbGxWZWN0b3I8Y29uc3QgdWludDMyX3QqLCA4PiBSZWdNYXNrQml0czsKKworICAgIC8vLyBGb3IgZWFjaCBiYXNpYyBibG9jayBudW1iZXIsIGtlZXAgKGJlZ2luLCBzaXplKSBwYWlycyBpbmRleGluZyBpbnRvIHRoZQorICAgIC8vLyBSZWdNYXNrU2xvdHMgYW5kIFJlZ01hc2tCaXRzIGFycmF5cy4KKyAgICAvLy8gTm90ZSB0aGF0IGJhc2ljIGJsb2NrIG51bWJlcnMgbWF5IG5vdCBiZSBsYXlvdXQgY29udGlndW91cywgdGhhdCdzIHdoeQorICAgIC8vLyB3ZSBjYW4ndCBqdXN0IGtlZXAgdHJhY2sgb2YgdGhlIGZpcnN0IHJlZ2lzdGVyIG1hc2sgaW4gZWFjaCBiYXNpYworICAgIC8vLyBibG9jay4KKyAgICBTbWFsbFZlY3RvcjxzdGQ6OnBhaXI8dW5zaWduZWQsIHVuc2lnbmVkPiwgOD4gUmVnTWFza0Jsb2NrczsKKworICAgIC8vLyBLZWVwcyBhIGxpdmUgcmFuZ2Ugc2V0IGZvciBlYWNoIHJlZ2lzdGVyIHVuaXQgdG8gdHJhY2sgZml4ZWQgcGh5c3JlZworICAgIC8vLyBpbnRlcmZlcmVuY2UuCisgICAgU21hbGxWZWN0b3I8TGl2ZVJhbmdlKiwgMD4gUmVnVW5pdFJhbmdlczsKKworICBwdWJsaWM6CisgICAgc3RhdGljIGNoYXIgSUQ7CisKKyAgICBMaXZlSW50ZXJ2YWxzKCk7CisgICAgfkxpdmVJbnRlcnZhbHMoKSBvdmVycmlkZTsKKworICAgIC8vLyBDYWxjdWxhdGUgdGhlIHNwaWxsIHdlaWdodCB0byBhc3NpZ24gdG8gYSBzaW5nbGUgaW5zdHJ1Y3Rpb24uCisgICAgc3RhdGljIGZsb2F0IGdldFNwaWxsV2VpZ2h0KGJvb2wgaXNEZWYsIGJvb2wgaXNVc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm8gKk1CRkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ciAmSW5zdHIpOworCisgICAgLy8vIENhbGN1bGF0ZSB0aGUgc3BpbGwgd2VpZ2h0IHRvIGFzc2lnbiB0byBhIHNpbmdsZSBpbnN0cnVjdGlvbi4KKyAgICBzdGF0aWMgZmxvYXQgZ2V0U3BpbGxXZWlnaHQoYm9vbCBpc0RlZiwgYm9vbCBpc1VzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mbyAqTUJGSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKk1CQik7CisKKyAgICBMaXZlSW50ZXJ2YWwgJmdldEludGVydmFsKHVuc2lnbmVkIFJlZykgeworICAgICAgaWYgKGhhc0ludGVydmFsKFJlZykpCisgICAgICAgIHJldHVybiAqVmlydFJlZ0ludGVydmFsc1tSZWddOworICAgICAgZWxzZQorICAgICAgICByZXR1cm4gY3JlYXRlQW5kQ29tcHV0ZVZpcnRSZWdJbnRlcnZhbChSZWcpOworICAgIH0KKworICAgIGNvbnN0IExpdmVJbnRlcnZhbCAmZ2V0SW50ZXJ2YWwodW5zaWduZWQgUmVnKSBjb25zdCB7CisgICAgICByZXR1cm4gY29uc3RfY2FzdDxMaXZlSW50ZXJ2YWxzKj4odGhpcyktPmdldEludGVydmFsKFJlZyk7CisgICAgfQorCisgICAgYm9vbCBoYXNJbnRlcnZhbCh1bnNpZ25lZCBSZWcpIGNvbnN0IHsKKyAgICAgIHJldHVybiBWaXJ0UmVnSW50ZXJ2YWxzLmluQm91bmRzKFJlZykgJiYgVmlydFJlZ0ludGVydmFsc1tSZWddOworICAgIH0KKworICAgIC8vLyBJbnRlcnZhbCBjcmVhdGlvbi4KKyAgICBMaXZlSW50ZXJ2YWwgJmNyZWF0ZUVtcHR5SW50ZXJ2YWwodW5zaWduZWQgUmVnKSB7CisgICAgICBhc3NlcnQoIWhhc0ludGVydmFsKFJlZykgJiYgIkludGVydmFsIGFscmVhZHkgZXhpc3RzISIpOworICAgICAgVmlydFJlZ0ludGVydmFscy5ncm93KFJlZyk7CisgICAgICBWaXJ0UmVnSW50ZXJ2YWxzW1JlZ10gPSBjcmVhdGVJbnRlcnZhbChSZWcpOworICAgICAgcmV0dXJuICpWaXJ0UmVnSW50ZXJ2YWxzW1JlZ107CisgICAgfQorCisgICAgTGl2ZUludGVydmFsICZjcmVhdGVBbmRDb21wdXRlVmlydFJlZ0ludGVydmFsKHVuc2lnbmVkIFJlZykgeworICAgICAgTGl2ZUludGVydmFsICZMSSA9IGNyZWF0ZUVtcHR5SW50ZXJ2YWwoUmVnKTsKKyAgICAgIGNvbXB1dGVWaXJ0UmVnSW50ZXJ2YWwoTEkpOworICAgICAgcmV0dXJuIExJOworICAgIH0KKworICAgIC8vLyBJbnRlcnZhbCByZW1vdmFsLgorICAgIHZvaWQgcmVtb3ZlSW50ZXJ2YWwodW5zaWduZWQgUmVnKSB7CisgICAgICBkZWxldGUgVmlydFJlZ0ludGVydmFsc1tSZWddOworICAgICAgVmlydFJlZ0ludGVydmFsc1tSZWddID0gbnVsbHB0cjsKKyAgICB9CisKKyAgICAvLy8gR2l2ZW4gYSByZWdpc3RlciBhbmQgYW4gaW5zdHJ1Y3Rpb24sIGFkZHMgYSBsaXZlIHNlZ21lbnQgZnJvbSB0aGF0CisgICAgLy8vIGluc3RydWN0aW9uIHRvIHRoZSBlbmQgb2YgaXRzIE1CQi4KKyAgICBMaXZlSW50ZXJ2YWw6OlNlZ21lbnQgYWRkU2VnbWVudFRvRW5kT2ZCbG9jayh1bnNpZ25lZCByZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUluc3RyICZzdGFydEluc3QpOworCisgICAgLy8vIEFmdGVyIHJlbW92aW5nIHNvbWUgdXNlcyBvZiBhIHJlZ2lzdGVyLCBzaHJpbmsgaXRzIGxpdmUgcmFuZ2UgdG8ganVzdAorICAgIC8vLyB0aGUgcmVtYWluaW5nIHVzZXMuIFRoaXMgbWV0aG9kIGRvZXMgbm90IGNvbXB1dGUgcmVhY2hpbmcgZGVmcyBmb3IgbmV3CisgICAgLy8vIHVzZXMsIGFuZCBpdCBkb2Vzbid0IHJlbW92ZSBkZWFkIGRlZnMuCisgICAgLy8vIERlYWQgUEhJRGVmIHZhbHVlcyBhcmUgbWFya2VkIGFzIHVudXNlZC4gTmV3IGRlYWQgbWFjaGluZSBpbnN0cnVjdGlvbnMKKyAgICAvLy8gYXJlIGFkZGVkIHRvIHRoZSBkZWFkIHZlY3Rvci4gUmV0dXJucyB0cnVlIGlmIHRoZSBpbnRlcnZhbCBtYXkgaGF2ZSBiZWVuCisgICAgLy8vIHNlcGFyYXRlZCBpbnRvIG11bHRpcGxlIGNvbm5lY3RlZCBjb21wb25lbnRzLgorICAgIGJvb2wgc2hyaW5rVG9Vc2VzKExpdmVJbnRlcnZhbCAqbGksCisgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVJbnN0cio+ICpkZWFkID0gbnVsbHB0cik7CisKKyAgICAvLy8gU3BlY2lhbGl6ZWQgdmVyc2lvbiBvZgorICAgIC8vLyBzaHJpbmtUb1VzZXMoTGl2ZUludGVydmFsICpsaSwgU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVJbnN0cio+ICpkZWFkKQorICAgIC8vLyB0aGF0IHdvcmtzIG9uIGEgc3VicmVnaXN0ZXIgbGl2ZSByYW5nZSBhbmQgb25seSBsb29rcyBhdCB1c2VzIG1hdGNoaW5nCisgICAgLy8vIHRoZSBsYW5lIG1hc2sgb2YgdGhlIHN1YnJlZ2lzdGVyIHJhbmdlLgorICAgIC8vLyBUaGlzIG1heSBsZWF2ZSB0aGUgc3VicmFuZ2UgZW1wdHkgd2hpY2ggbmVlZHMgdG8gYmUgY2xlYW5lZCB1cCB3aXRoCisgICAgLy8vIExpdmVJbnRlcnZhbDo6cmVtb3ZlRW1wdHlTdWJyYW5nZXMoKSBhZnRlcndhcmRzLgorICAgIHZvaWQgc2hyaW5rVG9Vc2VzKExpdmVJbnRlcnZhbDo6U3ViUmFuZ2UgJlNSLCB1bnNpZ25lZCBSZWcpOworCisgICAgLy8vIEV4dGVuZCB0aGUgbGl2ZSByYW5nZSBccCBMUiB0byByZWFjaCBhbGwgcG9pbnRzIGluIFxwIEluZGljZXMuIFRoZQorICAgIC8vLyBwb2ludHMgaW4gdGhlIFxwIEluZGljZXMgYXJyYXkgbXVzdCBiZSBqb2ludGx5IGRvbWluYXRlZCBieSB0aGUgdW5pb24KKyAgICAvLy8gb2YgdGhlIGV4aXN0aW5nIGRlZnMgaW4gXHAgTFIgYW5kIHBvaW50cyBpbiBccCBVbmRlZnMuCisgICAgLy8vCisgICAgLy8vIFBISS1kZWZzIGFyZSBhZGRlZCBhcyBuZWVkZWQgdG8gbWFpbnRhaW4gU1NBIGZvcm0uCisgICAgLy8vCisgICAgLy8vIElmIGEgU2xvdEluZGV4IGluIFxwIEluZGljZXMgaXMgdGhlIGVuZCBpbmRleCBvZiBhIGJhc2ljIGJsb2NrLCBccCBMUgorICAgIC8vLyB3aWxsIGJlIGV4dGVuZGVkIHRvIGJlIGxpdmUgb3V0IG9mIHRoZSBiYXNpYyBibG9jay4KKyAgICAvLy8gSWYgYSBTbG90SW5kZXggaW4gXHAgSW5kaWNlcyBpcyBqb2ludHkgZG9taW5hdGVkIG9ubHkgYnkgcG9pbnRzIGluCisgICAgLy8vIFxwIFVuZGVmcywgdGhlIGxpdmUgcmFuZ2Ugd2lsbCBub3QgYmUgZXh0ZW5kZWQgdG8gdGhhdCBwb2ludC4KKyAgICAvLy8KKyAgICAvLy8gU2VlIGFsc28gTGl2ZVJhbmdlQ2FsYzo6ZXh0ZW5kKCkuCisgICAgdm9pZCBleHRlbmRUb0luZGljZXMoTGl2ZVJhbmdlICZMUiwgQXJyYXlSZWY8U2xvdEluZGV4PiBJbmRpY2VzLAorICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFNsb3RJbmRleD4gVW5kZWZzKTsKKworICAgIHZvaWQgZXh0ZW5kVG9JbmRpY2VzKExpdmVSYW5nZSAmTFIsIEFycmF5UmVmPFNsb3RJbmRleD4gSW5kaWNlcykgeworICAgICAgZXh0ZW5kVG9JbmRpY2VzKExSLCBJbmRpY2VzLCAvKlVuZGVmcz0qL3t9KTsKKyAgICB9CisKKyAgICAvLy8gSWYgXHAgTFIgaGFzIGEgbGl2ZSB2YWx1ZSBhdCBccCBLaWxsLCBwcnVuZSBpdHMgbGl2ZSByYW5nZSBieSByZW1vdmluZworICAgIC8vLyBhbnkgbGl2ZW5lc3MgcmVhY2hhYmxlIGZyb20gS2lsbC4gQWRkIGxpdmUgcmFuZ2UgZW5kIHBvaW50cyB0bworICAgIC8vLyBFbmRQb2ludHMgc3VjaCB0aGF0IGV4dGVuZFRvSW5kaWNlcyhMSSwgRW5kUG9pbnRzKSB3aWxsIHJlY29uc3RydWN0IHRoZQorICAgIC8vLyB2YWx1ZSdzIGxpdmUgcmFuZ2UuCisgICAgLy8vCisgICAgLy8vIENhbGxpbmcgcHJ1bmVWYWx1ZSgpIGFuZCBleHRlbmRUb0luZGljZXMoKSBjYW4gYmUgdXNlZCB0byByZWNvbnN0cnVjdAorICAgIC8vLyBTU0EgZm9ybSBhZnRlciBhZGRpbmcgZGVmcyB0byBhIHZpcnR1YWwgcmVnaXN0ZXIuCisgICAgdm9pZCBwcnVuZVZhbHVlKExpdmVSYW5nZSAmTFIsIFNsb3RJbmRleCBLaWxsLAorICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8U2xvdEluZGV4PiAqRW5kUG9pbnRzKTsKKworICAgIC8vLyBUaGlzIGZ1bmN0aW9uIHNob3VsZCBub3QgYmUgdXNlZC4gSXRzIGludGVuZCBpcyB0byB0ZWxsIHlvdSB0aGF0CisgICAgLy8vIHlvdSBhcmUgZG9pbmcgc29tZXRoaW5nIHdyb25nIGlmIHlvdSBjYWxsIHBydXZlVmFsdWUgZGlyZWN0bHkgb24gYQorICAgIC8vLyBMaXZlSW50ZXJ2YWwuIEluZGVlZCwgeW91IGFyZSBzdXBwb3NlZCB0byBjYWxsIHBydW5lVmFsdWUgb24gdGhlIG1haW4KKyAgICAvLy8gTGl2ZVJhbmdlIGFuZCBhbGwgdGhlIExpdmVSYW5nZSBvZiB0aGUgc3VicmFuZ2VzIGlmIGFueS4KKyAgICBMTFZNX0FUVFJJQlVURV9VTlVTRUQgdm9pZCBwcnVuZVZhbHVlKExpdmVJbnRlcnZhbCAmLCBTbG90SW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8U2xvdEluZGV4PiAqKSB7CisgICAgICBsbHZtX3VucmVhY2hhYmxlKAorICAgICAgICAgICJVc2UgcHJ1bmVWYWx1ZSBvbiB0aGUgbWFpbiBMaXZlUmFuZ2UgYW5kIG9uIGVhY2ggc3VicmFuZ2UiKTsKKyAgICB9CisKKyAgICBTbG90SW5kZXhlcyAqZ2V0U2xvdEluZGV4ZXMoKSBjb25zdCB7CisgICAgICByZXR1cm4gSW5kZXhlczsKKyAgICB9CisKKyAgICBBbGlhc0FuYWx5c2lzICpnZXRBbGlhc0FuYWx5c2lzKCkgY29uc3QgeworICAgICAgcmV0dXJuIEFBOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBtYWNoaW5lIGluc3RyIGhhcyBiZWVuIHJlbW92ZWQgb3Igd2FzCisgICAgLy8vIG5ldmVyIGVudGVyZWQgaW4gdGhlIG1hcC4KKyAgICBib29sIGlzTm90SW5NSU1hcChjb25zdCBNYWNoaW5lSW5zdHIgJkluc3RyKSBjb25zdCB7CisgICAgICByZXR1cm4gIUluZGV4ZXMtPmhhc0luZGV4KEluc3RyKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0aGUgYmFzZSBpbmRleCBvZiB0aGUgZ2l2ZW4gaW5zdHJ1Y3Rpb24uCisgICAgU2xvdEluZGV4IGdldEluc3RydWN0aW9uSW5kZXgoY29uc3QgTWFjaGluZUluc3RyICZJbnN0cikgY29uc3QgeworICAgICAgcmV0dXJuIEluZGV4ZXMtPmdldEluc3RydWN0aW9uSW5kZXgoSW5zdHIpOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRoZSBpbnN0cnVjdGlvbiBhc3NvY2lhdGVkIHdpdGggdGhlIGdpdmVuIGluZGV4LgorICAgIE1hY2hpbmVJbnN0ciogZ2V0SW5zdHJ1Y3Rpb25Gcm9tSW5kZXgoU2xvdEluZGV4IGluZGV4KSBjb25zdCB7CisgICAgICByZXR1cm4gSW5kZXhlcy0+Z2V0SW5zdHJ1Y3Rpb25Gcm9tSW5kZXgoaW5kZXgpOworICAgIH0KKworICAgIC8vLyBSZXR1cm4gdGhlIGZpcnN0IGluZGV4IGluIHRoZSBnaXZlbiBiYXNpYyBibG9jay4KKyAgICBTbG90SW5kZXggZ2V0TUJCU3RhcnRJZHgoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKm1iYikgY29uc3QgeworICAgICAgcmV0dXJuIEluZGV4ZXMtPmdldE1CQlN0YXJ0SWR4KG1iYik7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0aGUgbGFzdCBpbmRleCBpbiB0aGUgZ2l2ZW4gYmFzaWMgYmxvY2suCisgICAgU2xvdEluZGV4IGdldE1CQkVuZElkeChjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqbWJiKSBjb25zdCB7CisgICAgICByZXR1cm4gSW5kZXhlcy0+Z2V0TUJCRW5kSWR4KG1iYik7CisgICAgfQorCisgICAgYm9vbCBpc0xpdmVJblRvTUJCKGNvbnN0IExpdmVSYW5nZSAmTFIsCisgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICptYmIpIGNvbnN0IHsKKyAgICAgIHJldHVybiBMUi5saXZlQXQoZ2V0TUJCU3RhcnRJZHgobWJiKSk7CisgICAgfQorCisgICAgYm9vbCBpc0xpdmVPdXRPZk1CQihjb25zdCBMaXZlUmFuZ2UgJkxSLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKm1iYikgY29uc3QgeworICAgICAgcmV0dXJuIExSLmxpdmVBdChnZXRNQkJFbmRJZHgobWJiKS5nZXRQcmV2U2xvdCgpKTsKKyAgICB9CisKKyAgICBNYWNoaW5lQmFzaWNCbG9jayogZ2V0TUJCRnJvbUluZGV4KFNsb3RJbmRleCBpbmRleCkgY29uc3QgeworICAgICAgcmV0dXJuIEluZGV4ZXMtPmdldE1CQkZyb21JbmRleChpbmRleCk7CisgICAgfQorCisgICAgdm9pZCBpbnNlcnRNQkJJbk1hcHMoTWFjaGluZUJhc2ljQmxvY2sgKk1CQikgeworICAgICAgSW5kZXhlcy0+aW5zZXJ0TUJCSW5NYXBzKE1CQik7CisgICAgICBhc3NlcnQodW5zaWduZWQoTUJCLT5nZXROdW1iZXIoKSkgPT0gUmVnTWFza0Jsb2Nrcy5zaXplKCkgJiYKKyAgICAgICAgICAgICAiQmxvY2tzIG11c3QgYmUgYWRkZWQgaW4gb3JkZXIuIik7CisgICAgICBSZWdNYXNrQmxvY2tzLnB1c2hfYmFjayhzdGQ6Om1ha2VfcGFpcihSZWdNYXNrU2xvdHMuc2l6ZSgpLCAwKSk7CisgICAgfQorCisgICAgU2xvdEluZGV4IEluc2VydE1hY2hpbmVJbnN0ckluTWFwcyhNYWNoaW5lSW5zdHIgJk1JKSB7CisgICAgICByZXR1cm4gSW5kZXhlcy0+aW5zZXJ0TWFjaGluZUluc3RySW5NYXBzKE1JKTsKKyAgICB9CisKKyAgICB2b2lkIEluc2VydE1hY2hpbmVJbnN0clJhbmdlSW5NYXBzKE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEUpIHsKKyAgICAgIGZvciAoTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEkgPSBCOyBJICE9IEU7ICsrSSkKKyAgICAgICAgSW5kZXhlcy0+aW5zZXJ0TWFjaGluZUluc3RySW5NYXBzKCpJKTsKKyAgICB9CisKKyAgICB2b2lkIFJlbW92ZU1hY2hpbmVJbnN0ckZyb21NYXBzKE1hY2hpbmVJbnN0ciAmTUkpIHsKKyAgICAgIEluZGV4ZXMtPnJlbW92ZU1hY2hpbmVJbnN0ckZyb21NYXBzKE1JKTsKKyAgICB9CisKKyAgICBTbG90SW5kZXggUmVwbGFjZU1hY2hpbmVJbnN0ckluTWFwcyhNYWNoaW5lSW5zdHIgJk1JLCBNYWNoaW5lSW5zdHIgJk5ld01JKSB7CisgICAgICByZXR1cm4gSW5kZXhlcy0+cmVwbGFjZU1hY2hpbmVJbnN0ckluTWFwcyhNSSwgTmV3TUkpOworICAgIH0KKworICAgIFZOSW5mbzo6QWxsb2NhdG9yJiBnZXRWTkluZm9BbGxvY2F0b3IoKSB7IHJldHVybiBWTkluZm9BbGxvY2F0b3I7IH0KKworICAgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlICZBVSkgY29uc3Qgb3ZlcnJpZGU7CisgICAgdm9pZCByZWxlYXNlTWVtb3J5KCkgb3ZlcnJpZGU7CisKKyAgICAvLy8gUGFzcyBlbnRyeSBwb2ludDsgQ2FsY3VsYXRlcyBMaXZlSW50ZXJ2YWxzLgorICAgIGJvb2wgcnVuT25NYWNoaW5lRnVuY3Rpb24oTWFjaGluZUZ1bmN0aW9uJikgb3ZlcnJpZGU7CisKKyAgICAvLy8gSW1wbGVtZW50IHRoZSBkdW1wIG1ldGhvZC4KKyAgICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPLCBjb25zdCBNb2R1bGUqID0gbnVsbHB0cikgY29uc3Qgb3ZlcnJpZGU7CisKKyAgICAvLy8gSWYgTEkgaXMgY29uZmluZWQgdG8gYSBzaW5nbGUgYmFzaWMgYmxvY2ssIHJldHVybiBhIHBvaW50ZXIgdG8gdGhhdAorICAgIC8vLyBibG9jay4gIElmIExJIGlzIGxpdmUgaW4gdG8gb3Igb3V0IG9mIGFueSBibG9jaywgcmV0dXJuIE5VTEwuCisgICAgTWFjaGluZUJhc2ljQmxvY2sgKmludGVydmFsSXNJbk9uZU1CQihjb25zdCBMaXZlSW50ZXJ2YWwgJkxJKSBjb25zdDsKKworICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgVk5JIGlzIGtpbGxlZCBieSBhbnkgUEhJLWRlZiB2YWx1ZXMgaW4gTEkuCisgICAgLy8vIFRoaXMgbWF5IGNvbnNlcnZhdGl2ZWx5IHJldHVybiB0cnVlIHRvIGF2b2lkIGV4cGVuc2l2ZSBjb21wdXRhdGlvbnMuCisgICAgYm9vbCBoYXNQSElLaWxsKGNvbnN0IExpdmVJbnRlcnZhbCAmTEksIGNvbnN0IFZOSW5mbyAqVk5JKSBjb25zdDsKKworICAgIC8vLyBBZGQga2lsbCBmbGFncyB0byBhbnkgaW5zdHJ1Y3Rpb24gdGhhdCBraWxscyBhIHZpcnR1YWwgcmVnaXN0ZXIuCisgICAgdm9pZCBhZGRLaWxsRmxhZ3MoY29uc3QgVmlydFJlZ01hcCopOworCisgICAgLy8vIENhbGwgdGhpcyBtZXRob2QgdG8gbm90aWZ5IExpdmVJbnRlcnZhbHMgdGhhdCBpbnN0cnVjdGlvbiBccCBNSSBoYXMgYmVlbgorICAgIC8vLyBtb3ZlZCB3aXRoaW4gYSBiYXNpYyBibG9jay4gVGhpcyB3aWxsIHVwZGF0ZSB0aGUgbGl2ZSBpbnRlcnZhbHMgZm9yIGFsbAorICAgIC8vLyBvcGVyYW5kcyBvZiBccCBNSS4gTW92ZXMgYmV0d2VlbiBiYXNpYyBibG9ja3MgYXJlIG5vdCBzdXBwb3J0ZWQuCisgICAgLy8vCisgICAgLy8vIFxwYXJhbSBVcGRhdGVGbGFncyBVcGRhdGUgbGl2ZSBpbnRlcnZhbHMgZm9yIG5vbmFsbG9jYXRhYmxlIHBoeXNyZWdzLgorICAgIHZvaWQgaGFuZGxlTW92ZShNYWNoaW5lSW5zdHIgJk1JLCBib29sIFVwZGF0ZUZsYWdzID0gZmFsc2UpOworCisgICAgLy8vIFVwZGF0ZSBpbnRlcnZhbHMgZm9yIG9wZXJhbmRzIG9mIFxwIE1JIHNvIHRoYXQgdGhleSBiZWdpbi9lbmQgb24gdGhlCisgICAgLy8vIFNsb3RJbmRleCBmb3IgXHAgQnVuZGxlU3RhcnQuCisgICAgLy8vCisgICAgLy8vIFxwYXJhbSBVcGRhdGVGbGFncyBVcGRhdGUgbGl2ZSBpbnRlcnZhbHMgZm9yIG5vbmFsbG9jYXRhYmxlIHBoeXNyZWdzLgorICAgIC8vLworICAgIC8vLyBSZXF1aXJlcyBNSSBhbmQgQnVuZGxlU3RhcnQgdG8gaGF2ZSBTbG90SW5kZXhlcywgYW5kIGFzc3VtZXMKKyAgICAvLy8gZXhpc3RpbmcgbGl2ZW5lc3MgaXMgYWNjdXJhdGUuIEJ1bmRsZVN0YXJ0IHNob3VsZCBiZSB0aGUgZmlyc3QKKyAgICAvLy8gaW5zdHJ1Y3Rpb24gaW4gdGhlIEJ1bmRsZS4KKyAgICB2b2lkIGhhbmRsZU1vdmVJbnRvQnVuZGxlKE1hY2hpbmVJbnN0ciAmTUksIE1hY2hpbmVJbnN0ciAmQnVuZGxlU3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIFVwZGF0ZUZsYWdzID0gZmFsc2UpOworCisgICAgLy8vIFVwZGF0ZSBsaXZlIGludGVydmFscyBmb3IgaW5zdHJ1Y3Rpb25zIGluIGEgcmFuZ2Ugb2YgaXRlcmF0b3JzLiBJdCBpcworICAgIC8vLyBpbnRlbmRlZCBmb3IgdXNlIGFmdGVyIHRhcmdldCBob29rcyB0aGF0IG1heSBpbnNlcnQgb3IgcmVtb3ZlCisgICAgLy8vIGluc3RydWN0aW9ucywgYW5kIGlzIG9ubHkgZWZmaWNpZW50IGZvciBhIHNtYWxsIG51bWJlciBvZiBpbnN0cnVjdGlvbnMuCisgICAgLy8vCisgICAgLy8vIE9yaWdSZWdzIGlzIGEgdmVjdG9yIG9mIHJlZ2lzdGVycyB0aGF0IHdlcmUgb3JpZ2luYWxseSB1c2VkIGJ5IHRoZQorICAgIC8vLyBpbnN0cnVjdGlvbnMgaW4gdGhlIHJhbmdlIGJldHdlZW4gdGhlIHR3byBpdGVyYXRvcnMuCisgICAgLy8vCisgICAgLy8vIEN1cnJlbnRseSwgdGhlIG9ubHkgb25seSBjaGFuZ2VzIHRoYXQgYXJlIHN1cHBvcnRlZCBhcmUgc2ltcGxlIHJlbW92YWwKKyAgICAvLy8gYW5kIGFkZGl0aW9uIG9mIHVzZXMuCisgICAgdm9pZCByZXBhaXJJbnRlcnZhbHNJblJhbmdlKE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBCZWdpbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEVuZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8dW5zaWduZWQ+IE9yaWdSZWdzKTsKKworICAgIC8vIFJlZ2lzdGVyIG1hc2sgZnVuY3Rpb25zLgorICAgIC8vCisgICAgLy8gTWFjaGluZSBpbnN0cnVjdGlvbnMgbWF5IHVzZSBhIHJlZ2lzdGVyIG1hc2sgb3BlcmFuZCB0byBpbmRpY2F0ZSB0aGF0IGEKKyAgICAvLyBsYXJnZSBudW1iZXIgb2YgcmVnaXN0ZXJzIGFyZSBjbG9iYmVyZWQgYnkgdGhlIGluc3RydWN0aW9uLiAgVGhpcyBpcworICAgIC8vIHR5cGljYWxseSB1c2VkIGZvciBjYWxscy4KKyAgICAvLworICAgIC8vIEZvciBjb21waWxlIHRpbWUgcGVyZm9ybWFuY2UgcmVhc29ucywgdGhlc2UgY2xvYmJlcnMgYXJlIG5vdCByZWNvcmRlZCBpbgorICAgIC8vIHRoZSBsaXZlIGludGVydmFscyBmb3IgaW5kaXZpZHVhbCBwaHlzaWNhbCByZWdpc3RlcnMuICBJbnN0ZWFkLAorICAgIC8vIExpdmVJbnRlcnZhbEFuYWx5c2lzIG1haW50YWlucyBhIHNvcnRlZCBsaXN0IG9mIGluc3RydWN0aW9ucyB3aXRoCisgICAgLy8gcmVnaXN0ZXIgbWFzayBvcGVyYW5kcy4KKworICAgIC8vLyBSZXR1cm5zIGEgc29ydGVkIGFycmF5IG9mIHNsb3QgaW5kaWNlcyBvZiBhbGwgaW5zdHJ1Y3Rpb25zIHdpdGgKKyAgICAvLy8gcmVnaXN0ZXIgbWFzayBvcGVyYW5kcy4KKyAgICBBcnJheVJlZjxTbG90SW5kZXg+IGdldFJlZ01hc2tTbG90cygpIGNvbnN0IHsgcmV0dXJuIFJlZ01hc2tTbG90czsgfQorCisgICAgLy8vIFJldHVybnMgYSBzb3J0ZWQgYXJyYXkgb2Ygc2xvdCBpbmRpY2VzIG9mIGFsbCBpbnN0cnVjdGlvbnMgd2l0aCByZWdpc3RlcgorICAgIC8vLyBtYXNrIG9wZXJhbmRzIGluIHRoZSBiYXNpYyBibG9jayBudW1iZXJlZCBccCBNQkJOdW0uCisgICAgQXJyYXlSZWY8U2xvdEluZGV4PiBnZXRSZWdNYXNrU2xvdHNJbkJsb2NrKHVuc2lnbmVkIE1CQk51bSkgY29uc3QgeworICAgICAgc3RkOjpwYWlyPHVuc2lnbmVkLCB1bnNpZ25lZD4gUCA9IFJlZ01hc2tCbG9ja3NbTUJCTnVtXTsKKyAgICAgIHJldHVybiBnZXRSZWdNYXNrU2xvdHMoKS5zbGljZShQLmZpcnN0LCBQLnNlY29uZCk7CisgICAgfQorCisgICAgLy8vIFJldHVybnMgYW4gYXJyYXkgb2YgcmVnaXN0ZXIgbWFzayBwb2ludGVycyBjb3JyZXNwb25kaW5nIHRvCisgICAgLy8vIGdldFJlZ01hc2tTbG90cygpLgorICAgIEFycmF5UmVmPGNvbnN0IHVpbnQzMl90Kj4gZ2V0UmVnTWFza0JpdHMoKSBjb25zdCB7IHJldHVybiBSZWdNYXNrQml0czsgfQorCisgICAgLy8vIFJldHVybnMgYW4gYXJyYXkgb2YgbWFzayBwb2ludGVycyBjb3JyZXNwb25kaW5nIHRvCisgICAgLy8vIGdldFJlZ01hc2tTbG90c0luQmxvY2soTUJCTnVtKS4KKyAgICBBcnJheVJlZjxjb25zdCB1aW50MzJfdCo+IGdldFJlZ01hc2tCaXRzSW5CbG9jayh1bnNpZ25lZCBNQkJOdW0pIGNvbnN0IHsKKyAgICAgIHN0ZDo6cGFpcjx1bnNpZ25lZCwgdW5zaWduZWQ+IFAgPSBSZWdNYXNrQmxvY2tzW01CQk51bV07CisgICAgICByZXR1cm4gZ2V0UmVnTWFza0JpdHMoKS5zbGljZShQLmZpcnN0LCBQLnNlY29uZCk7CisgICAgfQorCisgICAgLy8vIFRlc3QgaWYgXHAgTEkgaXMgbGl2ZSBhY3Jvc3MgYW55IHJlZ2lzdGVyIG1hc2sgaW5zdHJ1Y3Rpb25zLCBhbmQKKyAgICAvLy8gY29tcHV0ZSBhIGJpdCBtYXNrIG9mIHBoeXNpY2FsIHJlZ2lzdGVycyB0aGF0IGFyZSBub3QgY2xvYmJlcmVkIGJ5IGFueQorICAgIC8vLyBvZiB0aGVtLgorICAgIC8vLworICAgIC8vLyBSZXR1cm5zIGZhbHNlIGlmIFxwIExJIGRvZXNuJ3QgY3Jvc3MgYW55IHJlZ2lzdGVyIG1hc2sgaW5zdHJ1Y3Rpb25zLiBJbgorICAgIC8vLyB0aGF0IGNhc2UsIHRoZSBiaXQgdmVjdG9yIGlzIG5vdCBmaWxsZWQgaW4uCisgICAgYm9vbCBjaGVja1JlZ01hc2tJbnRlcmZlcmVuY2UoTGl2ZUludGVydmFsICZMSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaXRWZWN0b3IgJlVzYWJsZVJlZ3MpOworCisgICAgLy8gUmVnaXN0ZXIgdW5pdCBmdW5jdGlvbnMuCisgICAgLy8KKyAgICAvLyBGaXhlZCBpbnRlcmZlcmVuY2Ugb2NjdXJzIHdoZW4gTWFjaGluZUluc3RycyB1c2UgcGh5c3JlZ3MgZGlyZWN0bHkKKyAgICAvLyBpbnN0ZWFkIG9mIHZpcnR1YWwgcmVnaXN0ZXJzLiBUaGlzIHR5cGljYWxseSBoYXBwZW5zIHdoZW4gcGFzc2luZworICAgIC8vIGFyZ3VtZW50cyB0byBhIGZ1bmN0aW9uIGNhbGwsIG9yIHdoZW4gaW5zdHJ1Y3Rpb25zIHJlcXVpcmUgb3BlcmFuZHMgaW4KKyAgICAvLyBmaXhlZCByZWdpc3RlcnMuCisgICAgLy8KKyAgICAvLyBFYWNoIHBoeXNyZWcgaGFzIG9uZSBvciBtb3JlIHJlZ2lzdGVyIHVuaXRzLCBzZWUgTUNSZWdpc3RlckluZm8uIFdlCisgICAgLy8gdHJhY2sgbGl2ZW5lc3MgcGVyIHJlZ2lzdGVyIHVuaXQgdG8gaGFuZGxlIGFsaWFzaW5nIHJlZ2lzdGVycyBtb3JlCisgICAgLy8gZWZmaWNpZW50bHkuCisKKyAgICAvLy8gUmV0dXJuIHRoZSBsaXZlIHJhbmdlIGZvciByZWdpc3RlciB1bml0IFxwIFVuaXQuIEl0IHdpbGwgYmUgY29tcHV0ZWQgaWYKKyAgICAvLy8gaXQgZG9lc24ndCBleGlzdC4KKyAgICBMaXZlUmFuZ2UgJmdldFJlZ1VuaXQodW5zaWduZWQgVW5pdCkgeworICAgICAgTGl2ZVJhbmdlICpMUiA9IFJlZ1VuaXRSYW5nZXNbVW5pdF07CisgICAgICBpZiAoIUxSKSB7CisgICAgICAgIC8vIENvbXB1dGUgbWlzc2luZyByYW5nZXMgb24gZGVtYW5kLgorICAgICAgICAvLyBVc2Ugc2VnbWVudCBzZXQgdG8gc3BlZWQtdXAgaW5pdGlhbCBjb21wdXRhdGlvbiBvZiB0aGUgbGl2ZSByYW5nZS4KKyAgICAgICAgUmVnVW5pdFJhbmdlc1tVbml0XSA9IExSID0gbmV3IExpdmVSYW5nZShVc2VTZWdtZW50U2V0Rm9yUGh5c1JlZ3MpOworICAgICAgICBjb21wdXRlUmVnVW5pdFJhbmdlKCpMUiwgVW5pdCk7CisgICAgICB9CisgICAgICByZXR1cm4gKkxSOworICAgIH0KKworICAgIC8vLyBSZXR1cm4gdGhlIGxpdmUgcmFuZ2UgZm9yIHJlZ2lzdGVyIHVuaXQgXHAgVW5pdCBpZiBpdCBoYXMgYWxyZWFkeSBiZWVuCisgICAgLy8vIGNvbXB1dGVkLCBvciBudWxscHRyIGlmIGl0IGhhc24ndCBiZWVuIGNvbXB1dGVkIHlldC4KKyAgICBMaXZlUmFuZ2UgKmdldENhY2hlZFJlZ1VuaXQodW5zaWduZWQgVW5pdCkgeworICAgICAgcmV0dXJuIFJlZ1VuaXRSYW5nZXNbVW5pdF07CisgICAgfQorCisgICAgY29uc3QgTGl2ZVJhbmdlICpnZXRDYWNoZWRSZWdVbml0KHVuc2lnbmVkIFVuaXQpIGNvbnN0IHsKKyAgICAgIHJldHVybiBSZWdVbml0UmFuZ2VzW1VuaXRdOworICAgIH0KKworICAgIC8vLyBSZW1vdmUgY29tcHV0ZWQgbGl2ZSByYW5nZSBmb3IgcmVnaXN0ZXIgdW5pdCBccCBVbml0LiBTdWJzZXF1ZW50IHVzZXMKKyAgICAvLy8gc2hvdWxkIHJlbHkgb24gb24tZGVtYW5kIHJlY29tcHV0YXRpb24uCisgICAgdm9pZCByZW1vdmVSZWdVbml0KHVuc2lnbmVkIFVuaXQpIHsKKyAgICAgIGRlbGV0ZSBSZWdVbml0UmFuZ2VzW1VuaXRdOworICAgICAgUmVnVW5pdFJhbmdlc1tVbml0XSA9IG51bGxwdHI7CisgICAgfQorCisgICAgLy8vIFJlbW92ZSB2YWx1ZSBudW1iZXJzIGFuZCByZWxhdGVkIGxpdmUgc2VnbWVudHMgc3RhcnRpbmcgYXQgcG9zaXRpb24KKyAgICAvLy8gXHAgUG9zIHRoYXQgYXJlIHBhcnQgb2YgYW55IGxpdmVyYW5nZSBvZiBwaHlzaWNhbCByZWdpc3RlciBccCBSZWcgb3Igb25lCisgICAgLy8vIG9mIGl0cyBzdWJyZWdpc3RlcnMuCisgICAgdm9pZCByZW1vdmVQaHlzUmVnRGVmQXQodW5zaWduZWQgUmVnLCBTbG90SW5kZXggUG9zKTsKKworICAgIC8vLyBSZW1vdmUgdmFsdWUgbnVtYmVyIGFuZCByZWxhdGVkIGxpdmUgc2VnbWVudHMgb2YgXHAgTEkgYW5kIGl0cyBzdWJyYW5nZXMKKyAgICAvLy8gdGhhdCBzdGFydCBhdCBwb3NpdGlvbiBccCBQb3MuCisgICAgdm9pZCByZW1vdmVWUmVnRGVmQXQoTGl2ZUludGVydmFsICZMSSwgU2xvdEluZGV4IFBvcyk7CisKKyAgICAvLy8gU3BsaXQgc2VwYXJhdGUgY29tcG9uZW50cyBpbiBMaXZlSW50ZXJ2YWwgXHAgTEkgaW50byBzZXBhcmF0ZSBpbnRlcnZhbHMuCisgICAgdm9pZCBzcGxpdFNlcGFyYXRlQ29tcG9uZW50cyhMaXZlSW50ZXJ2YWwgJkxJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPExpdmVJbnRlcnZhbCo+ICZTcGxpdExJcyk7CisKKyAgICAvLy8gRm9yIGxpdmUgaW50ZXJ2YWwgXHAgTEkgd2l0aCBjb3JyZWN0IFN1YlJhbmdlcyBjb25zdHJ1Y3QgbWF0Y2hpbmcKKyAgICAvLy8gaW5mb3JtYXRpb24gZm9yIHRoZSBtYWluIGxpdmUgcmFuZ2UuIEV4cGVjdHMgdGhlIG1haW4gbGl2ZSByYW5nZSB0byBub3QKKyAgICAvLy8gaGF2ZSBhbnkgc2VnbWVudHMgb3IgdmFsdWUgbnVtYmVycy4KKyAgICB2b2lkIGNvbnN0cnVjdE1haW5SYW5nZUZyb21TdWJyYW5nZXMoTGl2ZUludGVydmFsICZMSSk7CisKKyAgcHJpdmF0ZToKKyAgICAvLy8gQ29tcHV0ZSBsaXZlIGludGVydmFscyBmb3IgYWxsIHZpcnR1YWwgcmVnaXN0ZXJzLgorICAgIHZvaWQgY29tcHV0ZVZpcnRSZWdzKCk7CisKKyAgICAvLy8gQ29tcHV0ZSBSZWdNYXNrU2xvdHMgYW5kIFJlZ01hc2tCaXRzLgorICAgIHZvaWQgY29tcHV0ZVJlZ01hc2tzKCk7CisKKyAgICAvLy8gV2FsayB0aGUgdmFsdWVzIGluIFxwIExJIGFuZCBjaGVjayBmb3IgZGVhZCB2YWx1ZXM6CisgICAgLy8vIC0gRGVhZCBQSElEZWYgdmFsdWVzIGFyZSBtYXJrZWQgYXMgdW51c2VkLgorICAgIC8vLyAtIERlYWQgb3BlcmFuZHMgYXJlIG1hcmtlZCBhcyBzdWNoLgorICAgIC8vLyAtIENvbXBsZXRlbHkgZGVhZCBtYWNoaW5lIGluc3RydWN0aW9ucyBhcmUgYWRkZWQgdG8gdGhlIFxwIGRlYWQgdmVjdG9yCisgICAgLy8vICAgaWYgaXQgaXMgbm90IG51bGxwdHIuCisgICAgLy8vIFJldHVybnMgdHJ1ZSBpZiBhbnkgUEhJIHZhbHVlIG51bWJlcnMgaGF2ZSBiZWVuIHJlbW92ZWQgd2hpY2ggbWF5CisgICAgLy8vIGhhdmUgc2VwYXJhdGVkIHRoZSBpbnRlcnZhbCBpbnRvIG11bHRpcGxlIGNvbm5lY3RlZCBjb21wb25lbnRzLgorICAgIGJvb2wgY29tcHV0ZURlYWRWYWx1ZXMoTGl2ZUludGVydmFsICZMSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxNYWNoaW5lSW5zdHIqPiAqZGVhZCk7CisKKyAgICBzdGF0aWMgTGl2ZUludGVydmFsKiBjcmVhdGVJbnRlcnZhbCh1bnNpZ25lZCBSZWcpOworCisgICAgdm9pZCBwcmludEluc3RycyhyYXdfb3N0cmVhbSAmTykgY29uc3Q7CisgICAgdm9pZCBkdW1wSW5zdHJzKCkgY29uc3Q7CisKKyAgICB2b2lkIGNvbXB1dGVMaXZlSW5SZWdVbml0cygpOworICAgIHZvaWQgY29tcHV0ZVJlZ1VuaXRSYW5nZShMaXZlUmFuZ2UmLCB1bnNpZ25lZCBVbml0KTsKKyAgICB2b2lkIGNvbXB1dGVWaXJ0UmVnSW50ZXJ2YWwoTGl2ZUludGVydmFsJik7CisKKworICAgIC8vLyBIZWxwZXIgZnVuY3Rpb24gZm9yIHJlcGFpckludGVydmFsc0luUmFuZ2UoKSwgd2Fsa3MgYmFja3dhcmRzIGFuZAorICAgIC8vLyBjcmVhdGVzL21vZGlmaWVzIGxpdmUgc2VnbWVudHMgaW4gXHAgTFIgdG8gbWF0Y2ggdGhlIG9wZXJhbmRzIGZvdW5kLgorICAgIC8vLyBPbmx5IGZ1bGwgb3BlcmFuZHMgb3Igb3BlcmFuZHMgd2l0aCBzdWJyZWdpc3RlcnMgbWF0Y2hpbmcgXHAgTGFuZU1hc2sKKyAgICAvLy8gYXJlIGNvbnNpZGVyZWQuCisgICAgdm9pZCByZXBhaXJPbGRSZWdJblJhbmdlKE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBCZWdpbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEVuZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2xvdEluZGV4IGVuZElkeCwgTGl2ZVJhbmdlICZMUiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgUmVnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYW5lQml0bWFzayBMYW5lTWFzayA9IExhbmVCaXRtYXNrOjpnZXRBbGwoKSk7CisKKyAgICBjbGFzcyBITUVkaXRvcjsKKyAgfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGl2ZVBoeXNSZWdzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGl2ZVBoeXNSZWdzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjlhYWIwZAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9MaXZlUGh5c1JlZ3MuaApAQCAtMCwwICsxLDE5MCBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9MaXZlUGh5c1JlZ3MuaCAtIExpdmUgUGh5c2ljYWwgUmVnaXN0ZXIgU2V0IC0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLy8gXGZpbGUKKy8vLyBUaGlzIGZpbGUgaW1wbGVtZW50cyB0aGUgTGl2ZVBoeXNSZWdzIHV0aWxpdHkgZm9yIHRyYWNraW5nIGxpdmVuZXNzIG9mCisvLy8gcGh5c2ljYWwgcmVnaXN0ZXJzLiBUaGlzIGNhbiBiZSB1c2VkIGZvciBhZC1ob2MgbGl2ZW5lc3MgdHJhY2tpbmcgYWZ0ZXIKKy8vLyByZWdpc3RlciBhbGxvY2F0aW9uLiBZb3UgY2FuIHN0YXJ0IHdpdGggdGhlIGxpdmUtaW5zL2xpdmUtb3V0cyBhdCB0aGUKKy8vLyBiZWdpbm5pbmcvZW5kIG9mIGEgYmxvY2sgYW5kIHVwZGF0ZSB0aGUgaW5mb3JtYXRpb24gd2hpbGUgd2Fsa2luZyB0aGUKKy8vLyBpbnN0cnVjdGlvbnMgaW5zaWRlIHRoZSBibG9jay4gVGhpcyBpbXBsZW1lbnRhdGlvbiB0cmFja3MgdGhlIGxpdmVuZXNzIG9uIGEKKy8vLyBzdWItcmVnaXN0ZXIgZ3JhbnVsYXJpdHkuCisvLy8KKy8vLyBXZSBhc3N1bWUgdGhhdCB0aGUgaGlnaCBiaXRzIG9mIGEgcGh5c2ljYWwgc3VwZXItcmVnaXN0ZXIgYXJlIG5vdCBwcmVzZXJ2ZWQKKy8vLyB1bmxlc3MgdGhlIGluc3RydWN0aW9uIGhhcyBhbiBpbXBsaWNpdC11c2Ugb3BlcmFuZCByZWFkaW5nIHRoZSBzdXBlci0KKy8vLyByZWdpc3Rlci4KKy8vLworLy8vIFg4NiBFeGFtcGxlOgorLy8vICV5bW0wID0gLi4uCisvLy8gJXhtbTAgPSAuLi4gKEtpbGxzICV4bW0wLCBhbGwgJXhtbTBzIHN1Yi1yZWdpc3RlcnMsIGFuZCAleW1tMCkKKy8vLworLy8vICV5bW0wID0gLi4uCisvLy8gJXhtbTAgPSAuLi4sIGltcGxpY2l0ICV5bW0wICgleW1tMCBhbmQgYWxsIGl0cyBzdWItcmVnaXN0ZXJzIGFyZSBhbGl2ZSkKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0xJVkVQSFlTUkVHU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9MSVZFUEhZU1JFR1NfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvU3BhcnNlU2V0LmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVCYXNpY0Jsb2NrLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1RhcmdldFJlZ2lzdGVySW5mby5oIgorI2luY2x1ZGUgImxsdm0vTUMvTUNSZWdpc3RlckluZm8uaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPHV0aWxpdHk+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgTWFjaGluZUluc3RyOworY2xhc3MgTWFjaGluZU9wZXJhbmQ7CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworY2xhc3MgcmF3X29zdHJlYW07CisKKy8vLyBcYnJpZWYgQSBzZXQgb2YgcGh5c2ljYWwgcmVnaXN0ZXJzIHdpdGggdXRpbGl0eSBmdW5jdGlvbnMgdG8gdHJhY2sgbGl2ZW5lc3MKKy8vLyB3aGVuIHdhbGtpbmcgYmFja3dhcmQvZm9yd2FyZCB0aHJvdWdoIGEgYmFzaWMgYmxvY2suCitjbGFzcyBMaXZlUGh5c1JlZ3MgeworICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSA9IG51bGxwdHI7CisgIFNwYXJzZVNldDx1bnNpZ25lZD4gTGl2ZVJlZ3M7CisKK3B1YmxpYzoKKyAgLy8vIENvbnN0cnVjdHMgYW4gdW5pdGlhbGl6ZWQgc2V0LiBpbml0KCkgbmVlZHMgdG8gYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgaXQuCisgIExpdmVQaHlzUmVncygpID0gZGVmYXVsdDsKKworICAvLy8gQ29uc3RydWN0cyBhbmQgaW5pdGlhbGl6ZXMgYW4gZW1wdHkgc2V0LgorICBMaXZlUGh5c1JlZ3MoY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICZUUkkpIDogVFJJKCZUUkkpIHsKKyAgICBMaXZlUmVncy5zZXRVbml2ZXJzZShUUkkuZ2V0TnVtUmVncygpKTsKKyAgfQorCisgIExpdmVQaHlzUmVncyhjb25zdCBMaXZlUGh5c1JlZ3MmKSA9IGRlbGV0ZTsKKyAgTGl2ZVBoeXNSZWdzICZvcGVyYXRvcj0oY29uc3QgTGl2ZVBoeXNSZWdzJikgPSBkZWxldGU7CisKKyAgLy8vIChyZS0paW5pdGlhbGl6ZXMgYW5kIGNsZWFycyB0aGUgc2V0LgorICB2b2lkIGluaXQoY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICZUUkkpIHsKKyAgICB0aGlzLT5UUkkgPSAmVFJJOworICAgIExpdmVSZWdzLmNsZWFyKCk7CisgICAgTGl2ZVJlZ3Muc2V0VW5pdmVyc2UoVFJJLmdldE51bVJlZ3MoKSk7CisgIH0KKworICAvLy8gQ2xlYXJzIHRoZSBzZXQuCisgIHZvaWQgY2xlYXIoKSB7IExpdmVSZWdzLmNsZWFyKCk7IH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBzZXQgaXMgZW1wdHkuCisgIGJvb2wgZW1wdHkoKSBjb25zdCB7IHJldHVybiBMaXZlUmVncy5lbXB0eSgpOyB9CisKKyAgLy8vIEFkZHMgYSBwaHlzaWNhbCByZWdpc3RlciBhbmQgYWxsIGl0cyBzdWItcmVnaXN0ZXJzIHRvIHRoZSBzZXQuCisgIHZvaWQgYWRkUmVnKHVuc2lnbmVkIFJlZykgeworICAgIGFzc2VydChUUkkgJiYgIkxpdmVQaHlzUmVncyBpcyBub3QgaW5pdGlhbGl6ZWQuIik7CisgICAgYXNzZXJ0KFJlZyA8PSBUUkktPmdldE51bVJlZ3MoKSAmJiAiRXhwZWN0ZWQgYSBwaHlzaWNhbCByZWdpc3Rlci4iKTsKKyAgICBmb3IgKE1DU3ViUmVnSXRlcmF0b3IgU3ViUmVncyhSZWcsIFRSSSwgLypJbmNsdWRlU2VsZj0qL3RydWUpOworICAgICAgICAgU3ViUmVncy5pc1ZhbGlkKCk7ICsrU3ViUmVncykKKyAgICAgIExpdmVSZWdzLmluc2VydCgqU3ViUmVncyk7CisgIH0KKworICAvLy8gXGJyaWVmIFJlbW92ZXMgYSBwaHlzaWNhbCByZWdpc3RlciwgYWxsIGl0cyBzdWItcmVnaXN0ZXJzLCBhbmQgYWxsIGl0cworICAvLy8gc3VwZXItcmVnaXN0ZXJzIGZyb20gdGhlIHNldC4KKyAgdm9pZCByZW1vdmVSZWcodW5zaWduZWQgUmVnKSB7CisgICAgYXNzZXJ0KFRSSSAmJiAiTGl2ZVBoeXNSZWdzIGlzIG5vdCBpbml0aWFsaXplZC4iKTsKKyAgICBhc3NlcnQoUmVnIDw9IFRSSS0+Z2V0TnVtUmVncygpICYmICJFeHBlY3RlZCBhIHBoeXNpY2FsIHJlZ2lzdGVyLiIpOworICAgIGZvciAoTUNSZWdBbGlhc0l0ZXJhdG9yIFIoUmVnLCBUUkksIHRydWUpOyBSLmlzVmFsaWQoKTsgKytSKQorICAgICAgTGl2ZVJlZ3MuZXJhc2UoKlIpOworICB9CisKKyAgLy8vIFJlbW92ZXMgcGh5c2ljYWwgcmVnaXN0ZXJzIGNsb2JiZXJlZCBieSB0aGUgcmVnbWFzayBvcGVyYW5kIFxwIE1PLgorICB2b2lkIHJlbW92ZVJlZ3NJbk1hc2soY29uc3QgTWFjaGluZU9wZXJhbmQgJk1PLAorICAgICAgICBTbWFsbFZlY3RvckltcGw8c3RkOjpwYWlyPHVuc2lnbmVkLCBjb25zdCBNYWNoaW5lT3BlcmFuZCo+PiAqQ2xvYmJlcnMgPQorICAgICAgICBudWxscHRyKTsKKworICAvLy8gXGJyaWVmIFJldHVybnMgdHJ1ZSBpZiByZWdpc3RlciBccCBSZWcgaXMgY29udGFpbmVkIGluIHRoZSBzZXQuIFRoaXMgYWxzbworICAvLy8gd29ya3MgaWYgb25seSB0aGUgc3VwZXIgcmVnaXN0ZXIgb2YgXHAgUmVnIGhhcyBiZWVuIGRlZmluZWQsIGJlY2F1c2UKKyAgLy8vIGFkZFJlZygpIGFsd2F5cyBhZGRzIGFsbCBzdWItcmVnaXN0ZXJzIHRvIHRoZSBzZXQgYXMgd2VsbC4KKyAgLy8vIE5vdGU6IFJldHVybnMgZmFsc2UgaWYganVzdCBzb21lIHN1YiByZWdpc3RlcnMgYXJlIGxpdmUsIHVzZSBhdmFpbGFibGUoKQorICAvLy8gd2hlbiBzZWFyY2hpbmcgYSBmcmVlIHJlZ2lzdGVyLgorICBib29sIGNvbnRhaW5zKHVuc2lnbmVkIFJlZykgY29uc3QgeyByZXR1cm4gTGl2ZVJlZ3MuY291bnQoUmVnKTsgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgcmVnaXN0ZXIgXHAgUmVnIGFuZCBubyBhbGlhc2luZyByZWdpc3RlciBpcyBpbiB0aGUgc2V0LgorICBib29sIGF2YWlsYWJsZShjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkksIHVuc2lnbmVkIFJlZykgY29uc3Q7CisKKyAgLy8vIFJlbW92ZSBkZWZpbmVkIHJlZ2lzdGVycyBhbmQgcmVnbWFzayBraWxscyBmcm9tIHRoZSBzZXQuCisgIHZvaWQgcmVtb3ZlRGVmcyhjb25zdCBNYWNoaW5lSW5zdHIgJk1JKTsKKworICAvLy8gQWRkIHVzZXMgdG8gdGhlIHNldC4KKyAgdm9pZCBhZGRVc2VzKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpOworCisgIC8vLyBTaW11bGF0ZXMgbGl2ZW5lc3Mgd2hlbiBzdGVwcGluZyBiYWNrd2FyZHMgb3ZlciBhbiBpbnN0cnVjdGlvbihidW5kbGUpLgorICAvLy8gUmVtb3ZlIERlZnMsIGFkZCB1c2VzLiBUaGlzIGlzIHRoZSByZWNvbW1lbmRlZCB3YXkgb2YgY2FsY3VsYXRpbmcKKyAgLy8vIGxpdmVuZXNzLgorICB2b2lkIHN0ZXBCYWNrd2FyZChjb25zdCBNYWNoaW5lSW5zdHIgJk1JKTsKKworICAvLy8gU2ltdWxhdGVzIGxpdmVuZXNzIHdoZW4gc3RlcHBpbmcgZm9yd2FyZCBvdmVyIGFuIGluc3RydWN0aW9uKGJ1bmRsZSkuCisgIC8vLyBSZW1vdmUga2lsbGVkLXVzZXMsIGFkZCBkZWZzLiBUaGlzIGlzIHRoZSBub3QgcmVjb21tZW5kZWQgd2F5LCBiZWNhdXNlIGl0CisgIC8vLyBkZXBlbmRzIG9uIGFjY3VyYXRlIGtpbGwgZmxhZ3MuIElmIHBvc3NpYmxlIHVzZSBzdGVwQmFja3dhcmQoKSBpbnN0ZWFkIG9mCisgIC8vLyB0aGlzIGZ1bmN0aW9uLiBUaGUgY2xvYmJlcnMgc2V0IHdpbGwgYmUgdGhlIGxpc3Qgb2YgcmVnaXN0ZXJzIGVpdGhlcgorICAvLy8gZGVmaW5lZCBvciBjbG9iYmVyZWQgYnkgYSByZWdtYXNrLiAgVGhlIG9wZXJhbmQgd2lsbCBpZGVudGlmeSB3aGV0aGVyIHRoaXMKKyAgLy8vIGlzIGEgcmVnbWFzayBvciByZWdpc3RlciBvcGVyYW5kLgorICB2b2lkIHN0ZXBGb3J3YXJkKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUksCisgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxzdGQ6OnBhaXI8dW5zaWduZWQsIGNvbnN0IE1hY2hpbmVPcGVyYW5kKj4+ICZDbG9iYmVycyk7CisKKyAgLy8vIEFkZHMgYWxsIGxpdmUtaW4gcmVnaXN0ZXJzIG9mIGJhc2ljIGJsb2NrIFxwIE1CQi4KKyAgLy8vIExpdmUgaW4gcmVnaXN0ZXJzIGFyZSB0aGUgcmVnaXN0ZXJzIGluIHRoZSBibG9ja3MgbGl2ZS1pbiBsaXN0IGFuZCB0aGUKKyAgLy8vIHByaXN0aW5lIHJlZ2lzdGVycy4KKyAgdm9pZCBhZGRMaXZlSW5zKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIpOworCisgIC8vLyBBZGRzIGFsbCBsaXZlLW91dCByZWdpc3RlcnMgb2YgYmFzaWMgYmxvY2sgXHAgTUJCLgorICAvLy8gTGl2ZSBvdXQgcmVnaXN0ZXJzIGFyZSB0aGUgdW5pb24gb2YgdGhlIGxpdmUtaW4gcmVnaXN0ZXJzIG9mIHRoZSBzdWNjZXNzb3IKKyAgLy8vIGJsb2NrcyBhbmQgcHJpc3RpbmUgcmVnaXN0ZXJzLiBMaXZlIG91dCByZWdpc3RlcnMgb2YgdGhlIGVuZCBibG9jayBhcmUgdGhlCisgIC8vLyBjYWxsZWUgc2F2ZWQgcmVnaXN0ZXJzLgorICB2b2lkIGFkZExpdmVPdXRzKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIpOworCisgIC8vLyBBZGRzIGFsbCBsaXZlLW91dCByZWdpc3RlcnMgb2YgYmFzaWMgYmxvY2sgXHAgTUJCIGJ1dCBza2lwcyBwcmlzdGluZQorICAvLy8gcmVnaXN0ZXJzLgorICB2b2lkIGFkZExpdmVPdXRzTm9QcmlzdGluZXMoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgJk1CQik7CisKKyAgdXNpbmcgY29uc3RfaXRlcmF0b3IgPSBTcGFyc2VTZXQ8dW5zaWduZWQ+Ojpjb25zdF9pdGVyYXRvcjsKKworICBjb25zdF9pdGVyYXRvciBiZWdpbigpIGNvbnN0IHsgcmV0dXJuIExpdmVSZWdzLmJlZ2luKCk7IH0KKyAgY29uc3RfaXRlcmF0b3IgZW5kKCkgY29uc3QgeyByZXR1cm4gTGl2ZVJlZ3MuZW5kKCk7IH0KKworICAvLy8gUHJpbnRzIHRoZSBjdXJyZW50bHkgbGl2ZSByZWdpc3RlcnMgdG8gXHAgT1MuCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk9TKSBjb25zdDsKKworICAvLy8gRHVtcHMgdGhlIGN1cnJlbnRseSBsaXZlIHJlZ2lzdGVycyB0byB0aGUgZGVidWcgb3V0cHV0LgorICB2b2lkIGR1bXAoKSBjb25zdDsKKworcHJpdmF0ZToKKyAgLy8vIFxicmllZiBBZGRzIGxpdmUtaW4gcmVnaXN0ZXJzIGZyb20gYmFzaWMgYmxvY2sgXHAgTUJCLCB0YWtpbmcgYXNzb2NpYXRlZAorICAvLy8gbGFuZSBtYXNrcyBpbnRvIGNvbnNpZGVyYXRpb24uCisgIHZvaWQgYWRkQmxvY2tMaXZlSW5zKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIpOworCisgIC8vLyBBZGRzIHByaXN0aW5lIHJlZ2lzdGVycy4gUHJpc3RpbmUgcmVnaXN0ZXJzIGFyZSBjYWxsZWUgc2F2ZWQgcmVnaXN0ZXJzCisgIC8vLyB0aGF0IGFyZSB1bnVzZWQgaW4gdGhlIGZ1bmN0aW9uLgorICB2b2lkIGFkZFByaXN0aW5lcyhjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKTsKK307CisKK2lubGluZSByYXdfb3N0cmVhbSAmb3BlcmF0b3I8PChyYXdfb3N0cmVhbSAmT1MsIGNvbnN0IExpdmVQaHlzUmVncyYgTFIpIHsKKyAgTFIucHJpbnQoT1MpOworICByZXR1cm4gT1M7Cit9CisKKy8vLyBcYnJpZWYgQ29tcHV0ZXMgcmVnaXN0ZXJzIGxpdmUtaW4gdG8gXHAgTUJCIGFzc3VtaW5nIGFsbCBvZiBpdHMgc3VjY2Vzc29ycworLy8vIGxpdmUtaW4gbGlzdHMgYXJlIHVwLXRvLWRhdGUuIFB1dHMgdGhlIHJlc3VsdCBpbnRvIHRoZSBnaXZlbiBMaXZlUGh5c1JlZworLy8vIGluc3RhbmNlIFxwIExpdmVSZWdzLgordm9pZCBjb21wdXRlTGl2ZUlucyhMaXZlUGh5c1JlZ3MgJkxpdmVSZWdzLCBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAmTUJCKTsKKworLy8vIFJlY29tcHV0ZXMgZGVhZCBhbmQga2lsbCBmbGFncyBpbiBccCBNQkIuCit2b2lkIHJlY29tcHV0ZUxpdmVuZXNzRmxhZ3MoTWFjaGluZUJhc2ljQmxvY2sgJk1CQik7CisKKy8vLyBBZGRzIHJlZ2lzdGVycyBjb250YWluZWQgaW4gXHAgTGl2ZVJlZ3MgdG8gdGhlIGJsb2NrIGxpdmUtaW4gbGlzdCBvZiBccCBNQkIuCisvLy8gRG9lcyBub3QgYWRkIHJlc2VydmVkIHJlZ2lzdGVycy4KK3ZvaWQgYWRkTGl2ZUlucyhNYWNoaW5lQmFzaWNCbG9jayAmTUJCLCBjb25zdCBMaXZlUGh5c1JlZ3MgJkxpdmVSZWdzKTsKKworLy8vIENvbnZlbmllbmNlIGZ1bmN0aW9uIGNvbWJpbmluZyBjb21wdXRlTGl2ZUlucygpIGFuZCBhZGRMaXZlSW5zKCkuCit2b2lkIGNvbXB1dGVBbmRBZGRMaXZlSW5zKExpdmVQaHlzUmVncyAmTGl2ZVJlZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIpOworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX0xJVkVQSFlTUkVHU19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGl2ZVJhbmdlRWRpdC5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xpdmVSYW5nZUVkaXQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MmIxZjBiCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xpdmVSYW5nZUVkaXQuaApAQCAtMCwwICsxLDI1OCBAQAorLy89PT0tIExpdmVSYW5nZUVkaXQuaCAtIEJhc2ljIHRvb2xzIGZvciBzcGxpdCBhbmQgc3BpbGwgLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGUgTGl2ZVJhbmdlRWRpdCBjbGFzcyByZXByZXNlbnRzIGNoYW5nZXMgZG9uZSB0byBhIHZpcnR1YWwgcmVnaXN0ZXIgd2hlbiBpdAorLy8gaXMgc3BpbGxlZCBvciBzcGxpdC4KKy8vCisvLyBUaGUgcGFyZW50IHJlZ2lzdGVyIGlzIG5ldmVyIGNoYW5nZWQuIEluc3RlYWQsIGEgbnVtYmVyIG9mIG5ldyB2aXJ0dWFsCisvLyByZWdpc3RlcnMgYXJlIGNyZWF0ZWQgYW5kIGFkZGVkIHRvIHRoZSBuZXdSZWdzIHZlY3Rvci4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9MSVZFUkFOR0VFRElUX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0xJVkVSQU5HRUVESVRfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvQXJyYXlSZWYuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9Ob25lLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU2V0VmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxQdHJTZXQuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQW5hbHlzaXMvQWxpYXNBbmFseXNpcy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9MaXZlSW50ZXJ2YWwuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVSZWdpc3RlckluZm8uaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2xvdEluZGV4ZXMuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0U3VidGFyZ2V0SW5mby5oIgorI2luY2x1ZGUgPGNhc3NlcnQ+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgTGl2ZUludGVydmFsczsKK2NsYXNzIE1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm87CitjbGFzcyBNYWNoaW5lSW5zdHI7CitjbGFzcyBNYWNoaW5lTG9vcEluZm87CitjbGFzcyBNYWNoaW5lT3BlcmFuZDsKK2NsYXNzIFRhcmdldEluc3RySW5mbzsKK2NsYXNzIFRhcmdldFJlZ2lzdGVySW5mbzsKK2NsYXNzIFZpcnRSZWdNYXA7CisKK2NsYXNzIExpdmVSYW5nZUVkaXQgOiBwcml2YXRlIE1hY2hpbmVSZWdpc3RlckluZm86OkRlbGVnYXRlIHsKK3B1YmxpYzoKKyAgLy8vIENhbGxiYWNrIG1ldGhvZHMgZm9yIExpdmVSYW5nZUVkaXQgb3duZXJzLgorICBjbGFzcyBEZWxlZ2F0ZSB7CisgICAgdmlydHVhbCB2b2lkIGFuY2hvcigpOworCisgIHB1YmxpYzoKKyAgICB2aXJ0dWFsIH5EZWxlZ2F0ZSgpID0gZGVmYXVsdDsKKworICAgIC8vLyBDYWxsZWQgaW1tZWRpYXRlbHkgYmVmb3JlIGVyYXNpbmcgYSBkZWFkIG1hY2hpbmUgaW5zdHJ1Y3Rpb24uCisgICAgdmlydHVhbCB2b2lkIExSRV9XaWxsRXJhc2VJbnN0cnVjdGlvbihNYWNoaW5lSW5zdHIgKk1JKSB7fQorCisgICAgLy8vIENhbGxlZCB3aGVuIGEgdmlydHVhbCByZWdpc3RlciBpcyBubyBsb25nZXIgdXNlZC4gUmV0dXJuIGZhbHNlIHRvIGRlZmVyCisgICAgLy8vIGl0cyBkZWxldGlvbiBmcm9tIExpdmVJbnRlcnZhbHMuCisgICAgdmlydHVhbCBib29sIExSRV9DYW5FcmFzZVZpcnRSZWcodW5zaWduZWQpIHsgcmV0dXJuIHRydWU7IH0KKworICAgIC8vLyBDYWxsZWQgYmVmb3JlIHNocmlua2luZyB0aGUgbGl2ZSByYW5nZSBvZiBhIHZpcnR1YWwgcmVnaXN0ZXIuCisgICAgdmlydHVhbCB2b2lkIExSRV9XaWxsU2hyaW5rVmlydFJlZyh1bnNpZ25lZCkge30KKworICAgIC8vLyBDYWxsZWQgYWZ0ZXIgY2xvbmluZyBhIHZpcnR1YWwgcmVnaXN0ZXIuCisgICAgLy8vIFRoaXMgaXMgdXNlZCBmb3IgbmV3IHJlZ2lzdGVycyByZXByZXNlbnRpbmcgY29ubmVjdGVkIGNvbXBvbmVudHMgb2YgT2xkLgorICAgIHZpcnR1YWwgdm9pZCBMUkVfRGlkQ2xvbmVWaXJ0UmVnKHVuc2lnbmVkIE5ldywgdW5zaWduZWQgT2xkKSB7fQorICB9OworCitwcml2YXRlOgorICBMaXZlSW50ZXJ2YWwgKlBhcmVudDsKKyAgU21hbGxWZWN0b3JJbXBsPHVuc2lnbmVkPiAmTmV3UmVnczsKKyAgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJOworICBMaXZlSW50ZXJ2YWxzICZMSVM7CisgIFZpcnRSZWdNYXAgKlZSTTsKKyAgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICZUSUk7CisgIERlbGVnYXRlICpjb25zdCBUaGVEZWxlZ2F0ZTsKKworICAvLy8gRmlyc3ROZXcgLSBJbmRleCBvZiB0aGUgZmlyc3QgcmVnaXN0ZXIgYWRkZWQgdG8gTmV3UmVncy4KKyAgY29uc3QgdW5zaWduZWQgRmlyc3ROZXc7CisKKyAgLy8vIFNjYW5uZWRSZW1hdHRhYmxlIC0gdHJ1ZSB3aGVuIHJlbWF0dGFibGUgdmFsdWVzIGhhdmUgYmVlbiBpZGVudGlmaWVkLgorICBib29sIFNjYW5uZWRSZW1hdHRhYmxlID0gZmFsc2U7CisKKyAgLy8vIERlYWRSZW1hdHMgLSBUaGUgc2F2ZWQgaW5zdHJ1Y3Rpb25zIHdoaWNoIGhhdmUgYWxyZWFkeSBiZWVuIGRlYWQgYWZ0ZXIKKyAgLy8vIHJlbWF0ZXJpYWxpemF0aW9uIGJ1dCBub3QgZGVsZXRlZCB5ZXQgLS0gdG8gYmUgZG9uZSBpbiBwb3N0T3B0aW1pemF0aW9uLgorICBTbWFsbFB0clNldDxNYWNoaW5lSW5zdHIgKiwgMzI+ICpEZWFkUmVtYXRzOworCisgIC8vLyBSZW1hdHRhYmxlIC0gVmFsdWVzIGRlZmluZWQgYnkgcmVtYXR0YWJsZSBpbnN0cnVjdGlvbnMgYXMgaWRlbnRpZmllZCBieQorICAvLy8gdGlpLmlzVHJpdmlhbGx5UmVNYXRlcmlhbGl6YWJsZSgpLgorICBTbWFsbFB0clNldDxjb25zdCBWTkluZm8gKiwgND4gUmVtYXR0YWJsZTsKKworICAvLy8gUmVtYXR0ZWQgLSBWYWx1ZXMgdGhhdCB3ZXJlIGFjdHVhbGx5IHJlbWF0dGVkLCBhbmQgc28gbmVlZCB0byBoYXZlIHRoZWlyCisgIC8vLyBsaXZlIHJhbmdlIHRyaW1tZWQgb3IgZW50aXJlbHkgcmVtb3ZlZC4KKyAgU21hbGxQdHJTZXQ8Y29uc3QgVk5JbmZvICosIDQ+IFJlbWF0dGVkOworCisgIC8vLyBzY2FuUmVtYXR0YWJsZSAtIElkZW50aWZ5IHRoZSBQYXJlbnQgdmFsdWVzIHRoYXQgbWF5IHJlbWF0ZXJpYWxpemUuCisgIHZvaWQgc2NhblJlbWF0dGFibGUoQWxpYXNBbmFseXNpcyAqYWEpOworCisgIC8vLyBhbGxVc2VzQXZhaWxhYmxlQXQgLSBSZXR1cm4gdHJ1ZSBpZiBhbGwgcmVnaXN0ZXJzIHVzZWQgYnkgT3JpZ01JIGF0CisgIC8vLyBPcmlnSWR4IGFyZSBhbHNvIGF2YWlsYWJsZSB3aXRoIHRoZSBzYW1lIHZhbHVlIGF0IFVzZUlkeC4KKyAgYm9vbCBhbGxVc2VzQXZhaWxhYmxlQXQoY29uc3QgTWFjaGluZUluc3RyICpPcmlnTUksIFNsb3RJbmRleCBPcmlnSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICBTbG90SW5kZXggVXNlSWR4KSBjb25zdDsKKworICAvLy8gZm9sZEFzTG9hZCAtIElmIExJIGhhcyBhIHNpbmdsZSB1c2UgYW5kIGEgc2luZ2xlIGRlZiB0aGF0IGNhbiBiZSBmb2xkZWQgYXMKKyAgLy8vIGEgbG9hZCwgZWxpbWluYXRlIHRoZSByZWdpc3RlciBieSBmb2xkaW5nIHRoZSBkZWYgaW50byB0aGUgdXNlLgorICBib29sIGZvbGRBc0xvYWQoTGl2ZUludGVydmFsICpMSSwgU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVJbnN0ciAqPiAmRGVhZCk7CisKKyAgdXNpbmcgVG9TaHJpbmtTZXQgPSBTZXRWZWN0b3I8TGl2ZUludGVydmFsICosIFNtYWxsVmVjdG9yPExpdmVJbnRlcnZhbCAqLCA4PiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU21hbGxQdHJTZXQ8TGl2ZUludGVydmFsICosIDg+PjsKKworICAvLy8gSGVscGVyIGZvciBlbGltaW5hdGVEZWFkRGVmcy4KKyAgdm9pZCBlbGltaW5hdGVEZWFkRGVmKE1hY2hpbmVJbnN0ciAqTUksIFRvU2hyaW5rU2V0ICZUb1NocmluaywKKyAgICAgICAgICAgICAgICAgICAgICAgIEFsaWFzQW5hbHlzaXMgKkFBKTsKKworICAvLy8gTWFjaGluZVJlZ2lzdGVySW5mbyBjYWxsYmFjayB0byBub3RpZnkgd2hlbiBuZXcgdmlydHVhbAorICAvLy8gcmVnaXN0ZXJzIGFyZSBjcmVhdGVkLgorICB2b2lkIE1SSV9Ob3RlTmV3VmlydHVhbFJlZ2lzdGVyKHVuc2lnbmVkIFZSZWcpIG92ZXJyaWRlOworCisgIC8vLyBcYnJpZWYgQ2hlY2sgaWYgTWFjaGluZU9wZXJhbmQgXHAgTU8gaXMgYSBsYXN0IHVzZS9raWxsIGVpdGhlciBpbiB0aGUKKyAgLy8vIG1haW4gbGl2ZSByYW5nZSBvZiBccCBMSSBvciBpbiBvbmUgb2YgdGhlIG1hdGNoaW5nIHN1YnJlZ2lzdGVyIHJhbmdlcy4KKyAgYm9vbCB1c2VJc0tpbGwoY29uc3QgTGl2ZUludGVydmFsICZMSSwgY29uc3QgTWFjaGluZU9wZXJhbmQgJk1PKSBjb25zdDsKKworICAvLy8gQ3JlYXRlIGEgbmV3IGVtcHR5IGludGVydmFsIGJhc2VkIG9uIE9sZFJlZy4KKyAgTGl2ZUludGVydmFsICZjcmVhdGVFbXB0eUludGVydmFsRnJvbSh1bnNpZ25lZCBPbGRSZWcsIGJvb2wgY3JlYXRlU3ViUmFuZ2VzKTsKKworcHVibGljOgorICAvLy8gQ3JlYXRlIGEgTGl2ZVJhbmdlRWRpdCBmb3IgYnJlYWtpbmcgZG93biBwYXJlbnQgaW50byBzbWFsbGVyIHBpZWNlcy4KKyAgLy8vIEBwYXJhbSBwYXJlbnQgVGhlIHJlZ2lzdGVyIGJlaW5nIHNwaWxsZWQgb3Igc3BsaXQuCisgIC8vLyBAcGFyYW0gbmV3UmVncyBMaXN0IHRvIHJlY2VpdmUgYW55IG5ldyByZWdpc3RlcnMgY3JlYXRlZC4gVGhpcyBuZWVkbid0IGJlCisgIC8vLyAgICAgICAgICAgICAgICBlbXB0eSBpbml0aWFsbHksIGFueSBleGlzdGluZyByZWdpc3RlcnMgYXJlIGlnbm9yZWQuCisgIC8vLyBAcGFyYW0gTUYgVGhlIE1hY2hpbmVGdW5jdGlvbiB0aGUgbGl2ZSByYW5nZSBlZGl0IGlzIHRha2luZyBwbGFjZSBpbi4KKyAgLy8vIEBwYXJhbSBsaXMgVGhlIGNvbGxlY3Rpb24gb2YgYWxsIGxpdmUgaW50ZXJ2YWxzIGluIHRoaXMgZnVuY3Rpb24uCisgIC8vLyBAcGFyYW0gdnJtIE1hcCBvZiB2aXJ0dWFsIHJlZ2lzdGVycyB0byBwaHlzaWNhbCByZWdpc3RlcnMgZm9yIHRoaXMKKyAgLy8vICAgICAgICAgICAgZnVuY3Rpb24uICBJZiBOVUxMLCBubyB2aXJ0dWFsIHJlZ2lzdGVyIG1hcCB1cGRhdGVzIHdpbGwKKyAgLy8vICAgICAgICAgICAgYmUgZG9uZS4gIFRoaXMgY291bGQgYmUgdGhlIGNhc2UgaWYgY2FsbGVkIGJlZm9yZSBSZWdhbGxvYy4KKyAgLy8vIEBwYXJhbSBkZWFkUmVtYXRzIFRoZSBjb2xsZWN0aW9uIG9mIGFsbCB0aGUgaW5zdHJ1Y3Rpb25zIGRlZmluaW5nIGFuCisgIC8vLyAgICAgICAgICAgICAgICAgICBvcmlnaW5hbCByZWcgYW5kIGFyZSBkZWFkIGFmdGVyIHJlbWF0LgorICBMaXZlUmFuZ2VFZGl0KExpdmVJbnRlcnZhbCAqcGFyZW50LCBTbWFsbFZlY3RvckltcGw8dW5zaWduZWQ+ICZuZXdSZWdzLAorICAgICAgICAgICAgICAgIE1hY2hpbmVGdW5jdGlvbiAmTUYsIExpdmVJbnRlcnZhbHMgJmxpcywgVmlydFJlZ01hcCAqdnJtLAorICAgICAgICAgICAgICAgIERlbGVnYXRlICpkZWxlZ2F0ZSA9IG51bGxwdHIsCisgICAgICAgICAgICAgICAgU21hbGxQdHJTZXQ8TWFjaGluZUluc3RyICosIDMyPiAqZGVhZFJlbWF0cyA9IG51bGxwdHIpCisgICAgICA6IFBhcmVudChwYXJlbnQpLCBOZXdSZWdzKG5ld1JlZ3MpLCBNUkkoTUYuZ2V0UmVnSW5mbygpKSwgTElTKGxpcyksCisgICAgICAgIFZSTSh2cm0pLCBUSUkoKk1GLmdldFN1YnRhcmdldCgpLmdldEluc3RySW5mbygpKSwgVGhlRGVsZWdhdGUoZGVsZWdhdGUpLAorICAgICAgICBGaXJzdE5ldyhuZXdSZWdzLnNpemUoKSksIERlYWRSZW1hdHMoZGVhZFJlbWF0cykgeworICAgIE1SSS5zZXREZWxlZ2F0ZSh0aGlzKTsKKyAgfQorCisgIH5MaXZlUmFuZ2VFZGl0KCkgb3ZlcnJpZGUgeyBNUkkucmVzZXREZWxlZ2F0ZSh0aGlzKTsgfQorCisgIExpdmVJbnRlcnZhbCAmZ2V0UGFyZW50KCkgY29uc3QgeworICAgIGFzc2VydChQYXJlbnQgJiYgIk5vIHBhcmVudCBMaXZlSW50ZXJ2YWwiKTsKKyAgICByZXR1cm4gKlBhcmVudDsKKyAgfQorCisgIHVuc2lnbmVkIGdldFJlZygpIGNvbnN0IHsgcmV0dXJuIGdldFBhcmVudCgpLnJlZzsgfQorCisgIC8vLyBJdGVyYXRvciBmb3IgYWNjZXNzaW5nIHRoZSBuZXcgcmVnaXN0ZXJzIGFkZGVkIGJ5IHRoaXMgZWRpdC4KKyAgdXNpbmcgaXRlcmF0b3IgPSBTbWFsbFZlY3RvckltcGw8dW5zaWduZWQ+Ojpjb25zdF9pdGVyYXRvcjsKKyAgaXRlcmF0b3IgYmVnaW4oKSBjb25zdCB7IHJldHVybiBOZXdSZWdzLmJlZ2luKCkgKyBGaXJzdE5ldzsgfQorICBpdGVyYXRvciBlbmQoKSBjb25zdCB7IHJldHVybiBOZXdSZWdzLmVuZCgpOyB9CisgIHVuc2lnbmVkIHNpemUoKSBjb25zdCB7IHJldHVybiBOZXdSZWdzLnNpemUoKSAtIEZpcnN0TmV3OyB9CisgIGJvb2wgZW1wdHkoKSBjb25zdCB7IHJldHVybiBzaXplKCkgPT0gMDsgfQorICB1bnNpZ25lZCBnZXQodW5zaWduZWQgaWR4KSBjb25zdCB7IHJldHVybiBOZXdSZWdzW2lkeCArIEZpcnN0TmV3XTsgfQorCisgIC8vLyBwb3BfYmFjayAtIEl0IGFsbG93cyBMaXZlUmFuZ2VFZGl0IHVzZXJzIHRvIGRyb3AgbmV3IHJlZ2lzdGVycy4KKyAgLy8vIFRoZSBjb250ZXh0IGlzIHdoZW4gYW4gb3JpZ2luYWwgZGVmIGluc3RydWN0aW9uIG9mIGEgcmVnaXN0ZXIgaXMKKyAgLy8vIGRlYWQgYWZ0ZXIgcmVtYXRlcmlhbGl6YXRpb24sIHdlIHN0aWxsIHdhbnQgdG8ga2VlcCBpdCBmb3IgZm9sbG93aW5nCisgIC8vLyByZW1hdGVyaWFsaXphdGlvbnMuIFdlIHNhdmUgdGhlIGRlZiBpbnN0cnVjdGlvbiBpbiBEZWFkUmVtYXRzLAorICAvLy8gYW5kIHJlcGxhY2UgdGhlIG9yaWdpbmFsIGRzdCByZWdpc3RlciB3aXRoIGEgbmV3IGR1bW15IHJlZ2lzdGVyIHNvCisgIC8vLyB0aGUgbGl2ZSByYW5nZSBvZiBvcmlnaW5hbCBkc3QgcmVnaXN0ZXIgY2FuIGJlIHNocmlua2VkIG5vcm1hbGx5LgorICAvLy8gV2UgZG9uJ3Qgd2FudCB0byBhbGxvY2F0ZSBwaHlzIHJlZ2lzdGVyIGZvciB0aGUgZHVtbXkgcmVnaXN0ZXIsIHNvCisgIC8vLyB3ZSB3YW50IHRvIGRyb3AgaXQgZnJvbSB0aGUgTmV3UmVncyBzZXQuCisgIHZvaWQgcG9wX2JhY2soKSB7IE5ld1JlZ3MucG9wX2JhY2soKTsgfQorCisgIEFycmF5UmVmPHVuc2lnbmVkPiByZWdzKCkgY29uc3QgeworICAgIHJldHVybiBtYWtlQXJyYXlSZWYoTmV3UmVncykuc2xpY2UoRmlyc3ROZXcpOworICB9CisKKyAgLy8vIGNyZWF0ZUZyb20gLSBDcmVhdGUgYSBuZXcgdmlydHVhbCByZWdpc3RlciBiYXNlZCBvbiBPbGRSZWcuCisgIHVuc2lnbmVkIGNyZWF0ZUZyb20odW5zaWduZWQgT2xkUmVnKTsKKworICAvLy8gY3JlYXRlIC0gQ3JlYXRlIGEgbmV3IHJlZ2lzdGVyIHdpdGggdGhlIHNhbWUgY2xhc3MgYW5kIG9yaWdpbmFsIHNsb3QgYXMKKyAgLy8vIHBhcmVudC4KKyAgTGl2ZUludGVydmFsICZjcmVhdGVFbXB0eUludGVydmFsKCkgeworICAgIHJldHVybiBjcmVhdGVFbXB0eUludGVydmFsRnJvbShnZXRSZWcoKSwgdHJ1ZSk7CisgIH0KKworICB1bnNpZ25lZCBjcmVhdGUoKSB7IHJldHVybiBjcmVhdGVGcm9tKGdldFJlZygpKTsgfQorCisgIC8vLyBhbnlSZW1hdGVyaWFsaXphYmxlIC0gUmV0dXJuIHRydWUgaWYgYW55IHBhcmVudCB2YWx1ZXMgbWF5IGJlCisgIC8vLyByZW1hdGVyaWFsaXphYmxlLgorICAvLy8gVGhpcyBmdW5jdGlvbiBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgYW55IHJlbWF0ZXJpYWxpemF0aW9uIGlzIGF0dGVtcHRlZC4KKyAgYm9vbCBhbnlSZW1hdGVyaWFsaXphYmxlKEFsaWFzQW5hbHlzaXMgKik7CisKKyAgLy8vIGNoZWNrUmVtYXRlcmlhbGl6YWJsZSAtIE1hbnVhbGx5IGFkZCBWTkkgdG8gdGhlIGxpc3Qgb2YgcmVtYXRlcmlhbGl6YWJsZQorICAvLy8gdmFsdWVzIGlmIERlZk1JIG1heSBiZSByZW1hdGVyaWFsaXphYmxlLgorICBib29sIGNoZWNrUmVtYXRlcmlhbGl6YWJsZShWTkluZm8gKlZOSSwgY29uc3QgTWFjaGluZUluc3RyICpEZWZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWxpYXNBbmFseXNpcyAqKTsKKworICAvLy8gUmVtYXQgLSBJbmZvcm1hdGlvbiBuZWVkZWQgdG8gcmVtYXRlcmlhbGl6ZSBhdCBhIHNwZWNpZmljIGxvY2F0aW9uLgorICBzdHJ1Y3QgUmVtYXQgeworICAgIFZOSW5mbyAqUGFyZW50Vk5JOyAgICAgICAgICAgICAgLy8gcGFyZW50XydzIHZhbHVlIGF0IHRoZSByZW1hdCBsb2NhdGlvbi4KKyAgICBNYWNoaW5lSW5zdHIgKk9yaWdNSSA9IG51bGxwdHI7IC8vIEluc3RydWN0aW9uIGRlZmluaW5nIE9yaWdWTkkuIEl0IGNvbnRhaW5zCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgcmVhbCBleHByIGZvciByZW1hdC4KKworICAgIGV4cGxpY2l0IFJlbWF0KFZOSW5mbyAqUGFyZW50Vk5JKSA6IFBhcmVudFZOSShQYXJlbnRWTkkpIHt9CisgIH07CisKKyAgLy8vIGNhblJlbWF0ZXJpYWxpemVBdCAtIERldGVybWluZSBpZiBQYXJlbnRWTkkgY2FuIGJlIHJlbWF0ZXJpYWxpemVkIGF0CisgIC8vLyBVc2VJZHguIEl0IGlzIGFzc3VtZWQgdGhhdCBwYXJlbnRfLmdldFZOSU5mb0F0KFVzZUlkeCkgPT0gUGFyZW50Vk5JLgorICAvLy8gV2hlbiBjaGVhcEFzQU1vdmUgaXMgc2V0LCBvbmx5IGNoZWFwIHJlbWF0cyBhcmUgYWxsb3dlZC4KKyAgYm9vbCBjYW5SZW1hdGVyaWFsaXplQXQoUmVtYXQgJlJNLCBWTkluZm8gKk9yaWdWTkksIFNsb3RJbmRleCBVc2VJZHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgY2hlYXBBc0FNb3ZlKTsKKworICAvLy8gcmVtYXRlcmlhbGl6ZUF0IC0gUmVtYXRlcmlhbGl6ZSBSTS5QYXJlbnRWTkkgaW50byBEZXN0UmVnIGJ5IGluc2VydGluZyBhbgorICAvLy8gaW5zdHJ1Y3Rpb24gaW50byBNQkIgYmVmb3JlIE1JLiBUaGUgbmV3IGluc3RydWN0aW9uIGlzIG1hcHBlZCwgYnV0CisgIC8vLyBsaXZlbmVzcyBpcyBub3QgdXBkYXRlZC4KKyAgLy8vIFJldHVybiB0aGUgU2xvdEluZGV4IG9mIHRoZSBuZXcgaW5zdHJ1Y3Rpb24uCisgIFNsb3RJbmRleCByZW1hdGVyaWFsaXplQXQoTWFjaGluZUJhc2ljQmxvY2sgJk1CQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgTUksIHVuc2lnbmVkIERlc3RSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVtYXQgJlJNLCBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gJiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIExhdGUgPSBmYWxzZSk7CisKKyAgLy8vIG1hcmtSZW1hdGVyaWFsaXplZCAtIGV4cGxpY2l0bHkgbWFyayBhIHZhbHVlIGFzIHJlbWF0ZXJpYWxpemVkIGFmdGVyIGRvaW5nCisgIC8vLyBpdCBtYW51YWxseS4KKyAgdm9pZCBtYXJrUmVtYXRlcmlhbGl6ZWQoY29uc3QgVk5JbmZvICpQYXJlbnRWTkkpIHsKKyAgICBSZW1hdHRlZC5pbnNlcnQoUGFyZW50Vk5JKTsKKyAgfQorCisgIC8vLyBkaWRSZW1hdGVyaWFsaXplIC0gUmV0dXJuIHRydWUgaWYgUGFyZW50Vk5JIHdhcyByZW1hdGVyaWFsaXplZCBhbnl3aGVyZS4KKyAgYm9vbCBkaWRSZW1hdGVyaWFsaXplKGNvbnN0IFZOSW5mbyAqUGFyZW50Vk5JKSBjb25zdCB7CisgICAgcmV0dXJuIFJlbWF0dGVkLmNvdW50KFBhcmVudFZOSSk7CisgIH0KKworICAvLy8gZXJhc2VWaXJ0UmVnIC0gTm90aWZ5IHRoZSBkZWxlZ2F0ZSB0aGF0IFJlZyBpcyBubyBsb25nZXIgaW4gdXNlLCBhbmQgdHJ5CisgIC8vLyB0byBlcmFzZSBpdCBmcm9tIExJUy4KKyAgdm9pZCBlcmFzZVZpcnRSZWcodW5zaWduZWQgUmVnKTsKKworICAvLy8gZWxpbWluYXRlRGVhZERlZnMgLSBUcnkgdG8gZGVsZXRlIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zIHRoYXQgYXJlIG5vdyBkZWFkCisgIC8vLyAoYWxsRGVmc0FyZURlYWQgcmV0dXJucyB0cnVlKS4gVGhpcyBtYXkgY2F1c2UgbGl2ZSBpbnRlcnZhbHMgdG8gYmUgdHJpbW1lZAorICAvLy8gYW5kIGZ1cnRoZXIgZGVhZCBlZnMgdG8gYmUgZWxpbWluYXRlZC4KKyAgLy8vIFJlZ3NCZWluZ1NwaWxsZWQgbGlzdHMgcmVnaXN0ZXJzIGN1cnJlbnRseSBiZWluZyBzcGlsbGVkIGJ5IHRoZSByZWdpc3RlcgorICAvLy8gYWxsb2NhdG9yLiAgVGhlc2UgcmVnaXN0ZXJzIHNob3VsZCBub3QgYmUgc3BsaXQgaW50byBuZXcgaW50ZXJ2YWxzCisgIC8vLyBhcyBjdXJyZW50bHkgdGhvc2UgbmV3IGludGVydmFscyBhcmUgbm90IGd1YXJhbnRlZWQgdG8gc3BpbGwuCisgIHZvaWQgZWxpbWluYXRlRGVhZERlZnMoU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVJbnN0ciAqPiAmRGVhZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjx1bnNpZ25lZD4gUmVnc0JlaW5nU3BpbGxlZCA9IE5vbmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgQWxpYXNBbmFseXNpcyAqQUEgPSBudWxscHRyKTsKKworICAvLy8gY2FsY3VsYXRlUmVnQ2xhc3NBbmRIaW50IC0gUmVjb21wdXRlIHJlZ2lzdGVyIGNsYXNzIGFuZCBoaW50IGZvciBlYWNoIG5ldworICAvLy8gcmVnaXN0ZXIuCisgIHZvaWQgY2FsY3VsYXRlUmVnQ2xhc3NBbmRIaW50KE1hY2hpbmVGdW5jdGlvbiAmLCBjb25zdCBNYWNoaW5lTG9vcEluZm8gJiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mbyAmKTsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTElWRVJBTkdFRURJVF9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGl2ZVJlZ01hdHJpeC5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xpdmVSZWdNYXRyaXguaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNjJhNTVjCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xpdmVSZWdNYXRyaXguaApAQCAtMCwwICsxLDE2MCBAQAorLy89PT0tIExpdmVSZWdNYXRyaXguaCAtIFRyYWNrIHJlZ2lzdGVyIGludGVyZmVyZW5jZSAtLS0tLS0tLS0tKi0gQysrIC0qLS0tPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGUgTGl2ZVJlZ01hdHJpeCBhbmFseXNpcyBwYXNzIGtlZXBzIHRyYWNrIG9mIHZpcnR1YWwgcmVnaXN0ZXIgaW50ZXJmZXJlbmNlCisvLyBhbG9uZyB0d28gZGltZW5zaW9uczogU2xvdCBpbmRleGVzIGFuZCByZWdpc3RlciB1bml0cy4gVGhlIG1hdHJpeCBpcyB1c2VkIGJ5CisvLyByZWdpc3RlciBhbGxvY2F0b3JzIHRvIGVuc3VyZSB0aGF0IG5vIGludGVyZmVyaW5nIHZpcnR1YWwgcmVnaXN0ZXJzIGdldAorLy8gYXNzaWduZWQgdG8gb3ZlcmxhcHBpbmcgcGh5c2ljYWwgcmVnaXN0ZXJzLgorLy8KKy8vIFJlZ2lzdGVyIHVuaXRzIGFyZSBkZWZpbmVkIGluIE1DUmVnaXN0ZXJJbmZvLmgsIHRoZXkgcmVwcmVzZW50IHRoZSBzbWFsbGVzdAorLy8gdW5pdCBvZiBpbnRlcmZlcmVuY2Ugd2hlbiBkZWFsaW5nIHdpdGggb3ZlcmxhcHBpbmcgcGh5c2ljYWwgcmVnaXN0ZXJzLiBUaGUKKy8vIExpdmVSZWdNYXRyaXggaXMgcmVwcmVzZW50ZWQgYXMgYSBMaXZlSW50ZXJ2YWxVbmlvbiBwZXIgcmVnaXN0ZXIgdW5pdC4gV2hlbgorLy8gYSB2aXJ0dWFsIHJlZ2lzdGVyIGlzIGFzc2lnbmVkIHRvIGEgcGh5c2ljYWwgcmVnaXN0ZXIsIHRoZSBsaXZlIHJhbmdlIGZvcgorLy8gdGhlIHZpcnR1YWwgcmVnaXN0ZXIgaXMgaW5zZXJ0ZWQgaW50byB0aGUgTGl2ZUludGVydmFsVW5pb24gZm9yIGVhY2ggcmVndW5pdAorLy8gaW4gdGhlIHBoeXNyZWcuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTElWRVJFR01BVFJJWF9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9MSVZFUkVHTUFUUklYX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0JpdFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9MaXZlSW50ZXJ2YWxVbmlvbi5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lRnVuY3Rpb25QYXNzLmgiCisjaW5jbHVkZSA8bWVtb3J5PgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIEFuYWx5c2lzVXNhZ2U7CitjbGFzcyBMaXZlSW50ZXJ2YWw7CitjbGFzcyBMaXZlSW50ZXJ2YWxzOworY2xhc3MgTWFjaGluZUZ1bmN0aW9uOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJJbmZvOworY2xhc3MgVmlydFJlZ01hcDsKKworY2xhc3MgTGl2ZVJlZ01hdHJpeCA6IHB1YmxpYyBNYWNoaW5lRnVuY3Rpb25QYXNzIHsKKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkk7CisgIExpdmVJbnRlcnZhbHMgKkxJUzsKKyAgVmlydFJlZ01hcCAqVlJNOworCisgIC8vIFVzZXJUYWcgY2hhbmdlcyB3aGVuZXZlciB2aXJ0dWFsIHJlZ2lzdGVycyBoYXZlIGJlZW4gbW9kaWZpZWQuCisgIHVuc2lnbmVkIFVzZXJUYWcgPSAwOworCisgIC8vIFRoZSBtYXRyaXggaXMgcmVwcmVzZW50ZWQgYXMgYSBMaXZlSW50ZXJ2YWxVbmlvbiBwZXIgcmVnaXN0ZXIgdW5pdC4KKyAgTGl2ZUludGVydmFsVW5pb246OkFsbG9jYXRvciBMSVVBbGxvYzsKKyAgTGl2ZUludGVydmFsVW5pb246OkFycmF5IE1hdHJpeDsKKworICAvLyBDYWNoZWQgcXVlcmllcyBwZXIgcmVnaXN0ZXIgdW5pdC4KKyAgc3RkOjp1bmlxdWVfcHRyPExpdmVJbnRlcnZhbFVuaW9uOjpRdWVyeVtdPiBRdWVyaWVzOworCisgIC8vIENhY2hlZCByZWdpc3RlciBtYXNrIGludGVyZmVyZW5jZSBpbmZvLgorICB1bnNpZ25lZCBSZWdNYXNrVGFnID0gMDsKKyAgdW5zaWduZWQgUmVnTWFza1ZpcnRSZWcgPSAwOworICBCaXRWZWN0b3IgUmVnTWFza1VzYWJsZTsKKworICAvLyBNYWNoaW5lRnVuY3Rpb25QYXNzIGJvaWxlcnBsYXRlLgorICB2b2lkIGdldEFuYWx5c2lzVXNhZ2UoQW5hbHlzaXNVc2FnZSAmKSBjb25zdCBvdmVycmlkZTsKKyAgYm9vbCBydW5Pbk1hY2hpbmVGdW5jdGlvbihNYWNoaW5lRnVuY3Rpb24gJikgb3ZlcnJpZGU7CisgIHZvaWQgcmVsZWFzZU1lbW9yeSgpIG92ZXJyaWRlOworCitwdWJsaWM6CisgIHN0YXRpYyBjaGFyIElEOworCisgIExpdmVSZWdNYXRyaXgoKTsKKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gSGlnaC1sZXZlbCBpbnRlcmZhY2UuCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLworICAvLyBDaGVjayBmb3IgaW50ZXJmZXJlbmNlIGJlZm9yZSBhc3NpZ25pbmcgdmlydHVhbCByZWdpc3RlcnMgdG8gcGh5c2ljYWwKKyAgLy8gcmVnaXN0ZXJzLgorICAvLworCisgIC8vLyBJbnZhbGlkYXRlIGNhY2hlZCBpbnRlcmZlcmVuY2UgcXVlcmllcyBhZnRlciBtb2RpZnlpbmcgdmlydHVhbCByZWdpc3RlcgorICAvLy8gbGl2ZSByYW5nZXMuIEludGVyZmVyZW5jZSBjaGVja3MgbWF5IHJldHVybiBzdGFsZSBpbmZvcm1hdGlvbiB1bmxlc3MKKyAgLy8vIGNhY2hlcyBhcmUgaW52YWxpZGF0ZWQuCisgIHZvaWQgaW52YWxpZGF0ZVZpcnRSZWdzKCkgeyArK1VzZXJUYWc7IH0KKworICBlbnVtIEludGVyZmVyZW5jZUtpbmQgeworICAgIC8vLyBObyBpbnRlcmZlcmVuY2UsIGdvIGFoZWFkIGFuZCBhc3NpZ24uCisgICAgSUtfRnJlZSA9IDAsCisKKyAgICAvLy8gVmlydHVhbCByZWdpc3RlciBpbnRlcmZlcmVuY2UuIFRoZXJlIGFyZSBpbnRlcmZlcmluZyB2aXJ0dWFsIHJlZ2lzdGVycworICAgIC8vLyBhc3NpZ25lZCB0byBQaHlzUmVnIG9yIGl0cyBhbGlhc2VzLiBUaGlzIGludGVyZmVyZW5jZSBjb3VsZCBiZSByZXNvbHZlZAorICAgIC8vLyBieSB1bmFzc2lnbmluZyB0aG9zZSBvdGhlciB2aXJ0dWFsIHJlZ2lzdGVycy4KKyAgICBJS19WaXJ0UmVnLAorCisgICAgLy8vIFJlZ2lzdGVyIHVuaXQgaW50ZXJmZXJlbmNlLiBBIGZpeGVkIGxpdmUgcmFuZ2UgaXMgaW4gdGhlIHdheSwgdHlwaWNhbGx5CisgICAgLy8vIGFyZ3VtZW50IHJlZ2lzdGVycyBmb3IgYSBjYWxsLiBUaGlzIGNhbid0IGJlIHJlc29sdmVkIGJ5IHVuYXNzaWduaW5nCisgICAgLy8vIG90aGVyIHZpcnR1YWwgcmVnaXN0ZXJzLgorICAgIElLX1JlZ1VuaXQsCisKKyAgICAvLy8gUmVnTWFzayBpbnRlcmZlcmVuY2UuIFRoZSBsaXZlIHJhbmdlIGlzIGNyb3NzaW5nIGFuIGluc3RydWN0aW9uIHdpdGggYQorICAgIC8vLyByZWdtYXNrIG9wZXJhbmQgdGhhdCBkb2Vzbid0IHByZXNlcnZlIFBoeXNSZWcuIFRoaXMgdHlwaWNhbGx5IG1lYW5zCisgICAgLy8vIFZpcnRSZWcgaXMgbGl2ZSBhY3Jvc3MgYSBjYWxsLCBhbmQgUGh5c1JlZyBpc24ndCBjYWxsLXByZXNlcnZlZC4KKyAgICBJS19SZWdNYXNrCisgIH07CisKKyAgLy8vIENoZWNrIGZvciBpbnRlcmZlcmVuY2UgYmVmb3JlIGFzc2lnbmluZyBWaXJ0UmVnIHRvIFBoeXNSZWcuCisgIC8vLyBJZiB0aGlzIGZ1bmN0aW9uIHJldHVybnMgSUtfRnJlZSwgaXQgaXMgbGVnYWwgdG8gYXNzaWduKFZpcnRSZWcsIFBoeXNSZWcpLgorICAvLy8gV2hlbiB0aGVyZSBpcyBtb3JlIHRoYW4gb25lIGtpbmQgb2YgaW50ZXJmZXJlbmNlLCB0aGUgSW50ZXJmZXJlbmNlS2luZAorICAvLy8gd2l0aCB0aGUgaGlnaGVzdCBlbnVtIHZhbHVlIGlzIHJldHVybmVkLgorICBJbnRlcmZlcmVuY2VLaW5kIGNoZWNrSW50ZXJmZXJlbmNlKExpdmVJbnRlcnZhbCAmVmlydFJlZywgdW5zaWduZWQgUGh5c1JlZyk7CisKKyAgLy8vIENoZWNrIGZvciBpbnRlcmZlcmVuY2UgaW4gdGhlIHNlZ21lbnQgW1N0YXJ0LCBFbmQpIHRoYXQgbWF5IHByZXZlbnQKKyAgLy8vIGFzc2lnbm1lbnQgdG8gUGh5c1JlZy4gSWYgdGhpcyBmdW5jdGlvbiByZXR1cm5zIHRydWUsIHRoZXJlIGlzCisgIC8vLyBpbnRlcmZlcmVuY2UgaW4gdGhlIHNlZ21lbnQgW1N0YXJ0LCBFbmQpIG9mIHNvbWUgb3RoZXIgaW50ZXJ2YWwgYWxyZWFkeQorICAvLy8gYXNzaWduZWQgdG8gUGh5c1JlZy4gSWYgdGhpcyBmdW5jdGlvbiByZXR1cm5zIGZhbHNlLCBQaHlzUmVnIGlzIGZyZWUgYXQKKyAgLy8vIHRoZSBzZWdtZW50IFtTdGFydCwgRW5kKS4KKyAgYm9vbCBjaGVja0ludGVyZmVyZW5jZShTbG90SW5kZXggU3RhcnQsIFNsb3RJbmRleCBFbmQsIHVuc2lnbmVkIFBoeXNSZWcpOworCisgIC8vLyBBc3NpZ24gVmlydFJlZyB0byBQaHlzUmVnLgorICAvLy8gVGhpcyB3aWxsIG1hcmsgVmlydFJlZydzIGxpdmUgcmFuZ2UgYXMgb2NjdXBpZWQgaW4gdGhlIExpdmVSZWdNYXRyaXggYW5kCisgIC8vLyB1cGRhdGUgVmlydFJlZ01hcC4gVGhlIGxpdmUgcmFuZ2UgaXMgZXhwZWN0ZWQgdG8gYmUgYXZhaWxhYmxlIGluIFBoeXNSZWcuCisgIHZvaWQgYXNzaWduKExpdmVJbnRlcnZhbCAmVmlydFJlZywgdW5zaWduZWQgUGh5c1JlZyk7CisKKyAgLy8vIFVuYXNzaWduIFZpcnRSZWcgZnJvbSBpdHMgUGh5c1JlZy4KKyAgLy8vIEFzc3VtaW5nIHRoYXQgVmlydFJlZyB3YXMgcHJldmlvdXNseSBhc3NpZ25lZCB0byBhIFBoeXNSZWcsIHRoaXMgdW5kb2VzCisgIC8vLyB0aGUgYXNzaWdubWVudCBhbmQgdXBkYXRlcyBWaXJ0UmVnTWFwIGFjY29yZGluZ2x5LgorICB2b2lkIHVuYXNzaWduKExpdmVJbnRlcnZhbCAmVmlydFJlZyk7CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gXHAgUGh5c1JlZyBoYXMgYW55IGxpdmUgaW50ZXJ2YWxzIGFzc2lnbmVkLgorICBib29sIGlzUGh5c1JlZ1VzZWQodW5zaWduZWQgUGh5c1JlZykgY29uc3Q7CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIExvdy1sZXZlbCBpbnRlcmZhY2UuCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLworICAvLyBQcm92aWRlIGFjY2VzcyB0byB0aGUgdW5kZXJseWluZyBMaXZlSW50ZXJ2YWxVbmlvbnMuCisgIC8vCisKKyAgLy8vIENoZWNrIGZvciByZWdtYXNrIGludGVyZmVyZW5jZSBvbmx5LgorICAvLy8gUmV0dXJuIHRydWUgaWYgVmlydFJlZyBjcm9zc2VzIGEgcmVnbWFzayBvcGVyYW5kIHRoYXQgY2xvYmJlcnMgUGh5c1JlZy4KKyAgLy8vIElmIFBoeXNSZWcgaXMgbnVsbCwgY2hlY2sgaWYgVmlydFJlZyBjcm9zc2VzIGFueSByZWdtYXNrIG9wZXJhbmRzLgorICBib29sIGNoZWNrUmVnTWFza0ludGVyZmVyZW5jZShMaXZlSW50ZXJ2YWwgJlZpcnRSZWcsIHVuc2lnbmVkIFBoeXNSZWcgPSAwKTsKKworICAvLy8gQ2hlY2sgZm9yIHJlZ3VuaXQgaW50ZXJmZXJlbmNlIG9ubHkuCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBWaXJ0UmVnIG92ZXJsYXBzIGEgZml4ZWQgYXNzaWdubWVudCBvZiBvbmUgb2YgUGh5c1JlZ3MncworICAvLy8gcmVnaXN0ZXIgdW5pdHMuCisgIGJvb2wgY2hlY2tSZWdVbml0SW50ZXJmZXJlbmNlKExpdmVJbnRlcnZhbCAmVmlydFJlZywgdW5zaWduZWQgUGh5c1JlZyk7CisKKyAgLy8vIFF1ZXJ5IGEgbGluZSBvZiB0aGUgYXNzaWduZWQgdmlydHVhbCByZWdpc3RlciBtYXRyaXggZGlyZWN0bHkuCisgIC8vLyBVc2UgTUNSZWdVbml0SXRlcmF0b3IgdG8gZW51bWVyYXRlIGFsbCByZWd1bml0cyBpbiB0aGUgZGVzaXJlZCBQaHlzUmVnLgorICAvLy8gVGhpcyByZXR1cm5zIGEgcmVmZXJlbmNlIHRvIGFuIGludGVybmFsIFF1ZXJ5IGRhdGEgc3RydWN0dXJlIHRoYXQgaXMgb25seQorICAvLy8gdmFsaWQgdW50aWwgdGhlIG5leHQgcXVlcnkoKSBjYWxsLgorICBMaXZlSW50ZXJ2YWxVbmlvbjo6UXVlcnkgJnF1ZXJ5KGNvbnN0IExpdmVSYW5nZSAmTFIsIHVuc2lnbmVkIFJlZ1VuaXQpOworCisgIC8vLyBEaXJlY3RseSBhY2Nlc3MgdGhlIGxpdmUgaW50ZXJ2YWwgdW5pb25zIHBlciByZWd1bml0LgorICAvLy8gVGhpcyByZXR1cm5zIGFuIGFycmF5IGluZGV4ZWQgYnkgdGhlIHJlZ3VuaXQgbnVtYmVyLgorICBMaXZlSW50ZXJ2YWxVbmlvbiAqZ2V0TGl2ZVVuaW9ucygpIHsgcmV0dXJuICZNYXRyaXhbMF07IH0KK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTElWRVJFR01BVFJJWF9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGl2ZVJlZ1VuaXRzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGl2ZVJlZ1VuaXRzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGM0OTU2ZAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9MaXZlUmVnVW5pdHMuaApAQCAtMCwwICsxLDEzNSBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9MaXZlUmVnVW5pdHMuaCAtIFJlZ2lzdGVyIFVuaXQgU2V0IC0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLy8gXGZpbGUKKy8vLyBBIHNldCBvZiByZWdpc3RlciB1bml0cy4gSXQgaXMgaW50ZW5kZWQgZm9yIHJlZ2lzdGVyIGxpdmVuZXNzIHRyYWNraW5nLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0xJVkVSRUdVTklUU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9MSVZFUkVHVU5JVFNfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvQml0VmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1RhcmdldFJlZ2lzdGVySW5mby5oIgorI2luY2x1ZGUgImxsdm0vTUMvTGFuZUJpdG1hc2suaCIKKyNpbmNsdWRlICJsbHZtL01DL01DUmVnaXN0ZXJJbmZvLmgiCisjaW5jbHVkZSA8Y3N0ZGludD4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNYWNoaW5lSW5zdHI7CitjbGFzcyBNYWNoaW5lQmFzaWNCbG9jazsKKworLy8vIEEgc2V0IG9mIHJlZ2lzdGVyIHVuaXRzIHVzZWQgdG8gdHJhY2sgcmVnaXN0ZXIgbGl2ZW5lc3MuCitjbGFzcyBMaXZlUmVnVW5pdHMgeworICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSA9IG51bGxwdHI7CisgIEJpdFZlY3RvciBVbml0czsKKworcHVibGljOgorICAvLy8gQ29uc3RydWN0cyBhIG5ldyBlbXB0eSBMaXZlUmVnVW5pdHMgc2V0LgorICBMaXZlUmVnVW5pdHMoKSA9IGRlZmF1bHQ7CisKKyAgLy8vIENvbnN0cnVjdHMgYW5kIGluaXRpYWxpemUgYW4gZW1wdHkgTGl2ZVJlZ1VuaXRzIHNldC4KKyAgTGl2ZVJlZ1VuaXRzKGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAmVFJJKSB7CisgICAgaW5pdChUUkkpOworICB9CisKKyAgLy8vIEluaXRpYWxpemUgYW5kIGNsZWFyIHRoZSBzZXQuCisgIHZvaWQgaW5pdChjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gJlRSSSkgeworICAgIHRoaXMtPlRSSSA9ICZUUkk7CisgICAgVW5pdHMucmVzZXQoKTsKKyAgICBVbml0cy5yZXNpemUoVFJJLmdldE51bVJlZ1VuaXRzKCkpOworICB9CisKKyAgLy8vIENsZWFycyB0aGUgc2V0LgorICB2b2lkIGNsZWFyKCkgeyBVbml0cy5yZXNldCgpOyB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2V0IGlzIGVtcHR5LgorICBib29sIGVtcHR5KCkgY29uc3QgeyByZXR1cm4gVW5pdHMubm9uZSgpOyB9CisKKyAgLy8vIEFkZHMgcmVnaXN0ZXIgdW5pdHMgY292ZXJlZCBieSBwaHlzaWNhbCByZWdpc3RlciBccCBSZWcuCisgIHZvaWQgYWRkUmVnKHVuc2lnbmVkIFJlZykgeworICAgIGZvciAoTUNSZWdVbml0SXRlcmF0b3IgVW5pdChSZWcsIFRSSSk7IFVuaXQuaXNWYWxpZCgpOyArK1VuaXQpCisgICAgICBVbml0cy5zZXQoKlVuaXQpOworICB9CisKKyAgLy8vIFxicmllZiBBZGRzIHJlZ2lzdGVyIHVuaXRzIGNvdmVyZWQgYnkgcGh5c2ljYWwgcmVnaXN0ZXIgXHAgUmVnIHRoYXQgYXJlCisgIC8vLyBwYXJ0IG9mIHRoZSBsYW5lbWFzayBccCBNYXNrLgorICB2b2lkIGFkZFJlZ01hc2tlZCh1bnNpZ25lZCBSZWcsIExhbmVCaXRtYXNrIE1hc2spIHsKKyAgICBmb3IgKE1DUmVnVW5pdE1hc2tJdGVyYXRvciBVbml0KFJlZywgVFJJKTsgVW5pdC5pc1ZhbGlkKCk7ICsrVW5pdCkgeworICAgICAgTGFuZUJpdG1hc2sgVW5pdE1hc2sgPSAoKlVuaXQpLnNlY29uZDsKKyAgICAgIGlmIChVbml0TWFzay5ub25lKCkgfHwgKFVuaXRNYXNrICYgTWFzaykuYW55KCkpCisgICAgICAgIFVuaXRzLnNldCgoKlVuaXQpLmZpcnN0KTsKKyAgICB9CisgIH0KKworICAvLy8gUmVtb3ZlcyBhbGwgcmVnaXN0ZXIgdW5pdHMgY292ZXJlZCBieSBwaHlzaWNhbCByZWdpc3RlciBccCBSZWcuCisgIHZvaWQgcmVtb3ZlUmVnKHVuc2lnbmVkIFJlZykgeworICAgIGZvciAoTUNSZWdVbml0SXRlcmF0b3IgVW5pdChSZWcsIFRSSSk7IFVuaXQuaXNWYWxpZCgpOyArK1VuaXQpCisgICAgICBVbml0cy5yZXNldCgqVW5pdCk7CisgIH0KKworICAvLy8gUmVtb3ZlcyByZWdpc3RlciB1bml0cyBub3QgcHJlc2VydmVkIGJ5IHRoZSByZWdtYXNrIFxwIFJlZ01hc2suCisgIC8vLyBUaGUgcmVnbWFzayBoYXMgdGhlIHNhbWUgZm9ybWF0IGFzIHRoZSBvbmUgaW4gdGhlIFJlZ01hc2sgbWFjaGluZSBvcGVyYW5kLgorICB2b2lkIHJlbW92ZVJlZ3NOb3RQcmVzZXJ2ZWQoY29uc3QgdWludDMyX3QgKlJlZ01hc2spOworCisgIC8vLyBBZGRzIHJlZ2lzdGVyIHVuaXRzIG5vdCBwcmVzZXJ2ZWQgYnkgdGhlIHJlZ21hc2sgXHAgUmVnTWFzay4KKyAgLy8vIFRoZSByZWdtYXNrIGhhcyB0aGUgc2FtZSBmb3JtYXQgYXMgdGhlIG9uZSBpbiB0aGUgUmVnTWFzayBtYWNoaW5lIG9wZXJhbmQuCisgIHZvaWQgYWRkUmVnc0luTWFzayhjb25zdCB1aW50MzJfdCAqUmVnTWFzayk7CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiBubyBwYXJ0IG9mIHBoeXNpY2FsIHJlZ2lzdGVyIFxwIFJlZyBpcyBsaXZlLgorICBib29sIGF2YWlsYWJsZSh1bnNpZ25lZCBSZWcpIGNvbnN0IHsKKyAgICBmb3IgKE1DUmVnVW5pdEl0ZXJhdG9yIFVuaXQoUmVnLCBUUkkpOyBVbml0LmlzVmFsaWQoKTsgKytVbml0KSB7CisgICAgICBpZiAoVW5pdHMudGVzdCgqVW5pdCkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICB9CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLy8gVXBkYXRlcyBsaXZlbmVzcyB3aGVuIHN0ZXBwaW5nIGJhY2t3YXJkcyBvdmVyIHRoZSBpbnN0cnVjdGlvbiBccCBNSS4KKyAgLy8vIFRoaXMgcmVtb3ZlcyBhbGwgcmVnaXN0ZXIgdW5pdHMgZGVmaW5lZCBvciBjbG9iYmVyZWQgaW4gXHAgTUkgYW5kIHRoZW4KKyAgLy8vIGFkZHMgdGhlIHVuaXRzIHVzZWQgKGFzIGluIHVzZSBvcGVyYW5kcykgaW4gXHAgTUkuCisgIHZvaWQgc3RlcEJhY2t3YXJkKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpOworCisgIC8vLyBBZGRzIGFsbCByZWdpc3RlciB1bml0cyB1c2VkLCBkZWZpbmVkIG9yIGNsb2JiZXJlZCBpbiBccCBNSS4KKyAgLy8vIFRoaXMgaXMgdXNlZnVsIHdoZW4gd2Fsa2luZyBvdmVyIGEgcmFuZ2Ugb2YgaW5zdHJ1Y3Rpb24gdG8gZmluZCByZWdpc3RlcnMKKyAgLy8vIHVudXNlZCBvdmVyIHRoZSB3aG9sZSByYW5nZS4KKyAgdm9pZCBhY2N1bXVsYXRlKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpOworCisgIC8vLyBBZGRzIHJlZ2lzdGVycyBsaXZpbmcgb3V0IG9mIGJsb2NrIFxwIE1CQi4KKyAgLy8vIExpdmUgb3V0IHJlZ2lzdGVycyBhcmUgdGhlIHVuaW9uIG9mIHRoZSBsaXZlLWluIHJlZ2lzdGVycyBvZiB0aGUgc3VjY2Vzc29yCisgIC8vLyBibG9ja3MgYW5kIHByaXN0aW5lIHJlZ2lzdGVycy4gTGl2ZSBvdXQgcmVnaXN0ZXJzIG9mIHRoZSBlbmQgYmxvY2sgYXJlIHRoZQorICAvLy8gY2FsbGVlIHNhdmVkIHJlZ2lzdGVycy4KKyAgdm9pZCBhZGRMaXZlT3V0cyhjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAmTUJCKTsKKworICAvLy8gQWRkcyByZWdpc3RlcnMgbGl2aW5nIGludG8gYmxvY2sgXHAgTUJCLgorICB2b2lkIGFkZExpdmVJbnMoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgJk1CQik7CisKKyAgLy8vIEFkZHMgYWxsIHJlZ2lzdGVyIHVuaXRzIG1hcmtlZCBpbiB0aGUgYml0dmVjdG9yIFxwIFJlZ1VuaXRzLgorICB2b2lkIGFkZFVuaXRzKGNvbnN0IEJpdFZlY3RvciAmUmVnVW5pdHMpIHsKKyAgICBVbml0cyB8PSBSZWdVbml0czsKKyAgfQorICAvLy8gUmVtb3ZlcyBhbGwgcmVnaXN0ZXIgdW5pdHMgbWFya2VkIGluIHRoZSBiaXR2ZWN0b3IgXHAgUmVnVW5pdHMuCisgIHZvaWQgcmVtb3ZlVW5pdHMoY29uc3QgQml0VmVjdG9yICZSZWdVbml0cykgeworICAgIFVuaXRzLnJlc2V0KFJlZ1VuaXRzKTsKKyAgfQorICAvLy8gUmV0dXJuIHRoZSBpbnRlcm5hbCBiaXR2ZWN0b3IgcmVwcmVzZW50YXRpb24gb2YgdGhlIHNldC4KKyAgY29uc3QgQml0VmVjdG9yICZnZXRCaXRWZWN0b3IoKSBjb25zdCB7CisgICAgcmV0dXJuIFVuaXRzOworICB9CisKK3ByaXZhdGU6CisgIC8vLyBBZGRzIHByaXN0aW5lIHJlZ2lzdGVycy4gUHJpc3RpbmUgcmVnaXN0ZXJzIGFyZSBjYWxsZWUgc2F2ZWQgcmVnaXN0ZXJzCisgIC8vLyB0aGF0IGFyZSB1bnVzZWQgaW4gdGhlIGZ1bmN0aW9uLgorICB2b2lkIGFkZFByaXN0aW5lcyhjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKTsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTElWRVJFR1VOSVRTX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9MaXZlU3RhY2tzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGl2ZVN0YWNrcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0ZWQ3ODUKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGl2ZVN0YWNrcy5oCkBAIC0wLDAgKzEsMTAzIEBACisvLz09PS0gTGl2ZVN0YWNrcy5oIC0gTGl2ZSBTdGFjayBTbG90IEFuYWx5c2lzIC0tLS0tLS0tLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBpbXBsZW1lbnRzIHRoZSBsaXZlIHN0YWNrIHNsb3QgYW5hbHlzaXMgcGFzcy4gSXQgaXMgYW5hbG9nb3VzIHRvCisvLyBsaXZlIGludGVydmFsIGFuYWx5c2lzIGV4Y2VwdCBpdCdzIGFuYWx5emluZyBsaXZlbmVzcyBvZiBzdGFjayBzbG90cyByYXRoZXIKKy8vIHRoYW4gcmVnaXN0ZXJzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX0xJVkVTVEFDS1NfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTElWRVNUQUNLU19ICisKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTGl2ZUludGVydmFsLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvblBhc3MuaCIKKyNpbmNsdWRlICJsbHZtL1Bhc3MuaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDx1bm9yZGVyZWRfbWFwPgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIFRhcmdldFJlZ2lzdGVyQ2xhc3M7CitjbGFzcyBUYXJnZXRSZWdpc3RlckluZm87CisKK2NsYXNzIExpdmVTdGFja3MgOiBwdWJsaWMgTWFjaGluZUZ1bmN0aW9uUGFzcyB7CisgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJOworCisgIC8vLyBTcGVjaWFsIHBvb2wgYWxsb2NhdG9yIGZvciBWTkluZm8ncyAoTGl2ZUludGVydmFsIHZhbCMpLgorICAvLy8KKyAgVk5JbmZvOjpBbGxvY2F0b3IgVk5JbmZvQWxsb2NhdG9yOworCisgIC8vLyBTMklNYXAgLSBTdGFjayBzbG90IGluZGljZXMgdG8gbGl2ZSBpbnRlcnZhbCBtYXBwaW5nLgorICB1c2luZyBTUzJJbnRlcnZhbE1hcCA9IHN0ZDo6dW5vcmRlcmVkX21hcDxpbnQsIExpdmVJbnRlcnZhbD47CisgIFNTMkludGVydmFsTWFwIFMySU1hcDsKKworICAvLy8gUzJSQ01hcCAtIFN0YWNrIHNsb3QgaW5kaWNlcyB0byByZWdpc3RlciBjbGFzcyBtYXBwaW5nLgorICBzdGQ6Om1hcDxpbnQsIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKj4gUzJSQ01hcDsKKworcHVibGljOgorICBzdGF0aWMgY2hhciBJRDsgLy8gUGFzcyBpZGVudGlmaWNhdGlvbiwgcmVwbGFjZW1lbnQgZm9yIHR5cGVpZAorCisgIExpdmVTdGFja3MoKSA6IE1hY2hpbmVGdW5jdGlvblBhc3MoSUQpIHsKKyAgICBpbml0aWFsaXplTGl2ZVN0YWNrc1Bhc3MoKlBhc3NSZWdpc3RyeTo6Z2V0UGFzc1JlZ2lzdHJ5KCkpOworICB9CisKKyAgdXNpbmcgaXRlcmF0b3IgPSBTUzJJbnRlcnZhbE1hcDo6aXRlcmF0b3I7CisgIHVzaW5nIGNvbnN0X2l0ZXJhdG9yID0gU1MySW50ZXJ2YWxNYXA6OmNvbnN0X2l0ZXJhdG9yOworCisgIGNvbnN0X2l0ZXJhdG9yIGJlZ2luKCkgY29uc3QgeyByZXR1cm4gUzJJTWFwLmJlZ2luKCk7IH0KKyAgY29uc3RfaXRlcmF0b3IgZW5kKCkgY29uc3QgeyByZXR1cm4gUzJJTWFwLmVuZCgpOyB9CisgIGl0ZXJhdG9yIGJlZ2luKCkgeyByZXR1cm4gUzJJTWFwLmJlZ2luKCk7IH0KKyAgaXRlcmF0b3IgZW5kKCkgeyByZXR1cm4gUzJJTWFwLmVuZCgpOyB9CisKKyAgdW5zaWduZWQgZ2V0TnVtSW50ZXJ2YWxzKCkgY29uc3QgeyByZXR1cm4gKHVuc2lnbmVkKVMySU1hcC5zaXplKCk7IH0KKworICBMaXZlSW50ZXJ2YWwgJmdldE9yQ3JlYXRlSW50ZXJ2YWwoaW50IFNsb3QsIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKTsKKworICBMaXZlSW50ZXJ2YWwgJmdldEludGVydmFsKGludCBTbG90KSB7CisgICAgYXNzZXJ0KFNsb3QgPj0gMCAmJiAiU3BpbGwgc2xvdCBpbmRpY2UgbXVzdCBiZSA+PSAwIik7CisgICAgU1MySW50ZXJ2YWxNYXA6Oml0ZXJhdG9yIEkgPSBTMklNYXAuZmluZChTbG90KTsKKyAgICBhc3NlcnQoSSAhPSBTMklNYXAuZW5kKCkgJiYgIkludGVydmFsIGRvZXMgbm90IGV4aXN0IGZvciBzdGFjayBzbG90Iik7CisgICAgcmV0dXJuIEktPnNlY29uZDsKKyAgfQorCisgIGNvbnN0IExpdmVJbnRlcnZhbCAmZ2V0SW50ZXJ2YWwoaW50IFNsb3QpIGNvbnN0IHsKKyAgICBhc3NlcnQoU2xvdCA+PSAwICYmICJTcGlsbCBzbG90IGluZGljZSBtdXN0IGJlID49IDAiKTsKKyAgICBTUzJJbnRlcnZhbE1hcDo6Y29uc3RfaXRlcmF0b3IgSSA9IFMySU1hcC5maW5kKFNsb3QpOworICAgIGFzc2VydChJICE9IFMySU1hcC5lbmQoKSAmJiAiSW50ZXJ2YWwgZG9lcyBub3QgZXhpc3QgZm9yIHN0YWNrIHNsb3QiKTsKKyAgICByZXR1cm4gSS0+c2Vjb25kOworICB9CisKKyAgYm9vbCBoYXNJbnRlcnZhbChpbnQgU2xvdCkgY29uc3QgeyByZXR1cm4gUzJJTWFwLmNvdW50KFNsb3QpOyB9CisKKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqZ2V0SW50ZXJ2YWxSZWdDbGFzcyhpbnQgU2xvdCkgY29uc3QgeworICAgIGFzc2VydChTbG90ID49IDAgJiYgIlNwaWxsIHNsb3QgaW5kaWNlIG11c3QgYmUgPj0gMCIpOworICAgIHN0ZDo6bWFwPGludCwgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqPjo6Y29uc3RfaXRlcmF0b3IgSSA9CisgICAgICAgIFMyUkNNYXAuZmluZChTbG90KTsKKyAgICBhc3NlcnQoSSAhPSBTMlJDTWFwLmVuZCgpICYmCisgICAgICAgICAgICJSZWdpc3RlciBjbGFzcyBpbmZvIGRvZXMgbm90IGV4aXN0IGZvciBzdGFjayBzbG90Iik7CisgICAgcmV0dXJuIEktPnNlY29uZDsKKyAgfQorCisgIFZOSW5mbzo6QWxsb2NhdG9yICZnZXRWTkluZm9BbGxvY2F0b3IoKSB7IHJldHVybiBWTkluZm9BbGxvY2F0b3I7IH0KKworICB2b2lkIGdldEFuYWx5c2lzVXNhZ2UoQW5hbHlzaXNVc2FnZSAmQVUpIGNvbnN0IG92ZXJyaWRlOworICB2b2lkIHJlbGVhc2VNZW1vcnkoKSBvdmVycmlkZTsKKworICAvLy8gcnVuT25NYWNoaW5lRnVuY3Rpb24gLSBwYXNzIGVudHJ5IHBvaW50CisgIGJvb2wgcnVuT25NYWNoaW5lRnVuY3Rpb24oTWFjaGluZUZ1bmN0aW9uICYpIG92ZXJyaWRlOworCisgIC8vLyBwcmludCAtIEltcGxlbWVudCB0aGUgZHVtcCBtZXRob2QuCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk8sIGNvbnN0IE1vZHVsZSAqID0gbnVsbHB0cikgY29uc3Qgb3ZlcnJpZGU7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9MaXZlVmFyaWFibGVzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGl2ZVZhcmlhYmxlcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVkOGRhODYKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTGl2ZVZhcmlhYmxlcy5oCkBAIC0wLDAgKzEsMzA5IEBACisvLz09PS0tIGxsdm0vQ29kZUdlbi9MaXZlVmFyaWFibGVzLmggLSBMaXZlIFZhcmlhYmxlIEFuYWx5c2lzIC0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBpbXBsZW1lbnRzIHRoZSBMaXZlVmFyaWFibGVzIGFuYWx5c2lzIHBhc3MuICBGb3IgZWFjaCBtYWNoaW5lCisvLyBpbnN0cnVjdGlvbiBpbiB0aGUgZnVuY3Rpb24sIHRoaXMgcGFzcyBjYWxjdWxhdGVzIHRoZSBzZXQgb2YgcmVnaXN0ZXJzIHRoYXQKKy8vIGFyZSBpbW1lZGlhdGVseSBkZWFkIGFmdGVyIHRoZSBpbnN0cnVjdGlvbiAoaS5lLiwgdGhlIGluc3RydWN0aW9uIGNhbGN1bGF0ZXMKKy8vIHRoZSB2YWx1ZSwgYnV0IGl0IGlzIG5ldmVyIHVzZWQpIGFuZCB0aGUgc2V0IG9mIHJlZ2lzdGVycyB0aGF0IGFyZSB1c2VkIGJ5CisvLyB0aGUgaW5zdHJ1Y3Rpb24sIGJ1dCBhcmUgbmV2ZXIgdXNlZCBhZnRlciB0aGUgaW5zdHJ1Y3Rpb24gKGkuZS4sIHRoZXkgYXJlCisvLyBraWxsZWQpLgorLy8KKy8vIFRoaXMgY2xhc3MgY29tcHV0ZXMgbGl2ZSB2YXJpYWJsZXMgdXNpbmcgYSBzcGFyc2UgaW1wbGVtZW50YXRpb24gYmFzZWQgb24KKy8vIHRoZSBtYWNoaW5lIGNvZGUgU1NBIGZvcm0uICBUaGlzIGNsYXNzIGNvbXB1dGVzIGxpdmUgdmFyaWFibGUgaW5mb3JtYXRpb24gZm9yCisvLyBlYWNoIHZpcnR1YWwgYW5kIF9yZWdpc3RlciBhbGxvY2F0YWJsZV8gcGh5c2ljYWwgcmVnaXN0ZXIgaW4gYSBmdW5jdGlvbi4gIEl0CisvLyB1c2VzIHRoZSBkb21pbmFuY2UgcHJvcGVydGllcyBvZiBTU0EgZm9ybSB0byBlZmZpY2llbnRseSBjb21wdXRlIGxpdmUKKy8vIHZhcmlhYmxlcyBmb3IgdmlydHVhbCByZWdpc3RlcnMsIGFuZCBhc3N1bWVzIHRoYXQgcGh5c2ljYWwgcmVnaXN0ZXJzIGFyZSBvbmx5CisvLyBsaXZlIHdpdGhpbiBhIHNpbmdsZSBiYXNpYyBibG9jayAoYWxsb3dpbmcgaXQgdG8gZG8gYSBzaW5nbGUgbG9jYWwgYW5hbHlzaXMKKy8vIHRvIHJlc29sdmUgcGh5c2ljYWwgcmVnaXN0ZXIgbGlmZXRpbWVzIGluIGVhY2ggYmFzaWMgYmxvY2spLiAgSWYgYSBwaHlzaWNhbAorLy8gcmVnaXN0ZXIgaXMgbm90IHJlZ2lzdGVyIGFsbG9jYXRhYmxlLCBpdCBpcyBub3QgdHJhY2tlZC4gIFRoaXMgaXMgdXNlZnVsIGZvcgorLy8gdGhpbmdzIGxpa2UgdGhlIHN0YWNrIHBvaW50ZXIgYW5kIGNvbmRpdGlvbiBjb2Rlcy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9MSVZFVkFSSUFCTEVTX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX0xJVkVWQVJJQUJMRVNfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9JbmRleGVkTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxTZXQuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NwYXJzZUJpdFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lRnVuY3Rpb25QYXNzLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVJbnN0ci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9UYXJnZXRSZWdpc3RlckluZm8uaCIKKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNYWNoaW5lQmFzaWNCbG9jazsKK2NsYXNzIE1hY2hpbmVSZWdpc3RlckluZm87CisKK2NsYXNzIExpdmVWYXJpYWJsZXMgOiBwdWJsaWMgTWFjaGluZUZ1bmN0aW9uUGFzcyB7CitwdWJsaWM6CisgIHN0YXRpYyBjaGFyIElEOyAvLyBQYXNzIGlkZW50aWZpY2F0aW9uLCByZXBsYWNlbWVudCBmb3IgdHlwZWlkCisgIExpdmVWYXJpYWJsZXMoKSA6IE1hY2hpbmVGdW5jdGlvblBhc3MoSUQpIHsKKyAgICBpbml0aWFsaXplTGl2ZVZhcmlhYmxlc1Bhc3MoKlBhc3NSZWdpc3RyeTo6Z2V0UGFzc1JlZ2lzdHJ5KCkpOworICB9CisKKyAgLy8vIFZhckluZm8gLSBUaGlzIHJlcHJlc2VudHMgdGhlIHJlZ2lvbnMgd2hlcmUgYSB2aXJ0dWFsIHJlZ2lzdGVyIGlzIGxpdmUgaW4KKyAgLy8vIHRoZSBwcm9ncmFtLiAgV2UgcmVwcmVzZW50IHRoaXMgd2l0aCB0aHJlZSBkaWZmZXJlbnQgcGllY2VzIG9mCisgIC8vLyBpbmZvcm1hdGlvbjogdGhlIHNldCBvZiBibG9ja3MgaW4gd2hpY2ggdGhlIGluc3RydWN0aW9uIGlzIGxpdmUKKyAgLy8vIHRocm91Z2hvdXQsIHRoZSBzZXQgb2YgYmxvY2tzIGluIHdoaWNoIHRoZSBpbnN0cnVjdGlvbiBpcyBhY3R1YWxseSB1c2VkLAorICAvLy8gYW5kIHRoZSBzZXQgb2Ygbm9uLXBoaSBpbnN0cnVjdGlvbnMgdGhhdCBhcmUgdGhlIGxhc3QgdXNlcnMgb2YgdGhlIHZhbHVlLgorICAvLy8KKyAgLy8vIEluIHRoZSBjb21tb24gY2FzZSB3aGVyZSBhIHZhbHVlIGlzIGRlZmluZWQgYW5kIGtpbGxlZCBpbiB0aGUgc2FtZSBibG9jaywKKyAgLy8vIFRoZXJlIGlzIG9uZSBraWxsaW5nIGluc3RydWN0aW9uLCBhbmQgQWxpdmVCbG9ja3MgaXMgZW1wdHkuCisgIC8vLworICAvLy8gT3RoZXJ3aXNlLCB0aGUgdmFsdWUgaXMgbGl2ZSBvdXQgb2YgdGhlIGJsb2NrLiAgSWYgdGhlIHZhbHVlIGlzIGxpdmUKKyAgLy8vIHRocm91Z2hvdXQgYW55IGJsb2NrcywgdGhlc2UgYmxvY2tzIGFyZSBsaXN0ZWQgaW4gQWxpdmVCbG9ja3MuICBCbG9ja3MKKyAgLy8vIHdoZXJlIHRoZSBsaXZlbmVzcyByYW5nZSBlbmRzIGFyZSBub3QgaW5jbHVkZWQgaW4gQWxpdmVCbG9ja3MsIGluc3RlYWQKKyAgLy8vIGJlaW5nIGNhcHR1cmVkIGJ5IHRoZSBLaWxscyBzZXQuICBJbiB0aGVzZSBibG9ja3MsIHRoZSB2YWx1ZSBpcyBsaXZlIGludG8KKyAgLy8vIHRoZSBibG9jayAodW5sZXNzIHRoZSB2YWx1ZSBpcyBkZWZpbmVkIGFuZCBraWxsZWQgaW4gdGhlIHNhbWUgYmxvY2spIGFuZAorICAvLy8gbGl2ZXMgdW50aWwgdGhlIHNwZWNpZmllZCBpbnN0cnVjdGlvbi4gIE5vdGUgdGhhdCB0aGVyZSBjYW5ub3QgZXZlciBiZSBhCisgIC8vLyB2YWx1ZSB3aG9zZSBLaWxscyBzZXQgY29udGFpbnMgdHdvIGluc3RydWN0aW9ucyBmcm9tIHRoZSBzYW1lIGJhc2ljIGJsb2NrLgorICAvLy8KKyAgLy8vIFBISSBub2RlcyBjb21wbGljYXRlIHRoaW5ncyBhIGJpdC4gIElmIGEgUEhJIG5vZGUgaXMgdGhlIGxhc3QgdXNlciBvZiBhCisgIC8vLyB2YWx1ZSBpbiBvbmUgb2YgaXRzIHByZWRlY2Vzc29yIGJsb2NrcywgaXQgaXMgbm90IGxpc3RlZCBpbiB0aGUga2lsbHMgc2V0LAorICAvLy8gYnV0IGRvZXMgaW5jbHVkZSB0aGUgcHJlZGVjZXNzb3IgYmxvY2sgaW4gdGhlIEFsaXZlQmxvY2tzIHNldCAodW5sZXNzIHRoYXQKKyAgLy8vIGJsb2NrIGFsc28gZGVmaW5lcyB0aGUgdmFsdWUpLiAgVGhpcyBsZWFkcyB0byB0aGUgKHBlcmZlY3RseSBzZW5zaWNhbCkKKyAgLy8vIHNpdHVhdGlvbiB3aGVyZSBhIHZhbHVlIGlzIGRlZmluZWQgaW4gYSBibG9jaywgYW5kIHRoZSBsYXN0IHVzZSBpcyBhIHBoaQorICAvLy8gbm9kZSBpbiB0aGUgc3VjY2Vzc29yLiAgSW4gdGhpcyBjYXNlLCBBbGl2ZUJsb2NrcyBpcyBlbXB0eSAodGhlIHZhbHVlIGlzCisgIC8vLyBub3QgbGl2ZSBhY3Jvc3MgYW55ICBibG9ja3MpIGFuZCBLaWxscyBpcyBlbXB0eSAocGhpIG5vZGVzIGFyZSBub3QKKyAgLy8vIGluY2x1ZGVkKS4gVGhpcyBpcyBzZW5zaWNhbCBiZWNhdXNlIHRoZSB2YWx1ZSBtdXN0IGJlIGxpdmUgdG8gdGhlIGVuZCBvZgorICAvLy8gdGhlIGJsb2NrLCBidXQgaXMgbm90IGxpdmUgaW4gYW55IHN1Y2Nlc3NvciBibG9ja3MuCisgIHN0cnVjdCBWYXJJbmZvIHsKKyAgICAvLy8gQWxpdmVCbG9ja3MgLSBTZXQgb2YgYmxvY2tzIGluIHdoaWNoIHRoaXMgdmFsdWUgaXMgYWxpdmUgY29tcGxldGVseQorICAgIC8vLyB0aHJvdWdoLiAgVGhpcyBpcyBhIGJpdCBzZXQgd2hpY2ggdXNlcyB0aGUgYmFzaWMgYmxvY2sgbnVtYmVyIGFzIGFuCisgICAgLy8vIGluZGV4LgorICAgIC8vLworICAgIFNwYXJzZUJpdFZlY3Rvcjw+IEFsaXZlQmxvY2tzOworCisgICAgLy8vIEtpbGxzIC0gTGlzdCBvZiBNYWNoaW5lSW5zdHJ1Y3Rpb24ncyB3aGljaCBhcmUgdGhlIGxhc3QgdXNlIG9mIHRoaXMKKyAgICAvLy8gdmlydHVhbCByZWdpc3RlciAoa2lsbCBpdCkgaW4gdGhlaXIgYmFzaWMgYmxvY2suCisgICAgLy8vCisgICAgc3RkOjp2ZWN0b3I8TWFjaGluZUluc3RyKj4gS2lsbHM7CisKKyAgICAvLy8gcmVtb3ZlS2lsbCAtIERlbGV0ZSBhIGtpbGwgY29ycmVzcG9uZGluZyB0byB0aGUgc3BlY2lmaWVkCisgICAgLy8vIG1hY2hpbmUgaW5zdHJ1Y3Rpb24uIFJldHVybnMgdHJ1ZSBpZiB0aGVyZSB3YXMgYSBraWxsCisgICAgLy8vIGNvcnJlc3BvbmRpbmcgdG8gdGhpcyBpbnN0cnVjdGlvbiwgZmFsc2Ugb3RoZXJ3aXNlLgorICAgIGJvb2wgcmVtb3ZlS2lsbChNYWNoaW5lSW5zdHIgJk1JKSB7CisgICAgICBzdGQ6OnZlY3RvcjxNYWNoaW5lSW5zdHIgKj46Oml0ZXJhdG9yIEkgPSBmaW5kKEtpbGxzLCAmTUkpOworICAgICAgaWYgKEkgPT0gS2lsbHMuZW5kKCkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIEtpbGxzLmVyYXNlKEkpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgLy8vIGZpbmRLaWxsIC0gRmluZCBhIGtpbGwgaW5zdHJ1Y3Rpb24gaW4gTUJCLiBSZXR1cm4gTlVMTCBpZiBub25lIGlzIGZvdW5kLgorICAgIE1hY2hpbmVJbnN0ciAqZmluZEtpbGwoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKk1CQikgY29uc3Q7CisKKyAgICAvLy8gaXNMaXZlSW4gLSBJcyBSZWcgbGl2ZSBpbiB0byBNQkI/IFRoaXMgbWVhbnMgdGhhdCBSZWcgaXMgbGl2ZSB0aHJvdWdoCisgICAgLy8vIE1CQiwgb3IgaXQgaXMga2lsbGVkIGluIE1CQi4gSWYgUmVnIGlzIG9ubHkgdXNlZCBieSBQSEkgaW5zdHJ1Y3Rpb25zIGluCisgICAgLy8vIE1CQiwgaXQgaXMgbm90IGNvbnNpZGVyZWQgbGl2ZSBpbi4KKyAgICBib29sIGlzTGl2ZUluKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBSZWcsCisgICAgICAgICAgICAgICAgICBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkkpOworCisgICAgdm9pZCBkdW1wKCkgY29uc3Q7CisgIH07CisKK3ByaXZhdGU6CisgIC8vLyBWaXJ0UmVnSW5mbyAtIFRoaXMgbGlzdCBpcyBhIG1hcHBpbmcgZnJvbSB2aXJ0dWFsIHJlZ2lzdGVyIG51bWJlciB0bworICAvLy8gdmFyaWFibGUgaW5mb3JtYXRpb24uCisgIC8vLworICBJbmRleGVkTWFwPFZhckluZm8sIFZpcnRSZWcySW5kZXhGdW5jdG9yPiBWaXJ0UmVnSW5mbzsKKworICAvLy8gUEhJSm9pbnMgLSBsaXN0IG9mIHZpcnR1YWwgcmVnaXN0ZXJzIHRoYXQgYXJlIFBISSBqb2lucy4gVGhlc2UgcmVnaXN0ZXJzCisgIC8vLyBtYXkgaGF2ZSBtdWx0aXBsZSBkZWZpbml0aW9ucywgYW5kIHRoZXkgcmVxdWlyZSBzcGVjaWFsIGhhbmRsaW5nIHdoZW4KKyAgLy8vIGJ1aWxkaW5nIGxpdmUgaW50ZXJ2YWxzLgorICBTcGFyc2VCaXRWZWN0b3I8PiBQSElKb2luczsKKworcHJpdmF0ZTogICAvLyBJbnRlcm1lZGlhdGUgZGF0YSBzdHJ1Y3R1cmVzCisgIE1hY2hpbmVGdW5jdGlvbiAqTUY7CisKKyAgTWFjaGluZVJlZ2lzdGVySW5mbyogTVJJOworCisgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJOworCisgIC8vIFBoeXNSZWdJbmZvIC0gS2VlcCB0cmFjayBvZiB3aGljaCBpbnN0cnVjdGlvbiB3YXMgdGhlIGxhc3QgZGVmIG9mIGEKKyAgLy8gcGh5c2ljYWwgcmVnaXN0ZXIuIFRoaXMgaXMgYSBwdXJlbHkgbG9jYWwgcHJvcGVydHksIGJlY2F1c2UgYWxsIHBoeXNpY2FsCisgIC8vIHJlZ2lzdGVyIHJlZmVyZW5jZXMgYXJlIHByZXN1bWVkIGRlYWQgYWNyb3NzIGJhc2ljIGJsb2Nrcy4KKyAgc3RkOjp2ZWN0b3I8TWFjaGluZUluc3RyICo+IFBoeXNSZWdEZWY7CisKKyAgLy8gUGh5c1JlZ0luZm8gLSBLZWVwIHRyYWNrIG9mIHdoaWNoIGluc3RydWN0aW9uIHdhcyB0aGUgbGFzdCB1c2Ugb2YgYQorICAvLyBwaHlzaWNhbCByZWdpc3Rlci4gVGhpcyBpcyBhIHB1cmVseSBsb2NhbCBwcm9wZXJ0eSwgYmVjYXVzZSBhbGwgcGh5c2ljYWwKKyAgLy8gcmVnaXN0ZXIgcmVmZXJlbmNlcyBhcmUgcHJlc3VtZWQgZGVhZCBhY3Jvc3MgYmFzaWMgYmxvY2tzLgorICBzdGQ6OnZlY3RvcjxNYWNoaW5lSW5zdHIgKj4gUGh5c1JlZ1VzZTsKKworICBzdGQ6OnZlY3RvcjxTbWFsbFZlY3Rvcjx1bnNpZ25lZCwgND4+IFBISVZhckluZm87CisKKyAgLy8gRGlzdGFuY2VNYXAgLSBLZWVwIHRyYWNrIHRoZSBkaXN0YW5jZSBvZiBhIE1JIGZyb20gdGhlIHN0YXJ0IG9mIHRoZQorICAvLyBjdXJyZW50IGJhc2ljIGJsb2NrLgorICBEZW5zZU1hcDxNYWNoaW5lSW5zdHIqLCB1bnNpZ25lZD4gRGlzdGFuY2VNYXA7CisKKyAgLy8vIEhhbmRsZVBoeXNSZWdLaWxsIC0gQWRkIGtpbGxzIG9mIFJlZyBhbmQgaXRzIHN1Yi1yZWdpc3RlcnMgdG8gdGhlCisgIC8vLyB1c2VzLiBQYXkgc3BlY2lhbCBhdHRlbnRpb24gdG8gdGhlIHN1Yi1yZWdpc3RlciB1c2VzIHdoaWNoIG1heSBjb21lIGJlbG93CisgIC8vLyB0aGUgbGFzdCB1c2Ugb2YgdGhlIHdob2xlIHJlZ2lzdGVyLgorICBib29sIEhhbmRsZVBoeXNSZWdLaWxsKHVuc2lnbmVkIFJlZywgTWFjaGluZUluc3RyICpNSSk7CisKKyAgLy8vIEhhbmRsZVJlZ01hc2sgLSBDYWxsIEhhbmRsZVBoeXNSZWdLaWxsIGZvciBhbGwgcmVnaXN0ZXJzIGNsb2JiZXJlZCBieSBNYXNrLgorICB2b2lkIEhhbmRsZVJlZ01hc2soY29uc3QgTWFjaGluZU9wZXJhbmQmKTsKKworICB2b2lkIEhhbmRsZVBoeXNSZWdVc2UodW5zaWduZWQgUmVnLCBNYWNoaW5lSW5zdHIgJk1JKTsKKyAgdm9pZCBIYW5kbGVQaHlzUmVnRGVmKHVuc2lnbmVkIFJlZywgTWFjaGluZUluc3RyICpNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDx1bnNpZ25lZD4gJkRlZnMpOworICB2b2lkIFVwZGF0ZVBoeXNSZWdEZWZzKE1hY2hpbmVJbnN0ciAmTUksIFNtYWxsVmVjdG9ySW1wbDx1bnNpZ25lZD4gJkRlZnMpOworCisgIC8vLyBGaW5kTGFzdFJlZk9yUGFydFJlZiAtIFJldHVybiB0aGUgbGFzdCByZWZlcmVuY2Ugb3IgcGFydGlhbCByZWZlcmVuY2Ugb2YKKyAgLy8vIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIuCisgIE1hY2hpbmVJbnN0ciAqRmluZExhc3RSZWZPclBhcnRSZWYodW5zaWduZWQgUmVnKTsKKworICAvLy8gRmluZExhc3RQYXJ0aWFsRGVmIC0gUmV0dXJuIHRoZSBsYXN0IHBhcnRpYWwgZGVmIG9mIHRoZSBzcGVjaWZpZWQKKyAgLy8vIHJlZ2lzdGVyLiBBbHNvIHJldHVybnMgdGhlIHN1Yi1yZWdpc3RlcnMgdGhhdCdyZSBkZWZpbmVkIGJ5IHRoZQorICAvLy8gaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ciAqRmluZExhc3RQYXJ0aWFsRGVmKHVuc2lnbmVkIFJlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU21hbGxTZXQ8dW5zaWduZWQsND4gJlBhcnREZWZSZWdzKTsKKworICAvLy8gYW5hbHl6ZVBISU5vZGVzIC0gR2F0aGVyIGluZm9ybWF0aW9uIGFib3V0IHRoZSBQSEkgbm9kZXMgaW4gaGVyZS4gSW4KKyAgLy8vIHBhcnRpY3VsYXIsIHdlIHdhbnQgdG8gbWFwIHRoZSB2YXJpYWJsZSBpbmZvcm1hdGlvbiBvZiBhIHZpcnR1YWwKKyAgLy8vIHJlZ2lzdGVyIHdoaWNoIGlzIHVzZWQgaW4gYSBQSEkgbm9kZS4gV2UgbWFwIHRoYXQgdG8gdGhlIEJCIHRoZSB2cmVnCisgIC8vLyBpcyBjb21pbmcgZnJvbS4KKyAgdm9pZCBhbmFseXplUEhJTm9kZXMoY29uc3QgTWFjaGluZUZ1bmN0aW9uJiBGbik7CisKKyAgdm9pZCBydW5Pbkluc3RyKE1hY2hpbmVJbnN0ciAmTUksIFNtYWxsVmVjdG9ySW1wbDx1bnNpZ25lZD4gJkRlZnMpOworCisgIHZvaWQgcnVuT25CbG9jayhNYWNoaW5lQmFzaWNCbG9jayAqTUJCLCB1bnNpZ25lZCBOdW1SZWdzKTsKK3B1YmxpYzoKKworICBib29sIHJ1bk9uTWFjaGluZUZ1bmN0aW9uKE1hY2hpbmVGdW5jdGlvbiAmTUYpIG92ZXJyaWRlOworCisgIC8vLyBSZWdpc3RlckRlZklzRGVhZCAtIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24gZGVmaW5lcyB0aGUKKyAgLy8vIHNwZWNpZmllZCByZWdpc3RlciwgYnV0IHRoYXQgZGVmaW5pdGlvbiBpcyBkZWFkLgorICBib29sIFJlZ2lzdGVyRGVmSXNEZWFkKE1hY2hpbmVJbnN0ciAmTUksIHVuc2lnbmVkIFJlZykgY29uc3Q7CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vICBBUEkgdG8gdXBkYXRlIGxpdmUgdmFyaWFibGUgaW5mb3JtYXRpb24KKworICAvLy8gcmVwbGFjZUtpbGxJbnN0cnVjdGlvbiAtIFVwZGF0ZSByZWdpc3RlciBraWxsIGluZm8gYnkgcmVwbGFjaW5nIGEga2lsbAorICAvLy8gaW5zdHJ1Y3Rpb24gd2l0aCBhIG5ldyBvbmUuCisgIHZvaWQgcmVwbGFjZUtpbGxJbnN0cnVjdGlvbih1bnNpZ25lZCBSZWcsIE1hY2hpbmVJbnN0ciAmT2xkTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSW5zdHIgJk5ld01JKTsKKworICAvLy8gYWRkVmlydHVhbFJlZ2lzdGVyS2lsbGVkIC0gQWRkIGluZm9ybWF0aW9uIGFib3V0IHRoZSBmYWN0IHRoYXQgdGhlCisgIC8vLyBzcGVjaWZpZWQgcmVnaXN0ZXIgaXMga2lsbGVkIGFmdGVyIGJlaW5nIHVzZWQgYnkgdGhlIHNwZWNpZmllZAorICAvLy8gaW5zdHJ1Y3Rpb24uIElmIEFkZElmTm90Rm91bmQgaXMgdHJ1ZSwgYWRkIGEgaW1wbGljaXQgb3BlcmFuZCBpZiBpdCdzCisgIC8vLyBub3QgZm91bmQuCisgIHZvaWQgYWRkVmlydHVhbFJlZ2lzdGVyS2lsbGVkKHVuc2lnbmVkIEluY29taW5nUmVnLCBNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIEFkZElmTm90Rm91bmQgPSBmYWxzZSkgeworICAgIGlmIChNSS5hZGRSZWdpc3RlcktpbGxlZChJbmNvbWluZ1JlZywgVFJJLCBBZGRJZk5vdEZvdW5kKSkKKyAgICAgIGdldFZhckluZm8oSW5jb21pbmdSZWcpLktpbGxzLnB1c2hfYmFjaygmTUkpOworICB9CisKKyAgLy8vIHJlbW92ZVZpcnR1YWxSZWdpc3RlcktpbGxlZCAtIFJlbW92ZSB0aGUgc3BlY2lmaWVkIGtpbGwgb2YgdGhlIHZpcnR1YWwKKyAgLy8vIHJlZ2lzdGVyIGZyb20gdGhlIGxpdmUgdmFyaWFibGUgaW5mb3JtYXRpb24uIFJldHVybnMgdHJ1ZSBpZiB0aGUKKyAgLy8vIHZhcmlhYmxlIHdhcyBtYXJrZWQgYXMga2lsbGVkIGJ5IHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24sCisgIC8vLyBmYWxzZSBvdGhlcndpc2UuCisgIGJvb2wgcmVtb3ZlVmlydHVhbFJlZ2lzdGVyS2lsbGVkKHVuc2lnbmVkIHJlZywgTWFjaGluZUluc3RyICZNSSkgeworICAgIGlmICghZ2V0VmFySW5mbyhyZWcpLnJlbW92ZUtpbGwoTUkpKQorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgYm9vbCBSZW1vdmVkID0gZmFsc2U7CisgICAgZm9yICh1bnNpZ25lZCBpID0gMCwgZSA9IE1JLmdldE51bU9wZXJhbmRzKCk7IGkgIT0gZTsgKytpKSB7CisgICAgICBNYWNoaW5lT3BlcmFuZCAmTU8gPSBNSS5nZXRPcGVyYW5kKGkpOworICAgICAgaWYgKE1PLmlzUmVnKCkgJiYgTU8uaXNLaWxsKCkgJiYgTU8uZ2V0UmVnKCkgPT0gcmVnKSB7CisgICAgICAgIE1PLnNldElzS2lsbChmYWxzZSk7CisgICAgICAgIFJlbW92ZWQgPSB0cnVlOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisKKyAgICBhc3NlcnQoUmVtb3ZlZCAmJiAiUmVnaXN0ZXIgaXMgbm90IHVzZWQgYnkgdGhpcyBpbnN0cnVjdGlvbiEiKTsKKyAgICAodm9pZClSZW1vdmVkOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8vIHJlbW92ZVZpcnR1YWxSZWdpc3RlcnNLaWxsZWQgLSBSZW1vdmUgYWxsIGtpbGxlZCBpbmZvIGZvciB0aGUgc3BlY2lmaWVkCisgIC8vLyBpbnN0cnVjdGlvbi4KKyAgdm9pZCByZW1vdmVWaXJ0dWFsUmVnaXN0ZXJzS2lsbGVkKE1hY2hpbmVJbnN0ciAmTUkpOworCisgIC8vLyBhZGRWaXJ0dWFsUmVnaXN0ZXJEZWFkIC0gQWRkIGluZm9ybWF0aW9uIGFib3V0IHRoZSBmYWN0IHRoYXQgdGhlIHNwZWNpZmllZAorICAvLy8gcmVnaXN0ZXIgaXMgZGVhZCBhZnRlciBiZWluZyB1c2VkIGJ5IHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24uIElmCisgIC8vLyBBZGRJZk5vdEZvdW5kIGlzIHRydWUsIGFkZCBhIGltcGxpY2l0IG9wZXJhbmQgaWYgaXQncyBub3QgZm91bmQuCisgIHZvaWQgYWRkVmlydHVhbFJlZ2lzdGVyRGVhZCh1bnNpZ25lZCBJbmNvbWluZ1JlZywgTWFjaGluZUluc3RyICZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgQWRkSWZOb3RGb3VuZCA9IGZhbHNlKSB7CisgICAgaWYgKE1JLmFkZFJlZ2lzdGVyRGVhZChJbmNvbWluZ1JlZywgVFJJLCBBZGRJZk5vdEZvdW5kKSkKKyAgICAgIGdldFZhckluZm8oSW5jb21pbmdSZWcpLktpbGxzLnB1c2hfYmFjaygmTUkpOworICB9CisKKyAgLy8vIHJlbW92ZVZpcnR1YWxSZWdpc3RlckRlYWQgLSBSZW1vdmUgdGhlIHNwZWNpZmllZCBraWxsIG9mIHRoZSB2aXJ0dWFsCisgIC8vLyByZWdpc3RlciBmcm9tIHRoZSBsaXZlIHZhcmlhYmxlIGluZm9ybWF0aW9uLiBSZXR1cm5zIHRydWUgaWYgdGhlCisgIC8vLyB2YXJpYWJsZSB3YXMgbWFya2VkIGRlYWQgYXQgdGhlIHNwZWNpZmllZCBpbnN0cnVjdGlvbiwgZmFsc2UKKyAgLy8vIG90aGVyd2lzZS4KKyAgYm9vbCByZW1vdmVWaXJ0dWFsUmVnaXN0ZXJEZWFkKHVuc2lnbmVkIHJlZywgTWFjaGluZUluc3RyICZNSSkgeworICAgIGlmICghZ2V0VmFySW5mbyhyZWcpLnJlbW92ZUtpbGwoTUkpKQorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgYm9vbCBSZW1vdmVkID0gZmFsc2U7CisgICAgZm9yICh1bnNpZ25lZCBpID0gMCwgZSA9IE1JLmdldE51bU9wZXJhbmRzKCk7IGkgIT0gZTsgKytpKSB7CisgICAgICBNYWNoaW5lT3BlcmFuZCAmTU8gPSBNSS5nZXRPcGVyYW5kKGkpOworICAgICAgaWYgKE1PLmlzUmVnKCkgJiYgTU8uaXNEZWYoKSAmJiBNTy5nZXRSZWcoKSA9PSByZWcpIHsKKyAgICAgICAgTU8uc2V0SXNEZWFkKGZhbHNlKTsKKyAgICAgICAgUmVtb3ZlZCA9IHRydWU7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgICBhc3NlcnQoUmVtb3ZlZCAmJiAiUmVnaXN0ZXIgaXMgbm90IGRlZmluZWQgYnkgdGhpcyBpbnN0cnVjdGlvbiEiKTsKKyAgICAodm9pZClSZW1vdmVkOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgdm9pZCBnZXRBbmFseXNpc1VzYWdlKEFuYWx5c2lzVXNhZ2UgJkFVKSBjb25zdCBvdmVycmlkZTsKKworICB2b2lkIHJlbGVhc2VNZW1vcnkoKSBvdmVycmlkZSB7CisgICAgVmlydFJlZ0luZm8uY2xlYXIoKTsKKyAgfQorCisgIC8vLyBnZXRWYXJJbmZvIC0gUmV0dXJuIHRoZSBWYXJJbmZvIHN0cnVjdHVyZSBmb3IgdGhlIHNwZWNpZmllZCBWSVJUVUFMCisgIC8vLyByZWdpc3Rlci4KKyAgVmFySW5mbyAmZ2V0VmFySW5mbyh1bnNpZ25lZCBSZWdJZHgpOworCisgIHZvaWQgTWFya1ZpcnRSZWdBbGl2ZUluQmxvY2soVmFySW5mbyYgVlJJbmZvLCBNYWNoaW5lQmFzaWNCbG9jayogRGVmQmxvY2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2sgKkJCKTsKKyAgdm9pZCBNYXJrVmlydFJlZ0FsaXZlSW5CbG9jayhWYXJJbmZvJiBWUkluZm8sIE1hY2hpbmVCYXNpY0Jsb2NrKiBEZWZCbG9jaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jayAqQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8TWFjaGluZUJhc2ljQmxvY2sqPiAmV29ya0xpc3QpOworICB2b2lkIEhhbmRsZVZpcnRSZWdEZWYodW5zaWduZWQgcmVnLCBNYWNoaW5lSW5zdHIgJk1JKTsKKyAgdm9pZCBIYW5kbGVWaXJ0UmVnVXNlKHVuc2lnbmVkIHJlZywgTWFjaGluZUJhc2ljQmxvY2sgKk1CQiwgTWFjaGluZUluc3RyICZNSSk7CisKKyAgYm9vbCBpc0xpdmVJbih1bnNpZ25lZCBSZWcsIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIpIHsKKyAgICByZXR1cm4gZ2V0VmFySW5mbyhSZWcpLmlzTGl2ZUluKE1CQiwgUmVnLCAqTVJJKTsKKyAgfQorCisgIC8vLyBpc0xpdmVPdXQgLSBEZXRlcm1pbmUgaWYgUmVnIGlzIGxpdmUgb3V0IGZyb20gTUJCLCB3aGVuIG5vdCBjb25zaWRlcmluZworICAvLy8gUEhJIG5vZGVzLiBUaGlzIG1lYW5zIHRoYXQgUmVnIGlzIGVpdGhlciBraWxsZWQgYnkgYSBzdWNjZXNzb3IgYmxvY2sgb3IKKyAgLy8vIHBhc3NlZCB0aHJvdWdoIG9uZS4KKyAgYm9vbCBpc0xpdmVPdXQodW5zaWduZWQgUmVnLCBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAmTUJCKTsKKworICAvLy8gYWRkTmV3QmxvY2sgLSBBZGQgYSBuZXcgYmFzaWMgYmxvY2sgQkIgYmV0d2VlbiBEb21CQiBhbmQgU3VjY0JCLiBBbGwKKyAgLy8vIHZhcmlhYmxlcyB0aGF0IGFyZSBsaXZlIG91dCBvZiBEb21CQiBhbmQgbGl2ZSBpbnRvIFN1Y2NCQiB3aWxsIGJlIG1hcmtlZAorICAvLy8gYXMgcGFzc2luZyBsaXZlIHRocm91Z2ggQkIuIFRoaXMgbWV0aG9kIGFzc3VtZXMgdGhhdCB0aGUgbWFjaGluZSBjb2RlIGlzCisgIC8vLyBzdGlsbCBpbiBTU0EgZm9ybS4KKyAgdm9pZCBhZGROZXdCbG9jayhNYWNoaW5lQmFzaWNCbG9jayAqQkIsCisgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2sgKkRvbUJCLAorICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpTdWNjQkIpOworCisgIC8vLyBpc1BISUpvaW4gLSBSZXR1cm4gdHJ1ZSBpZiBSZWcgaXMgYSBwaGkgam9pbiByZWdpc3Rlci4KKyAgYm9vbCBpc1BISUpvaW4odW5zaWduZWQgUmVnKSB7IHJldHVybiBQSElKb2lucy50ZXN0KFJlZyk7IH0KKworICAvLy8gc2V0UEhJSm9pbiAtIE1hcmsgUmVnIGFzIGEgcGhpIGpvaW4gcmVnaXN0ZXIuCisgIHZvaWQgc2V0UEhJSm9pbih1bnNpZ25lZCBSZWcpIHsgUEhJSm9pbnMuc2V0KFJlZyk7IH0KK307CisKK30gLy8gRW5kIGxsdm0gbmFtZXNwYWNlCisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xvb3BUcmF2ZXJzYWwuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9Mb29wVHJhdmVyc2FsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTgxNmY2ZAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9Mb29wVHJhdmVyc2FsLmgKQEAgLTAsMCArMSwxMTYgQEAKKy8vPT0tLS0tLS0gbGx2bS9Db2RlR2VuL0xvb3BUcmF2ZXJzYWwuaCAtIExvb3AgVHJhdmVyc2FsIC0qLSBDKysgLSotLS0tLS0tLS09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8vIFxmaWxlIExvb3AgVHJhdmVyc2FsIGxvZ2ljLgorLy8vCisvLy8gVGhpcyBjbGFzcyBwcm92aWRlcyB0aGUgYmFzaWMgYmxvY2tzIHRyYXZlcnNhbCBvcmRlciB1c2VkIGJ5IHBhc3NlcyBsaWtlCisvLy8gUmVhY2hpbmdEZWZBbmFseXNpcyBhbmQgRXhlY3V0aW9uRG9tYWluRml4LgorLy8vIEl0IGlkZW50aWZpZXMgYmFzaWMgYmxvY2tzIHRoYXQgYXJlIHBhcnQgb2YgbG9vcHMgYW5kIHNob3VsZCB0byBiZSB2aXNpdGVkCisvLy8gdHdpY2UgYW5kIHJldHVybnMgZWZmaWNpZW50IHRyYXZlcnNhbCBvcmRlciBmb3IgYWxsIHRoZSBibG9ja3MuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTE9PUFRSQVZFUlNBTF9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9MT09QVFJBVkVSU0FMX0gKKworI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgTWFjaGluZUJhc2ljQmxvY2s7CitjbGFzcyBNYWNoaW5lRnVuY3Rpb247CisKKy8vLyBUaGlzIGNsYXNzIHByb3ZpZGVzIHRoZSBiYXNpYyBibG9ja3MgdHJhdmVyc2FsIG9yZGVyIHVzZWQgYnkgcGFzc2VzIGxpa2UKKy8vLyBSZWFjaGluZ0RlZkFuYWx5c2lzIGFuZCBFeGVjdXRpb25Eb21haW5GaXguCisvLy8gSXQgaWRlbnRpZmllcyBiYXNpYyBibG9ja3MgdGhhdCBhcmUgcGFydCBvZiBsb29wcyBhbmQgc2hvdWxkIHRvIGJlIHZpc2l0ZWQKKy8vLyB0d2ljZSBhbmQgcmV0dXJucyBlZmZpY2llbnQgdHJhdmVyc2FsIG9yZGVyIGZvciBhbGwgdGhlIGJsb2Nrcy4KKy8vLworLy8vIFdlIHdhbnQgdG8gdmlzaXQgZXZlcnkgaW5zdHJ1Y3Rpb24gaW4gZXZlcnkgYmFzaWMgYmxvY2sgaW4gb3JkZXIgdG8gdXBkYXRlCisvLy8gaXQncyBleGVjdXRpb24gZG9tYWluIG9yIGNvbGxlY3QgY2xlYXJhbmNlIGluZm9ybWF0aW9uLiBIb3dldmVyLCBmb3IgdGhlCisvLy8gY2xlYXJhbmNlIGNhbGN1bGF0aW9uLCB3ZSBuZWVkIHRvIGtub3cgY2xlYXJhbmNlcyBmcm9tIGFsbCBwcmVkZWNlc3NvcnMKKy8vLyAoaW5jbHVkaW5nIGFueSBiYWNrZWRnZXMpLCB0aGVyZm9yZSB3ZSBuZWVkIHRvIHZpc2l0IHNvbWUgYmxvY2tzIHR3aWNlLgorLy8vIEFzIGFuIGV4YW1wbGUsIGNvbnNpZGVyIHRoZSBmb2xsb3dpbmcgbG9vcC4KKy8vLworLy8vCisvLy8gICAgUEggLT4gQSAtPiBCICh4bW08VW5kZWY+IC0+IHhtbTxEZWY+KSAtPiBDIC0+IEQgLT4gRVhJVAorLy8vICAgICAgICAgIF4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorLy8vICAgICAgICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKworLy8vCisvLy8gVGhlIGl0ZXJhdGlvbiBvcmRlciB0aGlzIHBhc3Mgd2lsbCByZXR1cm4gaXMgYXMgZm9sbG93czoKKy8vLyBPcHRpbWl6ZWQ6IFBIIEEgQiBDIEEnIEInIEMnIEQKKy8vLworLy8vIFRoZSBiYXNpYyBibG9jayBvcmRlciBpcyBjb25zdHJ1Y3RlZCBhcyBmb2xsb3dzOgorLy8vIE9uY2Ugd2UgZmluaXNoIHByb2Nlc3Npbmcgc29tZSBibG9jaywgd2UgdXBkYXRlIHRoZSBjb3VudGVycyBpbiBNQkJJbmZvcworLy8vIGFuZCByZS1wcm9jZXNzIGFueSBzdWNjZXNzb3JzIHRoYXQgYXJlIG5vdyAnZG9uZScuCisvLy8gV2UgY2FsbCBhIGJsb2NrIHRoYXQgaXMgcmVhZHkgZm9yIGl0cyBmaW5hbCByb3VuZCBvZiBwcm9jZXNzaW5nIGBkb25lYAorLy8vIChpc0Jsb2NrRG9uZSksIGUuZy4gd2hlbiBhbGwgcHJlZGVjZXNzb3IgaW5mb3JtYXRpb24gaXMga25vd24uCisvLy8KKy8vLyBOb3RlIHRoYXQgYSBuYWl2ZSB0cmF2ZXJzYWwgb3JkZXIgd291bGQgYmUgdG8gZG8gdHdvIGNvbXBsZXRlIHBhc3NlcyBvdmVyCisvLy8gYWxsIGJhc2ljIGJsb2Nrcy9pbnN0cnVjdGlvbnMsIHRoZSBmaXJzdCBmb3IgcmVjb3JkaW5nIGNsZWFyYW5jZXMsIHRoZQorLy8vIHNlY29uZCBmb3IgdXBkYXRpbmcgY2xlYXJhbmNlIGJhc2VkIG9uIGJhY2tlZGdlcy4KKy8vLyBIb3dldmVyLCBmb3IgZnVuY3Rpb25zIHdpdGhvdXQgYmFja2VkZ2VzLCBvciBmdW5jdGlvbnMgd2l0aCBhIGxvdCBvZgorLy8vIHN0cmFpZ2h0LWxpbmUgY29kZSwgYW5kIGEgc21hbGwgbG9vcCwgdGhhdCB3b3VsZCBiZSBhIGxvdCBvZiB1bm5lY2Vzc2FyeQorLy8vIHdvcmsgKHNpbmNlIG9ubHkgdGhlIEJCcyB0aGF0IGFyZSBwYXJ0IG9mIHRoZSBsb29wIHJlcXVpcmUgdHdvIHBhc3NlcykuCisvLy8KKy8vLyBFLmcuLCB0aGUgbmFpdmUgaXRlcmF0aW9uIG9yZGVyIGZvciB0aGUgYWJvdmUgZXhtcGxlIGlzIGFzIGZvbGxvd3M6CisvLy8gTmFpdmU6IFBIIEEgQiBDIEQgQScgQicgQycgRCcKKy8vLworLy8vIEluIHRoZSBvcHRpbWl6ZWQgYXBwcm9hY2ggd2UgYXZvaWQgcHJvY2Vzc2luZyBEIHR3aWNlLCBiZWNhdXNlIHdlCisvLy8gY2FuIGVudGlyZWx5IHByb2Nlc3MgdGhlIHByZWRlY2Vzc29ycyBiZWZvcmUgZ2V0dGluZyB0byBELgorY2xhc3MgTG9vcFRyYXZlcnNhbCB7Citwcml2YXRlOgorICBzdHJ1Y3QgTUJCSW5mbyB7CisgICAgLy8vIFdoZXRoZXIgd2UgaGF2ZSBnb3R0ZW4gdG8gdGhpcyBibG9jayBpbiBwcmltYXJ5IHByb2Nlc3NpbmcgeWV0LgorICAgIGJvb2wgUHJpbWFyeUNvbXBsZXRlZCA9IGZhbHNlOworCisgICAgLy8vIFRoZSBudW1iZXIgb2YgcHJlZGVjZXNzb3JzIGZvciB3aGljaCBwcmltYXJ5IHByb2Nlc3NpbmcgaGFzIGNvbXBsZXRlZAorICAgIHVuc2lnbmVkIEluY29taW5nUHJvY2Vzc2VkID0gMDsKKworICAgIC8vLyBUaGUgdmFsdWUgb2YgYEluY29taW5nUHJvY2Vzc2VkYCBhdCB0aGUgc3RhcnQgb2YgcHJpbWFyeSBwcm9jZXNzaW5nCisgICAgdW5zaWduZWQgUHJpbWFyeUluY29taW5nID0gMDsKKworICAgIC8vLyBUaGUgbnVtYmVyIG9mIHByZWRlY2Vzc29ycyBmb3Igd2hpY2ggYWxsIHByb2Nlc3Npbmcgc3RlcHMgYXJlIGRvbmUuCisgICAgdW5zaWduZWQgSW5jb21pbmdDb21wbGV0ZWQgPSAwOworCisgICAgTUJCSW5mbygpID0gZGVmYXVsdDsKKyAgfTsKKyAgdXNpbmcgTUJCSW5mb01hcCA9IFNtYWxsVmVjdG9yPE1CQkluZm8sIDQ+OworICAvLy8gSGVscHMga2VlcCB0cmFjayBpZiB3ZSBwcm9jY2Vzc2VkIHRoaXMgYmxvY2sgYW5kIGFsbCBpdHMgcHJlZGVjZXNzb3JzLgorICBNQkJJbmZvTWFwIE1CQkluZm9zOworCitwdWJsaWM6CisgIHN0cnVjdCBUcmF2ZXJzZWRNQkJJbmZvIHsKKyAgICAvLy8gVGhlIGJhc2ljIGJsb2NrLgorICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIgPSBudWxscHRyOworCisgICAgLy8vIFRydWUgaWYgdGhpcyBpcyB0aGUgZmlyc3QgdGltZSB3ZSBwcm9jZXNzIHRoZSBiYXNpYyBibG9jay4KKyAgICBib29sIFByaW1hcnlQYXNzID0gdHJ1ZTsKKworICAgIC8vLyBUcnVlIGlmIHRoZSBibG9jayB0aGF0IGlzIHJlYWR5IGZvciBpdHMgZmluYWwgcm91bmQgb2YgcHJvY2Vzc2luZy4KKyAgICBib29sIElzRG9uZSA9IHRydWU7CisKKyAgICBUcmF2ZXJzZWRNQkJJbmZvKE1hY2hpbmVCYXNpY0Jsb2NrICpCQiA9IG51bGxwdHIsIGJvb2wgUHJpbWFyeSA9IHRydWUsCisgICAgICAgICAgICAgICAgICAgICBib29sIERvbmUgPSB0cnVlKQorICAgICAgICA6IE1CQihCQiksIFByaW1hcnlQYXNzKFByaW1hcnkpLCBJc0RvbmUoRG9uZSkge30KKyAgfTsKKyAgTG9vcFRyYXZlcnNhbCgpIHt9CisKKyAgLy8vIFxicmllZiBJZGVudGlmaWVzIGJhc2ljIGJsb2NrcyB0aGF0IGFyZSBwYXJ0IG9mIGxvb3BzIGFuZCBzaG91bGQgdG8gYmUKKyAgLy8vICB2aXNpdGVkIHR3aWNlIGFuZCByZXR1cm5zIGVmZmljaWVudCB0cmF2ZXJzYWwgb3JkZXIgZm9yIGFsbCB0aGUgYmxvY2tzLgorICB0eXBlZGVmIFNtYWxsVmVjdG9yPFRyYXZlcnNlZE1CQkluZm8sIDQ+IFRyYXZlcnNhbE9yZGVyOworICBUcmF2ZXJzYWxPcmRlciB0cmF2ZXJzZShNYWNoaW5lRnVuY3Rpb24gJk1GKTsKKworcHJpdmF0ZToKKyAgLy8vIFJldHVyZW5zIHRydWUgaWYgdGhlIGJsb2NrIGlzIHJlYWR5IGZvciBpdHMgZmluYWwgcm91bmQgb2YgcHJvY2Vzc2luZy4KKyAgYm9vbCBpc0Jsb2NrRG9uZShNYWNoaW5lQmFzaWNCbG9jayAqTUJCKTsKK307CisKK30gLy8gbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9MT09QVFJBVkVSU0FMX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9Mb3dMZXZlbFR5cGUuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9Mb3dMZXZlbFR5cGUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hM2M1YzkzCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL0xvd0xldmVsVHlwZS5oCkBAIC0wLDAgKzEsMzIgQEAKKy8vPT0gbGx2bS9Db2RlR2VuL0xvd0xldmVsVHlwZS5oIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gLSotIEMrKyAtKi09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8vIEltcGxlbWVudCBhIGxvdy1sZXZlbCB0eXBlIHN1aXRhYmxlIGZvciBNYWNoaW5lSW5zdHIgbGV2ZWwgaW5zdHJ1Y3Rpb24KKy8vLyBzZWxlY3Rpb24uCisvLy8KKy8vLyBUaGlzIHByb3ZpZGVzIHRoZSBDb2RlR2VuIGFzcGVjdHMgb2YgTG93TGV2ZWxUeXBlLCBzdWNoIGFzIFR5cGUgY29udmVyc2lvbi4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9MT1dMRVZFTFRZUEVfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTE9XTEVWRUxUWVBFX0gKKworI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9Mb3dMZXZlbFR5cGVJbXBsLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgRGF0YUxheW91dDsKK2NsYXNzIFR5cGU7CisKKy8vLyBDb25zdHJ1Y3QgYSBsb3ctbGV2ZWwgdHlwZSBiYXNlZCBvbiBhbiBMTFZNIHR5cGUuCitMTFQgZ2V0TExURm9yVHlwZShUeXBlICZUeSwgY29uc3QgRGF0YUxheW91dCAmREwpOworCit9CisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTE9XTEVWRUxUWVBFX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NSVJQYXJzZXIvTUlSUGFyc2VyLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTUlSUGFyc2VyL01JUlBhcnNlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI2MzFhOGMKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTUlSUGFyc2VyL01JUlBhcnNlci5oCkBAIC0wLDAgKzEsODEgQEAKKy8vPT09LSBNSVJQYXJzZXIuaCAtIE1JUiBzZXJpYWxpemF0aW9uIGZvcm1hdCBwYXJzZXIgLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBNSVIgc2VyaWFsaXphdGlvbiBsaWJyYXJ5IGlzIGN1cnJlbnRseSBhIHdvcmsgaW4gcHJvZ3Jlc3MuIEl0IGNhbid0CisvLyBzZXJpYWxpemUgbWFjaGluZSBmdW5jdGlvbnMgYXQgdGhpcyB0aW1lLgorLy8KKy8vIFRoaXMgZmlsZSBkZWNsYXJlcyB0aGUgZnVuY3Rpb25zIHRoYXQgcGFyc2UgdGhlIE1JUiBzZXJpYWxpemF0aW9uIGZvcm1hdAorLy8gZmlsZXMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUlSUEFSU0VSX01JUlBBUlNFUl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9NSVJQQVJTRVJfTUlSUEFSU0VSX0gKKworI2luY2x1ZGUgImxsdm0vSVIvTW9kdWxlLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L01lbW9yeUJ1ZmZlci5oIgorI2luY2x1ZGUgPG1lbW9yeT4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBTdHJpbmdSZWY7CitjbGFzcyBNSVJQYXJzZXJJbXBsOworY2xhc3MgTWFjaGluZU1vZHVsZUluZm87CitjbGFzcyBTTURpYWdub3N0aWM7CisKKy8vLyBUaGlzIGNsYXNzIGluaXRpYWxpemVzIG1hY2hpbmUgZnVuY3Rpb25zIGJ5IGFwcGx5aW5nIHRoZSBzdGF0ZSBsb2FkZWQgZnJvbQorLy8vIGEgTUlSIGZpbGUuCitjbGFzcyBNSVJQYXJzZXIgeworICBzdGQ6OnVuaXF1ZV9wdHI8TUlSUGFyc2VySW1wbD4gSW1wbDsKKworcHVibGljOgorICBNSVJQYXJzZXIoc3RkOjp1bmlxdWVfcHRyPE1JUlBhcnNlckltcGw+IEltcGwpOworICBNSVJQYXJzZXIoY29uc3QgTUlSUGFyc2VyICYpID0gZGVsZXRlOworICB+TUlSUGFyc2VyKCk7CisKKyAgLy8vIFBhcnNlcyB0aGUgb3B0aW9uYWwgTExWTSBJUiBtb2R1bGUgaW4gdGhlIE1JUiBmaWxlLgorICAvLy8KKyAgLy8vIEEgbmV3LCBlbXB0eSBtb2R1bGUgaXMgY3JlYXRlZCBpZiB0aGUgTExWTSBJUiBpc24ndCBwcmVzZW50LgorICAvLy8gXHJldHVybnMgbnVsbHB0ciBpZiBhIHBhcnNpbmcgZXJyb3Igb2NjdXJyZWQuCisgIHN0ZDo6dW5pcXVlX3B0cjxNb2R1bGU+IHBhcnNlSVJNb2R1bGUoKTsKKworICAvLy8gXGJyaWVmIFBhcnNlcyBNYWNoaW5lRnVuY3Rpb25zIGluIHRoZSBNSVIgZmlsZSBhbmQgYWRkIHRoZW0gdG8gdGhlIGdpdmVuCisgIC8vLyBNYWNoaW5lTW9kdWxlSW5mbyBccCBNTUkuCisgIC8vLworICAvLy8gXHJldHVybnMgdHJ1ZSBpZiBhbiBlcnJvciBvY2N1cnJlZC4KKyAgYm9vbCBwYXJzZU1hY2hpbmVGdW5jdGlvbnMoTW9kdWxlICZNLCBNYWNoaW5lTW9kdWxlSW5mbyAmTU1JKTsKK307CisKKy8vLyBUaGlzIGZ1bmN0aW9uIGlzIHRoZSBtYWluIGludGVyZmFjZSB0byB0aGUgTUlSIHNlcmlhbGl6YXRpb24gZm9ybWF0IHBhcnNlci4KKy8vLworLy8vIEl0IHJlYWRzIGluIGEgTUlSIGZpbGUgYW5kIHJldHVybnMgYSBNSVIgcGFyc2VyIHRoYXQgY2FuIHBhcnNlIHRoZSBlbWJlZGRlZAorLy8vIExMVk0gSVIgbW9kdWxlIGFuZCBpbml0aWFsaXplIHRoZSBtYWNoaW5lIGZ1bmN0aW9ucyBieSBwYXJzaW5nIHRoZSBtYWNoaW5lCisvLy8gZnVuY3Rpb24ncyBzdGF0ZS4KKy8vLworLy8vIFxwYXJhbSBGaWxlbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBmaWxlIHRvIHBhcnNlLgorLy8vIFxwYXJhbSBFcnJvciAtIEVycm9yIHJlc3VsdCBpbmZvLgorLy8vIFxwYXJhbSBDb250ZXh0IC0gQ29udGV4dCB3aGljaCB3aWxsIGJlIHVzZWQgZm9yIHRoZSBwYXJzZWQgTExWTSBJUiBtb2R1bGUuCitzdGQ6OnVuaXF1ZV9wdHI8TUlSUGFyc2VyPiBjcmVhdGVNSVJQYXJzZXJGcm9tRmlsZShTdHJpbmdSZWYgRmlsZW5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTURpYWdub3N0aWMgJkVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTExWTUNvbnRleHQgJkNvbnRleHQpOworCisvLy8gVGhpcyBmdW5jdGlvbiBpcyBhbm90aGVyIGludGVyZmFjZSB0byB0aGUgTUlSIHNlcmlhbGl6YXRpb24gZm9ybWF0IHBhcnNlci4KKy8vLworLy8vIEl0IHJldHVybnMgYSBNSVIgcGFyc2VyIHRoYXQgd29ya3Mgd2l0aCB0aGUgZ2l2ZW4gbWVtb3J5IGJ1ZmZlciBhbmQgdGhhdCBjYW4KKy8vLyBwYXJzZSB0aGUgZW1iZWRkZWQgTExWTSBJUiBtb2R1bGUgYW5kIGluaXRpYWxpemUgdGhlIG1hY2hpbmUgZnVuY3Rpb25zIGJ5CisvLy8gcGFyc2luZyB0aGUgbWFjaGluZSBmdW5jdGlvbidzIHN0YXRlLgorLy8vCisvLy8gXHBhcmFtIENvbnRlbnRzIC0gVGhlIE1lbW9yeUJ1ZmZlciBjb250YWluaW5nIHRoZSBtYWNoaW5lIGxldmVsIElSLgorLy8vIFxwYXJhbSBDb250ZXh0IC0gQ29udGV4dCB3aGljaCB3aWxsIGJlIHVzZWQgZm9yIHRoZSBwYXJzZWQgTExWTSBJUiBtb2R1bGUuCitzdGQ6OnVuaXF1ZV9wdHI8TUlSUGFyc2VyPgorY3JlYXRlTUlSUGFyc2VyKHN0ZDo6dW5pcXVlX3B0cjxNZW1vcnlCdWZmZXI+IENvbnRlbnRzLCBMTFZNQ29udGV4dCAmQ29udGV4dCk7CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTUlSUEFSU0VSX01JUlBBUlNFUl9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTUlSUHJpbnRlci5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01JUlByaW50ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNzNhZGMzCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01JUlByaW50ZXIuaApAQCAtMCwwICsxLDQ2IEBACisvLz09PS0gTUlSUHJpbnRlci5oIC0gTUlSIHNlcmlhbGl6YXRpb24gZm9ybWF0IHByaW50ZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZWNsYXJlcyB0aGUgZnVuY3Rpb25zIHRoYXQgcHJpbnQgb3V0IHRoZSBMTFZNIElSIGFuZCB0aGUgbWFjaGluZQorLy8gZnVuY3Rpb25zIHVzaW5nIHRoZSBNSVIgc2VyaWFsaXphdGlvbiBmb3JtYXQuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0xJQl9DT0RFR0VOX01JUlBSSU5URVJfSAorI2RlZmluZSBMTFZNX0xJQl9DT0RFR0VOX01JUlBSSU5URVJfSAorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIE1hY2hpbmVCYXNpY0Jsb2NrOworY2xhc3MgTWFjaGluZUZ1bmN0aW9uOworY2xhc3MgTW9kdWxlOworY2xhc3MgcmF3X29zdHJlYW07Cit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gY2xhc3MgU21hbGxWZWN0b3JJbXBsOworCisvLy8gUHJpbnQgTExWTSBJUiB1c2luZyB0aGUgTUlSIHNlcmlhbGl6YXRpb24gZm9ybWF0IHRvIHRoZSBnaXZlbiBvdXRwdXQgc3RyZWFtLgordm9pZCBwcmludE1JUihyYXdfb3N0cmVhbSAmT1MsIGNvbnN0IE1vZHVsZSAmTSk7CisKKy8vLyBQcmludCBhIG1hY2hpbmUgZnVuY3Rpb24gdXNpbmcgdGhlIE1JUiBzZXJpYWxpemF0aW9uIGZvcm1hdCB0byB0aGUgZ2l2ZW4KKy8vLyBvdXRwdXQgc3RyZWFtLgordm9pZCBwcmludE1JUihyYXdfb3N0cmVhbSAmT1MsIGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYpOworCisvLy8gRGV0ZXJtaW5lIGEgcG9zc2libGUgbGlzdCBvZiBzdWNjZXNzb3JzIG9mIGEgYmFzaWMgYmxvY2sgYmFzZWQgb24gdGhlCisvLy8gYmFzaWMgYmxvY2sgbWFjaGluZSBvcGVyYW5kIGJlaW5nIHVzZWQgaW5zaWRlIHRoZSBibG9jay4gVGhpcyBzaG91bGQgZ2l2ZQorLy8vIHlvdSB0aGUgY29ycmVjdCBsaXN0IG9mIHN1Y2Nlc3NvciBibG9ja3MgaW4gbW9zdCBjYXNlcyBleGNlcHQgZm9yIHRoaW5ncworLy8vIGxpa2UganVtcCB0YWJsZXMgd2hlcmUgdGhlIGJhc2ljIGJsb2NrIHJlZmVyZW5jZXMgY2FuJ3QgZWFzaWx5IGJlIGZvdW5kLgorLy8vIFRoZSBNSVJQUmludGVyIHdpbGwgc2tpcCBwcmludGluZyBzdWNjZXNzb3JzIGlmIHRoZXkgbWF0Y2ggdGhlIHJlc3VsdCBvZgorLy8vIHRoaXMgZnVuY2l0b24gYW5kIHRoZSBwYXJzZXIgd2lsbCB1c2UgdGhpcyBmdW5jdGlvbiB0byBjb25zdHJ1Y3QgYSBsaXN0IGlmCisvLy8gaXQgaXMgbWlzc2luZy4KK3ZvaWQgZ3Vlc3NTdWNjZXNzb3JzKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8TWFjaGluZUJhc2ljQmxvY2sqPiAmU3VjY2Vzc29ycywKKyAgICAgICAgICAgICAgICAgICAgIGJvb2wgJklzRmFsbHRocm91Z2gpOworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NSVJZYW1sTWFwcGluZy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01JUllhbWxNYXBwaW5nLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjc1ZjljOAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NSVJZYW1sTWFwcGluZy5oCkBAIC0wLDAgKzEsNTIzIEBACisvLz09PS0gTUlSWUFNTE1hcHBpbmcuaCAtIERlc2NyaWJlcyB0aGUgbWFwcGluZyBiZXR3ZWVuIE1JUiBhbmQgWUFNTCAtLS0tLS09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBpbXBsZW1lbnRzIHRoZSBtYXBwaW5nIGJldHdlZW4gdmFyaW91cyBNSVIgZGF0YSBzdHJ1Y3R1cmVzIGFuZAorLy8gdGhlaXIgY29ycmVzcG9uZGluZyBZQU1MIHJlcHJlc2VudGF0aW9uLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01JUllBTUxNQVBQSU5HX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX01JUllBTUxNQVBQSU5HX0gKKworI2luY2x1ZGUgImxsdm0vQURUL09wdGlvbmFsLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU3RyaW5nUmVmLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVKdW1wVGFibGVJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L1NNTG9jLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L1lBTUxUcmFpdHMuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvcmF3X29zdHJlYW0uaCIKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Y3N0ZGludD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dmVjdG9yPgorCituYW1lc3BhY2UgbGx2bSB7CituYW1lc3BhY2UgeWFtbCB7CisKKy8vLyBBIHdyYXBwZXIgYXJvdW5kIHN0ZDo6c3RyaW5nIHdoaWNoIGNvbnRhaW5zIGEgc291cmNlIHJhbmdlIHRoYXQncyBiZWluZworLy8vIHNldCBkdXJpbmcgcGFyc2luZy4KK3N0cnVjdCBTdHJpbmdWYWx1ZSB7CisgIHN0ZDo6c3RyaW5nIFZhbHVlOworICBTTVJhbmdlIFNvdXJjZVJhbmdlOworCisgIFN0cmluZ1ZhbHVlKCkgPSBkZWZhdWx0OworICBTdHJpbmdWYWx1ZShzdGQ6OnN0cmluZyBWYWx1ZSkgOiBWYWx1ZShzdGQ6Om1vdmUoVmFsdWUpKSB7fQorCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBTdHJpbmdWYWx1ZSAmT3RoZXIpIGNvbnN0IHsKKyAgICByZXR1cm4gVmFsdWUgPT0gT3RoZXIuVmFsdWU7CisgIH0KK307CisKK3RlbXBsYXRlIDw+IHN0cnVjdCBTY2FsYXJUcmFpdHM8U3RyaW5nVmFsdWU+IHsKKyAgc3RhdGljIHZvaWQgb3V0cHV0KGNvbnN0IFN0cmluZ1ZhbHVlICZTLCB2b2lkICosIHJhd19vc3RyZWFtICZPUykgeworICAgIE9TIDw8IFMuVmFsdWU7CisgIH0KKworICBzdGF0aWMgU3RyaW5nUmVmIGlucHV0KFN0cmluZ1JlZiBTY2FsYXIsIHZvaWQgKkN0eCwgU3RyaW5nVmFsdWUgJlMpIHsKKyAgICBTLlZhbHVlID0gU2NhbGFyLnN0cigpOworICAgIGlmIChjb25zdCBhdXRvICpOb2RlID0KKyAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8eWFtbDo6SW5wdXQgKj4oQ3R4KS0+Z2V0Q3VycmVudE5vZGUoKSkKKyAgICAgIFMuU291cmNlUmFuZ2UgPSBOb2RlLT5nZXRTb3VyY2VSYW5nZSgpOworICAgIHJldHVybiAiIjsKKyAgfQorCisgIHN0YXRpYyBRdW90aW5nVHlwZSBtdXN0UXVvdGUoU3RyaW5nUmVmIFMpIHsgcmV0dXJuIG5lZWRzUXVvdGVzKFMpOyB9Cit9OworCitzdHJ1Y3QgRmxvd1N0cmluZ1ZhbHVlIDogU3RyaW5nVmFsdWUgeworICBGbG93U3RyaW5nVmFsdWUoKSA9IGRlZmF1bHQ7CisgIEZsb3dTdHJpbmdWYWx1ZShzdGQ6OnN0cmluZyBWYWx1ZSkgOiBTdHJpbmdWYWx1ZShzdGQ6Om1vdmUoVmFsdWUpKSB7fQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IFNjYWxhclRyYWl0czxGbG93U3RyaW5nVmFsdWU+IHsKKyAgc3RhdGljIHZvaWQgb3V0cHV0KGNvbnN0IEZsb3dTdHJpbmdWYWx1ZSAmUywgdm9pZCAqLCByYXdfb3N0cmVhbSAmT1MpIHsKKyAgICByZXR1cm4gU2NhbGFyVHJhaXRzPFN0cmluZ1ZhbHVlPjo6b3V0cHV0KFMsIG51bGxwdHIsIE9TKTsKKyAgfQorCisgIHN0YXRpYyBTdHJpbmdSZWYgaW5wdXQoU3RyaW5nUmVmIFNjYWxhciwgdm9pZCAqQ3R4LCBGbG93U3RyaW5nVmFsdWUgJlMpIHsKKyAgICByZXR1cm4gU2NhbGFyVHJhaXRzPFN0cmluZ1ZhbHVlPjo6aW5wdXQoU2NhbGFyLCBDdHgsIFMpOworICB9CisKKyAgc3RhdGljIFF1b3RpbmdUeXBlIG11c3RRdW90ZShTdHJpbmdSZWYgUykgeyByZXR1cm4gbmVlZHNRdW90ZXMoUyk7IH0KK307CisKK3N0cnVjdCBCbG9ja1N0cmluZ1ZhbHVlIHsKKyAgU3RyaW5nVmFsdWUgVmFsdWU7CisKKyAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IEJsb2NrU3RyaW5nVmFsdWUgJk90aGVyKSBjb25zdCB7CisgICAgcmV0dXJuIFZhbHVlID09IE90aGVyLlZhbHVlOworICB9Cit9OworCit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgQmxvY2tTY2FsYXJUcmFpdHM8QmxvY2tTdHJpbmdWYWx1ZT4geworICBzdGF0aWMgdm9pZCBvdXRwdXQoY29uc3QgQmxvY2tTdHJpbmdWYWx1ZSAmUywgdm9pZCAqQ3R4LCByYXdfb3N0cmVhbSAmT1MpIHsKKyAgICByZXR1cm4gU2NhbGFyVHJhaXRzPFN0cmluZ1ZhbHVlPjo6b3V0cHV0KFMuVmFsdWUsIEN0eCwgT1MpOworICB9CisKKyAgc3RhdGljIFN0cmluZ1JlZiBpbnB1dChTdHJpbmdSZWYgU2NhbGFyLCB2b2lkICpDdHgsIEJsb2NrU3RyaW5nVmFsdWUgJlMpIHsKKyAgICByZXR1cm4gU2NhbGFyVHJhaXRzPFN0cmluZ1ZhbHVlPjo6aW5wdXQoU2NhbGFyLCBDdHgsIFMuVmFsdWUpOworICB9Cit9OworCisvLy8gQSB3cmFwcGVyIGFyb3VuZCB1bnNpZ25lZCB3aGljaCBjb250YWlucyBhIHNvdXJjZSByYW5nZSB0aGF0J3MgYmVpbmcgc2V0CisvLy8gZHVyaW5nIHBhcnNpbmcuCitzdHJ1Y3QgVW5zaWduZWRWYWx1ZSB7CisgIHVuc2lnbmVkIFZhbHVlID0gMDsKKyAgU01SYW5nZSBTb3VyY2VSYW5nZTsKKworICBVbnNpZ25lZFZhbHVlKCkgPSBkZWZhdWx0OworICBVbnNpZ25lZFZhbHVlKHVuc2lnbmVkIFZhbHVlKSA6IFZhbHVlKFZhbHVlKSB7fQorCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBVbnNpZ25lZFZhbHVlICZPdGhlcikgY29uc3QgeworICAgIHJldHVybiBWYWx1ZSA9PSBPdGhlci5WYWx1ZTsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IFNjYWxhclRyYWl0czxVbnNpZ25lZFZhbHVlPiB7CisgIHN0YXRpYyB2b2lkIG91dHB1dChjb25zdCBVbnNpZ25lZFZhbHVlICZWYWx1ZSwgdm9pZCAqQ3R4LCByYXdfb3N0cmVhbSAmT1MpIHsKKyAgICByZXR1cm4gU2NhbGFyVHJhaXRzPHVuc2lnbmVkPjo6b3V0cHV0KFZhbHVlLlZhbHVlLCBDdHgsIE9TKTsKKyAgfQorCisgIHN0YXRpYyBTdHJpbmdSZWYgaW5wdXQoU3RyaW5nUmVmIFNjYWxhciwgdm9pZCAqQ3R4LCBVbnNpZ25lZFZhbHVlICZWYWx1ZSkgeworICAgIGlmIChjb25zdCBhdXRvICpOb2RlID0KKyAgICAgICAgICAgIHJlaW50ZXJwcmV0X2Nhc3Q8eWFtbDo6SW5wdXQgKj4oQ3R4KS0+Z2V0Q3VycmVudE5vZGUoKSkKKyAgICAgIFZhbHVlLlNvdXJjZVJhbmdlID0gTm9kZS0+Z2V0U291cmNlUmFuZ2UoKTsKKyAgICByZXR1cm4gU2NhbGFyVHJhaXRzPHVuc2lnbmVkPjo6aW5wdXQoU2NhbGFyLCBDdHgsIFZhbHVlLlZhbHVlKTsKKyAgfQorCisgIHN0YXRpYyBRdW90aW5nVHlwZSBtdXN0UXVvdGUoU3RyaW5nUmVmIFNjYWxhcikgeworICAgIHJldHVybiBTY2FsYXJUcmFpdHM8dW5zaWduZWQ+OjptdXN0UXVvdGUoU2NhbGFyKTsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IFNjYWxhckVudW1lcmF0aW9uVHJhaXRzPE1hY2hpbmVKdW1wVGFibGVJbmZvOjpKVEVudHJ5S2luZD4geworICBzdGF0aWMgdm9pZCBlbnVtZXJhdGlvbih5YW1sOjpJTyAmSU8sCisgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVKdW1wVGFibGVJbmZvOjpKVEVudHJ5S2luZCAmRW50cnlLaW5kKSB7CisgICAgSU8uZW51bUNhc2UoRW50cnlLaW5kLCAiYmxvY2stYWRkcmVzcyIsCisgICAgICAgICAgICAgICAgTWFjaGluZUp1bXBUYWJsZUluZm86OkVLX0Jsb2NrQWRkcmVzcyk7CisgICAgSU8uZW51bUNhc2UoRW50cnlLaW5kLCAiZ3AtcmVsNjQtYmxvY2stYWRkcmVzcyIsCisgICAgICAgICAgICAgICAgTWFjaGluZUp1bXBUYWJsZUluZm86OkVLX0dQUmVsNjRCbG9ja0FkZHJlc3MpOworICAgIElPLmVudW1DYXNlKEVudHJ5S2luZCwgImdwLXJlbDMyLWJsb2NrLWFkZHJlc3MiLAorICAgICAgICAgICAgICAgIE1hY2hpbmVKdW1wVGFibGVJbmZvOjpFS19HUFJlbDMyQmxvY2tBZGRyZXNzKTsKKyAgICBJTy5lbnVtQ2FzZShFbnRyeUtpbmQsICJsYWJlbC1kaWZmZXJlbmNlMzIiLAorICAgICAgICAgICAgICAgIE1hY2hpbmVKdW1wVGFibGVJbmZvOjpFS19MYWJlbERpZmZlcmVuY2UzMik7CisgICAgSU8uZW51bUNhc2UoRW50cnlLaW5kLCAiaW5saW5lIiwgTWFjaGluZUp1bXBUYWJsZUluZm86OkVLX0lubGluZSk7CisgICAgSU8uZW51bUNhc2UoRW50cnlLaW5kLCAiY3VzdG9tMzIiLCBNYWNoaW5lSnVtcFRhYmxlSW5mbzo6RUtfQ3VzdG9tMzIpOworICB9Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgeWFtbAorfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworTExWTV9ZQU1MX0lTX1NFUVVFTkNFX1ZFQ1RPUihsbHZtOjp5YW1sOjpTdHJpbmdWYWx1ZSkKK0xMVk1fWUFNTF9JU19GTE9XX1NFUVVFTkNFX1ZFQ1RPUihsbHZtOjp5YW1sOjpGbG93U3RyaW5nVmFsdWUpCitMTFZNX1lBTUxfSVNfRkxPV19TRVFVRU5DRV9WRUNUT1IobGx2bTo6eWFtbDo6VW5zaWduZWRWYWx1ZSkKKworbmFtZXNwYWNlIGxsdm0geworbmFtZXNwYWNlIHlhbWwgeworCitzdHJ1Y3QgVmlydHVhbFJlZ2lzdGVyRGVmaW5pdGlvbiB7CisgIFVuc2lnbmVkVmFsdWUgSUQ7CisgIFN0cmluZ1ZhbHVlIENsYXNzOworICBTdHJpbmdWYWx1ZSBQcmVmZXJyZWRSZWdpc3RlcjsKKworICAvLyBUT0RPOiBTZXJpYWxpemUgdGhlIHRhcmdldCBzcGVjaWZpYyByZWdpc3RlciBoaW50cy4KKworICBib29sIG9wZXJhdG9yPT0oY29uc3QgVmlydHVhbFJlZ2lzdGVyRGVmaW5pdGlvbiAmT3RoZXIpIGNvbnN0IHsKKyAgICByZXR1cm4gSUQgPT0gT3RoZXIuSUQgJiYgQ2xhc3MgPT0gT3RoZXIuQ2xhc3MgJiYKKyAgICAgICAgICAgUHJlZmVycmVkUmVnaXN0ZXIgPT0gT3RoZXIuUHJlZmVycmVkUmVnaXN0ZXI7CisgIH0KK307CisKK3RlbXBsYXRlIDw+IHN0cnVjdCBNYXBwaW5nVHJhaXRzPFZpcnR1YWxSZWdpc3RlckRlZmluaXRpb24+IHsKKyAgc3RhdGljIHZvaWQgbWFwcGluZyhJTyAmWWFtbElPLCBWaXJ0dWFsUmVnaXN0ZXJEZWZpbml0aW9uICZSZWcpIHsKKyAgICBZYW1sSU8ubWFwUmVxdWlyZWQoImlkIiwgUmVnLklEKTsKKyAgICBZYW1sSU8ubWFwUmVxdWlyZWQoImNsYXNzIiwgUmVnLkNsYXNzKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoInByZWZlcnJlZC1yZWdpc3RlciIsIFJlZy5QcmVmZXJyZWRSZWdpc3RlciwKKyAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nVmFsdWUoKSk7IC8vIERvbid0IHByaW50IG91dCB3aGVuIGl0J3MgZW1wdHkuCisgIH0KKworICBzdGF0aWMgY29uc3QgYm9vbCBmbG93ID0gdHJ1ZTsKK307CisKK3N0cnVjdCBNYWNoaW5lRnVuY3Rpb25MaXZlSW4geworICBTdHJpbmdWYWx1ZSBSZWdpc3RlcjsKKyAgU3RyaW5nVmFsdWUgVmlydHVhbFJlZ2lzdGVyOworCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBNYWNoaW5lRnVuY3Rpb25MaXZlSW4gJk90aGVyKSBjb25zdCB7CisgICAgcmV0dXJuIFJlZ2lzdGVyID09IE90aGVyLlJlZ2lzdGVyICYmCisgICAgICAgICAgIFZpcnR1YWxSZWdpc3RlciA9PSBPdGhlci5WaXJ0dWFsUmVnaXN0ZXI7CisgIH0KK307CisKK3RlbXBsYXRlIDw+IHN0cnVjdCBNYXBwaW5nVHJhaXRzPE1hY2hpbmVGdW5jdGlvbkxpdmVJbj4geworICBzdGF0aWMgdm9pZCBtYXBwaW5nKElPICZZYW1sSU8sIE1hY2hpbmVGdW5jdGlvbkxpdmVJbiAmTGl2ZUluKSB7CisgICAgWWFtbElPLm1hcFJlcXVpcmVkKCJyZWciLCBMaXZlSW4uUmVnaXN0ZXIpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgKKyAgICAgICAgInZpcnR1YWwtcmVnIiwgTGl2ZUluLlZpcnR1YWxSZWdpc3RlciwKKyAgICAgICAgU3RyaW5nVmFsdWUoKSk7IC8vIERvbid0IHByaW50IHRoZSB2aXJ0dWFsIHJlZ2lzdGVyIHdoZW4gaXQncyBlbXB0eS4KKyAgfQorCisgIHN0YXRpYyBjb25zdCBib29sIGZsb3cgPSB0cnVlOworfTsKKworLy8vIFNlcmlhbGl6YWJsZSByZXByZXNlbnRhdGlvbiBvZiBzdGFjayBvYmplY3QgZnJvbSB0aGUgTWFjaGluZUZyYW1lSW5mbyBjbGFzcy4KKy8vLworLy8vIFRoZSBmbGFncyAnaXNJbW11dGFibGUnIGFuZCAnaXNBbGlhc2VkJyBhcmVuJ3Qgc2VyaWFsaXplZCwgYXMgdGhleSBhcmUKKy8vLyBkZXRlcm1pbmVkIGJ5IHRoZSBvYmplY3QncyB0eXBlIGFuZCBmcmFtZSBpbmZvcm1hdGlvbiBmbGFncy4KKy8vLyBEZWFkIHN0YWNrIG9iamVjdHMgYXJlbid0IHNlcmlhbGl6ZWQuCisvLy8KKy8vLyBUaGUgJ2lzUHJlYWxsb2NhdGVkJyBmbGFnIGlzIGRldGVybWluZWQgYnkgdGhlIGxvY2FsIG9mZnNldC4KK3N0cnVjdCBNYWNoaW5lU3RhY2tPYmplY3QgeworICBlbnVtIE9iamVjdFR5cGUgeyBEZWZhdWx0VHlwZSwgU3BpbGxTbG90LCBWYXJpYWJsZVNpemVkIH07CisgIFVuc2lnbmVkVmFsdWUgSUQ7CisgIFN0cmluZ1ZhbHVlIE5hbWU7CisgIC8vIFRPRE86IFNlcmlhbGl6ZSB1bm5hbWVkIExMVk0gYWxsb2NhIHJlZmVyZW5jZS4KKyAgT2JqZWN0VHlwZSBUeXBlID0gRGVmYXVsdFR5cGU7CisgIGludDY0X3QgT2Zmc2V0ID0gMDsKKyAgdWludDY0X3QgU2l6ZSA9IDA7CisgIHVuc2lnbmVkIEFsaWdubWVudCA9IDA7CisgIHVpbnQ4X3QgU3RhY2tJRCA9IDA7CisgIFN0cmluZ1ZhbHVlIENhbGxlZVNhdmVkUmVnaXN0ZXI7CisgIGJvb2wgQ2FsbGVlU2F2ZWRSZXN0b3JlZCA9IHRydWU7CisgIE9wdGlvbmFsPGludDY0X3Q+IExvY2FsT2Zmc2V0OworICBTdHJpbmdWYWx1ZSBEZWJ1Z1ZhcjsKKyAgU3RyaW5nVmFsdWUgRGVidWdFeHByOworICBTdHJpbmdWYWx1ZSBEZWJ1Z0xvYzsKKworICBib29sIG9wZXJhdG9yPT0oY29uc3QgTWFjaGluZVN0YWNrT2JqZWN0ICZPdGhlcikgY29uc3QgeworICAgIHJldHVybiBJRCA9PSBPdGhlci5JRCAmJiBOYW1lID09IE90aGVyLk5hbWUgJiYgVHlwZSA9PSBPdGhlci5UeXBlICYmCisgICAgICAgICAgIE9mZnNldCA9PSBPdGhlci5PZmZzZXQgJiYgU2l6ZSA9PSBPdGhlci5TaXplICYmCisgICAgICAgICAgIEFsaWdubWVudCA9PSBPdGhlci5BbGlnbm1lbnQgJiYKKyAgICAgICAgICAgU3RhY2tJRCA9PSBPdGhlci5TdGFja0lEICYmCisgICAgICAgICAgIENhbGxlZVNhdmVkUmVnaXN0ZXIgPT0gT3RoZXIuQ2FsbGVlU2F2ZWRSZWdpc3RlciAmJgorICAgICAgICAgICBDYWxsZWVTYXZlZFJlc3RvcmVkID09IE90aGVyLkNhbGxlZVNhdmVkUmVzdG9yZWQgJiYKKyAgICAgICAgICAgTG9jYWxPZmZzZXQgPT0gT3RoZXIuTG9jYWxPZmZzZXQgJiYgRGVidWdWYXIgPT0gT3RoZXIuRGVidWdWYXIgJiYKKyAgICAgICAgICAgRGVidWdFeHByID09IE90aGVyLkRlYnVnRXhwciAmJiBEZWJ1Z0xvYyA9PSBPdGhlci5EZWJ1Z0xvYzsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IFNjYWxhckVudW1lcmF0aW9uVHJhaXRzPE1hY2hpbmVTdGFja09iamVjdDo6T2JqZWN0VHlwZT4geworICBzdGF0aWMgdm9pZCBlbnVtZXJhdGlvbih5YW1sOjpJTyAmSU8sIE1hY2hpbmVTdGFja09iamVjdDo6T2JqZWN0VHlwZSAmVHlwZSkgeworICAgIElPLmVudW1DYXNlKFR5cGUsICJkZWZhdWx0IiwgTWFjaGluZVN0YWNrT2JqZWN0OjpEZWZhdWx0VHlwZSk7CisgICAgSU8uZW51bUNhc2UoVHlwZSwgInNwaWxsLXNsb3QiLCBNYWNoaW5lU3RhY2tPYmplY3Q6OlNwaWxsU2xvdCk7CisgICAgSU8uZW51bUNhc2UoVHlwZSwgInZhcmlhYmxlLXNpemVkIiwgTWFjaGluZVN0YWNrT2JqZWN0OjpWYXJpYWJsZVNpemVkKTsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IE1hcHBpbmdUcmFpdHM8TWFjaGluZVN0YWNrT2JqZWN0PiB7CisgIHN0YXRpYyB2b2lkIG1hcHBpbmcoeWFtbDo6SU8gJllhbWxJTywgTWFjaGluZVN0YWNrT2JqZWN0ICZPYmplY3QpIHsKKyAgICBZYW1sSU8ubWFwUmVxdWlyZWQoImlkIiwgT2JqZWN0LklEKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoIm5hbWUiLCBPYmplY3QuTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nVmFsdWUoKSk7IC8vIERvbid0IHByaW50IG91dCBhbiBlbXB0eSBuYW1lLgorICAgIFlhbWxJTy5tYXBPcHRpb25hbCgKKyAgICAgICAgInR5cGUiLCBPYmplY3QuVHlwZSwKKyAgICAgICAgTWFjaGluZVN0YWNrT2JqZWN0OjpEZWZhdWx0VHlwZSk7IC8vIERvbid0IHByaW50IHRoZSBkZWZhdWx0IHR5cGUuCisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJvZmZzZXQiLCBPYmplY3QuT2Zmc2V0LCAoaW50NjRfdCkwKTsKKyAgICBpZiAoT2JqZWN0LlR5cGUgIT0gTWFjaGluZVN0YWNrT2JqZWN0OjpWYXJpYWJsZVNpemVkKQorICAgICAgWWFtbElPLm1hcFJlcXVpcmVkKCJzaXplIiwgT2JqZWN0LlNpemUpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiYWxpZ25tZW50IiwgT2JqZWN0LkFsaWdubWVudCwgKHVuc2lnbmVkKTApOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgic3RhY2staWQiLCBPYmplY3QuU3RhY2tJRCk7CisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJjYWxsZWUtc2F2ZWQtcmVnaXN0ZXIiLCBPYmplY3QuQ2FsbGVlU2F2ZWRSZWdpc3RlciwKKyAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nVmFsdWUoKSk7IC8vIERvbid0IHByaW50IGl0IG91dCB3aGVuIGl0J3MgZW1wdHkuCisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJjYWxsZWUtc2F2ZWQtcmVzdG9yZWQiLCBPYmplY3QuQ2FsbGVlU2F2ZWRSZXN0b3JlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgdHJ1ZSk7CisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJsb2NhbC1vZmZzZXQiLCBPYmplY3QuTG9jYWxPZmZzZXQsIE9wdGlvbmFsPGludDY0X3Q+KCkpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiZGktdmFyaWFibGUiLCBPYmplY3QuRGVidWdWYXIsCisgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1ZhbHVlKCkpOyAvLyBEb24ndCBwcmludCBpdCBvdXQgd2hlbiBpdCdzIGVtcHR5LgorICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiZGktZXhwcmVzc2lvbiIsIE9iamVjdC5EZWJ1Z0V4cHIsCisgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1ZhbHVlKCkpOyAvLyBEb24ndCBwcmludCBpdCBvdXQgd2hlbiBpdCdzIGVtcHR5LgorICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiZGktbG9jYXRpb24iLCBPYmplY3QuRGVidWdMb2MsCisgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1ZhbHVlKCkpOyAvLyBEb24ndCBwcmludCBpdCBvdXQgd2hlbiBpdCdzIGVtcHR5LgorICB9CisKKyAgc3RhdGljIGNvbnN0IGJvb2wgZmxvdyA9IHRydWU7Cit9OworCisvLy8gU2VyaWFsaXphYmxlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBmaXhlZCBzdGFjayBvYmplY3QgZnJvbSB0aGUKKy8vLyBNYWNoaW5lRnJhbWVJbmZvIGNsYXNzLgorc3RydWN0IEZpeGVkTWFjaGluZVN0YWNrT2JqZWN0IHsKKyAgZW51bSBPYmplY3RUeXBlIHsgRGVmYXVsdFR5cGUsIFNwaWxsU2xvdCB9OworICBVbnNpZ25lZFZhbHVlIElEOworICBPYmplY3RUeXBlIFR5cGUgPSBEZWZhdWx0VHlwZTsKKyAgaW50NjRfdCBPZmZzZXQgPSAwOworICB1aW50NjRfdCBTaXplID0gMDsKKyAgdW5zaWduZWQgQWxpZ25tZW50ID0gMDsKKyAgdWludDhfdCBTdGFja0lEID0gMDsKKyAgYm9vbCBJc0ltbXV0YWJsZSA9IGZhbHNlOworICBib29sIElzQWxpYXNlZCA9IGZhbHNlOworICBTdHJpbmdWYWx1ZSBDYWxsZWVTYXZlZFJlZ2lzdGVyOworICBib29sIENhbGxlZVNhdmVkUmVzdG9yZWQgPSB0cnVlOworCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBGaXhlZE1hY2hpbmVTdGFja09iamVjdCAmT3RoZXIpIGNvbnN0IHsKKyAgICByZXR1cm4gSUQgPT0gT3RoZXIuSUQgJiYgVHlwZSA9PSBPdGhlci5UeXBlICYmIE9mZnNldCA9PSBPdGhlci5PZmZzZXQgJiYKKyAgICAgICAgICAgU2l6ZSA9PSBPdGhlci5TaXplICYmIEFsaWdubWVudCA9PSBPdGhlci5BbGlnbm1lbnQgJiYKKyAgICAgICAgICAgU3RhY2tJRCA9PSBPdGhlci5TdGFja0lEICYmCisgICAgICAgICAgIElzSW1tdXRhYmxlID09IE90aGVyLklzSW1tdXRhYmxlICYmIElzQWxpYXNlZCA9PSBPdGhlci5Jc0FsaWFzZWQgJiYKKyAgICAgICAgICAgQ2FsbGVlU2F2ZWRSZWdpc3RlciA9PSBPdGhlci5DYWxsZWVTYXZlZFJlZ2lzdGVyICYmCisgICAgICAgICAgIENhbGxlZVNhdmVkUmVzdG9yZWQgPT0gT3RoZXIuQ2FsbGVlU2F2ZWRSZXN0b3JlZDsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4KK3N0cnVjdCBTY2FsYXJFbnVtZXJhdGlvblRyYWl0czxGaXhlZE1hY2hpbmVTdGFja09iamVjdDo6T2JqZWN0VHlwZT4geworICBzdGF0aWMgdm9pZCBlbnVtZXJhdGlvbih5YW1sOjpJTyAmSU8sCisgICAgICAgICAgICAgICAgICAgICAgICAgIEZpeGVkTWFjaGluZVN0YWNrT2JqZWN0OjpPYmplY3RUeXBlICZUeXBlKSB7CisgICAgSU8uZW51bUNhc2UoVHlwZSwgImRlZmF1bHQiLCBGaXhlZE1hY2hpbmVTdGFja09iamVjdDo6RGVmYXVsdFR5cGUpOworICAgIElPLmVudW1DYXNlKFR5cGUsICJzcGlsbC1zbG90IiwgRml4ZWRNYWNoaW5lU3RhY2tPYmplY3Q6OlNwaWxsU2xvdCk7CisgIH0KK307CisKK3RlbXBsYXRlIDw+IHN0cnVjdCBNYXBwaW5nVHJhaXRzPEZpeGVkTWFjaGluZVN0YWNrT2JqZWN0PiB7CisgIHN0YXRpYyB2b2lkIG1hcHBpbmcoeWFtbDo6SU8gJllhbWxJTywgRml4ZWRNYWNoaW5lU3RhY2tPYmplY3QgJk9iamVjdCkgeworICAgIFlhbWxJTy5tYXBSZXF1aXJlZCgiaWQiLCBPYmplY3QuSUQpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgKKyAgICAgICAgInR5cGUiLCBPYmplY3QuVHlwZSwKKyAgICAgICAgRml4ZWRNYWNoaW5lU3RhY2tPYmplY3Q6OkRlZmF1bHRUeXBlKTsgLy8gRG9uJ3QgcHJpbnQgdGhlIGRlZmF1bHQgdHlwZS4KKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoIm9mZnNldCIsIE9iamVjdC5PZmZzZXQsIChpbnQ2NF90KTApOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgic2l6ZSIsIE9iamVjdC5TaXplLCAodWludDY0X3QpMCk7CisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJhbGlnbm1lbnQiLCBPYmplY3QuQWxpZ25tZW50LCAodW5zaWduZWQpMCk7CisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJzdGFjay1pZCIsIE9iamVjdC5TdGFja0lEKTsKKyAgICBpZiAoT2JqZWN0LlR5cGUgIT0gRml4ZWRNYWNoaW5lU3RhY2tPYmplY3Q6OlNwaWxsU2xvdCkgeworICAgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJpc0ltbXV0YWJsZSIsIE9iamVjdC5Jc0ltbXV0YWJsZSwgZmFsc2UpOworICAgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJpc0FsaWFzZWQiLCBPYmplY3QuSXNBbGlhc2VkLCBmYWxzZSk7CisgICAgfQorICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiY2FsbGVlLXNhdmVkLXJlZ2lzdGVyIiwgT2JqZWN0LkNhbGxlZVNhdmVkUmVnaXN0ZXIsCisgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1ZhbHVlKCkpOyAvLyBEb24ndCBwcmludCBpdCBvdXQgd2hlbiBpdCdzIGVtcHR5LgorICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiY2FsbGVlLXNhdmVkLXJlc3RvcmVkIiwgT2JqZWN0LkNhbGxlZVNhdmVkUmVzdG9yZWQsCisgICAgICAgICAgICAgICAgICAgICB0cnVlKTsKKyAgfQorCisgIHN0YXRpYyBjb25zdCBib29sIGZsb3cgPSB0cnVlOworfTsKKworc3RydWN0IE1hY2hpbmVDb25zdGFudFBvb2xWYWx1ZSB7CisgIFVuc2lnbmVkVmFsdWUgSUQ7CisgIFN0cmluZ1ZhbHVlIFZhbHVlOworICB1bnNpZ25lZCBBbGlnbm1lbnQgPSAwOworICBib29sIElzVGFyZ2V0U3BlY2lmaWMgPSBmYWxzZTsKKworICBib29sIG9wZXJhdG9yPT0oY29uc3QgTWFjaGluZUNvbnN0YW50UG9vbFZhbHVlICZPdGhlcikgY29uc3QgeworICAgIHJldHVybiBJRCA9PSBPdGhlci5JRCAmJiBWYWx1ZSA9PSBPdGhlci5WYWx1ZSAmJgorICAgICAgICAgICBBbGlnbm1lbnQgPT0gT3RoZXIuQWxpZ25tZW50ICYmCisgICAgICAgICAgIElzVGFyZ2V0U3BlY2lmaWMgPT0gT3RoZXIuSXNUYXJnZXRTcGVjaWZpYzsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IE1hcHBpbmdUcmFpdHM8TWFjaGluZUNvbnN0YW50UG9vbFZhbHVlPiB7CisgIHN0YXRpYyB2b2lkIG1hcHBpbmcoSU8gJllhbWxJTywgTWFjaGluZUNvbnN0YW50UG9vbFZhbHVlICZDb25zdGFudCkgeworICAgIFlhbWxJTy5tYXBSZXF1aXJlZCgiaWQiLCBDb25zdGFudC5JRCk7CisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJ2YWx1ZSIsIENvbnN0YW50LlZhbHVlLCBTdHJpbmdWYWx1ZSgpKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoImFsaWdubWVudCIsIENvbnN0YW50LkFsaWdubWVudCwgKHVuc2lnbmVkKTApOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiaXNUYXJnZXRTcGVjaWZpYyIsIENvbnN0YW50LklzVGFyZ2V0U3BlY2lmaWMsIGZhbHNlKTsKKyAgfQorfTsKKworc3RydWN0IE1hY2hpbmVKdW1wVGFibGUgeworICBzdHJ1Y3QgRW50cnkgeworICAgIFVuc2lnbmVkVmFsdWUgSUQ7CisgICAgc3RkOjp2ZWN0b3I8Rmxvd1N0cmluZ1ZhbHVlPiBCbG9ja3M7CisKKyAgICBib29sIG9wZXJhdG9yPT0oY29uc3QgRW50cnkgJk90aGVyKSBjb25zdCB7CisgICAgICByZXR1cm4gSUQgPT0gT3RoZXIuSUQgJiYgQmxvY2tzID09IE90aGVyLkJsb2NrczsKKyAgICB9CisgIH07CisKKyAgTWFjaGluZUp1bXBUYWJsZUluZm86OkpURW50cnlLaW5kIEtpbmQgPSBNYWNoaW5lSnVtcFRhYmxlSW5mbzo6RUtfQ3VzdG9tMzI7CisgIHN0ZDo6dmVjdG9yPEVudHJ5PiBFbnRyaWVzOworCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBNYWNoaW5lSnVtcFRhYmxlICZPdGhlcikgY29uc3QgeworICAgIHJldHVybiBLaW5kID09IE90aGVyLktpbmQgJiYgRW50cmllcyA9PSBPdGhlci5FbnRyaWVzOworICB9Cit9OworCit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgTWFwcGluZ1RyYWl0czxNYWNoaW5lSnVtcFRhYmxlOjpFbnRyeT4geworICBzdGF0aWMgdm9pZCBtYXBwaW5nKElPICZZYW1sSU8sIE1hY2hpbmVKdW1wVGFibGU6OkVudHJ5ICZFbnRyeSkgeworICAgIFlhbWxJTy5tYXBSZXF1aXJlZCgiaWQiLCBFbnRyeS5JRCk7CisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJibG9ja3MiLCBFbnRyeS5CbG9ja3MsIHN0ZDo6dmVjdG9yPEZsb3dTdHJpbmdWYWx1ZT4oKSk7CisgIH0KK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSB5YW1sCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCitMTFZNX1lBTUxfSVNfU0VRVUVOQ0VfVkVDVE9SKGxsdm06OnlhbWw6Ok1hY2hpbmVGdW5jdGlvbkxpdmVJbikKK0xMVk1fWUFNTF9JU19TRVFVRU5DRV9WRUNUT1IobGx2bTo6eWFtbDo6VmlydHVhbFJlZ2lzdGVyRGVmaW5pdGlvbikKK0xMVk1fWUFNTF9JU19TRVFVRU5DRV9WRUNUT1IobGx2bTo6eWFtbDo6TWFjaGluZVN0YWNrT2JqZWN0KQorTExWTV9ZQU1MX0lTX1NFUVVFTkNFX1ZFQ1RPUihsbHZtOjp5YW1sOjpGaXhlZE1hY2hpbmVTdGFja09iamVjdCkKK0xMVk1fWUFNTF9JU19TRVFVRU5DRV9WRUNUT1IobGx2bTo6eWFtbDo6TWFjaGluZUNvbnN0YW50UG9vbFZhbHVlKQorTExWTV9ZQU1MX0lTX1NFUVVFTkNFX1ZFQ1RPUihsbHZtOjp5YW1sOjpNYWNoaW5lSnVtcFRhYmxlOjpFbnRyeSkKKworbmFtZXNwYWNlIGxsdm0geworbmFtZXNwYWNlIHlhbWwgeworCit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgTWFwcGluZ1RyYWl0czxNYWNoaW5lSnVtcFRhYmxlPiB7CisgIHN0YXRpYyB2b2lkIG1hcHBpbmcoSU8gJllhbWxJTywgTWFjaGluZUp1bXBUYWJsZSAmSlQpIHsKKyAgICBZYW1sSU8ubWFwUmVxdWlyZWQoImtpbmQiLCBKVC5LaW5kKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoImVudHJpZXMiLCBKVC5FbnRyaWVzLAorICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnZlY3RvcjxNYWNoaW5lSnVtcFRhYmxlOjpFbnRyeT4oKSk7CisgIH0KK307CisKKy8vLyBTZXJpYWxpemFibGUgcmVwcmVzZW50YXRpb24gb2YgTWFjaGluZUZyYW1lSW5mby4KKy8vLworLy8vIERvZXNuJ3Qgc2VyaWFsaXplIGF0dHJpYnV0ZXMgbGlrZSAnU3RhY2tBbGlnbm1lbnQnLCAnSXNTdGFja1JlYWxpZ25hYmxlJyBhbmQKKy8vLyAnUmVhbGlnbk9wdGlvbicgYXMgdGhleSBhcmUgZGV0ZXJtaW5lZCBieSB0aGUgdGFyZ2V0IGFuZCBMTFZNIGZ1bmN0aW9uCisvLy8gYXR0cmlidXRlcy4KKy8vLyBJdCBhbHNvIGRvZXNuJ3Qgc2VyaWFsaXplIGF0dHJpYnV0ZXMgbGlrZSAnTnVtRml4ZWRPYmplY3QnIGFuZAorLy8vICdIYXNWYXJTaXplZE9iamVjdHMnIGFzIHRoZXkgYXJlIGRldGVybWluZWQgYnkgdGhlIGZyYW1lIG9iamVjdHMgdGhlbXNlbHZlcy4KK3N0cnVjdCBNYWNoaW5lRnJhbWVJbmZvIHsKKyAgYm9vbCBJc0ZyYW1lQWRkcmVzc1Rha2VuID0gZmFsc2U7CisgIGJvb2wgSXNSZXR1cm5BZGRyZXNzVGFrZW4gPSBmYWxzZTsKKyAgYm9vbCBIYXNTdGFja01hcCA9IGZhbHNlOworICBib29sIEhhc1BhdGNoUG9pbnQgPSBmYWxzZTsKKyAgdWludDY0X3QgU3RhY2tTaXplID0gMDsKKyAgaW50IE9mZnNldEFkanVzdG1lbnQgPSAwOworICB1bnNpZ25lZCBNYXhBbGlnbm1lbnQgPSAwOworICBib29sIEFkanVzdHNTdGFjayA9IGZhbHNlOworICBib29sIEhhc0NhbGxzID0gZmFsc2U7CisgIFN0cmluZ1ZhbHVlIFN0YWNrUHJvdGVjdG9yOworICAvLyBUT0RPOiBTZXJpYWxpemUgRnVuY3Rpb25Db250ZXh0SWR4CisgIHVuc2lnbmVkIE1heENhbGxGcmFtZVNpemUgPSB+MHU7IC8vLzwgfjB1IG1lYW5zOiBub3QgY29tcHV0ZWQgeWV0LgorICBib29sIEhhc09wYXF1ZVNQQWRqdXN0bWVudCA9IGZhbHNlOworICBib29sIEhhc1ZBU3RhcnQgPSBmYWxzZTsKKyAgYm9vbCBIYXNNdXN0VGFpbEluVmFyQXJnRnVuYyA9IGZhbHNlOworICBTdHJpbmdWYWx1ZSBTYXZlUG9pbnQ7CisgIFN0cmluZ1ZhbHVlIFJlc3RvcmVQb2ludDsKKworICBib29sIG9wZXJhdG9yPT0oY29uc3QgTWFjaGluZUZyYW1lSW5mbyAmT3RoZXIpIGNvbnN0IHsKKyAgICByZXR1cm4gSXNGcmFtZUFkZHJlc3NUYWtlbiA9PSBPdGhlci5Jc0ZyYW1lQWRkcmVzc1Rha2VuICYmCisgICAgICAgICAgIElzUmV0dXJuQWRkcmVzc1Rha2VuID09IE90aGVyLklzUmV0dXJuQWRkcmVzc1Rha2VuICYmCisgICAgICAgICAgIEhhc1N0YWNrTWFwID09IE90aGVyLkhhc1N0YWNrTWFwICYmCisgICAgICAgICAgIEhhc1BhdGNoUG9pbnQgPT0gT3RoZXIuSGFzUGF0Y2hQb2ludCAmJgorICAgICAgICAgICBTdGFja1NpemUgPT0gT3RoZXIuU3RhY2tTaXplICYmCisgICAgICAgICAgIE9mZnNldEFkanVzdG1lbnQgPT0gT3RoZXIuT2Zmc2V0QWRqdXN0bWVudCAmJgorICAgICAgICAgICBNYXhBbGlnbm1lbnQgPT0gT3RoZXIuTWF4QWxpZ25tZW50ICYmCisgICAgICAgICAgIEFkanVzdHNTdGFjayA9PSBPdGhlci5BZGp1c3RzU3RhY2sgJiYgSGFzQ2FsbHMgPT0gT3RoZXIuSGFzQ2FsbHMgJiYKKyAgICAgICAgICAgU3RhY2tQcm90ZWN0b3IgPT0gT3RoZXIuU3RhY2tQcm90ZWN0b3IgJiYKKyAgICAgICAgICAgTWF4Q2FsbEZyYW1lU2l6ZSA9PSBPdGhlci5NYXhDYWxsRnJhbWVTaXplICYmCisgICAgICAgICAgIEhhc09wYXF1ZVNQQWRqdXN0bWVudCA9PSBPdGhlci5IYXNPcGFxdWVTUEFkanVzdG1lbnQgJiYKKyAgICAgICAgICAgSGFzVkFTdGFydCA9PSBPdGhlci5IYXNWQVN0YXJ0ICYmCisgICAgICAgICAgIEhhc011c3RUYWlsSW5WYXJBcmdGdW5jID09IE90aGVyLkhhc011c3RUYWlsSW5WYXJBcmdGdW5jICYmCisgICAgICAgICAgIFNhdmVQb2ludCA9PSBPdGhlci5TYXZlUG9pbnQgJiYgUmVzdG9yZVBvaW50ID09IE90aGVyLlJlc3RvcmVQb2ludDsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IE1hcHBpbmdUcmFpdHM8TWFjaGluZUZyYW1lSW5mbz4geworICBzdGF0aWMgdm9pZCBtYXBwaW5nKElPICZZYW1sSU8sIE1hY2hpbmVGcmFtZUluZm8gJk1GSSkgeworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiaXNGcmFtZUFkZHJlc3NUYWtlbiIsIE1GSS5Jc0ZyYW1lQWRkcmVzc1Rha2VuLCBmYWxzZSk7CisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJpc1JldHVybkFkZHJlc3NUYWtlbiIsIE1GSS5Jc1JldHVybkFkZHJlc3NUYWtlbiwgZmFsc2UpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiaGFzU3RhY2tNYXAiLCBNRkkuSGFzU3RhY2tNYXAsIGZhbHNlKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoImhhc1BhdGNoUG9pbnQiLCBNRkkuSGFzUGF0Y2hQb2ludCwgZmFsc2UpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgic3RhY2tTaXplIiwgTUZJLlN0YWNrU2l6ZSwgKHVpbnQ2NF90KTApOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgib2Zmc2V0QWRqdXN0bWVudCIsIE1GSS5PZmZzZXRBZGp1c3RtZW50LCAoaW50KTApOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgibWF4QWxpZ25tZW50IiwgTUZJLk1heEFsaWdubWVudCwgKHVuc2lnbmVkKTApOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiYWRqdXN0c1N0YWNrIiwgTUZJLkFkanVzdHNTdGFjaywgZmFsc2UpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiaGFzQ2FsbHMiLCBNRkkuSGFzQ2FsbHMsIGZhbHNlKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoInN0YWNrUHJvdGVjdG9yIiwgTUZJLlN0YWNrUHJvdGVjdG9yLAorICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdWYWx1ZSgpKTsgLy8gRG9uJ3QgcHJpbnQgaXQgb3V0IHdoZW4gaXQncyBlbXB0eS4KKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoIm1heENhbGxGcmFtZVNpemUiLCBNRkkuTWF4Q2FsbEZyYW1lU2l6ZSwgKHVuc2lnbmVkKX4wKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoImhhc09wYXF1ZVNQQWRqdXN0bWVudCIsIE1GSS5IYXNPcGFxdWVTUEFkanVzdG1lbnQsCisgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoImhhc1ZBU3RhcnQiLCBNRkkuSGFzVkFTdGFydCwgZmFsc2UpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiaGFzTXVzdFRhaWxJblZhckFyZ0Z1bmMiLCBNRkkuSGFzTXVzdFRhaWxJblZhckFyZ0Z1bmMsCisgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoInNhdmVQb2ludCIsIE1GSS5TYXZlUG9pbnQsCisgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZ1ZhbHVlKCkpOyAvLyBEb24ndCBwcmludCBpdCBvdXQgd2hlbiBpdCdzIGVtcHR5LgorICAgIFlhbWxJTy5tYXBPcHRpb25hbCgicmVzdG9yZVBvaW50IiwgTUZJLlJlc3RvcmVQb2ludCwKKyAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nVmFsdWUoKSk7IC8vIERvbid0IHByaW50IGl0IG91dCB3aGVuIGl0J3MgZW1wdHkuCisgIH0KK307CisKK3N0cnVjdCBNYWNoaW5lRnVuY3Rpb24geworICBTdHJpbmdSZWYgTmFtZTsKKyAgdW5zaWduZWQgQWxpZ25tZW50ID0gMDsKKyAgYm9vbCBFeHBvc2VzUmV0dXJuc1R3aWNlID0gZmFsc2U7CisgIC8vIEdJU2VsIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMuCisgIGJvb2wgTGVnYWxpemVkID0gZmFsc2U7CisgIGJvb2wgUmVnQmFua1NlbGVjdGVkID0gZmFsc2U7CisgIGJvb2wgU2VsZWN0ZWQgPSBmYWxzZTsKKyAgYm9vbCBGYWlsZWRJU2VsID0gZmFsc2U7CisgIC8vIFJlZ2lzdGVyIGluZm9ybWF0aW9uCisgIGJvb2wgVHJhY2tzUmVnTGl2ZW5lc3MgPSBmYWxzZTsKKyAgc3RkOjp2ZWN0b3I8VmlydHVhbFJlZ2lzdGVyRGVmaW5pdGlvbj4gVmlydHVhbFJlZ2lzdGVyczsKKyAgc3RkOjp2ZWN0b3I8TWFjaGluZUZ1bmN0aW9uTGl2ZUluPiBMaXZlSW5zOworICBPcHRpb25hbDxzdGQ6OnZlY3RvcjxGbG93U3RyaW5nVmFsdWU+PiBDYWxsZWVTYXZlZFJlZ2lzdGVyczsKKyAgLy8gVE9ETzogU2VyaWFsaXplIHRoZSB2YXJpb3VzIHJlZ2lzdGVyIG1hc2tzLgorICAvLyBGcmFtZSBpbmZvcm1hdGlvbgorICBNYWNoaW5lRnJhbWVJbmZvIEZyYW1lSW5mbzsKKyAgc3RkOjp2ZWN0b3I8Rml4ZWRNYWNoaW5lU3RhY2tPYmplY3Q+IEZpeGVkU3RhY2tPYmplY3RzOworICBzdGQ6OnZlY3RvcjxNYWNoaW5lU3RhY2tPYmplY3Q+IFN0YWNrT2JqZWN0czsKKyAgc3RkOjp2ZWN0b3I8TWFjaGluZUNvbnN0YW50UG9vbFZhbHVlPiBDb25zdGFudHM7IC8vLyBDb25zdGFudCBwb29sLgorICBNYWNoaW5lSnVtcFRhYmxlIEp1bXBUYWJsZUluZm87CisgIEJsb2NrU3RyaW5nVmFsdWUgQm9keTsKK307CisKK3RlbXBsYXRlIDw+IHN0cnVjdCBNYXBwaW5nVHJhaXRzPE1hY2hpbmVGdW5jdGlvbj4geworICBzdGF0aWMgdm9pZCBtYXBwaW5nKElPICZZYW1sSU8sIE1hY2hpbmVGdW5jdGlvbiAmTUYpIHsKKyAgICBZYW1sSU8ubWFwUmVxdWlyZWQoIm5hbWUiLCBNRi5OYW1lKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoImFsaWdubWVudCIsIE1GLkFsaWdubWVudCwgKHVuc2lnbmVkKTApOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiZXhwb3Nlc1JldHVybnNUd2ljZSIsIE1GLkV4cG9zZXNSZXR1cm5zVHdpY2UsIGZhbHNlKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoImxlZ2FsaXplZCIsIE1GLkxlZ2FsaXplZCwgZmFsc2UpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgicmVnQmFua1NlbGVjdGVkIiwgTUYuUmVnQmFua1NlbGVjdGVkLCBmYWxzZSk7CisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJzZWxlY3RlZCIsIE1GLlNlbGVjdGVkLCBmYWxzZSk7CisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJmYWlsZWRJU2VsIiwgTUYuRmFpbGVkSVNlbCwgZmFsc2UpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgidHJhY2tzUmVnTGl2ZW5lc3MiLCBNRi5UcmFja3NSZWdMaXZlbmVzcywgZmFsc2UpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgicmVnaXN0ZXJzIiwgTUYuVmlydHVhbFJlZ2lzdGVycywKKyAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8VmlydHVhbFJlZ2lzdGVyRGVmaW5pdGlvbj4oKSk7CisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJsaXZlaW5zIiwgTUYuTGl2ZUlucywKKyAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8TWFjaGluZUZ1bmN0aW9uTGl2ZUluPigpKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoImNhbGxlZVNhdmVkUmVnaXN0ZXJzIiwgTUYuQ2FsbGVlU2F2ZWRSZWdpc3RlcnMsCisgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsPHN0ZDo6dmVjdG9yPEZsb3dTdHJpbmdWYWx1ZT4+KCkpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiZnJhbWVJbmZvIiwgTUYuRnJhbWVJbmZvLCBNYWNoaW5lRnJhbWVJbmZvKCkpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiZml4ZWRTdGFjayIsIE1GLkZpeGVkU3RhY2tPYmplY3RzLAorICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnZlY3RvcjxGaXhlZE1hY2hpbmVTdGFja09iamVjdD4oKSk7CisgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJzdGFjayIsIE1GLlN0YWNrT2JqZWN0cywKKyAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8TWFjaGluZVN0YWNrT2JqZWN0PigpKTsKKyAgICBZYW1sSU8ubWFwT3B0aW9uYWwoImNvbnN0YW50cyIsIE1GLkNvbnN0YW50cywKKyAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8TWFjaGluZUNvbnN0YW50UG9vbFZhbHVlPigpKTsKKyAgICBpZiAoIVlhbWxJTy5vdXRwdXR0aW5nKCkgfHwgIU1GLkp1bXBUYWJsZUluZm8uRW50cmllcy5lbXB0eSgpKQorICAgICAgWWFtbElPLm1hcE9wdGlvbmFsKCJqdW1wVGFibGUiLCBNRi5KdW1wVGFibGVJbmZvLCBNYWNoaW5lSnVtcFRhYmxlKCkpOworICAgIFlhbWxJTy5tYXBPcHRpb25hbCgiYm9keSIsIE1GLkJvZHksIEJsb2NrU3RyaW5nVmFsdWUoKSk7CisgIH0KK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSB5YW1sCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX01JUllBTUxNQVBQSU5HX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoT1JlbG9jYXRpb24uaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoT1JlbG9jYXRpb24uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YzliN2E4Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hPUmVsb2NhdGlvbi5oCkBAIC0wLDAgKzEsNTYgQEAKKy8vPT09IE1hY2hPUmVsb2NhdGlvbi5oIC0gTWFjaC1PIFJlbG9jYXRpb24gSW5mbyAtLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlZmluZXMgdGhlIE1hY2hPUmVsb2NhdGlvbiBjbGFzcy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ0hPUkVMT0NBVElPTl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9NQUNIT1JFTE9DQVRJT05fSAorCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0RhdGFUeXBlcy5oIgorCituYW1lc3BhY2UgbGx2bSB7CisKKyAgLy8vIE1hY2hPUmVsb2NhdGlvbiAtIFRoaXMgc3RydWN0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IGVhY2ggcmVsb2NhdGlvbgorICAvLy8gdGhhdCBuZWVkcyB0byBiZSBlbWl0dGVkIHRvIHRoZSBmaWxlLgorICAvLy8gc2VlIDxtYWNoLW8vcmVsb2MuaD4KKyAgY2xhc3MgTWFjaE9SZWxvY2F0aW9uIHsKKyAgICB1aW50MzJfdCByX2FkZHJlc3M7ICAgLy8gb2Zmc2V0IGluIHRoZSBzZWN0aW9uIHRvIHdoYXQgaXMgYmVpbmcgIHJlbG9jYXRlZAorICAgIHVpbnQzMl90IHJfc3ltYm9sbnVtOyAvLyBzeW1ib2wgaW5kZXggaWYgcl9leHRlcm4gPT0gMSBlbHNlIHNlY3Rpb24gaW5kZXgKKyAgICBib29sICAgICByX3BjcmVsOyAgICAgLy8gd2FzIHJlbG9jYXRlZCBwYy1yZWxhdGl2ZSBhbHJlYWR5CisgICAgdWludDhfdCAgcl9sZW5ndGg7ICAgIC8vIGxlbmd0aCA9IDIgXiByX2xlbmd0aAorICAgIGJvb2wgICAgIHJfZXh0ZXJuOyAgICAvLyAKKyAgICB1aW50OF90ICByX3R5cGU7ICAgICAgLy8gaWYgbm90IDAsIG1hY2hpbmUtc3BlY2lmaWMgcmVsb2NhdGlvbiB0eXBlLgorICAgIGJvb2wgICAgIHJfc2NhdHRlcmVkOyAvLyAxID0gc2NhdHRlcmVkLCAwID0gbm9uLXNjYXR0ZXJlZAorICAgIGludDMyX3QgIHJfdmFsdWU7ICAgICAvLyB0aGUgdmFsdWUgdGhlIGl0ZW0gdG8gYmUgcmVsb2NhdGVkIGlzIHJlZmVycmluZworICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0by4KKyAgcHVibGljOiAgICAgIAorICAgIHVpbnQzMl90IGdldFBhY2tlZEZpZWxkcygpIGNvbnN0IHsKKyAgICAgIGlmIChyX3NjYXR0ZXJlZCkKKyAgICAgICAgcmV0dXJuICgxIDw8IDMxKSB8IChyX3BjcmVsIDw8IDMwKSB8ICgocl9sZW5ndGggJiAzKSA8PCAyOCkgfCAKKyAgICAgICAgICAoKHJfdHlwZSAmIDE1KSA8PCAyNCkgfCAocl9hZGRyZXNzICYgMHgwMEZGRkZGRik7CisgICAgICBlbHNlCisgICAgICAgIHJldHVybiAocl9zeW1ib2xudW0gPDwgOCkgfCAocl9wY3JlbCA8PCA3KSB8ICgocl9sZW5ndGggJiAzKSA8PCA1KSB8CisgICAgICAgICAgKHJfZXh0ZXJuIDw8IDQpIHwgKHJfdHlwZSAmIDE1KTsKKyAgICB9CisgICAgdWludDMyX3QgZ2V0QWRkcmVzcygpIGNvbnN0IHsgcmV0dXJuIHJfc2NhdHRlcmVkID8gcl92YWx1ZSA6IHJfYWRkcmVzczsgfQorICAgIHVpbnQzMl90IGdldFJhd0FkZHJlc3MoKSBjb25zdCB7IHJldHVybiByX2FkZHJlc3M7IH0KKworICAgIE1hY2hPUmVsb2NhdGlvbih1aW50MzJfdCBhZGRyLCB1aW50MzJfdCBpbmRleCwgYm9vbCBwY3JlbCwgdWludDhfdCBsZW4sCisgICAgICAgICAgICAgICAgICAgIGJvb2wgZXh0LCB1aW50OF90IHR5cGUsIGJvb2wgc2NhdHRlcmVkID0gZmFsc2UsIAorICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHZhbHVlID0gMCkgOiAKKyAgICAgIHJfYWRkcmVzcyhhZGRyKSwgcl9zeW1ib2xudW0oaW5kZXgpLCByX3BjcmVsKHBjcmVsKSwgcl9sZW5ndGgobGVuKSwKKyAgICAgIHJfZXh0ZXJuKGV4dCksIHJfdHlwZSh0eXBlKSwgcl9zY2F0dGVyZWQoc2NhdHRlcmVkKSwgcl92YWx1ZSh2YWx1ZSkge30KKyAgfTsKKworfSAvLyBlbmQgbGx2bSBuYW1lc3BhY2UKKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9NQUNIT1JFTE9DQVRJT05fSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVCYXNpY0Jsb2NrLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMzEzMGI2Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVCYXNpY0Jsb2NrLmgKQEAgLTAsMCArMSw5MTggQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gQ29sbGVjdCB0aGUgc2VxdWVuY2Ugb2YgbWFjaGluZSBpbnN0cnVjdGlvbnMgZm9yIGEgYmFzaWMgYmxvY2suCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORUJBU0lDQkxPQ0tfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTUFDSElORUJBU0lDQkxPQ0tfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvR3JhcGhUcmFpdHMuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9pbGlzdC5oIgorI2luY2x1ZGUgImxsdm0vQURUL2lsaXN0X25vZGUuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9pdGVyYXRvcl9yYW5nZS5oIgorI2luY2x1ZGUgImxsdm0vQURUL3NpbXBsZV9pbGlzdC5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lSW5zdHIuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0RlYnVnTG9jLmgiCisjaW5jbHVkZSAibGx2bS9NQy9MYW5lQml0bWFzay5oIgorI2luY2x1ZGUgImxsdm0vTUMvTUNSZWdpc3RlckluZm8uaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvQnJhbmNoUHJvYmFiaWxpdHkuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvUHJpbnRhYmxlLmgiCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CisjaW5jbHVkZSA8aXRlcmF0b3I+CisjaW5jbHVkZSA8c3RyaW5nPgorI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBCYXNpY0Jsb2NrOworY2xhc3MgTWFjaGluZUZ1bmN0aW9uOworY2xhc3MgTUNTeW1ib2w7CitjbGFzcyBNb2R1bGVTbG90VHJhY2tlcjsKK2NsYXNzIFBhc3M7CitjbGFzcyBTbG90SW5kZXhlczsKK2NsYXNzIFN0cmluZ1JlZjsKK2NsYXNzIHJhd19vc3RyZWFtOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJDbGFzczsKK2NsYXNzIFRhcmdldFJlZ2lzdGVySW5mbzsKKwordGVtcGxhdGUgPD4gc3RydWN0IGlsaXN0X3RyYWl0czxNYWNoaW5lSW5zdHI+IHsKK3ByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBNYWNoaW5lQmFzaWNCbG9jazsgLy8gU2V0IGJ5IHRoZSBvd25pbmcgTWFjaGluZUJhc2ljQmxvY2suCisKKyAgTWFjaGluZUJhc2ljQmxvY2sgKlBhcmVudDsKKworICB1c2luZyBpbnN0cl9pdGVyYXRvciA9CisgICAgICBzaW1wbGVfaWxpc3Q8TWFjaGluZUluc3RyLCBpbGlzdF9zZW50aW5lbF90cmFja2luZzx0cnVlPj46Oml0ZXJhdG9yOworCitwdWJsaWM6CisgIHZvaWQgYWRkTm9kZVRvTGlzdChNYWNoaW5lSW5zdHIgKk4pOworICB2b2lkIHJlbW92ZU5vZGVGcm9tTGlzdChNYWNoaW5lSW5zdHIgKk4pOworICB2b2lkIHRyYW5zZmVyTm9kZXNGcm9tTGlzdChpbGlzdF90cmFpdHMgJk9sZExpc3QsIGluc3RyX2l0ZXJhdG9yIEZpcnN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnN0cl9pdGVyYXRvciBMYXN0KTsKKyAgdm9pZCBkZWxldGVOb2RlKE1hY2hpbmVJbnN0ciAqTUkpOworfTsKKworY2xhc3MgTWFjaGluZUJhc2ljQmxvY2sKKyAgICA6IHB1YmxpYyBpbGlzdF9ub2RlX3dpdGhfcGFyZW50PE1hY2hpbmVCYXNpY0Jsb2NrLCBNYWNoaW5lRnVuY3Rpb24+IHsKK3B1YmxpYzoKKyAgLy8vIFBhaXIgb2YgcGh5c2ljYWwgcmVnaXN0ZXIgYW5kIGxhbmUgbWFzay4KKyAgLy8vIFRoaXMgaXMgbm90IHNpbXBseSBhIHN0ZDo6cGFpciB0eXBlZGVmIGJlY2F1c2UgdGhlIG1lbWJlcnMgc2hvdWxkIGJlIG5hbWVkCisgIC8vLyBjbGVhcmx5IGFzIHRoZXkgYm90aCBoYXZlIGFuIGludGVnZXIgdHlwZS4KKyAgc3RydWN0IFJlZ2lzdGVyTWFza1BhaXIgeworICBwdWJsaWM6CisgICAgTUNQaHlzUmVnIFBoeXNSZWc7CisgICAgTGFuZUJpdG1hc2sgTGFuZU1hc2s7CisKKyAgICBSZWdpc3Rlck1hc2tQYWlyKE1DUGh5c1JlZyBQaHlzUmVnLCBMYW5lQml0bWFzayBMYW5lTWFzaykKKyAgICAgICAgOiBQaHlzUmVnKFBoeXNSZWcpLCBMYW5lTWFzayhMYW5lTWFzaykge30KKyAgfTsKKworcHJpdmF0ZToKKyAgdXNpbmcgSW5zdHJ1Y3Rpb25zID0gaWxpc3Q8TWFjaGluZUluc3RyLCBpbGlzdF9zZW50aW5lbF90cmFja2luZzx0cnVlPj47CisKKyAgSW5zdHJ1Y3Rpb25zIEluc3RzOworICBjb25zdCBCYXNpY0Jsb2NrICpCQjsKKyAgaW50IE51bWJlcjsKKyAgTWFjaGluZUZ1bmN0aW9uICp4UGFyZW50OworCisgIC8vLyBLZWVwIHRyYWNrIG9mIHRoZSBwcmVkZWNlc3NvciAvIHN1Y2Nlc3NvciBiYXNpYyBibG9ja3MuCisgIHN0ZDo6dmVjdG9yPE1hY2hpbmVCYXNpY0Jsb2NrICo+IFByZWRlY2Vzc29yczsKKyAgc3RkOjp2ZWN0b3I8TWFjaGluZUJhc2ljQmxvY2sgKj4gU3VjY2Vzc29yczsKKworICAvLy8gS2VlcCB0cmFjayBvZiB0aGUgcHJvYmFiaWxpdGllcyB0byB0aGUgc3VjY2Vzc29ycy4gVGhpcyB2ZWN0b3IgaGFzIHRoZQorICAvLy8gc2FtZSBvcmRlciBhcyBTdWNjZXNzb3JzLCBvciBpdCBpcyBlbXB0eSBpZiB3ZSBkb24ndCB1c2UgaXQgKGRpc2FibGUKKyAgLy8vIG9wdGltaXphdGlvbikuCisgIHN0ZDo6dmVjdG9yPEJyYW5jaFByb2JhYmlsaXR5PiBQcm9iczsKKyAgdXNpbmcgcHJvYmFiaWxpdHlfaXRlcmF0b3IgPSBzdGQ6OnZlY3RvcjxCcmFuY2hQcm9iYWJpbGl0eT46Oml0ZXJhdG9yOworICB1c2luZyBjb25zdF9wcm9iYWJpbGl0eV9pdGVyYXRvciA9CisgICAgICBzdGQ6OnZlY3RvcjxCcmFuY2hQcm9iYWJpbGl0eT46OmNvbnN0X2l0ZXJhdG9yOworCisgIE9wdGlvbmFsPHVpbnQ2NF90PiBJcnJMb29wSGVhZGVyV2VpZ2h0OworCisgIC8vLyBLZWVwIHRyYWNrIG9mIHRoZSBwaHlzaWNhbCByZWdpc3RlcnMgdGhhdCBhcmUgbGl2ZWluIG9mIHRoZSBiYXNpY2Jsb2NrLgorICB1c2luZyBMaXZlSW5WZWN0b3IgPSBzdGQ6OnZlY3RvcjxSZWdpc3Rlck1hc2tQYWlyPjsKKyAgTGl2ZUluVmVjdG9yIExpdmVJbnM7CisKKyAgLy8vIEFsaWdubWVudCBvZiB0aGUgYmFzaWMgYmxvY2suIFplcm8gaWYgdGhlIGJhc2ljIGJsb2NrIGRvZXMgbm90IG5lZWQgdG8gYmUKKyAgLy8vIGFsaWduZWQuIFRoZSBhbGlnbm1lbnQgaXMgc3BlY2lmaWVkIGFzIGxvZzIoYnl0ZXMpLgorICB1bnNpZ25lZCBBbGlnbm1lbnQgPSAwOworCisgIC8vLyBJbmRpY2F0ZSB0aGF0IHRoaXMgYmFzaWMgYmxvY2sgaXMgZW50ZXJlZCB2aWEgYW4gZXhjZXB0aW9uIGhhbmRsZXIuCisgIGJvb2wgSXNFSFBhZCA9IGZhbHNlOworCisgIC8vLyBJbmRpY2F0ZSB0aGF0IHRoaXMgYmFzaWMgYmxvY2sgaXMgcG90ZW50aWFsbHkgdGhlIHRhcmdldCBvZiBhbiBpbmRpcmVjdAorICAvLy8gYnJhbmNoLgorICBib29sIEFkZHJlc3NUYWtlbiA9IGZhbHNlOworCisgIC8vLyBJbmRpY2F0ZSB0aGF0IHRoaXMgYmFzaWMgYmxvY2sgaXMgdGhlIGVudHJ5IGJsb2NrIG9mIGFuIEVIIGZ1bmNsZXQuCisgIGJvb2wgSXNFSEZ1bmNsZXRFbnRyeSA9IGZhbHNlOworCisgIC8vLyBJbmRpY2F0ZSB0aGF0IHRoaXMgYmFzaWMgYmxvY2sgaXMgdGhlIGVudHJ5IGJsb2NrIG9mIGEgY2xlYW51cCBmdW5jbGV0LgorICBib29sIElzQ2xlYW51cEZ1bmNsZXRFbnRyeSA9IGZhbHNlOworCisgIC8vLyBcYnJpZWYgc2luY2UgZ2V0U3ltYm9sIGlzIGEgcmVsYXRpdmVseSBoZWF2eS13ZWlnaHQgb3BlcmF0aW9uLCB0aGUgc3ltYm9sCisgIC8vLyBpcyBvbmx5IGNvbXB1dGVkIG9uY2UgYW5kIGlzIGNhY2hlZC4KKyAgbXV0YWJsZSBNQ1N5bWJvbCAqQ2FjaGVkTUNTeW1ib2wgPSBudWxscHRyOworCisgIC8vIEludHJ1c2l2ZSBsaXN0IHN1cHBvcnQKKyAgTWFjaGluZUJhc2ljQmxvY2soKSA9IGRlZmF1bHQ7CisKKyAgZXhwbGljaXQgTWFjaGluZUJhc2ljQmxvY2soTWFjaGluZUZ1bmN0aW9uICZNRiwgY29uc3QgQmFzaWNCbG9jayAqQkIpOworCisgIH5NYWNoaW5lQmFzaWNCbG9jaygpOworCisgIC8vIE1hY2hpbmVCYXNpY0Jsb2NrcyBhcmUgYWxsb2NhdGVkIGFuZCBvd25lZCBieSBNYWNoaW5lRnVuY3Rpb24uCisgIGZyaWVuZCBjbGFzcyBNYWNoaW5lRnVuY3Rpb247CisKK3B1YmxpYzoKKyAgLy8vIFJldHVybiB0aGUgTExWTSBiYXNpYyBibG9jayB0aGF0IHRoaXMgaW5zdGFuY2UgY29ycmVzcG9uZGVkIHRvIG9yaWdpbmFsbHkuCisgIC8vLyBOb3RlIHRoYXQgdGhpcyBtYXkgYmUgTlVMTCBpZiB0aGlzIGluc3RhbmNlIGRvZXMgbm90IGNvcnJlc3BvbmQgZGlyZWN0bHkKKyAgLy8vIHRvIGFuIExMVk0gYmFzaWMgYmxvY2suCisgIGNvbnN0IEJhc2ljQmxvY2sgKmdldEJhc2ljQmxvY2soKSBjb25zdCB7IHJldHVybiBCQjsgfQorCisgIC8vLyBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGNvcnJlc3BvbmRpbmcgTExWTSBiYXNpYyBibG9jaywgb3IgYW4gZW1wdHkgc3RyaW5nLgorICBTdHJpbmdSZWYgZ2V0TmFtZSgpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gYSBmb3JtYXR0ZWQgc3RyaW5nIHRvIGlkZW50aWZ5IHRoaXMgYmxvY2sgYW5kIGl0cyBwYXJlbnQgZnVuY3Rpb24uCisgIHN0ZDo6c3RyaW5nIGdldEZ1bGxOYW1lKCkgY29uc3Q7CisKKyAgLy8vIFRlc3Qgd2hldGhlciB0aGlzIGJsb2NrIGlzIHBvdGVudGlhbGx5IHRoZSB0YXJnZXQgb2YgYW4gaW5kaXJlY3QgYnJhbmNoLgorICBib29sIGhhc0FkZHJlc3NUYWtlbigpIGNvbnN0IHsgcmV0dXJuIEFkZHJlc3NUYWtlbjsgfQorCisgIC8vLyBTZXQgdGhpcyBibG9jayB0byByZWZsZWN0IHRoYXQgaXQgcG90ZW50aWFsbHkgaXMgdGhlIHRhcmdldCBvZiBhbiBpbmRpcmVjdAorICAvLy8gYnJhbmNoLgorICB2b2lkIHNldEhhc0FkZHJlc3NUYWtlbigpIHsgQWRkcmVzc1Rha2VuID0gdHJ1ZTsgfQorCisgIC8vLyBSZXR1cm4gdGhlIE1hY2hpbmVGdW5jdGlvbiBjb250YWluaW5nIHRoaXMgYmFzaWMgYmxvY2suCisgIGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAqZ2V0UGFyZW50KCkgY29uc3QgeyByZXR1cm4geFBhcmVudDsgfQorICBNYWNoaW5lRnVuY3Rpb24gKmdldFBhcmVudCgpIHsgcmV0dXJuIHhQYXJlbnQ7IH0KKworICB1c2luZyBpbnN0cl9pdGVyYXRvciA9IEluc3RydWN0aW9uczo6aXRlcmF0b3I7CisgIHVzaW5nIGNvbnN0X2luc3RyX2l0ZXJhdG9yID0gSW5zdHJ1Y3Rpb25zOjpjb25zdF9pdGVyYXRvcjsKKyAgdXNpbmcgcmV2ZXJzZV9pbnN0cl9pdGVyYXRvciA9IEluc3RydWN0aW9uczo6cmV2ZXJzZV9pdGVyYXRvcjsKKyAgdXNpbmcgY29uc3RfcmV2ZXJzZV9pbnN0cl9pdGVyYXRvciA9IEluc3RydWN0aW9uczo6Y29uc3RfcmV2ZXJzZV9pdGVyYXRvcjsKKworICB1c2luZyBpdGVyYXRvciA9IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yPE1hY2hpbmVJbnN0cj47CisgIHVzaW5nIGNvbnN0X2l0ZXJhdG9yID0gTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3I8Y29uc3QgTWFjaGluZUluc3RyPjsKKyAgdXNpbmcgcmV2ZXJzZV9pdGVyYXRvciA9IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yPE1hY2hpbmVJbnN0ciwgdHJ1ZT47CisgIHVzaW5nIGNvbnN0X3JldmVyc2VfaXRlcmF0b3IgPQorICAgICAgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3I8Y29uc3QgTWFjaGluZUluc3RyLCB0cnVlPjsKKworICB1bnNpZ25lZCBzaXplKCkgY29uc3QgeyByZXR1cm4gKHVuc2lnbmVkKUluc3RzLnNpemUoKTsgfQorICBib29sIGVtcHR5KCkgY29uc3QgeyByZXR1cm4gSW5zdHMuZW1wdHkoKTsgfQorCisgIE1hY2hpbmVJbnN0ciAgICAgICAmaW5zdHJfZnJvbnQoKSAgICAgICB7IHJldHVybiBJbnN0cy5mcm9udCgpOyB9CisgIE1hY2hpbmVJbnN0ciAgICAgICAmaW5zdHJfYmFjaygpICAgICAgICB7IHJldHVybiBJbnN0cy5iYWNrKCk7ICB9CisgIGNvbnN0IE1hY2hpbmVJbnN0ciAmaW5zdHJfZnJvbnQoKSBjb25zdCB7IHJldHVybiBJbnN0cy5mcm9udCgpOyB9CisgIGNvbnN0IE1hY2hpbmVJbnN0ciAmaW5zdHJfYmFjaygpICBjb25zdCB7IHJldHVybiBJbnN0cy5iYWNrKCk7ICB9CisKKyAgTWFjaGluZUluc3RyICAgICAgICZmcm9udCgpICAgICAgICAgICAgIHsgcmV0dXJuIEluc3RzLmZyb250KCk7IH0KKyAgTWFjaGluZUluc3RyICAgICAgICZiYWNrKCkgICAgICAgICAgICAgIHsgcmV0dXJuICotLWVuZCgpOyAgICAgIH0KKyAgY29uc3QgTWFjaGluZUluc3RyICZmcm9udCgpICAgICAgIGNvbnN0IHsgcmV0dXJuIEluc3RzLmZyb250KCk7IH0KKyAgY29uc3QgTWFjaGluZUluc3RyICZiYWNrKCkgICAgICAgIGNvbnN0IHsgcmV0dXJuICotLWVuZCgpOyAgICAgIH0KKworICBpbnN0cl9pdGVyYXRvciAgICAgICAgICAgICAgICBpbnN0cl9iZWdpbigpICAgICAgIHsgcmV0dXJuIEluc3RzLmJlZ2luKCk7ICB9CisgIGNvbnN0X2luc3RyX2l0ZXJhdG9yICAgICAgICAgIGluc3RyX2JlZ2luKCkgY29uc3QgeyByZXR1cm4gSW5zdHMuYmVnaW4oKTsgIH0KKyAgaW5zdHJfaXRlcmF0b3IgICAgICAgICAgICAgICAgICBpbnN0cl9lbmQoKSAgICAgICB7IHJldHVybiBJbnN0cy5lbmQoKTsgICAgfQorICBjb25zdF9pbnN0cl9pdGVyYXRvciAgICAgICAgICAgIGluc3RyX2VuZCgpIGNvbnN0IHsgcmV0dXJuIEluc3RzLmVuZCgpOyAgICB9CisgIHJldmVyc2VfaW5zdHJfaXRlcmF0b3IgICAgICAgaW5zdHJfcmJlZ2luKCkgICAgICAgeyByZXR1cm4gSW5zdHMucmJlZ2luKCk7IH0KKyAgY29uc3RfcmV2ZXJzZV9pbnN0cl9pdGVyYXRvciBpbnN0cl9yYmVnaW4oKSBjb25zdCB7IHJldHVybiBJbnN0cy5yYmVnaW4oKTsgfQorICByZXZlcnNlX2luc3RyX2l0ZXJhdG9yICAgICAgIGluc3RyX3JlbmQgICgpICAgICAgIHsgcmV0dXJuIEluc3RzLnJlbmQoKTsgICB9CisgIGNvbnN0X3JldmVyc2VfaW5zdHJfaXRlcmF0b3IgaW5zdHJfcmVuZCAgKCkgY29uc3QgeyByZXR1cm4gSW5zdHMucmVuZCgpOyAgIH0KKworICB1c2luZyBpbnN0cl9yYW5nZSA9IGl0ZXJhdG9yX3JhbmdlPGluc3RyX2l0ZXJhdG9yPjsKKyAgdXNpbmcgY29uc3RfaW5zdHJfcmFuZ2UgPSBpdGVyYXRvcl9yYW5nZTxjb25zdF9pbnN0cl9pdGVyYXRvcj47CisgIGluc3RyX3JhbmdlIGluc3RycygpIHsgcmV0dXJuIGluc3RyX3JhbmdlKGluc3RyX2JlZ2luKCksIGluc3RyX2VuZCgpKTsgfQorICBjb25zdF9pbnN0cl9yYW5nZSBpbnN0cnMoKSBjb25zdCB7CisgICAgcmV0dXJuIGNvbnN0X2luc3RyX3JhbmdlKGluc3RyX2JlZ2luKCksIGluc3RyX2VuZCgpKTsKKyAgfQorCisgIGl0ZXJhdG9yICAgICAgICAgICAgICAgIGJlZ2luKCkgICAgICAgeyByZXR1cm4gaW5zdHJfYmVnaW4oKTsgIH0KKyAgY29uc3RfaXRlcmF0b3IgICAgICAgICAgYmVnaW4oKSBjb25zdCB7IHJldHVybiBpbnN0cl9iZWdpbigpOyAgfQorICBpdGVyYXRvciAgICAgICAgICAgICAgICBlbmQgICgpICAgICAgIHsgcmV0dXJuIGluc3RyX2VuZCgpOyAgICB9CisgIGNvbnN0X2l0ZXJhdG9yICAgICAgICAgIGVuZCAgKCkgY29uc3QgeyByZXR1cm4gaW5zdHJfZW5kKCk7ICAgIH0KKyAgcmV2ZXJzZV9pdGVyYXRvciByYmVnaW4oKSB7CisgICAgcmV0dXJuIHJldmVyc2VfaXRlcmF0b3I6OmdldEF0QnVuZGxlQmVnaW4oaW5zdHJfcmJlZ2luKCkpOworICB9CisgIGNvbnN0X3JldmVyc2VfaXRlcmF0b3IgcmJlZ2luKCkgY29uc3QgeworICAgIHJldHVybiBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yOjpnZXRBdEJ1bmRsZUJlZ2luKGluc3RyX3JiZWdpbigpKTsKKyAgfQorICByZXZlcnNlX2l0ZXJhdG9yIHJlbmQoKSB7IHJldHVybiByZXZlcnNlX2l0ZXJhdG9yKGluc3RyX3JlbmQoKSk7IH0KKyAgY29uc3RfcmV2ZXJzZV9pdGVyYXRvciByZW5kKCkgY29uc3QgeworICAgIHJldHVybiBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yKGluc3RyX3JlbmQoKSk7CisgIH0KKworICAvLy8gU3VwcG9ydCBmb3IgTWFjaGluZUluc3RyOjpnZXROZXh0Tm9kZSgpLgorICBzdGF0aWMgSW5zdHJ1Y3Rpb25zIE1hY2hpbmVCYXNpY0Jsb2NrOjoqZ2V0U3VibGlzdEFjY2VzcyhNYWNoaW5lSW5zdHIgKikgeworICAgIHJldHVybiAmTWFjaGluZUJhc2ljQmxvY2s6Okluc3RzOworICB9CisKKyAgaW5saW5lIGl0ZXJhdG9yX3JhbmdlPGl0ZXJhdG9yPiB0ZXJtaW5hdG9ycygpIHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZShnZXRGaXJzdFRlcm1pbmF0b3IoKSwgZW5kKCkpOworICB9CisgIGlubGluZSBpdGVyYXRvcl9yYW5nZTxjb25zdF9pdGVyYXRvcj4gdGVybWluYXRvcnMoKSBjb25zdCB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2UoZ2V0Rmlyc3RUZXJtaW5hdG9yKCksIGVuZCgpKTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIGEgcmFuZ2UgdGhhdCBpdGVyYXRlcyBvdmVyIHRoZSBwaGlzIGluIHRoZSBiYXNpYyBibG9jay4KKyAgaW5saW5lIGl0ZXJhdG9yX3JhbmdlPGl0ZXJhdG9yPiBwaGlzKCkgeworICAgIHJldHVybiBtYWtlX3JhbmdlKGJlZ2luKCksIGdldEZpcnN0Tm9uUEhJKCkpOworICB9CisgIGlubGluZSBpdGVyYXRvcl9yYW5nZTxjb25zdF9pdGVyYXRvcj4gcGhpcygpIGNvbnN0IHsKKyAgICByZXR1cm4gY29uc3RfY2FzdDxNYWNoaW5lQmFzaWNCbG9jayAqPih0aGlzKS0+cGhpcygpOworICB9CisKKyAgLy8gTWFjaGluZS1DRkcgaXRlcmF0b3JzCisgIHVzaW5nIHByZWRfaXRlcmF0b3IgPSBzdGQ6OnZlY3RvcjxNYWNoaW5lQmFzaWNCbG9jayAqPjo6aXRlcmF0b3I7CisgIHVzaW5nIGNvbnN0X3ByZWRfaXRlcmF0b3IgPSBzdGQ6OnZlY3RvcjxNYWNoaW5lQmFzaWNCbG9jayAqPjo6Y29uc3RfaXRlcmF0b3I7CisgIHVzaW5nIHN1Y2NfaXRlcmF0b3IgPSBzdGQ6OnZlY3RvcjxNYWNoaW5lQmFzaWNCbG9jayAqPjo6aXRlcmF0b3I7CisgIHVzaW5nIGNvbnN0X3N1Y2NfaXRlcmF0b3IgPSBzdGQ6OnZlY3RvcjxNYWNoaW5lQmFzaWNCbG9jayAqPjo6Y29uc3RfaXRlcmF0b3I7CisgIHVzaW5nIHByZWRfcmV2ZXJzZV9pdGVyYXRvciA9CisgICAgICBzdGQ6OnZlY3RvcjxNYWNoaW5lQmFzaWNCbG9jayAqPjo6cmV2ZXJzZV9pdGVyYXRvcjsKKyAgdXNpbmcgY29uc3RfcHJlZF9yZXZlcnNlX2l0ZXJhdG9yID0KKyAgICAgIHN0ZDo6dmVjdG9yPE1hY2hpbmVCYXNpY0Jsb2NrICo+Ojpjb25zdF9yZXZlcnNlX2l0ZXJhdG9yOworICB1c2luZyBzdWNjX3JldmVyc2VfaXRlcmF0b3IgPQorICAgICAgc3RkOjp2ZWN0b3I8TWFjaGluZUJhc2ljQmxvY2sgKj46OnJldmVyc2VfaXRlcmF0b3I7CisgIHVzaW5nIGNvbnN0X3N1Y2NfcmV2ZXJzZV9pdGVyYXRvciA9CisgICAgICBzdGQ6OnZlY3RvcjxNYWNoaW5lQmFzaWNCbG9jayAqPjo6Y29uc3RfcmV2ZXJzZV9pdGVyYXRvcjsKKyAgcHJlZF9pdGVyYXRvciAgICAgICAgcHJlZF9iZWdpbigpICAgICAgIHsgcmV0dXJuIFByZWRlY2Vzc29ycy5iZWdpbigpOyB9CisgIGNvbnN0X3ByZWRfaXRlcmF0b3IgIHByZWRfYmVnaW4oKSBjb25zdCB7IHJldHVybiBQcmVkZWNlc3NvcnMuYmVnaW4oKTsgfQorICBwcmVkX2l0ZXJhdG9yICAgICAgICBwcmVkX2VuZCgpICAgICAgICAgeyByZXR1cm4gUHJlZGVjZXNzb3JzLmVuZCgpOyAgIH0KKyAgY29uc3RfcHJlZF9pdGVyYXRvciAgcHJlZF9lbmQoKSAgIGNvbnN0IHsgcmV0dXJuIFByZWRlY2Vzc29ycy5lbmQoKTsgICB9CisgIHByZWRfcmV2ZXJzZV9pdGVyYXRvciAgICAgICAgcHJlZF9yYmVnaW4oKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gUHJlZGVjZXNzb3JzLnJiZWdpbigpO30KKyAgY29uc3RfcHJlZF9yZXZlcnNlX2l0ZXJhdG9yICBwcmVkX3JiZWdpbigpIGNvbnN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBQcmVkZWNlc3NvcnMucmJlZ2luKCk7fQorICBwcmVkX3JldmVyc2VfaXRlcmF0b3IgICAgICAgIHByZWRfcmVuZCgpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBQcmVkZWNlc3NvcnMucmVuZCgpOyAgfQorICBjb25zdF9wcmVkX3JldmVyc2VfaXRlcmF0b3IgIHByZWRfcmVuZCgpICAgY29uc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIFByZWRlY2Vzc29ycy5yZW5kKCk7ICB9CisgIHVuc2lnbmVkICAgICAgICAgICAgIHByZWRfc2l6ZSgpICBjb25zdCB7CisgICAgcmV0dXJuICh1bnNpZ25lZClQcmVkZWNlc3NvcnMuc2l6ZSgpOworICB9CisgIGJvb2wgICAgICAgICAgICAgICAgIHByZWRfZW1wdHkoKSBjb25zdCB7IHJldHVybiBQcmVkZWNlc3NvcnMuZW1wdHkoKTsgfQorICBzdWNjX2l0ZXJhdG9yICAgICAgICBzdWNjX2JlZ2luKCkgICAgICAgeyByZXR1cm4gU3VjY2Vzc29ycy5iZWdpbigpOyAgIH0KKyAgY29uc3Rfc3VjY19pdGVyYXRvciAgc3VjY19iZWdpbigpIGNvbnN0IHsgcmV0dXJuIFN1Y2Nlc3NvcnMuYmVnaW4oKTsgICB9CisgIHN1Y2NfaXRlcmF0b3IgICAgICAgIHN1Y2NfZW5kKCkgICAgICAgICB7IHJldHVybiBTdWNjZXNzb3JzLmVuZCgpOyAgICAgfQorICBjb25zdF9zdWNjX2l0ZXJhdG9yICBzdWNjX2VuZCgpICAgY29uc3QgeyByZXR1cm4gU3VjY2Vzc29ycy5lbmQoKTsgICAgIH0KKyAgc3VjY19yZXZlcnNlX2l0ZXJhdG9yICAgICAgICBzdWNjX3JiZWdpbigpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IHJldHVybiBTdWNjZXNzb3JzLnJiZWdpbigpOyAgfQorICBjb25zdF9zdWNjX3JldmVyc2VfaXRlcmF0b3IgIHN1Y2NfcmJlZ2luKCkgY29uc3QKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIFN1Y2Nlc3NvcnMucmJlZ2luKCk7ICB9CisgIHN1Y2NfcmV2ZXJzZV9pdGVyYXRvciAgICAgICAgc3VjY19yZW5kKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIFN1Y2Nlc3NvcnMucmVuZCgpOyAgICB9CisgIGNvbnN0X3N1Y2NfcmV2ZXJzZV9pdGVyYXRvciAgc3VjY19yZW5kKCkgICBjb25zdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gU3VjY2Vzc29ycy5yZW5kKCk7ICAgIH0KKyAgdW5zaWduZWQgICAgICAgICAgICAgc3VjY19zaXplKCkgIGNvbnN0IHsKKyAgICByZXR1cm4gKHVuc2lnbmVkKVN1Y2Nlc3NvcnMuc2l6ZSgpOworICB9CisgIGJvb2wgICAgICAgICAgICAgICAgIHN1Y2NfZW1wdHkoKSBjb25zdCB7IHJldHVybiBTdWNjZXNzb3JzLmVtcHR5KCk7ICAgfQorCisgIGlubGluZSBpdGVyYXRvcl9yYW5nZTxwcmVkX2l0ZXJhdG9yPiBwcmVkZWNlc3NvcnMoKSB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2UocHJlZF9iZWdpbigpLCBwcmVkX2VuZCgpKTsKKyAgfQorICBpbmxpbmUgaXRlcmF0b3JfcmFuZ2U8Y29uc3RfcHJlZF9pdGVyYXRvcj4gcHJlZGVjZXNzb3JzKCkgY29uc3QgeworICAgIHJldHVybiBtYWtlX3JhbmdlKHByZWRfYmVnaW4oKSwgcHJlZF9lbmQoKSk7CisgIH0KKyAgaW5saW5lIGl0ZXJhdG9yX3JhbmdlPHN1Y2NfaXRlcmF0b3I+IHN1Y2Nlc3NvcnMoKSB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2Uoc3VjY19iZWdpbigpLCBzdWNjX2VuZCgpKTsKKyAgfQorICBpbmxpbmUgaXRlcmF0b3JfcmFuZ2U8Y29uc3Rfc3VjY19pdGVyYXRvcj4gc3VjY2Vzc29ycygpIGNvbnN0IHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZShzdWNjX2JlZ2luKCksIHN1Y2NfZW5kKCkpOworICB9CisKKyAgLy8gTGl2ZUluIG1hbmFnZW1lbnQgbWV0aG9kcy4KKworICAvLy8gQWRkcyB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyIGFzIGEgbGl2ZSBpbi4gTm90ZSB0aGF0IGl0IGlzIGFuIGVycm9yIHRvIGFkZAorICAvLy8gdGhlIHNhbWUgcmVnaXN0ZXIgdG8gdGhlIHNhbWUgc2V0IG1vcmUgdGhhbiBvbmNlIHVubGVzcyB0aGUgaW50ZW50aW9uIGlzCisgIC8vLyB0byBjYWxsIHNvcnRVbmlxdWVMaXZlSW5zIGFmdGVyIGFsbCByZWdpc3RlcnMgYXJlIGFkZGVkLgorICB2b2lkIGFkZExpdmVJbihNQ1BoeXNSZWcgUGh5c1JlZywKKyAgICAgICAgICAgICAgICAgTGFuZUJpdG1hc2sgTGFuZU1hc2sgPSBMYW5lQml0bWFzazo6Z2V0QWxsKCkpIHsKKyAgICBMaXZlSW5zLnB1c2hfYmFjayhSZWdpc3Rlck1hc2tQYWlyKFBoeXNSZWcsIExhbmVNYXNrKSk7CisgIH0KKyAgdm9pZCBhZGRMaXZlSW4oY29uc3QgUmVnaXN0ZXJNYXNrUGFpciAmUmVnTWFza1BhaXIpIHsKKyAgICBMaXZlSW5zLnB1c2hfYmFjayhSZWdNYXNrUGFpcik7CisgIH0KKworICAvLy8gU29ydHMgYW5kIHVuaXF1ZXMgdGhlIExpdmVJbnMgdmVjdG9yLiBJdCBjYW4gYmUgc2lnbmlmaWNhbnRseSBmYXN0ZXIgdG8gZG8KKyAgLy8vIHRoaXMgdGhhbiByZXBlYXRlZGx5IGNhbGxpbmcgaXNMaXZlSW4gYmVmb3JlIGNhbGxpbmcgYWRkTGl2ZUluIGZvciBldmVyeQorICAvLy8gTGl2ZUluIGluc2VydGlvbi4KKyAgdm9pZCBzb3J0VW5pcXVlTGl2ZUlucygpOworCisgIC8vLyBDbGVhciBsaXZlIGluIGxpc3QuCisgIHZvaWQgY2xlYXJMaXZlSW5zKCk7CisKKyAgLy8vIEFkZCBQaHlzUmVnIGFzIGxpdmUgaW4gdG8gdGhpcyBibG9jaywgYW5kIGVuc3VyZSB0aGF0IHRoZXJlIGlzIGEgY29weSBvZgorICAvLy8gUGh5c1JlZyB0byBhIHZpcnR1YWwgcmVnaXN0ZXIgb2YgY2xhc3MgUkMuIFJldHVybiB0aGUgdmlydHVhbCByZWdpc3RlcgorICAvLy8gdGhhdCBpcyBhIGNvcHkgb2YgdGhlIGxpdmUgaW4gUGh5c1JlZy4KKyAgdW5zaWduZWQgYWRkTGl2ZUluKE1DUGh5c1JlZyBQaHlzUmVnLCBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQyk7CisKKyAgLy8vIFJlbW92ZSB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyIGZyb20gdGhlIGxpdmUgaW4gc2V0LgorICB2b2lkIHJlbW92ZUxpdmVJbihNQ1BoeXNSZWcgUmVnLAorICAgICAgICAgICAgICAgICAgICBMYW5lQml0bWFzayBMYW5lTWFzayA9IExhbmVCaXRtYXNrOjpnZXRBbGwoKSk7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIgaXMgaW4gdGhlIGxpdmUgaW4gc2V0LgorICBib29sIGlzTGl2ZUluKE1DUGh5c1JlZyBSZWcsCisgICAgICAgICAgICAgICAgTGFuZUJpdG1hc2sgTGFuZU1hc2sgPSBMYW5lQml0bWFzazo6Z2V0QWxsKCkpIGNvbnN0OworCisgIC8vIEl0ZXJhdGlvbiBzdXBwb3J0IGZvciBsaXZlIGluIHNldHMuICBUaGVzZSBzZXRzIGFyZSBrZXB0IGluIHNvcnRlZAorICAvLyBvcmRlciBieSB0aGVpciByZWdpc3RlciBudW1iZXIuCisgIHVzaW5nIGxpdmVpbl9pdGVyYXRvciA9IExpdmVJblZlY3Rvcjo6Y29uc3RfaXRlcmF0b3I7CisjaWZuZGVmIE5ERUJVRworICAvLy8gVW5saWtlIGxpdmVpbl9iZWdpbiwgdGhpcyBtZXRob2QgZG9lcyBub3QgY2hlY2sgdGhhdCB0aGUgbGl2ZW5lc3MKKyAgLy8vIGluZm9ybWF0aW9uIGlzIGFjY3VyYXRlLiBTdGlsbCBmb3IgZGVidWcgcHVycG9zZXMgaXQgbWF5IGJlIHVzZWZ1bAorICAvLy8gdG8gaGF2ZSBpdGVyYXRvcnMgdGhhdCB3b24ndCBhc3NlcnQgaWYgdGhlIGxpdmVuZXNzIGluZm9ybWF0aW9uCisgIC8vLyBpcyBub3QgY3VycmVudC4KKyAgbGl2ZWluX2l0ZXJhdG9yIGxpdmVpbl9iZWdpbl9kYmcoKSBjb25zdCB7IHJldHVybiBMaXZlSW5zLmJlZ2luKCk7IH0KKyAgaXRlcmF0b3JfcmFuZ2U8bGl2ZWluX2l0ZXJhdG9yPiBsaXZlaW5zX2RiZygpIGNvbnN0IHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZShsaXZlaW5fYmVnaW5fZGJnKCksIGxpdmVpbl9lbmQoKSk7CisgIH0KKyNlbmRpZgorICBsaXZlaW5faXRlcmF0b3IgbGl2ZWluX2JlZ2luKCkgY29uc3Q7CisgIGxpdmVpbl9pdGVyYXRvciBsaXZlaW5fZW5kKCkgICBjb25zdCB7IHJldHVybiBMaXZlSW5zLmVuZCgpOyB9CisgIGJvb2wgICAgICAgICAgICBsaXZlaW5fZW1wdHkoKSBjb25zdCB7IHJldHVybiBMaXZlSW5zLmVtcHR5KCk7IH0KKyAgaXRlcmF0b3JfcmFuZ2U8bGl2ZWluX2l0ZXJhdG9yPiBsaXZlaW5zKCkgY29uc3QgeworICAgIHJldHVybiBtYWtlX3JhbmdlKGxpdmVpbl9iZWdpbigpLCBsaXZlaW5fZW5kKCkpOworICB9CisKKyAgLy8vIFJlbW92ZSBlbnRyeSBmcm9tIHRoZSBsaXZlaW4gc2V0IGFuZCByZXR1cm4gaXRlcmF0b3IgdG8gdGhlIG5leHQuCisgIGxpdmVpbl9pdGVyYXRvciByZW1vdmVMaXZlSW4obGl2ZWluX2l0ZXJhdG9yIEkpOworCisgIC8vLyBHZXQgdGhlIGNsb2JiZXIgbWFzayBmb3IgdGhlIHN0YXJ0IG9mIHRoaXMgYmFzaWMgYmxvY2suIEZ1bmNsZXRzIHVzZSB0aGlzCisgIC8vLyB0byBwcmV2ZW50IHJlZ2lzdGVyIGFsbG9jYXRpb24gYWNyb3NzIGZ1bmNsZXQgdHJhbnNpdGlvbnMuCisgIGNvbnN0IHVpbnQzMl90ICpnZXRCZWdpbkNsb2JiZXJNYXNrKGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJKSBjb25zdDsKKworICAvLy8gR2V0IHRoZSBjbG9iYmVyIG1hc2sgZm9yIHRoZSBlbmQgb2YgdGhlIGJhc2ljIGJsb2NrLgorICAvLy8gXHNlZSBnZXRCZWdpbkNsb2JiZXJNYXNrKCkKKyAgY29uc3QgdWludDMyX3QgKmdldEVuZENsb2JiZXJNYXNrKGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJKSBjb25zdDsKKworICAvLy8gUmV0dXJuIGFsaWdubWVudCBvZiB0aGUgYmFzaWMgYmxvY2suIFRoZSBhbGlnbm1lbnQgaXMgc3BlY2lmaWVkIGFzCisgIC8vLyBsb2cyKGJ5dGVzKS4KKyAgdW5zaWduZWQgZ2V0QWxpZ25tZW50KCkgY29uc3QgeyByZXR1cm4gQWxpZ25tZW50OyB9CisKKyAgLy8vIFNldCBhbGlnbm1lbnQgb2YgdGhlIGJhc2ljIGJsb2NrLiBUaGUgYWxpZ25tZW50IGlzIHNwZWNpZmllZCBhcworICAvLy8gbG9nMihieXRlcykuCisgIHZvaWQgc2V0QWxpZ25tZW50KHVuc2lnbmVkIEFsaWduKSB7IEFsaWdubWVudCA9IEFsaWduOyB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgYmxvY2sgaXMgYSBsYW5kaW5nIHBhZC4gVGhhdCBpcyB0aGlzIGJhc2ljIGJsb2NrIGlzCisgIC8vLyBlbnRlcmVkIHZpYSBhbiBleGNlcHRpb24gaGFuZGxlci4KKyAgYm9vbCBpc0VIUGFkKCkgY29uc3QgeyByZXR1cm4gSXNFSFBhZDsgfQorCisgIC8vLyBJbmRpY2F0ZXMgdGhlIGJsb2NrIGlzIGEgbGFuZGluZyBwYWQuICBUaGF0IGlzIHRoaXMgYmFzaWMgYmxvY2sgaXMgZW50ZXJlZAorICAvLy8gdmlhIGFuIGV4Y2VwdGlvbiBoYW5kbGVyLgorICB2b2lkIHNldElzRUhQYWQoYm9vbCBWID0gdHJ1ZSkgeyBJc0VIUGFkID0gVjsgfQorCisgIGJvb2wgaGFzRUhQYWRTdWNjZXNzb3IoKSBjb25zdDsKKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgdGhlIGVudHJ5IGJsb2NrIG9mIGFuIEVIIGZ1bmNsZXQuCisgIGJvb2wgaXNFSEZ1bmNsZXRFbnRyeSgpIGNvbnN0IHsgcmV0dXJuIElzRUhGdW5jbGV0RW50cnk7IH0KKworICAvLy8gSW5kaWNhdGVzIGlmIHRoaXMgaXMgdGhlIGVudHJ5IGJsb2NrIG9mIGFuIEVIIGZ1bmNsZXQuCisgIHZvaWQgc2V0SXNFSEZ1bmNsZXRFbnRyeShib29sIFYgPSB0cnVlKSB7IElzRUhGdW5jbGV0RW50cnkgPSBWOyB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGlzIHRoZSBlbnRyeSBibG9jayBvZiBhIGNsZWFudXAgZnVuY2xldC4KKyAgYm9vbCBpc0NsZWFudXBGdW5jbGV0RW50cnkoKSBjb25zdCB7IHJldHVybiBJc0NsZWFudXBGdW5jbGV0RW50cnk7IH0KKworICAvLy8gSW5kaWNhdGVzIGlmIHRoaXMgaXMgdGhlIGVudHJ5IGJsb2NrIG9mIGEgY2xlYW51cCBmdW5jbGV0LgorICB2b2lkIHNldElzQ2xlYW51cEZ1bmNsZXRFbnRyeShib29sIFYgPSB0cnVlKSB7IElzQ2xlYW51cEZ1bmNsZXRFbnRyeSA9IFY7IH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIGl0IGlzIGxlZ2FsIHRvIGhvaXN0IGluc3RydWN0aW9ucyBpbnRvIHRoaXMgYmxvY2suCisgIGJvb2wgaXNMZWdhbFRvSG9pc3RJbnRvKCkgY29uc3Q7CisKKyAgLy8gQ29kZSBMYXlvdXQgbWV0aG9kcy4KKworICAvLy8gTW92ZSAndGhpcycgYmxvY2sgYmVmb3JlIG9yIGFmdGVyIHRoZSBzcGVjaWZpZWQgYmxvY2suICBUaGlzIG9ubHkgbW92ZXMKKyAgLy8vIHRoZSBibG9jaywgaXQgZG9lcyBub3QgbW9kaWZ5IHRoZSBDRkcgb3IgYWRqdXN0IHBvdGVudGlhbCBmYWxsLXRocm91Z2hzIGF0CisgIC8vLyB0aGUgZW5kIG9mIHRoZSBibG9jay4KKyAgdm9pZCBtb3ZlQmVmb3JlKE1hY2hpbmVCYXNpY0Jsb2NrICpOZXdBZnRlcik7CisgIHZvaWQgbW92ZUFmdGVyKE1hY2hpbmVCYXNpY0Jsb2NrICpOZXdCZWZvcmUpOworCisgIC8vLyBVcGRhdGUgdGhlIHRlcm1pbmF0b3IgaW5zdHJ1Y3Rpb25zIGluIGJsb2NrIHRvIGFjY291bnQgZm9yIGNoYW5nZXMgdG8gdGhlCisgIC8vLyBsYXlvdXQuIElmIHRoZSBibG9jayBwcmV2aW91c2x5IHVzZWQgYSBmYWxsdGhyb3VnaCwgaXQgbWF5IG5vdyBuZWVkIGEKKyAgLy8vIGJyYW5jaCwgYW5kIGlmIGl0IHByZXZpb3VzbHkgdXNlZCBicmFuY2hpbmcgaXQgbWF5IG5vdyBiZSBhYmxlIHRvIHVzZSBhCisgIC8vLyBmYWxsdGhyb3VnaC4KKyAgdm9pZCB1cGRhdGVUZXJtaW5hdG9yKCk7CisKKyAgLy8gTWFjaGluZS1DRkcgbXV0YXRvcnMKKworICAvLy8gQWRkIFN1Y2MgYXMgYSBzdWNjZXNzb3Igb2YgdGhpcyBNYWNoaW5lQmFzaWNCbG9jay4gIFRoZSBQcmVkZWNlc3NvcnMgbGlzdAorICAvLy8gb2YgU3VjYyBpcyBhdXRvbWF0aWNhbGx5IHVwZGF0ZWQuIFBST0IgcGFyYW1ldGVyIGlzIHN0b3JlZCBpbgorICAvLy8gUHJvYmFiaWxpdGllcyBsaXN0LiBUaGUgZGVmYXVsdCBwcm9iYWJpbGl0eSBpcyBzZXQgYXMgdW5rbm93bi4gTWl4aW5nCisgIC8vLyBrbm93biBhbmQgdW5rbm93biBwcm9iYWJpbGl0aWVzIGluIHN1Y2Nlc3NvciBsaXN0IGlzIG5vdCBhbGxvd2VkLiBXaGVuIGFsbAorICAvLy8gc3VjY2Vzc29ycyBoYXZlIHVua25vd24gcHJvYmFiaWxpdGllcywgMSAvIE4gaXMgcmV0dXJuZWQgYXMgdGhlCisgIC8vLyBwcm9iYWJpbGl0eSBmb3IgZWFjaCBzdWNjZXNzb3IsIHdoZXJlIE4gaXMgdGhlIG51bWJlciBvZiBzdWNjZXNzb3JzLgorICAvLy8KKyAgLy8vIE5vdGUgdGhhdCBkdXBsaWNhdGUgTWFjaGluZSBDRkcgZWRnZXMgYXJlIG5vdCBhbGxvd2VkLgorICB2b2lkIGFkZFN1Y2Nlc3NvcihNYWNoaW5lQmFzaWNCbG9jayAqU3VjYywKKyAgICAgICAgICAgICAgICAgICAgQnJhbmNoUHJvYmFiaWxpdHkgUHJvYiA9IEJyYW5jaFByb2JhYmlsaXR5OjpnZXRVbmtub3duKCkpOworCisgIC8vLyBBZGQgU3VjYyBhcyBhIHN1Y2Nlc3NvciBvZiB0aGlzIE1hY2hpbmVCYXNpY0Jsb2NrLiAgVGhlIFByZWRlY2Vzc29ycyBsaXN0CisgIC8vLyBvZiBTdWNjIGlzIGF1dG9tYXRpY2FsbHkgdXBkYXRlZC4gVGhlIHByb2JhYmlsaXR5IGlzIG5vdCBwcm92aWRlZCBiZWNhdXNlCisgIC8vLyBCUEkgaXMgbm90IGF2YWlsYWJsZSAoZS5nLiAtTzAgaXMgdXNlZCksIGluIHdoaWNoIGNhc2UgZWRnZSBwcm9iYWJpbGl0aWVzCisgIC8vLyB3b24ndCBiZSB1c2VkLiBVc2luZyB0aGlzIGludGVyZmFjZSBjYW4gc2F2ZSBzb21lIHNwYWNlLgorICB2b2lkIGFkZFN1Y2Nlc3NvcldpdGhvdXRQcm9iKE1hY2hpbmVCYXNpY0Jsb2NrICpTdWNjKTsKKworICAvLy8gU2V0IHN1Y2Nlc3NvciBwcm9iYWJpbGl0eSBvZiBhIGdpdmVuIGl0ZXJhdG9yLgorICB2b2lkIHNldFN1Y2NQcm9iYWJpbGl0eShzdWNjX2l0ZXJhdG9yIEksIEJyYW5jaFByb2JhYmlsaXR5IFByb2IpOworCisgIC8vLyBOb3JtYWxpemUgcHJvYmFiaWxpdGllcyBvZiBhbGwgc3VjY2Vzc29ycyBzbyB0aGF0IHRoZSBzdW0gb2YgdGhlbSBiZWNvbWVzCisgIC8vLyBvbmUuIFRoaXMgaXMgdXN1YWxseSBkb25lIHdoZW4gdGhlIGN1cnJlbnQgdXBkYXRlIG9uIHRoaXMgTUJCIGlzIGRvbmUsIGFuZAorICAvLy8gdGhlIHN1bSBvZiBpdHMgc3VjY2Vzc29ycycgcHJvYmFiaWxpdGllcyBpcyBub3QgZ3VhcmFudGVlZCB0byBiZSBvbmUuIFRoZQorICAvLy8gdXNlciBpcyByZXNwb25zaWJsZSBmb3IgdGhlIGNvcnJlY3QgdXNlIG9mIHRoaXMgZnVuY3Rpb24uCisgIC8vLyBNQkI6OnJlbW92ZVN1Y2Nlc3NvcigpIGhhcyBhbiBvcHRpb24gdG8gZG8gdGhpcyBhdXRvbWF0aWNhbGx5LgorICB2b2lkIG5vcm1hbGl6ZVN1Y2NQcm9icygpIHsKKyAgICBCcmFuY2hQcm9iYWJpbGl0eTo6bm9ybWFsaXplUHJvYmFiaWxpdGllcyhQcm9icy5iZWdpbigpLCBQcm9icy5lbmQoKSk7CisgIH0KKworICAvLy8gVmFsaWRhdGUgc3VjY2Vzc29ycycgcHJvYmFiaWxpdGllcyBhbmQgY2hlY2sgaWYgdGhlIHN1bSBvZiB0aGVtIGlzCisgIC8vLyBhcHByb3hpbWF0ZSBvbmUuIFRoaXMgb25seSB3b3JrcyBpbiBERUJVRyBtb2RlLgorICB2b2lkIHZhbGlkYXRlU3VjY1Byb2JzKCkgY29uc3Q7CisKKyAgLy8vIFJlbW92ZSBzdWNjZXNzb3IgZnJvbSB0aGUgc3VjY2Vzc29ycyBsaXN0IG9mIHRoaXMgTWFjaGluZUJhc2ljQmxvY2suIFRoZQorICAvLy8gUHJlZGVjZXNzb3JzIGxpc3Qgb2YgU3VjYyBpcyBhdXRvbWF0aWNhbGx5IHVwZGF0ZWQuCisgIC8vLyBJZiBOb3JtYWxpemVTdWNjUHJvYnMgaXMgdHJ1ZSwgdGhlbiBub3JtYWxpemUgc3VjY2Vzc29ycycgcHJvYmFiaWxpdGllcworICAvLy8gYWZ0ZXIgdGhlIHN1Y2Nlc3NvciBpcyByZW1vdmVkLgorICB2b2lkIHJlbW92ZVN1Y2Nlc3NvcihNYWNoaW5lQmFzaWNCbG9jayAqU3VjYywKKyAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBOb3JtYWxpemVTdWNjUHJvYnMgPSBmYWxzZSk7CisKKyAgLy8vIFJlbW92ZSBzcGVjaWZpZWQgc3VjY2Vzc29yIGZyb20gdGhlIHN1Y2Nlc3NvcnMgbGlzdCBvZiB0aGlzCisgIC8vLyBNYWNoaW5lQmFzaWNCbG9jay4gVGhlIFByZWRlY2Vzc29ycyBsaXN0IG9mIFN1Y2MgaXMgYXV0b21hdGljYWxseSB1cGRhdGVkLgorICAvLy8gSWYgTm9ybWFsaXplU3VjY1Byb2JzIGlzIHRydWUsIHRoZW4gbm9ybWFsaXplIHN1Y2Nlc3NvcnMnIHByb2JhYmlsaXRpZXMKKyAgLy8vIGFmdGVyIHRoZSBzdWNjZXNzb3IgaXMgcmVtb3ZlZC4KKyAgLy8vIFJldHVybiB0aGUgaXRlcmF0b3IgdG8gdGhlIGVsZW1lbnQgYWZ0ZXIgdGhlIG9uZSByZW1vdmVkLgorICBzdWNjX2l0ZXJhdG9yIHJlbW92ZVN1Y2Nlc3NvcihzdWNjX2l0ZXJhdG9yIEksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgTm9ybWFsaXplU3VjY1Byb2JzID0gZmFsc2UpOworCisgIC8vLyBSZXBsYWNlIHN1Y2Nlc3NvciBPTEQgd2l0aCBORVcgYW5kIHVwZGF0ZSBwcm9iYWJpbGl0eSBpbmZvLgorICB2b2lkIHJlcGxhY2VTdWNjZXNzb3IoTWFjaGluZUJhc2ljQmxvY2sgKk9sZCwgTWFjaGluZUJhc2ljQmxvY2sgKk5ldyk7CisKKyAgLy8vIENvcHkgYSBzdWNjZXNzb3IgKGFuZCBhbnkgcHJvYmFiaWxpdHkgaW5mbykgZnJvbSBvcmlnaW5hbCBibG9jayB0byB0aGlzCisgIC8vLyBibG9jaydzLiBVc2VzIGFuIGl0ZXJhdG9yIGludG8gdGhlIG9yaWdpbmFsIGJsb2NrcyBzdWNjZXNzb3JzLgorICAvLy8KKyAgLy8vIFRoaXMgaXMgdXNlZnVsIHdoZW4gZG9pbmcgYSBwYXJ0aWFsIGNsb25lIG9mIHN1Y2Nlc3NvcnMuIEFmdGVyd2FyZCwgdGhlCisgIC8vLyBwcm9iYWJpbGl0aWVzIG1heSBuZWVkIHRvIGJlIG5vcm1hbGl6ZWQuCisgIHZvaWQgY29weVN1Y2Nlc3NvcihNYWNoaW5lQmFzaWNCbG9jayAqT3JpZywgc3VjY19pdGVyYXRvciBJKTsKKworICAvLy8gVHJhbnNmZXJzIGFsbCB0aGUgc3VjY2Vzc29ycyBmcm9tIE1CQiB0byB0aGlzIG1hY2hpbmUgYmFzaWMgYmxvY2sgKGkuZS4sCisgIC8vLyBjb3BpZXMgYWxsIHRoZSBzdWNjZXNzb3JzIEZyb21NQkIgYW5kIHJlbW92ZSBhbGwgdGhlIHN1Y2Nlc3NvcnMgZnJvbQorICAvLy8gRnJvbU1CQikuCisgIHZvaWQgdHJhbnNmZXJTdWNjZXNzb3JzKE1hY2hpbmVCYXNpY0Jsb2NrICpGcm9tTUJCKTsKKworICAvLy8gVHJhbnNmZXJzIGFsbCB0aGUgc3VjY2Vzc29ycywgYXMgaW4gdHJhbnNmZXJTdWNjZXNzb3JzLCBhbmQgdXBkYXRlIFBISQorICAvLy8gb3BlcmFuZHMgaW4gdGhlIHN1Y2Nlc3NvciBibG9ja3Mgd2hpY2ggcmVmZXIgdG8gRnJvbU1CQiB0byByZWZlciB0byB0aGlzLgorICB2b2lkIHRyYW5zZmVyU3VjY2Vzc29yc0FuZFVwZGF0ZVBISXMoTWFjaGluZUJhc2ljQmxvY2sgKkZyb21NQkIpOworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBhbnkgb2YgdGhlIHN1Y2Nlc3NvcnMgaGF2ZSBwcm9iYWJpbGl0aWVzIGF0dGFjaGVkIHRvIHRoZW0uCisgIGJvb2wgaGFzU3VjY2Vzc29yUHJvYmFiaWxpdGllcygpIGNvbnN0IHsgcmV0dXJuICFQcm9icy5lbXB0eSgpOyB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgTUJCIGlzIGEgcHJlZGVjZXNzb3Igb2YgdGhpcyBibG9jay4KKyAgYm9vbCBpc1ByZWRlY2Vzc29yKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIE1CQiBpcyBhIHN1Y2Nlc3NvciBvZiB0aGlzIGJsb2NrLgorICBib29sIGlzU3VjY2Vzc29yKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIE1CQiB3aWxsIGJlIGVtaXR0ZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhpcworICAvLy8gYmxvY2ssIHN1Y2ggdGhhdCBpZiB0aGlzIGJsb2NrIGV4aXRzIGJ5IGZhbGxpbmcgdGhyb3VnaCwgY29udHJvbCB3aWxsCisgIC8vLyB0cmFuc2ZlciB0byB0aGUgc3BlY2lmaWVkIE1CQi4gTm90ZSB0aGF0IE1CQiBuZWVkIG5vdCBiZSBhIHN1Y2Nlc3NvciBhdAorICAvLy8gYWxsLCBmb3IgZXhhbXBsZSBpZiB0aGlzIGJsb2NrIGVuZHMgd2l0aCBhbiB1bmNvbmRpdGlvbmFsIGJyYW5jaCB0byBzb21lCisgIC8vLyBvdGhlciBibG9jay4KKyAgYm9vbCBpc0xheW91dFN1Y2Nlc3Nvcihjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqTUJCKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRoZSBmYWxsdGhyb3VnaCBibG9jayBpZiB0aGUgYmxvY2sgY2FuIGltcGxpY2l0bHkKKyAgLy8vIHRyYW5zZmVyIGNvbnRyb2wgdG8gdGhlIGJsb2NrIGFmdGVyIGl0IGJ5IGZhbGxpbmcgb2ZmIHRoZSBlbmQgb2YKKyAgLy8vIGl0LiAgVGhpcyBzaG91bGQgcmV0dXJuIG51bGwgaWYgaXQgY2FuIHJlYWNoIHRoZSBibG9jayBhZnRlcgorICAvLy8gaXQsIGJ1dCBpdCB1c2VzIGFuIGV4cGxpY2l0IGJyYW5jaCB0byBkbyBzbyAoZS5nLiwgYSB0YWJsZQorICAvLy8ganVtcCkuICBOb24tbnVsbCByZXR1cm4gIGlzIGEgY29uc2VydmF0aXZlIGFuc3dlci4KKyAgTWFjaGluZUJhc2ljQmxvY2sgKmdldEZhbGxUaHJvdWdoKCk7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBibG9jayBjYW4gaW1wbGljaXRseSB0cmFuc2ZlciBjb250cm9sIHRvIHRoZQorICAvLy8gYmxvY2sgYWZ0ZXIgaXQgYnkgZmFsbGluZyBvZmYgdGhlIGVuZCBvZiBpdC4gIFRoaXMgc2hvdWxkIHJldHVybgorICAvLy8gZmFsc2UgaWYgaXQgY2FuIHJlYWNoIHRoZSBibG9jayBhZnRlciBpdCwgYnV0IGl0IHVzZXMgYW4KKyAgLy8vIGV4cGxpY2l0IGJyYW5jaCB0byBkbyBzbyAoZS5nLiwgYSB0YWJsZSBqdW1wKS4gIFRydWUgaXMgYQorICAvLy8gY29uc2VydmF0aXZlIGFuc3dlci4KKyAgYm9vbCBjYW5GYWxsVGhyb3VnaCgpOworCisgIC8vLyBSZXR1cm5zIGEgcG9pbnRlciB0byB0aGUgZmlyc3QgaW5zdHJ1Y3Rpb24gaW4gdGhpcyBibG9jayB0aGF0IGlzIG5vdCBhCisgIC8vLyBQSElOb2RlIGluc3RydWN0aW9uLiBXaGVuIGFkZGluZyBpbnN0cnVjdGlvbnMgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUKKyAgLy8vIGJhc2ljIGJsb2NrLCB0aGV5IHNob3VsZCBiZSBhZGRlZCBiZWZvcmUgdGhlIHJldHVybmVkIHZhbHVlLCBub3QgYmVmb3JlCisgIC8vLyB0aGUgZmlyc3QgaW5zdHJ1Y3Rpb24sIHdoaWNoIG1pZ2h0IGJlIFBISS4KKyAgLy8vIFJldHVybnMgZW5kKCkgaXMgdGhlcmUncyBubyBub24tUEhJIGluc3RydWN0aW9uLgorICBpdGVyYXRvciBnZXRGaXJzdE5vblBISSgpOworCisgIC8vLyBSZXR1cm4gdGhlIGZpcnN0IGluc3RydWN0aW9uIGluIE1CQiBhZnRlciBJIHRoYXQgaXMgbm90IGEgUEhJIG9yIGEgbGFiZWwuCisgIC8vLyBUaGlzIGlzIHRoZSBjb3JyZWN0IHBvaW50IHRvIGluc2VydCBsb3dlcmVkIGNvcGllcyBhdCB0aGUgYmVnaW5uaW5nIG9mIGEKKyAgLy8vIGJhc2ljIGJsb2NrIHRoYXQgbXVzdCBiZSBiZWZvcmUgYW55IGRlYnVnZ2luZyBpbmZvcm1hdGlvbi4KKyAgaXRlcmF0b3IgU2tpcFBISXNBbmRMYWJlbHMoaXRlcmF0b3IgSSk7CisKKyAgLy8vIFJldHVybiB0aGUgZmlyc3QgaW5zdHJ1Y3Rpb24gaW4gTUJCIGFmdGVyIEkgdGhhdCBpcyBub3QgYSBQSEksIGxhYmVsIG9yCisgIC8vLyBkZWJ1Zy4gIFRoaXMgaXMgdGhlIGNvcnJlY3QgcG9pbnQgdG8gaW5zZXJ0IGNvcGllcyBhdCB0aGUgYmVnaW5uaW5nIG9mIGEKKyAgLy8vIGJhc2ljIGJsb2NrLgorICBpdGVyYXRvciBTa2lwUEhJc0xhYmVsc0FuZERlYnVnKGl0ZXJhdG9yIEkpOworCisgIC8vLyBSZXR1cm5zIGFuIGl0ZXJhdG9yIHRvIHRoZSBmaXJzdCB0ZXJtaW5hdG9yIGluc3RydWN0aW9uIG9mIHRoaXMgYmFzaWMKKyAgLy8vIGJsb2NrLiBJZiBhIHRlcm1pbmF0b3IgZG9lcyBub3QgZXhpc3QsIGl0IHJldHVybnMgZW5kKCkuCisgIGl0ZXJhdG9yIGdldEZpcnN0VGVybWluYXRvcigpOworICBjb25zdF9pdGVyYXRvciBnZXRGaXJzdFRlcm1pbmF0b3IoKSBjb25zdCB7CisgICAgcmV0dXJuIGNvbnN0X2Nhc3Q8TWFjaGluZUJhc2ljQmxvY2sgKj4odGhpcyktPmdldEZpcnN0VGVybWluYXRvcigpOworICB9CisKKyAgLy8vIFNhbWUgZ2V0Rmlyc3RUZXJtaW5hdG9yIGJ1dCBpdCBpZ25vcmVzIGJ1bmRsZXMgYW5kIHJldHVybiBhbgorICAvLy8gaW5zdHJfaXRlcmF0b3IgaW5zdGVhZC4KKyAgaW5zdHJfaXRlcmF0b3IgZ2V0Rmlyc3RJbnN0clRlcm1pbmF0b3IoKTsKKworICAvLy8gUmV0dXJucyBhbiBpdGVyYXRvciB0byB0aGUgZmlyc3Qgbm9uLWRlYnVnIGluc3RydWN0aW9uIGluIHRoZSBiYXNpYyBibG9jaywKKyAgLy8vIG9yIGVuZCgpLgorICBpdGVyYXRvciBnZXRGaXJzdE5vbkRlYnVnSW5zdHIoKTsKKyAgY29uc3RfaXRlcmF0b3IgZ2V0Rmlyc3ROb25EZWJ1Z0luc3RyKCkgY29uc3QgeworICAgIHJldHVybiBjb25zdF9jYXN0PE1hY2hpbmVCYXNpY0Jsb2NrICo+KHRoaXMpLT5nZXRGaXJzdE5vbkRlYnVnSW5zdHIoKTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIGFuIGl0ZXJhdG9yIHRvIHRoZSBsYXN0IG5vbi1kZWJ1ZyBpbnN0cnVjdGlvbiBpbiB0aGUgYmFzaWMgYmxvY2ssCisgIC8vLyBvciBlbmQoKS4KKyAgaXRlcmF0b3IgZ2V0TGFzdE5vbkRlYnVnSW5zdHIoKTsKKyAgY29uc3RfaXRlcmF0b3IgZ2V0TGFzdE5vbkRlYnVnSW5zdHIoKSBjb25zdCB7CisgICAgcmV0dXJuIGNvbnN0X2Nhc3Q8TWFjaGluZUJhc2ljQmxvY2sgKj4odGhpcyktPmdldExhc3ROb25EZWJ1Z0luc3RyKCk7CisgIH0KKworICAvLy8gQ29udmVuaWVuY2UgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRydWUgaWYgdGhlIGJsb2NrIGVuZHMgaW4gYSByZXR1cm4KKyAgLy8vIGluc3RydWN0aW9uLgorICBib29sIGlzUmV0dXJuQmxvY2soKSBjb25zdCB7CisgICAgcmV0dXJuICFlbXB0eSgpICYmIGJhY2soKS5pc1JldHVybigpOworICB9CisKKyAgLy8vIFNwbGl0IHRoZSBjcml0aWNhbCBlZGdlIGZyb20gdGhpcyBibG9jayB0byB0aGUgZ2l2ZW4gc3VjY2Vzc29yIGJsb2NrLCBhbmQKKyAgLy8vIHJldHVybiB0aGUgbmV3bHkgY3JlYXRlZCBibG9jaywgb3IgbnVsbCBpZiBzcGxpdHRpbmcgaXMgbm90IHBvc3NpYmxlLgorICAvLy8KKyAgLy8vIFRoaXMgZnVuY3Rpb24gdXBkYXRlcyBMaXZlVmFyaWFibGVzLCBNYWNoaW5lRG9taW5hdG9yVHJlZSwgYW5kCisgIC8vLyBNYWNoaW5lTG9vcEluZm8sIGFzIGFwcGxpY2FibGUuCisgIE1hY2hpbmVCYXNpY0Jsb2NrICpTcGxpdENyaXRpY2FsRWRnZShNYWNoaW5lQmFzaWNCbG9jayAqU3VjYywgUGFzcyAmUCk7CisKKyAgLy8vIENoZWNrIGlmIHRoZSBlZGdlIGJldHdlZW4gdGhpcyBibG9jayBhbmQgdGhlIGdpdmVuIHN1Y2Nlc3NvciBccAorICAvLy8gU3VjYywgY2FuIGJlIHNwbGl0LiBJZiB0aGlzIHJldHVybnMgdHJ1ZSBhIHN1YnNlcXVlbnQgY2FsbCB0bworICAvLy8gU3BsaXRDcml0aWNhbEVkZ2UgaXMgZ3VhcmFudGVlZCB0byByZXR1cm4gYSB2YWxpZCBiYXNpYyBibG9jayBpZgorICAvLy8gbm8gY2hhbmdlcyBvY2N1cnJlZCBpbiB0aGUgbWVhbnRpbWUuCisgIGJvb2wgY2FuU3BsaXRDcml0aWNhbEVkZ2UoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKlN1Y2MpIGNvbnN0OworCisgIHZvaWQgcG9wX2Zyb250KCkgeyBJbnN0cy5wb3BfZnJvbnQoKTsgfQorICB2b2lkIHBvcF9iYWNrKCkgeyBJbnN0cy5wb3BfYmFjaygpOyB9CisgIHZvaWQgcHVzaF9iYWNrKE1hY2hpbmVJbnN0ciAqTUkpIHsgSW5zdHMucHVzaF9iYWNrKE1JKTsgfQorCisgIC8vLyBJbnNlcnQgTUkgaW50byB0aGUgaW5zdHJ1Y3Rpb24gbGlzdCBiZWZvcmUgSSwgcG9zc2libHkgaW5zaWRlIGEgYnVuZGxlLgorICAvLy8KKyAgLy8vIElmIHRoZSBpbnNlcnRpb24gcG9pbnQgaXMgaW5zaWRlIGEgYnVuZGxlLCBNSSB3aWxsIGJlIGFkZGVkIHRvIHRoZSBidW5kbGUsCisgIC8vLyBvdGhlcndpc2UgTUkgd2lsbCBub3QgYmUgYWRkZWQgdG8gYW55IGJ1bmRsZS4gVGhhdCBtZWFucyB0aGlzIGZ1bmN0aW9uCisgIC8vLyBhbG9uZSBjYW4ndCBiZSB1c2VkIHRvIHByZXBlbmQgb3IgYXBwZW5kIGluc3RydWN0aW9ucyB0byBidW5kbGVzLiBTZWUKKyAgLy8vIE1JQnVuZGxlQnVpbGRlcjo6aW5zZXJ0KCkgZm9yIGEgbW9yZSByZWxpYWJsZSB3YXkgb2YgZG9pbmcgdGhhdC4KKyAgaW5zdHJfaXRlcmF0b3IgaW5zZXJ0KGluc3RyX2l0ZXJhdG9yIEksIE1hY2hpbmVJbnN0ciAqTSk7CisKKyAgLy8vIEluc2VydCBhIHJhbmdlIG9mIGluc3RydWN0aW9ucyBpbnRvIHRoZSBpbnN0cnVjdGlvbiBsaXN0IGJlZm9yZSBJLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBJVD4KKyAgdm9pZCBpbnNlcnQoaXRlcmF0b3IgSSwgSVQgUywgSVQgRSkgeworICAgIGFzc2VydCgoSSA9PSBlbmQoKSB8fCBJLT5nZXRQYXJlbnQoKSA9PSB0aGlzKSAmJgorICAgICAgICAgICAiaXRlcmF0b3IgcG9pbnRzIG91dHNpZGUgb2YgYmFzaWMgYmxvY2siKTsKKyAgICBJbnN0cy5pbnNlcnQoSS5nZXRJbnN0ckl0ZXJhdG9yKCksIFMsIEUpOworICB9CisKKyAgLy8vIEluc2VydCBNSSBpbnRvIHRoZSBpbnN0cnVjdGlvbiBsaXN0IGJlZm9yZSBJLgorICBpdGVyYXRvciBpbnNlcnQoaXRlcmF0b3IgSSwgTWFjaGluZUluc3RyICpNSSkgeworICAgIGFzc2VydCgoSSA9PSBlbmQoKSB8fCBJLT5nZXRQYXJlbnQoKSA9PSB0aGlzKSAmJgorICAgICAgICAgICAiaXRlcmF0b3IgcG9pbnRzIG91dHNpZGUgb2YgYmFzaWMgYmxvY2siKTsKKyAgICBhc3NlcnQoIU1JLT5pc0J1bmRsZWRXaXRoUHJlZCgpICYmICFNSS0+aXNCdW5kbGVkV2l0aFN1Y2MoKSAmJgorICAgICAgICAgICAiQ2Fubm90IGluc2VydCBpbnN0cnVjdGlvbiB3aXRoIGJ1bmRsZSBmbGFncyIpOworICAgIHJldHVybiBJbnN0cy5pbnNlcnQoSS5nZXRJbnN0ckl0ZXJhdG9yKCksIE1JKTsKKyAgfQorCisgIC8vLyBJbnNlcnQgTUkgaW50byB0aGUgaW5zdHJ1Y3Rpb24gbGlzdCBhZnRlciBJLgorICBpdGVyYXRvciBpbnNlcnRBZnRlcihpdGVyYXRvciBJLCBNYWNoaW5lSW5zdHIgKk1JKSB7CisgICAgYXNzZXJ0KChJID09IGVuZCgpIHx8IEktPmdldFBhcmVudCgpID09IHRoaXMpICYmCisgICAgICAgICAgICJpdGVyYXRvciBwb2ludHMgb3V0c2lkZSBvZiBiYXNpYyBibG9jayIpOworICAgIGFzc2VydCghTUktPmlzQnVuZGxlZFdpdGhQcmVkKCkgJiYgIU1JLT5pc0J1bmRsZWRXaXRoU3VjYygpICYmCisgICAgICAgICAgICJDYW5ub3QgaW5zZXJ0IGluc3RydWN0aW9uIHdpdGggYnVuZGxlIGZsYWdzIik7CisgICAgcmV0dXJuIEluc3RzLmluc2VydEFmdGVyKEkuZ2V0SW5zdHJJdGVyYXRvcigpLCBNSSk7CisgIH0KKworICAvLy8gUmVtb3ZlIGFuIGluc3RydWN0aW9uIGZyb20gdGhlIGluc3RydWN0aW9uIGxpc3QgYW5kIGRlbGV0ZSBpdC4KKyAgLy8vCisgIC8vLyBJZiB0aGUgaW5zdHJ1Y3Rpb24gaXMgcGFydCBvZiBhIGJ1bmRsZSwgdGhlIG90aGVyIGluc3RydWN0aW9ucyBpbiB0aGUKKyAgLy8vIGJ1bmRsZSB3aWxsIHN0aWxsIGJlIGJ1bmRsZWQgYWZ0ZXIgcmVtb3ZpbmcgdGhlIHNpbmdsZSBpbnN0cnVjdGlvbi4KKyAgaW5zdHJfaXRlcmF0b3IgZXJhc2UoaW5zdHJfaXRlcmF0b3IgSSk7CisKKyAgLy8vIFJlbW92ZSBhbiBpbnN0cnVjdGlvbiBmcm9tIHRoZSBpbnN0cnVjdGlvbiBsaXN0IGFuZCBkZWxldGUgaXQuCisgIC8vLworICAvLy8gSWYgdGhlIGluc3RydWN0aW9uIGlzIHBhcnQgb2YgYSBidW5kbGUsIHRoZSBvdGhlciBpbnN0cnVjdGlvbnMgaW4gdGhlCisgIC8vLyBidW5kbGUgd2lsbCBzdGlsbCBiZSBidW5kbGVkIGFmdGVyIHJlbW92aW5nIHRoZSBzaW5nbGUgaW5zdHJ1Y3Rpb24uCisgIGluc3RyX2l0ZXJhdG9yIGVyYXNlX2luc3RyKE1hY2hpbmVJbnN0ciAqSSkgeworICAgIHJldHVybiBlcmFzZShpbnN0cl9pdGVyYXRvcihJKSk7CisgIH0KKworICAvLy8gUmVtb3ZlIGEgcmFuZ2Ugb2YgaW5zdHJ1Y3Rpb25zIGZyb20gdGhlIGluc3RydWN0aW9uIGxpc3QgYW5kIGRlbGV0ZSB0aGVtLgorICBpdGVyYXRvciBlcmFzZShpdGVyYXRvciBJLCBpdGVyYXRvciBFKSB7CisgICAgcmV0dXJuIEluc3RzLmVyYXNlKEkuZ2V0SW5zdHJJdGVyYXRvcigpLCBFLmdldEluc3RySXRlcmF0b3IoKSk7CisgIH0KKworICAvLy8gUmVtb3ZlIGFuIGluc3RydWN0aW9uIG9yIGJ1bmRsZSBmcm9tIHRoZSBpbnN0cnVjdGlvbiBsaXN0IGFuZCBkZWxldGUgaXQuCisgIC8vLworICAvLy8gSWYgSSBwb2ludHMgdG8gYSBidW5kbGUgb2YgaW5zdHJ1Y3Rpb25zLCB0aGV5IGFyZSBhbGwgZXJhc2VkLgorICBpdGVyYXRvciBlcmFzZShpdGVyYXRvciBJKSB7CisgICAgcmV0dXJuIGVyYXNlKEksIHN0ZDo6bmV4dChJKSk7CisgIH0KKworICAvLy8gUmVtb3ZlIGFuIGluc3RydWN0aW9uIGZyb20gdGhlIGluc3RydWN0aW9uIGxpc3QgYW5kIGRlbGV0ZSBpdC4KKyAgLy8vCisgIC8vLyBJZiBJIGlzIHRoZSBoZWFkIG9mIGEgYnVuZGxlIG9mIGluc3RydWN0aW9ucywgdGhlIHdob2xlIGJ1bmRsZSB3aWxsIGJlCisgIC8vLyBlcmFzZWQuCisgIGl0ZXJhdG9yIGVyYXNlKE1hY2hpbmVJbnN0ciAqSSkgeworICAgIHJldHVybiBlcmFzZShpdGVyYXRvcihJKSk7CisgIH0KKworICAvLy8gUmVtb3ZlIHRoZSB1bmJ1bmRsZWQgaW5zdHJ1Y3Rpb24gZnJvbSB0aGUgaW5zdHJ1Y3Rpb24gbGlzdCB3aXRob3V0CisgIC8vLyBkZWxldGluZyBpdC4KKyAgLy8vCisgIC8vLyBUaGlzIGZ1bmN0aW9uIGNhbiBub3QgYmUgdXNlZCB0byByZW1vdmUgYnVuZGxlZCBpbnN0cnVjdGlvbnMsIHVzZQorICAvLy8gcmVtb3ZlX2luc3RyIHRvIHJlbW92ZSBpbmRpdmlkdWFsIGluc3RydWN0aW9ucyBmcm9tIGEgYnVuZGxlLgorICBNYWNoaW5lSW5zdHIgKnJlbW92ZShNYWNoaW5lSW5zdHIgKkkpIHsKKyAgICBhc3NlcnQoIUktPmlzQnVuZGxlZCgpICYmICJDYW5ub3QgcmVtb3ZlIGJ1bmRsZWQgaW5zdHJ1Y3Rpb25zIik7CisgICAgcmV0dXJuIEluc3RzLnJlbW92ZShpbnN0cl9pdGVyYXRvcihJKSk7CisgIH0KKworICAvLy8gUmVtb3ZlIHRoZSBwb3NzaWJseSBidW5kbGVkIGluc3RydWN0aW9uIGZyb20gdGhlIGluc3RydWN0aW9uIGxpc3QKKyAgLy8vIHdpdGhvdXQgZGVsZXRpbmcgaXQuCisgIC8vLworICAvLy8gSWYgdGhlIGluc3RydWN0aW9uIGlzIHBhcnQgb2YgYSBidW5kbGUsIHRoZSBvdGhlciBpbnN0cnVjdGlvbnMgaW4gdGhlCisgIC8vLyBidW5kbGUgd2lsbCBzdGlsbCBiZSBidW5kbGVkIGFmdGVyIHJlbW92aW5nIHRoZSBzaW5nbGUgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ciAqcmVtb3ZlX2luc3RyKE1hY2hpbmVJbnN0ciAqSSk7CisKKyAgdm9pZCBjbGVhcigpIHsKKyAgICBJbnN0cy5jbGVhcigpOworICB9CisKKyAgLy8vIFRha2UgYW4gaW5zdHJ1Y3Rpb24gZnJvbSBNQkIgJ090aGVyJyBhdCB0aGUgcG9zaXRpb24gRnJvbSwgYW5kIGluc2VydCBpdAorICAvLy8gaW50byB0aGlzIE1CQiByaWdodCBiZWZvcmUgJ1doZXJlJy4KKyAgLy8vCisgIC8vLyBJZiBGcm9tIHBvaW50cyB0byBhIGJ1bmRsZSBvZiBpbnN0cnVjdGlvbnMsIHRoZSB3aG9sZSBidW5kbGUgaXMgbW92ZWQuCisgIHZvaWQgc3BsaWNlKGl0ZXJhdG9yIFdoZXJlLCBNYWNoaW5lQmFzaWNCbG9jayAqT3RoZXIsIGl0ZXJhdG9yIEZyb20pIHsKKyAgICAvLyBUaGUgcmFuZ2Ugc3BsaWNlKCkgZG9lc24ndCBhbGxvdyBub29wIG1vdmVzLCBidXQgdGhpcyBvbmUgZG9lcy4KKyAgICBpZiAoV2hlcmUgIT0gRnJvbSkKKyAgICAgIHNwbGljZShXaGVyZSwgT3RoZXIsIEZyb20sIHN0ZDo6bmV4dChGcm9tKSk7CisgIH0KKworICAvLy8gVGFrZSBhIGJsb2NrIG9mIGluc3RydWN0aW9ucyBmcm9tIE1CQiAnT3RoZXInIGluIHRoZSByYW5nZSBbRnJvbSwgVG8pLAorICAvLy8gYW5kIGluc2VydCB0aGVtIGludG8gdGhpcyBNQkIgcmlnaHQgYmVmb3JlICdXaGVyZScuCisgIC8vLworICAvLy8gVGhlIGluc3RydWN0aW9uIGF0ICdXaGVyZScgbXVzdCBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIHJhbmdlIG9mCisgIC8vLyBpbnN0cnVjdGlvbnMgdG8gbW92ZS4KKyAgdm9pZCBzcGxpY2UoaXRlcmF0b3IgV2hlcmUsIE1hY2hpbmVCYXNpY0Jsb2NrICpPdGhlciwKKyAgICAgICAgICAgICAgaXRlcmF0b3IgRnJvbSwgaXRlcmF0b3IgVG8pIHsKKyAgICBJbnN0cy5zcGxpY2UoV2hlcmUuZ2V0SW5zdHJJdGVyYXRvcigpLCBPdGhlci0+SW5zdHMsCisgICAgICAgICAgICAgICAgIEZyb20uZ2V0SW5zdHJJdGVyYXRvcigpLCBUby5nZXRJbnN0ckl0ZXJhdG9yKCkpOworICB9CisKKyAgLy8vIFRoaXMgbWV0aG9kIHVubGlua3MgJ3RoaXMnIGZyb20gdGhlIGNvbnRhaW5pbmcgZnVuY3Rpb24sIGFuZCByZXR1cm5zIGl0LAorICAvLy8gYnV0IGRvZXMgbm90IGRlbGV0ZSBpdC4KKyAgTWFjaGluZUJhc2ljQmxvY2sgKnJlbW92ZUZyb21QYXJlbnQoKTsKKworICAvLy8gVGhpcyBtZXRob2QgdW5saW5rcyAndGhpcycgZnJvbSB0aGUgY29udGFpbmluZyBmdW5jdGlvbiBhbmQgZGVsZXRlcyBpdC4KKyAgdm9pZCBlcmFzZUZyb21QYXJlbnQoKTsKKworICAvLy8gR2l2ZW4gYSBtYWNoaW5lIGJhc2ljIGJsb2NrIHRoYXQgYnJhbmNoZWQgdG8gJ09sZCcsIGNoYW5nZSB0aGUgY29kZSBhbmQKKyAgLy8vIENGRyBzbyB0aGF0IGl0IGJyYW5jaGVzIHRvICdOZXcnIGluc3RlYWQuCisgIHZvaWQgUmVwbGFjZVVzZXNPZkJsb2NrV2l0aChNYWNoaW5lQmFzaWNCbG9jayAqT2xkLCBNYWNoaW5lQmFzaWNCbG9jayAqTmV3KTsKKworICAvLy8gVmFyaW91cyBwaWVjZXMgb2YgY29kZSBjYW4gY2F1c2UgZXhjZXNzIGVkZ2VzIGluIHRoZSBDRkcgdG8gYmUgaW5zZXJ0ZWQuCisgIC8vLyBJZiB3ZSBoYXZlIHByb3ZlbiB0aGF0IE1CQiBjYW4gb25seSBicmFuY2ggdG8gRGVzdEEgYW5kIERlc3RCLCByZW1vdmUgYW55CisgIC8vLyBvdGhlciBNQkIgc3VjY2Vzc29ycyBmcm9tIHRoZSBDRkcuIERlc3RBIGFuZCBEZXN0QiBjYW4gYmUgbnVsbC4gQmVzaWRlcworICAvLy8gRGVzdEEgYW5kIERlc3RCLCByZXRhaW4gb3RoZXIgZWRnZXMgbGVhZGluZyB0byBMYW5kaW5nUGFkcyAoY3VycmVudGx5CisgIC8vLyB0aGVyZSBjYW4gYmUgb25seSBvbmU7IHdlIGRvbid0IGNoZWNrIG9yIHJlcXVpcmUgdGhhdCBoZXJlKS4gTm90ZSBpdCBpcworICAvLy8gcG9zc2libGUgdGhhdCBEZXN0QSBhbmQvb3IgRGVzdEIgYXJlIExhbmRpbmdQYWRzLgorICBib29sIENvcnJlY3RFeHRyYUNGR0VkZ2VzKE1hY2hpbmVCYXNpY0Jsb2NrICpEZXN0QSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jayAqRGVzdEIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBJc0NvbmQpOworCisgIC8vLyBGaW5kIHRoZSBuZXh0IHZhbGlkIERlYnVnTG9jIHN0YXJ0aW5nIGF0IE1CQkksIHNraXBwaW5nIGFueSBEQkdfVkFMVUUKKyAgLy8vIGluc3RydWN0aW9ucy4gIFJldHVybiBVbmtub3duTG9jIGlmIHRoZXJlIGlzIG5vbmUuCisgIERlYnVnTG9jIGZpbmREZWJ1Z0xvYyhpbnN0cl9pdGVyYXRvciBNQkJJKTsKKyAgRGVidWdMb2MgZmluZERlYnVnTG9jKGl0ZXJhdG9yIE1CQkkpIHsKKyAgICByZXR1cm4gZmluZERlYnVnTG9jKE1CQkkuZ2V0SW5zdHJJdGVyYXRvcigpKTsKKyAgfQorCisgIC8vLyBGaW5kIHRoZSBwcmV2aW91cyB2YWxpZCBEZWJ1Z0xvYyBwcmVjZWRpbmcgTUJCSSwgc2tpcHBpbmcgYW5kIERCR19WQUxVRQorICAvLy8gaW5zdHJ1Y3Rpb25zLiAgUmV0dXJuIFVua25vd25Mb2MgaWYgdGhlcmUgaXMgbm9uZS4KKyAgRGVidWdMb2MgZmluZFByZXZEZWJ1Z0xvYyhpbnN0cl9pdGVyYXRvciBNQkJJKTsKKyAgRGVidWdMb2MgZmluZFByZXZEZWJ1Z0xvYyhpdGVyYXRvciBNQkJJKSB7CisgICAgcmV0dXJuIGZpbmRQcmV2RGVidWdMb2MoTUJCSS5nZXRJbnN0ckl0ZXJhdG9yKCkpOworICB9CisKKyAgLy8vIEZpbmQgYW5kIHJldHVybiB0aGUgbWVyZ2VkIERlYnVnTG9jIG9mIHRoZSBicmFuY2ggaW5zdHJ1Y3Rpb25zIG9mIHRoZQorICAvLy8gYmxvY2suIFJldHVybiBVbmtub3duTG9jIGlmIHRoZXJlIGlzIG5vbmUuCisgIERlYnVnTG9jIGZpbmRCcmFuY2hEZWJ1Z0xvYygpOworCisgIC8vLyBQb3NzaWJsZSBvdXRjb21lIG9mIGEgcmVnaXN0ZXIgbGl2ZW5lc3MgcXVlcnkgdG8gY29tcHV0ZVJlZ2lzdGVyTGl2ZW5lc3MoKQorICBlbnVtIExpdmVuZXNzUXVlcnlSZXN1bHQgeworICAgIExRUl9MaXZlLCAgIC8vLzwgUmVnaXN0ZXIgaXMga25vd24gdG8gYmUgKGF0IGxlYXN0IHBhcnRpYWxseSkgbGl2ZS4KKyAgICBMUVJfRGVhZCwgICAvLy88IFJlZ2lzdGVyIGlzIGtub3duIHRvIGJlIGZ1bGx5IGRlYWQuCisgICAgTFFSX1Vua25vd24gLy8vPCBSZWdpc3RlciBsaXZlbmVzcyBub3QgZGVjaWRhYmxlIGZyb20gbG9jYWwgbmVpZ2hib3Job29kLgorICB9OworCisgIC8vLyBSZXR1cm4gd2hldGhlciAocGh5c2ljYWwpIHJlZ2lzdGVyIFxwIFJlZyBoYXMgYmVlbiBkZWZpbmVkIGFuZCBub3QKKyAgLy8vIGtpbGxlZCBhcyBvZiBqdXN0IGJlZm9yZSBccCBCZWZvcmUuCisgIC8vLworICAvLy8gU2VhcmNoIGlzIGxvY2FsaXNlZCB0byBhIG5laWdoYm9yaG9vZCBvZiBccCBOZWlnaGJvcmhvb2QgaW5zdHJ1Y3Rpb25zCisgIC8vLyBiZWZvcmUgKHNlYXJjaGluZyBmb3IgZGVmcyBvciBraWxscykgYW5kIFxwIE5laWdoYm9yaG9vZCBpbnN0cnVjdGlvbnMKKyAgLy8vIGFmdGVyIChzZWFyY2hpbmcganVzdCBmb3IgZGVmcykgXHAgQmVmb3JlLgorICAvLy8KKyAgLy8vIFxwIFJlZyBtdXN0IGJlIGEgcGh5c2ljYWwgcmVnaXN0ZXIuCisgIExpdmVuZXNzUXVlcnlSZXN1bHQgY29tcHV0ZVJlZ2lzdGVyTGl2ZW5lc3MoY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgUmVnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0X2l0ZXJhdG9yIEJlZm9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBOZWlnaGJvcmhvb2QgPSAxMCkgY29uc3Q7CisKKyAgLy8gRGVidWdnaW5nIG1ldGhvZHMuCisgIHZvaWQgZHVtcCgpIGNvbnN0OworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUywgY29uc3QgU2xvdEluZGV4ZXMgKiA9IG51bGxwdHIsCisgICAgICAgICAgICAgYm9vbCBJc1N0YW5kYWxvbmUgPSB0cnVlKSBjb25zdDsKKyAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MsIE1vZHVsZVNsb3RUcmFja2VyICZNU1QsCisgICAgICAgICAgICAgY29uc3QgU2xvdEluZGV4ZXMgKiA9IG51bGxwdHIsIGJvb2wgSXNTdGFuZGFsb25lID0gdHJ1ZSkgY29uc3Q7CisKKyAgLy8gUHJpbnRpbmcgbWV0aG9kIHVzZWQgYnkgTG9vcEluZm8uCisgIHZvaWQgcHJpbnRBc09wZXJhbmQocmF3X29zdHJlYW0gJk9TLCBib29sIFByaW50VHlwZSA9IHRydWUpIGNvbnN0OworCisgIC8vLyBNYWNoaW5lQmFzaWNCbG9ja3MgYXJlIHVuaXF1ZWx5IG51bWJlcmVkIGF0IHRoZSBmdW5jdGlvbiBsZXZlbCwgdW5sZXNzCisgIC8vLyB0aGV5J3JlIG5vdCBpbiBhIE1hY2hpbmVGdW5jdGlvbiB5ZXQsIGluIHdoaWNoIGNhc2UgdGhpcyB3aWxsIHJldHVybiAtMS4KKyAgaW50IGdldE51bWJlcigpIGNvbnN0IHsgcmV0dXJuIE51bWJlcjsgfQorICB2b2lkIHNldE51bWJlcihpbnQgTikgeyBOdW1iZXIgPSBOOyB9CisKKyAgLy8vIFJldHVybiB0aGUgTUNTeW1ib2wgZm9yIHRoaXMgYmFzaWMgYmxvY2suCisgIE1DU3ltYm9sICpnZXRTeW1ib2woKSBjb25zdDsKKworICBPcHRpb25hbDx1aW50NjRfdD4gZ2V0SXJyTG9vcEhlYWRlcldlaWdodCgpIGNvbnN0IHsKKyAgICByZXR1cm4gSXJyTG9vcEhlYWRlcldlaWdodDsKKyAgfQorCisgIHZvaWQgc2V0SXJyTG9vcEhlYWRlcldlaWdodCh1aW50NjRfdCBXZWlnaHQpIHsKKyAgICBJcnJMb29wSGVhZGVyV2VpZ2h0ID0gV2VpZ2h0OworICB9CisKK3ByaXZhdGU6CisgIC8vLyBSZXR1cm4gcHJvYmFiaWxpdHkgaXRlcmF0b3IgY29ycmVzcG9uZGluZyB0byB0aGUgSSBzdWNjZXNzb3IgaXRlcmF0b3IuCisgIHByb2JhYmlsaXR5X2l0ZXJhdG9yIGdldFByb2JhYmlsaXR5SXRlcmF0b3Ioc3VjY19pdGVyYXRvciBJKTsKKyAgY29uc3RfcHJvYmFiaWxpdHlfaXRlcmF0b3IKKyAgZ2V0UHJvYmFiaWxpdHlJdGVyYXRvcihjb25zdF9zdWNjX2l0ZXJhdG9yIEkpIGNvbnN0OworCisgIGZyaWVuZCBjbGFzcyBNYWNoaW5lQnJhbmNoUHJvYmFiaWxpdHlJbmZvOworICBmcmllbmQgY2xhc3MgTUlQcmludGVyOworCisgIC8vLyBSZXR1cm4gcHJvYmFiaWxpdHkgb2YgdGhlIGVkZ2UgZnJvbSB0aGlzIGJsb2NrIHRvIE1CQi4gVGhpcyBtZXRob2Qgc2hvdWxkCisgIC8vLyBOT1QgYmUgY2FsbGVkIGRpcmVjdGx5LCBidXQgYnkgdXNpbmcgZ2V0RWRnZVByb2JhYmlsaXR5IG1ldGhvZCBmcm9tCisgIC8vLyBNYWNoaW5lQnJhbmNoUHJvYmFiaWxpdHlJbmZvIGNsYXNzLgorICBCcmFuY2hQcm9iYWJpbGl0eSBnZXRTdWNjUHJvYmFiaWxpdHkoY29uc3Rfc3VjY19pdGVyYXRvciBTdWNjKSBjb25zdDsKKworICAvLyBNZXRob2RzIHVzZWQgdG8gbWFpbnRhaW4gZG91Ymx5IGxpbmtlZCBsaXN0IG9mIGJsb2Nrcy4uLgorICBmcmllbmQgc3RydWN0IGlsaXN0X2NhbGxiYWNrX3RyYWl0czxNYWNoaW5lQmFzaWNCbG9jaz47CisKKyAgLy8gTWFjaGluZS1DRkcgbXV0YXRvcnMKKworICAvLy8gQWRkIFByZWQgYXMgYSBwcmVkZWNlc3NvciBvZiB0aGlzIE1hY2hpbmVCYXNpY0Jsb2NrLiBEb24ndCBkbyB0aGlzCisgIC8vLyB1bmxlc3MgeW91IGtub3cgd2hhdCB5b3UncmUgZG9pbmcsIGJlY2F1c2UgaXQgZG9lc24ndCB1cGRhdGUgUHJlZCdzCisgIC8vLyBzdWNjZXNzb3JzIGxpc3QuIFVzZSBQcmVkLT5hZGRTdWNjZXNzb3IgaW5zdGVhZC4KKyAgdm9pZCBhZGRQcmVkZWNlc3NvcihNYWNoaW5lQmFzaWNCbG9jayAqUHJlZCk7CisKKyAgLy8vIFJlbW92ZSBQcmVkIGFzIGEgcHJlZGVjZXNzb3Igb2YgdGhpcyBNYWNoaW5lQmFzaWNCbG9jay4gRG9uJ3QgZG8gdGhpcworICAvLy8gdW5sZXNzIHlvdSBrbm93IHdoYXQgeW91J3JlIGRvaW5nLCBiZWNhdXNlIGl0IGRvZXNuJ3QgdXBkYXRlIFByZWQncworICAvLy8gc3VjY2Vzc29ycyBsaXN0LiBVc2UgUHJlZC0+cmVtb3ZlU3VjY2Vzc29yIGluc3RlYWQuCisgIHZvaWQgcmVtb3ZlUHJlZGVjZXNzb3IoTWFjaGluZUJhc2ljQmxvY2sgKlByZWQpOworfTsKKworcmF3X29zdHJlYW0mIG9wZXJhdG9yPDwocmF3X29zdHJlYW0gJk9TLCBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAmTUJCKTsKKworLy8vIFByaW50cyBhIG1hY2hpbmUgYmFzaWMgYmxvY2sgcmVmZXJlbmNlLgorLy8vCisvLy8gVGhlIGZvcm1hdCBpczoKKy8vLyAgICViYi41ICAgICAgICAgICAtIGEgbWFjaGluZSBiYXNpYyBibG9jayB3aXRoIE1CQi5nZXROdW1iZXIoKSA9PSA1LgorLy8vCisvLy8gVXNhZ2U6IE9TIDw8IHByaW50TUJCUmVmZXJlbmNlKE1CQikgPDwgJ1xuJzsKK1ByaW50YWJsZSBwcmludE1CQlJlZmVyZW5jZShjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAmTUJCKTsKKworLy8gVGhpcyBpcyB1c2VmdWwgd2hlbiBidWlsZGluZyBJbmRleGVkTWFwcyBrZXllZCBvbiBiYXNpYyBibG9jayBwb2ludGVycy4KK3N0cnVjdCBNQkIyTnVtYmVyRnVuY3RvciB7CisgIHVzaW5nIGFyZ3VtZW50X3R5cGUgPSBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqOworICB1bnNpZ25lZCBvcGVyYXRvcigpKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpIGNvbnN0IHsKKyAgICByZXR1cm4gTUJCLT5nZXROdW1iZXIoKTsKKyAgfQorfTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLyBHcmFwaFRyYWl0cyBzcGVjaWFsaXphdGlvbnMgZm9yIG1hY2hpbmUgYmFzaWMgYmxvY2sgZ3JhcGhzIChtYWNoaW5lLUNGR3MpCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworLy8gUHJvdmlkZSBzcGVjaWFsaXphdGlvbnMgb2YgR3JhcGhUcmFpdHMgdG8gYmUgYWJsZSB0byB0cmVhdCBhCisvLyBNYWNoaW5lRnVuY3Rpb24gYXMgYSBncmFwaCBvZiBNYWNoaW5lQmFzaWNCbG9ja3MuCisvLworCit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgR3JhcGhUcmFpdHM8TWFjaGluZUJhc2ljQmxvY2sgKj4geworICB1c2luZyBOb2RlUmVmID0gTWFjaGluZUJhc2ljQmxvY2sgKjsKKyAgdXNpbmcgQ2hpbGRJdGVyYXRvclR5cGUgPSBNYWNoaW5lQmFzaWNCbG9jazo6c3VjY19pdGVyYXRvcjsKKworICBzdGF0aWMgTm9kZVJlZiBnZXRFbnRyeU5vZGUoTWFjaGluZUJhc2ljQmxvY2sgKkJCKSB7IHJldHVybiBCQjsgfQorICBzdGF0aWMgQ2hpbGRJdGVyYXRvclR5cGUgY2hpbGRfYmVnaW4oTm9kZVJlZiBOKSB7IHJldHVybiBOLT5zdWNjX2JlZ2luKCk7IH0KKyAgc3RhdGljIENoaWxkSXRlcmF0b3JUeXBlIGNoaWxkX2VuZChOb2RlUmVmIE4pIHsgcmV0dXJuIE4tPnN1Y2NfZW5kKCk7IH0KK307CisKK3RlbXBsYXRlIDw+IHN0cnVjdCBHcmFwaFRyYWl0czxjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqPiB7CisgIHVzaW5nIE5vZGVSZWYgPSBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqOworICB1c2luZyBDaGlsZEl0ZXJhdG9yVHlwZSA9IE1hY2hpbmVCYXNpY0Jsb2NrOjpjb25zdF9zdWNjX2l0ZXJhdG9yOworCisgIHN0YXRpYyBOb2RlUmVmIGdldEVudHJ5Tm9kZShjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqQkIpIHsgcmV0dXJuIEJCOyB9CisgIHN0YXRpYyBDaGlsZEl0ZXJhdG9yVHlwZSBjaGlsZF9iZWdpbihOb2RlUmVmIE4pIHsgcmV0dXJuIE4tPnN1Y2NfYmVnaW4oKTsgfQorICBzdGF0aWMgQ2hpbGRJdGVyYXRvclR5cGUgY2hpbGRfZW5kKE5vZGVSZWYgTikgeyByZXR1cm4gTi0+c3VjY19lbmQoKTsgfQorfTsKKworLy8gUHJvdmlkZSBzcGVjaWFsaXphdGlvbnMgb2YgR3JhcGhUcmFpdHMgdG8gYmUgYWJsZSB0byB0cmVhdCBhCisvLyBNYWNoaW5lRnVuY3Rpb24gYXMgYSBncmFwaCBvZiBNYWNoaW5lQmFzaWNCbG9ja3MgYW5kIHRvIHdhbGsgaXQKKy8vIGluIGludmVyc2Ugb3JkZXIuICBJbnZlcnNlIG9yZGVyIGZvciBhIGZ1bmN0aW9uIGlzIGNvbnNpZGVyZWQKKy8vIHRvIGJlIHdoZW4gdHJhdmVyc2luZyB0aGUgcHJlZGVjZXNzb3IgZWRnZXMgb2YgYSBNQkIKKy8vIGluc3RlYWQgb2YgdGhlIHN1Y2Nlc3NvciBlZGdlcy4KKy8vCit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgR3JhcGhUcmFpdHM8SW52ZXJzZTxNYWNoaW5lQmFzaWNCbG9jayo+PiB7CisgIHVzaW5nIE5vZGVSZWYgPSBNYWNoaW5lQmFzaWNCbG9jayAqOworICB1c2luZyBDaGlsZEl0ZXJhdG9yVHlwZSA9IE1hY2hpbmVCYXNpY0Jsb2NrOjpwcmVkX2l0ZXJhdG9yOworCisgIHN0YXRpYyBOb2RlUmVmIGdldEVudHJ5Tm9kZShJbnZlcnNlPE1hY2hpbmVCYXNpY0Jsb2NrICo+IEcpIHsKKyAgICByZXR1cm4gRy5HcmFwaDsKKyAgfQorCisgIHN0YXRpYyBDaGlsZEl0ZXJhdG9yVHlwZSBjaGlsZF9iZWdpbihOb2RlUmVmIE4pIHsgcmV0dXJuIE4tPnByZWRfYmVnaW4oKTsgfQorICBzdGF0aWMgQ2hpbGRJdGVyYXRvclR5cGUgY2hpbGRfZW5kKE5vZGVSZWYgTikgeyByZXR1cm4gTi0+cHJlZF9lbmQoKTsgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IEdyYXBoVHJhaXRzPEludmVyc2U8Y29uc3QgTWFjaGluZUJhc2ljQmxvY2sqPj4geworICB1c2luZyBOb2RlUmVmID0gY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKjsKKyAgdXNpbmcgQ2hpbGRJdGVyYXRvclR5cGUgPSBNYWNoaW5lQmFzaWNCbG9jazo6Y29uc3RfcHJlZF9pdGVyYXRvcjsKKworICBzdGF0aWMgTm9kZVJlZiBnZXRFbnRyeU5vZGUoSW52ZXJzZTxjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqPiBHKSB7CisgICAgcmV0dXJuIEcuR3JhcGg7CisgIH0KKworICBzdGF0aWMgQ2hpbGRJdGVyYXRvclR5cGUgY2hpbGRfYmVnaW4oTm9kZVJlZiBOKSB7IHJldHVybiBOLT5wcmVkX2JlZ2luKCk7IH0KKyAgc3RhdGljIENoaWxkSXRlcmF0b3JUeXBlIGNoaWxkX2VuZChOb2RlUmVmIE4pIHsgcmV0dXJuIE4tPnByZWRfZW5kKCk7IH0KK307CisKKy8vLyBNYWNoaW5lSW5zdHJTcGFuIHByb3ZpZGVzIGFuIGludGVyZmFjZSB0byBnZXQgYW4gaXRlcmF0aW9uIHJhbmdlCisvLy8gY29udGFpbmluZyB0aGUgaW5zdHJ1Y3Rpb24gaXQgd2FzIGluaXRpYWxpemVkIHdpdGgsIGFsb25nIHdpdGggYWxsCisvLy8gdGhvc2UgaW5zdHJ1Y3Rpb25zIGluc2VydGVkIHByaW9yIHRvIG9yIGZvbGxvd2luZyB0aGF0IGluc3RydWN0aW9uCisvLy8gYXQgc29tZSBwb2ludCBhZnRlciB0aGUgTWFjaGluZUluc3RyU3BhbiBpcyBjb25zdHJ1Y3RlZC4KK2NsYXNzIE1hY2hpbmVJbnN0clNwYW4geworICBNYWNoaW5lQmFzaWNCbG9jayAmTUJCOworICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgSSwgQiwgRTsKKworcHVibGljOgorICBNYWNoaW5lSW5zdHJTcGFuKE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBJKQorICAgIDogTUJCKCpJLT5nZXRQYXJlbnQoKSksCisgICAgICBJKEkpLAorICAgICAgQihJID09IE1CQi5iZWdpbigpID8gTUJCLmVuZCgpIDogc3RkOjpwcmV2KEkpKSwKKyAgICAgIEUoc3RkOjpuZXh0KEkpKSB7fQorCisgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBiZWdpbigpIHsKKyAgICByZXR1cm4gQiA9PSBNQkIuZW5kKCkgPyBNQkIuYmVnaW4oKSA6IHN0ZDo6bmV4dChCKTsKKyAgfQorICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgZW5kKCkgeyByZXR1cm4gRTsgfQorICBib29sIGVtcHR5KCkgeyByZXR1cm4gYmVnaW4oKSA9PSBlbmQoKTsgfQorCisgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBnZXRJbml0aWFsKCkgeyByZXR1cm4gSTsgfQorfTsKKworLy8vIEluY3JlbWVudCBccCBJdCB1bnRpbCBpdCBwb2ludHMgdG8gYSBub24tZGVidWcgaW5zdHJ1Y3Rpb24gb3IgdG8gXHAgRW5kCisvLy8gYW5kIHJldHVybiB0aGUgcmVzdWx0aW5nIGl0ZXJhdG9yLiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBvbmx5IGJlIHVzZWQKKy8vLyBNYWNoaW5lQmFzaWNCbG9jazo6e2l0ZXJhdG9yLCBjb25zdF9pdGVyYXRvciwgaW5zdHJfaXRlcmF0b3IsCisvLy8gY29uc3RfaW5zdHJfaXRlcmF0b3J9IGFuZCB0aGUgcmVzcGVjdGl2ZSByZXZlcnNlIGl0ZXJhdG9ycy4KK3RlbXBsYXRlPHR5cGVuYW1lIEl0ZXJUPgoraW5saW5lIEl0ZXJUIHNraXBEZWJ1Z0luc3RydWN0aW9uc0ZvcndhcmQoSXRlclQgSXQsIEl0ZXJUIEVuZCkgeworICB3aGlsZSAoSXQgIT0gRW5kICYmIEl0LT5pc0RlYnVnVmFsdWUoKSkKKyAgICBJdCsrOworICByZXR1cm4gSXQ7Cit9CisKKy8vLyBEZWNyZW1lbnQgXHAgSXQgdW50aWwgaXQgcG9pbnRzIHRvIGEgbm9uLWRlYnVnIGluc3RydWN0aW9uIG9yIHRvIFxwIEJlZ2luCisvLy8gYW5kIHJldHVybiB0aGUgcmVzdWx0aW5nIGl0ZXJhdG9yLiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBvbmx5IGJlIHVzZWQKKy8vLyBNYWNoaW5lQmFzaWNCbG9jazo6e2l0ZXJhdG9yLCBjb25zdF9pdGVyYXRvciwgaW5zdHJfaXRlcmF0b3IsCisvLy8gY29uc3RfaW5zdHJfaXRlcmF0b3J9IGFuZCB0aGUgcmVzcGVjdGl2ZSByZXZlcnNlIGl0ZXJhdG9ycy4KK3RlbXBsYXRlPGNsYXNzIEl0ZXJUPgoraW5saW5lIEl0ZXJUIHNraXBEZWJ1Z0luc3RydWN0aW9uc0JhY2t3YXJkKEl0ZXJUIEl0LCBJdGVyVCBCZWdpbikgeworICB3aGlsZSAoSXQgIT0gQmVnaW4gJiYgSXQtPmlzRGVidWdWYWx1ZSgpKQorICAgIEl0LS07CisgIHJldHVybiBJdDsKK30KKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9NQUNISU5FQkFTSUNCTE9DS19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mby5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm8uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YjRiOTljCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm8uaApAQCAtMCwwICsxLDg1IEBACisvLz09PS0gTWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mby5oIC0gTUJCIEZyZXF1ZW5jeSBBbmFseXNpcyAtLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIExvb3BzIHNob3VsZCBiZSBzaW1wbGlmaWVkIGJlZm9yZSB0aGlzIGFuYWx5c2lzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ0hJTkVCTE9DS0ZSRVFVRU5DWUlORk9fSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTUFDSElORUJMT0NLRlJFUVVFTkNZSU5GT19ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9PcHRpb25hbC5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lRnVuY3Rpb25QYXNzLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0Jsb2NrRnJlcXVlbmN5LmgiCisjaW5jbHVkZSA8Y3N0ZGludD4KKyNpbmNsdWRlIDxtZW1vcnk+CisKK25hbWVzcGFjZSBsbHZtIHsKKwordGVtcGxhdGUgPGNsYXNzIEJsb2NrVD4gY2xhc3MgQmxvY2tGcmVxdWVuY3lJbmZvSW1wbDsKK2NsYXNzIE1hY2hpbmVCYXNpY0Jsb2NrOworY2xhc3MgTWFjaGluZUJyYW5jaFByb2JhYmlsaXR5SW5mbzsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIE1hY2hpbmVMb29wSW5mbzsKK2NsYXNzIHJhd19vc3RyZWFtOworCisvLy8gTWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mbyBwYXNzIHVzZXMgQmxvY2tGcmVxdWVuY3lJbmZvSW1wbCBpbXBsZW1lbnRhdGlvbgorLy8vIHRvIGVzdGltYXRlIG1hY2hpbmUgYmFzaWMgYmxvY2sgZnJlcXVlbmNpZXMuCitjbGFzcyBNYWNoaW5lQmxvY2tGcmVxdWVuY3lJbmZvIDogcHVibGljIE1hY2hpbmVGdW5jdGlvblBhc3MgeworICB1c2luZyBJbXBsVHlwZSA9IEJsb2NrRnJlcXVlbmN5SW5mb0ltcGw8TWFjaGluZUJhc2ljQmxvY2s+OworICBzdGQ6OnVuaXF1ZV9wdHI8SW1wbFR5cGU+IE1CRkk7CisKK3B1YmxpYzoKKyAgc3RhdGljIGNoYXIgSUQ7CisKKyAgTWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mbygpOworICB+TWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mbygpIG92ZXJyaWRlOworCisgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlICZBVSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgYm9vbCBydW5Pbk1hY2hpbmVGdW5jdGlvbihNYWNoaW5lRnVuY3Rpb24gJkYpIG92ZXJyaWRlOworCisgIC8vLyBjYWxjdWxhdGUgLSBjb21wdXRlIGJsb2NrIGZyZXF1ZW5jeSBpbmZvIGZvciB0aGUgZ2l2ZW4gZnVuY3Rpb24uCisgIHZvaWQgY2FsY3VsYXRlKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmRiwKKyAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUJyYW5jaFByb2JhYmlsaXR5SW5mbyAmTUJQSSwKKyAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUxvb3BJbmZvICZNTEkpOworCisgIHZvaWQgcmVsZWFzZU1lbW9yeSgpIG92ZXJyaWRlOworCisgIC8vLyBnZXRibG9ja0ZyZXEgLSBSZXR1cm4gYmxvY2sgZnJlcXVlbmN5LiBSZXR1cm4gMCBpZiB3ZSBkb24ndCBoYXZlIHRoZQorICAvLy8gaW5mb3JtYXRpb24uIFBsZWFzZSBub3RlIHRoYXQgaW5pdGlhbCBmcmVxdWVuY3kgaXMgZXF1YWwgdG8gMTAyNC4gSXQgbWVhbnMKKyAgLy8vIHRoYXQgd2Ugc2hvdWxkIG5vdCByZWx5IG9uIHRoZSB2YWx1ZSBpdHNlbGYsIGJ1dCBvbmx5IG9uIHRoZSBjb21wYXJpc29uIHRvCisgIC8vLyB0aGUgb3RoZXIgYmxvY2sgZnJlcXVlbmNpZXMuIFdlIGRvIHRoaXMgdG8gYXZvaWQgdXNpbmcgb2YgZmxvYXRpbmcgcG9pbnRzLgorICAvLy8KKyAgQmxvY2tGcmVxdWVuY3kgZ2V0QmxvY2tGcmVxKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpIGNvbnN0OworCisgIE9wdGlvbmFsPHVpbnQ2NF90PiBnZXRCbG9ja1Byb2ZpbGVDb3VudChjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqTUJCKSBjb25zdDsKKyAgT3B0aW9uYWw8dWludDY0X3Q+IGdldFByb2ZpbGVDb3VudEZyb21GcmVxKHVpbnQ2NF90IEZyZXEpIGNvbnN0OworCisgIGJvb2wgaXNJcnJMb29wSGVhZGVyKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpOworCisgIGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAqZ2V0RnVuY3Rpb24oKSBjb25zdDsKKyAgY29uc3QgTWFjaGluZUJyYW5jaFByb2JhYmlsaXR5SW5mbyAqZ2V0TUJQSSgpIGNvbnN0OworICB2b2lkIHZpZXcoY29uc3QgVHdpbmUgJk5hbWUsIGJvb2wgaXNTaW1wbGUgPSB0cnVlKSBjb25zdDsKKworICAvLyBQcmludCB0aGUgYmxvY2sgZnJlcXVlbmN5IEZyZXEgdG8gT1MgdXNpbmcgdGhlIGN1cnJlbnQgZnVuY3Rpb25zIGVudHJ5CisgIC8vIGZyZXF1ZW5jeSB0byBjb252ZXJ0IGZyZXEgaW50byBhIHJlbGF0aXZlIGRlY2ltYWwgZm9ybS4KKyAgcmF3X29zdHJlYW0gJnByaW50QmxvY2tGcmVxKHJhd19vc3RyZWFtICZPUywgY29uc3QgQmxvY2tGcmVxdWVuY3kgRnJlcSkgY29uc3Q7CisKKyAgLy8gQ29udmVuaWVuY2UgbWV0aG9kIHRoYXQgYXR0ZW1wdHMgdG8gbG9vayB1cCB0aGUgZnJlcXVlbmN5IGFzc29jaWF0ZWQgd2l0aAorICAvLyBCQiBhbmQgcHJpbnQgaXQgdG8gT1MuCisgIHJhd19vc3RyZWFtICZwcmludEJsb2NrRnJlcShyYXdfb3N0cmVhbSAmT1MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqTUJCKSBjb25zdDsKKworICB1aW50NjRfdCBnZXRFbnRyeUZyZXEoKSBjb25zdDsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTUFDSElORUJMT0NLRlJFUVVFTkNZSU5GT19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUJyYW5jaFByb2JhYmlsaXR5SW5mby5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVCcmFuY2hQcm9iYWJpbGl0eUluZm8uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MWIwNTI0Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVCcmFuY2hQcm9iYWJpbGl0eUluZm8uaApAQCAtMCwwICsxLDc3IEBACisvLz0tIE1hY2hpbmVCcmFuY2hQcm9iYWJpbGl0eUluZm8uaCAtIEJyYW5jaCBQcm9iYWJpbGl0eSBBbmFseXNpcyAtKi0gQysrIC0qLT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgcGFzcyBpcyB1c2VkIHRvIGV2YWx1YXRlIGJyYW5jaCBwcm9iYWJpbHRpZXMgb24gbWFjaGluZSBiYXNpYyBibG9ja3MuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORUJSQU5DSFBST0JBQklMSVRZSU5GT19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9NQUNISU5FQlJBTkNIUFJPQkFCSUxJVFlJTkZPX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lQmFzaWNCbG9jay5oIgorI2luY2x1ZGUgImxsdm0vUGFzcy5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9CcmFuY2hQcm9iYWJpbGl0eS5oIgorI2luY2x1ZGUgPGNsaW1pdHM+CisjaW5jbHVkZSA8bnVtZXJpYz4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNYWNoaW5lQnJhbmNoUHJvYmFiaWxpdHlJbmZvIDogcHVibGljIEltbXV0YWJsZVBhc3MgeworICB2aXJ0dWFsIHZvaWQgYW5jaG9yKCk7CisKKyAgLy8gRGVmYXVsdCB3ZWlnaHQgdmFsdWUuIFVzZWQgd2hlbiB3ZSBkb24ndCBoYXZlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBlZGdlLgorICAvLyBUT0RPOiBERUZBVUxUX1dFSUdIVCBtYWtlcyBzZW5zZSBkdXJpbmcgc3RhdGljIHByZWRpY2F0aW9uLCB3aGVuIG5vbmUgb2YKKyAgLy8gdGhlIHN1Y2Nlc3NvcnMgaGF2ZSBhIHdlaWdodCB5ZXQuIEJ1dCBpdCBkb2Vzbid0IG1ha2Ugc2Vuc2Ugd2hlbiBwcm92aWRpbmcKKyAgLy8gd2VpZ2h0IHRvIGFuIGVkZ2UgdGhhdCBtYXkgaGF2ZSBzaWJsaW5ncyB3aXRoIG5vbi16ZXJvIHdlaWdodHMuIFRoaXMgY2FuCisgIC8vIGJlIGhhbmRsZWQgdmFyaW91cyB3YXlzLCBidXQgaXQncyBwcm9iYWJseSBmaW5lIGZvciBhbiBlZGdlIHdpdGggdW5rbm93bgorICAvLyB3ZWlnaHQgdG8ganVzdCAiaW5oZXJpdCIgdGhlIG5vbi16ZXJvIHdlaWdodCBvZiBhbiBhZGphY2VudCBzdWNjZXNzb3IuCisgIHN0YXRpYyBjb25zdCB1aW50MzJfdCBERUZBVUxUX1dFSUdIVCA9IDE2OworCitwdWJsaWM6CisgIHN0YXRpYyBjaGFyIElEOworCisgIE1hY2hpbmVCcmFuY2hQcm9iYWJpbGl0eUluZm8oKSA6IEltbXV0YWJsZVBhc3MoSUQpIHsKKyAgICBQYXNzUmVnaXN0cnkgJlJlZ2lzdHJ5ID0gKlBhc3NSZWdpc3RyeTo6Z2V0UGFzc1JlZ2lzdHJ5KCk7CisgICAgaW5pdGlhbGl6ZU1hY2hpbmVCcmFuY2hQcm9iYWJpbGl0eUluZm9QYXNzKFJlZ2lzdHJ5KTsKKyAgfQorCisgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlICZBVSkgY29uc3Qgb3ZlcnJpZGUgeworICAgIEFVLnNldFByZXNlcnZlc0FsbCgpOworICB9CisKKyAgLy8gUmV0dXJuIGVkZ2UgcHJvYmFiaWxpdHkuCisgIEJyYW5jaFByb2JhYmlsaXR5IGdldEVkZ2VQcm9iYWJpbGl0eShjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqU3JjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKkRzdCkgY29uc3Q7CisKKyAgLy8gU2FtZSBhcyBhYm92ZSwgYnV0IHVzaW5nIGEgY29uc3Rfc3VjY19pdGVyYXRvciBmcm9tIFNyYy4gVGhpcyBpcyBmYXN0ZXIKKyAgLy8gd2hlbiB0aGUgaXRlcmF0b3IgaXMgYWxyZWFkeSBhdmFpbGFibGUuCisgIEJyYW5jaFByb2JhYmlsaXR5CisgIGdldEVkZ2VQcm9iYWJpbGl0eShjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqU3JjLAorICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6OmNvbnN0X3N1Y2NfaXRlcmF0b3IgRHN0KSBjb25zdDsKKworICAvLyBBICdIb3QnIGVkZ2UgaXMgYW4gZWRnZSB3aGljaCBwcm9iYWJpbGl0eSBpcyA+PSA4MCUuCisgIGJvb2wgaXNFZGdlSG90KGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpTcmMsCisgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpEc3QpIGNvbnN0OworCisgIC8vIFJldHVybiBhIGhvdCBzdWNjZXNzb3IgZm9yIHRoZSBibG9jayBCQiBvciBudWxsIGlmIHRoZXJlIGlzbid0IG9uZS4KKyAgLy8gTkI6IFRoaXMgcm91dGluZSdzIGNvbXBsZXhpdHkgaXMgbGluZWFyIG9uIHRoZSBudW1iZXIgb2Ygc3VjY2Vzc29ycy4KKyAgTWFjaGluZUJhc2ljQmxvY2sgKmdldEhvdFN1Y2MoTWFjaGluZUJhc2ljQmxvY2sgKk1CQikgY29uc3Q7CisKKyAgLy8gUHJpbnQgdmFsdWUgYmV0d2VlbiAwICgwJSBwcm9iYWJpbGl0eSkgYW5kIDEgKDEwMCUgcHJvYmFiaWxpdHkpLAorICAvLyBob3dldmVyIHRoZSB2YWx1ZSBpcyBuZXZlciBlcXVhbCB0byAwLCBhbmQgY2FuIGJlIDEgb25seSBpZmYgU1JDIGJsb2NrCisgIC8vIGhhcyBvbmx5IG9uZSBzdWNjZXNzb3IuCisgIHJhd19vc3RyZWFtICZwcmludEVkZ2VQcm9iYWJpbGl0eShyYXdfb3N0cmVhbSAmT1MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqU3JjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKkRzdCkgY29uc3Q7Cit9OworCit9CisKKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUNvbWJpbmVyUGF0dGVybi5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVDb21iaW5lclBhdHRlcm4uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ODY1MzVmCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVDb21iaW5lclBhdHRlcm4uaApAQCAtMCwwICsxLDg3IEBACisvLz09PS0tIGxsdm0vQ29kZUdlbi9NYWNoaW5lQ29tYmluZXJQYXR0ZXJuLmggLSBJbnN0cnVjdGlvbiBwYXR0ZXJuIHN1cHBvcnRlZCBieQorLy8gY29tYmluZXIgIC0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZWZpbmVzIGluc3RydWN0aW9uIHBhdHRlcm4gc3VwcG9ydGVkIGJ5IGNvbWJpbmVyCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORUNPTUJJTkVSUEFUVEVSTl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9NQUNISU5FQ09NQklORVJQQVRURVJOX0gKKworbmFtZXNwYWNlIGxsdm0geworCisvLy8gVGhlc2UgYXJlIGluc3RydWN0aW9uIHBhdHRlcm5zIG1hdGNoZWQgYnkgdGhlIG1hY2hpbmUgY29tYmluZXIgcGFzcy4KK2VudW0gY2xhc3MgTWFjaGluZUNvbWJpbmVyUGF0dGVybiB7CisgIC8vIFRoZXNlIGFyZSBjb21tdXRhdGl2ZSB2YXJpYW50cyBmb3IgcmVhc3NvY2lhdGluZyBhIGNvbXB1dGF0aW9uIGNoYWluLiBTZWUKKyAgLy8gdGhlIGNvbW1lbnRzIGJlZm9yZSBnZXRNYWNoaW5lQ29tYmluZXJQYXR0ZXJucygpIGluIFRhcmdldEluc3RySW5mby5jcHAuCisgIFJFQVNTT0NfQVhfQlksCisgIFJFQVNTT0NfQVhfWUIsCisgIFJFQVNTT0NfWEFfQlksCisgIFJFQVNTT0NfWEFfWUIsCisKKyAgLy8gVGhlc2UgYXJlIG11bHRpcGx5LWFkZCBwYXR0ZXJucyBtYXRjaGVkIGJ5IHRoZSBBQXJjaDY0IG1hY2hpbmUgY29tYmluZXIuCisgIE1VTEFERFdfT1AxLAorICBNVUxBRERXX09QMiwKKyAgTVVMU1VCV19PUDEsCisgIE1VTFNVQldfT1AyLAorICBNVUxBRERXSV9PUDEsCisgIE1VTFNVQldJX09QMSwKKyAgTVVMQUREWF9PUDEsCisgIE1VTEFERFhfT1AyLAorICBNVUxTVUJYX09QMSwKKyAgTVVMU1VCWF9PUDIsCisgIE1VTEFERFhJX09QMSwKKyAgTVVMU1VCWElfT1AxLAorICAvLyBGbG9hdGluZyBQb2ludAorICBGTVVMQUREU19PUDEsCisgIEZNVUxBRERTX09QMiwKKyAgRk1VTFNVQlNfT1AxLAorICBGTVVMU1VCU19PUDIsCisgIEZNVUxBREREX09QMSwKKyAgRk1VTEFERERfT1AyLAorICBGTVVMU1VCRF9PUDEsCisgIEZNVUxTVUJEX09QMiwKKyAgRk5NVUxTVUJTX09QMSwKKyAgRk5NVUxTVUJEX09QMSwKKyAgRk1MQXYxaTMyX2luZGV4ZWRfT1AxLAorICBGTUxBdjFpMzJfaW5kZXhlZF9PUDIsCisgIEZNTEF2MWk2NF9pbmRleGVkX09QMSwKKyAgRk1MQXYxaTY0X2luZGV4ZWRfT1AyLAorICBGTUxBdjJmMzJfT1AyLAorICBGTUxBdjJmMzJfT1AxLAorICBGTUxBdjJmNjRfT1AxLAorICBGTUxBdjJmNjRfT1AyLAorICBGTUxBdjJpMzJfaW5kZXhlZF9PUDEsCisgIEZNTEF2MmkzMl9pbmRleGVkX09QMiwKKyAgRk1MQXYyaTY0X2luZGV4ZWRfT1AxLAorICBGTUxBdjJpNjRfaW5kZXhlZF9PUDIsCisgIEZNTEF2NGYzMl9PUDEsCisgIEZNTEF2NGYzMl9PUDIsCisgIEZNTEF2NGkzMl9pbmRleGVkX09QMSwKKyAgRk1MQXY0aTMyX2luZGV4ZWRfT1AyLAorICBGTUxTdjFpMzJfaW5kZXhlZF9PUDIsCisgIEZNTFN2MWk2NF9pbmRleGVkX09QMiwKKyAgRk1MU3YyZjMyX09QMSwKKyAgRk1MU3YyZjMyX09QMiwKKyAgRk1MU3YyZjY0X09QMSwKKyAgRk1MU3YyZjY0X09QMiwKKyAgRk1MU3YyaTMyX2luZGV4ZWRfT1AxLAorICBGTUxTdjJpMzJfaW5kZXhlZF9PUDIsCisgIEZNTFN2Mmk2NF9pbmRleGVkX09QMSwKKyAgRk1MU3YyaTY0X2luZGV4ZWRfT1AyLAorICBGTUxTdjRmMzJfT1AxLAorICBGTUxTdjRmMzJfT1AyLAorICBGTUxTdjRpMzJfaW5kZXhlZF9PUDEsCisgIEZNTFN2NGkzMl9pbmRleGVkX09QMgorfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUNvbnN0YW50UG9vbC5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVDb25zdGFudFBvb2wuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNzA1YTBmCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVDb25zdGFudFBvb2wuaApAQCAtMCwwICsxLDE2NCBAQAorLy89PT0tIENvZGVHZW4vTWFjaGluZUNvbnN0YW50UG9vbC5oIC0gQWJzdHJhY3QgQ29uc3RhbnQgUG9vbCAtLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLy8gQGZpbGUKKy8vLyBUaGlzIGZpbGUgZGVjbGFyZXMgdGhlIE1hY2hpbmVDb25zdGFudFBvb2wgY2xhc3Mgd2hpY2ggaXMgYW4gYWJzdHJhY3QKKy8vLyBjb25zdGFudCBwb29sIHRvIGtlZXAgdHJhY2sgb2YgY29uc3RhbnRzIHJlZmVyZW5jZWQgYnkgYSBmdW5jdGlvbi4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9NQUNISU5FQ09OU1RBTlRQT09MX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX01BQ0hJTkVDT05TVEFOVFBPT0xfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VTZXQuaCIKKyNpbmNsdWRlICJsbHZtL01DL1NlY3Rpb25LaW5kLmgiCisjaW5jbHVkZSA8Y2xpbWl0cz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgQ29uc3RhbnQ7CitjbGFzcyBEYXRhTGF5b3V0OworY2xhc3MgRm9sZGluZ1NldE5vZGVJRDsKK2NsYXNzIE1hY2hpbmVDb25zdGFudFBvb2w7CitjbGFzcyByYXdfb3N0cmVhbTsKK2NsYXNzIFR5cGU7CisKKy8vLyBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBhbGwgbWFjaGluZSBzcGVjaWZpYyBjb25zdGFudHBvb2wgdmFsdWUgc3ViY2xhc3Nlcy4KKy8vLworY2xhc3MgTWFjaGluZUNvbnN0YW50UG9vbFZhbHVlIHsKKyAgdmlydHVhbCB2b2lkIGFuY2hvcigpOworCisgIFR5cGUgKlR5OworCitwdWJsaWM6CisgIGV4cGxpY2l0IE1hY2hpbmVDb25zdGFudFBvb2xWYWx1ZShUeXBlICp0eSkgOiBUeSh0eSkge30KKyAgdmlydHVhbCB+TWFjaGluZUNvbnN0YW50UG9vbFZhbHVlKCkgPSBkZWZhdWx0OworCisgIC8vLyBnZXRUeXBlIC0gZ2V0IHR5cGUgb2YgdGhpcyBNYWNoaW5lQ29uc3RhbnRQb29sVmFsdWUuCisgIC8vLworICBUeXBlICpnZXRUeXBlKCkgY29uc3QgeyByZXR1cm4gVHk7IH0KKworICB2aXJ0dWFsIGludCBnZXRFeGlzdGluZ01hY2hpbmVDUFZhbHVlKE1hY2hpbmVDb25zdGFudFBvb2wgKkNQLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIEFsaWdubWVudCkgPSAwOworCisgIHZpcnR1YWwgdm9pZCBhZGRTZWxlY3Rpb25EQUdDU0VJZChGb2xkaW5nU2V0Tm9kZUlEICZJRCkgPSAwOworCisgIC8vLyBwcmludCAtIEltcGxlbWVudCBvcGVyYXRvcjw8CisgIHZpcnR1YWwgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmTykgY29uc3QgPSAwOworfTsKKworaW5saW5lIHJhd19vc3RyZWFtICZvcGVyYXRvcjw8KHJhd19vc3RyZWFtICZPUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lQ29uc3RhbnRQb29sVmFsdWUgJlYpIHsKKyAgVi5wcmludChPUyk7CisgIHJldHVybiBPUzsKK30KKworLy8vIFRoaXMgY2xhc3MgaXMgYSBkYXRhIGNvbnRhaW5lciBmb3Igb25lIGVudHJ5IGluIGEgTWFjaGluZUNvbnN0YW50UG9vbC4KKy8vLyBJdCBjb250YWlucyBhIHBvaW50ZXIgdG8gdGhlIHZhbHVlIGFuZCBhbiBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YKKy8vLyB0aGUgY29uc3RhbnQgcG9vbC4KKy8vLyBAYnJpZWYgQW4gZW50cnkgaW4gYSBNYWNoaW5lQ29uc3RhbnRQb29sCitjbGFzcyBNYWNoaW5lQ29uc3RhbnRQb29sRW50cnkgeworcHVibGljOgorICAvLy8gVGhlIGNvbnN0YW50IGl0c2VsZi4KKyAgdW5pb24geworICAgIGNvbnN0IENvbnN0YW50ICpDb25zdFZhbDsKKyAgICBNYWNoaW5lQ29uc3RhbnRQb29sVmFsdWUgKk1hY2hpbmVDUFZhbDsKKyAgfSBWYWw7CisKKyAgLy8vIFRoZSByZXF1aXJlZCBhbGlnbm1lbnQgZm9yIHRoaXMgZW50cnkuIFRoZSB0b3AgYml0IGlzIHNldCB3aGVuIFZhbCBpcworICAvLy8gYSB0YXJnZXQgc3BlY2lmaWMgTWFjaGluZUNvbnN0YW50UG9vbFZhbHVlLgorICB1bnNpZ25lZCBBbGlnbm1lbnQ7CisKKyAgTWFjaGluZUNvbnN0YW50UG9vbEVudHJ5KGNvbnN0IENvbnN0YW50ICpWLCB1bnNpZ25lZCBBKQorICAgIDogQWxpZ25tZW50KEEpIHsKKyAgICBWYWwuQ29uc3RWYWwgPSBWOworICB9CisKKyAgTWFjaGluZUNvbnN0YW50UG9vbEVudHJ5KE1hY2hpbmVDb25zdGFudFBvb2xWYWx1ZSAqViwgdW5zaWduZWQgQSkKKyAgICAgIDogQWxpZ25tZW50KEEpIHsKKyAgICBWYWwuTWFjaGluZUNQVmFsID0gVjsKKyAgICBBbGlnbm1lbnQgfD0gMVUgPDwgKHNpemVvZih1bnNpZ25lZCkgKiBDSEFSX0JJVCAtIDEpOworICB9CisKKyAgLy8vIGlzTWFjaGluZUNvbnN0YW50UG9vbEVudHJ5IC0gUmV0dXJuIHRydWUgaWYgdGhlIE1hY2hpbmVDb25zdGFudFBvb2xFbnRyeQorICAvLy8gaXMgaW5kZWVkIGEgdGFyZ2V0IHNwZWNpZmljIGNvbnN0YW50cG9vbCBlbnRyeSwgbm90IGEgd3JhcHBlciBvdmVyIGEKKyAgLy8vIENvbnN0YW50LgorICBib29sIGlzTWFjaGluZUNvbnN0YW50UG9vbEVudHJ5KCkgY29uc3QgeworICAgIHJldHVybiAoaW50KUFsaWdubWVudCA8IDA7CisgIH0KKworICBpbnQgZ2V0QWxpZ25tZW50KCkgY29uc3QgeworICAgIHJldHVybiBBbGlnbm1lbnQgJiB+KDEgPDwgKHNpemVvZih1bnNpZ25lZCkgKiBDSEFSX0JJVCAtIDEpKTsKKyAgfQorCisgIFR5cGUgKmdldFR5cGUoKSBjb25zdDsKKworICAvLy8gVGhpcyBtZXRob2QgY2xhc3NpZmllcyB0aGUgZW50cnkgYWNjb3JkaW5nIHRvIHdoZXRoZXIgb3Igbm90IGl0IG1heQorICAvLy8gZ2VuZXJhdGUgYSByZWxvY2F0aW9uIGVudHJ5LiAgVGhpcyBtdXN0IGJlIGNvbnNlcnZhdGl2ZSwgc28gaWYgaXQgbWlnaHQKKyAgLy8vIGNvZGVnZW4gdG8gYSByZWxvY2F0YWJsZSBlbnRyeSwgaXQgc2hvdWxkIHNheSBzby4KKyAgYm9vbCBuZWVkc1JlbG9jYXRpb24oKSBjb25zdDsKKworICBTZWN0aW9uS2luZCBnZXRTZWN0aW9uS2luZChjb25zdCBEYXRhTGF5b3V0ICpETCkgY29uc3Q7Cit9OworCisvLy8gVGhlIE1hY2hpbmVDb25zdGFudFBvb2wgY2xhc3Mga2VlcHMgdHJhY2sgb2YgY29uc3RhbnRzIHJlZmVyZW5jZWQgYnkgYQorLy8vIGZ1bmN0aW9uIHdoaWNoIG11c3QgYmUgc3BpbGxlZCB0byBtZW1vcnkuICBUaGlzIGlzIHVzZWQgZm9yIGNvbnN0YW50cyB3aGljaAorLy8vIGFyZSB1bmFibGUgdG8gYmUgdXNlZCBkaXJlY3RseSBhcyBvcGVyYW5kcyB0byBpbnN0cnVjdGlvbnMsIHdoaWNoIHR5cGljYWxseQorLy8vIGluY2x1ZGUgZmxvYXRpbmcgcG9pbnQgYW5kIGxhcmdlIGludGVnZXIgY29uc3RhbnRzLgorLy8vCisvLy8gSW5zdHJ1Y3Rpb25zIHJlZmVyZW5jZSB0aGUgYWRkcmVzcyBvZiB0aGVzZSBjb25zdGFudCBwb29sIGNvbnN0YW50cyB0aHJvdWdoCisvLy8gdGhlIHVzZSBvZiBNT19Db25zdGFudFBvb2xJbmRleCB2YWx1ZXMuICBXaGVuIGVtaXR0aW5nIGFzc2VtYmx5IG9yIG1hY2hpbmUKKy8vLyBjb2RlLCB0aGVzZSB2aXJ0dWFsIGFkZHJlc3MgcmVmZXJlbmNlcyBhcmUgY29udmVydGVkIHRvIHJlZmVyIHRvIHRoZQorLy8vIGFkZHJlc3Mgb2YgdGhlIGZ1bmN0aW9uIGNvbnN0YW50IHBvb2wgdmFsdWVzLgorLy8vIEBicmllZiBUaGUgbWFjaGluZSBjb25zdGFudCBwb29sLgorY2xhc3MgTWFjaGluZUNvbnN0YW50UG9vbCB7CisgIHVuc2lnbmVkIFBvb2xBbGlnbm1lbnQ7ICAgICAgIC8vLzwgVGhlIGFsaWdubWVudCBmb3IgdGhlIHBvb2wuCisgIHN0ZDo6dmVjdG9yPE1hY2hpbmVDb25zdGFudFBvb2xFbnRyeT4gQ29uc3RhbnRzOyAvLy88IFRoZSBwb29sIG9mIGNvbnN0YW50cy4KKyAgLy8vIE1hY2hpbmVDb25zdGFudFBvb2xWYWx1ZXMgdGhhdCB1c2UgYW4gZXhpc3RpbmcgTWFjaGluZUNvbnN0YW50UG9vbEVudHJ5LgorICBEZW5zZVNldDxNYWNoaW5lQ29uc3RhbnRQb29sVmFsdWUqPiBNYWNoaW5lQ1BWc1NoYXJpbmdFbnRyaWVzOworICBjb25zdCBEYXRhTGF5b3V0ICZETDsKKworICBjb25zdCBEYXRhTGF5b3V0ICZnZXREYXRhTGF5b3V0KCkgY29uc3QgeyByZXR1cm4gREw7IH0KKworcHVibGljOgorICAvLy8gQGJyaWVmIFRoZSBvbmx5IGNvbnN0cnVjdG9yLgorICBleHBsaWNpdCBNYWNoaW5lQ29uc3RhbnRQb29sKGNvbnN0IERhdGFMYXlvdXQgJkRMKQorICAgICAgOiBQb29sQWxpZ25tZW50KDEpLCBETChETCkge30KKyAgfk1hY2hpbmVDb25zdGFudFBvb2woKTsKKworICAvLy8gZ2V0Q29uc3RhbnRQb29sQWxpZ25tZW50IC0gUmV0dXJuIHRoZSBhbGlnbm1lbnQgcmVxdWlyZWQgYnkKKyAgLy8vIHRoZSB3aG9sZSBjb25zdGFudCBwb29sLCBvZiB3aGljaCB0aGUgZmlyc3QgZWxlbWVudCBtdXN0IGJlIGFsaWduZWQuCisgIHVuc2lnbmVkIGdldENvbnN0YW50UG9vbEFsaWdubWVudCgpIGNvbnN0IHsgcmV0dXJuIFBvb2xBbGlnbm1lbnQ7IH0KKworICAvLy8gZ2V0Q29uc3RhbnRQb29sSW5kZXggLSBDcmVhdGUgYSBuZXcgZW50cnkgaW4gdGhlIGNvbnN0YW50IHBvb2wgb3IgcmV0dXJuCisgIC8vLyBhbiBleGlzdGluZyBvbmUuICBVc2VyIG11c3Qgc3BlY2lmeSB0aGUgbWluaW11bSByZXF1aXJlZCBhbGlnbm1lbnQgZm9yCisgIC8vLyB0aGUgb2JqZWN0LgorICB1bnNpZ25lZCBnZXRDb25zdGFudFBvb2xJbmRleChjb25zdCBDb25zdGFudCAqQywgdW5zaWduZWQgQWxpZ25tZW50KTsKKyAgdW5zaWduZWQgZ2V0Q29uc3RhbnRQb29sSW5kZXgoTWFjaGluZUNvbnN0YW50UG9vbFZhbHVlICpWLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBBbGlnbm1lbnQpOworCisgIC8vLyBpc0VtcHR5IC0gUmV0dXJuIHRydWUgaWYgdGhpcyBjb25zdGFudCBwb29sIGNvbnRhaW5zIG5vIGNvbnN0YW50cy4KKyAgYm9vbCBpc0VtcHR5KCkgY29uc3QgeyByZXR1cm4gQ29uc3RhbnRzLmVtcHR5KCk7IH0KKworICBjb25zdCBzdGQ6OnZlY3RvcjxNYWNoaW5lQ29uc3RhbnRQb29sRW50cnk+ICZnZXRDb25zdGFudHMoKSBjb25zdCB7CisgICAgcmV0dXJuIENvbnN0YW50czsKKyAgfQorCisgIC8vLyBwcmludCAtIFVzZWQgYnkgdGhlIE1hY2hpbmVGdW5jdGlvbiBwcmludGVyIHRvIHByaW50IGluZm9ybWF0aW9uIGFib3V0CisgIC8vLyBjb25zdGFudCBwb29sIG9iamVjdHMuICBJbXBsZW1lbnRlZCBpbiBNYWNoaW5lRnVuY3Rpb24uY3BwCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk9TKSBjb25zdDsKKworICAvLy8gZHVtcCAtIENhbGwgcHJpbnQoY2VycikgdG8gYmUgY2FsbGVkIGZyb20gdGhlIGRlYnVnZ2VyLgorICB2b2lkIGR1bXAoKSBjb25zdDsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTUFDSElORUNPTlNUQU5UUE9PTF9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZURvbWluYW5jZUZyb250aWVyLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZURvbWluYW5jZUZyb250aWVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmZiY2M2MgotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lRG9taW5hbmNlRnJvbnRpZXIuaApAQCAtMCwwICsxLDExMSBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9NYWNoaW5lRG9taW5hbmNlRnJvbnRpZXIuaCAtLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORURPTUlOQU5DRUZST05USUVSX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX01BQ0hJTkVET01JTkFOQ0VGUk9OVElFUl9ICisKKyNpbmNsdWRlICJsbHZtL0FuYWx5c2lzL0RvbWluYW5jZUZyb250aWVyLmgiCisjaW5jbHVkZSAibGx2bS9BbmFseXNpcy9Eb21pbmFuY2VGcm9udGllckltcGwuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uUGFzcy5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9HZW5lcmljRG9tVHJlZS5oIgorI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNYWNoaW5lRG9taW5hbmNlRnJvbnRpZXIgOiBwdWJsaWMgTWFjaGluZUZ1bmN0aW9uUGFzcyB7CisgIEZvcndhcmREb21pbmFuY2VGcm9udGllckJhc2U8TWFjaGluZUJhc2ljQmxvY2s+IEJhc2U7CisKK3B1YmxpYzoKKyB1c2luZyBEb21UcmVlVCA9IERvbVRyZWVCYXNlPE1hY2hpbmVCYXNpY0Jsb2NrPjsKKyB1c2luZyBEb21UcmVlTm9kZVQgPSBEb21UcmVlTm9kZUJhc2U8TWFjaGluZUJhc2ljQmxvY2s+OworIHVzaW5nIERvbVNldFR5cGUgPSBEb21pbmFuY2VGcm9udGllckJhc2U8TWFjaGluZUJhc2ljQmxvY2ssIGZhbHNlPjo6RG9tU2V0VHlwZTsKKyB1c2luZyBpdGVyYXRvciA9IERvbWluYW5jZUZyb250aWVyQmFzZTxNYWNoaW5lQmFzaWNCbG9jaywgZmFsc2U+OjppdGVyYXRvcjsKKyB1c2luZyBjb25zdF9pdGVyYXRvciA9CisgICAgIERvbWluYW5jZUZyb250aWVyQmFzZTxNYWNoaW5lQmFzaWNCbG9jaywgZmFsc2U+Ojpjb25zdF9pdGVyYXRvcjsKKworIE1hY2hpbmVEb21pbmFuY2VGcm9udGllcihjb25zdCBNYWNoaW5lRG9taW5hbmNlRnJvbnRpZXIgJikgPSBkZWxldGU7CisgTWFjaGluZURvbWluYW5jZUZyb250aWVyICZvcGVyYXRvcj0oY29uc3QgTWFjaGluZURvbWluYW5jZUZyb250aWVyICYpID0gZGVsZXRlOworCisgc3RhdGljIGNoYXIgSUQ7CisKKyBNYWNoaW5lRG9taW5hbmNlRnJvbnRpZXIoKTsKKworIERvbWluYW5jZUZyb250aWVyQmFzZTxNYWNoaW5lQmFzaWNCbG9jaywgZmFsc2U+ICZnZXRCYXNlKCkgeyByZXR1cm4gQmFzZTsgfQorCisgIGNvbnN0IFNtYWxsVmVjdG9ySW1wbDxNYWNoaW5lQmFzaWNCbG9jayAqPiAmZ2V0Um9vdHMoKSBjb25zdCB7CisgICByZXR1cm4gQmFzZS5nZXRSb290cygpOworICB9CisKKyAgTWFjaGluZUJhc2ljQmxvY2sgKmdldFJvb3QoKSBjb25zdCB7CisgICAgcmV0dXJuIEJhc2UuZ2V0Um9vdCgpOworICB9CisKKyAgYm9vbCBpc1Bvc3REb21pbmF0b3IoKSBjb25zdCB7CisgICAgcmV0dXJuIEJhc2UuaXNQb3N0RG9taW5hdG9yKCk7CisgIH0KKworICBpdGVyYXRvciBiZWdpbigpIHsKKyAgICByZXR1cm4gQmFzZS5iZWdpbigpOworICB9CisKKyAgY29uc3RfaXRlcmF0b3IgYmVnaW4oKSBjb25zdCB7CisgICAgcmV0dXJuIEJhc2UuYmVnaW4oKTsKKyAgfQorCisgIGl0ZXJhdG9yIGVuZCgpIHsKKyAgICByZXR1cm4gQmFzZS5lbmQoKTsKKyAgfQorCisgIGNvbnN0X2l0ZXJhdG9yIGVuZCgpIGNvbnN0IHsKKyAgICByZXR1cm4gQmFzZS5lbmQoKTsKKyAgfQorCisgIGl0ZXJhdG9yIGZpbmQoTWFjaGluZUJhc2ljQmxvY2sgKkIpIHsKKyAgICByZXR1cm4gQmFzZS5maW5kKEIpOworICB9CisKKyAgY29uc3RfaXRlcmF0b3IgZmluZChNYWNoaW5lQmFzaWNCbG9jayAqQikgY29uc3QgeworICAgIHJldHVybiBCYXNlLmZpbmQoQik7CisgIH0KKworICBpdGVyYXRvciBhZGRCYXNpY0Jsb2NrKE1hY2hpbmVCYXNpY0Jsb2NrICpCQiwgY29uc3QgRG9tU2V0VHlwZSAmZnJvbnRpZXIpIHsKKyAgICByZXR1cm4gQmFzZS5hZGRCYXNpY0Jsb2NrKEJCLCBmcm9udGllcik7CisgIH0KKworICB2b2lkIHJlbW92ZUJsb2NrKE1hY2hpbmVCYXNpY0Jsb2NrICpCQikgeworICAgIHJldHVybiBCYXNlLnJlbW92ZUJsb2NrKEJCKTsKKyAgfQorCisgIHZvaWQgYWRkVG9Gcm9udGllcihpdGVyYXRvciBJLCBNYWNoaW5lQmFzaWNCbG9jayAqTm9kZSkgeworICAgIHJldHVybiBCYXNlLmFkZFRvRnJvbnRpZXIoSSwgTm9kZSk7CisgIH0KKworICB2b2lkIHJlbW92ZUZyb21Gcm9udGllcihpdGVyYXRvciBJLCBNYWNoaW5lQmFzaWNCbG9jayAqTm9kZSkgeworICAgIHJldHVybiBCYXNlLnJlbW92ZUZyb21Gcm9udGllcihJLCBOb2RlKTsKKyAgfQorCisgIGJvb2wgY29tcGFyZURvbVNldChEb21TZXRUeXBlICZEUzEsIGNvbnN0IERvbVNldFR5cGUgJkRTMikgY29uc3QgeworICAgIHJldHVybiBCYXNlLmNvbXBhcmVEb21TZXQoRFMxLCBEUzIpOworICB9CisKKyAgYm9vbCBjb21wYXJlKERvbWluYW5jZUZyb250aWVyQmFzZTxNYWNoaW5lQmFzaWNCbG9jaywgZmFsc2U+ICZPdGhlcikgY29uc3QgeworICAgIHJldHVybiBCYXNlLmNvbXBhcmUoT3RoZXIpOworICB9CisKKyAgYm9vbCBydW5Pbk1hY2hpbmVGdW5jdGlvbihNYWNoaW5lRnVuY3Rpb24gJkYpIG92ZXJyaWRlOworCisgIHZvaWQgcmVsZWFzZU1lbW9yeSgpIG92ZXJyaWRlOworCisgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlICZBVSkgY29uc3Qgb3ZlcnJpZGU7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX01BQ0hJTkVET01JTkFOQ0VGUk9OVElFUl9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZURvbWluYXRvcnMuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lRG9taW5hdG9ycy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFmNjQyZDkKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZURvbWluYXRvcnMuaApAQCAtMCwwICsxLDI5MSBAQAorLy89PS0gbGx2bS9Db2RlR2VuL01hY2hpbmVEb21pbmF0b3JzLmggLSBNYWNoaW5lIERvbSBDYWxjdWxhdGlvbiAtKi0gQysrIC0qLT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgZGVmaW5lcyBjbGFzc2VzIG1pcnJvcmluZyB0aG9zZSBpbiBsbHZtL0FuYWx5c2lzL0RvbWluYXRvcnMuaCwKKy8vIGJ1dCBmb3IgdGFyZ2V0LXNwZWNpZmljIGNvZGUgcmF0aGVyIHRoYW4gdGFyZ2V0LWluZGVwZW5kZW50IElSLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ0hJTkVET01JTkFUT1JTX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX01BQ0hJTkVET01JTkFUT1JTX0gKKworI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsU2V0LmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uUGFzcy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lSW5zdHIuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvR2VuZXJpY0RvbVRyZWUuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvR2VuZXJpY0RvbVRyZWVDb25zdHJ1Y3Rpb24uaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKK25hbWVzcGFjZSBsbHZtIHsKKwordGVtcGxhdGUgPD4KK2lubGluZSB2b2lkIERvbWluYXRvclRyZWVCYXNlPE1hY2hpbmVCYXNpY0Jsb2NrLCBmYWxzZT46OmFkZFJvb3QoCisgICAgTWFjaGluZUJhc2ljQmxvY2sgKk1CQikgeworICB0aGlzLT5Sb290cy5wdXNoX2JhY2soTUJCKTsKK30KKworZXh0ZXJuIHRlbXBsYXRlIGNsYXNzIERvbVRyZWVOb2RlQmFzZTxNYWNoaW5lQmFzaWNCbG9jaz47CitleHRlcm4gdGVtcGxhdGUgY2xhc3MgRG9taW5hdG9yVHJlZUJhc2U8TWFjaGluZUJhc2ljQmxvY2ssIGZhbHNlPjsgLy8gRG9tVHJlZQorZXh0ZXJuIHRlbXBsYXRlIGNsYXNzIERvbWluYXRvclRyZWVCYXNlPE1hY2hpbmVCYXNpY0Jsb2NrLCB0cnVlPjsgLy8gUG9zdERvbVRyZWUKKwordXNpbmcgTWFjaGluZURvbVRyZWVOb2RlID0gRG9tVHJlZU5vZGVCYXNlPE1hY2hpbmVCYXNpY0Jsb2NrPjsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLy8gRG9taW5hdG9yVHJlZSBDbGFzcyAtIENvbmNyZXRlIHN1YmNsYXNzIG9mIERvbWluYXRvclRyZWVCYXNlIHRoYXQgaXMgdXNlZCB0bworLy8vIGNvbXB1dGUgYSBub3JtYWwgZG9taW5hdG9yIHRyZWUuCisvLy8KK2NsYXNzIE1hY2hpbmVEb21pbmF0b3JUcmVlIDogcHVibGljIE1hY2hpbmVGdW5jdGlvblBhc3MgeworICAvLy8gXGJyaWVmIEhlbHBlciBzdHJ1Y3R1cmUgdXNlZCB0byBob2xkIGFsbCB0aGUgYmFzaWMgYmxvY2tzCisgIC8vLyBpbnZvbHZlZCBpbiB0aGUgc3BsaXQgb2YgYSBjcml0aWNhbCBlZGdlLgorICBzdHJ1Y3QgQ3JpdGljYWxFZGdlIHsKKyAgICBNYWNoaW5lQmFzaWNCbG9jayAqRnJvbUJCOworICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpUb0JCOworICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpOZXdCQjsKKyAgfTsKKworICAvLy8gXGJyaWVmIFBpbGUgdXAgYWxsIHRoZSBjcml0aWNhbCBlZGdlcyB0byBiZSBzcGxpdC4KKyAgLy8vIFRoZSBzcGxpdHRpbmcgb2YgYSBjcml0aWNhbCBlZGdlIGlzIGxvY2FsIGFuZCB0aHVzLCBpdCBpcyBwb3NzaWJsZQorICAvLy8gdG8gYXBwbHkgc2V2ZXJhbCBvZiB0aG9zZSBjaGFuZ2VzIGF0IHRoZSBzYW1lIHRpbWUuCisgIG11dGFibGUgU21hbGxWZWN0b3I8Q3JpdGljYWxFZGdlLCAzMj4gQ3JpdGljYWxFZGdlc1RvU3BsaXQ7CisKKyAgLy8vIFxicmllZiBSZW1lbWJlciBhbGwgdGhlIGJhc2ljIGJsb2NrcyB0aGF0IGFyZSBpbnNlcnRlZCBkdXJpbmcKKyAgLy8vIGVkZ2Ugc3BsaXR0aW5nLgorICAvLy8gSW52YXJpYW50OiBOZXdCQnMgPT0gYWxsIHRoZSBiYXNpYyBibG9ja3MgY29udGFpbmVkIGluIHRoZSBOZXdCQgorICAvLy8gZmllbGQgb2YgYWxsIHRoZSBlbGVtZW50cyBvZiBDcml0aWNhbEVkZ2VzVG9TcGxpdC4KKyAgLy8vIEkuZS4sIGZvcmFsbCBlbHQgaW4gQ3JpdGljYWxFZGdlc1RvU3BsaXQsIGl0IGV4aXN0cyBCQiBpbiBOZXdCQnMKKyAgLy8vIHN1Y2ggYXMgQkIgPT0gZWx0Lk5ld0JCLgorICBtdXRhYmxlIFNtYWxsU2V0PE1hY2hpbmVCYXNpY0Jsb2NrICosIDMyPiBOZXdCQnM7CisKKyAgLy8vIFRoZSBEb21pbmF0b3JUcmVlQmFzZSB0aGF0IGlzIHVzZWQgdG8gY29tcHV0ZSBhIG5vcm1hbCBkb21pbmF0b3IgdHJlZQorICBzdGQ6OnVuaXF1ZV9wdHI8RG9tVHJlZUJhc2U8TWFjaGluZUJhc2ljQmxvY2s+PiBEVDsKKworICAvLy8gXGJyaWVmIEFwcGx5IGFsbCB0aGUgcmVjb3JkZWQgY3JpdGljYWwgZWRnZXMgdG8gdGhlIERULgorICAvLy8gVGhpcyB1cGRhdGVzIHRoZSB1bmRlcmx5aW5nIERUIGluZm9ybWF0aW9uIGluIGEgd2F5IHRoYXQgdXNlcworICAvLy8gdGhlIGZhc3QgcXVlcnkgcGF0aCBvZiBEVCBhcyBtdWNoIGFzIHBvc3NpYmxlLgorICAvLy8KKyAgLy8vIFxwb3N0IENyaXRpY2FsRWRnZXNUb1NwbGl0LmVtcHR5KCkuCisgIHZvaWQgYXBwbHlTcGxpdENyaXRpY2FsRWRnZXMoKSBjb25zdDsKKworcHVibGljOgorICBzdGF0aWMgY2hhciBJRDsgLy8gUGFzcyBJRCwgcmVwbGFjZW1lbnQgZm9yIHR5cGVpZAorCisgIE1hY2hpbmVEb21pbmF0b3JUcmVlKCk7CisKKyAgRG9tVHJlZUJhc2U8TWFjaGluZUJhc2ljQmxvY2s+ICZnZXRCYXNlKCkgeworICAgIGlmICghRFQpIERULnJlc2V0KG5ldyBEb21UcmVlQmFzZTxNYWNoaW5lQmFzaWNCbG9jaz4oKSk7CisgICAgYXBwbHlTcGxpdENyaXRpY2FsRWRnZXMoKTsKKyAgICByZXR1cm4gKkRUOworICB9CisKKyAgdm9pZCBnZXRBbmFseXNpc1VzYWdlKEFuYWx5c2lzVXNhZ2UgJkFVKSBjb25zdCBvdmVycmlkZTsKKworICAvLy8gZ2V0Um9vdHMgLSAgUmV0dXJuIHRoZSByb290IGJsb2NrcyBvZiB0aGUgY3VycmVudCBDRkcuICBUaGlzIG1heSBpbmNsdWRlCisgIC8vLyBtdWx0aXBsZSBibG9ja3MgaWYgd2UgYXJlIGNvbXB1dGluZyBwb3N0IGRvbWluYXRvcnMuICBGb3IgZm9yd2FyZAorICAvLy8gZG9taW5hdG9ycywgdGhpcyB3aWxsIGFsd2F5cyBiZSBhIHNpbmdsZSBibG9jayAodGhlIGVudHJ5IG5vZGUpLgorICAvLy8KKyAgaW5saW5lIGNvbnN0IFNtYWxsVmVjdG9ySW1wbDxNYWNoaW5lQmFzaWNCbG9jayo+ICZnZXRSb290cygpIGNvbnN0IHsKKyAgICBhcHBseVNwbGl0Q3JpdGljYWxFZGdlcygpOworICAgIHJldHVybiBEVC0+Z2V0Um9vdHMoKTsKKyAgfQorCisgIGlubGluZSBNYWNoaW5lQmFzaWNCbG9jayAqZ2V0Um9vdCgpIGNvbnN0IHsKKyAgICBhcHBseVNwbGl0Q3JpdGljYWxFZGdlcygpOworICAgIHJldHVybiBEVC0+Z2V0Um9vdCgpOworICB9CisKKyAgaW5saW5lIE1hY2hpbmVEb21UcmVlTm9kZSAqZ2V0Um9vdE5vZGUoKSBjb25zdCB7CisgICAgYXBwbHlTcGxpdENyaXRpY2FsRWRnZXMoKTsKKyAgICByZXR1cm4gRFQtPmdldFJvb3ROb2RlKCk7CisgIH0KKworICBib29sIHJ1bk9uTWFjaGluZUZ1bmN0aW9uKE1hY2hpbmVGdW5jdGlvbiAmRikgb3ZlcnJpZGU7CisKKyAgaW5saW5lIGJvb2wgZG9taW5hdGVzKGNvbnN0IE1hY2hpbmVEb21UcmVlTm9kZSogQSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVEb21UcmVlTm9kZSogQikgY29uc3QgeworICAgIGFwcGx5U3BsaXRDcml0aWNhbEVkZ2VzKCk7CisgICAgcmV0dXJuIERULT5kb21pbmF0ZXMoQSwgQik7CisgIH0KKworICBpbmxpbmUgYm9vbCBkb21pbmF0ZXMoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sqIEEsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayogQikgY29uc3QgeworICAgIGFwcGx5U3BsaXRDcml0aWNhbEVkZ2VzKCk7CisgICAgcmV0dXJuIERULT5kb21pbmF0ZXMoQSwgQik7CisgIH0KKworICAvLyBkb21pbmF0ZXMgLSBSZXR1cm4gdHJ1ZSBpZiBBIGRvbWluYXRlcyBCLiBUaGlzIHBlcmZvcm1zIHRoZQorICAvLyBzcGVjaWFsIGNoZWNrcyBuZWNlc3NhcnkgaWYgQSBhbmQgQiBhcmUgaW4gdGhlIHNhbWUgYmFzaWMgYmxvY2suCisgIGJvb2wgZG9taW5hdGVzKGNvbnN0IE1hY2hpbmVJbnN0ciAqQSwgY29uc3QgTWFjaGluZUluc3RyICpCKSBjb25zdCB7CisgICAgYXBwbHlTcGxpdENyaXRpY2FsRWRnZXMoKTsKKyAgICBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqQkJBID0gQS0+Z2V0UGFyZW50KCksICpCQkIgPSBCLT5nZXRQYXJlbnQoKTsKKyAgICBpZiAoQkJBICE9IEJCQikgcmV0dXJuIERULT5kb21pbmF0ZXMoQkJBLCBCQkIpOworCisgICAgLy8gTG9vcCB0aHJvdWdoIHRoZSBiYXNpYyBibG9jayB1bnRpbCB3ZSBmaW5kIEEgb3IgQi4KKyAgICBNYWNoaW5lQmFzaWNCbG9jazo6Y29uc3RfaXRlcmF0b3IgSSA9IEJCQS0+YmVnaW4oKTsKKyAgICBmb3IgKDsgJipJICE9IEEgJiYgJipJICE9IEI7ICsrSSkKKyAgICAgIC8qZW1wdHkqLyA7CisKKyAgICAvL2lmKCFEVC5Jc1Bvc3REb21pbmF0b3JzKSB7CisgICAgICAvLyBBIGRvbWluYXRlcyBCIGlmIGl0IGlzIGZvdW5kIGZpcnN0IGluIHRoZSBiYXNpYyBibG9jay4KKyAgICAgIHJldHVybiAmKkkgPT0gQTsKKyAgICAvL30gZWxzZSB7CisgICAgLy8gIC8vIEEgcG9zdC1kb21pbmF0ZXMgQiBpZiBCIGlzIGZvdW5kIGZpcnN0IGluIHRoZSBiYXNpYyBibG9jay4KKyAgICAvLyAgcmV0dXJuICYqSSA9PSBCOworICAgIC8vfQorICB9CisKKyAgaW5saW5lIGJvb2wgcHJvcGVybHlEb21pbmF0ZXMoY29uc3QgTWFjaGluZURvbVRyZWVOb2RlKiBBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lRG9tVHJlZU5vZGUqIEIpIGNvbnN0IHsKKyAgICBhcHBseVNwbGl0Q3JpdGljYWxFZGdlcygpOworICAgIHJldHVybiBEVC0+cHJvcGVybHlEb21pbmF0ZXMoQSwgQik7CisgIH0KKworICBpbmxpbmUgYm9vbCBwcm9wZXJseURvbWluYXRlcyhjb25zdCBNYWNoaW5lQmFzaWNCbG9jayogQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sqIEIpIGNvbnN0IHsKKyAgICBhcHBseVNwbGl0Q3JpdGljYWxFZGdlcygpOworICAgIHJldHVybiBEVC0+cHJvcGVybHlEb21pbmF0ZXMoQSwgQik7CisgIH0KKworICAvLy8gZmluZE5lYXJlc3RDb21tb25Eb21pbmF0b3IgLSBGaW5kIG5lYXJlc3QgY29tbW9uIGRvbWluYXRvciBiYXNpYyBibG9jaworICAvLy8gZm9yIGJhc2ljIGJsb2NrIEEgYW5kIEIuIElmIHRoZXJlIGlzIG5vIHN1Y2ggYmxvY2sgdGhlbiByZXR1cm4gTlVMTC4KKyAgaW5saW5lIE1hY2hpbmVCYXNpY0Jsb2NrICpmaW5kTmVhcmVzdENvbW1vbkRvbWluYXRvcihNYWNoaW5lQmFzaWNCbG9jayAqQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jayAqQikgeworICAgIGFwcGx5U3BsaXRDcml0aWNhbEVkZ2VzKCk7CisgICAgcmV0dXJuIERULT5maW5kTmVhcmVzdENvbW1vbkRvbWluYXRvcihBLCBCKTsKKyAgfQorCisgIGlubGluZSBNYWNoaW5lRG9tVHJlZU5vZGUgKm9wZXJhdG9yW10oTWFjaGluZUJhc2ljQmxvY2sgKkJCKSBjb25zdCB7CisgICAgYXBwbHlTcGxpdENyaXRpY2FsRWRnZXMoKTsKKyAgICByZXR1cm4gRFQtPmdldE5vZGUoQkIpOworICB9CisKKyAgLy8vIGdldE5vZGUgLSByZXR1cm4gdGhlIChQb3N0KURvbWluYXRvclRyZWUgbm9kZSBmb3IgdGhlIHNwZWNpZmllZCBiYXNpYworICAvLy8gYmxvY2suICBUaGlzIGlzIHRoZSBzYW1lIGFzIHVzaW5nIG9wZXJhdG9yW10gb24gdGhpcyBjbGFzcy4KKyAgLy8vCisgIGlubGluZSBNYWNoaW5lRG9tVHJlZU5vZGUgKmdldE5vZGUoTWFjaGluZUJhc2ljQmxvY2sgKkJCKSBjb25zdCB7CisgICAgYXBwbHlTcGxpdENyaXRpY2FsRWRnZXMoKTsKKyAgICByZXR1cm4gRFQtPmdldE5vZGUoQkIpOworICB9CisKKyAgLy8vIGFkZE5ld0Jsb2NrIC0gQWRkIGEgbmV3IG5vZGUgdG8gdGhlIGRvbWluYXRvciB0cmVlIGluZm9ybWF0aW9uLiAgVGhpcworICAvLy8gY3JlYXRlcyBhIG5ldyBub2RlIGFzIGEgY2hpbGQgb2YgRG9tQkIgZG9taW5hdG9yIG5vZGUsbGlua2luZyBpdCBpbnRvCisgIC8vLyB0aGUgY2hpbGRyZW4gbGlzdCBvZiB0aGUgaW1tZWRpYXRlIGRvbWluYXRvci4KKyAgaW5saW5lIE1hY2hpbmVEb21UcmVlTm9kZSAqYWRkTmV3QmxvY2soTWFjaGluZUJhc2ljQmxvY2sgKkJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jayAqRG9tQkIpIHsKKyAgICBhcHBseVNwbGl0Q3JpdGljYWxFZGdlcygpOworICAgIHJldHVybiBEVC0+YWRkTmV3QmxvY2soQkIsIERvbUJCKTsKKyAgfQorCisgIC8vLyBjaGFuZ2VJbW1lZGlhdGVEb21pbmF0b3IgLSBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIHVwZGF0ZSB0aGUgZG9taW5hdG9yCisgIC8vLyB0cmVlIGluZm9ybWF0aW9uIHdoZW4gYSBub2RlJ3MgaW1tZWRpYXRlIGRvbWluYXRvciBjaGFuZ2VzLgorICAvLy8KKyAgaW5saW5lIHZvaWQgY2hhbmdlSW1tZWRpYXRlRG9taW5hdG9yKE1hY2hpbmVCYXNpY0Jsb2NrICpOLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2sqIE5ld0lEb20pIHsKKyAgICBhcHBseVNwbGl0Q3JpdGljYWxFZGdlcygpOworICAgIERULT5jaGFuZ2VJbW1lZGlhdGVEb21pbmF0b3IoTiwgTmV3SURvbSk7CisgIH0KKworICBpbmxpbmUgdm9pZCBjaGFuZ2VJbW1lZGlhdGVEb21pbmF0b3IoTWFjaGluZURvbVRyZWVOb2RlICpOLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZURvbVRyZWVOb2RlKiBOZXdJRG9tKSB7CisgICAgYXBwbHlTcGxpdENyaXRpY2FsRWRnZXMoKTsKKyAgICBEVC0+Y2hhbmdlSW1tZWRpYXRlRG9taW5hdG9yKE4sIE5ld0lEb20pOworICB9CisKKyAgLy8vIGVyYXNlTm9kZSAtIFJlbW92ZXMgYSBub2RlIGZyb20gIHRoZSBkb21pbmF0b3IgdHJlZS4gQmxvY2sgbXVzdCBub3QKKyAgLy8vIGRvbWluYXRlIGFueSBvdGhlciBibG9ja3MuIFJlbW92ZXMgbm9kZSBmcm9tIGl0cyBpbW1lZGlhdGUgZG9taW5hdG9yJ3MKKyAgLy8vIGNoaWxkcmVuIGxpc3QuIERlbGV0ZXMgZG9taW5hdG9yIG5vZGUgYXNzb2NpYXRlZCB3aXRoIGJhc2ljIGJsb2NrIEJCLgorICBpbmxpbmUgdm9pZCBlcmFzZU5vZGUoTWFjaGluZUJhc2ljQmxvY2sgKkJCKSB7CisgICAgYXBwbHlTcGxpdENyaXRpY2FsRWRnZXMoKTsKKyAgICBEVC0+ZXJhc2VOb2RlKEJCKTsKKyAgfQorCisgIC8vLyBzcGxpdEJsb2NrIC0gQkIgaXMgc3BsaXQgYW5kIG5vdyBpdCBoYXMgb25lIHN1Y2Nlc3Nvci4gVXBkYXRlIGRvbWluYXRvcgorICAvLy8gdHJlZSB0byByZWZsZWN0IHRoaXMgY2hhbmdlLgorICBpbmxpbmUgdm9pZCBzcGxpdEJsb2NrKE1hY2hpbmVCYXNpY0Jsb2NrKiBOZXdCQikgeworICAgIGFwcGx5U3BsaXRDcml0aWNhbEVkZ2VzKCk7CisgICAgRFQtPnNwbGl0QmxvY2soTmV3QkIpOworICB9CisKKyAgLy8vIGlzUmVhY2hhYmxlRnJvbUVudHJ5IC0gUmV0dXJuIHRydWUgaWYgQSBpcyBkb21pbmF0ZWQgYnkgdGhlIGVudHJ5CisgIC8vLyBibG9jayBvZiB0aGUgZnVuY3Rpb24gY29udGFpbmluZyBpdC4KKyAgYm9vbCBpc1JlYWNoYWJsZUZyb21FbnRyeShjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqQSkgeworICAgIGFwcGx5U3BsaXRDcml0aWNhbEVkZ2VzKCk7CisgICAgcmV0dXJuIERULT5pc1JlYWNoYWJsZUZyb21FbnRyeShBKTsKKyAgfQorCisgIHZvaWQgcmVsZWFzZU1lbW9yeSgpIG92ZXJyaWRlOworCisgIHZvaWQgdmVyaWZ5QW5hbHlzaXMoKSBjb25zdCBvdmVycmlkZTsKKworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUywgY29uc3QgTW9kdWxlKikgY29uc3Qgb3ZlcnJpZGU7CisKKyAgLy8vIFxicmllZiBSZWNvcmQgdGhhdCB0aGUgY3JpdGljYWwgZWRnZSAoRnJvbUJCLCBUb0JCKSBoYXMgYmVlbgorICAvLy8gc3BsaXQgd2l0aCBOZXdCQi4KKyAgLy8vIFRoaXMgaXMgYmVzdCB0byB1c2UgdGhpcyBtZXRob2QgaW5zdGVhZCBvZiBkaXJlY3RseSB1cGRhdGUgdGhlCisgIC8vLyB1bmRlcmx5aW5nIGluZm9ybWF0aW9uLCBiZWNhdXNlIHRoaXMgaGVscHMgbWl0aWdhdGluZyB0aGUKKyAgLy8vIG51bWJlciBvZiB0aW1lIHRoZSBEVCBpbmZvcm1hdGlvbiBpcyBpbnZhbGlkYXRlZC4KKyAgLy8vCisgIC8vLyBcbm90ZSBEbyBub3QgdXNlIHRoaXMgbWV0aG9kIHdpdGggcmVndWxhciBlZGdlcy4KKyAgLy8vCisgIC8vLyBcbm90ZSBUbyBiZW5lZml0IGZyb20gdGhlIGNvbXBpbGUgdGltZSBpbXByb3ZlbWVudCBpbmN1cnJlZCBieSB0aGlzCisgIC8vLyBtZXRob2QsIHRoZSB1c2VycyBvZiB0aGlzIG1ldGhvZCBoYXZlIHRvIGxpbWl0IHRoZSBxdWVyaWVzIHRvIHRoZSBEVAorICAvLy8gaW50ZXJmYWNlIGJldHdlZW4gdHdvIGVkZ2VzIHNwbGl0dGluZy4gSW4gb3RoZXIgd29yZHMsIHRoZXkgaGF2ZSB0bworICAvLy8gcGFjayB0aGUgc3BsaXR0aW5nIG9mIGNyaXRpY2FsIGVkZ2VzIGFzIG11Y2ggYXMgcG9zc2libGUuCisgIHZvaWQgcmVjb3JkU3BsaXRDcml0aWNhbEVkZ2UoTWFjaGluZUJhc2ljQmxvY2sgKkZyb21CQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpUb0JCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2sgKk5ld0JCKSB7CisgICAgYm9vbCBJbnNlcnRlZCA9IE5ld0JCcy5pbnNlcnQoTmV3QkIpLnNlY29uZDsKKyAgICAodm9pZClJbnNlcnRlZDsKKyAgICBhc3NlcnQoSW5zZXJ0ZWQgJiYKKyAgICAgICAgICAgIkEgYmFzaWMgYmxvY2sgaW5zZXJ0ZWQgdmlhIGVkZ2Ugc3BsaXR0aW5nIGNhbm5vdCBhcHBlYXIgdHdpY2UiKTsKKyAgICBDcml0aWNhbEVkZ2VzVG9TcGxpdC5wdXNoX2JhY2soe0Zyb21CQiwgVG9CQiwgTmV3QkJ9KTsKKyAgfQorfTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLy8gRG9taW5hdG9yVHJlZSBHcmFwaFRyYWl0cyBzcGVjaWFsaXphdGlvbiBzbyB0aGUgRG9taW5hdG9yVHJlZSBjYW4gYmUKKy8vLyBpdGVyYWJsZSBieSBnZW5lcmljIGdyYXBoIGl0ZXJhdG9ycy4KKy8vLworCit0ZW1wbGF0ZSA8Y2xhc3MgTm9kZSwgY2xhc3MgQ2hpbGRJdGVyYXRvcj4KK3N0cnVjdCBNYWNoaW5lRG9tVHJlZUdyYXBoVHJhaXRzQmFzZSB7CisgIHVzaW5nIE5vZGVSZWYgPSBOb2RlICo7CisgIHVzaW5nIENoaWxkSXRlcmF0b3JUeXBlID0gQ2hpbGRJdGVyYXRvcjsKKworICBzdGF0aWMgTm9kZVJlZiBnZXRFbnRyeU5vZGUoTm9kZVJlZiBOKSB7IHJldHVybiBOOyB9CisgIHN0YXRpYyBDaGlsZEl0ZXJhdG9yVHlwZSBjaGlsZF9iZWdpbihOb2RlUmVmIE4pIHsgcmV0dXJuIE4tPmJlZ2luKCk7IH0KKyAgc3RhdGljIENoaWxkSXRlcmF0b3JUeXBlIGNoaWxkX2VuZChOb2RlUmVmIE4pIHsgcmV0dXJuIE4tPmVuZCgpOyB9Cit9OworCit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IEdyYXBoVHJhaXRzOworCit0ZW1wbGF0ZSA8Pgorc3RydWN0IEdyYXBoVHJhaXRzPE1hY2hpbmVEb21UcmVlTm9kZSAqPgorICAgIDogcHVibGljIE1hY2hpbmVEb21UcmVlR3JhcGhUcmFpdHNCYXNlPE1hY2hpbmVEb21UcmVlTm9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lRG9tVHJlZU5vZGU6Oml0ZXJhdG9yPiB7fTsKKwordGVtcGxhdGUgPD4KK3N0cnVjdCBHcmFwaFRyYWl0czxjb25zdCBNYWNoaW5lRG9tVHJlZU5vZGUgKj4KKyAgICA6IHB1YmxpYyBNYWNoaW5lRG9tVHJlZUdyYXBoVHJhaXRzQmFzZTxjb25zdCBNYWNoaW5lRG9tVHJlZU5vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZURvbVRyZWVOb2RlOjpjb25zdF9pdGVyYXRvcj4geworfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IEdyYXBoVHJhaXRzPE1hY2hpbmVEb21pbmF0b3JUcmVlKj4KKyAgOiBwdWJsaWMgR3JhcGhUcmFpdHM8TWFjaGluZURvbVRyZWVOb2RlICo+IHsKKyAgc3RhdGljIE5vZGVSZWYgZ2V0RW50cnlOb2RlKE1hY2hpbmVEb21pbmF0b3JUcmVlICpEVCkgeworICAgIHJldHVybiBEVC0+Z2V0Um9vdE5vZGUoKTsKKyAgfQorfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9NQUNISU5FRE9NSU5BVE9SU19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUZyYW1lSW5mby5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVGcmFtZUluZm8uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mODg3NTE3Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVGcmFtZUluZm8uaApAQCAtMCwwICsxLDcyNCBAQAorLy89PT0tLSBDb2RlR2VuL01hY2hpbmVGcmFtZUluZm8uaCAtIEFic3RyYWN0IFN0YWNrIEZyYW1lIFJlcC4gLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGUgZmlsZSBkZWZpbmVzIHRoZSBNYWNoaW5lRnJhbWVJbmZvIGNsYXNzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ0hJTkVGUkFNRUlORk9fSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTUFDSElORUZSQU1FSU5GT19ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9EYXRhVHlwZXMuaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGxsdm0geworY2xhc3MgcmF3X29zdHJlYW07CitjbGFzcyBNYWNoaW5lRnVuY3Rpb247CitjbGFzcyBNYWNoaW5lQmFzaWNCbG9jazsKK2NsYXNzIEJpdFZlY3RvcjsKK2NsYXNzIEFsbG9jYUluc3Q7CisKKy8vLyBUaGUgQ2FsbGVlU2F2ZWRJbmZvIGNsYXNzIHRyYWNrcyB0aGUgaW5mb3JtYXRpb24gbmVlZCB0byBsb2NhdGUgd2hlcmUgYQorLy8vIGNhbGxlZSBzYXZlZCByZWdpc3RlciBpcyBpbiB0aGUgY3VycmVudCBmcmFtZS4KK2NsYXNzIENhbGxlZVNhdmVkSW5mbyB7CisgIHVuc2lnbmVkIFJlZzsKKyAgaW50IEZyYW1lSWR4OworICAvLy8gRmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHJlZ2lzdGVyIGlzIGFjdHVhbGx5IHJlc3RvcmVkIGluIHRoZSBlcGlsb2cuCisgIC8vLyBJbiBtb3N0IGNhc2VzLCBpZiBhIHJlZ2lzdGVyIGlzIHNhdmVkLCBpdCBpcyBhbHNvIHJlc3RvcmVkLiBUaGVyZSBhcmUKKyAgLy8vIHNvbWUgc2l0dWF0aW9ucywgdGhvdWdoLCB3aGVuIHRoaXMgaXMgbm90IHRoZSBjYXNlLiBGb3IgZXhhbXBsZSwgdGhlCisgIC8vLyBMUiByZWdpc3RlciBvbiBBUk0gaXMgdXN1YWxseSBzYXZlZCwgYnV0IG9uIGV4aXQgZnJvbSB0aGUgZnVuY3Rpb24gaXRzCisgIC8vLyBzYXZlZCB2YWx1ZSBtYXkgYmUgbG9hZGVkIGRpcmVjdGx5IGludG8gUEMuIFNpbmNlIGxpdmVuZXNzIHRyYWNraW5nIG9mCisgIC8vLyBwaHlzaWNhbCByZWdpc3RlcnMgdHJlYXRzIGNhbGxlZS1zYXZlZCByZWdpc3RlcnMgYXJlIGxpdmUgb3V0c2lkZSBvZgorICAvLy8gdGhlIGZ1bmN0aW9uLCBMUiB3b3VsZCBiZSB0cmVhdGVkIGFzIGxpdmUtb24tZXhpdCwgZXZlbiB0aG91Z2ggaW4gdGhlc2UKKyAgLy8vIHNjZW5hcmlvcyBpdCBpcyBub3QuIFRoaXMgZmxhZyBpcyBhZGRlZCB0byBpbmRpY2F0ZSB0aGF0IHRoZSBzYXZlZAorICAvLy8gcmVnaXN0ZXIgZGVzY3JpYmVkIGJ5IHRoaXMgb2JqZWN0IGlzIG5vdCByZXN0b3JlZCBpbiB0aGUgZXBpbG9nLgorICAvLy8gVGhlIGxvbmctdGVybSBzb2x1dGlvbiBpcyB0byBtb2RlbCB0aGUgbGl2ZW5lc3Mgb2YgY2FsbGVlLXNhdmVkIHJlZ2lzdGVycworICAvLy8gYnkgaW1wbGljaXQgdXNlcyBvbiB0aGUgcmV0dXJuIGluc3RydWN0aW9ucywgaG93ZXZlciwgdGhlIHJlcXVpcmVkCisgIC8vLyBjaGFuZ2VzIGluIHRoZSBBUk0gYmFja2VuZCB3b3VsZCBiZSBxdWl0ZSBleHRlbnNpdmUuCisgIGJvb2wgUmVzdG9yZWQ7CisKK3B1YmxpYzoKKyAgZXhwbGljaXQgQ2FsbGVlU2F2ZWRJbmZvKHVuc2lnbmVkIFIsIGludCBGSSA9IDApCisgIDogUmVnKFIpLCBGcmFtZUlkeChGSSksIFJlc3RvcmVkKHRydWUpIHt9CisKKyAgLy8gQWNjZXNzb3JzLgorICB1bnNpZ25lZCBnZXRSZWcoKSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgcmV0dXJuIFJlZzsgfQorICBpbnQgZ2V0RnJhbWVJZHgoKSAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgcmV0dXJuIEZyYW1lSWR4OyB9CisgIHZvaWQgc2V0RnJhbWVJZHgoaW50IEZJKSAgICAgICAgICAgICAgICAgICAgICAgeyBGcmFtZUlkeCA9IEZJOyB9CisgIGJvb2wgaXNSZXN0b3JlZCgpICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyByZXR1cm4gUmVzdG9yZWQ7IH0KKyAgdm9pZCBzZXRSZXN0b3JlZChib29sIFIpICAgICAgICAgICAgICAgICAgICAgICB7IFJlc3RvcmVkID0gUjsgfQorfTsKKworLy8vIFRoZSBNYWNoaW5lRnJhbWVJbmZvIGNsYXNzIHJlcHJlc2VudHMgYW4gYWJzdHJhY3Qgc3RhY2sgZnJhbWUgdW50aWwKKy8vLyBwcm9sb2cvZXBpbG9nIGNvZGUgaXMgaW5zZXJ0ZWQuICBUaGlzIGNsYXNzIGlzIGtleSB0byBhbGxvd2luZyBzdGFjayBmcmFtZQorLy8vIHJlcHJlc2VudGF0aW9uIG9wdGltaXphdGlvbnMsIHN1Y2ggYXMgZnJhbWUgcG9pbnRlciBlbGltaW5hdGlvbi4gIEl0IGFsc28KKy8vLyBhbGxvd3MgbW9yZSBtdW5kYW5lIChidXQgc3RpbGwgaW1wb3J0YW50KSBvcHRpbWl6YXRpb25zLCBzdWNoIGFzIHJlb3JkZXJpbmcKKy8vLyBvZiBhYnN0cmFjdCBvYmplY3RzIG9uIHRoZSBzdGFjayBmcmFtZS4KKy8vLworLy8vIFRvIHN1cHBvcnQgdGhpcywgdGhlIGNsYXNzIGFzc2lnbnMgdW5pcXVlIGludGVnZXIgaWRlbnRpZmllcnMgdG8gc3RhY2sKKy8vLyBvYmplY3RzIHJlcXVlc3RlZCBjbGllbnRzLiAgVGhlc2UgaWRlbnRpZmllcnMgYXJlIG5lZ2F0aXZlIGludGVnZXJzIGZvcgorLy8vIGZpeGVkIHN0YWNrIG9iamVjdHMgKHN1Y2ggYXMgYXJndW1lbnRzIHBhc3NlZCBvbiB0aGUgc3RhY2spIG9yIG5vbm5lZ2F0aXZlCisvLy8gZm9yIG9iamVjdHMgdGhhdCBtYXkgYmUgcmVvcmRlcmVkLiAgSW5zdHJ1Y3Rpb25zIHdoaWNoIHJlZmVyIHRvIHN0YWNrCisvLy8gb2JqZWN0cyB1c2UgYSBzcGVjaWFsIE1PX0ZyYW1lSW5kZXggb3BlcmFuZCB0byByZXByZXNlbnQgdGhlc2UgZnJhbWUKKy8vLyBpbmRleGVzLgorLy8vCisvLy8gQmVjYXVzZSB0aGlzIGNsYXNzIGtlZXBzIHRyYWNrIG9mIGFsbCByZWZlcmVuY2VzIHRvIHRoZSBzdGFjayBmcmFtZSwgaXQKKy8vLyBrbm93cyB3aGVuIGEgdmFyaWFibGUgc2l6ZWQgb2JqZWN0IGlzIGFsbG9jYXRlZCBvbiB0aGUgc3RhY2suICBUaGlzIGlzIHRoZQorLy8vIHNvbGUgY29uZGl0aW9uIHdoaWNoIHByZXZlbnRzIGZyYW1lIHBvaW50ZXIgZWxpbWluYXRpb24sIHdoaWNoIGlzIGFuCisvLy8gaW1wb3J0YW50IG9wdGltaXphdGlvbiBvbiByZWdpc3Rlci1wb29yIGFyY2hpdGVjdHVyZXMuICBCZWNhdXNlIG9yaWdpbmFsCisvLy8gdmFyaWFibGUgc2l6ZWQgYWxsb2NhJ3MgaW4gdGhlIHNvdXJjZSBwcm9ncmFtIGFyZSB0aGUgb25seSBzb3VyY2Ugb2YKKy8vLyB2YXJpYWJsZSBzaXplZCBzdGFjayBvYmplY3RzLCBpdCBpcyBzYWZlIHRvIGRlY2lkZSB3aGV0aGVyIHRoZXJlIHdpbGwgYmUKKy8vLyBhbnkgdmFyaWFibGUgc2l6ZWQgb2JqZWN0cyBiZWZvcmUgYWxsIHN0YWNrIG9iamVjdHMgYXJlIGtub3duIChmb3IKKy8vLyBleGFtcGxlLCByZWdpc3RlciBhbGxvY2F0b3Igc3BpbGwgY29kZSBuZXZlciBuZWVkcyB2YXJpYWJsZSBzaXplZAorLy8vIG9iamVjdHMpLgorLy8vCisvLy8gV2hlbiBwcm9sb2cvZXBpbG9nIGNvZGUgZW1pc3Npb24gaXMgcGVyZm9ybWVkLCB0aGUgZmluYWwgc3RhY2sgZnJhbWUgaXMKKy8vLyBidWlsdCBhbmQgdGhlIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zIGFyZSBtb2RpZmllZCB0byByZWZlciB0byB0aGUgYWN0dWFsCisvLy8gc3RhY2sgb2Zmc2V0cyBvZiB0aGUgb2JqZWN0LCBlbGltaW5hdGluZyBhbGwgTU9fRnJhbWVJbmRleCBvcGVyYW5kcyBmcm9tCisvLy8gdGhlIHByb2dyYW0uCisvLy8KKy8vLyBAYnJpZWYgQWJzdHJhY3QgU3RhY2sgRnJhbWUgSW5mb3JtYXRpb24KK2NsYXNzIE1hY2hpbmVGcmFtZUluZm8geworCisgIC8vIFJlcHJlc2VudCBhIHNpbmdsZSBvYmplY3QgYWxsb2NhdGVkIG9uIHRoZSBzdGFjay4KKyAgc3RydWN0IFN0YWNrT2JqZWN0IHsKKyAgICAvLyBUaGUgb2Zmc2V0IG9mIHRoaXMgb2JqZWN0IGZyb20gdGhlIHN0YWNrIHBvaW50ZXIgb24gZW50cnkgdG8KKyAgICAvLyB0aGUgZnVuY3Rpb24uICBUaGlzIGZpZWxkIGhhcyBubyBtZWFuaW5nIGZvciBhIHZhcmlhYmxlIHNpemVkIGVsZW1lbnQuCisgICAgaW50NjRfdCBTUE9mZnNldDsKKworICAgIC8vIFRoZSBzaXplIG9mIHRoaXMgb2JqZWN0IG9uIHRoZSBzdGFjay4gMCBtZWFucyBhIHZhcmlhYmxlIHNpemVkIG9iamVjdCwKKyAgICAvLyB+MFVMTCBtZWFucyBhIGRlYWQgb2JqZWN0LgorICAgIHVpbnQ2NF90IFNpemU7CisKKyAgICAvLyBUaGUgcmVxdWlyZWQgYWxpZ25tZW50IG9mIHRoaXMgc3RhY2sgc2xvdC4KKyAgICB1bnNpZ25lZCBBbGlnbm1lbnQ7CisKKyAgICAvLyBJZiB0cnVlLCB0aGUgdmFsdWUgb2YgdGhlIHN0YWNrIG9iamVjdCBpcyBzZXQgYmVmb3JlCisgICAgLy8gZW50ZXJpbmcgdGhlIGZ1bmN0aW9uIGFuZCBpcyBub3QgbW9kaWZpZWQgaW5zaWRlIHRoZSBmdW5jdGlvbi4gQnkKKyAgICAvLyBkZWZhdWx0LCBmaXhlZCBvYmplY3RzIGFyZSBpbW11dGFibGUgdW5sZXNzIG1hcmtlZCBvdGhlcndpc2UuCisgICAgYm9vbCBpc0ltbXV0YWJsZTsKKworICAgIC8vIElmIHRydWUgdGhlIHN0YWNrIG9iamVjdCBpcyB1c2VkIGFzIHNwaWxsIHNsb3QuIEl0CisgICAgLy8gY2Fubm90IGFsaWFzIGFueSBvdGhlciBtZW1vcnkgb2JqZWN0cy4KKyAgICBib29sIGlzU3BpbGxTbG90OworCisgICAgLy8vIElmIHRydWUsIHRoaXMgc3RhY2sgc2xvdCBpcyB1c2VkIHRvIHNwaWxsIGEgdmFsdWUgKGNvdWxkIGJlIGRlb3B0CisgICAgLy8vIGFuZC9vciBHQyByZWxhdGVkKSBvdmVyIGEgc3RhdGVwb2ludC4gV2Uga25vdyB0aGF0IHRoZSBhZGRyZXNzIG9mIHRoZQorICAgIC8vLyBzbG90IGNhbid0IGFsaWFzIGFueSBMTFZNIElSIHZhbHVlLiAgVGhpcyBpcyB2ZXJ5IHNpbWlsYXIgdG8gYSBTcGlsbAorICAgIC8vLyBTbG90LCBidXQgaXMgY3JlYXRlZCBieSBzdGF0ZXBvaW50IGxvd2VyaW5nIGlzIFNlbGVjdGlvbkRBRywgbm90IHRoZQorICAgIC8vLyByZWdpc3RlciBhbGxvY2F0b3IuCisgICAgYm9vbCBpc1N0YXRlcG9pbnRTcGlsbFNsb3QgPSBmYWxzZTsKKworICAgIC8vLyBJZGVudGlmaWVyIGZvciBzdGFjayBtZW1vcnkgdHlwZSBhbmFsYWdvdXMgdG8gYWRkcmVzcyBzcGFjZS4gSWYgdGhpcyBpcworICAgIC8vLyBub24tMCwgdGhlIG1lYW5pbmcgaXMgdGFyZ2V0IGRlZmluZWQuIE9mZnNldHMgY2Fubm90IGJlIGRpcmVjdGx5CisgICAgLy8vIGNvbXBhcmVkIGJldHdlZW4gb2JqZWN0cyB3aXRoIGRpZmZlcmVudCBzdGFjayBJRHMuIFRoZSBvYmplY3QgbWF5IG5vdAorICAgIC8vLyBuZWNlc3NhcmlseSByZXNpZGUgaW4gdGhlIHNhbWUgY29udGlndW91cyBtZW1vcnkgYmxvY2sgYXMgb3RoZXIgc3RhY2sKKyAgICAvLy8gb2JqZWN0cy4gT2JqZWN0cyB3aXRoIGRpZmZlcmluZyBzdGFjayBJRHMgc2hvdWxkIG5vdCBiZSBtZXJnZWQgb3IKKyAgICAvLy8gcmVwbGFjZWQgc3Vic3RpdHV0ZWQgZm9yIGVhY2ggb3RoZXIuCisgICAgdWludDhfdCBTdGFja0lEOworCisgICAgLy8vIElmIHRoaXMgc3RhY2sgb2JqZWN0IGlzIG9yaWdpbmF0ZWQgZnJvbSBhbiBBbGxvY2EgaW5zdHJ1Y3Rpb24KKyAgICAvLy8gdGhpcyB2YWx1ZSBzYXZlcyB0aGUgb3JpZ2luYWwgSVIgYWxsb2NhdGlvbi4gQ2FuIGJlIE5VTEwuCisgICAgY29uc3QgQWxsb2NhSW5zdCAqQWxsb2NhOworCisgICAgLy8gSWYgdHJ1ZSwgdGhlIG9iamVjdCB3YXMgbWFwcGVkIGludG8gdGhlIGxvY2FsIGZyYW1lCisgICAgLy8gYmxvY2sgYW5kIGRvZXNuJ3QgbmVlZCBhZGRpdGlvbmFsIGhhbmRsaW5nIGZvciBhbGxvY2F0aW9uIGJleW9uZCB0aGF0LgorICAgIGJvb2wgUHJlQWxsb2NhdGVkID0gZmFsc2U7CisKKyAgICAvLyBJZiB0cnVlLCBhbiBMTFZNIElSIHZhbHVlIG1pZ2h0IHBvaW50IHRvIHRoaXMgb2JqZWN0LgorICAgIC8vIE5vcm1hbGx5LCBzcGlsbCBzbG90cyBhbmQgZml4ZWQtb2Zmc2V0IG9iamVjdHMgZG9uJ3QgYWxpYXMgSVItYWNjZXNzaWJsZQorICAgIC8vIG9iamVjdHMsIGJ1dCB0aGVyZSBhcmUgZXhjZXB0aW9ucyAob24gUG93ZXJQQywgZm9yIGV4YW1wbGUsIHNvbWUgYnl2YWwKKyAgICAvLyBhcmd1bWVudHMgaGF2ZSBBQkktcHJlc2NyaWJlZCBvZmZzZXRzKS4KKyAgICBib29sIGlzQWxpYXNlZDsKKworICAgIC8vLyBJZiB0cnVlLCB0aGUgb2JqZWN0IGhhcyBiZWVuIHplcm8tZXh0ZW5kZWQuCisgICAgYm9vbCBpc1pFeHQgPSBmYWxzZTsKKworICAgIC8vLyBJZiB0cnVlLCB0aGUgb2JqZWN0IGhhcyBiZWVuIHplcm8tZXh0ZW5kZWQuCisgICAgYm9vbCBpc1NFeHQgPSBmYWxzZTsKKworICAgIFN0YWNrT2JqZWN0KHVpbnQ2NF90IFNpemUsIHVuc2lnbmVkIEFsaWdubWVudCwgaW50NjRfdCBTUE9mZnNldCwKKyAgICAgICAgICAgICAgICBib29sIElzSW1tdXRhYmxlLCBib29sIElzU3BpbGxTbG90LCBjb25zdCBBbGxvY2FJbnN0ICpBbGxvY2EsCisgICAgICAgICAgICAgICAgYm9vbCBJc0FsaWFzZWQsIHVpbnQ4X3QgU3RhY2tJRCA9IDApCisgICAgICA6IFNQT2Zmc2V0KFNQT2Zmc2V0KSwgU2l6ZShTaXplKSwgQWxpZ25tZW50KEFsaWdubWVudCksCisgICAgICAgIGlzSW1tdXRhYmxlKElzSW1tdXRhYmxlKSwgaXNTcGlsbFNsb3QoSXNTcGlsbFNsb3QpLAorICAgICAgICBTdGFja0lEKFN0YWNrSUQpLCBBbGxvY2EoQWxsb2NhKSwgaXNBbGlhc2VkKElzQWxpYXNlZCkge30KKyAgfTsKKworICAvLy8gVGhlIGFsaWdubWVudCBvZiB0aGUgc3RhY2suCisgIHVuc2lnbmVkIFN0YWNrQWxpZ25tZW50OworCisgIC8vLyBDYW4gdGhlIHN0YWNrIGJlIHJlYWxpZ25lZC4gVGhpcyBjYW4gYmUgZmFsc2UgaWYgdGhlIHRhcmdldCBkb2VzIG5vdAorICAvLy8gc3VwcG9ydCBzdGFjayByZWFsaWdubWVudCwgb3IgaWYgdGhlIHVzZXIgYXNrcyB1cyBub3QgdG8gcmVhbGlnbiB0aGUKKyAgLy8vIHN0YWNrLiBJbiB0aGlzIHNpdHVhdGlvbiwgb3ZlcmFsaWduZWQgYWxsb2NhcyBhcmUgYWxsIHRyZWF0ZWQgYXMgZHluYW1pYworICAvLy8gYWxsb2NhdGlvbnMgYW5kIHRoZSB0YXJnZXQgbXVzdCBoYW5kbGUgdGhlbSBhcyBwYXJ0IG9mIERZTkFNSUNfU1RBQ0tBTExPQworICAvLy8gbG93ZXJpbmcuIEFsbCBub24tYWxsb2NhIHN0YWNrIG9iamVjdHMgaGF2ZSB0aGVpciBhbGlnbm1lbnQgY2xhbXBlZCB0byB0aGUKKyAgLy8vIGJhc2UgQUJJIHN0YWNrIGFsaWdubWVudC4KKyAgLy8vIEZJWE1FOiBUaGVyZSBpcyByb29tIGZvciBpbXByb3ZlbWVudCBpbiB0aGlzIGNhc2UsIGluIHRlcm1zIG9mCisgIC8vLyBncm91cGluZyBvdmVyYWxpZ25lZCBhbGxvY2FzIGludG8gYSAic2Vjb25kYXJ5IHN0YWNrIGZyYW1lIiBhbmQKKyAgLy8vIHRoZW4gb25seSB1c2UgYSBzaW5nbGUgYWxsb2NhIHRvIGFsbG9jYXRlIHRoaXMgZnJhbWUgYW5kIG9ubHkgYQorICAvLy8gc2luZ2xlIHZpcnR1YWwgcmVnaXN0ZXIgdG8gYWNjZXNzIGl0LiBDdXJyZW50bHksIHdpdGhvdXQgc3VjaCBhbgorICAvLy8gb3B0aW1pemF0aW9uLCBlYWNoIHN1Y2ggYWxsb2NhIGdldHMgaXRzIG93biBkeW5hbWljIHJlYWxpZ25tZW50LgorICBib29sIFN0YWNrUmVhbGlnbmFibGU7CisKKyAgLy8vIFdoZXRoZXIgdGhlIGZ1bmN0aW9uIGhhcyB0aGUgXGMgYWxpZ25zdGFjayBhdHRyaWJ1dGUuCisgIGJvb2wgRm9yY2VkUmVhbGlnbjsKKworICAvLy8gVGhlIGxpc3Qgb2Ygc3RhY2sgb2JqZWN0cyBhbGxvY2F0ZWQuCisgIHN0ZDo6dmVjdG9yPFN0YWNrT2JqZWN0PiBPYmplY3RzOworCisgIC8vLyBUaGlzIGNvbnRhaW5zIHRoZSBudW1iZXIgb2YgZml4ZWQgb2JqZWN0cyBjb250YWluZWQgb24KKyAgLy8vIHRoZSBzdGFjay4gIEJlY2F1c2UgZml4ZWQgb2JqZWN0cyBhcmUgc3RvcmVkIGF0IGEgbmVnYXRpdmUgaW5kZXggaW4gdGhlCisgIC8vLyBPYmplY3RzIGxpc3QsIHRoaXMgaXMgYWxzbyB0aGUgaW5kZXggdG8gdGhlIDB0aCBvYmplY3QgaW4gdGhlIGxpc3QuCisgIHVuc2lnbmVkIE51bUZpeGVkT2JqZWN0cyA9IDA7CisKKyAgLy8vIFRoaXMgYm9vbGVhbiBrZWVwcyB0cmFjayBvZiB3aGV0aGVyIGFueSB2YXJpYWJsZQorICAvLy8gc2l6ZWQgb2JqZWN0cyBoYXZlIGJlZW4gYWxsb2NhdGVkIHlldC4KKyAgYm9vbCBIYXNWYXJTaXplZE9iamVjdHMgPSBmYWxzZTsKKworICAvLy8gVGhpcyBib29sZWFuIGtlZXBzIHRyYWNrIG9mIHdoZXRoZXIgdGhlcmUgaXMgYSBjYWxsCisgIC8vLyB0byBidWlsdGluIFxAbGx2bS5mcmFtZWFkZHJlc3MuCisgIGJvb2wgRnJhbWVBZGRyZXNzVGFrZW4gPSBmYWxzZTsKKworICAvLy8gVGhpcyBib29sZWFuIGtlZXBzIHRyYWNrIG9mIHdoZXRoZXIgdGhlcmUgaXMgYSBjYWxsCisgIC8vLyB0byBidWlsdGluIFxAbGx2bS5yZXR1cm5hZGRyZXNzLgorICBib29sIFJldHVybkFkZHJlc3NUYWtlbiA9IGZhbHNlOworCisgIC8vLyBUaGlzIGJvb2xlYW4ga2VlcHMgdHJhY2sgb2Ygd2hldGhlciB0aGVyZSBpcyBhIGNhbGwKKyAgLy8vIHRvIGJ1aWx0aW4gXEBsbHZtLmV4cGVyaW1lbnRhbC5zdGFja21hcC4KKyAgYm9vbCBIYXNTdGFja01hcCA9IGZhbHNlOworCisgIC8vLyBUaGlzIGJvb2xlYW4ga2VlcHMgdHJhY2sgb2Ygd2hldGhlciB0aGVyZSBpcyBhIGNhbGwKKyAgLy8vIHRvIGJ1aWx0aW4gXEBsbHZtLmV4cGVyaW1lbnRhbC5wYXRjaHBvaW50LgorICBib29sIEhhc1BhdGNoUG9pbnQgPSBmYWxzZTsKKworICAvLy8gVGhlIHByb2xvZy9lcGlsb2cgY29kZSBpbnNlcnRlciBjYWxjdWxhdGVzIHRoZSBmaW5hbCBzdGFjaworICAvLy8gb2Zmc2V0cyBmb3IgYWxsIG9mIHRoZSBmaXhlZCBzaXplIG9iamVjdHMsIHVwZGF0aW5nIHRoZSBPYmplY3RzIGxpc3QKKyAgLy8vIGFib3ZlLiAgSXQgdGhlbiB1cGRhdGVzIFN0YWNrU2l6ZSB0byBjb250YWluIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBuZWVkCisgIC8vLyB0byBiZSBhbGxvY2F0ZWQgb24gZW50cnkgdG8gdGhlIGZ1bmN0aW9uLgorICB1aW50NjRfdCBTdGFja1NpemUgPSAwOworCisgIC8vLyBUaGUgYW1vdW50IHRoYXQgYSBmcmFtZSBvZmZzZXQgbmVlZHMgdG8gYmUgYWRqdXN0ZWQgdG8KKyAgLy8vIGhhdmUgdGhlIGFjdHVhbCBvZmZzZXQgZnJvbSB0aGUgc3RhY2svZnJhbWUgcG9pbnRlci4gIFRoZSBleGFjdCB1c2FnZSBvZgorICAvLy8gdGhpcyBpcyB0YXJnZXQtZGVwZW5kZW50LCBidXQgaXQgaXMgdHlwaWNhbGx5IHVzZWQgdG8gYWRqdXN0IGJldHdlZW4KKyAgLy8vIFNQLXJlbGF0aXZlIGFuZCBGUC1yZWxhdGl2ZSBvZmZzZXRzLiAgRS5HLiwgaWYgb2JqZWN0cyBhcmUgYWNjZXNzZWQgdmlhCisgIC8vLyBTUCB0aGVuIE9mZnNldEFkanVzdG1lbnQgaXMgemVybzsgaWYgRlAgaXMgdXNlZCwgT2Zmc2V0QWRqdXN0bWVudCBpcyBzZXQKKyAgLy8vIHRvIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBpbml0aWFsIFNQIGFuZCB0aGUgdmFsdWUgaW4gRlAuICBGb3IgbWFueQorICAvLy8gdGFyZ2V0cywgdGhpcyB2YWx1ZSBpcyBvbmx5IHVzZWQgd2hlbiBnZW5lcmF0aW5nIGRlYnVnIGluZm8gKHZpYQorICAvLy8gVGFyZ2V0UmVnaXN0ZXJJbmZvOjpnZXRGcmFtZUluZGV4UmVmZXJlbmNlKTsgd2hlbiBnZW5lcmF0aW5nIGNvZGUsIHRoZQorICAvLy8gY29ycmVzcG9uZGluZyBhZGp1c3RtZW50cyBhcmUgcGVyZm9ybWVkIGRpcmVjdGx5LgorICBpbnQgT2Zmc2V0QWRqdXN0bWVudCA9IDA7CisKKyAgLy8vIFRoZSBwcm9sb2cvZXBpbG9nIGNvZGUgaW5zZXJ0ZXIgbWF5IHByb2Nlc3Mgb2JqZWN0cyB0aGF0IHJlcXVpcmUgZ3JlYXRlcgorICAvLy8gYWxpZ25tZW50IHRoYW4gdGhlIGRlZmF1bHQgYWxpZ25tZW50IHRoZSB0YXJnZXQgcHJvdmlkZXMuCisgIC8vLyBUbyBoYW5kbGUgdGhpcywgTWF4QWxpZ25tZW50IGlzIHNldCB0byB0aGUgbWF4aW11bSBhbGlnbm1lbnQKKyAgLy8vIG5lZWRlZCBieSB0aGUgb2JqZWN0cyBvbiB0aGUgY3VycmVudCBmcmFtZS4gIElmIHRoaXMgaXMgZ3JlYXRlciB0aGFuIHRoZQorICAvLy8gbmF0aXZlIGFsaWdubWVudCBtYWludGFpbmVkIGJ5IHRoZSBjb21waWxlciwgZHluYW1pYyBhbGlnbm1lbnQgY29kZSB3aWxsCisgIC8vLyBiZSBuZWVkZWQuCisgIC8vLworICB1bnNpZ25lZCBNYXhBbGlnbm1lbnQgPSAwOworCisgIC8vLyBTZXQgdG8gdHJ1ZSBpZiB0aGlzIGZ1bmN0aW9uIGFkanVzdHMgdGhlIHN0YWNrIC0tIGUuZy4sCisgIC8vLyB3aGVuIGNhbGxpbmcgYW5vdGhlciBmdW5jdGlvbi4gVGhpcyBpcyBvbmx5IHZhbGlkIGR1cmluZyBhbmQgYWZ0ZXIKKyAgLy8vIHByb2xvZy9lcGlsb2cgY29kZSBpbnNlcnRpb24uCisgIGJvb2wgQWRqdXN0c1N0YWNrID0gZmFsc2U7CisKKyAgLy8vIFNldCB0byB0cnVlIGlmIHRoaXMgZnVuY3Rpb24gaGFzIGFueSBmdW5jdGlvbiBjYWxscy4KKyAgYm9vbCBIYXNDYWxscyA9IGZhbHNlOworCisgIC8vLyBUaGUgZnJhbWUgaW5kZXggZm9yIHRoZSBzdGFjayBwcm90ZWN0b3IuCisgIGludCBTdGFja1Byb3RlY3RvcklkeCA9IC0xOworCisgIC8vLyBUaGUgZnJhbWUgaW5kZXggZm9yIHRoZSBmdW5jdGlvbiBjb250ZXh0LiBVc2VkIGZvciBTakxqIGV4Y2VwdGlvbnMuCisgIGludCBGdW5jdGlvbkNvbnRleHRJZHggPSAtMTsKKworICAvLy8gVGhpcyBjb250YWlucyB0aGUgc2l6ZSBvZiB0aGUgbGFyZ2VzdCBjYWxsIGZyYW1lIGlmIHRoZSB0YXJnZXQgdXNlcyBmcmFtZQorICAvLy8gc2V0dXAvZGVzdHJveSBwc2V1ZG8gaW5zdHJ1Y3Rpb25zIChhcyBkZWZpbmVkIGluIHRoZSBUYXJnZXRGcmFtZUluZm8KKyAgLy8vIGNsYXNzKS4gIFRoaXMgaW5mb3JtYXRpb24gaXMgaW1wb3J0YW50IGZvciBmcmFtZSBwb2ludGVyIGVsaW1pbmF0aW9uLgorICAvLy8gSXQgaXMgb25seSB2YWxpZCBkdXJpbmcgYW5kIGFmdGVyIHByb2xvZy9lcGlsb2cgY29kZSBpbnNlcnRpb24uCisgIHVuc2lnbmVkIE1heENhbGxGcmFtZVNpemUgPSB+MHU7CisKKyAgLy8vIFRoZSBwcm9sb2cvZXBpbG9nIGNvZGUgaW5zZXJ0ZXIgZmlsbHMgaW4gdGhpcyB2ZWN0b3Igd2l0aCBlYWNoCisgIC8vLyBjYWxsZWUgc2F2ZWQgcmVnaXN0ZXIgc2F2ZWQgaW4gdGhlIGZyYW1lLiAgQmV5b25kIGl0cyB1c2UgYnkgdGhlIHByb2xvZy8KKyAgLy8vIGVwaWxvZyBjb2RlIGluc2VydGVyLCB0aGlzIGRhdGEgdXNlZCBmb3IgZGVidWcgaW5mbyBhbmQgZXhjZXB0aW9uCisgIC8vLyBoYW5kbGluZy4KKyAgc3RkOjp2ZWN0b3I8Q2FsbGVlU2F2ZWRJbmZvPiBDU0luZm87CisKKyAgLy8vIEhhcyBDU0luZm8gYmVlbiBzZXQgeWV0PworICBib29sIENTSVZhbGlkID0gZmFsc2U7CisKKyAgLy8vIFJlZmVyZW5jZXMgdG8gZnJhbWUgaW5kaWNlcyB3aGljaCBhcmUgbWFwcGVkCisgIC8vLyBpbnRvIHRoZSBsb2NhbCBmcmFtZSBhbGxvY2F0aW9uIGJsb2NrLiA8RnJhbWVJZHgsIExvY2FsT2Zmc2V0PgorICBTbWFsbFZlY3RvcjxzdGQ6OnBhaXI8aW50LCBpbnQ2NF90PiwgMzI+IExvY2FsRnJhbWVPYmplY3RzOworCisgIC8vLyBTaXplIG9mIHRoZSBwcmUtYWxsb2NhdGVkIGxvY2FsIGZyYW1lIGJsb2NrLgorICBpbnQ2NF90IExvY2FsRnJhbWVTaXplID0gMDsKKworICAvLy8gUmVxdWlyZWQgYWxpZ25tZW50IG9mIHRoZSBsb2NhbCBvYmplY3QgYmxvYiwgd2hpY2ggaXMgdGhlIHN0cmljdGVzdAorICAvLy8gYWxpZ25tZW50IG9mIGFueSBvYmplY3QgaW4gaXQuCisgIHVuc2lnbmVkIExvY2FsRnJhbWVNYXhBbGlnbiA9IDA7CisKKyAgLy8vIFdoZXRoZXIgdGhlIGxvY2FsIG9iamVjdCBibG9iIG5lZWRzIHRvIGJlIGFsbG9jYXRlZCB0b2dldGhlci4gSWYgbm90LAorICAvLy8gUEVJIHNob3VsZCBpZ25vcmUgdGhlIGlzUHJlQWxsb2NhdGVkIGZsYWdzIG9uIHRoZSBzdGFjayBvYmplY3RzIGFuZAorICAvLy8ganVzdCBhbGxvY2F0ZSB0aGVtIG5vcm1hbGx5LgorICBib29sIFVzZUxvY2FsU3RhY2tBbGxvY2F0aW9uQmxvY2sgPSBmYWxzZTsKKworICAvLy8gVHJ1ZSBpZiB0aGUgZnVuY3Rpb24gZHluYW1pY2FsbHkgYWRqdXN0cyB0aGUgc3RhY2sgcG9pbnRlciB0aHJvdWdoIHNvbWUKKyAgLy8vIG9wYXF1ZSBtZWNoYW5pc20gbGlrZSBpbmxpbmUgYXNzZW1ibHkgb3IgV2luMzIgRUguCisgIGJvb2wgSGFzT3BhcXVlU1BBZGp1c3RtZW50ID0gZmFsc2U7CisKKyAgLy8vIFRydWUgaWYgdGhlIGZ1bmN0aW9uIGNvbnRhaW5zIG9wZXJhdGlvbnMgd2hpY2ggd2lsbCBsb3dlciBkb3duIHRvCisgIC8vLyBpbnN0cnVjdGlvbnMgd2hpY2ggbWFuaXB1bGF0ZSB0aGUgc3RhY2sgcG9pbnRlci4KKyAgYm9vbCBIYXNDb3B5SW1wbHlpbmdTdGFja0FkanVzdG1lbnQgPSBmYWxzZTsKKworICAvLy8gVHJ1ZSBpZiB0aGUgZnVuY3Rpb24gY29udGFpbnMgYSBjYWxsIHRvIHRoZSBsbHZtLnZhc3RhcnQgaW50cmluc2ljLgorICBib29sIEhhc1ZBU3RhcnQgPSBmYWxzZTsKKworICAvLy8gVHJ1ZSBpZiB0aGlzIGlzIGEgdmFyYXJncyBmdW5jdGlvbiB0aGF0IGNvbnRhaW5zIGEgbXVzdHRhaWwgY2FsbC4KKyAgYm9vbCBIYXNNdXN0VGFpbEluVmFyQXJnRnVuYyA9IGZhbHNlOworCisgIC8vLyBUcnVlIGlmIHRoaXMgZnVuY3Rpb24gY29udGFpbnMgYSB0YWlsIGNhbGwuIElmIHNvIGltbXV0YWJsZSBvYmplY3RzIGxpa2UKKyAgLy8vIGZ1bmN0aW9uIGFyZ3VtZW50cyBhcmUgbm8gbG9uZ2VyIHNvLiBBIHRhaWwgY2FsbCAqY2FuKiBvdmVycmlkZSBmaXhlZAorICAvLy8gc3RhY2sgb2JqZWN0cyBsaWtlIGFyZ3VtZW50cyBzbyB3ZSBjYW4ndCB0cmVhdCB0aGVtIGFzIGltbXV0YWJsZS4KKyAgYm9vbCBIYXNUYWlsQ2FsbCA9IGZhbHNlOworCisgIC8vLyBOb3QgbnVsbCwgaWYgc2hyaW5rLXdyYXBwaW5nIGZvdW5kIGEgYmV0dGVyIHBsYWNlIGZvciB0aGUgcHJvbG9ndWUuCisgIE1hY2hpbmVCYXNpY0Jsb2NrICpTYXZlID0gbnVsbHB0cjsKKyAgLy8vIE5vdCBudWxsLCBpZiBzaHJpbmstd3JhcHBpbmcgZm91bmQgYSBiZXR0ZXIgcGxhY2UgZm9yIHRoZSBlcGlsb2d1ZS4KKyAgTWFjaGluZUJhc2ljQmxvY2sgKlJlc3RvcmUgPSBudWxscHRyOworCitwdWJsaWM6CisgIGV4cGxpY2l0IE1hY2hpbmVGcmFtZUluZm8odW5zaWduZWQgU3RhY2tBbGlnbm1lbnQsIGJvb2wgU3RhY2tSZWFsaWduYWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIEZvcmNlZFJlYWxpZ24pCisgICAgICA6IFN0YWNrQWxpZ25tZW50KFN0YWNrQWxpZ25tZW50KSwgU3RhY2tSZWFsaWduYWJsZShTdGFja1JlYWxpZ25hYmxlKSwKKyAgICAgICAgRm9yY2VkUmVhbGlnbihGb3JjZWRSZWFsaWduKSB7fQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGVyZSBhcmUgYW55IHN0YWNrIG9iamVjdHMgaW4gdGhpcyBmdW5jdGlvbi4KKyAgYm9vbCBoYXNTdGFja09iamVjdHMoKSBjb25zdCB7IHJldHVybiAhT2JqZWN0cy5lbXB0eSgpOyB9CisKKyAgLy8vIFRoaXMgbWV0aG9kIG1heSBiZSBjYWxsZWQgYW55IHRpbWUgYWZ0ZXIgaW5zdHJ1Y3Rpb24KKyAgLy8vIHNlbGVjdGlvbiBpcyBjb21wbGV0ZSB0byBkZXRlcm1pbmUgaWYgdGhlIHN0YWNrIGZyYW1lIGZvciB0aGlzIGZ1bmN0aW9uCisgIC8vLyBjb250YWlucyBhbnkgdmFyaWFibGUgc2l6ZWQgb2JqZWN0cy4KKyAgYm9vbCBoYXNWYXJTaXplZE9iamVjdHMoKSBjb25zdCB7IHJldHVybiBIYXNWYXJTaXplZE9iamVjdHM7IH0KKworICAvLy8gUmV0dXJuIHRoZSBpbmRleCBmb3IgdGhlIHN0YWNrIHByb3RlY3RvciBvYmplY3QuCisgIGludCBnZXRTdGFja1Byb3RlY3RvckluZGV4KCkgY29uc3QgeyByZXR1cm4gU3RhY2tQcm90ZWN0b3JJZHg7IH0KKyAgdm9pZCBzZXRTdGFja1Byb3RlY3RvckluZGV4KGludCBJKSB7IFN0YWNrUHJvdGVjdG9ySWR4ID0gSTsgfQorICBib29sIGhhc1N0YWNrUHJvdGVjdG9ySW5kZXgoKSBjb25zdCB7IHJldHVybiBTdGFja1Byb3RlY3RvcklkeCAhPSAtMTsgfQorCisgIC8vLyBSZXR1cm4gdGhlIGluZGV4IGZvciB0aGUgZnVuY3Rpb24gY29udGV4dCBvYmplY3QuCisgIC8vLyBUaGlzIG9iamVjdCBpcyB1c2VkIGZvciBTakxqIGV4Y2VwdGlvbnMuCisgIGludCBnZXRGdW5jdGlvbkNvbnRleHRJbmRleCgpIGNvbnN0IHsgcmV0dXJuIEZ1bmN0aW9uQ29udGV4dElkeDsgfQorICB2b2lkIHNldEZ1bmN0aW9uQ29udGV4dEluZGV4KGludCBJKSB7IEZ1bmN0aW9uQ29udGV4dElkeCA9IEk7IH0KKworICAvLy8gVGhpcyBtZXRob2QgbWF5IGJlIGNhbGxlZCBhbnkgdGltZSBhZnRlciBpbnN0cnVjdGlvbgorICAvLy8gc2VsZWN0aW9uIGlzIGNvbXBsZXRlIHRvIGRldGVybWluZSBpZiB0aGVyZSBpcyBhIGNhbGwgdG8KKyAgLy8vIFxAbGx2bS5mcmFtZWFkZHJlc3MgaW4gdGhpcyBmdW5jdGlvbi4KKyAgYm9vbCBpc0ZyYW1lQWRkcmVzc1Rha2VuKCkgY29uc3QgeyByZXR1cm4gRnJhbWVBZGRyZXNzVGFrZW47IH0KKyAgdm9pZCBzZXRGcmFtZUFkZHJlc3NJc1Rha2VuKGJvb2wgVCkgeyBGcmFtZUFkZHJlc3NUYWtlbiA9IFQ7IH0KKworICAvLy8gVGhpcyBtZXRob2QgbWF5IGJlIGNhbGxlZCBhbnkgdGltZSBhZnRlcgorICAvLy8gaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uIGlzIGNvbXBsZXRlIHRvIGRldGVybWluZSBpZiB0aGVyZSBpcyBhIGNhbGwgdG8KKyAgLy8vIFxAbGx2bS5yZXR1cm5hZGRyZXNzIGluIHRoaXMgZnVuY3Rpb24uCisgIGJvb2wgaXNSZXR1cm5BZGRyZXNzVGFrZW4oKSBjb25zdCB7IHJldHVybiBSZXR1cm5BZGRyZXNzVGFrZW47IH0KKyAgdm9pZCBzZXRSZXR1cm5BZGRyZXNzSXNUYWtlbihib29sIHMpIHsgUmV0dXJuQWRkcmVzc1Rha2VuID0gczsgfQorCisgIC8vLyBUaGlzIG1ldGhvZCBtYXkgYmUgY2FsbGVkIGFueSB0aW1lIGFmdGVyIGluc3RydWN0aW9uCisgIC8vLyBzZWxlY3Rpb24gaXMgY29tcGxldGUgdG8gZGV0ZXJtaW5lIGlmIHRoZXJlIGlzIGEgY2FsbCB0byBidWlsdGluCisgIC8vLyBcQGxsdm0uZXhwZXJpbWVudGFsLnN0YWNrbWFwLgorICBib29sIGhhc1N0YWNrTWFwKCkgY29uc3QgeyByZXR1cm4gSGFzU3RhY2tNYXA7IH0KKyAgdm9pZCBzZXRIYXNTdGFja01hcChib29sIHMgPSB0cnVlKSB7IEhhc1N0YWNrTWFwID0gczsgfQorCisgIC8vLyBUaGlzIG1ldGhvZCBtYXkgYmUgY2FsbGVkIGFueSB0aW1lIGFmdGVyIGluc3RydWN0aW9uCisgIC8vLyBzZWxlY3Rpb24gaXMgY29tcGxldGUgdG8gZGV0ZXJtaW5lIGlmIHRoZXJlIGlzIGEgY2FsbCB0byBidWlsdGluCisgIC8vLyBcQGxsdm0uZXhwZXJpbWVudGFsLnBhdGNocG9pbnQuCisgIGJvb2wgaGFzUGF0Y2hQb2ludCgpIGNvbnN0IHsgcmV0dXJuIEhhc1BhdGNoUG9pbnQ7IH0KKyAgdm9pZCBzZXRIYXNQYXRjaFBvaW50KGJvb2wgcyA9IHRydWUpIHsgSGFzUGF0Y2hQb2ludCA9IHM7IH0KKworICAvLy8gUmV0dXJuIHRoZSBtaW5pbXVtIGZyYW1lIG9iamVjdCBpbmRleC4KKyAgaW50IGdldE9iamVjdEluZGV4QmVnaW4oKSBjb25zdCB7IHJldHVybiAtTnVtRml4ZWRPYmplY3RzOyB9CisKKyAgLy8vIFJldHVybiBvbmUgcGFzdCB0aGUgbWF4aW11bSBmcmFtZSBvYmplY3QgaW5kZXguCisgIGludCBnZXRPYmplY3RJbmRleEVuZCgpIGNvbnN0IHsgcmV0dXJuIChpbnQpT2JqZWN0cy5zaXplKCktTnVtRml4ZWRPYmplY3RzOyB9CisKKyAgLy8vIFJldHVybiB0aGUgbnVtYmVyIG9mIGZpeGVkIG9iamVjdHMuCisgIHVuc2lnbmVkIGdldE51bUZpeGVkT2JqZWN0cygpIGNvbnN0IHsgcmV0dXJuIE51bUZpeGVkT2JqZWN0czsgfQorCisgIC8vLyBSZXR1cm4gdGhlIG51bWJlciBvZiBvYmplY3RzLgorICB1bnNpZ25lZCBnZXROdW1PYmplY3RzKCkgY29uc3QgeyByZXR1cm4gT2JqZWN0cy5zaXplKCk7IH0KKworICAvLy8gTWFwIGEgZnJhbWUgaW5kZXggaW50byB0aGUgbG9jYWwgb2JqZWN0IGJsb2NrCisgIHZvaWQgbWFwTG9jYWxGcmFtZU9iamVjdChpbnQgT2JqZWN0SW5kZXgsIGludDY0X3QgT2Zmc2V0KSB7CisgICAgTG9jYWxGcmFtZU9iamVjdHMucHVzaF9iYWNrKHN0ZDo6cGFpcjxpbnQsIGludDY0X3Q+KE9iamVjdEluZGV4LCBPZmZzZXQpKTsKKyAgICBPYmplY3RzW09iamVjdEluZGV4ICsgTnVtRml4ZWRPYmplY3RzXS5QcmVBbGxvY2F0ZWQgPSB0cnVlOworICB9CisKKyAgLy8vIEdldCB0aGUgbG9jYWwgb2Zmc2V0IG1hcHBpbmcgZm9yIGEgZm9yIGFuIG9iamVjdC4KKyAgc3RkOjpwYWlyPGludCwgaW50NjRfdD4gZ2V0TG9jYWxGcmFtZU9iamVjdE1hcChpbnQgaSkgY29uc3QgeworICAgIGFzc2VydCAoaSA+PSAwICYmICh1bnNpZ25lZClpIDwgTG9jYWxGcmFtZU9iamVjdHMuc2l6ZSgpICYmCisgICAgICAgICAgICAiSW52YWxpZCBsb2NhbCBvYmplY3QgcmVmZXJlbmNlISIpOworICAgIHJldHVybiBMb2NhbEZyYW1lT2JqZWN0c1tpXTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIG51bWJlciBvZiBvYmplY3RzIGFsbG9jYXRlZCBpbnRvIHRoZSBsb2NhbCBvYmplY3QgYmxvY2suCisgIGludDY0X3QgZ2V0TG9jYWxGcmFtZU9iamVjdENvdW50KCkgY29uc3QgeyByZXR1cm4gTG9jYWxGcmFtZU9iamVjdHMuc2l6ZSgpOyB9CisKKyAgLy8vIFNldCB0aGUgc2l6ZSBvZiB0aGUgbG9jYWwgb2JqZWN0IGJsb2IuCisgIHZvaWQgc2V0TG9jYWxGcmFtZVNpemUoaW50NjRfdCBzeikgeyBMb2NhbEZyYW1lU2l6ZSA9IHN6OyB9CisKKyAgLy8vIEdldCB0aGUgc2l6ZSBvZiB0aGUgbG9jYWwgb2JqZWN0IGJsb2IuCisgIGludDY0X3QgZ2V0TG9jYWxGcmFtZVNpemUoKSBjb25zdCB7IHJldHVybiBMb2NhbEZyYW1lU2l6ZTsgfQorCisgIC8vLyBSZXF1aXJlZCBhbGlnbm1lbnQgb2YgdGhlIGxvY2FsIG9iamVjdCBibG9iLAorICAvLy8gd2hpY2ggaXMgdGhlIHN0cmljdGVzdCBhbGlnbm1lbnQgb2YgYW55IG9iamVjdCBpbiBpdC4KKyAgdm9pZCBzZXRMb2NhbEZyYW1lTWF4QWxpZ24odW5zaWduZWQgQWxpZ24pIHsgTG9jYWxGcmFtZU1heEFsaWduID0gQWxpZ247IH0KKworICAvLy8gUmV0dXJuIHRoZSByZXF1aXJlZCBhbGlnbm1lbnQgb2YgdGhlIGxvY2FsIG9iamVjdCBibG9iLgorICB1bnNpZ25lZCBnZXRMb2NhbEZyYW1lTWF4QWxpZ24oKSBjb25zdCB7IHJldHVybiBMb2NhbEZyYW1lTWF4QWxpZ247IH0KKworICAvLy8gR2V0IHdoZXRoZXIgdGhlIGxvY2FsIGFsbG9jYXRpb24gYmxvYiBzaG91bGQgYmUgYWxsb2NhdGVkIHRvZ2V0aGVyIG9yCisgIC8vLyBsZXQgUEVJIGFsbG9jYXRlIHRoZSBsb2NhbHMgaW4gaXQgZGlyZWN0bHkuCisgIGJvb2wgZ2V0VXNlTG9jYWxTdGFja0FsbG9jYXRpb25CbG9jaygpIGNvbnN0IHsKKyAgICByZXR1cm4gVXNlTG9jYWxTdGFja0FsbG9jYXRpb25CbG9jazsKKyAgfQorCisgIC8vLyBzZXRVc2VMb2NhbFN0YWNrQWxsb2NhdGlvbkJsb2NrIC0gU2V0IHdoZXRoZXIgdGhlIGxvY2FsIGFsbG9jYXRpb24gYmxvYgorICAvLy8gc2hvdWxkIGJlIGFsbG9jYXRlZCB0b2dldGhlciBvciBsZXQgUEVJIGFsbG9jYXRlIHRoZSBsb2NhbHMgaW4gaXQKKyAgLy8vIGRpcmVjdGx5LgorICB2b2lkIHNldFVzZUxvY2FsU3RhY2tBbGxvY2F0aW9uQmxvY2soYm9vbCB2KSB7CisgICAgVXNlTG9jYWxTdGFja0FsbG9jYXRpb25CbG9jayA9IHY7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIG9iamVjdCB3YXMgcHJlLWFsbG9jYXRlZCBpbnRvIHRoZSBsb2NhbCBibG9jay4KKyAgYm9vbCBpc09iamVjdFByZUFsbG9jYXRlZChpbnQgT2JqZWN0SWR4KSBjb25zdCB7CisgICAgYXNzZXJ0KHVuc2lnbmVkKE9iamVjdElkeCtOdW1GaXhlZE9iamVjdHMpIDwgT2JqZWN0cy5zaXplKCkgJiYKKyAgICAgICAgICAgIkludmFsaWQgT2JqZWN0IElkeCEiKTsKKyAgICByZXR1cm4gT2JqZWN0c1tPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzXS5QcmVBbGxvY2F0ZWQ7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBzaXplIG9mIHRoZSBzcGVjaWZpZWQgb2JqZWN0LgorICBpbnQ2NF90IGdldE9iamVjdFNpemUoaW50IE9iamVjdElkeCkgY29uc3QgeworICAgIGFzc2VydCh1bnNpZ25lZChPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzKSA8IE9iamVjdHMuc2l6ZSgpICYmCisgICAgICAgICAgICJJbnZhbGlkIE9iamVjdCBJZHghIik7CisgICAgcmV0dXJuIE9iamVjdHNbT2JqZWN0SWR4K051bUZpeGVkT2JqZWN0c10uU2l6ZTsKKyAgfQorCisgIC8vLyBDaGFuZ2UgdGhlIHNpemUgb2YgdGhlIHNwZWNpZmllZCBzdGFjayBvYmplY3QuCisgIHZvaWQgc2V0T2JqZWN0U2l6ZShpbnQgT2JqZWN0SWR4LCBpbnQ2NF90IFNpemUpIHsKKyAgICBhc3NlcnQodW5zaWduZWQoT2JqZWN0SWR4K051bUZpeGVkT2JqZWN0cykgPCBPYmplY3RzLnNpemUoKSAmJgorICAgICAgICAgICAiSW52YWxpZCBPYmplY3QgSWR4ISIpOworICAgIE9iamVjdHNbT2JqZWN0SWR4K051bUZpeGVkT2JqZWN0c10uU2l6ZSA9IFNpemU7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBhbGlnbm1lbnQgb2YgdGhlIHNwZWNpZmllZCBzdGFjayBvYmplY3QuCisgIHVuc2lnbmVkIGdldE9iamVjdEFsaWdubWVudChpbnQgT2JqZWN0SWR4KSBjb25zdCB7CisgICAgYXNzZXJ0KHVuc2lnbmVkKE9iamVjdElkeCtOdW1GaXhlZE9iamVjdHMpIDwgT2JqZWN0cy5zaXplKCkgJiYKKyAgICAgICAgICAgIkludmFsaWQgT2JqZWN0IElkeCEiKTsKKyAgICByZXR1cm4gT2JqZWN0c1tPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzXS5BbGlnbm1lbnQ7CisgIH0KKworICAvLy8gc2V0T2JqZWN0QWxpZ25tZW50IC0gQ2hhbmdlIHRoZSBhbGlnbm1lbnQgb2YgdGhlIHNwZWNpZmllZCBzdGFjayBvYmplY3QuCisgIHZvaWQgc2V0T2JqZWN0QWxpZ25tZW50KGludCBPYmplY3RJZHgsIHVuc2lnbmVkIEFsaWduKSB7CisgICAgYXNzZXJ0KHVuc2lnbmVkKE9iamVjdElkeCtOdW1GaXhlZE9iamVjdHMpIDwgT2JqZWN0cy5zaXplKCkgJiYKKyAgICAgICAgICAgIkludmFsaWQgT2JqZWN0IElkeCEiKTsKKyAgICBPYmplY3RzW09iamVjdElkeCtOdW1GaXhlZE9iamVjdHNdLkFsaWdubWVudCA9IEFsaWduOworICAgIGVuc3VyZU1heEFsaWdubWVudChBbGlnbik7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSB1bmRlcmx5aW5nIEFsbG9jYSBvZiB0aGUgc3BlY2lmaWVkCisgIC8vLyBzdGFjayBvYmplY3QgaWYgaXQgZXhpc3RzLiBSZXR1cm5zIDAgaWYgbm9uZSBleGlzdHMuCisgIGNvbnN0IEFsbG9jYUluc3QqIGdldE9iamVjdEFsbG9jYXRpb24oaW50IE9iamVjdElkeCkgY29uc3QgeworICAgIGFzc2VydCh1bnNpZ25lZChPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzKSA8IE9iamVjdHMuc2l6ZSgpICYmCisgICAgICAgICAgICJJbnZhbGlkIE9iamVjdCBJZHghIik7CisgICAgcmV0dXJuIE9iamVjdHNbT2JqZWN0SWR4K051bUZpeGVkT2JqZWN0c10uQWxsb2NhOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgYXNzaWduZWQgc3RhY2sgb2Zmc2V0IG9mIHRoZSBzcGVjaWZpZWQgb2JqZWN0CisgIC8vLyBmcm9tIHRoZSBpbmNvbWluZyBzdGFjayBwb2ludGVyLgorICBpbnQ2NF90IGdldE9iamVjdE9mZnNldChpbnQgT2JqZWN0SWR4KSBjb25zdCB7CisgICAgYXNzZXJ0KHVuc2lnbmVkKE9iamVjdElkeCtOdW1GaXhlZE9iamVjdHMpIDwgT2JqZWN0cy5zaXplKCkgJiYKKyAgICAgICAgICAgIkludmFsaWQgT2JqZWN0IElkeCEiKTsKKyAgICBhc3NlcnQoIWlzRGVhZE9iamVjdEluZGV4KE9iamVjdElkeCkgJiYKKyAgICAgICAgICAgIkdldHRpbmcgZnJhbWUgb2Zmc2V0IGZvciBhIGRlYWQgb2JqZWN0PyIpOworICAgIHJldHVybiBPYmplY3RzW09iamVjdElkeCtOdW1GaXhlZE9iamVjdHNdLlNQT2Zmc2V0OworICB9CisKKyAgYm9vbCBpc09iamVjdFpFeHQoaW50IE9iamVjdElkeCkgY29uc3QgeworICAgIGFzc2VydCh1bnNpZ25lZChPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzKSA8IE9iamVjdHMuc2l6ZSgpICYmCisgICAgICAgICAgICJJbnZhbGlkIE9iamVjdCBJZHghIik7CisgICAgcmV0dXJuIE9iamVjdHNbT2JqZWN0SWR4K051bUZpeGVkT2JqZWN0c10uaXNaRXh0OworICB9CisKKyAgdm9pZCBzZXRPYmplY3RaRXh0KGludCBPYmplY3RJZHgsIGJvb2wgSXNaRXh0KSB7CisgICAgYXNzZXJ0KHVuc2lnbmVkKE9iamVjdElkeCtOdW1GaXhlZE9iamVjdHMpIDwgT2JqZWN0cy5zaXplKCkgJiYKKyAgICAgICAgICAgIkludmFsaWQgT2JqZWN0IElkeCEiKTsKKyAgICBPYmplY3RzW09iamVjdElkeCtOdW1GaXhlZE9iamVjdHNdLmlzWkV4dCA9IElzWkV4dDsKKyAgfQorCisgIGJvb2wgaXNPYmplY3RTRXh0KGludCBPYmplY3RJZHgpIGNvbnN0IHsKKyAgICBhc3NlcnQodW5zaWduZWQoT2JqZWN0SWR4K051bUZpeGVkT2JqZWN0cykgPCBPYmplY3RzLnNpemUoKSAmJgorICAgICAgICAgICAiSW52YWxpZCBPYmplY3QgSWR4ISIpOworICAgIHJldHVybiBPYmplY3RzW09iamVjdElkeCtOdW1GaXhlZE9iamVjdHNdLmlzU0V4dDsKKyAgfQorCisgIHZvaWQgc2V0T2JqZWN0U0V4dChpbnQgT2JqZWN0SWR4LCBib29sIElzU0V4dCkgeworICAgIGFzc2VydCh1bnNpZ25lZChPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzKSA8IE9iamVjdHMuc2l6ZSgpICYmCisgICAgICAgICAgICJJbnZhbGlkIE9iamVjdCBJZHghIik7CisgICAgT2JqZWN0c1tPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzXS5pc1NFeHQgPSBJc1NFeHQ7CisgIH0KKworICAvLy8gU2V0IHRoZSBzdGFjayBmcmFtZSBvZmZzZXQgb2YgdGhlIHNwZWNpZmllZCBvYmplY3QuIFRoZQorICAvLy8gb2Zmc2V0IGlzIHJlbGF0aXZlIHRvIHRoZSBzdGFjayBwb2ludGVyIG9uIGVudHJ5IHRvIHRoZSBmdW5jdGlvbi4KKyAgdm9pZCBzZXRPYmplY3RPZmZzZXQoaW50IE9iamVjdElkeCwgaW50NjRfdCBTUE9mZnNldCkgeworICAgIGFzc2VydCh1bnNpZ25lZChPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzKSA8IE9iamVjdHMuc2l6ZSgpICYmCisgICAgICAgICAgICJJbnZhbGlkIE9iamVjdCBJZHghIik7CisgICAgYXNzZXJ0KCFpc0RlYWRPYmplY3RJbmRleChPYmplY3RJZHgpICYmCisgICAgICAgICAgICJTZXR0aW5nIGZyYW1lIG9mZnNldCBmb3IgYSBkZWFkIG9iamVjdD8iKTsKKyAgICBPYmplY3RzW09iamVjdElkeCtOdW1GaXhlZE9iamVjdHNdLlNQT2Zmc2V0ID0gU1BPZmZzZXQ7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBtdXN0IGJlIGFsbG9jYXRlZCB0byBob2xkCisgIC8vLyBhbGwgb2YgdGhlIGZpeGVkIHNpemUgZnJhbWUgb2JqZWN0cy4gIFRoaXMgaXMgb25seSB2YWxpZCBhZnRlcgorICAvLy8gUHJvbG9nL0VwaWxvZyBjb2RlIGluc2VydGlvbiBoYXMgZmluYWxpemVkIHRoZSBzdGFjayBmcmFtZSBsYXlvdXQuCisgIHVpbnQ2NF90IGdldFN0YWNrU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIFN0YWNrU2l6ZTsgfQorCisgIC8vLyBTZXQgdGhlIHNpemUgb2YgdGhlIHN0YWNrLgorICB2b2lkIHNldFN0YWNrU2l6ZSh1aW50NjRfdCBTaXplKSB7IFN0YWNrU2l6ZSA9IFNpemU7IH0KKworICAvLy8gRXN0aW1hdGUgYW5kIHJldHVybiB0aGUgc2l6ZSBvZiB0aGUgc3RhY2sgZnJhbWUuCisgIHVuc2lnbmVkIGVzdGltYXRlU3RhY2tTaXplKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdGhlIGNvcnJlY3Rpb24gZm9yIGZyYW1lIG9mZnNldHMuCisgIGludCBnZXRPZmZzZXRBZGp1c3RtZW50KCkgY29uc3QgeyByZXR1cm4gT2Zmc2V0QWRqdXN0bWVudDsgfQorCisgIC8vLyBTZXQgdGhlIGNvcnJlY3Rpb24gZm9yIGZyYW1lIG9mZnNldHMuCisgIHZvaWQgc2V0T2Zmc2V0QWRqdXN0bWVudChpbnQgQWRqKSB7IE9mZnNldEFkanVzdG1lbnQgPSBBZGo7IH0KKworICAvLy8gUmV0dXJuIHRoZSBhbGlnbm1lbnQgaW4gYnl0ZXMgdGhhdCB0aGlzIGZ1bmN0aW9uIG11c3QgYmUgYWxpZ25lZCB0bywKKyAgLy8vIHdoaWNoIGlzIGdyZWF0ZXIgdGhhbiB0aGUgZGVmYXVsdCBzdGFjayBhbGlnbm1lbnQgcHJvdmlkZWQgYnkgdGhlIHRhcmdldC4KKyAgdW5zaWduZWQgZ2V0TWF4QWxpZ25tZW50KCkgY29uc3QgeyByZXR1cm4gTWF4QWxpZ25tZW50OyB9CisKKyAgLy8vIE1ha2Ugc3VyZSB0aGUgZnVuY3Rpb24gaXMgYXQgbGVhc3QgQWxpZ24gYnl0ZXMgYWxpZ25lZC4KKyAgdm9pZCBlbnN1cmVNYXhBbGlnbm1lbnQodW5zaWduZWQgQWxpZ24pOworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGZ1bmN0aW9uIGFkanVzdHMgdGhlIHN0YWNrIC0tIGUuZy4sCisgIC8vLyB3aGVuIGNhbGxpbmcgYW5vdGhlciBmdW5jdGlvbi4gVGhpcyBpcyBvbmx5IHZhbGlkIGR1cmluZyBhbmQgYWZ0ZXIKKyAgLy8vIHByb2xvZy9lcGlsb2cgY29kZSBpbnNlcnRpb24uCisgIGJvb2wgYWRqdXN0c1N0YWNrKCkgY29uc3QgeyByZXR1cm4gQWRqdXN0c1N0YWNrOyB9CisgIHZvaWQgc2V0QWRqdXN0c1N0YWNrKGJvb2wgVikgeyBBZGp1c3RzU3RhY2sgPSBWOyB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBjdXJyZW50IGZ1bmN0aW9uIGhhcyBhbnkgZnVuY3Rpb24gY2FsbHMuCisgIGJvb2wgaGFzQ2FsbHMoKSBjb25zdCB7IHJldHVybiBIYXNDYWxsczsgfQorICB2b2lkIHNldEhhc0NhbGxzKGJvb2wgVikgeyBIYXNDYWxscyA9IFY7IH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBmdW5jdGlvbiBjb250YWlucyBvcGFxdWUgZHluYW1pYyBzdGFjayBhZGp1c3RtZW50cy4KKyAgYm9vbCBoYXNPcGFxdWVTUEFkanVzdG1lbnQoKSBjb25zdCB7IHJldHVybiBIYXNPcGFxdWVTUEFkanVzdG1lbnQ7IH0KKyAgdm9pZCBzZXRIYXNPcGFxdWVTUEFkanVzdG1lbnQoYm9vbCBCKSB7IEhhc09wYXF1ZVNQQWRqdXN0bWVudCA9IEI7IH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBmdW5jdGlvbiBjb250YWlucyBvcGVyYXRpb25zIHdoaWNoIHdpbGwgbG93ZXIgZG93biB0bworICAvLy8gaW5zdHJ1Y3Rpb25zIHdoaWNoIG1hbmlwdWxhdGUgdGhlIHN0YWNrIHBvaW50ZXIuCisgIGJvb2wgaGFzQ29weUltcGx5aW5nU3RhY2tBZGp1c3RtZW50KCkgY29uc3QgeworICAgIHJldHVybiBIYXNDb3B5SW1wbHlpbmdTdGFja0FkanVzdG1lbnQ7CisgIH0KKyAgdm9pZCBzZXRIYXNDb3B5SW1wbHlpbmdTdGFja0FkanVzdG1lbnQoYm9vbCBCKSB7CisgICAgSGFzQ29weUltcGx5aW5nU3RhY2tBZGp1c3RtZW50ID0gQjsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIGZ1bmN0aW9uIGNhbGxzIHRoZSBsbHZtLnZhX3N0YXJ0IGludHJpbnNpYy4KKyAgYm9vbCBoYXNWQVN0YXJ0KCkgY29uc3QgeyByZXR1cm4gSGFzVkFTdGFydDsgfQorICB2b2lkIHNldEhhc1ZBU3RhcnQoYm9vbCBCKSB7IEhhc1ZBU3RhcnQgPSBCOyB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZnVuY3Rpb24gaXMgdmFyaWFkaWMgYW5kIGNvbnRhaW5zIGEgbXVzdHRhaWwgY2FsbC4KKyAgYm9vbCBoYXNNdXN0VGFpbEluVmFyQXJnRnVuYygpIGNvbnN0IHsgcmV0dXJuIEhhc011c3RUYWlsSW5WYXJBcmdGdW5jOyB9CisgIHZvaWQgc2V0SGFzTXVzdFRhaWxJblZhckFyZ0Z1bmMoYm9vbCBCKSB7IEhhc011c3RUYWlsSW5WYXJBcmdGdW5jID0gQjsgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIGZ1bmN0aW9uIGNvbnRhaW5zIGEgdGFpbCBjYWxsLgorICBib29sIGhhc1RhaWxDYWxsKCkgY29uc3QgeyByZXR1cm4gSGFzVGFpbENhbGw7IH0KKyAgdm9pZCBzZXRIYXNUYWlsQ2FsbCgpIHsgSGFzVGFpbENhbGwgPSB0cnVlOyB9CisKKyAgLy8vIENvbXB1dGVzIHRoZSBtYXhpbXVtIHNpemUgb2YgYSBjYWxsZnJhbWUgYW5kIHRoZSBBZGp1c3RzU3RhY2sgcHJvcGVydHkuCisgIC8vLyBUaGlzIG9ubHkgd29ya3MgZm9yIHRhcmdldHMgZGVmaW5pbmcKKyAgLy8vIFRhcmdldEluc3RySW5mbzo6Z2V0Q2FsbEZyYW1lU2V0dXBPcGNvZGUoKSwgZ2V0Q2FsbEZyYW1lRGVzdHJveU9wY29kZSgpLAorICAvLy8gYW5kIGdldEZyYW1lU2l6ZSgpLgorICAvLy8gVGhpcyBpcyB1c3VhbGx5IGNvbXB1dGVkIGJ5IHRoZSBwcm9sb2d1ZSBlcGlsb2d1ZSBpbnNlcnRlciBidXQgc29tZQorICAvLy8gdGFyZ2V0cyBtYXkgY2FsbCB0aGlzIHRvIGNvbXB1dGUgaXQgZWFybGllci4KKyAgdm9pZCBjb21wdXRlTWF4Q2FsbEZyYW1lU2l6ZShjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKTsKKworICAvLy8gUmV0dXJuIHRoZSBtYXhpbXVtIHNpemUgb2YgYSBjYWxsIGZyYW1lIHRoYXQgbXVzdCBiZQorICAvLy8gYWxsb2NhdGVkIGZvciBhbiBvdXRnb2luZyBmdW5jdGlvbiBjYWxsLiAgVGhpcyBpcyBvbmx5IGF2YWlsYWJsZSBpZgorICAvLy8gQ2FsbEZyYW1lU2V0dXAvRGVzdHJveSBwc2V1ZG8gaW5zdHJ1Y3Rpb25zIGFyZSB1c2VkIGJ5IHRoZSB0YXJnZXQsIGFuZAorICAvLy8gdGhlbiBvbmx5IGR1cmluZyBvciBhZnRlciBwcm9sb2cvZXBpbG9nIGNvZGUgaW5zZXJ0aW9uLgorICAvLy8KKyAgdW5zaWduZWQgZ2V0TWF4Q2FsbEZyYW1lU2l6ZSgpIGNvbnN0IHsKKyAgICAvLyBUT0RPOiBFbmFibGUgdGhpcyBhc3NlcnQgd2hlbiB0YXJnZXRzIGFyZSBmaXhlZC4KKyAgICAvL2Fzc2VydChpc01heENhbGxGcmFtZVNpemVDb21wdXRlZCgpICYmICJNYXhDYWxsRnJhbWVTaXplIG5vdCBjb21wdXRlZCB5ZXQiKTsKKyAgICBpZiAoIWlzTWF4Q2FsbEZyYW1lU2l6ZUNvbXB1dGVkKCkpCisgICAgICByZXR1cm4gMDsKKyAgICByZXR1cm4gTWF4Q2FsbEZyYW1lU2l6ZTsKKyAgfQorICBib29sIGlzTWF4Q2FsbEZyYW1lU2l6ZUNvbXB1dGVkKCkgY29uc3QgeworICAgIHJldHVybiBNYXhDYWxsRnJhbWVTaXplICE9IH4wdTsKKyAgfQorICB2b2lkIHNldE1heENhbGxGcmFtZVNpemUodW5zaWduZWQgUykgeyBNYXhDYWxsRnJhbWVTaXplID0gUzsgfQorCisgIC8vLyBDcmVhdGUgYSBuZXcgb2JqZWN0IGF0IGEgZml4ZWQgbG9jYXRpb24gb24gdGhlIHN0YWNrLgorICAvLy8gQWxsIGZpeGVkIG9iamVjdHMgc2hvdWxkIGJlIGNyZWF0ZWQgYmVmb3JlIG90aGVyIG9iamVjdHMgYXJlIGNyZWF0ZWQgZm9yCisgIC8vLyBlZmZpY2llbmN5LiBCeSBkZWZhdWx0LCBmaXhlZCBvYmplY3RzIGFyZSBub3QgcG9pbnRlZCB0byBieSBMTFZNIElSCisgIC8vLyB2YWx1ZXMuIFRoaXMgcmV0dXJucyBhbiBpbmRleCB3aXRoIGEgbmVnYXRpdmUgdmFsdWUuCisgIGludCBDcmVhdGVGaXhlZE9iamVjdCh1aW50NjRfdCBTaXplLCBpbnQ2NF90IFNQT2Zmc2V0LCBib29sIElzSW1tdXRhYmxlLAorICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc0FsaWFzZWQgPSBmYWxzZSk7CisKKyAgLy8vIENyZWF0ZSBhIHNwaWxsIHNsb3QgYXQgYSBmaXhlZCBsb2NhdGlvbiBvbiB0aGUgc3RhY2suCisgIC8vLyBSZXR1cm5zIGFuIGluZGV4IHdpdGggYSBuZWdhdGl2ZSB2YWx1ZS4KKyAgaW50IENyZWF0ZUZpeGVkU3BpbGxTdGFja09iamVjdCh1aW50NjRfdCBTaXplLCBpbnQ2NF90IFNQT2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgSXNJbW11dGFibGUgPSBmYWxzZSk7CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGluZGV4IGNvcnJlc3BvbmRzIHRvIGEgZml4ZWQgc3RhY2sgb2JqZWN0LgorICBib29sIGlzRml4ZWRPYmplY3RJbmRleChpbnQgT2JqZWN0SWR4KSBjb25zdCB7CisgICAgcmV0dXJuIE9iamVjdElkeCA8IDAgJiYgKE9iamVjdElkeCA+PSAtKGludClOdW1GaXhlZE9iamVjdHMpOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGluZGV4IGNvcnJlc3BvbmRzCisgIC8vLyB0byBhbiBvYmplY3QgdGhhdCBtaWdodCBiZSBwb2ludGVkIHRvIGJ5IGFuIExMVk0gSVIgdmFsdWUuCisgIGJvb2wgaXNBbGlhc2VkT2JqZWN0SW5kZXgoaW50IE9iamVjdElkeCkgY29uc3QgeworICAgIGFzc2VydCh1bnNpZ25lZChPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzKSA8IE9iamVjdHMuc2l6ZSgpICYmCisgICAgICAgICAgICJJbnZhbGlkIE9iamVjdCBJZHghIik7CisgICAgcmV0dXJuIE9iamVjdHNbT2JqZWN0SWR4K051bUZpeGVkT2JqZWN0c10uaXNBbGlhc2VkOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGluZGV4IGNvcnJlc3BvbmRzIHRvIGFuIGltbXV0YWJsZSBvYmplY3QuCisgIGJvb2wgaXNJbW11dGFibGVPYmplY3RJbmRleChpbnQgT2JqZWN0SWR4KSBjb25zdCB7CisgICAgLy8gVGFpbCBjYWxsaW5nIGZ1bmN0aW9ucyBjYW4gY2xvYmJlciB0aGVpciBmdW5jdGlvbiBhcmd1bWVudHMuCisgICAgaWYgKEhhc1RhaWxDYWxsKQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIGFzc2VydCh1bnNpZ25lZChPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzKSA8IE9iamVjdHMuc2l6ZSgpICYmCisgICAgICAgICAgICJJbnZhbGlkIE9iamVjdCBJZHghIik7CisgICAgcmV0dXJuIE9iamVjdHNbT2JqZWN0SWR4K051bUZpeGVkT2JqZWN0c10uaXNJbW11dGFibGU7CisgIH0KKworICAvLy8gTWFya3MgdGhlIGltbXV0YWJpbGl0eSBvZiBhbiBvYmplY3QuCisgIHZvaWQgc2V0SXNJbW11dGFibGVPYmplY3RJbmRleChpbnQgT2JqZWN0SWR4LCBib29sIElzSW1tdXRhYmxlKSB7CisgICAgYXNzZXJ0KHVuc2lnbmVkKE9iamVjdElkeCtOdW1GaXhlZE9iamVjdHMpIDwgT2JqZWN0cy5zaXplKCkgJiYKKyAgICAgICAgICAgIkludmFsaWQgT2JqZWN0IElkeCEiKTsKKyAgICBPYmplY3RzW09iamVjdElkeCtOdW1GaXhlZE9iamVjdHNdLmlzSW1tdXRhYmxlID0gSXNJbW11dGFibGU7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgaW5kZXggY29ycmVzcG9uZHMgdG8gYSBzcGlsbCBzbG90LgorICBib29sIGlzU3BpbGxTbG90T2JqZWN0SW5kZXgoaW50IE9iamVjdElkeCkgY29uc3QgeworICAgIGFzc2VydCh1bnNpZ25lZChPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzKSA8IE9iamVjdHMuc2l6ZSgpICYmCisgICAgICAgICAgICJJbnZhbGlkIE9iamVjdCBJZHghIik7CisgICAgcmV0dXJuIE9iamVjdHNbT2JqZWN0SWR4K051bUZpeGVkT2JqZWN0c10uaXNTcGlsbFNsb3Q7CisgIH0KKworICBib29sIGlzU3RhdGVwb2ludFNwaWxsU2xvdE9iamVjdEluZGV4KGludCBPYmplY3RJZHgpIGNvbnN0IHsKKyAgICBhc3NlcnQodW5zaWduZWQoT2JqZWN0SWR4K051bUZpeGVkT2JqZWN0cykgPCBPYmplY3RzLnNpemUoKSAmJgorICAgICAgICAgICAiSW52YWxpZCBPYmplY3QgSWR4ISIpOworICAgIHJldHVybiBPYmplY3RzW09iamVjdElkeCtOdW1GaXhlZE9iamVjdHNdLmlzU3RhdGVwb2ludFNwaWxsU2xvdDsKKyAgfQorCisgIC8vLyBcc2VlIFN0YWNrSUQKKyAgdWludDhfdCBnZXRTdGFja0lEKGludCBPYmplY3RJZHgpIGNvbnN0IHsKKyAgICByZXR1cm4gT2JqZWN0c1tPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzXS5TdGFja0lEOworICB9CisKKyAgLy8vIFxzZWUgU3RhY2tJRAorICB2b2lkIHNldFN0YWNrSUQoaW50IE9iamVjdElkeCwgdWludDhfdCBJRCkgeworICAgIGFzc2VydCh1bnNpZ25lZChPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzKSA8IE9iamVjdHMuc2l6ZSgpICYmCisgICAgICAgICAgICJJbnZhbGlkIE9iamVjdCBJZHghIik7CisgICAgT2JqZWN0c1tPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzXS5TdGFja0lEID0gSUQ7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgaW5kZXggY29ycmVzcG9uZHMgdG8gYSBkZWFkIG9iamVjdC4KKyAgYm9vbCBpc0RlYWRPYmplY3RJbmRleChpbnQgT2JqZWN0SWR4KSBjb25zdCB7CisgICAgYXNzZXJ0KHVuc2lnbmVkKE9iamVjdElkeCtOdW1GaXhlZE9iamVjdHMpIDwgT2JqZWN0cy5zaXplKCkgJiYKKyAgICAgICAgICAgIkludmFsaWQgT2JqZWN0IElkeCEiKTsKKyAgICByZXR1cm4gT2JqZWN0c1tPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzXS5TaXplID09IH4wVUxMOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGluZGV4IGNvcnJlc3BvbmRzIHRvIGEgdmFyaWFibGUgc2l6ZWQKKyAgLy8vIG9iamVjdC4KKyAgYm9vbCBpc1ZhcmlhYmxlU2l6ZWRPYmplY3RJbmRleChpbnQgT2JqZWN0SWR4KSBjb25zdCB7CisgICAgYXNzZXJ0KHVuc2lnbmVkKE9iamVjdElkeCArIE51bUZpeGVkT2JqZWN0cykgPCBPYmplY3RzLnNpemUoKSAmJgorICAgICAgICAgICAiSW52YWxpZCBPYmplY3QgSWR4ISIpOworICAgIHJldHVybiBPYmplY3RzW09iamVjdElkeCArIE51bUZpeGVkT2JqZWN0c10uU2l6ZSA9PSAwOworICB9CisKKyAgdm9pZCBtYXJrQXNTdGF0ZXBvaW50U3BpbGxTbG90T2JqZWN0SW5kZXgoaW50IE9iamVjdElkeCkgeworICAgIGFzc2VydCh1bnNpZ25lZChPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzKSA8IE9iamVjdHMuc2l6ZSgpICYmCisgICAgICAgICAgICJJbnZhbGlkIE9iamVjdCBJZHghIik7CisgICAgT2JqZWN0c1tPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzXS5pc1N0YXRlcG9pbnRTcGlsbFNsb3QgPSB0cnVlOworICAgIGFzc2VydChpc1N0YXRlcG9pbnRTcGlsbFNsb3RPYmplY3RJbmRleChPYmplY3RJZHgpICYmICJpbmNvbnNpc3RlbnQiKTsKKyAgfQorCisgIC8vLyBDcmVhdGUgYSBuZXcgc3RhdGljYWxseSBzaXplZCBzdGFjayBvYmplY3QsIHJldHVybmluZworICAvLy8gYSBub25uZWdhdGl2ZSBpZGVudGlmaWVyIHRvIHJlcHJlc2VudCBpdC4KKyAgaW50IENyZWF0ZVN0YWNrT2JqZWN0KHVpbnQ2NF90IFNpemUsIHVuc2lnbmVkIEFsaWdubWVudCwgYm9vbCBpc1NwaWxsU2xvdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFsbG9jYUluc3QgKkFsbG9jYSA9IG51bGxwdHIsIHVpbnQ4X3QgSUQgPSAwKTsKKworICAvLy8gQ3JlYXRlIGEgbmV3IHN0YXRpY2FsbHkgc2l6ZWQgc3RhY2sgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhIHNwaWxsIHNsb3QsCisgIC8vLyByZXR1cm5pbmcgYSBub25uZWdhdGl2ZSBpZGVudGlmaWVyIHRvIHJlcHJlc2VudCBpdC4KKyAgaW50IENyZWF0ZVNwaWxsU3RhY2tPYmplY3QodWludDY0X3QgU2l6ZSwgdW5zaWduZWQgQWxpZ25tZW50KTsKKworICAvLy8gUmVtb3ZlIG9yIG1hcmsgZGVhZCBhIHN0YXRpY2FsbHkgc2l6ZWQgc3RhY2sgb2JqZWN0LgorICB2b2lkIFJlbW92ZVN0YWNrT2JqZWN0KGludCBPYmplY3RJZHgpIHsKKyAgICAvLyBNYXJrIGl0IGRlYWQuCisgICAgT2JqZWN0c1tPYmplY3RJZHgrTnVtRml4ZWRPYmplY3RzXS5TaXplID0gfjBVTEw7CisgIH0KKworICAvLy8gTm90aWZ5IHRoZSBNYWNoaW5lRnJhbWVJbmZvIG9iamVjdCB0aGF0IGEgdmFyaWFibGUgc2l6ZWQgb2JqZWN0IGhhcyBiZWVuCisgIC8vLyBjcmVhdGVkLiAgVGhpcyBtdXN0IGJlIGNyZWF0ZWQgd2hlbmV2ZXIgYSB2YXJpYWJsZSBzaXplZCBvYmplY3QgaXMKKyAgLy8vIGNyZWF0ZWQsIHdoZXRoZXIgb3Igbm90IHRoZSBpbmRleCByZXR1cm5lZCBpcyBhY3R1YWxseSB1c2VkLgorICBpbnQgQ3JlYXRlVmFyaWFibGVTaXplZE9iamVjdCh1bnNpZ25lZCBBbGlnbm1lbnQsIGNvbnN0IEFsbG9jYUluc3QgKkFsbG9jYSk7CisKKyAgLy8vIFJldHVybnMgYSByZWZlcmVuY2UgdG8gY2FsbCBzYXZlZCBpbmZvIHZlY3RvciBmb3IgdGhlIGN1cnJlbnQgZnVuY3Rpb24uCisgIGNvbnN0IHN0ZDo6dmVjdG9yPENhbGxlZVNhdmVkSW5mbz4gJmdldENhbGxlZVNhdmVkSW5mbygpIGNvbnN0IHsKKyAgICByZXR1cm4gQ1NJbmZvOworICB9CisgIC8vLyBcY29weWRvYyBnZXRDYWxsZWVTYXZlZEluZm8oKQorICBzdGQ6OnZlY3RvcjxDYWxsZWVTYXZlZEluZm8+ICZnZXRDYWxsZWVTYXZlZEluZm8oKSB7IHJldHVybiBDU0luZm87IH0KKworICAvLy8gVXNlZCBieSBwcm9sb2cvZXBpbG9nIGluc2VydGVyIHRvIHNldCB0aGUgZnVuY3Rpb24ncyBjYWxsZWUgc2F2ZWQKKyAgLy8vIGluZm9ybWF0aW9uLgorICB2b2lkIHNldENhbGxlZVNhdmVkSW5mbyhjb25zdCBzdGQ6OnZlY3RvcjxDYWxsZWVTYXZlZEluZm8+ICZDU0kpIHsKKyAgICBDU0luZm8gPSBDU0k7CisgIH0KKworICAvLy8gSGFzIHRoZSBjYWxsZWUgc2F2ZWQgaW5mbyBiZWVuIGNhbGN1bGF0ZWQgeWV0PworICBib29sIGlzQ2FsbGVlU2F2ZWRJbmZvVmFsaWQoKSBjb25zdCB7IHJldHVybiBDU0lWYWxpZDsgfQorCisgIHZvaWQgc2V0Q2FsbGVlU2F2ZWRJbmZvVmFsaWQoYm9vbCB2KSB7IENTSVZhbGlkID0gdjsgfQorCisgIE1hY2hpbmVCYXNpY0Jsb2NrICpnZXRTYXZlUG9pbnQoKSBjb25zdCB7IHJldHVybiBTYXZlOyB9CisgIHZvaWQgc2V0U2F2ZVBvaW50KE1hY2hpbmVCYXNpY0Jsb2NrICpOZXdTYXZlKSB7IFNhdmUgPSBOZXdTYXZlOyB9CisgIE1hY2hpbmVCYXNpY0Jsb2NrICpnZXRSZXN0b3JlUG9pbnQoKSBjb25zdCB7IHJldHVybiBSZXN0b3JlOyB9CisgIHZvaWQgc2V0UmVzdG9yZVBvaW50KE1hY2hpbmVCYXNpY0Jsb2NrICpOZXdSZXN0b3JlKSB7IFJlc3RvcmUgPSBOZXdSZXN0b3JlOyB9CisKKyAgLy8vIFJldHVybiBhIHNldCBvZiBwaHlzaWNhbCByZWdpc3RlcnMgdGhhdCBhcmUgcHJpc3RpbmUuCisgIC8vLworICAvLy8gUHJpc3RpbmUgcmVnaXN0ZXJzIGhvbGQgYSB2YWx1ZSB0aGF0IGlzIHVzZWxlc3MgdG8gdGhlIGN1cnJlbnQgZnVuY3Rpb24sCisgIC8vLyBidXQgdGhhdCBtdXN0IGJlIHByZXNlcnZlZCAtIHRoZXkgYXJlIGNhbGxlZSBzYXZlZCByZWdpc3RlcnMgdGhhdCBhcmUgbm90CisgIC8vLyBzYXZlZC4KKyAgLy8vCisgIC8vLyBCZWZvcmUgdGhlIFByb2xvZ3VlRXBpbG9ndWVJbnNlcnRlciBoYXMgcGxhY2VkIHRoZSBDU1Igc3BpbGwgY29kZSwgdGhpcworICAvLy8gbWV0aG9kIGFsd2F5cyByZXR1cm5zIGFuIGVtcHR5IHNldC4KKyAgQml0VmVjdG9yIGdldFByaXN0aW5lUmVncyhjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKSBjb25zdDsKKworICAvLy8gVXNlZCBieSB0aGUgTWFjaGluZUZ1bmN0aW9uIHByaW50ZXIgdG8gcHJpbnQgaW5mb3JtYXRpb24gYWJvdXQKKyAgLy8vIHN0YWNrIG9iamVjdHMuIEltcGxlbWVudGVkIGluIE1hY2hpbmVGdW5jdGlvbi5jcHAuCisgIHZvaWQgcHJpbnQoY29uc3QgTWFjaGluZUZ1bmN0aW9uICZNRiwgcmF3X29zdHJlYW0gJk9TKSBjb25zdDsKKworICAvLy8gZHVtcCAtIFByaW50IHRoZSBmdW5jdGlvbiB0byBzdGRlcnIuCisgIHZvaWQgZHVtcChjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKSBjb25zdDsKK307CisKK30gLy8gRW5kIGxsdm0gbmFtZXNwYWNlCisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvbi5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvbi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdkOGI3ZWIKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uLmgKQEAgLTAsMCArMSw5NDggQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uLmggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gQ29sbGVjdCBuYXRpdmUgbWFjaGluZSBjb2RlIGZvciBhIGZ1bmN0aW9uLiAgVGhpcyBjbGFzcyBjb250YWlucyBhIGxpc3Qgb2YKKy8vIE1hY2hpbmVCYXNpY0Jsb2NrIGluc3RhbmNlcyB0aGF0IG1ha2UgdXAgdGhlIGN1cnJlbnQgY29tcGlsZWQgZnVuY3Rpb24uCisvLworLy8gVGhpcyBjbGFzcyBhbHNvIGNvbnRhaW5zIHBvaW50ZXJzIHRvIHZhcmlvdXMgY2xhc3NlcyB3aGljaCBob2xkCisvLyB0YXJnZXQtc3BlY2lmaWMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGdlbmVyYXRlZCBjb2RlLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ0hJTkVGVU5DVElPTl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9NQUNISU5FRlVOQ1RJT05fSAorCisjaW5jbHVkZSAibGx2bS9BRFQvQXJyYXlSZWYuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9CaXRWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9EZW5zZU1hcC5oIgorI2luY2x1ZGUgImxsdm0vQURUL0dyYXBoVHJhaXRzLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvT3B0aW9uYWwuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQURUL1N0cmluZ1JlZi5oIgorI2luY2x1ZGUgImxsdm0vQURUL2lsaXN0LmgiCisjaW5jbHVkZSAibGx2bS9BRFQvaXRlcmF0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FuYWx5c2lzL0VIUGVyc29uYWxpdGllcy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lQmFzaWNCbG9jay5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lSW5zdHIuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZU1lbU9wZXJhbmQuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0RlYnVnTG9jLmgiCisjaW5jbHVkZSAibGx2bS9JUi9JbnN0cnVjdGlvbnMuaCIKKyNpbmNsdWRlICJsbHZtL0lSL01ldGFkYXRhLmgiCisjaW5jbHVkZSAibGx2bS9NQy9NQ0R3YXJmLmgiCisjaW5jbHVkZSAibGx2bS9NQy9NQ1N5bWJvbC5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9BbGxvY2F0b3IuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvQXJyYXlSZWN5Y2xlci5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9BdG9taWNPcmRlcmluZy5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9Db21waWxlci5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9FcnJvckhhbmRsaW5nLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L1JlY3ljbGVyLmgiCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpbmNsdWRlIDx1dGlsaXR5PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBCYXNpY0Jsb2NrOworY2xhc3MgQmxvY2tBZGRyZXNzOworY2xhc3MgRGF0YUxheW91dDsKK2NsYXNzIERJRXhwcmVzc2lvbjsKK2NsYXNzIERJTG9jYWxWYXJpYWJsZTsKK2NsYXNzIERJTG9jYXRpb247CitjbGFzcyBGdW5jdGlvbjsKK2NsYXNzIEdsb2JhbFZhbHVlOworY2xhc3MgTWFjaGluZUNvbnN0YW50UG9vbDsKK2NsYXNzIE1hY2hpbmVGcmFtZUluZm87CitjbGFzcyBNYWNoaW5lRnVuY3Rpb247CitjbGFzcyBNYWNoaW5lSnVtcFRhYmxlSW5mbzsKK2NsYXNzIE1hY2hpbmVNb2R1bGVJbmZvOworY2xhc3MgTWFjaGluZVJlZ2lzdGVySW5mbzsKK2NsYXNzIE1DQ29udGV4dDsKK2NsYXNzIE1DSW5zdHJEZXNjOworY2xhc3MgUGFzczsKK2NsYXNzIFBzZXVkb1NvdXJjZVZhbHVlTWFuYWdlcjsKK2NsYXNzIHJhd19vc3RyZWFtOworY2xhc3MgU2xvdEluZGV4ZXM7CitjbGFzcyBUYXJnZXRNYWNoaW5lOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJDbGFzczsKK2NsYXNzIFRhcmdldFN1YnRhcmdldEluZm87CitzdHJ1Y3QgV2luRUhGdW5jSW5mbzsKKwordGVtcGxhdGUgPD4gc3RydWN0IGlsaXN0X2FsbG9jX3RyYWl0czxNYWNoaW5lQmFzaWNCbG9jaz4geworICB2b2lkIGRlbGV0ZU5vZGUoTWFjaGluZUJhc2ljQmxvY2sgKk1CQik7Cit9OworCit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgaWxpc3RfY2FsbGJhY2tfdHJhaXRzPE1hY2hpbmVCYXNpY0Jsb2NrPiB7CisgIHZvaWQgYWRkTm9kZVRvTGlzdChNYWNoaW5lQmFzaWNCbG9jayogTUJCKTsKKyAgdm9pZCByZW1vdmVOb2RlRnJvbUxpc3QoTWFjaGluZUJhc2ljQmxvY2sqIE1CQik7CisKKyAgdGVtcGxhdGUgPGNsYXNzIEl0ZXJhdG9yPgorICB2b2lkIHRyYW5zZmVyTm9kZXNGcm9tTGlzdChpbGlzdF9jYWxsYmFja190cmFpdHMgJk9sZExpc3QsIEl0ZXJhdG9yLCBJdGVyYXRvcikgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIk5ldmVyIHRyYW5zZmVyIGJldHdlZW4gbGlzdHMiKTsKKyAgfQorfTsKKworLy8vIE1hY2hpbmVGdW5jdGlvbkluZm8gLSBUaGlzIGNsYXNzIGNhbiBiZSBkZXJpdmVkIGZyb20gYW5kIHVzZWQgYnkgdGFyZ2V0cyB0bworLy8vIGhvbGQgcHJpdmF0ZSB0YXJnZXQtc3BlY2lmaWMgaW5mb3JtYXRpb24gZm9yIGVhY2ggTWFjaGluZUZ1bmN0aW9uLiAgT2JqZWN0cworLy8vIG9mIHR5cGUgYXJlIGFjY2Vzc2VkL2NyZWF0ZWQgd2l0aCBNRjo6Z2V0SW5mbyBhbmQgZGVzdHJveWVkIHdoZW4gdGhlCisvLy8gTWFjaGluZUZ1bmN0aW9uIGlzIGRlc3Ryb3llZC4KK3N0cnVjdCBNYWNoaW5lRnVuY3Rpb25JbmZvIHsKKyAgdmlydHVhbCB+TWFjaGluZUZ1bmN0aW9uSW5mbygpOworCisgIC8vLyBcYnJpZWYgRmFjdG9yeSBmdW5jdGlvbjogZGVmYXVsdCBiZWhhdmlvciBpcyB0byBjYWxsIG5ldyB1c2luZyB0aGUKKyAgLy8vIHN1cHBsaWVkIGFsbG9jYXRvci4KKyAgLy8vCisgIC8vLyBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBvdmVycmlkZGVuIGluIGEgZGVyaXZlIGNsYXNzLgorICB0ZW1wbGF0ZTx0eXBlbmFtZSBUeT4KKyAgc3RhdGljIFR5ICpjcmVhdGUoQnVtcFB0ckFsbG9jYXRvciAmQWxsb2NhdG9yLCBNYWNoaW5lRnVuY3Rpb24gJk1GKSB7CisgICAgcmV0dXJuIG5ldyAoQWxsb2NhdG9yLkFsbG9jYXRlPFR5PigpKSBUeShNRik7CisgIH0KK307CisKKy8vLyBQcm9wZXJ0aWVzIHdoaWNoIGEgTWFjaGluZUZ1bmN0aW9uIG1heSBoYXZlIGF0IGEgZ2l2ZW4gcG9pbnQgaW4gdGltZS4KKy8vLyBFYWNoIG9mIHRoZXNlIGhhcyBjaGVja2luZyBjb2RlIGluIHRoZSBNYWNoaW5lVmVyaWZpZXIsIGFuZCBwYXNzZXMgY2FuCisvLy8gcmVxdWlyZSB0aGF0IGEgcHJvcGVydHkgYmUgc2V0LgorY2xhc3MgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcyB7CisgIC8vIFBvc3NpYmxlIFRPRE86IEFsbG93IHRhcmdldHMgdG8gZXh0ZW5kIHRoaXMgKHBlcmhhcHMgYnkgYWxsb3dpbmcgdGhlCisgIC8vIGNvbnN0cnVjdG9yIHRvIHNwZWNpZnkgdGhlIHNpemUgb2YgdGhlIGJpdCB2ZWN0b3IpCisgIC8vIFBvc3NpYmxlIFRPRE86IEFsbG93IHJlcXVpcmluZyB0aGUgbmVnYXRpdmUgKGUuZy4gVlJlZ3NBbGxvY2F0ZWQgY291bGQgYmUKKyAgLy8gc3RhdGVkIGFzIHRoZSBuZWdhdGl2ZSBvZiAiaGFzIHZyZWdzIgorCitwdWJsaWM6CisgIC8vIFRoZSBwcm9wZXJ0aWVzIGFyZSBzdGF0ZWQgaW4gInBvc2l0aXZlIiBmb3JtOyBpLmUuIGEgcGFzcyBjb3VsZCByZXF1aXJlCisgIC8vIHRoYXQgdGhlIHByb3BlcnR5IGhvbGQsIGJ1dCBub3QgdGhhdCBpdCBkb2VzIG5vdCBob2xkLgorCisgIC8vIFByb3BlcnR5IGRlc2NyaXB0aW9uczoKKyAgLy8gSXNTU0E6IFRydWUgd2hlbiB0aGUgbWFjaGluZSBmdW5jdGlvbiBpcyBpbiBTU0EgZm9ybSBhbmQgdmlydHVhbCByZWdpc3RlcnMKKyAgLy8gIGhhdmUgYSBzaW5nbGUgZGVmLgorICAvLyBOb1BISXM6IFRoZSBtYWNoaW5lIGZ1bmN0aW9uIGRvZXMgbm90IGNvbnRhaW4gYW55IFBISSBpbnN0cnVjdGlvbi4KKyAgLy8gVHJhY2tzTGl2ZW5lc3M6IFRydWUgd2hlbiB0cmFja2luZyByZWdpc3RlciBsaXZlbmVzcyBhY2N1cmF0ZWx5LgorICAvLyAgV2hpbGUgdGhpcyBwcm9wZXJ0eSBpcyBzZXQsIHJlZ2lzdGVyIGxpdmVuZXNzIGluZm9ybWF0aW9uIGluIGJhc2ljIGJsb2NrCisgIC8vICBsaXZlLWluIGxpc3RzIGFuZCBtYWNoaW5lIGluc3RydWN0aW9uIG9wZXJhbmRzIChlLmcuIGtpbGwgZmxhZ3MsIGltcGxpY2l0CisgIC8vICBkZWZzKSBpcyBhY2N1cmF0ZS4gVGhpcyBtZWFucyBpdCBjYW4gYmUgdXNlZCB0byBjaGFuZ2UgdGhlIGNvZGUgaW4gd2F5cworICAvLyAgdGhhdCBhZmZlY3QgdGhlIHZhbHVlcyBpbiByZWdpc3RlcnMsIGZvciBleGFtcGxlIGJ5IHRoZSByZWdpc3RlcgorICAvLyAgc2NhdmVuZ2VyLgorICAvLyAgV2hlbiB0aGlzIHByb3BlcnR5IGlzIGNsZWFyLCBsaXZlbmVzcyBpcyBubyBsb25nZXIgcmVsaWFibGUuCisgIC8vIE5vVlJlZ3M6IFRoZSBtYWNoaW5lIGZ1bmN0aW9uIGRvZXMgbm90IHVzZSBhbnkgdmlydHVhbCByZWdpc3RlcnMuCisgIC8vIExlZ2FsaXplZDogSW4gR2xvYmFsSVNlbDogdGhlIE1hY2hpbmVMZWdhbGl6ZXIgcmFuIGFuZCBhbGwgcHJlLWlzZWwgZ2VuZXJpYworICAvLyAgaW5zdHJ1Y3Rpb25zIGhhdmUgYmVlbiBsZWdhbGl6ZWQ7IGkuZS4sIGFsbCBpbnN0cnVjdGlvbnMgYXJlIG5vdyBvbmUgb2Y6CisgIC8vICAgLSBnZW5lcmljIGFuZCBhbHdheXMgbGVnYWwgKGUuZy4sIENPUFkpCisgIC8vICAgLSB0YXJnZXQtc3BlY2lmaWMKKyAgLy8gICAtIGxlZ2FsIHByZS1pc2VsIGdlbmVyaWMgaW5zdHJ1Y3Rpb25zLgorICAvLyBSZWdCYW5rU2VsZWN0ZWQ6IEluIEdsb2JhbElTZWw6IHRoZSBSZWdCYW5rU2VsZWN0IHBhc3MgcmFuIGFuZCBhbGwgZ2VuZXJpYworICAvLyAgdmlydHVhbCByZWdpc3RlcnMgaGF2ZSBiZWVuIGFzc2lnbmVkIHRvIGEgcmVnaXN0ZXIgYmFuay4KKyAgLy8gU2VsZWN0ZWQ6IEluIEdsb2JhbElTZWw6IHRoZSBJbnN0cnVjdGlvblNlbGVjdCBwYXNzIHJhbiBhbmQgYWxsIHByZS1pc2VsCisgIC8vICBnZW5lcmljIGluc3RydWN0aW9ucyBoYXZlIGJlZW4gZWxpbWluYXRlZDsgaS5lLiwgYWxsIGluc3RydWN0aW9ucyBhcmUgbm93CisgIC8vICB0YXJnZXQtc3BlY2lmaWMgb3Igbm9uLXByZS1pc2VsIGdlbmVyaWMgaW5zdHJ1Y3Rpb25zIChlLmcuLCBDT1BZKS4KKyAgLy8gIFNpbmNlIG9ubHkgcHJlLWlzZWwgZ2VuZXJpYyBpbnN0cnVjdGlvbnMgY2FuIGhhdmUgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVyCisgIC8vICBvcGVyYW5kcywgdGhpcyBhbHNvIG1lYW5zIHRoYXQgYWxsIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlcnMgaGF2ZSBiZWVuCisgIC8vICBjb25zdHJhaW5lZCB0byB2aXJ0dWFsIHJlZ2lzdGVycyAoYXNzaWduZWQgdG8gcmVnaXN0ZXIgY2xhc3NlcykgYW5kIHRoYXQKKyAgLy8gIGFsbCBzaXplcyBhdHRhY2hlZCB0byB0aGVtIGhhdmUgYmVlbiBlbGltaW5hdGVkLgorICBlbnVtIGNsYXNzIFByb3BlcnR5IDogdW5zaWduZWQgeworICAgIElzU1NBLAorICAgIE5vUEhJcywKKyAgICBUcmFja3NMaXZlbmVzcywKKyAgICBOb1ZSZWdzLAorICAgIEZhaWxlZElTZWwsCisgICAgTGVnYWxpemVkLAorICAgIFJlZ0JhbmtTZWxlY3RlZCwKKyAgICBTZWxlY3RlZCwKKyAgICBMYXN0UHJvcGVydHkgPSBTZWxlY3RlZCwKKyAgfTsKKworICBib29sIGhhc1Byb3BlcnR5KFByb3BlcnR5IFApIGNvbnN0IHsKKyAgICByZXR1cm4gUHJvcGVydGllc1tzdGF0aWNfY2FzdDx1bnNpZ25lZD4oUCldOworICB9CisKKyAgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcyAmc2V0KFByb3BlcnR5IFApIHsKKyAgICBQcm9wZXJ0aWVzLnNldChzdGF0aWNfY2FzdDx1bnNpZ25lZD4oUCkpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMgJnJlc2V0KFByb3BlcnR5IFApIHsKKyAgICBQcm9wZXJ0aWVzLnJlc2V0KHN0YXRpY19jYXN0PHVuc2lnbmVkPihQKSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgLy8vIFJlc2V0IGFsbCB0aGUgcHJvcGVydGllcy4KKyAgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcyAmcmVzZXQoKSB7CisgICAgUHJvcGVydGllcy5yZXNldCgpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMgJnNldChjb25zdCBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzICZNRlApIHsKKyAgICBQcm9wZXJ0aWVzIHw9IE1GUC5Qcm9wZXJ0aWVzOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMgJnJlc2V0KGNvbnN0IE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMgJk1GUCkgeworICAgIFByb3BlcnRpZXMucmVzZXQoTUZQLlByb3BlcnRpZXMpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIC8vIFJldHVybnMgdHJ1ZSBpZiBhbGwgcHJvcGVydGllcyBzZXQgaW4gViAoaS5lLiByZXF1aXJlZCBieSBhIHBhc3MpIGFyZSBzZXQKKyAgLy8gaW4gdGhpcy4KKyAgYm9vbCB2ZXJpZnlSZXF1aXJlZFByb3BlcnRpZXMoY29uc3QgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcyAmVikgY29uc3QgeworICAgIHJldHVybiAhVi5Qcm9wZXJ0aWVzLnRlc3QoUHJvcGVydGllcyk7CisgIH0KKworICAvLy8gUHJpbnQgdGhlIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMgaW4gaHVtYW4tcmVhZGFibGUgZm9ybS4KKyAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MpIGNvbnN0OworCitwcml2YXRlOgorICBCaXRWZWN0b3IgUHJvcGVydGllcyA9CisgICAgICBCaXRWZWN0b3Ioc3RhdGljX2Nhc3Q8dW5zaWduZWQ+KFByb3BlcnR5OjpMYXN0UHJvcGVydHkpKzEpOworfTsKKworc3RydWN0IFNFSEhhbmRsZXIgeworICAvLy8gRmlsdGVyIG9yIGZpbmFsbHkgZnVuY3Rpb24uIE51bGwgaW5kaWNhdGVzIGEgY2F0Y2gtYWxsLgorICBjb25zdCBGdW5jdGlvbiAqRmlsdGVyT3JGaW5hbGx5OworCisgIC8vLyBBZGRyZXNzIG9mIGJsb2NrIHRvIHJlY292ZXIgYXQuIE51bGwgZm9yIGEgZmluYWxseSBoYW5kbGVyLgorICBjb25zdCBCbG9ja0FkZHJlc3MgKlJlY292ZXJCQTsKK307CisKKy8vLyBUaGlzIHN0cnVjdHVyZSBpcyB1c2VkIHRvIHJldGFpbiBsYW5kaW5nIHBhZCBpbmZvIGZvciB0aGUgY3VycmVudCBmdW5jdGlvbi4KK3N0cnVjdCBMYW5kaW5nUGFkSW5mbyB7CisgIE1hY2hpbmVCYXNpY0Jsb2NrICpMYW5kaW5nUGFkQmxvY2s7ICAgICAgLy8gTGFuZGluZyBwYWQgYmxvY2suCisgIFNtYWxsVmVjdG9yPE1DU3ltYm9sICosIDE+IEJlZ2luTGFiZWxzOyAgLy8gTGFiZWxzIHByaW9yIHRvIGludm9rZS4KKyAgU21hbGxWZWN0b3I8TUNTeW1ib2wgKiwgMT4gRW5kTGFiZWxzOyAgICAvLyBMYWJlbHMgYWZ0ZXIgaW52b2tlLgorICBTbWFsbFZlY3RvcjxTRUhIYW5kbGVyLCAxPiBTRUhIYW5kbGVyczsgIC8vIFNFSCBoYW5kbGVycyBhY3RpdmUgYXQgdGhpcyBscGFkLgorICBNQ1N5bWJvbCAqTGFuZGluZ1BhZExhYmVsID0gbnVsbHB0cjsgICAgIC8vIExhYmVsIGF0IGJlZ2lubmluZyBvZiBsYW5kaW5nIHBhZC4KKyAgc3RkOjp2ZWN0b3I8aW50PiBUeXBlSWRzOyAgICAgICAgICAgICAgICAvLyBMaXN0IG9mIHR5cGUgaWRzIChmaWx0ZXJzIG5lZ2F0aXZlKS4KKworICBleHBsaWNpdCBMYW5kaW5nUGFkSW5mbyhNYWNoaW5lQmFzaWNCbG9jayAqTUJCKQorICAgICAgOiBMYW5kaW5nUGFkQmxvY2soTUJCKSB7fQorfTsKKworY2xhc3MgTWFjaGluZUZ1bmN0aW9uIHsKKyAgY29uc3QgRnVuY3Rpb24gJkY7CisgIGNvbnN0IFRhcmdldE1hY2hpbmUgJlRhcmdldDsKKyAgY29uc3QgVGFyZ2V0U3VidGFyZ2V0SW5mbyAqU1RJOworICBNQ0NvbnRleHQgJkN0eDsKKyAgTWFjaGluZU1vZHVsZUluZm8gJk1NSTsKKworICAvLyBSZWdJbmZvIC0gSW5mb3JtYXRpb24gYWJvdXQgZWFjaCByZWdpc3RlciBpbiB1c2UgaW4gdGhlIGZ1bmN0aW9uLgorICBNYWNoaW5lUmVnaXN0ZXJJbmZvICpSZWdJbmZvOworCisgIC8vIFVzZWQgdG8ga2VlcCB0cmFjayBvZiB0YXJnZXQtc3BlY2lmaWMgcGVyLW1hY2hpbmUgZnVuY3Rpb24gaW5mb3JtYXRpb24gZm9yCisgIC8vIHRoZSB0YXJnZXQgaW1wbGVtZW50YXRpb24uCisgIE1hY2hpbmVGdW5jdGlvbkluZm8gKk1GSW5mbzsKKworICAvLyBLZWVwIHRyYWNrIG9mIG9iamVjdHMgYWxsb2NhdGVkIG9uIHRoZSBzdGFjay4KKyAgTWFjaGluZUZyYW1lSW5mbyAqRnJhbWVJbmZvOworCisgIC8vIEtlZXAgdHJhY2sgb2YgY29uc3RhbnRzIHdoaWNoIGFyZSBzcGlsbGVkIHRvIG1lbW9yeQorICBNYWNoaW5lQ29uc3RhbnRQb29sICpDb25zdGFudFBvb2w7CisKKyAgLy8gS2VlcCB0cmFjayBvZiBqdW1wIHRhYmxlcyBmb3Igc3dpdGNoIGluc3RydWN0aW9ucworICBNYWNoaW5lSnVtcFRhYmxlSW5mbyAqSnVtcFRhYmxlSW5mbzsKKworICAvLyBLZWVwcyB0cmFjayBvZiBXaW5kb3dzIGV4Y2VwdGlvbiBoYW5kbGluZyByZWxhdGVkIGRhdGEuIFRoaXMgd2lsbCBiZSBudWxsCisgIC8vIGZvciBmdW5jdGlvbnMgdGhhdCBhcmVuJ3QgdXNpbmcgYSBmdW5jbGV0LWJhc2VkIEVIIHBlcnNvbmFsaXR5LgorICBXaW5FSEZ1bmNJbmZvICpXaW5FSEluZm8gPSBudWxscHRyOworCisgIC8vIEZ1bmN0aW9uLWxldmVsIHVuaXF1ZSBudW1iZXJpbmcgZm9yIE1hY2hpbmVCYXNpY0Jsb2Nrcy4gIFdoZW4gYQorICAvLyBNYWNoaW5lQmFzaWNCbG9jayBpcyBpbnNlcnRlZCBpbnRvIGEgTWFjaGluZUZ1bmN0aW9uIGlzIGl0IGF1dG9tYXRpY2FsbHkKKyAgLy8gbnVtYmVyZWQgYW5kIHRoaXMgdmVjdG9yIGtlZXBzIHRyYWNrIG9mIHRoZSBtYXBwaW5nIGZyb20gSUQncyB0byBNQkIncy4KKyAgc3RkOjp2ZWN0b3I8TWFjaGluZUJhc2ljQmxvY2sqPiBNQkJOdW1iZXJpbmc7CisKKyAgLy8gUG9vbC1hbGxvY2F0ZSBNYWNoaW5lRnVuY3Rpb24tbGlmZXRpbWUgYW5kIElSIG9iamVjdHMuCisgIEJ1bXBQdHJBbGxvY2F0b3IgQWxsb2NhdG9yOworCisgIC8vIEFsbG9jYXRpb24gbWFuYWdlbWVudCBmb3IgaW5zdHJ1Y3Rpb25zIGluIGZ1bmN0aW9uLgorICBSZWN5Y2xlcjxNYWNoaW5lSW5zdHI+IEluc3RydWN0aW9uUmVjeWNsZXI7CisKKyAgLy8gQWxsb2NhdGlvbiBtYW5hZ2VtZW50IGZvciBvcGVyYW5kIGFycmF5cyBvbiBpbnN0cnVjdGlvbnMuCisgIEFycmF5UmVjeWNsZXI8TWFjaGluZU9wZXJhbmQ+IE9wZXJhbmRSZWN5Y2xlcjsKKworICAvLyBBbGxvY2F0aW9uIG1hbmFnZW1lbnQgZm9yIGJhc2ljIGJsb2NrcyBpbiBmdW5jdGlvbi4KKyAgUmVjeWNsZXI8TWFjaGluZUJhc2ljQmxvY2s+IEJhc2ljQmxvY2tSZWN5Y2xlcjsKKworICAvLyBMaXN0IG9mIG1hY2hpbmUgYmFzaWMgYmxvY2tzIGluIGZ1bmN0aW9uCisgIHVzaW5nIEJhc2ljQmxvY2tMaXN0VHlwZSA9IGlsaXN0PE1hY2hpbmVCYXNpY0Jsb2NrPjsKKyAgQmFzaWNCbG9ja0xpc3RUeXBlIEJhc2ljQmxvY2tzOworCisgIC8vLyBGdW5jdGlvbk51bWJlciAtIFRoaXMgcHJvdmlkZXMgYSB1bmlxdWUgSUQgZm9yIGVhY2ggZnVuY3Rpb24gZW1pdHRlZCBpbgorICAvLy8gdGhpcyB0cmFuc2xhdGlvbiB1bml0LgorICAvLy8KKyAgdW5zaWduZWQgRnVuY3Rpb25OdW1iZXI7CisKKyAgLy8vIEFsaWdubWVudCAtIFRoZSBhbGlnbm1lbnQgb2YgdGhlIGZ1bmN0aW9uLgorICB1bnNpZ25lZCBBbGlnbm1lbnQ7CisKKyAgLy8vIEV4cG9zZXNSZXR1cm5zVHdpY2UgLSBUcnVlIGlmIHRoZSBmdW5jdGlvbiBjYWxscyBzZXRqbXAgb3IgcmVsYXRlZAorICAvLy8gZnVuY3Rpb25zIHdpdGggYXR0cmlidXRlICJyZXR1cm5zIHR3aWNlIiwgYnV0IGRvZXNuJ3QgaGF2ZQorICAvLy8gdGhlIGF0dHJpYnV0ZSBpdHNlbGYuCisgIC8vLyBUaGlzIGlzIHVzZWQgdG8gbGltaXQgb3B0aW1pemF0aW9ucyB3aGljaCBjYW5ub3QgcmVhc29uCisgIC8vLyBhYm91dCB0aGUgY29udHJvbCBmbG93IG9mIHN1Y2ggZnVuY3Rpb25zLgorICBib29sIEV4cG9zZXNSZXR1cm5zVHdpY2UgPSBmYWxzZTsKKworICAvLy8gVHJ1ZSBpZiB0aGUgZnVuY3Rpb24gaW5jbHVkZXMgYW55IGlubGluZSBhc3NlbWJseS4KKyAgYm9vbCBIYXNJbmxpbmVBc20gPSBmYWxzZTsKKworICAvLy8gVHJ1ZSBpZiBhbnkgV2luQ0ZJIGluc3RydWN0aW9uIGhhdmUgYmVlbiBlbWl0dGVkIGluIHRoaXMgZnVuY3Rpb24uCisgIE9wdGlvbmFsPGJvb2w+IEhhc1dpbkNGSTsKKworICAvLy8gQ3VycmVudCBoaWdoLWxldmVsIHByb3BlcnRpZXMgb2YgdGhlIElSIG9mIHRoZSBmdW5jdGlvbiAoZS5nLiBpcyBpbiBTU0EKKyAgLy8vIGZvcm0gb3Igd2hldGhlciByZWdpc3RlcnMgaGF2ZSBiZWVuIGFsbG9jYXRlZCkKKyAgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcyBQcm9wZXJ0aWVzOworCisgIC8vIEFsbG9jYXRpb24gbWFuYWdlbWVudCBmb3IgcHNldWRvIHNvdXJjZSB2YWx1ZXMuCisgIHN0ZDo6dW5pcXVlX3B0cjxQc2V1ZG9Tb3VyY2VWYWx1ZU1hbmFnZXI+IFBTVk1hbmFnZXI7CisKKyAgLy8vIExpc3Qgb2YgbW92ZXMgZG9uZSBieSBhIGZ1bmN0aW9uJ3MgcHJvbG9nLiAgVXNlZCB0byBjb25zdHJ1Y3QgZnJhbWUgbWFwcworICAvLy8gYnkgZGVidWcgYW5kIGV4Y2VwdGlvbiBoYW5kbGluZyBjb25zdW1lcnMuCisgIHN0ZDo6dmVjdG9yPE1DQ0ZJSW5zdHJ1Y3Rpb24+IEZyYW1lSW5zdHJ1Y3Rpb25zOworCisgIC8vLyBcbmFtZSBFeGNlcHRpb24gSGFuZGxpbmcKKyAgLy8vIFx7CisKKyAgLy8vIExpc3Qgb2YgTGFuZGluZ1BhZEluZm8gZGVzY3JpYmluZyB0aGUgbGFuZGluZyBwYWQgaW5mb3JtYXRpb24uCisgIHN0ZDo6dmVjdG9yPExhbmRpbmdQYWRJbmZvPiBMYW5kaW5nUGFkczsKKworICAvLy8gTWFwIGEgbGFuZGluZyBwYWQncyBFSCBzeW1ib2wgdG8gdGhlIGNhbGwgc2l0ZSBpbmRleGVzLgorICBEZW5zZU1hcDxNQ1N5bWJvbCosIFNtYWxsVmVjdG9yPHVuc2lnbmVkLCA0Pj4gTFBhZFRvQ2FsbFNpdGVNYXA7CisKKyAgLy8vIE1hcCBvZiBpbnZva2UgY2FsbCBzaXRlIGluZGV4IHZhbHVlcyB0byBhc3NvY2lhdGVkIGJlZ2luIEVIX0xBQkVMLgorICBEZW5zZU1hcDxNQ1N5bWJvbCosIHVuc2lnbmVkPiBDYWxsU2l0ZU1hcDsKKworICAvLy8gQ29kZVZpZXcgbGFiZWwgYW5ub3RhdGlvbnMuCisgIHN0ZDo6dmVjdG9yPHN0ZDo6cGFpcjxNQ1N5bWJvbCAqLCBNRE5vZGUgKj4+IENvZGVWaWV3QW5ub3RhdGlvbnM7CisKKyAgYm9vbCBDYWxsc0VIUmV0dXJuID0gZmFsc2U7CisgIGJvb2wgQ2FsbHNVbndpbmRJbml0ID0gZmFsc2U7CisgIGJvb2wgSGFzRUhGdW5jbGV0cyA9IGZhbHNlOworCisgIC8vLyBMaXN0IG9mIEMrKyBUeXBlSW5mbyB1c2VkLgorICBzdGQ6OnZlY3Rvcjxjb25zdCBHbG9iYWxWYWx1ZSAqPiBUeXBlSW5mb3M7CisKKyAgLy8vIExpc3Qgb2YgdHlwZWlkcyBlbmNvZGluZyBmaWx0ZXJzIHVzZWQuCisgIHN0ZDo6dmVjdG9yPHVuc2lnbmVkPiBGaWx0ZXJJZHM7CisKKyAgLy8vIExpc3Qgb2YgdGhlIGluZGljZXMgaW4gRmlsdGVySWRzIGNvcnJlc3BvbmRpbmcgdG8gZmlsdGVyIHRlcm1pbmF0b3JzLgorICBzdGQ6OnZlY3Rvcjx1bnNpZ25lZD4gRmlsdGVyRW5kczsKKworICBFSFBlcnNvbmFsaXR5IFBlcnNvbmFsaXR5VHlwZUNhY2hlID0gRUhQZXJzb25hbGl0eTo6VW5rbm93bjsKKworICAvLy8gXH0KKworICAvLy8gQ2xlYXIgYWxsIHRoZSBtZW1iZXJzIG9mIHRoaXMgTWFjaGluZUZ1bmN0aW9uLCBidXQgdGhlIG9uZXMgdXNlZAorICAvLy8gdG8gaW5pdGlhbGl6ZSBhZ2FpbiB0aGUgTWFjaGluZUZ1bmN0aW9uLgorICAvLy8gTW9yZSBzcGVjaWZpY2FsbHksIHRoaXMgZGVhbGxvY2F0ZXMgYWxsIHRoZSBkeW5hbWljYWxseSBhbGxvY2F0ZWQKKyAgLy8vIG9iamVjdHMgYW5kIGdldCByaWQgb2YgYWxsIHRoZSBYWFhJbmZvIGRhdGEgc3RydWN0dXJlLCBidXQga2VlcAorICAvLy8gdW5jaGFuZ2VkIHRoZSByZWZlcmVuY2VzIHRvIEZuLCBUYXJnZXQsIE1NSSwgYW5kIEZ1bmN0aW9uTnVtYmVyLgorICB2b2lkIGNsZWFyKCk7CisgIC8vLyBBbGxvY2F0ZSBhbmQgaW5pdGlhbGl6ZSB0aGUgZGlmZmVyZW50IG1lbWJlcnMuCisgIC8vLyBJbiBwYXJ0aWN1bGFyLCB0aGUgWFhYSW5mbyBkYXRhIHN0cnVjdHVyZS4KKyAgLy8vIFxwcmUgRm4sIFRhcmdldCwgTU1JLCBhbmQgRnVuY3Rpb25OdW1iZXIgYXJlIHByb3Blcmx5IHNldC4KKyAgdm9pZCBpbml0KCk7CisKK3B1YmxpYzoKKyAgc3RydWN0IFZhcmlhYmxlRGJnSW5mbyB7CisgICAgY29uc3QgRElMb2NhbFZhcmlhYmxlICpWYXI7CisgICAgY29uc3QgRElFeHByZXNzaW9uICpFeHByOworICAgIHVuc2lnbmVkIFNsb3Q7CisgICAgY29uc3QgRElMb2NhdGlvbiAqTG9jOworCisgICAgVmFyaWFibGVEYmdJbmZvKGNvbnN0IERJTG9jYWxWYXJpYWJsZSAqVmFyLCBjb25zdCBESUV4cHJlc3Npb24gKkV4cHIsCisgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFNsb3QsIGNvbnN0IERJTG9jYXRpb24gKkxvYykKKyAgICAgICAgOiBWYXIoVmFyKSwgRXhwcihFeHByKSwgU2xvdChTbG90KSwgTG9jKExvYykge30KKyAgfTsKKyAgdXNpbmcgVmFyaWFibGVEYmdJbmZvTWFwVHkgPSBTbWFsbFZlY3RvcjxWYXJpYWJsZURiZ0luZm8sIDQ+OworICBWYXJpYWJsZURiZ0luZm9NYXBUeSBWYXJpYWJsZURiZ0luZm9zOworCisgIE1hY2hpbmVGdW5jdGlvbihjb25zdCBGdW5jdGlvbiAmRiwgY29uc3QgVGFyZ2V0TWFjaGluZSAmVE0sCisgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRTdWJ0YXJnZXRJbmZvICZTVEksIHVuc2lnbmVkIEZ1bmN0aW9uTnVtLAorICAgICAgICAgICAgICAgICAgTWFjaGluZU1vZHVsZUluZm8gJk1NSSk7CisgIE1hY2hpbmVGdW5jdGlvbihjb25zdCBNYWNoaW5lRnVuY3Rpb24gJikgPSBkZWxldGU7CisgIE1hY2hpbmVGdW5jdGlvbiAmb3BlcmF0b3I9KGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmKSA9IGRlbGV0ZTsKKyAgfk1hY2hpbmVGdW5jdGlvbigpOworCisgIC8vLyBSZXNldCB0aGUgaW5zdGFuY2UgYXMgaWYgaXQgd2FzIGp1c3QgY3JlYXRlZC4KKyAgdm9pZCByZXNldCgpIHsKKyAgICBjbGVhcigpOworICAgIGluaXQoKTsKKyAgfQorCisgIE1hY2hpbmVNb2R1bGVJbmZvICZnZXRNTUkoKSBjb25zdCB7IHJldHVybiBNTUk7IH0KKyAgTUNDb250ZXh0ICZnZXRDb250ZXh0KCkgY29uc3QgeyByZXR1cm4gQ3R4OyB9CisKKyAgUHNldWRvU291cmNlVmFsdWVNYW5hZ2VyICZnZXRQU1ZNYW5hZ2VyKCkgY29uc3QgeyByZXR1cm4gKlBTVk1hbmFnZXI7IH0KKworICAvLy8gUmV0dXJuIHRoZSBEYXRhTGF5b3V0IGF0dGFjaGVkIHRvIHRoZSBNb2R1bGUgYXNzb2NpYXRlZCB0byB0aGlzIE1GLgorICBjb25zdCBEYXRhTGF5b3V0ICZnZXREYXRhTGF5b3V0KCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0aGUgTExWTSBmdW5jdGlvbiB0aGF0IHRoaXMgbWFjaGluZSBjb2RlIHJlcHJlc2VudHMKKyAgY29uc3QgRnVuY3Rpb24gJmdldEZ1bmN0aW9uKCkgY29uc3QgeyByZXR1cm4gRjsgfQorCisgIC8vLyBnZXROYW1lIC0gUmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBjb3JyZXNwb25kaW5nIExMVk0gZnVuY3Rpb24uCisgIFN0cmluZ1JlZiBnZXROYW1lKCkgY29uc3Q7CisKKyAgLy8vIGdldEZ1bmN0aW9uTnVtYmVyIC0gUmV0dXJuIGEgdW5pcXVlIElEIGZvciB0aGUgY3VycmVudCBmdW5jdGlvbi4KKyAgdW5zaWduZWQgZ2V0RnVuY3Rpb25OdW1iZXIoKSBjb25zdCB7IHJldHVybiBGdW5jdGlvbk51bWJlcjsgfQorCisgIC8vLyBnZXRUYXJnZXQgLSBSZXR1cm4gdGhlIHRhcmdldCBtYWNoaW5lIHRoaXMgbWFjaGluZSBjb2RlIGlzIGNvbXBpbGVkIHdpdGgKKyAgY29uc3QgVGFyZ2V0TWFjaGluZSAmZ2V0VGFyZ2V0KCkgY29uc3QgeyByZXR1cm4gVGFyZ2V0OyB9CisKKyAgLy8vIGdldFN1YnRhcmdldCAtIFJldHVybiB0aGUgc3VidGFyZ2V0IGZvciB3aGljaCB0aGlzIG1hY2hpbmUgY29kZSBpcyBiZWluZworICAvLy8gY29tcGlsZWQuCisgIGNvbnN0IFRhcmdldFN1YnRhcmdldEluZm8gJmdldFN1YnRhcmdldCgpIGNvbnN0IHsgcmV0dXJuICpTVEk7IH0KKyAgdm9pZCBzZXRTdWJ0YXJnZXQoY29uc3QgVGFyZ2V0U3VidGFyZ2V0SW5mbyAqU1QpIHsgU1RJID0gU1Q7IH0KKworICAvLy8gZ2V0U3VidGFyZ2V0IC0gVGhpcyBtZXRob2QgcmV0dXJucyBhIHBvaW50ZXIgdG8gdGhlIHNwZWNpZmllZCB0eXBlIG9mCisgIC8vLyBUYXJnZXRTdWJ0YXJnZXRJbmZvLiAgSW4gZGVidWcgYnVpbGRzLCBpdCB2ZXJpZmllcyB0aGF0IHRoZSBvYmplY3QgYmVpbmcKKyAgLy8vIHJldHVybmVkIGlzIG9mIHRoZSBjb3JyZWN0IHR5cGUuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFNUQz4gY29uc3QgU1RDICZnZXRTdWJ0YXJnZXQoKSBjb25zdCB7CisgICAgcmV0dXJuICpzdGF0aWNfY2FzdDxjb25zdCBTVEMgKj4oU1RJKTsKKyAgfQorCisgIC8vLyBnZXRSZWdJbmZvIC0gUmV0dXJuIGluZm9ybWF0aW9uIGFib3V0IHRoZSByZWdpc3RlcnMgY3VycmVudGx5IGluIHVzZS4KKyAgTWFjaGluZVJlZ2lzdGVySW5mbyAmZ2V0UmVnSW5mbygpIHsgcmV0dXJuICpSZWdJbmZvOyB9CisgIGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gJmdldFJlZ0luZm8oKSBjb25zdCB7IHJldHVybiAqUmVnSW5mbzsgfQorCisgIC8vLyBnZXRGcmFtZUluZm8gLSBSZXR1cm4gdGhlIGZyYW1lIGluZm8gb2JqZWN0IGZvciB0aGUgY3VycmVudCBmdW5jdGlvbi4KKyAgLy8vIFRoaXMgb2JqZWN0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IG9iamVjdHMgYWxsb2NhdGVkIG9uIHRoZSBzdGFjaworICAvLy8gZnJhbWUgb2YgdGhlIGN1cnJlbnQgZnVuY3Rpb24gaW4gYW4gYWJzdHJhY3Qgd2F5LgorICBNYWNoaW5lRnJhbWVJbmZvICZnZXRGcmFtZUluZm8oKSB7IHJldHVybiAqRnJhbWVJbmZvOyB9CisgIGNvbnN0IE1hY2hpbmVGcmFtZUluZm8gJmdldEZyYW1lSW5mbygpIGNvbnN0IHsgcmV0dXJuICpGcmFtZUluZm87IH0KKworICAvLy8gZ2V0SnVtcFRhYmxlSW5mbyAtIFJldHVybiB0aGUganVtcCB0YWJsZSBpbmZvIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQKKyAgLy8vIGZ1bmN0aW9uLiAgVGhpcyBvYmplY3QgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQganVtcCB0YWJsZXMgaW4gdGhlCisgIC8vLyBjdXJyZW50IGZ1bmN0aW9uLiAgSWYgdGhlIGN1cnJlbnQgZnVuY3Rpb24gaGFzIG5vIGp1bXAgdGFibGVzLCB0aGlzIHdpbGwKKyAgLy8vIHJldHVybiBudWxsLgorICBjb25zdCBNYWNoaW5lSnVtcFRhYmxlSW5mbyAqZ2V0SnVtcFRhYmxlSW5mbygpIGNvbnN0IHsgcmV0dXJuIEp1bXBUYWJsZUluZm87IH0KKyAgTWFjaGluZUp1bXBUYWJsZUluZm8gKmdldEp1bXBUYWJsZUluZm8oKSB7IHJldHVybiBKdW1wVGFibGVJbmZvOyB9CisKKyAgLy8vIGdldE9yQ3JlYXRlSnVtcFRhYmxlSW5mbyAtIEdldCB0aGUgSnVtcFRhYmxlSW5mbyBmb3IgdGhpcyBmdW5jdGlvbiwgaWYgaXQKKyAgLy8vIGRvZXMgYWxyZWFkeSBleGlzdCwgYWxsb2NhdGUgb25lLgorICBNYWNoaW5lSnVtcFRhYmxlSW5mbyAqZ2V0T3JDcmVhdGVKdW1wVGFibGVJbmZvKHVuc2lnbmVkIEpURW50cnlLaW5kKTsKKworICAvLy8gZ2V0Q29uc3RhbnRQb29sIC0gUmV0dXJuIHRoZSBjb25zdGFudCBwb29sIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQKKyAgLy8vIGZ1bmN0aW9uLgorICBNYWNoaW5lQ29uc3RhbnRQb29sICpnZXRDb25zdGFudFBvb2woKSB7IHJldHVybiBDb25zdGFudFBvb2w7IH0KKyAgY29uc3QgTWFjaGluZUNvbnN0YW50UG9vbCAqZ2V0Q29uc3RhbnRQb29sKCkgY29uc3QgeyByZXR1cm4gQ29uc3RhbnRQb29sOyB9CisKKyAgLy8vIGdldFdpbkVIRnVuY0luZm8gLSBSZXR1cm4gaW5mb3JtYXRpb24gYWJvdXQgaG93IHRoZSBjdXJyZW50IGZ1bmN0aW9uIHVzZXMKKyAgLy8vIFdpbmRvd3MgZXhjZXB0aW9uIGhhbmRsaW5nLiBSZXR1cm5zIG51bGwgZm9yIGZ1bmN0aW9ucyB0aGF0IGRvbid0IHVzZQorICAvLy8gZnVuY2xldHMgZm9yIGV4Y2VwdGlvbiBoYW5kbGluZy4KKyAgY29uc3QgV2luRUhGdW5jSW5mbyAqZ2V0V2luRUhGdW5jSW5mbygpIGNvbnN0IHsgcmV0dXJuIFdpbkVISW5mbzsgfQorICBXaW5FSEZ1bmNJbmZvICpnZXRXaW5FSEZ1bmNJbmZvKCkgeyByZXR1cm4gV2luRUhJbmZvOyB9CisKKyAgLy8vIGdldEFsaWdubWVudCAtIFJldHVybiB0aGUgYWxpZ25tZW50IChsb2cyLCBub3QgYnl0ZXMpIG9mIHRoZSBmdW5jdGlvbi4KKyAgdW5zaWduZWQgZ2V0QWxpZ25tZW50KCkgY29uc3QgeyByZXR1cm4gQWxpZ25tZW50OyB9CisKKyAgLy8vIHNldEFsaWdubWVudCAtIFNldCB0aGUgYWxpZ25tZW50IChsb2cyLCBub3QgYnl0ZXMpIG9mIHRoZSBmdW5jdGlvbi4KKyAgdm9pZCBzZXRBbGlnbm1lbnQodW5zaWduZWQgQSkgeyBBbGlnbm1lbnQgPSBBOyB9CisKKyAgLy8vIGVuc3VyZUFsaWdubWVudCAtIE1ha2Ugc3VyZSB0aGUgZnVuY3Rpb24gaXMgYXQgbGVhc3QgMSA8PCBBIGJ5dGVzIGFsaWduZWQuCisgIHZvaWQgZW5zdXJlQWxpZ25tZW50KHVuc2lnbmVkIEEpIHsKKyAgICBpZiAoQWxpZ25tZW50IDwgQSkgQWxpZ25tZW50ID0gQTsKKyAgfQorCisgIC8vLyBleHBvc2VzUmV0dXJuc1R3aWNlIC0gUmV0dXJucyB0cnVlIGlmIHRoZSBmdW5jdGlvbiBjYWxscyBzZXRqbXAgb3IKKyAgLy8vIGFueSBvdGhlciBzaW1pbGFyIGZ1bmN0aW9ucyB3aXRoIGF0dHJpYnV0ZSAicmV0dXJucyB0d2ljZSIgd2l0aG91dAorICAvLy8gaGF2aW5nIHRoZSBhdHRyaWJ1dGUgaXRzZWxmLgorICBib29sIGV4cG9zZXNSZXR1cm5zVHdpY2UoKSBjb25zdCB7CisgICAgcmV0dXJuIEV4cG9zZXNSZXR1cm5zVHdpY2U7CisgIH0KKworICAvLy8gc2V0Q2FsbHNTZXRKbXAgLSBTZXQgYSBmbGFnIHRoYXQgaW5kaWNhdGVzIGlmIHRoZXJlJ3MgYSBjYWxsIHRvCisgIC8vLyBhICJyZXR1cm5zIHR3aWNlIiBmdW5jdGlvbi4KKyAgdm9pZCBzZXRFeHBvc2VzUmV0dXJuc1R3aWNlKGJvb2wgQikgeworICAgIEV4cG9zZXNSZXR1cm5zVHdpY2UgPSBCOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZnVuY3Rpb24gY29udGFpbnMgYW55IGlubGluZSBhc3NlbWJseS4KKyAgYm9vbCBoYXNJbmxpbmVBc20oKSBjb25zdCB7CisgICAgcmV0dXJuIEhhc0lubGluZUFzbTsKKyAgfQorCisgIC8vLyBTZXQgYSBmbGFnIHRoYXQgaW5kaWNhdGVzIHRoYXQgdGhlIGZ1bmN0aW9uIGNvbnRhaW5zIGlubGluZSBhc3NlbWJseS4KKyAgdm9pZCBzZXRIYXNJbmxpbmVBc20oYm9vbCBCKSB7CisgICAgSGFzSW5saW5lQXNtID0gQjsKKyAgfQorCisgIGJvb2wgaGFzV2luQ0ZJKCkgY29uc3QgeworICAgIGFzc2VydChIYXNXaW5DRkkuaGFzVmFsdWUoKSAmJiAiSGFzV2luQ0ZJIG5vdCBzZXQgeWV0ISIpOworICAgIHJldHVybiAqSGFzV2luQ0ZJOworICB9CisgIHZvaWQgc2V0SGFzV2luQ0ZJKGJvb2wgdikgeyBIYXNXaW5DRkkgPSB2OyB9CisKKyAgLy8vIEdldCB0aGUgZnVuY3Rpb24gcHJvcGVydGllcworICBjb25zdCBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzICZnZXRQcm9wZXJ0aWVzKCkgY29uc3QgeyByZXR1cm4gUHJvcGVydGllczsgfQorICBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzICZnZXRQcm9wZXJ0aWVzKCkgeyByZXR1cm4gUHJvcGVydGllczsgfQorCisgIC8vLyBnZXRJbmZvIC0gS2VlcCB0cmFjayBvZiB2YXJpb3VzIHBlci1mdW5jdGlvbiBwaWVjZXMgb2YgaW5mb3JtYXRpb24gZm9yCisgIC8vLyBiYWNrZW5kcyB0aGF0IHdvdWxkIGxpa2UgdG8gZG8gc28uCisgIC8vLworICB0ZW1wbGF0ZTx0eXBlbmFtZSBUeT4KKyAgVHkgKmdldEluZm8oKSB7CisgICAgaWYgKCFNRkluZm8pCisgICAgICBNRkluZm8gPSBUeTo6dGVtcGxhdGUgY3JlYXRlPFR5PihBbGxvY2F0b3IsICp0aGlzKTsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8VHkqPihNRkluZm8pOworICB9CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVHk+CisgIGNvbnN0IFR5ICpnZXRJbmZvKCkgY29uc3QgeworICAgICByZXR1cm4gY29uc3RfY2FzdDxNYWNoaW5lRnVuY3Rpb24qPih0aGlzKS0+Z2V0SW5mbzxUeT4oKTsKKyAgfQorCisgIC8vLyBnZXRCbG9ja051bWJlcmVkIC0gTWFjaGluZUJhc2ljQmxvY2tzIGFyZSBhdXRvbWF0aWNhbGx5IG51bWJlcmVkIHdoZW4gdGhleQorICAvLy8gYXJlIGluc2VydGVkIGludG8gdGhlIG1hY2hpbmUgZnVuY3Rpb24uICBUaGUgYmxvY2sgbnVtYmVyIGZvciBhIG1hY2hpbmUKKyAgLy8vIGJhc2ljIGJsb2NrIGNhbiBiZSBmb3VuZCBieSB1c2luZyB0aGUgTUJCOjpnZXROdW1iZXIgbWV0aG9kLCB0aGlzIG1ldGhvZAorICAvLy8gcHJvdmlkZXMgdGhlIGludmVyc2UgbWFwcGluZy4KKyAgTWFjaGluZUJhc2ljQmxvY2sgKmdldEJsb2NrTnVtYmVyZWQodW5zaWduZWQgTikgY29uc3QgeworICAgIGFzc2VydChOIDwgTUJCTnVtYmVyaW5nLnNpemUoKSAmJiAiSWxsZWdhbCBibG9jayBudW1iZXIiKTsKKyAgICBhc3NlcnQoTUJCTnVtYmVyaW5nW05dICYmICJCbG9jayB3YXMgcmVtb3ZlZCBmcm9tIHRoZSBtYWNoaW5lIGZ1bmN0aW9uISIpOworICAgIHJldHVybiBNQkJOdW1iZXJpbmdbTl07CisgIH0KKworICAvLy8gU2hvdWxkIHdlIGJlIGVtaXR0aW5nIHNlZ21lbnRlZCBzdGFjayBzdHVmZiBmb3IgdGhlIGZ1bmN0aW9uCisgIGJvb2wgc2hvdWxkU3BsaXRTdGFjaygpIGNvbnN0OworCisgIC8vLyBnZXROdW1CbG9ja0lEcyAtIFJldHVybiB0aGUgbnVtYmVyIG9mIE1CQiBJRCdzIGFsbG9jYXRlZC4KKyAgdW5zaWduZWQgZ2V0TnVtQmxvY2tJRHMoKSBjb25zdCB7IHJldHVybiAodW5zaWduZWQpTUJCTnVtYmVyaW5nLnNpemUoKTsgfQorCisgIC8vLyBSZW51bWJlckJsb2NrcyAtIFRoaXMgZGlzY2FyZHMgYWxsIG9mIHRoZSBNYWNoaW5lQmFzaWNCbG9jayBudW1iZXJzIGFuZAorICAvLy8gcmVjb21wdXRlcyB0aGVtLiAgVGhpcyBndWFyYW50ZWVzIHRoYXQgdGhlIE1CQiBudW1iZXJzIGFyZSBzZXF1ZW50aWFsLAorICAvLy8gZGVuc2UsIGFuZCBtYXRjaCB0aGUgb3JkZXJpbmcgb2YgdGhlIGJsb2NrcyB3aXRoaW4gdGhlIGZ1bmN0aW9uLiAgSWYgYQorICAvLy8gc3BlY2lmaWMgTWFjaGluZUJhc2ljQmxvY2sgaXMgc3BlY2lmaWVkLCBvbmx5IHRoYXQgYmxvY2sgYW5kIHRob3NlIGFmdGVyCisgIC8vLyBpdCBhcmUgcmVudW1iZXJlZC4KKyAgdm9pZCBSZW51bWJlckJsb2NrcyhNYWNoaW5lQmFzaWNCbG9jayAqTUJCRnJvbSA9IG51bGxwdHIpOworCisgIC8vLyBwcmludCAtIFByaW50IG91dCB0aGUgTWFjaGluZUZ1bmN0aW9uIGluIGEgZm9ybWF0IHN1aXRhYmxlIGZvciBkZWJ1Z2dpbmcKKyAgLy8vIHRvIHRoZSBzcGVjaWZpZWQgc3RyZWFtLgorICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUywgY29uc3QgU2xvdEluZGV4ZXMqID0gbnVsbHB0cikgY29uc3Q7CisKKyAgLy8vIHZpZXdDRkcgLSBUaGlzIGZ1bmN0aW9uIGlzIG1lYW50IGZvciB1c2UgZnJvbSB0aGUgZGVidWdnZXIuICBZb3UgY2FuIGp1c3QKKyAgLy8vIHNheSAnY2FsbCBGLT52aWV3Q0ZHKCknIGFuZCBhIGdob3N0dmlldyB3aW5kb3cgc2hvdWxkIHBvcCB1cCBmcm9tIHRoZQorICAvLy8gcHJvZ3JhbSwgZGlzcGxheWluZyB0aGUgQ0ZHIG9mIHRoZSBjdXJyZW50IGZ1bmN0aW9uIHdpdGggdGhlIGNvZGUgZm9yIGVhY2gKKyAgLy8vIGJhc2ljIGJsb2NrIGluc2lkZS4gIFRoaXMgZGVwZW5kcyBvbiB0aGVyZSBiZWluZyBhICdkb3QnIGFuZCAnZ3YnIHByb2dyYW0KKyAgLy8vIGluIHlvdXIgcGF0aC4KKyAgdm9pZCB2aWV3Q0ZHKCkgY29uc3Q7CisKKyAgLy8vIHZpZXdDRkdPbmx5IC0gVGhpcyBmdW5jdGlvbiBpcyBtZWFudCBmb3IgdXNlIGZyb20gdGhlIGRlYnVnZ2VyLiAgSXQgd29ya3MKKyAgLy8vIGp1c3QgbGlrZSB2aWV3Q0ZHLCBidXQgaXQgZG9lcyBub3QgaW5jbHVkZSB0aGUgY29udGVudHMgb2YgYmFzaWMgYmxvY2tzCisgIC8vLyBpbnRvIHRoZSBub2RlcywganVzdCB0aGUgbGFiZWwuICBJZiB5b3UgYXJlIG9ubHkgaW50ZXJlc3RlZCBpbiB0aGUgQ0ZHCisgIC8vLyB0aGlzIGNhbiBtYWtlIHRoZSBncmFwaCBzbWFsbGVyLgorICAvLy8KKyAgdm9pZCB2aWV3Q0ZHT25seSgpIGNvbnN0OworCisgIC8vLyBkdW1wIC0gUHJpbnQgdGhlIGN1cnJlbnQgTWFjaGluZUZ1bmN0aW9uIHRvIGNlcnIsIHVzZWZ1bCBmb3IgZGVidWdnZXIgdXNlLgorICB2b2lkIGR1bXAoKSBjb25zdDsKKworICAvLy8gUnVuIHRoZSBjdXJyZW50IE1hY2hpbmVGdW5jdGlvbiB0aHJvdWdoIHRoZSBtYWNoaW5lIGNvZGUgdmVyaWZpZXIsIHVzZWZ1bAorICAvLy8gZm9yIGRlYnVnZ2VyIHVzZS4KKyAgLy8vIFxyZXR1cm5zIHRydWUgaWYgbm8gcHJvYmxlbXMgd2VyZSBmb3VuZC4KKyAgYm9vbCB2ZXJpZnkoUGFzcyAqcCA9IG51bGxwdHIsIGNvbnN0IGNoYXIgKkJhbm5lciA9IG51bGxwdHIsCisgICAgICAgICAgICAgIGJvb2wgQWJvcnRPbkVycm9yID0gdHJ1ZSkgY29uc3Q7CisKKyAgLy8gUHJvdmlkZSBhY2Nlc3NvcnMgZm9yIHRoZSBNYWNoaW5lQmFzaWNCbG9jayBsaXN0Li4uCisgIHVzaW5nIGl0ZXJhdG9yID0gQmFzaWNCbG9ja0xpc3RUeXBlOjppdGVyYXRvcjsKKyAgdXNpbmcgY29uc3RfaXRlcmF0b3IgPSBCYXNpY0Jsb2NrTGlzdFR5cGU6OmNvbnN0X2l0ZXJhdG9yOworICB1c2luZyBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yID0gQmFzaWNCbG9ja0xpc3RUeXBlOjpjb25zdF9yZXZlcnNlX2l0ZXJhdG9yOworICB1c2luZyByZXZlcnNlX2l0ZXJhdG9yID0gQmFzaWNCbG9ja0xpc3RUeXBlOjpyZXZlcnNlX2l0ZXJhdG9yOworCisgIC8vLyBTdXBwb3J0IGZvciBNYWNoaW5lQmFzaWNCbG9jazo6Z2V0TmV4dE5vZGUoKS4KKyAgc3RhdGljIEJhc2ljQmxvY2tMaXN0VHlwZSBNYWNoaW5lRnVuY3Rpb246OioKKyAgZ2V0U3VibGlzdEFjY2VzcyhNYWNoaW5lQmFzaWNCbG9jayAqKSB7CisgICAgcmV0dXJuICZNYWNoaW5lRnVuY3Rpb246OkJhc2ljQmxvY2tzOworICB9CisKKyAgLy8vIGFkZExpdmVJbiAtIEFkZCB0aGUgc3BlY2lmaWVkIHBoeXNpY2FsIHJlZ2lzdGVyIGFzIGEgbGl2ZS1pbiB2YWx1ZSBhbmQKKyAgLy8vIGNyZWF0ZSBhIGNvcnJlc3BvbmRpbmcgdmlydHVhbCByZWdpc3RlciBmb3IgaXQuCisgIHVuc2lnbmVkIGFkZExpdmVJbih1bnNpZ25lZCBQUmVnLCBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQyk7CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIEJhc2ljQmxvY2sgYWNjZXNzb3IgZnVuY3Rpb25zLgorICAvLworICBpdGVyYXRvciAgICAgICAgICAgICAgICAgYmVnaW4oKSAgICAgICB7IHJldHVybiBCYXNpY0Jsb2Nrcy5iZWdpbigpOyB9CisgIGNvbnN0X2l0ZXJhdG9yICAgICAgICAgICBiZWdpbigpIGNvbnN0IHsgcmV0dXJuIEJhc2ljQmxvY2tzLmJlZ2luKCk7IH0KKyAgaXRlcmF0b3IgICAgICAgICAgICAgICAgIGVuZCAgKCkgICAgICAgeyByZXR1cm4gQmFzaWNCbG9ja3MuZW5kKCk7ICAgfQorICBjb25zdF9pdGVyYXRvciAgICAgICAgICAgZW5kICAoKSBjb25zdCB7IHJldHVybiBCYXNpY0Jsb2Nrcy5lbmQoKTsgICB9CisKKyAgcmV2ZXJzZV9pdGVyYXRvciAgICAgICAgcmJlZ2luKCkgICAgICAgeyByZXR1cm4gQmFzaWNCbG9ja3MucmJlZ2luKCk7IH0KKyAgY29uc3RfcmV2ZXJzZV9pdGVyYXRvciAgcmJlZ2luKCkgY29uc3QgeyByZXR1cm4gQmFzaWNCbG9ja3MucmJlZ2luKCk7IH0KKyAgcmV2ZXJzZV9pdGVyYXRvciAgICAgICAgcmVuZCAgKCkgICAgICAgeyByZXR1cm4gQmFzaWNCbG9ja3MucmVuZCgpOyAgIH0KKyAgY29uc3RfcmV2ZXJzZV9pdGVyYXRvciAgcmVuZCAgKCkgY29uc3QgeyByZXR1cm4gQmFzaWNCbG9ja3MucmVuZCgpOyAgIH0KKworICB1bnNpZ25lZCAgICAgICAgICAgICAgICAgIHNpemUoKSBjb25zdCB7IHJldHVybiAodW5zaWduZWQpQmFzaWNCbG9ja3Muc2l6ZSgpO30KKyAgYm9vbCAgICAgICAgICAgICAgICAgICAgIGVtcHR5KCkgY29uc3QgeyByZXR1cm4gQmFzaWNCbG9ja3MuZW1wdHkoKTsgfQorICBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAmZnJvbnQoKSBjb25zdCB7IHJldHVybiBCYXNpY0Jsb2Nrcy5mcm9udCgpOyB9CisgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICZmcm9udCgpICAgICAgIHsgcmV0dXJuIEJhc2ljQmxvY2tzLmZyb250KCk7IH0KKyAgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgJiBiYWNrKCkgY29uc3QgeyByZXR1cm4gQmFzaWNCbG9ja3MuYmFjaygpOyB9CisgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICYgYmFjaygpICAgICAgIHsgcmV0dXJuIEJhc2ljQmxvY2tzLmJhY2soKTsgfQorCisgIHZvaWQgcHVzaF9iYWNrIChNYWNoaW5lQmFzaWNCbG9jayAqTUJCKSB7IEJhc2ljQmxvY2tzLnB1c2hfYmFjayAoTUJCKTsgfQorICB2b2lkIHB1c2hfZnJvbnQoTWFjaGluZUJhc2ljQmxvY2sgKk1CQikgeyBCYXNpY0Jsb2Nrcy5wdXNoX2Zyb250KE1CQik7IH0KKyAgdm9pZCBpbnNlcnQoaXRlcmF0b3IgTUJCSSwgTWFjaGluZUJhc2ljQmxvY2sgKk1CQikgeworICAgIEJhc2ljQmxvY2tzLmluc2VydChNQkJJLCBNQkIpOworICB9CisgIHZvaWQgc3BsaWNlKGl0ZXJhdG9yIEluc2VydFB0LCBpdGVyYXRvciBNQkJJKSB7CisgICAgQmFzaWNCbG9ja3Muc3BsaWNlKEluc2VydFB0LCBCYXNpY0Jsb2NrcywgTUJCSSk7CisgIH0KKyAgdm9pZCBzcGxpY2UoaXRlcmF0b3IgSW5zZXJ0UHQsIE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpIHsKKyAgICBCYXNpY0Jsb2Nrcy5zcGxpY2UoSW5zZXJ0UHQsIEJhc2ljQmxvY2tzLCBNQkIpOworICB9CisgIHZvaWQgc3BsaWNlKGl0ZXJhdG9yIEluc2VydFB0LCBpdGVyYXRvciBNQkJJLCBpdGVyYXRvciBNQkJFKSB7CisgICAgQmFzaWNCbG9ja3Muc3BsaWNlKEluc2VydFB0LCBCYXNpY0Jsb2NrcywgTUJCSSwgTUJCRSk7CisgIH0KKworICB2b2lkIHJlbW92ZShpdGVyYXRvciBNQkJJKSB7IEJhc2ljQmxvY2tzLnJlbW92ZShNQkJJKTsgfQorICB2b2lkIHJlbW92ZShNYWNoaW5lQmFzaWNCbG9jayAqTUJCSSkgeyBCYXNpY0Jsb2Nrcy5yZW1vdmUoTUJCSSk7IH0KKyAgdm9pZCBlcmFzZShpdGVyYXRvciBNQkJJKSB7IEJhc2ljQmxvY2tzLmVyYXNlKE1CQkkpOyB9CisgIHZvaWQgZXJhc2UoTWFjaGluZUJhc2ljQmxvY2sgKk1CQkkpIHsgQmFzaWNCbG9ja3MuZXJhc2UoTUJCSSk7IH0KKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgQ29tcD4KKyAgdm9pZCBzb3J0KENvbXAgY29tcCkgeworICAgIEJhc2ljQmxvY2tzLnNvcnQoY29tcCk7CisgIH0KKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gSW50ZXJuYWwgZnVuY3Rpb25zIHVzZWQgdG8gYXV0b21hdGljYWxseSBudW1iZXIgTWFjaGluZUJhc2ljQmxvY2tzCisKKyAgLy8vIFxicmllZiBBZGRzIHRoZSBNQkIgdG8gdGhlIGludGVybmFsIG51bWJlcmluZy4gUmV0dXJucyB0aGUgdW5pcXVlIG51bWJlcgorICAvLy8gYXNzaWduZWQgdG8gdGhlIE1CQi4KKyAgdW5zaWduZWQgYWRkVG9NQkJOdW1iZXJpbmcoTWFjaGluZUJhc2ljQmxvY2sgKk1CQikgeworICAgIE1CQk51bWJlcmluZy5wdXNoX2JhY2soTUJCKTsKKyAgICByZXR1cm4gKHVuc2lnbmVkKU1CQk51bWJlcmluZy5zaXplKCktMTsKKyAgfQorCisgIC8vLyByZW1vdmVGcm9tTUJCTnVtYmVyaW5nIC0gUmVtb3ZlIHRoZSBzcGVjaWZpYyBtYWNoaW5lIGJhc2ljIGJsb2NrIGZyb20gb3VyCisgIC8vLyB0cmFja2VyLCB0aGlzIGlzIG9ubHkgcmVhbGx5IHRvIGJlIHVzZWQgYnkgdGhlIE1hY2hpbmVCYXNpY0Jsb2NrCisgIC8vLyBpbXBsZW1lbnRhdGlvbi4KKyAgdm9pZCByZW1vdmVGcm9tTUJCTnVtYmVyaW5nKHVuc2lnbmVkIE4pIHsKKyAgICBhc3NlcnQoTiA8IE1CQk51bWJlcmluZy5zaXplKCkgJiYgIklsbGVnYWwgYmFzaWMgYmxvY2sgIyIpOworICAgIE1CQk51bWJlcmluZ1tOXSA9IG51bGxwdHI7CisgIH0KKworICAvLy8gQ3JlYXRlTWFjaGluZUluc3RyIC0gQWxsb2NhdGUgYSBuZXcgTWFjaGluZUluc3RyLiBVc2UgdGhpcyBpbnN0ZWFkCisgIC8vLyBvZiBgbmV3IE1hY2hpbmVJbnN0cicuCisgIE1hY2hpbmVJbnN0ciAqQ3JlYXRlTWFjaGluZUluc3RyKGNvbnN0IE1DSW5zdHJEZXNjICZNQ0lELCBjb25zdCBEZWJ1Z0xvYyAmREwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgTm9JbXAgPSBmYWxzZSk7CisKKyAgLy8vIENyZWF0ZSBhIG5ldyBNYWNoaW5lSW5zdHIgd2hpY2ggaXMgYSBjb3B5IG9mIFxwIE9yaWcsIGlkZW50aWNhbCBpbiBhbGwKKyAgLy8vIHdheXMgZXhjZXB0IHRoZSBpbnN0cnVjdGlvbiBoYXMgbm8gcGFyZW50LCBwcmV2LCBvciBuZXh0LiBCdW5kbGluZyBmbGFncworICAvLy8gYXJlIHJlc2V0LgorICAvLy8KKyAgLy8vIE5vdGU6IENsb25lcyBhIHNpbmdsZSBpbnN0cnVjdGlvbiwgbm90IHdob2xlIGluc3RydWN0aW9uIGJ1bmRsZXMuCisgIC8vLyBEb2VzIG5vdCBwZXJmb3JtIHRhcmdldCBzcGVjaWZpYyBhZGp1c3RtZW50czsgY29uc2lkZXIgdXNpbmcKKyAgLy8vIFRhcmdldEluc3RySW5mbzo6ZHVwbGljYXRlKCkgaW5zdGVhZC4KKyAgTWFjaGluZUluc3RyICpDbG9uZU1hY2hpbmVJbnN0cihjb25zdCBNYWNoaW5lSW5zdHIgKk9yaWcpOworCisgIC8vLyBDbG9uZXMgaW5zdHJ1Y3Rpb24gb3IgdGhlIHdob2xlIGluc3RydWN0aW9uIGJ1bmRsZSBccCBPcmlnIGFuZCBpbnNlcnQKKyAgLy8vIGludG8gXHAgTUJCIGJlZm9yZSBccCBJbnNlcnRCZWZvcmUuCisgIC8vLworICAvLy8gTm90ZTogRG9lcyBub3QgcGVyZm9ybSB0YXJnZXQgc3BlY2lmaWMgYWRqdXN0bWVudHM7IGNvbnNpZGVyIHVzaW5nCisgIC8vLyBUYXJnZXRJbnN0ckluZm86OmR1cGxpY2F0ZSgpIGludGVhZC4KKyAgTWFjaGluZUluc3RyICZDbG9uZU1hY2hpbmVJbnN0ckJ1bmRsZShNYWNoaW5lQmFzaWNCbG9jayAmTUJCLAorICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEluc2VydEJlZm9yZSwgY29uc3QgTWFjaGluZUluc3RyICZPcmlnKTsKKworICAvLy8gRGVsZXRlTWFjaGluZUluc3RyIC0gRGVsZXRlIHRoZSBnaXZlbiBNYWNoaW5lSW5zdHIuCisgIHZvaWQgRGVsZXRlTWFjaGluZUluc3RyKE1hY2hpbmVJbnN0ciAqTUkpOworCisgIC8vLyBDcmVhdGVNYWNoaW5lQmFzaWNCbG9jayAtIEFsbG9jYXRlIGEgbmV3IE1hY2hpbmVCYXNpY0Jsb2NrLiBVc2UgdGhpcworICAvLy8gaW5zdGVhZCBvZiBgbmV3IE1hY2hpbmVCYXNpY0Jsb2NrJy4KKyAgTWFjaGluZUJhc2ljQmxvY2sgKkNyZWF0ZU1hY2hpbmVCYXNpY0Jsb2NrKGNvbnN0IEJhc2ljQmxvY2sgKmJiID0gbnVsbHB0cik7CisKKyAgLy8vIERlbGV0ZU1hY2hpbmVCYXNpY0Jsb2NrIC0gRGVsZXRlIHRoZSBnaXZlbiBNYWNoaW5lQmFzaWNCbG9jay4KKyAgdm9pZCBEZWxldGVNYWNoaW5lQmFzaWNCbG9jayhNYWNoaW5lQmFzaWNCbG9jayAqTUJCKTsKKworICAvLy8gZ2V0TWFjaGluZU1lbU9wZXJhbmQgLSBBbGxvY2F0ZSBhIG5ldyBNYWNoaW5lTWVtT3BlcmFuZC4KKyAgLy8vIE1hY2hpbmVNZW1PcGVyYW5kcyBhcmUgb3duZWQgYnkgdGhlIE1hY2hpbmVGdW5jdGlvbiBhbmQgbmVlZCBub3QgYmUKKyAgLy8vIGV4cGxpY2l0bHkgZGVhbGxvY2F0ZWQuCisgIE1hY2hpbmVNZW1PcGVyYW5kICpnZXRNYWNoaW5lTWVtT3BlcmFuZCgKKyAgICAgIE1hY2hpbmVQb2ludGVySW5mbyBQdHJJbmZvLCBNYWNoaW5lTWVtT3BlcmFuZDo6RmxhZ3MgZiwgdWludDY0X3QgcywKKyAgICAgIHVuc2lnbmVkIGJhc2VfYWxpZ25tZW50LCBjb25zdCBBQU1ETm9kZXMgJkFBSW5mbyA9IEFBTUROb2RlcygpLAorICAgICAgY29uc3QgTUROb2RlICpSYW5nZXMgPSBudWxscHRyLAorICAgICAgU3luY1Njb3BlOjpJRCBTU0lEID0gU3luY1Njb3BlOjpTeXN0ZW0sCisgICAgICBBdG9taWNPcmRlcmluZyBPcmRlcmluZyA9IEF0b21pY09yZGVyaW5nOjpOb3RBdG9taWMsCisgICAgICBBdG9taWNPcmRlcmluZyBGYWlsdXJlT3JkZXJpbmcgPSBBdG9taWNPcmRlcmluZzo6Tm90QXRvbWljKTsKKworICAvLy8gZ2V0TWFjaGluZU1lbU9wZXJhbmQgLSBBbGxvY2F0ZSBhIG5ldyBNYWNoaW5lTWVtT3BlcmFuZCBieSBjb3B5aW5nCisgIC8vLyBhbiBleGlzdGluZyBvbmUsIGFkanVzdGluZyBieSBhbiBvZmZzZXQgYW5kIHVzaW5nIHRoZSBnaXZlbiBzaXplLgorICAvLy8gTWFjaGluZU1lbU9wZXJhbmRzIGFyZSBvd25lZCBieSB0aGUgTWFjaGluZUZ1bmN0aW9uIGFuZCBuZWVkIG5vdCBiZQorICAvLy8gZXhwbGljaXRseSBkZWFsbG9jYXRlZC4KKyAgTWFjaGluZU1lbU9wZXJhbmQgKmdldE1hY2hpbmVNZW1PcGVyYW5kKGNvbnN0IE1hY2hpbmVNZW1PcGVyYW5kICpNTU8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NF90IE9mZnNldCwgdWludDY0X3QgU2l6ZSk7CisKKyAgLy8vIEFsbG9jYXRlIGEgbmV3IE1hY2hpbmVNZW1PcGVyYW5kIGJ5IGNvcHlpbmcgYW4gZXhpc3Rpbmcgb25lLAorICAvLy8gcmVwbGFjaW5nIG9ubHkgQWxpYXNBbmFseXNpcyBpbmZvcm1hdGlvbi4gTWFjaGluZU1lbU9wZXJhbmRzIGFyZSBvd25lZAorICAvLy8gYnkgdGhlIE1hY2hpbmVGdW5jdGlvbiBhbmQgbmVlZCBub3QgYmUgZXhwbGljaXRseSBkZWFsbG9jYXRlZC4KKyAgTWFjaGluZU1lbU9wZXJhbmQgKmdldE1hY2hpbmVNZW1PcGVyYW5kKGNvbnN0IE1hY2hpbmVNZW1PcGVyYW5kICpNTU8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBQU1ETm9kZXMgJkFBSW5mbyk7CisKKyAgdXNpbmcgT3BlcmFuZENhcGFjaXR5ID0gQXJyYXlSZWN5Y2xlcjxNYWNoaW5lT3BlcmFuZD46OkNhcGFjaXR5OworCisgIC8vLyBBbGxvY2F0ZSBhbiBhcnJheSBvZiBNYWNoaW5lT3BlcmFuZHMuIFRoaXMgaXMgb25seSBpbnRlbmRlZCBmb3IgdXNlIGJ5CisgIC8vLyBpbnRlcm5hbCBNYWNoaW5lSW5zdHIgZnVuY3Rpb25zLgorICBNYWNoaW5lT3BlcmFuZCAqYWxsb2NhdGVPcGVyYW5kQXJyYXkoT3BlcmFuZENhcGFjaXR5IENhcCkgeworICAgIHJldHVybiBPcGVyYW5kUmVjeWNsZXIuYWxsb2NhdGUoQ2FwLCBBbGxvY2F0b3IpOworICB9CisKKyAgLy8vIERlbGxvY2F0ZSBhbiBhcnJheSBvZiBNYWNoaW5lT3BlcmFuZHMgYW5kIHJlY3ljbGUgdGhlIG1lbW9yeS4gVGhpcyBpcworICAvLy8gb25seSBpbnRlbmRlZCBmb3IgdXNlIGJ5IGludGVybmFsIE1hY2hpbmVJbnN0ciBmdW5jdGlvbnMuCisgIC8vLyBDYXAgbXVzdCBiZSB0aGUgc2FtZSBjYXBhY2l0eSB0aGF0IHdhcyB1c2VkIHRvIGFsbG9jYXRlIHRoZSBhcnJheS4KKyAgdm9pZCBkZWFsbG9jYXRlT3BlcmFuZEFycmF5KE9wZXJhbmRDYXBhY2l0eSBDYXAsIE1hY2hpbmVPcGVyYW5kICpBcnJheSkgeworICAgIE9wZXJhbmRSZWN5Y2xlci5kZWFsbG9jYXRlKENhcCwgQXJyYXkpOworICB9CisKKyAgLy8vIFxicmllZiBBbGxvY2F0ZSBhbmQgaW5pdGlhbGl6ZSBhIHJlZ2lzdGVyIG1hc2sgd2l0aCBAcCBOdW1SZWdpc3RlciBiaXRzLgorICB1aW50MzJfdCAqYWxsb2NhdGVSZWdpc3Rlck1hc2sodW5zaWduZWQgTnVtUmVnaXN0ZXIpIHsKKyAgICB1bnNpZ25lZCBTaXplID0gKE51bVJlZ2lzdGVyICsgMzEpIC8gMzI7CisgICAgdWludDMyX3QgKk1hc2sgPSBBbGxvY2F0b3IuQWxsb2NhdGU8dWludDMyX3Q+KFNpemUpOworICAgIGZvciAodW5zaWduZWQgaSA9IDA7IGkgIT0gU2l6ZTsgKytpKQorICAgICAgTWFza1tpXSA9IDA7CisgICAgcmV0dXJuIE1hc2s7CisgIH0KKworICAvLy8gYWxsb2NhdGVNZW1SZWZzQXJyYXkgLSBBbGxvY2F0ZSBhbiBhcnJheSB0byBob2xkIE1hY2hpbmVNZW1PcGVyYW5kCisgIC8vLyBwb2ludGVycy4gIFRoaXMgYXJyYXkgaXMgb3duZWQgYnkgdGhlIE1hY2hpbmVGdW5jdGlvbi4KKyAgTWFjaGluZUluc3RyOjptbW9faXRlcmF0b3IgYWxsb2NhdGVNZW1SZWZzQXJyYXkodW5zaWduZWQgbG9uZyBOdW0pOworCisgIC8vLyBleHRyYWN0TG9hZE1lbVJlZnMgLSBBbGxvY2F0ZSBhbiBhcnJheSBhbmQgcG9wdWxhdGUgaXQgd2l0aCBqdXN0IHRoZQorICAvLy8gbG9hZCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBnaXZlbiBNYWNoaW5lTWVtT3BlcmFuZCBzZXF1ZW5jZS4KKyAgc3RkOjpwYWlyPE1hY2hpbmVJbnN0cjo6bW1vX2l0ZXJhdG9yLAorICAgICAgICAgICAgTWFjaGluZUluc3RyOjptbW9faXRlcmF0b3I+CisgICAgZXh0cmFjdExvYWRNZW1SZWZzKE1hY2hpbmVJbnN0cjo6bW1vX2l0ZXJhdG9yIEJlZ2luLAorICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSW5zdHI6Om1tb19pdGVyYXRvciBFbmQpOworCisgIC8vLyBleHRyYWN0U3RvcmVNZW1SZWZzIC0gQWxsb2NhdGUgYW4gYXJyYXkgYW5kIHBvcHVsYXRlIGl0IHdpdGgganVzdCB0aGUKKyAgLy8vIHN0b3JlIGluZm9ybWF0aW9uIGZyb20gdGhlIGdpdmVuIE1hY2hpbmVNZW1PcGVyYW5kIHNlcXVlbmNlLgorICBzdGQ6OnBhaXI8TWFjaGluZUluc3RyOjptbW9faXRlcmF0b3IsCisgICAgICAgICAgICBNYWNoaW5lSW5zdHI6Om1tb19pdGVyYXRvcj4KKyAgICBleHRyYWN0U3RvcmVNZW1SZWZzKE1hY2hpbmVJbnN0cjo6bW1vX2l0ZXJhdG9yIEJlZ2luLAorICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUluc3RyOjptbW9faXRlcmF0b3IgRW5kKTsKKworICAvLy8gQWxsb2NhdGUgYSBzdHJpbmcgYW5kIHBvcHVsYXRlIGl0IHdpdGggdGhlIGdpdmVuIGV4dGVybmFsIHN5bWJvbCBuYW1lLgorICBjb25zdCBjaGFyICpjcmVhdGVFeHRlcm5hbFN5bWJvbE5hbWUoU3RyaW5nUmVmIE5hbWUpOworCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLyBMYWJlbCBNYW5pcHVsYXRpb24uCisKKyAgLy8vIGdldEpUSVN5bWJvbCAtIFJldHVybiB0aGUgTUNTeW1ib2wgZm9yIHRoZSBzcGVjaWZpZWQgbm9uLWVtcHR5IGp1bXAgdGFibGUuCisgIC8vLyBJZiBpc0xpbmtlclByaXZhdGUgaXMgc3BlY2lmaWVkLCBhbiAnbCcgbGFiZWwgaXMgcmV0dXJuZWQsIG90aGVyd2lzZSBhCisgIC8vLyBub3JtYWwgJ0wnIGxhYmVsIGlzIHJldHVybmVkLgorICBNQ1N5bWJvbCAqZ2V0SlRJU3ltYm9sKHVuc2lnbmVkIEpUSSwgTUNDb250ZXh0ICZDdHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc0xpbmtlclByaXZhdGUgPSBmYWxzZSkgY29uc3Q7CisKKyAgLy8vIGdldFBJQ0Jhc2VTeW1ib2wgLSBSZXR1cm4gYSBmdW5jdGlvbi1sb2NhbCBzeW1ib2wgdG8gcmVwcmVzZW50IHRoZSBQSUMKKyAgLy8vIGJhc2UuCisgIE1DU3ltYm9sICpnZXRQSUNCYXNlU3ltYm9sKCkgY29uc3Q7CisKKyAgLy8vIFJldHVybnMgYSByZWZlcmVuY2UgdG8gYSBsaXN0IG9mIGNmaSBpbnN0cnVjdGlvbnMgaW4gdGhlIGZ1bmN0aW9uJ3MKKyAgLy8vIHByb2xvZ3VlLiAgVXNlZCB0byBjb25zdHJ1Y3QgZnJhbWUgbWFwcyBmb3IgZGVidWcgYW5kIGV4Y2VwdGlvbiBoYW5kbGluZworICAvLy8gY29tc3VtZXJzLgorICBjb25zdCBzdGQ6OnZlY3RvcjxNQ0NGSUluc3RydWN0aW9uPiAmZ2V0RnJhbWVJbnN0cnVjdGlvbnMoKSBjb25zdCB7CisgICAgcmV0dXJuIEZyYW1lSW5zdHJ1Y3Rpb25zOworICB9CisKKyAgTExWTV9OT0RJU0NBUkQgdW5zaWduZWQgYWRkRnJhbWVJbnN0KGNvbnN0IE1DQ0ZJSW5zdHJ1Y3Rpb24gJkluc3QpIHsKKyAgICBGcmFtZUluc3RydWN0aW9ucy5wdXNoX2JhY2soSW5zdCk7CisgICAgcmV0dXJuIEZyYW1lSW5zdHJ1Y3Rpb25zLnNpemUoKSAtIDE7CisgIH0KKworICAvLy8gXG5hbWUgRXhjZXB0aW9uIEhhbmRsaW5nCisgIC8vLyBceworCisgIGJvb2wgY2FsbHNFSFJldHVybigpIGNvbnN0IHsgcmV0dXJuIENhbGxzRUhSZXR1cm47IH0KKyAgdm9pZCBzZXRDYWxsc0VIUmV0dXJuKGJvb2wgYikgeyBDYWxsc0VIUmV0dXJuID0gYjsgfQorCisgIGJvb2wgY2FsbHNVbndpbmRJbml0KCkgY29uc3QgeyByZXR1cm4gQ2FsbHNVbndpbmRJbml0OyB9CisgIHZvaWQgc2V0Q2FsbHNVbndpbmRJbml0KGJvb2wgYikgeyBDYWxsc1Vud2luZEluaXQgPSBiOyB9CisKKyAgYm9vbCBoYXNFSEZ1bmNsZXRzKCkgY29uc3QgeyByZXR1cm4gSGFzRUhGdW5jbGV0czsgfQorICB2b2lkIHNldEhhc0VIRnVuY2xldHMoYm9vbCBWKSB7IEhhc0VIRnVuY2xldHMgPSBWOyB9CisKKyAgLy8vIEZpbmQgb3IgY3JlYXRlIGFuIExhbmRpbmdQYWRJbmZvIGZvciB0aGUgc3BlY2lmaWVkIE1hY2hpbmVCYXNpY0Jsb2NrLgorICBMYW5kaW5nUGFkSW5mbyAmZ2V0T3JDcmVhdGVMYW5kaW5nUGFkSW5mbyhNYWNoaW5lQmFzaWNCbG9jayAqTGFuZGluZ1BhZCk7CisKKyAgLy8vIFJlbWFwIGxhbmRpbmcgcGFkIGxhYmVscyBhbmQgcmVtb3ZlIGFueSBkZWxldGVkIGxhbmRpbmcgcGFkcy4KKyAgdm9pZCB0aWR5TGFuZGluZ1BhZHMoRGVuc2VNYXA8TUNTeW1ib2wqLCB1aW50cHRyX3Q+ICpMUE1hcCA9IG51bGxwdHIpOworCisgIC8vLyBSZXR1cm4gYSByZWZlcmVuY2UgdG8gdGhlIGxhbmRpbmcgcGFkIGluZm8gZm9yIHRoZSBjdXJyZW50IGZ1bmN0aW9uLgorICBjb25zdCBzdGQ6OnZlY3RvcjxMYW5kaW5nUGFkSW5mbz4gJmdldExhbmRpbmdQYWRzKCkgY29uc3QgeworICAgIHJldHVybiBMYW5kaW5nUGFkczsKKyAgfQorCisgIC8vLyBQcm92aWRlIHRoZSBiZWdpbiBhbmQgZW5kIGxhYmVscyBvZiBhbiBpbnZva2Ugc3R5bGUgY2FsbCBhbmQgYXNzb2NpYXRlIGl0CisgIC8vLyB3aXRoIGEgdHJ5IGxhbmRpbmcgcGFkIGJsb2NrLgorICB2b2lkIGFkZEludm9rZShNYWNoaW5lQmFzaWNCbG9jayAqTGFuZGluZ1BhZCwKKyAgICAgICAgICAgICAgICAgTUNTeW1ib2wgKkJlZ2luTGFiZWwsIE1DU3ltYm9sICpFbmRMYWJlbCk7CisKKyAgLy8vIEFkZCBhIG5ldyBwYW5kaW5nIHBhZC4gIFJldHVybnMgdGhlIGxhYmVsIElEIGZvciB0aGUgbGFuZGluZyBwYWQgZW50cnkuCisgIE1DU3ltYm9sICphZGRMYW5kaW5nUGFkKE1hY2hpbmVCYXNpY0Jsb2NrICpMYW5kaW5nUGFkKTsKKworICAvLy8gUHJvdmlkZSB0aGUgY2F0Y2ggdHlwZWluZm8gZm9yIGEgbGFuZGluZyBwYWQuCisgIHZvaWQgYWRkQ2F0Y2hUeXBlSW5mbyhNYWNoaW5lQmFzaWNCbG9jayAqTGFuZGluZ1BhZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPGNvbnN0IEdsb2JhbFZhbHVlICo+IFR5SW5mbyk7CisKKyAgLy8vIFByb3ZpZGUgdGhlIGZpbHRlciB0eXBlaW5mbyBmb3IgYSBsYW5kaW5nIHBhZC4KKyAgdm9pZCBhZGRGaWx0ZXJUeXBlSW5mbyhNYWNoaW5lQmFzaWNCbG9jayAqTGFuZGluZ1BhZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjxjb25zdCBHbG9iYWxWYWx1ZSAqPiBUeUluZm8pOworCisgIC8vLyBBZGQgYSBjbGVhbnVwIGFjdGlvbiBmb3IgYSBsYW5kaW5nIHBhZC4KKyAgdm9pZCBhZGRDbGVhbnVwKE1hY2hpbmVCYXNpY0Jsb2NrICpMYW5kaW5nUGFkKTsKKworICB2b2lkIGFkZFNFSENhdGNoSGFuZGxlcihNYWNoaW5lQmFzaWNCbG9jayAqTGFuZGluZ1BhZCwgY29uc3QgRnVuY3Rpb24gKkZpbHRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQmxvY2tBZGRyZXNzICpSZWNvdmVyTGFiZWwpOworCisgIHZvaWQgYWRkU0VIQ2xlYW51cEhhbmRsZXIoTWFjaGluZUJhc2ljQmxvY2sgKkxhbmRpbmdQYWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRnVuY3Rpb24gKkNsZWFudXApOworCisgIC8vLyBSZXR1cm4gdGhlIHR5cGUgaWQgZm9yIHRoZSBzcGVjaWZpZWQgdHlwZWluZm8uICBUaGlzIGlzIGZ1bmN0aW9uIHdpZGUuCisgIHVuc2lnbmVkIGdldFR5cGVJREZvcihjb25zdCBHbG9iYWxWYWx1ZSAqVEkpOworCisgIC8vLyBSZXR1cm4gdGhlIGlkIG9mIHRoZSBmaWx0ZXIgZW5jb2RlZCBieSBUeUlkcy4gIFRoaXMgaXMgZnVuY3Rpb24gd2lkZS4KKyAgaW50IGdldEZpbHRlcklERm9yKHN0ZDo6dmVjdG9yPHVuc2lnbmVkPiAmVHlJZHMpOworCisgIC8vLyBNYXAgdGhlIGxhbmRpbmcgcGFkJ3MgRUggc3ltYm9sIHRvIHRoZSBjYWxsIHNpdGUgaW5kZXhlcy4KKyAgdm9pZCBzZXRDYWxsU2l0ZUxhbmRpbmdQYWQoTUNTeW1ib2wgKlN5bSwgQXJyYXlSZWY8dW5zaWduZWQ+IFNpdGVzKTsKKworICAvLy8gR2V0IHRoZSBjYWxsIHNpdGUgaW5kZXhlcyBmb3IgYSBsYW5kaW5nIHBhZCBFSCBzeW1ib2wuCisgIFNtYWxsVmVjdG9ySW1wbDx1bnNpZ25lZD4gJmdldENhbGxTaXRlTGFuZGluZ1BhZChNQ1N5bWJvbCAqU3ltKSB7CisgICAgYXNzZXJ0KGhhc0NhbGxTaXRlTGFuZGluZ1BhZChTeW0pICYmCisgICAgICAgICAgICJtaXNzaW5nIGNhbGwgc2l0ZSBudW1iZXIgZm9yIGxhbmRpbmcgcGFkISIpOworICAgIHJldHVybiBMUGFkVG9DYWxsU2l0ZU1hcFtTeW1dOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBsYW5kaW5nIHBhZCBFaCBzeW1ib2wgaGFzIGFuIGFzc29jaWF0ZWQgY2FsbCBzaXRlLgorICBib29sIGhhc0NhbGxTaXRlTGFuZGluZ1BhZChNQ1N5bWJvbCAqU3ltKSB7CisgICAgcmV0dXJuICFMUGFkVG9DYWxsU2l0ZU1hcFtTeW1dLmVtcHR5KCk7CisgIH0KKworICAvLy8gTWFwIHRoZSBiZWdpbiBsYWJlbCBmb3IgYSBjYWxsIHNpdGUuCisgIHZvaWQgc2V0Q2FsbFNpdGVCZWdpbkxhYmVsKE1DU3ltYm9sICpCZWdpbkxhYmVsLCB1bnNpZ25lZCBTaXRlKSB7CisgICAgQ2FsbFNpdGVNYXBbQmVnaW5MYWJlbF0gPSBTaXRlOworICB9CisKKyAgLy8vIEdldCB0aGUgY2FsbCBzaXRlIG51bWJlciBmb3IgYSBiZWdpbiBsYWJlbC4KKyAgdW5zaWduZWQgZ2V0Q2FsbFNpdGVCZWdpbkxhYmVsKE1DU3ltYm9sICpCZWdpbkxhYmVsKSBjb25zdCB7CisgICAgYXNzZXJ0KGhhc0NhbGxTaXRlQmVnaW5MYWJlbChCZWdpbkxhYmVsKSAmJgorICAgICAgICAgICAiTWlzc2luZyBjYWxsIHNpdGUgbnVtYmVyIGZvciBFSF9MQUJFTCEiKTsKKyAgICByZXR1cm4gQ2FsbFNpdGVNYXAubG9va3VwKEJlZ2luTGFiZWwpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBiZWdpbiBsYWJlbCBoYXMgYSBjYWxsIHNpdGUgbnVtYmVyIGFzc29jaWF0ZWQgd2l0aCBpdC4KKyAgYm9vbCBoYXNDYWxsU2l0ZUJlZ2luTGFiZWwoTUNTeW1ib2wgKkJlZ2luTGFiZWwpIGNvbnN0IHsKKyAgICByZXR1cm4gQ2FsbFNpdGVNYXAuY291bnQoQmVnaW5MYWJlbCk7CisgIH0KKworICAvLy8gUmVjb3JkIGFubm90YXRpb25zIGFzc29jaWF0ZWQgd2l0aCBhIHBhcnRpY3VsYXIgbGFiZWwuCisgIHZvaWQgYWRkQ29kZVZpZXdBbm5vdGF0aW9uKE1DU3ltYm9sICpMYWJlbCwgTUROb2RlICpNRCkgeworICAgIENvZGVWaWV3QW5ub3RhdGlvbnMucHVzaF9iYWNrKHtMYWJlbCwgTUR9KTsKKyAgfQorCisgIEFycmF5UmVmPHN0ZDo6cGFpcjxNQ1N5bWJvbCAqLCBNRE5vZGUgKj4+IGdldENvZGVWaWV3QW5ub3RhdGlvbnMoKSBjb25zdCB7CisgICAgcmV0dXJuIENvZGVWaWV3QW5ub3RhdGlvbnM7CisgIH0KKworICAvLy8gUmV0dXJuIGEgcmVmZXJlbmNlIHRvIHRoZSBDKysgdHlwZWluZm8gZm9yIHRoZSBjdXJyZW50IGZ1bmN0aW9uLgorICBjb25zdCBzdGQ6OnZlY3Rvcjxjb25zdCBHbG9iYWxWYWx1ZSAqPiAmZ2V0VHlwZUluZm9zKCkgY29uc3QgeworICAgIHJldHVybiBUeXBlSW5mb3M7CisgIH0KKworICAvLy8gUmV0dXJuIGEgcmVmZXJlbmNlIHRvIHRoZSB0eXBlaWRzIGVuY29kaW5nIGZpbHRlcnMgdXNlZCBpbiB0aGUgY3VycmVudAorICAvLy8gZnVuY3Rpb24uCisgIGNvbnN0IHN0ZDo6dmVjdG9yPHVuc2lnbmVkPiAmZ2V0RmlsdGVySWRzKCkgY29uc3QgeworICAgIHJldHVybiBGaWx0ZXJJZHM7CisgIH0KKworICAvLy8gXH0KKworICAvLy8gQ29sbGVjdCBpbmZvcm1hdGlvbiB1c2VkIHRvIGVtaXQgZGVidWdnaW5nIGluZm9ybWF0aW9uIG9mIGEgdmFyaWFibGUuCisgIHZvaWQgc2V0VmFyaWFibGVEYmdJbmZvKGNvbnN0IERJTG9jYWxWYXJpYWJsZSAqVmFyLCBjb25zdCBESUV4cHJlc3Npb24gKkV4cHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFNsb3QsIGNvbnN0IERJTG9jYXRpb24gKkxvYykgeworICAgIFZhcmlhYmxlRGJnSW5mb3MuZW1wbGFjZV9iYWNrKFZhciwgRXhwciwgU2xvdCwgTG9jKTsKKyAgfQorCisgIFZhcmlhYmxlRGJnSW5mb01hcFR5ICZnZXRWYXJpYWJsZURiZ0luZm8oKSB7IHJldHVybiBWYXJpYWJsZURiZ0luZm9zOyB9CisgIGNvbnN0IFZhcmlhYmxlRGJnSW5mb01hcFR5ICZnZXRWYXJpYWJsZURiZ0luZm8oKSBjb25zdCB7CisgICAgcmV0dXJuIFZhcmlhYmxlRGJnSW5mb3M7CisgIH0KK307CisKKy8vLyBcbmFtZSBFeGNlcHRpb24gSGFuZGxpbmcKKy8vLyBceworCisvLy8gRXh0cmFjdCB0aGUgZXhjZXB0aW9uIGhhbmRsaW5nIGluZm9ybWF0aW9uIGZyb20gdGhlIGxhbmRpbmdwYWQgaW5zdHJ1Y3Rpb24KKy8vLyBhbmQgYWRkIHRoZW0gdG8gdGhlIHNwZWNpZmllZCBtYWNoaW5lIG1vZHVsZSBpbmZvLgordm9pZCBhZGRMYW5kaW5nUGFkSW5mbyhjb25zdCBMYW5kaW5nUGFkSW5zdCAmSSwgTWFjaGluZUJhc2ljQmxvY2sgJk1CQik7CisKKy8vLyBcfQorCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vIEdyYXBoVHJhaXRzIHNwZWNpYWxpemF0aW9ucyBmb3IgZnVuY3Rpb24gYmFzaWMgYmxvY2sgZ3JhcGhzIChDRkdzKQorLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKy8vIFByb3ZpZGUgc3BlY2lhbGl6YXRpb25zIG9mIEdyYXBoVHJhaXRzIHRvIGJlIGFibGUgdG8gdHJlYXQgYQorLy8gbWFjaGluZSBmdW5jdGlvbiBhcyBhIGdyYXBoIG9mIG1hY2hpbmUgYmFzaWMgYmxvY2tzLi4uIHRoZXNlIGFyZQorLy8gdGhlIHNhbWUgYXMgdGhlIG1hY2hpbmUgYmFzaWMgYmxvY2sgaXRlcmF0b3JzLCBleGNlcHQgdGhhdCB0aGUgcm9vdAorLy8gbm9kZSBpcyBpbXBsaWNpdGx5IHRoZSBmaXJzdCBub2RlIG9mIHRoZSBmdW5jdGlvbi4KKy8vCit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgR3JhcGhUcmFpdHM8TWFjaGluZUZ1bmN0aW9uKj4gOgorICBwdWJsaWMgR3JhcGhUcmFpdHM8TWFjaGluZUJhc2ljQmxvY2sqPiB7CisgIHN0YXRpYyBOb2RlUmVmIGdldEVudHJ5Tm9kZShNYWNoaW5lRnVuY3Rpb24gKkYpIHsgcmV0dXJuICZGLT5mcm9udCgpOyB9CisKKyAgLy8gbm9kZXNfaXRlcmF0b3IvYmVnaW4vZW5kIC0gQWxsb3cgaXRlcmF0aW9uIG92ZXIgYWxsIG5vZGVzIGluIHRoZSBncmFwaAorICB1c2luZyBub2Rlc19pdGVyYXRvciA9IHBvaW50ZXJfaXRlcmF0b3I8TWFjaGluZUZ1bmN0aW9uOjppdGVyYXRvcj47CisKKyAgc3RhdGljIG5vZGVzX2l0ZXJhdG9yIG5vZGVzX2JlZ2luKE1hY2hpbmVGdW5jdGlvbiAqRikgeworICAgIHJldHVybiBub2Rlc19pdGVyYXRvcihGLT5iZWdpbigpKTsKKyAgfQorCisgIHN0YXRpYyBub2Rlc19pdGVyYXRvciBub2Rlc19lbmQoTWFjaGluZUZ1bmN0aW9uICpGKSB7CisgICAgcmV0dXJuIG5vZGVzX2l0ZXJhdG9yKEYtPmVuZCgpKTsKKyAgfQorCisgIHN0YXRpYyB1bnNpZ25lZCAgICAgICBzaXplICAgICAgIChNYWNoaW5lRnVuY3Rpb24gKkYpIHsgcmV0dXJuIEYtPnNpemUoKTsgfQorfTsKK3RlbXBsYXRlIDw+IHN0cnVjdCBHcmFwaFRyYWl0czxjb25zdCBNYWNoaW5lRnVuY3Rpb24qPiA6CisgIHB1YmxpYyBHcmFwaFRyYWl0czxjb25zdCBNYWNoaW5lQmFzaWNCbG9jayo+IHsKKyAgc3RhdGljIE5vZGVSZWYgZ2V0RW50cnlOb2RlKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAqRikgeyByZXR1cm4gJkYtPmZyb250KCk7IH0KKworICAvLyBub2Rlc19pdGVyYXRvci9iZWdpbi9lbmQgLSBBbGxvdyBpdGVyYXRpb24gb3ZlciBhbGwgbm9kZXMgaW4gdGhlIGdyYXBoCisgIHVzaW5nIG5vZGVzX2l0ZXJhdG9yID0gcG9pbnRlcl9pdGVyYXRvcjxNYWNoaW5lRnVuY3Rpb246OmNvbnN0X2l0ZXJhdG9yPjsKKworICBzdGF0aWMgbm9kZXNfaXRlcmF0b3Igbm9kZXNfYmVnaW4oY29uc3QgTWFjaGluZUZ1bmN0aW9uICpGKSB7CisgICAgcmV0dXJuIG5vZGVzX2l0ZXJhdG9yKEYtPmJlZ2luKCkpOworICB9CisKKyAgc3RhdGljIG5vZGVzX2l0ZXJhdG9yIG5vZGVzX2VuZCAgKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAqRikgeworICAgIHJldHVybiBub2Rlc19pdGVyYXRvcihGLT5lbmQoKSk7CisgIH0KKworICBzdGF0aWMgdW5zaWduZWQgICAgICAgc2l6ZSAgICAgICAoY29uc3QgTWFjaGluZUZ1bmN0aW9uICpGKSAgeworICAgIHJldHVybiBGLT5zaXplKCk7CisgIH0KK307CisKKy8vIFByb3ZpZGUgc3BlY2lhbGl6YXRpb25zIG9mIEdyYXBoVHJhaXRzIHRvIGJlIGFibGUgdG8gdHJlYXQgYSBmdW5jdGlvbiBhcyBhCisvLyBncmFwaCBvZiBiYXNpYyBibG9ja3MuLi4gYW5kIHRvIHdhbGsgaXQgaW4gaW52ZXJzZSBvcmRlci4gIEludmVyc2Ugb3JkZXIgZm9yCisvLyBhIGZ1bmN0aW9uIGlzIGNvbnNpZGVyZWQgdG8gYmUgd2hlbiB0cmF2ZXJzaW5nIHRoZSBwcmVkZWNlc3NvciBlZGdlcyBvZiBhIEJCCisvLyBpbnN0ZWFkIG9mIHRoZSBzdWNjZXNzb3IgZWRnZXMuCisvLwordGVtcGxhdGUgPD4gc3RydWN0IEdyYXBoVHJhaXRzPEludmVyc2U8TWFjaGluZUZ1bmN0aW9uKj4+IDoKKyAgcHVibGljIEdyYXBoVHJhaXRzPEludmVyc2U8TWFjaGluZUJhc2ljQmxvY2sqPj4geworICBzdGF0aWMgTm9kZVJlZiBnZXRFbnRyeU5vZGUoSW52ZXJzZTxNYWNoaW5lRnVuY3Rpb24gKj4gRykgeworICAgIHJldHVybiAmRy5HcmFwaC0+ZnJvbnQoKTsKKyAgfQorfTsKK3RlbXBsYXRlIDw+IHN0cnVjdCBHcmFwaFRyYWl0czxJbnZlcnNlPGNvbnN0IE1hY2hpbmVGdW5jdGlvbio+PiA6CisgIHB1YmxpYyBHcmFwaFRyYWl0czxJbnZlcnNlPGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrKj4+IHsKKyAgc3RhdGljIE5vZGVSZWYgZ2V0RW50cnlOb2RlKEludmVyc2U8Y29uc3QgTWFjaGluZUZ1bmN0aW9uICo+IEcpIHsKKyAgICByZXR1cm4gJkcuR3JhcGgtPmZyb250KCk7CisgIH0KK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTUFDSElORUZVTkNUSU9OX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lRnVuY3Rpb25QYXNzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uUGFzcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZkOTc4ZGEKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uUGFzcy5oCkBAIC0wLDAgKzEsODEgQEAKKy8vPT09LS0gTWFjaGluZUZ1bmN0aW9uUGFzcy5oIC0gUGFzcyBmb3IgTWFjaGluZUZ1bmN0aW9ucyAtLS0tLS0tLSotQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlZmluZXMgdGhlIE1hY2hpbmVGdW5jdGlvblBhc3MgY2xhc3MuICBNYWNoaW5lRnVuY3Rpb25QYXNzJ3MgYXJlCisvLyBqdXN0IEZ1bmN0aW9uUGFzcydzLCBleGNlcHQgdGhleSBvcGVyYXRlIG9uIG1hY2hpbmUgY29kZSBhcyBwYXJ0IG9mIGEgY29kZQorLy8gZ2VuZXJhdG9yLiAgQmVjYXVzZSB0aGV5IG9wZXJhdGUgb24gbWFjaGluZSBjb2RlLCBub3QgdGhlIExMVk0KKy8vIHJlcHJlc2VudGF0aW9uLCBNYWNoaW5lRnVuY3Rpb25QYXNzJ3MgYXJlIG5vdCBhbGxvd2VkIHRvIG1vZGlmeSB0aGUgTExWTQorLy8gcmVwcmVzZW50YXRpb24uICBEdWUgdG8gdGhpcyBsaW1pdGF0aW9uLCB0aGUgTWFjaGluZUZ1bmN0aW9uUGFzcyBjbGFzcyB0YWtlcworLy8gY2FyZSBvZiBkZWNsYXJpbmcgdGhhdCBubyBMTFZNIHBhc3NlcyBhcmUgaW52YWxpZGF0ZWQuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORUZVTkNUSU9OUEFTU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9NQUNISU5FRlVOQ1RJT05QQVNTX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lRnVuY3Rpb24uaCIKKyNpbmNsdWRlICJsbHZtL1Bhc3MuaCIKKworbmFtZXNwYWNlIGxsdm0geworCisvLy8gTWFjaGluZUZ1bmN0aW9uUGFzcyAtIFRoaXMgY2xhc3MgYWRhcHRzIHRoZSBGdW5jdGlvblBhc3MgaW50ZXJmYWNlIHRvCisvLy8gYWxsb3cgY29udmVuaWVudCBjcmVhdGlvbiBvZiBwYXNzZXMgdGhhdCBvcGVyYXRlIG9uIHRoZSBNYWNoaW5lRnVuY3Rpb24KKy8vLyByZXByZXNlbnRhdGlvbi4gSW5zdGVhZCBvZiBvdmVycmlkaW5nIHJ1bk9uRnVuY3Rpb24sIHN1YmNsYXNzZXMKKy8vLyBvdmVycmlkZSBydW5Pbk1hY2hpbmVGdW5jdGlvbi4KK2NsYXNzIE1hY2hpbmVGdW5jdGlvblBhc3MgOiBwdWJsaWMgRnVuY3Rpb25QYXNzIHsKK3B1YmxpYzoKKyAgYm9vbCBkb0luaXRpYWxpemF0aW9uKE1vZHVsZSYpIG92ZXJyaWRlIHsKKyAgICAvLyBDYWNoZSB0aGUgcHJvcGVydGllcyBpbmZvIGF0IG1vZHVsZS1pbml0IHRpbWUgc28gd2UgZG9uJ3QgaGF2ZSB0bworICAgIC8vIGNvbnN0cnVjdCB0aGVtIGZvciBldmVyeSBmdW5jdGlvbi4KKyAgICBSZXF1aXJlZFByb3BlcnRpZXMgPSBnZXRSZXF1aXJlZFByb3BlcnRpZXMoKTsKKyAgICBTZXRQcm9wZXJ0aWVzID0gZ2V0U2V0UHJvcGVydGllcygpOworICAgIENsZWFyZWRQcm9wZXJ0aWVzID0gZ2V0Q2xlYXJlZFByb3BlcnRpZXMoKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KK3Byb3RlY3RlZDoKKyAgZXhwbGljaXQgTWFjaGluZUZ1bmN0aW9uUGFzcyhjaGFyICZJRCkgOiBGdW5jdGlvblBhc3MoSUQpIHt9CisKKyAgLy8vIHJ1bk9uTWFjaGluZUZ1bmN0aW9uIC0gVGhpcyBtZXRob2QgbXVzdCBiZSBvdmVybG9hZGVkIHRvIHBlcmZvcm0gdGhlCisgIC8vLyBkZXNpcmVkIG1hY2hpbmUgY29kZSB0cmFuc2Zvcm1hdGlvbiBvciBhbmFseXNpcy4KKyAgLy8vCisgIHZpcnR1YWwgYm9vbCBydW5Pbk1hY2hpbmVGdW5jdGlvbihNYWNoaW5lRnVuY3Rpb24gJk1GKSA9IDA7CisKKyAgLy8vIGdldEFuYWx5c2lzVXNhZ2UgLSBTdWJjbGFzc2VzIHRoYXQgb3ZlcnJpZGUgZ2V0QW5hbHlzaXNVc2FnZQorICAvLy8gbXVzdCBjYWxsIHRoaXMuCisgIC8vLworICAvLy8gRm9yIE1hY2hpbmVGdW5jdGlvblBhc3NlcywgY2FsbGluZyBBVS5wcmVzZXJ2ZXNDRkcoKSBpbmRpY2F0ZXMgdGhhdAorICAvLy8gdGhlIHBhc3MgZG9lcyBub3QgbW9kaWZ5IHRoZSBNYWNoaW5lQmFzaWNCbG9jayBDRkcuCisgIC8vLworICB2b2lkIGdldEFuYWx5c2lzVXNhZ2UoQW5hbHlzaXNVc2FnZSAmQVUpIGNvbnN0IG92ZXJyaWRlOworCisgIHZpcnR1YWwgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcyBnZXRSZXF1aXJlZFByb3BlcnRpZXMoKSBjb25zdCB7CisgICAgcmV0dXJuIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMoKTsKKyAgfQorICB2aXJ0dWFsIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMgZ2V0U2V0UHJvcGVydGllcygpIGNvbnN0IHsKKyAgICByZXR1cm4gTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcygpOworICB9CisgIHZpcnR1YWwgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcyBnZXRDbGVhcmVkUHJvcGVydGllcygpIGNvbnN0IHsKKyAgICByZXR1cm4gTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcygpOworICB9CisKK3ByaXZhdGU6CisgIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMgUmVxdWlyZWRQcm9wZXJ0aWVzOworICBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzIFNldFByb3BlcnRpZXM7CisgIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMgQ2xlYXJlZFByb3BlcnRpZXM7CisKKyAgLy8vIGNyZWF0ZVByaW50ZXJQYXNzIC0gR2V0IGEgbWFjaGluZSBmdW5jdGlvbiBwcmludGVyIHBhc3MuCisgIFBhc3MgKmNyZWF0ZVByaW50ZXJQYXNzKHJhd19vc3RyZWFtICZPLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGQ6OnN0cmluZyAmQmFubmVyKSBjb25zdCBvdmVycmlkZTsKKworICBib29sIHJ1bk9uRnVuY3Rpb24oRnVuY3Rpb24gJkYpIG92ZXJyaWRlOworfTsKKworfSAvLyBFbmQgbGx2bSBuYW1lc3BhY2UKKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUluc3RyLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUluc3RyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWE5NGJlMAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lSW5zdHIuaApAQCAtMCwwICsxLDE0MDcgQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vTWFjaGluZUluc3RyLmggLSBNYWNoaW5lSW5zdHIgY2xhc3MgLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBkZWNsYXJhdGlvbiBvZiB0aGUgTWFjaGluZUluc3RyIGNsYXNzLCB3aGljaCBpcyB0aGUKKy8vIGJhc2ljIHJlcHJlc2VudGF0aW9uIGZvciBhbGwgdGFyZ2V0IGRlcGVuZGVudCBtYWNoaW5lIGluc3RydWN0aW9ucyB1c2VkIGJ5CisvLyB0aGUgYmFjayBlbmQuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORUlOU1RSX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX01BQ0hJTkVJTlNUUl9ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9EZW5zZU1hcEluZm8uaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9pbGlzdC5oIgorI2luY2x1ZGUgImxsdm0vQURUL2lsaXN0X25vZGUuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9pdGVyYXRvcl9yYW5nZS5oIgorI2luY2x1ZGUgImxsdm0vQW5hbHlzaXMvQWxpYXNBbmFseXNpcy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lT3BlcmFuZC5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9UYXJnZXRPcGNvZGVzLmgiCisjaW5jbHVkZSAibGx2bS9JUi9EZWJ1Z0xvYy5oIgorI2luY2x1ZGUgImxsdm0vSVIvSW5saW5lQXNtLmgiCisjaW5jbHVkZSAibGx2bS9NQy9NQ0luc3RyRGVzYy5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9BcnJheVJlY3ljbGVyLmgiCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8Y3N0ZGludD4KKyNpbmNsdWRlIDx1dGlsaXR5PgorCituYW1lc3BhY2UgbGx2bSB7CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBUPiBjbGFzcyBBcnJheVJlZjsKK2NsYXNzIERJRXhwcmVzc2lvbjsKK2NsYXNzIERJTG9jYWxWYXJpYWJsZTsKK2NsYXNzIE1hY2hpbmVCYXNpY0Jsb2NrOworY2xhc3MgTWFjaGluZUZ1bmN0aW9uOworY2xhc3MgTWFjaGluZU1lbU9wZXJhbmQ7CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworY2xhc3MgTW9kdWxlU2xvdFRyYWNrZXI7CitjbGFzcyByYXdfb3N0cmVhbTsKK3RlbXBsYXRlIDx0eXBlbmFtZSBUPiBjbGFzcyBTbWFsbFZlY3RvckltcGw7CitjbGFzcyBTbWFsbEJpdFZlY3RvcjsKK2NsYXNzIFN0cmluZ1JlZjsKK2NsYXNzIFRhcmdldEluc3RySW5mbzsKK2NsYXNzIFRhcmdldFJlZ2lzdGVyQ2xhc3M7CitjbGFzcyBUYXJnZXRSZWdpc3RlckluZm87CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gUmVwcmVzZW50YXRpb24gb2YgZWFjaCBtYWNoaW5lIGluc3RydWN0aW9uLgorLy8vCisvLy8gVGhpcyBjbGFzcyBpc24ndCBhIFBPRCB0eXBlLCBidXQgaXQgbXVzdCBoYXZlIGEgdHJpdmlhbCBkZXN0cnVjdG9yLiBXaGVuIGEKKy8vLyBNYWNoaW5lRnVuY3Rpb24gaXMgZGVsZXRlZCwgYWxsIHRoZSBjb250YWluZWQgTWFjaGluZUluc3RycyBhcmUgZGVhbGxvY2F0ZWQKKy8vLyB3aXRob3V0IGhhdmluZyB0aGVpciBkZXN0cnVjdG9yIGNhbGxlZC4KKy8vLworY2xhc3MgTWFjaGluZUluc3RyCisgICAgOiBwdWJsaWMgaWxpc3Rfbm9kZV93aXRoX3BhcmVudDxNYWNoaW5lSW5zdHIsIE1hY2hpbmVCYXNpY0Jsb2NrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWxpc3Rfc2VudGluZWxfdHJhY2tpbmc8dHJ1ZT4+IHsKK3B1YmxpYzoKKyAgdXNpbmcgbW1vX2l0ZXJhdG9yID0gTWFjaGluZU1lbU9wZXJhbmQgKio7CisKKyAgLy8vIEZsYWdzIHRvIHNwZWNpZnkgZGlmZmVyZW50IGtpbmRzIG9mIGNvbW1lbnRzIHRvIG91dHB1dCBpbgorICAvLy8gYXNzZW1ibHkgY29kZS4gIFRoZXNlIGZsYWdzIGNhcnJ5IHNlbWFudGljIGluZm9ybWF0aW9uIG5vdAorICAvLy8gb3RoZXJ3aXNlIGVhc2lseSBkZXJpdmFibGUgZnJvbSB0aGUgSVIgdGV4dC4KKyAgLy8vCisgIGVudW0gQ29tbWVudEZsYWcgeworICAgIFJlbG9hZFJldXNlID0gMHgxLCAgICAvLyBoaWdoZXIgYml0cyBhcmUgcmVzZXJ2ZWQgZm9yIHRhcmdldCBkZXAgY29tbWVudHMuCisgICAgTm9TY2hlZENvbW1lbnQgPSAweDIsCisgICAgVEFzbUNvbW1lbnRzID0gMHg0ICAgIC8vIFRhcmdldCBBc20gY29tbWVudHMgc2hvdWxkIHN0YXJ0IGZyb20gdGhpcyB2YWx1ZS4KKyAgfTsKKworICBlbnVtIE1JRmxhZyB7CisgICAgTm9GbGFncyAgICAgID0gMCwKKyAgICBGcmFtZVNldHVwICAgPSAxIDw8IDAsICAgICAgICAgICAgICAvLyBJbnN0cnVjdGlvbiBpcyB1c2VkIGFzIGEgcGFydCBvZgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZ1bmN0aW9uIGZyYW1lIHNldHVwIGNvZGUuCisgICAgRnJhbWVEZXN0cm95ID0gMSA8PCAxLCAgICAgICAgICAgICAgLy8gSW5zdHJ1Y3Rpb24gaXMgdXNlZCBhcyBhIHBhcnQgb2YKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmdW5jdGlvbiBmcmFtZSBkZXN0cnVjdGlvbiBjb2RlLgorICAgIEJ1bmRsZWRQcmVkICA9IDEgPDwgMiwgICAgICAgICAgICAgIC8vIEluc3RydWN0aW9uIGhhcyBidW5kbGVkIHByZWRlY2Vzc29ycy4KKyAgICBCdW5kbGVkU3VjYyAgPSAxIDw8IDMgICAgICAgICAgICAgICAvLyBJbnN0cnVjdGlvbiBoYXMgYnVuZGxlZCBzdWNjZXNzb3JzLgorICB9OworCitwcml2YXRlOgorICBjb25zdCBNQ0luc3RyRGVzYyAqTUNJRDsgICAgICAgICAgICAgIC8vIEluc3RydWN0aW9uIGRlc2NyaXB0b3IuCisgIE1hY2hpbmVCYXNpY0Jsb2NrICpQYXJlbnQgPSBudWxscHRyOyAgLy8gUG9pbnRlciB0byB0aGUgb3duaW5nIGJhc2ljIGJsb2NrLgorCisgIC8vIE9wZXJhbmRzIGFyZSBhbGxvY2F0ZWQgYnkgYW4gQXJyYXlSZWN5Y2xlci4KKyAgTWFjaGluZU9wZXJhbmQgKk9wZXJhbmRzID0gbnVsbHB0cjsgICAvLyBQb2ludGVyIHRvIHRoZSBmaXJzdCBvcGVyYW5kLgorICB1bnNpZ25lZCBOdW1PcGVyYW5kcyA9IDA7ICAgICAgICAgICAgIC8vIE51bWJlciBvZiBvcGVyYW5kcyBvbiBpbnN0cnVjdGlvbi4KKyAgdXNpbmcgT3BlcmFuZENhcGFjaXR5ID0gQXJyYXlSZWN5Y2xlcjxNYWNoaW5lT3BlcmFuZD46OkNhcGFjaXR5OworICBPcGVyYW5kQ2FwYWNpdHkgQ2FwT3BlcmFuZHM7ICAgICAgICAgIC8vIENhcGFjaXR5IG9mIHRoZSBPcGVyYW5kcyBhcnJheS4KKworICB1aW50OF90IEZsYWdzID0gMDsgICAgICAgICAgICAgICAgICAgIC8vIFZhcmlvdXMgYml0cyBvZiBhZGRpdGlvbmFsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5mb3JtYXRpb24gYWJvdXQgbWFjaGluZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluc3RydWN0aW9uLgorCisgIHVpbnQ4X3QgQXNtUHJpbnRlckZsYWdzID0gMDsgICAgICAgICAgLy8gVmFyaW91cyBiaXRzIG9mIGluZm9ybWF0aW9uIHVzZWQgYnkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgQXNtUHJpbnRlciB0byBlbWl0IGhlbHBmdWwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb21tZW50cy4gIFRoaXMgaXMgKm5vdCogc2VtYW50aWMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbmZvcm1hdGlvbi4gIERvIG5vdCB1c2UgdGhpcyBmb3IKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbnl0aGluZyBvdGhlciB0aGFuIHRvIGNvbnZleSBjb21tZW50CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5mb3JtYXRpb24gdG8gQXNtUHJpbnRlci4KKworICB1aW50OF90IE51bU1lbVJlZnMgPSAwOyAgICAgICAgICAgICAgIC8vIEluZm9ybWF0aW9uIG9uIG1lbW9yeSByZWZlcmVuY2VzLgorICAvLyBOb3RlIHRoYXQgTWVtUmVmcyA9PSBudWxscHRyLCAgbWVhbnMgJ2Rvbid0IGtub3cnLCBub3QgJ25vIG1lbW9yeSBhY2Nlc3MnLgorICAvLyBDYWxsaW5nIGNvZGUgbXVzdCB0cmVhdCBtaXNzaW5nIGluZm9ybWF0aW9uIGNvbnNlcnZhdGl2ZWx5LiAgSWYgdGhlIG51bWJlcgorICAvLyBvZiBtZW1vcnkgb3BlcmFuZHMgcmVxdWlyZWQgdG8gYmUgcHJlY2lzZSBleGNlZWRzIHRoZSBtYXhpbXVtIHZhbHVlIG9mCisgIC8vIE51bU1lbVJlZnMgLSBjdXJyZW50bHkgMjU2IC0gd2UgcmVtb3ZlIHRoZSBvcGVyYW5kcyBlbnRpcmVseS4gTm90ZSBhbHNvCisgIC8vIHRoYXQgdGhpcyBpcyBhIG5vbi1vd25pbmcgcmVmZXJlbmNlIHRvIGEgc2hhcmVkIGNvcHkgb24gd3JpdGUgYnVmZmVyIG93bmVkCisgIC8vIGJ5IHRoZSBNYWNoaW5lRnVuY3Rpb24gYW5kIGNyZWF0ZWQgdmlhIE1GLmFsbG9jYXRlTWVtUmVmc0FycmF5LgorICBtbW9faXRlcmF0b3IgTWVtUmVmcyA9IG51bGxwdHI7CisKKyAgRGVidWdMb2MgZGVidWdMb2M7ICAgICAgICAgICAgICAgICAgICAvLyBTb3VyY2UgbGluZSBpbmZvcm1hdGlvbi4KKworICAvLyBJbnRydXNpdmUgbGlzdCBzdXBwb3J0CisgIGZyaWVuZCBzdHJ1Y3QgaWxpc3RfdHJhaXRzPE1hY2hpbmVJbnN0cj47CisgIGZyaWVuZCBzdHJ1Y3QgaWxpc3RfY2FsbGJhY2tfdHJhaXRzPE1hY2hpbmVCYXNpY0Jsb2NrPjsKKyAgdm9pZCBzZXRQYXJlbnQoTWFjaGluZUJhc2ljQmxvY2sgKlApIHsgUGFyZW50ID0gUDsgfQorCisgIC8vLyBUaGlzIGNvbnN0cnVjdG9yIGNyZWF0ZXMgYSBjb3B5IG9mIHRoZSBnaXZlbgorICAvLy8gTWFjaGluZUluc3RyIGluIHRoZSBnaXZlbiBNYWNoaW5lRnVuY3Rpb24uCisgIE1hY2hpbmVJbnN0cihNYWNoaW5lRnVuY3Rpb24gJiwgY29uc3QgTWFjaGluZUluc3RyICYpOworCisgIC8vLyBUaGlzIGNvbnN0cnVjdG9yIGNyZWF0ZSBhIE1hY2hpbmVJbnN0ciBhbmQgYWRkIHRoZSBpbXBsaWNpdCBvcGVyYW5kcy4KKyAgLy8vIEl0IHJlc2VydmVzIHNwYWNlIGZvciBudW1iZXIgb2Ygb3BlcmFuZHMgc3BlY2lmaWVkIGJ5CisgIC8vLyBNQ0luc3RyRGVzYy4gIEFuIGV4cGxpY2l0IERlYnVnTG9jIGlzIHN1cHBsaWVkLgorICBNYWNoaW5lSW5zdHIoTWFjaGluZUZ1bmN0aW9uICYsIGNvbnN0IE1DSW5zdHJEZXNjICZNQ0lELCBEZWJ1Z0xvYyBkbCwKKyAgICAgICAgICAgICAgIGJvb2wgTm9JbXAgPSBmYWxzZSk7CisKKyAgLy8gTWFjaGluZUluc3RycyBhcmUgcG9vbC1hbGxvY2F0ZWQgYW5kIG93bmVkIGJ5IE1hY2hpbmVGdW5jdGlvbi4KKyAgZnJpZW5kIGNsYXNzIE1hY2hpbmVGdW5jdGlvbjsKKworcHVibGljOgorICBNYWNoaW5lSW5zdHIoY29uc3QgTWFjaGluZUluc3RyICYpID0gZGVsZXRlOworICBNYWNoaW5lSW5zdHIgJm9wZXJhdG9yPShjb25zdCBNYWNoaW5lSW5zdHIgJikgPSBkZWxldGU7CisgIC8vIFVzZSBNYWNoaW5lRnVuY3Rpb246OkRlbGV0ZU1hY2hpbmVJbnN0cigpIGluc3RlYWQuCisgIH5NYWNoaW5lSW5zdHIoKSA9IGRlbGV0ZTsKKworICBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayogZ2V0UGFyZW50KCkgY29uc3QgeyByZXR1cm4gUGFyZW50OyB9CisgIE1hY2hpbmVCYXNpY0Jsb2NrKiBnZXRQYXJlbnQoKSB7IHJldHVybiBQYXJlbnQ7IH0KKworICAvLy8gUmV0dXJuIHRoZSBmdW5jdGlvbiB0aGF0IGNvbnRhaW5zIHRoZSBiYXNpYyBibG9jayB0aGF0IHRoaXMgaW5zdHJ1Y3Rpb24KKyAgLy8vIGJlbG9uZ3MgdG8uCisgIC8vLworICAvLy8gTm90ZTogdGhpcyBpcyB1bmRlZmluZWQgYmVoYXZpb3VyIGlmIHRoZSBpbnN0cnVjdGlvbiBkb2VzIG5vdCBoYXZlIGEKKyAgLy8vIHBhcmVudC4KKyAgY29uc3QgTWFjaGluZUZ1bmN0aW9uICpnZXRNRigpIGNvbnN0OworICBNYWNoaW5lRnVuY3Rpb24gKmdldE1GKCkgeworICAgIHJldHVybiBjb25zdF9jYXN0PE1hY2hpbmVGdW5jdGlvbiAqPigKKyAgICAgICAgc3RhdGljX2Nhc3Q8Y29uc3QgTWFjaGluZUluc3RyICo+KHRoaXMpLT5nZXRNRigpKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIGFzbSBwcmludGVyIGZsYWdzIGJpdHZlY3Rvci4KKyAgdWludDhfdCBnZXRBc21QcmludGVyRmxhZ3MoKSBjb25zdCB7IHJldHVybiBBc21QcmludGVyRmxhZ3M7IH0KKworICAvLy8gQ2xlYXIgdGhlIEFzbVByaW50ZXIgYml0dmVjdG9yLgorICB2b2lkIGNsZWFyQXNtUHJpbnRlckZsYWdzKCkgeyBBc21QcmludGVyRmxhZ3MgPSAwOyB9CisKKyAgLy8vIFJldHVybiB3aGV0aGVyIGFuIEFzbVByaW50ZXIgZmxhZyBpcyBzZXQuCisgIGJvb2wgZ2V0QXNtUHJpbnRlckZsYWcoQ29tbWVudEZsYWcgRmxhZykgY29uc3QgeworICAgIHJldHVybiBBc21QcmludGVyRmxhZ3MgJiBGbGFnOworICB9CisKKyAgLy8vIFNldCBhIGZsYWcgZm9yIHRoZSBBc21QcmludGVyLgorICB2b2lkIHNldEFzbVByaW50ZXJGbGFnKHVpbnQ4X3QgRmxhZykgeworICAgIEFzbVByaW50ZXJGbGFncyB8PSBGbGFnOworICB9CisKKyAgLy8vIENsZWFyIHNwZWNpZmljIEFzbVByaW50ZXIgZmxhZ3MuCisgIHZvaWQgY2xlYXJBc21QcmludGVyRmxhZyhDb21tZW50RmxhZyBGbGFnKSB7CisgICAgQXNtUHJpbnRlckZsYWdzICY9IH5GbGFnOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgTUkgZmxhZ3MgYml0dmVjdG9yLgorICB1aW50OF90IGdldEZsYWdzKCkgY29uc3QgeworICAgIHJldHVybiBGbGFnczsKKyAgfQorCisgIC8vLyBSZXR1cm4gd2hldGhlciBhbiBNSSBmbGFnIGlzIHNldC4KKyAgYm9vbCBnZXRGbGFnKE1JRmxhZyBGbGFnKSBjb25zdCB7CisgICAgcmV0dXJuIEZsYWdzICYgRmxhZzsKKyAgfQorCisgIC8vLyBTZXQgYSBNSSBmbGFnLgorICB2b2lkIHNldEZsYWcoTUlGbGFnIEZsYWcpIHsKKyAgICBGbGFncyB8PSAodWludDhfdClGbGFnOworICB9CisKKyAgdm9pZCBzZXRGbGFncyh1bnNpZ25lZCBmbGFncykgeworICAgIC8vIEZpbHRlciBvdXQgdGhlIGF1dG9tYXRpY2FsbHkgbWFpbnRhaW5lZCBmbGFncy4KKyAgICB1bnNpZ25lZCBNYXNrID0gQnVuZGxlZFByZWQgfCBCdW5kbGVkU3VjYzsKKyAgICBGbGFncyA9IChGbGFncyAmIE1hc2spIHwgKGZsYWdzICYgfk1hc2spOworICB9CisKKyAgLy8vIGNsZWFyRmxhZyAtIENsZWFyIGEgTUkgZmxhZy4KKyAgdm9pZCBjbGVhckZsYWcoTUlGbGFnIEZsYWcpIHsKKyAgICBGbGFncyAmPSB+KCh1aW50OF90KUZsYWcpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIE1JIGlzIGluIGEgYnVuZGxlIChidXQgbm90IHRoZSBmaXJzdCBNSSBpbiBhIGJ1bmRsZSkuCisgIC8vLworICAvLy8gQSBidW5kbGUgbG9va3MgbGlrZSB0aGlzIGJlZm9yZSBpdCdzIGZpbmFsaXplZDoKKyAgLy8vICAgLS0tLS0tLS0tLS0tLS0tLQorICAvLy8gICB8ICAgICAgTUkgICAgICB8CisgIC8vLyAgIC0tLS0tLS0tLS0tLS0tLS0KKyAgLy8vICAgICAgICAgIHwKKyAgLy8vICAgLS0tLS0tLS0tLS0tLS0tLQorICAvLy8gICB8ICAgICAgTUkgICAgKiB8CisgIC8vLyAgIC0tLS0tLS0tLS0tLS0tLS0KKyAgLy8vICAgICAgICAgIHwKKyAgLy8vICAgLS0tLS0tLS0tLS0tLS0tLQorICAvLy8gICB8ICAgICAgTUkgICAgKiB8CisgIC8vLyAgIC0tLS0tLS0tLS0tLS0tLS0KKyAgLy8vIEluIHRoaXMgY2FzZSwgdGhlIGZpcnN0IE1JIHN0YXJ0cyBhIGJ1bmRsZSBidXQgaXMgbm90IGluc2lkZSBhIGJ1bmRsZSwgdGhlCisgIC8vLyBuZXh0IDIgTUlzIGFyZSBjb25zaWRlcmVkICJpbnNpZGUiIHRoZSBidW5kbGUuCisgIC8vLworICAvLy8gQWZ0ZXIgYSBidW5kbGUgaXMgZmluYWxpemVkLCBpdCBsb29rcyBsaWtlIHRoaXM6CisgIC8vLyAgIC0tLS0tLS0tLS0tLS0tLS0KKyAgLy8vICAgfCAgICBCdW5kbGUgICAgfAorICAvLy8gICAtLS0tLS0tLS0tLS0tLS0tCisgIC8vLyAgICAgICAgICB8CisgIC8vLyAgIC0tLS0tLS0tLS0tLS0tLS0KKyAgLy8vICAgfCAgICAgIE1JICAgICogfAorICAvLy8gICAtLS0tLS0tLS0tLS0tLS0tCisgIC8vLyAgICAgICAgICB8CisgIC8vLyAgIC0tLS0tLS0tLS0tLS0tLS0KKyAgLy8vICAgfCAgICAgIE1JICAgICogfAorICAvLy8gICAtLS0tLS0tLS0tLS0tLS0tCisgIC8vLyAgICAgICAgICB8CisgIC8vLyAgIC0tLS0tLS0tLS0tLS0tLS0KKyAgLy8vICAgfCAgICAgIE1JICAgICogfAorICAvLy8gICAtLS0tLS0tLS0tLS0tLS0tCisgIC8vLyBUaGUgZmlyc3QgaW5zdHJ1Y3Rpb24gaGFzIHRoZSBzcGVjaWFsIG9wY29kZSAiQlVORExFIi4gSXQncyBub3QgImluc2lkZSIKKyAgLy8vIGEgYnVuZGxlLCBidXQgdGhlIG5leHQgdGhyZWUgTUlzIGFyZS4KKyAgYm9vbCBpc0luc2lkZUJ1bmRsZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0RmxhZyhCdW5kbGVkUHJlZCk7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpbnN0cnVjdGlvbiBwYXJ0IG9mIGEgYnVuZGxlLiBUaGlzIGlzIHRydWUKKyAgLy8vIGlmIGVpdGhlciBpdHNlbGYgb3IgaXRzIGZvbGxvd2luZyBpbnN0cnVjdGlvbiBpcyBtYXJrZWQgIkluc2lkZUJ1bmRsZSIuCisgIGJvb2wgaXNCdW5kbGVkKCkgY29uc3QgeworICAgIHJldHVybiBpc0J1bmRsZWRXaXRoUHJlZCgpIHx8IGlzQnVuZGxlZFdpdGhTdWNjKCk7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpbnN0cnVjdGlvbiBpcyBwYXJ0IG9mIGEgYnVuZGxlLCBhbmQgaXQgaXMgbm90IHRoZQorICAvLy8gZmlyc3QgaW5zdHJ1Y3Rpb24gaW4gdGhlIGJ1bmRsZS4KKyAgYm9vbCBpc0J1bmRsZWRXaXRoUHJlZCgpIGNvbnN0IHsgcmV0dXJuIGdldEZsYWcoQnVuZGxlZFByZWQpOyB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gaXMgcGFydCBvZiBhIGJ1bmRsZSwgYW5kIGl0IGlzIG5vdCB0aGUKKyAgLy8vIGxhc3QgaW5zdHJ1Y3Rpb24gaW4gdGhlIGJ1bmRsZS4KKyAgYm9vbCBpc0J1bmRsZWRXaXRoU3VjYygpIGNvbnN0IHsgcmV0dXJuIGdldEZsYWcoQnVuZGxlZFN1Y2MpOyB9CisKKyAgLy8vIEJ1bmRsZSB0aGlzIGluc3RydWN0aW9uIHdpdGggaXRzIHByZWRlY2Vzc29yLiBUaGlzIGNhbiBiZSBhbiB1bmJ1bmRsZWQKKyAgLy8vIGluc3RydWN0aW9uLCBvciBpdCBjYW4gYmUgdGhlIGZpcnN0IGluc3RydWN0aW9uIGluIGEgYnVuZGxlLgorICB2b2lkIGJ1bmRsZVdpdGhQcmVkKCk7CisKKyAgLy8vIEJ1bmRsZSB0aGlzIGluc3RydWN0aW9uIHdpdGggaXRzIHN1Y2Nlc3Nvci4gVGhpcyBjYW4gYmUgYW4gdW5idW5kbGVkCisgIC8vLyBpbnN0cnVjdGlvbiwgb3IgaXQgY2FuIGJlIHRoZSBsYXN0IGluc3RydWN0aW9uIGluIGEgYnVuZGxlLgorICB2b2lkIGJ1bmRsZVdpdGhTdWNjKCk7CisKKyAgLy8vIEJyZWFrIGJ1bmRsZSBhYm92ZSB0aGlzIGluc3RydWN0aW9uLgorICB2b2lkIHVuYnVuZGxlRnJvbVByZWQoKTsKKworICAvLy8gQnJlYWsgYnVuZGxlIGJlbG93IHRoaXMgaW5zdHJ1Y3Rpb24uCisgIHZvaWQgdW5idW5kbGVGcm9tU3VjYygpOworCisgIC8vLyBSZXR1cm5zIHRoZSBkZWJ1ZyBsb2NhdGlvbiBpZCBvZiB0aGlzIE1hY2hpbmVJbnN0ci4KKyAgY29uc3QgRGVidWdMb2MgJmdldERlYnVnTG9jKCkgY29uc3QgeyByZXR1cm4gZGVidWdMb2M7IH0KKworICAvLy8gUmV0dXJuIHRoZSBkZWJ1ZyB2YXJpYWJsZSByZWZlcmVuY2VkIGJ5CisgIC8vLyB0aGlzIERCR19WQUxVRSBpbnN0cnVjdGlvbi4KKyAgY29uc3QgRElMb2NhbFZhcmlhYmxlICpnZXREZWJ1Z1ZhcmlhYmxlKCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0aGUgY29tcGxleCBhZGRyZXNzIGV4cHJlc3Npb24gcmVmZXJlbmNlZCBieQorICAvLy8gdGhpcyBEQkdfVkFMVUUgaW5zdHJ1Y3Rpb24uCisgIGNvbnN0IERJRXhwcmVzc2lvbiAqZ2V0RGVidWdFeHByZXNzaW9uKCkgY29uc3Q7CisKKyAgLy8vIEVtaXQgYW4gZXJyb3IgcmVmZXJyaW5nIHRvIHRoZSBzb3VyY2UgbG9jYXRpb24gb2YgdGhpcyBpbnN0cnVjdGlvbi4KKyAgLy8vIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBmb3IgaW5saW5lIGFzc2VtYmx5IHRoYXQgaXMgc29tZWhvdworICAvLy8gaW1wb3NzaWJsZSB0byBjb21waWxlLiBPdGhlciBlcnJvcnMgc2hvdWxkIGhhdmUgYmVlbiBoYW5kbGVkIG11Y2gKKyAgLy8vIGVhcmxpZXIuCisgIC8vLworICAvLy8gSWYgdGhpcyBtZXRob2QgcmV0dXJucywgdGhlIGNhbGxlciBzaG91bGQgdHJ5IHRvIHJlY292ZXIgZnJvbSB0aGUgZXJyb3IuCisgIHZvaWQgZW1pdEVycm9yKFN0cmluZ1JlZiBNc2cpIGNvbnN0OworCisgIC8vLyBSZXR1cm5zIHRoZSB0YXJnZXQgaW5zdHJ1Y3Rpb24gZGVzY3JpcHRvciBvZiB0aGlzIE1hY2hpbmVJbnN0ci4KKyAgY29uc3QgTUNJbnN0ckRlc2MgJmdldERlc2MoKSBjb25zdCB7IHJldHVybiAqTUNJRDsgfQorCisgIC8vLyBSZXR1cm5zIHRoZSBvcGNvZGUgb2YgdGhpcyBNYWNoaW5lSW5zdHIuCisgIHVuc2lnbmVkIGdldE9wY29kZSgpIGNvbnN0IHsgcmV0dXJuIE1DSUQtPk9wY29kZTsgfQorCisgIC8vLyBBY2Nlc3MgdG8gZXhwbGljaXQgb3BlcmFuZHMgb2YgdGhlIGluc3RydWN0aW9uLgorICB1bnNpZ25lZCBnZXROdW1PcGVyYW5kcygpIGNvbnN0IHsgcmV0dXJuIE51bU9wZXJhbmRzOyB9CisKKyAgY29uc3QgTWFjaGluZU9wZXJhbmQmIGdldE9wZXJhbmQodW5zaWduZWQgaSkgY29uc3QgeworICAgIGFzc2VydChpIDwgZ2V0TnVtT3BlcmFuZHMoKSAmJiAiZ2V0T3BlcmFuZCgpIG91dCBvZiByYW5nZSEiKTsKKyAgICByZXR1cm4gT3BlcmFuZHNbaV07CisgIH0KKyAgTWFjaGluZU9wZXJhbmQmIGdldE9wZXJhbmQodW5zaWduZWQgaSkgeworICAgIGFzc2VydChpIDwgZ2V0TnVtT3BlcmFuZHMoKSAmJiAiZ2V0T3BlcmFuZCgpIG91dCBvZiByYW5nZSEiKTsKKyAgICByZXR1cm4gT3BlcmFuZHNbaV07CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgb3BlcmFuZCBccCBPcElkeCBpcyBhIHN1YnJlZ2lzdGVyIGluZGV4LgorICBib29sIGlzT3BlcmFuZFN1YnJlZ0lkeCh1bnNpZ25lZCBPcElkeCkgY29uc3QgeworICAgIGFzc2VydChnZXRPcGVyYW5kKE9wSWR4KS5nZXRUeXBlKCkgPT0gTWFjaGluZU9wZXJhbmQ6Ok1PX0ltbWVkaWF0ZSAmJgorICAgICAgICAgICAiRXhwZWN0ZWQgTU9fSW1tZWRpYXRlIG9wZXJhbmQgdHlwZS4iKTsKKyAgICBpZiAoaXNFeHRyYWN0U3VicmVnKCkgJiYgT3BJZHggPT0gMikKKyAgICAgIHJldHVybiB0cnVlOworICAgIGlmIChpc0luc2VydFN1YnJlZygpICYmIE9wSWR4ID09IDMpCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICBpZiAoaXNSZWdTZXF1ZW5jZSgpICYmIE9wSWR4ID4gMSAmJiAoT3BJZHggJSAyKSA9PSAwKQorICAgICAgcmV0dXJuIHRydWU7CisgICAgaWYgKGlzU3VicmVnVG9SZWcoKSAmJiBPcElkeCA9PSAzKQorICAgICAgcmV0dXJuIHRydWU7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybnMgdGhlIG51bWJlciBvZiBub24taW1wbGljaXQgb3BlcmFuZHMuCisgIHVuc2lnbmVkIGdldE51bUV4cGxpY2l0T3BlcmFuZHMoKSBjb25zdDsKKworICAvLy8gaXRlcmF0b3IvYmVnaW4vZW5kIC0gSXRlcmF0ZSBvdmVyIGFsbCBvcGVyYW5kcyBvZiBhIG1hY2hpbmUgaW5zdHJ1Y3Rpb24uCisgIHVzaW5nIG1vcF9pdGVyYXRvciA9IE1hY2hpbmVPcGVyYW5kICo7CisgIHVzaW5nIGNvbnN0X21vcF9pdGVyYXRvciA9IGNvbnN0IE1hY2hpbmVPcGVyYW5kICo7CisKKyAgbW9wX2l0ZXJhdG9yIG9wZXJhbmRzX2JlZ2luKCkgeyByZXR1cm4gT3BlcmFuZHM7IH0KKyAgbW9wX2l0ZXJhdG9yIG9wZXJhbmRzX2VuZCgpIHsgcmV0dXJuIE9wZXJhbmRzICsgTnVtT3BlcmFuZHM7IH0KKworICBjb25zdF9tb3BfaXRlcmF0b3Igb3BlcmFuZHNfYmVnaW4oKSBjb25zdCB7IHJldHVybiBPcGVyYW5kczsgfQorICBjb25zdF9tb3BfaXRlcmF0b3Igb3BlcmFuZHNfZW5kKCkgY29uc3QgeyByZXR1cm4gT3BlcmFuZHMgKyBOdW1PcGVyYW5kczsgfQorCisgIGl0ZXJhdG9yX3JhbmdlPG1vcF9pdGVyYXRvcj4gb3BlcmFuZHMoKSB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2Uob3BlcmFuZHNfYmVnaW4oKSwgb3BlcmFuZHNfZW5kKCkpOworICB9CisgIGl0ZXJhdG9yX3JhbmdlPGNvbnN0X21vcF9pdGVyYXRvcj4gb3BlcmFuZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2Uob3BlcmFuZHNfYmVnaW4oKSwgb3BlcmFuZHNfZW5kKCkpOworICB9CisgIGl0ZXJhdG9yX3JhbmdlPG1vcF9pdGVyYXRvcj4gZXhwbGljaXRfb3BlcmFuZHMoKSB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2Uob3BlcmFuZHNfYmVnaW4oKSwKKyAgICAgICAgICAgICAgICAgICAgICBvcGVyYW5kc19iZWdpbigpICsgZ2V0TnVtRXhwbGljaXRPcGVyYW5kcygpKTsKKyAgfQorICBpdGVyYXRvcl9yYW5nZTxjb25zdF9tb3BfaXRlcmF0b3I+IGV4cGxpY2l0X29wZXJhbmRzKCkgY29uc3QgeworICAgIHJldHVybiBtYWtlX3JhbmdlKG9wZXJhbmRzX2JlZ2luKCksCisgICAgICAgICAgICAgICAgICAgICAgb3BlcmFuZHNfYmVnaW4oKSArIGdldE51bUV4cGxpY2l0T3BlcmFuZHMoKSk7CisgIH0KKyAgaXRlcmF0b3JfcmFuZ2U8bW9wX2l0ZXJhdG9yPiBpbXBsaWNpdF9vcGVyYW5kcygpIHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZShleHBsaWNpdF9vcGVyYW5kcygpLmVuZCgpLCBvcGVyYW5kc19lbmQoKSk7CisgIH0KKyAgaXRlcmF0b3JfcmFuZ2U8Y29uc3RfbW9wX2l0ZXJhdG9yPiBpbXBsaWNpdF9vcGVyYW5kcygpIGNvbnN0IHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZShleHBsaWNpdF9vcGVyYW5kcygpLmVuZCgpLCBvcGVyYW5kc19lbmQoKSk7CisgIH0KKyAgLy8vIFJldHVybnMgYSByYW5nZSBvdmVyIGFsbCBleHBsaWNpdCBvcGVyYW5kcyB0aGF0IGFyZSByZWdpc3RlciBkZWZpbml0aW9ucy4KKyAgLy8vIEltcGxpY2l0IGRlZmluaXRpb24gYXJlIG5vdCBpbmNsdWRlZCEKKyAgaXRlcmF0b3JfcmFuZ2U8bW9wX2l0ZXJhdG9yPiBkZWZzKCkgeworICAgIHJldHVybiBtYWtlX3JhbmdlKG9wZXJhbmRzX2JlZ2luKCksCisgICAgICAgICAgICAgICAgICAgICAgb3BlcmFuZHNfYmVnaW4oKSArIGdldERlc2MoKS5nZXROdW1EZWZzKCkpOworICB9CisgIC8vLyBcY29weWRvYyBkZWZzKCkKKyAgaXRlcmF0b3JfcmFuZ2U8Y29uc3RfbW9wX2l0ZXJhdG9yPiBkZWZzKCkgY29uc3QgeworICAgIHJldHVybiBtYWtlX3JhbmdlKG9wZXJhbmRzX2JlZ2luKCksCisgICAgICAgICAgICAgICAgICAgICAgb3BlcmFuZHNfYmVnaW4oKSArIGdldERlc2MoKS5nZXROdW1EZWZzKCkpOworICB9CisgIC8vLyBSZXR1cm5zIGEgcmFuZ2UgdGhhdCBpbmNsdWRlcyBhbGwgb3BlcmFuZHMgdGhhdCBhcmUgcmVnaXN0ZXIgdXNlcy4KKyAgLy8vIFRoaXMgbWF5IGluY2x1ZGUgdW5yZWxhdGVkIG9wZXJhbmRzIHdoaWNoIGFyZSBub3QgcmVnaXN0ZXIgdXNlcy4KKyAgaXRlcmF0b3JfcmFuZ2U8bW9wX2l0ZXJhdG9yPiB1c2VzKCkgeworICAgIHJldHVybiBtYWtlX3JhbmdlKG9wZXJhbmRzX2JlZ2luKCkgKyBnZXREZXNjKCkuZ2V0TnVtRGVmcygpLAorICAgICAgICAgICAgICAgICAgICAgIG9wZXJhbmRzX2VuZCgpKTsKKyAgfQorICAvLy8gXGNvcHlkb2MgdXNlcygpCisgIGl0ZXJhdG9yX3JhbmdlPGNvbnN0X21vcF9pdGVyYXRvcj4gdXNlcygpIGNvbnN0IHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZShvcGVyYW5kc19iZWdpbigpICsgZ2V0RGVzYygpLmdldE51bURlZnMoKSwKKyAgICAgICAgICAgICAgICAgICAgICBvcGVyYW5kc19lbmQoKSk7CisgIH0KKyAgaXRlcmF0b3JfcmFuZ2U8bW9wX2l0ZXJhdG9yPiBleHBsaWNpdF91c2VzKCkgeworICAgIHJldHVybiBtYWtlX3JhbmdlKG9wZXJhbmRzX2JlZ2luKCkgKyBnZXREZXNjKCkuZ2V0TnVtRGVmcygpLAorICAgICAgICAgICAgICAgICAgICAgIG9wZXJhbmRzX2JlZ2luKCkgKyBnZXROdW1FeHBsaWNpdE9wZXJhbmRzKCkgKTsKKyAgfQorICBpdGVyYXRvcl9yYW5nZTxjb25zdF9tb3BfaXRlcmF0b3I+IGV4cGxpY2l0X3VzZXMoKSBjb25zdCB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2Uob3BlcmFuZHNfYmVnaW4oKSArIGdldERlc2MoKS5nZXROdW1EZWZzKCksCisgICAgICAgICAgICAgICAgICAgICAgb3BlcmFuZHNfYmVnaW4oKSArIGdldE51bUV4cGxpY2l0T3BlcmFuZHMoKSApOworICB9CisKKyAgLy8vIFJldHVybnMgdGhlIG51bWJlciBvZiB0aGUgb3BlcmFuZCBpdGVyYXRvciBccCBJIHBvaW50cyB0by4KKyAgdW5zaWduZWQgZ2V0T3BlcmFuZE5vKGNvbnN0X21vcF9pdGVyYXRvciBJKSBjb25zdCB7CisgICAgcmV0dXJuIEkgLSBvcGVyYW5kc19iZWdpbigpOworICB9CisKKyAgLy8vIEFjY2VzcyB0byBtZW1vcnkgb3BlcmFuZHMgb2YgdGhlIGluc3RydWN0aW9uCisgIG1tb19pdGVyYXRvciBtZW1vcGVyYW5kc19iZWdpbigpIGNvbnN0IHsgcmV0dXJuIE1lbVJlZnM7IH0KKyAgbW1vX2l0ZXJhdG9yIG1lbW9wZXJhbmRzX2VuZCgpIGNvbnN0IHsgcmV0dXJuIE1lbVJlZnMgKyBOdW1NZW1SZWZzOyB9CisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB3ZSBkb24ndCBoYXZlIGFueSBtZW1vcnkgb3BlcmFuZHMgd2hpY2ggZGVzY3JpYmVkIHRoZQorICAvLy8gbWVtb3J5IGFjY2VzcyBkb25lIGJ5IHRoaXMgaW5zdHJ1Y3Rpb24uICBJZiB0aGlzIGlzIHRydWUsIGNhbGxpbmcgY29kZQorICAvLy8gbXVzdCBiZSBjb25zZXJ2YXRpdmUuCisgIGJvb2wgbWVtb3BlcmFuZHNfZW1wdHkoKSBjb25zdCB7IHJldHVybiBOdW1NZW1SZWZzID09IDA7IH0KKworICBpdGVyYXRvcl9yYW5nZTxtbW9faXRlcmF0b3I+ICBtZW1vcGVyYW5kcygpIHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZShtZW1vcGVyYW5kc19iZWdpbigpLCBtZW1vcGVyYW5kc19lbmQoKSk7CisgIH0KKyAgaXRlcmF0b3JfcmFuZ2U8bW1vX2l0ZXJhdG9yPiBtZW1vcGVyYW5kcygpIGNvbnN0IHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZShtZW1vcGVyYW5kc19iZWdpbigpLCBtZW1vcGVyYW5kc19lbmQoKSk7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpbnN0cnVjdGlvbiBoYXMgZXhhY3RseSBvbmUgTWFjaGluZU1lbU9wZXJhbmQuCisgIGJvb2wgaGFzT25lTWVtT3BlcmFuZCgpIGNvbnN0IHsKKyAgICByZXR1cm4gTnVtTWVtUmVmcyA9PSAxOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgbnVtYmVyIG9mIG1lbW9yeSBvcGVyYW5kcy4KKyAgdW5zaWduZWQgZ2V0TnVtTWVtT3BlcmFuZHMoKSBjb25zdCB7IHJldHVybiBOdW1NZW1SZWZzOyB9CisKKyAgLy8vIEFQSSBmb3IgcXVlcnlpbmcgTWFjaGluZUluc3RyIHByb3BlcnRpZXMuIFRoZXkgYXJlIHRoZSBzYW1lIGFzIE1DSW5zdHJEZXNjCisgIC8vLyBxdWVyaWVzIGJ1dCB0aGV5IGFyZSBidW5kbGUgYXdhcmUuCisKKyAgZW51bSBRdWVyeVR5cGUgeworICAgIElnbm9yZUJ1bmRsZSwgICAgLy8gSWdub3JlIGJ1bmRsZXMKKyAgICBBbnlJbkJ1bmRsZSwgICAgIC8vIFJldHVybiB0cnVlIGlmIGFueSBpbnN0cnVjdGlvbiBpbiBidW5kbGUgaGFzIHByb3BlcnR5CisgICAgQWxsSW5CdW5kbGUgICAgICAvLyBSZXR1cm4gdHJ1ZSBpZiBhbGwgaW5zdHJ1Y3Rpb25zIGluIGJ1bmRsZSBoYXZlIHByb3BlcnR5CisgIH07CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBpbnN0cnVjdGlvbiAob3IgaW4gdGhlIGNhc2Ugb2YgYSBidW5kbGUsCisgIC8vLyB0aGUgaW5zdHJ1Y3Rpb25zIGluc2lkZSB0aGUgYnVuZGxlKSBoYXMgdGhlIHNwZWNpZmllZCBwcm9wZXJ0eS4KKyAgLy8vIFRoZSBmaXJzdCBhcmd1bWVudCBpcyB0aGUgcHJvcGVydHkgYmVpbmcgcXVlcmllZC4KKyAgLy8vIFRoZSBzZWNvbmQgYXJndW1lbnQgaW5kaWNhdGVzIHdoZXRoZXIgdGhlIHF1ZXJ5IHNob3VsZCBsb29rIGluc2lkZQorICAvLy8gaW5zdHJ1Y3Rpb24gYnVuZGxlcy4KKyAgYm9vbCBoYXNQcm9wZXJ0eSh1bnNpZ25lZCBNQ0ZsYWcsIFF1ZXJ5VHlwZSBUeXBlID0gQW55SW5CdW5kbGUpIGNvbnN0IHsKKyAgICAvLyBJbmxpbmUgdGhlIGZhc3QgcGF0aCBmb3IgdW5idW5kbGVkIG9yIGJ1bmRsZS1pbnRlcm5hbCBpbnN0cnVjdGlvbnMuCisgICAgaWYgKFR5cGUgPT0gSWdub3JlQnVuZGxlIHx8ICFpc0J1bmRsZWQoKSB8fCBpc0J1bmRsZWRXaXRoUHJlZCgpKQorICAgICAgcmV0dXJuIGdldERlc2MoKS5nZXRGbGFncygpICYgKDFVTEwgPDwgTUNGbGFnKTsKKworICAgIC8vIElmIHRoaXMgaXMgdGhlIGZpcnN0IGluc3RydWN0aW9uIGluIGEgYnVuZGxlLCB0YWtlIHRoZSBzbG93IHBhdGguCisgICAgcmV0dXJuIGhhc1Byb3BlcnR5SW5CdW5kbGUoMVVMTCA8PCBNQ0ZsYWcsIFR5cGUpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gY2FuIGhhdmUgYSB2YXJpYWJsZSBudW1iZXIgb2Ygb3BlcmFuZHMuCisgIC8vLyBJbiB0aGlzIGNhc2UsIHRoZSB2YXJpYWJsZSBvcGVyYW5kcyB3aWxsIGJlIGFmdGVyIHRoZSBub3JtYWwKKyAgLy8vIG9wZXJhbmRzIGJ1dCBiZWZvcmUgdGhlIGltcGxpY2l0IGRlZmluaXRpb25zIGFuZCB1c2VzIChpZiBhbnkgYXJlCisgIC8vLyBwcmVzZW50KS4KKyAgYm9vbCBpc1ZhcmlhZGljKFF1ZXJ5VHlwZSBUeXBlID0gSWdub3JlQnVuZGxlKSBjb25zdCB7CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6OlZhcmlhZGljLCBUeXBlKTsKKyAgfQorCisgIC8vLyBTZXQgaWYgdGhpcyBpbnN0cnVjdGlvbiBoYXMgYW4gb3B0aW9uYWwgZGVmaW5pdGlvbiwgZS5nLgorICAvLy8gQVJNIGluc3RydWN0aW9ucyB3aGljaCBjYW4gc2V0IGNvbmRpdGlvbiBjb2RlIGlmICdzJyBiaXQgaXMgc2V0LgorICBib29sIGhhc09wdGlvbmFsRGVmKFF1ZXJ5VHlwZSBUeXBlID0gSWdub3JlQnVuZGxlKSBjb25zdCB7CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6Okhhc09wdGlvbmFsRGVmLCBUeXBlKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGEgcHNldWRvIGluc3RydWN0aW9uIHRoYXQgZG9lc24ndAorICAvLy8gY29ycmVzcG9uZCB0byBhIHJlYWwgbWFjaGluZSBpbnN0cnVjdGlvbi4KKyAgYm9vbCBpc1BzZXVkbyhRdWVyeVR5cGUgVHlwZSA9IElnbm9yZUJ1bmRsZSkgY29uc3QgeworICAgIHJldHVybiBoYXNQcm9wZXJ0eShNQ0lEOjpQc2V1ZG8sIFR5cGUpOworICB9CisKKyAgYm9vbCBpc1JldHVybihRdWVyeVR5cGUgVHlwZSA9IEFueUluQnVuZGxlKSBjb25zdCB7CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6OlJldHVybiwgVHlwZSk7CisgIH0KKworICBib29sIGlzQ2FsbChRdWVyeVR5cGUgVHlwZSA9IEFueUluQnVuZGxlKSBjb25zdCB7CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6OkNhbGwsIFR5cGUpOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGluc3RydWN0aW9uIHN0b3BzIGNvbnRyb2wgZmxvdworICAvLy8gZnJvbSBleGVjdXRpbmcgdGhlIGluc3RydWN0aW9uIGltbWVkaWF0ZWx5IGZvbGxvd2luZyBpdC4gIEV4YW1wbGVzIGluY2x1ZGUKKyAgLy8vIHVuY29uZGl0aW9uYWwgYnJhbmNoZXMgYW5kIHJldHVybiBpbnN0cnVjdGlvbnMuCisgIGJvb2wgaXNCYXJyaWVyKFF1ZXJ5VHlwZSBUeXBlID0gQW55SW5CdW5kbGUpIGNvbnN0IHsKKyAgICByZXR1cm4gaGFzUHJvcGVydHkoTUNJRDo6QmFycmllciwgVHlwZSk7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gcGFydCBvZiB0aGUgdGVybWluYXRvciBmb3IgYSBiYXNpYyBibG9jay4KKyAgLy8vIFR5cGljYWxseSB0aGlzIGlzIHRoaW5ncyBsaWtlIHJldHVybiBhbmQgYnJhbmNoIGluc3RydWN0aW9ucy4KKyAgLy8vCisgIC8vLyBWYXJpb3VzIHBhc3NlcyB1c2UgdGhpcyB0byBpbnNlcnQgY29kZSBpbnRvIHRoZSBib3R0b20gb2YgYSBiYXNpYyBibG9jaywKKyAgLy8vIGJ1dCBiZWZvcmUgY29udHJvbCBmbG93IG9jY3Vycy4KKyAgYm9vbCBpc1Rlcm1pbmF0b3IoUXVlcnlUeXBlIFR5cGUgPSBBbnlJbkJ1bmRsZSkgY29uc3QgeworICAgIHJldHVybiBoYXNQcm9wZXJ0eShNQ0lEOjpUZXJtaW5hdG9yLCBUeXBlKTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIGNvbmRpdGlvbmFsLCB1bmNvbmRpdGlvbmFsLCBvciBpbmRpcmVjdCBicmFuY2guCisgIC8vLyBQcmVkaWNhdGVzIGJlbG93IGNhbiBiZSB1c2VkIHRvIGRpc2NyaW1pbmF0ZSBiZXR3ZWVuCisgIC8vLyB0aGVzZSBjYXNlcywgYW5kIHRoZSBUYXJnZXRJbnN0ckluZm86OkFuYWx5emVCcmFuY2ggbWV0aG9kIGNhbiBiZSB1c2VkIHRvCisgIC8vLyBnZXQgbW9yZSBpbmZvcm1hdGlvbi4KKyAgYm9vbCBpc0JyYW5jaChRdWVyeVR5cGUgVHlwZSA9IEFueUluQnVuZGxlKSBjb25zdCB7CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6OkJyYW5jaCwgVHlwZSk7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhbiBpbmRpcmVjdCBicmFuY2gsIHN1Y2ggYXMgYQorICAvLy8gYnJhbmNoIHRocm91Z2ggYSByZWdpc3Rlci4KKyAgYm9vbCBpc0luZGlyZWN0QnJhbmNoKFF1ZXJ5VHlwZSBUeXBlID0gQW55SW5CdW5kbGUpIGNvbnN0IHsKKyAgICByZXR1cm4gaGFzUHJvcGVydHkoTUNJRDo6SW5kaXJlY3RCcmFuY2gsIFR5cGUpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaXMgYSBicmFuY2ggd2hpY2ggbWF5IGZhbGwKKyAgLy8vIHRocm91Z2ggdG8gdGhlIG5leHQgaW5zdHJ1Y3Rpb24gb3IgbWF5IHRyYW5zZmVyIGNvbnRyb2wgZmxvdyB0byBzb21lIG90aGVyCisgIC8vLyBibG9jay4gIFRoZSBUYXJnZXRJbnN0ckluZm86OkFuYWx5emVCcmFuY2ggbWV0aG9kIGNhbiBiZSB1c2VkIHRvIGdldCBtb3JlCisgIC8vLyBpbmZvcm1hdGlvbiBhYm91dCB0aGlzIGJyYW5jaC4KKyAgYm9vbCBpc0NvbmRpdGlvbmFsQnJhbmNoKFF1ZXJ5VHlwZSBUeXBlID0gQW55SW5CdW5kbGUpIGNvbnN0IHsKKyAgICByZXR1cm4gaXNCcmFuY2goVHlwZSkgJiAhaXNCYXJyaWVyKFR5cGUpICYgIWlzSW5kaXJlY3RCcmFuY2goVHlwZSk7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIGJyYW5jaCB3aGljaCBhbHdheXMKKyAgLy8vIHRyYW5zZmVycyBjb250cm9sIGZsb3cgdG8gc29tZSBvdGhlciBibG9jay4gIFRoZQorICAvLy8gVGFyZ2V0SW5zdHJJbmZvOjpBbmFseXplQnJhbmNoIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBnZXQgbW9yZSBpbmZvcm1hdGlvbgorICAvLy8gYWJvdXQgdGhpcyBicmFuY2guCisgIGJvb2wgaXNVbmNvbmRpdGlvbmFsQnJhbmNoKFF1ZXJ5VHlwZSBUeXBlID0gQW55SW5CdW5kbGUpIGNvbnN0IHsKKyAgICByZXR1cm4gaXNCcmFuY2goVHlwZSkgJiBpc0JhcnJpZXIoVHlwZSkgJiAhaXNJbmRpcmVjdEJyYW5jaChUeXBlKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGluc3RydWN0aW9uIGhhcyBhIHByZWRpY2F0ZSBvcGVyYW5kIHRoYXQKKyAgLy8vIGNvbnRyb2xzIGV4ZWN1dGlvbi4gIEl0IG1heSBiZSBzZXQgdG8gJ2Fsd2F5cycsIG9yIG1heSBiZSBzZXQgdG8gb3RoZXIKKyAgLy8vIHZhbHVlcy4gICBUaGVyZSBhcmUgdmFyaW91cyBtZXRob2RzIGluIFRhcmdldEluc3RySW5mbyB0aGF0IGNhbiBiZSB1c2VkIHRvCisgIC8vLyBjb250cm9sIGFuZCBtb2RpZnkgdGhlIHByZWRpY2F0ZSBpbiB0aGlzIGluc3RydWN0aW9uLgorICBib29sIGlzUHJlZGljYWJsZShRdWVyeVR5cGUgVHlwZSA9IEFsbEluQnVuZGxlKSBjb25zdCB7CisgICAgLy8gSWYgaXQncyBhIGJ1bmRsZSB0aGFuIGFsbCBidW5kbGVkIGluc3RydWN0aW9ucyBtdXN0IGJlIHByZWRpY2FibGUgZm9yIHRoaXMKKyAgICAvLyB0byByZXR1cm4gdHJ1ZS4KKyAgICByZXR1cm4gaGFzUHJvcGVydHkoTUNJRDo6UHJlZGljYWJsZSwgVHlwZSk7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpbnN0cnVjdGlvbiBpcyBhIGNvbXBhcmlzb24uCisgIGJvb2wgaXNDb21wYXJlKFF1ZXJ5VHlwZSBUeXBlID0gSWdub3JlQnVuZGxlKSBjb25zdCB7CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6OkNvbXBhcmUsIFR5cGUpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gaXMgYSBtb3ZlIGltbWVkaWF0ZQorICAvLy8gKGluY2x1ZGluZyBjb25kaXRpb25hbCBtb3ZlcykgaW5zdHJ1Y3Rpb24uCisgIGJvb2wgaXNNb3ZlSW1tZWRpYXRlKFF1ZXJ5VHlwZSBUeXBlID0gSWdub3JlQnVuZGxlKSBjb25zdCB7CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6Ok1vdmVJbW0sIFR5cGUpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gaXMgYSBiaXRjYXN0IGluc3RydWN0aW9uLgorICBib29sIGlzQml0Y2FzdChRdWVyeVR5cGUgVHlwZSA9IElnbm9yZUJ1bmRsZSkgY29uc3QgeworICAgIHJldHVybiBoYXNQcm9wZXJ0eShNQ0lEOjpCaXRjYXN0LCBUeXBlKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGluc3RydWN0aW9uIGlzIGEgc2VsZWN0IGluc3RydWN0aW9uLgorICBib29sIGlzU2VsZWN0KFF1ZXJ5VHlwZSBUeXBlID0gSWdub3JlQnVuZGxlKSBjb25zdCB7CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6OlNlbGVjdCwgVHlwZSk7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpbnN0cnVjdGlvbiBjYW5ub3QgYmUgc2FmZWx5IGR1cGxpY2F0ZWQuCisgIC8vLyBGb3IgZXhhbXBsZSwgaWYgdGhlIGluc3RydWN0aW9uIGhhcyBhIHVuaXF1ZSBsYWJlbHMgYXR0YWNoZWQKKyAgLy8vIHRvIGl0LCBkdXBsaWNhdGluZyBpdCB3b3VsZCBjYXVzZSBtdWx0aXBsZSBkZWZpbml0aW9uIGVycm9ycy4KKyAgYm9vbCBpc05vdER1cGxpY2FibGUoUXVlcnlUeXBlIFR5cGUgPSBBbnlJbkJ1bmRsZSkgY29uc3QgeworICAgIHJldHVybiBoYXNQcm9wZXJ0eShNQ0lEOjpOb3REdXBsaWNhYmxlLCBUeXBlKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGluc3RydWN0aW9uIGlzIGNvbnZlcmdlbnQuCisgIC8vLyBDb252ZXJnZW50IGluc3RydWN0aW9ucyBjYW4gbm90IGJlIG1hZGUgY29udHJvbC1kZXBlbmRlbnQgb24gYW55CisgIC8vLyBhZGRpdGlvbmFsIHZhbHVlcy4KKyAgYm9vbCBpc0NvbnZlcmdlbnQoUXVlcnlUeXBlIFR5cGUgPSBBbnlJbkJ1bmRsZSkgY29uc3QgeworICAgIGlmIChpc0lubGluZUFzbSgpKSB7CisgICAgICB1bnNpZ25lZCBFeHRyYUluZm8gPSBnZXRPcGVyYW5kKElubGluZUFzbTo6TUlPcF9FeHRyYUluZm8pLmdldEltbSgpOworICAgICAgaWYgKEV4dHJhSW5mbyAmIElubGluZUFzbTo6RXh0cmFfSXNDb252ZXJnZW50KQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6OkNvbnZlcmdlbnQsIFR5cGUpOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGluc3RydWN0aW9uIGhhcyBhIGRlbGF5IHNsb3QKKyAgLy8vIHdoaWNoIG11c3QgYmUgZmlsbGVkIGJ5IHRoZSBjb2RlIGdlbmVyYXRvci4KKyAgYm9vbCBoYXNEZWxheVNsb3QoUXVlcnlUeXBlIFR5cGUgPSBBbnlJbkJ1bmRsZSkgY29uc3QgeworICAgIHJldHVybiBoYXNQcm9wZXJ0eShNQ0lEOjpEZWxheVNsb3QsIFR5cGUpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGZvciBpbnN0cnVjdGlvbnMgdGhhdCBjYW4gYmUgZm9sZGVkIGFzCisgIC8vLyBtZW1vcnkgb3BlcmFuZHMgaW4gb3RoZXIgaW5zdHJ1Y3Rpb25zLiBUaGUgbW9zdCBjb21tb24gdXNlIGZvciB0aGlzCisgIC8vLyBpcyBpbnN0cnVjdGlvbnMgdGhhdCBhcmUgc2ltcGxlIGxvYWRzIGZyb20gbWVtb3J5IHRoYXQgZG9uJ3QgbW9kaWZ5CisgIC8vLyB0aGUgbG9hZGVkIHZhbHVlIGluIGFueSB3YXksIGJ1dCBpdCBjYW4gYWxzbyBiZSB1c2VkIGZvciBpbnN0cnVjdGlvbnMKKyAgLy8vIHRoYXQgY2FuIGJlIGV4cHJlc3NlZCBhcyBjb25zdGFudC1wb29sIGxvYWRzLCBzdWNoIGFzIFZfU0VUQUxMT05FUworICAvLy8gb24geDg2LCB0byBhbGxvdyB0aGVtIHRvIGJlIGZvbGRlZCB3aGVuIGl0IGlzIGJlbmVmaWNpYWwuCisgIC8vLyBUaGlzIHNob3VsZCBvbmx5IGJlIHNldCBvbiBpbnN0cnVjdGlvbnMgdGhhdCByZXR1cm4gYSB2YWx1ZSBpbiB0aGVpcgorICAvLy8gb25seSB2aXJ0dWFsIHJlZ2lzdGVyIGRlZmluaXRpb24uCisgIGJvb2wgY2FuRm9sZEFzTG9hZChRdWVyeVR5cGUgVHlwZSA9IElnbm9yZUJ1bmRsZSkgY29uc3QgeworICAgIHJldHVybiBoYXNQcm9wZXJ0eShNQ0lEOjpGb2xkYWJsZUFzTG9hZCwgVHlwZSk7CisgIH0KKworICAvLy8gXGJyaWVmIFJldHVybiB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gYmVoYXZlcworICAvLy8gdGhlIHNhbWUgd2F5IGFzIHRoZSBnZW5lcmljIFJFR19TRVFVRU5DRSBpbnN0cnVjdGlvbnMuCisgIC8vLyBFLmcuLCBvbiBBUk0sCisgIC8vLyBkWCBWTU9WRFJSIHJZLCByWgorICAvLy8gaXMgZXF1aXZhbGVudCB0bworICAvLy8gZFggPSBSRUdfU0VRVUVOQ0UgclksIHNzdWJfMCwgclosIHNzdWJfMS4KKyAgLy8vCisgIC8vLyBOb3RlIHRoYXQgZm9yIHRoZSBvcHRpbWl6ZXJzIHRvIGJlIGFibGUgdG8gdGFrZSBhZHZhbnRhZ2Ugb2YKKyAgLy8vIHRoaXMgcHJvcGVydHksIFRhcmdldEluc3RySW5mbzo6Z2V0UmVnU2VxdWVuY2VMaWtlSW5wdXRzIGhhcyB0byBiZQorICAvLy8gb3ZlcnJpZGUgYWNjb3JkaW5nbHkuCisgIGJvb2wgaXNSZWdTZXF1ZW5jZUxpa2UoUXVlcnlUeXBlIFR5cGUgPSBJZ25vcmVCdW5kbGUpIGNvbnN0IHsKKyAgICByZXR1cm4gaGFzUHJvcGVydHkoTUNJRDo6UmVnU2VxdWVuY2UsIFR5cGUpOworICB9CisKKyAgLy8vIFxicmllZiBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGluc3RydWN0aW9uIGJlaGF2ZXMKKyAgLy8vIHRoZSBzYW1lIHdheSBhcyB0aGUgZ2VuZXJpYyBFWFRSQUNUX1NVQlJFRyBpbnN0cnVjdGlvbnMuCisgIC8vLyBFLmcuLCBvbiBBUk0sCisgIC8vLyByWCwgclkgVk1PVlJSRCBkWgorICAvLy8gaXMgZXF1aXZhbGVudCB0byB0d28gRVhUUkFDVF9TVUJSRUc6CisgIC8vLyByWCA9IEVYVFJBQ1RfU1VCUkVHIGRaLCBzc3ViXzAKKyAgLy8vIHJZID0gRVhUUkFDVF9TVUJSRUcgZFosIHNzdWJfMQorICAvLy8KKyAgLy8vIE5vdGUgdGhhdCBmb3IgdGhlIG9wdGltaXplcnMgdG8gYmUgYWJsZSB0byB0YWtlIGFkdmFudGFnZSBvZgorICAvLy8gdGhpcyBwcm9wZXJ0eSwgVGFyZ2V0SW5zdHJJbmZvOjpnZXRFeHRyYWN0U3VicmVnTGlrZUlucHV0cyBoYXMgdG8gYmUKKyAgLy8vIG92ZXJyaWRlIGFjY29yZGluZ2x5LgorICBib29sIGlzRXh0cmFjdFN1YnJlZ0xpa2UoUXVlcnlUeXBlIFR5cGUgPSBJZ25vcmVCdW5kbGUpIGNvbnN0IHsKKyAgICByZXR1cm4gaGFzUHJvcGVydHkoTUNJRDo6RXh0cmFjdFN1YnJlZywgVHlwZSk7CisgIH0KKworICAvLy8gXGJyaWVmIFJldHVybiB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gYmVoYXZlcworICAvLy8gdGhlIHNhbWUgd2F5IGFzIHRoZSBnZW5lcmljIElOU0VSVF9TVUJSRUcgaW5zdHJ1Y3Rpb25zLgorICAvLy8gRS5nLiwgb24gQVJNLAorICAvLy8gZFggPSBWU0VUTE5pMzIgZFksIHJaLCBJbW0KKyAgLy8vIGlzIGVxdWl2YWxlbnQgdG8gYSBJTlNFUlRfU1VCUkVHOgorICAvLy8gZFggPSBJTlNFUlRfU1VCUkVHIGRZLCByWiwgdHJhbnNsYXRlSW1tVG9TdWJJZHgoSW1tKQorICAvLy8KKyAgLy8vIE5vdGUgdGhhdCBmb3IgdGhlIG9wdGltaXplcnMgdG8gYmUgYWJsZSB0byB0YWtlIGFkdmFudGFnZSBvZgorICAvLy8gdGhpcyBwcm9wZXJ0eSwgVGFyZ2V0SW5zdHJJbmZvOjpnZXRJbnNlcnRTdWJyZWdMaWtlSW5wdXRzIGhhcyB0byBiZQorICAvLy8gb3ZlcnJpZGUgYWNjb3JkaW5nbHkuCisgIGJvb2wgaXNJbnNlcnRTdWJyZWdMaWtlKFF1ZXJ5VHlwZSBUeXBlID0gSWdub3JlQnVuZGxlKSBjb25zdCB7CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6Okluc2VydFN1YnJlZywgVHlwZSk7CisgIH0KKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gU2lkZSBFZmZlY3QgQW5hbHlzaXMKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gY291bGQgcG9zc2libHkgcmVhZCBtZW1vcnkuCisgIC8vLyBJbnN0cnVjdGlvbnMgd2l0aCB0aGlzIGZsYWcgc2V0IGFyZSBub3QgbmVjZXNzYXJpbHkgc2ltcGxlIGxvYWQKKyAgLy8vIGluc3RydWN0aW9ucywgdGhleSBtYXkgbG9hZCBhIHZhbHVlIGFuZCBtb2RpZnkgaXQsIGZvciBleGFtcGxlLgorICBib29sIG1heUxvYWQoUXVlcnlUeXBlIFR5cGUgPSBBbnlJbkJ1bmRsZSkgY29uc3QgeworICAgIGlmIChpc0lubGluZUFzbSgpKSB7CisgICAgICB1bnNpZ25lZCBFeHRyYUluZm8gPSBnZXRPcGVyYW5kKElubGluZUFzbTo6TUlPcF9FeHRyYUluZm8pLmdldEltbSgpOworICAgICAgaWYgKEV4dHJhSW5mbyAmIElubGluZUFzbTo6RXh0cmFfTWF5TG9hZCkKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICAgIHJldHVybiBoYXNQcm9wZXJ0eShNQ0lEOjpNYXlMb2FkLCBUeXBlKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGluc3RydWN0aW9uIGNvdWxkIHBvc3NpYmx5IG1vZGlmeSBtZW1vcnkuCisgIC8vLyBJbnN0cnVjdGlvbnMgd2l0aCB0aGlzIGZsYWcgc2V0IGFyZSBub3QgbmVjZXNzYXJpbHkgc2ltcGxlIHN0b3JlCisgIC8vLyBpbnN0cnVjdGlvbnMsIHRoZXkgbWF5IHN0b3JlIGEgbW9kaWZpZWQgdmFsdWUgYmFzZWQgb24gdGhlaXIgb3BlcmFuZHMsIG9yCisgIC8vLyBtYXkgbm90IGFjdHVhbGx5IG1vZGlmeSBhbnl0aGluZywgZm9yIGV4YW1wbGUuCisgIGJvb2wgbWF5U3RvcmUoUXVlcnlUeXBlIFR5cGUgPSBBbnlJbkJ1bmRsZSkgY29uc3QgeworICAgIGlmIChpc0lubGluZUFzbSgpKSB7CisgICAgICB1bnNpZ25lZCBFeHRyYUluZm8gPSBnZXRPcGVyYW5kKElubGluZUFzbTo6TUlPcF9FeHRyYUluZm8pLmdldEltbSgpOworICAgICAgaWYgKEV4dHJhSW5mbyAmIElubGluZUFzbTo6RXh0cmFfTWF5U3RvcmUpCisgICAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICByZXR1cm4gaGFzUHJvcGVydHkoTUNJRDo6TWF5U3RvcmUsIFR5cGUpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gY291bGQgcG9zc2libHkgcmVhZCBvciBtb2RpZnkgbWVtb3J5LgorICBib29sIG1heUxvYWRPclN0b3JlKFF1ZXJ5VHlwZSBUeXBlID0gQW55SW5CdW5kbGUpIGNvbnN0IHsKKyAgICByZXR1cm4gbWF5TG9hZChUeXBlKSB8fCBtYXlTdG9yZShUeXBlKTsKKyAgfQorCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLyBGbGFncyB0aGF0IGluZGljYXRlIHdoZXRoZXIgYW4gaW5zdHJ1Y3Rpb24gY2FuIGJlIG1vZGlmaWVkIGJ5IGEgbWV0aG9kLgorICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBtYXkgYmUgYSAyLSBvciAzLWFkZHJlc3MKKyAgLy8vIGluc3RydWN0aW9uIChvZiB0aGUgZm9ybSAiWCA9IG9wIFksIFosIC4uLiIpLCB3aGljaCBwcm9kdWNlcyB0aGUgc2FtZQorICAvLy8gcmVzdWx0IGlmIFkgYW5kIFogYXJlIGV4Y2hhbmdlZC4gIElmIHRoaXMgZmxhZyBpcyBzZXQsIHRoZW4gdGhlCisgIC8vLyBUYXJnZXRJbnN0ckluZm86OmNvbW11dGVJbnN0cnVjdGlvbiBtZXRob2QgbWF5IGJlIHVzZWQgdG8gaGFjayBvbiB0aGUKKyAgLy8vIGluc3RydWN0aW9uLgorICAvLy8KKyAgLy8vIE5vdGUgdGhhdCB0aGlzIGZsYWcgbWF5IGJlIHNldCBvbiBpbnN0cnVjdGlvbnMgdGhhdCBhcmUgb25seSBjb21tdXRhYmxlCisgIC8vLyBzb21ldGltZXMuICBJbiB0aGVzZSBjYXNlcywgdGhlIGNhbGwgdG8gY29tbXV0ZUluc3RydWN0aW9uIHdpbGwgZmFpbC4KKyAgLy8vIEFsc28gbm90ZSB0aGF0IHNvbWUgaW5zdHJ1Y3Rpb25zIHJlcXVpcmUgbm9uLXRyaXZpYWwgbW9kaWZpY2F0aW9uIHRvCisgIC8vLyBjb21tdXRlIHRoZW0uCisgIGJvb2wgaXNDb21tdXRhYmxlKFF1ZXJ5VHlwZSBUeXBlID0gSWdub3JlQnVuZGxlKSBjb25zdCB7CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6OkNvbW11dGFibGUsIFR5cGUpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaXMgYSAyLWFkZHJlc3MgaW5zdHJ1Y3Rpb24KKyAgLy8vIHdoaWNoIGNhbiBiZSBjaGFuZ2VkIGludG8gYSAzLWFkZHJlc3MgaW5zdHJ1Y3Rpb24gaWYgbmVlZGVkLiAgRG9pbmcgdGhpcworICAvLy8gdHJhbnNmb3JtYXRpb24gY2FuIGJlIHByb2ZpdGFibGUgaW4gdGhlIHJlZ2lzdGVyIGFsbG9jYXRvciwgYmVjYXVzZSBpdAorICAvLy8gbWVhbnMgdGhhdCB0aGUgaW5zdHJ1Y3Rpb24gY2FuIHVzZSBhIDItYWRkcmVzcyBmb3JtIGlmIHBvc3NpYmxlLCBidXQKKyAgLy8vIGRlZ3JhZGUgaW50byBhIGxlc3MgZWZmaWNpZW50IGZvcm0gaWYgdGhlIHNvdXJjZSBhbmQgZGVzdCByZWdpc3RlciBjYW5ub3QKKyAgLy8vIGJlIGFzc2lnbmVkIHRvIHRoZSBzYW1lIHJlZ2lzdGVyLiAgRm9yIGV4YW1wbGUsIHRoaXMgYWxsb3dzIHRoZSB4ODYKKyAgLy8vIGJhY2tlbmQgdG8gdHVybiBhICJzaGwgcmVnLCAzIiBpbnN0cnVjdGlvbiBpbnRvIGFuIExFQSBpbnN0cnVjdGlvbiwgd2hpY2gKKyAgLy8vIGlzIHRoZSBzYW1lIHNwZWVkIGFzIHRoZSBzaGlmdCBidXQgaGFzIGJpZ2dlciBjb2RlIHNpemUuCisgIC8vLworICAvLy8gSWYgdGhpcyByZXR1cm5zIHRydWUsIHRoZW4gdGhlIHRhcmdldCBtdXN0IGltcGxlbWVudCB0aGUKKyAgLy8vIFRhcmdldEluc3RySW5mbzo6Y29udmVydFRvVGhyZWVBZGRyZXNzIG1ldGhvZCBmb3IgdGhpcyBpbnN0cnVjdGlvbiwgd2hpY2gKKyAgLy8vIGlzIGFsbG93ZWQgdG8gZmFpbCBpZiB0aGUgdHJhbnNmb3JtYXRpb24gaXNuJ3QgdmFsaWQgZm9yIHRoaXMgc3BlY2lmaWMKKyAgLy8vIGluc3RydWN0aW9uIChlLmcuIHNobCByZWcsIDQgb24geDg2KS4KKyAgLy8vCisgIGJvb2wgaXNDb252ZXJ0aWJsZVRvM0FkZHIoUXVlcnlUeXBlIFR5cGUgPSBJZ25vcmVCdW5kbGUpIGNvbnN0IHsKKyAgICByZXR1cm4gaGFzUHJvcGVydHkoTUNJRDo6Q29udmVydGlibGVUbzNBZGRyLCBUeXBlKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGluc3RydWN0aW9uIHJlcXVpcmVzCisgIC8vLyBjdXN0b20gaW5zZXJ0aW9uIHN1cHBvcnQgd2hlbiB0aGUgREFHIHNjaGVkdWxlciBpcyBpbnNlcnRpbmcgaXQgaW50byBhCisgIC8vLyBtYWNoaW5lIGJhc2ljIGJsb2NrLiAgSWYgdGhpcyBpcyB0cnVlIGZvciB0aGUgaW5zdHJ1Y3Rpb24sIGl0IGJhc2ljYWxseQorICAvLy8gbWVhbnMgdGhhdCBpdCBpcyBhIHBzZXVkbyBpbnN0cnVjdGlvbiB1c2VkIGF0IFNlbGVjdGlvbkRBRyB0aW1lIHRoYXQgaXMKKyAgLy8vIGV4cGFuZGVkIG91dCBpbnRvIG1hZ2ljIGNvZGUgYnkgdGhlIHRhcmdldCB3aGVuIE1hY2hpbmVJbnN0cnMgYXJlIGZvcm1lZC4KKyAgLy8vCisgIC8vLyBJZiB0aGlzIGlzIHRydWUsIHRoZSBUYXJnZXRMb3dlcmluZ0luZm86Okluc2VydEF0RW5kT2ZCYXNpY0Jsb2NrIG1ldGhvZAorICAvLy8gaXMgdXNlZCB0byBpbnNlcnQgdGhpcyBpbnRvIHRoZSBNYWNoaW5lQmFzaWNCbG9jay4KKyAgYm9vbCB1c2VzQ3VzdG9tSW5zZXJ0aW9uSG9vayhRdWVyeVR5cGUgVHlwZSA9IElnbm9yZUJ1bmRsZSkgY29uc3QgeworICAgIHJldHVybiBoYXNQcm9wZXJ0eShNQ0lEOjpVc2VzQ3VzdG9tSW5zZXJ0ZXIsIFR5cGUpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gcmVxdWlyZXMgKmFkanVzdG1lbnQqCisgIC8vLyBhZnRlciBpbnN0cnVjdGlvbiBzZWxlY3Rpb24gYnkgY2FsbGluZyBhIHRhcmdldCBob29rLiBGb3IgZXhhbXBsZSwgdGhpcworICAvLy8gY2FuIGJlIHVzZWQgdG8gZmlsbCBpbiBBUk0gJ3MnIG9wdGlvbmFsIG9wZXJhbmQgZGVwZW5kaW5nIG9uIHdoZXRoZXIKKyAgLy8vIHRoZSBjb25kaXRpb25hbCBmbGFnIHJlZ2lzdGVyIGlzIHVzZWQuCisgIGJvb2wgaGFzUG9zdElTZWxIb29rKFF1ZXJ5VHlwZSBUeXBlID0gSWdub3JlQnVuZGxlKSBjb25zdCB7CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6Okhhc1Bvc3RJU2VsSG9vaywgVHlwZSk7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gaXMgYSBjYW5kaWRhdGUgZm9yIHJlbWF0LgorICAvLy8gVGhpcyBmbGFnIGlzIGRlcHJlY2F0ZWQsIHBsZWFzZSBkb24ndCB1c2UgaXQgYW55bW9yZS4gIElmIHRoaXMKKyAgLy8vIGZsYWcgaXMgc2V0LCB0aGUgaXNSZWFsbHlUcml2aWFsbHlSZU1hdGVyaWFsaXphYmxlKCkgbWV0aG9kIGlzIGNhbGxlZCB0bworICAvLy8gdmVyaWZ5IHRoZSBpbnN0cnVjdGlvbiBpcyByZWFsbHkgcmVtYXRhYmxlLgorICBib29sIGlzUmVtYXRlcmlhbGl6YWJsZShRdWVyeVR5cGUgVHlwZSA9IEFsbEluQnVuZGxlKSBjb25zdCB7CisgICAgLy8gSXQncyBvbmx5IHBvc3NpYmxlIHRvIHJlLW1hdCBhIGJ1bmRsZSBpZiBhbGwgYnVuZGxlZCBpbnN0cnVjdGlvbnMgYXJlCisgICAgLy8gcmUtbWF0ZXJpYWxpemFibGUuCisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6OlJlbWF0ZXJpYWxpemFibGUsIFR5cGUpOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGluc3RydWN0aW9uIGhhcyB0aGUgc2FtZSBjb3N0IChvciBsZXNzKSB0aGFuIGEgbW92ZQorICAvLy8gaW5zdHJ1Y3Rpb24uIFRoaXMgaXMgdXNlZnVsIGR1cmluZyBjZXJ0YWluIHR5cGVzIG9mIG9wdGltaXphdGlvbnMKKyAgLy8vIChlLmcuLCByZW1hdCBkdXJpbmcgdHdvLWFkZHJlc3MgY29udmVyc2lvbiBvciBtYWNoaW5lIGxpY20pCisgIC8vLyB3aGVyZSB3ZSB3b3VsZCBsaWtlIHRvIHJlbWF0IG9yIGhvaXN0IHRoZSBpbnN0cnVjdGlvbiwgYnV0IG5vdCBpZiBpdCBjb3N0cworICAvLy8gbW9yZSB0aGFuIG1vdmluZyB0aGUgaW5zdHJ1Y3Rpb24gaW50byB0aGUgYXBwcm9wcmlhdGUgcmVnaXN0ZXIuIE5vdGUsIHdlCisgIC8vLyBhcmUgbm90IG1hcmtpbmcgY29waWVzIGZyb20gYW5kIHRvIHRoZSBzYW1lIHJlZ2lzdGVyIGNsYXNzIHdpdGggdGhpcyBmbGFnLgorICBib29sIGlzQXNDaGVhcEFzQU1vdmUoUXVlcnlUeXBlIFR5cGUgPSBBbGxJbkJ1bmRsZSkgY29uc3QgeworICAgIC8vIE9ubHkgcmV0dXJucyB0cnVlIGZvciBhIGJ1bmRsZSBpZiBhbGwgYnVuZGxlZCBpbnN0cnVjdGlvbnMgYXJlIGNoZWFwLgorICAgIHJldHVybiBoYXNQcm9wZXJ0eShNQ0lEOjpDaGVhcEFzQU1vdmUsIFR5cGUpOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGluc3RydWN0aW9uIHNvdXJjZSBvcGVyYW5kcworICAvLy8gaGF2ZSBzcGVjaWFsIHJlZ2lzdGVyIGFsbG9jYXRpb24gcmVxdWlyZW1lbnRzIHRoYXQgYXJlIG5vdCBjYXB0dXJlZCBieSB0aGUKKyAgLy8vIG9wZXJhbmQgcmVnaXN0ZXIgY2xhc3Nlcy4gZS5nLiBBUk06OlNUUkQncyB0d28gc291cmNlIHJlZ2lzdGVycyBtdXN0IGJlIGFuCisgIC8vLyBldmVuIC8gb2RkIHBhaXIsIEFSTTo6U1RNIHJlZ2lzdGVycyBoYXZlIHRvIGJlIGluIGFzY2VuZGluZyBvcmRlci4KKyAgLy8vIFBvc3QtcmVnaXN0ZXIgYWxsb2NhdGlvbiBwYXNzZXMgc2hvdWxkIG5vdCBhdHRlbXB0IHRvIGNoYW5nZSBhbGxvY2F0aW9ucworICAvLy8gZm9yIHNvdXJjZXMgb2YgaW5zdHJ1Y3Rpb25zIHdpdGggdGhpcyBmbGFnLgorICBib29sIGhhc0V4dHJhU3JjUmVnQWxsb2NSZXEoUXVlcnlUeXBlIFR5cGUgPSBBbnlJbkJ1bmRsZSkgY29uc3QgeworICAgIHJldHVybiBoYXNQcm9wZXJ0eShNQ0lEOjpFeHRyYVNyY1JlZ0FsbG9jUmVxLCBUeXBlKTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBpbnN0cnVjdGlvbiBkZWYgb3BlcmFuZHMKKyAgLy8vIGhhdmUgc3BlY2lhbCByZWdpc3RlciBhbGxvY2F0aW9uIHJlcXVpcmVtZW50cyB0aGF0IGFyZSBub3QgY2FwdHVyZWQgYnkgdGhlCisgIC8vLyBvcGVyYW5kIHJlZ2lzdGVyIGNsYXNzZXMuIGUuZy4gQVJNOjpMRFJEJ3MgdHdvIGRlZiByZWdpc3RlcnMgbXVzdCBiZSBhbgorICAvLy8gZXZlbiAvIG9kZCBwYWlyLCBBUk06OkxETSByZWdpc3RlcnMgaGF2ZSB0byBiZSBpbiBhc2NlbmRpbmcgb3JkZXIuCisgIC8vLyBQb3N0LXJlZ2lzdGVyIGFsbG9jYXRpb24gcGFzc2VzIHNob3VsZCBub3QgYXR0ZW1wdCB0byBjaGFuZ2UgYWxsb2NhdGlvbnMKKyAgLy8vIGZvciBkZWZpbml0aW9ucyBvZiBpbnN0cnVjdGlvbnMgd2l0aCB0aGlzIGZsYWcuCisgIGJvb2wgaGFzRXh0cmFEZWZSZWdBbGxvY1JlcShRdWVyeVR5cGUgVHlwZSA9IEFueUluQnVuZGxlKSBjb25zdCB7CisgICAgcmV0dXJuIGhhc1Byb3BlcnR5KE1DSUQ6OkV4dHJhRGVmUmVnQWxsb2NSZXEsIFR5cGUpOworICB9CisKKyAgZW51bSBNSUNoZWNrVHlwZSB7CisgICAgQ2hlY2tEZWZzLCAgICAgIC8vIENoZWNrIGFsbCBvcGVyYW5kcyBmb3IgZXF1YWxpdHkKKyAgICBDaGVja0tpbGxEZWFkLCAgLy8gQ2hlY2sgYWxsIG9wZXJhbmRzIGluY2x1ZGluZyBraWxsIC8gZGVhZCBtYXJrZXJzCisgICAgSWdub3JlRGVmcywgICAgIC8vIElnbm9yZSBhbGwgZGVmaW5pdGlvbnMKKyAgICBJZ25vcmVWUmVnRGVmcyAgLy8gSWdub3JlIHZpcnR1YWwgcmVnaXN0ZXIgZGVmaW5pdGlvbnMKKyAgfTsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpbnN0cnVjdGlvbiBpcyBpZGVudGljYWwgdG8gXHAgT3RoZXIuCisgIC8vLyBUd28gaW5zdHJ1Y3Rpb25zIGFyZSBpZGVudGljYWwgaWYgdGhleSBoYXZlIHRoZSBzYW1lIG9wY29kZSBhbmQgYWxsIHRoZWlyCisgIC8vLyBvcGVyYW5kcyBhcmUgaWRlbnRpY2FsICh3aXRoIHJlc3BlY3QgdG8gTWFjaGluZU9wZXJhbmQ6OmlzSWRlbnRpY2FsVG8oKSkuCisgIC8vLyBOb3RlIHRoYXQgdGhpcyBtZWFucyBsaXZlbmVzcyByZWxhdGVkIGZsYWdzIChkZWFkLCB1bmRlZiwga2lsbCkgZG8gbm90CisgIC8vLyBhZmZlY3QgdGhlIG5vdGlvbiBvZiBpZGVudGljYWwuCisgIGJvb2wgaXNJZGVudGljYWxUbyhjb25zdCBNYWNoaW5lSW5zdHIgJk90aGVyLAorICAgICAgICAgICAgICAgICAgICAgTUlDaGVja1R5cGUgQ2hlY2sgPSBDaGVja0RlZnMpIGNvbnN0OworCisgIC8vLyBVbmxpbmsgJ3RoaXMnIGZyb20gdGhlIGNvbnRhaW5pbmcgYmFzaWMgYmxvY2ssIGFuZCByZXR1cm4gaXQgd2l0aG91dAorICAvLy8gZGVsZXRpbmcgaXQuCisgIC8vLworICAvLy8gVGhpcyBmdW5jdGlvbiBjYW4gbm90IGJlIHVzZWQgb24gYnVuZGxlZCBpbnN0cnVjdGlvbnMsIHVzZQorICAvLy8gcmVtb3ZlRnJvbUJ1bmRsZSgpIHRvIHJlbW92ZSBpbmRpdmlkdWFsIGluc3RydWN0aW9ucyBmcm9tIGEgYnVuZGxlLgorICBNYWNoaW5lSW5zdHIgKnJlbW92ZUZyb21QYXJlbnQoKTsKKworICAvLy8gVW5saW5rIHRoaXMgaW5zdHJ1Y3Rpb24gZnJvbSBpdHMgYmFzaWMgYmxvY2sgYW5kIHJldHVybiBpdCB3aXRob3V0CisgIC8vLyBkZWxldGluZyBpdC4KKyAgLy8vCisgIC8vLyBJZiB0aGUgaW5zdHJ1Y3Rpb24gaXMgcGFydCBvZiBhIGJ1bmRsZSwgdGhlIG90aGVyIGluc3RydWN0aW9ucyBpbiB0aGUKKyAgLy8vIGJ1bmRsZSByZW1haW4gYnVuZGxlZC4KKyAgTWFjaGluZUluc3RyICpyZW1vdmVGcm9tQnVuZGxlKCk7CisKKyAgLy8vIFVubGluayAndGhpcycgZnJvbSB0aGUgY29udGFpbmluZyBiYXNpYyBibG9jayBhbmQgZGVsZXRlIGl0LgorICAvLy8KKyAgLy8vIElmIHRoaXMgaW5zdHJ1Y3Rpb24gaXMgdGhlIGhlYWRlciBvZiBhIGJ1bmRsZSwgdGhlIHdob2xlIGJ1bmRsZSBpcyBlcmFzZWQuCisgIC8vLyBUaGlzIGZ1bmN0aW9uIGNhbiBub3QgYmUgdXNlZCBmb3IgaW5zdHJ1Y3Rpb25zIGluc2lkZSBhIGJ1bmRsZSwgdXNlCisgIC8vLyBlcmFzZUZyb21CdW5kbGUoKSB0byBlcmFzZSBpbmRpdmlkdWFsIGJ1bmRsZWQgaW5zdHJ1Y3Rpb25zLgorICB2b2lkIGVyYXNlRnJvbVBhcmVudCgpOworCisgIC8vLyBVbmxpbmsgJ3RoaXMnIGZyb20gdGhlIGNvbnRhaW5pbmcgYmFzaWMgYmxvY2sgYW5kIGRlbGV0ZSBpdC4KKyAgLy8vCisgIC8vLyBGb3IgYWxsIGRlZmluaXRpb25zIG1hcmsgdGhlaXIgdXNlcyBpbiBEQkdfVkFMVUUgbm9kZXMKKyAgLy8vIGFzIHVuZGVmaW5lZC4gT3RoZXJ3aXNlIGxpa2UgZXJhc2VGcm9tUGFyZW50KCkuCisgIHZvaWQgZXJhc2VGcm9tUGFyZW50QW5kTWFya0RCR1ZhbHVlc0ZvclJlbW92YWwoKTsKKworICAvLy8gVW5saW5rICd0aGlzJyBmb3JtIGl0cyBiYXNpYyBibG9jayBhbmQgZGVsZXRlIGl0LgorICAvLy8KKyAgLy8vIElmIHRoZSBpbnN0cnVjdGlvbiBpcyBwYXJ0IG9mIGEgYnVuZGxlLCB0aGUgb3RoZXIgaW5zdHJ1Y3Rpb25zIGluIHRoZQorICAvLy8gYnVuZGxlIHJlbWFpbiBidW5kbGVkLgorICB2b2lkIGVyYXNlRnJvbUJ1bmRsZSgpOworCisgIGJvb2wgaXNFSExhYmVsKCkgY29uc3QgeyByZXR1cm4gZ2V0T3Bjb2RlKCkgPT0gVGFyZ2V0T3Bjb2RlOjpFSF9MQUJFTDsgfQorICBib29sIGlzR0NMYWJlbCgpIGNvbnN0IHsgcmV0dXJuIGdldE9wY29kZSgpID09IFRhcmdldE9wY29kZTo6R0NfTEFCRUw7IH0KKyAgYm9vbCBpc0Fubm90YXRpb25MYWJlbCgpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0T3Bjb2RlKCkgPT0gVGFyZ2V0T3Bjb2RlOjpBTk5PVEFUSU9OX0xBQkVMOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgTWFjaGluZUluc3RyIHJlcHJlc2VudHMgYSBsYWJlbC4KKyAgYm9vbCBpc0xhYmVsKCkgY29uc3QgeworICAgIHJldHVybiBpc0VITGFiZWwoKSB8fCBpc0dDTGFiZWwoKSB8fCBpc0Fubm90YXRpb25MYWJlbCgpOworICB9CisKKyAgYm9vbCBpc0NGSUluc3RydWN0aW9uKCkgY29uc3QgeworICAgIHJldHVybiBnZXRPcGNvZGUoKSA9PSBUYXJnZXRPcGNvZGU6OkNGSV9JTlNUUlVDVElPTjsKKyAgfQorCisgIC8vIFRydWUgaWYgdGhlIGluc3RydWN0aW9uIHJlcHJlc2VudHMgYSBwb3NpdGlvbiBpbiB0aGUgZnVuY3Rpb24uCisgIGJvb2wgaXNQb3NpdGlvbigpIGNvbnN0IHsgcmV0dXJuIGlzTGFiZWwoKSB8fCBpc0NGSUluc3RydWN0aW9uKCk7IH0KKworICBib29sIGlzRGVidWdWYWx1ZSgpIGNvbnN0IHsgcmV0dXJuIGdldE9wY29kZSgpID09IFRhcmdldE9wY29kZTo6REJHX1ZBTFVFOyB9CisKKyAgLy8vIEEgREJHX1ZBTFVFIGlzIGluZGlyZWN0IGlmZiB0aGUgZmlyc3Qgb3BlcmFuZCBpcyBhIHJlZ2lzdGVyIGFuZAorICAvLy8gdGhlIHNlY29uZCBvcGVyYW5kIGlzIGFuIGltbWVkaWF0ZS4KKyAgYm9vbCBpc0luZGlyZWN0RGVidWdWYWx1ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gaXNEZWJ1Z1ZhbHVlKCkKKyAgICAgICYmIGdldE9wZXJhbmQoMCkuaXNSZWcoKQorICAgICAgJiYgZ2V0T3BlcmFuZCgxKS5pc0ltbSgpOworICB9CisKKyAgYm9vbCBpc1BISSgpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0T3Bjb2RlKCkgPT0gVGFyZ2V0T3Bjb2RlOjpQSEkgfHwKKyAgICAgICAgICAgZ2V0T3Bjb2RlKCkgPT0gVGFyZ2V0T3Bjb2RlOjpHX1BISTsKKyAgfQorICBib29sIGlzS2lsbCgpIGNvbnN0IHsgcmV0dXJuIGdldE9wY29kZSgpID09IFRhcmdldE9wY29kZTo6S0lMTDsgfQorICBib29sIGlzSW1wbGljaXREZWYoKSBjb25zdCB7IHJldHVybiBnZXRPcGNvZGUoKT09VGFyZ2V0T3Bjb2RlOjpJTVBMSUNJVF9ERUY7IH0KKyAgYm9vbCBpc0lubGluZUFzbSgpIGNvbnN0IHsgcmV0dXJuIGdldE9wY29kZSgpID09IFRhcmdldE9wY29kZTo6SU5MSU5FQVNNOyB9CisKKyAgYm9vbCBpc01TSW5saW5lQXNtKCkgY29uc3QgeworICAgIHJldHVybiBnZXRPcGNvZGUoKSA9PSBUYXJnZXRPcGNvZGU6OklOTElORUFTTSAmJiBnZXRJbmxpbmVBc21EaWFsZWN0KCk7CisgIH0KKworICBib29sIGlzU3RhY2tBbGlnbmluZ0lubGluZUFzbSgpIGNvbnN0OworICBJbmxpbmVBc206OkFzbURpYWxlY3QgZ2V0SW5saW5lQXNtRGlhbGVjdCgpIGNvbnN0OworCisgIGJvb2wgaXNJbnNlcnRTdWJyZWcoKSBjb25zdCB7CisgICAgcmV0dXJuIGdldE9wY29kZSgpID09IFRhcmdldE9wY29kZTo6SU5TRVJUX1NVQlJFRzsKKyAgfQorCisgIGJvb2wgaXNTdWJyZWdUb1JlZygpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0T3Bjb2RlKCkgPT0gVGFyZ2V0T3Bjb2RlOjpTVUJSRUdfVE9fUkVHOworICB9CisKKyAgYm9vbCBpc1JlZ1NlcXVlbmNlKCkgY29uc3QgeworICAgIHJldHVybiBnZXRPcGNvZGUoKSA9PSBUYXJnZXRPcGNvZGU6OlJFR19TRVFVRU5DRTsKKyAgfQorCisgIGJvb2wgaXNCdW5kbGUoKSBjb25zdCB7CisgICAgcmV0dXJuIGdldE9wY29kZSgpID09IFRhcmdldE9wY29kZTo6QlVORExFOworICB9CisKKyAgYm9vbCBpc0NvcHkoKSBjb25zdCB7CisgICAgcmV0dXJuIGdldE9wY29kZSgpID09IFRhcmdldE9wY29kZTo6Q09QWTsKKyAgfQorCisgIGJvb2wgaXNGdWxsQ29weSgpIGNvbnN0IHsKKyAgICByZXR1cm4gaXNDb3B5KCkgJiYgIWdldE9wZXJhbmQoMCkuZ2V0U3ViUmVnKCkgJiYgIWdldE9wZXJhbmQoMSkuZ2V0U3ViUmVnKCk7CisgIH0KKworICBib29sIGlzRXh0cmFjdFN1YnJlZygpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0T3Bjb2RlKCkgPT0gVGFyZ2V0T3Bjb2RlOjpFWFRSQUNUX1NVQlJFRzsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgaW5zdHJ1Y3Rpb24gYmVoYXZlcyBsaWtlIGEgY29weS4KKyAgLy8vIFRoaXMgZG9lcyBub3QgaW5jbHVkZSBuYXRpdmUgY29weSBpbnN0cnVjdGlvbnMuCisgIGJvb2wgaXNDb3B5TGlrZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gaXNDb3B5KCkgfHwgaXNTdWJyZWdUb1JlZygpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlzIHRoZSBpbnN0cnVjdGlvbiBpcyBhbiBpZGVudGl0eSBjb3B5LgorICBib29sIGlzSWRlbnRpdHlDb3B5KCkgY29uc3QgeworICAgIHJldHVybiBpc0NvcHkoKSAmJiBnZXRPcGVyYW5kKDApLmdldFJlZygpID09IGdldE9wZXJhbmQoMSkuZ2V0UmVnKCkgJiYKKyAgICAgIGdldE9wZXJhbmQoMCkuZ2V0U3ViUmVnKCkgPT0gZ2V0T3BlcmFuZCgxKS5nZXRTdWJSZWcoKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGluc3RydWN0aW9uIGRvZXNuJ3QgcHJvZHVjZSBhbnkgb3V0cHV0IGluIHRoZSBmb3JtIG9mCisgIC8vLyBleGVjdXRhYmxlIGluc3RydWN0aW9ucy4KKyAgYm9vbCBpc01ldGFJbnN0cnVjdGlvbigpIGNvbnN0IHsKKyAgICBzd2l0Y2ggKGdldE9wY29kZSgpKSB7CisgICAgZGVmYXVsdDoKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICBjYXNlIFRhcmdldE9wY29kZTo6SU1QTElDSVRfREVGOgorICAgIGNhc2UgVGFyZ2V0T3Bjb2RlOjpLSUxMOgorICAgIGNhc2UgVGFyZ2V0T3Bjb2RlOjpDRklfSU5TVFJVQ1RJT046CisgICAgY2FzZSBUYXJnZXRPcGNvZGU6OkVIX0xBQkVMOgorICAgIGNhc2UgVGFyZ2V0T3Bjb2RlOjpHQ19MQUJFTDoKKyAgICBjYXNlIFRhcmdldE9wY29kZTo6REJHX1ZBTFVFOgorICAgIGNhc2UgVGFyZ2V0T3Bjb2RlOjpMSUZFVElNRV9TVEFSVDoKKyAgICBjYXNlIFRhcmdldE9wY29kZTo6TElGRVRJTUVfRU5EOgorICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaXMgYSB0cmFuc2llbnQgaW5zdHJ1Y3Rpb24gdGhhdCBpcyBlaXRoZXIgdmVyeSBsaWtlbHkKKyAgLy8vIHRvIGJlIGVsaW1pbmF0ZWQgZHVyaW5nIHJlZ2lzdGVyIGFsbG9jYXRpb24gKHN1Y2ggYXMgY29weS1saWtlCisgIC8vLyBpbnN0cnVjdGlvbnMpLCBvciBpZiB0aGlzIGluc3RydWN0aW9uIGRvZXNuJ3QgaGF2ZSBhbiBleGVjdXRpb24tdGltZSBjb3N0LgorICBib29sIGlzVHJhbnNpZW50KCkgY29uc3QgeworICAgIHN3aXRjaCAoZ2V0T3Bjb2RlKCkpIHsKKyAgICBkZWZhdWx0OgorICAgICAgcmV0dXJuIGlzTWV0YUluc3RydWN0aW9uKCk7CisgICAgLy8gQ29weS1saWtlIGluc3RydWN0aW9ucyBhcmUgdXN1YWxseSBlbGltaW5hdGVkIGR1cmluZyByZWdpc3RlciBhbGxvY2F0aW9uLgorICAgIGNhc2UgVGFyZ2V0T3Bjb2RlOjpQSEk6CisgICAgY2FzZSBUYXJnZXRPcGNvZGU6OkdfUEhJOgorICAgIGNhc2UgVGFyZ2V0T3Bjb2RlOjpDT1BZOgorICAgIGNhc2UgVGFyZ2V0T3Bjb2RlOjpJTlNFUlRfU1VCUkVHOgorICAgIGNhc2UgVGFyZ2V0T3Bjb2RlOjpTVUJSRUdfVE9fUkVHOgorICAgIGNhc2UgVGFyZ2V0T3Bjb2RlOjpSRUdfU0VRVUVOQ0U6CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgaW5zdHJ1Y3Rpb25zIGluc2lkZSB0aGUgTUkgYnVuZGxlLCBleGNsdWRpbmcgdGhlCisgIC8vLyBidW5kbGUgaGVhZGVyLgorICAvLy8KKyAgLy8vIFRoaXMgaXMgdGhlIG51bWJlciBvZiBpbnN0cnVjdGlvbnMgdGhhdCBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IKKyAgLy8vIHNraXBzLCAwIGZvciB1bmJ1bmRsZWQgaW5zdHJ1Y3Rpb25zLgorICB1bnNpZ25lZCBnZXRCdW5kbGVTaXplKCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBNYWNoaW5lSW5zdHIgcmVhZHMgdGhlIHNwZWNpZmllZCByZWdpc3Rlci4KKyAgLy8vIElmIFRhcmdldFJlZ2lzdGVySW5mbyBpcyBwYXNzZWQsIHRoZW4gaXQgYWxzbyBjaGVja3MgaWYgdGhlcmUKKyAgLy8vIGlzIGEgcmVhZCBvZiBhIHN1cGVyLXJlZ2lzdGVyLgorICAvLy8gVGhpcyBkb2VzIG5vdCBjb3VudCBwYXJ0aWFsIHJlZGVmaW5lcyBvZiB2aXJ0dWFsIHJlZ2lzdGVycyBhcyByZWFkczoKKyAgLy8vICAgJXJlZzEwMjQ6NiA9IE9QLgorICBib29sIHJlYWRzUmVnaXN0ZXIodW5zaWduZWQgUmVnLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkgPSBudWxscHRyKSBjb25zdCB7CisgICAgcmV0dXJuIGZpbmRSZWdpc3RlclVzZU9wZXJhbmRJZHgoUmVnLCBmYWxzZSwgVFJJKSAhPSAtMTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgTWFjaGluZUluc3RyIHJlYWRzIHRoZSBzcGVjaWZpZWQgdmlydHVhbCByZWdpc3Rlci4KKyAgLy8vIFRha2UgaW50byBhY2NvdW50IHRoYXQgYSBwYXJ0aWFsIGRlZmluZSBpcyBhCisgIC8vLyByZWFkLW1vZGlmeS13cml0ZSBvcGVyYXRpb24uCisgIGJvb2wgcmVhZHNWaXJ0dWFsUmVnaXN0ZXIodW5zaWduZWQgUmVnKSBjb25zdCB7CisgICAgcmV0dXJuIHJlYWRzV3JpdGVzVmlydHVhbFJlZ2lzdGVyKFJlZykuZmlyc3Q7CisgIH0KKworICAvLy8gUmV0dXJuIGEgcGFpciBvZiBib29scyAocmVhZHMsIHdyaXRlcykgaW5kaWNhdGluZyBpZiB0aGlzIGluc3RydWN0aW9uCisgIC8vLyByZWFkcyBvciB3cml0ZXMgUmVnLiBUaGlzIGFsc28gY29uc2lkZXJzIHBhcnRpYWwgZGVmaW5lcy4KKyAgLy8vIElmIE9wcyBpcyBub3QgbnVsbCwgYWxsIG9wZXJhbmQgaW5kaWNlcyBmb3IgUmVnIGFyZSBhZGRlZC4KKyAgc3RkOjpwYWlyPGJvb2wsYm9vbD4gcmVhZHNXcml0ZXNWaXJ0dWFsUmVnaXN0ZXIodW5zaWduZWQgUmVnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8dW5zaWduZWQ+ICpPcHMgPSBudWxscHRyKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIE1hY2hpbmVJbnN0ciBraWxscyB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyLgorICAvLy8gSWYgVGFyZ2V0UmVnaXN0ZXJJbmZvIGlzIHBhc3NlZCwgdGhlbiBpdCBhbHNvIGNoZWNrcyBpZiB0aGVyZSBpcworICAvLy8gYSBraWxsIG9mIGEgc3VwZXItcmVnaXN0ZXIuCisgIGJvb2wga2lsbHNSZWdpc3Rlcih1bnNpZ25lZCBSZWcsCisgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSA9IG51bGxwdHIpIGNvbnN0IHsKKyAgICByZXR1cm4gZmluZFJlZ2lzdGVyVXNlT3BlcmFuZElkeChSZWcsIHRydWUsIFRSSSkgIT0gLTE7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIE1hY2hpbmVJbnN0ciBmdWxseSBkZWZpbmVzIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIuCisgIC8vLyBJZiBUYXJnZXRSZWdpc3RlckluZm8gaXMgcGFzc2VkLCB0aGVuIGl0IGFsc28gY2hlY2tzCisgIC8vLyBpZiB0aGVyZSBpcyBhIGRlZiBvZiBhIHN1cGVyLXJlZ2lzdGVyLgorICAvLy8gTk9URTogSXQncyBpZ25vcmluZyBzdWJyZWcgaW5kaWNlcyBvbiB2aXJ0dWFsIHJlZ2lzdGVycy4KKyAgYm9vbCBkZWZpbmVzUmVnaXN0ZXIodW5zaWduZWQgUmVnLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSA9IG51bGxwdHIpIGNvbnN0IHsKKyAgICByZXR1cm4gZmluZFJlZ2lzdGVyRGVmT3BlcmFuZElkeChSZWcsIGZhbHNlLCBmYWxzZSwgVFJJKSAhPSAtMTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgTWFjaGluZUluc3RyIG1vZGlmaWVzIChmdWxseSBkZWZpbmUgb3IgcGFydGlhbGx5CisgIC8vLyBkZWZpbmUpIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIuCisgIC8vLyBOT1RFOiBJdCdzIGlnbm9yaW5nIHN1YnJlZyBpbmRpY2VzIG9uIHZpcnR1YWwgcmVnaXN0ZXJzLgorICBib29sIG1vZGlmaWVzUmVnaXN0ZXIodW5zaWduZWQgUmVnLCBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSkgY29uc3QgeworICAgIHJldHVybiBmaW5kUmVnaXN0ZXJEZWZPcGVyYW5kSWR4KFJlZywgZmFsc2UsIHRydWUsIFRSSSkgIT0gLTE7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSByZWdpc3RlciBpcyBkZWFkIGluIHRoaXMgbWFjaGluZSBpbnN0cnVjdGlvbi4KKyAgLy8vIElmIFRhcmdldFJlZ2lzdGVySW5mbyBpcyBwYXNzZWQsIHRoZW4gaXQgYWxzbyBjaGVja3MKKyAgLy8vIGlmIHRoZXJlIGlzIGEgZGVhZCBkZWYgb2YgYSBzdXBlci1yZWdpc3Rlci4KKyAgYm9vbCByZWdpc3RlckRlZklzRGVhZCh1bnNpZ25lZCBSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkgPSBudWxscHRyKSBjb25zdCB7CisgICAgcmV0dXJuIGZpbmRSZWdpc3RlckRlZk9wZXJhbmRJZHgoUmVnLCB0cnVlLCBmYWxzZSwgVFJJKSAhPSAtMTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIE1hY2hpbmVJbnN0ciBoYXMgYW4gaW1wbGljaXQtdXNlIG9wZXJhbmQgb2YgZXhhY3RseQorICAvLy8gdGhlIGdpdmVuIHJlZ2lzdGVyIChub3QgY29uc2lkZXJpbmcgc3ViL3N1cGVyLXJlZ2lzdGVycykuCisgIGJvb2wgaGFzUmVnaXN0ZXJJbXBsaWNpdFVzZU9wZXJhbmQodW5zaWduZWQgUmVnKSBjb25zdDsKKworICAvLy8gUmV0dXJucyB0aGUgb3BlcmFuZCBpbmRleCB0aGF0IGlzIGEgdXNlIG9mIHRoZSBzcGVjaWZpYyByZWdpc3RlciBvciAtMQorICAvLy8gaWYgaXQgaXMgbm90IGZvdW5kLiBJdCBmdXJ0aGVyIHRpZ2h0ZW5zIHRoZSBzZWFyY2ggY3JpdGVyaWEgdG8gYSB1c2UKKyAgLy8vIHRoYXQga2lsbHMgdGhlIHJlZ2lzdGVyIGlmIGlzS2lsbCBpcyB0cnVlLgorICBpbnQgZmluZFJlZ2lzdGVyVXNlT3BlcmFuZElkeCh1bnNpZ25lZCBSZWcsIGJvb2wgaXNLaWxsID0gZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJID0gbnVsbHB0cikgY29uc3Q7CisKKyAgLy8vIFdyYXBwZXIgZm9yIGZpbmRSZWdpc3RlclVzZU9wZXJhbmRJZHgsIGl0IHJldHVybnMKKyAgLy8vIGEgcG9pbnRlciB0byB0aGUgTWFjaGluZU9wZXJhbmQgcmF0aGVyIHRoYW4gYW4gaW5kZXguCisgIE1hY2hpbmVPcGVyYW5kICpmaW5kUmVnaXN0ZXJVc2VPcGVyYW5kKHVuc2lnbmVkIFJlZywgYm9vbCBpc0tpbGwgPSBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkgPSBudWxscHRyKSB7CisgICAgaW50IElkeCA9IGZpbmRSZWdpc3RlclVzZU9wZXJhbmRJZHgoUmVnLCBpc0tpbGwsIFRSSSk7CisgICAgcmV0dXJuIChJZHggPT0gLTEpID8gbnVsbHB0ciA6ICZnZXRPcGVyYW5kKElkeCk7CisgIH0KKworICBjb25zdCBNYWNoaW5lT3BlcmFuZCAqZmluZFJlZ2lzdGVyVXNlT3BlcmFuZCgKKyAgICB1bnNpZ25lZCBSZWcsIGJvb2wgaXNLaWxsID0gZmFsc2UsCisgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkgPSBudWxscHRyKSBjb25zdCB7CisgICAgcmV0dXJuIGNvbnN0X2Nhc3Q8TWFjaGluZUluc3RyICo+KHRoaXMpLT4KKyAgICAgIGZpbmRSZWdpc3RlclVzZU9wZXJhbmQoUmVnLCBpc0tpbGwsIFRSSSk7CisgIH0KKworICAvLy8gUmV0dXJucyB0aGUgb3BlcmFuZCBpbmRleCB0aGF0IGlzIGEgZGVmIG9mIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIgb3IKKyAgLy8vIC0xIGlmIGl0IGlzIG5vdCBmb3VuZC4gSWYgaXNEZWFkIGlzIHRydWUsIGRlZnMgdGhhdCBhcmUgbm90IGRlYWQgYXJlCisgIC8vLyBza2lwcGVkLiBJZiBPdmVybGFwIGlzIHRydWUsIHRoZW4gaXQgYWxzbyBsb29rcyBmb3IgZGVmcyB0aGF0IG1lcmVseQorICAvLy8gb3ZlcmxhcCB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyLiBJZiBUYXJnZXRSZWdpc3RlckluZm8gaXMgbm9uLW51bGwsCisgIC8vLyB0aGVuIGl0IGFsc28gY2hlY2tzIGlmIHRoZXJlIGlzIGEgZGVmIG9mIGEgc3VwZXItcmVnaXN0ZXIuCisgIC8vLyBUaGlzIG1heSBhbHNvIHJldHVybiBhIHJlZ2lzdGVyIG1hc2sgb3BlcmFuZCB3aGVuIE92ZXJsYXAgaXMgdHJ1ZS4KKyAgaW50IGZpbmRSZWdpc3RlckRlZk9wZXJhbmRJZHgodW5zaWduZWQgUmVnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzRGVhZCA9IGZhbHNlLCBib29sIE92ZXJsYXAgPSBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkgPSBudWxscHRyKSBjb25zdDsKKworICAvLy8gV3JhcHBlciBmb3IgZmluZFJlZ2lzdGVyRGVmT3BlcmFuZElkeCwgaXQgcmV0dXJucworICAvLy8gYSBwb2ludGVyIHRvIHRoZSBNYWNoaW5lT3BlcmFuZCByYXRoZXIgdGhhbiBhbiBpbmRleC4KKyAgTWFjaGluZU9wZXJhbmQgKmZpbmRSZWdpc3RlckRlZk9wZXJhbmQodW5zaWduZWQgUmVnLCBib29sIGlzRGVhZCA9IGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSA9IG51bGxwdHIpIHsKKyAgICBpbnQgSWR4ID0gZmluZFJlZ2lzdGVyRGVmT3BlcmFuZElkeChSZWcsIGlzRGVhZCwgZmFsc2UsIFRSSSk7CisgICAgcmV0dXJuIChJZHggPT0gLTEpID8gbnVsbHB0ciA6ICZnZXRPcGVyYW5kKElkeCk7CisgIH0KKworICAvLy8gRmluZCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IG9wZXJhbmQgaW4gdGhlCisgIC8vLyBvcGVyYW5kIGxpc3QgdGhhdCBpcyB1c2VkIHRvIHJlcHJlc2VudCB0aGUgcHJlZGljYXRlLiBJdCByZXR1cm5zIC0xIGlmCisgIC8vLyBub25lIGlzIGZvdW5kLgorICBpbnQgZmluZEZpcnN0UHJlZE9wZXJhbmRJZHgoKSBjb25zdDsKKworICAvLy8gRmluZCB0aGUgaW5kZXggb2YgdGhlIGZsYWcgd29yZCBvcGVyYW5kIHRoYXQKKyAgLy8vIGNvcnJlc3BvbmRzIHRvIG9wZXJhbmQgT3BJZHggb24gYW4gaW5saW5lIGFzbSBpbnN0cnVjdGlvbi4gIFJldHVybnMgLTEgaWYKKyAgLy8vIGdldE9wZXJhbmQoT3BJZHgpIGRvZXMgbm90IGJlbG9uZyB0byBhbiBpbmxpbmUgYXNtIG9wZXJhbmQgZ3JvdXAuCisgIC8vLworICAvLy8gSWYgR3JvdXBObyBpcyBub3QgTlVMTCwgaXQgd2lsbCByZWNlaXZlIHRoZSBudW1iZXIgb2YgdGhlIG9wZXJhbmQgZ3JvdXAKKyAgLy8vIGNvbnRhaW5pbmcgT3BJZHguCisgIC8vLworICAvLy8gVGhlIGZsYWcgb3BlcmFuZCBpcyBhbiBpbW1lZGlhdGUgdGhhdCBjYW4gYmUgZGVjb2RlZCB3aXRoIG1ldGhvZHMgbGlrZQorICAvLy8gSW5saW5lQXNtOjpoYXNSZWdDbGFzc0NvbnN0cmFpbnQoKS4KKyAgaW50IGZpbmRJbmxpbmVBc21GbGFnSWR4KHVuc2lnbmVkIE9wSWR4LCB1bnNpZ25lZCAqR3JvdXBObyA9IG51bGxwdHIpIGNvbnN0OworCisgIC8vLyBDb21wdXRlIHRoZSBzdGF0aWMgcmVnaXN0ZXIgY2xhc3MgY29uc3RyYWludCBmb3Igb3BlcmFuZCBPcElkeC4KKyAgLy8vIEZvciBub3JtYWwgaW5zdHJ1Y3Rpb25zLCB0aGlzIGlzIGRlcml2ZWQgZnJvbSB0aGUgTUNJbnN0ckRlc2MuCisgIC8vLyBGb3IgaW5saW5lIGFzc2VtYmx5IGl0IGlzIGRlcml2ZWQgZnJvbSB0aGUgZmxhZyB3b3Jkcy4KKyAgLy8vCisgIC8vLyBSZXR1cm5zIE5VTEwgaWYgdGhlIHN0YXRpYyByZWdpc3RlciBjbGFzcyBjb25zdHJhaW50IGNhbm5vdCBiZQorICAvLy8gZGV0ZXJtaW5lZC4KKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyoKKyAgZ2V0UmVnQ2xhc3NDb25zdHJhaW50KHVuc2lnbmVkIE9wSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICpUSUksCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSkgY29uc3Q7CisKKyAgLy8vIFxicmllZiBBcHBsaWVzIHRoZSBjb25zdHJhaW50cyAoZGVmL3VzZSkgaW1wbGllZCBieSB0aGlzIE1JIG9uIFxwIFJlZyB0bworICAvLy8gdGhlIGdpdmVuIFxwIEN1clJDLgorICAvLy8gSWYgXHAgRXhwbG9yZUJ1bmRsZSBpcyBzZXQgYW5kIE1JIGlzIHBhcnQgb2YgYSBidW5kbGUsIGFsbCB0aGUKKyAgLy8vIGluc3RydWN0aW9ucyBpbnNpZGUgdGhlIGJ1bmRsZSB3aWxsIGJlIHRha2VuIGludG8gYWNjb3VudC4gSW4gb3RoZXIgd29yZHMsCisgIC8vLyB0aGlzIG1ldGhvZCBhY2N1bXVsYXRlcyBhbGwgdGhlIGNvbnN0cmFpbnRzIG9mIHRoZSBvcGVyYW5kIG9mIHRoaXMgTUkgYW5kCisgIC8vLyB0aGUgcmVsYXRlZCBidW5kbGUgaWYgTUkgaXMgYSBidW5kbGUgb3IgaW5zaWRlIGEgYnVuZGxlLgorICAvLy8KKyAgLy8vIFJldHVybnMgdGhlIHJlZ2lzdGVyIGNsYXNzIHRoYXQgc2F0aXNmaWVzIGJvdGggXHAgQ3VyUkMgYW5kIHRoZQorICAvLy8gY29uc3RyYWludHMgc2V0IGJ5IE1JLiBSZXR1cm5zIE5VTEwgaWYgc3VjaCBhIHJlZ2lzdGVyIGNsYXNzIGRvZXMgbm90CisgIC8vLyBleGlzdC4KKyAgLy8vCisgIC8vLyBccHJlIEN1clJDIG11c3Qgbm90IGJlIE5VTEwuCisgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKmdldFJlZ0NsYXNzQ29uc3RyYWludEVmZmVjdEZvclZSZWcoCisgICAgICB1bnNpZ25lZCBSZWcsIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKkN1clJDLAorICAgICAgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICpUSUksIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJLAorICAgICAgYm9vbCBFeHBsb3JlQnVuZGxlID0gZmFsc2UpIGNvbnN0OworCisgIC8vLyBcYnJpZWYgQXBwbGllcyB0aGUgY29uc3RyYWludHMgKGRlZi91c2UpIGltcGxpZWQgYnkgdGhlIFxwIE9wSWR4IG9wZXJhbmQKKyAgLy8vIHRvIHRoZSBnaXZlbiBccCBDdXJSQy4KKyAgLy8vCisgIC8vLyBSZXR1cm5zIHRoZSByZWdpc3RlciBjbGFzcyB0aGF0IHNhdGlzZmllcyBib3RoIFxwIEN1clJDIGFuZCB0aGUKKyAgLy8vIGNvbnN0cmFpbnRzIHNldCBieSBccCBPcElkeCBNSS4gUmV0dXJucyBOVUxMIGlmIHN1Y2ggYSByZWdpc3RlciBjbGFzcworICAvLy8gZG9lcyBub3QgZXhpc3QuCisgIC8vLworICAvLy8gXHByZSBDdXJSQyBtdXN0IG5vdCBiZSBOVUxMLgorICAvLy8gXHByZSBUaGUgb3BlcmFuZCBhdCBccCBPcElkeCBtdXN0IGJlIGEgcmVnaXN0ZXIuCisgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKgorICBnZXRSZWdDbGFzc0NvbnN0cmFpbnRFZmZlY3QodW5zaWduZWQgT3BJZHgsIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKkN1clJDLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICpUSUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSkgY29uc3Q7CisKKyAgLy8vIEFkZCBhIHRpZSBiZXR3ZWVuIHRoZSByZWdpc3RlciBvcGVyYW5kcyBhdCBEZWZJZHggYW5kIFVzZUlkeC4KKyAgLy8vIFRoZSB0aWUgd2lsbCBjYXVzZSB0aGUgcmVnaXN0ZXIgYWxsb2NhdG9yIHRvIGVuc3VyZSB0aGF0IHRoZSB0d28KKyAgLy8vIG9wZXJhbmRzIGFyZSBhc3NpZ25lZCB0aGUgc2FtZSBwaHlzaWNhbCByZWdpc3Rlci4KKyAgLy8vCisgIC8vLyBUaWVkIG9wZXJhbmRzIGFyZSBtYW5hZ2VkIGF1dG9tYXRpY2FsbHkgZm9yIGV4cGxpY2l0IG9wZXJhbmRzIGluIHRoZQorICAvLy8gTUNJbnN0ckRlc2MuIFRoaXMgbWV0aG9kIGlzIGZvciBleGNlcHRpb25hbCBjYXNlcyBsaWtlIGlubGluZSBhc20uCisgIHZvaWQgdGllT3BlcmFuZHModW5zaWduZWQgRGVmSWR4LCB1bnNpZ25lZCBVc2VJZHgpOworCisgIC8vLyBHaXZlbiB0aGUgaW5kZXggb2YgYSB0aWVkIHJlZ2lzdGVyIG9wZXJhbmQsIGZpbmQgdGhlCisgIC8vLyBvcGVyYW5kIGl0IGlzIHRpZWQgdG8uIERlZnMgYXJlIHRpZWQgdG8gdXNlcyBhbmQgdmljZSB2ZXJzYS4gUmV0dXJucyB0aGUKKyAgLy8vIGluZGV4IG9mIHRoZSB0aWVkIG9wZXJhbmQgd2hpY2ggbXVzdCBleGlzdC4KKyAgdW5zaWduZWQgZmluZFRpZWRPcGVyYW5kSWR4KHVuc2lnbmVkIE9wSWR4KSBjb25zdDsKKworICAvLy8gR2l2ZW4gdGhlIGluZGV4IG9mIGEgcmVnaXN0ZXIgZGVmIG9wZXJhbmQsCisgIC8vLyBjaGVjayBpZiB0aGUgcmVnaXN0ZXIgZGVmIGlzIHRpZWQgdG8gYSBzb3VyY2Ugb3BlcmFuZCwgZHVlIHRvIGVpdGhlcgorICAvLy8gdHdvLWFkZHJlc3MgZWxpbWluYXRpb24gb3IgaW5saW5lIGFzc2VtYmx5IGNvbnN0cmFpbnRzLiBSZXR1cm5zIHRoZQorICAvLy8gZmlyc3QgdGllZCB1c2Ugb3BlcmFuZCBpbmRleCBieSByZWZlcmVuY2UgaWYgVXNlT3BJZHggaXMgbm90IG51bGwuCisgIGJvb2wgaXNSZWdUaWVkVG9Vc2VPcGVyYW5kKHVuc2lnbmVkIERlZk9wSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCAqVXNlT3BJZHggPSBudWxscHRyKSBjb25zdCB7CisgICAgY29uc3QgTWFjaGluZU9wZXJhbmQgJk1PID0gZ2V0T3BlcmFuZChEZWZPcElkeCk7CisgICAgaWYgKCFNTy5pc1JlZygpIHx8ICFNTy5pc0RlZigpIHx8ICFNTy5pc1RpZWQoKSkKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICBpZiAoVXNlT3BJZHgpCisgICAgICAqVXNlT3BJZHggPSBmaW5kVGllZE9wZXJhbmRJZHgoRGVmT3BJZHgpOworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSB1c2Ugb3BlcmFuZCBvZiB0aGUgc3BlY2lmaWVkIGluZGV4IGlzIHRpZWQgdG8gYSBkZWYKKyAgLy8vIG9wZXJhbmQuIEl0IGFsc28gcmV0dXJucyB0aGUgZGVmIG9wZXJhbmQgaW5kZXggYnkgcmVmZXJlbmNlIGlmIERlZk9wSWR4CisgIC8vLyBpcyBub3QgbnVsbC4KKyAgYm9vbCBpc1JlZ1RpZWRUb0RlZk9wZXJhbmQodW5zaWduZWQgVXNlT3BJZHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkICpEZWZPcElkeCA9IG51bGxwdHIpIGNvbnN0IHsKKyAgICBjb25zdCBNYWNoaW5lT3BlcmFuZCAmTU8gPSBnZXRPcGVyYW5kKFVzZU9wSWR4KTsKKyAgICBpZiAoIU1PLmlzUmVnKCkgfHwgIU1PLmlzVXNlKCkgfHwgIU1PLmlzVGllZCgpKQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIGlmIChEZWZPcElkeCkKKyAgICAgICpEZWZPcElkeCA9IGZpbmRUaWVkT3BlcmFuZElkeChVc2VPcElkeCk7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLy8gQ2xlYXJzIGtpbGwgZmxhZ3Mgb24gYWxsIG9wZXJhbmRzLgorICB2b2lkIGNsZWFyS2lsbEluZm8oKTsKKworICAvLy8gUmVwbGFjZSBhbGwgb2NjdXJyZW5jZXMgb2YgRnJvbVJlZyB3aXRoIFRvUmVnOlN1YklkeCwKKyAgLy8vIHByb3Blcmx5IGNvbXBvc2luZyBzdWJyZWcgaW5kaWNlcyB3aGVyZSBuZWNlc3NhcnkuCisgIHZvaWQgc3Vic3RpdHV0ZVJlZ2lzdGVyKHVuc2lnbmVkIEZyb21SZWcsIHVuc2lnbmVkIFRvUmVnLCB1bnNpZ25lZCBTdWJJZHgsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAmUmVnSW5mbyk7CisKKyAgLy8vIFdlIGhhdmUgZGV0ZXJtaW5lZCBNSSBraWxscyBhIHJlZ2lzdGVyLiBMb29rIGZvciB0aGUKKyAgLy8vIG9wZXJhbmQgdGhhdCB1c2VzIGl0IGFuZCBtYXJrIGl0IGFzIElzS2lsbC4gSWYgQWRkSWZOb3RGb3VuZCBpcyB0cnVlLAorICAvLy8gYWRkIGEgaW1wbGljaXQgb3BlcmFuZCBpZiBpdCdzIG5vdCBmb3VuZC4gUmV0dXJucyB0cnVlIGlmIHRoZSBvcGVyYW5kCisgIC8vLyBleGlzdHMgLyBpcyBhZGRlZC4KKyAgYm9vbCBhZGRSZWdpc3RlcktpbGxlZCh1bnNpZ25lZCBJbmNvbWluZ1JlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlJlZ0luZm8sCisgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBBZGRJZk5vdEZvdW5kID0gZmFsc2UpOworCisgIC8vLyBDbGVhciBhbGwga2lsbCBmbGFncyBhZmZlY3RpbmcgUmVnLiAgSWYgUmVnSW5mbyBpcyBwcm92aWRlZCwgdGhpcyBpbmNsdWRlcworICAvLy8gYWxsIGFsaWFzaW5nIHJlZ2lzdGVycy4KKyAgdm9pZCBjbGVhclJlZ2lzdGVyS2lsbHModW5zaWduZWQgUmVnLCBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlJlZ0luZm8pOworCisgIC8vLyBXZSBoYXZlIGRldGVybWluZWQgTUkgZGVmaW5lZCBhIHJlZ2lzdGVyIHdpdGhvdXQgYSB1c2UuCisgIC8vLyBMb29rIGZvciB0aGUgb3BlcmFuZCB0aGF0IGRlZmluZXMgaXQgYW5kIG1hcmsgaXQgYXMgSXNEZWFkLiBJZgorICAvLy8gQWRkSWZOb3RGb3VuZCBpcyB0cnVlLCBhZGQgYSBpbXBsaWNpdCBvcGVyYW5kIGlmIGl0J3Mgbm90IGZvdW5kLiBSZXR1cm5zCisgIC8vLyB0cnVlIGlmIHRoZSBvcGVyYW5kIGV4aXN0cyAvIGlzIGFkZGVkLgorICBib29sIGFkZFJlZ2lzdGVyRGVhZCh1bnNpZ25lZCBSZWcsIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqUmVnSW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBBZGRJZk5vdEZvdW5kID0gZmFsc2UpOworCisgIC8vLyBDbGVhciBhbGwgZGVhZCBmbGFncyBvbiBvcGVyYW5kcyBkZWZpbmluZyByZWdpc3RlciBAcCBSZWcuCisgIHZvaWQgY2xlYXJSZWdpc3RlckRlYWRzKHVuc2lnbmVkIFJlZyk7CisKKyAgLy8vIE1hcmsgYWxsIHN1YnJlZ2lzdGVyIGRlZnMgb2YgcmVnaXN0ZXIgQHAgUmVnIHdpdGggdGhlIHVuZGVmIGZsYWcuCisgIC8vLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgd2hlbiB3ZSBkZXRlcm1pbmVkIHRvIGhhdmUgYSBzdWJyZWdpc3RlciBkZWYgaW4gYW4KKyAgLy8vIG90aGVyd2lzZSB1bmRlZmluZWQgc3VwZXIgcmVnaXN0ZXIuCisgIHZvaWQgc2V0UmVnaXN0ZXJEZWZSZWFkVW5kZWYodW5zaWduZWQgUmVnLCBib29sIElzVW5kZWYgPSB0cnVlKTsKKworICAvLy8gV2UgaGF2ZSBkZXRlcm1pbmVkIE1JIGRlZmluZXMgYSByZWdpc3Rlci4gTWFrZSBzdXJlIHRoZXJlIGlzIGFuIG9wZXJhbmQKKyAgLy8vIGRlZmluaW5nIFJlZy4KKyAgdm9pZCBhZGRSZWdpc3RlckRlZmluZWQodW5zaWduZWQgUmVnLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlJlZ0luZm8gPSBudWxscHRyKTsKKworICAvLy8gTWFyayBldmVyeSBwaHlzcmVnIHVzZWQgYnkgdGhpcyBpbnN0cnVjdGlvbiBhcworICAvLy8gZGVhZCBleGNlcHQgdGhvc2UgaW4gdGhlIFVzZWRSZWdzIGxpc3QuCisgIC8vLworICAvLy8gT24gaW5zdHJ1Y3Rpb25zIHdpdGggcmVnaXN0ZXIgbWFzayBvcGVyYW5kcywgYWxzbyBhZGQgaW1wbGljaXQtZGVmCisgIC8vLyBvcGVyYW5kcyBmb3IgYWxsIHJlZ2lzdGVycyBpbiBVc2VkUmVncy4KKyAgdm9pZCBzZXRQaHlzUmVnc0RlYWRFeGNlcHQoQXJyYXlSZWY8dW5zaWduZWQ+IFVzZWRSZWdzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gJlRSSSk7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGl0IGlzIHNhZmUgdG8gbW92ZSB0aGlzIGluc3RydWN0aW9uLiBJZgorICAvLy8gU2F3U3RvcmUgaXMgc2V0IHRvIHRydWUsIGl0IG1lYW5zIHRoYXQgdGhlcmUgaXMgYSBzdG9yZSAob3IgY2FsbCkgYmV0d2VlbgorICAvLy8gdGhlIGluc3RydWN0aW9uJ3MgbG9jYXRpb24gYW5kIGl0cyBpbnRlbmRlZCBkZXN0aW5hdGlvbi4KKyAgYm9vbCBpc1NhZmVUb01vdmUoQWxpYXNBbmFseXNpcyAqQUEsIGJvb2wgJlNhd1N0b3JlKSBjb25zdDsKKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24ncyBtZW1vcnkgYWNjZXNzIGFsaWFzZXMgdGhlIG1lbW9yeQorICAvLy8gYWNjZXNzIG9mIE90aGVyLgorICAvLworICAvLy8gQXNzdW1lcyBhbnkgcGh5c2ljYWwgcmVnaXN0ZXJzIHVzZWQgdG8gY29tcHV0ZSBhZGRyZXNzZXMKKyAgLy8vIGhhdmUgdGhlIHNhbWUgdmFsdWUgZm9yIGJvdGggaW5zdHJ1Y3Rpb25zLiAgUmV0dXJucyBmYWxzZSBpZiBuZWl0aGVyCisgIC8vLyBpbnN0cnVjdGlvbiB3cml0ZXMgdG8gbWVtb3J5LgorICAvLy8KKyAgLy8vIEBwYXJhbSBBQSBPcHRpb25hbCBhbGlhcyBhbmFseXNpcywgdXNlZCB0byBjb21wYXJlIG1lbW9yeSBvcGVyYW5kcy4KKyAgLy8vIEBwYXJhbSBPdGhlciBNYWNoaW5lSW5zdHIgdG8gY2hlY2sgYWxpYXNpbmcgYWdhaW5zdC4KKyAgLy8vIEBwYXJhbSBVc2VUQkFBIFdoZXRoZXIgdG8gcGFzcyBUQkFBIGluZm9ybWF0aW9uIHRvIGFsaWFzIGFuYWx5c2lzLgorICBib29sIG1heUFsaWFzKEFsaWFzQW5hbHlzaXMgKkFBLCBNYWNoaW5lSW5zdHIgJk90aGVyLCBib29sIFVzZVRCQUEpOworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGluc3RydWN0aW9uIG1heSBoYXZlIGFuIG9yZGVyZWQKKyAgLy8vIG9yIHZvbGF0aWxlIG1lbW9yeSByZWZlcmVuY2UsIG9yIGlmIHRoZSBpbmZvcm1hdGlvbiBkZXNjcmliaW5nIHRoZSBtZW1vcnkKKyAgLy8vIHJlZmVyZW5jZSBpcyBub3QgYXZhaWxhYmxlLiBSZXR1cm4gZmFsc2UgaWYgaXQgaXMga25vd24gdG8gaGF2ZSBubworICAvLy8gb3JkZXJlZCBvciB2b2xhdGlsZSBtZW1vcnkgcmVmZXJlbmNlcy4KKyAgYm9vbCBoYXNPcmRlcmVkTWVtb3J5UmVmKCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgbG9hZCBpbnN0cnVjdGlvbiBuZXZlciB0cmFwcyBhbmQgcG9pbnRzIHRvIGEgbWVtb3J5CisgIC8vLyBsb2NhdGlvbiB3aG9zZSB2YWx1ZSBkb2Vzbid0IGNoYW5nZSBkdXJpbmcgdGhlIGV4ZWN1dGlvbiBvZiB0aGlzIGZ1bmN0aW9uLgorICAvLy8KKyAgLy8vIEV4YW1wbGVzIGluY2x1ZGUgbG9hZGluZyBhIHZhbHVlIGZyb20gdGhlIGNvbnN0YW50IHBvb2wgb3IgZnJvbSB0aGUKKyAgLy8vIGFyZ3VtZW50IGFyZWEgb2YgYSBmdW5jdGlvbiAoaWYgaXQgZG9lcyBub3QgY2hhbmdlKS4gIElmIHRoZSBpbnN0cnVjdGlvbgorICAvLy8gZG9lcyBtdWx0aXBsZSBsb2FkcywgdGhpcyByZXR1cm5zIHRydWUgb25seSBpZiBhbGwgb2YgdGhlIGxvYWRzIGFyZQorICAvLy8gZGVyZWZlcmVuY2VhYmxlIGFuZCBpbnZhcmlhbnQuCisgIGJvb2wgaXNEZXJlZmVyZW5jZWFibGVJbnZhcmlhbnRMb2FkKEFsaWFzQW5hbHlzaXMgKkFBKSBjb25zdDsKKworICAvLy8gSWYgdGhlIHNwZWNpZmllZCBpbnN0cnVjdGlvbiBpcyBhIFBISSB0aGF0IGFsd2F5cyBtZXJnZXMgdG9nZXRoZXIgdGhlCisgIC8vLyBzYW1lIHZpcnR1YWwgcmVnaXN0ZXIsIHJldHVybiB0aGUgcmVnaXN0ZXIsIG90aGVyd2lzZSByZXR1cm4gMC4KKyAgdW5zaWduZWQgaXNDb25zdGFudFZhbHVlUEhJKCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaW5zdHJ1Y3Rpb24gaGFzIHNpZGUgZWZmZWN0cyB0aGF0IGFyZSBub3QgbW9kZWxlZAorICAvLy8gYnkgbWF5TG9hZCAvIG1heVN0b3JlLCBldGMuCisgIC8vLyBGb3IgYWxsIGluc3RydWN0aW9ucywgdGhlIHByb3BlcnR5IGlzIGVuY29kZWQgaW4gTUNJbnN0ckRlc2M6OkZsYWdzCisgIC8vLyAoc2VlIE1DSW5zdHJEZXNjOjpoYXNVbm1vZGVsZWRTaWRlRWZmZWN0cygpLiBUaGUgb25seSBleGNlcHRpb24gaXMKKyAgLy8vIElOTElORUFTTSBpbnN0cnVjdGlvbiwgaW4gd2hpY2ggY2FzZSB0aGUgc2lkZSBlZmZlY3QgcHJvcGVydHkgaXMgZW5jb2RlZAorICAvLy8gaW4gb25lIG9mIGl0cyBvcGVyYW5kcyAoc2VlIElubGluZUFzbTo6RXh0cmFfSGFzU2lkZUVmZmVjdCkuCisgIC8vLworICBib29sIGhhc1VubW9kZWxlZFNpZGVFZmZlY3RzKCkgY29uc3Q7CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiBpdCBpcyBpbGxlZ2FsIHRvIGZvbGQgYSBsb2FkIGFjcm9zcyB0aGlzIGluc3RydWN0aW9uLgorICBib29sIGlzTG9hZEZvbGRCYXJyaWVyKCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGFsbCB0aGUgZGVmcyBvZiB0aGlzIGluc3RydWN0aW9uIGFyZSBkZWFkLgorICBib29sIGFsbERlZnNBcmVEZWFkKCkgY29uc3Q7CisKKyAgLy8vIENvcHkgaW1wbGljaXQgcmVnaXN0ZXIgb3BlcmFuZHMgZnJvbSBzcGVjaWZpZWQKKyAgLy8vIGluc3RydWN0aW9uIHRvIHRoaXMgaW5zdHJ1Y3Rpb24uCisgIHZvaWQgY29weUltcGxpY2l0T3BzKE1hY2hpbmVGdW5jdGlvbiAmTUYsIGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpOworCisgIC8vLyBEZWJ1Z2dpbmcgc3VwcG9ydAorICAvLy8gQHsKKyAgLy8vIERldGVybWluZSB0aGUgZ2VuZXJpYyB0eXBlIHRvIGJlIHByaW50ZWQgKGlmIG5lZWRlZCkgb24gdXNlcyBhbmQgZGVmcy4KKyAgTExUIGdldFR5cGVUb1ByaW50KHVuc2lnbmVkIE9wSWR4LCBTbWFsbEJpdFZlY3RvciAmUHJpbnRlZFR5cGVzLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgd2hlbiBhbiBpbnN0cnVjdGlvbiBoYXMgdGllZCByZWdpc3RlciB0aGF0IGNhbid0IGJlIGRldGVybWluZWQKKyAgLy8vIGJ5IHRoZSBpbnN0cnVjdGlvbidzIGRlc2NyaXB0b3IuIFRoaXMgaXMgdXNlZnVsIGZvciBNSVIgcHJpbnRpbmcsIHRvCisgIC8vLyBkZXRlcm1pbmUgd2hldGhlciB3ZSBuZWVkIHRvIHByaW50IHRoZSB0aWVzIG9yIG5vdC4KKyAgYm9vbCBoYXNDb21wbGV4UmVnaXN0ZXJUaWVzKCkgY29uc3Q7CisKKyAgLy8vIFByaW50IHRoaXMgTUkgdG8gXHAgT1MuCisgIC8vLyBEb24ndCBwcmludCBpbmZvcm1hdGlvbiB0aGF0IGNhbiBiZSBpbmZlcnJlZCBmcm9tIG90aGVyIGluc3RydWN0aW9ucyBpZgorICAvLy8gXHAgSXNTdGFuZGFsb25lIGlzIGZhbHNlLiBJdCBpcyB1c3VhbGx5IHRydWUgd2hlbiBvbmx5IGEgZnJhZ21lbnQgb2YgdGhlCisgIC8vLyBmdW5jdGlvbiBpcyBwcmludGVkLgorICAvLy8gT25seSBwcmludCB0aGUgZGVmcyBhbmQgdGhlIG9wY29kZSBpZiBccCBTa2lwT3BlcnMgaXMgdHJ1ZS4KKyAgLy8vIE90aGVyd2lzZSwgYWxzbyBwcmludCBvcGVyYW5kcyBpZiBccCBTa2lwRGVidWdMb2MgaXMgdHJ1ZS4KKyAgLy8vIE90aGVyd2lzZSwgYWxzbyBwcmludCB0aGUgZGVidWcgbG9jLCB3aXRoIGEgdGVybWluYXRpbmcgbmV3bGluZS4KKyAgLy8vIFxwIFRJSSBpcyB1c2VkIHRvIHByaW50IHRoZSBvcGNvZGUgbmFtZS4gIElmIGl0J3Mgbm90IHByZXNlbnQsIGJ1dCB0aGUKKyAgLy8vIE1JIGlzIGluIGEgZnVuY3Rpb24sIHRoZSBvcGNvZGUgd2lsbCBiZSBwcmludGVkIHVzaW5nIHRoZSBmdW5jdGlvbidzIFRJSS4KKyAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MsIGJvb2wgSXNTdGFuZGFsb25lID0gdHJ1ZSwgYm9vbCBTa2lwT3BlcnMgPSBmYWxzZSwKKyAgICAgICAgICAgICBib29sIFNraXBEZWJ1Z0xvYyA9IGZhbHNlLAorICAgICAgICAgICAgIGNvbnN0IFRhcmdldEluc3RySW5mbyAqVElJID0gbnVsbHB0cikgY29uc3Q7CisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk9TLCBNb2R1bGVTbG90VHJhY2tlciAmTVNULCBib29sIElzU3RhbmRhbG9uZSA9IHRydWUsCisgICAgICAgICAgICAgYm9vbCBTa2lwT3BlcnMgPSBmYWxzZSwgYm9vbCBTa2lwRGVidWdMb2MgPSBmYWxzZSwKKyAgICAgICAgICAgICBjb25zdCBUYXJnZXRJbnN0ckluZm8gKlRJSSA9IG51bGxwdHIpIGNvbnN0OworICB2b2lkIGR1bXAoKSBjb25zdDsKKyAgLy8vIEB9CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIEFjY2Vzc29ycyB1c2VkIHRvIGJ1aWxkIHVwIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zLgorCisgIC8vLyBBZGQgdGhlIHNwZWNpZmllZCBvcGVyYW5kIHRvIHRoZSBpbnN0cnVjdGlvbi4gIElmIGl0IGlzIGFuIGltcGxpY2l0CisgIC8vLyBvcGVyYW5kLCBpdCBpcyBhZGRlZCB0byB0aGUgZW5kIG9mIHRoZSBvcGVyYW5kIGxpc3QuICBJZiBpdCBpcyBhbgorICAvLy8gZXhwbGljaXQgb3BlcmFuZCBpdCBpcyBhZGRlZCBhdCB0aGUgZW5kIG9mIHRoZSBleHBsaWNpdCBvcGVyYW5kIGxpc3QKKyAgLy8vIChiZWZvcmUgdGhlIGZpcnN0IGltcGxpY2l0IG9wZXJhbmQpLgorICAvLy8KKyAgLy8vIE1GIG11c3QgYmUgdGhlIG1hY2hpbmUgZnVuY3Rpb24gdGhhdCB3YXMgdXNlZCB0byBhbGxvY2F0ZSB0aGlzCisgIC8vLyBpbnN0cnVjdGlvbi4KKyAgLy8vCisgIC8vLyBNYWNoaW5lSW5zdHJCdWlsZGVyIHByb3ZpZGVzIGEgbW9yZSBjb252ZW5pZW50IGludGVyZmFjZSBmb3IgY3JlYXRpbmcKKyAgLy8vIGluc3RydWN0aW9ucyBhbmQgYWRkaW5nIG9wZXJhbmRzLgorICB2b2lkIGFkZE9wZXJhbmQoTWFjaGluZUZ1bmN0aW9uICZNRiwgY29uc3QgTWFjaGluZU9wZXJhbmQgJk9wKTsKKworICAvLy8gQWRkIGFuIG9wZXJhbmQgd2l0aG91dCBwcm92aWRpbmcgYW4gTUYgcmVmZXJlbmNlLiBUaGlzIG9ubHkgd29ya3MgZm9yCisgIC8vLyBpbnN0cnVjdGlvbnMgdGhhdCBhcmUgaW5zZXJ0ZWQgaW4gYSBiYXNpYyBibG9jay4KKyAgLy8vCisgIC8vLyBNYWNoaW5lSW5zdHJCdWlsZGVyIGFuZCB0aGUgdHdvLWFyZ3VtZW50IGFkZE9wZXJhbmQoTUYsIE1PKSBzaG91bGQgYmUKKyAgLy8vIHByZWZlcnJlZC4KKyAgdm9pZCBhZGRPcGVyYW5kKGNvbnN0IE1hY2hpbmVPcGVyYW5kICZPcCk7CisKKyAgLy8vIFJlcGxhY2UgdGhlIGluc3RydWN0aW9uIGRlc2NyaXB0b3IgKHRodXMgb3Bjb2RlKSBvZgorICAvLy8gdGhlIGN1cnJlbnQgaW5zdHJ1Y3Rpb24gd2l0aCBhIG5ldyBvbmUuCisgIHZvaWQgc2V0RGVzYyhjb25zdCBNQ0luc3RyRGVzYyAmdGlkKSB7IE1DSUQgPSAmdGlkOyB9CisKKyAgLy8vIFJlcGxhY2UgY3VycmVudCBzb3VyY2UgaW5mb3JtYXRpb24gd2l0aCBuZXcgc3VjaC4KKyAgLy8vIEF2b2lkIHVzaW5nIHRoaXMsIHRoZSBjb25zdHJ1Y3RvciBhcmd1bWVudCBpcyBwcmVmZXJhYmxlLgorICB2b2lkIHNldERlYnVnTG9jKERlYnVnTG9jIGRsKSB7CisgICAgZGVidWdMb2MgPSBzdGQ6Om1vdmUoZGwpOworICAgIGFzc2VydChkZWJ1Z0xvYy5oYXNUcml2aWFsRGVzdHJ1Y3RvcigpICYmICJFeHBlY3RlZCB0cml2aWFsIGRlc3RydWN0b3IiKTsKKyAgfQorCisgIC8vLyBFcmFzZSBhbiBvcGVyYW5kIGZyb20gYW4gaW5zdHJ1Y3Rpb24sIGxlYXZpbmcgaXQgd2l0aCBvbmUKKyAgLy8vIGZld2VyIG9wZXJhbmQgdGhhbiBpdCBzdGFydGVkIHdpdGguCisgIHZvaWQgUmVtb3ZlT3BlcmFuZCh1bnNpZ25lZCBpKTsKKworICAvLy8gQWRkIGEgTWFjaGluZU1lbU9wZXJhbmQgdG8gdGhlIG1hY2hpbmUgaW5zdHJ1Y3Rpb24uCisgIC8vLyBUaGlzIGZ1bmN0aW9uIHNob3VsZCBiZSB1c2VkIG9ubHkgb2NjYXNpb25hbGx5LiBUaGUgc2V0TWVtUmVmcyBmdW5jdGlvbgorICAvLy8gaXMgdGhlIHByaW1hcnkgbWV0aG9kIGZvciBzZXR0aW5nIHVwIGEgTWFjaGluZUluc3RyJ3MgTWVtUmVmcyBsaXN0LgorICB2b2lkIGFkZE1lbU9wZXJhbmQoTWFjaGluZUZ1bmN0aW9uICZNRiwgTWFjaGluZU1lbU9wZXJhbmQgKk1PKTsKKworICAvLy8gQXNzaWduIHRoaXMgTWFjaGluZUluc3RyJ3MgbWVtb3J5IHJlZmVyZW5jZSBkZXNjcmlwdG9yIGxpc3QuCisgIC8vLyBUaGlzIGRvZXMgbm90IHRyYW5zZmVyIG93bmVyc2hpcC4KKyAgdm9pZCBzZXRNZW1SZWZzKG1tb19pdGVyYXRvciBOZXdNZW1SZWZzLCBtbW9faXRlcmF0b3IgTmV3TWVtUmVmc0VuZCkgeworICAgIHNldE1lbVJlZnMoc3RkOjptYWtlX3BhaXIoTmV3TWVtUmVmcywgTmV3TWVtUmVmc0VuZC1OZXdNZW1SZWZzKSk7CisgIH0KKworICAvLy8gQXNzaWduIHRoaXMgTWFjaGluZUluc3RyJ3MgbWVtb3J5IHJlZmVyZW5jZSBkZXNjcmlwdG9yIGxpc3QuICBGaXJzdAorICAvLy8gZWxlbWVudCBpbiB0aGUgcGFpciBpcyB0aGUgYmVnaW4gaXRlcmF0b3IvcG9pbnRlciB0byB0aGUgYXJyYXk7IHRoZQorICAvLy8gc2Vjb25kIGlzIHRoZSBudW1iZXIgb2YgTWVtb3J5T3BlcmFuZHMuICBUaGlzIGRvZXMgbm90IHRyYW5zZmVyIG93bmVyc2hpcAorICAvLy8gb2YgdGhlIHVuZGVybHlpbmcgbWVtb3J5LgorICB2b2lkIHNldE1lbVJlZnMoc3RkOjpwYWlyPG1tb19pdGVyYXRvciwgdW5zaWduZWQ+IE5ld01lbVJlZnMpIHsKKyAgICBNZW1SZWZzID0gTmV3TWVtUmVmcy5maXJzdDsKKyAgICBOdW1NZW1SZWZzID0gdWludDhfdChOZXdNZW1SZWZzLnNlY29uZCk7CisgICAgYXNzZXJ0KE51bU1lbVJlZnMgPT0gTmV3TWVtUmVmcy5zZWNvbmQgJiYKKyAgICAgICAgICAgIlRvbyBtYW55IG1lbXJlZnMgLSBtdXN0IGRyb3AgbWVtb3J5IG9wZXJhbmRzIik7CisgIH0KKworICAvLy8gUmV0dXJuIGEgc2V0IG9mIG1lbXJlZnMgKGJlZ2luIGl0ZXJhdG9yLCBzaXplKSB3aGljaCBjb25zZXJ2YXRpdmVseQorICAvLy8gZGVzY3JpYmUgdGhlIG1lbW9yeSBiZWhhdmlvciBvZiBib3RoIE1hY2hpbmVJbnN0cnMuICBUaGlzIGlzIGFwcHJvcHJpYXRlCisgIC8vLyBmb3IgdXNlIHdoZW4gbWVyZ2luZyB0d28gTWFjaGluZUluc3RycyBpbnRvIG9uZS4gVGhpcyByb3V0aW5lIGRvZXMgbm90CisgIC8vLyBtb2RpZnkgdGhlIG1lbXJlZnMgb2YgdGhlIHRoaXMgTWFjaGluZUluc3RyLgorICBzdGQ6OnBhaXI8bW1vX2l0ZXJhdG9yLCB1bnNpZ25lZD4gbWVyZ2VNZW1SZWZzV2l0aChjb25zdCBNYWNoaW5lSW5zdHImIE90aGVyKTsKKworICAvLy8gUmV0dXJuIHRoZSBNSUZsYWdzIHdoaWNoIHJlcHJlc2VudCBib3RoIE1hY2hpbmVJbnN0cnMuIFRoaXMKKyAgLy8vIHNob3VsZCBiZSB1c2VkIHdoZW4gbWVyZ2luZyB0d28gTWFjaGluZUluc3RycyBpbnRvIG9uZS4gVGhpcyByb3V0aW5lIGRvZXMKKyAgLy8vIG5vdCBtb2RpZnkgdGhlIE1JRmxhZ3Mgb2YgdGhpcyBNYWNoaW5lSW5zdHIuCisgIHVpbnQ4X3QgbWVyZ2VGbGFnc1dpdGgoY29uc3QgTWFjaGluZUluc3RyJiBPdGhlcikgY29uc3Q7CisKKyAgLy8vIENsZWFyIHRoaXMgTWFjaGluZUluc3RyJ3MgbWVtb3J5IHJlZmVyZW5jZSBkZXNjcmlwdG9yIGxpc3QuICBUaGlzIHJlc2V0cworICAvLy8gdGhlIG1lbXJlZnMgdG8gdGhlaXIgbW9zdCBjb25zZXJ2YXRpdmUgc3RhdGUuICBUaGlzIHNob3VsZCBiZSB1c2VkIG9ubHkKKyAgLy8vIGFzIGEgbGFzdCByZXNvcnQgc2luY2UgaXQgZ3JlYXRseSBwZXNzaW1pemVzIG91ciBrbm93bGVkZ2Ugb2YgdGhlIG1lbW9yeQorICAvLy8gYWNjZXNzIHBlcmZvcm1lZCBieSB0aGUgaW5zdHJ1Y3Rpb24uCisgIHZvaWQgZHJvcE1lbVJlZnMoKSB7CisgICAgTWVtUmVmcyA9IG51bGxwdHI7CisgICAgTnVtTWVtUmVmcyA9IDA7CisgIH0KKworICAvLy8gQnJlYWsgYW55IHRpZSBpbnZvbHZpbmcgT3BJZHguCisgIHZvaWQgdW50aWVSZWdPcGVyYW5kKHVuc2lnbmVkIE9wSWR4KSB7CisgICAgTWFjaGluZU9wZXJhbmQgJk1PID0gZ2V0T3BlcmFuZChPcElkeCk7CisgICAgaWYgKE1PLmlzUmVnKCkgJiYgTU8uaXNUaWVkKCkpIHsKKyAgICAgIGdldE9wZXJhbmQoZmluZFRpZWRPcGVyYW5kSWR4KE9wSWR4KSkuVGllZFRvID0gMDsKKyAgICAgIE1PLlRpZWRUbyA9IDA7CisgICAgfQorICB9CisKKyAgLy8vIEFkZCBhbGwgaW1wbGljaXQgZGVmIGFuZCB1c2Ugb3BlcmFuZHMgdG8gdGhpcyBpbnN0cnVjdGlvbi4KKyAgdm9pZCBhZGRJbXBsaWNpdERlZlVzZU9wZXJhbmRzKE1hY2hpbmVGdW5jdGlvbiAmTUYpOworCitwcml2YXRlOgorICAvLy8gSWYgdGhpcyBpbnN0cnVjdGlvbiBpcyBlbWJlZGRlZCBpbnRvIGEgTWFjaGluZUZ1bmN0aW9uLCByZXR1cm4gdGhlCisgIC8vLyBNYWNoaW5lUmVnaXN0ZXJJbmZvIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgZnVuY3Rpb24sIG90aGVyd2lzZQorICAvLy8gcmV0dXJuIG51bGwuCisgIE1hY2hpbmVSZWdpc3RlckluZm8gKmdldFJlZ0luZm8oKTsKKworICAvLy8gVW5saW5rIGFsbCBvZiB0aGUgcmVnaXN0ZXIgb3BlcmFuZHMgaW4gdGhpcyBpbnN0cnVjdGlvbiBmcm9tIHRoZWlyCisgIC8vLyByZXNwZWN0aXZlIHVzZSBsaXN0cy4gIFRoaXMgcmVxdWlyZXMgdGhhdCB0aGUgb3BlcmFuZHMgYWxyZWFkeSBiZSBvbiB0aGVpcgorICAvLy8gdXNlIGxpc3RzLgorICB2b2lkIFJlbW92ZVJlZ09wZXJhbmRzRnJvbVVzZUxpc3RzKE1hY2hpbmVSZWdpc3RlckluZm8mKTsKKworICAvLy8gQWRkIGFsbCBvZiB0aGUgcmVnaXN0ZXIgb3BlcmFuZHMgaW4gdGhpcyBpbnN0cnVjdGlvbiBmcm9tIHRoZWlyCisgIC8vLyByZXNwZWN0aXZlIHVzZSBsaXN0cy4gIFRoaXMgcmVxdWlyZXMgdGhhdCB0aGUgb3BlcmFuZHMgbm90IGJlIG9uIHRoZWlyCisgIC8vLyB1c2UgbGlzdHMgeWV0LgorICB2b2lkIEFkZFJlZ09wZXJhbmRzVG9Vc2VMaXN0cyhNYWNoaW5lUmVnaXN0ZXJJbmZvJik7CisKKyAgLy8vIFNsb3cgcGF0aCBmb3IgaGFzUHJvcGVydHkgd2hlbiB3ZSdyZSBkZWFsaW5nIHdpdGggYSBidW5kbGUuCisgIGJvb2wgaGFzUHJvcGVydHlJbkJ1bmRsZSh1bnNpZ25lZCBNYXNrLCBRdWVyeVR5cGUgVHlwZSkgY29uc3Q7CisKKyAgLy8vIFxicmllZiBJbXBsZW1lbnRzIHRoZSBsb2dpYyBvZiBnZXRSZWdDbGFzc0NvbnN0cmFpbnRFZmZlY3RGb3JWUmVnIGZvciB0aGUKKyAgLy8vIHRoaXMgTUkgYW5kIHRoZSBnaXZlbiBvcGVyYW5kIGluZGV4IFxwIE9wSWR4LgorICAvLy8gSWYgdGhlIHJlbGF0ZWQgb3BlcmFuZCBkb2VzIG5vdCBjb25zdHJhaW5lZCBSZWcsIHRoaXMgcmV0dXJucyBDdXJSQy4KKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqZ2V0UmVnQ2xhc3NDb25zdHJhaW50RWZmZWN0Rm9yVlJlZ0ltcGwoCisgICAgICB1bnNpZ25lZCBPcElkeCwgdW5zaWduZWQgUmVnLCBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpDdXJSQywKKyAgICAgIGNvbnN0IFRhcmdldEluc3RySW5mbyAqVElJLCBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSkgY29uc3Q7Cit9OworCisvLy8gU3BlY2lhbCBEZW5zZU1hcEluZm8gdHJhaXRzIHRvIGNvbXBhcmUgTWFjaGluZUluc3RyKiBieSAqdmFsdWUqIG9mIHRoZQorLy8vIGluc3RydWN0aW9uIHJhdGhlciB0aGFuIGJ5IHBvaW50ZXIgdmFsdWUuCisvLy8gVGhlIGhhc2hpbmcgYW5kIGVxdWFsaXR5IHRlc3RpbmcgZnVuY3Rpb25zIGlnbm9yZSBkZWZpbml0aW9ucyBzbyB0aGlzIGlzCisvLy8gdXNlZnVsIGZvciBDU0UsIGV0Yy4KK3N0cnVjdCBNYWNoaW5lSW5zdHJFeHByZXNzaW9uVHJhaXQgOiBEZW5zZU1hcEluZm88TWFjaGluZUluc3RyKj4geworICBzdGF0aWMgaW5saW5lIE1hY2hpbmVJbnN0ciAqZ2V0RW1wdHlLZXkoKSB7CisgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKworICBzdGF0aWMgaW5saW5lIE1hY2hpbmVJbnN0ciAqZ2V0VG9tYnN0b25lS2V5KCkgeworICAgIHJldHVybiByZWludGVycHJldF9jYXN0PE1hY2hpbmVJbnN0cio+KC0xKTsKKyAgfQorCisgIHN0YXRpYyB1bnNpZ25lZCBnZXRIYXNoVmFsdWUoY29uc3QgTWFjaGluZUluc3RyKiBjb25zdCAmTUkpOworCisgIHN0YXRpYyBib29sIGlzRXF1YWwoY29uc3QgTWFjaGluZUluc3RyKiBjb25zdCAmTEhTLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ciogY29uc3QgJlJIUykgeworICAgIGlmIChSSFMgPT0gZ2V0RW1wdHlLZXkoKSB8fCBSSFMgPT0gZ2V0VG9tYnN0b25lS2V5KCkgfHwKKyAgICAgICAgTEhTID09IGdldEVtcHR5S2V5KCkgfHwgTEhTID09IGdldFRvbWJzdG9uZUtleSgpKQorICAgICAgcmV0dXJuIExIUyA9PSBSSFM7CisgICAgcmV0dXJuIExIUy0+aXNJZGVudGljYWxUbygqUkhTLCBNYWNoaW5lSW5zdHI6Oklnbm9yZVZSZWdEZWZzKTsKKyAgfQorfTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vIERlYnVnZ2luZyBTdXBwb3J0CisKK2lubGluZSByYXdfb3N0cmVhbSYgb3BlcmF0b3I8PChyYXdfb3N0cmVhbSAmT1MsIGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIHsKKyAgTUkucHJpbnQoT1MpOworICByZXR1cm4gT1M7Cit9CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTUFDSElORUlOU1RSX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lSW5zdHJCdWlsZGVyLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUluc3RyQnVpbGRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJkZjg5YjEKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUluc3RyQnVpbGRlci5oCkBAIC0wLDAgKzEsNTYwIEBACisvLz09PS0gQ29kZUdlbi9NYWNoaW5lSW5zdHJCdWlsZGVyLmggLSBTaW1wbGlmeSBjcmVhdGlvbiBvZiBNSXMgLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgZXhwb3NlcyBhIGZ1bmN0aW9uIG5hbWVkIEJ1aWxkTUksIHdoaWNoIGlzIHVzZWZ1bCBmb3IgZHJhbWF0aWNhbGx5CisvLyBzaW1wbGlmeWluZyBob3cgTWFjaGluZUluc3RyJ3MgYXJlIGNyZWF0ZWQuICBJdCBhbGxvd3MgdXNlIG9mIGNvZGUgbGlrZSB0aGlzOgorLy8KKy8vICAgTSA9IEJ1aWxkTUkoTUJCLCBNSSwgREwsIFRJSS5nZXQoWDg2OjpBREQ4cnIpLCBEc3QpCisvLyAgICAgICAgICAgLmFkZFJlZyhhcmdWYWwxKQorLy8gICAgICAgICAgIC5hZGRSZWcoYXJnVmFsMik7CisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORUlOU1RSQlVJTERFUl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9NQUNISU5FSU5TVFJCVUlMREVSX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0FycmF5UmVmLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0dsb2JhbElTZWwvVXRpbHMuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVJbnN0ci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lSW5zdHJCdW5kbGUuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZU9wZXJhbmQuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0UmVnaXN0ZXJJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9JUi9JbnN0clR5cGVzLmgiCisjaW5jbHVkZSAibGx2bS9JUi9JbnRyaW5zaWNzLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0Vycm9ySGFuZGxpbmcuaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPGNzdGRpbnQ+CisjaW5jbHVkZSA8dXRpbGl0eT4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNQ0luc3RyRGVzYzsKK2NsYXNzIE1ETm9kZTsKKworbmFtZXNwYWNlIFJlZ1N0YXRlIHsKKworICBlbnVtIHsKKyAgICBEZWZpbmUgICAgICAgICA9IDB4MiwKKyAgICBJbXBsaWNpdCAgICAgICA9IDB4NCwKKyAgICBLaWxsICAgICAgICAgICA9IDB4OCwKKyAgICBEZWFkICAgICAgICAgICA9IDB4MTAsCisgICAgVW5kZWYgICAgICAgICAgPSAweDIwLAorICAgIEVhcmx5Q2xvYmJlciAgID0gMHg0MCwKKyAgICBEZWJ1ZyAgICAgICAgICA9IDB4ODAsCisgICAgSW50ZXJuYWxSZWFkICAgPSAweDEwMCwKKyAgICBSZW5hbWFibGUgICAgICA9IDB4MjAwLAorICAgIERlZmluZU5vUmVhZCAgID0gRGVmaW5lIHwgVW5kZWYsCisgICAgSW1wbGljaXREZWZpbmUgPSBJbXBsaWNpdCB8IERlZmluZSwKKyAgICBJbXBsaWNpdEtpbGwgICA9IEltcGxpY2l0IHwgS2lsbAorICB9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgUmVnU3RhdGUKKworY2xhc3MgTWFjaGluZUluc3RyQnVpbGRlciB7CisgIE1hY2hpbmVGdW5jdGlvbiAqTUYgPSBudWxscHRyOworICBNYWNoaW5lSW5zdHIgKk1JID0gbnVsbHB0cjsKKworcHVibGljOgorICBNYWNoaW5lSW5zdHJCdWlsZGVyKCkgPSBkZWZhdWx0OworCisgIC8vLyBDcmVhdGUgYSBNYWNoaW5lSW5zdHJCdWlsZGVyIGZvciBtYW5pcHVsYXRpbmcgYW4gZXhpc3RpbmcgaW5zdHJ1Y3Rpb24uCisgIC8vLyBGIG11c3QgYmUgdGhlIG1hY2hpbmUgZnVuY3Rpb24gdGhhdCB3YXMgdXNlZCB0byBhbGxvY2F0ZSBJLgorICBNYWNoaW5lSW5zdHJCdWlsZGVyKE1hY2hpbmVGdW5jdGlvbiAmRiwgTWFjaGluZUluc3RyICpJKSA6IE1GKCZGKSwgTUkoSSkge30KKyAgTWFjaGluZUluc3RyQnVpbGRlcihNYWNoaW5lRnVuY3Rpb24gJkYsIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBJKQorICAgICAgOiBNRigmRiksIE1JKCYqSSkge30KKworICAvLy8gQWxsb3cgYXV0b21hdGljIGNvbnZlcnNpb24gdG8gdGhlIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gd2UgYXJlIHdvcmtpbmcgb24uCisgIG9wZXJhdG9yIE1hY2hpbmVJbnN0ciooKSBjb25zdCB7IHJldHVybiBNSTsgfQorICBNYWNoaW5lSW5zdHIgKm9wZXJhdG9yLT4oKSBjb25zdCB7IHJldHVybiBNSTsgfQorICBvcGVyYXRvciBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IoKSBjb25zdCB7IHJldHVybiBNSTsgfQorCisgIC8vLyBJZiBjb252ZXJzaW9uIG9wZXJhdG9ycyBmYWlsLCB1c2UgdGhpcyBtZXRob2QgdG8gZ2V0IHRoZSBNYWNoaW5lSW5zdHIKKyAgLy8vIGV4cGxpY2l0bHkuCisgIE1hY2hpbmVJbnN0ciAqZ2V0SW5zdHIoKSBjb25zdCB7IHJldHVybiBNSTsgfQorCisgIC8vLyBBZGQgYSBuZXcgdmlydHVhbCByZWdpc3RlciBvcGVyYW5kLgorICBjb25zdCBNYWNoaW5lSW5zdHJCdWlsZGVyICZhZGRSZWcodW5zaWduZWQgUmVnTm8sIHVuc2lnbmVkIGZsYWdzID0gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFN1YlJlZyA9IDApIGNvbnN0IHsKKyAgICBhc3NlcnQoKGZsYWdzICYgMHgxKSA9PSAwICYmCisgICAgICAgICAgICJQYXNzaW5nIGluICd0cnVlJyB0byBhZGRSZWcgaXMgZm9yYmlkZGVuISBVc2UgZW51bXMgaW5zdGVhZC4iKTsKKyAgICBNSS0+YWRkT3BlcmFuZCgqTUYsIE1hY2hpbmVPcGVyYW5kOjpDcmVhdGVSZWcoUmVnTm8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsYWdzICYgUmVnU3RhdGU6OkRlZmluZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ3MgJiBSZWdTdGF0ZTo6SW1wbGljaXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsYWdzICYgUmVnU3RhdGU6OktpbGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsYWdzICYgUmVnU3RhdGU6OkRlYWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsYWdzICYgUmVnU3RhdGU6OlVuZGVmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGFncyAmIFJlZ1N0YXRlOjpFYXJseUNsb2JiZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN1YlJlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ3MgJiBSZWdTdGF0ZTo6RGVidWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsYWdzICYgUmVnU3RhdGU6OkludGVybmFsUmVhZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ3MgJiBSZWdTdGF0ZTo6UmVuYW1hYmxlKSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgLy8vIEFkZCBhIHZpcnR1YWwgcmVnaXN0ZXIgZGVmaW5pdGlvbiBvcGVyYW5kLgorICBjb25zdCBNYWNoaW5lSW5zdHJCdWlsZGVyICZhZGREZWYodW5zaWduZWQgUmVnTm8sIHVuc2lnbmVkIEZsYWdzID0gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFN1YlJlZyA9IDApIGNvbnN0IHsKKyAgICByZXR1cm4gYWRkUmVnKFJlZ05vLCBGbGFncyB8IFJlZ1N0YXRlOjpEZWZpbmUsIFN1YlJlZyk7CisgIH0KKworICAvLy8gQWRkIGEgdmlydHVhbCByZWdpc3RlciB1c2Ugb3BlcmFuZC4gSXQgaXMgYW4gZXJyb3IgZm9yIEZsYWdzIHRvIGNvbnRhaW4KKyAgLy8vIGBSZWdTdGF0ZTo6RGVmaW5lYCB3aGVuIGNhbGxpbmcgdGhpcyBmdW5jdGlvbi4KKyAgY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmYWRkVXNlKHVuc2lnbmVkIFJlZ05vLCB1bnNpZ25lZCBGbGFncyA9IDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBTdWJSZWcgPSAwKSBjb25zdCB7CisgICAgYXNzZXJ0KCEoRmxhZ3MgJiBSZWdTdGF0ZTo6RGVmaW5lKSAmJgorICAgICAgICAgICAiTWlzbGVhZGluZyBhZGRVc2UgZGVmaW5lcyByZWdpc3RlciwgdXNlIGFkZFJlZyBpbnN0ZWFkLiIpOworICAgIHJldHVybiBhZGRSZWcoUmVnTm8sIEZsYWdzLCBTdWJSZWcpOworICB9CisKKyAgLy8vIEFkZCBhIG5ldyBpbW1lZGlhdGUgb3BlcmFuZC4KKyAgY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmYWRkSW1tKGludDY0X3QgVmFsKSBjb25zdCB7CisgICAgTUktPmFkZE9wZXJhbmQoKk1GLCBNYWNoaW5lT3BlcmFuZDo6Q3JlYXRlSW1tKFZhbCkpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1aWxkZXIgJmFkZENJbW0oY29uc3QgQ29uc3RhbnRJbnQgKlZhbCkgY29uc3QgeworICAgIE1JLT5hZGRPcGVyYW5kKCpNRiwgTWFjaGluZU9wZXJhbmQ6OkNyZWF0ZUNJbW0oVmFsKSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmYWRkRlBJbW0oY29uc3QgQ29uc3RhbnRGUCAqVmFsKSBjb25zdCB7CisgICAgTUktPmFkZE9wZXJhbmQoKk1GLCBNYWNoaW5lT3BlcmFuZDo6Q3JlYXRlRlBJbW0oVmFsKSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmYWRkTUJCKE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFRhcmdldEZsYWdzID0gMCkgY29uc3QgeworICAgIE1JLT5hZGRPcGVyYW5kKCpNRiwgTWFjaGluZU9wZXJhbmQ6OkNyZWF0ZU1CQihNQkIsIFRhcmdldEZsYWdzKSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmYWRkRnJhbWVJbmRleChpbnQgSWR4KSBjb25zdCB7CisgICAgTUktPmFkZE9wZXJhbmQoKk1GLCBNYWNoaW5lT3BlcmFuZDo6Q3JlYXRlRkkoSWR4KSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmYWRkQ29uc3RhbnRQb29sSW5kZXgodW5zaWduZWQgSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgT2Zmc2V0ID0gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKSBjb25zdCB7CisgICAgTUktPmFkZE9wZXJhbmQoKk1GLCBNYWNoaW5lT3BlcmFuZDo6Q3JlYXRlQ1BJKElkeCwgT2Zmc2V0LCBUYXJnZXRGbGFncykpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1aWxkZXIgJmFkZFRhcmdldEluZGV4KHVuc2lnbmVkIElkeCwgaW50NjRfdCBPZmZzZXQgPSAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciBUYXJnZXRGbGFncyA9IDApIGNvbnN0IHsKKyAgICBNSS0+YWRkT3BlcmFuZCgqTUYsIE1hY2hpbmVPcGVyYW5kOjpDcmVhdGVUYXJnZXRJbmRleChJZHgsIE9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUYXJnZXRGbGFncykpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1aWxkZXIgJmFkZEp1bXBUYWJsZUluZGV4KHVuc2lnbmVkIElkeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKSBjb25zdCB7CisgICAgTUktPmFkZE9wZXJhbmQoKk1GLCBNYWNoaW5lT3BlcmFuZDo6Q3JlYXRlSlRJKElkeCwgVGFyZ2V0RmxhZ3MpKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBjb25zdCBNYWNoaW5lSW5zdHJCdWlsZGVyICZhZGRHbG9iYWxBZGRyZXNzKGNvbnN0IEdsb2JhbFZhbHVlICpHViwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NF90IE9mZnNldCA9IDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFRhcmdldEZsYWdzID0gMCkgY29uc3QgeworICAgIE1JLT5hZGRPcGVyYW5kKCpNRiwgTWFjaGluZU9wZXJhbmQ6OkNyZWF0ZUdBKEdWLCBPZmZzZXQsIFRhcmdldEZsYWdzKSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmYWRkRXh0ZXJuYWxTeW1ib2woY29uc3QgY2hhciAqRm5OYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciBUYXJnZXRGbGFncyA9IDApIGNvbnN0IHsKKyAgICBNSS0+YWRkT3BlcmFuZCgqTUYsIE1hY2hpbmVPcGVyYW5kOjpDcmVhdGVFUyhGbk5hbWUsIFRhcmdldEZsYWdzKSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmYWRkQmxvY2tBZGRyZXNzKGNvbnN0IEJsb2NrQWRkcmVzcyAqQkEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NF90IE9mZnNldCA9IDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFRhcmdldEZsYWdzID0gMCkgY29uc3QgeworICAgIE1JLT5hZGRPcGVyYW5kKCpNRiwgTWFjaGluZU9wZXJhbmQ6OkNyZWF0ZUJBKEJBLCBPZmZzZXQsIFRhcmdldEZsYWdzKSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmYWRkUmVnTWFzayhjb25zdCB1aW50MzJfdCAqTWFzaykgY29uc3QgeworICAgIE1JLT5hZGRPcGVyYW5kKCpNRiwgTWFjaGluZU9wZXJhbmQ6OkNyZWF0ZVJlZ01hc2soTWFzaykpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1aWxkZXIgJmFkZE1lbU9wZXJhbmQoTWFjaGluZU1lbU9wZXJhbmQgKk1NTykgY29uc3QgeworICAgIE1JLT5hZGRNZW1PcGVyYW5kKCpNRiwgTU1PKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBjb25zdCBNYWNoaW5lSW5zdHJCdWlsZGVyICZzZXRNZW1SZWZzKE1hY2hpbmVJbnN0cjo6bW1vX2l0ZXJhdG9yIGIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUluc3RyOjptbW9faXRlcmF0b3IgZSkgY29uc3QgeworICAgIE1JLT5zZXRNZW1SZWZzKGIsIGUpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1aWxkZXIgJnNldE1lbVJlZnMoc3RkOjpwYWlyPE1hY2hpbmVJbnN0cjo6bW1vX2l0ZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkPiBNZW1PcGVyYW5kc1JlZikgY29uc3QgeworICAgIE1JLT5zZXRNZW1SZWZzKE1lbU9wZXJhbmRzUmVmKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBjb25zdCBNYWNoaW5lSW5zdHJCdWlsZGVyICZhZGQoY29uc3QgTWFjaGluZU9wZXJhbmQgJk1PKSBjb25zdCB7CisgICAgTUktPmFkZE9wZXJhbmQoKk1GLCBNTyk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmYWRkKEFycmF5UmVmPE1hY2hpbmVPcGVyYW5kPiBNT3MpIGNvbnN0IHsKKyAgICBmb3IgKGNvbnN0IE1hY2hpbmVPcGVyYW5kICZNTyA6IE1PcykgeworICAgICAgTUktPmFkZE9wZXJhbmQoKk1GLCBNTyk7CisgICAgfQorICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1aWxkZXIgJmFkZE1ldGFkYXRhKGNvbnN0IE1ETm9kZSAqTUQpIGNvbnN0IHsKKyAgICBNSS0+YWRkT3BlcmFuZCgqTUYsIE1hY2hpbmVPcGVyYW5kOjpDcmVhdGVNZXRhZGF0YShNRCkpOworICAgIGFzc2VydCgoTUktPmlzRGVidWdWYWx1ZSgpID8gc3RhdGljX2Nhc3Q8Ym9vbD4oTUktPmdldERlYnVnVmFyaWFibGUoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRydWUpICYmCisgICAgICAgICAgICJmaXJzdCBNRE5vZGUgYXJndW1lbnQgb2YgYSBEQkdfVkFMVUUgbm90IGEgdmFyaWFibGUiKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBjb25zdCBNYWNoaW5lSW5zdHJCdWlsZGVyICZhZGRDRklJbmRleCh1bnNpZ25lZCBDRklJbmRleCkgY29uc3QgeworICAgIE1JLT5hZGRPcGVyYW5kKCpNRiwgTWFjaGluZU9wZXJhbmQ6OkNyZWF0ZUNGSUluZGV4KENGSUluZGV4KSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmYWRkSW50cmluc2ljSUQoSW50cmluc2ljOjpJRCBJRCkgY29uc3QgeworICAgIE1JLT5hZGRPcGVyYW5kKCpNRiwgTWFjaGluZU9wZXJhbmQ6OkNyZWF0ZUludHJpbnNpY0lEKElEKSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgY29uc3QgTWFjaGluZUluc3RyQnVpbGRlciAmYWRkUHJlZGljYXRlKENtcEluc3Q6OlByZWRpY2F0ZSBQcmVkKSBjb25zdCB7CisgICAgTUktPmFkZE9wZXJhbmQoKk1GLCBNYWNoaW5lT3BlcmFuZDo6Q3JlYXRlUHJlZGljYXRlKFByZWQpKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBjb25zdCBNYWNoaW5lSW5zdHJCdWlsZGVyICZhZGRTeW0oTUNTeW1ib2wgKlN5bSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKSBjb25zdCB7CisgICAgTUktPmFkZE9wZXJhbmQoKk1GLCBNYWNoaW5lT3BlcmFuZDo6Q3JlYXRlTUNTeW1ib2woU3ltLCBUYXJnZXRGbGFncykpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1aWxkZXIgJnNldE1JRmxhZ3ModW5zaWduZWQgRmxhZ3MpIGNvbnN0IHsKKyAgICBNSS0+c2V0RmxhZ3MoRmxhZ3MpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1aWxkZXIgJnNldE1JRmxhZyhNYWNoaW5lSW5zdHI6Ok1JRmxhZyBGbGFnKSBjb25zdCB7CisgICAgTUktPnNldEZsYWcoRmxhZyk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisKKyAgLy8gQWRkIGEgZGlzcGxhY2VtZW50IGZyb20gYW4gZXhpc3RpbmcgTWFjaGluZU9wZXJhbmQgd2l0aCBhbiBhZGRlZCBvZmZzZXQuCisgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1aWxkZXIgJmFkZERpc3AoY29uc3QgTWFjaGluZU9wZXJhbmQgJkRpc3AsIGludDY0X3Qgb2ZmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKSBjb25zdCB7CisgICAgLy8gSWYgY2FsbGVyIHNwZWNpZmllcyBuZXcgVGFyZ2V0RmxhZ3MgdGhlbiB1c2UgaXQsIG90aGVyd2lzZSB0aGUKKyAgICAvLyBkZWZhdWx0IGJlaGF2aW9yIGlzIHRvIGNvcHkgdGhlIHRhcmdldCBmbGFncyBmcm9tIHRoZSBleGlzdGluZworICAgIC8vIE1hY2hpbmVPcGVyYW5kLiBUaGlzIG1lYW5zIGlmIHRoZSBjYWxsZXIgd2FudHMgdG8gY2xlYXIgdGhlCisgICAgLy8gdGFyZ2V0IGZsYWdzIGl0IG5lZWRzIHRvIGRvIHNvIGV4cGxpY2l0bHkuCisgICAgaWYgKDAgPT0gVGFyZ2V0RmxhZ3MpCisgICAgICBUYXJnZXRGbGFncyA9IERpc3AuZ2V0VGFyZ2V0RmxhZ3MoKTsKKworICAgIHN3aXRjaCAoRGlzcC5nZXRUeXBlKCkpIHsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIGxsdm1fdW5yZWFjaGFibGUoIlVuaGFuZGxlZCBvcGVyYW5kIHR5cGUgaW4gYWRkRGlzcCgpIik7CisgICAgICBjYXNlIE1hY2hpbmVPcGVyYW5kOjpNT19JbW1lZGlhdGU6CisgICAgICAgIHJldHVybiBhZGRJbW0oRGlzcC5nZXRJbW0oKSArIG9mZik7CisgICAgICBjYXNlIE1hY2hpbmVPcGVyYW5kOjpNT19Db25zdGFudFBvb2xJbmRleDoKKyAgICAgICAgcmV0dXJuIGFkZENvbnN0YW50UG9vbEluZGV4KERpc3AuZ2V0SW5kZXgoKSwgRGlzcC5nZXRPZmZzZXQoKSArIG9mZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRhcmdldEZsYWdzKTsKKyAgICAgIGNhc2UgTWFjaGluZU9wZXJhbmQ6Ok1PX0dsb2JhbEFkZHJlc3M6CisgICAgICAgIHJldHVybiBhZGRHbG9iYWxBZGRyZXNzKERpc3AuZ2V0R2xvYmFsKCksIERpc3AuZ2V0T2Zmc2V0KCkgKyBvZmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRhcmdldEZsYWdzKTsKKyAgICB9CisgIH0KKworICAvLy8gQ29weSBhbGwgdGhlIGltcGxpY2l0IG9wZXJhbmRzIGZyb20gT3RoZXJNSSBvbnRvIHRoaXMgb25lLgorICBjb25zdCBNYWNoaW5lSW5zdHJCdWlsZGVyICYKKyAgY29weUltcGxpY2l0T3BzKGNvbnN0IE1hY2hpbmVJbnN0ciAmT3RoZXJNSSkgY29uc3QgeworICAgIE1JLT5jb3B5SW1wbGljaXRPcHMoKk1GLCBPdGhlck1JKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICBib29sIGNvbnN0cmFpbkFsbFVzZXMoY29uc3QgVGFyZ2V0SW5zdHJJbmZvICZUSUksCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gJlRSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJlZ2lzdGVyQmFua0luZm8gJlJCSSkgY29uc3QgeworICAgIHJldHVybiBjb25zdHJhaW5TZWxlY3RlZEluc3RSZWdPcGVyYW5kcygqTUksIFRJSSwgVFJJLCBSQkkpOworICB9Cit9OworCisvLy8gQnVpbGRlciBpbnRlcmZhY2UuIFNwZWNpZnkgaG93IHRvIGNyZWF0ZSB0aGUgaW5pdGlhbCBpbnN0cnVjdGlvbiBpdHNlbGYuCitpbmxpbmUgTWFjaGluZUluc3RyQnVpbGRlciBCdWlsZE1JKE1hY2hpbmVGdW5jdGlvbiAmTUYsIGNvbnN0IERlYnVnTG9jICZETCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTUNJbnN0ckRlc2MgJk1DSUQpIHsKKyAgcmV0dXJuIE1hY2hpbmVJbnN0ckJ1aWxkZXIoTUYsIE1GLkNyZWF0ZU1hY2hpbmVJbnN0cihNQ0lELCBETCkpOworfQorCisvLy8gVGhpcyB2ZXJzaW9uIG9mIHRoZSBidWlsZGVyIHNldHMgdXAgdGhlIGZpcnN0IG9wZXJhbmQgYXMgYQorLy8vIGRlc3RpbmF0aW9uIHZpcnR1YWwgcmVnaXN0ZXIuCitpbmxpbmUgTWFjaGluZUluc3RyQnVpbGRlciBCdWlsZE1JKE1hY2hpbmVGdW5jdGlvbiAmTUYsIGNvbnN0IERlYnVnTG9jICZETCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTUNJbnN0ckRlc2MgJk1DSUQsIHVuc2lnbmVkIERlc3RSZWcpIHsKKyAgcmV0dXJuIE1hY2hpbmVJbnN0ckJ1aWxkZXIoTUYsIE1GLkNyZWF0ZU1hY2hpbmVJbnN0cihNQ0lELCBETCkpCisgICAgICAgICAgIC5hZGRSZWcoRGVzdFJlZywgUmVnU3RhdGU6OkRlZmluZSk7Cit9CisKKy8vLyBUaGlzIHZlcnNpb24gb2YgdGhlIGJ1aWxkZXIgaW5zZXJ0cyB0aGUgbmV3bHktYnVpbHQgaW5zdHJ1Y3Rpb24gYmVmb3JlCisvLy8gdGhlIGdpdmVuIHBvc2l0aW9uIGluIHRoZSBnaXZlbiBNYWNoaW5lQmFzaWNCbG9jaywgYW5kIHNldHMgdXAgdGhlIGZpcnN0CisvLy8gb3BlcmFuZCBhcyBhIGRlc3RpbmF0aW9uIHZpcnR1YWwgcmVnaXN0ZXIuCitpbmxpbmUgTWFjaGluZUluc3RyQnVpbGRlciBCdWlsZE1JKE1hY2hpbmVCYXNpY0Jsb2NrICZCQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnTG9jICZETCwgY29uc3QgTUNJbnN0ckRlc2MgJk1DSUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIERlc3RSZWcpIHsKKyAgTWFjaGluZUZ1bmN0aW9uICZNRiA9ICpCQi5nZXRQYXJlbnQoKTsKKyAgTWFjaGluZUluc3RyICpNSSA9IE1GLkNyZWF0ZU1hY2hpbmVJbnN0cihNQ0lELCBETCk7CisgIEJCLmluc2VydChJLCBNSSk7CisgIHJldHVybiBNYWNoaW5lSW5zdHJCdWlsZGVyKE1GLCBNSSkuYWRkUmVnKERlc3RSZWcsIFJlZ1N0YXRlOjpEZWZpbmUpOworfQorCisvLy8gVGhpcyB2ZXJzaW9uIG9mIHRoZSBidWlsZGVyIGluc2VydHMgdGhlIG5ld2x5LWJ1aWx0IGluc3RydWN0aW9uIGJlZm9yZQorLy8vIHRoZSBnaXZlbiBwb3NpdGlvbiBpbiB0aGUgZ2l2ZW4gTWFjaGluZUJhc2ljQmxvY2ssIGFuZCBzZXRzIHVwIHRoZSBmaXJzdAorLy8vIG9wZXJhbmQgYXMgYSBkZXN0aW5hdGlvbiB2aXJ0dWFsIHJlZ2lzdGVyLgorLy8vCisvLy8gSWYgXGMgSSBpcyBpbnNpZGUgYSBidW5kbGUsIHRoZW4gdGhlIG5ld2x5IGluc2VydGVkIFxhIE1hY2hpbmVJbnN0ciBpcworLy8vIGFkZGVkIHRvIHRoZSBzYW1lIGJ1bmRsZS4KK2lubGluZSBNYWNoaW5lSW5zdHJCdWlsZGVyIEJ1aWxkTUkoTWFjaGluZUJhc2ljQmxvY2sgJkJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aW5zdHJfaXRlcmF0b3IgSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdMb2MgJkRMLCBjb25zdCBNQ0luc3RyRGVzYyAmTUNJRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgRGVzdFJlZykgeworICBNYWNoaW5lRnVuY3Rpb24gJk1GID0gKkJCLmdldFBhcmVudCgpOworICBNYWNoaW5lSW5zdHIgKk1JID0gTUYuQ3JlYXRlTWFjaGluZUluc3RyKE1DSUQsIERMKTsKKyAgQkIuaW5zZXJ0KEksIE1JKTsKKyAgcmV0dXJuIE1hY2hpbmVJbnN0ckJ1aWxkZXIoTUYsIE1JKS5hZGRSZWcoRGVzdFJlZywgUmVnU3RhdGU6OkRlZmluZSk7Cit9CisKK2lubGluZSBNYWNoaW5lSW5zdHJCdWlsZGVyIEJ1aWxkTUkoTWFjaGluZUJhc2ljQmxvY2sgJkJCLCBNYWNoaW5lSW5zdHIgJkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnTG9jICZETCwgY29uc3QgTUNJbnN0ckRlc2MgJk1DSUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIERlc3RSZWcpIHsKKyAgLy8gQ2FsbGluZyB0aGUgb3ZlcmxvYWQgZm9yIGluc3RyX2l0ZXJhdG9yIGlzIGFsd2F5cyBjb3JyZWN0LiAgSG93ZXZlciwgdGhlCisgIC8vIGRlZmluaXRpb24gaXMgbm90IGF2YWlsYWJsZSBpbiBoZWFkZXJzLCBzbyBpbmxpbmUgdGhlIGNoZWNrLgorICBpZiAoSS5pc0luc2lkZUJ1bmRsZSgpKQorICAgIHJldHVybiBCdWlsZE1JKEJCLCBNYWNoaW5lQmFzaWNCbG9jazo6aW5zdHJfaXRlcmF0b3IoSSksIERMLCBNQ0lELCBEZXN0UmVnKTsKKyAgcmV0dXJuIEJ1aWxkTUkoQkIsIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvcihJKSwgREwsIE1DSUQsIERlc3RSZWcpOworfQorCitpbmxpbmUgTWFjaGluZUluc3RyQnVpbGRlciBCdWlsZE1JKE1hY2hpbmVCYXNpY0Jsb2NrICZCQiwgTWFjaGluZUluc3RyICpJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZWJ1Z0xvYyAmREwsIGNvbnN0IE1DSW5zdHJEZXNjICZNQ0lELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBEZXN0UmVnKSB7CisgIHJldHVybiBCdWlsZE1JKEJCLCAqSSwgREwsIE1DSUQsIERlc3RSZWcpOworfQorCisvLy8gVGhpcyB2ZXJzaW9uIG9mIHRoZSBidWlsZGVyIGluc2VydHMgdGhlIG5ld2x5LWJ1aWx0IGluc3RydWN0aW9uIGJlZm9yZSB0aGUKKy8vLyBnaXZlbiBwb3NpdGlvbiBpbiB0aGUgZ2l2ZW4gTWFjaGluZUJhc2ljQmxvY2ssIGFuZCBkb2VzIE5PVCB0YWtlIGEKKy8vLyBkZXN0aW5hdGlvbiByZWdpc3Rlci4KK2lubGluZSBNYWNoaW5lSW5zdHJCdWlsZGVyIEJ1aWxkTUkoTWFjaGluZUJhc2ljQmxvY2sgJkJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdMb2MgJkRMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNQ0luc3RyRGVzYyAmTUNJRCkgeworICBNYWNoaW5lRnVuY3Rpb24gJk1GID0gKkJCLmdldFBhcmVudCgpOworICBNYWNoaW5lSW5zdHIgKk1JID0gTUYuQ3JlYXRlTWFjaGluZUluc3RyKE1DSUQsIERMKTsKKyAgQkIuaW5zZXJ0KEksIE1JKTsKKyAgcmV0dXJuIE1hY2hpbmVJbnN0ckJ1aWxkZXIoTUYsIE1JKTsKK30KKworaW5saW5lIE1hY2hpbmVJbnN0ckJ1aWxkZXIgQnVpbGRNSShNYWNoaW5lQmFzaWNCbG9jayAmQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppbnN0cl9pdGVyYXRvciBJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZWJ1Z0xvYyAmREwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1DSW5zdHJEZXNjICZNQ0lEKSB7CisgIE1hY2hpbmVGdW5jdGlvbiAmTUYgPSAqQkIuZ2V0UGFyZW50KCk7CisgIE1hY2hpbmVJbnN0ciAqTUkgPSBNRi5DcmVhdGVNYWNoaW5lSW5zdHIoTUNJRCwgREwpOworICBCQi5pbnNlcnQoSSwgTUkpOworICByZXR1cm4gTWFjaGluZUluc3RyQnVpbGRlcihNRiwgTUkpOworfQorCitpbmxpbmUgTWFjaGluZUluc3RyQnVpbGRlciBCdWlsZE1JKE1hY2hpbmVCYXNpY0Jsb2NrICZCQiwgTWFjaGluZUluc3RyICZJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZWJ1Z0xvYyAmREwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1DSW5zdHJEZXNjICZNQ0lEKSB7CisgIC8vIENhbGxpbmcgdGhlIG92ZXJsb2FkIGZvciBpbnN0cl9pdGVyYXRvciBpcyBhbHdheXMgY29ycmVjdC4gIEhvd2V2ZXIsIHRoZQorICAvLyBkZWZpbml0aW9uIGlzIG5vdCBhdmFpbGFibGUgaW4gaGVhZGVycywgc28gaW5saW5lIHRoZSBjaGVjay4KKyAgaWYgKEkuaXNJbnNpZGVCdW5kbGUoKSkKKyAgICByZXR1cm4gQnVpbGRNSShCQiwgTWFjaGluZUJhc2ljQmxvY2s6Omluc3RyX2l0ZXJhdG9yKEkpLCBETCwgTUNJRCk7CisgIHJldHVybiBCdWlsZE1JKEJCLCBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IoSSksIERMLCBNQ0lEKTsKK30KKworaW5saW5lIE1hY2hpbmVJbnN0ckJ1aWxkZXIgQnVpbGRNSShNYWNoaW5lQmFzaWNCbG9jayAmQkIsIE1hY2hpbmVJbnN0ciAqSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdMb2MgJkRMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNQ0luc3RyRGVzYyAmTUNJRCkgeworICByZXR1cm4gQnVpbGRNSShCQiwgKkksIERMLCBNQ0lEKTsKK30KKworLy8vIFRoaXMgdmVyc2lvbiBvZiB0aGUgYnVpbGRlciBpbnNlcnRzIHRoZSBuZXdseS1idWlsdCBpbnN0cnVjdGlvbiBhdCB0aGUgZW5kCisvLy8gb2YgdGhlIGdpdmVuIE1hY2hpbmVCYXNpY0Jsb2NrLCBhbmQgZG9lcyBOT1QgdGFrZSBhIGRlc3RpbmF0aW9uIHJlZ2lzdGVyLgoraW5saW5lIE1hY2hpbmVJbnN0ckJ1aWxkZXIgQnVpbGRNSShNYWNoaW5lQmFzaWNCbG9jayAqQkIsIGNvbnN0IERlYnVnTG9jICZETCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTUNJbnN0ckRlc2MgJk1DSUQpIHsKKyAgcmV0dXJuIEJ1aWxkTUkoKkJCLCBCQi0+ZW5kKCksIERMLCBNQ0lEKTsKK30KKworLy8vIFRoaXMgdmVyc2lvbiBvZiB0aGUgYnVpbGRlciBpbnNlcnRzIHRoZSBuZXdseS1idWlsdCBpbnN0cnVjdGlvbiBhdCB0aGUKKy8vLyBlbmQgb2YgdGhlIGdpdmVuIE1hY2hpbmVCYXNpY0Jsb2NrLCBhbmQgc2V0cyB1cCB0aGUgZmlyc3Qgb3BlcmFuZCBhcyBhCisvLy8gZGVzdGluYXRpb24gdmlydHVhbCByZWdpc3Rlci4KK2lubGluZSBNYWNoaW5lSW5zdHJCdWlsZGVyIEJ1aWxkTUkoTWFjaGluZUJhc2ljQmxvY2sgKkJCLCBjb25zdCBEZWJ1Z0xvYyAmREwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1DSW5zdHJEZXNjICZNQ0lELCB1bnNpZ25lZCBEZXN0UmVnKSB7CisgIHJldHVybiBCdWlsZE1JKCpCQiwgQkItPmVuZCgpLCBETCwgTUNJRCwgRGVzdFJlZyk7Cit9CisKKy8vLyBUaGlzIHZlcnNpb24gb2YgdGhlIGJ1aWxkZXIgYnVpbGRzIGEgREJHX1ZBTFVFIGludHJpbnNpYworLy8vIGZvciBlaXRoZXIgYSB2YWx1ZSBpbiBhIHJlZ2lzdGVyIG9yIGEgcmVnaXN0ZXItaW5kaXJlY3QKKy8vLyBhZGRyZXNzLiAgVGhlIGNvbnZlbnRpb24gaXMgdGhhdCBhIERCR19WQUxVRSBpcyBpbmRpcmVjdCBpZmYgdGhlCisvLy8gc2Vjb25kIG9wZXJhbmQgaXMgYW4gaW1tZWRpYXRlLgorTWFjaGluZUluc3RyQnVpbGRlciBCdWlsZE1JKE1hY2hpbmVGdW5jdGlvbiAmTUYsIGNvbnN0IERlYnVnTG9jICZETCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNQ0luc3RyRGVzYyAmTUNJRCwgYm9vbCBJc0luZGlyZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFJlZywgY29uc3QgTUROb2RlICpWYXJpYWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNRE5vZGUgKkV4cHIpOworCisvLy8gVGhpcyB2ZXJzaW9uIG9mIHRoZSBidWlsZGVyIGJ1aWxkcyBhIERCR19WQUxVRSBpbnRyaW5zaWMKKy8vLyBmb3IgZWl0aGVyIGEgdmFsdWUgaW4gYSByZWdpc3RlciBvciBhIHJlZ2lzdGVyLWluZGlyZWN0CisvLy8gYWRkcmVzcyBhbmQgaW5zZXJ0cyBpdCBhdCBwb3NpdGlvbiBJLgorTWFjaGluZUluc3RyQnVpbGRlciBCdWlsZE1JKE1hY2hpbmVCYXNpY0Jsb2NrICZCQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgSSwgY29uc3QgRGVidWdMb2MgJkRMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1DSW5zdHJEZXNjICZNQ0lELCBib29sIElzSW5kaXJlY3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgUmVnLCBjb25zdCBNRE5vZGUgKlZhcmlhYmxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1ETm9kZSAqRXhwcik7CisKKy8vLyBDbG9uZSBhIERCR19WQUxVRSB3aG9zZSB2YWx1ZSBoYXMgYmVlbiBzcGlsbGVkIHRvIEZyYW1lSW5kZXguCitNYWNoaW5lSW5zdHIgKmJ1aWxkRGJnVmFsdWVGb3JTcGlsbChNYWNoaW5lQmFzaWNCbG9jayAmQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ciAmT3JpZywgaW50IEZyYW1lSW5kZXgpOworCisvLy8gVXBkYXRlIGEgREJHX1ZBTFVFIHdob3NlIHZhbHVlIGhhcyBiZWVuIHNwaWxsZWQgdG8gRnJhbWVJbmRleC4gVXNlZnVsIHdoZW4KKy8vLyBtb2RpZnlpbmcgYW4gaW5zdHJ1Y3Rpb24gaW4gcGxhY2Ugd2hpbGUgaXRlcmF0aW5nIG92ZXIgYSBiYXNpYyBibG9jay4KK3ZvaWQgdXBkYXRlRGJnVmFsdWVGb3JTcGlsbChNYWNoaW5lSW5zdHIgJk9yaWcsIGludCBGcmFtZUluZGV4KTsKKworaW5saW5lIHVuc2lnbmVkIGdldERlZlJlZ1N0YXRlKGJvb2wgQikgeworICByZXR1cm4gQiA/IFJlZ1N0YXRlOjpEZWZpbmUgOiAwOworfQoraW5saW5lIHVuc2lnbmVkIGdldEltcGxSZWdTdGF0ZShib29sIEIpIHsKKyAgcmV0dXJuIEIgPyBSZWdTdGF0ZTo6SW1wbGljaXQgOiAwOworfQoraW5saW5lIHVuc2lnbmVkIGdldEtpbGxSZWdTdGF0ZShib29sIEIpIHsKKyAgcmV0dXJuIEIgPyBSZWdTdGF0ZTo6S2lsbCA6IDA7Cit9CitpbmxpbmUgdW5zaWduZWQgZ2V0RGVhZFJlZ1N0YXRlKGJvb2wgQikgeworICByZXR1cm4gQiA/IFJlZ1N0YXRlOjpEZWFkIDogMDsKK30KK2lubGluZSB1bnNpZ25lZCBnZXRVbmRlZlJlZ1N0YXRlKGJvb2wgQikgeworICByZXR1cm4gQiA/IFJlZ1N0YXRlOjpVbmRlZiA6IDA7Cit9CitpbmxpbmUgdW5zaWduZWQgZ2V0SW50ZXJuYWxSZWFkUmVnU3RhdGUoYm9vbCBCKSB7CisgIHJldHVybiBCID8gUmVnU3RhdGU6OkludGVybmFsUmVhZCA6IDA7Cit9CitpbmxpbmUgdW5zaWduZWQgZ2V0RGVidWdSZWdTdGF0ZShib29sIEIpIHsKKyAgcmV0dXJuIEIgPyBSZWdTdGF0ZTo6RGVidWcgOiAwOworfQoraW5saW5lIHVuc2lnbmVkIGdldFJlbmFtYWJsZVJlZ1N0YXRlKGJvb2wgQikgeworICByZXR1cm4gQiA/IFJlZ1N0YXRlOjpSZW5hbWFibGUgOiAwOworfQorCisvLy8gR2V0IGFsbCByZWdpc3RlciBzdGF0ZSBmbGFncyBmcm9tIG1hY2hpbmUgb3BlcmFuZCBccCBSZWdPcC4KK2lubGluZSB1bnNpZ25lZCBnZXRSZWdTdGF0ZShjb25zdCBNYWNoaW5lT3BlcmFuZCAmUmVnT3ApIHsKKyAgYXNzZXJ0KFJlZ09wLmlzUmVnKCkgJiYgIk5vdCBhIHJlZ2lzdGVyIG9wZXJhbmQiKTsKKyAgcmV0dXJuIGdldERlZlJlZ1N0YXRlKFJlZ09wLmlzRGVmKCkpICAgICAgICAgICAgICAgICAgICB8CisgICAgICAgICBnZXRJbXBsUmVnU3RhdGUoUmVnT3AuaXNJbXBsaWNpdCgpKSAgICAgICAgICAgICAgfAorICAgICAgICAgZ2V0S2lsbFJlZ1N0YXRlKFJlZ09wLmlzS2lsbCgpKSAgICAgICAgICAgICAgICAgIHwKKyAgICAgICAgIGdldERlYWRSZWdTdGF0ZShSZWdPcC5pc0RlYWQoKSkgICAgICAgICAgICAgICAgICB8CisgICAgICAgICBnZXRVbmRlZlJlZ1N0YXRlKFJlZ09wLmlzVW5kZWYoKSkgICAgICAgICAgICAgICAgfAorICAgICAgICAgZ2V0SW50ZXJuYWxSZWFkUmVnU3RhdGUoUmVnT3AuaXNJbnRlcm5hbFJlYWQoKSkgIHwKKyAgICAgICAgIGdldERlYnVnUmVnU3RhdGUoUmVnT3AuaXNEZWJ1ZygpKSAgICAgICAgICAgICAgICB8CisgICAgICAgICBnZXRSZW5hbWFibGVSZWdTdGF0ZSgKKyAgICAgICAgICAgICBUYXJnZXRSZWdpc3RlckluZm86OmlzUGh5c2ljYWxSZWdpc3RlcihSZWdPcC5nZXRSZWcoKSkgJiYKKyAgICAgICAgICAgICBSZWdPcC5pc1JlbmFtYWJsZSgpKTsKK30KKworLy8vIEhlbHBlciBjbGFzcyBmb3IgY29uc3RydWN0aW5nIGJ1bmRsZXMgb2YgTWFjaGluZUluc3Rycy4KKy8vLworLy8vIE1JQnVuZGxlQnVpbGRlciBjYW4gY3JlYXRlIGEgYnVuZGxlIGZyb20gc2NyYXRjaCBieSBpbnNlcnRpbmcgbmV3CisvLy8gTWFjaGluZUluc3RycyBvbmUgYXQgYSB0aW1lLCBvciBpdCBjYW4gY3JlYXRlIGEgYnVuZGxlIGZyb20gYSBzZXF1ZW5jZSBvZgorLy8vIGV4aXN0aW5nIE1hY2hpbmVJbnN0cnMgaW4gYSBiYXNpYyBibG9jay4KK2NsYXNzIE1JQnVuZGxlQnVpbGRlciB7CisgIE1hY2hpbmVCYXNpY0Jsb2NrICZNQkI7CisgIE1hY2hpbmVCYXNpY0Jsb2NrOjppbnN0cl9pdGVyYXRvciBCZWdpbjsKKyAgTWFjaGluZUJhc2ljQmxvY2s6Omluc3RyX2l0ZXJhdG9yIEVuZDsKKworcHVibGljOgorICAvLy8gQ3JlYXRlIGFuIE1JQnVuZGxlQnVpbGRlciB0aGF0IGluc2VydHMgaW5zdHJ1Y3Rpb25zIGludG8gYSBuZXcgYnVuZGxlIGluCisgIC8vLyBCQiBhYm92ZSB0aGUgYnVuZGxlIG9yIGluc3RydWN0aW9uIGF0IFBvcy4KKyAgTUlCdW5kbGVCdWlsZGVyKE1hY2hpbmVCYXNpY0Jsb2NrICZCQiwgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIFBvcykKKyAgICAgIDogTUJCKEJCKSwgQmVnaW4oUG9zLmdldEluc3RySXRlcmF0b3IoKSksIEVuZChCZWdpbikge30KKworICAvLy8gQ3JlYXRlIGEgYnVuZGxlIGZyb20gdGhlIHNlcXVlbmNlIG9mIGluc3RydWN0aW9ucyBiZXR3ZWVuIEIgYW5kIEUuCisgIE1JQnVuZGxlQnVpbGRlcihNYWNoaW5lQmFzaWNCbG9jayAmQkIsIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBCLAorICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEUpCisgICAgICA6IE1CQihCQiksIEJlZ2luKEIuZ2V0SW5zdHJJdGVyYXRvcigpKSwgRW5kKEUuZ2V0SW5zdHJJdGVyYXRvcigpKSB7CisgICAgYXNzZXJ0KEIgIT0gRSAmJiAiTm8gaW5zdHJ1Y3Rpb25zIHRvIGJ1bmRsZSIpOworICAgICsrQjsKKyAgICB3aGlsZSAoQiAhPSBFKSB7CisgICAgICBNYWNoaW5lSW5zdHIgJk1JID0gKkI7CisgICAgICArK0I7CisgICAgICBNSS5idW5kbGVXaXRoUHJlZCgpOworICAgIH0KKyAgfQorCisgIC8vLyBDcmVhdGUgYW4gTUlCdW5kbGVCdWlsZGVyIHJlcHJlc2VudGluZyBhbiBleGlzdGluZyBpbnN0cnVjdGlvbiBvciBidW5kbGUKKyAgLy8vIHRoYXQgaGFzIE1JIGFzIGl0cyBoZWFkLgorICBleHBsaWNpdCBNSUJ1bmRsZUJ1aWxkZXIoTWFjaGluZUluc3RyICpNSSkKKyAgICAgIDogTUJCKCpNSS0+Z2V0UGFyZW50KCkpLCBCZWdpbihNSSksCisgICAgICAgIEVuZChnZXRCdW5kbGVFbmQoTUktPmdldEl0ZXJhdG9yKCkpKSB7fQorCisgIC8vLyBSZXR1cm4gYSByZWZlcmVuY2UgdG8gdGhlIGJhc2ljIGJsb2NrIGNvbnRhaW5pbmcgdGhpcyBidW5kbGUuCisgIE1hY2hpbmVCYXNpY0Jsb2NrICZnZXRNQkIoKSBjb25zdCB7IHJldHVybiBNQkI7IH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgbm8gaW5zdHJ1Y3Rpb25zIGhhdmUgYmVlbiBpbnNlcnRlZCBpbiB0aGlzIGJ1bmRsZSB5ZXQuCisgIC8vLyBFbXB0eSBidW5kbGVzIGFyZW4ndCByZXByZXNlbnRhYmxlIGluIGEgTWFjaGluZUJhc2ljQmxvY2suCisgIGJvb2wgZW1wdHkoKSBjb25zdCB7IHJldHVybiBCZWdpbiA9PSBFbmQ7IH0KKworICAvLy8gUmV0dXJuIGFuIGl0ZXJhdG9yIHRvIHRoZSBmaXJzdCBidW5kbGVkIGluc3RydWN0aW9uLgorICBNYWNoaW5lQmFzaWNCbG9jazo6aW5zdHJfaXRlcmF0b3IgYmVnaW4oKSBjb25zdCB7IHJldHVybiBCZWdpbjsgfQorCisgIC8vLyBSZXR1cm4gYW4gaXRlcmF0b3IgYmV5b25kIHRoZSBsYXN0IGJ1bmRsZWQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVCYXNpY0Jsb2NrOjppbnN0cl9pdGVyYXRvciBlbmQoKSBjb25zdCB7IHJldHVybiBFbmQ7IH0KKworICAvLy8gSW5zZXJ0IE1JIGludG8gdGhpcyBidW5kbGUgYmVmb3JlIEkgd2hpY2ggbXVzdCBwb2ludCB0byBhbiBpbnN0cnVjdGlvbiBpbgorICAvLy8gdGhlIGJ1bmRsZSwgb3IgZW5kKCkuCisgIE1JQnVuZGxlQnVpbGRlciAmaW5zZXJ0KE1hY2hpbmVCYXNpY0Jsb2NrOjppbnN0cl9pdGVyYXRvciBJLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSW5zdHIgKk1JKSB7CisgICAgTUJCLmluc2VydChJLCBNSSk7CisgICAgaWYgKEkgPT0gQmVnaW4pIHsKKyAgICAgIGlmICghZW1wdHkoKSkKKyAgICAgICAgTUktPmJ1bmRsZVdpdGhTdWNjKCk7CisgICAgICBCZWdpbiA9IE1JLT5nZXRJdGVyYXRvcigpOworICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KKyAgICBpZiAoSSA9PSBFbmQpIHsKKyAgICAgIE1JLT5idW5kbGVXaXRoUHJlZCgpOworICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KKyAgICAvLyBNSSB3YXMgaW5zZXJ0ZWQgaW4gdGhlIG1pZGRsZSBvZiB0aGUgYnVuZGxlLCBzbyBpdHMgbmVpZ2hib3JzJyBmbGFncyBhcmUKKyAgICAvLyBhbHJlYWR5IGZpbmUuIFVwZGF0ZSBNSSdzIGJ1bmRsZSBmbGFncyBtYW51YWxseS4KKyAgICBNSS0+c2V0RmxhZyhNYWNoaW5lSW5zdHI6OkJ1bmRsZWRQcmVkKTsKKyAgICBNSS0+c2V0RmxhZyhNYWNoaW5lSW5zdHI6OkJ1bmRsZWRTdWNjKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICAvLy8gSW5zZXJ0IE1JIGludG8gTUJCIGJ5IHByZXBlbmRpbmcgaXQgdG8gdGhlIGluc3RydWN0aW9ucyBpbiB0aGUgYnVuZGxlLgorICAvLy8gTUkgd2lsbCBiZWNvbWUgdGhlIGZpcnN0IGluc3RydWN0aW9uIGluIHRoZSBidW5kbGUuCisgIE1JQnVuZGxlQnVpbGRlciAmcHJlcGVuZChNYWNoaW5lSW5zdHIgKk1JKSB7CisgICAgcmV0dXJuIGluc2VydChiZWdpbigpLCBNSSk7CisgIH0KKworICAvLy8gSW5zZXJ0IE1JIGludG8gTUJCIGJ5IGFwcGVuZGluZyBpdCB0byB0aGUgaW5zdHJ1Y3Rpb25zIGluIHRoZSBidW5kbGUuCisgIC8vLyBNSSB3aWxsIGJlY29tZSB0aGUgbGFzdCBpbnN0cnVjdGlvbiBpbiB0aGUgYnVuZGxlLgorICBNSUJ1bmRsZUJ1aWxkZXIgJmFwcGVuZChNYWNoaW5lSW5zdHIgKk1JKSB7CisgICAgcmV0dXJuIGluc2VydChlbmQoKSwgTUkpOworICB9Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX01BQ0hJTkVJTlNUUkJVSUxERVJfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVJbnN0ckJ1bmRsZS5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVJbnN0ckJ1bmRsZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmI1MzQxZmQKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUluc3RyQnVuZGxlLmgKQEAgLTAsMCArMSwyNjEgQEAKKy8vPT09LS0gQ29kZUdlbi9NYWNoaW5lSW5zdEJ1bmRsZS5oIC0gTUkgYnVuZGxlIHV0aWxpdGllcyAtLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIHByb3ZpZGUgdXRpbGl0eSBmdW5jdGlvbnMgdG8gbWFuaXB1bGF0ZSBtYWNoaW5lIGluc3RydWN0aW9uCisvLyBidW5kbGVzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ0hJTkVJTlNUUkJVTkRMRV9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9NQUNISU5FSU5TVFJCVU5ETEVfSAorCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVCYXNpY0Jsb2NrLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKworLy8vIGZpbmFsaXplQnVuZGxlIC0gRmluYWxpemUgYSBtYWNoaW5lIGluc3RydWN0aW9uIGJ1bmRsZSB3aGljaCBpbmNsdWRlcworLy8vIGEgc2VxdWVuY2Ugb2YgaW5zdHJ1Y3Rpb25zIHN0YXJ0aW5nIGZyb20gRmlyc3RNSSB0byBMYXN0TUkgKGV4Y2x1c2l2ZSkuCisvLy8gVGhpcyByb3V0aW5lIGFkZHMgYSBCVU5ETEUgaW5zdHJ1Y3Rpb24gdG8gcmVwcmVzZW50IHRoZSBidW5kbGUsIGl0IGFkZHMKKy8vLyBJc0ludGVybmFsUmVhZCBtYXJrZXJzIHRvIE1hY2hpbmVPcGVyYW5kcyB3aGljaCBhcmUgZGVmaW5lZCBpbnNpZGUgdGhlCisvLy8gYnVuZGxlLCBhbmQgaXQgY29waWVzIGV4dGVybmFsbHkgdmlzaWJsZSBkZWZzIGFuZCB1c2VzIHRvIHRoZSBCVU5ETEUKKy8vLyBpbnN0cnVjdGlvbi4KK3ZvaWQgZmluYWxpemVCdW5kbGUoTWFjaGluZUJhc2ljQmxvY2sgJk1CQiwKKyAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Omluc3RyX2l0ZXJhdG9yIEZpcnN0TUksCisgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppbnN0cl9pdGVyYXRvciBMYXN0TUkpOworCisvLy8gZmluYWxpemVCdW5kbGUgLSBTYW1lIGZ1bmN0aW9uYWxpdHkgYXMgdGhlIHByZXZpb3VzIGZpbmFsaXplQnVuZGxlIGV4Y2VwdAorLy8vIHRoZSBsYXN0IGluc3RydWN0aW9uIGluIHRoZSBidW5kbGUgaXMgbm90IHByb3ZpZGVkIGFzIGFuIGlucHV0LiBUaGlzIGlzCisvLy8gdXNlZCBpbiBjYXNlcyB3aGVyZSBidW5kbGVzIGFyZSBwcmUtZGV0ZXJtaW5lZCBieSBtYXJraW5nIGluc3RydWN0aW9ucworLy8vIHdpdGggJ0luc2lkZUJ1bmRsZScgbWFya2VyLiBJdCByZXR1cm5zIHRoZSBNQkIgaW5zdHJ1Y3Rpb24gaXRlcmF0b3IgdGhhdAorLy8vIHBvaW50cyB0byB0aGUgZW5kIG9mIHRoZSBidW5kbGUuCitNYWNoaW5lQmFzaWNCbG9jazo6aW5zdHJfaXRlcmF0b3IgZmluYWxpemVCdW5kbGUoTWFjaGluZUJhc2ljQmxvY2sgJk1CQiwKKyAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Omluc3RyX2l0ZXJhdG9yIEZpcnN0TUkpOworCisvLy8gZmluYWxpemVCdW5kbGVzIC0gRmluYWxpemUgaW5zdHJ1Y3Rpb24gYnVuZGxlcyBpbiB0aGUgc3BlY2lmaWVkCisvLy8gTWFjaGluZUZ1bmN0aW9uLiBSZXR1cm4gdHJ1ZSBpZiBhbnkgYnVuZGxlcyBhcmUgZmluYWxpemVkLgorYm9vbCBmaW5hbGl6ZUJ1bmRsZXMoTWFjaGluZUZ1bmN0aW9uICZNRik7CisKKy8vLyBSZXR1cm5zIGFuIGl0ZXJhdG9yIHRvIHRoZSBmaXJzdCBpbnN0cnVjdGlvbiBpbiB0aGUgYnVuZGxlIGNvbnRhaW5pbmcgXHAgSS4KK2lubGluZSBNYWNoaW5lQmFzaWNCbG9jazo6aW5zdHJfaXRlcmF0b3IgZ2V0QnVuZGxlU3RhcnQoCisgICAgTWFjaGluZUJhc2ljQmxvY2s6Omluc3RyX2l0ZXJhdG9yIEkpIHsKKyAgd2hpbGUgKEktPmlzQnVuZGxlZFdpdGhQcmVkKCkpCisgICAgLS1JOworICByZXR1cm4gSTsKK30KKworLy8vIFJldHVybnMgYW4gaXRlcmF0b3IgdG8gdGhlIGZpcnN0IGluc3RydWN0aW9uIGluIHRoZSBidW5kbGUgY29udGFpbmluZyBccCBJLgoraW5saW5lIE1hY2hpbmVCYXNpY0Jsb2NrOjpjb25zdF9pbnN0cl9pdGVyYXRvciBnZXRCdW5kbGVTdGFydCgKKyAgICBNYWNoaW5lQmFzaWNCbG9jazo6Y29uc3RfaW5zdHJfaXRlcmF0b3IgSSkgeworICB3aGlsZSAoSS0+aXNCdW5kbGVkV2l0aFByZWQoKSkKKyAgICAtLUk7CisgIHJldHVybiBJOworfQorCisvLy8gUmV0dXJucyBhbiBpdGVyYXRvciBwb2ludGluZyBiZXlvbmQgdGhlIGJ1bmRsZSBjb250YWluaW5nIFxwIEkuCitpbmxpbmUgTWFjaGluZUJhc2ljQmxvY2s6Omluc3RyX2l0ZXJhdG9yIGdldEJ1bmRsZUVuZCgKKyAgICBNYWNoaW5lQmFzaWNCbG9jazo6aW5zdHJfaXRlcmF0b3IgSSkgeworICB3aGlsZSAoSS0+aXNCdW5kbGVkV2l0aFN1Y2MoKSkKKyAgICArK0k7CisgIHJldHVybiArK0k7Cit9CisKKy8vLyBSZXR1cm5zIGFuIGl0ZXJhdG9yIHBvaW50aW5nIGJleW9uZCB0aGUgYnVuZGxlIGNvbnRhaW5pbmcgXHAgSS4KK2lubGluZSBNYWNoaW5lQmFzaWNCbG9jazo6Y29uc3RfaW5zdHJfaXRlcmF0b3IgZ2V0QnVuZGxlRW5kKAorICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjpjb25zdF9pbnN0cl9pdGVyYXRvciBJKSB7CisgIHdoaWxlIChJLT5pc0J1bmRsZWRXaXRoU3VjYygpKQorICAgICsrSTsKKyAgcmV0dXJuICsrSTsKK30KKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vIE1hY2hpbmVPcGVyYW5kIGl0ZXJhdG9yCisvLworCisvLy8gTWFjaGluZU9wZXJhbmRJdGVyYXRvckJhc2UgLSBJdGVyYXRvciB0aGF0IGNhbiB2aXNpdCBhbGwgb3BlcmFuZHMgb24gYQorLy8vIE1hY2hpbmVJbnN0ciwgb3IgYWxsIG9wZXJhbmRzIG9uIGEgYnVuZGxlIG9mIE1hY2hpbmVJbnN0cnMuICBUaGlzIGNsYXNzIGlzCisvLy8gbm90IGludGVuZGVkIHRvIGJlIHVzZWQgZGlyZWN0bHksIHVzZSBvbmUgb2YgdGhlIHN1Yi1jbGFzc2VzIGluc3RlYWQuCisvLy8KKy8vLyBJbnRlbmRlZCB1c2U6CisvLy8KKy8vLyAgIGZvciAoTUlCdW5kbGVPcGVyYW5kcyBNSU8oTUkpOyBNSU8uaXNWYWxpZCgpOyArK01JTykgeworLy8vICAgICBpZiAoIU1JTy0+aXNSZWcoKSkKKy8vLyAgICAgICBjb250aW51ZTsKKy8vLyAgICAgLi4uCisvLy8gICB9CisvLy8KK2NsYXNzIE1hY2hpbmVPcGVyYW5kSXRlcmF0b3JCYXNlIHsKKyAgTWFjaGluZUJhc2ljQmxvY2s6Omluc3RyX2l0ZXJhdG9yIEluc3RySSwgSW5zdHJFOworICBNYWNoaW5lSW5zdHI6Om1vcF9pdGVyYXRvciBPcEksIE9wRTsKKworICAvLyBJZiB0aGUgb3BlcmFuZHMgb24gSW5zdHJJIGFyZSBleGhhdXN0ZWQsIGFkdmFuY2UgSW5zdHJJIHRvIHRoZSBuZXh0CisgIC8vIGJ1bmRsZWQgaW5zdHJ1Y3Rpb24gd2l0aCBvcGVyYW5kcy4KKyAgdm9pZCBhZHZhbmNlKCkgeworICAgIHdoaWxlIChPcEkgPT0gT3BFKSB7CisgICAgICAvLyBEb24ndCBhZHZhbmNlIG9mZiB0aGUgYmFzaWMgYmxvY2ssIG9yIGludG8gYSBuZXcgYnVuZGxlLgorICAgICAgaWYgKCsrSW5zdHJJID09IEluc3RyRSB8fCAhSW5zdHJJLT5pc0luc2lkZUJ1bmRsZSgpKQorICAgICAgICBicmVhazsKKyAgICAgIE9wSSA9IEluc3RySS0+b3BlcmFuZHNfYmVnaW4oKTsKKyAgICAgIE9wRSA9IEluc3RySS0+b3BlcmFuZHNfZW5kKCk7CisgICAgfQorICB9CisKK3Byb3RlY3RlZDoKKyAgLy8vIE1hY2hpbmVPcGVyYW5kSXRlcmF0b3JCYXNlIC0gQ3JlYXRlIGFuIGl0ZXJhdG9yIHRoYXQgdmlzaXRzIGFsbCBvcGVyYW5kcworICAvLy8gb24gTUksIG9yIGFsbCBvcGVyYW5kcyBvbiBldmVyeSBpbnN0cnVjdGlvbiBpbiB0aGUgYnVuZGxlIGNvbnRhaW5pbmcgTUkuCisgIC8vLworICAvLy8gQHBhcmFtIE1JIFRoZSBpbnN0cnVjdGlvbiB0byBleGFtaW5lLgorICAvLy8gQHBhcmFtIFdob2xlQnVuZGxlIFdoZW4gdHJ1ZSwgdmlzaXQgYWxsIG9wZXJhbmRzIG9uIHRoZSBlbnRpcmUgYnVuZGxlLgorICAvLy8KKyAgZXhwbGljaXQgTWFjaGluZU9wZXJhbmRJdGVyYXRvckJhc2UoTWFjaGluZUluc3RyICZNSSwgYm9vbCBXaG9sZUJ1bmRsZSkgeworICAgIGlmIChXaG9sZUJ1bmRsZSkgeworICAgICAgSW5zdHJJID0gZ2V0QnVuZGxlU3RhcnQoTUkuZ2V0SXRlcmF0b3IoKSk7CisgICAgICBJbnN0ckUgPSBNSS5nZXRQYXJlbnQoKS0+aW5zdHJfZW5kKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIEluc3RySSA9IEluc3RyRSA9IE1JLmdldEl0ZXJhdG9yKCk7CisgICAgICArK0luc3RyRTsKKyAgICB9CisgICAgT3BJID0gSW5zdHJJLT5vcGVyYW5kc19iZWdpbigpOworICAgIE9wRSA9IEluc3RySS0+b3BlcmFuZHNfZW5kKCk7CisgICAgaWYgKFdob2xlQnVuZGxlKQorICAgICAgYWR2YW5jZSgpOworICB9CisKKyAgTWFjaGluZU9wZXJhbmQgJmRlcmVmKCkgY29uc3QgeyByZXR1cm4gKk9wSTsgfQorCitwdWJsaWM6CisgIC8vLyBpc1ZhbGlkIC0gUmV0dXJucyB0cnVlIHVudGlsIGFsbCB0aGUgb3BlcmFuZHMgaGF2ZSBiZWVuIHZpc2l0ZWQuCisgIGJvb2wgaXNWYWxpZCgpIGNvbnN0IHsgcmV0dXJuIE9wSSAhPSBPcEU7IH0KKworICAvLy8gUHJlaW5jcmVtZW50LiAgTW92ZSB0byB0aGUgbmV4dCBvcGVyYW5kLgorICB2b2lkIG9wZXJhdG9yKysoKSB7CisgICAgYXNzZXJ0KGlzVmFsaWQoKSAmJiAiQ2Fubm90IGFkdmFuY2UgTUlPcGVyYW5kcyBiZXlvbmQgdGhlIGxhc3Qgb3BlcmFuZCIpOworICAgICsrT3BJOworICAgIGFkdmFuY2UoKTsKKyAgfQorCisgIC8vLyBnZXRPcGVyYW5kTm8gLSBSZXR1cm5zIHRoZSBudW1iZXIgb2YgdGhlIGN1cnJlbnQgb3BlcmFuZCByZWxhdGl2ZSB0byBpdHMKKyAgLy8vIGluc3RydWN0aW9uLgorICAvLy8KKyAgdW5zaWduZWQgZ2V0T3BlcmFuZE5vKCkgY29uc3QgeworICAgIHJldHVybiBPcEkgLSBJbnN0ckktPm9wZXJhbmRzX2JlZ2luKCk7CisgIH0KKworICAvLy8gVmlydFJlZ0luZm8gLSBJbmZvcm1hdGlvbiBhYm91dCBhIHZpcnR1YWwgcmVnaXN0ZXIgdXNlZCBieSBhIHNldCBvZiBvcGVyYW5kcy4KKyAgLy8vCisgIHN0cnVjdCBWaXJ0UmVnSW5mbyB7CisgICAgLy8vIFJlYWRzIC0gT25lIG9mIHRoZSBvcGVyYW5kcyByZWFkIHRoZSB2aXJ0dWFsIHJlZ2lzdGVyLiAgVGhpcyBkb2VzIG5vdAorICAgIC8vLyBpbmNsdWRlIHVuZGVmIG9yIGludGVybmFsIHVzZSBvcGVyYW5kcywgc2VlIE1POjpyZWFkc1JlZygpLgorICAgIGJvb2wgUmVhZHM7CisKKyAgICAvLy8gV3JpdGVzIC0gT25lIG9mIHRoZSBvcGVyYW5kcyB3cml0ZXMgdGhlIHZpcnR1YWwgcmVnaXN0ZXIuCisgICAgYm9vbCBXcml0ZXM7CisKKyAgICAvLy8gVGllZCAtIFVzZXMgYW5kIGRlZnMgbXVzdCB1c2UgdGhlIHNhbWUgcmVnaXN0ZXIuIFRoaXMgY2FuIGJlIGJlY2F1c2Ugb2YKKyAgICAvLy8gYSB0d28tYWRkcmVzcyBjb25zdHJhaW50LCBvciB0aGVyZSBtYXkgYmUgYSBwYXJ0aWFsIHJlZGVmaW5pdGlvbiBvZiBhCisgICAgLy8vIHN1Yi1yZWdpc3Rlci4KKyAgICBib29sIFRpZWQ7CisgIH07CisKKyAgLy8vIEluZm9ybWF0aW9uIGFib3V0IGhvdyBhIHBoeXNpY2FsIHJlZ2lzdGVyIFJlZyBpcyB1c2VkIGJ5IGEgc2V0IG9mCisgIC8vLyBvcGVyYW5kcy4KKyAgc3RydWN0IFBoeXNSZWdJbmZvIHsKKyAgICAvLy8gVGhlcmUgaXMgYSByZWdtYXNrIG9wZXJhbmQgaW5kaWNhdGluZyBSZWcgaXMgY2xvYmJlcmVkLgorICAgIC8vLyBcc2VlIE1hY2hpbmVPcGVyYW5kOjpDcmVhdGVSZWdNYXNrKCkuCisgICAgYm9vbCBDbG9iYmVyZWQ7CisKKyAgICAvLy8gUmVnIG9yIG9uZSBvZiBpdHMgYWxpYXNlcyBpcyBkZWZpbmVkLiBUaGUgZGVmaW5pdGlvbiBtYXkgb25seSBjb3ZlcgorICAgIC8vLyBwYXJ0cyBvZiB0aGUgcmVnaXN0ZXIuCisgICAgYm9vbCBEZWZpbmVkOworICAgIC8vLyBSZWcgb3IgYSBzdXBlci1yZWdpc3RlciBpcyBkZWZpbmVkLiBUaGUgZGVmaW5pdGlvbiBjb3ZlcnMgdGhlIGZ1bGwKKyAgICAvLy8gcmVnaXN0ZXIuCisgICAgYm9vbCBGdWxseURlZmluZWQ7CisKKyAgICAvLy8gUmVnIG9yIG9uZSBvZiBpdHMgYWxpYXNlcyBpcyByZWFkLiBUaGUgcmVnaXN0ZXIgbWF5IG9ubHkgYmUgcmVhZAorICAgIC8vLyBwYXJ0aWFsbHkuCisgICAgYm9vbCBSZWFkOworICAgIC8vLyBSZWcgb3IgYSBzdXBlci1yZWdpc3RlciBpcyByZWFkLiBUaGUgZnVsbCByZWdpc3RlciBpcyByZWFkLgorICAgIGJvb2wgRnVsbHlSZWFkOworCisgICAgLy8vIEVpdGhlcjoKKyAgICAvLy8gLSBSZWcgaXMgRnVsbHlEZWZpbmVkIGFuZCBhbGwgZGVmcyBvZiByZWcgb3IgYW4gb3ZlcmxhcHBpbmcKKyAgICAvLy8gICByZWdpc3RlciBhcmUgZGVhZCwgb3IKKyAgICAvLy8gLSBSZWcgaXMgY29tcGxldGVseSBkZWFkIGJlY2F1c2UgImRlZmluZWQiIGJ5IGEgY2xvYmJlci4KKyAgICBib29sIERlYWREZWY7CisKKyAgICAvLy8gUmVnIGlzIERlZmluZWQgYW5kIGFsbCBkZWZzIG9mIHJlZyBvciBhbiBvdmVybGFwcGluZyByZWdpc3RlciBhcmUKKyAgICAvLy8gZGVhZC4KKyAgICBib29sIFBhcnRpYWxEZWFkRGVmOworCisgICAgLy8vIFRoZXJlIGlzIGEgdXNlIG9wZXJhbmQgb2YgcmVnIG9yIGEgc3VwZXItcmVnaXN0ZXIgd2l0aCBraWxsIGZsYWcgc2V0LgorICAgIGJvb2wgS2lsbGVkOworICB9OworCisgIC8vLyBhbmFseXplVmlydFJlZyAtIEFuYWx5emUgaG93IHRoZSBjdXJyZW50IGluc3RydWN0aW9uIG9yIGJ1bmRsZSB1c2VzIGEKKyAgLy8vIHZpcnR1YWwgcmVnaXN0ZXIuICBUaGlzIGZ1bmN0aW9uIHNob3VsZCBub3QgYmUgY2FsbGVkIGFmdGVyIG9wZXJhdG9yKysoKSwKKyAgLy8vIGl0IGV4cGVjdHMgYSBmcmVzaCBpdGVyYXRvci4KKyAgLy8vCisgIC8vLyBAcGFyYW0gUmVnIFRoZSB2aXJ0dWFsIHJlZ2lzdGVyIHRvIGFuYWx5emUuCisgIC8vLyBAcGFyYW0gT3BzIFdoZW4gc2V0LCB0aGlzIHZlY3RvciB3aWxsIHJlY2VpdmUgYW4gKE1JLCBPcE51bSkgZW50cnkgZm9yCisgIC8vLyAgICAgICAgICAgIGVhY2ggb3BlcmFuZCByZWZlcnJpbmcgdG8gUmVnLgorICAvLy8gQHJldHVybnMgQSBmaWxsZWQtaW4gUmVnSW5mbyBzdHJ1Y3QuCisgIFZpcnRSZWdJbmZvIGFuYWx5emVWaXJ0UmVnKHVuc2lnbmVkIFJlZywKKyAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPHN0ZDo6cGFpcjxNYWNoaW5lSW5zdHIqLCB1bnNpZ25lZD4gPiAqT3BzID0gbnVsbHB0cik7CisKKyAgLy8vIGFuYWx5emVQaHlzUmVnIC0gQW5hbHl6ZSBob3cgdGhlIGN1cnJlbnQgaW5zdHJ1Y3Rpb24gb3IgYnVuZGxlIHVzZXMgYQorICAvLy8gcGh5c2ljYWwgcmVnaXN0ZXIuICBUaGlzIGZ1bmN0aW9uIHNob3VsZCBub3QgYmUgY2FsbGVkIGFmdGVyIG9wZXJhdG9yKysoKSwKKyAgLy8vIGl0IGV4cGVjdHMgYSBmcmVzaCBpdGVyYXRvci4KKyAgLy8vCisgIC8vLyBAcGFyYW0gUmVnIFRoZSBwaHlzaWNhbCByZWdpc3RlciB0byBhbmFseXplLgorICAvLy8gQHJldHVybnMgQSBmaWxsZWQtaW4gUGh5c1JlZ0luZm8gc3RydWN0LgorICBQaHlzUmVnSW5mbyBhbmFseXplUGh5c1JlZyh1bnNpZ25lZCBSZWcsIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJKTsKK307CisKKy8vLyBNSU9wZXJhbmRzIC0gSXRlcmF0ZSBvdmVyIG9wZXJhbmRzIG9mIGEgc2luZ2xlIGluc3RydWN0aW9uLgorLy8vCitjbGFzcyBNSU9wZXJhbmRzIDogcHVibGljIE1hY2hpbmVPcGVyYW5kSXRlcmF0b3JCYXNlIHsKK3B1YmxpYzoKKyAgTUlPcGVyYW5kcyhNYWNoaW5lSW5zdHIgJk1JKSA6IE1hY2hpbmVPcGVyYW5kSXRlcmF0b3JCYXNlKE1JLCBmYWxzZSkge30KKyAgTWFjaGluZU9wZXJhbmQgJm9wZXJhdG9yKiAoKSBjb25zdCB7IHJldHVybiBkZXJlZigpOyB9CisgIE1hY2hpbmVPcGVyYW5kICpvcGVyYXRvci0+KCkgY29uc3QgeyByZXR1cm4gJmRlcmVmKCk7IH0KK307CisKKy8vLyBDb25zdE1JT3BlcmFuZHMgLSBJdGVyYXRlIG92ZXIgb3BlcmFuZHMgb2YgYSBzaW5nbGUgY29uc3QgaW5zdHJ1Y3Rpb24uCisvLy8KK2NsYXNzIENvbnN0TUlPcGVyYW5kcyA6IHB1YmxpYyBNYWNoaW5lT3BlcmFuZEl0ZXJhdG9yQmFzZSB7CitwdWJsaWM6CisgIENvbnN0TUlPcGVyYW5kcyhjb25zdCBNYWNoaW5lSW5zdHIgJk1JKQorICAgICAgOiBNYWNoaW5lT3BlcmFuZEl0ZXJhdG9yQmFzZShjb25zdF9jYXN0PE1hY2hpbmVJbnN0ciAmPihNSSksIGZhbHNlKSB7fQorICBjb25zdCBNYWNoaW5lT3BlcmFuZCAmb3BlcmF0b3IqICgpIGNvbnN0IHsgcmV0dXJuIGRlcmVmKCk7IH0KKyAgY29uc3QgTWFjaGluZU9wZXJhbmQgKm9wZXJhdG9yLT4oKSBjb25zdCB7IHJldHVybiAmZGVyZWYoKTsgfQorfTsKKworLy8vIE1JQnVuZGxlT3BlcmFuZHMgLSBJdGVyYXRlIG92ZXIgYWxsIG9wZXJhbmRzIGluIGEgYnVuZGxlIG9mIG1hY2hpbmUKKy8vLyBpbnN0cnVjdGlvbnMuCisvLy8KK2NsYXNzIE1JQnVuZGxlT3BlcmFuZHMgOiBwdWJsaWMgTWFjaGluZU9wZXJhbmRJdGVyYXRvckJhc2UgeworcHVibGljOgorICBNSUJ1bmRsZU9wZXJhbmRzKE1hY2hpbmVJbnN0ciAmTUkpIDogTWFjaGluZU9wZXJhbmRJdGVyYXRvckJhc2UoTUksIHRydWUpIHt9CisgIE1hY2hpbmVPcGVyYW5kICZvcGVyYXRvciogKCkgY29uc3QgeyByZXR1cm4gZGVyZWYoKTsgfQorICBNYWNoaW5lT3BlcmFuZCAqb3BlcmF0b3ItPigpIGNvbnN0IHsgcmV0dXJuICZkZXJlZigpOyB9Cit9OworCisvLy8gQ29uc3RNSUJ1bmRsZU9wZXJhbmRzIC0gSXRlcmF0ZSBvdmVyIGFsbCBvcGVyYW5kcyBpbiBhIGNvbnN0IGJ1bmRsZSBvZgorLy8vIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zLgorLy8vCitjbGFzcyBDb25zdE1JQnVuZGxlT3BlcmFuZHMgOiBwdWJsaWMgTWFjaGluZU9wZXJhbmRJdGVyYXRvckJhc2UgeworcHVibGljOgorICBDb25zdE1JQnVuZGxlT3BlcmFuZHMoY29uc3QgTWFjaGluZUluc3RyICZNSSkKKyAgICAgIDogTWFjaGluZU9wZXJhbmRJdGVyYXRvckJhc2UoY29uc3RfY2FzdDxNYWNoaW5lSW5zdHIgJj4oTUkpLCB0cnVlKSB7fQorICBjb25zdCBNYWNoaW5lT3BlcmFuZCAmb3BlcmF0b3IqICgpIGNvbnN0IHsgcmV0dXJuIGRlcmVmKCk7IH0KKyAgY29uc3QgTWFjaGluZU9wZXJhbmQgKm9wZXJhdG9yLT4oKSBjb25zdCB7IHJldHVybiAmZGVyZWYoKTsgfQorfTsKKworfSAvLyBFbmQgbGx2bSBuYW1lc3BhY2UKKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3IuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVmZTQ5NjQKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3IuaApAQCAtMCwwICsxLDI4OSBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9NYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvci5oIC0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBEZWZpbmVzIGFuIGl0ZXJhdG9yIGNsYXNzIHRoYXQgYnVuZGxlcyBNYWNoaW5lSW5zdHIuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORUlOU1RSQlVORExFSVRFUkFUT1JfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTUFDSElORUlOU1RSQlVORExFSVRFUkFUT1JfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvaWxpc3QuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9zaW1wbGVfaWxpc3QuaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPGl0ZXJhdG9yPgorI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgorCituYW1lc3BhY2UgbGx2bSB7CisKK3RlbXBsYXRlIDxjbGFzcyBULCBib29sIElzUmV2ZXJzZT4gc3RydWN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yVHJhaXRzOwordGVtcGxhdGUgPGNsYXNzIFQ+IHN0cnVjdCBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvclRyYWl0czxULCBmYWxzZT4geworICB1c2luZyBsaXN0X3R5cGUgPSBzaW1wbGVfaWxpc3Q8VCwgaWxpc3Rfc2VudGluZWxfdHJhY2tpbmc8dHJ1ZT4+OworICB1c2luZyBpbnN0cl9pdGVyYXRvciA9IHR5cGVuYW1lIGxpc3RfdHlwZTo6aXRlcmF0b3I7CisgIHVzaW5nIG5vbmNvbnN0X2luc3RyX2l0ZXJhdG9yID0gdHlwZW5hbWUgbGlzdF90eXBlOjppdGVyYXRvcjsKKyAgdXNpbmcgY29uc3RfaW5zdHJfaXRlcmF0b3IgPSB0eXBlbmFtZSBsaXN0X3R5cGU6OmNvbnN0X2l0ZXJhdG9yOworfTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3JUcmFpdHM8VCwgdHJ1ZT4geworICB1c2luZyBsaXN0X3R5cGUgPSBzaW1wbGVfaWxpc3Q8VCwgaWxpc3Rfc2VudGluZWxfdHJhY2tpbmc8dHJ1ZT4+OworICB1c2luZyBpbnN0cl9pdGVyYXRvciA9IHR5cGVuYW1lIGxpc3RfdHlwZTo6cmV2ZXJzZV9pdGVyYXRvcjsKKyAgdXNpbmcgbm9uY29uc3RfaW5zdHJfaXRlcmF0b3IgPSB0eXBlbmFtZSBsaXN0X3R5cGU6OnJldmVyc2VfaXRlcmF0b3I7CisgIHVzaW5nIGNvbnN0X2luc3RyX2l0ZXJhdG9yID0gdHlwZW5hbWUgbGlzdF90eXBlOjpjb25zdF9yZXZlcnNlX2l0ZXJhdG9yOworfTsKK3RlbXBsYXRlIDxjbGFzcyBUPiBzdHJ1Y3QgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3JUcmFpdHM8Y29uc3QgVCwgZmFsc2U+IHsKKyAgdXNpbmcgbGlzdF90eXBlID0gc2ltcGxlX2lsaXN0PFQsIGlsaXN0X3NlbnRpbmVsX3RyYWNraW5nPHRydWU+PjsKKyAgdXNpbmcgaW5zdHJfaXRlcmF0b3IgPSB0eXBlbmFtZSBsaXN0X3R5cGU6OmNvbnN0X2l0ZXJhdG9yOworICB1c2luZyBub25jb25zdF9pbnN0cl9pdGVyYXRvciA9IHR5cGVuYW1lIGxpc3RfdHlwZTo6aXRlcmF0b3I7CisgIHVzaW5nIGNvbnN0X2luc3RyX2l0ZXJhdG9yID0gdHlwZW5hbWUgbGlzdF90eXBlOjpjb25zdF9pdGVyYXRvcjsKK307Cit0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yVHJhaXRzPGNvbnN0IFQsIHRydWU+IHsKKyAgdXNpbmcgbGlzdF90eXBlID0gc2ltcGxlX2lsaXN0PFQsIGlsaXN0X3NlbnRpbmVsX3RyYWNraW5nPHRydWU+PjsKKyAgdXNpbmcgaW5zdHJfaXRlcmF0b3IgPSB0eXBlbmFtZSBsaXN0X3R5cGU6OmNvbnN0X3JldmVyc2VfaXRlcmF0b3I7CisgIHVzaW5nIG5vbmNvbnN0X2luc3RyX2l0ZXJhdG9yID0gdHlwZW5hbWUgbGlzdF90eXBlOjpyZXZlcnNlX2l0ZXJhdG9yOworICB1c2luZyBjb25zdF9pbnN0cl9pdGVyYXRvciA9IHR5cGVuYW1lIGxpc3RfdHlwZTo6Y29uc3RfcmV2ZXJzZV9pdGVyYXRvcjsKK307CisKK3RlbXBsYXRlIDxib29sIElzUmV2ZXJzZT4gc3RydWN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9ySGVscGVyOwordGVtcGxhdGUgPD4gc3RydWN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9ySGVscGVyPGZhbHNlPiB7CisgIC8vLyBHZXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgY3VycmVudCBidW5kbGUuCisgIHRlbXBsYXRlIDxjbGFzcyBJdGVyYXRvcj4gc3RhdGljIEl0ZXJhdG9yIGdldEJ1bmRsZUJlZ2luKEl0ZXJhdG9yIEkpIHsKKyAgICBpZiAoIUkuaXNFbmQoKSkKKyAgICAgIHdoaWxlIChJLT5pc0J1bmRsZWRXaXRoUHJlZCgpKQorICAgICAgICAtLUk7CisgICAgcmV0dXJuIEk7CisgIH0KKworICAvLy8gR2V0IHRoZSBmaW5hbCBub2RlIG9mIHRoZSBjdXJyZW50IGJ1bmRsZS4KKyAgdGVtcGxhdGUgPGNsYXNzIEl0ZXJhdG9yPiBzdGF0aWMgSXRlcmF0b3IgZ2V0QnVuZGxlRmluYWwoSXRlcmF0b3IgSSkgeworICAgIGlmICghSS5pc0VuZCgpKQorICAgICAgd2hpbGUgKEktPmlzQnVuZGxlZFdpdGhTdWNjKCkpCisgICAgICAgICsrSTsKKyAgICByZXR1cm4gSTsKKyAgfQorCisgIC8vLyBJbmNyZW1lbnQgZm9yd2FyZCBpbGlzdCBpdGVyYXRvci4KKyAgdGVtcGxhdGUgPGNsYXNzIEl0ZXJhdG9yPiBzdGF0aWMgdm9pZCBpbmNyZW1lbnQoSXRlcmF0b3IgJkkpIHsKKyAgICBJID0gc3RkOjpuZXh0KGdldEJ1bmRsZUZpbmFsKEkpKTsKKyAgfQorCisgIC8vLyBEZWNyZW1lbnQgZm9yd2FyZCBpbGlzdCBpdGVyYXRvci4KKyAgdGVtcGxhdGUgPGNsYXNzIEl0ZXJhdG9yPiBzdGF0aWMgdm9pZCBkZWNyZW1lbnQoSXRlcmF0b3IgJkkpIHsKKyAgICBJID0gZ2V0QnVuZGxlQmVnaW4oc3RkOjpwcmV2KEkpKTsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9ySGVscGVyPHRydWU+IHsKKyAgLy8vIEdldCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBjdXJyZW50IGJ1bmRsZS4KKyAgdGVtcGxhdGUgPGNsYXNzIEl0ZXJhdG9yPiBzdGF0aWMgSXRlcmF0b3IgZ2V0QnVuZGxlQmVnaW4oSXRlcmF0b3IgSSkgeworICAgIHJldHVybiBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvckhlbHBlcjxmYWxzZT46OmdldEJ1bmRsZUJlZ2luKAorICAgICAgICAgICAgICAgSS5nZXRSZXZlcnNlKCkpCisgICAgICAgIC5nZXRSZXZlcnNlKCk7CisgIH0KKworICAvLy8gR2V0IHRoZSBmaW5hbCBub2RlIG9mIHRoZSBjdXJyZW50IGJ1bmRsZS4KKyAgdGVtcGxhdGUgPGNsYXNzIEl0ZXJhdG9yPiBzdGF0aWMgSXRlcmF0b3IgZ2V0QnVuZGxlRmluYWwoSXRlcmF0b3IgSSkgeworICAgIHJldHVybiBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvckhlbHBlcjxmYWxzZT46OmdldEJ1bmRsZUZpbmFsKAorICAgICAgICAgICAgICAgSS5nZXRSZXZlcnNlKCkpCisgICAgICAgIC5nZXRSZXZlcnNlKCk7CisgIH0KKworICAvLy8gSW5jcmVtZW50IHJldmVyc2UgaWxpc3QgaXRlcmF0b3IuCisgIHRlbXBsYXRlIDxjbGFzcyBJdGVyYXRvcj4gc3RhdGljIHZvaWQgaW5jcmVtZW50KEl0ZXJhdG9yICZJKSB7CisgICAgSSA9IGdldEJ1bmRsZUJlZ2luKHN0ZDo6bmV4dChJKSk7CisgIH0KKworICAvLy8gRGVjcmVtZW50IHJldmVyc2UgaWxpc3QgaXRlcmF0b3IuCisgIHRlbXBsYXRlIDxjbGFzcyBJdGVyYXRvcj4gc3RhdGljIHZvaWQgZGVjcmVtZW50KEl0ZXJhdG9yICZJKSB7CisgICAgSSA9IHN0ZDo6cHJldihnZXRCdW5kbGVGaW5hbChJKSk7CisgIH0KK307CisKKy8vLyBNYWNoaW5lQmFzaWNCbG9jayBpdGVyYXRvciB0aGF0IGF1dG9tYXRpY2FsbHkgc2tpcHMgb3ZlciBNSXMgdGhhdCBhcmUKKy8vLyBpbnNpZGUgYnVuZGxlcyAoaS5lLiB3YWxrIHRvcCBsZXZlbCBNSXMgb25seSkuCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVHksIGJvb2wgSXNSZXZlcnNlID0gZmFsc2U+CitjbGFzcyBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvciA6IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9ySGVscGVyPElzUmV2ZXJzZT4geworICB1c2luZyBUcmFpdHMgPSBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvclRyYWl0czxUeSwgSXNSZXZlcnNlPjsKKyAgdXNpbmcgaW5zdHJfaXRlcmF0b3IgPSB0eXBlbmFtZSBUcmFpdHM6Omluc3RyX2l0ZXJhdG9yOworCisgIGluc3RyX2l0ZXJhdG9yIE1JSTsKKworcHVibGljOgorICB1c2luZyB2YWx1ZV90eXBlID0gdHlwZW5hbWUgaW5zdHJfaXRlcmF0b3I6OnZhbHVlX3R5cGU7CisgIHVzaW5nIGRpZmZlcmVuY2VfdHlwZSA9IHR5cGVuYW1lIGluc3RyX2l0ZXJhdG9yOjpkaWZmZXJlbmNlX3R5cGU7CisgIHVzaW5nIHBvaW50ZXIgPSB0eXBlbmFtZSBpbnN0cl9pdGVyYXRvcjo6cG9pbnRlcjsKKyAgdXNpbmcgcmVmZXJlbmNlID0gdHlwZW5hbWUgaW5zdHJfaXRlcmF0b3I6OnJlZmVyZW5jZTsKKyAgdXNpbmcgY29uc3RfcG9pbnRlciA9IHR5cGVuYW1lIGluc3RyX2l0ZXJhdG9yOjpjb25zdF9wb2ludGVyOworICB1c2luZyBjb25zdF9yZWZlcmVuY2UgPSB0eXBlbmFtZSBpbnN0cl9pdGVyYXRvcjo6Y29uc3RfcmVmZXJlbmNlOworICB1c2luZyBpdGVyYXRvcl9jYXRlZ29yeSA9IHN0ZDo6YmlkaXJlY3Rpb25hbF9pdGVyYXRvcl90YWc7CisKK3ByaXZhdGU6CisgIHVzaW5nIG5vbmNvbnN0X2luc3RyX2l0ZXJhdG9yID0gdHlwZW5hbWUgVHJhaXRzOjpub25jb25zdF9pbnN0cl9pdGVyYXRvcjsKKyAgdXNpbmcgY29uc3RfaW5zdHJfaXRlcmF0b3IgPSB0eXBlbmFtZSBUcmFpdHM6OmNvbnN0X2luc3RyX2l0ZXJhdG9yOworICB1c2luZyBub25jb25zdF9pdGVyYXRvciA9CisgICAgICBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvcjx0eXBlbmFtZSBub25jb25zdF9pbnN0cl9pdGVyYXRvcjo6dmFsdWVfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElzUmV2ZXJzZT47CisgIHVzaW5nIHJldmVyc2VfaXRlcmF0b3IgPSBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvcjxUeSwgIUlzUmV2ZXJzZT47CisKK3B1YmxpYzoKKyAgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3IoaW5zdHJfaXRlcmF0b3IgTUkpIDogTUlJKE1JKSB7CisgICAgYXNzZXJ0KCghTUkuZ2V0Tm9kZVB0cigpIHx8IE1JLmlzRW5kKCkgfHwgIU1JLT5pc0J1bmRsZWRXaXRoUHJlZCgpKSAmJgorICAgICAgICAgICAiSXQncyBub3QgbGVnYWwgdG8gaW5pdGlhbGl6ZSBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvciB3aXRoIGEgIgorICAgICAgICAgICAiYnVuZGxlZCBNSSIpOworICB9CisKKyAgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3IocmVmZXJlbmNlIE1JKSA6IE1JSShNSSkgeworICAgIGFzc2VydCghTUkuaXNCdW5kbGVkV2l0aFByZWQoKSAmJiAiSXQncyBub3QgbGVnYWwgdG8gaW5pdGlhbGl6ZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvciB3aXRoIGEgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYnVuZGxlZCBNSSIpOworICB9CisKKyAgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3IocG9pbnRlciBNSSkgOiBNSUkoTUkpIHsKKyAgICAvLyBGSVhNRTogVGhpcyBjb252ZXJzaW9uIHNob3VsZCBiZSBleHBsaWNpdC4KKyAgICBhc3NlcnQoKCFNSSB8fCAhTUktPmlzQnVuZGxlZFdpdGhQcmVkKCkpICYmICJJdCdzIG5vdCBsZWdhbCB0byBpbml0aWFsaXplICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvciAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2l0aCBhIGJ1bmRsZWQgTUkiKTsKKyAgfQorCisgIC8vIFRlbXBsYXRlIGFsbG93cyBjb252ZXJzaW9uIGZyb20gY29uc3QgdG8gbm9uY29uc3QuCisgIHRlbXBsYXRlIDxjbGFzcyBPdGhlclR5PgorICBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvcigKKyAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yPE90aGVyVHksIElzUmV2ZXJzZT4gJkksCisgICAgICB0eXBlbmFtZSBzdGQ6OmVuYWJsZV9pZjxzdGQ6OmlzX2NvbnZlcnRpYmxlPE90aGVyVHkgKiwgVHkgKj46OnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqPjo6dHlwZSA9IG51bGxwdHIpCisgICAgICA6IE1JSShJLmdldEluc3RySXRlcmF0b3IoKSkge30KKworICBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvcigpIDogTUlJKG51bGxwdHIpIHt9CisKKyAgLy8vIEV4cGxpY2l0IGNvbnZlcnNpb24gYmV0d2VlbiBmb3J3YXJkL3JldmVyc2UgaXRlcmF0b3JzLgorICAvLy8KKyAgLy8vIFRyYW5zbGF0ZSBiZXR3ZWVuIGZvcndhcmQgYW5kIHJldmVyc2UgaXRlcmF0b3JzIHdpdGhvdXQgY2hhbmdpbmcgcmFuZ2UKKyAgLy8vIGJvdW5kYXJpZXMuICBUaGUgcmVzdWx0aW5nIGl0ZXJhdG9yIHdpbGwgZGVyZWZlcmVuY2UgKGFuZCBoYXZlIGEgaGFuZGxlKQorICAvLy8gdG8gdGhlIHByZXZpb3VzIG5vZGUsIHdoaWNoIGlzIHNvbWV3aGF0IHVuZXhwZWN0ZWQ7IGJ1dCBjb252ZXJ0aW5nIHRoZQorICAvLy8gdHdvIGVuZHBvaW50cyBpbiBhIHJhbmdlIHdpbGwgZ2l2ZSB0aGUgc2FtZSByYW5nZSBpbiByZXZlcnNlLgorICAvLy8KKyAgLy8vIFRoaXMgbWF0Y2hlcyBzdGQ6OnJldmVyc2VfaXRlcmF0b3IgY29udmVyc2lvbnMuCisgIGV4cGxpY2l0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yKAorICAgICAgY29uc3QgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3I8VHksICFJc1JldmVyc2U+ICZJKQorICAgICAgOiBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvcigrK0kuZ2V0UmV2ZXJzZSgpKSB7fQorCisgIC8vLyBHZXQgdGhlIGJ1bmRsZSBpdGVyYXRvciBmb3IgdGhlIGdpdmVuIGluc3RydWN0aW9uJ3MgYnVuZGxlLgorICBzdGF0aWMgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3IgZ2V0QXRCdW5kbGVCZWdpbihpbnN0cl9pdGVyYXRvciBNSSkgeworICAgIHJldHVybiBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvckhlbHBlcjxJc1JldmVyc2U+OjpnZXRCdW5kbGVCZWdpbihNSSk7CisgIH0KKworICByZWZlcmVuY2Ugb3BlcmF0b3IqKCkgY29uc3QgeyByZXR1cm4gKk1JSTsgfQorICBwb2ludGVyIG9wZXJhdG9yLT4oKSBjb25zdCB7IHJldHVybiAmb3BlcmF0b3IqKCk7IH0KKworICAvLy8gQ2hlY2sgZm9yIG51bGwuCisgIGJvb2wgaXNWYWxpZCgpIGNvbnN0IHsgcmV0dXJuIE1JSS5nZXROb2RlUHRyKCk7IH0KKworICBmcmllbmQgYm9vbCBvcGVyYXRvcj09KGNvbnN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yICZMLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yICZSKSB7CisgICAgcmV0dXJuIEwuTUlJID09IFIuTUlJOworICB9CisgIGZyaWVuZCBib29sIG9wZXJhdG9yPT0oY29uc3QgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3IgJkwsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uc3RfaW5zdHJfaXRlcmF0b3IgJlIpIHsKKyAgICByZXR1cm4gTC5NSUkgPT0gUjsgLy8gQXZvaWQgYXNzZXJ0aW9uIGFib3V0IHZhbGlkaXR5IG9mIFIuCisgIH0KKyAgZnJpZW5kIGJvb2wgb3BlcmF0b3I9PShjb25zdCBjb25zdF9pbnN0cl9pdGVyYXRvciAmTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvciAmUikgeworICAgIHJldHVybiBMID09IFIuTUlJOyAvLyBBdm9pZCBhc3NlcnRpb24gYWJvdXQgdmFsaWRpdHkgb2YgTC4KKyAgfQorICBmcmllbmQgYm9vbCBvcGVyYXRvcj09KGNvbnN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yICZMLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vbmNvbnN0X2luc3RyX2l0ZXJhdG9yICZSKSB7CisgICAgcmV0dXJuIEwuTUlJID09IFI7IC8vIEF2b2lkIGFzc2VydGlvbiBhYm91dCB2YWxpZGl0eSBvZiBSLgorICB9CisgIGZyaWVuZCBib29sIG9wZXJhdG9yPT0oY29uc3Qgbm9uY29uc3RfaW5zdHJfaXRlcmF0b3IgJkwsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3IgJlIpIHsKKyAgICByZXR1cm4gTCA9PSBSLk1JSTsgLy8gQXZvaWQgYXNzZXJ0aW9uIGFib3V0IHZhbGlkaXR5IG9mIEwuCisgIH0KKyAgZnJpZW5kIGJvb2wgb3BlcmF0b3I9PShjb25zdCBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvciAmTCwgY29uc3RfcG9pbnRlciBSKSB7CisgICAgcmV0dXJuIEwgPT0gY29uc3RfaW5zdHJfaXRlcmF0b3IoUik7IC8vIEF2b2lkIGFzc2VydGlvbiBhYm91dCB2YWxpZGl0eSBvZiBSLgorICB9CisgIGZyaWVuZCBib29sIG9wZXJhdG9yPT0oY29uc3RfcG9pbnRlciBMLCBjb25zdCBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvciAmUikgeworICAgIHJldHVybiBjb25zdF9pbnN0cl9pdGVyYXRvcihMKSA9PSBSOyAvLyBBdm9pZCBhc3NlcnRpb24gYWJvdXQgdmFsaWRpdHkgb2YgTC4KKyAgfQorICBmcmllbmQgYm9vbCBvcGVyYXRvcj09KGNvbnN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yICZMLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0X3JlZmVyZW5jZSBSKSB7CisgICAgcmV0dXJuIEwgPT0gJlI7IC8vIEF2b2lkIGFzc2VydGlvbiBhYm91dCB2YWxpZGl0eSBvZiBSLgorICB9CisgIGZyaWVuZCBib29sIG9wZXJhdG9yPT0oY29uc3RfcmVmZXJlbmNlIEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3IgJlIpIHsKKyAgICByZXR1cm4gJkwgPT0gUjsgLy8gQXZvaWQgYXNzZXJ0aW9uIGFib3V0IHZhbGlkaXR5IG9mIEwuCisgIH0KKworICBmcmllbmQgYm9vbCBvcGVyYXRvciE9KGNvbnN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yICZMLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yICZSKSB7CisgICAgcmV0dXJuICEoTCA9PSBSKTsKKyAgfQorICBmcmllbmQgYm9vbCBvcGVyYXRvciE9KGNvbnN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yICZMLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0X2luc3RyX2l0ZXJhdG9yICZSKSB7CisgICAgcmV0dXJuICEoTCA9PSBSKTsKKyAgfQorICBmcmllbmQgYm9vbCBvcGVyYXRvciE9KGNvbnN0IGNvbnN0X2luc3RyX2l0ZXJhdG9yICZMLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yICZSKSB7CisgICAgcmV0dXJuICEoTCA9PSBSKTsKKyAgfQorICBmcmllbmQgYm9vbCBvcGVyYXRvciE9KGNvbnN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yICZMLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vbmNvbnN0X2luc3RyX2l0ZXJhdG9yICZSKSB7CisgICAgcmV0dXJuICEoTCA9PSBSKTsKKyAgfQorICBmcmllbmQgYm9vbCBvcGVyYXRvciE9KGNvbnN0IG5vbmNvbnN0X2luc3RyX2l0ZXJhdG9yICZMLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yICZSKSB7CisgICAgcmV0dXJuICEoTCA9PSBSKTsKKyAgfQorICBmcmllbmQgYm9vbCBvcGVyYXRvciE9KGNvbnN0IE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yICZMLCBjb25zdF9wb2ludGVyIFIpIHsKKyAgICByZXR1cm4gIShMID09IFIpOworICB9CisgIGZyaWVuZCBib29sIG9wZXJhdG9yIT0oY29uc3RfcG9pbnRlciBMLCBjb25zdCBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvciAmUikgeworICAgIHJldHVybiAhKEwgPT0gUik7CisgIH0KKyAgZnJpZW5kIGJvb2wgb3BlcmF0b3IhPShjb25zdCBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvciAmTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdF9yZWZlcmVuY2UgUikgeworICAgIHJldHVybiAhKEwgPT0gUik7CisgIH0KKyAgZnJpZW5kIGJvb2wgb3BlcmF0b3IhPShjb25zdF9yZWZlcmVuY2UgTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvciAmUikgeworICAgIHJldHVybiAhKEwgPT0gUik7CisgIH0KKworICAvLyBJbmNyZW1lbnQgYW5kIGRlY3JlbWVudCBvcGVyYXRvcnMuLi4KKyAgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3IgJm9wZXJhdG9yLS0oKSB7CisgICAgdGhpcy0+ZGVjcmVtZW50KE1JSSk7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yICZvcGVyYXRvcisrKCkgeworICAgIHRoaXMtPmluY3JlbWVudChNSUkpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorICBNYWNoaW5lSW5zdHJCdW5kbGVJdGVyYXRvciBvcGVyYXRvci0tKGludCkgeworICAgIE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yIFRlbXAgPSAqdGhpczsKKyAgICAtLSp0aGlzOworICAgIHJldHVybiBUZW1wOworICB9CisgIE1hY2hpbmVJbnN0ckJ1bmRsZUl0ZXJhdG9yIG9wZXJhdG9yKysoaW50KSB7CisgICAgTWFjaGluZUluc3RyQnVuZGxlSXRlcmF0b3IgVGVtcCA9ICp0aGlzOworICAgICsrKnRoaXM7CisgICAgcmV0dXJuIFRlbXA7CisgIH0KKworICBpbnN0cl9pdGVyYXRvciBnZXRJbnN0ckl0ZXJhdG9yKCkgY29uc3QgeyByZXR1cm4gTUlJOyB9CisKKyAgbm9uY29uc3RfaXRlcmF0b3IgZ2V0Tm9uQ29uc3RJdGVyYXRvcigpIGNvbnN0IHsgcmV0dXJuIE1JSS5nZXROb25Db25zdCgpOyB9CisKKyAgLy8vIEdldCBhIHJldmVyc2UgaXRlcmF0b3IgdG8gdGhlIHNhbWUgbm9kZS4KKyAgLy8vCisgIC8vLyBHaXZlcyBhIHJldmVyc2UgaXRlcmF0b3IgdGhhdCB3aWxsIGRlcmVmZXJlbmNlIChhbmQgaGF2ZSBhIGhhbmRsZSkgdG8gdGhlCisgIC8vLyBzYW1lIG5vZGUuICBDb252ZXJ0aW5nIHRoZSBlbmRwb2ludCBpdGVyYXRvcnMgaW4gYSByYW5nZSB3aWxsIGdpdmUgYQorICAvLy8gZGlmZmVyZW50IHJhbmdlOyBmb3IgcmFuZ2Ugb3BlcmF0aW9ucywgdXNlIHRoZSBleHBsaWNpdCBjb252ZXJzaW9ucy4KKyAgcmV2ZXJzZV9pdGVyYXRvciBnZXRSZXZlcnNlKCkgY29uc3QgeyByZXR1cm4gTUlJLmdldFJldmVyc2UoKTsgfQorfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9NQUNISU5FSU5TVFJCVU5ETEVJVEVSQVRPUl9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUp1bXBUYWJsZUluZm8uaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lSnVtcFRhYmxlSW5mby5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1YTNlNmIKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZUp1bXBUYWJsZUluZm8uaApAQCAtMCwwICsxLDE0MCBAQAorLy89PT0tLSBDb2RlR2VuL01hY2hpbmVKdW1wVGFibGVJbmZvLmggLSBBYnN0cmFjdCBKdW1wIFRhYmxlcyAgLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGUgTWFjaGluZUp1bXBUYWJsZUluZm8gY2xhc3Mga2VlcHMgdHJhY2sgb2YganVtcCB0YWJsZXMgcmVmZXJlbmNlZCBieQorLy8gbG93ZXJlZCBzd2l0Y2ggaW5zdHJ1Y3Rpb25zIGluIHRoZSBNYWNoaW5lRnVuY3Rpb24uCisvLworLy8gSW5zdHJ1Y3Rpb25zIHJlZmVyZW5jZSB0aGUgYWRkcmVzcyBvZiB0aGVzZSBqdW1wIHRhYmxlcyB0aHJvdWdoIHRoZSB1c2Ugb2YKKy8vIE1PX0p1bXBUYWJsZUluZGV4IHZhbHVlcy4gIFdoZW4gZW1pdHRpbmcgYXNzZW1ibHkgb3IgbWFjaGluZSBjb2RlLCB0aGVzZQorLy8gdmlydHVhbCBhZGRyZXNzIHJlZmVyZW5jZXMgYXJlIGNvbnZlcnRlZCB0byByZWZlciB0byB0aGUgYWRkcmVzcyBvZiB0aGUKKy8vIGZ1bmN0aW9uIGp1bXAgdGFibGVzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ0hJTkVKVU1QVEFCTEVJTkZPX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX01BQ0hJTkVKVU1QVEFCTEVJTkZPX0gKKworI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9QcmludGFibGUuaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNYWNoaW5lQmFzaWNCbG9jazsKK2NsYXNzIERhdGFMYXlvdXQ7CitjbGFzcyByYXdfb3N0cmVhbTsKKworLy8vIE1hY2hpbmVKdW1wVGFibGVFbnRyeSAtIE9uZSBqdW1wIHRhYmxlIGluIHRoZSBqdW1wIHRhYmxlIGluZm8uCisvLy8KK3N0cnVjdCBNYWNoaW5lSnVtcFRhYmxlRW50cnkgeworICAvLy8gTUJCcyAtIFRoZSB2ZWN0b3Igb2YgYmFzaWMgYmxvY2tzIGZyb20gd2hpY2ggdG8gY3JlYXRlIHRoZSBqdW1wIHRhYmxlLgorICBzdGQ6OnZlY3RvcjxNYWNoaW5lQmFzaWNCbG9jayo+IE1CQnM7CisKKyAgZXhwbGljaXQgTWFjaGluZUp1bXBUYWJsZUVudHJ5KGNvbnN0IHN0ZDo6dmVjdG9yPE1hY2hpbmVCYXNpY0Jsb2NrKj4gJk0pCisgIDogTUJCcyhNKSB7fQorfTsKKworY2xhc3MgTWFjaGluZUp1bXBUYWJsZUluZm8geworcHVibGljOgorICAvLy8gSlRFbnRyeUtpbmQgLSBUaGlzIGVudW0gaW5kaWNhdGVzIGhvdyBlYWNoIGVudHJ5IG9mIHRoZSBqdW1wIHRhYmxlIGlzCisgIC8vLyByZXByZXNlbnRlZCBhbmQgZW1pdHRlZC4KKyAgZW51bSBKVEVudHJ5S2luZCB7CisgICAgLy8vIEVLX0Jsb2NrQWRkcmVzcyAtIEVhY2ggZW50cnkgaXMgYSBwbGFpbiBhZGRyZXNzIG9mIGJsb2NrLCBlLmcuOgorICAgIC8vLyAgICAgLndvcmQgTEJCMTIzCisgICAgRUtfQmxvY2tBZGRyZXNzLAorCisgICAgLy8vIEVLX0dQUmVsNjRCbG9ja0FkZHJlc3MgLSBFYWNoIGVudHJ5IGlzIGFuIGFkZHJlc3Mgb2YgYmxvY2ssIGVuY29kZWQKKyAgICAvLy8gd2l0aCBhIHJlbG9jYXRpb24gYXMgZ3AtcmVsYXRpdmUsIGUuZy46CisgICAgLy8vICAgICAuZ3Bkd29yZCBMQkIxMjMKKyAgICBFS19HUFJlbDY0QmxvY2tBZGRyZXNzLAorCisgICAgLy8vIEVLX0dQUmVsMzJCbG9ja0FkZHJlc3MgLSBFYWNoIGVudHJ5IGlzIGFuIGFkZHJlc3Mgb2YgYmxvY2ssIGVuY29kZWQKKyAgICAvLy8gd2l0aCBhIHJlbG9jYXRpb24gYXMgZ3AtcmVsYXRpdmUsIGUuZy46CisgICAgLy8vICAgICAuZ3ByZWwzMiBMQkIxMjMKKyAgICBFS19HUFJlbDMyQmxvY2tBZGRyZXNzLAorCisgICAgLy8vIEVLX0xhYmVsRGlmZmVyZW5jZTMyIC0gRWFjaCBlbnRyeSBpcyB0aGUgYWRkcmVzcyBvZiB0aGUgYmxvY2sgbWludXMKKyAgICAvLy8gdGhlIGFkZHJlc3Mgb2YgdGhlIGp1bXAgdGFibGUuICBUaGlzIGlzIHVzZWQgZm9yIFBJQyBqdW1wIHRhYmxlcyB3aGVyZQorICAgIC8vLyBncHJlbDMyIGlzIG5vdCBzdXBwb3J0ZWQuICBlLmcuOgorICAgIC8vLyAgICAgIC53b3JkIExCQjEyMyAtIExKVEkxXzIKKyAgICAvLy8gSWYgdGhlIC5zZXQgZGlyZWN0aXZlIGlzIHN1cHBvcnRlZCwgdGhpcyBpcyBlbWl0dGVkIGFzOgorICAgIC8vLyAgICAgIC5zZXQgTDRfNV9zZXRfMTIzLCBMQkIxMjMgLSBMSlRJMV8yCisgICAgLy8vICAgICAgLndvcmQgTDRfNV9zZXRfMTIzCisgICAgRUtfTGFiZWxEaWZmZXJlbmNlMzIsCisKKyAgICAvLy8gRUtfSW5saW5lIC0gSnVtcCB0YWJsZSBlbnRyaWVzIGFyZSBlbWl0dGVkIGlubGluZSBhdCB0aGVpciBwb2ludCBvZgorICAgIC8vLyB1c2UuIEl0IGlzIHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgdGFyZ2V0IHRvIGVtaXQgdGhlIGVudHJpZXMuCisgICAgRUtfSW5saW5lLAorCisgICAgLy8vIEVLX0N1c3RvbTMyIC0gRWFjaCBlbnRyeSBpcyBhIDMyLWJpdCB2YWx1ZSB0aGF0IGlzIGN1c3RvbSBsb3dlcmVkIGJ5IHRoZQorICAgIC8vLyBUYXJnZXRMb3dlcmluZzo6TG93ZXJDdXN0b21KdW1wVGFibGVFbnRyeSBob29rLgorICAgIEVLX0N1c3RvbTMyCisgIH07Citwcml2YXRlOgorICBKVEVudHJ5S2luZCBFbnRyeUtpbmQ7CisgIHN0ZDo6dmVjdG9yPE1hY2hpbmVKdW1wVGFibGVFbnRyeT4gSnVtcFRhYmxlczsKK3B1YmxpYzoKKyAgZXhwbGljaXQgTWFjaGluZUp1bXBUYWJsZUluZm8oSlRFbnRyeUtpbmQgS2luZCk6IEVudHJ5S2luZChLaW5kKSB7fQorCisgIEpURW50cnlLaW5kIGdldEVudHJ5S2luZCgpIGNvbnN0IHsgcmV0dXJuIEVudHJ5S2luZDsgfQorCisgIC8vLyBnZXRFbnRyeVNpemUgLSBSZXR1cm4gdGhlIHNpemUgb2YgZWFjaCBlbnRyeSBpbiB0aGUganVtcCB0YWJsZS4KKyAgdW5zaWduZWQgZ2V0RW50cnlTaXplKGNvbnN0IERhdGFMYXlvdXQgJlREKSBjb25zdDsKKyAgLy8vIGdldEVudHJ5QWxpZ25tZW50IC0gUmV0dXJuIHRoZSBhbGlnbm1lbnQgb2YgZWFjaCBlbnRyeSBpbiB0aGUganVtcCB0YWJsZS4KKyAgdW5zaWduZWQgZ2V0RW50cnlBbGlnbm1lbnQoY29uc3QgRGF0YUxheW91dCAmVEQpIGNvbnN0OworCisgIC8vLyBjcmVhdGVKdW1wVGFibGVJbmRleCAtIENyZWF0ZSBhIG5ldyBqdW1wIHRhYmxlLgorICAvLy8KKyAgdW5zaWduZWQgY3JlYXRlSnVtcFRhYmxlSW5kZXgoY29uc3Qgc3RkOjp2ZWN0b3I8TWFjaGluZUJhc2ljQmxvY2sqPiAmRGVzdEJCcyk7CisKKyAgLy8vIGlzRW1wdHkgLSBSZXR1cm4gdHJ1ZSBpZiB0aGVyZSBhcmUgbm8ganVtcCB0YWJsZXMuCisgIC8vLworICBib29sIGlzRW1wdHkoKSBjb25zdCB7IHJldHVybiBKdW1wVGFibGVzLmVtcHR5KCk7IH0KKworICBjb25zdCBzdGQ6OnZlY3RvcjxNYWNoaW5lSnVtcFRhYmxlRW50cnk+ICZnZXRKdW1wVGFibGVzKCkgY29uc3QgeworICAgIHJldHVybiBKdW1wVGFibGVzOworICB9CisKKyAgLy8vIFJlbW92ZUp1bXBUYWJsZSAtIE1hcmsgdGhlIHNwZWNpZmljIGluZGV4IGFzIGJlaW5nIGRlYWQuICBUaGlzIHdpbGwKKyAgLy8vIHByZXZlbnQgaXQgZnJvbSBiZWluZyBlbWl0dGVkLgorICB2b2lkIFJlbW92ZUp1bXBUYWJsZSh1bnNpZ25lZCBJZHgpIHsKKyAgICBKdW1wVGFibGVzW0lkeF0uTUJCcy5jbGVhcigpOworICB9CisKKyAgLy8vIFJlcGxhY2VNQkJJbkp1bXBUYWJsZXMgLSBJZiBPbGQgaXMgdGhlIHRhcmdldCBvZiBhbnkganVtcCB0YWJsZXMsIHVwZGF0ZQorICAvLy8gdGhlIGp1bXAgdGFibGVzIHRvIGJyYW5jaCB0byBOZXcgaW5zdGVhZC4KKyAgYm9vbCBSZXBsYWNlTUJCSW5KdW1wVGFibGVzKE1hY2hpbmVCYXNpY0Jsb2NrICpPbGQsIE1hY2hpbmVCYXNpY0Jsb2NrICpOZXcpOworCisgIC8vLyBSZXBsYWNlTUJCSW5KdW1wVGFibGUgLSBJZiBPbGQgaXMgYSB0YXJnZXQgb2YgdGhlIGp1bXAgdGFibGVzLCB1cGRhdGUKKyAgLy8vIHRoZSBqdW1wIHRhYmxlIHRvIGJyYW5jaCB0byBOZXcgaW5zdGVhZC4KKyAgYm9vbCBSZXBsYWNlTUJCSW5KdW1wVGFibGUodW5zaWduZWQgSWR4LCBNYWNoaW5lQmFzaWNCbG9jayAqT2xkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jayAqTmV3KTsKKworICAvLy8gcHJpbnQgLSBVc2VkIGJ5IHRoZSBNYWNoaW5lRnVuY3Rpb24gcHJpbnRlciB0byBwcmludCBpbmZvcm1hdGlvbiBhYm91dAorICAvLy8ganVtcCB0YWJsZXMuICBJbXBsZW1lbnRlZCBpbiBNYWNoaW5lRnVuY3Rpb24uY3BwCisgIC8vLworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUykgY29uc3Q7CisKKyAgLy8vIGR1bXAgLSBDYWxsIHRvIHN0ZGVyci4KKyAgLy8vCisgIHZvaWQgZHVtcCgpIGNvbnN0OworfTsKKworCisvLy8gUHJpbnRzIGEganVtcCB0YWJsZSBlbnRyeSByZWZlcmVuY2UuCisvLy8KKy8vLyBUaGUgZm9ybWF0IGlzOgorLy8vICAgJWp1bXAtdGFibGUuNSAgICAgICAtIGEganVtcCB0YWJsZSBlbnRyeSB3aXRoIGluZGV4ID09IDUuCisvLy8KKy8vLyBVc2FnZTogT1MgPDwgcHJpbnRKdW1wVGFibGVFbnRyeVJlZmVyZW5jZShJZHgpIDw8ICdcbic7CitQcmludGFibGUgcHJpbnRKdW1wVGFibGVFbnRyeVJlZmVyZW5jZSh1bnNpZ25lZCBJZHgpOworCit9IC8vIEVuZCBsbHZtIG5hbWVzcGFjZQorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lTG9vcEluZm8uaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lTG9vcEluZm8uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMDQ2NTVlCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVMb29wSW5mby5oCkBAIC0wLDAgKzEsMTkzIEBACisvLz09PS0gbGx2bS9Db2RlR2VuL01hY2hpbmVMb29wSW5mby5oIC0gTmF0dXJhbCBMb29wIENhbGN1bGF0b3IgLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZWZpbmVzIHRoZSBNYWNoaW5lTG9vcEluZm8gY2xhc3MgdGhhdCBpcyB1c2VkIHRvIGlkZW50aWZ5IG5hdHVyYWwKKy8vIGxvb3BzIGFuZCBkZXRlcm1pbmUgdGhlIGxvb3AgZGVwdGggb2YgdmFyaW91cyBub2RlcyBvZiB0aGUgQ0ZHLiAgTm90ZSB0aGF0CisvLyBuYXR1cmFsIGxvb3BzIG1heSBhY3R1YWxseSBiZSBzZXZlcmFsIGxvb3BzIHRoYXQgc2hhcmUgdGhlIHNhbWUgaGVhZGVyIG5vZGUuCisvLworLy8gVGhpcyBhbmFseXNpcyBjYWxjdWxhdGVzIHRoZSBuZXN0aW5nIHN0cnVjdHVyZSBvZiBsb29wcyBpbiBhIGZ1bmN0aW9uLiAgRm9yCisvLyBlYWNoIG5hdHVyYWwgbG9vcCBpZGVudGlmaWVkLCB0aGlzIGFuYWx5c2lzIGlkZW50aWZpZXMgbmF0dXJhbCBsb29wcworLy8gY29udGFpbmVkIGVudGlyZWx5IHdpdGhpbiB0aGUgbG9vcCBhbmQgdGhlIGJhc2ljIGJsb2NrcyB0aGUgbWFrZSB1cCB0aGUgbG9vcC4KKy8vCisvLyBJdCBjYW4gY2FsY3VsYXRlIG9uIHRoZSBmbHkgdmFyaW91cyBiaXRzIG9mIGluZm9ybWF0aW9uLCBmb3IgZXhhbXBsZToKKy8vCisvLyAgKiB3aGV0aGVyIHRoZXJlIGlzIGEgcHJlaGVhZGVyIGZvciB0aGUgbG9vcAorLy8gICogdGhlIG51bWJlciBvZiBiYWNrIGVkZ2VzIHRvIHRoZSBoZWFkZXIKKy8vICAqIHdoZXRoZXIgb3Igbm90IGEgcGFydGljdWxhciBibG9jayBicmFuY2hlcyBvdXQgb2YgdGhlIGxvb3AKKy8vICAqIHRoZSBzdWNjZXNzb3IgYmxvY2tzIG9mIHRoZSBsb29wCisvLyAgKiB0aGUgbG9vcCBkZXB0aAorLy8gICogdGhlIHRyaXAgY291bnQKKy8vICAqIGV0Yy4uLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ0hJTkVMT09QSU5GT19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9NQUNISU5FTE9PUElORk9fSAorCisjaW5jbHVkZSAibGx2bS9BbmFseXNpcy9Mb29wSW5mby5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lQmFzaWNCbG9jay5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lRnVuY3Rpb25QYXNzLmgiCisjaW5jbHVkZSAibGx2bS9JUi9EZWJ1Z0xvYy5oIgorI2luY2x1ZGUgImxsdm0vUGFzcy5oIgorCituYW1lc3BhY2UgbGx2bSB7CisKKy8vIEltcGxlbWVudGF0aW9uIGluIExvb3BJbmZvSW1wbC5oCitjbGFzcyBNYWNoaW5lTG9vcDsKK2V4dGVybiB0ZW1wbGF0ZSBjbGFzcyBMb29wQmFzZTxNYWNoaW5lQmFzaWNCbG9jaywgTWFjaGluZUxvb3A+OworCitjbGFzcyBNYWNoaW5lTG9vcCA6IHB1YmxpYyBMb29wQmFzZTxNYWNoaW5lQmFzaWNCbG9jaywgTWFjaGluZUxvb3A+IHsKK3B1YmxpYzoKKyAgLy8vIFJldHVybiB0aGUgInRvcCIgYmxvY2sgaW4gdGhlIGxvb3AsIHdoaWNoIGlzIHRoZSBmaXJzdCBibG9jayBpbiB0aGUgbGluZWFyCisgIC8vLyBsYXlvdXQsIGlnbm9yaW5nIGFueSBwYXJ0cyBvZiB0aGUgbG9vcCBub3QgY29udGlndW91cyB3aXRoIHRoZSBwYXJ0IHRoYXQKKyAgLy8vIGNvbnRhaW5zIHRoZSBoZWFkZXIuCisgIE1hY2hpbmVCYXNpY0Jsb2NrICpnZXRUb3BCbG9jaygpOworCisgIC8vLyBSZXR1cm4gdGhlICJib3R0b20iIGJsb2NrIGluIHRoZSBsb29wLCB3aGljaCBpcyB0aGUgbGFzdCBibG9jayBpbiB0aGUKKyAgLy8vIGxpbmVhciBsYXlvdXQsIGlnbm9yaW5nIGFueSBwYXJ0cyBvZiB0aGUgbG9vcCBub3QgY29udGlndW91cyB3aXRoIHRoZSBwYXJ0CisgIC8vLyB0aGF0IGNvbnRhaW5zIHRoZSBoZWFkZXIuCisgIE1hY2hpbmVCYXNpY0Jsb2NrICpnZXRCb3R0b21CbG9jaygpOworCisgIC8vLyBcYnJpZWYgRmluZCB0aGUgYmxvY2sgdGhhdCBjb250YWlucyB0aGUgbG9vcCBjb250cm9sIHZhcmlhYmxlIGFuZCB0aGUKKyAgLy8vIGxvb3AgdGVzdC4gVGhpcyB3aWxsIHJldHVybiB0aGUgbGF0Y2ggYmxvY2sgaWYgaXQncyBvbmUgb2YgdGhlIGV4aXRpbmcKKyAgLy8vIGJsb2Nrcy4gT3RoZXJ3aXNlLCByZXR1cm4gdGhlIGV4aXRpbmcgYmxvY2suIFJldHVybiAnbnVsbCcgd2hlbgorICAvLy8gbXVsdGlwbGUgZXhpdGluZyBibG9ja3MgYXJlIHByZXNlbnQuCisgIE1hY2hpbmVCYXNpY0Jsb2NrICpmaW5kTG9vcENvbnRyb2xCbG9jaygpOworCisgIC8vLyBSZXR1cm4gdGhlIGRlYnVnIGxvY2F0aW9uIG9mIHRoZSBzdGFydCBvZiB0aGlzIGxvb3AuCisgIC8vLyBUaGlzIGxvb2tzIGZvciBhIEJCIHRlcm1pbmF0aW5nIGluc3RydWN0aW9uIHdpdGggYSBrbm93biBkZWJ1ZworICAvLy8gbG9jYXRpb24gYnkgbG9va2luZyBhdCB0aGUgcHJlaGVhZGVyIGFuZCBoZWFkZXIgYmxvY2tzLiBJZiBpdAorICAvLy8gY2Fubm90IGZpbmQgYSB0ZXJtaW5hdGluZyBpbnN0cnVjdGlvbiB3aXRoIGxvY2F0aW9uIGluZm9ybWF0aW9uLAorICAvLy8gaXQgcmV0dXJucyBhbiB1bmtub3duIGxvY2F0aW9uLgorICBEZWJ1Z0xvYyBnZXRTdGFydExvYygpIGNvbnN0OworCisgIHZvaWQgZHVtcCgpIGNvbnN0OworCitwcml2YXRlOgorICBmcmllbmQgY2xhc3MgTG9vcEluZm9CYXNlPE1hY2hpbmVCYXNpY0Jsb2NrLCBNYWNoaW5lTG9vcD47CisKKyAgZXhwbGljaXQgTWFjaGluZUxvb3AoTWFjaGluZUJhc2ljQmxvY2sgKk1CQikKKyAgICA6IExvb3BCYXNlPE1hY2hpbmVCYXNpY0Jsb2NrLCBNYWNoaW5lTG9vcD4oTUJCKSB7fQorCisgIE1hY2hpbmVMb29wKCkgPSBkZWZhdWx0OworfTsKKworLy8gSW1wbGVtZW50YXRpb24gaW4gTG9vcEluZm9JbXBsLmgKK2V4dGVybiB0ZW1wbGF0ZSBjbGFzcyBMb29wSW5mb0Jhc2U8TWFjaGluZUJhc2ljQmxvY2ssIE1hY2hpbmVMb29wPjsKKworY2xhc3MgTWFjaGluZUxvb3BJbmZvIDogcHVibGljIE1hY2hpbmVGdW5jdGlvblBhc3MgeworICBmcmllbmQgY2xhc3MgTG9vcEJhc2U8TWFjaGluZUJhc2ljQmxvY2ssIE1hY2hpbmVMb29wPjsKKworICBMb29wSW5mb0Jhc2U8TWFjaGluZUJhc2ljQmxvY2ssIE1hY2hpbmVMb29wPiBMSTsKKworcHVibGljOgorICBzdGF0aWMgY2hhciBJRDsgLy8gUGFzcyBpZGVudGlmaWNhdGlvbiwgcmVwbGFjZW1lbnQgZm9yIHR5cGVpZAorCisgIE1hY2hpbmVMb29wSW5mbygpIDogTWFjaGluZUZ1bmN0aW9uUGFzcyhJRCkgeworICAgIGluaXRpYWxpemVNYWNoaW5lTG9vcEluZm9QYXNzKCpQYXNzUmVnaXN0cnk6OmdldFBhc3NSZWdpc3RyeSgpKTsKKyAgfQorICBNYWNoaW5lTG9vcEluZm8oY29uc3QgTWFjaGluZUxvb3BJbmZvICYpID0gZGVsZXRlOworICBNYWNoaW5lTG9vcEluZm8gJm9wZXJhdG9yPShjb25zdCBNYWNoaW5lTG9vcEluZm8gJikgPSBkZWxldGU7CisKKyAgTG9vcEluZm9CYXNlPE1hY2hpbmVCYXNpY0Jsb2NrLCBNYWNoaW5lTG9vcD4mIGdldEJhc2UoKSB7IHJldHVybiBMSTsgfQorCisgIC8vLyBcYnJpZWYgRmluZCB0aGUgYmxvY2sgdGhhdCBlaXRoZXIgaXMgdGhlIGxvb3AgcHJlaGVhZGVyLCBvciBjb3VsZAorICAvLy8gc3BlY3VsYXRpdmVseSBiZSB1c2VkIGFzIHRoZSBwcmVoZWFkZXIuIFRoaXMgaXMgZS5nLiB1c2VmdWwgdG8gcGxhY2UKKyAgLy8vIGxvb3Agc2V0dXAgY29kZS4gQ29kZSB0aGF0IGNhbm5vdCBiZSBzcGVjdWxhdGVkIHNob3VsZCBub3QgYmUgcGxhY2VkCisgIC8vLyBoZXJlLiBTcGVjdWxhdGl2ZVByZWhlYWRlciBpcyBjb250cm9sbGluZyB3aGV0aGVyIGl0IGFsc28gdHJpZXMgdG8KKyAgLy8vIGZpbmQgdGhlIHNwZWN1bGF0aXZlIHByZWhlYWRlciBpZiB0aGUgcmVndWxhciBwcmVoZWFkZXIgaXMgbm90IHByZXNlbnQuCisgIE1hY2hpbmVCYXNpY0Jsb2NrICpmaW5kTG9vcFByZWhlYWRlcihNYWNoaW5lTG9vcCAqTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgU3BlY3VsYXRpdmVQcmVoZWFkZXIgPSBmYWxzZSkgY29uc3Q7CisKKyAgLy8vIFRoZSBpdGVyYXRvciBpbnRlcmZhY2UgdG8gdGhlIHRvcC1sZXZlbCBsb29wcyBpbiB0aGUgY3VycmVudCBmdW5jdGlvbi4KKyAgdXNpbmcgaXRlcmF0b3IgPSBMb29wSW5mb0Jhc2U8TWFjaGluZUJhc2ljQmxvY2ssIE1hY2hpbmVMb29wPjo6aXRlcmF0b3I7CisgIGlubGluZSBpdGVyYXRvciBiZWdpbigpIGNvbnN0IHsgcmV0dXJuIExJLmJlZ2luKCk7IH0KKyAgaW5saW5lIGl0ZXJhdG9yIGVuZCgpIGNvbnN0IHsgcmV0dXJuIExJLmVuZCgpOyB9CisgIGJvb2wgZW1wdHkoKSBjb25zdCB7IHJldHVybiBMSS5lbXB0eSgpOyB9CisKKyAgLy8vIFJldHVybiB0aGUgaW5uZXJtb3N0IGxvb3AgdGhhdCBCQiBsaXZlcyBpbi4gSWYgYSBiYXNpYyBibG9jayBpcyBpbiBubyBsb29wCisgIC8vLyAoZm9yIGV4YW1wbGUgdGhlIGVudHJ5IG5vZGUpLCBudWxsIGlzIHJldHVybmVkLgorICBpbmxpbmUgTWFjaGluZUxvb3AgKmdldExvb3BGb3IoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKkJCKSBjb25zdCB7CisgICAgcmV0dXJuIExJLmdldExvb3BGb3IoQkIpOworICB9CisKKyAgLy8vIFNhbWUgYXMgZ2V0TG9vcEZvci4KKyAgaW5saW5lIGNvbnN0IE1hY2hpbmVMb29wICpvcGVyYXRvcltdKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpCQikgY29uc3QgeworICAgIHJldHVybiBMSS5nZXRMb29wRm9yKEJCKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIGxvb3AgbmVzdGluZyBsZXZlbCBvZiB0aGUgc3BlY2lmaWVkIGJsb2NrLgorICBpbmxpbmUgdW5zaWduZWQgZ2V0TG9vcERlcHRoKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpCQikgY29uc3QgeworICAgIHJldHVybiBMSS5nZXRMb29wRGVwdGgoQkIpOworICB9CisKKyAgLy8vIFRydWUgaWYgdGhlIGJsb2NrIGlzIGEgbG9vcCBoZWFkZXIgbm9kZS4KKyAgaW5saW5lIGJvb2wgaXNMb29wSGVhZGVyKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpCQikgY29uc3QgeworICAgIHJldHVybiBMSS5pc0xvb3BIZWFkZXIoQkIpOworICB9CisKKyAgLy8vIENhbGN1bGF0ZSB0aGUgbmF0dXJhbCBsb29wIGluZm9ybWF0aW9uLgorICBib29sIHJ1bk9uTWFjaGluZUZ1bmN0aW9uKE1hY2hpbmVGdW5jdGlvbiAmRikgb3ZlcnJpZGU7CisKKyAgdm9pZCByZWxlYXNlTWVtb3J5KCkgb3ZlcnJpZGUgeyBMSS5yZWxlYXNlTWVtb3J5KCk7IH0KKworICB2b2lkIGdldEFuYWx5c2lzVXNhZ2UoQW5hbHlzaXNVc2FnZSAmQVUpIGNvbnN0IG92ZXJyaWRlOworCisgIC8vLyBUaGlzIHJlbW92ZXMgdGhlIHNwZWNpZmllZCB0b3AtbGV2ZWwgbG9vcCBmcm9tIHRoaXMgbG9vcCBpbmZvIG9iamVjdC4gVGhlCisgIC8vLyBsb29wIGlzIG5vdCBkZWxldGVkLCBhcyBpdCB3aWxsIHByZXN1bWFibHkgYmUgaW5zZXJ0ZWQgaW50byBhbm90aGVyIGxvb3AuCisgIGlubGluZSBNYWNoaW5lTG9vcCAqcmVtb3ZlTG9vcChpdGVyYXRvciBJKSB7IHJldHVybiBMSS5yZW1vdmVMb29wKEkpOyB9CisKKyAgLy8vIENoYW5nZSB0aGUgdG9wLWxldmVsIGxvb3AgdGhhdCBjb250YWlucyBCQiB0byB0aGUgc3BlY2lmaWVkIGxvb3AuIFRoaXMKKyAgLy8vIHNob3VsZCBiZSB1c2VkIGJ5IHRyYW5zZm9ybWF0aW9ucyB0aGF0IHJlc3RydWN0dXJlIHRoZSBsb29wIGhpZXJhcmNoeQorICAvLy8gdHJlZS4KKyAgaW5saW5lIHZvaWQgY2hhbmdlTG9vcEZvcihNYWNoaW5lQmFzaWNCbG9jayAqQkIsIE1hY2hpbmVMb29wICpMKSB7CisgICAgTEkuY2hhbmdlTG9vcEZvcihCQiwgTCk7CisgIH0KKworICAvLy8gUmVwbGFjZSB0aGUgc3BlY2lmaWVkIGxvb3AgaW4gdGhlIHRvcC1sZXZlbCBsb29wcyBsaXN0IHdpdGggdGhlIGluZGljYXRlZAorICAvLy8gbG9vcC4KKyAgaW5saW5lIHZvaWQgY2hhbmdlVG9wTGV2ZWxMb29wKE1hY2hpbmVMb29wICpPbGRMb29wLCBNYWNoaW5lTG9vcCAqTmV3TG9vcCkgeworICAgIExJLmNoYW5nZVRvcExldmVsTG9vcChPbGRMb29wLCBOZXdMb29wKTsKKyAgfQorCisgIC8vLyBUaGlzIGFkZHMgdGhlIHNwZWNpZmllZCBsb29wIHRvIHRoZSBjb2xsZWN0aW9uIG9mIHRvcC1sZXZlbCBsb29wcy4KKyAgaW5saW5lIHZvaWQgYWRkVG9wTGV2ZWxMb29wKE1hY2hpbmVMb29wICpOZXcpIHsKKyAgICBMSS5hZGRUb3BMZXZlbExvb3AoTmV3KTsKKyAgfQorCisgIC8vLyBUaGlzIG1ldGhvZCBjb21wbGV0ZWx5IHJlbW92ZXMgQkIgZnJvbSBhbGwgZGF0YSBzdHJ1Y3R1cmVzLCBpbmNsdWRpbmcgYWxsCisgIC8vLyBvZiB0aGUgTG9vcCBvYmplY3RzIGl0IGlzIG5lc3RlZCBpbiBhbmQgb3VyIG1hcHBpbmcgZnJvbQorICAvLy8gTWFjaGluZUJhc2ljQmxvY2tzIHRvIGxvb3BzLgorICB2b2lkIHJlbW92ZUJsb2NrKE1hY2hpbmVCYXNpY0Jsb2NrICpCQikgeworICAgIExJLnJlbW92ZUJsb2NrKEJCKTsKKyAgfQorfTsKKworLy8gQWxsb3cgY2xpZW50cyB0byB3YWxrIHRoZSBsaXN0IG9mIG5lc3RlZCBsb29wcy4uLgordGVtcGxhdGUgPD4gc3RydWN0IEdyYXBoVHJhaXRzPGNvbnN0IE1hY2hpbmVMb29wKj4geworICB1c2luZyBOb2RlUmVmID0gY29uc3QgTWFjaGluZUxvb3AgKjsKKyAgdXNpbmcgQ2hpbGRJdGVyYXRvclR5cGUgPSBNYWNoaW5lTG9vcEluZm86Oml0ZXJhdG9yOworCisgIHN0YXRpYyBOb2RlUmVmIGdldEVudHJ5Tm9kZShjb25zdCBNYWNoaW5lTG9vcCAqTCkgeyByZXR1cm4gTDsgfQorICBzdGF0aWMgQ2hpbGRJdGVyYXRvclR5cGUgY2hpbGRfYmVnaW4oTm9kZVJlZiBOKSB7IHJldHVybiBOLT5iZWdpbigpOyB9CisgIHN0YXRpYyBDaGlsZEl0ZXJhdG9yVHlwZSBjaGlsZF9lbmQoTm9kZVJlZiBOKSB7IHJldHVybiBOLT5lbmQoKTsgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IEdyYXBoVHJhaXRzPE1hY2hpbmVMb29wKj4geworICB1c2luZyBOb2RlUmVmID0gTWFjaGluZUxvb3AgKjsKKyAgdXNpbmcgQ2hpbGRJdGVyYXRvclR5cGUgPSBNYWNoaW5lTG9vcEluZm86Oml0ZXJhdG9yOworCisgIHN0YXRpYyBOb2RlUmVmIGdldEVudHJ5Tm9kZShNYWNoaW5lTG9vcCAqTCkgeyByZXR1cm4gTDsgfQorICBzdGF0aWMgQ2hpbGRJdGVyYXRvclR5cGUgY2hpbGRfYmVnaW4oTm9kZVJlZiBOKSB7IHJldHVybiBOLT5iZWdpbigpOyB9CisgIHN0YXRpYyBDaGlsZEl0ZXJhdG9yVHlwZSBjaGlsZF9lbmQoTm9kZVJlZiBOKSB7IHJldHVybiBOLT5lbmQoKTsgfQorfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9NQUNISU5FTE9PUElORk9fSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVNZW1PcGVyYW5kLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZU1lbU9wZXJhbmQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZWEwZDgwCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVNZW1PcGVyYW5kLmgKQEAgLTAsMCArMSwzMjkgQEAKKy8vPT0tIGxsdm0vQ29kZUdlbi9NYWNoaW5lTWVtT3BlcmFuZC5oIC0gTWFjaGluZU1lbU9wZXJhbmQgY2xhc3MgLSotIEMrKyAtKi09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBkZWNsYXJhdGlvbiBvZiB0aGUgTWFjaGluZU1lbU9wZXJhbmQgY2xhc3MsIHdoaWNoIGlzIGEKKy8vIGRlc2NyaXB0aW9uIG9mIGEgbWVtb3J5IHJlZmVyZW5jZS4gSXQgaXMgdXNlZCB0byBoZWxwIHRyYWNrIGRlcGVuZGVuY2llcworLy8gaW4gdGhlIGJhY2tlbmQuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORU1FTU9QRVJBTkRfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTUFDSElORU1FTU9QRVJBTkRfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvQml0bWFza0VudW0uaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9Qb2ludGVyVW5pb24uaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vUHNldWRvU291cmNlVmFsdWUuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0luc3RydWN0aW9ucy5oIgorI2luY2x1ZGUgImxsdm0vSVIvTWV0YWRhdGEuaCIKKyNpbmNsdWRlICJsbHZtL0lSL1ZhbHVlLmgiIC8vIFBvaW50ZXJMaWtlVHlwZVRyYWl0czxWYWx1ZSo+CisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0F0b21pY09yZGVyaW5nLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0RhdGFUeXBlcy5oIgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIEZvbGRpbmdTZXROb2RlSUQ7CitjbGFzcyBNRE5vZGU7CitjbGFzcyByYXdfb3N0cmVhbTsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIE1vZHVsZVNsb3RUcmFja2VyOworCisvLy8gVGhpcyBjbGFzcyBjb250YWlucyBhIGRpc2NyaW1pbmF0ZWQgdW5pb24gb2YgaW5mb3JtYXRpb24gYWJvdXQgcG9pbnRlcnMgaW4KKy8vLyBtZW1vcnkgb3BlcmFuZHMsIHJlbGF0aW5nIHRoZW0gYmFjayB0byBMTFZNIElSIG9yIHRvIHZpcnR1YWwgbG9jYXRpb25zIChzdWNoCisvLy8gYXMgZnJhbWUgaW5kaWNlcykgdGhhdCBhcmUgZXhwb3NlZCBkdXJpbmcgY29kZWdlbi4KK3N0cnVjdCBNYWNoaW5lUG9pbnRlckluZm8geworICAvLy8gVGhpcyBpcyB0aGUgSVIgcG9pbnRlciB2YWx1ZSBmb3IgdGhlIGFjY2Vzcywgb3IgaXQgaXMgbnVsbCBpZiB1bmtub3duLgorICAvLy8gSWYgdGhpcyBpcyBudWxsLCB0aGVuIHRoZSBhY2Nlc3MgaXMgdG8gYSBwb2ludGVyIGluIHRoZSBkZWZhdWx0IGFkZHJlc3MKKyAgLy8vIHNwYWNlLgorICBQb2ludGVyVW5pb248Y29uc3QgVmFsdWUgKiwgY29uc3QgUHNldWRvU291cmNlVmFsdWUgKj4gVjsKKworICAvLy8gT2Zmc2V0IC0gVGhpcyBpcyBhbiBvZmZzZXQgZnJvbSB0aGUgYmFzZSBWYWx1ZSouCisgIGludDY0X3QgT2Zmc2V0OworCisgIHVpbnQ4X3QgU3RhY2tJRDsKKworICB1bnNpZ25lZCBBZGRyU3BhY2UgPSAwOworCisgIGV4cGxpY2l0IE1hY2hpbmVQb2ludGVySW5mbyhjb25zdCBWYWx1ZSAqdiwgaW50NjRfdCBvZmZzZXQgPSAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCBJRCA9IDApCisgICAgICA6IFYodiksIE9mZnNldChvZmZzZXQpLCBTdGFja0lEKElEKSB7CisgICAgQWRkclNwYWNlID0gdiA/IHYtPmdldFR5cGUoKS0+Z2V0UG9pbnRlckFkZHJlc3NTcGFjZSgpIDogMDsKKyAgfQorCisgIGV4cGxpY2l0IE1hY2hpbmVQb2ludGVySW5mbyhjb25zdCBQc2V1ZG9Tb3VyY2VWYWx1ZSAqdiwgaW50NjRfdCBvZmZzZXQgPSAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCBJRCA9IDApCisgICAgICA6IFYodiksIE9mZnNldChvZmZzZXQpLCBTdGFja0lEKElEKSB7CisgICAgQWRkclNwYWNlID0gdiA/IHYtPmdldEFkZHJlc3NTcGFjZSgpIDogMDsKKyAgfQorCisgIGV4cGxpY2l0IE1hY2hpbmVQb2ludGVySW5mbyh1bnNpZ25lZCBBZGRyZXNzU3BhY2UgPSAwKQorICAgICAgOiBWKChjb25zdCBWYWx1ZSAqKW51bGxwdHIpLCBPZmZzZXQoMCksIFN0YWNrSUQoMCksCisgICAgICAgIEFkZHJTcGFjZShBZGRyZXNzU3BhY2UpIHt9CisKKyAgZXhwbGljaXQgTWFjaGluZVBvaW50ZXJJbmZvKAorICAgIFBvaW50ZXJVbmlvbjxjb25zdCBWYWx1ZSAqLCBjb25zdCBQc2V1ZG9Tb3VyY2VWYWx1ZSAqPiB2LAorICAgIGludDY0X3Qgb2Zmc2V0ID0gMCwKKyAgICB1aW50OF90IElEID0gMCkKKyAgICA6IFYodiksIE9mZnNldChvZmZzZXQpLCBTdGFja0lEKElEKSB7CisgICAgaWYgKFYpIHsKKyAgICAgIGlmIChjb25zdCBhdXRvICpWYWxQdHIgPSBWLmR5bl9jYXN0PGNvbnN0IFZhbHVlKj4oKSkKKyAgICAgICAgQWRkclNwYWNlID0gVmFsUHRyLT5nZXRUeXBlKCktPmdldFBvaW50ZXJBZGRyZXNzU3BhY2UoKTsKKyAgICAgIGVsc2UKKyAgICAgICAgQWRkclNwYWNlID0gVi5nZXQ8Y29uc3QgUHNldWRvU291cmNlVmFsdWUqPigpLT5nZXRBZGRyZXNzU3BhY2UoKTsKKyAgICB9CisgIH0KKworICBNYWNoaW5lUG9pbnRlckluZm8gZ2V0V2l0aE9mZnNldChpbnQ2NF90IE8pIGNvbnN0IHsKKyAgICBpZiAoVi5pc051bGwoKSkKKyAgICAgIHJldHVybiBNYWNoaW5lUG9pbnRlckluZm8oQWRkclNwYWNlKTsKKyAgICBpZiAoVi5pczxjb25zdCBWYWx1ZSo+KCkpCisgICAgICByZXR1cm4gTWFjaGluZVBvaW50ZXJJbmZvKFYuZ2V0PGNvbnN0IFZhbHVlKj4oKSwgT2Zmc2V0K08sIFN0YWNrSUQpOworICAgIHJldHVybiBNYWNoaW5lUG9pbnRlckluZm8oVi5nZXQ8Y29uc3QgUHNldWRvU291cmNlVmFsdWUqPigpLCBPZmZzZXQrTywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YWNrSUQpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIG1lbW9yeSByZWdpb24gW1YsIFYrT2Zmc2V0K1NpemUpIGlzIGtub3duIHRvIGJlCisgIC8vLyBkZXJlZmVyZW5jZWFibGUuCisgIGJvb2wgaXNEZXJlZmVyZW5jZWFibGUodW5zaWduZWQgU2l6ZSwgTExWTUNvbnRleHQgJkMsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGF0YUxheW91dCAmREwpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdGhlIExMVk0gSVIgYWRkcmVzcyBzcGFjZSBudW1iZXIgdGhhdCB0aGlzIHBvaW50ZXIgcG9pbnRzIGludG8uCisgIHVuc2lnbmVkIGdldEFkZHJTcGFjZSgpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gYSBNYWNoaW5lUG9pbnRlckluZm8gcmVjb3JkIHRoYXQgcmVmZXJzIHRvIHRoZSBjb25zdGFudCBwb29sLgorICBzdGF0aWMgTWFjaGluZVBvaW50ZXJJbmZvIGdldENvbnN0YW50UG9vbChNYWNoaW5lRnVuY3Rpb24gJk1GKTsKKworICAvLy8gUmV0dXJuIGEgTWFjaGluZVBvaW50ZXJJbmZvIHJlY29yZCB0aGF0IHJlZmVycyB0byB0aGUgc3BlY2lmaWVkCisgIC8vLyBGcmFtZUluZGV4LgorICBzdGF0aWMgTWFjaGluZVBvaW50ZXJJbmZvIGdldEZpeGVkU3RhY2soTWFjaGluZUZ1bmN0aW9uICZNRiwgaW50IEZJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50NjRfdCBPZmZzZXQgPSAwKTsKKworICAvLy8gUmV0dXJuIGEgTWFjaGluZVBvaW50ZXJJbmZvIHJlY29yZCB0aGF0IHJlZmVycyB0byBhIGp1bXAgdGFibGUgZW50cnkuCisgIHN0YXRpYyBNYWNoaW5lUG9pbnRlckluZm8gZ2V0SnVtcFRhYmxlKE1hY2hpbmVGdW5jdGlvbiAmTUYpOworCisgIC8vLyBSZXR1cm4gYSBNYWNoaW5lUG9pbnRlckluZm8gcmVjb3JkIHRoYXQgcmVmZXJzIHRvIGEgR09UIGVudHJ5LgorICBzdGF0aWMgTWFjaGluZVBvaW50ZXJJbmZvIGdldEdPVChNYWNoaW5lRnVuY3Rpb24gJk1GKTsKKworICAvLy8gU3RhY2sgcG9pbnRlciByZWxhdGl2ZSBhY2Nlc3MuCisgIHN0YXRpYyBNYWNoaW5lUG9pbnRlckluZm8gZ2V0U3RhY2soTWFjaGluZUZ1bmN0aW9uICZNRiwgaW50NjRfdCBPZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCBJRCA9IDApOworCisgIC8vLyBTdGFjayBtZW1vcnkgd2l0aG91dCBvdGhlciBpbmZvcm1hdGlvbi4KKyAgc3RhdGljIE1hY2hpbmVQb2ludGVySW5mbyBnZXRVbmtub3duU3RhY2soTWFjaGluZUZ1bmN0aW9uICZNRik7Cit9OworCisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gQSBkZXNjcmlwdGlvbiBvZiBhIG1lbW9yeSByZWZlcmVuY2UgdXNlZCBpbiB0aGUgYmFja2VuZC4KKy8vLyBJbnN0ZWFkIG9mIGhvbGRpbmcgYSBTdG9yZUluc3Qgb3IgTG9hZEluc3QsIHRoaXMgY2xhc3MgaG9sZHMgdGhlIGFkZHJlc3MKKy8vLyBWYWx1ZSBvZiB0aGUgcmVmZXJlbmNlIGFsb25nIHdpdGggYSBieXRlIHNpemUgYW5kIG9mZnNldC4gVGhpcyBhbGxvd3MgaXQKKy8vLyB0byBkZXNjcmliZSBsb3dlcmVkIGxvYWRzIGFuZCBzdG9yZXMuIEFsc28sIHRoZSBzcGVjaWFsIFBzZXVkb1NvdXJjZVZhbHVlCisvLy8gb2JqZWN0cyBjYW4gYmUgdXNlZCB0byByZXByZXNlbnQgbG9hZHMgYW5kIHN0b3JlcyB0byBtZW1vcnkgbG9jYXRpb25zCisvLy8gdGhhdCBhcmVuJ3QgZXhwbGljaXQgaW4gdGhlIHJlZ3VsYXIgTExWTSBJUi4KKy8vLworY2xhc3MgTWFjaGluZU1lbU9wZXJhbmQgeworcHVibGljOgorICAvLy8gRmxhZ3MgdmFsdWVzLiBUaGVzZSBtYXkgYmUgb3InZCB0b2dldGhlci4KKyAgZW51bSBGbGFncyA6IHVpbnQxNl90IHsKKyAgICAvLyBObyBmbGFncyBzZXQuCisgICAgTU9Ob25lID0gMCwKKyAgICAvLy8gVGhlIG1lbW9yeSBhY2Nlc3MgcmVhZHMgZGF0YS4KKyAgICBNT0xvYWQgPSAxdSA8PCAwLAorICAgIC8vLyBUaGUgbWVtb3J5IGFjY2VzcyB3cml0ZXMgZGF0YS4KKyAgICBNT1N0b3JlID0gMXUgPDwgMSwKKyAgICAvLy8gVGhlIG1lbW9yeSBhY2Nlc3MgaXMgdm9sYXRpbGUuCisgICAgTU9Wb2xhdGlsZSA9IDF1IDw8IDIsCisgICAgLy8vIFRoZSBtZW1vcnkgYWNjZXNzIGlzIG5vbi10ZW1wb3JhbC4KKyAgICBNT05vblRlbXBvcmFsID0gMXUgPDwgMywKKyAgICAvLy8gVGhlIG1lbW9yeSBhY2Nlc3MgaXMgZGVyZWZlcmVuY2VhYmxlIChpLmUuLCBkb2Vzbid0IHRyYXApLgorICAgIE1PRGVyZWZlcmVuY2VhYmxlID0gMXUgPDwgNCwKKyAgICAvLy8gVGhlIG1lbW9yeSBhY2Nlc3MgYWx3YXlzIHJldHVybnMgdGhlIHNhbWUgdmFsdWUgKG9yIHRyYXBzKS4KKyAgICBNT0ludmFyaWFudCA9IDF1IDw8IDUsCisKKyAgICAvLyBSZXNlcnZlZCBmb3IgdXNlIGJ5IHRhcmdldC1zcGVjaWZpYyBwYXNzZXMuCisgICAgLy8gVGFyZ2V0cyBtYXkgb3ZlcnJpZGUgZ2V0U2VyaWFsaXphYmxlTWFjaGluZU1lbU9wZXJhbmRUYXJnZXRGbGFncygpIHRvCisgICAgLy8gZW5hYmxlIE1JUiBzZXJpYWxpemF0aW9uL3BhcnNpbmcgb2YgdGhlc2UgZmxhZ3MuICBJZiBtb3JlIG9mIHRoZXNlIGZsYWdzCisgICAgLy8gYXJlIGFkZGVkLCB0aGUgTUlSIHByaW50aW5nL3BhcnNpbmcgY29kZSB3aWxsIG5lZWQgdG8gYmUgdXBkYXRlZCBhcyB3ZWxsLgorICAgIE1PVGFyZ2V0RmxhZzEgPSAxdSA8PCA2LAorICAgIE1PVGFyZ2V0RmxhZzIgPSAxdSA8PCA3LAorICAgIE1PVGFyZ2V0RmxhZzMgPSAxdSA8PCA4LAorCisgICAgTExWTV9NQVJLX0FTX0JJVE1BU0tfRU5VTSgvKiBMYXJnZXN0RmxhZyA9ICovIE1PVGFyZ2V0RmxhZzMpCisgIH07CisKK3ByaXZhdGU6CisgIC8vLyBBdG9taWMgaW5mb3JtYXRpb24gZm9yIHRoaXMgbWVtb3J5IG9wZXJhdGlvbi4KKyAgc3RydWN0IE1hY2hpbmVBdG9taWNJbmZvIHsKKyAgICAvLy8gU3luY2hyb25pemF0aW9uIHNjb3BlIElEIGZvciB0aGlzIG1lbW9yeSBvcGVyYXRpb24uCisgICAgdW5zaWduZWQgU1NJRCA6IDg7ICAgICAgICAgICAgLy8gU3luY1Njb3BlOjpJRAorICAgIC8vLyBBdG9taWMgb3JkZXJpbmcgcmVxdWlyZW1lbnRzIGZvciB0aGlzIG1lbW9yeSBvcGVyYXRpb24uIEZvciBjbXB4Y2hnCisgICAgLy8vIGF0b21pYyBvcGVyYXRpb25zLCBhdG9taWMgb3JkZXJpbmcgcmVxdWlyZW1lbnRzIHdoZW4gc3RvcmUgb2NjdXJzLgorICAgIHVuc2lnbmVkIE9yZGVyaW5nIDogNDsgICAgICAgIC8vIGVudW0gQXRvbWljT3JkZXJpbmcKKyAgICAvLy8gRm9yIGNtcHhjaGcgYXRvbWljIG9wZXJhdGlvbnMsIGF0b21pYyBvcmRlcmluZyByZXF1aXJlbWVudHMgd2hlbiBzdG9yZQorICAgIC8vLyBkb2VzIG5vdCBvY2N1ci4KKyAgICB1bnNpZ25lZCBGYWlsdXJlT3JkZXJpbmcgOiA0OyAvLyBlbnVtIEF0b21pY09yZGVyaW5nCisgIH07CisKKyAgTWFjaGluZVBvaW50ZXJJbmZvIFB0ckluZm87CisgIHVpbnQ2NF90IFNpemU7CisgIEZsYWdzIEZsYWdWYWxzOworICB1aW50MTZfdCBCYXNlQWxpZ25Mb2cyOyAvLyBsb2dfMihiYXNlX2FsaWdubWVudCkgKyAxCisgIE1hY2hpbmVBdG9taWNJbmZvIEF0b21pY0luZm87CisgIEFBTUROb2RlcyBBQUluZm87CisgIGNvbnN0IE1ETm9kZSAqUmFuZ2VzOworCitwdWJsaWM6CisgIC8vLyBDb25zdHJ1Y3QgYSBNYWNoaW5lTWVtT3BlcmFuZCBvYmplY3Qgd2l0aCB0aGUgc3BlY2lmaWVkIFB0ckluZm8sIGZsYWdzLAorICAvLy8gc2l6ZSwgYW5kIGJhc2UgYWxpZ25tZW50LiBGb3IgYXRvbWljIG9wZXJhdGlvbnMgdGhlIHN5bmNocm9uaXphdGlvbiBzY29wZQorICAvLy8gYW5kIGF0b21pYyBvcmRlcmluZyByZXF1aXJlbWVudHMgbXVzdCBhbHNvIGJlIHNwZWNpZmllZC4gRm9yIGNtcHhjaGcKKyAgLy8vIGF0b21pYyBvcGVyYXRpb25zIHRoZSBhdG9taWMgb3JkZXJpbmcgcmVxdWlyZW1lbnRzIHdoZW4gc3RvcmUgZG9lcyBub3QKKyAgLy8vIG9jY3VyIG11c3QgYWxzbyBiZSBzcGVjaWZpZWQuCisgIE1hY2hpbmVNZW1PcGVyYW5kKE1hY2hpbmVQb2ludGVySW5mbyBQdHJJbmZvLCBGbGFncyBmbGFncywgdWludDY0X3QgcywKKyAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgYmFzZV9hbGlnbm1lbnQsCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFBTUROb2RlcyAmQUFJbmZvID0gQUFNRE5vZGVzKCksCisgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1ETm9kZSAqUmFuZ2VzID0gbnVsbHB0ciwKKyAgICAgICAgICAgICAgICAgICAgU3luY1Njb3BlOjpJRCBTU0lEID0gU3luY1Njb3BlOjpTeXN0ZW0sCisgICAgICAgICAgICAgICAgICAgIEF0b21pY09yZGVyaW5nIE9yZGVyaW5nID0gQXRvbWljT3JkZXJpbmc6Ok5vdEF0b21pYywKKyAgICAgICAgICAgICAgICAgICAgQXRvbWljT3JkZXJpbmcgRmFpbHVyZU9yZGVyaW5nID0gQXRvbWljT3JkZXJpbmc6Ok5vdEF0b21pYyk7CisKKyAgY29uc3QgTWFjaGluZVBvaW50ZXJJbmZvICZnZXRQb2ludGVySW5mbygpIGNvbnN0IHsgcmV0dXJuIFB0ckluZm87IH0KKworICAvLy8gUmV0dXJuIHRoZSBiYXNlIGFkZHJlc3Mgb2YgdGhlIG1lbW9yeSBhY2Nlc3MuIFRoaXMgbWF5IGVpdGhlciBiZSBhIG5vcm1hbAorICAvLy8gTExWTSBJUiBWYWx1ZSwgb3Igb25lIG9mIHRoZSBzcGVjaWFsIHZhbHVlcyB1c2VkIGluIENvZGVHZW4uCisgIC8vLyBTcGVjaWFsIHZhbHVlcyBhcmUgdGhvc2Ugb2J0YWluZWQgdmlhCisgIC8vLyBQc2V1ZG9Tb3VyY2VWYWx1ZTo6Z2V0Rml4ZWRTdGFjayhpbnQpLCBQc2V1ZG9Tb3VyY2VWYWx1ZTo6Z2V0U3RhY2ssIGFuZAorICAvLy8gb3RoZXIgUHNldWRvU291cmNlVmFsdWUgbWVtYmVyIGZ1bmN0aW9ucyB3aGljaCByZXR1cm4gb2JqZWN0cyB3aGljaCBzdGFuZAorICAvLy8gZm9yIGZyYW1lL3N0YWNrIHBvaW50ZXIgcmVsYXRpdmUgcmVmZXJlbmNlcyBhbmQgb3RoZXIgc3BlY2lhbCByZWZlcmVuY2VzCisgIC8vLyB3aGljaCBhcmUgbm90IHJlcHJlc2VudGFibGUgaW4gdGhlIGhpZ2gtbGV2ZWwgSVIuCisgIGNvbnN0IFZhbHVlICpnZXRWYWx1ZSgpIGNvbnN0IHsgcmV0dXJuIFB0ckluZm8uVi5keW5fY2FzdDxjb25zdCBWYWx1ZSo+KCk7IH0KKworICBjb25zdCBQc2V1ZG9Tb3VyY2VWYWx1ZSAqZ2V0UHNldWRvVmFsdWUoKSBjb25zdCB7CisgICAgcmV0dXJuIFB0ckluZm8uVi5keW5fY2FzdDxjb25zdCBQc2V1ZG9Tb3VyY2VWYWx1ZSo+KCk7CisgIH0KKworICBjb25zdCB2b2lkICpnZXRPcGFxdWVWYWx1ZSgpIGNvbnN0IHsgcmV0dXJuIFB0ckluZm8uVi5nZXRPcGFxdWVWYWx1ZSgpOyB9CisKKyAgLy8vIFJldHVybiB0aGUgcmF3IGZsYWdzIG9mIHRoZSBzb3VyY2UgdmFsdWUsIFxzZWUgRmxhZ3MuCisgIEZsYWdzIGdldEZsYWdzKCkgY29uc3QgeyByZXR1cm4gRmxhZ1ZhbHM7IH0KKworICAvLy8gQml0d2lzZSBPUiB0aGUgY3VycmVudCBmbGFncyB3aXRoIHRoZSBnaXZlbiBmbGFncy4KKyAgdm9pZCBzZXRGbGFncyhGbGFncyBmKSB7IEZsYWdWYWxzIHw9IGY7IH0KKworICAvLy8gRm9yIG5vcm1hbCB2YWx1ZXMsIHRoaXMgaXMgYSBieXRlIG9mZnNldCBhZGRlZCB0byB0aGUgYmFzZSBhZGRyZXNzLgorICAvLy8gRm9yIFBzZXVkb1NvdXJjZVZhbHVlOjpGUFJlbCB2YWx1ZXMsIHRoaXMgaXMgdGhlIEZyYW1lSW5kZXggbnVtYmVyLgorICBpbnQ2NF90IGdldE9mZnNldCgpIGNvbnN0IHsgcmV0dXJuIFB0ckluZm8uT2Zmc2V0OyB9CisKKyAgdW5zaWduZWQgZ2V0QWRkclNwYWNlKCkgY29uc3QgeyByZXR1cm4gUHRySW5mby5nZXRBZGRyU3BhY2UoKTsgfQorCisgIC8vLyBSZXR1cm4gdGhlIHNpemUgaW4gYnl0ZXMgb2YgdGhlIG1lbW9yeSByZWZlcmVuY2UuCisgIHVpbnQ2NF90IGdldFNpemUoKSBjb25zdCB7IHJldHVybiBTaXplOyB9CisKKyAgLy8vIFJldHVybiB0aGUgbWluaW11bSBrbm93biBhbGlnbm1lbnQgaW4gYnl0ZXMgb2YgdGhlIGFjdHVhbCBtZW1vcnkKKyAgLy8vIHJlZmVyZW5jZS4KKyAgdWludDY0X3QgZ2V0QWxpZ25tZW50KCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0aGUgbWluaW11bSBrbm93biBhbGlnbm1lbnQgaW4gYnl0ZXMgb2YgdGhlIGJhc2UgYWRkcmVzcywgd2l0aG91dAorICAvLy8gdGhlIG9mZnNldC4KKyAgdWludDY0X3QgZ2V0QmFzZUFsaWdubWVudCgpIGNvbnN0IHsgcmV0dXJuICgxdSA8PCBCYXNlQWxpZ25Mb2cyKSA+PiAxOyB9CisKKyAgLy8vIFJldHVybiB0aGUgQUEgdGFncyBmb3IgdGhlIG1lbW9yeSByZWZlcmVuY2UuCisgIEFBTUROb2RlcyBnZXRBQUluZm8oKSBjb25zdCB7IHJldHVybiBBQUluZm87IH0KKworICAvLy8gUmV0dXJuIHRoZSByYW5nZSB0YWcgZm9yIHRoZSBtZW1vcnkgcmVmZXJlbmNlLgorICBjb25zdCBNRE5vZGUgKmdldFJhbmdlcygpIGNvbnN0IHsgcmV0dXJuIFJhbmdlczsgfQorCisgIC8vLyBSZXR1cm5zIHRoZSBzeW5jaHJvbml6YXRpb24gc2NvcGUgSUQgZm9yIHRoaXMgbWVtb3J5IG9wZXJhdGlvbi4KKyAgU3luY1Njb3BlOjpJRCBnZXRTeW5jU2NvcGVJRCgpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8U3luY1Njb3BlOjpJRD4oQXRvbWljSW5mby5TU0lEKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIGF0b21pYyBvcmRlcmluZyByZXF1aXJlbWVudHMgZm9yIHRoaXMgbWVtb3J5IG9wZXJhdGlvbi4gRm9yCisgIC8vLyBjbXB4Y2hnIGF0b21pYyBvcGVyYXRpb25zLCByZXR1cm4gdGhlIGF0b21pYyBvcmRlcmluZyByZXF1aXJlbWVudHMgd2hlbgorICAvLy8gc3RvcmUgb2NjdXJzLgorICBBdG9taWNPcmRlcmluZyBnZXRPcmRlcmluZygpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8QXRvbWljT3JkZXJpbmc+KEF0b21pY0luZm8uT3JkZXJpbmcpOworICB9CisKKyAgLy8vIEZvciBjbXB4Y2hnIGF0b21pYyBvcGVyYXRpb25zLCByZXR1cm4gdGhlIGF0b21pYyBvcmRlcmluZyByZXF1aXJlbWVudHMKKyAgLy8vIHdoZW4gc3RvcmUgZG9lcyBub3Qgb2NjdXIuCisgIEF0b21pY09yZGVyaW5nIGdldEZhaWx1cmVPcmRlcmluZygpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8QXRvbWljT3JkZXJpbmc+KEF0b21pY0luZm8uRmFpbHVyZU9yZGVyaW5nKTsKKyAgfQorCisgIGJvb2wgaXNMb2FkKCkgY29uc3QgeyByZXR1cm4gRmxhZ1ZhbHMgJiBNT0xvYWQ7IH0KKyAgYm9vbCBpc1N0b3JlKCkgY29uc3QgeyByZXR1cm4gRmxhZ1ZhbHMgJiBNT1N0b3JlOyB9CisgIGJvb2wgaXNWb2xhdGlsZSgpIGNvbnN0IHsgcmV0dXJuIEZsYWdWYWxzICYgTU9Wb2xhdGlsZTsgfQorICBib29sIGlzTm9uVGVtcG9yYWwoKSBjb25zdCB7IHJldHVybiBGbGFnVmFscyAmIE1PTm9uVGVtcG9yYWw7IH0KKyAgYm9vbCBpc0RlcmVmZXJlbmNlYWJsZSgpIGNvbnN0IHsgcmV0dXJuIEZsYWdWYWxzICYgTU9EZXJlZmVyZW5jZWFibGU7IH0KKyAgYm9vbCBpc0ludmFyaWFudCgpIGNvbnN0IHsgcmV0dXJuIEZsYWdWYWxzICYgTU9JbnZhcmlhbnQ7IH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoaXMgb3BlcmF0aW9uIGhhcyBhbiBhdG9taWMgb3JkZXJpbmcgcmVxdWlyZW1lbnQgb2YKKyAgLy8vIHVub3JkZXJlZCBvciBoaWdoZXIsIGZhbHNlIG90aGVyd2lzZS4KKyAgYm9vbCBpc0F0b21pYygpIGNvbnN0IHsgcmV0dXJuIGdldE9yZGVyaW5nKCkgIT0gQXRvbWljT3JkZXJpbmc6Ok5vdEF0b21pYzsgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBtZW1vcnkgb3BlcmF0aW9uIGRvZXNuJ3QgaGF2ZSBhbnkgb3JkZXJpbmcKKyAgLy8vIGNvbnN0cmFpbnRzIG90aGVyIHRoYW4gbm9ybWFsIGFsaWFzaW5nLiBWb2xhdGlsZSBhbmQgYXRvbWljIG1lbW9yeQorICAvLy8gb3BlcmF0aW9ucyBjYW4ndCBiZSByZW9yZGVyZWQuCisgIC8vLworICAvLy8gQ3VycmVudGx5LCB3ZSBkb24ndCBtb2RlbCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHZvbGF0aWxlIGFuZCBhdG9taWMKKyAgLy8vIG9wZXJhdGlvbnMuIFRoZXkgc2hvdWxkIHJldGFpbiB0aGVpciBvcmRlcmluZyByZWxhdGl2ZSB0byBhbGwgbWVtb3J5CisgIC8vLyBvcGVyYXRpb25zLgorICBib29sIGlzVW5vcmRlcmVkKCkgY29uc3QgeyByZXR1cm4gIWlzVm9sYXRpbGUoKTsgfQorCisgIC8vLyBVcGRhdGUgdGhpcyBNYWNoaW5lTWVtT3BlcmFuZCB0byByZWZsZWN0IHRoZSBhbGlnbm1lbnQgb2YgTU1PLCBpZiBpdCBoYXMgYQorICAvLy8gZ3JlYXRlciBhbGlnbm1lbnQuIFRoaXMgbXVzdCBvbmx5IGJlIHVzZWQgd2hlbiB0aGUgbmV3IGFsaWdubWVudCBhcHBsaWVzCisgIC8vLyB0byBhbGwgdXNlcnMgb2YgdGhpcyBNYWNoaW5lTWVtT3BlcmFuZC4KKyAgdm9pZCByZWZpbmVBbGlnbm1lbnQoY29uc3QgTWFjaGluZU1lbU9wZXJhbmQgKk1NTyk7CisKKyAgLy8vIENoYW5nZSB0aGUgU291cmNlVmFsdWUgZm9yIHRoaXMgTWFjaGluZU1lbU9wZXJhbmQuIFRoaXMgc2hvdWxkIG9ubHkgYmUKKyAgLy8vIHVzZWQgd2hlbiBhbiBvYmplY3QgaXMgYmVpbmcgcmVsb2NhdGVkIGFuZCBhbGwgcmVmZXJlbmNlcyB0byBpdCBhcmUgYmVpbmcKKyAgLy8vIHVwZGF0ZWQuCisgIHZvaWQgc2V0VmFsdWUoY29uc3QgVmFsdWUgKk5ld1NWKSB7IFB0ckluZm8uViA9IE5ld1NWOyB9CisgIHZvaWQgc2V0VmFsdWUoY29uc3QgUHNldWRvU291cmNlVmFsdWUgKk5ld1NWKSB7IFB0ckluZm8uViA9IE5ld1NWOyB9CisgIHZvaWQgc2V0T2Zmc2V0KGludDY0X3QgTmV3T2Zmc2V0KSB7IFB0ckluZm8uT2Zmc2V0ID0gTmV3T2Zmc2V0OyB9CisKKyAgLy8vIFByb2ZpbGUgLSBHYXRoZXIgdW5pcXVlIGRhdGEgZm9yIHRoZSBvYmplY3QuCisgIC8vLworICB2b2lkIFByb2ZpbGUoRm9sZGluZ1NldE5vZGVJRCAmSUQpIGNvbnN0OworCisgIC8vLyBTdXBwb3J0IGZvciBvcGVyYXRvcjw8LgorICAvLy8gQHsKKyAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MpIGNvbnN0OworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUywgTW9kdWxlU2xvdFRyYWNrZXIgJk1TVCkgY29uc3Q7CisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk9TLCBNb2R1bGVTbG90VHJhY2tlciAmTVNULAorICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxTdHJpbmdSZWY+ICZTU05zLCBjb25zdCBMTFZNQ29udGV4dCAmQ29udGV4dCwKKyAgICAgICAgICAgICBjb25zdCBNYWNoaW5lRnJhbWVJbmZvICpNRkksIGNvbnN0IFRhcmdldEluc3RySW5mbyAqVElJKSBjb25zdDsKKyAgLy8vIEB9CisKKyAgZnJpZW5kIGJvb2wgb3BlcmF0b3I9PShjb25zdCBNYWNoaW5lTWVtT3BlcmFuZCAmTEhTLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVNZW1PcGVyYW5kICZSSFMpIHsKKyAgICByZXR1cm4gTEhTLmdldFZhbHVlKCkgPT0gUkhTLmdldFZhbHVlKCkgJiYKKyAgICAgICAgICAgTEhTLmdldFBzZXVkb1ZhbHVlKCkgPT0gUkhTLmdldFBzZXVkb1ZhbHVlKCkgJiYKKyAgICAgICAgICAgTEhTLmdldFNpemUoKSA9PSBSSFMuZ2V0U2l6ZSgpICYmCisgICAgICAgICAgIExIUy5nZXRPZmZzZXQoKSA9PSBSSFMuZ2V0T2Zmc2V0KCkgJiYKKyAgICAgICAgICAgTEhTLmdldEZsYWdzKCkgPT0gUkhTLmdldEZsYWdzKCkgJiYKKyAgICAgICAgICAgTEhTLmdldEFBSW5mbygpID09IFJIUy5nZXRBQUluZm8oKSAmJgorICAgICAgICAgICBMSFMuZ2V0UmFuZ2VzKCkgPT0gUkhTLmdldFJhbmdlcygpICYmCisgICAgICAgICAgIExIUy5nZXRBbGlnbm1lbnQoKSA9PSBSSFMuZ2V0QWxpZ25tZW50KCkgJiYKKyAgICAgICAgICAgTEhTLmdldEFkZHJTcGFjZSgpID09IFJIUy5nZXRBZGRyU3BhY2UoKTsKKyAgfQorCisgIGZyaWVuZCBib29sIG9wZXJhdG9yIT0oY29uc3QgTWFjaGluZU1lbU9wZXJhbmQgJkxIUywKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lTWVtT3BlcmFuZCAmUkhTKSB7CisgICAgcmV0dXJuICEoTEhTID09IFJIUyk7CisgIH0KK307CisKK2lubGluZSByYXdfb3N0cmVhbSAmb3BlcmF0b3I8PChyYXdfb3N0cmVhbSAmT1MsIGNvbnN0IE1hY2hpbmVNZW1PcGVyYW5kICZNUk8pIHsKKyAgTVJPLnByaW50KE9TKTsKKyAgcmV0dXJuIE9TOworfQorCit9IC8vIEVuZCBsbHZtIG5hbWVzcGFjZQorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lTW9kdWxlSW5mby5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVNb2R1bGVJbmZvLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmJlMzA0ZgotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lTW9kdWxlSW5mby5oCkBAIC0wLDAgKzEsMjcxIEBACisvLz09PS0tIGxsdm0vQ29kZUdlbi9NYWNoaW5lTW9kdWxlSW5mby5oIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIENvbGxlY3QgbWV0YSBpbmZvcm1hdGlvbiBmb3IgYSBtb2R1bGUuICBUaGlzIGluZm9ybWF0aW9uIHNob3VsZCBiZSBpbiBhCisvLyBuZXV0cmFsIGZvcm0gdGhhdCBjYW4gYmUgdXNlZCBieSBkaWZmZXJlbnQgZGVidWdnaW5nIGFuZCBleGNlcHRpb24gaGFuZGxpbmcKKy8vIHNjaGVtZXMuCisvLworLy8gVGhlIG9yZ2FuaXphdGlvbiBvZiBpbmZvcm1hdGlvbiBpcyBwcmltYXJpbHkgY2x1c3RlcmVkIGFyb3VuZCB0aGUgc291cmNlCisvLyBjb21waWxlIHVuaXRzLiAgVGhlIG1haW4gZXhjZXB0aW9uIGlzIHNvdXJjZSBsaW5lIGNvcnJlc3BvbmRlbmNlIHdoZXJlCisvLyBpbmxpbmluZyBtYXkgaW50ZXJsZWF2ZSBjb2RlIGZyb20gdmFyaW91cyBjb21waWxlIHVuaXRzLgorLy8KKy8vIFRoZSBmb2xsb3dpbmcgaW5mb3JtYXRpb24gY2FuIGJlIHJldHJpZXZlZCBmcm9tIHRoZSBNYWNoaW5lTW9kdWxlSW5mby4KKy8vCisvLyAgLS0gU291cmNlIGRpcmVjdG9yaWVzIC0gRGlyZWN0b3JpZXMgYXJlIHVuaXF1ZWQgYmFzZWQgb24gdGhlaXIgY2Fub25pY2FsCisvLyAgICAgc3RyaW5nIGFuZCBhc3NpZ25lZCBhIHNlcXVlbnRpYWwgbnVtZXJpYyBJRCAoYmFzZSAxLikKKy8vICAtLSBTb3VyY2UgZmlsZXMgLSBGaWxlcyBhcmUgYWxzbyB1bmlxdWVkIGJhc2VkIG9uIHRoZWlyIG5hbWUgYW5kIGRpcmVjdG9yeQorLy8gICAgIElELiAgQSBmaWxlIElEIGlzIHNlcXVlbnRpYWwgbnVtYmVyIChiYXNlIDEuKQorLy8gIC0tIFNvdXJjZSBsaW5lIGNvcnJlc3BvbmRlbmNlIC0gQSB2ZWN0b3Igb2YgZmlsZSBJRCwgbGluZSMsIGNvbHVtbiMgdHJpcGxlcy4KKy8vICAgICBBIERFQlVHX0xPQ0FUSU9OIGluc3RydWN0aW9uIGlzIGdlbmVyYXRlZCAgYnkgdGhlIERBRyBMZWdhbGl6ZXIKKy8vICAgICBjb3JyZXNwb25kaW5nIHRvIGVhY2ggZW50cnkgaW4gdGhlIHNvdXJjZSBsaW5lIGxpc3QuICBUaGlzIGFsbG93cyBhIGRlYnVnCisvLyAgICAgZW1pdHRlciB0byBnZW5lcmF0ZSBsYWJlbHMgcmVmZXJlbmNlZCBieSBkZWJ1ZyBpbmZvcm1hdGlvbiB0YWJsZXMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORU1PRFVMRUlORk9fSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTUFDSElORU1PRFVMRUlORk9fSAorCisjaW5jbHVkZSAibGx2bS9BRFQvQXJyYXlSZWYuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9EZW5zZU1hcC5oIgorI2luY2x1ZGUgImxsdm0vQURUL1BvaW50ZXJJbnRQYWlyLmgiCisjaW5jbHVkZSAibGx2bS9NQy9NQ0NvbnRleHQuaCIKKyNpbmNsdWRlICJsbHZtL01DL01DU3ltYm9sLmgiCisjaW5jbHVkZSAibGx2bS9QYXNzLmgiCisjaW5jbHVkZSA8bWVtb3J5PgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8dmVjdG9yPgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIEJhc2ljQmxvY2s7CitjbGFzcyBDYWxsSW5zdDsKK2NsYXNzIEZ1bmN0aW9uOworY2xhc3MgTWFjaGluZUZ1bmN0aW9uOworY2xhc3MgTU1JQWRkckxhYmVsTWFwOworY2xhc3MgTW9kdWxlOworY2xhc3MgVGFyZ2V0TWFjaGluZTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLyBUaGlzIGNsYXNzIGNhbiBiZSBkZXJpdmVkIGZyb20gYW5kIHVzZWQgYnkgdGFyZ2V0cyB0byBob2xkIHByaXZhdGUKKy8vLyB0YXJnZXQtc3BlY2lmaWMgaW5mb3JtYXRpb24gZm9yIGVhY2ggTW9kdWxlLiAgT2JqZWN0cyBvZiB0eXBlIGFyZQorLy8vIGFjY2Vzc2VkL2NyZWF0ZWQgd2l0aCBNTUk6OmdldEluZm8gYW5kIGRlc3Ryb3llZCB3aGVuIHRoZSBNYWNoaW5lTW9kdWxlSW5mbworLy8vIGlzIGRlc3Ryb3llZC4KKy8vLworY2xhc3MgTWFjaGluZU1vZHVsZUluZm9JbXBsIHsKK3B1YmxpYzoKKyAgdXNpbmcgU3R1YlZhbHVlVHkgPSBQb2ludGVySW50UGFpcjxNQ1N5bWJvbCAqLCAxLCBib29sPjsKKyAgdXNpbmcgU3ltYm9sTGlzdFR5ID0gc3RkOjp2ZWN0b3I8c3RkOjpwYWlyPE1DU3ltYm9sICosIFN0dWJWYWx1ZVR5Pj47CisKKyAgdmlydHVhbCB+TWFjaGluZU1vZHVsZUluZm9JbXBsKCk7CisKK3Byb3RlY3RlZDoKKyAgLy8vIFJldHVybiB0aGUgZW50cmllcyBmcm9tIGEgRGVuc2VNYXAgaW4gYSBkZXRlcm1pbmlzdGljIHNvcnRlZCBvcmVyLgorICAvLy8gQ2xlYXJzIHRoZSBtYXAuCisgIHN0YXRpYyBTeW1ib2xMaXN0VHkgZ2V0U29ydGVkU3R1YnMoRGVuc2VNYXA8TUNTeW1ib2wqLCBTdHViVmFsdWVUeT4mKTsKK307CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8gVGhpcyBjbGFzcyBjb250YWlucyBtZXRhIGluZm9ybWF0aW9uIHNwZWNpZmljIHRvIGEgbW9kdWxlLiAgUXVlcmllcyBjYW4gYmUKKy8vLyBtYWRlIGJ5IGRpZmZlcmVudCBkZWJ1Z2dpbmcgYW5kIGV4Y2VwdGlvbiBoYW5kbGluZyBzY2hlbWVzIGFuZCByZWZvcm1hdGVkCisvLy8gZm9yIHNwZWNpZmljIHVzZS4KKy8vLworY2xhc3MgTWFjaGluZU1vZHVsZUluZm8gOiBwdWJsaWMgSW1tdXRhYmxlUGFzcyB7CisgIGNvbnN0IFRhcmdldE1hY2hpbmUgJlRNOworCisgIC8vLyBUaGlzIGlzIHRoZSBNQ0NvbnRleHQgdXNlZCBmb3IgdGhlIGVudGlyZSBjb2RlIGdlbmVyYXRvci4KKyAgTUNDb250ZXh0IENvbnRleHQ7CisKKyAgLy8vIFRoaXMgaXMgdGhlIExMVk0gTW9kdWxlIGJlaW5nIHdvcmtlZCBvbi4KKyAgY29uc3QgTW9kdWxlICpUaGVNb2R1bGU7CisKKyAgLy8vIFRoaXMgaXMgdGhlIG9iamVjdC1maWxlLWZvcm1hdC1zcGVjaWZpYyBpbXBsZW1lbnRhdGlvbiBvZgorICAvLy8gTWFjaGluZU1vZHVsZUluZm9JbXBsLCB3aGljaCBsZXRzIHRhcmdldHMgYWNjdW11bGF0ZSB3aGF0ZXZlciBpbmZvIHRoZXkKKyAgLy8vIHdhbnQuCisgIE1hY2hpbmVNb2R1bGVJbmZvSW1wbCAqT2JqRmlsZU1NSTsKKworICAvLy8gXG5hbWUgRXhjZXB0aW9uIEhhbmRsaW5nCisgIC8vLyBceworCisgIC8vLyBWZWN0b3Igb2YgYWxsIHBlcnNvbmFsaXR5IGZ1bmN0aW9ucyBldmVyIHNlZW4uIFVzZWQgdG8gZW1pdCBjb21tb24gRUgKKyAgLy8vIGZyYW1lcy4KKyAgc3RkOjp2ZWN0b3I8Y29uc3QgRnVuY3Rpb24gKj4gUGVyc29uYWxpdGllczsKKworICAvLy8gVGhlIGN1cnJlbnQgY2FsbCBzaXRlIGluZGV4IGJlaW5nIHByb2Nlc3NlZCwgaWYgYW55LiAwIGlmIG5vbmUuCisgIHVuc2lnbmVkIEN1ckNhbGxTaXRlOworCisgIC8vLyBcfQorCisgIC8vLyBUaGlzIG1hcCBrZWVwcyB0cmFjayBvZiB3aGljaCBzeW1ib2wgaXMgYmVpbmcgdXNlZCBmb3IgdGhlIHNwZWNpZmllZAorICAvLy8gYmFzaWMgYmxvY2sncyBhZGRyZXNzIG9mIGxhYmVsLgorICBNTUlBZGRyTGFiZWxNYXAgKkFkZHJMYWJlbFN5bWJvbHM7CisKKyAgLy8gVE9ETzogSWRlYWxseSwgd2hhdCB3ZSdkIGxpa2UgaXMgdG8gaGF2ZSBhIHN3aXRjaCB0aGF0IGFsbG93cyBlbWl0dGluZyAKKyAgLy8gc3luY2hyb25vdXMgKHByZWNpc2UgYXQgY2FsbC1zaXRlcyBvbmx5KSBDRkEgaW50byAuZWhfZnJhbWUuIEhvd2V2ZXIsCisgIC8vIGV2ZW4gdW5kZXIgdGhpcyBzd2l0Y2gsIHdlJ2QgbGlrZSAuZGVidWdfZnJhbWUgdG8gYmUgcHJlY2lzZSB3aGVuIHVzaW5nCisgIC8vIC1nLiBBdCB0aGlzIG1vbWVudCwgdGhlcmUncyBubyB3YXkgdG8gc3BlY2lmeSB0aGF0IHNvbWUgQ0ZJIGRpcmVjdGl2ZXMKKyAgLy8gZ28gaW50byAuZWhfZnJhbWUgb25seSwgd2hpbGUgb3RoZXJzIGdvIGludG8gLmRlYnVnX2ZyYW1lIG9ubHkuCisKKyAgLy8vIFRydWUgaWYgZGVidWdnaW5nIGluZm9ybWF0aW9uIGlzIGF2YWlsYWJsZSBpbiB0aGlzIG1vZHVsZS4KKyAgYm9vbCBEYmdJbmZvQXZhaWxhYmxlOworCisgIC8vLyBUcnVlIGlmIHRoaXMgbW9kdWxlIGNhbGxzIFZhckFyZyBmdW5jdGlvbiB3aXRoIGZsb2F0aW5nLXBvaW50IGFyZ3VtZW50cy4KKyAgLy8vIFRoaXMgaXMgdXNlZCB0byBlbWl0IGFuIHVuZGVmaW5lZCByZWZlcmVuY2UgdG8gX2ZsdHVzZWQgb24gV2luZG93cworICAvLy8gdGFyZ2V0cy4KKyAgYm9vbCBVc2VzVkFGbG9hdEFyZ3VtZW50OworCisgIC8vLyBUcnVlIGlmIHRoZSBtb2R1bGUgY2FsbHMgdGhlIF9fbW9yZXN0YWNrIGZ1bmN0aW9uIGluZGlyZWN0bHksIGFzIGlzCisgIC8vLyByZXF1aXJlZCB1bmRlciB0aGUgbGFyZ2UgY29kZSBtb2RlbCBvbiB4ODYuIFRoaXMgaXMgdXNlZCB0byBlbWl0CisgIC8vLyBhIGRlZmluaXRpb24gb2YgYSBzeW1ib2wsIF9fbW9yZXN0YWNrX2FkZHIsIGNvbnRhaW5pbmcgdGhlIGFkZHJlc3MuIFNlZQorICAvLy8gY29tbWVudHMgaW4gbGliL1RhcmdldC9YODYvWDg2RnJhbWVMb3dlcmluZy5jcHAgZm9yIG1vcmUgZGV0YWlscy4KKyAgYm9vbCBVc2VzTW9yZXN0YWNrQWRkcjsKKworICAvLy8gVHJ1ZSBpZiB0aGUgbW9kdWxlIGNvbnRhaW5zIHNwbGl0LXN0YWNrIGZ1bmN0aW9ucy4gVGhpcyBpcyB1c2VkIHRvCisgIC8vLyBlbWl0IC5ub3RlLkdOVS1zcGxpdC1zdGFjayBzZWN0aW9uIGFzIHJlcXVpcmVkIGJ5IHRoZSBsaW5rZXIgZm9yCisgIC8vLyBzcGVjaWFsIGhhbmRsaW5nIHNwbGl0LXN0YWNrIGZ1bmN0aW9uIGNhbGxpbmcgbm8tc3BsaXQtc3RhY2sgZnVuY3Rpb24uCisgIGJvb2wgSGFzU3BsaXRTdGFjazsKKworICAvLy8gVHJ1ZSBpZiB0aGUgbW9kdWxlIGNvbnRhaW5zIG5vLXNwbGl0LXN0YWNrIGZ1bmN0aW9ucy4gVGhpcyBpcyB1c2VkIHRvCisgIC8vLyBlbWl0IC5ub3RlLkdOVS1uby1zcGxpdC1zdGFjayBzZWN0aW9uIHdoZW4gaXQgYWxzbyBjb250YWlucyBzcGxpdC1zdGFjaworICAvLy8gZnVuY3Rpb25zLgorICBib29sIEhhc05vc3BsaXRTdGFjazsKKworICAvLy8gTWFwcyBJUiBGdW5jdGlvbnMgdG8gdGhlaXIgY29ycmVzcG9uZGluZyBNYWNoaW5lRnVuY3Rpb25zLgorICBEZW5zZU1hcDxjb25zdCBGdW5jdGlvbiosIHN0ZDo6dW5pcXVlX3B0cjxNYWNoaW5lRnVuY3Rpb24+PiBNYWNoaW5lRnVuY3Rpb25zOworICAvLy8gTmV4dCB1bmlxdWUgbnVtYmVyIGF2YWlsYWJsZSBmb3IgYSBNYWNoaW5lRnVuY3Rpb24uCisgIHVuc2lnbmVkIE5leHRGbk51bSA9IDA7CisgIGNvbnN0IEZ1bmN0aW9uICpMYXN0UmVxdWVzdCA9IG51bGxwdHI7IC8vLzwgVXNlZCBmb3Igc2hvcnRjdXQvY2FjaGUuCisgIE1hY2hpbmVGdW5jdGlvbiAqTGFzdFJlc3VsdCA9IG51bGxwdHI7IC8vLzwgVXNlZCBmb3Igc2hvcnRjdXQvY2FjaGUuCisKK3B1YmxpYzoKKyAgc3RhdGljIGNoYXIgSUQ7IC8vIFBhc3MgaWRlbnRpZmljYXRpb24sIHJlcGxhY2VtZW50IGZvciB0eXBlaWQKKworICBleHBsaWNpdCBNYWNoaW5lTW9kdWxlSW5mbyhjb25zdCBUYXJnZXRNYWNoaW5lICpUTSA9IG51bGxwdHIpOworICB+TWFjaGluZU1vZHVsZUluZm8oKSBvdmVycmlkZTsKKworICAvLyBJbml0aWFsaXphdGlvbiBhbmQgRmluYWxpemF0aW9uCisgIGJvb2wgZG9Jbml0aWFsaXphdGlvbihNb2R1bGUgJikgb3ZlcnJpZGU7CisgIGJvb2wgZG9GaW5hbGl6YXRpb24oTW9kdWxlICYpIG92ZXJyaWRlOworCisgIGNvbnN0IE1DQ29udGV4dCAmZ2V0Q29udGV4dCgpIGNvbnN0IHsgcmV0dXJuIENvbnRleHQ7IH0KKyAgTUNDb250ZXh0ICZnZXRDb250ZXh0KCkgeyByZXR1cm4gQ29udGV4dDsgfQorCisgIGNvbnN0IE1vZHVsZSAqZ2V0TW9kdWxlKCkgY29uc3QgeyByZXR1cm4gVGhlTW9kdWxlOyB9CisKKyAgLy8vIFJldHVybnMgdGhlIE1hY2hpbmVGdW5jdGlvbiBjb25zdHJ1Y3RlZCBmb3IgdGhlIElSIGZ1bmN0aW9uIFxwIEYuCisgIC8vLyBDcmVhdGVzIGEgbmV3IE1hY2hpbmVGdW5jdGlvbiBpZiBub25lIGV4aXN0cyB5ZXQuCisgIE1hY2hpbmVGdW5jdGlvbiAmZ2V0T3JDcmVhdGVNYWNoaW5lRnVuY3Rpb24oY29uc3QgRnVuY3Rpb24gJkYpOworCisgIC8vLyBcYnJpZWQgUmV0dXJucyB0aGUgTWFjaGluZUZ1bmN0aW9uIGFzc29jaWF0ZWQgdG8gSVIgZnVuY3Rpb24gXHAgRiBpZiB0aGVyZQorICAvLy8gaXMgb25lLCBvdGhlcndpc2UgbnVsbHB0ci4KKyAgTWFjaGluZUZ1bmN0aW9uICpnZXRNYWNoaW5lRnVuY3Rpb24oY29uc3QgRnVuY3Rpb24gJkYpIGNvbnN0OworCisgIC8vLyBEZWxldGUgdGhlIE1hY2hpbmVGdW5jdGlvbiBccCBNRiBhbmQgcmVzZXQgdGhlIGxpbmsgaW4gdGhlIElSIEZ1bmN0aW9uIHRvCisgIC8vLyBNYWNoaW5lIEZ1bmN0aW9uIG1hcC4KKyAgdm9pZCBkZWxldGVNYWNoaW5lRnVuY3Rpb25Gb3IoRnVuY3Rpb24gJkYpOworCisgIC8vLyBLZWVwIHRyYWNrIG9mIHZhcmlvdXMgcGVyLWZ1bmN0aW9uIHBpZWNlcyBvZiBpbmZvcm1hdGlvbiBmb3IgYmFja2VuZHMKKyAgLy8vIHRoYXQgd291bGQgbGlrZSB0byBkbyBzby4KKyAgdGVtcGxhdGU8dHlwZW5hbWUgVHk+CisgIFR5ICZnZXRPYmpGaWxlSW5mbygpIHsKKyAgICBpZiAoT2JqRmlsZU1NSSA9PSBudWxscHRyKQorICAgICAgT2JqRmlsZU1NSSA9IG5ldyBUeSgqdGhpcyk7CisgICAgcmV0dXJuICpzdGF0aWNfY2FzdDxUeSo+KE9iakZpbGVNTUkpOworICB9CisKKyAgdGVtcGxhdGU8dHlwZW5hbWUgVHk+CisgIGNvbnN0IFR5ICZnZXRPYmpGaWxlSW5mbygpIGNvbnN0IHsKKyAgICByZXR1cm4gY29uc3RfY2FzdDxNYWNoaW5lTW9kdWxlSW5mbyo+KHRoaXMpLT5nZXRPYmpGaWxlSW5mbzxUeT4oKTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdmFsaWQgZGVidWcgaW5mbyBpcyBwcmVzZW50LgorICBib29sIGhhc0RlYnVnSW5mbygpIGNvbnN0IHsgcmV0dXJuIERiZ0luZm9BdmFpbGFibGU7IH0KKyAgdm9pZCBzZXREZWJ1Z0luZm9BdmFpbGFiaWxpdHkoYm9vbCBhdmFpbCkgeyBEYmdJbmZvQXZhaWxhYmxlID0gYXZhaWw7IH0KKworICBib29sIHVzZXNWQUZsb2F0QXJndW1lbnQoKSBjb25zdCB7CisgICAgcmV0dXJuIFVzZXNWQUZsb2F0QXJndW1lbnQ7CisgIH0KKworICB2b2lkIHNldFVzZXNWQUZsb2F0QXJndW1lbnQoYm9vbCBiKSB7CisgICAgVXNlc1ZBRmxvYXRBcmd1bWVudCA9IGI7CisgIH0KKworICBib29sIHVzZXNNb3Jlc3RhY2tBZGRyKCkgY29uc3QgeworICAgIHJldHVybiBVc2VzTW9yZXN0YWNrQWRkcjsKKyAgfQorCisgIHZvaWQgc2V0VXNlc01vcmVzdGFja0FkZHIoYm9vbCBiKSB7CisgICAgVXNlc01vcmVzdGFja0FkZHIgPSBiOworICB9CisKKyAgYm9vbCBoYXNTcGxpdFN0YWNrKCkgY29uc3QgeworICAgIHJldHVybiBIYXNTcGxpdFN0YWNrOworICB9CisKKyAgdm9pZCBzZXRIYXNTcGxpdFN0YWNrKGJvb2wgYikgeworICAgIEhhc1NwbGl0U3RhY2sgPSBiOworICB9CisKKyAgYm9vbCBoYXNOb3NwbGl0U3RhY2soKSBjb25zdCB7CisgICAgcmV0dXJuIEhhc05vc3BsaXRTdGFjazsKKyAgfQorCisgIHZvaWQgc2V0SGFzTm9zcGxpdFN0YWNrKGJvb2wgYikgeworICAgIEhhc05vc3BsaXRTdGFjayA9IGI7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBzeW1ib2wgdG8gYmUgdXNlZCBmb3IgdGhlIHNwZWNpZmllZCBiYXNpYyBibG9jayB3aGVuIGl0cworICAvLy8gYWRkcmVzcyBpcyB0YWtlbi4gIFRoaXMgY2Fubm90IGJlIGl0cyBub3JtYWwgTEJCIGxhYmVsIGJlY2F1c2UgdGhlIGJsb2NrCisgIC8vLyBtYXkgYmUgYWNjZXNzZWQgb3V0c2lkZSBpdHMgY29udGFpbmluZyBmdW5jdGlvbi4KKyAgTUNTeW1ib2wgKmdldEFkZHJMYWJlbFN5bWJvbChjb25zdCBCYXNpY0Jsb2NrICpCQikgeworICAgIHJldHVybiBnZXRBZGRyTGFiZWxTeW1ib2xUb0VtaXQoQkIpLmZyb250KCk7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBzeW1ib2wgdG8gYmUgdXNlZCBmb3IgdGhlIHNwZWNpZmllZCBiYXNpYyBibG9jayB3aGVuIGl0cworICAvLy8gYWRkcmVzcyBpcyB0YWtlbi4gIElmIG90aGVyIGJsb2NrcyB3ZXJlIFJBVVcnZCB0byB0aGlzIG9uZSwgd2UgbWF5IGhhdmUKKyAgLy8vIHRvIGVtaXQgdGhlbSBhcyB3ZWxsLCByZXR1cm4gdGhlIHdob2xlIHNldC4KKyAgQXJyYXlSZWY8TUNTeW1ib2wgKj4gZ2V0QWRkckxhYmVsU3ltYm9sVG9FbWl0KGNvbnN0IEJhc2ljQmxvY2sgKkJCKTsKKworICAvLy8gSWYgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBoYXMgaGFkIGFueSByZWZlcmVuY2VzIHRvIGFkZHJlc3MtdGFrZW4gYmxvY2tzCisgIC8vLyBnZW5lcmF0ZWQsIGJ1dCB0aGUgYmxvY2sgZ290IGRlbGV0ZWQsIHJldHVybiB0aGUgc3ltYm9sIG5vdyBzbyB3ZSBjYW4KKyAgLy8vIGVtaXQgaXQuICBUaGlzIHByZXZlbnRzIGVtaXR0aW5nIGEgcmVmZXJlbmNlIHRvIGEgc3ltYm9sIHRoYXQgaGFzIG5vCisgIC8vLyBkZWZpbml0aW9uLgorICB2b2lkIHRha2VEZWxldGVkU3ltYm9sc0ZvckZ1bmN0aW9uKGNvbnN0IEZ1bmN0aW9uICpGLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPE1DU3ltYm9sKj4gJlJlc3VsdCk7CisKKyAgLy8vIFxuYW1lIEV4Y2VwdGlvbiBIYW5kbGluZworICAvLy8gXHsKKworICAvLy8gU2V0IHRoZSBjYWxsIHNpdGUgY3VycmVudGx5IGJlaW5nIHByb2Nlc3NlZC4KKyAgdm9pZCBzZXRDdXJyZW50Q2FsbFNpdGUodW5zaWduZWQgU2l0ZSkgeyBDdXJDYWxsU2l0ZSA9IFNpdGU7IH0KKworICAvLy8gR2V0IHRoZSBjYWxsIHNpdGUgY3VycmVudGx5IGJlaW5nIHByb2Nlc3NlZCwgaWYgYW55LiAgcmV0dXJuIHplcm8gaWYKKyAgLy8vIG5vbmUuCisgIHVuc2lnbmVkIGdldEN1cnJlbnRDYWxsU2l0ZSgpIHsgcmV0dXJuIEN1ckNhbGxTaXRlOyB9CisKKyAgLy8vIFByb3ZpZGUgdGhlIHBlcnNvbmFsaXR5IGZ1bmN0aW9uIGZvciB0aGUgZXhjZXB0aW9uIGluZm9ybWF0aW9uLgorICB2b2lkIGFkZFBlcnNvbmFsaXR5KGNvbnN0IEZ1bmN0aW9uICpQZXJzb25hbGl0eSk7CisKKyAgLy8vIFJldHVybiBhcnJheSBvZiBwZXJzb25hbGl0eSBmdW5jdGlvbnMgZXZlciBzZWVuLgorICBjb25zdCBzdGQ6OnZlY3Rvcjxjb25zdCBGdW5jdGlvbiAqPiYgZ2V0UGVyc29uYWxpdGllcygpIGNvbnN0IHsKKyAgICByZXR1cm4gUGVyc29uYWxpdGllczsKKyAgfQorICAvLy8gXH0KK307IC8vIEVuZCBjbGFzcyBNYWNoaW5lTW9kdWxlSW5mbworCisvLz09PS0gTU1JIGJ1aWxkaW5nIGhlbHBlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisvLy8gRGV0ZXJtaW5lIGlmIGFueSBmbG9hdGluZy1wb2ludCB2YWx1ZXMgYXJlIGJlaW5nIHBhc3NlZCB0byB0aGlzIHZhcmlhZGljCisvLy8gZnVuY3Rpb24sIGFuZCBzZXQgdGhlIE1hY2hpbmVNb2R1bGVJbmZvJ3MgdXNlc1ZBRmxvYXRBcmd1bWVudCBmbGFnIGlmIHNvLgorLy8vIFRoaXMgZmxhZyBpcyB1c2VkIHRvIGVtaXQgYW4gdW5kZWZpbmVkIHJlZmVyZW5jZSB0byBfZmx0dXNlZCBvbiBXaW5kb3dzLAorLy8vIHdoaWNoIHdpbGwgbGluayBpbiBNU1ZDUlQncyBmbG9hdGluZy1wb2ludCBzdXBwb3J0Lgordm9pZCBjb21wdXRlVXNlc1ZBRmxvYXRBcmd1bWVudChjb25zdCBDYWxsSW5zdCAmSSwgTWFjaGluZU1vZHVsZUluZm8gJk1NSSk7CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTUFDSElORU1PRFVMRUlORk9fSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVNb2R1bGVJbmZvSW1wbHMuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lTW9kdWxlSW5mb0ltcGxzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmE4N2ZhMgotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lTW9kdWxlSW5mb0ltcGxzLmgKQEAgLTAsMCArMSw4NSBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9NYWNoaW5lTW9kdWxlSW5mb0ltcGxzLmggLS0tLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgZGVmaW5lcyBvYmplY3QtZmlsZSBmb3JtYXQgc3BlY2lmaWMgaW1wbGVtZW50YXRpb25zIG9mCisvLyBNYWNoaW5lTW9kdWxlSW5mb0ltcGwuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORU1PRFVMRUlORk9JTVBMU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9NQUNISU5FTU9EVUxFSU5GT0lNUExTX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVNb2R1bGVJbmZvLmgiCisjaW5jbHVkZSA8Y2Fzc2VydD4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNQ1N5bWJvbDsKKworLy8vIE1hY2hpbmVNb2R1bGVJbmZvTWFjaE8gLSBUaGlzIGlzIGEgTWFjaGluZU1vZHVsZUluZm9JbXBsIGltcGxlbWVudGF0aW9uCisvLy8gZm9yIE1hY2hPIHRhcmdldHMuCitjbGFzcyBNYWNoaW5lTW9kdWxlSW5mb01hY2hPIDogcHVibGljIE1hY2hpbmVNb2R1bGVJbmZvSW1wbCB7CisgIC8vLyBHVlN0dWJzIC0gRGFyd2luICckbm9uX2xhenlfcHRyJyBzdHVicy4gIFRoZSBrZXkgaXMgc29tZXRoaW5nIGxpa2UKKyAgLy8vICJMZm9vJG5vbl9sYXp5X3B0ciIsIHRoZSB2YWx1ZSBpcyBzb21ldGhpbmcgbGlrZSAiX2ZvbyIuIFRoZSBleHRyYSBiaXQKKyAgLy8vIGlzIHRydWUgaWYgdGhpcyBHViBpcyBleHRlcm5hbC4KKyAgRGVuc2VNYXA8TUNTeW1ib2wgKiwgU3R1YlZhbHVlVHk+IEdWU3R1YnM7CisKKyAgLy8vIFRocmVhZExvY2FsR1ZTdHVicyAtIERhcndpbiAnJG5vbl9sYXp5X3B0cicgc3R1YnMuICBUaGUga2V5IGlzIHNvbWV0aGluZworICAvLy8gbGlrZSAiTGZvbyRub25fbGF6eV9wdHIiLCB0aGUgdmFsdWUgaXMgc29tZXRoaW5nIGxpa2UgIl9mb28iLiBUaGUgZXh0cmEKKyAgLy8vIGJpdCBpcyB0cnVlIGlmIHRoaXMgR1YgaXMgZXh0ZXJuYWwuCisgIERlbnNlTWFwPE1DU3ltYm9sICosIFN0dWJWYWx1ZVR5PiBUaHJlYWRMb2NhbEdWU3R1YnM7CisKKyAgdmlydHVhbCB2b2lkIGFuY2hvcigpOyAvLyBPdXQgb2YgbGluZSB2aXJ0dWFsIG1ldGhvZC4KKworcHVibGljOgorICBNYWNoaW5lTW9kdWxlSW5mb01hY2hPKGNvbnN0IE1hY2hpbmVNb2R1bGVJbmZvICYpIHt9CisKKyAgU3R1YlZhbHVlVHkgJmdldEdWU3R1YkVudHJ5KE1DU3ltYm9sICpTeW0pIHsKKyAgICBhc3NlcnQoU3ltICYmICJLZXkgY2Fubm90IGJlIG51bGwiKTsKKyAgICByZXR1cm4gR1ZTdHVic1tTeW1dOworICB9CisKKyAgU3R1YlZhbHVlVHkgJmdldFRocmVhZExvY2FsR1ZTdHViRW50cnkoTUNTeW1ib2wgKlN5bSkgeworICAgIGFzc2VydChTeW0gJiYgIktleSBjYW5ub3QgYmUgbnVsbCIpOworICAgIHJldHVybiBUaHJlYWRMb2NhbEdWU3R1YnNbU3ltXTsKKyAgfQorCisgIC8vLyBBY2Nlc3NvciBtZXRob2RzIHRvIHJldHVybiB0aGUgc2V0IG9mIHN0dWJzIGluIHNvcnRlZCBvcmRlci4KKyAgU3ltYm9sTGlzdFR5IEdldEdWU3R1Ykxpc3QoKSB7IHJldHVybiBnZXRTb3J0ZWRTdHVicyhHVlN0dWJzKTsgfQorICBTeW1ib2xMaXN0VHkgR2V0VGhyZWFkTG9jYWxHVlN0dWJMaXN0KCkgeworICAgIHJldHVybiBnZXRTb3J0ZWRTdHVicyhUaHJlYWRMb2NhbEdWU3R1YnMpOworICB9Cit9OworCisvLy8gTWFjaGluZU1vZHVsZUluZm9FTEYgLSBUaGlzIGlzIGEgTWFjaGluZU1vZHVsZUluZm9JbXBsIGltcGxlbWVudGF0aW9uCisvLy8gZm9yIEVMRiB0YXJnZXRzLgorY2xhc3MgTWFjaGluZU1vZHVsZUluZm9FTEYgOiBwdWJsaWMgTWFjaGluZU1vZHVsZUluZm9JbXBsIHsKKyAgLy8vIEdWU3R1YnMgLSBUaGVzZSBzdHVicyBhcmUgdXNlZCB0byBtYXRlcmlhbGl6ZSBnbG9iYWwgYWRkcmVzc2VzIGluIFBJQworICAvLy8gbW9kZS4KKyAgRGVuc2VNYXA8TUNTeW1ib2wgKiwgU3R1YlZhbHVlVHk+IEdWU3R1YnM7CisKKyAgdmlydHVhbCB2b2lkIGFuY2hvcigpOyAvLyBPdXQgb2YgbGluZSB2aXJ0dWFsIG1ldGhvZC4KKworcHVibGljOgorICBNYWNoaW5lTW9kdWxlSW5mb0VMRihjb25zdCBNYWNoaW5lTW9kdWxlSW5mbyAmKSB7fQorCisgIFN0dWJWYWx1ZVR5ICZnZXRHVlN0dWJFbnRyeShNQ1N5bWJvbCAqU3ltKSB7CisgICAgYXNzZXJ0KFN5bSAmJiAiS2V5IGNhbm5vdCBiZSBudWxsIik7CisgICAgcmV0dXJuIEdWU3R1YnNbU3ltXTsKKyAgfQorCisgIC8vLyBBY2Nlc3NvciBtZXRob2RzIHRvIHJldHVybiB0aGUgc2V0IG9mIHN0dWJzIGluIHNvcnRlZCBvcmRlci4KKworICBTeW1ib2xMaXN0VHkgR2V0R1ZTdHViTGlzdCgpIHsgcmV0dXJuIGdldFNvcnRlZFN0dWJzKEdWU3R1YnMpOyB9Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX01BQ0hJTkVNT0RVTEVJTkZPSU1QTFNfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVPcGVyYW5kLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZU9wZXJhbmQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZjBkYjFjCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVPcGVyYW5kLmgKQEAgLTAsMCArMSw5NDEgQEAKKy8vPT09LS0gbGx2bS9Db2RlR2VuL01hY2hpbmVPcGVyYW5kLmggLSBNYWNoaW5lT3BlcmFuZCBjbGFzcyAtLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBkZWNsYXJhdGlvbiBvZiB0aGUgTWFjaGluZU9wZXJhbmQgY2xhc3MuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORU9QRVJBTkRfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTUFDSElORU9QRVJBTkRfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0ludHJpbnNpY3MuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvRGF0YVR5cGVzLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0xvd0xldmVsVHlwZUltcGwuaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIEJsb2NrQWRkcmVzczsKK2NsYXNzIENvbnN0YW50RlA7CitjbGFzcyBDb25zdGFudEludDsKK2NsYXNzIEdsb2JhbFZhbHVlOworY2xhc3MgTWFjaGluZUJhc2ljQmxvY2s7CitjbGFzcyBNYWNoaW5lSW5zdHI7CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworY2xhc3MgTUNDRklJbnN0cnVjdGlvbjsKK2NsYXNzIE1ETm9kZTsKK2NsYXNzIE1vZHVsZVNsb3RUcmFja2VyOworY2xhc3MgVGFyZ2V0TWFjaGluZTsKK2NsYXNzIFRhcmdldEludHJpbnNpY0luZm87CitjbGFzcyBUYXJnZXRSZWdpc3RlckluZm87CitjbGFzcyBoYXNoX2NvZGU7CitjbGFzcyByYXdfb3N0cmVhbTsKK2NsYXNzIE1DU3ltYm9sOworCisvLy8gTWFjaGluZU9wZXJhbmQgY2xhc3MgLSBSZXByZXNlbnRhdGlvbiBvZiBlYWNoIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gb3BlcmFuZC4KKy8vLworLy8vIFRoaXMgY2xhc3MgaXNuJ3QgYSBQT0QgdHlwZSBiZWNhdXNlIGl0IGhhcyBhIHByaXZhdGUgY29uc3RydWN0b3IsIGJ1dCBpdHMKKy8vLyBkZXN0cnVjdG9yIG11c3QgYmUgdHJpdmlhbC4gRnVuY3Rpb25zIGxpa2UgTWFjaGluZUluc3RyOjphZGRPcGVyYW5kKCksCisvLy8gTWFjaGluZVJlZ2lzdGVySW5mbzo6bW92ZU9wZXJhbmRzKCksIGFuZCBNRjo6RGVsZXRlTWFjaGluZUluc3RyKCkgZGVwZW5kIG9uCisvLy8gbm90IGhhdmluZyB0byBjYWxsIHRoZSBNYWNoaW5lT3BlcmFuZCBkZXN0cnVjdG9yLgorLy8vCitjbGFzcyBNYWNoaW5lT3BlcmFuZCB7CitwdWJsaWM6CisgIGVudW0gTWFjaGluZU9wZXJhbmRUeXBlIDogdW5zaWduZWQgY2hhciB7CisgICAgTU9fUmVnaXN0ZXIsICAgICAgICAgIC8vLzwgUmVnaXN0ZXIgb3BlcmFuZC4KKyAgICBNT19JbW1lZGlhdGUsICAgICAgICAgLy8vPCBJbW1lZGlhdGUgb3BlcmFuZAorICAgIE1PX0NJbW1lZGlhdGUsICAgICAgICAvLy88IEltbWVkaWF0ZSA+NjRiaXQgb3BlcmFuZAorICAgIE1PX0ZQSW1tZWRpYXRlLCAgICAgICAvLy88IEZsb2F0aW5nLXBvaW50IGltbWVkaWF0ZSBvcGVyYW5kCisgICAgTU9fTWFjaGluZUJhc2ljQmxvY2ssIC8vLzwgTWFjaGluZUJhc2ljQmxvY2sgcmVmZXJlbmNlCisgICAgTU9fRnJhbWVJbmRleCwgICAgICAgIC8vLzwgQWJzdHJhY3QgU3RhY2sgRnJhbWUgSW5kZXgKKyAgICBNT19Db25zdGFudFBvb2xJbmRleCwgLy8vPCBBZGRyZXNzIG9mIGluZGV4ZWQgQ29uc3RhbnQgaW4gQ29uc3RhbnQgUG9vbAorICAgIE1PX1RhcmdldEluZGV4LCAgICAgICAvLy88IFRhcmdldC1kZXBlbmRlbnQgaW5kZXgrb2Zmc2V0IG9wZXJhbmQuCisgICAgTU9fSnVtcFRhYmxlSW5kZXgsICAgIC8vLzwgQWRkcmVzcyBvZiBpbmRleGVkIEp1bXAgVGFibGUgZm9yIHN3aXRjaAorICAgIE1PX0V4dGVybmFsU3ltYm9sLCAgICAvLy88IE5hbWUgb2YgZXh0ZXJuYWwgZ2xvYmFsIHN5bWJvbAorICAgIE1PX0dsb2JhbEFkZHJlc3MsICAgICAvLy88IEFkZHJlc3Mgb2YgYSBnbG9iYWwgdmFsdWUKKyAgICBNT19CbG9ja0FkZHJlc3MsICAgICAgLy8vPCBBZGRyZXNzIG9mIGEgYmFzaWMgYmxvY2sKKyAgICBNT19SZWdpc3Rlck1hc2ssICAgICAgLy8vPCBNYXNrIG9mIHByZXNlcnZlZCByZWdpc3RlcnMuCisgICAgTU9fUmVnaXN0ZXJMaXZlT3V0LCAgIC8vLzwgTWFzayBvZiBsaXZlLW91dCByZWdpc3RlcnMuCisgICAgTU9fTWV0YWRhdGEsICAgICAgICAgIC8vLzwgTWV0YWRhdGEgcmVmZXJlbmNlIChmb3IgZGVidWcgaW5mbykKKyAgICBNT19NQ1N5bWJvbCwgICAgICAgICAgLy8vPCBNQ1N5bWJvbCByZWZlcmVuY2UgKGZvciBkZWJ1Zy9laCBpbmZvKQorICAgIE1PX0NGSUluZGV4LCAgICAgICAgICAvLy88IE1DQ0ZJSW5zdHJ1Y3Rpb24gaW5kZXguCisgICAgTU9fSW50cmluc2ljSUQsICAgICAgIC8vLzwgSW50cmluc2ljIElEIGZvciBJU2VsCisgICAgTU9fUHJlZGljYXRlLCAgICAgICAgIC8vLzwgR2VuZXJpYyBwcmVkaWNhdGUgZm9yIElTZWwKKyAgICBNT19MYXN0ID0gTU9fUHJlZGljYXRlLAorICB9OworCitwcml2YXRlOgorICAvLy8gT3BLaW5kIC0gU3BlY2lmeSB3aGF0IGtpbmQgb2Ygb3BlcmFuZCB0aGlzIGlzLiAgVGhpcyBkaXNjcmltaW5hdGVzIHRoZQorICAvLy8gdW5pb24uCisgIHVuc2lnbmVkIE9wS2luZCA6IDg7CisKKyAgLy8vIFN1YnJlZ2lzdGVyIG51bWJlciBmb3IgTU9fUmVnaXN0ZXIuICBBIHZhbHVlIG9mIDAgaW5kaWNhdGVzIHRoZQorICAvLy8gTU9fUmVnaXN0ZXIgaGFzIG5vIHN1YlJlZy4KKyAgLy8vCisgIC8vLyBGb3IgYWxsIG90aGVyIGtpbmRzIG9mIG9wZXJhbmRzLCB0aGlzIGZpZWxkIGhvbGRzIHRhcmdldC1zcGVjaWZpYyBmbGFncy4KKyAgdW5zaWduZWQgU3ViUmVnX1RhcmdldEZsYWdzIDogMTI7CisKKyAgLy8vIFRpZWRUbyAtIE5vbi16ZXJvIHdoZW4gdGhpcyByZWdpc3RlciBvcGVyYW5kIGlzIHRpZWQgdG8gYW5vdGhlciByZWdpc3RlcgorICAvLy8gb3BlcmFuZC4gVGhlIGVuY29kaW5nIG9mIHRoaXMgZmllbGQgaXMgZGVzY3JpYmVkIGluIHRoZSBibG9jayBjb21tZW50CisgIC8vLyBiZWZvcmUgTWFjaGluZUluc3RyOjp0aWVPcGVyYW5kcygpLgorICB1bnNpZ25lZCBUaWVkVG8gOiA0OworCisgIC8vLyBJc0RlZiAtIFRydWUgaWYgdGhpcyBpcyBhIGRlZiwgZmFsc2UgaWYgdGhpcyBpcyBhIHVzZSBvZiB0aGUgcmVnaXN0ZXIuCisgIC8vLyBUaGlzIGlzIG9ubHkgdmFsaWQgb24gcmVnaXN0ZXIgb3BlcmFuZHMuCisgIC8vLworICB1bnNpZ25lZCBJc0RlZiA6IDE7CisKKyAgLy8vIElzSW1wIC0gVHJ1ZSBpZiB0aGlzIGlzIGFuIGltcGxpY2l0IGRlZiBvciB1c2UsIGZhbHNlIGlmIGl0IGlzIGV4cGxpY2l0LgorICAvLy8gVGhpcyBpcyBvbmx5IHZhbGlkIG9uIHJlZ2lzdGVyIG9wZGVyYW5kcy4KKyAgLy8vCisgIHVuc2lnbmVkIElzSW1wIDogMTsKKworICAvLy8gSXNEZWFkT3JLaWxsCisgIC8vLyBGb3IgdXNlczogSXNLaWxsIC0gVHJ1ZSBpZiB0aGlzIGluc3RydWN0aW9uIGlzIHRoZSBsYXN0IHVzZSBvZiB0aGUKKyAgLy8vIHJlZ2lzdGVyIG9uIHRoaXMgcGF0aCB0aHJvdWdoIHRoZSBmdW5jdGlvbi4KKyAgLy8vIEZvciBkZWZzOiBJc0RlYWQgLSBUcnVlIGlmIHRoaXMgcmVnaXN0ZXIgaXMgbmV2ZXIgdXNlZCBieSBhIHN1YnNlcXVlbnQKKyAgLy8vIGluc3RydWN0aW9uLgorICAvLy8gVGhpcyBpcyBvbmx5IHZhbGlkIG9uIHJlZ2lzdGVyIG9wZXJhbmRzLgorICB1bnNpZ25lZCBJc0RlYWRPcktpbGwgOiAxOworCisgIC8vLyBTZWUgaXNSZW5hbWFibGUoKS4KKyAgdW5zaWduZWQgSXNSZW5hbWFibGUgOiAxOworCisgIC8vLyBJc1VuZGVmIC0gVHJ1ZSBpZiB0aGlzIHJlZ2lzdGVyIG9wZXJhbmQgcmVhZHMgYW4gInVuZGVmIiB2YWx1ZSwgaS5lLiB0aGUKKyAgLy8vIHJlYWQgdmFsdWUgZG9lc24ndCBtYXR0ZXIuICBUaGlzIGZsYWcgY2FuIGJlIHNldCBvbiBib3RoIHVzZSBhbmQgZGVmCisgIC8vLyBvcGVyYW5kcy4gIE9uIGEgc3ViLXJlZ2lzdGVyIGRlZiBvcGVyYW5kLCBpdCByZWZlcnMgdG8gdGhlIHBhcnQgb2YgdGhlCisgIC8vLyByZWdpc3RlciB0aGF0IGlzbid0IHdyaXR0ZW4uICBPbiBhIGZ1bGwtcmVnaXN0ZXIgZGVmIG9wZXJhbmQsIGl0IGlzIGEKKyAgLy8vIG5vb3AuICBTZWUgcmVhZHNSZWcoKS4KKyAgLy8vCisgIC8vLyBUaGlzIGlzIG9ubHkgdmFsaWQgb24gcmVnaXN0ZXJzLgorICAvLy8KKyAgLy8vIE5vdGUgdGhhdCBhbiBpbnN0cnVjdGlvbiBtYXkgaGF2ZSBtdWx0aXBsZSA8dW5kZWY+IG9wZXJhbmRzIHJlZmVycmluZyB0bworICAvLy8gdGhlIHNhbWUgcmVnaXN0ZXIuICBJbiB0aGF0IGNhc2UsIHRoZSBpbnN0cnVjdGlvbiBtYXkgZGVwZW5kIG9uIHRob3NlCisgIC8vLyBvcGVyYW5kcyByZWFkaW5nIHRoZSBzYW1lIGRvbnQtY2FyZSB2YWx1ZS4gIEZvciBleGFtcGxlOgorICAvLy8KKyAgLy8vICAgJTEgPSBYT1IgdW5kZWYgJTIsIHVuZGVmICUyCisgIC8vLworICAvLy8gQW55IHJlZ2lzdGVyIGNhbiBiZSB1c2VkIGZvciAlMiwgYW5kIGl0cyB2YWx1ZSBkb2Vzbid0IG1hdHRlciwgYnV0CisgIC8vLyB0aGUgdHdvIG9wZXJhbmRzIG11c3QgYmUgdGhlIHNhbWUgcmVnaXN0ZXIuCisgIC8vLworICB1bnNpZ25lZCBJc1VuZGVmIDogMTsKKworICAvLy8gSXNJbnRlcm5hbFJlYWQgLSBUcnVlIGlmIHRoaXMgb3BlcmFuZCByZWFkcyBhIHZhbHVlIHRoYXQgd2FzIGRlZmluZWQKKyAgLy8vIGluc2lkZSB0aGUgc2FtZSBpbnN0cnVjdGlvbiBvciBidW5kbGUuICBUaGlzIGZsYWcgY2FuIGJlIHNldCBvbiBib3RoIHVzZQorICAvLy8gYW5kIGRlZiBvcGVyYW5kcy4gIE9uIGEgc3ViLXJlZ2lzdGVyIGRlZiBvcGVyYW5kLCBpdCByZWZlcnMgdG8gdGhlIHBhcnQKKyAgLy8vIG9mIHRoZSByZWdpc3RlciB0aGF0IGlzbid0IHdyaXR0ZW4uICBPbiBhIGZ1bGwtcmVnaXN0ZXIgZGVmIG9wZXJhbmQsIGl0CisgIC8vLyBpcyBhIG5vb3AuCisgIC8vLworICAvLy8gV2hlbiB0aGlzIGZsYWcgaXMgc2V0LCB0aGUgaW5zdHJ1Y3Rpb24gYnVuZGxlIG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUKKyAgLy8vIG90aGVyIGRlZiBvZiB0aGUgcmVnaXN0ZXIuICBJZiBtdWx0aXBsZSBpbnN0cnVjdGlvbnMgaW4gdGhlIGJ1bmRsZSBkZWZpbmUKKyAgLy8vIHRoZSByZWdpc3RlciwgdGhlIG1lYW5pbmcgaXMgdGFyZ2V0LWRlZmluZWQuCisgIHVuc2lnbmVkIElzSW50ZXJuYWxSZWFkIDogMTsKKworICAvLy8gSXNFYXJseUNsb2JiZXIgLSBUcnVlIGlmIHRoaXMgTU9fUmVnaXN0ZXIgJ2RlZicgb3BlcmFuZCBpcyB3cml0dGVuIHRvCisgIC8vLyBieSB0aGUgTWFjaGluZUluc3RyIGJlZm9yZSBhbGwgaW5wdXQgcmVnaXN0ZXJzIGFyZSByZWFkLiAgVGhpcyBpcyB1c2VkIHRvCisgIC8vLyBtb2RlbCB0aGUgR0NDIGlubGluZSBhc20gJyYnIGNvbnN0cmFpbnQgbW9kaWZpZXIuCisgIHVuc2lnbmVkIElzRWFybHlDbG9iYmVyIDogMTsKKworICAvLy8gSXNEZWJ1ZyAtIFRydWUgaWYgdGhpcyBNT19SZWdpc3RlciAndXNlJyBvcGVyYW5kIGlzIGluIGEgZGVidWcgcHNldWRvLAorICAvLy8gbm90IGEgcmVhbCBpbnN0cnVjdGlvbi4gIFN1Y2ggdXNlcyBzaG91bGQgYmUgaWdub3JlZCBkdXJpbmcgY29kZWdlbi4KKyAgdW5zaWduZWQgSXNEZWJ1ZyA6IDE7CisKKyAgLy8vIFNtYWxsQ29udGVudHMgLSBUaGlzIHJlYWxseSBzaG91bGQgYmUgcGFydCBvZiB0aGUgQ29udGVudHMgdW5pb24sIGJ1dAorICAvLy8gbGl2ZXMgb3V0IGhlcmUgc28gd2UgY2FuIGdldCBhIGJldHRlciBwYWNrZWQgc3RydWN0LgorICAvLy8gTU9fUmVnaXN0ZXI6IFJlZ2lzdGVyIG51bWJlci4KKyAgLy8vIE9mZnNldGVkSW5mbzogTG93IGJpdHMgb2Ygb2Zmc2V0LgorICB1bmlvbiB7CisgICAgdW5zaWduZWQgUmVnTm87ICAgICAgICAgICAvLyBGb3IgTU9fUmVnaXN0ZXIuCisgICAgdW5zaWduZWQgT2Zmc2V0TG87ICAgICAgICAvLyBNYXRjaGVzIENvbnRlbnRzLk9mZnNldGVkSW5mby5PZmZzZXRIaS4KKyAgfSBTbWFsbENvbnRlbnRzOworCisgIC8vLyBQYXJlbnRNSSAtIFRoaXMgaXMgdGhlIGluc3RydWN0aW9uIHRoYXQgdGhpcyBvcGVyYW5kIGlzIGVtYmVkZGVkIGludG8uCisgIC8vLyBUaGlzIGlzIHZhbGlkIGZvciBhbGwgb3BlcmFuZCB0eXBlcywgd2hlbiB0aGUgb3BlcmFuZCBpcyBpbiBhbiBpbnN0ci4KKyAgTWFjaGluZUluc3RyICpQYXJlbnRNSTsKKworICAvLy8gQ29udGVudHMgdW5pb24gLSBUaGlzIGNvbnRhaW5zIHRoZSBwYXlsb2FkIGZvciB0aGUgdmFyaW91cyBvcGVyYW5kIHR5cGVzLgorICB1bmlvbiB7CisgICAgTWFjaGluZUJhc2ljQmxvY2sgKk1CQjsgIC8vIEZvciBNT19NYWNoaW5lQmFzaWNCbG9jay4KKyAgICBjb25zdCBDb25zdGFudEZQICpDRlA7ICAgLy8gRm9yIE1PX0ZQSW1tZWRpYXRlLgorICAgIGNvbnN0IENvbnN0YW50SW50ICpDSTsgICAvLyBGb3IgTU9fQ0ltbWVkaWF0ZS4gSW50ZWdlcnMgPiA2NGJpdC4KKyAgICBpbnQ2NF90IEltbVZhbDsgICAgICAgICAgLy8gRm9yIE1PX0ltbWVkaWF0ZS4KKyAgICBjb25zdCB1aW50MzJfdCAqUmVnTWFzazsgLy8gRm9yIE1PX1JlZ2lzdGVyTWFzayBhbmQgTU9fUmVnaXN0ZXJMaXZlT3V0LgorICAgIGNvbnN0IE1ETm9kZSAqTUQ7ICAgICAgICAvLyBGb3IgTU9fTWV0YWRhdGEuCisgICAgTUNTeW1ib2wgKlN5bTsgICAgICAgICAgIC8vIEZvciBNT19NQ1N5bWJvbC4KKyAgICB1bnNpZ25lZCBDRklJbmRleDsgICAgICAgLy8gRm9yIE1PX0NGSS4KKyAgICBJbnRyaW5zaWM6OklEIEludHJpbnNpY0lEOyAvLyBGb3IgTU9fSW50cmluc2ljSUQuCisgICAgdW5zaWduZWQgUHJlZDsgICAgICAgICAgIC8vIEZvciBNT19QcmVkaWNhdGUKKworICAgIHN0cnVjdCB7ICAgICAgICAgICAgICAgICAgLy8gRm9yIE1PX1JlZ2lzdGVyLgorICAgICAgLy8gUmVnaXN0ZXIgbnVtYmVyIGlzIGluIFNtYWxsQ29udGVudHMuUmVnTm8uCisgICAgICBNYWNoaW5lT3BlcmFuZCAqUHJldjsgICAvLyBBY2Nlc3MgbGlzdCBmb3IgcmVnaXN0ZXIuIFNlZSBNUkkuCisgICAgICBNYWNoaW5lT3BlcmFuZCAqTmV4dDsKKyAgICB9IFJlZzsKKworICAgIC8vLyBPZmZzZXRlZEluZm8gLSBUaGlzIHN0cnVjdCBjb250YWlucyB0aGUgb2Zmc2V0IGFuZCBhbiBvYmplY3QgaWRlbnRpZmllci4KKyAgICAvLy8gdGhpcyByZXByZXNlbnQgdGhlIG9iamVjdCBhcyB3aXRoIGFuIG9wdGlvbmFsIG9mZnNldCBmcm9tIGl0LgorICAgIHN0cnVjdCB7CisgICAgICB1bmlvbiB7CisgICAgICAgIGludCBJbmRleDsgICAgICAgICAgICAgICAgLy8gRm9yIE1PXypJbmRleCAtIFRoZSBpbmRleCBpdHNlbGYuCisgICAgICAgIGNvbnN0IGNoYXIgKlN5bWJvbE5hbWU7ICAgLy8gRm9yIE1PX0V4dGVybmFsU3ltYm9sLgorICAgICAgICBjb25zdCBHbG9iYWxWYWx1ZSAqR1Y7ICAgIC8vIEZvciBNT19HbG9iYWxBZGRyZXNzLgorICAgICAgICBjb25zdCBCbG9ja0FkZHJlc3MgKkJBOyAgIC8vIEZvciBNT19CbG9ja0FkZHJlc3MuCisgICAgICB9IFZhbDsKKyAgICAgIC8vIExvdyBiaXRzIG9mIG9mZnNldCBhcmUgaW4gU21hbGxDb250ZW50cy5PZmZzZXRMby4KKyAgICAgIGludCBPZmZzZXRIaTsgICAgICAgICAgICAgICAvLyBBbiBvZmZzZXQgZnJvbSB0aGUgb2JqZWN0LCBoaWdoIDMyIGJpdHMuCisgICAgfSBPZmZzZXRlZEluZm87CisgIH0gQ29udGVudHM7CisKKyAgZXhwbGljaXQgTWFjaGluZU9wZXJhbmQoTWFjaGluZU9wZXJhbmRUeXBlIEspCisgICAgOiBPcEtpbmQoSyksIFN1YlJlZ19UYXJnZXRGbGFncygwKSwgUGFyZW50TUkobnVsbHB0cikgeworICAgIC8vIEFzc2VydCB0aGF0IHRoZSBsYXlvdXQgaXMgd2hhdCB3ZSBleHBlY3QuIEl0J3MgZWFzeSB0byBncm93IHRoaXMgb2JqZWN0LgorICAgIHN0YXRpY19hc3NlcnQoYWxpZ25vZihNYWNoaW5lT3BlcmFuZCkgPD0gYWxpZ25vZihpbnQ2NF90KSwKKyAgICAgICAgICAgICAgICAgICJNYWNoaW5lT3BlcmFuZCBzaG91bGRuJ3QgYmUgbW9yZSB0aGFuIDggYnl0ZSBhbGlnbmVkIik7CisgICAgc3RhdGljX2Fzc2VydChzaXplb2YoQ29udGVudHMpIDw9IDIgKiBzaXplb2Yodm9pZCAqKSwKKyAgICAgICAgICAgICAgICAgICJDb250ZW50cyBzaG91bGQgYmUgYXQgbW9zdCB0d28gcG9pbnRlcnMiKTsKKyAgICBzdGF0aWNfYXNzZXJ0KHNpemVvZihNYWNoaW5lT3BlcmFuZCkgPD0KKyAgICAgICAgICAgICAgICAgICAgICBhbGlnblRvPGFsaWdub2YoaW50NjRfdCk+KDIgKiBzaXplb2YodW5zaWduZWQpICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDMgKiBzaXplb2Yodm9pZCAqKSksCisgICAgICAgICAgICAgICAgICAiTWFjaGluZU9wZXJhbmQgdG9vIGJpZy4gU2hvdWxkIGJlIEtpbmQsIFNtYWxsQ29udGVudHMsICIKKyAgICAgICAgICAgICAgICAgICJQYXJlbnRNSSwgYW5kIENvbnRlbnRzIik7CisgIH0KKworcHVibGljOgorICAvLy8gZ2V0VHlwZSAtIFJldHVybnMgdGhlIE1hY2hpbmVPcGVyYW5kVHlwZSBmb3IgdGhpcyBvcGVyYW5kLgorICAvLy8KKyAgTWFjaGluZU9wZXJhbmRUeXBlIGdldFR5cGUoKSBjb25zdCB7IHJldHVybiAoTWFjaGluZU9wZXJhbmRUeXBlKU9wS2luZDsgfQorCisgIHVuc2lnbmVkIGdldFRhcmdldEZsYWdzKCkgY29uc3QgeworICAgIHJldHVybiBpc1JlZygpID8gMCA6IFN1YlJlZ19UYXJnZXRGbGFnczsKKyAgfQorICB2b2lkIHNldFRhcmdldEZsYWdzKHVuc2lnbmVkIEYpIHsKKyAgICBhc3NlcnQoIWlzUmVnKCkgJiYgIlJlZ2lzdGVyIG9wZXJhbmRzIGNhbid0IGhhdmUgdGFyZ2V0IGZsYWdzIik7CisgICAgU3ViUmVnX1RhcmdldEZsYWdzID0gRjsKKyAgICBhc3NlcnQoU3ViUmVnX1RhcmdldEZsYWdzID09IEYgJiYgIlRhcmdldCBmbGFncyBvdXQgb2YgcmFuZ2UiKTsKKyAgfQorICB2b2lkIGFkZFRhcmdldEZsYWcodW5zaWduZWQgRikgeworICAgIGFzc2VydCghaXNSZWcoKSAmJiAiUmVnaXN0ZXIgb3BlcmFuZHMgY2FuJ3QgaGF2ZSB0YXJnZXQgZmxhZ3MiKTsKKyAgICBTdWJSZWdfVGFyZ2V0RmxhZ3MgfD0gRjsKKyAgICBhc3NlcnQoKFN1YlJlZ19UYXJnZXRGbGFncyAmIEYpICYmICJUYXJnZXQgZmxhZ3Mgb3V0IG9mIHJhbmdlIik7CisgIH0KKworCisgIC8vLyBnZXRQYXJlbnQgLSBSZXR1cm4gdGhlIGluc3RydWN0aW9uIHRoYXQgdGhpcyBvcGVyYW5kIGJlbG9uZ3MgdG8uCisgIC8vLworICBNYWNoaW5lSW5zdHIgKmdldFBhcmVudCgpIHsgcmV0dXJuIFBhcmVudE1JOyB9CisgIGNvbnN0IE1hY2hpbmVJbnN0ciAqZ2V0UGFyZW50KCkgY29uc3QgeyByZXR1cm4gUGFyZW50TUk7IH0KKworICAvLy8gY2xlYXJQYXJlbnQgLSBSZXNldCB0aGUgcGFyZW50IHBvaW50ZXIuCisgIC8vLworICAvLy8gVGhlIE1hY2hpbmVPcGVyYW5kIGNvcHkgY29uc3RydWN0b3IgYWxzbyBjb3BpZXMgUGFyZW50TUksIGV4cGVjdGluZyB0aGUKKyAgLy8vIG9yaWdpbmFsIHRvIGJlIGRlbGV0ZWQuIElmIGEgTWFjaGluZU9wZXJhbmQgaXMgZXZlciBzdG9yZWQgb3V0c2lkZSBhCisgIC8vLyBNYWNoaW5lSW5zdHIsIHRoZSBwYXJlbnQgcG9pbnRlciBtdXN0IGJlIGNsZWFyZWQuCisgIC8vLworICAvLy8gTmV2ZXIgY2FsbCBjbGVhclBhcmVudCgpIG9uIGFuIG9wZXJhbmQgaW4gYSBNYWNoaW5lSW5zdHIuCisgIC8vLworICB2b2lkIGNsZWFyUGFyZW50KCkgeyBQYXJlbnRNSSA9IG51bGxwdHI7IH0KKworICAvLy8gUHJpbnQgYSBzdWJyZWcgaW5kZXggb3BlcmFuZC4KKyAgLy8vIE1PX0ltbWVkaWF0ZSBvcGVyYW5kcyBjYW4gYWxzbyBiZSBzdWJyZWcgaWRpY2VzLiBJZiBpdCdzIHRoZSBjYXNlLCB0aGUKKyAgLy8vIHN1YnJlZyBpbmRleCBuYW1lIHdpbGwgYmUgcHJpbnRlZC4gTWFjaGluZUluc3RyOjppc09wZXJhbmRTdWJyZWdJZHggY2FuIGJlCisgIC8vLyBjYWxsZWQgdG8gY2hlY2sgdGhpcy4KKyAgc3RhdGljIHZvaWQgcHJpbnRTdWJSZWdJZHgocmF3X29zdHJlYW0gJk9TLCB1aW50NjRfdCBJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkpOworCisgIC8vLyBQcmludCBvcGVyYW5kIHRhcmdldCBmbGFncy4KKyAgc3RhdGljIHZvaWQgcHJpbnRUYXJnZXRGbGFncyhyYXdfb3N0cmVhbSYgT1MsIGNvbnN0IE1hY2hpbmVPcGVyYW5kICZPcCk7CisKKyAgLy8vIFByaW50IGEgTUNTeW1ib2wgYXMgYW4gb3BlcmFuZC4KKyAgc3RhdGljIHZvaWQgcHJpbnRTeW1ib2wocmF3X29zdHJlYW0gJk9TLCBNQ1N5bWJvbCAmU3ltKTsKKworICAvLy8gUHJpbnQgYSBzdGFjayBvYmplY3QgcmVmZXJlbmNlLgorICBzdGF0aWMgdm9pZCBwcmludFN0YWNrT2JqZWN0UmVmZXJlbmNlKHJhd19vc3RyZWFtICZPUywgdW5zaWduZWQgRnJhbWVJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIElzRml4ZWQsIFN0cmluZ1JlZiBOYW1lKTsKKworICAvLy8gUHJpbnQgdGhlIG9mZnNldCB3aXRoIGV4cGxpY2l0ICsvLSBzaWducy4KKyAgc3RhdGljIHZvaWQgcHJpbnRPcGVyYW5kT2Zmc2V0KHJhd19vc3RyZWFtICZPUywgaW50NjRfdCBPZmZzZXQpOworCisgIC8vLyBQcmludCBhbiBJUlNsb3ROdW1iZXIuCisgIHN0YXRpYyB2b2lkIHByaW50SVJTbG90TnVtYmVyKHJhd19vc3RyZWFtICZPUywgaW50IFNsb3QpOworCisgIC8vLyBQcmludCB0aGUgTWFjaGluZU9wZXJhbmQgdG8gXHAgb3MuCisgIC8vLyBQcm92aWRpbmcgYSB2YWxpZCBccCBUUkkgYW5kIFxwIEludHJpbnNpY0luZm8gcmVzdWx0cyBpbiBhIG1vcmUKKyAgLy8vIHRhcmdldC1zcGVjaWZpYyBwcmludGluZy4gSWYgXHAgVFJJIGFuZCBccCBJbnRyaW5zaWNJbmZvIGFyZSBudWxsLCB0aGUKKyAgLy8vIGZ1bmN0aW9uIHdpbGwgdHJ5IHRvIHBpY2sgaXQgdXAgZnJvbSB0aGUgcGFyZW50LgorICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZvcywgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkgPSBudWxscHRyLAorICAgICAgICAgICAgIGNvbnN0IFRhcmdldEludHJpbnNpY0luZm8gKkludHJpbnNpY0luZm8gPSBudWxscHRyKSBjb25zdDsKKworICAvLy8gTW9yZSBjb21wbGV4IHdheSBvZiBwcmludGluZyBhIE1hY2hpbmVPcGVyYW5kLgorICAvLy8gXHBhcmFtIFR5cGVUb1ByaW50IHNwZWNpZmllcyB0aGUgZ2VuZXJpYyB0eXBlIHRvIGJlIHByaW50ZWQgb24gdXNlcyBhbmQKKyAgLy8vIGRlZnMuIEl0IGNhbiBiZSBkZXRlcm1pbmVkIHVzaW5nIE1hY2hpbmVJbnN0cjo6Z2V0VHlwZVRvUHJpbnQuCisgIC8vLyBccGFyYW0gUHJpbnREZWYgLSB3aGV0aGVyIHdlIHdhbnQgdG8gcHJpbnQgYGRlZmAgb24gYW4gb3BlcmFuZCB3aGljaAorICAvLy8gaXNEZWYuIFNvbWV0aW1lcywgaWYgdGhlIG9wZXJhbmQgaXMgcHJpbnRlZCBiZWZvcmUgJz0nLCB3ZSBkb24ndCBwcmludAorICAvLy8gYGRlZmAuCisgIC8vLyBccGFyYW0gSXNTdGFuZGFsb25lIC0gd2hldGhlciB3ZSB3YW50IGEgdmVyYm9zZSBvdXRwdXQgb2YgdGhlIE1PLiBUaGlzCisgIC8vLyBwcmludHMgZXh0cmEgaW5mb3JtYXRpb24gdGhhdCBjYW4gYmUgZWFzaWx5IGluZmVycmVkIHdoZW4gcHJpbnRpbmcgdGhlCisgIC8vLyB3aG9sZSBmdW5jdGlvbiwgYnV0IG5vdCB3aGVuIHByaW50aW5nIG9ubHkgYSBmcmFnbWVudCBvZiBpdC4KKyAgLy8vIFxwYXJhbSBTaG91bGRQcmludFJlZ2lzdGVyVGllcyAtIHdoZXRoZXIgd2Ugd2FudCB0byBwcmludCByZWdpc3RlciB0aWVzLgorICAvLy8gU29tZXRpbWVzIHRoZXkgYXJlIGVhc2lseSBkZXRlcm1pbmVkIGJ5IHRoZSBpbnN0cnVjdGlvbidzIGRlc2NyaXB0b3IKKyAgLy8vIChNYWNoaW5lSW5zdHI6Omhhc0NvbXBsZXhSZWdpdGVyVGllcyBjYW4gZGV0ZXJtaW5lIGlmIGl0J3MgbmVlZGVkKS4KKyAgLy8vIFxwYXJhbSBUaWVkT3BlcmFuZElkeCAtIGlmIHdlIG5lZWQgdG8gcHJpbnQgcmVnaXN0ZXIgdGllcyB0aGlzIG5lZWRzIHRvCisgIC8vLyBwcm92aWRlIHRoZSBpbmRleCBvZiB0aGUgdGllZCByZWdpc3Rlci4gSWYgbm90LCBpdCB3aWxsIGJlIGlnbm9yZWQuCisgIC8vLyBccGFyYW0gVFJJIC0gcHJvdmlkZSBtb3JlIHRhcmdldC1zcGVjaWZpYyBpbmZvcm1hdGlvbiB0byB0aGUgcHJpbnRlci4KKyAgLy8vIFVubGlrZSB0aGUgcHJldmlvdXMgZnVuY3Rpb24sIHRoaXMgb25lIHdpbGwgbm90IHRyeSBhbmQgZ2V0IHRoZQorICAvLy8gaW5mb3JtYXRpb24gZnJvbSBpdCdzIHBhcmVudC4KKyAgLy8vIFxwYXJhbSBJbnRyaW5zaWNJbmZvIC0gc2FtZSBhcyBccCBUUkkuCisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJm9zLCBNb2R1bGVTbG90VHJhY2tlciAmTVNULCBMTFQgVHlwZVRvUHJpbnQsCisgICAgICAgICAgICAgYm9vbCBQcmludERlZiwgYm9vbCBJc1N0YW5kYWxvbmUsIGJvb2wgU2hvdWxkUHJpbnRSZWdpc3RlclRpZXMsCisgICAgICAgICAgICAgdW5zaWduZWQgVGllZE9wZXJhbmRJZHgsIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJLAorICAgICAgICAgICAgIGNvbnN0IFRhcmdldEludHJpbnNpY0luZm8gKkludHJpbnNpY0luZm8pIGNvbnN0OworCisgIHZvaWQgZHVtcCgpIGNvbnN0OworCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLyBBY2Nlc3NvcnMgdGhhdCB0ZWxsIHlvdSB3aGF0IGtpbmQgb2YgTWFjaGluZU9wZXJhbmQgeW91J3JlIGxvb2tpbmcgYXQuCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisgIC8vLyBpc1JlZyAtIFRlc3RzIGlmIHRoaXMgaXMgYSBNT19SZWdpc3RlciBvcGVyYW5kLgorICBib29sIGlzUmVnKCkgY29uc3QgeyByZXR1cm4gT3BLaW5kID09IE1PX1JlZ2lzdGVyOyB9CisgIC8vLyBpc0ltbSAtIFRlc3RzIGlmIHRoaXMgaXMgYSBNT19JbW1lZGlhdGUgb3BlcmFuZC4KKyAgYm9vbCBpc0ltbSgpIGNvbnN0IHsgcmV0dXJuIE9wS2luZCA9PSBNT19JbW1lZGlhdGU7IH0KKyAgLy8vIGlzQ0ltbSAtIFRlc3QgaWYgdGhpcyBpcyBhIE1PX0NJbW1lZGlhdGUgb3BlcmFuZC4KKyAgYm9vbCBpc0NJbW0oKSBjb25zdCB7IHJldHVybiBPcEtpbmQgPT0gTU9fQ0ltbWVkaWF0ZTsgfQorICAvLy8gaXNGUEltbSAtIFRlc3RzIGlmIHRoaXMgaXMgYSBNT19GUEltbWVkaWF0ZSBvcGVyYW5kLgorICBib29sIGlzRlBJbW0oKSBjb25zdCB7IHJldHVybiBPcEtpbmQgPT0gTU9fRlBJbW1lZGlhdGU7IH0KKyAgLy8vIGlzTUJCIC0gVGVzdHMgaWYgdGhpcyBpcyBhIE1PX01hY2hpbmVCYXNpY0Jsb2NrIG9wZXJhbmQuCisgIGJvb2wgaXNNQkIoKSBjb25zdCB7IHJldHVybiBPcEtpbmQgPT0gTU9fTWFjaGluZUJhc2ljQmxvY2s7IH0KKyAgLy8vIGlzRkkgLSBUZXN0cyBpZiB0aGlzIGlzIGEgTU9fRnJhbWVJbmRleCBvcGVyYW5kLgorICBib29sIGlzRkkoKSBjb25zdCB7IHJldHVybiBPcEtpbmQgPT0gTU9fRnJhbWVJbmRleDsgfQorICAvLy8gaXNDUEkgLSBUZXN0cyBpZiB0aGlzIGlzIGEgTU9fQ29uc3RhbnRQb29sSW5kZXggb3BlcmFuZC4KKyAgYm9vbCBpc0NQSSgpIGNvbnN0IHsgcmV0dXJuIE9wS2luZCA9PSBNT19Db25zdGFudFBvb2xJbmRleDsgfQorICAvLy8gaXNUYXJnZXRJbmRleCAtIFRlc3RzIGlmIHRoaXMgaXMgYSBNT19UYXJnZXRJbmRleCBvcGVyYW5kLgorICBib29sIGlzVGFyZ2V0SW5kZXgoKSBjb25zdCB7IHJldHVybiBPcEtpbmQgPT0gTU9fVGFyZ2V0SW5kZXg7IH0KKyAgLy8vIGlzSlRJIC0gVGVzdHMgaWYgdGhpcyBpcyBhIE1PX0p1bXBUYWJsZUluZGV4IG9wZXJhbmQuCisgIGJvb2wgaXNKVEkoKSBjb25zdCB7IHJldHVybiBPcEtpbmQgPT0gTU9fSnVtcFRhYmxlSW5kZXg7IH0KKyAgLy8vIGlzR2xvYmFsIC0gVGVzdHMgaWYgdGhpcyBpcyBhIE1PX0dsb2JhbEFkZHJlc3Mgb3BlcmFuZC4KKyAgYm9vbCBpc0dsb2JhbCgpIGNvbnN0IHsgcmV0dXJuIE9wS2luZCA9PSBNT19HbG9iYWxBZGRyZXNzOyB9CisgIC8vLyBpc1N5bWJvbCAtIFRlc3RzIGlmIHRoaXMgaXMgYSBNT19FeHRlcm5hbFN5bWJvbCBvcGVyYW5kLgorICBib29sIGlzU3ltYm9sKCkgY29uc3QgeyByZXR1cm4gT3BLaW5kID09IE1PX0V4dGVybmFsU3ltYm9sOyB9CisgIC8vLyBpc0Jsb2NrQWRkcmVzcyAtIFRlc3RzIGlmIHRoaXMgaXMgYSBNT19CbG9ja0FkZHJlc3Mgb3BlcmFuZC4KKyAgYm9vbCBpc0Jsb2NrQWRkcmVzcygpIGNvbnN0IHsgcmV0dXJuIE9wS2luZCA9PSBNT19CbG9ja0FkZHJlc3M7IH0KKyAgLy8vIGlzUmVnTWFzayAtIFRlc3RzIGlmIHRoaXMgaXMgYSBNT19SZWdpc3Rlck1hc2sgb3BlcmFuZC4KKyAgYm9vbCBpc1JlZ01hc2soKSBjb25zdCB7IHJldHVybiBPcEtpbmQgPT0gTU9fUmVnaXN0ZXJNYXNrOyB9CisgIC8vLyBpc1JlZ0xpdmVPdXQgLSBUZXN0cyBpZiB0aGlzIGlzIGEgTU9fUmVnaXN0ZXJMaXZlT3V0IG9wZXJhbmQuCisgIGJvb2wgaXNSZWdMaXZlT3V0KCkgY29uc3QgeyByZXR1cm4gT3BLaW5kID09IE1PX1JlZ2lzdGVyTGl2ZU91dDsgfQorICAvLy8gaXNNZXRhZGF0YSAtIFRlc3RzIGlmIHRoaXMgaXMgYSBNT19NZXRhZGF0YSBvcGVyYW5kLgorICBib29sIGlzTWV0YWRhdGEoKSBjb25zdCB7IHJldHVybiBPcEtpbmQgPT0gTU9fTWV0YWRhdGE7IH0KKyAgYm9vbCBpc01DU3ltYm9sKCkgY29uc3QgeyByZXR1cm4gT3BLaW5kID09IE1PX01DU3ltYm9sOyB9CisgIGJvb2wgaXNDRklJbmRleCgpIGNvbnN0IHsgcmV0dXJuIE9wS2luZCA9PSBNT19DRklJbmRleDsgfQorICBib29sIGlzSW50cmluc2ljSUQoKSBjb25zdCB7IHJldHVybiBPcEtpbmQgPT0gTU9fSW50cmluc2ljSUQ7IH0KKyAgYm9vbCBpc1ByZWRpY2F0ZSgpIGNvbnN0IHsgcmV0dXJuIE9wS2luZCA9PSBNT19QcmVkaWNhdGU7IH0KKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIEFjY2Vzc29ycyBmb3IgUmVnaXN0ZXIgT3BlcmFuZHMKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyAgLy8vIGdldFJlZyAtIFJldHVybnMgdGhlIHJlZ2lzdGVyIG51bWJlci4KKyAgdW5zaWduZWQgZ2V0UmVnKCkgY29uc3QgeworICAgIGFzc2VydChpc1JlZygpICYmICJUaGlzIGlzIG5vdCBhIHJlZ2lzdGVyIG9wZXJhbmQhIik7CisgICAgcmV0dXJuIFNtYWxsQ29udGVudHMuUmVnTm87CisgIH0KKworICB1bnNpZ25lZCBnZXRTdWJSZWcoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzUmVnKCkgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIGFjY2Vzc29yIik7CisgICAgcmV0dXJuIFN1YlJlZ19UYXJnZXRGbGFnczsKKyAgfQorCisgIGJvb2wgaXNVc2UoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzUmVnKCkgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIGFjY2Vzc29yIik7CisgICAgcmV0dXJuICFJc0RlZjsKKyAgfQorCisgIGJvb2wgaXNEZWYoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzUmVnKCkgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIGFjY2Vzc29yIik7CisgICAgcmV0dXJuIElzRGVmOworICB9CisKKyAgYm9vbCBpc0ltcGxpY2l0KCkgY29uc3QgeworICAgIGFzc2VydChpc1JlZygpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBhY2Nlc3NvciIpOworICAgIHJldHVybiBJc0ltcDsKKyAgfQorCisgIGJvb2wgaXNEZWFkKCkgY29uc3QgeworICAgIGFzc2VydChpc1JlZygpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBhY2Nlc3NvciIpOworICAgIHJldHVybiBJc0RlYWRPcktpbGwgJiBJc0RlZjsKKyAgfQorCisgIGJvb2wgaXNLaWxsKCkgY29uc3QgeworICAgIGFzc2VydChpc1JlZygpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBhY2Nlc3NvciIpOworICAgIHJldHVybiBJc0RlYWRPcktpbGwgJiAhSXNEZWY7CisgIH0KKworICBib29sIGlzVW5kZWYoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzUmVnKCkgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIGFjY2Vzc29yIik7CisgICAgcmV0dXJuIElzVW5kZWY7CisgIH0KKworICAvLy8gaXNSZW5hbWFibGUgLSBSZXR1cm5zIHRydWUgaWYgdGhpcyByZWdpc3RlciBtYXkgYmUgcmVuYW1lZCwgaS5lLiBpdCBkb2VzCisgIC8vLyBub3QgZ2VuZXJhdGUgYSB2YWx1ZSB0aGF0IGlzIHNvbWVob3cgcmVhZCBpbiBhIHdheSB0aGF0IGlzIG5vdCByZXByZXNlbnRlZAorICAvLy8gYnkgdGhlIE1hY2hpbmUgSVIgKGUuZy4gdG8gbWVldCBhbiBBQkkgb3IgSVNBIHJlcXVpcmVtZW50KS4gIFRoaXMgaXMgb25seQorICAvLy8gdmFsaWQgb24gcGh5c2ljYWwgcmVnaXN0ZXIgb3BlcmFuZHMuICBWaXJ0dWFsIHJlZ2lzdGVycyBhcmUgYXNzdW1lZCB0bworICAvLy8gYWx3YXlzIGJlIHJlbmFtYWJsZSByZWdhcmRsZXNzIG9mIHRoZSB2YWx1ZSBvZiB0aGlzIGZpZWxkLgorICAvLy8KKyAgLy8vIE9wZXJhbmRzIHRoYXQgYXJlIHJlbmFtYWJsZSBjYW4gZnJlZWx5IGJlIGNoYW5nZWQgdG8gYW55IG90aGVyIHJlZ2lzdGVyCisgIC8vLyB0aGF0IGlzIGEgbWVtYmVyIG9mIHRoZSByZWdpc3RlciBjbGFzcyByZXR1cm5lZCBieQorICAvLy8gTUktPmdldFJlZ0NsYXNzQ29uc3RyYWludCgpLgorICAvLy8KKyAgLy8vIGlzUmVuYW1hYmxlIGNhbiByZXR1cm4gZmFsc2UgZm9yIHNldmVyYWwgZGlmZmVyZW50IHJlYXNvbnM6CisgIC8vLworICAvLy8gLSBBQkkgY29uc3RyYWludHMgKHNpbmNlIGxpdmVuZXNzIGlzIG5vdCBhbHdheXMgcHJlY2lzZWx5IG1vZGVsZWQpLiAgV2UKKyAgLy8vICAgY29uc2VydmF0aXZlbHkgaGFuZGxlIHRoZXNlIGNhc2VzIGJ5IHNldHRpbmcgYWxsIHBoeXNpY2FsIHJlZ2lzdGVyCisgIC8vLyAgIG9wZXJhbmRzIHRoYXQgZGlkbuKAmXQgc3RhcnQgb3V0IGFzIHZpcnR1YWwgcmVncyB0byBub3QgYmUgcmVuYW1hYmxlLgorICAvLy8gICBBbHNvIGFueSBwaHlzaWNhbCByZWdpc3RlciBvcGVyYW5kcyBjcmVhdGVkIGFmdGVyIHJlZ2lzdGVyIGFsbG9jYXRpb24gb3IKKyAgLy8vICAgd2hvc2UgcmVnaXN0ZXIgaXMgY2hhbmdlZCBhZnRlciByZWdpc3RlciBhbGxvY2F0aW9uIHdpbGwgbm90IGJlCisgIC8vLyAgIHJlbmFtYWJsZS4gIFRoaXMgc3RhdGUgaXMgdHJhY2tlZCBpbiB0aGUgTWFjaGluZU9wZXJhbmQ6OklzUmVuYW1hYmxlCisgIC8vLyAgIGJpdC4KKyAgLy8vCisgIC8vLyAtIE9wY29kZS90YXJnZXQgY29uc3RyYWludHM6IGZvciBvcGNvZGVzIHRoYXQgaGF2ZSBjb21wbGV4IHJlZ2lzdGVyIGNsYXNzCisgIC8vLyAgIHJlcXVpcmVtZW50cyAoZS5nLiB0aGF0IGRlcGVuZCBvbiBvdGhlciBvcGVyYW5kcy9pbnN0cnVjdGlvbnMpLCB3ZSBzZXQKKyAgLy8vICAgaGFzRXh0cmFTcmNSZWdBbGxvY1JlcS9oYXNFeHRyYURzdFJlZ0FsbG9jUmVxIGluIHRoZSBtYWNoaW5lIG9wY29kZQorICAvLy8gICBkZXNjcmlwdGlvbi4gIE9wZXJhbmRzIGJlbG9uZ2luZyB0byBpbnN0cnVjdGlvbnMgd2l0aCBvcGNvZGVzIHRoYXQgYXJlCisgIC8vLyAgIG1hcmtlZCBoYXNFeHRyYVNyY1JlZ0FsbG9jUmVxL2hhc0V4dHJhRHN0UmVnQWxsb2NSZXEgcmV0dXJuIGZhbHNlIGZyb20KKyAgLy8vICAgaXNSZW5hbWFibGUoKS4gIEFkZGl0aW9uYWxseSwgdGhlIEFsbG93UmVnaXN0ZXJSZW5hbWluZyB0YXJnZXQgcHJvcGVydHkKKyAgLy8vICAgcHJldmVudHMgYW55IG9wZXJhbmRzIGZyb20gYmVpbmcgbWFya2VkIHJlbmFtYWJsZSBmb3IgdGFyZ2V0cyB0aGF0IGRvbid0CisgIC8vLyAgIGhhdmUgZGV0YWlsZWQgb3Bjb2RlIGhhc0V4dHJhU3JjUmVnQWxsb2NSZXEvaGFzRXh0cmFEc3RSZWdBbGxvY1JlcQorICAvLy8gICB2YWx1ZXMuCisgIGJvb2wgaXNSZW5hbWFibGUoKSBjb25zdDsKKworICBib29sIGlzSW50ZXJuYWxSZWFkKCkgY29uc3QgeworICAgIGFzc2VydChpc1JlZygpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBhY2Nlc3NvciIpOworICAgIHJldHVybiBJc0ludGVybmFsUmVhZDsKKyAgfQorCisgIGJvb2wgaXNFYXJseUNsb2JiZXIoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzUmVnKCkgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIGFjY2Vzc29yIik7CisgICAgcmV0dXJuIElzRWFybHlDbG9iYmVyOworICB9CisKKyAgYm9vbCBpc1RpZWQoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzUmVnKCkgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIGFjY2Vzc29yIik7CisgICAgcmV0dXJuIFRpZWRUbzsKKyAgfQorCisgIGJvb2wgaXNEZWJ1ZygpIGNvbnN0IHsKKyAgICBhc3NlcnQoaXNSZWcoKSAmJiAiV3JvbmcgTWFjaGluZU9wZXJhbmQgYWNjZXNzb3IiKTsKKyAgICByZXR1cm4gSXNEZWJ1ZzsKKyAgfQorCisgIC8vLyByZWFkc1JlZyAtIFJldHVybnMgdHJ1ZSBpZiB0aGlzIG9wZXJhbmQgcmVhZHMgdGhlIHByZXZpb3VzIHZhbHVlIG9mIGl0cworICAvLy8gcmVnaXN0ZXIuICBBIHVzZSBvcGVyYW5kIHdpdGggdGhlIDx1bmRlZj4gZmxhZyBzZXQgZG9lc24ndCByZWFkIGl0cworICAvLy8gcmVnaXN0ZXIuICBBIHN1Yi1yZWdpc3RlciBkZWYgaW1wbGljaXRseSByZWFkcyB0aGUgb3RoZXIgcGFydHMgb2YgdGhlCisgIC8vLyByZWdpc3RlciBiZWluZyByZWRlZmluZWQgdW5sZXNzIHRoZSA8dW5kZWY+IGZsYWcgaXMgc2V0LgorICAvLy8KKyAgLy8vIFRoaXMgcmVmZXJzIHRvIHJlYWRpbmcgdGhlIHJlZ2lzdGVyIHZhbHVlIGZyb20gYmVmb3JlIHRoZSBjdXJyZW50CisgIC8vLyBpbnN0cnVjdGlvbiBvciBidW5kbGUuIEludGVybmFsIGJ1bmRsZSByZWFkcyBhcmUgbm90IGluY2x1ZGVkLgorICBib29sIHJlYWRzUmVnKCkgY29uc3QgeworICAgIGFzc2VydChpc1JlZygpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBhY2Nlc3NvciIpOworICAgIHJldHVybiAhaXNVbmRlZigpICYmICFpc0ludGVybmFsUmVhZCgpICYmIChpc1VzZSgpIHx8IGdldFN1YlJlZygpKTsKKyAgfQorCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLyBNdXRhdG9ycyBmb3IgUmVnaXN0ZXIgT3BlcmFuZHMKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyAgLy8vIENoYW5nZSB0aGUgcmVnaXN0ZXIgdGhpcyBvcGVyYW5kIGNvcnJlc3BvbmRzIHRvLgorICAvLy8KKyAgdm9pZCBzZXRSZWcodW5zaWduZWQgUmVnKTsKKworICB2b2lkIHNldFN1YlJlZyh1bnNpZ25lZCBzdWJSZWcpIHsKKyAgICBhc3NlcnQoaXNSZWcoKSAmJiAiV3JvbmcgTWFjaGluZU9wZXJhbmQgbXV0YXRvciIpOworICAgIFN1YlJlZ19UYXJnZXRGbGFncyA9IHN1YlJlZzsKKyAgICBhc3NlcnQoU3ViUmVnX1RhcmdldEZsYWdzID09IHN1YlJlZyAmJiAiU3ViUmVnIG91dCBvZiByYW5nZSIpOworICB9CisKKyAgLy8vIHN1YnN0VmlydFJlZyAtIFN1YnN0aXR1dGUgdGhlIGN1cnJlbnQgcmVnaXN0ZXIgd2l0aCB0aGUgdmlydHVhbAorICAvLy8gc3VicmVnaXN0ZXIgUmVnOlN1YlJlZy4gVGFrZSBhbnkgZXhpc3RpbmcgU3ViUmVnIGluZGV4IGludG8gYWNjb3VudCwKKyAgLy8vIHVzaW5nIFRhcmdldFJlZ2lzdGVySW5mbyB0byBjb21wb3NlIHRoZSBzdWJyZWcgaW5kaWNlcyBpZiBuZWNlc3NhcnkuCisgIC8vLyBSZWcgbXVzdCBiZSBhIHZpcnR1YWwgcmVnaXN0ZXIsIFN1YklkeCBjYW4gYmUgMC4KKyAgLy8vCisgIHZvaWQgc3Vic3RWaXJ0UmVnKHVuc2lnbmVkIFJlZywgdW5zaWduZWQgU3ViSWR4LCBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8mKTsKKworICAvLy8gc3Vic3RQaHlzUmVnIC0gU3Vic3RpdHV0ZSB0aGUgY3VycmVudCByZWdpc3RlciB3aXRoIHRoZSBwaHlzaWNhbCByZWdpc3RlcgorICAvLy8gUmVnLCB0YWtpbmcgYW55IGV4aXN0aW5nIFN1YlJlZyBpbnRvIGFjY291bnQuIEZvciBpbnN0YW5jZSwKKyAgLy8vIHN1YnN0UGh5c1JlZyglZWF4KSB3aWxsIGNoYW5nZSAlcmVnMTAyNDpzdWJfOGJpdCB0byAlYWwuCisgIC8vLworICB2b2lkIHN1YnN0UGh5c1JlZyh1bnNpZ25lZCBSZWcsIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyYpOworCisgIHZvaWQgc2V0SXNVc2UoYm9vbCBWYWwgPSB0cnVlKSB7IHNldElzRGVmKCFWYWwpOyB9CisKKyAgLy8vIENoYW5nZSBhIGRlZiB0byBhIHVzZSwgb3IgYSB1c2UgdG8gYSBkZWYuCisgIHZvaWQgc2V0SXNEZWYoYm9vbCBWYWwgPSB0cnVlKTsKKworICB2b2lkIHNldEltcGxpY2l0KGJvb2wgVmFsID0gdHJ1ZSkgeworICAgIGFzc2VydChpc1JlZygpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBtdXRhdG9yIik7CisgICAgSXNJbXAgPSBWYWw7CisgIH0KKworICB2b2lkIHNldElzS2lsbChib29sIFZhbCA9IHRydWUpIHsKKyAgICBhc3NlcnQoaXNSZWcoKSAmJiAhSXNEZWYgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIG11dGF0b3IiKTsKKyAgICBhc3NlcnQoKCFWYWwgfHwgIWlzRGVidWcoKSkgJiYgIk1hcmtpbmcgYSBkZWJ1ZyBvcGVyYXRpb24gYXMga2lsbCIpOworICAgIElzRGVhZE9yS2lsbCA9IFZhbDsKKyAgfQorCisgIHZvaWQgc2V0SXNEZWFkKGJvb2wgVmFsID0gdHJ1ZSkgeworICAgIGFzc2VydChpc1JlZygpICYmIElzRGVmICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBtdXRhdG9yIik7CisgICAgSXNEZWFkT3JLaWxsID0gVmFsOworICB9CisKKyAgdm9pZCBzZXRJc1VuZGVmKGJvb2wgVmFsID0gdHJ1ZSkgeworICAgIGFzc2VydChpc1JlZygpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBtdXRhdG9yIik7CisgICAgSXNVbmRlZiA9IFZhbDsKKyAgfQorCisgIHZvaWQgc2V0SXNSZW5hbWFibGUoYm9vbCBWYWwgPSB0cnVlKTsKKworICB2b2lkIHNldElzSW50ZXJuYWxSZWFkKGJvb2wgVmFsID0gdHJ1ZSkgeworICAgIGFzc2VydChpc1JlZygpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBtdXRhdG9yIik7CisgICAgSXNJbnRlcm5hbFJlYWQgPSBWYWw7CisgIH0KKworICB2b2lkIHNldElzRWFybHlDbG9iYmVyKGJvb2wgVmFsID0gdHJ1ZSkgeworICAgIGFzc2VydChpc1JlZygpICYmIElzRGVmICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBtdXRhdG9yIik7CisgICAgSXNFYXJseUNsb2JiZXIgPSBWYWw7CisgIH0KKworICB2b2lkIHNldElzRGVidWcoYm9vbCBWYWwgPSB0cnVlKSB7CisgICAgYXNzZXJ0KGlzUmVnKCkgJiYgIUlzRGVmICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBtdXRhdG9yIik7CisgICAgSXNEZWJ1ZyA9IFZhbDsKKyAgfQorCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLyBBY2Nlc3NvcnMgZm9yIHZhcmlvdXMgb3BlcmFuZCB0eXBlcy4KKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyAgaW50NjRfdCBnZXRJbW0oKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzSW1tKCkgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIGFjY2Vzc29yIik7CisgICAgcmV0dXJuIENvbnRlbnRzLkltbVZhbDsKKyAgfQorCisgIGNvbnN0IENvbnN0YW50SW50ICpnZXRDSW1tKCkgY29uc3QgeworICAgIGFzc2VydChpc0NJbW0oKSAmJiAiV3JvbmcgTWFjaGluZU9wZXJhbmQgYWNjZXNzb3IiKTsKKyAgICByZXR1cm4gQ29udGVudHMuQ0k7CisgIH0KKworICBjb25zdCBDb25zdGFudEZQICpnZXRGUEltbSgpIGNvbnN0IHsKKyAgICBhc3NlcnQoaXNGUEltbSgpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBhY2Nlc3NvciIpOworICAgIHJldHVybiBDb250ZW50cy5DRlA7CisgIH0KKworICBNYWNoaW5lQmFzaWNCbG9jayAqZ2V0TUJCKCkgY29uc3QgeworICAgIGFzc2VydChpc01CQigpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBhY2Nlc3NvciIpOworICAgIHJldHVybiBDb250ZW50cy5NQkI7CisgIH0KKworICBpbnQgZ2V0SW5kZXgoKSBjb25zdCB7CisgICAgYXNzZXJ0KChpc0ZJKCkgfHwgaXNDUEkoKSB8fCBpc1RhcmdldEluZGV4KCkgfHwgaXNKVEkoKSkgJiYKKyAgICAgICAgICAgIldyb25nIE1hY2hpbmVPcGVyYW5kIGFjY2Vzc29yIik7CisgICAgcmV0dXJuIENvbnRlbnRzLk9mZnNldGVkSW5mby5WYWwuSW5kZXg7CisgIH0KKworICBjb25zdCBHbG9iYWxWYWx1ZSAqZ2V0R2xvYmFsKCkgY29uc3QgeworICAgIGFzc2VydChpc0dsb2JhbCgpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBhY2Nlc3NvciIpOworICAgIHJldHVybiBDb250ZW50cy5PZmZzZXRlZEluZm8uVmFsLkdWOworICB9CisKKyAgY29uc3QgQmxvY2tBZGRyZXNzICpnZXRCbG9ja0FkZHJlc3MoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzQmxvY2tBZGRyZXNzKCkgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIGFjY2Vzc29yIik7CisgICAgcmV0dXJuIENvbnRlbnRzLk9mZnNldGVkSW5mby5WYWwuQkE7CisgIH0KKworICBNQ1N5bWJvbCAqZ2V0TUNTeW1ib2woKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzTUNTeW1ib2woKSAmJiAiV3JvbmcgTWFjaGluZU9wZXJhbmQgYWNjZXNzb3IiKTsKKyAgICByZXR1cm4gQ29udGVudHMuU3ltOworICB9CisKKyAgdW5zaWduZWQgZ2V0Q0ZJSW5kZXgoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzQ0ZJSW5kZXgoKSAmJiAiV3JvbmcgTWFjaGluZU9wZXJhbmQgYWNjZXNzb3IiKTsKKyAgICByZXR1cm4gQ29udGVudHMuQ0ZJSW5kZXg7CisgIH0KKworICBJbnRyaW5zaWM6OklEIGdldEludHJpbnNpY0lEKCkgY29uc3QgeworICAgIGFzc2VydChpc0ludHJpbnNpY0lEKCkgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIGFjY2Vzc29yIik7CisgICAgcmV0dXJuIENvbnRlbnRzLkludHJpbnNpY0lEOworICB9CisKKyAgdW5zaWduZWQgZ2V0UHJlZGljYXRlKCkgY29uc3QgeworICAgIGFzc2VydChpc1ByZWRpY2F0ZSgpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBhY2Nlc3NvciIpOworICAgIHJldHVybiBDb250ZW50cy5QcmVkOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgb2Zmc2V0IGZyb20gdGhlIHN5bWJvbCBpbiB0aGlzIG9wZXJhbmQuIFRoaXMgYWx3YXlzIHJldHVybnMgMAorICAvLy8gZm9yIEV4dGVybmFsU3ltYm9sIG9wZXJhbmRzLgorICBpbnQ2NF90IGdldE9mZnNldCgpIGNvbnN0IHsKKyAgICBhc3NlcnQoKGlzR2xvYmFsKCkgfHwgaXNTeW1ib2woKSB8fCBpc01DU3ltYm9sKCkgfHwgaXNDUEkoKSB8fAorICAgICAgICAgICAgaXNUYXJnZXRJbmRleCgpIHx8IGlzQmxvY2tBZGRyZXNzKCkpICYmCisgICAgICAgICAgICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBhY2Nlc3NvciIpOworICAgIHJldHVybiBpbnQ2NF90KHVpbnQ2NF90KENvbnRlbnRzLk9mZnNldGVkSW5mby5PZmZzZXRIaSkgPDwgMzIpIHwKKyAgICAgICAgICAgU21hbGxDb250ZW50cy5PZmZzZXRMbzsKKyAgfQorCisgIGNvbnN0IGNoYXIgKmdldFN5bWJvbE5hbWUoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzU3ltYm9sKCkgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIGFjY2Vzc29yIik7CisgICAgcmV0dXJuIENvbnRlbnRzLk9mZnNldGVkSW5mby5WYWwuU3ltYm9sTmFtZTsKKyAgfQorCisgIC8vLyBjbG9iYmVyc1BoeXNSZWcgLSBSZXR1cm5zIHRydWUgaWYgdGhpcyBSZWdNYXNrIGNsb2JiZXJzIFBoeXNSZWcuCisgIC8vLyBJdCBpcyBzb21ldGltZXMgbmVjZXNzYXJ5IHRvIGRldGFjaCB0aGUgcmVnaXN0ZXIgbWFzayBwb2ludGVyIGZyb20gaXRzCisgIC8vLyBtYWNoaW5lIG9wZXJhbmQuIFRoaXMgc3RhdGljIG1ldGhvZCBjYW4gYmUgdXNlZCBmb3Igc3VjaCBkZXRhY2hlZCBiaXQKKyAgLy8vIG1hc2sgcG9pbnRlcnMuCisgIHN0YXRpYyBib29sIGNsb2JiZXJzUGh5c1JlZyhjb25zdCB1aW50MzJfdCAqUmVnTWFzaywgdW5zaWduZWQgUGh5c1JlZykgeworICAgIC8vIFNlZSBUYXJnZXRSZWdpc3RlckluZm8uaC4KKyAgICBhc3NlcnQoUGh5c1JlZyA8ICgxdSA8PCAzMCkgJiYgIk5vdCBhIHBoeXNpY2FsIHJlZ2lzdGVyIik7CisgICAgcmV0dXJuICEoUmVnTWFza1tQaHlzUmVnIC8gMzJdICYgKDF1IDw8IFBoeXNSZWcgJSAzMikpOworICB9CisKKyAgLy8vIGNsb2JiZXJzUGh5c1JlZyAtIFJldHVybnMgdHJ1ZSBpZiB0aGlzIFJlZ01hc2sgb3BlcmFuZCBjbG9iYmVycyBQaHlzUmVnLgorICBib29sIGNsb2JiZXJzUGh5c1JlZyh1bnNpZ25lZCBQaHlzUmVnKSBjb25zdCB7CisgICAgIHJldHVybiBjbG9iYmVyc1BoeXNSZWcoZ2V0UmVnTWFzaygpLCBQaHlzUmVnKTsKKyAgfQorCisgIC8vLyBnZXRSZWdNYXNrIC0gUmV0dXJucyBhIGJpdCBtYXNrIG9mIHJlZ2lzdGVycyBwcmVzZXJ2ZWQgYnkgdGhpcyBSZWdNYXNrCisgIC8vLyBvcGVyYW5kLgorICBjb25zdCB1aW50MzJfdCAqZ2V0UmVnTWFzaygpIGNvbnN0IHsKKyAgICBhc3NlcnQoaXNSZWdNYXNrKCkgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIGFjY2Vzc29yIik7CisgICAgcmV0dXJuIENvbnRlbnRzLlJlZ01hc2s7CisgIH0KKworICAvLy8gZ2V0UmVnTGl2ZU91dCAtIFJldHVybnMgYSBiaXQgbWFzayBvZiBsaXZlLW91dCByZWdpc3RlcnMuCisgIGNvbnN0IHVpbnQzMl90ICpnZXRSZWdMaXZlT3V0KCkgY29uc3QgeworICAgIGFzc2VydChpc1JlZ0xpdmVPdXQoKSAmJiAiV3JvbmcgTWFjaGluZU9wZXJhbmQgYWNjZXNzb3IiKTsKKyAgICByZXR1cm4gQ29udGVudHMuUmVnTWFzazsKKyAgfQorCisgIGNvbnN0IE1ETm9kZSAqZ2V0TWV0YWRhdGEoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzTWV0YWRhdGEoKSAmJiAiV3JvbmcgTWFjaGluZU9wZXJhbmQgYWNjZXNzb3IiKTsKKyAgICByZXR1cm4gQ29udGVudHMuTUQ7CisgIH0KKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gTXV0YXRvcnMgZm9yIHZhcmlvdXMgb3BlcmFuZCB0eXBlcy4KKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyAgdm9pZCBzZXRJbW0oaW50NjRfdCBpbW1WYWwpIHsKKyAgICBhc3NlcnQoaXNJbW0oKSAmJiAiV3JvbmcgTWFjaGluZU9wZXJhbmQgbXV0YXRvciIpOworICAgIENvbnRlbnRzLkltbVZhbCA9IGltbVZhbDsKKyAgfQorCisgIHZvaWQgc2V0RlBJbW0oY29uc3QgQ29uc3RhbnRGUCAqQ0ZQKSB7CisgICAgYXNzZXJ0KGlzRlBJbW0oKSAmJiAiV3JvbmcgTWFjaGluZU9wZXJhbmQgbXV0YXRvciIpOworICAgIENvbnRlbnRzLkNGUCA9IENGUDsKKyAgfQorCisgIHZvaWQgc2V0T2Zmc2V0KGludDY0X3QgT2Zmc2V0KSB7CisgICAgYXNzZXJ0KChpc0dsb2JhbCgpIHx8IGlzU3ltYm9sKCkgfHwgaXNNQ1N5bWJvbCgpIHx8IGlzQ1BJKCkgfHwKKyAgICAgICAgICAgIGlzVGFyZ2V0SW5kZXgoKSB8fCBpc0Jsb2NrQWRkcmVzcygpKSAmJgorICAgICAgICAgICAiV3JvbmcgTWFjaGluZU9wZXJhbmQgbXV0YXRvciIpOworICAgIFNtYWxsQ29udGVudHMuT2Zmc2V0TG8gPSB1bnNpZ25lZChPZmZzZXQpOworICAgIENvbnRlbnRzLk9mZnNldGVkSW5mby5PZmZzZXRIaSA9IGludChPZmZzZXQgPj4gMzIpOworICB9CisKKyAgdm9pZCBzZXRJbmRleChpbnQgSWR4KSB7CisgICAgYXNzZXJ0KChpc0ZJKCkgfHwgaXNDUEkoKSB8fCBpc1RhcmdldEluZGV4KCkgfHwgaXNKVEkoKSkgJiYKKyAgICAgICAgICAgIldyb25nIE1hY2hpbmVPcGVyYW5kIG11dGF0b3IiKTsKKyAgICBDb250ZW50cy5PZmZzZXRlZEluZm8uVmFsLkluZGV4ID0gSWR4OworICB9CisKKyAgdm9pZCBzZXRNZXRhZGF0YShjb25zdCBNRE5vZGUgKk1EKSB7CisgICAgYXNzZXJ0KGlzTWV0YWRhdGEoKSAmJiAiV3JvbmcgTWFjaGluZU9wZXJhbmQgbXV0YXRvciIpOworICAgIENvbnRlbnRzLk1EID0gTUQ7CisgIH0KKworICB2b2lkIHNldE1CQihNYWNoaW5lQmFzaWNCbG9jayAqTUJCKSB7CisgICAgYXNzZXJ0KGlzTUJCKCkgJiYgIldyb25nIE1hY2hpbmVPcGVyYW5kIG11dGF0b3IiKTsKKyAgICBDb250ZW50cy5NQkIgPSBNQkI7CisgIH0KKworICAvLy8gU2V0cyB2YWx1ZSBvZiByZWdpc3RlciBtYXNrIG9wZXJhbmQgcmVmZXJlbmNpbmcgTWFzay4gIFRoZQorICAvLy8gb3BlcmFuZCBkb2VzIG5vdCB0YWtlIG93bmVyc2hpcCBvZiB0aGUgbWVtb3J5IHJlZmVyZW5jZWQgYnkgTWFzaywgaXQgbXVzdAorICAvLy8gcmVtYWluIHZhbGlkIGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlIG9wZXJhbmQuIFNlZSBDcmVhdGVSZWdNYXNrKCkuCisgIC8vLyBBbnkgcGh5c3JlZyB3aXRoIGEgMCBiaXQgaW4gdGhlIG1hc2sgaXMgY2xvYmJlcmVkIGJ5IHRoZSBpbnN0cnVjdGlvbi4KKyAgdm9pZCBzZXRSZWdNYXNrKGNvbnN0IHVpbnQzMl90ICpSZWdNYXNrUHRyKSB7CisgICAgYXNzZXJ0KGlzUmVnTWFzaygpICYmICJXcm9uZyBNYWNoaW5lT3BlcmFuZCBtdXRhdG9yIik7CisgICAgQ29udGVudHMuUmVnTWFzayA9IFJlZ01hc2tQdHI7CisgIH0KKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gT3RoZXIgbWV0aG9kcy4KKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIG9wZXJhbmQgaXMgaWRlbnRpY2FsIHRvIHRoZSBzcGVjaWZpZWQgb3BlcmFuZCBleGNlcHQKKyAgLy8vIGZvciBsaXZlbmVzcyByZWxhdGVkIGZsYWdzIChpc0tpbGwsIGlzVW5kZWYgYW5kIGlzRGVhZCkuIE5vdGUgdGhhdCB0aGlzCisgIC8vLyBzaG91bGQgc3RheSBpbiBzeW5jIHdpdGggdGhlIGhhc2hfdmFsdWUgb3ZlcmxvYWQgYmVsb3cuCisgIGJvb2wgaXNJZGVudGljYWxUbyhjb25zdCBNYWNoaW5lT3BlcmFuZCAmT3RoZXIpIGNvbnN0OworCisgIC8vLyBcYnJpZWYgTWFjaGluZU9wZXJhbmQgaGFzaF92YWx1ZSBvdmVybG9hZC4KKyAgLy8vCisgIC8vLyBOb3RlIHRoYXQgdGhpcyBpbmNsdWRlcyB0aGUgc2FtZSBpbmZvcm1hdGlvbiBpbiB0aGUgaGFzaCB0aGF0CisgIC8vLyBpc0lkZW50aWNhbFRvIHVzZXMgZm9yIGNvbXBhcmlzb24uIEl0IGlzIHRodXMgc3VpdGVkIGZvciB1c2UgaW4gaGFzaAorICAvLy8gdGFibGVzIHdoaWNoIHVzZSB0aGF0IGZ1bmN0aW9uIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucyBvbmx5LiBUaGlzIG11c3QKKyAgLy8vIHN0YXkgZXhhY3RseSBpbiBzeW5jIHdpdGggaXNJZGVudGljYWxUbyBhYm92ZS4KKyAgZnJpZW5kIGhhc2hfY29kZSBoYXNoX3ZhbHVlKGNvbnN0IE1hY2hpbmVPcGVyYW5kICZNTyk7CisKKyAgLy8vIENoYW5nZVRvSW1tZWRpYXRlIC0gUmVwbGFjZSB0aGlzIG9wZXJhbmQgd2l0aCBhIG5ldyBpbW1lZGlhdGUgb3BlcmFuZCBvZgorICAvLy8gdGhlIHNwZWNpZmllZCB2YWx1ZS4gIElmIGFuIG9wZXJhbmQgaXMga25vd24gdG8gYmUgYW4gaW1tZWRpYXRlIGFscmVhZHksCisgIC8vLyB0aGUgc2V0SW1tIG1ldGhvZCBzaG91bGQgYmUgdXNlZC4KKyAgdm9pZCBDaGFuZ2VUb0ltbWVkaWF0ZShpbnQ2NF90IEltbVZhbCk7CisKKyAgLy8vIENoYW5nZVRvRlBJbW1lZGlhdGUgLSBSZXBsYWNlIHRoaXMgb3BlcmFuZCB3aXRoIGEgbmV3IEZQIGltbWVkaWF0ZSBvcGVyYW5kCisgIC8vLyBvZiB0aGUgc3BlY2lmaWVkIHZhbHVlLiAgSWYgYW4gb3BlcmFuZCBpcyBrbm93biB0byBiZSBhbiBGUCBpbW1lZGlhdGUKKyAgLy8vIGFscmVhZHksIHRoZSBzZXRGUEltbSBtZXRob2Qgc2hvdWxkIGJlIHVzZWQuCisgIHZvaWQgQ2hhbmdlVG9GUEltbWVkaWF0ZShjb25zdCBDb25zdGFudEZQICpGUEltbSk7CisKKyAgLy8vIENoYW5nZVRvRVMgLSBSZXBsYWNlIHRoaXMgb3BlcmFuZCB3aXRoIGEgbmV3IGV4dGVybmFsIHN5bWJvbCBvcGVyYW5kLgorICB2b2lkIENoYW5nZVRvRVMoY29uc3QgY2hhciAqU3ltTmFtZSwgdW5zaWduZWQgY2hhciBUYXJnZXRGbGFncyA9IDApOworCisgIC8vLyBDaGFuZ2VUb01DU3ltYm9sIC0gUmVwbGFjZSB0aGlzIG9wZXJhbmQgd2l0aCBhIG5ldyBNQyBzeW1ib2wgb3BlcmFuZC4KKyAgdm9pZCBDaGFuZ2VUb01DU3ltYm9sKE1DU3ltYm9sICpTeW0pOworCisgIC8vLyBSZXBsYWNlIHRoaXMgb3BlcmFuZCB3aXRoIGEgZnJhbWUgaW5kZXguCisgIHZvaWQgQ2hhbmdlVG9GcmFtZUluZGV4KGludCBJZHgpOworCisgIC8vLyBSZXBsYWNlIHRoaXMgb3BlcmFuZCB3aXRoIGEgdGFyZ2V0IGluZGV4LgorICB2b2lkIENoYW5nZVRvVGFyZ2V0SW5kZXgodW5zaWduZWQgSWR4LCBpbnQ2NF90IE9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKTsKKworICAvLy8gQ2hhbmdlVG9SZWdpc3RlciAtIFJlcGxhY2UgdGhpcyBvcGVyYW5kIHdpdGggYSBuZXcgcmVnaXN0ZXIgb3BlcmFuZCBvZgorICAvLy8gdGhlIHNwZWNpZmllZCB2YWx1ZS4gIElmIGFuIG9wZXJhbmQgaXMga25vd24gdG8gYmUgYW4gcmVnaXN0ZXIgYWxyZWFkeSwKKyAgLy8vIHRoZSBzZXRSZWcgbWV0aG9kIHNob3VsZCBiZSB1c2VkLgorICB2b2lkIENoYW5nZVRvUmVnaXN0ZXIodW5zaWduZWQgUmVnLCBib29sIGlzRGVmLCBib29sIGlzSW1wID0gZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzS2lsbCA9IGZhbHNlLCBib29sIGlzRGVhZCA9IGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc1VuZGVmID0gZmFsc2UsIGJvb2wgaXNEZWJ1ZyA9IGZhbHNlKTsKKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gQ29uc3RydWN0aW9uIG1ldGhvZHMuCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisgIHN0YXRpYyBNYWNoaW5lT3BlcmFuZCBDcmVhdGVJbW0oaW50NjRfdCBWYWwpIHsKKyAgICBNYWNoaW5lT3BlcmFuZCBPcChNYWNoaW5lT3BlcmFuZDo6TU9fSW1tZWRpYXRlKTsKKyAgICBPcC5zZXRJbW0oVmFsKTsKKyAgICByZXR1cm4gT3A7CisgIH0KKworICBzdGF0aWMgTWFjaGluZU9wZXJhbmQgQ3JlYXRlQ0ltbShjb25zdCBDb25zdGFudEludCAqQ0kpIHsKKyAgICBNYWNoaW5lT3BlcmFuZCBPcChNYWNoaW5lT3BlcmFuZDo6TU9fQ0ltbWVkaWF0ZSk7CisgICAgT3AuQ29udGVudHMuQ0kgPSBDSTsKKyAgICByZXR1cm4gT3A7CisgIH0KKworICBzdGF0aWMgTWFjaGluZU9wZXJhbmQgQ3JlYXRlRlBJbW0oY29uc3QgQ29uc3RhbnRGUCAqQ0ZQKSB7CisgICAgTWFjaGluZU9wZXJhbmQgT3AoTWFjaGluZU9wZXJhbmQ6Ok1PX0ZQSW1tZWRpYXRlKTsKKyAgICBPcC5Db250ZW50cy5DRlAgPSBDRlA7CisgICAgcmV0dXJuIE9wOworICB9CisKKyAgc3RhdGljIE1hY2hpbmVPcGVyYW5kIENyZWF0ZVJlZyh1bnNpZ25lZCBSZWcsIGJvb2wgaXNEZWYsIGJvb2wgaXNJbXAgPSBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzS2lsbCA9IGZhbHNlLCBib29sIGlzRGVhZCA9IGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNVbmRlZiA9IGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNFYXJseUNsb2JiZXIgPSBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBTdWJSZWcgPSAwLCBib29sIGlzRGVidWcgPSBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzSW50ZXJuYWxSZWFkID0gZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc1JlbmFtYWJsZSA9IGZhbHNlKSB7CisgICAgYXNzZXJ0KCEoaXNEZWFkICYmICFpc0RlZikgJiYgIkRlYWQgZmxhZyBvbiBub24tZGVmIik7CisgICAgYXNzZXJ0KCEoaXNLaWxsICYmIGlzRGVmKSAmJiAiS2lsbCBmbGFnIG9uIGRlZiIpOworICAgIE1hY2hpbmVPcGVyYW5kIE9wKE1hY2hpbmVPcGVyYW5kOjpNT19SZWdpc3Rlcik7CisgICAgT3AuSXNEZWYgPSBpc0RlZjsKKyAgICBPcC5Jc0ltcCA9IGlzSW1wOworICAgIE9wLklzRGVhZE9yS2lsbCA9IGlzS2lsbCB8IGlzRGVhZDsKKyAgICBPcC5Jc1JlbmFtYWJsZSA9IGlzUmVuYW1hYmxlOworICAgIE9wLklzVW5kZWYgPSBpc1VuZGVmOworICAgIE9wLklzSW50ZXJuYWxSZWFkID0gaXNJbnRlcm5hbFJlYWQ7CisgICAgT3AuSXNFYXJseUNsb2JiZXIgPSBpc0Vhcmx5Q2xvYmJlcjsKKyAgICBPcC5UaWVkVG8gPSAwOworICAgIE9wLklzRGVidWcgPSBpc0RlYnVnOworICAgIE9wLlNtYWxsQ29udGVudHMuUmVnTm8gPSBSZWc7CisgICAgT3AuQ29udGVudHMuUmVnLlByZXYgPSBudWxscHRyOworICAgIE9wLkNvbnRlbnRzLlJlZy5OZXh0ID0gbnVsbHB0cjsKKyAgICBPcC5zZXRTdWJSZWcoU3ViUmVnKTsKKyAgICByZXR1cm4gT3A7CisgIH0KKyAgc3RhdGljIE1hY2hpbmVPcGVyYW5kIENyZWF0ZU1CQihNYWNoaW5lQmFzaWNCbG9jayAqTUJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKSB7CisgICAgTWFjaGluZU9wZXJhbmQgT3AoTWFjaGluZU9wZXJhbmQ6Ok1PX01hY2hpbmVCYXNpY0Jsb2NrKTsKKyAgICBPcC5zZXRNQkIoTUJCKTsKKyAgICBPcC5zZXRUYXJnZXRGbGFncyhUYXJnZXRGbGFncyk7CisgICAgcmV0dXJuIE9wOworICB9CisgIHN0YXRpYyBNYWNoaW5lT3BlcmFuZCBDcmVhdGVGSShpbnQgSWR4KSB7CisgICAgTWFjaGluZU9wZXJhbmQgT3AoTWFjaGluZU9wZXJhbmQ6Ok1PX0ZyYW1lSW5kZXgpOworICAgIE9wLnNldEluZGV4KElkeCk7CisgICAgcmV0dXJuIE9wOworICB9CisgIHN0YXRpYyBNYWNoaW5lT3BlcmFuZCBDcmVhdGVDUEkodW5zaWduZWQgSWR4LCBpbnQgT2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKSB7CisgICAgTWFjaGluZU9wZXJhbmQgT3AoTWFjaGluZU9wZXJhbmQ6Ok1PX0NvbnN0YW50UG9vbEluZGV4KTsKKyAgICBPcC5zZXRJbmRleChJZHgpOworICAgIE9wLnNldE9mZnNldChPZmZzZXQpOworICAgIE9wLnNldFRhcmdldEZsYWdzKFRhcmdldEZsYWdzKTsKKyAgICByZXR1cm4gT3A7CisgIH0KKyAgc3RhdGljIE1hY2hpbmVPcGVyYW5kIENyZWF0ZVRhcmdldEluZGV4KHVuc2lnbmVkIElkeCwgaW50NjRfdCBPZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFRhcmdldEZsYWdzID0gMCkgeworICAgIE1hY2hpbmVPcGVyYW5kIE9wKE1hY2hpbmVPcGVyYW5kOjpNT19UYXJnZXRJbmRleCk7CisgICAgT3Auc2V0SW5kZXgoSWR4KTsKKyAgICBPcC5zZXRPZmZzZXQoT2Zmc2V0KTsKKyAgICBPcC5zZXRUYXJnZXRGbGFncyhUYXJnZXRGbGFncyk7CisgICAgcmV0dXJuIE9wOworICB9CisgIHN0YXRpYyBNYWNoaW5lT3BlcmFuZCBDcmVhdGVKVEkodW5zaWduZWQgSWR4LCB1bnNpZ25lZCBjaGFyIFRhcmdldEZsYWdzID0gMCkgeworICAgIE1hY2hpbmVPcGVyYW5kIE9wKE1hY2hpbmVPcGVyYW5kOjpNT19KdW1wVGFibGVJbmRleCk7CisgICAgT3Auc2V0SW5kZXgoSWR4KTsKKyAgICBPcC5zZXRUYXJnZXRGbGFncyhUYXJnZXRGbGFncyk7CisgICAgcmV0dXJuIE9wOworICB9CisgIHN0YXRpYyBNYWNoaW5lT3BlcmFuZCBDcmVhdGVHQShjb25zdCBHbG9iYWxWYWx1ZSAqR1YsIGludDY0X3QgT2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciBUYXJnZXRGbGFncyA9IDApIHsKKyAgICBNYWNoaW5lT3BlcmFuZCBPcChNYWNoaW5lT3BlcmFuZDo6TU9fR2xvYmFsQWRkcmVzcyk7CisgICAgT3AuQ29udGVudHMuT2Zmc2V0ZWRJbmZvLlZhbC5HViA9IEdWOworICAgIE9wLnNldE9mZnNldChPZmZzZXQpOworICAgIE9wLnNldFRhcmdldEZsYWdzKFRhcmdldEZsYWdzKTsKKyAgICByZXR1cm4gT3A7CisgIH0KKyAgc3RhdGljIE1hY2hpbmVPcGVyYW5kIENyZWF0ZUVTKGNvbnN0IGNoYXIgKlN5bU5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFRhcmdldEZsYWdzID0gMCkgeworICAgIE1hY2hpbmVPcGVyYW5kIE9wKE1hY2hpbmVPcGVyYW5kOjpNT19FeHRlcm5hbFN5bWJvbCk7CisgICAgT3AuQ29udGVudHMuT2Zmc2V0ZWRJbmZvLlZhbC5TeW1ib2xOYW1lID0gU3ltTmFtZTsKKyAgICBPcC5zZXRPZmZzZXQoMCk7IC8vIE9mZnNldCBpcyBhbHdheXMgMC4KKyAgICBPcC5zZXRUYXJnZXRGbGFncyhUYXJnZXRGbGFncyk7CisgICAgcmV0dXJuIE9wOworICB9CisgIHN0YXRpYyBNYWNoaW5lT3BlcmFuZCBDcmVhdGVCQShjb25zdCBCbG9ja0FkZHJlc3MgKkJBLCBpbnQ2NF90IE9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKSB7CisgICAgTWFjaGluZU9wZXJhbmQgT3AoTWFjaGluZU9wZXJhbmQ6Ok1PX0Jsb2NrQWRkcmVzcyk7CisgICAgT3AuQ29udGVudHMuT2Zmc2V0ZWRJbmZvLlZhbC5CQSA9IEJBOworICAgIE9wLnNldE9mZnNldChPZmZzZXQpOworICAgIE9wLnNldFRhcmdldEZsYWdzKFRhcmdldEZsYWdzKTsKKyAgICByZXR1cm4gT3A7CisgIH0KKyAgLy8vIENyZWF0ZVJlZ01hc2sgLSBDcmVhdGVzIGEgcmVnaXN0ZXIgbWFzayBvcGVyYW5kIHJlZmVyZW5jaW5nIE1hc2suICBUaGUKKyAgLy8vIG9wZXJhbmQgZG9lcyBub3QgdGFrZSBvd25lcnNoaXAgb2YgdGhlIG1lbW9yeSByZWZlcmVuY2VkIGJ5IE1hc2ssIGl0CisgIC8vLyBtdXN0IHJlbWFpbiB2YWxpZCBmb3IgdGhlIGxpZmV0aW1lIG9mIHRoZSBvcGVyYW5kLgorICAvLy8KKyAgLy8vIEEgUmVnTWFzayBvcGVyYW5kIHJlcHJlc2VudHMgYSBzZXQgb2Ygbm9uLWNsb2JiZXJlZCBwaHlzaWNhbCByZWdpc3RlcnMKKyAgLy8vIG9uIGFuIGluc3RydWN0aW9uIHRoYXQgY2xvYmJlcnMgbWFueSByZWdpc3RlcnMsIHR5cGljYWxseSBhIGNhbGwuICBUaGUKKyAgLy8vIGJpdCBtYXNrIGhhcyBhIGJpdCBzZXQgZm9yIGVhY2ggcGh5c3JlZyB0aGF0IGlzIHByZXNlcnZlZCBieSB0aGlzCisgIC8vLyBpbnN0cnVjdGlvbiwgYXMgZGVzY3JpYmVkIGluIHRoZSBkb2N1bWVudGF0aW9uIGZvcgorICAvLy8gVGFyZ2V0UmVnaXN0ZXJJbmZvOjpnZXRDYWxsUHJlc2VydmVkTWFzaygpLgorICAvLy8KKyAgLy8vIEFueSBwaHlzcmVnIHdpdGggYSAwIGJpdCBpbiB0aGUgbWFzayBpcyBjbG9iYmVyZWQgYnkgdGhlIGluc3RydWN0aW9uLgorICAvLy8KKyAgc3RhdGljIE1hY2hpbmVPcGVyYW5kIENyZWF0ZVJlZ01hc2soY29uc3QgdWludDMyX3QgKk1hc2spIHsKKyAgICBhc3NlcnQoTWFzayAmJiAiTWlzc2luZyByZWdpc3RlciBtYXNrIik7CisgICAgTWFjaGluZU9wZXJhbmQgT3AoTWFjaGluZU9wZXJhbmQ6Ok1PX1JlZ2lzdGVyTWFzayk7CisgICAgT3AuQ29udGVudHMuUmVnTWFzayA9IE1hc2s7CisgICAgcmV0dXJuIE9wOworICB9CisgIHN0YXRpYyBNYWNoaW5lT3BlcmFuZCBDcmVhdGVSZWdMaXZlT3V0KGNvbnN0IHVpbnQzMl90ICpNYXNrKSB7CisgICAgYXNzZXJ0KE1hc2sgJiYgIk1pc3NpbmcgbGl2ZS1vdXQgcmVnaXN0ZXIgbWFzayIpOworICAgIE1hY2hpbmVPcGVyYW5kIE9wKE1hY2hpbmVPcGVyYW5kOjpNT19SZWdpc3RlckxpdmVPdXQpOworICAgIE9wLkNvbnRlbnRzLlJlZ01hc2sgPSBNYXNrOworICAgIHJldHVybiBPcDsKKyAgfQorICBzdGF0aWMgTWFjaGluZU9wZXJhbmQgQ3JlYXRlTWV0YWRhdGEoY29uc3QgTUROb2RlICpNZXRhKSB7CisgICAgTWFjaGluZU9wZXJhbmQgT3AoTWFjaGluZU9wZXJhbmQ6Ok1PX01ldGFkYXRhKTsKKyAgICBPcC5Db250ZW50cy5NRCA9IE1ldGE7CisgICAgcmV0dXJuIE9wOworICB9CisKKyAgc3RhdGljIE1hY2hpbmVPcGVyYW5kIENyZWF0ZU1DU3ltYm9sKE1DU3ltYm9sICpTeW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFRhcmdldEZsYWdzID0gMCkgeworICAgIE1hY2hpbmVPcGVyYW5kIE9wKE1hY2hpbmVPcGVyYW5kOjpNT19NQ1N5bWJvbCk7CisgICAgT3AuQ29udGVudHMuU3ltID0gU3ltOworICAgIE9wLnNldE9mZnNldCgwKTsKKyAgICBPcC5zZXRUYXJnZXRGbGFncyhUYXJnZXRGbGFncyk7CisgICAgcmV0dXJuIE9wOworICB9CisKKyAgc3RhdGljIE1hY2hpbmVPcGVyYW5kIENyZWF0ZUNGSUluZGV4KHVuc2lnbmVkIENGSUluZGV4KSB7CisgICAgTWFjaGluZU9wZXJhbmQgT3AoTWFjaGluZU9wZXJhbmQ6Ok1PX0NGSUluZGV4KTsKKyAgICBPcC5Db250ZW50cy5DRklJbmRleCA9IENGSUluZGV4OworICAgIHJldHVybiBPcDsKKyAgfQorCisgIHN0YXRpYyBNYWNoaW5lT3BlcmFuZCBDcmVhdGVJbnRyaW5zaWNJRChJbnRyaW5zaWM6OklEIElEKSB7CisgICAgTWFjaGluZU9wZXJhbmQgT3AoTWFjaGluZU9wZXJhbmQ6Ok1PX0ludHJpbnNpY0lEKTsKKyAgICBPcC5Db250ZW50cy5JbnRyaW5zaWNJRCA9IElEOworICAgIHJldHVybiBPcDsKKyAgfQorCisgIHN0YXRpYyBNYWNoaW5lT3BlcmFuZCBDcmVhdGVQcmVkaWNhdGUodW5zaWduZWQgUHJlZCkgeworICAgIE1hY2hpbmVPcGVyYW5kIE9wKE1hY2hpbmVPcGVyYW5kOjpNT19QcmVkaWNhdGUpOworICAgIE9wLkNvbnRlbnRzLlByZWQgPSBQcmVkOworICAgIHJldHVybiBPcDsKKyAgfQorCisgIGZyaWVuZCBjbGFzcyBNYWNoaW5lSW5zdHI7CisgIGZyaWVuZCBjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworCitwcml2YXRlOgorICAvLyBJZiB0aGlzIG9wZXJhbmQgaXMgY3VycmVudGx5IGEgcmVnaXN0ZXIgb3BlcmFuZCwgYW5kIGlmIHRoaXMgaXMgaW4gYQorICAvLyBmdW5jdGlvbiwgZGVyZWdpc3RlciB0aGUgb3BlcmFuZCBmcm9tIHRoZSByZWdpc3RlcidzIHVzZS9kZWYgbGlzdC4KKyAgdm9pZCByZW1vdmVSZWdGcm9tVXNlcygpOworCisgIC8vLyBBcnRpZmljaWFsIGtpbmRzIGZvciBEZW5zZU1hcCB1c2FnZS4KKyAgZW51bSA6IHVuc2lnbmVkIGNoYXIgeworICAgIE1PX0VtcHR5ID0gTU9fTGFzdCArIDEsCisgICAgTU9fVG9tYnN0b25lLAorICB9OworCisgIGZyaWVuZCBzdHJ1Y3QgRGVuc2VNYXBJbmZvPE1hY2hpbmVPcGVyYW5kPjsKKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gTWV0aG9kcyBmb3IgaGFuZGxpbmcgcmVnaXN0ZXIgdXNlL2RlZiBsaXN0cy4KKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyAgLy8vIGlzT25SZWdVc2VMaXN0IC0gUmV0dXJuIHRydWUgaWYgdGhpcyBvcGVyYW5kIGlzIG9uIGEgcmVnaXN0ZXIgdXNlL2RlZgorICAvLy8gbGlzdCBvciBmYWxzZSBpZiBub3QuICBUaGlzIGNhbiBvbmx5IGJlIGNhbGxlZCBmb3IgcmVnaXN0ZXIgb3BlcmFuZHMKKyAgLy8vIHRoYXQgYXJlIHBhcnQgb2YgYSBtYWNoaW5lIGluc3RydWN0aW9uLgorICBib29sIGlzT25SZWdVc2VMaXN0KCkgY29uc3QgeworICAgIGFzc2VydChpc1JlZygpICYmICJDYW4gb25seSBhZGQgcmVnIG9wZXJhbmQgdG8gdXNlIGxpc3RzIik7CisgICAgcmV0dXJuIENvbnRlbnRzLlJlZy5QcmV2ICE9IG51bGxwdHI7CisgIH0KK307CisKK3RlbXBsYXRlIDw+IHN0cnVjdCBEZW5zZU1hcEluZm88TWFjaGluZU9wZXJhbmQ+IHsKKyAgc3RhdGljIE1hY2hpbmVPcGVyYW5kIGdldEVtcHR5S2V5KCkgeworICAgIHJldHVybiBNYWNoaW5lT3BlcmFuZChzdGF0aWNfY2FzdDxNYWNoaW5lT3BlcmFuZDo6TWFjaGluZU9wZXJhbmRUeXBlPigKKyAgICAgICAgTWFjaGluZU9wZXJhbmQ6Ok1PX0VtcHR5KSk7CisgIH0KKyAgc3RhdGljIE1hY2hpbmVPcGVyYW5kIGdldFRvbWJzdG9uZUtleSgpIHsKKyAgICByZXR1cm4gTWFjaGluZU9wZXJhbmQoc3RhdGljX2Nhc3Q8TWFjaGluZU9wZXJhbmQ6Ok1hY2hpbmVPcGVyYW5kVHlwZT4oCisgICAgICAgIE1hY2hpbmVPcGVyYW5kOjpNT19Ub21ic3RvbmUpKTsKKyAgfQorICBzdGF0aWMgdW5zaWduZWQgZ2V0SGFzaFZhbHVlKGNvbnN0IE1hY2hpbmVPcGVyYW5kICZNTykgeworICAgIHJldHVybiBoYXNoX3ZhbHVlKE1PKTsKKyAgfQorICBzdGF0aWMgYm9vbCBpc0VxdWFsKGNvbnN0IE1hY2hpbmVPcGVyYW5kICZMSFMsIGNvbnN0IE1hY2hpbmVPcGVyYW5kICZSSFMpIHsKKyAgICBpZiAoTEhTLmdldFR5cGUoKSA9PSBzdGF0aWNfY2FzdDxNYWNoaW5lT3BlcmFuZDo6TWFjaGluZU9wZXJhbmRUeXBlPigKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZU9wZXJhbmQ6Ok1PX0VtcHR5KSB8fAorICAgICAgICBMSFMuZ2V0VHlwZSgpID09IHN0YXRpY19jYXN0PE1hY2hpbmVPcGVyYW5kOjpNYWNoaW5lT3BlcmFuZFR5cGU+KAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lT3BlcmFuZDo6TU9fVG9tYnN0b25lKSkKKyAgICAgIHJldHVybiBMSFMuZ2V0VHlwZSgpID09IFJIUy5nZXRUeXBlKCk7CisgICAgcmV0dXJuIExIUy5pc0lkZW50aWNhbFRvKFJIUyk7CisgIH0KK307CisKK2lubGluZSByYXdfb3N0cmVhbSAmb3BlcmF0b3I8PChyYXdfb3N0cmVhbSAmT1MsIGNvbnN0IE1hY2hpbmVPcGVyYW5kICZNTykgeworICBNTy5wcmludChPUyk7CisgIHJldHVybiBPUzsKK30KKworLy8gU2VlIGZyaWVuZCBkZWNsYXJhdGlvbiBhYm92ZS4gVGhpcyBhZGRpdGlvbmFsIGRlY2xhcmF0aW9uIGlzIHJlcXVpcmVkIGluCisvLyBvcmRlciB0byBjb21waWxlIExMVk0gd2l0aCBJQk0geGxDIGNvbXBpbGVyLgoraGFzaF9jb2RlIGhhc2hfdmFsdWUoY29uc3QgTWFjaGluZU9wZXJhbmQgJk1PKTsKK30gLy8gbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZU9wdGltaXphdGlvblJlbWFya0VtaXR0ZXIuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lT3B0aW1pemF0aW9uUmVtYXJrRW1pdHRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJmZGVmYmUKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZU9wdGltaXphdGlvblJlbWFya0VtaXR0ZXIuaApAQCAtMCwwICsxLDIyNCBAQAorLy8vPT09LSBNYWNoaW5lT3B0aW1pemF0aW9uUmVtYXJrRW1pdHRlci5oIC0gT3B0IERpYWdub3N0aWNzIC0qLSBDKysgLSotLS0tPT09Ly8KKy8vLworLy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vLworLy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vLworLy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLyBcZmlsZQorLy8vIE9wdGltaXphdGlvbiBkaWFnbm9zdGljIGludGVyZmFjZXMgZm9yIG1hY2hpbmUgcGFzc2VzLiAgSXQncyBwYWNrYWdlZCBhcyBhbgorLy8vIGFuYWx5c2lzIHBhc3Mgc28gdGhhdCBieSB1c2luZyB0aGlzIHNlcnZpY2UgcGFzc2VzIGJlY29tZSBkZXBlbmRlbnQgb24gTUJGSQorLy8vIGFzIHdlbGwuICBNQkZJIGlzIHVzZWQgdG8gY29tcHV0ZSB0aGUgImhvdG5lc3MiIG9mIHRoZSBkaWFnbm9zdGljIG1lc3NhZ2UuCisvLy8KKy8vLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ0hJTkVPUFRJTUlaQVRJT05SRU1BUktFTUlUVEVSX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX01BQ0hJTkVPUFRJTUlaQVRJT05SRU1BUktFTUlUVEVSX0gKKworI2luY2x1ZGUgImxsdm0vQW5hbHlzaXMvT3B0aW1pemF0aW9uUmVtYXJrRW1pdHRlci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lRnVuY3Rpb25QYXNzLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKK2NsYXNzIE1hY2hpbmVCYXNpY0Jsb2NrOworY2xhc3MgTWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mbzsKK2NsYXNzIE1hY2hpbmVJbnN0cjsKKworLy8vIFxicmllZiBDb21tb24gZmVhdHVyZXMgZm9yIGRpYWdub3N0aWNzIGRlYWxpbmcgd2l0aCBvcHRpbWl6YXRpb24gcmVtYXJrcworLy8vIHRoYXQgYXJlIHVzZWQgYnkgbWFjaGluZSBwYXNzZXMuCitjbGFzcyBEaWFnbm9zdGljSW5mb01JUk9wdGltaXphdGlvbiA6IHB1YmxpYyBEaWFnbm9zdGljSW5mb09wdGltaXphdGlvbkJhc2UgeworcHVibGljOgorICBEaWFnbm9zdGljSW5mb01JUk9wdGltaXphdGlvbihlbnVtIERpYWdub3N0aWNLaW5kIEtpbmQsIGNvbnN0IGNoYXIgKlBhc3NOYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdSZWYgUmVtYXJrTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGlhZ25vc3RpY0xvY2F0aW9uICZMb2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpCisgICAgICA6IERpYWdub3N0aWNJbmZvT3B0aW1pemF0aW9uQmFzZShLaW5kLCBEU19SZW1hcmssIFBhc3NOYW1lLCBSZW1hcmtOYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUJCLT5nZXRQYXJlbnQoKS0+Z2V0RnVuY3Rpb24oKSwgTG9jKSwKKyAgICAgICAgTUJCKE1CQikge30KKworICAvLy8gTUktc3BlY2lmaWMga2luZHMgb2YgZGlhZ25vc3RpYyBBcmd1bWVudHMuCisgIHN0cnVjdCBNYWNoaW5lQXJndW1lbnQgOiBwdWJsaWMgRGlhZ25vc3RpY0luZm9PcHRpbWl6YXRpb25CYXNlOjpBcmd1bWVudCB7CisgICAgLy8vIFByaW50IGFuIGVudGlyZSBNYWNoaW5lSW5zdHIuCisgICAgTWFjaGluZUFyZ3VtZW50KFN0cmluZ1JlZiBLZXksIGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpOworICB9OworCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgRGlhZ25vc3RpY0luZm8gKkRJKSB7CisgICAgcmV0dXJuIERJLT5nZXRLaW5kKCkgPj0gREtfRmlyc3RNYWNoaW5lUmVtYXJrICYmCisgICAgICAgICAgIERJLT5nZXRLaW5kKCkgPD0gREtfTGFzdE1hY2hpbmVSZW1hcms7CisgIH0KKworICBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqZ2V0QmxvY2soKSBjb25zdCB7IHJldHVybiBNQkI7IH0KKworcHJpdmF0ZToKKyAgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKk1CQjsKK307CisKKy8vLyBEaWFnbm9zdGljIGluZm9ybWF0aW9uIGZvciBhcHBsaWVkIG9wdGltaXphdGlvbiByZW1hcmtzLgorY2xhc3MgTWFjaGluZU9wdGltaXphdGlvblJlbWFyayA6IHB1YmxpYyBEaWFnbm9zdGljSW5mb01JUk9wdGltaXphdGlvbiB7CitwdWJsaWM6CisgIC8vLyBccCBQYXNzTmFtZSBpcyB0aGUgbmFtZSBvZiB0aGUgcGFzcyBlbWl0dGluZyB0aGlzIGRpYWdub3N0aWMuIElmIHRoaXMgbmFtZQorICAvLy8gbWF0Y2hlcyB0aGUgcmVndWxhciBleHByZXNzaW9uIGdpdmVuIGluIC1ScGFzcz0sIHRoZW4gdGhlIGRpYWdub3N0aWMgd2lsbAorICAvLy8gYmUgZW1pdHRlZC4gIFxwIFJlbWFya05hbWUgaXMgYSB0ZXh0dWFsIGlkZW50aWZpZXIgZm9yIHRoZSByZW1hcmsuICBccAorICAvLy8gTG9jIGlzIHRoZSBkZWJ1ZyBsb2NhdGlvbiBhbmQgXHAgTUJCIGlzIHRoZSBibG9jayB0aGF0IHRoZSBvcHRpbWl6YXRpb24KKyAgLy8vIG9wZXJhdGVzIGluLgorICBNYWNoaW5lT3B0aW1pemF0aW9uUmVtYXJrKGNvbnN0IGNoYXIgKlBhc3NOYW1lLCBTdHJpbmdSZWYgUmVtYXJrTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEaWFnbm9zdGljTG9jYXRpb24gJkxvYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqTUJCKQorICAgICAgOiBEaWFnbm9zdGljSW5mb01JUk9wdGltaXphdGlvbihES19NYWNoaW5lT3B0aW1pemF0aW9uUmVtYXJrLCBQYXNzTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVtYXJrTmFtZSwgTG9jLCBNQkIpIHt9CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBEaWFnbm9zdGljSW5mbyAqREkpIHsKKyAgICByZXR1cm4gREktPmdldEtpbmQoKSA9PSBES19NYWNoaW5lT3B0aW1pemF0aW9uUmVtYXJrOworICB9CisKKyAgLy8vIFxzZWUgRGlhZ25vc3RpY0luZm9PcHRpbWl6YXRpb25CYXNlOjppc0VuYWJsZWQuCisgIGJvb2wgaXNFbmFibGVkKCkgY29uc3Qgb3ZlcnJpZGUgeworICAgIGNvbnN0IEZ1bmN0aW9uICZGbiA9IGdldEZ1bmN0aW9uKCk7CisgICAgTExWTUNvbnRleHQgJkN0eCA9IEZuLmdldENvbnRleHQoKTsKKyAgICByZXR1cm4gQ3R4LmdldERpYWdIYW5kbGVyUHRyKCktPmlzUGFzc2VkT3B0UmVtYXJrRW5hYmxlZChnZXRQYXNzTmFtZSgpKTsKKyAgfQorfTsKKworLy8vIERpYWdub3N0aWMgaW5mb3JtYXRpb24gZm9yIG1pc3NlZC1vcHRpbWl6YXRpb24gcmVtYXJrcy4KK2NsYXNzIE1hY2hpbmVPcHRpbWl6YXRpb25SZW1hcmtNaXNzZWQgOiBwdWJsaWMgRGlhZ25vc3RpY0luZm9NSVJPcHRpbWl6YXRpb24geworcHVibGljOgorICAvLy8gXHAgUGFzc05hbWUgaXMgdGhlIG5hbWUgb2YgdGhlIHBhc3MgZW1pdHRpbmcgdGhpcyBkaWFnbm9zdGljLiBJZiB0aGlzIG5hbWUKKyAgLy8vIG1hdGNoZXMgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBnaXZlbiBpbiAtUnBhc3MtbWlzc2VkPSwgdGhlbiB0aGUKKyAgLy8vIGRpYWdub3N0aWMgd2lsbCBiZSBlbWl0dGVkLiAgXHAgUmVtYXJrTmFtZSBpcyBhIHRleHR1YWwgaWRlbnRpZmllciBmb3IgdGhlCisgIC8vLyByZW1hcmsuICBccCBMb2MgaXMgdGhlIGRlYnVnIGxvY2F0aW9uIGFuZCBccCBNQkIgaXMgdGhlIGJsb2NrIHRoYXQgdGhlCisgIC8vLyBvcHRpbWl6YXRpb24gb3BlcmF0ZXMgaW4uCisgIE1hY2hpbmVPcHRpbWl6YXRpb25SZW1hcmtNaXNzZWQoY29uc3QgY2hhciAqUGFzc05hbWUsIFN0cmluZ1JlZiBSZW1hcmtOYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERpYWdub3N0aWNMb2NhdGlvbiAmTG9jLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpCisgICAgICA6IERpYWdub3N0aWNJbmZvTUlST3B0aW1pemF0aW9uKERLX01hY2hpbmVPcHRpbWl6YXRpb25SZW1hcmtNaXNzZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhc3NOYW1lLCBSZW1hcmtOYW1lLCBMb2MsIE1CQikge30KKworICBzdGF0aWMgYm9vbCBjbGFzc29mKGNvbnN0IERpYWdub3N0aWNJbmZvICpESSkgeworICAgIHJldHVybiBESS0+Z2V0S2luZCgpID09IERLX01hY2hpbmVPcHRpbWl6YXRpb25SZW1hcmtNaXNzZWQ7CisgIH0KKworICAvLy8gXHNlZSBEaWFnbm9zdGljSW5mb09wdGltaXphdGlvbkJhc2U6OmlzRW5hYmxlZC4KKyAgYm9vbCBpc0VuYWJsZWQoKSBjb25zdCBvdmVycmlkZSB7CisgICAgY29uc3QgRnVuY3Rpb24gJkZuID0gZ2V0RnVuY3Rpb24oKTsKKyAgICBMTFZNQ29udGV4dCAmQ3R4ID0gRm4uZ2V0Q29udGV4dCgpOworICAgIHJldHVybiBDdHguZ2V0RGlhZ0hhbmRsZXJQdHIoKS0+aXNNaXNzZWRPcHRSZW1hcmtFbmFibGVkKGdldFBhc3NOYW1lKCkpOworICB9Cit9OworCisvLy8gRGlhZ25vc3RpYyBpbmZvcm1hdGlvbiBmb3Igb3B0aW1pemF0aW9uIGFuYWx5c2lzIHJlbWFya3MuCitjbGFzcyBNYWNoaW5lT3B0aW1pemF0aW9uUmVtYXJrQW5hbHlzaXMgOiBwdWJsaWMgRGlhZ25vc3RpY0luZm9NSVJPcHRpbWl6YXRpb24geworcHVibGljOgorICAvLy8gXHAgUGFzc05hbWUgaXMgdGhlIG5hbWUgb2YgdGhlIHBhc3MgZW1pdHRpbmcgdGhpcyBkaWFnbm9zdGljLiBJZiB0aGlzIG5hbWUKKyAgLy8vIG1hdGNoZXMgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBnaXZlbiBpbiAtUnBhc3MtYW5hbHlzaXM9LCB0aGVuIHRoZQorICAvLy8gZGlhZ25vc3RpYyB3aWxsIGJlIGVtaXR0ZWQuICBccCBSZW1hcmtOYW1lIGlzIGEgdGV4dHVhbCBpZGVudGlmaWVyIGZvciB0aGUKKyAgLy8vIHJlbWFyay4gIFxwIExvYyBpcyB0aGUgZGVidWcgbG9jYXRpb24gYW5kIFxwIE1CQiBpcyB0aGUgYmxvY2sgdGhhdCB0aGUKKyAgLy8vIG9wdGltaXphdGlvbiBvcGVyYXRlcyBpbi4KKyAgTWFjaGluZU9wdGltaXphdGlvblJlbWFya0FuYWx5c2lzKGNvbnN0IGNoYXIgKlBhc3NOYW1lLCBTdHJpbmdSZWYgUmVtYXJrTmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERpYWdub3N0aWNMb2NhdGlvbiAmTG9jLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKk1CQikKKyAgICAgIDogRGlhZ25vc3RpY0luZm9NSVJPcHRpbWl6YXRpb24oREtfTWFjaGluZU9wdGltaXphdGlvblJlbWFya0FuYWx5c2lzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXNzTmFtZSwgUmVtYXJrTmFtZSwgTG9jLCBNQkIpIHt9CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBEaWFnbm9zdGljSW5mbyAqREkpIHsKKyAgICByZXR1cm4gREktPmdldEtpbmQoKSA9PSBES19NYWNoaW5lT3B0aW1pemF0aW9uUmVtYXJrQW5hbHlzaXM7CisgIH0KKworICAvLy8gXHNlZSBEaWFnbm9zdGljSW5mb09wdGltaXphdGlvbkJhc2U6OmlzRW5hYmxlZC4KKyAgYm9vbCBpc0VuYWJsZWQoKSBjb25zdCBvdmVycmlkZSB7CisgICAgY29uc3QgRnVuY3Rpb24gJkZuID0gZ2V0RnVuY3Rpb24oKTsKKyAgICBMTFZNQ29udGV4dCAmQ3R4ID0gRm4uZ2V0Q29udGV4dCgpOworICAgIHJldHVybiBDdHguZ2V0RGlhZ0hhbmRsZXJQdHIoKS0+aXNBbmFseXNpc1JlbWFya0VuYWJsZWQoZ2V0UGFzc05hbWUoKSk7CisgIH0KK307CisKKy8vLyBFeHRlbmQgbGx2bTo6b3JlOjogd2l0aCBNSS1zcGVjaWZpYyBoZWxwZXIgbmFtZXMuCituYW1lc3BhY2Ugb3JlIHsKK3VzaW5nIE1OViA9IERpYWdub3N0aWNJbmZvTUlST3B0aW1pemF0aW9uOjpNYWNoaW5lQXJndW1lbnQ7Cit9CisKKy8vLyBUaGUgb3B0aW1pemF0aW9uIGRpYWdub3N0aWMgaW50ZXJmYWNlLgorLy8vCisvLy8gSXQgYWxsb3dzIHJlcG9ydGluZyB3aGVuIG9wdGltaXphdGlvbnMgYXJlIHBlcmZvcm1lZCBhbmQgd2hlbiB0aGV5IGFyZSBub3QKKy8vLyBhbG9uZyB3aXRoIHRoZSByZWFzb25zIGZvciBpdC4gIEhvdG5lc3MgaW5mb3JtYXRpb24gb2YgdGhlIGNvcnJlc3BvbmRpbmcKKy8vLyBjb2RlIHJlZ2lvbiBjYW4gYmUgaW5jbHVkZWQgaW4gdGhlIHJlbWFyayBpZiBEaWFnbm9zdGljc0hvdG5lc3NSZXF1ZXN0ZWQgaXMKKy8vLyBlbmFibGVkIGluIHRoZSBMTFZNIGNvbnRleHQuCitjbGFzcyBNYWNoaW5lT3B0aW1pemF0aW9uUmVtYXJrRW1pdHRlciB7CitwdWJsaWM6CisgIE1hY2hpbmVPcHRpbWl6YXRpb25SZW1hcmtFbWl0dGVyKE1hY2hpbmVGdW5jdGlvbiAmTUYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm8gKk1CRkkpCisgICAgICA6IE1GKE1GKSwgTUJGSShNQkZJKSB7fQorCisgIC8vLyBFbWl0IGFuIG9wdGltaXphdGlvbiByZW1hcmsuCisgIHZvaWQgZW1pdChEaWFnbm9zdGljSW5mb09wdGltaXphdGlvbkJhc2UgJk9wdERpYWcpOworCisgIC8vLyBcYnJpZWYgV2hldGhlciB3ZSBhbGxvdyBmb3IgZXh0cmEgY29tcGlsZS10aW1lIGJ1ZGdldCB0byBwZXJmb3JtIG1vcmUKKyAgLy8vIGFuYWx5c2lzIHRvIGJlIG1vcmUgaW5mb3JtYXRpdmUuCisgIC8vLworICAvLy8gVGhpcyBpcyB1c2VmdWwgdG8gZW5hYmxlIGFkZGl0aW9uYWwgbWlzc2VkIG9wdGltaXphdGlvbnMgdG8gYmUgcmVwb3J0ZWQKKyAgLy8vIHRoYXQgYXJlIG5vcm1hbGx5IHRvbyBub2lzeS4gIEluIHRoaXMgbW9kZSwgd2UgY2FuIHVzZSB0aGUgZXh0cmEgYW5hbHlzaXMKKyAgLy8vICgxKSB0byBmaWx0ZXIgdHJpdmlhbCBmYWxzZSBwb3NpdGl2ZXMgb3IgKDIpIHRvIHByb3ZpZGUgbW9yZSBjb250ZXh0IHNvCisgIC8vLyB0aGF0IG5vbi10cml2aWFsIGZhbHNlIHBvc2l0aXZlcyBjYW4gYmUgcXVpY2tseSBkZXRlY3RlZCBieSB0aGUgdXNlci4KKyAgYm9vbCBhbGxvd0V4dHJhQW5hbHlzaXMoU3RyaW5nUmVmIFBhc3NOYW1lKSBjb25zdCB7CisgICAgcmV0dXJuIChNRi5nZXRGdW5jdGlvbigpLmdldENvbnRleHQoKS5nZXREaWFnbm9zdGljc091dHB1dEZpbGUoKSB8fAorICAgICAgICAgICAgTUYuZ2V0RnVuY3Rpb24oKS5nZXRDb250ZXh0KCkKKyAgICAgICAgICAgIC5nZXREaWFnSGFuZGxlclB0cigpLT5pc0FueVJlbWFya0VuYWJsZWQoUGFzc05hbWUpKTsKKyAgfQorCisgIC8vLyBcYnJpZWYgVGFrZSBhIGxhbWJkYSB0aGF0IHJldHVybnMgYSByZW1hcmsgd2hpY2ggd2lsbCBiZSBlbWl0dGVkLiAgU2Vjb25kCisgIC8vLyBhcmd1bWVudCBpcyBvbmx5IHVzZWQgdG8gcmVzdHJpY3QgdGhpcyB0byBmdW5jdGlvbnMuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPgorICB2b2lkIGVtaXQoVCBSZW1hcmtCdWlsZGVyLCBkZWNsdHlwZShSZW1hcmtCdWlsZGVyKCkpICogPSBudWxscHRyKSB7CisgICAgLy8gQXZvaWQgYnVpbGRpbmcgdGhlIHJlbWFyayB1bmxlc3Mgd2Uga25vdyB0aGVyZSBhcmUgYXQgbGVhc3QgKnNvbWUqCisgICAgLy8gcmVtYXJrcyBlbmFibGVkLiBXZSBjYW4ndCBjdXJyZW50bHkgY2hlY2sgd2hldGhlciByZW1hcmtzIGFyZSByZXF1ZXN0ZWQKKyAgICAvLyBmb3IgdGhlIGNhbGxpbmcgcGFzcyBzaW5jZSB0aGF0IHJlcXVpcmVzIGFjdHVhbGx5IGJ1aWxkaW5nIHRoZSByZW1hcmsuCisKKyAgICBpZiAoTUYuZ2V0RnVuY3Rpb24oKS5nZXRDb250ZXh0KCkuZ2V0RGlhZ25vc3RpY3NPdXRwdXRGaWxlKCkgfHwKKyAgICAgICAgTUYuZ2V0RnVuY3Rpb24oKS5nZXRDb250ZXh0KCkuZ2V0RGlhZ0hhbmRsZXJQdHIoKS0+aXNBbnlSZW1hcmtFbmFibGVkKCkpIHsKKyAgICAgIGF1dG8gUiA9IFJlbWFya0J1aWxkZXIoKTsKKyAgICAgIGVtaXQoKERpYWdub3N0aWNJbmZvT3B0aW1pemF0aW9uQmFzZSAmKVIpOworICAgIH0KKyAgfQorCitwcml2YXRlOgorICBNYWNoaW5lRnVuY3Rpb24gJk1GOworCisgIC8vLyBNQkZJIGlzIG9ubHkgc2V0IGlmIGhvdG5lc3MgaXMgcmVxdWVzdGVkLgorICBNYWNoaW5lQmxvY2tGcmVxdWVuY3lJbmZvICpNQkZJOworCisgIC8vLyBDb21wdXRlIGhvdG5lc3MgZnJvbSBJUiB2YWx1ZSAoY3VycmVudGx5IGFzc3VtZWQgdG8gYmUgYSBibG9jaykgaWYgUEdPIGlzCisgIC8vLyBhdmFpbGFibGUuCisgIE9wdGlvbmFsPHVpbnQ2NF90PiBjb21wdXRlSG90bmVzcyhjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAmTUJCKTsKKworICAvLy8gU2ltaWxhciBidXQgdXNlIHZhbHVlIGZyb20gXHAgT3B0RGlhZyBhbmQgdXBkYXRlIGhvdG5lc3MgdGhlcmUuCisgIHZvaWQgY29tcHV0ZUhvdG5lc3MoRGlhZ25vc3RpY0luZm9NSVJPcHRpbWl6YXRpb24gJlJlbWFyayk7CisKKyAgLy8vIFxicmllZiBPbmx5IGFsbG93IHZlcmJvc2UgbWVzc2FnZXMgaWYgd2Uga25vdyB3ZSdyZSBmaWx0ZXJpbmcgYnkgaG90bmVzcworICAvLy8gKEJGSSBpcyBvbmx5IHNldCBpbiB0aGlzIGNhc2UpLgorICBib29sIHNob3VsZEVtaXRWZXJib3NlKCkgeyByZXR1cm4gTUJGSSAhPSBudWxscHRyOyB9Cit9OworCisvLy8gVGhlIGFuYWx5c2lzIHBhc3MKKy8vLworLy8vIE5vdGUgdGhhdCB0aGlzIHBhc3Mgc2hvdWxkbid0IGdlbmVyYWxseSBiZSBtYXJrZWQgYXMgcHJlc2VydmVkIGJ5IG90aGVyCisvLy8gcGFzc2VzLiAgSXQncyBob2xkaW5nIG9udG8gQkZJLCBzbyBpZiB0aGUgcGFzcyBkb2VzIG5vdCBwcmVzZXJ2ZSBCRkksIEJGSQorLy8vIGNvdWxkIGJlIGZyZWVkLgorY2xhc3MgTWFjaGluZU9wdGltaXphdGlvblJlbWFya0VtaXR0ZXJQYXNzIDogcHVibGljIE1hY2hpbmVGdW5jdGlvblBhc3MgeworICBzdGQ6OnVuaXF1ZV9wdHI8TWFjaGluZU9wdGltaXphdGlvblJlbWFya0VtaXR0ZXI+IE9SRTsKKworcHVibGljOgorICBNYWNoaW5lT3B0aW1pemF0aW9uUmVtYXJrRW1pdHRlclBhc3MoKTsKKworICBib29sIHJ1bk9uTWFjaGluZUZ1bmN0aW9uKE1hY2hpbmVGdW5jdGlvbiAmTUYpIG92ZXJyaWRlOworCisgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlICZBVSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgTWFjaGluZU9wdGltaXphdGlvblJlbWFya0VtaXR0ZXIgJmdldE9SRSgpIHsKKyAgICBhc3NlcnQoT1JFICYmICJwYXNzIG5vdCBydW4geWV0Iik7CisgICAgcmV0dXJuICpPUkU7CisgIH0KKworICBzdGF0aWMgY2hhciBJRDsKK307Cit9CisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVQYXNzUmVnaXN0cnkuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lUGFzc1JlZ2lzdHJ5LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2FiYTBiYgotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lUGFzc1JlZ2lzdHJ5LmgKQEAgLTAsMCArMSwxNDIgQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vTWFjaGluZVBhc3NSZWdpc3RyeS5oIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBtZWNoYW5pY3MgZm9yIG1hY2hpbmUgZnVuY3Rpb24gcGFzcyByZWdpc3RyaWVzLiAgQQorLy8gZnVuY3Rpb24gcGFzcyByZWdpc3RyeSAoTWFjaGluZVBhc3NSZWdpc3RyeSkgaXMgYXV0byBmaWxsZWQgYnkgdGhlIHN0YXRpYworLy8gY29uc3RydWN0b3JzIG9mIE1hY2hpbmVQYXNzUmVnaXN0cnlOb2RlLiAgRnVydGhlciB0aGVyZSBpcyBhIGNvbW1hbmQgbGluZQorLy8gcGFyc2VyIChSZWdpc3RlclBhc3NQYXJzZXIpIHdoaWNoIGxpc3RlbnMgdG8gZWFjaCByZWdpc3RyeSBmb3IgYWRkaXRpb25zCisvLyBhbmQgZGVsZXRpb25zLCBzbyB0aGF0IHRoZSBhcHByb3ByaWF0ZSBjb21tYW5kIG9wdGlvbiBpcyB1cGRhdGVkLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ0hJTkVQQVNTUkVHSVNUUllfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTUFDSElORVBBU1NSRUdJU1RSWV9ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9TdHJpbmdSZWYuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vUGFzc2VzLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0NvbW1hbmRMaW5lLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKwordXNpbmcgTWFjaGluZVBhc3NDdG9yID0gdm9pZCAqKCopKCk7CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8KKy8vLyBNYWNoaW5lUGFzc1JlZ2lzdHJ5TGlzdGVuZXIgLSBMaXN0ZW5lciB0byBhZGRzIGFuZCByZW1vdmFscyBvZiBub2RlcyBpbgorLy8vIHJlZ2lzdHJhdGlvbiBsaXN0LgorLy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworY2xhc3MgTWFjaGluZVBhc3NSZWdpc3RyeUxpc3RlbmVyIHsKKyAgdmlydHVhbCB2b2lkIGFuY2hvcigpOworCitwdWJsaWM6CisgIE1hY2hpbmVQYXNzUmVnaXN0cnlMaXN0ZW5lcigpID0gZGVmYXVsdDsKKyAgdmlydHVhbCB+TWFjaGluZVBhc3NSZWdpc3RyeUxpc3RlbmVyKCkgPSBkZWZhdWx0OworCisgIHZpcnR1YWwgdm9pZCBOb3RpZnlBZGQoU3RyaW5nUmVmIE4sIE1hY2hpbmVQYXNzQ3RvciBDLCBTdHJpbmdSZWYgRCkgPSAwOworICB2aXJ0dWFsIHZvaWQgTm90aWZ5UmVtb3ZlKFN0cmluZ1JlZiBOKSA9IDA7Cit9OworCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vCisvLy8gTWFjaGluZVBhc3NSZWdpc3RyeU5vZGUgLSBNYWNoaW5lIHBhc3Mgbm9kZSBzdG9yZWQgaW4gcmVnaXN0cmF0aW9uIGxpc3QuCisvLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCitjbGFzcyBNYWNoaW5lUGFzc1JlZ2lzdHJ5Tm9kZSB7Citwcml2YXRlOgorICBNYWNoaW5lUGFzc1JlZ2lzdHJ5Tm9kZSAqTmV4dCA9IG51bGxwdHI7IC8vIE5leHQgZnVuY3Rpb24gcGFzcyBpbiBsaXN0LgorICBTdHJpbmdSZWYgTmFtZTsgICAgICAgICAgICAgICAgICAgICAgIC8vIE5hbWUgb2YgZnVuY3Rpb24gcGFzcy4KKyAgU3RyaW5nUmVmIERlc2NyaXB0aW9uOyAgICAgICAgICAgICAgICAvLyBEZXNjcmlwdGlvbiBzdHJpbmcuCisgIE1hY2hpbmVQYXNzQ3RvciBDdG9yOyAgICAgICAgICAgICAgICAgLy8gRnVuY3Rpb24gcGFzcyBjcmVhdG9yLgorCitwdWJsaWM6CisgIE1hY2hpbmVQYXNzUmVnaXN0cnlOb2RlKGNvbnN0IGNoYXIgKk4sIGNvbnN0IGNoYXIgKkQsIE1hY2hpbmVQYXNzQ3RvciBDKQorICAgICAgOiBOYW1lKE4pLCBEZXNjcmlwdGlvbihEKSwgQ3RvcihDKSB7fQorCisgIC8vIEFjY2Vzc29ycworICBNYWNoaW5lUGFzc1JlZ2lzdHJ5Tm9kZSAqZ2V0TmV4dCgpICAgICAgY29uc3QgeyByZXR1cm4gTmV4dDsgfQorICBNYWNoaW5lUGFzc1JlZ2lzdHJ5Tm9kZSAqKmdldE5leHRBZGRyZXNzKCkgICAgeyByZXR1cm4gJk5leHQ7IH0KKyAgU3RyaW5nUmVmIGdldE5hbWUoKSAgICAgICAgICAgICAgICAgICBjb25zdCB7IHJldHVybiBOYW1lOyB9CisgIFN0cmluZ1JlZiBnZXREZXNjcmlwdGlvbigpICAgICAgICAgICAgY29uc3QgeyByZXR1cm4gRGVzY3JpcHRpb247IH0KKyAgTWFjaGluZVBhc3NDdG9yIGdldEN0b3IoKSAgICAgICAgICAgICAgIGNvbnN0IHsgcmV0dXJuIEN0b3I7IH0KKyAgdm9pZCBzZXROZXh0KE1hY2hpbmVQYXNzUmVnaXN0cnlOb2RlICpOKSAgICAgIHsgTmV4dCA9IE47IH0KK307CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLy8KKy8vLyBNYWNoaW5lUGFzc1JlZ2lzdHJ5IC0gVHJhY2sgdGhlIHJlZ2lzdHJhdGlvbiBvZiBtYWNoaW5lIHBhc3Nlcy4KKy8vLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KK2NsYXNzIE1hY2hpbmVQYXNzUmVnaXN0cnkgeworcHJpdmF0ZToKKyAgTWFjaGluZVBhc3NSZWdpc3RyeU5vZGUgKkxpc3Q7ICAgICAgICAvLyBMaXN0IG9mIHJlZ2lzdHJ5IG5vZGVzLgorICBNYWNoaW5lUGFzc0N0b3IgRGVmYXVsdDsgICAgICAgICAgICAgIC8vIERlZmF1bHQgZnVuY3Rpb24gcGFzcyBjcmVhdG9yLgorICBNYWNoaW5lUGFzc1JlZ2lzdHJ5TGlzdGVuZXIgKkxpc3RlbmVyOyAvLyBMaXN0ZW5lciBmb3IgbGlzdCBhZGRzIGFyZSByZW1vdmVzLgorCitwdWJsaWM6CisgIC8vIE5PIENPTlNUUlVDVE9SIC0gd2UgZG9uJ3Qgd2FudCBzdGF0aWMgY29uc3RydWN0b3Igb3JkZXJpbmcgdG8gbWVzcworICAvLyB3aXRoIHRoZSByZWdpc3RyeS4KKworICAvLyBBY2Nlc3NvcnMuCisgIC8vCisgIE1hY2hpbmVQYXNzUmVnaXN0cnlOb2RlICpnZXRMaXN0KCkgICAgICAgICAgICAgICAgICAgIHsgcmV0dXJuIExpc3Q7IH0KKyAgTWFjaGluZVBhc3NDdG9yIGdldERlZmF1bHQoKSAgICAgICAgICAgICAgICAgICAgICAgICAgeyByZXR1cm4gRGVmYXVsdDsgfQorICB2b2lkIHNldERlZmF1bHQoTWFjaGluZVBhc3NDdG9yIEMpICAgICAgICAgICAgICAgICAgICB7IERlZmF1bHQgPSBDOyB9CisgIHZvaWQgc2V0RGVmYXVsdChTdHJpbmdSZWYgTmFtZSk7CisgIHZvaWQgc2V0TGlzdGVuZXIoTWFjaGluZVBhc3NSZWdpc3RyeUxpc3RlbmVyICpMKSAgICAgIHsgTGlzdGVuZXIgPSBMOyB9CisKKyAgLy8vIEFkZCAtIEFkZHMgYSBmdW5jdGlvbiBwYXNzIHRvIHRoZSByZWdpc3RyYXRpb24gbGlzdC4KKyAgLy8vCisgIHZvaWQgQWRkKE1hY2hpbmVQYXNzUmVnaXN0cnlOb2RlICpOb2RlKTsKKworICAvLy8gUmVtb3ZlIC0gUmVtb3ZlcyBhIGZ1bmN0aW9uIHBhc3MgZnJvbSB0aGUgcmVnaXN0cmF0aW9uIGxpc3QuCisgIC8vLworICB2b2lkIFJlbW92ZShNYWNoaW5lUGFzc1JlZ2lzdHJ5Tm9kZSAqTm9kZSk7Cit9OworCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vCisvLy8gUmVnaXN0ZXJQYXNzUGFyc2VyIGNsYXNzIC0gSGFuZGxlIHRoZSBhZGRpdGlvbiBvZiBuZXcgbWFjaGluZSBwYXNzZXMuCisvLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCit0ZW1wbGF0ZTxjbGFzcyBSZWdpc3RyeUNsYXNzPgorY2xhc3MgUmVnaXN0ZXJQYXNzUGFyc2VyIDogcHVibGljIE1hY2hpbmVQYXNzUmVnaXN0cnlMaXN0ZW5lciwKKyAgICAgICAgICAgICAgICAgICBwdWJsaWMgY2w6OnBhcnNlcjx0eXBlbmFtZSBSZWdpc3RyeUNsYXNzOjpGdW5jdGlvblBhc3NDdG9yPiB7CitwdWJsaWM6CisgIFJlZ2lzdGVyUGFzc1BhcnNlcihjbDo6T3B0aW9uICZPKQorICAgICAgOiBjbDo6cGFyc2VyPHR5cGVuYW1lIFJlZ2lzdHJ5Q2xhc3M6OkZ1bmN0aW9uUGFzc0N0b3I+KE8pIHt9CisgIH5SZWdpc3RlclBhc3NQYXJzZXIoKSBvdmVycmlkZSB7IFJlZ2lzdHJ5Q2xhc3M6OnNldExpc3RlbmVyKG51bGxwdHIpOyB9CisKKyAgdm9pZCBpbml0aWFsaXplKCkgeworICAgIGNsOjpwYXJzZXI8dHlwZW5hbWUgUmVnaXN0cnlDbGFzczo6RnVuY3Rpb25QYXNzQ3Rvcj46OmluaXRpYWxpemUoKTsKKworICAgIC8vIEFkZCBleGlzdGluZyBwYXNzZXMgdG8gb3B0aW9uLgorICAgIGZvciAoUmVnaXN0cnlDbGFzcyAqTm9kZSA9IFJlZ2lzdHJ5Q2xhc3M6OmdldExpc3QoKTsKKyAgICAgICAgIE5vZGU7IE5vZGUgPSBOb2RlLT5nZXROZXh0KCkpIHsKKyAgICAgIHRoaXMtPmFkZExpdGVyYWxPcHRpb24oTm9kZS0+Z2V0TmFtZSgpLAorICAgICAgICAgICAgICAgICAgICAgICh0eXBlbmFtZSBSZWdpc3RyeUNsYXNzOjpGdW5jdGlvblBhc3NDdG9yKU5vZGUtPmdldEN0b3IoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZS0+Z2V0RGVzY3JpcHRpb24oKSk7CisgICAgfQorCisgICAgLy8gTWFrZSBzdXJlIHdlIGxpc3RlbiBmb3IgbGlzdCBjaGFuZ2VzLgorICAgIFJlZ2lzdHJ5Q2xhc3M6OnNldExpc3RlbmVyKHRoaXMpOworICB9CisKKyAgLy8gSW1wbGVtZW50IHRoZSBNYWNoaW5lUGFzc1JlZ2lzdHJ5TGlzdGVuZXIgY2FsbGJhY2tzLgorICB2b2lkIE5vdGlmeUFkZChTdHJpbmdSZWYgTiwgTWFjaGluZVBhc3NDdG9yIEMsIFN0cmluZ1JlZiBEKSBvdmVycmlkZSB7CisgICAgdGhpcy0+YWRkTGl0ZXJhbE9wdGlvbihOLCAodHlwZW5hbWUgUmVnaXN0cnlDbGFzczo6RnVuY3Rpb25QYXNzQ3RvcilDLCBEKTsKKyAgfQorICB2b2lkIE5vdGlmeVJlbW92ZShTdHJpbmdSZWYgTikgb3ZlcnJpZGUgeworICAgIHRoaXMtPnJlbW92ZUxpdGVyYWxPcHRpb24oTik7CisgIH0KK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTUFDSElORVBBU1NSRUdJU1RSWV9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZVBvc3REb21pbmF0b3JzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZVBvc3REb21pbmF0b3JzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzZhNDE1OQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lUG9zdERvbWluYXRvcnMuaApAQCAtMCwwICsxLDg2IEBACisvLz0tIGxsdm0vQ29kZUdlbi9NYWNoaW5lRG9taW5hdG9ycy5oIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBleHBvc2VzIGludGVyZmFjZXMgdG8gcG9zdCBkb21pbmFuY2UgaW5mb3JtYXRpb24gZm9yCisvLyB0YXJnZXQtc3BlY2lmaWMgY29kZS4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9NQUNISU5FUE9TVERPTUlOQVRPUlNfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTUFDSElORVBPU1RET01JTkFUT1JTX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lRG9taW5hdG9ycy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lRnVuY3Rpb25QYXNzLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKworLy8vCisvLy8gUG9zdERvbWluYXRvclRyZWUgQ2xhc3MgLSBDb25jcmV0ZSBzdWJjbGFzcyBvZiBEb21pbmF0b3JUcmVlIHRoYXQgaXMgdXNlZAorLy8vIHRvIGNvbXB1dGUgdGhlIHBvc3QtZG9taW5hdG9yIHRyZWUuCisvLy8KK3N0cnVjdCBNYWNoaW5lUG9zdERvbWluYXRvclRyZWUgOiBwdWJsaWMgTWFjaGluZUZ1bmN0aW9uUGFzcyB7Citwcml2YXRlOgorIFBvc3REb21UcmVlQmFzZTxNYWNoaW5lQmFzaWNCbG9jaz4gKkRUOworCitwdWJsaWM6CisgIHN0YXRpYyBjaGFyIElEOworCisgIE1hY2hpbmVQb3N0RG9taW5hdG9yVHJlZSgpOworCisgIH5NYWNoaW5lUG9zdERvbWluYXRvclRyZWUoKSBvdmVycmlkZTsKKworICBGdW5jdGlvblBhc3MgKmNyZWF0ZU1hY2hpbmVQb3N0RG9taW5hdG9yVHJlZVBhc3MoKTsKKworICBjb25zdCBTbWFsbFZlY3RvckltcGw8TWFjaGluZUJhc2ljQmxvY2sgKj4gJmdldFJvb3RzKCkgY29uc3QgeworICAgIHJldHVybiBEVC0+Z2V0Um9vdHMoKTsKKyAgfQorCisgIE1hY2hpbmVEb21UcmVlTm9kZSAqZ2V0Um9vdE5vZGUoKSBjb25zdCB7CisgICAgcmV0dXJuIERULT5nZXRSb290Tm9kZSgpOworICB9CisKKyAgTWFjaGluZURvbVRyZWVOb2RlICpvcGVyYXRvcltdKE1hY2hpbmVCYXNpY0Jsb2NrICpCQikgY29uc3QgeworICAgIHJldHVybiBEVC0+Z2V0Tm9kZShCQik7CisgIH0KKworICBNYWNoaW5lRG9tVHJlZU5vZGUgKmdldE5vZGUoTWFjaGluZUJhc2ljQmxvY2sgKkJCKSBjb25zdCB7CisgICAgcmV0dXJuIERULT5nZXROb2RlKEJCKTsKKyAgfQorCisgIGJvb2wgZG9taW5hdGVzKGNvbnN0IE1hY2hpbmVEb21UcmVlTm9kZSAqQSwKKyAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZURvbVRyZWVOb2RlICpCKSBjb25zdCB7CisgICAgcmV0dXJuIERULT5kb21pbmF0ZXMoQSwgQik7CisgIH0KKworICBib29sIGRvbWluYXRlcyhjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqQSwgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKkIpIGNvbnN0IHsKKyAgICByZXR1cm4gRFQtPmRvbWluYXRlcyhBLCBCKTsKKyAgfQorCisgIGJvb2wgcHJvcGVybHlEb21pbmF0ZXMoY29uc3QgTWFjaGluZURvbVRyZWVOb2RlICpBLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVEb21UcmVlTm9kZSAqQikgY29uc3QgeworICAgIHJldHVybiBEVC0+cHJvcGVybHlEb21pbmF0ZXMoQSwgQik7CisgIH0KKworICBib29sIHByb3Blcmx5RG9taW5hdGVzKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpBLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpCKSBjb25zdCB7CisgICAgcmV0dXJuIERULT5wcm9wZXJseURvbWluYXRlcyhBLCBCKTsKKyAgfQorCisgIE1hY2hpbmVCYXNpY0Jsb2NrICpmaW5kTmVhcmVzdENvbW1vbkRvbWluYXRvcihNYWNoaW5lQmFzaWNCbG9jayAqQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpCKSB7CisgICAgcmV0dXJuIERULT5maW5kTmVhcmVzdENvbW1vbkRvbWluYXRvcihBLCBCKTsKKyAgfQorCisgIGJvb2wgcnVuT25NYWNoaW5lRnVuY3Rpb24oTWFjaGluZUZ1bmN0aW9uICZNRikgb3ZlcnJpZGU7CisgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlICZBVSkgY29uc3Qgb3ZlcnJpZGU7CisgIHZvaWQgcHJpbnQobGx2bTo6cmF3X29zdHJlYW0gJk9TLCBjb25zdCBNb2R1bGUgKk0gPSBudWxscHRyKSBjb25zdCBvdmVycmlkZTsKK307Cit9IC8vZW5kIG9mIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVSZWdpb25JbmZvLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZVJlZ2lvbkluZm8uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44Mzk0YjU4Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVSZWdpb25JbmZvLmgKQEAgLTAsMCArMSwxODIgQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vTWFjaGluZVJlZ2lvbkluZm8uaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ0hJTkVSRUdJT05JTkZPX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX01BQ0hJTkVSRUdJT05JTkZPX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0RlcHRoRmlyc3RJdGVyYXRvci5oIgorI2luY2x1ZGUgImxsdm0vQW5hbHlzaXMvUmVnaW9uSW5mby5oIgorI2luY2x1ZGUgImxsdm0vQW5hbHlzaXMvUmVnaW9uSXRlcmF0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZURvbWluYW5jZUZyb250aWVyLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVEb21pbmF0b3JzLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvbi5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lRnVuY3Rpb25QYXNzLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVMb29wSW5mby5oIgorI2luY2x1ZGUgPGNhc3NlcnQ+CisKK25hbWVzcGFjZSBsbHZtIHsKKworc3RydWN0IE1hY2hpbmVQb3N0RG9taW5hdG9yVHJlZTsKK2NsYXNzIE1hY2hpbmVSZWdpb247CitjbGFzcyBNYWNoaW5lUmVnaW9uTm9kZTsKK2NsYXNzIE1hY2hpbmVSZWdpb25JbmZvOworCit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgUmVnaW9uVHJhaXRzPE1hY2hpbmVGdW5jdGlvbj4geworICB1c2luZyBGdW5jVCA9IE1hY2hpbmVGdW5jdGlvbjsKKyAgdXNpbmcgQmxvY2tUID0gTWFjaGluZUJhc2ljQmxvY2s7CisgIHVzaW5nIFJlZ2lvblQgPSBNYWNoaW5lUmVnaW9uOworICB1c2luZyBSZWdpb25Ob2RlVCA9IE1hY2hpbmVSZWdpb25Ob2RlOworICB1c2luZyBSZWdpb25JbmZvVCA9IE1hY2hpbmVSZWdpb25JbmZvOworICB1c2luZyBEb21UcmVlVCA9IE1hY2hpbmVEb21pbmF0b3JUcmVlOworICB1c2luZyBEb21UcmVlTm9kZVQgPSBNYWNoaW5lRG9tVHJlZU5vZGU7CisgIHVzaW5nIFBvc3REb21UcmVlVCA9IE1hY2hpbmVQb3N0RG9taW5hdG9yVHJlZTsKKyAgdXNpbmcgRG9tRnJvbnRpZXJUID0gTWFjaGluZURvbWluYW5jZUZyb250aWVyOworICB1c2luZyBJbnN0VCA9IE1hY2hpbmVJbnN0cjsKKyAgdXNpbmcgTG9vcFQgPSBNYWNoaW5lTG9vcDsKKyAgdXNpbmcgTG9vcEluZm9UID0gTWFjaGluZUxvb3BJbmZvOworCisgIHN0YXRpYyB1bnNpZ25lZCBnZXROdW1TdWNjZXNzb3JzKE1hY2hpbmVCYXNpY0Jsb2NrICpCQikgeworICAgIHJldHVybiBCQi0+c3VjY19zaXplKCk7CisgIH0KK307CisKK2NsYXNzIE1hY2hpbmVSZWdpb25Ob2RlIDogcHVibGljIFJlZ2lvbk5vZGVCYXNlPFJlZ2lvblRyYWl0czxNYWNoaW5lRnVuY3Rpb24+PiB7CitwdWJsaWM6CisgIGlubGluZSBNYWNoaW5lUmVnaW9uTm9kZShNYWNoaW5lUmVnaW9uICpQYXJlbnQsIE1hY2hpbmVCYXNpY0Jsb2NrICpFbnRyeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNTdWJSZWdpb24gPSBmYWxzZSkKKyAgICAgIDogUmVnaW9uTm9kZUJhc2U8UmVnaW9uVHJhaXRzPE1hY2hpbmVGdW5jdGlvbj4+KFBhcmVudCwgRW50cnksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1N1YlJlZ2lvbikge30KKworICBib29sIG9wZXJhdG9yPT0oY29uc3QgTWFjaGluZVJlZ2lvbiAmUk4pIGNvbnN0IHsKKyAgICByZXR1cm4gdGhpcyA9PSByZWludGVycHJldF9jYXN0PGNvbnN0IE1hY2hpbmVSZWdpb25Ob2RlICo+KCZSTik7CisgIH0KK307CisKK2NsYXNzIE1hY2hpbmVSZWdpb24gOiBwdWJsaWMgUmVnaW9uQmFzZTxSZWdpb25UcmFpdHM8TWFjaGluZUZ1bmN0aW9uPj4geworcHVibGljOgorICBNYWNoaW5lUmVnaW9uKE1hY2hpbmVCYXNpY0Jsb2NrICpFbnRyeSwgTWFjaGluZUJhc2ljQmxvY2sgKkV4aXQsCisgICAgICAgICAgICAgICAgTWFjaGluZVJlZ2lvbkluZm8gKlJJLCBNYWNoaW5lRG9taW5hdG9yVHJlZSAqRFQsCisgICAgICAgICAgICAgICAgTWFjaGluZVJlZ2lvbiAqUGFyZW50ID0gbnVsbHB0cik7CisgIH5NYWNoaW5lUmVnaW9uKCk7CisKKyAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IE1hY2hpbmVSZWdpb25Ob2RlICZSTikgY29uc3QgeworICAgIHJldHVybiAmUk4gPT0gcmVpbnRlcnByZXRfY2FzdDxjb25zdCBNYWNoaW5lUmVnaW9uTm9kZSAqPih0aGlzKTsKKyAgfQorfTsKKworY2xhc3MgTWFjaGluZVJlZ2lvbkluZm8gOiBwdWJsaWMgUmVnaW9uSW5mb0Jhc2U8UmVnaW9uVHJhaXRzPE1hY2hpbmVGdW5jdGlvbj4+IHsKK3B1YmxpYzoKKyAgZXhwbGljaXQgTWFjaGluZVJlZ2lvbkluZm8oKTsKKyAgfk1hY2hpbmVSZWdpb25JbmZvKCkgb3ZlcnJpZGU7CisKKyAgLy8gdXBkYXRlU3RhdGlzdGljcyAtIFVwZGF0ZSBzdGF0aXN0aWMgYWJvdXQgY3JlYXRlZCByZWdpb25zLgorICB2b2lkIHVwZGF0ZVN0YXRpc3RpY3MoTWFjaGluZVJlZ2lvbiAqUikgZmluYWw7CisKKyAgdm9pZCByZWNhbGN1bGF0ZShNYWNoaW5lRnVuY3Rpb24gJkYsIE1hY2hpbmVEb21pbmF0b3JUcmVlICpEVCwKKyAgICAgICAgICAgICAgICAgICBNYWNoaW5lUG9zdERvbWluYXRvclRyZWUgKlBEVCwgTWFjaGluZURvbWluYW5jZUZyb250aWVyICpERik7Cit9OworCitjbGFzcyBNYWNoaW5lUmVnaW9uSW5mb1Bhc3MgOiBwdWJsaWMgTWFjaGluZUZ1bmN0aW9uUGFzcyB7CisgIE1hY2hpbmVSZWdpb25JbmZvIFJJOworCitwdWJsaWM6CisgIHN0YXRpYyBjaGFyIElEOworCisgIGV4cGxpY2l0IE1hY2hpbmVSZWdpb25JbmZvUGFzcygpOworICB+TWFjaGluZVJlZ2lvbkluZm9QYXNzKCkgb3ZlcnJpZGU7CisKKyAgTWFjaGluZVJlZ2lvbkluZm8gJmdldFJlZ2lvbkluZm8oKSB7IHJldHVybiBSSTsgfQorCisgIGNvbnN0IE1hY2hpbmVSZWdpb25JbmZvICZnZXRSZWdpb25JbmZvKCkgY29uc3QgeyByZXR1cm4gUkk7IH0KKworICAvLy8gQG5hbWUgTWFjaGluZUZ1bmN0aW9uUGFzcyBpbnRlcmZhY2UKKyAgLy9AeworICBib29sIHJ1bk9uTWFjaGluZUZ1bmN0aW9uKE1hY2hpbmVGdW5jdGlvbiAmRikgb3ZlcnJpZGU7CisgIHZvaWQgcmVsZWFzZU1lbW9yeSgpIG92ZXJyaWRlOworICB2b2lkIHZlcmlmeUFuYWx5c2lzKCkgY29uc3Qgb3ZlcnJpZGU7CisgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlICZBVSkgY29uc3Qgb3ZlcnJpZGU7CisgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0gJk9TLCBjb25zdCBNb2R1bGUgKikgY29uc3Qgb3ZlcnJpZGU7CisgIHZvaWQgZHVtcCgpIGNvbnN0OworICAvL0B9Cit9OworCit0ZW1wbGF0ZSA8PgordGVtcGxhdGUgPD4KK2lubGluZSBNYWNoaW5lQmFzaWNCbG9jayAqCitSZWdpb25Ob2RlQmFzZTxSZWdpb25UcmFpdHM8TWFjaGluZUZ1bmN0aW9uPj46OmdldE5vZGVBczxNYWNoaW5lQmFzaWNCbG9jaz4oKQorICAgIGNvbnN0IHsKKyAgYXNzZXJ0KCFpc1N1YlJlZ2lvbigpICYmICJUaGlzIGlzIG5vdCBhIE1hY2hpbmVCYXNpY0Jsb2NrIFJlZ2lvbk5vZGUhIik7CisgIHJldHVybiBnZXRFbnRyeSgpOworfQorCit0ZW1wbGF0ZSA8PgordGVtcGxhdGUgPD4KK2lubGluZSBNYWNoaW5lUmVnaW9uICoKK1JlZ2lvbk5vZGVCYXNlPFJlZ2lvblRyYWl0czxNYWNoaW5lRnVuY3Rpb24+Pjo6Z2V0Tm9kZUFzPE1hY2hpbmVSZWdpb24+KCkKKyAgICBjb25zdCB7CisgIGFzc2VydChpc1N1YlJlZ2lvbigpICYmICJUaGlzIGlzIG5vdCBhIHN1YnJlZ2lvbiBSZWdpb25Ob2RlISIpOworICBhdXRvIFVuY29uc3QgPQorICAgICAgY29uc3RfY2FzdDxSZWdpb25Ob2RlQmFzZTxSZWdpb25UcmFpdHM8TWFjaGluZUZ1bmN0aW9uPj4gKj4odGhpcyk7CisgIHJldHVybiByZWludGVycHJldF9jYXN0PE1hY2hpbmVSZWdpb24gKj4oVW5jb25zdCk7Cit9CisKK1JlZ2lvbk5vZGVHcmFwaFRyYWl0cyhNYWNoaW5lUmVnaW9uTm9kZSwgTWFjaGluZUJhc2ljQmxvY2ssIE1hY2hpbmVSZWdpb24pOworUmVnaW9uTm9kZUdyYXBoVHJhaXRzKGNvbnN0IE1hY2hpbmVSZWdpb25Ob2RlLCBNYWNoaW5lQmFzaWNCbG9jaywKKyAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lUmVnaW9uKTsKKworUmVnaW9uR3JhcGhUcmFpdHMoTWFjaGluZVJlZ2lvbiwgTWFjaGluZVJlZ2lvbk5vZGUpOworUmVnaW9uR3JhcGhUcmFpdHMoY29uc3QgTWFjaGluZVJlZ2lvbiwgY29uc3QgTWFjaGluZVJlZ2lvbk5vZGUpOworCit0ZW1wbGF0ZSA8Pgorc3RydWN0IEdyYXBoVHJhaXRzPE1hY2hpbmVSZWdpb25JbmZvICo+CisgICAgOiBwdWJsaWMgR3JhcGhUcmFpdHM8RmxhdEl0PE1hY2hpbmVSZWdpb25Ob2RlICo+PiB7CisgIHVzaW5nIG5vZGVzX2l0ZXJhdG9yID0gZGZfaXRlcmF0b3I8Tm9kZVJlZiwgZGZfaXRlcmF0b3JfZGVmYXVsdF9zZXQ8Tm9kZVJlZj4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsIEdyYXBoVHJhaXRzPEZsYXRJdDxOb2RlUmVmPj4+OworCisgIHN0YXRpYyBOb2RlUmVmIGdldEVudHJ5Tm9kZShNYWNoaW5lUmVnaW9uSW5mbyAqUkkpIHsKKyAgICByZXR1cm4gR3JhcGhUcmFpdHM8RmxhdEl0PE1hY2hpbmVSZWdpb24gKj4+OjpnZXRFbnRyeU5vZGUoCisgICAgICAgIFJJLT5nZXRUb3BMZXZlbFJlZ2lvbigpKTsKKyAgfQorCisgIHN0YXRpYyBub2Rlc19pdGVyYXRvciBub2Rlc19iZWdpbihNYWNoaW5lUmVnaW9uSW5mbyAqUkkpIHsKKyAgICByZXR1cm4gbm9kZXNfaXRlcmF0b3I6OmJlZ2luKGdldEVudHJ5Tm9kZShSSSkpOworICB9CisKKyAgc3RhdGljIG5vZGVzX2l0ZXJhdG9yIG5vZGVzX2VuZChNYWNoaW5lUmVnaW9uSW5mbyAqUkkpIHsKKyAgICByZXR1cm4gbm9kZXNfaXRlcmF0b3I6OmVuZChnZXRFbnRyeU5vZGUoUkkpKTsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4KK3N0cnVjdCBHcmFwaFRyYWl0czxNYWNoaW5lUmVnaW9uSW5mb1Bhc3MgKj4KKyAgICA6IHB1YmxpYyBHcmFwaFRyYWl0czxNYWNoaW5lUmVnaW9uSW5mbyAqPiB7CisgIHVzaW5nIG5vZGVzX2l0ZXJhdG9yID0gZGZfaXRlcmF0b3I8Tm9kZVJlZiwgZGZfaXRlcmF0b3JfZGVmYXVsdF9zZXQ8Tm9kZVJlZj4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsIEdyYXBoVHJhaXRzPEZsYXRJdDxOb2RlUmVmPj4+OworCisgIHN0YXRpYyBOb2RlUmVmIGdldEVudHJ5Tm9kZShNYWNoaW5lUmVnaW9uSW5mb1Bhc3MgKlJJKSB7CisgICAgcmV0dXJuIEdyYXBoVHJhaXRzPE1hY2hpbmVSZWdpb25JbmZvICo+OjpnZXRFbnRyeU5vZGUoJlJJLT5nZXRSZWdpb25JbmZvKCkpOworICB9CisKKyAgc3RhdGljIG5vZGVzX2l0ZXJhdG9yIG5vZGVzX2JlZ2luKE1hY2hpbmVSZWdpb25JbmZvUGFzcyAqUkkpIHsKKyAgICByZXR1cm4gR3JhcGhUcmFpdHM8TWFjaGluZVJlZ2lvbkluZm8gKj46Om5vZGVzX2JlZ2luKCZSSS0+Z2V0UmVnaW9uSW5mbygpKTsKKyAgfQorCisgIHN0YXRpYyBub2Rlc19pdGVyYXRvciBub2Rlc19lbmQoTWFjaGluZVJlZ2lvbkluZm9QYXNzICpSSSkgeworICAgIHJldHVybiBHcmFwaFRyYWl0czxNYWNoaW5lUmVnaW9uSW5mbyAqPjo6bm9kZXNfZW5kKCZSSS0+Z2V0UmVnaW9uSW5mbygpKTsKKyAgfQorfTsKKworZXh0ZXJuIHRlbXBsYXRlIGNsYXNzIFJlZ2lvbkJhc2U8UmVnaW9uVHJhaXRzPE1hY2hpbmVGdW5jdGlvbj4+OworZXh0ZXJuIHRlbXBsYXRlIGNsYXNzIFJlZ2lvbk5vZGVCYXNlPFJlZ2lvblRyYWl0czxNYWNoaW5lRnVuY3Rpb24+PjsKK2V4dGVybiB0ZW1wbGF0ZSBjbGFzcyBSZWdpb25JbmZvQmFzZTxSZWdpb25UcmFpdHM8TWFjaGluZUZ1bmN0aW9uPj47CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTUFDSElORVJFR0lPTklORk9fSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVSZWdpc3RlckluZm8uaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lUmVnaXN0ZXJJbmZvLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjBkZmQwMgotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lUmVnaXN0ZXJJbmZvLmgKQEAgLTAsMCArMSwxMTk3IEBACisvLz09PS0gbGx2bS9Db2RlR2VuL01hY2hpbmVSZWdpc3RlckluZm8uaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZWZpbmVzIHRoZSBNYWNoaW5lUmVnaXN0ZXJJbmZvIGNsYXNzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ0hJTkVSRUdJU1RFUklORk9fSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTUFDSElORVJFR0lTVEVSSU5GT19ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9BcnJheVJlZi5oIgorI2luY2x1ZGUgImxsdm0vQURUL0JpdFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvSW5kZXhlZE1hcC5oIgorI2luY2x1ZGUgImxsdm0vQURUL1BvaW50ZXJVbmlvbi5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU3RyaW5nU2V0LmgiCisjaW5jbHVkZSAibGx2bS9BRFQvaXRlcmF0b3JfcmFuZ2UuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vR2xvYmFsSVNlbC9SZWdpc3RlckJhbmsuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTG93TGV2ZWxUeXBlLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVCYXNpY0Jsb2NrLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvbi5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lSW5zdHJCdW5kbGUuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZU9wZXJhbmQuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0UmVnaXN0ZXJJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1RhcmdldFN1YnRhcmdldEluZm8uaCIKKyNpbmNsdWRlICJsbHZtL01DL0xhbmVCaXRtYXNrLmgiCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkZGVmPgorI2luY2x1ZGUgPGNzdGRpbnQ+CisjaW5jbHVkZSA8aXRlcmF0b3I+CisjaW5jbHVkZSA8bWVtb3J5PgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8dmVjdG9yPgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIFBTZXRJdGVyYXRvcjsKKworLy8vIENvbnZlbmllbnQgdHlwZSB0byByZXByZXNlbnQgZWl0aGVyIGEgcmVnaXN0ZXIgY2xhc3Mgb3IgYSByZWdpc3RlciBiYW5rLgordXNpbmcgUmVnQ2xhc3NPclJlZ0JhbmsgPQorICAgIFBvaW50ZXJVbmlvbjxjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICosIGNvbnN0IFJlZ2lzdGVyQmFuayAqPjsKKworLy8vIE1hY2hpbmVSZWdpc3RlckluZm8gLSBLZWVwIHRyYWNrIG9mIGluZm9ybWF0aW9uIGZvciB2aXJ0dWFsIGFuZCBwaHlzaWNhbAorLy8vIHJlZ2lzdGVycywgaW5jbHVkaW5nIHZyZWcgcmVnaXN0ZXIgY2xhc3NlcywgdXNlL2RlZiBjaGFpbnMgZm9yIHJlZ2lzdGVycywKKy8vLyBldGMuCitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvIHsKK3B1YmxpYzoKKyAgY2xhc3MgRGVsZWdhdGUgeworICAgIHZpcnR1YWwgdm9pZCBhbmNob3IoKTsKKworICBwdWJsaWM6CisgICAgdmlydHVhbCB+RGVsZWdhdGUoKSA9IGRlZmF1bHQ7CisKKyAgICB2aXJ0dWFsIHZvaWQgTVJJX05vdGVOZXdWaXJ0dWFsUmVnaXN0ZXIodW5zaWduZWQgUmVnKSA9IDA7CisgIH07CisKK3ByaXZhdGU6CisgIE1hY2hpbmVGdW5jdGlvbiAqTUY7CisgIERlbGVnYXRlICpUaGVEZWxlZ2F0ZSA9IG51bGxwdHI7CisKKyAgLy8vIFRydWUgaWYgc3VicmVnaXN0ZXIgbGl2ZW5lc3MgaXMgdHJhY2tlZC4KKyAgY29uc3QgYm9vbCBUcmFja3NTdWJSZWdMaXZlbmVzczsKKworICAvLy8gVlJlZ0luZm8gLSBJbmZvcm1hdGlvbiB3ZSBrZWVwIGZvciBlYWNoIHZpcnR1YWwgcmVnaXN0ZXIuCisgIC8vLworICAvLy8gRWFjaCBlbGVtZW50IGluIHRoaXMgbGlzdCBjb250YWlucyB0aGUgcmVnaXN0ZXIgY2xhc3Mgb2YgdGhlIHZyZWcgYW5kIHRoZQorICAvLy8gc3RhcnQgb2YgdGhlIHVzZS9kZWYgbGlzdCBmb3IgdGhlIHJlZ2lzdGVyLgorICBJbmRleGVkTWFwPHN0ZDo6cGFpcjxSZWdDbGFzc09yUmVnQmFuaywgTWFjaGluZU9wZXJhbmQgKj4sCisgICAgICAgICAgICAgVmlydFJlZzJJbmRleEZ1bmN0b3I+CisgICAgICBWUmVnSW5mbzsKKworICAvLy8gTWFwIGZvciByZWNvdmVyaW5nIHZyZWcgbmFtZSBmcm9tIHZyZWcgbnVtYmVyLgorICAvLy8gVGhpcyBtYXAgaXMgdXNlZCBieSB0aGUgTUlSIFByaW50ZXIuCisgIEluZGV4ZWRNYXA8c3RkOjpzdHJpbmcsIFZpcnRSZWcySW5kZXhGdW5jdG9yPiBWUmVnMk5hbWU7CisKKyAgLy8vIFN0cmluZ1NldCB0aGF0IGlzIHVzZWQgdG8gdW5pcXVlIHZyZWcgbmFtZXMuCisgIFN0cmluZ1NldDw+IFZSZWdOYW1lczsKKworICAvLy8gVGhlIGZsYWcgaXMgdHJ1ZSB1cG9uIFxwIFVwZGF0ZWRDU1JzIGluaXRpYWxpemF0aW9uCisgIC8vLyBhbmQgZmFsc2Ugb3RoZXJ3aXNlLgorICBib29sIElzVXBkYXRlZENTUnNJbml0aWFsaXplZDsKKworICAvLy8gQ29udGFpbnMgdGhlIHVwZGF0ZWQgY2FsbGVlIHNhdmVkIHJlZ2lzdGVyIGxpc3QuCisgIC8vLyBBcyBvcHBvc2VkIHRvIHRoZSBzdGF0aWMgbGlzdCBkZWZpbmVkIGluIHJlZ2lzdGVyIGluZm8sCisgIC8vLyBhbGwgcmVnaXN0ZXJzIHRoYXQgd2VyZSBkaXNhYmxlZCBhcmUgcmVtb3ZlZCBmcm9tIHRoZSBsaXN0LgorICBTbWFsbFZlY3RvcjxNQ1BoeXNSZWcsIDE2PiBVcGRhdGVkQ1NSczsKKworICAvLy8gUmVnQWxsb2NIaW50cyAtIFRoaXMgdmVjdG9yIHJlY29yZHMgcmVnaXN0ZXIgYWxsb2NhdGlvbiBoaW50cyBmb3IKKyAgLy8vIHZpcnR1YWwgcmVnaXN0ZXJzLiBGb3IgZWFjaCB2aXJ0dWFsIHJlZ2lzdGVyLCBpdCBrZWVwcyBhIHBhaXIgb2YgaGludAorICAvLy8gdHlwZSBhbmQgaGludHMgdmVjdG9yIG1ha2luZyB1cCB0aGUgYWxsb2NhdGlvbiBoaW50cy4gT25seSB0aGUgZmlyc3QKKyAgLy8vIGhpbnQgbWF5IGJlIHRhcmdldCBzcGVjaWZpYywgYW5kIGluIHRoYXQgY2FzZSB0aGlzIGlzIHJlZmxlY3RlZCBieSB0aGUKKyAgLy8vIGZpcnN0IG1lbWJlciBvZiB0aGUgcGFpciBiZWluZyBub24temVyby4gSWYgdGhlIGhpbnRlZCByZWdpc3RlciBpcworICAvLy8gdmlydHVhbCwgaXQgbWVhbnMgdGhlIGFsbG9jYXRvciBzaG91bGQgcHJlZmVyIHRoZSBwaHlzaWNhbCByZWdpc3RlcgorICAvLy8gYWxsb2NhdGVkIHRvIGl0IGlmIGFueS4KKyAgSW5kZXhlZE1hcDxzdGQ6OnBhaXI8dW5zaWduZWQsIFNtYWxsVmVjdG9yPHVuc2lnbmVkLCA0Pj4sCisgICAgICAgICAgICAgVmlydFJlZzJJbmRleEZ1bmN0b3I+IFJlZ0FsbG9jSGludHM7CisKKyAgLy8vIFBoeXNSZWdVc2VEZWZMaXN0cyAtIFRoaXMgaXMgYW4gYXJyYXkgb2YgdGhlIGhlYWQgb2YgdGhlIHVzZS9kZWYgbGlzdCBmb3IKKyAgLy8vIHBoeXNpY2FsIHJlZ2lzdGVycy4KKyAgc3RkOjp1bmlxdWVfcHRyPE1hY2hpbmVPcGVyYW5kICpbXT4gUGh5c1JlZ1VzZURlZkxpc3RzOworCisgIC8vLyBnZXRSZWdVc2VEZWZMaXN0SGVhZCAtIFJldHVybiB0aGUgaGVhZCBwb2ludGVyIGZvciB0aGUgcmVnaXN0ZXIgdXNlL2RlZgorICAvLy8gbGlzdCBmb3IgdGhlIHNwZWNpZmllZCB2aXJ0dWFsIG9yIHBoeXNpY2FsIHJlZ2lzdGVyLgorICBNYWNoaW5lT3BlcmFuZCAqJmdldFJlZ1VzZURlZkxpc3RIZWFkKHVuc2lnbmVkIFJlZ05vKSB7CisgICAgaWYgKFRhcmdldFJlZ2lzdGVySW5mbzo6aXNWaXJ0dWFsUmVnaXN0ZXIoUmVnTm8pKQorICAgICAgcmV0dXJuIFZSZWdJbmZvW1JlZ05vXS5zZWNvbmQ7CisgICAgcmV0dXJuIFBoeXNSZWdVc2VEZWZMaXN0c1tSZWdOb107CisgIH0KKworICBNYWNoaW5lT3BlcmFuZCAqZ2V0UmVnVXNlRGVmTGlzdEhlYWQodW5zaWduZWQgUmVnTm8pIGNvbnN0IHsKKyAgICBpZiAoVGFyZ2V0UmVnaXN0ZXJJbmZvOjppc1ZpcnR1YWxSZWdpc3RlcihSZWdObykpCisgICAgICByZXR1cm4gVlJlZ0luZm9bUmVnTm9dLnNlY29uZDsKKyAgICByZXR1cm4gUGh5c1JlZ1VzZURlZkxpc3RzW1JlZ05vXTsKKyAgfQorCisgIC8vLyBHZXQgdGhlIG5leHQgZWxlbWVudCBpbiB0aGUgdXNlLWRlZiBjaGFpbi4KKyAgc3RhdGljIE1hY2hpbmVPcGVyYW5kICpnZXROZXh0T3BlcmFuZEZvclJlZyhjb25zdCBNYWNoaW5lT3BlcmFuZCAqTU8pIHsKKyAgICBhc3NlcnQoTU8gJiYgTU8tPmlzUmVnKCkgJiYgIlRoaXMgaXMgbm90IGEgcmVnaXN0ZXIgb3BlcmFuZCEiKTsKKyAgICByZXR1cm4gTU8tPkNvbnRlbnRzLlJlZy5OZXh0OworICB9CisKKyAgLy8vIFVzZWRQaHlzUmVnTWFzayAtIEFkZGl0aW9uYWwgdXNlZCBwaHlzcmVncyBpbmNsdWRpbmcgYWxpYXNlcy4KKyAgLy8vIFRoaXMgYml0IHZlY3RvciByZXByZXNlbnRzIGFsbCB0aGUgcmVnaXN0ZXJzIGNsb2JiZXJlZCBieSBmdW5jdGlvbiBjYWxscy4KKyAgQml0VmVjdG9yIFVzZWRQaHlzUmVnTWFzazsKKworICAvLy8gUmVzZXJ2ZWRSZWdzIC0gVGhpcyBpcyBhIGJpdCB2ZWN0b3Igb2YgcmVzZXJ2ZWQgcmVnaXN0ZXJzLiAgVGhlIHRhcmdldAorICAvLy8gbWF5IGNoYW5nZSBpdHMgbWluZCBhYm91dCB3aGljaCByZWdpc3RlcnMgc2hvdWxkIGJlIHJlc2VydmVkLiAgVGhpcworICAvLy8gdmVjdG9yIGlzIHRoZSBmcm96ZW4gc2V0IG9mIHJlc2VydmVkIHJlZ2lzdGVycyB3aGVuIHJlZ2lzdGVyIGFsbG9jYXRpb24KKyAgLy8vIHN0YXJ0ZWQuCisgIEJpdFZlY3RvciBSZXNlcnZlZFJlZ3M7CisKKyAgdXNpbmcgVlJlZ1RvVHlwZU1hcCA9IERlbnNlTWFwPHVuc2lnbmVkLCBMTFQ+OworICAvLy8gTWFwIGdlbmVyaWMgdmlydHVhbCByZWdpc3RlcnMgdG8gdGhlaXIgYWN0dWFsIHNpemUuCisgIG11dGFibGUgc3RkOjp1bmlxdWVfcHRyPFZSZWdUb1R5cGVNYXA+IFZSZWdUb1R5cGU7CisKKyAgLy8vIEtlZXAgdHJhY2sgb2YgdGhlIHBoeXNpY2FsIHJlZ2lzdGVycyB0aGF0IGFyZSBsaXZlIGluIHRvIHRoZSBmdW5jdGlvbi4KKyAgLy8vIExpdmUgaW4gdmFsdWVzIGFyZSB0eXBpY2FsbHkgYXJndW1lbnRzIGluIHJlZ2lzdGVycy4gIExpdmVJbiB2YWx1ZXMgYXJlCisgIC8vLyBhbGxvd2VkIHRvIGhhdmUgdmlydHVhbCByZWdpc3RlcnMgYXNzb2NpYXRlZCB3aXRoIHRoZW0sIHN0b3JlZCBpbiB0aGUKKyAgLy8vIHNlY29uZCBlbGVtZW50LgorICBzdGQ6OnZlY3RvcjxzdGQ6OnBhaXI8dW5zaWduZWQsIHVuc2lnbmVkPj4gTGl2ZUluczsKKworcHVibGljOgorICBleHBsaWNpdCBNYWNoaW5lUmVnaXN0ZXJJbmZvKE1hY2hpbmVGdW5jdGlvbiAqTUYpOworICBNYWNoaW5lUmVnaXN0ZXJJbmZvKGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gJikgPSBkZWxldGU7CisgIE1hY2hpbmVSZWdpc3RlckluZm8gJm9wZXJhdG9yPShjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICYpID0gZGVsZXRlOworCisgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqZ2V0VGFyZ2V0UmVnaXN0ZXJJbmZvKCkgY29uc3QgeworICAgIHJldHVybiBNRi0+Z2V0U3VidGFyZ2V0KCkuZ2V0UmVnaXN0ZXJJbmZvKCk7CisgIH0KKworICB2b2lkIHJlc2V0RGVsZWdhdGUoRGVsZWdhdGUgKmRlbGVnYXRlKSB7CisgICAgLy8gRW5zdXJlIGFub3RoZXIgZGVsZWdhdGUgZG9lcyBub3QgdGFrZSBvdmVyIHVubGVzcyB0aGUgY3VycmVudAorICAgIC8vIGRlbGVnYXRlIGZpcnN0IHVuYXR0YWNoZXMgaXRzZWxmLiBJZiB3ZSBldmVyIG5lZWQgdG8gbXVsdGljYXN0CisgICAgLy8gbm90aWZpY2F0aW9ucywgd2Ugd2lsbCBuZWVkIHRvIGNoYW5nZSB0byB1c2luZyBhIGxpc3QuCisgICAgYXNzZXJ0KFRoZURlbGVnYXRlID09IGRlbGVnYXRlICYmCisgICAgICAgICAgICJPbmx5IHRoZSBjdXJyZW50IGRlbGVnYXRlIGNhbiBwZXJmb3JtIHJlc2V0ISIpOworICAgIFRoZURlbGVnYXRlID0gbnVsbHB0cjsKKyAgfQorCisgIHZvaWQgc2V0RGVsZWdhdGUoRGVsZWdhdGUgKmRlbGVnYXRlKSB7CisgICAgYXNzZXJ0KGRlbGVnYXRlICYmICFUaGVEZWxlZ2F0ZSAmJgorICAgICAgICAgICAiQXR0ZW1wdGVkIHRvIHNldCBkZWxlZ2F0ZSB0byBudWxsLCBvciB0byBjaGFuZ2UgaXQgd2l0aG91dCAiCisgICAgICAgICAgICJmaXJzdCByZXNldHRpbmcgaXQhIik7CisKKyAgICBUaGVEZWxlZ2F0ZSA9IGRlbGVnYXRlOworICB9CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIEZ1bmN0aW9uIFN0YXRlCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisgIC8vIGlzU1NBIC0gUmV0dXJucyB0cnVlIHdoZW4gdGhlIG1hY2hpbmUgZnVuY3Rpb24gaXMgaW4gU1NBIGZvcm0uIEVhcmx5CisgIC8vIHBhc3NlcyByZXF1aXJlIHRoZSBtYWNoaW5lIGZ1bmN0aW9uIHRvIGJlIGluIFNTQSBmb3JtIHdoZXJlIGV2ZXJ5IHZpcnR1YWwKKyAgLy8gcmVnaXN0ZXIgaGFzIGEgc2luZ2xlIGRlZmluaW5nIGluc3RydWN0aW9uLgorICAvLworICAvLyBUaGUgVHdvQWRkcmVzc0luc3RydWN0aW9uUGFzcyBhbmQgUEhJRWxpbWluYXRpb24gcGFzc2VzIHRha2UgdGhlIG1hY2hpbmUKKyAgLy8gZnVuY3Rpb24gb3V0IG9mIFNTQSBmb3JtIHdoZW4gdGhleSBpbnRyb2R1Y2UgbXVsdGlwbGUgZGVmcyBwZXIgdmlydHVhbAorICAvLyByZWdpc3Rlci4KKyAgYm9vbCBpc1NTQSgpIGNvbnN0IHsKKyAgICByZXR1cm4gTUYtPmdldFByb3BlcnRpZXMoKS5oYXNQcm9wZXJ0eSgKKyAgICAgICAgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllczo6UHJvcGVydHk6OklzU1NBKTsKKyAgfQorCisgIC8vIGxlYXZlU1NBIC0gSW5kaWNhdGVzIHRoYXQgdGhlIG1hY2hpbmUgZnVuY3Rpb24gaXMgbm8gbG9uZ2VyIGluIFNTQSBmb3JtLgorICB2b2lkIGxlYXZlU1NBKCkgeworICAgIE1GLT5nZXRQcm9wZXJ0aWVzKCkucmVzZXQoTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllczo6UHJvcGVydHk6OklzU1NBKTsKKyAgfQorCisgIC8vLyB0cmFja3NMaXZlbmVzcyAtIFJldHVybnMgdHJ1ZSB3aGVuIHRyYWNraW5nIHJlZ2lzdGVyIGxpdmVuZXNzIGFjY3VyYXRlbHkuCisgIC8vLyAoc2VlIE1hY2hpbmVGVW5jdGlvblByb3BlcnRpZXM6OlByb3BlcnR5IGRlc2NyaXB0aW9uIGZvciBkZXRhaWxzKQorICBib29sIHRyYWNrc0xpdmVuZXNzKCkgY29uc3QgeworICAgIHJldHVybiBNRi0+Z2V0UHJvcGVydGllcygpLmhhc1Byb3BlcnR5KAorICAgICAgICBNYWNoaW5lRnVuY3Rpb25Qcm9wZXJ0aWVzOjpQcm9wZXJ0eTo6VHJhY2tzTGl2ZW5lc3MpOworICB9CisKKyAgLy8vIGludmFsaWRhdGVMaXZlbmVzcyAtIEluZGljYXRlcyB0aGF0IHJlZ2lzdGVyIGxpdmVuZXNzIGlzIG5vIGxvbmdlciBiZWluZworICAvLy8gdHJhY2tlZCBhY2N1cmF0ZWx5LgorICAvLy8KKyAgLy8vIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBieSBsYXRlIHBhc3NlcyB0aGF0IGludmFsaWRhdGUgdGhlIGxpdmVuZXNzCisgIC8vLyBpbmZvcm1hdGlvbi4KKyAgdm9pZCBpbnZhbGlkYXRlTGl2ZW5lc3MoKSB7CisgICAgTUYtPmdldFByb3BlcnRpZXMoKS5yZXNldCgKKyAgICAgICAgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllczo6UHJvcGVydHk6OlRyYWNrc0xpdmVuZXNzKTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgbGl2ZW5lc3MgZm9yIHJlZ2lzdGVyIGNsYXNzIEBwIFJDIHNob3VsZCBiZSB0cmFja2VkIGF0CisgIC8vLyB0aGUgc3VicmVnaXN0ZXIgbGV2ZWwuCisgIGJvb2wgc2hvdWxkVHJhY2tTdWJSZWdMaXZlbmVzcyhjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICZSQykgY29uc3QgeworICAgIHJldHVybiBzdWJSZWdMaXZlbmVzc0VuYWJsZWQoKSAmJiBSQy5IYXNEaXNqdW5jdFN1YlJlZ3M7CisgIH0KKyAgYm9vbCBzaG91bGRUcmFja1N1YlJlZ0xpdmVuZXNzKHVuc2lnbmVkIFZSZWcpIGNvbnN0IHsKKyAgICBhc3NlcnQoVGFyZ2V0UmVnaXN0ZXJJbmZvOjppc1ZpcnR1YWxSZWdpc3RlcihWUmVnKSAmJiAiTXVzdCBwYXNzIGEgVlJlZyIpOworICAgIHJldHVybiBzaG91bGRUcmFja1N1YlJlZ0xpdmVuZXNzKCpnZXRSZWdDbGFzcyhWUmVnKSk7CisgIH0KKyAgYm9vbCBzdWJSZWdMaXZlbmVzc0VuYWJsZWQoKSBjb25zdCB7CisgICAgcmV0dXJuIFRyYWNrc1N1YlJlZ0xpdmVuZXNzOworICB9CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIFJlZ2lzdGVyIEluZm8KKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgdXBkYXRlZCBDU1IgbGlzdCB3YXMgaW5pdGlhbGl6ZWQgYW5kIGZhbHNlIG90aGVyd2lzZS4KKyAgYm9vbCBpc1VwZGF0ZWRDU1JzSW5pdGlhbGl6ZWQoKSBjb25zdCB7IHJldHVybiBJc1VwZGF0ZWRDU1JzSW5pdGlhbGl6ZWQ7IH0KKworICAvLy8gRGlzYWJsZXMgdGhlIHJlZ2lzdGVyIGZyb20gdGhlIGxpc3Qgb2YgQ1NScy4KKyAgLy8vIEkuZS4gdGhlIHJlZ2lzdGVyIHdpbGwgbm90IGFwcGVhciBhcyBwYXJ0IG9mIHRoZSBDU1IgbWFzay4KKyAgLy8vIFxzZWUgVXBkYXRlZENhbGxlZVNhdmVkUmVncy4KKyAgdm9pZCBkaXNhYmxlQ2FsbGVlU2F2ZWRSZWdpc3Rlcih1bnNpZ25lZCBSZWcpOworCisgIC8vLyBSZXR1cm5zIGxpc3Qgb2YgY2FsbGVlIHNhdmVkIHJlZ2lzdGVycy4KKyAgLy8vIFRoZSBmdW5jdGlvbiByZXR1cm5zIHRoZSB1cGRhdGVkIENTUiBsaXN0IChhZnRlciB0YWtpbmcgaW50byBhY2NvdW50CisgIC8vLyByZWdpc3RlcnMgdGhhdCBhcmUgZGlzYWJsZWQgZnJvbSB0aGUgQ1NSIGxpc3QpLgorICBjb25zdCBNQ1BoeXNSZWcgKmdldENhbGxlZVNhdmVkUmVncygpIGNvbnN0OworCisgIC8vLyBTZXRzIHRoZSB1cGRhdGVkIENhbGxlZSBTYXZlZCBSZWdpc3RlcnMgbGlzdC4KKyAgLy8vIE5vdGljZSB0aGF0IGl0IHdpbGwgb3ZlcnJpZGUgYW50IHByZXZpb3VzbHkgZGlzYWJsZWQvc2F2ZWQgQ1NScy4KKyAgdm9pZCBzZXRDYWxsZWVTYXZlZFJlZ3MoQXJyYXlSZWY8TUNQaHlzUmVnPiBDU1JzKTsKKworICAvLyBTdHJpY3RseSBmb3IgdXNlIGJ5IE1hY2hpbmVJbnN0ci5jcHAuCisgIHZvaWQgYWRkUmVnT3BlcmFuZFRvVXNlTGlzdChNYWNoaW5lT3BlcmFuZCAqTU8pOworCisgIC8vIFN0cmljdGx5IGZvciB1c2UgYnkgTWFjaGluZUluc3RyLmNwcC4KKyAgdm9pZCByZW1vdmVSZWdPcGVyYW5kRnJvbVVzZUxpc3QoTWFjaGluZU9wZXJhbmQgKk1PKTsKKworICAvLyBTdHJpY3RseSBmb3IgdXNlIGJ5IE1hY2hpbmVJbnN0ci5jcHAuCisgIHZvaWQgbW92ZU9wZXJhbmRzKE1hY2hpbmVPcGVyYW5kICpEc3QsIE1hY2hpbmVPcGVyYW5kICpTcmMsIHVuc2lnbmVkIE51bU9wcyk7CisKKyAgLy8vIFZlcmlmeSB0aGUgc2FuaXR5IG9mIHRoZSB1c2UgbGlzdCBmb3IgUmVnLgorICB2b2lkIHZlcmlmeVVzZUxpc3QodW5zaWduZWQgUmVnKSBjb25zdDsKKworICAvLy8gVmVyaWZ5IHRoZSB1c2UgbGlzdCBvZiBhbGwgcmVnaXN0ZXJzLgorICB2b2lkIHZlcmlmeVVzZUxpc3RzKCkgY29uc3Q7CisKKyAgLy8vIHJlZ19iZWdpbi9yZWdfZW5kIC0gUHJvdmlkZSBpdGVyYXRpb24gc3VwcG9ydCB0byB3YWxrIG92ZXIgYWxsIGRlZmluaXRpb25zCisgIC8vLyBhbmQgdXNlcyBvZiBhIHJlZ2lzdGVyIHdpdGhpbiB0aGUgTWFjaGluZUZ1bmN0aW9uIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhpcworICAvLy8gTWFjaGluZVJlZ2lzdGVySW5mbyBvYmplY3QuCisgIHRlbXBsYXRlPGJvb2wgVXNlcywgYm9vbCBEZWZzLCBib29sIFNraXBEZWJ1ZywKKyAgICAgICAgICAgYm9vbCBCeU9wZXJhbmQsIGJvb2wgQnlJbnN0ciwgYm9vbCBCeUJ1bmRsZT4KKyAgY2xhc3MgZGVmdXNlY2hhaW5faXRlcmF0b3I7CisgIHRlbXBsYXRlPGJvb2wgVXNlcywgYm9vbCBEZWZzLCBib29sIFNraXBEZWJ1ZywKKyAgICAgICAgICAgYm9vbCBCeU9wZXJhbmQsIGJvb2wgQnlJbnN0ciwgYm9vbCBCeUJ1bmRsZT4KKyAgY2xhc3MgZGVmdXNlY2hhaW5faW5zdHJfaXRlcmF0b3I7CisKKyAgLy8gTWFrZSBpdCBhIGZyaWVuZCBzbyBpdCBjYW4gYWNjZXNzIGdldE5leHRPcGVyYW5kRm9yUmVnKCkuCisgIHRlbXBsYXRlPGJvb2wsIGJvb2wsIGJvb2wsIGJvb2wsIGJvb2wsIGJvb2w+CisgICAgZnJpZW5kIGNsYXNzIGRlZnVzZWNoYWluX2l0ZXJhdG9yOworICB0ZW1wbGF0ZTxib29sLCBib29sLCBib29sLCBib29sLCBib29sLCBib29sPgorICAgIGZyaWVuZCBjbGFzcyBkZWZ1c2VjaGFpbl9pbnN0cl9pdGVyYXRvcjsKKworICAvLy8gcmVnX2l0ZXJhdG9yL3JlZ19iZWdpbi9yZWdfZW5kIC0gV2FsayBhbGwgZGVmcyBhbmQgdXNlcyBvZiB0aGUgc3BlY2lmaWVkCisgIC8vLyByZWdpc3Rlci4KKyAgdXNpbmcgcmVnX2l0ZXJhdG9yID0KKyAgICAgIGRlZnVzZWNoYWluX2l0ZXJhdG9yPHRydWUsIHRydWUsIGZhbHNlLCB0cnVlLCBmYWxzZSwgZmFsc2U+OworICByZWdfaXRlcmF0b3IgcmVnX2JlZ2luKHVuc2lnbmVkIFJlZ05vKSBjb25zdCB7CisgICAgcmV0dXJuIHJlZ19pdGVyYXRvcihnZXRSZWdVc2VEZWZMaXN0SGVhZChSZWdObykpOworICB9CisgIHN0YXRpYyByZWdfaXRlcmF0b3IgcmVnX2VuZCgpIHsgcmV0dXJuIHJlZ19pdGVyYXRvcihudWxscHRyKTsgfQorCisgIGlubGluZSBpdGVyYXRvcl9yYW5nZTxyZWdfaXRlcmF0b3I+ICByZWdfb3BlcmFuZHModW5zaWduZWQgUmVnKSBjb25zdCB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2UocmVnX2JlZ2luKFJlZyksIHJlZ19lbmQoKSk7CisgIH0KKworICAvLy8gcmVnX2luc3RyX2l0ZXJhdG9yL3JlZ19pbnN0cl9iZWdpbi9yZWdfaW5zdHJfZW5kIC0gV2FsayBhbGwgZGVmcyBhbmQgdXNlcworICAvLy8gb2YgdGhlIHNwZWNpZmllZCByZWdpc3Rlciwgc3RlcHBpbmcgYnkgTWFjaGluZUluc3RyLgorICB1c2luZyByZWdfaW5zdHJfaXRlcmF0b3IgPQorICAgICAgZGVmdXNlY2hhaW5faW5zdHJfaXRlcmF0b3I8dHJ1ZSwgdHJ1ZSwgZmFsc2UsIGZhbHNlLCB0cnVlLCBmYWxzZT47CisgIHJlZ19pbnN0cl9pdGVyYXRvciByZWdfaW5zdHJfYmVnaW4odW5zaWduZWQgUmVnTm8pIGNvbnN0IHsKKyAgICByZXR1cm4gcmVnX2luc3RyX2l0ZXJhdG9yKGdldFJlZ1VzZURlZkxpc3RIZWFkKFJlZ05vKSk7CisgIH0KKyAgc3RhdGljIHJlZ19pbnN0cl9pdGVyYXRvciByZWdfaW5zdHJfZW5kKCkgeworICAgIHJldHVybiByZWdfaW5zdHJfaXRlcmF0b3IobnVsbHB0cik7CisgIH0KKworICBpbmxpbmUgaXRlcmF0b3JfcmFuZ2U8cmVnX2luc3RyX2l0ZXJhdG9yPgorICByZWdfaW5zdHJ1Y3Rpb25zKHVuc2lnbmVkIFJlZykgY29uc3QgeworICAgIHJldHVybiBtYWtlX3JhbmdlKHJlZ19pbnN0cl9iZWdpbihSZWcpLCByZWdfaW5zdHJfZW5kKCkpOworICB9CisKKyAgLy8vIHJlZ19idW5kbGVfaXRlcmF0b3IvcmVnX2J1bmRsZV9iZWdpbi9yZWdfYnVuZGxlX2VuZCAtIFdhbGsgYWxsIGRlZnMgYW5kIHVzZXMKKyAgLy8vIG9mIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIsIHN0ZXBwaW5nIGJ5IGJ1bmRsZS4KKyAgdXNpbmcgcmVnX2J1bmRsZV9pdGVyYXRvciA9CisgICAgICBkZWZ1c2VjaGFpbl9pbnN0cl9pdGVyYXRvcjx0cnVlLCB0cnVlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCB0cnVlPjsKKyAgcmVnX2J1bmRsZV9pdGVyYXRvciByZWdfYnVuZGxlX2JlZ2luKHVuc2lnbmVkIFJlZ05vKSBjb25zdCB7CisgICAgcmV0dXJuIHJlZ19idW5kbGVfaXRlcmF0b3IoZ2V0UmVnVXNlRGVmTGlzdEhlYWQoUmVnTm8pKTsKKyAgfQorICBzdGF0aWMgcmVnX2J1bmRsZV9pdGVyYXRvciByZWdfYnVuZGxlX2VuZCgpIHsKKyAgICByZXR1cm4gcmVnX2J1bmRsZV9pdGVyYXRvcihudWxscHRyKTsKKyAgfQorCisgIGlubGluZSBpdGVyYXRvcl9yYW5nZTxyZWdfYnVuZGxlX2l0ZXJhdG9yPiByZWdfYnVuZGxlcyh1bnNpZ25lZCBSZWcpIGNvbnN0IHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZShyZWdfYnVuZGxlX2JlZ2luKFJlZyksIHJlZ19idW5kbGVfZW5kKCkpOworICB9CisKKyAgLy8vIHJlZ19lbXB0eSAtIFJldHVybiB0cnVlIGlmIHRoZXJlIGFyZSBubyBpbnN0cnVjdGlvbnMgdXNpbmcgb3IgZGVmaW5pbmcgdGhlCisgIC8vLyBzcGVjaWZpZWQgcmVnaXN0ZXIgKGl0IG1heSBiZSBsaXZlLWluKS4KKyAgYm9vbCByZWdfZW1wdHkodW5zaWduZWQgUmVnTm8pIGNvbnN0IHsgcmV0dXJuIHJlZ19iZWdpbihSZWdObykgPT0gcmVnX2VuZCgpOyB9CisKKyAgLy8vIHJlZ19ub2RiZ19pdGVyYXRvci9yZWdfbm9kYmdfYmVnaW4vcmVnX25vZGJnX2VuZCAtIFdhbGsgYWxsIGRlZnMgYW5kIHVzZXMKKyAgLy8vIG9mIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIsIHNraXBwaW5nIHRob3NlIG1hcmtlZCBhcyBEZWJ1Zy4KKyAgdXNpbmcgcmVnX25vZGJnX2l0ZXJhdG9yID0KKyAgICAgIGRlZnVzZWNoYWluX2l0ZXJhdG9yPHRydWUsIHRydWUsIHRydWUsIHRydWUsIGZhbHNlLCBmYWxzZT47CisgIHJlZ19ub2RiZ19pdGVyYXRvciByZWdfbm9kYmdfYmVnaW4odW5zaWduZWQgUmVnTm8pIGNvbnN0IHsKKyAgICByZXR1cm4gcmVnX25vZGJnX2l0ZXJhdG9yKGdldFJlZ1VzZURlZkxpc3RIZWFkKFJlZ05vKSk7CisgIH0KKyAgc3RhdGljIHJlZ19ub2RiZ19pdGVyYXRvciByZWdfbm9kYmdfZW5kKCkgeworICAgIHJldHVybiByZWdfbm9kYmdfaXRlcmF0b3IobnVsbHB0cik7CisgIH0KKworICBpbmxpbmUgaXRlcmF0b3JfcmFuZ2U8cmVnX25vZGJnX2l0ZXJhdG9yPgorICByZWdfbm9kYmdfb3BlcmFuZHModW5zaWduZWQgUmVnKSBjb25zdCB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2UocmVnX25vZGJnX2JlZ2luKFJlZyksIHJlZ19ub2RiZ19lbmQoKSk7CisgIH0KKworICAvLy8gcmVnX2luc3RyX25vZGJnX2l0ZXJhdG9yL3JlZ19pbnN0cl9ub2RiZ19iZWdpbi9yZWdfaW5zdHJfbm9kYmdfZW5kIC0gV2FsaworICAvLy8gYWxsIGRlZnMgYW5kIHVzZXMgb2YgdGhlIHNwZWNpZmllZCByZWdpc3Rlciwgc3RlcHBpbmcgYnkgTWFjaGluZUluc3RyLAorICAvLy8gc2tpcHBpbmcgdGhvc2UgbWFya2VkIGFzIERlYnVnLgorICB1c2luZyByZWdfaW5zdHJfbm9kYmdfaXRlcmF0b3IgPQorICAgICAgZGVmdXNlY2hhaW5faW5zdHJfaXRlcmF0b3I8dHJ1ZSwgdHJ1ZSwgdHJ1ZSwgZmFsc2UsIHRydWUsIGZhbHNlPjsKKyAgcmVnX2luc3RyX25vZGJnX2l0ZXJhdG9yIHJlZ19pbnN0cl9ub2RiZ19iZWdpbih1bnNpZ25lZCBSZWdObykgY29uc3QgeworICAgIHJldHVybiByZWdfaW5zdHJfbm9kYmdfaXRlcmF0b3IoZ2V0UmVnVXNlRGVmTGlzdEhlYWQoUmVnTm8pKTsKKyAgfQorICBzdGF0aWMgcmVnX2luc3RyX25vZGJnX2l0ZXJhdG9yIHJlZ19pbnN0cl9ub2RiZ19lbmQoKSB7CisgICAgcmV0dXJuIHJlZ19pbnN0cl9ub2RiZ19pdGVyYXRvcihudWxscHRyKTsKKyAgfQorCisgIGlubGluZSBpdGVyYXRvcl9yYW5nZTxyZWdfaW5zdHJfbm9kYmdfaXRlcmF0b3I+CisgIHJlZ19ub2RiZ19pbnN0cnVjdGlvbnModW5zaWduZWQgUmVnKSBjb25zdCB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2UocmVnX2luc3RyX25vZGJnX2JlZ2luKFJlZyksIHJlZ19pbnN0cl9ub2RiZ19lbmQoKSk7CisgIH0KKworICAvLy8gcmVnX2J1bmRsZV9ub2RiZ19pdGVyYXRvci9yZWdfYnVuZGxlX25vZGJnX2JlZ2luL3JlZ19idW5kbGVfbm9kYmdfZW5kIC0gV2FsaworICAvLy8gYWxsIGRlZnMgYW5kIHVzZXMgb2YgdGhlIHNwZWNpZmllZCByZWdpc3Rlciwgc3RlcHBpbmcgYnkgYnVuZGxlLAorICAvLy8gc2tpcHBpbmcgdGhvc2UgbWFya2VkIGFzIERlYnVnLgorICB1c2luZyByZWdfYnVuZGxlX25vZGJnX2l0ZXJhdG9yID0KKyAgICAgIGRlZnVzZWNoYWluX2luc3RyX2l0ZXJhdG9yPHRydWUsIHRydWUsIHRydWUsIGZhbHNlLCBmYWxzZSwgdHJ1ZT47CisgIHJlZ19idW5kbGVfbm9kYmdfaXRlcmF0b3IgcmVnX2J1bmRsZV9ub2RiZ19iZWdpbih1bnNpZ25lZCBSZWdObykgY29uc3QgeworICAgIHJldHVybiByZWdfYnVuZGxlX25vZGJnX2l0ZXJhdG9yKGdldFJlZ1VzZURlZkxpc3RIZWFkKFJlZ05vKSk7CisgIH0KKyAgc3RhdGljIHJlZ19idW5kbGVfbm9kYmdfaXRlcmF0b3IgcmVnX2J1bmRsZV9ub2RiZ19lbmQoKSB7CisgICAgcmV0dXJuIHJlZ19idW5kbGVfbm9kYmdfaXRlcmF0b3IobnVsbHB0cik7CisgIH0KKworICBpbmxpbmUgaXRlcmF0b3JfcmFuZ2U8cmVnX2J1bmRsZV9ub2RiZ19pdGVyYXRvcj4KKyAgcmVnX25vZGJnX2J1bmRsZXModW5zaWduZWQgUmVnKSBjb25zdCB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2UocmVnX2J1bmRsZV9ub2RiZ19iZWdpbihSZWcpLCByZWdfYnVuZGxlX25vZGJnX2VuZCgpKTsKKyAgfQorCisgIC8vLyByZWdfbm9kYmdfZW1wdHkgLSBSZXR1cm4gdHJ1ZSBpZiB0aGUgb25seSBpbnN0cnVjdGlvbnMgdXNpbmcgb3IgZGVmaW5pbmcKKyAgLy8vIFJlZyBhcmUgRGVidWcgaW5zdHJ1Y3Rpb25zLgorICBib29sIHJlZ19ub2RiZ19lbXB0eSh1bnNpZ25lZCBSZWdObykgY29uc3QgeworICAgIHJldHVybiByZWdfbm9kYmdfYmVnaW4oUmVnTm8pID09IHJlZ19ub2RiZ19lbmQoKTsKKyAgfQorCisgIC8vLyBkZWZfaXRlcmF0b3IvZGVmX2JlZ2luL2RlZl9lbmQgLSBXYWxrIGFsbCBkZWZzIG9mIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIuCisgIHVzaW5nIGRlZl9pdGVyYXRvciA9CisgICAgICBkZWZ1c2VjaGFpbl9pdGVyYXRvcjxmYWxzZSwgdHJ1ZSwgZmFsc2UsIHRydWUsIGZhbHNlLCBmYWxzZT47CisgIGRlZl9pdGVyYXRvciBkZWZfYmVnaW4odW5zaWduZWQgUmVnTm8pIGNvbnN0IHsKKyAgICByZXR1cm4gZGVmX2l0ZXJhdG9yKGdldFJlZ1VzZURlZkxpc3RIZWFkKFJlZ05vKSk7CisgIH0KKyAgc3RhdGljIGRlZl9pdGVyYXRvciBkZWZfZW5kKCkgeyByZXR1cm4gZGVmX2l0ZXJhdG9yKG51bGxwdHIpOyB9CisKKyAgaW5saW5lIGl0ZXJhdG9yX3JhbmdlPGRlZl9pdGVyYXRvcj4gZGVmX29wZXJhbmRzKHVuc2lnbmVkIFJlZykgY29uc3QgeworICAgIHJldHVybiBtYWtlX3JhbmdlKGRlZl9iZWdpbihSZWcpLCBkZWZfZW5kKCkpOworICB9CisKKyAgLy8vIGRlZl9pbnN0cl9pdGVyYXRvci9kZWZfaW5zdHJfYmVnaW4vZGVmX2luc3RyX2VuZCAtIFdhbGsgYWxsIGRlZnMgb2YgdGhlCisgIC8vLyBzcGVjaWZpZWQgcmVnaXN0ZXIsIHN0ZXBwaW5nIGJ5IE1hY2hpbmVJbnN0LgorICB1c2luZyBkZWZfaW5zdHJfaXRlcmF0b3IgPQorICAgICAgZGVmdXNlY2hhaW5faW5zdHJfaXRlcmF0b3I8ZmFsc2UsIHRydWUsIGZhbHNlLCBmYWxzZSwgdHJ1ZSwgZmFsc2U+OworICBkZWZfaW5zdHJfaXRlcmF0b3IgZGVmX2luc3RyX2JlZ2luKHVuc2lnbmVkIFJlZ05vKSBjb25zdCB7CisgICAgcmV0dXJuIGRlZl9pbnN0cl9pdGVyYXRvcihnZXRSZWdVc2VEZWZMaXN0SGVhZChSZWdObykpOworICB9CisgIHN0YXRpYyBkZWZfaW5zdHJfaXRlcmF0b3IgZGVmX2luc3RyX2VuZCgpIHsKKyAgICByZXR1cm4gZGVmX2luc3RyX2l0ZXJhdG9yKG51bGxwdHIpOworICB9CisKKyAgaW5saW5lIGl0ZXJhdG9yX3JhbmdlPGRlZl9pbnN0cl9pdGVyYXRvcj4KKyAgZGVmX2luc3RydWN0aW9ucyh1bnNpZ25lZCBSZWcpIGNvbnN0IHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZShkZWZfaW5zdHJfYmVnaW4oUmVnKSwgZGVmX2luc3RyX2VuZCgpKTsKKyAgfQorCisgIC8vLyBkZWZfYnVuZGxlX2l0ZXJhdG9yL2RlZl9idW5kbGVfYmVnaW4vZGVmX2J1bmRsZV9lbmQgLSBXYWxrIGFsbCBkZWZzIG9mIHRoZQorICAvLy8gc3BlY2lmaWVkIHJlZ2lzdGVyLCBzdGVwcGluZyBieSBidW5kbGUuCisgIHVzaW5nIGRlZl9idW5kbGVfaXRlcmF0b3IgPQorICAgICAgZGVmdXNlY2hhaW5faW5zdHJfaXRlcmF0b3I8ZmFsc2UsIHRydWUsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWU+OworICBkZWZfYnVuZGxlX2l0ZXJhdG9yIGRlZl9idW5kbGVfYmVnaW4odW5zaWduZWQgUmVnTm8pIGNvbnN0IHsKKyAgICByZXR1cm4gZGVmX2J1bmRsZV9pdGVyYXRvcihnZXRSZWdVc2VEZWZMaXN0SGVhZChSZWdObykpOworICB9CisgIHN0YXRpYyBkZWZfYnVuZGxlX2l0ZXJhdG9yIGRlZl9idW5kbGVfZW5kKCkgeworICAgIHJldHVybiBkZWZfYnVuZGxlX2l0ZXJhdG9yKG51bGxwdHIpOworICB9CisKKyAgaW5saW5lIGl0ZXJhdG9yX3JhbmdlPGRlZl9idW5kbGVfaXRlcmF0b3I+IGRlZl9idW5kbGVzKHVuc2lnbmVkIFJlZykgY29uc3QgeworICAgIHJldHVybiBtYWtlX3JhbmdlKGRlZl9idW5kbGVfYmVnaW4oUmVnKSwgZGVmX2J1bmRsZV9lbmQoKSk7CisgIH0KKworICAvLy8gZGVmX2VtcHR5IC0gUmV0dXJuIHRydWUgaWYgdGhlcmUgYXJlIG5vIGluc3RydWN0aW9ucyBkZWZpbmluZyB0aGUKKyAgLy8vIHNwZWNpZmllZCByZWdpc3RlciAoaXQgbWF5IGJlIGxpdmUtaW4pLgorICBib29sIGRlZl9lbXB0eSh1bnNpZ25lZCBSZWdObykgY29uc3QgeyByZXR1cm4gZGVmX2JlZ2luKFJlZ05vKSA9PSBkZWZfZW5kKCk7IH0KKworICBTdHJpbmdSZWYgZ2V0VlJlZ05hbWUodW5zaWduZWQgUmVnKSBjb25zdCB7CisgICAgcmV0dXJuIFZSZWcyTmFtZS5pbkJvdW5kcyhSZWcpID8gU3RyaW5nUmVmKFZSZWcyTmFtZVtSZWddKSA6ICIiOworICB9CisKKyAgdm9pZCBpbnNlcnRWUmVnQnlOYW1lKFN0cmluZ1JlZiBOYW1lLCB1bnNpZ25lZCBSZWcpIHsKKyAgICBhc3NlcnQoKE5hbWUuZW1wdHkoKSB8fCBWUmVnTmFtZXMuZmluZChOYW1lKSA9PSBWUmVnTmFtZXMuZW5kKCkpICYmCisgICAgICAgICAgICJOYW1lZCBWUmVncyBNdXN0IGJlIFVuaXF1ZS4iKTsKKyAgICBpZiAoIU5hbWUuZW1wdHkoKSkgeworICAgICAgVlJlZ05hbWVzLmluc2VydChOYW1lKTsKKyAgICAgIFZSZWcyTmFtZS5ncm93KFJlZyk7CisgICAgICBWUmVnMk5hbWVbUmVnXSA9IE5hbWUuc3RyKCk7CisgICAgfQorICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZXJlIGlzIGV4YWN0bHkgb25lIG9wZXJhbmQgZGVmaW5pbmcgdGhlIHNwZWNpZmllZAorICAvLy8gcmVnaXN0ZXIuCisgIGJvb2wgaGFzT25lRGVmKHVuc2lnbmVkIFJlZ05vKSBjb25zdCB7CisgICAgZGVmX2l0ZXJhdG9yIERJID0gZGVmX2JlZ2luKFJlZ05vKTsKKyAgICBpZiAoREkgPT0gZGVmX2VuZCgpKQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIHJldHVybiArK0RJID09IGRlZl9lbmQoKTsKKyAgfQorCisgIC8vLyB1c2VfaXRlcmF0b3IvdXNlX2JlZ2luL3VzZV9lbmQgLSBXYWxrIGFsbCB1c2VzIG9mIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIuCisgIHVzaW5nIHVzZV9pdGVyYXRvciA9CisgICAgICBkZWZ1c2VjaGFpbl9pdGVyYXRvcjx0cnVlLCBmYWxzZSwgZmFsc2UsIHRydWUsIGZhbHNlLCBmYWxzZT47CisgIHVzZV9pdGVyYXRvciB1c2VfYmVnaW4odW5zaWduZWQgUmVnTm8pIGNvbnN0IHsKKyAgICByZXR1cm4gdXNlX2l0ZXJhdG9yKGdldFJlZ1VzZURlZkxpc3RIZWFkKFJlZ05vKSk7CisgIH0KKyAgc3RhdGljIHVzZV9pdGVyYXRvciB1c2VfZW5kKCkgeyByZXR1cm4gdXNlX2l0ZXJhdG9yKG51bGxwdHIpOyB9CisKKyAgaW5saW5lIGl0ZXJhdG9yX3JhbmdlPHVzZV9pdGVyYXRvcj4gdXNlX29wZXJhbmRzKHVuc2lnbmVkIFJlZykgY29uc3QgeworICAgIHJldHVybiBtYWtlX3JhbmdlKHVzZV9iZWdpbihSZWcpLCB1c2VfZW5kKCkpOworICB9CisKKyAgLy8vIHVzZV9pbnN0cl9pdGVyYXRvci91c2VfaW5zdHJfYmVnaW4vdXNlX2luc3RyX2VuZCAtIFdhbGsgYWxsIHVzZXMgb2YgdGhlCisgIC8vLyBzcGVjaWZpZWQgcmVnaXN0ZXIsIHN0ZXBwaW5nIGJ5IE1hY2hpbmVJbnN0ci4KKyAgdXNpbmcgdXNlX2luc3RyX2l0ZXJhdG9yID0KKyAgICAgIGRlZnVzZWNoYWluX2luc3RyX2l0ZXJhdG9yPHRydWUsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIHRydWUsIGZhbHNlPjsKKyAgdXNlX2luc3RyX2l0ZXJhdG9yIHVzZV9pbnN0cl9iZWdpbih1bnNpZ25lZCBSZWdObykgY29uc3QgeworICAgIHJldHVybiB1c2VfaW5zdHJfaXRlcmF0b3IoZ2V0UmVnVXNlRGVmTGlzdEhlYWQoUmVnTm8pKTsKKyAgfQorICBzdGF0aWMgdXNlX2luc3RyX2l0ZXJhdG9yIHVzZV9pbnN0cl9lbmQoKSB7CisgICAgcmV0dXJuIHVzZV9pbnN0cl9pdGVyYXRvcihudWxscHRyKTsKKyAgfQorCisgIGlubGluZSBpdGVyYXRvcl9yYW5nZTx1c2VfaW5zdHJfaXRlcmF0b3I+CisgIHVzZV9pbnN0cnVjdGlvbnModW5zaWduZWQgUmVnKSBjb25zdCB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2UodXNlX2luc3RyX2JlZ2luKFJlZyksIHVzZV9pbnN0cl9lbmQoKSk7CisgIH0KKworICAvLy8gdXNlX2J1bmRsZV9pdGVyYXRvci91c2VfYnVuZGxlX2JlZ2luL3VzZV9idW5kbGVfZW5kIC0gV2FsayBhbGwgdXNlcyBvZiB0aGUKKyAgLy8vIHNwZWNpZmllZCByZWdpc3Rlciwgc3RlcHBpbmcgYnkgYnVuZGxlLgorICB1c2luZyB1c2VfYnVuZGxlX2l0ZXJhdG9yID0KKyAgICAgIGRlZnVzZWNoYWluX2luc3RyX2l0ZXJhdG9yPHRydWUsIGZhbHNlLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCB0cnVlPjsKKyAgdXNlX2J1bmRsZV9pdGVyYXRvciB1c2VfYnVuZGxlX2JlZ2luKHVuc2lnbmVkIFJlZ05vKSBjb25zdCB7CisgICAgcmV0dXJuIHVzZV9idW5kbGVfaXRlcmF0b3IoZ2V0UmVnVXNlRGVmTGlzdEhlYWQoUmVnTm8pKTsKKyAgfQorICBzdGF0aWMgdXNlX2J1bmRsZV9pdGVyYXRvciB1c2VfYnVuZGxlX2VuZCgpIHsKKyAgICByZXR1cm4gdXNlX2J1bmRsZV9pdGVyYXRvcihudWxscHRyKTsKKyAgfQorCisgIGlubGluZSBpdGVyYXRvcl9yYW5nZTx1c2VfYnVuZGxlX2l0ZXJhdG9yPiB1c2VfYnVuZGxlcyh1bnNpZ25lZCBSZWcpIGNvbnN0IHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZSh1c2VfYnVuZGxlX2JlZ2luKFJlZyksIHVzZV9idW5kbGVfZW5kKCkpOworICB9CisKKyAgLy8vIHVzZV9lbXB0eSAtIFJldHVybiB0cnVlIGlmIHRoZXJlIGFyZSBubyBpbnN0cnVjdGlvbnMgdXNpbmcgdGhlIHNwZWNpZmllZAorICAvLy8gcmVnaXN0ZXIuCisgIGJvb2wgdXNlX2VtcHR5KHVuc2lnbmVkIFJlZ05vKSBjb25zdCB7IHJldHVybiB1c2VfYmVnaW4oUmVnTm8pID09IHVzZV9lbmQoKTsgfQorCisgIC8vLyBoYXNPbmVVc2UgLSBSZXR1cm4gdHJ1ZSBpZiB0aGVyZSBpcyBleGFjdGx5IG9uZSBpbnN0cnVjdGlvbiB1c2luZyB0aGUKKyAgLy8vIHNwZWNpZmllZCByZWdpc3Rlci4KKyAgYm9vbCBoYXNPbmVVc2UodW5zaWduZWQgUmVnTm8pIGNvbnN0IHsKKyAgICB1c2VfaXRlcmF0b3IgVUkgPSB1c2VfYmVnaW4oUmVnTm8pOworICAgIGlmIChVSSA9PSB1c2VfZW5kKCkpCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgcmV0dXJuICsrVUkgPT0gdXNlX2VuZCgpOworICB9CisKKyAgLy8vIHVzZV9ub2RiZ19pdGVyYXRvci91c2Vfbm9kYmdfYmVnaW4vdXNlX25vZGJnX2VuZCAtIFdhbGsgYWxsIHVzZXMgb2YgdGhlCisgIC8vLyBzcGVjaWZpZWQgcmVnaXN0ZXIsIHNraXBwaW5nIHRob3NlIG1hcmtlZCBhcyBEZWJ1Zy4KKyAgdXNpbmcgdXNlX25vZGJnX2l0ZXJhdG9yID0KKyAgICAgIGRlZnVzZWNoYWluX2l0ZXJhdG9yPHRydWUsIGZhbHNlLCB0cnVlLCB0cnVlLCBmYWxzZSwgZmFsc2U+OworICB1c2Vfbm9kYmdfaXRlcmF0b3IgdXNlX25vZGJnX2JlZ2luKHVuc2lnbmVkIFJlZ05vKSBjb25zdCB7CisgICAgcmV0dXJuIHVzZV9ub2RiZ19pdGVyYXRvcihnZXRSZWdVc2VEZWZMaXN0SGVhZChSZWdObykpOworICB9CisgIHN0YXRpYyB1c2Vfbm9kYmdfaXRlcmF0b3IgdXNlX25vZGJnX2VuZCgpIHsKKyAgICByZXR1cm4gdXNlX25vZGJnX2l0ZXJhdG9yKG51bGxwdHIpOworICB9CisKKyAgaW5saW5lIGl0ZXJhdG9yX3JhbmdlPHVzZV9ub2RiZ19pdGVyYXRvcj4KKyAgdXNlX25vZGJnX29wZXJhbmRzKHVuc2lnbmVkIFJlZykgY29uc3QgeworICAgIHJldHVybiBtYWtlX3JhbmdlKHVzZV9ub2RiZ19iZWdpbihSZWcpLCB1c2Vfbm9kYmdfZW5kKCkpOworICB9CisKKyAgLy8vIHVzZV9pbnN0cl9ub2RiZ19pdGVyYXRvci91c2VfaW5zdHJfbm9kYmdfYmVnaW4vdXNlX2luc3RyX25vZGJnX2VuZCAtIFdhbGsKKyAgLy8vIGFsbCB1c2VzIG9mIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIsIHN0ZXBwaW5nIGJ5IE1hY2hpbmVJbnN0ciwgc2tpcHBpbmcKKyAgLy8vIHRob3NlIG1hcmtlZCBhcyBEZWJ1Zy4KKyAgdXNpbmcgdXNlX2luc3RyX25vZGJnX2l0ZXJhdG9yID0KKyAgICAgIGRlZnVzZWNoYWluX2luc3RyX2l0ZXJhdG9yPHRydWUsIGZhbHNlLCB0cnVlLCBmYWxzZSwgdHJ1ZSwgZmFsc2U+OworICB1c2VfaW5zdHJfbm9kYmdfaXRlcmF0b3IgdXNlX2luc3RyX25vZGJnX2JlZ2luKHVuc2lnbmVkIFJlZ05vKSBjb25zdCB7CisgICAgcmV0dXJuIHVzZV9pbnN0cl9ub2RiZ19pdGVyYXRvcihnZXRSZWdVc2VEZWZMaXN0SGVhZChSZWdObykpOworICB9CisgIHN0YXRpYyB1c2VfaW5zdHJfbm9kYmdfaXRlcmF0b3IgdXNlX2luc3RyX25vZGJnX2VuZCgpIHsKKyAgICByZXR1cm4gdXNlX2luc3RyX25vZGJnX2l0ZXJhdG9yKG51bGxwdHIpOworICB9CisKKyAgaW5saW5lIGl0ZXJhdG9yX3JhbmdlPHVzZV9pbnN0cl9ub2RiZ19pdGVyYXRvcj4KKyAgdXNlX25vZGJnX2luc3RydWN0aW9ucyh1bnNpZ25lZCBSZWcpIGNvbnN0IHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZSh1c2VfaW5zdHJfbm9kYmdfYmVnaW4oUmVnKSwgdXNlX2luc3RyX25vZGJnX2VuZCgpKTsKKyAgfQorCisgIC8vLyB1c2VfYnVuZGxlX25vZGJnX2l0ZXJhdG9yL3VzZV9idW5kbGVfbm9kYmdfYmVnaW4vdXNlX2J1bmRsZV9ub2RiZ19lbmQgLSBXYWxrCisgIC8vLyBhbGwgdXNlcyBvZiB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyLCBzdGVwcGluZyBieSBidW5kbGUsIHNraXBwaW5nCisgIC8vLyB0aG9zZSBtYXJrZWQgYXMgRGVidWcuCisgIHVzaW5nIHVzZV9idW5kbGVfbm9kYmdfaXRlcmF0b3IgPQorICAgICAgZGVmdXNlY2hhaW5faW5zdHJfaXRlcmF0b3I8dHJ1ZSwgZmFsc2UsIHRydWUsIGZhbHNlLCBmYWxzZSwgdHJ1ZT47CisgIHVzZV9idW5kbGVfbm9kYmdfaXRlcmF0b3IgdXNlX2J1bmRsZV9ub2RiZ19iZWdpbih1bnNpZ25lZCBSZWdObykgY29uc3QgeworICAgIHJldHVybiB1c2VfYnVuZGxlX25vZGJnX2l0ZXJhdG9yKGdldFJlZ1VzZURlZkxpc3RIZWFkKFJlZ05vKSk7CisgIH0KKyAgc3RhdGljIHVzZV9idW5kbGVfbm9kYmdfaXRlcmF0b3IgdXNlX2J1bmRsZV9ub2RiZ19lbmQoKSB7CisgICAgcmV0dXJuIHVzZV9idW5kbGVfbm9kYmdfaXRlcmF0b3IobnVsbHB0cik7CisgIH0KKworICBpbmxpbmUgaXRlcmF0b3JfcmFuZ2U8dXNlX2J1bmRsZV9ub2RiZ19pdGVyYXRvcj4KKyAgdXNlX25vZGJnX2J1bmRsZXModW5zaWduZWQgUmVnKSBjb25zdCB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2UodXNlX2J1bmRsZV9ub2RiZ19iZWdpbihSZWcpLCB1c2VfYnVuZGxlX25vZGJnX2VuZCgpKTsKKyAgfQorCisgIC8vLyB1c2Vfbm9kYmdfZW1wdHkgLSBSZXR1cm4gdHJ1ZSBpZiB0aGVyZSBhcmUgbm8gbm9uLURlYnVnIGluc3RydWN0aW9ucworICAvLy8gdXNpbmcgdGhlIHNwZWNpZmllZCByZWdpc3Rlci4KKyAgYm9vbCB1c2Vfbm9kYmdfZW1wdHkodW5zaWduZWQgUmVnTm8pIGNvbnN0IHsKKyAgICByZXR1cm4gdXNlX25vZGJnX2JlZ2luKFJlZ05vKSA9PSB1c2Vfbm9kYmdfZW5kKCk7CisgIH0KKworICAvLy8gaGFzT25lTm9uREJHVXNlIC0gUmV0dXJuIHRydWUgaWYgdGhlcmUgaXMgZXhhY3RseSBvbmUgbm9uLURlYnVnCisgIC8vLyBpbnN0cnVjdGlvbiB1c2luZyB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyLgorICBib29sIGhhc09uZU5vbkRCR1VzZSh1bnNpZ25lZCBSZWdObykgY29uc3Q7CisKKyAgLy8vIHJlcGxhY2VSZWdXaXRoIC0gUmVwbGFjZSBhbGwgaW5zdGFuY2VzIG9mIEZyb21SZWcgd2l0aCBUb1JlZyBpbiB0aGUKKyAgLy8vIG1hY2hpbmUgZnVuY3Rpb24uICBUaGlzIGlzIGxpa2UgbGx2bS1sZXZlbCBYLT5yZXBsYWNlQWxsVXNlc1dpdGgoWSksCisgIC8vLyBleGNlcHQgdGhhdCBpdCBhbHNvIGNoYW5nZXMgYW55IGRlZmluaXRpb25zIG9mIHRoZSByZWdpc3RlciBhcyB3ZWxsLgorICAvLy8KKyAgLy8vIE5vdGUgdGhhdCBpdCBpcyB1c3VhbGx5IG5lY2Vzc2FyeSB0byBmaXJzdCBjb25zdHJhaW4gVG9SZWcncyByZWdpc3RlcgorICAvLy8gY2xhc3MgYW5kIHJlZ2lzdGVyIGJhbmsgdG8gbWF0Y2ggdGhlIEZyb21SZWcgY29uc3RyYWludHMgdXNpbmcgb25lIG9mIHRoZQorICAvLy8gbWV0aG9kczoKKyAgLy8vCisgIC8vLyAgIGNvbnN0cmFpblJlZ0NsYXNzKFRvUmVnLCBnZXRSZWdDbGFzcyhGcm9tUmVnKSkKKyAgLy8vICAgY29uc3RyYWluUmVnQXR0cnMoVG9SZWcsIEZyb21SZWcpCisgIC8vLyAgIFJlZ2lzdGVyQmFua0luZm86OmNvbnN0cmFpbkdlbmVyaWNSZWdpc3RlcihUb1JlZywKKyAgLy8vICAgICAgICpNUkkuZ2V0UmVnQ2xhc3MoRnJvbVJlZyksIE1SSSkKKyAgLy8vCisgIC8vLyBUaGVzZSBmdW5jdGlvbnMgd2lsbCByZXR1cm4gYSBmYWxzeSByZXN1bHQgaWYgdGhlIHZpcnR1YWwgcmVnaXN0ZXJzIGhhdmUKKyAgLy8vIGluY29tcGF0aWJsZSBjb25zdHJhaW50cy4KKyAgLy8vCisgIC8vLyBOb3RlIHRoYXQgaWYgVG9SZWcgaXMgYSBwaHlzaWNhbCByZWdpc3RlciB0aGUgZnVuY3Rpb24gd2lsbCByZXBsYWNlIGFuZAorICAvLy8gYXBwbHkgc3ViIHJlZ2lzdGVycyB0byBUb1JlZyBpbiBvcmRlciB0byBvYnRhaW4gYSBmaW5hbC9wcm9wZXIgcGh5c2ljYWwKKyAgLy8vIHJlZ2lzdGVyLgorICB2b2lkIHJlcGxhY2VSZWdXaXRoKHVuc2lnbmVkIEZyb21SZWcsIHVuc2lnbmVkIFRvUmVnKTsKKworICAvLy8gZ2V0VlJlZ0RlZiAtIFJldHVybiB0aGUgbWFjaGluZSBpbnN0ciB0aGF0IGRlZmluZXMgdGhlIHNwZWNpZmllZCB2aXJ0dWFsCisgIC8vLyByZWdpc3RlciBvciBudWxsIGlmIG5vbmUgaXMgZm91bmQuICBUaGlzIGFzc3VtZXMgdGhhdCB0aGUgY29kZSBpcyBpbiBTU0EKKyAgLy8vIGZvcm0sIHNvIHRoZXJlIHNob3VsZCBvbmx5IGJlIG9uZSBkZWZpbml0aW9uLgorICBNYWNoaW5lSW5zdHIgKmdldFZSZWdEZWYodW5zaWduZWQgUmVnKSBjb25zdDsKKworICAvLy8gZ2V0VW5pcXVlVlJlZ0RlZiAtIFJldHVybiB0aGUgdW5pcXVlIG1hY2hpbmUgaW5zdHIgdGhhdCBkZWZpbmVzIHRoZQorICAvLy8gc3BlY2lmaWVkIHZpcnR1YWwgcmVnaXN0ZXIgb3IgbnVsbCBpZiBub25lIGlzIGZvdW5kLiAgSWYgdGhlcmUgYXJlCisgIC8vLyBtdWx0aXBsZSBkZWZpbml0aW9ucyBvciBubyBkZWZpbml0aW9uLCByZXR1cm4gbnVsbC4KKyAgTWFjaGluZUluc3RyICpnZXRVbmlxdWVWUmVnRGVmKHVuc2lnbmVkIFJlZykgY29uc3Q7CisKKyAgLy8vIGNsZWFyS2lsbEZsYWdzIC0gSXRlcmF0ZSBvdmVyIGFsbCB0aGUgdXNlcyBvZiB0aGUgZ2l2ZW4gcmVnaXN0ZXIgYW5kCisgIC8vLyBjbGVhciB0aGUga2lsbCBmbGFnIGZyb20gdGhlIE1hY2hpbmVPcGVyYW5kLiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgYnkKKyAgLy8vIG9wdGltaXphdGlvbiBwYXNzZXMgd2hpY2ggZXh0ZW5kIHJlZ2lzdGVyIGxpZmV0aW1lcyBhbmQgbmVlZCBvbmx5CisgIC8vLyBwcmVzZXJ2ZSBjb25zZXJ2YXRpdmUga2lsbCBmbGFnIGluZm9ybWF0aW9uLgorICB2b2lkIGNsZWFyS2lsbEZsYWdzKHVuc2lnbmVkIFJlZykgY29uc3Q7CisKKyAgdm9pZCBkdW1wVXNlcyh1bnNpZ25lZCBSZWdObykgY29uc3Q7CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiBQaHlzUmVnIGlzIHVuYWxsb2NhdGFibGUgYW5kIGNvbnN0YW50IHRocm91Z2hvdXQgdGhlCisgIC8vLyBmdW5jdGlvbi4gV3JpdGluZyB0byBhIGNvbnN0YW50IHJlZ2lzdGVyIGhhcyBubyBlZmZlY3QuCisgIGJvb2wgaXNDb25zdGFudFBoeXNSZWcodW5zaWduZWQgUGh5c1JlZykgY29uc3Q7CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiBlaXRoZXIgaXNDb25zdGFudFBoeXNSZWcgb3IgVFJJLT5pc0NhbGxlclByZXNlcnZlZFBoeXNSZWcKKyAgLy8vIHJldHVybnMgdHJ1ZS4gVGhpcyBpcyBhIHV0aWxpdHkgbWVtYmVyIGZ1bmN0aW9uLgorICBib29sIGlzQ2FsbGVyUHJlc2VydmVkT3JDb25zdFBoeXNSZWcodW5zaWduZWQgUGh5c1JlZykgY29uc3Q7CisKKyAgLy8vIEdldCBhbiBpdGVyYXRvciBvdmVyIHRoZSBwcmVzc3VyZSBzZXRzIGFmZmVjdGVkIGJ5IHRoZSBnaXZlbiBwaHlzaWNhbCBvcgorICAvLy8gdmlydHVhbCByZWdpc3Rlci4gSWYgUmVnVW5pdCBpcyBwaHlzaWNhbCwgaXQgbXVzdCBiZSBhIHJlZ2lzdGVyIHVuaXQgKGZyb20KKyAgLy8vIE1DUmVnVW5pdEl0ZXJhdG9yKS4KKyAgUFNldEl0ZXJhdG9yIGdldFByZXNzdXJlU2V0cyh1bnNpZ25lZCBSZWdVbml0KSBjb25zdDsKKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gVmlydHVhbCBSZWdpc3RlciBJbmZvCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisgIC8vLyBSZXR1cm4gdGhlIHJlZ2lzdGVyIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgdmlydHVhbCByZWdpc3Rlci4KKyAgLy8vIFRoaXMgc2hvdWxkbid0IGJlIHVzZWQgZGlyZWN0bHkgdW5sZXNzIFxwIFJlZyBoYXMgYSByZWdpc3RlciBjbGFzcy4KKyAgLy8vIFxzZWUgZ2V0UmVnQ2xhc3NPck51bGwgd2hlbiB0aGlzIG1pZ2h0IGhhcHBlbi4KKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqZ2V0UmVnQ2xhc3ModW5zaWduZWQgUmVnKSBjb25zdCB7CisgICAgYXNzZXJ0KFZSZWdJbmZvW1JlZ10uZmlyc3QuaXM8Y29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqPigpICYmCisgICAgICAgICAgICJSZWdpc3RlciBjbGFzcyBub3Qgc2V0LCB3cm9uZyBhY2Nlc3NvciIpOworICAgIHJldHVybiBWUmVnSW5mb1tSZWddLmZpcnN0LmdldDxjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICo+KCk7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSByZWdpc3RlciBjbGFzcyBvZiBccCBSZWcsIG9yIG51bGwgaWYgUmVnIGhhcyBub3QgYmVlbiBhc3NpZ25lZAorICAvLy8gYSByZWdpc3RlciBjbGFzcyB5ZXQuCisgIC8vLworICAvLy8gXG5vdGUgQSBudWxsIHJlZ2lzdGVyIGNsYXNzIGNhbiBvbmx5IGhhcHBlbiB3aGVuIHRoZXNlIHR3bworICAvLy8gY29uZGl0aW9ucyBhcmUgbWV0OgorICAvLy8gMS4gR2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVycyBhcmUgY3JlYXRlZC4KKyAgLy8vIDIuIFRoZSBtYWNoaW5lIGZ1bmN0aW9uIGhhcyBub3QgY29tcGxldGVseSBiZWVuIHRocm91Z2ggdGhlCisgIC8vLyAgICBpbnN0cnVjdGlvbiBzZWxlY3Rpb24gcHJvY2Vzcy4KKyAgLy8vIE5vbmUgb2YgdGhpcyBjb25kaXRpb24gaXMgcG9zc2libGUgd2l0aG91dCBHbG9iYWxJU2VsIGZvciBub3cuCisgIC8vLyBJbiBvdGhlciB3b3JkcywgaWYgR2xvYmFsSVNlbCBpcyBub3QgdXNlZCBvciBpZiB0aGUgcXVlcnkgaGFwcGVucyBhZnRlcgorICAvLy8gdGhlIHNlbGVjdCBwYXNzLCB1c2luZyBnZXRSZWdDbGFzcyBpcyBzYWZlLgorICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpnZXRSZWdDbGFzc09yTnVsbCh1bnNpZ25lZCBSZWcpIGNvbnN0IHsKKyAgICBjb25zdCBSZWdDbGFzc09yUmVnQmFuayAmVmFsID0gVlJlZ0luZm9bUmVnXS5maXJzdDsKKyAgICByZXR1cm4gVmFsLmR5bl9jYXN0PGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKj4oKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIHJlZ2lzdGVyIGJhbmsgb2YgXHAgUmVnLCBvciBudWxsIGlmIFJlZyBoYXMgbm90IGJlZW4gYXNzaWduZWQKKyAgLy8vIGEgcmVnaXN0ZXIgYmFuayBvciBoYXMgYmVlbiBhc3NpZ25lZCBhIHJlZ2lzdGVyIGNsYXNzLgorICAvLy8gXG5vdGUgSXQgaXMgcG9zc2libGUgdG8gZ2V0IHRoZSByZWdpc3RlciBiYW5rIGZyb20gdGhlIHJlZ2lzdGVyIGNsYXNzIHZpYQorICAvLy8gUmVnaXN0ZXJCYW5rSW5mbzo6Z2V0UmVnQmFua0Zyb21SZWdDbGFzcy4KKyAgY29uc3QgUmVnaXN0ZXJCYW5rICpnZXRSZWdCYW5rT3JOdWxsKHVuc2lnbmVkIFJlZykgY29uc3QgeworICAgIGNvbnN0IFJlZ0NsYXNzT3JSZWdCYW5rICZWYWwgPSBWUmVnSW5mb1tSZWddLmZpcnN0OworICAgIHJldHVybiBWYWwuZHluX2Nhc3Q8Y29uc3QgUmVnaXN0ZXJCYW5rICo+KCk7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSByZWdpc3RlciBiYW5rIG9yIHJlZ2lzdGVyIGNsYXNzIG9mIFxwIFJlZy4KKyAgLy8vIFxub3RlIEJlZm9yZSB0aGUgcmVnaXN0ZXIgYmFuayBnZXRzIGFzc2lnbmVkIChpLmUuLCBiZWZvcmUgdGhlCisgIC8vLyBSZWdCYW5rU2VsZWN0IHBhc3MpIFxwIFJlZyBtYXkgbm90IGhhdmUgZWl0aGVyLgorICBjb25zdCBSZWdDbGFzc09yUmVnQmFuayAmZ2V0UmVnQ2xhc3NPclJlZ0JhbmsodW5zaWduZWQgUmVnKSBjb25zdCB7CisgICAgcmV0dXJuIFZSZWdJbmZvW1JlZ10uZmlyc3Q7CisgIH0KKworICAvLy8gc2V0UmVnQ2xhc3MgLSBTZXQgdGhlIHJlZ2lzdGVyIGNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgdmlydHVhbCByZWdpc3Rlci4KKyAgdm9pZCBzZXRSZWdDbGFzcyh1bnNpZ25lZCBSZWcsIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKTsKKworICAvLy8gU2V0IHRoZSByZWdpc3RlciBiYW5rIHRvIFxwIFJlZ0JhbmsgZm9yIFxwIFJlZy4KKyAgdm9pZCBzZXRSZWdCYW5rKHVuc2lnbmVkIFJlZywgY29uc3QgUmVnaXN0ZXJCYW5rICZSZWdCYW5rKTsKKworICB2b2lkIHNldFJlZ0NsYXNzT3JSZWdCYW5rKHVuc2lnbmVkIFJlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZWdDbGFzc09yUmVnQmFuayAmUkNPclJCKXsKKyAgICBWUmVnSW5mb1tSZWddLmZpcnN0ID0gUkNPclJCOworICB9CisKKyAgLy8vIGNvbnN0cmFpblJlZ0NsYXNzIC0gQ29uc3RyYWluIHRoZSByZWdpc3RlciBjbGFzcyBvZiB0aGUgc3BlY2lmaWVkIHZpcnR1YWwKKyAgLy8vIHJlZ2lzdGVyIHRvIGJlIGEgY29tbW9uIHN1YmNsYXNzIG9mIFJDIGFuZCB0aGUgY3VycmVudCByZWdpc3RlciBjbGFzcywKKyAgLy8vIGJ1dCBvbmx5IGlmIHRoZSBuZXcgY2xhc3MgaGFzIGF0IGxlYXN0IE1pbk51bVJlZ3MgcmVnaXN0ZXJzLiAgUmV0dXJuIHRoZQorICAvLy8gbmV3IHJlZ2lzdGVyIGNsYXNzLCBvciBOVUxMIGlmIG5vIHN1Y2ggY2xhc3MgZXhpc3RzLgorICAvLy8gVGhpcyBzaG91bGQgb25seSBiZSB1c2VkIHdoZW4gdGhlIGNvbnN0cmFpbnQgaXMga25vd24gdG8gYmUgdHJpdmlhbCwgbGlrZQorICAvLy8gR1IzMiAtPiBHUjMyX05PU1AuIEJld2FyZSBvZiBpbmNyZWFzaW5nIHJlZ2lzdGVyIHByZXNzdXJlLgorICAvLy8KKyAgLy8vIFxub3RlIEFzc3VtZXMgdGhhdCB0aGUgcmVnaXN0ZXIgaGFzIGEgcmVnaXN0ZXIgY2xhc3MgYXNzaWduZWQuCisgIC8vLyBVc2UgUmVnaXN0ZXJCYW5rSW5mbzo6Y29uc3RyYWluR2VuZXJpY1JlZ2lzdGVyIGluIEdsb2JhbElTZWwncworICAvLy8gSW5zdHJ1Y3Rpb25TZWxlY3QgcGFzcyBhbmQgY29uc3RyYWluUmVnQXR0cnMgaW4gZXZlcnkgb3RoZXIgcGFzcywKKyAgLy8vIGluY2x1ZGluZyBub24tc2VsZWN0IHBhc3NlcyBvZiBHbG9iYWxJU2VsLCBpbnN0ZWFkLgorICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpjb25zdHJhaW5SZWdDbGFzcyh1bnNpZ25lZCBSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBNaW5OdW1SZWdzID0gMCk7CisKKyAgLy8vIENvbnN0cmFpbiB0aGUgcmVnaXN0ZXIgY2xhc3Mgb3IgdGhlIHJlZ2lzdGVyIGJhbmsgb2YgdGhlIHZpcnR1YWwgcmVnaXN0ZXIKKyAgLy8vIFxwIFJlZyB0byBiZSBhIGNvbW1vbiBzdWJjbGFzcyBhbmQgYSBjb21tb24gYmFuayBvZiBib3RoIHJlZ2lzdGVycworICAvLy8gcHJvdmlkZWQgcmVzcGVjdGl2ZWx5LiBEbyBub3RoaW5nIGlmIGFueSBvZiB0aGUgYXR0cmlidXRlcyAoY2xhc3NlcywKKyAgLy8vIGJhbmtzLCBvciBsb3ctbGV2ZWwgdHlwZXMpIG9mIHRoZSByZWdpc3RlcnMgYXJlIGRlZW1lZCBpbmNvbXBhdGlibGUsIG9yIGlmCisgIC8vLyB0aGUgcmVzdWx0aW5nIHJlZ2lzdGVyIHdpbGwgaGF2ZSBhIGNsYXNzIHNtYWxsZXIgdGhhbiBiZWZvcmUgYW5kIG9mIHNpemUKKyAgLy8vIGxlc3MgdGhhbiBccCBNaW5OdW1SZWdzLiBSZXR1cm4gdHJ1ZSBpZiBzdWNoIHJlZ2lzdGVyIGF0dHJpYnV0ZXMgZXhpc3QsCisgIC8vLyBmYWxzZSBvdGhlcndpc2UuCisgIC8vLworICAvLy8gXG5vdGUgQXNzdW1lcyB0aGF0IGVhY2ggcmVnaXN0ZXIgaGFzIGVpdGhlciBhIGxvdy1sZXZlbCB0eXBlIG9yIGEgY2xhc3MKKyAgLy8vIGFzc2lnbmVkLCBidXQgbm90IGJvdGguIFVzZSB0aGlzIG1ldGhvZCBpbnN0ZWFkIG9mIGNvbnN0cmFpblJlZ0NsYXNzIGFuZAorICAvLy8gUmVnaXN0ZXJCYW5rSW5mbzo6Y29uc3RyYWluR2VuZXJpY1JlZ2lzdGVyIGV2ZXJ5d2hlcmUgYnV0IFNlbGVjdGlvbkRBRworICAvLy8gSVNlbCAvIEZhc3RJU2VsIGFuZCBHbG9iYWxJU2VsJ3MgSW5zdHJ1Y3Rpb25TZWxlY3QgcGFzcyByZXNwZWN0aXZlbHkuCisgIGJvb2wgY29uc3RyYWluUmVnQXR0cnModW5zaWduZWQgUmVnLCB1bnNpZ25lZCBDb25zdHJhaW5pbmdSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgTWluTnVtUmVncyA9IDApOworCisgIC8vLyByZWNvbXB1dGVSZWdDbGFzcyAtIFRyeSB0byBmaW5kIGEgbGVnYWwgc3VwZXItY2xhc3Mgb2YgUmVnJ3MgcmVnaXN0ZXIKKyAgLy8vIGNsYXNzIHRoYXQgc3RpbGwgc2F0aXNmaWVzIHRoZSBjb25zdHJhaW50cyBmcm9tIHRoZSBpbnN0cnVjdGlvbnMgdXNpbmcKKyAgLy8vIFJlZy4gIFJldHVybnMgdHJ1ZSBpZiBSZWcgd2FzIHVwZ3JhZGVkLgorICAvLy8KKyAgLy8vIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIGFmdGVyIGNvbnN0cmFpbnRzIGhhdmUgYmVlbiByZW1vdmVkIGZyb20gYQorICAvLy8gdmlydHVhbCByZWdpc3RlciwgZm9yIGV4YW1wbGUgYWZ0ZXIgcmVtb3ZpbmcgaW5zdHJ1Y3Rpb25zIG9yIHNwbGl0dGluZworICAvLy8gdGhlIGxpdmUgcmFuZ2UuCisgIGJvb2wgcmVjb21wdXRlUmVnQ2xhc3ModW5zaWduZWQgUmVnKTsKKworICAvLy8gY3JlYXRlVmlydHVhbFJlZ2lzdGVyIC0gQ3JlYXRlIGFuZCByZXR1cm4gYSBuZXcgdmlydHVhbCByZWdpc3RlciBpbiB0aGUKKyAgLy8vIGZ1bmN0aW9uIHdpdGggdGhlIHNwZWNpZmllZCByZWdpc3RlciBjbGFzcy4KKyAgdW5zaWduZWQgY3JlYXRlVmlydHVhbFJlZ2lzdGVyKGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJlZ0NsYXNzKTsKKworICAvLy8gQWNjZXNzb3IgZm9yIFZSZWdUb1R5cGUuIFRoaXMgYWNjZXNzb3Igc2hvdWxkIG9ubHkgYmUgdXNlZAorICAvLy8gYnkgZ2xvYmFsLWlzZWwgcmVsYXRlZCB3b3JrLgorICBWUmVnVG9UeXBlTWFwICZnZXRWUmVnVG9UeXBlKCkgY29uc3QgeworICAgIGlmICghVlJlZ1RvVHlwZSkKKyAgICAgIFZSZWdUb1R5cGUucmVzZXQobmV3IFZSZWdUb1R5cGVNYXApOworICAgIHJldHVybiAqVlJlZ1RvVHlwZS5nZXQoKTsKKyAgfQorCisgIC8vLyBHZXQgdGhlIGxvdy1sZXZlbCB0eXBlIG9mIFxwIFZSZWcgb3IgTExUe30gaWYgVlJlZyBpcyBub3QgYSBnZW5lcmljCisgIC8vLyAodGFyZ2V0IGluZGVwZW5kZW50KSB2aXJ0dWFsIHJlZ2lzdGVyLgorICBMTFQgZ2V0VHlwZSh1bnNpZ25lZCBWUmVnKSBjb25zdDsKKworICAvLy8gU2V0IHRoZSBsb3ctbGV2ZWwgdHlwZSBvZiBccCBWUmVnIHRvIFxwIFR5LgorICB2b2lkIHNldFR5cGUodW5zaWduZWQgVlJlZywgTExUIFR5KTsKKworICAvLy8gQ3JlYXRlIGFuZCByZXR1cm4gYSBuZXcgZ2VuZXJpYyB2aXJ0dWFsIHJlZ2lzdGVyIHdpdGggbG93LWxldmVsCisgIC8vLyB0eXBlIFxwIFR5LgorICB1bnNpZ25lZCBjcmVhdGVHZW5lcmljVmlydHVhbFJlZ2lzdGVyKExMVCBUeSk7CisKKyAgLy8vIFJlbW92ZSBhbGwgdHlwZXMgYXNzb2NpYXRlZCB0byB2aXJ0dWFsIHJlZ2lzdGVycyAoYWZ0ZXIgaW5zdHJ1Y3Rpb24KKyAgLy8vIHNlbGVjdGlvbiBhbmQgY29uc3RyYWluaW5nIG9mIGFsbCBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXJzKS4KKyAgdm9pZCBjbGVhclZpcnRSZWdUeXBlcygpOworCisgIC8vLyBDcmVhdGVzIGEgbmV3IHZpcnR1YWwgcmVnaXN0ZXIgdGhhdCBoYXMgbm8gcmVnaXN0ZXIgY2xhc3MsIHJlZ2lzdGVyIGJhbmsKKyAgLy8vIG9yIHNpemUgYXNzaWduZWQgeWV0LiBUaGlzIGlzIG9ubHkgYWxsb3dlZCB0byBiZSB1c2VkCisgIC8vLyB0ZW1wb3JhcmlseSB3aGlsZSBjb25zdHJ1Y3RpbmcgbWFjaGluZSBpbnN0cnVjdGlvbnMuIE1vc3Qgb3BlcmF0aW9ucyBhcmUKKyAgLy8vIHVuZGVmaW5lZCBvbiBhbiBpbmNvbXBsZXRlIHJlZ2lzdGVyIHVudGlsIG9uZSBvZiBzZXRSZWdDbGFzcygpLAorICAvLy8gc2V0UmVnQmFuaygpIG9yIHNldFNpemUoKSBoYXMgYmVlbiBjYWxsZWQgb24gaXQuCisgIHVuc2lnbmVkIGNyZWF0ZUluY29tcGxldGVWaXJ0dWFsUmVnaXN0ZXIoU3RyaW5nUmVmIE5hbWUgPSAiIik7CisKKyAgLy8vIGdldE51bVZpcnRSZWdzIC0gUmV0dXJuIHRoZSBudW1iZXIgb2YgdmlydHVhbCByZWdpc3RlcnMgY3JlYXRlZC4KKyAgdW5zaWduZWQgZ2V0TnVtVmlydFJlZ3MoKSBjb25zdCB7IHJldHVybiBWUmVnSW5mby5zaXplKCk7IH0KKworICAvLy8gY2xlYXJWaXJ0UmVncyAtIFJlbW92ZSBhbGwgdmlydHVhbCByZWdpc3RlcnMgKGFmdGVyIHBoeXNyZWcgYXNzaWdubWVudCkuCisgIHZvaWQgY2xlYXJWaXJ0UmVncygpOworCisgIC8vLyBzZXRSZWdBbGxvY2F0aW9uSGludCAtIFNwZWNpZnkgYSByZWdpc3RlciBhbGxvY2F0aW9uIGhpbnQgZm9yIHRoZQorICAvLy8gc3BlY2lmaWVkIHZpcnR1YWwgcmVnaXN0ZXIuIFRoaXMgaXMgdHlwaWNhbGx5IHVzZWQgYnkgdGFyZ2V0LCBhbmQgaW4gY2FzZQorICAvLy8gb2YgYW4gZWFybGllciBoaW50IGl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4uCisgIHZvaWQgc2V0UmVnQWxsb2NhdGlvbkhpbnQodW5zaWduZWQgVlJlZywgdW5zaWduZWQgVHlwZSwgdW5zaWduZWQgUHJlZlJlZykgeworICAgIGFzc2VydChUYXJnZXRSZWdpc3RlckluZm86OmlzVmlydHVhbFJlZ2lzdGVyKFZSZWcpKTsKKyAgICBSZWdBbGxvY0hpbnRzW1ZSZWddLmZpcnN0ICA9IFR5cGU7CisgICAgUmVnQWxsb2NIaW50c1tWUmVnXS5zZWNvbmQuY2xlYXIoKTsKKyAgICBSZWdBbGxvY0hpbnRzW1ZSZWddLnNlY29uZC5wdXNoX2JhY2soUHJlZlJlZyk7CisgIH0KKworICAvLy8gYWRkUmVnQWxsb2NhdGlvbkhpbnQgLSBBZGQgYSByZWdpc3RlciBhbGxvY2F0aW9uIGhpbnQgdG8gdGhlIGhpbnRzCisgIC8vLyB2ZWN0b3IgZm9yIFZSZWcuCisgIHZvaWQgYWRkUmVnQWxsb2NhdGlvbkhpbnQodW5zaWduZWQgVlJlZywgdW5zaWduZWQgUHJlZlJlZykgeworICAgIGFzc2VydChUYXJnZXRSZWdpc3RlckluZm86OmlzVmlydHVhbFJlZ2lzdGVyKFZSZWcpKTsKKyAgICBSZWdBbGxvY0hpbnRzW1ZSZWddLnNlY29uZC5wdXNoX2JhY2soUHJlZlJlZyk7CisgIH0KKworICAvLy8gU3BlY2lmeSB0aGUgcHJlZmVycmVkICh0YXJnZXQgaW5kZXBlbmRlbnQpIHJlZ2lzdGVyIGFsbG9jYXRpb24gaGludCBmb3IKKyAgLy8vIHRoZSBzcGVjaWZpZWQgdmlydHVhbCByZWdpc3Rlci4KKyAgdm9pZCBzZXRTaW1wbGVIaW50KHVuc2lnbmVkIFZSZWcsIHVuc2lnbmVkIFByZWZSZWcpIHsKKyAgICBzZXRSZWdBbGxvY2F0aW9uSGludChWUmVnLCAvKlR5cGU9Ki8wLCBQcmVmUmVnKTsKKyAgfQorCisgIHZvaWQgY2xlYXJTaW1wbGVIaW50KHVuc2lnbmVkIFZSZWcpIHsKKyAgICBhc3NlcnQgKFJlZ0FsbG9jSGludHNbVlJlZ10uZmlyc3QgPT0gMCAmJgorICAgICAgICAgICAgIkV4cGVjdGVkIHRvIGNsZWFyIGEgbm9uLXRhcmdldCBoaW50ISIpOworICAgIFJlZ0FsbG9jSGludHNbVlJlZ10uc2Vjb25kLmNsZWFyKCk7CisgIH0KKworICAvLy8gZ2V0UmVnQWxsb2NhdGlvbkhpbnQgLSBSZXR1cm4gdGhlIHJlZ2lzdGVyIGFsbG9jYXRpb24gaGludCBmb3IgdGhlCisgIC8vLyBzcGVjaWZpZWQgdmlydHVhbCByZWdpc3Rlci4gSWYgdGhlcmUgYXJlIG1hbnkgaGludHMsIHRoaXMgcmV0dXJucyB0aGUKKyAgLy8vIG9uZSB3aXRoIHRoZSBncmVhdGVzdCB3ZWlnaHQuCisgIHN0ZDo6cGFpcjx1bnNpZ25lZCwgdW5zaWduZWQ+CisgIGdldFJlZ0FsbG9jYXRpb25IaW50KHVuc2lnbmVkIFZSZWcpIGNvbnN0IHsKKyAgICBhc3NlcnQoVGFyZ2V0UmVnaXN0ZXJJbmZvOjppc1ZpcnR1YWxSZWdpc3RlcihWUmVnKSk7CisgICAgdW5zaWduZWQgQmVzdEhpbnQgPSAoUmVnQWxsb2NIaW50c1tWUmVnXS5zZWNvbmQuc2l6ZSgpID8KKyAgICAgICAgICAgICAgICAgICAgICAgICBSZWdBbGxvY0hpbnRzW1ZSZWddLnNlY29uZFswXSA6IDApOworICAgIHJldHVybiBzdGQ6OnBhaXI8dW5zaWduZWQsIHVuc2lnbmVkPihSZWdBbGxvY0hpbnRzW1ZSZWddLmZpcnN0LCBCZXN0SGludCk7CisgIH0KKworICAvLy8gZ2V0U2ltcGxlSGludCAtIHNhbWUgYXMgZ2V0UmVnQWxsb2NhdGlvbkhpbnQgZXhjZXB0IGl0IHdpbGwgb25seSByZXR1cm4KKyAgLy8vIGEgdGFyZ2V0IGluZGVwZW5kZW50IGhpbnQuCisgIHVuc2lnbmVkIGdldFNpbXBsZUhpbnQodW5zaWduZWQgVlJlZykgY29uc3QgeworICAgIGFzc2VydChUYXJnZXRSZWdpc3RlckluZm86OmlzVmlydHVhbFJlZ2lzdGVyKFZSZWcpKTsKKyAgICBzdGQ6OnBhaXI8dW5zaWduZWQsIHVuc2lnbmVkPiBIaW50ID0gZ2V0UmVnQWxsb2NhdGlvbkhpbnQoVlJlZyk7CisgICAgcmV0dXJuIEhpbnQuZmlyc3QgPyAwIDogSGludC5zZWNvbmQ7CisgIH0KKworICAvLy8gZ2V0UmVnQWxsb2NhdGlvbkhpbnRzIC0gUmV0dXJuIGEgcmVmZXJlbmNlIHRvIHRoZSB2ZWN0b3Igb2YgYWxsCisgIC8vLyByZWdpc3RlciBhbGxvY2F0aW9uIGhpbnRzIGZvciBWUmVnLgorICBjb25zdCBzdGQ6OnBhaXI8dW5zaWduZWQsIFNtYWxsVmVjdG9yPHVuc2lnbmVkLCA0Pj4KKyAgJmdldFJlZ0FsbG9jYXRpb25IaW50cyh1bnNpZ25lZCBWUmVnKSBjb25zdCB7CisgICAgYXNzZXJ0KFRhcmdldFJlZ2lzdGVySW5mbzo6aXNWaXJ0dWFsUmVnaXN0ZXIoVlJlZykpOworICAgIHJldHVybiBSZWdBbGxvY0hpbnRzW1ZSZWddOworICB9CisKKyAgLy8vIG1hcmtVc2VzSW5EZWJ1Z1ZhbHVlQXNVbmRlZiAtIE1hcmsgZXZlcnkgREJHX1ZBTFVFIHJlZmVyZW5jaW5nIHRoZQorICAvLy8gc3BlY2lmaWVkIHJlZ2lzdGVyIGFzIHVuZGVmaW5lZCB3aGljaCBjYXVzZXMgdGhlIERCR19WQUxVRSB0byBiZQorICAvLy8gZGVsZXRlZCBkdXJpbmcgTGl2ZURlYnVnVmFyaWFibGVzIGFuYWx5c2lzLgorICB2b2lkIG1hcmtVc2VzSW5EZWJ1Z1ZhbHVlQXNVbmRlZih1bnNpZ25lZCBSZWcpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyIGlzIG1vZGlmaWVkIGluIHRoaXMgZnVuY3Rpb24uCisgIC8vLyBUaGlzIGNoZWNrcyB0aGF0IG5vIGRlZmluaW5nIG1hY2hpbmUgb3BlcmFuZHMgZXhpc3QgZm9yIHRoZSByZWdpc3RlciBvcgorICAvLy8gYW55IG9mIGl0cyBhbGlhc2VzLiBEZWZpbml0aW9ucyBmb3VuZCBvbiBmdW5jdGlvbnMgbWFya2VkIG5vcmV0dXJuIGFyZQorICAvLy8gaWdub3JlZCwgdG8gY29uc2lkZXIgdGhlbSBwYXNzICd0cnVlJyBmb3Igb3B0aW9uYWwgcGFyYW1ldGVyCisgIC8vLyBTa2lwTm9SZXR1cm5EZWYuIFRoZSByZWdpc3RlciBpcyBhbHNvIGNvbnNpZGVyZWQgbW9kaWZpZWQgd2hlbiBpdCBpcyBzZXQKKyAgLy8vIGluIHRoZSBVc2VkUGh5c1JlZ01hc2suCisgIGJvb2wgaXNQaHlzUmVnTW9kaWZpZWQodW5zaWduZWQgUGh5c1JlZywgYm9vbCBTa2lwTm9SZXR1cm5EZWYgPSBmYWxzZSkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIgaXMgbW9kaWZpZWQgb3IgcmVhZCBpbiB0aGlzCisgIC8vLyBmdW5jdGlvbi4gVGhpcyBjaGVja3MgdGhhdCBubyBtYWNoaW5lIG9wZXJhbmRzIGV4aXN0IGZvciB0aGUgcmVnaXN0ZXIgb3IKKyAgLy8vIGFueSBvZiBpdHMgYWxpYXNlcy4gVGhlIHJlZ2lzdGVyIGlzIGFsc28gY29uc2lkZXJlZCB1c2VkIHdoZW4gaXQgaXMgc2V0CisgIC8vLyBpbiB0aGUgVXNlZFBoeXNSZWdNYXNrLgorICBib29sIGlzUGh5c1JlZ1VzZWQodW5zaWduZWQgUGh5c1JlZykgY29uc3Q7CisKKyAgLy8vIGFkZFBoeXNSZWdzVXNlZEZyb21SZWdNYXNrIC0gTWFyayBhbnkgcmVnaXN0ZXJzIG5vdCBpbiBSZWdNYXNrIGFzIHVzZWQuCisgIC8vLyBUaGlzIGNvcnJlc3BvbmRzIHRvIHRoZSBiaXQgbWFzayBhdHRhY2hlZCB0byByZWdpc3RlciBtYXNrIG9wZXJhbmRzLgorICB2b2lkIGFkZFBoeXNSZWdzVXNlZEZyb21SZWdNYXNrKGNvbnN0IHVpbnQzMl90ICpSZWdNYXNrKSB7CisgICAgVXNlZFBoeXNSZWdNYXNrLnNldEJpdHNOb3RJbk1hc2soUmVnTWFzayk7CisgIH0KKworICBjb25zdCBCaXRWZWN0b3IgJmdldFVzZWRQaHlzUmVnc01hc2soKSBjb25zdCB7IHJldHVybiBVc2VkUGh5c1JlZ01hc2s7IH0KKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gUmVzZXJ2ZWQgUmVnaXN0ZXIgSW5mbworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8KKyAgLy8gVGhlIHNldCBvZiByZXNlcnZlZCByZWdpc3RlcnMgbXVzdCBiZSBpbnZhcmlhbnQgZHVyaW5nIHJlZ2lzdGVyCisgIC8vIGFsbG9jYXRpb24uICBGb3IgZXhhbXBsZSwgdGhlIHRhcmdldCBjYW5ub3Qgc3VkZGVubHkgZGVjaWRlIGl0IG5lZWRzIGEKKyAgLy8gZnJhbWUgcG9pbnRlciB3aGVuIHRoZSByZWdpc3RlciBhbGxvY2F0b3IgaGFzIGFscmVhZHkgdXNlZCB0aGUgZnJhbWUKKyAgLy8gcG9pbnRlciByZWdpc3RlciBmb3Igc29tZXRoaW5nIGVsc2UuCisgIC8vCisgIC8vIFRoZXNlIG1ldGhvZHMgY2FuIGJlIHVzZWQgYnkgdGFyZ2V0IGhvb2tzIGxpa2UgaGFzRlAoKSB0byBhdm9pZCBjaGFuZ2luZworICAvLyB0aGUgcmVzZXJ2ZWQgcmVnaXN0ZXIgc2V0IGR1cmluZyByZWdpc3RlciBhbGxvY2F0aW9uLgorCisgIC8vLyBmcmVlemVSZXNlcnZlZFJlZ3MgLSBDYWxsZWQgYnkgdGhlIHJlZ2lzdGVyIGFsbG9jYXRvciB0byBmcmVlemUgdGhlIHNldAorICAvLy8gb2YgcmVzZXJ2ZWQgcmVnaXN0ZXJzIGJlZm9yZSBhbGxvY2F0aW9uIGJlZ2lucy4KKyAgdm9pZCBmcmVlemVSZXNlcnZlZFJlZ3MoY29uc3QgTWFjaGluZUZ1bmN0aW9uJik7CisKKyAgLy8vIHJlc2VydmVkUmVnc0Zyb3plbiAtIFJldHVybnMgdHJ1ZSBhZnRlciBmcmVlemVSZXNlcnZlZFJlZ3MoKSB3YXMgY2FsbGVkCisgIC8vLyB0byBlbnN1cmUgdGhlIHNldCBvZiByZXNlcnZlZCByZWdpc3RlcnMgc3RheXMgY29uc3RhbnQuCisgIGJvb2wgcmVzZXJ2ZWRSZWdzRnJvemVuKCkgY29uc3QgeworICAgIHJldHVybiAhUmVzZXJ2ZWRSZWdzLmVtcHR5KCk7CisgIH0KKworICAvLy8gY2FuUmVzZXJ2ZVJlZyAtIFJldHVybnMgdHJ1ZSBpZiBQaHlzUmVnIGNhbiBiZSB1c2VkIGFzIGEgcmVzZXJ2ZWQKKyAgLy8vIHJlZ2lzdGVyLiAgQW55IHJlZ2lzdGVyIGNhbiBiZSByZXNlcnZlZCBiZWZvcmUgZnJlZXplUmVzZXJ2ZWRSZWdzKCkgaXMKKyAgLy8vIGNhbGxlZC4KKyAgYm9vbCBjYW5SZXNlcnZlUmVnKHVuc2lnbmVkIFBoeXNSZWcpIGNvbnN0IHsKKyAgICByZXR1cm4gIXJlc2VydmVkUmVnc0Zyb3plbigpIHx8IFJlc2VydmVkUmVncy50ZXN0KFBoeXNSZWcpOworICB9CisKKyAgLy8vIGdldFJlc2VydmVkUmVncyAtIFJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIGZyb3plbiBzZXQgb2YgcmVzZXJ2ZWQKKyAgLy8vIHJlZ2lzdGVycy4gVGhpcyBtZXRob2Qgc2hvdWxkIGFsd2F5cyBiZSBwcmVmZXJyZWQgdG8gY2FsbGluZworICAvLy8gVFJJOjpnZXRSZXNlcnZlZFJlZ3MoKSB3aGVuIHBvc3NpYmxlLgorICBjb25zdCBCaXRWZWN0b3IgJmdldFJlc2VydmVkUmVncygpIGNvbnN0IHsKKyAgICBhc3NlcnQocmVzZXJ2ZWRSZWdzRnJvemVuKCkgJiYKKyAgICAgICAgICAgIlJlc2VydmVkIHJlZ2lzdGVycyBoYXZlbid0IGJlZW4gZnJvemVuIHlldC4gIgorICAgICAgICAgICAiVXNlIFRSSTo6Z2V0UmVzZXJ2ZWRSZWdzKCkuIik7CisgICAgcmV0dXJuIFJlc2VydmVkUmVnczsKKyAgfQorCisgIC8vLyBpc1Jlc2VydmVkIC0gUmV0dXJucyB0cnVlIHdoZW4gUGh5c1JlZyBpcyBhIHJlc2VydmVkIHJlZ2lzdGVyLgorICAvLy8KKyAgLy8vIFJlc2VydmVkIHJlZ2lzdGVycyBtYXkgYmVsb25nIHRvIGFuIGFsbG9jYXRhYmxlIHJlZ2lzdGVyIGNsYXNzLCBidXQgdGhlCisgIC8vLyB0YXJnZXQgaGFzIGV4cGxpY2l0bHkgcmVxdWVzdGVkIHRoYXQgdGhleSBhcmUgbm90IHVzZWQuCisgIGJvb2wgaXNSZXNlcnZlZCh1bnNpZ25lZCBQaHlzUmVnKSBjb25zdCB7CisgICAgcmV0dXJuIGdldFJlc2VydmVkUmVncygpLnRlc3QoUGh5c1JlZyk7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIHdoZW4gdGhlIGdpdmVuIHJlZ2lzdGVyIHVuaXQgaXMgY29uc2lkZXJlZCByZXNlcnZlZC4KKyAgLy8vCisgIC8vLyBSZWdpc3RlciB1bml0cyBhcmUgY29uc2lkZXJlZCByZXNlcnZlZCB3aGVuIGZvciBhdCBsZWFzdCBvbmUgb2YgdGhlaXIKKyAgLy8vIHJvb3QgcmVnaXN0ZXJzLCB0aGUgcm9vdCByZWdpc3RlciBhbmQgYWxsIHN1cGVyIHJlZ2lzdGVycyBhcmUgcmVzZXJ2ZWQuCisgIC8vLyBUaGlzIGN1cnJlbnRseSBpdGVyYXRlcyB0aGUgcmVnaXN0ZXIgaGllcmFyY2h5IGFuZCBtYXkgYmUgc2xvd2VyIHRoYW4KKyAgLy8vIGV4cGVjdGVkLgorICBib29sIGlzUmVzZXJ2ZWRSZWdVbml0KHVuc2lnbmVkIFVuaXQpIGNvbnN0OworCisgIC8vLyBpc0FsbG9jYXRhYmxlIC0gUmV0dXJucyB0cnVlIHdoZW4gUGh5c1JlZyBiZWxvbmdzIHRvIGFuIGFsbG9jYXRhYmxlCisgIC8vLyByZWdpc3RlciBjbGFzcyBhbmQgaXQgaGFzbid0IGJlZW4gcmVzZXJ2ZWQuCisgIC8vLworICAvLy8gQWxsb2NhdGFibGUgcmVnaXN0ZXJzIG1heSBzaG93IHVwIGluIHRoZSBhbGxvY2F0aW9uIG9yZGVyIG9mIHNvbWUgdmlydHVhbAorICAvLy8gcmVnaXN0ZXIsIHNvIGEgcmVnaXN0ZXIgYWxsb2NhdG9yIG5lZWRzIHRvIHRyYWNrIGl0cyBsaXZlbmVzcyBhbmQKKyAgLy8vIGF2YWlsYWJpbGl0eS4KKyAgYm9vbCBpc0FsbG9jYXRhYmxlKHVuc2lnbmVkIFBoeXNSZWcpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0VGFyZ2V0UmVnaXN0ZXJJbmZvKCktPmlzSW5BbGxvY2F0YWJsZUNsYXNzKFBoeXNSZWcpICYmCisgICAgICAhaXNSZXNlcnZlZChQaHlzUmVnKTsKKyAgfQorCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLyBMaXZlSW4gTWFuYWdlbWVudAorICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworICAvLy8gYWRkTGl2ZUluIC0gQWRkIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIgYXMgYSBsaXZlLWluLiAgTm90ZSB0aGF0IGl0CisgIC8vLyBpcyBhbiBlcnJvciB0byBhZGQgdGhlIHNhbWUgcmVnaXN0ZXIgdG8gdGhlIHNhbWUgc2V0IG1vcmUgdGhhbiBvbmNlLgorICB2b2lkIGFkZExpdmVJbih1bnNpZ25lZCBSZWcsIHVuc2lnbmVkIHZyZWcgPSAwKSB7CisgICAgTGl2ZUlucy5wdXNoX2JhY2soc3RkOjptYWtlX3BhaXIoUmVnLCB2cmVnKSk7CisgIH0KKworICAvLyBJdGVyYXRpb24gc3VwcG9ydCBmb3IgdGhlIGxpdmUtaW5zIHNldC4gIEl0J3Mga2VwdCBpbiBzb3J0ZWQgb3JkZXIKKyAgLy8gYnkgcmVnaXN0ZXIgbnVtYmVyLgorICB1c2luZyBsaXZlaW5faXRlcmF0b3IgPQorICAgICAgc3RkOjp2ZWN0b3I8c3RkOjpwYWlyPHVuc2lnbmVkLHVuc2lnbmVkPj46OmNvbnN0X2l0ZXJhdG9yOworICBsaXZlaW5faXRlcmF0b3IgbGl2ZWluX2JlZ2luKCkgY29uc3QgeyByZXR1cm4gTGl2ZUlucy5iZWdpbigpOyB9CisgIGxpdmVpbl9pdGVyYXRvciBsaXZlaW5fZW5kKCkgICBjb25zdCB7IHJldHVybiBMaXZlSW5zLmVuZCgpOyB9CisgIGJvb2wgICAgICAgICAgICBsaXZlaW5fZW1wdHkoKSBjb25zdCB7IHJldHVybiBMaXZlSW5zLmVtcHR5KCk7IH0KKworICBBcnJheVJlZjxzdGQ6OnBhaXI8dW5zaWduZWQsIHVuc2lnbmVkPj4gbGl2ZWlucygpIGNvbnN0IHsKKyAgICByZXR1cm4gTGl2ZUluczsKKyAgfQorCisgIGJvb2wgaXNMaXZlSW4odW5zaWduZWQgUmVnKSBjb25zdDsKKworICAvLy8gZ2V0TGl2ZUluUGh5c1JlZyAtIElmIFZSZWcgaXMgYSBsaXZlLWluIHZpcnR1YWwgcmVnaXN0ZXIsIHJldHVybiB0aGUKKyAgLy8vIGNvcnJlc3BvbmRpbmcgbGl2ZS1pbiBwaHlzaWNhbCByZWdpc3Rlci4KKyAgdW5zaWduZWQgZ2V0TGl2ZUluUGh5c1JlZyh1bnNpZ25lZCBWUmVnKSBjb25zdDsKKworICAvLy8gZ2V0TGl2ZUluVmlydFJlZyAtIElmIFBSZWcgaXMgYSBsaXZlLWluIHBoeXNpY2FsIHJlZ2lzdGVyLCByZXR1cm4gdGhlCisgIC8vLyBjb3JyZXNwb25kaW5nIGxpdmUtaW4gcGh5c2ljYWwgcmVnaXN0ZXIuCisgIHVuc2lnbmVkIGdldExpdmVJblZpcnRSZWcodW5zaWduZWQgUFJlZykgY29uc3Q7CisKKyAgLy8vIEVtaXRMaXZlSW5Db3BpZXMgLSBFbWl0IGNvcGllcyB0byBpbml0aWFsaXplIGxpdmVpbiB2aXJ0dWFsIHJlZ2lzdGVycworICAvLy8gaW50byB0aGUgZ2l2ZW4gZW50cnkgYmxvY2suCisgIHZvaWQgRW1pdExpdmVJbkNvcGllcyhNYWNoaW5lQmFzaWNCbG9jayAqRW50cnlNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gJlRSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldEluc3RySW5mbyAmVElJKTsKKworICAvLy8gUmV0dXJucyBhIG1hc2sgY292ZXJpbmcgYWxsIGJpdHMgdGhhdCBjYW4gYXBwZWFyIGluIGxhbmUgbWFza3Mgb2YKKyAgLy8vIHN1YnJlZ2lzdGVycyBvZiB0aGUgdmlydHVhbCByZWdpc3RlciBAcCBSZWcuCisgIExhbmVCaXRtYXNrIGdldE1heExhbmVNYXNrRm9yVlJlZyh1bnNpZ25lZCBSZWcpIGNvbnN0OworCisgIC8vLyBkZWZ1c2VjaGFpbl9pdGVyYXRvciAtIFRoaXMgY2xhc3MgcHJvdmlkZXMgaXRlcmF0b3Igc3VwcG9ydCBmb3IgbWFjaGluZQorICAvLy8gb3BlcmFuZHMgaW4gdGhlIGZ1bmN0aW9uIHRoYXQgdXNlIG9yIGRlZmluZSBhIHNwZWNpZmljIHJlZ2lzdGVyLiAgSWYKKyAgLy8vIFJldHVyblVzZXMgaXMgdHJ1ZSBpdCByZXR1cm5zIHVzZXMgb2YgcmVnaXN0ZXJzLCBpZiBSZXR1cm5EZWZzIGlzIHRydWUgaXQKKyAgLy8vIHJldHVybnMgZGVmcy4gIElmIG5laXRoZXIgYXJlIHRydWUgdGhlbiB5b3UgYXJlIHNpbGx5IGFuZCBpdCBhbHdheXMKKyAgLy8vIHJldHVybnMgZW5kKCkuICBJZiBTa2lwRGVidWcgaXMgdHJ1ZSBpdCBza2lwcyB1c2VzIG1hcmtlZCBEZWJ1ZworICAvLy8gd2hlbiBpbmNyZW1lbnRpbmcuCisgIHRlbXBsYXRlPGJvb2wgUmV0dXJuVXNlcywgYm9vbCBSZXR1cm5EZWZzLCBib29sIFNraXBEZWJ1ZywKKyAgICAgICAgICAgYm9vbCBCeU9wZXJhbmQsIGJvb2wgQnlJbnN0ciwgYm9vbCBCeUJ1bmRsZT4KKyAgY2xhc3MgZGVmdXNlY2hhaW5faXRlcmF0b3IKKyAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsIE1hY2hpbmVJbnN0ciwgcHRyZGlmZl90PiB7CisgICAgZnJpZW5kIGNsYXNzIE1hY2hpbmVSZWdpc3RlckluZm87CisKKyAgICBNYWNoaW5lT3BlcmFuZCAqT3AgPSBudWxscHRyOworCisgICAgZXhwbGljaXQgZGVmdXNlY2hhaW5faXRlcmF0b3IoTWFjaGluZU9wZXJhbmQgKm9wKSA6IE9wKG9wKSB7CisgICAgICAvLyBJZiB0aGUgZmlyc3Qgbm9kZSBpc24ndCBvbmUgd2UncmUgaW50ZXJlc3RlZCBpbiwgYWR2YW5jZSB0byBvbmUgdGhhdAorICAgICAgLy8gd2UgYXJlIGludGVyZXN0ZWQgaW4uCisgICAgICBpZiAob3ApIHsKKyAgICAgICAgaWYgKCghUmV0dXJuVXNlcyAmJiBvcC0+aXNVc2UoKSkgfHwKKyAgICAgICAgICAgICghUmV0dXJuRGVmcyAmJiBvcC0+aXNEZWYoKSkgfHwKKyAgICAgICAgICAgIChTa2lwRGVidWcgJiYgb3AtPmlzRGVidWcoKSkpCisgICAgICAgICAgYWR2YW5jZSgpOworICAgICAgfQorICAgIH0KKworICAgIHZvaWQgYWR2YW5jZSgpIHsKKyAgICAgIGFzc2VydChPcCAmJiAiQ2Fubm90IGluY3JlbWVudCBlbmQgaXRlcmF0b3IhIik7CisgICAgICBPcCA9IGdldE5leHRPcGVyYW5kRm9yUmVnKE9wKTsKKworICAgICAgLy8gQWxsIGRlZnMgY29tZSBiZWZvcmUgdGhlIHVzZXMsIHNvIHN0b3AgZGVmX2l0ZXJhdG9yIGVhcmx5LgorICAgICAgaWYgKCFSZXR1cm5Vc2VzKSB7CisgICAgICAgIGlmIChPcCkgeworICAgICAgICAgIGlmIChPcC0+aXNVc2UoKSkKKyAgICAgICAgICAgIE9wID0gbnVsbHB0cjsKKyAgICAgICAgICBlbHNlCisgICAgICAgICAgICBhc3NlcnQoIU9wLT5pc0RlYnVnKCkgJiYgIkNhbid0IGhhdmUgZGVidWcgZGVmcyIpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBJZiB0aGlzIGlzIGFuIG9wZXJhbmQgd2UgZG9uJ3QgY2FyZSBhYm91dCwgc2tpcCBpdC4KKyAgICAgICAgd2hpbGUgKE9wICYmICgoIVJldHVybkRlZnMgJiYgT3AtPmlzRGVmKCkpIHx8CisgICAgICAgICAgICAgICAgICAgICAgKFNraXBEZWJ1ZyAmJiBPcC0+aXNEZWJ1ZygpKSkpCisgICAgICAgICAgT3AgPSBnZXROZXh0T3BlcmFuZEZvclJlZyhPcCk7CisgICAgICB9CisgICAgfQorCisgIHB1YmxpYzoKKyAgICB1c2luZyByZWZlcmVuY2UgPSBzdGQ6Oml0ZXJhdG9yPHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSW5zdHIsIHB0cmRpZmZfdD46OnJlZmVyZW5jZTsKKyAgICB1c2luZyBwb2ludGVyID0gc3RkOjppdGVyYXRvcjxzdGQ6OmZvcndhcmRfaXRlcmF0b3JfdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVJbnN0ciwgcHRyZGlmZl90Pjo6cG9pbnRlcjsKKworICAgIGRlZnVzZWNoYWluX2l0ZXJhdG9yKCkgPSBkZWZhdWx0OworCisgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IGRlZnVzZWNoYWluX2l0ZXJhdG9yICZ4KSBjb25zdCB7CisgICAgICByZXR1cm4gT3AgPT0geC5PcDsKKyAgICB9CisgICAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IGRlZnVzZWNoYWluX2l0ZXJhdG9yICZ4KSBjb25zdCB7CisgICAgICByZXR1cm4gIW9wZXJhdG9yPT0oeCk7CisgICAgfQorCisgICAgLy8vIGF0RW5kIC0gcmV0dXJuIHRydWUgaWYgdGhpcyBpdGVyYXRvciBpcyBlcXVhbCB0byByZWdfZW5kKCkgb24gdGhlIHZhbHVlLgorICAgIGJvb2wgYXRFbmQoKSBjb25zdCB7IHJldHVybiBPcCA9PSBudWxscHRyOyB9CisKKyAgICAvLyBJdGVyYXRvciB0cmF2ZXJzYWw6IGZvcndhcmQgaXRlcmF0aW9uIG9ubHkKKyAgICBkZWZ1c2VjaGFpbl9pdGVyYXRvciAmb3BlcmF0b3IrKygpIHsgICAgICAgICAgLy8gUHJlaW5jcmVtZW50CisgICAgICBhc3NlcnQoT3AgJiYgIkNhbm5vdCBpbmNyZW1lbnQgZW5kIGl0ZXJhdG9yISIpOworICAgICAgaWYgKEJ5T3BlcmFuZCkKKyAgICAgICAgYWR2YW5jZSgpOworICAgICAgZWxzZSBpZiAoQnlJbnN0cikgeworICAgICAgICBNYWNoaW5lSW5zdHIgKlAgPSBPcC0+Z2V0UGFyZW50KCk7CisgICAgICAgIGRvIHsKKyAgICAgICAgICBhZHZhbmNlKCk7CisgICAgICAgIH0gd2hpbGUgKE9wICYmIE9wLT5nZXRQYXJlbnQoKSA9PSBQKTsKKyAgICAgIH0gZWxzZSBpZiAoQnlCdW5kbGUpIHsKKyAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Omluc3RyX2l0ZXJhdG9yIFAgPQorICAgICAgICAgICAgZ2V0QnVuZGxlU3RhcnQoT3AtPmdldFBhcmVudCgpLT5nZXRJdGVyYXRvcigpKTsKKyAgICAgICAgZG8geworICAgICAgICAgIGFkdmFuY2UoKTsKKyAgICAgICAgfSB3aGlsZSAoT3AgJiYgZ2V0QnVuZGxlU3RhcnQoT3AtPmdldFBhcmVudCgpLT5nZXRJdGVyYXRvcigpKSA9PSBQKTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KKyAgICBkZWZ1c2VjaGFpbl9pdGVyYXRvciBvcGVyYXRvcisrKGludCkgeyAgICAgICAgLy8gUG9zdGluY3JlbWVudAorICAgICAgZGVmdXNlY2hhaW5faXRlcmF0b3IgdG1wID0gKnRoaXM7ICsrKnRoaXM7IHJldHVybiB0bXA7CisgICAgfQorCisgICAgLy8vIGdldE9wZXJhbmRObyAtIFJldHVybiB0aGUgb3BlcmFuZCAjIG9mIHRoaXMgTWFjaGluZU9wZXJhbmQgaW4gaXRzCisgICAgLy8vIE1hY2hpbmVJbnN0ci4KKyAgICB1bnNpZ25lZCBnZXRPcGVyYW5kTm8oKSBjb25zdCB7CisgICAgICBhc3NlcnQoT3AgJiYgIkNhbm5vdCBkZXJlZmVyZW5jZSBlbmQgaXRlcmF0b3IhIik7CisgICAgICByZXR1cm4gT3AgLSAmT3AtPmdldFBhcmVudCgpLT5nZXRPcGVyYW5kKDApOworICAgIH0KKworICAgIC8vIFJldHJpZXZlIGEgcmVmZXJlbmNlIHRvIHRoZSBjdXJyZW50IG9wZXJhbmQuCisgICAgTWFjaGluZU9wZXJhbmQgJm9wZXJhdG9yKigpIGNvbnN0IHsKKyAgICAgIGFzc2VydChPcCAmJiAiQ2Fubm90IGRlcmVmZXJlbmNlIGVuZCBpdGVyYXRvciEiKTsKKyAgICAgIHJldHVybiAqT3A7CisgICAgfQorCisgICAgTWFjaGluZU9wZXJhbmQgKm9wZXJhdG9yLT4oKSBjb25zdCB7CisgICAgICBhc3NlcnQoT3AgJiYgIkNhbm5vdCBkZXJlZmVyZW5jZSBlbmQgaXRlcmF0b3IhIik7CisgICAgICByZXR1cm4gT3A7CisgICAgfQorICB9OworCisgIC8vLyBkZWZ1c2VjaGFpbl9pdGVyYXRvciAtIFRoaXMgY2xhc3MgcHJvdmlkZXMgaXRlcmF0b3Igc3VwcG9ydCBmb3IgbWFjaGluZQorICAvLy8gb3BlcmFuZHMgaW4gdGhlIGZ1bmN0aW9uIHRoYXQgdXNlIG9yIGRlZmluZSBhIHNwZWNpZmljIHJlZ2lzdGVyLiAgSWYKKyAgLy8vIFJldHVyblVzZXMgaXMgdHJ1ZSBpdCByZXR1cm5zIHVzZXMgb2YgcmVnaXN0ZXJzLCBpZiBSZXR1cm5EZWZzIGlzIHRydWUgaXQKKyAgLy8vIHJldHVybnMgZGVmcy4gIElmIG5laXRoZXIgYXJlIHRydWUgdGhlbiB5b3UgYXJlIHNpbGx5IGFuZCBpdCBhbHdheXMKKyAgLy8vIHJldHVybnMgZW5kKCkuICBJZiBTa2lwRGVidWcgaXMgdHJ1ZSBpdCBza2lwcyB1c2VzIG1hcmtlZCBEZWJ1ZworICAvLy8gd2hlbiBpbmNyZW1lbnRpbmcuCisgIHRlbXBsYXRlPGJvb2wgUmV0dXJuVXNlcywgYm9vbCBSZXR1cm5EZWZzLCBib29sIFNraXBEZWJ1ZywKKyAgICAgICAgICAgYm9vbCBCeU9wZXJhbmQsIGJvb2wgQnlJbnN0ciwgYm9vbCBCeUJ1bmRsZT4KKyAgY2xhc3MgZGVmdXNlY2hhaW5faW5zdHJfaXRlcmF0b3IKKyAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsIE1hY2hpbmVJbnN0ciwgcHRyZGlmZl90PiB7CisgICAgZnJpZW5kIGNsYXNzIE1hY2hpbmVSZWdpc3RlckluZm87CisKKyAgICBNYWNoaW5lT3BlcmFuZCAqT3AgPSBudWxscHRyOworCisgICAgZXhwbGljaXQgZGVmdXNlY2hhaW5faW5zdHJfaXRlcmF0b3IoTWFjaGluZU9wZXJhbmQgKm9wKSA6IE9wKG9wKSB7CisgICAgICAvLyBJZiB0aGUgZmlyc3Qgbm9kZSBpc24ndCBvbmUgd2UncmUgaW50ZXJlc3RlZCBpbiwgYWR2YW5jZSB0byBvbmUgdGhhdAorICAgICAgLy8gd2UgYXJlIGludGVyZXN0ZWQgaW4uCisgICAgICBpZiAob3ApIHsKKyAgICAgICAgaWYgKCghUmV0dXJuVXNlcyAmJiBvcC0+aXNVc2UoKSkgfHwKKyAgICAgICAgICAgICghUmV0dXJuRGVmcyAmJiBvcC0+aXNEZWYoKSkgfHwKKyAgICAgICAgICAgIChTa2lwRGVidWcgJiYgb3AtPmlzRGVidWcoKSkpCisgICAgICAgICAgYWR2YW5jZSgpOworICAgICAgfQorICAgIH0KKworICAgIHZvaWQgYWR2YW5jZSgpIHsKKyAgICAgIGFzc2VydChPcCAmJiAiQ2Fubm90IGluY3JlbWVudCBlbmQgaXRlcmF0b3IhIik7CisgICAgICBPcCA9IGdldE5leHRPcGVyYW5kRm9yUmVnKE9wKTsKKworICAgICAgLy8gQWxsIGRlZnMgY29tZSBiZWZvcmUgdGhlIHVzZXMsIHNvIHN0b3AgZGVmX2l0ZXJhdG9yIGVhcmx5LgorICAgICAgaWYgKCFSZXR1cm5Vc2VzKSB7CisgICAgICAgIGlmIChPcCkgeworICAgICAgICAgIGlmIChPcC0+aXNVc2UoKSkKKyAgICAgICAgICAgIE9wID0gbnVsbHB0cjsKKyAgICAgICAgICBlbHNlCisgICAgICAgICAgICBhc3NlcnQoIU9wLT5pc0RlYnVnKCkgJiYgIkNhbid0IGhhdmUgZGVidWcgZGVmcyIpOworICAgICAgICB9CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBJZiB0aGlzIGlzIGFuIG9wZXJhbmQgd2UgZG9uJ3QgY2FyZSBhYm91dCwgc2tpcCBpdC4KKyAgICAgICAgd2hpbGUgKE9wICYmICgoIVJldHVybkRlZnMgJiYgT3AtPmlzRGVmKCkpIHx8CisgICAgICAgICAgICAgICAgICAgICAgKFNraXBEZWJ1ZyAmJiBPcC0+aXNEZWJ1ZygpKSkpCisgICAgICAgICAgT3AgPSBnZXROZXh0T3BlcmFuZEZvclJlZyhPcCk7CisgICAgICB9CisgICAgfQorCisgIHB1YmxpYzoKKyAgICB1c2luZyByZWZlcmVuY2UgPSBzdGQ6Oml0ZXJhdG9yPHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSW5zdHIsIHB0cmRpZmZfdD46OnJlZmVyZW5jZTsKKyAgICB1c2luZyBwb2ludGVyID0gc3RkOjppdGVyYXRvcjxzdGQ6OmZvcndhcmRfaXRlcmF0b3JfdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVJbnN0ciwgcHRyZGlmZl90Pjo6cG9pbnRlcjsKKworICAgIGRlZnVzZWNoYWluX2luc3RyX2l0ZXJhdG9yKCkgPSBkZWZhdWx0OworCisgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IGRlZnVzZWNoYWluX2luc3RyX2l0ZXJhdG9yICZ4KSBjb25zdCB7CisgICAgICByZXR1cm4gT3AgPT0geC5PcDsKKyAgICB9CisgICAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IGRlZnVzZWNoYWluX2luc3RyX2l0ZXJhdG9yICZ4KSBjb25zdCB7CisgICAgICByZXR1cm4gIW9wZXJhdG9yPT0oeCk7CisgICAgfQorCisgICAgLy8vIGF0RW5kIC0gcmV0dXJuIHRydWUgaWYgdGhpcyBpdGVyYXRvciBpcyBlcXVhbCB0byByZWdfZW5kKCkgb24gdGhlIHZhbHVlLgorICAgIGJvb2wgYXRFbmQoKSBjb25zdCB7IHJldHVybiBPcCA9PSBudWxscHRyOyB9CisKKyAgICAvLyBJdGVyYXRvciB0cmF2ZXJzYWw6IGZvcndhcmQgaXRlcmF0aW9uIG9ubHkKKyAgICBkZWZ1c2VjaGFpbl9pbnN0cl9pdGVyYXRvciAmb3BlcmF0b3IrKygpIHsgICAgICAgICAgLy8gUHJlaW5jcmVtZW50CisgICAgICBhc3NlcnQoT3AgJiYgIkNhbm5vdCBpbmNyZW1lbnQgZW5kIGl0ZXJhdG9yISIpOworICAgICAgaWYgKEJ5T3BlcmFuZCkKKyAgICAgICAgYWR2YW5jZSgpOworICAgICAgZWxzZSBpZiAoQnlJbnN0cikgeworICAgICAgICBNYWNoaW5lSW5zdHIgKlAgPSBPcC0+Z2V0UGFyZW50KCk7CisgICAgICAgIGRvIHsKKyAgICAgICAgICBhZHZhbmNlKCk7CisgICAgICAgIH0gd2hpbGUgKE9wICYmIE9wLT5nZXRQYXJlbnQoKSA9PSBQKTsKKyAgICAgIH0gZWxzZSBpZiAoQnlCdW5kbGUpIHsKKyAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Omluc3RyX2l0ZXJhdG9yIFAgPQorICAgICAgICAgICAgZ2V0QnVuZGxlU3RhcnQoT3AtPmdldFBhcmVudCgpLT5nZXRJdGVyYXRvcigpKTsKKyAgICAgICAgZG8geworICAgICAgICAgIGFkdmFuY2UoKTsKKyAgICAgICAgfSB3aGlsZSAoT3AgJiYgZ2V0QnVuZGxlU3RhcnQoT3AtPmdldFBhcmVudCgpLT5nZXRJdGVyYXRvcigpKSA9PSBQKTsKKyAgICAgIH0KKworICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KKyAgICBkZWZ1c2VjaGFpbl9pbnN0cl9pdGVyYXRvciBvcGVyYXRvcisrKGludCkgeyAgICAgICAgLy8gUG9zdGluY3JlbWVudAorICAgICAgZGVmdXNlY2hhaW5faW5zdHJfaXRlcmF0b3IgdG1wID0gKnRoaXM7ICsrKnRoaXM7IHJldHVybiB0bXA7CisgICAgfQorCisgICAgLy8gUmV0cmlldmUgYSByZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnQgb3BlcmFuZC4KKyAgICBNYWNoaW5lSW5zdHIgJm9wZXJhdG9yKigpIGNvbnN0IHsKKyAgICAgIGFzc2VydChPcCAmJiAiQ2Fubm90IGRlcmVmZXJlbmNlIGVuZCBpdGVyYXRvciEiKTsKKyAgICAgIGlmIChCeUJ1bmRsZSkKKyAgICAgICAgcmV0dXJuICpnZXRCdW5kbGVTdGFydChPcC0+Z2V0UGFyZW50KCktPmdldEl0ZXJhdG9yKCkpOworICAgICAgcmV0dXJuICpPcC0+Z2V0UGFyZW50KCk7CisgICAgfQorCisgICAgTWFjaGluZUluc3RyICpvcGVyYXRvci0+KCkgY29uc3QgeyByZXR1cm4gJm9wZXJhdG9yKigpOyB9CisgIH07Cit9OworCisvLy8gSXRlcmF0ZSBvdmVyIHRoZSBwcmVzc3VyZSBzZXRzIGFmZmVjdGVkIGJ5IHRoZSBnaXZlbiBwaHlzaWNhbCBvciB2aXJ0dWFsCisvLy8gcmVnaXN0ZXIuIElmIFJlZyBpcyBwaHlzaWNhbCwgaXQgbXVzdCBiZSBhIHJlZ2lzdGVyIHVuaXQgKGZyb20KKy8vLyBNQ1JlZ1VuaXRJdGVyYXRvcikuCitjbGFzcyBQU2V0SXRlcmF0b3IgeworICBjb25zdCBpbnQgKlBTZXQgPSBudWxscHRyOworICB1bnNpZ25lZCBXZWlnaHQgPSAwOworCitwdWJsaWM6CisgIFBTZXRJdGVyYXRvcigpID0gZGVmYXVsdDsKKworICBQU2V0SXRlcmF0b3IodW5zaWduZWQgUmVnVW5pdCwgY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAqTVJJKSB7CisgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkgPSBNUkktPmdldFRhcmdldFJlZ2lzdGVySW5mbygpOworICAgIGlmIChUYXJnZXRSZWdpc3RlckluZm86OmlzVmlydHVhbFJlZ2lzdGVyKFJlZ1VuaXQpKSB7CisgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQyA9IE1SSS0+Z2V0UmVnQ2xhc3MoUmVnVW5pdCk7CisgICAgICBQU2V0ID0gVFJJLT5nZXRSZWdDbGFzc1ByZXNzdXJlU2V0cyhSQyk7CisgICAgICBXZWlnaHQgPSBUUkktPmdldFJlZ0NsYXNzV2VpZ2h0KFJDKS5SZWdXZWlnaHQ7CisgICAgfQorICAgIGVsc2UgeworICAgICAgUFNldCA9IFRSSS0+Z2V0UmVnVW5pdFByZXNzdXJlU2V0cyhSZWdVbml0KTsKKyAgICAgIFdlaWdodCA9IFRSSS0+Z2V0UmVnVW5pdFdlaWdodChSZWdVbml0KTsKKyAgICB9CisgICAgaWYgKCpQU2V0ID09IC0xKQorICAgICAgUFNldCA9IG51bGxwdHI7CisgIH0KKworICBib29sIGlzVmFsaWQoKSBjb25zdCB7IHJldHVybiBQU2V0OyB9CisKKyAgdW5zaWduZWQgZ2V0V2VpZ2h0KCkgY29uc3QgeyByZXR1cm4gV2VpZ2h0OyB9CisKKyAgdW5zaWduZWQgb3BlcmF0b3IqKCkgY29uc3QgeyByZXR1cm4gKlBTZXQ7IH0KKworICB2b2lkIG9wZXJhdG9yKysoKSB7CisgICAgYXNzZXJ0KGlzVmFsaWQoKSAmJiAiSW52YWxpZCBQU2V0SXRlcmF0b3IuIik7CisgICAgKytQU2V0OworICAgIGlmICgqUFNldCA9PSAtMSkKKyAgICAgIFBTZXQgPSBudWxscHRyOworICB9Cit9OworCitpbmxpbmUgUFNldEl0ZXJhdG9yIE1hY2hpbmVSZWdpc3RlckluZm86OgorZ2V0UHJlc3N1cmVTZXRzKHVuc2lnbmVkIFJlZ1VuaXQpIGNvbnN0IHsKKyAgcmV0dXJuIFBTZXRJdGVyYXRvcihSZWdVbml0LCB0aGlzKTsKK30KKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9NQUNISU5FUkVHSVNURVJJTkZPX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lU1NBVXBkYXRlci5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVTU0FVcGRhdGVyLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjVlYTIwOAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lU1NBVXBkYXRlci5oCkBAIC0wLDAgKzEsMTEzIEBACisvLz09PS0gTWFjaGluZVNTQVVwZGF0ZXIuaCAtIFVuc3RydWN0dXJlZCBTU0EgVXBkYXRlIFRvb2wgLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZWNsYXJlcyB0aGUgTWFjaGluZVNTQVVwZGF0ZXIgY2xhc3MuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORVNTQVVQREFURVJfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fTUFDSElORVNTQVVQREFURVJfSAorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIE1hY2hpbmVCYXNpY0Jsb2NrOworY2xhc3MgTWFjaGluZUZ1bmN0aW9uOworY2xhc3MgTWFjaGluZUluc3RyOworY2xhc3MgTWFjaGluZU9wZXJhbmQ7CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworY2xhc3MgVGFyZ2V0SW5zdHJJbmZvOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJDbGFzczsKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IGNsYXNzIFNtYWxsVmVjdG9ySW1wbDsKK3RlbXBsYXRlPHR5cGVuYW1lIFQ+IGNsYXNzIFNTQVVwZGF0ZXJUcmFpdHM7CisKKy8vLyBNYWNoaW5lU1NBVXBkYXRlciAtIFRoaXMgY2xhc3MgdXBkYXRlcyBTU0EgZm9ybSBmb3IgYSBzZXQgb2YgdmlydHVhbAorLy8vIHJlZ2lzdGVycyBkZWZpbmVkIGluIG11bHRpcGxlIGJsb2Nrcy4gIFRoaXMgaXMgdXNlZCB3aGVuIGNvZGUgZHVwbGljYXRpb24KKy8vLyBvciBhbm90aGVyIHVuc3RydWN0dXJlZCB0cmFuc2Zvcm1hdGlvbiB3YW50cyB0byByZXdyaXRlIGEgc2V0IG9mIHVzZXMgb2Ygb25lCisvLy8gdnJlZyB3aXRoIHVzZXMgb2YgYSBzZXQgb2YgdnJlZ3MuCitjbGFzcyBNYWNoaW5lU1NBVXBkYXRlciB7CisgIGZyaWVuZCBjbGFzcyBTU0FVcGRhdGVyVHJhaXRzPE1hY2hpbmVTU0FVcGRhdGVyPjsKKworcHJpdmF0ZToKKyAgLy8vIEF2YWlsYWJsZVZhbHMgLSBUaGlzIGtlZXBzIHRyYWNrIG9mIHdoaWNoIHZhbHVlIHRvIHVzZSBvbiBhIHBlci1ibG9jaworICAvLy8gYmFzaXMuICBXaGVuIHdlIGluc2VydCBQSEkgbm9kZXMsIHdlIGtlZXAgdHJhY2sgb2YgdGhlbSBoZXJlLgorICAvL3R5cGVkZWYgRGVuc2VNYXA8TWFjaGluZUJhc2ljQmxvY2sqLCB1bnNpZ25lZCA+IEF2YWlsYWJsZVZhbHNUeTsKKyAgdm9pZCAqQVYgPSBudWxscHRyOworCisgIC8vLyBWUiAtIEN1cnJlbnQgdmlydHVhbCByZWdpc3RlciB3aG9zZSB1c2VzIGFyZSBiZWluZyB1cGRhdGVkLgorICB1bnNpZ25lZCBWUjsKKworICAvLy8gVlJDIC0gUmVnaXN0ZXIgY2xhc3Mgb2YgdGhlIGN1cnJlbnQgdmlydHVhbCByZWdpc3Rlci4KKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqVlJDOworCisgIC8vLyBJbnNlcnRlZFBISXMgLSBJZiB0aGlzIGlzIG5vbi1udWxsLCB0aGUgTWFjaGluZVNTQVVwZGF0ZXIgYWRkcyBhbGwgUEhJCisgIC8vLyBub2RlcyB0aGF0IGl0IGNyZWF0ZXMgdG8gdGhlIHZlY3Rvci4KKyAgU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVJbnN0cio+ICpJbnNlcnRlZFBISXM7CisKKyAgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICpUSUk7CisgIE1hY2hpbmVSZWdpc3RlckluZm8gKk1SSTsKKworcHVibGljOgorICAvLy8gTWFjaGluZVNTQVVwZGF0ZXIgY29uc3RydWN0b3IuICBJZiBJbnNlcnRlZFBISXMgaXMgc3BlY2lmaWVkLCBpdCB3aWxsIGJlCisgIC8vLyBmaWxsZWQgaW4gd2l0aCBhbGwgUEhJIE5vZGVzIGNyZWF0ZWQgYnkgcmV3cml0aW5nLgorICBleHBsaWNpdCBNYWNoaW5lU1NBVXBkYXRlcihNYWNoaW5lRnVuY3Rpb24gJk1GLAorICAgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVJbnN0cio+ICpJbnNlcnRlZFBISXMgPSBudWxscHRyKTsKKyAgTWFjaGluZVNTQVVwZGF0ZXIoY29uc3QgTWFjaGluZVNTQVVwZGF0ZXIgJikgPSBkZWxldGU7CisgIE1hY2hpbmVTU0FVcGRhdGVyICZvcGVyYXRvcj0oY29uc3QgTWFjaGluZVNTQVVwZGF0ZXIgJikgPSBkZWxldGU7CisgIH5NYWNoaW5lU1NBVXBkYXRlcigpOworCisgIC8vLyBJbml0aWFsaXplIC0gUmVzZXQgdGhpcyBvYmplY3QgdG8gZ2V0IHJlYWR5IGZvciBhIG5ldyBzZXQgb2YgU1NBCisgIC8vLyB1cGRhdGVzLgorICB2b2lkIEluaXRpYWxpemUodW5zaWduZWQgVik7CisKKyAgLy8vIEFkZEF2YWlsYWJsZVZhbHVlIC0gSW5kaWNhdGUgdGhhdCBhIHJld3JpdHRlbiB2YWx1ZSBpcyBhdmFpbGFibGUgYXQgdGhlCisgIC8vLyBlbmQgb2YgdGhlIHNwZWNpZmllZCBibG9jayB3aXRoIHRoZSBzcGVjaWZpZWQgdmFsdWUuCisgIHZvaWQgQWRkQXZhaWxhYmxlVmFsdWUoTWFjaGluZUJhc2ljQmxvY2sgKkJCLCB1bnNpZ25lZCBWKTsKKworICAvLy8gSGFzVmFsdWVGb3JCbG9jayAtIFJldHVybiB0cnVlIGlmIHRoZSBNYWNoaW5lU1NBVXBkYXRlciBhbHJlYWR5IGhhcyBhCisgIC8vLyB2YWx1ZSBmb3IgdGhlIHNwZWNpZmllZCBibG9jay4KKyAgYm9vbCBIYXNWYWx1ZUZvckJsb2NrKE1hY2hpbmVCYXNpY0Jsb2NrICpCQikgY29uc3Q7CisKKyAgLy8vIEdldFZhbHVlQXRFbmRPZkJsb2NrIC0gQ29uc3RydWN0IFNTQSBmb3JtLCBtYXRlcmlhbGl6aW5nIGEgdmFsdWUgdGhhdCBpcworICAvLy8gbGl2ZSBhdCB0aGUgZW5kIG9mIHRoZSBzcGVjaWZpZWQgYmxvY2suCisgIHVuc2lnbmVkIEdldFZhbHVlQXRFbmRPZkJsb2NrKE1hY2hpbmVCYXNpY0Jsb2NrICpCQik7CisKKyAgLy8vIEdldFZhbHVlSW5NaWRkbGVPZkJsb2NrIC0gQ29uc3RydWN0IFNTQSBmb3JtLCBtYXRlcmlhbGl6aW5nIGEgdmFsdWUgdGhhdAorICAvLy8gaXMgbGl2ZSBpbiB0aGUgbWlkZGxlIG9mIHRoZSBzcGVjaWZpZWQgYmxvY2suCisgIC8vLworICAvLy8gR2V0VmFsdWVJbk1pZGRsZU9mQmxvY2sgaXMgdGhlIHNhbWUgYXMgR2V0VmFsdWVBdEVuZE9mQmxvY2sgZXhjZXB0IGluIG9uZQorICAvLy8gaW1wb3J0YW50IGNhc2U6IGlmIHRoZXJlIGlzIGEgZGVmaW5pdGlvbiBvZiB0aGUgcmV3cml0dGVuIHZhbHVlIGFmdGVyIHRoZQorICAvLy8gJ3VzZScgaW4gQkIuICBDb25zaWRlciBjb2RlIGxpa2UgdGhpczoKKyAgLy8vCisgIC8vLyAgICAgIFgxID0gLi4uCisgIC8vLyAgIFNvbWVCQjoKKyAgLy8vICAgICAgdXNlKFgpCisgIC8vLyAgICAgIFgyID0gLi4uCisgIC8vLyAgICAgIGJyIENvbmQsIFNvbWVCQiwgT3V0QkIKKyAgLy8vCisgIC8vLyBJbiB0aGlzIGNhc2UsIHRoZXJlIGFyZSB0d28gdmFsdWVzIChYMSBhbmQgWDIpIGFkZGVkIHRvIHRoZSBBdmFpbGFibGVWYWxzCisgIC8vLyBzZXQgYnkgdGhlIGNsaWVudCBvZiB0aGUgcmV3cml0ZXIsIGFuZCB0aG9zZSB2YWx1ZXMgYXJlIGJvdGggbGl2ZSBvdXQgb2YKKyAgLy8vIHRoZWlyIHJlc3BlY3RpdmUgYmxvY2tzLiAgSG93ZXZlciwgdGhlIHVzZSBvZiBYIGhhcHBlbnMgaW4gdGhlICptaWRkbGUqIG9mCisgIC8vLyBhIGJsb2NrLiAgQmVjYXVzZSBvZiB0aGlzLCB3ZSBuZWVkIHRvIGluc2VydCBhIG5ldyBQSEkgbm9kZSBpbiBTb21lQkIgdG8KKyAgLy8vIG1lcmdlIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZXMsIGFuZCB0aGlzIHZhbHVlIGlzbid0IGxpdmUgb3V0IG9mIHRoZSBibG9jay4KKyAgdW5zaWduZWQgR2V0VmFsdWVJbk1pZGRsZU9mQmxvY2soTWFjaGluZUJhc2ljQmxvY2sgKkJCKTsKKworICAvLy8gUmV3cml0ZVVzZSAtIFJld3JpdGUgYSB1c2Ugb2YgdGhlIHN5bWJvbGljIHZhbHVlLiAgVGhpcyBoYW5kbGVzIFBISSBub2RlcywKKyAgLy8vIHdoaWNoIHVzZSB0aGVpciB2YWx1ZSBpbiB0aGUgY29ycmVzcG9uZGluZyBwcmVkZWNlc3Nvci4gIE5vdGUgdGhhdCB0aGlzCisgIC8vLyB3aWxsIG5vdCB3b3JrIGlmIHRoZSB1c2UgaXMgc3VwcG9zZWQgdG8gYmUgcmV3cml0dGVuIHRvIGEgdmFsdWUgZGVmaW5lZCBpbgorICAvLy8gdGhlIHNhbWUgYmxvY2sgYXMgdGhlIHVzZSwgYnV0IGFib3ZlIGl0LiAgQW55ICdBZGRBdmFpbGFibGVWYWx1ZSdzIGFkZGVkCisgIC8vLyBmb3IgdGhlIHVzZSdzIGJsb2NrIHdpbGwgYmUgY29uc2lkZXJlZCB0byBiZSBiZWxvdyBpdC4KKyAgdm9pZCBSZXdyaXRlVXNlKE1hY2hpbmVPcGVyYW5kICZVKTsKKworcHJpdmF0ZToKKyAgdW5zaWduZWQgR2V0VmFsdWVBdEVuZE9mQmxvY2tJbnRlcm5hbChNYWNoaW5lQmFzaWNCbG9jayAqQkIpOworfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9NQUNISU5FU1NBVVBEQVRFUl9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjaGluZVNjaGVkdWxlci5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVTY2hlZHVsZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMzI3ODgxCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVTY2hlZHVsZXIuaApAQCAtMCwwICsxLDEwNTYgQEAKKy8vPT09LSBNYWNoaW5lU2NoZWR1bGVyLmggLSBNYWNoaW5lSW5zdHIgU2NoZWR1bGluZyBQYXNzIC0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIHByb3ZpZGVzIGFuIGludGVyZmFjZSBmb3IgY3VzdG9taXppbmcgdGhlIHN0YW5kYXJkIE1hY2hpbmVTY2hlZHVsZXIKKy8vIHBhc3MuIE5vdGUgdGhhdCB0aGUgZW50aXJlIHBhc3MgbWF5IGJlIHJlcGxhY2VkIGFzIGZvbGxvd3M6CisvLworLy8gPFRhcmdldD5UYXJnZXRNYWNoaW5lOjpjcmVhdGVQYXNzQ29uZmlnKFBhc3NNYW5hZ2VyQmFzZSAmUE0pIHsKKy8vICAgUE0uc3Vic3RpdHV0ZVBhc3MoJk1hY2hpbmVTY2hlZHVsZXJJRCwgJkN1c3RvbVNjaGVkdWxlclBhc3NJRCk7CisvLyAgIC4uLn0KKy8vCisvLyBUaGUgTWFjaGluZVNjaGVkdWxlciBwYXNzIGlzIG9ubHkgcmVzcG9uc2libGUgZm9yIGNob29zaW5nIHRoZSByZWdpb25zIHRvIGJlCisvLyBzY2hlZHVsZWQuIFRhcmdldHMgY2FuIG92ZXJyaWRlIHRoZSBEQUcgYnVpbGRlciBhbmQgc2NoZWR1bGVyIHdpdGhvdXQKKy8vIHJlcGxhY2luZyB0aGUgcGFzcyBhcyBmb2xsb3dzOgorLy8KKy8vIFNjaGVkdWxlREFHSW5zdHJzICo8VGFyZ2V0PlBhc3NDb25maWc6OgorLy8gY3JlYXRlTWFjaGluZVNjaGVkdWxlcihNYWNoaW5lU2NoZWRDb250ZXh0ICpDKSB7CisvLyAgIHJldHVybiBuZXcgQ3VzdG9tTWFjaGluZVNjaGVkdWxlcihDKTsKKy8vIH0KKy8vCisvLyBUaGUgZGVmYXVsdCBzY2hlZHVsZXIsIFNjaGVkdWxlREFHTUlMaXZlLCBidWlsZHMgdGhlIERBRyBhbmQgZHJpdmVzIGxpc3QKKy8vIHNjaGVkdWxpbmcgd2hpbGUgdXBkYXRpbmcgdGhlIGluc3RydWN0aW9uIHN0cmVhbSwgcmVnaXN0ZXIgcHJlc3N1cmUsIGFuZCBsaXZlCisvLyBpbnRlcnZhbHMuIE1vc3QgdGFyZ2V0cyBkb24ndCBuZWVkIHRvIG92ZXJyaWRlIHRoZSBEQUcgYnVpbGRlciBhbmQgbGlzdAorLy8gc2NoZWR1bGVyLCBidXQgc3VidGFyZ2V0cyB0aGF0IHJlcXVpcmUgY3VzdG9tIHNjaGVkdWxpbmcgaGV1cmlzdGljcyBtYXkKKy8vIHBsdWdpbiBhbiBhbHRlcm5hdGUgTWFjaGluZVNjaGVkU3RyYXRlZ3kuIFRoZSBzdHJhdGVneSBpcyByZXNwb25zaWJsZSBmb3IKKy8vIHNlbGVjdGluZyB0aGUgaGlnaGVzdCBwcmlvcml0eSBub2RlIGZyb20gdGhlIGxpc3Q6CisvLworLy8gU2NoZWR1bGVEQUdJbnN0cnMgKjxUYXJnZXQ+UGFzc0NvbmZpZzo6CisvLyBjcmVhdGVNYWNoaW5lU2NoZWR1bGVyKE1hY2hpbmVTY2hlZENvbnRleHQgKkMpIHsKKy8vICAgcmV0dXJuIG5ldyBTY2hlZHVsZURBR01JTGl2ZShDLCBDdXN0b21TdHJhdGVneShDKSk7CisvLyB9CisvLworLy8gVGhlIERBRyBidWlsZGVyIGNhbiBhbHNvIGJlIGN1c3RvbWl6ZWQgaW4gYSBzZW5zZSBieSBhZGRpbmcgREFHIG11dGF0aW9ucworLy8gdGhhdCB3aWxsIHJ1biBhZnRlciBEQUcgYnVpbGRpbmcgYW5kIGJlZm9yZSBsaXN0IHNjaGVkdWxpbmcuIERBRyBtdXRhdGlvbnMKKy8vIGNhbiBhZGp1c3QgZGVwZW5kZW5jaWVzIGJhc2VkIG9uIHRhcmdldC1zcGVjaWZpYyBrbm93bGVkZ2Ugb3IgYWRkIHdlYWsgZWRnZXMKKy8vIHRvIGFpZCBoZXVyaXN0aWNzOgorLy8KKy8vIFNjaGVkdWxlREFHSW5zdHJzICo8VGFyZ2V0PlBhc3NDb25maWc6OgorLy8gY3JlYXRlTWFjaGluZVNjaGVkdWxlcihNYWNoaW5lU2NoZWRDb250ZXh0ICpDKSB7CisvLyAgIFNjaGVkdWxlREFHTUkgKkRBRyA9IGNyZWF0ZUdlbmVyaWNTY2hlZExpdmUoQyk7CisvLyAgIERBRy0+YWRkTXV0YXRpb24obmV3IEN1c3RvbURBR011dGF0aW9uKC4uLikpOworLy8gICByZXR1cm4gREFHOworLy8gfQorLy8KKy8vIEEgdGFyZ2V0IHRoYXQgc3VwcG9ydHMgYWx0ZXJuYXRpdmUgc2NoZWR1bGVycyBjYW4gdXNlIHRoZQorLy8gTWFjaGluZVNjaGVkUmVnaXN0cnkgdG8gYWxsb3cgY29tbWFuZCBsaW5lIHNlbGVjdGlvbi4gVGhpcyBjYW4gYmUgZG9uZSBieQorLy8gaW1wbGVtZW50aW5nIHRoZSBmb2xsb3dpbmcgYm9pbGVycGxhdGU6CisvLworLy8gc3RhdGljIFNjaGVkdWxlREFHSW5zdHJzICpjcmVhdGVDdXN0b21NYWNoaW5lU2NoZWQoTWFjaGluZVNjaGVkQ29udGV4dCAqQykgeworLy8gIHJldHVybiBuZXcgQ3VzdG9tTWFjaGluZVNjaGVkdWxlcihDKTsKKy8vIH0KKy8vIHN0YXRpYyBNYWNoaW5lU2NoZWRSZWdpc3RyeQorLy8gU2NoZWRDdXN0b21SZWdpc3RyeSgiY3VzdG9tIiwgIlJ1biBteSB0YXJnZXQncyBjdXN0b20gc2NoZWR1bGVyIiwKKy8vICAgICAgICAgICAgICAgICAgICAgY3JlYXRlQ3VzdG9tTWFjaGluZVNjaGVkKTsKKy8vCisvLworLy8gRmluYWxseSwgc3VidGFyZ2V0cyB0aGF0IGRvbid0IG5lZWQgdG8gaW1wbGVtZW50IGN1c3RvbSBoZXVyaXN0aWNzIGJ1dCB3b3VsZAorLy8gbGlrZSB0byBjb25maWd1cmUgdGhlIEdlbmVyaWNTY2hlZHVsZXIncyBwb2xpY3kgZm9yIGEgZ2l2ZW4gc2NoZWR1bGVyIHJlZ2lvbiwKKy8vIGluY2x1ZGluZyBzY2hlZHVsaW5nIGRpcmVjdGlvbiBhbmQgcmVnaXN0ZXIgcHJlc3N1cmUgdHJhY2tpbmcgcG9saWN5LCBjYW4gZG8KKy8vIHRoaXM6CisvLworLy8gdm9pZCA8U3ViVGFyZ2V0PlN1YnRhcmdldDo6CisvLyBvdmVycmlkZVNjaGVkUG9saWN5KE1hY2hpbmVTY2hlZFBvbGljeSAmUG9saWN5LAorLy8gICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBOdW1SZWdpb25JbnN0cnMpIGNvbnN0IHsKKy8vICAgUG9saWN5LjxGbGFnPiA9IHRydWU7CisvLyB9CisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORVNDSEVEVUxFUl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9NQUNISU5FU0NIRURVTEVSX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0FycmF5UmVmLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvQml0VmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU1RMRXh0cmFzLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TdHJpbmdSZWYuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9Ud2luZS5oIgorI2luY2x1ZGUgImxsdm0vQW5hbHlzaXMvQWxpYXNBbmFseXNpcy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lQmFzaWNCbG9jay5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lUGFzc1JlZ2lzdHJ5LmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1JlZ2lzdGVyUHJlc3N1cmUuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2NoZWR1bGVEQUcuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2NoZWR1bGVEQUdJbnN0cnMuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2NoZWR1bGVEQUdNdXRhdGlvbi5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9UYXJnZXRTY2hlZHVsZS5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9Db21tYW5kTGluZS5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9FcnJvckhhbmRsaW5nLmgiCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8bWVtb3J5PgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKK25hbWVzcGFjZSBsbHZtIHsKKworZXh0ZXJuIGNsOjpvcHQ8Ym9vbD4gRm9yY2VUb3BEb3duOworZXh0ZXJuIGNsOjpvcHQ8Ym9vbD4gRm9yY2VCb3R0b21VcDsKKworY2xhc3MgTGl2ZUludGVydmFsczsKK2NsYXNzIE1hY2hpbmVEb21pbmF0b3JUcmVlOworY2xhc3MgTWFjaGluZUZ1bmN0aW9uOworY2xhc3MgTWFjaGluZUluc3RyOworY2xhc3MgTWFjaGluZUxvb3BJbmZvOworY2xhc3MgUmVnaXN0ZXJDbGFzc0luZm87CitjbGFzcyBTY2hlZERGU1Jlc3VsdDsKK2NsYXNzIFNjaGVkdWxlSGF6YXJkUmVjb2duaXplcjsKK2NsYXNzIFRhcmdldEluc3RySW5mbzsKK2NsYXNzIFRhcmdldFBhc3NDb25maWc7CitjbGFzcyBUYXJnZXRSZWdpc3RlckluZm87CisKKy8vLyBNYWNoaW5lU2NoZWRDb250ZXh0IHByb3ZpZGVzIGVub3VnaCBjb250ZXh0IGZyb20gdGhlIE1hY2hpbmVTY2hlZHVsZXIgcGFzcworLy8vIGZvciB0aGUgdGFyZ2V0IHRvIGluc3RhbnRpYXRlIGEgc2NoZWR1bGVyLgorc3RydWN0IE1hY2hpbmVTY2hlZENvbnRleHQgeworICBNYWNoaW5lRnVuY3Rpb24gKk1GID0gbnVsbHB0cjsKKyAgY29uc3QgTWFjaGluZUxvb3BJbmZvICpNTEkgPSBudWxscHRyOworICBjb25zdCBNYWNoaW5lRG9taW5hdG9yVHJlZSAqTURUID0gbnVsbHB0cjsKKyAgY29uc3QgVGFyZ2V0UGFzc0NvbmZpZyAqUGFzc0NvbmZpZyA9IG51bGxwdHI7CisgIEFsaWFzQW5hbHlzaXMgKkFBID0gbnVsbHB0cjsKKyAgTGl2ZUludGVydmFscyAqTElTID0gbnVsbHB0cjsKKworICBSZWdpc3RlckNsYXNzSW5mbyAqUmVnQ2xhc3NJbmZvOworCisgIE1hY2hpbmVTY2hlZENvbnRleHQoKTsKKyAgdmlydHVhbCB+TWFjaGluZVNjaGVkQ29udGV4dCgpOworfTsKKworLy8vIE1hY2hpbmVTY2hlZFJlZ2lzdHJ5IHByb3ZpZGVzIGEgc2VsZWN0aW9uIG9mIGF2YWlsYWJsZSBtYWNoaW5lIGluc3RydWN0aW9uCisvLy8gc2NoZWR1bGVycy4KK2NsYXNzIE1hY2hpbmVTY2hlZFJlZ2lzdHJ5IDogcHVibGljIE1hY2hpbmVQYXNzUmVnaXN0cnlOb2RlIHsKK3B1YmxpYzoKKyAgdXNpbmcgU2NoZWR1bGVEQUdDdG9yID0gU2NoZWR1bGVEQUdJbnN0cnMgKigqKShNYWNoaW5lU2NoZWRDb250ZXh0ICopOworCisgIC8vIFJlZ2lzdGVyUGFzc1BhcnNlciByZXF1aXJlcyBhIChtaXNuYW1lZCkgRnVuY3Rpb25QYXNzQ3RvciB0eXBlLgorICB1c2luZyBGdW5jdGlvblBhc3NDdG9yID0gU2NoZWR1bGVEQUdDdG9yOworCisgIHN0YXRpYyBNYWNoaW5lUGFzc1JlZ2lzdHJ5IFJlZ2lzdHJ5OworCisgIE1hY2hpbmVTY2hlZFJlZ2lzdHJ5KGNvbnN0IGNoYXIgKk4sIGNvbnN0IGNoYXIgKkQsIFNjaGVkdWxlREFHQ3RvciBDKQorICAgIDogTWFjaGluZVBhc3NSZWdpc3RyeU5vZGUoTiwgRCwgKE1hY2hpbmVQYXNzQ3RvcilDKSB7CisgICAgUmVnaXN0cnkuQWRkKHRoaXMpOworICB9CisKKyAgfk1hY2hpbmVTY2hlZFJlZ2lzdHJ5KCkgeyBSZWdpc3RyeS5SZW1vdmUodGhpcyk7IH0KKworICAvLyBBY2Nlc3NvcnMuCisgIC8vCisgIE1hY2hpbmVTY2hlZFJlZ2lzdHJ5ICpnZXROZXh0KCkgY29uc3QgeworICAgIHJldHVybiAoTWFjaGluZVNjaGVkUmVnaXN0cnkgKilNYWNoaW5lUGFzc1JlZ2lzdHJ5Tm9kZTo6Z2V0TmV4dCgpOworICB9CisKKyAgc3RhdGljIE1hY2hpbmVTY2hlZFJlZ2lzdHJ5ICpnZXRMaXN0KCkgeworICAgIHJldHVybiAoTWFjaGluZVNjaGVkUmVnaXN0cnkgKilSZWdpc3RyeS5nZXRMaXN0KCk7CisgIH0KKworICBzdGF0aWMgdm9pZCBzZXRMaXN0ZW5lcihNYWNoaW5lUGFzc1JlZ2lzdHJ5TGlzdGVuZXIgKkwpIHsKKyAgICBSZWdpc3RyeS5zZXRMaXN0ZW5lcihMKTsKKyAgfQorfTsKKworY2xhc3MgU2NoZWR1bGVEQUdNSTsKKworLy8vIERlZmluZSBhIGdlbmVyaWMgc2NoZWR1bGluZyBwb2xpY3kgZm9yIHRhcmdldHMgdGhhdCBkb24ndCBwcm92aWRlIHRoZWlyIG93bgorLy8vIE1hY2hpbmVTY2hlZFN0cmF0ZWd5LiBUaGlzIGNhbiBiZSBvdmVycmlkZW4gZm9yIGVhY2ggc2NoZWR1bGluZyByZWdpb24KKy8vLyBiZWZvcmUgYnVpbGRpbmcgdGhlIERBRy4KK3N0cnVjdCBNYWNoaW5lU2NoZWRQb2xpY3kgeworICAvLyBBbGxvdyB0aGUgc2NoZWR1bGVyIHRvIGRpc2FibGUgcmVnaXN0ZXIgcHJlc3N1cmUgdHJhY2tpbmcuCisgIGJvb2wgU2hvdWxkVHJhY2tQcmVzc3VyZSA9IGZhbHNlOworICAvLy8gVHJhY2sgTGFuZU1hc2tzIHRvIGFsbG93IHJlb3JkZXJpbmcgb2YgaW5kZXBlbmRlbnQgc3VicmVnaXN0ZXIgd3JpdGVzCisgIC8vLyBvZiB0aGUgc2FtZSB2cmVnLiBcc2EgTWFjaGluZVNjaGVkU3RyYXRlZ3k6OnNob3VsZFRyYWNrTGFuZU1hc2tzKCkKKyAgYm9vbCBTaG91bGRUcmFja0xhbmVNYXNrcyA9IGZhbHNlOworCisgIC8vIEFsbG93IHRoZSBzY2hlZHVsZXIgdG8gZm9yY2UgdG9wLWRvd24gb3IgYm90dG9tLXVwIHNjaGVkdWxpbmcuIElmIG5laXRoZXIKKyAgLy8gaXMgdHJ1ZSwgdGhlIHNjaGVkdWxlciBydW5zIGluIGJvdGggZGlyZWN0aW9ucyBhbmQgY29udmVyZ2VzLgorICBib29sIE9ubHlUb3BEb3duID0gZmFsc2U7CisgIGJvb2wgT25seUJvdHRvbVVwID0gZmFsc2U7CisKKyAgLy8gRGlzYWJsZSBoZXVyaXN0aWMgdGhhdCB0cmllcyB0byBmZXRjaCBub2RlcyBmcm9tIGxvbmcgZGVwZW5kZW5jeSBjaGFpbnMKKyAgLy8gZmlyc3QuCisgIGJvb2wgRGlzYWJsZUxhdGVuY3lIZXVyaXN0aWMgPSBmYWxzZTsKKworICBNYWNoaW5lU2NoZWRQb2xpY3koKSA9IGRlZmF1bHQ7Cit9OworCisvLy8gTWFjaGluZVNjaGVkU3RyYXRlZ3kgLSBJbnRlcmZhY2UgdG8gdGhlIHNjaGVkdWxpbmcgYWxnb3JpdGhtIHVzZWQgYnkKKy8vLyBTY2hlZHVsZURBR01JLgorLy8vCisvLy8gSW5pdGlhbGl6YXRpb24gc2VxdWVuY2U6CisvLy8gICBpbml0UG9saWN5IC0+IHNob3VsZFRyYWNrUHJlc3N1cmUgLT4gaW5pdGlhbGl6ZShEQUcpIC0+IHJlZ2lzdGVyUm9vdHMKK2NsYXNzIE1hY2hpbmVTY2hlZFN0cmF0ZWd5IHsKKyAgdmlydHVhbCB2b2lkIGFuY2hvcigpOworCitwdWJsaWM6CisgIHZpcnR1YWwgfk1hY2hpbmVTY2hlZFN0cmF0ZWd5KCkgPSBkZWZhdWx0OworCisgIC8vLyBPcHRpb25hbGx5IG92ZXJyaWRlIHRoZSBwZXItcmVnaW9uIHNjaGVkdWxpbmcgcG9saWN5LgorICB2aXJ0dWFsIHZvaWQgaW5pdFBvbGljeShNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgQmVnaW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBFbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIE51bVJlZ2lvbkluc3Rycykge30KKworICB2aXJ0dWFsIHZvaWQgZHVtcFBvbGljeSgpIGNvbnN0IHt9CisKKyAgLy8vIENoZWNrIGlmIHByZXNzdXJlIHRyYWNraW5nIGlzIG5lZWRlZCBiZWZvcmUgYnVpbGRpbmcgdGhlIERBRyBhbmQKKyAgLy8vIGluaXRpYWxpemluZyB0aGlzIHN0cmF0ZWd5LiBDYWxsZWQgYWZ0ZXIgaW5pdFBvbGljeS4KKyAgdmlydHVhbCBib29sIHNob3VsZFRyYWNrUHJlc3N1cmUoKSBjb25zdCB7IHJldHVybiB0cnVlOyB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiBsYW5lbWFza3Mgc2hvdWxkIGJlIHRyYWNrZWQuIExhbmVNYXNrIHRyYWNraW5nIGlzCisgIC8vLyBuZWNlc3NhcnkgdG8gcmVvcmRlciBpbmRlcGVuZGVudCBzdWJyZWdpc3RlciBkZWZzIGZvciB0aGUgc2FtZSB2cmVnLgorICAvLy8gVGhpcyBoYXMgdG8gYmUgZW5hYmxlZCBpbiBjb21iaW5hdGlvbiB3aXRoIHNob3VsZFRyYWNrUHJlc3N1cmUoKS4KKyAgdmlydHVhbCBib29sIHNob3VsZFRyYWNrTGFuZU1hc2tzKCkgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KKworICAvLyBJZiB0aGlzIG1ldGhvZCByZXR1cm5zIHRydWUsIGhhbmRsaW5nIG9mIHRoZSBzY2hlZHVsaW5nIHJlZ2lvbnMKKyAgLy8gdGhlbXNlbHZlcyAoaW4gY2FzZSBvZiBhIHNjaGVkdWxpbmcgYm91bmRhcnkgaW4gTUJCKSB3aWxsIGJlIGRvbmUKKyAgLy8gYmVnaW5uaW5nIHdpdGggdGhlIHRvcG1vc3QgcmVnaW9uIG9mIE1CQi4KKyAgdmlydHVhbCBib29sIGRvTUJCU2NoZWRSZWdpb25zVG9wRG93bigpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgLy8vIEluaXRpYWxpemUgdGhlIHN0cmF0ZWd5IGFmdGVyIGJ1aWxkaW5nIHRoZSBEQUcgZm9yIGEgbmV3IHJlZ2lvbi4KKyAgdmlydHVhbCB2b2lkIGluaXRpYWxpemUoU2NoZWR1bGVEQUdNSSAqREFHKSA9IDA7CisKKyAgLy8vIFRlbGwgdGhlIHN0cmF0ZWd5IHRoYXQgTUJCIGlzIGFib3V0IHRvIGJlIHByb2Nlc3NlZC4KKyAgdmlydHVhbCB2b2lkIGVudGVyTUJCKE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpIHt9OworCisgIC8vLyBUZWxsIHRoZSBzdHJhdGVneSB0aGF0IGN1cnJlbnQgTUJCIGlzIGRvbmUuCisgIHZpcnR1YWwgdm9pZCBsZWF2ZU1CQigpIHt9OworCisgIC8vLyBOb3RpZnkgdGhpcyBzdHJhdGVneSB0aGF0IGFsbCByb290cyBoYXZlIGJlZW4gcmVsZWFzZWQgKGluY2x1ZGluZyB0aG9zZQorICAvLy8gdGhhdCBkZXBlbmQgb24gRW50cnlTVSBvciBFeGl0U1UpLgorICB2aXJ0dWFsIHZvaWQgcmVnaXN0ZXJSb290cygpIHt9CisKKyAgLy8vIFBpY2sgdGhlIG5leHQgbm9kZSB0byBzY2hlZHVsZSwgb3IgcmV0dXJuIE5VTEwuIFNldCBJc1RvcE5vZGUgdG8gdHJ1ZSB0bworICAvLy8gc2NoZWR1bGUgdGhlIG5vZGUgYXQgdGhlIHRvcCBvZiB0aGUgdW5zY2hlZHVsZWQgcmVnaW9uLiBPdGhlcndpc2UgaXQgd2lsbAorICAvLy8gYmUgc2NoZWR1bGVkIGF0IHRoZSBib3R0b20uCisgIHZpcnR1YWwgU1VuaXQgKnBpY2tOb2RlKGJvb2wgJklzVG9wTm9kZSkgPSAwOworCisgIC8vLyBcYnJpZWYgU2NoZWR1bGVyIGNhbGxiYWNrIHRvIG5vdGlmeSB0aGF0IGEgbmV3IHN1YnRyZWUgaXMgc2NoZWR1bGVkLgorICB2aXJ0dWFsIHZvaWQgc2NoZWR1bGVUcmVlKHVuc2lnbmVkIFN1YnRyZWVJRCkge30KKworICAvLy8gTm90aWZ5IE1hY2hpbmVTY2hlZFN0cmF0ZWd5IHRoYXQgU2NoZWR1bGVEQUdNSSBoYXMgc2NoZWR1bGVkIGFuCisgIC8vLyBpbnN0cnVjdGlvbiBhbmQgdXBkYXRlZCBzY2hlZHVsZWQvcmVtYWluaW5nIGZsYWdzIGluIHRoZSBEQUcgbm9kZXMuCisgIHZpcnR1YWwgdm9pZCBzY2hlZE5vZGUoU1VuaXQgKlNVLCBib29sIElzVG9wTm9kZSkgPSAwOworCisgIC8vLyBXaGVuIGFsbCBwcmVkZWNlc3NvciBkZXBlbmRlbmNpZXMgaGF2ZSBiZWVuIHJlc29sdmVkLCBmcmVlIHRoaXMgbm9kZSBmb3IKKyAgLy8vIHRvcC1kb3duIHNjaGVkdWxpbmcuCisgIHZpcnR1YWwgdm9pZCByZWxlYXNlVG9wTm9kZShTVW5pdCAqU1UpID0gMDsKKworICAvLy8gV2hlbiBhbGwgc3VjY2Vzc29yIGRlcGVuZGVuY2llcyBoYXZlIGJlZW4gcmVzb2x2ZWQsIGZyZWUgdGhpcyBub2RlIGZvcgorICAvLy8gYm90dG9tLXVwIHNjaGVkdWxpbmcuCisgIHZpcnR1YWwgdm9pZCByZWxlYXNlQm90dG9tTm9kZShTVW5pdCAqU1UpID0gMDsKK307CisKKy8vLyBTY2hlZHVsZURBR01JIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIFNjaGVkdWxlREFHSW5zdHJzIHRoYXQgc2ltcGx5CisvLy8gc2NoZWR1bGVzIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zIGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gTWFjaGluZVNjaGVkU3RyYXRlZ3kKKy8vLyB3aXRob3V0IG11Y2ggZXh0cmEgYm9vay1rZWVwaW5nLiBUaGlzIGlzIHRoZSBjb21tb24gZnVuY3Rpb25hbGl0eSBiZXR3ZWVuCisvLy8gUHJlUkEgYW5kIFBvc3RSQSBNYWNoaW5lU2NoZWR1bGVyLgorY2xhc3MgU2NoZWR1bGVEQUdNSSA6IHB1YmxpYyBTY2hlZHVsZURBR0luc3RycyB7Citwcm90ZWN0ZWQ6CisgIEFsaWFzQW5hbHlzaXMgKkFBOworICBMaXZlSW50ZXJ2YWxzICpMSVM7CisgIHN0ZDo6dW5pcXVlX3B0cjxNYWNoaW5lU2NoZWRTdHJhdGVneT4gU2NoZWRJbXBsOworCisgIC8vLyBUb3BvIC0gQSB0b3BvbG9naWNhbCBvcmRlcmluZyBmb3IgU1VuaXRzIHdoaWNoIHBlcm1pdHMgZmFzdCBJc1JlYWNoYWJsZQorICAvLy8gYW5kIHNpbWlsYXIgcXVlcmllcy4KKyAgU2NoZWR1bGVEQUdUb3BvbG9naWNhbFNvcnQgVG9wbzsKKworICAvLy8gT3JkZXJlZCBsaXN0IG9mIERBRyBwb3N0cHJvY2Vzc2luZyBzdGVwcy4KKyAgc3RkOjp2ZWN0b3I8c3RkOjp1bmlxdWVfcHRyPFNjaGVkdWxlREFHTXV0YXRpb24+PiBNdXRhdGlvbnM7CisKKyAgLy8vIFRoZSB0b3Agb2YgdGhlIHVuc2NoZWR1bGVkIHpvbmUuCisgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBDdXJyZW50VG9wOworCisgIC8vLyBUaGUgYm90dG9tIG9mIHRoZSB1bnNjaGVkdWxlZCB6b25lLgorICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgQ3VycmVudEJvdHRvbTsKKworICAvLy8gUmVjb3JkIHRoZSBuZXh0IG5vZGUgaW4gYSBzY2hlZHVsZWQgY2x1c3Rlci4KKyAgY29uc3QgU1VuaXQgKk5leHRDbHVzdGVyUHJlZCA9IG51bGxwdHI7CisgIGNvbnN0IFNVbml0ICpOZXh0Q2x1c3RlclN1Y2MgPSBudWxscHRyOworCisjaWZuZGVmIE5ERUJVRworICAvLy8gVGhlIG51bWJlciBvZiBpbnN0cnVjdGlvbnMgc2NoZWR1bGVkIHNvIGZhci4gVXNlZCB0byBjdXQgb2ZmIHRoZQorICAvLy8gc2NoZWR1bGVyIGF0IHRoZSBwb2ludCBkZXRlcm1pbmVkIGJ5IG1pc2NoZWQtY3V0b2ZmLgorICB1bnNpZ25lZCBOdW1JbnN0cnNTY2hlZHVsZWQgPSAwOworI2VuZGlmCisKK3B1YmxpYzoKKyAgU2NoZWR1bGVEQUdNSShNYWNoaW5lU2NoZWRDb250ZXh0ICpDLCBzdGQ6OnVuaXF1ZV9wdHI8TWFjaGluZVNjaGVkU3RyYXRlZ3k+IFMsCisgICAgICAgICAgICAgICAgYm9vbCBSZW1vdmVLaWxsRmxhZ3MpCisgICAgICA6IFNjaGVkdWxlREFHSW5zdHJzKCpDLT5NRiwgQy0+TUxJLCBSZW1vdmVLaWxsRmxhZ3MpLCBBQShDLT5BQSksCisgICAgICAgIExJUyhDLT5MSVMpLCBTY2hlZEltcGwoc3RkOjptb3ZlKFMpKSwgVG9wbyhTVW5pdHMsICZFeGl0U1UpIHt9CisKKyAgLy8gUHJvdmlkZSBhIHZ0YWJsZSBhbmNob3IKKyAgflNjaGVkdWxlREFHTUkoKSBvdmVycmlkZTsKKworICAvLy8gSWYgdGhpcyBtZXRob2QgcmV0dXJucyB0cnVlLCBoYW5kbGluZyBvZiB0aGUgc2NoZWR1bGluZyByZWdpb25zCisgIC8vLyB0aGVtc2VsdmVzIChpbiBjYXNlIG9mIGEgc2NoZWR1bGluZyBib3VuZGFyeSBpbiBNQkIpIHdpbGwgYmUgZG9uZQorICAvLy8gYmVnaW5uaW5nIHdpdGggdGhlIHRvcG1vc3QgcmVnaW9uIG9mIE1CQi4KKyAgYm9vbCBkb01CQlNjaGVkUmVnaW9uc1RvcERvd24oKSBjb25zdCBvdmVycmlkZSB7CisgICAgcmV0dXJuIFNjaGVkSW1wbC0+ZG9NQkJTY2hlZFJlZ2lvbnNUb3BEb3duKCk7CisgIH0KKworICAvLyBSZXR1cm5zIExpdmVJbnRlcnZhbHMgaW5zdGFuY2UgZm9yIHVzZSBpbiBEQUcgbXV0YXRvcnMgYW5kIHN1Y2guCisgIExpdmVJbnRlcnZhbHMgKmdldExJUygpIGNvbnN0IHsgcmV0dXJuIExJUzsgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIERBRyBzdXBwb3J0cyBWUmVnIGxpdmVuZXNzIGFuZCBSZWdQcmVzc3VyZS4KKyAgdmlydHVhbCBib29sIGhhc1ZSZWdMaXZlbmVzcygpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgLy8vIEFkZCBhIHBvc3Rwcm9jZXNzaW5nIHN0ZXAgdG8gdGhlIERBRyBidWlsZGVyLgorICAvLy8gTXV0YXRpb25zIGFyZSBhcHBsaWVkIGluIHRoZSBvcmRlciB0aGF0IHRoZXkgYXJlIGFkZGVkIGFmdGVyIG5vcm1hbCBEQUcKKyAgLy8vIGJ1aWxkaW5nIGFuZCBiZWZvcmUgTWFjaGluZVNjaGVkU3RyYXRlZ3kgaW5pdGlhbGl6YXRpb24uCisgIC8vLworICAvLy8gU2NoZWR1bGVEQUdNSSB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIE11dGF0aW9uIG9iamVjdC4KKyAgdm9pZCBhZGRNdXRhdGlvbihzdGQ6OnVuaXF1ZV9wdHI8U2NoZWR1bGVEQUdNdXRhdGlvbj4gTXV0YXRpb24pIHsKKyAgICBpZiAoTXV0YXRpb24pCisgICAgICBNdXRhdGlvbnMucHVzaF9iYWNrKHN0ZDo6bW92ZShNdXRhdGlvbikpOworICB9CisKKyAgLy8vIFxicmllZiBUcnVlIGlmIGFuIGVkZ2UgY2FuIGJlIGFkZGVkIGZyb20gUHJlZFNVIHRvIFN1Y2NTVSB3aXRob3V0IGNyZWF0aW5nCisgIC8vLyBhIGN5Y2xlLgorICBib29sIGNhbkFkZEVkZ2UoU1VuaXQgKlN1Y2NTVSwgU1VuaXQgKlByZWRTVSk7CisKKyAgLy8vIFxicmllZiBBZGQgYSBEQUcgZWRnZSB0byB0aGUgZ2l2ZW4gU1Ugd2l0aCB0aGUgZ2l2ZW4gcHJlZGVjZXNzb3IKKyAgLy8vIGRlcGVuZGVuY2UgZGF0YS4KKyAgLy8vCisgIC8vLyBccmV0dXJucyB0cnVlIGlmIHRoZSBlZGdlIG1heSBiZSBhZGRlZCB3aXRob3V0IGNyZWF0aW5nIGEgY3ljbGUgT1IgaWYgYW4KKyAgLy8vIGVxdWl2YWxlbnQgZWRnZSBhbHJlYWR5IGV4aXN0ZWQgKGZhbHNlIGluZGljYXRlcyBmYWlsdXJlKS4KKyAgYm9vbCBhZGRFZGdlKFNVbml0ICpTdWNjU1UsIGNvbnN0IFNEZXAgJlByZWREZXApOworCisgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciB0b3AoKSBjb25zdCB7IHJldHVybiBDdXJyZW50VG9wOyB9CisgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBib3R0b20oKSBjb25zdCB7IHJldHVybiBDdXJyZW50Qm90dG9tOyB9CisKKyAgLy8vIEltcGxlbWVudCB0aGUgU2NoZWR1bGVEQUdJbnN0cnMgaW50ZXJmYWNlIGZvciBoYW5kbGluZyB0aGUgbmV4dCBzY2hlZHVsaW5nCisgIC8vLyByZWdpb24uIFRoaXMgY292ZXJzIGFsbCBpbnN0cnVjdGlvbnMgaW4gYSBibG9jaywgd2hpbGUgc2NoZWR1bGUoKSBtYXkgb25seQorICAvLy8gY292ZXIgYSBzdWJzZXQuCisgIHZvaWQgZW50ZXJSZWdpb24oTWFjaGluZUJhc2ljQmxvY2sgKmJiLAorICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBiZWdpbiwKKyAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgZW5kLAorICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHJlZ2lvbmluc3Rycykgb3ZlcnJpZGU7CisKKyAgLy8vIEltcGxlbWVudCBTY2hlZHVsZURBR0luc3RycyBpbnRlcmZhY2UgZm9yIHNjaGVkdWxpbmcgYSBzZXF1ZW5jZSBvZgorICAvLy8gcmVvcmRlcmFibGUgaW5zdHJ1Y3Rpb25zLgorICB2b2lkIHNjaGVkdWxlKCkgb3ZlcnJpZGU7CisKKyAgdm9pZCBzdGFydEJsb2NrKE1hY2hpbmVCYXNpY0Jsb2NrICpiYikgb3ZlcnJpZGU7CisgIHZvaWQgZmluaXNoQmxvY2soKSBvdmVycmlkZTsKKworICAvLy8gQ2hhbmdlIHRoZSBwb3NpdGlvbiBvZiBhbiBpbnN0cnVjdGlvbiB3aXRoaW4gdGhlIGJhc2ljIGJsb2NrIGFuZCB1cGRhdGUKKyAgLy8vIGxpdmUgcmFuZ2VzIGFuZCByZWdpb24gYm91bmRhcnkgaXRlcmF0b3JzLgorICB2b2lkIG1vdmVJbnN0cnVjdGlvbihNYWNoaW5lSW5zdHIgKk1JLCBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgSW5zZXJ0UG9zKTsKKworICBjb25zdCBTVW5pdCAqZ2V0TmV4dENsdXN0ZXJQcmVkKCkgY29uc3QgeyByZXR1cm4gTmV4dENsdXN0ZXJQcmVkOyB9CisKKyAgY29uc3QgU1VuaXQgKmdldE5leHRDbHVzdGVyU3VjYygpIGNvbnN0IHsgcmV0dXJuIE5leHRDbHVzdGVyU3VjYzsgfQorCisgIHZvaWQgdmlld0dyYXBoKGNvbnN0IFR3aW5lICZOYW1lLCBjb25zdCBUd2luZSAmVGl0bGUpIG92ZXJyaWRlOworICB2b2lkIHZpZXdHcmFwaCgpIG92ZXJyaWRlOworCitwcm90ZWN0ZWQ6CisgIC8vIFRvcC1MZXZlbCBlbnRyeSBwb2ludHMgZm9yIHRoZSBzY2hlZHVsZSgpIGRyaXZlci4uLgorCisgIC8vLyBBcHBseSBlYWNoIFNjaGVkdWxlREFHTXV0YXRpb24gc3RlcCBpbiBvcmRlci4gVGhpcyBhbGxvd3MgZGlmZmVyZW50CisgIC8vLyBpbnN0YW5jZXMgb2YgU2NoZWR1bGVEQUdNSSB0byBwZXJmb3JtIGN1c3RvbSBEQUcgcG9zdHByb2Nlc3NpbmcuCisgIHZvaWQgcG9zdHByb2Nlc3NEQUcoKTsKKworICAvLy8gUmVsZWFzZSBFeGl0U1UgcHJlZGVjZXNzb3JzIGFuZCBzZXR1cCBzY2hlZHVsZXIgcXVldWVzLgorICB2b2lkIGluaXRRdWV1ZXMoQXJyYXlSZWY8U1VuaXQqPiBUb3BSb290cywgQXJyYXlSZWY8U1VuaXQqPiBCb3RSb290cyk7CisKKyAgLy8vIFVwZGF0ZSBzY2hlZHVsZXIgREFHIGFuZCBxdWV1ZXMgYWZ0ZXIgc2NoZWR1bGluZyBhbiBpbnN0cnVjdGlvbi4KKyAgdm9pZCB1cGRhdGVRdWV1ZXMoU1VuaXQgKlNVLCBib29sIElzVG9wTm9kZSk7CisKKyAgLy8vIFJlaW5zZXJ0IGRlYnVnX3ZhbHVlcyByZWNvcmRlZCBpbiBTY2hlZHVsZURBR0luc3Ryczo6RGJnVmFsdWVzLgorICB2b2lkIHBsYWNlRGVidWdWYWx1ZXMoKTsKKworICAvLy8gXGJyaWVmIGR1bXAgdGhlIHNjaGVkdWxlZCBTZXF1ZW5jZS4KKyAgdm9pZCBkdW1wU2NoZWR1bGUoKSBjb25zdDsKKworICAvLyBMZXNzZXIgaGVscGVycy4uLgorICBib29sIGNoZWNrU2NoZWRMaW1pdCgpOworCisgIHZvaWQgZmluZFJvb3RzQW5kQmlhc0VkZ2VzKFNtYWxsVmVjdG9ySW1wbDxTVW5pdCo+ICZUb3BSb290cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPFNVbml0Kj4gJkJvdFJvb3RzKTsKKworICB2b2lkIHJlbGVhc2VTdWNjKFNVbml0ICpTVSwgU0RlcCAqU3VjY0VkZ2UpOworICB2b2lkIHJlbGVhc2VTdWNjZXNzb3JzKFNVbml0ICpTVSk7CisgIHZvaWQgcmVsZWFzZVByZWQoU1VuaXQgKlNVLCBTRGVwICpQcmVkRWRnZSk7CisgIHZvaWQgcmVsZWFzZVByZWRlY2Vzc29ycyhTVW5pdCAqU1UpOworfTsKKworLy8vIFNjaGVkdWxlREFHTUlMaXZlIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIFNjaGVkdWxlREFHSW5zdHJzIHRoYXQgc2NoZWR1bGVzCisvLy8gbWFjaGluZSBpbnN0cnVjdGlvbnMgd2hpbGUgdXBkYXRpbmcgTGl2ZUludGVydmFscyBhbmQgdHJhY2tpbmcgcmVncHJlc3N1cmUuCitjbGFzcyBTY2hlZHVsZURBR01JTGl2ZSA6IHB1YmxpYyBTY2hlZHVsZURBR01JIHsKK3Byb3RlY3RlZDoKKyAgUmVnaXN0ZXJDbGFzc0luZm8gKlJlZ0NsYXNzSW5mbzsKKworICAvLy8gSW5mb3JtYXRpb24gYWJvdXQgREFHIHN1YnRyZWVzLiBJZiBERlNSZXN1bHQgaXMgTlVMTCwgdGhlbiBTY2hlZHVsZXJUcmVlcworICAvLy8gd2lsbCBiZSBlbXB0eS4KKyAgU2NoZWRERlNSZXN1bHQgKkRGU1Jlc3VsdCA9IG51bGxwdHI7CisgIEJpdFZlY3RvciBTY2hlZHVsZWRUcmVlczsKKworICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgTGl2ZVJlZ2lvbkVuZDsKKworICAvLy8gTWFwcyB2cmVncyB0byB0aGUgU1VuaXRzIG9mIHRoZWlyIHVzZXMgaW4gdGhlIGN1cnJlbnQgc2NoZWR1bGluZyByZWdpb24uCisgIFZSZWcyU1VuaXRNdWx0aU1hcCBWUmVnVXNlczsKKworICAvLyBNYXAgZWFjaCBTVSB0byBpdHMgc3VtbWFyeSBvZiBwcmVzc3VyZSBjaGFuZ2VzLiBUaGlzIGFycmF5IGlzIHVwZGF0ZWQgZm9yCisgIC8vIGxpdmVuZXNzIGR1cmluZyBib3R0b20tdXAgc2NoZWR1bGluZy4gVG9wLWRvd24gc2NoZWR1bGluZyBtYXkgcHJvY2VlZCBidXQKKyAgLy8gaGFzIG5vIGFmZmVjdCBvbiB0aGUgcHJlc3N1cmUgZGlmZnMuCisgIFByZXNzdXJlRGlmZnMgU1VQcmVzc3VyZURpZmZzOworCisgIC8vLyBSZWdpc3RlciBwcmVzc3VyZSBpbiB0aGlzIHJlZ2lvbiBjb21wdXRlZCBieSBpbml0UmVnUHJlc3N1cmUuCisgIGJvb2wgU2hvdWxkVHJhY2tQcmVzc3VyZSA9IGZhbHNlOworICBib29sIFNob3VsZFRyYWNrTGFuZU1hc2tzID0gZmFsc2U7CisgIEludGVydmFsUHJlc3N1cmUgUmVnUHJlc3N1cmU7CisgIFJlZ1ByZXNzdXJlVHJhY2tlciBSUFRyYWNrZXI7CisKKyAgLy8vIExpc3Qgb2YgcHJlc3N1cmUgc2V0cyB0aGF0IGV4Y2VlZCB0aGUgdGFyZ2V0J3MgcHJlc3N1cmUgbGltaXQgYmVmb3JlCisgIC8vLyBzY2hlZHVsaW5nLCBsaXN0ZWQgaW4gaW5jcmVhc2luZyBzZXQgSUQgb3JkZXIuIEVhY2ggcHJlc3N1cmUgc2V0IGlzIHBhaXJlZAorICAvLy8gd2l0aCBpdHMgbWF4IHByZXNzdXJlIGluIHRoZSBjdXJyZW50bHkgc2NoZWR1bGVkIHJlZ2lvbnMuCisgIHN0ZDo6dmVjdG9yPFByZXNzdXJlQ2hhbmdlPiBSZWdpb25Dcml0aWNhbFBTZXRzOworCisgIC8vLyBUaGUgdG9wIG9mIHRoZSB1bnNjaGVkdWxlZCB6b25lLgorICBJbnRlcnZhbFByZXNzdXJlIFRvcFByZXNzdXJlOworICBSZWdQcmVzc3VyZVRyYWNrZXIgVG9wUlBUcmFja2VyOworCisgIC8vLyBUaGUgYm90dG9tIG9mIHRoZSB1bnNjaGVkdWxlZCB6b25lLgorICBJbnRlcnZhbFByZXNzdXJlIEJvdFByZXNzdXJlOworICBSZWdQcmVzc3VyZVRyYWNrZXIgQm90UlBUcmFja2VyOworCisgIC8vLyBUcnVlIGlmIGRpc2Nvbm5lY3RlZCBzdWJyZWdpc3RlciBjb21wb25lbnRzIGFyZSBhbHJlYWR5IHJlbmFtZWQuCisgIC8vLyBUaGUgcmVuYW1pbmcgaXMgb25seSBkb25lIG9uIGRlbWFuZCBpZiBsYW5lIG1hc2tzIGFyZSB0cmFja2VkLgorICBib29sIERpc2Nvbm5lY3RlZENvbXBvbmVudHNSZW5hbWVkID0gZmFsc2U7CisKK3B1YmxpYzoKKyAgU2NoZWR1bGVEQUdNSUxpdmUoTWFjaGluZVNjaGVkQ29udGV4dCAqQywKKyAgICAgICAgICAgICAgICAgICAgc3RkOjp1bmlxdWVfcHRyPE1hY2hpbmVTY2hlZFN0cmF0ZWd5PiBTKQorICAgICAgOiBTY2hlZHVsZURBR01JKEMsIHN0ZDo6bW92ZShTKSwgLypSZW1vdmVLaWxsRmxhZ3M9Ki9mYWxzZSksCisgICAgICAgIFJlZ0NsYXNzSW5mbyhDLT5SZWdDbGFzc0luZm8pLCBSUFRyYWNrZXIoUmVnUHJlc3N1cmUpLAorICAgICAgICBUb3BSUFRyYWNrZXIoVG9wUHJlc3N1cmUpLCBCb3RSUFRyYWNrZXIoQm90UHJlc3N1cmUpIHt9CisKKyAgflNjaGVkdWxlREFHTUlMaXZlKCkgb3ZlcnJpZGU7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgREFHIHN1cHBvcnRzIFZSZWcgbGl2ZW5lc3MgYW5kIFJlZ1ByZXNzdXJlLgorICBib29sIGhhc1ZSZWdMaXZlbmVzcygpIGNvbnN0IG92ZXJyaWRlIHsgcmV0dXJuIHRydWU7IH0KKworICAvLy8gXGJyaWVmIFJldHVybiB0cnVlIGlmIHJlZ2lzdGVyIHByZXNzdXJlIHRyYWNraW5nIGlzIGVuYWJsZWQuCisgIGJvb2wgaXNUcmFja2luZ1ByZXNzdXJlKCkgY29uc3QgeyByZXR1cm4gU2hvdWxkVHJhY2tQcmVzc3VyZTsgfQorCisgIC8vLyBHZXQgY3VycmVudCByZWdpc3RlciBwcmVzc3VyZSBmb3IgdGhlIHRvcCBzY2hlZHVsZWQgaW5zdHJ1Y3Rpb25zLgorICBjb25zdCBJbnRlcnZhbFByZXNzdXJlICZnZXRUb3BQcmVzc3VyZSgpIGNvbnN0IHsgcmV0dXJuIFRvcFByZXNzdXJlOyB9CisgIGNvbnN0IFJlZ1ByZXNzdXJlVHJhY2tlciAmZ2V0VG9wUlBUcmFja2VyKCkgY29uc3QgeyByZXR1cm4gVG9wUlBUcmFja2VyOyB9CisKKyAgLy8vIEdldCBjdXJyZW50IHJlZ2lzdGVyIHByZXNzdXJlIGZvciB0aGUgYm90dG9tIHNjaGVkdWxlZCBpbnN0cnVjdGlvbnMuCisgIGNvbnN0IEludGVydmFsUHJlc3N1cmUgJmdldEJvdFByZXNzdXJlKCkgY29uc3QgeyByZXR1cm4gQm90UHJlc3N1cmU7IH0KKyAgY29uc3QgUmVnUHJlc3N1cmVUcmFja2VyICZnZXRCb3RSUFRyYWNrZXIoKSBjb25zdCB7IHJldHVybiBCb3RSUFRyYWNrZXI7IH0KKworICAvLy8gR2V0IHJlZ2lzdGVyIHByZXNzdXJlIGZvciB0aGUgZW50aXJlIHNjaGVkdWxpbmcgcmVnaW9uIGJlZm9yZSBzY2hlZHVsaW5nLgorICBjb25zdCBJbnRlcnZhbFByZXNzdXJlICZnZXRSZWdQcmVzc3VyZSgpIGNvbnN0IHsgcmV0dXJuIFJlZ1ByZXNzdXJlOyB9CisKKyAgY29uc3Qgc3RkOjp2ZWN0b3I8UHJlc3N1cmVDaGFuZ2U+ICZnZXRSZWdpb25Dcml0aWNhbFBTZXRzKCkgY29uc3QgeworICAgIHJldHVybiBSZWdpb25Dcml0aWNhbFBTZXRzOworICB9CisKKyAgUHJlc3N1cmVEaWZmICZnZXRQcmVzc3VyZURpZmYoY29uc3QgU1VuaXQgKlNVKSB7CisgICAgcmV0dXJuIFNVUHJlc3N1cmVEaWZmc1tTVS0+Tm9kZU51bV07CisgIH0KKworICAvLy8gQ29tcHV0ZSBhIERGU1Jlc3VsdCBhZnRlciBEQUcgYnVpbGRpbmcgaXMgY29tcGxldGUsIGFuZCBiZWZvcmUgYW55CisgIC8vLyBxdWV1ZSBjb21wYXJpc29ucy4KKyAgdm9pZCBjb21wdXRlREZTUmVzdWx0KCk7CisKKyAgLy8vIFJldHVybiBhIG5vbi1udWxsIERGUyByZXN1bHQgaWYgdGhlIHNjaGVkdWxpbmcgc3RyYXRlZ3kgaW5pdGlhbGl6ZWQgaXQuCisgIGNvbnN0IFNjaGVkREZTUmVzdWx0ICpnZXRERlNSZXN1bHQoKSBjb25zdCB7IHJldHVybiBERlNSZXN1bHQ7IH0KKworICBCaXRWZWN0b3IgJmdldFNjaGVkdWxlZFRyZWVzKCkgeyByZXR1cm4gU2NoZWR1bGVkVHJlZXM7IH0KKworICAvLy8gSW1wbGVtZW50IHRoZSBTY2hlZHVsZURBR0luc3RycyBpbnRlcmZhY2UgZm9yIGhhbmRsaW5nIHRoZSBuZXh0IHNjaGVkdWxpbmcKKyAgLy8vIHJlZ2lvbi4gVGhpcyBjb3ZlcnMgYWxsIGluc3RydWN0aW9ucyBpbiBhIGJsb2NrLCB3aGlsZSBzY2hlZHVsZSgpIG1heSBvbmx5CisgIC8vLyBjb3ZlciBhIHN1YnNldC4KKyAgdm9pZCBlbnRlclJlZ2lvbihNYWNoaW5lQmFzaWNCbG9jayAqYmIsCisgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIGJlZ2luLAorICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBlbmQsCisgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgcmVnaW9uaW5zdHJzKSBvdmVycmlkZTsKKworICAvLy8gSW1wbGVtZW50IFNjaGVkdWxlREFHSW5zdHJzIGludGVyZmFjZSBmb3Igc2NoZWR1bGluZyBhIHNlcXVlbmNlIG9mCisgIC8vLyByZW9yZGVyYWJsZSBpbnN0cnVjdGlvbnMuCisgIHZvaWQgc2NoZWR1bGUoKSBvdmVycmlkZTsKKworICAvLy8gQ29tcHV0ZSB0aGUgY3ljbGljIGNyaXRpY2FsIHBhdGggdGhyb3VnaCB0aGUgREFHLgorICB1bnNpZ25lZCBjb21wdXRlQ3ljbGljQ3JpdGljYWxQYXRoKCk7CisKK3Byb3RlY3RlZDoKKyAgLy8gVG9wLUxldmVsIGVudHJ5IHBvaW50cyBmb3IgdGhlIHNjaGVkdWxlKCkgZHJpdmVyLi4uCisKKyAgLy8vIENhbGwgU2NoZWR1bGVEQUdJbnN0cnM6OmJ1aWxkU2NoZWRHcmFwaCB3aXRoIHJlZ2lzdGVyIHByZXNzdXJlIHRyYWNraW5nCisgIC8vLyBlbmFibGVkLiBUaGlzIHNldHMgdXAgdGhyZWUgdHJhY2tlcnMuIFJQVHJhY2tlciB3aWxsIGNvdmVyIHRoZSBlbnRpcmUgREFHCisgIC8vLyByZWdpb24sIFRvcFRyYWNrZXIgYW5kIEJvdHRvbVRyYWNrZXIgd2lsbCBiZSBpbml0aWFsaXplZCB0byB0aGUgdG9wIGFuZAorICAvLy8gYm90dG9tIG9mIHRoZSBEQUcgcmVnaW9uIHdpdGhvdXQgY292ZXJlaW5nIGFueSB1bnNjaGVkdWxlZCBpbnN0cnVjdGlvbi4KKyAgdm9pZCBidWlsZERBR1dpdGhSZWdQcmVzc3VyZSgpOworCisgIC8vLyBSZWxlYXNlIEV4aXRTVSBwcmVkZWNlc3NvcnMgYW5kIHNldHVwIHNjaGVkdWxlciBxdWV1ZXMuIFJlLXBvc2l0aW9uCisgIC8vLyB0aGUgVG9wIFJQIHRyYWNrZXIgaW4gY2FzZSB0aGUgcmVnaW9uIGJlZ2lubmluZyBoYXMgY2hhbmdlZC4KKyAgdm9pZCBpbml0UXVldWVzKEFycmF5UmVmPFNVbml0Kj4gVG9wUm9vdHMsIEFycmF5UmVmPFNVbml0Kj4gQm90Um9vdHMpOworCisgIC8vLyBNb3ZlIGFuIGluc3RydWN0aW9uIGFuZCB1cGRhdGUgcmVnaXN0ZXIgcHJlc3N1cmUuCisgIHZvaWQgc2NoZWR1bGVNSShTVW5pdCAqU1UsIGJvb2wgSXNUb3BOb2RlKTsKKworICAvLyBMZXNzZXIgaGVscGVycy4uLgorCisgIHZvaWQgaW5pdFJlZ1ByZXNzdXJlKCk7CisKKyAgdm9pZCB1cGRhdGVQcmVzc3VyZURpZmZzKEFycmF5UmVmPFJlZ2lzdGVyTWFza1BhaXI+IExpdmVVc2VzKTsKKworICB2b2lkIHVwZGF0ZVNjaGVkdWxlZFByZXNzdXJlKGNvbnN0IFNVbml0ICpTVSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGQ6OnZlY3Rvcjx1bnNpZ25lZD4gJk5ld01heFByZXNzdXJlKTsKKworICB2b2lkIGNvbGxlY3RWUmVnVXNlcyhTVW5pdCAmU1UpOworfTsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLworLy8vIEhlbHBlcnMgZm9yIGltcGxlbWVudGluZyBjdXN0b20gTWFjaGluZVNjaGVkU3RyYXRlZ3kgY2xhc3Nlcy4gVGhlc2UgdGFrZQorLy8vIGNhcmUgb2YgdGhlIGJvb2sta2VlcGluZyBhc3NvY2lhdGVkIHdpdGggbGlzdCBzY2hlZHVsaW5nIGhldXJpc3RpY3MuCisvLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKy8vLyBSZWFkeVF1ZXVlIGVuY2Fwc3VsYXRlcyB2ZWN0b3Igb2YgInJlYWR5IiBTVW5pdHMgd2l0aCBiYXNpYyBjb252ZW5pZW5jZQorLy8vIG1ldGhvZHMgZm9yIHB1c2hpbmcgYW5kIHJlbW92aW5nIG5vZGVzLiBSZWFkeVF1ZXVlJ3MgYXJlIHVuaXF1ZWx5IGlkZW50aWZpZWQKKy8vLyBieSBhbiBJRC4gU1VuaXQ6Ok5vZGVRdWV1ZUlkIGlzIGEgbWFzayBvZiB0aGUgUmVhZHlRdWV1ZXMgdGhlIFNVbml0IGlzIGluLgorLy8vCisvLy8gVGhpcyBpcyBhIGNvbnZlbmllbmNlIGNsYXNzIHRoYXQgbWF5IGJlIHVzZWQgYnkgaW1wbGVtZW50YXRpb25zIG9mCisvLy8gTWFjaGluZVNjaGVkU3RyYXRlZ3kuCitjbGFzcyBSZWFkeVF1ZXVlIHsKKyAgdW5zaWduZWQgSUQ7CisgIHN0ZDo6c3RyaW5nIE5hbWU7CisgIHN0ZDo6dmVjdG9yPFNVbml0Kj4gUXVldWU7CisKK3B1YmxpYzoKKyAgUmVhZHlRdWV1ZSh1bnNpZ25lZCBpZCwgY29uc3QgVHdpbmUgJm5hbWUpOiBJRChpZCksIE5hbWUobmFtZS5zdHIoKSkge30KKworICB1bnNpZ25lZCBnZXRJRCgpIGNvbnN0IHsgcmV0dXJuIElEOyB9CisKKyAgU3RyaW5nUmVmIGdldE5hbWUoKSBjb25zdCB7IHJldHVybiBOYW1lOyB9CisKKyAgLy8gU1UgaXMgaW4gdGhpcyBxdWV1ZSBpZiBpdCdzIE5vZGVRdWV1ZUlEIGlzIGEgc3VwZXJzZXQgb2YgdGhpcyBJRC4KKyAgYm9vbCBpc0luUXVldWUoU1VuaXQgKlNVKSBjb25zdCB7IHJldHVybiAoU1UtPk5vZGVRdWV1ZUlkICYgSUQpOyB9CisKKyAgYm9vbCBlbXB0eSgpIGNvbnN0IHsgcmV0dXJuIFF1ZXVlLmVtcHR5KCk7IH0KKworICB2b2lkIGNsZWFyKCkgeyBRdWV1ZS5jbGVhcigpOyB9CisKKyAgdW5zaWduZWQgc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIFF1ZXVlLnNpemUoKTsgfQorCisgIHVzaW5nIGl0ZXJhdG9yID0gc3RkOjp2ZWN0b3I8U1VuaXQqPjo6aXRlcmF0b3I7CisKKyAgaXRlcmF0b3IgYmVnaW4oKSB7IHJldHVybiBRdWV1ZS5iZWdpbigpOyB9CisKKyAgaXRlcmF0b3IgZW5kKCkgeyByZXR1cm4gUXVldWUuZW5kKCk7IH0KKworICBBcnJheVJlZjxTVW5pdCo+IGVsZW1lbnRzKCkgeyByZXR1cm4gUXVldWU7IH0KKworICBpdGVyYXRvciBmaW5kKFNVbml0ICpTVSkgeyByZXR1cm4gbGx2bTo6ZmluZChRdWV1ZSwgU1UpOyB9CisKKyAgdm9pZCBwdXNoKFNVbml0ICpTVSkgeworICAgIFF1ZXVlLnB1c2hfYmFjayhTVSk7CisgICAgU1UtPk5vZGVRdWV1ZUlkIHw9IElEOworICB9CisKKyAgaXRlcmF0b3IgcmVtb3ZlKGl0ZXJhdG9yIEkpIHsKKyAgICAoKkkpLT5Ob2RlUXVldWVJZCAmPSB+SUQ7CisgICAgKkkgPSBRdWV1ZS5iYWNrKCk7CisgICAgdW5zaWduZWQgaWR4ID0gSSAtIFF1ZXVlLmJlZ2luKCk7CisgICAgUXVldWUucG9wX2JhY2soKTsKKyAgICByZXR1cm4gUXVldWUuYmVnaW4oKSArIGlkeDsKKyAgfQorCisgIHZvaWQgZHVtcCgpIGNvbnN0OworfTsKKworLy8vIFN1bW1hcml6ZSB0aGUgdW5zY2hlZHVsZWQgcmVnaW9uLgorc3RydWN0IFNjaGVkUmVtYWluZGVyIHsKKyAgLy8gQ3JpdGljYWwgcGF0aCB0aHJvdWdoIHRoZSBEQUcgaW4gZXhwZWN0ZWQgbGF0ZW5jeS4KKyAgdW5zaWduZWQgQ3JpdGljYWxQYXRoOworICB1bnNpZ25lZCBDeWNsaWNDcml0UGF0aDsKKworICAvLyBTY2FsZWQgY291bnQgb2YgbWljcm8tb3BzIGxlZnQgdG8gc2NoZWR1bGUuCisgIHVuc2lnbmVkIFJlbUlzc3VlQ291bnQ7CisKKyAgYm9vbCBJc0FjeWNsaWNMYXRlbmN5TGltaXRlZDsKKworICAvLyBVbnNjaGVkdWxlZCByZXNvdXJjZXMKKyAgU21hbGxWZWN0b3I8dW5zaWduZWQsIDE2PiBSZW1haW5pbmdDb3VudHM7CisKKyAgU2NoZWRSZW1haW5kZXIoKSB7IHJlc2V0KCk7IH0KKworICB2b2lkIHJlc2V0KCkgeworICAgIENyaXRpY2FsUGF0aCA9IDA7CisgICAgQ3ljbGljQ3JpdFBhdGggPSAwOworICAgIFJlbUlzc3VlQ291bnQgPSAwOworICAgIElzQWN5Y2xpY0xhdGVuY3lMaW1pdGVkID0gZmFsc2U7CisgICAgUmVtYWluaW5nQ291bnRzLmNsZWFyKCk7CisgIH0KKworICB2b2lkIGluaXQoU2NoZWR1bGVEQUdNSSAqREFHLCBjb25zdCBUYXJnZXRTY2hlZE1vZGVsICpTY2hlZE1vZGVsKTsKK307CisKKy8vLyBFYWNoIFNjaGVkdWxpbmcgYm91bmRhcnkgaXMgYXNzb2NpYXRlZCB3aXRoIHJlYWR5IHF1ZXVlcy4gSXQgdHJhY2tzIHRoZQorLy8vIGN1cnJlbnQgY3ljbGUgaW4gdGhlIGRpcmVjdGlvbiBvZiBtb3ZlbWVudCwgYW5kIG1haW50YWlucyB0aGUgc3RhdGUKKy8vLyBvZiAiaGF6YXJkcyIgYW5kIG90aGVyIGludGVybG9ja3MgYXQgdGhlIGN1cnJlbnQgY3ljbGUuCitjbGFzcyBTY2hlZEJvdW5kYXJ5IHsKK3B1YmxpYzoKKyAgLy8vIFNVbml0OjpOb2RlUXVldWVJZDogMCAobm9uZSksIDEgKHRvcCksIDIgKGJvdCksIDMgKGJvdGgpCisgIGVudW0geworICAgIFRvcFFJRCA9IDEsCisgICAgQm90UUlEID0gMiwKKyAgICBMb2dNYXhRSUQgPSAyCisgIH07CisKKyAgU2NoZWR1bGVEQUdNSSAqREFHID0gbnVsbHB0cjsKKyAgY29uc3QgVGFyZ2V0U2NoZWRNb2RlbCAqU2NoZWRNb2RlbCA9IG51bGxwdHI7CisgIFNjaGVkUmVtYWluZGVyICpSZW0gPSBudWxscHRyOworCisgIFJlYWR5UXVldWUgQXZhaWxhYmxlOworICBSZWFkeVF1ZXVlIFBlbmRpbmc7CisKKyAgU2NoZWR1bGVIYXphcmRSZWNvZ25pemVyICpIYXphcmRSZWMgPSBudWxscHRyOworCitwcml2YXRlOgorICAvLy8gVHJ1ZSBpZiB0aGUgcGVuZGluZyBRIHNob3VsZCBiZSBjaGVja2VkL3VwZGF0ZWQgYmVmb3JlIHNjaGVkdWxpbmcgYW5vdGhlcgorICAvLy8gaW5zdHJ1Y3Rpb24uCisgIGJvb2wgQ2hlY2tQZW5kaW5nOworCisgIC8vLyBOdW1iZXIgb2YgY3ljbGVzIGl0IHRha2VzIHRvIGlzc3VlIHRoZSBpbnN0cnVjdGlvbnMgc2NoZWR1bGVkIGluIHRoaXMKKyAgLy8vIHpvbmUuIEl0IGlzIGRlZmluZWQgYXM6IHNjaGVkdWxlZC1taWNyby1vcHMgLyBpc3N1ZS13aWR0aCArIHN0YWxscy4KKyAgLy8vIFNlZSBnZXRTdGFsbHMoKS4KKyAgdW5zaWduZWQgQ3VyckN5Y2xlOworCisgIC8vLyBNaWNyby1vcHMgaXNzdWVkIGluIHRoZSBjdXJyZW50IGN5Y2xlCisgIHVuc2lnbmVkIEN1cnJNT3BzOworCisgIC8vLyBNaW5SZWFkeUN5Y2xlIC0gQ3ljbGUgb2YgdGhlIHNvb25lc3QgYXZhaWxhYmxlIGluc3RydWN0aW9uLgorICB1bnNpZ25lZCBNaW5SZWFkeUN5Y2xlOworCisgIC8vIFRoZSBleHBlY3RlZCBsYXRlbmN5IG9mIHRoZSBjcml0aWNhbCBwYXRoIGluIHRoaXMgc2NoZWR1bGVkIHpvbmUuCisgIHVuc2lnbmVkIEV4cGVjdGVkTGF0ZW5jeTsKKworICAvLyBUaGUgbGF0ZW5jeSBvZiBkZXBlbmRlbmNlIGNoYWlucyBsZWFkaW5nIGludG8gdGhpcyB6b25lLgorICAvLyBGb3IgZWFjaCBub2RlIHNjaGVkdWxlZCBib3R0b20tdXA6IERMYXQgPSBtYXggRExhdCwgTi5EZXB0aC4KKyAgLy8gRm9yIGVhY2ggY3ljbGUgc2NoZWR1bGVkOiBETGF0IC09IDEuCisgIHVuc2lnbmVkIERlcGVuZGVudExhdGVuY3k7CisKKyAgLy8vIENvdW50IHRoZSBzY2hlZHVsZWQgKGlzc3VlZCkgbWljcm8tb3BzIHRoYXQgY2FuIGJlIHJldGlyZWQgYnkKKyAgLy8vIHRpbWU9Q3VyckN5Y2xlIGFzc3VtaW5nIHRoZSBmaXJzdCBzY2hlZHVsZWQgaW5zdHIgaXMgcmV0aXJlZCBhdCB0aW1lPTAuCisgIHVuc2lnbmVkIFJldGlyZWRNT3BzOworCisgIC8vIENvdW50IHNjaGVkdWxlZCByZXNvdXJjZXMgdGhhdCBoYXZlIGJlZW4gZXhlY3V0ZWQuIFJlc291cmNlcyBhcmUKKyAgLy8gY29uc2lkZXJlZCBleGVjdXRlZCBpZiB0aGV5IGJlY29tZSByZWFkeSBpbiB0aGUgdGltZSB0aGF0IGl0IHRha2VzIHRvCisgIC8vIHNhdHVyYXRlIGFueSByZXNvdXJjZSBpbmNsdWRpbmcgdGhlIG9uZSBpbiBxdWVzdGlvbi4gQ291bnRzIGFyZSBzY2FsZWQKKyAgLy8gZm9yIGRpcmVjdCBjb21wYXJpc29uIHdpdGggb3RoZXIgcmVzb3VyY2VzLiBDb3VudHMgY2FuIGJlIGNvbXBhcmVkIHdpdGgKKyAgLy8gTU9wcyAqIGdldE1pY3JvT3BGYWN0b3IgYW5kIExhdGVuY3kgKiBnZXRMYXRlbmN5RmFjdG9yLgorICBTbWFsbFZlY3Rvcjx1bnNpZ25lZCwgMTY+IEV4ZWN1dGVkUmVzQ291bnRzOworCisgIC8vLyBDYWNoZSB0aGUgbWF4IGNvdW50IGZvciBhIHNpbmdsZSByZXNvdXJjZS4KKyAgdW5zaWduZWQgTWF4RXhlY3V0ZWRSZXNDb3VudDsKKworICAvLyBDYWNoZSB0aGUgY3JpdGljYWwgcmVzb3VyY2VzIElEIGluIHRoaXMgc2NoZWR1bGVkIHpvbmUuCisgIHVuc2lnbmVkIFpvbmVDcml0UmVzSWR4OworCisgIC8vIElzIHRoZSBzY2hlZHVsZWQgcmVnaW9uIHJlc291cmNlIGxpbWl0ZWQgdnMuIGxhdGVuY3kgbGltaXRlZC4KKyAgYm9vbCBJc1Jlc291cmNlTGltaXRlZDsKKworICAvLyBSZWNvcmQgdGhlIGhpZ2hlc3QgY3ljbGUgYXQgd2hpY2ggZWFjaCByZXNvdXJjZSBoYXMgYmVlbiByZXNlcnZlZCBieSBhCisgIC8vIHNjaGVkdWxlZCBpbnN0cnVjdGlvbi4KKyAgU21hbGxWZWN0b3I8dW5zaWduZWQsIDE2PiBSZXNlcnZlZEN5Y2xlczsKKworI2lmbmRlZiBOREVCVUcKKyAgLy8gUmVtZW1iZXIgdGhlIGdyZWF0ZXN0IHBvc3NpYmxlIHN0YWxsIGFzIGFuIHVwcGVyIGJvdW5kIG9uIHRoZSBudW1iZXIgb2YKKyAgLy8gdGltZXMgd2Ugc2hvdWxkIHJldHJ5IHRoZSBwZW5kaW5nIHF1ZXVlIGJlY2F1c2Ugb2YgYSBoYXphcmQuCisgIHVuc2lnbmVkIE1heE9ic2VydmVkU3RhbGw7CisjZW5kaWYKKworcHVibGljOgorICAvLy8gUGVuZGluZyBxdWV1ZXMgZXh0ZW5kIHRoZSByZWFkeSBxdWV1ZXMgd2l0aCB0aGUgc2FtZSBJRCBhbmQgdGhlCisgIC8vLyBQZW5kaW5nRmxhZyBzZXQuCisgIFNjaGVkQm91bmRhcnkodW5zaWduZWQgSUQsIGNvbnN0IFR3aW5lICZOYW1lKToKKyAgICBBdmFpbGFibGUoSUQsIE5hbWUrIi5BIiksIFBlbmRpbmcoSUQgPDwgTG9nTWF4UUlELCBOYW1lKyIuUCIpIHsKKyAgICByZXNldCgpOworICB9CisKKyAgflNjaGVkQm91bmRhcnkoKTsKKworICB2b2lkIHJlc2V0KCk7CisKKyAgdm9pZCBpbml0KFNjaGVkdWxlREFHTUkgKmRhZywgY29uc3QgVGFyZ2V0U2NoZWRNb2RlbCAqc21vZGVsLAorICAgICAgICAgICAgU2NoZWRSZW1haW5kZXIgKnJlbSk7CisKKyAgYm9vbCBpc1RvcCgpIGNvbnN0IHsKKyAgICByZXR1cm4gQXZhaWxhYmxlLmdldElEKCkgPT0gVG9wUUlEOworICB9CisKKyAgLy8vIE51bWJlciBvZiBjeWNsZXMgdG8gaXNzdWUgdGhlIGluc3RydWN0aW9ucyBzY2hlZHVsZWQgaW4gdGhpcyB6b25lLgorICB1bnNpZ25lZCBnZXRDdXJyQ3ljbGUoKSBjb25zdCB7IHJldHVybiBDdXJyQ3ljbGU7IH0KKworICAvLy8gTWljcm8tb3BzIGlzc3VlZCBpbiB0aGUgY3VycmVudCBjeWNsZQorICB1bnNpZ25lZCBnZXRDdXJyTU9wcygpIGNvbnN0IHsgcmV0dXJuIEN1cnJNT3BzOyB9CisKKyAgLy8gVGhlIGxhdGVuY3kgb2YgZGVwZW5kZW5jZSBjaGFpbnMgbGVhZGluZyBpbnRvIHRoaXMgem9uZS4KKyAgdW5zaWduZWQgZ2V0RGVwZW5kZW50TGF0ZW5jeSgpIGNvbnN0IHsgcmV0dXJuIERlcGVuZGVudExhdGVuY3k7IH0KKworICAvLy8gR2V0IHRoZSBudW1iZXIgb2YgbGF0ZW5jeSBjeWNsZXMgImNvdmVyZWQiIGJ5IHRoZSBzY2hlZHVsZWQKKyAgLy8vIGluc3RydWN0aW9ucy4gVGhpcyBpcyB0aGUgbGFyZ2VyIG9mIHRoZSBjcml0aWNhbCBwYXRoIHdpdGhpbiB0aGUgem9uZQorICAvLy8gYW5kIHRoZSBudW1iZXIgb2YgY3ljbGVzIHJlcXVpcmVkIHRvIGlzc3VlIHRoZSBpbnN0cnVjdGlvbnMuCisgIHVuc2lnbmVkIGdldFNjaGVkdWxlZExhdGVuY3koKSBjb25zdCB7CisgICAgcmV0dXJuIHN0ZDo6bWF4KEV4cGVjdGVkTGF0ZW5jeSwgQ3VyckN5Y2xlKTsKKyAgfQorCisgIHVuc2lnbmVkIGdldFVuc2NoZWR1bGVkTGF0ZW5jeShTVW5pdCAqU1UpIGNvbnN0IHsKKyAgICByZXR1cm4gaXNUb3AoKSA/IFNVLT5nZXRIZWlnaHQoKSA6IFNVLT5nZXREZXB0aCgpOworICB9CisKKyAgdW5zaWduZWQgZ2V0UmVzb3VyY2VDb3VudCh1bnNpZ25lZCBSZXNJZHgpIGNvbnN0IHsKKyAgICByZXR1cm4gRXhlY3V0ZWRSZXNDb3VudHNbUmVzSWR4XTsKKyAgfQorCisgIC8vLyBHZXQgdGhlIHNjYWxlZCBjb3VudCBvZiBzY2hlZHVsZWQgbWljcm8tb3BzIGFuZCByZXNvdXJjZXMsIGluY2x1ZGluZworICAvLy8gZXhlY3V0ZWQgcmVzb3VyY2VzLgorICB1bnNpZ25lZCBnZXRDcml0aWNhbENvdW50KCkgY29uc3QgeworICAgIGlmICghWm9uZUNyaXRSZXNJZHgpCisgICAgICByZXR1cm4gUmV0aXJlZE1PcHMgKiBTY2hlZE1vZGVsLT5nZXRNaWNyb09wRmFjdG9yKCk7CisgICAgcmV0dXJuIGdldFJlc291cmNlQ291bnQoWm9uZUNyaXRSZXNJZHgpOworICB9CisKKyAgLy8vIEdldCBhIHNjYWxlZCBjb3VudCBmb3IgdGhlIG1pbmltdW0gZXhlY3V0aW9uIHRpbWUgb2YgdGhlIHNjaGVkdWxlZAorICAvLy8gbWljcm8tb3BzIHRoYXQgYXJlIHJlYWR5IHRvIGV4ZWN1dGUgYnkgZ2V0RXhlY3V0ZWRDb3VudC4gTm90aWNlIHRoZQorICAvLy8gZmVlZGJhY2sgbG9vcC4KKyAgdW5zaWduZWQgZ2V0RXhlY3V0ZWRDb3VudCgpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RkOjptYXgoQ3VyckN5Y2xlICogU2NoZWRNb2RlbC0+Z2V0TGF0ZW5jeUZhY3RvcigpLAorICAgICAgICAgICAgICAgICAgICBNYXhFeGVjdXRlZFJlc0NvdW50KTsKKyAgfQorCisgIHVuc2lnbmVkIGdldFpvbmVDcml0UmVzSWR4KCkgY29uc3QgeyByZXR1cm4gWm9uZUNyaXRSZXNJZHg7IH0KKworICAvLyBJcyB0aGUgc2NoZWR1bGVkIHJlZ2lvbiByZXNvdXJjZSBsaW1pdGVkIHZzLiBsYXRlbmN5IGxpbWl0ZWQuCisgIGJvb2wgaXNSZXNvdXJjZUxpbWl0ZWQoKSBjb25zdCB7IHJldHVybiBJc1Jlc291cmNlTGltaXRlZDsgfQorCisgIC8vLyBHZXQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgZ2l2ZW4gU1VuaXQncyByZWFkeSB0aW1lIGFuZCB0aGUgY3VycmVudAorICAvLy8gY3ljbGUuCisgIHVuc2lnbmVkIGdldExhdGVuY3lTdGFsbEN5Y2xlcyhTVW5pdCAqU1UpOworCisgIHVuc2lnbmVkIGdldE5leHRSZXNvdXJjZUN5Y2xlKHVuc2lnbmVkIFBJZHgsIHVuc2lnbmVkIEN5Y2xlcyk7CisKKyAgYm9vbCBjaGVja0hhemFyZChTVW5pdCAqU1UpOworCisgIHVuc2lnbmVkIGZpbmRNYXhMYXRlbmN5KEFycmF5UmVmPFNVbml0Kj4gUmVhZHlTVXMpOworCisgIHVuc2lnbmVkIGdldE90aGVyUmVzb3VyY2VDb3VudCh1bnNpZ25lZCAmT3RoZXJDcml0SWR4KTsKKworICB2b2lkIHJlbGVhc2VOb2RlKFNVbml0ICpTVSwgdW5zaWduZWQgUmVhZHlDeWNsZSk7CisKKyAgdm9pZCBidW1wQ3ljbGUodW5zaWduZWQgTmV4dEN5Y2xlKTsKKworICB2b2lkIGluY0V4ZWN1dGVkUmVzb3VyY2VzKHVuc2lnbmVkIFBJZHgsIHVuc2lnbmVkIENvdW50KTsKKworICB1bnNpZ25lZCBjb3VudFJlc291cmNlKHVuc2lnbmVkIFBJZHgsIHVuc2lnbmVkIEN5Y2xlcywgdW5zaWduZWQgUmVhZHlDeWNsZSk7CisKKyAgdm9pZCBidW1wTm9kZShTVW5pdCAqU1UpOworCisgIHZvaWQgcmVsZWFzZVBlbmRpbmcoKTsKKworICB2b2lkIHJlbW92ZVJlYWR5KFNVbml0ICpTVSk7CisKKyAgLy8vIENhbGwgdGhpcyBiZWZvcmUgYXBwbHlpbmcgYW55IG90aGVyIGhldXJpc3RpY3MgdG8gdGhlIEF2YWlsYWJsZSBxdWV1ZS4KKyAgLy8vIFVwZGF0ZXMgdGhlIEF2YWlsYWJsZS9QZW5kaW5nIFEncyBpZiBuZWNlc3NhcnkgYW5kIHJldHVybnMgdGhlIHNpbmdsZQorICAvLy8gYXZhaWxhYmxlIGluc3RydWN0aW9uLCBvciBOVUxMIGlmIHRoZXJlIGFyZSBtdWx0aXBsZSBjYW5kaWRhdGVzLgorICBTVW5pdCAqcGlja09ubHlDaG9pY2UoKTsKKworICB2b2lkIGR1bXBTY2hlZHVsZWRTdGF0ZSgpIGNvbnN0OworfTsKKworLy8vIEJhc2UgY2xhc3MgZm9yIEdlbmVyaWNTY2hlZHVsZXIuIFRoaXMgY2xhc3MgbWFpbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0CisvLy8gc2NoZWR1bGluZyBjYW5kaWRhdGVzIGJhc2VkIG9uIFRhcmdldFNjaGVkTW9kZWwgbWFraW5nIGl0IGVhc3kgdG8gaW1wbGVtZW50CisvLy8gaGV1cmlzdGljcyBmb3IgZWl0aGVyIHByZVJBIG9yIHBvc3RSQSBzY2hlZHVsaW5nLgorY2xhc3MgR2VuZXJpY1NjaGVkdWxlckJhc2UgOiBwdWJsaWMgTWFjaGluZVNjaGVkU3RyYXRlZ3kgeworcHVibGljOgorICAvLy8gUmVwcmVzZW50IHRoZSB0eXBlIG9mIFNjaGVkQ2FuZGlkYXRlIGZvdW5kIHdpdGhpbiBhIHNpbmdsZSBxdWV1ZS4KKyAgLy8vIHBpY2tOb2RlQmlkaXJlY3Rpb25hbCBkZXBlbmRzIG9uIHRoZXNlIGxpc3RlZCBieSBkZWNyZWFzaW5nIHByaW9yaXR5LgorICBlbnVtIENhbmRSZWFzb24gOiB1aW50OF90IHsKKyAgICBOb0NhbmQsIE9ubHkxLCBQaHlzUmVnQ29weSwgUmVnRXhjZXNzLCBSZWdDcml0aWNhbCwgU3RhbGwsIENsdXN0ZXIsIFdlYWssCisgICAgUmVnTWF4LCBSZXNvdXJjZVJlZHVjZSwgUmVzb3VyY2VEZW1hbmQsIEJvdEhlaWdodFJlZHVjZSwgQm90UGF0aFJlZHVjZSwKKyAgICBUb3BEZXB0aFJlZHVjZSwgVG9wUGF0aFJlZHVjZSwgTmV4dERlZlVzZSwgTm9kZU9yZGVyfTsKKworI2lmbmRlZiBOREVCVUcKKyAgc3RhdGljIGNvbnN0IGNoYXIgKmdldFJlYXNvblN0cihHZW5lcmljU2NoZWR1bGVyQmFzZTo6Q2FuZFJlYXNvbiBSZWFzb24pOworI2VuZGlmCisKKyAgLy8vIFBvbGljeSBmb3Igc2NoZWR1bGluZyB0aGUgbmV4dCBpbnN0cnVjdGlvbiBpbiB0aGUgY2FuZGlkYXRlJ3Mgem9uZS4KKyAgc3RydWN0IENhbmRQb2xpY3kgeworICAgIGJvb2wgUmVkdWNlTGF0ZW5jeSA9IGZhbHNlOworICAgIHVuc2lnbmVkIFJlZHVjZVJlc0lkeCA9IDA7CisgICAgdW5zaWduZWQgRGVtYW5kUmVzSWR4ID0gMDsKKworICAgIENhbmRQb2xpY3koKSA9IGRlZmF1bHQ7CisKKyAgICBib29sIG9wZXJhdG9yPT0oY29uc3QgQ2FuZFBvbGljeSAmUkhTKSBjb25zdCB7CisgICAgICByZXR1cm4gUmVkdWNlTGF0ZW5jeSA9PSBSSFMuUmVkdWNlTGF0ZW5jeSAmJgorICAgICAgICAgICAgIFJlZHVjZVJlc0lkeCA9PSBSSFMuUmVkdWNlUmVzSWR4ICYmCisgICAgICAgICAgICAgRGVtYW5kUmVzSWR4ID09IFJIUy5EZW1hbmRSZXNJZHg7CisgICAgfQorICAgIGJvb2wgb3BlcmF0b3IhPShjb25zdCBDYW5kUG9saWN5ICZSSFMpIGNvbnN0IHsKKyAgICAgIHJldHVybiAhKCp0aGlzID09IFJIUyk7CisgICAgfQorICB9OworCisgIC8vLyBTdGF0dXMgb2YgYW4gaW5zdHJ1Y3Rpb24ncyBjcml0aWNhbCByZXNvdXJjZSBjb25zdW1wdGlvbi4KKyAgc3RydWN0IFNjaGVkUmVzb3VyY2VEZWx0YSB7CisgICAgLy8gQ291bnQgY3JpdGljYWwgcmVzb3VyY2VzIGluIHRoZSBzY2hlZHVsZWQgcmVnaW9uIHJlcXVpcmVkIGJ5IFNVLgorICAgIHVuc2lnbmVkIENyaXRSZXNvdXJjZXMgPSAwOworCisgICAgLy8gQ291bnQgY3JpdGljYWwgcmVzb3VyY2VzIGZyb20gYW5vdGhlciByZWdpb24gY29uc3VtZWQgYnkgU1UuCisgICAgdW5zaWduZWQgRGVtYW5kZWRSZXNvdXJjZXMgPSAwOworCisgICAgU2NoZWRSZXNvdXJjZURlbHRhKCkgPSBkZWZhdWx0OworCisgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IFNjaGVkUmVzb3VyY2VEZWx0YSAmUkhTKSBjb25zdCB7CisgICAgICByZXR1cm4gQ3JpdFJlc291cmNlcyA9PSBSSFMuQ3JpdFJlc291cmNlcworICAgICAgICAmJiBEZW1hbmRlZFJlc291cmNlcyA9PSBSSFMuRGVtYW5kZWRSZXNvdXJjZXM7CisgICAgfQorICAgIGJvb2wgb3BlcmF0b3IhPShjb25zdCBTY2hlZFJlc291cmNlRGVsdGEgJlJIUykgY29uc3QgeworICAgICAgcmV0dXJuICFvcGVyYXRvcj09KFJIUyk7CisgICAgfQorICB9OworCisgIC8vLyBTdG9yZSB0aGUgc3RhdGUgdXNlZCBieSBHZW5lcmljU2NoZWR1bGVyIGhldXJpc3RpY3MsIHJlcXVpcmVkIGZvciB0aGUKKyAgLy8vIGxpZmV0aW1lIG9mIG9uZSBpbnZvY2F0aW9uIG9mIHBpY2tOb2RlKCkuCisgIHN0cnVjdCBTY2hlZENhbmRpZGF0ZSB7CisgICAgQ2FuZFBvbGljeSBQb2xpY3k7CisKKyAgICAvLyBUaGUgYmVzdCBTVW5pdCBjYW5kaWRhdGUuCisgICAgU1VuaXQgKlNVOworCisgICAgLy8gVGhlIHJlYXNvbiBmb3IgdGhpcyBjYW5kaWRhdGUuCisgICAgQ2FuZFJlYXNvbiBSZWFzb247CisKKyAgICAvLyBXaGV0aGVyIHRoaXMgY2FuZGlkYXRlIHNob3VsZCBiZSBzY2hlZHVsZWQgYXQgdG9wL2JvdHRvbS4KKyAgICBib29sIEF0VG9wOworCisgICAgLy8gUmVnaXN0ZXIgcHJlc3N1cmUgdmFsdWVzIGZvciB0aGUgYmVzdCBjYW5kaWRhdGUuCisgICAgUmVnUHJlc3N1cmVEZWx0YSBSUERlbHRhOworCisgICAgLy8gQ3JpdGljYWwgcmVzb3VyY2UgY29uc3VtcHRpb24gb2YgdGhlIGJlc3QgY2FuZGlkYXRlLgorICAgIFNjaGVkUmVzb3VyY2VEZWx0YSBSZXNEZWx0YTsKKworICAgIFNjaGVkQ2FuZGlkYXRlKCkgeyByZXNldChDYW5kUG9saWN5KCkpOyB9CisgICAgU2NoZWRDYW5kaWRhdGUoY29uc3QgQ2FuZFBvbGljeSAmUG9saWN5KSB7IHJlc2V0KFBvbGljeSk7IH0KKworICAgIHZvaWQgcmVzZXQoY29uc3QgQ2FuZFBvbGljeSAmTmV3UG9saWN5KSB7CisgICAgICBQb2xpY3kgPSBOZXdQb2xpY3k7CisgICAgICBTVSA9IG51bGxwdHI7CisgICAgICBSZWFzb24gPSBOb0NhbmQ7CisgICAgICBBdFRvcCA9IGZhbHNlOworICAgICAgUlBEZWx0YSA9IFJlZ1ByZXNzdXJlRGVsdGEoKTsKKyAgICAgIFJlc0RlbHRhID0gU2NoZWRSZXNvdXJjZURlbHRhKCk7CisgICAgfQorCisgICAgYm9vbCBpc1ZhbGlkKCkgY29uc3QgeyByZXR1cm4gU1U7IH0KKworICAgIC8vIENvcHkgdGhlIHN0YXR1cyBvZiBhbm90aGVyIGNhbmRpZGF0ZSB3aXRob3V0IGNoYW5naW5nIHBvbGljeS4KKyAgICB2b2lkIHNldEJlc3QoU2NoZWRDYW5kaWRhdGUgJkJlc3QpIHsKKyAgICAgIGFzc2VydChCZXN0LlJlYXNvbiAhPSBOb0NhbmQgJiYgInVuaW5pdGlhbGl6ZWQgU2NoZWQgY2FuZGlkYXRlIik7CisgICAgICBTVSA9IEJlc3QuU1U7CisgICAgICBSZWFzb24gPSBCZXN0LlJlYXNvbjsKKyAgICAgIEF0VG9wID0gQmVzdC5BdFRvcDsKKyAgICAgIFJQRGVsdGEgPSBCZXN0LlJQRGVsdGE7CisgICAgICBSZXNEZWx0YSA9IEJlc3QuUmVzRGVsdGE7CisgICAgfQorCisgICAgdm9pZCBpbml0UmVzb3VyY2VEZWx0YShjb25zdCBTY2hlZHVsZURBR01JICpEQUcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRTY2hlZE1vZGVsICpTY2hlZE1vZGVsKTsKKyAgfTsKKworcHJvdGVjdGVkOgorICBjb25zdCBNYWNoaW5lU2NoZWRDb250ZXh0ICpDb250ZXh0OworICBjb25zdCBUYXJnZXRTY2hlZE1vZGVsICpTY2hlZE1vZGVsID0gbnVsbHB0cjsKKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkgPSBudWxscHRyOworCisgIFNjaGVkUmVtYWluZGVyIFJlbTsKKworICBHZW5lcmljU2NoZWR1bGVyQmFzZShjb25zdCBNYWNoaW5lU2NoZWRDb250ZXh0ICpDKSA6IENvbnRleHQoQykge30KKworICB2b2lkIHNldFBvbGljeShDYW5kUG9saWN5ICZQb2xpY3ksIGJvb2wgSXNQb3N0UkEsIFNjaGVkQm91bmRhcnkgJkN1cnJab25lLAorICAgICAgICAgICAgICAgICBTY2hlZEJvdW5kYXJ5ICpPdGhlclpvbmUpOworCisjaWZuZGVmIE5ERUJVRworICB2b2lkIHRyYWNlQ2FuZGlkYXRlKGNvbnN0IFNjaGVkQ2FuZGlkYXRlICZDYW5kKTsKKyNlbmRpZgorfTsKKworLy8vIEdlbmVyaWNTY2hlZHVsZXIgc2hyaW5rcyB0aGUgdW5zY2hlZHVsZWQgem9uZSB1c2luZyBoZXVyaXN0aWNzIHRvIGJhbGFuY2UKKy8vLyB0aGUgc2NoZWR1bGUuCitjbGFzcyBHZW5lcmljU2NoZWR1bGVyIDogcHVibGljIEdlbmVyaWNTY2hlZHVsZXJCYXNlIHsKK3B1YmxpYzoKKyAgR2VuZXJpY1NjaGVkdWxlcihjb25zdCBNYWNoaW5lU2NoZWRDb250ZXh0ICpDKToKKyAgICBHZW5lcmljU2NoZWR1bGVyQmFzZShDKSwgVG9wKFNjaGVkQm91bmRhcnk6OlRvcFFJRCwgIlRvcFEiKSwKKyAgICBCb3QoU2NoZWRCb3VuZGFyeTo6Qm90UUlELCAiQm90USIpIHt9CisKKyAgdm9pZCBpbml0UG9saWN5KE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBCZWdpbiwKKyAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBFbmQsCisgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBOdW1SZWdpb25JbnN0cnMpIG92ZXJyaWRlOworCisgIHZvaWQgZHVtcFBvbGljeSgpIGNvbnN0IG92ZXJyaWRlOworCisgIGJvb2wgc2hvdWxkVHJhY2tQcmVzc3VyZSgpIGNvbnN0IG92ZXJyaWRlIHsKKyAgICByZXR1cm4gUmVnaW9uUG9saWN5LlNob3VsZFRyYWNrUHJlc3N1cmU7CisgIH0KKworICBib29sIHNob3VsZFRyYWNrTGFuZU1hc2tzKCkgY29uc3Qgb3ZlcnJpZGUgeworICAgIHJldHVybiBSZWdpb25Qb2xpY3kuU2hvdWxkVHJhY2tMYW5lTWFza3M7CisgIH0KKworICB2b2lkIGluaXRpYWxpemUoU2NoZWR1bGVEQUdNSSAqZGFnKSBvdmVycmlkZTsKKworICBTVW5pdCAqcGlja05vZGUoYm9vbCAmSXNUb3BOb2RlKSBvdmVycmlkZTsKKworICB2b2lkIHNjaGVkTm9kZShTVW5pdCAqU1UsIGJvb2wgSXNUb3BOb2RlKSBvdmVycmlkZTsKKworICB2b2lkIHJlbGVhc2VUb3BOb2RlKFNVbml0ICpTVSkgb3ZlcnJpZGUgeworICAgIGlmIChTVS0+aXNTY2hlZHVsZWQpCisgICAgICByZXR1cm47CisKKyAgICBUb3AucmVsZWFzZU5vZGUoU1UsIFNVLT5Ub3BSZWFkeUN5Y2xlKTsKKyAgICBUb3BDYW5kLlNVID0gbnVsbHB0cjsKKyAgfQorCisgIHZvaWQgcmVsZWFzZUJvdHRvbU5vZGUoU1VuaXQgKlNVKSBvdmVycmlkZSB7CisgICAgaWYgKFNVLT5pc1NjaGVkdWxlZCkKKyAgICAgIHJldHVybjsKKworICAgIEJvdC5yZWxlYXNlTm9kZShTVSwgU1UtPkJvdFJlYWR5Q3ljbGUpOworICAgIEJvdENhbmQuU1UgPSBudWxscHRyOworICB9CisKKyAgdm9pZCByZWdpc3RlclJvb3RzKCkgb3ZlcnJpZGU7CisKK3Byb3RlY3RlZDoKKyAgU2NoZWR1bGVEQUdNSUxpdmUgKkRBRyA9IG51bGxwdHI7CisKKyAgTWFjaGluZVNjaGVkUG9saWN5IFJlZ2lvblBvbGljeTsKKworICAvLyBTdGF0ZSBvZiB0aGUgdG9wIGFuZCBib3R0b20gc2NoZWR1bGVkIGluc3RydWN0aW9uIGJvdW5kYXJpZXMuCisgIFNjaGVkQm91bmRhcnkgVG9wOworICBTY2hlZEJvdW5kYXJ5IEJvdDsKKworICAvLy8gQ2FuZGlkYXRlIGxhc3QgcGlja2VkIGZyb20gVG9wIGJvdW5kYXJ5LgorICBTY2hlZENhbmRpZGF0ZSBUb3BDYW5kOworICAvLy8gQ2FuZGlkYXRlIGxhc3QgcGlja2VkIGZyb20gQm90IGJvdW5kYXJ5LgorICBTY2hlZENhbmRpZGF0ZSBCb3RDYW5kOworCisgIHZvaWQgY2hlY2tBY3ljbGljTGF0ZW5jeSgpOworCisgIHZvaWQgaW5pdENhbmRpZGF0ZShTY2hlZENhbmRpZGF0ZSAmQ2FuZCwgU1VuaXQgKlNVLCBib29sIEF0VG9wLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVnUHJlc3N1cmVUcmFja2VyICZSUFRyYWNrZXIsCisgICAgICAgICAgICAgICAgICAgICBSZWdQcmVzc3VyZVRyYWNrZXIgJlRlbXBUcmFja2VyKTsKKworICB2b2lkIHRyeUNhbmRpZGF0ZShTY2hlZENhbmRpZGF0ZSAmQ2FuZCwKKyAgICAgICAgICAgICAgICAgICAgU2NoZWRDYW5kaWRhdGUgJlRyeUNhbmQsCisgICAgICAgICAgICAgICAgICAgIFNjaGVkQm91bmRhcnkgKlpvbmUpOworCisgIFNVbml0ICpwaWNrTm9kZUJpZGlyZWN0aW9uYWwoYm9vbCAmSXNUb3BOb2RlKTsKKworICB2b2lkIHBpY2tOb2RlRnJvbVF1ZXVlKFNjaGVkQm91bmRhcnkgJlpvbmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ2FuZFBvbGljeSAmWm9uZVBvbGljeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSZWdQcmVzc3VyZVRyYWNrZXIgJlJQVHJhY2tlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBTY2hlZENhbmRpZGF0ZSAmQ2FuZGlkYXRlKTsKKworICB2b2lkIHJlc2NoZWR1bGVQaHlzUmVnQ29waWVzKFNVbml0ICpTVSwgYm9vbCBpc1RvcCk7Cit9OworCisvLy8gUG9zdEdlbmVyaWNTY2hlZHVsZXIgLSBJbnRlcmZhY2UgdG8gdGhlIHNjaGVkdWxpbmcgYWxnb3JpdGhtIHVzZWQgYnkKKy8vLyBTY2hlZHVsZURBR01JLgorLy8vCisvLy8gQ2FsbGJhY2tzIGZyb20gU2NoZWR1bGVEQUdNSToKKy8vLyAgIGluaXRQb2xpY3kgLT4gaW5pdGlhbGl6ZShEQUcpIC0+IHJlZ2lzdGVyUm9vdHMgLT4gcGlja05vZGUgLi4uCitjbGFzcyBQb3N0R2VuZXJpY1NjaGVkdWxlciA6IHB1YmxpYyBHZW5lcmljU2NoZWR1bGVyQmFzZSB7CisgIFNjaGVkdWxlREFHTUkgKkRBRzsKKyAgU2NoZWRCb3VuZGFyeSBUb3A7CisgIFNtYWxsVmVjdG9yPFNVbml0KiwgOD4gQm90Um9vdHM7CisKK3B1YmxpYzoKKyAgUG9zdEdlbmVyaWNTY2hlZHVsZXIoY29uc3QgTWFjaGluZVNjaGVkQ29udGV4dCAqQyk6CisgICAgR2VuZXJpY1NjaGVkdWxlckJhc2UoQyksIFRvcChTY2hlZEJvdW5kYXJ5OjpUb3BRSUQsICJUb3BRIikge30KKworICB+UG9zdEdlbmVyaWNTY2hlZHVsZXIoKSBvdmVycmlkZSA9IGRlZmF1bHQ7CisKKyAgdm9pZCBpbml0UG9saWN5KE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBCZWdpbiwKKyAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBFbmQsCisgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBOdW1SZWdpb25JbnN0cnMpIG92ZXJyaWRlIHsKKyAgICAvKiBubyBjb25maWd1cmFibGUgcG9saWN5ICovCisgIH0KKworICAvLy8gUG9zdFJBIHNjaGVkdWxpbmcgZG9lcyBub3QgdHJhY2sgcHJlc3N1cmUuCisgIGJvb2wgc2hvdWxkVHJhY2tQcmVzc3VyZSgpIGNvbnN0IG92ZXJyaWRlIHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgdm9pZCBpbml0aWFsaXplKFNjaGVkdWxlREFHTUkgKkRhZykgb3ZlcnJpZGU7CisKKyAgdm9pZCByZWdpc3RlclJvb3RzKCkgb3ZlcnJpZGU7CisKKyAgU1VuaXQgKnBpY2tOb2RlKGJvb2wgJklzVG9wTm9kZSkgb3ZlcnJpZGU7CisKKyAgdm9pZCBzY2hlZHVsZVRyZWUodW5zaWduZWQgU3VidHJlZUlEKSBvdmVycmlkZSB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgiUG9zdFJBIHNjaGVkdWxlciBkb2VzIG5vdCBzdXBwb3J0IHN1YnRyZWUgYW5hbHlzaXMuIik7CisgIH0KKworICB2b2lkIHNjaGVkTm9kZShTVW5pdCAqU1UsIGJvb2wgSXNUb3BOb2RlKSBvdmVycmlkZTsKKworICB2b2lkIHJlbGVhc2VUb3BOb2RlKFNVbml0ICpTVSkgb3ZlcnJpZGUgeworICAgIGlmIChTVS0+aXNTY2hlZHVsZWQpCisgICAgICByZXR1cm47CisgICAgVG9wLnJlbGVhc2VOb2RlKFNVLCBTVS0+VG9wUmVhZHlDeWNsZSk7CisgIH0KKworICAvLyBPbmx5IGNhbGxlZCBmb3Igcm9vdHMuCisgIHZvaWQgcmVsZWFzZUJvdHRvbU5vZGUoU1VuaXQgKlNVKSBvdmVycmlkZSB7CisgICAgQm90Um9vdHMucHVzaF9iYWNrKFNVKTsKKyAgfQorCitwcm90ZWN0ZWQ6CisgIHZvaWQgdHJ5Q2FuZGlkYXRlKFNjaGVkQ2FuZGlkYXRlICZDYW5kLCBTY2hlZENhbmRpZGF0ZSAmVHJ5Q2FuZCk7CisKKyAgdm9pZCBwaWNrTm9kZUZyb21RdWV1ZShTY2hlZENhbmRpZGF0ZSAmQ2FuZCk7Cit9OworCisvLy8gQ3JlYXRlIHRoZSBzdGFuZGFyZCBjb252ZXJnaW5nIG1hY2hpbmUgc2NoZWR1bGVyLiBUaGlzIHdpbGwgYmUgdXNlZCBhcyB0aGUKKy8vLyBkZWZhdWx0IHNjaGVkdWxlciBpZiB0aGUgdGFyZ2V0IGRvZXMgbm90IHNldCBhIGRlZmF1bHQuCisvLy8gQWRkcyBkZWZhdWx0IERBRyBtdXRhdGlvbnMuCitTY2hlZHVsZURBR01JTGl2ZSAqY3JlYXRlR2VuZXJpY1NjaGVkTGl2ZShNYWNoaW5lU2NoZWRDb250ZXh0ICpDKTsKKworLy8vIENyZWF0ZSBhIGdlbmVyaWMgc2NoZWR1bGVyIHdpdGggbm8gdnJlZyBsaXZlbmVzcyBvciBEQUcgbXV0YXRpb24gcGFzc2VzLgorU2NoZWR1bGVEQUdNSSAqY3JlYXRlR2VuZXJpY1NjaGVkUG9zdFJBKE1hY2hpbmVTY2hlZENvbnRleHQgKkMpOworCitzdGQ6OnVuaXF1ZV9wdHI8U2NoZWR1bGVEQUdNdXRhdGlvbj4KK2NyZWF0ZUxvYWRDbHVzdGVyREFHTXV0YXRpb24oY29uc3QgVGFyZ2V0SW5zdHJJbmZvICpUSUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJKTsKKworc3RkOjp1bmlxdWVfcHRyPFNjaGVkdWxlREFHTXV0YXRpb24+CitjcmVhdGVTdG9yZUNsdXN0ZXJEQUdNdXRhdGlvbihjb25zdCBUYXJnZXRJbnN0ckluZm8gKlRJSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJKTsKKworc3RkOjp1bmlxdWVfcHRyPFNjaGVkdWxlREFHTXV0YXRpb24+CitjcmVhdGVDb3B5Q29uc3RyYWluREFHTXV0YXRpb24oY29uc3QgVGFyZ2V0SW5zdHJJbmZvICpUSUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkpOworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX01BQ0hJTkVTQ0hFRFVMRVJfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL01hY2hpbmVUcmFjZU1ldHJpY3MuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lVHJhY2VNZXRyaWNzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOWQ4ZGIzOQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNoaW5lVHJhY2VNZXRyaWNzLmgKQEAgLTAsMCArMSw0MzYgQEAKKy8vPT09LSBsaWIvQ29kZUdlbi9NYWNoaW5lVHJhY2VNZXRyaWNzLmggLSBTdXBlci1zY2FsYXIgbWV0cmljcyAtKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlZmluZXMgdGhlIGludGVyZmFjZSBmb3IgdGhlIE1hY2hpbmVUcmFjZU1ldHJpY3MgYW5hbHlzaXMgcGFzcworLy8gdGhhdCBlc3RpbWF0ZXMgQ1BVIHJlc291cmNlIHVzYWdlIGFuZCBjcml0aWNhbCBkYXRhIGRlcGVuZGVuY3kgcGF0aHMgdGhyb3VnaAorLy8gcHJlZmVycmVkIHRyYWNlcy4gVGhpcyBpcyB1c2VmdWwgZm9yIHN1cGVyLXNjYWxhciBDUFVzIHdoZXJlIGV4ZWN1dGlvbiBzcGVlZAorLy8gY2FuIGJlIGxpbWl0ZWQgYm90aCBieSBkYXRhIGRlcGVuZGVuY2llcyBhbmQgYnkgbGltaXRlZCBleGVjdXRpb24gcmVzb3VyY2VzLgorLy8KKy8vIE91dC1vZi1vcmRlciBDUFVzIHdpbGwgb2Z0ZW4gYmUgZXhlY3V0aW5nIGluc3RydWN0aW9ucyBmcm9tIG11bHRpcGxlIGJhc2ljCisvLyBibG9ja3MgYXQgdGhlIHNhbWUgdGltZS4gVGhpcyBtYWtlcyBpdCBkaWZmaWN1bHQgdG8gZXN0aW1hdGUgdGhlIHJlc291cmNlCisvLyB1c2FnZSBhY2N1cmF0ZWx5IGluIGEgc2luZ2xlIGJhc2ljIGJsb2NrLiBSZXNvdXJjZXMgY2FuIGJlIGVzdGltYXRlZCBiZXR0ZXIKKy8vIGJ5IGxvb2tpbmcgYXQgYSB0cmFjZSB0aHJvdWdoIHRoZSBjdXJyZW50IGJhc2ljIGJsb2NrLgorLy8KKy8vIEZvciBldmVyeSBibG9jaywgdGhlIE1hY2hpbmVUcmFjZU1ldHJpY3MgcGFzcyB3aWxsIHBpY2sgYSBwcmVmZXJyZWQgdHJhY2UKKy8vIHRoYXQgcGFzc2VzIHRocm91Z2ggdGhlIGJsb2NrLiBUaGUgdHJhY2UgaXMgY2hvc2VuIGJhc2VkIG9uIGxvb3Agc3RydWN0dXJlLAorLy8gYnJhbmNoIHByb2JhYmlsaXRpZXMsIGFuZCByZXNvdXJjZSB1c2FnZS4gVGhlIGludGVudGlvbiBpcyB0byBwaWNrIGxpa2VseQorLy8gdHJhY2VzIHRoYXQgd291bGQgYmUgdGhlIG1vc3QgYWZmZWN0ZWQgYnkgY29kZSB0cmFuc2Zvcm1hdGlvbnMuCisvLworLy8gSXQgaXMgZXhwZW5zaXZlIHRvIGNvbXB1dGUgYSBmdWxsIGFyYml0cmFyeSB0cmFjZSBmb3IgZXZlcnkgYmxvY2ssIHNvIHRvCisvLyBzYXZlIHNvbWUgY29tcHV0YXRpb25zLCB0cmFjZXMgYXJlIGNob3NlbiB0byBiZSBjb252ZXJnZW50LiBUaGlzIG1lYW5zIHRoYXQKKy8vIGlmIHRoZSB0cmFjZXMgdGhyb3VnaCBiYXNpYyBibG9ja3MgQSBhbmQgQiBldmVyIGNyb3NzIHdoZW4gbW92aW5nIGF3YXkgZnJvbQorLy8gQSBhbmQgQiwgdGhleSBuZXZlciBkaXZlcmdlIGFnYWluLiBUaGlzIGFwcGxpZXMgaW4gYm90aCBkaXJlY3Rpb25zIC0gSWYgdGhlCisvLyB0cmFjZXMgbWVldCBhYm92ZSBBIGFuZCBCLCB0aGV5IHdvbid0IGRpdmVyZ2Ugd2hlbiBnb2luZyBmdXJ0aGVyIGJhY2suCisvLworLy8gVHJhY2VzIHRlbmQgdG8gYWxpZ24gd2l0aCBsb29wcy4gVGhlIHRyYWNlIHRocm91Z2ggYSBibG9jayBpbiBhbiBpbm5lciBsb29wCisvLyB3aWxsIGJlZ2luIGF0IHRoZSBsb29wIGVudHJ5IGJsb2NrIGFuZCBlbmQgYXQgYSBiYWNrIGVkZ2UuIElmIHRoZXJlIGFyZQorLy8gbmVzdGVkIGxvb3BzLCB0aGUgdHJhY2UgbWF5IGJlZ2luIGFuZCBlbmQgYXQgdGhvc2UgaW5zdGVhZC4KKy8vCisvLyBGb3IgZWFjaCB0cmFjZSwgd2UgY29tcHV0ZSB0aGUgY3JpdGljYWwgcGF0aCBsZW5ndGgsIHdoaWNoIGlzIHRoZSBudW1iZXIgb2YKKy8vIGN5Y2xlcyByZXF1aXJlZCB0byBleGVjdXRlIHRoZSB0cmFjZSB3aGVuIGV4ZWN1dGlvbiBpcyBsaW1pdGVkIGJ5IGRhdGEKKy8vIGRlcGVuZGVuY2llcyBvbmx5LiBXZSBhbHNvIGNvbXB1dGUgdGhlIHJlc291cmNlIGhlaWdodCwgd2hpY2ggaXMgdGhlIG51bWJlcgorLy8gb2YgY3ljbGVzIHJlcXVpcmVkIHRvIGV4ZWN1dGUgYWxsIGluc3RydWN0aW9ucyBpbiB0aGUgdHJhY2Ugd2hlbiBpZ25vcmluZworLy8gZGF0YSBkZXBlbmRlbmNpZXMuCisvLworLy8gRXZlcnkgaW5zdHJ1Y3Rpb24gaW4gdGhlIGN1cnJlbnQgYmxvY2sgaGFzIGEgc2xhY2sgLSB0aGUgbnVtYmVyIG9mIGN5Y2xlcworLy8gZXhlY3V0aW9uIG9mIHRoZSBpbnN0cnVjdGlvbiBjYW4gYmUgZGVsYXllZCB3aXRob3V0IGV4dGVuZGluZyB0aGUgY3JpdGljYWwKKy8vIHBhdGguCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fTUFDSElORVRSQUNFTUVUUklDU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9NQUNISU5FVFJBQ0VNRVRSSUNTX0gKKworI2luY2x1ZGUgImxsdm0vQURUL1NwYXJzZVNldC5oIgorI2luY2x1ZGUgImxsdm0vQURUL0FycmF5UmVmLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9Ob25lLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uUGFzcy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9UYXJnZXRTY2hlZHVsZS5oIgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIEFuYWx5c2lzVXNhZ2U7CitjbGFzcyBNYWNoaW5lRnVuY3Rpb247CitjbGFzcyBNYWNoaW5lSW5zdHI7CitjbGFzcyBNYWNoaW5lTG9vcDsKK2NsYXNzIE1hY2hpbmVMb29wSW5mbzsKK2NsYXNzIE1hY2hpbmVSZWdpc3RlckluZm87CitzdHJ1Y3QgTUNTY2hlZENsYXNzRGVzYzsKK2NsYXNzIHJhd19vc3RyZWFtOworY2xhc3MgVGFyZ2V0SW5zdHJJbmZvOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJJbmZvOworCisvLyBLZWVwIHRyYWNrIG9mIHBoeXNyZWcgZGF0YSBkZXBlbmRlbmNpZXMgYnkgcmVjb3JkaW5nIGVhY2ggbGl2ZSByZWdpc3RlciB1bml0LgorLy8gQXNzb2NpYXRlIGVhY2ggcmVndW5pdCB3aXRoIGFuIGluc3RydWN0aW9uIG9wZXJhbmQuIERlcGVuZGluZyBvbiB0aGUKKy8vIGRpcmVjdGlvbiBpbnN0cnVjdGlvbnMgYXJlIHNjYW5uZWQsIGl0IGNvdWxkIGJlIHRoZSBvcGVyYW5kIHRoYXQgZGVmaW5lZCB0aGUKKy8vIHJlZ3VuaXQsIG9yIHRoZSBoaWdoZXN0IG9wZXJhbmQgdG8gcmVhZCB0aGUgcmVndW5pdC4KK3N0cnVjdCBMaXZlUmVnVW5pdCB7CisgIHVuc2lnbmVkIFJlZ1VuaXQ7CisgIHVuc2lnbmVkIEN5Y2xlID0gMDsKKyAgY29uc3QgTWFjaGluZUluc3RyICpNSSA9IG51bGxwdHI7CisgIHVuc2lnbmVkIE9wID0gMDsKKworICB1bnNpZ25lZCBnZXRTcGFyc2VTZXRJbmRleCgpIGNvbnN0IHsgcmV0dXJuIFJlZ1VuaXQ7IH0KKworICBMaXZlUmVnVW5pdCh1bnNpZ25lZCBSVSkgOiBSZWdVbml0KFJVKSB7fQorfTsKKworCitjbGFzcyBNYWNoaW5lVHJhY2VNZXRyaWNzIDogcHVibGljIE1hY2hpbmVGdW5jdGlvblBhc3MgeworICBjb25zdCBNYWNoaW5lRnVuY3Rpb24gKk1GID0gbnVsbHB0cjsKKyAgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICpUSUkgPSBudWxscHRyOworICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSA9IG51bGxwdHI7CisgIGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gKk1SSSA9IG51bGxwdHI7CisgIGNvbnN0IE1hY2hpbmVMb29wSW5mbyAqTG9vcHMgPSBudWxscHRyOworICBUYXJnZXRTY2hlZE1vZGVsIFNjaGVkTW9kZWw7CisKK3B1YmxpYzoKKyAgZnJpZW5kIGNsYXNzIEVuc2VtYmxlOworICBmcmllbmQgY2xhc3MgVHJhY2U7CisKKyAgY2xhc3MgRW5zZW1ibGU7CisKKyAgc3RhdGljIGNoYXIgSUQ7CisKKyAgTWFjaGluZVRyYWNlTWV0cmljcygpOworCisgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlJikgY29uc3Qgb3ZlcnJpZGU7CisgIGJvb2wgcnVuT25NYWNoaW5lRnVuY3Rpb24oTWFjaGluZUZ1bmN0aW9uJikgb3ZlcnJpZGU7CisgIHZvaWQgcmVsZWFzZU1lbW9yeSgpIG92ZXJyaWRlOworICB2b2lkIHZlcmlmeUFuYWx5c2lzKCkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgLy8vIFBlci1iYXNpYyBibG9jayBpbmZvcm1hdGlvbiB0aGF0IGRvZXNuJ3QgZGVwZW5kIG9uIHRoZSB0cmFjZSB0aHJvdWdoIHRoZQorICAvLy8gYmxvY2suCisgIHN0cnVjdCBGaXhlZEJsb2NrSW5mbyB7CisgICAgLy8vIFRoZSBudW1iZXIgb2Ygbm9uLXRyaXZpYWwgaW5zdHJ1Y3Rpb25zIGluIHRoZSBibG9jay4KKyAgICAvLy8gRG9lc24ndCBjb3VudCBQSEkgYW5kIENPUFkgaW5zdHJ1Y3Rpb25zIHRoYXQgYXJlIGxpa2VseSB0byBiZSByZW1vdmVkLgorICAgIHVuc2lnbmVkIEluc3RyQ291bnQgPSB+MHU7CisKKyAgICAvLy8gVHJ1ZSB3aGVuIHRoZSBibG9jayBjb250YWlucyBjYWxscy4KKyAgICBib29sIEhhc0NhbGxzID0gZmFsc2U7CisKKyAgICBGaXhlZEJsb2NrSW5mbygpID0gZGVmYXVsdDsKKworICAgIC8vLyBSZXR1cm5zIHRydWUgd2hlbiByZXNvdXJjZSBpbmZvcm1hdGlvbiBmb3IgdGhpcyBibG9jayBoYXMgYmVlbiBjb21wdXRlZC4KKyAgICBib29sIGhhc1Jlc291cmNlcygpIGNvbnN0IHsgcmV0dXJuIEluc3RyQ291bnQgIT0gfjB1OyB9CisKKyAgICAvLy8gSW52YWxpZGF0ZSByZXNvdXJjZSBpbmZvcm1hdGlvbi4KKyAgICB2b2lkIGludmFsaWRhdGUoKSB7IEluc3RyQ291bnQgPSB+MHU7IH0KKyAgfTsKKworICAvLy8gR2V0IHRoZSBmaXhlZCByZXNvdXJjZSBpbmZvcm1hdGlvbiBhYm91dCBNQkIuIENvbXB1dGUgaXQgb24gZGVtYW5kLgorICBjb25zdCBGaXhlZEJsb2NrSW5mbyAqZ2V0UmVzb3VyY2VzKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrKik7CisKKyAgLy8vIEdldCB0aGUgc2NhbGVkIG51bWJlciBvZiBjeWNsZXMgdXNlZCBwZXIgcHJvY2Vzc29yIHJlc291cmNlIGluIE1CQi4KKyAgLy8vIFRoaXMgaXMgYW4gYXJyYXkgd2l0aCBTY2hlZE1vZGVsLmdldE51bVByb2NSZXNvdXJjZUtpbmRzKCkgZW50cmllcy4KKyAgLy8vIFRoZSBnZXRSZXNvdXJjZXMoKSBmdW5jdGlvbiBhYm92ZSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQgZmlyc3QuCisgIC8vLworICAvLy8gVGhlc2UgbnVtYmVycyBoYXZlIGFscmVhZHkgYmVlbiBzY2FsZWQgYnkgU2NoZWRNb2RlbC5nZXRSZXNvdXJjZUZhY3RvcigpLgorICBBcnJheVJlZjx1bnNpZ25lZD4gZ2V0UHJvY1Jlc291cmNlQ3ljbGVzKHVuc2lnbmVkIE1CQk51bSkgY29uc3Q7CisKKyAgLy8vIEEgdmlydHVhbCByZWdpc3RlciBvciByZWd1bml0IHJlcXVpcmVkIGJ5IGEgYmFzaWMgYmxvY2sgb3IgaXRzIHRyYWNlCisgIC8vLyBzdWNjZXNzb3JzLgorICBzdHJ1Y3QgTGl2ZUluUmVnIHsKKyAgICAvLy8gVGhlIHZpcnR1YWwgcmVnaXN0ZXIgcmVxdWlyZWQsIG9yIGEgcmVnaXN0ZXIgdW5pdC4KKyAgICB1bnNpZ25lZCBSZWc7CisKKyAgICAvLy8gRm9yIHZpcnR1YWwgcmVnaXN0ZXJzOiBNaW5pbXVtIGhlaWdodCBvZiB0aGUgZGVmaW5pbmcgaW5zdHJ1Y3Rpb24uCisgICAgLy8vIEZvciByZWd1bml0czogSGVpZ2h0IG9mIHRoZSBoaWdoZXN0IHVzZXIgaW4gdGhlIHRyYWNlLgorICAgIHVuc2lnbmVkIEhlaWdodDsKKworICAgIExpdmVJblJlZyh1bnNpZ25lZCBSZWcsIHVuc2lnbmVkIEhlaWdodCA9IDApIDogUmVnKFJlZyksIEhlaWdodChIZWlnaHQpIHt9CisgIH07CisKKyAgLy8vIFBlci1iYXNpYyBibG9jayBpbmZvcm1hdGlvbiB0aGF0IHJlbGF0ZXMgdG8gYSBzcGVjaWZpYyB0cmFjZSB0aHJvdWdoIHRoZQorICAvLy8gYmxvY2suIENvbnZlcmdlbnQgdHJhY2VzIG1lYW5zIHRoYXQgb25seSBvbmUgb2YgdGhlc2UgaXMgcmVxdWlyZWQgcGVyCisgIC8vLyBibG9jayBpbiBhIHRyYWNlIGVuc2VtYmxlLgorICBzdHJ1Y3QgVHJhY2VCbG9ja0luZm8geworICAgIC8vLyBUcmFjZSBwcmVkZWNlc3Nvciwgb3IgTlVMTCBmb3IgdGhlIGZpcnN0IGJsb2NrIGluIHRoZSB0cmFjZS4KKyAgICAvLy8gVmFsaWQgd2hlbiBoYXNWYWxpZERlcHRoKCkuCisgICAgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKlByZWQgPSBudWxscHRyOworCisgICAgLy8vIFRyYWNlIHN1Y2Nlc3Nvciwgb3IgTlVMTCBmb3IgdGhlIGxhc3QgYmxvY2sgaW4gdGhlIHRyYWNlLgorICAgIC8vLyBWYWxpZCB3aGVuIGhhc1ZhbGlkSGVpZ2h0KCkuCisgICAgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKlN1Y2MgPSBudWxscHRyOworCisgICAgLy8vIFRoZSBibG9jayBudW1iZXIgb2YgdGhlIGhlYWQgb2YgdGhlIHRyYWNlLiAoV2hlbiBoYXNWYWxpZERlcHRoKCkpLgorICAgIHVuc2lnbmVkIEhlYWQ7CisKKyAgICAvLy8gVGhlIGJsb2NrIG51bWJlciBvZiB0aGUgdGFpbCBvZiB0aGUgdHJhY2UuIChXaGVuIGhhc1ZhbGlkSGVpZ2h0KCkpLgorICAgIHVuc2lnbmVkIFRhaWw7CisKKyAgICAvLy8gQWNjdW11bGF0ZWQgbnVtYmVyIG9mIGluc3RydWN0aW9ucyBpbiB0aGUgdHJhY2UgYWJvdmUgdGhpcyBibG9jay4KKyAgICAvLy8gRG9lcyBub3QgaW5jbHVkZSBpbnN0cnVjdGlvbnMgaW4gdGhpcyBibG9jay4KKyAgICB1bnNpZ25lZCBJbnN0ckRlcHRoID0gfjB1OworCisgICAgLy8vIEFjY3VtdWxhdGVkIG51bWJlciBvZiBpbnN0cnVjdGlvbnMgaW4gdGhlIHRyYWNlIGJlbG93IHRoaXMgYmxvY2suCisgICAgLy8vIEluY2x1ZGVzIGluc3RydWN0aW9ucyBpbiB0aGlzIGJsb2NrLgorICAgIHVuc2lnbmVkIEluc3RySGVpZ2h0ID0gfjB1OworCisgICAgVHJhY2VCbG9ja0luZm8oKSA9IGRlZmF1bHQ7CisKKyAgICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBkZXB0aCByZXNvdXJjZXMgaGF2ZSBiZWVuIGNvbXB1dGVkIGZyb20gdGhlIHRyYWNlCisgICAgLy8vIGFib3ZlIHRoaXMgYmxvY2suCisgICAgYm9vbCBoYXNWYWxpZERlcHRoKCkgY29uc3QgeyByZXR1cm4gSW5zdHJEZXB0aCAhPSB+MHU7IH0KKworICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIGhlaWdodCByZXNvdXJjZXMgaGF2ZSBiZWVuIGNvbXB1dGVkIGZyb20gdGhlIHRyYWNlCisgICAgLy8vIGJlbG93IHRoaXMgYmxvY2suCisgICAgYm9vbCBoYXNWYWxpZEhlaWdodCgpIGNvbnN0IHsgcmV0dXJuIEluc3RySGVpZ2h0ICE9IH4wdTsgfQorCisgICAgLy8vIEludmFsaWRhdGUgZGVwdGggcmVzb3VyY2VzIHdoZW4gc29tZSBibG9jayBhYm92ZSB0aGlzIG9uZSBoYXMgY2hhbmdlZC4KKyAgICB2b2lkIGludmFsaWRhdGVEZXB0aCgpIHsgSW5zdHJEZXB0aCA9IH4wdTsgSGFzVmFsaWRJbnN0ckRlcHRocyA9IGZhbHNlOyB9CisKKyAgICAvLy8gSW52YWxpZGF0ZSBoZWlnaHQgcmVzb3VyY2VzIHdoZW4gYSBibG9jayBiZWxvdyB0aGlzIG9uZSBoYXMgY2hhbmdlZC4KKyAgICB2b2lkIGludmFsaWRhdGVIZWlnaHQoKSB7IEluc3RySGVpZ2h0ID0gfjB1OyBIYXNWYWxpZEluc3RySGVpZ2h0cyA9IGZhbHNlOyB9CisKKyAgICAvLy8gQXNzdW1pbmcgdGhhdCB0aGlzIGlzIGEgZG9taW5hdG9yIG9mIFRCSSwgZGV0ZXJtaW5lIGlmIGl0IGNvbnRhaW5zCisgICAgLy8vIHVzZWZ1bCBpbnN0cnVjdGlvbiBkZXB0aHMuIEEgZG9taW5hdGluZyBibG9jayBjYW4gYmUgYWJvdmUgdGhlIGN1cnJlbnQKKyAgICAvLy8gdHJhY2UgaGVhZCwgYW5kIGFueSBkZXBlbmRlbmNpZXMgZnJvbSBzdWNoIGEgZmFyIGF3YXkgZG9taW5hdG9yIGFyZSBub3QKKyAgICAvLy8gZXhwZWN0ZWQgdG8gYWZmZWN0IHRoZSBjcml0aWNhbCBwYXRoLgorICAgIC8vLworICAgIC8vLyBBbHNvIHJldHVybnMgdHJ1ZSB3aGVuIFRCSSA9PSB0aGlzLgorICAgIGJvb2wgaXNVc2VmdWxEb21pbmF0b3IoY29uc3QgVHJhY2VCbG9ja0luZm8gJlRCSSkgY29uc3QgeworICAgICAgLy8gVGhlIHRyYWNlIGZvciBUQkkgbWF5IG5vdCBldmVuIGJlIGNhbGN1bGF0ZWQgeWV0LgorICAgICAgaWYgKCFoYXNWYWxpZERlcHRoKCkgfHwgIVRCSS5oYXNWYWxpZERlcHRoKCkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIC8vIEluc3RydWN0aW9uIGRlcHRocyBhcmUgb25seSBjb21wYXJhYmxlIGlmIHRoZSB0cmFjZXMgc2hhcmUgYSBoZWFkLgorICAgICAgaWYgKEhlYWQgIT0gVEJJLkhlYWQpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIC8vIEl0IGlzIGFsbW9zdCBhbHdheXMgdGhlIGNhc2UgdGhhdCBUQkkgYmVsb25ncyB0byB0aGUgc2FtZSB0cmFjZSBhcworICAgICAgLy8gdGhpcyBibG9jaywgYnV0IHJhcmUgY29udm9sdXRlZCBjYXNlcyBpbnZvbHZpbmcgaXJyZWR1Y2libGUgY29udHJvbAorICAgICAgLy8gZmxvdywgYSBkb21pbmF0b3IgbWF5IHNoYXJlIGEgdHJhY2UgaGVhZCB3aXRob3V0IGFjdHVhbGx5IGJlaW5nIG9uIHRoZQorICAgICAgLy8gc2FtZSB0cmFjZSBhcyBUQkkuIFRoaXMgaXMgbm90IGEgYmlnIHByb2JsZW0gYXMgbG9uZyBhcyBpdCBkb2Vzbid0CisgICAgICAvLyBpbmNyZWFzZSB0aGUgaW5zdHJ1Y3Rpb24gZGVwdGguCisgICAgICByZXR1cm4gSGFzVmFsaWRJbnN0ckRlcHRocyAmJiBJbnN0ckRlcHRoIDw9IFRCSS5JbnN0ckRlcHRoOworICAgIH0KKworICAgIC8vIERhdGEtZGVwZW5kZW5jeS1yZWxhdGVkIGluZm9ybWF0aW9uLiBQZXItaW5zdHJ1Y3Rpb24gZGVwdGggYW5kIGhlaWdodAorICAgIC8vIGFyZSBjb21wdXRlZCBmcm9tIGRhdGEgZGVwZW5kZW5jaWVzIGluIHRoZSBjdXJyZW50IHRyYWNlLCB1c2luZworICAgIC8vIGl0aW5lcmFyeSBkYXRhLgorCisgICAgLy8vIEluc3RydWN0aW9uIGRlcHRocyBoYXZlIGJlZW4gY29tcHV0ZWQuIFRoaXMgaW1wbGllcyBoYXNWYWxpZERlcHRoKCkuCisgICAgYm9vbCBIYXNWYWxpZEluc3RyRGVwdGhzID0gZmFsc2U7CisKKyAgICAvLy8gSW5zdHJ1Y3Rpb24gaGVpZ2h0cyBoYXZlIGJlZW4gY29tcHV0ZWQuIFRoaXMgaW1wbGllcyBoYXNWYWxpZEhlaWdodCgpLgorICAgIGJvb2wgSGFzVmFsaWRJbnN0ckhlaWdodHMgPSBmYWxzZTsKKworICAgIC8vLyBDcml0aWNhbCBwYXRoIGxlbmd0aC4gVGhpcyBpcyB0aGUgbnVtYmVyIG9mIGN5Y2xlcyBpbiB0aGUgbG9uZ2VzdCBkYXRhCisgICAgLy8vIGRlcGVuZGVuY3kgY2hhaW4gdGhyb3VnaCB0aGUgdHJhY2UuIFRoaXMgaXMgb25seSB2YWxpZCB3aGVuIGJvdGgKKyAgICAvLy8gSGFzVmFsaWRJbnN0ckRlcHRocyBhbmQgSGFzVmFsaWRJbnN0ckhlaWdodHMgYXJlIHNldC4KKyAgICB1bnNpZ25lZCBDcml0aWNhbFBhdGg7CisKKyAgICAvLy8gTGl2ZS1pbiByZWdpc3RlcnMuIFRoZXNlIHJlZ2lzdGVycyBhcmUgZGVmaW5lZCBhYm92ZSB0aGUgY3VycmVudCBibG9jaworICAgIC8vLyBhbmQgdXNlZCBieSB0aGlzIGJsb2NrIG9yIGEgYmxvY2sgYmVsb3cgaXQuCisgICAgLy8vIFRoaXMgZG9lcyBub3QgaW5jbHVkZSBQSEkgdXNlcyBpbiB0aGUgY3VycmVudCBibG9jaywgYnV0IGl0IGRvZXMKKyAgICAvLy8gaW5jbHVkZSBQSEkgdXNlcyBpbiBkZWVwZXIgYmxvY2tzLgorICAgIFNtYWxsVmVjdG9yPExpdmVJblJlZywgND4gTGl2ZUluczsKKworICAgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0mKSBjb25zdDsKKyAgfTsKKworICAvLy8gSW5zdHJDeWNsZXMgcmVwcmVzZW50cyB0aGUgY3ljbGUgaGVpZ2h0IGFuZCBkZXB0aCBvZiBhbiBpbnN0cnVjdGlvbiBpbiBhCisgIC8vLyB0cmFjZS4KKyAgc3RydWN0IEluc3RyQ3ljbGVzIHsKKyAgICAvLy8gRWFybGllc3QgaXNzdWUgY3ljbGUgYXMgZGV0ZXJtaW5lZCBieSBkYXRhIGRlcGVuZGVuY2llcyBhbmQgaW5zdHJ1Y3Rpb24KKyAgICAvLy8gbGF0ZW5jaWVzIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgdHJhY2UuIERhdGEgZGVwZW5kZW5jaWVzIGZyb20KKyAgICAvLy8gYmVmb3JlIHRoZSB0cmFjZSBhcmUgbm90IGluY2x1ZGVkLgorICAgIHVuc2lnbmVkIERlcHRoOworCisgICAgLy8vIE1pbmltdW0gbnVtYmVyIG9mIGN5Y2xlcyBmcm9tIHRoaXMgaW5zdHJ1Y3Rpb24gaXMgaXNzdWVkIHRvIHRoZSBvZiB0aGUKKyAgICAvLy8gdHJhY2UsIGFzIGRldGVybWluZWQgYnkgZGF0YSBkZXBlbmRlbmNpZXMgYW5kIGluc3RydWN0aW9uIGxhdGVuY2llcy4KKyAgICB1bnNpZ25lZCBIZWlnaHQ7CisgIH07CisKKyAgLy8vIEEgdHJhY2UgcmVwcmVzZW50cyBhIHBsYXVzaWJsZSBzZXF1ZW5jZSBvZiBleGVjdXRlZCBiYXNpYyBibG9ja3MgdGhhdAorICAvLy8gcGFzc2VzIHRocm91Z2ggdGhlIGN1cnJlbnQgYmFzaWMgYmxvY2sgb25lLiBUaGUgVHJhY2UgY2xhc3Mgc2VydmVzIGFzIGEKKyAgLy8vIGhhbmRsZSB0byBpbnRlcm5hbCBjYWNoZWQgZGF0YSBzdHJ1Y3R1cmVzLgorICBjbGFzcyBUcmFjZSB7CisgICAgRW5zZW1ibGUgJlRFOworICAgIFRyYWNlQmxvY2tJbmZvICZUQkk7CisKKyAgICB1bnNpZ25lZCBnZXRCbG9ja051bSgpIGNvbnN0IHsgcmV0dXJuICZUQkkgLSAmVEUuQmxvY2tJbmZvWzBdOyB9CisKKyAgcHVibGljOgorICAgIGV4cGxpY2l0IFRyYWNlKEVuc2VtYmxlICZ0ZSwgVHJhY2VCbG9ja0luZm8gJnRiaSkgOiBURSh0ZSksIFRCSSh0YmkpIHt9CisKKyAgICB2b2lkIHByaW50KHJhd19vc3RyZWFtJikgY29uc3Q7CisKKyAgICAvLy8gQ29tcHV0ZSB0aGUgdG90YWwgbnVtYmVyIG9mIGluc3RydWN0aW9ucyBpbiB0aGUgdHJhY2UuCisgICAgdW5zaWduZWQgZ2V0SW5zdHJDb3VudCgpIGNvbnN0IHsKKyAgICAgIHJldHVybiBUQkkuSW5zdHJEZXB0aCArIFRCSS5JbnN0ckhlaWdodDsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRoZSByZXNvdXJjZSBkZXB0aCBvZiB0aGUgdG9wL2JvdHRvbSBvZiB0aGUgdHJhY2UgY2VudGVyIGJsb2NrLgorICAgIC8vLyBUaGlzIGlzIHRoZSBudW1iZXIgb2YgY3ljbGVzIHJlcXVpcmVkIHRvIGV4ZWN1dGUgYWxsIGluc3RydWN0aW9ucyBmcm9tCisgICAgLy8vIHRoZSB0cmFjZSBoZWFkIHRvIHRoZSB0cmFjZSBjZW50ZXIgYmxvY2suIFRoZSByZXNvdXJjZSBkZXB0aCBvbmx5CisgICAgLy8vIGNvbnNpZGVycyBleGVjdXRpb24gcmVzb3VyY2VzLCBpdCBpZ25vcmVzIGRhdGEgZGVwZW5kZW5jaWVzLgorICAgIC8vLyBXaGVuIEJvdHRvbSBpcyBzZXQsIGluc3RydWN0aW9ucyBpbiB0aGUgdHJhY2UgY2VudGVyIGJsb2NrIGFyZSBpbmNsdWRlZC4KKyAgICB1bnNpZ25lZCBnZXRSZXNvdXJjZURlcHRoKGJvb2wgQm90dG9tKSBjb25zdDsKKworICAgIC8vLyBSZXR1cm4gdGhlIHJlc291cmNlIGxlbmd0aCBvZiB0aGUgdHJhY2UuIFRoaXMgaXMgdGhlIG51bWJlciBvZiBjeWNsZXMKKyAgICAvLy8gcmVxdWlyZWQgdG8gZXhlY3V0ZSB0aGUgaW5zdHJ1Y3Rpb25zIGluIHRoZSB0cmFjZSBpZiB0aGV5IHdlcmUgYWxsCisgICAgLy8vIGluZGVwZW5kZW50LCBleHBvc2luZyB0aGUgbWF4aW11bSBpbnN0cnVjdGlvbi1sZXZlbCBwYXJhbGxlbGlzbS4KKyAgICAvLy8KKyAgICAvLy8gQW55IGJsb2NrcyBpbiBFeHRyYWJsb2NrcyBhcmUgaW5jbHVkZWQgYXMgaWYgdGhleSB3ZXJlIHBhcnQgb2YgdGhlCisgICAgLy8vIHRyYWNlLiBMaWtld2lzZSwgZXh0cmEgcmVzb3VyY2VzIHJlcXVpcmVkIGJ5IHRoZSBzcGVjaWZpZWQgc2NoZWR1bGluZworICAgIC8vLyBjbGFzc2VzIGFyZSBpbmNsdWRlZC4gRm9yIHRoZSBjYWxsZXIgdG8gYWNjb3VudCBmb3IgZXh0cmEgbWFjaGluZQorICAgIC8vLyBpbnN0cnVjdGlvbnMsIGl0IG11c3QgZmlyc3QgcmVzb2x2ZSBlYWNoIGluc3RydWN0aW9uJ3Mgc2NoZWR1bGluZyBjbGFzcy4KKyAgICB1bnNpZ25lZCBnZXRSZXNvdXJjZUxlbmd0aCgKKyAgICAgICAgQXJyYXlSZWY8Y29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKj4gRXh0cmFibG9ja3MgPSBOb25lLAorICAgICAgICBBcnJheVJlZjxjb25zdCBNQ1NjaGVkQ2xhc3NEZXNjICo+IEV4dHJhSW5zdHJzID0gTm9uZSwKKyAgICAgICAgQXJyYXlSZWY8Y29uc3QgTUNTY2hlZENsYXNzRGVzYyAqPiBSZW1vdmVJbnN0cnMgPSBOb25lKSBjb25zdDsKKworICAgIC8vLyBSZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgKGRhdGEgZGVwZW5kZW5jeSkgY3JpdGljYWwgcGF0aCB0aHJvdWdoIHRoZQorICAgIC8vLyB0cmFjZS4KKyAgICB1bnNpZ25lZCBnZXRDcml0aWNhbFBhdGgoKSBjb25zdCB7IHJldHVybiBUQkkuQ3JpdGljYWxQYXRoOyB9CisKKyAgICAvLy8gUmV0dXJuIHRoZSBkZXB0aCBhbmQgaGVpZ2h0IG9mIE1JLiBUaGUgZGVwdGggaXMgb25seSB2YWxpZCBmb3IKKyAgICAvLy8gaW5zdHJ1Y3Rpb25zIGluIG9yIGFib3ZlIHRoZSB0cmFjZSBjZW50ZXIgYmxvY2suIFRoZSBoZWlnaHQgaXMgb25seQorICAgIC8vLyB2YWxpZCBmb3IgaW5zdHJ1Y3Rpb25zIGluIG9yIGJlbG93IHRoZSB0cmFjZSBjZW50ZXIgYmxvY2suCisgICAgSW5zdHJDeWNsZXMgZ2V0SW5zdHJDeWNsZXMoY29uc3QgTWFjaGluZUluc3RyICZNSSkgY29uc3QgeworICAgICAgcmV0dXJuIFRFLkN5Y2xlcy5sb29rdXAoJk1JKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRoZSBzbGFjayBvZiBNSS4gVGhpcyBpcyB0aGUgbnVtYmVyIG9mIGN5Y2xlcyBNSSBjYW4gYmUgZGVsYXllZAorICAgIC8vLyBiZWZvcmUgdGhlIGNyaXRpY2FsIHBhdGggYmVjb21lcyBsb25nZXIuCisgICAgLy8vIE1JIG11c3QgYmUgYW4gaW5zdHJ1Y3Rpb24gaW4gdGhlIHRyYWNlIGNlbnRlciBibG9jay4KKyAgICB1bnNpZ25lZCBnZXRJbnN0clNsYWNrKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIGNvbnN0OworCisgICAgLy8vIFJldHVybiB0aGUgRGVwdGggb2YgYSBQSEkgaW5zdHJ1Y3Rpb24gaW4gYSB0cmFjZSBjZW50ZXIgYmxvY2sgc3VjY2Vzc29yLgorICAgIC8vLyBUaGUgUEhJIGRvZXMgbm90IGhhdmUgdG8gYmUgcGFydCBvZiB0aGUgdHJhY2UuCisgICAgdW5zaWduZWQgZ2V0UEhJRGVwdGgoY29uc3QgTWFjaGluZUluc3RyICZQSEkpIGNvbnN0OworCisgICAgLy8vIEEgZGVwZW5kZW5jZSBpcyB1c2VmdWwgaWYgdGhlIGJhc2ljIGJsb2NrIG9mIHRoZSBkZWZpbmluZyBpbnN0cnVjdGlvbgorICAgIC8vLyBpcyBwYXJ0IG9mIHRoZSB0cmFjZSBvZiB0aGUgdXNlciBpbnN0cnVjdGlvbi4gSXQgaXMgYXNzdW1lZCB0aGF0IERlZk1JCisgICAgLy8vIGRvbWluYXRlcyBVc2VNSSAoc2VlIGFsc28gaXNVc2VmdWxEb21pbmF0b3IpLgorICAgIGJvb2wgaXNEZXBJblRyYWNlKGNvbnN0IE1hY2hpbmVJbnN0ciAmRGVmTUksCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUluc3RyICZVc2VNSSkgY29uc3Q7CisgIH07CisKKyAgLy8vIEEgdHJhY2UgZW5zZW1ibGUgaXMgYSBjb2xsZWN0aW9uIG9mIHRyYWNlcyBzZWxlY3RlZCB1c2luZyB0aGUgc2FtZQorICAvLy8gc3RyYXRlZ3ksIGZvciBleGFtcGxlICdtaW5pbXVtIHJlc291cmNlIGhlaWdodCcuIFRoZXJlIGlzIG9uZSB0cmFjZSBmb3IKKyAgLy8vIGV2ZXJ5IGJsb2NrIGluIHRoZSBmdW5jdGlvbi4KKyAgY2xhc3MgRW5zZW1ibGUgeworICAgIGZyaWVuZCBjbGFzcyBUcmFjZTsKKworICAgIFNtYWxsVmVjdG9yPFRyYWNlQmxvY2tJbmZvLCA0PiBCbG9ja0luZm87CisgICAgRGVuc2VNYXA8Y29uc3QgTWFjaGluZUluc3RyKiwgSW5zdHJDeWNsZXM+IEN5Y2xlczsKKyAgICBTbWFsbFZlY3Rvcjx1bnNpZ25lZCwgMD4gUHJvY1Jlc291cmNlRGVwdGhzOworICAgIFNtYWxsVmVjdG9yPHVuc2lnbmVkLCAwPiBQcm9jUmVzb3VyY2VIZWlnaHRzOworCisgICAgdm9pZCBjb21wdXRlVHJhY2UoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sqKTsKKyAgICB2b2lkIGNvbXB1dGVEZXB0aFJlc291cmNlcyhjb25zdCBNYWNoaW5lQmFzaWNCbG9jayopOworICAgIHZvaWQgY29tcHV0ZUhlaWdodFJlc291cmNlcyhjb25zdCBNYWNoaW5lQmFzaWNCbG9jayopOworICAgIHVuc2lnbmVkIGNvbXB1dGVDcm9zc0Jsb2NrQ3JpdGljYWxQYXRoKGNvbnN0IFRyYWNlQmxvY2tJbmZvJik7CisgICAgdm9pZCBjb21wdXRlSW5zdHJEZXB0aHMoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sqKTsKKyAgICB2b2lkIGNvbXB1dGVJbnN0ckhlaWdodHMoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sqKTsKKyAgICB2b2lkIGFkZExpdmVJbnMoY29uc3QgTWFjaGluZUluc3RyICpEZWZNSSwgdW5zaWduZWQgRGVmT3AsCisgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrKj4gVHJhY2UpOworCisgIHByb3RlY3RlZDoKKyAgICBNYWNoaW5lVHJhY2VNZXRyaWNzICZNVE07CisKKyAgICBleHBsaWNpdCBFbnNlbWJsZShNYWNoaW5lVHJhY2VNZXRyaWNzKik7CisKKyAgICB2aXJ0dWFsIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpwaWNrVHJhY2VQcmVkKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrKikgPTA7CisgICAgdmlydHVhbCBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqcGlja1RyYWNlU3VjYyhjb25zdCBNYWNoaW5lQmFzaWNCbG9jayopID0wOworICAgIGNvbnN0IE1hY2hpbmVMb29wICpnZXRMb29wRm9yKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrKikgY29uc3Q7CisgICAgY29uc3QgVHJhY2VCbG9ja0luZm8gKmdldERlcHRoUmVzb3VyY2VzKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrKikgY29uc3Q7CisgICAgY29uc3QgVHJhY2VCbG9ja0luZm8gKmdldEhlaWdodFJlc291cmNlcyhjb25zdCBNYWNoaW5lQmFzaWNCbG9jayopIGNvbnN0OworICAgIEFycmF5UmVmPHVuc2lnbmVkPiBnZXRQcm9jUmVzb3VyY2VEZXB0aHModW5zaWduZWQgTUJCTnVtKSBjb25zdDsKKyAgICBBcnJheVJlZjx1bnNpZ25lZD4gZ2V0UHJvY1Jlc291cmNlSGVpZ2h0cyh1bnNpZ25lZCBNQkJOdW0pIGNvbnN0OworCisgIHB1YmxpYzoKKyAgICB2aXJ0dWFsIH5FbnNlbWJsZSgpOworCisgICAgdmlydHVhbCBjb25zdCBjaGFyICpnZXROYW1lKCkgY29uc3QgPSAwOworICAgIHZvaWQgcHJpbnQocmF3X29zdHJlYW0mKSBjb25zdDsKKyAgICB2b2lkIGludmFsaWRhdGUoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKk1CQik7CisgICAgdm9pZCB2ZXJpZnkoKSBjb25zdDsKKworICAgIC8vLyBHZXQgdGhlIHRyYWNlIHRoYXQgcGFzc2VzIHRocm91Z2ggTUJCLgorICAgIC8vLyBUaGUgdHJhY2UgaXMgY29tcHV0ZWQgb24gZGVtYW5kLgorICAgIFRyYWNlIGdldFRyYWNlKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpOworCisgICAgLy8vIFVwZGF0ZXMgdGhlIGRlcHRoIG9mIGFuIG1hY2hpbmUgaW5zdHJ1Y3Rpb24sIGdpdmVuIFJlZ1VuaXRzLgorICAgIHZvaWQgdXBkYXRlRGVwdGgoVHJhY2VCbG9ja0luZm8gJlRCSSwgY29uc3QgTWFjaGluZUluc3RyJiwKKyAgICAgICAgICAgICAgICAgICAgIFNwYXJzZVNldDxMaXZlUmVnVW5pdD4gJlJlZ1VuaXRzKTsKKyAgICB2b2lkIHVwZGF0ZURlcHRoKGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICosIGNvbnN0IE1hY2hpbmVJbnN0ciYsCisgICAgICAgICAgICAgICAgICAgICBTcGFyc2VTZXQ8TGl2ZVJlZ1VuaXQ+ICZSZWdVbml0cyk7CisKKyAgICAvLy8gVXBkYXRlcyB0aGUgZGVwdGggb2YgdGhlIGluc3RydWN0aW9ucyBmcm9tIFN0YXJ0IHRvIEVuZC4KKyAgICB2b2lkIHVwZGF0ZURlcHRocyhNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgU3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEVuZCwKKyAgICAgICAgICAgICAgICAgICAgICBTcGFyc2VTZXQ8TGl2ZVJlZ1VuaXQ+ICZSZWdVbml0cyk7CisKKyAgfTsKKworICAvLy8gU3RyYXRlZ2llcyBmb3Igc2VsZWN0aW5nIHRyYWNlcy4KKyAgZW51bSBTdHJhdGVneSB7CisgICAgLy8vIFNlbGVjdCB0aGUgdHJhY2UgdGhyb3VnaCBhIGJsb2NrIHRoYXQgaGFzIHRoZSBmZXdlc3QgaW5zdHJ1Y3Rpb25zLgorICAgIFRTX01pbkluc3RyQ291bnQsCisKKyAgICBUU19OdW1TdHJhdGVnaWVzCisgIH07CisKKyAgLy8vIEdldCB0aGUgdHJhY2UgZW5zZW1ibGUgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiB0cmFjZSBzZWxlY3Rpb24gc3RyYXRlZ3kuCisgIC8vLyBUaGUgcmV0dXJuZWQgRW5zZW1ibGUgb2JqZWN0IGlzIG93bmVkIGJ5IHRoZSBNYWNoaW5lVHJhY2VNZXRyaWNzIGFuYWx5c2lzLAorICAvLy8gYW5kIHZhbGlkIGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlIGFuYWx5c2lzIHBhc3MuCisgIEVuc2VtYmxlICpnZXRFbnNlbWJsZShTdHJhdGVneSk7CisKKyAgLy8vIEludmFsaWRhdGUgY2FjaGVkIGluZm9ybWF0aW9uIGFib3V0IE1CQi4gVGhpcyBtdXN0IGJlIGNhbGxlZCAqYmVmb3JlKiBNQkIKKyAgLy8vIGlzIGVyYXNlZCwgb3IgdGhlIENGRyBpcyBvdGhlcndpc2UgY2hhbmdlZC4KKyAgLy8vCisgIC8vLyBUaGlzIGludmFsaWRhdGVzIHBlci1ibG9jayBpbmZvcm1hdGlvbiBhYm91dCByZXNvdXJjZSB1c2FnZSBmb3IgTUJCIG9ubHksCisgIC8vLyBhbmQgaXQgaW52YWxpZGF0ZXMgcGVyLXRyYWNlIGluZm9ybWF0aW9uIGZvciBhbnkgdHJhY2UgdGhhdCBwYXNzZXMKKyAgLy8vIHRocm91Z2ggTUJCLgorICAvLy8KKyAgLy8vIENhbGwgRW5zZW1ibGU6OmdldFRyYWNlKCkgYWdhaW4gdG8gdXBkYXRlIGFueSB0cmFjZSBoYW5kbGVzLgorICB2b2lkIGludmFsaWRhdGUoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKk1CQik7CisKK3ByaXZhdGU6CisgIC8vIE9uZSBlbnRyeSBwZXIgYmFzaWMgYmxvY2ssIGluZGV4ZWQgYnkgYmxvY2sgbnVtYmVyLgorICBTbWFsbFZlY3RvcjxGaXhlZEJsb2NrSW5mbywgND4gQmxvY2tJbmZvOworCisgIC8vIEN5Y2xlcyBjb25zdW1lZCBvbiBlYWNoIHByb2Nlc3NvciByZXNvdXJjZSBwZXIgYmxvY2suCisgIC8vIFRoZSBudW1iZXIgb2YgcHJvY2Vzc29yIHJlc291cmNlIGtpbmRzIGlzIGNvbnN0YW50IGZvciBhIGdpdmVuIHN1YnRhcmdldCwKKyAgLy8gYnV0IGl0IGlzIG5vdCBrbm93biBhdCBjb21waWxlIHRpbWUuIFRoZSBudW1iZXIgb2YgY3ljbGVzIGNvbnN1bWVkIGJ5CisgIC8vIGJsb2NrIEIgb24gcHJvY2Vzc29yIHJlc291cmNlIFIgaXMgYXQgUHJvY1Jlc291cmNlQ3ljbGVzW0IqS2luZHMgKyBSXQorICAvLyB3aGVyZSBLaW5kcyA9IFNjaGVkTW9kZWwuZ2V0TnVtUHJvY1Jlc291cmNlS2luZHMoKS4KKyAgU21hbGxWZWN0b3I8dW5zaWduZWQsIDA+IFByb2NSZXNvdXJjZUN5Y2xlczsKKworICAvLyBPbmUgZW5zZW1ibGUgcGVyIHN0cmF0ZWd5LgorICBFbnNlbWJsZSogRW5zZW1ibGVzW1RTX051bVN0cmF0ZWdpZXNdOworCisgIC8vIENvbnZlcnQgc2NhbGVkIHJlc291cmNlIHVzYWdlIHRvIGEgY3ljbGUgY291bnQgdGhhdCBjYW4gYmUgY29tcGFyZWQgd2l0aAorICAvLyBsYXRlbmNpZXMuCisgIHVuc2lnbmVkIGdldEN5Y2xlcyh1bnNpZ25lZCBTY2FsZWQpIHsKKyAgICB1bnNpZ25lZCBGYWN0b3IgPSBTY2hlZE1vZGVsLmdldExhdGVuY3lGYWN0b3IoKTsKKyAgICByZXR1cm4gKFNjYWxlZCArIEZhY3RvciAtIDEpIC8gRmFjdG9yOworICB9Cit9OworCitpbmxpbmUgcmF3X29zdHJlYW0gJm9wZXJhdG9yPDwocmF3X29zdHJlYW0gJk9TLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVUcmFjZU1ldHJpY3M6OlRyYWNlICZUcikgeworICBUci5wcmludChPUyk7CisgIHJldHVybiBPUzsKK30KKworaW5saW5lIHJhd19vc3RyZWFtICZvcGVyYXRvcjw8KHJhd19vc3RyZWFtICZPUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lVHJhY2VNZXRyaWNzOjpFbnNlbWJsZSAmRW4pIHsKKyAgRW4ucHJpbnQoT1MpOworICByZXR1cm4gT1M7Cit9CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTUFDSElORVRSQUNFTUVUUklDU19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjcm9GdXNpb24uaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9NYWNyb0Z1c2lvbi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjMTA1ZmQKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vTWFjcm9GdXNpb24uaApAQCAtMCwwICsxLDUwIEBACisvLz09PS0gTWFjcm9GdXNpb24uaCAtIE1hY3JvIEZ1c2lvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vLyBcZmlsZSBUaGlzIGZpbGUgY29udGFpbnMgdGhlIGRlZmluaXRpb24gb2YgdGhlIERBRyBzY2hlZHVsaW5nIG11dGF0aW9uIHRvCisvLy8gcGFpciBpbnN0cnVjdGlvbnMgYmFjayB0byBiYWNrLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX01BQ1JPRlVTSU9OX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX01BQ1JPRlVTSU9OX0gKKworI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CisjaW5jbHVkZSA8bWVtb3J5PgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIE1hY2hpbmVJbnN0cjsKK2NsYXNzIFNjaGVkdWxlREFHTXV0YXRpb247CitjbGFzcyBUYXJnZXRJbnN0ckluZm87CitjbGFzcyBUYXJnZXRTdWJ0YXJnZXRJbmZvOworCisvLy8gXGJyaWVmIENoZWNrIGlmIHRoZSBpbnN0ciBwYWlyLCBGaXJzdE1JIGFuZCBTZWNvbmRNSSwgc2hvdWxkIGJlIGZ1c2VkCisvLy8gdG9nZXRoZXIuIEdpdmVuIFNlY29uZE1JLCB3aGVuIEZpcnN0TUkgaXMgdW5zcGVjaWZpZWQsIHRoZW4gY2hlY2sgaWYKKy8vLyBTZWNvbmRNSSBtYXkgYmUgcGFydCBvZiBhIGZ1c2VkIHBhaXIgYXQgYWxsLgordXNpbmcgU2hvdWxkU2NoZWR1bGVQcmVkVHkgPSBzdGQ6OmZ1bmN0aW9uPGJvb2woY29uc3QgVGFyZ2V0SW5zdHJJbmZvICZUSUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRTdWJ0YXJnZXRJbmZvICZUU0ksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lSW5zdHIgKkZpcnN0TUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lSW5zdHIgJlNlY29uZE1JKT47CisKKy8vLyBcYnJpZWYgQ3JlYXRlIGEgREFHIHNjaGVkdWxpbmcgbXV0YXRpb24gdG8gcGFpciBpbnN0cnVjdGlvbnMgYmFjayB0byBiYWNrCisvLy8gZm9yIGluc3RydWN0aW9ucyB0aGF0IGJlbmVmaXQgYWNjb3JkaW5nIHRvIHRoZSB0YXJnZXQtc3BlY2lmaWMKKy8vLyBzaG91bGRTY2hlZHVsZUFkamFjZW50IHByZWRpY2F0ZSBmdW5jdGlvbi4KK3N0ZDo6dW5pcXVlX3B0cjxTY2hlZHVsZURBR011dGF0aW9uPgorY3JlYXRlTWFjcm9GdXNpb25EQUdNdXRhdGlvbihTaG91bGRTY2hlZHVsZVByZWRUeSBzaG91bGRTY2hlZHVsZUFkamFjZW50KTsKKworLy8vIFxicmllZiBDcmVhdGUgYSBEQUcgc2NoZWR1bGluZyBtdXRhdGlvbiB0byBwYWlyIGJyYW5jaCBpbnN0cnVjdGlvbnMgd2l0aCBvbmUKKy8vLyBvZiB0aGVpciBwcmVkZWNlc3NvcnMgYmFjayB0byBiYWNrIGZvciBpbnN0cnVjdGlvbnMgdGhhdCBiZW5lZml0IGFjY29yZGluZworLy8vIHRvIHRoZSB0YXJnZXQtc3BlY2lmaWMgc2hvdWxkU2NoZWR1bGVBZGphY2VudCBwcmVkaWNhdGUgZnVuY3Rpb24uCitzdGQ6OnVuaXF1ZV9wdHI8U2NoZWR1bGVEQUdNdXRhdGlvbj4KK2NyZWF0ZUJyYW5jaE1hY3JvRnVzaW9uREFHTXV0YXRpb24oU2hvdWxkU2NoZWR1bGVQcmVkVHkgc2hvdWxkU2NoZWR1bGVBZGphY2VudCk7CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fTUFDUk9GVVNJT05fSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1BCUVAvQ29zdEFsbG9jYXRvci5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1BCUVAvQ29zdEFsbG9jYXRvci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJkZTQ1MWEKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUEJRUC9Db3N0QWxsb2NhdG9yLmgKQEAgLTAsMCArMSwxMzUgQEAKKy8vPT09LSBDb3N0QWxsb2NhdG9yLmggLSBQQlFQIENvc3QgQWxsb2NhdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gRGVmaW5lcyBjbGFzc2VzIGNvbmZvcm1pbmcgdG8gdGhlIFBCUVAgY29zdCB2YWx1ZSBtYW5hZ2VyIGNvbmNlcHQuCisvLworLy8gQ29zdCB2YWx1ZSBtYW5hZ2VycyBhcmUgbWVtb3J5IG1hbmFnZXJzIGZvciBQQlFQIGNvc3QgdmFsdWVzICh2ZWN0b3JzIGFuZAorLy8gbWF0cmljZXMpLiBTaW5jZSBQQlFQIGdyYXBocyBjYW4gZ3JvdyB2ZXJ5IGxhcmdlIChFLmcuIGh1bmRyZWRzIG9mIHRob3VzYW5kcworLy8gb2YgZWRnZXMgb24gdGhlIGxhcmdlc3QgZnVuY3Rpb24gaW4gU1BFQzIwMDYpLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1BCUVBfQ09TVEFMTE9DQVRPUl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9QQlFQX0NPU1RBTExPQ0FUT1JfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VTZXQuaCIKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Y3N0ZGludD4KKyNpbmNsdWRlIDxtZW1vcnk+CisKK25hbWVzcGFjZSBsbHZtIHsKK25hbWVzcGFjZSBQQlFQIHsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlVD4gY2xhc3MgVmFsdWVQb29sIHsKK3B1YmxpYzoKKyAgdXNpbmcgUG9vbFJlZiA9IHN0ZDo6c2hhcmVkX3B0cjxjb25zdCBWYWx1ZVQ+OworCitwcml2YXRlOgorICBjbGFzcyBQb29sRW50cnkgOiBwdWJsaWMgc3RkOjplbmFibGVfc2hhcmVkX2Zyb21fdGhpczxQb29sRW50cnk+IHsKKyAgcHVibGljOgorICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBWYWx1ZUtleVQ+CisgICAgUG9vbEVudHJ5KFZhbHVlUG9vbCAmUG9vbCwgVmFsdWVLZXlUIFZhbHVlKQorICAgICAgICA6IFBvb2woUG9vbCksIFZhbHVlKHN0ZDo6bW92ZShWYWx1ZSkpIHt9CisKKyAgICB+UG9vbEVudHJ5KCkgeyBQb29sLnJlbW92ZUVudHJ5KHRoaXMpOyB9CisKKyAgICBjb25zdCBWYWx1ZVQgJmdldFZhbHVlKCkgY29uc3QgeyByZXR1cm4gVmFsdWU7IH0KKworICBwcml2YXRlOgorICAgIFZhbHVlUG9vbCAmUG9vbDsKKyAgICBWYWx1ZVQgVmFsdWU7CisgIH07CisKKyAgY2xhc3MgUG9vbEVudHJ5RFNJbmZvIHsKKyAgcHVibGljOgorICAgIHN0YXRpYyBpbmxpbmUgUG9vbEVudHJ5ICpnZXRFbXB0eUtleSgpIHsgcmV0dXJuIG51bGxwdHI7IH0KKworICAgIHN0YXRpYyBpbmxpbmUgUG9vbEVudHJ5ICpnZXRUb21ic3RvbmVLZXkoKSB7CisgICAgICByZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxQb29sRW50cnkgKj4oc3RhdGljX2Nhc3Q8dWludHB0cl90PigxKSk7CisgICAgfQorCisgICAgdGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlS2V5VD4KKyAgICBzdGF0aWMgdW5zaWduZWQgZ2V0SGFzaFZhbHVlKGNvbnN0IFZhbHVlS2V5VCAmQykgeworICAgICAgcmV0dXJuIGhhc2hfdmFsdWUoQyk7CisgICAgfQorCisgICAgc3RhdGljIHVuc2lnbmVkIGdldEhhc2hWYWx1ZShQb29sRW50cnkgKlApIHsKKyAgICAgIHJldHVybiBnZXRIYXNoVmFsdWUoUC0+Z2V0VmFsdWUoKSk7CisgICAgfQorCisgICAgc3RhdGljIHVuc2lnbmVkIGdldEhhc2hWYWx1ZShjb25zdCBQb29sRW50cnkgKlApIHsKKyAgICAgIHJldHVybiBnZXRIYXNoVmFsdWUoUC0+Z2V0VmFsdWUoKSk7CisgICAgfQorCisgICAgdGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlS2V5VDEsIHR5cGVuYW1lIFZhbHVlS2V5VDI+CisgICAgc3RhdGljIGJvb2wgaXNFcXVhbChjb25zdCBWYWx1ZUtleVQxICZDMSwgY29uc3QgVmFsdWVLZXlUMiAmQzIpIHsKKyAgICAgIHJldHVybiBDMSA9PSBDMjsKKyAgICB9CisKKyAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVmFsdWVLZXlUPgorICAgIHN0YXRpYyBib29sIGlzRXF1YWwoY29uc3QgVmFsdWVLZXlUICZDLCBQb29sRW50cnkgKlApIHsKKyAgICAgIGlmIChQID09IGdldEVtcHR5S2V5KCkgfHwgUCA9PSBnZXRUb21ic3RvbmVLZXkoKSkKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgcmV0dXJuIGlzRXF1YWwoQywgUC0+Z2V0VmFsdWUoKSk7CisgICAgfQorCisgICAgc3RhdGljIGJvb2wgaXNFcXVhbChQb29sRW50cnkgKlAxLCBQb29sRW50cnkgKlAyKSB7CisgICAgICBpZiAoUDEgPT0gZ2V0RW1wdHlLZXkoKSB8fCBQMSA9PSBnZXRUb21ic3RvbmVLZXkoKSkKKyAgICAgICAgcmV0dXJuIFAxID09IFAyOworICAgICAgcmV0dXJuIGlzRXF1YWwoUDEtPmdldFZhbHVlKCksIFAyKTsKKyAgICB9CisgIH07CisKKyAgdXNpbmcgRW50cnlTZXRUID0gRGVuc2VTZXQ8UG9vbEVudHJ5ICosIFBvb2xFbnRyeURTSW5mbz47CisKKyAgRW50cnlTZXRUIEVudHJ5U2V0OworCisgIHZvaWQgcmVtb3ZlRW50cnkoUG9vbEVudHJ5ICpQKSB7IEVudHJ5U2V0LmVyYXNlKFApOyB9CisKK3B1YmxpYzoKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFZhbHVlS2V5VD4gUG9vbFJlZiBnZXRWYWx1ZShWYWx1ZUtleVQgVmFsdWVLZXkpIHsKKyAgICB0eXBlbmFtZSBFbnRyeVNldFQ6Oml0ZXJhdG9yIEkgPSBFbnRyeVNldC5maW5kX2FzKFZhbHVlS2V5KTsKKworICAgIGlmIChJICE9IEVudHJ5U2V0LmVuZCgpKQorICAgICAgcmV0dXJuIFBvb2xSZWYoKCpJKS0+c2hhcmVkX2Zyb21fdGhpcygpLCAmKCpJKS0+Z2V0VmFsdWUoKSk7CisKKyAgICBhdXRvIFAgPSBzdGQ6Om1ha2Vfc2hhcmVkPFBvb2xFbnRyeT4oKnRoaXMsIHN0ZDo6bW92ZShWYWx1ZUtleSkpOworICAgIEVudHJ5U2V0Lmluc2VydChQLmdldCgpKTsKKyAgICByZXR1cm4gUG9vbFJlZihzdGQ6Om1vdmUoUCksICZQLT5nZXRWYWx1ZSgpKTsKKyAgfQorfTsKKwordGVtcGxhdGUgPHR5cGVuYW1lIFZlY3RvclQsIHR5cGVuYW1lIE1hdHJpeFQ+IGNsYXNzIFBvb2xDb3N0QWxsb2NhdG9yIHsKK3ByaXZhdGU6CisgIHVzaW5nIFZlY3RvckNvc3RQb29sID0gVmFsdWVQb29sPFZlY3RvclQ+OworICB1c2luZyBNYXRyaXhDb3N0UG9vbCA9IFZhbHVlUG9vbDxNYXRyaXhUPjsKKworcHVibGljOgorICB1c2luZyBWZWN0b3IgPSBWZWN0b3JUOworICB1c2luZyBNYXRyaXggPSBNYXRyaXhUOworICB1c2luZyBWZWN0b3JQdHIgPSB0eXBlbmFtZSBWZWN0b3JDb3N0UG9vbDo6UG9vbFJlZjsKKyAgdXNpbmcgTWF0cml4UHRyID0gdHlwZW5hbWUgTWF0cml4Q29zdFBvb2w6OlBvb2xSZWY7CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFZlY3RvcktleVQ+IFZlY3RvclB0ciBnZXRWZWN0b3IoVmVjdG9yS2V5VCB2KSB7CisgICAgcmV0dXJuIFZlY3RvclBvb2wuZ2V0VmFsdWUoc3RkOjptb3ZlKHYpKTsKKyAgfQorCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBNYXRyaXhLZXlUPiBNYXRyaXhQdHIgZ2V0TWF0cml4KE1hdHJpeEtleVQgbSkgeworICAgIHJldHVybiBNYXRyaXhQb29sLmdldFZhbHVlKHN0ZDo6bW92ZShtKSk7CisgIH0KKworcHJpdmF0ZToKKyAgVmVjdG9yQ29zdFBvb2wgVmVjdG9yUG9vbDsKKyAgTWF0cml4Q29zdFBvb2wgTWF0cml4UG9vbDsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBQQlFQCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1BCUVBfQ09TVEFMTE9DQVRPUl9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUEJRUC9HcmFwaC5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1BCUVAvR3JhcGguaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOTQ4NzhjCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1BCUVAvR3JhcGguaApAQCAtMCwwICsxLDY3NSBAQAorLy89PT0tIEdyYXBoLmggLSBQQlFQIEdyYXBoIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBQQlFQIEdyYXBoIGNsYXNzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1BCUVBfR1JBUEhfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fUEJRUF9HUkFQSF9ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9TVExFeHRyYXMuaCIKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxpdGVyYXRvcj4KKyNpbmNsdWRlIDxsaW1pdHM+CisjaW5jbHVkZSA8dmVjdG9yPgorCituYW1lc3BhY2UgbGx2bSB7CituYW1lc3BhY2UgUEJRUCB7CisKKyAgY2xhc3MgR3JhcGhCYXNlIHsKKyAgcHVibGljOgorICAgIHVzaW5nIE5vZGVJZCA9IHVuc2lnbmVkOworICAgIHVzaW5nIEVkZ2VJZCA9IHVuc2lnbmVkOworCisgICAgLy8vIEBicmllZiBSZXR1cm5zIGEgdmFsdWUgcmVwcmVzZW50aW5nIGFuIGludmFsaWQgKG5vbi1leGlzdGVudCkgbm9kZS4KKyAgICBzdGF0aWMgTm9kZUlkIGludmFsaWROb2RlSWQoKSB7CisgICAgICByZXR1cm4gc3RkOjpudW1lcmljX2xpbWl0czxOb2RlSWQ+OjptYXgoKTsKKyAgICB9CisKKyAgICAvLy8gQGJyaWVmIFJldHVybnMgYSB2YWx1ZSByZXByZXNlbnRpbmcgYW4gaW52YWxpZCAobm9uLWV4aXN0ZW50KSBlZGdlLgorICAgIHN0YXRpYyBFZGdlSWQgaW52YWxpZEVkZ2VJZCgpIHsKKyAgICAgIHJldHVybiBzdGQ6Om51bWVyaWNfbGltaXRzPEVkZ2VJZD46Om1heCgpOworICAgIH0KKyAgfTsKKworICAvLy8gUEJRUCBHcmFwaCBjbGFzcy4KKyAgLy8vIEluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIGRlc2NyaWJlIFBCUVAgcHJvYmxlbXMuCisgIC8vLworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgU29sdmVyVD4KKyAgY2xhc3MgR3JhcGggOiBwdWJsaWMgR3JhcGhCYXNlIHsKKyAgcHJpdmF0ZToKKyAgICB1c2luZyBDb3N0QWxsb2NhdG9yID0gdHlwZW5hbWUgU29sdmVyVDo6Q29zdEFsbG9jYXRvcjsKKworICBwdWJsaWM6CisgICAgdXNpbmcgUmF3VmVjdG9yID0gdHlwZW5hbWUgU29sdmVyVDo6UmF3VmVjdG9yOworICAgIHVzaW5nIFJhd01hdHJpeCA9IHR5cGVuYW1lIFNvbHZlclQ6OlJhd01hdHJpeDsKKyAgICB1c2luZyBWZWN0b3IgPSB0eXBlbmFtZSBTb2x2ZXJUOjpWZWN0b3I7CisgICAgdXNpbmcgTWF0cml4ID0gdHlwZW5hbWUgU29sdmVyVDo6TWF0cml4OworICAgIHVzaW5nIFZlY3RvclB0ciA9IHR5cGVuYW1lIENvc3RBbGxvY2F0b3I6OlZlY3RvclB0cjsKKyAgICB1c2luZyBNYXRyaXhQdHIgPSB0eXBlbmFtZSBDb3N0QWxsb2NhdG9yOjpNYXRyaXhQdHI7CisgICAgdXNpbmcgTm9kZU1ldGFkYXRhID0gdHlwZW5hbWUgU29sdmVyVDo6Tm9kZU1ldGFkYXRhOworICAgIHVzaW5nIEVkZ2VNZXRhZGF0YSA9IHR5cGVuYW1lIFNvbHZlclQ6OkVkZ2VNZXRhZGF0YTsKKyAgICB1c2luZyBHcmFwaE1ldGFkYXRhID0gdHlwZW5hbWUgU29sdmVyVDo6R3JhcGhNZXRhZGF0YTsKKworICBwcml2YXRlOgorICAgIGNsYXNzIE5vZGVFbnRyeSB7CisgICAgcHVibGljOgorICAgICAgdXNpbmcgQWRqRWRnZUxpc3QgPSBzdGQ6OnZlY3RvcjxFZGdlSWQ+OworICAgICAgdXNpbmcgQWRqRWRnZUlkeCA9IEFkakVkZ2VMaXN0OjpzaXplX3R5cGU7CisgICAgICB1c2luZyBBZGpFZGdlSXRyID0gQWRqRWRnZUxpc3Q6OmNvbnN0X2l0ZXJhdG9yOworCisgICAgICBOb2RlRW50cnkoVmVjdG9yUHRyIENvc3RzKSA6IENvc3RzKHN0ZDo6bW92ZShDb3N0cykpIHt9CisKKyAgICAgIHN0YXRpYyBBZGpFZGdlSWR4IGdldEludmFsaWRBZGpFZGdlSWR4KCkgeworICAgICAgICByZXR1cm4gc3RkOjpudW1lcmljX2xpbWl0czxBZGpFZGdlSWR4Pjo6bWF4KCk7CisgICAgICB9CisKKyAgICAgIEFkakVkZ2VJZHggYWRkQWRqRWRnZUlkKEVkZ2VJZCBFSWQpIHsKKyAgICAgICAgQWRqRWRnZUlkeCBJZHggPSBBZGpFZGdlSWRzLnNpemUoKTsKKyAgICAgICAgQWRqRWRnZUlkcy5wdXNoX2JhY2soRUlkKTsKKyAgICAgICAgcmV0dXJuIElkeDsKKyAgICAgIH0KKworICAgICAgdm9pZCByZW1vdmVBZGpFZGdlSWQoR3JhcGggJkcsIE5vZGVJZCBUaGlzTklkLCBBZGpFZGdlSWR4IElkeCkgeworICAgICAgICAvLyBTd2FwLWFuZC1wb3AgZm9yIGZhc3QgcmVtb3ZhbC4KKyAgICAgICAgLy8gICAxKSBVcGRhdGUgdGhlIGFkaiBpbmRleCBvZiB0aGUgZWRnZSBjdXJyZW50bHkgYXQgYmFjaygpLgorICAgICAgICAvLyAgIDIpIE1vdmUgbGFzdCBFZGdlIGRvd24gdG8gSWR4LgorICAgICAgICAvLyAgIDMpIHBvcF9iYWNrKCkKKyAgICAgICAgLy8gSWYgSWR4ID09IHNpemUoKSAtIDEgdGhlbiB0aGUgc2V0QWRqRWRnZUlkeCBhbmQgc3dhcCBhcmUKKyAgICAgICAgLy8gcmVkdW5kYW50LCBidXQgYm90aCBvcGVyYXRpb25zIGFyZSBjaGVhcC4KKyAgICAgICAgRy5nZXRFZGdlKEFkakVkZ2VJZHMuYmFjaygpKS5zZXRBZGpFZGdlSWR4KFRoaXNOSWQsIElkeCk7CisgICAgICAgIEFkakVkZ2VJZHNbSWR4XSA9IEFkakVkZ2VJZHMuYmFjaygpOworICAgICAgICBBZGpFZGdlSWRzLnBvcF9iYWNrKCk7CisgICAgICB9CisKKyAgICAgIGNvbnN0IEFkakVkZ2VMaXN0JiBnZXRBZGpFZGdlSWRzKCkgY29uc3QgeyByZXR1cm4gQWRqRWRnZUlkczsgfQorCisgICAgICBWZWN0b3JQdHIgQ29zdHM7CisgICAgICBOb2RlTWV0YWRhdGEgTWV0YWRhdGE7CisKKyAgICBwcml2YXRlOgorICAgICAgQWRqRWRnZUxpc3QgQWRqRWRnZUlkczsKKyAgICB9OworCisgICAgY2xhc3MgRWRnZUVudHJ5IHsKKyAgICBwdWJsaWM6CisgICAgICBFZGdlRW50cnkoTm9kZUlkIE4xSWQsIE5vZGVJZCBOMklkLCBNYXRyaXhQdHIgQ29zdHMpCisgICAgICAgICAgOiBDb3N0cyhzdGQ6Om1vdmUoQ29zdHMpKSB7CisgICAgICAgIE5JZHNbMF0gPSBOMUlkOworICAgICAgICBOSWRzWzFdID0gTjJJZDsKKyAgICAgICAgVGhpc0VkZ2VBZGpJZHhzWzBdID0gTm9kZUVudHJ5OjpnZXRJbnZhbGlkQWRqRWRnZUlkeCgpOworICAgICAgICBUaGlzRWRnZUFkaklkeHNbMV0gPSBOb2RlRW50cnk6OmdldEludmFsaWRBZGpFZGdlSWR4KCk7CisgICAgICB9CisKKyAgICAgIHZvaWQgY29ubmVjdFRvTihHcmFwaCAmRywgRWRnZUlkIFRoaXNFZGdlSWQsIHVuc2lnbmVkIE5JZHgpIHsKKyAgICAgICAgYXNzZXJ0KFRoaXNFZGdlQWRqSWR4c1tOSWR4XSA9PSBOb2RlRW50cnk6OmdldEludmFsaWRBZGpFZGdlSWR4KCkgJiYKKyAgICAgICAgICAgICAgICJFZGdlIGFscmVhZHkgY29ubmVjdGVkIHRvIE5JZHNbTklkeF0uIik7CisgICAgICAgIE5vZGVFbnRyeSAmTiA9IEcuZ2V0Tm9kZShOSWRzW05JZHhdKTsKKyAgICAgICAgVGhpc0VkZ2VBZGpJZHhzW05JZHhdID0gTi5hZGRBZGpFZGdlSWQoVGhpc0VkZ2VJZCk7CisgICAgICB9CisKKyAgICAgIHZvaWQgY29ubmVjdChHcmFwaCAmRywgRWRnZUlkIFRoaXNFZGdlSWQpIHsKKyAgICAgICAgY29ubmVjdFRvTihHLCBUaGlzRWRnZUlkLCAwKTsKKyAgICAgICAgY29ubmVjdFRvTihHLCBUaGlzRWRnZUlkLCAxKTsKKyAgICAgIH0KKworICAgICAgdm9pZCBzZXRBZGpFZGdlSWR4KE5vZGVJZCBOSWQsIHR5cGVuYW1lIE5vZGVFbnRyeTo6QWRqRWRnZUlkeCBOZXdJZHgpIHsKKyAgICAgICAgaWYgKE5JZCA9PSBOSWRzWzBdKQorICAgICAgICAgIFRoaXNFZGdlQWRqSWR4c1swXSA9IE5ld0lkeDsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgYXNzZXJ0KE5JZCA9PSBOSWRzWzFdICYmICJFZGdlIG5vdCBjb25uZWN0ZWQgdG8gTklkIik7CisgICAgICAgICAgVGhpc0VkZ2VBZGpJZHhzWzFdID0gTmV3SWR4OworICAgICAgICB9CisgICAgICB9CisKKyAgICAgIHZvaWQgZGlzY29ubmVjdEZyb21OKEdyYXBoICZHLCB1bnNpZ25lZCBOSWR4KSB7CisgICAgICAgIGFzc2VydChUaGlzRWRnZUFkaklkeHNbTklkeF0gIT0gTm9kZUVudHJ5OjpnZXRJbnZhbGlkQWRqRWRnZUlkeCgpICYmCisgICAgICAgICAgICAgICAiRWRnZSBub3QgY29ubmVjdGVkIHRvIE5JZHNbTklkeF0uIik7CisgICAgICAgIE5vZGVFbnRyeSAmTiA9IEcuZ2V0Tm9kZShOSWRzW05JZHhdKTsKKyAgICAgICAgTi5yZW1vdmVBZGpFZGdlSWQoRywgTklkc1tOSWR4XSwgVGhpc0VkZ2VBZGpJZHhzW05JZHhdKTsKKyAgICAgICAgVGhpc0VkZ2VBZGpJZHhzW05JZHhdID0gTm9kZUVudHJ5OjpnZXRJbnZhbGlkQWRqRWRnZUlkeCgpOworICAgICAgfQorCisgICAgICB2b2lkIGRpc2Nvbm5lY3RGcm9tKEdyYXBoICZHLCBOb2RlSWQgTklkKSB7CisgICAgICAgIGlmIChOSWQgPT0gTklkc1swXSkKKyAgICAgICAgICBkaXNjb25uZWN0RnJvbU4oRywgMCk7CisgICAgICAgIGVsc2UgeworICAgICAgICAgIGFzc2VydChOSWQgPT0gTklkc1sxXSAmJiAiRWRnZSBkb2VzIG5vdCBjb25uZWN0IE5JZCIpOworICAgICAgICAgIGRpc2Nvbm5lY3RGcm9tTihHLCAxKTsKKyAgICAgICAgfQorICAgICAgfQorCisgICAgICBOb2RlSWQgZ2V0TjFJZCgpIGNvbnN0IHsgcmV0dXJuIE5JZHNbMF07IH0KKyAgICAgIE5vZGVJZCBnZXROMklkKCkgY29uc3QgeyByZXR1cm4gTklkc1sxXTsgfQorCisgICAgICBNYXRyaXhQdHIgQ29zdHM7CisgICAgICBFZGdlTWV0YWRhdGEgTWV0YWRhdGE7CisKKyAgICBwcml2YXRlOgorICAgICAgTm9kZUlkIE5JZHNbMl07CisgICAgICB0eXBlbmFtZSBOb2RlRW50cnk6OkFkakVkZ2VJZHggVGhpc0VkZ2VBZGpJZHhzWzJdOworICAgIH07CisKKyAgICAvLyAtLS0tLSBNRU1CRVJTIC0tLS0tCisKKyAgICBHcmFwaE1ldGFkYXRhIE1ldGFkYXRhOworICAgIENvc3RBbGxvY2F0b3IgQ29zdEFsbG9jOworICAgIFNvbHZlclQgKlNvbHZlciA9IG51bGxwdHI7CisKKyAgICB1c2luZyBOb2RlVmVjdG9yID0gc3RkOjp2ZWN0b3I8Tm9kZUVudHJ5PjsKKyAgICB1c2luZyBGcmVlTm9kZVZlY3RvciA9IHN0ZDo6dmVjdG9yPE5vZGVJZD47CisgICAgTm9kZVZlY3RvciBOb2RlczsKKyAgICBGcmVlTm9kZVZlY3RvciBGcmVlTm9kZUlkczsKKworICAgIHVzaW5nIEVkZ2VWZWN0b3IgPSBzdGQ6OnZlY3RvcjxFZGdlRW50cnk+OworICAgIHVzaW5nIEZyZWVFZGdlVmVjdG9yID0gc3RkOjp2ZWN0b3I8RWRnZUlkPjsKKyAgICBFZGdlVmVjdG9yIEVkZ2VzOworICAgIEZyZWVFZGdlVmVjdG9yIEZyZWVFZGdlSWRzOworCisgICAgR3JhcGgoY29uc3QgR3JhcGggJk90aGVyKSB7fQorCisgICAgLy8gLS0tLS0gSU5URVJOQUwgTUVUSE9EUyAtLS0tLQorCisgICAgTm9kZUVudHJ5ICZnZXROb2RlKE5vZGVJZCBOSWQpIHsKKyAgICAgIGFzc2VydChOSWQgPCBOb2Rlcy5zaXplKCkgJiYgIk91dCBvZiBib3VuZCBOb2RlSWQiKTsKKyAgICAgIHJldHVybiBOb2Rlc1tOSWRdOworICAgIH0KKyAgICBjb25zdCBOb2RlRW50cnkgJmdldE5vZGUoTm9kZUlkIE5JZCkgY29uc3QgeworICAgICAgYXNzZXJ0KE5JZCA8IE5vZGVzLnNpemUoKSAmJiAiT3V0IG9mIGJvdW5kIE5vZGVJZCIpOworICAgICAgcmV0dXJuIE5vZGVzW05JZF07CisgICAgfQorCisgICAgRWRnZUVudHJ5JiBnZXRFZGdlKEVkZ2VJZCBFSWQpIHsgcmV0dXJuIEVkZ2VzW0VJZF07IH0KKyAgICBjb25zdCBFZGdlRW50cnkmIGdldEVkZ2UoRWRnZUlkIEVJZCkgY29uc3QgeyByZXR1cm4gRWRnZXNbRUlkXTsgfQorCisgICAgTm9kZUlkIGFkZENvbnN0cnVjdGVkTm9kZShOb2RlRW50cnkgTikgeworICAgICAgTm9kZUlkIE5JZCA9IDA7CisgICAgICBpZiAoIUZyZWVOb2RlSWRzLmVtcHR5KCkpIHsKKyAgICAgICAgTklkID0gRnJlZU5vZGVJZHMuYmFjaygpOworICAgICAgICBGcmVlTm9kZUlkcy5wb3BfYmFjaygpOworICAgICAgICBOb2Rlc1tOSWRdID0gc3RkOjptb3ZlKE4pOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgTklkID0gTm9kZXMuc2l6ZSgpOworICAgICAgICBOb2Rlcy5wdXNoX2JhY2soc3RkOjptb3ZlKE4pKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBOSWQ7CisgICAgfQorCisgICAgRWRnZUlkIGFkZENvbnN0cnVjdGVkRWRnZShFZGdlRW50cnkgRSkgeworICAgICAgYXNzZXJ0KGZpbmRFZGdlKEUuZ2V0TjFJZCgpLCBFLmdldE4ySWQoKSkgPT0gaW52YWxpZEVkZ2VJZCgpICYmCisgICAgICAgICAgICAgIkF0dGVtcHQgdG8gYWRkIGR1cGxpY2F0ZSBlZGdlLiIpOworICAgICAgRWRnZUlkIEVJZCA9IDA7CisgICAgICBpZiAoIUZyZWVFZGdlSWRzLmVtcHR5KCkpIHsKKyAgICAgICAgRUlkID0gRnJlZUVkZ2VJZHMuYmFjaygpOworICAgICAgICBGcmVlRWRnZUlkcy5wb3BfYmFjaygpOworICAgICAgICBFZGdlc1tFSWRdID0gc3RkOjptb3ZlKEUpOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgRUlkID0gRWRnZXMuc2l6ZSgpOworICAgICAgICBFZGdlcy5wdXNoX2JhY2soc3RkOjptb3ZlKEUpKTsKKyAgICAgIH0KKworICAgICAgRWRnZUVudHJ5ICZORSA9IGdldEVkZ2UoRUlkKTsKKworICAgICAgLy8gQWRkIHRoZSBlZGdlIHRvIHRoZSBhZGphY2VuY3kgc2V0cyBvZiBpdHMgbm9kZXMuCisgICAgICBORS5jb25uZWN0KCp0aGlzLCBFSWQpOworICAgICAgcmV0dXJuIEVJZDsKKyAgICB9CisKKyAgICB2b2lkIG9wZXJhdG9yPShjb25zdCBHcmFwaCAmT3RoZXIpIHt9CisKKyAgcHVibGljOgorICAgIHVzaW5nIEFkakVkZ2VJdHIgPSB0eXBlbmFtZSBOb2RlRW50cnk6OkFkakVkZ2VJdHI7CisKKyAgICBjbGFzcyBOb2RlSXRyIHsKKyAgICBwdWJsaWM6CisgICAgICB1c2luZyBpdGVyYXRvcl9jYXRlZ29yeSA9IHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWc7CisgICAgICB1c2luZyB2YWx1ZV90eXBlID0gTm9kZUlkOworICAgICAgdXNpbmcgZGlmZmVyZW5jZV90eXBlID0gaW50OworICAgICAgdXNpbmcgcG9pbnRlciA9IE5vZGVJZCAqOworICAgICAgdXNpbmcgcmVmZXJlbmNlID0gTm9kZUlkICY7CisKKyAgICAgIE5vZGVJdHIoTm9kZUlkIEN1ck5JZCwgY29uc3QgR3JhcGggJkcpCisgICAgICAgIDogQ3VyTklkKEN1ck5JZCksIEVuZE5JZChHLk5vZGVzLnNpemUoKSksIEZyZWVOb2RlSWRzKEcuRnJlZU5vZGVJZHMpIHsKKyAgICAgICAgdGhpcy0+Q3VyTklkID0gZmluZE5leHRJblVzZShDdXJOSWQpOyAvLyBNb3ZlIHRvIGZpcnN0IGluLXVzZSBub2RlIGlkCisgICAgICB9CisKKyAgICAgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBOb2RlSXRyICZPKSBjb25zdCB7IHJldHVybiBDdXJOSWQgPT0gTy5DdXJOSWQ7IH0KKyAgICAgIGJvb2wgb3BlcmF0b3IhPShjb25zdCBOb2RlSXRyICZPKSBjb25zdCB7IHJldHVybiAhKCp0aGlzID09IE8pOyB9CisgICAgICBOb2RlSXRyJiBvcGVyYXRvcisrKCkgeyBDdXJOSWQgPSBmaW5kTmV4dEluVXNlKCsrQ3VyTklkKTsgcmV0dXJuICp0aGlzOyB9CisgICAgICBOb2RlSWQgb3BlcmF0b3IqKCkgY29uc3QgeyByZXR1cm4gQ3VyTklkOyB9CisKKyAgICBwcml2YXRlOgorICAgICAgTm9kZUlkIGZpbmROZXh0SW5Vc2UoTm9kZUlkIE5JZCkgY29uc3QgeworICAgICAgICB3aGlsZSAoTklkIDwgRW5kTklkICYmIGlzX2NvbnRhaW5lZChGcmVlTm9kZUlkcywgTklkKSkgeworICAgICAgICAgICsrTklkOworICAgICAgICB9CisgICAgICAgIHJldHVybiBOSWQ7CisgICAgICB9CisKKyAgICAgIE5vZGVJZCBDdXJOSWQsIEVuZE5JZDsKKyAgICAgIGNvbnN0IEZyZWVOb2RlVmVjdG9yICZGcmVlTm9kZUlkczsKKyAgICB9OworCisgICAgY2xhc3MgRWRnZUl0ciB7CisgICAgcHVibGljOgorICAgICAgRWRnZUl0cihFZGdlSWQgQ3VyRUlkLCBjb25zdCBHcmFwaCAmRykKKyAgICAgICAgOiBDdXJFSWQoQ3VyRUlkKSwgRW5kRUlkKEcuRWRnZXMuc2l6ZSgpKSwgRnJlZUVkZ2VJZHMoRy5GcmVlRWRnZUlkcykgeworICAgICAgICB0aGlzLT5DdXJFSWQgPSBmaW5kTmV4dEluVXNlKEN1ckVJZCk7IC8vIE1vdmUgdG8gZmlyc3QgaW4tdXNlIGVkZ2UgaWQKKyAgICAgIH0KKworICAgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IEVkZ2VJdHIgJk8pIGNvbnN0IHsgcmV0dXJuIEN1ckVJZCA9PSBPLkN1ckVJZDsgfQorICAgICAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IEVkZ2VJdHIgJk8pIGNvbnN0IHsgcmV0dXJuICEoKnRoaXMgPT0gTyk7IH0KKyAgICAgIEVkZ2VJdHImIG9wZXJhdG9yKysoKSB7IEN1ckVJZCA9IGZpbmROZXh0SW5Vc2UoKytDdXJFSWQpOyByZXR1cm4gKnRoaXM7IH0KKyAgICAgIEVkZ2VJZCBvcGVyYXRvciooKSBjb25zdCB7IHJldHVybiBDdXJFSWQ7IH0KKworICAgIHByaXZhdGU6CisgICAgICBFZGdlSWQgZmluZE5leHRJblVzZShFZGdlSWQgRUlkKSBjb25zdCB7CisgICAgICAgIHdoaWxlIChFSWQgPCBFbmRFSWQgJiYgaXNfY29udGFpbmVkKEZyZWVFZGdlSWRzLCBFSWQpKSB7CisgICAgICAgICAgKytFSWQ7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIEVJZDsKKyAgICAgIH0KKworICAgICAgRWRnZUlkIEN1ckVJZCwgRW5kRUlkOworICAgICAgY29uc3QgRnJlZUVkZ2VWZWN0b3IgJkZyZWVFZGdlSWRzOworICAgIH07CisKKyAgICBjbGFzcyBOb2RlSWRTZXQgeworICAgIHB1YmxpYzoKKyAgICAgIE5vZGVJZFNldChjb25zdCBHcmFwaCAmRykgOiBHKEcpIHt9CisKKyAgICAgIE5vZGVJdHIgYmVnaW4oKSBjb25zdCB7IHJldHVybiBOb2RlSXRyKDAsIEcpOyB9CisgICAgICBOb2RlSXRyIGVuZCgpIGNvbnN0IHsgcmV0dXJuIE5vZGVJdHIoRy5Ob2Rlcy5zaXplKCksIEcpOyB9CisKKyAgICAgIGJvb2wgZW1wdHkoKSBjb25zdCB7IHJldHVybiBHLk5vZGVzLmVtcHR5KCk7IH0KKworICAgICAgdHlwZW5hbWUgTm9kZVZlY3Rvcjo6c2l6ZV90eXBlIHNpemUoKSBjb25zdCB7CisgICAgICAgIHJldHVybiBHLk5vZGVzLnNpemUoKSAtIEcuRnJlZU5vZGVJZHMuc2l6ZSgpOworICAgICAgfQorCisgICAgcHJpdmF0ZToKKyAgICAgIGNvbnN0IEdyYXBoJiBHOworICAgIH07CisKKyAgICBjbGFzcyBFZGdlSWRTZXQgeworICAgIHB1YmxpYzoKKyAgICAgIEVkZ2VJZFNldChjb25zdCBHcmFwaCAmRykgOiBHKEcpIHt9CisKKyAgICAgIEVkZ2VJdHIgYmVnaW4oKSBjb25zdCB7IHJldHVybiBFZGdlSXRyKDAsIEcpOyB9CisgICAgICBFZGdlSXRyIGVuZCgpIGNvbnN0IHsgcmV0dXJuIEVkZ2VJdHIoRy5FZGdlcy5zaXplKCksIEcpOyB9CisKKyAgICAgIGJvb2wgZW1wdHkoKSBjb25zdCB7IHJldHVybiBHLkVkZ2VzLmVtcHR5KCk7IH0KKworICAgICAgdHlwZW5hbWUgTm9kZVZlY3Rvcjo6c2l6ZV90eXBlIHNpemUoKSBjb25zdCB7CisgICAgICAgIHJldHVybiBHLkVkZ2VzLnNpemUoKSAtIEcuRnJlZUVkZ2VJZHMuc2l6ZSgpOworICAgICAgfQorCisgICAgcHJpdmF0ZToKKyAgICAgIGNvbnN0IEdyYXBoJiBHOworICAgIH07CisKKyAgICBjbGFzcyBBZGpFZGdlSWRTZXQgeworICAgIHB1YmxpYzoKKyAgICAgIEFkakVkZ2VJZFNldChjb25zdCBOb2RlRW50cnkgJk5FKSA6IE5FKE5FKSB7fQorCisgICAgICB0eXBlbmFtZSBOb2RlRW50cnk6OkFkakVkZ2VJdHIgYmVnaW4oKSBjb25zdCB7CisgICAgICAgIHJldHVybiBORS5nZXRBZGpFZGdlSWRzKCkuYmVnaW4oKTsKKyAgICAgIH0KKworICAgICAgdHlwZW5hbWUgTm9kZUVudHJ5OjpBZGpFZGdlSXRyIGVuZCgpIGNvbnN0IHsKKyAgICAgICAgcmV0dXJuIE5FLmdldEFkakVkZ2VJZHMoKS5lbmQoKTsKKyAgICAgIH0KKworICAgICAgYm9vbCBlbXB0eSgpIGNvbnN0IHsgcmV0dXJuIE5FLmdldEFkakVkZ2VJZHMoKS5lbXB0eSgpOyB9CisKKyAgICAgIHR5cGVuYW1lIE5vZGVFbnRyeTo6QWRqRWRnZUxpc3Q6OnNpemVfdHlwZSBzaXplKCkgY29uc3QgeworICAgICAgICByZXR1cm4gTkUuZ2V0QWRqRWRnZUlkcygpLnNpemUoKTsKKyAgICAgIH0KKworICAgIHByaXZhdGU6CisgICAgICBjb25zdCBOb2RlRW50cnkgJk5FOworICAgIH07CisKKyAgICAvLy8gQGJyaWVmIENvbnN0cnVjdCBhbiBlbXB0eSBQQlFQIGdyYXBoLgorICAgIEdyYXBoKCkgPSBkZWZhdWx0OworCisgICAgLy8vIEBicmllZiBDb25zdHJ1Y3QgYW4gZW1wdHkgUEJRUCBncmFwaCB3aXRoIHRoZSBnaXZlbiBncmFwaCBtZXRhZGF0YS4KKyAgICBHcmFwaChHcmFwaE1ldGFkYXRhIE1ldGFkYXRhKSA6IE1ldGFkYXRhKHN0ZDo6bW92ZShNZXRhZGF0YSkpIHt9CisKKyAgICAvLy8gQGJyaWVmIEdldCBhIHJlZmVyZW5jZSB0byB0aGUgZ3JhcGggbWV0YWRhdGEuCisgICAgR3JhcGhNZXRhZGF0YSYgZ2V0TWV0YWRhdGEoKSB7IHJldHVybiBNZXRhZGF0YTsgfQorCisgICAgLy8vIEBicmllZiBHZXQgYSBjb25zdC1yZWZlcmVuY2UgdG8gdGhlIGdyYXBoIG1ldGFkYXRhLgorICAgIGNvbnN0IEdyYXBoTWV0YWRhdGEmIGdldE1ldGFkYXRhKCkgY29uc3QgeyByZXR1cm4gTWV0YWRhdGE7IH0KKworICAgIC8vLyBAYnJpZWYgTG9jayB0aGlzIGdyYXBoIHRvIHRoZSBnaXZlbiBzb2x2ZXIgaW5zdGFuY2UgaW4gcHJlcGFyYXRpb24KKyAgICAvLy8gZm9yIHJ1bm5pbmcgdGhlIHNvbHZlci4gVGhpcyBtZXRob2Qgd2lsbCBjYWxsIHNvbHZlci5oYW5kbGVBZGROb2RlIGZvcgorICAgIC8vLyBlYWNoIG5vZGUgaW4gdGhlIGdyYXBoLCBhbmQgaGFuZGxlQWRkRWRnZSBmb3IgZWFjaCBlZGdlLCB0byBnaXZlIHRoZQorICAgIC8vLyBzb2x2ZXIgYW4gb3Bwb3J0dW5pdHkgdG8gc2V0IHVwIGFueSByZXF1cmllZCBtZXRhZGF0YS4KKyAgICB2b2lkIHNldFNvbHZlcihTb2x2ZXJUICZTKSB7CisgICAgICBhc3NlcnQoIVNvbHZlciAmJiAiU29sdmVyIGFscmVhZHkgc2V0LiBDYWxsIHVuc2V0U29sdmVyKCkuIik7CisgICAgICBTb2x2ZXIgPSAmUzsKKyAgICAgIGZvciAoYXV0byBOSWQgOiBub2RlSWRzKCkpCisgICAgICAgIFNvbHZlci0+aGFuZGxlQWRkTm9kZShOSWQpOworICAgICAgZm9yIChhdXRvIEVJZCA6IGVkZ2VJZHMoKSkKKyAgICAgICAgU29sdmVyLT5oYW5kbGVBZGRFZGdlKEVJZCk7CisgICAgfQorCisgICAgLy8vIEBicmllZiBSZWxlYXNlIGZyb20gc29sdmVyIGluc3RhbmNlLgorICAgIHZvaWQgdW5zZXRTb2x2ZXIoKSB7CisgICAgICBhc3NlcnQoU29sdmVyICYmICJTb2x2ZXIgbm90IHNldC4iKTsKKyAgICAgIFNvbHZlciA9IG51bGxwdHI7CisgICAgfQorCisgICAgLy8vIEBicmllZiBBZGQgYSBub2RlIHdpdGggdGhlIGdpdmVuIGNvc3RzLgorICAgIC8vLyBAcGFyYW0gQ29zdHMgQ29zdCB2ZWN0b3IgZm9yIHRoZSBuZXcgbm9kZS4KKyAgICAvLy8gQHJldHVybiBOb2RlIGl0ZXJhdG9yIGZvciB0aGUgYWRkZWQgbm9kZS4KKyAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgT3RoZXJWZWN0b3JUPgorICAgIE5vZGVJZCBhZGROb2RlKE90aGVyVmVjdG9yVCBDb3N0cykgeworICAgICAgLy8gR2V0IGNvc3QgdmVjdG9yIGZyb20gdGhlIHByb2JsZW0gZG9tYWluCisgICAgICBWZWN0b3JQdHIgQWxsb2NhdGVkQ29zdHMgPSBDb3N0QWxsb2MuZ2V0VmVjdG9yKHN0ZDo6bW92ZShDb3N0cykpOworICAgICAgTm9kZUlkIE5JZCA9IGFkZENvbnN0cnVjdGVkTm9kZShOb2RlRW50cnkoQWxsb2NhdGVkQ29zdHMpKTsKKyAgICAgIGlmIChTb2x2ZXIpCisgICAgICAgIFNvbHZlci0+aGFuZGxlQWRkTm9kZShOSWQpOworICAgICAgcmV0dXJuIE5JZDsKKyAgICB9CisKKyAgICAvLy8gQGJyaWVmIEFkZCBhIG5vZGUgYnlwYXNzaW5nIHRoZSBjb3N0IGFsbG9jYXRvci4KKyAgICAvLy8gQHBhcmFtIENvc3RzIENvc3QgdmVjdG9yIHB0ciBmb3IgdGhlIG5ldyBub2RlIChtdXN0IGJlIGNvbnZlcnRpYmxlIHRvCisgICAgLy8vICAgICAgICBWZWN0b3JQdHIpLgorICAgIC8vLyBAcmV0dXJuIE5vZGUgaXRlcmF0b3IgZm9yIHRoZSBhZGRlZCBub2RlLgorICAgIC8vLworICAgIC8vLyAgIFRoaXMgbWV0aG9kIGFsbG93cyBmb3IgZmFzdCBhZGRpdGlvbiBvZiBhIG5vZGUgd2hvc2UgY29zdHMgZG9uJ3QgbmVlZAorICAgIC8vLyB0byBiZSBwYXNzZWQgdGhyb3VnaCB0aGUgY29zdCBhbGxvY2F0b3IuIFRoZSBtb3N0IGNvbW1vbiB1c2UgY2FzZSBmb3IKKyAgICAvLy8gdGhpcyBpcyB3aGVuIGR1cGxpY2F0aW5nIGNvc3RzIGZyb20gYW4gZXhpc3Rpbmcgbm9kZSAod2hlbiB1c2luZyBhCisgICAgLy8vIHBvb2xpbmcgYWxsb2NhdG9yKS4gVGhlc2UgaGF2ZSBhbHJlYWR5IGJlZW4gdW5pcXVlZCwgc28gd2UgY2FuIGF2b2lkCisgICAgLy8vIHJlLWNvbnN0cnVjdGluZyBhbmQgcmUtdW5pcXVpbmcgdGhlbSBieSBhdHRhY2hpbmcgdGhlbSBkaXJlY3RseSB0byB0aGUKKyAgICAvLy8gbmV3IG5vZGUuCisgICAgdGVtcGxhdGUgPHR5cGVuYW1lIE90aGVyVmVjdG9yUHRyVD4KKyAgICBOb2RlSWQgYWRkTm9kZUJ5cGFzc2luZ0Nvc3RBbGxvY2F0b3IoT3RoZXJWZWN0b3JQdHJUIENvc3RzKSB7CisgICAgICBOb2RlSWQgTklkID0gYWRkQ29uc3RydWN0ZWROb2RlKE5vZGVFbnRyeShDb3N0cykpOworICAgICAgaWYgKFNvbHZlcikKKyAgICAgICAgU29sdmVyLT5oYW5kbGVBZGROb2RlKE5JZCk7CisgICAgICByZXR1cm4gTklkOworICAgIH0KKworICAgIC8vLyBAYnJpZWYgQWRkIGFuIGVkZ2UgYmV0d2VlbiB0aGUgZ2l2ZW4gbm9kZXMgd2l0aCB0aGUgZ2l2ZW4gY29zdHMuCisgICAgLy8vIEBwYXJhbSBOMUlkIEZpcnN0IG5vZGUuCisgICAgLy8vIEBwYXJhbSBOMklkIFNlY29uZCBub2RlLgorICAgIC8vLyBAcGFyYW0gQ29zdHMgQ29zdCBtYXRyaXggZm9yIG5ldyBlZGdlLgorICAgIC8vLyBAcmV0dXJuIEVkZ2UgaXRlcmF0b3IgZm9yIHRoZSBhZGRlZCBlZGdlLgorICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBPdGhlclZlY3RvclQ+CisgICAgRWRnZUlkIGFkZEVkZ2UoTm9kZUlkIE4xSWQsIE5vZGVJZCBOMklkLCBPdGhlclZlY3RvclQgQ29zdHMpIHsKKyAgICAgIGFzc2VydChnZXROb2RlQ29zdHMoTjFJZCkuZ2V0TGVuZ3RoKCkgPT0gQ29zdHMuZ2V0Um93cygpICYmCisgICAgICAgICAgICAgZ2V0Tm9kZUNvc3RzKE4ySWQpLmdldExlbmd0aCgpID09IENvc3RzLmdldENvbHMoKSAmJgorICAgICAgICAgICAgICJNYXRyaXggZGltZW5zaW9ucyBtaXNtYXRjaC4iKTsKKyAgICAgIC8vIEdldCBjb3N0IG1hdHJpeCBmcm9tIHRoZSBwcm9ibGVtIGRvbWFpbi4KKyAgICAgIE1hdHJpeFB0ciBBbGxvY2F0ZWRDb3N0cyA9IENvc3RBbGxvYy5nZXRNYXRyaXgoc3RkOjptb3ZlKENvc3RzKSk7CisgICAgICBFZGdlSWQgRUlkID0gYWRkQ29uc3RydWN0ZWRFZGdlKEVkZ2VFbnRyeShOMUlkLCBOMklkLCBBbGxvY2F0ZWRDb3N0cykpOworICAgICAgaWYgKFNvbHZlcikKKyAgICAgICAgU29sdmVyLT5oYW5kbGVBZGRFZGdlKEVJZCk7CisgICAgICByZXR1cm4gRUlkOworICAgIH0KKworICAgIC8vLyBAYnJpZWYgQWRkIGFuIGVkZ2UgYnlwYXNzaW5nIHRoZSBjb3N0IGFsbG9jYXRvci4KKyAgICAvLy8gQHBhcmFtIE4xSWQgRmlyc3Qgbm9kZS4KKyAgICAvLy8gQHBhcmFtIE4ySWQgU2Vjb25kIG5vZGUuCisgICAgLy8vIEBwYXJhbSBDb3N0cyBDb3N0IG1hdHJpeCBmb3IgbmV3IGVkZ2UuCisgICAgLy8vIEByZXR1cm4gRWRnZSBpdGVyYXRvciBmb3IgdGhlIGFkZGVkIGVkZ2UuCisgICAgLy8vCisgICAgLy8vICAgVGhpcyBtZXRob2QgYWxsb3dzIGZvciBmYXN0IGFkZGl0aW9uIG9mIGFuIGVkZ2Ugd2hvc2UgY29zdHMgZG9uJ3QgbmVlZAorICAgIC8vLyB0byBiZSBwYXNzZWQgdGhyb3VnaCB0aGUgY29zdCBhbGxvY2F0b3IuIFRoZSBtb3N0IGNvbW1vbiB1c2UgY2FzZSBmb3IKKyAgICAvLy8gdGhpcyBpcyB3aGVuIGR1cGxpY2F0aW5nIGNvc3RzIGZyb20gYW4gZXhpc3RpbmcgZWRnZSAod2hlbiB1c2luZyBhCisgICAgLy8vIHBvb2xpbmcgYWxsb2NhdG9yKS4gVGhlc2UgaGF2ZSBhbHJlYWR5IGJlZW4gdW5pcXVlZCwgc28gd2UgY2FuIGF2b2lkCisgICAgLy8vIHJlLWNvbnN0cnVjdGluZyBhbmQgcmUtdW5pcXVpbmcgdGhlbSBieSBhdHRhY2hpbmcgdGhlbSBkaXJlY3RseSB0byB0aGUKKyAgICAvLy8gbmV3IGVkZ2UuCisgICAgdGVtcGxhdGUgPHR5cGVuYW1lIE90aGVyTWF0cml4UHRyVD4KKyAgICBOb2RlSWQgYWRkRWRnZUJ5cGFzc2luZ0Nvc3RBbGxvY2F0b3IoTm9kZUlkIE4xSWQsIE5vZGVJZCBOMklkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPdGhlck1hdHJpeFB0clQgQ29zdHMpIHsKKyAgICAgIGFzc2VydChnZXROb2RlQ29zdHMoTjFJZCkuZ2V0TGVuZ3RoKCkgPT0gQ29zdHMtPmdldFJvd3MoKSAmJgorICAgICAgICAgICAgIGdldE5vZGVDb3N0cyhOMklkKS5nZXRMZW5ndGgoKSA9PSBDb3N0cy0+Z2V0Q29scygpICYmCisgICAgICAgICAgICAgIk1hdHJpeCBkaW1lbnNpb25zIG1pc21hdGNoLiIpOworICAgICAgLy8gR2V0IGNvc3QgbWF0cml4IGZyb20gdGhlIHByb2JsZW0gZG9tYWluLgorICAgICAgRWRnZUlkIEVJZCA9IGFkZENvbnN0cnVjdGVkRWRnZShFZGdlRW50cnkoTjFJZCwgTjJJZCwgQ29zdHMpKTsKKyAgICAgIGlmIChTb2x2ZXIpCisgICAgICAgIFNvbHZlci0+aGFuZGxlQWRkRWRnZShFSWQpOworICAgICAgcmV0dXJuIEVJZDsKKyAgICB9CisKKyAgICAvLy8gQGJyaWVmIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ3JhcGggaXMgZW1wdHkuCisgICAgYm9vbCBlbXB0eSgpIGNvbnN0IHsgcmV0dXJuIE5vZGVJZFNldCgqdGhpcykuZW1wdHkoKTsgfQorCisgICAgTm9kZUlkU2V0IG5vZGVJZHMoKSBjb25zdCB7IHJldHVybiBOb2RlSWRTZXQoKnRoaXMpOyB9CisgICAgRWRnZUlkU2V0IGVkZ2VJZHMoKSBjb25zdCB7IHJldHVybiBFZGdlSWRTZXQoKnRoaXMpOyB9CisKKyAgICBBZGpFZGdlSWRTZXQgYWRqRWRnZUlkcyhOb2RlSWQgTklkKSB7IHJldHVybiBBZGpFZGdlSWRTZXQoZ2V0Tm9kZShOSWQpKTsgfQorCisgICAgLy8vIEBicmllZiBHZXQgdGhlIG51bWJlciBvZiBub2RlcyBpbiB0aGUgZ3JhcGguCisgICAgLy8vIEByZXR1cm4gTnVtYmVyIG9mIG5vZGVzIGluIHRoZSBncmFwaC4KKyAgICB1bnNpZ25lZCBnZXROdW1Ob2RlcygpIGNvbnN0IHsgcmV0dXJuIE5vZGVJZFNldCgqdGhpcykuc2l6ZSgpOyB9CisKKyAgICAvLy8gQGJyaWVmIEdldCB0aGUgbnVtYmVyIG9mIGVkZ2VzIGluIHRoZSBncmFwaC4KKyAgICAvLy8gQHJldHVybiBOdW1iZXIgb2YgZWRnZXMgaW4gdGhlIGdyYXBoLgorICAgIHVuc2lnbmVkIGdldE51bUVkZ2VzKCkgY29uc3QgeyByZXR1cm4gRWRnZUlkU2V0KCp0aGlzKS5zaXplKCk7IH0KKworICAgIC8vLyBAYnJpZWYgU2V0IGEgbm9kZSdzIGNvc3QgdmVjdG9yLgorICAgIC8vLyBAcGFyYW0gTklkIE5vZGUgdG8gdXBkYXRlLgorICAgIC8vLyBAcGFyYW0gQ29zdHMgTmV3IGNvc3RzIHRvIHNldC4KKyAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgT3RoZXJWZWN0b3JUPgorICAgIHZvaWQgc2V0Tm9kZUNvc3RzKE5vZGVJZCBOSWQsIE90aGVyVmVjdG9yVCBDb3N0cykgeworICAgICAgVmVjdG9yUHRyIEFsbG9jYXRlZENvc3RzID0gQ29zdEFsbG9jLmdldFZlY3RvcihzdGQ6Om1vdmUoQ29zdHMpKTsKKyAgICAgIGlmIChTb2x2ZXIpCisgICAgICAgIFNvbHZlci0+aGFuZGxlU2V0Tm9kZUNvc3RzKE5JZCwgKkFsbG9jYXRlZENvc3RzKTsKKyAgICAgIGdldE5vZGUoTklkKS5Db3N0cyA9IEFsbG9jYXRlZENvc3RzOworICAgIH0KKworICAgIC8vLyBAYnJpZWYgR2V0IGEgVmVjdG9yUHRyIHRvIGEgbm9kZSdzIGNvc3QgdmVjdG9yLiBSYXJlbHkgdXNlZnVsIC0gdXNlCisgICAgLy8vICAgICAgICBnZXROb2RlQ29zdHMgd2hlcmUgcG9zc2libGUuCisgICAgLy8vIEBwYXJhbSBOSWQgTm9kZSBpZC4KKyAgICAvLy8gQHJldHVybiBWZWN0b3JQdHIgdG8gbm9kZSBjb3N0IHZlY3Rvci4KKyAgICAvLy8KKyAgICAvLy8gICBUaGlzIG1ldGhvZCBpcyBwcmltYXJpbHkgdXNlZnVsIGZvciBkdXBsaWNhdGluZyBjb3N0cyBxdWlja2x5IGJ5CisgICAgLy8vIGJ5cGFzc2luZyB0aGUgY29zdCBhbGxvY2F0b3IuIFNlZSBhZGROb2RlQnlwYXNzaW5nQ29zdEFsbG9jYXRvci4gUHJlZmVyCisgICAgLy8vIGdldE5vZGVDb3N0cyB3aGVuIGRlYWxpbmcgd2l0aCBub2RlIGNvc3QgdmFsdWVzLgorICAgIGNvbnN0IFZlY3RvclB0ciYgZ2V0Tm9kZUNvc3RzUHRyKE5vZGVJZCBOSWQpIGNvbnN0IHsKKyAgICAgIHJldHVybiBnZXROb2RlKE5JZCkuQ29zdHM7CisgICAgfQorCisgICAgLy8vIEBicmllZiBHZXQgYSBub2RlJ3MgY29zdCB2ZWN0b3IuCisgICAgLy8vIEBwYXJhbSBOSWQgTm9kZSBpZC4KKyAgICAvLy8gQHJldHVybiBOb2RlIGNvc3QgdmVjdG9yLgorICAgIGNvbnN0IFZlY3RvciYgZ2V0Tm9kZUNvc3RzKE5vZGVJZCBOSWQpIGNvbnN0IHsKKyAgICAgIHJldHVybiAqZ2V0Tm9kZUNvc3RzUHRyKE5JZCk7CisgICAgfQorCisgICAgTm9kZU1ldGFkYXRhJiBnZXROb2RlTWV0YWRhdGEoTm9kZUlkIE5JZCkgeworICAgICAgcmV0dXJuIGdldE5vZGUoTklkKS5NZXRhZGF0YTsKKyAgICB9CisKKyAgICBjb25zdCBOb2RlTWV0YWRhdGEmIGdldE5vZGVNZXRhZGF0YShOb2RlSWQgTklkKSBjb25zdCB7CisgICAgICByZXR1cm4gZ2V0Tm9kZShOSWQpLk1ldGFkYXRhOworICAgIH0KKworICAgIHR5cGVuYW1lIE5vZGVFbnRyeTo6QWRqRWRnZUxpc3Q6OnNpemVfdHlwZSBnZXROb2RlRGVncmVlKE5vZGVJZCBOSWQpIGNvbnN0IHsKKyAgICAgIHJldHVybiBnZXROb2RlKE5JZCkuZ2V0QWRqRWRnZUlkcygpLnNpemUoKTsKKyAgICB9CisKKyAgICAvLy8gQGJyaWVmIFVwZGF0ZSBhbiBlZGdlJ3MgY29zdCBtYXRyaXguCisgICAgLy8vIEBwYXJhbSBFSWQgRWRnZSBpZC4KKyAgICAvLy8gQHBhcmFtIENvc3RzIE5ldyBjb3N0IG1hdHJpeC4KKyAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgT3RoZXJNYXRyaXhUPgorICAgIHZvaWQgdXBkYXRlRWRnZUNvc3RzKEVkZ2VJZCBFSWQsIE90aGVyTWF0cml4VCBDb3N0cykgeworICAgICAgTWF0cml4UHRyIEFsbG9jYXRlZENvc3RzID0gQ29zdEFsbG9jLmdldE1hdHJpeChzdGQ6Om1vdmUoQ29zdHMpKTsKKyAgICAgIGlmIChTb2x2ZXIpCisgICAgICAgIFNvbHZlci0+aGFuZGxlVXBkYXRlQ29zdHMoRUlkLCAqQWxsb2NhdGVkQ29zdHMpOworICAgICAgZ2V0RWRnZShFSWQpLkNvc3RzID0gQWxsb2NhdGVkQ29zdHM7CisgICAgfQorCisgICAgLy8vIEBicmllZiBHZXQgYSBNYXRyaXhQdHIgdG8gYSBub2RlJ3MgY29zdCBtYXRyaXguIFJhcmVseSB1c2VmdWwgLSB1c2UKKyAgICAvLy8gICAgICAgIGdldEVkZ2VDb3N0cyB3aGVyZSBwb3NzaWJsZS4KKyAgICAvLy8gQHBhcmFtIEVJZCBFZGdlIGlkLgorICAgIC8vLyBAcmV0dXJuIE1hdHJpeFB0ciB0byBlZGdlIGNvc3QgbWF0cml4LgorICAgIC8vLworICAgIC8vLyAgIFRoaXMgbWV0aG9kIGlzIHByaW1hcmlseSB1c2VmdWwgZm9yIGR1cGxpY2F0aW5nIGNvc3RzIHF1aWNrbHkgYnkKKyAgICAvLy8gYnlwYXNzaW5nIHRoZSBjb3N0IGFsbG9jYXRvci4gU2VlIGFkZE5vZGVCeXBhc3NpbmdDb3N0QWxsb2NhdG9yLiBQcmVmZXIKKyAgICAvLy8gZ2V0RWRnZUNvc3RzIHdoZW4gZGVhbGluZyB3aXRoIGVkZ2UgY29zdCB2YWx1ZXMuCisgICAgY29uc3QgTWF0cml4UHRyJiBnZXRFZGdlQ29zdHNQdHIoRWRnZUlkIEVJZCkgY29uc3QgeworICAgICAgcmV0dXJuIGdldEVkZ2UoRUlkKS5Db3N0czsKKyAgICB9CisKKyAgICAvLy8gQGJyaWVmIEdldCBhbiBlZGdlJ3MgY29zdCBtYXRyaXguCisgICAgLy8vIEBwYXJhbSBFSWQgRWRnZSBpZC4KKyAgICAvLy8gQHJldHVybiBFZGdlIGNvc3QgbWF0cml4LgorICAgIGNvbnN0IE1hdHJpeCYgZ2V0RWRnZUNvc3RzKEVkZ2VJZCBFSWQpIGNvbnN0IHsKKyAgICAgIHJldHVybiAqZ2V0RWRnZShFSWQpLkNvc3RzOworICAgIH0KKworICAgIEVkZ2VNZXRhZGF0YSYgZ2V0RWRnZU1ldGFkYXRhKEVkZ2VJZCBFSWQpIHsKKyAgICAgIHJldHVybiBnZXRFZGdlKEVJZCkuTWV0YWRhdGE7CisgICAgfQorCisgICAgY29uc3QgRWRnZU1ldGFkYXRhJiBnZXRFZGdlTWV0YWRhdGEoRWRnZUlkIEVJZCkgY29uc3QgeworICAgICAgcmV0dXJuIGdldEVkZ2UoRUlkKS5NZXRhZGF0YTsKKyAgICB9CisKKyAgICAvLy8gQGJyaWVmIEdldCB0aGUgZmlyc3Qgbm9kZSBjb25uZWN0ZWQgdG8gdGhpcyBlZGdlLgorICAgIC8vLyBAcGFyYW0gRUlkIEVkZ2UgaWQuCisgICAgLy8vIEByZXR1cm4gVGhlIGZpcnN0IG5vZGUgY29ubmVjdGVkIHRvIHRoZSBnaXZlbiBlZGdlLgorICAgIE5vZGVJZCBnZXRFZGdlTm9kZTFJZChFZGdlSWQgRUlkKSBjb25zdCB7CisgICAgICByZXR1cm4gZ2V0RWRnZShFSWQpLmdldE4xSWQoKTsKKyAgICB9CisKKyAgICAvLy8gQGJyaWVmIEdldCB0aGUgc2Vjb25kIG5vZGUgY29ubmVjdGVkIHRvIHRoaXMgZWRnZS4KKyAgICAvLy8gQHBhcmFtIEVJZCBFZGdlIGlkLgorICAgIC8vLyBAcmV0dXJuIFRoZSBzZWNvbmQgbm9kZSBjb25uZWN0ZWQgdG8gdGhlIGdpdmVuIGVkZ2UuCisgICAgTm9kZUlkIGdldEVkZ2VOb2RlMklkKEVkZ2VJZCBFSWQpIGNvbnN0IHsKKyAgICAgIHJldHVybiBnZXRFZGdlKEVJZCkuZ2V0TjJJZCgpOworICAgIH0KKworICAgIC8vLyBAYnJpZWYgR2V0IHRoZSAib3RoZXIiIG5vZGUgY29ubmVjdGVkIHRvIHRoaXMgZWRnZS4KKyAgICAvLy8gQHBhcmFtIEVJZCBFZGdlIGlkLgorICAgIC8vLyBAcGFyYW0gTklkIE5vZGUgaWQgZm9yIHRoZSAiZ2l2ZW4iIG5vZGUuCisgICAgLy8vIEByZXR1cm4gVGhlIGl0ZXJhdG9yIGZvciB0aGUgIm90aGVyIiBub2RlIGNvbm5lY3RlZCB0byB0aGlzIGVkZ2UuCisgICAgTm9kZUlkIGdldEVkZ2VPdGhlck5vZGVJZChFZGdlSWQgRUlkLCBOb2RlSWQgTklkKSB7CisgICAgICBFZGdlRW50cnkgJkUgPSBnZXRFZGdlKEVJZCk7CisgICAgICBpZiAoRS5nZXROMUlkKCkgPT0gTklkKSB7CisgICAgICAgIHJldHVybiBFLmdldE4ySWQoKTsKKyAgICAgIH0gLy8gZWxzZQorICAgICAgcmV0dXJuIEUuZ2V0TjFJZCgpOworICAgIH0KKworICAgIC8vLyBAYnJpZWYgR2V0IHRoZSBlZGdlIGNvbm5lY3RpbmcgdHdvIG5vZGVzLgorICAgIC8vLyBAcGFyYW0gTjFJZCBGaXJzdCBub2RlIGlkLgorICAgIC8vLyBAcGFyYW0gTjJJZCBTZWNvbmQgbm9kZSBpZC4KKyAgICAvLy8gQHJldHVybiBBbiBpZCBmb3IgZWRnZSAoTjFJZCwgTjJJZCkgaWYgc3VjaCBhbiBlZGdlIGV4aXN0cywKKyAgICAvLy8gICAgICAgICBvdGhlcndpc2UgcmV0dXJucyBhbiBpbnZhbGlkIGVkZ2UgaWQuCisgICAgRWRnZUlkIGZpbmRFZGdlKE5vZGVJZCBOMUlkLCBOb2RlSWQgTjJJZCkgeworICAgICAgZm9yIChhdXRvIEFFSWQgOiBhZGpFZGdlSWRzKE4xSWQpKSB7CisgICAgICAgIGlmICgoZ2V0RWRnZU5vZGUxSWQoQUVJZCkgPT0gTjJJZCkgfHwKKyAgICAgICAgICAgIChnZXRFZGdlTm9kZTJJZChBRUlkKSA9PSBOMklkKSkgeworICAgICAgICAgIHJldHVybiBBRUlkOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR1cm4gaW52YWxpZEVkZ2VJZCgpOworICAgIH0KKworICAgIC8vLyBAYnJpZWYgUmVtb3ZlIGEgbm9kZSBmcm9tIHRoZSBncmFwaC4KKyAgICAvLy8gQHBhcmFtIE5JZCBOb2RlIGlkLgorICAgIHZvaWQgcmVtb3ZlTm9kZShOb2RlSWQgTklkKSB7CisgICAgICBpZiAoU29sdmVyKQorICAgICAgICBTb2x2ZXItPmhhbmRsZVJlbW92ZU5vZGUoTklkKTsKKyAgICAgIE5vZGVFbnRyeSAmTiA9IGdldE5vZGUoTklkKTsKKyAgICAgIC8vIFRPRE86IENhbiB0aGlzIGJlIGZvci1lYWNoJ2Q/CisgICAgICBmb3IgKEFkakVkZ2VJdHIgQUVJdHIgPSBOLmFkakVkZ2VzQmVnaW4oKSwKKyAgICAgICAgICAgICBBRUVuZCA9IE4uYWRqRWRnZXNFbmQoKTsKKyAgICAgICAgICAgQUVJdHIgIT0gQUVFbmQ7KSB7CisgICAgICAgIEVkZ2VJZCBFSWQgPSAqQUVJdHI7CisgICAgICAgICsrQUVJdHI7CisgICAgICAgIHJlbW92ZUVkZ2UoRUlkKTsKKyAgICAgIH0KKyAgICAgIEZyZWVOb2RlSWRzLnB1c2hfYmFjayhOSWQpOworICAgIH0KKworICAgIC8vLyBAYnJpZWYgRGlzY29ubmVjdCBhbiBlZGdlIGZyb20gdGhlIGdpdmVuIG5vZGUuCisgICAgLy8vCisgICAgLy8vIFJlbW92ZXMgdGhlIGdpdmVuIGVkZ2UgZnJvbSB0aGUgYWRqYWNlbmN5IGxpc3Qgb2YgdGhlIGdpdmVuIG5vZGUuCisgICAgLy8vIFRoaXMgb3BlcmF0aW9uIGxlYXZlcyB0aGUgZWRnZSBpbiBhbiAnYXN5bW1ldHJpYycgc3RhdGU6IEl0IHdpbGwgbm8KKyAgICAvLy8gbG9uZ2VyIGFwcGVhciBpbiBhbiBpdGVyYXRpb24gb3ZlciB0aGUgZ2l2ZW4gbm9kZSdzIChOSWQncykgZWRnZXMsIGJ1dAorICAgIC8vLyB3aWxsIGFwcGVhciBpbiBhbiBpdGVyYXRpb24gb3ZlciB0aGUgJ290aGVyJywgdW5uYW1lZCBub2RlJ3MgZWRnZXMuCisgICAgLy8vCisgICAgLy8vIFRoaXMgZG9lcyBub3QgY29ycmVzcG9uZCB0byBhbnkgbm9ybWFsIGdyYXBoIG9wZXJhdGlvbiwgYnV0IGV4aXN0cyB0bworICAgIC8vLyBzdXBwb3J0IGVmZmljaWVudCBQQlFQIGdyYXBoLXJlZHVjdGlvbiBiYXNlZCBzb2x2ZXJzLiBJdCBpcyB1c2VkIHRvCisgICAgLy8vICdlZmZlY3RpdmVseScgcmVtb3ZlIHRoZSB1bm5hbWVkIG5vZGUgZnJvbSB0aGUgZ3JhcGggd2hpbGUgdGhlIHNvbHZlcgorICAgIC8vLyBpcyBwZXJmb3JtaW5nIHRoZSByZWR1Y3Rpb24uIFRoZSBzb2x2ZXIgd2lsbCBsYXRlciBjYWxsIHJlY29ubmVjdE5vZGUKKyAgICAvLy8gdG8gcmVzdG9yZSB0aGUgZWRnZSBpbiB0aGUgbmFtZWQgbm9kZSdzIGFkamFjZW5jeSBsaXN0LgorICAgIC8vLworICAgIC8vLyBTaW5jZSB0aGUgZGVncmVlIG9mIGEgbm9kZSBpcyB0aGUgbnVtYmVyIG9mIGNvbm5lY3RlZCBlZGdlcywKKyAgICAvLy8gZGlzY29ubmVjdGluZyBhbiBlZGdlIGZyb20gYSBub2RlICd1JyB3aWxsIGNhdXNlIHRoZSBkZWdyZWUgb2YgJ3UnIHRvCisgICAgLy8vIGRyb3AgYnkgMS4KKyAgICAvLy8KKyAgICAvLy8gQSBkaXNjb25uZWN0ZWQgZWRnZSBXSUxMIHN0aWxsIGFwcGVhciBpbiBhbiBpdGVyYXRpb24gb3ZlciB0aGUgZ3JhcGgKKyAgICAvLy8gZWRnZXMuCisgICAgLy8vCisgICAgLy8vIEEgZGlzY29ubmVjdGVkIGVkZ2Ugc2hvdWxkIG5vdCBiZSByZW1vdmVkIGZyb20gdGhlIGdyYXBoLCBpdCBzaG91bGQgYmUKKyAgICAvLy8gcmVjb25uZWN0ZWQgZmlyc3QuCisgICAgLy8vCisgICAgLy8vIEEgZGlzY29ubmVjdGVkIGVkZ2UgY2FuIGJlIHJlY29ubmVjdGVkIGJ5IGNhbGxpbmcgdGhlIHJlY29ubmVjdEVkZ2UKKyAgICAvLy8gbWV0aG9kLgorICAgIHZvaWQgZGlzY29ubmVjdEVkZ2UoRWRnZUlkIEVJZCwgTm9kZUlkIE5JZCkgeworICAgICAgaWYgKFNvbHZlcikKKyAgICAgICAgU29sdmVyLT5oYW5kbGVEaXNjb25uZWN0RWRnZShFSWQsIE5JZCk7CisKKyAgICAgIEVkZ2VFbnRyeSAmRSA9IGdldEVkZ2UoRUlkKTsKKyAgICAgIEUuZGlzY29ubmVjdEZyb20oKnRoaXMsIE5JZCk7CisgICAgfQorCisgICAgLy8vIEBicmllZiBDb252ZW5pZW5jZSBtZXRob2QgdG8gZGlzY29ubmVjdCBhbGwgbmVpZ2hib3VycyBmcm9tIHRoZSBnaXZlbgorICAgIC8vLyAgICAgICAgbm9kZS4KKyAgICB2b2lkIGRpc2Nvbm5lY3RBbGxOZWlnaGJvcnNGcm9tTm9kZShOb2RlSWQgTklkKSB7CisgICAgICBmb3IgKGF1dG8gQUVJZCA6IGFkakVkZ2VJZHMoTklkKSkKKyAgICAgICAgZGlzY29ubmVjdEVkZ2UoQUVJZCwgZ2V0RWRnZU90aGVyTm9kZUlkKEFFSWQsIE5JZCkpOworICAgIH0KKworICAgIC8vLyBAYnJpZWYgUmUtYXR0YWNoIGFuIGVkZ2UgdG8gaXRzIG5vZGVzLgorICAgIC8vLworICAgIC8vLyBBZGRzIGFuIGVkZ2UgdGhhdCBoYWQgYmVlbiBwcmV2aW91c2x5IGRpc2Nvbm5lY3RlZCBiYWNrIGludG8gdGhlCisgICAgLy8vIGFkamFjZW5jeSBzZXQgb2YgdGhlIG5vZGVzIHRoYXQgdGhlIGVkZ2UgY29ubmVjdHMuCisgICAgdm9pZCByZWNvbm5lY3RFZGdlKEVkZ2VJZCBFSWQsIE5vZGVJZCBOSWQpIHsKKyAgICAgIEVkZ2VFbnRyeSAmRSA9IGdldEVkZ2UoRUlkKTsKKyAgICAgIEUuY29ubmVjdFRvKCp0aGlzLCBFSWQsIE5JZCk7CisgICAgICBpZiAoU29sdmVyKQorICAgICAgICBTb2x2ZXItPmhhbmRsZVJlY29ubmVjdEVkZ2UoRUlkLCBOSWQpOworICAgIH0KKworICAgIC8vLyBAYnJpZWYgUmVtb3ZlIGFuIGVkZ2UgZnJvbSB0aGUgZ3JhcGguCisgICAgLy8vIEBwYXJhbSBFSWQgRWRnZSBpZC4KKyAgICB2b2lkIHJlbW92ZUVkZ2UoRWRnZUlkIEVJZCkgeworICAgICAgaWYgKFNvbHZlcikKKyAgICAgICAgU29sdmVyLT5oYW5kbGVSZW1vdmVFZGdlKEVJZCk7CisgICAgICBFZGdlRW50cnkgJkUgPSBnZXRFZGdlKEVJZCk7CisgICAgICBFLmRpc2Nvbm5lY3QoKTsKKyAgICAgIEZyZWVFZGdlSWRzLnB1c2hfYmFjayhFSWQpOworICAgICAgRWRnZXNbRUlkXS5pbnZhbGlkYXRlKCk7CisgICAgfQorCisgICAgLy8vIEBicmllZiBSZW1vdmUgYWxsIG5vZGVzIGFuZCBlZGdlcyBmcm9tIHRoZSBncmFwaC4KKyAgICB2b2lkIGNsZWFyKCkgeworICAgICAgTm9kZXMuY2xlYXIoKTsKKyAgICAgIEZyZWVOb2RlSWRzLmNsZWFyKCk7CisgICAgICBFZGdlcy5jbGVhcigpOworICAgICAgRnJlZUVkZ2VJZHMuY2xlYXIoKTsKKyAgICB9CisgIH07CisKK30gLy8gZW5kIG5hbWVzcGFjZSBQQlFQCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1BCUVBfR1JBUEhfSFBQCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUEJRUC9NYXRoLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUEJRUC9NYXRoLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmE0MDVlOAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9QQlFQL01hdGguaApAQCAtMCwwICsxLDI5MiBAQAorLy89PT0tIE1hdGguaCAtIFBCUVAgVmVjdG9yIGFuZCBNYXRyaXggY2xhc3NlcyAtLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fUEJRUF9NQVRIX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1BCUVBfTUFUSF9ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9IYXNoaW5nLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU1RMRXh0cmFzLmgiCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8ZnVuY3Rpb25hbD4KKyNpbmNsdWRlIDxtZW1vcnk+CisKK25hbWVzcGFjZSBsbHZtIHsKK25hbWVzcGFjZSBQQlFQIHsKKwordXNpbmcgUEJRUE51bSA9IGZsb2F0OworCisvLy8gXGJyaWVmIFBCUVAgVmVjdG9yIGNsYXNzLgorY2xhc3MgVmVjdG9yIHsKKyAgZnJpZW5kIGhhc2hfY29kZSBoYXNoX3ZhbHVlKGNvbnN0IFZlY3RvciAmKTsKKworcHVibGljOgorICAvLy8gXGJyaWVmIENvbnN0cnVjdCBhIFBCUVAgdmVjdG9yIG9mIHRoZSBnaXZlbiBzaXplLgorICBleHBsaWNpdCBWZWN0b3IodW5zaWduZWQgTGVuZ3RoKQorICAgIDogTGVuZ3RoKExlbmd0aCksIERhdGEobGx2bTo6bWFrZV91bmlxdWU8UEJRUE51bSBbXT4oTGVuZ3RoKSkge30KKworICAvLy8gXGJyaWVmIENvbnN0cnVjdCBhIFBCUVAgdmVjdG9yIHdpdGggaW5pdGlhbGl6ZXIuCisgIFZlY3Rvcih1bnNpZ25lZCBMZW5ndGgsIFBCUVBOdW0gSW5pdFZhbCkKKyAgICA6IExlbmd0aChMZW5ndGgpLCBEYXRhKGxsdm06Om1ha2VfdW5pcXVlPFBCUVBOdW0gW10+KExlbmd0aCkpIHsKKyAgICBzdGQ6OmZpbGwoRGF0YS5nZXQoKSwgRGF0YS5nZXQoKSArIExlbmd0aCwgSW5pdFZhbCk7CisgIH0KKworICAvLy8gXGJyaWVmIENvcHkgY29uc3RydWN0IGEgUEJRUCB2ZWN0b3IuCisgIFZlY3Rvcihjb25zdCBWZWN0b3IgJlYpCisgICAgOiBMZW5ndGgoVi5MZW5ndGgpLCBEYXRhKGxsdm06Om1ha2VfdW5pcXVlPFBCUVBOdW0gW10+KExlbmd0aCkpIHsKKyAgICBzdGQ6OmNvcHkoVi5EYXRhLmdldCgpLCBWLkRhdGEuZ2V0KCkgKyBMZW5ndGgsIERhdGEuZ2V0KCkpOworICB9CisKKyAgLy8vIFxicmllZiBNb3ZlIGNvbnN0cnVjdCBhIFBCUVAgdmVjdG9yLgorICBWZWN0b3IoVmVjdG9yICYmVikKKyAgICA6IExlbmd0aChWLkxlbmd0aCksIERhdGEoc3RkOjptb3ZlKFYuRGF0YSkpIHsKKyAgICBWLkxlbmd0aCA9IDA7CisgIH0KKworICAvLy8gXGJyaWVmIENvbXBhcmlzb24gb3BlcmF0b3IuCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBWZWN0b3IgJlYpIGNvbnN0IHsKKyAgICBhc3NlcnQoTGVuZ3RoICE9IDAgJiYgRGF0YSAmJiAiSW52YWxpZCB2ZWN0b3IiKTsKKyAgICBpZiAoTGVuZ3RoICE9IFYuTGVuZ3RoKQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIHJldHVybiBzdGQ6OmVxdWFsKERhdGEuZ2V0KCksIERhdGEuZ2V0KCkgKyBMZW5ndGgsIFYuRGF0YS5nZXQoKSk7CisgIH0KKworICAvLy8gXGJyaWVmIFJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSB2ZWN0b3IKKyAgdW5zaWduZWQgZ2V0TGVuZ3RoKCkgY29uc3QgeworICAgIGFzc2VydChMZW5ndGggIT0gMCAmJiBEYXRhICYmICJJbnZhbGlkIHZlY3RvciIpOworICAgIHJldHVybiBMZW5ndGg7CisgIH0KKworICAvLy8gXGJyaWVmIEVsZW1lbnQgYWNjZXNzLgorICBQQlFQTnVtJiBvcGVyYXRvcltdKHVuc2lnbmVkIEluZGV4KSB7CisgICAgYXNzZXJ0KExlbmd0aCAhPSAwICYmIERhdGEgJiYgIkludmFsaWQgdmVjdG9yIik7CisgICAgYXNzZXJ0KEluZGV4IDwgTGVuZ3RoICYmICJWZWN0b3IgZWxlbWVudCBhY2Nlc3Mgb3V0IG9mIGJvdW5kcy4iKTsKKyAgICByZXR1cm4gRGF0YVtJbmRleF07CisgIH0KKworICAvLy8gXGJyaWVmIENvbnN0IGVsZW1lbnQgYWNjZXNzLgorICBjb25zdCBQQlFQTnVtJiBvcGVyYXRvcltdKHVuc2lnbmVkIEluZGV4KSBjb25zdCB7CisgICAgYXNzZXJ0KExlbmd0aCAhPSAwICYmIERhdGEgJiYgIkludmFsaWQgdmVjdG9yIik7CisgICAgYXNzZXJ0KEluZGV4IDwgTGVuZ3RoICYmICJWZWN0b3IgZWxlbWVudCBhY2Nlc3Mgb3V0IG9mIGJvdW5kcy4iKTsKKyAgICByZXR1cm4gRGF0YVtJbmRleF07CisgIH0KKworICAvLy8gXGJyaWVmIEFkZCBhbm90aGVyIHZlY3RvciB0byB0aGlzIG9uZS4KKyAgVmVjdG9yJiBvcGVyYXRvcis9KGNvbnN0IFZlY3RvciAmVikgeworICAgIGFzc2VydChMZW5ndGggIT0gMCAmJiBEYXRhICYmICJJbnZhbGlkIHZlY3RvciIpOworICAgIGFzc2VydChMZW5ndGggPT0gVi5MZW5ndGggJiYgIlZlY3RvciBsZW5ndGggbWlzbWF0Y2guIik7CisgICAgc3RkOjp0cmFuc2Zvcm0oRGF0YS5nZXQoKSwgRGF0YS5nZXQoKSArIExlbmd0aCwgVi5EYXRhLmdldCgpLCBEYXRhLmdldCgpLAorICAgICAgICAgICAgICAgICAgIHN0ZDo6cGx1czxQQlFQTnVtPigpKTsKKyAgICByZXR1cm4gKnRoaXM7CisgIH0KKworICAvLy8gXGJyaWVmIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtaW5pbXVtIHZhbHVlIGluIHRoaXMgdmVjdG9yCisgIHVuc2lnbmVkIG1pbkluZGV4KCkgY29uc3QgeworICAgIGFzc2VydChMZW5ndGggIT0gMCAmJiBEYXRhICYmICJJbnZhbGlkIHZlY3RvciIpOworICAgIHJldHVybiBzdGQ6Om1pbl9lbGVtZW50KERhdGEuZ2V0KCksIERhdGEuZ2V0KCkgKyBMZW5ndGgpIC0gRGF0YS5nZXQoKTsKKyAgfQorCitwcml2YXRlOgorICB1bnNpZ25lZCBMZW5ndGg7CisgIHN0ZDo6dW5pcXVlX3B0cjxQQlFQTnVtIFtdPiBEYXRhOworfTsKKworLy8vIFxicmllZiBSZXR1cm4gYSBoYXNoX3ZhbHVlIGZvciB0aGUgZ2l2ZW4gdmVjdG9yLgoraW5saW5lIGhhc2hfY29kZSBoYXNoX3ZhbHVlKGNvbnN0IFZlY3RvciAmVikgeworICB1bnNpZ25lZCAqVkJlZ2luID0gcmVpbnRlcnByZXRfY2FzdDx1bnNpZ25lZCo+KFYuRGF0YS5nZXQoKSk7CisgIHVuc2lnbmVkICpWRW5kID0gcmVpbnRlcnByZXRfY2FzdDx1bnNpZ25lZCo+KFYuRGF0YS5nZXQoKSArIFYuTGVuZ3RoKTsKKyAgcmV0dXJuIGhhc2hfY29tYmluZShWLkxlbmd0aCwgaGFzaF9jb21iaW5lX3JhbmdlKFZCZWdpbiwgVkVuZCkpOworfQorCisvLy8gXGJyaWVmIE91dHB1dCBhIHRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIHZlY3RvciBvbiB0aGUgZ2l2ZW4KKy8vLyAgICAgICAgb3V0cHV0IHN0cmVhbS4KK3RlbXBsYXRlIDx0eXBlbmFtZSBPU3RyZWFtPgorT1N0cmVhbSYgb3BlcmF0b3I8PChPU3RyZWFtICZPUywgY29uc3QgVmVjdG9yICZWKSB7CisgIGFzc2VydCgoVi5nZXRMZW5ndGgoKSAhPSAwKSAmJiAiWmVyby1sZW5ndGggdmVjdG9yIGJhZG5lc3MuIik7CisKKyAgT1MgPDwgIlsgIiA8PCBWWzBdOworICBmb3IgKHVuc2lnbmVkIGkgPSAxOyBpIDwgVi5nZXRMZW5ndGgoKTsgKytpKQorICAgIE9TIDw8ICIsICIgPDwgVltpXTsKKyAgT1MgPDwgIiBdIjsKKworICByZXR1cm4gT1M7Cit9CisKKy8vLyBcYnJpZWYgUEJRUCBNYXRyaXggY2xhc3MKK2NsYXNzIE1hdHJpeCB7Citwcml2YXRlOgorICBmcmllbmQgaGFzaF9jb2RlIGhhc2hfdmFsdWUoY29uc3QgTWF0cml4ICYpOworCitwdWJsaWM6CisgIC8vLyBcYnJpZWYgQ29uc3RydWN0IGEgUEJRUCBNYXRyaXggd2l0aCB0aGUgZ2l2ZW4gZGltZW5zaW9ucy4KKyAgTWF0cml4KHVuc2lnbmVkIFJvd3MsIHVuc2lnbmVkIENvbHMpIDoKKyAgICBSb3dzKFJvd3MpLCBDb2xzKENvbHMpLCBEYXRhKGxsdm06Om1ha2VfdW5pcXVlPFBCUVBOdW0gW10+KFJvd3MgKiBDb2xzKSkgeworICB9CisKKyAgLy8vIFxicmllZiBDb25zdHJ1Y3QgYSBQQlFQIE1hdHJpeCB3aXRoIHRoZSBnaXZlbiBkaW1lbnNpb25zIGFuZCBpbml0aWFsCisgIC8vLyB2YWx1ZS4KKyAgTWF0cml4KHVuc2lnbmVkIFJvd3MsIHVuc2lnbmVkIENvbHMsIFBCUVBOdW0gSW5pdFZhbCkKKyAgICA6IFJvd3MoUm93cyksIENvbHMoQ29scyksCisgICAgICBEYXRhKGxsdm06Om1ha2VfdW5pcXVlPFBCUVBOdW0gW10+KFJvd3MgKiBDb2xzKSkgeworICAgIHN0ZDo6ZmlsbChEYXRhLmdldCgpLCBEYXRhLmdldCgpICsgKFJvd3MgKiBDb2xzKSwgSW5pdFZhbCk7CisgIH0KKworICAvLy8gXGJyaWVmIENvcHkgY29uc3RydWN0IGEgUEJRUCBtYXRyaXguCisgIE1hdHJpeChjb25zdCBNYXRyaXggJk0pCisgICAgOiBSb3dzKE0uUm93cyksIENvbHMoTS5Db2xzKSwKKyAgICAgIERhdGEobGx2bTo6bWFrZV91bmlxdWU8UEJRUE51bSBbXT4oUm93cyAqIENvbHMpKSB7CisgICAgc3RkOjpjb3B5KE0uRGF0YS5nZXQoKSwgTS5EYXRhLmdldCgpICsgKFJvd3MgKiBDb2xzKSwgRGF0YS5nZXQoKSk7CisgIH0KKworICAvLy8gXGJyaWVmIE1vdmUgY29uc3RydWN0IGEgUEJRUCBtYXRyaXguCisgIE1hdHJpeChNYXRyaXggJiZNKQorICAgIDogUm93cyhNLlJvd3MpLCBDb2xzKE0uQ29scyksIERhdGEoc3RkOjptb3ZlKE0uRGF0YSkpIHsKKyAgICBNLlJvd3MgPSBNLkNvbHMgPSAwOworICB9CisKKyAgLy8vIFxicmllZiBDb21wYXJpc29uIG9wZXJhdG9yLgorICBib29sIG9wZXJhdG9yPT0oY29uc3QgTWF0cml4ICZNKSBjb25zdCB7CisgICAgYXNzZXJ0KFJvd3MgIT0gMCAmJiBDb2xzICE9IDAgJiYgRGF0YSAmJiAiSW52YWxpZCBtYXRyaXgiKTsKKyAgICBpZiAoUm93cyAhPSBNLlJvd3MgfHwgQ29scyAhPSBNLkNvbHMpCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgcmV0dXJuIHN0ZDo6ZXF1YWwoRGF0YS5nZXQoKSwgRGF0YS5nZXQoKSArIChSb3dzICogQ29scyksIE0uRGF0YS5nZXQoKSk7CisgIH0KKworICAvLy8gXGJyaWVmIFJldHVybiB0aGUgbnVtYmVyIG9mIHJvd3MgaW4gdGhpcyBtYXRyaXguCisgIHVuc2lnbmVkIGdldFJvd3MoKSBjb25zdCB7CisgICAgYXNzZXJ0KFJvd3MgIT0gMCAmJiBDb2xzICE9IDAgJiYgRGF0YSAmJiAiSW52YWxpZCBtYXRyaXgiKTsKKyAgICByZXR1cm4gUm93czsKKyAgfQorCisgIC8vLyBcYnJpZWYgUmV0dXJuIHRoZSBudW1iZXIgb2YgY29scyBpbiB0aGlzIG1hdHJpeC4KKyAgdW5zaWduZWQgZ2V0Q29scygpIGNvbnN0IHsKKyAgICBhc3NlcnQoUm93cyAhPSAwICYmIENvbHMgIT0gMCAmJiBEYXRhICYmICJJbnZhbGlkIG1hdHJpeCIpOworICAgIHJldHVybiBDb2xzOworICB9CisKKyAgLy8vIFxicmllZiBNYXRyaXggZWxlbWVudCBhY2Nlc3MuCisgIFBCUVBOdW0qIG9wZXJhdG9yW10odW5zaWduZWQgUikgeworICAgIGFzc2VydChSb3dzICE9IDAgJiYgQ29scyAhPSAwICYmIERhdGEgJiYgIkludmFsaWQgbWF0cml4Iik7CisgICAgYXNzZXJ0KFIgPCBSb3dzICYmICJSb3cgb3V0IG9mIGJvdW5kcy4iKTsKKyAgICByZXR1cm4gRGF0YS5nZXQoKSArIChSICogQ29scyk7CisgIH0KKworICAvLy8gXGJyaWVmIE1hdHJpeCBlbGVtZW50IGFjY2Vzcy4KKyAgY29uc3QgUEJRUE51bSogb3BlcmF0b3JbXSh1bnNpZ25lZCBSKSBjb25zdCB7CisgICAgYXNzZXJ0KFJvd3MgIT0gMCAmJiBDb2xzICE9IDAgJiYgRGF0YSAmJiAiSW52YWxpZCBtYXRyaXgiKTsKKyAgICBhc3NlcnQoUiA8IFJvd3MgJiYgIlJvdyBvdXQgb2YgYm91bmRzLiIpOworICAgIHJldHVybiBEYXRhLmdldCgpICsgKFIgKiBDb2xzKTsKKyAgfQorCisgIC8vLyBcYnJpZWYgUmV0dXJucyB0aGUgZ2l2ZW4gcm93IGFzIGEgdmVjdG9yLgorICBWZWN0b3IgZ2V0Um93QXNWZWN0b3IodW5zaWduZWQgUikgY29uc3QgeworICAgIGFzc2VydChSb3dzICE9IDAgJiYgQ29scyAhPSAwICYmIERhdGEgJiYgIkludmFsaWQgbWF0cml4Iik7CisgICAgVmVjdG9yIFYoQ29scyk7CisgICAgZm9yICh1bnNpZ25lZCBDID0gMDsgQyA8IENvbHM7ICsrQykKKyAgICAgIFZbQ10gPSAoKnRoaXMpW1JdW0NdOworICAgIHJldHVybiBWOworICB9CisKKyAgLy8vIFxicmllZiBSZXR1cm5zIHRoZSBnaXZlbiBjb2x1bW4gYXMgYSB2ZWN0b3IuCisgIFZlY3RvciBnZXRDb2xBc1ZlY3Rvcih1bnNpZ25lZCBDKSBjb25zdCB7CisgICAgYXNzZXJ0KFJvd3MgIT0gMCAmJiBDb2xzICE9IDAgJiYgRGF0YSAmJiAiSW52YWxpZCBtYXRyaXgiKTsKKyAgICBWZWN0b3IgVihSb3dzKTsKKyAgICBmb3IgKHVuc2lnbmVkIFIgPSAwOyBSIDwgUm93czsgKytSKQorICAgICAgVltSXSA9ICgqdGhpcylbUl1bQ107CisgICAgcmV0dXJuIFY7CisgIH0KKworICAvLy8gXGJyaWVmIE1hdHJpeCB0cmFuc3Bvc2UuCisgIE1hdHJpeCB0cmFuc3Bvc2UoKSBjb25zdCB7CisgICAgYXNzZXJ0KFJvd3MgIT0gMCAmJiBDb2xzICE9IDAgJiYgRGF0YSAmJiAiSW52YWxpZCBtYXRyaXgiKTsKKyAgICBNYXRyaXggTShDb2xzLCBSb3dzKTsKKyAgICBmb3IgKHVuc2lnbmVkIHIgPSAwOyByIDwgUm93czsgKytyKQorICAgICAgZm9yICh1bnNpZ25lZCBjID0gMDsgYyA8IENvbHM7ICsrYykKKyAgICAgICAgTVtjXVtyXSA9ICgqdGhpcylbcl1bY107CisgICAgcmV0dXJuIE07CisgIH0KKworICAvLy8gXGJyaWVmIEFkZCB0aGUgZ2l2ZW4gbWF0cml4IHRvIHRoaXMgb25lLgorICBNYXRyaXgmIG9wZXJhdG9yKz0oY29uc3QgTWF0cml4ICZNKSB7CisgICAgYXNzZXJ0KFJvd3MgIT0gMCAmJiBDb2xzICE9IDAgJiYgRGF0YSAmJiAiSW52YWxpZCBtYXRyaXgiKTsKKyAgICBhc3NlcnQoUm93cyA9PSBNLlJvd3MgJiYgQ29scyA9PSBNLkNvbHMgJiYKKyAgICAgICAgICAgIk1hdHJpeCBkaW1lbnNpb25zIG1pc21hdGNoLiIpOworICAgIHN0ZDo6dHJhbnNmb3JtKERhdGEuZ2V0KCksIERhdGEuZ2V0KCkgKyAoUm93cyAqIENvbHMpLCBNLkRhdGEuZ2V0KCksCisgICAgICAgICAgICAgICAgICAgRGF0YS5nZXQoKSwgc3RkOjpwbHVzPFBCUVBOdW0+KCkpOworICAgIHJldHVybiAqdGhpczsKKyAgfQorCisgIE1hdHJpeCBvcGVyYXRvcisoY29uc3QgTWF0cml4ICZNKSB7CisgICAgYXNzZXJ0KFJvd3MgIT0gMCAmJiBDb2xzICE9IDAgJiYgRGF0YSAmJiAiSW52YWxpZCBtYXRyaXgiKTsKKyAgICBNYXRyaXggVG1wKCp0aGlzKTsKKyAgICBUbXAgKz0gTTsKKyAgICByZXR1cm4gVG1wOworICB9CisKK3ByaXZhdGU6CisgIHVuc2lnbmVkIFJvd3MsIENvbHM7CisgIHN0ZDo6dW5pcXVlX3B0cjxQQlFQTnVtIFtdPiBEYXRhOworfTsKKworLy8vIFxicmllZiBSZXR1cm4gYSBoYXNoX2NvZGUgZm9yIHRoZSBnaXZlbiBtYXRyaXguCitpbmxpbmUgaGFzaF9jb2RlIGhhc2hfdmFsdWUoY29uc3QgTWF0cml4ICZNKSB7CisgIHVuc2lnbmVkICpNQmVnaW4gPSByZWludGVycHJldF9jYXN0PHVuc2lnbmVkKj4oTS5EYXRhLmdldCgpKTsKKyAgdW5zaWduZWQgKk1FbmQgPQorICAgIHJlaW50ZXJwcmV0X2Nhc3Q8dW5zaWduZWQqPihNLkRhdGEuZ2V0KCkgKyAoTS5Sb3dzICogTS5Db2xzKSk7CisgIHJldHVybiBoYXNoX2NvbWJpbmUoTS5Sb3dzLCBNLkNvbHMsIGhhc2hfY29tYmluZV9yYW5nZShNQmVnaW4sIE1FbmQpKTsKK30KKworLy8vIFxicmllZiBPdXRwdXQgYSB0ZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiBtYXRyaXggb24gdGhlIGdpdmVuCisvLy8gICAgICAgIG91dHB1dCBzdHJlYW0uCit0ZW1wbGF0ZSA8dHlwZW5hbWUgT1N0cmVhbT4KK09TdHJlYW0mIG9wZXJhdG9yPDwoT1N0cmVhbSAmT1MsIGNvbnN0IE1hdHJpeCAmTSkgeworICBhc3NlcnQoKE0uZ2V0Um93cygpICE9IDApICYmICJaZXJvLXJvdyBtYXRyaXggYmFkbmVzcy4iKTsKKyAgZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IE0uZ2V0Um93cygpOyArK2kpCisgICAgT1MgPDwgTS5nZXRSb3dBc1ZlY3RvcihpKSA8PCAiXG4iOworICByZXR1cm4gT1M7Cit9CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBNZXRhZGF0YT4KK2NsYXNzIE1EVmVjdG9yIDogcHVibGljIFZlY3RvciB7CitwdWJsaWM6CisgIE1EVmVjdG9yKGNvbnN0IFZlY3RvciAmdikgOiBWZWN0b3IodiksIG1kKCp0aGlzKSB7fQorICBNRFZlY3RvcihWZWN0b3IgJiZ2KSA6IFZlY3RvcihzdGQ6Om1vdmUodikpLCBtZCgqdGhpcykgeyB9CisKKyAgY29uc3QgTWV0YWRhdGEmIGdldE1ldGFkYXRhKCkgY29uc3QgeyByZXR1cm4gbWQ7IH0KKworcHJpdmF0ZToKKyAgTWV0YWRhdGEgbWQ7Cit9OworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgTWV0YWRhdGE+CitpbmxpbmUgaGFzaF9jb2RlIGhhc2hfdmFsdWUoY29uc3QgTURWZWN0b3I8TWV0YWRhdGE+ICZWKSB7CisgIHJldHVybiBoYXNoX3ZhbHVlKHN0YXRpY19jYXN0PGNvbnN0IFZlY3RvciY+KFYpKTsKK30KKwordGVtcGxhdGUgPHR5cGVuYW1lIE1ldGFkYXRhPgorY2xhc3MgTURNYXRyaXggOiBwdWJsaWMgTWF0cml4IHsKK3B1YmxpYzoKKyAgTURNYXRyaXgoY29uc3QgTWF0cml4ICZtKSA6IE1hdHJpeChtKSwgbWQoKnRoaXMpIHt9CisgIE1ETWF0cml4KE1hdHJpeCAmJm0pIDogTWF0cml4KHN0ZDo6bW92ZShtKSksIG1kKCp0aGlzKSB7IH0KKworICBjb25zdCBNZXRhZGF0YSYgZ2V0TWV0YWRhdGEoKSBjb25zdCB7IHJldHVybiBtZDsgfQorCitwcml2YXRlOgorICBNZXRhZGF0YSBtZDsKK307CisKK3RlbXBsYXRlIDx0eXBlbmFtZSBNZXRhZGF0YT4KK2lubGluZSBoYXNoX2NvZGUgaGFzaF92YWx1ZShjb25zdCBNRE1hdHJpeDxNZXRhZGF0YT4gJk0pIHsKKyAgcmV0dXJuIGhhc2hfdmFsdWUoc3RhdGljX2Nhc3Q8Y29uc3QgTWF0cml4Jj4oTSkpOworfQorCit9IC8vIGVuZCBuYW1lc3BhY2UgUEJRUAorfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9QQlFQX01BVEhfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1BCUVAvUmVkdWN0aW9uUnVsZXMuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9QQlFQL1JlZHVjdGlvblJ1bGVzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGFlYjUxOQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9QQlFQL1JlZHVjdGlvblJ1bGVzLmgKQEAgLTAsMCArMSwyMjMgQEAKKy8vPT09LSBSZWR1Y3Rpb25SdWxlcy5oIC0gUmVkdWN0aW9uIFJ1bGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gUmVkdWN0aW9uIFJ1bGVzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1BCUVBfUkVEVUNUSU9OUlVMRVNfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fUEJRUF9SRURVQ1RJT05SVUxFU19ICisKKyNpbmNsdWRlICJHcmFwaC5oIgorI2luY2x1ZGUgIk1hdGguaCIKKyNpbmNsdWRlICJTb2x1dGlvbi5oIgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8bGltaXRzPgorCituYW1lc3BhY2UgbGx2bSB7CituYW1lc3BhY2UgUEJRUCB7CisKKyAgLy8vIFxicmllZiBSZWR1Y2UgYSBub2RlIG9mIGRlZ3JlZSBvbmUuCisgIC8vLworICAvLy8gUHJvcGFnYXRlIGNvc3RzIGZyb20gdGhlIGdpdmVuIG5vZGUsIHdoaWNoIG11c3QgYmUgb2YgZGVncmVlIG9uZSwgdG8gaXRzCisgIC8vLyBuZWlnaGJvci4gTm90aWZ5IHRoZSBwcm9ibGVtIGRvbWFpbi4KKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEdyYXBoVD4KKyAgdm9pZCBhcHBseVIxKEdyYXBoVCAmRywgdHlwZW5hbWUgR3JhcGhUOjpOb2RlSWQgTklkKSB7CisgICAgdXNpbmcgTm9kZUlkID0gdHlwZW5hbWUgR3JhcGhUOjpOb2RlSWQ7CisgICAgdXNpbmcgRWRnZUlkID0gdHlwZW5hbWUgR3JhcGhUOjpFZGdlSWQ7CisgICAgdXNpbmcgVmVjdG9yID0gdHlwZW5hbWUgR3JhcGhUOjpWZWN0b3I7CisgICAgdXNpbmcgTWF0cml4ID0gdHlwZW5hbWUgR3JhcGhUOjpNYXRyaXg7CisgICAgdXNpbmcgUmF3VmVjdG9yID0gdHlwZW5hbWUgR3JhcGhUOjpSYXdWZWN0b3I7CisKKyAgICBhc3NlcnQoRy5nZXROb2RlRGVncmVlKE5JZCkgPT0gMSAmJgorICAgICAgICAgICAiUjEgYXBwbGllZCB0byBub2RlIHdpdGggZGVncmVlICE9IDEuIik7CisKKyAgICBFZGdlSWQgRUlkID0gKkcuYWRqRWRnZUlkcyhOSWQpLmJlZ2luKCk7CisgICAgTm9kZUlkIE1JZCA9IEcuZ2V0RWRnZU90aGVyTm9kZUlkKEVJZCwgTklkKTsKKworICAgIGNvbnN0IE1hdHJpeCAmRUNvc3RzID0gRy5nZXRFZGdlQ29zdHMoRUlkKTsKKyAgICBjb25zdCBWZWN0b3IgJlhDb3N0cyA9IEcuZ2V0Tm9kZUNvc3RzKE5JZCk7CisgICAgUmF3VmVjdG9yIFlDb3N0cyA9IEcuZ2V0Tm9kZUNvc3RzKE1JZCk7CisKKyAgICAvLyBEdXBsaWNhdGUgYSBsaXR0bGUgdG8gYXZvaWQgdHJhbnNwb3NpbmcgbWF0cmljZXMuCisgICAgaWYgKE5JZCA9PSBHLmdldEVkZ2VOb2RlMUlkKEVJZCkpIHsKKyAgICAgIGZvciAodW5zaWduZWQgaiA9IDA7IGogPCBZQ29zdHMuZ2V0TGVuZ3RoKCk7ICsraikgeworICAgICAgICBQQlFQTnVtIE1pbiA9IEVDb3N0c1swXVtqXSArIFhDb3N0c1swXTsKKyAgICAgICAgZm9yICh1bnNpZ25lZCBpID0gMTsgaSA8IFhDb3N0cy5nZXRMZW5ndGgoKTsgKytpKSB7CisgICAgICAgICAgUEJRUE51bSBDID0gRUNvc3RzW2ldW2pdICsgWENvc3RzW2ldOworICAgICAgICAgIGlmIChDIDwgTWluKQorICAgICAgICAgICAgTWluID0gQzsKKyAgICAgICAgfQorICAgICAgICBZQ29zdHNbal0gKz0gTWluOworICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICBmb3IgKHVuc2lnbmVkIGkgPSAwOyBpIDwgWUNvc3RzLmdldExlbmd0aCgpOyArK2kpIHsKKyAgICAgICAgUEJRUE51bSBNaW4gPSBFQ29zdHNbaV1bMF0gKyBYQ29zdHNbMF07CisgICAgICAgIGZvciAodW5zaWduZWQgaiA9IDE7IGogPCBYQ29zdHMuZ2V0TGVuZ3RoKCk7ICsraikgeworICAgICAgICAgIFBCUVBOdW0gQyA9IEVDb3N0c1tpXVtqXSArIFhDb3N0c1tqXTsKKyAgICAgICAgICBpZiAoQyA8IE1pbikKKyAgICAgICAgICAgIE1pbiA9IEM7CisgICAgICAgIH0KKyAgICAgICAgWUNvc3RzW2ldICs9IE1pbjsKKyAgICAgIH0KKyAgICB9CisgICAgRy5zZXROb2RlQ29zdHMoTUlkLCBZQ29zdHMpOworICAgIEcuZGlzY29ubmVjdEVkZ2UoRUlkLCBNSWQpOworICB9CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIEdyYXBoVD4KKyAgdm9pZCBhcHBseVIyKEdyYXBoVCAmRywgdHlwZW5hbWUgR3JhcGhUOjpOb2RlSWQgTklkKSB7CisgICAgdXNpbmcgTm9kZUlkID0gdHlwZW5hbWUgR3JhcGhUOjpOb2RlSWQ7CisgICAgdXNpbmcgRWRnZUlkID0gdHlwZW5hbWUgR3JhcGhUOjpFZGdlSWQ7CisgICAgdXNpbmcgVmVjdG9yID0gdHlwZW5hbWUgR3JhcGhUOjpWZWN0b3I7CisgICAgdXNpbmcgTWF0cml4ID0gdHlwZW5hbWUgR3JhcGhUOjpNYXRyaXg7CisgICAgdXNpbmcgUmF3TWF0cml4ID0gdHlwZW5hbWUgR3JhcGhUOjpSYXdNYXRyaXg7CisKKyAgICBhc3NlcnQoRy5nZXROb2RlRGVncmVlKE5JZCkgPT0gMiAmJgorICAgICAgICAgICAiUjIgYXBwbGllZCB0byBub2RlIHdpdGggZGVncmVlICE9IDIuIik7CisKKyAgICBjb25zdCBWZWN0b3IgJlhDb3N0cyA9IEcuZ2V0Tm9kZUNvc3RzKE5JZCk7CisKKyAgICB0eXBlbmFtZSBHcmFwaFQ6OkFkakVkZ2VJdHIgQUVJdHIgPSBHLmFkakVkZ2VJZHMoTklkKS5iZWdpbigpOworICAgIEVkZ2VJZCBZWEVJZCA9ICpBRUl0ciwKKyAgICAgICAgICAgWlhFSWQgPSAqKCsrQUVJdHIpOworCisgICAgTm9kZUlkIFlOSWQgPSBHLmdldEVkZ2VPdGhlck5vZGVJZChZWEVJZCwgTklkKSwKKyAgICAgICAgICAgWk5JZCA9IEcuZ2V0RWRnZU90aGVyTm9kZUlkKFpYRUlkLCBOSWQpOworCisgICAgYm9vbCBGbGlwRWRnZTEgPSAoRy5nZXRFZGdlTm9kZTFJZChZWEVJZCkgPT0gTklkKSwKKyAgICAgICAgIEZsaXBFZGdlMiA9IChHLmdldEVkZ2VOb2RlMUlkKFpYRUlkKSA9PSBOSWQpOworCisgICAgY29uc3QgTWF0cml4ICpZWEVDb3N0cyA9IEZsaXBFZGdlMSA/CisgICAgICBuZXcgTWF0cml4KEcuZ2V0RWRnZUNvc3RzKFlYRUlkKS50cmFuc3Bvc2UoKSkgOgorICAgICAgJkcuZ2V0RWRnZUNvc3RzKFlYRUlkKTsKKworICAgIGNvbnN0IE1hdHJpeCAqWlhFQ29zdHMgPSBGbGlwRWRnZTIgPworICAgICAgbmV3IE1hdHJpeChHLmdldEVkZ2VDb3N0cyhaWEVJZCkudHJhbnNwb3NlKCkpIDoKKyAgICAgICZHLmdldEVkZ2VDb3N0cyhaWEVJZCk7CisKKyAgICB1bnNpZ25lZCBYTGVuID0gWENvc3RzLmdldExlbmd0aCgpLAorICAgICAgWUxlbiA9IFlYRUNvc3RzLT5nZXRSb3dzKCksCisgICAgICBaTGVuID0gWlhFQ29zdHMtPmdldFJvd3MoKTsKKworICAgIFJhd01hdHJpeCBEZWx0YShZTGVuLCBaTGVuKTsKKworICAgIGZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBZTGVuOyArK2kpIHsKKyAgICAgIGZvciAodW5zaWduZWQgaiA9IDA7IGogPCBaTGVuOyArK2opIHsKKyAgICAgICAgUEJRUE51bSBNaW4gPSAoKllYRUNvc3RzKVtpXVswXSArICgqWlhFQ29zdHMpW2pdWzBdICsgWENvc3RzWzBdOworICAgICAgICBmb3IgKHVuc2lnbmVkIGsgPSAxOyBrIDwgWExlbjsgKytrKSB7CisgICAgICAgICAgUEJRUE51bSBDID0gKCpZWEVDb3N0cylbaV1ba10gKyAoKlpYRUNvc3RzKVtqXVtrXSArIFhDb3N0c1trXTsKKyAgICAgICAgICBpZiAoQyA8IE1pbikgeworICAgICAgICAgICAgTWluID0gQzsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgRGVsdGFbaV1bal0gPSBNaW47CisgICAgICB9CisgICAgfQorCisgICAgaWYgKEZsaXBFZGdlMSkKKyAgICAgIGRlbGV0ZSBZWEVDb3N0czsKKworICAgIGlmIChGbGlwRWRnZTIpCisgICAgICBkZWxldGUgWlhFQ29zdHM7CisKKyAgICBFZGdlSWQgWVpFSWQgPSBHLmZpbmRFZGdlKFlOSWQsIFpOSWQpOworCisgICAgaWYgKFlaRUlkID09IEcuaW52YWxpZEVkZ2VJZCgpKSB7CisgICAgICBZWkVJZCA9IEcuYWRkRWRnZShZTklkLCBaTklkLCBEZWx0YSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGNvbnN0IE1hdHJpeCAmWVpFQ29zdHMgPSBHLmdldEVkZ2VDb3N0cyhZWkVJZCk7CisgICAgICBpZiAoWU5JZCA9PSBHLmdldEVkZ2VOb2RlMUlkKFlaRUlkKSkgeworICAgICAgICBHLnVwZGF0ZUVkZ2VDb3N0cyhZWkVJZCwgRGVsdGEgKyBZWkVDb3N0cyk7CisgICAgICB9IGVsc2UgeworICAgICAgICBHLnVwZGF0ZUVkZ2VDb3N0cyhZWkVJZCwgRGVsdGEudHJhbnNwb3NlKCkgKyBZWkVDb3N0cyk7CisgICAgICB9CisgICAgfQorCisgICAgRy5kaXNjb25uZWN0RWRnZShZWEVJZCwgWU5JZCk7CisgICAgRy5kaXNjb25uZWN0RWRnZShaWEVJZCwgWk5JZCk7CisKKyAgICAvLyBUT0RPOiBUcnkgdG8gbm9ybWFsaXplIG5ld2x5IGFkZGVkL21vZGlmaWVkIGVkZ2UuCisgIH0KKworI2lmbmRlZiBOREVCVUcKKyAgLy8gRG9lcyB0aGlzIENvc3QgdmVjdG9yIGhhdmUgYW55IHJlZ2lzdGVyIG9wdGlvbnMgPworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVmVjdG9yVD4KKyAgYm9vbCBoYXNSZWdpc3Rlck9wdGlvbnMoY29uc3QgVmVjdG9yVCAmVikgeworICAgIHVuc2lnbmVkIFZMID0gVi5nZXRMZW5ndGgoKTsKKworICAgIC8vIEFuIGVtcHR5IG9yIHNwaWxsIG9ubHkgY29zdCB2ZWN0b3IgZG9lcyBub3QgcHJvdmlkZSBhbnkgcmVnaXN0ZXIgb3B0aW9uLgorICAgIGlmIChWTCA8PSAxKQorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgLy8gSWYgdGhlcmUgYXJlIHJlZ2lzdGVycyBpbiB0aGUgY29zdCB2ZWN0b3IsIGJ1dCBhbGwgb2YgdGhlbSBoYXZlIGluZmluaXRlCisgICAgLy8gY29zdHMsIHRoZW4gLi4uIHRoZXJlIGlzIG5vIGF2YWlsYWJsZSByZWdpc3Rlci4KKyAgICBmb3IgKHVuc2lnbmVkIGkgPSAxOyBpIDwgVkw7ICsraSkKKyAgICAgIGlmIChWW2ldICE9IHN0ZDo6bnVtZXJpY19saW1pdHM8UEJRUDo6UEJRUE51bT46OmluZmluaXR5KCkpCisgICAgICAgIHJldHVybiB0cnVlOworCisgICAgcmV0dXJuIGZhbHNlOworICB9CisjZW5kaWYKKworICAvLyBcYnJpZWYgRmluZCBhIHNvbHV0aW9uIHRvIGEgZnVsbHkgcmVkdWNlZCBncmFwaCBieSBiYWNrcHJvcGFnYXRpb24uCisgIC8vCisgIC8vIEdpdmVuIGEgZ3JhcGggYW5kIGEgcmVkdWN0aW9uIG9yZGVyLCBwb3AgZWFjaCBub2RlIGZyb20gdGhlIHJlZHVjdGlvbgorICAvLyBvcmRlciBhbmQgZ3JlZWRpbHkgY29tcHV0ZSBhIG1pbmltdW0gc29sdXRpb24gYmFzZWQgb24gdGhlIG5vZGUgY29zdHMsIGFuZAorICAvLyB0aGUgZGVwZW5kZW50IGNvc3RzIGR1ZSB0byBwcmV2aW91c2x5IHNvbHZlZCBub2Rlcy4KKyAgLy8KKyAgLy8gTm90ZSAtIFRoaXMgZG9lcyBub3QgcmV0dXJuIHRoZSBncmFwaCB0byBpdHMgb3JpZ2luYWwgKHByZS1yZWR1Y3Rpb24pCisgIC8vICAgICAgICBzdGF0ZTogdGhlIGV4aXN0aW5nIHNvbHZlcnMgZGVzdHJ1Y3RpdmVseSBhbHRlciB0aGUgbm9kZSBhbmQgZWRnZQorICAvLyAgICAgICAgY29zdHMuIEdpdmVuIHRoYXQsIHRoZSBiYWNrcHJvcGFnYXRlIGZ1bmN0aW9uIGRvZXNuJ3QgYXR0ZW1wdCB0bworICAvLyAgICAgICAgcmVwbGFjZSB0aGUgZWRnZXMgZWl0aGVyLCBidXQgbGVhdmVzIHRoZSBncmFwaCBpbiBpdHMgcmVkdWNlZAorICAvLyAgICAgICAgc3RhdGUuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBHcmFwaFQsIHR5cGVuYW1lIFN0YWNrVD4KKyAgU29sdXRpb24gYmFja3Byb3BhZ2F0ZShHcmFwaFQmIEcsIFN0YWNrVCBzdGFjaykgeworICAgIHVzaW5nIE5vZGVJZCA9IEdyYXBoQmFzZTo6Tm9kZUlkOworICAgIHVzaW5nIE1hdHJpeCA9IHR5cGVuYW1lIEdyYXBoVDo6TWF0cml4OworICAgIHVzaW5nIFJhd1ZlY3RvciA9IHR5cGVuYW1lIEdyYXBoVDo6UmF3VmVjdG9yOworCisgICAgU29sdXRpb24gczsKKworICAgIHdoaWxlICghc3RhY2suZW1wdHkoKSkgeworICAgICAgTm9kZUlkIE5JZCA9IHN0YWNrLmJhY2soKTsKKyAgICAgIHN0YWNrLnBvcF9iYWNrKCk7CisKKyAgICAgIFJhd1ZlY3RvciB2ID0gRy5nZXROb2RlQ29zdHMoTklkKTsKKworI2lmbmRlZiBOREVCVUcKKyAgICAgIC8vIEFsdGhvdWdoIGEgY29uc2VydmF0aXZlbHkgYWxsb2NhdGFibGUgbm9kZSBjYW4gYmUgYWxsb2NhdGVkIHRvIGEgcmVnaXN0ZXIsCisgICAgICAvLyBzcGlsbGluZyBpdCBtYXkgcHJvdmlkZSBhIGxvd2VyIGNvc3Qgc29sdXRpb24uIEFzc2VydCBoZXJlIHRoYXQgc3BpbGxpbmcKKyAgICAgIC8vIGlzIGRvbmUgYnkgY2hvaWNlLCBub3QgYmVjYXVzZSB0aGVyZSB3ZXJlIG5vIHJlZ2lzdGVyIGF2YWlsYWJsZS4KKyAgICAgIGlmIChHLmdldE5vZGVNZXRhZGF0YShOSWQpLndhc0NvbnNlcnZhdGl2ZWx5QWxsb2NhdGFibGUoKSkKKyAgICAgICAgYXNzZXJ0KGhhc1JlZ2lzdGVyT3B0aW9ucyh2KSAmJiAiQSBjb25zZXJ2YXRpdmVseSBhbGxvY2F0YWJsZSBub2RlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVzdCBoYXZlIGF2YWlsYWJsZSByZWdpc3RlciBvcHRpb25zIik7CisjZW5kaWYKKworICAgICAgZm9yIChhdXRvIEVJZCA6IEcuYWRqRWRnZUlkcyhOSWQpKSB7CisgICAgICAgIGNvbnN0IE1hdHJpeCYgZWRnZUNvc3RzID0gRy5nZXRFZGdlQ29zdHMoRUlkKTsKKyAgICAgICAgaWYgKE5JZCA9PSBHLmdldEVkZ2VOb2RlMUlkKEVJZCkpIHsKKyAgICAgICAgICBOb2RlSWQgbUlkID0gRy5nZXRFZGdlTm9kZTJJZChFSWQpOworICAgICAgICAgIHYgKz0gZWRnZUNvc3RzLmdldENvbEFzVmVjdG9yKHMuZ2V0U2VsZWN0aW9uKG1JZCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIE5vZGVJZCBtSWQgPSBHLmdldEVkZ2VOb2RlMUlkKEVJZCk7CisgICAgICAgICAgdiArPSBlZGdlQ29zdHMuZ2V0Um93QXNWZWN0b3Iocy5nZXRTZWxlY3Rpb24obUlkKSk7CisgICAgICAgIH0KKyAgICAgIH0KKworICAgICAgcy5zZXRTZWxlY3Rpb24oTklkLCB2Lm1pbkluZGV4KCkpOworICAgIH0KKworICAgIHJldHVybiBzOworICB9CisKK30gLy8gZW5kIG5hbWVzcGFjZSBQQlFQCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1BCUVBfUkVEVUNUSU9OUlVMRVNfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1BCUVAvU29sdXRpb24uaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9QQlFQL1NvbHV0aW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNmEyNDcyNwotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9QQlFQL1NvbHV0aW9uLmgKQEAgLTAsMCArMSw1NiBAQAorLy89PT0tIFNvbHV0aW9uLmggLSBQQlFQIFNvbHV0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBQQlFQIFNvbHV0aW9uIGNsYXNzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1BCUVBfU09MVVRJT05fSAorI2RlZmluZSBMTFZNX0NPREVHRU5fUEJRUF9TT0xVVElPTl9ICisKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vUEJRUC9HcmFwaC5oIgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8bWFwPgorCituYW1lc3BhY2UgbGx2bSB7CituYW1lc3BhY2UgUEJRUCB7CisKKyAgLy8vIFxicmllZiBSZXByZXNlbnRzIGEgc29sdXRpb24gdG8gYSBQQlFQIHByb2JsZW0uCisgIC8vLworICAvLy8gVG8gZ2V0IHRoZSBzZWxlY3Rpb24gZm9yIGVhY2ggbm9kZSBpbiB0aGUgcHJvYmxlbSB1c2UgdGhlIGdldFNlbGVjdGlvbiBtZXRob2QuCisgIGNsYXNzIFNvbHV0aW9uIHsKKyAgcHJpdmF0ZToKKyAgICB1c2luZyBTZWxlY3Rpb25zTWFwID0gc3RkOjptYXA8R3JhcGhCYXNlOjpOb2RlSWQsIHVuc2lnbmVkPjsKKyAgICBTZWxlY3Rpb25zTWFwIHNlbGVjdGlvbnM7CisKKyAgcHVibGljOgorICAgIC8vLyBcYnJpZWYgSW5pdGlhbGlzZSBhbiBlbXB0eSBzb2x1dGlvbi4KKyAgICBTb2x1dGlvbigpID0gZGVmYXVsdDsKKworICAgIC8vLyBcYnJpZWYgU2V0IHRoZSBzZWxlY3Rpb24gZm9yIGEgZ2l2ZW4gbm9kZS4KKyAgICAvLy8gQHBhcmFtIG5vZGVJZCBOb2RlIGlkLgorICAgIC8vLyBAcGFyYW0gc2VsZWN0aW9uIFNlbGVjdGlvbiBmb3Igbm9kZUlkLgorICAgIHZvaWQgc2V0U2VsZWN0aW9uKEdyYXBoQmFzZTo6Tm9kZUlkIG5vZGVJZCwgdW5zaWduZWQgc2VsZWN0aW9uKSB7CisgICAgICBzZWxlY3Rpb25zW25vZGVJZF0gPSBzZWxlY3Rpb247CisgICAgfQorCisgICAgLy8vIFxicmllZiBHZXQgYSBub2RlJ3Mgc2VsZWN0aW9uLgorICAgIC8vLyBAcGFyYW0gbm9kZUlkIE5vZGUgaWQuCisgICAgLy8vIEByZXR1cm4gVGhlIHNlbGVjdGlvbiBmb3Igbm9kZUlkOworICAgIHVuc2lnbmVkIGdldFNlbGVjdGlvbihHcmFwaEJhc2U6Ok5vZGVJZCBub2RlSWQpIGNvbnN0IHsKKyAgICAgIFNlbGVjdGlvbnNNYXA6OmNvbnN0X2l0ZXJhdG9yIHNJdHIgPSBzZWxlY3Rpb25zLmZpbmQobm9kZUlkKTsKKyAgICAgIGFzc2VydChzSXRyICE9IHNlbGVjdGlvbnMuZW5kKCkgJiYgIk5vIHNlbGVjdGlvbiBmb3Igbm9kZS4iKTsKKyAgICAgIHJldHVybiBzSXRyLT5zZWNvbmQ7CisgICAgfQorICB9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgUEJRUAorfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9QQlFQX1NPTFVUSU9OX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9QQlFQUkFDb25zdHJhaW50LmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUEJRUFJBQ29uc3RyYWludC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI2OWI3YTcKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUEJRUFJBQ29uc3RyYWludC5oCkBAIC0wLDAgKzEsNzEgQEAKKy8vPT09LSBSZWdBbGxvY1BCUVAuaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlZmluZXMgdGhlIFBCUVBCdWlsZGVyIGludGVyZmFjZSwgZm9yIGNsYXNzZXMgd2hpY2ggYnVpbGQgUEJRUAorLy8gaW5zdGFuY2VzIHRvIHJlcHJlc2VudCByZWdpc3RlciBhbGxvY2F0aW9uIHByb2JsZW1zLCBhbmQgdGhlIFJlZ0FsbG9jUEJRUAorLy8gaW50ZXJmYWNlLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1BCUVBSQUNPTlNUUkFJTlRfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fUEJRUFJBQ09OU1RSQUlOVF9ICisKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8bWVtb3J5PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGxsdm0geworCituYW1lc3BhY2UgUEJRUCB7CituYW1lc3BhY2UgUmVnQWxsb2MgeworCisvLyBGb3J3YXJkIGRlY2xhcmUgUEJRUCBncmFwaCBjbGFzcy4KK2NsYXNzIFBCUVBSQUdyYXBoOworCit9IC8vIGVuZCBuYW1lc3BhY2UgUmVnQWxsb2MKK30gLy8gZW5kIG5hbWVzcGFjZSBQQlFQCisKK3VzaW5nIFBCUVBSQUdyYXBoID0gUEJRUDo6UmVnQWxsb2M6OlBCUVBSQUdyYXBoOworCisvLy8gQGJyaWVmIEFic3RyYWN0IGJhc2UgZm9yIGNsYXNzZXMgaW1wbGVtZW50aW5nIFBCUVAgcmVnaXN0ZXIgYWxsb2NhdGlvbgorLy8vICAgICAgICBjb25zdHJhaW50cyAoZS5nLiBTcGlsbC1jb3N0cywgaW50ZXJmZXJlbmNlLCBjb2FsZXNjaW5nKS4KK2NsYXNzIFBCUVBSQUNvbnN0cmFpbnQgeworcHVibGljOgorICB2aXJ0dWFsIH5QQlFQUkFDb25zdHJhaW50KCkgPSAwOworICB2aXJ0dWFsIHZvaWQgYXBwbHkoUEJRUFJBR3JhcGggJkcpID0gMDsKKworcHJpdmF0ZToKKyAgdmlydHVhbCB2b2lkIGFuY2hvcigpOworfTsKKworLy8vIEBicmllZiBQQlFQIHJlZ2lzdGVyIGFsbG9jYXRpb24gY29uc3RyYWludCBjb21wb3Nlci4KKy8vLworLy8vICAgQ29uc3RyYWludHMgYWRkZWQgdG8gdGhpcyBsaXN0IHdpbGwgYmUgYXBwbGllZCwgaW4gdGhlIG9yZGVyIHRoYXQgdGhleSBhcmUKKy8vLyBhZGRlZCwgdG8gdGhlIFBCUVAgZ3JhcGguCitjbGFzcyBQQlFQUkFDb25zdHJhaW50TGlzdCA6IHB1YmxpYyBQQlFQUkFDb25zdHJhaW50IHsKK3B1YmxpYzoKKyAgdm9pZCBhcHBseShQQlFQUkFHcmFwaCAmRykgb3ZlcnJpZGUgeworICAgIGZvciAoYXV0byAmQyA6IENvbnN0cmFpbnRzKQorICAgICAgQy0+YXBwbHkoRyk7CisgIH0KKworICB2b2lkIGFkZENvbnN0cmFpbnQoc3RkOjp1bmlxdWVfcHRyPFBCUVBSQUNvbnN0cmFpbnQ+IEMpIHsKKyAgICBpZiAoQykKKyAgICAgIENvbnN0cmFpbnRzLnB1c2hfYmFjayhzdGQ6Om1vdmUoQykpOworICB9CisKK3ByaXZhdGU6CisgIHN0ZDo6dmVjdG9yPHN0ZDo6dW5pcXVlX3B0cjxQQlFQUkFDb25zdHJhaW50Pj4gQ29uc3RyYWludHM7CisKKyAgdm9pZCBhbmNob3IoKSBvdmVycmlkZTsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fUEJRUFJBQ09OU1RSQUlOVF9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUGFyYWxsZWxDRy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1BhcmFsbGVsQ0cuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNGVmMGVjCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1BhcmFsbGVsQ0cuaApAQCAtMCwwICsxLDQ4IEBACisvLz09PS0tIGxsdm0vQ29kZUdlbi9QYXJhbGxlbENHLmggLSBQYXJhbGxlbCBjb2RlIGdlbmVyYXRpb24gLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgaGVhZGVyIGRlY2xhcmVzIGZ1bmN0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIGZvciBwYXJhbGxlbCBjb2RlIGdlbmVyYXRpb24uCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fUEFSQUxMRUxDR19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9QQVJBTExFTENHX0gKKworI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9Db2RlR2VuLmgiCisjaW5jbHVkZSAibGx2bS9UYXJnZXQvVGFyZ2V0TWFjaGluZS5oIgorCisjaW5jbHVkZSA8ZnVuY3Rpb25hbD4KKworbmFtZXNwYWNlIGxsdm0geworCit0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gY2xhc3MgQXJyYXlSZWY7CitjbGFzcyBNb2R1bGU7CitjbGFzcyBUYXJnZXRPcHRpb25zOworY2xhc3MgcmF3X3B3cml0ZV9zdHJlYW07CisKKy8vLyBTcGxpdCBNIGludG8gT1NzLnNpemUoKSBwYXJ0aXRpb25zLCBhbmQgZ2VuZXJhdGUgY29kZSBmb3IgZWFjaC4gVGFrZXMgYQorLy8vIGZhY3RvcnkgZnVuY3Rpb24gZm9yIHRoZSBUYXJnZXRNYWNoaW5lIFRNRmFjdG9yeS4gV3JpdGVzIE9Tcy5zaXplKCkgb3V0cHV0CisvLy8gZmlsZXMgdG8gdGhlIG91dHB1dCBzdHJlYW1zIGluIE9Tcy4gVGhlIHJlc3VsdGluZyBvdXRwdXQgZmlsZXMgaWYgbGlua2VkCisvLy8gdG9nZXRoZXIgYXJlIGludGVuZGVkIHRvIGJlIGVxdWl2YWxlbnQgdG8gdGhlIHNpbmdsZSBvdXRwdXQgZmlsZSB0aGF0IHdvdWxkCisvLy8gaGF2ZSBiZWVuIGNvZGUgZ2VuZXJhdGVkIGZyb20gTS4KKy8vLworLy8vIFdyaXRlcyBiaXRjb2RlIGZvciBpbmRpdmlkdWFsIHBhcnRpdGlvbnMgaW50byBvdXRwdXQgc3RyZWFtcyBpbiBCQ09TcywgaWYKKy8vLyBCQ09TcyBpcyBub3QgZW1wdHkuCisvLy8KKy8vLyBccmV0dXJucyBNIGlmIE9Tcy5zaXplKCkgPT0gMSwgb3RoZXJ3aXNlIHJldHVybnMgc3RkOjp1bmlxdWVfcHRyPE1vZHVsZT4oKS4KK3N0ZDo6dW5pcXVlX3B0cjxNb2R1bGU+CitzcGxpdENvZGVHZW4oc3RkOjp1bmlxdWVfcHRyPE1vZHVsZT4gTSwgQXJyYXlSZWY8cmF3X3B3cml0ZV9zdHJlYW0gKj4gT1NzLAorICAgICAgICAgICAgIEFycmF5UmVmPGxsdm06OnJhd19wd3JpdGVfc3RyZWFtICo+IEJDT1NzLAorICAgICAgICAgICAgIGNvbnN0IHN0ZDo6ZnVuY3Rpb248c3RkOjp1bmlxdWVfcHRyPFRhcmdldE1hY2hpbmU+KCk+ICZUTUZhY3RvcnksCisgICAgICAgICAgICAgVGFyZ2V0TWFjaGluZTo6Q29kZUdlbkZpbGVUeXBlIEZUID0gVGFyZ2V0TWFjaGluZTo6Q0dGVF9PYmplY3RGaWxlLAorICAgICAgICAgICAgIGJvb2wgUHJlc2VydmVMb2NhbHMgPSBmYWxzZSk7CisKK30gLy8gbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUGFzc2VzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUGFzc2VzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjhmZDA0YgotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9QYXNzZXMuaApAQCAtMCwwICsxLDQzOSBAQAorLy89PT0tLSBQYXNzZXMuaCAtIFRhcmdldCBpbmRlcGVuZGVudCBjb2RlIGdlbmVyYXRpb24gcGFzc2VzIC0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgZGVmaW5lcyBpbnRlcmZhY2VzIHRvIGFjY2VzcyB0aGUgdGFyZ2V0IGluZGVwZW5kZW50IGNvZGUgZ2VuZXJhdGlvbgorLy8gcGFzc2VzIHByb3ZpZGVkIGJ5IHRoZSBMTFZNIGJhY2tlbmQuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fUEFTU0VTX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1BBU1NFU19ICisKKyNpbmNsdWRlIDxmdW5jdGlvbmFsPgorI2luY2x1ZGUgPHN0cmluZz4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBGdW5jdGlvblBhc3M7CitjbGFzcyBNYWNoaW5lRnVuY3Rpb247CitjbGFzcyBNYWNoaW5lRnVuY3Rpb25QYXNzOworY2xhc3MgTW9kdWxlUGFzczsKK2NsYXNzIFBhc3M7CitjbGFzcyBUYXJnZXRNYWNoaW5lOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJDbGFzczsKK2NsYXNzIHJhd19vc3RyZWFtOworCit9IC8vIEVuZCBsbHZtIG5hbWVzcGFjZQorCisvLy8gTGlzdCBvZiB0YXJnZXQgaW5kZXBlbmRlbnQgQ29kZUdlbiBwYXNzIElEcy4KK25hbWVzcGFjZSBsbHZtIHsKKyAgRnVuY3Rpb25QYXNzICpjcmVhdGVBdG9taWNFeHBhbmRQYXNzKCk7CisKKyAgLy8vIGNyZWF0ZVVucmVhY2hhYmxlQmxvY2tFbGltaW5hdGlvblBhc3MgLSBUaGUgTExWTSBjb2RlIGdlbmVyYXRvciBkb2VzIG5vdAorICAvLy8gd29yayB3ZWxsIHdpdGggdW5yZWFjaGFibGUgYmFzaWMgYmxvY2tzICh3aGF0IGxpdmUgcmFuZ2VzIG1ha2Ugc2Vuc2UgZm9yIGEKKyAgLy8vIGJsb2NrIHRoYXQgY2Fubm90IGJlIHJlYWNoZWQ/KS4gIEFzIHN1Y2gsIGEgY29kZSBnZW5lcmF0b3Igc2hvdWxkIGVpdGhlcgorICAvLy8gbm90IGluc3RydWN0aW9uIHNlbGVjdCB1bnJlYWNoYWJsZSBibG9ja3MsIG9yIHJ1biB0aGlzIHBhc3MgYXMgaXRzCisgIC8vLyBsYXN0IExMVk0gbW9kaWZ5aW5nIHBhc3MgdG8gY2xlYW4gdXAgYmxvY2tzIHRoYXQgYXJlIG5vdCByZWFjaGFibGUgZnJvbQorICAvLy8gdGhlIGVudHJ5IGJsb2NrLgorICBGdW5jdGlvblBhc3MgKmNyZWF0ZVVucmVhY2hhYmxlQmxvY2tFbGltaW5hdGlvblBhc3MoKTsKKworICAvLy8gTWFjaGluZUZ1bmN0aW9uUHJpbnRlciBwYXNzIC0gVGhpcyBwYXNzIHByaW50cyBvdXQgdGhlIG1hY2hpbmUgZnVuY3Rpb24gdG8KKyAgLy8vIHRoZSBnaXZlbiBzdHJlYW0gYXMgYSBkZWJ1Z2dpbmcgdG9vbC4KKyAgTWFjaGluZUZ1bmN0aW9uUGFzcyAqCisgIGNyZWF0ZU1hY2hpbmVGdW5jdGlvblByaW50ZXJQYXNzKHJhd19vc3RyZWFtICZPUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RkOjpzdHJpbmcgJkJhbm5lciA9IiIpOworCisgIC8vLyBNSVJQcmludGluZyBwYXNzIC0gdGhpcyBwYXNzIHByaW50cyBvdXQgdGhlIExMVk0gSVIgaW50byB0aGUgZ2l2ZW4gc3RyZWFtCisgIC8vLyB1c2luZyB0aGUgTUlSIHNlcmlhbGl6YXRpb24gZm9ybWF0LgorICBNYWNoaW5lRnVuY3Rpb25QYXNzICpjcmVhdGVQcmludE1JUlBhc3MocmF3X29zdHJlYW0gJk9TKTsKKworICAvLy8gVGhpcyBwYXNzIHJlc2V0cyBhIE1hY2hpbmVGdW5jdGlvbiB3aGVuIGl0IGhhcyB0aGUgRmFpbGVkSVNlbCBwcm9wZXJ0eQorICAvLy8gYXMgaWYgaXQgd2FzIGp1c3QgY3JlYXRlZC4KKyAgLy8vIElmIEVtaXRGYWxsYmFja0RpYWcgaXMgdHJ1ZSwgdGhlIHBhc3Mgd2lsbCBlbWl0IGEKKyAgLy8vIERpYWdub3N0aWNJbmZvSVNlbEZhbGxiYWNrIGZvciBldmVyeSBNYWNoaW5lRnVuY3Rpb24gaXQgcmVzZXRzLgorICAvLy8gSWYgQWJvcnRPbkZhaWxlZElTZWwgaXMgdHJ1ZSwgYWJvcnQgY29tcGlsYXRpb24gaW5zdGVhZCBvZiByZXNldHRpbmcuCisgIE1hY2hpbmVGdW5jdGlvblBhc3MgKmNyZWF0ZVJlc2V0TWFjaGluZUZ1bmN0aW9uUGFzcyhib29sIEVtaXRGYWxsYmFja0RpYWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIEFib3J0T25GYWlsZWRJU2VsKTsKKworICAvLy8gY3JlYXRlQ29kZUdlblByZXBhcmVQYXNzIC0gVHJhbnNmb3JtIHRoZSBjb2RlIHRvIGV4cG9zZSBtb3JlIHBhdHRlcm4KKyAgLy8vIG1hdGNoaW5nIGR1cmluZyBpbnN0cnVjdGlvbiBzZWxlY3Rpb24uCisgIEZ1bmN0aW9uUGFzcyAqY3JlYXRlQ29kZUdlblByZXBhcmVQYXNzKCk7CisKKyAgLy8vIGNyZWF0ZVNjYWxhcml6ZU1hc2tlZE1lbUludHJpblBhc3MgLSBSZXBsYWNlIG1hc2tlZCBsb2FkLCBzdG9yZSwgZ2F0aGVyCisgIC8vLyBhbmQgc2NhdHRlciBpbnRyaW5zaWNzIHdpdGggc2NhbGFyIGNvZGUgd2hlbiB0YXJnZXQgZG9lc24ndCBzdXBwb3J0IHRoZW0uCisgIEZ1bmN0aW9uUGFzcyAqY3JlYXRlU2NhbGFyaXplTWFza2VkTWVtSW50cmluUGFzcygpOworCisgIC8vLyBBdG9taWNFeHBhbmRJRCAtLSBMb3dlcnMgYXRvbWljIG9wZXJhdGlvbnMgaW4gdGVybXMgb2YgZWl0aGVyIGNtcHhjaGcKKyAgLy8vIGxvYWQtbGlua2VkL3N0b3JlLWNvbmRpdGlvbmFsIGxvb3BzLgorICBleHRlcm4gY2hhciAmQXRvbWljRXhwYW5kSUQ7CisKKyAgLy8vIE1hY2hpbmVMb29wSW5mbyAtIFRoaXMgcGFzcyBpcyBhIGxvb3AgYW5hbHlzaXMgcGFzcy4KKyAgZXh0ZXJuIGNoYXIgJk1hY2hpbmVMb29wSW5mb0lEOworCisgIC8vLyBNYWNoaW5lRG9taW5hdG9ycyAtIFRoaXMgcGFzcyBpcyBhIG1hY2hpbmUgZG9taW5hdG9ycyBhbmFseXNpcyBwYXNzLgorICBleHRlcm4gY2hhciAmTWFjaGluZURvbWluYXRvcnNJRDsKKworLy8vIE1hY2hpbmVEb21pbmFuYWNlRnJvbnRpZXIgLSBUaGlzIHBhc3MgaXMgYSBtYWNoaW5lIGRvbWluYXRvcnMgYW5hbHlzaXMgcGFzcy4KKyAgZXh0ZXJuIGNoYXIgJk1hY2hpbmVEb21pbmFuY2VGcm9udGllcklEOworCisgIC8vLyBNYWNoaW5lUmVnaW9uSW5mbyAtIFRoaXMgcGFzcyBjb21wdXRlcyBTRVNFIHJlZ2lvbnMgZm9yIG1hY2hpbmUgZnVuY3Rpb25zLgorICBleHRlcm4gY2hhciAmTWFjaGluZVJlZ2lvbkluZm9QYXNzSUQ7CisKKyAgLy8vIEVkZ2VCdW5kbGVzIGFuYWx5c2lzIC0gQnVuZGxlIG1hY2hpbmUgQ0ZHIGVkZ2VzLgorICBleHRlcm4gY2hhciAmRWRnZUJ1bmRsZXNJRDsKKworICAvLy8gTGl2ZVZhcmlhYmxlcyBwYXNzIC0gVGhpcyBwYXNzIGNvbXB1dGVzIHRoZSBzZXQgb2YgYmxvY2tzIGluIHdoaWNoIGVhY2gKKyAgLy8vIHZhcmlhYmxlIGlzIGxpZmUgYW5kIHNldHMgbWFjaGluZSBvcGVyYW5kIGtpbGwgZmxhZ3MuCisgIGV4dGVybiBjaGFyICZMaXZlVmFyaWFibGVzSUQ7CisKKyAgLy8vIFBISUVsaW1pbmF0aW9uIC0gVGhpcyBwYXNzIGVsaW1pbmF0ZXMgbWFjaGluZSBpbnN0cnVjdGlvbiBQSEkgbm9kZXMKKyAgLy8vIGJ5IGluc2VydGluZyBjb3B5IGluc3RydWN0aW9ucy4gIFRoaXMgZGVzdHJveXMgU1NBIGluZm9ybWF0aW9uLCBidXQgaXMgdGhlCisgIC8vLyBkZXNpcmVkIGlucHV0IGZvciBzb21lIHJlZ2lzdGVyIGFsbG9jYXRvcnMuICBUaGlzIHBhc3MgaXMgInJlcXVpcmVkIiBieQorICAvLy8gdGhlc2UgcmVnaXN0ZXIgYWxsb2NhdG9yIGxpa2UgdGhpczogQVUuYWRkUmVxdWlyZWRJRChQSElFbGltaW5hdGlvbklEKTsKKyAgZXh0ZXJuIGNoYXIgJlBISUVsaW1pbmF0aW9uSUQ7CisKKyAgLy8vIExpdmVJbnRlcnZhbHMgLSBUaGlzIGFuYWx5c2lzIGtlZXBzIHRyYWNrIG9mIHRoZSBsaXZlIHJhbmdlcyBvZiB2aXJ0dWFsCisgIC8vLyBhbmQgcGh5c2ljYWwgcmVnaXN0ZXJzLgorICBleHRlcm4gY2hhciAmTGl2ZUludGVydmFsc0lEOworCisgIC8vLyBMaXZlU3RhY2tzIHBhc3MuIEFuIGFuYWx5c2lzIGtlZXBpbmcgdHJhY2sgb2YgdGhlIGxpdmVuZXNzIG9mIHN0YWNrIHNsb3RzLgorICBleHRlcm4gY2hhciAmTGl2ZVN0YWNrc0lEOworCisgIC8vLyBUd29BZGRyZXNzSW5zdHJ1Y3Rpb24gLSBUaGlzIHBhc3MgcmVkdWNlcyB0d28tYWRkcmVzcyBpbnN0cnVjdGlvbnMgdG8KKyAgLy8vIHVzZSB0d28gb3BlcmFuZHMuIFRoaXMgZGVzdHJveXMgU1NBIGluZm9ybWF0aW9uIGJ1dCBpdCBpcyBkZXNpcmVkIGJ5CisgIC8vLyByZWdpc3RlciBhbGxvY2F0b3JzLgorICBleHRlcm4gY2hhciAmVHdvQWRkcmVzc0luc3RydWN0aW9uUGFzc0lEOworCisgIC8vLyBQcm9jZXNzSW1waWNpdERlZnMgcGFzcyAtIFRoaXMgcGFzcyByZW1vdmVzIElNUExJQ0lUX0RFRnMuCisgIGV4dGVybiBjaGFyICZQcm9jZXNzSW1wbGljaXREZWZzSUQ7CisKKyAgLy8vIFJlZ2lzdGVyQ29hbGVzY2VyIC0gVGhpcyBwYXNzIG1lcmdlcyBsaXZlIHJhbmdlcyB0byBlbGltaW5hdGUgY29waWVzLgorICBleHRlcm4gY2hhciAmUmVnaXN0ZXJDb2FsZXNjZXJJRDsKKworICAvLy8gTWFjaGluZVNjaGVkdWxlciAtIFRoaXMgcGFzcyBzY2hlZHVsZXMgbWFjaGluZSBpbnN0cnVjdGlvbnMuCisgIGV4dGVybiBjaGFyICZNYWNoaW5lU2NoZWR1bGVySUQ7CisKKyAgLy8vIFBvc3RNYWNoaW5lU2NoZWR1bGVyIC0gVGhpcyBwYXNzIHNjaGVkdWxlcyBtYWNoaW5lIGluc3RydWN0aW9ucyBwb3N0UkEuCisgIGV4dGVybiBjaGFyICZQb3N0TWFjaGluZVNjaGVkdWxlcklEOworCisgIC8vLyBTcGlsbFBsYWNlbWVudCBhbmFseXNpcy4gU3VnZ2VzdCBvcHRpbWFsIHBsYWNlbWVudCBvZiBzcGlsbCBjb2RlIGJldHdlZW4KKyAgLy8vIGJhc2ljIGJsb2Nrcy4KKyAgZXh0ZXJuIGNoYXIgJlNwaWxsUGxhY2VtZW50SUQ7CisKKyAgLy8vIFNocmlua1dyYXAgcGFzcy4gTG9vayBmb3IgdGhlIGJlc3QgcGxhY2UgdG8gaW5zZXJ0IHNhdmUgYW5kIHJlc3RvcmUKKyAgLy8gaW5zdHJ1Y3Rpb24gYW5kIHVwZGF0ZSB0aGUgTWFjaGluZUZ1bmN0aW9uSW5mbyB3aXRoIHRoYXQgaW5mb3JtYXRpb24uCisgIGV4dGVybiBjaGFyICZTaHJpbmtXcmFwSUQ7CisKKyAgLy8vIExpdmVSYW5nZVNocmluayBwYXNzLiBNb3ZlIGluc3RydWN0aW9uIGNsb3NlIHRvIGl0cyBkZWZpbml0aW9uIHRvIHNocmluaworICAvLy8gdGhlIGRlZmluaXRpb24ncyBsaXZlIHJhbmdlLgorICBleHRlcm4gY2hhciAmTGl2ZVJhbmdlU2hyaW5rSUQ7CisKKyAgLy8vIEdyZWVkeSByZWdpc3RlciBhbGxvY2F0b3IuCisgIGV4dGVybiBjaGFyICZSQUdyZWVkeUlEOworCisgIC8vLyBCYXNpYyByZWdpc3RlciBhbGxvY2F0b3IuCisgIGV4dGVybiBjaGFyICZSQUJhc2ljSUQ7CisKKyAgLy8vIFZpcnRSZWdSZXdyaXRlciBwYXNzLiBSZXdyaXRlIHZpcnR1YWwgcmVnaXN0ZXJzIHRvIHBoeXNpY2FsIHJlZ2lzdGVycyBhcworICAvLy8gYXNzaWduZWQgaW4gVmlydFJlZ01hcC4KKyAgZXh0ZXJuIGNoYXIgJlZpcnRSZWdSZXdyaXRlcklEOworCisgIC8vLyBVbnJlYWNoYWJsZU1hY2hpbmVCbG9ja0VsaW1pbmF0aW9uIC0gVGhpcyBwYXNzIHJlbW92ZXMgdW5yZWFjaGFibGUKKyAgLy8vIG1hY2hpbmUgYmFzaWMgYmxvY2tzLgorICBleHRlcm4gY2hhciAmVW5yZWFjaGFibGVNYWNoaW5lQmxvY2tFbGltSUQ7CisKKyAgLy8vIERlYWRNYWNoaW5lSW5zdHJ1Y3Rpb25FbGltIC0gVGhpcyBwYXNzIHJlbW92ZXMgZGVhZCBtYWNoaW5lIGluc3RydWN0aW9ucy4KKyAgZXh0ZXJuIGNoYXIgJkRlYWRNYWNoaW5lSW5zdHJ1Y3Rpb25FbGltSUQ7CisKKyAgLy8vIFRoaXMgcGFzcyBhZGRzIGRlYWQvdW5kZWYgZmxhZ3MgYWZ0ZXIgYW5hbHl6aW5nIHN1YnJlZ2lzdGVyIGxhbmVzLgorICBleHRlcm4gY2hhciAmRGV0ZWN0RGVhZExhbmVzSUQ7CisKKyAgLy8vIFRoaXMgcGFzcyBwZXJmb3JtIHBvc3QtcmEgbWFjaGluZSBzaW5rIGZvciBDT1BZIGluc3RydWN0aW9ucy4KKyAgZXh0ZXJuIGNoYXIgJlBvc3RSQU1hY2hpbmVTaW5raW5nSUQ7CisKKyAgLy8vIEZhc3RSZWdpc3RlckFsbG9jYXRpb24gUGFzcyAtIFRoaXMgcGFzcyByZWdpc3RlciBhbGxvY2F0ZXMgYXMgZmFzdCBhcworICAvLy8gcG9zc2libGUuIEl0IGlzIGJlc3Qgc3VpdGVkIGZvciBkZWJ1ZyBjb2RlIHdoZXJlIGxpdmUgcmFuZ2VzIGFyZSBzaG9ydC4KKyAgLy8vCisgIEZ1bmN0aW9uUGFzcyAqY3JlYXRlRmFzdFJlZ2lzdGVyQWxsb2NhdG9yKCk7CisKKyAgLy8vIEJhc2ljUmVnaXN0ZXJBbGxvY2F0aW9uIFBhc3MgLSBUaGlzIHBhc3MgaW1wbGVtZW50cyBhIGRlZ2VuZXJhdGUgZ2xvYmFsCisgIC8vLyByZWdpc3RlciBhbGxvY2F0b3IgdXNpbmcgdGhlIGJhc2ljIHJlZ2FsbG9jIGZyYW1ld29yay4KKyAgLy8vCisgIEZ1bmN0aW9uUGFzcyAqY3JlYXRlQmFzaWNSZWdpc3RlckFsbG9jYXRvcigpOworCisgIC8vLyBHcmVlZHkgcmVnaXN0ZXIgYWxsb2NhdGlvbiBwYXNzIC0gVGhpcyBwYXNzIGltcGxlbWVudHMgYSBnbG9iYWwgcmVnaXN0ZXIKKyAgLy8vIGFsbG9jYXRvciBmb3Igb3B0aW1pemVkIGJ1aWxkcy4KKyAgLy8vCisgIEZ1bmN0aW9uUGFzcyAqY3JlYXRlR3JlZWR5UmVnaXN0ZXJBbGxvY2F0b3IoKTsKKworICAvLy8gUEJRUFJlZ2lzdGVyQWxsb2NhdGlvbiBQYXNzIC0gVGhpcyBwYXNzIGltcGxlbWVudHMgdGhlIFBhcnRpdGlvbmVkIEJvb2xlYW4KKyAgLy8vIFF1YWRyYXRpYyBQcm9ncmFhbWluZyAoUEJRUCkgYmFzZWQgcmVnaXN0ZXIgYWxsb2NhdG9yLgorICAvLy8KKyAgRnVuY3Rpb25QYXNzICpjcmVhdGVEZWZhdWx0UEJRUFJlZ2lzdGVyQWxsb2NhdG9yKCk7CisKKyAgLy8vIFByb2xvZ0VwaWxvZ0NvZGVJbnNlcnRlciAtIFRoaXMgcGFzcyBpbnNlcnRzIHByb2xvZyBhbmQgZXBpbG9nIGNvZGUsCisgIC8vLyBhbmQgZWxpbWluYXRlcyBhYnN0cmFjdCBmcmFtZSByZWZlcmVuY2VzLgorICBleHRlcm4gY2hhciAmUHJvbG9nRXBpbG9nQ29kZUluc2VydGVySUQ7CisgIE1hY2hpbmVGdW5jdGlvblBhc3MgKmNyZWF0ZVByb2xvZ0VwaWxvZ0luc2VydGVyUGFzcygpOworCisgIC8vLyBFeHBhbmRQb3N0UkFQc2V1ZG9zIC0gVGhpcyBwYXNzIGV4cGFuZHMgcHNldWRvIGluc3RydWN0aW9ucyBhZnRlcgorICAvLy8gcmVnaXN0ZXIgYWxsb2NhdGlvbi4KKyAgZXh0ZXJuIGNoYXIgJkV4cGFuZFBvc3RSQVBzZXVkb3NJRDsKKworICAvLy8gY3JlYXRlUG9zdFJBSGF6YXJkUmVjb2duaXplciAtIFRoaXMgcGFzcyBydW5zIHRoZSBwb3N0LXJhIGhhemFyZAorICAvLy8gcmVjb2duaXplci4KKyAgZXh0ZXJuIGNoYXIgJlBvc3RSQUhhemFyZFJlY29nbml6ZXJJRDsKKworICAvLy8gY3JlYXRlUG9zdFJBU2NoZWR1bGVyIC0gVGhpcyBwYXNzIHBlcmZvcm1zIHBvc3QgcmVnaXN0ZXIgYWxsb2NhdGlvbgorICAvLy8gc2NoZWR1bGluZy4KKyAgZXh0ZXJuIGNoYXIgJlBvc3RSQVNjaGVkdWxlcklEOworCisgIC8vLyBCcmFuY2hGb2xkaW5nIC0gVGhpcyBwYXNzIHBlcmZvcm1zIG1hY2hpbmUgY29kZSBDRkcgYmFzZWQKKyAgLy8vIG9wdGltaXphdGlvbnMgdG8gZGVsZXRlIGJyYW5jaGVzIHRvIGJyYW5jaGVzLCBlbGltaW5hdGUgYnJhbmNoZXMgdG8KKyAgLy8vIHN1Y2Nlc3NvciBibG9ja3MgKGNyZWF0aW5nIGZhbGwgdGhyb3VnaHMpLCBhbmQgZWxpbWluYXRpbmcgYnJhbmNoZXMgb3ZlcgorICAvLy8gYnJhbmNoZXMuCisgIGV4dGVybiBjaGFyICZCcmFuY2hGb2xkZXJQYXNzSUQ7CisKKyAgLy8vIEJyYW5jaFJlbGF4YXRpb24gLSBUaGlzIHBhc3MgcmVwbGFjZXMgYnJhbmNoZXMgdGhhdCBuZWVkIHRvIGp1bXAgZnVydGhlcgorICAvLy8gdGhhbiBpcyBzdXBwb3J0ZWQgYnkgYSBicmFuY2ggaW5zdHJ1Y3Rpb24uCisgIGV4dGVybiBjaGFyICZCcmFuY2hSZWxheGF0aW9uUGFzc0lEOworCisgIC8vLyBNYWNoaW5lRnVuY3Rpb25QcmludGVyUGFzcyAtIFRoaXMgcGFzcyBwcmludHMgb3V0IE1hY2hpbmVJbnN0cidzLgorICBleHRlcm4gY2hhciAmTWFjaGluZUZ1bmN0aW9uUHJpbnRlclBhc3NJRDsKKworICAvLy8gTUlSUHJpbnRpbmdQYXNzIC0gdGhpcyBwYXNzIHByaW50cyBvdXQgdGhlIExMVk0gSVIgdXNpbmcgdGhlIE1JUgorICAvLy8gc2VyaWFsaXphdGlvbiBmb3JtYXQuCisgIGV4dGVybiBjaGFyICZNSVJQcmludGluZ1Bhc3NJRDsKKworICAvLy8gVGFpbER1cGxpY2F0ZSAtIER1cGxpY2F0ZSBibG9ja3Mgd2l0aCB1bmNvbmRpdGlvbmFsIGJyYW5jaGVzCisgIC8vLyBpbnRvIHRhaWxzIG9mIHRoZWlyIHByZWRlY2Vzc29ycy4KKyAgZXh0ZXJuIGNoYXIgJlRhaWxEdXBsaWNhdGVJRDsKKworICAvLy8gRHVwbGljYXRlIGJsb2NrcyB3aXRoIHVuY29uZGl0aW9uYWwgYnJhbmNoZXMgaW50byB0YWlscyBvZiB0aGVpcgorICAvLy8gcHJlZGVjZXNzb3JzLiBWYXJpYW50IHRoYXQgd29ya3MgYmVmb3JlIHJlZ2lzdGVyIGFsbG9jYXRpb24uCisgIGV4dGVybiBjaGFyICZFYXJseVRhaWxEdXBsaWNhdGVJRDsKKworICAvLy8gTWFjaGluZVRyYWNlTWV0cmljcyAtIFRoaXMgcGFzcyBjb21wdXRlcyBjcml0aWNhbCBwYXRoIGFuZCBDUFUgcmVzb3VyY2UKKyAgLy8vIHVzYWdlIGluIGFuIGVuc2VtYmxlIG9mIHRyYWNlcy4KKyAgZXh0ZXJuIGNoYXIgJk1hY2hpbmVUcmFjZU1ldHJpY3NJRDsKKworICAvLy8gRWFybHlJZkNvbnZlcnRlciAtIFRoaXMgcGFzcyBwZXJmb3JtcyBpZi1jb252ZXJzaW9uIG9uIFNTQSBmb3JtIGJ5CisgIC8vLyBpbnNlcnRpbmcgY21vdiBpbnN0cnVjdGlvbnMuCisgIGV4dGVybiBjaGFyICZFYXJseUlmQ29udmVydGVySUQ7CisKKyAgLy8vIFRoaXMgcGFzcyBwZXJmb3JtcyBpbnN0cnVjdGlvbiBjb21iaW5pbmcgdXNpbmcgdHJhY2UgbWV0cmljcyB0byBlc3RpbWF0ZQorICAvLy8gY3JpdGljYWwtcGF0aCBhbmQgcmVzb3VyY2UgZGVwdGguCisgIGV4dGVybiBjaGFyICZNYWNoaW5lQ29tYmluZXJJRDsKKworICAvLy8gU3RhY2tTbG90Q29sb3JpbmcgLSBUaGlzIHBhc3MgcGVyZm9ybXMgc3RhY2sgY29sb3JpbmcgYW5kIG1lcmdpbmcuCisgIC8vLyBJdCBtZXJnZXMgZGlzam9pbnQgYWxsb2NhcyB0byByZWR1Y2UgdGhlIHN0YWNrIHNpemUuCisgIGV4dGVybiBjaGFyICZTdGFja0NvbG9yaW5nSUQ7CisKKyAgLy8vIElmQ29udmVydGVyIC0gVGhpcyBwYXNzIHBlcmZvcm1zIG1hY2hpbmUgY29kZSBpZiBjb252ZXJzaW9uLgorICBleHRlcm4gY2hhciAmSWZDb252ZXJ0ZXJJRDsKKworICBGdW5jdGlvblBhc3MgKmNyZWF0ZUlmQ29udmVydGVyKAorICAgICAgc3RkOjpmdW5jdGlvbjxib29sKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmKT4gRnRvcik7CisKKyAgLy8vIE1hY2hpbmVCbG9ja1BsYWNlbWVudCAtIFRoaXMgcGFzcyBwbGFjZXMgYmFzaWMgYmxvY2tzIGJhc2VkIG9uIGJyYW5jaAorICAvLy8gcHJvYmFiaWxpdGllcy4KKyAgZXh0ZXJuIGNoYXIgJk1hY2hpbmVCbG9ja1BsYWNlbWVudElEOworCisgIC8vLyBNYWNoaW5lQmxvY2tQbGFjZW1lbnRTdGF0cyAtIFRoaXMgcGFzcyBjb2xsZWN0cyBzdGF0aXN0aWNzIGFib3V0IHRoZQorICAvLy8gYmFzaWMgYmxvY2sgcGxhY2VtZW50IHVzaW5nIGJyYW5jaCBwcm9iYWJpbGl0aWVzIGFuZCBibG9jayBmcmVxdWVuY3kKKyAgLy8vIGluZm9ybWF0aW9uLgorICBleHRlcm4gY2hhciAmTWFjaGluZUJsb2NrUGxhY2VtZW50U3RhdHNJRDsKKworICAvLy8gR0NMb3dlcmluZyBQYXNzIC0gVXNlZCBieSBnYy5yb290IHRvIHBlcmZvcm0gaXRzIGRlZmF1bHQgbG93ZXJpbmcKKyAgLy8vIG9wZXJhdGlvbnMuCisgIEZ1bmN0aW9uUGFzcyAqY3JlYXRlR0NMb3dlcmluZ1Bhc3MoKTsKKworICAvLy8gU2hhZG93U3RhY2tHQ0xvd2VyaW5nIC0gSW1wbGVtZW50cyB0aGUgY3VzdG9tIGxvd2VyaW5nIG1lY2hhbmlzbQorICAvLy8gdXNlZCBieSB0aGUgc2hhZG93IHN0YWNrIEdDLiAgT25seSBydW5zIG9uIGZ1bmN0aW9ucyB3aGljaCBvcHQgaW4gdG8KKyAgLy8vIHRoZSBzaGFkb3cgc3RhY2sgY29sbGVjdG9yLgorICBGdW5jdGlvblBhc3MgKmNyZWF0ZVNoYWRvd1N0YWNrR0NMb3dlcmluZ1Bhc3MoKTsKKworICAvLy8gR0NNYWNoaW5lQ29kZUFuYWx5c2lzIC0gVGFyZ2V0LWluZGVwZW5kZW50IHBhc3MgdG8gbWFyayBzYWZlIHBvaW50cworICAvLy8gaW4gbWFjaGluZSBjb2RlLiBNdXN0IGJlIGFkZGVkIHZlcnkgbGF0ZSBkdXJpbmcgY29kZSBnZW5lcmF0aW9uLCBqdXN0CisgIC8vLyBwcmlvciB0byBvdXRwdXQsIGFuZCBpbXBvcnRhbnRseSBhZnRlciBhbGwgQ0ZHIHRyYW5zZm9ybWF0aW9ucyAoc3VjaCBhcworICAvLy8gYnJhbmNoIGZvbGRpbmcpLgorICBleHRlcm4gY2hhciAmR0NNYWNoaW5lQ29kZUFuYWx5c2lzSUQ7CisKKyAgLy8vIENyZWF0ZXMgYSBwYXNzIHRvIHByaW50IEdDIG1ldGFkYXRhLgorICAvLy8KKyAgRnVuY3Rpb25QYXNzICpjcmVhdGVHQ0luZm9QcmludGVyKHJhd19vc3RyZWFtICZPUyk7CisKKyAgLy8vIE1hY2hpbmVDU0UgLSBUaGlzIHBhc3MgcGVyZm9ybXMgZ2xvYmFsIENTRSBvbiBtYWNoaW5lIGluc3RydWN0aW9ucy4KKyAgZXh0ZXJuIGNoYXIgJk1hY2hpbmVDU0VJRDsKKworICAvLy8gSW1wbGljaXROdWxsQ2hlY2tzIC0gVGhpcyBwYXNzIGZvbGRzIG51bGwgcG9pbnRlciBjaGVja3MgaW50byBuZWFyYnkKKyAgLy8vIG1lbW9yeSBvcGVyYXRpb25zLgorICBleHRlcm4gY2hhciAmSW1wbGljaXROdWxsQ2hlY2tzSUQ7CisKKyAgLy8vIFRoaXMgcGFzcyBwZXJmb3JtcyBsb29wIGludmFyaWFudCBjb2RlIG1vdGlvbiBvbiBtYWNoaW5lIGluc3RydWN0aW9ucy4KKyAgZXh0ZXJuIGNoYXIgJk1hY2hpbmVMSUNNSUQ7CisKKyAgLy8vIFRoaXMgcGFzcyBwZXJmb3JtcyBsb29wIGludmFyaWFudCBjb2RlIG1vdGlvbiBvbiBtYWNoaW5lIGluc3RydWN0aW9ucy4KKyAgLy8vIFRoaXMgdmFyaWFudCB3b3JrcyBiZWZvcmUgcmVnaXN0ZXIgYWxsb2NhdGlvbi4gXHNlZSBNYWNoaW5lTElDTUlELgorICBleHRlcm4gY2hhciAmRWFybHlNYWNoaW5lTElDTUlEOworCisgIC8vLyBNYWNoaW5lU2lua2luZyAtIFRoaXMgcGFzcyBwZXJmb3JtcyBzaW5raW5nIG9uIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zLgorICBleHRlcm4gY2hhciAmTWFjaGluZVNpbmtpbmdJRDsKKworICAvLy8gTWFjaGluZUNvcHlQcm9wYWdhdGlvbiAtIFRoaXMgcGFzcyBwZXJmb3JtcyBjb3B5IHByb3BhZ2F0aW9uIG9uCisgIC8vLyBtYWNoaW5lIGluc3RydWN0aW9ucy4KKyAgZXh0ZXJuIGNoYXIgJk1hY2hpbmVDb3B5UHJvcGFnYXRpb25JRDsKKworICAvLy8gUGVlcGhvbGVPcHRpbWl6ZXIgLSBUaGlzIHBhc3MgcGVyZm9ybXMgcGVlcGhvbGUgb3B0aW1pemF0aW9ucyAtCisgIC8vLyBsaWtlIGV4dGVuc2lvbiBhbmQgY29tcGFyaXNvbiBlbGltaW5hdGlvbnMuCisgIGV4dGVybiBjaGFyICZQZWVwaG9sZU9wdGltaXplcklEOworCisgIC8vLyBPcHRpbWl6ZVBISXMgLSBUaGlzIHBhc3Mgb3B0aW1pemVzIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gUEhJcworICAvLy8gdG8gdGFrZSBhZHZhbnRhZ2Ugb2Ygb3Bwb3J0dW5pdGllcyBjcmVhdGVkIGR1cmluZyBEQUcgbGVnYWxpemF0aW9uLgorICBleHRlcm4gY2hhciAmT3B0aW1pemVQSElzSUQ7CisKKyAgLy8vIFN0YWNrU2xvdENvbG9yaW5nIC0gVGhpcyBwYXNzIHBlcmZvcm1zIHN0YWNrIHNsb3QgY29sb3JpbmcuCisgIGV4dGVybiBjaGFyICZTdGFja1Nsb3RDb2xvcmluZ0lEOworCisgIC8vLyBcYnJpZWYgVGhpcyBwYXNzIGxheXMgb3V0IGZ1bmNsZXRzIGNvbnRpZ3VvdXNseS4KKyAgZXh0ZXJuIGNoYXIgJkZ1bmNsZXRMYXlvdXRJRDsKKworICAvLy8gVGhpcyBwYXNzIGluc2VydHMgdGhlIFhSYXkgaW5zdHJ1bWVudGF0aW9uIHNsZWRzIGlmIHRoZXkgYXJlIHN1cHBvcnRlZCBieQorICAvLy8gdGhlIHRhcmdldCBwbGF0Zm9ybS4KKyAgZXh0ZXJuIGNoYXIgJlhSYXlJbnN0cnVtZW50YXRpb25JRDsKKworICAvLy8gVGhpcyBwYXNzIGluc2VydHMgRkVudHJ5IGNhbGxzCisgIGV4dGVybiBjaGFyICZGRW50cnlJbnNlcnRlcklEOworCisgIC8vLyBcYnJpZWYgVGhpcyBwYXNzIGltcGxlbWVudHMgdGhlICJwYXRjaGFibGUtZnVuY3Rpb24iIGF0dHJpYnV0ZS4KKyAgZXh0ZXJuIGNoYXIgJlBhdGNoYWJsZUZ1bmN0aW9uSUQ7CisKKyAgLy8vIGNyZWF0ZVN0YWNrUHJvdGVjdG9yUGFzcyAtIFRoaXMgcGFzcyBhZGRzIHN0YWNrIHByb3RlY3RvcnMgdG8gZnVuY3Rpb25zLgorICAvLy8KKyAgRnVuY3Rpb25QYXNzICpjcmVhdGVTdGFja1Byb3RlY3RvclBhc3MoKTsKKworICAvLy8gY3JlYXRlTWFjaGluZVZlcmlmaWVyUGFzcyAtIFRoaXMgcGFzcyB2ZXJpZmllcyBjZW5lcmF0ZWQgbWFjaGluZSBjb2RlCisgIC8vLyBpbnN0cnVjdGlvbnMgZm9yIGNvcnJlY3RuZXNzLgorICAvLy8KKyAgRnVuY3Rpb25QYXNzICpjcmVhdGVNYWNoaW5lVmVyaWZpZXJQYXNzKGNvbnN0IHN0ZDo6c3RyaW5nJiBCYW5uZXIpOworCisgIC8vLyBjcmVhdGVEd2FyZkVIUGFzcyAtIFRoaXMgcGFzcyBtdWxjaGVzIGV4Y2VwdGlvbiBoYW5kbGluZyBjb2RlIGludG8gYSBmb3JtCisgIC8vLyBhZGFwdGVkIHRvIGNvZGUgZ2VuZXJhdGlvbi4gIFJlcXVpcmVkIGlmIHVzaW5nIGR3YXJmIGV4Y2VwdGlvbiBoYW5kbGluZy4KKyAgRnVuY3Rpb25QYXNzICpjcmVhdGVEd2FyZkVIUGFzcygpOworCisgIC8vLyBjcmVhdGVXaW5FSFBhc3MgLSBQcmVwYXJlcyBwZXJzb25hbGl0eSBmdW5jdGlvbnMgdXNlZCBieSBNU1ZDIG9uIFdpbmRvd3MsCisgIC8vLyBpbiBhZGRpdGlvbiB0byB0aGUgSXRhbml1bSBMU0RBIGJhc2VkIHBlcnNvbmFsaXRpZXMuCisgIEZ1bmN0aW9uUGFzcyAqY3JlYXRlV2luRUhQYXNzKCk7CisKKyAgLy8vIGNyZWF0ZVNqTGpFSFByZXBhcmVQYXNzIC0gVGhpcyBwYXNzIGFkYXB0cyBleGNlcHRpb24gaGFuZGxpbmcgY29kZSB0byB1c2UKKyAgLy8vIHRoZSBHQ0Mtc3R5bGUgYnVpbHRpbiBzZXRqbXAvbG9uZ2ptcCAoc2psaikgdG8gaGFuZGxpbmcgRUggY29udHJvbCBmbG93LgorICAvLy8KKyAgRnVuY3Rpb25QYXNzICpjcmVhdGVTakxqRUhQcmVwYXJlUGFzcygpOworCisgIC8vLyBMb2NhbFN0YWNrU2xvdEFsbG9jYXRpb24gLSBUaGlzIHBhc3MgYXNzaWducyBsb2NhbCBmcmFtZSBpbmRpY2VzIHRvIHN0YWNrCisgIC8vLyBzbG90cyByZWxhdGl2ZSB0byBvbmUgYW5vdGhlciBhbmQgYWxsb2NhdGVzIGJhc2UgcmVnaXN0ZXJzIHRvIGFjY2VzcyB0aGVtCisgIC8vLyB3aGVuIGl0IGlzIGVzdGltYXRlZCBieSB0aGUgdGFyZ2V0IHRvIGJlIG91dCBvZiByYW5nZSBvZiBub3JtYWwgZnJhbWUKKyAgLy8vIHBvaW50ZXIgb3Igc3RhY2sgcG9pbnRlciBpbmRleCBhZGRyZXNzaW5nLgorICBleHRlcm4gY2hhciAmTG9jYWxTdGFja1Nsb3RBbGxvY2F0aW9uSUQ7CisKKyAgLy8vIEV4cGFuZElTZWxQc2V1ZG9zIC0gVGhpcyBwYXNzIGV4cGFuZHMgcHNldWRvLWluc3RydWN0aW9ucy4KKyAgZXh0ZXJuIGNoYXIgJkV4cGFuZElTZWxQc2V1ZG9zSUQ7CisKKyAgLy8vIFVucGFja01hY2hpbmVCdW5kbGVzIC0gVGhpcyBwYXNzIHVucGFjayBtYWNoaW5lIGluc3RydWN0aW9uIGJ1bmRsZXMuCisgIGV4dGVybiBjaGFyICZVbnBhY2tNYWNoaW5lQnVuZGxlc0lEOworCisgIEZ1bmN0aW9uUGFzcyAqCisgIGNyZWF0ZVVucGFja01hY2hpbmVCdW5kbGVzKHN0ZDo6ZnVuY3Rpb248Ym9vbChjb25zdCBNYWNoaW5lRnVuY3Rpb24gJik+IEZ0b3IpOworCisgIC8vLyBGaW5hbGl6ZU1hY2hpbmVCdW5kbGVzIC0gVGhpcyBwYXNzIGZpbmFsaXplIG1hY2hpbmUgaW5zdHJ1Y3Rpb24KKyAgLy8vIGJ1bmRsZXMgKGNyZWF0ZWQgZWFybGllciwgZS5nLiBkdXJpbmcgcHJlLVJBIHNjaGVkdWxpbmcpLgorICBleHRlcm4gY2hhciAmRmluYWxpemVNYWNoaW5lQnVuZGxlc0lEOworCisgIC8vLyBTdGFja01hcExpdmVuZXNzIC0gVGhpcyBwYXNzIGFuYWx5c2VzIHRoZSByZWdpc3RlciBsaXZlLW91dCBzZXQgb2YKKyAgLy8vIHN0YWNrbWFwL3BhdGNocG9pbnQgaW50cmluc2ljcyBhbmQgYXR0YWNoZXMgdGhlIGNhbGN1bGF0ZWQgaW5mb3JtYXRpb24gdG8KKyAgLy8vIHRoZSBpbnRyaW5zaWMgZm9yIGxhdGVyIGVtaXNzaW9uIHRvIHRoZSBTdGFja01hcC4KKyAgZXh0ZXJuIGNoYXIgJlN0YWNrTWFwTGl2ZW5lc3NJRDsKKworICAvLy8gTGl2ZURlYnVnVmFsdWVzIHBhc3MKKyAgZXh0ZXJuIGNoYXIgJkxpdmVEZWJ1Z1ZhbHVlc0lEOworCisgIC8vLyBjcmVhdGVKdW1wSW5zdHJUYWJsZXMgLSBUaGlzIHBhc3MgY3JlYXRlcyBqdW1wLWluc3RydWN0aW9uIHRhYmxlcy4KKyAgTW9kdWxlUGFzcyAqY3JlYXRlSnVtcEluc3RyVGFibGVzUGFzcygpOworCisgIC8vLyBjcmVhdGVGb3J3YXJkQ29udHJvbEZsb3dJbnRlZ3JpdHlQYXNzIC0gVGhpcyBwYXNzIGFkZHMgY29udHJvbC1mbG93CisgIC8vLyBpbnRlZ3JpdHkuCisgIE1vZHVsZVBhc3MgKmNyZWF0ZUZvcndhcmRDb250cm9sRmxvd0ludGVncml0eVBhc3MoKTsKKworICAvLy8gSW50ZXJsZWF2ZWRBY2Nlc3MgUGFzcyAtIFRoaXMgcGFzcyBpZGVudGlmaWVzIGFuZCBtYXRjaGVzIGludGVybGVhdmVkCisgIC8vLyBtZW1vcnkgYWNjZXNzZXMgdG8gdGFyZ2V0IHNwZWNpZmljIGludHJpbnNpY3MuCisgIC8vLworICBGdW5jdGlvblBhc3MgKmNyZWF0ZUludGVybGVhdmVkQWNjZXNzUGFzcygpOworCisgIC8vLyBMb3dlckVtdVRMUyAtIFRoaXMgcGFzcyBnZW5lcmF0ZXMgX19lbXV0bHNfW3Z0XS54eXogdmFyaWFibGVzIGZvciBhbGwKKyAgLy8vIFRMUyB2YXJpYWJsZXMgZm9yIHRoZSBlbXVsYXRlZCBUTFMgbW9kZWwuCisgIC8vLworICBNb2R1bGVQYXNzICpjcmVhdGVMb3dlckVtdVRMU1Bhc3MoKTsKKworICAvLy8gVGhpcyBwYXNzIGxvd2VycyB0aGUgQGxsdm0ubG9hZC5yZWxhdGl2ZSBpbnRyaW5zaWMgdG8gaW5zdHJ1Y3Rpb25zLgorICAvLy8gVGhpcyBpcyB1bnNhZmUgdG8gZG8gZWFybGllciBiZWNhdXNlIGEgcGFzcyBtYXkgY29tYmluZSB0aGUgY29uc3RhbnQKKyAgLy8vIGluaXRpYWxpemVyIGludG8gdGhlIGxvYWQsIHdoaWNoIG1heSByZXN1bHQgaW4gYW4gb3ZlcmZsb3dpbmcgZXZhbHVhdGlvbi4KKyAgTW9kdWxlUGFzcyAqY3JlYXRlUHJlSVNlbEludHJpbnNpY0xvd2VyaW5nUGFzcygpOworCisgIC8vLyBHbG9iYWxNZXJnZSAtIFRoaXMgcGFzcyBtZXJnZXMgaW50ZXJuYWwgKGJ5IGRlZmF1bHQpIGdsb2JhbHMgaW50byBzdHJ1Y3RzCisgIC8vLyB0byBlbmFibGUgcmV1c2Ugb2YgYSBiYXNlIHBvaW50ZXIgYnkgaW5kZXhlZCBhZGRyZXNzaW5nIG1vZGVzLgorICAvLy8gSXQgY2FuIGFsc28gYmUgY29uZmlndXJlZCB0byBmb2N1cyBvbiBzaXplIG9wdGltaXphdGlvbnMgb25seS4KKyAgLy8vCisgIFBhc3MgKmNyZWF0ZUdsb2JhbE1lcmdlUGFzcyhjb25zdCBUYXJnZXRNYWNoaW5lICpUTSwgdW5zaWduZWQgTWF4aW1hbE9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgT25seU9wdGltaXplRm9yU2l6ZSA9IGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBNZXJnZUV4dGVybmFsQnlEZWZhdWx0ID0gZmFsc2UpOworCisgIC8vLyBUaGlzIHBhc3Mgc3BsaXRzIHRoZSBzdGFjayBpbnRvIGEgc2FmZSBzdGFjayBhbmQgYW4gdW5zYWZlIHN0YWNrIHRvCisgIC8vLyBwcm90ZWN0IGFnYWluc3Qgc3RhY2stYmFzZWQgb3ZlcmZsb3cgdnVsbmVyYWJpbGl0aWVzLgorICBGdW5jdGlvblBhc3MgKmNyZWF0ZVNhZmVTdGFja1Bhc3MoKTsKKworICAvLy8gVGhpcyBwYXNzIGRldGVjdHMgc3VicmVnaXN0ZXIgbGFuZXMgaW4gYSB2aXJ0dWFsIHJlZ2lzdGVyIHRoYXQgYXJlIHVzZWQKKyAgLy8vIGluZGVwZW5kZW50bHkgb2Ygb3RoZXIgbGFuZXMgYW5kIHNwbGl0cyB0aGVtIGludG8gc2VwYXJhdGUgdmlydHVhbAorICAvLy8gcmVnaXN0ZXJzLgorICBleHRlcm4gY2hhciAmUmVuYW1lSW5kZXBlbmRlbnRTdWJyZWdzSUQ7CisKKyAgLy8vIFRoaXMgcGFzcyBpcyBleGVjdXRlZCBQT1NULVJBIHRvIGNvbGxlY3Qgd2hpY2ggcGh5c2ljYWwgcmVnaXN0ZXJzIGFyZQorICAvLy8gcHJlc2VydmVkIGJ5IGdpdmVuIG1hY2hpbmUgZnVuY3Rpb24uCisgIEZ1bmN0aW9uUGFzcyAqY3JlYXRlUmVnVXNhZ2VJbmZvQ29sbGVjdG9yKCk7CisKKyAgLy8vIFJldHVybiBhIE1hY2hpbmVGdW5jdGlvbiBwYXNzIHRoYXQgaWRlbnRpZmllcyBjYWxsIHNpdGVzCisgIC8vLyBhbmQgcHJvcGFnYXRlcyByZWdpc3RlciB1c2FnZSBpbmZvcm1hdGlvbiBvZiBjYWxsZWUgdG8gY2FsbGVyCisgIC8vLyBpZiBhdmFpbGFibGUgd2l0aCBQeXNpY2FsUmVnaXN0ZXJVc2FnZUluZm8gcGFzcy4KKyAgRnVuY3Rpb25QYXNzICpjcmVhdGVSZWdVc2FnZUluZm9Qcm9wUGFzcygpOworCisgIC8vLyBUaGlzIHBhc3MgcGVyZm9ybXMgc29mdHdhcmUgcGlwZWxpbmluZyBvbiBtYWNoaW5lIGluc3RydWN0aW9ucy4KKyAgZXh0ZXJuIGNoYXIgJk1hY2hpbmVQaXBlbGluZXJJRDsKKworICAvLy8gVGhpcyBwYXNzIGZyZWVzIHRoZSBtZW1vcnkgb2NjdXBpZWQgYnkgdGhlIE1hY2hpbmVGdW5jdGlvbi4KKyAgRnVuY3Rpb25QYXNzICpjcmVhdGVGcmVlTWFjaGluZUZ1bmN0aW9uUGFzcygpOworCisgIC8vLyBUaGlzIHBhc3MgcGVyZm9ybXMgb3V0bGluaW5nIG9uIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zIGRpcmVjdGx5IGJlZm9yZQorICAvLy8gcHJpbnRpbmcgYXNzZW1ibHkuCisgIE1vZHVsZVBhc3MgKmNyZWF0ZU1hY2hpbmVPdXRsaW5lclBhc3MoYm9vbCBPdXRsaW5lRnJvbUxpbmtPbmNlT0RScyA9IGZhbHNlKTsKKworICAvLy8gVGhpcyBwYXNzIGV4cGFuZHMgdGhlIGV4cGVyaW1lbnRhbCByZWR1Y3Rpb24gaW50cmluc2ljcyBpbnRvIHNlcXVlbmNlcyBvZgorICAvLy8gc2h1ZmZsZXMuCisgIEZ1bmN0aW9uUGFzcyAqY3JlYXRlRXhwYW5kUmVkdWN0aW9uc1Bhc3MoKTsKKworICAvLyBUaGlzIHBhc3MgZXhwYW5kcyBtZW1jbXAoKSB0byBsb2FkL3N0b3Jlcy4KKyAgRnVuY3Rpb25QYXNzICpjcmVhdGVFeHBhbmRNZW1DbXBQYXNzKCk7CisKKyAgLy8vIENyZWF0ZXMgQnJlYWsgRmFsc2UgRGVwZW5kZW5jaWVzIHBhc3MuIFxzZWUgQnJlYWtGYWxzZURlcHMuY3BwCisgIEZ1bmN0aW9uUGFzcyAqY3JlYXRlQnJlYWtGYWxzZURlcHMoKTsKKworICAvLyBUaGlzIHBhc3MgZXhwYW5kcyBpbmRpcmVjdGJyIGluc3RydWN0aW9ucy4KKyAgRnVuY3Rpb25QYXNzICpjcmVhdGVJbmRpcmVjdEJyRXhwYW5kUGFzcygpOworCit9IC8vIEVuZCBsbHZtIG5hbWVzcGFjZQorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9QcmVJU2VsSW50cmluc2ljTG93ZXJpbmcuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9QcmVJU2VsSW50cmluc2ljTG93ZXJpbmcuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YTAwN2ViCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1ByZUlTZWxJbnRyaW5zaWNMb3dlcmluZy5oCkBAIC0wLDAgKzEsMjkgQEAKKy8vPT09LSBQcmVJU2VsSW50cmluc2ljTG93ZXJpbmcuaCAtIFByZS1JU2VsIGludHJpbnNpYyBsb3dlcmluZyBwYXNzIC0tLS0tLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBwYXNzIGltcGxlbWVudHMgSVIgbG93ZXJpbmcgZm9yIHRoZSBsbHZtLmxvYWQucmVsYXRpdmUgaW50cmluc2ljLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisjaWZuZGVmIExMVk1fQ09ERUdFTl9QUkVJU0VMSU5UUklOU0lDTE9XRVJJTkdfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fUFJFSVNFTElOVFJJTlNJQ0xPV0VSSU5HX0gKKworI2luY2x1ZGUgImxsdm0vSVIvUGFzc01hbmFnZXIuaCIKKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNb2R1bGU7CisKK3N0cnVjdCBQcmVJU2VsSW50cmluc2ljTG93ZXJpbmdQYXNzCisgICAgOiBQYXNzSW5mb01peGluPFByZUlTZWxJbnRyaW5zaWNMb3dlcmluZ1Bhc3M+IHsKKyAgUHJlc2VydmVkQW5hbHlzZXMgcnVuKE1vZHVsZSAmTSwgTW9kdWxlQW5hbHlzaXNNYW5hZ2VyICZBTSk7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1BSRUlTRUxJTlRSSU5TSUNMT1dFUklOR19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUHNldWRvU291cmNlVmFsdWUuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9Qc2V1ZG9Tb3VyY2VWYWx1ZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJkZjBiYjcKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUHNldWRvU291cmNlVmFsdWUuaApAQCAtMCwwICsxLDE5OCBAQAorLy89PT0tLSBsbHZtL0NvZGVHZW4vUHNldWRvU291cmNlVmFsdWUuaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgY29udGFpbnMgdGhlIGRlY2xhcmF0aW9uIG9mIHRoZSBQc2V1ZG9Tb3VyY2VWYWx1ZSBjbGFzcy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9QU0VVRE9TT1VSQ0VWQUxVRV9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9QU0VVRE9TT1VSQ0VWQUxVRV9ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9TdHJpbmdNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0dsb2JhbFZhbHVlLmgiCisjaW5jbHVkZSAibGx2bS9JUi9WYWx1ZS5oIgorI2luY2x1ZGUgImxsdm0vSVIvVmFsdWVNYXAuaCIKKyNpbmNsdWRlIDxtYXA+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgTWFjaGluZUZyYW1lSW5mbzsKK2NsYXNzIE1hY2hpbmVNZW1PcGVyYW5kOworY2xhc3MgcmF3X29zdHJlYW07CitjbGFzcyBUYXJnZXRJbnN0ckluZm87CisKK3Jhd19vc3RyZWFtICZvcGVyYXRvcjw8KHJhd19vc3RyZWFtICZPUywgY29uc3QgTWFjaGluZU1lbU9wZXJhbmQgJk1NTyk7CitjbGFzcyBQc2V1ZG9Tb3VyY2VWYWx1ZTsKK3Jhd19vc3RyZWFtICZvcGVyYXRvcjw8KHJhd19vc3RyZWFtICZPUywgY29uc3QgUHNldWRvU291cmNlVmFsdWUqIFBTVik7CisKKy8vLyBTcGVjaWFsIHZhbHVlIHN1cHBsaWVkIGZvciBtYWNoaW5lIGxldmVsIGFsaWFzIGFuYWx5c2lzLiBJdCBpbmRpY2F0ZXMgdGhhdAorLy8vIGEgbWVtb3J5IGFjY2VzcyByZWZlcmVuY2VzIHRoZSBmdW5jdGlvbnMgc3RhY2sgZnJhbWUgKGUuZy4sIGEgc3BpbGwgc2xvdCksCisvLy8gYmVsb3cgdGhlIHN0YWNrIGZyYW1lIChlLmcuLCBhcmd1bWVudCBzcGFjZSksIG9yIGNvbnN0YW50IHBvb2wuCitjbGFzcyBQc2V1ZG9Tb3VyY2VWYWx1ZSB7CitwdWJsaWM6CisgIGVudW0gUFNWS2luZCB7CisgICAgU3RhY2ssCisgICAgR09ULAorICAgIEp1bXBUYWJsZSwKKyAgICBDb25zdGFudFBvb2wsCisgICAgRml4ZWRTdGFjaywKKyAgICBHbG9iYWxWYWx1ZUNhbGxFbnRyeSwKKyAgICBFeHRlcm5hbFN5bWJvbENhbGxFbnRyeSwKKyAgICBUYXJnZXRDdXN0b20KKyAgfTsKKworcHJpdmF0ZToKKyAgUFNWS2luZCBLaW5kOworICB1bnNpZ25lZCBBZGRyZXNzU3BhY2U7CisgIGZyaWVuZCByYXdfb3N0cmVhbSAmbGx2bTo6b3BlcmF0b3I8PChyYXdfb3N0cmVhbSAmT1MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQc2V1ZG9Tb3VyY2VWYWx1ZSogUFNWKTsKKworICBmcmllbmQgY2xhc3MgTWFjaGluZU1lbU9wZXJhbmQ7IC8vIEZvciBwcmludEN1c3RvbSgpLgorCisgIC8vLyBJbXBsZW1lbnQgcHJpbnRpbmcgZm9yIFBzZXVkb1NvdXJjZVZhbHVlLiBUaGlzIGlzIGNhbGxlZCBmcm9tCisgIC8vLyBWYWx1ZTo6cHJpbnQgb3IgVmFsdWUncyBvcGVyYXRvcjw8LgorICB2aXJ0dWFsIHZvaWQgcHJpbnRDdXN0b20ocmF3X29zdHJlYW0gJk8pIGNvbnN0OworCitwdWJsaWM6CisgIGV4cGxpY2l0IFBzZXVkb1NvdXJjZVZhbHVlKFBTVktpbmQgS2luZCwgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICZUSUkpOworCisgIHZpcnR1YWwgflBzZXVkb1NvdXJjZVZhbHVlKCk7CisKKyAgUFNWS2luZCBraW5kKCkgY29uc3QgeyByZXR1cm4gS2luZDsgfQorCisgIGJvb2wgaXNTdGFjaygpIGNvbnN0IHsgcmV0dXJuIEtpbmQgPT0gU3RhY2s7IH0KKyAgYm9vbCBpc0dPVCgpIGNvbnN0IHsgcmV0dXJuIEtpbmQgPT0gR09UOyB9CisgIGJvb2wgaXNDb25zdGFudFBvb2woKSBjb25zdCB7IHJldHVybiBLaW5kID09IENvbnN0YW50UG9vbDsgfQorICBib29sIGlzSnVtcFRhYmxlKCkgY29uc3QgeyByZXR1cm4gS2luZCA9PSBKdW1wVGFibGU7IH0KKworICB1bnNpZ25lZCBnZXRBZGRyZXNzU3BhY2UoKSBjb25zdCB7IHJldHVybiBBZGRyZXNzU3BhY2U7IH0KKworICB1bnNpZ25lZCBnZXRUYXJnZXRDdXN0b20oKSBjb25zdCB7CisgICAgcmV0dXJuIChLaW5kID49IFRhcmdldEN1c3RvbSkgPyAoKEtpbmQrMSkgLSBUYXJnZXRDdXN0b20pIDogMDsKKyAgfQorCisgIC8vLyBUZXN0IHdoZXRoZXIgdGhlIG1lbW9yeSBwb2ludGVkIHRvIGJ5IHRoaXMgUHNldWRvU291cmNlVmFsdWUgaGFzIGEKKyAgLy8vIGNvbnN0YW50IHZhbHVlLgorICB2aXJ0dWFsIGJvb2wgaXNDb25zdGFudChjb25zdCBNYWNoaW5lRnJhbWVJbmZvICopIGNvbnN0OworCisgIC8vLyBUZXN0IHdoZXRoZXIgdGhlIG1lbW9yeSBwb2ludGVkIHRvIGJ5IHRoaXMgUHNldWRvU291cmNlVmFsdWUgbWF5IGFsc28gYmUKKyAgLy8vIHBvaW50ZWQgdG8gYnkgYW4gTExWTSBJUiBWYWx1ZS4KKyAgdmlydHVhbCBib29sIGlzQWxpYXNlZChjb25zdCBNYWNoaW5lRnJhbWVJbmZvICopIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgbWVtb3J5IHBvaW50ZWQgdG8gYnkgdGhpcyBQc2V1ZG9Tb3VyY2VWYWx1ZSBjYW4gZXZlcgorICAvLy8gYWxpYXMgYW4gTExWTSBJUiBWYWx1ZS4KKyAgdmlydHVhbCBib29sIG1heUFsaWFzKGNvbnN0IE1hY2hpbmVGcmFtZUluZm8gKikgY29uc3Q7Cit9OworCisvLy8gQSBzcGVjaWFsaXplZCBQc2V1ZG9Tb3VyY2VWYWx1ZSBmb3IgaG9sZGluZyBGaXhlZFN0YWNrIHZhbHVlcywgd2hpY2ggbXVzdAorLy8vIGluY2x1ZGUgYSBmcmFtZSBpbmRleC4KK2NsYXNzIEZpeGVkU3RhY2tQc2V1ZG9Tb3VyY2VWYWx1ZSA6IHB1YmxpYyBQc2V1ZG9Tb3VyY2VWYWx1ZSB7CisgIGNvbnN0IGludCBGSTsKKworcHVibGljOgorICBleHBsaWNpdCBGaXhlZFN0YWNrUHNldWRvU291cmNlVmFsdWUoaW50IEZJLCBjb25zdCBUYXJnZXRJbnN0ckluZm8gJlRJSSkKKyAgICAgIDogUHNldWRvU291cmNlVmFsdWUoRml4ZWRTdGFjaywgVElJKSwgRkkoRkkpIHt9CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBQc2V1ZG9Tb3VyY2VWYWx1ZSAqVikgeworICAgIHJldHVybiBWLT5raW5kKCkgPT0gRml4ZWRTdGFjazsKKyAgfQorCisgIGJvb2wgaXNDb25zdGFudChjb25zdCBNYWNoaW5lRnJhbWVJbmZvICpNRkkpIGNvbnN0IG92ZXJyaWRlOworCisgIGJvb2wgaXNBbGlhc2VkKGNvbnN0IE1hY2hpbmVGcmFtZUluZm8gKk1GSSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgYm9vbCBtYXlBbGlhcyhjb25zdCBNYWNoaW5lRnJhbWVJbmZvICopIGNvbnN0IG92ZXJyaWRlOworCisgIHZvaWQgcHJpbnRDdXN0b20ocmF3X29zdHJlYW0gJk9TKSBjb25zdCBvdmVycmlkZTsKKworICBpbnQgZ2V0RnJhbWVJbmRleCgpIGNvbnN0IHsgcmV0dXJuIEZJOyB9Cit9OworCitjbGFzcyBDYWxsRW50cnlQc2V1ZG9Tb3VyY2VWYWx1ZSA6IHB1YmxpYyBQc2V1ZG9Tb3VyY2VWYWx1ZSB7Citwcm90ZWN0ZWQ6CisgIENhbGxFbnRyeVBzZXVkb1NvdXJjZVZhbHVlKFBTVktpbmQgS2luZCwgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICZUSUkpOworCitwdWJsaWM6CisgIGJvb2wgaXNDb25zdGFudChjb25zdCBNYWNoaW5lRnJhbWVJbmZvICopIGNvbnN0IG92ZXJyaWRlOworICBib29sIGlzQWxpYXNlZChjb25zdCBNYWNoaW5lRnJhbWVJbmZvICopIGNvbnN0IG92ZXJyaWRlOworICBib29sIG1heUFsaWFzKGNvbnN0IE1hY2hpbmVGcmFtZUluZm8gKikgY29uc3Qgb3ZlcnJpZGU7Cit9OworCisvLy8gQSBzcGVjaWFsaXplZCBwc2V1ZG8gc29ydWNlIHZhbHVlIGZvciBob2xkaW5nIEdsb2JhbFZhbHVlIHZhbHVlcy4KK2NsYXNzIEdsb2JhbFZhbHVlUHNldWRvU291cmNlVmFsdWUgOiBwdWJsaWMgQ2FsbEVudHJ5UHNldWRvU291cmNlVmFsdWUgeworICBjb25zdCBHbG9iYWxWYWx1ZSAqR1Y7CisKK3B1YmxpYzoKKyAgR2xvYmFsVmFsdWVQc2V1ZG9Tb3VyY2VWYWx1ZShjb25zdCBHbG9iYWxWYWx1ZSAqR1YsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0SW5zdHJJbmZvICZUSUkpOworCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgUHNldWRvU291cmNlVmFsdWUgKlYpIHsKKyAgICByZXR1cm4gVi0+a2luZCgpID09IEdsb2JhbFZhbHVlQ2FsbEVudHJ5OworICB9CisKKyAgY29uc3QgR2xvYmFsVmFsdWUgKmdldFZhbHVlKCkgY29uc3QgeyByZXR1cm4gR1Y7IH0KK307CisKKy8vLyBBIHNwZWNpYWxpemVkIHBzZXVkbyBzb3VyY2UgdmFsdWUgZm9yIGhvbGRpbmcgZXh0ZXJuYWwgc3ltYm9sIHZhbHVlcy4KK2NsYXNzIEV4dGVybmFsU3ltYm9sUHNldWRvU291cmNlVmFsdWUgOiBwdWJsaWMgQ2FsbEVudHJ5UHNldWRvU291cmNlVmFsdWUgeworICBjb25zdCBjaGFyICpFUzsKKworcHVibGljOgorICBFeHRlcm5hbFN5bWJvbFBzZXVkb1NvdXJjZVZhbHVlKGNvbnN0IGNoYXIgKkVTLCBjb25zdCBUYXJnZXRJbnN0ckluZm8gJlRJSSk7CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBQc2V1ZG9Tb3VyY2VWYWx1ZSAqVikgeworICAgIHJldHVybiBWLT5raW5kKCkgPT0gRXh0ZXJuYWxTeW1ib2xDYWxsRW50cnk7CisgIH0KKworICBjb25zdCBjaGFyICpnZXRTeW1ib2woKSBjb25zdCB7IHJldHVybiBFUzsgfQorfTsKKworLy8vIE1hbmFnZXMgY3JlYXRpb24gb2YgcHNldWRvIHNvdXJjZSB2YWx1ZXMuCitjbGFzcyBQc2V1ZG9Tb3VyY2VWYWx1ZU1hbmFnZXIgeworICBjb25zdCBUYXJnZXRJbnN0ckluZm8gJlRJSTsKKyAgY29uc3QgUHNldWRvU291cmNlVmFsdWUgU3RhY2tQU1YsIEdPVFBTViwgSnVtcFRhYmxlUFNWLCBDb25zdGFudFBvb2xQU1Y7CisgIHN0ZDo6bWFwPGludCwgc3RkOjp1bmlxdWVfcHRyPEZpeGVkU3RhY2tQc2V1ZG9Tb3VyY2VWYWx1ZT4+IEZTVmFsdWVzOworICBTdHJpbmdNYXA8c3RkOjp1bmlxdWVfcHRyPGNvbnN0IEV4dGVybmFsU3ltYm9sUHNldWRvU291cmNlVmFsdWU+PgorICAgICAgRXh0ZXJuYWxDYWxsRW50cmllczsKKyAgVmFsdWVNYXA8Y29uc3QgR2xvYmFsVmFsdWUgKiwKKyAgICAgICAgICAgc3RkOjp1bmlxdWVfcHRyPGNvbnN0IEdsb2JhbFZhbHVlUHNldWRvU291cmNlVmFsdWU+PgorICAgICAgR2xvYmFsQ2FsbEVudHJpZXM7CisKK3B1YmxpYzoKKyAgUHNldWRvU291cmNlVmFsdWVNYW5hZ2VyKGNvbnN0IFRhcmdldEluc3RySW5mbyAmVElJKTsKKworICAvLy8gUmV0dXJuIGEgcHNldWRvIHNvdXJjZSB2YWx1ZSByZWZlcmVuY2luZyB0aGUgYXJlYSBiZWxvdyB0aGUgc3RhY2sgZnJhbWUgb2YKKyAgLy8vIGEgZnVuY3Rpb24sIGUuZy4sIHRoZSBhcmd1bWVudCBzcGFjZS4KKyAgY29uc3QgUHNldWRvU291cmNlVmFsdWUgKmdldFN0YWNrKCk7CisKKyAgLy8vIFJldHVybiBhIHBzZXVkbyBzb3VyY2UgdmFsdWUgcmVmZXJlbmNpbmcgdGhlIGdsb2JhbCBvZmZzZXQgdGFibGUKKyAgLy8vIChvciBzb21ldGhpbmcgdGhlIGxpa2UpLgorICBjb25zdCBQc2V1ZG9Tb3VyY2VWYWx1ZSAqZ2V0R09UKCk7CisKKyAgLy8vIFJldHVybiBhIHBzZXVkbyBzb3VyY2UgdmFsdWUgcmVmZXJlbmNpbmcgdGhlIGNvbnN0YW50IHBvb2wuIFNpbmNlIGNvbnN0YW50CisgIC8vLyBwb29scyBhcmUgY29uc3RhbnQsIHRoaXMgZG9lc24ndCBuZWVkIHRvIGlkZW50aWZ5IGEgc3BlY2lmaWMgY29uc3RhbnQKKyAgLy8vIHBvb2wgZW50cnkuCisgIGNvbnN0IFBzZXVkb1NvdXJjZVZhbHVlICpnZXRDb25zdGFudFBvb2woKTsKKworICAvLy8gUmV0dXJuIGEgcHNldWRvIHNvdXJjZSB2YWx1ZSByZWZlcmVuY2luZyBhIGp1bXAgdGFibGUuIFNpbmNlIGp1bXAgdGFibGVzCisgIC8vLyBhcmUgY29uc3RhbnQsIHRoaXMgZG9lc24ndCBuZWVkIHRvIGlkZW50aWZ5IGEgc3BlY2lmaWMganVtcCB0YWJsZS4KKyAgY29uc3QgUHNldWRvU291cmNlVmFsdWUgKmdldEp1bXBUYWJsZSgpOworCisgIC8vLyBSZXR1cm4gYSBwc2V1ZG8gc291cmNlIHZhbHVlIHJlZmVyZW5jaW5nIGEgZml4ZWQgc3RhY2sgZnJhbWUgZW50cnksCisgIC8vLyBlLmcuLCBhIHNwaWxsIHNsb3QuCisgIGNvbnN0IFBzZXVkb1NvdXJjZVZhbHVlICpnZXRGaXhlZFN0YWNrKGludCBGSSk7CisKKyAgY29uc3QgUHNldWRvU291cmNlVmFsdWUgKmdldEdsb2JhbFZhbHVlQ2FsbEVudHJ5KGNvbnN0IEdsb2JhbFZhbHVlICpHVik7CisKKyAgY29uc3QgUHNldWRvU291cmNlVmFsdWUgKmdldEV4dGVybmFsU3ltYm9sQ2FsbEVudHJ5KGNvbnN0IGNoYXIgKkVTKTsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1JlYWNoaW5nRGVmQW5hbHlzaXMuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SZWFjaGluZ0RlZkFuYWx5c2lzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjIxYjc0NQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SZWFjaGluZ0RlZkFuYWx5c2lzLmgKQEAgLTAsMCArMSwxMTggQEAKKy8vPT0tLS0gbGx2bS9Db2RlR2VuL1JlYWNoaW5nRGVmQW5hbHlzaXMuaCAtIFJlYWNoaW5nIERlZiBBbmFseXNpcyAtKi0gQysrIC0qLS0tPT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vLyBcZmlsZSBSZWFjaGluZyBEZWZzIEFuYWx5c2lzIHBhc3MuCisvLy8KKy8vLyBUaGlzIHBhc3MgdHJhY2tzIGZvciBlYWNoIGluc3RydWN0aW9uIHdoYXQgaXMgdGhlIJNjbG9zZXN0lCByZWFjaGluZyBkZWYgb2YKKy8vLyBhIGdpdmVuIHJlZ2lzdGVyLiBJdCBpcyB1c2VkIGJ5IEJyZWFrRmFsc2VEZXBzIChmb3IgY2xlYXJhbmNlIGNhbGN1bGF0aW9uKQorLy8vIGFuZCBFeGVjdXRpb25Eb21haW5GaXggKGZvciBhcmJpdHJhdGluZyBjb25mbGljdGluZyBkb21haW5zKS4KKy8vLworLy8vIE5vdGUgdGhhdCB0aGlzIGlzIGRpZmZlcmVudCBmcm9tIHRoZSB1c3VhbCBkZWZpbml0aW9uIG5vdGlvbiBvZiBsaXZlbmVzcy4KKy8vLyBUaGUgQ1BVIGRvZXNuJ3QgY2FyZSB3aGV0aGVyIG9yIG5vdCB3ZSBjb25zaWRlciBhIHJlZ2lzdGVyIGtpbGxlZC4KKy8vLworLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1JFQUNISU5HREVGU0FOQUxZU0lTX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1JFQUNISU5HREVGU0FOQUxZU0lTX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTG9vcFRyYXZlcnNhbC5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lRnVuY3Rpb25QYXNzLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgTWFjaGluZUJhc2ljQmxvY2s7CitjbGFzcyBNYWNoaW5lSW5zdHI7CisKKy8vLyBUaGlzIGNsYXNzIHByb3ZpZGVzIHRoZSByZWFjaGluZyBkZWYgYW5hbHlzaXMuCitjbGFzcyBSZWFjaGluZ0RlZkFuYWx5c2lzIDogcHVibGljIE1hY2hpbmVGdW5jdGlvblBhc3MgeworcHJpdmF0ZToKKyAgTWFjaGluZUZ1bmN0aW9uICpNRjsKKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkk7CisgIHVuc2lnbmVkIE51bVJlZ1VuaXRzOworICAvLy8gSW5zdHJ1Y3Rpb24gdGhhdCBkZWZpbmVkIGVhY2ggcmVnaXN0ZXIsIHJlbGF0aXZlIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlCisgIC8vLyBjdXJyZW50IGJhc2ljIGJsb2NrLiAgV2hlbiBhIExpdmVSZWdzRGVmSW5mbyBpcyB1c2VkIHRvIHJlcHJlc2VudCBhCisgIC8vLyBsaXZlLW91dCByZWdpc3RlciwgdGhpcyB2YWx1ZSBpcyByZWxhdGl2ZSB0byB0aGUgZW5kIG9mIHRoZSBiYXNpYyBibG9jaywKKyAgLy8vIHNvIGl0IHdpbGwgYmUgYSBuZWdhdGl2ZSBudW1iZXIuCisgIHVzaW5nIExpdmVSZWdzRGVmSW5mbyA9IHN0ZDo6dmVjdG9yPGludD47CisgIExpdmVSZWdzRGVmSW5mbyBMaXZlUmVnczsKKworICAvLy8gS2VlcHMgY2xlYXJhbmNlIGluZm9ybWF0aW9uIGZvciBhbGwgcmVnaXN0ZXJzLiBOb3RlIHRoYXQgdGhpcworICAvLy8gaXMgZGlmZmVyZW50IGZyb20gdGhlIHVzdWFsIGRlZmluaXRpb24gbm90aW9uIG9mIGxpdmVuZXNzLiBUaGUgQ1BVCisgIC8vLyBkb2Vzbid0IGNhcmUgd2hldGhlciBvciBub3Qgd2UgY29uc2lkZXIgYSByZWdpc3RlciBraWxsZWQuCisgIHVzaW5nIE91dFJlZ3NJbmZvTWFwID0gU21hbGxWZWN0b3I8TGl2ZVJlZ3NEZWZJbmZvLCA0PjsKKyAgT3V0UmVnc0luZm9NYXAgTUJCT3V0UmVnc0luZm9zOworCisgIC8vLyBDdXJyZW50IGluc3RydWN0aW9uIG51bWJlci4KKyAgLy8vIFRoZSBmaXJzdCBpbnN0cnVjdGlvbiBpbiBlYWNoIGJhc2ljIGJsb2NrIGlzIDAuCisgIGludCBDdXJJbnN0cjsKKworICAvLy8gTWFwcyBpbnN0cnVjdGlvbnMgdG8gdGhlaXIgaW5zdHJ1Y3Rpb24gSWRzLCByZWxhdGl2ZSB0byB0aGUgYmVnaW5pbmcgb2YKKyAgLy8vIHRoZWlyIGJhc2ljIGJsb2Nrcy4KKyAgRGVuc2VNYXA8TWFjaGluZUluc3RyICosIGludD4gSW5zdElkczsKKworICAvLy8gQWxsIHJlYWNoaW5nIGRlZnMgb2YgYSBnaXZlbiBSZWdVbml0IGZvciBhIGdpdmVuIE1CQi4KKyAgdXNpbmcgTUJCUmVnVW5pdERlZnMgPSBTbWFsbFZlY3RvcjxpbnQsIDE+OworICAvLy8gQWxsIHJlYWNoaW5nIGRlZnMgb2YgYWxsIHJlZyB1bml0cyBmb3IgYSBnaXZlbiBNQkIKKyAgdXNpbmcgTUJCRGVmc0luZm8gPSBzdGQ6OnZlY3RvcjxNQkJSZWdVbml0RGVmcz47CisgIC8vLyBBbGwgcmVhY2hpbmcgZGVmcyBvZiBhbGwgcmVnIHVuaXRzIGZvciBhIGFsbCBNQkJzCisgIHVzaW5nIE1CQlJlYWNoaW5nRGVmc0luZm8gPSBTbWFsbFZlY3RvcjxNQkJEZWZzSW5mbywgND47CisgIE1CQlJlYWNoaW5nRGVmc0luZm8gTUJCUmVhY2hpbmdEZWZzOworCisgIC8vLyBEZWZhdWx0IHZhbHVlcyBhcmUgJ25vdGhpbmcgaGFwcGVuZWQgYSBsb25nIHRpbWUgYWdvJy4KKyAgY29uc3QgaW50IFJlYWNoaW5nRGVmRGVmYXVsdFZhbCA9IC0oMSA8PCAyMCk7CisKK3B1YmxpYzoKKyAgc3RhdGljIGNoYXIgSUQ7IC8vIFBhc3MgaWRlbnRpZmljYXRpb24sIHJlcGxhY2VtZW50IGZvciB0eXBlaWQKKworICBSZWFjaGluZ0RlZkFuYWx5c2lzKCkgOiBNYWNoaW5lRnVuY3Rpb25QYXNzKElEKSB7CisgICAgaW5pdGlhbGl6ZVJlYWNoaW5nRGVmQW5hbHlzaXNQYXNzKCpQYXNzUmVnaXN0cnk6OmdldFBhc3NSZWdpc3RyeSgpKTsKKyAgfQorICB2b2lkIHJlbGVhc2VNZW1vcnkoKSBvdmVycmlkZTsKKworICB2b2lkIGdldEFuYWx5c2lzVXNhZ2UoQW5hbHlzaXNVc2FnZSAmQVUpIGNvbnN0IG92ZXJyaWRlIHsKKyAgICBBVS5zZXRQcmVzZXJ2ZXNBbGwoKTsKKyAgICBNYWNoaW5lRnVuY3Rpb25QYXNzOjpnZXRBbmFseXNpc1VzYWdlKEFVKTsKKyAgfQorCisgIGJvb2wgcnVuT25NYWNoaW5lRnVuY3Rpb24oTWFjaGluZUZ1bmN0aW9uICZNRikgb3ZlcnJpZGU7CisKKyAgTWFjaGluZUZ1bmN0aW9uUHJvcGVydGllcyBnZXRSZXF1aXJlZFByb3BlcnRpZXMoKSBjb25zdCBvdmVycmlkZSB7CisgICAgcmV0dXJuIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXMoKS5zZXQoCisgICAgICAgIE1hY2hpbmVGdW5jdGlvblByb3BlcnRpZXM6OlByb3BlcnR5OjpOb1ZSZWdzKTsKKyAgfQorCisgIC8vLyBQcm92aWRlcyB0aGUgaW5zdHJ1Y3Rpb24gaWQgb2YgdGhlIGNsb3Nlc3QgcmVhY2hpbmcgZGVmIGluc3RydWN0aW9uIG9mCisgIC8vLyBQaHlzUmVnIHRoYXQgcmVhY2hlcyBNSSwgcmVsYXRpdmUgdG8gdGhlIGJlZ2luaW5nIG9mIE1JJ3MgYmFzaWMgYmxvY2suCisgIGludCBnZXRSZWFjaGluZ0RlZihNYWNoaW5lSW5zdHIgKk1JLCBpbnQgUGh5c1JlZyk7CisKKyAgLy8vIFByb3ZpZGVzIHRoZSBjbGVhcmFuY2UgLSB0aGUgbnVtYmVyIG9mIGluc3RydWN0aW9ucyBzaW5jZSB0aGUgY2xvc2VzdAorICAvLy8gcmVhY2hpbmcgZGVmIGluc3R1Y3Rpb24gb2YgUGh5c1JlZyB0aGF0IHJlYWNoZXMgTUkuCisgIGludCBnZXRDbGVhcmFuY2UoTWFjaGluZUluc3RyICpNSSwgTUNQaHlzUmVnIFBoeXNSZWcpOworCitwcml2YXRlOgorICAvLy8gU2V0IHVwIExpdmVSZWdzIGJ5IG1lcmdpbmcgcHJlZGVjZXNzb3IgbGl2ZS1vdXQgdmFsdWVzLgorICB2b2lkIGVudGVyQmFzaWNCbG9jayhjb25zdCBMb29wVHJhdmVyc2FsOjpUcmF2ZXJzZWRNQkJJbmZvICZUcmF2ZXJzZWRNQkIpOworCisgIC8vLyBVcGRhdGUgbGl2ZS1vdXQgdmFsdWVzLgorICB2b2lkIGxlYXZlQmFzaWNCbG9jayhjb25zdCBMb29wVHJhdmVyc2FsOjpUcmF2ZXJzZWRNQkJJbmZvICZUcmF2ZXJzZWRNQkIpOworCisgIC8vLyBQcm9jZXNzIGhlIGdpdmVuIGJhc2ljIGJsb2NrLgorICB2b2lkIHByb2Nlc3NCYXNpY0Jsb2NrKGNvbnN0IExvb3BUcmF2ZXJzYWw6OlRyYXZlcnNlZE1CQkluZm8gJlRyYXZlcnNlZE1CQik7CisKKyAgLy8vIFVwZGF0ZSBkZWYtYWdlcyBmb3IgcmVnaXN0ZXJzIGRlZmluZWQgYnkgTUkuCisgIC8vLyBBbHNvIGJyZWFrIGRlcGVuZGVuY2llcyBvbiBwYXJ0aWFsIGRlZnMgYW5kIHVuZGVmIHVzZXMuCisgIHZvaWQgcHJvY2Vzc0RlZnMoTWFjaGluZUluc3RyICopOworfTsKKworfSAvLyBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1JFQUNISU5HREVGU0FOQUxZU0lTX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SZWdBbGxvY1BCUVAuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SZWdBbGxvY1BCUVAuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YjM0Mjg2Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1JlZ0FsbG9jUEJRUC5oCkBAIC0wLDAgKzEsNTM2IEBACisvLz09PS0gUmVnQWxsb2NQQlFQLmggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZWZpbmVzIHRoZSBQQlFQQnVpbGRlciBpbnRlcmZhY2UsIGZvciBjbGFzc2VzIHdoaWNoIGJ1aWxkIFBCUVAKKy8vIGluc3RhbmNlcyB0byByZXByZXNlbnQgcmVnaXN0ZXIgYWxsb2NhdGlvbiBwcm9ibGVtcywgYW5kIHRoZSBSZWdBbGxvY1BCUVAKKy8vIGludGVyZmFjZS4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9SRUdBTExPQ1BCUVBfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fUkVHQUxMT0NQQlFQX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvSGFzaGluZy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9QQlFQL0Nvc3RBbGxvY2F0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vUEJRUC9HcmFwaC5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9QQlFQL01hdGguaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vUEJRUC9SZWR1Y3Rpb25SdWxlcy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9QQlFQL1NvbHV0aW9uLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0Vycm9ySGFuZGxpbmcuaCIKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkZGVmPgorI2luY2x1ZGUgPGxpbWl0cz4KKyNpbmNsdWRlIDxtZW1vcnk+CisjaW5jbHVkZSA8c2V0PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBGdW5jdGlvblBhc3M7CitjbGFzcyBMaXZlSW50ZXJ2YWxzOworY2xhc3MgTWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mbzsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIHJhd19vc3RyZWFtOworCituYW1lc3BhY2UgUEJRUCB7CituYW1lc3BhY2UgUmVnQWxsb2MgeworCisvLy8gQGJyaWVmIFNwaWxsIG9wdGlvbiBpbmRleC4KK2lubGluZSB1bnNpZ25lZCBnZXRTcGlsbE9wdGlvbklkeCgpIHsgcmV0dXJuIDA7IH0KKworLy8vIFxicmllZiBNZXRhZGF0YSB0byBzcGVlZCBhbGxvY2F0YWJpbGl0eSB0ZXN0LgorLy8vCisvLy8gS2VlcHMgdHJhY2sgb2YgdGhlIG51bWJlciBvZiBpbmZpbml0aWVzIGluIGVhY2ggcm93IGFuZCBjb2x1bW4uCitjbGFzcyBNYXRyaXhNZXRhZGF0YSB7CitwdWJsaWM6CisgIE1hdHJpeE1ldGFkYXRhKGNvbnN0IE1hdHJpeCYgTSkKKyAgICA6IFVuc2FmZVJvd3MobmV3IGJvb2xbTS5nZXRSb3dzKCkgLSAxXSgpKSwKKyAgICAgIFVuc2FmZUNvbHMobmV3IGJvb2xbTS5nZXRDb2xzKCkgLSAxXSgpKSB7CisgICAgdW5zaWduZWQqIENvbENvdW50cyA9IG5ldyB1bnNpZ25lZFtNLmdldENvbHMoKSAtIDFdKCk7CisKKyAgICBmb3IgKHVuc2lnbmVkIGkgPSAxOyBpIDwgTS5nZXRSb3dzKCk7ICsraSkgeworICAgICAgdW5zaWduZWQgUm93Q291bnQgPSAwOworICAgICAgZm9yICh1bnNpZ25lZCBqID0gMTsgaiA8IE0uZ2V0Q29scygpOyArK2opIHsKKyAgICAgICAgaWYgKE1baV1bal0gPT0gc3RkOjpudW1lcmljX2xpbWl0czxQQlFQTnVtPjo6aW5maW5pdHkoKSkgeworICAgICAgICAgICsrUm93Q291bnQ7CisgICAgICAgICAgKytDb2xDb3VudHNbaiAtIDFdOworICAgICAgICAgIFVuc2FmZVJvd3NbaSAtIDFdID0gdHJ1ZTsKKyAgICAgICAgICBVbnNhZmVDb2xzW2ogLSAxXSA9IHRydWU7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIFdvcnN0Um93ID0gc3RkOjptYXgoV29yc3RSb3csIFJvd0NvdW50KTsKKyAgICB9CisgICAgdW5zaWduZWQgV29yc3RDb2xDb3VudEZvckN1clJvdyA9CisgICAgICAqc3RkOjptYXhfZWxlbWVudChDb2xDb3VudHMsIENvbENvdW50cyArIE0uZ2V0Q29scygpIC0gMSk7CisgICAgV29yc3RDb2wgPSBzdGQ6Om1heChXb3JzdENvbCwgV29yc3RDb2xDb3VudEZvckN1clJvdyk7CisgICAgZGVsZXRlW10gQ29sQ291bnRzOworICB9CisKKyAgTWF0cml4TWV0YWRhdGEoY29uc3QgTWF0cml4TWV0YWRhdGEgJikgPSBkZWxldGU7CisgIE1hdHJpeE1ldGFkYXRhICZvcGVyYXRvcj0oY29uc3QgTWF0cml4TWV0YWRhdGEgJikgPSBkZWxldGU7CisKKyAgdW5zaWduZWQgZ2V0V29yc3RSb3coKSBjb25zdCB7IHJldHVybiBXb3JzdFJvdzsgfQorICB1bnNpZ25lZCBnZXRXb3JzdENvbCgpIGNvbnN0IHsgcmV0dXJuIFdvcnN0Q29sOyB9CisgIGNvbnN0IGJvb2wqIGdldFVuc2FmZVJvd3MoKSBjb25zdCB7IHJldHVybiBVbnNhZmVSb3dzLmdldCgpOyB9CisgIGNvbnN0IGJvb2wqIGdldFVuc2FmZUNvbHMoKSBjb25zdCB7IHJldHVybiBVbnNhZmVDb2xzLmdldCgpOyB9CisKK3ByaXZhdGU6CisgIHVuc2lnbmVkIFdvcnN0Um93ID0gMDsKKyAgdW5zaWduZWQgV29yc3RDb2wgPSAwOworICBzdGQ6OnVuaXF1ZV9wdHI8Ym9vbFtdPiBVbnNhZmVSb3dzOworICBzdGQ6OnVuaXF1ZV9wdHI8Ym9vbFtdPiBVbnNhZmVDb2xzOworfTsKKworLy8vIFxicmllZiBIb2xkcyBhIHZlY3RvciBvZiB0aGUgYWxsb3dlZCBwaHlzaWNhbCByZWdzIGZvciBhIHZyZWcuCitjbGFzcyBBbGxvd2VkUmVnVmVjdG9yIHsKKyAgZnJpZW5kIGhhc2hfY29kZSBoYXNoX3ZhbHVlKGNvbnN0IEFsbG93ZWRSZWdWZWN0b3IgJik7CisKK3B1YmxpYzoKKyAgQWxsb3dlZFJlZ1ZlY3RvcigpID0gZGVmYXVsdDsKKyAgQWxsb3dlZFJlZ1ZlY3RvcihBbGxvd2VkUmVnVmVjdG9yICYmKSA9IGRlZmF1bHQ7CisKKyAgQWxsb3dlZFJlZ1ZlY3Rvcihjb25zdCBzdGQ6OnZlY3Rvcjx1bnNpZ25lZD4gJk9wdFZlYykKKyAgICA6IE51bU9wdHMoT3B0VmVjLnNpemUoKSksIE9wdHMobmV3IHVuc2lnbmVkW051bU9wdHNdKSB7CisgICAgc3RkOjpjb3B5KE9wdFZlYy5iZWdpbigpLCBPcHRWZWMuZW5kKCksIE9wdHMuZ2V0KCkpOworICB9CisKKyAgdW5zaWduZWQgc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIE51bU9wdHM7IH0KKyAgdW5zaWduZWQgb3BlcmF0b3JbXShzaXplX3QgSSkgY29uc3QgeyByZXR1cm4gT3B0c1tJXTsgfQorCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBBbGxvd2VkUmVnVmVjdG9yICZPdGhlcikgY29uc3QgeworICAgIGlmIChOdW1PcHRzICE9IE90aGVyLk51bU9wdHMpCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgcmV0dXJuIHN0ZDo6ZXF1YWwoT3B0cy5nZXQoKSwgT3B0cy5nZXQoKSArIE51bU9wdHMsIE90aGVyLk9wdHMuZ2V0KCkpOworICB9CisKKyAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IEFsbG93ZWRSZWdWZWN0b3IgJk90aGVyKSBjb25zdCB7CisgICAgcmV0dXJuICEoKnRoaXMgPT0gT3RoZXIpOworICB9CisKK3ByaXZhdGU6CisgIHVuc2lnbmVkIE51bU9wdHMgPSAwOworICBzdGQ6OnVuaXF1ZV9wdHI8dW5zaWduZWRbXT4gT3B0czsKK307CisKK2lubGluZSBoYXNoX2NvZGUgaGFzaF92YWx1ZShjb25zdCBBbGxvd2VkUmVnVmVjdG9yICZPcHRSZWdzKSB7CisgIHVuc2lnbmVkICpPU3RhcnQgPSBPcHRSZWdzLk9wdHMuZ2V0KCk7CisgIHVuc2lnbmVkICpPRW5kID0gT3B0UmVncy5PcHRzLmdldCgpICsgT3B0UmVncy5OdW1PcHRzOworICByZXR1cm4gaGFzaF9jb21iaW5lKE9wdFJlZ3MuTnVtT3B0cywKKyAgICAgICAgICAgICAgICAgICAgICBoYXNoX2NvbWJpbmVfcmFuZ2UoT1N0YXJ0LCBPRW5kKSk7Cit9CisKKy8vLyBcYnJpZWYgSG9sZHMgZ3JhcGgtbGV2ZWwgbWV0YWRhdGEgcmVsZXZhbnQgdG8gUEJRUCBSQSBwcm9ibGVtcy4KK2NsYXNzIEdyYXBoTWV0YWRhdGEgeworcHJpdmF0ZToKKyAgdXNpbmcgQWxsb3dlZFJlZ1ZlY1Bvb2wgPSBWYWx1ZVBvb2w8QWxsb3dlZFJlZ1ZlY3Rvcj47CisKK3B1YmxpYzoKKyAgdXNpbmcgQWxsb3dlZFJlZ1ZlY1JlZiA9IEFsbG93ZWRSZWdWZWNQb29sOjpQb29sUmVmOworCisgIEdyYXBoTWV0YWRhdGEoTWFjaGluZUZ1bmN0aW9uICZNRiwKKyAgICAgICAgICAgICAgICBMaXZlSW50ZXJ2YWxzICZMSVMsCisgICAgICAgICAgICAgICAgTWFjaGluZUJsb2NrRnJlcXVlbmN5SW5mbyAmTUJGSSkKKyAgICA6IE1GKE1GKSwgTElTKExJUyksIE1CRkkoTUJGSSkge30KKworICBNYWNoaW5lRnVuY3Rpb24gJk1GOworICBMaXZlSW50ZXJ2YWxzICZMSVM7CisgIE1hY2hpbmVCbG9ja0ZyZXF1ZW5jeUluZm8gJk1CRkk7CisKKyAgdm9pZCBzZXROb2RlSWRGb3JWUmVnKHVuc2lnbmVkIFZSZWcsIEdyYXBoQmFzZTo6Tm9kZUlkIE5JZCkgeworICAgIFZSZWdUb05vZGVJZFtWUmVnXSA9IE5JZDsKKyAgfQorCisgIEdyYXBoQmFzZTo6Tm9kZUlkIGdldE5vZGVJZEZvclZSZWcodW5zaWduZWQgVlJlZykgY29uc3QgeworICAgIGF1dG8gVlJlZ0l0ciA9IFZSZWdUb05vZGVJZC5maW5kKFZSZWcpOworICAgIGlmIChWUmVnSXRyID09IFZSZWdUb05vZGVJZC5lbmQoKSkKKyAgICAgIHJldHVybiBHcmFwaEJhc2U6OmludmFsaWROb2RlSWQoKTsKKyAgICByZXR1cm4gVlJlZ0l0ci0+c2Vjb25kOworICB9CisKKyAgQWxsb3dlZFJlZ1ZlY1JlZiBnZXRBbGxvd2VkUmVncyhBbGxvd2VkUmVnVmVjdG9yIEFsbG93ZWQpIHsKKyAgICByZXR1cm4gQWxsb3dlZFJlZ1ZlY3MuZ2V0VmFsdWUoc3RkOjptb3ZlKEFsbG93ZWQpKTsKKyAgfQorCitwcml2YXRlOgorICBEZW5zZU1hcDx1bnNpZ25lZCwgR3JhcGhCYXNlOjpOb2RlSWQ+IFZSZWdUb05vZGVJZDsKKyAgQWxsb3dlZFJlZ1ZlY1Bvb2wgQWxsb3dlZFJlZ1ZlY3M7Cit9OworCisvLy8gXGJyaWVmIEhvbGRzIHNvbHZlciBzdGF0ZSBhbmQgb3RoZXIgbWV0YWRhdGEgcmVsZXZhbnQgdG8gZWFjaCBQQlFQIFJBIG5vZGUuCitjbGFzcyBOb2RlTWV0YWRhdGEgeworcHVibGljOgorICB1c2luZyBBbGxvd2VkUmVnVmVjdG9yID0gUmVnQWxsb2M6OkFsbG93ZWRSZWdWZWN0b3I7CisKKyAgLy8gVGhlIG5vZGUncyByZWR1Y3Rpb24gc3RhdGUuIFRoZSBvcmRlciBpbiB0aGlzIGVudW0gaXMgaW1wb3J0YW50LAorICAvLyBhcyBpdCBpcyBhc3N1bWVkIG5vZGVzIGNhbiBvbmx5IHByb2dyZXNzIHVwIChpLmUuIHRvd2FyZHMgYmVpbmcKKyAgLy8gb3B0aW1hbGx5IHJlZHVjaWJsZSkgd2hlbiByZWR1Y2luZyB0aGUgZ3JhcGguCisgIHVzaW5nIFJlZHVjdGlvblN0YXRlID0gZW51bSB7CisgICAgVW5wcm9jZXNzZWQsCisgICAgTm90UHJvdmFibHlBbGxvY2F0YWJsZSwKKyAgICBDb25zZXJ2YXRpdmVseUFsbG9jYXRhYmxlLAorICAgIE9wdGltYWxseVJlZHVjaWJsZQorICB9OworCisgIE5vZGVNZXRhZGF0YSgpID0gZGVmYXVsdDsKKworICBOb2RlTWV0YWRhdGEoY29uc3QgTm9kZU1ldGFkYXRhICZPdGhlcikKKyAgICA6IFJTKE90aGVyLlJTKSwgTnVtT3B0cyhPdGhlci5OdW1PcHRzKSwgRGVuaWVkT3B0cyhPdGhlci5EZW5pZWRPcHRzKSwKKyAgICAgIE9wdFVuc2FmZUVkZ2VzKG5ldyB1bnNpZ25lZFtOdW1PcHRzXSksIFZSZWcoT3RoZXIuVlJlZyksCisgICAgICBBbGxvd2VkUmVncyhPdGhlci5BbGxvd2VkUmVncykKKyNpZm5kZWYgTkRFQlVHCisgICAgICAsIGV2ZXJDb25zZXJ2YXRpdmVseUFsbG9jYXRhYmxlKE90aGVyLmV2ZXJDb25zZXJ2YXRpdmVseUFsbG9jYXRhYmxlKQorI2VuZGlmCisgIHsKKyAgICBpZiAoTnVtT3B0cyA+IDApIHsKKyAgICAgIHN0ZDo6Y29weSgmT3RoZXIuT3B0VW5zYWZlRWRnZXNbMF0sICZPdGhlci5PcHRVbnNhZmVFZGdlc1tOdW1PcHRzXSwKKyAgICAgICAgICAgICAgICAmT3B0VW5zYWZlRWRnZXNbMF0pOworICAgIH0KKyAgfQorCisgIE5vZGVNZXRhZGF0YShOb2RlTWV0YWRhdGEgJiYpID0gZGVmYXVsdDsKKyAgTm9kZU1ldGFkYXRhJiBvcGVyYXRvcj0oTm9kZU1ldGFkYXRhICYmKSA9IGRlZmF1bHQ7CisKKyAgdm9pZCBzZXRWUmVnKHVuc2lnbmVkIFZSZWcpIHsgdGhpcy0+VlJlZyA9IFZSZWc7IH0KKyAgdW5zaWduZWQgZ2V0VlJlZygpIGNvbnN0IHsgcmV0dXJuIFZSZWc7IH0KKworICB2b2lkIHNldEFsbG93ZWRSZWdzKEdyYXBoTWV0YWRhdGE6OkFsbG93ZWRSZWdWZWNSZWYgQWxsb3dlZFJlZ3MpIHsKKyAgICB0aGlzLT5BbGxvd2VkUmVncyA9IHN0ZDo6bW92ZShBbGxvd2VkUmVncyk7CisgIH0KKyAgY29uc3QgQWxsb3dlZFJlZ1ZlY3RvciYgZ2V0QWxsb3dlZFJlZ3MoKSBjb25zdCB7IHJldHVybiAqQWxsb3dlZFJlZ3M7IH0KKworICB2b2lkIHNldHVwKGNvbnN0IFZlY3RvciYgQ29zdHMpIHsKKyAgICBOdW1PcHRzID0gQ29zdHMuZ2V0TGVuZ3RoKCkgLSAxOworICAgIE9wdFVuc2FmZUVkZ2VzID0gc3RkOjp1bmlxdWVfcHRyPHVuc2lnbmVkW10+KG5ldyB1bnNpZ25lZFtOdW1PcHRzXSgpKTsKKyAgfQorCisgIFJlZHVjdGlvblN0YXRlIGdldFJlZHVjdGlvblN0YXRlKCkgY29uc3QgeyByZXR1cm4gUlM7IH0KKyAgdm9pZCBzZXRSZWR1Y3Rpb25TdGF0ZShSZWR1Y3Rpb25TdGF0ZSBSUykgeworICAgIGFzc2VydChSUyA+PSB0aGlzLT5SUyAmJiAiQSBub2RlJ3MgcmVkdWN0aW9uIHN0YXRlIGNhbiBub3QgYmUgZG93bmdyYWRlZCIpOworICAgIHRoaXMtPlJTID0gUlM7CisKKyNpZm5kZWYgTkRFQlVHCisgICAgLy8gUmVtZW1iZXIgdGhpcyBzdGF0ZSB0byBhc3NlcnQgbGF0ZXIgdGhhdCBhIG5vbi1pbmZpbml0ZSByZWdpc3RlcgorICAgIC8vIG9wdGlvbiB3YXMgYXZhaWxhYmxlLgorICAgIGlmIChSUyA9PSBDb25zZXJ2YXRpdmVseUFsbG9jYXRhYmxlKQorICAgICAgZXZlckNvbnNlcnZhdGl2ZWx5QWxsb2NhdGFibGUgPSB0cnVlOworI2VuZGlmCisgIH0KKworICB2b2lkIGhhbmRsZUFkZEVkZ2UoY29uc3QgTWF0cml4TWV0YWRhdGEmIE1ELCBib29sIFRyYW5zcG9zZSkgeworICAgIERlbmllZE9wdHMgKz0gVHJhbnNwb3NlID8gTUQuZ2V0V29yc3RSb3coKSA6IE1ELmdldFdvcnN0Q29sKCk7CisgICAgY29uc3QgYm9vbCogVW5zYWZlT3B0cyA9CisgICAgICBUcmFuc3Bvc2UgPyBNRC5nZXRVbnNhZmVDb2xzKCkgOiBNRC5nZXRVbnNhZmVSb3dzKCk7CisgICAgZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IE51bU9wdHM7ICsraSkKKyAgICAgIE9wdFVuc2FmZUVkZ2VzW2ldICs9IFVuc2FmZU9wdHNbaV07CisgIH0KKworICB2b2lkIGhhbmRsZVJlbW92ZUVkZ2UoY29uc3QgTWF0cml4TWV0YWRhdGEmIE1ELCBib29sIFRyYW5zcG9zZSkgeworICAgIERlbmllZE9wdHMgLT0gVHJhbnNwb3NlID8gTUQuZ2V0V29yc3RSb3coKSA6IE1ELmdldFdvcnN0Q29sKCk7CisgICAgY29uc3QgYm9vbCogVW5zYWZlT3B0cyA9CisgICAgICBUcmFuc3Bvc2UgPyBNRC5nZXRVbnNhZmVDb2xzKCkgOiBNRC5nZXRVbnNhZmVSb3dzKCk7CisgICAgZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IE51bU9wdHM7ICsraSkKKyAgICAgIE9wdFVuc2FmZUVkZ2VzW2ldIC09IFVuc2FmZU9wdHNbaV07CisgIH0KKworICBib29sIGlzQ29uc2VydmF0aXZlbHlBbGxvY2F0YWJsZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gKERlbmllZE9wdHMgPCBOdW1PcHRzKSB8fAorICAgICAgKHN0ZDo6ZmluZCgmT3B0VW5zYWZlRWRnZXNbMF0sICZPcHRVbnNhZmVFZGdlc1tOdW1PcHRzXSwgMCkgIT0KKyAgICAgICAmT3B0VW5zYWZlRWRnZXNbTnVtT3B0c10pOworICB9CisKKyNpZm5kZWYgTkRFQlVHCisgIGJvb2wgd2FzQ29uc2VydmF0aXZlbHlBbGxvY2F0YWJsZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gZXZlckNvbnNlcnZhdGl2ZWx5QWxsb2NhdGFibGU7CisgIH0KKyNlbmRpZgorCitwcml2YXRlOgorICBSZWR1Y3Rpb25TdGF0ZSBSUyA9IFVucHJvY2Vzc2VkOworICB1bnNpZ25lZCBOdW1PcHRzID0gMDsKKyAgdW5zaWduZWQgRGVuaWVkT3B0cyA9IDA7CisgIHN0ZDo6dW5pcXVlX3B0cjx1bnNpZ25lZFtdPiBPcHRVbnNhZmVFZGdlczsKKyAgdW5zaWduZWQgVlJlZyA9IDA7CisgIEdyYXBoTWV0YWRhdGE6OkFsbG93ZWRSZWdWZWNSZWYgQWxsb3dlZFJlZ3M7CisKKyNpZm5kZWYgTkRFQlVHCisgIGJvb2wgZXZlckNvbnNlcnZhdGl2ZWx5QWxsb2NhdGFibGUgPSBmYWxzZTsKKyNlbmRpZgorfTsKKworY2xhc3MgUmVnQWxsb2NTb2x2ZXJJbXBsIHsKK3ByaXZhdGU6CisgIHVzaW5nIFJBTWF0cml4ID0gTURNYXRyaXg8TWF0cml4TWV0YWRhdGE+OworCitwdWJsaWM6CisgIHVzaW5nIFJhd1ZlY3RvciA9IFBCUVA6OlZlY3RvcjsKKyAgdXNpbmcgUmF3TWF0cml4ID0gUEJRUDo6TWF0cml4OworICB1c2luZyBWZWN0b3IgPSBQQlFQOjpWZWN0b3I7CisgIHVzaW5nIE1hdHJpeCA9IFJBTWF0cml4OworICB1c2luZyBDb3N0QWxsb2NhdG9yID0gUEJRUDo6UG9vbENvc3RBbGxvY2F0b3I8VmVjdG9yLCBNYXRyaXg+OworCisgIHVzaW5nIE5vZGVJZCA9IEdyYXBoQmFzZTo6Tm9kZUlkOworICB1c2luZyBFZGdlSWQgPSBHcmFwaEJhc2U6OkVkZ2VJZDsKKworICB1c2luZyBOb2RlTWV0YWRhdGEgPSBSZWdBbGxvYzo6Tm9kZU1ldGFkYXRhOworICBzdHJ1Y3QgRWRnZU1ldGFkYXRhIHt9OworICB1c2luZyBHcmFwaE1ldGFkYXRhID0gUmVnQWxsb2M6OkdyYXBoTWV0YWRhdGE7CisKKyAgdXNpbmcgR3JhcGggPSBQQlFQOjpHcmFwaDxSZWdBbGxvY1NvbHZlckltcGw+OworCisgIFJlZ0FsbG9jU29sdmVySW1wbChHcmFwaCAmRykgOiBHKEcpIHt9CisKKyAgU29sdXRpb24gc29sdmUoKSB7CisgICAgRy5zZXRTb2x2ZXIoKnRoaXMpOworICAgIFNvbHV0aW9uIFM7CisgICAgc2V0dXAoKTsKKyAgICBTID0gYmFja3Byb3BhZ2F0ZShHLCByZWR1Y2UoKSk7CisgICAgRy51bnNldFNvbHZlcigpOworICAgIHJldHVybiBTOworICB9CisKKyAgdm9pZCBoYW5kbGVBZGROb2RlKE5vZGVJZCBOSWQpIHsKKyAgICBhc3NlcnQoRy5nZXROb2RlQ29zdHMoTklkKS5nZXRMZW5ndGgoKSA+IDEgJiYKKyAgICAgICAgICAgIlBCUVAgR3JhcGggc2hvdWxkIG5vdCBjb250YWluIHNpbmdsZSBvciB6ZXJvLW9wdGlvbiBub2RlcyIpOworICAgIEcuZ2V0Tm9kZU1ldGFkYXRhKE5JZCkuc2V0dXAoRy5nZXROb2RlQ29zdHMoTklkKSk7CisgIH0KKworICB2b2lkIGhhbmRsZVJlbW92ZU5vZGUoTm9kZUlkIE5JZCkge30KKyAgdm9pZCBoYW5kbGVTZXROb2RlQ29zdHMoTm9kZUlkIE5JZCwgY29uc3QgVmVjdG9yJiBuZXdDb3N0cykge30KKworICB2b2lkIGhhbmRsZUFkZEVkZ2UoRWRnZUlkIEVJZCkgeworICAgIGhhbmRsZVJlY29ubmVjdEVkZ2UoRUlkLCBHLmdldEVkZ2VOb2RlMUlkKEVJZCkpOworICAgIGhhbmRsZVJlY29ubmVjdEVkZ2UoRUlkLCBHLmdldEVkZ2VOb2RlMklkKEVJZCkpOworICB9CisKKyAgdm9pZCBoYW5kbGVEaXNjb25uZWN0RWRnZShFZGdlSWQgRUlkLCBOb2RlSWQgTklkKSB7CisgICAgTm9kZU1ldGFkYXRhJiBOTWQgPSBHLmdldE5vZGVNZXRhZGF0YShOSWQpOworICAgIGNvbnN0IE1hdHJpeE1ldGFkYXRhJiBNTWQgPSBHLmdldEVkZ2VDb3N0cyhFSWQpLmdldE1ldGFkYXRhKCk7CisgICAgTk1kLmhhbmRsZVJlbW92ZUVkZ2UoTU1kLCBOSWQgPT0gRy5nZXRFZGdlTm9kZTJJZChFSWQpKTsKKyAgICBwcm9tb3RlKE5JZCwgTk1kKTsKKyAgfQorCisgIHZvaWQgaGFuZGxlUmVjb25uZWN0RWRnZShFZGdlSWQgRUlkLCBOb2RlSWQgTklkKSB7CisgICAgTm9kZU1ldGFkYXRhJiBOTWQgPSBHLmdldE5vZGVNZXRhZGF0YShOSWQpOworICAgIGNvbnN0IE1hdHJpeE1ldGFkYXRhJiBNTWQgPSBHLmdldEVkZ2VDb3N0cyhFSWQpLmdldE1ldGFkYXRhKCk7CisgICAgTk1kLmhhbmRsZUFkZEVkZ2UoTU1kLCBOSWQgPT0gRy5nZXRFZGdlTm9kZTJJZChFSWQpKTsKKyAgfQorCisgIHZvaWQgaGFuZGxlVXBkYXRlQ29zdHMoRWRnZUlkIEVJZCwgY29uc3QgTWF0cml4JiBOZXdDb3N0cykgeworICAgIE5vZGVJZCBOMUlkID0gRy5nZXRFZGdlTm9kZTFJZChFSWQpOworICAgIE5vZGVJZCBOMklkID0gRy5nZXRFZGdlTm9kZTJJZChFSWQpOworICAgIE5vZGVNZXRhZGF0YSYgTjFNZCA9IEcuZ2V0Tm9kZU1ldGFkYXRhKE4xSWQpOworICAgIE5vZGVNZXRhZGF0YSYgTjJNZCA9IEcuZ2V0Tm9kZU1ldGFkYXRhKE4ySWQpOworICAgIGJvb2wgVHJhbnNwb3NlID0gTjFJZCAhPSBHLmdldEVkZ2VOb2RlMUlkKEVJZCk7CisKKyAgICAvLyBNZXRhZGF0YSBhcmUgY29tcHV0ZWQgaW5jcmVtZW50YWxseS4gRmlyc3QsIHVwZGF0ZSB0aGVtCisgICAgLy8gYnkgcmVtb3ZpbmcgdGhlIG9sZCBjb3N0LgorICAgIGNvbnN0IE1hdHJpeE1ldGFkYXRhJiBPbGRNTWQgPSBHLmdldEVkZ2VDb3N0cyhFSWQpLmdldE1ldGFkYXRhKCk7CisgICAgTjFNZC5oYW5kbGVSZW1vdmVFZGdlKE9sZE1NZCwgVHJhbnNwb3NlKTsKKyAgICBOMk1kLmhhbmRsZVJlbW92ZUVkZ2UoT2xkTU1kLCAhVHJhbnNwb3NlKTsKKworICAgIC8vIEFuZCB1cGRhdGUgbm93IHRoZSBtZXRhZGF0YSB3aXRoIHRoZSBuZXcgY29zdC4KKyAgICBjb25zdCBNYXRyaXhNZXRhZGF0YSYgTU1kID0gTmV3Q29zdHMuZ2V0TWV0YWRhdGEoKTsKKyAgICBOMU1kLmhhbmRsZUFkZEVkZ2UoTU1kLCBUcmFuc3Bvc2UpOworICAgIE4yTWQuaGFuZGxlQWRkRWRnZShNTWQsICFUcmFuc3Bvc2UpOworCisgICAgLy8gQXMgdGhlIG1ldGFkYXRhIG1heSBoYXZlIGNoYW5nZWQgd2l0aCB0aGUgdXBkYXRlLCB0aGUgbm9kZXMgbWF5IGhhdmUKKyAgICAvLyBiZWNvbWUgQ29uc2VydmF0aXZlbHlBbGxvY2F0YWJsZSBvciBPcHRpbWFsbHlSZWR1Y2libGUuCisgICAgcHJvbW90ZShOMUlkLCBOMU1kKTsKKyAgICBwcm9tb3RlKE4ySWQsIE4yTWQpOworICB9CisKK3ByaXZhdGU6CisgIHZvaWQgcHJvbW90ZShOb2RlSWQgTklkLCBOb2RlTWV0YWRhdGEmIE5NZCkgeworICAgIGlmIChHLmdldE5vZGVEZWdyZWUoTklkKSA9PSAzKSB7CisgICAgICAvLyBUaGlzIG5vZGUgaXMgYmVjb21pbmcgb3B0aW1hbGx5IHJlZHVjaWJsZS4KKyAgICAgIG1vdmVUb09wdGltYWxseVJlZHVjaWJsZU5vZGVzKE5JZCk7CisgICAgfSBlbHNlIGlmIChOTWQuZ2V0UmVkdWN0aW9uU3RhdGUoKSA9PQorICAgICAgICAgICAgICAgTm9kZU1ldGFkYXRhOjpOb3RQcm92YWJseUFsbG9jYXRhYmxlICYmCisgICAgICAgICAgICAgICBOTWQuaXNDb25zZXJ2YXRpdmVseUFsbG9jYXRhYmxlKCkpIHsKKyAgICAgIC8vIFRoaXMgbm9kZSBqdXN0IGJlY2FtZSBjb25zZXJ2YXRpdmVseSBhbGxvY2F0YWJsZS4KKyAgICAgIG1vdmVUb0NvbnNlcnZhdGl2ZWx5QWxsb2NhdGFibGVOb2RlcyhOSWQpOworICAgIH0KKyAgfQorCisgIHZvaWQgcmVtb3ZlRnJvbUN1cnJlbnRTZXQoTm9kZUlkIE5JZCkgeworICAgIHN3aXRjaCAoRy5nZXROb2RlTWV0YWRhdGEoTklkKS5nZXRSZWR1Y3Rpb25TdGF0ZSgpKSB7CisgICAgY2FzZSBOb2RlTWV0YWRhdGE6OlVucHJvY2Vzc2VkOiBicmVhazsKKyAgICBjYXNlIE5vZGVNZXRhZGF0YTo6T3B0aW1hbGx5UmVkdWNpYmxlOgorICAgICAgYXNzZXJ0KE9wdGltYWxseVJlZHVjaWJsZU5vZGVzLmZpbmQoTklkKSAhPQorICAgICAgICAgICAgIE9wdGltYWxseVJlZHVjaWJsZU5vZGVzLmVuZCgpICYmCisgICAgICAgICAgICAgIk5vZGUgbm90IGluIG9wdGltYWxseSByZWR1Y2libGUgc2V0LiIpOworICAgICAgT3B0aW1hbGx5UmVkdWNpYmxlTm9kZXMuZXJhc2UoTklkKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTm9kZU1ldGFkYXRhOjpDb25zZXJ2YXRpdmVseUFsbG9jYXRhYmxlOgorICAgICAgYXNzZXJ0KENvbnNlcnZhdGl2ZWx5QWxsb2NhdGFibGVOb2Rlcy5maW5kKE5JZCkgIT0KKyAgICAgICAgICAgICBDb25zZXJ2YXRpdmVseUFsbG9jYXRhYmxlTm9kZXMuZW5kKCkgJiYKKyAgICAgICAgICAgICAiTm9kZSBub3QgaW4gY29uc2VydmF0aXZlbHkgYWxsb2NhdGFibGUgc2V0LiIpOworICAgICAgQ29uc2VydmF0aXZlbHlBbGxvY2F0YWJsZU5vZGVzLmVyYXNlKE5JZCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIE5vZGVNZXRhZGF0YTo6Tm90UHJvdmFibHlBbGxvY2F0YWJsZToKKyAgICAgIGFzc2VydChOb3RQcm92YWJseUFsbG9jYXRhYmxlTm9kZXMuZmluZChOSWQpICE9CisgICAgICAgICAgICAgTm90UHJvdmFibHlBbGxvY2F0YWJsZU5vZGVzLmVuZCgpICYmCisgICAgICAgICAgICAgIk5vZGUgbm90IGluIG5vdC1wcm92YWJseS1hbGxvY2F0YWJsZSBzZXQuIik7CisgICAgICBOb3RQcm92YWJseUFsbG9jYXRhYmxlTm9kZXMuZXJhc2UoTklkKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgfQorCisgIHZvaWQgbW92ZVRvT3B0aW1hbGx5UmVkdWNpYmxlTm9kZXMoTm9kZUlkIE5JZCkgeworICAgIHJlbW92ZUZyb21DdXJyZW50U2V0KE5JZCk7CisgICAgT3B0aW1hbGx5UmVkdWNpYmxlTm9kZXMuaW5zZXJ0KE5JZCk7CisgICAgRy5nZXROb2RlTWV0YWRhdGEoTklkKS5zZXRSZWR1Y3Rpb25TdGF0ZSgKKyAgICAgIE5vZGVNZXRhZGF0YTo6T3B0aW1hbGx5UmVkdWNpYmxlKTsKKyAgfQorCisgIHZvaWQgbW92ZVRvQ29uc2VydmF0aXZlbHlBbGxvY2F0YWJsZU5vZGVzKE5vZGVJZCBOSWQpIHsKKyAgICByZW1vdmVGcm9tQ3VycmVudFNldChOSWQpOworICAgIENvbnNlcnZhdGl2ZWx5QWxsb2NhdGFibGVOb2Rlcy5pbnNlcnQoTklkKTsKKyAgICBHLmdldE5vZGVNZXRhZGF0YShOSWQpLnNldFJlZHVjdGlvblN0YXRlKAorICAgICAgTm9kZU1ldGFkYXRhOjpDb25zZXJ2YXRpdmVseUFsbG9jYXRhYmxlKTsKKyAgfQorCisgIHZvaWQgbW92ZVRvTm90UHJvdmFibHlBbGxvY2F0YWJsZU5vZGVzKE5vZGVJZCBOSWQpIHsKKyAgICByZW1vdmVGcm9tQ3VycmVudFNldChOSWQpOworICAgIE5vdFByb3ZhYmx5QWxsb2NhdGFibGVOb2Rlcy5pbnNlcnQoTklkKTsKKyAgICBHLmdldE5vZGVNZXRhZGF0YShOSWQpLnNldFJlZHVjdGlvblN0YXRlKAorICAgICAgTm9kZU1ldGFkYXRhOjpOb3RQcm92YWJseUFsbG9jYXRhYmxlKTsKKyAgfQorCisgIHZvaWQgc2V0dXAoKSB7CisgICAgLy8gU2V0IHVwIHdvcmtsaXN0cy4KKyAgICBmb3IgKGF1dG8gTklkIDogRy5ub2RlSWRzKCkpIHsKKyAgICAgIGlmIChHLmdldE5vZGVEZWdyZWUoTklkKSA8IDMpCisgICAgICAgIG1vdmVUb09wdGltYWxseVJlZHVjaWJsZU5vZGVzKE5JZCk7CisgICAgICBlbHNlIGlmIChHLmdldE5vZGVNZXRhZGF0YShOSWQpLmlzQ29uc2VydmF0aXZlbHlBbGxvY2F0YWJsZSgpKQorICAgICAgICBtb3ZlVG9Db25zZXJ2YXRpdmVseUFsbG9jYXRhYmxlTm9kZXMoTklkKTsKKyAgICAgIGVsc2UKKyAgICAgICAgbW92ZVRvTm90UHJvdmFibHlBbGxvY2F0YWJsZU5vZGVzKE5JZCk7CisgICAgfQorICB9CisKKyAgLy8gQ29tcHV0ZSBhIHJlZHVjdGlvbiBvcmRlciBmb3IgdGhlIGdyYXBoIGJ5IGl0ZXJhdGl2ZWx5IGFwcGx5aW5nIFBCUVAKKyAgLy8gcmVkdWN0aW9uIHJ1bGVzLiBMb2NhbGx5IG9wdGltYWwgcnVsZXMgYXJlIGFwcGxpZWQgd2hlbmV2ZXIgcG9zc2libGUgKFIwLAorICAvLyBSMSwgUjIpLiBJZiBubyBsb2NhbGx5LW9wdGltYWwgcnVsZXMgYXBwbHkgdGhlbiBhbnkgY29uc2VydmF0aXZlbHkKKyAgLy8gYWxsb2NhdGFibGUgbm9kZSBpcyByZWR1Y2VkLiBGaW5hbGx5LCBpZiBubyBjb25zZXJ2YXRpdmVseSBhbGxvY2F0YWJsZQorICAvLyBub2RlIGV4aXN0cyB0aGVuIHRoZSBub2RlIHdpdGggdGhlIGxvd2VzdCBzcGlsbC1jb3N0OmRlZ3JlZSByYXRpbyBpcworICAvLyBzZWxlY3RlZC4KKyAgc3RkOjp2ZWN0b3I8R3JhcGhCYXNlOjpOb2RlSWQ+IHJlZHVjZSgpIHsKKyAgICBhc3NlcnQoIUcuZW1wdHkoKSAmJiAiQ2Fubm90IHJlZHVjZSBlbXB0eSBncmFwaC4iKTsKKworICAgIHVzaW5nIE5vZGVJZCA9IEdyYXBoQmFzZTo6Tm9kZUlkOworICAgIHN0ZDo6dmVjdG9yPE5vZGVJZD4gTm9kZVN0YWNrOworCisgICAgLy8gQ29uc3VtZSB3b3JrbGlzdHMuCisgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgIGlmICghT3B0aW1hbGx5UmVkdWNpYmxlTm9kZXMuZW1wdHkoKSkgeworICAgICAgICBOb2RlU2V0OjppdGVyYXRvciBOSXRyID0gT3B0aW1hbGx5UmVkdWNpYmxlTm9kZXMuYmVnaW4oKTsKKyAgICAgICAgTm9kZUlkIE5JZCA9ICpOSXRyOworICAgICAgICBPcHRpbWFsbHlSZWR1Y2libGVOb2Rlcy5lcmFzZShOSXRyKTsKKyAgICAgICAgTm9kZVN0YWNrLnB1c2hfYmFjayhOSWQpOworICAgICAgICBzd2l0Y2ggKEcuZ2V0Tm9kZURlZ3JlZShOSWQpKSB7CisgICAgICAgIGNhc2UgMDoKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAxOgorICAgICAgICAgIGFwcGx5UjEoRywgTklkKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAyOgorICAgICAgICAgIGFwcGx5UjIoRywgTklkKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDogbGx2bV91bnJlYWNoYWJsZSgiTm90IGFuIG9wdGltYWxseSByZWR1Y2libGUgbm9kZS4iKTsKKyAgICAgICAgfQorICAgICAgfSBlbHNlIGlmICghQ29uc2VydmF0aXZlbHlBbGxvY2F0YWJsZU5vZGVzLmVtcHR5KCkpIHsKKyAgICAgICAgLy8gQ29uc2VydmF0aXZlbHkgYWxsb2NhdGFibGUgbm9kZXMgd2lsbCBuZXZlciBzcGlsbC4gRm9yIG5vdyBqdXN0CisgICAgICAgIC8vIHRha2UgdGhlIGZpcnN0IG5vZGUgaW4gdGhlIHNldCBhbmQgcHVzaCBpdCBvbiB0aGUgc3RhY2suIFdoZW4gd2UKKyAgICAgICAgLy8gc3RhcnQgb3B0aW1pemluZyBtb3JlIGhlYXZpbHkgZm9yIHJlZ2lzdGVyIHByZWZlcmVuY2luZywgaXQgbWF5CisgICAgICAgIC8vIHdvdWxkIGJlIGJldHRlciB0byBwdXNoIG5vZGVzIHdpdGggbG93ZXIgJ2V4cGVjdGVkJyBvciB3b3JzdC1jYXNlCisgICAgICAgIC8vIHJlZ2lzdGVyIGNvc3RzIGZpcnN0IChzaW5jZSBlYXJseSBub2RlcyBhcmUgdGhlIG1vc3QKKyAgICAgICAgLy8gY29uc3RyYWluZWQpLgorICAgICAgICBOb2RlU2V0OjppdGVyYXRvciBOSXRyID0gQ29uc2VydmF0aXZlbHlBbGxvY2F0YWJsZU5vZGVzLmJlZ2luKCk7CisgICAgICAgIE5vZGVJZCBOSWQgPSAqTkl0cjsKKyAgICAgICAgQ29uc2VydmF0aXZlbHlBbGxvY2F0YWJsZU5vZGVzLmVyYXNlKE5JdHIpOworICAgICAgICBOb2RlU3RhY2sucHVzaF9iYWNrKE5JZCk7CisgICAgICAgIEcuZGlzY29ubmVjdEFsbE5laWdoYm9yc0Zyb21Ob2RlKE5JZCk7CisgICAgICB9IGVsc2UgaWYgKCFOb3RQcm92YWJseUFsbG9jYXRhYmxlTm9kZXMuZW1wdHkoKSkgeworICAgICAgICBOb2RlU2V0OjppdGVyYXRvciBOSXRyID0KKyAgICAgICAgICBzdGQ6Om1pbl9lbGVtZW50KE5vdFByb3ZhYmx5QWxsb2NhdGFibGVOb2Rlcy5iZWdpbigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgTm90UHJvdmFibHlBbGxvY2F0YWJsZU5vZGVzLmVuZCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU3BpbGxDb3N0Q29tcGFyYXRvcihHKSk7CisgICAgICAgIE5vZGVJZCBOSWQgPSAqTkl0cjsKKyAgICAgICAgTm90UHJvdmFibHlBbGxvY2F0YWJsZU5vZGVzLmVyYXNlKE5JdHIpOworICAgICAgICBOb2RlU3RhY2sucHVzaF9iYWNrKE5JZCk7CisgICAgICAgIEcuZGlzY29ubmVjdEFsbE5laWdoYm9yc0Zyb21Ob2RlKE5JZCk7CisgICAgICB9IGVsc2UKKyAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgcmV0dXJuIE5vZGVTdGFjazsKKyAgfQorCisgIGNsYXNzIFNwaWxsQ29zdENvbXBhcmF0b3IgeworICBwdWJsaWM6CisgICAgU3BpbGxDb3N0Q29tcGFyYXRvcihjb25zdCBHcmFwaCYgRykgOiBHKEcpIHt9CisKKyAgICBib29sIG9wZXJhdG9yKCkoTm9kZUlkIE4xSWQsIE5vZGVJZCBOMklkKSB7CisgICAgICBQQlFQTnVtIE4xU0MgPSBHLmdldE5vZGVDb3N0cyhOMUlkKVswXTsKKyAgICAgIFBCUVBOdW0gTjJTQyA9IEcuZ2V0Tm9kZUNvc3RzKE4ySWQpWzBdOworICAgICAgaWYgKE4xU0MgPT0gTjJTQykKKyAgICAgICAgcmV0dXJuIEcuZ2V0Tm9kZURlZ3JlZShOMUlkKSA8IEcuZ2V0Tm9kZURlZ3JlZShOMklkKTsKKyAgICAgIHJldHVybiBOMVNDIDwgTjJTQzsKKyAgICB9CisKKyAgcHJpdmF0ZToKKyAgICBjb25zdCBHcmFwaCYgRzsKKyAgfTsKKworICBHcmFwaCYgRzsKKyAgdXNpbmcgTm9kZVNldCA9IHN0ZDo6c2V0PE5vZGVJZD47CisgIE5vZGVTZXQgT3B0aW1hbGx5UmVkdWNpYmxlTm9kZXM7CisgIE5vZGVTZXQgQ29uc2VydmF0aXZlbHlBbGxvY2F0YWJsZU5vZGVzOworICBOb2RlU2V0IE5vdFByb3ZhYmx5QWxsb2NhdGFibGVOb2RlczsKK307CisKK2NsYXNzIFBCUVBSQUdyYXBoIDogcHVibGljIFBCUVA6OkdyYXBoPFJlZ0FsbG9jU29sdmVySW1wbD4geworcHJpdmF0ZToKKyAgdXNpbmcgQmFzZVQgPSBQQlFQOjpHcmFwaDxSZWdBbGxvY1NvbHZlckltcGw+OworCitwdWJsaWM6CisgIFBCUVBSQUdyYXBoKEdyYXBoTWV0YWRhdGEgTWV0YWRhdGEpIDogQmFzZVQoc3RkOjptb3ZlKE1ldGFkYXRhKSkge30KKworICAvLy8gQGJyaWVmIER1bXAgdGhpcyBncmFwaCB0byBkYmdzKCkuCisgIHZvaWQgZHVtcCgpIGNvbnN0OworCisgIC8vLyBAYnJpZWYgRHVtcCB0aGlzIGdyYXBoIHRvIGFuIG91dHB1dCBzdHJlYW0uCisgIC8vLyBAcGFyYW0gT1MgT3V0cHV0IHN0cmVhbSB0byBwcmludCBvbi4KKyAgdm9pZCBkdW1wKHJhd19vc3RyZWFtICZPUykgY29uc3Q7CisKKyAgLy8vIEBicmllZiBQcmludCBhIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgZ3JhcGggaW4gRE9UIGZvcm1hdC4KKyAgLy8vIEBwYXJhbSBPUyBPdXRwdXQgc3RyZWFtIHRvIHByaW50IG9uLgorICB2b2lkIHByaW50RG90KHJhd19vc3RyZWFtICZPUykgY29uc3Q7Cit9OworCitpbmxpbmUgU29sdXRpb24gc29sdmUoUEJRUFJBR3JhcGgmIEcpIHsKKyAgaWYgKEcuZW1wdHkoKSkKKyAgICByZXR1cm4gU29sdXRpb24oKTsKKyAgUmVnQWxsb2NTb2x2ZXJJbXBsIFJlZ0FsbG9jU29sdmVyKEcpOworICByZXR1cm4gUmVnQWxsb2NTb2x2ZXIuc29sdmUoKTsKK30KKworfSAvLyBlbmQgbmFtZXNwYWNlIFJlZ0FsbG9jCit9IC8vIGVuZCBuYW1lc3BhY2UgUEJRUAorCisvLy8gQGJyaWVmIENyZWF0ZSBhIFBCUVAgcmVnaXN0ZXIgYWxsb2NhdG9yIGluc3RhbmNlLgorRnVuY3Rpb25QYXNzICoKK2NyZWF0ZVBCUVBSZWdpc3RlckFsbG9jYXRvcihjaGFyICpjdXN0b21QYXNzSUQgPSBudWxscHRyKTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9SRUdBTExPQ1BCUVBfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1JlZ0FsbG9jUmVnaXN0cnkuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SZWdBbGxvY1JlZ2lzdHJ5LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDgxNzQ3ZAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SZWdBbGxvY1JlZ2lzdHJ5LmgKQEAgLTAsMCArMSw2NiBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9SZWdBbGxvY1JlZ2lzdHJ5LmggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgY29udGFpbnMgdGhlIGltcGxlbWVudGF0aW9uIGZvciByZWdpc3RlciBhbGxvY2F0b3IgZnVuY3Rpb24KKy8vIHBhc3MgcmVnaXN0cnkgKFJlZ2lzdGVyUmVnQWxsb2MpLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1JFR0FMTE9DUkVHSVNUUllfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fUkVHQUxMT0NSRUdJU1RSWV9ICisKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZVBhc3NSZWdpc3RyeS5oIgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIEZ1bmN0aW9uUGFzczsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLworLy8vIFJlZ2lzdGVyUmVnQWxsb2MgY2xhc3MgLSBUcmFjayB0aGUgcmVnaXN0cmF0aW9uIG9mIHJlZ2lzdGVyIGFsbG9jYXRvcnMuCisvLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCitjbGFzcyBSZWdpc3RlclJlZ0FsbG9jIDogcHVibGljIE1hY2hpbmVQYXNzUmVnaXN0cnlOb2RlIHsKK3B1YmxpYzoKKyAgdXNpbmcgRnVuY3Rpb25QYXNzQ3RvciA9IEZ1bmN0aW9uUGFzcyAqKCopKCk7CisKKyAgc3RhdGljIE1hY2hpbmVQYXNzUmVnaXN0cnkgUmVnaXN0cnk7CisKKyAgUmVnaXN0ZXJSZWdBbGxvYyhjb25zdCBjaGFyICpOLCBjb25zdCBjaGFyICpELCBGdW5jdGlvblBhc3NDdG9yIEMpCisgICAgICA6IE1hY2hpbmVQYXNzUmVnaXN0cnlOb2RlKE4sIEQsIChNYWNoaW5lUGFzc0N0b3IpQykgeworICAgIFJlZ2lzdHJ5LkFkZCh0aGlzKTsKKyAgfQorCisgIH5SZWdpc3RlclJlZ0FsbG9jKCkgeyBSZWdpc3RyeS5SZW1vdmUodGhpcyk7IH0KKworICAvLyBBY2Nlc3NvcnMuCisgIFJlZ2lzdGVyUmVnQWxsb2MgKmdldE5leHQoKSBjb25zdCB7CisgICAgcmV0dXJuIChSZWdpc3RlclJlZ0FsbG9jICopTWFjaGluZVBhc3NSZWdpc3RyeU5vZGU6OmdldE5leHQoKTsKKyAgfQorCisgIHN0YXRpYyBSZWdpc3RlclJlZ0FsbG9jICpnZXRMaXN0KCkgeworICAgIHJldHVybiAoUmVnaXN0ZXJSZWdBbGxvYyAqKVJlZ2lzdHJ5LmdldExpc3QoKTsKKyAgfQorCisgIHN0YXRpYyBGdW5jdGlvblBhc3NDdG9yIGdldERlZmF1bHQoKSB7CisgICAgcmV0dXJuIChGdW5jdGlvblBhc3NDdG9yKVJlZ2lzdHJ5LmdldERlZmF1bHQoKTsKKyAgfQorCisgIHN0YXRpYyB2b2lkIHNldERlZmF1bHQoRnVuY3Rpb25QYXNzQ3RvciBDKSB7CisgICAgUmVnaXN0cnkuc2V0RGVmYXVsdCgoTWFjaGluZVBhc3NDdG9yKUMpOworICB9CisKKyAgc3RhdGljIHZvaWQgc2V0TGlzdGVuZXIoTWFjaGluZVBhc3NSZWdpc3RyeUxpc3RlbmVyICpMKSB7CisgICAgUmVnaXN0cnkuc2V0TGlzdGVuZXIoTCk7CisgIH0KK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fUkVHQUxMT0NSRUdJU1RSWV9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUmVnaXN0ZXJDbGFzc0luZm8uaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SZWdpc3RlckNsYXNzSW5mby5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk3MTEzYzUKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUmVnaXN0ZXJDbGFzc0luZm8uaApAQCAtMCwwICsxLDE1MCBAQAorLy89PT0tIFJlZ2lzdGVyQ2xhc3NJbmZvLmggLSBEeW5hbWljIFJlZ2lzdGVyIENsYXNzIEluZm8gLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgaW1wbGVtZW50cyB0aGUgUmVnaXN0ZXJDbGFzc0luZm8gY2xhc3Mgd2hpY2ggcHJvdmlkZXMgZHluYW1pYworLy8gaW5mb3JtYXRpb24gYWJvdXQgdGFyZ2V0IHJlZ2lzdGVyIGNsYXNzZXMuIENhbGxlZSBzYXZlZCBhbmQgcmVzZXJ2ZWQKKy8vIHJlZ2lzdGVycyBkZXBlbmRzIG9uIGNhbGxpbmcgY29udmVudGlvbnMgYW5kIG90aGVyIGR5bmFtaWMgaW5mb3JtYXRpb24sIHNvCisvLyBzb21lIHRoaW5ncyBjYW5ub3QgYmUgZGV0ZXJtaW5lZCBzdGF0aWNhbGx5LgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1JFR0lTVEVSQ0xBU1NJTkZPX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1JFR0lTVEVSQ0xBU1NJTkZPX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0FycmF5UmVmLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvQml0VmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0UmVnaXN0ZXJJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9NQy9NQ1JlZ2lzdGVySW5mby5oIgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8Y3N0ZGludD4KKyNpbmNsdWRlIDxtZW1vcnk+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgUmVnaXN0ZXJDbGFzc0luZm8geworICBzdHJ1Y3QgUkNJbmZvIHsKKyAgICB1bnNpZ25lZCBUYWcgPSAwOworICAgIHVuc2lnbmVkIE51bVJlZ3MgPSAwOworICAgIGJvb2wgUHJvcGVyU3ViQ2xhc3MgPSBmYWxzZTsKKyAgICB1aW50OF90IE1pbkNvc3QgPSAwOworICAgIHVpbnQxNl90IExhc3RDb3N0Q2hhbmdlID0gMDsKKyAgICBzdGQ6OnVuaXF1ZV9wdHI8TUNQaHlzUmVnW10+IE9yZGVyOworCisgICAgUkNJbmZvKCkgPSBkZWZhdWx0OworCisgICAgb3BlcmF0b3IgQXJyYXlSZWY8TUNQaHlzUmVnPigpIGNvbnN0IHsKKyAgICAgIHJldHVybiBtYWtlQXJyYXlSZWYoT3JkZXIuZ2V0KCksIE51bVJlZ3MpOworICAgIH0KKyAgfTsKKworICAvLyBCcmllZiBjYWNoZWQgaW5mb3JtYXRpb24gZm9yIGVhY2ggcmVnaXN0ZXIgY2xhc3MuCisgIHN0ZDo6dW5pcXVlX3B0cjxSQ0luZm9bXT4gUmVnQ2xhc3M7CisKKyAgLy8gVGFnIGNoYW5nZXMgd2hlbmV2ZXIgY2FjaGVkIGluZm9ybWF0aW9uIG5lZWRzIHRvIGJlIHJlY29tcHV0ZWQuIEFuIFJDSW5mbworICAvLyBlbnRyeSBpcyB2YWxpZCB3aGVuIGl0cyB0YWcgbWF0Y2hlcy4KKyAgdW5zaWduZWQgVGFnID0gMDsKKworICBjb25zdCBNYWNoaW5lRnVuY3Rpb24gKk1GID0gbnVsbHB0cjsKKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkgPSBudWxscHRyOworCisgIC8vIENhbGxlZSBzYXZlZCByZWdpc3RlcnMgb2YgbGFzdCBNRi4gQXNzdW1lZCB0byBiZSB2YWxpZCB1bnRpbCB0aGUgbmV4dAorICAvLyBydW5PbkZ1bmN0aW9uKCkgY2FsbC4KKyAgLy8gVXNlZCBvbmx5IHRvIGRldGVybWluZSBpZiBhbiB1cGRhdGUgd2FzIG1hZGUgdG8gQ2FsbGVlU2F2ZWRBbGlhc2VzLgorICBjb25zdCBNQ1BoeXNSZWcgKkNhbGxlZVNhdmVkUmVncyA9IG51bGxwdHI7CisKKyAgLy8gTWFwIHJlZ2lzdGVyIGFsaWFzIHRvIHRoZSBjYWxsZWUgc2F2ZWQgUmVnaXN0ZXIuCisgIFNtYWxsVmVjdG9yPE1DUGh5c1JlZywgND4gQ2FsbGVlU2F2ZWRBbGlhc2VzOworCisgIC8vIFJlc2VydmVkIHJlZ2lzdGVycyBpbiB0aGUgY3VycmVudCBNRi4KKyAgQml0VmVjdG9yIFJlc2VydmVkOworCisgIHN0ZDo6dW5pcXVlX3B0cjx1bnNpZ25lZFtdPiBQU2V0TGltaXRzOworCisgIC8vIENvbXB1dGUgYWxsIGluZm9ybWF0aW9uIGFib3V0IFJDLgorICB2b2lkIGNvbXB1dGUoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUkMpIGNvbnN0OworCisgIC8vIFJldHVybiBhbiB1cC10by1kYXRlIFJDSW5mbyBmb3IgUkMuCisgIGNvbnN0IFJDSW5mbyAmZ2V0KGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKSBjb25zdCB7CisgICAgY29uc3QgUkNJbmZvICZSQ0kgPSBSZWdDbGFzc1tSQy0+Z2V0SUQoKV07CisgICAgaWYgKFRhZyAhPSBSQ0kuVGFnKQorICAgICAgY29tcHV0ZShSQyk7CisgICAgcmV0dXJuIFJDSTsKKyAgfQorCitwdWJsaWM6CisgIFJlZ2lzdGVyQ2xhc3NJbmZvKCk7CisKKyAgLy8vIHJ1bk9uRnVuY3Rpb24gLSBQcmVwYXJlIHRvIGFuc3dlciBxdWVzdGlvbnMgYWJvdXQgTUYuIFRoaXMgbXVzdCBiZSBjYWxsZWQKKyAgLy8vIGJlZm9yZSBhbnkgb3RoZXIgbWV0aG9kcyBhcmUgdXNlZC4KKyAgdm9pZCBydW5Pbk1hY2hpbmVGdW5jdGlvbihjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKTsKKworICAvLy8gZ2V0TnVtQWxsb2NhdGFibGVSZWdzIC0gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGFjdHVhbGx5IGFsbG9jYXRhYmxlCisgIC8vLyByZWdpc3RlcnMgaW4gUkMgaW4gdGhlIGN1cnJlbnQgZnVuY3Rpb24uCisgIHVuc2lnbmVkIGdldE51bUFsbG9jYXRhYmxlUmVncyhjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQykgY29uc3QgeworICAgIHJldHVybiBnZXQoUkMpLk51bVJlZ3M7CisgIH0KKworICAvLy8gZ2V0T3JkZXIgLSBSZXR1cm5zIHRoZSBwcmVmZXJyZWQgYWxsb2NhdGlvbiBvcmRlciBmb3IgUkMuIFRoZSBvcmRlcgorICAvLy8gY29udGFpbnMgbm8gcmVzZXJ2ZWQgcmVnaXN0ZXJzLCBhbmQgcmVnaXN0ZXJzIHRoYXQgYWxpYXMgY2FsbGVlIHNhdmVkCisgIC8vLyByZWdpc3RlcnMgY29tZSBsYXN0LgorICBBcnJheVJlZjxNQ1BoeXNSZWc+IGdldE9yZGVyKGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKSBjb25zdCB7CisgICAgcmV0dXJuIGdldChSQyk7CisgIH0KKworICAvLy8gaXNQcm9wZXJTdWJDbGFzcyAtIFJldHVybnMgdHJ1ZSBpZiBSQyBoYXMgYSBsZWdhbCBzdXBlci1jbGFzcyB3aXRoIG1vcmUKKyAgLy8vIGFsbG9jYXRhYmxlIHJlZ2lzdGVycy4KKyAgLy8vCisgIC8vLyBSZWdpc3RlciBjbGFzc2VzIGxpa2UgR1IzMl9OT1NQIGFyZSBub3QgcHJvcGVyIHN1Yi1jbGFzc2VzIGJlY2F1c2UgJWVzcAorICAvLy8gaXMgbm90IGFsbG9jYXRhYmxlLiAgU2ltaWxhcmx5LCB0R1BSIGlzIG5vdCBhIHByb3BlciBzdWItY2xhc3MgaW4gVGh1bWIKKyAgLy8vIG1vZGUgYmVjYXVzZSB0aGUgR1BSIHN1cGVyLWNsYXNzIGlzIG5vdCBsZWdhbC4KKyAgYm9vbCBpc1Byb3BlclN1YkNsYXNzKGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKSBjb25zdCB7CisgICAgcmV0dXJuIGdldChSQykuUHJvcGVyU3ViQ2xhc3M7CisgIH0KKworICAvLy8gZ2V0TGFzdENhbGxlZVNhdmVkQWxpYXMgLSBSZXR1cm5zIHRoZSBsYXN0IGNhbGxlZSBzYXZlZCByZWdpc3RlciB0aGF0CisgIC8vLyBvdmVybGFwcyBQaHlzUmVnLCBvciAwIGlmIFJlZyBkb2Vzbid0IG92ZXJsYXAgYSBDYWxsZWVTYXZlZEFsaWFzZXMuCisgIHVuc2lnbmVkIGdldExhc3RDYWxsZWVTYXZlZEFsaWFzKHVuc2lnbmVkIFBoeXNSZWcpIGNvbnN0IHsKKyAgICBhc3NlcnQoVGFyZ2V0UmVnaXN0ZXJJbmZvOjppc1BoeXNpY2FsUmVnaXN0ZXIoUGh5c1JlZykpOworICAgIGlmIChQaHlzUmVnIDwgQ2FsbGVlU2F2ZWRBbGlhc2VzLnNpemUoKSkKKyAgICAgIHJldHVybiBDYWxsZWVTYXZlZEFsaWFzZXNbUGh5c1JlZ107CisgICAgcmV0dXJuIDA7CisgIH0KKworICAvLy8gR2V0IHRoZSBtaW5pbXVtIHJlZ2lzdGVyIGNvc3QgaW4gUkMncyBhbGxvY2F0aW9uIG9yZGVyLgorICAvLy8gVGhpcyBpcyB0aGUgc21hbGxlc3QgdmFsdWUgcmV0dXJuZWQgYnkgVFJJLT5nZXRDb3N0UGVyVXNlKFJlZykgZm9yIGFsbAorICAvLy8gdGhlIHJlZ2lzdGVycyBpbiBnZXRPcmRlcihSQykuCisgIHVuc2lnbmVkIGdldE1pbkNvc3QoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUkMpIHsKKyAgICByZXR1cm4gZ2V0KFJDKS5NaW5Db3N0OworICB9CisKKyAgLy8vIEdldCB0aGUgcG9zaXRpb24gb2YgdGhlIGxhc3QgY29zdCBjaGFuZ2UgaW4gZ2V0T3JkZXIoUkMpLgorICAvLy8KKyAgLy8vIEFsbCByZWdpc3RlcnMgaW4gZ2V0T3JkZXIoUkMpLnNsaWNlKGdldExhc3RDb3N0Q2hhbmdlKFJDKSkgd2lsbCBoYXZlIHRoZQorICAvLy8gc2FtZSBjb3N0IGFjY29yZGluZyB0byBUUkktPmdldENvc3RQZXJVc2UoKS4KKyAgdW5zaWduZWQgZ2V0TGFzdENvc3RDaGFuZ2UoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUkMpIHsKKyAgICByZXR1cm4gZ2V0KFJDKS5MYXN0Q29zdENoYW5nZTsKKyAgfQorCisgIC8vLyBHZXQgdGhlIHJlZ2lzdGVyIHVuaXQgbGltaXQgZm9yIHRoZSBnaXZlbiBwcmVzc3VyZSBzZXQgaW5kZXguCisgIC8vLworICAvLy8gUmVnaXN0ZXJDbGFzc0luZm8gYWRqdXN0cyB0aGlzIGxpbWl0IGZvciByZXNlcnZlZCByZWdpc3RlcnMuCisgIHVuc2lnbmVkIGdldFJlZ1ByZXNzdXJlU2V0TGltaXQodW5zaWduZWQgSWR4KSBjb25zdCB7CisgICAgaWYgKCFQU2V0TGltaXRzW0lkeF0pCisgICAgICBQU2V0TGltaXRzW0lkeF0gPSBjb21wdXRlUFNldExpbWl0KElkeCk7CisgICAgcmV0dXJuIFBTZXRMaW1pdHNbSWR4XTsKKyAgfQorCitwcm90ZWN0ZWQ6CisgIHVuc2lnbmVkIGNvbXB1dGVQU2V0TGltaXQodW5zaWduZWQgSWR4KSBjb25zdDsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fUkVHSVNURVJDTEFTU0lORk9fSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1JlZ2lzdGVyUHJlc3N1cmUuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SZWdpc3RlclByZXNzdXJlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmIxNGI3OAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SZWdpc3RlclByZXNzdXJlLmgKQEAgLTAsMCArMSw1NzYgQEAKKy8vPT09LSBSZWdpc3RlclByZXNzdXJlLmggLSBEeW5hbWljIFJlZ2lzdGVyIFByZXNzdXJlIC0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlZmluZXMgdGhlIFJlZ2lzdGVyUHJlc3N1cmUgY2xhc3Mgd2hpY2ggY2FuIGJlIHVzZWQgdG8gdHJhY2sKKy8vIE1hY2hpbmVJbnN0ciBsZXZlbCByZWdpc3RlciBwcmVzc3VyZS4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9SRUdJU1RFUlBSRVNTVVJFX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1JFR0lTVEVSUFJFU1NVUkVfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvQXJyYXlSZWYuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NwYXJzZVNldC5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lQmFzaWNCbG9jay5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9TbG90SW5kZXhlcy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9UYXJnZXRSZWdpc3RlckluZm8uaCIKKyNpbmNsdWRlICJsbHZtL01DL0xhbmVCaXRtYXNrLmgiCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkZGVmPgorI2luY2x1ZGUgPGNzdGRpbnQ+CisjaW5jbHVkZSA8Y3N0ZGxpYj4KKyNpbmNsdWRlIDxsaW1pdHM+CisjaW5jbHVkZSA8dmVjdG9yPgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIExpdmVJbnRlcnZhbHM7CitjbGFzcyBNYWNoaW5lRnVuY3Rpb247CitjbGFzcyBNYWNoaW5lSW5zdHI7CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworY2xhc3MgUmVnaXN0ZXJDbGFzc0luZm87CisKK3N0cnVjdCBSZWdpc3Rlck1hc2tQYWlyIHsKKyAgdW5zaWduZWQgUmVnVW5pdDsgLy8vPCBWaXJ0dWFsIHJlZ2lzdGVyIG9yIHJlZ2lzdGVyIHVuaXQuCisgIExhbmVCaXRtYXNrIExhbmVNYXNrOworCisgIFJlZ2lzdGVyTWFza1BhaXIodW5zaWduZWQgUmVnVW5pdCwgTGFuZUJpdG1hc2sgTGFuZU1hc2spCisgICAgICA6IFJlZ1VuaXQoUmVnVW5pdCksIExhbmVNYXNrKExhbmVNYXNrKSB7fQorfTsKKworLy8vIEJhc2UgY2xhc3MgZm9yIHJlZ2lzdGVyIHByZXNzdXJlIHJlc3VsdHMuCitzdHJ1Y3QgUmVnaXN0ZXJQcmVzc3VyZSB7CisgIC8vLyBNYXAgb2YgbWF4IHJlZyBwcmVzc3VyZSBpbmRleGVkIGJ5IHByZXNzdXJlIHNldCBJRCwgbm90IGNsYXNzIElELgorICBzdGQ6OnZlY3Rvcjx1bnNpZ25lZD4gTWF4U2V0UHJlc3N1cmU7CisKKyAgLy8vIExpc3Qgb2YgbGl2ZSBpbiB2aXJ0dWFsIHJlZ2lzdGVycyBvciBwaHlzaWNhbCByZWdpc3RlciB1bml0cy4KKyAgU21hbGxWZWN0b3I8UmVnaXN0ZXJNYXNrUGFpciw4PiBMaXZlSW5SZWdzOworICBTbWFsbFZlY3RvcjxSZWdpc3Rlck1hc2tQYWlyLDg+IExpdmVPdXRSZWdzOworCisgIHZvaWQgZHVtcChjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSkgY29uc3Q7Cit9OworCisvLy8gUmVnaXN0ZXJQcmVzc3VyZSBjb21wdXRlZCB3aXRoaW4gYSByZWdpb24gb2YgaW5zdHJ1Y3Rpb25zIGRlbGltaXRlZCBieQorLy8vIFRvcElkeCBhbmQgQm90dG9tSWR4LiAgRHVyaW5nIHByZXNzdXJlIGNvbXB1dGF0aW9uLCB0aGUgbWF4aW11bSBwcmVzc3VyZSBwZXIKKy8vLyByZWdpc3RlciBwcmVzc3VyZSBzZXQgaXMgaW5jcmVhc2VkLiBPbmNlIHByZXNzdXJlIHdpdGhpbiBhIHJlZ2lvbiBpcyBmdWxseQorLy8vIGNvbXB1dGVkLCB0aGUgbGl2ZS1pbiBhbmQgbGl2ZS1vdXQgc2V0cyBhcmUgcmVjb3JkZWQuCisvLy8KKy8vLyBUaGlzIGlzIHByZWZlcmFibGUgdG8gUmVnaW9uUHJlc3N1cmUgd2hlbiBMaXZlSW50ZXJ2YWxzIGFyZSBhdmFpbGFibGUsCisvLy8gYmVjYXVzZSBkZWxpbWl0aW5nIHJlZ2lvbnMgYnkgU2xvdEluZGV4IGlzIG1vcmUgcm9idXN0IGFuZCBjb252ZW5pZW50IHRoYW4KKy8vLyBob2xkaW5nIGJsb2NrIGl0ZXJhdG9ycy4gVGhlIGJsb2NrIGNvbnRlbnRzIGNhbiBjaGFuZ2Ugd2l0aG91dCBpbnZhbGlkYXRpbmcKKy8vLyB0aGUgcHJlc3N1cmUgcmVzdWx0Lgorc3RydWN0IEludGVydmFsUHJlc3N1cmUgOiBSZWdpc3RlclByZXNzdXJlIHsKKyAgLy8vIFJlY29yZCB0aGUgYm91bmRhcnkgb2YgdGhlIHJlZ2lvbiBiZWluZyB0cmFja2VkLgorICBTbG90SW5kZXggVG9wSWR4OworICBTbG90SW5kZXggQm90dG9tSWR4OworCisgIHZvaWQgcmVzZXQoKTsKKworICB2b2lkIG9wZW5Ub3AoU2xvdEluZGV4IE5leHRUb3ApOworCisgIHZvaWQgb3BlbkJvdHRvbShTbG90SW5kZXggUHJldkJvdHRvbSk7Cit9OworCisvLy8gUmVnaXN0ZXJQcmVzc3VyZSBjb21wdXRlZCB3aXRoaW4gYSByZWdpb24gb2YgaW5zdHJ1Y3Rpb25zIGRlbGltaXRlZCBieQorLy8vIFRvcFBvcyBhbmQgQm90dG9tUG9zLiBUaGlzIGlzIGEgbGVzcyBwcmVjaXNlIHZlcnNpb24gb2YgSW50ZXJ2YWxQcmVzc3VyZSBmb3IKKy8vLyB1c2Ugd2hlbiBMaXZlSW50ZXJ2YWxzIGFyZSB1bmF2YWlsYWJsZS4KK3N0cnVjdCBSZWdpb25QcmVzc3VyZSA6IFJlZ2lzdGVyUHJlc3N1cmUgeworICAvLy8gUmVjb3JkIHRoZSBib3VuZGFyeSBvZiB0aGUgcmVnaW9uIGJlaW5nIHRyYWNrZWQuCisgIE1hY2hpbmVCYXNpY0Jsb2NrOjpjb25zdF9pdGVyYXRvciBUb3BQb3M7CisgIE1hY2hpbmVCYXNpY0Jsb2NrOjpjb25zdF9pdGVyYXRvciBCb3R0b21Qb3M7CisKKyAgdm9pZCByZXNldCgpOworCisgIHZvaWQgb3BlblRvcChNYWNoaW5lQmFzaWNCbG9jazo6Y29uc3RfaXRlcmF0b3IgUHJldlRvcCk7CisKKyAgdm9pZCBvcGVuQm90dG9tKE1hY2hpbmVCYXNpY0Jsb2NrOjpjb25zdF9pdGVyYXRvciBQcmV2Qm90dG9tKTsKK307CisKKy8vLyBDYXB0dXJlIGEgY2hhbmdlIGluIHByZXNzdXJlIGZvciBhIHNpbmdsZSBwcmVzc3VyZSBzZXQuIFVuaXRJbmMgbWF5IGJlCisvLy8gZXhwcmVzc2VkIGluIHRlcm1zIG9mIHVwd2FyZCBvciBkb3dud2FyZCBwcmVzc3VyZSBkZXBlbmRpbmcgb24gdGhlIGNsaWVudAorLy8vIGFuZCB3aWxsIGJlIGR5bmFtaWNhbGx5IGFkanVzdGVkIGZvciBjdXJyZW50IGxpdmVuZXNzLgorLy8vCisvLy8gUHJlc3N1cmUgaW5jcmVtZW50cyBhcmUgdGlueSwgdHlwaWNhbGx5IDEtMiB1bml0cywgYW5kIHRoaXMgaXMgb25seSBmb3IKKy8vLyBoZXVyaXN0aWNzLCBzbyB3ZSBkb24ndCBjaGVjayBVbml0SW5jIG92ZXJmbG93LiBJbnN0ZWFkLCB3ZSBtYXkgaGF2ZSBhCisvLy8gaGlnaGVyIGxldmVsIGFzc2VydCB0aGF0IHByZXNzdXJlIGlzIGNvbnNpc3RlbnQgd2l0aGluIGEgcmVnaW9uLiBXZSBhbHNvCisvLy8gZWZmZWN0aXZlbHkgaWdub3JlIGRlYWQgZGVmcyB3aGljaCBkb24ndCBhZmZlY3QgaGV1cmlzdGljcyBtdWNoLgorY2xhc3MgUHJlc3N1cmVDaGFuZ2UgeworICB1aW50MTZfdCBQU2V0SUQgPSAwOyAvLyBJRCsxLiAwPUludmFsaWQuCisgIGludDE2X3QgVW5pdEluYyA9IDA7CisKK3B1YmxpYzoKKyAgUHJlc3N1cmVDaGFuZ2UoKSA9IGRlZmF1bHQ7CisgIFByZXNzdXJlQ2hhbmdlKHVuc2lnbmVkIGlkKTogUFNldElEKGlkICsgMSkgeworICAgIGFzc2VydChpZCA8IHN0ZDo6bnVtZXJpY19saW1pdHM8dWludDE2X3Q+OjptYXgoKSAmJiAiUFNldElEIG92ZXJmbG93LiIpOworICB9CisKKyAgYm9vbCBpc1ZhbGlkKCkgY29uc3QgeyByZXR1cm4gUFNldElEID4gMDsgfQorCisgIHVuc2lnbmVkIGdldFBTZXQoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzVmFsaWQoKSAmJiAiaW52YWxpZCBQcmVzc3VyZUNoYW5nZSIpOworICAgIHJldHVybiBQU2V0SUQgLSAxOworICB9CisKKyAgLy8gSWYgUFNldElEIGlzIGludmFsaWQsIHJldHVybiBVSU5UMTZfTUFYIHRvIGdpdmUgaXQgbG93ZXN0IHByaW9yaXR5LgorICB1bnNpZ25lZCBnZXRQU2V0T3JNYXgoKSBjb25zdCB7CisgICAgcmV0dXJuIChQU2V0SUQgLSAxKSAmIHN0ZDo6bnVtZXJpY19saW1pdHM8dWludDE2X3Q+OjptYXgoKTsKKyAgfQorCisgIGludCBnZXRVbml0SW5jKCkgY29uc3QgeyByZXR1cm4gVW5pdEluYzsgfQorCisgIHZvaWQgc2V0VW5pdEluYyhpbnQgSW5jKSB7IFVuaXRJbmMgPSBJbmM7IH0KKworICBib29sIG9wZXJhdG9yPT0oY29uc3QgUHJlc3N1cmVDaGFuZ2UgJlJIUykgY29uc3QgeworICAgIHJldHVybiBQU2V0SUQgPT0gUkhTLlBTZXRJRCAmJiBVbml0SW5jID09IFJIUy5Vbml0SW5jOworICB9Cit9OworCit0ZW1wbGF0ZSA8PiBzdHJ1Y3QgaXNQb2RMaWtlPFByZXNzdXJlQ2hhbmdlPiB7CisgICBzdGF0aWMgY29uc3QgYm9vbCB2YWx1ZSA9IHRydWU7Cit9OworCisvLy8gTGlzdCBvZiBQcmVzc3VyZUNoYW5nZXMgaW4gb3JkZXIgb2YgaW5jcmVhc2luZywgdW5pcXVlIFBTZXRJRC4KKy8vLworLy8vIFVzZSBhIHNtYWxsIGZpeGVkIG51bWJlciwgYmVjYXVzZSB3ZSBjYW4gZml0IG1vcmUgUHJlc3N1cmVDaGFuZ2VzIGluIGFuCisvLy8gZW1wdHkgU21hbGxWZWN0b3IgdGhhbiBldmVyIG5lZWQgdG8gYmUgdHJhY2tlZCBwZXIgcmVnaXN0ZXIgY2xhc3MuIElmIG1vcmUKKy8vLyBQU2V0cyBhcmUgYWZmZWN0ZWQsIHRoZW4gd2Ugb25seSB0cmFjayB0aGUgbW9zdCBjb25zdHJhaW5lZC4KK2NsYXNzIFByZXNzdXJlRGlmZiB7CisgIC8vIFRoZSBpbml0aWFsIGRlc2lnbiB3YXMgZm9yIE1heFBTZXRzPTQsIGJ1dCB0aGF0IHJlcXVpcmVzIFBTZXQgcGFydGl0aW9ucywKKyAgLy8gd2hpY2ggYXJlIG5vdCB5ZXQgaW1wbGVtZW50ZWQuIChQU2V0IHBhcnRpdGlvbnMgYXJlIGVxdWl2YWxlbnQgUFNldHMgZ2l2ZW4KKyAgLy8gdGhlIHJlZ2lzdGVyIGNsYXNzZXMgYWN0dWFsbHkgaW4gdXNlIHdpdGhpbiB0aGUgc2NoZWR1bGluZyByZWdpb24uKQorICBlbnVtIHsgTWF4UFNldHMgPSAxNiB9OworCisgIFByZXNzdXJlQ2hhbmdlIFByZXNzdXJlQ2hhbmdlc1tNYXhQU2V0c107CisKKyAgdXNpbmcgaXRlcmF0b3IgPSBQcmVzc3VyZUNoYW5nZSAqOworCisgIGl0ZXJhdG9yIG5vbmNvbnN0X2JlZ2luKCkgeyByZXR1cm4gJlByZXNzdXJlQ2hhbmdlc1swXTsgfQorICBpdGVyYXRvciBub25jb25zdF9lbmQoKSB7IHJldHVybiAmUHJlc3N1cmVDaGFuZ2VzW01heFBTZXRzXTsgfQorCitwdWJsaWM6CisgIHVzaW5nIGNvbnN0X2l0ZXJhdG9yID0gY29uc3QgUHJlc3N1cmVDaGFuZ2UgKjsKKworICBjb25zdF9pdGVyYXRvciBiZWdpbigpIGNvbnN0IHsgcmV0dXJuICZQcmVzc3VyZUNoYW5nZXNbMF07IH0KKyAgY29uc3RfaXRlcmF0b3IgZW5kKCkgY29uc3QgeyByZXR1cm4gJlByZXNzdXJlQ2hhbmdlc1tNYXhQU2V0c107IH0KKworICB2b2lkIGFkZFByZXNzdXJlQ2hhbmdlKHVuc2lnbmVkIFJlZ1VuaXQsIGJvb2wgSXNEZWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAqTVJJKTsKKworICB2b2lkIGR1bXAoY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICZUUkkpIGNvbnN0OworfTsKKworLy8vIExpc3Qgb2YgcmVnaXN0ZXJzIGRlZmluZWQgYW5kIHVzZWQgYnkgYSBtYWNoaW5lIGluc3RydWN0aW9uLgorY2xhc3MgUmVnaXN0ZXJPcGVyYW5kcyB7CitwdWJsaWM6CisgIC8vLyBMaXN0IG9mIHZpcnR1YWwgcmVnaXN0ZXJzIGFuZCByZWdpc3RlciB1bml0cyByZWFkIGJ5IHRoZSBpbnN0cnVjdGlvbi4KKyAgU21hbGxWZWN0b3I8UmVnaXN0ZXJNYXNrUGFpciwgOD4gVXNlczsKKyAgLy8vIFxicmllZiBMaXN0IG9mIHZpcnR1YWwgcmVnaXN0ZXJzIGFuZCByZWdpc3RlciB1bml0cyBkZWZpbmVkIGJ5IHRoZQorICAvLy8gaW5zdHJ1Y3Rpb24gd2hpY2ggYXJlIG5vdCBkZWFkLgorICBTbWFsbFZlY3RvcjxSZWdpc3Rlck1hc2tQYWlyLCA4PiBEZWZzOworICAvLy8gXGJyaWVmIExpc3Qgb2YgdmlydHVhbCByZWdpc3RlcnMgYW5kIHJlZ2lzdGVyIHVuaXRzIGRlZmluZWQgYnkgdGhlCisgIC8vLyBpbnN0cnVjdGlvbiBidXQgZGVhZC4KKyAgU21hbGxWZWN0b3I8UmVnaXN0ZXJNYXNrUGFpciwgOD4gRGVhZERlZnM7CisKKyAgLy8vIEFuYWx5emUgdGhlIGdpdmVuIGluc3RydWN0aW9uIFxwIE1JIGFuZCBmaWxsIGluIHRoZSBVc2VzLCBEZWZzIGFuZAorICAvLy8gRGVhZERlZnMgbGlzdCBiYXNlZCBvbiB0aGUgTWFjaGluZU9wZXJhbmQgZmxhZ3MuCisgIHZvaWQgY29sbGVjdChjb25zdCBNYWNoaW5lSW5zdHIgJk1JLCBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gJlRSSSwKKyAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSwgYm9vbCBUcmFja0xhbmVNYXNrcywKKyAgICAgICAgICAgICAgIGJvb2wgSWdub3JlRGVhZCk7CisKKyAgLy8vIFVzZSBsaXZlbmVzcyBpbmZvcm1hdGlvbiB0byBmaW5kIGRlYWQgZGVmcyBub3QgbWFya2VkIHdpdGggYSBkZWFkIGZsYWcKKyAgLy8vIGFuZCBtb3ZlIHRoZW0gdG8gdGhlIERlYWREZWZzIHZlY3Rvci4KKyAgdm9pZCBkZXRlY3REZWFkRGVmcyhjb25zdCBNYWNoaW5lSW5zdHIgJk1JLCBjb25zdCBMaXZlSW50ZXJ2YWxzICZMSVMpOworCisgIC8vLyBVc2UgbGl2ZW5lc3MgaW5mb3JtYXRpb24gdG8gZmluZCBvdXQgd2hpY2ggdXNlcy9kZWZzIGFyZSBwYXJ0aWFsbHkKKyAgLy8vIHVuZGVmaW5lZC9kZWFkIGFuZCBhZGp1c3QgdGhlIFJlZ2lzdGVyTWFza1BhaXJzIGFjY29yZGluZ2x5LgorICAvLy8gSWYgXHAgQWRkRmxhZ3NNSSBpcyBnaXZlbiB0aGVuIG1pc3NpbmcgcmVhZC11bmRlZiBhbmQgZGVhZCBmbGFncyB3aWxsIGJlCisgIC8vLyBhZGRlZCB0byB0aGUgaW5zdHJ1Y3Rpb24uCisgIHZvaWQgYWRqdXN0TGFuZUxpdmVuZXNzKGNvbnN0IExpdmVJbnRlcnZhbHMgJkxJUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJLCBTbG90SW5kZXggUG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSW5zdHIgKkFkZEZsYWdzTUkgPSBudWxscHRyKTsKK307CisKKy8vLyBBcnJheSBvZiBQcmVzc3VyZURpZmZzLgorY2xhc3MgUHJlc3N1cmVEaWZmcyB7CisgIFByZXNzdXJlRGlmZiAqUERpZmZBcnJheSA9IG51bGxwdHI7CisgIHVuc2lnbmVkIFNpemUgPSAwOworICB1bnNpZ25lZCBNYXggPSAwOworCitwdWJsaWM6CisgIFByZXNzdXJlRGlmZnMoKSA9IGRlZmF1bHQ7CisgIH5QcmVzc3VyZURpZmZzKCkgeyBmcmVlKFBEaWZmQXJyYXkpOyB9CisKKyAgdm9pZCBjbGVhcigpIHsgU2l6ZSA9IDA7IH0KKworICB2b2lkIGluaXQodW5zaWduZWQgTik7CisKKyAgUHJlc3N1cmVEaWZmICZvcGVyYXRvcltdKHVuc2lnbmVkIElkeCkgeworICAgIGFzc2VydChJZHggPCBTaXplICYmICJQcmVzc3VyZURpZmYgaW5kZXggb3V0IG9mIGJvdW5kcyIpOworICAgIHJldHVybiBQRGlmZkFycmF5W0lkeF07CisgIH0KKyAgY29uc3QgUHJlc3N1cmVEaWZmICZvcGVyYXRvcltdKHVuc2lnbmVkIElkeCkgY29uc3QgeworICAgIHJldHVybiBjb25zdF9jYXN0PFByZXNzdXJlRGlmZnMqPih0aGlzKS0+b3BlcmF0b3JbXShJZHgpOworICB9CisKKyAgLy8vIFxicmllZiBSZWNvcmQgcHJlc3N1cmUgZGlmZmVyZW5jZSBpbmR1Y2VkIGJ5IHRoZSBnaXZlbiBvcGVyYW5kIGxpc3QgdG8KKyAgLy8vIG5vZGUgd2l0aCBpbmRleCBccCBJZHguCisgIHZvaWQgYWRkSW5zdHJ1Y3Rpb24odW5zaWduZWQgSWR4LCBjb25zdCBSZWdpc3Rlck9wZXJhbmRzICZSZWdPcGVycywKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkkpOworfTsKKworLy8vIFN0b3JlIHRoZSBlZmZlY3RzIG9mIGEgY2hhbmdlIGluIHByZXNzdXJlIG9uIHRoaW5ncyB0aGF0IE1JIHNjaGVkdWxlciBjYXJlcworLy8vIGFib3V0LgorLy8vCisvLy8gRXhjZXNzIHJlY29yZHMgdGhlIHZhbHVlIG9mIHRoZSBsYXJnZXN0IGRpZmZlcmVuY2UgaW4gcmVnaXN0ZXIgdW5pdHMgYmV5b25kCisvLy8gdGhlIHRhcmdldCdzIHByZXNzdXJlIGxpbWl0cyBhY3Jvc3MgdGhlIGFmZmVjdGVkIHByZXNzdXJlIHNldHMsIHdoZXJlCisvLy8gbGFyZ2VzdCBpcyBkZWZpbmVkIGFzIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGUgZGlmZmVyZW5jZS4gTmVnYXRpdmUKKy8vLyBFeGNlc3NVbml0cyBpbmRpY2F0ZXMgYSByZWR1Y3Rpb24gaW4gcHJlc3N1cmUgdGhhdCBoYWQgYWxyZWFkeSBleGNlZWRlZCB0aGUKKy8vLyB0YXJnZXQncyBsaW1pdHMuCisvLy8KKy8vLyBDcml0aWNhbE1heCByZWNvcmRzIHRoZSBsYXJnZXN0IGluY3JlYXNlIGluIHRoZSB0cmFja2VyJ3MgbWF4IHByZXNzdXJlIHRoYXQKKy8vLyBleGNlZWRzIHRoZSBjcml0aWNhbCBsaW1pdCBmb3Igc29tZSBwcmVzc3VyZSBzZXQgZGV0ZXJtaW5lZCBieSB0aGUgY2xpZW50LgorLy8vCisvLy8gQ3VycmVudE1heCByZWNvcmRzIHRoZSBsYXJnZXN0IGluY3JlYXNlIGluIHRoZSB0cmFja2VyJ3MgbWF4IHByZXNzdXJlIHRoYXQKKy8vLyBleGNlZWRzIHRoZSBjdXJyZW50IGxpbWl0IGZvciBzb21lIHByZXNzdXJlIHNldCBkZXRlcm1pbmVkIGJ5IHRoZSBjbGllbnQuCitzdHJ1Y3QgUmVnUHJlc3N1cmVEZWx0YSB7CisgIFByZXNzdXJlQ2hhbmdlIEV4Y2VzczsKKyAgUHJlc3N1cmVDaGFuZ2UgQ3JpdGljYWxNYXg7CisgIFByZXNzdXJlQ2hhbmdlIEN1cnJlbnRNYXg7CisKKyAgUmVnUHJlc3N1cmVEZWx0YSgpID0gZGVmYXVsdDsKKworICBib29sIG9wZXJhdG9yPT0oY29uc3QgUmVnUHJlc3N1cmVEZWx0YSAmUkhTKSBjb25zdCB7CisgICAgcmV0dXJuIEV4Y2VzcyA9PSBSSFMuRXhjZXNzICYmIENyaXRpY2FsTWF4ID09IFJIUy5Dcml0aWNhbE1heAorICAgICAgJiYgQ3VycmVudE1heCA9PSBSSFMuQ3VycmVudE1heDsKKyAgfQorICBib29sIG9wZXJhdG9yIT0oY29uc3QgUmVnUHJlc3N1cmVEZWx0YSAmUkhTKSBjb25zdCB7CisgICAgcmV0dXJuICFvcGVyYXRvcj09KFJIUyk7CisgIH0KK307CisKKy8vLyBBIHNldCBvZiBsaXZlIHZpcnR1YWwgcmVnaXN0ZXJzIGFuZCBwaHlzaWNhbCByZWdpc3RlciB1bml0cy4KKy8vLworLy8vIFRoaXMgaXMgYSB3cmFwcGVyIGFyb3VuZCBhIFNwYXJzZVNldCB3aGljaCBkZWFscyB3aXRoIG1hcHBpbmcgcmVnaXN0ZXIgdW5pdAorLy8vIGFuZCB2aXJ0dWFsIHJlZ2lzdGVyIGluZGV4ZXMgdG8gYW4gaW5kZXggdXNhYmxlIGJ5IHRoZSBzcGFyc2Ugc2V0LgorY2xhc3MgTGl2ZVJlZ1NldCB7Citwcml2YXRlOgorICBzdHJ1Y3QgSW5kZXhNYXNrUGFpciB7CisgICAgdW5zaWduZWQgSW5kZXg7CisgICAgTGFuZUJpdG1hc2sgTGFuZU1hc2s7CisKKyAgICBJbmRleE1hc2tQYWlyKHVuc2lnbmVkIEluZGV4LCBMYW5lQml0bWFzayBMYW5lTWFzaykKKyAgICAgICAgOiBJbmRleChJbmRleCksIExhbmVNYXNrKExhbmVNYXNrKSB7fQorCisgICAgdW5zaWduZWQgZ2V0U3BhcnNlU2V0SW5kZXgoKSBjb25zdCB7CisgICAgICByZXR1cm4gSW5kZXg7CisgICAgfQorICB9OworCisgIHVzaW5nIFJlZ1NldCA9IFNwYXJzZVNldDxJbmRleE1hc2tQYWlyPjsKKyAgUmVnU2V0IFJlZ3M7CisgIHVuc2lnbmVkIE51bVJlZ1VuaXRzOworCisgIHVuc2lnbmVkIGdldFNwYXJzZUluZGV4RnJvbVJlZyh1bnNpZ25lZCBSZWcpIGNvbnN0IHsKKyAgICBpZiAoVGFyZ2V0UmVnaXN0ZXJJbmZvOjppc1ZpcnR1YWxSZWdpc3RlcihSZWcpKQorICAgICAgcmV0dXJuIFRhcmdldFJlZ2lzdGVySW5mbzo6dmlydFJlZzJJbmRleChSZWcpICsgTnVtUmVnVW5pdHM7CisgICAgYXNzZXJ0KFJlZyA8IE51bVJlZ1VuaXRzKTsKKyAgICByZXR1cm4gUmVnOworICB9CisKKyAgdW5zaWduZWQgZ2V0UmVnRnJvbVNwYXJzZUluZGV4KHVuc2lnbmVkIFNwYXJzZUluZGV4KSBjb25zdCB7CisgICAgaWYgKFNwYXJzZUluZGV4ID49IE51bVJlZ1VuaXRzKQorICAgICAgcmV0dXJuIFRhcmdldFJlZ2lzdGVySW5mbzo6aW5kZXgyVmlydFJlZyhTcGFyc2VJbmRleC1OdW1SZWdVbml0cyk7CisgICAgcmV0dXJuIFNwYXJzZUluZGV4OworICB9CisKK3B1YmxpYzoKKyAgdm9pZCBjbGVhcigpOworICB2b2lkIGluaXQoY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJKTsKKworICBMYW5lQml0bWFzayBjb250YWlucyh1bnNpZ25lZCBSZWcpIGNvbnN0IHsKKyAgICB1bnNpZ25lZCBTcGFyc2VJbmRleCA9IGdldFNwYXJzZUluZGV4RnJvbVJlZyhSZWcpOworICAgIFJlZ1NldDo6Y29uc3RfaXRlcmF0b3IgSSA9IFJlZ3MuZmluZChTcGFyc2VJbmRleCk7CisgICAgaWYgKEkgPT0gUmVncy5lbmQoKSkKKyAgICAgIHJldHVybiBMYW5lQml0bWFzazo6Z2V0Tm9uZSgpOworICAgIHJldHVybiBJLT5MYW5lTWFzazsKKyAgfQorCisgIC8vLyBNYXJrIHRoZSBccCBQYWlyLkxhbmVNYXNrIGxhbmVzIG9mIFxwIFBhaXIuUmVnIGFzIGxpdmUuCisgIC8vLyBSZXR1cm5zIHRoZSBwcmV2aW91c2x5IGxpdmUgbGFuZXMgb2YgXHAgUGFpci5SZWcuCisgIExhbmVCaXRtYXNrIGluc2VydChSZWdpc3Rlck1hc2tQYWlyIFBhaXIpIHsKKyAgICB1bnNpZ25lZCBTcGFyc2VJbmRleCA9IGdldFNwYXJzZUluZGV4RnJvbVJlZyhQYWlyLlJlZ1VuaXQpOworICAgIGF1dG8gSW5zZXJ0UmVzID0gUmVncy5pbnNlcnQoSW5kZXhNYXNrUGFpcihTcGFyc2VJbmRleCwgUGFpci5MYW5lTWFzaykpOworICAgIGlmICghSW5zZXJ0UmVzLnNlY29uZCkgeworICAgICAgTGFuZUJpdG1hc2sgUHJldk1hc2sgPSBJbnNlcnRSZXMuZmlyc3QtPkxhbmVNYXNrOworICAgICAgSW5zZXJ0UmVzLmZpcnN0LT5MYW5lTWFzayB8PSBQYWlyLkxhbmVNYXNrOworICAgICAgcmV0dXJuIFByZXZNYXNrOworICAgIH0KKyAgICByZXR1cm4gTGFuZUJpdG1hc2s6OmdldE5vbmUoKTsKKyAgfQorCisgIC8vLyBDbGVhcnMgdGhlIFxwIFBhaXIuTGFuZU1hc2sgbGFuZXMgb2YgXHAgUGFpci5SZWcgKG1hcmsgdGhlbSBhcyBkZWFkKS4KKyAgLy8vIFJldHVybnMgdGhlIHByZXZpb3VzbHkgbGl2ZSBsYW5lcyBvZiBccCBQYWlyLlJlZy4KKyAgTGFuZUJpdG1hc2sgZXJhc2UoUmVnaXN0ZXJNYXNrUGFpciBQYWlyKSB7CisgICAgdW5zaWduZWQgU3BhcnNlSW5kZXggPSBnZXRTcGFyc2VJbmRleEZyb21SZWcoUGFpci5SZWdVbml0KTsKKyAgICBSZWdTZXQ6Oml0ZXJhdG9yIEkgPSBSZWdzLmZpbmQoU3BhcnNlSW5kZXgpOworICAgIGlmIChJID09IFJlZ3MuZW5kKCkpCisgICAgICByZXR1cm4gTGFuZUJpdG1hc2s6OmdldE5vbmUoKTsKKyAgICBMYW5lQml0bWFzayBQcmV2TWFzayA9IEktPkxhbmVNYXNrOworICAgIEktPkxhbmVNYXNrICY9IH5QYWlyLkxhbmVNYXNrOworICAgIHJldHVybiBQcmV2TWFzazsKKyAgfQorCisgIHNpemVfdCBzaXplKCkgY29uc3QgeworICAgIHJldHVybiBSZWdzLnNpemUoKTsKKyAgfQorCisgIHRlbXBsYXRlPHR5cGVuYW1lIENvbnRhaW5lclQ+CisgIHZvaWQgYXBwZW5kVG8oQ29udGFpbmVyVCAmVG8pIGNvbnN0IHsKKyAgICBmb3IgKGNvbnN0IEluZGV4TWFza1BhaXIgJlAgOiBSZWdzKSB7CisgICAgICB1bnNpZ25lZCBSZWcgPSBnZXRSZWdGcm9tU3BhcnNlSW5kZXgoUC5JbmRleCk7CisgICAgICBpZiAoUC5MYW5lTWFzay5hbnkoKSkKKyAgICAgICAgVG8ucHVzaF9iYWNrKFJlZ2lzdGVyTWFza1BhaXIoUmVnLCBQLkxhbmVNYXNrKSk7CisgICAgfQorICB9Cit9OworCisvLy8gVHJhY2sgdGhlIGN1cnJlbnQgcmVnaXN0ZXIgcHJlc3N1cmUgYXQgc29tZSBwb3NpdGlvbiBpbiB0aGUgaW5zdHJ1Y3Rpb24KKy8vLyBzdHJlYW0sIGFuZCByZW1lbWJlciB0aGUgaGlnaCB3YXRlciBtYXJrIHdpdGhpbiB0aGUgcmVnaW9uIHRyYXZlcnNlZC4gVGhpcworLy8vIGRvZXMgbm90IGF1dG9tYXRpY2FsbHkgY29uc2lkZXIgbGl2ZS10aHJvdWdoIHJhbmdlcy4gVGhlIGNsaWVudCBtYXkKKy8vLyBpbmRlcGVuZGVudGx5IGFkanVzdCBmb3IgZ2xvYmFsIGxpdmVuZXNzLgorLy8vCisvLy8gRWFjaCBSZWdQcmVzc3VyZVRyYWNrZXIgb25seSB3b3JrcyB3aXRoaW4gYSBNYWNoaW5lQmFzaWNCbG9jay4gUHJlc3N1cmUgY2FuCisvLy8gYmUgdHJhY2tlZCBhY3Jvc3MgYSBsYXJnZXIgcmVnaW9uIGJ5IHN0b3JpbmcgYSBSZWdpc3RlclByZXNzdXJlIHJlc3VsdCBhdAorLy8vIGVhY2ggYmxvY2sgYm91bmRhcnkgYW5kIGV4cGxpY2l0bHkgYWRqdXN0aW5nIHByZXNzdXJlIHRvIGFjY291bnQgZm9yIGJsb2NrCisvLy8gbGl2ZS1pbiBhbmQgbGl2ZS1vdXQgcmVnaXN0ZXIgc2V0cy4KKy8vLworLy8vIFJlZ1ByZXNzdXJlVHJhY2tlciBob2xkcyBhIHJlZmVyZW5jZSB0byBhIFJlZ2lzdGVyUHJlc3N1cmUgcmVzdWx0IHRoYXQgaXQKKy8vLyBjb21wdXRlcyBpbmNyZW1lbnRhbGx5LiBEdXJpbmcgZG93bndhcmQgdHJhY2tpbmcsIFAuQm90dG9tSWR4IG9yIFAuQm90dG9tUG9zCisvLy8gaXMgaW52YWxpZCB1bnRpbCBpdCByZWFjaGVzIHRoZSBlbmQgb2YgdGhlIGJsb2NrIG9yIGNsb3NlUmVnaW9uKCkgaXMKKy8vLyBleHBsaWNpdGx5IGNhbGxlZC4gU2ltaWxhcmx5LCBQLlRvcElkeCBpcyBpbnZhbGlkIGR1cmluZyB1cHdhcmQKKy8vLyB0cmFja2luZy4gQ2hhbmdpbmcgZGlyZWN0aW9uIGhhcyB0aGUgc2lkZSBlZmZlY3Qgb2YgY2xvc2luZyByZWdpb24sIGFuZAorLy8vIHRyYXZlcnNpbmcgcGFzdCBUb3BJZHggb3IgQm90dG9tSWR4IHJlb3BlbnMgaXQuCitjbGFzcyBSZWdQcmVzc3VyZVRyYWNrZXIgeworICBjb25zdCBNYWNoaW5lRnVuY3Rpb24gKk1GID0gbnVsbHB0cjsKKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkgPSBudWxscHRyOworICBjb25zdCBSZWdpc3RlckNsYXNzSW5mbyAqUkNJID0gbnVsbHB0cjsKKyAgY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAqTVJJOworICBjb25zdCBMaXZlSW50ZXJ2YWxzICpMSVMgPSBudWxscHRyOworCisgIC8vLyBXZSBjdXJyZW50bHkgb25seSBhbGxvdyBwcmVzc3VyZSB0cmFja2luZyB3aXRoaW4gYSBibG9jay4KKyAgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKk1CQiA9IG51bGxwdHI7CisKKyAgLy8vIFRyYWNrIHRoZSBtYXggcHJlc3N1cmUgd2l0aGluIHRoZSByZWdpb24gdHJhdmVyc2VkIHNvIGZhci4KKyAgUmVnaXN0ZXJQcmVzc3VyZSAmUDsKKworICAvLy8gUnVuIGluIHR3byBtb2RlcyBkZXBlbmRlbmRpbmcgb24gd2hldGhlciBjb25zdHJ1Y3RlZCB3aXRoIEludGVydmFsUHJlc3N1cmUKKyAgLy8vIG9yIFJlZ2lzdGVyUHJlc3N1cmUuIElmIHJlcXVpcmVJbnRlcnZhbHMgaXMgZmFsc2UsIExJUyBhcmUgaWdub3JlZC4KKyAgYm9vbCBSZXF1aXJlSW50ZXJ2YWxzOworCisgIC8vLyBUcnVlIGlmIFVudGllZERlZnMgd2lsbCBiZSBwb3B1bGF0ZWQuCisgIGJvb2wgVHJhY2tVbnRpZWREZWZzID0gZmFsc2U7CisKKyAgLy8vIFRydWUgaWYgbGFuZW1hc2tzIHNob3VsZCBiZSB0cmFja2VkLgorICBib29sIFRyYWNrTGFuZU1hc2tzID0gZmFsc2U7CisKKyAgLy8vIFJlZ2lzdGVyIHByZXNzdXJlIGNvcnJlc3BvbmRzIHRvIGxpdmVuZXNzIGJlZm9yZSB0aGlzIGluc3RydWN0aW9uCisgIC8vLyBpdGVyYXRvci4gSXQgbWF5IHBvaW50IHRvIHRoZSBlbmQgb2YgdGhlIGJsb2NrIG9yIGEgRGVidWdWYWx1ZSByYXRoZXIgdGhhbgorICAvLy8gYW4gaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVCYXNpY0Jsb2NrOjpjb25zdF9pdGVyYXRvciBDdXJyUG9zOworCisgIC8vLyBQcmVzc3VyZSBtYXAgaW5kZXhlZCBieSBwcmVzc3VyZSBzZXQgSUQsIG5vdCBjbGFzcyBJRC4KKyAgc3RkOjp2ZWN0b3I8dW5zaWduZWQ+IEN1cnJTZXRQcmVzc3VyZTsKKworICAvLy8gU2V0IG9mIGxpdmUgcmVnaXN0ZXJzLgorICBMaXZlUmVnU2V0IExpdmVSZWdzOworCisgIC8vLyBTZXQgb2YgdnJlZyBkZWZzIHRoYXQgc3RhcnQgYSBsaXZlIHJhbmdlLgorICBTcGFyc2VTZXQ8dW5zaWduZWQsIFZpcnRSZWcySW5kZXhGdW5jdG9yPiBVbnRpZWREZWZzOworICAvLy8gTGl2ZS10aHJvdWdoIHByZXNzdXJlLgorICBzdGQ6OnZlY3Rvcjx1bnNpZ25lZD4gTGl2ZVRocnVQcmVzc3VyZTsKKworcHVibGljOgorICBSZWdQcmVzc3VyZVRyYWNrZXIoSW50ZXJ2YWxQcmVzc3VyZSAmcnApIDogUChycCksIFJlcXVpcmVJbnRlcnZhbHModHJ1ZSkge30KKyAgUmVnUHJlc3N1cmVUcmFja2VyKFJlZ2lvblByZXNzdXJlICZycCkgOiBQKHJwKSwgUmVxdWlyZUludGVydmFscyhmYWxzZSkge30KKworICB2b2lkIHJlc2V0KCk7CisKKyAgdm9pZCBpbml0KGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAqbWYsIGNvbnN0IFJlZ2lzdGVyQ2xhc3NJbmZvICpyY2ksCisgICAgICAgICAgICBjb25zdCBMaXZlSW50ZXJ2YWxzICpsaXMsIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICptYmIsCisgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6Y29uc3RfaXRlcmF0b3IgcG9zLAorICAgICAgICAgICAgYm9vbCBUcmFja0xhbmVNYXNrcywgYm9vbCBUcmFja1VudGllZERlZnMpOworCisgIC8vLyBGb3JjZSBsaXZlbmVzcyBvZiB2aXJ0dWFsIHJlZ2lzdGVycyBvciBwaHlzaWNhbCByZWdpc3RlcgorICAvLy8gdW5pdHMuIFBhcnRpY3VsYXJseSB1c2VmdWwgdG8gaW5pdGlhbGl6ZSB0aGUgbGl2ZWluL291dCBzdGF0ZSBvZiB0aGUKKyAgLy8vIHRyYWNrZXIgYmVmb3JlIHRoZSBmaXJzdCBjYWxsIHRvIGFkdmFuY2UvcmVjZWRlLgorICB2b2lkIGFkZExpdmVSZWdzKEFycmF5UmVmPFJlZ2lzdGVyTWFza1BhaXI+IFJlZ3MpOworCisgIC8vLyBHZXQgdGhlIE1JIHBvc2l0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhpcyByZWdpc3RlciBwcmVzc3VyZS4KKyAgTWFjaGluZUJhc2ljQmxvY2s6OmNvbnN0X2l0ZXJhdG9yIGdldFBvcygpIGNvbnN0IHsgcmV0dXJuIEN1cnJQb3M7IH0KKworICAvLyBSZXNldCB0aGUgTUkgcG9zaXRpb24gY29ycmVzcG9uZGluZyB0byB0aGUgcmVnaXN0ZXIgcHJlc3N1cmUuIFRoaXMgYWxsb3dzCisgIC8vIHNjaGVkdWxlcnMgdG8gbW92ZSBpbnN0cnVjdGlvbnMgYWJvdmUgdGhlIFJlZ1ByZXNzdXJlVHJhY2tlcidzCisgIC8vIEN1cnJQb3MuIFNpbmNlIHRoZSBwcmVzc3VyZSBpcyBjb21wdXRlZCBiZWZvcmUgQ3VyclBvcywgdGhlIGl0ZXJhdG9yCisgIC8vIHBvc2l0aW9uIGNoYW5nZXMgd2hpbGUgcHJlc3N1cmUgZG9lcyBub3QuCisgIHZvaWQgc2V0UG9zKE1hY2hpbmVCYXNpY0Jsb2NrOjpjb25zdF9pdGVyYXRvciBQb3MpIHsgQ3VyclBvcyA9IFBvczsgfQorCisgIC8vLyBSZWNlZGUgYWNyb3NzIHRoZSBwcmV2aW91cyBpbnN0cnVjdGlvbi4KKyAgdm9pZCByZWNlZGUoU21hbGxWZWN0b3JJbXBsPFJlZ2lzdGVyTWFza1BhaXI+ICpMaXZlVXNlcyA9IG51bGxwdHIpOworCisgIC8vLyBSZWNlZGUgYWNyb3NzIHRoZSBwcmV2aW91cyBpbnN0cnVjdGlvbi4KKyAgLy8vIFRoaXMgImxvdy1sZXZlbCIgdmFyaWFudCBhc3N1bWVzIHRoYXQgcmVjZWRlU2tpcERlYnVnVmFsdWVzKCkgd2FzCisgIC8vLyBjYWxsZWQgcHJldmlvdXNseSBhbmQgdGFrZXMgcHJlY29tcHV0ZWQgUmVnaXN0ZXJPcGVyYW5kcyBmb3IgdGhlCisgIC8vLyBpbnN0cnVjdGlvbi4KKyAgdm9pZCByZWNlZGUoY29uc3QgUmVnaXN0ZXJPcGVyYW5kcyAmUmVnT3BlcnMsCisgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxSZWdpc3Rlck1hc2tQYWlyPiAqTGl2ZVVzZXMgPSBudWxscHRyKTsKKworICAvLy8gUmVjZWRlIHVudGlsIHdlIGZpbmQgYW4gaW5zdHJ1Y3Rpb24gd2hpY2ggaXMgbm90IGEgRGVidWdWYWx1ZS4KKyAgdm9pZCByZWNlZGVTa2lwRGVidWdWYWx1ZXMoKTsKKworICAvLy8gQWR2YW5jZSBhY3Jvc3MgdGhlIGN1cnJlbnQgaW5zdHJ1Y3Rpb24uCisgIHZvaWQgYWR2YW5jZSgpOworCisgIC8vLyBBZHZhbmNlIGFjcm9zcyB0aGUgY3VycmVudCBpbnN0cnVjdGlvbi4KKyAgLy8vIFRoaXMgaXMgYSAibG93LWxldmVsIiB2YXJpYW50IG9mIGFkdmFuY2UoKSB3aGljaCB0YWtlcyBwcmVjb21wdXRlZAorICAvLy8gUmVnaXN0ZXJPcGVyYW5kcyBvZiB0aGUgaW5zdHJ1Y3Rpb24uCisgIHZvaWQgYWR2YW5jZShjb25zdCBSZWdpc3Rlck9wZXJhbmRzICZSZWdPcGVycyk7CisKKyAgLy8vIEZpbmFsaXplIHRoZSByZWdpb24gYm91bmRhcmllcyBhbmQgcmVjb3JlZCBsaXZlIGlucyBhbmQgbGl2ZSBvdXRzLgorICB2b2lkIGNsb3NlUmVnaW9uKCk7CisKKyAgLy8vIEluaXRpYWxpemUgdGhlIExpdmVUaHJ1IHByZXNzdXJlIHNldCBiYXNlZCBvbiB0aGUgdW50aWVkIGRlZnMgZm91bmQgaW4KKyAgLy8vIFJQVHJhY2tlci4KKyAgdm9pZCBpbml0TGl2ZVRocnUoY29uc3QgUmVnUHJlc3N1cmVUcmFja2VyICZSUFRyYWNrZXIpOworCisgIC8vLyBDb3B5IGFuIGV4aXN0aW5nIGxpdmUgdGhydSBwcmVzc3VyZSByZXN1bHQuCisgIHZvaWQgaW5pdExpdmVUaHJ1KEFycmF5UmVmPHVuc2lnbmVkPiBQcmVzc3VyZVNldCkgeworICAgIExpdmVUaHJ1UHJlc3N1cmUuYXNzaWduKFByZXNzdXJlU2V0LmJlZ2luKCksIFByZXNzdXJlU2V0LmVuZCgpKTsKKyAgfQorCisgIEFycmF5UmVmPHVuc2lnbmVkPiBnZXRMaXZlVGhydSgpIGNvbnN0IHsgcmV0dXJuIExpdmVUaHJ1UHJlc3N1cmU7IH0KKworICAvLy8gR2V0IHRoZSByZXN1bHRpbmcgcmVnaXN0ZXIgcHJlc3N1cmUgb3ZlciB0aGUgdHJhdmVyc2VkIHJlZ2lvbi4KKyAgLy8vIFRoaXMgcmVzdWx0IGlzIGNvbXBsZXRlIGlmIGNsb3NlUmVnaW9uKCkgd2FzIGV4cGxpY2l0bHkgaW52b2tlZC4KKyAgUmVnaXN0ZXJQcmVzc3VyZSAmZ2V0UHJlc3N1cmUoKSB7IHJldHVybiBQOyB9CisgIGNvbnN0IFJlZ2lzdGVyUHJlc3N1cmUgJmdldFByZXNzdXJlKCkgY29uc3QgeyByZXR1cm4gUDsgfQorCisgIC8vLyBHZXQgdGhlIHJlZ2lzdGVyIHNldCBwcmVzc3VyZSBhdCB0aGUgY3VycmVudCBwb3NpdGlvbiwgd2hpY2ggbWF5IGJlIGxlc3MKKyAgLy8vIHRoYW4gdGhlIHByZXNzdXJlIGFjcm9zcyB0aGUgdHJhdmVyc2VkIHJlZ2lvbi4KKyAgY29uc3Qgc3RkOjp2ZWN0b3I8dW5zaWduZWQ+ICZnZXRSZWdTZXRQcmVzc3VyZUF0UG9zKCkgY29uc3QgeworICAgIHJldHVybiBDdXJyU2V0UHJlc3N1cmU7CisgIH0KKworICBib29sIGlzVG9wQ2xvc2VkKCkgY29uc3Q7CisgIGJvb2wgaXNCb3R0b21DbG9zZWQoKSBjb25zdDsKKworICB2b2lkIGNsb3NlVG9wKCk7CisgIHZvaWQgY2xvc2VCb3R0b20oKTsKKworICAvLy8gQ29uc2lkZXIgdGhlIHByZXNzdXJlIGluY3JlYXNlIGNhdXNlZCBieSB0cmF2ZXJzaW5nIHRoaXMgaW5zdHJ1Y3Rpb24KKyAgLy8vIGJvdHRvbS11cC4gRmluZCB0aGUgcHJlc3N1cmUgc2V0IHdpdGggdGhlIG1vc3QgY2hhbmdlIGJleW9uZCBpdHMgcHJlc3N1cmUKKyAgLy8vIGxpbWl0IGJhc2VkIG9uIHRoZSB0cmFja2VyJ3MgY3VycmVudCBwcmVzc3VyZSwgYW5kIHJlY29yZCB0aGUgbnVtYmVyIG9mCisgIC8vLyBleGNlc3MgcmVnaXN0ZXIgdW5pdHMgb2YgdGhhdCBwcmVzc3VyZSBzZXQgaW50cm9kdWNlZCBieSB0aGlzIGluc3RydWN0aW9uLgorICB2b2lkIGdldE1heFVwd2FyZFByZXNzdXJlRGVsdGEoY29uc3QgTWFjaGluZUluc3RyICpNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByZXNzdXJlRGlmZiAqUERpZmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdQcmVzc3VyZURlbHRhICZEZWx0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFByZXNzdXJlQ2hhbmdlPiBDcml0aWNhbFBTZXRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8dW5zaWduZWQ+IE1heFByZXNzdXJlTGltaXQpOworCisgIHZvaWQgZ2V0VXB3YXJkUHJlc3N1cmVEZWx0YShjb25zdCBNYWNoaW5lSW5zdHIgKk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypjb25zdCovIFByZXNzdXJlRGlmZiAmUERpZmYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdQcmVzc3VyZURlbHRhICZEZWx0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFByZXNzdXJlQ2hhbmdlPiBDcml0aWNhbFBTZXRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8dW5zaWduZWQ+IE1heFByZXNzdXJlTGltaXQpIGNvbnN0OworCisgIC8vLyBDb25zaWRlciB0aGUgcHJlc3N1cmUgaW5jcmVhc2UgY2F1c2VkIGJ5IHRyYXZlcnNpbmcgdGhpcyBpbnN0cnVjdGlvbgorICAvLy8gdG9wLWRvd24uIEZpbmQgdGhlIHByZXNzdXJlIHNldCB3aXRoIHRoZSBtb3N0IGNoYW5nZSBiZXlvbmQgaXRzIHByZXNzdXJlCisgIC8vLyBsaW1pdCBiYXNlZCBvbiB0aGUgdHJhY2tlcidzIGN1cnJlbnQgcHJlc3N1cmUsIGFuZCByZWNvcmQgdGhlIG51bWJlciBvZgorICAvLy8gZXhjZXNzIHJlZ2lzdGVyIHVuaXRzIG9mIHRoYXQgcHJlc3N1cmUgc2V0IGludHJvZHVjZWQgYnkgdGhpcyBpbnN0cnVjdGlvbi4KKyAgdm9pZCBnZXRNYXhEb3dud2FyZFByZXNzdXJlRGVsdGEoY29uc3QgTWFjaGluZUluc3RyICpNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnUHJlc3N1cmVEZWx0YSAmRGVsdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFByZXNzdXJlQ2hhbmdlPiBDcml0aWNhbFBTZXRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjx1bnNpZ25lZD4gTWF4UHJlc3N1cmVMaW1pdCk7CisKKyAgLy8vIEZpbmQgdGhlIHByZXNzdXJlIHNldCB3aXRoIHRoZSBtb3N0IGNoYW5nZSBiZXlvbmQgaXRzIHByZXNzdXJlIGxpbWl0IGFmdGVyCisgIC8vLyB0cmF2ZXJzaW5nIHRoaXMgaW5zdHJ1Y3Rpb24gZWl0aGVyIHVwd2FyZCBvciBkb3dud2FyZCBkZXBlbmRpbmcgb24gdGhlCisgIC8vLyBjbG9zZWQgZW5kIG9mIHRoZSBjdXJyZW50IHJlZ2lvbi4KKyAgdm9pZCBnZXRNYXhQcmVzc3VyZURlbHRhKGNvbnN0IE1hY2hpbmVJbnN0ciAqTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdQcmVzc3VyZURlbHRhICZEZWx0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFByZXNzdXJlQ2hhbmdlPiBDcml0aWNhbFBTZXRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8dW5zaWduZWQ+IE1heFByZXNzdXJlTGltaXQpIHsKKyAgICBpZiAoaXNUb3BDbG9zZWQoKSkKKyAgICAgIHJldHVybiBnZXRNYXhEb3dud2FyZFByZXNzdXJlRGVsdGEoTUksIERlbHRhLCBDcml0aWNhbFBTZXRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXhQcmVzc3VyZUxpbWl0KTsKKworICAgIGFzc2VydChpc0JvdHRvbUNsb3NlZCgpICYmICJVbmluaXRpYWxpemVkIHByZXNzdXJlIHRyYWNrZXIiKTsKKyAgICByZXR1cm4gZ2V0TWF4VXB3YXJkUHJlc3N1cmVEZWx0YShNSSwgbnVsbHB0ciwgRGVsdGEsIENyaXRpY2FsUFNldHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF4UHJlc3N1cmVMaW1pdCk7CisgIH0KKworICAvLy8gR2V0IHRoZSBwcmVzc3VyZSBvZiBlYWNoIFBTZXQgYWZ0ZXIgdHJhdmVyc2luZyB0aGlzIGluc3RydWN0aW9uIGJvdHRvbS11cC4KKyAgdm9pZCBnZXRVcHdhcmRQcmVzc3VyZShjb25zdCBNYWNoaW5lSW5zdHIgKk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPHVuc2lnbmVkPiAmUHJlc3N1cmVSZXN1bHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8dW5zaWduZWQ+ICZNYXhQcmVzc3VyZVJlc3VsdCk7CisKKyAgLy8vIEdldCB0aGUgcHJlc3N1cmUgb2YgZWFjaCBQU2V0IGFmdGVyIHRyYXZlcnNpbmcgdGhpcyBpbnN0cnVjdGlvbiB0b3AtZG93bi4KKyAgdm9pZCBnZXREb3dud2FyZFByZXNzdXJlKGNvbnN0IE1hY2hpbmVJbnN0ciAqTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnZlY3Rvcjx1bnNpZ25lZD4gJlByZXNzdXJlUmVzdWx0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8dW5zaWduZWQ+ICZNYXhQcmVzc3VyZVJlc3VsdCk7CisKKyAgdm9pZCBnZXRQcmVzc3VyZUFmdGVySW5zdChjb25zdCBNYWNoaW5lSW5zdHIgKk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPHVuc2lnbmVkPiAmUHJlc3N1cmVSZXN1bHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8dW5zaWduZWQ+ICZNYXhQcmVzc3VyZVJlc3VsdCkgeworICAgIGlmIChpc1RvcENsb3NlZCgpKQorICAgICAgcmV0dXJuIGdldFVwd2FyZFByZXNzdXJlKE1JLCBQcmVzc3VyZVJlc3VsdCwgTWF4UHJlc3N1cmVSZXN1bHQpOworCisgICAgYXNzZXJ0KGlzQm90dG9tQ2xvc2VkKCkgJiYgIlVuaW5pdGlhbGl6ZWQgcHJlc3N1cmUgdHJhY2tlciIpOworICAgIHJldHVybiBnZXREb3dud2FyZFByZXNzdXJlKE1JLCBQcmVzc3VyZVJlc3VsdCwgTWF4UHJlc3N1cmVSZXN1bHQpOworICB9CisKKyAgYm9vbCBoYXNVbnRpZWREZWYodW5zaWduZWQgVmlydFJlZykgY29uc3QgeworICAgIHJldHVybiBVbnRpZWREZWZzLmNvdW50KFZpcnRSZWcpOworICB9CisKKyAgdm9pZCBkdW1wKCkgY29uc3Q7CisKK3Byb3RlY3RlZDoKKyAgLy8vIEFkZCBSZWcgdG8gdGhlIGxpdmUgb3V0IHNldCBhbmQgaW5jcmVhc2UgbWF4IHByZXNzdXJlLgorICB2b2lkIGRpc2NvdmVyTGl2ZU91dChSZWdpc3Rlck1hc2tQYWlyIFBhaXIpOworICAvLy8gQWRkIFJlZyB0byB0aGUgbGl2ZSBpbiBzZXQgYW5kIGluY3JlYXNlIG1heCBwcmVzc3VyZS4KKyAgdm9pZCBkaXNjb3ZlckxpdmVJbihSZWdpc3Rlck1hc2tQYWlyIFBhaXIpOworCisgIC8vLyBcYnJpZWYgR2V0IHRoZSBTbG90SW5kZXggZm9yIHRoZSBmaXJzdCBub25kZWJ1ZyBpbnN0cnVjdGlvbiBpbmNsdWRpbmcgb3IKKyAgLy8vIGFmdGVyIHRoZSBjdXJyZW50IHBvc2l0aW9uLgorICBTbG90SW5kZXggZ2V0Q3VyclNsb3QoKSBjb25zdDsKKworICB2b2lkIGluY3JlYXNlUmVnUHJlc3N1cmUodW5zaWduZWQgUmVnVW5pdCwgTGFuZUJpdG1hc2sgUHJldmlvdXNNYXNrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgTGFuZUJpdG1hc2sgTmV3TWFzayk7CisgIHZvaWQgZGVjcmVhc2VSZWdQcmVzc3VyZSh1bnNpZ25lZCBSZWdVbml0LCBMYW5lQml0bWFzayBQcmV2aW91c01hc2ssCisgICAgICAgICAgICAgICAgICAgICAgICAgICBMYW5lQml0bWFzayBOZXdNYXNrKTsKKworICB2b2lkIGJ1bXBEZWFkRGVmcyhBcnJheVJlZjxSZWdpc3Rlck1hc2tQYWlyPiBEZWFkRGVmcyk7CisKKyAgdm9pZCBidW1wVXB3YXJkUHJlc3N1cmUoY29uc3QgTWFjaGluZUluc3RyICpNSSk7CisgIHZvaWQgYnVtcERvd253YXJkUHJlc3N1cmUoY29uc3QgTWFjaGluZUluc3RyICpNSSk7CisKKyAgdm9pZCBkaXNjb3ZlckxpdmVJbk9yT3V0KFJlZ2lzdGVyTWFza1BhaXIgUGFpciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxSZWdpc3Rlck1hc2tQYWlyPiAmTGl2ZUluT3JPdXQpOworCisgIExhbmVCaXRtYXNrIGdldExhc3RVc2VkTGFuZXModW5zaWduZWQgUmVnVW5pdCwgU2xvdEluZGV4IFBvcykgY29uc3Q7CisgIExhbmVCaXRtYXNrIGdldExpdmVMYW5lc0F0KHVuc2lnbmVkIFJlZ1VuaXQsIFNsb3RJbmRleCBQb3MpIGNvbnN0OworICBMYW5lQml0bWFzayBnZXRMaXZlVGhyb3VnaEF0KHVuc2lnbmVkIFJlZ1VuaXQsIFNsb3RJbmRleCBQb3MpIGNvbnN0OworfTsKKwordm9pZCBkdW1wUmVnU2V0UHJlc3N1cmUoQXJyYXlSZWY8dW5zaWduZWQ+IFNldFByZXNzdXJlLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkpOworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1JFR0lTVEVSUFJFU1NVUkVfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1JlZ2lzdGVyU2NhdmVuZ2luZy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1JlZ2lzdGVyU2NhdmVuZ2luZy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ4OWM3MmIKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUmVnaXN0ZXJTY2F2ZW5naW5nLmgKQEAgLTAsMCArMSwyMzEgQEAKKy8vPT09LSBSZWdpc3RlclNjYXZlbmdpbmcuaCAtIE1hY2hpbmUgcmVnaXN0ZXIgc2NhdmVuZ2luZyAtLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8vIFxmaWxlCisvLy8gVGhpcyBmaWxlIGRlY2xhcmVzIHRoZSBtYWNoaW5lIHJlZ2lzdGVyIHNjYXZlbmdlciBjbGFzcy4gSXQgY2FuIHByb3ZpZGUKKy8vLyBpbmZvcm1hdGlvbiBzdWNoIGFzIHVudXNlZCByZWdpc3RlciBhdCBhbnkgcG9pbnQgaW4gYSBtYWNoaW5lIGJhc2ljIGJsb2NrLgorLy8vIEl0IGFsc28gcHJvdmlkZXMgYSBtZWNoYW5pc20gdG8gbWFrZSByZWdpc3RlcnMgYXZhaWxhYmxlIGJ5IGV2aWN0aW5nIHRoZW0KKy8vLyB0byBzcGlsbCBzbG90cy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9SRUdJU1RFUlNDQVZFTkdJTkdfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fUkVHSVNURVJTQ0FWRU5HSU5HX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0JpdFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0xpdmVSZWdVbml0cy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lQmFzaWNCbG9jay5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lUmVnaXN0ZXJJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9NQy9MYW5lQml0bWFzay5oIgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIE1hY2hpbmVJbnN0cjsKK2NsYXNzIFRhcmdldEluc3RySW5mbzsKK2NsYXNzIFRhcmdldFJlZ2lzdGVyQ2xhc3M7CitjbGFzcyBUYXJnZXRSZWdpc3RlckluZm87CisKK2NsYXNzIFJlZ1NjYXZlbmdlciB7CisgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJOworICBjb25zdCBUYXJnZXRJbnN0ckluZm8gKlRJSTsKKyAgTWFjaGluZVJlZ2lzdGVySW5mbyogTVJJOworICBNYWNoaW5lQmFzaWNCbG9jayAqTUJCID0gbnVsbHB0cjsKKyAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIE1CQkk7CisgIHVuc2lnbmVkIE51bVJlZ1VuaXRzID0gMDsKKworICAvLy8gVHJ1ZSBpZiBSZWdTY2F2ZW5nZXIgaXMgY3VycmVudGx5IHRyYWNraW5nIHRoZSBsaXZlbmVzcyBvZiByZWdpc3RlcnMuCisgIGJvb2wgVHJhY2tpbmcgPSBmYWxzZTsKKworICAvLy8gSW5mb3JtYXRpb24gb24gc2NhdmVuZ2VkIHJlZ2lzdGVycyAoaGVsZCBpbiBhIHNwaWxsIHNsb3QpLgorICBzdHJ1Y3QgU2NhdmVuZ2VkSW5mbyB7CisgICAgU2NhdmVuZ2VkSW5mbyhpbnQgRkkgPSAtMSkgOiBGcmFtZUluZGV4KEZJKSB7fQorCisgICAgLy8vIEEgc3BpbGwgc2xvdCB1c2VkIGZvciBzY2F2ZW5naW5nIGEgcmVnaXN0ZXIgcG9zdCByZWdpc3RlciBhbGxvY2F0aW9uLgorICAgIGludCBGcmFtZUluZGV4OworCisgICAgLy8vIElmIG5vbi16ZXJvLCB0aGUgc3BlY2lmaWMgcmVnaXN0ZXIgaXMgY3VycmVudGx5IGJlaW5nCisgICAgLy8vIHNjYXZlbmdlZC4gVGhhdCBpcywgaXQgaXMgc3BpbGxlZCB0byB0aGlzIHNjYXZlbmdpbmcgc3RhY2sgc2xvdC4KKyAgICB1bnNpZ25lZCBSZWcgPSAwOworCisgICAgLy8vIFRoZSBpbnN0cnVjdGlvbiB0aGF0IHJlc3RvcmVzIHRoZSBzY2F2ZW5nZWQgcmVnaXN0ZXIgZnJvbSBzdGFjay4KKyAgICBjb25zdCBNYWNoaW5lSW5zdHIgKlJlc3RvcmUgPSBudWxscHRyOworICB9OworCisgIC8vLyBBIHZlY3RvciBvZiBpbmZvcm1hdGlvbiBvbiBzY2F2ZW5nZWQgcmVnaXN0ZXJzLgorICBTbWFsbFZlY3RvcjxTY2F2ZW5nZWRJbmZvLCAyPiBTY2F2ZW5nZWQ7CisKKyAgTGl2ZVJlZ1VuaXRzIExpdmVVbml0czsKKworICAvLyBUaGVzZSBCaXRWZWN0b3JzIGFyZSBvbmx5IHVzZWQgaW50ZXJuYWxseSB0byBmb3J3YXJkKCkuIFRoZXkgYXJlIG1lbWJlcnMKKyAgLy8gdG8gYXZvaWQgZnJlcXVlbnQgcmVhbGxvY2F0aW9ucy4KKyAgQml0VmVjdG9yIEtpbGxSZWdVbml0cywgRGVmUmVnVW5pdHM7CisgIEJpdFZlY3RvciBUbXBSZWdVbml0czsKKworcHVibGljOgorICBSZWdTY2F2ZW5nZXIoKSA9IGRlZmF1bHQ7CisKKyAgLy8vIFN0YXJ0IHRyYWNraW5nIGxpdmVuZXNzIGZyb20gdGhlIGJlZ2luIG9mIGJhc2ljIGJsb2NrIFxwIE1CQi4KKyAgdm9pZCBlbnRlckJhc2ljQmxvY2soTWFjaGluZUJhc2ljQmxvY2sgJk1CQik7CisKKyAgLy8vIFN0YXJ0IHRyYWNraW5nIGxpdmVuZXNzIGZyb20gdGhlIGVuZCBvZiBiYXNpYyBibG9jayBccCBNQkIuCisgIC8vLyBVc2UgYmFja3dhcmQoKSB0byBtb3ZlIHRvd2FyZHMgdGhlIGJlZ2lubmluZyBvZiB0aGUgYmxvY2suIFRoaXMgaXMKKyAgLy8vIHByZWZlcnJlZCB0byBlbnRlckJhc2ljQmxvY2soKSBhbmQgZm9yd2FyZCgpIGJlY2F1c2UgaXQgZG9lcyBub3QgZGVwZW5kCisgIC8vLyBvbiB0aGUgcHJlc2VuY2Ugb2Yga2lsbCBmbGFncy4KKyAgdm9pZCBlbnRlckJhc2ljQmxvY2tFbmQoTWFjaGluZUJhc2ljQmxvY2sgJk1CQik7CisKKyAgLy8vIE1vdmUgdGhlIGludGVybmFsIE1CQiBpdGVyYXRvciBhbmQgdXBkYXRlIHJlZ2lzdGVyIHN0YXRlcy4KKyAgdm9pZCBmb3J3YXJkKCk7CisKKyAgLy8vIE1vdmUgdGhlIGludGVybmFsIE1CQiBpdGVyYXRvciBhbmQgdXBkYXRlIHJlZ2lzdGVyIHN0YXRlcyB1bnRpbAorICAvLy8gaXQgaGFzIHByb2Nlc3NlZCB0aGUgc3BlY2lmaWMgaXRlcmF0b3IuCisgIHZvaWQgZm9yd2FyZChNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgSSkgeworICAgIGlmICghVHJhY2tpbmcgJiYgTUJCLT5iZWdpbigpICE9IEkpIGZvcndhcmQoKTsKKyAgICB3aGlsZSAoTUJCSSAhPSBJKSBmb3J3YXJkKCk7CisgIH0KKworICAvLy8gSW52ZXJ0IHRoZSBiZWhhdmlvciBvZiBmb3J3YXJkKCkgb24gdGhlIGN1cnJlbnQgaW5zdHJ1Y3Rpb24gKHVuZG8gdGhlCisgIC8vLyBjaGFuZ2VzIHRvIHRoZSBhdmFpbGFibGUgcmVnaXN0ZXJzIG1hZGUgYnkgZm9yd2FyZCgpKS4KKyAgdm9pZCB1bnByb2Nlc3MoKTsKKworICAvLy8gVW5wcm9jZXNzIGluc3RydWN0aW9ucyB1bnRpbCB5b3UgcmVhY2ggdGhlIHByb3ZpZGVkIGl0ZXJhdG9yLgorICB2b2lkIHVucHJvY2VzcyhNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgSSkgeworICAgIHdoaWxlIChNQkJJICE9IEkpIHVucHJvY2VzcygpOworICB9CisKKyAgLy8vIFVwZGF0ZSBpbnRlcm5hbCByZWdpc3RlciBzdGF0ZSBhbmQgbW92ZSBNQkIgaXRlcmF0b3IgYmFja3dhcmRzLgorICAvLy8gQ29udHJhcnkgdG8gdW5wcm9jZXNzKCkgdGhpcyBtZXRob2QgZ2l2ZXMgcHJlY2lzZSByZXN1bHRzIGV2ZW4gaW4gdGhlCisgIC8vLyBhYnNlbmNlIG9mIGtpbGwgZmxhZ3MuCisgIHZvaWQgYmFja3dhcmQoKTsKKworICAvLy8gQ2FsbCBiYWNrd2FyZCgpIGFzIGxvbmcgYXMgdGhlIGludGVybmFsIGl0ZXJhdG9yIGRvZXMgbm90IHBvaW50IHRvIFxwIEkuCisgIHZvaWQgYmFja3dhcmQoTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEkpIHsKKyAgICB3aGlsZSAoTUJCSSAhPSBJKQorICAgICAgYmFja3dhcmQoKTsKKyAgfQorCisgIC8vLyBNb3ZlIHRoZSBpbnRlcm5hbCBNQkIgaXRlcmF0b3IgYnV0IGRvIG5vdCB1cGRhdGUgcmVnaXN0ZXIgc3RhdGVzLgorICB2b2lkIHNraXBUbyhNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgSSkgeworICAgIGlmIChJID09IE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvcihudWxscHRyKSkKKyAgICAgIFRyYWNraW5nID0gZmFsc2U7CisgICAgTUJCSSA9IEk7CisgIH0KKworICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgZ2V0Q3VycmVudFBvc2l0aW9uKCkgY29uc3QgeyByZXR1cm4gTUJCSTsgfQorCisgIC8vLyBSZXR1cm4gaWYgYSBzcGVjaWZpYyByZWdpc3RlciBpcyBjdXJyZW50bHkgdXNlZC4KKyAgYm9vbCBpc1JlZ1VzZWQodW5zaWduZWQgUmVnLCBib29sIGluY2x1ZGVSZXNlcnZlZCA9IHRydWUpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gYWxsIGF2YWlsYWJsZSByZWdpc3RlcnMgaW4gdGhlIHJlZ2lzdGVyIGNsYXNzIGluIE1hc2suCisgIEJpdFZlY3RvciBnZXRSZWdzQXZhaWxhYmxlKGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKTsKKworICAvLy8gRmluZCBhbiB1bnVzZWQgcmVnaXN0ZXIgb2YgdGhlIHNwZWNpZmllZCByZWdpc3RlciBjbGFzcy4KKyAgLy8vIFJldHVybiAwIGlmIG5vbmUgaXMgZm91bmQuCisgIHVuc2lnbmVkIEZpbmRVbnVzZWRSZWcoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUmVnQ2xhc3MpIGNvbnN0OworCisgIC8vLyBBZGQgYSBzY2F2ZW5naW5nIGZyYW1lIGluZGV4LgorICB2b2lkIGFkZFNjYXZlbmdpbmdGcmFtZUluZGV4KGludCBGSSkgeworICAgIFNjYXZlbmdlZC5wdXNoX2JhY2soU2NhdmVuZ2VkSW5mbyhGSSkpOworICB9CisKKyAgLy8vIFF1ZXJ5IHdoZXRoZXIgYSBmcmFtZSBpbmRleCBpcyBhIHNjYXZlbmdpbmcgZnJhbWUgaW5kZXguCisgIGJvb2wgaXNTY2F2ZW5naW5nRnJhbWVJbmRleChpbnQgRkkpIGNvbnN0IHsKKyAgICBmb3IgKFNtYWxsVmVjdG9ySW1wbDxTY2F2ZW5nZWRJbmZvPjo6Y29uc3RfaXRlcmF0b3IgSSA9IFNjYXZlbmdlZC5iZWdpbigpLAorICAgICAgICAgSUUgPSBTY2F2ZW5nZWQuZW5kKCk7IEkgIT0gSUU7ICsrSSkKKyAgICAgIGlmIChJLT5GcmFtZUluZGV4ID09IEZJKQorICAgICAgICByZXR1cm4gdHJ1ZTsKKworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBHZXQgYW4gYXJyYXkgb2Ygc2NhdmVuZ2luZyBmcmFtZSBpbmRpY2VzLgorICB2b2lkIGdldFNjYXZlbmdpbmdGcmFtZUluZGljZXMoU21hbGxWZWN0b3JJbXBsPGludD4gJkEpIGNvbnN0IHsKKyAgICBmb3IgKFNtYWxsVmVjdG9ySW1wbDxTY2F2ZW5nZWRJbmZvPjo6Y29uc3RfaXRlcmF0b3IgSSA9IFNjYXZlbmdlZC5iZWdpbigpLAorICAgICAgICAgSUUgPSBTY2F2ZW5nZWQuZW5kKCk7IEkgIT0gSUU7ICsrSSkKKyAgICAgIGlmIChJLT5GcmFtZUluZGV4ID49IDApCisgICAgICAgIEEucHVzaF9iYWNrKEktPkZyYW1lSW5kZXgpOworICB9CisKKyAgLy8vIE1ha2UgYSByZWdpc3RlciBvZiB0aGUgc3BlY2lmaWMgcmVnaXN0ZXIgY2xhc3MKKyAgLy8vIGF2YWlsYWJsZSBhbmQgZG8gdGhlIGFwcHJvcHJpYXRlIGJvb2trZWVwaW5nLiBTUEFkaiBpcyB0aGUgc3RhY2sKKyAgLy8vIGFkanVzdG1lbnQgZHVlIHRvIGNhbGwgZnJhbWUsIGl0J3MgcGFzc2VkIGFsb25nIHRvIGVsaW1pbmF0ZUZyYW1lSW5kZXgoKS4KKyAgLy8vIFJldHVybnMgdGhlIHNjYXZlbmdlZCByZWdpc3Rlci4KKyAgLy8vIFRoaXMgaXMgZGVwcmVjYXRlZCBhcyBpdCBkZXBlbmRzIG9uIHRoZSBxdWFsaXR5IG9mIHRoZSBraWxsIGZsYWdzIGJlaW5nCisgIC8vLyBwcmVzZW50OyBVc2Ugc2NhdmVuZ2VSZWdpc3RlckJhY2t3YXJkcygpIGluc3RlYWQhCisgIHVuc2lnbmVkIHNjYXZlbmdlUmVnaXN0ZXIoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUmVnQ2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEksIGludCBTUEFkaik7CisgIHVuc2lnbmVkIHNjYXZlbmdlUmVnaXN0ZXIoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUmVnQ2xhc3MsIGludCBTUEFkaikgeworICAgIHJldHVybiBzY2F2ZW5nZVJlZ2lzdGVyKFJlZ0NsYXNzLCBNQkJJLCBTUEFkaik7CisgIH0KKworICAvLy8gTWFrZSBhIHJlZ2lzdGVyIG9mIHRoZSBzcGVjaWZpYyByZWdpc3RlciBjbGFzcyBhdmFpbGFibGUgZnJvbSB0aGUgY3VycmVudAorICAvLy8gcG9zaXRpb24gYmFja3dhcmRzIHRvIHRoZSBwbGFjZSBiZWZvcmUgXHAgVG8uIElmIFxwIFJlc3RvcmVBZnRlciBpcyB0cnVlCisgIC8vLyB0aGlzIGluY2x1ZGVzIHRoZSBpbnN0cnVjdGlvbiBmb2xsb3dpbmcgdGhlIGN1cnJlbnQgcG9zaXRpb24uCisgIC8vLyBTUEFkaiBpcyB0aGUgc3RhY2sgYWRqdXN0bWVudCBkdWUgdG8gY2FsbCBmcmFtZSwgaXQncyBwYXNzZWQgYWxvbmcgdG8KKyAgLy8vIGVsaW1pbmF0ZUZyYW1lSW5kZXgoKS4KKyAgLy8vIFJldHVybnMgdGhlIHNjYXZlbmdlZCByZWdpc3Rlci4KKyAgdW5zaWduZWQgc2NhdmVuZ2VSZWdpc3RlckJhY2t3YXJkcyhjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICZSQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgVG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBSZXN0b3JlQWZ0ZXIsIGludCBTUEFkaik7CisKKyAgLy8vIFRlbGwgdGhlIHNjYXZlbmdlciBhIHJlZ2lzdGVyIGlzIHVzZWQuCisgIHZvaWQgc2V0UmVnVXNlZCh1bnNpZ25lZCBSZWcsIExhbmVCaXRtYXNrIExhbmVNYXNrID0gTGFuZUJpdG1hc2s6OmdldEFsbCgpKTsKKworcHJpdmF0ZToKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiBhIHJlZ2lzdGVyIGlzIHJlc2VydmVkLiBJdCBpcyBuZXZlciAidW51c2VkIi4KKyAgYm9vbCBpc1Jlc2VydmVkKHVuc2lnbmVkIFJlZykgY29uc3QgeyByZXR1cm4gTVJJLT5pc1Jlc2VydmVkKFJlZyk7IH0KKworICAvLy8gc2V0VXNlZCAvIHNldFVudXNlZCAtIE1hcmsgdGhlIHN0YXRlIG9mIG9uZSBvciBhIG51bWJlciBvZiByZWdpc3RlciB1bml0cy4KKyAgLy8vCisgIHZvaWQgc2V0VXNlZChjb25zdCBCaXRWZWN0b3IgJlJlZ1VuaXRzKSB7CisgICAgTGl2ZVVuaXRzLmFkZFVuaXRzKFJlZ1VuaXRzKTsKKyAgfQorICB2b2lkIHNldFVudXNlZChjb25zdCBCaXRWZWN0b3IgJlJlZ1VuaXRzKSB7CisgICAgTGl2ZVVuaXRzLnJlbW92ZVVuaXRzKFJlZ1VuaXRzKTsKKyAgfQorCisgIC8vLyBQcm9jZXNzZXMgdGhlIGN1cnJlbnQgaW5zdHJ1Y3Rpb24gYW5kIGZpbGwgdGhlIEtpbGxSZWdVbml0cyBhbmQKKyAgLy8vIERlZlJlZ1VuaXRzIGJpdCB2ZWN0b3JzLgorICB2b2lkIGRldGVybWluZUtpbGxzQW5kRGVmcygpOworCisgIC8vLyBBZGQgYWxsIFJlZyBVbml0cyB0aGF0IFJlZyBjb250YWlucyB0byBCVi4KKyAgdm9pZCBhZGRSZWdVbml0cyhCaXRWZWN0b3IgJkJWLCB1bnNpZ25lZCBSZWcpOworCisgIC8vLyBSZW1vdmUgYWxsIFJlZyBVbml0cyB0aGF0IFxwIFJlZyBjb250YWlucyBmcm9tIFxwIEJWLgorICB2b2lkIHJlbW92ZVJlZ1VuaXRzKEJpdFZlY3RvciAmQlYsIHVuc2lnbmVkIFJlZyk7CisKKyAgLy8vIFJldHVybiB0aGUgY2FuZGlkYXRlIHJlZ2lzdGVyIHRoYXQgaXMgdW51c2VkIGZvciB0aGUgbG9uZ2VzdCBhZnRlcgorICAvLy8gU3RhcnRNSS4gVXNlTUkgaXMgc2V0IHRvIHRoZSBpbnN0cnVjdGlvbiB3aGVyZSB0aGUgc2VhcmNoIHN0b3BwZWQuCisgIC8vLworICAvLy8gTm8gbW9yZSB0aGFuIEluc3RyTGltaXQgaW5zdHJ1Y3Rpb25zIGFyZSBpbnNwZWN0ZWQuCisgIHVuc2lnbmVkIGZpbmRTdXJ2aXZvclJlZyhNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgU3RhcnRNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpdFZlY3RvciAmQ2FuZGlkYXRlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIEluc3RyTGltaXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgJlVzZU1JKTsKKworICAvLy8gSW5pdGlhbGl6ZSBSZWdpc3RlclNjYXZlbmdlci4KKyAgdm9pZCBpbml0KE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIpOworCisgIC8vLyBNYXJrIGxpdmUtaW4gcmVnaXN0ZXJzIG9mIGJhc2ljIGJsb2NrIGFzIHVzZWQuCisgIHZvaWQgc2V0TGl2ZUluc1VzZWQoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgJk1CQik7CisKKyAgLy8vIFNwaWxsIGEgcmVnaXN0ZXIgYWZ0ZXIgcG9zaXRpb24gXHAgQWZ0ZXIgYW5kIHJlbG9hZCBpdCBiZWZvcmUgcG9zaXRpb24KKyAgLy8vIFxwIFVzZU1JLgorICBTY2F2ZW5nZWRJbmZvICZzcGlsbCh1bnNpZ25lZCBSZWcsIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgJlJDLCBpbnQgU1BBZGosCisgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBBZnRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yICZVc2VNSSk7Cit9OworCisvLy8gUmVwbGFjZXMgYWxsIGZyYW1lIGluZGV4IHZpcnR1YWwgcmVnaXN0ZXJzIHdpdGggcGh5c2ljYWwgcmVnaXN0ZXJzLiBVc2VzIHRoZQorLy8vIHJlZ2lzdGVyIHNjYXZlbmdlciB0byBmaW5kIGFuIGFwcHJvcHJpYXRlIHJlZ2lzdGVyIHRvIHVzZS4KK3ZvaWQgc2NhdmVuZ2VGcmFtZVZpcnR1YWxSZWdzKE1hY2hpbmVGdW5jdGlvbiAmTUYsIFJlZ1NjYXZlbmdlciAmUlMpOworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1JFR0lTVEVSU0NBVkVOR0lOR19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUmVnaXN0ZXJVc2FnZUluZm8uaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SZWdpc3RlclVzYWdlSW5mby5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhYmFkZDgKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUmVnaXN0ZXJVc2FnZUluZm8uaApAQCAtMCwwICsxLDc3IEBACisvLz09LSBSZWdpc3RlclVzYWdlSW5mby5oIC0gUmVnaXN0ZXIgVXNhZ2UgSW5mb3JtYXJ0aW9uIFN0b3JhZ2UgLS0qLSBDKysgLSotPT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vIFxmaWxlCisvLy8gVGhpcyBwYXNzIGlzIHJlcXVpcmVkIHRvIHRha2UgYWR2YW50YWdlIG9mIHRoZSBpbnRlcnByb2NlZHVyYWwgcmVnaXN0ZXIKKy8vLyBhbGxvY2F0aW9uIGluZnJhc3RydWN0dXJlLgorLy8vCisvLy8gVGhpcyBwYXNzIGlzIHNpbXBsZSBpbW11dGFibGUgcGFzcyB3aGljaCBrZWVwcyBSZWdNYXNrcyAoY2FsY3VsYXRlZCBiYXNlZCBvbgorLy8vIGFjdHVhbCByZWdpc3RlciBhbGxvY2F0aW9uKSBmb3IgZnVuY3Rpb25zIGluIGEgbW9kdWxlIGFuZCBwcm92aWRlcyBzaW1wbGUKKy8vLyBBUEkgdG8gcXVlcnkgdGhpcyBpbmZvcm1hdGlvbi4KKy8vLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fUEhZU0lDQUxSRUdJU1RFUlVTQUdFSU5GT19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9QSFlTSUNBTFJFR0lTVEVSVVNBR0VJTkZPX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9JUi9JbnN0cnVjdGlvbnMuaCIKKyNpbmNsdWRlICJsbHZtL1Bhc3MuaCIKKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBGdW5jdGlvbjsKK2NsYXNzIFRhcmdldE1hY2hpbmU7CisKK2NsYXNzIFBoeXNpY2FsUmVnaXN0ZXJVc2FnZUluZm8gOiBwdWJsaWMgSW1tdXRhYmxlUGFzcyB7CisgIHZpcnR1YWwgdm9pZCBhbmNob3IoKTsKKworcHVibGljOgorICBzdGF0aWMgY2hhciBJRDsKKworICBQaHlzaWNhbFJlZ2lzdGVyVXNhZ2VJbmZvKCkgOiBJbW11dGFibGVQYXNzKElEKSB7CisgICAgUGFzc1JlZ2lzdHJ5ICZSZWdpc3RyeSA9ICpQYXNzUmVnaXN0cnk6OmdldFBhc3NSZWdpc3RyeSgpOworICAgIGluaXRpYWxpemVQaHlzaWNhbFJlZ2lzdGVyVXNhZ2VJbmZvUGFzcyhSZWdpc3RyeSk7CisgIH0KKworICB2b2lkIGdldEFuYWx5c2lzVXNhZ2UoQW5hbHlzaXNVc2FnZSAmQVUpIGNvbnN0IG92ZXJyaWRlIHsKKyAgICBBVS5zZXRQcmVzZXJ2ZXNBbGwoKTsKKyAgfQorCisgIC8vLyBUbyBzZXQgVGFyZ2V0TWFjaGluZSAqLCB3aGljaCBpcyB1c2VkIHRvIHByaW50CisgIC8vLyBhbmFseXNpcyB3aGVuIGNvbW1hbmQgbGluZSBvcHRpb24gLXByaW50LXJlZ3VzYWdlIGlzIHVzZWQuCisgIHZvaWQgc2V0VGFyZ2V0TWFjaGluZShjb25zdCBUYXJnZXRNYWNoaW5lICpUTV8pIHsgVE0gPSBUTV87IH0KKworICBib29sIGRvSW5pdGlhbGl6YXRpb24oTW9kdWxlICZNKSBvdmVycmlkZTsKKworICBib29sIGRvRmluYWxpemF0aW9uKE1vZHVsZSAmTSkgb3ZlcnJpZGU7CisKKyAgLy8vIFRvIHN0b3JlIFJlZ01hc2sgZm9yIGdpdmVuIEZ1bmN0aW9uICouCisgIHZvaWQgc3RvcmVVcGRhdGVSZWdVc2FnZUluZm8oY29uc3QgRnVuY3Rpb24gKkZQLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPHVpbnQzMl90PiBSZWdNYXNrKTsKKworICAvLy8gVG8gcXVlcnkgc3RvcmVkIFJlZ01hc2sgZm9yIGdpdmVuIEZ1bmN0aW9uICosIGl0IHdpbGwgcmV0dXJuIG51bGxwdHIgaWYKKyAgLy8vIGZ1bmN0aW9uIGlzIG5vdCBrbm93bi4KKyAgY29uc3Qgc3RkOjp2ZWN0b3I8dWludDMyX3Q+ICpnZXRSZWdVc2FnZUluZm8oY29uc3QgRnVuY3Rpb24gKkZQKTsKKworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUywgY29uc3QgTW9kdWxlICpNID0gbnVsbHB0cikgY29uc3Qgb3ZlcnJpZGU7CisKK3ByaXZhdGU6CisgIC8vLyBBIERlbnNlIG1hcCBmcm9tIEZ1bmN0aW9uICogdG8gUmVnTWFzay4KKyAgLy8vIEluIFJlZ01hc2sgMCBtZWFucyByZWdpc3RlciB1c2VkIChjbG9iYmVyZWQpIGJ5IGZ1bmN0aW9uLgorICAvLy8gYW5kIDEgbWVhbnMgY29udGVudCBvZiByZWdpc3RlciB3aWxsIGJlIHByZXNlcnZlZCBhcm91bmQgZnVuY3Rpb24gY2FsbC4KKyAgRGVuc2VNYXA8Y29uc3QgRnVuY3Rpb24gKiwgc3RkOjp2ZWN0b3I8dWludDMyX3Q+PiBSZWdNYXNrczsKKworICBjb25zdCBUYXJnZXRNYWNoaW5lICpUTTsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fUEhZU0lDQUxSRUdJU1RFUlVTQUdFSU5GT19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUmVzb3VyY2VQcmlvcml0eVF1ZXVlLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUmVzb3VyY2VQcmlvcml0eVF1ZXVlLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDMxNjZjYwotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SZXNvdXJjZVByaW9yaXR5UXVldWUuaApAQCAtMCwwICsxLDEzNiBAQAorLy89PT0tLS0tLSBSZXNvdXJjZVByaW9yaXR5UXVldWUuaCAtIEEgREZBLW9yaWVudGVkIHByaW9yaXR5IHF1ZXVlIC0tLS0tLS09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBpbXBsZW1lbnRzIHRoZSBSZXNvdXJjZVByaW9yaXR5UXVldWUgY2xhc3MsIHdoaWNoIGlzIGEKKy8vIFNjaGVkdWxpbmdQcmlvcml0eVF1ZXVlIHRoYXQgc2NoZWR1bGVzIHVzaW5nIERGQSBzdGF0ZSB0bworLy8gcmVkdWNlIHRoZSBsZW5ndGggb2YgdGhlIGNyaXRpY2FsIHBhdGggdGhyb3VnaCB0aGUgYmFzaWMgYmxvY2sKKy8vIG9uIFZMSVcgcGxhdGZvcm1zLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1JFU09VUkNFUFJJT1JJVFlRVUVVRV9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9SRVNPVVJDRVBSSU9SSVRZUVVFVUVfSAorCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0RGQVBhY2tldGl6ZXIuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2NoZWR1bGVEQUcuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2VsZWN0aW9uREFHSVNlbC5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9UYXJnZXRJbnN0ckluZm8uaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0UmVnaXN0ZXJJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9NQy9NQ0luc3RySXRpbmVyYXJpZXMuaCIKKworbmFtZXNwYWNlIGxsdm0geworICBjbGFzcyBSZXNvdXJjZVByaW9yaXR5UXVldWU7CisKKyAgLy8vIFNvcnRpbmcgZnVuY3Rpb25zIGZvciB0aGUgQXZhaWxhYmxlIHF1ZXVlLgorICBzdHJ1Y3QgcmVzb3VyY2Vfc29ydCB7CisgICAgUmVzb3VyY2VQcmlvcml0eVF1ZXVlICpQUTsKKyAgICBleHBsaWNpdCByZXNvdXJjZV9zb3J0KFJlc291cmNlUHJpb3JpdHlRdWV1ZSAqcHEpIDogUFEocHEpIHt9CisKKyAgICBib29sIG9wZXJhdG9yKCkoY29uc3QgU1VuaXQqIGxlZnQsIGNvbnN0IFNVbml0KiByaWdodCkgY29uc3Q7CisgIH07CisKKyAgY2xhc3MgUmVzb3VyY2VQcmlvcml0eVF1ZXVlIDogcHVibGljIFNjaGVkdWxpbmdQcmlvcml0eVF1ZXVlIHsKKyAgICAvLy8gU1VuaXRzIC0gVGhlIFNVbml0cyBmb3IgdGhlIGN1cnJlbnQgZ3JhcGguCisgICAgc3RkOjp2ZWN0b3I8U1VuaXQ+ICpTVW5pdHM7CisKKyAgICAvLy8gTnVtTm9kZXNTb2xlbHlCbG9ja2luZyAtIFRoaXMgdmVjdG9yIGNvbnRhaW5zLCBmb3IgZXZlcnkgbm9kZSBpbiB0aGUKKyAgICAvLy8gUXVldWUsIHRoZSBudW1iZXIgb2Ygbm9kZXMgdGhhdCB0aGUgbm9kZSBpcyB0aGUgc29sZSB1bnNjaGVkdWxlZAorICAgIC8vLyBwcmVkZWNlc3NvciBmb3IuICBUaGlzIGlzIHVzZWQgYXMgYSB0aWUtYnJlYWtlciBoZXVyaXN0aWMgZm9yIGJldHRlcgorICAgIC8vLyBtb2JpbGl0eS4KKyAgICBzdGQ6OnZlY3Rvcjx1bnNpZ25lZD4gTnVtTm9kZXNTb2xlbHlCbG9ja2luZzsKKworICAgIC8vLyBRdWV1ZSAtIFRoZSBxdWV1ZS4KKyAgICBzdGQ6OnZlY3RvcjxTVW5pdCo+IFF1ZXVlOworCisgICAgLy8vIFJlZ1ByZXNzdXJlIC0gVHJhY2tpbmcgY3VycmVudCByZWcgcHJlc3N1cmUgcGVyIHJlZ2lzdGVyIGNsYXNzLgorICAgIC8vLworICAgIHN0ZDo6dmVjdG9yPHVuc2lnbmVkPiBSZWdQcmVzc3VyZTsKKworICAgIC8vLyBSZWdMaW1pdCAtIFRyYWNraW5nIHRoZSBudW1iZXIgb2YgYWxsb2NhdGFibGUgcmVnaXN0ZXJzIHBlciByZWdpc3RlcgorICAgIC8vLyBjbGFzcy4KKyAgICBzdGQ6OnZlY3Rvcjx1bnNpZ25lZD4gUmVnTGltaXQ7CisKKyAgICByZXNvdXJjZV9zb3J0IFBpY2tlcjsKKyAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSTsKKyAgICBjb25zdCBUYXJnZXRMb3dlcmluZyAqVExJOworICAgIGNvbnN0IFRhcmdldEluc3RySW5mbyAqVElJOworICAgIGNvbnN0IEluc3RySXRpbmVyYXJ5RGF0YSogSW5zdHJJdGluczsKKyAgICAvLy8gUmVzb3VyY2VzTW9kZWwgLSBSZXByZXNlbnRzIFZMSVcgc3RhdGUuCisgICAgLy8vIE5vdCBsaW1pdGVkIHRvIFZMSVcgdGFyZ2V0cyBwZXIgc2F5LCBidXQgYXNzdW1lcworICAgIC8vLyBkZWZpbml0aW9uIG9mIERGQSBieSBhIHRhcmdldC4KKyAgICBzdGQ6OnVuaXF1ZV9wdHI8REZBUGFja2V0aXplcj4gUmVzb3VyY2VzTW9kZWw7CisKKyAgICAvLy8gUmVzb3VyY2UgbW9kZWwgLSBwYWNrZXQvYnVuZGxlIG1vZGVsLiBQdXJlbHkKKyAgICAvLy8gaW50ZXJuYWwgYXQgdGhlIHRpbWUuCisgICAgc3RkOjp2ZWN0b3I8U1VuaXQqPiBQYWNrZXQ7CisKKyAgICAvLy8gSGV1cmlzdGljcyBmb3IgZXN0aW1hdGluZyByZWdpc3RlciBwcmVzc3VyZS4KKyAgICB1bnNpZ25lZCBQYXJhbGxlbExpdmVSYW5nZXM7CisgICAgaW50IEhvcml6b250YWxWZXJ0aWNhbEJhbGFuY2U7CisKKyAgcHVibGljOgorICAgIFJlc291cmNlUHJpb3JpdHlRdWV1ZShTZWxlY3Rpb25EQUdJU2VsICpJUyk7CisKKyAgICBib29sIGlzQm90dG9tVXAoKSBjb25zdCBvdmVycmlkZSB7IHJldHVybiBmYWxzZTsgfQorCisgICAgdm9pZCBpbml0Tm9kZXMoc3RkOjp2ZWN0b3I8U1VuaXQ+ICZzdW5pdHMpIG92ZXJyaWRlOworCisgICAgdm9pZCBhZGROb2RlKGNvbnN0IFNVbml0ICpTVSkgb3ZlcnJpZGUgeworICAgICAgTnVtTm9kZXNTb2xlbHlCbG9ja2luZy5yZXNpemUoU1VuaXRzLT5zaXplKCksIDApOworICAgIH0KKworICAgIHZvaWQgdXBkYXRlTm9kZShjb25zdCBTVW5pdCAqU1UpIG92ZXJyaWRlIHt9CisKKyAgICB2b2lkIHJlbGVhc2VTdGF0ZSgpIG92ZXJyaWRlIHsKKyAgICAgIFNVbml0cyA9IG51bGxwdHI7CisgICAgfQorCisgICAgdW5zaWduZWQgZ2V0TGF0ZW5jeSh1bnNpZ25lZCBOb2RlTnVtKSBjb25zdCB7CisgICAgICBhc3NlcnQoTm9kZU51bSA8ICgqU1VuaXRzKS5zaXplKCkpOworICAgICAgcmV0dXJuICgqU1VuaXRzKVtOb2RlTnVtXS5nZXRIZWlnaHQoKTsKKyAgICB9CisKKyAgICB1bnNpZ25lZCBnZXROdW1Tb2xlbHlCbG9ja05vZGVzKHVuc2lnbmVkIE5vZGVOdW0pIGNvbnN0IHsKKyAgICAgIGFzc2VydChOb2RlTnVtIDwgTnVtTm9kZXNTb2xlbHlCbG9ja2luZy5zaXplKCkpOworICAgICAgcmV0dXJuIE51bU5vZGVzU29sZWx5QmxvY2tpbmdbTm9kZU51bV07CisgICAgfQorCisgICAgLy8vIFNpbmdsZSBjb3N0IGZ1bmN0aW9uIHJlZmxlY3RpbmcgYmVuZWZpdCBvZiBzY2hlZHVsaW5nIFNVCisgICAgLy8vIGluIHRoZSBjdXJyZW50IGN5Y2xlLgorICAgIGludCBTVVNjaGVkdWxpbmdDb3N0IChTVW5pdCAqU1UpOworCisgICAgLy8vIEluaXROdW1SZWdEZWZzTGVmdCAtIERldGVybWluZSB0aGUgIyBvZiByZWdzIGRlZmluZWQgYnkgdGhpcyBub2RlLgorICAgIC8vLworICAgIHZvaWQgaW5pdE51bVJlZ0RlZnNMZWZ0KFNVbml0ICpTVSk7CisgICAgdm9pZCB1cGRhdGVOdW1SZWdEZWZzTGVmdChTVW5pdCAqU1UpOworICAgIGludCByZWdQcmVzc3VyZURlbHRhKFNVbml0ICpTVSwgYm9vbCBSYXdQcmVzc3VyZSA9IGZhbHNlKTsKKyAgICBpbnQgcmF3UmVnUHJlc3N1cmVEZWx0YSAoU1VuaXQgKlNVLCB1bnNpZ25lZCBSQ0lkKTsKKworICAgIGJvb2wgZW1wdHkoKSBjb25zdCBvdmVycmlkZSB7IHJldHVybiBRdWV1ZS5lbXB0eSgpOyB9CisKKyAgICB2b2lkIHB1c2goU1VuaXQgKlUpIG92ZXJyaWRlOworCisgICAgU1VuaXQgKnBvcCgpIG92ZXJyaWRlOworCisgICAgdm9pZCByZW1vdmUoU1VuaXQgKlNVKSBvdmVycmlkZTsKKworICAgIC8vLyBzY2hlZHVsZWROb2RlIC0gTWFpbiByZXNvdXJjZSB0cmFja2luZyBwb2ludC4KKyAgICB2b2lkIHNjaGVkdWxlZE5vZGUoU1VuaXQgKk5vZGUpIG92ZXJyaWRlOworICAgIGJvb2wgaXNSZXNvdXJjZUF2YWlsYWJsZShTVW5pdCAqU1UpOworICAgIHZvaWQgcmVzZXJ2ZVJlc291cmNlcyhTVW5pdCAqU1UpOworCitwcml2YXRlOgorICAgIHZvaWQgYWRqdXN0UHJpb3JpdHlPZlVuc2NoZWR1bGVkUHJlZHMoU1VuaXQgKlNVKTsKKyAgICBTVW5pdCAqZ2V0U2luZ2xlVW5zY2hlZHVsZWRQcmVkKFNVbml0ICpTVSk7CisgICAgdW5zaWduZWQgbnVtYmVyUkNWYWxQcmVkSW5TVSAoU1VuaXQgKlNVLCB1bnNpZ25lZCBSQ0lkKTsKKyAgICB1bnNpZ25lZCBudW1iZXJSQ1ZhbFN1Y2NJblNVIChTVW5pdCAqU1UsIHVuc2lnbmVkIFJDSWQpOworICB9OworfQorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SdW50aW1lTGliY2FsbHMuZGVmIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1J1bnRpbWVMaWJjYWxscy5kZWYKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2VkOTBkOQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9SdW50aW1lTGliY2FsbHMuZGVmCkBAIC0wLDAgKzEsNTI3IEBACisvLz09PS0tIGxsdm0vUnVudGltZUxpYmNhbGxzLmRlZiAtIEZpbGUgdGhhdCBkZXNjcmliZXMgbGliY2FsbHMgLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZWZpbmVzIGFsbCBvZiB0aGUgcnVudGltZSBsaWJyYXJ5IGNhbGxzIHRoZSBiYWNrZW5kIGNhbiBlbWl0LgorLy8gVGhlIHZhcmlvdXMgbG9uZyBkb3VibGUgdHlwZXMgY2Fubm90IGJlIG1lcmdlZCwgYmVjYXVzZSA4MC1iaXQgbGlicmFyeQorLy8gZnVuY3Rpb25zIHVzZSAieGYiIGFuZCAxMjgtYml0IHVzZSAidGYiLgorLy8KKy8vIFdoZW4gYWRkaW5nIFBQQ0YxMjggZnVuY3Rpb25zIGhlcmUsIG5vdGUgdGhhdCB0aGVpciBuYW1lcyBnZW5lcmFsbHkgbmVlZAorLy8gdG8gYmUgb3ZlcnJpZGRlbiBmb3IgRGFyd2luIHdpdGggdGhlIHh4eCRMREJMMTI4IGZvcm0uICBTZWUKKy8vIFBQQ0lTZWxMb3dlcmluZy5jcHAuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworLy8gTk9URTogTk8gSU5DTFVERSBHVUFSRCBERVNJUkVEIQorCisvLyBQcm92aWRlIGRlZmluaXRpb25zIG9mIG1hY3JvcyBzbyB0aGF0IHVzZXJzIG9mIHRoaXMgZmlsZSBkbyBub3QgaGF2ZSB0bworLy8gZGVmaW5lIGV2ZXJ5dGhpbmcgdG8gdXNlIGl0Li4uCisKKy8vIERlY2xhcmUgdGhlIGVudW1lcmF0b3IgZm9yIGVhY2ggbGliY2FsbCwgYWxvbmcgd2l0aCBpdHMgZGVmYXVsdCBuYW1lLiBTb21lCisvLyBsaWJjYWxscyBoYXZlIGRpZmZlcmVudCBuYW1lcyBvbiBwYXJ0aWN1bGFyIE9TZXMgb3IgYXJjaGl0ZWN0dXJlcy4gVGhlc2UKKy8vIGFyZSBzZXQgaW4gSW5pdExpYmNhbGxOYW1lcygpIGluIFRhcmdldExvd2VyaW5nQmFzZS5jcHAgYW5kL29yIGJ5IHRhcmdldHMKKy8vIHVzaW5nIFRhcmdldExvd2VyaW5nQmFzZTo6c2V0TGliY2FsbE5hbWUoKQorI2lmbmRlZiBIQU5ETEVfTElCQ0FMTAorI2Vycm9yICJIQU5ETEVfTElCQ0FMTCBtdXN0IGJlIGRlZmluZWQiCisjZW5kaWYKKworLy8gSW50ZWdlcgorSEFORExFX0xJQkNBTEwoU0hMX0kxNiwgIl9fYXNobGhpMyIpCitIQU5ETEVfTElCQ0FMTChTSExfSTMyLCAiX19hc2hsc2kzIikKK0hBTkRMRV9MSUJDQUxMKFNITF9JNjQsICJfX2FzaGxkaTMiKQorSEFORExFX0xJQkNBTEwoU0hMX0kxMjgsICJfX2FzaGx0aTMiKQorSEFORExFX0xJQkNBTEwoU1JMX0kxNiwgIl9fbHNocmhpMyIpCitIQU5ETEVfTElCQ0FMTChTUkxfSTMyLCAiX19sc2hyc2kzIikKK0hBTkRMRV9MSUJDQUxMKFNSTF9JNjQsICJfX2xzaHJkaTMiKQorSEFORExFX0xJQkNBTEwoU1JMX0kxMjgsICJfX2xzaHJ0aTMiKQorSEFORExFX0xJQkNBTEwoU1JBX0kxNiwgIl9fYXNocmhpMyIpCitIQU5ETEVfTElCQ0FMTChTUkFfSTMyLCAiX19hc2hyc2kzIikKK0hBTkRMRV9MSUJDQUxMKFNSQV9JNjQsICJfX2FzaHJkaTMiKQorSEFORExFX0xJQkNBTEwoU1JBX0kxMjgsICJfX2FzaHJ0aTMiKQorSEFORExFX0xJQkNBTEwoTVVMX0k4LCAiX19tdWxxaTMiKQorSEFORExFX0xJQkNBTEwoTVVMX0kxNiwgIl9fbXVsaGkzIikKK0hBTkRMRV9MSUJDQUxMKE1VTF9JMzIsICJfX211bHNpMyIpCitIQU5ETEVfTElCQ0FMTChNVUxfSTY0LCAiX19tdWxkaTMiKQorSEFORExFX0xJQkNBTEwoTVVMX0kxMjgsICJfX211bHRpMyIpCitIQU5ETEVfTElCQ0FMTChNVUxPX0kzMiwgIl9fbXVsb3NpNCIpCitIQU5ETEVfTElCQ0FMTChNVUxPX0k2NCwgIl9fbXVsb2RpNCIpCitIQU5ETEVfTElCQ0FMTChNVUxPX0kxMjgsICJfX211bG90aTQiKQorSEFORExFX0xJQkNBTEwoU0RJVl9JOCwgIl9fZGl2cWkzIikKK0hBTkRMRV9MSUJDQUxMKFNESVZfSTE2LCAiX19kaXZoaTMiKQorSEFORExFX0xJQkNBTEwoU0RJVl9JMzIsICJfX2RpdnNpMyIpCitIQU5ETEVfTElCQ0FMTChTRElWX0k2NCwgIl9fZGl2ZGkzIikKK0hBTkRMRV9MSUJDQUxMKFNESVZfSTEyOCwgIl9fZGl2dGkzIikKK0hBTkRMRV9MSUJDQUxMKFVESVZfSTgsICJfX3VkaXZxaTMiKQorSEFORExFX0xJQkNBTEwoVURJVl9JMTYsICJfX3VkaXZoaTMiKQorSEFORExFX0xJQkNBTEwoVURJVl9JMzIsICJfX3VkaXZzaTMiKQorSEFORExFX0xJQkNBTEwoVURJVl9JNjQsICJfX3VkaXZkaTMiKQorSEFORExFX0xJQkNBTEwoVURJVl9JMTI4LCAiX191ZGl2dGkzIikKK0hBTkRMRV9MSUJDQUxMKFNSRU1fSTgsICJfX21vZHFpMyIpCitIQU5ETEVfTElCQ0FMTChTUkVNX0kxNiwgIl9fbW9kaGkzIikKK0hBTkRMRV9MSUJDQUxMKFNSRU1fSTMyLCAiX19tb2RzaTMiKQorSEFORExFX0xJQkNBTEwoU1JFTV9JNjQsICJfX21vZGRpMyIpCitIQU5ETEVfTElCQ0FMTChTUkVNX0kxMjgsICJfX21vZHRpMyIpCitIQU5ETEVfTElCQ0FMTChVUkVNX0k4LCAiX191bW9kcWkzIikKK0hBTkRMRV9MSUJDQUxMKFVSRU1fSTE2LCAiX191bW9kaGkzIikKK0hBTkRMRV9MSUJDQUxMKFVSRU1fSTMyLCAiX191bW9kc2kzIikKK0hBTkRMRV9MSUJDQUxMKFVSRU1fSTY0LCAiX191bW9kZGkzIikKK0hBTkRMRV9MSUJDQUxMKFVSRU1fSTEyOCwgIl9fdW1vZHRpMyIpCitIQU5ETEVfTElCQ0FMTChTRElWUkVNX0k4LCBudWxscHRyKQorSEFORExFX0xJQkNBTEwoU0RJVlJFTV9JMTYsIG51bGxwdHIpCitIQU5ETEVfTElCQ0FMTChTRElWUkVNX0kzMiwgbnVsbHB0cikKK0hBTkRMRV9MSUJDQUxMKFNESVZSRU1fSTY0LCBudWxscHRyKQorSEFORExFX0xJQkNBTEwoU0RJVlJFTV9JMTI4LCBudWxscHRyKQorSEFORExFX0xJQkNBTEwoVURJVlJFTV9JOCwgbnVsbHB0cikKK0hBTkRMRV9MSUJDQUxMKFVESVZSRU1fSTE2LCBudWxscHRyKQorSEFORExFX0xJQkNBTEwoVURJVlJFTV9JMzIsIG51bGxwdHIpCitIQU5ETEVfTElCQ0FMTChVRElWUkVNX0k2NCwgbnVsbHB0cikKK0hBTkRMRV9MSUJDQUxMKFVESVZSRU1fSTEyOCwgbnVsbHB0cikKK0hBTkRMRV9MSUJDQUxMKE5FR19JMzIsICJfX25lZ3NpMiIpCitIQU5ETEVfTElCQ0FMTChORUdfSTY0LCAiX19uZWdkaTIiKQorCisvLyBGbG9hdGluZy1wb2ludAorSEFORExFX0xJQkNBTEwoQUREX0YzMiwgIl9fYWRkc2YzIikKK0hBTkRMRV9MSUJDQUxMKEFERF9GNjQsICJfX2FkZGRmMyIpCitIQU5ETEVfTElCQ0FMTChBRERfRjgwLCAiX19hZGR4ZjMiKQorSEFORExFX0xJQkNBTEwoQUREX0YxMjgsICJfX2FkZHRmMyIpCitIQU5ETEVfTElCQ0FMTChBRERfUFBDRjEyOCwgIl9fZ2NjX3FhZGQiKQorSEFORExFX0xJQkNBTEwoU1VCX0YzMiwgIl9fc3Vic2YzIikKK0hBTkRMRV9MSUJDQUxMKFNVQl9GNjQsICJfX3N1YmRmMyIpCitIQU5ETEVfTElCQ0FMTChTVUJfRjgwLCAiX19zdWJ4ZjMiKQorSEFORExFX0xJQkNBTEwoU1VCX0YxMjgsICJfX3N1YnRmMyIpCitIQU5ETEVfTElCQ0FMTChTVUJfUFBDRjEyOCwgIl9fZ2NjX3FzdWIiKQorSEFORExFX0xJQkNBTEwoTVVMX0YzMiwgIl9fbXVsc2YzIikKK0hBTkRMRV9MSUJDQUxMKE1VTF9GNjQsICJfX211bGRmMyIpCitIQU5ETEVfTElCQ0FMTChNVUxfRjgwLCAiX19tdWx4ZjMiKQorSEFORExFX0xJQkNBTEwoTVVMX0YxMjgsICJfX211bHRmMyIpCitIQU5ETEVfTElCQ0FMTChNVUxfUFBDRjEyOCwgIl9fZ2NjX3FtdWwiKQorSEFORExFX0xJQkNBTEwoRElWX0YzMiwgIl9fZGl2c2YzIikKK0hBTkRMRV9MSUJDQUxMKERJVl9GNjQsICJfX2RpdmRmMyIpCitIQU5ETEVfTElCQ0FMTChESVZfRjgwLCAiX19kaXZ4ZjMiKQorSEFORExFX0xJQkNBTEwoRElWX0YxMjgsICJfX2RpdnRmMyIpCitIQU5ETEVfTElCQ0FMTChESVZfUFBDRjEyOCwgIl9fZ2NjX3FkaXYiKQorSEFORExFX0xJQkNBTEwoUkVNX0YzMiwgImZtb2RmIikKK0hBTkRMRV9MSUJDQUxMKFJFTV9GNjQsICJmbW9kIikKK0hBTkRMRV9MSUJDQUxMKFJFTV9GODAsICJmbW9kbCIpCitIQU5ETEVfTElCQ0FMTChSRU1fRjEyOCwgImZtb2RsIikKK0hBTkRMRV9MSUJDQUxMKFJFTV9QUENGMTI4LCAiZm1vZGwiKQorSEFORExFX0xJQkNBTEwoRk1BX0YzMiwgImZtYWYiKQorSEFORExFX0xJQkNBTEwoRk1BX0Y2NCwgImZtYSIpCitIQU5ETEVfTElCQ0FMTChGTUFfRjgwLCAiZm1hbCIpCitIQU5ETEVfTElCQ0FMTChGTUFfRjEyOCwgImZtYWwiKQorSEFORExFX0xJQkNBTEwoRk1BX1BQQ0YxMjgsICJmbWFsIikKK0hBTkRMRV9MSUJDQUxMKFBPV0lfRjMyLCAiX19wb3dpc2YyIikKK0hBTkRMRV9MSUJDQUxMKFBPV0lfRjY0LCAiX19wb3dpZGYyIikKK0hBTkRMRV9MSUJDQUxMKFBPV0lfRjgwLCAiX19wb3dpeGYyIikKK0hBTkRMRV9MSUJDQUxMKFBPV0lfRjEyOCwgIl9fcG93aXRmMiIpCitIQU5ETEVfTElCQ0FMTChQT1dJX1BQQ0YxMjgsICJfX3Bvd2l0ZjIiKQorSEFORExFX0xJQkNBTEwoU1FSVF9GMzIsICJzcXJ0ZiIpCitIQU5ETEVfTElCQ0FMTChTUVJUX0Y2NCwgInNxcnQiKQorSEFORExFX0xJQkNBTEwoU1FSVF9GODAsICJzcXJ0bCIpCitIQU5ETEVfTElCQ0FMTChTUVJUX0YxMjgsICJzcXJ0bCIpCitIQU5ETEVfTElCQ0FMTChTUVJUX1BQQ0YxMjgsICJzcXJ0bCIpCitIQU5ETEVfTElCQ0FMTChMT0dfRjMyLCAibG9nZiIpCitIQU5ETEVfTElCQ0FMTChMT0dfRjY0LCAibG9nIikKK0hBTkRMRV9MSUJDQUxMKExPR19GODAsICJsb2dsIikKK0hBTkRMRV9MSUJDQUxMKExPR19GMTI4LCAibG9nbCIpCitIQU5ETEVfTElCQ0FMTChMT0dfUFBDRjEyOCwgImxvZ2wiKQorSEFORExFX0xJQkNBTEwoTE9HX0ZJTklURV9GMzIsICJfX2xvZ2ZfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKExPR19GSU5JVEVfRjY0LCAiX19sb2dfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKExPR19GSU5JVEVfRjgwLCAiX19sb2dsX2Zpbml0ZSIpCitIQU5ETEVfTElCQ0FMTChMT0dfRklOSVRFX0YxMjgsICJfX2xvZ2xfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKExPR19GSU5JVEVfUFBDRjEyOCwgIl9fbG9nbF9maW5pdGUiKQorSEFORExFX0xJQkNBTEwoTE9HMl9GMzIsICJsb2cyZiIpCitIQU5ETEVfTElCQ0FMTChMT0cyX0Y2NCwgImxvZzIiKQorSEFORExFX0xJQkNBTEwoTE9HMl9GODAsICJsb2cybCIpCitIQU5ETEVfTElCQ0FMTChMT0cyX0YxMjgsICJsb2cybCIpCitIQU5ETEVfTElCQ0FMTChMT0cyX1BQQ0YxMjgsICJsb2cybCIpCitIQU5ETEVfTElCQ0FMTChMT0cyX0ZJTklURV9GMzIsICJfX2xvZzJmX2Zpbml0ZSIpCitIQU5ETEVfTElCQ0FMTChMT0cyX0ZJTklURV9GNjQsICJfX2xvZzJfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKExPRzJfRklOSVRFX0Y4MCwgIl9fbG9nMmxfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKExPRzJfRklOSVRFX0YxMjgsICJfX2xvZzJsX2Zpbml0ZSIpCitIQU5ETEVfTElCQ0FMTChMT0cyX0ZJTklURV9QUENGMTI4LCAiX19sb2cybF9maW5pdGUiKQorSEFORExFX0xJQkNBTEwoTE9HMTBfRjMyLCAibG9nMTBmIikKK0hBTkRMRV9MSUJDQUxMKExPRzEwX0Y2NCwgImxvZzEwIikKK0hBTkRMRV9MSUJDQUxMKExPRzEwX0Y4MCwgImxvZzEwbCIpCitIQU5ETEVfTElCQ0FMTChMT0cxMF9GMTI4LCAibG9nMTBsIikKK0hBTkRMRV9MSUJDQUxMKExPRzEwX1BQQ0YxMjgsICJsb2cxMGwiKQorSEFORExFX0xJQkNBTEwoTE9HMTBfRklOSVRFX0YzMiwgIl9fbG9nMTBmX2Zpbml0ZSIpCitIQU5ETEVfTElCQ0FMTChMT0cxMF9GSU5JVEVfRjY0LCAiX19sb2cxMF9maW5pdGUiKQorSEFORExFX0xJQkNBTEwoTE9HMTBfRklOSVRFX0Y4MCwgIl9fbG9nMTBsX2Zpbml0ZSIpCitIQU5ETEVfTElCQ0FMTChMT0cxMF9GSU5JVEVfRjEyOCwgIl9fbG9nMTBsX2Zpbml0ZSIpCitIQU5ETEVfTElCQ0FMTChMT0cxMF9GSU5JVEVfUFBDRjEyOCwgIl9fbG9nMTBsX2Zpbml0ZSIpCitIQU5ETEVfTElCQ0FMTChFWFBfRjMyLCAiZXhwZiIpCitIQU5ETEVfTElCQ0FMTChFWFBfRjY0LCAiZXhwIikKK0hBTkRMRV9MSUJDQUxMKEVYUF9GODAsICJleHBsIikKK0hBTkRMRV9MSUJDQUxMKEVYUF9GMTI4LCAiZXhwbCIpCitIQU5ETEVfTElCQ0FMTChFWFBfUFBDRjEyOCwgImV4cGwiKQorSEFORExFX0xJQkNBTEwoRVhQX0ZJTklURV9GMzIsICJfX2V4cGZfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKEVYUF9GSU5JVEVfRjY0LCAiX19leHBfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKEVYUF9GSU5JVEVfRjgwLCAiX19leHBsX2Zpbml0ZSIpCitIQU5ETEVfTElCQ0FMTChFWFBfRklOSVRFX0YxMjgsICJfX2V4cGxfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKEVYUF9GSU5JVEVfUFBDRjEyOCwgIl9fZXhwbF9maW5pdGUiKQorSEFORExFX0xJQkNBTEwoRVhQMl9GMzIsICJleHAyZiIpCitIQU5ETEVfTElCQ0FMTChFWFAyX0Y2NCwgImV4cDIiKQorSEFORExFX0xJQkNBTEwoRVhQMl9GODAsICJleHAybCIpCitIQU5ETEVfTElCQ0FMTChFWFAyX0YxMjgsICJleHAybCIpCitIQU5ETEVfTElCQ0FMTChFWFAyX1BQQ0YxMjgsICJleHAybCIpCitIQU5ETEVfTElCQ0FMTChFWFAyX0ZJTklURV9GMzIsICJfX2V4cDJmX2Zpbml0ZSIpCitIQU5ETEVfTElCQ0FMTChFWFAyX0ZJTklURV9GNjQsICJfX2V4cDJfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKEVYUDJfRklOSVRFX0Y4MCwgIl9fZXhwMmxfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKEVYUDJfRklOSVRFX0YxMjgsICJfX2V4cDJsX2Zpbml0ZSIpCitIQU5ETEVfTElCQ0FMTChFWFAyX0ZJTklURV9QUENGMTI4LCAiX19leHAybF9maW5pdGUiKQorSEFORExFX0xJQkNBTEwoU0lOX0YzMiwgInNpbmYiKQorSEFORExFX0xJQkNBTEwoU0lOX0Y2NCwgInNpbiIpCitIQU5ETEVfTElCQ0FMTChTSU5fRjgwLCAic2lubCIpCitIQU5ETEVfTElCQ0FMTChTSU5fRjEyOCwgInNpbmwiKQorSEFORExFX0xJQkNBTEwoU0lOX1BQQ0YxMjgsICJzaW5sIikKK0hBTkRMRV9MSUJDQUxMKENPU19GMzIsICJjb3NmIikKK0hBTkRMRV9MSUJDQUxMKENPU19GNjQsICJjb3MiKQorSEFORExFX0xJQkNBTEwoQ09TX0Y4MCwgImNvc2wiKQorSEFORExFX0xJQkNBTEwoQ09TX0YxMjgsICJjb3NsIikKK0hBTkRMRV9MSUJDQUxMKENPU19QUENGMTI4LCAiY29zbCIpCitIQU5ETEVfTElCQ0FMTChTSU5DT1NfRjMyLCBudWxscHRyKQorSEFORExFX0xJQkNBTEwoU0lOQ09TX0Y2NCwgbnVsbHB0cikKK0hBTkRMRV9MSUJDQUxMKFNJTkNPU19GODAsIG51bGxwdHIpCitIQU5ETEVfTElCQ0FMTChTSU5DT1NfRjEyOCwgbnVsbHB0cikKK0hBTkRMRV9MSUJDQUxMKFNJTkNPU19QUENGMTI4LCBudWxscHRyKQorSEFORExFX0xJQkNBTEwoU0lOQ09TX1NUUkVUX0YzMiwgbnVsbHB0cikKK0hBTkRMRV9MSUJDQUxMKFNJTkNPU19TVFJFVF9GNjQsIG51bGxwdHIpCitIQU5ETEVfTElCQ0FMTChQT1dfRjMyLCAicG93ZiIpCitIQU5ETEVfTElCQ0FMTChQT1dfRjY0LCAicG93IikKK0hBTkRMRV9MSUJDQUxMKFBPV19GODAsICJwb3dsIikKK0hBTkRMRV9MSUJDQUxMKFBPV19GMTI4LCAicG93bCIpCitIQU5ETEVfTElCQ0FMTChQT1dfUFBDRjEyOCwgInBvd2wiKQorSEFORExFX0xJQkNBTEwoUE9XX0ZJTklURV9GMzIsICJfX3Bvd2ZfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKFBPV19GSU5JVEVfRjY0LCAiX19wb3dfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKFBPV19GSU5JVEVfRjgwLCAiX19wb3dsX2Zpbml0ZSIpCitIQU5ETEVfTElCQ0FMTChQT1dfRklOSVRFX0YxMjgsICJfX3Bvd2xfZmluaXRlIikKK0hBTkRMRV9MSUJDQUxMKFBPV19GSU5JVEVfUFBDRjEyOCwgIl9fcG93bF9maW5pdGUiKQorSEFORExFX0xJQkNBTEwoQ0VJTF9GMzIsICJjZWlsZiIpCitIQU5ETEVfTElCQ0FMTChDRUlMX0Y2NCwgImNlaWwiKQorSEFORExFX0xJQkNBTEwoQ0VJTF9GODAsICJjZWlsbCIpCitIQU5ETEVfTElCQ0FMTChDRUlMX0YxMjgsICJjZWlsbCIpCitIQU5ETEVfTElCQ0FMTChDRUlMX1BQQ0YxMjgsICJjZWlsbCIpCitIQU5ETEVfTElCQ0FMTChUUlVOQ19GMzIsICJ0cnVuY2YiKQorSEFORExFX0xJQkNBTEwoVFJVTkNfRjY0LCAidHJ1bmMiKQorSEFORExFX0xJQkNBTEwoVFJVTkNfRjgwLCAidHJ1bmNsIikKK0hBTkRMRV9MSUJDQUxMKFRSVU5DX0YxMjgsICJ0cnVuY2wiKQorSEFORExFX0xJQkNBTEwoVFJVTkNfUFBDRjEyOCwgInRydW5jbCIpCitIQU5ETEVfTElCQ0FMTChSSU5UX0YzMiwgInJpbnRmIikKK0hBTkRMRV9MSUJDQUxMKFJJTlRfRjY0LCAicmludCIpCitIQU5ETEVfTElCQ0FMTChSSU5UX0Y4MCwgInJpbnRsIikKK0hBTkRMRV9MSUJDQUxMKFJJTlRfRjEyOCwgInJpbnRsIikKK0hBTkRMRV9MSUJDQUxMKFJJTlRfUFBDRjEyOCwgInJpbnRsIikKK0hBTkRMRV9MSUJDQUxMKE5FQVJCWUlOVF9GMzIsICJuZWFyYnlpbnRmIikKK0hBTkRMRV9MSUJDQUxMKE5FQVJCWUlOVF9GNjQsICJuZWFyYnlpbnQiKQorSEFORExFX0xJQkNBTEwoTkVBUkJZSU5UX0Y4MCwgIm5lYXJieWludGwiKQorSEFORExFX0xJQkNBTEwoTkVBUkJZSU5UX0YxMjgsICJuZWFyYnlpbnRsIikKK0hBTkRMRV9MSUJDQUxMKE5FQVJCWUlOVF9QUENGMTI4LCAibmVhcmJ5aW50bCIpCitIQU5ETEVfTElCQ0FMTChST1VORF9GMzIsICJyb3VuZGYiKQorSEFORExFX0xJQkNBTEwoUk9VTkRfRjY0LCAicm91bmQiKQorSEFORExFX0xJQkNBTEwoUk9VTkRfRjgwLCAicm91bmRsIikKK0hBTkRMRV9MSUJDQUxMKFJPVU5EX0YxMjgsICJyb3VuZGwiKQorSEFORExFX0xJQkNBTEwoUk9VTkRfUFBDRjEyOCwgInJvdW5kbCIpCitIQU5ETEVfTElCQ0FMTChGTE9PUl9GMzIsICJmbG9vcmYiKQorSEFORExFX0xJQkNBTEwoRkxPT1JfRjY0LCAiZmxvb3IiKQorSEFORExFX0xJQkNBTEwoRkxPT1JfRjgwLCAiZmxvb3JsIikKK0hBTkRMRV9MSUJDQUxMKEZMT09SX0YxMjgsICJmbG9vcmwiKQorSEFORExFX0xJQkNBTEwoRkxPT1JfUFBDRjEyOCwgImZsb29ybCIpCitIQU5ETEVfTElCQ0FMTChDT1BZU0lHTl9GMzIsICJjb3B5c2lnbmYiKQorSEFORExFX0xJQkNBTEwoQ09QWVNJR05fRjY0LCAiY29weXNpZ24iKQorSEFORExFX0xJQkNBTEwoQ09QWVNJR05fRjgwLCAiY29weXNpZ25sIikKK0hBTkRMRV9MSUJDQUxMKENPUFlTSUdOX0YxMjgsICJjb3B5c2lnbmwiKQorSEFORExFX0xJQkNBTEwoQ09QWVNJR05fUFBDRjEyOCwgImNvcHlzaWdubCIpCitIQU5ETEVfTElCQ0FMTChGTUlOX0YzMiwgImZtaW5mIikKK0hBTkRMRV9MSUJDQUxMKEZNSU5fRjY0LCAiZm1pbiIpCitIQU5ETEVfTElCQ0FMTChGTUlOX0Y4MCwgImZtaW5sIikKK0hBTkRMRV9MSUJDQUxMKEZNSU5fRjEyOCwgImZtaW5sIikKK0hBTkRMRV9MSUJDQUxMKEZNSU5fUFBDRjEyOCwgImZtaW5sIikKK0hBTkRMRV9MSUJDQUxMKEZNQVhfRjMyLCAiZm1heGYiKQorSEFORExFX0xJQkNBTEwoRk1BWF9GNjQsICJmbWF4IikKK0hBTkRMRV9MSUJDQUxMKEZNQVhfRjgwLCAiZm1heGwiKQorSEFORExFX0xJQkNBTEwoRk1BWF9GMTI4LCAiZm1heGwiKQorSEFORExFX0xJQkNBTEwoRk1BWF9QUENGMTI4LCAiZm1heGwiKQorCisvLyBDb252ZXJzaW9uCitIQU5ETEVfTElCQ0FMTChGUEVYVF9GMzJfUFBDRjEyOCwgIl9fZ2NjX3N0b3EiKQorSEFORExFX0xJQkNBTEwoRlBFWFRfRjY0X1BQQ0YxMjgsICJfX2djY19kdG9xIikKK0hBTkRMRV9MSUJDQUxMKEZQRVhUX0Y4MF9GMTI4LCAiX19leHRlbmR4ZnRmMiIpCitIQU5ETEVfTElCQ0FMTChGUEVYVF9GNjRfRjEyOCwgIl9fZXh0ZW5kZGZ0ZjIiKQorSEFORExFX0xJQkNBTEwoRlBFWFRfRjMyX0YxMjgsICJfX2V4dGVuZHNmdGYyIikKK0hBTkRMRV9MSUJDQUxMKEZQRVhUX0YzMl9GNjQsICJfX2V4dGVuZHNmZGYyIikKK0hBTkRMRV9MSUJDQUxMKEZQRVhUX0YxNl9GMzIsICJfX2dudV9oMmZfaWVlZSIpCitIQU5ETEVfTElCQ0FMTChGUFJPVU5EX0YzMl9GMTYsICJfX2dudV9mMmhfaWVlZSIpCitIQU5ETEVfTElCQ0FMTChGUFJPVU5EX0Y2NF9GMTYsICJfX3RydW5jZGZoZjIiKQorSEFORExFX0xJQkNBTEwoRlBST1VORF9GODBfRjE2LCAiX190cnVuY3hmaGYyIikKK0hBTkRMRV9MSUJDQUxMKEZQUk9VTkRfRjEyOF9GMTYsICJfX3RydW5jdGZoZjIiKQorSEFORExFX0xJQkNBTEwoRlBST1VORF9QUENGMTI4X0YxNiwgIl9fdHJ1bmN0ZmhmMiIpCitIQU5ETEVfTElCQ0FMTChGUFJPVU5EX0Y2NF9GMzIsICJfX3RydW5jZGZzZjIiKQorSEFORExFX0xJQkNBTEwoRlBST1VORF9GODBfRjMyLCAiX190cnVuY3hmc2YyIikKK0hBTkRMRV9MSUJDQUxMKEZQUk9VTkRfRjEyOF9GMzIsICJfX3RydW5jdGZzZjIiKQorSEFORExFX0xJQkNBTEwoRlBST1VORF9QUENGMTI4X0YzMiwgIl9fZ2NjX3F0b3MiKQorSEFORExFX0xJQkNBTEwoRlBST1VORF9GODBfRjY0LCAiX190cnVuY3hmZGYyIikKK0hBTkRMRV9MSUJDQUxMKEZQUk9VTkRfRjEyOF9GNjQsICJfX3RydW5jdGZkZjIiKQorSEFORExFX0xJQkNBTEwoRlBST1VORF9QUENGMTI4X0Y2NCwgIl9fZ2NjX3F0b2QiKQorSEFORExFX0xJQkNBTEwoRlBST1VORF9GMTI4X0Y4MCwgIl9fdHJ1bmN0ZnhmMiIpCitIQU5ETEVfTElCQ0FMTChGUFRPU0lOVF9GMzJfSTMyLCAiX19maXhzZnNpIikKK0hBTkRMRV9MSUJDQUxMKEZQVE9TSU5UX0YzMl9JNjQsICJfX2ZpeHNmZGkiKQorSEFORExFX0xJQkNBTEwoRlBUT1NJTlRfRjMyX0kxMjgsICJfX2ZpeHNmdGkiKQorSEFORExFX0xJQkNBTEwoRlBUT1NJTlRfRjY0X0kzMiwgIl9fZml4ZGZzaSIpCitIQU5ETEVfTElCQ0FMTChGUFRPU0lOVF9GNjRfSTY0LCAiX19maXhkZmRpIikKK0hBTkRMRV9MSUJDQUxMKEZQVE9TSU5UX0Y2NF9JMTI4LCAiX19maXhkZnRpIikKK0hBTkRMRV9MSUJDQUxMKEZQVE9TSU5UX0Y4MF9JMzIsICJfX2ZpeHhmc2kiKQorSEFORExFX0xJQkNBTEwoRlBUT1NJTlRfRjgwX0k2NCwgIl9fZml4eGZkaSIpCitIQU5ETEVfTElCQ0FMTChGUFRPU0lOVF9GODBfSTEyOCwgIl9fZml4eGZ0aSIpCitIQU5ETEVfTElCQ0FMTChGUFRPU0lOVF9GMTI4X0kzMiwgIl9fZml4dGZzaSIpCitIQU5ETEVfTElCQ0FMTChGUFRPU0lOVF9GMTI4X0k2NCwgIl9fZml4dGZkaSIpCitIQU5ETEVfTElCQ0FMTChGUFRPU0lOVF9GMTI4X0kxMjgsICJfX2ZpeHRmdGkiKQorSEFORExFX0xJQkNBTEwoRlBUT1NJTlRfUFBDRjEyOF9JMzIsICJfX2djY19xdG91IikKK0hBTkRMRV9MSUJDQUxMKEZQVE9TSU5UX1BQQ0YxMjhfSTY0LCAiX19maXh0ZmRpIikKK0hBTkRMRV9MSUJDQUxMKEZQVE9TSU5UX1BQQ0YxMjhfSTEyOCwgIl9fZml4dGZ0aSIpCitIQU5ETEVfTElCQ0FMTChGUFRPVUlOVF9GMzJfSTMyLCAiX19maXh1bnNzZnNpIikKK0hBTkRMRV9MSUJDQUxMKEZQVE9VSU5UX0YzMl9JNjQsICJfX2ZpeHVuc3NmZGkiKQorSEFORExFX0xJQkNBTEwoRlBUT1VJTlRfRjMyX0kxMjgsICJfX2ZpeHVuc3NmdGkiKQorSEFORExFX0xJQkNBTEwoRlBUT1VJTlRfRjY0X0kzMiwgIl9fZml4dW5zZGZzaSIpCitIQU5ETEVfTElCQ0FMTChGUFRPVUlOVF9GNjRfSTY0LCAiX19maXh1bnNkZmRpIikKK0hBTkRMRV9MSUJDQUxMKEZQVE9VSU5UX0Y2NF9JMTI4LCAiX19maXh1bnNkZnRpIikKK0hBTkRMRV9MSUJDQUxMKEZQVE9VSU5UX0Y4MF9JMzIsICJfX2ZpeHVuc3hmc2kiKQorSEFORExFX0xJQkNBTEwoRlBUT1VJTlRfRjgwX0k2NCwgIl9fZml4dW5zeGZkaSIpCitIQU5ETEVfTElCQ0FMTChGUFRPVUlOVF9GODBfSTEyOCwgIl9fZml4dW5zeGZ0aSIpCitIQU5ETEVfTElCQ0FMTChGUFRPVUlOVF9GMTI4X0kzMiwgIl9fZml4dW5zdGZzaSIpCitIQU5ETEVfTElCQ0FMTChGUFRPVUlOVF9GMTI4X0k2NCwgIl9fZml4dW5zdGZkaSIpCitIQU5ETEVfTElCQ0FMTChGUFRPVUlOVF9GMTI4X0kxMjgsICJfX2ZpeHVuc3RmdGkiKQorSEFORExFX0xJQkNBTEwoRlBUT1VJTlRfUFBDRjEyOF9JMzIsICJfX2ZpeHVuc3Rmc2kiKQorSEFORExFX0xJQkNBTEwoRlBUT1VJTlRfUFBDRjEyOF9JNjQsICJfX2ZpeHVuc3RmZGkiKQorSEFORExFX0xJQkNBTEwoRlBUT1VJTlRfUFBDRjEyOF9JMTI4LCAiX19maXh1bnN0ZnRpIikKK0hBTkRMRV9MSUJDQUxMKFNJTlRUT0ZQX0kzMl9GMzIsICJfX2Zsb2F0c2lzZiIpCitIQU5ETEVfTElCQ0FMTChTSU5UVE9GUF9JMzJfRjY0LCAiX19mbG9hdHNpZGYiKQorSEFORExFX0xJQkNBTEwoU0lOVFRPRlBfSTMyX0Y4MCwgIl9fZmxvYXRzaXhmIikKK0hBTkRMRV9MSUJDQUxMKFNJTlRUT0ZQX0kzMl9GMTI4LCAiX19mbG9hdHNpdGYiKQorSEFORExFX0xJQkNBTEwoU0lOVFRPRlBfSTMyX1BQQ0YxMjgsICJfX2djY19pdG9xIikKK0hBTkRMRV9MSUJDQUxMKFNJTlRUT0ZQX0k2NF9GMzIsICJfX2Zsb2F0ZGlzZiIpCitIQU5ETEVfTElCQ0FMTChTSU5UVE9GUF9JNjRfRjY0LCAiX19mbG9hdGRpZGYiKQorSEFORExFX0xJQkNBTEwoU0lOVFRPRlBfSTY0X0Y4MCwgIl9fZmxvYXRkaXhmIikKK0hBTkRMRV9MSUJDQUxMKFNJTlRUT0ZQX0k2NF9GMTI4LCAiX19mbG9hdGRpdGYiKQorSEFORExFX0xJQkNBTEwoU0lOVFRPRlBfSTY0X1BQQ0YxMjgsICJfX2Zsb2F0ZGl0ZiIpCitIQU5ETEVfTElCQ0FMTChTSU5UVE9GUF9JMTI4X0YzMiwgIl9fZmxvYXR0aXNmIikKK0hBTkRMRV9MSUJDQUxMKFNJTlRUT0ZQX0kxMjhfRjY0LCAiX19mbG9hdHRpZGYiKQorSEFORExFX0xJQkNBTEwoU0lOVFRPRlBfSTEyOF9GODAsICJfX2Zsb2F0dGl4ZiIpCitIQU5ETEVfTElCQ0FMTChTSU5UVE9GUF9JMTI4X0YxMjgsICJfX2Zsb2F0dGl0ZiIpCitIQU5ETEVfTElCQ0FMTChTSU5UVE9GUF9JMTI4X1BQQ0YxMjgsICJfX2Zsb2F0dGl0ZiIpCitIQU5ETEVfTElCQ0FMTChVSU5UVE9GUF9JMzJfRjMyLCAiX19mbG9hdHVuc2lzZiIpCitIQU5ETEVfTElCQ0FMTChVSU5UVE9GUF9JMzJfRjY0LCAiX19mbG9hdHVuc2lkZiIpCitIQU5ETEVfTElCQ0FMTChVSU5UVE9GUF9JMzJfRjgwLCAiX19mbG9hdHVuc2l4ZiIpCitIQU5ETEVfTElCQ0FMTChVSU5UVE9GUF9JMzJfRjEyOCwgIl9fZmxvYXR1bnNpdGYiKQorSEFORExFX0xJQkNBTEwoVUlOVFRPRlBfSTMyX1BQQ0YxMjgsICJfX2djY191dG9xIikKK0hBTkRMRV9MSUJDQUxMKFVJTlRUT0ZQX0k2NF9GMzIsICJfX2Zsb2F0dW5kaXNmIikKK0hBTkRMRV9MSUJDQUxMKFVJTlRUT0ZQX0k2NF9GNjQsICJfX2Zsb2F0dW5kaWRmIikKK0hBTkRMRV9MSUJDQUxMKFVJTlRUT0ZQX0k2NF9GODAsICJfX2Zsb2F0dW5kaXhmIikKK0hBTkRMRV9MSUJDQUxMKFVJTlRUT0ZQX0k2NF9GMTI4LCAiX19mbG9hdHVuZGl0ZiIpCitIQU5ETEVfTElCQ0FMTChVSU5UVE9GUF9JNjRfUFBDRjEyOCwgIl9fZmxvYXR1bmRpdGYiKQorSEFORExFX0xJQkNBTEwoVUlOVFRPRlBfSTEyOF9GMzIsICJfX2Zsb2F0dW50aXNmIikKK0hBTkRMRV9MSUJDQUxMKFVJTlRUT0ZQX0kxMjhfRjY0LCAiX19mbG9hdHVudGlkZiIpCitIQU5ETEVfTElCQ0FMTChVSU5UVE9GUF9JMTI4X0Y4MCwgIl9fZmxvYXR1bnRpeGYiKQorSEFORExFX0xJQkNBTEwoVUlOVFRPRlBfSTEyOF9GMTI4LCAiX19mbG9hdHVudGl0ZiIpCitIQU5ETEVfTElCQ0FMTChVSU5UVE9GUF9JMTI4X1BQQ0YxMjgsICJfX2Zsb2F0dW50aXRmIikKKworLy8gQ29tcGFyaXNvbgorSEFORExFX0xJQkNBTEwoT0VRX0YzMiwgIl9fZXFzZjIiKQorSEFORExFX0xJQkNBTEwoT0VRX0Y2NCwgIl9fZXFkZjIiKQorSEFORExFX0xJQkNBTEwoT0VRX0YxMjgsICJfX2VxdGYyIikKK0hBTkRMRV9MSUJDQUxMKE9FUV9QUENGMTI4LCAiX19nY2NfcWVxIikKK0hBTkRMRV9MSUJDQUxMKFVORV9GMzIsICJfX25lc2YyIikKK0hBTkRMRV9MSUJDQUxMKFVORV9GNjQsICJfX25lZGYyIikKK0hBTkRMRV9MSUJDQUxMKFVORV9GMTI4LCAiX19uZXRmMiIpCitIQU5ETEVfTElCQ0FMTChVTkVfUFBDRjEyOCwgIl9fZ2NjX3FuZSIpCitIQU5ETEVfTElCQ0FMTChPR0VfRjMyLCAiX19nZXNmMiIpCitIQU5ETEVfTElCQ0FMTChPR0VfRjY0LCAiX19nZWRmMiIpCitIQU5ETEVfTElCQ0FMTChPR0VfRjEyOCwgIl9fZ2V0ZjIiKQorSEFORExFX0xJQkNBTEwoT0dFX1BQQ0YxMjgsICJfX2djY19xZ2UiKQorSEFORExFX0xJQkNBTEwoT0xUX0YzMiwgIl9fbHRzZjIiKQorSEFORExFX0xJQkNBTEwoT0xUX0Y2NCwgIl9fbHRkZjIiKQorSEFORExFX0xJQkNBTEwoT0xUX0YxMjgsICJfX2x0dGYyIikKK0hBTkRMRV9MSUJDQUxMKE9MVF9QUENGMTI4LCAiX19nY2NfcWx0IikKK0hBTkRMRV9MSUJDQUxMKE9MRV9GMzIsICJfX2xlc2YyIikKK0hBTkRMRV9MSUJDQUxMKE9MRV9GNjQsICJfX2xlZGYyIikKK0hBTkRMRV9MSUJDQUxMKE9MRV9GMTI4LCAiX19sZXRmMiIpCitIQU5ETEVfTElCQ0FMTChPTEVfUFBDRjEyOCwgIl9fZ2NjX3FsZSIpCitIQU5ETEVfTElCQ0FMTChPR1RfRjMyLCAiX19ndHNmMiIpCitIQU5ETEVfTElCQ0FMTChPR1RfRjY0LCAiX19ndGRmMiIpCitIQU5ETEVfTElCQ0FMTChPR1RfRjEyOCwgIl9fZ3R0ZjIiKQorSEFORExFX0xJQkNBTEwoT0dUX1BQQ0YxMjgsICJfX2djY19xZ3QiKQorSEFORExFX0xJQkNBTEwoVU9fRjMyLCAiX191bm9yZHNmMiIpCitIQU5ETEVfTElCQ0FMTChVT19GNjQsICJfX3Vub3JkZGYyIikKK0hBTkRMRV9MSUJDQUxMKFVPX0YxMjgsICJfX3Vub3JkdGYyIikKK0hBTkRMRV9MSUJDQUxMKFVPX1BQQ0YxMjgsICJfX2djY19xdW5vcmQiKQorSEFORExFX0xJQkNBTEwoT19GMzIsICJfX3Vub3Jkc2YyIikKK0hBTkRMRV9MSUJDQUxMKE9fRjY0LCAiX191bm9yZGRmMiIpCitIQU5ETEVfTElCQ0FMTChPX0YxMjgsICJfX3Vub3JkdGYyIikKK0hBTkRMRV9MSUJDQUxMKE9fUFBDRjEyOCwgIl9fZ2NjX3F1bm9yZCIpCisKKy8vIE1lbW9yeQorSEFORExFX0xJQkNBTEwoTUVNQ1BZLCAibWVtY3B5IikKK0hBTkRMRV9MSUJDQUxMKE1FTU1PVkUsICJtZW1tb3ZlIikKK0hBTkRMRV9MSUJDQUxMKE1FTVNFVCwgIm1lbXNldCIpCitIQU5ETEVfTElCQ0FMTChCWkVSTywgbnVsbHB0cikKKworLy8gRWxlbWVudC13aXNlIHVub3JkZXJlZC1hdG9taWMgbWVtb3J5IG9mIGRpZmZlcmVudCBzaXplcworSEFORExFX0xJQkNBTEwoTUVNQ1BZX0VMRU1FTlRfVU5PUkRFUkVEX0FUT01JQ18xLCAiX19sbHZtX21lbWNweV9lbGVtZW50X3Vub3JkZXJlZF9hdG9taWNfMSIpCitIQU5ETEVfTElCQ0FMTChNRU1DUFlfRUxFTUVOVF9VTk9SREVSRURfQVRPTUlDXzIsICJfX2xsdm1fbWVtY3B5X2VsZW1lbnRfdW5vcmRlcmVkX2F0b21pY18yIikKK0hBTkRMRV9MSUJDQUxMKE1FTUNQWV9FTEVNRU5UX1VOT1JERVJFRF9BVE9NSUNfNCwgIl9fbGx2bV9tZW1jcHlfZWxlbWVudF91bm9yZGVyZWRfYXRvbWljXzQiKQorSEFORExFX0xJQkNBTEwoTUVNQ1BZX0VMRU1FTlRfVU5PUkRFUkVEX0FUT01JQ184LCAiX19sbHZtX21lbWNweV9lbGVtZW50X3Vub3JkZXJlZF9hdG9taWNfOCIpCitIQU5ETEVfTElCQ0FMTChNRU1DUFlfRUxFTUVOVF9VTk9SREVSRURfQVRPTUlDXzE2LCAiX19sbHZtX21lbWNweV9lbGVtZW50X3Vub3JkZXJlZF9hdG9taWNfMTYiKQorSEFORExFX0xJQkNBTEwoTUVNTU9WRV9FTEVNRU5UX1VOT1JERVJFRF9BVE9NSUNfMSwgIl9fbGx2bV9tZW1tb3ZlX2VsZW1lbnRfdW5vcmRlcmVkX2F0b21pY18xIikKK0hBTkRMRV9MSUJDQUxMKE1FTU1PVkVfRUxFTUVOVF9VTk9SREVSRURfQVRPTUlDXzIsICJfX2xsdm1fbWVtbW92ZV9lbGVtZW50X3Vub3JkZXJlZF9hdG9taWNfMiIpCitIQU5ETEVfTElCQ0FMTChNRU1NT1ZFX0VMRU1FTlRfVU5PUkRFUkVEX0FUT01JQ180LCAiX19sbHZtX21lbW1vdmVfZWxlbWVudF91bm9yZGVyZWRfYXRvbWljXzQiKQorSEFORExFX0xJQkNBTEwoTUVNTU9WRV9FTEVNRU5UX1VOT1JERVJFRF9BVE9NSUNfOCwgIl9fbGx2bV9tZW1tb3ZlX2VsZW1lbnRfdW5vcmRlcmVkX2F0b21pY184IikKK0hBTkRMRV9MSUJDQUxMKE1FTU1PVkVfRUxFTUVOVF9VTk9SREVSRURfQVRPTUlDXzE2LCAiX19sbHZtX21lbW1vdmVfZWxlbWVudF91bm9yZGVyZWRfYXRvbWljXzE2IikKK0hBTkRMRV9MSUJDQUxMKE1FTVNFVF9FTEVNRU5UX1VOT1JERVJFRF9BVE9NSUNfMSwgIl9fbGx2bV9tZW1zZXRfZWxlbWVudF91bm9yZGVyZWRfYXRvbWljXzEiKQorSEFORExFX0xJQkNBTEwoTUVNU0VUX0VMRU1FTlRfVU5PUkRFUkVEX0FUT01JQ18yLCAiX19sbHZtX21lbXNldF9lbGVtZW50X3Vub3JkZXJlZF9hdG9taWNfMiIpCitIQU5ETEVfTElCQ0FMTChNRU1TRVRfRUxFTUVOVF9VTk9SREVSRURfQVRPTUlDXzQsICJfX2xsdm1fbWVtc2V0X2VsZW1lbnRfdW5vcmRlcmVkX2F0b21pY180IikKK0hBTkRMRV9MSUJDQUxMKE1FTVNFVF9FTEVNRU5UX1VOT1JERVJFRF9BVE9NSUNfOCwgIl9fbGx2bV9tZW1zZXRfZWxlbWVudF91bm9yZGVyZWRfYXRvbWljXzgiKQorSEFORExFX0xJQkNBTEwoTUVNU0VUX0VMRU1FTlRfVU5PUkRFUkVEX0FUT01JQ18xNiwgIl9fbGx2bV9tZW1zZXRfZWxlbWVudF91bm9yZGVyZWRfYXRvbWljXzE2IikKKworLy8gRXhjZXB0aW9uIGhhbmRsaW5nCitIQU5ETEVfTElCQ0FMTChVTldJTkRfUkVTVU1FLCAiX1Vud2luZF9SZXN1bWUiKQorCisvLyBOb3RlOiB0aGVyZSBhcmUgdHdvIHNldHMgb2YgYXRvbWljcyBsaWJjYWxsczsgc2VlCisvLyA8aHR0cHM6Ly9sbHZtLm9yZy9kb2NzL0F0b21pY3MuaHRtbD4gZm9yIG1vcmUgaW5mbyBvbiB0aGUKKy8vIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGVtLgorCisvLyBBdG9taWMgJ19fc3luY18qJyBsaWJjYWxscy4KK0hBTkRMRV9MSUJDQUxMKFNZTkNfVkFMX0NPTVBBUkVfQU5EX1NXQVBfMSwgIl9fc3luY192YWxfY29tcGFyZV9hbmRfc3dhcF8xIikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfVkFMX0NPTVBBUkVfQU5EX1NXQVBfMiwgIl9fc3luY192YWxfY29tcGFyZV9hbmRfc3dhcF8yIikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfVkFMX0NPTVBBUkVfQU5EX1NXQVBfNCwgIl9fc3luY192YWxfY29tcGFyZV9hbmRfc3dhcF80IikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfVkFMX0NPTVBBUkVfQU5EX1NXQVBfOCwgIl9fc3luY192YWxfY29tcGFyZV9hbmRfc3dhcF84IikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfVkFMX0NPTVBBUkVfQU5EX1NXQVBfMTYsICJfX3N5bmNfdmFsX2NvbXBhcmVfYW5kX3N3YXBfMTYiKQorSEFORExFX0xJQkNBTEwoU1lOQ19MT0NLX1RFU1RfQU5EX1NFVF8xLCAiX19zeW5jX2xvY2tfdGVzdF9hbmRfc2V0XzEiKQorSEFORExFX0xJQkNBTEwoU1lOQ19MT0NLX1RFU1RfQU5EX1NFVF8yLCAiX19zeW5jX2xvY2tfdGVzdF9hbmRfc2V0XzIiKQorSEFORExFX0xJQkNBTEwoU1lOQ19MT0NLX1RFU1RfQU5EX1NFVF80LCAiX19zeW5jX2xvY2tfdGVzdF9hbmRfc2V0XzQiKQorSEFORExFX0xJQkNBTEwoU1lOQ19MT0NLX1RFU1RfQU5EX1NFVF84LCAiX19zeW5jX2xvY2tfdGVzdF9hbmRfc2V0XzgiKQorSEFORExFX0xJQkNBTEwoU1lOQ19MT0NLX1RFU1RfQU5EX1NFVF8xNiwgIl9fc3luY19sb2NrX3Rlc3RfYW5kX3NldF8xNiIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9BRERfMSwgIl9fc3luY19mZXRjaF9hbmRfYWRkXzEiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfQUREXzIsICJfX3N5bmNfZmV0Y2hfYW5kX2FkZF8yIikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfRkVUQ0hfQU5EX0FERF80LCAiX19zeW5jX2ZldGNoX2FuZF9hZGRfNCIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9BRERfOCwgIl9fc3luY19mZXRjaF9hbmRfYWRkXzgiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfQUREXzE2LCAiX19zeW5jX2ZldGNoX2FuZF9hZGRfMTYiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfU1VCXzEsICJfX3N5bmNfZmV0Y2hfYW5kX3N1Yl8xIikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfRkVUQ0hfQU5EX1NVQl8yLCAiX19zeW5jX2ZldGNoX2FuZF9zdWJfMiIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9TVUJfNCwgIl9fc3luY19mZXRjaF9hbmRfc3ViXzQiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfU1VCXzgsICJfX3N5bmNfZmV0Y2hfYW5kX3N1Yl84IikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfRkVUQ0hfQU5EX1NVQl8xNiwgIl9fc3luY19mZXRjaF9hbmRfc3ViXzE2IikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfRkVUQ0hfQU5EX0FORF8xLCAiX19zeW5jX2ZldGNoX2FuZF9hbmRfMSIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9BTkRfMiwgIl9fc3luY19mZXRjaF9hbmRfYW5kXzIiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfQU5EXzQsICJfX3N5bmNfZmV0Y2hfYW5kX2FuZF80IikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfRkVUQ0hfQU5EX0FORF84LCAiX19zeW5jX2ZldGNoX2FuZF9hbmRfOCIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9BTkRfMTYsICJfX3N5bmNfZmV0Y2hfYW5kX2FuZF8xNiIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9PUl8xLCAiX19zeW5jX2ZldGNoX2FuZF9vcl8xIikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfRkVUQ0hfQU5EX09SXzIsICJfX3N5bmNfZmV0Y2hfYW5kX29yXzIiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfT1JfNCwgIl9fc3luY19mZXRjaF9hbmRfb3JfNCIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9PUl84LCAiX19zeW5jX2ZldGNoX2FuZF9vcl84IikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfRkVUQ0hfQU5EX09SXzE2LCAiX19zeW5jX2ZldGNoX2FuZF9vcl8xNiIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9YT1JfMSwgIl9fc3luY19mZXRjaF9hbmRfeG9yXzEiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfWE9SXzIsICJfX3N5bmNfZmV0Y2hfYW5kX3hvcl8yIikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfRkVUQ0hfQU5EX1hPUl80LCAiX19zeW5jX2ZldGNoX2FuZF94b3JfNCIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9YT1JfOCwgIl9fc3luY19mZXRjaF9hbmRfeG9yXzgiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfWE9SXzE2LCAiX19zeW5jX2ZldGNoX2FuZF94b3JfMTYiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfTkFORF8xLCAiX19zeW5jX2ZldGNoX2FuZF9uYW5kXzEiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfTkFORF8yLCAiX19zeW5jX2ZldGNoX2FuZF9uYW5kXzIiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfTkFORF80LCAiX19zeW5jX2ZldGNoX2FuZF9uYW5kXzQiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfTkFORF84LCAiX19zeW5jX2ZldGNoX2FuZF9uYW5kXzgiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfTkFORF8xNiwgIl9fc3luY19mZXRjaF9hbmRfbmFuZF8xNiIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9NQVhfMSwgIl9fc3luY19mZXRjaF9hbmRfbWF4XzEiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfTUFYXzIsICJfX3N5bmNfZmV0Y2hfYW5kX21heF8yIikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfRkVUQ0hfQU5EX01BWF80LCAiX19zeW5jX2ZldGNoX2FuZF9tYXhfNCIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9NQVhfOCwgIl9fc3luY19mZXRjaF9hbmRfbWF4XzgiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfTUFYXzE2LCAiX19zeW5jX2ZldGNoX2FuZF9tYXhfMTYiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfVU1BWF8xLCAiX19zeW5jX2ZldGNoX2FuZF91bWF4XzEiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfVU1BWF8yLCAiX19zeW5jX2ZldGNoX2FuZF91bWF4XzIiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfVU1BWF80LCAiX19zeW5jX2ZldGNoX2FuZF91bWF4XzQiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfVU1BWF84LCAiX19zeW5jX2ZldGNoX2FuZF91bWF4XzgiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfVU1BWF8xNiwgIl9fc3luY19mZXRjaF9hbmRfdW1heF8xNiIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9NSU5fMSwgIl9fc3luY19mZXRjaF9hbmRfbWluXzEiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfTUlOXzIsICJfX3N5bmNfZmV0Y2hfYW5kX21pbl8yIikKK0hBTkRMRV9MSUJDQUxMKFNZTkNfRkVUQ0hfQU5EX01JTl80LCAiX19zeW5jX2ZldGNoX2FuZF9taW5fNCIpCitIQU5ETEVfTElCQ0FMTChTWU5DX0ZFVENIX0FORF9NSU5fOCwgIl9fc3luY19mZXRjaF9hbmRfbWluXzgiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfTUlOXzE2LCAiX19zeW5jX2ZldGNoX2FuZF9taW5fMTYiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfVU1JTl8xLCAiX19zeW5jX2ZldGNoX2FuZF91bWluXzEiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfVU1JTl8yLCAiX19zeW5jX2ZldGNoX2FuZF91bWluXzIiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfVU1JTl80LCAiX19zeW5jX2ZldGNoX2FuZF91bWluXzQiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfVU1JTl84LCAiX19zeW5jX2ZldGNoX2FuZF91bWluXzgiKQorSEFORExFX0xJQkNBTEwoU1lOQ19GRVRDSF9BTkRfVU1JTl8xNiwgIl9fc3luY19mZXRjaF9hbmRfdW1pbl8xNiIpCisKKy8vIEF0b21pYyBgX19hdG9taWNfKicgbGliY2FsbHMuCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfTE9BRCwgIl9fYXRvbWljX2xvYWQiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0xPQURfMSwgIl9fYXRvbWljX2xvYWRfMSIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfTE9BRF8yLCAiX19hdG9taWNfbG9hZF8yIikKK0hBTkRMRV9MSUJDQUxMKEFUT01JQ19MT0FEXzQsICJfX2F0b21pY19sb2FkXzQiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0xPQURfOCwgIl9fYXRvbWljX2xvYWRfOCIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfTE9BRF8xNiwgIl9fYXRvbWljX2xvYWRfMTYiKQorCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfU1RPUkUsICJfX2F0b21pY19zdG9yZSIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfU1RPUkVfMSwgIl9fYXRvbWljX3N0b3JlXzEiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX1NUT1JFXzIsICJfX2F0b21pY19zdG9yZV8yIikKK0hBTkRMRV9MSUJDQUxMKEFUT01JQ19TVE9SRV80LCAiX19hdG9taWNfc3RvcmVfNCIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfU1RPUkVfOCwgIl9fYXRvbWljX3N0b3JlXzgiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX1NUT1JFXzE2LCAiX19hdG9taWNfc3RvcmVfMTYiKQorCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfRVhDSEFOR0UsICJfX2F0b21pY19leGNoYW5nZSIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfRVhDSEFOR0VfMSwgIl9fYXRvbWljX2V4Y2hhbmdlXzEiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0VYQ0hBTkdFXzIsICJfX2F0b21pY19leGNoYW5nZV8yIikKK0hBTkRMRV9MSUJDQUxMKEFUT01JQ19FWENIQU5HRV80LCAiX19hdG9taWNfZXhjaGFuZ2VfNCIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfRVhDSEFOR0VfOCwgIl9fYXRvbWljX2V4Y2hhbmdlXzgiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0VYQ0hBTkdFXzE2LCAiX19hdG9taWNfZXhjaGFuZ2VfMTYiKQorCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfQ09NUEFSRV9FWENIQU5HRSwgIl9fYXRvbWljX2NvbXBhcmVfZXhjaGFuZ2UiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0NPTVBBUkVfRVhDSEFOR0VfMSwgIl9fYXRvbWljX2NvbXBhcmVfZXhjaGFuZ2VfMSIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfQ09NUEFSRV9FWENIQU5HRV8yLCAiX19hdG9taWNfY29tcGFyZV9leGNoYW5nZV8yIikKK0hBTkRMRV9MSUJDQUxMKEFUT01JQ19DT01QQVJFX0VYQ0hBTkdFXzQsICJfX2F0b21pY19jb21wYXJlX2V4Y2hhbmdlXzQiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0NPTVBBUkVfRVhDSEFOR0VfOCwgIl9fYXRvbWljX2NvbXBhcmVfZXhjaGFuZ2VfOCIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfQ09NUEFSRV9FWENIQU5HRV8xNiwgIl9fYXRvbWljX2NvbXBhcmVfZXhjaGFuZ2VfMTYiKQorCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfRkVUQ0hfQUREXzEsICJfX2F0b21pY19mZXRjaF9hZGRfMSIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfRkVUQ0hfQUREXzIsICJfX2F0b21pY19mZXRjaF9hZGRfMiIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfRkVUQ0hfQUREXzQsICJfX2F0b21pY19mZXRjaF9hZGRfNCIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfRkVUQ0hfQUREXzgsICJfX2F0b21pY19mZXRjaF9hZGRfOCIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfRkVUQ0hfQUREXzE2LCAiX19hdG9taWNfZmV0Y2hfYWRkXzE2IikKK0hBTkRMRV9MSUJDQUxMKEFUT01JQ19GRVRDSF9TVUJfMSwgIl9fYXRvbWljX2ZldGNoX3N1Yl8xIikKK0hBTkRMRV9MSUJDQUxMKEFUT01JQ19GRVRDSF9TVUJfMiwgIl9fYXRvbWljX2ZldGNoX3N1Yl8yIikKK0hBTkRMRV9MSUJDQUxMKEFUT01JQ19GRVRDSF9TVUJfNCwgIl9fYXRvbWljX2ZldGNoX3N1Yl80IikKK0hBTkRMRV9MSUJDQUxMKEFUT01JQ19GRVRDSF9TVUJfOCwgIl9fYXRvbWljX2ZldGNoX3N1Yl84IikKK0hBTkRMRV9MSUJDQUxMKEFUT01JQ19GRVRDSF9TVUJfMTYsICJfX2F0b21pY19mZXRjaF9zdWJfMTYiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX0FORF8xLCAiX19hdG9taWNfZmV0Y2hfYW5kXzEiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX0FORF8yLCAiX19hdG9taWNfZmV0Y2hfYW5kXzIiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX0FORF80LCAiX19hdG9taWNfZmV0Y2hfYW5kXzQiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX0FORF84LCAiX19hdG9taWNfZmV0Y2hfYW5kXzgiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX0FORF8xNiwgIl9fYXRvbWljX2ZldGNoX2FuZF8xNiIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfRkVUQ0hfT1JfMSwgIl9fYXRvbWljX2ZldGNoX29yXzEiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX09SXzIsICJfX2F0b21pY19mZXRjaF9vcl8yIikKK0hBTkRMRV9MSUJDQUxMKEFUT01JQ19GRVRDSF9PUl80LCAiX19hdG9taWNfZmV0Y2hfb3JfNCIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfRkVUQ0hfT1JfOCwgIl9fYXRvbWljX2ZldGNoX29yXzgiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX09SXzE2LCAiX19hdG9taWNfZmV0Y2hfb3JfMTYiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX1hPUl8xLCAiX19hdG9taWNfZmV0Y2hfeG9yXzEiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX1hPUl8yLCAiX19hdG9taWNfZmV0Y2hfeG9yXzIiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX1hPUl80LCAiX19hdG9taWNfZmV0Y2hfeG9yXzQiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX1hPUl84LCAiX19hdG9taWNfZmV0Y2hfeG9yXzgiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX1hPUl8xNiwgIl9fYXRvbWljX2ZldGNoX3hvcl8xNiIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfRkVUQ0hfTkFORF8xLCAiX19hdG9taWNfZmV0Y2hfbmFuZF8xIikKK0hBTkRMRV9MSUJDQUxMKEFUT01JQ19GRVRDSF9OQU5EXzIsICJfX2F0b21pY19mZXRjaF9uYW5kXzIiKQorSEFORExFX0xJQkNBTEwoQVRPTUlDX0ZFVENIX05BTkRfNCwgIl9fYXRvbWljX2ZldGNoX25hbmRfNCIpCitIQU5ETEVfTElCQ0FMTChBVE9NSUNfRkVUQ0hfTkFORF84LCAiX19hdG9taWNfZmV0Y2hfbmFuZF84IikKK0hBTkRMRV9MSUJDQUxMKEFUT01JQ19GRVRDSF9OQU5EXzE2LCAiX19hdG9taWNfZmV0Y2hfbmFuZF8xNiIpCisKKy8vIFN0YWNrIFByb3RlY3RvciBGYWlsCitIQU5ETEVfTElCQ0FMTChTVEFDS1BST1RFQ1RPUl9DSEVDS19GQUlMLCAiX19zdGFja19jaGtfZmFpbCIpCisKKy8vIERlb3B0aW1pemF0aW9uCitIQU5ETEVfTElCQ0FMTChERU9QVElNSVpFLCAiX19sbHZtX2Rlb3B0aW1pemUiKQorCitIQU5ETEVfTElCQ0FMTChVTktOT1dOX0xJQkNBTEwsIG51bGxwdHIpCisKKyN1bmRlZiBIQU5ETEVfTElCQ0FMTApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1J1bnRpbWVMaWJjYWxscy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1J1bnRpbWVMaWJjYWxscy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAxNmJlZjEKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vUnVudGltZUxpYmNhbGxzLmgKQEAgLTAsMCArMSw4MiBAQAorLy89PT0tLSBDb2RlR2VuL1J1bnRpbWVMaWJjYWxscy5oIC0gUnVudGltZSBMaWJyYXJ5IENhbGxzIC0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgZGVmaW5lcyB0aGUgZW51bSByZXByZXNlbnRpbmcgdGhlIGxpc3Qgb2YgcnVudGltZSBsaWJyYXJ5IGNhbGxzCisvLyB0aGUgYmFja2VuZCBtYXkgZW1pdCBkdXJpbmcgY29kZSBnZW5lcmF0aW9uLCBhbmQgYWxzbyBzb21lIGhlbHBlciBmdW5jdGlvbnMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fUlVOVElNRUxJQkNBTExTX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1JVTlRJTUVMSUJDQUxMU19ICisKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVmFsdWVUeXBlcy5oIgorCituYW1lc3BhY2UgbGx2bSB7CituYW1lc3BhY2UgUlRMSUIgeworICAvLy8gUlRMSUI6OkxpYmNhbGwgZW51bSAtIFRoaXMgZW51bSBkZWZpbmVzIGFsbCBvZiB0aGUgcnVudGltZSBsaWJyYXJ5IGNhbGxzCisgIC8vLyB0aGUgYmFja2VuZCBjYW4gZW1pdC4gIFRoZSB2YXJpb3VzIGxvbmcgZG91YmxlIHR5cGVzIGNhbm5vdCBiZSBtZXJnZWQsCisgIC8vLyBiZWNhdXNlIDgwLWJpdCBsaWJyYXJ5IGZ1bmN0aW9ucyB1c2UgInhmIiBhbmQgMTI4LWJpdCB1c2UgInRmIi4KKyAgLy8vCisgIC8vLyBXaGVuIGFkZGluZyBQUENGMTI4IGZ1bmN0aW9ucyBoZXJlLCBub3RlIHRoYXQgdGhlaXIgbmFtZXMgZ2VuZXJhbGx5IG5lZWQKKyAgLy8vIHRvIGJlIG92ZXJyaWRkZW4gZm9yIERhcndpbiB3aXRoIHRoZSB4eHgkTERCTDEyOCBmb3JtLiAgU2VlCisgIC8vLyBQUENJU2VsTG93ZXJpbmcuY3BwLgorICAvLy8KKyAgZW51bSBMaWJjYWxsIHsKKyNkZWZpbmUgSEFORExFX0xJQkNBTEwoY29kZSwgbmFtZSkgY29kZSwKKyAgICAjaW5jbHVkZSAiUnVudGltZUxpYmNhbGxzLmRlZiIKKyN1bmRlZiBIQU5ETEVfTElCQ0FMTAorICB9OworCisgIC8vLyBnZXRGUEVYVCAtIFJldHVybiB0aGUgRlBFWFRfKl8qIHZhbHVlIGZvciB0aGUgZ2l2ZW4gdHlwZXMsIG9yCisgIC8vLyBVTktOT1dOX0xJQkNBTEwgaWYgdGhlcmUgaXMgbm9uZS4KKyAgTGliY2FsbCBnZXRGUEVYVChFVlQgT3BWVCwgRVZUIFJldFZUKTsKKworICAvLy8gZ2V0RlBST1VORCAtIFJldHVybiB0aGUgRlBST1VORF8qXyogdmFsdWUgZm9yIHRoZSBnaXZlbiB0eXBlcywgb3IKKyAgLy8vIFVOS05PV05fTElCQ0FMTCBpZiB0aGVyZSBpcyBub25lLgorICBMaWJjYWxsIGdldEZQUk9VTkQoRVZUIE9wVlQsIEVWVCBSZXRWVCk7CisKKyAgLy8vIGdldEZQVE9TSU5UIC0gUmV0dXJuIHRoZSBGUFRPU0lOVF8qXyogdmFsdWUgZm9yIHRoZSBnaXZlbiB0eXBlcywgb3IKKyAgLy8vIFVOS05PV05fTElCQ0FMTCBpZiB0aGVyZSBpcyBub25lLgorICBMaWJjYWxsIGdldEZQVE9TSU5UKEVWVCBPcFZULCBFVlQgUmV0VlQpOworCisgIC8vLyBnZXRGUFRPVUlOVCAtIFJldHVybiB0aGUgRlBUT1VJTlRfKl8qIHZhbHVlIGZvciB0aGUgZ2l2ZW4gdHlwZXMsIG9yCisgIC8vLyBVTktOT1dOX0xJQkNBTEwgaWYgdGhlcmUgaXMgbm9uZS4KKyAgTGliY2FsbCBnZXRGUFRPVUlOVChFVlQgT3BWVCwgRVZUIFJldFZUKTsKKworICAvLy8gZ2V0U0lOVFRPRlAgLSBSZXR1cm4gdGhlIFNJTlRUT0ZQXypfKiB2YWx1ZSBmb3IgdGhlIGdpdmVuIHR5cGVzLCBvcgorICAvLy8gVU5LTk9XTl9MSUJDQUxMIGlmIHRoZXJlIGlzIG5vbmUuCisgIExpYmNhbGwgZ2V0U0lOVFRPRlAoRVZUIE9wVlQsIEVWVCBSZXRWVCk7CisKKyAgLy8vIGdldFVJTlRUT0ZQIC0gUmV0dXJuIHRoZSBVSU5UVE9GUF8qXyogdmFsdWUgZm9yIHRoZSBnaXZlbiB0eXBlcywgb3IKKyAgLy8vIFVOS05PV05fTElCQ0FMTCBpZiB0aGVyZSBpcyBub25lLgorICBMaWJjYWxsIGdldFVJTlRUT0ZQKEVWVCBPcFZULCBFVlQgUmV0VlQpOworCisgIC8vLyBSZXR1cm4gdGhlIFNZTkNfRkVUQ0hfQU5EXyogdmFsdWUgZm9yIHRoZSBnaXZlbiBvcGNvZGUgYW5kIHR5cGUsIG9yCisgIC8vLyBVTktOT1dOX0xJQkNBTEwgaWYgdGhlcmUgaXMgbm9uZS4KKyAgTGliY2FsbCBnZXRTWU5DKHVuc2lnbmVkIE9wYywgTVZUIFZUKTsKKworICAvLy8gZ2V0TUVNQ1BZX0VMRU1FTlRfVU5PUkRFUkVEX0FUT01JQyAtIFJldHVybgorICAvLy8gTUVNQ1BZX0VMRU1FTlRfVU5PUkRFUkVEX0FUT01JQ18qIHZhbHVlIGZvciB0aGUgZ2l2ZW4gZWxlbWVudCBzaXplIG9yCisgIC8vLyBVTktOT1dfTElCQ0FMTCBpZiB0aGVyZSBpcyBub25lLgorICBMaWJjYWxsIGdldE1FTUNQWV9FTEVNRU5UX1VOT1JERVJFRF9BVE9NSUModWludDY0X3QgRWxlbWVudFNpemUpOworCisgIC8vLyBnZXRNRU1NT1ZFX0VMRU1FTlRfVU5PUkRFUkVEX0FUT01JQyAtIFJldHVybgorICAvLy8gTUVNTU9WRV9FTEVNRU5UX1VOT1JERVJFRF9BVE9NSUNfKiB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVsZW1lbnQgc2l6ZSBvcgorICAvLy8gVU5LTk9XX0xJQkNBTEwgaWYgdGhlcmUgaXMgbm9uZS4KKyAgTGliY2FsbCBnZXRNRU1NT1ZFX0VMRU1FTlRfVU5PUkRFUkVEX0FUT01JQyh1aW50NjRfdCBFbGVtZW50U2l6ZSk7CisKKyAgLy8vIGdldE1FTVNFVF9FTEVNRU5UX1VOT1JERVJFRF9BVE9NSUMgLSBSZXR1cm4KKyAgLy8vIE1FTVNFVF9FTEVNRU5UX1VOT1JERVJFRF9BVE9NSUNfKiB2YWx1ZSBmb3IgdGhlIGdpdmVuIGVsZW1lbnQgc2l6ZSBvcgorICAvLy8gVU5LTk9XX0xJQkNBTEwgaWYgdGhlcmUgaXMgbm9uZS4KKyAgTGliY2FsbCBnZXRNRU1TRVRfRUxFTUVOVF9VTk9SREVSRURfQVRPTUlDKHVpbnQ2NF90IEVsZW1lbnRTaXplKTsKKworfQorfQorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TRE5vZGVQcm9wZXJ0aWVzLnRkIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NETm9kZVByb3BlcnRpZXMudGQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODNiYmFiMgotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TRE5vZGVQcm9wZXJ0aWVzLnRkCkBAIC0wLDAgKzEsMzQgQEAKKy8vPT09LSBTRE5vZGVQcm9wZXJ0aWVzLnRkIC0gQ29tbW9uIGNvZGUgZm9yIERBRyBpc2VscyAtLS0qLSB0YWJsZWdlbiAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCitjbGFzcyBTRE5vZGVQcm9wZXJ0eTsKKworLy8gU2VsZWN0aW9uIERBRyBQYXR0ZXJuIE9wZXJhdGlvbnMKK2NsYXNzIFNEUGF0dGVybk9wZXJhdG9yIHsKKyAgbGlzdDxTRE5vZGVQcm9wZXJ0eT4gUHJvcGVydGllcyA9IFtdOworfQorCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8gU2VsZWN0aW9uIERBRyBOb2RlIFByb3BlcnRpZXMuCisvLworLy8gTm90ZTogVGhlc2UgYXJlIGhhcmQgY29kZWQgaW50byB0YmxnZW4uCisvLworZGVmIFNETlBDb21tdXRhdGl2ZSA6IFNETm9kZVByb3BlcnR5OyAgIC8vIFggb3AgWSA9PSBZIG9wIFgKK2RlZiBTRE5QQXNzb2NpYXRpdmUgOiBTRE5vZGVQcm9wZXJ0eTsgICAvLyAoWCBvcCBZKSBvcCBaID09IFggb3AgKFkgb3AgWikKK2RlZiBTRE5QSGFzQ2hhaW4gICAgOiBTRE5vZGVQcm9wZXJ0eTsgICAvLyBSL1cgY2hhaW4gb3BlcmFuZCBhbmQgcmVzdWx0CitkZWYgU0ROUE91dEdsdWUgICAgIDogU0ROb2RlUHJvcGVydHk7ICAgLy8gV3JpdGUgYSBmbGFnIHJlc3VsdAorZGVmIFNETlBJbkdsdWUgICAgICA6IFNETm9kZVByb3BlcnR5OyAgIC8vIFJlYWQgYSBmbGFnIG9wZXJhbmQKK2RlZiBTRE5QT3B0SW5HbHVlICAgOiBTRE5vZGVQcm9wZXJ0eTsgICAvLyBPcHRpb25hbGx5IHJlYWQgYSBmbGFnIG9wZXJhbmQKK2RlZiBTRE5QTWF5U3RvcmUgICAgOiBTRE5vZGVQcm9wZXJ0eTsgICAvLyBNYXkgd3JpdGUgdG8gbWVtb3J5LCBzZXRzICdtYXlTdG9yZScuCitkZWYgU0ROUE1heUxvYWQgICAgIDogU0ROb2RlUHJvcGVydHk7ICAgLy8gTWF5IHJlYWQgbWVtb3J5LCBzZXRzICdtYXlMb2FkJy4KK2RlZiBTRE5QU2lkZUVmZmVjdCAgOiBTRE5vZGVQcm9wZXJ0eTsgICAvLyBTZXRzICdIYXNVbm1vZGVsbGVkU2lkZUVmZmVjdHMnLgorZGVmIFNETlBNZW1PcGVyYW5kICA6IFNETm9kZVByb3BlcnR5OyAgIC8vIFRvdWNoZXMgbWVtb3J5LCBoYXMgYXNzb2MgTWVtT3BlcmFuZAorZGVmIFNETlBWYXJpYWRpYyAgICA6IFNETm9kZVByb3BlcnR5OyAgIC8vIE5vZGUgaGFzIHZhcmlhYmxlIGFyZ3VtZW50cy4KK2RlZiBTRE5QV2FudFJvb3QgICAgOiBTRE5vZGVQcm9wZXJ0eTsgICAvLyBDb21wbGV4UGF0dGVybiBnZXRzIHRoZSByb290IG9mIG1hdGNoCitkZWYgU0ROUFdhbnRQYXJlbnQgIDogU0ROb2RlUHJvcGVydHk7ICAgLy8gQ29tcGxleFBhdHRlcm4gZ2V0cyB0aGUgcGFyZW50CmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vU2NoZWR1bGVEQUcuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TY2hlZHVsZURBRy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzZjJmMDUKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vU2NoZWR1bGVEQUcuaApAQCAtMCwwICsxLDc2NCBAQAorLy89PT0tIGxsdm0vQ29kZUdlbi9TY2hlZHVsZURBRy5oIC0gQ29tbW9uIEJhc2UgQ2xhc3MgLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLy8gXGZpbGUgSW1wbGVtZW50cyB0aGUgU2NoZWR1bGVEQUcgY2xhc3MsIHdoaWNoIGlzIHVzZWQgYXMgdGhlIGNvbW1vbiBiYXNlCisvLy8gY2xhc3MgZm9yIGluc3RydWN0aW9uIHNjaGVkdWxlcnMuIFRoaXMgZW5jYXBzdWxhdGVzIHRoZSBzY2hlZHVsaW5nIERBRywKKy8vLyB3aGljaCBpcyBzaGFyZWQgYmV0d2VlbiBTZWxlY3Rpb25EQUcgYW5kIE1hY2hpbmVJbnN0ciBzY2hlZHVsaW5nLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1NDSEVEVUxFREFHX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1NDSEVEVUxFREFHX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0JpdFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQURUL0dyYXBoVHJhaXRzLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvUG9pbnRlckludFBhaXIuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQURUL2l0ZXJhdG9yLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVJbnN0ci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9UYXJnZXRMb3dlcmluZy5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9FcnJvckhhbmRsaW5nLmgiCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkZGVmPgorI2luY2x1ZGUgPGl0ZXJhdG9yPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKK25hbWVzcGFjZSBsbHZtIHsKKwordGVtcGxhdGU8Y2xhc3MgR3JhcGg+IGNsYXNzIEdyYXBoV3JpdGVyOworY2xhc3MgTWFjaGluZUZ1bmN0aW9uOworY2xhc3MgTWFjaGluZVJlZ2lzdGVySW5mbzsKK2NsYXNzIE1DSW5zdHJEZXNjOworc3RydWN0IE1DU2NoZWRDbGFzc0Rlc2M7CitjbGFzcyBTY2hlZHVsZURBRzsKK2NsYXNzIFNETm9kZTsKK2NsYXNzIFNVbml0OworY2xhc3MgVGFyZ2V0SW5zdHJJbmZvOworY2xhc3MgVGFyZ2V0TWFjaGluZTsKK2NsYXNzIFRhcmdldFJlZ2lzdGVyQ2xhc3M7CitjbGFzcyBUYXJnZXRSZWdpc3RlckluZm87CisKKyAgLy8vIFNjaGVkdWxpbmcgZGVwZW5kZW5jeS4gVGhpcyByZXByZXNlbnRzIG9uZSBkaXJlY3Rpb24gb2YgYW4gZWRnZSBpbiB0aGUKKyAgLy8vIHNjaGVkdWxpbmcgREFHLgorICBjbGFzcyBTRGVwIHsKKyAgcHVibGljOgorICAgIC8vLyBUaGVzZSBhcmUgdGhlIGRpZmZlcmVudCBraW5kcyBvZiBzY2hlZHVsaW5nIGRlcGVuZGVuY2llcy4KKyAgICBlbnVtIEtpbmQgeworICAgICAgRGF0YSwgICAgICAgIC8vLzwgUmVndWxhciBkYXRhIGRlcGVuZGVuY2UgKGFrYSB0cnVlLWRlcGVuZGVuY2UpLgorICAgICAgQW50aSwgICAgICAgIC8vLzwgQSByZWdpc3RlciBhbnRpLWRlcGVuZGVuY2UgKGFrYSBXQVIpLgorICAgICAgT3V0cHV0LCAgICAgIC8vLzwgQSByZWdpc3RlciBvdXRwdXQtZGVwZW5kZW5jZSAoYWthIFdBVykuCisgICAgICBPcmRlciAgICAgICAgLy8vPCBBbnkgb3RoZXIgb3JkZXJpbmcgZGVwZW5kZW5jeS4KKyAgICB9OworCisgICAgLy8gU3Ryb25nIGRlcGVuZGVuY2llcyBtdXN0IGJlIHJlc3BlY3RlZCBieSB0aGUgc2NoZWR1bGVyLiBBcnRpZmljaWFsCisgICAgLy8gZGVwZW5kZW5jaWVzIG1heSBiZSByZW1vdmVkIG9ubHkgaWYgdGhleSBhcmUgcmVkdW5kYW50IHdpdGggYW5vdGhlcgorICAgIC8vIHN0cm9uZyBkZXBlbmRlbmNlLgorICAgIC8vCisgICAgLy8gV2VhayBkZXBlbmRlbmNpZXMgbWF5IGJlIHZpb2xhdGVkIGJ5IHRoZSBzY2hlZHVsaW5nIHN0cmF0ZWd5LCBidXQgb25seSBpZgorICAgIC8vIHRoZSBzdHJhdGVneSBjYW4gcHJvdmUgaXQgaXMgY29ycmVjdCB0byBkbyBzby4KKyAgICAvLworICAgIC8vIFN0cm9uZyBPcmRlcktpbmRzIG11c3Qgb2NjdXIgYmVmb3JlICJXZWFrIi4KKyAgICAvLyBXZWFrIE9yZGVyS2luZHMgbXVzdCBvY2N1ciBhZnRlciAiV2VhayIuCisgICAgZW51bSBPcmRlcktpbmQgeworICAgICAgQmFycmllciwgICAgICAvLy88IEFuIHVua25vd24gc2NoZWR1bGluZyBiYXJyaWVyLgorICAgICAgTWF5QWxpYXNNZW0sICAvLy88IE5vbnZvbGF0aWxlIGxvYWQvU3RvcmUgaW5zdHJ1Y3Rpb25zIHRoYXQgbWF5IGFsaWFzLgorICAgICAgTXVzdEFsaWFzTWVtLCAvLy88IE5vbnZvbGF0aWxlIGxvYWQvU3RvcmUgaW5zdHJ1Y3Rpb25zIHRoYXQgbXVzdCBhbGlhcy4KKyAgICAgIEFydGlmaWNpYWwsICAgLy8vPCBBcmJpdHJhcnkgc3Ryb25nIERBRyBlZGdlIChubyByZWFsIGRlcGVuZGVuY2UpLgorICAgICAgV2VhaywgICAgICAgICAvLy88IEFyYml0cmFyeSB3ZWFrIERBRyBlZGdlLgorICAgICAgQ2x1c3RlciAgICAgICAvLy88IFdlYWsgREFHIGVkZ2UgbGlua2luZyBhIGNoYWluIG9mIGNsdXN0ZXJlZCBpbnN0cnMuCisgICAgfTsKKworICBwcml2YXRlOgorICAgIC8vLyBcYnJpZWYgQSBwb2ludGVyIHRvIHRoZSBkZXBlbmRpbmcvZGVwZW5kZWQtb24gU1VuaXQsIGFuZCBhbiBlbnVtCisgICAgLy8vIGluZGljYXRpbmcgdGhlIGtpbmQgb2YgdGhlIGRlcGVuZGVuY3kuCisgICAgUG9pbnRlckludFBhaXI8U1VuaXQgKiwgMiwgS2luZD4gRGVwOworCisgICAgLy8vIEEgdW5pb24gZGlzY3JpbWluYXRlZCBieSB0aGUgZGVwZW5kZW5jZSBraW5kLgorICAgIHVuaW9uIHsKKyAgICAgIC8vLyBGb3IgRGF0YSwgQW50aSwgYW5kIE91dHB1dCBkZXBlbmRlbmNpZXMsIHRoZSBhc3NvY2lhdGVkIHJlZ2lzdGVyLiBGb3IKKyAgICAgIC8vLyBEYXRhIGRlcGVuZGVuY2llcyB0aGF0IGRvbid0IGN1cnJlbnRseSBoYXZlIGEgcmVnaXN0ZXIvIGFzc2lnbmVkLCB0aGlzCisgICAgICAvLy8gaXMgc2V0IHRvIHplcm8uCisgICAgICB1bnNpZ25lZCBSZWc7CisKKyAgICAgIC8vLyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uIGFib3V0IE9yZGVyIGRlcGVuZGVuY2llcy4KKyAgICAgIHVuc2lnbmVkIE9yZEtpbmQ7IC8vIGVudW0gT3JkZXJLaW5kCisgICAgfSBDb250ZW50czsKKworICAgIC8vLyBUaGUgdGltZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBlZGdlLiBPZnRlbiB0aGlzIGlzIGp1c3QgdGhlIHZhbHVlIG9mIHRoZQorICAgIC8vLyBMYXRlbmN5IGZpZWxkIG9mIHRoZSBwcmVkZWNlc3NvciwgaG93ZXZlciBhZHZhbmNlZCBtb2RlbHMgbWF5IHByb3ZpZGUKKyAgICAvLy8gYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBhYm91dCBzcGVjaWZpYyBlZGdlcy4KKyAgICB1bnNpZ25lZCBMYXRlbmN5OworCisgIHB1YmxpYzoKKyAgICAvLy8gQ29uc3RydWN0cyBhIG51bGwgU0RlcC4gVGhpcyBpcyBvbmx5IGZvciB1c2UgYnkgY29udGFpbmVyIGNsYXNzZXMgd2hpY2gKKyAgICAvLy8gcmVxdWlyZSBkZWZhdWx0IGNvbnN0cnVjdG9ycy4gU1VuaXRzIG1heSBub3QvIGhhdmUgbnVsbCBTRGVwIGVkZ2VzLgorICAgIFNEZXAoKSA6IERlcChudWxscHRyLCBEYXRhKSB7fQorCisgICAgLy8vIENvbnN0cnVjdHMgYW4gU0RlcCB3aXRoIHRoZSBzcGVjaWZpZWQgdmFsdWVzLgorICAgIFNEZXAoU1VuaXQgKlMsIEtpbmQga2luZCwgdW5zaWduZWQgUmVnKQorICAgICAgOiBEZXAoUywga2luZCksIENvbnRlbnRzKCkgeworICAgICAgc3dpdGNoIChraW5kKSB7CisgICAgICBkZWZhdWx0OgorICAgICAgICBsbHZtX3VucmVhY2hhYmxlKCJSZWcgZ2l2ZW4gZm9yIG5vbi1yZWdpc3RlciBkZXBlbmRlbmNlISIpOworICAgICAgY2FzZSBBbnRpOgorICAgICAgY2FzZSBPdXRwdXQ6CisgICAgICAgIGFzc2VydChSZWcgIT0gMCAmJgorICAgICAgICAgICAgICAgIlNEZXA6OkFudGkgYW5kIFNEZXA6Ok91dHB1dCBtdXN0IHVzZSBhIG5vbi16ZXJvIFJlZyEiKTsKKyAgICAgICAgQ29udGVudHMuUmVnID0gUmVnOworICAgICAgICBMYXRlbmN5ID0gMDsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIERhdGE6CisgICAgICAgIENvbnRlbnRzLlJlZyA9IFJlZzsKKyAgICAgICAgTGF0ZW5jeSA9IDE7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKworICAgIFNEZXAoU1VuaXQgKlMsIE9yZGVyS2luZCBraW5kKQorICAgICAgOiBEZXAoUywgT3JkZXIpLCBDb250ZW50cygpLCBMYXRlbmN5KDApIHsKKyAgICAgIENvbnRlbnRzLk9yZEtpbmQgPSBraW5kOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBTRGVwIGlzIGVxdWl2YWxlbnQgZXhjZXB0IGZvciBsYXRlbmN5LgorICAgIGJvb2wgb3ZlcmxhcHMoY29uc3QgU0RlcCAmT3RoZXIpIGNvbnN0OworCisgICAgYm9vbCBvcGVyYXRvcj09KGNvbnN0IFNEZXAgJk90aGVyKSBjb25zdCB7CisgICAgICByZXR1cm4gb3ZlcmxhcHMoT3RoZXIpICYmIExhdGVuY3kgPT0gT3RoZXIuTGF0ZW5jeTsKKyAgICB9CisKKyAgICBib29sIG9wZXJhdG9yIT0oY29uc3QgU0RlcCAmT3RoZXIpIGNvbnN0IHsKKyAgICAgIHJldHVybiAhb3BlcmF0b3I9PShPdGhlcik7CisgICAgfQorCisgICAgLy8vIFxicmllZiBSZXR1cm5zIHRoZSBsYXRlbmN5IHZhbHVlIGZvciB0aGlzIGVkZ2UsIHdoaWNoIHJvdWdobHkgbWVhbnMgdGhlCisgICAgLy8vIG1pbmltdW0gbnVtYmVyIG9mIGN5Y2xlcyB0aGF0IG11c3QgZWxhcHNlIGJldHdlZW4gdGhlIHByZWRlY2Vzc29yIGFuZAorICAgIC8vLyB0aGUgc3VjY2Vzc29yLCBnaXZlbiB0aGF0IHRoZXkgaGF2ZSB0aGlzIGVkZ2UgYmV0d2VlbiB0aGVtLgorICAgIHVuc2lnbmVkIGdldExhdGVuY3koKSBjb25zdCB7CisgICAgICByZXR1cm4gTGF0ZW5jeTsKKyAgICB9CisKKyAgICAvLy8gU2V0cyB0aGUgbGF0ZW5jeSBmb3IgdGhpcyBlZGdlLgorICAgIHZvaWQgc2V0TGF0ZW5jeSh1bnNpZ25lZCBMYXQpIHsKKyAgICAgIExhdGVuY3kgPSBMYXQ7CisgICAgfQorCisgICAgLy8vLyBSZXR1cm5zIHRoZSBTVW5pdCB0byB3aGljaCB0aGlzIGVkZ2UgcG9pbnRzLgorICAgIFNVbml0ICpnZXRTVW5pdCgpIGNvbnN0OworCisgICAgLy8vLyBBc3NpZ25zIHRoZSBTVW5pdCB0byB3aGljaCB0aGlzIGVkZ2UgcG9pbnRzLgorICAgIHZvaWQgc2V0U1VuaXQoU1VuaXQgKlNVKTsKKworICAgIC8vLyBSZXR1cm5zIGFuIGVudW0gdmFsdWUgcmVwcmVzZW50aW5nIHRoZSBraW5kIG9mIHRoZSBkZXBlbmRlbmNlLgorICAgIEtpbmQgZ2V0S2luZCgpIGNvbnN0OworCisgICAgLy8vIFNob3J0aGFuZCBmb3IgZ2V0S2luZCgpICE9IFNEZXA6OkRhdGEuCisgICAgYm9vbCBpc0N0cmwoKSBjb25zdCB7CisgICAgICByZXR1cm4gZ2V0S2luZCgpICE9IERhdGE7CisgICAgfQorCisgICAgLy8vIFxicmllZiBUZXN0cyBpZiB0aGlzIGlzIGFuIE9yZGVyIGRlcGVuZGVuY2UgYmV0d2VlbiB0d28gbWVtb3J5IGFjY2Vzc2VzCisgICAgLy8vIHdoZXJlIGJvdGggc2lkZXMgb2YgdGhlIGRlcGVuZGVuY2UgYWNjZXNzIG1lbW9yeSBpbiBub24tdm9sYXRpbGUgYW5kCisgICAgLy8vIGZ1bGx5IG1vZGVsZWQgd2F5cy4KKyAgICBib29sIGlzTm9ybWFsTWVtb3J5KCkgY29uc3QgeworICAgICAgcmV0dXJuIGdldEtpbmQoKSA9PSBPcmRlciAmJiAoQ29udGVudHMuT3JkS2luZCA9PSBNYXlBbGlhc01lbQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgQ29udGVudHMuT3JkS2luZCA9PSBNdXN0QWxpYXNNZW0pOworICAgIH0KKworICAgIC8vLyBUZXN0cyBpZiB0aGlzIGlzIGFuIE9yZGVyIGRlcGVuZGVuY2UgdGhhdCBpcyBtYXJrZWQgYXMgYSBiYXJyaWVyLgorICAgIGJvb2wgaXNCYXJyaWVyKCkgY29uc3QgeworICAgICAgcmV0dXJuIGdldEtpbmQoKSA9PSBPcmRlciAmJiBDb250ZW50cy5PcmRLaW5kID09IEJhcnJpZXI7CisgICAgfQorCisgICAgLy8vIFRlc3RzIGlmIHRoaXMgaXMgY291bGQgYmUgYW55IGtpbmQgb2YgbWVtb3J5IGRlcGVuZGVuY2UuCisgICAgYm9vbCBpc05vcm1hbE1lbW9yeU9yQmFycmllcigpIGNvbnN0IHsKKyAgICAgIHJldHVybiAoaXNOb3JtYWxNZW1vcnkoKSB8fCBpc0JhcnJpZXIoKSk7CisgICAgfQorCisgICAgLy8vIFxicmllZiBUZXN0cyBpZiB0aGlzIGlzIGFuIE9yZGVyIGRlcGVuZGVuY2UgdGhhdCBpcyBtYXJrZWQgYXMKKyAgICAvLy8gIm11c3QgYWxpYXMiLCBtZWFuaW5nIHRoYXQgdGhlIFNVbml0cyBhdCBlaXRoZXIgZW5kIG9mIHRoZSBlZGdlIGhhdmUgYQorICAgIC8vLyBtZW1vcnkgZGVwZW5kZW5jZSBvbiBhIGtub3duIG1lbW9yeSBsb2NhdGlvbi4KKyAgICBib29sIGlzTXVzdEFsaWFzKCkgY29uc3QgeworICAgICAgcmV0dXJuIGdldEtpbmQoKSA9PSBPcmRlciAmJiBDb250ZW50cy5PcmRLaW5kID09IE11c3RBbGlhc01lbTsKKyAgICB9CisKKyAgICAvLy8gVGVzdHMgaWYgdGhpcyBhIHdlYWsgZGVwZW5kZW5jZS4gV2VhayBkZXBlbmRlbmNpZXMgYXJlIGNvbnNpZGVyZWQgREFHCisgICAgLy8vIGVkZ2VzIGZvciBoZWlnaHQgY29tcHV0YXRpb24gYW5kIG90aGVyIGhldXJpc3RpY3MsIGJ1dCBkbyBub3QgZm9yY2UKKyAgICAvLy8gb3JkZXJpbmcuIEJyZWFraW5nIGEgd2VhayBlZGdlIG1heSByZXF1aXJlIHRoZSBzY2hlZHVsZXIgdG8gY29tcGVuc2F0ZSwKKyAgICAvLy8gZm9yIGV4YW1wbGUgYnkgaW5zZXJ0aW5nIGEgY29weS4KKyAgICBib29sIGlzV2VhaygpIGNvbnN0IHsKKyAgICAgIHJldHVybiBnZXRLaW5kKCkgPT0gT3JkZXIgJiYgQ29udGVudHMuT3JkS2luZCA+PSBXZWFrOworICAgIH0KKworICAgIC8vLyBcYnJpZWYgVGVzdHMgaWYgdGhpcyBpcyBhbiBPcmRlciBkZXBlbmRlbmNlIHRoYXQgaXMgbWFya2VkIGFzCisgICAgLy8vICJhcnRpZmljaWFsIiwgbWVhbmluZyBpdCBpc24ndCBuZWNlc3NhcnkgZm9yIGNvcnJlY3RuZXNzLgorICAgIGJvb2wgaXNBcnRpZmljaWFsKCkgY29uc3QgeworICAgICAgcmV0dXJuIGdldEtpbmQoKSA9PSBPcmRlciAmJiBDb250ZW50cy5PcmRLaW5kID09IEFydGlmaWNpYWw7CisgICAgfQorCisgICAgLy8vIFxicmllZiBUZXN0cyBpZiB0aGlzIGlzIGFuIE9yZGVyIGRlcGVuZGVuY2UgdGhhdCBpcyBtYXJrZWQgYXMgImNsdXN0ZXIiLAorICAgIC8vLyBtZWFuaW5nIGl0IGlzIGFydGlmaWNpYWwgYW5kIHdhbnRzIHRvIGJlIGFkamFjZW50LgorICAgIGJvb2wgaXNDbHVzdGVyKCkgY29uc3QgeworICAgICAgcmV0dXJuIGdldEtpbmQoKSA9PSBPcmRlciAmJiBDb250ZW50cy5PcmRLaW5kID09IENsdXN0ZXI7CisgICAgfQorCisgICAgLy8vIFRlc3RzIGlmIHRoaXMgaXMgYSBEYXRhIGRlcGVuZGVuY2UgdGhhdCBpcyBhc3NvY2lhdGVkIHdpdGggYSByZWdpc3Rlci4KKyAgICBib29sIGlzQXNzaWduZWRSZWdEZXAoKSBjb25zdCB7CisgICAgICByZXR1cm4gZ2V0S2luZCgpID09IERhdGEgJiYgQ29udGVudHMuUmVnICE9IDA7CisgICAgfQorCisgICAgLy8vIFJldHVybnMgdGhlIHJlZ2lzdGVyIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGVkZ2UuIFRoaXMgaXMgb25seSB2YWxpZCBvbgorICAgIC8vLyBEYXRhLCBBbnRpLCBhbmQgT3V0cHV0IGVkZ2VzLiBPbiBEYXRhIGVkZ2VzLCB0aGlzIHZhbHVlIG1heSBiZSB6ZXJvLAorICAgIC8vLyBtZWFuaW5nIHRoZXJlIGlzIG5vIGFzc29jaWF0ZWQgcmVnaXN0ZXIuCisgICAgdW5zaWduZWQgZ2V0UmVnKCkgY29uc3QgeworICAgICAgYXNzZXJ0KChnZXRLaW5kKCkgPT0gRGF0YSB8fCBnZXRLaW5kKCkgPT0gQW50aSB8fCBnZXRLaW5kKCkgPT0gT3V0cHV0KSAmJgorICAgICAgICAgICAgICJnZXRSZWcgY2FsbGVkIG9uIG5vbi1yZWdpc3RlciBkZXBlbmRlbmNlIGVkZ2UhIik7CisgICAgICByZXR1cm4gQ29udGVudHMuUmVnOworICAgIH0KKworICAgIC8vLyBBc3NpZ25zIHRoZSBhc3NvY2lhdGVkIHJlZ2lzdGVyIGZvciB0aGlzIGVkZ2UuIFRoaXMgaXMgb25seSB2YWxpZCBvbgorICAgIC8vLyBEYXRhLCBBbnRpLCBhbmQgT3V0cHV0IGVkZ2VzLiBPbiBBbnRpIGFuZCBPdXRwdXQgZWRnZXMsIHRoaXMgdmFsdWUgbXVzdAorICAgIC8vLyBub3QgYmUgemVyby4gT24gRGF0YSBlZGdlcywgdGhlIHZhbHVlIG1heSBiZSB6ZXJvLCB3aGljaCB3b3VsZCBtZWFuIHRoYXQKKyAgICAvLy8gbm8gc3BlY2lmaWMgcmVnaXN0ZXIgaXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZWRnZS4KKyAgICB2b2lkIHNldFJlZyh1bnNpZ25lZCBSZWcpIHsKKyAgICAgIGFzc2VydCgoZ2V0S2luZCgpID09IERhdGEgfHwgZ2V0S2luZCgpID09IEFudGkgfHwgZ2V0S2luZCgpID09IE91dHB1dCkgJiYKKyAgICAgICAgICAgICAic2V0UmVnIGNhbGxlZCBvbiBub24tcmVnaXN0ZXIgZGVwZW5kZW5jZSBlZGdlISIpOworICAgICAgYXNzZXJ0KChnZXRLaW5kKCkgIT0gQW50aSB8fCBSZWcgIT0gMCkgJiYKKyAgICAgICAgICAgICAiU0RlcDo6QW50aSBlZGdlIGNhbm5vdCB1c2UgdGhlIHplcm8gcmVnaXN0ZXIhIik7CisgICAgICBhc3NlcnQoKGdldEtpbmQoKSAhPSBPdXRwdXQgfHwgUmVnICE9IDApICYmCisgICAgICAgICAgICAgIlNEZXA6Ok91dHB1dCBlZGdlIGNhbm5vdCB1c2UgdGhlIHplcm8gcmVnaXN0ZXIhIik7CisgICAgICBDb250ZW50cy5SZWcgPSBSZWc7CisgICAgfQorCisgICAgcmF3X29zdHJlYW0gJnByaW50KHJhd19vc3RyZWFtICZPLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSA9IG51bGxwdHIpIGNvbnN0OworICB9OworCisgIHRlbXBsYXRlIDw+CisgIHN0cnVjdCBpc1BvZExpa2U8U0RlcD4geyBzdGF0aWMgY29uc3QgYm9vbCB2YWx1ZSA9IHRydWU7IH07CisKKyAgLy8vIFNjaGVkdWxpbmcgdW5pdC4gVGhpcyBpcyBhIG5vZGUgaW4gdGhlIHNjaGVkdWxpbmcgREFHLgorICBjbGFzcyBTVW5pdCB7CisgIHByaXZhdGU6CisgICAgZW51bSA6IHVuc2lnbmVkIHsgQm91bmRhcnlJRCA9IH4wdSB9OworCisgICAgU0ROb2RlICpOb2RlID0gbnVsbHB0cjsgICAgICAgIC8vLzwgUmVwcmVzZW50YXRpdmUgbm9kZS4KKyAgICBNYWNoaW5lSW5zdHIgKkluc3RyID0gbnVsbHB0cjsgLy8vPCBBbHRlcm5hdGl2ZWx5LCBhIE1hY2hpbmVJbnN0ci4KKworICBwdWJsaWM6CisgICAgU1VuaXQgKk9yaWdOb2RlID0gbnVsbHB0cjsgLy8vPCBJZiBub3QgdGhpcywgdGhlIG5vZGUgZnJvbSB3aGljaCB0aGlzIG5vZGUgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8vIHdhcyBjbG9uZWQuIChTRCBzY2hlZHVsaW5nIG9ubHkpCisKKyAgICBjb25zdCBNQ1NjaGVkQ2xhc3NEZXNjICpTY2hlZENsYXNzID0KKyAgICAgICAgbnVsbHB0cjsgLy8vPCBudWxscHRyIG9yIHJlc29sdmVkIFNjaGVkQ2xhc3MuCisKKyAgICBTbWFsbFZlY3RvcjxTRGVwLCA0PiBQcmVkczsgIC8vLzwgQWxsIHN1bml0IHByZWRlY2Vzc29ycy4KKyAgICBTbWFsbFZlY3RvcjxTRGVwLCA0PiBTdWNjczsgIC8vLzwgQWxsIHN1bml0IHN1Y2Nlc3NvcnMuCisKKyAgICB0eXBlZGVmIFNtYWxsVmVjdG9ySW1wbDxTRGVwPjo6aXRlcmF0b3IgcHJlZF9pdGVyYXRvcjsKKyAgICB0eXBlZGVmIFNtYWxsVmVjdG9ySW1wbDxTRGVwPjo6aXRlcmF0b3Igc3VjY19pdGVyYXRvcjsKKyAgICB0eXBlZGVmIFNtYWxsVmVjdG9ySW1wbDxTRGVwPjo6Y29uc3RfaXRlcmF0b3IgY29uc3RfcHJlZF9pdGVyYXRvcjsKKyAgICB0eXBlZGVmIFNtYWxsVmVjdG9ySW1wbDxTRGVwPjo6Y29uc3RfaXRlcmF0b3IgY29uc3Rfc3VjY19pdGVyYXRvcjsKKworICAgIHVuc2lnbmVkIE5vZGVOdW0gPSBCb3VuZGFyeUlEOyAgICAgLy8vPCBFbnRyeSAjIG9mIG5vZGUgaW4gdGhlIG5vZGUgdmVjdG9yLgorICAgIHVuc2lnbmVkIE5vZGVRdWV1ZUlkID0gMDsgICAgICAgICAgLy8vPCBRdWV1ZSBpZCBvZiBub2RlLgorICAgIHVuc2lnbmVkIE51bVByZWRzID0gMDsgICAgICAgICAgICAgLy8vPCAjIG9mIFNEZXA6OkRhdGEgcHJlZHMuCisgICAgdW5zaWduZWQgTnVtU3VjY3MgPSAwOyAgICAgICAgICAgICAvLy88ICMgb2YgU0RlcDo6RGF0YSBzdWNzcy4KKyAgICB1bnNpZ25lZCBOdW1QcmVkc0xlZnQgPSAwOyAgICAgICAgIC8vLzwgIyBvZiBwcmVkcyBub3Qgc2NoZWR1bGVkLgorICAgIHVuc2lnbmVkIE51bVN1Y2NzTGVmdCA9IDA7ICAgICAgICAgLy8vPCAjIG9mIHN1Y2NzIG5vdCBzY2hlZHVsZWQuCisgICAgdW5zaWduZWQgV2Vha1ByZWRzTGVmdCA9IDA7ICAgICAgICAvLy88ICMgb2Ygd2VhayBwcmVkcyBub3Qgc2NoZWR1bGVkLgorICAgIHVuc2lnbmVkIFdlYWtTdWNjc0xlZnQgPSAwOyAgICAgICAgLy8vPCAjIG9mIHdlYWsgc3VjY3Mgbm90IHNjaGVkdWxlZC4KKyAgICB1bnNpZ25lZCBzaG9ydCBOdW1SZWdEZWZzTGVmdCA9IDA7IC8vLzwgIyBvZiByZWcgZGVmcyB3aXRoIG5vIHNjaGVkdWxlZCB1c2UuCisgICAgdW5zaWduZWQgc2hvcnQgTGF0ZW5jeSA9IDA7ICAgICAgICAvLy88IE5vZGUgbGF0ZW5jeS4KKyAgICBib29sIGlzVlJlZ0N5Y2xlICAgICAgOiAxOyAgICAgICAgIC8vLzwgTWF5IHVzZSBhbmQgZGVmIHRoZSBzYW1lIHZyZWcuCisgICAgYm9vbCBpc0NhbGwgICAgICAgICAgIDogMTsgICAgICAgICAvLy88IElzIGEgZnVuY3Rpb24gY2FsbC4KKyAgICBib29sIGlzQ2FsbE9wICAgICAgICAgOiAxOyAgICAgICAgIC8vLzwgSXMgYSBmdW5jdGlvbiBjYWxsIG9wZXJhbmQuCisgICAgYm9vbCBpc1R3b0FkZHJlc3MgICAgIDogMTsgICAgICAgICAvLy88IElzIGEgdHdvLWFkZHJlc3MgaW5zdHJ1Y3Rpb24uCisgICAgYm9vbCBpc0NvbW11dGFibGUgICAgIDogMTsgICAgICAgICAvLy88IElzIGEgY29tbXV0YWJsZSBpbnN0cnVjdGlvbi4KKyAgICBib29sIGhhc1BoeXNSZWdVc2VzICAgOiAxOyAgICAgICAgIC8vLzwgSGFzIHBoeXNyZWcgdXNlcy4KKyAgICBib29sIGhhc1BoeXNSZWdEZWZzICAgOiAxOyAgICAgICAgIC8vLzwgSGFzIHBoeXNyZWcgZGVmcyB0aGF0IGFyZSBiZWluZyB1c2VkLgorICAgIGJvb2wgaGFzUGh5c1JlZ0Nsb2JiZXJzIDogMTsgICAgICAgLy8vPCBIYXMgYW55IHBoeXNyZWcgZGVmcywgdXNlZCBvciBub3QuCisgICAgYm9vbCBpc1BlbmRpbmcgICAgICAgIDogMTsgICAgICAgICAvLy88IFRydWUgb25jZSBwZW5kaW5nLgorICAgIGJvb2wgaXNBdmFpbGFibGUgICAgICA6IDE7ICAgICAgICAgLy8vPCBUcnVlIG9uY2UgYXZhaWxhYmxlLgorICAgIGJvb2wgaXNTY2hlZHVsZWQgICAgICA6IDE7ICAgICAgICAgLy8vPCBUcnVlIG9uY2Ugc2NoZWR1bGVkLgorICAgIGJvb2wgaXNTY2hlZHVsZUhpZ2ggICA6IDE7ICAgICAgICAgLy8vPCBUcnVlIGlmIHByZWZlcmFibGUgdG8gc2NoZWR1bGUgaGlnaC4KKyAgICBib29sIGlzU2NoZWR1bGVMb3cgICAgOiAxOyAgICAgICAgIC8vLzwgVHJ1ZSBpZiBwcmVmZXJhYmxlIHRvIHNjaGVkdWxlIGxvdy4KKyAgICBib29sIGlzQ2xvbmVkICAgICAgICAgOiAxOyAgICAgICAgIC8vLzwgVHJ1ZSBpZiB0aGlzIG5vZGUgaGFzIGJlZW4gY2xvbmVkLgorICAgIGJvb2wgaXNVbmJ1ZmZlcmVkICAgICA6IDE7ICAgICAgICAgLy8vPCBVc2VzIGFuIHVuYnVmZmVyZWQgcmVzb3VyY2UuCisgICAgYm9vbCBoYXNSZXNlcnZlZFJlc291cmNlIDogMTsgICAgICAvLy88IFVzZXMgYSByZXNlcnZlZCByZXNvdXJjZS4KKyAgICBTY2hlZDo6UHJlZmVyZW5jZSBTY2hlZHVsaW5nUHJlZiA9IFNjaGVkOjpOb25lOyAvLy88IFNjaGVkdWxpbmcgcHJlZmVyZW5jZS4KKworICBwcml2YXRlOgorICAgIGJvb2wgaXNEZXB0aEN1cnJlbnQgICA6IDE7ICAgICAgICAgLy8vPCBUcnVlIGlmIERlcHRoIGlzIGN1cnJlbnQuCisgICAgYm9vbCBpc0hlaWdodEN1cnJlbnQgIDogMTsgICAgICAgICAvLy88IFRydWUgaWYgSGVpZ2h0IGlzIGN1cnJlbnQuCisgICAgdW5zaWduZWQgRGVwdGggPSAwOyAgICAgICAgICAgICAgICAvLy88IE5vZGUgZGVwdGguCisgICAgdW5zaWduZWQgSGVpZ2h0ID0gMDsgICAgICAgICAgICAgICAvLy88IE5vZGUgaGVpZ2h0LgorCisgIHB1YmxpYzoKKyAgICB1bnNpZ25lZCBUb3BSZWFkeUN5Y2xlID0gMDsgLy8vPCBDeWNsZSByZWxhdGl2ZSB0byBzdGFydCB3aGVuIG5vZGUgaXMgcmVhZHkuCisgICAgdW5zaWduZWQgQm90UmVhZHlDeWNsZSA9IDA7IC8vLzwgQ3ljbGUgcmVsYXRpdmUgdG8gZW5kIHdoZW4gbm9kZSBpcyByZWFkeS4KKworICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKkNvcHlEc3RSQyA9CisgICAgICAgIG51bGxwdHI7IC8vLzwgSXMgYSBzcGVjaWFsIGNvcHkgbm9kZSBpZiAhPSBudWxscHRyLgorICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKkNvcHlTcmNSQyA9IG51bGxwdHI7CisKKyAgICAvLy8gXGJyaWVmIENvbnN0cnVjdHMgYW4gU1VuaXQgZm9yIHByZS1yZWdhbGxvYyBzY2hlZHVsaW5nIHRvIHJlcHJlc2VudCBhbgorICAgIC8vLyBTRE5vZGUgYW5kIGFueSBub2RlcyBmbGFnZ2VkIHRvIGl0LgorICAgIFNVbml0KFNETm9kZSAqbm9kZSwgdW5zaWduZWQgbm9kZW51bSkKKyAgICAgIDogTm9kZShub2RlKSwgTm9kZU51bShub2RlbnVtKSwgaXNWUmVnQ3ljbGUoZmFsc2UpLCBpc0NhbGwoZmFsc2UpLAorICAgICAgICBpc0NhbGxPcChmYWxzZSksIGlzVHdvQWRkcmVzcyhmYWxzZSksIGlzQ29tbXV0YWJsZShmYWxzZSksCisgICAgICAgIGhhc1BoeXNSZWdVc2VzKGZhbHNlKSwgaGFzUGh5c1JlZ0RlZnMoZmFsc2UpLCBoYXNQaHlzUmVnQ2xvYmJlcnMoZmFsc2UpLAorICAgICAgICBpc1BlbmRpbmcoZmFsc2UpLCBpc0F2YWlsYWJsZShmYWxzZSksIGlzU2NoZWR1bGVkKGZhbHNlKSwKKyAgICAgICAgaXNTY2hlZHVsZUhpZ2goZmFsc2UpLCBpc1NjaGVkdWxlTG93KGZhbHNlKSwgaXNDbG9uZWQoZmFsc2UpLAorICAgICAgICBpc1VuYnVmZmVyZWQoZmFsc2UpLCBoYXNSZXNlcnZlZFJlc291cmNlKGZhbHNlKSwgaXNEZXB0aEN1cnJlbnQoZmFsc2UpLAorICAgICAgICBpc0hlaWdodEN1cnJlbnQoZmFsc2UpIHt9CisKKyAgICAvLy8gXGJyaWVmIENvbnN0cnVjdHMgYW4gU1VuaXQgZm9yIHBvc3QtcmVnYWxsb2Mgc2NoZWR1bGluZyB0byByZXByZXNlbnQgYQorICAgIC8vLyBNYWNoaW5lSW5zdHIuCisgICAgU1VuaXQoTWFjaGluZUluc3RyICppbnN0ciwgdW5zaWduZWQgbm9kZW51bSkKKyAgICAgIDogSW5zdHIoaW5zdHIpLCBOb2RlTnVtKG5vZGVudW0pLCBpc1ZSZWdDeWNsZShmYWxzZSksIGlzQ2FsbChmYWxzZSksCisgICAgICAgIGlzQ2FsbE9wKGZhbHNlKSwgaXNUd29BZGRyZXNzKGZhbHNlKSwgaXNDb21tdXRhYmxlKGZhbHNlKSwKKyAgICAgICAgaGFzUGh5c1JlZ1VzZXMoZmFsc2UpLCBoYXNQaHlzUmVnRGVmcyhmYWxzZSksIGhhc1BoeXNSZWdDbG9iYmVycyhmYWxzZSksCisgICAgICAgIGlzUGVuZGluZyhmYWxzZSksIGlzQXZhaWxhYmxlKGZhbHNlKSwgaXNTY2hlZHVsZWQoZmFsc2UpLAorICAgICAgICBpc1NjaGVkdWxlSGlnaChmYWxzZSksIGlzU2NoZWR1bGVMb3coZmFsc2UpLCBpc0Nsb25lZChmYWxzZSksCisgICAgICAgIGlzVW5idWZmZXJlZChmYWxzZSksIGhhc1Jlc2VydmVkUmVzb3VyY2UoZmFsc2UpLCBpc0RlcHRoQ3VycmVudChmYWxzZSksCisgICAgICAgIGlzSGVpZ2h0Q3VycmVudChmYWxzZSkge30KKworICAgIC8vLyBcYnJpZWYgQ29uc3RydWN0cyBhIHBsYWNlaG9sZGVyIFNVbml0LgorICAgIFNVbml0KCkKKyAgICAgIDogaXNWUmVnQ3ljbGUoZmFsc2UpLCBpc0NhbGwoZmFsc2UpLCBpc0NhbGxPcChmYWxzZSksIGlzVHdvQWRkcmVzcyhmYWxzZSksCisgICAgICAgIGlzQ29tbXV0YWJsZShmYWxzZSksIGhhc1BoeXNSZWdVc2VzKGZhbHNlKSwgaGFzUGh5c1JlZ0RlZnMoZmFsc2UpLAorICAgICAgICBoYXNQaHlzUmVnQ2xvYmJlcnMoZmFsc2UpLCBpc1BlbmRpbmcoZmFsc2UpLCBpc0F2YWlsYWJsZShmYWxzZSksCisgICAgICAgIGlzU2NoZWR1bGVkKGZhbHNlKSwgaXNTY2hlZHVsZUhpZ2goZmFsc2UpLCBpc1NjaGVkdWxlTG93KGZhbHNlKSwKKyAgICAgICAgaXNDbG9uZWQoZmFsc2UpLCBpc1VuYnVmZmVyZWQoZmFsc2UpLCBoYXNSZXNlcnZlZFJlc291cmNlKGZhbHNlKSwKKyAgICAgICAgaXNEZXB0aEN1cnJlbnQoZmFsc2UpLCBpc0hlaWdodEN1cnJlbnQoZmFsc2UpIHt9CisKKyAgICAvLy8gXGJyaWVmIEJvdW5kYXJ5IG5vZGVzIGFyZSBwbGFjZWhvbGRlcnMgZm9yIHRoZSBib3VuZGFyeSBvZiB0aGUKKyAgICAvLy8gc2NoZWR1bGluZyByZWdpb24uCisgICAgLy8vCisgICAgLy8vIEJvdW5kYXJ5Tm9kZXMgY2FuIGhhdmUgREFHIGVkZ2VzLCBpbmNsdWRpbmcgRGF0YSBlZGdlcywgYnV0IHRoZXkgZG8gbm90CisgICAgLy8vIGNvcnJlc3BvbmQgdG8gc2NoZWR1bGFibGUgZW50aXRpZXMgKGUuZy4gaW5zdHJ1Y3Rpb25zKSBhbmQgZG8gbm90IGhhdmUgYQorICAgIC8vLyB2YWxpZCBJRC4gQ29uc2VxdWVudGx5LCBhbHdheXMgY2hlY2sgZm9yIGJvdW5kYXJ5IG5vZGVzIGJlZm9yZSBhY2Nlc3NpbmcKKyAgICAvLy8gYW4gYXNzb2NpYXRpdmUgZGF0YSBzdHJ1Y3R1cmUga2V5ZWQgb24gbm9kZSBJRC4KKyAgICBib29sIGlzQm91bmRhcnlOb2RlKCkgY29uc3QgeyByZXR1cm4gTm9kZU51bSA9PSBCb3VuZGFyeUlEOyB9CisKKyAgICAvLy8gQXNzaWducyB0aGUgcmVwcmVzZW50YXRpdmUgU0ROb2RlIGZvciB0aGlzIFNVbml0LiBUaGlzIG1heSBiZSB1c2VkCisgICAgLy8vIGR1cmluZyBwcmUtcmVnYWxsb2Mgc2NoZWR1bGluZy4KKyAgICB2b2lkIHNldE5vZGUoU0ROb2RlICpOKSB7CisgICAgICBhc3NlcnQoIUluc3RyICYmICJTZXR0aW5nIFNETm9kZSBvZiBTVW5pdCB3aXRoIE1hY2hpbmVJbnN0ciEiKTsKKyAgICAgIE5vZGUgPSBOOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRoZSByZXByZXNlbnRhdGl2ZSBTRE5vZGUgZm9yIHRoaXMgU1VuaXQuIFRoaXMgbWF5IGJlIHVzZWQKKyAgICAvLy8gZHVyaW5nIHByZS1yZWdhbGxvYyBzY2hlZHVsaW5nLgorICAgIFNETm9kZSAqZ2V0Tm9kZSgpIGNvbnN0IHsKKyAgICAgIGFzc2VydCghSW5zdHIgJiYgIlJlYWRpbmcgU0ROb2RlIG9mIFNVbml0IHdpdGggTWFjaGluZUluc3RyISIpOworICAgICAgcmV0dXJuIE5vZGU7CisgICAgfQorCisgICAgLy8vIFxicmllZiBSZXR1cm5zIHRydWUgaWYgdGhpcyBTVW5pdCByZWZlcnMgdG8gYSBtYWNoaW5lIGluc3RydWN0aW9uIGFzCisgICAgLy8vIG9wcG9zZWQgdG8gYW4gU0ROb2RlLgorICAgIGJvb2wgaXNJbnN0cigpIGNvbnN0IHsgcmV0dXJuIEluc3RyOyB9CisKKyAgICAvLy8gQXNzaWducyB0aGUgaW5zdHJ1Y3Rpb24gZm9yIHRoZSBTVW5pdC4gVGhpcyBtYXkgYmUgdXNlZCBkdXJpbmcKKyAgICAvLy8gcG9zdC1yZWdhbGxvYyBzY2hlZHVsaW5nLgorICAgIHZvaWQgc2V0SW5zdHIoTWFjaGluZUluc3RyICpNSSkgeworICAgICAgYXNzZXJ0KCFOb2RlICYmICJTZXR0aW5nIE1hY2hpbmVJbnN0ciBvZiBTVW5pdCB3aXRoIFNETm9kZSEiKTsKKyAgICAgIEluc3RyID0gTUk7CisgICAgfQorCisgICAgLy8vIFJldHVybnMgdGhlIHJlcHJlc2VudGF0aXZlIE1hY2hpbmVJbnN0ciBmb3IgdGhpcyBTVW5pdC4gVGhpcyBtYXkgYmUgdXNlZAorICAgIC8vLyBkdXJpbmcgcG9zdC1yZWdhbGxvYyBzY2hlZHVsaW5nLgorICAgIE1hY2hpbmVJbnN0ciAqZ2V0SW5zdHIoKSBjb25zdCB7CisgICAgICBhc3NlcnQoIU5vZGUgJiYgIlJlYWRpbmcgTWFjaGluZUluc3RyIG9mIFNVbml0IHdpdGggU0ROb2RlISIpOworICAgICAgcmV0dXJuIEluc3RyOworICAgIH0KKworICAgIC8vLyBBZGRzIHRoZSBzcGVjaWZpZWQgZWRnZSBhcyBhIHByZWQgb2YgdGhlIGN1cnJlbnQgbm9kZSBpZiBub3QgYWxyZWFkeS4KKyAgICAvLy8gSXQgYWxzbyBhZGRzIHRoZSBjdXJyZW50IG5vZGUgYXMgYSBzdWNjZXNzb3Igb2YgdGhlIHNwZWNpZmllZCBub2RlLgorICAgIGJvb2wgYWRkUHJlZChjb25zdCBTRGVwICZELCBib29sIFJlcXVpcmVkID0gdHJ1ZSk7CisKKyAgICAvLy8gXGJyaWVmIEFkZHMgYSBiYXJyaWVyIGVkZ2UgdG8gU1UgYnkgY2FsbGluZyBhZGRQcmVkKCksIHdpdGggbGF0ZW5jeSAwCisgICAgLy8vIGdlbmVyYWxseSBvciBsYXRlbmN5IDEgZm9yIGEgc3RvcmUgZm9sbG93ZWQgYnkgYSBsb2FkLgorICAgIGJvb2wgYWRkUHJlZEJhcnJpZXIoU1VuaXQgKlNVKSB7CisgICAgICBTRGVwIERlcChTVSwgU0RlcDo6QmFycmllcik7CisgICAgICB1bnNpZ25lZCBUcnVlTWVtT3JkZXJMYXRlbmN5ID0KKyAgICAgICAgKChTVS0+Z2V0SW5zdHIoKS0+bWF5U3RvcmUoKSAmJiB0aGlzLT5nZXRJbnN0cigpLT5tYXlMb2FkKCkpID8gMSA6IDApOworICAgICAgRGVwLnNldExhdGVuY3koVHJ1ZU1lbU9yZGVyTGF0ZW5jeSk7CisgICAgICByZXR1cm4gYWRkUHJlZChEZXApOworICAgIH0KKworICAgIC8vLyBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgZWRnZSBhcyBhIHByZWQgb2YgdGhlIGN1cnJlbnQgbm9kZSBpZiBpdCBleGlzdHMuCisgICAgLy8vIEl0IGFsc28gcmVtb3ZlcyB0aGUgY3VycmVudCBub2RlIGFzIGEgc3VjY2Vzc29yIG9mIHRoZSBzcGVjaWZpZWQgbm9kZS4KKyAgICB2b2lkIHJlbW92ZVByZWQoY29uc3QgU0RlcCAmRCk7CisKKyAgICAvLy8gUmV0dXJucyB0aGUgZGVwdGggb2YgdGhpcyBub2RlLCB3aGljaCBpcyB0aGUgbGVuZ3RoIG9mIHRoZSBtYXhpbXVtIHBhdGgKKyAgICAvLy8gdXAgdG8gYW55IG5vZGUgd2hpY2ggaGFzIG5vIHByZWRlY2Vzc29ycy4KKyAgICB1bnNpZ25lZCBnZXREZXB0aCgpIGNvbnN0IHsKKyAgICAgIGlmICghaXNEZXB0aEN1cnJlbnQpCisgICAgICAgIGNvbnN0X2Nhc3Q8U1VuaXQgKj4odGhpcyktPkNvbXB1dGVEZXB0aCgpOworICAgICAgcmV0dXJuIERlcHRoOworICAgIH0KKworICAgIC8vLyBcYnJpZWYgUmV0dXJucyB0aGUgaGVpZ2h0IG9mIHRoaXMgbm9kZSwgd2hpY2ggaXMgdGhlIGxlbmd0aCBvZiB0aGUKKyAgICAvLy8gbWF4aW11bSBwYXRoIGRvd24gdG8gYW55IG5vZGUgd2hpY2ggaGFzIG5vIHN1Y2Nlc3NvcnMuCisgICAgdW5zaWduZWQgZ2V0SGVpZ2h0KCkgY29uc3QgeworICAgICAgaWYgKCFpc0hlaWdodEN1cnJlbnQpCisgICAgICAgIGNvbnN0X2Nhc3Q8U1VuaXQgKj4odGhpcyktPkNvbXB1dGVIZWlnaHQoKTsKKyAgICAgIHJldHVybiBIZWlnaHQ7CisgICAgfQorCisgICAgLy8vIFxicmllZiBJZiBOZXdEZXB0aCBpcyBncmVhdGVyIHRoYW4gdGhpcyBub2RlJ3MgZGVwdGggdmFsdWUsIHNldHMgaXQgdG8KKyAgICAvLy8gYmUgdGhlIG5ldyBkZXB0aCB2YWx1ZS4gVGhpcyBhbHNvIHJlY3Vyc2l2ZWx5IG1hcmtzIHN1Y2Nlc3NvciBub2RlcworICAgIC8vLyBkaXJ0eS4KKyAgICB2b2lkIHNldERlcHRoVG9BdExlYXN0KHVuc2lnbmVkIE5ld0RlcHRoKTsKKworICAgIC8vLyBcYnJpZWYgSWYgTmV3RGVwdGggaXMgZ3JlYXRlciB0aGFuIHRoaXMgbm9kZSdzIGRlcHRoIHZhbHVlLCBzZXQgaXQgdG8gYmUKKyAgICAvLy8gdGhlIG5ldyBoZWlnaHQgdmFsdWUuIFRoaXMgYWxzbyByZWN1cnNpdmVseSBtYXJrcyBwcmVkZWNlc3NvciBub2RlcworICAgIC8vLyBkaXJ0eS4KKyAgICB2b2lkIHNldEhlaWdodFRvQXRMZWFzdCh1bnNpZ25lZCBOZXdIZWlnaHQpOworCisgICAgLy8vIFxicmllZiBTZXRzIGEgZmxhZyBpbiB0aGlzIG5vZGUgdG8gaW5kaWNhdGUgdGhhdCBpdHMgc3RvcmVkIERlcHRoIHZhbHVlCisgICAgLy8vIHdpbGwgcmVxdWlyZSByZWNvbXB1dGF0aW9uIHRoZSBuZXh0IHRpbWUgZ2V0RGVwdGgoKSBpcyBjYWxsZWQuCisgICAgdm9pZCBzZXREZXB0aERpcnR5KCk7CisKKyAgICAvLy8gXGJyaWVmIFNldHMgYSBmbGFnIGluIHRoaXMgbm9kZSB0byBpbmRpY2F0ZSB0aGF0IGl0cyBzdG9yZWQgSGVpZ2h0IHZhbHVlCisgICAgLy8vIHdpbGwgcmVxdWlyZSByZWNvbXB1dGF0aW9uIHRoZSBuZXh0IHRpbWUgZ2V0SGVpZ2h0KCkgaXMgY2FsbGVkLgorICAgIHZvaWQgc2V0SGVpZ2h0RGlydHkoKTsKKworICAgIC8vLyBUZXN0cyBpZiBub2RlIE4gaXMgYSBwcmVkZWNlc3NvciBvZiB0aGlzIG5vZGUuCisgICAgYm9vbCBpc1ByZWQoY29uc3QgU1VuaXQgKk4pIGNvbnN0IHsKKyAgICAgIGZvciAoY29uc3QgU0RlcCAmUHJlZCA6IFByZWRzKQorICAgICAgICBpZiAoUHJlZC5nZXRTVW5pdCgpID09IE4pCisgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgLy8vIFRlc3RzIGlmIG5vZGUgTiBpcyBhIHN1Y2Nlc3NvciBvZiB0aGlzIG5vZGUuCisgICAgYm9vbCBpc1N1Y2MoY29uc3QgU1VuaXQgKk4pIGNvbnN0IHsKKyAgICAgIGZvciAoY29uc3QgU0RlcCAmU3VjYyA6IFN1Y2NzKQorICAgICAgICBpZiAoU3VjYy5nZXRTVW5pdCgpID09IE4pCisgICAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICByZXR1cm4gZmFsc2U7CisgICAgfQorCisgICAgYm9vbCBpc1RvcFJlYWR5KCkgY29uc3QgeworICAgICAgcmV0dXJuIE51bVByZWRzTGVmdCA9PSAwOworICAgIH0KKyAgICBib29sIGlzQm90dG9tUmVhZHkoKSBjb25zdCB7CisgICAgICByZXR1cm4gTnVtU3VjY3NMZWZ0ID09IDA7CisgICAgfQorCisgICAgLy8vIFxicmllZiBPcmRlcnMgdGhpcyBub2RlJ3MgcHJlZGVjZXNzb3IgZWRnZXMgc3VjaCB0aGF0IHRoZSBjcml0aWNhbCBwYXRoCisgICAgLy8vIGVkZ2Ugb2NjdXJzIGZpcnN0LgorICAgIHZvaWQgYmlhc0NyaXRpY2FsUGF0aCgpOworCisgICAgdm9pZCBkdW1wKGNvbnN0IFNjaGVkdWxlREFHICpHKSBjb25zdDsKKyAgICB2b2lkIGR1bXBBbGwoY29uc3QgU2NoZWR1bGVEQUcgKkcpIGNvbnN0OworICAgIHJhd19vc3RyZWFtICZwcmludChyYXdfb3N0cmVhbSAmTywKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU1VuaXQgKk4gPSBudWxscHRyLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTVW5pdCAqWCA9IG51bGxwdHIpIGNvbnN0OworICAgIHJhd19vc3RyZWFtICZwcmludChyYXdfb3N0cmVhbSAmTywgY29uc3QgU2NoZWR1bGVEQUcgKkcpIGNvbnN0OworCisgIHByaXZhdGU6CisgICAgdm9pZCBDb21wdXRlRGVwdGgoKTsKKyAgICB2b2lkIENvbXB1dGVIZWlnaHQoKTsKKyAgfTsKKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgU0RlcCBpcyBlcXVpdmFsZW50IGV4Y2VwdCBmb3IgbGF0ZW5jeS4KKyAgaW5saW5lIGJvb2wgU0RlcDo6b3ZlcmxhcHMoY29uc3QgU0RlcCAmT3RoZXIpIGNvbnN0IHsKKyAgICBpZiAoRGVwICE9IE90aGVyLkRlcCkKKyAgICAgIHJldHVybiBmYWxzZTsKKyAgICBzd2l0Y2ggKERlcC5nZXRJbnQoKSkgeworICAgIGNhc2UgRGF0YToKKyAgICBjYXNlIEFudGk6CisgICAgY2FzZSBPdXRwdXQ6CisgICAgICByZXR1cm4gQ29udGVudHMuUmVnID09IE90aGVyLkNvbnRlbnRzLlJlZzsKKyAgICBjYXNlIE9yZGVyOgorICAgICAgcmV0dXJuIENvbnRlbnRzLk9yZEtpbmQgPT0gT3RoZXIuQ29udGVudHMuT3JkS2luZDsKKyAgICB9CisgICAgbGx2bV91bnJlYWNoYWJsZSgiSW52YWxpZCBkZXBlbmRlbmN5IGtpbmQhIik7CisgIH0KKworICAvLy8vIFJldHVybnMgdGhlIFNVbml0IHRvIHdoaWNoIHRoaXMgZWRnZSBwb2ludHMuCisgIGlubGluZSBTVW5pdCAqU0RlcDo6Z2V0U1VuaXQoKSBjb25zdCB7IHJldHVybiBEZXAuZ2V0UG9pbnRlcigpOyB9CisKKyAgLy8vLyBBc3NpZ25zIHRoZSBTVW5pdCB0byB3aGljaCB0aGlzIGVkZ2UgcG9pbnRzLgorICBpbmxpbmUgdm9pZCBTRGVwOjpzZXRTVW5pdChTVW5pdCAqU1UpIHsgRGVwLnNldFBvaW50ZXIoU1UpOyB9CisKKyAgLy8vIFJldHVybnMgYW4gZW51bSB2YWx1ZSByZXByZXNlbnRpbmcgdGhlIGtpbmQgb2YgdGhlIGRlcGVuZGVuY2UuCisgIGlubGluZSBTRGVwOjpLaW5kIFNEZXA6OmdldEtpbmQoKSBjb25zdCB7IHJldHVybiBEZXAuZ2V0SW50KCk7IH0KKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworICAvLy8gXGJyaWVmIFRoaXMgaW50ZXJmYWNlIGlzIHVzZWQgdG8gcGx1ZyBkaWZmZXJlbnQgcHJpb3JpdGllcyBjb21wdXRhdGlvbgorICAvLy8gYWxnb3JpdGhtcyBpbnRvIHRoZSBsaXN0IHNjaGVkdWxlci4gSXQgaW1wbGVtZW50cyB0aGUgaW50ZXJmYWNlIG9mIGEKKyAgLy8vIHN0YW5kYXJkIHByaW9yaXR5IHF1ZXVlLCB3aGVyZSBub2RlcyBhcmUgaW5zZXJ0ZWQgaW4gYXJiaXRyYXJ5IG9yZGVyIGFuZAorICAvLy8gcmV0dXJuZWQgaW4gcHJpb3JpdHkgb3JkZXIuICBUaGUgY29tcHV0YXRpb24gb2YgdGhlIHByaW9yaXR5IGFuZCB0aGUKKyAgLy8vIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBxdWV1ZSBhcmUgdG90YWxseSB1cCB0byB0aGUgaW1wbGVtZW50YXRpb24gdG8KKyAgLy8vIGRlY2lkZS4KKyAgY2xhc3MgU2NoZWR1bGluZ1ByaW9yaXR5UXVldWUgeworICAgIHZpcnR1YWwgdm9pZCBhbmNob3IoKTsKKworICAgIHVuc2lnbmVkIEN1ckN5Y2xlID0gMDsKKyAgICBib29sIEhhc1JlYWR5RmlsdGVyOworCisgIHB1YmxpYzoKKyAgICBTY2hlZHVsaW5nUHJpb3JpdHlRdWV1ZShib29sIHJmID0gZmFsc2UpIDogIEhhc1JlYWR5RmlsdGVyKHJmKSB7fQorCisgICAgdmlydHVhbCB+U2NoZWR1bGluZ1ByaW9yaXR5UXVldWUoKSA9IGRlZmF1bHQ7CisKKyAgICB2aXJ0dWFsIGJvb2wgaXNCb3R0b21VcCgpIGNvbnN0ID0gMDsKKworICAgIHZpcnR1YWwgdm9pZCBpbml0Tm9kZXMoc3RkOjp2ZWN0b3I8U1VuaXQ+ICZTVW5pdHMpID0gMDsKKyAgICB2aXJ0dWFsIHZvaWQgYWRkTm9kZShjb25zdCBTVW5pdCAqU1UpID0gMDsKKyAgICB2aXJ0dWFsIHZvaWQgdXBkYXRlTm9kZShjb25zdCBTVW5pdCAqU1UpID0gMDsKKyAgICB2aXJ0dWFsIHZvaWQgcmVsZWFzZVN0YXRlKCkgPSAwOworCisgICAgdmlydHVhbCBib29sIGVtcHR5KCkgY29uc3QgPSAwOworCisgICAgYm9vbCBoYXNSZWFkeUZpbHRlcigpIGNvbnN0IHsgcmV0dXJuIEhhc1JlYWR5RmlsdGVyOyB9CisKKyAgICB2aXJ0dWFsIGJvb2wgdHJhY2tzUmVnUHJlc3N1cmUoKSBjb25zdCB7IHJldHVybiBmYWxzZTsgfQorCisgICAgdmlydHVhbCBib29sIGlzUmVhZHkoU1VuaXQgKikgY29uc3QgeworICAgICAgYXNzZXJ0KCFIYXNSZWFkeUZpbHRlciAmJiAiVGhlIHJlYWR5IGZpbHRlciBtdXN0IG92ZXJyaWRlIGlzUmVhZHkoKSIpOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorCisgICAgdmlydHVhbCB2b2lkIHB1c2goU1VuaXQgKlUpID0gMDsKKworICAgIHZvaWQgcHVzaF9hbGwoY29uc3Qgc3RkOjp2ZWN0b3I8U1VuaXQgKj4gJk5vZGVzKSB7CisgICAgICBmb3IgKHN0ZDo6dmVjdG9yPFNVbml0ICo+Ojpjb25zdF9pdGVyYXRvciBJID0gTm9kZXMuYmVnaW4oKSwKKyAgICAgICAgICAgRSA9IE5vZGVzLmVuZCgpOyBJICE9IEU7ICsrSSkKKyAgICAgICAgcHVzaCgqSSk7CisgICAgfQorCisgICAgdmlydHVhbCBTVW5pdCAqcG9wKCkgPSAwOworCisgICAgdmlydHVhbCB2b2lkIHJlbW92ZShTVW5pdCAqU1UpID0gMDsKKworICAgIHZpcnR1YWwgdm9pZCBkdW1wKFNjaGVkdWxlREFHICopIGNvbnN0IHt9CisKKyAgICAvLy8gQXMgZWFjaCBub2RlIGlzIHNjaGVkdWxlZCwgdGhpcyBtZXRob2QgaXMgaW52b2tlZC4gIFRoaXMgYWxsb3dzIHRoZQorICAgIC8vLyBwcmlvcml0eSBmdW5jdGlvbiB0byBhZGp1c3QgdGhlIHByaW9yaXR5IG9mIHJlbGF0ZWQgdW5zY2hlZHVsZWQgbm9kZXMsCisgICAgLy8vIGZvciBleGFtcGxlLgorICAgIHZpcnR1YWwgdm9pZCBzY2hlZHVsZWROb2RlKFNVbml0ICopIHt9CisKKyAgICB2aXJ0dWFsIHZvaWQgdW5zY2hlZHVsZWROb2RlKFNVbml0ICopIHt9CisKKyAgICB2b2lkIHNldEN1ckN5Y2xlKHVuc2lnbmVkIEN5Y2xlKSB7CisgICAgICBDdXJDeWNsZSA9IEN5Y2xlOworICAgIH0KKworICAgIHVuc2lnbmVkIGdldEN1ckN5Y2xlKCkgY29uc3QgeworICAgICAgcmV0dXJuIEN1ckN5Y2xlOworICAgIH0KKyAgfTsKKworICBjbGFzcyBTY2hlZHVsZURBRyB7CisgIHB1YmxpYzoKKyAgICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTTsgICAgICAgICAgICAvLy88IFRhcmdldCBwcm9jZXNzb3IKKyAgICBjb25zdCBUYXJnZXRJbnN0ckluZm8gKlRJSTsgICAgICAgICAvLy88IFRhcmdldCBpbnN0cnVjdGlvbiBpbmZvcm1hdGlvbgorICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJOyAgICAgIC8vLzwgVGFyZ2V0IHByb2Nlc3NvciByZWdpc3RlciBpbmZvCisgICAgTWFjaGluZUZ1bmN0aW9uICZNRjsgICAgICAgICAgICAgICAgLy8vPCBNYWNoaW5lIGZ1bmN0aW9uCisgICAgTWFjaGluZVJlZ2lzdGVySW5mbyAmTVJJOyAgICAgICAgICAgLy8vPCBWaXJ0dWFsL3JlYWwgcmVnaXN0ZXIgbWFwCisgICAgc3RkOjp2ZWN0b3I8U1VuaXQ+IFNVbml0czsgICAgICAgICAgLy8vPCBUaGUgc2NoZWR1bGluZyB1bml0cy4KKyAgICBTVW5pdCBFbnRyeVNVOyAgICAgICAgICAgICAgICAgICAgICAvLy88IFNwZWNpYWwgbm9kZSBmb3IgdGhlIHJlZ2lvbiBlbnRyeS4KKyAgICBTVW5pdCBFeGl0U1U7ICAgICAgICAgICAgICAgICAgICAgICAvLy88IFNwZWNpYWwgbm9kZSBmb3IgdGhlIHJlZ2lvbiBleGl0LgorCisjaWZkZWYgTkRFQlVHCisgICAgc3RhdGljIGNvbnN0IGJvb2wgU3RyZXNzU2NoZWQgPSBmYWxzZTsKKyNlbHNlCisgICAgYm9vbCBTdHJlc3NTY2hlZDsKKyNlbmRpZgorCisgICAgZXhwbGljaXQgU2NoZWR1bGVEQUcoTWFjaGluZUZ1bmN0aW9uICZtZik7CisKKyAgICB2aXJ0dWFsIH5TY2hlZHVsZURBRygpOworCisgICAgLy8vIENsZWFycyB0aGUgREFHIHN0YXRlIChiZXR3ZWVuIHJlZ2lvbnMpLgorICAgIHZvaWQgY2xlYXJEQUcoKTsKKworICAgIC8vLyBSZXR1cm5zIHRoZSBNQ0luc3RyRGVzYyBvZiB0aGlzIFNVbml0LgorICAgIC8vLyBSZXR1cm5zIE5VTEwgZm9yIFNETm9kZXMgd2l0aG91dCBhIG1hY2hpbmUgb3Bjb2RlLgorICAgIGNvbnN0IE1DSW5zdHJEZXNjICpnZXRJbnN0ckRlc2MoY29uc3QgU1VuaXQgKlNVKSBjb25zdCB7CisgICAgICBpZiAoU1UtPmlzSW5zdHIoKSkgcmV0dXJuICZTVS0+Z2V0SW5zdHIoKS0+Z2V0RGVzYygpOworICAgICAgcmV0dXJuIGdldE5vZGVEZXNjKFNVLT5nZXROb2RlKCkpOworICAgIH0KKworICAgIC8vLyBQb3BzIHVwIGEgR3JhcGhWaXovZ3Ygd2luZG93IHdpdGggdGhlIFNjaGVkdWxlREFHIHJlbmRlcmVkIHVzaW5nICdkb3QnLgorICAgIHZpcnR1YWwgdm9pZCB2aWV3R3JhcGgoY29uc3QgVHdpbmUgJk5hbWUsIGNvbnN0IFR3aW5lICZUaXRsZSk7CisgICAgdmlydHVhbCB2b2lkIHZpZXdHcmFwaCgpOworCisgICAgdmlydHVhbCB2b2lkIGR1bXBOb2RlKGNvbnN0IFNVbml0ICpTVSkgY29uc3QgPSAwOworCisgICAgLy8vIFJldHVybnMgYSBsYWJlbCBmb3IgYW4gU1VuaXQgbm9kZSBpbiBhIHZpc3VhbGl6YXRpb24gb2YgdGhlIFNjaGVkdWxlREFHLgorICAgIHZpcnR1YWwgc3RkOjpzdHJpbmcgZ2V0R3JhcGhOb2RlTGFiZWwoY29uc3QgU1VuaXQgKlNVKSBjb25zdCA9IDA7CisKKyAgICAvLy8gUmV0dXJucyBhIGxhYmVsIGZvciB0aGUgcmVnaW9uIG9mIGNvZGUgY292ZXJlZCBieSB0aGUgREFHLgorICAgIHZpcnR1YWwgc3RkOjpzdHJpbmcgZ2V0REFHTmFtZSgpIGNvbnN0ID0gMDsKKworICAgIC8vLyBBZGRzIGN1c3RvbSBmZWF0dXJlcyBmb3IgYSB2aXN1YWxpemF0aW9uIG9mIHRoZSBTY2hlZHVsZURBRy4KKyAgICB2aXJ0dWFsIHZvaWQgYWRkQ3VzdG9tR3JhcGhGZWF0dXJlcyhHcmFwaFdyaXRlcjxTY2hlZHVsZURBRyo+ICYpIGNvbnN0IHt9CisKKyNpZm5kZWYgTkRFQlVHCisgICAgLy8vIFxicmllZiBWZXJpZmllcyB0aGF0IGFsbCBTVW5pdHMgd2VyZSBzY2hlZHVsZWQgYW5kIHRoYXQgdGhlaXIgc3RhdGUgaXMKKyAgICAvLy8gY29uc2lzdGVudC4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIHNjaGVkdWxlZCBTVW5pdHMuCisgICAgdW5zaWduZWQgVmVyaWZ5U2NoZWR1bGVkREFHKGJvb2wgaXNCb3R0b21VcCk7CisjZW5kaWYKKworICBwcml2YXRlOgorICAgIC8vLyBSZXR1cm5zIHRoZSBNQ0luc3RyRGVzYyBvZiB0aGlzIFNETm9kZSBvciBOVUxMLgorICAgIGNvbnN0IE1DSW5zdHJEZXNjICpnZXROb2RlRGVzYyhjb25zdCBTRE5vZGUgKk5vZGUpIGNvbnN0OworICB9OworCisgIGNsYXNzIFNVbml0SXRlcmF0b3IgOiBwdWJsaWMgc3RkOjppdGVyYXRvcjxzdGQ6OmZvcndhcmRfaXRlcmF0b3JfdGFnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1VuaXQsIHB0cmRpZmZfdD4geworICAgIFNVbml0ICpOb2RlOworICAgIHVuc2lnbmVkIE9wZXJhbmQ7CisKKyAgICBTVW5pdEl0ZXJhdG9yKFNVbml0ICpOLCB1bnNpZ25lZCBPcCkgOiBOb2RlKE4pLCBPcGVyYW5kKE9wKSB7fQorCisgIHB1YmxpYzoKKyAgICBib29sIG9wZXJhdG9yPT0oY29uc3QgU1VuaXRJdGVyYXRvciYgeCkgY29uc3QgeworICAgICAgcmV0dXJuIE9wZXJhbmQgPT0geC5PcGVyYW5kOworICAgIH0KKyAgICBib29sIG9wZXJhdG9yIT0oY29uc3QgU1VuaXRJdGVyYXRvciYgeCkgY29uc3QgeyByZXR1cm4gIW9wZXJhdG9yPT0oeCk7IH0KKworICAgIHBvaW50ZXIgb3BlcmF0b3IqKCkgY29uc3QgeworICAgICAgcmV0dXJuIE5vZGUtPlByZWRzW09wZXJhbmRdLmdldFNVbml0KCk7CisgICAgfQorICAgIHBvaW50ZXIgb3BlcmF0b3ItPigpIGNvbnN0IHsgcmV0dXJuIG9wZXJhdG9yKigpOyB9CisKKyAgICBTVW5pdEl0ZXJhdG9yJiBvcGVyYXRvcisrKCkgeyAgICAgICAgICAgICAgICAvLyBQcmVpbmNyZW1lbnQKKyAgICAgICsrT3BlcmFuZDsKKyAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisgICAgU1VuaXRJdGVyYXRvciBvcGVyYXRvcisrKGludCkgeyAvLyBQb3N0aW5jcmVtZW50CisgICAgICBTVW5pdEl0ZXJhdG9yIHRtcCA9ICp0aGlzOyArKyp0aGlzOyByZXR1cm4gdG1wOworICAgIH0KKworICAgIHN0YXRpYyBTVW5pdEl0ZXJhdG9yIGJlZ2luKFNVbml0ICpOKSB7IHJldHVybiBTVW5pdEl0ZXJhdG9yKE4sIDApOyB9CisgICAgc3RhdGljIFNVbml0SXRlcmF0b3IgZW5kICAoU1VuaXQgKk4pIHsKKyAgICAgIHJldHVybiBTVW5pdEl0ZXJhdG9yKE4sICh1bnNpZ25lZClOLT5QcmVkcy5zaXplKCkpOworICAgIH0KKworICAgIHVuc2lnbmVkIGdldE9wZXJhbmQoKSBjb25zdCB7IHJldHVybiBPcGVyYW5kOyB9CisgICAgY29uc3QgU1VuaXQgKmdldE5vZGUoKSBjb25zdCB7IHJldHVybiBOb2RlOyB9CisKKyAgICAvLy8gVGVzdHMgaWYgdGhpcyBpcyBub3QgYW4gU0RlcDo6RGF0YSBkZXBlbmRlbmNlLgorICAgIGJvb2wgaXNDdHJsRGVwKCkgY29uc3QgeworICAgICAgcmV0dXJuIGdldFNEZXAoKS5pc0N0cmwoKTsKKyAgICB9CisgICAgYm9vbCBpc0FydGlmaWNpYWxEZXAoKSBjb25zdCB7CisgICAgICByZXR1cm4gZ2V0U0RlcCgpLmlzQXJ0aWZpY2lhbCgpOworICAgIH0KKyAgICBjb25zdCBTRGVwICZnZXRTRGVwKCkgY29uc3QgeworICAgICAgcmV0dXJuIE5vZGUtPlByZWRzW09wZXJhbmRdOworICAgIH0KKyAgfTsKKworICB0ZW1wbGF0ZSA8PiBzdHJ1Y3QgR3JhcGhUcmFpdHM8U1VuaXQqPiB7CisgICAgdHlwZWRlZiBTVW5pdCAqTm9kZVJlZjsKKyAgICB0eXBlZGVmIFNVbml0SXRlcmF0b3IgQ2hpbGRJdGVyYXRvclR5cGU7CisgICAgc3RhdGljIE5vZGVSZWYgZ2V0RW50cnlOb2RlKFNVbml0ICpOKSB7IHJldHVybiBOOyB9CisgICAgc3RhdGljIENoaWxkSXRlcmF0b3JUeXBlIGNoaWxkX2JlZ2luKE5vZGVSZWYgTikgeworICAgICAgcmV0dXJuIFNVbml0SXRlcmF0b3I6OmJlZ2luKE4pOworICAgIH0KKyAgICBzdGF0aWMgQ2hpbGRJdGVyYXRvclR5cGUgY2hpbGRfZW5kKE5vZGVSZWYgTikgeworICAgICAgcmV0dXJuIFNVbml0SXRlcmF0b3I6OmVuZChOKTsKKyAgICB9CisgIH07CisKKyAgdGVtcGxhdGUgPD4gc3RydWN0IEdyYXBoVHJhaXRzPFNjaGVkdWxlREFHKj4gOiBwdWJsaWMgR3JhcGhUcmFpdHM8U1VuaXQqPiB7CisgICAgdHlwZWRlZiBwb2ludGVyX2l0ZXJhdG9yPHN0ZDo6dmVjdG9yPFNVbml0Pjo6aXRlcmF0b3I+IG5vZGVzX2l0ZXJhdG9yOworICAgIHN0YXRpYyBub2Rlc19pdGVyYXRvciBub2Rlc19iZWdpbihTY2hlZHVsZURBRyAqRykgeworICAgICAgcmV0dXJuIG5vZGVzX2l0ZXJhdG9yKEctPlNVbml0cy5iZWdpbigpKTsKKyAgICB9CisgICAgc3RhdGljIG5vZGVzX2l0ZXJhdG9yIG5vZGVzX2VuZChTY2hlZHVsZURBRyAqRykgeworICAgICAgcmV0dXJuIG5vZGVzX2l0ZXJhdG9yKEctPlNVbml0cy5lbmQoKSk7CisgICAgfQorICB9OworCisgIC8vLyBUaGlzIGNsYXNzIGNhbiBjb21wdXRlIGEgdG9wb2xvZ2ljYWwgb3JkZXJpbmcgZm9yIFNVbml0cyBhbmQgcHJvdmlkZXMKKyAgLy8vIG1ldGhvZHMgZm9yIGR5bmFtaWNhbGx5IHVwZGF0aW5nIHRoZSBvcmRlcmluZyBhcyBuZXcgZWRnZXMgYXJlIGFkZGVkLgorICAvLy8KKyAgLy8vIFRoaXMgYWxsb3dzIGEgdmVyeSBmYXN0IGltcGxlbWVudGF0aW9uIG9mIElzUmVhY2hhYmxlLCBmb3IgZXhhbXBsZS4KKyAgY2xhc3MgU2NoZWR1bGVEQUdUb3BvbG9naWNhbFNvcnQgeworICAgIC8vLyBBIHJlZmVyZW5jZSB0byB0aGUgU2NoZWR1bGVEQUcncyBTVW5pdHMuCisgICAgc3RkOjp2ZWN0b3I8U1VuaXQ+ICZTVW5pdHM7CisgICAgU1VuaXQgKkV4aXRTVTsKKworICAgIC8vLyBNYXBzIHRvcG9sb2dpY2FsIGluZGV4IHRvIHRoZSBub2RlIG51bWJlci4KKyAgICBzdGQ6OnZlY3RvcjxpbnQ+IEluZGV4Mk5vZGU7CisgICAgLy8vIE1hcHMgdGhlIG5vZGUgbnVtYmVyIHRvIGl0cyB0b3BvbG9naWNhbCBpbmRleC4KKyAgICBzdGQ6OnZlY3RvcjxpbnQ+IE5vZGUySW5kZXg7CisgICAgLy8vIGEgc2V0IG9mIG5vZGVzIHZpc2l0ZWQgZHVyaW5nIGEgREZTIHRyYXZlcnNhbC4KKyAgICBCaXRWZWN0b3IgVmlzaXRlZDsKKworICAgIC8vLyBNYWtlcyBhIERGUyB0cmF2ZXJzYWwgYW5kIG1hcmsgYWxsIG5vZGVzIGFmZmVjdGVkIGJ5IHRoZSBlZGdlIGluc2VydGlvbi4KKyAgICAvLy8gVGhlc2Ugbm9kZXMgd2lsbCBsYXRlciBnZXQgbmV3IHRvcG9sb2dpY2FsIGluZGV4ZXMgYnkgbWVhbnMgb2YgdGhlIFNoaWZ0CisgICAgLy8vIG1ldGhvZC4KKyAgICB2b2lkIERGUyhjb25zdCBTVW5pdCAqU1UsIGludCBVcHBlckJvdW5kLCBib29sJiBIYXNMb29wKTsKKworICAgIC8vLyBcYnJpZWYgUmVhc3NpZ25zIHRvcG9sb2dpY2FsIGluZGV4ZXMgZm9yIHRoZSBub2RlcyBpbiB0aGUgREFHIHRvCisgICAgLy8vIHByZXNlcnZlIHRoZSB0b3BvbG9naWNhbCBvcmRlcmluZy4KKyAgICB2b2lkIFNoaWZ0KEJpdFZlY3RvciYgVmlzaXRlZCwgaW50IExvd2VyQm91bmQsIGludCBVcHBlckJvdW5kKTsKKworICAgIC8vLyBBc3NpZ25zIHRoZSB0b3BvbG9naWNhbCBpbmRleCB0byB0aGUgbm9kZSBuLgorICAgIHZvaWQgQWxsb2NhdGUoaW50IG4sIGludCBpbmRleCk7CisKKyAgcHVibGljOgorICAgIFNjaGVkdWxlREFHVG9wb2xvZ2ljYWxTb3J0KHN0ZDo6dmVjdG9yPFNVbml0PiAmU1VuaXRzLCBTVW5pdCAqRXhpdFNVKTsKKworICAgIC8vLyBDcmVhdGVzIHRoZSBpbml0aWFsIHRvcG9sb2dpY2FsIG9yZGVyaW5nIGZyb20gdGhlIERBRyB0byBiZSBzY2hlZHVsZWQuCisgICAgdm9pZCBJbml0REFHVG9wb2xvZ2ljYWxTb3J0aW5nKCk7CisKKyAgICAvLy8gUmV0dXJucyBhbiBhcnJheSBvZiBTVXMgdGhhdCBhcmUgYm90aCBpbiB0aGUgc3VjY2Vzc29yCisgICAgLy8vIHN1YnRyZWUgb2YgU3RhcnRTVSBhbmQgaW4gdGhlIHByZWRlY2Vzc29yIHN1YnRyZWUgb2YgVGFyZ2V0U1UuCisgICAgLy8vIFN0YXJ0U1UgYW5kIFRhcmdldFNVIGFyZSBub3QgaW4gdGhlIGFycmF5LgorICAgIC8vLyBTdWNjZXNzIGlzIGZhbHNlIGlmIFRhcmdldFNVIGlzIG5vdCBpbiB0aGUgc3VjY2Vzc29yIHN1YnRyZWUgb2YKKyAgICAvLy8gU3RhcnRTVSwgZWxzZSBpdCBpcyB0cnVlLgorICAgIHN0ZDo6dmVjdG9yPGludD4gR2V0U3ViR3JhcGgoY29uc3QgU1VuaXQgJlN0YXJ0U1UsIGNvbnN0IFNVbml0ICZUYXJnZXRTVSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgJlN1Y2Nlc3MpOworCisgICAgLy8vIENoZWNrcyBpZiBccCBTVSBpcyByZWFjaGFibGUgZnJvbSBccCBUYXJnZXRTVS4KKyAgICBib29sIElzUmVhY2hhYmxlKGNvbnN0IFNVbml0ICpTVSwgY29uc3QgU1VuaXQgKlRhcmdldFNVKTsKKworICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgYWRkUHJlZChUYXJnZXRTVSwgU1UpIGNyZWF0ZXMgYSBjeWNsZS4KKyAgICBib29sIFdpbGxDcmVhdGVDeWNsZShTVW5pdCAqVGFyZ2V0U1UsIFNVbml0ICpTVSk7CisKKyAgICAvLy8gXGJyaWVmIFVwZGF0ZXMgdGhlIHRvcG9sb2dpY2FsIG9yZGVyaW5nIHRvIGFjY29tbW9kYXRlIGFuIGVkZ2UgdG8gYmUKKyAgICAvLy8gYWRkZWQgZnJvbSBTVW5pdCBccCBYIHRvIFNVbml0IFxwIFkuCisgICAgdm9pZCBBZGRQcmVkKFNVbml0ICpZLCBTVW5pdCAqWCk7CisKKyAgICAvLy8gXGJyaWVmIFVwZGF0ZXMgdGhlIHRvcG9sb2dpY2FsIG9yZGVyaW5nIHRvIGFjY29tbW9kYXRlIGFuIGFuIGVkZ2UgdG8gYmUKKyAgICAvLy8gcmVtb3ZlZCBmcm9tIHRoZSBzcGVjaWZpZWQgbm9kZSBccCBOIGZyb20gdGhlIHByZWRlY2Vzc29ycyBvZiB0aGUKKyAgICAvLy8gY3VycmVudCBub2RlIFxwIE0uCisgICAgdm9pZCBSZW1vdmVQcmVkKFNVbml0ICpNLCBTVW5pdCAqTik7CisKKyAgICB0eXBlZGVmIHN0ZDo6dmVjdG9yPGludD46Oml0ZXJhdG9yIGl0ZXJhdG9yOworICAgIHR5cGVkZWYgc3RkOjp2ZWN0b3I8aW50Pjo6Y29uc3RfaXRlcmF0b3IgY29uc3RfaXRlcmF0b3I7CisgICAgaXRlcmF0b3IgYmVnaW4oKSB7IHJldHVybiBJbmRleDJOb2RlLmJlZ2luKCk7IH0KKyAgICBjb25zdF9pdGVyYXRvciBiZWdpbigpIGNvbnN0IHsgcmV0dXJuIEluZGV4Mk5vZGUuYmVnaW4oKTsgfQorICAgIGl0ZXJhdG9yIGVuZCgpIHsgcmV0dXJuIEluZGV4Mk5vZGUuZW5kKCk7IH0KKyAgICBjb25zdF9pdGVyYXRvciBlbmQoKSBjb25zdCB7IHJldHVybiBJbmRleDJOb2RlLmVuZCgpOyB9CisKKyAgICB0eXBlZGVmIHN0ZDo6dmVjdG9yPGludD46OnJldmVyc2VfaXRlcmF0b3IgcmV2ZXJzZV9pdGVyYXRvcjsKKyAgICB0eXBlZGVmIHN0ZDo6dmVjdG9yPGludD46OmNvbnN0X3JldmVyc2VfaXRlcmF0b3IgY29uc3RfcmV2ZXJzZV9pdGVyYXRvcjsKKyAgICByZXZlcnNlX2l0ZXJhdG9yIHJiZWdpbigpIHsgcmV0dXJuIEluZGV4Mk5vZGUucmJlZ2luKCk7IH0KKyAgICBjb25zdF9yZXZlcnNlX2l0ZXJhdG9yIHJiZWdpbigpIGNvbnN0IHsgcmV0dXJuIEluZGV4Mk5vZGUucmJlZ2luKCk7IH0KKyAgICByZXZlcnNlX2l0ZXJhdG9yIHJlbmQoKSB7IHJldHVybiBJbmRleDJOb2RlLnJlbmQoKTsgfQorICAgIGNvbnN0X3JldmVyc2VfaXRlcmF0b3IgcmVuZCgpIGNvbnN0IHsgcmV0dXJuIEluZGV4Mk5vZGUucmVuZCgpOyB9CisgIH07CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fU0NIRURVTEVEQUdfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NjaGVkdWxlREFHSW5zdHJzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vU2NoZWR1bGVEQUdJbnN0cnMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNDg4MjIwCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NjaGVkdWxlREFHSW5zdHJzLmgKQEAgLTAsMCArMSwzODQgQEAKKy8vPT09LSBTY2hlZHVsZURBR0luc3Rycy5oIC0gTWFjaGluZUluc3RyIFNjaGVkdWxpbmcgLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8vIFxmaWxlIEltcGxlbWVudHMgdGhlIFNjaGVkdWxlREFHSW5zdHJzIGNsYXNzLCB3aGljaCBpbXBsZW1lbnRzIHNjaGVkdWxpbmcKKy8vLyBmb3IgYSBNYWNoaW5lSW5zdHItYmFzZWQgZGVwZW5kZW5jeSBncmFwaC4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9TQ0hFRFVMRURBR0lOU1RSU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9TQ0hFRFVMRURBR0lOU1RSU19ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9EZW5zZU1hcC5oIgorI2luY2x1ZGUgImxsdm0vQURUL1BvaW50ZXJJbnRQYWlyLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU1RMRXh0cmFzLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TcGFyc2VNdWx0aVNldC5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NwYXJzZVNldC5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9MaXZlUGh5c1JlZ3MuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2NoZWR1bGVEQUcuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0UmVnaXN0ZXJJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1RhcmdldFNjaGVkdWxlLmgiCisjaW5jbHVkZSAibGx2bS9NQy9MYW5lQml0bWFzay5oIgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8Y3N0ZGludD4KKyNpbmNsdWRlIDxsaXN0PgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8dmVjdG9yPgorCituYW1lc3BhY2UgbGx2bSB7CisKKyAgY2xhc3MgTGl2ZUludGVydmFsczsKKyAgY2xhc3MgTWFjaGluZUZyYW1lSW5mbzsKKyAgY2xhc3MgTWFjaGluZUZ1bmN0aW9uOworICBjbGFzcyBNYWNoaW5lSW5zdHI7CisgIGNsYXNzIE1hY2hpbmVMb29wSW5mbzsKKyAgY2xhc3MgTWFjaGluZU9wZXJhbmQ7CisgIHN0cnVjdCBNQ1NjaGVkQ2xhc3NEZXNjOworICBjbGFzcyBQcmVzc3VyZURpZmZzOworICBjbGFzcyBQc2V1ZG9Tb3VyY2VWYWx1ZTsKKyAgY2xhc3MgUmVnUHJlc3N1cmVUcmFja2VyOworICBjbGFzcyBVbmRlZlZhbHVlOworICBjbGFzcyBWYWx1ZTsKKworICAvLy8gQW4gaW5kaXZpZHVhbCBtYXBwaW5nIGZyb20gdmlydHVhbCByZWdpc3RlciBudW1iZXIgdG8gU1VuaXQuCisgIHN0cnVjdCBWUmVnMlNVbml0IHsKKyAgICB1bnNpZ25lZCBWaXJ0UmVnOworICAgIExhbmVCaXRtYXNrIExhbmVNYXNrOworICAgIFNVbml0ICpTVTsKKworICAgIFZSZWcyU1VuaXQodW5zaWduZWQgVlJlZywgTGFuZUJpdG1hc2sgTGFuZU1hc2ssIFNVbml0ICpTVSkKKyAgICAgIDogVmlydFJlZyhWUmVnKSwgTGFuZU1hc2soTGFuZU1hc2spLCBTVShTVSkge30KKworICAgIHVuc2lnbmVkIGdldFNwYXJzZVNldEluZGV4KCkgY29uc3QgeworICAgICAgcmV0dXJuIFRhcmdldFJlZ2lzdGVySW5mbzo6dmlydFJlZzJJbmRleChWaXJ0UmVnKTsKKyAgICB9CisgIH07CisKKyAgLy8vIE1hcHBpbmcgZnJvbSB2aXJ0dWFsIHJlZ2lzdGVyIHRvIFNVbml0IGluY2x1ZGluZyBhbiBvcGVyYW5kIGluZGV4LgorICBzdHJ1Y3QgVlJlZzJTVW5pdE9wZXJJZHggOiBwdWJsaWMgVlJlZzJTVW5pdCB7CisgICAgdW5zaWduZWQgT3BlcmFuZEluZGV4OworCisgICAgVlJlZzJTVW5pdE9wZXJJZHgodW5zaWduZWQgVlJlZywgTGFuZUJpdG1hc2sgTGFuZU1hc2ssCisgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgT3BlcmFuZEluZGV4LCBTVW5pdCAqU1UpCisgICAgICA6IFZSZWcyU1VuaXQoVlJlZywgTGFuZU1hc2ssIFNVKSwgT3BlcmFuZEluZGV4KE9wZXJhbmRJbmRleCkge30KKyAgfTsKKworICAvLy8gUmVjb3JkIGEgcGh5c2ljYWwgcmVnaXN0ZXIgYWNjZXNzLgorICAvLy8gRm9yIG5vbi1kYXRhLWRlcGVuZGVudCB1c2VzLCBPcElkeCA9PSAtMS4KKyAgc3RydWN0IFBoeXNSZWdTVU9wZXIgeworICAgIFNVbml0ICpTVTsKKyAgICBpbnQgT3BJZHg7CisgICAgdW5zaWduZWQgUmVnOworCisgICAgUGh5c1JlZ1NVT3BlcihTVW5pdCAqc3UsIGludCBvcCwgdW5zaWduZWQgUik6IFNVKHN1KSwgT3BJZHgob3ApLCBSZWcoUikge30KKworICAgIHVuc2lnbmVkIGdldFNwYXJzZVNldEluZGV4KCkgY29uc3QgeyByZXR1cm4gUmVnOyB9CisgIH07CisKKyAgLy8vIFVzZSBhIFNwYXJzZU11bHRpU2V0IHRvIHRyYWNrIHBoeXNpY2FsIHJlZ2lzdGVycy4gU3RvcmFnZSBpcyBvbmx5CisgIC8vLyBhbGxvY2F0ZWQgb25jZSBmb3IgdGhlIHBhc3MuIEl0IGNhbiBiZSBjbGVhcmVkIGluIGNvbnN0YW50IHRpbWUgYW5kIHJldXNlZAorICAvLy8gd2l0aG91dCBhbnkgZnJlZXMuCisgIHVzaW5nIFJlZzJTVW5pdHNNYXAgPQorICAgICAgU3BhcnNlTXVsdGlTZXQ8UGh5c1JlZ1NVT3BlciwgaWRlbnRpdHk8dW5zaWduZWQ+LCB1aW50MTZfdD47CisKKyAgLy8vIFVzZSBTcGFyc2VTZXQgYXMgYSBTcGFyc2VNYXAgYnkgcmVseWluZyBvbiB0aGUgZmFjdCB0aGF0IGl0IG5ldmVyCisgIC8vLyBjb21wYXJlcyBWYWx1ZVQncywgb25seSB1bnNpZ25lZCBrZXlzLiBUaGlzIGFsbG93cyB0aGUgc2V0IHRvIGJlIGNsZWFyZWQKKyAgLy8vIGJldHdlZW4gc2NoZWR1bGluZyByZWdpb25zIGluIGNvbnN0YW50IHRpbWUgYXMgbG9uZyBhcyBWYWx1ZVQgZG9lcyBub3QKKyAgLy8vIHJlcXVpcmUgYSBkZXN0cnVjdG9yLgorICB1c2luZyBWUmVnMlNVbml0TWFwID0gU3BhcnNlU2V0PFZSZWcyU1VuaXQsIFZpcnRSZWcySW5kZXhGdW5jdG9yPjsKKworICAvLy8gVHJhY2sgbG9jYWwgdXNlcyBvZiB2aXJ0dWFsIHJlZ2lzdGVycy4gVGhlc2UgdXNlcyBhcmUgZ2F0aGVyZWQgYnkgdGhlIERBRworICAvLy8gYnVpbGRlciBhbmQgbWF5IGJlIGNvbnN1bHRlZCBieSB0aGUgc2NoZWR1bGVyIHRvIGF2b2lkIGl0ZXJhdGluZyBhbiBlbnRpcmUKKyAgLy8vIHZyZWcgdXNlIGxpc3QuCisgIHVzaW5nIFZSZWcyU1VuaXRNdWx0aU1hcCA9IFNwYXJzZU11bHRpU2V0PFZSZWcyU1VuaXQsIFZpcnRSZWcySW5kZXhGdW5jdG9yPjsKKworICB1c2luZyBWUmVnMlNVbml0T3BlcklkeE11bHRpTWFwID0KKyAgICAgIFNwYXJzZU11bHRpU2V0PFZSZWcyU1VuaXRPcGVySWR4LCBWaXJ0UmVnMkluZGV4RnVuY3Rvcj47CisKKyAgdXNpbmcgVmFsdWVUeXBlID0gUG9pbnRlclVuaW9uPGNvbnN0IFZhbHVlICosIGNvbnN0IFBzZXVkb1NvdXJjZVZhbHVlICo+OworCisgIHN0cnVjdCBVbmRlcmx5aW5nT2JqZWN0IDogUG9pbnRlckludFBhaXI8VmFsdWVUeXBlLCAxLCBib29sPiB7CisgICAgVW5kZXJseWluZ09iamVjdChWYWx1ZVR5cGUgViwgYm9vbCBNYXlBbGlhcykKKyAgICAgICAgOiBQb2ludGVySW50UGFpcjxWYWx1ZVR5cGUsIDEsIGJvb2w+KFYsIE1heUFsaWFzKSB7fQorCisgICAgVmFsdWVUeXBlIGdldFZhbHVlKCkgY29uc3QgeyByZXR1cm4gZ2V0UG9pbnRlcigpOyB9CisgICAgYm9vbCBtYXlBbGlhcygpIGNvbnN0IHsgcmV0dXJuIGdldEludCgpOyB9CisgIH07CisKKyAgdXNpbmcgVW5kZXJseWluZ09iamVjdHNWZWN0b3IgPSBTbWFsbFZlY3RvcjxVbmRlcmx5aW5nT2JqZWN0LCA0PjsKKworICAvLy8gQSBTY2hlZHVsZURBRyBmb3Igc2NoZWR1bGluZyBsaXN0cyBvZiBNYWNoaW5lSW5zdHIuCisgIGNsYXNzIFNjaGVkdWxlREFHSW5zdHJzIDogcHVibGljIFNjaGVkdWxlREFHIHsKKyAgcHJvdGVjdGVkOgorICAgIGNvbnN0IE1hY2hpbmVMb29wSW5mbyAqTUxJOworICAgIGNvbnN0IE1hY2hpbmVGcmFtZUluZm8gJk1GSTsKKworICAgIC8vLyBUYXJnZXRTY2hlZE1vZGVsIHByb3ZpZGVzIGFuIGludGVyZmFjZSB0byB0aGUgbWFjaGluZSBtb2RlbC4KKyAgICBUYXJnZXRTY2hlZE1vZGVsIFNjaGVkTW9kZWw7CisKKyAgICAvLy8gVHJ1ZSBpZiB0aGUgREFHIGJ1aWxkZXIgc2hvdWxkIHJlbW92ZSBraWxsIGZsYWdzIChpbiBwcmVwYXJhdGlvbiBmb3IKKyAgICAvLy8gcmVzY2hlZHVsaW5nKS4KKyAgICBib29sIFJlbW92ZUtpbGxGbGFnczsKKworICAgIC8vLyBUaGUgc3RhbmRhcmQgREFHIGJ1aWxkZXIgZG9lcyBub3Qgbm9ybWFsbHkgaW5jbHVkZSB0ZXJtaW5hdG9ycyBhcyBEQUcKKyAgICAvLy8gbm9kZXMgYmVjYXVzZSBpdCBkb2VzIG5vdCBjcmVhdGUgdGhlIG5lY2Vzc2FyeSBkZXBlbmRlbmNpZXMgdG8gcHJldmVudAorICAgIC8vLyByZW9yZGVyaW5nLiBBIHNwZWNpYWxpemVkIHNjaGVkdWxlciBjYW4gb3ZlcnJpZGUKKyAgICAvLy8gVGFyZ2V0SW5zdHJJbmZvOjppc1NjaGVkdWxpbmdCb3VuZGFyeSB0aGVuIGVuYWJsZSB0aGlzIGZsYWcgdG8gaW5kaWNhdGUKKyAgICAvLy8gaXQgaGFzIHRha2VuIHJlc3BvbnNpYmlsaXR5IGZvciBzY2hlZHVsaW5nIHRoZSB0ZXJtaW5hdG9yIGNvcnJlY3RseS4KKyAgICBib29sIENhbkhhbmRsZVRlcm1pbmF0b3JzID0gZmFsc2U7CisKKyAgICAvLy8gV2hldGhlciBsYW5lIG1hc2tzIHNob3VsZCBnZXQgdHJhY2tlZC4KKyAgICBib29sIFRyYWNrTGFuZU1hc2tzID0gZmFsc2U7CisKKyAgICAvLyBTdGF0ZSBzcGVjaWZpYyB0byB0aGUgY3VycmVudCBzY2hlZHVsaW5nIHJlZ2lvbi4KKyAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworICAgIC8vLyBUaGUgYmxvY2sgaW4gd2hpY2ggdG8gaW5zZXJ0IGluc3RydWN0aW9ucworICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpCQjsKKworICAgIC8vLyBUaGUgYmVnaW5uaW5nIG9mIHRoZSByYW5nZSB0byBiZSBzY2hlZHVsZWQuCisgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIFJlZ2lvbkJlZ2luOworCisgICAgLy8vIFRoZSBlbmQgb2YgdGhlIHJhbmdlIHRvIGJlIHNjaGVkdWxlZC4KKyAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgUmVnaW9uRW5kOworCisgICAgLy8vIEluc3RydWN0aW9ucyBpbiB0aGlzIHJlZ2lvbiAoZGlzdGFuY2UoUmVnaW9uQmVnaW4sIFJlZ2lvbkVuZCkpLgorICAgIHVuc2lnbmVkIE51bVJlZ2lvbkluc3RyczsKKworICAgIC8vLyBBZnRlciBjYWxsaW5nIEJ1aWxkU2NoZWRHcmFwaCwgZWFjaCBtYWNoaW5lIGluc3RydWN0aW9uIGluIHRoZSBjdXJyZW50CisgICAgLy8vIHNjaGVkdWxpbmcgcmVnaW9uIGlzIG1hcHBlZCB0byBhbiBTVW5pdC4KKyAgICBEZW5zZU1hcDxNYWNoaW5lSW5zdHIqLCBTVW5pdCo+IE1JU1VuaXRNYXA7CisKKyAgICAvLyBTdGF0ZSBpbnRlcm5hbCB0byBEQUcgYnVpbGRpbmcuCisgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisgICAgLy8vIERlZnMsIFVzZXMgLSBSZW1lbWJlciB3aGVyZSBkZWZzIGFuZCB1c2VzIG9mIGVhY2ggcmVnaXN0ZXIgYXJlIGFzIHdlCisgICAgLy8vIGl0ZXJhdGUgdXB3YXJkIHRocm91Z2ggdGhlIGluc3RydWN0aW9ucy4gVGhpcyBpcyBhbGxvY2F0ZWQgaGVyZSBpbnN0ZWFkCisgICAgLy8vIG9mIGluc2lkZSBCdWlsZFNjaGVkR3JhcGggdG8gYXZvaWQgdGhlIG5lZWQgZm9yIGl0IHRvIGJlIGluaXRpYWxpemVkIGFuZAorICAgIC8vLyBkZXN0cnVjdGVkIGZvciBlYWNoIGJsb2NrLgorICAgIFJlZzJTVW5pdHNNYXAgRGVmczsKKyAgICBSZWcyU1VuaXRzTWFwIFVzZXM7CisKKyAgICAvLy8gVHJhY2tzIHRoZSBsYXN0IGluc3RydWN0aW9uKHMpIGluIHRoaXMgcmVnaW9uIGRlZmluaW5nIGVhY2ggdmlydHVhbAorICAgIC8vLyByZWdpc3Rlci4gVGhlcmUgbWF5IGJlIG11bHRpcGxlIGN1cnJlbnQgZGVmaW5pdGlvbnMgZm9yIGEgcmVnaXN0ZXIgd2l0aAorICAgIC8vLyBkaXNqdW5jdCBsYW5lbWFza3MuCisgICAgVlJlZzJTVW5pdE11bHRpTWFwIEN1cnJlbnRWUmVnRGVmczsKKyAgICAvLy8gVHJhY2tzIHRoZSBsYXN0IGluc3RydWN0aW9ucyBpbiB0aGlzIHJlZ2lvbiB1c2luZyBlYWNoIHZpcnR1YWwgcmVnaXN0ZXIuCisgICAgVlJlZzJTVW5pdE9wZXJJZHhNdWx0aU1hcCBDdXJyZW50VlJlZ1VzZXM7CisKKyAgICBBbGlhc0FuYWx5c2lzICpBQUZvckRlcCA9IG51bGxwdHI7CisKKyAgICAvLy8gUmVtZW1iZXIgYSBnZW5lcmljIHNpZGUtZWZmZWN0aW5nIGluc3RydWN0aW9uIGFzIHdlIHByb2NlZWQuCisgICAgLy8vIE5vIG90aGVyIFNVIGV2ZXIgZ2V0cyBzY2hlZHVsZWQgYXJvdW5kIGl0IChleGNlcHQgaW4gdGhlIHNwZWNpYWwKKyAgICAvLy8gY2FzZSBvZiBhIGh1Z2UgcmVnaW9uIHRoYXQgZ2V0cyByZWR1Y2VkKS4KKyAgICBTVW5pdCAqQmFycmllckNoYWluID0gbnVsbHB0cjsKKworICBwdWJsaWM6CisgICAgLy8vIEEgbGlzdCBvZiBTVW5pdHMsIHVzZWQgaW4gVmFsdWUyU1VzTWFwLCBkdXJpbmcgREFHIGNvbnN0cnVjdGlvbi4KKyAgICAvLy8gTm90ZTogdG8gZ2FpbiBzcGVlZCBpdCBtaWdodCBiZSB3b3J0aCBpbnZlc3RpZ2F0aW5nIGFuIG9wdGltaXplZAorICAgIC8vLyBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIGRhdGEgc3RydWN0dXJlLCBzdWNoIGFzIGEgc2luZ2x5IGxpbmtlZCBsaXN0CisgICAgLy8vIHdpdGggYSBtZW1vcnkgcG9vbCAoU21hbGxWZWN0b3Igd2FzIHRyaWVkIGJ1dCBzbG93IGFuZCBTcGFyc2VTZXQgaXMgbm90CisgICAgLy8vIGFwcGxpY2FibGUpLgorICAgIHVzaW5nIFNVTGlzdCA9IHN0ZDo6bGlzdDxTVW5pdCAqPjsKKworICBwcm90ZWN0ZWQ6CisgICAgLy8vIFxicmllZiBBIG1hcCBmcm9tIFZhbHVlVHlwZSB0byBTVUxpc3QsIHVzZWQgZHVyaW5nIERBRyBjb25zdHJ1Y3Rpb24sIGFzCisgICAgLy8vIGEgbWVhbnMgb2YgcmVtZW1iZXJpbmcgd2hpY2ggU1VzIGRlcGVuZCBvbiB3aGljaCBtZW1vcnkgbG9jYXRpb25zLgorICAgIGNsYXNzIFZhbHVlMlNVc01hcDsKKworICAgIC8vLyBSZWR1Y2VzIG1hcHMgaW4gRklGTyBvcmRlciwgYnkgTiBTVXMuIFRoaXMgaXMgYmV0dGVyIHRoYW4gdHVybmluZworICAgIC8vLyBldmVyeSBOdGggbWVtb3J5IFNVIGludG8gQmFycmllckNoYWluIGluIGJ1aWxkU2NoZWRHcmFwaCgpLCBzaW5jZQorICAgIC8vLyBpdCBhdm9pZHMgdW5uZWNlc3NhcnkgZWRnZXMgYmV0d2VlbiBzZWVuIFNVcyBhYm92ZSB0aGUgbmV3IEJhcnJpZXJDaGFpbiwKKyAgICAvLy8gYW5kIHRob3NlIGJlbG93IGl0LgorICAgIHZvaWQgcmVkdWNlSHVnZU1lbU5vZGVNYXBzKFZhbHVlMlNVc01hcCAmc3RvcmVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlMlNVc01hcCAmbG9hZHMsIHVuc2lnbmVkIE4pOworCisgICAgLy8vIFxicmllZiBBZGRzIGEgY2hhaW4gZWRnZSBiZXR3ZWVuIFNVYSBhbmQgU1ViLCBidXQgb25seSBpZiBib3RoCisgICAgLy8vIEFsaWFzQW5hbHlzaXMgYW5kIFRhcmdldCBmYWlsIHRvIGRlbnkgdGhlIGRlcGVuZGVuY3kuCisgICAgdm9pZCBhZGRDaGFpbkRlcGVuZGVuY3koU1VuaXQgKlNVYSwgU1VuaXQgKlNVYiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBMYXRlbmN5ID0gMCk7CisKKyAgICAvLy8gQWRkcyBkZXBlbmRlbmNpZXMgYXMgbmVlZGVkIGZyb20gYWxsIFNVcyBpbiBsaXN0IHRvIFNVLgorICAgIHZvaWQgYWRkQ2hhaW5EZXBlbmRlbmNpZXMoU1VuaXQgKlNVLCBTVUxpc3QgJlNVcywgdW5zaWduZWQgTGF0ZW5jeSkgeworICAgICAgZm9yIChTVW5pdCAqRW50cnkgOiBTVXMpCisgICAgICAgIGFkZENoYWluRGVwZW5kZW5jeShTVSwgRW50cnksIExhdGVuY3kpOworICAgIH0KKworICAgIC8vLyBBZGRzIGRlcGVuZGVuY2llcyBhcyBuZWVkZWQgZnJvbSBhbGwgU1VzIGluIG1hcCwgdG8gU1UuCisgICAgdm9pZCBhZGRDaGFpbkRlcGVuZGVuY2llcyhTVW5pdCAqU1UsIFZhbHVlMlNVc01hcCAmVmFsMlNVc01hcCk7CisKKyAgICAvLy8gQWRkcyBkZXBlbmRlbmNpZXMgYXMgbmVlZGVkIHRvIFNVLCBmcm9tIGFsbCBTVXMgbWFwcGVkIHRvIFYuCisgICAgdm9pZCBhZGRDaGFpbkRlcGVuZGVuY2llcyhTVW5pdCAqU1UsIFZhbHVlMlNVc01hcCAmVmFsMlNVc01hcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlVHlwZSBWKTsKKworICAgIC8vLyBBZGRzIGJhcnJpZXIgY2hhaW4gZWRnZXMgZnJvbSBhbGwgU1VzIGluIG1hcCwgYW5kIHRoZW4gY2xlYXIgdGhlIG1hcC4KKyAgICAvLy8gVGhpcyBpcyBlcXVpdmFsZW50IHRvIGluc2VydEJhcnJpZXJDaGFpbigpLCBidXQgb3B0aW1pemVkIGZvciB0aGUgY29tbW9uCisgICAgLy8vIGNhc2Ugd2hlcmUgdGhlIG5ldyBCYXJyaWVyQ2hhaW4gKGEgZ2xvYmFsIG1lbW9yeSBvYmplY3QpIGhhcyBhIGhpZ2hlcgorICAgIC8vLyBOb2RlTnVtIHRoYW4gYWxsIFNVcyBpbiBtYXAuIEl0IGlzIGFzc3VtZWQgQmFycmllckNoYWluIGhhcyBiZWVuIHNldAorICAgIC8vLyBiZWZvcmUgY2FsbGluZyB0aGlzLgorICAgIHZvaWQgYWRkQmFycmllckNoYWluKFZhbHVlMlNVc01hcCAmbWFwKTsKKworICAgIC8vLyBJbnNlcnRzIGEgYmFycmllciBjaGFpbiBpbiBhIGh1Z2UgcmVnaW9uLCBmYXIgYmVsb3cgY3VycmVudCBTVS4KKyAgICAvLy8gQWRkcyBiYXJyaWVyIGNoYWluIGVkZ2VzIGZyb20gYWxsIFNVcyBpbiBtYXAgd2l0aCBoaWdoZXIgTm9kZU51bXMgdGhhbgorICAgIC8vLyB0aGlzIG5ldyBCYXJyaWVyQ2hhaW4sIGFuZCByZW1vdmUgdGhlbSBmcm9tIG1hcC4gSXQgaXMgYXNzdW1lZAorICAgIC8vLyBCYXJyaWVyQ2hhaW4gaGFzIGJlZW4gc2V0IGJlZm9yZSBjYWxsaW5nIHRoaXMuCisgICAgdm9pZCBpbnNlcnRCYXJyaWVyQ2hhaW4oVmFsdWUyU1VzTWFwICZtYXApOworCisgICAgLy8vIEZvciBhbiB1bmFuYWx5emFibGUgbWVtb3J5IGFjY2VzcywgdGhpcyBWYWx1ZSBpcyB1c2VkIGluIG1hcHMuCisgICAgVW5kZWZWYWx1ZSAqVW5rbm93blZhbHVlOworCisgICAgdXNpbmcgRGJnVmFsdWVWZWN0b3IgPQorICAgICAgICBzdGQ6OnZlY3RvcjxzdGQ6OnBhaXI8TWFjaGluZUluc3RyICosIE1hY2hpbmVJbnN0ciAqPj47CisgICAgLy8vIFJlbWVtYmVyIGluc3RydWN0aW9uIHRoYXQgcHJlY2VkZXMgREJHX1ZBTFVFLgorICAgIC8vLyBUaGVzZSBhcmUgZ2VuZXJhdGVkIGJ5IGJ1aWxkU2NoZWRHcmFwaCBidXQgcGVyc2lzdCBzbyB0aGV5IGNhbiBiZQorICAgIC8vLyByZWZlcmVuY2VkIHdoZW4gZW1pdHRpbmcgdGhlIGZpbmFsIHNjaGVkdWxlLgorICAgIERiZ1ZhbHVlVmVjdG9yIERiZ1ZhbHVlczsKKyAgICBNYWNoaW5lSW5zdHIgKkZpcnN0RGJnVmFsdWUgPSBudWxscHRyOworCisgICAgLy8vIFNldCBvZiBsaXZlIHBoeXNpY2FsIHJlZ2lzdGVycyBmb3IgdXBkYXRpbmcga2lsbCBmbGFncy4KKyAgICBMaXZlUGh5c1JlZ3MgTGl2ZVJlZ3M7CisKKyAgcHVibGljOgorICAgIGV4cGxpY2l0IFNjaGVkdWxlREFHSW5zdHJzKE1hY2hpbmVGdW5jdGlvbiAmbWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUxvb3BJbmZvICptbGksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBSZW1vdmVLaWxsRmxhZ3MgPSBmYWxzZSk7CisKKyAgICB+U2NoZWR1bGVEQUdJbnN0cnMoKSBvdmVycmlkZSA9IGRlZmF1bHQ7CisKKyAgICAvLy8gR2V0cyB0aGUgbWFjaGluZSBtb2RlbCBmb3IgaW5zdHJ1Y3Rpb24gc2NoZWR1bGluZy4KKyAgICBjb25zdCBUYXJnZXRTY2hlZE1vZGVsICpnZXRTY2hlZE1vZGVsKCkgY29uc3QgeyByZXR1cm4gJlNjaGVkTW9kZWw7IH0KKworICAgIC8vLyBSZXNvbHZlcyBhbmQgY2FjaGUgYSByZXNvbHZlZCBzY2hlZHVsaW5nIGNsYXNzIGZvciBhbiBTVW5pdC4KKyAgICBjb25zdCBNQ1NjaGVkQ2xhc3NEZXNjICpnZXRTY2hlZENsYXNzKFNVbml0ICpTVSkgY29uc3QgeworICAgICAgaWYgKCFTVS0+U2NoZWRDbGFzcyAmJiBTY2hlZE1vZGVsLmhhc0luc3RyU2NoZWRNb2RlbCgpKQorICAgICAgICBTVS0+U2NoZWRDbGFzcyA9IFNjaGVkTW9kZWwucmVzb2x2ZVNjaGVkQ2xhc3MoU1UtPmdldEluc3RyKCkpOworICAgICAgcmV0dXJuIFNVLT5TY2hlZENsYXNzOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIGFuIGl0ZXJhdG9yIHRvIHRoZSB0b3Agb2YgdGhlIGN1cnJlbnQgc2NoZWR1bGluZyByZWdpb24uCisgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIGJlZ2luKCkgY29uc3QgeyByZXR1cm4gUmVnaW9uQmVnaW47IH0KKworICAgIC8vLyBSZXR1cm5zIGFuIGl0ZXJhdG9yIHRvIHRoZSBib3R0b20gb2YgdGhlIGN1cnJlbnQgc2NoZWR1bGluZyByZWdpb24uCisgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIGVuZCgpIGNvbnN0IHsgcmV0dXJuIFJlZ2lvbkVuZDsgfQorCisgICAgLy8vIENyZWF0ZXMgYSBuZXcgU1VuaXQgYW5kIHJldHVybiBhIHB0ciB0byBpdC4KKyAgICBTVW5pdCAqbmV3U1VuaXQoTWFjaGluZUluc3RyICpNSSk7CisKKyAgICAvLy8gUmV0dXJucyBhbiBleGlzdGluZyBTVW5pdCBmb3IgdGhpcyBNSSwgb3IgbnVsbHB0ci4KKyAgICBTVW5pdCAqZ2V0U1VuaXQoTWFjaGluZUluc3RyICpNSSkgY29uc3Q7CisKKyAgICAvLy8gSWYgdGhpcyBtZXRob2QgcmV0dXJucyB0cnVlLCBoYW5kbGluZyBvZiB0aGUgc2NoZWR1bGluZyByZWdpb25zCisgICAgLy8vIHRoZW1zZWx2ZXMgKGluIGNhc2Ugb2YgYSBzY2hlZHVsaW5nIGJvdW5kYXJ5IGluIE1CQikgd2lsbCBiZSBkb25lCisgICAgLy8vIGJlZ2lubmluZyB3aXRoIHRoZSB0b3Btb3N0IHJlZ2lvbiBvZiBNQkIuCisgICAgdmlydHVhbCBib29sIGRvTUJCU2NoZWRSZWdpb25zVG9wRG93bigpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgICAvLy8gUHJlcGFyZXMgdG8gcGVyZm9ybSBzY2hlZHVsaW5nIGluIHRoZSBnaXZlbiBibG9jay4KKyAgICB2aXJ0dWFsIHZvaWQgc3RhcnRCbG9jayhNYWNoaW5lQmFzaWNCbG9jayAqQkIpOworCisgICAgLy8vIENsZWFucyB1cCBhZnRlciBzY2hlZHVsaW5nIGluIHRoZSBnaXZlbiBibG9jay4KKyAgICB2aXJ0dWFsIHZvaWQgZmluaXNoQmxvY2soKTsKKworICAgIC8vLyBcYnJpZWYgSW5pdGlhbGl6ZSB0aGUgREFHIGFuZCBjb21tb24gc2NoZWR1bGVyIHN0YXRlIGZvciBhIG5ldworICAgIC8vLyBzY2hlZHVsaW5nIHJlZ2lvbi4gVGhpcyBkb2VzIG5vdCBhY3R1YWxseSBjcmVhdGUgdGhlIERBRywgb25seSBjbGVhcnMKKyAgICAvLy8gaXQuIFRoZSBzY2hlZHVsaW5nIGRyaXZlciBtYXkgY2FsbCBCdWlsZFNjaGVkR3JhcGggbXVsdGlwbGUgdGltZXMgcGVyCisgICAgLy8vIHNjaGVkdWxpbmcgcmVnaW9uLgorICAgIHZpcnR1YWwgdm9pZCBlbnRlclJlZ2lvbihNYWNoaW5lQmFzaWNCbG9jayAqYmIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBiZWdpbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIGVuZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgcmVnaW9uaW5zdHJzKTsKKworICAgIC8vLyBDYWxsZWQgd2hlbiB0aGUgc2NoZWR1bGVyIGhhcyBmaW5pc2hlZCBzY2hlZHVsaW5nIHRoZSBjdXJyZW50IHJlZ2lvbi4KKyAgICB2aXJ0dWFsIHZvaWQgZXhpdFJlZ2lvbigpOworCisgICAgLy8vIEJ1aWxkcyBTVW5pdHMgZm9yIHRoZSBjdXJyZW50IHJlZ2lvbi4KKyAgICAvLy8gSWYgXHAgUlBUcmFja2VyIGlzIG5vbi1udWxsLCBjb21wdXRlIHJlZ2lzdGVyIHByZXNzdXJlIGFzIGEgc2lkZSBlZmZlY3QuCisgICAgLy8vIFRoZSBEQUcgYnVpbGRlciBpcyBhbiBlZmZpY2llbnQgcGxhY2UgdG8gZG8gaXQgYmVjYXVzZSBpdCBhbHJlYWR5IHZpc2l0cworICAgIC8vLyBvcGVyYW5kcy4KKyAgICB2b2lkIGJ1aWxkU2NoZWRHcmFwaChBbGlhc0FuYWx5c2lzICpBQSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBSZWdQcmVzc3VyZVRyYWNrZXIgKlJQVHJhY2tlciA9IG51bGxwdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgUHJlc3N1cmVEaWZmcyAqUERpZmZzID0gbnVsbHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBMaXZlSW50ZXJ2YWxzICpMSVMgPSBudWxscHRyLAorICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgVHJhY2tMYW5lTWFza3MgPSBmYWxzZSk7CisKKyAgICAvLy8gXGJyaWVmIEFkZHMgZGVwZW5kZW5jaWVzIGZyb20gaW5zdHJ1Y3Rpb25zIGluIHRoZSBjdXJyZW50IGxpc3Qgb2YKKyAgICAvLy8gaW5zdHJ1Y3Rpb25zIGJlaW5nIHNjaGVkdWxlZCB0byBzY2hlZHVsaW5nIGJhcnJpZXIuIFdlIHdhbnQgdG8gbWFrZSBzdXJlCisgICAgLy8vIGluc3RydWN0aW9ucyB3aGljaCBkZWZpbmUgcmVnaXN0ZXJzIHRoYXQgYXJlIGVpdGhlciB1c2VkIGJ5IHRoZQorICAgIC8vLyB0ZXJtaW5hdG9yIG9yIGFyZSBsaXZlLW91dCBhcmUgcHJvcGVybHkgc2NoZWR1bGVkLiBUaGlzIGlzIGVzcGVjaWFsbHkKKyAgICAvLy8gaW1wb3J0YW50IHdoZW4gdGhlIGRlZmluaXRpb24gbGF0ZW5jeSBvZiB0aGUgcmV0dXJuIHZhbHVlKHMpIGFyZSB0b28KKyAgICAvLy8gaGlnaCB0byBiZSBoaWRkZW4gYnkgdGhlIGJyYW5jaCBvciB3aGVuIHRoZSBsaXZlb3V0IHJlZ2lzdGVycyB1c2VkIGJ5CisgICAgLy8vIGluc3RydWN0aW9ucyBpbiB0aGUgZmFsbHRocm91Z2ggYmxvY2suCisgICAgdm9pZCBhZGRTY2hlZEJhcnJpZXJEZXBzKCk7CisKKyAgICAvLy8gT3JkZXJzIG5vZGVzIGFjY29yZGluZyB0byBzZWxlY3RlZCBzdHlsZS4KKyAgICAvLy8KKyAgICAvLy8gVHlwaWNhbGx5LCBhIHNjaGVkdWxpbmcgYWxnb3JpdGhtIHdpbGwgaW1wbGVtZW50IHNjaGVkdWxlKCkgd2l0aG91dAorICAgIC8vLyBvdmVycmlkaW5nIGVudGVyUmVnaW9uKCkgb3IgZXhpdFJlZ2lvbigpLgorICAgIHZpcnR1YWwgdm9pZCBzY2hlZHVsZSgpID0gMDsKKworICAgIC8vLyBBbGxvdyB0YXJnZXRzIHRvIHBlcmZvcm0gZmluYWwgc2NoZWR1bGluZyBhY3Rpb25zIGF0IHRoZSBsZXZlbCBvZiB0aGUKKyAgICAvLy8gd2hvbGUgTWFjaGluZUZ1bmN0aW9uLiBCeSBkZWZhdWx0IGRvZXMgbm90aGluZy4KKyAgICB2aXJ0dWFsIHZvaWQgZmluYWxpemVTY2hlZHVsZSgpIHt9CisKKyAgICB2b2lkIGR1bXBOb2RlKGNvbnN0IFNVbml0ICpTVSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgICAvLy8gUmV0dXJucyBhIGxhYmVsIGZvciBhIERBRyBub2RlIHRoYXQgcG9pbnRzIHRvIGFuIGluc3RydWN0aW9uLgorICAgIHN0ZDo6c3RyaW5nIGdldEdyYXBoTm9kZUxhYmVsKGNvbnN0IFNVbml0ICpTVSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgICAvLy8gUmV0dXJucyBhIGxhYmVsIGZvciB0aGUgcmVnaW9uIG9mIGNvZGUgY292ZXJlZCBieSB0aGUgREFHLgorICAgIHN0ZDo6c3RyaW5nIGdldERBR05hbWUoKSBjb25zdCBvdmVycmlkZTsKKworICAgIC8vLyBGaXhlcyByZWdpc3RlciBraWxsIGZsYWdzIHRoYXQgc2NoZWR1bGluZyBoYXMgbWFkZSBpbnZhbGlkLgorICAgIHZvaWQgZml4dXBLaWxscyhNYWNoaW5lQmFzaWNCbG9jayAmTUJCKTsKKworICBwcm90ZWN0ZWQ6CisgICAgdm9pZCBpbml0U1VuaXRzKCk7CisgICAgdm9pZCBhZGRQaHlzUmVnRGF0YURlcHMoU1VuaXQgKlNVLCB1bnNpZ25lZCBPcGVySWR4KTsKKyAgICB2b2lkIGFkZFBoeXNSZWdEZXBzKFNVbml0ICpTVSwgdW5zaWduZWQgT3BlcklkeCk7CisgICAgdm9pZCBhZGRWUmVnRGVmRGVwcyhTVW5pdCAqU1UsIHVuc2lnbmVkIE9wZXJJZHgpOworICAgIHZvaWQgYWRkVlJlZ1VzZURlcHMoU1VuaXQgKlNVLCB1bnNpZ25lZCBPcGVySWR4KTsKKworICAgIC8vLyBJbml0aWFsaXplcyByZWdpc3RlciBsaXZlLXJhbmdlIHN0YXRlIGZvciB1cGRhdGluZyBraWxscy4KKyAgICAvLy8gUG9zdFJBIGhlbHBlciBmb3IgcmV3cml0aW5nIGtpbGwgZmxhZ3MuCisgICAgdm9pZCBzdGFydEJsb2NrRm9yS2lsbHMoTWFjaGluZUJhc2ljQmxvY2sgKkJCKTsKKworICAgIC8vLyBUb2dnbGVzIGEgcmVnaXN0ZXIgb3BlcmFuZCBraWxsIGZsYWcuCisgICAgLy8vCisgICAgLy8vIE90aGVyIGFkanVzdG1lbnRzIG1heSBiZSBtYWRlIHRvIHRoZSBpbnN0cnVjdGlvbiBpZiBuZWNlc3NhcnkuIFJldHVybgorICAgIC8vLyB0cnVlIGlmIHRoZSBvcGVyYW5kIGhhcyBiZWVuIGRlbGV0ZWQsIGZhbHNlIGlmIG5vdC4KKyAgICB2b2lkIHRvZ2dsZUtpbGxGbGFnKE1hY2hpbmVJbnN0ciAmTUksIE1hY2hpbmVPcGVyYW5kICZNTyk7CisKKyAgICAvLy8gUmV0dXJucyBhIG1hc2sgZm9yIHdoaWNoIGxhbmVzIGdldCByZWFkL3dyaXR0ZW4gYnkgdGhlIGdpdmVuIChyZWdpc3RlcikKKyAgICAvLy8gbWFjaGluZSBvcGVyYW5kLgorICAgIExhbmVCaXRtYXNrIGdldExhbmVNYXNrRm9yTU8oY29uc3QgTWFjaGluZU9wZXJhbmQgJk1PKSBjb25zdDsKKyAgfTsKKworICAvLy8gQ3JlYXRlcyBhIG5ldyBTVW5pdCBhbmQgcmV0dXJuIGEgcHRyIHRvIGl0LgorICBpbmxpbmUgU1VuaXQgKlNjaGVkdWxlREFHSW5zdHJzOjpuZXdTVW5pdChNYWNoaW5lSW5zdHIgKk1JKSB7CisjaWZuZGVmIE5ERUJVRworICAgIGNvbnN0IFNVbml0ICpBZGRyID0gU1VuaXRzLmVtcHR5KCkgPyBudWxscHRyIDogJlNVbml0c1swXTsKKyNlbmRpZgorICAgIFNVbml0cy5lbXBsYWNlX2JhY2soTUksICh1bnNpZ25lZClTVW5pdHMuc2l6ZSgpKTsKKyAgICBhc3NlcnQoKEFkZHIgPT0gbnVsbHB0ciB8fCBBZGRyID09ICZTVW5pdHNbMF0pICYmCisgICAgICAgICAgICJTVW5pdHMgc3RkOjp2ZWN0b3IgcmVhbGxvY2F0ZWQgb24gdGhlIGZseSEiKTsKKyAgICByZXR1cm4gJlNVbml0cy5iYWNrKCk7CisgIH0KKworICAvLy8gUmV0dXJucyBhbiBleGlzdGluZyBTVW5pdCBmb3IgdGhpcyBNSSwgb3IgbnVsbHB0ci4KKyAgaW5saW5lIFNVbml0ICpTY2hlZHVsZURBR0luc3Ryczo6Z2V0U1VuaXQoTWFjaGluZUluc3RyICpNSSkgY29uc3QgeworICAgIERlbnNlTWFwPE1hY2hpbmVJbnN0ciosIFNVbml0Kj46OmNvbnN0X2l0ZXJhdG9yIEkgPSBNSVNVbml0TWFwLmZpbmQoTUkpOworICAgIGlmIChJID09IE1JU1VuaXRNYXAuZW5kKCkpCisgICAgICByZXR1cm4gbnVsbHB0cjsKKyAgICByZXR1cm4gSS0+c2Vjb25kOworICB9CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fU0NIRURVTEVEQUdJTlNUUlNfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NjaGVkdWxlREFHTXV0YXRpb24uaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TY2hlZHVsZURBR011dGF0aW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWMyMzY0MgotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TY2hlZHVsZURBR011dGF0aW9uLmgKQEAgLTAsMCArMSwzNCBAQAorLy89PT0tIFNjaGVkdWxlREFHTXV0YXRpb24uaCAtIE1hY2hpbmVJbnN0ciBTY2hlZHVsaW5nIC0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgaW1wbGVtZW50cyB0aGUgU2NoZWR1bGVEQUdNdXRhdGlvbiBjbGFzcywgd2hpY2ggcmVwcmVzZW50cworLy8gYSB0YXJnZXQtc3BlY2lmaWMgbXV0YXRpb24gb2YgdGhlIGRlcGVuZGVuY3kgZ3JhcGggZm9yIHNjaGVkdWxpbmcuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fU0NIRURVTEVEQUdNVVRBVElPTl9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9TQ0hFRFVMRURBR01VVEFUSU9OX0gKKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBTY2hlZHVsZURBR0luc3RyczsKKworLy8vIE11dGF0ZSB0aGUgREFHIGFzIGEgcG9zdHBhc3MgYWZ0ZXIgbm9ybWFsIERBRyBidWlsZGluZy4KK2NsYXNzIFNjaGVkdWxlREFHTXV0YXRpb24geworICB2aXJ0dWFsIHZvaWQgYW5jaG9yKCk7CisKK3B1YmxpYzoKKyAgdmlydHVhbCB+U2NoZWR1bGVEQUdNdXRhdGlvbigpID0gZGVmYXVsdDsKKworICB2aXJ0dWFsIHZvaWQgYXBwbHkoU2NoZWR1bGVEQUdJbnN0cnMgKkRBRykgPSAwOworfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9TQ0hFRFVMRURBR01VVEFUSU9OX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TY2hlZHVsZURGUy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NjaGVkdWxlREZTLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDZhOGM3OQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TY2hlZHVsZURGUy5oCkBAIC0wLDAgKzEsMTk0IEBACisvLz09PS0gU2NoZWR1bGVEQUdJTFAuaCAtIElMUCBtZXRyaWMgZm9yIFNjaGVkdWxlREFHSW5zdHJzIC0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIERlZmluaXRpb24gb2YgYW4gSUxQIG1ldHJpYyBmb3IgbWFjaGluZSBsZXZlbCBpbnN0cnVjdGlvbiBzY2hlZHVsaW5nLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1NDSEVEVUxFREZTX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1NDSEVEVUxFREZTX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0FycmF5UmVmLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2NoZWR1bGVEQUcuaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPGNzdGRpbnQ+CisjaW5jbHVkZSA8dmVjdG9yPgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIHJhd19vc3RyZWFtOworCisvLy8gXGJyaWVmIFJlcHJlc2VudCB0aGUgSUxQIG9mIHRoZSBzdWJEQUcgcm9vdGVkIGF0IGEgREFHIG5vZGUuCisvLy8KKy8vLyBJTFBWYWx1ZXMgc3VtbWFyaXplIHRoZSBEQUcgc3VidHJlZSByb290ZWQgYXQgZWFjaCBub2RlLiBJTFBWYWx1ZXMgYXJlCisvLy8gdmFsaWQgZm9yIGFsbCBub2RlcyByZWdhcmRsZXNzIG9mIHRoZWlyIHN1YnRyZWUgbWVtYmVyc2hpcC4KKy8vLworLy8vIFdoZW4gY29tcHV0ZWQgdXNpbmcgYm90dG9tLXVwIERGUywgdGhpcyBtZXRyaWMgYXNzdW1lcyB0aGF0IHRoZSBEQUcgaXMgYQorLy8vIGZvcmVzdCBvZiB0cmVlcyB3aXRoIHJvb3RzIGF0IHRoZSBib3R0b20gb2YgdGhlIHNjaGVkdWxlIGJyYW5jaGluZyB1cHdhcmQuCitzdHJ1Y3QgSUxQVmFsdWUgeworICB1bnNpZ25lZCBJbnN0ckNvdW50OworICAvLy8gTGVuZ3RoIG1heSBlaXRoZXIgY29ycmVzcG9uZCB0byBkZXB0aCBvciBoZWlnaHQsIGRlcGVuZGluZyBvbiBkaXJlY3Rpb24sCisgIC8vLyBhbmQgY3ljbGVzIG9yIG5vZGVzIGRlcGVuZGluZyBvbiBjb250ZXh0LgorICB1bnNpZ25lZCBMZW5ndGg7CisKKyAgSUxQVmFsdWUodW5zaWduZWQgY291bnQsIHVuc2lnbmVkIGxlbmd0aCk6CisgICAgSW5zdHJDb3VudChjb3VudCksIExlbmd0aChsZW5ndGgpIHt9CisKKyAgLy8gT3JkZXIgYnkgdGhlIElMUCBtZXRyaWMncyB2YWx1ZS4KKyAgYm9vbCBvcGVyYXRvcjwoSUxQVmFsdWUgUkhTKSBjb25zdCB7CisgICAgcmV0dXJuICh1aW50NjRfdClJbnN0ckNvdW50ICogUkhTLkxlbmd0aAorICAgICAgPCAodWludDY0X3QpTGVuZ3RoICogUkhTLkluc3RyQ291bnQ7CisgIH0KKyAgYm9vbCBvcGVyYXRvcj4oSUxQVmFsdWUgUkhTKSBjb25zdCB7CisgICAgcmV0dXJuIFJIUyA8ICp0aGlzOworICB9CisgIGJvb2wgb3BlcmF0b3I8PShJTFBWYWx1ZSBSSFMpIGNvbnN0IHsKKyAgICByZXR1cm4gKHVpbnQ2NF90KUluc3RyQ291bnQgKiBSSFMuTGVuZ3RoCisgICAgICA8PSAodWludDY0X3QpTGVuZ3RoICogUkhTLkluc3RyQ291bnQ7CisgIH0KKyAgYm9vbCBvcGVyYXRvcj49KElMUFZhbHVlIFJIUykgY29uc3QgeworICAgIHJldHVybiBSSFMgPD0gKnRoaXM7CisgIH0KKworICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUykgY29uc3Q7CisKKyAgdm9pZCBkdW1wKCkgY29uc3Q7Cit9OworCisvLy8gXGJyaWVmIENvbXB1dGUgdGhlIHZhbHVlcyBvZiBlYWNoIERBRyBub2RlIGZvciB2YXJpb3VzIG1ldHJpY3MgZHVyaW5nIERGUy4KK2NsYXNzIFNjaGVkREZTUmVzdWx0IHsKKyAgZnJpZW5kIGNsYXNzIFNjaGVkREZTSW1wbDsKKworICBzdGF0aWMgY29uc3QgdW5zaWduZWQgSW52YWxpZFN1YnRyZWVJRCA9IH4wdTsKKworICAvLy8gXGJyaWVmIFBlci1TVW5pdCBkYXRhIGNvbXB1dGVkIGR1cmluZyBERlMgZm9yIHZhcmlvdXMgbWV0cmljcy4KKyAgLy8vCisgIC8vLyBBIG5vZGUncyBTdWJ0cmVlSUQgaXMgc2V0IHRvIGl0c2VsZiB3aGVuIGl0IGlzIHZpc2l0ZWQgdG8gaW5kaWNhdGUgdGhhdCBpdAorICAvLy8gaXMgdGhlIHJvb3Qgb2YgYSBzdWJ0cmVlLiBMYXRlciBpdCBpcyBzZXQgdG8gaXRzIHBhcmVudCB0byBpbmRpY2F0ZSBhbgorICAvLy8gaW50ZXJpb3Igbm9kZS4gRmluYWxseSwgaXQgaXMgc2V0IHRvIGEgcmVwcmVzZW50YXRpdmUgc3VidHJlZSBJRCBkdXJpbmcKKyAgLy8vIGZpbmFsaXphdGlvbi4KKyAgc3RydWN0IE5vZGVEYXRhIHsKKyAgICB1bnNpZ25lZCBJbnN0ckNvdW50ID0gMDsKKyAgICB1bnNpZ25lZCBTdWJ0cmVlSUQgPSBJbnZhbGlkU3VidHJlZUlEOworCisgICAgTm9kZURhdGEoKSA9IGRlZmF1bHQ7CisgIH07CisKKyAgLy8vIFxicmllZiBQZXItU3VidHJlZSBkYXRhIGNvbXB1dGVkIGR1cmluZyBERlMuCisgIHN0cnVjdCBUcmVlRGF0YSB7CisgICAgdW5zaWduZWQgUGFyZW50VHJlZUlEID0gSW52YWxpZFN1YnRyZWVJRDsKKyAgICB1bnNpZ25lZCBTdWJJbnN0ckNvdW50ID0gMDsKKworICAgIFRyZWVEYXRhKCkgPSBkZWZhdWx0OworICB9OworCisgIC8vLyBcYnJpZWYgUmVjb3JkIGEgY29ubmVjdGlvbiBiZXR3ZWVuIHN1YnRyZWVzIGFuZCB0aGUgY29ubmVjdGlvbiBsZXZlbC4KKyAgc3RydWN0IENvbm5lY3Rpb24geworICAgIHVuc2lnbmVkIFRyZWVJRDsKKyAgICB1bnNpZ25lZCBMZXZlbDsKKworICAgIENvbm5lY3Rpb24odW5zaWduZWQgdHJlZSwgdW5zaWduZWQgbGV2ZWwpOiBUcmVlSUQodHJlZSksIExldmVsKGxldmVsKSB7fQorICB9OworCisgIGJvb2wgSXNCb3R0b21VcDsKKyAgdW5zaWduZWQgU3VidHJlZUxpbWl0OworICAvLy8gREZTIHJlc3VsdHMgZm9yIGVhY2ggU1VuaXQgaW4gdGhpcyBEQUcuCisgIHN0ZDo6dmVjdG9yPE5vZGVEYXRhPiBERlNOb2RlRGF0YTsKKworICAvLyBTdG9yZSBwZXItdHJlZSBkYXRhIGluZGV4ZWQgb24gdHJlZSBJRCwKKyAgU21hbGxWZWN0b3I8VHJlZURhdGEsIDE2PiBERlNUcmVlRGF0YTsKKworICAvLyBGb3IgZWFjaCBzdWJ0cmVlIGRpc2NvdmVyZWQgZHVyaW5nIERGUywgcmVjb3JkIGl0cyBjb25uZWN0aW9ucyB0byBvdGhlcgorICAvLyBzdWJ0cmVlcy4KKyAgc3RkOjp2ZWN0b3I8U21hbGxWZWN0b3I8Q29ubmVjdGlvbiwgND4+IFN1YnRyZWVDb25uZWN0aW9uczsKKworICAvLy8gQ2FjaGUgdGhlIGN1cnJlbnQgY29ubmVjdGlvbiBsZXZlbCBvZiBlYWNoIHN1YnRyZWUuCisgIC8vLyBUaGlzIG11dGFibGUgYXJyYXkgaXMgdXBkYXRlZCBkdXJpbmcgc2NoZWR1bGluZy4KKyAgc3RkOjp2ZWN0b3I8dW5zaWduZWQ+IFN1YnRyZWVDb25uZWN0TGV2ZWxzOworCitwdWJsaWM6CisgIFNjaGVkREZTUmVzdWx0KGJvb2wgSXNCVSwgdW5zaWduZWQgbGltKQorICAgIDogSXNCb3R0b21VcChJc0JVKSwgU3VidHJlZUxpbWl0KGxpbSkge30KKworICAvLy8gXGJyaWVmIEdldCB0aGUgbm9kZSBjdXRvZmYgYmVmb3JlIHN1YnRyZWVzIGFyZSBjb25zaWRlcmVkIHNpZ25pZmljYW50LgorICB1bnNpZ25lZCBnZXRTdWJ0cmVlTGltaXQoKSBjb25zdCB7IHJldHVybiBTdWJ0cmVlTGltaXQ7IH0KKworICAvLy8gXGJyaWVmIFJldHVybiB0cnVlIGlmIHRoaXMgREZTUmVzdWx0IGlzIHVuaW5pdGlhbGl6ZWQuCisgIC8vLworICAvLy8gcmVzaXplKCkgaW5pdGlhbGl6ZXMgREZTUmVzdWx0LCB3aGlsZSBjb21wdXRlKCkgcG9wdWxhdGVzIGl0LgorICBib29sIGVtcHR5KCkgY29uc3QgeyByZXR1cm4gREZTTm9kZURhdGEuZW1wdHkoKTsgfQorCisgIC8vLyBcYnJpZWYgQ2xlYXIgdGhlIHJlc3VsdHMuCisgIHZvaWQgY2xlYXIoKSB7CisgICAgREZTTm9kZURhdGEuY2xlYXIoKTsKKyAgICBERlNUcmVlRGF0YS5jbGVhcigpOworICAgIFN1YnRyZWVDb25uZWN0aW9ucy5jbGVhcigpOworICAgIFN1YnRyZWVDb25uZWN0TGV2ZWxzLmNsZWFyKCk7CisgIH0KKworICAvLy8gXGJyaWVmIEluaXRpYWxpemUgdGhlIHJlc3VsdCBkYXRhIHdpdGggdGhlIHNpemUgb2YgdGhlIERBRy4KKyAgdm9pZCByZXNpemUodW5zaWduZWQgTnVtU1VuaXRzKSB7CisgICAgREZTTm9kZURhdGEucmVzaXplKE51bVNVbml0cyk7CisgIH0KKworICAvLy8gXGJyaWVmIENvbXB1dGUgdmFyaW91cyBtZXRyaWNzIGZvciB0aGUgREFHIHdpdGggZ2l2ZW4gcm9vdHMuCisgIHZvaWQgY29tcHV0ZShBcnJheVJlZjxTVW5pdD4gU1VuaXRzKTsKKworICAvLy8gXGJyaWVmIEdldCB0aGUgbnVtYmVyIG9mIGluc3RydWN0aW9ucyBpbiB0aGUgZ2l2ZW4gc3VidHJlZSBhbmQgaXRzCisgIC8vLyBjaGlsZHJlbi4KKyAgdW5zaWduZWQgZ2V0TnVtSW5zdHJzKGNvbnN0IFNVbml0ICpTVSkgY29uc3QgeworICAgIHJldHVybiBERlNOb2RlRGF0YVtTVS0+Tm9kZU51bV0uSW5zdHJDb3VudDsKKyAgfQorCisgIC8vLyBcYnJpZWYgR2V0IHRoZSBudW1iZXIgb2YgaW5zdHJ1Y3Rpb25zIGluIHRoZSBnaXZlbiBzdWJ0cmVlIG5vdCBpbmNsdWRpbmcKKyAgLy8vIGNoaWxkcmVuLgorICB1bnNpZ25lZCBnZXROdW1TdWJJbnN0cnModW5zaWduZWQgU3VidHJlZUlEKSBjb25zdCB7CisgICAgcmV0dXJuIERGU1RyZWVEYXRhW1N1YnRyZWVJRF0uU3ViSW5zdHJDb3VudDsKKyAgfQorCisgIC8vLyBcYnJpZWYgR2V0IHRoZSBJTFAgdmFsdWUgZm9yIGEgREFHIG5vZGUuCisgIC8vLworICAvLy8gQSBsZWFmIG5vZGUgaGFzIGFuIElMUCBvZiAxLzEuCisgIElMUFZhbHVlIGdldElMUChjb25zdCBTVW5pdCAqU1UpIGNvbnN0IHsKKyAgICByZXR1cm4gSUxQVmFsdWUoREZTTm9kZURhdGFbU1UtPk5vZGVOdW1dLkluc3RyQ291bnQsIDEgKyBTVS0+Z2V0RGVwdGgoKSk7CisgIH0KKworICAvLy8gXGJyaWVmIFRoZSBudW1iZXIgb2Ygc3VidHJlZXMgZGV0ZWN0ZWQgaW4gdGhpcyBEQUcuCisgIHVuc2lnbmVkIGdldE51bVN1YnRyZWVzKCkgY29uc3QgeyByZXR1cm4gU3VidHJlZUNvbm5lY3RMZXZlbHMuc2l6ZSgpOyB9CisKKyAgLy8vIFxicmllZiBHZXQgdGhlIElEIG9mIHRoZSBzdWJ0cmVlIHRoZSBnaXZlbiBEQUcgbm9kZSBiZWxvbmdzIHRvLgorICAvLy8KKyAgLy8vIEZvciBjb252ZW5pZW5jZSwgaWYgREZTUmVzdWx0cyBoYXZlIG5vdCBiZWVuIGNvbXB1dGVkIHlldCwgZ2l2ZSBldmVyeXRoaW5nCisgIC8vLyB0cmVlIElEIDAuCisgIHVuc2lnbmVkIGdldFN1YnRyZWVJRChjb25zdCBTVW5pdCAqU1UpIGNvbnN0IHsKKyAgICBpZiAoZW1wdHkoKSkKKyAgICAgIHJldHVybiAwOworICAgIGFzc2VydChTVS0+Tm9kZU51bSA8IERGU05vZGVEYXRhLnNpemUoKSAmJiAgIk5ldyBOb2RlIik7CisgICAgcmV0dXJuIERGU05vZGVEYXRhW1NVLT5Ob2RlTnVtXS5TdWJ0cmVlSUQ7CisgIH0KKworICAvLy8gXGJyaWVmIEdldCB0aGUgY29ubmVjdGlvbiBsZXZlbCBvZiBhIHN1YnRyZWUuCisgIC8vLworICAvLy8gRm9yIGJvdHRvbS11cCB0cmVlcywgdGhlIGNvbm5lY3Rpb24gbGV2ZWwgaXMgdGhlIGxhdGVuY3kgZGVwdGggKGluIGN5Y2xlcykKKyAgLy8vIG9mIHRoZSBkZWVwZXN0IGNvbm5lY3Rpb24gdG8gYW5vdGhlciBzdWJ0cmVlLgorICB1bnNpZ25lZCBnZXRTdWJ0cmVlTGV2ZWwodW5zaWduZWQgU3VidHJlZUlEKSBjb25zdCB7CisgICAgcmV0dXJuIFN1YnRyZWVDb25uZWN0TGV2ZWxzW1N1YnRyZWVJRF07CisgIH0KKworICAvLy8gXGJyaWVmIFNjaGVkdWxlciBjYWxsYmFjayB0byB1cGRhdGUgU3VidHJlZUNvbm5lY3RMZXZlbHMgd2hlbiBhIHRyZWUgaXMKKyAgLy8vIGluaXRpYWxseSBzY2hlZHVsZWQuCisgIHZvaWQgc2NoZWR1bGVUcmVlKHVuc2lnbmVkIFN1YnRyZWVJRCk7Cit9OworCityYXdfb3N0cmVhbSAmb3BlcmF0b3I8PChyYXdfb3N0cmVhbSAmT1MsIGNvbnN0IElMUFZhbHVlICZWYWwpOworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1NDSEVEVUxFREZTX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TY2hlZHVsZUhhemFyZFJlY29nbml6ZXIuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TY2hlZHVsZUhhemFyZFJlY29nbml6ZXIuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hY2U0YTJkCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NjaGVkdWxlSGF6YXJkUmVjb2duaXplci5oCkBAIC0wLDAgKzEsMTIyIEBACisvLz0tIGxsdm0vQ29kZUdlbi9TY2hlZHVsZUhhemFyZFJlY29nbml6ZXIuaCAtIFNjaGVkdWxpbmcgU3VwcG9ydCAtKi0gQysrIC0qLT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBpbXBsZW1lbnRzIHRoZSBTY2hlZHVsZUhhemFyZFJlY29nbml6ZXIgY2xhc3MsIHdoaWNoIGltcGxlbWVudHMKKy8vIGhhemFyZC1hdm9pZGFuY2UgaGV1cmlzdGljcyBmb3Igc2NoZWR1bGluZy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9TQ0hFRFVMRUhBWkFSRFJFQ09HTklaRVJfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fU0NIRURVTEVIQVpBUkRSRUNPR05JWkVSX0gKKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNYWNoaW5lSW5zdHI7CitjbGFzcyBTVW5pdDsKKworLy8vIEhhemFyZFJlY29nbml6ZXIgLSBUaGlzIGRldGVybWluZXMgd2hldGhlciBvciBub3QgYW4gaW5zdHJ1Y3Rpb24gY2FuIGJlCisvLy8gaXNzdWVkIHRoaXMgY3ljbGUsIGFuZCB3aGV0aGVyIG9yIG5vdCBhIG5vb3AgbmVlZHMgdG8gYmUgaW5zZXJ0ZWQgdG8gaGFuZGxlCisvLy8gdGhlIGhhemFyZC4KK2NsYXNzIFNjaGVkdWxlSGF6YXJkUmVjb2duaXplciB7Citwcm90ZWN0ZWQ6CisgIC8vLyBNYXhMb29rQWhlYWQgLSBJbmRpY2F0ZSB0aGUgbnVtYmVyIG9mIGN5Y2xlcyBpbiB0aGUgc2NvcmVib2FyZAorICAvLy8gc3RhdGUuIEltcG9ydGFudCB0byByZXN0b3JlIHRoZSBzdGF0ZSBhZnRlciBiYWNrdHJhY2tpbmcuIEFkZGl0aW9uYWxseSwKKyAgLy8vIE1heExvb2tBaGVhZD0wIGlkZW50aWZpZXMgYSBmYWtlIHJlY29nbml6ZXIsIGFsbG93aW5nIHRoZSBjbGllbnQgdG8KKyAgLy8vIGJ5cGFzcyB2aXJ0dWFsIGNhbGxzLiBDdXJyZW50bHkgdGhlIFBvc3RSQSBzY2hlZHVsZXIgaWdub3JlcyBpdC4KKyAgdW5zaWduZWQgTWF4TG9va0FoZWFkID0gMDsKKworcHVibGljOgorICBTY2hlZHVsZUhhemFyZFJlY29nbml6ZXIoKSA9IGRlZmF1bHQ7CisgIHZpcnR1YWwgflNjaGVkdWxlSGF6YXJkUmVjb2duaXplcigpOworCisgIGVudW0gSGF6YXJkVHlwZSB7CisgICAgTm9IYXphcmQsICAgICAgLy8gVGhpcyBpbnN0cnVjdGlvbiBjYW4gYmUgZW1pdHRlZCBhdCB0aGlzIGN5Y2xlLgorICAgIEhhemFyZCwgICAgICAgIC8vIFRoaXMgaW5zdHJ1Y3Rpb24gY2FuJ3QgYmUgZW1pdHRlZCBhdCB0aGlzIGN5Y2xlLgorICAgIE5vb3BIYXphcmQgICAgIC8vIFRoaXMgaW5zdHJ1Y3Rpb24gY2FuJ3QgYmUgZW1pdHRlZCwgYW5kIG5lZWRzIG5vb3BzLgorICB9OworCisgIHVuc2lnbmVkIGdldE1heExvb2tBaGVhZCgpIGNvbnN0IHsgcmV0dXJuIE1heExvb2tBaGVhZDsgfQorCisgIGJvb2wgaXNFbmFibGVkKCkgY29uc3QgeyByZXR1cm4gTWF4TG9va0FoZWFkICE9IDA7IH0KKworICAvLy8gYXRJc3N1ZUxpbWl0IC0gUmV0dXJuIHRydWUgaWYgbm8gbW9yZSBpbnN0cnVjdGlvbnMgbWF5IGJlIGlzc3VlZCBpbiB0aGlzCisgIC8vLyBjeWNsZS4KKyAgLy8vCisgIC8vLyBGSVhNRTogcmVtb3ZlIHRoaXMgb25jZSBNYWNoaW5lU2NoZWR1bGVyIGlzIHRoZSBvbmx5IGNsaWVudC4KKyAgdmlydHVhbCBib29sIGF0SXNzdWVMaW1pdCgpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgLy8vIGdldEhhemFyZFR5cGUgLSBSZXR1cm4gdGhlIGhhemFyZCB0eXBlIG9mIGVtaXR0aW5nIHRoaXMgbm9kZS4gIFRoZXJlIGFyZQorICAvLy8gdGhyZWUgcG9zc2libGUgcmVzdWx0cy4gIEVpdGhlcjoKKyAgLy8vICAqIE5vSGF6YXJkOiBpdCBpcyBsZWdhbCB0byBpc3N1ZSB0aGlzIGluc3RydWN0aW9uIG9uIHRoaXMgY3ljbGUuCisgIC8vLyAgKiBIYXphcmQ6IGlzc3VpbmcgdGhpcyBpbnN0cnVjdGlvbiB3b3VsZCBzdGFsbCB0aGUgbWFjaGluZS4gIElmIHNvbWUKKyAgLy8vICAgICBvdGhlciBpbnN0cnVjdGlvbiBpcyBhdmFpbGFibGUsIGlzc3VlIGl0IGZpcnN0LgorICAvLy8gICogTm9vcEhhemFyZDogaXNzdWluZyB0aGlzIGluc3RydWN0aW9uIHdvdWxkIGJyZWFrIHRoZSBwcm9ncmFtLiAgSWYKKyAgLy8vICAgICBzb21lIG90aGVyIGluc3RydWN0aW9uIGNhbiBiZSBpc3N1ZWQsIGRvIHNvLCBvdGhlcndpc2UgaXNzdWUgYSBub29wLgorICB2aXJ0dWFsIEhhemFyZFR5cGUgZ2V0SGF6YXJkVHlwZShTVW5pdCAqbSwgaW50IFN0YWxscyA9IDApIHsKKyAgICByZXR1cm4gTm9IYXphcmQ7CisgIH0KKworICAvLy8gUmVzZXQgLSBUaGlzIGNhbGxiYWNrIGlzIGludm9rZWQgd2hlbiBhIG5ldyBibG9jayBvZgorICAvLy8gaW5zdHJ1Y3Rpb25zIGlzIGFib3V0IHRvIGJlIHNjaGVkdWxlLiBUaGUgaGF6YXJkIHN0YXRlIHNob3VsZCBiZQorICAvLy8gc2V0IHRvIGFuIGluaXRpYWxpemVkIHN0YXRlLgorICB2aXJ0dWFsIHZvaWQgUmVzZXQoKSB7fQorCisgIC8vLyBFbWl0SW5zdHJ1Y3Rpb24gLSBUaGlzIGNhbGxiYWNrIGlzIGludm9rZWQgd2hlbiBhbiBpbnN0cnVjdGlvbiBpcworICAvLy8gZW1pdHRlZCwgdG8gYWR2YW5jZSB0aGUgaGF6YXJkIHN0YXRlLgorICB2aXJ0dWFsIHZvaWQgRW1pdEluc3RydWN0aW9uKFNVbml0ICopIHt9CisKKyAgLy8vIFRoaXMgb3ZlcmxvYWQgd2lsbCBiZSB1c2VkIHdoZW4gdGhlIGhhemFyZCByZWNvZ25pemVyIGlzIGJlaW5nIHVzZWQKKyAgLy8vIGJ5IGEgbm9uLXNjaGVkdWxpbmcgcGFzcywgd2hpY2ggZG9lcyBub3QgdXNlIFNVbml0cy4KKyAgdmlydHVhbCB2b2lkIEVtaXRJbnN0cnVjdGlvbihNYWNoaW5lSW5zdHIgKikge30KKworICAvLy8gUHJlRW1pdE5vb3BzIC0gVGhpcyBjYWxsYmFjayBpcyBpbnZva2VkIHByaW9yIHRvIGVtaXR0aW5nIGFuIGluc3RydWN0aW9uLgorICAvLy8gSXQgc2hvdWxkIHJldHVybiB0aGUgbnVtYmVyIG9mIG5vb3BzIHRvIGVtaXQgcHJpb3IgdG8gdGhlIHByb3ZpZGVkCisgIC8vLyBpbnN0cnVjdGlvbi4KKyAgLy8vIE5vdGU6IFRoaXMgaXMgb25seSB1c2VkIGR1cmluZyBQb3N0UkEgc2NoZWR1bGluZy4gRW1pdE5vb3AgaXMgbm90IGNhbGxlZAorICAvLy8gZm9yIHRoZXNlIG5vb3BzLgorICB2aXJ0dWFsIHVuc2lnbmVkIFByZUVtaXROb29wcyhTVW5pdCAqKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICAvLy8gVGhpcyBvdmVybG9hZCB3aWxsIGJlIHVzZWQgd2hlbiB0aGUgaGF6YXJkIHJlY29nbml6ZXIgaXMgYmVpbmcgdXNlZAorICAvLy8gYnkgYSBub24tc2NoZWR1bGluZyBwYXNzLCB3aGljaCBkb2VzIG5vdCB1c2UgU1VuaXRzLgorICB2aXJ0dWFsIHVuc2lnbmVkIFByZUVtaXROb29wcyhNYWNoaW5lSW5zdHIgKikgeworICAgIHJldHVybiAwOworICB9CisKKyAgLy8vIFNob3VsZFByZWZlckFub3RoZXIgLSBUaGlzIGNhbGxiYWNrIG1heSBiZSBpbnZva2VkIGlmIGdldEhhemFyZFR5cGUKKyAgLy8vIHJldHVybnMgTm9IYXphcmQuIElmLCBldmVuIHRob3VnaCB0aGVyZSBpcyBubyBoYXphcmQsIGl0IHdvdWxkIGJlIGJldHRlciB0bworICAvLy8gc2NoZWR1bGUgYW5vdGhlciBhdmFpbGFibGUgaW5zdHJ1Y3Rpb24sIHRoaXMgY2FsbGJhY2sgc2hvdWxkIHJldHVybiB0cnVlLgorICB2aXJ0dWFsIGJvb2wgU2hvdWxkUHJlZmVyQW5vdGhlcihTVW5pdCAqKSB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIEFkdmFuY2VDeWNsZSAtIFRoaXMgY2FsbGJhY2sgaXMgaW52b2tlZCB3aGVuZXZlciB0aGUgbmV4dCB0b3AtZG93bgorICAvLy8gaW5zdHJ1Y3Rpb24gdG8gYmUgc2NoZWR1bGVkIGNhbm5vdCBpc3N1ZSBpbiB0aGUgY3VycmVudCBjeWNsZSwgZWl0aGVyCisgIC8vLyBiZWNhdXNlIG9mIGxhdGVuY3kgb3IgcmVzb3VyY2UgY29uZmxpY3RzLiAgVGhpcyBzaG91bGQgaW5jcmVtZW50IHRoZQorICAvLy8gaW50ZXJuYWwgc3RhdGUgb2YgdGhlIGhhemFyZCByZWNvZ25pemVyIHNvIHRoYXQgcHJldmlvdXNseSAiSGF6YXJkIgorICAvLy8gaW5zdHJ1Y3Rpb25zIHdpbGwgbm93IG5vdCBiZSBoYXphcmRzLgorICB2aXJ0dWFsIHZvaWQgQWR2YW5jZUN5Y2xlKCkge30KKworICAvLy8gUmVjZWRlQ3ljbGUgLSBUaGlzIGNhbGxiYWNrIGlzIGludm9rZWQgd2hlbmV2ZXIgdGhlIG5leHQgYm90dG9tLXVwCisgIC8vLyBpbnN0cnVjdGlvbiB0byBiZSBzY2hlZHVsZWQgY2Fubm90IGlzc3VlIGluIHRoZSBjdXJyZW50IGN5Y2xlLCBlaXRoZXIKKyAgLy8vIGJlY2F1c2Ugb2YgbGF0ZW5jeSBvciByZXNvdXJjZSBjb25mbGljdHMuCisgIHZpcnR1YWwgdm9pZCBSZWNlZGVDeWNsZSgpIHt9CisKKyAgLy8vIEVtaXROb29wIC0gVGhpcyBjYWxsYmFjayBpcyBpbnZva2VkIHdoZW4gYSBub29wIHdhcyBhZGRlZCB0byB0aGUKKyAgLy8vIGluc3RydWN0aW9uIHN0cmVhbS4KKyAgdmlydHVhbCB2b2lkIEVtaXROb29wKCkgeworICAgIC8vIERlZmF1bHQgaW1wbGVtZW50YXRpb246IGNvdW50IGl0IGFzIGEgY3ljbGUuCisgICAgQWR2YW5jZUN5Y2xlKCk7CisgIH0KK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fU0NIRURVTEVIQVpBUkRSRUNPR05JWkVSX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TY2hlZHVsZXJSZWdpc3RyeS5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NjaGVkdWxlclJlZ2lzdHJ5LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmFkZjkyNwotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TY2hlZHVsZXJSZWdpc3RyeS5oCkBAIC0wLDAgKzEsMTA1IEBACisvLz09PS0gbGx2bS9Db2RlR2VuL1NjaGVkdWxlclJlZ2lzdHJ5LmggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBjb250YWlucyB0aGUgaW1wbGVtZW50YXRpb24gZm9yIGluc3RydWN0aW9uIHNjaGVkdWxlciBmdW5jdGlvbgorLy8gcGFzcyByZWdpc3RyeSAoUmVnaXN0ZXJTY2hlZHVsZXIpLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1NDSEVEVUxFUlJFR0lTVFJZX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1NDSEVEVUxFUlJFR0lTVFJZX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lUGFzc1JlZ2lzdHJ5LmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0NvZGVHZW4uaCIKKworbmFtZXNwYWNlIGxsdm0geworCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vCisvLy8gUmVnaXN0ZXJTY2hlZHVsZXIgY2xhc3MgLSBUcmFjayB0aGUgcmVnaXN0cmF0aW9uIG9mIGluc3RydWN0aW9uIHNjaGVkdWxlcnMuCisvLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKK2NsYXNzIFNjaGVkdWxlREFHU0ROb2RlczsKK2NsYXNzIFNlbGVjdGlvbkRBR0lTZWw7CisKK2NsYXNzIFJlZ2lzdGVyU2NoZWR1bGVyIDogcHVibGljIE1hY2hpbmVQYXNzUmVnaXN0cnlOb2RlIHsKK3B1YmxpYzoKKyAgdXNpbmcgRnVuY3Rpb25QYXNzQ3RvciA9IFNjaGVkdWxlREFHU0ROb2RlcyAqKCopKFNlbGVjdGlvbkRBR0lTZWwqLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29kZUdlbk9wdDo6TGV2ZWwpOworCisgIHN0YXRpYyBNYWNoaW5lUGFzc1JlZ2lzdHJ5IFJlZ2lzdHJ5OworCisgIFJlZ2lzdGVyU2NoZWR1bGVyKGNvbnN0IGNoYXIgKk4sIGNvbnN0IGNoYXIgKkQsIEZ1bmN0aW9uUGFzc0N0b3IgQykKKyAgOiBNYWNoaW5lUGFzc1JlZ2lzdHJ5Tm9kZShOLCBELCAoTWFjaGluZVBhc3NDdG9yKUMpCisgIHsgUmVnaXN0cnkuQWRkKHRoaXMpOyB9CisgIH5SZWdpc3RlclNjaGVkdWxlcigpIHsgUmVnaXN0cnkuUmVtb3ZlKHRoaXMpOyB9CisKKworICAvLyBBY2Nlc3NvcnMuCisgIFJlZ2lzdGVyU2NoZWR1bGVyICpnZXROZXh0KCkgY29uc3QgeworICAgIHJldHVybiAoUmVnaXN0ZXJTY2hlZHVsZXIgKilNYWNoaW5lUGFzc1JlZ2lzdHJ5Tm9kZTo6Z2V0TmV4dCgpOworICB9CisKKyAgc3RhdGljIFJlZ2lzdGVyU2NoZWR1bGVyICpnZXRMaXN0KCkgeworICAgIHJldHVybiAoUmVnaXN0ZXJTY2hlZHVsZXIgKilSZWdpc3RyeS5nZXRMaXN0KCk7CisgIH0KKworICBzdGF0aWMgdm9pZCBzZXRMaXN0ZW5lcihNYWNoaW5lUGFzc1JlZ2lzdHJ5TGlzdGVuZXIgKkwpIHsKKyAgICBSZWdpc3RyeS5zZXRMaXN0ZW5lcihMKTsKKyAgfQorfTsKKworLy8vIGNyZWF0ZUJVUlJMaXN0REFHU2NoZWR1bGVyIC0gVGhpcyBjcmVhdGVzIGEgYm90dG9tIHVwIHJlZ2lzdGVyIHVzYWdlCisvLy8gcmVkdWN0aW9uIGxpc3Qgc2NoZWR1bGVyLgorU2NoZWR1bGVEQUdTRE5vZGVzICpjcmVhdGVCVVJSTGlzdERBR1NjaGVkdWxlcihTZWxlY3Rpb25EQUdJU2VsICpJUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29kZUdlbk9wdDo6TGV2ZWwgT3B0TGV2ZWwpOworCisvLy8gY3JlYXRlQlVSUkxpc3REQUdTY2hlZHVsZXIgLSBUaGlzIGNyZWF0ZXMgYSBib3R0b20gdXAgbGlzdCBzY2hlZHVsZXIgdGhhdAorLy8vIHNjaGVkdWxlcyBub2RlcyBpbiBzb3VyY2UgY29kZSBvcmRlciB3aGVuIHBvc3NpYmxlLgorU2NoZWR1bGVEQUdTRE5vZGVzICpjcmVhdGVTb3VyY2VMaXN0REFHU2NoZWR1bGVyKFNlbGVjdGlvbkRBR0lTZWwgKklTLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvZGVHZW5PcHQ6OkxldmVsIE9wdExldmVsKTsKKworLy8vIGNyZWF0ZUh5YnJpZExpc3REQUdTY2hlZHVsZXIgLSBUaGlzIGNyZWF0ZXMgYSBib3R0b20gdXAgcmVnaXN0ZXIgcHJlc3N1cmUKKy8vLyBhd2FyZSBsaXN0IHNjaGVkdWxlciB0aGF0IG1ha2UgdXNlIG9mIGxhdGVuY3kgaW5mb3JtYXRpb24gdG8gYXZvaWQgc3RhbGxzCisvLy8gZm9yIGxvbmcgbGF0ZW5jeSBpbnN0cnVjdGlvbnMgaW4gbG93IHJlZ2lzdGVyIHByZXNzdXJlIG1vZGUuIEluIGhpZ2gKKy8vLyByZWdpc3RlciBwcmVzc3VyZSBtb2RlIGl0IHNjaGVkdWxlcyB0byByZWR1Y2UgcmVnaXN0ZXIgcHJlc3N1cmUuCitTY2hlZHVsZURBR1NETm9kZXMgKmNyZWF0ZUh5YnJpZExpc3REQUdTY2hlZHVsZXIoU2VsZWN0aW9uREFHSVNlbCAqSVMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29kZUdlbk9wdDo6TGV2ZWwpOworCisvLy8gY3JlYXRlSUxQTGlzdERBR1NjaGVkdWxlciAtIFRoaXMgY3JlYXRlcyBhIGJvdHRvbSB1cCByZWdpc3RlciBwcmVzc3VyZQorLy8vIGF3YXJlIGxpc3Qgc2NoZWR1bGVyIHRoYXQgdHJpZXMgdG8gaW5jcmVhc2UgaW5zdHJ1Y3Rpb24gbGV2ZWwgcGFyYWxsZWxpc20KKy8vLyBpbiBsb3cgcmVnaXN0ZXIgcHJlc3N1cmUgbW9kZS4gSW4gaGlnaCByZWdpc3RlciBwcmVzc3VyZSBtb2RlIGl0IHNjaGVkdWxlcworLy8vIHRvIHJlZHVjZSByZWdpc3RlciBwcmVzc3VyZS4KK1NjaGVkdWxlREFHU0ROb2RlcyAqY3JlYXRlSUxQTGlzdERBR1NjaGVkdWxlcihTZWxlY3Rpb25EQUdJU2VsICpJUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlR2VuT3B0OjpMZXZlbCk7CisKKy8vLyBjcmVhdGVGYXN0REFHU2NoZWR1bGVyIC0gVGhpcyBjcmVhdGVzIGEgImZhc3QiIHNjaGVkdWxlci4KKy8vLworU2NoZWR1bGVEQUdTRE5vZGVzICpjcmVhdGVGYXN0REFHU2NoZWR1bGVyKFNlbGVjdGlvbkRBR0lTZWwgKklTLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvZGVHZW5PcHQ6OkxldmVsIE9wdExldmVsKTsKKworLy8vIGNyZWF0ZVZMSVdEQUdTY2hlZHVsZXIgLSBTY2hlZHVsZXIgZm9yIFZMSVcgdGFyZ2V0cy4gVGhpcyBjcmVhdGVzIHRvcCBkb3duCisvLy8gREZBIGRyaXZlbiBsaXN0IHNjaGVkdWxlciB3aXRoIGNsdXN0ZXJpbmcgaGV1cmlzdGljIHRvIGNvbnRyb2wKKy8vLyByZWdpc3RlciBwcmVzc3VyZS4KK1NjaGVkdWxlREFHU0ROb2RlcyAqY3JlYXRlVkxJV0RBR1NjaGVkdWxlcihTZWxlY3Rpb25EQUdJU2VsICpJUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlR2VuT3B0OjpMZXZlbCBPcHRMZXZlbCk7CisvLy8gY3JlYXRlRGVmYXVsdFNjaGVkdWxlciAtIFRoaXMgY3JlYXRlcyBhbiBpbnN0cnVjdGlvbiBzY2hlZHVsZXIgYXBwcm9wcmlhdGUKKy8vLyBmb3IgdGhlIHRhcmdldC4KK1NjaGVkdWxlREFHU0ROb2RlcyAqY3JlYXRlRGVmYXVsdFNjaGVkdWxlcihTZWxlY3Rpb25EQUdJU2VsICpJUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2RlR2VuT3B0OjpMZXZlbCBPcHRMZXZlbCk7CisKKy8vLyBjcmVhdGVEQUdMaW5lYXJpemVyIC0gVGhpcyBjcmVhdGVzIGEgIm5vLXNjaGVkdWxpbmciIHNjaGVkdWxlciB3aGljaAorLy8vIGxpbmVhcml6ZSB0aGUgREFHIHVzaW5nIHRvcG9sb2dpY2FsIG9yZGVyLgorU2NoZWR1bGVEQUdTRE5vZGVzICpjcmVhdGVEQUdMaW5lYXJpemVyKFNlbGVjdGlvbkRBR0lTZWwgKklTLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvZGVHZW5PcHQ6OkxldmVsIE9wdExldmVsKTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9TQ0hFRFVMRVJSRUdJU1RSWV9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vU2NvcmVib2FyZEhhemFyZFJlY29nbml6ZXIuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TY29yZWJvYXJkSGF6YXJkUmVjb2duaXplci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2NmFiNTMKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vU2NvcmVib2FyZEhhemFyZFJlY29nbml6ZXIuaApAQCAtMCwwICsxLDEyOCBAQAorLy89LSBsbHZtL0NvZGVHZW4vU2NvcmVib2FyZEhhemFyZFJlY29nbml6ZXIuaCAtIFNjaGVkdWxlIFN1cHBvcnQgLSotIEMrKyAtKi09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgZGVmaW5lcyB0aGUgU2NvcmVib2FyZEhhemFyZFJlY29nbml6ZXIgY2xhc3MsIHdoaWNoCisvLyBlbmNhcHN1bGF0ZXMgaGF6YXJkLWF2b2lkYW5jZSBoZXVyaXN0aWNzIGZvciBzY2hlZHVsaW5nLCBiYXNlZCBvbiB0aGUKKy8vIHNjaGVkdWxpbmcgaXRpbmVyYXJpZXMgc3BlY2lmaWVkIGZvciB0aGUgdGFyZ2V0LgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1NDT1JFQk9BUkRIQVpBUkRSRUNPR05JWkVSX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1NDT1JFQk9BUkRIQVpBUkRSRUNPR05JWkVSX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9TY2hlZHVsZUhhemFyZFJlY29nbml6ZXIuaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPGNzdGRkZWY+CisjaW5jbHVkZSA8Y3N0cmluZz4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBJbnN0ckl0aW5lcmFyeURhdGE7CitjbGFzcyBTY2hlZHVsZURBRzsKK2NsYXNzIFNVbml0OworCitjbGFzcyBTY29yZWJvYXJkSGF6YXJkUmVjb2duaXplciA6IHB1YmxpYyBTY2hlZHVsZUhhemFyZFJlY29nbml6ZXIgeworICAvLyBTY29yZWJvYXJkIHRvIHRyYWNrIGZ1bmN0aW9uIHVuaXQgdXNhZ2UuIFNjb3JlYm9hcmRbMF0gaXMgYQorICAvLyBtYXNrIG9mIHRoZSBGVXMgaW4gdXNlIGluIHRoZSBjeWNsZSBjdXJyZW50bHkgYmVpbmcKKyAgLy8gc2NoZWR1bGUuIFNjb3JlYm9hcmRbMV0gaXMgYSBtYXNrIGZvciB0aGUgbmV4dCBjeWNsZS4gVGhlCisgIC8vIFNjb3JlYm9hcmQgaXMgdXNlZCBhcyBhIGNpcmN1bGFyIGJ1ZmZlciB3aXRoIHRoZSBjdXJyZW50IGN5Y2xlCisgIC8vIGluZGljYXRlZCBieSBIZWFkLgorICAvLworICAvLyBTY29yZWJvYXJkIGFsd2F5cyBjb3VudHMgY3ljbGVzIGluIGZvcndhcmQgZXhlY3V0aW9uIG9yZGVyLiBJZiB1c2VkIGJ5IGEKKyAgLy8gYm90dG9tLXVwIHNjaGVkdWxlciwgdGhlbiB0aGUgc2NvcmVib2FyZCBjeWNsZXMgYXJlIHRoZSBpbnZlcnNlIG9mIHRoZQorICAvLyBzY2hlZHVsZXIncyBjeWNsZXMuCisgIGNsYXNzIFNjb3JlYm9hcmQgeworICAgIHVuc2lnbmVkICpEYXRhID0gbnVsbHB0cjsKKworICAgIC8vIFRoZSBtYXhpbXVtIG51bWJlciBvZiBjeWNsZXMgbW9uaXRvcmVkIGJ5IHRoZSBTY29yZWJvYXJkLiBUaGlzCisgICAgLy8gdmFsdWUgaXMgZGV0ZXJtaW5lZCBiYXNlZCBvbiB0aGUgdGFyZ2V0IGl0aW5lcmFyaWVzIHRvIGVuc3VyZQorICAgIC8vIHRoYXQgYWxsIGhhemFyZHMgY2FuIGJlIHRyYWNrZWQuCisgICAgc2l6ZV90IERlcHRoID0gMDsKKworICAgIC8vIEluZGljZXMgaW50byB0aGUgU2NvcmVib2FyZCB0aGF0IHJlcHJlc2VudCB0aGUgY3VycmVudCBjeWNsZS4KKyAgICBzaXplX3QgSGVhZCA9IDA7CisKKyAgcHVibGljOgorICAgIFNjb3JlYm9hcmQoKSA9IGRlZmF1bHQ7CisKKyAgICB+U2NvcmVib2FyZCgpIHsKKyAgICAgIGRlbGV0ZVtdIERhdGE7CisgICAgfQorCisgICAgc2l6ZV90IGdldERlcHRoKCkgY29uc3QgeyByZXR1cm4gRGVwdGg7IH0KKworICAgIHVuc2lnbmVkJiBvcGVyYXRvcltdKHNpemVfdCBpZHgpIGNvbnN0IHsKKyAgICAgIC8vIERlcHRoIGlzIGV4cGVjdGVkIHRvIGJlIGEgcG93ZXItb2YtMi4KKyAgICAgIGFzc2VydChEZXB0aCAmJiAhKERlcHRoICYgKERlcHRoIC0gMSkpICYmCisgICAgICAgICAgICAgIlNjb3JlYm9hcmQgd2FzIG5vdCBpbml0aWFsaXplZCBwcm9wZXJseSEiKTsKKworICAgICAgcmV0dXJuIERhdGFbKEhlYWQgKyBpZHgpICYgKERlcHRoLTEpXTsKKyAgICB9CisKKyAgICB2b2lkIHJlc2V0KHNpemVfdCBkID0gMSkgeworICAgICAgaWYgKCFEYXRhKSB7CisgICAgICAgIERlcHRoID0gZDsKKyAgICAgICAgRGF0YSA9IG5ldyB1bnNpZ25lZFtEZXB0aF07CisgICAgICB9CisKKyAgICAgIG1lbXNldChEYXRhLCAwLCBEZXB0aCAqIHNpemVvZihEYXRhWzBdKSk7CisgICAgICBIZWFkID0gMDsKKyAgICB9CisKKyAgICB2b2lkIGFkdmFuY2UoKSB7CisgICAgICBIZWFkID0gKEhlYWQgKyAxKSAmIChEZXB0aC0xKTsKKyAgICB9CisKKyAgICB2b2lkIHJlY2VkZSgpIHsKKyAgICAgIEhlYWQgPSAoSGVhZCAtIDEpICYgKERlcHRoLTEpOworICAgIH0KKworICAgIC8vIFByaW50IHRoZSBzY29yZWJvYXJkLgorICAgIHZvaWQgZHVtcCgpIGNvbnN0OworICB9OworCisgIC8vIFN1cHBvcnQgZm9yIHRyYWNpbmcgU2NvcmVib2FyZEhhemFyZFJlY29nbml6ZXIgYXMgYSBjb21wb25lbnQgd2l0aGluCisgIC8vIGFub3RoZXIgbW9kdWxlLgorICBjb25zdCBjaGFyICpEZWJ1Z1R5cGU7CisKKyAgLy8gSXRpbmVyYXJ5IGRhdGEgZm9yIHRoZSB0YXJnZXQuCisgIGNvbnN0IEluc3RySXRpbmVyYXJ5RGF0YSAqSXRpbkRhdGE7CisKKyAgY29uc3QgU2NoZWR1bGVEQUcgKkRBRzsKKworICAvLy8gSXNzdWVXaWR0aCAtIE1heCBpc3N1ZSBwZXIgY3ljbGUuIDA9VW5rbm93bi4KKyAgdW5zaWduZWQgSXNzdWVXaWR0aCA9IDA7CisKKyAgLy8vIElzc3VlQ291bnQgLSBDb3VudCBpbnN0cnVjdGlvbnMgaXNzdWVkIGluIHRoaXMgY3ljbGUuCisgIHVuc2lnbmVkIElzc3VlQ291bnQgPSAwOworCisgIFNjb3JlYm9hcmQgUmVzZXJ2ZWRTY29yZWJvYXJkOworICBTY29yZWJvYXJkIFJlcXVpcmVkU2NvcmVib2FyZDsKKworcHVibGljOgorICBTY29yZWJvYXJkSGF6YXJkUmVjb2duaXplcihjb25zdCBJbnN0ckl0aW5lcmFyeURhdGEgKkl0aW5EYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTY2hlZHVsZURBRyAqREFHLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpQYXJlbnREZWJ1Z1R5cGUgPSAiIik7CisKKyAgLy8vIGF0SXNzdWVMaW1pdCAtIFJldHVybiB0cnVlIGlmIG5vIG1vcmUgaW5zdHJ1Y3Rpb25zIG1heSBiZSBpc3N1ZWQgaW4gdGhpcworICAvLy8gY3ljbGUuCisgIGJvb2wgYXRJc3N1ZUxpbWl0KCkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgLy8gU3RhbGxzIHByb3ZpZGVzIGFuIGN5Y2xlIG9mZnNldCBhdCB3aGljaCBTVSB3aWxsIGJlIHNjaGVkdWxlZC4gSXQgd2lsbCBiZQorICAvLyBuZWdhdGl2ZSBmb3IgYm90dG9tLXVwIHNjaGVkdWxpbmcuCisgIEhhemFyZFR5cGUgZ2V0SGF6YXJkVHlwZShTVW5pdCAqU1UsIGludCBTdGFsbHMpIG92ZXJyaWRlOworICB2b2lkIFJlc2V0KCkgb3ZlcnJpZGU7CisgIHZvaWQgRW1pdEluc3RydWN0aW9uKFNVbml0ICpTVSkgb3ZlcnJpZGU7CisgIHZvaWQgQWR2YW5jZUN5Y2xlKCkgb3ZlcnJpZGU7CisgIHZvaWQgUmVjZWRlQ3ljbGUoKSBvdmVycmlkZTsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fU0NPUkVCT0FSREhBWkFSRFJFQ09HTklaRVJfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBRy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBRy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFmNDNjOWIKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vU2VsZWN0aW9uREFHLmgKQEAgLTAsMCArMSwxNjExIEBACisvLz09PS0gbGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBRy5oIC0gSW5zdFNlbGVjdGlvbiBEQUcgLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZWNsYXJlcyB0aGUgU2VsZWN0aW9uREFHIGNsYXNzLCBhbmQgdHJhbnNpdGl2ZWx5IGRlZmluZXMgdGhlCisvLyBTRE5vZGUgY2xhc3MgYW5kIHN1YmNsYXNzZXMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fU0VMRUNUSU9OREFHX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1NFTEVDVElPTkRBR19ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9BUEZsb2F0LmgiCisjaW5jbHVkZSAibGx2bS9BRFQvQVBJbnQuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9BcnJheVJlZi5oIgorI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VTZXQuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9Gb2xkaW5nU2V0LmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU2V0VmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TdHJpbmdNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9pbGlzdC5oIgorI2luY2x1ZGUgImxsdm0vQURUL2l0ZXJhdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvaXRlcmF0b3JfcmFuZ2UuaCIKKyNpbmNsdWRlICJsbHZtL0FuYWx5c2lzL0FsaWFzQW5hbHlzaXMuaCIKKyNpbmNsdWRlICJsbHZtL0FuYWx5c2lzL0RpdmVyZ2VuY2VBbmFseXNpcy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9EQUdDb21iaW5lLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0Z1bmN0aW9uTG93ZXJpbmdJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL0lTRE9wY29kZXMuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVNZW1PcGVyYW5kLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBR05vZGVzLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1ZhbHVlVHlwZXMuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0RlYnVnTG9jLmgiCisjaW5jbHVkZSAibGx2bS9JUi9JbnN0cnVjdGlvbnMuaCIKKyNpbmNsdWRlICJsbHZtL0lSL01ldGFkYXRhLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0FsbG9jYXRvci5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9BcnJheVJlY3ljbGVyLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0F0b21pY09yZGVyaW5nLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0Nhc3RpbmcuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvQ29kZUdlbi5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9FcnJvckhhbmRsaW5nLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L01hY2hpbmVWYWx1ZVR5cGUuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvUmVjeWNsaW5nQWxsb2NhdG9yLmgiCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8Y3N0ZGludD4KKyNpbmNsdWRlIDxmdW5jdGlvbmFsPgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dHVwbGU+CisjaW5jbHVkZSA8dXRpbGl0eT4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgQmxvY2tBZGRyZXNzOworY2xhc3MgQ29uc3RhbnQ7CitjbGFzcyBDb25zdGFudEZQOworY2xhc3MgQ29uc3RhbnRJbnQ7CitjbGFzcyBEYXRhTGF5b3V0Oworc3RydWN0IGZsdFNlbWFudGljczsKK2NsYXNzIEdsb2JhbFZhbHVlOworc3RydWN0IEtub3duQml0czsKK2NsYXNzIExMVk1Db250ZXh0OworY2xhc3MgTWFjaGluZUJhc2ljQmxvY2s7CitjbGFzcyBNYWNoaW5lQ29uc3RhbnRQb29sVmFsdWU7CitjbGFzcyBNQ1N5bWJvbDsKK2NsYXNzIE9wdGltaXphdGlvblJlbWFya0VtaXR0ZXI7CitjbGFzcyBTRERiZ1ZhbHVlOworY2xhc3MgU2VsZWN0aW9uREFHOworY2xhc3MgU2VsZWN0aW9uREFHVGFyZ2V0SW5mbzsKK2NsYXNzIFRhcmdldExpYnJhcnlJbmZvOworY2xhc3MgVGFyZ2V0TG93ZXJpbmc7CitjbGFzcyBUYXJnZXRNYWNoaW5lOworY2xhc3MgVGFyZ2V0U3VidGFyZ2V0SW5mbzsKK2NsYXNzIFZhbHVlOworCitjbGFzcyBTRFZUTGlzdE5vZGUgOiBwdWJsaWMgRm9sZGluZ1NldE5vZGUgeworICBmcmllbmQgc3RydWN0IEZvbGRpbmdTZXRUcmFpdDxTRFZUTGlzdE5vZGU+OworCisgIC8vLyBBIHJlZmVyZW5jZSB0byBhbiBJbnRlcm5lZCBGb2xkaW5nU2V0Tm9kZUlEIGZvciB0aGlzIG5vZGUuCisgIC8vLyBUaGUgQWxsb2NhdG9yIGluIFNlbGVjdGlvbkRBRyBob2xkcyB0aGUgZGF0YS4KKyAgLy8vIFNEVlRMaXN0IGNvbnRhaW5zIGFsbCB0eXBlcyB3aGljaCBhcmUgZnJlcXVlbnRseSBhY2Nlc3NlZCBpbiBTZWxlY3Rpb25EQUcuCisgIC8vLyBUaGUgc2l6ZSBvZiB0aGlzIGxpc3QgaXMgbm90IGV4cGVjdGVkIHRvIGJlIGJpZyBzbyBpdCB3b24ndCBpbnRyb2R1Y2UKKyAgLy8vIGEgbWVtb3J5IHBlbmFsdHkuCisgIEZvbGRpbmdTZXROb2RlSURSZWYgRmFzdElEOworICBjb25zdCBFVlQgKlZUczsKKyAgdW5zaWduZWQgaW50IE51bVZUczsKKyAgLy8vIFRoZSBoYXNoIHZhbHVlIGZvciBTRFZUTGlzdCBpcyBmaXhlZCwgc28gY2FjaGUgaXQgdG8gYXZvaWQKKyAgLy8vIGhhc2ggY2FsY3VsYXRpb24uCisgIHVuc2lnbmVkIEhhc2hWYWx1ZTsKKworcHVibGljOgorICBTRFZUTGlzdE5vZGUoY29uc3QgRm9sZGluZ1NldE5vZGVJRFJlZiBJRCwgY29uc3QgRVZUICpWVCwgdW5zaWduZWQgaW50IE51bSkgOgorICAgICAgRmFzdElEKElEKSwgVlRzKFZUKSwgTnVtVlRzKE51bSkgeworICAgIEhhc2hWYWx1ZSA9IElELkNvbXB1dGVIYXNoKCk7CisgIH0KKworICBTRFZUTGlzdCBnZXRTRFZUTGlzdCgpIHsKKyAgICBTRFZUTGlzdCByZXN1bHQgPSB7VlRzLCBOdW1WVHN9OworICAgIHJldHVybiByZXN1bHQ7CisgIH0KK307CisKKy8vLyBTcGVjaWFsaXplIEZvbGRpbmdTZXRUcmFpdCBmb3IgU0RWVExpc3ROb2RlCisvLy8gdG8gYXZvaWQgY29tcHV0aW5nIHRlbXAgRm9sZGluZ1NldE5vZGVJRCBhbmQgaGFzaCB2YWx1ZS4KK3RlbXBsYXRlPD4gc3RydWN0IEZvbGRpbmdTZXRUcmFpdDxTRFZUTGlzdE5vZGU+IDogRGVmYXVsdEZvbGRpbmdTZXRUcmFpdDxTRFZUTGlzdE5vZGU+IHsKKyAgc3RhdGljIHZvaWQgUHJvZmlsZShjb25zdCBTRFZUTGlzdE5vZGUgJlgsIEZvbGRpbmdTZXROb2RlSUQmIElEKSB7CisgICAgSUQgPSBYLkZhc3RJRDsKKyAgfQorCisgIHN0YXRpYyBib29sIEVxdWFscyhjb25zdCBTRFZUTGlzdE5vZGUgJlgsIGNvbnN0IEZvbGRpbmdTZXROb2RlSUQgJklELAorICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgSURIYXNoLCBGb2xkaW5nU2V0Tm9kZUlEICZUZW1wSUQpIHsKKyAgICBpZiAoWC5IYXNoVmFsdWUgIT0gSURIYXNoKQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIHJldHVybiBJRCA9PSBYLkZhc3RJRDsKKyAgfQorCisgIHN0YXRpYyB1bnNpZ25lZCBDb21wdXRlSGFzaChjb25zdCBTRFZUTGlzdE5vZGUgJlgsIEZvbGRpbmdTZXROb2RlSUQgJlRlbXBJRCkgeworICAgIHJldHVybiBYLkhhc2hWYWx1ZTsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IGlsaXN0X2FsbG9jX3RyYWl0czxTRE5vZGU+IHsKKyAgc3RhdGljIHZvaWQgZGVsZXRlTm9kZShTRE5vZGUgKikgeworICAgIGxsdm1fdW5yZWFjaGFibGUoImlsaXN0X3RyYWl0czxTRE5vZGU+IHNob3VsZG4ndCBzZWUgYSBkZWxldGVOb2RlIGNhbGwhIik7CisgIH0KK307CisKKy8vLyBLZWVwcyB0cmFjayBvZiBkYmdfdmFsdWUgaW5mb3JtYXRpb24gdGhyb3VnaCBTRElTZWwuICBXZSBkbworLy8vIG5vdCBidWlsZCBTRE5vZGVzIGZvciB0aGVzZSBzbyBhcyBub3QgdG8gcGVydHVyYiB0aGUgZ2VuZXJhdGVkIGNvZGU7CisvLy8gaW5zdGVhZCB0aGUgaW5mbyBpcyBrZXB0IG9mZiB0byB0aGUgc2lkZSBpbiB0aGlzIHN0cnVjdHVyZS4gRWFjaCBTRE5vZGUgbWF5CisvLy8gaGF2ZSBvbmUgb3IgbW9yZSBhc3NvY2lhdGVkIGRiZ192YWx1ZSBlbnRyaWVzLiBUaGlzIGluZm9ybWF0aW9uIGlzIGtlcHQgaW4KKy8vLyBEYmdWYWxNYXAuCisvLy8gQnl2YWwgcGFyYW1ldGVycyBhcmUgaGFuZGxlZCBzZXBhcmF0ZWx5IGJlY2F1c2UgdGhleSBkb24ndCB1c2UgYWxsb2NhJ3MsCisvLy8gd2hpY2ggYnVzdHMgdGhlIG5vcm1hbCBtZWNoYW5pc20uICBUaGVyZSBpcyBnb29kIHJlYXNvbiBmb3IgaGFuZGxpbmcgYWxsCisvLy8gcGFyYW1ldGVycyBzZXBhcmF0ZWx5OiAgdGhleSBtYXkgbm90IGhhdmUgY29kZSBnZW5lcmF0ZWQgZm9yIHRoZW0sIHRoZXkKKy8vLyBzaG91bGQgYWx3YXlzIGdvIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZ1bmN0aW9uIHJlZ2FyZGxlc3Mgb2Ygb3RoZXIgY29kZQorLy8vIG1vdGlvbiwgYW5kIGRlYnVnIGluZm8gZm9yIHRoZW0gaXMgcG90ZW50aWFsbHkgdXNlZnVsIGV2ZW4gaWYgdGhlIHBhcmFtZXRlcgorLy8vIGlzIHVudXNlZC4gIFJpZ2h0IG5vdyBvbmx5IGJ5dmFsIHBhcmFtZXRlcnMgYXJlIGhhbmRsZWQgc2VwYXJhdGVseS4KK2NsYXNzIFNERGJnSW5mbyB7CisgIEJ1bXBQdHJBbGxvY2F0b3IgQWxsb2M7CisgIFNtYWxsVmVjdG9yPFNERGJnVmFsdWUqLCAzMj4gRGJnVmFsdWVzOworICBTbWFsbFZlY3RvcjxTRERiZ1ZhbHVlKiwgMzI+IEJ5dmFsUGFybURiZ1ZhbHVlczsKKyAgdXNpbmcgRGJnVmFsTWFwVHlwZSA9IERlbnNlTWFwPGNvbnN0IFNETm9kZSAqLCBTbWFsbFZlY3RvcjxTRERiZ1ZhbHVlICosIDI+PjsKKyAgRGJnVmFsTWFwVHlwZSBEYmdWYWxNYXA7CisKK3B1YmxpYzoKKyAgU0REYmdJbmZvKCkgPSBkZWZhdWx0OworICBTRERiZ0luZm8oY29uc3QgU0REYmdJbmZvICYpID0gZGVsZXRlOworICBTRERiZ0luZm8gJm9wZXJhdG9yPShjb25zdCBTRERiZ0luZm8gJikgPSBkZWxldGU7CisKKyAgdm9pZCBhZGQoU0REYmdWYWx1ZSAqViwgY29uc3QgU0ROb2RlICpOb2RlLCBib29sIGlzUGFyYW1ldGVyKSB7CisgICAgaWYgKGlzUGFyYW1ldGVyKSB7CisgICAgICBCeXZhbFBhcm1EYmdWYWx1ZXMucHVzaF9iYWNrKFYpOworICAgIH0gZWxzZSAgICAgRGJnVmFsdWVzLnB1c2hfYmFjayhWKTsKKyAgICBpZiAoTm9kZSkKKyAgICAgIERiZ1ZhbE1hcFtOb2RlXS5wdXNoX2JhY2soVik7CisgIH0KKworICAvLy8gXGJyaWVmIEludmFsaWRhdGUgYWxsIERiZ1ZhbHVlcyBhdHRhY2hlZCB0byB0aGUgbm9kZSBhbmQgcmVtb3ZlCisgIC8vLyBpdCBmcm9tIHRoZSBOb2RlLXRvLURiZ1ZhbHVlcyBtYXAuCisgIHZvaWQgZXJhc2UoY29uc3QgU0ROb2RlICpOb2RlKTsKKworICB2b2lkIGNsZWFyKCkgeworICAgIERiZ1ZhbE1hcC5jbGVhcigpOworICAgIERiZ1ZhbHVlcy5jbGVhcigpOworICAgIEJ5dmFsUGFybURiZ1ZhbHVlcy5jbGVhcigpOworICAgIEFsbG9jLlJlc2V0KCk7CisgIH0KKworICBCdW1wUHRyQWxsb2NhdG9yICZnZXRBbGxvYygpIHsgcmV0dXJuIEFsbG9jOyB9CisKKyAgYm9vbCBlbXB0eSgpIGNvbnN0IHsKKyAgICByZXR1cm4gRGJnVmFsdWVzLmVtcHR5KCkgJiYgQnl2YWxQYXJtRGJnVmFsdWVzLmVtcHR5KCk7CisgIH0KKworICBBcnJheVJlZjxTRERiZ1ZhbHVlKj4gZ2V0U0REYmdWYWx1ZXMoY29uc3QgU0ROb2RlICpOb2RlKSB7CisgICAgRGJnVmFsTWFwVHlwZTo6aXRlcmF0b3IgSSA9IERiZ1ZhbE1hcC5maW5kKE5vZGUpOworICAgIGlmIChJICE9IERiZ1ZhbE1hcC5lbmQoKSkKKyAgICAgIHJldHVybiBJLT5zZWNvbmQ7CisgICAgcmV0dXJuIEFycmF5UmVmPFNERGJnVmFsdWUqPigpOworICB9CisKKyAgdXNpbmcgRGJnSXRlcmF0b3IgPSBTbWFsbFZlY3RvckltcGw8U0REYmdWYWx1ZSo+OjppdGVyYXRvcjsKKworICBEYmdJdGVyYXRvciBEYmdCZWdpbigpIHsgcmV0dXJuIERiZ1ZhbHVlcy5iZWdpbigpOyB9CisgIERiZ0l0ZXJhdG9yIERiZ0VuZCgpICAgeyByZXR1cm4gRGJnVmFsdWVzLmVuZCgpOyB9CisgIERiZ0l0ZXJhdG9yIEJ5dmFsUGFybURiZ0JlZ2luKCkgeyByZXR1cm4gQnl2YWxQYXJtRGJnVmFsdWVzLmJlZ2luKCk7IH0KKyAgRGJnSXRlcmF0b3IgQnl2YWxQYXJtRGJnRW5kKCkgICB7IHJldHVybiBCeXZhbFBhcm1EYmdWYWx1ZXMuZW5kKCk7IH0KK307CisKK3ZvaWQgY2hlY2tGb3JDeWNsZXMoY29uc3QgU2VsZWN0aW9uREFHICpEQUcsIGJvb2wgZm9yY2UgPSBmYWxzZSk7CisKKy8vLyBUaGlzIGlzIHVzZWQgdG8gcmVwcmVzZW50IGEgcG9ydGlvbiBvZiBhbiBMTFZNIGZ1bmN0aW9uIGluIGEgbG93LWxldmVsCisvLy8gRGF0YSBEZXBlbmRlbmNlIERBRyByZXByZXNlbnRhdGlvbiBzdWl0YWJsZSBmb3IgaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uLgorLy8vIFRoaXMgREFHIGlzIGNvbnN0cnVjdGVkIGFzIHRoZSBmaXJzdCBzdGVwIG9mIGluc3RydWN0aW9uIHNlbGVjdGlvbiBpbiBvcmRlcgorLy8vIHRvIGFsbG93IGltcGxlbWVudGF0aW9uIG9mIG1hY2hpbmUgc3BlY2lmaWMgb3B0aW1pemF0aW9ucworLy8vIGFuZCBjb2RlIHNpbXBsaWZpY2F0aW9ucy4KKy8vLworLy8vIFRoZSByZXByZXNlbnRhdGlvbiB1c2VkIGJ5IHRoZSBTZWxlY3Rpb25EQUcgaXMgYSB0YXJnZXQtaW5kZXBlbmRlbnQKKy8vLyByZXByZXNlbnRhdGlvbiwgd2hpY2ggaGFzIHNvbWUgc2ltaWxhcml0aWVzIHRvIHRoZSBHQ0MgUlRMIHJlcHJlc2VudGF0aW9uLAorLy8vIGJ1dCBpcyBzaWduaWZpY2FudGx5IG1vcmUgc2ltcGxlLCBwb3dlcmZ1bCwgYW5kIGlzIGEgZ3JhcGggZm9ybSBpbnN0ZWFkIG9mIGEKKy8vLyBsaW5lYXIgZm9ybS4KKy8vLworY2xhc3MgU2VsZWN0aW9uREFHIHsKKyAgY29uc3QgVGFyZ2V0TWFjaGluZSAmVE07CisgIGNvbnN0IFNlbGVjdGlvbkRBR1RhcmdldEluZm8gKlRTSSA9IG51bGxwdHI7CisgIGNvbnN0IFRhcmdldExvd2VyaW5nICpUTEkgPSBudWxscHRyOworICBjb25zdCBUYXJnZXRMaWJyYXJ5SW5mbyAqTGliSW5mbyA9IG51bGxwdHI7CisgIE1hY2hpbmVGdW5jdGlvbiAqTUY7CisgIFBhc3MgKlNEQUdJU2VsUGFzcyA9IG51bGxwdHI7CisgIExMVk1Db250ZXh0ICpDb250ZXh0OworICBDb2RlR2VuT3B0OjpMZXZlbCBPcHRMZXZlbDsKKworICBEaXZlcmdlbmNlQW5hbHlzaXMgKiBEQSA9IG51bGxwdHI7CisgIEZ1bmN0aW9uTG93ZXJpbmdJbmZvICogRkxJID0gbnVsbHB0cjsKKworICAvLy8gVGhlIGZ1bmN0aW9uLWxldmVsIG9wdGltaXphdGlvbiByZW1hcmsgZW1pdHRlci4gIFVzZWQgdG8gZW1pdCByZW1hcmtzCisgIC8vLyB3aGVuZXZlciBtYW5pcHVsYXRpbmcgdGhlIERBRy4KKyAgT3B0aW1pemF0aW9uUmVtYXJrRW1pdHRlciAqT1JFOworCisgIC8vLyBUaGUgc3RhcnRpbmcgdG9rZW4uCisgIFNETm9kZSBFbnRyeU5vZGU7CisKKyAgLy8vIFRoZSByb290IG9mIHRoZSBlbnRpcmUgREFHLgorICBTRFZhbHVlIFJvb3Q7CisKKyAgLy8vIEEgbGlua2VkIGxpc3Qgb2Ygbm9kZXMgaW4gdGhlIGN1cnJlbnQgREFHLgorICBpbGlzdDxTRE5vZGU+IEFsbE5vZGVzOworCisgIC8vLyBUaGUgQWxsb2NhdG9yVHlwZSBmb3IgYWxsb2NhdGluZyBTRE5vZGVzLiBXZSB1c2UKKyAgLy8vIHBvb2wgYWxsb2NhdGlvbiB3aXRoIHJlY3ljbGluZy4KKyAgdXNpbmcgTm9kZUFsbG9jYXRvclR5cGUgPSBSZWN5Y2xpbmdBbGxvY2F0b3I8QnVtcFB0ckFsbG9jYXRvciwgU0ROb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoTGFyZ2VzdFNETm9kZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWdub2YoTW9zdEFsaWduZWRTRE5vZGUpPjsKKworICAvLy8gUG9vbCBhbGxvY2F0aW9uIGZvciBub2Rlcy4KKyAgTm9kZUFsbG9jYXRvclR5cGUgTm9kZUFsbG9jYXRvcjsKKworICAvLy8gVGhpcyBzdHJ1Y3R1cmUgaXMgdXNlZCB0byBtZW1vaXplIG5vZGVzLCBhdXRvbWF0aWNhbGx5IHBlcmZvcm1pbmcKKyAgLy8vIENTRSB3aXRoIGV4aXN0aW5nIG5vZGVzIHdoZW4gYSBkdXBsaWNhdGUgaXMgcmVxdWVzdGVkLgorICBGb2xkaW5nU2V0PFNETm9kZT4gQ1NFTWFwOworCisgIC8vLyBQb29sIGFsbG9jYXRpb24gZm9yIG1hY2hpbmUtb3Bjb2RlIFNETm9kZSBvcGVyYW5kcy4KKyAgQnVtcFB0ckFsbG9jYXRvciBPcGVyYW5kQWxsb2NhdG9yOworICBBcnJheVJlY3ljbGVyPFNEVXNlPiBPcGVyYW5kUmVjeWNsZXI7CisKKyAgLy8vIFBvb2wgYWxsb2NhdGlvbiBmb3IgbWlzYy4gb2JqZWN0cyB0aGF0IGFyZSBjcmVhdGVkIG9uY2UgcGVyIFNlbGVjdGlvbkRBRy4KKyAgQnVtcFB0ckFsbG9jYXRvciBBbGxvY2F0b3I7CisKKyAgLy8vIFRyYWNrcyBkYmdfdmFsdWUgaW5mb3JtYXRpb24gdGhyb3VnaCBTRElTZWwuCisgIFNERGJnSW5mbyAqRGJnSW5mbzsKKworICB1aW50MTZfdCBOZXh0UGVyc2lzdGVudElkID0gMDsKKworcHVibGljOgorICAvLy8gQ2xpZW50cyBvZiB2YXJpb3VzIEFQSXMgdGhhdCBjYXVzZSBnbG9iYWwgZWZmZWN0cyBvbgorICAvLy8gdGhlIERBRyBjYW4gb3B0aW9uYWxseSBpbXBsZW1lbnQgdGhpcyBpbnRlcmZhY2UuICBUaGlzIGFsbG93cyB0aGUgY2xpZW50cworICAvLy8gdG8gaGFuZGxlIHRoZSB2YXJpb3VzIHNvcnRzIG9mIHVwZGF0ZXMgdGhhdCBoYXBwZW4uCisgIC8vLworICAvLy8gQSBEQUdVcGRhdGVMaXN0ZW5lciBhdXRvbWF0aWNhbGx5IHJlZ2lzdGVycyBpdHNlbGYgd2l0aCBEQUcgd2hlbiBpdCBpcworICAvLy8gY29uc3RydWN0ZWQsIGFuZCByZW1vdmVzIGl0c2VsZiB3aGVuIGRlc3Ryb3llZCBpbiBSQUlJIGZhc2hpb24uCisgIHN0cnVjdCBEQUdVcGRhdGVMaXN0ZW5lciB7CisgICAgREFHVXBkYXRlTGlzdGVuZXIgKmNvbnN0IE5leHQ7CisgICAgU2VsZWN0aW9uREFHICZEQUc7CisKKyAgICBleHBsaWNpdCBEQUdVcGRhdGVMaXN0ZW5lcihTZWxlY3Rpb25EQUcgJkQpCisgICAgICA6IE5leHQoRC5VcGRhdGVMaXN0ZW5lcnMpLCBEQUcoRCkgeworICAgICAgREFHLlVwZGF0ZUxpc3RlbmVycyA9IHRoaXM7CisgICAgfQorCisgICAgdmlydHVhbCB+REFHVXBkYXRlTGlzdGVuZXIoKSB7CisgICAgICBhc3NlcnQoREFHLlVwZGF0ZUxpc3RlbmVycyA9PSB0aGlzICYmCisgICAgICAgICAgICAgIkRBR1VwZGF0ZUxpc3RlbmVycyBtdXN0IGJlIGRlc3Ryb3llZCBpbiBMSUZPIG9yZGVyIik7CisgICAgICBEQUcuVXBkYXRlTGlzdGVuZXJzID0gTmV4dDsKKyAgICB9CisKKyAgICAvLy8gVGhlIG5vZGUgTiB0aGF0IHdhcyBkZWxldGVkIGFuZCwgaWYgRSBpcyBub3QgbnVsbCwgYW4KKyAgICAvLy8gZXF1aXZhbGVudCBub2RlIEUgdGhhdCByZXBsYWNlZCBpdC4KKyAgICB2aXJ0dWFsIHZvaWQgTm9kZURlbGV0ZWQoU0ROb2RlICpOLCBTRE5vZGUgKkUpOworCisgICAgLy8vIFRoZSBub2RlIE4gdGhhdCB3YXMgdXBkYXRlZC4KKyAgICB2aXJ0dWFsIHZvaWQgTm9kZVVwZGF0ZWQoU0ROb2RlICpOKTsKKyAgfTsKKworICBzdHJ1Y3QgREFHTm9kZURlbGV0ZWRMaXN0ZW5lciA6IHB1YmxpYyBEQUdVcGRhdGVMaXN0ZW5lciB7CisgICAgc3RkOjpmdW5jdGlvbjx2b2lkKFNETm9kZSAqLCBTRE5vZGUgKik+IENhbGxiYWNrOworCisgICAgREFHTm9kZURlbGV0ZWRMaXN0ZW5lcihTZWxlY3Rpb25EQUcgJkRBRywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6ZnVuY3Rpb248dm9pZChTRE5vZGUgKiwgU0ROb2RlICopPiBDYWxsYmFjaykKKyAgICAgICAgOiBEQUdVcGRhdGVMaXN0ZW5lcihEQUcpLCBDYWxsYmFjayhzdGQ6Om1vdmUoQ2FsbGJhY2spKSB7fQorCisgICAgdm9pZCBOb2RlRGVsZXRlZChTRE5vZGUgKk4sIFNETm9kZSAqRSkgb3ZlcnJpZGUgeyBDYWxsYmFjayhOLCBFKTsgfQorICB9OworCisgIC8vLyBXaGVuIHRydWUsIGFkZGl0aW9uYWwgc3RlcHMgYXJlIHRha2VuIHRvCisgIC8vLyBlbnN1cmUgdGhhdCBnZXRDb25zdGFudCgpIGFuZCBzaW1pbGFyIGZ1bmN0aW9ucyByZXR1cm4gREFHIG5vZGVzIHRoYXQKKyAgLy8vIGhhdmUgbGVnYWwgdHlwZXMuIFRoaXMgaXMgaW1wb3J0YW50IGFmdGVyIHR5cGUgbGVnYWxpemF0aW9uIHNpbmNlCisgIC8vLyBhbnkgaWxsZWdhbGx5IHR5cGVkIG5vZGVzIGdlbmVyYXRlZCBhZnRlciB0aGlzIHBvaW50IHdpbGwgbm90IGV4cGVyaWVuY2UKKyAgLy8vIHR5cGUgbGVnYWxpemF0aW9uLgorICBib29sIE5ld05vZGVzTXVzdEhhdmVMZWdhbFR5cGVzID0gZmFsc2U7CisKK3ByaXZhdGU6CisgIC8vLyBEQUdVcGRhdGVMaXN0ZW5lciBpcyBhIGZyaWVuZCBzbyBpdCBjYW4gbWFuaXB1bGF0ZSB0aGUgbGlzdGVuZXIgc3RhY2suCisgIGZyaWVuZCBzdHJ1Y3QgREFHVXBkYXRlTGlzdGVuZXI7CisKKyAgLy8vIExpbmtlZCBsaXN0IG9mIHJlZ2lzdGVyZWQgREFHVXBkYXRlTGlzdGVuZXIgaW5zdGFuY2VzLgorICAvLy8gVGhpcyBzdGFjayBpcyBtYWludGFpbmVkIGJ5IERBR1VwZGF0ZUxpc3RlbmVyIFJBSUkuCisgIERBR1VwZGF0ZUxpc3RlbmVyICpVcGRhdGVMaXN0ZW5lcnMgPSBudWxscHRyOworCisgIC8vLyBJbXBsZW1lbnRhdGlvbiBvZiBzZXRTdWJncmFwaENvbG9yLgorICAvLy8gUmV0dXJuIHdoZXRoZXIgd2UgaGFkIHRvIHRydW5jYXRlIHRoZSBzZWFyY2guCisgIGJvb2wgc2V0U3ViZ3JhcGhDb2xvckhlbHBlcihTRE5vZGUgKk4sIGNvbnN0IGNoYXIgKkNvbG9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVuc2VTZXQ8U0ROb2RlICo+ICZ2aXNpdGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGxldmVsLCBib29sICZwcmludGVkKTsKKworICB0ZW1wbGF0ZSA8dHlwZW5hbWUgU0ROb2RlVCwgdHlwZW5hbWUuLi4gQXJnVHlwZXM+CisgIFNETm9kZVQgKm5ld1NETm9kZShBcmdUeXBlcyAmJi4uLiBBcmdzKSB7CisgICAgcmV0dXJuIG5ldyAoTm9kZUFsbG9jYXRvci50ZW1wbGF0ZSBBbGxvY2F0ZTxTRE5vZGVUPigpKQorICAgICAgICBTRE5vZGVUKHN0ZDo6Zm9yd2FyZDxBcmdUeXBlcz4oQXJncykuLi4pOworICB9CisKKyAgLy8vIEJ1aWxkIGEgc3ludGhldGljIFNETm9kZVQgd2l0aCB0aGUgZ2l2ZW4gYXJncyBhbmQgZXh0cmFjdCBpdHMgc3ViY2xhc3MKKyAgLy8vIGRhdGEgYXMgYW4gaW50ZWdlciAoZS5nLiBmb3IgdXNlIGluIGEgZm9sZGluZyBzZXQpLgorICAvLy8KKyAgLy8vIFRoZSBhcmdzIHRvIHRoaXMgZnVuY3Rpb24gYXJlIHRoZSBzYW1lIGFzIHRoZSBhcmdzIHRvIFNETm9kZVQncworICAvLy8gY29uc3RydWN0b3IsIGV4Y2VwdCB0aGUgc2Vjb25kIGFyZyAoYXNzdW1lZCB0byBiZSBhIGNvbnN0IERlYnVnTG9jJikgaXMKKyAgLy8vIG9taXR0ZWQuCisgIHRlbXBsYXRlIDx0eXBlbmFtZSBTRE5vZGVULCB0eXBlbmFtZS4uLiBBcmdUeXBlcz4KKyAgc3RhdGljIHVpbnQxNl90IGdldFN5bnRoZXRpY05vZGVTdWJjbGFzc0RhdGEodW5zaWduZWQgSVJPcmRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJnVHlwZXMgJiYuLi4gQXJncykgeworICAgIC8vIFRoZSBjb21waWxlciBjYW4gcmVkdWNlIHRoaXMgZXhwcmVzc2lvbiB0byBhIGNvbnN0YW50IGlmZiB3ZSBwYXNzIGFuCisgICAgLy8gZW1wdHkgRGVidWdMb2MuICBUaGFua2Z1bGx5LCB0aGUgZGVidWcgbG9jYXRpb24gZG9lc24ndCBoYXZlIGFueSBiZWFyaW5nCisgICAgLy8gb24gdGhlIHN1YmNsYXNzIGRhdGEuCisgICAgcmV0dXJuIFNETm9kZVQoSVJPcmRlciwgRGVidWdMb2MoKSwgc3RkOjpmb3J3YXJkPEFyZ1R5cGVzPihBcmdzKS4uLikKKyAgICAgICAgLmdldFJhd1N1YmNsYXNzRGF0YSgpOworICB9CisKKyAgdGVtcGxhdGUgPHR5cGVuYW1lIFNETm9kZVR5PgorICBzdGF0aWMgdWludDE2X3QgZ2V0U3ludGhldGljTm9kZVN1YmNsYXNzRGF0YSh1bnNpZ25lZCBPcGMsIHVuc2lnbmVkIE9yZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWVExpc3QgVlRzLCBFVlQgTWVtb3J5VlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lTWVtT3BlcmFuZCAqTU1PKSB7CisgICAgcmV0dXJuIFNETm9kZVR5KE9wYywgT3JkZXIsIERlYnVnTG9jKCksIFZUcywgTWVtb3J5VlQsIE1NTykKKyAgICAgICAgIC5nZXRSYXdTdWJjbGFzc0RhdGEoKTsKKyAgfQorCisgIHZvaWQgY3JlYXRlT3BlcmFuZHMoU0ROb2RlICpOb2RlLCBBcnJheVJlZjxTRFZhbHVlPiBWYWxzKTsKKworICB2b2lkIHJlbW92ZU9wZXJhbmRzKFNETm9kZSAqTm9kZSkgeworICAgIGlmICghTm9kZS0+T3BlcmFuZExpc3QpCisgICAgICByZXR1cm47CisgICAgT3BlcmFuZFJlY3ljbGVyLmRlYWxsb2NhdGUoCisgICAgICAgIEFycmF5UmVjeWNsZXI8U0RVc2U+OjpDYXBhY2l0eTo6Z2V0KE5vZGUtPk51bU9wZXJhbmRzKSwKKyAgICAgICAgTm9kZS0+T3BlcmFuZExpc3QpOworICAgIE5vZGUtPk51bU9wZXJhbmRzID0gMDsKKyAgICBOb2RlLT5PcGVyYW5kTGlzdCA9IG51bGxwdHI7CisgIH0KKyAgdm9pZCBDcmVhdGVUb3BvbG9naWNhbE9yZGVyKHN0ZDo6dmVjdG9yPFNETm9kZSo+JiBPcmRlcik7CitwdWJsaWM6CisgIGV4cGxpY2l0IFNlbGVjdGlvbkRBRyhjb25zdCBUYXJnZXRNYWNoaW5lICZUTSwgQ29kZUdlbk9wdDo6TGV2ZWwpOworICBTZWxlY3Rpb25EQUcoY29uc3QgU2VsZWN0aW9uREFHICYpID0gZGVsZXRlOworICBTZWxlY3Rpb25EQUcgJm9wZXJhdG9yPShjb25zdCBTZWxlY3Rpb25EQUcgJikgPSBkZWxldGU7CisgIH5TZWxlY3Rpb25EQUcoKTsKKworICAvLy8gUHJlcGFyZSB0aGlzIFNlbGVjdGlvbkRBRyB0byBwcm9jZXNzIGNvZGUgaW4gdGhlIGdpdmVuIE1hY2hpbmVGdW5jdGlvbi4KKyAgdm9pZCBpbml0KE1hY2hpbmVGdW5jdGlvbiAmTmV3TUYsIE9wdGltaXphdGlvblJlbWFya0VtaXR0ZXIgJk5ld09SRSwKKyAgICAgICAgICAgIFBhc3MgKlBhc3NQdHIsIGNvbnN0IFRhcmdldExpYnJhcnlJbmZvICpMaWJyYXJ5SW5mbywKKyAgICAgICAgICAgIERpdmVyZ2VuY2VBbmFseXNpcyAqIERBKTsKKworICB2b2lkIHNldEZ1bmN0aW9uTG93ZXJpbmdJbmZvKEZ1bmN0aW9uTG93ZXJpbmdJbmZvICogRnVuY0luZm8pIHsKKyAgICBGTEkgPSBGdW5jSW5mbzsKKyAgfQorCisgIC8vLyBDbGVhciBzdGF0ZSBhbmQgZnJlZSBtZW1vcnkgbmVjZXNzYXJ5IHRvIG1ha2UgdGhpcworICAvLy8gU2VsZWN0aW9uREFHIHJlYWR5IHRvIHByb2Nlc3MgYSBuZXcgYmxvY2suCisgIHZvaWQgY2xlYXIoKTsKKworICBNYWNoaW5lRnVuY3Rpb24gJmdldE1hY2hpbmVGdW5jdGlvbigpIGNvbnN0IHsgcmV0dXJuICpNRjsgfQorICBjb25zdCBQYXNzICpnZXRQYXNzKCkgY29uc3QgeyByZXR1cm4gU0RBR0lTZWxQYXNzOyB9CisKKyAgY29uc3QgRGF0YUxheW91dCAmZ2V0RGF0YUxheW91dCgpIGNvbnN0IHsgcmV0dXJuIE1GLT5nZXREYXRhTGF5b3V0KCk7IH0KKyAgY29uc3QgVGFyZ2V0TWFjaGluZSAmZ2V0VGFyZ2V0KCkgY29uc3QgeyByZXR1cm4gVE07IH0KKyAgY29uc3QgVGFyZ2V0U3VidGFyZ2V0SW5mbyAmZ2V0U3VidGFyZ2V0KCkgY29uc3QgeyByZXR1cm4gTUYtPmdldFN1YnRhcmdldCgpOyB9CisgIGNvbnN0IFRhcmdldExvd2VyaW5nICZnZXRUYXJnZXRMb3dlcmluZ0luZm8oKSBjb25zdCB7IHJldHVybiAqVExJOyB9CisgIGNvbnN0IFRhcmdldExpYnJhcnlJbmZvICZnZXRMaWJJbmZvKCkgY29uc3QgeyByZXR1cm4gKkxpYkluZm87IH0KKyAgY29uc3QgU2VsZWN0aW9uREFHVGFyZ2V0SW5mbyAmZ2V0U2VsZWN0aW9uREFHSW5mbygpIGNvbnN0IHsgcmV0dXJuICpUU0k7IH0KKyAgTExWTUNvbnRleHQgKmdldENvbnRleHQoKSBjb25zdCB7cmV0dXJuIENvbnRleHQ7IH0KKyAgT3B0aW1pemF0aW9uUmVtYXJrRW1pdHRlciAmZ2V0T1JFKCkgY29uc3QgeyByZXR1cm4gKk9SRTsgfQorCisgIC8vLyBQb3AgdXAgYSBHcmFwaFZpei9ndiB3aW5kb3cgd2l0aCB0aGUgREFHIHJlbmRlcmVkIHVzaW5nICdkb3QnLgorICB2b2lkIHZpZXdHcmFwaChjb25zdCBzdGQ6OnN0cmluZyAmVGl0bGUpOworICB2b2lkIHZpZXdHcmFwaCgpOworCisjaWZuZGVmIE5ERUJVRworICBzdGQ6Om1hcDxjb25zdCBTRE5vZGUgKiwgc3RkOjpzdHJpbmc+IE5vZGVHcmFwaEF0dHJzOworI2VuZGlmCisKKyAgLy8vIENsZWFyIGFsbCBwcmV2aW91c2x5IGRlZmluZWQgbm9kZSBncmFwaCBhdHRyaWJ1dGVzLgorICAvLy8gSW50ZW5kZWQgdG8gYmUgdXNlZCBmcm9tIGEgZGVidWdnaW5nIHRvb2wgKGVnLiBnZGIpLgorICB2b2lkIGNsZWFyR3JhcGhBdHRycygpOworCisgIC8vLyBTZXQgZ3JhcGggYXR0cmlidXRlcyBmb3IgYSBub2RlLiAoZWcuICJjb2xvcj1yZWQiLikKKyAgdm9pZCBzZXRHcmFwaEF0dHJzKGNvbnN0IFNETm9kZSAqTiwgY29uc3QgY2hhciAqQXR0cnMpOworCisgIC8vLyBHZXQgZ3JhcGggYXR0cmlidXRlcyBmb3IgYSBub2RlLiAoZWcuICJjb2xvcj1yZWQiLikKKyAgLy8vIFVzZWQgZnJvbSBnZXROb2RlQXR0cmlidXRlcy4KKyAgY29uc3Qgc3RkOjpzdHJpbmcgZ2V0R3JhcGhBdHRycyhjb25zdCBTRE5vZGUgKk4pIGNvbnN0OworCisgIC8vLyBDb252ZW5pZW5jZSBmb3Igc2V0dGluZyBub2RlIGNvbG9yIGF0dHJpYnV0ZS4KKyAgdm9pZCBzZXRHcmFwaENvbG9yKGNvbnN0IFNETm9kZSAqTiwgY29uc3QgY2hhciAqQ29sb3IpOworCisgIC8vLyBDb252ZW5pZW5jZSBmb3Igc2V0dGluZyBzdWJncmFwaCBjb2xvciBhdHRyaWJ1dGUuCisgIHZvaWQgc2V0U3ViZ3JhcGhDb2xvcihTRE5vZGUgKk4sIGNvbnN0IGNoYXIgKkNvbG9yKTsKKworICB1c2luZyBhbGxub2Rlc19jb25zdF9pdGVyYXRvciA9IGlsaXN0PFNETm9kZT46OmNvbnN0X2l0ZXJhdG9yOworCisgIGFsbG5vZGVzX2NvbnN0X2l0ZXJhdG9yIGFsbG5vZGVzX2JlZ2luKCkgY29uc3QgeyByZXR1cm4gQWxsTm9kZXMuYmVnaW4oKTsgfQorICBhbGxub2Rlc19jb25zdF9pdGVyYXRvciBhbGxub2Rlc19lbmQoKSBjb25zdCB7IHJldHVybiBBbGxOb2Rlcy5lbmQoKTsgfQorCisgIHVzaW5nIGFsbG5vZGVzX2l0ZXJhdG9yID0gaWxpc3Q8U0ROb2RlPjo6aXRlcmF0b3I7CisKKyAgYWxsbm9kZXNfaXRlcmF0b3IgYWxsbm9kZXNfYmVnaW4oKSB7IHJldHVybiBBbGxOb2Rlcy5iZWdpbigpOyB9CisgIGFsbG5vZGVzX2l0ZXJhdG9yIGFsbG5vZGVzX2VuZCgpIHsgcmV0dXJuIEFsbE5vZGVzLmVuZCgpOyB9CisKKyAgaWxpc3Q8U0ROb2RlPjo6c2l6ZV90eXBlIGFsbG5vZGVzX3NpemUoKSBjb25zdCB7CisgICAgcmV0dXJuIEFsbE5vZGVzLnNpemUoKTsKKyAgfQorCisgIGl0ZXJhdG9yX3JhbmdlPGFsbG5vZGVzX2l0ZXJhdG9yPiBhbGxub2RlcygpIHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZShhbGxub2Rlc19iZWdpbigpLCBhbGxub2Rlc19lbmQoKSk7CisgIH0KKyAgaXRlcmF0b3JfcmFuZ2U8YWxsbm9kZXNfY29uc3RfaXRlcmF0b3I+IGFsbG5vZGVzKCkgY29uc3QgeworICAgIHJldHVybiBtYWtlX3JhbmdlKGFsbG5vZGVzX2JlZ2luKCksIGFsbG5vZGVzX2VuZCgpKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIHJvb3QgdGFnIG9mIHRoZSBTZWxlY3Rpb25EQUcuCisgIGNvbnN0IFNEVmFsdWUgJmdldFJvb3QoKSBjb25zdCB7IHJldHVybiBSb290OyB9CisKKyAgLy8vIFJldHVybiB0aGUgdG9rZW4gY2hhaW4gY29ycmVzcG9uZGluZyB0byB0aGUgZW50cnkgb2YgdGhlIGZ1bmN0aW9uLgorICBTRFZhbHVlIGdldEVudHJ5Tm9kZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gU0RWYWx1ZShjb25zdF9jYXN0PFNETm9kZSAqPigmRW50cnlOb2RlKSwgMCk7CisgIH0KKworICAvLy8gU2V0IHRoZSBjdXJyZW50IHJvb3QgdGFnIG9mIHRoZSBTZWxlY3Rpb25EQUcuCisgIC8vLworICBjb25zdCBTRFZhbHVlICZzZXRSb290KFNEVmFsdWUgTikgeworICAgIGFzc2VydCgoIU4uZ2V0Tm9kZSgpIHx8IE4uZ2V0VmFsdWVUeXBlKCkgPT0gTVZUOjpPdGhlcikgJiYKKyAgICAgICAgICAgIkRBRyByb290IHZhbHVlIGlzIG5vdCBhIGNoYWluISIpOworICAgIGlmIChOLmdldE5vZGUoKSkKKyAgICAgIGNoZWNrRm9yQ3ljbGVzKE4uZ2V0Tm9kZSgpLCB0aGlzKTsKKyAgICBSb290ID0gTjsKKyAgICBpZiAoTi5nZXROb2RlKCkpCisgICAgICBjaGVja0ZvckN5Y2xlcyh0aGlzKTsKKyAgICByZXR1cm4gUm9vdDsKKyAgfQorCisgIHZvaWQgVmVyaWZ5REFHRGl2ZXJlbmNlKCk7CisKKyAgLy8vIFRoaXMgaXRlcmF0ZXMgb3ZlciB0aGUgbm9kZXMgaW4gdGhlIFNlbGVjdGlvbkRBRywgZm9sZGluZworICAvLy8gY2VydGFpbiB0eXBlcyBvZiBub2RlcyB0b2dldGhlciwgb3IgZWxpbWluYXRpbmcgc3VwZXJmbHVvdXMgbm9kZXMuICBUaGUKKyAgLy8vIExldmVsIGFyZ3VtZW50IGNvbnRyb2xzIHdoZXRoZXIgQ29tYmluZSBpcyBhbGxvd2VkIHRvIHByb2R1Y2Ugbm9kZXMgYW5kCisgIC8vLyB0eXBlcyB0aGF0IGFyZSBpbGxlZ2FsIG9uIHRoZSB0YXJnZXQuCisgIHZvaWQgQ29tYmluZShDb21iaW5lTGV2ZWwgTGV2ZWwsIEFsaWFzQW5hbHlzaXMgKkFBLAorICAgICAgICAgICAgICAgQ29kZUdlbk9wdDo6TGV2ZWwgT3B0TGV2ZWwpOworCisgIC8vLyBUaGlzIHRyYW5zZm9ybXMgdGhlIFNlbGVjdGlvbkRBRyBpbnRvIGEgU2VsZWN0aW9uREFHIHRoYXQKKyAgLy8vIG9ubHkgdXNlcyB0eXBlcyBuYXRpdmVseSBzdXBwb3J0ZWQgYnkgdGhlIHRhcmdldC4KKyAgLy8vIFJldHVybnMgInRydWUiIGlmIGl0IG1hZGUgYW55IGNoYW5nZXMuCisgIC8vLworICAvLy8gTm90ZSB0aGF0IHRoaXMgaXMgYW4gaW52b2x2ZWQgcHJvY2VzcyB0aGF0IG1heSBpbnZhbGlkYXRlIHBvaW50ZXJzIGludG8KKyAgLy8vIHRoZSBncmFwaC4KKyAgYm9vbCBMZWdhbGl6ZVR5cGVzKCk7CisKKyAgLy8vIFRoaXMgdHJhbnNmb3JtcyB0aGUgU2VsZWN0aW9uREFHIGludG8gYSBTZWxlY3Rpb25EQUcgdGhhdCBpcworICAvLy8gY29tcGF0aWJsZSB3aXRoIHRoZSB0YXJnZXQgaW5zdHJ1Y3Rpb24gc2VsZWN0b3IsIGFzIGluZGljYXRlZCBieSB0aGUKKyAgLy8vIFRhcmdldExvd2VyaW5nIG9iamVjdC4KKyAgLy8vCisgIC8vLyBOb3RlIHRoYXQgdGhpcyBpcyBhbiBpbnZvbHZlZCBwcm9jZXNzIHRoYXQgbWF5IGludmFsaWRhdGUgcG9pbnRlcnMgaW50bworICAvLy8gdGhlIGdyYXBoLgorICB2b2lkIExlZ2FsaXplKCk7CisKKyAgLy8vIFxicmllZiBUcmFuc2Zvcm1zIGEgU2VsZWN0aW9uREFHIG5vZGUgYW5kIGFueSBvcGVyYW5kcyB0byBpdCBpbnRvIGEgbm9kZQorICAvLy8gdGhhdCBpcyBjb21wYXRpYmxlIHdpdGggdGhlIHRhcmdldCBpbnN0cnVjdGlvbiBzZWxlY3RvciwgYXMgaW5kaWNhdGVkIGJ5CisgIC8vLyB0aGUgVGFyZ2V0TG93ZXJpbmcgb2JqZWN0LgorICAvLy8KKyAgLy8vIFxyZXR1cm5zIHRydWUgaWYgXGMgTiBpcyBhIHZhbGlkLCBsZWdhbCBub2RlIGFmdGVyIGNhbGxpbmcgdGhpcy4KKyAgLy8vCisgIC8vLyBUaGlzIGVzc2VudGlhbGx5IHJ1bnMgYSBzaW5nbGUgcmVjdXJzaXZlIHdhbGsgb2YgdGhlIFxjIExlZ2FsaXplIHByb2Nlc3MKKyAgLy8vIG92ZXIgdGhlIGdpdmVuIG5vZGUgKGFuZCBpdHMgb3BlcmFuZHMpLiBUaGlzIGNhbiBiZSB1c2VkIHRvIGluY3JlbWVudGFsbHkKKyAgLy8vIGxlZ2FsaXplIHRoZSBEQUcuIEFsbCBvZiB0aGUgbm9kZXMgd2hpY2ggYXJlIGRpcmVjdGx5IHJlcGxhY2VkLAorICAvLy8gcG90ZW50aWFsbHkgaW5jbHVkaW5nIE4sIGFyZSBhZGRlZCB0byB0aGUgb3V0cHV0IHBhcmFtZXRlciBcYworICAvLy8gVXBkYXRlZE5vZGVzIHNvIHRoYXQgdGhlIGRlbHRhIHRvIHRoZSBEQUcgY2FuIGJlIHVuZGVyc3Rvb2QgYnkgdGhlCisgIC8vLyBjYWxsZXIuCisgIC8vLworICAvLy8gV2hlbiB0aGlzIHJldHVybnMgZmFsc2UsIE4gaGFzIGJlZW4gbGVnYWxpemVkIGluIGEgd2F5IHRoYXQgbWFrZSB0aGUKKyAgLy8vIHBvaW50ZXIgcGFzc2VkIGluIG5vIGxvbmdlciB2YWxpZC4gSXQgbWF5IGhhdmUgZXZlbiBiZWVuIGRlbGV0ZWQgZnJvbSB0aGUKKyAgLy8vIERBRywgYW5kIHNvIGl0IHNob3VsZG4ndCBiZSB1c2VkIGZ1cnRoZXIuIFdoZW4gdGhpcyByZXR1cm5zIHRydWUsIHRoZQorICAvLy8gTiBwYXNzZWQgaW4gaXMgYSBsZWdhbCBub2RlLCBhbmQgY2FuIGJlIGltbWVkaWF0ZWx5IHByb2Nlc3NlZCBhcyBzdWNoLgorICAvLy8gVGhpcyBtYXkgc3RpbGwgaGF2ZSBkb25lIHNvbWUgd29yayBvbiB0aGUgREFHLCBhbmQgd2lsbCBzdGlsbCBwb3B1bGF0ZQorICAvLy8gVXBkYXRlZE5vZGVzIHdpdGggYW55IG5ldyBub2RlcyByZXBsYWNpbmcgdGhvc2Ugb3JpZ2luYWxseSBpbiB0aGUgREFHLgorICBib29sIExlZ2FsaXplT3AoU0ROb2RlICpOLCBTbWFsbFNldFZlY3RvcjxTRE5vZGUgKiwgMTY+ICZVcGRhdGVkTm9kZXMpOworCisgIC8vLyBUaGlzIHRyYW5zZm9ybXMgdGhlIFNlbGVjdGlvbkRBRyBpbnRvIGEgU2VsZWN0aW9uREFHCisgIC8vLyB0aGF0IG9ubHkgdXNlcyB2ZWN0b3IgbWF0aCBvcGVyYXRpb25zIHN1cHBvcnRlZCBieSB0aGUgdGFyZ2V0LiAgVGhpcyBpcworICAvLy8gbmVjZXNzYXJ5IGFzIGEgc2VwYXJhdGUgc3RlcCBmcm9tIExlZ2FsaXplIGJlY2F1c2UgdW5yb2xsaW5nIGEgdmVjdG9yCisgIC8vLyBvcGVyYXRpb24gY2FuIGludHJvZHVjZSBpbGxlZ2FsIHR5cGVzLCB3aGljaCByZXF1aXJlcyBydW5uaW5nCisgIC8vLyBMZWdhbGl6ZVR5cGVzIGFnYWluLgorICAvLy8KKyAgLy8vIFRoaXMgcmV0dXJucyB0cnVlIGlmIGl0IG1hZGUgYW55IGNoYW5nZXM7IGluIHRoYXQgY2FzZSwgTGVnYWxpemVUeXBlcworICAvLy8gaXMgY2FsbGVkIGFnYWluIGJlZm9yZSBMZWdhbGl6ZS4KKyAgLy8vCisgIC8vLyBOb3RlIHRoYXQgdGhpcyBpcyBhbiBpbnZvbHZlZCBwcm9jZXNzIHRoYXQgbWF5IGludmFsaWRhdGUgcG9pbnRlcnMgaW50bworICAvLy8gdGhlIGdyYXBoLgorICBib29sIExlZ2FsaXplVmVjdG9ycygpOworCisgIC8vLyBUaGlzIG1ldGhvZCBkZWxldGVzIGFsbCB1bnJlYWNoYWJsZSBub2RlcyBpbiB0aGUgU2VsZWN0aW9uREFHLgorICB2b2lkIFJlbW92ZURlYWROb2RlcygpOworCisgIC8vLyBSZW1vdmUgdGhlIHNwZWNpZmllZCBub2RlIGZyb20gdGhlIHN5c3RlbS4gIFRoaXMgbm9kZSBtdXN0CisgIC8vLyBoYXZlIG5vIHJlZmVycmVycy4KKyAgdm9pZCBEZWxldGVOb2RlKFNETm9kZSAqTik7CisKKyAgLy8vIFJldHVybiBhbiBTRFZUTGlzdCB0aGF0IHJlcHJlc2VudHMgdGhlIGxpc3Qgb2YgdmFsdWVzIHNwZWNpZmllZC4KKyAgU0RWVExpc3QgZ2V0VlRMaXN0KEVWVCBWVCk7CisgIFNEVlRMaXN0IGdldFZUTGlzdChFVlQgVlQxLCBFVlQgVlQyKTsKKyAgU0RWVExpc3QgZ2V0VlRMaXN0KEVWVCBWVDEsIEVWVCBWVDIsIEVWVCBWVDMpOworICBTRFZUTGlzdCBnZXRWVExpc3QoRVZUIFZUMSwgRVZUIFZUMiwgRVZUIFZUMywgRVZUIFZUNCk7CisgIFNEVlRMaXN0IGdldFZUTGlzdChBcnJheVJlZjxFVlQ+IFZUcyk7CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIE5vZGUgY3JlYXRpb24gbWV0aG9kcy4KKworICAvLy8gXGJyaWVmIENyZWF0ZSBhIENvbnN0YW50U0ROb2RlIHdyYXBwaW5nIGEgY29uc3RhbnQgdmFsdWUuCisgIC8vLyBJZiBWVCBpcyBhIHZlY3RvciB0eXBlLCB0aGUgY29uc3RhbnQgaXMgc3BsYXR0ZWQgaW50byBhIEJVSUxEX1ZFQ1RPUi4KKyAgLy8vCisgIC8vLyBJZiBvbmx5IGxlZ2FsIHR5cGVzIGNhbiBiZSBwcm9kdWNlZCwgdGhpcyBkb2VzIHRoZSBuZWNlc3NhcnkKKyAgLy8vIHRyYW5zZm9ybWF0aW9ucyAoZS5nLiwgaWYgdGhlIHZlY3RvciBlbGVtZW50IHR5cGUgaXMgaWxsZWdhbCkuCisgIC8vLyBAeworICBTRFZhbHVlIGdldENvbnN0YW50KHVpbnQ2NF90IFZhbCwgY29uc3QgU0RMb2MgJkRMLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc1RhcmdldCA9IGZhbHNlLCBib29sIGlzT3BhcXVlID0gZmFsc2UpOworICBTRFZhbHVlIGdldENvbnN0YW50KGNvbnN0IEFQSW50ICZWYWwsIGNvbnN0IFNETG9jICZETCwgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNUYXJnZXQgPSBmYWxzZSwgYm9vbCBpc09wYXF1ZSA9IGZhbHNlKTsKKworICBTRFZhbHVlIGdldEFsbE9uZXNDb25zdGFudChjb25zdCBTRExvYyAmREwsIEVWVCBWVCwgYm9vbCBJc1RhcmdldCA9IGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIElzT3BhcXVlID0gZmFsc2UpIHsKKyAgICByZXR1cm4gZ2V0Q29uc3RhbnQoQVBJbnQ6OmdldEFsbE9uZXNWYWx1ZShWVC5nZXRTY2FsYXJTaXplSW5CaXRzKCkpLCBETCwKKyAgICAgICAgICAgICAgICAgICAgICAgVlQsIElzVGFyZ2V0LCBJc09wYXF1ZSk7CisgIH0KKworICBTRFZhbHVlIGdldENvbnN0YW50KGNvbnN0IENvbnN0YW50SW50ICZWYWwsIGNvbnN0IFNETG9jICZETCwgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNUYXJnZXQgPSBmYWxzZSwgYm9vbCBpc09wYXF1ZSA9IGZhbHNlKTsKKyAgU0RWYWx1ZSBnZXRJbnRQdHJDb25zdGFudCh1aW50NjRfdCBWYWwsIGNvbnN0IFNETG9jICZETCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzVGFyZ2V0ID0gZmFsc2UpOworICBTRFZhbHVlIGdldFRhcmdldENvbnN0YW50KHVpbnQ2NF90IFZhbCwgY29uc3QgU0RMb2MgJkRMLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc09wYXF1ZSA9IGZhbHNlKSB7CisgICAgcmV0dXJuIGdldENvbnN0YW50KFZhbCwgREwsIFZULCB0cnVlLCBpc09wYXF1ZSk7CisgIH0KKyAgU0RWYWx1ZSBnZXRUYXJnZXRDb25zdGFudChjb25zdCBBUEludCAmVmFsLCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzT3BhcXVlID0gZmFsc2UpIHsKKyAgICByZXR1cm4gZ2V0Q29uc3RhbnQoVmFsLCBETCwgVlQsIHRydWUsIGlzT3BhcXVlKTsKKyAgfQorICBTRFZhbHVlIGdldFRhcmdldENvbnN0YW50KGNvbnN0IENvbnN0YW50SW50ICZWYWwsIGNvbnN0IFNETG9jICZETCwgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNPcGFxdWUgPSBmYWxzZSkgeworICAgIHJldHVybiBnZXRDb25zdGFudChWYWwsIERMLCBWVCwgdHJ1ZSwgaXNPcGFxdWUpOworICB9CisKKyAgLy8vIFxicmllZiBDcmVhdGUgYSB0cnVlIG9yIGZhbHNlIGNvbnN0YW50IG9mIHR5cGUgXHAgVlQgdXNpbmcgdGhlIHRhcmdldCdzCisgIC8vLyBCb29sZWFuQ29udGVudCBmb3IgdHlwZSBccCBPcFZULgorICBTRFZhbHVlIGdldEJvb2xDb25zdGFudChib29sIFYsIGNvbnN0IFNETG9jICZETCwgRVZUIFZULCBFVlQgT3BWVCk7CisgIC8vLyBAfQorCisgIC8vLyBcYnJpZWYgQ3JlYXRlIGEgQ29uc3RhbnRGUFNETm9kZSB3cmFwcGluZyBhIGNvbnN0YW50IHZhbHVlLgorICAvLy8gSWYgVlQgaXMgYSB2ZWN0b3IgdHlwZSwgdGhlIGNvbnN0YW50IGlzIHNwbGF0dGVkIGludG8gYSBCVUlMRF9WRUNUT1IuCisgIC8vLworICAvLy8gSWYgb25seSBsZWdhbCB0eXBlcyBjYW4gYmUgcHJvZHVjZWQsIHRoaXMgZG9lcyB0aGUgbmVjZXNzYXJ5CisgIC8vLyB0cmFuc2Zvcm1hdGlvbnMgKGUuZy4sIGlmIHRoZSB2ZWN0b3IgZWxlbWVudCB0eXBlIGlzIGlsbGVnYWwpLgorICAvLy8gVGhlIGZvcm1zIHRoYXQgdGFrZSBhIGRvdWJsZSBzaG91bGQgb25seSBiZSB1c2VkIGZvciBzaW1wbGUgY29uc3RhbnRzCisgIC8vLyB0aGF0IGNhbiBiZSBleGFjdGx5IHJlcHJlc2VudGVkIGluIFZULiAgTm8gY2hlY2tzIGFyZSBtYWRlLgorICAvLy8gQHsKKyAgU0RWYWx1ZSBnZXRDb25zdGFudEZQKGRvdWJsZSBWYWwsIGNvbnN0IFNETG9jICZETCwgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc1RhcmdldCA9IGZhbHNlKTsKKyAgU0RWYWx1ZSBnZXRDb25zdGFudEZQKGNvbnN0IEFQRmxvYXQgJlZhbCwgY29uc3QgU0RMb2MgJkRMLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzVGFyZ2V0ID0gZmFsc2UpOworICBTRFZhbHVlIGdldENvbnN0YW50RlAoY29uc3QgQ29uc3RhbnRGUCAmQ0YsIGNvbnN0IFNETG9jICZETCwgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc1RhcmdldCA9IGZhbHNlKTsKKyAgU0RWYWx1ZSBnZXRUYXJnZXRDb25zdGFudEZQKGRvdWJsZSBWYWwsIGNvbnN0IFNETG9jICZETCwgRVZUIFZUKSB7CisgICAgcmV0dXJuIGdldENvbnN0YW50RlAoVmFsLCBETCwgVlQsIHRydWUpOworICB9CisgIFNEVmFsdWUgZ2V0VGFyZ2V0Q29uc3RhbnRGUChjb25zdCBBUEZsb2F0ICZWYWwsIGNvbnN0IFNETG9jICZETCwgRVZUIFZUKSB7CisgICAgcmV0dXJuIGdldENvbnN0YW50RlAoVmFsLCBETCwgVlQsIHRydWUpOworICB9CisgIFNEVmFsdWUgZ2V0VGFyZ2V0Q29uc3RhbnRGUChjb25zdCBDb25zdGFudEZQICZWYWwsIGNvbnN0IFNETG9jICZETCwgRVZUIFZUKSB7CisgICAgcmV0dXJuIGdldENvbnN0YW50RlAoVmFsLCBETCwgVlQsIHRydWUpOworICB9CisgIC8vLyBAfQorCisgIFNEVmFsdWUgZ2V0R2xvYmFsQWRkcmVzcyhjb25zdCBHbG9iYWxWYWx1ZSAqR1YsIGNvbnN0IFNETG9jICZETCwgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50NjRfdCBvZmZzZXQgPSAwLCBib29sIGlzVGFyZ2V0R0EgPSBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKTsKKyAgU0RWYWx1ZSBnZXRUYXJnZXRHbG9iYWxBZGRyZXNzKGNvbnN0IEdsb2JhbFZhbHVlICpHViwgY29uc3QgU0RMb2MgJkRMLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NF90IG9mZnNldCA9IDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFRhcmdldEZsYWdzID0gMCkgeworICAgIHJldHVybiBnZXRHbG9iYWxBZGRyZXNzKEdWLCBETCwgVlQsIG9mZnNldCwgdHJ1ZSwgVGFyZ2V0RmxhZ3MpOworICB9CisgIFNEVmFsdWUgZ2V0RnJhbWVJbmRleChpbnQgRkksIEVWVCBWVCwgYm9vbCBpc1RhcmdldCA9IGZhbHNlKTsKKyAgU0RWYWx1ZSBnZXRUYXJnZXRGcmFtZUluZGV4KGludCBGSSwgRVZUIFZUKSB7CisgICAgcmV0dXJuIGdldEZyYW1lSW5kZXgoRkksIFZULCB0cnVlKTsKKyAgfQorICBTRFZhbHVlIGdldEp1bXBUYWJsZShpbnQgSlRJLCBFVlQgVlQsIGJvb2wgaXNUYXJnZXQgPSBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciBUYXJnZXRGbGFncyA9IDApOworICBTRFZhbHVlIGdldFRhcmdldEp1bXBUYWJsZShpbnQgSlRJLCBFVlQgVlQsIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKSB7CisgICAgcmV0dXJuIGdldEp1bXBUYWJsZShKVEksIFZULCB0cnVlLCBUYXJnZXRGbGFncyk7CisgIH0KKyAgU0RWYWx1ZSBnZXRDb25zdGFudFBvb2woY29uc3QgQ29uc3RhbnQgKkMsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgQWxpZ24gPSAwLCBpbnQgT2ZmcyA9IDAsIGJvb2wgaXNUPWZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFRhcmdldEZsYWdzID0gMCk7CisgIFNEVmFsdWUgZ2V0VGFyZ2V0Q29uc3RhbnRQb29sKGNvbnN0IENvbnN0YW50ICpDLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIEFsaWduID0gMCwgaW50IE9mZnNldCA9IDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKSB7CisgICAgcmV0dXJuIGdldENvbnN0YW50UG9vbChDLCBWVCwgQWxpZ24sIE9mZnNldCwgdHJ1ZSwgVGFyZ2V0RmxhZ3MpOworICB9CisgIFNEVmFsdWUgZ2V0Q29uc3RhbnRQb29sKE1hY2hpbmVDb25zdGFudFBvb2xWYWx1ZSAqQywgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBBbGlnbiA9IDAsIGludCBPZmZzID0gMCwgYm9vbCBpc1Q9ZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKTsKKyAgU0RWYWx1ZSBnZXRUYXJnZXRDb25zdGFudFBvb2woTWFjaGluZUNvbnN0YW50UG9vbFZhbHVlICpDLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVWVCBWVCwgdW5zaWduZWQgQWxpZ24gPSAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBPZmZzZXQgPSAwLCB1bnNpZ25lZCBjaGFyIFRhcmdldEZsYWdzPTApIHsKKyAgICByZXR1cm4gZ2V0Q29uc3RhbnRQb29sKEMsIFZULCBBbGlnbiwgT2Zmc2V0LCB0cnVlLCBUYXJnZXRGbGFncyk7CisgIH0KKyAgU0RWYWx1ZSBnZXRUYXJnZXRJbmRleChpbnQgSW5kZXgsIEVWVCBWVCwgaW50NjRfdCBPZmZzZXQgPSAwLAorICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKTsKKyAgLy8gV2hlbiBnZW5lcmF0aW5nIGEgYnJhbmNoIHRvIGEgQkIsIHdlIGRvbid0IGluIGdlbmVyYWwga25vdyBlbm91Z2gKKyAgLy8gdG8gcHJvdmlkZSBkZWJ1ZyBpbmZvIGZvciB0aGUgQkIgYXQgdGhhdCB0aW1lLCBzbyBrZWVwIHRoaXMgb25lIGFyb3VuZC4KKyAgU0RWYWx1ZSBnZXRCYXNpY0Jsb2NrKE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpOworICBTRFZhbHVlIGdldEJhc2ljQmxvY2soTWFjaGluZUJhc2ljQmxvY2sgKk1CQiwgU0RMb2MgZGwpOworICBTRFZhbHVlIGdldEV4dGVybmFsU3ltYm9sKGNvbnN0IGNoYXIgKlN5bSwgRVZUIFZUKTsKKyAgU0RWYWx1ZSBnZXRFeHRlcm5hbFN5bWJvbChjb25zdCBjaGFyICpTeW0sIGNvbnN0IFNETG9jICZkbCwgRVZUIFZUKTsKKyAgU0RWYWx1ZSBnZXRUYXJnZXRFeHRlcm5hbFN5bWJvbChjb25zdCBjaGFyICpTeW0sIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFRhcmdldEZsYWdzID0gMCk7CisgIFNEVmFsdWUgZ2V0TUNTeW1ib2woTUNTeW1ib2wgKlN5bSwgRVZUIFZUKTsKKworICBTRFZhbHVlIGdldFZhbHVlVHlwZShFVlQpOworICBTRFZhbHVlIGdldFJlZ2lzdGVyKHVuc2lnbmVkIFJlZywgRVZUIFZUKTsKKyAgU0RWYWx1ZSBnZXRSZWdpc3Rlck1hc2soY29uc3QgdWludDMyX3QgKlJlZ01hc2spOworICBTRFZhbHVlIGdldEVITGFiZWwoY29uc3QgU0RMb2MgJmRsLCBTRFZhbHVlIFJvb3QsIE1DU3ltYm9sICpMYWJlbCk7CisgIFNEVmFsdWUgZ2V0TGFiZWxOb2RlKHVuc2lnbmVkIE9wY29kZSwgY29uc3QgU0RMb2MgJmRsLCBTRFZhbHVlIFJvb3QsCisgICAgICAgICAgICAgICAgICAgICAgIE1DU3ltYm9sICpMYWJlbCk7CisgIFNEVmFsdWUgZ2V0QmxvY2tBZGRyZXNzKGNvbnN0IEJsb2NrQWRkcmVzcyAqQkEsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgaW50NjRfdCBPZmZzZXQgPSAwLCBib29sIGlzVGFyZ2V0ID0gZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKTsKKyAgU0RWYWx1ZSBnZXRUYXJnZXRCbG9ja0FkZHJlc3MoY29uc3QgQmxvY2tBZGRyZXNzICpCQSwgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NF90IE9mZnNldCA9IDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MgPSAwKSB7CisgICAgcmV0dXJuIGdldEJsb2NrQWRkcmVzcyhCQSwgVlQsIE9mZnNldCwgdHJ1ZSwgVGFyZ2V0RmxhZ3MpOworICB9CisKKyAgU0RWYWx1ZSBnZXRDb3B5VG9SZWcoU0RWYWx1ZSBDaGFpbiwgY29uc3QgU0RMb2MgJmRsLCB1bnNpZ25lZCBSZWcsCisgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgTikgeworICAgIHJldHVybiBnZXROb2RlKElTRDo6Q29weVRvUmVnLCBkbCwgTVZUOjpPdGhlciwgQ2hhaW4sCisgICAgICAgICAgICAgICAgICAgZ2V0UmVnaXN0ZXIoUmVnLCBOLmdldFZhbHVlVHlwZSgpKSwgTik7CisgIH0KKworICAvLyBUaGlzIHZlcnNpb24gb2YgdGhlIGdldENvcHlUb1JlZyBtZXRob2QgdGFrZXMgYW4gZXh0cmEgb3BlcmFuZCwgd2hpY2gKKyAgLy8gaW5kaWNhdGVzIHRoYXQgdGhlcmUgaXMgcG90ZW50aWFsbHkgYW4gaW5jb21pbmcgZ2x1ZSB2YWx1ZSAoaWYgR2x1ZSBpcyBub3QKKyAgLy8gbnVsbCkgYW5kIHRoYXQgdGhlcmUgc2hvdWxkIGJlIGEgZ2x1ZSByZXN1bHQuCisgIFNEVmFsdWUgZ2V0Q29weVRvUmVnKFNEVmFsdWUgQ2hhaW4sIGNvbnN0IFNETG9jICZkbCwgdW5zaWduZWQgUmVnLCBTRFZhbHVlIE4sCisgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgR2x1ZSkgeworICAgIFNEVlRMaXN0IFZUcyA9IGdldFZUTGlzdChNVlQ6Ok90aGVyLCBNVlQ6OkdsdWUpOworICAgIFNEVmFsdWUgT3BzW10gPSB7IENoYWluLCBnZXRSZWdpc3RlcihSZWcsIE4uZ2V0VmFsdWVUeXBlKCkpLCBOLCBHbHVlIH07CisgICAgcmV0dXJuIGdldE5vZGUoSVNEOjpDb3B5VG9SZWcsIGRsLCBWVHMsCisgICAgICAgICAgICAgICAgICAgbWFrZUFycmF5UmVmKE9wcywgR2x1ZS5nZXROb2RlKCkgPyA0IDogMykpOworICB9CisKKyAgLy8gU2ltaWxhciB0byBsYXN0IGdldENvcHlUb1JlZygpIGV4Y2VwdCBwYXJhbWV0ZXIgUmVnIGlzIGEgU0RWYWx1ZQorICBTRFZhbHVlIGdldENvcHlUb1JlZyhTRFZhbHVlIENoYWluLCBjb25zdCBTRExvYyAmZGwsIFNEVmFsdWUgUmVnLCBTRFZhbHVlIE4sCisgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgR2x1ZSkgeworICAgIFNEVlRMaXN0IFZUcyA9IGdldFZUTGlzdChNVlQ6Ok90aGVyLCBNVlQ6OkdsdWUpOworICAgIFNEVmFsdWUgT3BzW10gPSB7IENoYWluLCBSZWcsIE4sIEdsdWUgfTsKKyAgICByZXR1cm4gZ2V0Tm9kZShJU0Q6OkNvcHlUb1JlZywgZGwsIFZUcywKKyAgICAgICAgICAgICAgICAgICBtYWtlQXJyYXlSZWYoT3BzLCBHbHVlLmdldE5vZGUoKSA/IDQgOiAzKSk7CisgIH0KKworICBTRFZhbHVlIGdldENvcHlGcm9tUmVnKFNEVmFsdWUgQ2hhaW4sIGNvbnN0IFNETG9jICZkbCwgdW5zaWduZWQgUmVnLCBFVlQgVlQpIHsKKyAgICBTRFZUTGlzdCBWVHMgPSBnZXRWVExpc3QoVlQsIE1WVDo6T3RoZXIpOworICAgIFNEVmFsdWUgT3BzW10gPSB7IENoYWluLCBnZXRSZWdpc3RlcihSZWcsIFZUKSB9OworICAgIHJldHVybiBnZXROb2RlKElTRDo6Q29weUZyb21SZWcsIGRsLCBWVHMsIE9wcyk7CisgIH0KKworICAvLyBUaGlzIHZlcnNpb24gb2YgdGhlIGdldENvcHlGcm9tUmVnIG1ldGhvZCB0YWtlcyBhbiBleHRyYSBvcGVyYW5kLCB3aGljaAorICAvLyBpbmRpY2F0ZXMgdGhhdCB0aGVyZSBpcyBwb3RlbnRpYWxseSBhbiBpbmNvbWluZyBnbHVlIHZhbHVlIChpZiBHbHVlIGlzIG5vdAorICAvLyBudWxsKSBhbmQgdGhhdCB0aGVyZSBzaG91bGQgYmUgYSBnbHVlIHJlc3VsdC4KKyAgU0RWYWx1ZSBnZXRDb3B5RnJvbVJlZyhTRFZhbHVlIENoYWluLCBjb25zdCBTRExvYyAmZGwsIHVuc2lnbmVkIFJlZywgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgR2x1ZSkgeworICAgIFNEVlRMaXN0IFZUcyA9IGdldFZUTGlzdChWVCwgTVZUOjpPdGhlciwgTVZUOjpHbHVlKTsKKyAgICBTRFZhbHVlIE9wc1tdID0geyBDaGFpbiwgZ2V0UmVnaXN0ZXIoUmVnLCBWVCksIEdsdWUgfTsKKyAgICByZXR1cm4gZ2V0Tm9kZShJU0Q6OkNvcHlGcm9tUmVnLCBkbCwgVlRzLAorICAgICAgICAgICAgICAgICAgIG1ha2VBcnJheVJlZihPcHMsIEdsdWUuZ2V0Tm9kZSgpID8gMyA6IDIpKTsKKyAgfQorCisgIFNEVmFsdWUgZ2V0Q29uZENvZGUoSVNEOjpDb25kQ29kZSBDb25kKTsKKworICAvLy8gUmV0dXJuIGFuIElTRDo6VkVDVE9SX1NIVUZGTEUgbm9kZS4gVGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiBWVCwKKyAgLy8vIHdoaWNoIG11c3QgYmUgYSB2ZWN0b3IgdHlwZSwgbXVzdCBtYXRjaCB0aGUgbnVtYmVyIG9mIG1hc2sgZWxlbWVudHMKKyAgLy8vIE51bUVsdHMuIEFuIGludGVnZXIgbWFzayBlbGVtZW50IGVxdWFsIHRvIC0xIGlzIHRyZWF0ZWQgYXMgdW5kZWZpbmVkLgorICBTRFZhbHVlIGdldFZlY3RvclNodWZmbGUoRVZUIFZULCBjb25zdCBTRExvYyAmZGwsIFNEVmFsdWUgTjEsIFNEVmFsdWUgTjIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjxpbnQ+IE1hc2spOworCisgIC8vLyBSZXR1cm4gYW4gSVNEOjpCVUlMRF9WRUNUT1Igbm9kZS4gVGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiBWVCwKKyAgLy8vIHdoaWNoIG11c3QgYmUgYSB2ZWN0b3IgdHlwZSwgbXVzdCBtYXRjaCB0aGUgbnVtYmVyIG9mIG9wZXJhbmRzIGluIE9wcy4KKyAgLy8vIFRoZSBvcGVyYW5kcyBtdXN0IGhhdmUgdGhlIHNhbWUgdHlwZSBhcyAob3IsIGZvciBpbnRlZ2VycywgYSB0eXBlIHdpZGVyCisgIC8vLyB0aGFuKSBWVCdzIGVsZW1lbnQgdHlwZS4KKyAgU0RWYWx1ZSBnZXRCdWlsZFZlY3RvcihFVlQgVlQsIGNvbnN0IFNETG9jICZETCwgQXJyYXlSZWY8U0RWYWx1ZT4gT3BzKSB7CisgICAgLy8gVmVyaWZ5U0ROb2RlICh2aWEgSW5zZXJ0Tm9kZSkgY2hlY2tzIEJVSUxEX1ZFQ1RPUiBsYXRlci4KKyAgICByZXR1cm4gZ2V0Tm9kZShJU0Q6OkJVSUxEX1ZFQ1RPUiwgREwsIFZULCBPcHMpOworICB9CisKKyAgLy8vIFJldHVybiBhbiBJU0Q6OkJVSUxEX1ZFQ1RPUiBub2RlLiBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIFZULAorICAvLy8gd2hpY2ggbXVzdCBiZSBhIHZlY3RvciB0eXBlLCBtdXN0IG1hdGNoIHRoZSBudW1iZXIgb2Ygb3BlcmFuZHMgaW4gT3BzLgorICAvLy8gVGhlIG9wZXJhbmRzIG11c3QgaGF2ZSB0aGUgc2FtZSB0eXBlIGFzIChvciwgZm9yIGludGVnZXJzLCBhIHR5cGUgd2lkZXIKKyAgLy8vIHRoYW4pIFZUJ3MgZWxlbWVudCB0eXBlLgorICBTRFZhbHVlIGdldEJ1aWxkVmVjdG9yKEVWVCBWVCwgY29uc3QgU0RMb2MgJkRMLCBBcnJheVJlZjxTRFVzZT4gT3BzKSB7CisgICAgLy8gVmVyaWZ5U0ROb2RlICh2aWEgSW5zZXJ0Tm9kZSkgY2hlY2tzIEJVSUxEX1ZFQ1RPUiBsYXRlci4KKyAgICByZXR1cm4gZ2V0Tm9kZShJU0Q6OkJVSUxEX1ZFQ1RPUiwgREwsIFZULCBPcHMpOworICB9CisKKyAgLy8vIFJldHVybiBhIHNwbGF0IElTRDo6QlVJTERfVkVDVE9SIG5vZGUsIGNvbnNpc3Rpbmcgb2YgT3Agc3BsYXR0ZWQgdG8gYWxsCisgIC8vLyBlbGVtZW50cy4gVlQgbXVzdCBiZSBhIHZlY3RvciB0eXBlLiBPcCdzIHR5cGUgbXVzdCBiZSB0aGUgc2FtZSBhcyAob3IsCisgIC8vLyBmb3IgaW50ZWdlcnMsIGEgdHlwZSB3aWRlciB0aGFuKSBWVCdzIGVsZW1lbnQgdHlwZS4KKyAgU0RWYWx1ZSBnZXRTcGxhdEJ1aWxkVmVjdG9yKEVWVCBWVCwgY29uc3QgU0RMb2MgJkRMLCBTRFZhbHVlIE9wKSB7CisgICAgLy8gVmVyaWZ5U0ROb2RlICh2aWEgSW5zZXJ0Tm9kZSkgY2hlY2tzIEJVSUxEX1ZFQ1RPUiBsYXRlci4KKyAgICBpZiAoT3AuZ2V0T3Bjb2RlKCkgPT0gSVNEOjpVTkRFRikgeworICAgICAgYXNzZXJ0KChWVC5nZXRWZWN0b3JFbGVtZW50VHlwZSgpID09IE9wLmdldFZhbHVlVHlwZSgpIHx8CisgICAgICAgICAgICAgIChWVC5pc0ludGVnZXIoKSAmJgorICAgICAgICAgICAgICAgVlQuZ2V0VmVjdG9yRWxlbWVudFR5cGUoKS5iaXRzTEUoT3AuZ2V0VmFsdWVUeXBlKCkpKSkgJiYKKyAgICAgICAgICAgICAiQSBzcGxhdHRlZCB2YWx1ZSBtdXN0IGhhdmUgYSB3aWR0aCBlcXVhbCBvciAoZm9yIGludGVnZXJzKSAiCisgICAgICAgICAgICAgImdyZWF0ZXIgdGhhbiB0aGUgdmVjdG9yIGVsZW1lbnQgdHlwZSEiKTsKKyAgICAgIHJldHVybiBnZXROb2RlKElTRDo6VU5ERUYsIFNETG9jKCksIFZUKTsKKyAgICB9CisKKyAgICBTbWFsbFZlY3RvcjxTRFZhbHVlLCAxNj4gT3BzKFZULmdldFZlY3Rvck51bUVsZW1lbnRzKCksIE9wKTsKKyAgICByZXR1cm4gZ2V0Tm9kZShJU0Q6OkJVSUxEX1ZFQ1RPUiwgREwsIFZULCBPcHMpOworICB9CisKKyAgLy8vIFxicmllZiBSZXR1cm5zIGFuIElTRDo6VkVDVE9SX1NIVUZGTEUgbm9kZSBzZW1hbnRpY2FsbHkgZXF1aXZhbGVudCB0bworICAvLy8gdGhlIHNodWZmbGUgbm9kZSBpbiBpbnB1dCBidXQgd2l0aCBzd2FwcGVkIG9wZXJhbmRzLgorICAvLy8KKyAgLy8vIEV4YW1wbGU6IHNodWZmbGUgQSwgQiwgPDAsNSwyLDc+IC0+IHNodWZmbGUgQiwgQSwgPDQsMSw2LDM+CisgIFNEVmFsdWUgZ2V0Q29tbXV0ZWRWZWN0b3JTaHVmZmxlKGNvbnN0IFNodWZmbGVWZWN0b3JTRE5vZGUgJlNWKTsKKworICAvLy8gQ29udmVydCBPcCwgd2hpY2ggbXVzdCBiZSBvZiBmbG9hdCB0eXBlLCB0byB0aGUKKyAgLy8vIGZsb2F0IHR5cGUgVlQsIGJ5IGVpdGhlciBleHRlbmRpbmcgb3Igcm91bmRpbmcgKGJ5IHRydW5jYXRpb24pLgorICBTRFZhbHVlIGdldEZQRXh0ZW5kT3JSb3VuZChTRFZhbHVlIE9wLCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCk7CisKKyAgLy8vIENvbnZlcnQgT3AsIHdoaWNoIG11c3QgYmUgb2YgaW50ZWdlciB0eXBlLCB0byB0aGUKKyAgLy8vIGludGVnZXIgdHlwZSBWVCwgYnkgZWl0aGVyIGFueS1leHRlbmRpbmcgb3IgdHJ1bmNhdGluZyBpdC4KKyAgU0RWYWx1ZSBnZXRBbnlFeHRPclRydW5jKFNEVmFsdWUgT3AsIGNvbnN0IFNETG9jICZETCwgRVZUIFZUKTsKKworICAvLy8gQ29udmVydCBPcCwgd2hpY2ggbXVzdCBiZSBvZiBpbnRlZ2VyIHR5cGUsIHRvIHRoZQorICAvLy8gaW50ZWdlciB0eXBlIFZULCBieSBlaXRoZXIgc2lnbi1leHRlbmRpbmcgb3IgdHJ1bmNhdGluZyBpdC4KKyAgU0RWYWx1ZSBnZXRTRXh0T3JUcnVuYyhTRFZhbHVlIE9wLCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCk7CisKKyAgLy8vIENvbnZlcnQgT3AsIHdoaWNoIG11c3QgYmUgb2YgaW50ZWdlciB0eXBlLCB0byB0aGUKKyAgLy8vIGludGVnZXIgdHlwZSBWVCwgYnkgZWl0aGVyIHplcm8tZXh0ZW5kaW5nIG9yIHRydW5jYXRpbmcgaXQuCisgIFNEVmFsdWUgZ2V0WkV4dE9yVHJ1bmMoU0RWYWx1ZSBPcCwgY29uc3QgU0RMb2MgJkRMLCBFVlQgVlQpOworCisgIC8vLyBSZXR1cm4gdGhlIGV4cHJlc3Npb24gcmVxdWlyZWQgdG8gemVybyBleHRlbmQgdGhlIE9wCisgIC8vLyB2YWx1ZSBhc3N1bWluZyBpdCB3YXMgdGhlIHNtYWxsZXIgU3JjVHkgdmFsdWUuCisgIFNEVmFsdWUgZ2V0WmVyb0V4dGVuZEluUmVnKFNEVmFsdWUgT3AsIGNvbnN0IFNETG9jICZETCwgRVZUIFNyY1R5KTsKKworICAvLy8gUmV0dXJuIGFuIG9wZXJhdGlvbiB3aGljaCB3aWxsIGFueS1leHRlbmQgdGhlIGxvdyBsYW5lcyBvZiB0aGUgb3BlcmFuZAorICAvLy8gaW50byB0aGUgc3BlY2lmaWVkIHZlY3RvciB0eXBlLiBGb3IgZXhhbXBsZSwKKyAgLy8vIHRoaXMgY2FuIGNvbnZlcnQgYSB2MTZpOCBpbnRvIGEgdjRpMzIgYnkgYW55LWV4dGVuZGluZyB0aGUgbG93IGZvdXIKKyAgLy8vIGxhbmVzIG9mIHRoZSBvcGVyYW5kIGZyb20gaTggdG8gaTMyLgorICBTRFZhbHVlIGdldEFueUV4dGVuZFZlY3RvckluUmVnKFNEVmFsdWUgT3AsIGNvbnN0IFNETG9jICZETCwgRVZUIFZUKTsKKworICAvLy8gUmV0dXJuIGFuIG9wZXJhdGlvbiB3aGljaCB3aWxsIHNpZ24gZXh0ZW5kIHRoZSBsb3cgbGFuZXMgb2YgdGhlIG9wZXJhbmQKKyAgLy8vIGludG8gdGhlIHNwZWNpZmllZCB2ZWN0b3IgdHlwZS4gRm9yIGV4YW1wbGUsCisgIC8vLyB0aGlzIGNhbiBjb252ZXJ0IGEgdjE2aTggaW50byBhIHY0aTMyIGJ5IHNpZ24gZXh0ZW5kaW5nIHRoZSBsb3cgZm91cgorICAvLy8gbGFuZXMgb2YgdGhlIG9wZXJhbmQgZnJvbSBpOCB0byBpMzIuCisgIFNEVmFsdWUgZ2V0U2lnbkV4dGVuZFZlY3RvckluUmVnKFNEVmFsdWUgT3AsIGNvbnN0IFNETG9jICZETCwgRVZUIFZUKTsKKworICAvLy8gUmV0dXJuIGFuIG9wZXJhdGlvbiB3aGljaCB3aWxsIHplcm8gZXh0ZW5kIHRoZSBsb3cgbGFuZXMgb2YgdGhlIG9wZXJhbmQKKyAgLy8vIGludG8gdGhlIHNwZWNpZmllZCB2ZWN0b3IgdHlwZS4gRm9yIGV4YW1wbGUsCisgIC8vLyB0aGlzIGNhbiBjb252ZXJ0IGEgdjE2aTggaW50byBhIHY0aTMyIGJ5IHplcm8gZXh0ZW5kaW5nIHRoZSBsb3cgZm91cgorICAvLy8gbGFuZXMgb2YgdGhlIG9wZXJhbmQgZnJvbSBpOCB0byBpMzIuCisgIFNEVmFsdWUgZ2V0WmVyb0V4dGVuZFZlY3RvckluUmVnKFNEVmFsdWUgT3AsIGNvbnN0IFNETG9jICZETCwgRVZUIFZUKTsKKworICAvLy8gQ29udmVydCBPcCwgd2hpY2ggbXVzdCBiZSBvZiBpbnRlZ2VyIHR5cGUsIHRvIHRoZSBpbnRlZ2VyIHR5cGUgVlQsCisgIC8vLyBieSB1c2luZyBhbiBleHRlbnNpb24gYXBwcm9wcmlhdGUgZm9yIHRoZSB0YXJnZXQncworICAvLy8gQm9vbGVhbkNvbnRlbnQgZm9yIHR5cGUgT3BWVCBvciB0cnVuY2F0aW5nIGl0LgorICBTRFZhbHVlIGdldEJvb2xFeHRPclRydW5jKFNEVmFsdWUgT3AsIGNvbnN0IFNETG9jICZTTCwgRVZUIFZULCBFVlQgT3BWVCk7CisKKyAgLy8vIENyZWF0ZSBhIGJpdHdpc2UgTk9UIG9wZXJhdGlvbiBhcyAoWE9SIFZhbCwgLTEpLgorICBTRFZhbHVlIGdldE5PVChjb25zdCBTRExvYyAmREwsIFNEVmFsdWUgVmFsLCBFVlQgVlQpOworCisgIC8vLyBcYnJpZWYgQ3JlYXRlIGEgbG9naWNhbCBOT1Qgb3BlcmF0aW9uIGFzIChYT1IgVmFsLCBCb29sZWFuT25lKS4KKyAgU0RWYWx1ZSBnZXRMb2dpY2FsTk9UKGNvbnN0IFNETG9jICZETCwgU0RWYWx1ZSBWYWwsIEVWVCBWVCk7CisKKyAgLy8vIFxicmllZiBDcmVhdGUgYW4gYWRkIGluc3RydWN0aW9uIHdpdGggYXBwcm9wcmlhdGUgZmxhZ3Mgd2hlbiB1c2VkIGZvcgorICAvLy8gYWRkcmVzc2luZyBzb21lIG9mZnNldCBvZiBhbiBvYmplY3QuIGkuZS4gaWYgYSBsb2FkIGlzIHNwbGl0IGludG8gbXVsdGlwbGUKKyAgLy8vIGNvbXBvbmVudHMsIGNyZWF0ZSBhbiBhZGQgbnV3IGZyb20gdGhlIGJhc2UgcG9pbnRlciB0byB0aGUgb2Zmc2V0LgorICBTRFZhbHVlIGdldE9iamVjdFB0ck9mZnNldChjb25zdCBTRExvYyAmU0wsIFNEVmFsdWUgT3AsIGludDY0X3QgT2Zmc2V0KSB7CisgICAgRVZUIFZUID0gT3AuZ2V0VmFsdWVUeXBlKCk7CisgICAgcmV0dXJuIGdldE9iamVjdFB0ck9mZnNldChTTCwgT3AsIGdldENvbnN0YW50KE9mZnNldCwgU0wsIFZUKSk7CisgIH0KKworICBTRFZhbHVlIGdldE9iamVjdFB0ck9mZnNldChjb25zdCBTRExvYyAmU0wsIFNEVmFsdWUgT3AsIFNEVmFsdWUgT2Zmc2V0KSB7CisgICAgRVZUIFZUID0gT3AuZ2V0VmFsdWVUeXBlKCk7CisKKyAgICAvLyBUaGUgb2JqZWN0IGl0c2VsZiBjYW4ndCB3cmFwIGFyb3VuZCB0aGUgYWRkcmVzcyBzcGFjZSwgc28gaXQgc2hvdWxkbid0IGJlCisgICAgLy8gcG9zc2libGUgZm9yIHRoZSBhZGRzIG9mIHRoZSBvZmZzZXRzIHRvIHRoZSBzcGxpdCBwYXJ0cyB0byBvdmVyZmxvdy4KKyAgICBTRE5vZGVGbGFncyBGbGFnczsKKyAgICBGbGFncy5zZXROb1Vuc2lnbmVkV3JhcCh0cnVlKTsKKyAgICByZXR1cm4gZ2V0Tm9kZShJU0Q6OkFERCwgU0wsIFZULCBPcCwgT2Zmc2V0LCBGbGFncyk7CisgIH0KKworICAvLy8gUmV0dXJuIGEgbmV3IENBTExTRVFfU1RBUlQgbm9kZSwgdGhhdCBzdGFydHMgbmV3IGNhbGwgZnJhbWUsIGluIHdoaWNoCisgIC8vLyBJblNpemUgYnl0ZXMgYXJlIHNldCB1cCBpbnNpZGUgQ0FMTFNFUV9TVEFSVC4uQ0FMTFNFUV9FTkQgc2VxdWVuY2UgYW5kCisgIC8vLyBPdXRTaXplIHNwZWNpZmllcyBwYXJ0IG9mIHRoZSBmcmFtZSBzZXQgdXAgcHJpb3IgdG8gdGhlIHNlcXVlbmNlLgorICBTRFZhbHVlIGdldENBTExTRVFfU1RBUlQoU0RWYWx1ZSBDaGFpbiwgdWludDY0X3QgSW5TaXplLCB1aW50NjRfdCBPdXRTaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU0RMb2MgJkRMKSB7CisgICAgU0RWVExpc3QgVlRzID0gZ2V0VlRMaXN0KE1WVDo6T3RoZXIsIE1WVDo6R2x1ZSk7CisgICAgU0RWYWx1ZSBPcHNbXSA9IHsgQ2hhaW4sCisgICAgICAgICAgICAgICAgICAgICAgZ2V0SW50UHRyQ29uc3RhbnQoSW5TaXplLCBETCwgdHJ1ZSksCisgICAgICAgICAgICAgICAgICAgICAgZ2V0SW50UHRyQ29uc3RhbnQoT3V0U2l6ZSwgREwsIHRydWUpIH07CisgICAgcmV0dXJuIGdldE5vZGUoSVNEOjpDQUxMU0VRX1NUQVJULCBETCwgVlRzLCBPcHMpOworICB9CisKKyAgLy8vIFJldHVybiBhIG5ldyBDQUxMU0VRX0VORCBub2RlLCB3aGljaCBhbHdheXMgbXVzdCBoYXZlIGEKKyAgLy8vIGdsdWUgcmVzdWx0ICh0byBlbnN1cmUgaXQncyBub3QgQ1NFJ2QpLgorICAvLy8gQ0FMTFNFUV9FTkQgZG9lcyBub3QgaGF2ZSBhIHVzZWZ1bCBTRExvYy4KKyAgU0RWYWx1ZSBnZXRDQUxMU0VRX0VORChTRFZhbHVlIENoYWluLCBTRFZhbHVlIE9wMSwgU0RWYWx1ZSBPcDIsCisgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBJbkdsdWUsIGNvbnN0IFNETG9jICZETCkgeworICAgIFNEVlRMaXN0IE5vZGVUeXMgPSBnZXRWVExpc3QoTVZUOjpPdGhlciwgTVZUOjpHbHVlKTsKKyAgICBTbWFsbFZlY3RvcjxTRFZhbHVlLCA0PiBPcHM7CisgICAgT3BzLnB1c2hfYmFjayhDaGFpbik7CisgICAgT3BzLnB1c2hfYmFjayhPcDEpOworICAgIE9wcy5wdXNoX2JhY2soT3AyKTsKKyAgICBpZiAoSW5HbHVlLmdldE5vZGUoKSkKKyAgICAgIE9wcy5wdXNoX2JhY2soSW5HbHVlKTsKKyAgICByZXR1cm4gZ2V0Tm9kZShJU0Q6OkNBTExTRVFfRU5ELCBETCwgTm9kZVR5cywgT3BzKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgcmVzdWx0IG9mIHRoaXMgb3BlcmF0aW9uIGlzIGFsd2F5cyB1bmRlZmluZWQuCisgIGJvb2wgaXNVbmRlZih1bnNpZ25lZCBPcGNvZGUsIEFycmF5UmVmPFNEVmFsdWU+IE9wcyk7CisKKyAgLy8vIFJldHVybiBhbiBVTkRFRiBub2RlLiBVTkRFRiBkb2VzIG5vdCBoYXZlIGEgdXNlZnVsIFNETG9jLgorICBTRFZhbHVlIGdldFVOREVGKEVWVCBWVCkgeworICAgIHJldHVybiBnZXROb2RlKElTRDo6VU5ERUYsIFNETG9jKCksIFZUKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gYSBHTE9CQUxfT0ZGU0VUX1RBQkxFIG5vZGUuIFRoaXMgZG9lcyBub3QgaGF2ZSBhIHVzZWZ1bCBTRExvYy4KKyAgU0RWYWx1ZSBnZXRHTE9CQUxfT0ZGU0VUX1RBQkxFKEVWVCBWVCkgeworICAgIHJldHVybiBnZXROb2RlKElTRDo6R0xPQkFMX09GRlNFVF9UQUJMRSwgU0RMb2MoKSwgVlQpOworICB9CisKKyAgLy8vIEdldHMgb3IgY3JlYXRlcyB0aGUgc3BlY2lmaWVkIG5vZGUuCisgIC8vLworICBTRFZhbHVlIGdldE5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFNEVXNlPiBPcHMpOworICBTRFZhbHVlIGdldE5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFNEVmFsdWU+IE9wcywgY29uc3QgU0ROb2RlRmxhZ3MgRmxhZ3MgPSBTRE5vZGVGbGFncygpKTsKKyAgU0RWYWx1ZSBnZXROb2RlKHVuc2lnbmVkIE9wY29kZSwgY29uc3QgU0RMb2MgJkRMLCBBcnJheVJlZjxFVlQ+IFJlc3VsdFR5cywKKyAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFNEVmFsdWU+IE9wcyk7CisgIFNEVmFsdWUgZ2V0Tm9kZSh1bnNpZ25lZCBPcGNvZGUsIGNvbnN0IFNETG9jICZETCwgU0RWVExpc3QgVlRzLAorICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8U0RWYWx1ZT4gT3BzKTsKKworICAvLyBTcGVjaWFsaXplIGJhc2VkIG9uIG51bWJlciBvZiBvcGVyYW5kcy4KKyAgU0RWYWx1ZSBnZXROb2RlKHVuc2lnbmVkIE9wY29kZSwgY29uc3QgU0RMb2MgJkRMLCBFVlQgVlQpOworICBTRFZhbHVlIGdldE5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCwgU0RWYWx1ZSBOLAorICAgICAgICAgICAgICAgICAgY29uc3QgU0ROb2RlRmxhZ3MgRmxhZ3MgPSBTRE5vZGVGbGFncygpKTsKKyAgU0RWYWx1ZSBnZXROb2RlKHVuc2lnbmVkIE9wY29kZSwgY29uc3QgU0RMb2MgJkRMLCBFVlQgVlQsIFNEVmFsdWUgTjEsCisgICAgICAgICAgICAgICAgICBTRFZhbHVlIE4yLCBjb25zdCBTRE5vZGVGbGFncyBGbGFncyA9IFNETm9kZUZsYWdzKCkpOworICBTRFZhbHVlIGdldE5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCwgU0RWYWx1ZSBOMSwKKyAgICAgICAgICAgICAgICAgIFNEVmFsdWUgTjIsIFNEVmFsdWUgTjMpOworICBTRFZhbHVlIGdldE5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCwgU0RWYWx1ZSBOMSwKKyAgICAgICAgICAgICAgICAgIFNEVmFsdWUgTjIsIFNEVmFsdWUgTjMsIFNEVmFsdWUgTjQpOworICBTRFZhbHVlIGdldE5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCwgU0RWYWx1ZSBOMSwKKyAgICAgICAgICAgICAgICAgIFNEVmFsdWUgTjIsIFNEVmFsdWUgTjMsIFNEVmFsdWUgTjQsIFNEVmFsdWUgTjUpOworCisgIC8vIFNwZWNpYWxpemUgYWdhaW4gYmFzZWQgb24gbnVtYmVyIG9mIG9wZXJhbmRzIGZvciBub2RlcyB3aXRoIGEgVlRMaXN0CisgIC8vIHJhdGhlciB0aGFuIGEgc2luZ2xlIFZULgorICBTRFZhbHVlIGdldE5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIFNEVlRMaXN0IFZUcyk7CisgIFNEVmFsdWUgZ2V0Tm9kZSh1bnNpZ25lZCBPcGNvZGUsIGNvbnN0IFNETG9jICZETCwgU0RWVExpc3QgVlRzLCBTRFZhbHVlIE4pOworICBTRFZhbHVlIGdldE5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIFNEVlRMaXN0IFZUcywgU0RWYWx1ZSBOMSwKKyAgICAgICAgICAgICAgICAgIFNEVmFsdWUgTjIpOworICBTRFZhbHVlIGdldE5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIFNEVlRMaXN0IFZUcywgU0RWYWx1ZSBOMSwKKyAgICAgICAgICAgICAgICAgIFNEVmFsdWUgTjIsIFNEVmFsdWUgTjMpOworICBTRFZhbHVlIGdldE5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIFNEVlRMaXN0IFZUcywgU0RWYWx1ZSBOMSwKKyAgICAgICAgICAgICAgICAgIFNEVmFsdWUgTjIsIFNEVmFsdWUgTjMsIFNEVmFsdWUgTjQpOworICBTRFZhbHVlIGdldE5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIFNEVlRMaXN0IFZUcywgU0RWYWx1ZSBOMSwKKyAgICAgICAgICAgICAgICAgIFNEVmFsdWUgTjIsIFNEVmFsdWUgTjMsIFNEVmFsdWUgTjQsIFNEVmFsdWUgTjUpOworCisgIC8vLyBDb21wdXRlIGEgVG9rZW5GYWN0b3IgdG8gZm9yY2UgYWxsIHRoZSBpbmNvbWluZyBzdGFjayBhcmd1bWVudHMgdG8gYmUKKyAgLy8vIGxvYWRlZCBmcm9tIHRoZSBzdGFjay4gVGhpcyBpcyB1c2VkIGluIHRhaWwgY2FsbCBsb3dlcmluZyB0byBwcm90ZWN0CisgIC8vLyBzdGFjayBhcmd1bWVudHMgZnJvbSBiZWluZyBjbG9iYmVyZWQuCisgIFNEVmFsdWUgZ2V0U3RhY2tBcmd1bWVudFRva2VuRmFjdG9yKFNEVmFsdWUgQ2hhaW4pOworCisgIFNEVmFsdWUgZ2V0TWVtY3B5KFNEVmFsdWUgQ2hhaW4sIGNvbnN0IFNETG9jICZkbCwgU0RWYWx1ZSBEc3QsIFNEVmFsdWUgU3JjLAorICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIFNpemUsIHVuc2lnbmVkIEFsaWduLCBib29sIGlzVm9sLCBib29sIEFsd2F5c0lubGluZSwKKyAgICAgICAgICAgICAgICAgICAgYm9vbCBpc1RhaWxDYWxsLCBNYWNoaW5lUG9pbnRlckluZm8gRHN0UHRySW5mbywKKyAgICAgICAgICAgICAgICAgICAgTWFjaGluZVBvaW50ZXJJbmZvIFNyY1B0ckluZm8pOworCisgIFNEVmFsdWUgZ2V0TWVtbW92ZShTRFZhbHVlIENoYWluLCBjb25zdCBTRExvYyAmZGwsIFNEVmFsdWUgRHN0LCBTRFZhbHVlIFNyYywKKyAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgU2l6ZSwgdW5zaWduZWQgQWxpZ24sIGJvb2wgaXNWb2wsIGJvb2wgaXNUYWlsQ2FsbCwKKyAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVQb2ludGVySW5mbyBEc3RQdHJJbmZvLAorICAgICAgICAgICAgICAgICAgICAgTWFjaGluZVBvaW50ZXJJbmZvIFNyY1B0ckluZm8pOworCisgIFNEVmFsdWUgZ2V0TWVtc2V0KFNEVmFsdWUgQ2hhaW4sIGNvbnN0IFNETG9jICZkbCwgU0RWYWx1ZSBEc3QsIFNEVmFsdWUgU3JjLAorICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIFNpemUsIHVuc2lnbmVkIEFsaWduLCBib29sIGlzVm9sLCBib29sIGlzVGFpbENhbGwsCisgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVQb2ludGVySW5mbyBEc3RQdHJJbmZvKTsKKworICAvLy8gSGVscGVyIGZ1bmN0aW9uIHRvIG1ha2UgaXQgZWFzaWVyIHRvIGJ1aWxkIFNldENDJ3MgaWYgeW91IGp1c3QKKyAgLy8vIGhhdmUgYW4gSVNEOjpDb25kQ29kZSBpbnN0ZWFkIG9mIGFuIFNEVmFsdWUuCisgIC8vLworICBTRFZhbHVlIGdldFNldENDKGNvbnN0IFNETG9jICZETCwgRVZUIFZULCBTRFZhbHVlIExIUywgU0RWYWx1ZSBSSFMsCisgICAgICAgICAgICAgICAgICAgSVNEOjpDb25kQ29kZSBDb25kKSB7CisgICAgYXNzZXJ0KExIUy5nZXRWYWx1ZVR5cGUoKS5pc1ZlY3RvcigpID09IFJIUy5nZXRWYWx1ZVR5cGUoKS5pc1ZlY3RvcigpICYmCisgICAgICAiQ2Fubm90IGNvbXBhcmUgc2NhbGFycyB0byB2ZWN0b3JzIik7CisgICAgYXNzZXJ0KExIUy5nZXRWYWx1ZVR5cGUoKS5pc1ZlY3RvcigpID09IFZULmlzVmVjdG9yKCkgJiYKKyAgICAgICJDYW5ub3QgY29tcGFyZSBzY2FsYXJzIHRvIHZlY3RvcnMiKTsKKyAgICBhc3NlcnQoQ29uZCAhPSBJU0Q6OlNFVENDX0lOVkFMSUQgJiYKKyAgICAgICAgIkNhbm5vdCBjcmVhdGUgYSBzZXRDQyBvZiBhbiBpbnZhbGlkIG5vZGUuIik7CisgICAgcmV0dXJuIGdldE5vZGUoSVNEOjpTRVRDQywgREwsIFZULCBMSFMsIFJIUywgZ2V0Q29uZENvZGUoQ29uZCkpOworICB9CisKKyAgLy8vIEhlbHBlciBmdW5jdGlvbiB0byBtYWtlIGl0IGVhc2llciB0byBidWlsZCBTZWxlY3QncyBpZiB5b3UganVzdAorICAvLy8gaGF2ZSBvcGVyYW5kcyBhbmQgZG9uJ3Qgd2FudCB0byBjaGVjayBmb3IgdmVjdG9yLgorICBTRFZhbHVlIGdldFNlbGVjdChjb25zdCBTRExvYyAmREwsIEVWVCBWVCwgU0RWYWx1ZSBDb25kLCBTRFZhbHVlIExIUywKKyAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBSSFMpIHsKKyAgICBhc3NlcnQoTEhTLmdldFZhbHVlVHlwZSgpID09IFJIUy5nZXRWYWx1ZVR5cGUoKSAmJgorICAgICAgICAgICAiQ2Fubm90IHVzZSBzZWxlY3Qgb24gZGlmZmVyaW5nIHR5cGVzIik7CisgICAgYXNzZXJ0KFZULmlzVmVjdG9yKCkgPT0gTEhTLmdldFZhbHVlVHlwZSgpLmlzVmVjdG9yKCkgJiYKKyAgICAgICAgICAgIkNhbm5vdCBtaXggdmVjdG9ycyBhbmQgc2NhbGFycyIpOworICAgIHJldHVybiBnZXROb2RlKENvbmQuZ2V0VmFsdWVUeXBlKCkuaXNWZWN0b3IoKSA/IElTRDo6VlNFTEVDVCA6IElTRDo6U0VMRUNULCBETCwgVlQsCisgICAgICAgICAgICAgICAgICAgQ29uZCwgTEhTLCBSSFMpOworICB9CisKKyAgLy8vIEhlbHBlciBmdW5jdGlvbiB0byBtYWtlIGl0IGVhc2llciB0byBidWlsZCBTZWxlY3RDQydzIGlmIHlvdQorICAvLy8ganVzdCBoYXZlIGFuIElTRDo6Q29uZENvZGUgaW5zdGVhZCBvZiBhbiBTRFZhbHVlLgorICAvLy8KKyAgU0RWYWx1ZSBnZXRTZWxlY3RDQyhjb25zdCBTRExvYyAmREwsIFNEVmFsdWUgTEhTLCBTRFZhbHVlIFJIUywgU0RWYWx1ZSBUcnVlLAorICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgRmFsc2UsIElTRDo6Q29uZENvZGUgQ29uZCkgeworICAgIHJldHVybiBnZXROb2RlKElTRDo6U0VMRUNUX0NDLCBETCwgVHJ1ZS5nZXRWYWx1ZVR5cGUoKSwKKyAgICAgICAgICAgICAgICAgICBMSFMsIFJIUywgVHJ1ZSwgRmFsc2UsIGdldENvbmRDb2RlKENvbmQpKTsKKyAgfQorCisgIC8vLyBWQUFyZyBwcm9kdWNlcyBhIHJlc3VsdCBhbmQgdG9rZW4gY2hhaW4sIGFuZCB0YWtlcyBhIHBvaW50ZXIKKyAgLy8vIGFuZCBhIHNvdXJjZSB2YWx1ZSBhcyBpbnB1dC4KKyAgU0RWYWx1ZSBnZXRWQUFyZyhFVlQgVlQsIGNvbnN0IFNETG9jICZkbCwgU0RWYWx1ZSBDaGFpbiwgU0RWYWx1ZSBQdHIsCisgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBTViwgdW5zaWduZWQgQWxpZ24pOworCisgIC8vLyBHZXRzIGEgbm9kZSBmb3IgYW4gYXRvbWljIGNtcHhjaGcgb3AuIFRoZXJlIGFyZSB0d28KKyAgLy8vIHZhbGlkIE9wY29kZXMuIElTRDo6QVRPTUlDX0NNT19TV0FQIHByb2R1Y2VzIHRoZSB2YWx1ZSBsb2FkZWQgYW5kIGEKKyAgLy8vIGNoYWluIHJlc3VsdC4gSVNEOjpBVE9NSUNfQ01QX1NXQVBfV0lUSF9TVUNDRVNTIHByb2R1Y2VzIHRoZSB2YWx1ZSBsb2FkZWQsCisgIC8vLyBhIHN1Y2Nlc3MgZmxhZyAoaW5pdGlhbGx5IGkxKSwgYW5kIGEgY2hhaW4uCisgIFNEVmFsdWUgZ2V0QXRvbWljQ21wU3dhcCh1bnNpZ25lZCBPcGNvZGUsIGNvbnN0IFNETG9jICZkbCwgRVZUIE1lbVZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWVExpc3QgVlRzLCBTRFZhbHVlIENoYWluLCBTRFZhbHVlIFB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgQ21wLCBTRFZhbHVlIFN3cCwgTWFjaGluZVBvaW50ZXJJbmZvIFB0ckluZm8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBBbGlnbm1lbnQsIEF0b21pY09yZGVyaW5nIFN1Y2Nlc3NPcmRlcmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIEF0b21pY09yZGVyaW5nIEZhaWx1cmVPcmRlcmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5bmNTY29wZTo6SUQgU1NJRCk7CisgIFNEVmFsdWUgZ2V0QXRvbWljQ21wU3dhcCh1bnNpZ25lZCBPcGNvZGUsIGNvbnN0IFNETG9jICZkbCwgRVZUIE1lbVZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWVExpc3QgVlRzLCBTRFZhbHVlIENoYWluLCBTRFZhbHVlIFB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgQ21wLCBTRFZhbHVlIFN3cCwgTWFjaGluZU1lbU9wZXJhbmQgKk1NTyk7CisKKyAgLy8vIEdldHMgYSBub2RlIGZvciBhbiBhdG9taWMgb3AsIHByb2R1Y2VzIHJlc3VsdCAoaWYgcmVsZXZhbnQpCisgIC8vLyBhbmQgY2hhaW4gYW5kIHRha2VzIDIgb3BlcmFuZHMuCisgIFNEVmFsdWUgZ2V0QXRvbWljKHVuc2lnbmVkIE9wY29kZSwgY29uc3QgU0RMb2MgJmRsLCBFVlQgTWVtVlQsIFNEVmFsdWUgQ2hhaW4sCisgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgUHRyLCBTRFZhbHVlIFZhbCwgY29uc3QgVmFsdWUgKlB0clZhbCwKKyAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgQWxpZ25tZW50LCBBdG9taWNPcmRlcmluZyBPcmRlcmluZywKKyAgICAgICAgICAgICAgICAgICAgU3luY1Njb3BlOjpJRCBTU0lEKTsKKyAgU0RWYWx1ZSBnZXRBdG9taWModW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmZGwsIEVWVCBNZW1WVCwgU0RWYWx1ZSBDaGFpbiwKKyAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBQdHIsIFNEVmFsdWUgVmFsLCBNYWNoaW5lTWVtT3BlcmFuZCAqTU1PKTsKKworICAvLy8gR2V0cyBhIG5vZGUgZm9yIGFuIGF0b21pYyBvcCwgcHJvZHVjZXMgcmVzdWx0IGFuZCBjaGFpbiBhbmQKKyAgLy8vIHRha2VzIDEgb3BlcmFuZC4KKyAgU0RWYWx1ZSBnZXRBdG9taWModW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmZGwsIEVWVCBNZW1WVCwgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIENoYWluLCBTRFZhbHVlIFB0ciwgTWFjaGluZU1lbU9wZXJhbmQgKk1NTyk7CisKKyAgLy8vIEdldHMgYSBub2RlIGZvciBhbiBhdG9taWMgb3AsIHByb2R1Y2VzIHJlc3VsdCBhbmQgY2hhaW4gYW5kIHRha2VzIE4KKyAgLy8vIG9wZXJhbmRzLgorICBTRFZhbHVlIGdldEF0b21pYyh1bnNpZ25lZCBPcGNvZGUsIGNvbnN0IFNETG9jICZkbCwgRVZUIE1lbVZULAorICAgICAgICAgICAgICAgICAgICBTRFZUTGlzdCBWVExpc3QsIEFycmF5UmVmPFNEVmFsdWU+IE9wcywKKyAgICAgICAgICAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQgKk1NTyk7CisKKyAgLy8vIENyZWF0ZXMgYSBNZW1JbnRyaW5zaWNOb2RlIHRoYXQgbWF5IHByb2R1Y2UgYQorICAvLy8gcmVzdWx0IGFuZCB0YWtlcyBhIGxpc3Qgb2Ygb3BlcmFuZHMuIE9wY29kZSBtYXkgYmUgSU5UUklOU0lDX1ZPSUQsCisgIC8vLyBJTlRSSU5TSUNfV19DSEFJTiwgb3IgYSB0YXJnZXQtc3BlY2lmaWMgb3Bjb2RlIHdpdGggYSB2YWx1ZSBub3QKKyAgLy8vIGxlc3MgdGhhbiBGSVJTVF9UQVJHRVRfTUVNT1JZX09QQ09ERS4KKyAgU0RWYWx1ZSBnZXRNZW1JbnRyaW5zaWNOb2RlKAorICAgIHVuc2lnbmVkIE9wY29kZSwgY29uc3QgU0RMb2MgJmRsLCBTRFZUTGlzdCBWVExpc3QsCisgICAgQXJyYXlSZWY8U0RWYWx1ZT4gT3BzLCBFVlQgTWVtVlQsCisgICAgTWFjaGluZVBvaW50ZXJJbmZvIFB0ckluZm8sCisgICAgdW5zaWduZWQgQWxpZ24gPSAwLAorICAgIE1hY2hpbmVNZW1PcGVyYW5kOjpGbGFncyBGbGFncworICAgID0gTWFjaGluZU1lbU9wZXJhbmQ6Ok1PTG9hZCB8IE1hY2hpbmVNZW1PcGVyYW5kOjpNT1N0b3JlLAorICAgIHVuc2lnbmVkIFNpemUgPSAwKTsKKworICBTRFZhbHVlIGdldE1lbUludHJpbnNpY05vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmZGwsIFNEVlRMaXN0IFZUTGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFNEVmFsdWU+IE9wcywgRVZUIE1lbVZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQgKk1NTyk7CisKKyAgLy8vIENyZWF0ZSBhIE1FUkdFX1ZBTFVFUyBub2RlIGZyb20gdGhlIGdpdmVuIG9wZXJhbmRzLgorICBTRFZhbHVlIGdldE1lcmdlVmFsdWVzKEFycmF5UmVmPFNEVmFsdWU+IE9wcywgY29uc3QgU0RMb2MgJmRsKTsKKworICAvLy8gTG9hZHMgYXJlIG5vdCBub3JtYWwgYmluYXJ5IG9wZXJhdG9yczogdGhlaXIgcmVzdWx0IHR5cGUgaXMgbm90CisgIC8vLyBkZXRlcm1pbmVkIGJ5IHRoZWlyIG9wZXJhbmRzLCBhbmQgdGhleSBwcm9kdWNlIGEgdmFsdWUgQU5EIGEgdG9rZW4gY2hhaW4uCisgIC8vLworICAvLy8gVGhpcyBmdW5jdGlvbiB3aWxsIHNldCB0aGUgTU9Mb2FkIGZsYWcgb24gTU1PRmxhZ3MsIGJ1dCB5b3UgY2FuIHNldCBpdCBpZgorICAvLy8geW91IHdhbnQuICBUaGUgTU9TdG9yZSBmbGFnIG11c3Qgbm90IGJlIHNldC4KKyAgU0RWYWx1ZSBnZXRMb2FkKEVWVCBWVCwgY29uc3QgU0RMb2MgJmRsLCBTRFZhbHVlIENoYWluLCBTRFZhbHVlIFB0ciwKKyAgICAgICAgICAgICAgICAgIE1hY2hpbmVQb2ludGVySW5mbyBQdHJJbmZvLCB1bnNpZ25lZCBBbGlnbm1lbnQgPSAwLAorICAgICAgICAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQ6OkZsYWdzIE1NT0ZsYWdzID0gTWFjaGluZU1lbU9wZXJhbmQ6Ok1PTm9uZSwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IEFBTUROb2RlcyAmQUFJbmZvID0gQUFNRE5vZGVzKCksCisgICAgICAgICAgICAgICAgICBjb25zdCBNRE5vZGUgKlJhbmdlcyA9IG51bGxwdHIpOworICBTRFZhbHVlIGdldExvYWQoRVZUIFZULCBjb25zdCBTRExvYyAmZGwsIFNEVmFsdWUgQ2hhaW4sIFNEVmFsdWUgUHRyLAorICAgICAgICAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQgKk1NTyk7CisgIFNEVmFsdWUKKyAgZ2V0RXh0TG9hZChJU0Q6OkxvYWRFeHRUeXBlIEV4dFR5cGUsIGNvbnN0IFNETG9jICZkbCwgRVZUIFZULCBTRFZhbHVlIENoYWluLAorICAgICAgICAgICAgIFNEVmFsdWUgUHRyLCBNYWNoaW5lUG9pbnRlckluZm8gUHRySW5mbywgRVZUIE1lbVZULAorICAgICAgICAgICAgIHVuc2lnbmVkIEFsaWdubWVudCA9IDAsCisgICAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQ6OkZsYWdzIE1NT0ZsYWdzID0gTWFjaGluZU1lbU9wZXJhbmQ6Ok1PTm9uZSwKKyAgICAgICAgICAgICBjb25zdCBBQU1ETm9kZXMgJkFBSW5mbyA9IEFBTUROb2RlcygpKTsKKyAgU0RWYWx1ZSBnZXRFeHRMb2FkKElTRDo6TG9hZEV4dFR5cGUgRXh0VHlwZSwgY29uc3QgU0RMb2MgJmRsLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIENoYWluLCBTRFZhbHVlIFB0ciwgRVZUIE1lbVZULAorICAgICAgICAgICAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQgKk1NTyk7CisgIFNEVmFsdWUgZ2V0SW5kZXhlZExvYWQoU0RWYWx1ZSBPcmlnTG9hZCwgY29uc3QgU0RMb2MgJmRsLCBTRFZhbHVlIEJhc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBPZmZzZXQsIElTRDo6TWVtSW5kZXhlZE1vZGUgQU0pOworICBTRFZhbHVlIGdldExvYWQoSVNEOjpNZW1JbmRleGVkTW9kZSBBTSwgSVNEOjpMb2FkRXh0VHlwZSBFeHRUeXBlLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICBjb25zdCBTRExvYyAmZGwsIFNEVmFsdWUgQ2hhaW4sIFNEVmFsdWUgUHRyLCBTRFZhbHVlIE9mZnNldCwKKyAgICAgICAgICAgICAgICAgIE1hY2hpbmVQb2ludGVySW5mbyBQdHJJbmZvLCBFVlQgTWVtVlQsIHVuc2lnbmVkIEFsaWdubWVudCA9IDAsCisgICAgICAgICAgICAgICAgICBNYWNoaW5lTWVtT3BlcmFuZDo6RmxhZ3MgTU1PRmxhZ3MgPSBNYWNoaW5lTWVtT3BlcmFuZDo6TU9Ob25lLAorICAgICAgICAgICAgICAgICAgY29uc3QgQUFNRE5vZGVzICZBQUluZm8gPSBBQU1ETm9kZXMoKSwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IE1ETm9kZSAqUmFuZ2VzID0gbnVsbHB0cik7CisgIFNEVmFsdWUgZ2V0TG9hZChJU0Q6Ok1lbUluZGV4ZWRNb2RlIEFNLCBJU0Q6OkxvYWRFeHRUeXBlIEV4dFR5cGUsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IFNETG9jICZkbCwgU0RWYWx1ZSBDaGFpbiwgU0RWYWx1ZSBQdHIsIFNEVmFsdWUgT2Zmc2V0LAorICAgICAgICAgICAgICAgICAgRVZUIE1lbVZULCBNYWNoaW5lTWVtT3BlcmFuZCAqTU1PKTsKKworICAvLy8gSGVscGVyIGZ1bmN0aW9uIHRvIGJ1aWxkIElTRDo6U1RPUkUgbm9kZXMuCisgIC8vLworICAvLy8gVGhpcyBmdW5jdGlvbiB3aWxsIHNldCB0aGUgTU9TdG9yZSBmbGFnIG9uIE1NT0ZsYWdzLCBidXQgeW91IGNhbiBzZXQgaXQgaWYKKyAgLy8vIHlvdSB3YW50LiAgVGhlIE1PTG9hZCBhbmQgTU9JbnZhcmlhbnQgZmxhZ3MgbXVzdCBub3QgYmUgc2V0LgorICBTRFZhbHVlCisgIGdldFN0b3JlKFNEVmFsdWUgQ2hhaW4sIGNvbnN0IFNETG9jICZkbCwgU0RWYWx1ZSBWYWwsIFNEVmFsdWUgUHRyLAorICAgICAgICAgICBNYWNoaW5lUG9pbnRlckluZm8gUHRySW5mbywgdW5zaWduZWQgQWxpZ25tZW50ID0gMCwKKyAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQ6OkZsYWdzIE1NT0ZsYWdzID0gTWFjaGluZU1lbU9wZXJhbmQ6Ok1PTm9uZSwKKyAgICAgICAgICAgY29uc3QgQUFNRE5vZGVzICZBQUluZm8gPSBBQU1ETm9kZXMoKSk7CisgIFNEVmFsdWUgZ2V0U3RvcmUoU0RWYWx1ZSBDaGFpbiwgY29uc3QgU0RMb2MgJmRsLCBTRFZhbHVlIFZhbCwgU0RWYWx1ZSBQdHIsCisgICAgICAgICAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQgKk1NTyk7CisgIFNEVmFsdWUKKyAgZ2V0VHJ1bmNTdG9yZShTRFZhbHVlIENoYWluLCBjb25zdCBTRExvYyAmZGwsIFNEVmFsdWUgVmFsLCBTRFZhbHVlIFB0ciwKKyAgICAgICAgICAgICAgICBNYWNoaW5lUG9pbnRlckluZm8gUHRySW5mbywgRVZUIFRWVCwgdW5zaWduZWQgQWxpZ25tZW50ID0gMCwKKyAgICAgICAgICAgICAgICBNYWNoaW5lTWVtT3BlcmFuZDo6RmxhZ3MgTU1PRmxhZ3MgPSBNYWNoaW5lTWVtT3BlcmFuZDo6TU9Ob25lLAorICAgICAgICAgICAgICAgIGNvbnN0IEFBTUROb2RlcyAmQUFJbmZvID0gQUFNRE5vZGVzKCkpOworICBTRFZhbHVlIGdldFRydW5jU3RvcmUoU0RWYWx1ZSBDaGFpbiwgY29uc3QgU0RMb2MgJmRsLCBTRFZhbHVlIFZhbCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgUHRyLCBFVlQgVFZULCBNYWNoaW5lTWVtT3BlcmFuZCAqTU1PKTsKKyAgU0RWYWx1ZSBnZXRJbmRleGVkU3RvcmUoU0RWYWx1ZSBPcmlnU3RvZSwgY29uc3QgU0RMb2MgJmRsLCBTRFZhbHVlIEJhc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgT2Zmc2V0LCBJU0Q6Ok1lbUluZGV4ZWRNb2RlIEFNKTsKKworICAvLy8gUmV0dXJucyBzdW0gb2YgdGhlIGJhc2UgcG9pbnRlciBhbmQgb2Zmc2V0LgorICBTRFZhbHVlIGdldE1lbUJhc2VQbHVzT2Zmc2V0KFNEVmFsdWUgQmFzZSwgdW5zaWduZWQgT2Zmc2V0LCBjb25zdCBTRExvYyAmREwpOworCisgIFNEVmFsdWUgZ2V0TWFza2VkTG9hZChFVlQgVlQsIGNvbnN0IFNETG9jICZkbCwgU0RWYWx1ZSBDaGFpbiwgU0RWYWx1ZSBQdHIsCisgICAgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIE1hc2ssIFNEVmFsdWUgU3JjMCwgRVZUIE1lbVZULAorICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQgKk1NTywgSVNEOjpMb2FkRXh0VHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgSXNFeHBhbmRpbmcgPSBmYWxzZSk7CisgIFNEVmFsdWUgZ2V0TWFza2VkU3RvcmUoU0RWYWx1ZSBDaGFpbiwgY29uc3QgU0RMb2MgJmRsLCBTRFZhbHVlIFZhbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIFB0ciwgU0RWYWx1ZSBNYXNrLCBFVlQgTWVtVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQgKk1NTywgYm9vbCBJc1RydW5jYXRpbmcgPSBmYWxzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBib29sIElzQ29tcHJlc3NpbmcgPSBmYWxzZSk7CisgIFNEVmFsdWUgZ2V0TWFza2VkR2F0aGVyKFNEVlRMaXN0IFZUcywgRVZUIFZULCBjb25zdCBTRExvYyAmZGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFNEVmFsdWU+IE9wcywgTWFjaGluZU1lbU9wZXJhbmQgKk1NTyk7CisgIFNEVmFsdWUgZ2V0TWFza2VkU2NhdHRlcihTRFZUTGlzdCBWVHMsIEVWVCBWVCwgY29uc3QgU0RMb2MgJmRsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8U0RWYWx1ZT4gT3BzLCBNYWNoaW5lTWVtT3BlcmFuZCAqTU1PKTsKKworICAvLy8gUmV0dXJuIChjcmVhdGUgYSBuZXcgb3IgZmluZCBleGlzdGluZykgYSB0YXJnZXQtc3BlY2lmaWMgbm9kZS4KKyAgLy8vIFRhcmdldE1lbVNETm9kZSBzaG91bGQgYmUgZGVyaXZlZCBjbGFzcyBmcm9tIE1lbVNETm9kZS4KKyAgdGVtcGxhdGUgPGNsYXNzIFRhcmdldE1lbVNETm9kZT4KKyAgU0RWYWx1ZSBnZXRUYXJnZXRNZW1TRE5vZGUoU0RWVExpc3QgVlRzLCBBcnJheVJlZjxTRFZhbHVlPiBPcHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNETG9jICZkbCwgRVZUIE1lbVZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lTWVtT3BlcmFuZCAqTU1PKTsKKworICAvLy8gQ29uc3RydWN0IGEgbm9kZSB0byB0cmFjayBhIFZhbHVlKiB0aHJvdWdoIHRoZSBiYWNrZW5kLgorICBTRFZhbHVlIGdldFNyY1ZhbHVlKGNvbnN0IFZhbHVlICp2KTsKKworICAvLy8gUmV0dXJuIGFuIE1ETm9kZVNETm9kZSB3aGljaCBob2xkcyBhbiBNRE5vZGUuCisgIFNEVmFsdWUgZ2V0TUROb2RlKGNvbnN0IE1ETm9kZSAqTUQpOworCisgIC8vLyBSZXR1cm4gYSBiaXRjYXN0IHVzaW5nIHRoZSBTRExvYyBvZiB0aGUgdmFsdWUgb3BlcmFuZCwgYW5kIGNhc3RpbmcgdG8gdGhlCisgIC8vLyBwcm92aWRlZCB0eXBlLiBVc2UgZ2V0Tm9kZSB0byBzZXQgYSBjdXN0b20gU0RMb2MuCisgIFNEVmFsdWUgZ2V0Qml0Y2FzdChFVlQgVlQsIFNEVmFsdWUgVik7CisKKyAgLy8vIFJldHVybiBhbiBBZGRyU3BhY2VDYXN0U0ROb2RlLgorICBTRFZhbHVlIGdldEFkZHJTcGFjZUNhc3QoY29uc3QgU0RMb2MgJmRsLCBFVlQgVlQsIFNEVmFsdWUgUHRyLCB1bnNpZ25lZCBTcmNBUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIERlc3RBUyk7CisKKyAgLy8vIFJldHVybiB0aGUgc3BlY2lmaWVkIHZhbHVlIGNhc3RlZCB0bworICAvLy8gdGhlIHRhcmdldCdzIGRlc2lyZWQgc2hpZnQgYW1vdW50IHR5cGUuCisgIFNEVmFsdWUgZ2V0U2hpZnRBbW91bnRPcGVyYW5kKEVWVCBMSFNUeSwgU0RWYWx1ZSBPcCk7CisKKyAgLy8vIEV4cGFuZCB0aGUgc3BlY2lmaWVkIFxjIElTRDo6VkFBUkcgbm9kZSBhcyB0aGUgTGVnYWxpemUgcGFzcyB3b3VsZC4KKyAgU0RWYWx1ZSBleHBhbmRWQUFyZyhTRE5vZGUgKk5vZGUpOworCisgIC8vLyBFeHBhbmQgdGhlIHNwZWNpZmllZCBcYyBJU0Q6OlZBQ09QWSBub2RlIGFzIHRoZSBMZWdhbGl6ZSBwYXNzIHdvdWxkLgorICBTRFZhbHVlIGV4cGFuZFZBQ29weShTRE5vZGUgKk5vZGUpOworCisgIC8vLyAqTXV0YXRlKiB0aGUgc3BlY2lmaWVkIG5vZGUgaW4tcGxhY2UgdG8gaGF2ZSB0aGUKKyAgLy8vIHNwZWNpZmllZCBvcGVyYW5kcy4gIElmIHRoZSByZXN1bHRhbnQgbm9kZSBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgREFHLAorICAvLy8gdGhpcyBkb2VzIG5vdCBtb2RpZnkgdGhlIHNwZWNpZmllZCBub2RlLCBpbnN0ZWFkIGl0IHJldHVybnMgdGhlIG5vZGUgdGhhdAorICAvLy8gYWxyZWFkeSBleGlzdHMuICBJZiB0aGUgcmVzdWx0YW50IG5vZGUgZG9lcyBub3QgZXhpc3QgaW4gdGhlIERBRywgdGhlCisgIC8vLyBpbnB1dCBub2RlIGlzIHJldHVybmVkLiAgQXMgYSBkZWdlbmVyYXRlIGNhc2UsIGlmIHlvdSBzcGVjaWZ5IHRoZSBzYW1lCisgIC8vLyBpbnB1dCBvcGVyYW5kcyBhcyB0aGUgbm9kZSBhbHJlYWR5IGhhcywgdGhlIGlucHV0IG5vZGUgaXMgcmV0dXJuZWQuCisgIFNETm9kZSAqVXBkYXRlTm9kZU9wZXJhbmRzKFNETm9kZSAqTiwgU0RWYWx1ZSBPcCk7CisgIFNETm9kZSAqVXBkYXRlTm9kZU9wZXJhbmRzKFNETm9kZSAqTiwgU0RWYWx1ZSBPcDEsIFNEVmFsdWUgT3AyKTsKKyAgU0ROb2RlICpVcGRhdGVOb2RlT3BlcmFuZHMoU0ROb2RlICpOLCBTRFZhbHVlIE9wMSwgU0RWYWx1ZSBPcDIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBPcDMpOworICBTRE5vZGUgKlVwZGF0ZU5vZGVPcGVyYW5kcyhTRE5vZGUgKk4sIFNEVmFsdWUgT3AxLCBTRFZhbHVlIE9wMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIE9wMywgU0RWYWx1ZSBPcDQpOworICBTRE5vZGUgKlVwZGF0ZU5vZGVPcGVyYW5kcyhTRE5vZGUgKk4sIFNEVmFsdWUgT3AxLCBTRFZhbHVlIE9wMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIE9wMywgU0RWYWx1ZSBPcDQsIFNEVmFsdWUgT3A1KTsKKyAgU0ROb2RlICpVcGRhdGVOb2RlT3BlcmFuZHMoU0ROb2RlICpOLCBBcnJheVJlZjxTRFZhbHVlPiBPcHMpOworCisgIC8vIFByb3BhZ2F0ZXMgdGhlIGNoYW5nZSBpbiBkaXZlcmdlbmNlIHRvIHVzZXJzCisgIHZvaWQgdXBkYXRlRGl2ZXJnZW5jZShTRE5vZGUgKiBOKTsKKworICAvLy8gVGhlc2UgYXJlIHVzZWQgZm9yIHRhcmdldCBzZWxlY3RvcnMgdG8gKm11dGF0ZSogdGhlCisgIC8vLyBzcGVjaWZpZWQgbm9kZSB0byBoYXZlIHRoZSBzcGVjaWZpZWQgcmV0dXJuIHR5cGUsIFRhcmdldCBvcGNvZGUsIGFuZAorICAvLy8gb3BlcmFuZHMuICBOb3RlIHRoYXQgdGFyZ2V0IG9wY29kZXMgYXJlIHN0b3JlZCBhcworICAvLy8gflRhcmdldE9wY29kZSBpbiB0aGUgbm9kZSBvcGNvZGUgZmllbGQuICBUaGUgcmVzdWx0YW50IG5vZGUgaXMgcmV0dXJuZWQuCisgIFNETm9kZSAqU2VsZWN0Tm9kZVRvKFNETm9kZSAqTiwgdW5zaWduZWQgVGFyZ2V0T3BjLCBFVlQgVlQpOworICBTRE5vZGUgKlNlbGVjdE5vZGVUbyhTRE5vZGUgKk4sIHVuc2lnbmVkIFRhcmdldE9wYywgRVZUIFZULCBTRFZhbHVlIE9wMSk7CisgIFNETm9kZSAqU2VsZWN0Tm9kZVRvKFNETm9kZSAqTiwgdW5zaWduZWQgVGFyZ2V0T3BjLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgT3AxLCBTRFZhbHVlIE9wMik7CisgIFNETm9kZSAqU2VsZWN0Tm9kZVRvKFNETm9kZSAqTiwgdW5zaWduZWQgVGFyZ2V0T3BjLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgT3AxLCBTRFZhbHVlIE9wMiwgU0RWYWx1ZSBPcDMpOworICBTRE5vZGUgKlNlbGVjdE5vZGVUbyhTRE5vZGUgKk4sIHVuc2lnbmVkIFRhcmdldE9wYywgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjxTRFZhbHVlPiBPcHMpOworICBTRE5vZGUgKlNlbGVjdE5vZGVUbyhTRE5vZGUgKk4sIHVuc2lnbmVkIFRhcmdldE9wYywgRVZUIFZUMSwgRVZUIFZUMik7CisgIFNETm9kZSAqU2VsZWN0Tm9kZVRvKFNETm9kZSAqTiwgdW5zaWduZWQgVGFyZ2V0T3BjLCBFVlQgVlQxLAorICAgICAgICAgICAgICAgICAgICAgICBFVlQgVlQyLCBBcnJheVJlZjxTRFZhbHVlPiBPcHMpOworICBTRE5vZGUgKlNlbGVjdE5vZGVUbyhTRE5vZGUgKk4sIHVuc2lnbmVkIFRhcmdldE9wYywgRVZUIFZUMSwKKyAgICAgICAgICAgICAgICAgICAgICAgRVZUIFZUMiwgRVZUIFZUMywgQXJyYXlSZWY8U0RWYWx1ZT4gT3BzKTsKKyAgU0ROb2RlICpTZWxlY3ROb2RlVG8oU0ROb2RlICpOLCB1bnNpZ25lZCBUYXJnZXRPcGMsIEVWVCBWVDEsCisgICAgICAgICAgICAgICAgICAgICAgIEVWVCBWVDIsIFNEVmFsdWUgT3AxKTsKKyAgU0ROb2RlICpTZWxlY3ROb2RlVG8oU0ROb2RlICpOLCB1bnNpZ25lZCBUYXJnZXRPcGMsIEVWVCBWVDEsCisgICAgICAgICAgICAgICAgICAgICAgIEVWVCBWVDIsIFNEVmFsdWUgT3AxLCBTRFZhbHVlIE9wMik7CisgIFNETm9kZSAqU2VsZWN0Tm9kZVRvKFNETm9kZSAqTiwgdW5zaWduZWQgVGFyZ2V0T3BjLCBTRFZUTGlzdCBWVHMsCisgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFNEVmFsdWU+IE9wcyk7CisKKyAgLy8vIFRoaXMgKm11dGF0ZXMqIHRoZSBzcGVjaWZpZWQgbm9kZSB0byBoYXZlIHRoZSBzcGVjaWZpZWQKKyAgLy8vIHJldHVybiB0eXBlLCBvcGNvZGUsIGFuZCBvcGVyYW5kcy4KKyAgU0ROb2RlICpNb3JwaE5vZGVUbyhTRE5vZGUgKk4sIHVuc2lnbmVkIE9wYywgU0RWVExpc3QgVlRzLAorICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFNEVmFsdWU+IE9wcyk7CisKKyAgLy8vIE11dGF0ZSB0aGUgc3BlY2lmaWVkIHN0cmljdCBGUCBub2RlIHRvIGl0cyBub24tc3RyaWN0IGVxdWl2YWxlbnQsCisgIC8vLyB1bmxpbmtpbmcgdGhlIG5vZGUgZnJvbSBpdHMgY2hhaW4gYW5kIGRyb3BwaW5nIHRoZSBtZXRhZGF0YSBhcmd1bWVudHMuCisgIC8vLyBUaGUgbm9kZSBtdXN0IGJlIGEgc3RyaWN0IEZQIG5vZGUuCisgIFNETm9kZSAqbXV0YXRlU3RyaWN0RlBUb0ZQKFNETm9kZSAqTm9kZSk7CisKKyAgLy8vIFRoZXNlIGFyZSB1c2VkIGZvciB0YXJnZXQgc2VsZWN0b3JzIHRvIGNyZWF0ZSBhIG5ldyBub2RlCisgIC8vLyB3aXRoIHNwZWNpZmllZCByZXR1cm4gdHlwZShzKSwgTWFjaGluZUluc3RyIG9wY29kZSwgYW5kIG9wZXJhbmRzLgorICAvLy8KKyAgLy8vIE5vdGUgdGhhdCBnZXRNYWNoaW5lTm9kZSByZXR1cm5zIHRoZSByZXN1bHRhbnQgbm9kZS4gIElmIHRoZXJlIGlzIGFscmVhZHkKKyAgLy8vIGEgbm9kZSBvZiB0aGUgc3BlY2lmaWVkIG9wY29kZSBhbmQgb3BlcmFuZHMsIGl0IHJldHVybnMgdGhhdCBub2RlIGluc3RlYWQKKyAgLy8vIG9mIHRoZSBjdXJyZW50IG9uZS4KKyAgTWFjaGluZVNETm9kZSAqZ2V0TWFjaGluZU5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmZGwsIEVWVCBWVCk7CisgIE1hY2hpbmVTRE5vZGUgKmdldE1hY2hpbmVOb2RlKHVuc2lnbmVkIE9wY29kZSwgY29uc3QgU0RMb2MgJmRsLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgT3AxKTsKKyAgTWFjaGluZVNETm9kZSAqZ2V0TWFjaGluZU5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmZGwsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBPcDEsIFNEVmFsdWUgT3AyKTsKKyAgTWFjaGluZVNETm9kZSAqZ2V0TWFjaGluZU5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmZGwsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBPcDEsIFNEVmFsdWUgT3AyLCBTRFZhbHVlIE9wMyk7CisgIE1hY2hpbmVTRE5vZGUgKmdldE1hY2hpbmVOb2RlKHVuc2lnbmVkIE9wY29kZSwgY29uc3QgU0RMb2MgJmRsLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFNEVmFsdWU+IE9wcyk7CisgIE1hY2hpbmVTRE5vZGUgKmdldE1hY2hpbmVOb2RlKHVuc2lnbmVkIE9wY29kZSwgY29uc3QgU0RMb2MgJmRsLCBFVlQgVlQxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFVlQgVlQyLCBTRFZhbHVlIE9wMSwgU0RWYWx1ZSBPcDIpOworICBNYWNoaW5lU0ROb2RlICpnZXRNYWNoaW5lTm9kZSh1bnNpZ25lZCBPcGNvZGUsIGNvbnN0IFNETG9jICZkbCwgRVZUIFZUMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVZUIFZUMiwgU0RWYWx1ZSBPcDEsIFNEVmFsdWUgT3AyLCBTRFZhbHVlIE9wMyk7CisgIE1hY2hpbmVTRE5vZGUgKmdldE1hY2hpbmVOb2RlKHVuc2lnbmVkIE9wY29kZSwgY29uc3QgU0RMb2MgJmRsLCBFVlQgVlQxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFVlQgVlQyLCBBcnJheVJlZjxTRFZhbHVlPiBPcHMpOworICBNYWNoaW5lU0ROb2RlICpnZXRNYWNoaW5lTm9kZSh1bnNpZ25lZCBPcGNvZGUsIGNvbnN0IFNETG9jICZkbCwgRVZUIFZUMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVZUIFZUMiwgRVZUIFZUMywgU0RWYWx1ZSBPcDEsIFNEVmFsdWUgT3AyKTsKKyAgTWFjaGluZVNETm9kZSAqZ2V0TWFjaGluZU5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmZGwsIEVWVCBWVDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVWVCBWVDIsIEVWVCBWVDMsIFNEVmFsdWUgT3AxLCBTRFZhbHVlIE9wMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBPcDMpOworICBNYWNoaW5lU0ROb2RlICpnZXRNYWNoaW5lTm9kZSh1bnNpZ25lZCBPcGNvZGUsIGNvbnN0IFNETG9jICZkbCwgRVZUIFZUMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVZUIFZUMiwgRVZUIFZUMywgQXJyYXlSZWY8U0RWYWx1ZT4gT3BzKTsKKyAgTWFjaGluZVNETm9kZSAqZ2V0TWFjaGluZU5vZGUodW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmZGwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPEVWVD4gUmVzdWx0VHlzLCBBcnJheVJlZjxTRFZhbHVlPiBPcHMpOworICBNYWNoaW5lU0ROb2RlICpnZXRNYWNoaW5lTm9kZSh1bnNpZ25lZCBPcGNvZGUsIGNvbnN0IFNETG9jICZkbCwgU0RWVExpc3QgVlRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjxTRFZhbHVlPiBPcHMpOworCisgIC8vLyBBIGNvbnZlbmllbmNlIGZ1bmN0aW9uIGZvciBjcmVhdGluZyBUYXJnZXRJbnN0ckluZm86OkVYVFJBQ1RfU1VCUkVHIG5vZGVzLgorICBTRFZhbHVlIGdldFRhcmdldEV4dHJhY3RTdWJyZWcoaW50IFNSSWR4LCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgT3BlcmFuZCk7CisKKyAgLy8vIEEgY29udmVuaWVuY2UgZnVuY3Rpb24gZm9yIGNyZWF0aW5nIFRhcmdldEluc3RySW5mbzo6SU5TRVJUX1NVQlJFRyBub2Rlcy4KKyAgU0RWYWx1ZSBnZXRUYXJnZXRJbnNlcnRTdWJyZWcoaW50IFNSSWR4LCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBPcGVyYW5kLCBTRFZhbHVlIFN1YnJlZyk7CisKKyAgLy8vIEdldCB0aGUgc3BlY2lmaWVkIG5vZGUgaWYgaXQncyBhbHJlYWR5IGF2YWlsYWJsZSwgb3IgZWxzZSByZXR1cm4gTlVMTC4KKyAgU0ROb2RlICpnZXROb2RlSWZFeGlzdHModW5zaWduZWQgT3Bjb2RlLCBTRFZUTGlzdCBWVHMsIEFycmF5UmVmPFNEVmFsdWU+IE9wcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU0ROb2RlRmxhZ3MgRmxhZ3MgPSBTRE5vZGVGbGFncygpKTsKKworICAvLy8gQ3JlYXRlcyBhIFNERGJnVmFsdWUgbm9kZS4KKyAgU0REYmdWYWx1ZSAqZ2V0RGJnVmFsdWUoRElWYXJpYWJsZSAqVmFyLCBESUV4cHJlc3Npb24gKkV4cHIsIFNETm9kZSAqTiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgUiwgYm9vbCBJc0luZGlyZWN0LCBjb25zdCBEZWJ1Z0xvYyAmREwsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIE8pOworCisgIC8vLyBDcmVhdGVzIGEgY29uc3RhbnQgU0REYmdWYWx1ZSBub2RlLgorICBTRERiZ1ZhbHVlICpnZXRDb25zdGFudERiZ1ZhbHVlKERJVmFyaWFibGUgKlZhciwgRElFeHByZXNzaW9uICpFeHByLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFZhbHVlICpDLCBjb25zdCBEZWJ1Z0xvYyAmREwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgTyk7CisKKyAgLy8vIENyZWF0ZXMgYSBGcmFtZUluZGV4IFNERGJnVmFsdWUgbm9kZS4KKyAgU0REYmdWYWx1ZSAqZ2V0RnJhbWVJbmRleERiZ1ZhbHVlKERJVmFyaWFibGUgKlZhciwgRElFeHByZXNzaW9uICpFeHByLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgRkksIGNvbnN0IERlYnVnTG9jICZETCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIE8pOworCisgIC8vLyBUcmFuc2ZlciBkZWJ1ZyB2YWx1ZXMgZnJvbSBvbmUgbm9kZSB0byBhbm90aGVyLCB3aGlsZSBvcHRpb25hbGx5CisgIC8vLyBnZW5lcmF0aW5nIGZyYWdtZW50IGV4cHJlc3Npb25zIGZvciBzcGxpdC11cCB2YWx1ZXMuIElmIFxwIEludmFsaWRhdGVEYmcKKyAgLy8vIGlzIHNldCwgZGVidWcgdmFsdWVzIGFyZSBpbnZhbGlkYXRlZCBhZnRlciB0aGV5IGFyZSB0cmFuc2ZlcnJlZC4KKyAgdm9pZCB0cmFuc2ZlckRiZ1ZhbHVlcyhTRFZhbHVlIEZyb20sIFNEVmFsdWUgVG8sIHVuc2lnbmVkIE9mZnNldEluQml0cyA9IDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgU2l6ZUluQml0cyA9IDAsIGJvb2wgSW52YWxpZGF0ZURiZyA9IHRydWUpOworCisgIC8vLyBSZW1vdmUgdGhlIHNwZWNpZmllZCBub2RlIGZyb20gdGhlIHN5c3RlbS4gSWYgYW55IG9mIGl0cworICAvLy8gb3BlcmFuZHMgdGhlbiBiZWNvbWVzIGRlYWQsIHJlbW92ZSB0aGVtIGFzIHdlbGwuIEluZm9ybSBVcGRhdGVMaXN0ZW5lcgorICAvLy8gZm9yIGVhY2ggbm9kZSBkZWxldGVkLgorICB2b2lkIFJlbW92ZURlYWROb2RlKFNETm9kZSAqTik7CisKKyAgLy8vIFRoaXMgbWV0aG9kIGRlbGV0ZXMgdGhlIHVucmVhY2hhYmxlIG5vZGVzIGluIHRoZQorICAvLy8gZ2l2ZW4gbGlzdCwgYW5kIGFueSBub2RlcyB0aGF0IGJlY29tZSB1bnJlYWNoYWJsZSBhcyBhIHJlc3VsdC4KKyAgdm9pZCBSZW1vdmVEZWFkTm9kZXMoU21hbGxWZWN0b3JJbXBsPFNETm9kZSAqPiAmRGVhZE5vZGVzKTsKKworICAvLy8gTW9kaWZ5IGFueXRoaW5nIHVzaW5nICdGcm9tJyB0byB1c2UgJ1RvJyBpbnN0ZWFkLgorICAvLy8gVGhpcyBjYW4gY2F1c2UgcmVjdXJzaXZlIG1lcmdpbmcgb2Ygbm9kZXMgaW4gdGhlIERBRy4gIFVzZSB0aGUgZmlyc3QKKyAgLy8vIHZlcnNpb24gaWYgJ0Zyb20nIGlzIGtub3duIHRvIGhhdmUgYSBzaW5nbGUgcmVzdWx0LCB1c2UgdGhlIHNlY29uZAorICAvLy8gaWYgeW91IGhhdmUgdHdvIG5vZGVzIHdpdGggaWRlbnRpY2FsIHJlc3VsdHMgKG9yIGlmICdUbycgaGFzIGEgc3VwZXJzZXQKKyAgLy8vIG9mIHRoZSByZXN1bHRzIG9mICdGcm9tJyksIHVzZSB0aGUgdGhpcmQgb3RoZXJ3aXNlLgorICAvLy8KKyAgLy8vIFRoZXNlIG1ldGhvZHMgYWxsIHRha2UgYW4gb3B0aW9uYWwgVXBkYXRlTGlzdGVuZXIsIHdoaWNoIChpZiBub3QgbnVsbCkgaXMKKyAgLy8vIGluZm9ybWVkIGFib3V0IG5vZGVzIHRoYXQgYXJlIGRlbGV0ZWQgYW5kIG1vZGlmaWVkIGR1ZSB0byByZWN1cnNpdmUKKyAgLy8vIGNoYW5nZXMgaW4gdGhlIGRhZy4KKyAgLy8vCisgIC8vLyBUaGVzZSBmdW5jdGlvbnMgb25seSByZXBsYWNlIGFsbCBleGlzdGluZyB1c2VzLiBJdCdzIHBvc3NpYmxlIHRoYXQgYXMKKyAgLy8vIHRoZXNlIHJlcGxhY2VtZW50cyBhcmUgYmVpbmcgcGVyZm9ybWVkLCBDU0UgbWF5IGNhdXNlIHRoZSBGcm9tIG5vZGUKKyAgLy8vIHRvIGJlIGdpdmVuIG5ldyB1c2VzLiBUaGVzZSBuZXcgdXNlcyBvZiBGcm9tIGFyZSBsZWZ0IGluIHBsYWNlLCBhbmQKKyAgLy8vIG5vdCBhdXRvbWF0aWNhbGx5IHRyYW5zZmVycmVkIHRvIFRvLgorICAvLy8KKyAgdm9pZCBSZXBsYWNlQWxsVXNlc1dpdGgoU0RWYWx1ZSBGcm9tLCBTRFZhbHVlIE9wKTsKKyAgdm9pZCBSZXBsYWNlQWxsVXNlc1dpdGgoU0ROb2RlICpGcm9tLCBTRE5vZGUgKlRvKTsKKyAgdm9pZCBSZXBsYWNlQWxsVXNlc1dpdGgoU0ROb2RlICpGcm9tLCBjb25zdCBTRFZhbHVlICpUbyk7CisKKyAgLy8vIFJlcGxhY2UgYW55IHVzZXMgb2YgRnJvbSB3aXRoIFRvLCBsZWF2aW5nCisgIC8vLyB1c2VzIG9mIG90aGVyIHZhbHVlcyBwcm9kdWNlZCBieSBGcm9tLmdldE5vZGUoKSBhbG9uZS4KKyAgdm9pZCBSZXBsYWNlQWxsVXNlc09mVmFsdWVXaXRoKFNEVmFsdWUgRnJvbSwgU0RWYWx1ZSBUbyk7CisKKyAgLy8vIExpa2UgUmVwbGFjZUFsbFVzZXNPZlZhbHVlV2l0aCwgYnV0IGZvciBtdWx0aXBsZSB2YWx1ZXMgYXQgb25jZS4KKyAgLy8vIFRoaXMgY29ycmVjdGx5IGhhbmRsZXMgdGhlIGNhc2Ugd2hlcmUKKyAgLy8vIHRoZXJlIGlzIGFuIG92ZXJsYXAgYmV0d2VlbiB0aGUgRnJvbSB2YWx1ZXMgYW5kIHRoZSBUbyB2YWx1ZXMuCisgIHZvaWQgUmVwbGFjZUFsbFVzZXNPZlZhbHVlc1dpdGgoY29uc3QgU0RWYWx1ZSAqRnJvbSwgY29uc3QgU0RWYWx1ZSAqVG8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgTnVtKTsKKworICAvLy8gSWYgYW4gZXhpc3RpbmcgbG9hZCBoYXMgdXNlcyBvZiBpdHMgY2hhaW4sIGNyZWF0ZSBhIHRva2VuIGZhY3RvciBub2RlIHdpdGgKKyAgLy8vIHRoYXQgY2hhaW4gYW5kIHRoZSBuZXcgbWVtb3J5IG5vZGUncyBjaGFpbiBhbmQgdXBkYXRlIHVzZXJzIG9mIHRoZSBvbGQKKyAgLy8vIGNoYWluIHRvIHRoZSB0b2tlbiBmYWN0b3IuIFRoaXMgZW5zdXJlcyB0aGF0IHRoZSBuZXcgbWVtb3J5IG5vZGUgd2lsbCBoYXZlCisgIC8vLyB0aGUgc2FtZSByZWxhdGl2ZSBtZW1vcnkgZGVwZW5kZW5jeSBwb3NpdGlvbiBhcyB0aGUgb2xkIGxvYWQuIFJldHVybnMgdGhlCisgIC8vLyBuZXcgbWVyZ2VkIGxvYWQgY2hhaW4uCisgIFNEVmFsdWUgbWFrZUVxdWl2YWxlbnRNZW1vcnlPcmRlcmluZyhMb2FkU0ROb2RlICpPbGQsIFNEVmFsdWUgTmV3KTsKKworICAvLy8gVG9wb2xvZ2ljYWwtc29ydCB0aGUgQWxsTm9kZXMgbGlzdCBhbmQgYQorICAvLy8gYXNzaWduIGEgdW5pcXVlIG5vZGUgaWQgZm9yIGVhY2ggbm9kZSBpbiB0aGUgREFHIGJhc2VkIG9uIHRoZWlyCisgIC8vLyB0b3BvbG9naWNhbCBvcmRlci4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIG5vZGVzLgorICB1bnNpZ25lZCBBc3NpZ25Ub3BvbG9naWNhbE9yZGVyKCk7CisKKyAgLy8vIE1vdmUgbm9kZSBOIGluIHRoZSBBbGxOb2RlcyBsaXN0IHRvIGJlIGltbWVkaWF0ZWx5CisgIC8vLyBiZWZvcmUgdGhlIGdpdmVuIGl0ZXJhdG9yIFBvc2l0aW9uLiBUaGlzIG1heSBiZSB1c2VkIHRvIHVwZGF0ZSB0aGUKKyAgLy8vIHRvcG9sb2dpY2FsIG9yZGVyaW5nIHdoZW4gdGhlIGxpc3Qgb2Ygbm9kZXMgaXMgbW9kaWZpZWQuCisgIHZvaWQgUmVwb3NpdGlvbk5vZGUoYWxsbm9kZXNfaXRlcmF0b3IgUG9zaXRpb24sIFNETm9kZSAqTikgeworICAgIEFsbE5vZGVzLmluc2VydChQb3NpdGlvbiwgQWxsTm9kZXMucmVtb3ZlKE4pKTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIGFuIEFQRmxvYXQgc2VtYW50aWNzIHRhZyBhcHByb3ByaWF0ZSBmb3IgdGhlIGdpdmVuIHR5cGUuIElmIFZUIGlzCisgIC8vLyBhIHZlY3RvciB0eXBlLCB0aGUgZWxlbWVudCBzZW1hbnRpY3MgYXJlIHJldHVybmVkLgorICBzdGF0aWMgY29uc3QgZmx0U2VtYW50aWNzICZFVlRUb0FQRmxvYXRTZW1hbnRpY3MoRVZUIFZUKSB7CisgICAgc3dpdGNoIChWVC5nZXRTY2FsYXJUeXBlKCkuZ2V0U2ltcGxlVlQoKS5TaW1wbGVUeSkgeworICAgIGRlZmF1bHQ6IGxsdm1fdW5yZWFjaGFibGUoIlVua25vd24gRlAgZm9ybWF0Iik7CisgICAgY2FzZSBNVlQ6OmYxNjogICAgIHJldHVybiBBUEZsb2F0OjpJRUVFaGFsZigpOworICAgIGNhc2UgTVZUOjpmMzI6ICAgICByZXR1cm4gQVBGbG9hdDo6SUVFRXNpbmdsZSgpOworICAgIGNhc2UgTVZUOjpmNjQ6ICAgICByZXR1cm4gQVBGbG9hdDo6SUVFRWRvdWJsZSgpOworICAgIGNhc2UgTVZUOjpmODA6ICAgICByZXR1cm4gQVBGbG9hdDo6eDg3RG91YmxlRXh0ZW5kZWQoKTsKKyAgICBjYXNlIE1WVDo6ZjEyODogICAgcmV0dXJuIEFQRmxvYXQ6OklFRUVxdWFkKCk7CisgICAgY2FzZSBNVlQ6OnBwY2YxMjg6IHJldHVybiBBUEZsb2F0OjpQUENEb3VibGVEb3VibGUoKTsKKyAgICB9CisgIH0KKworICAvLy8gQWRkIGEgZGJnX3ZhbHVlIFNETm9kZS4gSWYgU0QgaXMgbm9uLW51bGwgdGhhdCBtZWFucyB0aGUKKyAgLy8vIHZhbHVlIGlzIHByb2R1Y2VkIGJ5IFNELgorICB2b2lkIEFkZERiZ1ZhbHVlKFNERGJnVmFsdWUgKkRCLCBTRE5vZGUgKlNELCBib29sIGlzUGFyYW1ldGVyKTsKKworICAvLy8gR2V0IHRoZSBkZWJ1ZyB2YWx1ZXMgd2hpY2ggcmVmZXJlbmNlIHRoZSBnaXZlbiBTRE5vZGUuCisgIEFycmF5UmVmPFNERGJnVmFsdWUqPiBHZXREYmdWYWx1ZXMoY29uc3QgU0ROb2RlKiBTRCkgeworICAgIHJldHVybiBEYmdJbmZvLT5nZXRTRERiZ1ZhbHVlcyhTRCk7CisgIH0KKworcHVibGljOgorICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlcmUgYXJlIGFueSBTRERiZ1ZhbHVlIG5vZGVzIGFzc29jaWF0ZWQKKyAgLy8vIHdpdGggdGhpcyBTZWxlY3Rpb25EQUcuCisgIGJvb2wgaGFzRGVidWdWYWx1ZXMoKSBjb25zdCB7IHJldHVybiAhRGJnSW5mby0+ZW1wdHkoKTsgfQorCisgIFNERGJnSW5mbzo6RGJnSXRlcmF0b3IgRGJnQmVnaW4oKSB7IHJldHVybiBEYmdJbmZvLT5EYmdCZWdpbigpOyB9CisgIFNERGJnSW5mbzo6RGJnSXRlcmF0b3IgRGJnRW5kKCkgICB7IHJldHVybiBEYmdJbmZvLT5EYmdFbmQoKTsgfQorCisgIFNERGJnSW5mbzo6RGJnSXRlcmF0b3IgQnl2YWxQYXJtRGJnQmVnaW4oKSB7CisgICAgcmV0dXJuIERiZ0luZm8tPkJ5dmFsUGFybURiZ0JlZ2luKCk7CisgIH0KKworICBTRERiZ0luZm86OkRiZ0l0ZXJhdG9yIEJ5dmFsUGFybURiZ0VuZCgpICAgeworICAgIHJldHVybiBEYmdJbmZvLT5CeXZhbFBhcm1EYmdFbmQoKTsKKyAgfQorCisgIC8vLyBUbyBiZSBpbnZva2VkIG9uIGFuIFNETm9kZSB0aGF0IGlzIHNsYXRlZCB0byBiZSBlcmFzZWQuIFRoaXMKKyAgLy8vIGZ1bmN0aW9uIG1pcnJvcnMgXGMgbGx2bTo6c2FsdmFnZURlYnVnSW5mby4KKyAgdm9pZCBzYWx2YWdlRGVidWdJbmZvKFNETm9kZSAmTik7CisKKyAgdm9pZCBkdW1wKCkgY29uc3Q7CisKKyAgLy8vIENyZWF0ZSBhIHN0YWNrIHRlbXBvcmFyeSwgc3VpdGFibGUgZm9yIGhvbGRpbmcgdGhlIHNwZWNpZmllZCB2YWx1ZSB0eXBlLgorICAvLy8gSWYgbWluQWxpZ24gaXMgc3BlY2lmaWVkLCB0aGUgc2xvdCBzaXplIHdpbGwgaGF2ZSBhdCBsZWFzdCB0aGF0IGFsaWdubWVudC4KKyAgU0RWYWx1ZSBDcmVhdGVTdGFja1RlbXBvcmFyeShFVlQgVlQsIHVuc2lnbmVkIG1pbkFsaWduID0gMSk7CisKKyAgLy8vIENyZWF0ZSBhIHN0YWNrIHRlbXBvcmFyeSBzdWl0YWJsZSBmb3IgaG9sZGluZyBlaXRoZXIgb2YgdGhlIHNwZWNpZmllZAorICAvLy8gdmFsdWUgdHlwZXMuCisgIFNEVmFsdWUgQ3JlYXRlU3RhY2tUZW1wb3JhcnkoRVZUIFZUMSwgRVZUIFZUMik7CisKKyAgU0RWYWx1ZSBGb2xkU3ltYm9sT2Zmc2V0KHVuc2lnbmVkIE9wY29kZSwgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgR2xvYmFsQWRkcmVzc1NETm9kZSAqR0EsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTRE5vZGUgKk4yKTsKKworICBTRFZhbHVlIEZvbGRDb25zdGFudEFyaXRobWV0aWModW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNETm9kZSAqQ3N0MSwgU0ROb2RlICpDc3QyKTsKKworICBTRFZhbHVlIEZvbGRDb25zdGFudEFyaXRobWV0aWModW5zaWduZWQgT3Bjb2RlLCBjb25zdCBTRExvYyAmREwsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENvbnN0YW50U0ROb2RlICpDc3QxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ29uc3RhbnRTRE5vZGUgKkNzdDIpOworCisgIFNEVmFsdWUgRm9sZENvbnN0YW50VmVjdG9yQXJpdGhtZXRpYyh1bnNpZ25lZCBPcGNvZGUsIGNvbnN0IFNETG9jICZETCwgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8U0RWYWx1ZT4gT3BzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU0ROb2RlRmxhZ3MgRmxhZ3MgPSBTRE5vZGVGbGFncygpKTsKKworICAvLy8gQ29uc3RhbnQgZm9sZCBhIHNldGNjIHRvIHRydWUgb3IgZmFsc2UuCisgIFNEVmFsdWUgRm9sZFNldENDKEVWVCBWVCwgU0RWYWx1ZSBOMSwgU0RWYWx1ZSBOMiwgSVNEOjpDb25kQ29kZSBDb25kLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBTRExvYyAmZGwpOworCisgIC8vLyBTZWUgaWYgdGhlIHNwZWNpZmllZCBvcGVyYW5kIGNhbiBiZSBzaW1wbGlmaWVkIHdpdGggdGhlIGtub3dsZWRnZSB0aGF0IG9ubHkKKyAgLy8vIHRoZSBiaXRzIHNwZWNpZmllZCBieSBNYXNrIGFyZSB1c2VkLiAgSWYgc28sIHJldHVybiB0aGUgc2ltcGxlciBvcGVyYW5kLAorICAvLy8gb3RoZXJ3aXNlIHJldHVybiBhIG51bGwgU0RWYWx1ZS4KKyAgLy8vCisgIC8vLyAoVGhpcyBleGlzdHMgYWxvbmdzaWRlIFNpbXBsaWZ5RGVtYW5kZWRCaXRzIGJlY2F1c2UgR2V0RGVtYW5kZWRCaXRzIGNhbgorICAvLy8gc2ltcGxpZnkgbm9kZXMgd2l0aCBtdWx0aXBsZSB1c2VzIG1vcmUgYWdncmVzc2l2ZWx5LikKKyAgU0RWYWx1ZSBHZXREZW1hbmRlZEJpdHMoU0RWYWx1ZSBWLCBjb25zdCBBUEludCAmTWFzayk7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzaWduIGJpdCBvZiBPcCBpcyBrbm93biB0byBiZSB6ZXJvLgorICAvLy8gV2UgdXNlIHRoaXMgcHJlZGljYXRlIHRvIHNpbXBsaWZ5IG9wZXJhdGlvbnMgZG93bnN0cmVhbS4KKyAgYm9vbCBTaWduQml0SXNaZXJvKFNEVmFsdWUgT3AsIHVuc2lnbmVkIERlcHRoID0gMCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmICdPcCAmIE1hc2snIGlzIGtub3duIHRvIGJlIHplcm8uICBXZQorICAvLy8gdXNlIHRoaXMgcHJlZGljYXRlIHRvIHNpbXBsaWZ5IG9wZXJhdGlvbnMgZG93bnN0cmVhbS4gIE9wIGFuZCBNYXNrIGFyZQorICAvLy8ga25vd24gdG8gYmUgdGhlIHNhbWUgdHlwZS4KKyAgYm9vbCBNYXNrZWRWYWx1ZUlzWmVybyhTRFZhbHVlIE9wLCBjb25zdCBBUEludCAmTWFzaywgdW5zaWduZWQgRGVwdGggPSAwKQorICAgIGNvbnN0OworCisgIC8vLyBEZXRlcm1pbmUgd2hpY2ggYml0cyBvZiBPcCBhcmUga25vd24gdG8gYmUgZWl0aGVyIHplcm8gb3Igb25lIGFuZCByZXR1cm4KKyAgLy8vIHRoZW0gaW4gS25vd24uIEZvciB2ZWN0b3JzLCB0aGUga25vd24gYml0cyBhcmUgdGhvc2UgdGhhdCBhcmUgc2hhcmVkIGJ5CisgIC8vLyBldmVyeSB2ZWN0b3IgZWxlbWVudC4KKyAgLy8vIFRhcmdldHMgY2FuIGltcGxlbWVudCB0aGUgY29tcHV0ZUtub3duQml0c0ZvclRhcmdldE5vZGUgbWV0aG9kIGluIHRoZQorICAvLy8gVGFyZ2V0TG93ZXJpbmcgY2xhc3MgdG8gYWxsb3cgdGFyZ2V0IG5vZGVzIHRvIGJlIHVuZGVyc3Rvb2QuCisgIHZvaWQgY29tcHV0ZUtub3duQml0cyhTRFZhbHVlIE9wLCBLbm93bkJpdHMgJktub3duLCB1bnNpZ25lZCBEZXB0aCA9IDApIGNvbnN0OworCisgIC8vLyBEZXRlcm1pbmUgd2hpY2ggYml0cyBvZiBPcCBhcmUga25vd24gdG8gYmUgZWl0aGVyIHplcm8gb3Igb25lIGFuZCByZXR1cm4KKyAgLy8vIHRoZW0gaW4gS25vd24uIFRoZSBEZW1hbmRlZEVsdHMgYXJndW1lbnQgYWxsb3dzIHVzIHRvIG9ubHkgY29sbGVjdCB0aGUKKyAgLy8vIGtub3duIGJpdHMgdGhhdCBhcmUgc2hhcmVkIGJ5IHRoZSByZXF1ZXN0ZWQgdmVjdG9yIGVsZW1lbnRzLgorICAvLy8gVGFyZ2V0cyBjYW4gaW1wbGVtZW50IHRoZSBjb21wdXRlS25vd25CaXRzRm9yVGFyZ2V0Tm9kZSBtZXRob2QgaW4gdGhlCisgIC8vLyBUYXJnZXRMb3dlcmluZyBjbGFzcyB0byBhbGxvdyB0YXJnZXQgbm9kZXMgdG8gYmUgdW5kZXJzdG9vZC4KKyAgdm9pZCBjb21wdXRlS25vd25CaXRzKFNEVmFsdWUgT3AsIEtub3duQml0cyAmS25vd24sIGNvbnN0IEFQSW50ICZEZW1hbmRlZEVsdHMsCisgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBEZXB0aCA9IDApIGNvbnN0OworCisgIC8vLyBVc2VkIHRvIHJlcHJlc2VudCB0aGUgcG9zc2libGUgb3ZlcmZsb3cgYmVoYXZpb3Igb2YgYW4gb3BlcmF0aW9uLgorICAvLy8gTmV2ZXI6IHRoZSBvcGVyYXRpb24gY2Fubm90IG92ZXJmbG93LgorICAvLy8gQWx3YXlzOiB0aGUgb3BlcmF0aW9uIHdpbGwgYWx3YXlzIG92ZXJmbG93LgorICAvLy8gU29tZXRpbWU6IHRoZSBvcGVyYXRpb24gbWF5IG9yIG1heSBub3Qgb3ZlcmZsb3cuCisgIGVudW0gT3ZlcmZsb3dLaW5kIHsKKyAgICBPRktfTmV2ZXIsCisgICAgT0ZLX1NvbWV0aW1lLAorICAgIE9GS19BbHdheXMsCisgIH07CisKKyAgLy8vIERldGVybWluZSBpZiB0aGUgcmVzdWx0IG9mIHRoZSBhZGRpdGlvbiBvZiAyIG5vZGUgY2FuIG92ZXJmbG93LgorICBPdmVyZmxvd0tpbmQgY29tcHV0ZU92ZXJmbG93S2luZChTRFZhbHVlIE4wLCBTRFZhbHVlIE4xKSBjb25zdDsKKworICAvLy8gVGVzdCBpZiB0aGUgZ2l2ZW4gdmFsdWUgaXMga25vd24gdG8gaGF2ZSBleGFjdGx5IG9uZSBiaXQgc2V0LiBUaGlzIGRpZmZlcnMKKyAgLy8vIGZyb20gY29tcHV0ZUtub3duQml0cyBpbiB0aGF0IGl0IGRvZXNuJ3QgbmVjZXNzYXJpbHkgZGV0ZXJtaW5lIHdoaWNoIGJpdAorICAvLy8gaXMgc2V0LgorICBib29sIGlzS25vd25Ub0JlQVBvd2VyT2ZUd28oU0RWYWx1ZSBWYWwpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdGhlIG51bWJlciBvZiB0aW1lcyB0aGUgc2lnbiBiaXQgb2YgdGhlIHJlZ2lzdGVyIGlzIHJlcGxpY2F0ZWQgaW50bworICAvLy8gdGhlIG90aGVyIGJpdHMuIFdlIGtub3cgdGhhdCBhdCBsZWFzdCAxIGJpdCBpcyBhbHdheXMgZXF1YWwgdG8gdGhlIHNpZ24KKyAgLy8vIGJpdCAoaXRzZWxmKSwgYnV0IG90aGVyIGNhc2VzIGNhbiBnaXZlIHVzIGluZm9ybWF0aW9uLiBGb3IgZXhhbXBsZSwKKyAgLy8vIGltbWVkaWF0ZWx5IGFmdGVyIGFuICJTUkEgWCwgMiIsIHdlIGtub3cgdGhhdCB0aGUgdG9wIDMgYml0cyBhcmUgYWxsIGVxdWFsCisgIC8vLyB0byBlYWNoIG90aGVyLCBzbyB3ZSByZXR1cm4gMy4gVGFyZ2V0cyBjYW4gaW1wbGVtZW50IHRoZQorICAvLy8gQ29tcHV0ZU51bVNpZ25CaXRzRm9yVGFyZ2V0IG1ldGhvZCBpbiB0aGUgVGFyZ2V0TG93ZXJpbmcgY2xhc3MgdG8gYWxsb3cKKyAgLy8vIHRhcmdldCBub2RlcyB0byBiZSB1bmRlcnN0b29kLgorICB1bnNpZ25lZCBDb21wdXRlTnVtU2lnbkJpdHMoU0RWYWx1ZSBPcCwgdW5zaWduZWQgRGVwdGggPSAwKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgdGltZXMgdGhlIHNpZ24gYml0IG9mIHRoZSByZWdpc3RlciBpcyByZXBsaWNhdGVkIGludG8KKyAgLy8vIHRoZSBvdGhlciBiaXRzLiBXZSBrbm93IHRoYXQgYXQgbGVhc3QgMSBiaXQgaXMgYWx3YXlzIGVxdWFsIHRvIHRoZSBzaWduCisgIC8vLyBiaXQgKGl0c2VsZiksIGJ1dCBvdGhlciBjYXNlcyBjYW4gZ2l2ZSB1cyBpbmZvcm1hdGlvbi4gRm9yIGV4YW1wbGUsCisgIC8vLyBpbW1lZGlhdGVseSBhZnRlciBhbiAiU1JBIFgsIDIiLCB3ZSBrbm93IHRoYXQgdGhlIHRvcCAzIGJpdHMgYXJlIGFsbCBlcXVhbAorICAvLy8gdG8gZWFjaCBvdGhlciwgc28gd2UgcmV0dXJuIDMuIFRoZSBEZW1hbmRlZEVsdHMgYXJndW1lbnQgYWxsb3dzCisgIC8vLyB1cyB0byBvbmx5IGNvbGxlY3QgdGhlIG1pbmltdW0gc2lnbiBiaXRzIG9mIHRoZSByZXF1ZXN0ZWQgdmVjdG9yIGVsZW1lbnRzLgorICAvLy8gVGFyZ2V0cyBjYW4gaW1wbGVtZW50IHRoZSBDb21wdXRlTnVtU2lnbkJpdHNGb3JUYXJnZXQgbWV0aG9kIGluIHRoZQorICAvLy8gVGFyZ2V0TG93ZXJpbmcgY2xhc3MgdG8gYWxsb3cgdGFyZ2V0IG5vZGVzIHRvIGJlIHVuZGVyc3Rvb2QuCisgIHVuc2lnbmVkIENvbXB1dGVOdW1TaWduQml0cyhTRFZhbHVlIE9wLCBjb25zdCBBUEludCAmRGVtYW5kZWRFbHRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgRGVwdGggPSAwKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCBvcGVyYW5kIGlzIGFuIElTRDo6QUREIHdpdGggYSBDb25zdGFudFNETm9kZQorICAvLy8gb24gdGhlIHJpZ2h0LWhhbmQgc2lkZSwgb3IgaWYgaXQgaXMgYW4gSVNEOjpPUiB3aXRoIGEgQ29uc3RhbnRTRE5vZGUgdGhhdAorICAvLy8gaXMgZ3VhcmFudGVlZCB0byBoYXZlIHRoZSBzYW1lIHNlbWFudGljcyBhcyBhbiBBREQuIFRoaXMgaGFuZGxlcyB0aGUKKyAgLy8vIGVxdWl2YWxlbmNlOgorICAvLy8gICAgIFh8Q3N0ID09IFgrQ3N0IGlmZiBYJkNzdCA9IDAuCisgIGJvb2wgaXNCYXNlV2l0aENvbnN0YW50T2Zmc2V0KFNEVmFsdWUgT3ApIGNvbnN0OworCisgIC8vLyBUZXN0IHdoZXRoZXIgdGhlIGdpdmVuIFNEVmFsdWUgaXMga25vd24gdG8gbmV2ZXIgYmUgTmFOLgorICBib29sIGlzS25vd25OZXZlck5hTihTRFZhbHVlIE9wKSBjb25zdDsKKworICAvLy8gVGVzdCB3aGV0aGVyIHRoZSBnaXZlbiBTRFZhbHVlIGlzIGtub3duIHRvIG5ldmVyIGJlIHBvc2l0aXZlIG9yIG5lZ2F0aXZlCisgIC8vLyB6ZXJvLgorICBib29sIGlzS25vd25OZXZlclplcm8oU0RWYWx1ZSBPcCkgY29uc3Q7CisKKyAgLy8vIFRlc3Qgd2hldGhlciB0d28gU0RWYWx1ZXMgYXJlIGtub3duIHRvIGNvbXBhcmUgZXF1YWwuIFRoaXMKKyAgLy8vIGlzIHRydWUgaWYgdGhleSBhcmUgdGhlIHNhbWUgdmFsdWUsIG9yIGlmIG9uZSBpcyBuZWdhdGl2ZSB6ZXJvIGFuZCB0aGUKKyAgLy8vIG90aGVyIHBvc2l0aXZlIHplcm8uCisgIGJvb2wgaXNFcXVhbFRvKFNEVmFsdWUgQSwgU0RWYWx1ZSBCKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgQSBhbmQgQiBoYXZlIG5vIGNvbW1vbiBiaXRzIHNldC4gQXMgYW4gZXhhbXBsZSwgdGhpcyBjYW4KKyAgLy8vIGFsbG93IGFuICdhZGQnIHRvIGJlIHRyYW5zZm9ybWVkIGludG8gYW4gJ29yJy4KKyAgYm9vbCBoYXZlTm9Db21tb25CaXRzU2V0KFNEVmFsdWUgQSwgU0RWYWx1ZSBCKSBjb25zdDsKKworICAvLy8gVXRpbGl0eSBmdW5jdGlvbiB1c2VkIGJ5IGxlZ2FsaXplIGFuZCBsb3dlcmluZyB0bworICAvLy8gInVucm9sbCIgYSB2ZWN0b3Igb3BlcmF0aW9uIGJ5IHNwbGl0dGluZyBvdXQgdGhlIHNjYWxhcnMgYW5kIG9wZXJhdGluZworICAvLy8gb24gZWFjaCBlbGVtZW50IGluZGl2aWR1YWxseS4gIElmIHRoZSBSZXNORSBpcyAwLCBmdWxseSB1bnJvbGwgdGhlIHZlY3RvcgorICAvLy8gb3AuIElmIFJlc05FIGlzIGxlc3MgdGhhbiB0aGUgd2lkdGggb2YgdGhlIHZlY3RvciBvcCwgdW5yb2xsIHVwIHRvIFJlc05FLgorICAvLy8gSWYgdGhlICBSZXNORSBpcyBncmVhdGVyIHRoYW4gdGhlIHdpZHRoIG9mIHRoZSB2ZWN0b3Igb3AsIHVucm9sbCB0aGUKKyAgLy8vIHZlY3RvciBvcCBhbmQgZmlsbCB0aGUgZW5kIG9mIHRoZSByZXN1bHRpbmcgdmVjdG9yIHdpdGggVU5ERUZTLgorICBTRFZhbHVlIFVucm9sbFZlY3Rvck9wKFNETm9kZSAqTiwgdW5zaWduZWQgUmVzTkUgPSAwKTsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgbG9hZHMgYXJlIG5leHQgdG8gZWFjaCBvdGhlciBhbmQgY2FuIGJlCisgIC8vLyBtZXJnZWQuIENoZWNrIHRoYXQgYm90aCBhcmUgbm9udm9sYXRpbGUgYW5kIGlmIExEIGlzIGxvYWRpbmcKKyAgLy8vICdCeXRlcycgYnl0ZXMgZnJvbSBhIGxvY2F0aW9uIHRoYXQgaXMgJ0Rpc3QnIHVuaXRzIGF3YXkgZnJvbSB0aGUKKyAgLy8vIGxvY2F0aW9uIHRoYXQgdGhlICdCYXNlJyBsb2FkIGlzIGxvYWRpbmcgZnJvbS4KKyAgYm9vbCBhcmVOb25Wb2xhdGlsZUNvbnNlY3V0aXZlTG9hZHMoTG9hZFNETm9kZSAqTEQsIExvYWRTRE5vZGUgKkJhc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIEJ5dGVzLCBpbnQgRGlzdCkgY29uc3Q7CisKKyAgLy8vIEluZmVyIGFsaWdubWVudCBvZiBhIGxvYWQgLyBzdG9yZSBhZGRyZXNzLiBSZXR1cm4gMCBpZgorICAvLy8gaXQgY2Fubm90IGJlIGluZmVycmVkLgorICB1bnNpZ25lZCBJbmZlclB0ckFsaWdubWVudChTRFZhbHVlIFB0cikgY29uc3Q7CisKKyAgLy8vIENvbXB1dGUgdGhlIFZUcyBuZWVkZWQgZm9yIHRoZSBsb3cvaGkgcGFydHMgb2YgYSB0eXBlCisgIC8vLyB3aGljaCBpcyBzcGxpdCAob3IgZXhwYW5kZWQpIGludG8gdHdvIG5vdCBuZWNlc3NhcmlseSBpZGVudGljYWwgcGllY2VzLgorICBzdGQ6OnBhaXI8RVZULCBFVlQ+IEdldFNwbGl0RGVzdFZUcyhjb25zdCBFVlQgJlZUKSBjb25zdDsKKworICAvLy8gU3BsaXQgdGhlIHZlY3RvciB3aXRoIEVYVFJBQ1RfU1VCVkVDVE9SIHVzaW5nIHRoZSBwcm92aWRlcworICAvLy8gVlRzIGFuZCByZXR1cm4gdGhlIGxvdy9oaWdoIHBhcnQuCisgIHN0ZDo6cGFpcjxTRFZhbHVlLCBTRFZhbHVlPiBTcGxpdFZlY3Rvcihjb25zdCBTRFZhbHVlICZOLCBjb25zdCBTRExvYyAmREwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBFVlQgJkxvVlQsIGNvbnN0IEVWVCAmSGlWVCk7CisKKyAgLy8vIFNwbGl0IHRoZSB2ZWN0b3Igd2l0aCBFWFRSQUNUX1NVQlZFQ1RPUiBhbmQgcmV0dXJuIHRoZSBsb3cvaGlnaCBwYXJ0LgorICBzdGQ6OnBhaXI8U0RWYWx1ZSwgU0RWYWx1ZT4gU3BsaXRWZWN0b3IoY29uc3QgU0RWYWx1ZSAmTiwgY29uc3QgU0RMb2MgJkRMKSB7CisgICAgRVZUIExvVlQsIEhpVlQ7CisgICAgc3RkOjp0aWUoTG9WVCwgSGlWVCkgPSBHZXRTcGxpdERlc3RWVHMoTi5nZXRWYWx1ZVR5cGUoKSk7CisgICAgcmV0dXJuIFNwbGl0VmVjdG9yKE4sIERMLCBMb1ZULCBIaVZUKTsKKyAgfQorCisgIC8vLyBTcGxpdCB0aGUgbm9kZSdzIG9wZXJhbmQgd2l0aCBFWFRSQUNUX1NVQlZFQ1RPUiBhbmQKKyAgLy8vIHJldHVybiB0aGUgbG93L2hpZ2ggcGFydC4KKyAgc3RkOjpwYWlyPFNEVmFsdWUsIFNEVmFsdWU+IFNwbGl0VmVjdG9yT3BlcmFuZChjb25zdCBTRE5vZGUgKk4sIHVuc2lnbmVkIE9wTm8pCisgIHsKKyAgICByZXR1cm4gU3BsaXRWZWN0b3IoTi0+Z2V0T3BlcmFuZChPcE5vKSwgU0RMb2MoTikpOworICB9CisKKyAgLy8vIEFwcGVuZCB0aGUgZXh0cmFjdGVkIGVsZW1lbnRzIGZyb20gU3RhcnQgdG8gQ291bnQgb3V0IG9mIHRoZSB2ZWN0b3IgT3AKKyAgLy8vIGluIEFyZ3MuIElmIENvdW50IGlzIDAsIGFsbCBvZiB0aGUgZWxlbWVudHMgd2lsbCBiZSBleHRyYWN0ZWQuCisgIHZvaWQgRXh0cmFjdFZlY3RvckVsZW1lbnRzKFNEVmFsdWUgT3AsIFNtYWxsVmVjdG9ySW1wbDxTRFZhbHVlPiAmQXJncywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgU3RhcnQgPSAwLCB1bnNpZ25lZCBDb3VudCA9IDApOworCisgIC8vLyBDb21wdXRlIHRoZSBkZWZhdWx0IGFsaWdubWVudCB2YWx1ZSBmb3IgdGhlIGdpdmVuIHR5cGUuCisgIHVuc2lnbmVkIGdldEVWVEFsaWdubWVudChFVlQgTWVtb3J5VlQpIGNvbnN0OworCisgIC8vLyBUZXN0IHdoZXRoZXIgdGhlIGdpdmVuIHZhbHVlIGlzIGEgY29uc3RhbnQgaW50IG9yIHNpbWlsYXIgbm9kZS4KKyAgU0ROb2RlICppc0NvbnN0YW50SW50QnVpbGRWZWN0b3JPckNvbnN0YW50SW50KFNEVmFsdWUgTik7CisKKyAgLy8vIFRlc3Qgd2hldGhlciB0aGUgZ2l2ZW4gdmFsdWUgaXMgYSBjb25zdGFudCBGUCBvciBzaW1pbGFyIG5vZGUuCisgIFNETm9kZSAqaXNDb25zdGFudEZQQnVpbGRWZWN0b3JPckNvbnN0YW50RlAoU0RWYWx1ZSBOKTsKKworICAvLy8gXHJldHVybnMgdHJ1ZSBpZiBccCBOIGlzIGFueSBraW5kIG9mIGNvbnN0YW50IG9yIGJ1aWxkX3ZlY3RvciBvZgorICAvLy8gY29uc3RhbnRzLCBpbnQgb3IgZmxvYXQuIElmIGEgdmVjdG9yLCBpdCBtYXkgbm90IG5lY2Vzc2FyaWx5IGJlIGEgc3BsYXQuCisgIGlubGluZSBib29sIGlzQ29uc3RhbnRWYWx1ZU9mQW55VHlwZShTRFZhbHVlIE4pIHsKKyAgICByZXR1cm4gaXNDb25zdGFudEludEJ1aWxkVmVjdG9yT3JDb25zdGFudEludChOKSB8fAorICAgICAgICAgICBpc0NvbnN0YW50RlBCdWlsZFZlY3Rvck9yQ29uc3RhbnRGUChOKTsKKyAgfQorCitwcml2YXRlOgorICB2b2lkIEluc2VydE5vZGUoU0ROb2RlICpOKTsKKyAgYm9vbCBSZW1vdmVOb2RlRnJvbUNTRU1hcHMoU0ROb2RlICpOKTsKKyAgdm9pZCBBZGRNb2RpZmllZE5vZGVUb0NTRU1hcHMoU0ROb2RlICpOKTsKKyAgU0ROb2RlICpGaW5kTW9kaWZpZWROb2RlU2xvdChTRE5vZGUgKk4sIFNEVmFsdWUgT3AsIHZvaWQgKiZJbnNlcnRQb3MpOworICBTRE5vZGUgKkZpbmRNb2RpZmllZE5vZGVTbG90KFNETm9kZSAqTiwgU0RWYWx1ZSBPcDEsIFNEVmFsdWUgT3AyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKiZJbnNlcnRQb3MpOworICBTRE5vZGUgKkZpbmRNb2RpZmllZE5vZGVTbG90KFNETm9kZSAqTiwgQXJyYXlSZWY8U0RWYWx1ZT4gT3BzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKiZJbnNlcnRQb3MpOworICBTRE5vZGUgKlVwZGF0ZVNETG9jT25NZXJnZVNETm9kZShTRE5vZGUgKk4sIGNvbnN0IFNETG9jICZsb2MpOworCisgIHZvaWQgRGVsZXRlTm9kZU5vdEluQ1NFTWFwcyhTRE5vZGUgKk4pOworICB2b2lkIERlYWxsb2NhdGVOb2RlKFNETm9kZSAqTik7CisKKyAgdm9pZCBhbGxub2Rlc19jbGVhcigpOworCisgIC8vLyBMb29rIHVwIHRoZSBub2RlIHNwZWNpZmllZCBieSBJRCBpbiBDU0VNYXAuICBJZiBpdCBleGlzdHMsIHJldHVybiBpdC4gIElmCisgIC8vLyBub3QsIHJldHVybiB0aGUgaW5zZXJ0aW9uIHRva2VuIHRoYXQgd2lsbCBtYWtlIGluc2VydGlvbiBmYXN0ZXIuICBUaGlzCisgIC8vLyBvdmVybG9hZCBpcyBmb3Igbm9kZXMgb3RoZXIgdGhhbiBDb25zdGFudCBvciBDb25zdGFudEZQLCB1c2UgdGhlIG90aGVyIG9uZQorICAvLy8gZm9yIHRob3NlLgorICBTRE5vZGUgKkZpbmROb2RlT3JJbnNlcnRQb3MoY29uc3QgRm9sZGluZ1NldE5vZGVJRCAmSUQsIHZvaWQgKiZJbnNlcnRQb3MpOworCisgIC8vLyBMb29rIHVwIHRoZSBub2RlIHNwZWNpZmllZCBieSBJRCBpbiBDU0VNYXAuICBJZiBpdCBleGlzdHMsIHJldHVybiBpdC4gIElmCisgIC8vLyBub3QsIHJldHVybiB0aGUgaW5zZXJ0aW9uIHRva2VuIHRoYXQgd2lsbCBtYWtlIGluc2VydGlvbiBmYXN0ZXIuICBQZXJmb3JtcworICAvLy8gYWRkaXRpb25hbCBwcm9jZXNzaW5nIGZvciBjb25zdGFudCBub2Rlcy4KKyAgU0ROb2RlICpGaW5kTm9kZU9ySW5zZXJ0UG9zKGNvbnN0IEZvbGRpbmdTZXROb2RlSUQgJklELCBjb25zdCBTRExvYyAmREwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkIComSW5zZXJ0UG9zKTsKKworICAvLy8gTGlzdCBvZiBub24tc2luZ2xlIHZhbHVlIHR5cGVzLgorICBGb2xkaW5nU2V0PFNEVlRMaXN0Tm9kZT4gVlRMaXN0TWFwOworCisgIC8vLyBNYXBzIHRvIGF1dG8tQ1NFIG9wZXJhdGlvbnMuCisgIHN0ZDo6dmVjdG9yPENvbmRDb2RlU0ROb2RlKj4gQ29uZENvZGVOb2RlczsKKworICBzdGQ6OnZlY3RvcjxTRE5vZGUqPiBWYWx1ZVR5cGVOb2RlczsKKyAgc3RkOjptYXA8RVZULCBTRE5vZGUqLCBFVlQ6OmNvbXBhcmVSYXdCaXRzPiBFeHRlbmRlZFZhbHVlVHlwZU5vZGVzOworICBTdHJpbmdNYXA8U0ROb2RlKj4gRXh0ZXJuYWxTeW1ib2xzOworCisgIHN0ZDo6bWFwPHN0ZDo6cGFpcjxzdGQ6OnN0cmluZywgdW5zaWduZWQgY2hhcj4sU0ROb2RlKj4gVGFyZ2V0RXh0ZXJuYWxTeW1ib2xzOworICBEZW5zZU1hcDxNQ1N5bWJvbCAqLCBTRE5vZGUgKj4gTUNTeW1ib2xzOworfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IEdyYXBoVHJhaXRzPFNlbGVjdGlvbkRBRyo+IDogcHVibGljIEdyYXBoVHJhaXRzPFNETm9kZSo+IHsKKyAgdXNpbmcgbm9kZXNfaXRlcmF0b3IgPSBwb2ludGVyX2l0ZXJhdG9yPFNlbGVjdGlvbkRBRzo6YWxsbm9kZXNfaXRlcmF0b3I+OworCisgIHN0YXRpYyBub2Rlc19pdGVyYXRvciBub2Rlc19iZWdpbihTZWxlY3Rpb25EQUcgKkcpIHsKKyAgICByZXR1cm4gbm9kZXNfaXRlcmF0b3IoRy0+YWxsbm9kZXNfYmVnaW4oKSk7CisgIH0KKworICBzdGF0aWMgbm9kZXNfaXRlcmF0b3Igbm9kZXNfZW5kKFNlbGVjdGlvbkRBRyAqRykgeworICAgIHJldHVybiBub2Rlc19pdGVyYXRvcihHLT5hbGxub2Rlc19lbmQoKSk7CisgIH0KK307CisKK3RlbXBsYXRlIDxjbGFzcyBUYXJnZXRNZW1TRE5vZGU+CitTRFZhbHVlIFNlbGVjdGlvbkRBRzo6Z2V0VGFyZ2V0TWVtU0ROb2RlKFNEVlRMaXN0IFZUcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8U0RWYWx1ZT4gT3BzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTRExvYyAmZGwsIEVWVCBNZW1WVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQgKk1NTykgeworICAvLy8gQ29tcG9zZSBub2RlIElEIGFuZCB0cnkgdG8gZmluZCBhbiBleGlzdGluZyBub2RlLgorICBGb2xkaW5nU2V0Tm9kZUlEIElEOworICB1bnNpZ25lZCBPcGNvZGUgPQorICAgIFRhcmdldE1lbVNETm9kZShkbC5nZXRJUk9yZGVyKCksIERlYnVnTG9jKCksIFZUcywgTWVtVlQsIE1NTykuZ2V0T3Bjb2RlKCk7CisgIElELkFkZEludGVnZXIoT3Bjb2RlKTsKKyAgSUQuQWRkUG9pbnRlcihWVHMuVlRzKTsKKyAgZm9yIChhdXRvJiBPcCA6IE9wcykgeworICAgIElELkFkZFBvaW50ZXIoT3AuZ2V0Tm9kZSgpKTsKKyAgICBJRC5BZGRJbnRlZ2VyKE9wLmdldFJlc05vKCkpOworICB9CisgIElELkFkZEludGVnZXIoTWVtVlQuZ2V0UmF3Qml0cygpKTsKKyAgSUQuQWRkSW50ZWdlcihNTU8tPmdldFBvaW50ZXJJbmZvKCkuZ2V0QWRkclNwYWNlKCkpOworICBJRC5BZGRJbnRlZ2VyKGdldFN5bnRoZXRpY05vZGVTdWJjbGFzc0RhdGE8VGFyZ2V0TWVtU0ROb2RlPigKKyAgICBkbC5nZXRJUk9yZGVyKCksIFZUcywgTWVtVlQsIE1NTykpOworCisgIHZvaWQgKklQID0gbnVsbHB0cjsKKyAgaWYgKFNETm9kZSAqRSA9IEZpbmROb2RlT3JJbnNlcnRQb3MoSUQsIGRsLCBJUCkpIHsKKyAgICBjYXN0PFRhcmdldE1lbVNETm9kZT4oRSktPnJlZmluZUFsaWdubWVudChNTU8pOworICAgIHJldHVybiBTRFZhbHVlKEUsIDApOworICB9CisKKyAgLy8vIEV4aXN0aW5nIG5vZGUgd2FzIG5vdCBmb3VuZC4gQ3JlYXRlIGEgbmV3IG9uZS4KKyAgYXV0byAqTiA9IG5ld1NETm9kZTxUYXJnZXRNZW1TRE5vZGU+KGRsLmdldElST3JkZXIoKSwgZGwuZ2V0RGVidWdMb2MoKSwgVlRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVtVlQsIE1NTyk7CisgIGNyZWF0ZU9wZXJhbmRzKE4sIE9wcyk7CisgIENTRU1hcC5JbnNlcnROb2RlKE4sIElQKTsKKyAgSW5zZXJ0Tm9kZShOKTsKKyAgcmV0dXJuIFNEVmFsdWUoTiwgMCk7Cit9CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fU0VMRUNUSU9OREFHX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TZWxlY3Rpb25EQUdBZGRyZXNzQW5hbHlzaXMuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TZWxlY3Rpb25EQUdBZGRyZXNzQW5hbHlzaXMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ODA2MDY0Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBR0FkZHJlc3NBbmFseXNpcy5oCkBAIC0wLDAgKzEsNjQgQEAKKy8vPT09LSBTZWxlY3Rpb25EQUdBZGRyZXNzQW5hbHlzaXMuaCAtIERBRyBBZGRyZXNzIEFuYWx5c2lzIC0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1NFTEVDVElPTkRBR0FERFJFU1NBTkFMWVNJU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9TRUxFQ1RJT05EQUdBRERSRVNTQU5BTFlTSVNfSAorCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBR05vZGVzLmgiCisjaW5jbHVkZSA8Y3N0ZGludD4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBTZWxlY3Rpb25EQUc7CisKKy8vLyBIZWxwZXIgc3RydWN0IHRvIHBhcnNlIGFuZCBzdG9yZSBhIG1lbW9yeSBhZGRyZXNzIGFzIGJhc2UgKyBpbmRleCArIG9mZnNldC4KKy8vLyBXZSBpZ25vcmUgc2lnbiBleHRlbnNpb25zIHdoZW4gaXQgaXMgc2FmZSB0byBkbyBzby4KKy8vLyBUaGUgZm9sbG93aW5nIHR3byBleHByZXNzaW9ucyBhcmUgbm90IGVxdWl2YWxlbnQuIFRvIGRpZmZlcmVudGlhdGUgd2UgbmVlZAorLy8vIHRvIHN0b3JlIHdoZXRoZXIgdGhlcmUgd2FzIGEgc2lnbiBleHRlbnNpb24gaW52b2x2ZWQgaW4gdGhlIGluZGV4CisvLy8gY29tcHV0YXRpb24uCisvLy8gIChsb2FkIChpNjQgYWRkIChpNjQgY29weWZyb21yZWcgJWMpCisvLy8gICAgICAgICAgICAgICAgIChpNjQgc2lnbmV4dGVuZCAoYWRkIChpOCBsb2FkICVpbmRleCkKKy8vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGk4IDEpKSkpCisvLy8gdnMKKy8vLworLy8vIChsb2FkIChpNjQgYWRkIChpNjQgY29weWZyb21yZWcgJWMpCisvLy8gICAgICAgICAgICAgICAgKGk2NCBzaWduZXh0ZW5kIChpMzIgYWRkIChpMzIgc2lnbmV4dGVuZCAoaTggbG9hZCAlaW5kZXgpKQorLy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaTMyIDEpKSkpKQorY2xhc3MgQmFzZUluZGV4T2Zmc2V0IHsKK3ByaXZhdGU6CisgIFNEVmFsdWUgQmFzZTsKKyAgU0RWYWx1ZSBJbmRleDsKKyAgaW50NjRfdCBPZmZzZXQgPSAwOworICBib29sIElzSW5kZXhTaWduRXh0ID0gZmFsc2U7CisKK3B1YmxpYzoKKyAgQmFzZUluZGV4T2Zmc2V0KCkgPSBkZWZhdWx0OworICBCYXNlSW5kZXhPZmZzZXQoU0RWYWx1ZSBCYXNlLCBTRFZhbHVlIEluZGV4LCBpbnQ2NF90IE9mZnNldCwKKyAgICAgICAgICAgICAgICAgIGJvb2wgSXNJbmRleFNpZ25FeHQpCisgICAgICA6IEJhc2UoQmFzZSksIEluZGV4KEluZGV4KSwgT2Zmc2V0KE9mZnNldCksCisgICAgICAgIElzSW5kZXhTaWduRXh0KElzSW5kZXhTaWduRXh0KSB7fQorCisgIFNEVmFsdWUgZ2V0QmFzZSgpIHsgcmV0dXJuIEJhc2U7IH0KKyAgU0RWYWx1ZSBnZXRJbmRleCgpIHsgcmV0dXJuIEluZGV4OyB9CisKKyAgYm9vbCBlcXVhbEJhc2VJbmRleChCYXNlSW5kZXhPZmZzZXQgJk90aGVyLCBjb25zdCBTZWxlY3Rpb25EQUcgJkRBRykgeworICAgIGludDY0X3QgT2ZmOworICAgIHJldHVybiBlcXVhbEJhc2VJbmRleChPdGhlciwgREFHLCBPZmYpOworICB9CisKKyAgYm9vbCBlcXVhbEJhc2VJbmRleChCYXNlSW5kZXhPZmZzZXQgJk90aGVyLCBjb25zdCBTZWxlY3Rpb25EQUcgJkRBRywKKyAgICAgICAgICAgICAgICAgICAgICBpbnQ2NF90ICZPZmYpOworCisgIC8vLyBQYXJzZXMgdHJlZSBpbiBQdHIgZm9yIGJhc2UsIGluZGV4LCBvZmZzZXQgYWRkcmVzc2VzLgorICBzdGF0aWMgQmFzZUluZGV4T2Zmc2V0IG1hdGNoKExTQmFzZVNETm9kZSAqTiwgY29uc3QgU2VsZWN0aW9uREFHICZEQUcpOworfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9TRUxFQ1RJT05EQUdBRERSRVNTQU5BTFlTSVNfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBR0lTZWwuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TZWxlY3Rpb25EQUdJU2VsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTU2ZWFmYwotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TZWxlY3Rpb25EQUdJU2VsLmgKQEAgLTAsMCArMSwzNDggQEAKKy8vPT09LS0gbGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBR0lTZWwuaCAtIENvbW1vbiBCYXNlIENsYXNzLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGltcGxlbWVudHMgdGhlIFNlbGVjdGlvbkRBR0lTZWwgY2xhc3MsIHdoaWNoIGlzIHVzZWQgYXMgdGhlIGNvbW1vbgorLy8gYmFzZSBjbGFzcyBmb3IgU2VsZWN0aW9uREFHLWJhc2VkIGluc3RydWN0aW9uIHNlbGVjdG9ycy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9TRUxFQ1RJT05EQUdJU0VMX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1NFTEVDVElPTkRBR0lTRUxfSAorCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvblBhc3MuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2VsZWN0aW9uREFHLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1RhcmdldFN1YnRhcmdldEluZm8uaCIKKyNpbmNsdWRlICJsbHZtL0lSL0Jhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL1Bhc3MuaCIKKyNpbmNsdWRlIDxtZW1vcnk+CisKK25hbWVzcGFjZSBsbHZtIHsKKyAgY2xhc3MgRmFzdElTZWw7CisgIGNsYXNzIFNlbGVjdGlvbkRBR0J1aWxkZXI7CisgIGNsYXNzIFNEVmFsdWU7CisgIGNsYXNzIE1hY2hpbmVSZWdpc3RlckluZm87CisgIGNsYXNzIE1hY2hpbmVCYXNpY0Jsb2NrOworICBjbGFzcyBNYWNoaW5lRnVuY3Rpb247CisgIGNsYXNzIE1hY2hpbmVJbnN0cjsKKyAgY2xhc3MgT3B0aW1pemF0aW9uUmVtYXJrRW1pdHRlcjsKKyAgY2xhc3MgVGFyZ2V0TG93ZXJpbmc7CisgIGNsYXNzIFRhcmdldExpYnJhcnlJbmZvOworICBjbGFzcyBGdW5jdGlvbkxvd2VyaW5nSW5mbzsKKyAgY2xhc3MgU2NoZWR1bGVIYXphcmRSZWNvZ25pemVyOworICBjbGFzcyBHQ0Z1bmN0aW9uSW5mbzsKKyAgY2xhc3MgU2NoZWR1bGVEQUdTRE5vZGVzOworICBjbGFzcyBMb2FkSW5zdDsKKworLy8vIFNlbGVjdGlvbkRBR0lTZWwgLSBUaGlzIGlzIHRoZSBjb21tb24gYmFzZSBjbGFzcyB1c2VkIGZvciBTZWxlY3Rpb25EQUctYmFzZWQKKy8vLyBwYXR0ZXJuLW1hdGNoaW5nIGluc3RydWN0aW9uIHNlbGVjdG9ycy4KK2NsYXNzIFNlbGVjdGlvbkRBR0lTZWwgOiBwdWJsaWMgTWFjaGluZUZ1bmN0aW9uUGFzcyB7CitwdWJsaWM6CisgIFRhcmdldE1hY2hpbmUgJlRNOworICBjb25zdCBUYXJnZXRMaWJyYXJ5SW5mbyAqTGliSW5mbzsKKyAgRnVuY3Rpb25Mb3dlcmluZ0luZm8gKkZ1bmNJbmZvOworICBNYWNoaW5lRnVuY3Rpb24gKk1GOworICBNYWNoaW5lUmVnaXN0ZXJJbmZvICpSZWdJbmZvOworICBTZWxlY3Rpb25EQUcgKkN1ckRBRzsKKyAgU2VsZWN0aW9uREFHQnVpbGRlciAqU0RCOworICBBbGlhc0FuYWx5c2lzICpBQTsKKyAgR0NGdW5jdGlvbkluZm8gKkdGSTsKKyAgQ29kZUdlbk9wdDo6TGV2ZWwgT3B0TGV2ZWw7CisgIGNvbnN0IFRhcmdldEluc3RySW5mbyAqVElJOworICBjb25zdCBUYXJnZXRMb3dlcmluZyAqVExJOworICBib29sIEZhc3RJU2VsRmFpbGVkOworICBTbWFsbFB0clNldDxjb25zdCBJbnN0cnVjdGlvbiAqLCA0PiBFbGlkZWRBcmdDb3B5SW5zdHJzOworCisgIC8vLyBDdXJyZW50IG9wdGltaXphdGlvbiByZW1hcmsgZW1pdHRlci4KKyAgLy8vIFVzZWQgdG8gcmVwb3J0IHRoaW5ncyBsaWtlIGNvbWJpbmVzIGFuZCBGYXN0SVNlbCBmYWlsdXJlcy4KKyAgc3RkOjp1bmlxdWVfcHRyPE9wdGltaXphdGlvblJlbWFya0VtaXR0ZXI+IE9SRTsKKworICBzdGF0aWMgY2hhciBJRDsKKworICBleHBsaWNpdCBTZWxlY3Rpb25EQUdJU2VsKFRhcmdldE1hY2hpbmUgJnRtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvZGVHZW5PcHQ6OkxldmVsIE9MID0gQ29kZUdlbk9wdDo6RGVmYXVsdCk7CisgIH5TZWxlY3Rpb25EQUdJU2VsKCkgb3ZlcnJpZGU7CisKKyAgY29uc3QgVGFyZ2V0TG93ZXJpbmcgKmdldFRhcmdldExvd2VyaW5nKCkgY29uc3QgeyByZXR1cm4gVExJOyB9CisKKyAgdm9pZCBnZXRBbmFseXNpc1VzYWdlKEFuYWx5c2lzVXNhZ2UgJkFVKSBjb25zdCBvdmVycmlkZTsKKworICBib29sIHJ1bk9uTWFjaGluZUZ1bmN0aW9uKE1hY2hpbmVGdW5jdGlvbiAmTUYpIG92ZXJyaWRlOworCisgIHZpcnR1YWwgdm9pZCBFbWl0RnVuY3Rpb25FbnRyeUNvZGUoKSB7fQorCisgIC8vLyBQcmVwcm9jZXNzSVNlbERBRyAtIFRoaXMgaG9vayBhbGxvd3MgdGFyZ2V0cyB0byBoYWNrIG9uIHRoZSBncmFwaCBiZWZvcmUKKyAgLy8vIGluc3RydWN0aW9uIHNlbGVjdGlvbiBzdGFydHMuCisgIHZpcnR1YWwgdm9pZCBQcmVwcm9jZXNzSVNlbERBRygpIHt9CisKKyAgLy8vIFBvc3Rwcm9jZXNzSVNlbERBRygpIC0gVGhpcyBob29rIGFsbG93cyB0aGUgdGFyZ2V0IHRvIGhhY2sgb24gdGhlIGdyYXBoCisgIC8vLyByaWdodCBhZnRlciBzZWxlY3Rpb24uCisgIHZpcnR1YWwgdm9pZCBQb3N0cHJvY2Vzc0lTZWxEQUcoKSB7fQorCisgIC8vLyBNYWluIGhvb2sgZm9yIHRhcmdldHMgdG8gdHJhbnNmb3JtIG5vZGVzIGludG8gbWFjaGluZSBub2Rlcy4KKyAgdmlydHVhbCB2b2lkIFNlbGVjdChTRE5vZGUgKk4pID0gMDsKKworICAvLy8gU2VsZWN0SW5saW5lQXNtTWVtb3J5T3BlcmFuZCAtIFNlbGVjdCB0aGUgc3BlY2lmaWVkIGFkZHJlc3MgYXMgYSB0YXJnZXQKKyAgLy8vIGFkZHJlc3NpbmcgbW9kZSwgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgY29uc3RyYWludC4gIElmIHRoaXMgZG9lcworICAvLy8gbm90IG1hdGNoIG9yIGlzIG5vdCBpbXBsZW1lbnRlZCwgcmV0dXJuIHRydWUuICBUaGUgcmVzdWx0YW50IG9wZXJhbmRzCisgIC8vLyAod2hpY2ggd2lsbCBhcHBlYXIgaW4gdGhlIG1hY2hpbmUgaW5zdHJ1Y3Rpb24pIHNob3VsZCBiZSBhZGRlZCB0byB0aGUKKyAgLy8vIE91dE9wcyB2ZWN0b3IuCisgIHZpcnR1YWwgYm9vbCBTZWxlY3RJbmxpbmVBc21NZW1vcnlPcGVyYW5kKGNvbnN0IFNEVmFsdWUgJk9wLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBDb25zdHJhaW50SUQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPFNEVmFsdWU+ICZPdXRPcHMpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vLyBJc1Byb2ZpdGFibGVUb0ZvbGQgLSBSZXR1cm5zIHRydWUgaWYgaXQncyBwcm9maXRhYmxlIHRvIGZvbGQgdGhlIHNwZWNpZmljCisgIC8vLyBvcGVyYW5kIG5vZGUgTiBvZiBVIGR1cmluZyBpbnN0cnVjdGlvbiBzZWxlY3Rpb24gdGhhdCBzdGFydHMgYXQgUm9vdC4KKyAgdmlydHVhbCBib29sIElzUHJvZml0YWJsZVRvRm9sZChTRFZhbHVlIE4sIFNETm9kZSAqVSwgU0ROb2RlICpSb290KSBjb25zdDsKKworICAvLy8gSXNMZWdhbFRvRm9sZCAtIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWMgb3BlcmFuZCBub2RlIE4gb2YKKyAgLy8vIFUgY2FuIGJlIGZvbGRlZCBkdXJpbmcgaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uIHRoYXQgc3RhcnRzIGF0IFJvb3QuCisgIC8vLyBGSVhNRTogVGhpcyBpcyBhIHN0YXRpYyBtZW1iZXIgZnVuY3Rpb24gYmVjYXVzZSB0aGUgTVNQNDMwL1g4NgorICAvLy8gdGFyZ2V0cywgd2hpY2ggdXNlcyBpdCBkdXJpbmcgaXNlbC4gIFRoaXMgY291bGQgYmVjb21lIGEgcHJvcGVyIG1lbWJlci4KKyAgc3RhdGljIGJvb2wgSXNMZWdhbFRvRm9sZChTRFZhbHVlIE4sIFNETm9kZSAqVSwgU0ROb2RlICpSb290LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvZGVHZW5PcHQ6OkxldmVsIE9wdExldmVsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgSWdub3JlQ2hhaW5zID0gZmFsc2UpOworCisgIHN0YXRpYyB2b2lkIEludmFsaWRhdGVOb2RlSWQoU0ROb2RlICpOKTsKKyAgc3RhdGljIGludCBnZXRVbmludmFsaWRhdGVkTm9kZUlkKFNETm9kZSAqTik7CisKKyAgc3RhdGljIHZvaWQgRW5mb3JjZU5vZGVJZEludmFyaWFudChTRE5vZGUgKk4pOworCisgIC8vIE9wY29kZXMgdXNlZCBieSB0aGUgREFHIHN0YXRlIG1hY2hpbmU6CisgIGVudW0gQnVpbHRpbk9wY29kZXMgeworICAgIE9QQ19TY29wZSwKKyAgICBPUENfUmVjb3JkTm9kZSwKKyAgICBPUENfUmVjb3JkQ2hpbGQwLCBPUENfUmVjb3JkQ2hpbGQxLCBPUENfUmVjb3JkQ2hpbGQyLCBPUENfUmVjb3JkQ2hpbGQzLAorICAgIE9QQ19SZWNvcmRDaGlsZDQsIE9QQ19SZWNvcmRDaGlsZDUsIE9QQ19SZWNvcmRDaGlsZDYsIE9QQ19SZWNvcmRDaGlsZDcsCisgICAgT1BDX1JlY29yZE1lbVJlZiwKKyAgICBPUENfQ2FwdHVyZUdsdWVJbnB1dCwKKyAgICBPUENfTW92ZUNoaWxkLAorICAgIE9QQ19Nb3ZlQ2hpbGQwLCBPUENfTW92ZUNoaWxkMSwgT1BDX01vdmVDaGlsZDIsIE9QQ19Nb3ZlQ2hpbGQzLAorICAgIE9QQ19Nb3ZlQ2hpbGQ0LCBPUENfTW92ZUNoaWxkNSwgT1BDX01vdmVDaGlsZDYsIE9QQ19Nb3ZlQ2hpbGQ3LAorICAgIE9QQ19Nb3ZlUGFyZW50LAorICAgIE9QQ19DaGVja1NhbWUsCisgICAgT1BDX0NoZWNrQ2hpbGQwU2FtZSwgT1BDX0NoZWNrQ2hpbGQxU2FtZSwKKyAgICBPUENfQ2hlY2tDaGlsZDJTYW1lLCBPUENfQ2hlY2tDaGlsZDNTYW1lLAorICAgIE9QQ19DaGVja1BhdHRlcm5QcmVkaWNhdGUsCisgICAgT1BDX0NoZWNrUHJlZGljYXRlLAorICAgIE9QQ19DaGVja09wY29kZSwKKyAgICBPUENfU3dpdGNoT3Bjb2RlLAorICAgIE9QQ19DaGVja1R5cGUsCisgICAgT1BDX0NoZWNrVHlwZVJlcywKKyAgICBPUENfU3dpdGNoVHlwZSwKKyAgICBPUENfQ2hlY2tDaGlsZDBUeXBlLCBPUENfQ2hlY2tDaGlsZDFUeXBlLCBPUENfQ2hlY2tDaGlsZDJUeXBlLAorICAgIE9QQ19DaGVja0NoaWxkM1R5cGUsIE9QQ19DaGVja0NoaWxkNFR5cGUsIE9QQ19DaGVja0NoaWxkNVR5cGUsCisgICAgT1BDX0NoZWNrQ2hpbGQ2VHlwZSwgT1BDX0NoZWNrQ2hpbGQ3VHlwZSwKKyAgICBPUENfQ2hlY2tJbnRlZ2VyLAorICAgIE9QQ19DaGVja0NoaWxkMEludGVnZXIsIE9QQ19DaGVja0NoaWxkMUludGVnZXIsIE9QQ19DaGVja0NoaWxkMkludGVnZXIsCisgICAgT1BDX0NoZWNrQ2hpbGQzSW50ZWdlciwgT1BDX0NoZWNrQ2hpbGQ0SW50ZWdlciwKKyAgICBPUENfQ2hlY2tDb25kQ29kZSwKKyAgICBPUENfQ2hlY2tWYWx1ZVR5cGUsCisgICAgT1BDX0NoZWNrQ29tcGxleFBhdCwKKyAgICBPUENfQ2hlY2tBbmRJbW0sIE9QQ19DaGVja09ySW1tLAorICAgIE9QQ19DaGVja0ZvbGRhYmxlQ2hhaW5Ob2RlLAorCisgICAgT1BDX0VtaXRJbnRlZ2VyLAorICAgIE9QQ19FbWl0UmVnaXN0ZXIsCisgICAgT1BDX0VtaXRSZWdpc3RlcjIsCisgICAgT1BDX0VtaXRDb252ZXJ0VG9UYXJnZXQsCisgICAgT1BDX0VtaXRNZXJnZUlucHV0Q2hhaW5zLAorICAgIE9QQ19FbWl0TWVyZ2VJbnB1dENoYWluczFfMCwKKyAgICBPUENfRW1pdE1lcmdlSW5wdXRDaGFpbnMxXzEsCisgICAgT1BDX0VtaXRNZXJnZUlucHV0Q2hhaW5zMV8yLAorICAgIE9QQ19FbWl0Q29weVRvUmVnLAorICAgIE9QQ19FbWl0Tm9kZVhGb3JtLAorICAgIE9QQ19FbWl0Tm9kZSwKKyAgICAvLyBTcGFjZS1vcHRpbWl6ZWQgZm9ybXMgdGhhdCBpbXBsaWNpdGx5IGVuY29kZSBudW1iZXIgb2YgcmVzdWx0IFZUcy4KKyAgICBPUENfRW1pdE5vZGUwLCBPUENfRW1pdE5vZGUxLCBPUENfRW1pdE5vZGUyLAorICAgIE9QQ19Nb3JwaE5vZGVUbywKKyAgICAvLyBTcGFjZS1vcHRpbWl6ZWQgZm9ybXMgdGhhdCBpbXBsaWNpdGx5IGVuY29kZSBudW1iZXIgb2YgcmVzdWx0IFZUcy4KKyAgICBPUENfTW9ycGhOb2RlVG8wLCBPUENfTW9ycGhOb2RlVG8xLCBPUENfTW9ycGhOb2RlVG8yLAorICAgIE9QQ19Db21wbGV0ZU1hdGNoLAorICAgIC8vIENvbnRhaW5zIG9mZnNldCBpbiB0YWJsZSBmb3IgcGF0dGVybiBiZWluZyBzZWxlY3RlZAorICAgIE9QQ19Db3ZlcmFnZQorICB9OworCisgIGVudW0geworICAgIE9QRkxfTm9uZSAgICAgICA9IDAsICAvLyBOb2RlIGhhcyBubyBjaGFpbiBvciBnbHVlIGlucHV0IGFuZCBpc24ndCB2YXJpYWRpYy4KKyAgICBPUEZMX0NoYWluICAgICAgPSAxLCAgICAgLy8gTm9kZSBoYXMgYSBjaGFpbiBpbnB1dC4KKyAgICBPUEZMX0dsdWVJbnB1dCAgPSAyLCAgICAgLy8gTm9kZSBoYXMgYSBnbHVlIGlucHV0LgorICAgIE9QRkxfR2x1ZU91dHB1dCA9IDQsICAgICAvLyBOb2RlIGhhcyBhIGdsdWUgb3V0cHV0LgorICAgIE9QRkxfTWVtUmVmcyAgICA9IDgsICAgICAvLyBOb2RlIGdldHMgYWNjdW11bGF0ZWQgTWVtUmVmcy4KKyAgICBPUEZMX1ZhcmlhZGljMCAgPSAxPDw0LCAgLy8gTm9kZSBpcyB2YXJpYWRpYywgcm9vdCBoYXMgMCBmaXhlZCBpbnB1dHMuCisgICAgT1BGTF9WYXJpYWRpYzEgID0gMjw8NCwgIC8vIE5vZGUgaXMgdmFyaWFkaWMsIHJvb3QgaGFzIDEgZml4ZWQgaW5wdXRzLgorICAgIE9QRkxfVmFyaWFkaWMyICA9IDM8PDQsICAvLyBOb2RlIGlzIHZhcmlhZGljLCByb290IGhhcyAyIGZpeGVkIGlucHV0cy4KKyAgICBPUEZMX1ZhcmlhZGljMyAgPSA0PDw0LCAgLy8gTm9kZSBpcyB2YXJpYWRpYywgcm9vdCBoYXMgMyBmaXhlZCBpbnB1dHMuCisgICAgT1BGTF9WYXJpYWRpYzQgID0gNTw8NCwgIC8vIE5vZGUgaXMgdmFyaWFkaWMsIHJvb3QgaGFzIDQgZml4ZWQgaW5wdXRzLgorICAgIE9QRkxfVmFyaWFkaWM1ICA9IDY8PDQsICAvLyBOb2RlIGlzIHZhcmlhZGljLCByb290IGhhcyA1IGZpeGVkIGlucHV0cy4KKyAgICBPUEZMX1ZhcmlhZGljNiAgPSA3PDw0LCAgLy8gTm9kZSBpcyB2YXJpYWRpYywgcm9vdCBoYXMgNiBmaXhlZCBpbnB1dHMuCisKKyAgICBPUEZMX1ZhcmlhZGljSW5mbyA9IE9QRkxfVmFyaWFkaWM2CisgIH07CisKKyAgLy8vIGdldE51bUZpeGVkRnJvbVZhcmlhZGljSW5mbyAtIFRyYW5zZm9ybSBhbiBFbWl0Tm9kZSBmbGFncyB3b3JkIGludG8gdGhlCisgIC8vLyBudW1iZXIgb2YgZml4ZWQgYXJpdHkgdmFsdWVzIHRoYXQgc2hvdWxkIGJlIHNraXBwZWQgd2hlbiBjb3B5aW5nIGZyb20gdGhlCisgIC8vLyByb290LgorICBzdGF0aWMgaW5saW5lIGludCBnZXROdW1GaXhlZEZyb21WYXJpYWRpY0luZm8odW5zaWduZWQgRmxhZ3MpIHsKKyAgICByZXR1cm4gKChGbGFncyZPUEZMX1ZhcmlhZGljSW5mbykgPj4gNCktMTsKKyAgfQorCisKK3Byb3RlY3RlZDoKKyAgLy8vIERBR1NpemUgLSBTaXplIG9mIERBRyBiZWluZyBpbnN0cnVjdGlvbiBzZWxlY3RlZC4KKyAgLy8vCisgIHVuc2lnbmVkIERBR1NpemU7CisKKyAgLy8vIFJlcGxhY2VVc2VzIC0gcmVwbGFjZSBhbGwgdXNlcyBvZiB0aGUgb2xkIG5vZGUgRiB3aXRoIHRoZSB1c2UKKyAgLy8vIG9mIHRoZSBuZXcgbm9kZSBULgorICB2b2lkIFJlcGxhY2VVc2VzKFNEVmFsdWUgRiwgU0RWYWx1ZSBUKSB7CisgICAgQ3VyREFHLT5SZXBsYWNlQWxsVXNlc09mVmFsdWVXaXRoKEYsIFQpOworICAgIEVuZm9yY2VOb2RlSWRJbnZhcmlhbnQoVC5nZXROb2RlKCkpOworICB9CisKKyAgLy8vIFJlcGxhY2VVc2VzIC0gcmVwbGFjZSBhbGwgdXNlcyBvZiB0aGUgb2xkIG5vZGVzIEYgd2l0aCB0aGUgdXNlCisgIC8vLyBvZiB0aGUgbmV3IG5vZGVzIFQuCisgIHZvaWQgUmVwbGFjZVVzZXMoY29uc3QgU0RWYWx1ZSAqRiwgY29uc3QgU0RWYWx1ZSAqVCwgdW5zaWduZWQgTnVtKSB7CisgICAgQ3VyREFHLT5SZXBsYWNlQWxsVXNlc09mVmFsdWVzV2l0aChGLCBULCBOdW0pOworICAgIGZvciAodW5zaWduZWQgaSA9IDA7IGkgPCBOdW07ICsraSkKKyAgICAgIEVuZm9yY2VOb2RlSWRJbnZhcmlhbnQoVFtpXS5nZXROb2RlKCkpOworICB9CisKKyAgLy8vIFJlcGxhY2VVc2VzIC0gcmVwbGFjZSBhbGwgdXNlcyBvZiB0aGUgb2xkIG5vZGUgRiB3aXRoIHRoZSB1c2UKKyAgLy8vIG9mIHRoZSBuZXcgbm9kZSBULgorICB2b2lkIFJlcGxhY2VVc2VzKFNETm9kZSAqRiwgU0ROb2RlICpUKSB7CisgICAgQ3VyREFHLT5SZXBsYWNlQWxsVXNlc1dpdGgoRiwgVCk7CisgICAgRW5mb3JjZU5vZGVJZEludmFyaWFudChUKTsKKyAgfQorCisgIC8vLyBSZXBsYWNlIGFsbCB1c2VzIG9mIFxjIEYgd2l0aCBcYyBULCB0aGVuIHJlbW92ZSBcYyBGIGZyb20gdGhlIERBRy4KKyAgdm9pZCBSZXBsYWNlTm9kZShTRE5vZGUgKkYsIFNETm9kZSAqVCkgeworICAgIEN1ckRBRy0+UmVwbGFjZUFsbFVzZXNXaXRoKEYsIFQpOworICAgIEVuZm9yY2VOb2RlSWRJbnZhcmlhbnQoVCk7CisgICAgQ3VyREFHLT5SZW1vdmVEZWFkTm9kZShGKTsKKyAgfQorCisgIC8vLyBTZWxlY3RJbmxpbmVBc21NZW1vcnlPcGVyYW5kcyAtIENhbGxzIHRvIHRoaXMgYXJlIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkCisgIC8vLyBieSB0YmxnZW4uICBPdGhlcnMgc2hvdWxkIG5vdCBjYWxsIGl0LgorICB2b2lkIFNlbGVjdElubGluZUFzbU1lbW9yeU9wZXJhbmRzKHN0ZDo6dmVjdG9yPFNEVmFsdWU+ICZPcHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU0RMb2MgJkRMKTsKKworICAvLy8gZ2V0UGF0dGVybkZvckluZGV4IC0gUGF0dGVybnMgc2VsZWN0ZWQgYnkgdGFibGVnZW4gZHVyaW5nIElTRUwKKyAgdmlydHVhbCBTdHJpbmdSZWYgZ2V0UGF0dGVybkZvckluZGV4KHVuc2lnbmVkIGluZGV4KSB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgiVGJsZ2VuIHNob3VsZCBnZW5lcmF0ZSB0aGUgaW1wbGVtZW50YXRpb24gb2YgdGhpcyEiKTsKKyAgfQorCisgIC8vLyBnZXRJbmNsdWRlUGF0aEZvckluZGV4IC0gZ2V0IHRoZSB0ZCBzb3VyY2UgbG9jYXRpb24gb2YgcGF0dGVybiBpbnN0YW50aWF0aW9uCisgIHZpcnR1YWwgU3RyaW5nUmVmIGdldEluY2x1ZGVQYXRoRm9ySW5kZXgodW5zaWduZWQgaW5kZXgpIHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJUYmxnZW4gc2hvdWxkIGdlbmVyYXRlIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzISIpOworICB9CitwdWJsaWM6CisgIC8vIENhbGxzIHRvIHRoZXNlIHByZWRpY2F0ZXMgYXJlIGdlbmVyYXRlZCBieSB0YmxnZW4uCisgIGJvb2wgQ2hlY2tBbmRNYXNrKFNEVmFsdWUgTEhTLCBDb25zdGFudFNETm9kZSAqUkhTLAorICAgICAgICAgICAgICAgICAgICBpbnQ2NF90IERlc2lyZWRNYXNrUykgY29uc3Q7CisgIGJvb2wgQ2hlY2tPck1hc2soU0RWYWx1ZSBMSFMsIENvbnN0YW50U0ROb2RlICpSSFMsCisgICAgICAgICAgICAgICAgICAgIGludDY0X3QgRGVzaXJlZE1hc2tTKSBjb25zdDsKKworCisgIC8vLyBDaGVja1BhdHRlcm5QcmVkaWNhdGUgLSBUaGlzIGZ1bmN0aW9uIGlzIGdlbmVyYXRlZCBieSB0YmxnZW4gaW4gdGhlCisgIC8vLyB0YXJnZXQuICBJdCBydW5zIHRoZSBzcGVjaWZpZWQgcGF0dGVybiBwcmVkaWNhdGUgYW5kIHJldHVybnMgdHJ1ZSBpZiBpdAorICAvLy8gc3VjY2VlZHMgb3IgZmFsc2UgaWYgaXQgZmFpbHMuICBUaGUgbnVtYmVyIGlzIGEgcHJpdmF0ZSBpbXBsZW1lbnRhdGlvbgorICAvLy8gZGV0YWlsIHRvIHRoZSBjb2RlIHRibGdlbiBwcm9kdWNlcy4KKyAgdmlydHVhbCBib29sIENoZWNrUGF0dGVyblByZWRpY2F0ZSh1bnNpZ25lZCBQcmVkTm8pIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJUYmxnZW4gc2hvdWxkIGdlbmVyYXRlIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzISIpOworICB9CisKKyAgLy8vIENoZWNrTm9kZVByZWRpY2F0ZSAtIFRoaXMgZnVuY3Rpb24gaXMgZ2VuZXJhdGVkIGJ5IHRibGdlbiBpbiB0aGUgdGFyZ2V0LgorICAvLy8gSXQgcnVucyBub2RlIHByZWRpY2F0ZSBudW1iZXIgUHJlZE5vIGFuZCByZXR1cm5zIHRydWUgaWYgaXQgc3VjY2VlZHMgb3IKKyAgLy8vIGZhbHNlIGlmIGl0IGZhaWxzLiAgVGhlIG51bWJlciBpcyBhIHByaXZhdGUgaW1wbGVtZW50YXRpb24KKyAgLy8vIGRldGFpbCB0byB0aGUgY29kZSB0YmxnZW4gcHJvZHVjZXMuCisgIHZpcnR1YWwgYm9vbCBDaGVja05vZGVQcmVkaWNhdGUoU0ROb2RlICpOLCB1bnNpZ25lZCBQcmVkTm8pIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJUYmxnZW4gc2hvdWxkIGdlbmVyYXRlIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzISIpOworICB9CisKKyAgdmlydHVhbCBib29sIENoZWNrQ29tcGxleFBhdHRlcm4oU0ROb2RlICpSb290LCBTRE5vZGUgKlBhcmVudCwgU0RWYWx1ZSBOLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBQYXR0ZXJuTm8sCisgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8c3RkOjpwYWlyPFNEVmFsdWUsIFNETm9kZSo+ID4gJlJlc3VsdCkgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIlRibGdlbiBzaG91bGQgZ2VuZXJhdGUgdGhlIGltcGxlbWVudGF0aW9uIG9mIHRoaXMhIik7CisgIH0KKworICB2aXJ0dWFsIFNEVmFsdWUgUnVuU0ROb2RlWEZvcm0oU0RWYWx1ZSBWLCB1bnNpZ25lZCBYRm9ybU5vKSB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgiVGJsZ2VuIHNob3VsZCBnZW5lcmF0ZSB0aGlzISIpOworICB9CisKKyAgdm9pZCBTZWxlY3RDb2RlQ29tbW9uKFNETm9kZSAqTm9kZVRvTWF0Y2gsIGNvbnN0IHVuc2lnbmVkIGNoYXIgKk1hdGNoZXJUYWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFRhYmxlU2l6ZSk7CisKKyAgLy8vIFxicmllZiBSZXR1cm4gdHJ1ZSBpZiBjb21wbGV4IHBhdHRlcm5zIGZvciB0aGlzIHRhcmdldCBjYW4gbXV0YXRlIHRoZQorICAvLy8gREFHLgorICB2aXJ0dWFsIGJvb2wgQ29tcGxleFBhdHRlcm5GdW5jTXV0YXRlc0RBRygpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICBib29sIGlzT3JFcXVpdmFsZW50VG9BZGQoY29uc3QgU0ROb2RlICpOKSBjb25zdDsKKworcHJpdmF0ZToKKworICAvLyBDYWxscyB0byB0aGVzZSBmdW5jdGlvbnMgYXJlIGdlbmVyYXRlZCBieSB0YmxnZW4uCisgIHZvaWQgU2VsZWN0X0lOTElORUFTTShTRE5vZGUgKk4pOworICB2b2lkIFNlbGVjdF9SRUFEX1JFR0lTVEVSKFNETm9kZSAqTik7CisgIHZvaWQgU2VsZWN0X1dSSVRFX1JFR0lTVEVSKFNETm9kZSAqTik7CisgIHZvaWQgU2VsZWN0X1VOREVGKFNETm9kZSAqTik7CisgIHZvaWQgQ2Fubm90WWV0U2VsZWN0KFNETm9kZSAqTik7CisKK3ByaXZhdGU6CisgIHZvaWQgRG9JbnN0cnVjdGlvblNlbGVjdGlvbigpOworICBTRE5vZGUgKk1vcnBoTm9kZShTRE5vZGUgKk5vZGUsIHVuc2lnbmVkIFRhcmdldE9wYywgU0RWVExpc3QgVlRzLAorICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjxTRFZhbHVlPiBPcHMsIHVuc2lnbmVkIEVtaXROb2RlSW5mbyk7CisKKyAgU0ROb2RlICpNdXRhdGVTdHJpY3RGUFRvRlAoU0ROb2RlICpOb2RlLCB1bnNpZ25lZCBOZXdPcGMpOworCisgIC8vLyBQcmVwYXJlcyB0aGUgbGFuZGluZyBwYWQgdG8gdGFrZSBpbmNvbWluZyB2YWx1ZXMgb3IgZG8gb3RoZXIgRUgKKyAgLy8vIHBlcnNvbmFsaXR5IHNwZWNpZmljIHRhc2tzLiBSZXR1cm5zIHRydWUgaWYgdGhlIGJsb2NrIHNob3VsZCBiZQorICAvLy8gaW5zdHJ1Y3Rpb24gc2VsZWN0ZWQsIGZhbHNlIGlmIG5vIGNvZGUgc2hvdWxkIGJlIGVtaXR0ZWQgZm9yIGl0LgorICBib29sIFByZXBhcmVFSExhbmRpbmdQYWQoKTsKKworICAvLy8gXGJyaWVmIFBlcmZvcm0gaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uIG9uIGFsbCBiYXNpYyBibG9ja3MgaW4gdGhlIGZ1bmN0aW9uLgorICB2b2lkIFNlbGVjdEFsbEJhc2ljQmxvY2tzKGNvbnN0IEZ1bmN0aW9uICZGbik7CisKKyAgLy8vIFxicmllZiBQZXJmb3JtIGluc3RydWN0aW9uIHNlbGVjdGlvbiBvbiBhIHNpbmdsZSBiYXNpYyBibG9jaywgZm9yCisgIC8vLyBpbnN0cnVjdGlvbnMgYmV0d2VlbiBccCBCZWdpbiBhbmQgXHAgRW5kLiAgXHAgSGFkVGFpbENhbGwgd2lsbCBiZSBzZXQKKyAgLy8vIHRvIHRydWUgaWYgYSBjYWxsIGluIHRoZSBibG9jayB3YXMgdHJhbnNsYXRlZCBhcyBhIHRhaWwgY2FsbC4KKyAgdm9pZCBTZWxlY3RCYXNpY0Jsb2NrKEJhc2ljQmxvY2s6OmNvbnN0X2l0ZXJhdG9yIEJlZ2luLAorICAgICAgICAgICAgICAgICAgICAgICAgQmFzaWNCbG9jazo6Y29uc3RfaXRlcmF0b3IgRW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCAmSGFkVGFpbENhbGwpOworICB2b2lkIEZpbmlzaEJhc2ljQmxvY2soKTsKKworICB2b2lkIENvZGVHZW5BbmRFbWl0REFHKCk7CisKKyAgLy8vIFxicmllZiBHZW5lcmF0ZSBpbnN0cnVjdGlvbnMgZm9yIGxvd2VyaW5nIHRoZSBpbmNvbWluZyBhcmd1bWVudHMgb2YgdGhlCisgIC8vLyBnaXZlbiBmdW5jdGlvbi4KKyAgdm9pZCBMb3dlckFyZ3VtZW50cyhjb25zdCBGdW5jdGlvbiAmRik7CisKKyAgdm9pZCBDb21wdXRlTGl2ZU91dFZSZWdJbmZvKCk7CisKKyAgLy8vIENyZWF0ZSB0aGUgc2NoZWR1bGVyLiBJZiBhIHNwZWNpZmljIHNjaGVkdWxlciB3YXMgc3BlY2lmaWVkCisgIC8vLyB2aWEgdGhlIFNjaGVkdWxlclJlZ2lzdHJ5LCB1c2UgaXQsIG90aGVyd2lzZSBzZWxlY3QgdGhlCisgIC8vLyBvbmUgcHJlZmVycmVkIGJ5IHRoZSB0YXJnZXQuCisgIC8vLworICBTY2hlZHVsZURBR1NETm9kZXMgKkNyZWF0ZVNjaGVkdWxlcigpOworCisgIC8vLyBPcGNvZGVPZmZzZXQgLSBUaGlzIGlzIGEgY2FjaGUgdXNlZCB0byBkaXNwYXRjaCBlZmZpY2llbnRseSBpbnRvIGlzZWwKKyAgLy8vIHN0YXRlIG1hY2hpbmVzIHRoYXQgc3RhcnQgd2l0aCBhIE9QQ19Td2l0Y2hPcGNvZGUgbm9kZS4KKyAgc3RkOjp2ZWN0b3I8dW5zaWduZWQ+IE9wY29kZU9mZnNldDsKKworICB2b2lkIFVwZGF0ZUNoYWlucyhTRE5vZGUgKk5vZGVUb01hdGNoLCBTRFZhbHVlIElucHV0Q2hhaW4sCisgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxTRE5vZGUgKj4gJkNoYWluTm9kZXNNYXRjaGVkLAorICAgICAgICAgICAgICAgICAgICBib29sIGlzTW9ycGhOb2RlVG8pOworfTsKKworfQorCisjZW5kaWYgLyogTExWTV9DT0RFR0VOX1NFTEVDVElPTkRBR0lTRUxfSCAqLwpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBR05vZGVzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vU2VsZWN0aW9uREFHTm9kZXMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZmI1YzAwCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBR05vZGVzLmgKQEAgLTAsMCArMSwyMzk5IEBACisvLz09PS0gbGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBR05vZGVzLmggLSBTZWxlY3Rpb25EQUcgTm9kZXMgLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZWNsYXJlcyB0aGUgU0ROb2RlIGNsYXNzIGFuZCBkZXJpdmVkIGNsYXNzZXMsIHdoaWNoIGFyZSB1c2VkIHRvCisvLyByZXByZXNlbnQgdGhlIG5vZGVzIGFuZCBvcGVyYXRpb25zIHByZXNlbnQgaW4gYSBTZWxlY3Rpb25EQUcuICBUaGVzZSBub2RlcworLy8gYW5kIG9wZXJhdGlvbnMgYXJlIG1hY2hpbmUgY29kZSBsZXZlbCBvcGVyYXRpb25zLCB3aXRoIHNvbWUgc2ltaWxhcml0aWVzIHRvCisvLyB0aGUgR0NDIFJUTCByZXByZXNlbnRhdGlvbi4KKy8vCisvLyBDbGllbnRzIHNob3VsZCBpbmNsdWRlIHRoZSBTZWxlY3Rpb25EQUcuaCBmaWxlIGluc3RlYWQgb2YgdGhpcyBmaWxlIGRpcmVjdGx5LgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1NFTEVDVElPTkRBR05PREVTX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1NFTEVDVElPTkRBR05PREVTX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0FQRmxvYXQuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9BcnJheVJlZi5oIgorI2luY2x1ZGUgImxsdm0vQURUL0JpdFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQURUL0ZvbGRpbmdTZXQuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9HcmFwaFRyYWl0cy5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsUHRyU2V0LmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9pbGlzdF9ub2RlLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvaXRlcmF0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9pdGVyYXRvcl9yYW5nZS5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9JU0RPcGNvZGVzLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVNZW1PcGVyYW5kLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1ZhbHVlVHlwZXMuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0NvbnN0YW50cy5oIgorI2luY2x1ZGUgImxsdm0vSVIvRGVidWdMb2MuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0luc3RydWN0aW9uLmgiCisjaW5jbHVkZSAibGx2bS9JUi9JbnN0cnVjdGlvbnMuaCIKKyNpbmNsdWRlICJsbHZtL0lSL01ldGFkYXRhLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0FsaWduT2YuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvQXRvbWljT3JkZXJpbmcuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvQ2FzdGluZy5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9FcnJvckhhbmRsaW5nLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L01hY2hpbmVWYWx1ZVR5cGUuaCIKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjbGltaXRzPgorI2luY2x1ZGUgPGNzdGRkZWY+CisjaW5jbHVkZSA8Y3N0ZGludD4KKyNpbmNsdWRlIDxjc3RyaW5nPgorI2luY2x1ZGUgPGl0ZXJhdG9yPgorI2luY2x1ZGUgPHN0cmluZz4KKyNpbmNsdWRlIDx0dXBsZT4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBBUEludDsKK2NsYXNzIENvbnN0YW50OwordGVtcGxhdGUgPHR5cGVuYW1lIFQ+IHN0cnVjdCBEZW5zZU1hcEluZm87CitjbGFzcyBHbG9iYWxWYWx1ZTsKK2NsYXNzIE1hY2hpbmVCYXNpY0Jsb2NrOworY2xhc3MgTWFjaGluZUNvbnN0YW50UG9vbFZhbHVlOworY2xhc3MgTUNTeW1ib2w7CitjbGFzcyByYXdfb3N0cmVhbTsKK2NsYXNzIFNETm9kZTsKK2NsYXNzIFNlbGVjdGlvbkRBRzsKK2NsYXNzIFR5cGU7CitjbGFzcyBWYWx1ZTsKKwordm9pZCBjaGVja0ZvckN5Y2xlcyhjb25zdCBTRE5vZGUgKk4sIGNvbnN0IFNlbGVjdGlvbkRBRyAqREFHID0gbnVsbHB0ciwKKyAgICAgICAgICAgICAgICAgICAgYm9vbCBmb3JjZSA9IGZhbHNlKTsKKworLy8vIFRoaXMgcmVwcmVzZW50cyBhIGxpc3Qgb2YgVmFsdWVUeXBlJ3MgdGhhdCBoYXMgYmVlbiBpbnRlcm4nZCBieQorLy8vIGEgU2VsZWN0aW9uREFHLiAgSW5zdGFuY2VzIG9mIHRoaXMgc2ltcGxlIHZhbHVlIGNsYXNzIGFyZSByZXR1cm5lZCBieQorLy8vIFNlbGVjdGlvbkRBRzo6Z2V0VlRMaXN0KC4uLikuCisvLy8KK3N0cnVjdCBTRFZUTGlzdCB7CisgIGNvbnN0IEVWVCAqVlRzOworICB1bnNpZ25lZCBpbnQgTnVtVlRzOworfTsKKworbmFtZXNwYWNlIElTRCB7CisKKyAgLy8vIE5vZGUgcHJlZGljYXRlcworCisgIC8vLyBJZiBOIGlzIGEgQlVJTERfVkVDVE9SIG5vZGUgd2hvc2UgZWxlbWVudHMgYXJlIGFsbCB0aGUgc2FtZSBjb25zdGFudCBvcgorICAvLy8gdW5kZWZpbmVkLCByZXR1cm4gdHJ1ZSBhbmQgcmV0dXJuIHRoZSBjb25zdGFudCB2YWx1ZSBpbiBccCBTcGxhdFZhbHVlLgorICBib29sIGlzQ29uc3RhbnRTcGxhdFZlY3Rvcihjb25zdCBTRE5vZGUgKk4sIEFQSW50ICZTcGxhdFZhbHVlKTsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCBub2RlIGlzIGEgQlVJTERfVkVDVE9SIHdoZXJlIGFsbCBvZiB0aGUKKyAgLy8vIGVsZW1lbnRzIGFyZSB+MCBvciB1bmRlZi4KKyAgYm9vbCBpc0J1aWxkVmVjdG9yQWxsT25lcyhjb25zdCBTRE5vZGUgKk4pOworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIG5vZGUgaXMgYSBCVUlMRF9WRUNUT1Igd2hlcmUgYWxsIG9mIHRoZQorICAvLy8gZWxlbWVudHMgYXJlIDAgb3IgdW5kZWYuCisgIGJvb2wgaXNCdWlsZFZlY3RvckFsbFplcm9zKGNvbnN0IFNETm9kZSAqTik7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgbm9kZSBpcyBhIEJVSUxEX1ZFQ1RPUiBub2RlIG9mIGFsbAorICAvLy8gQ29uc3RhbnRTRE5vZGUgb3IgdW5kZWYuCisgIGJvb2wgaXNCdWlsZFZlY3Rvck9mQ29uc3RhbnRTRE5vZGVzKGNvbnN0IFNETm9kZSAqTik7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgbm9kZSBpcyBhIEJVSUxEX1ZFQ1RPUiBub2RlIG9mIGFsbAorICAvLy8gQ29uc3RhbnRGUFNETm9kZSBvciB1bmRlZi4KKyAgYm9vbCBpc0J1aWxkVmVjdG9yT2ZDb25zdGFudEZQU0ROb2Rlcyhjb25zdCBTRE5vZGUgKk4pOworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgbm9kZSBoYXMgYXQgbGVhc3Qgb25lIG9wZXJhbmQgYW5kIGFsbCBvcGVyYW5kcyBvZiB0aGUKKyAgLy8vIHNwZWNpZmllZCBub2RlIGFyZSBJU0Q6OlVOREVGLgorICBib29sIGFsbE9wZXJhbmRzVW5kZWYoY29uc3QgU0ROb2RlICpOKTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIElTRAorCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vIFVubGlrZSBMTFZNIHZhbHVlcywgU2VsZWN0aW9uIERBRyBub2RlcyBtYXkgcmV0dXJuIG11bHRpcGxlCisvLy8gdmFsdWVzIGFzIHRoZSByZXN1bHQgb2YgYSBjb21wdXRhdGlvbi4gIE1hbnkgbm9kZXMgcmV0dXJuIG11bHRpcGxlIHZhbHVlcywKKy8vLyBmcm9tIGxvYWRzICh3aGljaCBkZWZpbmUgYSB0b2tlbiBhbmQgYSByZXR1cm4gdmFsdWUpIHRvIEFEREMgKHdoaWNoIHJldHVybnMKKy8vLyBhIHJlc3VsdCBhbmQgYSBjYXJyeSB2YWx1ZSksIHRvIGNhbGxzICh3aGljaCBtYXkgcmV0dXJuIGFuIGFyYml0cmFyeSBudW1iZXIKKy8vLyBvZiB2YWx1ZXMpLgorLy8vCisvLy8gQXMgc3VjaCwgZWFjaCB1c2Ugb2YgYSBTZWxlY3Rpb25EQUcgY29tcHV0YXRpb24gbXVzdCBpbmRpY2F0ZSB0aGUgbm9kZSB0aGF0CisvLy8gY29tcHV0ZXMgaXQgYXMgd2VsbCBhcyB3aGljaCByZXR1cm4gdmFsdWUgdG8gdXNlIGZyb20gdGhhdCBub2RlLiAgVGhpcyBwYWlyCisvLy8gb2YgaW5mb3JtYXRpb24gaXMgcmVwcmVzZW50ZWQgd2l0aCB0aGUgU0RWYWx1ZSB2YWx1ZSB0eXBlLgorLy8vCitjbGFzcyBTRFZhbHVlIHsKKyAgZnJpZW5kIHN0cnVjdCBEZW5zZU1hcEluZm88U0RWYWx1ZT47CisKKyAgU0ROb2RlICpOb2RlID0gbnVsbHB0cjsgLy8gVGhlIG5vZGUgZGVmaW5pbmcgdGhlIHZhbHVlIHdlIGFyZSB1c2luZy4KKyAgdW5zaWduZWQgUmVzTm8gPSAwOyAgICAgLy8gV2hpY2ggcmV0dXJuIHZhbHVlIG9mIHRoZSBub2RlIHdlIGFyZSB1c2luZy4KKworcHVibGljOgorICBTRFZhbHVlKCkgPSBkZWZhdWx0OworICBTRFZhbHVlKFNETm9kZSAqbm9kZSwgdW5zaWduZWQgcmVzbm8pOworCisgIC8vLyBnZXQgdGhlIGluZGV4IHdoaWNoIHNlbGVjdHMgYSBzcGVjaWZpYyByZXN1bHQgaW4gdGhlIFNETm9kZQorICB1bnNpZ25lZCBnZXRSZXNObygpIGNvbnN0IHsgcmV0dXJuIFJlc05vOyB9CisKKyAgLy8vIGdldCB0aGUgU0ROb2RlIHdoaWNoIGhvbGRzIHRoZSBkZXNpcmVkIHJlc3VsdAorICBTRE5vZGUgKmdldE5vZGUoKSBjb25zdCB7IHJldHVybiBOb2RlOyB9CisKKyAgLy8vIHNldCB0aGUgU0ROb2RlCisgIHZvaWQgc2V0Tm9kZShTRE5vZGUgKk4pIHsgTm9kZSA9IE47IH0KKworICBpbmxpbmUgU0ROb2RlICpvcGVyYXRvci0+KCkgY29uc3QgeyByZXR1cm4gTm9kZTsgfQorCisgIGJvb2wgb3BlcmF0b3I9PShjb25zdCBTRFZhbHVlICZPKSBjb25zdCB7CisgICAgcmV0dXJuIE5vZGUgPT0gTy5Ob2RlICYmIFJlc05vID09IE8uUmVzTm87CisgIH0KKyAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IFNEVmFsdWUgJk8pIGNvbnN0IHsKKyAgICByZXR1cm4gIW9wZXJhdG9yPT0oTyk7CisgIH0KKyAgYm9vbCBvcGVyYXRvcjwoY29uc3QgU0RWYWx1ZSAmTykgY29uc3QgeworICAgIHJldHVybiBzdGQ6OnRpZShOb2RlLCBSZXNObykgPCBzdGQ6OnRpZShPLk5vZGUsIE8uUmVzTm8pOworICB9CisgIGV4cGxpY2l0IG9wZXJhdG9yIGJvb2woKSBjb25zdCB7CisgICAgcmV0dXJuIE5vZGUgIT0gbnVsbHB0cjsKKyAgfQorCisgIFNEVmFsdWUgZ2V0VmFsdWUodW5zaWduZWQgUikgY29uc3QgeworICAgIHJldHVybiBTRFZhbHVlKE5vZGUsIFIpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgbm9kZSBpcyBhbiBvcGVyYW5kIG9mIE4uCisgIGJvb2wgaXNPcGVyYW5kT2YoY29uc3QgU0ROb2RlICpOKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRoZSBWYWx1ZVR5cGUgb2YgdGhlIHJlZmVyZW5jZWQgcmV0dXJuIHZhbHVlLgorICBpbmxpbmUgRVZUIGdldFZhbHVlVHlwZSgpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdGhlIHNpbXBsZSBWYWx1ZVR5cGUgb2YgdGhlIHJlZmVyZW5jZWQgcmV0dXJuIHZhbHVlLgorICBNVlQgZ2V0U2ltcGxlVmFsdWVUeXBlKCkgY29uc3QgeworICAgIHJldHVybiBnZXRWYWx1ZVR5cGUoKS5nZXRTaW1wbGVWVCgpOworICB9CisKKyAgLy8vIFJldHVybnMgdGhlIHNpemUgb2YgdGhlIHZhbHVlIGluIGJpdHMuCisgIHVuc2lnbmVkIGdldFZhbHVlU2l6ZUluQml0cygpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0VmFsdWVUeXBlKCkuZ2V0U2l6ZUluQml0cygpOworICB9CisKKyAgdW5zaWduZWQgZ2V0U2NhbGFyVmFsdWVTaXplSW5CaXRzKCkgY29uc3QgeworICAgIHJldHVybiBnZXRWYWx1ZVR5cGUoKS5nZXRTY2FsYXJUeXBlKCkuZ2V0U2l6ZUluQml0cygpOworICB9CisKKyAgLy8gRm9yd2FyZGluZyBtZXRob2RzIC0gVGhlc2UgZm9yd2FyZCB0byB0aGUgY29ycmVzcG9uZGluZyBtZXRob2RzIGluIFNETm9kZS4KKyAgaW5saW5lIHVuc2lnbmVkIGdldE9wY29kZSgpIGNvbnN0OworICBpbmxpbmUgdW5zaWduZWQgZ2V0TnVtT3BlcmFuZHMoKSBjb25zdDsKKyAgaW5saW5lIGNvbnN0IFNEVmFsdWUgJmdldE9wZXJhbmQodW5zaWduZWQgaSkgY29uc3Q7CisgIGlubGluZSB1aW50NjRfdCBnZXRDb25zdGFudE9wZXJhbmRWYWwodW5zaWduZWQgaSkgY29uc3Q7CisgIGlubGluZSBib29sIGlzVGFyZ2V0TWVtb3J5T3Bjb2RlKCkgY29uc3Q7CisgIGlubGluZSBib29sIGlzVGFyZ2V0T3Bjb2RlKCkgY29uc3Q7CisgIGlubGluZSBib29sIGlzTWFjaGluZU9wY29kZSgpIGNvbnN0OworICBpbmxpbmUgYm9vbCBpc1VuZGVmKCkgY29uc3Q7CisgIGlubGluZSB1bnNpZ25lZCBnZXRNYWNoaW5lT3Bjb2RlKCkgY29uc3Q7CisgIGlubGluZSBjb25zdCBEZWJ1Z0xvYyAmZ2V0RGVidWdMb2MoKSBjb25zdDsKKyAgaW5saW5lIHZvaWQgZHVtcCgpIGNvbnN0OworICBpbmxpbmUgdm9pZCBkdW1wKGNvbnN0IFNlbGVjdGlvbkRBRyAqRykgY29uc3Q7CisgIGlubGluZSB2b2lkIGR1bXByKCkgY29uc3Q7CisgIGlubGluZSB2b2lkIGR1bXByKGNvbnN0IFNlbGVjdGlvbkRBRyAqRykgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgb3BlcmFuZCAod2hpY2ggbXVzdCBiZSBhIGNoYWluKSByZWFjaGVzIHRoZQorICAvLy8gc3BlY2lmaWVkIG9wZXJhbmQgd2l0aG91dCBjcm9zc2luZyBhbnkgc2lkZS1lZmZlY3RpbmcgaW5zdHJ1Y3Rpb25zLgorICAvLy8gSW4gcHJhY3RpY2UsIHRoaXMgbG9va3MgdGhyb3VnaCB0b2tlbiBmYWN0b3JzIGFuZCBub24tdm9sYXRpbGUgbG9hZHMuCisgIC8vLyBJbiBvcmRlciB0byByZW1haW4gZWZmaWNpZW50LCB0aGlzIG9ubHkKKyAgLy8vIGxvb2tzIGEgY291cGxlIG9mIG5vZGVzIGluLCBpdCBkb2VzIG5vdCBkbyBhbiBleGhhdXN0aXZlIHNlYXJjaC4KKyAgYm9vbCByZWFjaGVzQ2hhaW5XaXRob3V0U2lkZUVmZmVjdHMoU0RWYWx1ZSBEZXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBEZXB0aCA9IDIpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGVyZSBhcmUgbm8gbm9kZXMgdXNpbmcgdmFsdWUgUmVzTm8gb2YgTm9kZS4KKyAgaW5saW5lIGJvb2wgdXNlX2VtcHR5KCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZXJlIGlzIGV4YWN0bHkgb25lIG5vZGUgdXNpbmcgdmFsdWUgUmVzTm8gb2YgTm9kZS4KKyAgaW5saW5lIGJvb2wgaGFzT25lVXNlKCkgY29uc3Q7Cit9OworCit0ZW1wbGF0ZTw+IHN0cnVjdCBEZW5zZU1hcEluZm88U0RWYWx1ZT4geworICBzdGF0aWMgaW5saW5lIFNEVmFsdWUgZ2V0RW1wdHlLZXkoKSB7CisgICAgU0RWYWx1ZSBWOworICAgIFYuUmVzTm8gPSAtMVU7CisgICAgcmV0dXJuIFY7CisgIH0KKworICBzdGF0aWMgaW5saW5lIFNEVmFsdWUgZ2V0VG9tYnN0b25lS2V5KCkgeworICAgIFNEVmFsdWUgVjsKKyAgICBWLlJlc05vID0gLTJVOworICAgIHJldHVybiBWOworICB9CisKKyAgc3RhdGljIHVuc2lnbmVkIGdldEhhc2hWYWx1ZShjb25zdCBTRFZhbHVlICZWYWwpIHsKKyAgICByZXR1cm4gKCh1bnNpZ25lZCkoKHVpbnRwdHJfdClWYWwuZ2V0Tm9kZSgpID4+IDQpIF4KKyAgICAgICAgICAgICh1bnNpZ25lZCkoKHVpbnRwdHJfdClWYWwuZ2V0Tm9kZSgpID4+IDkpKSArIFZhbC5nZXRSZXNObygpOworICB9CisKKyAgc3RhdGljIGJvb2wgaXNFcXVhbChjb25zdCBTRFZhbHVlICZMSFMsIGNvbnN0IFNEVmFsdWUgJlJIUykgeworICAgIHJldHVybiBMSFMgPT0gUkhTOworICB9Cit9OwordGVtcGxhdGUgPD4gc3RydWN0IGlzUG9kTGlrZTxTRFZhbHVlPiB7IHN0YXRpYyBjb25zdCBib29sIHZhbHVlID0gdHJ1ZTsgfTsKKworLy8vIEFsbG93IGNhc3Rpbmcgb3BlcmF0b3JzIHRvIHdvcmsgZGlyZWN0bHkgb24KKy8vLyBTRFZhbHVlcyBhcyBpZiB0aGV5IHdlcmUgU0ROb2RlKidzLgordGVtcGxhdGU8PiBzdHJ1Y3Qgc2ltcGxpZnlfdHlwZTxTRFZhbHVlPiB7CisgIHVzaW5nIFNpbXBsZVR5cGUgPSBTRE5vZGUgKjsKKworICBzdGF0aWMgU2ltcGxlVHlwZSBnZXRTaW1wbGlmaWVkVmFsdWUoU0RWYWx1ZSAmVmFsKSB7CisgICAgcmV0dXJuIFZhbC5nZXROb2RlKCk7CisgIH0KK307Cit0ZW1wbGF0ZTw+IHN0cnVjdCBzaW1wbGlmeV90eXBlPGNvbnN0IFNEVmFsdWU+IHsKKyAgdXNpbmcgU2ltcGxlVHlwZSA9IC8qY29uc3QqLyBTRE5vZGUgKjsKKworICBzdGF0aWMgU2ltcGxlVHlwZSBnZXRTaW1wbGlmaWVkVmFsdWUoY29uc3QgU0RWYWx1ZSAmVmFsKSB7CisgICAgcmV0dXJuIFZhbC5nZXROb2RlKCk7CisgIH0KK307CisKKy8vLyBSZXByZXNlbnRzIGEgdXNlIG9mIGEgU0ROb2RlLiBUaGlzIGNsYXNzIGhvbGRzIGFuIFNEVmFsdWUsCisvLy8gd2hpY2ggcmVjb3JkcyB0aGUgU0ROb2RlIGJlaW5nIHVzZWQgYW5kIHRoZSByZXN1bHQgbnVtYmVyLCBhCisvLy8gcG9pbnRlciB0byB0aGUgU0ROb2RlIHVzaW5nIHRoZSB2YWx1ZSwgYW5kIE5leHQgYW5kIFByZXYgcG9pbnRlcnMsCisvLy8gd2hpY2ggbGluayB0b2dldGhlciBhbGwgdGhlIHVzZXMgb2YgYW4gU0ROb2RlLgorLy8vCitjbGFzcyBTRFVzZSB7CisgIC8vLyBWYWwgLSBUaGUgdmFsdWUgYmVpbmcgdXNlZC4KKyAgU0RWYWx1ZSBWYWw7CisgIC8vLyBVc2VyIC0gVGhlIHVzZXIgb2YgdGhpcyB2YWx1ZS4KKyAgU0ROb2RlICpVc2VyID0gbnVsbHB0cjsKKyAgLy8vIFByZXYsIE5leHQgLSBQb2ludGVycyB0byB0aGUgdXNlcyBsaXN0IG9mIHRoZSBTRE5vZGUgcmVmZXJyZWQgYnkKKyAgLy8vIHRoaXMgb3BlcmFuZC4KKyAgU0RVc2UgKipQcmV2ID0gbnVsbHB0cjsKKyAgU0RVc2UgKk5leHQgPSBudWxscHRyOworCitwdWJsaWM6CisgIFNEVXNlKCkgPSBkZWZhdWx0OworICBTRFVzZShjb25zdCBTRFVzZSAmVSkgPSBkZWxldGU7CisgIFNEVXNlICZvcGVyYXRvcj0oY29uc3QgU0RVc2UgJikgPSBkZWxldGU7CisKKyAgLy8vIE5vcm1hbGx5IFNEVXNlIHdpbGwganVzdCBpbXBsaWNpdGx5IGNvbnZlcnQgdG8gYW4gU0RWYWx1ZSB0aGF0IGl0IGhvbGRzLgorICBvcGVyYXRvciBjb25zdCBTRFZhbHVlJigpIGNvbnN0IHsgcmV0dXJuIFZhbDsgfQorCisgIC8vLyBJZiBpbXBsaWNpdCBjb252ZXJzaW9uIHRvIFNEVmFsdWUgZG9lc24ndCB3b3JrLCB0aGUgZ2V0KCkgbWV0aG9kIHJldHVybnMKKyAgLy8vIHRoZSBTRFZhbHVlLgorICBjb25zdCBTRFZhbHVlICZnZXQoKSBjb25zdCB7IHJldHVybiBWYWw7IH0KKworICAvLy8gVGhpcyByZXR1cm5zIHRoZSBTRE5vZGUgdGhhdCBjb250YWlucyB0aGlzIFVzZS4KKyAgU0ROb2RlICpnZXRVc2VyKCkgeyByZXR1cm4gVXNlcjsgfQorCisgIC8vLyBHZXQgdGhlIG5leHQgU0RVc2UgaW4gdGhlIHVzZSBsaXN0LgorICBTRFVzZSAqZ2V0TmV4dCgpIGNvbnN0IHsgcmV0dXJuIE5leHQ7IH0KKworICAvLy8gQ29udmVuaWVuY2UgZnVuY3Rpb24gZm9yIGdldCgpLmdldE5vZGUoKS4KKyAgU0ROb2RlICpnZXROb2RlKCkgY29uc3QgeyByZXR1cm4gVmFsLmdldE5vZGUoKTsgfQorICAvLy8gQ29udmVuaWVuY2UgZnVuY3Rpb24gZm9yIGdldCgpLmdldFJlc05vKCkuCisgIHVuc2lnbmVkIGdldFJlc05vKCkgY29uc3QgeyByZXR1cm4gVmFsLmdldFJlc05vKCk7IH0KKyAgLy8vIENvbnZlbmllbmNlIGZ1bmN0aW9uIGZvciBnZXQoKS5nZXRWYWx1ZVR5cGUoKS4KKyAgRVZUIGdldFZhbHVlVHlwZSgpIGNvbnN0IHsgcmV0dXJuIFZhbC5nZXRWYWx1ZVR5cGUoKTsgfQorCisgIC8vLyBDb252ZW5pZW5jZSBmdW5jdGlvbiBmb3IgZ2V0KCkub3BlcmF0b3I9PQorICBib29sIG9wZXJhdG9yPT0oY29uc3QgU0RWYWx1ZSAmVikgY29uc3QgeworICAgIHJldHVybiBWYWwgPT0gVjsKKyAgfQorCisgIC8vLyBDb252ZW5pZW5jZSBmdW5jdGlvbiBmb3IgZ2V0KCkub3BlcmF0b3IhPQorICBib29sIG9wZXJhdG9yIT0oY29uc3QgU0RWYWx1ZSAmVikgY29uc3QgeworICAgIHJldHVybiBWYWwgIT0gVjsKKyAgfQorCisgIC8vLyBDb252ZW5pZW5jZSBmdW5jdGlvbiBmb3IgZ2V0KCkub3BlcmF0b3I8CisgIGJvb2wgb3BlcmF0b3I8KGNvbnN0IFNEVmFsdWUgJlYpIGNvbnN0IHsKKyAgICByZXR1cm4gVmFsIDwgVjsKKyAgfQorCitwcml2YXRlOgorICBmcmllbmQgY2xhc3MgU2VsZWN0aW9uREFHOworICBmcmllbmQgY2xhc3MgU0ROb2RlOworICAvLyBUT0RPOiB1bmZyaWVuZCBIYW5kbGVTRE5vZGUgb25jZSB3ZSBmaXggaXRzIG9wZXJhbmQgaGFuZGxpbmcuCisgIGZyaWVuZCBjbGFzcyBIYW5kbGVTRE5vZGU7CisKKyAgdm9pZCBzZXRVc2VyKFNETm9kZSAqcCkgeyBVc2VyID0gcDsgfQorCisgIC8vLyBSZW1vdmUgdGhpcyB1c2UgZnJvbSBpdHMgZXhpc3RpbmcgdXNlIGxpc3QsIGFzc2lnbiBpdCB0aGUKKyAgLy8vIGdpdmVuIHZhbHVlLCBhbmQgYWRkIGl0IHRvIHRoZSBuZXcgdmFsdWUncyBub2RlJ3MgdXNlIGxpc3QuCisgIGlubGluZSB2b2lkIHNldChjb25zdCBTRFZhbHVlICZWKTsKKyAgLy8vIExpa2Ugc2V0LCBidXQgb25seSBzdXBwb3J0cyBpbml0aWFsaXppbmcgYSBuZXdseS1hbGxvY2F0ZWQKKyAgLy8vIFNEVXNlIHdpdGggYSBub24tbnVsbCB2YWx1ZS4KKyAgaW5saW5lIHZvaWQgc2V0SW5pdGlhbChjb25zdCBTRFZhbHVlICZWKTsKKyAgLy8vIExpa2Ugc2V0LCBidXQgb25seSBzZXRzIHRoZSBOb2RlIHBvcnRpb24gb2YgdGhlIHZhbHVlLAorICAvLy8gbGVhdmluZyB0aGUgUmVzTm8gcG9ydGlvbiB1bm1vZGlmaWVkLgorICBpbmxpbmUgdm9pZCBzZXROb2RlKFNETm9kZSAqTik7CisKKyAgdm9pZCBhZGRUb0xpc3QoU0RVc2UgKipMaXN0KSB7CisgICAgTmV4dCA9ICpMaXN0OworICAgIGlmIChOZXh0KSBOZXh0LT5QcmV2ID0gJk5leHQ7CisgICAgUHJldiA9IExpc3Q7CisgICAgKkxpc3QgPSB0aGlzOworICB9CisKKyAgdm9pZCByZW1vdmVGcm9tTGlzdCgpIHsKKyAgICAqUHJldiA9IE5leHQ7CisgICAgaWYgKE5leHQpIE5leHQtPlByZXYgPSBQcmV2OworICB9Cit9OworCisvLy8gc2ltcGxpZnlfdHlwZSBzcGVjaWFsaXphdGlvbnMgLSBBbGxvdyBjYXN0aW5nIG9wZXJhdG9ycyB0byB3b3JrIGRpcmVjdGx5IG9uCisvLy8gU0RWYWx1ZXMgYXMgaWYgdGhleSB3ZXJlIFNETm9kZSoncy4KK3RlbXBsYXRlPD4gc3RydWN0IHNpbXBsaWZ5X3R5cGU8U0RVc2U+IHsKKyAgdXNpbmcgU2ltcGxlVHlwZSA9IFNETm9kZSAqOworCisgIHN0YXRpYyBTaW1wbGVUeXBlIGdldFNpbXBsaWZpZWRWYWx1ZShTRFVzZSAmVmFsKSB7CisgICAgcmV0dXJuIFZhbC5nZXROb2RlKCk7CisgIH0KK307CisKKy8vLyBUaGVzZSBhcmUgSVItbGV2ZWwgb3B0aW1pemF0aW9uIGZsYWdzIHRoYXQgbWF5IGJlIHByb3BhZ2F0ZWQgdG8gU0ROb2Rlcy4KKy8vLyBUT0RPOiBUaGlzIGRhdGEgc3RydWN0dXJlIHNob3VsZCBiZSBzaGFyZWQgYnkgdGhlIElSIG9wdGltaXplciBhbmQgdGhlCisvLy8gdGhlIGJhY2tlbmQuCitzdHJ1Y3QgU0ROb2RlRmxhZ3MgeworcHJpdmF0ZToKKyAgLy8gVGhpcyBiaXQgaXMgdXNlZCB0byBkZXRlcm1pbmUgaWYgdGhlIGZsYWdzIGFyZSBpbiBhIGRlZmluZWQgc3RhdGUuCisgIC8vIEZsYWcgYml0cyBjYW4gb25seSBiZSBtYXNrZWQgb3V0IGR1cmluZyBpbnRlcnNlY3Rpb24gaWYgdGhlIG1hc2tpbmcgZmxhZ3MKKyAgLy8gYXJlIGRlZmluZWQuCisgIGJvb2wgQW55RGVmaW5lZCA6IDE7CisKKyAgYm9vbCBOb1Vuc2lnbmVkV3JhcCA6IDE7CisgIGJvb2wgTm9TaWduZWRXcmFwIDogMTsKKyAgYm9vbCBFeGFjdCA6IDE7CisgIGJvb2wgVW5zYWZlQWxnZWJyYSA6IDE7CisgIGJvb2wgTm9OYU5zIDogMTsKKyAgYm9vbCBOb0luZnMgOiAxOworICBib29sIE5vU2lnbmVkWmVyb3MgOiAxOworICBib29sIEFsbG93UmVjaXByb2NhbCA6IDE7CisgIGJvb2wgVmVjdG9yUmVkdWN0aW9uIDogMTsKKyAgYm9vbCBBbGxvd0NvbnRyYWN0IDogMTsKKworcHVibGljOgorICAvLy8gRGVmYXVsdCBjb25zdHJ1Y3RvciB0dXJucyBvZmYgYWxsIG9wdGltaXphdGlvbiBmbGFncy4KKyAgU0ROb2RlRmxhZ3MoKQorICAgICAgOiBBbnlEZWZpbmVkKGZhbHNlKSwgTm9VbnNpZ25lZFdyYXAoZmFsc2UpLCBOb1NpZ25lZFdyYXAoZmFsc2UpLAorICAgICAgICBFeGFjdChmYWxzZSksIFVuc2FmZUFsZ2VicmEoZmFsc2UpLCBOb05hTnMoZmFsc2UpLCBOb0luZnMoZmFsc2UpLAorICAgICAgICBOb1NpZ25lZFplcm9zKGZhbHNlKSwgQWxsb3dSZWNpcHJvY2FsKGZhbHNlKSwgVmVjdG9yUmVkdWN0aW9uKGZhbHNlKSwKKyAgICAgICAgQWxsb3dDb250cmFjdChmYWxzZSkge30KKworICAvLy8gU2V0cyB0aGUgc3RhdGUgb2YgdGhlIGZsYWdzIHRvIHRoZSBkZWZpbmVkIHN0YXRlLgorICB2b2lkIHNldERlZmluZWQoKSB7IEFueURlZmluZWQgPSB0cnVlOyB9CisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIGZsYWdzIGFyZSBpbiBhIGRlZmluZWQgc3RhdGUuCisgIGJvb2wgaXNEZWZpbmVkKCkgY29uc3QgeyByZXR1cm4gQW55RGVmaW5lZDsgfQorCisgIC8vIFRoZXNlIGFyZSBtdXRhdG9ycyBmb3IgZWFjaCBmbGFnLgorICB2b2lkIHNldE5vVW5zaWduZWRXcmFwKGJvb2wgYikgeworICAgIHNldERlZmluZWQoKTsKKyAgICBOb1Vuc2lnbmVkV3JhcCA9IGI7CisgIH0KKyAgdm9pZCBzZXROb1NpZ25lZFdyYXAoYm9vbCBiKSB7CisgICAgc2V0RGVmaW5lZCgpOworICAgIE5vU2lnbmVkV3JhcCA9IGI7CisgIH0KKyAgdm9pZCBzZXRFeGFjdChib29sIGIpIHsKKyAgICBzZXREZWZpbmVkKCk7CisgICAgRXhhY3QgPSBiOworICB9CisgIHZvaWQgc2V0VW5zYWZlQWxnZWJyYShib29sIGIpIHsKKyAgICBzZXREZWZpbmVkKCk7CisgICAgVW5zYWZlQWxnZWJyYSA9IGI7CisgIH0KKyAgdm9pZCBzZXROb05hTnMoYm9vbCBiKSB7CisgICAgc2V0RGVmaW5lZCgpOworICAgIE5vTmFOcyA9IGI7CisgIH0KKyAgdm9pZCBzZXROb0luZnMoYm9vbCBiKSB7CisgICAgc2V0RGVmaW5lZCgpOworICAgIE5vSW5mcyA9IGI7CisgIH0KKyAgdm9pZCBzZXROb1NpZ25lZFplcm9zKGJvb2wgYikgeworICAgIHNldERlZmluZWQoKTsKKyAgICBOb1NpZ25lZFplcm9zID0gYjsKKyAgfQorICB2b2lkIHNldEFsbG93UmVjaXByb2NhbChib29sIGIpIHsKKyAgICBzZXREZWZpbmVkKCk7CisgICAgQWxsb3dSZWNpcHJvY2FsID0gYjsKKyAgfQorICB2b2lkIHNldFZlY3RvclJlZHVjdGlvbihib29sIGIpIHsKKyAgICBzZXREZWZpbmVkKCk7CisgICAgVmVjdG9yUmVkdWN0aW9uID0gYjsKKyAgfQorICB2b2lkIHNldEFsbG93Q29udHJhY3QoYm9vbCBiKSB7CisgICAgc2V0RGVmaW5lZCgpOworICAgIEFsbG93Q29udHJhY3QgPSBiOworICB9CisKKyAgLy8gVGhlc2UgYXJlIGFjY2Vzc29ycyBmb3IgZWFjaCBmbGFnLgorICBib29sIGhhc05vVW5zaWduZWRXcmFwKCkgY29uc3QgeyByZXR1cm4gTm9VbnNpZ25lZFdyYXA7IH0KKyAgYm9vbCBoYXNOb1NpZ25lZFdyYXAoKSBjb25zdCB7IHJldHVybiBOb1NpZ25lZFdyYXA7IH0KKyAgYm9vbCBoYXNFeGFjdCgpIGNvbnN0IHsgcmV0dXJuIEV4YWN0OyB9CisgIGJvb2wgaGFzVW5zYWZlQWxnZWJyYSgpIGNvbnN0IHsgcmV0dXJuIFVuc2FmZUFsZ2VicmE7IH0KKyAgYm9vbCBoYXNOb05hTnMoKSBjb25zdCB7IHJldHVybiBOb05hTnM7IH0KKyAgYm9vbCBoYXNOb0luZnMoKSBjb25zdCB7IHJldHVybiBOb0luZnM7IH0KKyAgYm9vbCBoYXNOb1NpZ25lZFplcm9zKCkgY29uc3QgeyByZXR1cm4gTm9TaWduZWRaZXJvczsgfQorICBib29sIGhhc0FsbG93UmVjaXByb2NhbCgpIGNvbnN0IHsgcmV0dXJuIEFsbG93UmVjaXByb2NhbDsgfQorICBib29sIGhhc1ZlY3RvclJlZHVjdGlvbigpIGNvbnN0IHsgcmV0dXJuIFZlY3RvclJlZHVjdGlvbjsgfQorICBib29sIGhhc0FsbG93Q29udHJhY3QoKSBjb25zdCB7IHJldHVybiBBbGxvd0NvbnRyYWN0OyB9CisKKyAgLy8vIENsZWFyIGFueSBmbGFncyBpbiB0aGlzIGZsYWcgc2V0IHRoYXQgYXJlbid0IGFsc28gc2V0IGluIEZsYWdzLgorICAvLy8gSWYgdGhlIGdpdmVuIEZsYWdzIGFyZSB1bmRlZmluZWQgdGhlbiBkb24ndCBkbyBhbnl0aGluZy4KKyAgdm9pZCBpbnRlcnNlY3RXaXRoKGNvbnN0IFNETm9kZUZsYWdzIEZsYWdzKSB7CisgICAgaWYgKCFGbGFncy5pc0RlZmluZWQoKSkKKyAgICAgIHJldHVybjsKKyAgICBOb1Vuc2lnbmVkV3JhcCAmPSBGbGFncy5Ob1Vuc2lnbmVkV3JhcDsKKyAgICBOb1NpZ25lZFdyYXAgJj0gRmxhZ3MuTm9TaWduZWRXcmFwOworICAgIEV4YWN0ICY9IEZsYWdzLkV4YWN0OworICAgIFVuc2FmZUFsZ2VicmEgJj0gRmxhZ3MuVW5zYWZlQWxnZWJyYTsKKyAgICBOb05hTnMgJj0gRmxhZ3MuTm9OYU5zOworICAgIE5vSW5mcyAmPSBGbGFncy5Ob0luZnM7CisgICAgTm9TaWduZWRaZXJvcyAmPSBGbGFncy5Ob1NpZ25lZFplcm9zOworICAgIEFsbG93UmVjaXByb2NhbCAmPSBGbGFncy5BbGxvd1JlY2lwcm9jYWw7CisgICAgVmVjdG9yUmVkdWN0aW9uICY9IEZsYWdzLlZlY3RvclJlZHVjdGlvbjsKKyAgICBBbGxvd0NvbnRyYWN0ICY9IEZsYWdzLkFsbG93Q29udHJhY3Q7CisgIH0KK307CisKKy8vLyBSZXByZXNlbnRzIG9uZSBub2RlIGluIHRoZSBTZWxlY3Rpb25EQUcuCisvLy8KK2NsYXNzIFNETm9kZSA6IHB1YmxpYyBGb2xkaW5nU2V0Tm9kZSwgcHVibGljIGlsaXN0X25vZGU8U0ROb2RlPiB7Citwcml2YXRlOgorICAvLy8gVGhlIG9wZXJhdGlvbiB0aGF0IHRoaXMgbm9kZSBwZXJmb3Jtcy4KKyAgaW50MTZfdCBOb2RlVHlwZTsKKworcHJvdGVjdGVkOgorICAvLyBXZSBkZWZpbmUgYSBzZXQgb2YgbWluaS1oZWxwZXIgY2xhc3NlcyB0byBoZWxwIHVzIGludGVycHJldCB0aGUgYml0cyBpbiBvdXIKKyAgLy8gU3ViY2xhc3NEYXRhLiAgVGhlc2UgYXJlIGRlc2lnbmVkIHRvIGZpdCB3aXRoaW4gYSB1aW50MTZfdCBzbyB0aGV5IHBhY2sKKyAgLy8gd2l0aCBOb2RlVHlwZS4KKworICBjbGFzcyBTRE5vZGVCaXRmaWVsZHMgeworICAgIGZyaWVuZCBjbGFzcyBTRE5vZGU7CisgICAgZnJpZW5kIGNsYXNzIE1lbUludHJpbnNpY1NETm9kZTsKKyAgICBmcmllbmQgY2xhc3MgTWVtU0ROb2RlOworICAgIGZyaWVuZCBjbGFzcyBTZWxlY3Rpb25EQUc7CisKKyAgICB1aW50MTZfdCBIYXNEZWJ1Z1ZhbHVlIDogMTsKKyAgICB1aW50MTZfdCBJc01lbUludHJpbnNpYyA6IDE7CisgICAgdWludDE2X3QgSXNEaXZlcmdlbnQgOiAxOworICB9OworICBlbnVtIHsgTnVtU0ROb2RlQml0cyA9IDMgfTsKKworICBjbGFzcyBDb25zdGFudFNETm9kZUJpdGZpZWxkcyB7CisgICAgZnJpZW5kIGNsYXNzIENvbnN0YW50U0ROb2RlOworCisgICAgdWludDE2X3QgOiBOdW1TRE5vZGVCaXRzOworCisgICAgdWludDE2X3QgSXNPcGFxdWUgOiAxOworICB9OworCisgIGNsYXNzIE1lbVNETm9kZUJpdGZpZWxkcyB7CisgICAgZnJpZW5kIGNsYXNzIE1lbVNETm9kZTsKKyAgICBmcmllbmQgY2xhc3MgTWVtSW50cmluc2ljU0ROb2RlOworICAgIGZyaWVuZCBjbGFzcyBBdG9taWNTRE5vZGU7CisKKyAgICB1aW50MTZfdCA6IE51bVNETm9kZUJpdHM7CisKKyAgICB1aW50MTZfdCBJc1ZvbGF0aWxlIDogMTsKKyAgICB1aW50MTZfdCBJc05vblRlbXBvcmFsIDogMTsKKyAgICB1aW50MTZfdCBJc0RlcmVmZXJlbmNlYWJsZSA6IDE7CisgICAgdWludDE2X3QgSXNJbnZhcmlhbnQgOiAxOworICB9OworICBlbnVtIHsgTnVtTWVtU0ROb2RlQml0cyA9IE51bVNETm9kZUJpdHMgKyA0IH07CisKKyAgY2xhc3MgTFNCYXNlU0ROb2RlQml0ZmllbGRzIHsKKyAgICBmcmllbmQgY2xhc3MgTFNCYXNlU0ROb2RlOworCisgICAgdWludDE2X3QgOiBOdW1NZW1TRE5vZGVCaXRzOworCisgICAgdWludDE2X3QgQWRkcmVzc2luZ01vZGUgOiAzOyAvLyBlbnVtIElTRDo6TWVtSW5kZXhlZE1vZGUKKyAgfTsKKyAgZW51bSB7IE51bUxTQmFzZVNETm9kZUJpdHMgPSBOdW1NZW1TRE5vZGVCaXRzICsgMyB9OworCisgIGNsYXNzIExvYWRTRE5vZGVCaXRmaWVsZHMgeworICAgIGZyaWVuZCBjbGFzcyBMb2FkU0ROb2RlOworICAgIGZyaWVuZCBjbGFzcyBNYXNrZWRMb2FkU0ROb2RlOworCisgICAgdWludDE2X3QgOiBOdW1MU0Jhc2VTRE5vZGVCaXRzOworCisgICAgdWludDE2X3QgRXh0VHkgOiAyOyAvLyBlbnVtIElTRDo6TG9hZEV4dFR5cGUKKyAgICB1aW50MTZfdCBJc0V4cGFuZGluZyA6IDE7CisgIH07CisKKyAgY2xhc3MgU3RvcmVTRE5vZGVCaXRmaWVsZHMgeworICAgIGZyaWVuZCBjbGFzcyBTdG9yZVNETm9kZTsKKyAgICBmcmllbmQgY2xhc3MgTWFza2VkU3RvcmVTRE5vZGU7CisKKyAgICB1aW50MTZfdCA6IE51bUxTQmFzZVNETm9kZUJpdHM7CisKKyAgICB1aW50MTZfdCBJc1RydW5jYXRpbmcgOiAxOworICAgIHVpbnQxNl90IElzQ29tcHJlc3NpbmcgOiAxOworICB9OworCisgIHVuaW9uIHsKKyAgICBjaGFyIFJhd1NETm9kZUJpdHNbc2l6ZW9mKHVpbnQxNl90KV07CisgICAgU0ROb2RlQml0ZmllbGRzIFNETm9kZUJpdHM7CisgICAgQ29uc3RhbnRTRE5vZGVCaXRmaWVsZHMgQ29uc3RhbnRTRE5vZGVCaXRzOworICAgIE1lbVNETm9kZUJpdGZpZWxkcyBNZW1TRE5vZGVCaXRzOworICAgIExTQmFzZVNETm9kZUJpdGZpZWxkcyBMU0Jhc2VTRE5vZGVCaXRzOworICAgIExvYWRTRE5vZGVCaXRmaWVsZHMgTG9hZFNETm9kZUJpdHM7CisgICAgU3RvcmVTRE5vZGVCaXRmaWVsZHMgU3RvcmVTRE5vZGVCaXRzOworICB9OworCisgIC8vIFJhd1NETm9kZUJpdHMgbXVzdCBjb3ZlciB0aGUgZW50aXJldHkgb2YgdGhlIHVuaW9uLiAgVGhpcyBtZWFucyB0aGF0IGFsbCBvZgorICAvLyB0aGUgdW5pb24ncyBtZW1iZXJzIG11c3QgaGF2ZSBzaXplIDw9IFJhd1NETm9kZUJpdHMuICBXZSB3cml0ZSB0aGUgUkhTIGFzCisgIC8vICIyIiBpbnN0ZWFkIG9mIHNpemVvZihSYXdTRE5vZGVCaXRzKSBiZWNhdXNlIE1TVkMgY2FuJ3QgaGFuZGxlIHRoZSBsYXR0ZXIuCisgIHN0YXRpY19hc3NlcnQoc2l6ZW9mKFNETm9kZUJpdGZpZWxkcykgPD0gMiwgImZpZWxkIHRvbyB3aWRlIik7CisgIHN0YXRpY19hc3NlcnQoc2l6ZW9mKENvbnN0YW50U0ROb2RlQml0ZmllbGRzKSA8PSAyLCAiZmllbGQgdG9vIHdpZGUiKTsKKyAgc3RhdGljX2Fzc2VydChzaXplb2YoTWVtU0ROb2RlQml0ZmllbGRzKSA8PSAyLCAiZmllbGQgdG9vIHdpZGUiKTsKKyAgc3RhdGljX2Fzc2VydChzaXplb2YoTFNCYXNlU0ROb2RlQml0ZmllbGRzKSA8PSAyLCAiZmllbGQgdG9vIHdpZGUiKTsKKyAgc3RhdGljX2Fzc2VydChzaXplb2YoTG9hZFNETm9kZUJpdGZpZWxkcykgPD0gNCwgImZpZWxkIHRvbyB3aWRlIik7CisgIHN0YXRpY19hc3NlcnQoc2l6ZW9mKFN0b3JlU0ROb2RlQml0ZmllbGRzKSA8PSAyLCAiZmllbGQgdG9vIHdpZGUiKTsKKworcHJpdmF0ZToKKyAgZnJpZW5kIGNsYXNzIFNlbGVjdGlvbkRBRzsKKyAgLy8gVE9ETzogdW5mcmllbmQgSGFuZGxlU0ROb2RlIG9uY2Ugd2UgZml4IGl0cyBvcGVyYW5kIGhhbmRsaW5nLgorICBmcmllbmQgY2xhc3MgSGFuZGxlU0ROb2RlOworCisgIC8vLyBVbmlxdWUgaWQgcGVyIFNETm9kZSBpbiB0aGUgREFHLgorICBpbnQgTm9kZUlkID0gLTE7CisKKyAgLy8vIFRoZSB2YWx1ZXMgdGhhdCBhcmUgdXNlZCBieSB0aGlzIG9wZXJhdGlvbi4KKyAgU0RVc2UgKk9wZXJhbmRMaXN0ID0gbnVsbHB0cjsKKworICAvLy8gVGhlIHR5cGVzIG9mIHRoZSB2YWx1ZXMgdGhpcyBub2RlIGRlZmluZXMuICBTRE5vZGUncyBtYXkKKyAgLy8vIGRlZmluZSBtdWx0aXBsZSB2YWx1ZXMgc2ltdWx0YW5lb3VzbHkuCisgIGNvbnN0IEVWVCAqVmFsdWVMaXN0OworCisgIC8vLyBMaXN0IG9mIHVzZXMgZm9yIHRoaXMgU0ROb2RlLgorICBTRFVzZSAqVXNlTGlzdCA9IG51bGxwdHI7CisKKyAgLy8vIFRoZSBudW1iZXIgb2YgZW50cmllcyBpbiB0aGUgT3BlcmFuZC9WYWx1ZSBsaXN0LgorICB1bnNpZ25lZCBzaG9ydCBOdW1PcGVyYW5kcyA9IDA7CisgIHVuc2lnbmVkIHNob3J0IE51bVZhbHVlczsKKworICAvLyBUaGUgb3JkZXJpbmcgb2YgdGhlIFNETm9kZXMuIEl0IHJvdWdobHkgY29ycmVzcG9uZHMgdG8gdGhlIG9yZGVyaW5nIG9mIHRoZQorICAvLyBvcmlnaW5hbCBMTFZNIGluc3RydWN0aW9ucy4KKyAgLy8gVGhpcyBpcyB1c2VkIGZvciB0dXJuaW5nIG9mZiBzY2hlZHVsaW5nLCBiZWNhdXNlIHdlJ2xsIGZvcmdvCisgIC8vIHRoZSBub3JtYWwgc2NoZWR1bGluZyBhbGdvcml0aG1zIGFuZCBvdXRwdXQgdGhlIGluc3RydWN0aW9ucyBhY2NvcmRpbmcgdG8KKyAgLy8gdGhpcyBvcmRlcmluZy4KKyAgdW5zaWduZWQgSVJPcmRlcjsKKworICAvLy8gU291cmNlIGxpbmUgaW5mb3JtYXRpb24uCisgIERlYnVnTG9jIGRlYnVnTG9jOworCisgIC8vLyBSZXR1cm4gYSBwb2ludGVyIHRvIHRoZSBzcGVjaWZpZWQgdmFsdWUgdHlwZS4KKyAgc3RhdGljIGNvbnN0IEVWVCAqZ2V0VmFsdWVUeXBlTGlzdChFVlQgVlQpOworCisgIFNETm9kZUZsYWdzIEZsYWdzOworCitwdWJsaWM6CisgIC8vLyBVbmlxdWUgYW5kIHBlcnNpc3RlbnQgaWQgcGVyIFNETm9kZSBpbiB0aGUgREFHLgorICAvLy8gVXNlZCBmb3IgZGVidWcgcHJpbnRpbmcuCisgIHVpbnQxNl90IFBlcnNpc3RlbnRJZDsKKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gIEFjY2Vzc29ycworICAvLworCisgIC8vLyBSZXR1cm4gdGhlIFNlbGVjdGlvbkRBRyBvcGNvZGUgdmFsdWUgZm9yIHRoaXMgbm9kZS4gRm9yCisgIC8vLyBwcmUtaXNlbCBub2RlcyAodGhvc2UgZm9yIHdoaWNoIGlzTWFjaGluZU9wY29kZSByZXR1cm5zIGZhbHNlKSwgdGhlc2UKKyAgLy8vIGFyZSB0aGUgb3Bjb2RlIHZhbHVlcyBpbiB0aGUgSVNEIGFuZCA8dGFyZ2V0PklTRCBuYW1lc3BhY2VzLiBGb3IKKyAgLy8vIHBvc3QtaXNlbCBvcGNvZGVzLCBzZWUgZ2V0TWFjaGluZU9wY29kZS4KKyAgdW5zaWduZWQgZ2V0T3Bjb2RlKCkgIGNvbnN0IHsgcmV0dXJuICh1bnNpZ25lZCBzaG9ydClOb2RlVHlwZTsgfQorCisgIC8vLyBUZXN0IGlmIHRoaXMgbm9kZSBoYXMgYSB0YXJnZXQtc3BlY2lmaWMgb3Bjb2RlIChpbiB0aGUKKyAgLy8vIFw8dGFyZ2V0XD5JU0QgbmFtZXNwYWNlKS4KKyAgYm9vbCBpc1RhcmdldE9wY29kZSgpIGNvbnN0IHsgcmV0dXJuIE5vZGVUeXBlID49IElTRDo6QlVJTFRJTl9PUF9FTkQ7IH0KKworICAvLy8gVGVzdCBpZiB0aGlzIG5vZGUgaGFzIGEgdGFyZ2V0LXNwZWNpZmljCisgIC8vLyBtZW1vcnktcmVmZXJlbmNpbmcgb3Bjb2RlIChpbiB0aGUgXDx0YXJnZXRcPklTRCBuYW1lc3BhY2UgYW5kCisgIC8vLyBncmVhdGVyIHRoYW4gRklSU1RfVEFSR0VUX01FTU9SWV9PUENPREUpLgorICBib29sIGlzVGFyZ2V0TWVtb3J5T3Bjb2RlKCkgY29uc3QgeworICAgIHJldHVybiBOb2RlVHlwZSA+PSBJU0Q6OkZJUlNUX1RBUkdFVF9NRU1PUllfT1BDT0RFOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSB0eXBlIG9mIHRoZSBub2RlIHR5cGUgdW5kZWZpbmVkLgorICBib29sIGlzVW5kZWYoKSBjb25zdCB7IHJldHVybiBOb2RlVHlwZSA9PSBJU0Q6OlVOREVGOyB9CisKKyAgLy8vIFRlc3QgaWYgdGhpcyBub2RlIGlzIGEgbWVtb3J5IGludHJpbnNpYyAod2l0aCB2YWxpZCBwb2ludGVyIGluZm9ybWF0aW9uKS4KKyAgLy8vIElOVFJJTlNJQ19XX0NIQUlOIGFuZCBJTlRSSU5TSUNfVk9JRCBub2RlcyBhcmUgc29tZXRpbWVzIGNyZWF0ZWQgZm9yCisgIC8vLyBub24tbWVtb3J5IGludHJpbnNpY3MgKHdpdGggY2hhaW5zKSB0aGF0IGFyZSBub3QgcmVhbGx5IGluc3RhbmNlcyBvZgorICAvLy8gTWVtU0ROb2RlLiBGb3Igc3VjaCBub2Rlcywgd2UgbmVlZCBzb21lIGV4dHJhIHN0YXRlIHRvIGRldGVybWluZSB0aGUKKyAgLy8vIHByb3BlciBjbGFzc29mIHJlbGF0aW9uc2hpcC4KKyAgYm9vbCBpc01lbUludHJpbnNpYygpIGNvbnN0IHsKKyAgICByZXR1cm4gKE5vZGVUeXBlID09IElTRDo6SU5UUklOU0lDX1dfQ0hBSU4gfHwKKyAgICAgICAgICAgIE5vZGVUeXBlID09IElTRDo6SU5UUklOU0lDX1ZPSUQpICYmCisgICAgICAgICAgIFNETm9kZUJpdHMuSXNNZW1JbnRyaW5zaWM7CisgIH0KKworICAvLy8gVGVzdCBpZiB0aGlzIG5vZGUgaXMgYSBzdHJpY3QgZmxvYXRpbmcgcG9pbnQgcHNldWRvLW9wLgorICBib29sIGlzU3RyaWN0RlBPcGNvZGUoKSB7CisgICAgc3dpdGNoIChOb2RlVHlwZSkgeworICAgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIGZhbHNlOworICAgICAgY2FzZSBJU0Q6OlNUUklDVF9GQUREOgorICAgICAgY2FzZSBJU0Q6OlNUUklDVF9GU1VCOgorICAgICAgY2FzZSBJU0Q6OlNUUklDVF9GTVVMOgorICAgICAgY2FzZSBJU0Q6OlNUUklDVF9GRElWOgorICAgICAgY2FzZSBJU0Q6OlNUUklDVF9GUkVNOgorICAgICAgY2FzZSBJU0Q6OlNUUklDVF9GTUE6CisgICAgICBjYXNlIElTRDo6U1RSSUNUX0ZTUVJUOgorICAgICAgY2FzZSBJU0Q6OlNUUklDVF9GUE9XOgorICAgICAgY2FzZSBJU0Q6OlNUUklDVF9GUE9XSToKKyAgICAgIGNhc2UgSVNEOjpTVFJJQ1RfRlNJTjoKKyAgICAgIGNhc2UgSVNEOjpTVFJJQ1RfRkNPUzoKKyAgICAgIGNhc2UgSVNEOjpTVFJJQ1RfRkVYUDoKKyAgICAgIGNhc2UgSVNEOjpTVFJJQ1RfRkVYUDI6CisgICAgICBjYXNlIElTRDo6U1RSSUNUX0ZMT0c6CisgICAgICBjYXNlIElTRDo6U1RSSUNUX0ZMT0cxMDoKKyAgICAgIGNhc2UgSVNEOjpTVFJJQ1RfRkxPRzI6CisgICAgICBjYXNlIElTRDo6U1RSSUNUX0ZSSU5UOgorICAgICAgY2FzZSBJU0Q6OlNUUklDVF9GTkVBUkJZSU5UOgorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICB9CisgIH0KKworICAvLy8gVGVzdCBpZiB0aGlzIG5vZGUgaGFzIGEgcG9zdC1pc2VsIG9wY29kZSwgZGlyZWN0bHkKKyAgLy8vIGNvcnJlc3BvbmRpbmcgdG8gYSBNYWNoaW5lSW5zdHIgb3Bjb2RlLgorICBib29sIGlzTWFjaGluZU9wY29kZSgpIGNvbnN0IHsgcmV0dXJuIE5vZGVUeXBlIDwgMDsgfQorCisgIC8vLyBUaGlzIG1heSBvbmx5IGJlIGNhbGxlZCBpZiBpc01hY2hpbmVPcGNvZGUgcmV0dXJucworICAvLy8gdHJ1ZS4gSXQgcmV0dXJucyB0aGUgTWFjaGluZUluc3RyIG9wY29kZSB2YWx1ZSB0aGF0IHRoZSBub2RlJ3Mgb3Bjb2RlCisgIC8vLyBjb3JyZXNwb25kcyB0by4KKyAgdW5zaWduZWQgZ2V0TWFjaGluZU9wY29kZSgpIGNvbnN0IHsKKyAgICBhc3NlcnQoaXNNYWNoaW5lT3Bjb2RlKCkgJiYgIk5vdCBhIE1hY2hpbmVJbnN0ciBvcGNvZGUhIik7CisgICAgcmV0dXJuIH5Ob2RlVHlwZTsKKyAgfQorCisgIGJvb2wgZ2V0SGFzRGVidWdWYWx1ZSgpIGNvbnN0IHsgcmV0dXJuIFNETm9kZUJpdHMuSGFzRGVidWdWYWx1ZTsgfQorICB2b2lkIHNldEhhc0RlYnVnVmFsdWUoYm9vbCBiKSB7IFNETm9kZUJpdHMuSGFzRGVidWdWYWx1ZSA9IGI7IH0KKworICBib29sIGlzRGl2ZXJnZW50KCkgY29uc3QgeyByZXR1cm4gU0ROb2RlQml0cy5Jc0RpdmVyZ2VudDsgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGVyZSBhcmUgbm8gdXNlcyBvZiB0aGlzIG5vZGUuCisgIGJvb2wgdXNlX2VtcHR5KCkgY29uc3QgeyByZXR1cm4gVXNlTGlzdCA9PSBudWxscHRyOyB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZXJlIGlzIGV4YWN0bHkgb25lIHVzZSBvZiB0aGlzIG5vZGUuCisgIGJvb2wgaGFzT25lVXNlKCkgY29uc3QgeworICAgIHJldHVybiAhdXNlX2VtcHR5KCkgJiYgc3RkOjpuZXh0KHVzZV9iZWdpbigpKSA9PSB1c2VfZW5kKCk7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgdXNlcyBvZiB0aGlzIG5vZGUuIFRoaXMgbWV0aG9kIHRha2VzCisgIC8vLyB0aW1lIHByb3BvcnRpb25hbCB0byB0aGUgbnVtYmVyIG9mIHVzZXMuCisgIHNpemVfdCB1c2Vfc2l6ZSgpIGNvbnN0IHsgcmV0dXJuIHN0ZDo6ZGlzdGFuY2UodXNlX2JlZ2luKCksIHVzZV9lbmQoKSk7IH0KKworICAvLy8gUmV0dXJuIHRoZSB1bmlxdWUgbm9kZSBpZC4KKyAgaW50IGdldE5vZGVJZCgpIGNvbnN0IHsgcmV0dXJuIE5vZGVJZDsgfQorCisgIC8vLyBTZXQgdW5pcXVlIG5vZGUgaWQuCisgIHZvaWQgc2V0Tm9kZUlkKGludCBJZCkgeyBOb2RlSWQgPSBJZDsgfQorCisgIC8vLyBSZXR1cm4gdGhlIG5vZGUgb3JkZXJpbmcuCisgIHVuc2lnbmVkIGdldElST3JkZXIoKSBjb25zdCB7IHJldHVybiBJUk9yZGVyOyB9CisKKyAgLy8vIFNldCB0aGUgbm9kZSBvcmRlcmluZy4KKyAgdm9pZCBzZXRJUk9yZGVyKHVuc2lnbmVkIE9yZGVyKSB7IElST3JkZXIgPSBPcmRlcjsgfQorCisgIC8vLyBSZXR1cm4gdGhlIHNvdXJjZSBsb2NhdGlvbiBpbmZvLgorICBjb25zdCBEZWJ1Z0xvYyAmZ2V0RGVidWdMb2MoKSBjb25zdCB7IHJldHVybiBkZWJ1Z0xvYzsgfQorCisgIC8vLyBTZXQgc291cmNlIGxvY2F0aW9uIGluZm8uICBUcnkgdG8gYXZvaWQgdGhpcywgcHV0dGluZworICAvLy8gaXQgaW4gdGhlIGNvbnN0cnVjdG9yIGlzIHByZWZlcmFibGUuCisgIHZvaWQgc2V0RGVidWdMb2MoRGVidWdMb2MgZGwpIHsgZGVidWdMb2MgPSBzdGQ6Om1vdmUoZGwpOyB9CisKKyAgLy8vIFRoaXMgY2xhc3MgcHJvdmlkZXMgaXRlcmF0b3Igc3VwcG9ydCBmb3IgU0RVc2UKKyAgLy8vIG9wZXJhbmRzIHRoYXQgdXNlIGEgc3BlY2lmaWMgU0ROb2RlLgorICBjbGFzcyB1c2VfaXRlcmF0b3IKKyAgICA6IHB1YmxpYyBzdGQ6Oml0ZXJhdG9yPHN0ZDo6Zm9yd2FyZF9pdGVyYXRvcl90YWcsIFNEVXNlLCBwdHJkaWZmX3Q+IHsKKyAgICBmcmllbmQgY2xhc3MgU0ROb2RlOworCisgICAgU0RVc2UgKk9wID0gbnVsbHB0cjsKKworICAgIGV4cGxpY2l0IHVzZV9pdGVyYXRvcihTRFVzZSAqb3ApIDogT3Aob3ApIHt9CisKKyAgcHVibGljOgorICAgIHVzaW5nIHJlZmVyZW5jZSA9IHN0ZDo6aXRlcmF0b3I8c3RkOjpmb3J3YXJkX2l0ZXJhdG9yX3RhZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNEVXNlLCBwdHJkaWZmX3Q+OjpyZWZlcmVuY2U7CisgICAgdXNpbmcgcG9pbnRlciA9IHN0ZDo6aXRlcmF0b3I8c3RkOjpmb3J3YXJkX2l0ZXJhdG9yX3RhZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRFVzZSwgcHRyZGlmZl90Pjo6cG9pbnRlcjsKKworICAgIHVzZV9pdGVyYXRvcigpID0gZGVmYXVsdDsKKyAgICB1c2VfaXRlcmF0b3IoY29uc3QgdXNlX2l0ZXJhdG9yICZJKSA6IE9wKEkuT3ApIHt9CisKKyAgICBib29sIG9wZXJhdG9yPT0oY29uc3QgdXNlX2l0ZXJhdG9yICZ4KSBjb25zdCB7CisgICAgICByZXR1cm4gT3AgPT0geC5PcDsKKyAgICB9CisgICAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IHVzZV9pdGVyYXRvciAmeCkgY29uc3QgeworICAgICAgcmV0dXJuICFvcGVyYXRvcj09KHgpOworICAgIH0KKworICAgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGl0ZXJhdG9yIGlzIGF0IHRoZSBlbmQgb2YgdXNlcyBsaXN0LgorICAgIGJvb2wgYXRFbmQoKSBjb25zdCB7IHJldHVybiBPcCA9PSBudWxscHRyOyB9CisKKyAgICAvLyBJdGVyYXRvciB0cmF2ZXJzYWw6IGZvcndhcmQgaXRlcmF0aW9uIG9ubHkuCisgICAgdXNlX2l0ZXJhdG9yICZvcGVyYXRvcisrKCkgeyAgICAgICAgICAvLyBQcmVpbmNyZW1lbnQKKyAgICAgIGFzc2VydChPcCAmJiAiQ2Fubm90IGluY3JlbWVudCBlbmQgaXRlcmF0b3IhIik7CisgICAgICBPcCA9IE9wLT5nZXROZXh0KCk7CisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorCisgICAgdXNlX2l0ZXJhdG9yIG9wZXJhdG9yKysoaW50KSB7ICAgICAgICAvLyBQb3N0aW5jcmVtZW50CisgICAgICB1c2VfaXRlcmF0b3IgdG1wID0gKnRoaXM7ICsrKnRoaXM7IHJldHVybiB0bXA7CisgICAgfQorCisgICAgLy8vIFJldHJpZXZlIGEgcG9pbnRlciB0byB0aGUgY3VycmVudCB1c2VyIG5vZGUuCisgICAgU0ROb2RlICpvcGVyYXRvciooKSBjb25zdCB7CisgICAgICBhc3NlcnQoT3AgJiYgIkNhbm5vdCBkZXJlZmVyZW5jZSBlbmQgaXRlcmF0b3IhIik7CisgICAgICByZXR1cm4gT3AtPmdldFVzZXIoKTsKKyAgICB9CisKKyAgICBTRE5vZGUgKm9wZXJhdG9yLT4oKSBjb25zdCB7IHJldHVybiBvcGVyYXRvciooKTsgfQorCisgICAgU0RVc2UgJmdldFVzZSgpIGNvbnN0IHsgcmV0dXJuICpPcDsgfQorCisgICAgLy8vIFJldHJpZXZlIHRoZSBvcGVyYW5kICMgb2YgdGhpcyB1c2UgaW4gaXRzIHVzZXIuCisgICAgdW5zaWduZWQgZ2V0T3BlcmFuZE5vKCkgY29uc3QgeworICAgICAgYXNzZXJ0KE9wICYmICJDYW5ub3QgZGVyZWZlcmVuY2UgZW5kIGl0ZXJhdG9yISIpOworICAgICAgcmV0dXJuICh1bnNpZ25lZCkoT3AgLSBPcC0+Z2V0VXNlcigpLT5PcGVyYW5kTGlzdCk7CisgICAgfQorICB9OworCisgIC8vLyBQcm92aWRlIGl0ZXJhdGlvbiBzdXBwb3J0IHRvIHdhbGsgb3ZlciBhbGwgdXNlcyBvZiBhbiBTRE5vZGUuCisgIHVzZV9pdGVyYXRvciB1c2VfYmVnaW4oKSBjb25zdCB7CisgICAgcmV0dXJuIHVzZV9pdGVyYXRvcihVc2VMaXN0KTsKKyAgfQorCisgIHN0YXRpYyB1c2VfaXRlcmF0b3IgdXNlX2VuZCgpIHsgcmV0dXJuIHVzZV9pdGVyYXRvcihudWxscHRyKTsgfQorCisgIGlubGluZSBpdGVyYXRvcl9yYW5nZTx1c2VfaXRlcmF0b3I+IHVzZXMoKSB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2UodXNlX2JlZ2luKCksIHVzZV9lbmQoKSk7CisgIH0KKyAgaW5saW5lIGl0ZXJhdG9yX3JhbmdlPHVzZV9pdGVyYXRvcj4gdXNlcygpIGNvbnN0IHsKKyAgICByZXR1cm4gbWFrZV9yYW5nZSh1c2VfYmVnaW4oKSwgdXNlX2VuZCgpKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGVyZSBhcmUgZXhhY3RseSBOVVNFUyB1c2VzIG9mIHRoZSBpbmRpY2F0ZWQgdmFsdWUuCisgIC8vLyBUaGlzIG1ldGhvZCBpZ25vcmVzIHVzZXMgb2Ygb3RoZXIgdmFsdWVzIGRlZmluZWQgYnkgdGhpcyBvcGVyYXRpb24uCisgIGJvb2wgaGFzTlVzZXNPZlZhbHVlKHVuc2lnbmVkIE5Vc2VzLCB1bnNpZ25lZCBWYWx1ZSkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZXJlIGFyZSBhbnkgdXNlIG9mIHRoZSBpbmRpY2F0ZWQgdmFsdWUuCisgIC8vLyBUaGlzIG1ldGhvZCBpZ25vcmVzIHVzZXMgb2Ygb3RoZXIgdmFsdWVzIGRlZmluZWQgYnkgdGhpcyBvcGVyYXRpb24uCisgIGJvb2wgaGFzQW55VXNlT2ZWYWx1ZSh1bnNpZ25lZCBWYWx1ZSkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgbm9kZSBpcyB0aGUgb25seSB1c2Ugb2YgTi4KKyAgYm9vbCBpc09ubHlVc2VyT2YoY29uc3QgU0ROb2RlICpOKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBub2RlIGlzIGFuIG9wZXJhbmQgb2YgTi4KKyAgYm9vbCBpc09wZXJhbmRPZihjb25zdCBTRE5vZGUgKk4pIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIG5vZGUgaXMgYSBwcmVkZWNlc3NvciBvZiBOLgorICAvLy8gTk9URTogSW1wbGVtZW50ZWQgb24gdG9wIG9mIGhhc1ByZWRlY2Vzc29yIGFuZCBldmVyeSBiaXQgYXMKKyAgLy8vIGV4cGVuc2l2ZS4gVXNlIGNhcmVmdWxseS4KKyAgYm9vbCBpc1ByZWRlY2Vzc29yT2YoY29uc3QgU0ROb2RlICpOKSBjb25zdCB7CisgICAgcmV0dXJuIE4tPmhhc1ByZWRlY2Vzc29yKHRoaXMpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIE4gaXMgYSBwcmVkZWNlc3NvciBvZiB0aGlzIG5vZGUuCisgIC8vLyBOIGlzIGVpdGhlciBhbiBvcGVyYW5kIG9mIHRoaXMgbm9kZSwgb3IgY2FuIGJlIHJlYWNoZWQgYnkgcmVjdXJzaXZlbHkKKyAgLy8vIHRyYXZlcnNpbmcgdXAgdGhlIG9wZXJhbmRzLgorICAvLy8gTk9URTogVGhpcyBpcyBhbiBleHBlbnNpdmUgbWV0aG9kLiBVc2UgaXQgY2FyZWZ1bGx5LgorICBib29sIGhhc1ByZWRlY2Vzc29yKGNvbnN0IFNETm9kZSAqTikgY29uc3Q7CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiBOIGlzIGEgcHJlZGVjZXNzb3Igb2YgYW55IG5vZGUgaW4gV29ya2xpc3QuIFRoaXMKKyAgLy8vIGhlbHBlciBrZWVwcyBWaXNpdGVkIGFuZCBXb3JrbGlzdCBzZXRzIGV4dGVybmFsbHkgdG8gYWxsb3cgdW5pb25zCisgIC8vLyBzZWFyY2hlcyB0byBiZSBwZXJmb3JtZWQgaW4gcGFyYWxsZWwsIGNhY2hpbmcgb2YgcmVzdWx0cyBhY3Jvc3MKKyAgLy8vIHF1ZXJpZXMgYW5kIGluY3JlbWVudGFsIGFkZGl0aW9uIHRvIFdvcmtsaXN0LiBTdG9wcyBlYXJseSBpZiBOIGlzCisgIC8vLyBmb3VuZCBidXQgd2lsbCByZXN1bWUuIFJlbWVtYmVyIHRvIGNsZWFyIFZpc2l0ZWQgYW5kIFdvcmtsaXN0cworICAvLy8gaWYgREFHIGNoYW5nZXMuIE1heFN0ZXBzIGdpdmVzIGEgbWF4aW11bSBudW1iZXIgb2Ygbm9kZXMgdG8gdmlzaXQgYmVmb3JlCisgIC8vLyBnaXZpbmcgdXAuIFRoZSBUb3BvbG9naWNhbFBydW5lIGZsYWcgc2lnbmFscyB0aGF0IHBvc2l0aXZlIE5vZGVJZHMgYXJlCisgIC8vLyB0b3BvbG9naWNhbGx5IG9yZGVyZWQgKE9wZXJhbmRzIGhhdmUgc3RyaWN0bHkgc21hbGxlciBub2RlIGlkKSBhbmQgc2VhcmNoCisgIC8vLyBjYW4gYmUgcHJ1bmVkIGxldmVyYWdpbmcgdGhpcy4KKyAgc3RhdGljIGJvb2wgaGFzUHJlZGVjZXNzb3JIZWxwZXIoY29uc3QgU0ROb2RlICpOLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFB0clNldEltcGw8Y29uc3QgU0ROb2RlICo+ICZWaXNpdGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8Y29uc3QgU0ROb2RlICo+ICZXb3JrbGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IE1heFN0ZXBzID0gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBUb3BvbG9naWNhbFBydW5lID0gZmFsc2UpIHsKKyAgICBTbWFsbFZlY3Rvcjxjb25zdCBTRE5vZGUgKiwgOD4gRGVmZXJyZWROb2RlczsKKyAgICBpZiAoVmlzaXRlZC5jb3VudChOKSkKKyAgICAgIHJldHVybiB0cnVlOworCisgICAgLy8gTm9kZSBJZCdzIGFyZSBhc3NpZ25lZCBpbiB0aHJlZSBwbGFjZXM6IEFzIGEgdG9wb2xvZ2ljYWwKKyAgICAvLyBvcmRlcmluZyAoPiAwKSwgZHVyaW5nIGxlZ2FsaXphdGlvbiAocmVzdWx0cyBpbiB2YWx1ZXMgc2V0IHRvCisgICAgLy8gMCksIG5ldyBub2RlcyAoc2V0IHRvIC0xKS4gSWYgTiBoYXMgYSB0b3BvbGdpY2FsIGlkIHRoZW4gd2UKKyAgICAvLyBrbm93IHRoYXQgYWxsIG5vZGVzIHdpdGggaWRzIHNtYWxsZXIgdGhhbiBpdCBjYW5ub3QgYmUKKyAgICAvLyBzdWNjZXNzb3JzIGFuZCB3ZSBuZWVkIG5vdCBjaGVjayB0aGVtLiBGaWx0ZXIgb3V0IGFsbCBub2RlCisgICAgLy8gdGhhdCBjYW4ndCBiZSBtYXRjaGVzLiBXZSBhZGQgdGhlbSB0byB0aGUgd29ya2xpc3QgYmVmb3JlIGV4aXQKKyAgICAvLyBpbiBjYXNlIG9mIG11bHRpcGxlIGNhbGxzLiBOb3RlIHRoYXQgZHVyaW5nIHNlbGVjdGlvbiB0aGUgdG9wb2xvZ2ljYWwgaWQKKyAgICAvLyBtYXkgYmUgdmlvbGF0ZWQgaWYgYSBub2RlJ3MgcHJlZGVjZXNzb3IgaXMgc2VsZWN0ZWQgYmVmb3JlIGl0LiBXZSBtYXJrCisgICAgLy8gdGhpcyBhdCBzZWxlY3Rpb24gbmVnYXRpbmcgdGhlIGlkIG9mIHVuc2VsZWN0ZWQgc3VjY2Vzc29ycyBhbmQKKyAgICAvLyByZXN0cmljdGluZyB0b3BvbG9naWNhbCBwcnVuaW5nIHRvIHBvc2l0aXZlIGlkcy4KKworICAgIGludCBOSWQgPSBOLT5nZXROb2RlSWQoKTsKKyAgICAvLyBJZiB3ZSBJbnZhbGlkYXRlZCB0aGUgSWQsIHJlY29uc3RydWN0IG9yaWdpbmFsIE5JZC4KKyAgICBpZiAoTklkIDwgLTEpCisgICAgICBOSWQgPSAtKE5JZCArIDEpOworCisgICAgYm9vbCBGb3VuZCA9IGZhbHNlOworICAgIHdoaWxlICghV29ya2xpc3QuZW1wdHkoKSkgeworICAgICAgY29uc3QgU0ROb2RlICpNID0gV29ya2xpc3QucG9wX2JhY2tfdmFsKCk7CisgICAgICBpbnQgTUlkID0gTS0+Z2V0Tm9kZUlkKCk7CisgICAgICBpZiAoVG9wb2xvZ2ljYWxQcnVuZSAmJiBNLT5nZXRPcGNvZGUoKSAhPSBJU0Q6OlRva2VuRmFjdG9yICYmIChOSWQgPiAwKSAmJgorICAgICAgICAgIChNSWQgPiAwKSAmJiAoTUlkIDwgTklkKSkgeworICAgICAgICBEZWZlcnJlZE5vZGVzLnB1c2hfYmFjayhNKTsKKyAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBmb3IgKGNvbnN0IFNEVmFsdWUgJk9wViA6IE0tPm9wX3ZhbHVlcygpKSB7CisgICAgICAgIFNETm9kZSAqT3AgPSBPcFYuZ2V0Tm9kZSgpOworICAgICAgICBpZiAoVmlzaXRlZC5pbnNlcnQoT3ApLnNlY29uZCkKKyAgICAgICAgICBXb3JrbGlzdC5wdXNoX2JhY2soT3ApOworICAgICAgICBpZiAoT3AgPT0gTikKKyAgICAgICAgICBGb3VuZCA9IHRydWU7CisgICAgICB9CisgICAgICBpZiAoRm91bmQpCisgICAgICAgIGJyZWFrOworICAgICAgaWYgKE1heFN0ZXBzICE9IDAgJiYgVmlzaXRlZC5zaXplKCkgPj0gTWF4U3RlcHMpCisgICAgICAgIGJyZWFrOworICAgIH0KKyAgICAvLyBQdXNoIGRlZmVycmVkIG5vZGVzIGJhY2sgb24gd29ya2xpc3QuCisgICAgV29ya2xpc3QuYXBwZW5kKERlZmVycmVkTm9kZXMuYmVnaW4oKSwgRGVmZXJyZWROb2Rlcy5lbmQoKSk7CisgICAgLy8gSWYgd2UgYmFpbGVkIGVhcmx5LCBjb25zZXJ2YXRpdmVseSByZXR1cm4gZm91bmQuCisgICAgaWYgKE1heFN0ZXBzICE9IDAgJiYgVmlzaXRlZC5zaXplKCkgPj0gTWF4U3RlcHMpCisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICByZXR1cm4gRm91bmQ7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgYWxsIHRoZSB1c2VycyBvZiBOIGFyZSBjb250YWluZWQgaW4gTm9kZXMuCisgIC8vLyBOT1RFOiBSZXF1aXJlcyBhdCBsZWFzdCBvbmUgbWF0Y2gsIGJ1dCBkb2Vzbid0IHJlcXVpcmUgdGhlbSBhbGwuCisgIHN0YXRpYyBib29sIGFyZU9ubHlVc2Vyc09mKEFycmF5UmVmPGNvbnN0IFNETm9kZSAqPiBOb2RlcywgY29uc3QgU0ROb2RlICpOKTsKKworICAvLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgdmFsdWVzIHVzZWQgYnkgdGhpcyBvcGVyYXRpb24uCisgIHVuc2lnbmVkIGdldE51bU9wZXJhbmRzKCkgY29uc3QgeyByZXR1cm4gTnVtT3BlcmFuZHM7IH0KKworICAvLy8gSGVscGVyIG1ldGhvZCByZXR1cm5zIHRoZSBpbnRlZ2VyIHZhbHVlIG9mIGEgQ29uc3RhbnRTRE5vZGUgb3BlcmFuZC4KKyAgaW5saW5lIHVpbnQ2NF90IGdldENvbnN0YW50T3BlcmFuZFZhbCh1bnNpZ25lZCBOdW0pIGNvbnN0OworCisgIGNvbnN0IFNEVmFsdWUgJmdldE9wZXJhbmQodW5zaWduZWQgTnVtKSBjb25zdCB7CisgICAgYXNzZXJ0KE51bSA8IE51bU9wZXJhbmRzICYmICJJbnZhbGlkIGNoaWxkICMgb2YgU0ROb2RlISIpOworICAgIHJldHVybiBPcGVyYW5kTGlzdFtOdW1dOworICB9CisKKyAgdXNpbmcgb3BfaXRlcmF0b3IgPSBTRFVzZSAqOworCisgIG9wX2l0ZXJhdG9yIG9wX2JlZ2luKCkgY29uc3QgeyByZXR1cm4gT3BlcmFuZExpc3Q7IH0KKyAgb3BfaXRlcmF0b3Igb3BfZW5kKCkgY29uc3QgeyByZXR1cm4gT3BlcmFuZExpc3QrTnVtT3BlcmFuZHM7IH0KKyAgQXJyYXlSZWY8U0RVc2U+IG9wcygpIGNvbnN0IHsgcmV0dXJuIG1ha2VBcnJheVJlZihvcF9iZWdpbigpLCBvcF9lbmQoKSk7IH0KKworICAvLy8gSXRlcmF0b3IgZm9yIGRpcmVjdGx5IGl0ZXJhdGluZyBvdmVyIHRoZSBvcGVyYW5kIFNEVmFsdWUncy4KKyAgc3RydWN0IHZhbHVlX29wX2l0ZXJhdG9yCisgICAgICA6IGl0ZXJhdG9yX2FkYXB0b3JfYmFzZTx2YWx1ZV9vcF9pdGVyYXRvciwgb3BfaXRlcmF0b3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnJhbmRvbV9hY2Nlc3NfaXRlcmF0b3JfdGFnLCBTRFZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHRyZGlmZl90LCB2YWx1ZV9vcF9pdGVyYXRvciAqLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfb3BfaXRlcmF0b3IgKj4geworICAgIGV4cGxpY2l0IHZhbHVlX29wX2l0ZXJhdG9yKFNEVXNlICpVID0gbnVsbHB0cikKKyAgICAgIDogaXRlcmF0b3JfYWRhcHRvcl9iYXNlKFUpIHt9CisKKyAgICBjb25zdCBTRFZhbHVlICZvcGVyYXRvciooKSBjb25zdCB7IHJldHVybiBJLT5nZXQoKTsgfQorICB9OworCisgIGl0ZXJhdG9yX3JhbmdlPHZhbHVlX29wX2l0ZXJhdG9yPiBvcF92YWx1ZXMoKSBjb25zdCB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2UodmFsdWVfb3BfaXRlcmF0b3Iob3BfYmVnaW4oKSksCisgICAgICAgICAgICAgICAgICAgICAgdmFsdWVfb3BfaXRlcmF0b3Iob3BfZW5kKCkpKTsKKyAgfQorCisgIFNEVlRMaXN0IGdldFZUTGlzdCgpIGNvbnN0IHsKKyAgICBTRFZUTGlzdCBYID0geyBWYWx1ZUxpc3QsIE51bVZhbHVlcyB9OworICAgIHJldHVybiBYOworICB9CisKKyAgLy8vIElmIHRoaXMgbm9kZSBoYXMgYSBnbHVlIG9wZXJhbmQsIHJldHVybiB0aGUgbm9kZQorICAvLy8gdG8gd2hpY2ggdGhlIGdsdWUgb3BlcmFuZCBwb2ludHMuIE90aGVyd2lzZSByZXR1cm4gTlVMTC4KKyAgU0ROb2RlICpnZXRHbHVlZE5vZGUoKSBjb25zdCB7CisgICAgaWYgKGdldE51bU9wZXJhbmRzKCkgIT0gMCAmJgorICAgICAgICBnZXRPcGVyYW5kKGdldE51bU9wZXJhbmRzKCktMSkuZ2V0VmFsdWVUeXBlKCkgPT0gTVZUOjpHbHVlKQorICAgICAgcmV0dXJuIGdldE9wZXJhbmQoZ2V0TnVtT3BlcmFuZHMoKS0xKS5nZXROb2RlKCk7CisgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKworICAvLy8gSWYgdGhpcyBub2RlIGhhcyBhIGdsdWUgdmFsdWUgd2l0aCBhIHVzZXIsIHJldHVybgorICAvLy8gdGhlIHVzZXIgKHRoZXJlIGlzIGF0IG1vc3Qgb25lKS4gT3RoZXJ3aXNlIHJldHVybiBOVUxMLgorICBTRE5vZGUgKmdldEdsdWVkVXNlcigpIGNvbnN0IHsKKyAgICBmb3IgKHVzZV9pdGVyYXRvciBVSSA9IHVzZV9iZWdpbigpLCBVRSA9IHVzZV9lbmQoKTsgVUkgIT0gVUU7ICsrVUkpCisgICAgICBpZiAoVUkuZ2V0VXNlKCkuZ2V0KCkuZ2V0VmFsdWVUeXBlKCkgPT0gTVZUOjpHbHVlKQorICAgICAgICByZXR1cm4gKlVJOworICAgIHJldHVybiBudWxscHRyOworICB9CisKKyAgY29uc3QgU0ROb2RlRmxhZ3MgZ2V0RmxhZ3MoKSBjb25zdCB7IHJldHVybiBGbGFnczsgfQorICB2b2lkIHNldEZsYWdzKFNETm9kZUZsYWdzIE5ld0ZsYWdzKSB7IEZsYWdzID0gTmV3RmxhZ3M7IH0KKworICAvLy8gQ2xlYXIgYW55IGZsYWdzIGluIHRoaXMgbm9kZSB0aGF0IGFyZW4ndCBhbHNvIHNldCBpbiBGbGFncy4KKyAgLy8vIElmIEZsYWdzIGlzIG5vdCBpbiBhIGRlZmluZWQgc3RhdGUgdGhlbiB0aGlzIGhhcyBubyBlZmZlY3QuCisgIHZvaWQgaW50ZXJzZWN0RmxhZ3NXaXRoKGNvbnN0IFNETm9kZUZsYWdzIEZsYWdzKTsKKworICAvLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgdmFsdWVzIGRlZmluZWQvcmV0dXJuZWQgYnkgdGhpcyBvcGVyYXRvci4KKyAgdW5zaWduZWQgZ2V0TnVtVmFsdWVzKCkgY29uc3QgeyByZXR1cm4gTnVtVmFsdWVzOyB9CisKKyAgLy8vIFJldHVybiB0aGUgdHlwZSBvZiBhIHNwZWNpZmllZCByZXN1bHQuCisgIEVWVCBnZXRWYWx1ZVR5cGUodW5zaWduZWQgUmVzTm8pIGNvbnN0IHsKKyAgICBhc3NlcnQoUmVzTm8gPCBOdW1WYWx1ZXMgJiYgIklsbGVnYWwgcmVzdWx0IG51bWJlciEiKTsKKyAgICByZXR1cm4gVmFsdWVMaXN0W1Jlc05vXTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIHR5cGUgb2YgYSBzcGVjaWZpZWQgcmVzdWx0IGFzIGEgc2ltcGxlIHR5cGUuCisgIE1WVCBnZXRTaW1wbGVWYWx1ZVR5cGUodW5zaWduZWQgUmVzTm8pIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0VmFsdWVUeXBlKFJlc05vKS5nZXRTaW1wbGVWVCgpOworICB9CisKKyAgLy8vIFJldHVybnMgTVZUOjpnZXRTaXplSW5CaXRzKGdldFZhbHVlVHlwZShSZXNObykpLgorICB1bnNpZ25lZCBnZXRWYWx1ZVNpemVJbkJpdHModW5zaWduZWQgUmVzTm8pIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0VmFsdWVUeXBlKFJlc05vKS5nZXRTaXplSW5CaXRzKCk7CisgIH0KKworICB1c2luZyB2YWx1ZV9pdGVyYXRvciA9IGNvbnN0IEVWVCAqOworCisgIHZhbHVlX2l0ZXJhdG9yIHZhbHVlX2JlZ2luKCkgY29uc3QgeyByZXR1cm4gVmFsdWVMaXN0OyB9CisgIHZhbHVlX2l0ZXJhdG9yIHZhbHVlX2VuZCgpIGNvbnN0IHsgcmV0dXJuIFZhbHVlTGlzdCtOdW1WYWx1ZXM7IH0KKworICAvLy8gUmV0dXJuIHRoZSBvcGNvZGUgb2YgdGhpcyBvcGVyYXRpb24gZm9yIHByaW50aW5nLgorICBzdGQ6OnN0cmluZyBnZXRPcGVyYXRpb25OYW1lKGNvbnN0IFNlbGVjdGlvbkRBRyAqRyA9IG51bGxwdHIpIGNvbnN0OworICBzdGF0aWMgY29uc3QgY2hhciogZ2V0SW5kZXhlZE1vZGVOYW1lKElTRDo6TWVtSW5kZXhlZE1vZGUgQU0pOworICB2b2lkIHByaW50X3R5cGVzKHJhd19vc3RyZWFtICZPUywgY29uc3QgU2VsZWN0aW9uREFHICpHKSBjb25zdDsKKyAgdm9pZCBwcmludF9kZXRhaWxzKHJhd19vc3RyZWFtICZPUywgY29uc3QgU2VsZWN0aW9uREFHICpHKSBjb25zdDsKKyAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MsIGNvbnN0IFNlbGVjdGlvbkRBRyAqRyA9IG51bGxwdHIpIGNvbnN0OworICB2b2lkIHByaW50cihyYXdfb3N0cmVhbSAmT1MsIGNvbnN0IFNlbGVjdGlvbkRBRyAqRyA9IG51bGxwdHIpIGNvbnN0OworCisgIC8vLyBQcmludCBhIFNlbGVjdGlvbkRBRyBub2RlIGFuZCBhbGwgY2hpbGRyZW4gZG93biB0bworICAvLy8gdGhlIGxlYXZlcy4gIFRoZSBnaXZlbiBTZWxlY3Rpb25EQUcgYWxsb3dzIHRhcmdldC1zcGVjaWZpYyBub2RlcworICAvLy8gdG8gYmUgcHJpbnRlZCBpbiBodW1hbi1yZWFkYWJsZSBmb3JtLiAgVW5saWtlIHByaW50ciwgdGhpcyB3aWxsCisgIC8vLyBwcmludCB0aGUgd2hvbGUgREFHLCBpbmNsdWRpbmcgY2hpbGRyZW4gdGhhdCBhcHBlYXIgbXVsdGlwbGUKKyAgLy8vIHRpbWVzLgorICAvLy8KKyAgdm9pZCBwcmludHJGdWxsKHJhd19vc3RyZWFtICZPLCBjb25zdCBTZWxlY3Rpb25EQUcgKkcgPSBudWxscHRyKSBjb25zdDsKKworICAvLy8gUHJpbnQgYSBTZWxlY3Rpb25EQUcgbm9kZSBhbmQgY2hpbGRyZW4gdXAgdG8KKyAgLy8vIGRlcHRoICJkZXB0aC4iICBUaGUgZ2l2ZW4gU2VsZWN0aW9uREFHIGFsbG93cyB0YXJnZXQtc3BlY2lmaWMKKyAgLy8vIG5vZGVzIHRvIGJlIHByaW50ZWQgaW4gaHVtYW4tcmVhZGFibGUgZm9ybS4gIFVubGlrZSBwcmludHIsIHRoaXMKKyAgLy8vIHdpbGwgcHJpbnQgY2hpbGRyZW4gdGhhdCBhcHBlYXIgbXVsdGlwbGUgdGltZXMgd2hlcmV2ZXIgdGhleSBhcmUKKyAgLy8vIHVzZWQuCisgIC8vLworICB2b2lkIHByaW50cldpdGhEZXB0aChyYXdfb3N0cmVhbSAmTywgY29uc3QgU2VsZWN0aW9uREFHICpHID0gbnVsbHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgZGVwdGggPSAxMDApIGNvbnN0OworCisgIC8vLyBEdW1wIHRoaXMgbm9kZSwgZm9yIGRlYnVnZ2luZy4KKyAgdm9pZCBkdW1wKCkgY29uc3Q7CisKKyAgLy8vIER1bXAgKHJlY3Vyc2l2ZWx5KSB0aGlzIG5vZGUgYW5kIGl0cyB1c2UtZGVmIHN1YmdyYXBoLgorICB2b2lkIGR1bXByKCkgY29uc3Q7CisKKyAgLy8vIER1bXAgdGhpcyBub2RlLCBmb3IgZGVidWdnaW5nLgorICAvLy8gVGhlIGdpdmVuIFNlbGVjdGlvbkRBRyBhbGxvd3MgdGFyZ2V0LXNwZWNpZmljIG5vZGVzIHRvIGJlIHByaW50ZWQKKyAgLy8vIGluIGh1bWFuLXJlYWRhYmxlIGZvcm0uCisgIHZvaWQgZHVtcChjb25zdCBTZWxlY3Rpb25EQUcgKkcpIGNvbnN0OworCisgIC8vLyBEdW1wIChyZWN1cnNpdmVseSkgdGhpcyBub2RlIGFuZCBpdHMgdXNlLWRlZiBzdWJncmFwaC4KKyAgLy8vIFRoZSBnaXZlbiBTZWxlY3Rpb25EQUcgYWxsb3dzIHRhcmdldC1zcGVjaWZpYyBub2RlcyB0byBiZSBwcmludGVkCisgIC8vLyBpbiBodW1hbi1yZWFkYWJsZSBmb3JtLgorICB2b2lkIGR1bXByKGNvbnN0IFNlbGVjdGlvbkRBRyAqRykgY29uc3Q7CisKKyAgLy8vIHByaW50ckZ1bGwgdG8gZGJncygpLiAgVGhlIGdpdmVuIFNlbGVjdGlvbkRBRyBhbGxvd3MKKyAgLy8vIHRhcmdldC1zcGVjaWZpYyBub2RlcyB0byBiZSBwcmludGVkIGluIGh1bWFuLXJlYWRhYmxlIGZvcm0uCisgIC8vLyBVbmxpa2UgZHVtcHIsIHRoaXMgd2lsbCBwcmludCB0aGUgd2hvbGUgREFHLCBpbmNsdWRpbmcgY2hpbGRyZW4KKyAgLy8vIHRoYXQgYXBwZWFyIG11bHRpcGxlIHRpbWVzLgorICB2b2lkIGR1bXByRnVsbChjb25zdCBTZWxlY3Rpb25EQUcgKkcgPSBudWxscHRyKSBjb25zdDsKKworICAvLy8gcHJpbnRyV2l0aERlcHRoIHRvIGRiZ3MoKS4gIFRoZSBnaXZlbgorICAvLy8gU2VsZWN0aW9uREFHIGFsbG93cyB0YXJnZXQtc3BlY2lmaWMgbm9kZXMgdG8gYmUgcHJpbnRlZCBpbgorICAvLy8gaHVtYW4tcmVhZGFibGUgZm9ybS4gIFVubGlrZSBkdW1wciwgdGhpcyB3aWxsIHByaW50IGNoaWxkcmVuCisgIC8vLyB0aGF0IGFwcGVhciBtdWx0aXBsZSB0aW1lcyB3aGVyZXZlciB0aGV5IGFyZSB1c2VkLgorICAvLy8KKyAgdm9pZCBkdW1wcldpdGhEZXB0aChjb25zdCBTZWxlY3Rpb25EQUcgKkcgPSBudWxscHRyLAorICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGRlcHRoID0gMTAwKSBjb25zdDsKKworICAvLy8gR2F0aGVyIHVuaXF1ZSBkYXRhIGZvciB0aGUgbm9kZS4KKyAgdm9pZCBQcm9maWxlKEZvbGRpbmdTZXROb2RlSUQgJklEKSBjb25zdDsKKworICAvLy8gVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgdXNlZCBieSB0aGUgU0RVc2UgY2xhc3MuCisgIHZvaWQgYWRkVXNlKFNEVXNlICZVKSB7IFUuYWRkVG9MaXN0KCZVc2VMaXN0KTsgfQorCitwcm90ZWN0ZWQ6CisgIHN0YXRpYyBTRFZUTGlzdCBnZXRTRFZUTGlzdChFVlQgVlQpIHsKKyAgICBTRFZUTGlzdCBSZXQgPSB7IGdldFZhbHVlVHlwZUxpc3QoVlQpLCAxIH07CisgICAgcmV0dXJuIFJldDsKKyAgfQorCisgIC8vLyBDcmVhdGUgYW4gU0ROb2RlLgorICAvLy8KKyAgLy8vIFNETm9kZXMgYXJlIGNyZWF0ZWQgd2l0aG91dCBhbnkgb3BlcmFuZHMsIGFuZCBuZXZlciBvd24gdGhlIG9wZXJhbmQKKyAgLy8vIHN0b3JhZ2UuIFRvIGFkZCBvcGVyYW5kcywgc2VlIFNlbGVjdGlvbkRBRzo6Y3JlYXRlT3BlcmFuZHMuCisgIFNETm9kZSh1bnNpZ25lZCBPcGMsIHVuc2lnbmVkIE9yZGVyLCBEZWJ1Z0xvYyBkbCwgU0RWVExpc3QgVlRzKQorICAgICAgOiBOb2RlVHlwZShPcGMpLCBWYWx1ZUxpc3QoVlRzLlZUcyksIE51bVZhbHVlcyhWVHMuTnVtVlRzKSwKKyAgICAgICAgSVJPcmRlcihPcmRlciksIGRlYnVnTG9jKHN0ZDo6bW92ZShkbCkpIHsKKyAgICBtZW1zZXQoJlJhd1NETm9kZUJpdHMsIDAsIHNpemVvZihSYXdTRE5vZGVCaXRzKSk7CisgICAgYXNzZXJ0KGRlYnVnTG9jLmhhc1RyaXZpYWxEZXN0cnVjdG9yKCkgJiYgIkV4cGVjdGVkIHRyaXZpYWwgZGVzdHJ1Y3RvciIpOworICAgIGFzc2VydChOdW1WYWx1ZXMgPT0gVlRzLk51bVZUcyAmJgorICAgICAgICAgICAiTnVtVmFsdWVzIHdhc24ndCB3aWRlIGVub3VnaCBmb3IgaXRzIG9wZXJhbmRzISIpOworICB9CisKKyAgLy8vIFJlbGVhc2UgdGhlIG9wZXJhbmRzIGFuZCBzZXQgdGhpcyBub2RlIHRvIGhhdmUgemVybyBvcGVyYW5kcy4KKyAgdm9pZCBEcm9wT3BlcmFuZHMoKTsKK307CisKKy8vLyBXcmFwcGVyIGNsYXNzIGZvciBJUiBsb2NhdGlvbiBpbmZvIChJUiBvcmRlcmluZyBhbmQgRGVidWdMb2MpIHRvIGJlIHBhc3NlZAorLy8vIGludG8gU0ROb2RlIGNyZWF0aW9uIGZ1bmN0aW9ucy4KKy8vLyBXaGVuIGFuIFNETm9kZSBpcyBjcmVhdGVkIGZyb20gdGhlIERBR0J1aWxkZXIsIHRoZSBEZWJ1Z0xvYyBpcyBleHRyYWN0ZWQKKy8vLyBmcm9tIHRoZSBvcmlnaW5hbCBJbnN0cnVjdGlvbiwgYW5kIElST3JkZXIgaXMgdGhlIG9yZGluYWwgcG9zaXRpb24gb2YKKy8vLyB0aGUgaW5zdHJ1Y3Rpb24uCisvLy8gV2hlbiBhbiBTRE5vZGUgaXMgY3JlYXRlZCBhZnRlciB0aGUgREFHIGlzIGJlaW5nIGJ1aWx0LCBib3RoIERlYnVnTG9jIGFuZAorLy8vIHRoZSBJUk9yZGVyIGFyZSBwcm9wYWdhdGVkIGZyb20gdGhlIG9yaWdpbmFsIFNETm9kZS4KKy8vLyBTbyBTRExvYyBjbGFzcyBwcm92aWRlcyB0d28gY29uc3RydWN0b3JzIGJlc2lkZXMgdGhlIGRlZmF1bHQgb25lLCBvbmUgdG8KKy8vLyBiZSB1c2VkIGJ5IHRoZSBEQUdCdWlsZGVyLCB0aGUgb3RoZXIgdG8gYmUgdXNlZCBieSBvdGhlcnMuCitjbGFzcyBTRExvYyB7Citwcml2YXRlOgorICBEZWJ1Z0xvYyBETDsKKyAgaW50IElST3JkZXIgPSAwOworCitwdWJsaWM6CisgIFNETG9jKCkgPSBkZWZhdWx0OworICBTRExvYyhjb25zdCBTRE5vZGUgKk4pIDogREwoTi0+Z2V0RGVidWdMb2MoKSksIElST3JkZXIoTi0+Z2V0SVJPcmRlcigpKSB7fQorICBTRExvYyhjb25zdCBTRFZhbHVlIFYpIDogU0RMb2MoVi5nZXROb2RlKCkpIHt9CisgIFNETG9jKGNvbnN0IEluc3RydWN0aW9uICpJLCBpbnQgT3JkZXIpIDogSVJPcmRlcihPcmRlcikgeworICAgIGFzc2VydChPcmRlciA+PSAwICYmICJiYWQgSVJPcmRlciIpOworICAgIGlmIChJKQorICAgICAgREwgPSBJLT5nZXREZWJ1Z0xvYygpOworICB9CisKKyAgdW5zaWduZWQgZ2V0SVJPcmRlcigpIGNvbnN0IHsgcmV0dXJuIElST3JkZXI7IH0KKyAgY29uc3QgRGVidWdMb2MgJmdldERlYnVnTG9jKCkgY29uc3QgeyByZXR1cm4gREw7IH0KK307CisKKy8vIERlZmluZSBpbmxpbmUgZnVuY3Rpb25zIGZyb20gdGhlIFNEVmFsdWUgY2xhc3MuCisKK2lubGluZSBTRFZhbHVlOjpTRFZhbHVlKFNETm9kZSAqbm9kZSwgdW5zaWduZWQgcmVzbm8pCisgICAgOiBOb2RlKG5vZGUpLCBSZXNObyhyZXNubykgeworICAvLyBFeHBsaWNpdGx5IGNoZWNrIGZvciAhUmVzTm8gdG8gYXZvaWQgdXNlLWFmdGVyLWZyZWUsIGJlY2F1c2UgdGhlcmUgYXJlCisgIC8vIGNhbGxlcnMgdGhhdCB1c2UgU0RWYWx1ZShOLCAwKSB3aXRoIGEgZGVsZXRlZCBOIHRvIGluZGljYXRlIHN1Y2Nlc3NmdWwKKyAgLy8gY29tYmluZXMuCisgIGFzc2VydCgoIU5vZGUgfHwgIVJlc05vIHx8IFJlc05vIDwgTm9kZS0+Z2V0TnVtVmFsdWVzKCkpICYmCisgICAgICAgICAiSW52YWxpZCByZXN1bHQgbnVtYmVyIGZvciB0aGUgZ2l2ZW4gbm9kZSEiKTsKKyAgYXNzZXJ0KFJlc05vIDwgLTJVICYmICJDYW5ub3QgdXNlIHJlc3VsdCBudW1iZXJzIHJlc2VydmVkIGZvciBEZW5zZU1hcHMuIik7Cit9CisKK2lubGluZSB1bnNpZ25lZCBTRFZhbHVlOjpnZXRPcGNvZGUoKSBjb25zdCB7CisgIHJldHVybiBOb2RlLT5nZXRPcGNvZGUoKTsKK30KKworaW5saW5lIEVWVCBTRFZhbHVlOjpnZXRWYWx1ZVR5cGUoKSBjb25zdCB7CisgIHJldHVybiBOb2RlLT5nZXRWYWx1ZVR5cGUoUmVzTm8pOworfQorCitpbmxpbmUgdW5zaWduZWQgU0RWYWx1ZTo6Z2V0TnVtT3BlcmFuZHMoKSBjb25zdCB7CisgIHJldHVybiBOb2RlLT5nZXROdW1PcGVyYW5kcygpOworfQorCitpbmxpbmUgY29uc3QgU0RWYWx1ZSAmU0RWYWx1ZTo6Z2V0T3BlcmFuZCh1bnNpZ25lZCBpKSBjb25zdCB7CisgIHJldHVybiBOb2RlLT5nZXRPcGVyYW5kKGkpOworfQorCitpbmxpbmUgdWludDY0X3QgU0RWYWx1ZTo6Z2V0Q29uc3RhbnRPcGVyYW5kVmFsKHVuc2lnbmVkIGkpIGNvbnN0IHsKKyAgcmV0dXJuIE5vZGUtPmdldENvbnN0YW50T3BlcmFuZFZhbChpKTsKK30KKworaW5saW5lIGJvb2wgU0RWYWx1ZTo6aXNUYXJnZXRPcGNvZGUoKSBjb25zdCB7CisgIHJldHVybiBOb2RlLT5pc1RhcmdldE9wY29kZSgpOworfQorCitpbmxpbmUgYm9vbCBTRFZhbHVlOjppc1RhcmdldE1lbW9yeU9wY29kZSgpIGNvbnN0IHsKKyAgcmV0dXJuIE5vZGUtPmlzVGFyZ2V0TWVtb3J5T3Bjb2RlKCk7Cit9CisKK2lubGluZSBib29sIFNEVmFsdWU6OmlzTWFjaGluZU9wY29kZSgpIGNvbnN0IHsKKyAgcmV0dXJuIE5vZGUtPmlzTWFjaGluZU9wY29kZSgpOworfQorCitpbmxpbmUgdW5zaWduZWQgU0RWYWx1ZTo6Z2V0TWFjaGluZU9wY29kZSgpIGNvbnN0IHsKKyAgcmV0dXJuIE5vZGUtPmdldE1hY2hpbmVPcGNvZGUoKTsKK30KKworaW5saW5lIGJvb2wgU0RWYWx1ZTo6aXNVbmRlZigpIGNvbnN0IHsKKyAgcmV0dXJuIE5vZGUtPmlzVW5kZWYoKTsKK30KKworaW5saW5lIGJvb2wgU0RWYWx1ZTo6dXNlX2VtcHR5KCkgY29uc3QgeworICByZXR1cm4gIU5vZGUtPmhhc0FueVVzZU9mVmFsdWUoUmVzTm8pOworfQorCitpbmxpbmUgYm9vbCBTRFZhbHVlOjpoYXNPbmVVc2UoKSBjb25zdCB7CisgIHJldHVybiBOb2RlLT5oYXNOVXNlc09mVmFsdWUoMSwgUmVzTm8pOworfQorCitpbmxpbmUgY29uc3QgRGVidWdMb2MgJlNEVmFsdWU6OmdldERlYnVnTG9jKCkgY29uc3QgeworICByZXR1cm4gTm9kZS0+Z2V0RGVidWdMb2MoKTsKK30KKworaW5saW5lIHZvaWQgU0RWYWx1ZTo6ZHVtcCgpIGNvbnN0IHsKKyAgcmV0dXJuIE5vZGUtPmR1bXAoKTsKK30KKworaW5saW5lIHZvaWQgU0RWYWx1ZTo6ZHVtcChjb25zdCBTZWxlY3Rpb25EQUcgKkcpIGNvbnN0IHsKKyAgcmV0dXJuIE5vZGUtPmR1bXAoRyk7Cit9CisKK2lubGluZSB2b2lkIFNEVmFsdWU6OmR1bXByKCkgY29uc3QgeworICByZXR1cm4gTm9kZS0+ZHVtcHIoKTsKK30KKworaW5saW5lIHZvaWQgU0RWYWx1ZTo6ZHVtcHIoY29uc3QgU2VsZWN0aW9uREFHICpHKSBjb25zdCB7CisgIHJldHVybiBOb2RlLT5kdW1wcihHKTsKK30KKworLy8gRGVmaW5lIGlubGluZSBmdW5jdGlvbnMgZnJvbSB0aGUgU0RVc2UgY2xhc3MuCisKK2lubGluZSB2b2lkIFNEVXNlOjpzZXQoY29uc3QgU0RWYWx1ZSAmVikgeworICBpZiAoVmFsLmdldE5vZGUoKSkgcmVtb3ZlRnJvbUxpc3QoKTsKKyAgVmFsID0gVjsKKyAgaWYgKFYuZ2V0Tm9kZSgpKSBWLmdldE5vZGUoKS0+YWRkVXNlKCp0aGlzKTsKK30KKworaW5saW5lIHZvaWQgU0RVc2U6OnNldEluaXRpYWwoY29uc3QgU0RWYWx1ZSAmVikgeworICBWYWwgPSBWOworICBWLmdldE5vZGUoKS0+YWRkVXNlKCp0aGlzKTsKK30KKworaW5saW5lIHZvaWQgU0RVc2U6OnNldE5vZGUoU0ROb2RlICpOKSB7CisgIGlmIChWYWwuZ2V0Tm9kZSgpKSByZW1vdmVGcm9tTGlzdCgpOworICBWYWwuc2V0Tm9kZShOKTsKKyAgaWYgKE4pIE4tPmFkZFVzZSgqdGhpcyk7Cit9CisKKy8vLyBUaGlzIGNsYXNzIGlzIHVzZWQgdG8gZm9ybSBhIGhhbmRsZSBhcm91bmQgYW5vdGhlciBub2RlIHRoYXQKKy8vLyBpcyBwZXJzaXN0ZW50IGFuZCBpcyB1cGRhdGVkIGFjcm9zcyBpbnZvY2F0aW9ucyBvZiByZXBsYWNlQWxsVXNlc1dpdGggb24gaXRzCisvLy8gb3BlcmFuZC4gIFRoaXMgbm9kZSBzaG91bGQgYmUgZGlyZWN0bHkgY3JlYXRlZCBieSBlbmQtdXNlcnMgYW5kIG5vdCBhZGRlZCB0bworLy8vIHRoZSBBbGxOb2RlcyBsaXN0LgorY2xhc3MgSGFuZGxlU0ROb2RlIDogcHVibGljIFNETm9kZSB7CisgIFNEVXNlIE9wOworCitwdWJsaWM6CisgIGV4cGxpY2l0IEhhbmRsZVNETm9kZShTRFZhbHVlIFgpCisgICAgOiBTRE5vZGUoSVNEOjpIQU5ETEVOT0RFLCAwLCBEZWJ1Z0xvYygpLCBnZXRTRFZUTGlzdChNVlQ6Ok90aGVyKSkgeworICAgIC8vIEhhbmRsZVNETm9kZXMgYXJlIG5ldmVyIGluc2VydGVkIGludG8gdGhlIERBRywgc28gdGhleSB3b24ndCBiZQorICAgIC8vIGF1dG8tbnVtYmVyZWQuIFVzZSBJRCA2NTUzNSBhcyBhIHNlbnRpbmVsLgorICAgIFBlcnNpc3RlbnRJZCA9IDB4ZmZmZjsKKworICAgIC8vIE1hbnVhbGx5IHNldCB1cCB0aGUgb3BlcmFuZCBsaXN0LiBUaGlzIG5vZGUgdHlwZSBpcyBzcGVjaWFsIGluIHRoYXQgaXQncworICAgIC8vIGFsd2F5cyBzdGFjayBhbGxvY2F0ZWQgYW5kIFNlbGVjdGlvbkRBRyBkb2VzIG5vdCBtYW5hZ2UgaXRzIG9wZXJhbmRzLgorICAgIC8vIFRPRE86IFRoaXMgc2hvdWxkIGVpdGhlciAoYSkgbm90IGJlIGluIHRoZSBTRE5vZGUgaGllcmFyY2h5LCBvciAoYikgbm90CisgICAgLy8gYmUgc28gc3BlY2lhbC4KKyAgICBPcC5zZXRVc2VyKHRoaXMpOworICAgIE9wLnNldEluaXRpYWwoWCk7CisgICAgTnVtT3BlcmFuZHMgPSAxOworICAgIE9wZXJhbmRMaXN0ID0gJk9wOworICB9CisgIH5IYW5kbGVTRE5vZGUoKTsKKworICBjb25zdCBTRFZhbHVlICZnZXRWYWx1ZSgpIGNvbnN0IHsgcmV0dXJuIE9wOyB9Cit9OworCitjbGFzcyBBZGRyU3BhY2VDYXN0U0ROb2RlIDogcHVibGljIFNETm9kZSB7Citwcml2YXRlOgorICB1bnNpZ25lZCBTcmNBZGRyU3BhY2U7CisgIHVuc2lnbmVkIERlc3RBZGRyU3BhY2U7CisKK3B1YmxpYzoKKyAgQWRkclNwYWNlQ2FzdFNETm9kZSh1bnNpZ25lZCBPcmRlciwgY29uc3QgRGVidWdMb2MgJmRsLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgU3JjQVMsIHVuc2lnbmVkIERlc3RBUyk7CisKKyAgdW5zaWduZWQgZ2V0U3JjQWRkcmVzc1NwYWNlKCkgY29uc3QgeyByZXR1cm4gU3JjQWRkclNwYWNlOyB9CisgIHVuc2lnbmVkIGdldERlc3RBZGRyZXNzU3BhY2UoKSBjb25zdCB7IHJldHVybiBEZXN0QWRkclNwYWNlOyB9CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpBRERSU1BBQ0VDQVNUOworICB9Cit9OworCisvLy8gVGhpcyBpcyBhbiBhYnN0cmFjdCB2aXJ0dWFsIGNsYXNzIGZvciBtZW1vcnkgb3BlcmF0aW9ucy4KK2NsYXNzIE1lbVNETm9kZSA6IHB1YmxpYyBTRE5vZGUgeworcHJpdmF0ZToKKyAgLy8gVlQgb2YgaW4tbWVtb3J5IHZhbHVlLgorICBFVlQgTWVtb3J5VlQ7CisKK3Byb3RlY3RlZDoKKyAgLy8vIE1lbW9yeSByZWZlcmVuY2UgaW5mb3JtYXRpb24uCisgIE1hY2hpbmVNZW1PcGVyYW5kICpNTU87CisKK3B1YmxpYzoKKyAgTWVtU0ROb2RlKHVuc2lnbmVkIE9wYywgdW5zaWduZWQgT3JkZXIsIGNvbnN0IERlYnVnTG9jICZkbCwgU0RWVExpc3QgVlRzLAorICAgICAgICAgICAgRVZUIE1lbW9yeVZULCBNYWNoaW5lTWVtT3BlcmFuZCAqTU1PKTsKKworICBib29sIHJlYWRNZW0oKSBjb25zdCB7IHJldHVybiBNTU8tPmlzTG9hZCgpOyB9CisgIGJvb2wgd3JpdGVNZW0oKSBjb25zdCB7IHJldHVybiBNTU8tPmlzU3RvcmUoKTsgfQorCisgIC8vLyBSZXR1cm5zIGFsaWdubWVudCBhbmQgdm9sYXRpbGl0eSBvZiB0aGUgbWVtb3J5IGFjY2VzcworICB1bnNpZ25lZCBnZXRPcmlnaW5hbEFsaWdubWVudCgpIGNvbnN0IHsKKyAgICByZXR1cm4gTU1PLT5nZXRCYXNlQWxpZ25tZW50KCk7CisgIH0KKyAgdW5zaWduZWQgZ2V0QWxpZ25tZW50KCkgY29uc3QgeworICAgIHJldHVybiBNTU8tPmdldEFsaWdubWVudCgpOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgU3ViY2xhc3NEYXRhIHZhbHVlLCB3aXRob3V0IEhhc0RlYnVnVmFsdWUuIFRoaXMgY29udGFpbnMgYW4KKyAgLy8vIGVuY29kaW5nIG9mIHRoZSB2b2xhdGlsZSBmbGFnLCBhcyB3ZWxsIGFzIGJpdHMgdXNlZCBieSBzdWJjbGFzc2VzLiBUaGlzCisgIC8vLyBmdW5jdGlvbiBzaG91bGQgb25seSBiZSB1c2VkIHRvIGNvbXB1dGUgYSBGb2xkaW5nU2V0Tm9kZUlEIHZhbHVlLgorICAvLy8gVGhlIEhhc0RlYnVnVmFsdWUgYml0IGlzIG1hc2tlZCBvdXQgYmVjYXVzZSBDU0UgbWFwIG5lZWRzIHRvIG1hdGNoCisgIC8vLyBub2RlcyB3aXRoIGRlYnVnIGluZm8gd2l0aCBub2RlcyB3aXRob3V0IGRlYnVnIGluZm8uIFNhbWUgaXMgYWJvdXQKKyAgLy8vIGlzRGl2ZXJnZW50IGJpdC4KKyAgdW5zaWduZWQgZ2V0UmF3U3ViY2xhc3NEYXRhKCkgY29uc3QgeworICAgIHVpbnQxNl90IERhdGE7CisgICAgdW5pb24geworICAgICAgY2hhciBSYXdTRE5vZGVCaXRzW3NpemVvZih1aW50MTZfdCldOworICAgICAgU0ROb2RlQml0ZmllbGRzIFNETm9kZUJpdHM7CisgICAgfTsKKyAgICBtZW1jcHkoJlJhd1NETm9kZUJpdHMsICZ0aGlzLT5SYXdTRE5vZGVCaXRzLCBzaXplb2YodGhpcy0+UmF3U0ROb2RlQml0cykpOworICAgIFNETm9kZUJpdHMuSGFzRGVidWdWYWx1ZSA9IDA7CisgICAgU0ROb2RlQml0cy5Jc0RpdmVyZ2VudCA9IGZhbHNlOworICAgIG1lbWNweSgmRGF0YSwgJlJhd1NETm9kZUJpdHMsIHNpemVvZihSYXdTRE5vZGVCaXRzKSk7CisgICAgcmV0dXJuIERhdGE7CisgIH0KKworICBib29sIGlzVm9sYXRpbGUoKSBjb25zdCB7IHJldHVybiBNZW1TRE5vZGVCaXRzLklzVm9sYXRpbGU7IH0KKyAgYm9vbCBpc05vblRlbXBvcmFsKCkgY29uc3QgeyByZXR1cm4gTWVtU0ROb2RlQml0cy5Jc05vblRlbXBvcmFsOyB9CisgIGJvb2wgaXNEZXJlZmVyZW5jZWFibGUoKSBjb25zdCB7IHJldHVybiBNZW1TRE5vZGVCaXRzLklzRGVyZWZlcmVuY2VhYmxlOyB9CisgIGJvb2wgaXNJbnZhcmlhbnQoKSBjb25zdCB7IHJldHVybiBNZW1TRE5vZGVCaXRzLklzSW52YXJpYW50OyB9CisKKyAgLy8gUmV0dXJucyB0aGUgb2Zmc2V0IGZyb20gdGhlIGxvY2F0aW9uIG9mIHRoZSBhY2Nlc3MuCisgIGludDY0X3QgZ2V0U3JjVmFsdWVPZmZzZXQoKSBjb25zdCB7IHJldHVybiBNTU8tPmdldE9mZnNldCgpOyB9CisKKyAgLy8vIFJldHVybnMgdGhlIEFBIGluZm8gdGhhdCBkZXNjcmliZXMgdGhlIGRlcmVmZXJlbmNlLgorICBBQU1ETm9kZXMgZ2V0QUFJbmZvKCkgY29uc3QgeyByZXR1cm4gTU1PLT5nZXRBQUluZm8oKTsgfQorCisgIC8vLyBSZXR1cm5zIHRoZSBSYW5nZXMgdGhhdCBkZXNjcmliZXMgdGhlIGRlcmVmZXJlbmNlLgorICBjb25zdCBNRE5vZGUgKmdldFJhbmdlcygpIGNvbnN0IHsgcmV0dXJuIE1NTy0+Z2V0UmFuZ2VzKCk7IH0KKworICAvLy8gUmV0dXJucyB0aGUgc3luY2hyb25pemF0aW9uIHNjb3BlIElEIGZvciB0aGlzIG1lbW9yeSBvcGVyYXRpb24uCisgIFN5bmNTY29wZTo6SUQgZ2V0U3luY1Njb3BlSUQoKSBjb25zdCB7IHJldHVybiBNTU8tPmdldFN5bmNTY29wZUlEKCk7IH0KKworICAvLy8gUmV0dXJuIHRoZSBhdG9taWMgb3JkZXJpbmcgcmVxdWlyZW1lbnRzIGZvciB0aGlzIG1lbW9yeSBvcGVyYXRpb24uIEZvcgorICAvLy8gY21weGNoZyBhdG9taWMgb3BlcmF0aW9ucywgcmV0dXJuIHRoZSBhdG9taWMgb3JkZXJpbmcgcmVxdWlyZW1lbnRzIHdoZW4KKyAgLy8vIHN0b3JlIG9jY3Vycy4KKyAgQXRvbWljT3JkZXJpbmcgZ2V0T3JkZXJpbmcoKSBjb25zdCB7IHJldHVybiBNTU8tPmdldE9yZGVyaW5nKCk7IH0KKworICAvLy8gUmV0dXJuIHRoZSB0eXBlIG9mIHRoZSBpbi1tZW1vcnkgdmFsdWUuCisgIEVWVCBnZXRNZW1vcnlWVCgpIGNvbnN0IHsgcmV0dXJuIE1lbW9yeVZUOyB9CisKKyAgLy8vIFJldHVybiBhIE1hY2hpbmVNZW1PcGVyYW5kIG9iamVjdCBkZXNjcmliaW5nIHRoZSBtZW1vcnkKKyAgLy8vIHJlZmVyZW5jZSBwZXJmb3JtZWQgYnkgb3BlcmF0aW9uLgorICBNYWNoaW5lTWVtT3BlcmFuZCAqZ2V0TWVtT3BlcmFuZCgpIGNvbnN0IHsgcmV0dXJuIE1NTzsgfQorCisgIGNvbnN0IE1hY2hpbmVQb2ludGVySW5mbyAmZ2V0UG9pbnRlckluZm8oKSBjb25zdCB7CisgICAgcmV0dXJuIE1NTy0+Z2V0UG9pbnRlckluZm8oKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIGFkZHJlc3Mgc3BhY2UgZm9yIHRoZSBhc3NvY2lhdGVkIHBvaW50ZXIKKyAgdW5zaWduZWQgZ2V0QWRkcmVzc1NwYWNlKCkgY29uc3QgeworICAgIHJldHVybiBnZXRQb2ludGVySW5mbygpLmdldEFkZHJTcGFjZSgpOworICB9CisKKyAgLy8vIFVwZGF0ZSB0aGlzIE1lbVNETm9kZSdzIE1hY2hpbmVNZW1PcGVyYW5kIGluZm9ybWF0aW9uCisgIC8vLyB0byByZWZsZWN0IHRoZSBhbGlnbm1lbnQgb2YgTmV3TU1PLCBpZiBpdCBoYXMgYSBncmVhdGVyIGFsaWdubWVudC4KKyAgLy8vIFRoaXMgbXVzdCBvbmx5IGJlIHVzZWQgd2hlbiB0aGUgbmV3IGFsaWdubWVudCBhcHBsaWVzIHRvIGFsbCB1c2VycyBvZgorICAvLy8gdGhpcyBNYWNoaW5lTWVtT3BlcmFuZC4KKyAgdm9pZCByZWZpbmVBbGlnbm1lbnQoY29uc3QgTWFjaGluZU1lbU9wZXJhbmQgKk5ld01NTykgeworICAgIE1NTy0+cmVmaW5lQWxpZ25tZW50KE5ld01NTyk7CisgIH0KKworICBjb25zdCBTRFZhbHVlICZnZXRDaGFpbigpIGNvbnN0IHsgcmV0dXJuIGdldE9wZXJhbmQoMCk7IH0KKyAgY29uc3QgU0RWYWx1ZSAmZ2V0QmFzZVB0cigpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0T3BlcmFuZChnZXRPcGNvZGUoKSA9PSBJU0Q6OlNUT1JFID8gMiA6IDEpOworICB9CisKKyAgLy8gTWV0aG9kcyB0byBzdXBwb3J0IGlzYSBhbmQgZHluX2Nhc3QKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICAvLyBGb3Igc29tZSB0YXJnZXRzLCB3ZSBsb3dlciBzb21lIHRhcmdldCBpbnRyaW5zaWNzIHRvIGEgTWVtSW50cmluc2ljTm9kZQorICAgIC8vIHdpdGggZWl0aGVyIGFuIGludHJpbnNpYyBvciBhIHRhcmdldCBvcGNvZGUuCisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6TE9BRCAgICAgICAgICAgICAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OlNUT1JFICAgICAgICAgICAgICAgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpQUkVGRVRDSCAgICAgICAgICAgIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6QVRPTUlDX0NNUF9TV0FQICAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OkFUT01JQ19DTVBfU1dBUF9XSVRIX1NVQ0NFU1MgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpBVE9NSUNfU1dBUCAgICAgICAgIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6QVRPTUlDX0xPQURfQUREICAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OkFUT01JQ19MT0FEX1NVQiAgICAgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpBVE9NSUNfTE9BRF9BTkQgICAgIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6QVRPTUlDX0xPQURfQ0xSICAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OkFUT01JQ19MT0FEX09SICAgICAgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpBVE9NSUNfTE9BRF9YT1IgICAgIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6QVRPTUlDX0xPQURfTkFORCAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OkFUT01JQ19MT0FEX01JTiAgICAgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpBVE9NSUNfTE9BRF9NQVggICAgIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6QVRPTUlDX0xPQURfVU1JTiAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OkFUT01JQ19MT0FEX1VNQVggICAgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpBVE9NSUNfTE9BRCAgICAgICAgIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6QVRPTUlDX1NUT1JFICAgICAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6Ok1MT0FEICAgICAgICAgICAgICAgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpNU1RPUkUgICAgICAgICAgICAgIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6TUdBVEhFUiAgICAgICAgICAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6Ok1TQ0FUVEVSICAgICAgICAgICAgfHwKKyAgICAgICAgICAgTi0+aXNNZW1JbnRyaW5zaWMoKSAgICAgICAgICAgICAgICAgICAgICAgIHx8CisgICAgICAgICAgIE4tPmlzVGFyZ2V0TWVtb3J5T3Bjb2RlKCk7CisgIH0KK307CisKKy8vLyBUaGlzIGlzIGFuIFNETm9kZSByZXByZXNlbnRpbmcgYXRvbWljIG9wZXJhdGlvbnMuCitjbGFzcyBBdG9taWNTRE5vZGUgOiBwdWJsaWMgTWVtU0ROb2RlIHsKK3B1YmxpYzoKKyAgQXRvbWljU0ROb2RlKHVuc2lnbmVkIE9wYywgdW5zaWduZWQgT3JkZXIsIGNvbnN0IERlYnVnTG9jICZkbCwgU0RWVExpc3QgVlRMLAorICAgICAgICAgICAgICAgRVZUIE1lbVZULCBNYWNoaW5lTWVtT3BlcmFuZCAqTU1PKQorICAgICAgOiBNZW1TRE5vZGUoT3BjLCBPcmRlciwgZGwsIFZUTCwgTWVtVlQsIE1NTykge30KKworICBjb25zdCBTRFZhbHVlICZnZXRCYXNlUHRyKCkgY29uc3QgeyByZXR1cm4gZ2V0T3BlcmFuZCgxKTsgfQorICBjb25zdCBTRFZhbHVlICZnZXRWYWwoKSBjb25zdCB7IHJldHVybiBnZXRPcGVyYW5kKDIpOyB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIFNETm9kZSByZXByZXNlbnRzIGNtcHhjaGcgYXRvbWljIG9wZXJhdGlvbiwgZmFsc2UKKyAgLy8vIG90aGVyd2lzZS4KKyAgYm9vbCBpc0NvbXBhcmVBbmRTd2FwKCkgY29uc3QgeworICAgIHVuc2lnbmVkIE9wID0gZ2V0T3Bjb2RlKCk7CisgICAgcmV0dXJuIE9wID09IElTRDo6QVRPTUlDX0NNUF9TV0FQIHx8CisgICAgICAgICAgIE9wID09IElTRDo6QVRPTUlDX0NNUF9TV0FQX1dJVEhfU1VDQ0VTUzsKKyAgfQorCisgIC8vLyBGb3IgY21weGNoZyBhdG9taWMgb3BlcmF0aW9ucywgcmV0dXJuIHRoZSBhdG9taWMgb3JkZXJpbmcgcmVxdWlyZW1lbnRzCisgIC8vLyB3aGVuIHN0b3JlIGRvZXMgbm90IG9jY3VyLgorICBBdG9taWNPcmRlcmluZyBnZXRGYWlsdXJlT3JkZXJpbmcoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzQ29tcGFyZUFuZFN3YXAoKSAmJiAiTXVzdCBiZSBjbXB4Y2hnIG9wZXJhdGlvbiIpOworICAgIHJldHVybiBNTU8tPmdldEZhaWx1cmVPcmRlcmluZygpOworICB9CisKKyAgLy8gTWV0aG9kcyB0byBzdXBwb3J0IGlzYSBhbmQgZHluX2Nhc3QKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpBVE9NSUNfQ01QX1NXQVAgICAgIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6QVRPTUlDX0NNUF9TV0FQX1dJVEhfU1VDQ0VTUyB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OkFUT01JQ19TV0FQICAgICAgICAgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpBVE9NSUNfTE9BRF9BREQgICAgIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6QVRPTUlDX0xPQURfU1VCICAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OkFUT01JQ19MT0FEX0FORCAgICAgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpBVE9NSUNfTE9BRF9DTFIgICAgIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6QVRPTUlDX0xPQURfT1IgICAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OkFUT01JQ19MT0FEX1hPUiAgICAgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpBVE9NSUNfTE9BRF9OQU5EICAgIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6QVRPTUlDX0xPQURfTUlOICAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OkFUT01JQ19MT0FEX01BWCAgICAgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpBVE9NSUNfTE9BRF9VTUlOICAgIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6QVRPTUlDX0xPQURfVU1BWCAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OkFUT01JQ19MT0FEICAgICAgICAgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpBVE9NSUNfU1RPUkU7CisgIH0KK307CisKKy8vLyBUaGlzIFNETm9kZSBpcyB1c2VkIGZvciB0YXJnZXQgaW50cmluc2ljcyB0aGF0IHRvdWNoCisvLy8gbWVtb3J5IGFuZCBuZWVkIGFuIGFzc29jaWF0ZWQgTWFjaGluZU1lbU9wZXJhbmQuIEl0cyBvcGNvZGUgbWF5IGJlCisvLy8gSU5UUklOU0lDX1ZPSUQsIElOVFJJTlNJQ19XX0NIQUlOLCBQUkVGRVRDSCwgb3IgYSB0YXJnZXQtc3BlY2lmaWMgb3Bjb2RlCisvLy8gd2l0aCBhIHZhbHVlIG5vdCBsZXNzIHRoYW4gRklSU1RfVEFSR0VUX01FTU9SWV9PUENPREUuCitjbGFzcyBNZW1JbnRyaW5zaWNTRE5vZGUgOiBwdWJsaWMgTWVtU0ROb2RlIHsKK3B1YmxpYzoKKyAgTWVtSW50cmluc2ljU0ROb2RlKHVuc2lnbmVkIE9wYywgdW5zaWduZWQgT3JkZXIsIGNvbnN0IERlYnVnTG9jICZkbCwKKyAgICAgICAgICAgICAgICAgICAgIFNEVlRMaXN0IFZUcywgRVZUIE1lbW9yeVZULCBNYWNoaW5lTWVtT3BlcmFuZCAqTU1PKQorICAgICAgOiBNZW1TRE5vZGUoT3BjLCBPcmRlciwgZGwsIFZUcywgTWVtb3J5VlQsIE1NTykgeworICAgIFNETm9kZUJpdHMuSXNNZW1JbnRyaW5zaWMgPSB0cnVlOworICB9CisKKyAgLy8gTWV0aG9kcyB0byBzdXBwb3J0IGlzYSBhbmQgZHluX2Nhc3QKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICAvLyBXZSBsb3dlciBzb21lIHRhcmdldCBpbnRyaW5zaWNzIHRvIHRoZWlyIHRhcmdldCBvcGNvZGUKKyAgICAvLyBlYXJseSBhIG5vZGUgd2l0aCBhIHRhcmdldCBvcGNvZGUgY2FuIGJlIG9mIHRoaXMgY2xhc3MKKyAgICByZXR1cm4gTi0+aXNNZW1JbnRyaW5zaWMoKSAgICAgICAgICAgICB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OlBSRUZFVENIIHx8CisgICAgICAgICAgIE4tPmlzVGFyZ2V0TWVtb3J5T3Bjb2RlKCk7CisgIH0KK307CisKKy8vLyBUaGlzIFNETm9kZSBpcyB1c2VkIHRvIGltcGxlbWVudCB0aGUgY29kZSBnZW5lcmF0b3IKKy8vLyBzdXBwb3J0IGZvciB0aGUgbGx2bSBJUiBzaHVmZmxldmVjdG9yIGluc3RydWN0aW9uLiAgSXQgY29tYmluZXMgZWxlbWVudHMKKy8vLyBmcm9tIHR3byBpbnB1dCB2ZWN0b3JzIGludG8gYSBuZXcgaW5wdXQgdmVjdG9yLCB3aXRoIHRoZSBzZWxlY3Rpb24gYW5kCisvLy8gb3JkZXJpbmcgb2YgZWxlbWVudHMgZGV0ZXJtaW5lZCBieSBhbiBhcnJheSBvZiBpbnRlZ2VycywgcmVmZXJyZWQgdG8gYXMKKy8vLyB0aGUgc2h1ZmZsZSBtYXNrLiAgRm9yIGlucHV0IHZlY3RvcnMgb2Ygd2lkdGggTiwgbWFzayBpbmRpY2VzIG9mIDAuLk4tMQorLy8vIHJlZmVyIHRvIGVsZW1lbnRzIGZyb20gdGhlIExIUyBpbnB1dCwgYW5kIGluZGljZXMgZnJvbSBOIHRvIDJOLTEgdGhlIFJIUy4KKy8vLyBBbiBpbmRleCBvZiAtMSBpcyB0cmVhdGVkIGFzIHVuZGVmLCBzdWNoIHRoYXQgdGhlIGNvZGUgZ2VuZXJhdG9yIG1heSBwdXQKKy8vLyBhbnkgdmFsdWUgaW4gdGhlIGNvcnJlc3BvbmRpbmcgZWxlbWVudCBvZiB0aGUgcmVzdWx0LgorY2xhc3MgU2h1ZmZsZVZlY3RvclNETm9kZSA6IHB1YmxpYyBTRE5vZGUgeworICAvLyBUaGUgbWVtb3J5IGZvciBNYXNrIGlzIG93bmVkIGJ5IHRoZSBTZWxlY3Rpb25EQUcncyBPcGVyYW5kQWxsb2NhdG9yLCBhbmQKKyAgLy8gaXMgZnJlZWQgd2hlbiB0aGUgU2VsZWN0aW9uREFHIG9iamVjdCBpcyBkZXN0cm95ZWQuCisgIGNvbnN0IGludCAqTWFzazsKKworcHJvdGVjdGVkOgorICBmcmllbmQgY2xhc3MgU2VsZWN0aW9uREFHOworCisgIFNodWZmbGVWZWN0b3JTRE5vZGUoRVZUIFZULCB1bnNpZ25lZCBPcmRlciwgY29uc3QgRGVidWdMb2MgJmRsLCBjb25zdCBpbnQgKk0pCisgICAgICA6IFNETm9kZShJU0Q6OlZFQ1RPUl9TSFVGRkxFLCBPcmRlciwgZGwsIGdldFNEVlRMaXN0KFZUKSksIE1hc2soTSkge30KKworcHVibGljOgorICBBcnJheVJlZjxpbnQ+IGdldE1hc2soKSBjb25zdCB7CisgICAgRVZUIFZUID0gZ2V0VmFsdWVUeXBlKDApOworICAgIHJldHVybiBtYWtlQXJyYXlSZWYoTWFzaywgVlQuZ2V0VmVjdG9yTnVtRWxlbWVudHMoKSk7CisgIH0KKworICBpbnQgZ2V0TWFza0VsdCh1bnNpZ25lZCBJZHgpIGNvbnN0IHsKKyAgICBhc3NlcnQoSWR4IDwgZ2V0VmFsdWVUeXBlKDApLmdldFZlY3Rvck51bUVsZW1lbnRzKCkgJiYgIklkeCBvdXQgb2YgcmFuZ2UhIik7CisgICAgcmV0dXJuIE1hc2tbSWR4XTsKKyAgfQorCisgIGJvb2wgaXNTcGxhdCgpIGNvbnN0IHsgcmV0dXJuIGlzU3BsYXRNYXNrKE1hc2ssIGdldFZhbHVlVHlwZSgwKSk7IH0KKworICBpbnQgIGdldFNwbGF0SW5kZXgoKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzU3BsYXQoKSAmJiAiQ2Fubm90IGdldCBzcGxhdCBpbmRleCBmb3Igbm9uLXNwbGF0ISIpOworICAgIEVWVCBWVCA9IGdldFZhbHVlVHlwZSgwKTsKKyAgICBmb3IgKHVuc2lnbmVkIGkgPSAwLCBlID0gVlQuZ2V0VmVjdG9yTnVtRWxlbWVudHMoKTsgaSAhPSBlOyArK2kpIHsKKyAgICAgIGlmIChNYXNrW2ldID49IDApCisgICAgICAgIHJldHVybiBNYXNrW2ldOworICAgIH0KKyAgICBsbHZtX3VucmVhY2hhYmxlKCJTcGxhdCB3aXRoIGFsbCB1bmRlZiBpbmRpY2VzPyIpOworICB9CisKKyAgc3RhdGljIGJvb2wgaXNTcGxhdE1hc2soY29uc3QgaW50ICpNYXNrLCBFVlQgVlQpOworCisgIC8vLyBDaGFuZ2UgdmFsdWVzIGluIGEgc2h1ZmZsZSBwZXJtdXRlIG1hc2sgYXNzdW1pbmcKKyAgLy8vIHRoZSB0d28gdmVjdG9yIG9wZXJhbmRzIGhhdmUgc3dhcHBlZCBwb3NpdGlvbi4KKyAgc3RhdGljIHZvaWQgY29tbXV0ZU1hc2soTXV0YWJsZUFycmF5UmVmPGludD4gTWFzaykgeworICAgIHVuc2lnbmVkIE51bUVsZW1zID0gTWFzay5zaXplKCk7CisgICAgZm9yICh1bnNpZ25lZCBpID0gMDsgaSAhPSBOdW1FbGVtczsgKytpKSB7CisgICAgICBpbnQgaWR4ID0gTWFza1tpXTsKKyAgICAgIGlmIChpZHggPCAwKQorICAgICAgICBjb250aW51ZTsKKyAgICAgIGVsc2UgaWYgKGlkeCA8IChpbnQpTnVtRWxlbXMpCisgICAgICAgIE1hc2tbaV0gPSBpZHggKyBOdW1FbGVtczsKKyAgICAgIGVsc2UKKyAgICAgICAgTWFza1tpXSA9IGlkeCAtIE51bUVsZW1zOworICAgIH0KKyAgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6VkVDVE9SX1NIVUZGTEU7CisgIH0KK307CisKK2NsYXNzIENvbnN0YW50U0ROb2RlIDogcHVibGljIFNETm9kZSB7CisgIGZyaWVuZCBjbGFzcyBTZWxlY3Rpb25EQUc7CisKKyAgY29uc3QgQ29uc3RhbnRJbnQgKlZhbHVlOworCisgIENvbnN0YW50U0ROb2RlKGJvb2wgaXNUYXJnZXQsIGJvb2wgaXNPcGFxdWUsIGNvbnN0IENvbnN0YW50SW50ICp2YWwsCisgICAgICAgICAgICAgICAgIGNvbnN0IERlYnVnTG9jICZETCwgRVZUIFZUKQorICAgICAgOiBTRE5vZGUoaXNUYXJnZXQgPyBJU0Q6OlRhcmdldENvbnN0YW50IDogSVNEOjpDb25zdGFudCwgMCwgREwsCisgICAgICAgICAgICAgICBnZXRTRFZUTGlzdChWVCkpLAorICAgICAgICBWYWx1ZSh2YWwpIHsKKyAgICBDb25zdGFudFNETm9kZUJpdHMuSXNPcGFxdWUgPSBpc09wYXF1ZTsKKyAgfQorCitwdWJsaWM6CisgIGNvbnN0IENvbnN0YW50SW50ICpnZXRDb25zdGFudEludFZhbHVlKCkgY29uc3QgeyByZXR1cm4gVmFsdWU7IH0KKyAgY29uc3QgQVBJbnQgJmdldEFQSW50VmFsdWUoKSBjb25zdCB7IHJldHVybiBWYWx1ZS0+Z2V0VmFsdWUoKTsgfQorICB1aW50NjRfdCBnZXRaRXh0VmFsdWUoKSBjb25zdCB7IHJldHVybiBWYWx1ZS0+Z2V0WkV4dFZhbHVlKCk7IH0KKyAgaW50NjRfdCBnZXRTRXh0VmFsdWUoKSBjb25zdCB7IHJldHVybiBWYWx1ZS0+Z2V0U0V4dFZhbHVlKCk7IH0KKyAgdWludDY0X3QgZ2V0TGltaXRlZFZhbHVlKHVpbnQ2NF90IExpbWl0ID0gVUlOVDY0X01BWCkgeworICAgIHJldHVybiBWYWx1ZS0+Z2V0TGltaXRlZFZhbHVlKExpbWl0KTsKKyAgfQorCisgIGJvb2wgaXNPbmUoKSBjb25zdCB7IHJldHVybiBWYWx1ZS0+aXNPbmUoKTsgfQorICBib29sIGlzTnVsbFZhbHVlKCkgY29uc3QgeyByZXR1cm4gVmFsdWUtPmlzWmVybygpOyB9CisgIGJvb2wgaXNBbGxPbmVzVmFsdWUoKSBjb25zdCB7IHJldHVybiBWYWx1ZS0+aXNNaW51c09uZSgpOyB9CisKKyAgYm9vbCBpc09wYXF1ZSgpIGNvbnN0IHsgcmV0dXJuIENvbnN0YW50U0ROb2RlQml0cy5Jc09wYXF1ZTsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6Q29uc3RhbnQgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpUYXJnZXRDb25zdGFudDsKKyAgfQorfTsKKwordWludDY0X3QgU0ROb2RlOjpnZXRDb25zdGFudE9wZXJhbmRWYWwodW5zaWduZWQgTnVtKSBjb25zdCB7CisgIHJldHVybiBjYXN0PENvbnN0YW50U0ROb2RlPihnZXRPcGVyYW5kKE51bSkpLT5nZXRaRXh0VmFsdWUoKTsKK30KKworY2xhc3MgQ29uc3RhbnRGUFNETm9kZSA6IHB1YmxpYyBTRE5vZGUgeworICBmcmllbmQgY2xhc3MgU2VsZWN0aW9uREFHOworCisgIGNvbnN0IENvbnN0YW50RlAgKlZhbHVlOworCisgIENvbnN0YW50RlBTRE5vZGUoYm9vbCBpc1RhcmdldCwgY29uc3QgQ29uc3RhbnRGUCAqdmFsLCBjb25zdCBEZWJ1Z0xvYyAmREwsCisgICAgICAgICAgICAgICAgICAgRVZUIFZUKQorICAgICAgOiBTRE5vZGUoaXNUYXJnZXQgPyBJU0Q6OlRhcmdldENvbnN0YW50RlAgOiBJU0Q6OkNvbnN0YW50RlAsIDAsIERMLAorICAgICAgICAgICAgICAgZ2V0U0RWVExpc3QoVlQpKSwKKyAgICAgICAgVmFsdWUodmFsKSB7fQorCitwdWJsaWM6CisgIGNvbnN0IEFQRmxvYXQmIGdldFZhbHVlQVBGKCkgY29uc3QgeyByZXR1cm4gVmFsdWUtPmdldFZhbHVlQVBGKCk7IH0KKyAgY29uc3QgQ29uc3RhbnRGUCAqZ2V0Q29uc3RhbnRGUFZhbHVlKCkgY29uc3QgeyByZXR1cm4gVmFsdWU7IH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIGlzIHBvc2l0aXZlIG9yIG5lZ2F0aXZlIHplcm8uCisgIGJvb2wgaXNaZXJvKCkgY29uc3QgeyByZXR1cm4gVmFsdWUtPmlzWmVybygpOyB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSB2YWx1ZSBpcyBhIE5hTi4KKyAgYm9vbCBpc05hTigpIGNvbnN0IHsgcmV0dXJuIFZhbHVlLT5pc05hTigpOyB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSB2YWx1ZSBpcyBhbiBpbmZpbml0eQorICBib29sIGlzSW5maW5pdHkoKSBjb25zdCB7IHJldHVybiBWYWx1ZS0+aXNJbmZpbml0eSgpOyB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSB2YWx1ZSBpcyBuZWdhdGl2ZS4KKyAgYm9vbCBpc05lZ2F0aXZlKCkgY29uc3QgeyByZXR1cm4gVmFsdWUtPmlzTmVnYXRpdmUoKTsgfQorCisgIC8vLyBXZSBkb24ndCByZWx5IG9uIG9wZXJhdG9yPT0gd29ya2luZyBvbiBkb3VibGUgdmFsdWVzLCBhcworICAvLy8gaXQgcmV0dXJucyB0cnVlIGZvciB0aGluZ3MgdGhhdCBhcmUgY2xlYXJseSBub3QgZXF1YWwsIGxpa2UgLTAuMCBhbmQgMC4wLgorICAvLy8gQXMgc3VjaCwgdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gZG8gYW4gZXhhY3QgYml0LWZvci1iaXQgY29tcGFyaXNvbiBvZgorICAvLy8gdHdvIGZsb2F0aW5nIHBvaW50IHZhbHVlcy4KKworICAvLy8gV2UgbGVhdmUgdGhlIHZlcnNpb24gd2l0aCB0aGUgZG91YmxlIGFyZ3VtZW50IGhlcmUgYmVjYXVzZSBpdCdzIGp1c3Qgc28KKyAgLy8vIGNvbnZlbmllbnQgdG8gd3JpdGUgIjIuMCIgYW5kIHRoZSBsaWtlLiAgV2l0aG91dCB0aGlzIGZ1bmN0aW9uIHdlJ2QKKyAgLy8vIGhhdmUgdG8gZHVwbGljYXRlIGl0cyBsb2dpYyBldmVyeXdoZXJlIGl0J3MgY2FsbGVkLgorICBib29sIGlzRXhhY3RseVZhbHVlKGRvdWJsZSBWKSBjb25zdCB7CisgICAgcmV0dXJuIFZhbHVlLT5nZXRWYWx1ZUFQRigpLmlzRXhhY3RseVZhbHVlKFYpOworICB9CisgIGJvb2wgaXNFeGFjdGx5VmFsdWUoY29uc3QgQVBGbG9hdCYgVikgY29uc3Q7CisKKyAgc3RhdGljIGJvb2wgaXNWYWx1ZVZhbGlkRm9yVHlwZShFVlQgVlQsIGNvbnN0IEFQRmxvYXQmIFZhbCk7CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpDb25zdGFudEZQIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6VGFyZ2V0Q29uc3RhbnRGUDsKKyAgfQorfTsKKworLy8vIFJldHVybnMgdHJ1ZSBpZiBccCBWIGlzIGEgY29uc3RhbnQgaW50ZWdlciB6ZXJvLgorYm9vbCBpc051bGxDb25zdGFudChTRFZhbHVlIFYpOworCisvLy8gUmV0dXJucyB0cnVlIGlmIFxwIFYgaXMgYW4gRlAgY29uc3RhbnQgd2l0aCBhIHZhbHVlIG9mIHBvc2l0aXZlIHplcm8uCitib29sIGlzTnVsbEZQQ29uc3RhbnQoU0RWYWx1ZSBWKTsKKworLy8vIFJldHVybnMgdHJ1ZSBpZiBccCBWIGlzIGFuIGludGVnZXIgY29uc3RhbnQgd2l0aCBhbGwgYml0cyBzZXQuCitib29sIGlzQWxsT25lc0NvbnN0YW50KFNEVmFsdWUgVik7CisKKy8vLyBSZXR1cm5zIHRydWUgaWYgXHAgViBpcyBhIGNvbnN0YW50IGludGVnZXIgb25lLgorYm9vbCBpc09uZUNvbnN0YW50KFNEVmFsdWUgVik7CisKKy8vLyBSZXR1cm5zIHRydWUgaWYgXHAgViBpcyBhIGJpdHdpc2Ugbm90IG9wZXJhdGlvbi4gQXNzdW1lcyB0aGF0IGFuIGFsbCBvbmVzCisvLy8gY29uc3RhbnQgaXMgY2Fub25pY2FsaXplZCB0byBiZSBvcGVyYW5kIDEuCitib29sIGlzQml0d2lzZU5vdChTRFZhbHVlIFYpOworCisvLy8gUmV0dXJucyB0aGUgU0ROb2RlIGlmIGl0IGlzIGEgY29uc3RhbnQgc3BsYXQgQnVpbGRWZWN0b3Igb3IgY29uc3RhbnQgaW50LgorQ29uc3RhbnRTRE5vZGUgKmlzQ29uc3RPckNvbnN0U3BsYXQoU0RWYWx1ZSBWKTsKKworLy8vIFJldHVybnMgdGhlIFNETm9kZSBpZiBpdCBpcyBhIGNvbnN0YW50IHNwbGF0IEJ1aWxkVmVjdG9yIG9yIGNvbnN0YW50IGZsb2F0LgorQ29uc3RhbnRGUFNETm9kZSAqaXNDb25zdE9yQ29uc3RTcGxhdEZQKFNEVmFsdWUgVik7CisKK2NsYXNzIEdsb2JhbEFkZHJlc3NTRE5vZGUgOiBwdWJsaWMgU0ROb2RlIHsKKyAgZnJpZW5kIGNsYXNzIFNlbGVjdGlvbkRBRzsKKworICBjb25zdCBHbG9iYWxWYWx1ZSAqVGhlR2xvYmFsOworICBpbnQ2NF90IE9mZnNldDsKKyAgdW5zaWduZWQgY2hhciBUYXJnZXRGbGFnczsKKworICBHbG9iYWxBZGRyZXNzU0ROb2RlKHVuc2lnbmVkIE9wYywgdW5zaWduZWQgT3JkZXIsIGNvbnN0IERlYnVnTG9jICZETCwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBHbG9iYWxWYWx1ZSAqR0EsIEVWVCBWVCwgaW50NjRfdCBvLAorICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3MpOworCitwdWJsaWM6CisgIGNvbnN0IEdsb2JhbFZhbHVlICpnZXRHbG9iYWwoKSBjb25zdCB7IHJldHVybiBUaGVHbG9iYWw7IH0KKyAgaW50NjRfdCBnZXRPZmZzZXQoKSBjb25zdCB7IHJldHVybiBPZmZzZXQ7IH0KKyAgdW5zaWduZWQgY2hhciBnZXRUYXJnZXRGbGFncygpIGNvbnN0IHsgcmV0dXJuIFRhcmdldEZsYWdzOyB9CisgIC8vIFJldHVybiB0aGUgYWRkcmVzcyBzcGFjZSB0aGlzIEdsb2JhbEFkZHJlc3MgYmVsb25ncyB0by4KKyAgdW5zaWduZWQgZ2V0QWRkcmVzc1NwYWNlKCkgY29uc3Q7CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpHbG9iYWxBZGRyZXNzIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6VGFyZ2V0R2xvYmFsQWRkcmVzcyB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6Okdsb2JhbFRMU0FkZHJlc3MgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpUYXJnZXRHbG9iYWxUTFNBZGRyZXNzOworICB9Cit9OworCitjbGFzcyBGcmFtZUluZGV4U0ROb2RlIDogcHVibGljIFNETm9kZSB7CisgIGZyaWVuZCBjbGFzcyBTZWxlY3Rpb25EQUc7CisKKyAgaW50IEZJOworCisgIEZyYW1lSW5kZXhTRE5vZGUoaW50IGZpLCBFVlQgVlQsIGJvb2wgaXNUYXJnKQorICAgIDogU0ROb2RlKGlzVGFyZyA/IElTRDo6VGFyZ2V0RnJhbWVJbmRleCA6IElTRDo6RnJhbWVJbmRleCwKKyAgICAgIDAsIERlYnVnTG9jKCksIGdldFNEVlRMaXN0KFZUKSksIEZJKGZpKSB7CisgIH0KKworcHVibGljOgorICBpbnQgZ2V0SW5kZXgoKSBjb25zdCB7IHJldHVybiBGSTsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6RnJhbWVJbmRleCB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OlRhcmdldEZyYW1lSW5kZXg7CisgIH0KK307CisKK2NsYXNzIEp1bXBUYWJsZVNETm9kZSA6IHB1YmxpYyBTRE5vZGUgeworICBmcmllbmQgY2xhc3MgU2VsZWN0aW9uREFHOworCisgIGludCBKVEk7CisgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3M7CisKKyAgSnVtcFRhYmxlU0ROb2RlKGludCBqdGksIEVWVCBWVCwgYm9vbCBpc1RhcmcsIHVuc2lnbmVkIGNoYXIgVEYpCisgICAgOiBTRE5vZGUoaXNUYXJnID8gSVNEOjpUYXJnZXRKdW1wVGFibGUgOiBJU0Q6Okp1bXBUYWJsZSwKKyAgICAgIDAsIERlYnVnTG9jKCksIGdldFNEVlRMaXN0KFZUKSksIEpUSShqdGkpLCBUYXJnZXRGbGFncyhURikgeworICB9CisKK3B1YmxpYzoKKyAgaW50IGdldEluZGV4KCkgY29uc3QgeyByZXR1cm4gSlRJOyB9CisgIHVuc2lnbmVkIGNoYXIgZ2V0VGFyZ2V0RmxhZ3MoKSBjb25zdCB7IHJldHVybiBUYXJnZXRGbGFnczsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6SnVtcFRhYmxlIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6VGFyZ2V0SnVtcFRhYmxlOworICB9Cit9OworCitjbGFzcyBDb25zdGFudFBvb2xTRE5vZGUgOiBwdWJsaWMgU0ROb2RlIHsKKyAgZnJpZW5kIGNsYXNzIFNlbGVjdGlvbkRBRzsKKworICB1bmlvbiB7CisgICAgY29uc3QgQ29uc3RhbnQgKkNvbnN0VmFsOworICAgIE1hY2hpbmVDb25zdGFudFBvb2xWYWx1ZSAqTWFjaGluZUNQVmFsOworICB9IFZhbDsKKyAgaW50IE9mZnNldDsgIC8vIEl0J3MgYSBNYWNoaW5lQ29uc3RhbnRQb29sVmFsdWUgaWYgdG9wIGJpdCBpcyBzZXQuCisgIHVuc2lnbmVkIEFsaWdubWVudDsgIC8vIE1pbmltdW0gYWxpZ25tZW50IHJlcXVpcmVtZW50IG9mIENQIChub3QgbG9nMiB2YWx1ZSkuCisgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3M7CisKKyAgQ29uc3RhbnRQb29sU0ROb2RlKGJvb2wgaXNUYXJnZXQsIGNvbnN0IENvbnN0YW50ICpjLCBFVlQgVlQsIGludCBvLAorICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgQWxpZ24sIHVuc2lnbmVkIGNoYXIgVEYpCisgICAgOiBTRE5vZGUoaXNUYXJnZXQgPyBJU0Q6OlRhcmdldENvbnN0YW50UG9vbCA6IElTRDo6Q29uc3RhbnRQb29sLCAwLAorICAgICAgICAgICAgIERlYnVnTG9jKCksIGdldFNEVlRMaXN0KFZUKSksIE9mZnNldChvKSwgQWxpZ25tZW50KEFsaWduKSwKKyAgICAgICAgICAgICBUYXJnZXRGbGFncyhURikgeworICAgIGFzc2VydChPZmZzZXQgPj0gMCAmJiAiT2Zmc2V0IGlzIHRvbyBsYXJnZSIpOworICAgIFZhbC5Db25zdFZhbCA9IGM7CisgIH0KKworICBDb25zdGFudFBvb2xTRE5vZGUoYm9vbCBpc1RhcmdldCwgTWFjaGluZUNvbnN0YW50UG9vbFZhbHVlICp2LAorICAgICAgICAgICAgICAgICAgICAgRVZUIFZULCBpbnQgbywgdW5zaWduZWQgQWxpZ24sIHVuc2lnbmVkIGNoYXIgVEYpCisgICAgOiBTRE5vZGUoaXNUYXJnZXQgPyBJU0Q6OlRhcmdldENvbnN0YW50UG9vbCA6IElTRDo6Q29uc3RhbnRQb29sLCAwLAorICAgICAgICAgICAgIERlYnVnTG9jKCksIGdldFNEVlRMaXN0KFZUKSksIE9mZnNldChvKSwgQWxpZ25tZW50KEFsaWduKSwKKyAgICAgICAgICAgICBUYXJnZXRGbGFncyhURikgeworICAgIGFzc2VydChPZmZzZXQgPj0gMCAmJiAiT2Zmc2V0IGlzIHRvbyBsYXJnZSIpOworICAgIFZhbC5NYWNoaW5lQ1BWYWwgPSB2OworICAgIE9mZnNldCB8PSAxIDw8IChzaXplb2YodW5zaWduZWQpKkNIQVJfQklULTEpOworICB9CisKK3B1YmxpYzoKKyAgYm9vbCBpc01hY2hpbmVDb25zdGFudFBvb2xFbnRyeSgpIGNvbnN0IHsKKyAgICByZXR1cm4gT2Zmc2V0IDwgMDsKKyAgfQorCisgIGNvbnN0IENvbnN0YW50ICpnZXRDb25zdFZhbCgpIGNvbnN0IHsKKyAgICBhc3NlcnQoIWlzTWFjaGluZUNvbnN0YW50UG9vbEVudHJ5KCkgJiYgIldyb25nIGNvbnN0YW50cG9vbCB0eXBlIik7CisgICAgcmV0dXJuIFZhbC5Db25zdFZhbDsKKyAgfQorCisgIE1hY2hpbmVDb25zdGFudFBvb2xWYWx1ZSAqZ2V0TWFjaGluZUNQVmFsKCkgY29uc3QgeworICAgIGFzc2VydChpc01hY2hpbmVDb25zdGFudFBvb2xFbnRyeSgpICYmICJXcm9uZyBjb25zdGFudHBvb2wgdHlwZSIpOworICAgIHJldHVybiBWYWwuTWFjaGluZUNQVmFsOworICB9CisKKyAgaW50IGdldE9mZnNldCgpIGNvbnN0IHsKKyAgICByZXR1cm4gT2Zmc2V0ICYgfigxIDw8IChzaXplb2YodW5zaWduZWQpKkNIQVJfQklULTEpKTsKKyAgfQorCisgIC8vIFJldHVybiB0aGUgYWxpZ25tZW50IG9mIHRoaXMgY29uc3RhbnQgcG9vbCBvYmplY3QsIHdoaWNoIGlzIGVpdGhlciAwIChmb3IKKyAgLy8gZGVmYXVsdCBhbGlnbm1lbnQpIG9yIHRoZSBkZXNpcmVkIHZhbHVlLgorICB1bnNpZ25lZCBnZXRBbGlnbm1lbnQoKSBjb25zdCB7IHJldHVybiBBbGlnbm1lbnQ7IH0KKyAgdW5zaWduZWQgY2hhciBnZXRUYXJnZXRGbGFncygpIGNvbnN0IHsgcmV0dXJuIFRhcmdldEZsYWdzOyB9CisKKyAgVHlwZSAqZ2V0VHlwZSgpIGNvbnN0OworCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6Q29uc3RhbnRQb29sIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6VGFyZ2V0Q29uc3RhbnRQb29sOworICB9Cit9OworCisvLy8gQ29tcGxldGVseSB0YXJnZXQtZGVwZW5kZW50IG9iamVjdCByZWZlcmVuY2UuCitjbGFzcyBUYXJnZXRJbmRleFNETm9kZSA6IHB1YmxpYyBTRE5vZGUgeworICBmcmllbmQgY2xhc3MgU2VsZWN0aW9uREFHOworCisgIHVuc2lnbmVkIGNoYXIgVGFyZ2V0RmxhZ3M7CisgIGludCBJbmRleDsKKyAgaW50NjRfdCBPZmZzZXQ7CisKK3B1YmxpYzoKKyAgVGFyZ2V0SW5kZXhTRE5vZGUoaW50IElkeCwgRVZUIFZULCBpbnQ2NF90IE9mcywgdW5zaWduZWQgY2hhciBURikKKyAgICA6IFNETm9kZShJU0Q6OlRhcmdldEluZGV4LCAwLCBEZWJ1Z0xvYygpLCBnZXRTRFZUTGlzdChWVCkpLAorICAgICAgVGFyZ2V0RmxhZ3MoVEYpLCBJbmRleChJZHgpLCBPZmZzZXQoT2ZzKSB7fQorCisgIHVuc2lnbmVkIGNoYXIgZ2V0VGFyZ2V0RmxhZ3MoKSBjb25zdCB7IHJldHVybiBUYXJnZXRGbGFnczsgfQorICBpbnQgZ2V0SW5kZXgoKSBjb25zdCB7IHJldHVybiBJbmRleDsgfQorICBpbnQ2NF90IGdldE9mZnNldCgpIGNvbnN0IHsgcmV0dXJuIE9mZnNldDsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6VGFyZ2V0SW5kZXg7CisgIH0KK307CisKK2NsYXNzIEJhc2ljQmxvY2tTRE5vZGUgOiBwdWJsaWMgU0ROb2RlIHsKKyAgZnJpZW5kIGNsYXNzIFNlbGVjdGlvbkRBRzsKKworICBNYWNoaW5lQmFzaWNCbG9jayAqTUJCOworCisgIC8vLyBEZWJ1ZyBpbmZvIGlzIG1lYW5pbmdmdWwgYW5kIHBvdGVudGlhbGx5IHVzZWZ1bCBoZXJlLCBidXQgd2UgY3JlYXRlCisgIC8vLyBibG9ja3Mgb3V0IG9mIG9yZGVyIHdoZW4gdGhleSdyZSBqdW1wZWQgdG8sIHdoaWNoIG1ha2VzIGl0IGEgYml0CisgIC8vLyBoYXJkZXIuICBMZXQncyBzZWUgaWYgd2UgbmVlZCBpdCBmaXJzdC4KKyAgZXhwbGljaXQgQmFzaWNCbG9ja1NETm9kZShNYWNoaW5lQmFzaWNCbG9jayAqbWJiKQorICAgIDogU0ROb2RlKElTRDo6QmFzaWNCbG9jaywgMCwgRGVidWdMb2MoKSwgZ2V0U0RWVExpc3QoTVZUOjpPdGhlcikpLCBNQkIobWJiKQorICB7fQorCitwdWJsaWM6CisgIE1hY2hpbmVCYXNpY0Jsb2NrICpnZXRCYXNpY0Jsb2NrKCkgY29uc3QgeyByZXR1cm4gTUJCOyB9CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpCYXNpY0Jsb2NrOworICB9Cit9OworCisvLy8gQSAicHNldWRvLWNsYXNzIiB3aXRoIG1ldGhvZHMgZm9yIG9wZXJhdGluZyBvbiBCVUlMRF9WRUNUT1JzLgorY2xhc3MgQnVpbGRWZWN0b3JTRE5vZGUgOiBwdWJsaWMgU0ROb2RlIHsKK3B1YmxpYzoKKyAgLy8gVGhlc2UgYXJlIGNvbnN0cnVjdGVkIGFzIFNETm9kZXMgYW5kIHRoZW4gY2FzdCB0byBCdWlsZFZlY3RvclNETm9kZXMuCisgIGV4cGxpY2l0IEJ1aWxkVmVjdG9yU0ROb2RlKCkgPSBkZWxldGU7CisKKyAgLy8vIENoZWNrIGlmIHRoaXMgaXMgYSBjb25zdGFudCBzcGxhdCwgYW5kIGlmIHNvLCBmaW5kIHRoZQorICAvLy8gc21hbGxlc3QgZWxlbWVudCBzaXplIHRoYXQgc3BsYXRzIHRoZSB2ZWN0b3IuICBJZiBNaW5TcGxhdEJpdHMgaXMKKyAgLy8vIG5vbnplcm8sIHRoZSBlbGVtZW50IHNpemUgbXVzdCBiZSBhdCBsZWFzdCB0aGF0IGxhcmdlLiAgTm90ZSB0aGF0IHRoZQorICAvLy8gc3BsYXQgZWxlbWVudCBtYXkgYmUgdGhlIGVudGlyZSB2ZWN0b3IgKGkuZS4sIGEgb25lIGVsZW1lbnQgdmVjdG9yKS4KKyAgLy8vIFJldHVybnMgdGhlIHNwbGF0IGVsZW1lbnQgdmFsdWUgaW4gU3BsYXRWYWx1ZS4gIEFueSB1bmRlZmluZWQgYml0cyBpbgorICAvLy8gdGhhdCB2YWx1ZSBhcmUgemVybywgYW5kIHRoZSBjb3JyZXNwb25kaW5nIGJpdHMgaW4gdGhlIFNwbGF0VW5kZWYgbWFzaworICAvLy8gYXJlIHNldC4gIFRoZSBTcGxhdEJpdFNpemUgdmFsdWUgaXMgc2V0IHRvIHRoZSBzcGxhdCBlbGVtZW50IHNpemUgaW4KKyAgLy8vIGJpdHMuICBIYXNBbnlVbmRlZnMgaXMgc2V0IHRvIHRydWUgaWYgYW55IGJpdHMgaW4gdGhlIHZlY3RvciBhcmUKKyAgLy8vIHVuZGVmaW5lZC4gIGlzQmlnRW5kaWFuIGRlc2NyaWJlcyB0aGUgZW5kaWFubmVzcyBvZiB0aGUgdGFyZ2V0LgorICBib29sIGlzQ29uc3RhbnRTcGxhdChBUEludCAmU3BsYXRWYWx1ZSwgQVBJbnQgJlNwbGF0VW5kZWYsCisgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkICZTcGxhdEJpdFNpemUsIGJvb2wgJkhhc0FueVVuZGVmcywKKyAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgTWluU3BsYXRCaXRzID0gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc0JpZ0VuZGlhbiA9IGZhbHNlKSBjb25zdDsKKworICAvLy8gXGJyaWVmIFJldHVybnMgdGhlIHNwbGF0dGVkIHZhbHVlIG9yIGEgbnVsbCB2YWx1ZSBpZiB0aGlzIGlzIG5vdCBhIHNwbGF0LgorICAvLy8KKyAgLy8vIElmIHBhc3NlZCBhIG5vbi1udWxsIFVuZGVmRWxlbWVudHMgYml0dmVjdG9yLCBpdCB3aWxsIHJlc2l6ZSBpdCB0byBtYXRjaAorICAvLy8gdGhlIHZlY3RvciB3aWR0aCBhbmQgc2V0IHRoZSBiaXRzIHdoZXJlIGVsZW1lbnRzIGFyZSB1bmRlZi4KKyAgU0RWYWx1ZSBnZXRTcGxhdFZhbHVlKEJpdFZlY3RvciAqVW5kZWZFbGVtZW50cyA9IG51bGxwdHIpIGNvbnN0OworCisgIC8vLyBcYnJpZWYgUmV0dXJucyB0aGUgc3BsYXR0ZWQgY29uc3RhbnQgb3IgbnVsbCBpZiB0aGlzIGlzIG5vdCBhIGNvbnN0YW50CisgIC8vLyBzcGxhdC4KKyAgLy8vCisgIC8vLyBJZiBwYXNzZWQgYSBub24tbnVsbCBVbmRlZkVsZW1lbnRzIGJpdHZlY3RvciwgaXQgd2lsbCByZXNpemUgaXQgdG8gbWF0Y2gKKyAgLy8vIHRoZSB2ZWN0b3Igd2lkdGggYW5kIHNldCB0aGUgYml0cyB3aGVyZSBlbGVtZW50cyBhcmUgdW5kZWYuCisgIENvbnN0YW50U0ROb2RlICoKKyAgZ2V0Q29uc3RhbnRTcGxhdE5vZGUoQml0VmVjdG9yICpVbmRlZkVsZW1lbnRzID0gbnVsbHB0cikgY29uc3Q7CisKKyAgLy8vIFxicmllZiBSZXR1cm5zIHRoZSBzcGxhdHRlZCBjb25zdGFudCBGUCBvciBudWxsIGlmIHRoaXMgaXMgbm90IGEgY29uc3RhbnQKKyAgLy8vIEZQIHNwbGF0LgorICAvLy8KKyAgLy8vIElmIHBhc3NlZCBhIG5vbi1udWxsIFVuZGVmRWxlbWVudHMgYml0dmVjdG9yLCBpdCB3aWxsIHJlc2l6ZSBpdCB0byBtYXRjaAorICAvLy8gdGhlIHZlY3RvciB3aWR0aCBhbmQgc2V0IHRoZSBiaXRzIHdoZXJlIGVsZW1lbnRzIGFyZSB1bmRlZi4KKyAgQ29uc3RhbnRGUFNETm9kZSAqCisgIGdldENvbnN0YW50RlBTcGxhdE5vZGUoQml0VmVjdG9yICpVbmRlZkVsZW1lbnRzID0gbnVsbHB0cikgY29uc3Q7CisKKyAgLy8vIFxicmllZiBJZiB0aGlzIGlzIGEgY29uc3RhbnQgRlAgc3BsYXQgYW5kIHRoZSBzcGxhdHRlZCBjb25zdGFudCBGUCBpcyBhbgorICAvLy8gZXhhY3QgcG93ZXIgb3IgMiwgcmV0dXJuIHRoZSBsb2cgYmFzZSAyIGludGVnZXIgdmFsdWUuICBPdGhlcndpc2UsCisgIC8vLyByZXR1cm4gLTEuCisgIC8vLworICAvLy8gVGhlIEJpdFdpZHRoIHNwZWNpZmllcyB0aGUgbmVjZXNzYXJ5IGJpdCBwcmVjaXNpb24uCisgIGludDMyX3QgZ2V0Q29uc3RhbnRGUFNwbGF0UG93MlRvTG9nMkludChCaXRWZWN0b3IgKlVuZGVmRWxlbWVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBCaXRXaWR0aCkgY29uc3Q7CisKKyAgYm9vbCBpc0NvbnN0YW50KCkgY29uc3Q7CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpCVUlMRF9WRUNUT1I7CisgIH0KK307CisKKy8vLyBBbiBTRE5vZGUgdGhhdCBob2xkcyBhbiBhcmJpdHJhcnkgTExWTSBJUiBWYWx1ZS4gVGhpcyBpcworLy8vIHVzZWQgd2hlbiB0aGUgU2VsZWN0aW9uREFHIG5lZWRzIHRvIG1ha2UgYSBzaW1wbGUgcmVmZXJlbmNlIHRvIHNvbWV0aGluZworLy8vIGluIHRoZSBMTFZNIElSIHJlcHJlc2VudGF0aW9uLgorLy8vCitjbGFzcyBTcmNWYWx1ZVNETm9kZSA6IHB1YmxpYyBTRE5vZGUgeworICBmcmllbmQgY2xhc3MgU2VsZWN0aW9uREFHOworCisgIGNvbnN0IFZhbHVlICpWOworCisgIC8vLyBDcmVhdGUgYSBTcmNWYWx1ZSBmb3IgYSBnZW5lcmFsIHZhbHVlLgorICBleHBsaWNpdCBTcmNWYWx1ZVNETm9kZShjb25zdCBWYWx1ZSAqdikKKyAgICA6IFNETm9kZShJU0Q6OlNSQ1ZBTFVFLCAwLCBEZWJ1Z0xvYygpLCBnZXRTRFZUTGlzdChNVlQ6Ok90aGVyKSksIFYodikge30KKworcHVibGljOgorICAvLy8gUmV0dXJuIHRoZSBjb250YWluZWQgVmFsdWUuCisgIGNvbnN0IFZhbHVlICpnZXRWYWx1ZSgpIGNvbnN0IHsgcmV0dXJuIFY7IH0KKworICBzdGF0aWMgYm9vbCBjbGFzc29mKGNvbnN0IFNETm9kZSAqTikgeworICAgIHJldHVybiBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OlNSQ1ZBTFVFOworICB9Cit9OworCitjbGFzcyBNRE5vZGVTRE5vZGUgOiBwdWJsaWMgU0ROb2RlIHsKKyAgZnJpZW5kIGNsYXNzIFNlbGVjdGlvbkRBRzsKKworICBjb25zdCBNRE5vZGUgKk1EOworCisgIGV4cGxpY2l0IE1ETm9kZVNETm9kZShjb25zdCBNRE5vZGUgKm1kKQorICA6IFNETm9kZShJU0Q6Ok1ETk9ERV9TRE5PREUsIDAsIERlYnVnTG9jKCksIGdldFNEVlRMaXN0KE1WVDo6T3RoZXIpKSwgTUQobWQpCisgIHt9CisKK3B1YmxpYzoKKyAgY29uc3QgTUROb2RlICpnZXRNRCgpIGNvbnN0IHsgcmV0dXJuIE1EOyB9CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpNRE5PREVfU0ROT0RFOworICB9Cit9OworCitjbGFzcyBSZWdpc3RlclNETm9kZSA6IHB1YmxpYyBTRE5vZGUgeworICBmcmllbmQgY2xhc3MgU2VsZWN0aW9uREFHOworCisgIHVuc2lnbmVkIFJlZzsKKworICBSZWdpc3RlclNETm9kZSh1bnNpZ25lZCByZWcsIEVWVCBWVCkKKyAgICA6IFNETm9kZShJU0Q6OlJlZ2lzdGVyLCAwLCBEZWJ1Z0xvYygpLCBnZXRTRFZUTGlzdChWVCkpLCBSZWcocmVnKSB7fQorCitwdWJsaWM6CisgIHVuc2lnbmVkIGdldFJlZygpIGNvbnN0IHsgcmV0dXJuIFJlZzsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6UmVnaXN0ZXI7CisgIH0KK307CisKK2NsYXNzIFJlZ2lzdGVyTWFza1NETm9kZSA6IHB1YmxpYyBTRE5vZGUgeworICBmcmllbmQgY2xhc3MgU2VsZWN0aW9uREFHOworCisgIC8vIFRoZSBtZW1vcnkgZm9yIFJlZ01hc2sgaXMgbm90IG93bmVkIGJ5IHRoZSBub2RlLgorICBjb25zdCB1aW50MzJfdCAqUmVnTWFzazsKKworICBSZWdpc3Rlck1hc2tTRE5vZGUoY29uc3QgdWludDMyX3QgKm1hc2spCisgICAgOiBTRE5vZGUoSVNEOjpSZWdpc3Rlck1hc2ssIDAsIERlYnVnTG9jKCksIGdldFNEVlRMaXN0KE1WVDo6VW50eXBlZCkpLAorICAgICAgUmVnTWFzayhtYXNrKSB7fQorCitwdWJsaWM6CisgIGNvbnN0IHVpbnQzMl90ICpnZXRSZWdNYXNrKCkgY29uc3QgeyByZXR1cm4gUmVnTWFzazsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6UmVnaXN0ZXJNYXNrOworICB9Cit9OworCitjbGFzcyBCbG9ja0FkZHJlc3NTRE5vZGUgOiBwdWJsaWMgU0ROb2RlIHsKKyAgZnJpZW5kIGNsYXNzIFNlbGVjdGlvbkRBRzsKKworICBjb25zdCBCbG9ja0FkZHJlc3MgKkJBOworICBpbnQ2NF90IE9mZnNldDsKKyAgdW5zaWduZWQgY2hhciBUYXJnZXRGbGFnczsKKworICBCbG9ja0FkZHJlc3NTRE5vZGUodW5zaWduZWQgTm9kZVR5LCBFVlQgVlQsIGNvbnN0IEJsb2NrQWRkcmVzcyAqYmEsCisgICAgICAgICAgICAgICAgICAgICBpbnQ2NF90IG8sIHVuc2lnbmVkIGNoYXIgRmxhZ3MpCisgICAgOiBTRE5vZGUoTm9kZVR5LCAwLCBEZWJ1Z0xvYygpLCBnZXRTRFZUTGlzdChWVCkpLAorICAgICAgICAgICAgIEJBKGJhKSwgT2Zmc2V0KG8pLCBUYXJnZXRGbGFncyhGbGFncykge30KKworcHVibGljOgorICBjb25zdCBCbG9ja0FkZHJlc3MgKmdldEJsb2NrQWRkcmVzcygpIGNvbnN0IHsgcmV0dXJuIEJBOyB9CisgIGludDY0X3QgZ2V0T2Zmc2V0KCkgY29uc3QgeyByZXR1cm4gT2Zmc2V0OyB9CisgIHVuc2lnbmVkIGNoYXIgZ2V0VGFyZ2V0RmxhZ3MoKSBjb25zdCB7IHJldHVybiBUYXJnZXRGbGFnczsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6QmxvY2tBZGRyZXNzIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6VGFyZ2V0QmxvY2tBZGRyZXNzOworICB9Cit9OworCitjbGFzcyBMYWJlbFNETm9kZSA6IHB1YmxpYyBTRE5vZGUgeworICBmcmllbmQgY2xhc3MgU2VsZWN0aW9uREFHOworCisgIE1DU3ltYm9sICpMYWJlbDsKKworICBMYWJlbFNETm9kZSh1bnNpZ25lZCBPcmRlciwgY29uc3QgRGVidWdMb2MgJmRsLCBNQ1N5bWJvbCAqTCkKKyAgICAgIDogU0ROb2RlKElTRDo6RUhfTEFCRUwsIE9yZGVyLCBkbCwgZ2V0U0RWVExpc3QoTVZUOjpPdGhlcikpLCBMYWJlbChMKSB7fQorCitwdWJsaWM6CisgIE1DU3ltYm9sICpnZXRMYWJlbCgpIGNvbnN0IHsgcmV0dXJuIExhYmVsOyB9CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpFSF9MQUJFTCB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OkFOTk9UQVRJT05fTEFCRUw7CisgIH0KK307CisKK2NsYXNzIEV4dGVybmFsU3ltYm9sU0ROb2RlIDogcHVibGljIFNETm9kZSB7CisgIGZyaWVuZCBjbGFzcyBTZWxlY3Rpb25EQUc7CisKKyAgY29uc3QgY2hhciAqU3ltYm9sOworICB1bnNpZ25lZCBjaGFyIFRhcmdldEZsYWdzOworCisgIEV4dGVybmFsU3ltYm9sU0ROb2RlKGJvb2wgaXNUYXJnZXQsIGNvbnN0IGNoYXIgKlN5bSwgdW5zaWduZWQgY2hhciBURiwgRVZUIFZUKQorICAgIDogU0ROb2RlKGlzVGFyZ2V0ID8gSVNEOjpUYXJnZXRFeHRlcm5hbFN5bWJvbCA6IElTRDo6RXh0ZXJuYWxTeW1ib2wsCisgICAgICAgICAgICAgMCwgRGVidWdMb2MoKSwgZ2V0U0RWVExpc3QoVlQpKSwgU3ltYm9sKFN5bSksIFRhcmdldEZsYWdzKFRGKSB7fQorCitwdWJsaWM6CisgIGNvbnN0IGNoYXIgKmdldFN5bWJvbCgpIGNvbnN0IHsgcmV0dXJuIFN5bWJvbDsgfQorICB1bnNpZ25lZCBjaGFyIGdldFRhcmdldEZsYWdzKCkgY29uc3QgeyByZXR1cm4gVGFyZ2V0RmxhZ3M7IH0KKworICBzdGF0aWMgYm9vbCBjbGFzc29mKGNvbnN0IFNETm9kZSAqTikgeworICAgIHJldHVybiBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OkV4dGVybmFsU3ltYm9sIHx8CisgICAgICAgICAgIE4tPmdldE9wY29kZSgpID09IElTRDo6VGFyZ2V0RXh0ZXJuYWxTeW1ib2w7CisgIH0KK307CisKK2NsYXNzIE1DU3ltYm9sU0ROb2RlIDogcHVibGljIFNETm9kZSB7CisgIGZyaWVuZCBjbGFzcyBTZWxlY3Rpb25EQUc7CisKKyAgTUNTeW1ib2wgKlN5bWJvbDsKKworICBNQ1N5bWJvbFNETm9kZShNQ1N5bWJvbCAqU3ltYm9sLCBFVlQgVlQpCisgICAgICA6IFNETm9kZShJU0Q6Ok1DU3ltYm9sLCAwLCBEZWJ1Z0xvYygpLCBnZXRTRFZUTGlzdChWVCkpLCBTeW1ib2woU3ltYm9sKSB7fQorCitwdWJsaWM6CisgIE1DU3ltYm9sICpnZXRNQ1N5bWJvbCgpIGNvbnN0IHsgcmV0dXJuIFN5bWJvbDsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6TUNTeW1ib2w7CisgIH0KK307CisKK2NsYXNzIENvbmRDb2RlU0ROb2RlIDogcHVibGljIFNETm9kZSB7CisgIGZyaWVuZCBjbGFzcyBTZWxlY3Rpb25EQUc7CisKKyAgSVNEOjpDb25kQ29kZSBDb25kaXRpb247CisKKyAgZXhwbGljaXQgQ29uZENvZGVTRE5vZGUoSVNEOjpDb25kQ29kZSBDb25kKQorICAgIDogU0ROb2RlKElTRDo6Q09ORENPREUsIDAsIERlYnVnTG9jKCksIGdldFNEVlRMaXN0KE1WVDo6T3RoZXIpKSwKKyAgICAgIENvbmRpdGlvbihDb25kKSB7fQorCitwdWJsaWM6CisgIElTRDo6Q29uZENvZGUgZ2V0KCkgY29uc3QgeyByZXR1cm4gQ29uZGl0aW9uOyB9CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpDT05EQ09ERTsKKyAgfQorfTsKKworLy8vIFRoaXMgY2xhc3MgaXMgdXNlZCB0byByZXByZXNlbnQgRVZUJ3MsIHdoaWNoIGFyZSB1c2VkCisvLy8gdG8gcGFyYW1ldGVyaXplIHNvbWUgb3BlcmF0aW9ucy4KK2NsYXNzIFZUU0ROb2RlIDogcHVibGljIFNETm9kZSB7CisgIGZyaWVuZCBjbGFzcyBTZWxlY3Rpb25EQUc7CisKKyAgRVZUIFZhbHVlVHlwZTsKKworICBleHBsaWNpdCBWVFNETm9kZShFVlQgVlQpCisgICAgOiBTRE5vZGUoSVNEOjpWQUxVRVRZUEUsIDAsIERlYnVnTG9jKCksIGdldFNEVlRMaXN0KE1WVDo6T3RoZXIpKSwKKyAgICAgIFZhbHVlVHlwZShWVCkge30KKworcHVibGljOgorICBFVlQgZ2V0VlQoKSBjb25zdCB7IHJldHVybiBWYWx1ZVR5cGU7IH0KKworICBzdGF0aWMgYm9vbCBjbGFzc29mKGNvbnN0IFNETm9kZSAqTikgeworICAgIHJldHVybiBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OlZBTFVFVFlQRTsKKyAgfQorfTsKKworLy8vIEJhc2UgY2xhc3MgZm9yIExvYWRTRE5vZGUgYW5kIFN0b3JlU0ROb2RlCitjbGFzcyBMU0Jhc2VTRE5vZGUgOiBwdWJsaWMgTWVtU0ROb2RlIHsKK3B1YmxpYzoKKyAgTFNCYXNlU0ROb2RlKElTRDo6Tm9kZVR5cGUgTm9kZVR5LCB1bnNpZ25lZCBPcmRlciwgY29uc3QgRGVidWdMb2MgJmRsLAorICAgICAgICAgICAgICAgU0RWVExpc3QgVlRzLCBJU0Q6Ok1lbUluZGV4ZWRNb2RlIEFNLCBFVlQgTWVtVlQsCisgICAgICAgICAgICAgICBNYWNoaW5lTWVtT3BlcmFuZCAqTU1PKQorICAgICAgOiBNZW1TRE5vZGUoTm9kZVR5LCBPcmRlciwgZGwsIFZUcywgTWVtVlQsIE1NTykgeworICAgIExTQmFzZVNETm9kZUJpdHMuQWRkcmVzc2luZ01vZGUgPSBBTTsKKyAgICBhc3NlcnQoZ2V0QWRkcmVzc2luZ01vZGUoKSA9PSBBTSAmJiAiVmFsdWUgdHJ1bmNhdGVkIik7CisgIH0KKworICBjb25zdCBTRFZhbHVlICZnZXRPZmZzZXQoKSBjb25zdCB7CisgICAgcmV0dXJuIGdldE9wZXJhbmQoZ2V0T3Bjb2RlKCkgPT0gSVNEOjpMT0FEID8gMiA6IDMpOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgYWRkcmVzc2luZyBtb2RlIGZvciB0aGlzIGxvYWQgb3Igc3RvcmU6CisgIC8vLyB1bmluZGV4ZWQsIHByZS1pbmMsIHByZS1kZWMsIHBvc3QtaW5jLCBvciBwb3N0LWRlYy4KKyAgSVNEOjpNZW1JbmRleGVkTW9kZSBnZXRBZGRyZXNzaW5nTW9kZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8SVNEOjpNZW1JbmRleGVkTW9kZT4oTFNCYXNlU0ROb2RlQml0cy5BZGRyZXNzaW5nTW9kZSk7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIHByZS9wb3N0IGluYy9kZWMgbG9hZC9zdG9yZS4KKyAgYm9vbCBpc0luZGV4ZWQoKSBjb25zdCB7IHJldHVybiBnZXRBZGRyZXNzaW5nTW9kZSgpICE9IElTRDo6VU5JTkRFWEVEOyB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaXMgTk9UIGEgcHJlL3Bvc3QgaW5jL2RlYyBsb2FkL3N0b3JlLgorICBib29sIGlzVW5pbmRleGVkKCkgY29uc3QgeyByZXR1cm4gZ2V0QWRkcmVzc2luZ01vZGUoKSA9PSBJU0Q6OlVOSU5ERVhFRDsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6TE9BRCB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6OlNUT1JFOworICB9Cit9OworCisvLy8gVGhpcyBjbGFzcyBpcyB1c2VkIHRvIHJlcHJlc2VudCBJU0Q6OkxPQUQgbm9kZXMuCitjbGFzcyBMb2FkU0ROb2RlIDogcHVibGljIExTQmFzZVNETm9kZSB7CisgIGZyaWVuZCBjbGFzcyBTZWxlY3Rpb25EQUc7CisKKyAgTG9hZFNETm9kZSh1bnNpZ25lZCBPcmRlciwgY29uc3QgRGVidWdMb2MgJmRsLCBTRFZUTGlzdCBWVHMsCisgICAgICAgICAgICAgSVNEOjpNZW1JbmRleGVkTW9kZSBBTSwgSVNEOjpMb2FkRXh0VHlwZSBFVHksIEVWVCBNZW1WVCwKKyAgICAgICAgICAgICBNYWNoaW5lTWVtT3BlcmFuZCAqTU1PKQorICAgICAgOiBMU0Jhc2VTRE5vZGUoSVNEOjpMT0FELCBPcmRlciwgZGwsIFZUcywgQU0sIE1lbVZULCBNTU8pIHsKKyAgICBMb2FkU0ROb2RlQml0cy5FeHRUeSA9IEVUeTsKKyAgICBhc3NlcnQocmVhZE1lbSgpICYmICJMb2FkIE1hY2hpbmVNZW1PcGVyYW5kIGlzIG5vdCBhIGxvYWQhIik7CisgICAgYXNzZXJ0KCF3cml0ZU1lbSgpICYmICJMb2FkIE1hY2hpbmVNZW1PcGVyYW5kIGlzIGEgc3RvcmUhIik7CisgIH0KKworcHVibGljOgorICAvLy8gUmV0dXJuIHdoZXRoZXIgdGhpcyBpcyBhIHBsYWluIG5vZGUsCisgIC8vLyBvciBvbmUgb2YgdGhlIHZhcmlldGllcyBvZiB2YWx1ZS1leHRlbmRpbmcgbG9hZHMuCisgIElTRDo6TG9hZEV4dFR5cGUgZ2V0RXh0ZW5zaW9uVHlwZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gc3RhdGljX2Nhc3Q8SVNEOjpMb2FkRXh0VHlwZT4oTG9hZFNETm9kZUJpdHMuRXh0VHkpOworICB9CisKKyAgY29uc3QgU0RWYWx1ZSAmZ2V0QmFzZVB0cigpIGNvbnN0IHsgcmV0dXJuIGdldE9wZXJhbmQoMSk7IH0KKyAgY29uc3QgU0RWYWx1ZSAmZ2V0T2Zmc2V0KCkgY29uc3QgeyByZXR1cm4gZ2V0T3BlcmFuZCgyKTsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6TE9BRDsKKyAgfQorfTsKKworLy8vIFRoaXMgY2xhc3MgaXMgdXNlZCB0byByZXByZXNlbnQgSVNEOjpTVE9SRSBub2Rlcy4KK2NsYXNzIFN0b3JlU0ROb2RlIDogcHVibGljIExTQmFzZVNETm9kZSB7CisgIGZyaWVuZCBjbGFzcyBTZWxlY3Rpb25EQUc7CisKKyAgU3RvcmVTRE5vZGUodW5zaWduZWQgT3JkZXIsIGNvbnN0IERlYnVnTG9jICZkbCwgU0RWVExpc3QgVlRzLAorICAgICAgICAgICAgICBJU0Q6Ok1lbUluZGV4ZWRNb2RlIEFNLCBib29sIGlzVHJ1bmMsIEVWVCBNZW1WVCwKKyAgICAgICAgICAgICAgTWFjaGluZU1lbU9wZXJhbmQgKk1NTykKKyAgICAgIDogTFNCYXNlU0ROb2RlKElTRDo6U1RPUkUsIE9yZGVyLCBkbCwgVlRzLCBBTSwgTWVtVlQsIE1NTykgeworICAgIFN0b3JlU0ROb2RlQml0cy5Jc1RydW5jYXRpbmcgPSBpc1RydW5jOworICAgIGFzc2VydCghcmVhZE1lbSgpICYmICJTdG9yZSBNYWNoaW5lTWVtT3BlcmFuZCBpcyBhIGxvYWQhIik7CisgICAgYXNzZXJ0KHdyaXRlTWVtKCkgJiYgIlN0b3JlIE1hY2hpbmVNZW1PcGVyYW5kIGlzIG5vdCBhIHN0b3JlISIpOworICB9CisKK3B1YmxpYzoKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBvcCBkb2VzIGEgdHJ1bmNhdGlvbiBiZWZvcmUgc3RvcmUuCisgIC8vLyBGb3IgaW50ZWdlcnMgdGhpcyBpcyB0aGUgc2FtZSBhcyBkb2luZyBhIFRSVU5DQVRFIGFuZCBzdG9yaW5nIHRoZSByZXN1bHQuCisgIC8vLyBGb3IgZmxvYXRzLCBpdCBpcyB0aGUgc2FtZSBhcyBkb2luZyBhbiBGUF9ST1VORCBhbmQgc3RvcmluZyB0aGUgcmVzdWx0LgorICBib29sIGlzVHJ1bmNhdGluZ1N0b3JlKCkgY29uc3QgeyByZXR1cm4gU3RvcmVTRE5vZGVCaXRzLklzVHJ1bmNhdGluZzsgfQorICB2b2lkIHNldFRydW5jYXRpbmdTdG9yZShib29sIFRydW5jYXRpbmcpIHsKKyAgICBTdG9yZVNETm9kZUJpdHMuSXNUcnVuY2F0aW5nID0gVHJ1bmNhdGluZzsKKyAgfQorCisgIGNvbnN0IFNEVmFsdWUgJmdldFZhbHVlKCkgY29uc3QgeyByZXR1cm4gZ2V0T3BlcmFuZCgxKTsgfQorICBjb25zdCBTRFZhbHVlICZnZXRCYXNlUHRyKCkgY29uc3QgeyByZXR1cm4gZ2V0T3BlcmFuZCgyKTsgfQorICBjb25zdCBTRFZhbHVlICZnZXRPZmZzZXQoKSBjb25zdCB7IHJldHVybiBnZXRPcGVyYW5kKDMpOyB9CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpTVE9SRTsKKyAgfQorfTsKKworLy8vIFRoaXMgYmFzZSBjbGFzcyBpcyB1c2VkIHRvIHJlcHJlc2VudCBNTE9BRCBhbmQgTVNUT1JFIG5vZGVzCitjbGFzcyBNYXNrZWRMb2FkU3RvcmVTRE5vZGUgOiBwdWJsaWMgTWVtU0ROb2RlIHsKK3B1YmxpYzoKKyAgZnJpZW5kIGNsYXNzIFNlbGVjdGlvbkRBRzsKKworICBNYXNrZWRMb2FkU3RvcmVTRE5vZGUoSVNEOjpOb2RlVHlwZSBOb2RlVHksIHVuc2lnbmVkIE9yZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdMb2MgJmRsLCBTRFZUTGlzdCBWVHMsIEVWVCBNZW1WVCwKKyAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVNZW1PcGVyYW5kICpNTU8pCisgICAgICA6IE1lbVNETm9kZShOb2RlVHksIE9yZGVyLCBkbCwgVlRzLCBNZW1WVCwgTU1PKSB7fQorCisgIC8vIEluIHRoZSBib3RoIG5vZGVzIGFkZHJlc3MgaXMgT3AxLCBtYXNrIGlzIE9wMjoKKyAgLy8gTWFza2VkTG9hZFNETm9kZSAoQ2hhaW4sIHB0ciwgbWFzaywgc3JjMCksIHNyYzAgaXMgYSBwYXNzdGhydSB2YWx1ZQorICAvLyBNYXNrZWRTdG9yZVNETm9kZSAoQ2hhaW4sIHB0ciwgbWFzaywgZGF0YSkKKyAgLy8gTWFzayBpcyBhIHZlY3RvciBvZiBpMSBlbGVtZW50cworICBjb25zdCBTRFZhbHVlICZnZXRCYXNlUHRyKCkgY29uc3QgeyByZXR1cm4gZ2V0T3BlcmFuZCgxKTsgfQorICBjb25zdCBTRFZhbHVlICZnZXRNYXNrKCkgY29uc3QgICAgeyByZXR1cm4gZ2V0T3BlcmFuZCgyKTsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6TUxPQUQgfHwKKyAgICAgICAgICAgTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpNU1RPUkU7CisgIH0KK307CisKKy8vLyBUaGlzIGNsYXNzIGlzIHVzZWQgdG8gcmVwcmVzZW50IGFuIE1MT0FEIG5vZGUKK2NsYXNzIE1hc2tlZExvYWRTRE5vZGUgOiBwdWJsaWMgTWFza2VkTG9hZFN0b3JlU0ROb2RlIHsKK3B1YmxpYzoKKyAgZnJpZW5kIGNsYXNzIFNlbGVjdGlvbkRBRzsKKworICBNYXNrZWRMb2FkU0ROb2RlKHVuc2lnbmVkIE9yZGVyLCBjb25zdCBEZWJ1Z0xvYyAmZGwsIFNEVlRMaXN0IFZUcywKKyAgICAgICAgICAgICAgICAgICBJU0Q6OkxvYWRFeHRUeXBlIEVUeSwgYm9vbCBJc0V4cGFuZGluZywgRVZUIE1lbVZULAorICAgICAgICAgICAgICAgICAgIE1hY2hpbmVNZW1PcGVyYW5kICpNTU8pCisgICAgICA6IE1hc2tlZExvYWRTdG9yZVNETm9kZShJU0Q6Ok1MT0FELCBPcmRlciwgZGwsIFZUcywgTWVtVlQsIE1NTykgeworICAgIExvYWRTRE5vZGVCaXRzLkV4dFR5ID0gRVR5OworICAgIExvYWRTRE5vZGVCaXRzLklzRXhwYW5kaW5nID0gSXNFeHBhbmRpbmc7CisgIH0KKworICBJU0Q6OkxvYWRFeHRUeXBlIGdldEV4dGVuc2lvblR5cGUoKSBjb25zdCB7CisgICAgcmV0dXJuIHN0YXRpY19jYXN0PElTRDo6TG9hZEV4dFR5cGU+KExvYWRTRE5vZGVCaXRzLkV4dFR5KTsKKyAgfQorCisgIGNvbnN0IFNEVmFsdWUgJmdldFNyYzAoKSBjb25zdCB7IHJldHVybiBnZXRPcGVyYW5kKDMpOyB9CisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6TUxPQUQ7CisgIH0KKworICBib29sIGlzRXhwYW5kaW5nTG9hZCgpIGNvbnN0IHsgcmV0dXJuIExvYWRTRE5vZGVCaXRzLklzRXhwYW5kaW5nOyB9Cit9OworCisvLy8gVGhpcyBjbGFzcyBpcyB1c2VkIHRvIHJlcHJlc2VudCBhbiBNU1RPUkUgbm9kZQorY2xhc3MgTWFza2VkU3RvcmVTRE5vZGUgOiBwdWJsaWMgTWFza2VkTG9hZFN0b3JlU0ROb2RlIHsKK3B1YmxpYzoKKyAgZnJpZW5kIGNsYXNzIFNlbGVjdGlvbkRBRzsKKworICBNYXNrZWRTdG9yZVNETm9kZSh1bnNpZ25lZCBPcmRlciwgY29uc3QgRGVidWdMb2MgJmRsLCBTRFZUTGlzdCBWVHMsCisgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNUcnVuYywgYm9vbCBpc0NvbXByZXNzaW5nLCBFVlQgTWVtVlQsCisgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVNZW1PcGVyYW5kICpNTU8pCisgICAgICA6IE1hc2tlZExvYWRTdG9yZVNETm9kZShJU0Q6Ok1TVE9SRSwgT3JkZXIsIGRsLCBWVHMsIE1lbVZULCBNTU8pIHsKKyAgICBTdG9yZVNETm9kZUJpdHMuSXNUcnVuY2F0aW5nID0gaXNUcnVuYzsKKyAgICBTdG9yZVNETm9kZUJpdHMuSXNDb21wcmVzc2luZyA9IGlzQ29tcHJlc3Npbmc7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIG9wIGRvZXMgYSB0cnVuY2F0aW9uIGJlZm9yZSBzdG9yZS4KKyAgLy8vIEZvciBpbnRlZ2VycyB0aGlzIGlzIHRoZSBzYW1lIGFzIGRvaW5nIGEgVFJVTkNBVEUgYW5kIHN0b3JpbmcgdGhlIHJlc3VsdC4KKyAgLy8vIEZvciBmbG9hdHMsIGl0IGlzIHRoZSBzYW1lIGFzIGRvaW5nIGFuIEZQX1JPVU5EIGFuZCBzdG9yaW5nIHRoZSByZXN1bHQuCisgIGJvb2wgaXNUcnVuY2F0aW5nU3RvcmUoKSBjb25zdCB7IHJldHVybiBTdG9yZVNETm9kZUJpdHMuSXNUcnVuY2F0aW5nOyB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgb3AgZG9lcyBhIGNvbXByZXNzaW9uIHRvIHRoZSB2ZWN0b3IgYmVmb3JlIHN0b3JpbmcuCisgIC8vLyBUaGUgbm9kZSBjb250aWd1b3VzbHkgc3RvcmVzIHRoZSBhY3RpdmUgZWxlbWVudHMgKGludGVnZXJzIG9yIGZsb2F0cykKKyAgLy8vIGluIHNyYyAodGhvc2Ugd2l0aCB0aGVpciByZXNwZWN0aXZlIGJpdCBzZXQgaW4gd3JpdGVtYXNrIGspIHRvIHVuYWxpZ25lZAorICAvLy8gbWVtb3J5IGF0IGJhc2VfYWRkci4KKyAgYm9vbCBpc0NvbXByZXNzaW5nU3RvcmUoKSBjb25zdCB7IHJldHVybiBTdG9yZVNETm9kZUJpdHMuSXNDb21wcmVzc2luZzsgfQorCisgIGNvbnN0IFNEVmFsdWUgJmdldFZhbHVlKCkgY29uc3QgeyByZXR1cm4gZ2V0T3BlcmFuZCgzKTsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6TVNUT1JFOworICB9Cit9OworCisvLy8gVGhpcyBpcyBhIGJhc2UgY2xhc3MgdXNlZCB0byByZXByZXNlbnQKKy8vLyBNR0FUSEVSIGFuZCBNU0NBVFRFUiBub2RlcworLy8vCitjbGFzcyBNYXNrZWRHYXRoZXJTY2F0dGVyU0ROb2RlIDogcHVibGljIE1lbVNETm9kZSB7CitwdWJsaWM6CisgIGZyaWVuZCBjbGFzcyBTZWxlY3Rpb25EQUc7CisKKyAgTWFza2VkR2F0aGVyU2NhdHRlclNETm9kZShJU0Q6Ok5vZGVUeXBlIE5vZGVUeSwgdW5zaWduZWQgT3JkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdMb2MgJmRsLCBTRFZUTGlzdCBWVHMsIEVWVCBNZW1WVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lTWVtT3BlcmFuZCAqTU1PKQorICAgICAgOiBNZW1TRE5vZGUoTm9kZVR5LCBPcmRlciwgZGwsIFZUcywgTWVtVlQsIE1NTykge30KKworICAvLyBJbiB0aGUgYm90aCBub2RlcyBhZGRyZXNzIGlzIE9wMSwgbWFzayBpcyBPcDI6CisgIC8vIE1hc2tlZEdhdGhlclNETm9kZSAgKENoYWluLCBwYXNzdGhydSwgbWFzaywgYmFzZSwgaW5kZXgsIHNjYWxlKQorICAvLyBNYXNrZWRTY2F0dGVyU0ROb2RlIChDaGFpbiwgdmFsdWUsIG1hc2ssIGJhc2UsIGluZGV4LCBzY2FsZSkKKyAgLy8gTWFzayBpcyBhIHZlY3RvciBvZiBpMSBlbGVtZW50cworICBjb25zdCBTRFZhbHVlICZnZXRCYXNlUHRyKCkgY29uc3QgeyByZXR1cm4gZ2V0T3BlcmFuZCgzKTsgfQorICBjb25zdCBTRFZhbHVlICZnZXRJbmRleCgpICAgY29uc3QgeyByZXR1cm4gZ2V0T3BlcmFuZCg0KTsgfQorICBjb25zdCBTRFZhbHVlICZnZXRNYXNrKCkgICAgY29uc3QgeyByZXR1cm4gZ2V0T3BlcmFuZCgyKTsgfQorICBjb25zdCBTRFZhbHVlICZnZXRWYWx1ZSgpICAgY29uc3QgeyByZXR1cm4gZ2V0T3BlcmFuZCgxKTsgfQorICBjb25zdCBTRFZhbHVlICZnZXRTY2FsZSgpICAgY29uc3QgeyByZXR1cm4gZ2V0T3BlcmFuZCg1KTsgfQorCisgIHN0YXRpYyBib29sIGNsYXNzb2YoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIE4tPmdldE9wY29kZSgpID09IElTRDo6TUdBVEhFUiB8fAorICAgICAgICAgICBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6Ok1TQ0FUVEVSOworICB9Cit9OworCisvLy8gVGhpcyBjbGFzcyBpcyB1c2VkIHRvIHJlcHJlc2VudCBhbiBNR0FUSEVSIG5vZGUKKy8vLworY2xhc3MgTWFza2VkR2F0aGVyU0ROb2RlIDogcHVibGljIE1hc2tlZEdhdGhlclNjYXR0ZXJTRE5vZGUgeworcHVibGljOgorICBmcmllbmQgY2xhc3MgU2VsZWN0aW9uREFHOworCisgIE1hc2tlZEdhdGhlclNETm9kZSh1bnNpZ25lZCBPcmRlciwgY29uc3QgRGVidWdMb2MgJmRsLCBTRFZUTGlzdCBWVHMsCisgICAgICAgICAgICAgICAgICAgICBFVlQgTWVtVlQsIE1hY2hpbmVNZW1PcGVyYW5kICpNTU8pCisgICAgICA6IE1hc2tlZEdhdGhlclNjYXR0ZXJTRE5vZGUoSVNEOjpNR0FUSEVSLCBPcmRlciwgZGwsIFZUcywgTWVtVlQsIE1NTykge30KKworICBzdGF0aWMgYm9vbCBjbGFzc29mKGNvbnN0IFNETm9kZSAqTikgeworICAgIHJldHVybiBOLT5nZXRPcGNvZGUoKSA9PSBJU0Q6Ok1HQVRIRVI7CisgIH0KK307CisKKy8vLyBUaGlzIGNsYXNzIGlzIHVzZWQgdG8gcmVwcmVzZW50IGFuIE1TQ0FUVEVSIG5vZGUKKy8vLworY2xhc3MgTWFza2VkU2NhdHRlclNETm9kZSA6IHB1YmxpYyBNYXNrZWRHYXRoZXJTY2F0dGVyU0ROb2RlIHsKK3B1YmxpYzoKKyAgZnJpZW5kIGNsYXNzIFNlbGVjdGlvbkRBRzsKKworICBNYXNrZWRTY2F0dGVyU0ROb2RlKHVuc2lnbmVkIE9yZGVyLCBjb25zdCBEZWJ1Z0xvYyAmZGwsIFNEVlRMaXN0IFZUcywKKyAgICAgICAgICAgICAgICAgICAgICBFVlQgTWVtVlQsIE1hY2hpbmVNZW1PcGVyYW5kICpNTU8pCisgICAgICA6IE1hc2tlZEdhdGhlclNjYXR0ZXJTRE5vZGUoSVNEOjpNU0NBVFRFUiwgT3JkZXIsIGRsLCBWVHMsIE1lbVZULCBNTU8pIHt9CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gTi0+Z2V0T3Bjb2RlKCkgPT0gSVNEOjpNU0NBVFRFUjsKKyAgfQorfTsKKworLy8vIEFuIFNETm9kZSB0aGF0IHJlcHJlc2VudHMgZXZlcnl0aGluZyB0aGF0IHdpbGwgYmUgbmVlZGVkCisvLy8gdG8gY29uc3RydWN0IGEgTWFjaGluZUluc3RyLiBUaGVzZSBub2RlcyBhcmUgY3JlYXRlZCBkdXJpbmcgdGhlCisvLy8gaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uIHByb3BlciBwaGFzZS4KK2NsYXNzIE1hY2hpbmVTRE5vZGUgOiBwdWJsaWMgU0ROb2RlIHsKK3B1YmxpYzoKKyAgdXNpbmcgbW1vX2l0ZXJhdG9yID0gTWFjaGluZU1lbU9wZXJhbmQgKio7CisKK3ByaXZhdGU6CisgIGZyaWVuZCBjbGFzcyBTZWxlY3Rpb25EQUc7CisKKyAgTWFjaGluZVNETm9kZSh1bnNpZ25lZCBPcGMsIHVuc2lnbmVkIE9yZGVyLCBjb25zdCBEZWJ1Z0xvYyAmREwsIFNEVlRMaXN0IFZUcykKKyAgICAgIDogU0ROb2RlKE9wYywgT3JkZXIsIERMLCBWVHMpIHt9CisKKyAgLy8vIE1lbW9yeSByZWZlcmVuY2UgZGVzY3JpcHRpb25zIGZvciB0aGlzIGluc3RydWN0aW9uLgorICBtbW9faXRlcmF0b3IgTWVtUmVmcyA9IG51bGxwdHI7CisgIG1tb19pdGVyYXRvciBNZW1SZWZzRW5kID0gbnVsbHB0cjsKKworcHVibGljOgorICBtbW9faXRlcmF0b3IgbWVtb3BlcmFuZHNfYmVnaW4oKSBjb25zdCB7IHJldHVybiBNZW1SZWZzOyB9CisgIG1tb19pdGVyYXRvciBtZW1vcGVyYW5kc19lbmQoKSBjb25zdCB7IHJldHVybiBNZW1SZWZzRW5kOyB9CisgIGJvb2wgbWVtb3BlcmFuZHNfZW1wdHkoKSBjb25zdCB7IHJldHVybiBNZW1SZWZzRW5kID09IE1lbVJlZnM7IH0KKworICAvLy8gQXNzaWduIHRoaXMgTWFjaGluZVNETm9kZXMncyBtZW1vcnkgcmVmZXJlbmNlIGRlc2NyaXB0b3IKKyAgLy8vIGxpc3QuIFRoaXMgZG9lcyBub3QgdHJhbnNmZXIgb3duZXJzaGlwLgorICB2b2lkIHNldE1lbVJlZnMobW1vX2l0ZXJhdG9yIE5ld01lbVJlZnMsIG1tb19pdGVyYXRvciBOZXdNZW1SZWZzRW5kKSB7CisgICAgZm9yIChtbW9faXRlcmF0b3IgTU1JID0gTmV3TWVtUmVmcywgTU1FID0gTmV3TWVtUmVmc0VuZDsgTU1JICE9IE1NRTsgKytNTUkpCisgICAgICBhc3NlcnQoKk1NSSAmJiAiTnVsbCBtZW0gcmVmIGRldGVjdGVkISIpOworICAgIE1lbVJlZnMgPSBOZXdNZW1SZWZzOworICAgIE1lbVJlZnNFbmQgPSBOZXdNZW1SZWZzRW5kOworICB9CisKKyAgc3RhdGljIGJvb2wgY2xhc3NvZihjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gTi0+aXNNYWNoaW5lT3Bjb2RlKCk7CisgIH0KK307CisKK2NsYXNzIFNETm9kZUl0ZXJhdG9yIDogcHVibGljIHN0ZDo6aXRlcmF0b3I8c3RkOjpmb3J3YXJkX2l0ZXJhdG9yX3RhZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0ROb2RlLCBwdHJkaWZmX3Q+IHsKKyAgY29uc3QgU0ROb2RlICpOb2RlOworICB1bnNpZ25lZCBPcGVyYW5kOworCisgIFNETm9kZUl0ZXJhdG9yKGNvbnN0IFNETm9kZSAqTiwgdW5zaWduZWQgT3ApIDogTm9kZShOKSwgT3BlcmFuZChPcCkge30KKworcHVibGljOgorICBib29sIG9wZXJhdG9yPT0oY29uc3QgU0ROb2RlSXRlcmF0b3ImIHgpIGNvbnN0IHsKKyAgICByZXR1cm4gT3BlcmFuZCA9PSB4Lk9wZXJhbmQ7CisgIH0KKyAgYm9vbCBvcGVyYXRvciE9KGNvbnN0IFNETm9kZUl0ZXJhdG9yJiB4KSBjb25zdCB7IHJldHVybiAhb3BlcmF0b3I9PSh4KTsgfQorCisgIHBvaW50ZXIgb3BlcmF0b3IqKCkgY29uc3QgeworICAgIHJldHVybiBOb2RlLT5nZXRPcGVyYW5kKE9wZXJhbmQpLmdldE5vZGUoKTsKKyAgfQorICBwb2ludGVyIG9wZXJhdG9yLT4oKSBjb25zdCB7IHJldHVybiBvcGVyYXRvciooKTsgfQorCisgIFNETm9kZUl0ZXJhdG9yJiBvcGVyYXRvcisrKCkgeyAgICAgICAgICAgICAgICAvLyBQcmVpbmNyZW1lbnQKKyAgICArK09wZXJhbmQ7CisgICAgcmV0dXJuICp0aGlzOworICB9CisgIFNETm9kZUl0ZXJhdG9yIG9wZXJhdG9yKysoaW50KSB7IC8vIFBvc3RpbmNyZW1lbnQKKyAgICBTRE5vZGVJdGVyYXRvciB0bXAgPSAqdGhpczsgKysqdGhpczsgcmV0dXJuIHRtcDsKKyAgfQorICBzaXplX3Qgb3BlcmF0b3ItKFNETm9kZUl0ZXJhdG9yIE90aGVyKSBjb25zdCB7CisgICAgYXNzZXJ0KE5vZGUgPT0gT3RoZXIuTm9kZSAmJgorICAgICAgICAgICAiQ2Fubm90IGNvbXBhcmUgaXRlcmF0b3JzIG9mIHR3byBkaWZmZXJlbnQgbm9kZXMhIik7CisgICAgcmV0dXJuIE9wZXJhbmQgLSBPdGhlci5PcGVyYW5kOworICB9CisKKyAgc3RhdGljIFNETm9kZUl0ZXJhdG9yIGJlZ2luKGNvbnN0IFNETm9kZSAqTikgeyByZXR1cm4gU0ROb2RlSXRlcmF0b3IoTiwgMCk7IH0KKyAgc3RhdGljIFNETm9kZUl0ZXJhdG9yIGVuZCAgKGNvbnN0IFNETm9kZSAqTikgeworICAgIHJldHVybiBTRE5vZGVJdGVyYXRvcihOLCBOLT5nZXROdW1PcGVyYW5kcygpKTsKKyAgfQorCisgIHVuc2lnbmVkIGdldE9wZXJhbmQoKSBjb25zdCB7IHJldHVybiBPcGVyYW5kOyB9CisgIGNvbnN0IFNETm9kZSAqZ2V0Tm9kZSgpIGNvbnN0IHsgcmV0dXJuIE5vZGU7IH0KK307CisKK3RlbXBsYXRlIDw+IHN0cnVjdCBHcmFwaFRyYWl0czxTRE5vZGUqPiB7CisgIHVzaW5nIE5vZGVSZWYgPSBTRE5vZGUgKjsKKyAgdXNpbmcgQ2hpbGRJdGVyYXRvclR5cGUgPSBTRE5vZGVJdGVyYXRvcjsKKworICBzdGF0aWMgTm9kZVJlZiBnZXRFbnRyeU5vZGUoU0ROb2RlICpOKSB7IHJldHVybiBOOyB9CisKKyAgc3RhdGljIENoaWxkSXRlcmF0b3JUeXBlIGNoaWxkX2JlZ2luKE5vZGVSZWYgTikgeworICAgIHJldHVybiBTRE5vZGVJdGVyYXRvcjo6YmVnaW4oTik7CisgIH0KKworICBzdGF0aWMgQ2hpbGRJdGVyYXRvclR5cGUgY2hpbGRfZW5kKE5vZGVSZWYgTikgeworICAgIHJldHVybiBTRE5vZGVJdGVyYXRvcjo6ZW5kKE4pOworICB9Cit9OworCisvLy8gQSByZXByZXNlbnRhdGlvbiBvZiB0aGUgbGFyZ2VzdCBTRE5vZGUsIGZvciB1c2UgaW4gc2l6ZW9mKCkuCisvLy8KKy8vLyBUaGlzIG5lZWRzIHRvIGJlIGEgdW5pb24gYmVjYXVzZSB0aGUgbGFyZ2VzdCBub2RlIGRpZmZlcnMgb24gMzIgYml0IHN5c3RlbXMKKy8vLyB3aXRoIDQgYW5kIDggYnl0ZSBwb2ludGVyIGFsaWdubWVudCwgcmVzcGVjdGl2ZWx5LgordXNpbmcgTGFyZ2VzdFNETm9kZSA9IEFsaWduZWRDaGFyQXJyYXlVbmlvbjxBdG9taWNTRE5vZGUsIFRhcmdldEluZGV4U0ROb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCbG9ja0FkZHJlc3NTRE5vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdsb2JhbEFkZHJlc3NTRE5vZGU+OworCisvLy8gVGhlIFNETm9kZSBjbGFzcyB3aXRoIHRoZSBncmVhdGVzdCBhbGlnbm1lbnQgcmVxdWlyZW1lbnQuCit1c2luZyBNb3N0QWxpZ25lZFNETm9kZSA9IEdsb2JhbEFkZHJlc3NTRE5vZGU7CisKK25hbWVzcGFjZSBJU0QgeworCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBub2RlIGlzIGEgbm9uLWV4dGVuZGluZyBhbmQgdW5pbmRleGVkIGxvYWQuCisgIGlubGluZSBib29sIGlzTm9ybWFsTG9hZChjb25zdCBTRE5vZGUgKk4pIHsKKyAgICBjb25zdCBMb2FkU0ROb2RlICpMZCA9IGR5bl9jYXN0PExvYWRTRE5vZGU+KE4pOworICAgIHJldHVybiBMZCAmJiBMZC0+Z2V0RXh0ZW5zaW9uVHlwZSgpID09IElTRDo6Tk9OX0VYVExPQUQgJiYKKyAgICAgIExkLT5nZXRBZGRyZXNzaW5nTW9kZSgpID09IElTRDo6VU5JTkRFWEVEOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIG5vZGUgaXMgYSBub24tZXh0ZW5kaW5nIGxvYWQuCisgIGlubGluZSBib29sIGlzTk9OX0VYVExvYWQoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIGlzYTxMb2FkU0ROb2RlPihOKSAmJgorICAgICAgY2FzdDxMb2FkU0ROb2RlPihOKS0+Z2V0RXh0ZW5zaW9uVHlwZSgpID09IElTRDo6Tk9OX0VYVExPQUQ7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgbm9kZSBpcyBhIEVYVExPQUQuCisgIGlubGluZSBib29sIGlzRVhUTG9hZChjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gaXNhPExvYWRTRE5vZGU+KE4pICYmCisgICAgICBjYXN0PExvYWRTRE5vZGU+KE4pLT5nZXRFeHRlbnNpb25UeXBlKCkgPT0gSVNEOjpFWFRMT0FEOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIG5vZGUgaXMgYSBTRVhUTE9BRC4KKyAgaW5saW5lIGJvb2wgaXNTRVhUTG9hZChjb25zdCBTRE5vZGUgKk4pIHsKKyAgICByZXR1cm4gaXNhPExvYWRTRE5vZGU+KE4pICYmCisgICAgICBjYXN0PExvYWRTRE5vZGU+KE4pLT5nZXRFeHRlbnNpb25UeXBlKCkgPT0gSVNEOjpTRVhUTE9BRDsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBub2RlIGlzIGEgWkVYVExPQUQuCisgIGlubGluZSBib29sIGlzWkVYVExvYWQoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIGlzYTxMb2FkU0ROb2RlPihOKSAmJgorICAgICAgY2FzdDxMb2FkU0ROb2RlPihOKS0+Z2V0RXh0ZW5zaW9uVHlwZSgpID09IElTRDo6WkVYVExPQUQ7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgbm9kZSBpcyBhbiB1bmluZGV4ZWQgbG9hZC4KKyAgaW5saW5lIGJvb2wgaXNVTklOREVYRURMb2FkKGNvbnN0IFNETm9kZSAqTikgeworICAgIHJldHVybiBpc2E8TG9hZFNETm9kZT4oTikgJiYKKyAgICAgIGNhc3Q8TG9hZFNETm9kZT4oTiktPmdldEFkZHJlc3NpbmdNb2RlKCkgPT0gSVNEOjpVTklOREVYRUQ7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgbm9kZSBpcyBhIG5vbi10cnVuY2F0aW5nCisgIC8vLyBhbmQgdW5pbmRleGVkIHN0b3JlLgorICBpbmxpbmUgYm9vbCBpc05vcm1hbFN0b3JlKGNvbnN0IFNETm9kZSAqTikgeworICAgIGNvbnN0IFN0b3JlU0ROb2RlICpTdCA9IGR5bl9jYXN0PFN0b3JlU0ROb2RlPihOKTsKKyAgICByZXR1cm4gU3QgJiYgIVN0LT5pc1RydW5jYXRpbmdTdG9yZSgpICYmCisgICAgICBTdC0+Z2V0QWRkcmVzc2luZ01vZGUoKSA9PSBJU0Q6OlVOSU5ERVhFRDsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBub2RlIGlzIGEgbm9uLXRydW5jYXRpbmcgc3RvcmUuCisgIGlubGluZSBib29sIGlzTk9OX1RSVU5DU3RvcmUoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIGlzYTxTdG9yZVNETm9kZT4oTikgJiYgIWNhc3Q8U3RvcmVTRE5vZGU+KE4pLT5pc1RydW5jYXRpbmdTdG9yZSgpOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIG5vZGUgaXMgYSB0cnVuY2F0aW5nIHN0b3JlLgorICBpbmxpbmUgYm9vbCBpc1RSVU5DU3RvcmUoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIGlzYTxTdG9yZVNETm9kZT4oTikgJiYgY2FzdDxTdG9yZVNETm9kZT4oTiktPmlzVHJ1bmNhdGluZ1N0b3JlKCk7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgbm9kZSBpcyBhbiB1bmluZGV4ZWQgc3RvcmUuCisgIGlubGluZSBib29sIGlzVU5JTkRFWEVEU3RvcmUoY29uc3QgU0ROb2RlICpOKSB7CisgICAgcmV0dXJuIGlzYTxTdG9yZVNETm9kZT4oTikgJiYKKyAgICAgIGNhc3Q8U3RvcmVTRE5vZGU+KE4pLT5nZXRBZGRyZXNzaW5nTW9kZSgpID09IElTRDo6VU5JTkRFWEVEOworICB9CisKKyAgLy8vIEF0dGVtcHQgdG8gbWF0Y2ggYSB1bmFyeSBwcmVkaWNhdGUgYWdhaW5zdCBhIHNjYWxhci9zcGxhdCBjb25zdGFudCBvcgorICAvLy8gZXZlcnkgZWxlbWVudCBvZiBhIGNvbnN0YW50IEJVSUxEX1ZFQ1RPUi4KKyAgYm9vbCBtYXRjaFVuYXJ5UHJlZGljYXRlKFNEVmFsdWUgT3AsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OmZ1bmN0aW9uPGJvb2woQ29uc3RhbnRTRE5vZGUgKik+IE1hdGNoKTsKKworICAvLy8gQXR0ZW1wdCB0byBtYXRjaCBhIGJpbmFyeSBwcmVkaWNhdGUgYWdhaW5zdCBhIHBhaXIgb2Ygc2NhbGFyL3NwbGF0CisgIC8vLyBjb25zdGFudHMgb3IgZXZlcnkgZWxlbWVudCBvZiBhIHBhaXIgb2YgY29uc3RhbnQgQlVJTERfVkVDVE9Scy4KKyAgYm9vbCBtYXRjaEJpbmFyeVByZWRpY2F0ZSgKKyAgICAgIFNEVmFsdWUgTEhTLCBTRFZhbHVlIFJIUywKKyAgICAgIHN0ZDo6ZnVuY3Rpb248Ym9vbChDb25zdGFudFNETm9kZSAqLCBDb25zdGFudFNETm9kZSAqKT4gTWF0Y2gpOworCit9IC8vIGVuZCBuYW1lc3BhY2UgSVNECisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fU0VMRUNUSU9OREFHTk9ERVNfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBR1RhcmdldEluZm8uaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TZWxlY3Rpb25EQUdUYXJnZXRJbmZvLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDVjMWRmNAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TZWxlY3Rpb25EQUdUYXJnZXRJbmZvLmgKQEAgLTAsMCArMSwxNjAgQEAKKy8vPT0tIGxsdm0vQ29kZUdlbi9TZWxlY3Rpb25EQUdUYXJnZXRJbmZvLmggLSBTZWxlY3Rpb25EQUcgSW5mbyAtLSotIEMrKyAtKi09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlY2xhcmVzIHRoZSBTZWxlY3Rpb25EQUdUYXJnZXRJbmZvIGNsYXNzLCB3aGljaCB0YXJnZXRzIGNhbgorLy8gc3ViY2xhc3MgdG8gcGFyYW1ldGVyaXplIHRoZSBTZWxlY3Rpb25EQUcgbG93ZXJpbmcgYW5kIGluc3RydWN0aW9uCisvLyBzZWxlY3Rpb24gcHJvY2Vzcy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9TRUxFQ1RJT05EQUdUQVJHRVRJTkZPX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1NFTEVDVElPTkRBR1RBUkdFVElORk9fSAorCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVNZW1PcGVyYW5kLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1NlbGVjdGlvbkRBR05vZGVzLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0NvZGVHZW4uaCIKKyNpbmNsdWRlIDx1dGlsaXR5PgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIFNlbGVjdGlvbkRBRzsKKworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLyBUYXJnZXRzIGNhbiBzdWJjbGFzcyB0aGlzIHRvIHBhcmFtZXRlcml6ZSB0aGUKKy8vLyBTZWxlY3Rpb25EQUcgbG93ZXJpbmcgYW5kIGluc3RydWN0aW9uIHNlbGVjdGlvbiBwcm9jZXNzLgorLy8vCitjbGFzcyBTZWxlY3Rpb25EQUdUYXJnZXRJbmZvIHsKK3B1YmxpYzoKKyAgZXhwbGljaXQgU2VsZWN0aW9uREFHVGFyZ2V0SW5mbygpID0gZGVmYXVsdDsKKyAgU2VsZWN0aW9uREFHVGFyZ2V0SW5mbyhjb25zdCBTZWxlY3Rpb25EQUdUYXJnZXRJbmZvICYpID0gZGVsZXRlOworICBTZWxlY3Rpb25EQUdUYXJnZXRJbmZvICZvcGVyYXRvcj0oY29uc3QgU2VsZWN0aW9uREFHVGFyZ2V0SW5mbyAmKSA9IGRlbGV0ZTsKKyAgdmlydHVhbCB+U2VsZWN0aW9uREFHVGFyZ2V0SW5mbygpOworCisgIC8vLyBFbWl0IHRhcmdldC1zcGVjaWZpYyBjb2RlIHRoYXQgcGVyZm9ybXMgYSBtZW1jcHkuCisgIC8vLyBUaGlzIGNhbiBiZSB1c2VkIGJ5IHRhcmdldHMgdG8gcHJvdmlkZSBjb2RlIHNlcXVlbmNlcyBmb3IgY2FzZXMKKyAgLy8vIHRoYXQgZG9uJ3QgZml0IHRoZSB0YXJnZXQncyBwYXJhbWV0ZXJzIGZvciBzaW1wbGUgbG9hZHMvc3RvcmVzIGFuZCBjYW4gYmUKKyAgLy8vIG1vcmUgZWZmaWNpZW50IHRoYW4gdXNpbmcgYSBsaWJyYXJ5IGNhbGwuIFRoaXMgZnVuY3Rpb24gY2FuIHJldHVybiBhIG51bGwKKyAgLy8vIFNEVmFsdWUgaWYgdGhlIHRhcmdldCBkZWNsaW5lcyB0byB1c2UgY3VzdG9tIGNvZGUgYW5kIGEgZGlmZmVyZW50CisgIC8vLyBsb3dlcmluZyBzdHJhdGVneSBzaG91bGQgYmUgdXNlZC4KKyAgLy8vCisgIC8vLyBJZiBBbHdheXNJbmxpbmUgaXMgdHJ1ZSwgdGhlIHNpemUgaXMgY29uc3RhbnQgYW5kIHRoZSB0YXJnZXQgc2hvdWxkIG5vdAorICAvLy8gZW1pdCBhbnkgY2FsbHMgYW5kIGlzIHN0cm9uZ2x5IGVuY291cmFnZWQgdG8gYXR0ZW1wdCB0byBlbWl0IGlubGluZSBjb2RlCisgIC8vLyBldmVuIGlmIGl0IGlzIGJleW9uZCB0aGUgdXN1YWwgdGhyZXNob2xkIGJlY2F1c2UgdGhpcyBpbnRyaW5zaWMgaXMgYmVpbmcKKyAgLy8vIGV4cGFuZGVkIGluIGEgcGxhY2Ugd2hlcmUgY2FsbHMgYXJlIG5vdCBmZWFzaWJsZSAoZS5nLiB3aXRoaW4gdGhlIHByb2xvZ3VlCisgIC8vLyBmb3IgYW5vdGhlciBjYWxsKS4gSWYgdGhlIHRhcmdldCBjaG9vc2VzIHRvIGRlY2xpbmUgYW4gQWx3YXlzSW5saW5lCisgIC8vLyByZXF1ZXN0IGhlcmUsIGxlZ2FsaXplIHdpbGwgcmVzb3J0IHRvIHVzaW5nIHNpbXBsZSBsb2FkcyBhbmQgc3RvcmVzLgorICB2aXJ0dWFsIFNEVmFsdWUgRW1pdFRhcmdldENvZGVGb3JNZW1jcHkoU2VsZWN0aW9uREFHICZEQUcsIGNvbnN0IFNETG9jICZkbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgQ2hhaW4sIFNEVmFsdWUgT3AxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBPcDIsIFNEVmFsdWUgT3AzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgQWxpZ24sIGJvb2wgaXNWb2xhdGlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgQWx3YXlzSW5saW5lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZVBvaW50ZXJJbmZvIERzdFB0ckluZm8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lUG9pbnRlckluZm8gU3JjUHRySW5mbykgY29uc3QgeworICAgIHJldHVybiBTRFZhbHVlKCk7CisgIH0KKworICAvLy8gRW1pdCB0YXJnZXQtc3BlY2lmaWMgY29kZSB0aGF0IHBlcmZvcm1zIGEgbWVtbW92ZS4KKyAgLy8vIFRoaXMgY2FuIGJlIHVzZWQgYnkgdGFyZ2V0cyB0byBwcm92aWRlIGNvZGUgc2VxdWVuY2VzIGZvciBjYXNlcworICAvLy8gdGhhdCBkb24ndCBmaXQgdGhlIHRhcmdldCdzIHBhcmFtZXRlcnMgZm9yIHNpbXBsZSBsb2Fkcy9zdG9yZXMgYW5kIGNhbiBiZQorICAvLy8gbW9yZSBlZmZpY2llbnQgdGhhbiB1c2luZyBhIGxpYnJhcnkgY2FsbC4gVGhpcyBmdW5jdGlvbiBjYW4gcmV0dXJuIGEgbnVsbAorICAvLy8gU0RWYWx1ZSBpZiB0aGUgdGFyZ2V0IGRlY2xpbmVzIHRvIHVzZSBjdXN0b20gY29kZSBhbmQgYSBkaWZmZXJlbnQKKyAgLy8vIGxvd2VyaW5nIHN0cmF0ZWd5IHNob3VsZCBiZSB1c2VkLgorICB2aXJ0dWFsIFNEVmFsdWUgRW1pdFRhcmdldENvZGVGb3JNZW1tb3ZlKAorICAgICAgU2VsZWN0aW9uREFHICZEQUcsIGNvbnN0IFNETG9jICZkbCwgU0RWYWx1ZSBDaGFpbiwgU0RWYWx1ZSBPcDEsCisgICAgICBTRFZhbHVlIE9wMiwgU0RWYWx1ZSBPcDMsIHVuc2lnbmVkIEFsaWduLCBib29sIGlzVm9sYXRpbGUsCisgICAgICBNYWNoaW5lUG9pbnRlckluZm8gRHN0UHRySW5mbywgTWFjaGluZVBvaW50ZXJJbmZvIFNyY1B0ckluZm8pIGNvbnN0IHsKKyAgICByZXR1cm4gU0RWYWx1ZSgpOworICB9CisKKyAgLy8vIEVtaXQgdGFyZ2V0LXNwZWNpZmljIGNvZGUgdGhhdCBwZXJmb3JtcyBhIG1lbXNldC4KKyAgLy8vIFRoaXMgY2FuIGJlIHVzZWQgYnkgdGFyZ2V0cyB0byBwcm92aWRlIGNvZGUgc2VxdWVuY2VzIGZvciBjYXNlcworICAvLy8gdGhhdCBkb24ndCBmaXQgdGhlIHRhcmdldCdzIHBhcmFtZXRlcnMgZm9yIHNpbXBsZSBzdG9yZXMgYW5kIGNhbiBiZSBtb3JlCisgIC8vLyBlZmZpY2llbnQgdGhhbiB1c2luZyBhIGxpYnJhcnkgY2FsbC4gVGhpcyBmdW5jdGlvbiBjYW4gcmV0dXJuIGEgbnVsbAorICAvLy8gU0RWYWx1ZSBpZiB0aGUgdGFyZ2V0IGRlY2xpbmVzIHRvIHVzZSBjdXN0b20gY29kZSBhbmQgYSBkaWZmZXJlbnQKKyAgLy8vIGxvd2VyaW5nIHN0cmF0ZWd5IHNob3VsZCBiZSB1c2VkLgorICB2aXJ0dWFsIFNEVmFsdWUgRW1pdFRhcmdldENvZGVGb3JNZW1zZXQoU2VsZWN0aW9uREFHICZEQUcsIGNvbnN0IFNETG9jICZkbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgQ2hhaW4sIFNEVmFsdWUgT3AxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBPcDIsIFNEVmFsdWUgT3AzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgQWxpZ24sIGJvb2wgaXNWb2xhdGlsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVQb2ludGVySW5mbyBEc3RQdHJJbmZvKSBjb25zdCB7CisgICAgcmV0dXJuIFNEVmFsdWUoKTsKKyAgfQorCisgIC8vLyBFbWl0IHRhcmdldC1zcGVjaWZpYyBjb2RlIHRoYXQgcGVyZm9ybXMgYSBtZW1jbXAsIGluIGNhc2VzIHdoZXJlIHRoYXQgaXMKKyAgLy8vIGZhc3RlciB0aGFuIGEgbGliY2FsbC4gVGhlIGZpcnN0IHJldHVybmVkIFNEVmFsdWUgaXMgdGhlIHJlc3VsdCBvZiB0aGUKKyAgLy8vIG1lbWNtcCBhbmQgdGhlIHNlY29uZCBpcyB0aGUgY2hhaW4uIEJvdGggU0RWYWx1ZXMgY2FuIGJlIG51bGwgaWYgYSBub3JtYWwKKyAgLy8vIGxpYmNhbGwgc2hvdWxkIGJlIHVzZWQuCisgIHZpcnR1YWwgc3RkOjpwYWlyPFNEVmFsdWUsIFNEVmFsdWU+CisgIEVtaXRUYXJnZXRDb2RlRm9yTWVtY21wKFNlbGVjdGlvbkRBRyAmREFHLCBjb25zdCBTRExvYyAmZGwsIFNEVmFsdWUgQ2hhaW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgT3AxLCBTRFZhbHVlIE9wMiwgU0RWYWx1ZSBPcDMsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVQb2ludGVySW5mbyBPcDFQdHJJbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lUG9pbnRlckluZm8gT3AyUHRySW5mbykgY29uc3QgeworICAgIHJldHVybiBzdGQ6Om1ha2VfcGFpcihTRFZhbHVlKCksIFNEVmFsdWUoKSk7CisgIH0KKworICAvLy8gRW1pdCB0YXJnZXQtc3BlY2lmaWMgY29kZSB0aGF0IHBlcmZvcm1zIGEgbWVtY2hyLCBpbiBjYXNlcyB3aGVyZSB0aGF0IGlzCisgIC8vLyBmYXN0ZXIgdGhhbiBhIGxpYmNhbGwuIFRoZSBmaXJzdCByZXR1cm5lZCBTRFZhbHVlIGlzIHRoZSByZXN1bHQgb2YgdGhlCisgIC8vLyBtZW1jaHIgYW5kIHRoZSBzZWNvbmQgaXMgdGhlIGNoYWluLiBCb3RoIFNEVmFsdWVzIGNhbiBiZSBudWxsIGlmIGEgbm9ybWFsCisgIC8vLyBsaWJjYWxsIHNob3VsZCBiZSB1c2VkLgorICB2aXJ0dWFsIHN0ZDo6cGFpcjxTRFZhbHVlLCBTRFZhbHVlPgorICBFbWl0VGFyZ2V0Q29kZUZvck1lbWNocihTZWxlY3Rpb25EQUcgJkRBRywgY29uc3QgU0RMb2MgJmRsLCBTRFZhbHVlIENoYWluLAorICAgICAgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIFNyYywgU0RWYWx1ZSBDaGFyLCBTRFZhbHVlIExlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZVBvaW50ZXJJbmZvIFNyY1B0ckluZm8pIGNvbnN0IHsKKyAgICByZXR1cm4gc3RkOjptYWtlX3BhaXIoU0RWYWx1ZSgpLCBTRFZhbHVlKCkpOworICB9CisKKyAgLy8vIEVtaXQgdGFyZ2V0LXNwZWNpZmljIGNvZGUgdGhhdCBwZXJmb3JtcyBhIHN0cmNweSBvciBzdHBjcHksIGluIGNhc2VzCisgIC8vLyB3aGVyZSB0aGF0IGlzIGZhc3RlciB0aGFuIGEgbGliY2FsbC4KKyAgLy8vIFRoZSBmaXJzdCByZXR1cm5lZCBTRFZhbHVlIGlzIHRoZSByZXN1bHQgb2YgdGhlIGNvcHkgKHRoZSBzdGFydAorICAvLy8gb2YgdGhlIGRlc3RpbmF0aW9uIHN0cmluZyBmb3Igc3RyY3B5LCBhIHBvaW50ZXIgdG8gdGhlIG51bGwgdGVybWluYXRvcgorICAvLy8gZm9yIHN0cGNweSkgYW5kIHRoZSBzZWNvbmQgaXMgdGhlIGNoYWluLiAgQm90aCBTRFZhbHVlcyBjYW4gYmUgbnVsbAorICAvLy8gaWYgYSBub3JtYWwgbGliY2FsbCBzaG91bGQgYmUgdXNlZC4KKyAgdmlydHVhbCBzdGQ6OnBhaXI8U0RWYWx1ZSwgU0RWYWx1ZT4KKyAgRW1pdFRhcmdldENvZGVGb3JTdHJjcHkoU2VsZWN0aW9uREFHICZEQUcsIGNvbnN0IFNETG9jICZETCwgU0RWYWx1ZSBDaGFpbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBEZXN0LCBTRFZhbHVlIFNyYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZVBvaW50ZXJJbmZvIERlc3RQdHJJbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lUG9pbnRlckluZm8gU3JjUHRySW5mbywgYm9vbCBpc1N0cGNweSkgY29uc3QgeworICAgIHJldHVybiBzdGQ6Om1ha2VfcGFpcihTRFZhbHVlKCksIFNEVmFsdWUoKSk7CisgIH0KKworICAvLy8gRW1pdCB0YXJnZXQtc3BlY2lmaWMgY29kZSB0aGF0IHBlcmZvcm1zIGEgc3RyY21wLCBpbiBjYXNlcyB3aGVyZSB0aGF0IGlzCisgIC8vLyBmYXN0ZXIgdGhhbiBhIGxpYmNhbGwuCisgIC8vLyBUaGUgZmlyc3QgcmV0dXJuZWQgU0RWYWx1ZSBpcyB0aGUgcmVzdWx0IG9mIHRoZSBzdHJjbXAgYW5kIHRoZSBzZWNvbmQgaXMKKyAgLy8vIHRoZSBjaGFpbi4gQm90aCBTRFZhbHVlcyBjYW4gYmUgbnVsbCBpZiBhIG5vcm1hbCBsaWJjYWxsIHNob3VsZCBiZSB1c2VkLgorICB2aXJ0dWFsIHN0ZDo6cGFpcjxTRFZhbHVlLCBTRFZhbHVlPgorICBFbWl0VGFyZ2V0Q29kZUZvclN0cmNtcChTZWxlY3Rpb25EQUcgJkRBRywgY29uc3QgU0RMb2MgJmRsLCBTRFZhbHVlIENoYWluLAorICAgICAgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIE9wMSwgU0RWYWx1ZSBPcDIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVQb2ludGVySW5mbyBPcDFQdHJJbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lUG9pbnRlckluZm8gT3AyUHRySW5mbykgY29uc3QgeworICAgIHJldHVybiBzdGQ6Om1ha2VfcGFpcihTRFZhbHVlKCksIFNEVmFsdWUoKSk7CisgIH0KKworICB2aXJ0dWFsIHN0ZDo6cGFpcjxTRFZhbHVlLCBTRFZhbHVlPgorICBFbWl0VGFyZ2V0Q29kZUZvclN0cmxlbihTZWxlY3Rpb25EQUcgJkRBRywgY29uc3QgU0RMb2MgJkRMLCBTRFZhbHVlIENoYWluLAorICAgICAgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIFNyYywgTWFjaGluZVBvaW50ZXJJbmZvIFNyY1B0ckluZm8pIGNvbnN0IHsKKyAgICByZXR1cm4gc3RkOjptYWtlX3BhaXIoU0RWYWx1ZSgpLCBTRFZhbHVlKCkpOworICB9CisKKyAgdmlydHVhbCBzdGQ6OnBhaXI8U0RWYWx1ZSwgU0RWYWx1ZT4KKyAgRW1pdFRhcmdldENvZGVGb3JTdHJubGVuKFNlbGVjdGlvbkRBRyAmREFHLCBjb25zdCBTRExvYyAmREwsIFNEVmFsdWUgQ2hhaW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIFNyYywgU0RWYWx1ZSBNYXhMZW5ndGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lUG9pbnRlckluZm8gU3JjUHRySW5mbykgY29uc3QgeworICAgIHJldHVybiBzdGQ6Om1ha2VfcGFpcihTRFZhbHVlKCksIFNEVmFsdWUoKSk7CisgIH0KKworICAvLyBSZXR1cm4gdHJ1ZSB3aGVuIHRoZSBkZWNpc2lvbiB0byBnZW5lcmF0ZSBGTUEncyAob3IgRk1TLCBGTUxBIGV0YykgcmF0aGVyCisgIC8vIHRoYW4gRk1VTCBhbmQgQUREIGlzIGRlbGVnYXRlZCB0byB0aGUgbWFjaGluZSBjb21iaW5lci4KKyAgdmlydHVhbCBib29sIGdlbmVyYXRlRk1Bc0luTWFjaGluZUNvbWJpbmVyKENvZGVHZW5PcHQ6OkxldmVsIE9wdExldmVsKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1NFTEVDVElPTkRBR1RBUkdFVElORk9fSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1Nsb3RJbmRleGVzLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vU2xvdEluZGV4ZXMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zYTkxZTM2Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1Nsb3RJbmRleGVzLmgKQEAgLTAsMCArMSw3MTQgQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vU2xvdEluZGV4ZXMuaCAtIFNsb3QgaW5kZXhlcyByZXByZXNlbnRhdGlvbiAtKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGltcGxlbWVudHMgU2xvdEluZGV4IGFuZCByZWxhdGVkIGNsYXNzZXMuIFRoZSBwdXJwb3NlIG9mIFNsb3RJbmRleAorLy8gaXMgdG8gZGVzY3JpYmUgYSBwb3NpdGlvbiBhdCB3aGljaCBhIHJlZ2lzdGVyIGNhbiBiZWNvbWUgbGl2ZSwgb3IgY2Vhc2UgdG8KKy8vIGJlIGxpdmUuCisvLworLy8gU2xvdEluZGV4IGlzIG1vc3RseSBhIHByb3h5IGZvciBlbnRyaWVzIG9mIHRoZSBTbG90SW5kZXhMaXN0LCBhIGNsYXNzIHdoaWNoCisvLyBpcyBoZWxkIGlzIExpdmVJbnRlcnZhbHMgYW5kIHByb3ZpZGVzIHRoZSByZWFsIG51bWJlcmluZy4gVGhpcyBhbGxvd3MKKy8vIExpdmVJbnRlcnZhbHMgdG8gcGVyZm9ybSBsYXJnZWx5IHRyYW5zcGFyZW50IHJlbnVtYmVyaW5nLgorLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fU0xPVElOREVYRVNfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fU0xPVElOREVYRVNfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9JbnRlcnZhbE1hcC5oIgorI2luY2x1ZGUgImxsdm0vQURUL1BvaW50ZXJJbnRQYWlyLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9pbGlzdC5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lQmFzaWNCbG9jay5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lRnVuY3Rpb24uaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uUGFzcy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lSW5zdHIuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUluc3RyQnVuZGxlLmgiCisjaW5jbHVkZSAibGx2bS9QYXNzLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0FsbG9jYXRvci5oIgorI2luY2x1ZGUgPGFsZ29yaXRobT4KKyNpbmNsdWRlIDxjYXNzZXJ0PgorI2luY2x1ZGUgPGl0ZXJhdG9yPgorI2luY2x1ZGUgPHV0aWxpdHk+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgcmF3X29zdHJlYW07CisKKyAgLy8vIFRoaXMgY2xhc3MgcmVwcmVzZW50cyBhbiBlbnRyeSBpbiB0aGUgc2xvdCBpbmRleCBsaXN0IGhlbGQgaW4gdGhlCisgIC8vLyBTbG90SW5kZXhlcyBwYXNzLiBJdCBzaG91bGQgbm90IGJlIHVzZWQgZGlyZWN0bHkuIFNlZSB0aGUKKyAgLy8vIFNsb3RJbmRleCAmIFNsb3RJbmRleGVzIGNsYXNzZXMgZm9yIHRoZSBwdWJsaWMgaW50ZXJmYWNlIHRvIHRoaXMKKyAgLy8vIGluZm9ybWF0aW9uLgorICBjbGFzcyBJbmRleExpc3RFbnRyeSA6IHB1YmxpYyBpbGlzdF9ub2RlPEluZGV4TGlzdEVudHJ5PiB7CisgICAgTWFjaGluZUluc3RyICptaTsKKyAgICB1bnNpZ25lZCBpbmRleDsKKworICBwdWJsaWM6CisgICAgSW5kZXhMaXN0RW50cnkoTWFjaGluZUluc3RyICptaSwgdW5zaWduZWQgaW5kZXgpIDogbWkobWkpLCBpbmRleChpbmRleCkge30KKworICAgIE1hY2hpbmVJbnN0ciogZ2V0SW5zdHIoKSBjb25zdCB7IHJldHVybiBtaTsgfQorICAgIHZvaWQgc2V0SW5zdHIoTWFjaGluZUluc3RyICptaSkgeworICAgICAgdGhpcy0+bWkgPSBtaTsKKyAgICB9CisKKyAgICB1bnNpZ25lZCBnZXRJbmRleCgpIGNvbnN0IHsgcmV0dXJuIGluZGV4OyB9CisgICAgdm9pZCBzZXRJbmRleCh1bnNpZ25lZCBpbmRleCkgeworICAgICAgdGhpcy0+aW5kZXggPSBpbmRleDsKKyAgICB9CisKKyNpZmRlZiBFWFBFTlNJVkVfQ0hFQ0tTCisgICAgLy8gV2hlbiBFWFBFTlNJVkVfQ0hFQ0tTIGlzIGRlZmluZWQsICJlcmFzZWQiIGluZGV4IGxpc3QgZW50cmllcyB3aWxsCisgICAgLy8gYWN0dWFsbHkgYmUgbW92ZWQgdG8gYSAiZ3JhdmV5YXJkIiBsaXN0LCBhbmQgaGF2ZSB0aGVpciBwb2ludGVycworICAgIC8vIHBvaXNvbmVkLCBzbyB0aGF0IGRhbmdsaW5nIFNsb3RJbmRleCBhY2Nlc3MgY2FuIGJlIHJlbGlhYmx5IGRldGVjdGVkLgorICAgIHZvaWQgc2V0UG9pc29uKCkgeworICAgICAgaW50cHRyX3QgdG1wID0gcmVpbnRlcnByZXRfY2FzdDxpbnRwdHJfdD4obWkpOworICAgICAgYXNzZXJ0KCgodG1wICYgMHgxKSA9PSAweDApICYmICJQb2ludGVyIGFscmVhZHkgcG9pc29uZWQ/Iik7CisgICAgICB0bXAgfD0gMHgxOworICAgICAgbWkgPSByZWludGVycHJldF9jYXN0PE1hY2hpbmVJbnN0cio+KHRtcCk7CisgICAgfQorCisgICAgYm9vbCBpc1BvaXNvbmVkKCkgY29uc3QgeyByZXR1cm4gKHJlaW50ZXJwcmV0X2Nhc3Q8aW50cHRyX3Q+KG1pKSAmIDB4MSkgPT0gMHgxOyB9CisjZW5kaWYgLy8gRVhQRU5TSVZFX0NIRUNLUworICB9OworCisgIHRlbXBsYXRlIDw+CisgIHN0cnVjdCBpbGlzdF9hbGxvY190cmFpdHM8SW5kZXhMaXN0RW50cnk+CisgICAgICA6IHB1YmxpYyBpbGlzdF9ub2FsbG9jX3RyYWl0czxJbmRleExpc3RFbnRyeT4ge307CisKKyAgLy8vIFNsb3RJbmRleCAtIEFuIG9wYXF1ZSB3cmFwcGVyIGFyb3VuZCBtYWNoaW5lIGluZGV4ZXMuCisgIGNsYXNzIFNsb3RJbmRleCB7CisgICAgZnJpZW5kIGNsYXNzIFNsb3RJbmRleGVzOworCisgICAgZW51bSBTbG90IHsKKyAgICAgIC8vLyBCYXNpYyBibG9jayBib3VuZGFyeS4gIFVzZWQgZm9yIGxpdmUgcmFuZ2VzIGVudGVyaW5nIGFuZCBsZWF2aW5nIGEKKyAgICAgIC8vLyBibG9jayB3aXRob3V0IGJlaW5nIGxpdmUgaW4gdGhlIGxheW91dCBuZWlnaGJvci4gIEFsc28gdXNlZCBhcyB0aGUKKyAgICAgIC8vLyBkZWYgc2xvdCBvZiBQSEktZGVmcy4KKyAgICAgIFNsb3RfQmxvY2ssCisKKyAgICAgIC8vLyBFYXJseS1jbG9iYmVyIHJlZ2lzdGVyIHVzZS9kZWYgc2xvdC4gIEEgbGl2ZSByYW5nZSBkZWZpbmVkIGF0CisgICAgICAvLy8gU2xvdF9FYXJseUNsb2JiZXIgaW50ZXJmZXJlcyB3aXRoIG5vcm1hbCBsaXZlIHJhbmdlcyBraWxsZWQgYXQKKyAgICAgIC8vLyBTbG90X1JlZ2lzdGVyLiAgQWxzbyB1c2VkIGFzIHRoZSBraWxsIHNsb3QgZm9yIGxpdmUgcmFuZ2VzIHRpZWQgdG8gYW4KKyAgICAgIC8vLyBlYXJseS1jbG9iYmVyIGRlZi4KKyAgICAgIFNsb3RfRWFybHlDbG9iYmVyLAorCisgICAgICAvLy8gTm9ybWFsIHJlZ2lzdGVyIHVzZS9kZWYgc2xvdC4gIE5vcm1hbCBpbnN0cnVjdGlvbnMga2lsbCBhbmQgZGVmaW5lCisgICAgICAvLy8gcmVnaXN0ZXIgbGl2ZSByYW5nZXMgYXQgdGhpcyBzbG90LgorICAgICAgU2xvdF9SZWdpc3RlciwKKworICAgICAgLy8vIERlYWQgZGVmIGtpbGwgcG9pbnQuICBLaWxsIHNsb3QgZm9yIGEgbGl2ZSByYW5nZSB0aGF0IGlzIGRlZmluZWQgYnkKKyAgICAgIC8vLyB0aGUgc2FtZSBpbnN0cnVjdGlvbiAoU2xvdF9SZWdpc3RlciBvciBTbG90X0Vhcmx5Q2xvYmJlciksIGJ1dCBpc24ndAorICAgICAgLy8vIHVzZWQgYW55d2hlcmUuCisgICAgICBTbG90X0RlYWQsCisKKyAgICAgIFNsb3RfQ291bnQKKyAgICB9OworCisgICAgUG9pbnRlckludFBhaXI8SW5kZXhMaXN0RW50cnkqLCAyLCB1bnNpZ25lZD4gbGllOworCisgICAgU2xvdEluZGV4KEluZGV4TGlzdEVudHJ5ICplbnRyeSwgdW5zaWduZWQgc2xvdCkKKyAgICAgIDogbGllKGVudHJ5LCBzbG90KSB7fQorCisgICAgSW5kZXhMaXN0RW50cnkqIGxpc3RFbnRyeSgpIGNvbnN0IHsKKyAgICAgIGFzc2VydChpc1ZhbGlkKCkgJiYgIkF0dGVtcHQgdG8gY29tcGFyZSByZXNlcnZlZCBpbmRleC4iKTsKKyNpZmRlZiBFWFBFTlNJVkVfQ0hFQ0tTCisgICAgICBhc3NlcnQoIWxpZS5nZXRQb2ludGVyKCktPmlzUG9pc29uZWQoKSAmJgorICAgICAgICAgICAgICJBdHRlbXB0IHRvIGFjY2VzcyBkZWxldGVkIGxpc3QtZW50cnkuIik7CisjZW5kaWYgLy8gRVhQRU5TSVZFX0NIRUNLUworICAgICAgcmV0dXJuIGxpZS5nZXRQb2ludGVyKCk7CisgICAgfQorCisgICAgdW5zaWduZWQgZ2V0SW5kZXgoKSBjb25zdCB7CisgICAgICByZXR1cm4gbGlzdEVudHJ5KCktPmdldEluZGV4KCkgfCBnZXRTbG90KCk7CisgICAgfQorCisgICAgLy8vIFJldHVybnMgdGhlIHNsb3QgZm9yIHRoaXMgU2xvdEluZGV4LgorICAgIFNsb3QgZ2V0U2xvdCgpIGNvbnN0IHsKKyAgICAgIHJldHVybiBzdGF0aWNfY2FzdDxTbG90PihsaWUuZ2V0SW50KCkpOworICAgIH0KKworICBwdWJsaWM6CisgICAgZW51bSB7CisgICAgICAvLy8gVGhlIGRlZmF1bHQgZGlzdGFuY2UgYmV0d2VlbiBpbnN0cnVjdGlvbnMgYXMgcmV0dXJuZWQgYnkgZGlzdGFuY2UoKS4KKyAgICAgIC8vLyBUaGlzIG1heSB2YXJ5IGFzIGluc3RydWN0aW9ucyBhcmUgaW5zZXJ0ZWQgYW5kIHJlbW92ZWQuCisgICAgICBJbnN0ckRpc3QgPSA0ICogU2xvdF9Db3VudAorICAgIH07CisKKyAgICAvLy8gQ29uc3RydWN0IGFuIGludmFsaWQgaW5kZXguCisgICAgU2xvdEluZGV4KCkgPSBkZWZhdWx0OworCisgICAgLy8gQ29uc3RydWN0IGEgbmV3IHNsb3QgaW5kZXggZnJvbSB0aGUgZ2l2ZW4gb25lLCBhbmQgc2V0IHRoZSBzbG90LgorICAgIFNsb3RJbmRleChjb25zdCBTbG90SW5kZXggJmxpLCBTbG90IHMpIDogbGllKGxpLmxpc3RFbnRyeSgpLCB1bnNpZ25lZChzKSkgeworICAgICAgYXNzZXJ0KGxpZS5nZXRQb2ludGVyKCkgIT0gbnVsbHB0ciAmJgorICAgICAgICAgICAgICJBdHRlbXB0IHRvIGNvbnN0cnVjdCBpbmRleCB3aXRoIDAgcG9pbnRlci4iKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYSB2YWxpZCBpbmRleC4gSW52YWxpZCBpbmRpY2VzIGRvCisgICAgLy8vIG5vdCBwb2ludCBpbnRvIGFuIGluZGV4IHRhYmxlLCBhbmQgY2Fubm90IGJlIGNvbXBhcmVkLgorICAgIGJvb2wgaXNWYWxpZCgpIGNvbnN0IHsKKyAgICAgIHJldHVybiBsaWUuZ2V0UG9pbnRlcigpOworICAgIH0KKworICAgIC8vLyBSZXR1cm4gdHJ1ZSBmb3IgYSB2YWxpZCBpbmRleC4KKyAgICBleHBsaWNpdCBvcGVyYXRvciBib29sKCkgY29uc3QgeyByZXR1cm4gaXNWYWxpZCgpOyB9CisKKyAgICAvLy8gUHJpbnQgdGhpcyBpbmRleCB0byB0aGUgZ2l2ZW4gcmF3X29zdHJlYW0uCisgICAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmb3MpIGNvbnN0OworCisgICAgLy8vIER1bXAgdGhpcyBpbmRleCB0byBzdGRlcnIuCisgICAgdm9pZCBkdW1wKCkgY29uc3Q7CisKKyAgICAvLy8gQ29tcGFyZSB0d28gU2xvdEluZGV4IG9iamVjdHMgZm9yIGVxdWFsaXR5LgorICAgIGJvb2wgb3BlcmF0b3I9PShTbG90SW5kZXggb3RoZXIpIGNvbnN0IHsKKyAgICAgIHJldHVybiBsaWUgPT0gb3RoZXIubGllOworICAgIH0KKyAgICAvLy8gQ29tcGFyZSB0d28gU2xvdEluZGV4IG9iamVjdHMgZm9yIGluZXF1YWxpdHkuCisgICAgYm9vbCBvcGVyYXRvciE9KFNsb3RJbmRleCBvdGhlcikgY29uc3QgeworICAgICAgcmV0dXJuIGxpZSAhPSBvdGhlci5saWU7CisgICAgfQorCisgICAgLy8vIENvbXBhcmUgdHdvIFNsb3RJbmRleCBvYmplY3RzLiBSZXR1cm4gdHJ1ZSBpZiB0aGUgZmlyc3QgaW5kZXgKKyAgICAvLy8gaXMgc3RyaWN0bHkgbG93ZXIgdGhhbiB0aGUgc2Vjb25kLgorICAgIGJvb2wgb3BlcmF0b3I8KFNsb3RJbmRleCBvdGhlcikgY29uc3QgeworICAgICAgcmV0dXJuIGdldEluZGV4KCkgPCBvdGhlci5nZXRJbmRleCgpOworICAgIH0KKyAgICAvLy8gQ29tcGFyZSB0d28gU2xvdEluZGV4IG9iamVjdHMuIFJldHVybiB0cnVlIGlmIHRoZSBmaXJzdCBpbmRleAorICAgIC8vLyBpcyBsb3dlciB0aGFuLCBvciBlcXVhbCB0bywgdGhlIHNlY29uZC4KKyAgICBib29sIG9wZXJhdG9yPD0oU2xvdEluZGV4IG90aGVyKSBjb25zdCB7CisgICAgICByZXR1cm4gZ2V0SW5kZXgoKSA8PSBvdGhlci5nZXRJbmRleCgpOworICAgIH0KKworICAgIC8vLyBDb21wYXJlIHR3byBTbG90SW5kZXggb2JqZWN0cy4gUmV0dXJuIHRydWUgaWYgdGhlIGZpcnN0IGluZGV4CisgICAgLy8vIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2Vjb25kLgorICAgIGJvb2wgb3BlcmF0b3I+KFNsb3RJbmRleCBvdGhlcikgY29uc3QgeworICAgICAgcmV0dXJuIGdldEluZGV4KCkgPiBvdGhlci5nZXRJbmRleCgpOworICAgIH0KKworICAgIC8vLyBDb21wYXJlIHR3byBTbG90SW5kZXggb2JqZWN0cy4gUmV0dXJuIHRydWUgaWYgdGhlIGZpcnN0IGluZGV4CisgICAgLy8vIGlzIGdyZWF0ZXIgdGhhbiwgb3IgZXF1YWwgdG8sIHRoZSBzZWNvbmQuCisgICAgYm9vbCBvcGVyYXRvcj49KFNsb3RJbmRleCBvdGhlcikgY29uc3QgeworICAgICAgcmV0dXJuIGdldEluZGV4KCkgPj0gb3RoZXIuZ2V0SW5kZXgoKTsKKyAgICB9CisKKyAgICAvLy8gaXNTYW1lSW5zdHIgLSBSZXR1cm4gdHJ1ZSBpZiBBIGFuZCBCIHJlZmVyIHRvIHRoZSBzYW1lIGluc3RydWN0aW9uLgorICAgIHN0YXRpYyBib29sIGlzU2FtZUluc3RyKFNsb3RJbmRleCBBLCBTbG90SW5kZXggQikgeworICAgICAgcmV0dXJuIEEubGllLmdldFBvaW50ZXIoKSA9PSBCLmxpZS5nZXRQb2ludGVyKCk7CisgICAgfQorCisgICAgLy8vIGlzRWFybGllckluc3RyIC0gUmV0dXJuIHRydWUgaWYgQSByZWZlcnMgdG8gYW4gaW5zdHJ1Y3Rpb24gZWFybGllciB0aGFuCisgICAgLy8vIEIuIFRoaXMgaXMgZXF1aXZhbGVudCB0byBBIDwgQiAmJiAhaXNTYW1lSW5zdHIoQSwgQikuCisgICAgc3RhdGljIGJvb2wgaXNFYXJsaWVySW5zdHIoU2xvdEluZGV4IEEsIFNsb3RJbmRleCBCKSB7CisgICAgICByZXR1cm4gQS5saXN0RW50cnkoKS0+Z2V0SW5kZXgoKSA8IEIubGlzdEVudHJ5KCktPmdldEluZGV4KCk7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0cnVlIGlmIEEgcmVmZXJzIHRvIHRoZSBzYW1lIGluc3RydWN0aW9uIGFzIEIgb3IgYW4gZWFybGllciBvbmUuCisgICAgLy8vIFRoaXMgaXMgZXF1aXZhbGVudCB0byAhaXNFYXJsaWVySW5zdHIoQiwgQSkuCisgICAgc3RhdGljIGJvb2wgaXNFYXJsaWVyRXF1YWxJbnN0cihTbG90SW5kZXggQSwgU2xvdEluZGV4IEIpIHsKKyAgICAgIHJldHVybiAhaXNFYXJsaWVySW5zdHIoQiwgQSk7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0aGUgZGlzdGFuY2UgZnJvbSB0aGlzIGluZGV4IHRvIHRoZSBnaXZlbiBvbmUuCisgICAgaW50IGRpc3RhbmNlKFNsb3RJbmRleCBvdGhlcikgY29uc3QgeworICAgICAgcmV0dXJuIG90aGVyLmdldEluZGV4KCkgLSBnZXRJbmRleCgpOworICAgIH0KKworICAgIC8vLyBSZXR1cm4gdGhlIHNjYWxlZCBkaXN0YW5jZSBmcm9tIHRoaXMgaW5kZXggdG8gdGhlIGdpdmVuIG9uZSwgd2hlcmUgYWxsCisgICAgLy8vIHNsb3RzIG9uIHRoZSBzYW1lIGluc3RydWN0aW9uIGhhdmUgemVybyBkaXN0YW5jZS4KKyAgICBpbnQgZ2V0SW5zdHJEaXN0YW5jZShTbG90SW5kZXggb3RoZXIpIGNvbnN0IHsKKyAgICAgIHJldHVybiAob3RoZXIubGlzdEVudHJ5KCktPmdldEluZGV4KCkgLSBsaXN0RW50cnkoKS0+Z2V0SW5kZXgoKSkKKyAgICAgICAgLyBTbG90X0NvdW50OworICAgIH0KKworICAgIC8vLyBpc0Jsb2NrIC0gUmV0dXJucyB0cnVlIGlmIHRoaXMgaXMgYSBibG9jayBib3VuZGFyeSBzbG90LgorICAgIGJvb2wgaXNCbG9jaygpIGNvbnN0IHsgcmV0dXJuIGdldFNsb3QoKSA9PSBTbG90X0Jsb2NrOyB9CisKKyAgICAvLy8gaXNFYXJseUNsb2JiZXIgLSBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhbiBlYXJseS1jbG9iYmVyIHNsb3QuCisgICAgYm9vbCBpc0Vhcmx5Q2xvYmJlcigpIGNvbnN0IHsgcmV0dXJuIGdldFNsb3QoKSA9PSBTbG90X0Vhcmx5Q2xvYmJlcjsgfQorCisgICAgLy8vIGlzUmVnaXN0ZXIgLSBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIG5vcm1hbCByZWdpc3RlciB1c2UvZGVmIHNsb3QuCisgICAgLy8vIE5vdGUgdGhhdCBlYXJseS1jbG9iYmVyIHNsb3RzIG1heSBhbHNvIGJlIHVzZWQgZm9yIHVzZXMgYW5kIGRlZnMuCisgICAgYm9vbCBpc1JlZ2lzdGVyKCkgY29uc3QgeyByZXR1cm4gZ2V0U2xvdCgpID09IFNsb3RfUmVnaXN0ZXI7IH0KKworICAgIC8vLyBpc0RlYWQgLSBSZXR1cm5zIHRydWUgaWYgdGhpcyBpcyBhIGRlYWQgZGVmIGtpbGwgc2xvdC4KKyAgICBib29sIGlzRGVhZCgpIGNvbnN0IHsgcmV0dXJuIGdldFNsb3QoKSA9PSBTbG90X0RlYWQ7IH0KKworICAgIC8vLyBSZXR1cm5zIHRoZSBiYXNlIGluZGV4IGZvciBhc3NvY2lhdGVkIHdpdGggdGhpcyBpbmRleC4gVGhlIGJhc2UgaW5kZXgKKyAgICAvLy8gaXMgdGhlIG9uZSBhc3NvY2lhdGVkIHdpdGggdGhlIFNsb3RfQmxvY2sgc2xvdCBmb3IgdGhlIGluc3RydWN0aW9uCisgICAgLy8vIHBvaW50ZWQgdG8gYnkgdGhpcyBpbmRleC4KKyAgICBTbG90SW5kZXggZ2V0QmFzZUluZGV4KCkgY29uc3QgeworICAgICAgcmV0dXJuIFNsb3RJbmRleChsaXN0RW50cnkoKSwgU2xvdF9CbG9jayk7CisgICAgfQorCisgICAgLy8vIFJldHVybnMgdGhlIGJvdW5kYXJ5IGluZGV4IGZvciBhc3NvY2lhdGVkIHdpdGggdGhpcyBpbmRleC4gVGhlIGJvdW5kYXJ5CisgICAgLy8vIGluZGV4IGlzIHRoZSBvbmUgYXNzb2NpYXRlZCB3aXRoIHRoZSBTbG90X0Jsb2NrIHNsb3QgZm9yIHRoZSBpbnN0cnVjdGlvbgorICAgIC8vLyBwb2ludGVkIHRvIGJ5IHRoaXMgaW5kZXguCisgICAgU2xvdEluZGV4IGdldEJvdW5kYXJ5SW5kZXgoKSBjb25zdCB7CisgICAgICByZXR1cm4gU2xvdEluZGV4KGxpc3RFbnRyeSgpLCBTbG90X0RlYWQpOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRoZSByZWdpc3RlciB1c2UvZGVmIHNsb3QgaW4gdGhlIGN1cnJlbnQgaW5zdHJ1Y3Rpb24gZm9yIGEKKyAgICAvLy8gbm9ybWFsIG9yIGVhcmx5LWNsb2JiZXIgZGVmLgorICAgIFNsb3RJbmRleCBnZXRSZWdTbG90KGJvb2wgRUMgPSBmYWxzZSkgY29uc3QgeworICAgICAgcmV0dXJuIFNsb3RJbmRleChsaXN0RW50cnkoKSwgRUMgPyBTbG90X0Vhcmx5Q2xvYmJlciA6IFNsb3RfUmVnaXN0ZXIpOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRoZSBkZWFkIGRlZiBraWxsIHNsb3QgZm9yIHRoZSBjdXJyZW50IGluc3RydWN0aW9uLgorICAgIFNsb3RJbmRleCBnZXREZWFkU2xvdCgpIGNvbnN0IHsKKyAgICAgIHJldHVybiBTbG90SW5kZXgobGlzdEVudHJ5KCksIFNsb3RfRGVhZCk7CisgICAgfQorCisgICAgLy8vIFJldHVybnMgdGhlIG5leHQgc2xvdCBpbiB0aGUgaW5kZXggbGlzdC4gVGhpcyBjb3VsZCBiZSBlaXRoZXIgdGhlCisgICAgLy8vIG5leHQgc2xvdCBmb3IgdGhlIGluc3RydWN0aW9uIHBvaW50ZWQgdG8gYnkgdGhpcyBpbmRleCBvciwgaWYgdGhpcworICAgIC8vLyBpbmRleCBpcyBhIFNUT1JFLCB0aGUgZmlyc3Qgc2xvdCBmb3IgdGhlIG5leHQgaW5zdHJ1Y3Rpb24uCisgICAgLy8vIFdBUk5JTkc6IFRoaXMgbWV0aG9kIGlzIGNvbnNpZGVyYWJseSBtb3JlIGV4cGVuc2l2ZSB0aGFuIHRoZSBtZXRob2RzCisgICAgLy8vIHRoYXQgcmV0dXJuIHNwZWNpZmljIHNsb3RzIChnZXRVc2VJbmRleCgpLCBldGMpLiBJZiB5b3UgY2FuIC0gcGxlYXNlCisgICAgLy8vIHVzZSBvbmUgb2YgdGhvc2UgbWV0aG9kcy4KKyAgICBTbG90SW5kZXggZ2V0TmV4dFNsb3QoKSBjb25zdCB7CisgICAgICBTbG90IHMgPSBnZXRTbG90KCk7CisgICAgICBpZiAocyA9PSBTbG90X0RlYWQpIHsKKyAgICAgICAgcmV0dXJuIFNsb3RJbmRleCgmKisrbGlzdEVudHJ5KCktPmdldEl0ZXJhdG9yKCksIFNsb3RfQmxvY2spOworICAgICAgfQorICAgICAgcmV0dXJuIFNsb3RJbmRleChsaXN0RW50cnkoKSwgcyArIDEpOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRoZSBuZXh0IGluZGV4LiBUaGlzIGlzIHRoZSBpbmRleCBjb3JyZXNwb25kaW5nIHRvIHRoZSB0aGlzCisgICAgLy8vIGluZGV4J3Mgc2xvdCwgYnV0IGZvciB0aGUgbmV4dCBpbnN0cnVjdGlvbi4KKyAgICBTbG90SW5kZXggZ2V0TmV4dEluZGV4KCkgY29uc3QgeworICAgICAgcmV0dXJuIFNsb3RJbmRleCgmKisrbGlzdEVudHJ5KCktPmdldEl0ZXJhdG9yKCksIGdldFNsb3QoKSk7CisgICAgfQorCisgICAgLy8vIFJldHVybnMgdGhlIHByZXZpb3VzIHNsb3QgaW4gdGhlIGluZGV4IGxpc3QuIFRoaXMgY291bGQgYmUgZWl0aGVyIHRoZQorICAgIC8vLyBwcmV2aW91cyBzbG90IGZvciB0aGUgaW5zdHJ1Y3Rpb24gcG9pbnRlZCB0byBieSB0aGlzIGluZGV4IG9yLCBpZiB0aGlzCisgICAgLy8vIGluZGV4IGlzIGEgU2xvdF9CbG9jaywgdGhlIGxhc3Qgc2xvdCBmb3IgdGhlIHByZXZpb3VzIGluc3RydWN0aW9uLgorICAgIC8vLyBXQVJOSU5HOiBUaGlzIG1ldGhvZCBpcyBjb25zaWRlcmFibHkgbW9yZSBleHBlbnNpdmUgdGhhbiB0aGUgbWV0aG9kcworICAgIC8vLyB0aGF0IHJldHVybiBzcGVjaWZpYyBzbG90cyAoZ2V0VXNlSW5kZXgoKSwgZXRjKS4gSWYgeW91IGNhbiAtIHBsZWFzZQorICAgIC8vLyB1c2Ugb25lIG9mIHRob3NlIG1ldGhvZHMuCisgICAgU2xvdEluZGV4IGdldFByZXZTbG90KCkgY29uc3QgeworICAgICAgU2xvdCBzID0gZ2V0U2xvdCgpOworICAgICAgaWYgKHMgPT0gU2xvdF9CbG9jaykgeworICAgICAgICByZXR1cm4gU2xvdEluZGV4KCYqLS1saXN0RW50cnkoKS0+Z2V0SXRlcmF0b3IoKSwgU2xvdF9EZWFkKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiBTbG90SW5kZXgobGlzdEVudHJ5KCksIHMgLSAxKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0aGUgcHJldmlvdXMgaW5kZXguIFRoaXMgaXMgdGhlIGluZGV4IGNvcnJlc3BvbmRpbmcgdG8gdGhpcworICAgIC8vLyBpbmRleCdzIHNsb3QsIGJ1dCBmb3IgdGhlIHByZXZpb3VzIGluc3RydWN0aW9uLgorICAgIFNsb3RJbmRleCBnZXRQcmV2SW5kZXgoKSBjb25zdCB7CisgICAgICByZXR1cm4gU2xvdEluZGV4KCYqLS1saXN0RW50cnkoKS0+Z2V0SXRlcmF0b3IoKSwgZ2V0U2xvdCgpKTsKKyAgICB9CisgIH07CisKKyAgdGVtcGxhdGUgPD4gc3RydWN0IGlzUG9kTGlrZTxTbG90SW5kZXg+IHsgc3RhdGljIGNvbnN0IGJvb2wgdmFsdWUgPSB0cnVlOyB9OworCisgIGlubGluZSByYXdfb3N0cmVhbSYgb3BlcmF0b3I8PChyYXdfb3N0cmVhbSAmb3MsIFNsb3RJbmRleCBsaSkgeworICAgIGxpLnByaW50KG9zKTsKKyAgICByZXR1cm4gb3M7CisgIH0KKworICB1c2luZyBJZHhNQkJQYWlyID0gc3RkOjpwYWlyPFNsb3RJbmRleCwgTWFjaGluZUJhc2ljQmxvY2sgKj47CisKKyAgaW5saW5lIGJvb2wgb3BlcmF0b3I8KFNsb3RJbmRleCBWLCBjb25zdCBJZHhNQkJQYWlyICZJTSkgeworICAgIHJldHVybiBWIDwgSU0uZmlyc3Q7CisgIH0KKworICBpbmxpbmUgYm9vbCBvcGVyYXRvcjwoY29uc3QgSWR4TUJCUGFpciAmSU0sIFNsb3RJbmRleCBWKSB7CisgICAgcmV0dXJuIElNLmZpcnN0IDwgVjsKKyAgfQorCisgIHN0cnVjdCBJZHgyTUJCQ29tcGFyZSB7CisgICAgYm9vbCBvcGVyYXRvcigpKGNvbnN0IElkeE1CQlBhaXIgJkxIUywgY29uc3QgSWR4TUJCUGFpciAmUkhTKSBjb25zdCB7CisgICAgICByZXR1cm4gTEhTLmZpcnN0IDwgUkhTLmZpcnN0OworICAgIH0KKyAgfTsKKworICAvLy8gU2xvdEluZGV4ZXMgcGFzcy4KKyAgLy8vCisgIC8vLyBUaGlzIHBhc3MgYXNzaWducyBpbmRleGVzIHRvIGVhY2ggaW5zdHJ1Y3Rpb24uCisgIGNsYXNzIFNsb3RJbmRleGVzIDogcHVibGljIE1hY2hpbmVGdW5jdGlvblBhc3MgeworICBwcml2YXRlOgorICAgIC8vIEluZGV4TGlzdEVudHJ5IGFsbG9jYXRvci4KKyAgICBCdW1wUHRyQWxsb2NhdG9yIGlsZUFsbG9jYXRvcjsKKworICAgIHVzaW5nIEluZGV4TGlzdCA9IGlsaXN0PEluZGV4TGlzdEVudHJ5PjsKKyAgICBJbmRleExpc3QgaW5kZXhMaXN0OworCisjaWZkZWYgRVhQRU5TSVZFX0NIRUNLUworICAgIEluZGV4TGlzdCBncmF2ZXlhcmRMaXN0OworI2VuZGlmIC8vIEVYUEVOU0lWRV9DSEVDS1MKKworICAgIE1hY2hpbmVGdW5jdGlvbiAqbWY7CisKKyAgICB1c2luZyBNaTJJbmRleE1hcCA9IERlbnNlTWFwPGNvbnN0IE1hY2hpbmVJbnN0ciAqLCBTbG90SW5kZXg+OworICAgIE1pMkluZGV4TWFwIG1pMmlNYXA7CisKKyAgICAvLy8gTUJCUmFuZ2VzIC0gTWFwIE1CQiBudW1iZXIgdG8gKHN0YXJ0LCBzdG9wKSBpbmRleGVzLgorICAgIFNtYWxsVmVjdG9yPHN0ZDo6cGFpcjxTbG90SW5kZXgsIFNsb3RJbmRleD4sIDg+IE1CQlJhbmdlczsKKworICAgIC8vLyBJZHgyTUJCTWFwIC0gU29ydGVkIGxpc3Qgb2YgcGFpcnMgb2YgaW5kZXggb2YgZmlyc3QgaW5zdHJ1Y3Rpb24KKyAgICAvLy8gYW5kIE1CQiBpZC4KKyAgICBTbWFsbFZlY3RvcjxJZHhNQkJQYWlyLCA4PiBpZHgyTUJCTWFwOworCisgICAgSW5kZXhMaXN0RW50cnkqIGNyZWF0ZUVudHJ5KE1hY2hpbmVJbnN0ciAqbWksIHVuc2lnbmVkIGluZGV4KSB7CisgICAgICBJbmRleExpc3RFbnRyeSAqZW50cnkgPQorICAgICAgICAgIHN0YXRpY19jYXN0PEluZGV4TGlzdEVudHJ5ICo+KGlsZUFsbG9jYXRvci5BbGxvY2F0ZSgKKyAgICAgICAgICAgICAgc2l6ZW9mKEluZGV4TGlzdEVudHJ5KSwgYWxpZ25vZihJbmRleExpc3RFbnRyeSkpKTsKKworICAgICAgbmV3IChlbnRyeSkgSW5kZXhMaXN0RW50cnkobWksIGluZGV4KTsKKworICAgICAgcmV0dXJuIGVudHJ5OworICAgIH0KKworICAgIC8vLyBSZW51bWJlciBsb2NhbGx5IGFmdGVyIGluc2VydGluZyBjdXJJdHIuCisgICAgdm9pZCByZW51bWJlckluZGV4ZXMoSW5kZXhMaXN0OjppdGVyYXRvciBjdXJJdHIpOworCisgIHB1YmxpYzoKKyAgICBzdGF0aWMgY2hhciBJRDsKKworICAgIFNsb3RJbmRleGVzKCkgOiBNYWNoaW5lRnVuY3Rpb25QYXNzKElEKSB7CisgICAgICBpbml0aWFsaXplU2xvdEluZGV4ZXNQYXNzKCpQYXNzUmVnaXN0cnk6OmdldFBhc3NSZWdpc3RyeSgpKTsKKyAgICB9CisKKyAgICB+U2xvdEluZGV4ZXMoKSBvdmVycmlkZSB7CisgICAgICAvLyBUaGUgaW5kZXhMaXN0J3Mgbm9kZXMgYXJlIGFsbCBhbGxvY2F0ZWQgaW4gdGhlIEJ1bXBQdHJBbGxvY2F0b3IuCisgICAgICBpbmRleExpc3QuY2xlYXJBbmRMZWFrTm9kZXNVbnNhZmVseSgpOworICAgIH0KKworICAgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlICZhdSkgY29uc3Qgb3ZlcnJpZGU7CisgICAgdm9pZCByZWxlYXNlTWVtb3J5KCkgb3ZlcnJpZGU7CisKKyAgICBib29sIHJ1bk9uTWFjaGluZUZ1bmN0aW9uKE1hY2hpbmVGdW5jdGlvbiAmZm4pIG92ZXJyaWRlOworCisgICAgLy8vIER1bXAgdGhlIGluZGV4ZXMuCisgICAgdm9pZCBkdW1wKCkgY29uc3Q7CisKKyAgICAvLy8gUmVudW1iZXIgdGhlIGluZGV4IGxpc3QsIHByb3ZpZGluZyBzcGFjZSBmb3IgbmV3IGluc3RydWN0aW9ucy4KKyAgICB2b2lkIHJlbnVtYmVySW5kZXhlcygpOworCisgICAgLy8vIFJlcGFpciBpbmRleGVzIGFmdGVyIGFkZGluZyBhbmQgcmVtb3ZpbmcgaW5zdHJ1Y3Rpb25zLgorICAgIHZvaWQgcmVwYWlySW5kZXhlc0luUmFuZ2UoTWFjaGluZUJhc2ljQmxvY2sgKk1CQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBCZWdpbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBFbmQpOworCisgICAgLy8vIFJldHVybnMgdGhlIHplcm8gaW5kZXggZm9yIHRoaXMgYW5hbHlzaXMuCisgICAgU2xvdEluZGV4IGdldFplcm9JbmRleCgpIHsKKyAgICAgIGFzc2VydChpbmRleExpc3QuZnJvbnQoKS5nZXRJbmRleCgpID09IDAgJiYgIkZpcnN0IGluZGV4IGlzIG5vdCAwPyIpOworICAgICAgcmV0dXJuIFNsb3RJbmRleCgmaW5kZXhMaXN0LmZyb250KCksIDApOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRoZSBiYXNlIGluZGV4IG9mIHRoZSBsYXN0IHNsb3QgaW4gdGhpcyBhbmFseXNpcy4KKyAgICBTbG90SW5kZXggZ2V0TGFzdEluZGV4KCkgeworICAgICAgcmV0dXJuIFNsb3RJbmRleCgmaW5kZXhMaXN0LmJhY2soKSwgMCk7CisgICAgfQorCisgICAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gbWFjaGluZSBpbnN0ciBpcyBtYXBwZWQgdG8gYW4gaW5kZXgsCisgICAgLy8vIG90aGVyd2lzZSByZXR1cm5zIGZhbHNlLgorICAgIGJvb2wgaGFzSW5kZXgoY29uc3QgTWFjaGluZUluc3RyICZpbnN0cikgY29uc3QgeworICAgICAgcmV0dXJuIG1pMmlNYXAuY291bnQoJmluc3RyKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0aGUgYmFzZSBpbmRleCBmb3IgdGhlIGdpdmVuIGluc3RydWN0aW9uLgorICAgIFNsb3RJbmRleCBnZXRJbnN0cnVjdGlvbkluZGV4KGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIGNvbnN0IHsKKyAgICAgIC8vIEluc3RydWN0aW9ucyBpbnNpZGUgYSBidW5kbGUgaGF2ZSB0aGUgc2FtZSBudW1iZXIgYXMgdGhlIGJ1bmRsZSBpdHNlbGYuCisgICAgICBjb25zdCBNYWNoaW5lSW5zdHIgJkJ1bmRsZVN0YXJ0ID0gKmdldEJ1bmRsZVN0YXJ0KE1JLmdldEl0ZXJhdG9yKCkpOworICAgICAgTWkySW5kZXhNYXA6OmNvbnN0X2l0ZXJhdG9yIGl0ciA9IG1pMmlNYXAuZmluZCgmQnVuZGxlU3RhcnQpOworICAgICAgYXNzZXJ0KGl0ciAhPSBtaTJpTWFwLmVuZCgpICYmICJJbnN0cnVjdGlvbiBub3QgZm91bmQgaW4gbWFwcy4iKTsKKyAgICAgIHJldHVybiBpdHItPnNlY29uZDsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0aGUgaW5zdHJ1Y3Rpb24gZm9yIHRoZSBnaXZlbiBpbmRleCwgb3IgbnVsbCBpZiB0aGUgZ2l2ZW4KKyAgICAvLy8gaW5kZXggaGFzIG5vIGluc3RydWN0aW9uIGFzc29jaWF0ZWQgd2l0aCBpdC4KKyAgICBNYWNoaW5lSW5zdHIqIGdldEluc3RydWN0aW9uRnJvbUluZGV4KFNsb3RJbmRleCBpbmRleCkgY29uc3QgeworICAgICAgcmV0dXJuIGluZGV4LmlzVmFsaWQoKSA/IGluZGV4Lmxpc3RFbnRyeSgpLT5nZXRJbnN0cigpIDogbnVsbHB0cjsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0aGUgbmV4dCBub24tbnVsbCBpbmRleCwgaWYgb25lIGV4aXN0cy4KKyAgICAvLy8gT3RoZXJ3aXNlIHJldHVybnMgZ2V0TGFzdEluZGV4KCkuCisgICAgU2xvdEluZGV4IGdldE5leHROb25OdWxsSW5kZXgoU2xvdEluZGV4IEluZGV4KSB7CisgICAgICBJbmRleExpc3Q6Oml0ZXJhdG9yIEkgPSBJbmRleC5saXN0RW50cnkoKS0+Z2V0SXRlcmF0b3IoKTsKKyAgICAgIEluZGV4TGlzdDo6aXRlcmF0b3IgRSA9IGluZGV4TGlzdC5lbmQoKTsKKyAgICAgIHdoaWxlICgrK0kgIT0gRSkKKyAgICAgICAgaWYgKEktPmdldEluc3RyKCkpCisgICAgICAgICAgcmV0dXJuIFNsb3RJbmRleCgmKkksIEluZGV4LmdldFNsb3QoKSk7CisgICAgICAvLyBXZSByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIGZ1bmN0aW9uLgorICAgICAgcmV0dXJuIGdldExhc3RJbmRleCgpOworICAgIH0KKworICAgIC8vLyBnZXRJbmRleEJlZm9yZSAtIFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGluZGV4ZWQgaW5zdHJ1Y3Rpb24KKyAgICAvLy8gYmVmb3JlIE1JLCBvciB0aGUgc3RhcnQgaW5kZXggb2YgaXRzIGJhc2ljIGJsb2NrLgorICAgIC8vLyBNSSBpcyBub3QgcmVxdWlyZWQgdG8gaGF2ZSBhbiBpbmRleC4KKyAgICBTbG90SW5kZXggZ2V0SW5kZXhCZWZvcmUoY29uc3QgTWFjaGluZUluc3RyICZNSSkgY29uc3QgeworICAgICAgY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKk1CQiA9IE1JLmdldFBhcmVudCgpOworICAgICAgYXNzZXJ0KE1CQiAmJiAiTUkgbXVzdCBiZSBpbnNlcnRlZCBpbm5hIGJhc2ljIGJsb2NrIik7CisgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6Y29uc3RfaXRlcmF0b3IgSSA9IE1JLCBCID0gTUJCLT5iZWdpbigpOworICAgICAgd2hpbGUgKHRydWUpIHsKKyAgICAgICAgaWYgKEkgPT0gQikKKyAgICAgICAgICByZXR1cm4gZ2V0TUJCU3RhcnRJZHgoTUJCKTsKKyAgICAgICAgLS1JOworICAgICAgICBNaTJJbmRleE1hcDo6Y29uc3RfaXRlcmF0b3IgTWFwSXRyID0gbWkyaU1hcC5maW5kKCYqSSk7CisgICAgICAgIGlmIChNYXBJdHIgIT0gbWkyaU1hcC5lbmQoKSkKKyAgICAgICAgICByZXR1cm4gTWFwSXRyLT5zZWNvbmQ7CisgICAgICB9CisgICAgfQorCisgICAgLy8vIGdldEluZGV4QWZ0ZXIgLSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgaW5kZXhlZCBpbnN0cnVjdGlvbgorICAgIC8vLyBhZnRlciBNSSwgb3IgdGhlIGVuZCBpbmRleCBvZiBpdHMgYmFzaWMgYmxvY2suCisgICAgLy8vIE1JIGlzIG5vdCByZXF1aXJlZCB0byBoYXZlIGFuIGluZGV4LgorICAgIFNsb3RJbmRleCBnZXRJbmRleEFmdGVyKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIGNvbnN0IHsKKyAgICAgIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIgPSBNSS5nZXRQYXJlbnQoKTsKKyAgICAgIGFzc2VydChNQkIgJiYgIk1JIG11c3QgYmUgaW5zZXJ0ZWQgaW5uYSBiYXNpYyBibG9jayIpOworICAgICAgTWFjaGluZUJhc2ljQmxvY2s6OmNvbnN0X2l0ZXJhdG9yIEkgPSBNSSwgRSA9IE1CQi0+ZW5kKCk7CisgICAgICB3aGlsZSAodHJ1ZSkgeworICAgICAgICArK0k7CisgICAgICAgIGlmIChJID09IEUpCisgICAgICAgICAgcmV0dXJuIGdldE1CQkVuZElkeChNQkIpOworICAgICAgICBNaTJJbmRleE1hcDo6Y29uc3RfaXRlcmF0b3IgTWFwSXRyID0gbWkyaU1hcC5maW5kKCYqSSk7CisgICAgICAgIGlmIChNYXBJdHIgIT0gbWkyaU1hcC5lbmQoKSkKKyAgICAgICAgICByZXR1cm4gTWFwSXRyLT5zZWNvbmQ7CisgICAgICB9CisgICAgfQorCisgICAgLy8vIFJldHVybiB0aGUgKHN0YXJ0LGVuZCkgcmFuZ2Ugb2YgdGhlIGdpdmVuIGJhc2ljIGJsb2NrIG51bWJlci4KKyAgICBjb25zdCBzdGQ6OnBhaXI8U2xvdEluZGV4LCBTbG90SW5kZXg+ICYKKyAgICBnZXRNQkJSYW5nZSh1bnNpZ25lZCBOdW0pIGNvbnN0IHsKKyAgICAgIHJldHVybiBNQkJSYW5nZXNbTnVtXTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRoZSAoc3RhcnQsZW5kKSByYW5nZSBvZiB0aGUgZ2l2ZW4gYmFzaWMgYmxvY2suCisgICAgY29uc3Qgc3RkOjpwYWlyPFNsb3RJbmRleCwgU2xvdEluZGV4PiAmCisgICAgZ2V0TUJCUmFuZ2UoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgKk1CQikgY29uc3QgeworICAgICAgcmV0dXJuIGdldE1CQlJhbmdlKE1CQi0+Z2V0TnVtYmVyKCkpOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRoZSBmaXJzdCBpbmRleCBpbiB0aGUgZ2l2ZW4gYmFzaWMgYmxvY2sgbnVtYmVyLgorICAgIFNsb3RJbmRleCBnZXRNQkJTdGFydElkeCh1bnNpZ25lZCBOdW0pIGNvbnN0IHsKKyAgICAgIHJldHVybiBnZXRNQkJSYW5nZShOdW0pLmZpcnN0OworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRoZSBmaXJzdCBpbmRleCBpbiB0aGUgZ2l2ZW4gYmFzaWMgYmxvY2suCisgICAgU2xvdEluZGV4IGdldE1CQlN0YXJ0SWR4KGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICptYmIpIGNvbnN0IHsKKyAgICAgIHJldHVybiBnZXRNQkJSYW5nZShtYmIpLmZpcnN0OworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRoZSBsYXN0IGluZGV4IGluIHRoZSBnaXZlbiBiYXNpYyBibG9jayBudW1iZXIuCisgICAgU2xvdEluZGV4IGdldE1CQkVuZElkeCh1bnNpZ25lZCBOdW0pIGNvbnN0IHsKKyAgICAgIHJldHVybiBnZXRNQkJSYW5nZShOdW0pLnNlY29uZDsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0aGUgbGFzdCBpbmRleCBpbiB0aGUgZ2l2ZW4gYmFzaWMgYmxvY2suCisgICAgU2xvdEluZGV4IGdldE1CQkVuZElkeChjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqbWJiKSBjb25zdCB7CisgICAgICByZXR1cm4gZ2V0TUJCUmFuZ2UobWJiKS5zZWNvbmQ7CisgICAgfQorCisgICAgLy8vIEl0ZXJhdG9yIG92ZXIgdGhlIGlkeDJNQkJNYXAgKHNvcnRlZCBwYWlycyBvZiBzbG90IGluZGV4IG9mIGJhc2ljIGJsb2NrCisgICAgLy8vIGJlZ2luIGFuZCBiYXNpYyBibG9jaykKKyAgICB1c2luZyBNQkJJbmRleEl0ZXJhdG9yID0gU21hbGxWZWN0b3JJbXBsPElkeE1CQlBhaXI+Ojpjb25zdF9pdGVyYXRvcjsKKworICAgIC8vLyBNb3ZlIGl0ZXJhdG9yIHRvIHRoZSBuZXh0IElkeE1CQlBhaXIgd2hlcmUgdGhlIFNsb3RJbmRleCBpcyBncmVhdGVyIG9yCisgICAgLy8vIGVxdWFsIHRvIFxwIFRvLgorICAgIE1CQkluZGV4SXRlcmF0b3IgYWR2YW5jZU1CQkluZGV4KE1CQkluZGV4SXRlcmF0b3IgSSwgU2xvdEluZGV4IFRvKSBjb25zdCB7CisgICAgICByZXR1cm4gc3RkOjpsb3dlcl9ib3VuZChJLCBpZHgyTUJCTWFwLmVuZCgpLCBUbyk7CisgICAgfQorCisgICAgLy8vIEdldCBhbiBpdGVyYXRvciBwb2ludGluZyB0byB0aGUgSWR4TUJCUGFpciB3aXRoIHRoZSBiaWdnZXN0IFNsb3RJbmRleAorICAgIC8vLyB0aGF0IGlzIGdyZWF0ZXIgb3IgZXF1YWwgdG8gXHAgSWR4LgorICAgIE1CQkluZGV4SXRlcmF0b3IgZmluZE1CQkluZGV4KFNsb3RJbmRleCBJZHgpIGNvbnN0IHsKKyAgICAgIHJldHVybiBhZHZhbmNlTUJCSW5kZXgoaWR4Mk1CQk1hcC5iZWdpbigpLCBJZHgpOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIGFuIGl0ZXJhdG9yIGZvciB0aGUgYmVnaW4gb2YgdGhlIGlkeDJNQkJNYXAuCisgICAgTUJCSW5kZXhJdGVyYXRvciBNQkJJbmRleEJlZ2luKCkgY29uc3QgeworICAgICAgcmV0dXJuIGlkeDJNQkJNYXAuYmVnaW4oKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIGFuIGl0ZXJhdG9yIGZvciB0aGUgZW5kIG9mIHRoZSBpZHgyTUJCTWFwLgorICAgIE1CQkluZGV4SXRlcmF0b3IgTUJCSW5kZXhFbmQoKSBjb25zdCB7CisgICAgICByZXR1cm4gaWR4Mk1CQk1hcC5lbmQoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0aGUgYmFzaWMgYmxvY2sgd2hpY2ggdGhlIGdpdmVuIGluZGV4IGZhbGxzIGluLgorICAgIE1hY2hpbmVCYXNpY0Jsb2NrKiBnZXRNQkJGcm9tSW5kZXgoU2xvdEluZGV4IGluZGV4KSBjb25zdCB7CisgICAgICBpZiAoTWFjaGluZUluc3RyICpNSSA9IGdldEluc3RydWN0aW9uRnJvbUluZGV4KGluZGV4KSkKKyAgICAgICAgcmV0dXJuIE1JLT5nZXRQYXJlbnQoKTsKKworICAgICAgTUJCSW5kZXhJdGVyYXRvciBJID0gZmluZE1CQkluZGV4KGluZGV4KTsKKyAgICAgIC8vIFRha2UgdGhlIHBhaXIgY29udGFpbmluZyB0aGUgaW5kZXgKKyAgICAgIE1CQkluZGV4SXRlcmF0b3IgSiA9CisgICAgICAgICgoSSAhPSBNQkJJbmRleEVuZCgpICYmIEktPmZpcnN0ID4gaW5kZXgpIHx8CisgICAgICAgICAoSSA9PSBNQkJJbmRleEVuZCgpICYmICFpZHgyTUJCTWFwLmVtcHR5KCkpKSA/IHN0ZDo6cHJldihJKSA6IEk7CisKKyAgICAgIGFzc2VydChKICE9IE1CQkluZGV4RW5kKCkgJiYgSi0+Zmlyc3QgPD0gaW5kZXggJiYKKyAgICAgICAgICAgICBpbmRleCA8IGdldE1CQkVuZElkeChKLT5zZWNvbmQpICYmCisgICAgICAgICAgICAgImluZGV4IGRvZXMgbm90IGNvcnJlc3BvbmQgdG8gYW4gTUJCIik7CisgICAgICByZXR1cm4gSi0+c2Vjb25kOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRoZSBNQkIgY292ZXJpbmcgdGhlIGdpdmVuIHJhbmdlLCBvciBudWxsIGlmIHRoZSByYW5nZSBjb3ZlcnMKKyAgICAvLy8gbW9yZSB0aGFuIG9uZSBiYXNpYyBibG9jay4KKyAgICBNYWNoaW5lQmFzaWNCbG9jayogZ2V0TUJCQ292ZXJpbmdSYW5nZShTbG90SW5kZXggc3RhcnQsIFNsb3RJbmRleCBlbmQpIGNvbnN0IHsKKworICAgICAgYXNzZXJ0KHN0YXJ0IDwgZW5kICYmICJCYWNrd2FyZHMgcmFuZ2VzIG5vdCBhbGxvd2VkLiIpOworICAgICAgTUJCSW5kZXhJdGVyYXRvciBpdHIgPSBmaW5kTUJCSW5kZXgoc3RhcnQpOworICAgICAgaWYgKGl0ciA9PSBNQkJJbmRleEVuZCgpKSB7CisgICAgICAgIGl0ciA9IHN0ZDo6cHJldihpdHIpOworICAgICAgICByZXR1cm4gaXRyLT5zZWNvbmQ7CisgICAgICB9CisKKyAgICAgIC8vIENoZWNrIHRoYXQgd2UgZG9uJ3QgY3Jvc3MgdGhlIGJvdW5kYXJ5IGludG8gdGhpcyBibG9jay4KKyAgICAgIGlmIChpdHItPmZpcnN0IDwgZW5kKQorICAgICAgICByZXR1cm4gbnVsbHB0cjsKKworICAgICAgaXRyID0gc3RkOjpwcmV2KGl0cik7CisKKyAgICAgIGlmIChpdHItPmZpcnN0IDw9IHN0YXJ0KQorICAgICAgICByZXR1cm4gaXRyLT5zZWNvbmQ7CisKKyAgICAgIHJldHVybiBudWxscHRyOworICAgIH0KKworICAgIC8vLyBJbnNlcnQgdGhlIGdpdmVuIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gaW50byB0aGUgbWFwcGluZy4gUmV0dXJucyB0aGUKKyAgICAvLy8gYXNzaWduZWQgaW5kZXguCisgICAgLy8vIElmIExhdGUgaXMgc2V0IGFuZCB0aGVyZSBhcmUgbnVsbCBpbmRleGVzIGJldHdlZW4gbWkncyBuZWlnaGJvcmluZworICAgIC8vLyBpbnN0cnVjdGlvbnMsIGNyZWF0ZSB0aGUgbmV3IGluZGV4IGFmdGVyIHRoZSBudWxsIGluZGV4ZXMgaW5zdGVhZCBvZgorICAgIC8vLyBiZWZvcmUgdGhlbS4KKyAgICBTbG90SW5kZXggaW5zZXJ0TWFjaGluZUluc3RySW5NYXBzKE1hY2hpbmVJbnN0ciAmTUksIGJvb2wgTGF0ZSA9IGZhbHNlKSB7CisgICAgICBhc3NlcnQoIU1JLmlzSW5zaWRlQnVuZGxlKCkgJiYKKyAgICAgICAgICAgICAiSW5zdHJ1Y3Rpb25zIGluc2lkZSBidW5kbGVzIHNob3VsZCB1c2UgYnVuZGxlIHN0YXJ0J3Mgc2xvdC4iKTsKKyAgICAgIGFzc2VydChtaTJpTWFwLmZpbmQoJk1JKSA9PSBtaTJpTWFwLmVuZCgpICYmICJJbnN0ciBhbHJlYWR5IGluZGV4ZWQuIik7CisgICAgICAvLyBOdW1iZXJpbmcgREJHX1ZBTFVFIGluc3RydWN0aW9ucyBjb3VsZCBjYXVzZSBjb2RlIGdlbmVyYXRpb24gdG8gYmUKKyAgICAgIC8vIGFmZmVjdGVkIGJ5IGRlYnVnIGluZm9ybWF0aW9uLgorICAgICAgYXNzZXJ0KCFNSS5pc0RlYnVnVmFsdWUoKSAmJiAiQ2Fubm90IG51bWJlciBEQkdfVkFMVUUgaW5zdHJ1Y3Rpb25zLiIpOworCisgICAgICBhc3NlcnQoTUkuZ2V0UGFyZW50KCkgIT0gbnVsbHB0ciAmJiAiSW5zdHIgbXVzdCBiZSBhZGRlZCB0byBmdW5jdGlvbi4iKTsKKworICAgICAgLy8gR2V0IHRoZSBlbnRyaWVzIHdoZXJlIE1JIHNob3VsZCBiZSBpbnNlcnRlZC4KKyAgICAgIEluZGV4TGlzdDo6aXRlcmF0b3IgcHJldkl0ciwgbmV4dEl0cjsKKyAgICAgIGlmIChMYXRlKSB7CisgICAgICAgIC8vIEluc2VydCBNSSdzIGluZGV4IGltbWVkaWF0ZWx5IGJlZm9yZSB0aGUgZm9sbG93aW5nIGluc3RydWN0aW9uLgorICAgICAgICBuZXh0SXRyID0gZ2V0SW5kZXhBZnRlcihNSSkubGlzdEVudHJ5KCktPmdldEl0ZXJhdG9yKCk7CisgICAgICAgIHByZXZJdHIgPSBzdGQ6OnByZXYobmV4dEl0cik7CisgICAgICB9IGVsc2UgeworICAgICAgICAvLyBJbnNlcnQgTUkncyBpbmRleCBpbW1lZGlhdGVseSBhZnRlciB0aGUgcHJlY2VkaW5nIGluc3RydWN0aW9uLgorICAgICAgICBwcmV2SXRyID0gZ2V0SW5kZXhCZWZvcmUoTUkpLmxpc3RFbnRyeSgpLT5nZXRJdGVyYXRvcigpOworICAgICAgICBuZXh0SXRyID0gc3RkOjpuZXh0KHByZXZJdHIpOworICAgICAgfQorCisgICAgICAvLyBHZXQgYSBudW1iZXIgZm9yIHRoZSBuZXcgaW5zdHIsIG9yIDAgaWYgdGhlcmUncyBubyByb29tIGN1cnJlbnRseS4KKyAgICAgIC8vIEluIHRoZSBsYXR0ZXIgY2FzZSB3ZSdsbCBmb3JjZSBhIHJlbnVtYmVyIGxhdGVyLgorICAgICAgdW5zaWduZWQgZGlzdCA9ICgobmV4dEl0ci0+Z2V0SW5kZXgoKSAtIHByZXZJdHItPmdldEluZGV4KCkpLzIpICYgfjN1OworICAgICAgdW5zaWduZWQgbmV3TnVtYmVyID0gcHJldkl0ci0+Z2V0SW5kZXgoKSArIGRpc3Q7CisKKyAgICAgIC8vIEluc2VydCBhIG5ldyBsaXN0IGVudHJ5IGZvciBNSS4KKyAgICAgIEluZGV4TGlzdDo6aXRlcmF0b3IgbmV3SXRyID0KKyAgICAgICAgICBpbmRleExpc3QuaW5zZXJ0KG5leHRJdHIsIGNyZWF0ZUVudHJ5KCZNSSwgbmV3TnVtYmVyKSk7CisKKyAgICAgIC8vIFJlbnVtYmVyIGxvY2FsbHkgaWYgd2UgbmVlZCB0by4KKyAgICAgIGlmIChkaXN0ID09IDApCisgICAgICAgIHJlbnVtYmVySW5kZXhlcyhuZXdJdHIpOworCisgICAgICBTbG90SW5kZXggbmV3SW5kZXgoJipuZXdJdHIsIFNsb3RJbmRleDo6U2xvdF9CbG9jayk7CisgICAgICBtaTJpTWFwLmluc2VydChzdGQ6Om1ha2VfcGFpcigmTUksIG5ld0luZGV4KSk7CisgICAgICByZXR1cm4gbmV3SW5kZXg7CisgICAgfQorCisgICAgLy8vIFJlbW92ZXMgbWFjaGluZSBpbnN0cnVjdGlvbiAoYnVuZGxlKSBccCBNSSBmcm9tIHRoZSBtYXBwaW5nLgorICAgIC8vLyBUaGlzIHNob3VsZCBiZSBjYWxsZWQgYmVmb3JlIE1hY2hpbmVJbnN0cjo6ZXJhc2VGcm9tUGFyZW50KCkgaXMgdXNlZCB0bworICAgIC8vLyByZW1vdmUgYSB3aG9sZSBidW5kbGUgb3IgYW4gdW5idW5kbGVkIGluc3RydWN0aW9uLgorICAgIHZvaWQgcmVtb3ZlTWFjaGluZUluc3RyRnJvbU1hcHMoTWFjaGluZUluc3RyICZNSSk7CisKKyAgICAvLy8gUmVtb3ZlcyBhIHNpbmdsZSBtYWNoaW5lIGluc3RydWN0aW9uIFxwIE1JIGZyb20gdGhlIG1hcHBpbmcuCisgICAgLy8vIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBiZWZvcmUgTWFjaGluZUluc3RyOjplcmFzZUZyb21CdW5kbGUoKSBpcyB1c2VkIHRvCisgICAgLy8vIHJlbW92ZSBhIHNpbmdsZSBpbnN0cnVjdGlvbiAob3V0IG9mIGEgYnVuZGxlKS4KKyAgICB2b2lkIHJlbW92ZVNpbmdsZU1hY2hpbmVJbnN0ckZyb21NYXBzKE1hY2hpbmVJbnN0ciAmTUkpOworCisgICAgLy8vIFJlcGxhY2VNYWNoaW5lSW5zdHJJbk1hcHMgLSBSZXBsYWNpbmcgYSBtYWNoaW5lIGluc3RyIHdpdGggYSBuZXcgb25lIGluCisgICAgLy8vIG1hcHMgdXNlZCBieSByZWdpc3RlciBhbGxvY2F0b3IuIFxyZXR1cm5zIHRoZSBpbmRleCB3aGVyZSB0aGUgbmV3CisgICAgLy8vIGluc3RydWN0aW9uIHdhcyBpbnNlcnRlZC4KKyAgICBTbG90SW5kZXggcmVwbGFjZU1hY2hpbmVJbnN0ckluTWFwcyhNYWNoaW5lSW5zdHIgJk1JLCBNYWNoaW5lSW5zdHIgJk5ld01JKSB7CisgICAgICBNaTJJbmRleE1hcDo6aXRlcmF0b3IgbWkyaUl0ciA9IG1pMmlNYXAuZmluZCgmTUkpOworICAgICAgaWYgKG1pMmlJdHIgPT0gbWkyaU1hcC5lbmQoKSkKKyAgICAgICAgcmV0dXJuIFNsb3RJbmRleCgpOworICAgICAgU2xvdEluZGV4IHJlcGxhY2VCYXNlSW5kZXggPSBtaTJpSXRyLT5zZWNvbmQ7CisgICAgICBJbmRleExpc3RFbnRyeSAqbWlFbnRyeShyZXBsYWNlQmFzZUluZGV4Lmxpc3RFbnRyeSgpKTsKKyAgICAgIGFzc2VydChtaUVudHJ5LT5nZXRJbnN0cigpID09ICZNSSAmJgorICAgICAgICAgICAgICJNaXNtYXRjaGVkIGluc3RydWN0aW9uIGluIGluZGV4IHRhYmxlcy4iKTsKKyAgICAgIG1pRW50cnktPnNldEluc3RyKCZOZXdNSSk7CisgICAgICBtaTJpTWFwLmVyYXNlKG1pMmlJdHIpOworICAgICAgbWkyaU1hcC5pbnNlcnQoc3RkOjptYWtlX3BhaXIoJk5ld01JLCByZXBsYWNlQmFzZUluZGV4KSk7CisgICAgICByZXR1cm4gcmVwbGFjZUJhc2VJbmRleDsKKyAgICB9CisKKyAgICAvLy8gQWRkIHRoZSBnaXZlbiBNYWNoaW5lQmFzaWNCbG9jayBpbnRvIHRoZSBtYXBzLgorICAgIHZvaWQgaW5zZXJ0TUJCSW5NYXBzKE1hY2hpbmVCYXNpY0Jsb2NrICptYmIpIHsKKyAgICAgIE1hY2hpbmVGdW5jdGlvbjo6aXRlcmF0b3IgbmV4dE1CQiA9CisgICAgICAgIHN0ZDo6bmV4dChNYWNoaW5lRnVuY3Rpb246Oml0ZXJhdG9yKG1iYikpOworCisgICAgICBJbmRleExpc3RFbnRyeSAqc3RhcnRFbnRyeSA9IG51bGxwdHI7CisgICAgICBJbmRleExpc3RFbnRyeSAqZW5kRW50cnkgPSBudWxscHRyOworICAgICAgSW5kZXhMaXN0OjppdGVyYXRvciBuZXdJdHI7CisgICAgICBpZiAobmV4dE1CQiA9PSBtYmItPmdldFBhcmVudCgpLT5lbmQoKSkgeworICAgICAgICBzdGFydEVudHJ5ID0gJmluZGV4TGlzdC5iYWNrKCk7CisgICAgICAgIGVuZEVudHJ5ID0gY3JlYXRlRW50cnkobnVsbHB0ciwgMCk7CisgICAgICAgIG5ld0l0ciA9IGluZGV4TGlzdC5pbnNlcnRBZnRlcihzdGFydEVudHJ5LT5nZXRJdGVyYXRvcigpLCBlbmRFbnRyeSk7CisgICAgICB9IGVsc2UgeworICAgICAgICBzdGFydEVudHJ5ID0gY3JlYXRlRW50cnkobnVsbHB0ciwgMCk7CisgICAgICAgIGVuZEVudHJ5ID0gZ2V0TUJCU3RhcnRJZHgoJipuZXh0TUJCKS5saXN0RW50cnkoKTsKKyAgICAgICAgbmV3SXRyID0gaW5kZXhMaXN0Lmluc2VydChlbmRFbnRyeS0+Z2V0SXRlcmF0b3IoKSwgc3RhcnRFbnRyeSk7CisgICAgICB9CisKKyAgICAgIFNsb3RJbmRleCBzdGFydElkeChzdGFydEVudHJ5LCBTbG90SW5kZXg6OlNsb3RfQmxvY2spOworICAgICAgU2xvdEluZGV4IGVuZElkeChlbmRFbnRyeSwgU2xvdEluZGV4OjpTbG90X0Jsb2NrKTsKKworICAgICAgTWFjaGluZUZ1bmN0aW9uOjppdGVyYXRvciBwcmV2TUJCKG1iYik7CisgICAgICBhc3NlcnQocHJldk1CQiAhPSBtYmItPmdldFBhcmVudCgpLT5lbmQoKSAmJgorICAgICAgICAgICAgICJDYW4ndCBpbnNlcnQgYSBuZXcgYmxvY2sgYXQgdGhlIGJlZ2lubmluZyBvZiBhIGZ1bmN0aW9uLiIpOworICAgICAgLS1wcmV2TUJCOworICAgICAgTUJCUmFuZ2VzW3ByZXZNQkItPmdldE51bWJlcigpXS5zZWNvbmQgPSBzdGFydElkeDsKKworICAgICAgYXNzZXJ0KHVuc2lnbmVkKG1iYi0+Z2V0TnVtYmVyKCkpID09IE1CQlJhbmdlcy5zaXplKCkgJiYKKyAgICAgICAgICAgICAiQmxvY2tzIG11c3QgYmUgYWRkZWQgaW4gb3JkZXIiKTsKKyAgICAgIE1CQlJhbmdlcy5wdXNoX2JhY2soc3RkOjptYWtlX3BhaXIoc3RhcnRJZHgsIGVuZElkeCkpOworICAgICAgaWR4Mk1CQk1hcC5wdXNoX2JhY2soSWR4TUJCUGFpcihzdGFydElkeCwgbWJiKSk7CisKKyAgICAgIHJlbnVtYmVySW5kZXhlcyhuZXdJdHIpOworICAgICAgc3RkOjpzb3J0KGlkeDJNQkJNYXAuYmVnaW4oKSwgaWR4Mk1CQk1hcC5lbmQoKSwgSWR4Mk1CQkNvbXBhcmUoKSk7CisgICAgfQorCisgICAgLy8vIFxicmllZiBGcmVlIHRoZSByZXNvdXJjZXMgdGhhdCB3ZXJlIHJlcXVpcmVkIHRvIG1haW50YWluIGEgU2xvdEluZGV4LgorICAgIC8vLworICAgIC8vLyBPbmNlIGFuIGluZGV4IGlzIG5vIGxvbmdlciBuZWVkZWQgKGZvciBpbnN0YW5jZSBiZWNhdXNlIHRoZSBpbnN0cnVjdGlvbgorICAgIC8vLyBhdCB0aGF0IGluZGV4IGhhcyBiZWVuIG1vdmVkKSwgdGhlIHJlc291cmNlcyByZXF1aXJlZCB0byBtYWludGFpbiB0aGUKKyAgICAvLy8gaW5kZXggY2FuIGJlIHJlbGlucXVpc2hlZCB0byByZWR1Y2UgbWVtb3J5IHVzZSBhbmQgaW1wcm92ZSByZW51bWJlcmluZworICAgIC8vLyBwZXJmb3JtYW5jZS4gQW55IHJlbWFpbmluZyBTbG90SW5kZXggb2JqZWN0cyB0aGF0IHBvaW50IHRvIHRoZSBzYW1lCisgICAgLy8vIGluZGV4IGFyZSBsZWZ0ICdkYW5nbGluZycgKG11Y2ggdGhlIHNhbWUgYXMgYSBkYW5nbGluZyBwb2ludGVyIHRvIGEKKyAgICAvLy8gZnJlZWQgb2JqZWN0KSBhbmQgc2hvdWxkIG5vdCBiZSBhY2Nlc3NlZCwgZXhjZXB0IHRvIGRlc3RydWN0IHRoZW0uCisgICAgLy8vCisgICAgLy8vIExpa2UgZGFuZ2xpbmcgcG9pbnRlcnMsIGFjY2VzcyB0byBkYW5nbGluZyBTbG90SW5kZXhlcyBjYW4gY2F1c2UKKyAgICAvLy8gcGFpbmZ1bC10by10cmFjay1kb3duIGJ1Z3MsIGVzcGVjaWFsbHkgaWYgdGhlIG1lbW9yeSBmb3IgdGhlIGluZGV4CisgICAgLy8vIHByZXZpb3VzbHkgcG9pbnRlZCB0byBoYXMgYmVlbiByZS11c2VkLiBUbyBkZXRlY3QgZGFuZ2xpbmcgU2xvdEluZGV4CisgICAgLy8vIGJ1Z3MsIGJ1aWxkIHdpdGggRVhQRU5TSVZFX0NIRUNLUz0xLiBUaGlzIHdpbGwgY2F1c2UgImVyYXNlZCIgaW5kZXhlcyB0bworICAgIC8vLyBiZSByZXRhaW5lZCBpbiBhIGdyYXZleWFyZCBpbnN0ZWFkIG9mIGJlaW5nIGZyZWVkLiBPcGVyYXRpb25zIG9uIGluZGV4ZXMKKyAgICAvLy8gaW4gdGhlIGdyYXZleWFyZCB3aWxsIHRyaWdnZXIgYW4gYXNzZXJ0aW9uLgorICAgIHZvaWQgZXJhc2VJbmRleChTbG90SW5kZXggaW5kZXgpIHsKKyAgICAgIEluZGV4TGlzdEVudHJ5ICplbnRyeSA9IGluZGV4Lmxpc3RFbnRyeSgpOworI2lmZGVmIEVYUEVOU0lWRV9DSEVDS1MKKyAgICAgIGluZGV4TGlzdC5yZW1vdmUoZW50cnkpOworICAgICAgZ3JhdmV5YXJkTGlzdC5wdXNoX2JhY2soZW50cnkpOworICAgICAgZW50cnktPnNldFBvaXNvbigpOworI2Vsc2UKKyAgICAgIGluZGV4TGlzdC5lcmFzZShlbnRyeSk7CisjZW5kaWYKKyAgICB9CisgIH07CisKKyAgLy8gU3BlY2lhbGl6ZSBJbnRlcnZhbE1hcEluZm8gZm9yIGhhbGYtb3BlbiBzbG90IGluZGV4IGludGVydmFscy4KKyAgdGVtcGxhdGUgPD4KKyAgc3RydWN0IEludGVydmFsTWFwSW5mbzxTbG90SW5kZXg+IDogSW50ZXJ2YWxNYXBIYWxmT3BlbkluZm88U2xvdEluZGV4PiB7CisgIH07CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fU0xPVElOREVYRVNfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1N0YWNrTWFwcy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1N0YWNrTWFwcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ0MDcxMTQKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vU3RhY2tNYXBzLmgKQEAgLTAsMCArMSwzMzIgQEAKKy8vPT09LSBTdGFja01hcHMuaCAtIFN0YWNrTWFwcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1NUQUNLTUFQU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9TVEFDS01BUFNfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvTWFwVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUluc3RyLmgiCisjaW5jbHVkZSAibGx2bS9JUi9DYWxsaW5nQ29udi5oIgorI2luY2x1ZGUgImxsdm0vTUMvTUNTeW1ib2wuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvRGVidWcuaCIKKyNpbmNsdWRlIDxhbGdvcml0aG0+CisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPHZlY3Rvcj4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBBc21QcmludGVyOworY2xhc3MgTUNFeHByOworY2xhc3MgTUNTdHJlYW1lcjsKK2NsYXNzIHJhd19vc3RyZWFtOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJJbmZvOworCisvLy8gXGJyaWVmIE1JLWxldmVsIHN0YWNrbWFwIG9wZXJhbmRzLgorLy8vCisvLy8gTUkgc3RhY2ttYXAgb3BlcmF0aW9ucyB0YWtlIHRoZSBmb3JtOgorLy8vIDxpZD4sIDxudW1CeXRlcz4sIGxpdmUgYXJncy4uLgorY2xhc3MgU3RhY2tNYXBPcGVycyB7CitwdWJsaWM6CisgIC8vLyBFbnVtZXJhdGUgdGhlIG1ldGEgb3BlcmFuZHMuCisgIGVudW0geyBJRFBvcywgTkJ5dGVzUG9zIH07CisKK3ByaXZhdGU6CisgIGNvbnN0IE1hY2hpbmVJbnN0ciogTUk7CisKK3B1YmxpYzoKKyAgZXhwbGljaXQgU3RhY2tNYXBPcGVycyhjb25zdCBNYWNoaW5lSW5zdHIgKk1JKTsKKworICAvLy8gUmV0dXJuIHRoZSBJRCBmb3IgdGhlIGdpdmVuIHN0YWNrbWFwCisgIHVpbnQ2NF90IGdldElEKCkgY29uc3QgeyByZXR1cm4gTUktPmdldE9wZXJhbmQoSURQb3MpLmdldEltbSgpOyB9CisKKyAgLy8vIFJldHVybiB0aGUgbnVtYmVyIG9mIHBhdGNoYWJsZSBieXRlcyB0aGUgZ2l2ZW4gc3RhY2ttYXAgc2hvdWxkIGVtaXQuCisgIHVpbnQzMl90IGdldE51bVBhdGNoQnl0ZXMoKSBjb25zdCB7CisgICAgcmV0dXJuIE1JLT5nZXRPcGVyYW5kKE5CeXRlc1BvcykuZ2V0SW1tKCk7CisgIH0KKworICAvLy8gR2V0IHRoZSBvcGVyYW5kIGluZGV4IG9mIHRoZSB2YXJpYWJsZSBsaXN0IG9mIG5vbi1hcmd1bWVudCBvcGVyYW5kcy4KKyAgLy8vIFRoZXNlIGhvbGQgdGhlICJsaXZlIHN0YXRlIi4KKyAgdW5zaWduZWQgZ2V0VmFySWR4KCkgY29uc3QgeworICAgIC8vIFNraXAgSUQsIG5TaGFkb3dCeXRlcy4KKyAgICByZXR1cm4gMjsKKyAgfQorfTsKKworLy8vIFxicmllZiBNSS1sZXZlbCBwYXRjaHBvaW50IG9wZXJhbmRzLgorLy8vCisvLy8gTUkgcGF0Y2hwb2ludCBvcGVyYXRpb25zIHRha2UgdGhlIGZvcm06CisvLy8gWzxkZWY+XSwgPGlkPiwgPG51bUJ5dGVzPiwgPHRhcmdldD4sIDxudW1BcmdzPiwgPGNjPiwgLi4uCisvLy8KKy8vLyBJUiBwYXRjaHBvaW50IGludHJpbnNpY3MgZG8gbm90IGhhdmUgdGhlIDxjYz4gb3BlcmFuZCBiZWNhdXNlIGNhbGxpbmcKKy8vLyBjb252ZW50aW9uIGlzIHBhcnQgb2YgdGhlIHN1YmNsYXNzIGRhdGEuCisvLy8KKy8vLyBTRCBwYXRjaHBvaW50IG5vZGVzIGRvIG5vdCBoYXZlIGEgZGVmIG9wZXJhbmQgYmVjYXVzZSBpdCBpcyBwYXJ0IG9mIHRoZQorLy8vIFNEVmFsdWUuCisvLy8KKy8vLyBQYXRjaHBvaW50cyBmb2xsb3dpbmcgdGhlIGFueXJlZ2NjIGNvbnZlbnRpb24gYXJlIGhhbmRsZWQgc3BlY2lhbGx5LiBGb3IKKy8vLyB0aGVzZSwgdGhlIHN0YWNrIG1hcCBhbHNvIHJlY29yZHMgdGhlIGxvY2F0aW9uIG9mIHRoZSByZXR1cm4gdmFsdWUgYW5kCisvLy8gYXJndW1lbnRzLgorY2xhc3MgUGF0Y2hQb2ludE9wZXJzIHsKK3B1YmxpYzoKKyAgLy8vIEVudW1lcmF0ZSB0aGUgbWV0YSBvcGVyYW5kcy4KKyAgZW51bSB7IElEUG9zLCBOQnl0ZXNQb3MsIFRhcmdldFBvcywgTkFyZ1BvcywgQ0NQb3MsIE1ldGFFbmQgfTsKKworcHJpdmF0ZToKKyAgY29uc3QgTWFjaGluZUluc3RyICpNSTsKKyAgYm9vbCBIYXNEZWY7CisKKyAgdW5zaWduZWQgZ2V0TWV0YUlkeCh1bnNpZ25lZCBQb3MgPSAwKSBjb25zdCB7CisgICAgYXNzZXJ0KFBvcyA8IE1ldGFFbmQgJiYgIk1ldGEgb3BlcmFuZCBpbmRleCBvdXQgb2YgcmFuZ2UuIik7CisgICAgcmV0dXJuIChIYXNEZWYgPyAxIDogMCkgKyBQb3M7CisgIH0KKworICBjb25zdCBNYWNoaW5lT3BlcmFuZCAmZ2V0TWV0YU9wZXIodW5zaWduZWQgUG9zKSBjb25zdCB7CisgICAgcmV0dXJuIE1JLT5nZXRPcGVyYW5kKGdldE1ldGFJZHgoUG9zKSk7CisgIH0KKworcHVibGljOgorICBleHBsaWNpdCBQYXRjaFBvaW50T3BlcnMoY29uc3QgTWFjaGluZUluc3RyICpNSSk7CisKKyAgYm9vbCBpc0FueVJlZygpIGNvbnN0IHsgcmV0dXJuIChnZXRDYWxsaW5nQ29udigpID09IENhbGxpbmdDb252OjpBbnlSZWcpOyB9CisgIGJvb2wgaGFzRGVmKCkgY29uc3QgeyByZXR1cm4gSGFzRGVmOyB9CisKKyAgLy8vIFJldHVybiB0aGUgSUQgZm9yIHRoZSBnaXZlbiBwYXRjaHBvaW50LgorICB1aW50NjRfdCBnZXRJRCgpIGNvbnN0IHsgcmV0dXJuIGdldE1ldGFPcGVyKElEUG9zKS5nZXRJbW0oKTsgfQorCisgIC8vLyBSZXR1cm4gdGhlIG51bWJlciBvZiBwYXRjaGFibGUgYnl0ZXMgdGhlIGdpdmVuIHBhdGNocG9pbnQgc2hvdWxkIGVtaXQuCisgIHVpbnQzMl90IGdldE51bVBhdGNoQnl0ZXMoKSBjb25zdCB7CisgICAgcmV0dXJuIGdldE1ldGFPcGVyKE5CeXRlc1BvcykuZ2V0SW1tKCk7CisgIH0KKworICAvLy8gUmV0dXJucyB0aGUgdGFyZ2V0IG9mIHRoZSB1bmRlcmx5aW5nIGNhbGwuCisgIGNvbnN0IE1hY2hpbmVPcGVyYW5kICZnZXRDYWxsVGFyZ2V0KCkgY29uc3QgeworICAgIHJldHVybiBnZXRNZXRhT3BlcihUYXJnZXRQb3MpOworICB9CisKKyAgLy8vIFJldHVybnMgdGhlIGNhbGxpbmcgY29udmVudGlvbgorICBDYWxsaW5nQ29udjo6SUQgZ2V0Q2FsbGluZ0NvbnYoKSBjb25zdCB7CisgICAgcmV0dXJuIGdldE1ldGFPcGVyKENDUG9zKS5nZXRJbW0oKTsKKyAgfQorCisgIHVuc2lnbmVkIGdldEFyZ0lkeCgpIGNvbnN0IHsgcmV0dXJuIGdldE1ldGFJZHgoKSArIE1ldGFFbmQ7IH0KKworICAvLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgY2FsbCBhcmd1bWVudHMKKyAgdWludDMyX3QgZ2V0TnVtQ2FsbEFyZ3MoKSBjb25zdCB7CisgICAgcmV0dXJuIE1JLT5nZXRPcGVyYW5kKGdldE1ldGFJZHgoTkFyZ1BvcykpLmdldEltbSgpOworICB9CisKKyAgLy8vIEdldCB0aGUgb3BlcmFuZCBpbmRleCBvZiB0aGUgdmFyaWFibGUgbGlzdCBvZiBub24tYXJndW1lbnQgb3BlcmFuZHMuCisgIC8vLyBUaGVzZSBob2xkIHRoZSAibGl2ZSBzdGF0ZSIuCisgIHVuc2lnbmVkIGdldFZhcklkeCgpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0TWV0YUlkeCgpICsgTWV0YUVuZCArIGdldE51bUNhbGxBcmdzKCk7CisgIH0KKworICAvLy8gR2V0IHRoZSBpbmRleCBhdCB3aGljaCBzdGFjayBtYXAgbG9jYXRpb25zIHdpbGwgYmUgcmVjb3JkZWQuCisgIC8vLyBBcmd1bWVudHMgYXJlIG5vdCByZWNvcmRlZCB1bmxlc3MgdGhlIGFueXJlZ2NjIGNvbnZlbnRpb24gaXMgdXNlZC4KKyAgdW5zaWduZWQgZ2V0U3RhY2tNYXBTdGFydElkeCgpIGNvbnN0IHsKKyAgICBpZiAoaXNBbnlSZWcoKSkKKyAgICAgIHJldHVybiBnZXRBcmdJZHgoKTsKKyAgICByZXR1cm4gZ2V0VmFySWR4KCk7CisgIH0KKworICAvLy8gXGJyaWVmIEdldCB0aGUgbmV4dCBzY3JhdGNoIHJlZ2lzdGVyIG9wZXJhbmQgaW5kZXguCisgIHVuc2lnbmVkIGdldE5leHRTY3JhdGNoSWR4KHVuc2lnbmVkIFN0YXJ0SWR4ID0gMCkgY29uc3Q7Cit9OworCisvLy8gTUktbGV2ZWwgU3RhdGVwb2ludCBvcGVyYW5kcworLy8vCisvLy8gU3RhdGVwb2ludCBvcGVyYW5kcyB0YWtlIHRoZSBmb3JtOgorLy8vICAgPGlkPiwgPG51bSBwYXRjaCBieXRlcyA+LCA8bnVtIGNhbGwgYXJndW1lbnRzPiwgPGNhbGwgdGFyZ2V0PiwKKy8vLyAgIFtjYWxsIGFyZ3VtZW50cy4uLl0sCisvLy8gICA8U3RhY2tNYXBzOjpDb25zdGFudE9wPiwgPGNhbGxpbmcgY29udmVudGlvbj4sCisvLy8gICA8U3RhY2tNYXBzOjpDb25zdGFudE9wPiwgPHN0YXRlcG9pbnQgZmxhZ3M+LAorLy8vICAgPFN0YWNrTWFwczo6Q29uc3RhbnRPcD4sIDxudW0gZGVvcHQgYXJncz4sIFtkZW9wdCBhcmdzLi4uXSwKKy8vLyAgIDxnYyBiYXNlL2Rlcml2ZWQgcGFpcnMuLi4+IDxnYyBhbGxvY2FzLi4uPgorLy8vIE5vdGUgdGhhdCB0aGUgbGFzdCB0d28gc2V0cyBvZiBhcmd1bWVudHMgYXJlIG5vdCBjdXJyZW50bHkgbGVuZ3RoCisvLy8gICBwcmVmaXhlZC4KK2NsYXNzIFN0YXRlcG9pbnRPcGVycyB7CisgIC8vIFRPRE86OiB3ZSBzaG91bGQgY2hhbmdlIHRoZSBTVEFURVBPSU5UIHJlcHJlc2VudGF0aW9uIHNvIHRoYXQgQ0MgYW5kCisgIC8vIEZsYWdzIHNob3VsZCBiZSBwYXJ0IG9mIG1ldGEgb3BlcmFuZHMsIHdpdGggYXJncyBhbmQgZGVvcHQgb3BlcmFuZHMsIGFuZAorICAvLyBnYyBvcGVyYW5kcyBhbGwgcHJlZml4ZWQgYnkgdGhlaXIgbGVuZ3RoIGFuZCBhIHR5cGUgY29kZS4gVGhpcyB3b3VsZCBiZQorICAvLyBtdWNoIG1vcmUgY29uc2lzdGVudC4gCitwdWJsaWM6CisgIC8vIFRoZXNlIHZhbHVlcyBhcmUgYWJvb2x1dGUgb2Zmc2V0cyBpbnRvIHRoZSBvcGVyYW5kcyBvZiB0aGUgc3RhdGVwb2ludAorICAvLyBpbnN0cnVjdGlvbi4KKyAgZW51bSB7IElEUG9zLCBOQnl0ZXNQb3MsIE5DYWxsQXJnc1BvcywgQ2FsbFRhcmdldFBvcywgTWV0YUVuZCB9OworCisgIC8vIFRoZXNlIHZhbHVlcyBhcmUgcmVsYXRpdmUgb2ZmZXN0cyBmcm9tIHRoZSBzdGFydCBvZiB0aGUgc3RhdGVwb2ludCBtZXRhCisgIC8vIGFyZ3VtZW50cyAoaS5lLiB0aGUgZW5kIG9mIHRoZSBjYWxsIGFyZ3VtZW50cykuCisgIGVudW0geyBDQ09mZnNldCA9IDEsIEZsYWdzT2Zmc2V0ID0gMywgTnVtRGVvcHRPcGVyYW5kc09mZnNldCA9IDUgfTsKKworICBleHBsaWNpdCBTdGF0ZXBvaW50T3BlcnMoY29uc3QgTWFjaGluZUluc3RyICpNSSkgOiBNSShNSSkge30KKworICAvLy8gR2V0IHN0YXJ0aW5nIGluZGV4IG9mIG5vbiBjYWxsIHJlbGF0ZWQgYXJndW1lbnRzCisgIC8vLyAoY2FsbGluZyBjb252ZW50aW9uLCBzdGF0ZXBvaW50IGZsYWdzLCB2bSBzdGF0ZSBhbmQgZ2Mgc3RhdGUpLgorICB1bnNpZ25lZCBnZXRWYXJJZHgoKSBjb25zdCB7CisgICAgcmV0dXJuIE1JLT5nZXRPcGVyYW5kKE5DYWxsQXJnc1BvcykuZ2V0SW1tKCkgKyBNZXRhRW5kOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgSUQgZm9yIHRoZSBnaXZlbiBzdGF0ZXBvaW50LgorICB1aW50NjRfdCBnZXRJRCgpIGNvbnN0IHsgcmV0dXJuIE1JLT5nZXRPcGVyYW5kKElEUG9zKS5nZXRJbW0oKTsgfQorCisgIC8vLyBSZXR1cm4gdGhlIG51bWJlciBvZiBwYXRjaGFibGUgYnl0ZXMgdGhlIGdpdmVuIHN0YXRlcG9pbnQgc2hvdWxkIGVtaXQuCisgIHVpbnQzMl90IGdldE51bVBhdGNoQnl0ZXMoKSBjb25zdCB7CisgICAgcmV0dXJuIE1JLT5nZXRPcGVyYW5kKE5CeXRlc1BvcykuZ2V0SW1tKCk7CisgIH0KKworICAvLy8gUmV0dXJucyB0aGUgdGFyZ2V0IG9mIHRoZSB1bmRlcmx5aW5nIGNhbGwuCisgIGNvbnN0IE1hY2hpbmVPcGVyYW5kICZnZXRDYWxsVGFyZ2V0KCkgY29uc3QgeworICAgIHJldHVybiBNSS0+Z2V0T3BlcmFuZChDYWxsVGFyZ2V0UG9zKTsKKyAgfQorCitwcml2YXRlOgorICBjb25zdCBNYWNoaW5lSW5zdHIgKk1JOworfTsKKworY2xhc3MgU3RhY2tNYXBzIHsKK3B1YmxpYzoKKyAgc3RydWN0IExvY2F0aW9uIHsKKyAgICBlbnVtIExvY2F0aW9uVHlwZSB7CisgICAgICBVbnByb2Nlc3NlZCwKKyAgICAgIFJlZ2lzdGVyLAorICAgICAgRGlyZWN0LAorICAgICAgSW5kaXJlY3QsCisgICAgICBDb25zdGFudCwKKyAgICAgIENvbnN0YW50SW5kZXgKKyAgICB9OworICAgIExvY2F0aW9uVHlwZSBUeXBlID0gVW5wcm9jZXNzZWQ7CisgICAgdW5zaWduZWQgU2l6ZSA9IDA7CisgICAgdW5zaWduZWQgUmVnID0gMDsKKyAgICBpbnQ2NF90IE9mZnNldCA9IDA7CisKKyAgICBMb2NhdGlvbigpID0gZGVmYXVsdDsKKyAgICBMb2NhdGlvbihMb2NhdGlvblR5cGUgVHlwZSwgdW5zaWduZWQgU2l6ZSwgdW5zaWduZWQgUmVnLCBpbnQ2NF90IE9mZnNldCkKKyAgICAgICAgOiBUeXBlKFR5cGUpLCBTaXplKFNpemUpLCBSZWcoUmVnKSwgT2Zmc2V0KE9mZnNldCkge30KKyAgfTsKKworICBzdHJ1Y3QgTGl2ZU91dFJlZyB7CisgICAgdW5zaWduZWQgc2hvcnQgUmVnID0gMDsKKyAgICB1bnNpZ25lZCBzaG9ydCBEd2FyZlJlZ051bSA9IDA7CisgICAgdW5zaWduZWQgc2hvcnQgU2l6ZSA9IDA7CisKKyAgICBMaXZlT3V0UmVnKCkgPSBkZWZhdWx0OworICAgIExpdmVPdXRSZWcodW5zaWduZWQgc2hvcnQgUmVnLCB1bnNpZ25lZCBzaG9ydCBEd2FyZlJlZ051bSwKKyAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IFNpemUpCisgICAgICAgIDogUmVnKFJlZyksIER3YXJmUmVnTnVtKER3YXJmUmVnTnVtKSwgU2l6ZShTaXplKSB7fQorICB9OworCisgIC8vIE9wVHlwZXMgYXJlIHVzZWQgdG8gZW5jb2RlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBmb2xsb3dpbmcgbG9naWNhbAorICAvLyBvcGVyYW5kICh3aGljaCBtYXkgY29uc2lzdCBvZiBzZXZlcmFsIE1hY2hpbmVPcGVyYW5kcykgZm9yIHRoZQorICAvLyBPcFBhcnNlci4KKyAgdXNpbmcgT3BUeXBlID0gZW51bSB7IERpcmVjdE1lbVJlZk9wLCBJbmRpcmVjdE1lbVJlZk9wLCBDb25zdGFudE9wIH07CisKKyAgU3RhY2tNYXBzKEFzbVByaW50ZXIgJkFQKTsKKworICB2b2lkIHJlc2V0KCkgeworICAgIENTSW5mb3MuY2xlYXIoKTsKKyAgICBDb25zdFBvb2wuY2xlYXIoKTsKKyAgICBGbkluZm9zLmNsZWFyKCk7CisgIH0KKworICAvLy8gXGJyaWVmIEdlbmVyYXRlIGEgc3RhY2ttYXAgcmVjb3JkIGZvciBhIHN0YWNrbWFwIGluc3RydWN0aW9uLgorICAvLy8KKyAgLy8vIE1JIG11c3QgYmUgYSByYXcgU1RBQ0tNQVAsIG5vdCBhIFBBVENIUE9JTlQuCisgIHZvaWQgcmVjb3JkU3RhY2tNYXAoY29uc3QgTWFjaGluZUluc3RyICZNSSk7CisKKyAgLy8vIFxicmllZiBHZW5lcmF0ZSBhIHN0YWNrbWFwIHJlY29yZCBmb3IgYSBwYXRjaHBvaW50IGluc3RydWN0aW9uLgorICB2b2lkIHJlY29yZFBhdGNoUG9pbnQoY29uc3QgTWFjaGluZUluc3RyICZNSSk7CisKKyAgLy8vIFxicmllZiBHZW5lcmF0ZSBhIHN0YWNrbWFwIHJlY29yZCBmb3IgYSBzdGF0ZXBvaW50IGluc3RydWN0aW9uLgorICB2b2lkIHJlY29yZFN0YXRlcG9pbnQoY29uc3QgTWFjaGluZUluc3RyICZNSSk7CisKKyAgLy8vIElmIHRoZXJlIGlzIGFueSBzdGFjayBtYXAgZGF0YSwgY3JlYXRlIGEgc3RhY2sgbWFwIHNlY3Rpb24gYW5kIHNlcmlhbGl6ZQorICAvLy8gdGhlIG1hcCBpbmZvIGludG8gaXQuIFRoaXMgY2xlYXJzIHRoZSBzdGFjayBtYXAgZGF0YSBzdHJ1Y3R1cmVzCisgIC8vLyBhZnRlcndhcmRzLgorICB2b2lkIHNlcmlhbGl6ZVRvU3RhY2tNYXBTZWN0aW9uKCk7CisKK3ByaXZhdGU6CisgIHN0YXRpYyBjb25zdCBjaGFyICpXU01QOworCisgIHVzaW5nIExvY2F0aW9uVmVjID0gU21hbGxWZWN0b3I8TG9jYXRpb24sIDg+OworICB1c2luZyBMaXZlT3V0VmVjID0gU21hbGxWZWN0b3I8TGl2ZU91dFJlZywgOD47CisgIHVzaW5nIENvbnN0YW50UG9vbCA9IE1hcFZlY3Rvcjx1aW50NjRfdCwgdWludDY0X3Q+OworCisgIHN0cnVjdCBGdW5jdGlvbkluZm8geworICAgIHVpbnQ2NF90IFN0YWNrU2l6ZSA9IDA7CisgICAgdWludDY0X3QgUmVjb3JkQ291bnQgPSAxOworCisgICAgRnVuY3Rpb25JbmZvKCkgPSBkZWZhdWx0OworICAgIGV4cGxpY2l0IEZ1bmN0aW9uSW5mbyh1aW50NjRfdCBTdGFja1NpemUpIDogU3RhY2tTaXplKFN0YWNrU2l6ZSkge30KKyAgfTsKKworICBzdHJ1Y3QgQ2FsbHNpdGVJbmZvIHsKKyAgICBjb25zdCBNQ0V4cHIgKkNTT2Zmc2V0RXhwciA9IG51bGxwdHI7CisgICAgdWludDY0X3QgSUQgPSAwOworICAgIExvY2F0aW9uVmVjIExvY2F0aW9uczsKKyAgICBMaXZlT3V0VmVjIExpdmVPdXRzOworCisgICAgQ2FsbHNpdGVJbmZvKCkgPSBkZWZhdWx0OworICAgIENhbGxzaXRlSW5mbyhjb25zdCBNQ0V4cHIgKkNTT2Zmc2V0RXhwciwgdWludDY0X3QgSUQsCisgICAgICAgICAgICAgICAgIExvY2F0aW9uVmVjICYmTG9jYXRpb25zLCBMaXZlT3V0VmVjICYmTGl2ZU91dHMpCisgICAgICAgIDogQ1NPZmZzZXRFeHByKENTT2Zmc2V0RXhwciksIElEKElEKSwgTG9jYXRpb25zKHN0ZDo6bW92ZShMb2NhdGlvbnMpKSwKKyAgICAgICAgICBMaXZlT3V0cyhzdGQ6Om1vdmUoTGl2ZU91dHMpKSB7fQorICB9OworCisgIHVzaW5nIEZuSW5mb01hcCA9IE1hcFZlY3Rvcjxjb25zdCBNQ1N5bWJvbCAqLCBGdW5jdGlvbkluZm8+OworICB1c2luZyBDYWxsc2l0ZUluZm9MaXN0ID0gc3RkOjp2ZWN0b3I8Q2FsbHNpdGVJbmZvPjsKKworICBBc21QcmludGVyICZBUDsKKyAgQ2FsbHNpdGVJbmZvTGlzdCBDU0luZm9zOworICBDb25zdGFudFBvb2wgQ29uc3RQb29sOworICBGbkluZm9NYXAgRm5JbmZvczsKKworICBNYWNoaW5lSW5zdHI6OmNvbnN0X21vcF9pdGVyYXRvcgorICBwYXJzZU9wZXJhbmQoTWFjaGluZUluc3RyOjpjb25zdF9tb3BfaXRlcmF0b3IgTU9JLAorICAgICAgICAgICAgICAgTWFjaGluZUluc3RyOjpjb25zdF9tb3BfaXRlcmF0b3IgTU9FLCBMb2NhdGlvblZlYyAmTG9jcywKKyAgICAgICAgICAgICAgIExpdmVPdXRWZWMgJkxpdmVPdXRzKSBjb25zdDsKKworICAvLy8gXGJyaWVmIENyZWF0ZSBhIGxpdmUtb3V0IHJlZ2lzdGVyIHJlY29yZCBmb3IgdGhlIGdpdmVuIHJlZ2lzdGVyIEBwIFJlZy4KKyAgTGl2ZU91dFJlZyBjcmVhdGVMaXZlT3V0UmVnKHVuc2lnbmVkIFJlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJKSBjb25zdDsKKworICAvLy8gXGJyaWVmIFBhcnNlIHRoZSByZWdpc3RlciBsaXZlLW91dCBtYXNrIGFuZCByZXR1cm4gYSB2ZWN0b3Igb2YgbGl2ZS1vdXQKKyAgLy8vIHJlZ2lzdGVycyB0aGF0IG5lZWQgdG8gYmUgcmVjb3JkZWQgaW4gdGhlIHN0YWNrbWFwLgorICBMaXZlT3V0VmVjIHBhcnNlUmVnaXN0ZXJMaXZlT3V0TWFzayhjb25zdCB1aW50MzJfdCAqTWFzaykgY29uc3Q7CisKKyAgLy8vIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBieSB0aGUgTUMgbG93ZXJpbmcgY29kZSBfaW1tZWRpYXRlbHlfIGJlZm9yZQorICAvLy8gbG93ZXJpbmcgdGhlIE1JIHRvIGFuIE1DSW5zdC4gSXQgcmVjb3JkcyB3aGVyZSB0aGUgb3BlcmFuZHMgZm9yIHRoZQorICAvLy8gaW5zdHJ1Y3Rpb24gYXJlIHN0b3JlZCwgYW5kIG91dHB1dHMgYSBsYWJlbCB0byByZWNvcmQgdGhlIG9mZnNldCBvZgorICAvLy8gdGhlIGNhbGwgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHRleHQgc2VjdGlvbi4gSW4gc3BlY2lhbCBjYXNlcyAoZS5nLiBBbnlSZWcKKyAgLy8vIGNhbGxpbmcgY29udmVudGlvbikgdGhlIHJldHVybiByZWdpc3RlciBpcyBhbHNvIHJlY29yZGVkIGlmIHJlcXVlc3RlZC4KKyAgdm9pZCByZWNvcmRTdGFja01hcE9wZXJzKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUksIHVpbnQ2NF90IElELAorICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUluc3RyOjpjb25zdF9tb3BfaXRlcmF0b3IgTU9JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUluc3RyOjpjb25zdF9tb3BfaXRlcmF0b3IgTU9FLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCByZWNvcmRSZXN1bHQgPSBmYWxzZSk7CisKKyAgLy8vIFxicmllZiBFbWl0IHRoZSBzdGFja21hcCBoZWFkZXIuCisgIHZvaWQgZW1pdFN0YWNrbWFwSGVhZGVyKE1DU3RyZWFtZXIgJk9TKTsKKworICAvLy8gXGJyaWVmIEVtaXQgdGhlIGZ1bmN0aW9uIGZyYW1lIHJlY29yZCBmb3IgZWFjaCBmdW5jdGlvbi4KKyAgdm9pZCBlbWl0RnVuY3Rpb25GcmFtZVJlY29yZHMoTUNTdHJlYW1lciAmT1MpOworCisgIC8vLyBcYnJpZWYgRW1pdCB0aGUgY29uc3RhbnQgcG9vbC4KKyAgdm9pZCBlbWl0Q29uc3RhbnRQb29sRW50cmllcyhNQ1N0cmVhbWVyICZPUyk7CisKKyAgLy8vIFxicmllZiBFbWl0IHRoZSBjYWxsc2l0ZSBpbmZvIGZvciBlYWNoIHN0YWNrbWFwL3BhdGNocG9pbnQgaW50cmluc2ljIGNhbGwuCisgIHZvaWQgZW1pdENhbGxzaXRlRW50cmllcyhNQ1N0cmVhbWVyICZPUyk7CisKKyAgdm9pZCBwcmludChyYXdfb3N0cmVhbSAmT1MpOworICB2b2lkIGRlYnVnKCkgeyBwcmludChkYmdzKCkpOyB9Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1NUQUNLTUFQU19ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vU3RhY2tQcm90ZWN0b3IuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9TdGFja1Byb3RlY3Rvci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcyZGUyMTIKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vU3RhY2tQcm90ZWN0b3IuaApAQCAtMCwwICsxLDEzOCBAQAorLy89PT0tIFN0YWNrUHJvdGVjdG9yLmggLSBTdGFjayBQcm90ZWN0b3IgSW5zZXJ0aW9uIC0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIHBhc3MgaW5zZXJ0cyBzdGFjayBwcm90ZWN0b3JzIGludG8gZnVuY3Rpb25zIHdoaWNoIG5lZWQgdGhlbS4gQSB2YXJpYWJsZQorLy8gd2l0aCBhIHJhbmRvbSB2YWx1ZSBpbiBpdCBpcyBzdG9yZWQgb250byB0aGUgc3RhY2sgYmVmb3JlIHRoZSBsb2NhbCB2YXJpYWJsZXMKKy8vIGFyZSBhbGxvY2F0ZWQuIFVwb24gZXhpdGluZyB0aGUgYmxvY2ssIHRoZSBzdG9yZWQgdmFsdWUgaXMgY2hlY2tlZC4gSWYgaXQncworLy8gY2hhbmdlZCwgdGhlbiB0aGVyZSB3YXMgc29tZSBzb3J0IG9mIHZpb2xhdGlvbiBhbmQgdGhlIHByb2dyYW0gYWJvcnRzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1NUQUNLUFJPVEVDVE9SX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1NUQUNLUFJPVEVDVE9SX0gKKworI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsUHRyU2V0LmgiCisjaW5jbHVkZSAibGx2bS9BRFQvVHJpcGxlLmgiCisjaW5jbHVkZSAibGx2bS9JUi9JbnN0cnVjdGlvbnMuaCIKKyNpbmNsdWRlICJsbHZtL0lSL1ZhbHVlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9QYXNzLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgQmFzaWNCbG9jazsKK2NsYXNzIERvbWluYXRvclRyZWU7CitjbGFzcyBGdW5jdGlvbjsKK2NsYXNzIEluc3RydWN0aW9uOworY2xhc3MgTW9kdWxlOworY2xhc3MgVGFyZ2V0TG93ZXJpbmdCYXNlOworY2xhc3MgVGFyZ2V0TWFjaGluZTsKK2NsYXNzIFR5cGU7CisKK2NsYXNzIFN0YWNrUHJvdGVjdG9yIDogcHVibGljIEZ1bmN0aW9uUGFzcyB7CitwdWJsaWM6CisgIC8vLyBTU1BMYXlvdXRLaW5kLiAgU3RhY2sgU21hc2hpbmcgUHJvdGVjdGlvbiAoU1NQKSBydWxlcyByZXF1aXJlIHRoYXQKKyAgLy8vIHZ1bG5lcmFibGUgc3RhY2sgYWxsb2NhdGlvbnMgYXJlIGxvY2F0ZWQgY2xvc2UgdGhlIHN0YWNrIHByb3RlY3Rvci4KKyAgZW51bSBTU1BMYXlvdXRLaW5kIHsKKyAgICBTU1BMS19Ob25lLCAgICAgICAvLy88IERpZCBub3QgdHJpZ2dlciBhIHN0YWNrIHByb3RlY3Rvci4gIE5vIGVmZmVjdCBvbiBkYXRhCisgICAgICAgICAgICAgICAgICAgICAgLy8vPCBsYXlvdXQuCisgICAgU1NQTEtfTGFyZ2VBcnJheSwgLy8vPCBBcnJheSBvciBuZXN0ZWQgYXJyYXkgPj0gU1NQLWJ1ZmZlci1zaXplLiAgQ2xvc2VzdAorICAgICAgICAgICAgICAgICAgICAgIC8vLzwgdG8gdGhlIHN0YWNrIHByb3RlY3Rvci4KKyAgICBTU1BMS19TbWFsbEFycmF5LCAvLy88IEFycmF5IG9yIG5lc3RlZCBhcnJheSA8IFNTUC1idWZmZXItc2l6ZS4gMm5kIGNsb3Nlc3QKKyAgICAgICAgICAgICAgICAgICAgICAvLy88IHRvIHRoZSBzdGFjayBwcm90ZWN0b3IuCisgICAgU1NQTEtfQWRkck9mICAgICAgLy8vPCBUaGUgYWRkcmVzcyBvZiB0aGlzIGFsbG9jYXRpb24gaXMgZXhwb3NlZCBhbmQKKyAgICAgICAgICAgICAgICAgICAgICAvLy88IHRyaWdnZXJlZCBwcm90ZWN0aW9uLiAgM3JkIGNsb3Nlc3QgdG8gdGhlIHByb3RlY3Rvci4KKyAgfTsKKworICAvLy8gQSBtYXBwaW5nIG9mIEFsbG9jYUluc3RzIHRvIHRoZWlyIHJlcXVpcmVkIFNTUCBsYXlvdXQuCisgIHVzaW5nIFNTUExheW91dE1hcCA9IFZhbHVlTWFwPGNvbnN0IEFsbG9jYUluc3QgKiwgU1NQTGF5b3V0S2luZD47CisKK3ByaXZhdGU6CisgIGNvbnN0IFRhcmdldE1hY2hpbmUgKlRNID0gbnVsbHB0cjsKKworICAvLy8gVExJIC0gS2VlcCBhIHBvaW50ZXIgb2YgYSBUYXJnZXRMb3dlcmluZyB0byBjb25zdWx0IGZvciBkZXRlcm1pbmluZworICAvLy8gdGFyZ2V0IHR5cGUgc2l6ZXMuCisgIGNvbnN0IFRhcmdldExvd2VyaW5nQmFzZSAqVExJID0gbnVsbHB0cjsKKyAgVHJpcGxlIFRyaXA7CisKKyAgRnVuY3Rpb24gKkY7CisgIE1vZHVsZSAqTTsKKworICBEb21pbmF0b3JUcmVlICpEVDsKKworICAvLy8gTGF5b3V0IC0gTWFwcGluZyBvZiBhbGxvY2F0aW9ucyB0byB0aGUgcmVxdWlyZWQgU1NQTGF5b3V0S2luZC4KKyAgLy8vIFN0YWNrUHJvdGVjdG9yIGFuYWx5c2lzIHdpbGwgdXBkYXRlIHRoaXMgbWFwIHdoZW4gZGV0ZXJtaW5pbmcgaWYgYW4KKyAgLy8vIEFsbG9jYUluc3QgdHJpZ2dlcnMgYSBzdGFjayBwcm90ZWN0b3IuCisgIFNTUExheW91dE1hcCBMYXlvdXQ7CisKKyAgLy8vIFxicmllZiBUaGUgbWluaW11bSBzaXplIG9mIGJ1ZmZlcnMgdGhhdCB3aWxsIHJlY2VpdmUgc3RhY2sgc21hc2hpbmcKKyAgLy8vIHByb3RlY3Rpb24gd2hlbiAtZnN0YWNrLXByb3RlY3Rpb24gaXMgdXNlZC4KKyAgdW5zaWduZWQgU1NQQnVmZmVyU2l6ZSA9IDA7CisKKyAgLy8vIFZpc2l0ZWRQSElzIC0gVGhlIHNldCBvZiBQSEkgbm9kZXMgdmlzaXRlZCB3aGVuIGRldGVybWluaW5nCisgIC8vLyBpZiBhIHZhcmlhYmxlJ3MgcmVmZXJlbmNlIGhhcyBiZWVuIHRha2VuLiAgVGhpcyBzZXQKKyAgLy8vIGlzIG1haW50YWluZWQgdG8gZW5zdXJlIHdlIGRvbid0IHZpc2l0IHRoZSBzYW1lIFBISSBub2RlIG11bHRpcGxlCisgIC8vLyB0aW1lcy4KKyAgU21hbGxQdHJTZXQ8Y29uc3QgUEhJTm9kZSAqLCAxNj4gVmlzaXRlZFBISXM7CisKKyAgLy8gQSBwcm9sb2d1ZSBpcyBnZW5lcmF0ZWQuCisgIGJvb2wgSGFzUHJvbG9ndWUgPSBmYWxzZTsKKworICAvLyBJUiBjaGVja2luZyBjb2RlIGlzIGdlbmVyYXRlZC4KKyAgYm9vbCBIYXNJUkNoZWNrID0gZmFsc2U7CisKKyAgLy8vIEluc2VydFN0YWNrUHJvdGVjdG9ycyAtIEluc2VydCBjb2RlIGludG8gdGhlIHByb2xvZ3VlIGFuZCBlcGlsb2d1ZSBvZgorICAvLy8gdGhlIGZ1bmN0aW9uLgorICAvLy8KKyAgLy8vICAtIFRoZSBwcm9sb2d1ZSBjb2RlIGxvYWRzIGFuZCBzdG9yZXMgdGhlIHN0YWNrIGd1YXJkIG9udG8gdGhlIHN0YWNrLgorICAvLy8gIC0gVGhlIGVwaWxvZ3VlIGNoZWNrcyB0aGUgdmFsdWUgc3RvcmVkIGluIHRoZSBwcm9sb2d1ZSBhZ2FpbnN0IHRoZQorICAvLy8gICAgb3JpZ2luYWwgdmFsdWUuIEl0IGNhbGxzIF9fc3RhY2tfY2hrX2ZhaWwgaWYgdGhleSBkaWZmZXIuCisgIGJvb2wgSW5zZXJ0U3RhY2tQcm90ZWN0b3JzKCk7CisKKyAgLy8vIENyZWF0ZUZhaWxCQiAtIENyZWF0ZSBhIGJhc2ljIGJsb2NrIHRvIGp1bXAgdG8gd2hlbiB0aGUgc3RhY2sgcHJvdGVjdG9yCisgIC8vLyBjaGVjayBmYWlscy4KKyAgQmFzaWNCbG9jayAqQ3JlYXRlRmFpbEJCKCk7CisKKyAgLy8vIENvbnRhaW5zUHJvdGVjdGFibGVBcnJheSAtIENoZWNrIHdoZXRoZXIgdGhlIHR5cGUgZWl0aGVyIGlzIGFuIGFycmF5IG9yCisgIC8vLyBjb250YWlucyBhbiBhcnJheSBvZiBzdWZmaWNpZW50IHNpemUgc28gdGhhdCB3ZSBuZWVkIHN0YWNrIHByb3RlY3RvcnMKKyAgLy8vIGZvciBpdC4KKyAgLy8vIFxwYXJhbSBbb3V0XSBJc0xhcmdlIGlzIHNldCB0byB0cnVlIGlmIGEgcHJvdGVjdGFibGUgYXJyYXkgaXMgZm91bmQgYW5kCisgIC8vLyBpdCBpcyAibGFyZ2UiICggPj0gc3NwLWJ1ZmZlci1zaXplKS4gIEluIHRoZSBjYXNlIG9mIGEgc3RydWN0dXJlIHdpdGgKKyAgLy8vIG11bHRpcGxlIGFycmF5cywgdGhpcyBnZXRzIHNldCBpZiBhbnkgb2YgdGhlbSBpcyBsYXJnZS4KKyAgYm9vbCBDb250YWluc1Byb3RlY3RhYmxlQXJyYXkoVHlwZSAqVHksIGJvb2wgJklzTGFyZ2UsIGJvb2wgU3Ryb25nID0gZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgSW5TdHJ1Y3QgPSBmYWxzZSkgY29uc3Q7CisKKyAgLy8vIFxicmllZiBDaGVjayB3aGV0aGVyIGEgc3RhY2sgYWxsb2NhdGlvbiBoYXMgaXRzIGFkZHJlc3MgdGFrZW4uCisgIGJvb2wgSGFzQWRkcmVzc1Rha2VuKGNvbnN0IEluc3RydWN0aW9uICpBSSk7CisKKyAgLy8vIFJlcXVpcmVzU3RhY2tQcm90ZWN0b3IgLSBDaGVjayB3aGV0aGVyIG9yIG5vdCB0aGlzIGZ1bmN0aW9uIG5lZWRzIGEKKyAgLy8vIHN0YWNrIHByb3RlY3RvciBiYXNlZCB1cG9uIHRoZSBzdGFjayBwcm90ZWN0b3IgbGV2ZWwuCisgIGJvb2wgUmVxdWlyZXNTdGFja1Byb3RlY3RvcigpOworCitwdWJsaWM6CisgIHN0YXRpYyBjaGFyIElEOyAvLyBQYXNzIGlkZW50aWZpY2F0aW9uLCByZXBsYWNlbWVudCBmb3IgdHlwZWlkLgorCisgIFN0YWNrUHJvdGVjdG9yKCkgOiBGdW5jdGlvblBhc3MoSUQpLCBTU1BCdWZmZXJTaXplKDgpIHsKKyAgICBpbml0aWFsaXplU3RhY2tQcm90ZWN0b3JQYXNzKCpQYXNzUmVnaXN0cnk6OmdldFBhc3NSZWdpc3RyeSgpKTsKKyAgfQorCisgIHZvaWQgZ2V0QW5hbHlzaXNVc2FnZShBbmFseXNpc1VzYWdlICZBVSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgU1NQTGF5b3V0S2luZCBnZXRTU1BMYXlvdXQoY29uc3QgQWxsb2NhSW5zdCAqQUkpIGNvbnN0OworCisgIC8vIFJldHVybiB0cnVlIGlmIFN0YWNrUHJvdGVjdG9yIGlzIHN1cHBvc2VkIHRvIGJlIGhhbmRsZWQgYnkgU2VsZWN0aW9uREFHLgorICBib29sIHNob3VsZEVtaXRTRENoZWNrKGNvbnN0IEJhc2ljQmxvY2sgJkJCKSBjb25zdDsKKworICB2b2lkIGFkanVzdEZvckNvbG9yaW5nKGNvbnN0IEFsbG9jYUluc3QgKkZyb20sIGNvbnN0IEFsbG9jYUluc3QgKlRvKTsKKworICBib29sIHJ1bk9uRnVuY3Rpb24oRnVuY3Rpb24gJkZuKSBvdmVycmlkZTsKK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fU1RBQ0tQUk9URUNUT1JfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhaWxEdXBsaWNhdG9yLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vVGFpbER1cGxpY2F0b3IuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZTY1NjJjCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhaWxEdXBsaWNhdG9yLmgKQEAgLTAsMCArMSwxMjggQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vVGFpbER1cGxpY2F0b3IuaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlZmluZXMgdGhlIFRhaWxEdXBsaWNhdG9yIGNsYXNzLiBVc2VkIGJ5IHRoZQorLy8gVGFpbER1cGxpY2F0aW9uIHBhc3MsIGFuZCBNYWNoaW5lQmxvY2tQbGFjZW1lbnQuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fVEFJTERVUExJQ0FUT1JfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fVEFJTERVUExJQ0FUT1JfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9EZW5zZVNldC5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NldFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1RhcmdldEluc3RySW5mby5oIgorI2luY2x1ZGUgPHV0aWxpdHk+CisjaW5jbHVkZSA8dmVjdG9yPgorCituYW1lc3BhY2UgbGx2bSB7CisKK2NsYXNzIE1hY2hpbmVCYXNpY0Jsb2NrOworY2xhc3MgTWFjaGluZUJyYW5jaFByb2JhYmlsaXR5SW5mbzsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIE1hY2hpbmVJbnN0cjsKK2NsYXNzIE1hY2hpbmVNb2R1bGVJbmZvOworY2xhc3MgTWFjaGluZVJlZ2lzdGVySW5mbzsKK2NsYXNzIFRhcmdldFJlZ2lzdGVySW5mbzsKKworLy8vIFV0aWxpdHkgY2xhc3MgdG8gcGVyZm9ybSB0YWlsIGR1cGxpY2F0aW9uLgorY2xhc3MgVGFpbER1cGxpY2F0b3IgeworICBjb25zdCBUYXJnZXRJbnN0ckluZm8gKlRJSTsKKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkk7CisgIGNvbnN0IE1hY2hpbmVCcmFuY2hQcm9iYWJpbGl0eUluZm8gKk1CUEk7CisgIGNvbnN0IE1hY2hpbmVNb2R1bGVJbmZvICpNTUk7CisgIE1hY2hpbmVSZWdpc3RlckluZm8gKk1SSTsKKyAgTWFjaGluZUZ1bmN0aW9uICpNRjsKKyAgYm9vbCBQcmVSZWdBbGxvYzsKKyAgYm9vbCBMYXlvdXRNb2RlOworICB1bnNpZ25lZCBUYWlsRHVwU2l6ZTsKKworICAvLyBBIGxpc3Qgb2YgdmlydHVhbCByZWdpc3RlcnMgZm9yIHdoaWNoIHRvIHVwZGF0ZSBTU0EgZm9ybS4KKyAgU21hbGxWZWN0b3I8dW5zaWduZWQsIDE2PiBTU0FVcGRhdGVWUnM7CisKKyAgLy8gRm9yIGVhY2ggdmlydHVhbCByZWdpc3RlciBpbiBTU0FVcGRhdGVWYWxzIGtlZXAgYSBsaXN0IG9mIHNvdXJjZSB2aXJ0dWFsCisgIC8vIHJlZ2lzdGVycy4KKyAgdXNpbmcgQXZhaWxhYmxlVmFsc1R5ID0gc3RkOjp2ZWN0b3I8c3RkOjpwYWlyPE1hY2hpbmVCYXNpY0Jsb2NrICosIHVuc2lnbmVkPj47CisKKyAgRGVuc2VNYXA8dW5zaWduZWQsIEF2YWlsYWJsZVZhbHNUeT4gU1NBVXBkYXRlVmFsczsKKworcHVibGljOgorICAvLy8gUHJlcGFyZSB0byBydW4gb24gYSBzcGVjaWZpYyBtYWNoaW5lIGZ1bmN0aW9uLgorICAvLy8gQHBhcmFtIE1GIC0gRnVuY3Rpb24gdGhhdCB3aWxsIGJlIHByb2Nlc3NlZAorICAvLy8gQHBhcmFtIFByZVJlZ0FsbG9jIC0gdHJ1ZSBpZiB1c2VkIGJlZm9yZSByZWdpc3RlciBhbGxvY2F0aW9uCisgIC8vLyBAcGFyYW0gTUJQSSAtIEJyYW5jaCBQcm9iYWJpbGl0eSBJbmZvLiBVc2VkIHRvIHByb3BhZ2F0ZSBjb3JyZWN0CisgIC8vLyAgICAgcHJvYmFiaWxpdGllcyB3aGVuIG1vZGlmeWluZyB0aGUgQ0ZHLgorICAvLy8gQHBhcmFtIExheW91dE1vZGUgLSBXaGVuIHRydWUsIGRvbid0IHVzZSB0aGUgZXhpc3RpbmcgbGF5b3V0IHRvIG1ha2UKKyAgLy8vICAgICBkZWNpc2lvbnMuCisgIC8vLyBAcGFyYW0gVGFpbER1cFNpemUgLSBNYXhtaW11bSBzaXplIG9mIGJsb2NrcyB0byB0YWlsLWR1cGxpY2F0ZS4gWmVybworICAvLy8gICAgIGRlZmF1bHQgaW1wbGllcyB1c2luZyB0aGUgY29tbWFuZCBsaW5lIHZhbHVlIFRhaWxEdXBTaXplLgorICB2b2lkIGluaXRNRihNYWNoaW5lRnVuY3Rpb24gJk1GLCBib29sIFByZVJlZ0FsbG9jLAorICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lQnJhbmNoUHJvYmFiaWxpdHlJbmZvICpNQlBJLAorICAgICAgICAgICAgICBib29sIExheW91dE1vZGUsIHVuc2lnbmVkIFRhaWxEdXBTaXplID0gMCk7CisKKyAgYm9vbCB0YWlsRHVwbGljYXRlQmxvY2tzKCk7CisgIHN0YXRpYyBib29sIGlzU2ltcGxlQkIoTWFjaGluZUJhc2ljQmxvY2sgKlRhaWxCQik7CisgIGJvb2wgc2hvdWxkVGFpbER1cGxpY2F0ZShib29sIElzU2ltcGxlLCBNYWNoaW5lQmFzaWNCbG9jayAmVGFpbEJCKTsKKworICAvLy8gUmV0dXJucyB0cnVlIGlmIFRhaWxCQiBjYW4gc3VjY2Vzc2Z1bGx5IGJlIGR1cGxpY2F0ZWQgaW50byBQcmVkQkIKKyAgYm9vbCBjYW5UYWlsRHVwbGljYXRlKE1hY2hpbmVCYXNpY0Jsb2NrICpUYWlsQkIsIE1hY2hpbmVCYXNpY0Jsb2NrICpQcmVkQkIpOworCisgIC8vLyBUYWlsIGR1cGxpY2F0ZSBhIHNpbmdsZSBiYXNpYyBibG9jayBpbnRvIGl0cyBwcmVkZWNlc3NvcnMsIGFuZCB0aGVuIGNsZWFuCisgIC8vLyB1cC4KKyAgLy8vIElmIFxwIER1cGxpY2F0ZVByZWRzIGlzIG5vdCBudWxsLCBpdCB3aWxsIGJlIHVwZGF0ZWQgdG8gY29udGFpbiB0aGUgbGlzdAorICAvLy8gb2YgcHJlZGVjZXNzb3JzIHRoYXQgcmVjZWl2ZWQgYSBjb3B5IG9mIFxwIE1CQi4KKyAgLy8vIElmIFxwIFJlbW92YWxDYWxsYmFjayBpcyBub24tbnVsbC4gSXQgd2lsbCBiZSBjYWxsZWQgYmVmb3JlIE1CQiBpcworICAvLy8gZGVsZXRlZC4KKyAgYm9vbCB0YWlsRHVwbGljYXRlQW5kVXBkYXRlKAorICAgICAgYm9vbCBJc1NpbXBsZSwgTWFjaGluZUJhc2ljQmxvY2sgKk1CQiwKKyAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpGb3JjZWRMYXlvdXRQcmVkLAorICAgICAgU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVCYXNpY0Jsb2NrKj4gKkR1cGxpY2F0ZWRQcmVkcyA9IG51bGxwdHIsCisgICAgICBmdW5jdGlvbl9yZWY8dm9pZChNYWNoaW5lQmFzaWNCbG9jayAqKT4gKlJlbW92YWxDYWxsYmFjayA9IG51bGxwdHIpOworCitwcml2YXRlOgorICB1c2luZyBSZWdTdWJSZWdQYWlyID0gVGFyZ2V0SW5zdHJJbmZvOjpSZWdTdWJSZWdQYWlyOworCisgIHZvaWQgYWRkU1NBVXBkYXRlRW50cnkodW5zaWduZWQgT3JpZ1JlZywgdW5zaWduZWQgTmV3UmVnLAorICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpCQik7CisgIHZvaWQgcHJvY2Vzc1BISShNYWNoaW5lSW5zdHIgKk1JLCBNYWNoaW5lQmFzaWNCbG9jayAqVGFpbEJCLAorICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2sgKlByZWRCQiwKKyAgICAgICAgICAgICAgICAgIERlbnNlTWFwPHVuc2lnbmVkLCBSZWdTdWJSZWdQYWlyPiAmTG9jYWxWUk1hcCwKKyAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxzdGQ6OnBhaXI8dW5zaWduZWQsIFJlZ1N1YlJlZ1BhaXI+PiAmQ29waWVzLAorICAgICAgICAgICAgICAgICAgY29uc3QgRGVuc2VTZXQ8dW5zaWduZWQ+ICZVc2VkQnlQaGksIGJvb2wgUmVtb3ZlKTsKKyAgdm9pZCBkdXBsaWNhdGVJbnN0cnVjdGlvbihNYWNoaW5lSW5zdHIgKk1JLCBNYWNoaW5lQmFzaWNCbG9jayAqVGFpbEJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpQcmVkQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVuc2VNYXA8dW5zaWduZWQsIFJlZ1N1YlJlZ1BhaXI+ICZMb2NhbFZSTWFwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlbnNlU2V0PHVuc2lnbmVkPiAmVXNlZEJ5UGhpKTsKKyAgdm9pZCB1cGRhdGVTdWNjZXNzb3JzUEhJcyhNYWNoaW5lQmFzaWNCbG9jayAqRnJvbUJCLCBib29sIGlzRGVhZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8TWFjaGluZUJhc2ljQmxvY2sgKj4gJlREQkJzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNtYWxsU2V0VmVjdG9yPE1hY2hpbmVCYXNpY0Jsb2NrICosIDg+ICZTdWNjcyk7CisgIGJvb2wgY2FuQ29tcGxldGVseUR1cGxpY2F0ZUJCKE1hY2hpbmVCYXNpY0Jsb2NrICZCQik7CisgIGJvb2wgZHVwbGljYXRlU2ltcGxlQkIoTWFjaGluZUJhc2ljQmxvY2sgKlRhaWxCQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8TWFjaGluZUJhc2ljQmxvY2sgKj4gJlREQkJzLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IERlbnNlU2V0PHVuc2lnbmVkPiAmUmVnc1VzZWRCeVBoaSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8TWFjaGluZUluc3RyICo+ICZDb3BpZXMpOworICBib29sIHRhaWxEdXBsaWNhdGUoYm9vbCBJc1NpbXBsZSwKKyAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpUYWlsQkIsCisgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jayAqRm9yY2VkTGF5b3V0UHJlZCwKKyAgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxNYWNoaW5lQmFzaWNCbG9jayAqPiAmVERCQnMsCisgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8TWFjaGluZUluc3RyICo+ICZDb3BpZXMpOworICB2b2lkIGFwcGVuZENvcGllcyhNYWNoaW5lQmFzaWNCbG9jayAqTUJCLAorICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8c3RkOjpwYWlyPHVuc2lnbmVkLFJlZ1N1YlJlZ1BhaXI+PiAmQ29weUluZm9zLAorICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8TWFjaGluZUluc3RyICo+ICZDb3BpZXMpOworCisgIHZvaWQgcmVtb3ZlRGVhZEJsb2NrKAorICAgICAgTWFjaGluZUJhc2ljQmxvY2sgKk1CQiwKKyAgICAgIGZ1bmN0aW9uX3JlZjx2b2lkKE1hY2hpbmVCYXNpY0Jsb2NrICopPiAqUmVtb3ZhbENhbGxiYWNrID0gbnVsbHB0cik7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1RBSUxEVVBMSUNBVE9SX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9UYXJnZXRDYWxsaW5nQ29udi5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhcmdldENhbGxpbmdDb252LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2QxMzhmNQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9UYXJnZXRDYWxsaW5nQ29udi5oCkBAIC0wLDAgKzEsMjA0IEBACisvLz09PS0tIGxsdm0vQ29kZUdlbi9UYXJnZXRDYWxsaW5nQ29udi5oIC0gQ2FsbGluZyBDb252ZW50aW9uIC0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZWZpbmVzIHR5cGVzIGZvciB3b3JraW5nIHdpdGggY2FsbGluZy1jb252ZW50aW9uIGluZm9ybWF0aW9uLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1RBUkdFVENBTExJTkdDT05WX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1RBUkdFVENBTExJTkdDT05WX0gKKworI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9WYWx1ZVR5cGVzLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L01hY2hpbmVWYWx1ZVR5cGUuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvTWF0aEV4dHJhcy5oIgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8Y2xpbWl0cz4KKyNpbmNsdWRlIDxjc3RkaW50PgorCituYW1lc3BhY2UgbGx2bSB7CituYW1lc3BhY2UgSVNEIHsKKworICBzdHJ1Y3QgQXJnRmxhZ3NUeSB7CisgIHByaXZhdGU6CisgICAgdW5zaWduZWQgSXNaRXh0IDogMTsgICAgIC8vLzwgWmVybyBleHRlbmRlZAorICAgIHVuc2lnbmVkIElzU0V4dCA6IDE7ICAgICAvLy88IFNpZ24gZXh0ZW5kZWQKKyAgICB1bnNpZ25lZCBJc0luUmVnIDogMTsgICAgLy8vPCBQYXNzZWQgaW4gcmVnaXN0ZXIKKyAgICB1bnNpZ25lZCBJc1NSZXQgOiAxOyAgICAgLy8vPCBIaWRkZW4gc3RydWN0LXJldCBwdHIKKyAgICB1bnNpZ25lZCBJc0J5VmFsIDogMTsgICAgLy8vPCBTdHJ1Y3QgcGFzc2VkIGJ5IHZhbHVlCisgICAgdW5zaWduZWQgSXNOZXN0IDogMTsgICAgIC8vLzwgTmVzdGVkIGZuIHN0YXRpYyBjaGFpbgorICAgIHVuc2lnbmVkIElzUmV0dXJuZWQgOiAxOyAvLy88IEFsd2F5cyByZXR1cm5lZAorICAgIHVuc2lnbmVkIElzU3BsaXQgOiAxOworICAgIHVuc2lnbmVkIElzSW5BbGxvY2EgOiAxOyAgIC8vLzwgUGFzc2VkIHdpdGggaW5hbGxvY2EKKyAgICB1bnNpZ25lZCBJc1NwbGl0RW5kIDogMTsgICAvLy88IExhc3QgcGFydCBvZiBhIHNwbGl0CisgICAgdW5zaWduZWQgSXNTd2lmdFNlbGYgOiAxOyAgLy8vPCBTd2lmdCBzZWxmIHBhcmFtZXRlcgorICAgIHVuc2lnbmVkIElzU3dpZnRFcnJvciA6IDE7IC8vLzwgU3dpZnQgZXJyb3IgcGFyYW1ldGVyCisgICAgdW5zaWduZWQgSXNIdmEgOiAxOyAgICAgICAgLy8vPCBIVkEgZmllbGQgZm9yCisgICAgdW5zaWduZWQgSXNIdmFTdGFydCA6IDE7ICAgLy8vPCBIVkEgc3RydWN0dXJlIHN0YXJ0CisgICAgdW5zaWduZWQgSXNTZWNBcmdQYXNzIDogMTsgLy8vPCBTZWNvbmQgYXJndW1lbnQKKyAgICB1bnNpZ25lZCBCeVZhbEFsaWduIDogNDsgICAvLy88IExvZyAyIG9mIGJ5dmFsIGFsaWdubWVudAorICAgIHVuc2lnbmVkIE9yaWdBbGlnbiA6IDU7ICAgIC8vLzwgTG9nIDIgb2Ygb3JpZ2luYWwgYWxpZ25tZW50CisgICAgdW5zaWduZWQgSXNJbkNvbnNlY3V0aXZlUmVnc0xhc3QgOiAxOworICAgIHVuc2lnbmVkIElzSW5Db25zZWN1dGl2ZVJlZ3MgOiAxOworICAgIHVuc2lnbmVkIElzQ29weUVsaXNpb25DYW5kaWRhdGUgOiAxOyAvLy88IEFyZ3VtZW50IGNvcHkgZWxpc2lvbiBjYW5kaWRhdGUKKworICAgIHVuc2lnbmVkIEJ5VmFsU2l6ZTsgLy8vPCBCeXZhbCBzdHJ1Y3Qgc2l6ZQorCisgIHB1YmxpYzoKKyAgICBBcmdGbGFnc1R5KCkKKyAgICAgICAgOiBJc1pFeHQoMCksIElzU0V4dCgwKSwgSXNJblJlZygwKSwgSXNTUmV0KDApLCBJc0J5VmFsKDApLCBJc05lc3QoMCksCisgICAgICAgICAgSXNSZXR1cm5lZCgwKSwgSXNTcGxpdCgwKSwgSXNJbkFsbG9jYSgwKSwgSXNTcGxpdEVuZCgwKSwKKyAgICAgICAgICBJc1N3aWZ0U2VsZigwKSwgSXNTd2lmdEVycm9yKDApLCBJc0h2YSgwKSwgSXNIdmFTdGFydCgwKSwKKyAgICAgICAgICBJc1NlY0FyZ1Bhc3MoMCksIEJ5VmFsQWxpZ24oMCksIE9yaWdBbGlnbigwKSwKKyAgICAgICAgICBJc0luQ29uc2VjdXRpdmVSZWdzTGFzdCgwKSwgSXNJbkNvbnNlY3V0aXZlUmVncygwKSwKKyAgICAgICAgICBJc0NvcHlFbGlzaW9uQ2FuZGlkYXRlKDApLCBCeVZhbFNpemUoMCkgeworICAgICAgc3RhdGljX2Fzc2VydChzaXplb2YoKnRoaXMpID09IDIgKiBzaXplb2YodW5zaWduZWQpLCAiZmxhZ3MgYXJlIHRvbyBiaWciKTsKKyAgICB9CisKKyAgICBib29sIGlzWkV4dCgpIGNvbnN0IHsgcmV0dXJuIElzWkV4dDsgfQorICAgIHZvaWQgc2V0WkV4dCgpIHsgSXNaRXh0ID0gMTsgfQorCisgICAgYm9vbCBpc1NFeHQoKSBjb25zdCB7IHJldHVybiBJc1NFeHQ7IH0KKyAgICB2b2lkIHNldFNFeHQoKSB7IElzU0V4dCA9IDE7IH0KKworICAgIGJvb2wgaXNJblJlZygpIGNvbnN0IHsgcmV0dXJuIElzSW5SZWc7IH0KKyAgICB2b2lkIHNldEluUmVnKCkgeyBJc0luUmVnID0gMTsgfQorCisgICAgYm9vbCBpc1NSZXQoKSBjb25zdCB7IHJldHVybiBJc1NSZXQ7IH0KKyAgICB2b2lkIHNldFNSZXQoKSB7IElzU1JldCA9IDE7IH0KKworICAgIGJvb2wgaXNCeVZhbCgpIGNvbnN0IHsgcmV0dXJuIElzQnlWYWw7IH0KKyAgICB2b2lkIHNldEJ5VmFsKCkgeyBJc0J5VmFsID0gMTsgfQorCisgICAgYm9vbCBpc0luQWxsb2NhKCkgY29uc3QgeyByZXR1cm4gSXNJbkFsbG9jYTsgfQorICAgIHZvaWQgc2V0SW5BbGxvY2EoKSB7IElzSW5BbGxvY2EgPSAxOyB9CisKKyAgICBib29sIGlzU3dpZnRTZWxmKCkgY29uc3QgeyByZXR1cm4gSXNTd2lmdFNlbGY7IH0KKyAgICB2b2lkIHNldFN3aWZ0U2VsZigpIHsgSXNTd2lmdFNlbGYgPSAxOyB9CisKKyAgICBib29sIGlzU3dpZnRFcnJvcigpIGNvbnN0IHsgcmV0dXJuIElzU3dpZnRFcnJvcjsgfQorICAgIHZvaWQgc2V0U3dpZnRFcnJvcigpIHsgSXNTd2lmdEVycm9yID0gMTsgfQorCisgICAgYm9vbCBpc0h2YSgpIGNvbnN0IHsgcmV0dXJuIElzSHZhOyB9CisgICAgdm9pZCBzZXRIdmEoKSB7IElzSHZhID0gMTsgfQorCisgICAgYm9vbCBpc0h2YVN0YXJ0KCkgY29uc3QgeyByZXR1cm4gSXNIdmFTdGFydDsgfQorICAgIHZvaWQgc2V0SHZhU3RhcnQoKSB7IElzSHZhU3RhcnQgPSAxOyB9CisKKyAgICBib29sIGlzU2VjQXJnUGFzcygpIGNvbnN0IHsgcmV0dXJuIElzU2VjQXJnUGFzczsgfQorICAgIHZvaWQgc2V0U2VjQXJnUGFzcygpIHsgSXNTZWNBcmdQYXNzID0gMTsgfQorCisgICAgYm9vbCBpc05lc3QoKSBjb25zdCB7IHJldHVybiBJc05lc3Q7IH0KKyAgICB2b2lkIHNldE5lc3QoKSB7IElzTmVzdCA9IDE7IH0KKworICAgIGJvb2wgaXNSZXR1cm5lZCgpIGNvbnN0IHsgcmV0dXJuIElzUmV0dXJuZWQ7IH0KKyAgICB2b2lkIHNldFJldHVybmVkKCkgeyBJc1JldHVybmVkID0gMTsgfQorCisgICAgYm9vbCBpc0luQ29uc2VjdXRpdmVSZWdzKCkgIGNvbnN0IHsgcmV0dXJuIElzSW5Db25zZWN1dGl2ZVJlZ3M7IH0KKyAgICB2b2lkIHNldEluQ29uc2VjdXRpdmVSZWdzKCkgeyBJc0luQ29uc2VjdXRpdmVSZWdzID0gMTsgfQorCisgICAgYm9vbCBpc0luQ29uc2VjdXRpdmVSZWdzTGFzdCgpIGNvbnN0IHsgcmV0dXJuIElzSW5Db25zZWN1dGl2ZVJlZ3NMYXN0OyB9CisgICAgdm9pZCBzZXRJbkNvbnNlY3V0aXZlUmVnc0xhc3QoKSB7IElzSW5Db25zZWN1dGl2ZVJlZ3NMYXN0ID0gMTsgfQorCisgICAgYm9vbCBpc1NwbGl0KCkgICBjb25zdCB7IHJldHVybiBJc1NwbGl0OyB9CisgICAgdm9pZCBzZXRTcGxpdCgpICB7IElzU3BsaXQgPSAxOyB9CisKKyAgICBib29sIGlzU3BsaXRFbmQoKSAgIGNvbnN0IHsgcmV0dXJuIElzU3BsaXRFbmQ7IH0KKyAgICB2b2lkIHNldFNwbGl0RW5kKCkgIHsgSXNTcGxpdEVuZCA9IDE7IH0KKworICAgIGJvb2wgaXNDb3B5RWxpc2lvbkNhbmRpZGF0ZSgpICBjb25zdCB7IHJldHVybiBJc0NvcHlFbGlzaW9uQ2FuZGlkYXRlOyB9CisgICAgdm9pZCBzZXRDb3B5RWxpc2lvbkNhbmRpZGF0ZSgpIHsgSXNDb3B5RWxpc2lvbkNhbmRpZGF0ZSA9IDE7IH0KKworICAgIHVuc2lnbmVkIGdldEJ5VmFsQWxpZ24oKSBjb25zdCB7IHJldHVybiAoMVUgPDwgQnlWYWxBbGlnbikgLyAyOyB9CisgICAgdm9pZCBzZXRCeVZhbEFsaWduKHVuc2lnbmVkIEEpIHsKKyAgICAgIEJ5VmFsQWxpZ24gPSBMb2cyXzMyKEEpICsgMTsKKyAgICAgIGFzc2VydChnZXRCeVZhbEFsaWduKCkgPT0gQSAmJiAiYml0ZmllbGQgb3ZlcmZsb3ciKTsKKyAgICB9CisKKyAgICB1bnNpZ25lZCBnZXRPcmlnQWxpZ24oKSBjb25zdCB7IHJldHVybiAoMVUgPDwgT3JpZ0FsaWduKSAvIDI7IH0KKyAgICB2b2lkIHNldE9yaWdBbGlnbih1bnNpZ25lZCBBKSB7CisgICAgICBPcmlnQWxpZ24gPSBMb2cyXzMyKEEpICsgMTsKKyAgICAgIGFzc2VydChnZXRPcmlnQWxpZ24oKSA9PSBBICYmICJiaXRmaWVsZCBvdmVyZmxvdyIpOworICAgIH0KKworICAgIHVuc2lnbmVkIGdldEJ5VmFsU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIEJ5VmFsU2l6ZTsgfQorICAgIHZvaWQgc2V0QnlWYWxTaXplKHVuc2lnbmVkIFMpIHsgQnlWYWxTaXplID0gUzsgfQorICB9OworCisgIC8vLyBJbnB1dEFyZyAtIFRoaXMgc3RydWN0IGNhcnJpZXMgZmxhZ3MgYW5kIHR5cGUgaW5mb3JtYXRpb24gYWJvdXQgYQorICAvLy8gc2luZ2xlIGluY29taW5nIChmb3JtYWwpIGFyZ3VtZW50IG9yIGluY29taW5nIChmcm9tIHRoZSBwZXJzcGVjdGl2ZQorICAvLy8gb2YgdGhlIGNhbGxlcikgcmV0dXJuIHZhbHVlIHZpcnR1YWwgcmVnaXN0ZXIuCisgIC8vLworICBzdHJ1Y3QgSW5wdXRBcmcgeworICAgIEFyZ0ZsYWdzVHkgRmxhZ3M7CisgICAgTVZUIFZUID0gTVZUOjpPdGhlcjsKKyAgICBFVlQgQXJnVlQ7CisgICAgYm9vbCBVc2VkID0gZmFsc2U7CisKKyAgICAvLy8gSW5kZXggb3JpZ2luYWwgRnVuY3Rpb24ncyBhcmd1bWVudC4KKyAgICB1bnNpZ25lZCBPcmlnQXJnSW5kZXg7CisgICAgLy8vIFNlbnRpbmVsIHZhbHVlIGZvciBpbXBsaWNpdCBtYWNoaW5lLWxldmVsIGlucHV0IGFyZ3VtZW50cy4KKyAgICBzdGF0aWMgY29uc3QgdW5zaWduZWQgTm9BcmdJbmRleCA9IFVJTlRfTUFYOworCisgICAgLy8vIE9mZnNldCBpbiBieXRlcyBvZiBjdXJyZW50IGlucHV0IHZhbHVlIHJlbGF0aXZlIHRvIHRoZSBiZWdpbm5pbmcgb2YKKyAgICAvLy8gb3JpZ2luYWwgYXJndW1lbnQuIEUuZy4gaWYgYXJndW1lbnQgd2FzIHNwbGl0dGVkIGludG8gZm91ciAzMiBiaXQKKyAgICAvLy8gcmVnaXN0ZXJzLCB3ZSBnb3QgNCBJbnB1dEFyZ3Mgd2l0aCBQYXJ0T2Zmc2V0cyAwLCA0LCA4IGFuZCAxMi4KKyAgICB1bnNpZ25lZCBQYXJ0T2Zmc2V0OworCisgICAgSW5wdXRBcmcoKSA9IGRlZmF1bHQ7CisgICAgSW5wdXRBcmcoQXJnRmxhZ3NUeSBmbGFncywgRVZUIHZ0LCBFVlQgYXJndnQsIGJvb2wgdXNlZCwKKyAgICAgICAgICAgICB1bnNpZ25lZCBvcmlnSWR4LCB1bnNpZ25lZCBwYXJ0T2ZmcykKKyAgICAgIDogRmxhZ3MoZmxhZ3MpLCBVc2VkKHVzZWQpLCBPcmlnQXJnSW5kZXgob3JpZ0lkeCksIFBhcnRPZmZzZXQocGFydE9mZnMpIHsKKyAgICAgIFZUID0gdnQuZ2V0U2ltcGxlVlQoKTsKKyAgICAgIEFyZ1ZUID0gYXJndnQ7CisgICAgfQorCisgICAgYm9vbCBpc09yaWdBcmcoKSBjb25zdCB7CisgICAgICByZXR1cm4gT3JpZ0FyZ0luZGV4ICE9IE5vQXJnSW5kZXg7CisgICAgfQorCisgICAgdW5zaWduZWQgZ2V0T3JpZ0FyZ0luZGV4KCkgY29uc3QgeworICAgICAgYXNzZXJ0KE9yaWdBcmdJbmRleCAhPSBOb0FyZ0luZGV4ICYmICJJbXBsaWNpdCBtYWNoaW5lLWxldmVsIGFyZ3VtZW50Iik7CisgICAgICByZXR1cm4gT3JpZ0FyZ0luZGV4OworICAgIH0KKyAgfTsKKworICAvLy8gT3V0cHV0QXJnIC0gVGhpcyBzdHJ1Y3QgY2FycmllcyBmbGFncyBhbmQgYSB2YWx1ZSBmb3IgYQorICAvLy8gc2luZ2xlIG91dGdvaW5nIChhY3R1YWwpIGFyZ3VtZW50IG9yIG91dGdvaW5nIChmcm9tIHRoZSBwZXJzcGVjdGl2ZQorICAvLy8gb2YgdGhlIGNhbGxlcikgcmV0dXJuIHZhbHVlIHZpcnR1YWwgcmVnaXN0ZXIuCisgIC8vLworICBzdHJ1Y3QgT3V0cHV0QXJnIHsKKyAgICBBcmdGbGFnc1R5IEZsYWdzOworICAgIE1WVCBWVDsKKyAgICBFVlQgQXJnVlQ7CisKKyAgICAvLy8gSXNGaXhlZCAtIElzIHRoaXMgYSAiZml4ZWQiIHZhbHVlLCBpZSBub3QgcGFzc2VkIHRocm91Z2ggYSB2YXJhcmcgIi4uLiIuCisgICAgYm9vbCBJc0ZpeGVkID0gZmFsc2U7CisKKyAgICAvLy8gSW5kZXggb3JpZ2luYWwgRnVuY3Rpb24ncyBhcmd1bWVudC4KKyAgICB1bnNpZ25lZCBPcmlnQXJnSW5kZXg7CisKKyAgICAvLy8gT2Zmc2V0IGluIGJ5dGVzIG9mIGN1cnJlbnQgb3V0cHV0IHZhbHVlIHJlbGF0aXZlIHRvIHRoZSBiZWdpbm5pbmcgb2YKKyAgICAvLy8gb3JpZ2luYWwgYXJndW1lbnQuIEUuZy4gaWYgYXJndW1lbnQgd2FzIHNwbGl0dGVkIGludG8gZm91ciAzMiBiaXQKKyAgICAvLy8gcmVnaXN0ZXJzLCB3ZSBnb3QgNCBPdXRwdXRBcmdzIHdpdGggUGFydE9mZnNldHMgMCwgNCwgOCBhbmQgMTIuCisgICAgdW5zaWduZWQgUGFydE9mZnNldDsKKworICAgIE91dHB1dEFyZygpID0gZGVmYXVsdDsKKyAgICBPdXRwdXRBcmcoQXJnRmxhZ3NUeSBmbGFncywgRVZUIHZ0LCBFVlQgYXJndnQsIGJvb2wgaXNmaXhlZCwKKyAgICAgICAgICAgICAgdW5zaWduZWQgb3JpZ0lkeCwgdW5zaWduZWQgcGFydE9mZnMpCisgICAgICA6IEZsYWdzKGZsYWdzKSwgSXNGaXhlZChpc2ZpeGVkKSwgT3JpZ0FyZ0luZGV4KG9yaWdJZHgpLAorICAgICAgICBQYXJ0T2Zmc2V0KHBhcnRPZmZzKSB7CisgICAgICBWVCA9IHZ0LmdldFNpbXBsZVZUKCk7CisgICAgICBBcmdWVCA9IGFyZ3Z0OworICAgIH0KKyAgfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIElTRAorfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9UQVJHRVRDQUxMSU5HQ09OVl9ICmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vVGFyZ2V0RnJhbWVMb3dlcmluZy5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhcmdldEZyYW1lTG93ZXJpbmcuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MWYxY2YwCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhcmdldEZyYW1lTG93ZXJpbmcuaApAQCAtMCwwICsxLDM0OCBAQAorLy89PT0tLSBsbHZtL0NvZGVHZW4vVGFyZ2V0RnJhbWVMb3dlcmluZy5oIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBJbnRlcmZhY2UgdG8gZGVzY3JpYmUgdGhlIGxheW91dCBvZiBhIHN0YWNrIGZyYW1lIG9uIHRoZSB0YXJnZXQgbWFjaGluZS4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9UQVJHRVRGUkFNRUxPV0VSSU5HX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1RBUkdFVEZSQU1FTE9XRVJJTkdfSAorCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVCYXNpY0Jsb2NrLmgiCisjaW5jbHVkZSA8dXRpbGl0eT4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKK25hbWVzcGFjZSBsbHZtIHsKKyAgY2xhc3MgQml0VmVjdG9yOworICBjbGFzcyBDYWxsZWVTYXZlZEluZm87CisgIGNsYXNzIE1hY2hpbmVGdW5jdGlvbjsKKyAgY2xhc3MgUmVnU2NhdmVuZ2VyOworCisvLy8gSW5mb3JtYXRpb24gYWJvdXQgc3RhY2sgZnJhbWUgbGF5b3V0IG9uIHRoZSB0YXJnZXQuICBJdCBob2xkcyB0aGUgZGlyZWN0aW9uCisvLy8gb2Ygc3RhY2sgZ3Jvd3RoLCB0aGUga25vd24gc3RhY2sgYWxpZ25tZW50IG9uIGVudHJ5IHRvIGVhY2ggZnVuY3Rpb24sIGFuZAorLy8vIHRoZSBvZmZzZXQgdG8gdGhlIGxvY2FscyBhcmVhLgorLy8vCisvLy8gVGhlIG9mZnNldCB0byB0aGUgbG9jYWwgYXJlYSBpcyB0aGUgb2Zmc2V0IGZyb20gdGhlIHN0YWNrIHBvaW50ZXIgb24KKy8vLyBmdW5jdGlvbiBlbnRyeSB0byB0aGUgZmlyc3QgbG9jYXRpb24gd2hlcmUgZnVuY3Rpb24gZGF0YSAobG9jYWwgdmFyaWFibGVzLAorLy8vIHNwaWxsIGxvY2F0aW9ucykgY2FuIGJlIHN0b3JlZC4KK2NsYXNzIFRhcmdldEZyYW1lTG93ZXJpbmcgeworcHVibGljOgorICBlbnVtIFN0YWNrRGlyZWN0aW9uIHsKKyAgICBTdGFja0dyb3dzVXAsICAgICAgICAvLyBBZGRpbmcgdG8gdGhlIHN0YWNrIGluY3JlYXNlcyB0aGUgc3RhY2sgYWRkcmVzcworICAgIFN0YWNrR3Jvd3NEb3duICAgICAgIC8vIEFkZGluZyB0byB0aGUgc3RhY2sgZGVjcmVhc2VzIHRoZSBzdGFjayBhZGRyZXNzCisgIH07CisKKyAgLy8gTWFwcyBhIGNhbGxlZSBzYXZlZCByZWdpc3RlciB0byBhIHN0YWNrIHNsb3Qgd2l0aCBhIGZpeGVkIG9mZnNldC4KKyAgc3RydWN0IFNwaWxsU2xvdCB7CisgICAgdW5zaWduZWQgUmVnOworICAgIGludCBPZmZzZXQ7IC8vIE9mZnNldCByZWxhdGl2ZSB0byBzdGFjayBwb2ludGVyIG9uIGZ1bmN0aW9uIGVudHJ5LgorICB9OworcHJpdmF0ZToKKyAgU3RhY2tEaXJlY3Rpb24gU3RhY2tEaXI7CisgIHVuc2lnbmVkIFN0YWNrQWxpZ25tZW50OworICB1bnNpZ25lZCBUcmFuc2llbnRTdGFja0FsaWdubWVudDsKKyAgaW50IExvY2FsQXJlYU9mZnNldDsKKyAgYm9vbCBTdGFja1JlYWxpZ25hYmxlOworcHVibGljOgorICBUYXJnZXRGcmFtZUxvd2VyaW5nKFN0YWNrRGlyZWN0aW9uIEQsIHVuc2lnbmVkIFN0YWNrQWwsIGludCBMQU8sCisgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgVHJhbnNBbCA9IDEsIGJvb2wgU3RhY2tSZWFsID0gdHJ1ZSkKKyAgICA6IFN0YWNrRGlyKEQpLCBTdGFja0FsaWdubWVudChTdGFja0FsKSwgVHJhbnNpZW50U3RhY2tBbGlnbm1lbnQoVHJhbnNBbCksCisgICAgICBMb2NhbEFyZWFPZmZzZXQoTEFPKSwgU3RhY2tSZWFsaWduYWJsZShTdGFja1JlYWwpIHt9CisKKyAgdmlydHVhbCB+VGFyZ2V0RnJhbWVMb3dlcmluZygpOworCisgIC8vIFRoZXNlIG1ldGhvZHMgcmV0dXJuIGluZm9ybWF0aW9uIHRoYXQgZGVzY3JpYmVzIHRoZSBhYnN0cmFjdCBzdGFjayBsYXlvdXQKKyAgLy8gb2YgdGhlIHRhcmdldCBtYWNoaW5lLgorCisgIC8vLyBnZXRTdGFja0dyb3d0aERpcmVjdGlvbiAtIFJldHVybiB0aGUgZGlyZWN0aW9uIHRoZSBzdGFjayBncm93cworICAvLy8KKyAgU3RhY2tEaXJlY3Rpb24gZ2V0U3RhY2tHcm93dGhEaXJlY3Rpb24oKSBjb25zdCB7IHJldHVybiBTdGFja0RpcjsgfQorCisgIC8vLyBnZXRTdGFja0FsaWdubWVudCAtIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIG51bWJlciBvZiBieXRlcyB0byB3aGljaCB0aGUKKyAgLy8vIHN0YWNrIHBvaW50ZXIgbXVzdCBiZSBhbGlnbmVkIG9uIGVudHJ5IHRvIGEgZnVuY3Rpb24uICBUeXBpY2FsbHksIHRoaXMKKyAgLy8vIGlzIHRoZSBsYXJnZXN0IGFsaWdubWVudCBmb3IgYW55IGRhdGEgb2JqZWN0IGluIHRoZSB0YXJnZXQuCisgIC8vLworICB1bnNpZ25lZCBnZXRTdGFja0FsaWdubWVudCgpIGNvbnN0IHsgcmV0dXJuIFN0YWNrQWxpZ25tZW50OyB9CisKKyAgLy8vIGFsaWduU1BBZGp1c3QgLSBUaGlzIG1ldGhvZCBhbGlnbnMgdGhlIHN0YWNrIGFkanVzdG1lbnQgdG8gdGhlIGNvcnJlY3QKKyAgLy8vIGFsaWdubWVudC4KKyAgLy8vCisgIGludCBhbGlnblNQQWRqdXN0KGludCBTUEFkaikgY29uc3QgeworICAgIGlmIChTUEFkaiA8IDApIHsKKyAgICAgIFNQQWRqID0gLWFsaWduVG8oLVNQQWRqLCBTdGFja0FsaWdubWVudCk7CisgICAgfSBlbHNlIHsKKyAgICAgIFNQQWRqID0gYWxpZ25UbyhTUEFkaiwgU3RhY2tBbGlnbm1lbnQpOworICAgIH0KKyAgICByZXR1cm4gU1BBZGo7CisgIH0KKworICAvLy8gZ2V0VHJhbnNpZW50U3RhY2tBbGlnbm1lbnQgLSBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8KKyAgLy8vIHdoaWNoIHRoZSBzdGFjayBwb2ludGVyIG11c3QgYmUgYWxpZ25lZCBhdCBhbGwgdGltZXMsIGV2ZW4gYmV0d2VlbgorICAvLy8gY2FsbHMuCisgIC8vLworICB1bnNpZ25lZCBnZXRUcmFuc2llbnRTdGFja0FsaWdubWVudCgpIGNvbnN0IHsKKyAgICByZXR1cm4gVHJhbnNpZW50U3RhY2tBbGlnbm1lbnQ7CisgIH0KKworICAvLy8gaXNTdGFja1JlYWxpZ25hYmxlIC0gVGhpcyBtZXRob2QgcmV0dXJucyB3aGV0aGVyIHRoZSBzdGFjayBjYW4gYmUKKyAgLy8vIHJlYWxpZ25lZC4KKyAgYm9vbCBpc1N0YWNrUmVhbGlnbmFibGUoKSBjb25zdCB7CisgICAgcmV0dXJuIFN0YWNrUmVhbGlnbmFibGU7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBza2V3IHRoYXQgaGFzIHRvIGJlIGFwcGxpZWQgdG8gc3RhY2sgYWxpZ25tZW50IHVuZGVyCisgIC8vLyBjZXJ0YWluIGNvbmRpdGlvbnMgKGUuZy4gc3RhY2sgd2FzIGFkanVzdGVkIGJlZm9yZSBmdW5jdGlvbiBccCBNRgorICAvLy8gd2FzIGNhbGxlZCkuCisgIHZpcnR1YWwgdW5zaWduZWQgZ2V0U3RhY2tBbGlnbm1lbnRTa2V3KGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0OworCisgIC8vLyBnZXRPZmZzZXRPZkxvY2FsQXJlYSAtIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIG9mZnNldCBvZiB0aGUgbG9jYWwgYXJlYQorICAvLy8gZnJvbSB0aGUgc3RhY2sgcG9pbnRlciBvbiBlbnRyYW5jZSB0byBhIGZ1bmN0aW9uLgorICAvLy8KKyAgaW50IGdldE9mZnNldE9mTG9jYWxBcmVhKCkgY29uc3QgeyByZXR1cm4gTG9jYWxBcmVhT2Zmc2V0OyB9CisKKyAgLy8vIGlzRlBDbG9zZVRvSW5jb21pbmdTUCAtIFJldHVybiB0cnVlIGlmIHRoZSBmcmFtZSBwb2ludGVyIGlzIGNsb3NlIHRvCisgIC8vLyB0aGUgaW5jb21pbmcgc3RhY2sgcG9pbnRlciwgZmFsc2UgaWYgaXQgaXMgY2xvc2UgdG8gdGhlIHBvc3QtcHJvbG9ndWUKKyAgLy8vIHN0YWNrIHBvaW50ZXIuCisgIHZpcnR1YWwgYm9vbCBpc0ZQQ2xvc2VUb0luY29taW5nU1AoKSBjb25zdCB7IHJldHVybiB0cnVlOyB9CisKKyAgLy8vIGFzc2lnbkNhbGxlZVNhdmVkU3BpbGxTbG90cyAtIEFsbG93cyB0YXJnZXQgdG8gb3ZlcnJpZGUgc3BpbGwgc2xvdAorICAvLy8gYXNzaWdubWVudCBsb2dpYy4gIElmIGltcGxlbWVudGVkLCBhc3NpZ25DYWxsZWVTYXZlZFNwaWxsU2xvdHMoKSBzaG91bGQKKyAgLy8vIGFzc2lnbiBmcmFtZSBzbG90cyB0byBhbGwgQ1NJIGVudHJpZXMgYW5kIHJldHVybiB0cnVlLiAgSWYgdGhpcyBtZXRob2QKKyAgLy8vIHJldHVybnMgZmFsc2UsIHNwaWxsIHNsb3RzIHdpbGwgYmUgYXNzaWduZWQgdXNpbmcgZ2VuZXJpYyBpbXBsZW1lbnRhdGlvbi4KKyAgLy8vIGFzc2lnbkNhbGxlZVNhdmVkU3BpbGxTbG90cygpIG1heSBhZGQsIGRlbGV0ZSBvciByZWFycmFuZ2UgZWxlbWVudHMgb2YKKyAgLy8vIENTSS4KKyAgdmlydHVhbCBib29sCisgIGFzc2lnbkNhbGxlZVNhdmVkU3BpbGxTbG90cyhNYWNoaW5lRnVuY3Rpb24gJk1GLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnZlY3RvcjxDYWxsZWVTYXZlZEluZm8+ICZDU0kpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gZ2V0Q2FsbGVlU2F2ZWRTcGlsbFNsb3RzIC0gVGhpcyBtZXRob2QgcmV0dXJucyBhIHBvaW50ZXIgdG8gYW4gYXJyYXkgb2YKKyAgLy8vIHBhaXJzLCB0aGF0IGNvbnRhaW5zIGFuIGVudHJ5IGZvciBlYWNoIGNhbGxlZSBzYXZlZCByZWdpc3RlciB0aGF0IG11c3QgYmUKKyAgLy8vIHNwaWxsZWQgdG8gYSBwYXJ0aWN1bGFyIHN0YWNrIGxvY2F0aW9uIGlmIGl0IGlzIHNwaWxsZWQuCisgIC8vLworICAvLy8gRWFjaCBlbnRyeSBpbiB0aGlzIGFycmF5IGNvbnRhaW5zIGEgPHJlZ2lzdGVyLG9mZnNldD4gcGFpciwgaW5kaWNhdGluZyB0aGUKKyAgLy8vIGZpeGVkIG9mZnNldCBmcm9tIHRoZSBpbmNvbWluZyBzdGFjayBwb2ludGVyIHRoYXQgZWFjaCByZWdpc3RlciBzaG91bGQgYmUKKyAgLy8vIHNwaWxsZWQgYXQuIElmIGEgcmVnaXN0ZXIgaXMgbm90IGxpc3RlZCBoZXJlLCB0aGUgY29kZSBnZW5lcmF0b3IgaXMKKyAgLy8vIGFsbG93ZWQgdG8gc3BpbGwgaXQgYW55d2hlcmUgaXQgY2hvb3Nlcy4KKyAgLy8vCisgIHZpcnR1YWwgY29uc3QgU3BpbGxTbG90ICoKKyAgZ2V0Q2FsbGVlU2F2ZWRTcGlsbFNsb3RzKHVuc2lnbmVkICZOdW1FbnRyaWVzKSBjb25zdCB7CisgICAgTnVtRW50cmllcyA9IDA7CisgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKworICAvLy8gdGFyZ2V0SGFuZGxlc1N0YWNrRnJhbWVSb3VuZGluZyAtIFJldHVybnMgdHJ1ZSBpZiB0aGUgdGFyZ2V0IGlzCisgIC8vLyByZXNwb25zaWJsZSBmb3Igcm91bmRpbmcgdXAgdGhlIHN0YWNrIGZyYW1lIChwcm9iYWJseSBhdCBlbWl0UHJvbG9ndWUKKyAgLy8vIHRpbWUpLgorICB2aXJ0dWFsIGJvb2wgdGFyZ2V0SGFuZGxlc1N0YWNrRnJhbWVSb3VuZGluZygpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSB0YXJnZXQgd2lsbCBjb3JyZWN0bHkgaGFuZGxlIHNocmluayB3cmFwcGluZy4KKyAgdmlydHVhbCBib29sIGVuYWJsZVNocmlua1dyYXBwaW5nKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBzdGFjayBzbG90IGhvbGVzIGluIHRoZSBmaXhlZCBhbmQgY2FsbGVlLXNhdmUgc3RhY2sKKyAgLy8vIGFyZWEgc2hvdWxkIGJlIHVzZWQgd2hlbiBhbGxvY2F0aW5nIG90aGVyIHN0YWNrIGxvY2F0aW9ucyB0byByZWR1Y2Ugc3RhY2sKKyAgLy8vIHNpemUuCisgIHZpcnR1YWwgYm9vbCBlbmFibGVTdGFja1Nsb3RTY2F2ZW5naW5nKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gZW1pdFByb2xvZy9lbWl0RXBpbG9nIC0gVGhlc2UgbWV0aG9kcyBpbnNlcnQgcHJvbG9nIGFuZCBlcGlsb2cgY29kZSBpbnRvCisgIC8vLyB0aGUgZnVuY3Rpb24uCisgIHZpcnR1YWwgdm9pZCBlbWl0UHJvbG9ndWUoTWFjaGluZUZ1bmN0aW9uICZNRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jayAmTUJCKSBjb25zdCA9IDA7CisgIHZpcnR1YWwgdm9pZCBlbWl0RXBpbG9ndWUoTWFjaGluZUZ1bmN0aW9uICZNRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jayAmTUJCKSBjb25zdCA9IDA7CisKKyAgLy8vIFJlcGxhY2UgYSBTdGFja1Byb2JlIHN0dWIgKGlmIGFueSkgd2l0aCB0aGUgYWN0dWFsIHByb2JlIGNvZGUgaW5saW5lCisgIHZpcnR1YWwgdm9pZCBpbmxpbmVTdGFja1Byb2JlKE1hY2hpbmVGdW5jdGlvbiAmTUYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICZQcm9sb2d1ZU1CQikgY29uc3Qge30KKworICAvLy8gQWRqdXN0IHRoZSBwcm9sb2d1ZSB0byBoYXZlIHRoZSBmdW5jdGlvbiB1c2Ugc2VnbWVudGVkIHN0YWNrcy4gVGhpcyB3b3JrcworICAvLy8gYnkgYWRkaW5nIGEgY2hlY2sgZXZlbiBiZWZvcmUgdGhlICJub3JtYWwiIGZ1bmN0aW9uIHByb2xvZ3VlLgorICB2aXJ0dWFsIHZvaWQgYWRqdXN0Rm9yU2VnbWVudGVkU3RhY2tzKE1hY2hpbmVGdW5jdGlvbiAmTUYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2sgJlByb2xvZ3VlTUJCKSBjb25zdCB7fQorCisgIC8vLyBBZGp1c3QgdGhlIHByb2xvZ3VlIHRvIGFkZCBFcmxhbmcgUnVuLVRpbWUgU3lzdGVtIChFUlRTKSBzcGVjaWZpYyBjb2RlIGluCisgIC8vLyB0aGUgYXNzZW1ibHkgcHJvbG9ndWUgdG8gZXhwbGljaXRseSBoYW5kbGUgdGhlIHN0YWNrLgorICB2aXJ0dWFsIHZvaWQgYWRqdXN0Rm9ySGlQRVByb2xvZ3VlKE1hY2hpbmVGdW5jdGlvbiAmTUYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2sgJlByb2xvZ3VlTUJCKSBjb25zdCB7fQorCisgIC8vLyBzcGlsbENhbGxlZVNhdmVkUmVnaXN0ZXJzIC0gSXNzdWVzIGluc3RydWN0aW9uKHMpIHRvIHNwaWxsIGFsbCBjYWxsZWUKKyAgLy8vIHNhdmVkIHJlZ2lzdGVycyBhbmQgcmV0dXJucyB0cnVlIGlmIGl0IGlzbid0IHBvc3NpYmxlIC8gcHJvZml0YWJsZSB0byBkbworICAvLy8gc28gYnkgaXNzdWluZyBhIHNlcmllcyBvZiBzdG9yZSBpbnN0cnVjdGlvbnMgdmlhCisgIC8vLyBzdG9yZVJlZ1RvU3RhY2tTbG90KCkuIFJldHVybnMgZmFsc2Ugb3RoZXJ3aXNlLgorICB2aXJ0dWFsIGJvb2wgc3BpbGxDYWxsZWVTYXZlZFJlZ2lzdGVycyhNYWNoaW5lQmFzaWNCbG9jayAmTUJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RkOjp2ZWN0b3I8Q2FsbGVlU2F2ZWRJbmZvPiAmQ1NJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyByZXN0b3JlQ2FsbGVlU2F2ZWRSZWdpc3RlcnMgLSBJc3N1ZXMgaW5zdHJ1Y3Rpb24ocykgdG8gcmVzdG9yZSBhbGwgY2FsbGVlCisgIC8vLyBzYXZlZCByZWdpc3RlcnMgYW5kIHJldHVybnMgdHJ1ZSBpZiBpdCBpc24ndCBwb3NzaWJsZSAvIHByb2ZpdGFibGUgdG8gZG8KKyAgLy8vIHNvIGJ5IGlzc3VpbmcgYSBzZXJpZXMgb2YgbG9hZCBpbnN0cnVjdGlvbnMgdmlhIGxvYWRSZWdUb1N0YWNrU2xvdCgpLgorICAvLy8gSWYgaXQgcmV0dXJucyB0cnVlLCBhbmQgYW55IG9mIHRoZSByZWdpc3RlcnMgaW4gQ1NJIGlzIG5vdCByZXN0b3JlZCwKKyAgLy8vIGl0IHNldHMgdGhlIGNvcnJlc3BvbmRpbmcgUmVzdG9yZWQgZmxhZyBpbiBDU0kgdG8gZmFsc2UuCisgIC8vLyBSZXR1cm5zIGZhbHNlIG90aGVyd2lzZS4KKyAgdmlydHVhbCBib29sIHJlc3RvcmVDYWxsZWVTYXZlZFJlZ2lzdGVycyhNYWNoaW5lQmFzaWNCbG9jayAmTUJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnZlY3RvcjxDYWxsZWVTYXZlZEluZm8+ICZDU0ksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHRhcmdldCBuZWVkcyB0byBkaXNhYmxlIGZyYW1lIHBvaW50ZXIgZWxpbWluYXRpb24uCisgIHZpcnR1YWwgYm9vbCBub0ZyYW1lUG9pbnRlckVsaW0oY29uc3QgTWFjaGluZUZ1bmN0aW9uICZNRikgY29uc3Q7CisKKyAgLy8vIGhhc0ZQIC0gUmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBzaG91bGQgaGF2ZSBhIGRlZGljYXRlZAorICAvLy8gZnJhbWUgcG9pbnRlciByZWdpc3Rlci4gRm9yIG1vc3QgdGFyZ2V0cyB0aGlzIGlzIHRydWUgb25seSBpZiB0aGUgZnVuY3Rpb24KKyAgLy8vIGhhcyB2YXJpYWJsZSBzaXplZCBhbGxvY2FzIG9yIGlmIGZyYW1lIHBvaW50ZXIgZWxpbWluYXRpb24gaXMgZGlzYWJsZWQuCisgIHZpcnR1YWwgYm9vbCBoYXNGUChjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKSBjb25zdCA9IDA7CisKKyAgLy8vIGhhc1Jlc2VydmVkQ2FsbEZyYW1lIC0gVW5kZXIgbm9ybWFsIGNpcmN1bXN0YW5jZXMsIHdoZW4gYSBmcmFtZSBwb2ludGVyIGlzCisgIC8vLyBub3QgcmVxdWlyZWQsIHdlIHJlc2VydmUgYXJndW1lbnQgc3BhY2UgZm9yIGNhbGwgc2l0ZXMgaW4gdGhlIGZ1bmN0aW9uCisgIC8vLyBpbW1lZGlhdGVseSBvbiBlbnRyeSB0byB0aGUgY3VycmVudCBmdW5jdGlvbi4gVGhpcyBlbGltaW5hdGVzIHRoZSBuZWVkIGZvcgorICAvLy8gYWRkL3N1YiBzcCBicmFja2V0cyBhcm91bmQgY2FsbCBzaXRlcy4gUmV0dXJucyB0cnVlIGlmIHRoZSBjYWxsIGZyYW1lIGlzCisgIC8vLyBpbmNsdWRlZCBhcyBwYXJ0IG9mIHRoZSBzdGFjayBmcmFtZS4KKyAgdmlydHVhbCBib29sIGhhc1Jlc2VydmVkQ2FsbEZyYW1lKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0IHsKKyAgICByZXR1cm4gIWhhc0ZQKE1GKTsKKyAgfQorCisgIC8vLyBjYW5TaW1wbGlmeUNhbGxGcmFtZVBzZXVkb3MgLSBXaGVuIHBvc3NpYmxlLCBpdCdzIGJlc3QgdG8gc2ltcGxpZnkgdGhlCisgIC8vLyBjYWxsIGZyYW1lIHBzZXVkbyBvcHMgYmVmb3JlIGRvaW5nIGZyYW1lIGluZGV4IGVsaW1pbmF0aW9uLiBUaGlzIGlzCisgIC8vLyBwb3NzaWJsZSBvbmx5IHdoZW4gZnJhbWUgaW5kZXggcmVmZXJlbmNlcyBiZXR3ZWVuIHRoZSBwc2V1ZG9zIHdvbid0CisgIC8vLyBuZWVkIGFkanVzdGluZyBmb3IgdGhlIGNhbGwgZnJhbWUgYWRqdXN0bWVudHMuIE5vcm1hbGx5LCB0aGF0J3MgdHJ1ZQorICAvLy8gaWYgdGhlIGZ1bmN0aW9uIGhhcyBhIHJlc2VydmVkIGNhbGwgZnJhbWUgb3IgYSBmcmFtZSBwb2ludGVyLiBTb21lCisgIC8vLyB0YXJnZXRzIChUaHVtYjIsIGZvciBleGFtcGxlKSBtYXkgaGF2ZSBtb3JlIGNvbXBsaWNhdGVkIGNyaXRlcmlhLAorICAvLy8gaG93ZXZlciwgYW5kIGNhbiBvdmVycmlkZSB0aGlzIGJlaGF2aW9yLgorICB2aXJ0dWFsIGJvb2wgY2FuU2ltcGxpZnlDYWxsRnJhbWVQc2V1ZG9zKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0IHsKKyAgICByZXR1cm4gaGFzUmVzZXJ2ZWRDYWxsRnJhbWUoTUYpIHx8IGhhc0ZQKE1GKTsKKyAgfQorCisgIC8vIG5lZWRzRnJhbWVJbmRleFJlc29sdXRpb24gLSBEbyB3ZSBuZWVkIHRvIHBlcmZvcm0gRkkgcmVzb2x1dGlvbiBmb3IKKyAgLy8gdGhpcyBmdW5jdGlvbi4gTm9ybWFsbHksIHRoaXMgaXMgcmVxdWlyZWQgb25seSB3aGVuIHRoZSBmdW5jdGlvbgorICAvLyBoYXMgYW55IHN0YWNrIG9iamVjdHMuIEhvd2V2ZXIsIHRhcmdldHMgbWF5IHdhbnQgdG8gb3ZlcnJpZGUgdGhpcy4KKyAgdmlydHVhbCBib29sIG5lZWRzRnJhbWVJbmRleFJlc29sdXRpb24oY29uc3QgTWFjaGluZUZ1bmN0aW9uICZNRikgY29uc3Q7CisKKyAgLy8vIGdldEZyYW1lSW5kZXhSZWZlcmVuY2UgLSBUaGlzIG1ldGhvZCBzaG91bGQgcmV0dXJuIHRoZSBiYXNlIHJlZ2lzdGVyCisgIC8vLyBhbmQgb2Zmc2V0IHVzZWQgdG8gcmVmZXJlbmNlIGEgZnJhbWUgaW5kZXggbG9jYXRpb24uIFRoZSBvZmZzZXQgaXMKKyAgLy8vIHJldHVybmVkIGRpcmVjdGx5LCBhbmQgdGhlIGJhc2UgcmVnaXN0ZXIgaXMgcmV0dXJuZWQgdmlhIEZyYW1lUmVnLgorICB2aXJ0dWFsIGludCBnZXRGcmFtZUluZGV4UmVmZXJlbmNlKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYsIGludCBGSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCAmRnJhbWVSZWcpIGNvbnN0OworCisgIC8vLyBTYW1lIGFzIFxjIGdldEZyYW1lSW5kZXhSZWZlcmVuY2UsIGV4Y2VwdCB0aGF0IHRoZSBzdGFjayBwb2ludGVyIChhcworICAvLy8gb3Bwb3NlZCB0byB0aGUgZnJhbWUgcG9pbnRlcikgd2lsbCBiZSB0aGUgcHJlZmVycmVkIHZhbHVlIGZvciBccAorICAvLy8gRnJhbWVSZWcuIFRoaXMgaXMgZ2VuZXJhbGx5IHVzZWQgZm9yIGVtaXR0aW5nIHN0YXRlcG9pbnQgb3IgRUggdGFibGVzIHRoYXQKKyAgLy8vIHVzZSBvZmZzZXRzIGZyb20gUlNQLiAgSWYgXHAgSWdub3JlU1BVcGRhdGVzIGlzIHRydWUsIHRoZSByZXR1cm5lZAorICAvLy8gb2Zmc2V0IGlzIG9ubHkgZ3VhcmFudGVlZCB0byBiZSB2YWxpZCB3aXRoIHJlc3BlY3QgdG8gdGhlIHZhbHVlIG9mIFNQIGF0CisgIC8vLyB0aGUgZW5kIG9mIHRoZSBwcm9sb2d1ZS4KKyAgdmlydHVhbCBpbnQgZ2V0RnJhbWVJbmRleFJlZmVyZW5jZVByZWZlclNQKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYsIGludCBGSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkICZGcmFtZVJlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgSWdub3JlU1BVcGRhdGVzKSBjb25zdCB7CisgICAgLy8gQWx3YXlzIHNhZmUgdG8gZGlzcGF0Y2ggdG8gZ2V0RnJhbWVJbmRleFJlZmVyZW5jZS4KKyAgICByZXR1cm4gZ2V0RnJhbWVJbmRleFJlZmVyZW5jZShNRiwgRkksIEZyYW1lUmVnKTsKKyAgfQorCisgIC8vLyBUaGlzIG1ldGhvZCBkZXRlcm1pbmVzIHdoaWNoIG9mIHRoZSByZWdpc3RlcnMgcmVwb3J0ZWQgYnkKKyAgLy8vIFRhcmdldFJlZ2lzdGVySW5mbzo6Z2V0Q2FsbGVlU2F2ZWRSZWdzKCkgc2hvdWxkIGFjdHVhbGx5IGdldCBzYXZlZC4KKyAgLy8vIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGNoZWNrcyBwb3B1bGF0ZXMgdGhlIFxwIFNhdmVkUmVncyBiaXRzZXQgd2l0aAorICAvLy8gYWxsIHJlZ2lzdGVycyB3aGljaCBhcmUgbW9kaWZpZWQgaW4gdGhlIGZ1bmN0aW9uLCB0YXJnZXRzIG1heSBvdmVycmlkZQorICAvLy8gdGhpcyBmdW5jdGlvbiB0byBzYXZlIGFkZGl0aW9uYWwgcmVnaXN0ZXJzLgorICAvLy8gVGhpcyBtZXRob2QgYWxzbyBzZXRzIHVwIHRoZSByZWdpc3RlciBzY2F2ZW5nZXIgZW5zdXJpbmcgdGhlcmUgaXMgYSBmcmVlCisgIC8vLyByZWdpc3RlciBvciBhIGZyYW1laW5kZXggYXZhaWxhYmxlLgorICB2aXJ0dWFsIHZvaWQgZGV0ZXJtaW5lQ2FsbGVlU2F2ZXMoTWFjaGluZUZ1bmN0aW9uICZNRiwgQml0VmVjdG9yICZTYXZlZFJlZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdTY2F2ZW5nZXIgKlJTID0gbnVsbHB0cikgY29uc3Q7CisKKyAgLy8vIHByb2Nlc3NGdW5jdGlvbkJlZm9yZUZyYW1lRmluYWxpemVkIC0gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGltbWVkaWF0ZWx5CisgIC8vLyBiZWZvcmUgdGhlIHNwZWNpZmllZCBmdW5jdGlvbidzIGZyYW1lIGxheW91dCAoTUYuZ2V0RnJhbWVJbmZvKCkpIGlzCisgIC8vLyBmaW5hbGl6ZWQuICBPbmNlIHRoZSBmcmFtZSBpcyBmaW5hbGl6ZWQsIE1PX0ZyYW1lSW5kZXggb3BlcmFuZHMgYXJlCisgIC8vLyByZXBsYWNlZCB3aXRoIGRpcmVjdCBjb25zdGFudHMuICBUaGlzIG1ldGhvZCBpcyBvcHRpb25hbC4KKyAgLy8vCisgIHZpcnR1YWwgdm9pZCBwcm9jZXNzRnVuY3Rpb25CZWZvcmVGcmFtZUZpbmFsaXplZChNYWNoaW5lRnVuY3Rpb24gJk1GLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnU2NhdmVuZ2VyICpSUyA9IG51bGxwdHIpIGNvbnN0IHsKKyAgfQorCisgIHZpcnR1YWwgdW5zaWduZWQgZ2V0V2luRUhQYXJlbnRGcmFtZU9mZnNldChjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKSBjb25zdCB7CisgICAgcmVwb3J0X2ZhdGFsX2Vycm9yKCJXaW5FSCBub3QgaW1wbGVtZW50ZWQgZm9yIHRoaXMgdGFyZ2V0Iik7CisgIH0KKworICAvLy8gVGhpcyBtZXRob2QgaXMgY2FsbGVkIGR1cmluZyBwcm9sb2cvZXBpbG9nIGNvZGUgaW5zZXJ0aW9uIHRvIGVsaW1pbmF0ZQorICAvLy8gY2FsbCBmcmFtZSBzZXR1cCBhbmQgZGVzdHJveSBwc2V1ZG8gaW5zdHJ1Y3Rpb25zIChidXQgb25seSBpZiB0aGUgVGFyZ2V0CisgIC8vLyBpcyB1c2luZyB0aGVtKS4gIEl0IGlzIHJlc3BvbnNpYmxlIGZvciBlbGltaW5hdGluZyB0aGVzZSBpbnN0cnVjdGlvbnMsCisgIC8vLyByZXBsYWNpbmcgdGhlbSB3aXRoIGNvbmNyZXRlIGluc3RydWN0aW9ucy4gIFRoaXMgbWV0aG9kIG5lZWQgb25seSBiZQorICAvLy8gaW1wbGVtZW50ZWQgaWYgdXNpbmcgY2FsbCBmcmFtZSBzZXR1cC9kZXN0cm95IHBzZXVkbyBpbnN0cnVjdGlvbnMuCisgIC8vLyBSZXR1cm5zIGFuIGl0ZXJhdG9yIHBvaW50aW5nIHRvIHRoZSBpbnN0cnVjdGlvbiBhZnRlciB0aGUgcmVwbGFjZWQgb25lLgorICB2aXJ0dWFsIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvcgorICBlbGltaW5hdGVDYWxsRnJhbWVQc2V1ZG9JbnN0cihNYWNoaW5lRnVuY3Rpb24gJk1GLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jayAmTUJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgTUkpIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJDYWxsIEZyYW1lIFBzZXVkbyBJbnN0cnVjdGlvbnMgZG8gbm90IGV4aXN0IG9uIHRoaXMgIgorICAgICAgICAgICAgICAgICAgICAgInRhcmdldCEiKTsKKyAgfQorCisKKyAgLy8vIE9yZGVyIHRoZSBzeW1ib2xzIGluIHRoZSBsb2NhbCBzdGFjayBmcmFtZS4KKyAgLy8vIFRoZSBsaXN0IG9mIG9iamVjdHMgdGhhdCB3ZSB3YW50IHRvIG9yZGVyIGlzIGluIFxwIG9iamVjdHNUb0FsbG9jYXRlIGFzCisgIC8vLyBpbmRpY2VzIGludG8gdGhlIE1hY2hpbmVGcmFtZUluZm8uIFRoZSBhcnJheSBjYW4gYmUgcmVvcmRlcmVkIGluIGFueSB3YXkKKyAgLy8vIHVwb24gcmV0dXJuLiBUaGUgY29udGVudHMgb2YgdGhlIGFycmF5LCBob3dldmVyLCBtYXkgbm90IGJlIG1vZGlmaWVkIChpLmUuCisgIC8vLyBvbmx5IHRoZWlyIG9yZGVyIG1heSBiZSBjaGFuZ2VkKS4KKyAgLy8vIEJ5IGRlZmF1bHQsIGp1c3QgbWFpbnRhaW4gdGhlIG9yaWdpbmFsIG9yZGVyLgorICB2aXJ0dWFsIHZvaWQKKyAgb3JkZXJGcmFtZU9iamVjdHMoY29uc3QgTWFjaGluZUZ1bmN0aW9uICZNRiwKKyAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPGludD4gJm9iamVjdHNUb0FsbG9jYXRlKSBjb25zdCB7CisgIH0KKworICAvLy8gQ2hlY2sgd2hldGhlciBvciBub3QgdGhlIGdpdmVuIFxwIE1CQiBjYW4gYmUgdXNlZCBhcyBhIHByb2xvZ3VlCisgIC8vLyBmb3IgdGhlIHRhcmdldC4KKyAgLy8vIFRoZSBwcm9sb2d1ZSB3aWxsIGJlIGluc2VydGVkIGZpcnN0IGluIHRoaXMgYmFzaWMgYmxvY2suCisgIC8vLyBUaGlzIG1ldGhvZCBpcyB1c2VkIGJ5IHRoZSBzaHJpbmstd3JhcHBpbmcgcGFzcyB0byBkZWNpZGUgaWYKKyAgLy8vIFxwIE1CQiB3aWxsIGJlIGNvcnJlY3RseSBoYW5kbGVkIGJ5IHRoZSB0YXJnZXQuCisgIC8vLyBBcyBzb29uIGFzIHRoZSB0YXJnZXQgZW5hYmxlIHNocmluay13cmFwcGluZyB3aXRob3V0IG92ZXJyaWRpbmcKKyAgLy8vIHRoaXMgbWV0aG9kLCB3ZSBhc3N1bWUgdGhhdCBlYWNoIGJhc2ljIGJsb2NrIGlzIGEgdmFsaWQKKyAgLy8vIHByb2xvZ3VlLgorICB2aXJ0dWFsIGJvb2wgY2FuVXNlQXNQcm9sb2d1ZShjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAmTUJCKSBjb25zdCB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLy8gQ2hlY2sgd2hldGhlciBvciBub3QgdGhlIGdpdmVuIFxwIE1CQiBjYW4gYmUgdXNlZCBhcyBhIGVwaWxvZ3VlCisgIC8vLyBmb3IgdGhlIHRhcmdldC4KKyAgLy8vIFRoZSBlcGlsb2d1ZSB3aWxsIGJlIGluc2VydGVkIGJlZm9yZSB0aGUgZmlyc3QgdGVybWluYXRvciBvZiB0aGF0IGJsb2NrLgorICAvLy8gVGhpcyBtZXRob2QgaXMgdXNlZCBieSB0aGUgc2hyaW5rLXdyYXBwaW5nIHBhc3MgdG8gZGVjaWRlIGlmCisgIC8vLyBccCBNQkIgd2lsbCBiZSBjb3JyZWN0bHkgaGFuZGxlZCBieSB0aGUgdGFyZ2V0LgorICAvLy8gQXMgc29vbiBhcyB0aGUgdGFyZ2V0IGVuYWJsZSBzaHJpbmstd3JhcHBpbmcgd2l0aG91dCBvdmVycmlkaW5nCisgIC8vLyB0aGlzIG1ldGhvZCwgd2UgYXNzdW1lIHRoYXQgZWFjaCBiYXNpYyBibG9jayBpcyBhIHZhbGlkCisgIC8vLyBlcGlsb2d1ZS4KKyAgdmlydHVhbCBib29sIGNhblVzZUFzRXBpbG9ndWUoY29uc3QgTWFjaGluZUJhc2ljQmxvY2sgJk1CQikgY29uc3QgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8vIENoZWNrIGlmIGdpdmVuIGZ1bmN0aW9uIGlzIHNhZmUgZm9yIG5vdCBoYXZpbmcgY2FsbGVlIHNhdmVkIHJlZ2lzdGVycy4KKyAgLy8vIFRoaXMgaXMgdXNlZCB3aGVuIGludGVycHJvY2VkdXJhbCByZWdpc3RlciBhbGxvY2F0aW9uIGlzIGVuYWJsZWQuCisgIHN0YXRpYyBib29sIGlzU2FmZUZvck5vQ1NST3B0KGNvbnN0IEZ1bmN0aW9uICZGKSB7CisgICAgaWYgKCFGLmhhc0xvY2FsTGlua2FnZSgpIHx8IEYuaGFzQWRkcmVzc1Rha2VuKCkgfHwKKyAgICAgICAgIUYuaGFzRm5BdHRyaWJ1dGUoQXR0cmlidXRlOjpOb1JlY3Vyc2UpKQorICAgICAgcmV0dXJuIGZhbHNlOworICAgIC8vIEZ1bmN0aW9uIHNob3VsZCBub3QgYmUgb3B0aW1pemVkIGFzIHRhaWwgY2FsbC4KKyAgICBmb3IgKGNvbnN0IFVzZXIgKlUgOiBGLnVzZXJzKCkpCisgICAgICBpZiAoYXV0byBDUyA9IEltbXV0YWJsZUNhbGxTaXRlKFUpKQorICAgICAgICBpZiAoQ1MuaXNUYWlsQ2FsbCgpKQorICAgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorfTsKKworfSAvLyBFbmQgbGx2bSBuYW1lc3BhY2UKKworI2VuZGlmCmRpZmYgLS1naXQgYS9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vVGFyZ2V0SW5zdHJJbmZvLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vVGFyZ2V0SW5zdHJJbmZvLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWMyYTUzMAotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9UYXJnZXRJbnN0ckluZm8uaApAQCAtMCwwICsxLDE3MTAgQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vVGFyZ2V0SW5zdHJJbmZvLmggLSBJbnN0cnVjdGlvbiBJbmZvIC0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlc2NyaWJlcyB0aGUgdGFyZ2V0IG1hY2hpbmUgaW5zdHJ1Y3Rpb24gc2V0IHRvIHRoZSBjb2RlIGdlbmVyYXRvci4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fVEFSR0VUX1RBUkdFVElOU1RSSU5GT19ICisjZGVmaW5lIExMVk1fVEFSR0VUX1RBUkdFVElOU1RSSU5GT19ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9BcnJheVJlZi5oIgorI2luY2x1ZGUgImxsdm0vQURUL0RlbnNlTWFwLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VNYXBJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvTm9uZS5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lQmFzaWNCbG9jay5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lQ29tYmluZXJQYXR0ZXJuLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVGdW5jdGlvbi5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9NYWNoaW5lSW5zdHIuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUxvb3BJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL01hY2hpbmVPcGVyYW5kLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1BzZXVkb1NvdXJjZVZhbHVlLmgiCisjaW5jbHVkZSAibGx2bS9NQy9NQ0luc3RySW5mby5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9CcmFuY2hQcm9iYWJpbGl0eS5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9FcnJvckhhbmRsaW5nLmgiCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkZGVmPgorI2luY2x1ZGUgPGNzdGRpbnQ+CisjaW5jbHVkZSA8dXRpbGl0eT4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgREZBUGFja2V0aXplcjsKK2NsYXNzIEluc3RySXRpbmVyYXJ5RGF0YTsKK2NsYXNzIExpdmVJbnRlcnZhbHM7CitjbGFzcyBMaXZlVmFyaWFibGVzOworY2xhc3MgTWFjaGluZU1lbU9wZXJhbmQ7CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworY2xhc3MgTUNBc21JbmZvOworY2xhc3MgTUNJbnN0Oworc3RydWN0IE1DU2NoZWRNb2RlbDsKK2NsYXNzIE1vZHVsZTsKK2NsYXNzIFNjaGVkdWxlREFHOworY2xhc3MgU2NoZWR1bGVIYXphcmRSZWNvZ25pemVyOworY2xhc3MgU0ROb2RlOworY2xhc3MgU2VsZWN0aW9uREFHOworY2xhc3MgUmVnU2NhdmVuZ2VyOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJDbGFzczsKK2NsYXNzIFRhcmdldFJlZ2lzdGVySW5mbzsKK2NsYXNzIFRhcmdldFNjaGVkTW9kZWw7CitjbGFzcyBUYXJnZXRTdWJ0YXJnZXRJbmZvOworCit0ZW1wbGF0ZSA8Y2xhc3MgVD4gY2xhc3MgU21hbGxWZWN0b3JJbXBsOworCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8vCisvLy8gVGFyZ2V0SW5zdHJJbmZvIC0gSW50ZXJmYWNlIHRvIGRlc2NyaXB0aW9uIG9mIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gc2V0CisvLy8KK2NsYXNzIFRhcmdldEluc3RySW5mbyA6IHB1YmxpYyBNQ0luc3RySW5mbyB7CitwdWJsaWM6CisgIFRhcmdldEluc3RySW5mbyh1bnNpZ25lZCBDRlNldHVwT3Bjb2RlID0gfjB1LCB1bnNpZ25lZCBDRkRlc3Ryb3lPcGNvZGUgPSB+MHUsCisgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBDYXRjaFJldE9wY29kZSA9IH4wdSwgdW5zaWduZWQgUmV0dXJuT3Bjb2RlID0gfjB1KQorICAgICAgOiBDYWxsRnJhbWVTZXR1cE9wY29kZShDRlNldHVwT3Bjb2RlKSwKKyAgICAgICAgQ2FsbEZyYW1lRGVzdHJveU9wY29kZShDRkRlc3Ryb3lPcGNvZGUpLCBDYXRjaFJldE9wY29kZShDYXRjaFJldE9wY29kZSksCisgICAgICAgIFJldHVybk9wY29kZShSZXR1cm5PcGNvZGUpIHt9CisgIFRhcmdldEluc3RySW5mbyhjb25zdCBUYXJnZXRJbnN0ckluZm8gJikgPSBkZWxldGU7CisgIFRhcmdldEluc3RySW5mbyAmb3BlcmF0b3I9KGNvbnN0IFRhcmdldEluc3RySW5mbyAmKSA9IGRlbGV0ZTsKKyAgdmlydHVhbCB+VGFyZ2V0SW5zdHJJbmZvKCk7CisKKyAgc3RhdGljIGJvb2wgaXNHZW5lcmljT3Bjb2RlKHVuc2lnbmVkIE9wYykgeworICAgIHJldHVybiBPcGMgPD0gVGFyZ2V0T3Bjb2RlOjpHRU5FUklDX09QX0VORDsKKyAgfQorCisgIC8vLyBHaXZlbiBhIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gZGVzY3JpcHRvciwgcmV0dXJucyB0aGUgcmVnaXN0ZXIKKyAgLy8vIGNsYXNzIGNvbnN0cmFpbnQgZm9yIE9wTnVtLCBvciBOVUxMLgorICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpnZXRSZWdDbGFzcyhjb25zdCBNQ0luc3RyRGVzYyAmVElELCB1bnNpZ25lZCBPcE51bSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgaW5zdHJ1Y3Rpb24gaXMgdHJpdmlhbGx5IHJlbWF0ZXJpYWxpemFibGUsIG1lYW5pbmcgaXQKKyAgLy8vIGhhcyBubyBzaWRlIGVmZmVjdHMgYW5kIHJlcXVpcmVzIG5vIG9wZXJhbmRzIHRoYXQgYXJlbid0IGFsd2F5cyBhdmFpbGFibGUuCisgIC8vLyBUaGlzIG1lYW5zIHRoZSBvbmx5IGFsbG93ZWQgdXNlcyBhcmUgY29uc3RhbnRzIGFuZCB1bmFsbG9jYXRhYmxlIHBoeXNpY2FsCisgIC8vLyByZWdpc3RlcnMgc28gdGhhdCB0aGUgaW5zdHJ1Y3Rpb25zIHJlc3VsdCBpcyBpbmRlcGVuZGVudCBvZiB0aGUgcGxhY2UKKyAgLy8vIGluIHRoZSBmdW5jdGlvbi4KKyAgYm9vbCBpc1RyaXZpYWxseVJlTWF0ZXJpYWxpemFibGUoY29uc3QgTWFjaGluZUluc3RyICZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWxpYXNBbmFseXNpcyAqQUEgPSBudWxscHRyKSBjb25zdCB7CisgICAgcmV0dXJuIE1JLmdldE9wY29kZSgpID09IFRhcmdldE9wY29kZTo6SU1QTElDSVRfREVGIHx8CisgICAgICAgICAgIChNSS5nZXREZXNjKCkuaXNSZW1hdGVyaWFsaXphYmxlKCkgJiYKKyAgICAgICAgICAgIChpc1JlYWxseVRyaXZpYWxseVJlTWF0ZXJpYWxpemFibGUoTUksIEFBKSB8fAorICAgICAgICAgICAgIGlzUmVhbGx5VHJpdmlhbGx5UmVNYXRlcmlhbGl6YWJsZUdlbmVyaWMoTUksIEFBKSkpOworICB9CisKK3Byb3RlY3RlZDoKKyAgLy8vIEZvciBpbnN0cnVjdGlvbnMgd2l0aCBvcGNvZGVzIGZvciB3aGljaCB0aGUgTV9SRU1BVEVSSUFMSVpBQkxFIGZsYWcgaXMKKyAgLy8vIHNldCwgdGhpcyBob29rIGxldHMgdGhlIHRhcmdldCBzcGVjaWZ5IHdoZXRoZXIgdGhlIGluc3RydWN0aW9uIGlzIGFjdHVhbGx5CisgIC8vLyB0cml2aWFsbHkgcmVtYXRlcmlhbGl6YWJsZSwgdGFraW5nIGludG8gY29uc2lkZXJhdGlvbiBpdHMgb3BlcmFuZHMuIFRoaXMKKyAgLy8vIHByZWRpY2F0ZSBtdXN0IHJldHVybiBmYWxzZSBpZiB0aGUgaW5zdHJ1Y3Rpb24gaGFzIGFueSBzaWRlIGVmZmVjdHMgb3RoZXIKKyAgLy8vIHRoYW4gcHJvZHVjaW5nIGEgdmFsdWUsIG9yIGlmIGl0IHJlcXVyZXMgYW55IGFkZHJlc3MgcmVnaXN0ZXJzIHRoYXQgYXJlCisgIC8vLyBub3QgYWx3YXlzIGF2YWlsYWJsZS4KKyAgLy8vIFJlcXVpcmVtZW50cyBtdXN0IGJlIGNoZWNrIGFzIHN0YXRlZCBpbiBpc1RyaXZpYWxseVJlTWF0ZXJpYWxpemFibGUoKSAuCisgIHZpcnR1YWwgYm9vbCBpc1JlYWxseVRyaXZpYWxseVJlTWF0ZXJpYWxpemFibGUoY29uc3QgTWFjaGluZUluc3RyICZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbGlhc0FuYWx5c2lzICpBQSkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBUaGlzIG1ldGhvZCBjb21tdXRlcyB0aGUgb3BlcmFuZHMgb2YgdGhlIGdpdmVuIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gTUkuCisgIC8vLyBUaGUgb3BlcmFuZHMgdG8gYmUgY29tbXV0ZWQgYXJlIHNwZWNpZmllZCBieSB0aGVpciBpbmRpY2VzIE9wSWR4MSBhbmQKKyAgLy8vIE9wSWR4Mi4KKyAgLy8vCisgIC8vLyBJZiBhIHRhcmdldCBoYXMgYW55IGluc3RydWN0aW9ucyB0aGF0IGFyZSBjb21tdXRhYmxlIGJ1dCByZXF1aXJlCisgIC8vLyBjb252ZXJ0aW5nIHRvIGRpZmZlcmVudCBpbnN0cnVjdGlvbnMgb3IgbWFraW5nIG5vbi10cml2aWFsIGNoYW5nZXMKKyAgLy8vIHRvIGNvbW11dGUgdGhlbSwgdGhpcyBtZXRob2QgY2FuIGJlIG92ZXJsb2FkZWQgdG8gZG8gdGhhdC4KKyAgLy8vIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHNpbXBseSBzd2FwcyB0aGUgY29tbXV0YWJsZSBvcGVyYW5kcy4KKyAgLy8vCisgIC8vLyBJZiBOZXdNSSBpcyBmYWxzZSwgTUkgaXMgbW9kaWZpZWQgaW4gcGxhY2UgYW5kIHJldHVybmVkOyBvdGhlcndpc2UsIGEKKyAgLy8vIG5ldyBtYWNoaW5lIGluc3RydWN0aW9uIGlzIGNyZWF0ZWQgYW5kIHJldHVybmVkLgorICAvLy8KKyAgLy8vIERvIG5vdCBjYWxsIHRoaXMgbWV0aG9kIGZvciBhIG5vbi1jb21tdXRhYmxlIGluc3RydWN0aW9uLgorICAvLy8gRXZlbiB0aG91Z2ggdGhlIGluc3RydWN0aW9uIGlzIGNvbW11dGFibGUsIHRoZSBtZXRob2QgbWF5IHN0aWxsCisgIC8vLyBmYWlsIHRvIGNvbW11dGUgdGhlIG9wZXJhbmRzLCBudWxsIHBvaW50ZXIgaXMgcmV0dXJuZWQgaW4gc3VjaCBjYXNlcy4KKyAgdmlydHVhbCBNYWNoaW5lSW5zdHIgKmNvbW11dGVJbnN0cnVjdGlvbkltcGwoTWFjaGluZUluc3RyICZNSSwgYm9vbCBOZXdNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgT3BJZHgxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBPcElkeDIpIGNvbnN0OworCisgIC8vLyBBc3NpZ25zIHRoZSAoQ29tbXV0YWJsZU9wSWR4MSwgQ29tbXV0YWJsZU9wSWR4MikgcGFpciBvZiBjb21tdXRhYmxlCisgIC8vLyBvcGVyYW5kIGluZGljZXMgdG8gKFJlc3VsdElkeDEsIFJlc3VsdElkeDIpLgorICAvLy8gT25lIG9yIGJvdGggaW5wdXQgdmFsdWVzIG9mIHRoZSBwYWlyOiAoUmVzdWx0SWR4MSwgUmVzdWx0SWR4MikgbWF5IGJlCisgIC8vLyBwcmVkZWZpbmVkIHRvIHNvbWUgaW5kaWNlcyBvciBiZSB1bmRlZmluZWQgKGRlc2lnbmF0ZWQgYnkgdGhlIHNwZWNpYWwKKyAgLy8vIHZhbHVlICdDb21tdXRlQW55T3BlcmFuZEluZGV4JykuCisgIC8vLyBUaGUgcHJlZGVmaW5lZCByZXN1bHQgaW5kaWNlcyBjYW5ub3QgYmUgcmUtZGVmaW5lZC4KKyAgLy8vIFRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgaWZmIGFmdGVyIHRoZSByZXN1bHQgcGFpciByZWRlZmluaXRpb24KKyAgLy8vIHRoZSBmaXhlZCByZXN1bHQgcGFpciBpcyBlcXVhbCB0byBvciBlcXVpdmFsZW50IHRvIHRoZSBzb3VyY2UgcGFpciBvZgorICAvLy8gaW5kaWNlczogKENvbW11dGFibGVPcElkeDEsIENvbW11dGFibGVPcElkeDIpLiBJdCBpcyBhc3N1bWVkIGhlcmUgdGhhdAorICAvLy8gdGhlIHBhaXJzICh4LHkpIGFuZCAoeSx4KSBhcmUgZXF1aXZhbGVudC4KKyAgc3RhdGljIGJvb2wgZml4Q29tbXV0ZWRPcEluZGljZXModW5zaWduZWQgJlJlc3VsdElkeDEsIHVuc2lnbmVkICZSZXN1bHRJZHgyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBDb21tdXRhYmxlT3BJZHgxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBDb21tdXRhYmxlT3BJZHgyKTsKKworcHJpdmF0ZToKKyAgLy8vIEZvciBpbnN0cnVjdGlvbnMgd2l0aCBvcGNvZGVzIGZvciB3aGljaCB0aGUgTV9SRU1BVEVSSUFMSVpBQkxFIGZsYWcgaXMKKyAgLy8vIHNldCBhbmQgdGhlIHRhcmdldCBob29rIGlzUmVhbGx5VHJpdmlhbGx5UmVNYXRlcmlhbGl6YWJsZSByZXR1cm5zIGZhbHNlLAorICAvLy8gdGhpcyBmdW5jdGlvbiBkb2VzIHRhcmdldC1pbmRlcGVuZGVudCB0ZXN0cyB0byBkZXRlcm1pbmUgaWYgdGhlCisgIC8vLyBpbnN0cnVjdGlvbiBpcyByZWFsbHkgdHJpdmlhbGx5IHJlbWF0ZXJpYWxpemFibGUuCisgIGJvb2wgaXNSZWFsbHlUcml2aWFsbHlSZU1hdGVyaWFsaXphYmxlR2VuZXJpYyhjb25zdCBNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWxpYXNBbmFseXNpcyAqQUEpIGNvbnN0OworCitwdWJsaWM6CisgIC8vLyBUaGVzZSBtZXRob2RzIHJldHVybiB0aGUgb3Bjb2RlIG9mIHRoZSBmcmFtZSBzZXR1cC9kZXN0cm95IGluc3RydWN0aW9ucworICAvLy8gaWYgdGhleSBleGlzdCAoLTEgb3RoZXJ3aXNlKS4gIFNvbWUgdGFyZ2V0cyB1c2UgcHNldWRvIGluc3RydWN0aW9ucyBpbgorICAvLy8gb3JkZXIgdG8gYWJzdHJhY3QgYXdheSB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG9wZXJhdGluZyB3aXRoIGEgZnJhbWUKKyAgLy8vIHBvaW50ZXIgYW5kIG9wZXJhdGluZyB3aXRob3V0LCB0aHJvdWdoIHRoZSB1c2Ugb2YgdGhlc2UgdHdvIGluc3RydWN0aW9ucy4KKyAgLy8vCisgIHVuc2lnbmVkIGdldENhbGxGcmFtZVNldHVwT3Bjb2RlKCkgY29uc3QgeyByZXR1cm4gQ2FsbEZyYW1lU2V0dXBPcGNvZGU7IH0KKyAgdW5zaWduZWQgZ2V0Q2FsbEZyYW1lRGVzdHJveU9wY29kZSgpIGNvbnN0IHsgcmV0dXJuIENhbGxGcmFtZURlc3Ryb3lPcGNvZGU7IH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBhcmd1bWVudCBpcyBhIGZyYW1lIHBzZXVkbyBpbnN0cnVjdGlvbi4KKyAgYm9vbCBpc0ZyYW1lSW5zdHIoY29uc3QgTWFjaGluZUluc3RyICZJKSBjb25zdCB7CisgICAgcmV0dXJuIEkuZ2V0T3Bjb2RlKCkgPT0gZ2V0Q2FsbEZyYW1lU2V0dXBPcGNvZGUoKSB8fAorICAgICAgICAgICBJLmdldE9wY29kZSgpID09IGdldENhbGxGcmFtZURlc3Ryb3lPcGNvZGUoKTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIGFyZ3VtZW50IGlzIGEgZnJhbWUgc2V0dXAgcHNldWRvIGluc3RydWN0aW9uLgorICBib29sIGlzRnJhbWVTZXR1cChjb25zdCBNYWNoaW5lSW5zdHIgJkkpIGNvbnN0IHsKKyAgICByZXR1cm4gSS5nZXRPcGNvZGUoKSA9PSBnZXRDYWxsRnJhbWVTZXR1cE9wY29kZSgpOworICB9CisKKyAgLy8vIFJldHVybnMgc2l6ZSBvZiB0aGUgZnJhbWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBmcmFtZSBpbnN0cnVjdGlvbi4KKyAgLy8vIEZvciBmcmFtZSBzZXR1cCBpbnN0cnVjdGlvbiB0aGlzIGlzIGZyYW1lIHRoYXQgaXMgc2V0IHVwIHNwYWNlIHNldCB1cAorICAvLy8gYWZ0ZXIgdGhlIGluc3RydWN0aW9uLiBGb3IgZnJhbWUgZGVzdHJveSBpbnN0cnVjdGlvbiB0aGlzIGlzIHRoZSBmcmFtZQorICAvLy8gZnJlZWQgYnkgdGhlIGNhbGxlci4KKyAgLy8vIE5vdGUsIGluIHNvbWUgY2FzZXMgYSBjYWxsIGZyYW1lIChvciBhIHBhcnQgb2YgaXQpIG1heSBiZSBwcmVwYXJlZCBwcmlvcgorICAvLy8gdG8gdGhlIGZyYW1lIHNldHVwIGluc3RydWN0aW9uLiBJdCBvY2N1cnMgaW4gdGhlIGNhbGxzIHRoYXQgaW52b2x2ZQorICAvLy8gaW5hbGxvY2EgYXJndW1lbnRzLiBUaGlzIGZ1bmN0aW9uIHJlcG9ydHMgb25seSB0aGUgc2l6ZSBvZiB0aGUgZnJhbWUgcGFydAorICAvLy8gdGhhdCBpcyBzZXQgdXAgYmV0d2VlbiB0aGUgZnJhbWUgc2V0dXAgYW5kIGRlc3Ryb3kgcHNldWRvIGluc3RydWN0aW9ucy4KKyAgaW50NjRfdCBnZXRGcmFtZVNpemUoY29uc3QgTWFjaGluZUluc3RyICZJKSBjb25zdCB7CisgICAgYXNzZXJ0KGlzRnJhbWVJbnN0cihJKSAmJiAiTm90IGEgZnJhbWUgaW5zdHJ1Y3Rpb24iKTsKKyAgICBhc3NlcnQoSS5nZXRPcGVyYW5kKDApLmdldEltbSgpID49IDApOworICAgIHJldHVybiBJLmdldE9wZXJhbmQoMCkuZ2V0SW1tKCk7CisgIH0KKworICAvLy8gUmV0dXJucyB0aGUgdG90YWwgZnJhbWUgc2l6ZSwgd2hpY2ggaXMgbWFkZSB1cCBvZiB0aGUgc3BhY2Ugc2V0IHVwIGluc2lkZQorICAvLy8gdGhlIHBhaXIgb2YgZnJhbWUgc3RhcnQtc3RvcCBpbnN0cnVjdGlvbnMgYW5kIHRoZSBzcGFjZSB0aGF0IGlzIHNldCB1cAorICAvLy8gcHJpb3IgdG8gdGhlIHBhaXIuCisgIGludDY0X3QgZ2V0RnJhbWVUb3RhbFNpemUoY29uc3QgTWFjaGluZUluc3RyICZJKSBjb25zdCB7CisgICAgaWYgKGlzRnJhbWVTZXR1cChJKSkgeworICAgICAgYXNzZXJ0KEkuZ2V0T3BlcmFuZCgxKS5nZXRJbW0oKSA+PSAwICYmCisgICAgICAgICAgICAgIkZyYW1lIHNpemUgbXVzdCBub3QgYmUgbmVnYXRpdmUiKTsKKyAgICAgIHJldHVybiBnZXRGcmFtZVNpemUoSSkgKyBJLmdldE9wZXJhbmQoMSkuZ2V0SW1tKCk7CisgICAgfQorICAgIHJldHVybiBnZXRGcmFtZVNpemUoSSk7CisgIH0KKworICB1bnNpZ25lZCBnZXRDYXRjaFJldHVybk9wY29kZSgpIGNvbnN0IHsgcmV0dXJuIENhdGNoUmV0T3Bjb2RlOyB9CisgIHVuc2lnbmVkIGdldFJldHVybk9wY29kZSgpIGNvbnN0IHsgcmV0dXJuIFJldHVybk9wY29kZTsgfQorCisgIC8vLyBSZXR1cm5zIHRoZSBhY3R1YWwgc3RhY2sgcG9pbnRlciBhZGp1c3RtZW50IG1hZGUgYnkgYW4gaW5zdHJ1Y3Rpb24KKyAgLy8vIGFzIHBhcnQgb2YgYSBjYWxsIHNlcXVlbmNlLiBCeSBkZWZhdWx0LCBvbmx5IGNhbGwgZnJhbWUgc2V0dXAvZGVzdHJveQorICAvLy8gaW5zdHJ1Y3Rpb25zIGFkanVzdCB0aGUgc3RhY2ssIGJ1dCB0YXJnZXRzIG1heSB3YW50IHRvIG92ZXJyaWRlIHRoaXMKKyAgLy8vIHRvIGVuYWJsZSBtb3JlIGZpbmUtZ3JhaW5lZCBhZGp1c3RtZW50LCBvciBhZGp1c3QgYnkgYSBkaWZmZXJlbnQgdmFsdWUuCisgIHZpcnR1YWwgaW50IGdldFNQQWRqdXN0KGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgaW5zdHJ1Y3Rpb24gaXMgYSAiY29hbGVzY2FibGUiIGV4dGVuc2lvbiBpbnN0cnVjdGlvbi4KKyAgLy8vIFRoYXQgaXMsIGl0J3MgbGlrZSBhIGNvcHkgd2hlcmUgaXQncyBsZWdhbCBmb3IgdGhlIHNvdXJjZSB0byBvdmVybGFwIHRoZQorICAvLy8gZGVzdGluYXRpb24uIGUuZy4gWDg2OjpNT1ZTWDY0cnIzMi4gSWYgdGhpcyByZXR1cm5zIHRydWUsIHRoZW4gaXQncworICAvLy8gZXhwZWN0ZWQgdGhlIHByZS1leHRlbnNpb24gdmFsdWUgaXMgYXZhaWxhYmxlIGFzIGEgc3VicmVnIG9mIHRoZSByZXN1bHQKKyAgLy8vIHJlZ2lzdGVyLiBUaGlzIGFsc28gcmV0dXJucyB0aGUgc3ViLXJlZ2lzdGVyIGluZGV4IGluIFN1YklkeC4KKyAgdmlydHVhbCBib29sIGlzQ29hbGVzY2FibGVFeHRJbnN0cihjb25zdCBNYWNoaW5lSW5zdHIgJk1JLCB1bnNpZ25lZCAmU3JjUmVnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkICZEc3RSZWcsIHVuc2lnbmVkICZTdWJJZHgpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gSWYgdGhlIHNwZWNpZmllZCBtYWNoaW5lIGluc3RydWN0aW9uIGlzIGEgZGlyZWN0CisgIC8vLyBsb2FkIGZyb20gYSBzdGFjayBzbG90LCByZXR1cm4gdGhlIHZpcnR1YWwgb3IgcGh5c2ljYWwgcmVnaXN0ZXIgbnVtYmVyIG9mCisgIC8vLyB0aGUgZGVzdGluYXRpb24gYWxvbmcgd2l0aCB0aGUgRnJhbWVJbmRleCBvZiB0aGUgbG9hZGVkIHN0YWNrIHNsb3QuICBJZgorICAvLy8gbm90LCByZXR1cm4gMC4gIFRoaXMgcHJlZGljYXRlIG11c3QgcmV0dXJuIDAgaWYgdGhlIGluc3RydWN0aW9uIGhhcworICAvLy8gYW55IHNpZGUgZWZmZWN0cyBvdGhlciB0aGFuIGxvYWRpbmcgZnJvbSB0aGUgc3RhY2sgc2xvdC4KKyAgdmlydHVhbCB1bnNpZ25lZCBpc0xvYWRGcm9tU3RhY2tTbG90KGNvbnN0IE1hY2hpbmVJbnN0ciAmTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgJkZyYW1lSW5kZXgpIGNvbnN0IHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIC8vLyBDaGVjayBmb3IgcG9zdC1mcmFtZSBwdHIgZWxpbWluYXRpb24gc3RhY2sgbG9jYXRpb25zIGFzIHdlbGwuCisgIC8vLyBUaGlzIHVzZXMgYSBoZXVyaXN0aWMgc28gaXQgaXNuJ3QgcmVsaWFibGUgZm9yIGNvcnJlY3RuZXNzLgorICB2aXJ0dWFsIHVuc2lnbmVkIGlzTG9hZEZyb21TdGFja1Nsb3RQb3N0RkUoY29uc3QgTWFjaGluZUluc3RyICZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAmRnJhbWVJbmRleCkgY29uc3QgeworICAgIHJldHVybiAwOworICB9CisKKyAgLy8vIElmIHRoZSBzcGVjaWZpZWQgbWFjaGluZSBpbnN0cnVjdGlvbiBoYXMgYSBsb2FkIGZyb20gYSBzdGFjayBzbG90LAorICAvLy8gcmV0dXJuIHRydWUgYWxvbmcgd2l0aCB0aGUgRnJhbWVJbmRleCBvZiB0aGUgbG9hZGVkIHN0YWNrIHNsb3QgYW5kIHRoZQorICAvLy8gbWFjaGluZSBtZW0gb3BlcmFuZCBjb250YWluaW5nIHRoZSByZWZlcmVuY2UuCisgIC8vLyBJZiBub3QsIHJldHVybiBmYWxzZS4gIFVubGlrZSBpc0xvYWRGcm9tU3RhY2tTbG90LCB0aGlzIHJldHVybnMgdHJ1ZSBmb3IKKyAgLy8vIGFueSBpbnN0cnVjdGlvbnMgdGhhdCBsb2FkcyBmcm9tIHRoZSBzdGFjay4gIFRoaXMgaXMganVzdCBhIGhpbnQsIGFzIHNvbWUKKyAgLy8vIGNhc2VzIG1heSBiZSBtaXNzZWQuCisgIHZpcnR1YWwgYm9vbCBoYXNMb2FkRnJvbVN0YWNrU2xvdChjb25zdCBNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZU1lbU9wZXJhbmQgKiZNTU8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgJkZyYW1lSW5kZXgpIGNvbnN0OworCisgIC8vLyBJZiB0aGUgc3BlY2lmaWVkIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gaXMgYSBkaXJlY3QKKyAgLy8vIHN0b3JlIHRvIGEgc3RhY2sgc2xvdCwgcmV0dXJuIHRoZSB2aXJ0dWFsIG9yIHBoeXNpY2FsIHJlZ2lzdGVyIG51bWJlciBvZgorICAvLy8gdGhlIHNvdXJjZSByZWcgYWxvbmcgd2l0aCB0aGUgRnJhbWVJbmRleCBvZiB0aGUgbG9hZGVkIHN0YWNrIHNsb3QuICBJZgorICAvLy8gbm90LCByZXR1cm4gMC4gIFRoaXMgcHJlZGljYXRlIG11c3QgcmV0dXJuIDAgaWYgdGhlIGluc3RydWN0aW9uIGhhcworICAvLy8gYW55IHNpZGUgZWZmZWN0cyBvdGhlciB0aGFuIHN0b3JpbmcgdG8gdGhlIHN0YWNrIHNsb3QuCisgIHZpcnR1YWwgdW5zaWduZWQgaXNTdG9yZVRvU3RhY2tTbG90KGNvbnN0IE1hY2hpbmVJbnN0ciAmTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAmRnJhbWVJbmRleCkgY29uc3QgeworICAgIHJldHVybiAwOworICB9CisKKyAgLy8vIENoZWNrIGZvciBwb3N0LWZyYW1lIHB0ciBlbGltaW5hdGlvbiBzdGFjayBsb2NhdGlvbnMgYXMgd2VsbC4KKyAgLy8vIFRoaXMgdXNlcyBhIGhldXJpc3RpYywgc28gaXQgaXNuJ3QgcmVsaWFibGUgZm9yIGNvcnJlY3RuZXNzLgorICB2aXJ0dWFsIHVuc2lnbmVkIGlzU3RvcmVUb1N0YWNrU2xvdFBvc3RGRShjb25zdCBNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgJkZyYW1lSW5kZXgpIGNvbnN0IHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIC8vLyBJZiB0aGUgc3BlY2lmaWVkIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gaGFzIGEgc3RvcmUgdG8gYSBzdGFjayBzbG90LAorICAvLy8gcmV0dXJuIHRydWUgYWxvbmcgd2l0aCB0aGUgRnJhbWVJbmRleCBvZiB0aGUgbG9hZGVkIHN0YWNrIHNsb3QgYW5kIHRoZQorICAvLy8gbWFjaGluZSBtZW0gb3BlcmFuZCBjb250YWluaW5nIHRoZSByZWZlcmVuY2UuCisgIC8vLyBJZiBub3QsIHJldHVybiBmYWxzZS4gIFVubGlrZSBpc1N0b3JlVG9TdGFja1Nsb3QsCisgIC8vLyB0aGlzIHJldHVybnMgdHJ1ZSBmb3IgYW55IGluc3RydWN0aW9ucyB0aGF0IHN0b3JlcyB0byB0aGUKKyAgLy8vIHN0YWNrLiAgVGhpcyBpcyBqdXN0IGEgaGludCwgYXMgc29tZSBjYXNlcyBtYXkgYmUgbWlzc2VkLgorICB2aXJ0dWFsIGJvb2wgaGFzU3RvcmVUb1N0YWNrU2xvdChjb25zdCBNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lTWVtT3BlcmFuZCAqJk1NTywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICZGcmFtZUluZGV4KSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCBtYWNoaW5lIGluc3RydWN0aW9uCisgIC8vLyBpcyBhIGNvcHkgb2Ygb25lIHN0YWNrIHNsb3QgdG8gYW5vdGhlciBhbmQgaGFzIG5vIG90aGVyIGVmZmVjdC4KKyAgLy8vIFByb3ZpZGUgdGhlIGlkZW50aXR5IG9mIHRoZSB0d28gZnJhbWUgaW5kaWNlcy4KKyAgdmlydHVhbCBib29sIGlzU3RhY2tTbG90Q29weShjb25zdCBNYWNoaW5lSW5zdHIgJk1JLCBpbnQgJkRlc3RGcmFtZUluZGV4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAmU3JjRnJhbWVJbmRleCkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBDb21wdXRlIHRoZSBzaXplIGluIGJ5dGVzIGFuZCBvZmZzZXQgd2l0aGluIGEgc3RhY2sgc2xvdCBvZiBhIHNwaWxsZWQKKyAgLy8vIHJlZ2lzdGVyIG9yIHN1YnJlZ2lzdGVyLgorICAvLy8KKyAgLy8vIFxwYXJhbSBbb3V0XSBTaXplIGluIGJ5dGVzIG9mIHRoZSBzcGlsbGVkIHZhbHVlLgorICAvLy8gXHBhcmFtIFtvdXRdIE9mZnNldCBpbiBieXRlcyB3aXRoaW4gdGhlIHN0YWNrIHNsb3QuCisgIC8vLyBccmV0dXJucyB0cnVlIGlmIGJvdGggU2l6ZSBhbmQgT2Zmc2V0IGFyZSBzdWNjZXNzZnVsbHkgY29tcHV0ZWQuCisgIC8vLworICAvLy8gTm90IGFsbCBzdWJyZWdpc3RlcnMgaGF2ZSBjb21wdXRhYmxlIHNwaWxsIHNsb3RzLiBGb3IgZXhhbXBsZSwKKyAgLy8vIHN1YnJlZ2lzdGVycyByZWdpc3RlcnMgbWF5IG5vdCBiZSBieXRlLXNpemVkLCBhbmQgYSBwYWlyIG9mIGRpc2NvbnRpZ3VvdXMKKyAgLy8vIHN1YnJlZ2lzdGVycyBoYXMgbm8gc2luZ2xlIG9mZnNldC4KKyAgLy8vCisgIC8vLyBUYXJnZXRzIHdpdGggbm9udHJpdmlhbCBiaWdlbmRpYW4gaW1wbGVtZW50YXRpb25zIG1heSBuZWVkIHRvIG92ZXJyaWRlCisgIC8vLyB0aGlzLCBwYXJ0aWN1bGFybHkgdG8gc3VwcG9ydCBzcGlsbGVkIHZlY3RvciByZWdpc3RlcnMuCisgIHZpcnR1YWwgYm9vbCBnZXRTdGFja1Nsb3RSYW5nZShjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQywgdW5zaWduZWQgU3ViSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgJlNpemUsIHVuc2lnbmVkICZPZmZzZXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKSBjb25zdDsKKworICAvLy8gUmV0dXJucyB0aGUgc2l6ZSBpbiBieXRlcyBvZiB0aGUgc3BlY2lmaWVkIE1hY2hpbmVJbnN0ciwgb3IgfjBVCisgIC8vLyB3aGVuIHRoaXMgZnVuY3Rpb24gaXMgbm90IGltcGxlbWVudGVkIGJ5IGEgdGFyZ2V0LgorICB2aXJ0dWFsIHVuc2lnbmVkIGdldEluc3RTaXplSW5CeXRlcyhjb25zdCBNYWNoaW5lSW5zdHIgJk1JKSBjb25zdCB7CisgICAgcmV0dXJuIH4wVTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgaW5zdHJ1Y3Rpb24gaXMgYXMgY2hlYXAgYXMgYSBtb3ZlIGluc3RydWN0aW9uLgorICAvLy8KKyAgLy8vIFRhcmdldHMgZm9yIGRpZmZlcmVudCBhcmNocyBuZWVkIHRvIG92ZXJyaWRlIHRoaXMsIGFuZCBkaWZmZXJlbnQKKyAgLy8vIG1pY3JvLWFyY2hpdGVjdHVyZXMgY2FuIGFsc28gYmUgZmluZWx5IHR1bmVkIGluc2lkZS4KKyAgdmlydHVhbCBib29sIGlzQXNDaGVhcEFzQU1vdmUoY29uc3QgTWFjaGluZUluc3RyICZNSSkgY29uc3QgeworICAgIHJldHVybiBNSS5pc0FzQ2hlYXBBc0FNb3ZlKCk7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIGluc3RydWN0aW9uIHNob3VsZCBiZSBzdW5rIGJ5IE1hY2hpbmVTaW5rLgorICAvLy8KKyAgLy8vIE1hY2hpbmVTaW5rIGRldGVybWluZXMgb24gaXRzIG93biB3aGV0aGVyIHRoZSBpbnN0cnVjdGlvbiBpcyBzYWZlIHRvIHNpbms7CisgIC8vLyB0aGlzIGdpdmVzIHRoZSB0YXJnZXQgYSBob29rIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IGJlaGF2aW9yIHdpdGggcmVnYXJkcworICAvLy8gdG8gd2hpY2ggaW5zdHJ1Y3Rpb25zIHNob3VsZCBiZSBzdW5rLgorICB2aXJ0dWFsIGJvb2wgc2hvdWxkU2luayhjb25zdCBNYWNoaW5lSW5zdHIgJk1JKSBjb25zdCB7IHJldHVybiB0cnVlOyB9CisKKyAgLy8vIFJlLWlzc3VlIHRoZSBzcGVjaWZpZWQgJ29yaWdpbmFsJyBpbnN0cnVjdGlvbiBhdCB0aGUKKyAgLy8vIHNwZWNpZmljIGxvY2F0aW9uIHRhcmdldGluZyBhIG5ldyBkZXN0aW5hdGlvbiByZWdpc3Rlci4KKyAgLy8vIFRoZSByZWdpc3RlciBpbiBPcmlnLT5nZXRPcGVyYW5kKDApLmdldFJlZygpIHdpbGwgYmUgc3Vic3RpdHV0ZWQgYnkKKyAgLy8vIERlc3RSZWc6U3ViSWR4LiBBbnkgZXhpc3Rpbmcgc3VicmVnIGluZGV4IGlzIHByZXNlcnZlZCBvciBjb21wb3NlZCB3aXRoCisgIC8vLyBTdWJJZHguCisgIHZpcnR1YWwgdm9pZCByZU1hdGVyaWFsaXplKE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBNSSwgdW5zaWduZWQgRGVzdFJlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgU3ViSWR4LCBjb25zdCBNYWNoaW5lSW5zdHIgJk9yaWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAmVFJJKSBjb25zdDsKKworICAvLy8gXGJyaWVmIENsb25lcyBpbnN0cnVjdGlvbiBvciB0aGUgd2hvbGUgaW5zdHJ1Y3Rpb24gYnVuZGxlIFxwIE9yaWcgYW5kCisgIC8vLyBpbnNlcnQgaW50byBccCBNQkIgYmVmb3JlIFxwIEluc2VydEJlZm9yZS4gVGhlIHRhcmdldCBtYXkgdXBkYXRlIG9wZXJhbmRzCisgIC8vLyB0aGF0IGFyZSByZXF1aXJlZCB0byBiZSB1bmlxdWUuCisgIC8vLworICAvLy8gXHAgT3JpZyBtdXN0IG5vdCByZXR1cm4gdHJ1ZSBmb3IgTWFjaGluZUluc3RyOjppc05vdER1cGxpY2FibGUoKS4KKyAgdmlydHVhbCBNYWNoaW5lSW5zdHIgJmR1cGxpY2F0ZShNYWNoaW5lQmFzaWNCbG9jayAmTUJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBJbnNlcnRCZWZvcmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUluc3RyICZPcmlnKSBjb25zdDsKKworICAvLy8gVGhpcyBtZXRob2QgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSB0YXJnZXRzIHRoYXQKKyAgLy8vIHNldCB0aGUgTV9DT05WRVJUSUJMRV9UT18zX0FERFIgZmxhZy4gIFdoZW4gdGhpcyBmbGFnIGlzIHNldCwgdGhlIHRhcmdldAorICAvLy8gbWF5IGJlIGFibGUgdG8gY29udmVydCBhIHR3by1hZGRyZXNzIGluc3RydWN0aW9uIGludG8gb25lIG9yIG1vcmUgdHJ1ZQorICAvLy8gdGhyZWUtYWRkcmVzcyBpbnN0cnVjdGlvbnMgb24gZGVtYW5kLiAgVGhpcyBhbGxvd3MgdGhlIFg4NiB0YXJnZXQgKGZvcgorICAvLy8gZXhhbXBsZSkgdG8gY29udmVydCBBREQgYW5kIFNITCBpbnN0cnVjdGlvbnMgaW50byBMRUEgaW5zdHJ1Y3Rpb25zIGlmIHRoZXkKKyAgLy8vIHdvdWxkIHJlcXVpcmUgcmVnaXN0ZXIgY29waWVzIGR1ZSB0byB0d28tYWRkcmVzc25lc3MuCisgIC8vLworICAvLy8gVGhpcyBtZXRob2QgcmV0dXJucyBhIG51bGwgcG9pbnRlciBpZiB0aGUgdHJhbnNmb3JtYXRpb24gY2Fubm90IGJlCisgIC8vLyBwZXJmb3JtZWQsIG90aGVyd2lzZSBpdCByZXR1cm5zIHRoZSBsYXN0IG5ldyBpbnN0cnVjdGlvbi4KKyAgLy8vCisgIHZpcnR1YWwgTWFjaGluZUluc3RyICpjb252ZXJ0VG9UaHJlZUFkZHJlc3MoTWFjaGluZUZ1bmN0aW9uOjppdGVyYXRvciAmTUZJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVJbnN0ciAmTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGl2ZVZhcmlhYmxlcyAqTFYpIGNvbnN0IHsKKyAgICByZXR1cm4gbnVsbHB0cjsKKyAgfQorCisgIC8vIFRoaXMgY29uc3RhbnQgY2FuIGJlIHVzZWQgYXMgYW4gaW5wdXQgdmFsdWUgb2Ygb3BlcmFuZCBpbmRleCBwYXNzZWQgdG8KKyAgLy8gdGhlIG1ldGhvZCBmaW5kQ29tbXV0ZWRPcEluZGljZXMoKSB0byB0ZWxsIHRoZSBtZXRob2QgdGhhdCB0aGUKKyAgLy8gY29ycmVzcG9uZGluZyBvcGVyYW5kIGluZGV4IGlzIG5vdCBwcmUtZGVmaW5lZCBhbmQgdGhhdCB0aGUgbWV0aG9kCisgIC8vIGNhbiBwaWNrIGFueSBjb21tdXRhYmxlIG9wZXJhbmQuCisgIHN0YXRpYyBjb25zdCB1bnNpZ25lZCBDb21tdXRlQW55T3BlcmFuZEluZGV4ID0gfjBVOworCisgIC8vLyBUaGlzIG1ldGhvZCBjb21tdXRlcyB0aGUgb3BlcmFuZHMgb2YgdGhlIGdpdmVuIG1hY2hpbmUgaW5zdHJ1Y3Rpb24gTUkuCisgIC8vLworICAvLy8gVGhlIG9wZXJhbmRzIHRvIGJlIGNvbW11dGVkIGFyZSBzcGVjaWZpZWQgYnkgdGhlaXIgaW5kaWNlcyBPcElkeDEgYW5kCisgIC8vLyBPcElkeDIuIE9wSWR4MSBhbmQgT3BJZHgyIGFyZ3VtZW50cyBtYXkgYmUgc2V0IHRvIGEgc3BlY2lhbCB2YWx1ZQorICAvLy8gJ0NvbW11dGVBbnlPcGVyYW5kSW5kZXgnLCB3aGljaCBtZWFucyB0aGF0IHRoZSBtZXRob2QgaXMgZnJlZSB0byBjaG9vc2UKKyAgLy8vIGFueSBhcmJpdHJhcmlseSBjaG9zZW4gY29tbXV0YWJsZSBvcGVyYW5kLiBJZiBib3RoIGFyZ3VtZW50cyBhcmUgc2V0IHRvCisgIC8vLyAnQ29tbXV0ZUFueU9wZXJhbmRJbmRleCcgdGhlbiB0aGUgbWV0aG9kIGxvb2tzIGZvciAyIGRpZmZlcmVudCBjb21tdXRhYmxlCisgIC8vLyBvcGVyYW5kczsgdGhlbiBjb21tdXRlcyB0aGVtIGlmIHN1Y2ggb3BlcmFuZHMgY291bGQgYmUgZm91bmQuCisgIC8vLworICAvLy8gSWYgTmV3TUkgaXMgZmFsc2UsIE1JIGlzIG1vZGlmaWVkIGluIHBsYWNlIGFuZCByZXR1cm5lZDsgb3RoZXJ3aXNlLCBhCisgIC8vLyBuZXcgbWFjaGluZSBpbnN0cnVjdGlvbiBpcyBjcmVhdGVkIGFuZCByZXR1cm5lZC4KKyAgLy8vCisgIC8vLyBEbyBub3QgY2FsbCB0aGlzIG1ldGhvZCBmb3IgYSBub24tY29tbXV0YWJsZSBpbnN0cnVjdGlvbiBvcgorICAvLy8gZm9yIG5vbi1jb21tdWFibGUgb3BlcmFuZHMuCisgIC8vLyBFdmVuIHRob3VnaCB0aGUgaW5zdHJ1Y3Rpb24gaXMgY29tbXV0YWJsZSwgdGhlIG1ldGhvZCBtYXkgc3RpbGwKKyAgLy8vIGZhaWwgdG8gY29tbXV0ZSB0aGUgb3BlcmFuZHMsIG51bGwgcG9pbnRlciBpcyByZXR1cm5lZCBpbiBzdWNoIGNhc2VzLgorICBNYWNoaW5lSW5zdHIgKgorICBjb21tdXRlSW5zdHJ1Y3Rpb24oTWFjaGluZUluc3RyICZNSSwgYm9vbCBOZXdNSSA9IGZhbHNlLAorICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgT3BJZHgxID0gQ29tbXV0ZUFueU9wZXJhbmRJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIE9wSWR4MiA9IENvbW11dGVBbnlPcGVyYW5kSW5kZXgpIGNvbnN0OworCisgIC8vLyBSZXR1cm5zIHRydWUgaWZmIHRoZSByb3V0aW5lIGNvdWxkIGZpbmQgdHdvIGNvbW11dGFibGUgb3BlcmFuZHMgaW4gdGhlCisgIC8vLyBnaXZlbiBtYWNoaW5lIGluc3RydWN0aW9uLgorICAvLy8gVGhlICdTcmNPcElkeDEnIGFuZCAnU3JjT3BJZHgyJyBhcmUgSU5QVVQgYW5kIE9VVFBVVCBhcmd1bWVudHMuCisgIC8vLyBJZiBhbnkgb2YgdGhlIElOUFVUIHZhbHVlcyBpcyBzZXQgdG8gdGhlIHNwZWNpYWwgdmFsdWUKKyAgLy8vICdDb21tdXRlQW55T3BlcmFuZEluZGV4JyB0aGVuIHRoZSBtZXRob2QgYXJiaXRyYXJpbHkgcGlja3MgYSBjb21tdXRhYmxlCisgIC8vLyBvcGVyYW5kLCB0aGVuIHJldHVybnMgaXRzIGluZGV4IGluIHRoZSBjb3JyZXNwb25kaW5nIGFyZ3VtZW50LgorICAvLy8gSWYgYm90aCBvZiBJTlBVVCB2YWx1ZXMgYXJlIHNldCB0byAnQ29tbXV0ZUFueU9wZXJhbmRJbmRleCcgdGhlbiBtZXRob2QKKyAgLy8vIGxvb2tzIGZvciAyIGNvbW11dGFibGUgb3BlcmFuZHMuCisgIC8vLyBJZiBJTlBVVCB2YWx1ZXMgcmVmZXIgdG8gc29tZSBvcGVyYW5kcyBvZiBNSSwgdGhlbiB0aGUgbWV0aG9kIHNpbXBseQorICAvLy8gcmV0dXJucyB0cnVlIGlmIHRoZSBjb3JyZXNwb25kaW5nIG9wZXJhbmRzIGFyZSBjb21tdXRhYmxlIGFuZCByZXR1cm5zCisgIC8vLyBmYWxzZSBvdGhlcndpc2UuCisgIC8vLworICAvLy8gRm9yIGV4YW1wbGUsIGNhbGxpbmcgdGhpcyBtZXRob2QgdGhpcyB3YXk6CisgIC8vLyAgICAgdW5zaWduZWQgT3AxID0gMSwgT3AyID0gQ29tbXV0ZUFueU9wZXJhbmRJbmRleDsKKyAgLy8vICAgICBmaW5kQ29tbXV0ZWRPcEluZGljZXMoTUksIE9wMSwgT3AyKTsKKyAgLy8vIGNhbiBiZSBpbnRlcnByZXRlZCBhcyBhIHF1ZXJ5IGFza2luZyB0byBmaW5kIGFuIG9wZXJhbmQgdGhhdCB3b3VsZCBiZQorICAvLy8gY29tbXV0YWJsZSB3aXRoIHRoZSBvcGVyYW5kIzEuCisgIHZpcnR1YWwgYm9vbCBmaW5kQ29tbXV0ZWRPcEluZGljZXMoTWFjaGluZUluc3RyICZNSSwgdW5zaWduZWQgJlNyY09wSWR4MSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCAmU3JjT3BJZHgyKSBjb25zdDsKKworICAvLy8gQSBwYWlyIGNvbXBvc2VkIG9mIGEgcmVnaXN0ZXIgYW5kIGEgc3ViLXJlZ2lzdGVyIGluZGV4LgorICAvLy8gVXNlZCB0byBnaXZlIHNvbWUgdHlwZSBjaGVja2luZyB3aGVuIG1vZGVsaW5nIFJlZzpTdWJSZWcuCisgIHN0cnVjdCBSZWdTdWJSZWdQYWlyIHsKKyAgICB1bnNpZ25lZCBSZWc7CisgICAgdW5zaWduZWQgU3ViUmVnOworCisgICAgUmVnU3ViUmVnUGFpcih1bnNpZ25lZCBSZWcgPSAwLCB1bnNpZ25lZCBTdWJSZWcgPSAwKQorICAgICAgICA6IFJlZyhSZWcpLCBTdWJSZWcoU3ViUmVnKSB7fQorICB9OworCisgIC8vLyBBIHBhaXIgY29tcG9zZWQgb2YgYSBwYWlyIG9mIGEgcmVnaXN0ZXIgYW5kIGEgc3ViLXJlZ2lzdGVyIGluZGV4LAorICAvLy8gYW5kIGFub3RoZXIgc3ViLXJlZ2lzdGVyIGluZGV4LgorICAvLy8gVXNlZCB0byBnaXZlIHNvbWUgdHlwZSBjaGVja2luZyB3aGVuIG1vZGVsaW5nIFJlZzpTdWJSZWcxLCBTdWJSZWcyLgorICBzdHJ1Y3QgUmVnU3ViUmVnUGFpckFuZElkeCA6IFJlZ1N1YlJlZ1BhaXIgeworICAgIHVuc2lnbmVkIFN1YklkeDsKKworICAgIFJlZ1N1YlJlZ1BhaXJBbmRJZHgodW5zaWduZWQgUmVnID0gMCwgdW5zaWduZWQgU3ViUmVnID0gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFN1YklkeCA9IDApCisgICAgICAgIDogUmVnU3ViUmVnUGFpcihSZWcsIFN1YlJlZyksIFN1YklkeChTdWJJZHgpIHt9CisgIH07CisKKyAgLy8vIEJ1aWxkIHRoZSBlcXVpdmFsZW50IGlucHV0cyBvZiBhIFJFR19TRVFVRU5DRSBmb3IgdGhlIGdpdmVuIFxwIE1JCisgIC8vLyBhbmQgXHAgRGVmSWR4LgorICAvLy8gXHAgW291dF0gSW5wdXRSZWdzIG9mIHRoZSBlcXVpdmFsZW50IFJFR19TRVFVRU5DRS4gRWFjaCBlbGVtZW50IG9mCisgIC8vLyB0aGUgbGlzdCBpcyBtb2RlbGVkIGFzIDxSZWc6U3ViUmVnLCBTdWJJZHg+LiBPcGVyYW5kcyB3aXRoIHRoZSB1bmRlZgorICAvLy8gZmxhZyBhcmUgbm90IGFkZGVkIHRvIHRoaXMgbGlzdC4KKyAgLy8vIEUuZy4sIFJFR19TRVFVRU5DRSAlMTpzdWIxLCBzdWIwLCAlMiwgc3ViMSB3b3VsZCBwcm9kdWNlCisgIC8vLyB0d28gZWxlbWVudHM6CisgIC8vLyAtICUxOnN1YjEsIHN1YjAKKyAgLy8vIC0gJTI8OjA+LCBzdWIxCisgIC8vLworICAvLy8gXHJldHVybnMgdHJ1ZSBpZiBpdCBpcyBwb3NzaWJsZSB0byBidWlsZCBzdWNoIGFuIGlucHV0IHNlcXVlbmNlCisgIC8vLyB3aXRoIHRoZSBwYWlyIFxwIE1JLCBccCBEZWZJZHguIEZhbHNlIG90aGVyd2lzZS4KKyAgLy8vCisgIC8vLyBccHJlIE1JLmlzUmVnU2VxdWVuY2UoKSBvciBNSS5pc1JlZ1NlcXVlbmNlTGlrZSgpLgorICAvLy8KKyAgLy8vIFxub3RlIFRoZSBnZW5lcmljIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHByb3ZpZGUgYW55IHN1cHBvcnQgZm9yCisgIC8vLyBNSS5pc1JlZ1NlcXVlbmNlTGlrZSgpLiBJbiBvdGhlciB3b3Jkcywgb25lIGhhcyB0byBvdmVycmlkZQorICAvLy8gZ2V0UmVnU2VxdWVuY2VMaWtlSW5wdXRzIGZvciB0YXJnZXQgc3BlY2lmaWMgaW5zdHJ1Y3Rpb25zLgorICBib29sCisgIGdldFJlZ1NlcXVlbmNlSW5wdXRzKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUksIHVuc2lnbmVkIERlZklkeCwKKyAgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPFJlZ1N1YlJlZ1BhaXJBbmRJZHg+ICZJbnB1dFJlZ3MpIGNvbnN0OworCisgIC8vLyBCdWlsZCB0aGUgZXF1aXZhbGVudCBpbnB1dHMgb2YgYSBFWFRSQUNUX1NVQlJFRyBmb3IgdGhlIGdpdmVuIFxwIE1JCisgIC8vLyBhbmQgXHAgRGVmSWR4LgorICAvLy8gXHAgW291dF0gSW5wdXRSZWcgb2YgdGhlIGVxdWl2YWxlbnQgRVhUUkFDVF9TVUJSRUcuCisgIC8vLyBFLmcuLCBFWFRSQUNUX1NVQlJFRyAlMTpzdWIxLCBzdWIwLCBzdWIxIHdvdWxkIHByb2R1Y2U6CisgIC8vLyAtICUxOnN1YjEsIHN1YjAKKyAgLy8vCisgIC8vLyBccmV0dXJucyB0cnVlIGlmIGl0IGlzIHBvc3NpYmxlIHRvIGJ1aWxkIHN1Y2ggYW4gaW5wdXQgc2VxdWVuY2UKKyAgLy8vIHdpdGggdGhlIHBhaXIgXHAgTUksIFxwIERlZklkeCBhbmQgdGhlIG9wZXJhbmQgaGFzIG5vIHVuZGVmIGZsYWcgc2V0LgorICAvLy8gRmFsc2Ugb3RoZXJ3aXNlLgorICAvLy8KKyAgLy8vIFxwcmUgTUkuaXNFeHRyYWN0U3VicmVnKCkgb3IgTUkuaXNFeHRyYWN0U3VicmVnTGlrZSgpLgorICAvLy8KKyAgLy8vIFxub3RlIFRoZSBnZW5lcmljIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHByb3ZpZGUgYW55IHN1cHBvcnQgZm9yCisgIC8vLyBNSS5pc0V4dHJhY3RTdWJyZWdMaWtlKCkuIEluIG90aGVyIHdvcmRzLCBvbmUgaGFzIHRvIG92ZXJyaWRlCisgIC8vLyBnZXRFeHRyYWN0U3VicmVnTGlrZUlucHV0cyBmb3IgdGFyZ2V0IHNwZWNpZmljIGluc3RydWN0aW9ucy4KKyAgYm9vbCBnZXRFeHRyYWN0U3VicmVnSW5wdXRzKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUksIHVuc2lnbmVkIERlZklkeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1N1YlJlZ1BhaXJBbmRJZHggJklucHV0UmVnKSBjb25zdDsKKworICAvLy8gQnVpbGQgdGhlIGVxdWl2YWxlbnQgaW5wdXRzIG9mIGEgSU5TRVJUX1NVQlJFRyBmb3IgdGhlIGdpdmVuIFxwIE1JCisgIC8vLyBhbmQgXHAgRGVmSWR4LgorICAvLy8gXHAgW291dF0gQmFzZVJlZyBhbmQgXHAgW291dF0gSW5zZXJ0ZWRSZWcgY29udGFpbgorICAvLy8gdGhlIGVxdWl2YWxlbnQgaW5wdXRzIG9mIElOU0VSVF9TVUJSRUcuCisgIC8vLyBFLmcuLCBJTlNFUlRfU1VCUkVHICUwOnN1YjAsICUxOnN1YjEsIHN1YjMgd291bGQgcHJvZHVjZToKKyAgLy8vIC0gQmFzZVJlZzogJTA6c3ViMAorICAvLy8gLSBJbnNlcnRlZFJlZzogJTE6c3ViMSwgc3ViMworICAvLy8KKyAgLy8vIFxyZXR1cm5zIHRydWUgaWYgaXQgaXMgcG9zc2libGUgdG8gYnVpbGQgc3VjaCBhbiBpbnB1dCBzZXF1ZW5jZQorICAvLy8gd2l0aCB0aGUgcGFpciBccCBNSSwgXHAgRGVmSWR4IGFuZCB0aGUgb3BlcmFuZCBoYXMgbm8gdW5kZWYgZmxhZyBzZXQuCisgIC8vLyBGYWxzZSBvdGhlcndpc2UuCisgIC8vLworICAvLy8gXHByZSBNSS5pc0luc2VydFN1YnJlZygpIG9yIE1JLmlzSW5zZXJ0U3VicmVnTGlrZSgpLgorICAvLy8KKyAgLy8vIFxub3RlIFRoZSBnZW5lcmljIGltcGxlbWVudGF0aW9uIGRvZXMgbm90IHByb3ZpZGUgYW55IHN1cHBvcnQgZm9yCisgIC8vLyBNSS5pc0luc2VydFN1YnJlZ0xpa2UoKS4gSW4gb3RoZXIgd29yZHMsIG9uZSBoYXMgdG8gb3ZlcnJpZGUKKyAgLy8vIGdldEluc2VydFN1YnJlZ0xpa2VJbnB1dHMgZm9yIHRhcmdldCBzcGVjaWZpYyBpbnN0cnVjdGlvbnMuCisgIGJvb2wgZ2V0SW5zZXJ0U3VicmVnSW5wdXRzKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUksIHVuc2lnbmVkIERlZklkeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnU3ViUmVnUGFpciAmQmFzZVJlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnU3ViUmVnUGFpckFuZElkeCAmSW5zZXJ0ZWRSZWcpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0d28gbWFjaGluZSBpbnN0cnVjdGlvbnMgd291bGQgcHJvZHVjZSBpZGVudGljYWwgdmFsdWVzLgorICAvLy8gQnkgZGVmYXVsdCwgdGhpcyBpcyBvbmx5IHRydWUgd2hlbiB0aGUgdHdvIGluc3RydWN0aW9ucworICAvLy8gYXJlIGRlZW1lZCBpZGVudGljYWwgZXhjZXB0IGZvciBkZWZzLiBJZiB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuIHRoZQorICAvLy8gSVIgaXMgc3RpbGwgaW4gU1NBIGZvcm0sIHRoZSBjYWxsZXIgY2FuIHBhc3MgdGhlIE1hY2hpbmVSZWdpc3RlckluZm8gZm9yCisgIC8vLyBhZ2dyZXNzaXZlIGNoZWNrcy4KKyAgdmlydHVhbCBib29sIHByb2R1Y2VTYW1lVmFsdWUoY29uc3QgTWFjaGluZUluc3RyICZNSTAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICpNUkkgPSBudWxscHRyKSBjb25zdDsKKworICAvLy8gXHJldHVybnMgdHJ1ZSBpZiBhIGJyYW5jaCBmcm9tIGFuIGluc3RydWN0aW9uIHdpdGggb3Bjb2RlIFxwIEJyYW5jaE9wYworICAvLy8gIGJ5dGVzIGlzIGNhcGFibGUgb2YganVtcGluZyB0byBhIHBvc2l0aW9uIFxwIEJyT2Zmc2V0IGJ5dGVzIGF3YXkuCisgIHZpcnR1YWwgYm9vbCBpc0JyYW5jaE9mZnNldEluUmFuZ2UodW5zaWduZWQgQnJhbmNoT3BjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDY0X3QgQnJPZmZzZXQpIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJ0YXJnZXQgZGlkIG5vdCBpbXBsZW1lbnQiKTsKKyAgfQorCisgIC8vLyBccmV0dXJucyBUaGUgYmxvY2sgdGhhdCBicmFuY2ggaW5zdHJ1Y3Rpb24gXHAgTUkganVtcHMgdG8uCisgIHZpcnR1YWwgTWFjaGluZUJhc2ljQmxvY2sgKmdldEJyYW5jaERlc3RCbG9jayhjb25zdCBNYWNoaW5lSW5zdHIgJk1JKSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgidGFyZ2V0IGRpZCBub3QgaW1wbGVtZW50Iik7CisgIH0KKworICAvLy8gSW5zZXJ0IGFuIHVuY29uZGl0aW9uYWwgaW5kaXJlY3QgYnJhbmNoIGF0IHRoZSBlbmQgb2YgXHAgTUJCIHRvIFxwCisgIC8vLyBOZXdEZXN0QkIuICBccCBCck9mZnNldCBpbmRpY2F0ZXMgdGhlIG9mZnNldCBvZiBccCBOZXdEZXN0QkIgcmVsYXRpdmUgdG8KKyAgLy8vIHRoZSBvZmZzZXQgb2YgdGhlIHBvc2l0aW9uIHRvIGluc2VydCB0aGUgbmV3IGJyYW5jaC4KKyAgLy8vCisgIC8vLyBccmV0dXJucyBUaGUgbnVtYmVyIG9mIGJ5dGVzIGFkZGVkIHRvIHRoZSBibG9jay4KKyAgdmlydHVhbCB1bnNpZ25lZCBpbnNlcnRJbmRpcmVjdEJyYW5jaChNYWNoaW5lQmFzaWNCbG9jayAmTUJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICZOZXdEZXN0QkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdMb2MgJkRMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDY0X3QgQnJPZmZzZXQgPSAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1NjYXZlbmdlciAqUlMgPSBudWxscHRyKSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgidGFyZ2V0IGRpZCBub3QgaW1wbGVtZW50Iik7CisgIH0KKworICAvLy8gQW5hbHl6ZSB0aGUgYnJhbmNoaW5nIGNvZGUgYXQgdGhlIGVuZCBvZiBNQkIsIHJldHVybmluZworICAvLy8gdHJ1ZSBpZiBpdCBjYW5ub3QgYmUgdW5kZXJzdG9vZCAoZS5nLiBpdCdzIGEgc3dpdGNoIGRpc3BhdGNoIG9yIGlzbid0CisgIC8vLyBpbXBsZW1lbnRlZCBmb3IgYSB0YXJnZXQpLiAgVXBvbiBzdWNjZXNzLCB0aGlzIHJldHVybnMgZmFsc2UgYW5kIHJldHVybnMKKyAgLy8vIHdpdGggdGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbiBpbiB2YXJpb3VzIGNhc2VzOgorICAvLy8KKyAgLy8vIDEuIElmIHRoaXMgYmxvY2sgZW5kcyB3aXRoIG5vIGJyYW5jaGVzIChpdCBqdXN0IGZhbGxzIHRocm91Z2ggdG8gaXRzIHN1Y2MpCisgIC8vLyAgICBqdXN0IHJldHVybiBmYWxzZSwgbGVhdmluZyBUQkIvRkJCIG51bGwuCisgIC8vLyAyLiBJZiB0aGlzIGJsb2NrIGVuZHMgd2l0aCBvbmx5IGFuIHVuY29uZGl0aW9uYWwgYnJhbmNoLCBpdCBzZXRzIFRCQiB0byBiZQorICAvLy8gICAgdGhlIGRlc3RpbmF0aW9uIGJsb2NrLgorICAvLy8gMy4gSWYgdGhpcyBibG9jayBlbmRzIHdpdGggYSBjb25kaXRpb25hbCBicmFuY2ggYW5kIGl0IGZhbGxzIHRocm91Z2ggdG8gYQorICAvLy8gICAgc3VjY2Vzc29yIGJsb2NrLCBpdCBzZXRzIFRCQiB0byBiZSB0aGUgYnJhbmNoIGRlc3RpbmF0aW9uIGJsb2NrIGFuZCBhCisgIC8vLyAgICBsaXN0IG9mIG9wZXJhbmRzIHRoYXQgZXZhbHVhdGUgdGhlIGNvbmRpdGlvbi4gVGhlc2Ugb3BlcmFuZHMgY2FuIGJlCisgIC8vLyAgICBwYXNzZWQgdG8gb3RoZXIgVGFyZ2V0SW5zdHJJbmZvIG1ldGhvZHMgdG8gY3JlYXRlIG5ldyBicmFuY2hlcy4KKyAgLy8vIDQuIElmIHRoaXMgYmxvY2sgZW5kcyB3aXRoIGEgY29uZGl0aW9uYWwgYnJhbmNoIGZvbGxvd2VkIGJ5IGFuCisgIC8vLyAgICB1bmNvbmRpdGlvbmFsIGJyYW5jaCwgaXQgcmV0dXJucyB0aGUgJ3RydWUnIGRlc3RpbmF0aW9uIGluIFRCQiwgdGhlCisgIC8vLyAgICAnZmFsc2UnIGRlc3RpbmF0aW9uIGluIEZCQiwgYW5kIGEgbGlzdCBvZiBvcGVyYW5kcyB0aGF0IGV2YWx1YXRlIHRoZQorICAvLy8gICAgY29uZGl0aW9uLiAgVGhlc2Ugb3BlcmFuZHMgY2FuIGJlIHBhc3NlZCB0byBvdGhlciBUYXJnZXRJbnN0ckluZm8KKyAgLy8vICAgIG1ldGhvZHMgdG8gY3JlYXRlIG5ldyBicmFuY2hlcy4KKyAgLy8vCisgIC8vLyBOb3RlIHRoYXQgcmVtb3ZlQnJhbmNoIGFuZCBpbnNlcnRCcmFuY2ggbXVzdCBiZSBpbXBsZW1lbnRlZCB0byBzdXBwb3J0CisgIC8vLyBjYXNlcyB3aGVyZSB0aGlzIG1ldGhvZCByZXR1cm5zIHN1Y2Nlc3MuCisgIC8vLworICAvLy8gSWYgQWxsb3dNb2RpZnkgaXMgdHJ1ZSwgdGhlbiB0aGlzIHJvdXRpbmUgaXMgYWxsb3dlZCB0byBtb2RpZnkgdGhlIGJhc2ljCisgIC8vLyBibG9jayAoZS5nLiBkZWxldGUgaW5zdHJ1Y3Rpb25zIGFmdGVyIHRoZSB1bmNvbmRpdGlvbmFsIGJyYW5jaCkuCisgIC8vLworICAvLy8gVGhlIENGRyBpbmZvcm1hdGlvbiBpbiBNQkIuUHJlZGVjZXNzb3JzIGFuZCBNQkIuU3VjY2Vzc29ycyBtdXN0IGJlIHZhbGlkCisgIC8vLyBiZWZvcmUgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLgorICB2aXJ0dWFsIGJvb2wgYW5hbHl6ZUJyYW5jaChNYWNoaW5lQmFzaWNCbG9jayAmTUJCLCBNYWNoaW5lQmFzaWNCbG9jayAqJlRCQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2sgKiZGQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxNYWNoaW5lT3BlcmFuZD4gJkNvbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgQWxsb3dNb2RpZnkgPSBmYWxzZSkgY29uc3QgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8vIFJlcHJlc2VudHMgYSBwcmVkaWNhdGUgYXQgdGhlIE1hY2hpbmVGdW5jdGlvbiBsZXZlbC4gIFRoZSBjb250cm9sIGZsb3cgYQorICAvLy8gTWFjaGluZUJyYW5jaFByZWRpY2F0ZSByZXByZXNlbnRzIGlzOgorICAvLy8KKyAgLy8vICBSZWcgPSBMSFMgYFByZWRpY2F0ZWAgUkhTICAgICAgICAgPT0gQ29uZGl0aW9uRGVmCisgIC8vLyAgaWYgUmVnIHRoZW4gZ290byBUcnVlRGVzdCBlbHNlIGdvdG8gRmFsc2VEZXN0CisgIC8vLworICBzdHJ1Y3QgTWFjaGluZUJyYW5jaFByZWRpY2F0ZSB7CisgICAgZW51bSBDb21wYXJlUHJlZGljYXRlIHsKKyAgICAgIFBSRURfRVEsICAgICAvLyBUcnVlIGlmIHR3byB2YWx1ZXMgYXJlIGVxdWFsCisgICAgICBQUkVEX05FLCAgICAgLy8gVHJ1ZSBpZiB0d28gdmFsdWVzIGFyZSBub3QgZXF1YWwKKyAgICAgIFBSRURfSU5WQUxJRCAvLyBTZW50aW5lbCB2YWx1ZQorICAgIH07CisKKyAgICBDb21wYXJlUHJlZGljYXRlIFByZWRpY2F0ZSA9IFBSRURfSU5WQUxJRDsKKyAgICBNYWNoaW5lT3BlcmFuZCBMSFMgPSBNYWNoaW5lT3BlcmFuZDo6Q3JlYXRlSW1tKDApOworICAgIE1hY2hpbmVPcGVyYW5kIFJIUyA9IE1hY2hpbmVPcGVyYW5kOjpDcmVhdGVJbW0oMCk7CisgICAgTWFjaGluZUJhc2ljQmxvY2sgKlRydWVEZXN0ID0gbnVsbHB0cjsKKyAgICBNYWNoaW5lQmFzaWNCbG9jayAqRmFsc2VEZXN0ID0gbnVsbHB0cjsKKyAgICBNYWNoaW5lSW5zdHIgKkNvbmRpdGlvbkRlZiA9IG51bGxwdHI7CisKKyAgICAvLy8gU2luZ2xlVXNlQ29uZGl0aW9uIGlzIHRydWUgaWYgQ29uZGl0aW9uRGVmIGlzIGRlYWQgZXhjZXB0IGZvciB0aGUKKyAgICAvLy8gYnJhbmNoKGVzKSBhdCB0aGUgZW5kIG9mIHRoZSBiYXNpYyBibG9jay4KKyAgICAvLy8KKyAgICBib29sIFNpbmdsZVVzZUNvbmRpdGlvbiA9IGZhbHNlOworCisgICAgZXhwbGljaXQgTWFjaGluZUJyYW5jaFByZWRpY2F0ZSgpID0gZGVmYXVsdDsKKyAgfTsKKworICAvLy8gQW5hbHl6ZSB0aGUgYnJhbmNoaW5nIGNvZGUgYXQgdGhlIGVuZCBvZiBNQkIgYW5kIHBhcnNlIGl0IGludG8gdGhlCisgIC8vLyBNYWNoaW5lQnJhbmNoUHJlZGljYXRlIHN0cnVjdHVyZSBpZiBwb3NzaWJsZS4gIFJldHVybnMgZmFsc2Ugb24gc3VjY2VzcworICAvLy8gYW5kIHRydWUgb24gZmFpbHVyZS4KKyAgLy8vCisgIC8vLyBJZiBBbGxvd01vZGlmeSBpcyB0cnVlLCB0aGVuIHRoaXMgcm91dGluZSBpcyBhbGxvd2VkIHRvIG1vZGlmeSB0aGUgYmFzaWMKKyAgLy8vIGJsb2NrIChlLmcuIGRlbGV0ZSBpbnN0cnVjdGlvbnMgYWZ0ZXIgdGhlIHVuY29uZGl0aW9uYWwgYnJhbmNoKS4KKyAgLy8vCisgIHZpcnR1YWwgYm9vbCBhbmFseXplQnJhbmNoUHJlZGljYXRlKE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCcmFuY2hQcmVkaWNhdGUgJk1CUCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBBbGxvd01vZGlmeSA9IGZhbHNlKSBjb25zdCB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLy8gUmVtb3ZlIHRoZSBicmFuY2hpbmcgY29kZSBhdCB0aGUgZW5kIG9mIHRoZSBzcGVjaWZpYyBNQkIuCisgIC8vLyBUaGlzIGlzIG9ubHkgaW52b2tlZCBpbiBjYXNlcyB3aGVyZSBBbmFseXplQnJhbmNoIHJldHVybnMgc3VjY2Vzcy4gSXQKKyAgLy8vIHJldHVybnMgdGhlIG51bWJlciBvZiBpbnN0cnVjdGlvbnMgdGhhdCB3ZXJlIHJlbW92ZWQuCisgIC8vLyBJZiBccCBCeXRlc1JlbW92ZWQgaXMgbm9uLW51bGwsIHJlcG9ydCB0aGUgY2hhbmdlIGluIGNvZGUgc2l6ZSBmcm9tIHRoZQorICAvLy8gcmVtb3ZlZCBpbnN0cnVjdGlvbnMuCisgIHZpcnR1YWwgdW5zaWduZWQgcmVtb3ZlQnJhbmNoKE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqQnl0ZXNSZW1vdmVkID0gbnVsbHB0cikgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIlRhcmdldCBkaWRuJ3QgaW1wbGVtZW50IFRhcmdldEluc3RySW5mbzo6cmVtb3ZlQnJhbmNoISIpOworICB9CisKKyAgLy8vIEluc2VydCBicmFuY2ggY29kZSBpbnRvIHRoZSBlbmQgb2YgdGhlIHNwZWNpZmllZCBNYWNoaW5lQmFzaWNCbG9jay4gVGhlCisgIC8vLyBvcGVyYW5kcyB0byB0aGlzIG1ldGhvZCBhcmUgdGhlIHNhbWUgYXMgdGhvc2UgcmV0dXJuZWQgYnkgQW5hbHl6ZUJyYW5jaC4KKyAgLy8vIFRoaXMgaXMgb25seSBpbnZva2VkIGluIGNhc2VzIHdoZXJlIEFuYWx5emVCcmFuY2ggcmV0dXJucyBzdWNjZXNzLiBJdAorICAvLy8gcmV0dXJucyB0aGUgbnVtYmVyIG9mIGluc3RydWN0aW9ucyBpbnNlcnRlZC4gSWYgXHAgQnl0ZXNBZGRlZCBpcyBub24tbnVsbCwKKyAgLy8vIHJlcG9ydCB0aGUgY2hhbmdlIGluIGNvZGUgc2l6ZSBmcm9tIHRoZSBhZGRlZCBpbnN0cnVjdGlvbnMuCisgIC8vLworICAvLy8gSXQgaXMgYWxzbyBpbnZva2VkIGJ5IHRhaWwgbWVyZ2luZyB0byBhZGQgdW5jb25kaXRpb25hbCBicmFuY2hlcyBpbgorICAvLy8gY2FzZXMgd2hlcmUgQW5hbHl6ZUJyYW5jaCBkb2Vzbid0IGFwcGx5IGJlY2F1c2UgdGhlcmUgd2FzIG5vIG9yaWdpbmFsCisgIC8vLyBicmFuY2ggdG8gYW5hbHl6ZS4gIEF0IGxlYXN0IHRoaXMgbXVjaCBtdXN0IGJlIGltcGxlbWVudGVkLCBlbHNlIHRhaWwKKyAgLy8vIG1lcmdpbmcgbmVlZHMgdG8gYmUgZGlzYWJsZWQuCisgIC8vLworICAvLy8gVGhlIENGRyBpbmZvcm1hdGlvbiBpbiBNQkIuUHJlZGVjZXNzb3JzIGFuZCBNQkIuU3VjY2Vzc29ycyBtdXN0IGJlIHZhbGlkCisgIC8vLyBiZWZvcmUgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLgorICB2aXJ0dWFsIHVuc2lnbmVkIGluc2VydEJyYW5jaChNYWNoaW5lQmFzaWNCbG9jayAmTUJCLCBNYWNoaW5lQmFzaWNCbG9jayAqVEJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jayAqRkJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjxNYWNoaW5lT3BlcmFuZD4gQ29uZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGVidWdMb2MgJkRMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKkJ5dGVzQWRkZWQgPSBudWxscHRyKSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgiVGFyZ2V0IGRpZG4ndCBpbXBsZW1lbnQgVGFyZ2V0SW5zdHJJbmZvOjppbnNlcnRCcmFuY2ghIik7CisgIH0KKworICB1bnNpZ25lZCBpbnNlcnRVbmNvbmRpdGlvbmFsQnJhbmNoKE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2sgKkRlc3RCQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEZWJ1Z0xvYyAmREwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICpCeXRlc0FkZGVkID0gbnVsbHB0cikgY29uc3QgeworICAgIHJldHVybiBpbnNlcnRCcmFuY2goTUJCLCBEZXN0QkIsIG51bGxwdHIsIEFycmF5UmVmPE1hY2hpbmVPcGVyYW5kPigpLCBETCwKKyAgICAgICAgICAgICAgICAgICAgICAgIEJ5dGVzQWRkZWQpOworICB9CisKKyAgLy8vIEFuYWx5emUgdGhlIGxvb3AgY29kZSwgcmV0dXJuIHRydWUgaWYgaXQgY2Fubm90IGJlIHVuZGVyc3Rvby4gVXBvbgorICAvLy8gc3VjY2VzcywgdGhpcyBmdW5jdGlvbiByZXR1cm5zIGZhbHNlIGFuZCByZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHRoZQorICAvLy8gaW5kdWN0aW9uIHZhcmlhYmxlIGFuZCBjb21wYXJlIGluc3RydWN0aW9uIHVzZWQgYXQgdGhlIGVuZC4KKyAgdmlydHVhbCBib29sIGFuYWx5emVMb29wKE1hY2hpbmVMb29wICZMLCBNYWNoaW5lSW5zdHIgKiZJbmRWYXJJbnN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUluc3RyIComQ21wSW5zdCkgY29uc3QgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8vIEdlbmVyYXRlIGNvZGUgdG8gcmVkdWNlIHRoZSBsb29wIGl0ZXJhdGlvbiBieSBvbmUgYW5kIGNoZWNrIGlmIHRoZSBsb29wCisgIC8vLyBpcyBmaW5pc2hlZC4gIFJldHVybiB0aGUgdmFsdWUvcmVnaXN0ZXIgb2YgdGhlIG5ldyBsb29wIGNvdW50LiAgV2UgbmVlZAorICAvLy8gdGhpcyBmdW5jdGlvbiB3aGVuIHBlZWxpbmcgb2ZmIG9uZSBvciBtb3JlIGl0ZXJhdGlvbnMgb2YgYSBsb29wLiBUaGlzCisgIC8vLyBmdW5jdGlvbiBhc3N1bWVzIHRoZSBudGggaXRlcmF0aW9uIGlzIHBlZWxlZCBmaXJzdC4KKyAgdmlydHVhbCB1bnNpZ25lZCByZWR1Y2VMb29wQ291bnQoTWFjaGluZUJhc2ljQmxvY2sgJk1CQiwgTWFjaGluZUluc3RyICpJbmRWYXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVJbnN0ciAmQ21wLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8TWFjaGluZU9wZXJhbmQ+ICZDb25kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8TWFjaGluZUluc3RyICo+ICZQcmV2SW5zdHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIEl0ZXIsIHVuc2lnbmVkIE1heEl0ZXIpIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJUYXJnZXQgZGlkbid0IGltcGxlbWVudCBSZWR1Y2VMb29wQ291bnQiKTsKKyAgfQorCisgIC8vLyBEZWxldGUgdGhlIGluc3RydWN0aW9uIE9sZEluc3QgYW5kIGV2ZXJ5dGhpbmcgYWZ0ZXIgaXQsIHJlcGxhY2luZyBpdCB3aXRoCisgIC8vLyBhbiB1bmNvbmRpdGlvbmFsIGJyYW5jaCB0byBOZXdEZXN0LiBUaGlzIGlzIHVzZWQgYnkgdGhlIHRhaWwgbWVyZ2luZyBwYXNzLgorICB2aXJ0dWFsIHZvaWQgUmVwbGFjZVRhaWxXaXRoQnJhbmNoVG8oTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIFRhaWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jayAqTmV3RGVzdCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGl0J3MgbGVnYWwgdG8gc3BsaXQgdGhlIGdpdmVuIGJhc2ljCisgIC8vLyBibG9jayBhdCB0aGUgc3BlY2lmaWVkIGluc3RydWN0aW9uIChpLmUuIGluc3RydWN0aW9uIHdvdWxkIGJlIHRoZSBzdGFydAorICAvLy8gb2YgYSBuZXcgYmFzaWMgYmxvY2spLgorICB2aXJ0dWFsIGJvb2wgaXNMZWdhbFRvU3BsaXRNQkJBdChNYWNoaW5lQmFzaWNCbG9jayAmTUJCLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgTUJCSSkgY29uc3QgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGl0J3MgcHJvZml0YWJsZSB0byBwcmVkaWNhdGUKKyAgLy8vIGluc3RydWN0aW9ucyB3aXRoIGFjY3VtdWxhdGVkIGluc3RydWN0aW9uIGxhdGVuY3kgb2YgIk51bUN5Y2xlcyIKKyAgLy8vIG9mIHRoZSBzcGVjaWZpZWQgYmFzaWMgYmxvY2ssIHdoZXJlIHRoZSBwcm9iYWJpbGl0eSBvZiB0aGUgaW5zdHJ1Y3Rpb25zCisgIC8vLyBiZWluZyBleGVjdXRlZCBpcyBnaXZlbiBieSBQcm9iYWJpbGl0eSwgYW5kIENvbmZpZGVuY2UgaXMgYSBtZWFzdXJlCisgIC8vLyBvZiBvdXIgY29uZmlkZW5jZSB0aGF0IGl0IHdpbGwgYmUgcHJvcGVybHkgcHJlZGljdGVkLgorICB2aXJ0dWFsIGJvb2wgaXNQcm9maXRhYmxlVG9JZkN2dChNYWNoaW5lQmFzaWNCbG9jayAmTUJCLCB1bnNpZ25lZCBOdW1DeWNsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIEV4dHJhUHJlZEN5Y2xlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnJhbmNoUHJvYmFiaWxpdHkgUHJvYmFiaWxpdHkpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gU2Vjb25kIHZhcmlhbnQgb2YgaXNQcm9maXRhYmxlVG9JZkN2dC4gVGhpcyBvbmUKKyAgLy8vIGNoZWNrcyBmb3IgdGhlIGNhc2Ugd2hlcmUgdHdvIGJhc2ljIGJsb2NrcyBmcm9tIHRydWUgYW5kIGZhbHNlIHBhdGgKKyAgLy8vIG9mIGEgaWYtdGhlbi1lbHNlIChkaWFtb25kKSBhcmUgcHJlZGljYXRlZCBvbiBtdXRhbGx5IGV4Y2x1c2l2ZQorICAvLy8gcHJlZGljYXRlcywgd2hlcmUgdGhlIHByb2JhYmlsaXR5IG9mIHRoZSB0cnVlIHBhdGggYmVpbmcgdGFrZW4gaXMgZ2l2ZW4KKyAgLy8vIGJ5IFByb2JhYmlsaXR5LCBhbmQgQ29uZmlkZW5jZSBpcyBhIG1lYXN1cmUgb2Ygb3VyIGNvbmZpZGVuY2UgdGhhdCBpdAorICAvLy8gd2lsbCBiZSBwcm9wZXJseSBwcmVkaWN0ZWQuCisgIHZpcnR1YWwgYm9vbCBpc1Byb2ZpdGFibGVUb0lmQ3Z0KE1hY2hpbmVCYXNpY0Jsb2NrICZUTUJCLCB1bnNpZ25lZCBOdW1UQ3ljbGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBFeHRyYVRDeWNsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICZGTUJCLCB1bnNpZ25lZCBOdW1GQ3ljbGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBFeHRyYUZDeWNsZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJyYW5jaFByb2JhYmlsaXR5IFByb2JhYmlsaXR5KSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGl0J3MgcHJvZml0YWJsZSBmb3IgaWYtY29udmVydGVyIHRvIGR1cGxpY2F0ZSBpbnN0cnVjdGlvbnMKKyAgLy8vIG9mIHNwZWNpZmllZCBhY2N1bXVsYXRlZCBpbnN0cnVjdGlvbiBsYXRlbmNpZXMgaW4gdGhlIHNwZWNpZmllZCBNQkIgdG8KKyAgLy8vIGVuYWJsZSBpZi1jb252ZXJzaW9uLgorICAvLy8gVGhlIHByb2JhYmlsaXR5IG9mIHRoZSBpbnN0cnVjdGlvbnMgYmVpbmcgZXhlY3V0ZWQgaXMgZ2l2ZW4gYnkKKyAgLy8vIFByb2JhYmlsaXR5LCBhbmQgQ29uZmlkZW5jZSBpcyBhIG1lYXN1cmUgb2Ygb3VyIGNvbmZpZGVuY2UgdGhhdCBpdAorICAvLy8gd2lsbCBiZSBwcm9wZXJseSBwcmVkaWN0ZWQuCisgIHZpcnR1YWwgYm9vbCBpc1Byb2ZpdGFibGVUb0R1cEZvcklmQ3Z0KE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIE51bUN5Y2xlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnJhbmNoUHJvYmFiaWxpdHkgUHJvYmFiaWxpdHkpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgaXQncyBwcm9maXRhYmxlIHRvIHVucHJlZGljYXRlCisgIC8vLyBvbmUgc2lkZSBvZiBhICdkaWFtb25kJywgaS5lLiB0d28gc2lkZXMgb2YgaWYtZWxzZSBwcmVkaWNhdGVkIG9uIG11dHVhbGx5CisgIC8vLyBleGNsdXNpdmUgcHJlZGljYXRlcy4KKyAgLy8vIGUuZy4KKyAgLy8vICAgc3ViZXEgIHIwLCByMSwgIzEKKyAgLy8vICAgYWRkbmUgIHIwLCByMSwgIzEKKyAgLy8vID0+CisgIC8vLyAgIHN1YiAgICByMCwgcjEsICMxCisgIC8vLyAgIGFkZG5lICByMCwgcjEsICMxCisgIC8vLworICAvLy8gVGhpcyBtYXkgYmUgcHJvZml0YWJsZSBpcyBjb25kaXRpb25hbCBpbnN0cnVjdGlvbnMgYXJlIGFsd2F5cyBleGVjdXRlZC4KKyAgdmlydHVhbCBib29sIGlzUHJvZml0YWJsZVRvVW5wcmVkaWNhdGUoTWFjaGluZUJhc2ljQmxvY2sgJlRNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICZGTUJCKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGl0IGlzIHBvc3NpYmxlIHRvIGluc2VydCBhIHNlbGVjdAorICAvLy8gaW5zdHJ1Y3Rpb24gdGhhdCBjaG9vc2VzIGJldHdlZW4gVHJ1ZVJlZyBhbmQgRmFsc2VSZWcgYmFzZWQgb24gdGhlCisgIC8vLyBjb25kaXRpb24gY29kZSBpbiBDb25kLgorICAvLy8KKyAgLy8vIFdoZW4gc3VjY2Vzc2Z1bCwgYWxzbyByZXR1cm4gdGhlIGxhdGVuY3kgaW4gY3ljbGVzIGZyb20gVHJ1ZVJlZywKKyAgLy8vIEZhbHNlUmVnLCBhbmQgQ29uZCB0byB0aGUgZGVzdGluYXRpb24gcmVnaXN0ZXIuIEluIG1vc3QgY2FzZXMsIGEgc2VsZWN0CisgIC8vLyBpbnN0cnVjdGlvbiB3aWxsIGJlIDEgY3ljbGUsIHNvIENvbmRDeWNsZXMgPSBUcnVlQ3ljbGVzID0gRmFsc2VDeWNsZXMgPSAxCisgIC8vLworICAvLy8gU29tZSB4ODYgaW1wbGVtZW50YXRpb25zIGhhdmUgMi1jeWNsZSBjbW92IGluc3RydWN0aW9ucy4KKyAgLy8vCisgIC8vLyBAcGFyYW0gTUJCICAgICAgICAgQmxvY2sgd2hlcmUgc2VsZWN0IGluc3RydWN0aW9uIHdvdWxkIGJlIGluc2VydGVkLgorICAvLy8gQHBhcmFtIENvbmQgICAgICAgIENvbmRpdGlvbiByZXR1cm5lZCBieSBBbmFseXplQnJhbmNoLgorICAvLy8gQHBhcmFtIFRydWVSZWcgICAgIFZpcnR1YWwgcmVnaXN0ZXIgdG8gc2VsZWN0IHdoZW4gQ29uZCBpcyB0cnVlLgorICAvLy8gQHBhcmFtIEZhbHNlUmVnICAgIFZpcnR1YWwgcmVnaXN0ZXIgdG8gc2VsZWN0IHdoZW4gQ29uZCBpcyBmYWxzZS4KKyAgLy8vIEBwYXJhbSBDb25kQ3ljbGVzICBMYXRlbmN5IGZyb20gQ29uZCtCcmFuY2ggdG8gc2VsZWN0IG91dHB1dC4KKyAgLy8vIEBwYXJhbSBUcnVlQ3ljbGVzICBMYXRlbmN5IGZyb20gVHJ1ZVJlZyB0byBzZWxlY3Qgb3V0cHV0LgorICAvLy8gQHBhcmFtIEZhbHNlQ3ljbGVzIExhdGVuY3kgZnJvbSBGYWxzZVJlZyB0byBzZWxlY3Qgb3V0cHV0LgorICB2aXJ0dWFsIGJvb2wgY2FuSW5zZXJ0U2VsZWN0KGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8TWFjaGluZU9wZXJhbmQ+IENvbmQsIHVuc2lnbmVkIFRydWVSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgRmFsc2VSZWcsIGludCAmQ29uZEN5Y2xlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgJlRydWVDeWNsZXMsIGludCAmRmFsc2VDeWNsZXMpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gSW5zZXJ0IGEgc2VsZWN0IGluc3RydWN0aW9uIGludG8gTUJCIGJlZm9yZSBJIHRoYXQgd2lsbCBjb3B5IFRydWVSZWcgdG8KKyAgLy8vIERzdFJlZyB3aGVuIENvbmQgaXMgdHJ1ZSwgYW5kIEZhbHNlUmVnIHRvIERzdFJlZyB3aGVuIENvbmQgaXMgZmFsc2UuCisgIC8vLworICAvLy8gVGhpcyBmdW5jdGlvbiBjYW4gb25seSBiZSBjYWxsZWQgYWZ0ZXIgY2FuSW5zZXJ0U2VsZWN0KCkgcmV0dXJuZWQgdHJ1ZS4KKyAgLy8vIFRoZSBjb25kaXRpb24gaW4gQ29uZCBjb21lcyBmcm9tIEFuYWx5emVCcmFuY2gsIGFuZCBpdCBjYW4gYmUgYXNzdW1lZAorICAvLy8gdGhhdCB0aGUgc2FtZSBmbGFncyBvciByZWdpc3RlcnMgcmVxdWlyZWQgYnkgQ29uZCBhcmUgYXZhaWxhYmxlIGF0IHRoZQorICAvLy8gaW5zZXJ0aW9uIHBvaW50LgorICAvLy8KKyAgLy8vIEBwYXJhbSBNQkIgICAgICBCbG9jayB3aGVyZSBzZWxlY3QgaW5zdHJ1Y3Rpb24gc2hvdWxkIGJlIGluc2VydGVkLgorICAvLy8gQHBhcmFtIEkgICAgICAgIEluc2VydGlvbiBwb2ludC4KKyAgLy8vIEBwYXJhbSBETCAgICAgICBTb3VyY2UgbG9jYXRpb24gZm9yIGRlYnVnZ2luZy4KKyAgLy8vIEBwYXJhbSBEc3RSZWcgICBWaXJ0dWFsIHJlZ2lzdGVyIHRvIGJlIGRlZmluZWQgYnkgc2VsZWN0IGluc3RydWN0aW9uLgorICAvLy8gQHBhcmFtIENvbmQgICAgIENvbmRpdGlvbiBhcyBjb21wdXRlZCBieSBBbmFseXplQnJhbmNoLgorICAvLy8gQHBhcmFtIFRydWVSZWcgIFZpcnR1YWwgcmVnaXN0ZXIgdG8gY29weSB3aGVuIENvbmQgaXMgdHJ1ZS4KKyAgLy8vIEBwYXJhbSBGYWxzZVJlZyBWaXJ0dWFsIHJlZ2lzdGVyIHRvIGNvcHkgd2hlbiBDb25zIGlzIGZhbHNlLgorICB2aXJ0dWFsIHZvaWQgaW5zZXJ0U2VsZWN0KE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEksIGNvbnN0IERlYnVnTG9jICZETCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBEc3RSZWcsIEFycmF5UmVmPE1hY2hpbmVPcGVyYW5kPiBDb25kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFRydWVSZWcsIHVuc2lnbmVkIEZhbHNlUmVnKSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgiVGFyZ2V0IGRpZG4ndCBpbXBsZW1lbnQgVGFyZ2V0SW5zdHJJbmZvOjppbnNlcnRTZWxlY3QhIik7CisgIH0KKworICAvLy8gQW5hbHl6ZSB0aGUgZ2l2ZW4gc2VsZWN0IGluc3RydWN0aW9uLCByZXR1cm5pbmcgdHJ1ZSBpZgorICAvLy8gaXQgY2Fubm90IGJlIHVuZGVyc3Rvb2QuIEl0IGlzIGFzc3VtZWQgdGhhdCBNSS0+aXNTZWxlY3QoKSBpcyB0cnVlLgorICAvLy8KKyAgLy8vIFdoZW4gc3VjY2Vzc2Z1bCwgcmV0dXJuIHRoZSBjb250cm9sbGluZyBjb25kaXRpb24gYW5kIHRoZSBvcGVyYW5kcyB0aGF0CisgIC8vLyBkZXRlcm1pbmUgdGhlIHRydWUgYW5kIGZhbHNlIHJlc3VsdCB2YWx1ZXMuCisgIC8vLworICAvLy8gICBSZXN1bHQgPSBTRUxFQ1QgQ29uZCwgVHJ1ZU9wLCBGYWxzZU9wCisgIC8vLworICAvLy8gU29tZSB0YXJnZXRzIGNhbiBvcHRpbWl6ZSBzZWxlY3QgaW5zdHJ1Y3Rpb25zLCBmb3IgZXhhbXBsZSBieSBwcmVkaWNhdGluZworICAvLy8gdGhlIGluc3RydWN0aW9uIGRlZmluaW5nIG9uZSBvZiB0aGUgb3BlcmFuZHMuIFN1Y2ggdGFyZ2V0cyBzaG91bGQgc2V0CisgIC8vLyBPcHRpbWl6YWJsZS4KKyAgLy8vCisgIC8vLyBAcGFyYW0gICAgICAgICBNSSBTZWxlY3QgaW5zdHJ1Y3Rpb24gdG8gYW5hbHl6ZS4KKyAgLy8vIEBwYXJhbSBDb25kICAgIENvbmRpdGlvbiBjb250cm9sbGluZyB0aGUgc2VsZWN0LgorICAvLy8gQHBhcmFtIFRydWVPcCAgT3BlcmFuZCBudW1iZXIgb2YgdGhlIHZhbHVlIHNlbGVjdGVkIHdoZW4gQ29uZCBpcyB0cnVlLgorICAvLy8gQHBhcmFtIEZhbHNlT3AgT3BlcmFuZCBudW1iZXIgb2YgdGhlIHZhbHVlIHNlbGVjdGVkIHdoZW4gQ29uZCBpcyBmYWxzZS4KKyAgLy8vIEBwYXJhbSBPcHRpbWl6YWJsZSBSZXR1cm5lZCBhcyB0cnVlIGlmIE1JIGlzIG9wdGltaXphYmxlLgorICAvLy8gQHJldHVybnMgRmFsc2Ugb24gc3VjY2Vzcy4KKyAgdmlydHVhbCBib29sIGFuYWx5emVTZWxlY3QoY29uc3QgTWFjaGluZUluc3RyICZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVPcGVyYW5kPiAmQ29uZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgJlRydWVPcCwgdW5zaWduZWQgJkZhbHNlT3AsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgJk9wdGltaXphYmxlKSBjb25zdCB7CisgICAgYXNzZXJ0KE1JLmdldERlc2MoKS5pc1NlbGVjdCgpICYmICJNSSBtdXN0IGJlIGEgc2VsZWN0IGluc3RydWN0aW9uIik7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLy8gR2l2ZW4gYSBzZWxlY3QgaW5zdHJ1Y3Rpb24gdGhhdCB3YXMgdW5kZXJzdG9vZCBieQorICAvLy8gYW5hbHl6ZVNlbGVjdCBhbmQgcmV0dXJuZWQgT3B0aW1pemFibGUgPSB0cnVlLCBhdHRlbXB0IHRvIG9wdGltaXplIE1JIGJ5CisgIC8vLyBtZXJnaW5nIGl0IHdpdGggb25lIG9mIGl0cyBvcGVyYW5kcy4gUmV0dXJucyBOVUxMIG9uIGZhaWx1cmUuCisgIC8vLworICAvLy8gV2hlbiBzdWNjZXNzZnVsLCByZXR1cm5zIHRoZSBuZXcgc2VsZWN0IGluc3RydWN0aW9uLiBUaGUgY2xpZW50IGlzCisgIC8vLyByZXNwb25zaWJsZSBmb3IgZGVsZXRpbmcgTUkuCisgIC8vLworICAvLy8gSWYgYm90aCBzaWRlcyBvZiB0aGUgc2VsZWN0IGNhbiBiZSBvcHRpbWl6ZWQsIFByZWZlckZhbHNlIGlzIHVzZWQgdG8gcGljaworICAvLy8gYSBzaWRlLgorICAvLy8KKyAgLy8vIEBwYXJhbSBNSSAgICAgICAgICBPcHRpbWl6YWJsZSBzZWxlY3QgaW5zdHJ1Y3Rpb24uCisgIC8vLyBAcGFyYW0gTmV3TUlzICAgICBTZXQgdGhhdCByZWNvcmQgYWxsIE1JcyBpbiB0aGUgYmFzaWMgYmxvY2sgdXAgdG8gXHAKKyAgLy8vIE1JLiBIYXMgdG8gYmUgdXBkYXRlZCB3aXRoIGFueSBuZXdseSBjcmVhdGVkIE1JIG9yIGRlbGV0ZWQgb25lcy4KKyAgLy8vIEBwYXJhbSBQcmVmZXJGYWxzZSBUcnkgdG8gb3B0aW1pemUgRmFsc2VPcCBpbnN0ZWFkIG9mIFRydWVPcC4KKyAgLy8vIEByZXR1cm5zIE9wdGltaXplZCBpbnN0cnVjdGlvbiBvciBOVUxMLgorICB2aXJ0dWFsIE1hY2hpbmVJbnN0ciAqb3B0aW1pemVTZWxlY3QoTWFjaGluZUluc3RyICZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNtYWxsUHRyU2V0SW1wbDxNYWNoaW5lSW5zdHIgKj4gJk5ld01JcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgUHJlZmVyRmFsc2UgPSBmYWxzZSkgY29uc3QgeworICAgIC8vIFRoaXMgZnVuY3Rpb24gbXVzdCBiZSBpbXBsZW1lbnRlZCBpZiBPcHRpbWl6YWJsZSBpcyBldmVyIHNldC4KKyAgICBsbHZtX3VucmVhY2hhYmxlKCJUYXJnZXQgbXVzdCBpbXBsZW1lbnQgVGFyZ2V0SW5zdHJJbmZvOjpvcHRpbWl6ZVNlbGVjdCEiKTsKKyAgfQorCisgIC8vLyBFbWl0IGluc3RydWN0aW9ucyB0byBjb3B5IGEgcGFpciBvZiBwaHlzaWNhbCByZWdpc3RlcnMuCisgIC8vLworICAvLy8gVGhpcyBmdW5jdGlvbiBzaG91bGQgc3VwcG9ydCBjb3BpZXMgd2l0aGluIGFueSBsZWdhbCByZWdpc3RlciBjbGFzcyBhcworICAvLy8gd2VsbCBhcyBhbnkgY3Jvc3MtY2xhc3MgY29waWVzIGNyZWF0ZWQgZHVyaW5nIGluc3RydWN0aW9uIHNlbGVjdGlvbi4KKyAgLy8vCisgIC8vLyBUaGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiByZWdpc3RlcnMgbWF5IG92ZXJsYXAsIHdoaWNoIG1heSByZXF1aXJlIGEKKyAgLy8vIGNhcmVmdWwgaW1wbGVtZW50YXRpb24gd2hlbiBtdWx0aXBsZSBjb3B5IGluc3RydWN0aW9ucyBhcmUgcmVxdWlyZWQgZm9yCisgIC8vLyBsYXJnZSByZWdpc3RlcnMuIFNlZSBmb3IgZXhhbXBsZSB0aGUgQVJNIHRhcmdldC4KKyAgdmlydHVhbCB2b2lkIGNvcHlQaHlzUmVnKE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgTUksIGNvbnN0IERlYnVnTG9jICZETCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIERlc3RSZWcsIHVuc2lnbmVkIFNyY1JlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgS2lsbFNyYykgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIlRhcmdldCBkaWRuJ3QgaW1wbGVtZW50IFRhcmdldEluc3RySW5mbzo6Y29weVBoeXNSZWchIik7CisgIH0KKworICAvLy8gU3RvcmUgdGhlIHNwZWNpZmllZCByZWdpc3RlciBvZiB0aGUgZ2l2ZW4gcmVnaXN0ZXIgY2xhc3MgdG8gdGhlIHNwZWNpZmllZAorICAvLy8gc3RhY2sgZnJhbWUgaW5kZXguIFRoZSBzdG9yZSBpbnN0cnVjdGlvbiBpcyB0byBiZSBhZGRlZCB0byB0aGUgZ2l2ZW4KKyAgLy8vIG1hY2hpbmUgYmFzaWMgYmxvY2sgYmVmb3JlIHRoZSBzcGVjaWZpZWQgbWFjaGluZSBpbnN0cnVjdGlvbi4gSWYgaXNLaWxsCisgIC8vLyBpcyB0cnVlLCB0aGUgcmVnaXN0ZXIgb3BlcmFuZCBpcyB0aGUgbGFzdCB1c2UgYW5kIG11c3QgYmUgbWFya2VkIGtpbGwuCisgIHZpcnR1YWwgdm9pZCBzdG9yZVJlZ1RvU3RhY2tTbG90KE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgU3JjUmVnLCBib29sIGlzS2lsbCwgaW50IEZyYW1lSW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSkgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIlRhcmdldCBkaWRuJ3QgaW1wbGVtZW50ICIKKyAgICAgICAgICAgICAgICAgICAgICJUYXJnZXRJbnN0ckluZm86OnN0b3JlUmVnVG9TdGFja1Nsb3QhIik7CisgIH0KKworICAvLy8gTG9hZCB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyIG9mIHRoZSBnaXZlbiByZWdpc3RlciBjbGFzcyBmcm9tIHRoZSBzcGVjaWZpZWQKKyAgLy8vIHN0YWNrIGZyYW1lIGluZGV4LiBUaGUgbG9hZCBpbnN0cnVjdGlvbiBpcyB0byBiZSBhZGRlZCB0byB0aGUgZ2l2ZW4KKyAgLy8vIG1hY2hpbmUgYmFzaWMgYmxvY2sgYmVmb3JlIHRoZSBzcGVjaWZpZWQgbWFjaGluZSBpbnN0cnVjdGlvbi4KKyAgdmlydHVhbCB2b2lkIGxvYWRSZWdGcm9tU3RhY2tTbG90KE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBEZXN0UmVnLCBpbnQgRnJhbWVJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkpIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJUYXJnZXQgZGlkbid0IGltcGxlbWVudCAiCisgICAgICAgICAgICAgICAgICAgICAiVGFyZ2V0SW5zdHJJbmZvOjpsb2FkUmVnRnJvbVN0YWNrU2xvdCEiKTsKKyAgfQorCisgIC8vLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBmb3IgYWxsIHBzZXVkbyBpbnN0cnVjdGlvbnMKKyAgLy8vIHRoYXQgcmVtYWluIGFmdGVyIHJlZ2lzdGVyIGFsbG9jYXRpb24uIE1hbnkgcHNldWRvIGluc3RydWN0aW9ucyBhcmUKKyAgLy8vIGNyZWF0ZWQgdG8gaGVscCByZWdpc3RlciBhbGxvY2F0aW9uLiBUaGlzIGlzIHRoZSBwbGFjZSB0byBjb252ZXJ0IHRoZW0KKyAgLy8vIGludG8gcmVhbCBpbnN0cnVjdGlvbnMuIFRoZSB0YXJnZXQgY2FuIGVkaXQgTUkgaW4gcGxhY2UsIG9yIGl0IGNhbiBpbnNlcnQKKyAgLy8vIG5ldyBpbnN0cnVjdGlvbnMgYW5kIGVyYXNlIE1JLiBUaGUgZnVuY3Rpb24gc2hvdWxkIHJldHVybiB0cnVlIGlmCisgIC8vLyBhbnl0aGluZyB3YXMgY2hhbmdlZC4KKyAgdmlydHVhbCBib29sIGV4cGFuZFBvc3RSQVBzZXVkbyhNYWNoaW5lSW5zdHIgJk1JKSBjb25zdCB7IHJldHVybiBmYWxzZTsgfQorCisgIC8vLyBDaGVjayB3aGV0aGVyIHRoZSB0YXJnZXQgY2FuIGZvbGQgYSBsb2FkIHRoYXQgZmVlZHMgYSBzdWJyZWcgb3BlcmFuZAorICAvLy8gKG9yIGEgc3VicmVnIG9wZXJhbmQgdGhhdCBmZWVkcyBhIHN0b3JlKS4KKyAgLy8vIEZvciBleGFtcGxlLCBYODYgbWF5IHdhbnQgdG8gcmV0dXJuIHRydWUgaWYgaXQgY2FuIGZvbGQKKyAgLy8vIG1vdmwgKCVlc3ApLCAlZWF4CisgIC8vLyBzdWJiLCAlYWwsIC4uLgorICAvLy8gSW50bzoKKyAgLy8vIHN1YmIgKCVlc3ApLCAuLi4KKyAgLy8vCisgIC8vLyBJZGVhbGx5LCB3ZSdkIGxpa2UgdGhlIHRhcmdldCBpbXBsZW1lbnRhdGlvbiBvZiBmb2xkTWVtb3J5T3BlcmFuZCgpIHRvCisgIC8vLyByZWplY3Qgc3VicmVncyAtIGJ1dCBzaW5jZSB0aGlzIGJlaGF2aW9yIHVzZWQgdG8gYmUgZW5mb3JjZWQgaW4gdGhlCisgIC8vLyB0YXJnZXQtaW5kZXBlbmRlbnQgY29kZSwgbW92aW5nIHRoaXMgcmVzcG9uc2liaWxpdHkgdG8gdGhlIHRhcmdldHMKKyAgLy8vIGhhcyB0aGUgcG90ZW50aWFsIG9mIGNhdXNpbmcgbmFzdHkgc2lsZW50IGJyZWFrYWdlIGluIG91dC1vZi10cmVlIHRhcmdldHMuCisgIHZpcnR1YWwgYm9vbCBpc1N1YnJlZ0ZvbGRhYmxlKCkgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KKworICAvLy8gQXR0ZW1wdCB0byBmb2xkIGEgbG9hZCBvciBzdG9yZSBvZiB0aGUgc3BlY2lmaWVkIHN0YWNrCisgIC8vLyBzbG90IGludG8gdGhlIHNwZWNpZmllZCBtYWNoaW5lIGluc3RydWN0aW9uIGZvciB0aGUgc3BlY2lmaWVkIG9wZXJhbmQocykuCisgIC8vLyBJZiB0aGlzIGlzIHBvc3NpYmxlLCBhIG5ldyBpbnN0cnVjdGlvbiBpcyByZXR1cm5lZCB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgLy8vIG9wZXJhbmQgZm9sZGVkLCBvdGhlcndpc2UgTlVMTCBpcyByZXR1cm5lZC4KKyAgLy8vIFRoZSBuZXcgaW5zdHJ1Y3Rpb24gaXMgaW5zZXJ0ZWQgYmVmb3JlIE1JLCBhbmQgdGhlIGNsaWVudCBpcyByZXNwb25zaWJsZQorICAvLy8gZm9yIHJlbW92aW5nIHRoZSBvbGQgaW5zdHJ1Y3Rpb24uCisgIE1hY2hpbmVJbnN0ciAqZm9sZE1lbW9yeU9wZXJhbmQoTWFjaGluZUluc3RyICZNSSwgQXJyYXlSZWY8dW5zaWduZWQ+IE9wcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgRnJhbWVJbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMaXZlSW50ZXJ2YWxzICpMSVMgPSBudWxscHRyKSBjb25zdDsKKworICAvLy8gU2FtZSBhcyB0aGUgcHJldmlvdXMgdmVyc2lvbiBleGNlcHQgaXQgYWxsb3dzIGZvbGRpbmcgb2YgYW55IGxvYWQgYW5kCisgIC8vLyBzdG9yZSBmcm9tIC8gdG8gYW55IGFkZHJlc3MsIG5vdCBqdXN0IGZyb20gYSBzcGVjaWZpYyBzdGFjayBzbG90LgorICBNYWNoaW5lSW5zdHIgKmZvbGRNZW1vcnlPcGVyYW5kKE1hY2hpbmVJbnN0ciAmTUksIEFycmF5UmVmPHVuc2lnbmVkPiBPcHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUluc3RyICZMb2FkTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGl2ZUludGVydmFscyAqTElTID0gbnVsbHB0cikgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIHdoZW4gdGhlcmUgaXMgcG90ZW50aWFsbHkgYSBmYXN0ZXIgY29kZSBzZXF1ZW5jZQorICAvLy8gZm9yIGFuIGluc3RydWN0aW9uIGNoYWluIGVuZGluZyBpbiBccCBSb290LiBBbGwgcG90ZW50aWFsIHBhdHRlcm5zIGFyZQorICAvLy8gcmV0dXJuZWQgaW4gdGhlIFxwIFBhdHRlcm4gdmVjdG9yLiBQYXR0ZXJuIHNob3VsZCBiZSBzb3J0ZWQgaW4gcHJpb3JpdHkKKyAgLy8vIG9yZGVyIHNpbmNlIHRoZSBwYXR0ZXJuIGV2YWx1YXRvciBzdG9wcyBjaGVja2luZyBhcyBzb29uIGFzIGl0IGZpbmRzIGEKKyAgLy8vIGZhc3RlciBzZXF1ZW5jZS4KKyAgLy8vIFxwYXJhbSBSb290IC0gSW5zdHJ1Y3Rpb24gdGhhdCBjb3VsZCBiZSBjb21iaW5lZCB3aXRoIG9uZSBvZiBpdHMgb3BlcmFuZHMKKyAgLy8vIFxwYXJhbSBQYXR0ZXJucyAtIFZlY3RvciBvZiBwb3NzaWJsZSBjb21iaW5hdGlvbiBwYXR0ZXJucworICB2aXJ0dWFsIGJvb2wgZ2V0TWFjaGluZUNvbWJpbmVyUGF0dGVybnMoCisgICAgICBNYWNoaW5lSW5zdHIgJlJvb3QsCisgICAgICBTbWFsbFZlY3RvckltcGw8TWFjaGluZUNvbWJpbmVyUGF0dGVybj4gJlBhdHRlcm5zKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgd2hlbiBhIGNvZGUgc2VxdWVuY2UgY2FuIGltcHJvdmUgdGhyb3VnaHB1dC4gSXQKKyAgLy8vIHNob3VsZCBiZSBjYWxsZWQgb25seSBmb3IgaW5zdHJ1Y3Rpb25zIGluIGxvb3BzLgorICAvLy8gXHBhcmFtIFBhdHRlcm4gLSBjb21iaW5lciBwYXR0ZXJuCisgIHZpcnR1YWwgYm9vbCBpc1Rocm91Z2hwdXRQYXR0ZXJuKE1hY2hpbmVDb21iaW5lclBhdHRlcm4gUGF0dGVybikgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBpbnB1dCBcUCBJbnN0IGlzIHBhcnQgb2YgYSBjaGFpbiBvZiBkZXBlbmRlbnQgb3BzCisgIC8vLyB0aGF0IGFyZSBzdWl0YWJsZSBmb3IgcmVhc3NvY2lhdGlvbiwgb3RoZXJ3aXNlIHJldHVybiBmYWxzZS4KKyAgLy8vIElmIHRoZSBpbnN0cnVjdGlvbidzIG9wZXJhbmRzIG11c3QgYmUgY29tbXV0ZWQgdG8gaGF2ZSBhIHByZXZpb3VzCisgIC8vLyBpbnN0cnVjdGlvbiBvZiB0aGUgc2FtZSB0eXBlIGRlZmluZSB0aGUgZmlyc3Qgc291cmNlIG9wZXJhbmQsIFxQIENvbW11dGVkCisgIC8vLyB3aWxsIGJlIHNldCB0byB0cnVlLgorICBib29sIGlzUmVhc3NvY2lhdGlvbkNhbmRpZGF0ZShjb25zdCBNYWNoaW5lSW5zdHIgJkluc3QsIGJvb2wgJkNvbW11dGVkKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgd2hlbiBcUCBJbnN0IGlzIGJvdGggYXNzb2NpYXRpdmUgYW5kIGNvbW11dGF0aXZlLgorICB2aXJ0dWFsIGJvb2wgaXNBc3NvY2lhdGl2ZUFuZENvbW11dGF0aXZlKGNvbnN0IE1hY2hpbmVJbnN0ciAmSW5zdCkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSB3aGVuIFxQIEluc3QgaGFzIHJlYXNzb2NpYWJsZSBvcGVyYW5kcyBpbiB0aGUgc2FtZSBcUCBNQkIuCisgIHZpcnR1YWwgYm9vbCBoYXNSZWFzc29jaWFibGVPcGVyYW5kcyhjb25zdCBNYWNoaW5lSW5zdHIgJkluc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lQmFzaWNCbG9jayAqTUJCKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgd2hlbiBcUCBJbnN0IGhhcyByZWFzc29jaWFibGUgc2libGluZy4KKyAgYm9vbCBoYXNSZWFzc29jaWFibGVTaWJsaW5nKGNvbnN0IE1hY2hpbmVJbnN0ciAmSW5zdCwgYm9vbCAmQ29tbXV0ZWQpIGNvbnN0OworCisgIC8vLyBXaGVuIGdldE1hY2hpbmVDb21iaW5lclBhdHRlcm5zKCkgZmluZHMgcGF0dGVybnMsIHRoaXMgZnVuY3Rpb24gZ2VuZXJhdGVzCisgIC8vLyB0aGUgaW5zdHJ1Y3Rpb25zIHRoYXQgY291bGQgcmVwbGFjZSB0aGUgb3JpZ2luYWwgY29kZSBzZXF1ZW5jZS4gVGhlIGNsaWVudAorICAvLy8gaGFzIHRvIGRlY2lkZSB3aGV0aGVyIHRoZSBhY3R1YWwgcmVwbGFjZW1lbnQgaXMgYmVuZWZpY2lhbCBvciBub3QuCisgIC8vLyBccGFyYW0gUm9vdCAtIEluc3RydWN0aW9uIHRoYXQgY291bGQgYmUgY29tYmluZWQgd2l0aCBvbmUgb2YgaXRzIG9wZXJhbmRzCisgIC8vLyBccGFyYW0gUGF0dGVybiAtIENvbWJpbmF0aW9uIHBhdHRlcm4gZm9yIFJvb3QKKyAgLy8vIFxwYXJhbSBJbnNJbnN0cnMgLSBWZWN0b3Igb2YgbmV3IGluc3RydWN0aW9ucyB0aGF0IGltcGxlbWVudCBQCisgIC8vLyBccGFyYW0gRGVsSW5zdHJzIC0gT2xkIGluc3RydWN0aW9ucywgaW5jbHVkaW5nIFJvb3QsIHRoYXQgY291bGQgYmUKKyAgLy8vIHJlcGxhY2VkIGJ5IEluc0luc3RyCisgIC8vLyBccGFyYW0gSW5zdHJJZHhGb3JWaXJ0UmVnIC0gbWFwIG9mIHZpcnR1YWwgcmVnaXN0ZXIgdG8gaW5zdHJ1Y3Rpb24gaW4KKyAgLy8vIEluc0luc3RyIHRoYXQgZGVmaW5lcyBpdAorICB2aXJ0dWFsIHZvaWQgZ2VuQWx0ZXJuYXRpdmVDb2RlU2VxdWVuY2UoCisgICAgICBNYWNoaW5lSW5zdHIgJlJvb3QsIE1hY2hpbmVDb21iaW5lclBhdHRlcm4gUGF0dGVybiwKKyAgICAgIFNtYWxsVmVjdG9ySW1wbDxNYWNoaW5lSW5zdHIgKj4gJkluc0luc3RycywKKyAgICAgIFNtYWxsVmVjdG9ySW1wbDxNYWNoaW5lSW5zdHIgKj4gJkRlbEluc3RycywKKyAgICAgIERlbnNlTWFwPHVuc2lnbmVkLCB1bnNpZ25lZD4gJkluc3RySWR4Rm9yVmlydFJlZykgY29uc3Q7CisKKyAgLy8vIEF0dGVtcHQgdG8gcmVhc3NvY2lhdGUgXFAgUm9vdCBhbmQgXFAgUHJldiBhY2NvcmRpbmcgdG8gXFAgUGF0dGVybiB0bworICAvLy8gcmVkdWNlIGNyaXRpY2FsIHBhdGggbGVuZ3RoLgorICB2b2lkIHJlYXNzb2NpYXRlT3BzKE1hY2hpbmVJbnN0ciAmUm9vdCwgTWFjaGluZUluc3RyICZQcmV2LAorICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVDb21iaW5lclBhdHRlcm4gUGF0dGVybiwKKyAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8TWFjaGluZUluc3RyICo+ICZJbnNJbnN0cnMsCisgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVJbnN0ciAqPiAmRGVsSW5zdHJzLAorICAgICAgICAgICAgICAgICAgICAgIERlbnNlTWFwPHVuc2lnbmVkLCB1bnNpZ25lZD4gJkluc3RySWR4Rm9yVmlydFJlZykgY29uc3Q7CisKKyAgLy8vIFRoaXMgaXMgYW4gYXJjaGl0ZWN0dXJlLXNwZWNpZmljIGhlbHBlciBmdW5jdGlvbiBvZiByZWFzc29jaWF0ZU9wcy4KKyAgLy8vIFNldCBzcGVjaWFsIG9wZXJhbmQgYXR0cmlidXRlcyBmb3IgbmV3IGluc3RydWN0aW9ucyBhZnRlciByZWFzc29jaWF0aW9uLgorICB2aXJ0dWFsIHZvaWQgc2V0U3BlY2lhbE9wZXJhbmRBdHRyKE1hY2hpbmVJbnN0ciAmT2xkTUkxLCBNYWNoaW5lSW5zdHIgJk9sZE1JMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSW5zdHIgJk5ld01JMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSW5zdHIgJk5ld01JMikgY29uc3Qge30KKworICAvLy8gUmV0dXJuIHRydWUgd2hlbiBhIHRhcmdldCBzdXBwb3J0cyBNYWNoaW5lQ29tYmluZXIuCisgIHZpcnR1YWwgYm9vbCB1c2VNYWNoaW5lQ29tYmluZXIoKSBjb25zdCB7IHJldHVybiBmYWxzZTsgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gU0ROb2RlIGNhbiBiZSBjb3BpZWQgZHVyaW5nIHNjaGVkdWxpbmcKKyAgLy8vIGV2ZW4gaWYgaXQgaGFzIGdsdWUuCisgIHZpcnR1YWwgYm9vbCBjYW5Db3B5R2x1ZWROb2RlRHVyaW5nU2NoZWR1bGUoU0ROb2RlICpOKSBjb25zdCB7IHJldHVybiBmYWxzZTsgfQorCisgIC8vLyBSZW1lbWJlciB3aGF0IHJlZ2lzdGVycyB0aGUgc3BlY2lmaWVkIGluc3RydWN0aW9uIHVzZXMgYW5kIG1vZGlmaWVzLgorICB2aXJ0dWFsIHZvaWQgdHJhY2tSZWdEZWZzVXNlcyhjb25zdCBNYWNoaW5lSW5zdHIgJk1JLCBCaXRWZWN0b3IgJk1vZGlmaWVkUmVncywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQml0VmVjdG9yICZVc2VkUmVncywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkpIGNvbnN0OworCitwcm90ZWN0ZWQ6CisgIC8vLyBUYXJnZXQtZGVwZW5kZW50IGltcGxlbWVudGF0aW9uIGZvciBmb2xkTWVtb3J5T3BlcmFuZC4KKyAgLy8vIFRhcmdldC1pbmRlcGVuZGVudCBjb2RlIGluIGZvbGRNZW1vcnlPcGVyYW5kIHdpbGwKKyAgLy8vIHRha2UgY2FyZSBvZiBhZGRpbmcgYSBNYWNoaW5lTWVtT3BlcmFuZCB0byB0aGUgbmV3bHkgY3JlYXRlZCBpbnN0cnVjdGlvbi4KKyAgLy8vIFRoZSBpbnN0cnVjdGlvbiBhbmQgYW55IGF1eGlsaWFyeSBpbnN0cnVjdGlvbnMgbmVjZXNzYXJ5IHdpbGwgYmUgaW5zZXJ0ZWQKKyAgLy8vIGF0IEluc2VydFB0LgorICB2aXJ0dWFsIE1hY2hpbmVJbnN0ciAqCisgIGZvbGRNZW1vcnlPcGVyYW5kSW1wbChNYWNoaW5lRnVuY3Rpb24gJk1GLCBNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8dW5zaWduZWQ+IE9wcywKKyAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBJbnNlcnRQdCwgaW50IEZyYW1lSW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICBMaXZlSW50ZXJ2YWxzICpMSVMgPSBudWxscHRyKSBjb25zdCB7CisgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKworICAvLy8gVGFyZ2V0LWRlcGVuZGVudCBpbXBsZW1lbnRhdGlvbiBmb3IgZm9sZE1lbW9yeU9wZXJhbmQuCisgIC8vLyBUYXJnZXQtaW5kZXBlbmRlbnQgY29kZSBpbiBmb2xkTWVtb3J5T3BlcmFuZCB3aWxsCisgIC8vLyB0YWtlIGNhcmUgb2YgYWRkaW5nIGEgTWFjaGluZU1lbU9wZXJhbmQgdG8gdGhlIG5ld2x5IGNyZWF0ZWQgaW5zdHJ1Y3Rpb24uCisgIC8vLyBUaGUgaW5zdHJ1Y3Rpb24gYW5kIGFueSBhdXhpbGlhcnkgaW5zdHJ1Y3Rpb25zIG5lY2Vzc2FyeSB3aWxsIGJlIGluc2VydGVkCisgIC8vLyBhdCBJbnNlcnRQdC4KKyAgdmlydHVhbCBNYWNoaW5lSW5zdHIgKmZvbGRNZW1vcnlPcGVyYW5kSW1wbCgKKyAgICAgIE1hY2hpbmVGdW5jdGlvbiAmTUYsIE1hY2hpbmVJbnN0ciAmTUksIEFycmF5UmVmPHVuc2lnbmVkPiBPcHMsCisgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgSW5zZXJ0UHQsIE1hY2hpbmVJbnN0ciAmTG9hZE1JLAorICAgICAgTGl2ZUludGVydmFscyAqTElTID0gbnVsbHB0cikgY29uc3QgeworICAgIHJldHVybiBudWxscHRyOworICB9CisKKyAgLy8vIFxicmllZiBUYXJnZXQtZGVwZW5kZW50IGltcGxlbWVudGF0aW9uIG9mIGdldFJlZ1NlcXVlbmNlSW5wdXRzLgorICAvLy8KKyAgLy8vIFxyZXR1cm5zIHRydWUgaWYgaXQgaXMgcG9zc2libGUgdG8gYnVpbGQgdGhlIGVxdWl2YWxlbnQKKyAgLy8vIFJFR19TRVFVRU5DRSBpbnB1dHMgd2l0aCB0aGUgcGFpciBccCBNSSwgXHAgRGVmSWR4LiBGYWxzZSBvdGhlcndpc2UuCisgIC8vLworICAvLy8gXHByZSBNSS5pc1JlZ1NlcXVlbmNlTGlrZSgpLgorICAvLy8KKyAgLy8vIFxzZWUgVGFyZ2V0SW5zdHJJbmZvOjpnZXRSZWdTZXF1ZW5jZUlucHV0cy4KKyAgdmlydHVhbCBib29sIGdldFJlZ1NlcXVlbmNlTGlrZUlucHV0cygKKyAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ciAmTUksIHVuc2lnbmVkIERlZklkeCwKKyAgICAgIFNtYWxsVmVjdG9ySW1wbDxSZWdTdWJSZWdQYWlyQW5kSWR4PiAmSW5wdXRSZWdzKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFxicmllZiBUYXJnZXQtZGVwZW5kZW50IGltcGxlbWVudGF0aW9uIG9mIGdldEV4dHJhY3RTdWJyZWdJbnB1dHMuCisgIC8vLworICAvLy8gXHJldHVybnMgdHJ1ZSBpZiBpdCBpcyBwb3NzaWJsZSB0byBidWlsZCB0aGUgZXF1aXZhbGVudAorICAvLy8gRVhUUkFDVF9TVUJSRUcgaW5wdXRzIHdpdGggdGhlIHBhaXIgXHAgTUksIFxwIERlZklkeC4gRmFsc2Ugb3RoZXJ3aXNlLgorICAvLy8KKyAgLy8vIFxwcmUgTUkuaXNFeHRyYWN0U3VicmVnTGlrZSgpLgorICAvLy8KKyAgLy8vIFxzZWUgVGFyZ2V0SW5zdHJJbmZvOjpnZXRFeHRyYWN0U3VicmVnSW5wdXRzLgorICB2aXJ0dWFsIGJvb2wgZ2V0RXh0cmFjdFN1YnJlZ0xpa2VJbnB1dHMoY29uc3QgTWFjaGluZUluc3RyICZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIERlZklkeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1N1YlJlZ1BhaXJBbmRJZHggJklucHV0UmVnKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFxicmllZiBUYXJnZXQtZGVwZW5kZW50IGltcGxlbWVudGF0aW9uIG9mIGdldEluc2VydFN1YnJlZ0lucHV0cy4KKyAgLy8vCisgIC8vLyBccmV0dXJucyB0cnVlIGlmIGl0IGlzIHBvc3NpYmxlIHRvIGJ1aWxkIHRoZSBlcXVpdmFsZW50CisgIC8vLyBJTlNFUlRfU1VCUkVHIGlucHV0cyB3aXRoIHRoZSBwYWlyIFxwIE1JLCBccCBEZWZJZHguIEZhbHNlIG90aGVyd2lzZS4KKyAgLy8vCisgIC8vLyBccHJlIE1JLmlzSW5zZXJ0U3VicmVnTGlrZSgpLgorICAvLy8KKyAgLy8vIFxzZWUgVGFyZ2V0SW5zdHJJbmZvOjpnZXRJbnNlcnRTdWJyZWdJbnB1dHMuCisgIHZpcnR1YWwgYm9vbAorICBnZXRJbnNlcnRTdWJyZWdMaWtlSW5wdXRzKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUksIHVuc2lnbmVkIERlZklkeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdTdWJSZWdQYWlyICZCYXNlUmVnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ1N1YlJlZ1BhaXJBbmRJZHggJkluc2VydGVkUmVnKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKK3B1YmxpYzoKKyAgLy8vIGdldEFkZHJlc3NTcGFjZUZvclBzZXVkb1NvdXJjZUtpbmQgLSBHaXZlbiB0aGUga2luZCBvZiBtZW1vcnkKKyAgLy8vIChlLmcuIHN0YWNrKSB0aGUgdGFyZ2V0IHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgYWRkcmVzcyBzcGFjZS4KKyAgdmlydHVhbCB1bnNpZ25lZAorICBnZXRBZGRyZXNzU3BhY2VGb3JQc2V1ZG9Tb3VyY2VLaW5kKFBzZXVkb1NvdXJjZVZhbHVlOjpQU1ZLaW5kIEtpbmQpIGNvbnN0IHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIC8vLyB1bmZvbGRNZW1vcnlPcGVyYW5kIC0gU2VwYXJhdGUgYSBzaW5nbGUgaW5zdHJ1Y3Rpb24gd2hpY2ggZm9sZGVkIGEgbG9hZCBvcgorICAvLy8gYSBzdG9yZSBvciBhIGxvYWQgYW5kIGEgc3RvcmUgaW50byB0d28gb3IgbW9yZSBpbnN0cnVjdGlvbi4gSWYgdGhpcyBpcworICAvLy8gcG9zc2libGUsIHJldHVybnMgdHJ1ZSBhcyB3ZWxsIGFzIHRoZSBuZXcgaW5zdHJ1Y3Rpb25zIGJ5IHJlZmVyZW5jZS4KKyAgdmlydHVhbCBib29sCisgIHVuZm9sZE1lbW9yeU9wZXJhbmQoTWFjaGluZUZ1bmN0aW9uICZNRiwgTWFjaGluZUluc3RyICZNSSwgdW5zaWduZWQgUmVnLAorICAgICAgICAgICAgICAgICAgICAgIGJvb2wgVW5mb2xkTG9hZCwgYm9vbCBVbmZvbGRTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8TWFjaGluZUluc3RyICo+ICZOZXdNSXMpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICB2aXJ0dWFsIGJvb2wgdW5mb2xkTWVtb3J5T3BlcmFuZChTZWxlY3Rpb25EQUcgJkRBRywgU0ROb2RlICpOLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8U0ROb2RlICo+ICZOZXdOb2RlcykgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRoZSBvcGNvZGUgb2YgdGhlIHdvdWxkIGJlIG5ldworICAvLy8gaW5zdHJ1Y3Rpb24gYWZ0ZXIgbG9hZCAvIHN0b3JlIGFyZSB1bmZvbGRlZCBmcm9tIGFuIGluc3RydWN0aW9uIG9mIHRoZQorICAvLy8gc3BlY2lmaWVkIG9wY29kZS4gSXQgcmV0dXJucyB6ZXJvIGlmIHRoZSBzcGVjaWZpZWQgdW5mb2xkaW5nIGlzIG5vdAorICAvLy8gcG9zc2libGUuIElmIExvYWRSZWdJbmRleCBpcyBub24tbnVsbCwgaXQgaXMgZmlsbGVkIGluIHdpdGggdGhlIG9wZXJhbmQKKyAgLy8vIGluZGV4IG9mIHRoZSBvcGVyYW5kIHdoaWNoIHdpbGwgaG9sZCB0aGUgcmVnaXN0ZXIgaG9sZGluZyB0aGUgbG9hZGVkCisgIC8vLyB2YWx1ZS4KKyAgdmlydHVhbCB1bnNpZ25lZAorICBnZXRPcGNvZGVBZnRlck1lbW9yeVVuZm9sZCh1bnNpZ25lZCBPcGMsIGJvb2wgVW5mb2xkTG9hZCwgYm9vbCBVbmZvbGRTdG9yZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgKkxvYWRSZWdJbmRleCA9IG51bGxwdHIpIGNvbnN0IHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIC8vLyBUaGlzIGlzIHVzZWQgYnkgdGhlIHByZS1yZWdhbGxvYyBzY2hlZHVsZXIgdG8gZGV0ZXJtaW5lIGlmIHR3byBsb2FkcyBhcmUKKyAgLy8vIGxvYWRpbmcgZnJvbSB0aGUgc2FtZSBiYXNlIGFkZHJlc3MuIEl0IHNob3VsZCBvbmx5IHJldHVybiB0cnVlIGlmIHRoZSBiYXNlCisgIC8vLyBwb2ludGVycyBhcmUgdGhlIHNhbWUgYW5kIHRoZSBvbmx5IGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIHR3byBhZGRyZXNzZXMKKyAgLy8vIGFyZSB0aGUgb2Zmc2V0LiBJdCBhbHNvIHJldHVybnMgdGhlIG9mZnNldHMgYnkgcmVmZXJlbmNlLgorICB2aXJ0dWFsIGJvb2wgYXJlTG9hZHNGcm9tU2FtZUJhc2VQdHIoU0ROb2RlICpMb2FkMSwgU0ROb2RlICpMb2FkMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDY0X3QgJk9mZnNldDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NF90ICZPZmZzZXQyKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFRoaXMgaXMgYSB1c2VkIGJ5IHRoZSBwcmUtcmVnYWxsb2Mgc2NoZWR1bGVyIHRvIGRldGVybWluZSAoaW4gY29uanVuY3Rpb24KKyAgLy8vIHdpdGggYXJlTG9hZHNGcm9tU2FtZUJhc2VQdHIpIGlmIHR3byBsb2FkcyBzaG91bGQgYmUgc2NoZWR1bGVkIHRvZ2V0aGVyLgorICAvLy8gT24gc29tZSB0YXJnZXRzIGlmIHR3byBsb2FkcyBhcmUgbG9hZGluZyBmcm9tCisgIC8vLyBhZGRyZXNzZXMgaW4gdGhlIHNhbWUgY2FjaGUgbGluZSwgaXQncyBiZXR0ZXIgaWYgdGhleSBhcmUgc2NoZWR1bGVkCisgIC8vLyB0b2dldGhlci4gVGhpcyBmdW5jdGlvbiB0YWtlcyB0d28gaW50ZWdlcnMgdGhhdCByZXByZXNlbnQgdGhlIGxvYWQgb2Zmc2V0cworICAvLy8gZnJvbSB0aGUgY29tbW9uIGJhc2UgYWRkcmVzcy4gSXQgcmV0dXJucyB0cnVlIGlmIGl0IGRlY2lkZXMgaXQncyBkZXNpcmFibGUKKyAgLy8vIHRvIHNjaGVkdWxlIHRoZSB0d28gbG9hZHMgdG9nZXRoZXIuICJOdW1Mb2FkcyIgaXMgdGhlIG51bWJlciBvZiBsb2FkcyB0aGF0CisgIC8vLyBoYXZlIGFscmVhZHkgYmVlbiBzY2hlZHVsZWQgYWZ0ZXIgTG9hZDEuCisgIHZpcnR1YWwgYm9vbCBzaG91bGRTY2hlZHVsZUxvYWRzTmVhcihTRE5vZGUgKkxvYWQxLCBTRE5vZGUgKkxvYWQyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50NjRfdCBPZmZzZXQxLCBpbnQ2NF90IE9mZnNldDIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBOdW1Mb2FkcykgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBHZXQgdGhlIGJhc2UgcmVnaXN0ZXIgYW5kIGJ5dGUgb2Zmc2V0IG9mIGFuIGluc3RydWN0aW9uIHRoYXQgcmVhZHMvd3JpdGVzCisgIC8vLyBtZW1vcnkuCisgIHZpcnR1YWwgYm9vbCBnZXRNZW1PcEJhc2VSZWdJbW1PZnMoTWFjaGluZUluc3RyICZNZW1PcCwgdW5zaWduZWQgJkJhc2VSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50NjRfdCAmT2Zmc2V0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBpbnN0cnVjdGlvbiBjb250YWlucyBhIGJhc2UgcmVnaXN0ZXIgYW5kIG9mZnNldC4gSWYKKyAgLy8vIHRydWUsIHRoZSBmdW5jdGlvbiBhbHNvIHNldHMgdGhlIG9wZXJhbmQgcG9zaXRpb24gaW4gdGhlIGluc3RydWN0aW9uCisgIC8vLyBmb3IgdGhlIGJhc2UgcmVnaXN0ZXIgYW5kIG9mZnNldC4KKyAgdmlydHVhbCBib29sIGdldEJhc2VBbmRPZmZzZXRQb3NpdGlvbihjb25zdCBNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkICZCYXNlUG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkICZPZmZzZXRQb3MpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gSWYgdGhlIGluc3RydWN0aW9uIGlzIGFuIGluY3JlbWVudCBvZiBhIGNvbnN0YW50IHZhbHVlLCByZXR1cm4gdGhlIGFtb3VudC4KKyAgdmlydHVhbCBib29sIGdldEluY3JlbWVudFZhbHVlKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUksIGludCAmVmFsdWUpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSB0d28gZ2l2ZW4gbWVtb3J5IG9wZXJhdGlvbnMgc2hvdWxkIGJlIHNjaGVkdWxlZAorICAvLy8gYWRqYWNlbnQuIE5vdGUgdGhhdCB5b3UgaGF2ZSB0byBhZGQ6CisgIC8vLyAgIERBRy0+YWRkTXV0YXRpb24oY3JlYXRlTG9hZENsdXN0ZXJEQUdNdXRhdGlvbihEQUctPlRJSSwgREFHLT5UUkkpKTsKKyAgLy8vIG9yCisgIC8vLyAgIERBRy0+YWRkTXV0YXRpb24oY3JlYXRlU3RvcmVDbHVzdGVyREFHTXV0YXRpb24oREFHLT5USUksIERBRy0+VFJJKSk7CisgIC8vLyB0byBUYXJnZXRQYXNzQ29uZmlnOjpjcmVhdGVNYWNoaW5lU2NoZWR1bGVyKCkgdG8gaGF2ZSBhbiBlZmZlY3QuCisgIHZpcnR1YWwgYm9vbCBzaG91bGRDbHVzdGVyTWVtT3BzKE1hY2hpbmVJbnN0ciAmRmlyc3RMZFN0LCB1bnNpZ25lZCBCYXNlUmVnMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUluc3RyICZTZWNvbmRMZFN0LCB1bnNpZ25lZCBCYXNlUmVnMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgTnVtTG9hZHMpIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJ0YXJnZXQgZGlkIG5vdCBpbXBsZW1lbnQgc2hvdWxkQ2x1c3Rlck1lbU9wcygpIik7CisgIH0KKworICAvLy8gUmV2ZXJzZXMgdGhlIGJyYW5jaCBjb25kaXRpb24gb2YgdGhlIHNwZWNpZmllZCBjb25kaXRpb24gbGlzdCwKKyAgLy8vIHJldHVybmluZyBmYWxzZSBvbiBzdWNjZXNzIGFuZCB0cnVlIGlmIGl0IGNhbm5vdCBiZSByZXZlcnNlZC4KKyAgdmlydHVhbCBib29sCisgIHJldmVyc2VCcmFuY2hDb25kaXRpb24oU21hbGxWZWN0b3JJbXBsPE1hY2hpbmVPcGVyYW5kPiAmQ29uZCkgY29uc3QgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8vIEluc2VydCBhIG5vb3AgaW50byB0aGUgaW5zdHJ1Y3Rpb24gc3RyZWFtIGF0IHRoZSBzcGVjaWZpZWQgcG9pbnQuCisgIHZpcnR1YWwgdm9pZCBpbnNlcnROb29wKE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciBNSSkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0aGUgbm9vcCBpbnN0cnVjdGlvbiB0byB1c2UgZm9yIGEgbm9vcC4KKyAgdmlydHVhbCB2b2lkIGdldE5vb3AoTUNJbnN0ICZOb3BJbnN0KSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgZm9yIHBvc3QtaW5jcmVtZW50ZWQgaW5zdHJ1Y3Rpb25zLgorICB2aXJ0dWFsIGJvb2wgaXNQb3N0SW5jcmVtZW50KGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgaW5zdHJ1Y3Rpb24gaXMgYWxyZWFkeSBwcmVkaWNhdGVkLgorICB2aXJ0dWFsIGJvb2wgaXNQcmVkaWNhdGVkKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgaW5zdHJ1Y3Rpb24gaXMgYQorICAvLy8gdGVybWluYXRvciBpbnN0cnVjdGlvbiB0aGF0IGhhcyBub3QgYmVlbiBwcmVkaWNhdGVkLgorICB2aXJ0dWFsIGJvb2wgaXNVbnByZWRpY2F0ZWRUZXJtaW5hdG9yKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIGNvbnN0OworCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgTUkgaXMgYW4gdW5jb25kaXRpb25hbCB0YWlsIGNhbGwuCisgIHZpcnR1YWwgYm9vbCBpc1VuY29uZGl0aW9uYWxUYWlsQ2FsbChjb25zdCBNYWNoaW5lSW5zdHIgJk1JKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgdGFpbCBjYWxsIGNhbiBiZSBtYWRlIGNvbmRpdGlvbmFsIG9uIEJyYW5jaENvbmQuCisgIHZpcnR1YWwgYm9vbCBjYW5NYWtlVGFpbENhbGxDb25kaXRpb25hbChTbWFsbFZlY3RvckltcGw8TWFjaGluZU9wZXJhbmQ+ICZDb25kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUluc3RyICZUYWlsQ2FsbCkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXBsYWNlIHRoZSBjb25kaXRpb25hbCBicmFuY2ggaW4gTUJCIHdpdGggYSBjb25kaXRpb25hbCB0YWlsIGNhbGwuCisgIHZpcnR1YWwgdm9pZCByZXBsYWNlQnJhbmNoV2l0aFRhaWxDYWxsKE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNtYWxsVmVjdG9ySW1wbDxNYWNoaW5lT3BlcmFuZD4gJkNvbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ciAmVGFpbENhbGwpIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJUYXJnZXQgZGlkbid0IGltcGxlbWVudCByZXBsYWNlQnJhbmNoV2l0aFRhaWxDYWxsISIpOworICB9CisKKyAgLy8vIENvbnZlcnQgdGhlIGluc3RydWN0aW9uIGludG8gYSBwcmVkaWNhdGVkIGluc3RydWN0aW9uLgorICAvLy8gSXQgcmV0dXJucyB0cnVlIGlmIHRoZSBvcGVyYXRpb24gd2FzIHN1Y2Nlc3NmdWwuCisgIHZpcnR1YWwgYm9vbCBQcmVkaWNhdGVJbnN0cnVjdGlvbihNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8TWFjaGluZU9wZXJhbmQ+IFByZWQpIGNvbnN0OworCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIGZpcnN0IHNwZWNpZmllZCBwcmVkaWNhdGUKKyAgLy8vIHN1YnN1bWVzIHRoZSBzZWNvbmQsIGUuZy4gR0Ugc3Vic3VtZXMgR1QuCisgIHZpcnR1YWwgYm9vbCBTdWJzdW1lc1ByZWRpY2F0ZShBcnJheVJlZjxNYWNoaW5lT3BlcmFuZD4gUHJlZDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheVJlZjxNYWNoaW5lT3BlcmFuZD4gUHJlZDIpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gSWYgdGhlIHNwZWNpZmllZCBpbnN0cnVjdGlvbiBkZWZpbmVzIGFueSBwcmVkaWNhdGUKKyAgLy8vIG9yIGNvbmRpdGlvbiBjb2RlIHJlZ2lzdGVyKHMpIHVzZWQgZm9yIHByZWRpY2F0aW9uLCByZXR1cm5zIHRydWUgYXMgd2VsbAorICAvLy8gYXMgdGhlIGRlZmluaXRpb24gcHJlZGljYXRlKHMpIGJ5IHJlZmVyZW5jZS4KKyAgdmlydHVhbCBib29sIERlZmluZXNQcmVkaWNhdGUoTWFjaGluZUluc3RyICZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp2ZWN0b3I8TWFjaGluZU9wZXJhbmQ+ICZQcmVkKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24gY2FuIGJlIHByZWRpY2F0ZWQuCisgIC8vLyBCeSBkZWZhdWx0LCB0aGlzIHJldHVybnMgdHJ1ZSBmb3IgZXZlcnkgaW5zdHJ1Y3Rpb24gd2l0aCBhCisgIC8vLyBQcmVkaWNhdGVPcGVyYW5kLgorICB2aXJ0dWFsIGJvb2wgaXNQcmVkaWNhYmxlKGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIGNvbnN0IHsKKyAgICByZXR1cm4gTUkuZ2V0RGVzYygpLmlzUHJlZGljYWJsZSgpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGl0J3Mgc2FmZSB0byBtb3ZlIGEgbWFjaGluZQorICAvLy8gaW5zdHJ1Y3Rpb24gdGhhdCBkZWZpbmVzIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIgY2xhc3MuCisgIHZpcnR1YWwgYm9vbCBpc1NhZmVUb01vdmVSZWdDbGFzc0RlZnMoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUkMpIGNvbnN0IHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vLyBUZXN0IGlmIHRoZSBnaXZlbiBpbnN0cnVjdGlvbiBzaG91bGQgYmUgY29uc2lkZXJlZCBhIHNjaGVkdWxpbmcgYm91bmRhcnkuCisgIC8vLyBUaGlzIHByaW1hcmlseSBpbmNsdWRlcyBsYWJlbHMgYW5kIHRlcm1pbmF0b3JzLgorICB2aXJ0dWFsIGJvb2wgaXNTY2hlZHVsaW5nQm91bmRhcnkoY29uc3QgTWFjaGluZUluc3RyICZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKSBjb25zdDsKKworICAvLy8gTWVhc3VyZSB0aGUgc3BlY2lmaWVkIGlubGluZSBhc20gdG8gZGV0ZXJtaW5lIGFuIGFwcHJveGltYXRpb24gb2YgaXRzCisgIC8vLyBsZW5ndGguCisgIHZpcnR1YWwgdW5zaWduZWQgZ2V0SW5saW5lQXNtTGVuZ3RoKGNvbnN0IGNoYXIgKlN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTUNBc21JbmZvICZNQUkpIGNvbnN0OworCisgIC8vLyBBbGxvY2F0ZSBhbmQgcmV0dXJuIGEgaGF6YXJkIHJlY29nbml6ZXIgdG8gdXNlIGZvciB0aGlzIHRhcmdldCB3aGVuCisgIC8vLyBzY2hlZHVsaW5nIHRoZSBtYWNoaW5lIGluc3RydWN0aW9ucyBiZWZvcmUgcmVnaXN0ZXIgYWxsb2NhdGlvbi4KKyAgdmlydHVhbCBTY2hlZHVsZUhhemFyZFJlY29nbml6ZXIgKgorICBDcmVhdGVUYXJnZXRIYXphcmRSZWNvZ25pemVyKGNvbnN0IFRhcmdldFN1YnRhcmdldEluZm8gKlNUSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTY2hlZHVsZURBRyAqREFHKSBjb25zdDsKKworICAvLy8gQWxsb2NhdGUgYW5kIHJldHVybiBhIGhhemFyZCByZWNvZ25pemVyIHRvIHVzZSBmb3IgdGhpcyB0YXJnZXQgd2hlbgorICAvLy8gc2NoZWR1bGluZyB0aGUgbWFjaGluZSBpbnN0cnVjdGlvbnMgYmVmb3JlIHJlZ2lzdGVyIGFsbG9jYXRpb24uCisgIHZpcnR1YWwgU2NoZWR1bGVIYXphcmRSZWNvZ25pemVyICoKKyAgQ3JlYXRlVGFyZ2V0TUlIYXphcmRSZWNvZ25pemVyKGNvbnN0IEluc3RySXRpbmVyYXJ5RGF0YSAqLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2NoZWR1bGVEQUcgKkRBRykgY29uc3Q7CisKKyAgLy8vIEFsbG9jYXRlIGFuZCByZXR1cm4gYSBoYXphcmQgcmVjb2duaXplciB0byB1c2UgZm9yIHRoaXMgdGFyZ2V0IHdoZW4KKyAgLy8vIHNjaGVkdWxpbmcgdGhlIG1hY2hpbmUgaW5zdHJ1Y3Rpb25zIGFmdGVyIHJlZ2lzdGVyIGFsbG9jYXRpb24uCisgIHZpcnR1YWwgU2NoZWR1bGVIYXphcmRSZWNvZ25pemVyICoKKyAgQ3JlYXRlVGFyZ2V0UG9zdFJBSGF6YXJkUmVjb2duaXplcihjb25zdCBJbnN0ckl0aW5lcmFyeURhdGEgKiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTY2hlZHVsZURBRyAqREFHKSBjb25zdDsKKworICAvLy8gQWxsb2NhdGUgYW5kIHJldHVybiBhIGhhemFyZCByZWNvZ25pemVyIHRvIHVzZSBmb3IgYnkgbm9uLXNjaGVkdWxpbmcKKyAgLy8vIHBhc3Nlcy4KKyAgdmlydHVhbCBTY2hlZHVsZUhhemFyZFJlY29nbml6ZXIgKgorICBDcmVhdGVUYXJnZXRQb3N0UkFIYXphcmRSZWNvZ25pemVyKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0IHsKKyAgICByZXR1cm4gbnVsbHB0cjsKKyAgfQorCisgIC8vLyBQcm92aWRlIGEgZ2xvYmFsIGZsYWcgZm9yIGRpc2FibGluZyB0aGUgUHJlUkEgaGF6YXJkIHJlY29nbml6ZXIgdGhhdAorICAvLy8gdGFyZ2V0cyBtYXkgY2hvb3NlIHRvIGhvbm9yLgorICBib29sIHVzZVByZVJBSGF6YXJkUmVjb2duaXplcigpIGNvbnN0OworCisgIC8vLyBGb3IgYSBjb21wYXJpc29uIGluc3RydWN0aW9uLCByZXR1cm4gdGhlIHNvdXJjZSByZWdpc3RlcnMKKyAgLy8vIGluIFNyY1JlZyBhbmQgU3JjUmVnMiBpZiBoYXZpbmcgdHdvIHJlZ2lzdGVyIG9wZXJhbmRzLCBhbmQgdGhlIHZhbHVlIGl0CisgIC8vLyBjb21wYXJlcyBhZ2FpbnN0IGluIENtcFZhbHVlLiBSZXR1cm4gdHJ1ZSBpZiB0aGUgY29tcGFyaXNvbiBpbnN0cnVjdGlvbgorICAvLy8gY2FuIGJlIGFuYWx5emVkLgorICB2aXJ0dWFsIGJvb2wgYW5hbHl6ZUNvbXBhcmUoY29uc3QgTWFjaGluZUluc3RyICZNSSwgdW5zaWduZWQgJlNyY1JlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkICZTcmNSZWcyLCBpbnQgJk1hc2ssIGludCAmVmFsdWUpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gU2VlIGlmIHRoZSBjb21wYXJpc29uIGluc3RydWN0aW9uIGNhbiBiZSBjb252ZXJ0ZWQKKyAgLy8vIGludG8gc29tZXRoaW5nIG1vcmUgZWZmaWNpZW50LiBFLmcuLCBvbiBBUk0gbW9zdCBpbnN0cnVjdGlvbnMgY2FuIHNldCB0aGUKKyAgLy8vIGZsYWdzIHJlZ2lzdGVyLCBvYnZpYXRpbmcgdGhlIG5lZWQgZm9yIGEgc2VwYXJhdGUgQ01QLgorICB2aXJ0dWFsIGJvb2wgb3B0aW1pemVDb21wYXJlSW5zdHIoTWFjaGluZUluc3RyICZDbXBJbnN0ciwgdW5zaWduZWQgU3JjUmVnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgU3JjUmVnMiwgaW50IE1hc2ssIGludCBWYWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gKk1SSSkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorICB2aXJ0dWFsIGJvb2wgb3B0aW1pemVDb25kQnJhbmNoKE1hY2hpbmVJbnN0ciAmTUkpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgLy8vIFRyeSB0byByZW1vdmUgdGhlIGxvYWQgYnkgZm9sZGluZyBpdCB0byBhIHJlZ2lzdGVyIG9wZXJhbmQgYXQgdGhlIHVzZS4KKyAgLy8vIFdlIGZvbGQgdGhlIGxvYWQgaW5zdHJ1Y3Rpb25zIGlmIGFuZCBvbmx5IGlmIHRoZQorICAvLy8gZGVmIGFuZCB1c2UgYXJlIGluIHRoZSBzYW1lIEJCLiBXZSBvbmx5IGxvb2sgYXQgb25lIGxvYWQgYW5kIHNlZQorICAvLy8gd2hldGhlciBpdCBjYW4gYmUgZm9sZGVkIGludG8gTUkuIEZvbGRBc0xvYWREZWZSZWcgaXMgdGhlIHZpcnR1YWwgcmVnaXN0ZXIKKyAgLy8vIGRlZmluZWQgYnkgdGhlIGxvYWQgd2UgYXJlIHRyeWluZyB0byBmb2xkLiBEZWZNSSByZXR1cm5zIHRoZSBtYWNoaW5lCisgIC8vLyBpbnN0cnVjdGlvbiB0aGF0IGRlZmluZXMgRm9sZEFzTG9hZERlZlJlZywgYW5kIHRoZSBmdW5jdGlvbiByZXR1cm5zCisgIC8vLyB0aGUgbWFjaGluZSBpbnN0cnVjdGlvbiBnZW5lcmF0ZWQgZHVlIHRvIGZvbGRpbmcuCisgIHZpcnR1YWwgTWFjaGluZUluc3RyICpvcHRpbWl6ZUxvYWRJbnN0cihNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAqTVJJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgJkZvbGRBc0xvYWREZWZSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lSW5zdHIgKiZEZWZNSSkgY29uc3QgeworICAgIHJldHVybiBudWxscHRyOworICB9CisKKyAgLy8vICdSZWcnIGlzIGtub3duIHRvIGJlIGRlZmluZWQgYnkgYSBtb3ZlIGltbWVkaWF0ZSBpbnN0cnVjdGlvbiwKKyAgLy8vIHRyeSB0byBmb2xkIHRoZSBpbW1lZGlhdGUgaW50byB0aGUgdXNlIGluc3RydWN0aW9uLgorICAvLy8gSWYgTVJJLT5oYXNPbmVOb25EQkdVc2UoUmVnKSBpcyB0cnVlLCBhbmQgdGhpcyBmdW5jdGlvbiByZXR1cm5zIHRydWUsCisgIC8vLyB0aGVuIHRoZSBjYWxsZXIgbWF5IGFzc3VtZSB0aGF0IERlZk1JIGhhcyBiZWVuIGVyYXNlZCBmcm9tIGl0cyBwYXJlbnQKKyAgLy8vIGJsb2NrLiBUaGUgY2FsbGVyIG1heSBhc3N1bWUgdGhhdCBpdCB3aWxsIG5vdCBiZSBlcmFzZWQgYnkgdGhpcworICAvLy8gZnVuY3Rpb24gb3RoZXJ3aXNlLgorICB2aXJ0dWFsIGJvb2wgRm9sZEltbWVkaWF0ZShNYWNoaW5lSW5zdHIgJlVzZU1JLCBNYWNoaW5lSW5zdHIgJkRlZk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBSZWcsIE1hY2hpbmVSZWdpc3RlckluZm8gKk1SSSkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIG51bWJlciBvZiB1LW9wZXJhdGlvbnMgdGhlIGdpdmVuIG1hY2hpbmUKKyAgLy8vIGluc3RydWN0aW9uIHdpbGwgYmUgZGVjb2RlZCB0byBvbiB0aGUgdGFyZ2V0IGNwdS4gVGhlIGl0aW5lcmFyeSdzCisgIC8vLyBJc3N1ZVdpZHRoIGlzIHRoZSBudW1iZXIgb2YgbWljcm9vcHMgdGhhdCBjYW4gYmUgZGlzcGF0Y2hlZCBlYWNoCisgIC8vLyBjeWNsZS4gQW4gaW5zdHJ1Y3Rpb24gd2l0aCB6ZXJvIG1pY3Jvb3BzIHRha2VzIG5vIGRpc3BhdGNoIHJlc291cmNlcy4KKyAgdmlydHVhbCB1bnNpZ25lZCBnZXROdW1NaWNyb09wcyhjb25zdCBJbnN0ckl0aW5lcmFyeURhdGEgKkl0aW5EYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ciAmTUkpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBmb3IgcHNldWRvIGluc3RydWN0aW9ucyB0aGF0IGRvbid0IGNvbnN1bWUgYW55CisgIC8vLyBtYWNoaW5lIHJlc291cmNlcyBpbiB0aGVpciBjdXJyZW50IGZvcm0uIFRoZXNlIGFyZSBjb21tb24gY2FzZXMgdGhhdCB0aGUKKyAgLy8vIHNjaGVkdWxlciBzaG91bGQgY29uc2lkZXIgZnJlZSwgcmF0aGVyIHRoYW4gY29uc2VydmF0aXZlbHkgaGFuZGxpbmcgdGhlbQorICAvLy8gYXMgaW5zdHJ1Y3Rpb25zIHdpdGggbm8gaXRpbmVyYXJ5LgorICBib29sIGlzWmVyb0Nvc3QodW5zaWduZWQgT3Bjb2RlKSBjb25zdCB7CisgICAgcmV0dXJuIE9wY29kZSA8PSBUYXJnZXRPcGNvZGU6OkNPUFk7CisgIH0KKworICB2aXJ0dWFsIGludCBnZXRPcGVyYW5kTGF0ZW5jeShjb25zdCBJbnN0ckl0aW5lcmFyeURhdGEgKkl0aW5EYXRhLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRE5vZGUgKkRlZk5vZGUsIHVuc2lnbmVkIERlZklkeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0ROb2RlICpVc2VOb2RlLCB1bnNpZ25lZCBVc2VJZHgpIGNvbnN0OworCisgIC8vLyBDb21wdXRlIGFuZCByZXR1cm4gdGhlIHVzZSBvcGVyYW5kIGxhdGVuY3kgb2YgYSBnaXZlbiBwYWlyIG9mIGRlZiBhbmQgdXNlLgorICAvLy8gSW4gbW9zdCBjYXNlcywgdGhlIHN0YXRpYyBzY2hlZHVsaW5nIGl0aW5lcmFyeSB3YXMgZW5vdWdoIHRvIGRldGVybWluZSB0aGUKKyAgLy8vIG9wZXJhbmQgbGF0ZW5jeS4gQnV0IGl0IG1heSBub3QgYmUgcG9zc2libGUgZm9yIGluc3RydWN0aW9ucyB3aXRoIHZhcmlhYmxlCisgIC8vLyBudW1iZXIgb2YgZGVmcyAvIHVzZXMuCisgIC8vLworICAvLy8gVGhpcyBpcyBhIHJhdyBpbnRlcmZhY2UgdG8gdGhlIGl0aW5lcmFyeSB0aGF0IG1heSBiZSBkaXJlY3RseSBvdmVycmlkZGVuCisgIC8vLyBieSBhIHRhcmdldC4gVXNlIGNvbXB1dGVPcGVyYW5kTGF0ZW5jeSB0byBnZXQgdGhlIGJlc3QgZXN0aW1hdGUgb2YKKyAgLy8vIGxhdGVuY3kuCisgIHZpcnR1YWwgaW50IGdldE9wZXJhbmRMYXRlbmN5KGNvbnN0IEluc3RySXRpbmVyYXJ5RGF0YSAqSXRpbkRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ciAmRGVmTUksIHVuc2lnbmVkIERlZklkeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUluc3RyICZVc2VNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgVXNlSWR4KSBjb25zdDsKKworICAvLy8gQ29tcHV0ZSB0aGUgaW5zdHJ1Y3Rpb24gbGF0ZW5jeSBvZiBhIGdpdmVuIGluc3RydWN0aW9uLgorICAvLy8gSWYgdGhlIGluc3RydWN0aW9uIGhhcyBoaWdoZXIgY29zdCB3aGVuIHByZWRpY2F0ZWQsIGl0J3MgcmV0dXJuZWQgdmlhCisgIC8vLyBQcmVkQ29zdC4KKyAgdmlydHVhbCB1bnNpZ25lZCBnZXRJbnN0ckxhdGVuY3koY29uc3QgSW5zdHJJdGluZXJhcnlEYXRhICpJdGluRGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUluc3RyICZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgKlByZWRDb3N0ID0gbnVsbHB0cikgY29uc3Q7CisKKyAgdmlydHVhbCB1bnNpZ25lZCBnZXRQcmVkaWNhdGlvbkNvc3QoY29uc3QgTWFjaGluZUluc3RyICZNSSkgY29uc3Q7CisKKyAgdmlydHVhbCBpbnQgZ2V0SW5zdHJMYXRlbmN5KGNvbnN0IEluc3RySXRpbmVyYXJ5RGF0YSAqSXRpbkRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRE5vZGUgKk5vZGUpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdGhlIGRlZmF1bHQgZXhwZWN0ZWQgbGF0ZW5jeSBmb3IgYSBkZWYgYmFzZWQgb24gaXRzIG9wY29kZS4KKyAgdW5zaWduZWQgZGVmYXVsdERlZkxhdGVuY3koY29uc3QgTUNTY2hlZE1vZGVsICZTY2hlZE1vZGVsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lSW5zdHIgJkRlZk1JKSBjb25zdDsKKworICBpbnQgY29tcHV0ZURlZk9wZXJhbmRMYXRlbmN5KGNvbnN0IEluc3RySXRpbmVyYXJ5RGF0YSAqSXRpbkRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUluc3RyICZEZWZNSSkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgb3Bjb2RlIGhhcyBoaWdoIGxhdGVuY3kgdG8gaXRzIHJlc3VsdC4KKyAgdmlydHVhbCBib29sIGlzSGlnaExhdGVuY3lEZWYoaW50IG9wYykgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KKworICAvLy8gQ29tcHV0ZSBvcGVyYW5kIGxhdGVuY3kgYmV0d2VlbiBhIGRlZiBvZiAnUmVnJworICAvLy8gYW5kIGEgdXNlIGluIHRoZSBjdXJyZW50IGxvb3AuIFJldHVybiB0cnVlIGlmIHRoZSB0YXJnZXQgY29uc2lkZXJlZAorICAvLy8gaXQgJ2hpZ2gnLiBUaGlzIGlzIHVzZWQgYnkgb3B0aW1pemF0aW9uIHBhc3NlcyBzdWNoIGFzIG1hY2hpbmUgTElDTSB0bworICAvLy8gZGV0ZXJtaW5lIHdoZXRoZXIgaXQgbWFrZXMgc2Vuc2UgdG8gaG9pc3QgYW4gaW5zdHJ1Y3Rpb24gb3V0IGV2ZW4gaW4gYQorICAvLy8gaGlnaCByZWdpc3RlciBwcmVzc3VyZSBzaXR1YXRpb24uCisgIHZpcnR1YWwgYm9vbCBoYXNIaWdoT3BlcmFuZExhdGVuY3koY29uc3QgVGFyZ2V0U2NoZWRNb2RlbCAmU2NoZWRNb2RlbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICpNUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUluc3RyICZEZWZNSSwgdW5zaWduZWQgRGVmSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVJbnN0ciAmVXNlTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgVXNlSWR4KSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIENvbXB1dGUgb3BlcmFuZCBsYXRlbmN5IG9mIGEgZGVmIG9mICdSZWcnLiBSZXR1cm4gdHJ1ZQorICAvLy8gaWYgdGhlIHRhcmdldCBjb25zaWRlcmVkIGl0ICdsb3cnLgorICB2aXJ0dWFsIGJvb2wgaGFzTG93RGVmTGF0ZW5jeShjb25zdCBUYXJnZXRTY2hlZE1vZGVsICZTY2hlZE1vZGVsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lSW5zdHIgJkRlZk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBEZWZJZHgpIGNvbnN0OworCisgIC8vLyBQZXJmb3JtIHRhcmdldC1zcGVjaWZpYyBpbnN0cnVjdGlvbiB2ZXJpZmljYXRpb24uCisgIHZpcnR1YWwgYm9vbCB2ZXJpZnlJbnN0cnVjdGlvbihjb25zdCBNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nUmVmICZFcnJJbmZvKSBjb25zdCB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBjdXJyZW50IGV4ZWN1dGlvbiBkb21haW4gYW5kIGJpdCBtYXNrIG9mCisgIC8vLyBwb3NzaWJsZSBkb21haW5zIGZvciBpbnN0cnVjdGlvbi4KKyAgLy8vCisgIC8vLyBTb21lIG1pY3JvLWFyY2hpdGVjdHVyZXMgaGF2ZSBtdWx0aXBsZSBleGVjdXRpb24gZG9tYWlucywgYW5kIG11bHRpcGxlCisgIC8vLyBvcGNvZGVzIHRoYXQgcGVyZm9ybSB0aGUgc2FtZSBvcGVyYXRpb24gaW4gZGlmZmVyZW50IGRvbWFpbnMuICBGb3IKKyAgLy8vIGV4YW1wbGUsIHRoZSB4ODYgYXJjaGl0ZWN0dXJlIHByb3ZpZGVzIHRoZSBwb3IsIG9ycHMsIGFuZCBvcnBkCisgIC8vLyBpbnN0cnVjdGlvbnMgdGhhdCBhbGwgZG8gdGhlIHNhbWUgdGhpbmcuICBUaGVyZSBpcyBhIGxhdGVuY3kgcGVuYWx0eSBpZiBhCisgIC8vLyByZWdpc3RlciBpcyB3cml0dGVuIGluIG9uZSBkb21haW4gYW5kIHJlYWQgaW4gYW5vdGhlci4KKyAgLy8vCisgIC8vLyBUaGlzIGZ1bmN0aW9uIHJldHVybnMgYSBwYWlyIChkb21haW4sIG1hc2spIGNvbnRhaW5pbmcgdGhlIGV4ZWN1dGlvbgorICAvLy8gZG9tYWluIG9mIE1JLCBhbmQgYSBiaXQgbWFzayBvZiBwb3NzaWJsZSBkb21haW5zLiAgVGhlIHNldEV4ZWN1dGlvbkRvbWFpbgorICAvLy8gZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gY2hhbmdlIHRoZSBvcGNvZGUgdG8gb25lIG9mIHRoZSBkb21haW5zIGluIHRoZQorICAvLy8gYml0IG1hc2suICBJbnN0cnVjdGlvbnMgd2hvc2UgZXhlY3V0aW9uIGRvbWFpbiBjYW4ndCBiZSBjaGFuZ2VkIHNob3VsZAorICAvLy8gcmV0dXJuIGEgMCBtYXNrLgorICAvLy8KKyAgLy8vIFRoZSBleGVjdXRpb24gZG9tYWluIG51bWJlcnMgZG9uJ3QgaGF2ZSBhbnkgc3BlY2lhbCBtZWFuaW5nIGV4Y2VwdCBkb21haW4KKyAgLy8vIDAgaXMgdXNlZCBmb3IgaW5zdHJ1Y3Rpb25zIHRoYXQgYXJlIG5vdCBhc3NvY2lhdGVkIHdpdGggYW55IGludGVyZXN0aW5nCisgIC8vLyBleGVjdXRpb24gZG9tYWluLgorICAvLy8KKyAgdmlydHVhbCBzdGQ6OnBhaXI8dWludDE2X3QsIHVpbnQxNl90PgorICBnZXRFeGVjdXRpb25Eb21haW4oY29uc3QgTWFjaGluZUluc3RyICZNSSkgY29uc3QgeworICAgIHJldHVybiBzdGQ6Om1ha2VfcGFpcigwLCAwKTsKKyAgfQorCisgIC8vLyBDaGFuZ2UgdGhlIG9wY29kZSBvZiBNSSB0byBleGVjdXRlIGluIERvbWFpbi4KKyAgLy8vCisgIC8vLyBUaGUgYml0ICgxIDw8IERvbWFpbikgbXVzdCBiZSBzZXQgaW4gdGhlIG1hc2sgcmV0dXJuZWQgZnJvbQorICAvLy8gZ2V0RXhlY3V0aW9uRG9tYWluKE1JKS4KKyAgdmlydHVhbCB2b2lkIHNldEV4ZWN1dGlvbkRvbWFpbihNYWNoaW5lSW5zdHIgJk1JLCB1bnNpZ25lZCBEb21haW4pIGNvbnN0IHt9CisKKyAgLy8vIFJldHVybnMgdGhlIHByZWZlcnJlZCBtaW5pbXVtIGNsZWFyYW5jZQorICAvLy8gYmVmb3JlIGFuIGluc3RydWN0aW9uIHdpdGggYW4gdW53YW50ZWQgcGFydGlhbCByZWdpc3RlciB1cGRhdGUuCisgIC8vLworICAvLy8gU29tZSBpbnN0cnVjdGlvbnMgb25seSB3cml0ZSBwYXJ0IG9mIGEgcmVnaXN0ZXIsIGFuZCBpbXBsaWNpdGx5IG5lZWQgdG8KKyAgLy8vIHJlYWQgdGhlIG90aGVyIHBhcnRzIG9mIHRoZSByZWdpc3Rlci4gIFRoaXMgbWF5IGNhdXNlIHVud2FudGVkIHN0YWxscworICAvLy8gcHJldmVudGluZyBvdGhlcndpc2UgdW5yZWxhdGVkIGluc3RydWN0aW9ucyBmcm9tIGV4ZWN1dGluZyBpbiBwYXJhbGxlbCBpbgorICAvLy8gYW4gb3V0LW9mLW9yZGVyIENQVS4KKyAgLy8vCisgIC8vLyBGb3IgZXhhbXBsZSwgdGhlIHg4NiBpbnN0cnVjdGlvbiBjdnRzaTJzcyB3cml0ZXMgaXRzIHJlc3VsdCB0byBiaXRzCisgIC8vLyBbMzE6MF0gb2YgdGhlIGRlc3RpbmF0aW9uIHhtbSByZWdpc3Rlci4gQml0cyBbMTI3OjMyXSBhcmUgdW5hZmZlY3RlZCwgc28KKyAgLy8vIHRoZSBpbnN0cnVjdGlvbiBuZWVkcyB0byB3YWl0IGZvciB0aGUgb2xkIHZhbHVlIG9mIHRoZSByZWdpc3RlciB0byBiZWNvbWUKKyAgLy8vIGF2YWlsYWJsZToKKyAgLy8vCisgIC8vLyAgIGFkZHBzICV4bW0xLCAleG1tMAorICAvLy8gICBtb3ZhcHMgJXhtbTAsICglcmF4KQorICAvLy8gICBjdnRzaTJzcyAlcmJ4LCAleG1tMAorICAvLy8KKyAgLy8vIEluIHRoZSBjb2RlIGFib3ZlLCB0aGUgY3Z0c2kyc3MgaW5zdHJ1Y3Rpb24gbmVlZHMgdG8gd2FpdCBmb3IgdGhlIGFkZHBzCisgIC8vLyBpbnN0cnVjdGlvbiBiZWZvcmUgaXQgY2FuIGlzc3VlLCBldmVuIHRob3VnaCB0aGUgaGlnaCBiaXRzIG9mICV4bW0wCisgIC8vLyBwcm9iYWJseSBhcmVuJ3QgbmVlZGVkLgorICAvLy8KKyAgLy8vIFRoaXMgaG9vayByZXR1cm5zIHRoZSBwcmVmZXJyZWQgY2xlYXJhbmNlIGJlZm9yZSBNSSwgbWVhc3VyZWQgaW4KKyAgLy8vIGluc3RydWN0aW9ucy4gIE90aGVyIGRlZnMgb2YgTUkncyBvcGVyYW5kIE9wTnVtIGFyZSBhdm9pZGVkIGluIHRoZSBsYXN0IE4KKyAgLy8vIGluc3RydWN0aW9ucyBiZWZvcmUgTUkuICBJdCBzaG91bGQgb25seSByZXR1cm4gYSBwb3NpdGl2ZSB2YWx1ZSBmb3IKKyAgLy8vIHVud2FudGVkIGRlcGVuZGVuY2llcy4gIElmIHRoZSBvbGQgYml0cyBvZiB0aGUgZGVmaW5lZCByZWdpc3RlciBoYXZlCisgIC8vLyB1c2VmdWwgdmFsdWVzLCBvciBpZiBNSSBpcyBkZXRlcm1pbmVkIHRvIG90aGVyd2lzZSByZWFkIHRoZSBkZXBlbmRlbmN5LAorICAvLy8gdGhlIGhvb2sgc2hvdWxkIHJldHVybiAwLgorICAvLy8KKyAgLy8vIFRoZSB1bndhbnRlZCBkZXBlbmRlbmN5IG1heSBiZSBoYW5kbGVkIGJ5OgorICAvLy8KKyAgLy8vIDEuIEFsbG9jYXRpbmcgdGhlIHNhbWUgcmVnaXN0ZXIgZm9yIGFuIE1JIGRlZiBhbmQgdXNlLiAgVGhhdCBtYWtlcyB0aGUKKyAgLy8vICAgIHVud2FudGVkIGRlcGVuZGVuY3kgaWRlbnRpY2FsIHRvIGEgcmVxdWlyZWQgZGVwZW5kZW5jeS4KKyAgLy8vCisgIC8vLyAyLiBBbGxvY2F0aW5nIGEgcmVnaXN0ZXIgZm9yIHRoZSBkZWYgdGhhdCBoYXMgbm8gZGVmcyBpbiB0aGUgcHJldmlvdXMgTgorICAvLy8gICAgaW5zdHJ1Y3Rpb25zLgorICAvLy8KKyAgLy8vIDMuIENhbGxpbmcgYnJlYWtQYXJ0aWFsUmVnRGVwZW5kZW5jeSgpIHdpdGggdGhlIHNhbWUgYXJndW1lbnRzLiAgVGhpcworICAvLy8gICAgYWxsb3dzIHRoZSB0YXJnZXQgdG8gaW5zZXJ0IGEgZGVwZW5kZW5jeSBicmVha2luZyBpbnN0cnVjdGlvbi4KKyAgLy8vCisgIHZpcnR1YWwgdW5zaWduZWQKKyAgZ2V0UGFydGlhbFJlZ1VwZGF0ZUNsZWFyYW5jZShjb25zdCBNYWNoaW5lSW5zdHIgJk1JLCB1bnNpZ25lZCBPcE51bSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSkgY29uc3QgeworICAgIC8vIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHJldHVybnMgMCBmb3Igbm8gcGFydGlhbCByZWdpc3RlciBkZXBlbmRlbmN5LgorICAgIHJldHVybiAwOworICB9CisKKyAgLy8vIFxicmllZiBSZXR1cm4gdGhlIG1pbmltdW0gY2xlYXJhbmNlIGJlZm9yZSBhbiBpbnN0cnVjdGlvbiB0aGF0IHJlYWRzIGFuCisgIC8vLyB1bnVzZWQgcmVnaXN0ZXIuCisgIC8vLworICAvLy8gRm9yIGV4YW1wbGUsIEFWWCBpbnN0cnVjdGlvbnMgbWF5IGNvcHkgcGFydCBvZiBhIHJlZ2lzdGVyIG9wZXJhbmQgaW50bworICAvLy8gdGhlIHVudXNlZCBoaWdoIGJpdHMgb2YgdGhlIGRlc3RpbmF0aW9uIHJlZ2lzdGVyLgorICAvLy8KKyAgLy8vIHZjdnRzaTJzZHEgJXJheCwgdW5kZWYgJXhtbTAsICV4bW0xNAorICAvLy8KKyAgLy8vIEluIHRoZSBjb2RlIGFib3ZlLCB2Y3Z0c2kyc2RxIGNvcGllcyAleG1tMFsxMjc6NjRdIGludG8gJXhtbTE0IGNyZWF0aW5nIGEKKyAgLy8vIGZhbHNlIGRlcGVuZGVuY2Ugb24gYW55IHByZXZpb3VzIHdyaXRlIHRvICV4bW0wLgorICAvLy8KKyAgLy8vIFRoaXMgaG9vayB3b3JrcyBzaW1pbGFybHkgdG8gZ2V0UGFydGlhbFJlZ1VwZGF0ZUNsZWFyYW5jZSwgZXhjZXB0IHRoYXQgaXQKKyAgLy8vIGRvZXMgbm90IHRha2UgYW4gb3BlcmFuZCBpbmRleC4gSW5zdGVhZCBzZXRzIFxwIE9wTnVtIHRvIHRoZSBpbmRleCBvZiB0aGUKKyAgLy8vIHVudXNlZCByZWdpc3Rlci4KKyAgdmlydHVhbCB1bnNpZ25lZCBnZXRVbmRlZlJlZ0NsZWFyYW5jZShjb25zdCBNYWNoaW5lSW5zdHIgJk1JLCB1bnNpZ25lZCAmT3BOdW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkpIGNvbnN0IHsKKyAgICAvLyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIDAgZm9yIG5vIHVuZGVmIHJlZ2lzdGVyIGRlcGVuZGVuY3kuCisgICAgcmV0dXJuIDA7CisgIH0KKworICAvLy8gSW5zZXJ0IGEgZGVwZW5kZW5jeS1icmVha2luZyBpbnN0cnVjdGlvbgorICAvLy8gYmVmb3JlIE1JIHRvIGVsaW1pbmF0ZSBhbiB1bndhbnRlZCBkZXBlbmRlbmN5IG9uIE9wTnVtLgorICAvLy8KKyAgLy8vIElmIGl0IHdhc24ndCBwb3NzaWJsZSB0byBhdm9pZCBhIGRlZiBpbiB0aGUgbGFzdCBOIGluc3RydWN0aW9ucyBiZWZvcmUgTUkKKyAgLy8vIChzZWUgZ2V0UGFydGlhbFJlZ1VwZGF0ZUNsZWFyYW5jZSksIHRoaXMgaG9vayB3aWxsIGJlIGNhbGxlZCB0byBicmVhayB0aGUKKyAgLy8vIHVud2FudGVkIGRlcGVuZGVuY3kuCisgIC8vLworICAvLy8gT24geDg2LCBhbiB4b3JwcyBpbnN0cnVjdGlvbiBjYW4gYmUgdXNlZCBhcyBhIGRlcGVuZGVuY3kgYnJlYWtlcjoKKyAgLy8vCisgIC8vLyAgIGFkZHBzICV4bW0xLCAleG1tMAorICAvLy8gICBtb3ZhcHMgJXhtbTAsICglcmF4KQorICAvLy8gICB4b3JwcyAleG1tMCwgJXhtbTAKKyAgLy8vICAgY3Z0c2kyc3MgJXJieCwgJXhtbTAKKyAgLy8vCisgIC8vLyBBbiA8aW1wLWtpbGw+IG9wZXJhbmQgc2hvdWxkIGJlIGFkZGVkIHRvIE1JIGlmIGFuIGluc3RydWN0aW9uIHdhcworICAvLy8gaW5zZXJ0ZWQuICBUaGlzIHRpZXMgdGhlIGluc3RydWN0aW9ucyB0b2dldGhlciBpbiB0aGUgcG9zdC1yYSBzY2hlZHVsZXIuCisgIC8vLworICB2aXJ0dWFsIHZvaWQgYnJlYWtQYXJ0aWFsUmVnRGVwZW5kZW5jeShNYWNoaW5lSW5zdHIgJk1JLCB1bnNpZ25lZCBPcE51bSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkpIGNvbnN0IHt9CisKKyAgLy8vIENyZWF0ZSBtYWNoaW5lIHNwZWNpZmljIG1vZGVsIGZvciBzY2hlZHVsaW5nLgorICB2aXJ0dWFsIERGQVBhY2tldGl6ZXIgKgorICBDcmVhdGVUYXJnZXRTY2hlZHVsZVN0YXRlKGNvbnN0IFRhcmdldFN1YnRhcmdldEluZm8gJikgY29uc3QgeworICAgIHJldHVybiBudWxscHRyOworICB9CisKKyAgLy8vIFNvbWV0aW1lcywgaXQgaXMgcG9zc2libGUgZm9yIHRoZSB0YXJnZXQKKyAgLy8vIHRvIHRlbGwsIGV2ZW4gd2l0aG91dCBhbGlhc2luZyBpbmZvcm1hdGlvbiwgdGhhdCB0d28gTUlzIGFjY2VzcyBkaWZmZXJlbnQKKyAgLy8vIG1lbW9yeSBhZGRyZXNzZXMuIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB0cnVlIGlmIHR3byBNSXMgYWNjZXNzIGRpZmZlcmVudAorICAvLy8gbWVtb3J5IGFkZHJlc3NlcyBhbmQgZmFsc2Ugb3RoZXJ3aXNlLgorICAvLy8KKyAgLy8vIEFzc3VtZXMgYW55IHBoeXNpY2FsIHJlZ2lzdGVycyB1c2VkIHRvIGNvbXB1dGUgYWRkcmVzc2VzIGhhdmUgdGhlIHNhbWUKKyAgLy8vIHZhbHVlIGZvciBib3RoIGluc3RydWN0aW9ucy4gKFRoaXMgaXMgdGhlIG1vc3QgdXNlZnVsIGFzc3VtcHRpb24gZm9yCisgIC8vLyBwb3N0LVJBIHNjaGVkdWxpbmcuKQorICAvLy8KKyAgLy8vIFNlZSBhbHNvIE1hY2hpbmVJbnN0cjo6bWF5QWxpYXMsIHdoaWNoIGlzIGltcGxlbWVudGVkIG9uIHRvcCBvZiB0aGlzCisgIC8vLyBmdW5jdGlvbi4KKyAgdmlydHVhbCBib29sCisgIGFyZU1lbUFjY2Vzc2VzVHJpdmlhbGx5RGlzam9pbnQoTWFjaGluZUluc3RyICZNSWEsIE1hY2hpbmVJbnN0ciAmTUliLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFsaWFzQW5hbHlzaXMgKkFBID0gbnVsbHB0cikgY29uc3QgeworICAgIGFzc2VydCgoTUlhLm1heUxvYWQoKSB8fCBNSWEubWF5U3RvcmUoKSkgJiYKKyAgICAgICAgICAgIk1JYSBtdXN0IGxvYWQgZnJvbSBvciBtb2RpZnkgYSBtZW1vcnkgbG9jYXRpb24iKTsKKyAgICBhc3NlcnQoKE1JYi5tYXlMb2FkKCkgfHwgTUliLm1heVN0b3JlKCkpICYmCisgICAgICAgICAgICJNSWIgbXVzdCBsb2FkIGZyb20gb3IgbW9kaWZ5IGEgbWVtb3J5IGxvY2F0aW9uIik7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFxicmllZiBSZXR1cm4gdGhlIHZhbHVlIHRvIHVzZSBmb3IgdGhlIE1hY2hpbmVDU0UncyBMb29rQWhlYWRMaW1pdCwKKyAgLy8vIHdoaWNoIGlzIGEgaGV1cmlzdGljIHVzZWQgZm9yIENTRSdpbmcgcGh5cyByZWcgZGVmcy4KKyAgdmlydHVhbCB1bnNpZ25lZCBnZXRNYWNoaW5lQ1NFTG9va0FoZWFkTGltaXQoKSBjb25zdCB7CisgICAgLy8gVGhlIGRlZmF1bHQgbG9va2FoZWFkIGlzIHNtYWxsIHRvIHByZXZlbnQgdW5wcm9maXRhYmxlIHF1YWRyYXRpYworICAgIC8vIGJlaGF2aW9yLgorICAgIHJldHVybiA1OworICB9CisKKyAgLy8vIFJldHVybiBhbiBhcnJheSB0aGF0IGNvbnRhaW5zIHRoZSBpZHMgb2YgdGhlIHRhcmdldCBpbmRpY2VzICh1c2VkIGZvciB0aGUKKyAgLy8vIFRhcmdldEluZGV4IG1hY2hpbmUgb3BlcmFuZCkgYW5kIHRoZWlyIG5hbWVzLgorICAvLy8KKyAgLy8vIE1JUiBTZXJpYWxpemF0aW9uIGlzIGFibGUgdG8gc2VyaWFsaXplIG9ubHkgdGhlIHRhcmdldCBpbmRpY2VzIHRoYXQgYXJlCisgIC8vLyBkZWZpbmVkIGJ5IHRoaXMgbWV0aG9kLgorICB2aXJ0dWFsIEFycmF5UmVmPHN0ZDo6cGFpcjxpbnQsIGNvbnN0IGNoYXIgKj4+CisgIGdldFNlcmlhbGl6YWJsZVRhcmdldEluZGljZXMoKSBjb25zdCB7CisgICAgcmV0dXJuIE5vbmU7CisgIH0KKworICAvLy8gRGVjb21wb3NlIHRoZSBtYWNoaW5lIG9wZXJhbmQncyB0YXJnZXQgZmxhZ3MgaW50byB0d28gdmFsdWVzIC0gdGhlIGRpcmVjdAorICAvLy8gdGFyZ2V0IGZsYWcgdmFsdWUgYW5kIGFueSBvZiBiaXQgZmxhZ3MgdGhhdCBhcmUgYXBwbGllZC4KKyAgdmlydHVhbCBzdGQ6OnBhaXI8dW5zaWduZWQsIHVuc2lnbmVkPgorICBkZWNvbXBvc2VNYWNoaW5lT3BlcmFuZHNUYXJnZXRGbGFncyh1bnNpZ25lZCAvKlRGKi8pIGNvbnN0IHsKKyAgICByZXR1cm4gc3RkOjptYWtlX3BhaXIoMHUsIDB1KTsKKyAgfQorCisgIC8vLyBSZXR1cm4gYW4gYXJyYXkgdGhhdCBjb250YWlucyB0aGUgZGlyZWN0IHRhcmdldCBmbGFnIHZhbHVlcyBhbmQgdGhlaXIKKyAgLy8vIG5hbWVzLgorICAvLy8KKyAgLy8vIE1JUiBTZXJpYWxpemF0aW9uIGlzIGFibGUgdG8gc2VyaWFsaXplIG9ubHkgdGhlIHRhcmdldCBmbGFncyB0aGF0IGFyZQorICAvLy8gZGVmaW5lZCBieSB0aGlzIG1ldGhvZC4KKyAgdmlydHVhbCBBcnJheVJlZjxzdGQ6OnBhaXI8dW5zaWduZWQsIGNvbnN0IGNoYXIgKj4+CisgIGdldFNlcmlhbGl6YWJsZURpcmVjdE1hY2hpbmVPcGVyYW5kVGFyZ2V0RmxhZ3MoKSBjb25zdCB7CisgICAgcmV0dXJuIE5vbmU7CisgIH0KKworICAvLy8gUmV0dXJuIGFuIGFycmF5IHRoYXQgY29udGFpbnMgdGhlIGJpdG1hc2sgdGFyZ2V0IGZsYWcgdmFsdWVzIGFuZCB0aGVpcgorICAvLy8gbmFtZXMuCisgIC8vLworICAvLy8gTUlSIFNlcmlhbGl6YXRpb24gaXMgYWJsZSB0byBzZXJpYWxpemUgb25seSB0aGUgdGFyZ2V0IGZsYWdzIHRoYXQgYXJlCisgIC8vLyBkZWZpbmVkIGJ5IHRoaXMgbWV0aG9kLgorICB2aXJ0dWFsIEFycmF5UmVmPHN0ZDo6cGFpcjx1bnNpZ25lZCwgY29uc3QgY2hhciAqPj4KKyAgZ2V0U2VyaWFsaXphYmxlQml0bWFza01hY2hpbmVPcGVyYW5kVGFyZ2V0RmxhZ3MoKSBjb25zdCB7CisgICAgcmV0dXJuIE5vbmU7CisgIH0KKworICAvLy8gUmV0dXJuIGFuIGFycmF5IHRoYXQgY29udGFpbnMgdGhlIE1NTyB0YXJnZXQgZmxhZyB2YWx1ZXMgYW5kIHRoZWlyCisgIC8vLyBuYW1lcy4KKyAgLy8vCisgIC8vLyBNSVIgU2VyaWFsaXphdGlvbiBpcyBhYmxlIHRvIHNlcmlhbGl6ZSBvbmx5IHRoZSBNTU8gdGFyZ2V0IGZsYWdzIHRoYXQgYXJlCisgIC8vLyBkZWZpbmVkIGJ5IHRoaXMgbWV0aG9kLgorICB2aXJ0dWFsIEFycmF5UmVmPHN0ZDo6cGFpcjxNYWNoaW5lTWVtT3BlcmFuZDo6RmxhZ3MsIGNvbnN0IGNoYXIgKj4+CisgIGdldFNlcmlhbGl6YWJsZU1hY2hpbmVNZW1PcGVyYW5kVGFyZ2V0RmxhZ3MoKSBjb25zdCB7CisgICAgcmV0dXJuIE5vbmU7CisgIH0KKworICAvLy8gRGV0ZXJtaW5lcyB3aGV0aGVyIFxwIEluc3QgaXMgYSB0YWlsIGNhbGwgaW5zdHJ1Y3Rpb24uIE92ZXJyaWRlIHRoaXMKKyAgLy8vIG1ldGhvZCBvbiB0YXJnZXRzIHRoYXQgZG8gbm90IHByb3Blcmx5IHNldCBNQ0lEOjpSZXR1cm4gYW5kIE1DSUQ6OkNhbGwgb24KKyAgLy8vIHRhaWwgY2FsbCBpbnN0cnVjdGlvbnMuIgorICB2aXJ0dWFsIGJvb2wgaXNUYWlsQ2FsbChjb25zdCBNYWNoaW5lSW5zdHIgJkluc3QpIGNvbnN0IHsKKyAgICByZXR1cm4gSW5zdC5pc1JldHVybigpICYmIEluc3QuaXNDYWxsKCk7CisgIH0KKworICAvLy8gVHJ1ZSBpZiB0aGUgaW5zdHJ1Y3Rpb24gaXMgYm91bmQgdG8gdGhlIHRvcCBvZiBpdHMgYmFzaWMgYmxvY2sgYW5kIG5vCisgIC8vLyBvdGhlciBpbnN0cnVjdGlvbnMgc2hhbGwgYmUgaW5zZXJ0ZWQgYmVmb3JlIGl0LiBUaGlzIGNhbiBiZSBpbXBsZW1lbnRlZAorICAvLy8gdG8gcHJldmVudCByZWdpc3RlciBhbGxvY2F0b3IgdG8gaW5zZXJ0IHNwaWxscyBiZWZvcmUgc3VjaCBpbnN0cnVjdGlvbnMuCisgIHZpcnR1YWwgYm9vbCBpc0Jhc2ljQmxvY2tQcm9sb2d1ZShjb25zdCBNYWNoaW5lSW5zdHIgJk1JKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFxicmllZiBEZXNjcmliZXMgdGhlIG51bWJlciBvZiBpbnN0cnVjdGlvbnMgdGhhdCBpdCB3aWxsIHRha2UgdG8gY2FsbCBhbmQKKyAgLy8vIGNvbnN0cnVjdCBhIGZyYW1lIGZvciBhIGdpdmVuIG91dGxpbmluZyBjYW5kaWRhdGUuCisgIHN0cnVjdCBNYWNoaW5lT3V0bGluZXJJbmZvIHsKKyAgICAvLy8gTnVtYmVyIG9mIGluc3RydWN0aW9ucyB0byBjYWxsIGFuIG91dGxpbmVkIGZ1bmN0aW9uIGZvciB0aGlzIGNhbmRpZGF0ZS4KKyAgICB1bnNpZ25lZCBDYWxsT3ZlcmhlYWQ7CisKKyAgICAvLy8gXGJyaWVmIE51bWJlciBvZiBpbnN0cnVjdGlvbnMgdG8gY29uc3RydWN0IGFuIG91dGxpbmVkIGZ1bmN0aW9uIGZyYW1lCisgICAgLy8vIGZvciB0aGlzIGNhbmRpZGF0ZS4KKyAgICB1bnNpZ25lZCBGcmFtZU92ZXJoZWFkOworCisgICAgLy8vIFxicmllZiBSZXByZXNlbnRzIHRoZSBzcGVjaWZpYyBpbnN0cnVjdGlvbnMgdGhhdCBtdXN0IGJlIGVtaXR0ZWQgdG8KKyAgICAvLy8gY29uc3RydWN0IGEgY2FsbCB0byB0aGlzIGNhbmRpZGF0ZS4KKyAgICB1bnNpZ25lZCBDYWxsQ29uc3RydWN0aW9uSUQ7CisKKyAgICAvLy8gXGJyaWVmIFJlcHJlc2VudHMgdGhlIHNwZWNpZmljIGluc3RydWN0aW9ucyB0aGF0IG11c3QgYmUgZW1pdHRlZCB0bworICAgIC8vLyBjb25zdHJ1Y3QgYSBmcmFtZSBmb3IgdGhpcyBjYW5kaWRhdGUncyBvdXRsaW5lZCBmdW5jdGlvbi4KKyAgICB1bnNpZ25lZCBGcmFtZUNvbnN0cnVjdGlvbklEOworCisgICAgTWFjaGluZU91dGxpbmVySW5mbygpIHt9CisgICAgTWFjaGluZU91dGxpbmVySW5mbyh1bnNpZ25lZCBDYWxsT3ZlcmhlYWQsIHVuc2lnbmVkIEZyYW1lT3ZlcmhlYWQsCisgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBDYWxsQ29uc3RydWN0aW9uSUQsCisgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBGcmFtZUNvbnN0cnVjdGlvbklEKQorICAgICAgICA6IENhbGxPdmVyaGVhZChDYWxsT3ZlcmhlYWQpLCBGcmFtZU92ZXJoZWFkKEZyYW1lT3ZlcmhlYWQpLAorICAgICAgICAgIENhbGxDb25zdHJ1Y3Rpb25JRChDYWxsQ29uc3RydWN0aW9uSUQpLAorICAgICAgICAgIEZyYW1lQ29uc3RydWN0aW9uSUQoRnJhbWVDb25zdHJ1Y3Rpb25JRCkge30KKyAgfTsKKworICAvLy8gXGJyaWVmIFJldHVybnMgYSBccCBNYWNoaW5lT3V0bGluZXJJbmZvIHN0cnVjdCBjb250YWluaW5nIHRhcmdldC1zcGVjaWZpYworICAvLy8gaW5mb3JtYXRpb24gZm9yIGEgc2V0IG9mIG91dGxpbmluZyBjYW5kaWRhdGVzLgorICB2aXJ0dWFsIE1hY2hpbmVPdXRsaW5lckluZm8gZ2V0T3V0bGluaW5pbmdDYW5kaWRhdGVJbmZvKAorICAgICAgc3RkOjp2ZWN0b3I8CisgICAgICAgICAgc3RkOjpwYWlyPE1hY2hpbmVCYXNpY0Jsb2NrOjppdGVyYXRvciwgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yPj4KKyAgICAgICAgICAmUmVwZWF0ZWRTZXF1ZW5jZUxvY3MpIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKAorICAgICAgICAiVGFyZ2V0IGRpZG4ndCBpbXBsZW1lbnQgVGFyZ2V0SW5zdHJJbmZvOjpnZXRPdXRsaW5pbmdPdmVyaGVhZCEiKTsKKyAgfQorCisgIC8vLyBSZXByZXNlbnRzIGhvdyBhbiBpbnN0cnVjdGlvbiBzaG91bGQgYmUgbWFwcGVkIGJ5IHRoZSBvdXRsaW5lci4KKyAgLy8vIFxwIExlZ2FsIGluc3RydWN0aW9ucyBhcmUgdGhvc2Ugd2hpY2ggYXJlIHNhZmUgdG8gb3V0bGluZS4KKyAgLy8vIFxwIElsbGVnYWwgaW5zdHJ1Y3Rpb25zIGFyZSB0aG9zZSB3aGljaCBjYW5ub3QgYmUgb3V0bGluZWQuCisgIC8vLyBccCBJbnZpc2libGUgaW5zdHJ1Y3Rpb25zIGFyZSBpbnN0cnVjdGlvbnMgd2hpY2ggY2FuIGJlIG91dGxpbmVkLCBidXQKKyAgLy8vIHNob3VsZG4ndCBhY3R1YWxseSBpbXBhY3QgdGhlIG91dGxpbmluZyByZXN1bHQuCisgIGVudW0gTWFjaGluZU91dGxpbmVySW5zdHJUeXBlIHsgTGVnYWwsIElsbGVnYWwsIEludmlzaWJsZSB9OworCisgIC8vLyBSZXR1cm5zIGhvdyBvciBpZiBccCBNSSBzaG91bGQgYmUgb3V0bGluZWQuCisgIHZpcnR1YWwgTWFjaGluZU91dGxpbmVySW5zdHJUeXBlCisgIGdldE91dGxpbmluZ1R5cGUoTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yICZNSVQsIHVuc2lnbmVkIEZsYWdzKSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgKKyAgICAgICAgIlRhcmdldCBkaWRuJ3QgaW1wbGVtZW50IFRhcmdldEluc3RySW5mbzo6Z2V0T3V0bGluaW5nVHlwZSEiKTsKKyAgfQorCisgIC8vLyBcYnJpZWYgUmV0dXJucyB0YXJnZXQtZGVmaW5lZCBmbGFncyBkZWZpbmluZyBwcm9wZXJ0aWVzIG9mIHRoZSBNQkIgZm9yCisgIC8vLyB0aGUgb3V0bGluZXIuCisgIHZpcnR1YWwgdW5zaWduZWQgZ2V0TWFjaGluZU91dGxpbmVyTUJCRmxhZ3MoTWFjaGluZUJhc2ljQmxvY2sgJk1CQikgY29uc3QgeworICAgIHJldHVybiAweDA7CisgIH0KKworICAvLy8gSW5zZXJ0IGEgY3VzdG9tIGVwaWxvZ3VlIGZvciBvdXRsaW5lZCBmdW5jdGlvbnMuCisgIC8vLyBUaGlzIG1heSBiZSBlbXB0eSwgaW4gd2hpY2ggY2FzZSBubyBlcGlsb2d1ZSBvciByZXR1cm4gc3RhdGVtZW50IHdpbGwgYmUKKyAgLy8vIGVtaXR0ZWQuCisgIHZpcnR1YWwgdm9pZCBpbnNlcnRPdXRsaW5lckVwaWxvZ3VlKE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVGdW5jdGlvbiAmTUYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVPdXRsaW5lckluZm8gJk1JbmZvKSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgKKyAgICAgICAgIlRhcmdldCBkaWRuJ3QgaW1wbGVtZW50IFRhcmdldEluc3RySW5mbzo6aW5zZXJ0T3V0bGluZXJFcGlsb2d1ZSEiKTsKKyAgfQorCisgIC8vLyBJbnNlcnQgYSBjYWxsIHRvIGFuIG91dGxpbmVkIGZ1bmN0aW9uIGludG8gdGhlIHByb2dyYW0uCisgIC8vLyBSZXR1cm5zIGFuIGl0ZXJhdG9yIHRvIHRoZSBzcG90IHdoZXJlIHdlIGluc2VydGVkIHRoZSBjYWxsLiBUaGlzIG11c3QgYmUKKyAgLy8vIGltcGxlbWVudGVkIGJ5IHRoZSB0YXJnZXQuCisgIHZpcnR1YWwgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yCisgIGluc2VydE91dGxpbmVkQ2FsbChNb2R1bGUgJk0sIE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jazo6aXRlcmF0b3IgJkl0LCBNYWNoaW5lRnVuY3Rpb24gJk1GLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZU91dGxpbmVySW5mbyAmTUluZm8pIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKAorICAgICAgICAiVGFyZ2V0IGRpZG4ndCBpbXBsZW1lbnQgVGFyZ2V0SW5zdHJJbmZvOjppbnNlcnRPdXRsaW5lZENhbGwhIik7CisgIH0KKworICAvLy8gSW5zZXJ0IGEgY3VzdG9tIHByb2xvZ3VlIGZvciBvdXRsaW5lZCBmdW5jdGlvbnMuCisgIC8vLyBUaGlzIG1heSBiZSBlbXB0eSwgaW4gd2hpY2ggY2FzZSBubyBwcm9sb2d1ZSB3aWxsIGJlIGVtaXR0ZWQuCisgIHZpcnR1YWwgdm9pZCBpbnNlcnRPdXRsaW5lclByb2xvZ3VlKE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVGdW5jdGlvbiAmTUYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVPdXRsaW5lckluZm8gJk1JbmZvKSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgKKyAgICAgICAgIlRhcmdldCBkaWRuJ3QgaW1wbGVtZW50IFRhcmdldEluc3RySW5mbzo6aW5zZXJ0T3V0bGluZXJQcm9sb2d1ZSEiKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgZnVuY3Rpb24gY2FuIHNhZmVseSBiZSBvdXRsaW5lZCBmcm9tLgorICAvLy8gQSBmdW5jdGlvbiBccCBNRiBpcyBjb25zaWRlcmVkIHNhZmUgZm9yIG91dGxpbmluZyBpZiBhbiBvdXRsaW5lZCBmdW5jdGlvbgorICAvLy8gcHJvZHVjZWQgZnJvbSBpbnN0cnVjdGlvbnMgaW4gRiB3aWxsIHByb2R1Y2UgYSBwcm9ncmFtIHdoaWNoIHByb2R1Y2VzIHRoZQorICAvLy8gc2FtZSBvdXRwdXQgZm9yIGFueSBzZXQgb2YgZ2l2ZW4gaW5wdXRzLgorICB2aXJ0dWFsIGJvb2wgaXNGdW5jdGlvblNhZmVUb091dGxpbmVGcm9tKE1hY2hpbmVGdW5jdGlvbiAmTUYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBPdXRsaW5lRnJvbUxpbmtPbmNlT0RScykgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIlRhcmdldCBkaWRuJ3QgaW1wbGVtZW50ICIKKyAgICAgICAgICAgICAgICAgICAgICJUYXJnZXRJbnN0ckluZm86OmlzRnVuY3Rpb25TYWZlVG9PdXRsaW5lRnJvbSEiKTsKKyAgfQorCitwcml2YXRlOgorICB1bnNpZ25lZCBDYWxsRnJhbWVTZXR1cE9wY29kZSwgQ2FsbEZyYW1lRGVzdHJveU9wY29kZTsKKyAgdW5zaWduZWQgQ2F0Y2hSZXRPcGNvZGU7CisgIHVuc2lnbmVkIFJldHVybk9wY29kZTsKK307CisKKy8vLyBcYnJpZWYgUHJvdmlkZSBEZW5zZU1hcEluZm8gZm9yIFRhcmdldEluc3RySW5mbzo6UmVnU3ViUmVnUGFpci4KK3RlbXBsYXRlIDw+IHN0cnVjdCBEZW5zZU1hcEluZm88VGFyZ2V0SW5zdHJJbmZvOjpSZWdTdWJSZWdQYWlyPiB7CisgIHVzaW5nIFJlZ0luZm8gPSBEZW5zZU1hcEluZm88dW5zaWduZWQ+OworCisgIHN0YXRpYyBpbmxpbmUgVGFyZ2V0SW5zdHJJbmZvOjpSZWdTdWJSZWdQYWlyIGdldEVtcHR5S2V5KCkgeworICAgIHJldHVybiBUYXJnZXRJbnN0ckluZm86OlJlZ1N1YlJlZ1BhaXIoUmVnSW5mbzo6Z2V0RW1wdHlLZXkoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZ0luZm86OmdldEVtcHR5S2V5KCkpOworICB9CisKKyAgc3RhdGljIGlubGluZSBUYXJnZXRJbnN0ckluZm86OlJlZ1N1YlJlZ1BhaXIgZ2V0VG9tYnN0b25lS2V5KCkgeworICAgIHJldHVybiBUYXJnZXRJbnN0ckluZm86OlJlZ1N1YlJlZ1BhaXIoUmVnSW5mbzo6Z2V0VG9tYnN0b25lS2V5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdJbmZvOjpnZXRUb21ic3RvbmVLZXkoKSk7CisgIH0KKworICAvLy8gXGJyaWVmIFJldXNlIGdldEhhc2hWYWx1ZSBpbXBsZW1lbnRhdGlvbiBmcm9tCisgIC8vLyBzdGQ6OnBhaXI8dW5zaWduZWQsIHVuc2lnbmVkPi4KKyAgc3RhdGljIHVuc2lnbmVkIGdldEhhc2hWYWx1ZShjb25zdCBUYXJnZXRJbnN0ckluZm86OlJlZ1N1YlJlZ1BhaXIgJlZhbCkgeworICAgIHN0ZDo6cGFpcjx1bnNpZ25lZCwgdW5zaWduZWQ+IFBhaXJWYWwgPSBzdGQ6Om1ha2VfcGFpcihWYWwuUmVnLCBWYWwuU3ViUmVnKTsKKyAgICByZXR1cm4gRGVuc2VNYXBJbmZvPHN0ZDo6cGFpcjx1bnNpZ25lZCwgdW5zaWduZWQ+Pjo6Z2V0SGFzaFZhbHVlKFBhaXJWYWwpOworICB9CisKKyAgc3RhdGljIGJvb2wgaXNFcXVhbChjb25zdCBUYXJnZXRJbnN0ckluZm86OlJlZ1N1YlJlZ1BhaXIgJkxIUywKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRJbnN0ckluZm86OlJlZ1N1YlJlZ1BhaXIgJlJIUykgeworICAgIHJldHVybiBSZWdJbmZvOjppc0VxdWFsKExIUy5SZWcsIFJIUy5SZWcpICYmCisgICAgICAgICAgIFJlZ0luZm86OmlzRXF1YWwoTEhTLlN1YlJlZywgUkhTLlN1YlJlZyk7CisgIH0KK307CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX1RBUkdFVF9UQVJHRVRJTlNUUklORk9fSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhcmdldExvd2VyaW5nLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vVGFyZ2V0TG93ZXJpbmcuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ODMyMjNhCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhcmdldExvd2VyaW5nLmgKQEAgLTAsMCArMSwzNjE1IEBACisvLz09PS0gbGx2bS9Db2RlR2VuL1RhcmdldExvd2VyaW5nLmggLSBUYXJnZXQgTG93ZXJpbmcgSW5mbyAtLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vCisvLy8gXGZpbGUKKy8vLyBUaGlzIGZpbGUgZGVzY3JpYmVzIGhvdyB0byBsb3dlciBMTFZNIGNvZGUgdG8gbWFjaGluZSBjb2RlLiAgVGhpcyBoYXMgdHdvCisvLy8gbWFpbiBjb21wb25lbnRzOgorLy8vCisvLy8gIDEuIFdoaWNoIFZhbHVlVHlwZXMgYXJlIG5hdGl2ZWx5IHN1cHBvcnRlZCBieSB0aGUgdGFyZ2V0LgorLy8vICAyLiBXaGljaCBvcGVyYXRpb25zIGFyZSBzdXBwb3J0ZWQgZm9yIHN1cHBvcnRlZCBWYWx1ZVR5cGVzLgorLy8vICAzLiBDb3N0IHRocmVzaG9sZHMgZm9yIGFsdGVybmF0aXZlIGltcGxlbWVudGF0aW9ucyBvZiBjZXJ0YWluIG9wZXJhdGlvbnMuCisvLy8KKy8vLyBJbiBhZGRpdGlvbiBpdCBoYXMgYSBmZXcgb3RoZXIgY29tcG9uZW50cywgbGlrZSBpbmZvcm1hdGlvbiBhYm91dCBGUAorLy8vIGltbWVkaWF0ZXMuCisvLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1RBUkdFVExPV0VSSU5HX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1RBUkdFVExPV0VSSU5HX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0FQSW50LmgiCisjaW5jbHVkZSAibGx2bS9BRFQvQXJyYXlSZWYuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9EZW5zZU1hcC5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NUTEV4dHJhcy5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU3RyaW5nUmVmLmgiCisjaW5jbHVkZSAibGx2bS9BbmFseXNpcy9EaXZlcmdlbmNlQW5hbHlzaXMuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vREFHQ29tYmluZS5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9JU0RPcGNvZGVzLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1J1bnRpbWVMaWJjYWxscy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9TZWxlY3Rpb25EQUcuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vU2VsZWN0aW9uREFHTm9kZXMuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVGFyZ2V0Q2FsbGluZ0NvbnYuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vVmFsdWVUeXBlcy5oIgorI2luY2x1ZGUgImxsdm0vSVIvQXR0cmlidXRlcy5oIgorI2luY2x1ZGUgImxsdm0vSVIvQ2FsbFNpdGUuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0NhbGxpbmdDb252LmgiCisjaW5jbHVkZSAibGx2bS9JUi9EYXRhTGF5b3V0LmgiCisjaW5jbHVkZSAibGx2bS9JUi9EZXJpdmVkVHlwZXMuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0Z1bmN0aW9uLmgiCisjaW5jbHVkZSAibGx2bS9JUi9JUkJ1aWxkZXIuaCIKKyNpbmNsdWRlICJsbHZtL0lSL0lubGluZUFzbS5oIgorI2luY2x1ZGUgImxsdm0vSVIvSW5zdHJ1Y3Rpb24uaCIKKyNpbmNsdWRlICJsbHZtL0lSL0luc3RydWN0aW9ucy5oIgorI2luY2x1ZGUgImxsdm0vSVIvVHlwZS5oIgorI2luY2x1ZGUgImxsdm0vTUMvTUNSZWdpc3RlckluZm8uaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvQXRvbWljT3JkZXJpbmcuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvQ2FzdGluZy5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9FcnJvckhhbmRsaW5nLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L01hY2hpbmVWYWx1ZVR5cGUuaCIKKyNpbmNsdWRlICJsbHZtL1RhcmdldC9UYXJnZXRNYWNoaW5lLmgiCisjaW5jbHVkZSA8YWxnb3JpdGhtPgorI2luY2x1ZGUgPGNhc3NlcnQ+CisjaW5jbHVkZSA8Y2xpbWl0cz4KKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPGl0ZXJhdG9yPgorI2luY2x1ZGUgPG1hcD4KKyNpbmNsdWRlIDxzdHJpbmc+CisjaW5jbHVkZSA8dXRpbGl0eT4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgQnJhbmNoUHJvYmFiaWxpdHk7CitjbGFzcyBDQ1N0YXRlOworY2xhc3MgQ0NWYWxBc3NpZ247CitjbGFzcyBDb25zdGFudDsKK2NsYXNzIEZhc3RJU2VsOworY2xhc3MgRnVuY3Rpb25Mb3dlcmluZ0luZm87CitjbGFzcyBHbG9iYWxWYWx1ZTsKK2NsYXNzIEludHJpbnNpY0luc3Q7CitzdHJ1Y3QgS25vd25CaXRzOworY2xhc3MgTExWTUNvbnRleHQ7CitjbGFzcyBNYWNoaW5lQmFzaWNCbG9jazsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIE1hY2hpbmVJbnN0cjsKK2NsYXNzIE1hY2hpbmVKdW1wVGFibGVJbmZvOworY2xhc3MgTWFjaGluZUxvb3A7CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworY2xhc3MgTUNDb250ZXh0OworY2xhc3MgTUNFeHByOworY2xhc3MgTW9kdWxlOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJDbGFzczsKK2NsYXNzIFRhcmdldExpYnJhcnlJbmZvOworY2xhc3MgVGFyZ2V0UmVnaXN0ZXJJbmZvOworY2xhc3MgVmFsdWU7CisKK25hbWVzcGFjZSBTY2hlZCB7CisKKyAgZW51bSBQcmVmZXJlbmNlIHsKKyAgICBOb25lLCAgICAgICAgICAgICAvLyBObyBwcmVmZXJlbmNlCisgICAgU291cmNlLCAgICAgICAgICAgLy8gRm9sbG93IHNvdXJjZSBvcmRlci4KKyAgICBSZWdQcmVzc3VyZSwgICAgICAvLyBTY2hlZHVsaW5nIGZvciBsb3dlc3QgcmVnaXN0ZXIgcHJlc3N1cmUuCisgICAgSHlicmlkLCAgICAgICAgICAgLy8gU2NoZWR1bGluZyBmb3IgYm90aCBsYXRlbmN5IGFuZCByZWdpc3RlciBwcmVzc3VyZS4KKyAgICBJTFAsICAgICAgICAgICAgICAvLyBTY2hlZHVsaW5nIGZvciBJTFAgaW4gbG93IHJlZ2lzdGVyIHByZXNzdXJlIG1vZGUuCisgICAgVkxJVyAgICAgICAgICAgICAgLy8gU2NoZWR1bGluZyBmb3IgVkxJVyB0YXJnZXRzLgorICB9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgU2NoZWQKKworLy8vIFRoaXMgYmFzZSBjbGFzcyBmb3IgVGFyZ2V0TG93ZXJpbmcgY29udGFpbnMgdGhlIFNlbGVjdGlvbkRBRy1pbmRlcGVuZGVudAorLy8vIHBhcnRzIHRoYXQgY2FuIGJlIHVzZWQgZnJvbSB0aGUgcmVzdCBvZiBDb2RlR2VuLgorY2xhc3MgVGFyZ2V0TG93ZXJpbmdCYXNlIHsKK3B1YmxpYzoKKyAgLy8vIFRoaXMgZW51bSBpbmRpY2F0ZXMgd2hldGhlciBvcGVyYXRpb25zIGFyZSB2YWxpZCBmb3IgYSB0YXJnZXQsIGFuZCBpZiBub3QsCisgIC8vLyB3aGF0IGFjdGlvbiBzaG91bGQgYmUgdXNlZCB0byBtYWtlIHRoZW0gdmFsaWQuCisgIGVudW0gTGVnYWxpemVBY3Rpb24gOiB1aW50OF90IHsKKyAgICBMZWdhbCwgICAgICAvLyBUaGUgdGFyZ2V0IG5hdGl2ZWx5IHN1cHBvcnRzIHRoaXMgb3BlcmF0aW9uLgorICAgIFByb21vdGUsICAgIC8vIFRoaXMgb3BlcmF0aW9uIHNob3VsZCBiZSBleGVjdXRlZCBpbiBhIGxhcmdlciB0eXBlLgorICAgIEV4cGFuZCwgICAgIC8vIFRyeSB0byBleHBhbmQgdGhpcyB0byBvdGhlciBvcHMsIG90aGVyd2lzZSB1c2UgYSBsaWJjYWxsLgorICAgIExpYkNhbGwsICAgIC8vIERvbid0IHRyeSB0byBleHBhbmQgdGhpcyB0byBvdGhlciBvcHMsIGFsd2F5cyB1c2UgYSBsaWJjYWxsLgorICAgIEN1c3RvbSAgICAgIC8vIFVzZSB0aGUgTG93ZXJPcGVyYXRpb24gaG9vayB0byBpbXBsZW1lbnQgY3VzdG9tIGxvd2VyaW5nLgorICB9OworCisgIC8vLyBUaGlzIGVudW0gaW5kaWNhdGVzIHdoZXRoZXIgYSB0eXBlcyBhcmUgbGVnYWwgZm9yIGEgdGFyZ2V0LCBhbmQgaWYgbm90LAorICAvLy8gd2hhdCBhY3Rpb24gc2hvdWxkIGJlIHVzZWQgdG8gbWFrZSB0aGVtIHZhbGlkLgorICBlbnVtIExlZ2FsaXplVHlwZUFjdGlvbiA6IHVpbnQ4X3QgeworICAgIFR5cGVMZWdhbCwgICAgICAgICAgIC8vIFRoZSB0YXJnZXQgbmF0aXZlbHkgc3VwcG9ydHMgdGhpcyB0eXBlLgorICAgIFR5cGVQcm9tb3RlSW50ZWdlciwgIC8vIFJlcGxhY2UgdGhpcyBpbnRlZ2VyIHdpdGggYSBsYXJnZXIgb25lLgorICAgIFR5cGVFeHBhbmRJbnRlZ2VyLCAgIC8vIFNwbGl0IHRoaXMgaW50ZWdlciBpbnRvIHR3byBvZiBoYWxmIHRoZSBzaXplLgorICAgIFR5cGVTb2Z0ZW5GbG9hdCwgICAgIC8vIENvbnZlcnQgdGhpcyBmbG9hdCB0byBhIHNhbWUgc2l6ZSBpbnRlZ2VyIHR5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgYW4gb3BlcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgaW4gdGFyZ2V0IEhXLgorICAgIFR5cGVFeHBhbmRGbG9hdCwgICAgIC8vIFNwbGl0IHRoaXMgZmxvYXQgaW50byB0d28gb2YgaGFsZiB0aGUgc2l6ZS4KKyAgICBUeXBlU2NhbGFyaXplVmVjdG9yLCAvLyBSZXBsYWNlIHRoaXMgb25lLWVsZW1lbnQgdmVjdG9yIHdpdGggaXRzIGVsZW1lbnQuCisgICAgVHlwZVNwbGl0VmVjdG9yLCAgICAgLy8gU3BsaXQgdGhpcyB2ZWN0b3IgaW50byB0d28gb2YgaGFsZiB0aGUgc2l6ZS4KKyAgICBUeXBlV2lkZW5WZWN0b3IsICAgICAvLyBUaGlzIHZlY3RvciBzaG91bGQgYmUgd2lkZW5lZCBpbnRvIGEgbGFyZ2VyIHZlY3Rvci4KKyAgICBUeXBlUHJvbW90ZUZsb2F0ICAgICAvLyBSZXBsYWNlIHRoaXMgZmxvYXQgd2l0aCBhIGxhcmdlciBvbmUuCisgIH07CisKKyAgLy8vIExlZ2FsaXplS2luZCBob2xkcyB0aGUgbGVnYWxpemF0aW9uIGtpbmQgdGhhdCBuZWVkcyB0byBoYXBwZW4gdG8gRVZUCisgIC8vLyBpbiBvcmRlciB0byB0eXBlLWxlZ2FsaXplIGl0LgorICB1c2luZyBMZWdhbGl6ZUtpbmQgPSBzdGQ6OnBhaXI8TGVnYWxpemVUeXBlQWN0aW9uLCBFVlQ+OworCisgIC8vLyBFbnVtIHRoYXQgZGVzY3JpYmVzIGhvdyB0aGUgdGFyZ2V0IHJlcHJlc2VudHMgdHJ1ZS9mYWxzZSB2YWx1ZXMuCisgIGVudW0gQm9vbGVhbkNvbnRlbnQgeworICAgIFVuZGVmaW5lZEJvb2xlYW5Db250ZW50LCAgICAvLyBPbmx5IGJpdCAwIGNvdW50cywgdGhlIHJlc3QgY2FuIGhvbGQgZ2FyYmFnZS4KKyAgICBaZXJvT3JPbmVCb29sZWFuQ29udGVudCwgICAgICAgIC8vIEFsbCBiaXRzIHplcm8gZXhjZXB0IGZvciBiaXQgMC4KKyAgICBaZXJvT3JOZWdhdGl2ZU9uZUJvb2xlYW5Db250ZW50IC8vIEFsbCBiaXRzIGVxdWFsIHRvIGJpdCAwLgorICB9OworCisgIC8vLyBFbnVtIHRoYXQgZGVzY3JpYmVzIHdoYXQgdHlwZSBvZiBzdXBwb3J0IGZvciBzZWxlY3RzIHRoZSB0YXJnZXQgaGFzLgorICBlbnVtIFNlbGVjdFN1cHBvcnRLaW5kIHsKKyAgICBTY2FsYXJWYWxTZWxlY3QsICAgICAgLy8gVGhlIHRhcmdldCBzdXBwb3J0cyBzY2FsYXIgc2VsZWN0cyAoZXg6IGNtb3YpLgorICAgIFNjYWxhckNvbmRWZWN0b3JWYWwsICAvLyBUaGUgdGFyZ2V0IHN1cHBvcnRzIHNlbGVjdHMgd2l0aCBhIHNjYWxhciBjb25kaXRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYW5kIHZlY3RvciB2YWx1ZXMgKGV4OiBjbW92KS4KKyAgICBWZWN0b3JNYXNrU2VsZWN0ICAgICAgLy8gVGhlIHRhcmdldCBzdXBwb3J0cyB2ZWN0b3Igc2VsZWN0cyB3aXRoIGEgdmVjdG9yCisgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1hc2sgKGV4OiB4ODYgYmxlbmRzKS4KKyAgfTsKKworICAvLy8gRW51bSB0aGF0IHNwZWNpZmllcyB3aGF0IGFuIGF0b21pYyBsb2FkL0F0b21pY1JNV0luc3QgaXMgZXhwYW5kZWQKKyAgLy8vIHRvLCBpZiBhdCBhbGwuIEV4aXN0cyBiZWNhdXNlIGRpZmZlcmVudCB0YXJnZXRzIGhhdmUgZGlmZmVyZW50IGxldmVscyBvZgorICAvLy8gc3VwcG9ydCBmb3IgdGhlc2UgYXRvbWljIGluc3RydWN0aW9ucywgYW5kIGFsc28gaGF2ZSBkaWZmZXJlbnQgb3B0aW9ucworICAvLy8gdy5yLnQuIHdoYXQgdGhleSBzaG91bGQgZXhwYW5kIHRvLgorICBlbnVtIGNsYXNzIEF0b21pY0V4cGFuc2lvbktpbmQgeworICAgIE5vbmUsICAgIC8vIERvbid0IGV4cGFuZCB0aGUgaW5zdHJ1Y3Rpb24uCisgICAgTExTQywgICAgLy8gRXhwYW5kIHRoZSBpbnN0cnVjdGlvbiBpbnRvIGxvYWRsaW5rZWQvc3RvcmVjb25kaXRpb25hbDsgdXNlZAorICAgICAgICAgICAgIC8vIGJ5IEFSTS9BQXJjaDY0LgorICAgIExMT25seSwgIC8vIEV4cGFuZCB0aGUgKGxvYWQpIGluc3RydWN0aW9uIGludG8ganVzdCBhIGxvYWQtbGlua2VkLCB3aGljaCBoYXMKKyAgICAgICAgICAgICAvLyBncmVhdGVyIGF0b21pYyBndWFyYW50ZWVzIHRoYW4gYSBub3JtYWwgbG9hZC4KKyAgICBDbXBYQ2hnLCAvLyBFeHBhbmQgdGhlIGluc3RydWN0aW9uIGludG8gY21weGNoZzsgdXNlZCBieSBhdCBsZWFzdCBYODYuCisgIH07CisKKyAgLy8vIEVudW0gdGhhdCBzcGVjaWZpZXMgd2hlbiBhIG11bHRpcGxpY2F0aW9uIHNob3VsZCBiZSBleHBhbmRlZC4KKyAgZW51bSBjbGFzcyBNdWxFeHBhbnNpb25LaW5kIHsKKyAgICBBbHdheXMsICAgICAgICAgICAgLy8gQWx3YXlzIGV4cGFuZCB0aGUgaW5zdHJ1Y3Rpb24uCisgICAgT25seUxlZ2FsT3JDdXN0b20sIC8vIE9ubHkgZXhwYW5kIHdoZW4gdGhlIHJlc3VsdGluZyBpbnN0cnVjdGlvbnMgYXJlIGxlZ2FsCisgICAgICAgICAgICAgICAgICAgICAgIC8vIG9yIGN1c3RvbS4KKyAgfTsKKworICBjbGFzcyBBcmdMaXN0RW50cnkgeworICBwdWJsaWM6CisgICAgVmFsdWUgKlZhbCA9IG51bGxwdHI7CisgICAgU0RWYWx1ZSBOb2RlID0gU0RWYWx1ZSgpOworICAgIFR5cGUgKlR5ID0gbnVsbHB0cjsKKyAgICBib29sIElzU0V4dCA6IDE7CisgICAgYm9vbCBJc1pFeHQgOiAxOworICAgIGJvb2wgSXNJblJlZyA6IDE7CisgICAgYm9vbCBJc1NSZXQgOiAxOworICAgIGJvb2wgSXNOZXN0IDogMTsKKyAgICBib29sIElzQnlWYWwgOiAxOworICAgIGJvb2wgSXNJbkFsbG9jYSA6IDE7CisgICAgYm9vbCBJc1JldHVybmVkIDogMTsKKyAgICBib29sIElzU3dpZnRTZWxmIDogMTsKKyAgICBib29sIElzU3dpZnRFcnJvciA6IDE7CisgICAgdWludDE2X3QgQWxpZ25tZW50ID0gMDsKKworICAgIEFyZ0xpc3RFbnRyeSgpCisgICAgICAgIDogSXNTRXh0KGZhbHNlKSwgSXNaRXh0KGZhbHNlKSwgSXNJblJlZyhmYWxzZSksIElzU1JldChmYWxzZSksCisgICAgICAgICAgSXNOZXN0KGZhbHNlKSwgSXNCeVZhbChmYWxzZSksIElzSW5BbGxvY2EoZmFsc2UpLCBJc1JldHVybmVkKGZhbHNlKSwKKyAgICAgICAgICBJc1N3aWZ0U2VsZihmYWxzZSksIElzU3dpZnRFcnJvcihmYWxzZSkge30KKworICAgIHZvaWQgc2V0QXR0cmlidXRlcyhJbW11dGFibGVDYWxsU2l0ZSAqQ1MsIHVuc2lnbmVkIEFyZ0lkeCk7CisgIH07CisgIHVzaW5nIEFyZ0xpc3RUeSA9IHN0ZDo6dmVjdG9yPEFyZ0xpc3RFbnRyeT47CisKKyAgdmlydHVhbCB2b2lkIG1hcmtMaWJDYWxsQXR0cmlidXRlcyhNYWNoaW5lRnVuY3Rpb24gKk1GLCB1bnNpZ25lZCBDQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcmdMaXN0VHkgJkFyZ3MpIGNvbnN0IHt9OworCisgIHN0YXRpYyBJU0Q6Ok5vZGVUeXBlIGdldEV4dGVuZEZvckNvbnRlbnQoQm9vbGVhbkNvbnRlbnQgQ29udGVudCkgeworICAgIHN3aXRjaCAoQ29udGVudCkgeworICAgIGNhc2UgVW5kZWZpbmVkQm9vbGVhbkNvbnRlbnQ6CisgICAgICAvLyBFeHRlbmQgYnkgYWRkaW5nIHJ1YmJpc2ggYml0cy4KKyAgICAgIHJldHVybiBJU0Q6OkFOWV9FWFRFTkQ7CisgICAgY2FzZSBaZXJvT3JPbmVCb29sZWFuQ29udGVudDoKKyAgICAgIC8vIEV4dGVuZCBieSBhZGRpbmcgemVybyBiaXRzLgorICAgICAgcmV0dXJuIElTRDo6WkVST19FWFRFTkQ7CisgICAgY2FzZSBaZXJvT3JOZWdhdGl2ZU9uZUJvb2xlYW5Db250ZW50OgorICAgICAgLy8gRXh0ZW5kIGJ5IGNvcHlpbmcgdGhlIHNpZ24gYml0LgorICAgICAgcmV0dXJuIElTRDo6U0lHTl9FWFRFTkQ7CisgICAgfQorICAgIGxsdm1fdW5yZWFjaGFibGUoIkludmFsaWQgY29udGVudCBraW5kIik7CisgIH0KKworICAvLy8gTk9URTogVGhlIFRhcmdldE1hY2hpbmUgb3ducyBUTE9GLgorICBleHBsaWNpdCBUYXJnZXRMb3dlcmluZ0Jhc2UoY29uc3QgVGFyZ2V0TWFjaGluZSAmVE0pOworICBUYXJnZXRMb3dlcmluZ0Jhc2UoY29uc3QgVGFyZ2V0TG93ZXJpbmdCYXNlICYpID0gZGVsZXRlOworICBUYXJnZXRMb3dlcmluZ0Jhc2UgJm9wZXJhdG9yPShjb25zdCBUYXJnZXRMb3dlcmluZ0Jhc2UgJikgPSBkZWxldGU7CisgIHZpcnR1YWwgflRhcmdldExvd2VyaW5nQmFzZSgpID0gZGVmYXVsdDsKKworcHJvdGVjdGVkOgorICAvLy8gXGJyaWVmIEluaXRpYWxpemUgYWxsIG9mIHRoZSBhY3Rpb25zIHRvIGRlZmF1bHQgdmFsdWVzLgorICB2b2lkIGluaXRBY3Rpb25zKCk7CisKK3B1YmxpYzoKKyAgY29uc3QgVGFyZ2V0TWFjaGluZSAmZ2V0VGFyZ2V0TWFjaGluZSgpIGNvbnN0IHsgcmV0dXJuIFRNOyB9CisKKyAgdmlydHVhbCBib29sIHVzZVNvZnRGbG9hdCgpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgLy8vIFJldHVybiB0aGUgcG9pbnRlciB0eXBlIGZvciB0aGUgZ2l2ZW4gYWRkcmVzcyBzcGFjZSwgZGVmYXVsdHMgdG8KKyAgLy8vIHRoZSBwb2ludGVyIHR5cGUgZnJvbSB0aGUgZGF0YSBsYXlvdXQuCisgIC8vLyBGSVhNRTogVGhlIGRlZmF1bHQgbmVlZHMgdG8gYmUgcmVtb3ZlZCBvbmNlIGFsbCB0aGUgY29kZSBpcyB1cGRhdGVkLgorICBNVlQgZ2V0UG9pbnRlclR5KGNvbnN0IERhdGFMYXlvdXQgJkRMLCB1aW50MzJfdCBBUyA9IDApIGNvbnN0IHsKKyAgICByZXR1cm4gTVZUOjpnZXRJbnRlZ2VyVlQoREwuZ2V0UG9pbnRlclNpemVJbkJpdHMoQVMpKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIHR5cGUgZm9yIGZyYW1lIGluZGV4LCB3aGljaCBpcyBkZXRlcm1pbmVkIGJ5CisgIC8vLyB0aGUgYWxsb2NhIGFkZHJlc3Mgc3BhY2Ugc3BlY2lmaWVkIHRocm91Z2ggdGhlIGRhdGEgbGF5b3V0LgorICBNVlQgZ2V0RnJhbWVJbmRleFR5KGNvbnN0IERhdGFMYXlvdXQgJkRMKSBjb25zdCB7CisgICAgcmV0dXJuIGdldFBvaW50ZXJUeShETCwgREwuZ2V0QWxsb2NhQWRkclNwYWNlKCkpOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgdHlwZSBmb3Igb3BlcmFuZHMgb2YgZmVuY2UuCisgIC8vLyBUT0RPOiBMZXQgZmVuY2Ugb3BlcmFuZHMgYmUgb2YgaTMyIHR5cGUgYW5kIHJlbW92ZSB0aGlzLgorICB2aXJ0dWFsIE1WVCBnZXRGZW5jZU9wZXJhbmRUeShjb25zdCBEYXRhTGF5b3V0ICZETCkgY29uc3QgeworICAgIHJldHVybiBnZXRQb2ludGVyVHkoREwpOworICB9CisKKyAgLy8vIEVWVCBpcyBub3QgdXNlZCBpbi10cmVlLCBidXQgaXMgdXNlZCBieSBvdXQtb2YtdHJlZSB0YXJnZXQuCisgIC8vLyBBIGRvY3VtZW50YXRpb24gZm9yIHRoaXMgZnVuY3Rpb24gd291bGQgYmUgbmljZS4uLgorICB2aXJ0dWFsIE1WVCBnZXRTY2FsYXJTaGlmdEFtb3VudFR5KGNvbnN0IERhdGFMYXlvdXQgJiwgRVZUKSBjb25zdDsKKworICBFVlQgZ2V0U2hpZnRBbW91bnRUeShFVlQgTEhTVHksIGNvbnN0IERhdGFMYXlvdXQgJkRMLAorICAgICAgICAgICAgICAgICAgICAgICBib29sIExlZ2FsVHlwZXMgPSB0cnVlKSBjb25zdDsKKworICAvLy8gUmV0dXJucyB0aGUgdHlwZSB0byBiZSB1c2VkIGZvciB0aGUgaW5kZXggb3BlcmFuZCBvZjoKKyAgLy8vIElTRDo6SU5TRVJUX1ZFQ1RPUl9FTFQsIElTRDo6RVhUUkFDVF9WRUNUT1JfRUxULAorICAvLy8gSVNEOjpJTlNFUlRfU1VCVkVDVE9SLCBhbmQgSVNEOjpFWFRSQUNUX1NVQlZFQ1RPUgorICB2aXJ0dWFsIE1WVCBnZXRWZWN0b3JJZHhUeShjb25zdCBEYXRhTGF5b3V0ICZETCkgY29uc3QgeworICAgIHJldHVybiBnZXRQb2ludGVyVHkoREwpOworICB9CisKKyAgdmlydHVhbCBib29sIGlzU2VsZWN0U3VwcG9ydGVkKFNlbGVjdFN1cHBvcnRLaW5kIC8qa2luZCovKSBjb25zdCB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgbXVsdGlwbGUgY29uZGl0aW9uIHJlZ2lzdGVycyBhcmUgYXZhaWxhYmxlLgorICBib29sIGhhc011bHRpcGxlQ29uZGl0aW9uUmVnaXN0ZXJzKCkgY29uc3QgeworICAgIHJldHVybiBIYXNNdWx0aXBsZUNvbmRpdGlvblJlZ2lzdGVyczsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgdGFyZ2V0IGhhcyBCaXRFeHRyYWN0IGluc3RydWN0aW9ucy4KKyAgYm9vbCBoYXNFeHRyYWN0Qml0c0luc24oKSBjb25zdCB7IHJldHVybiBIYXNFeHRyYWN0Qml0c0luc247IH0KKworICAvLy8gUmV0dXJuIHRoZSBwcmVmZXJyZWQgdmVjdG9yIHR5cGUgbGVnYWxpemF0aW9uIGFjdGlvbi4KKyAgdmlydHVhbCBUYXJnZXRMb3dlcmluZ0Jhc2U6OkxlZ2FsaXplVHlwZUFjdGlvbgorICBnZXRQcmVmZXJyZWRWZWN0b3JBY3Rpb24oRVZUIFZUKSBjb25zdCB7CisgICAgLy8gVGhlIGRlZmF1bHQgYWN0aW9uIGZvciBvbmUgZWxlbWVudCB2ZWN0b3JzIGlzIHRvIHNjYWxhcml6ZQorICAgIGlmIChWVC5nZXRWZWN0b3JOdW1FbGVtZW50cygpID09IDEpCisgICAgICByZXR1cm4gVHlwZVNjYWxhcml6ZVZlY3RvcjsKKyAgICAvLyBUaGUgZGVmYXVsdCBhY3Rpb24gZm9yIG90aGVyIHZlY3RvcnMgaXMgdG8gcHJvbW90ZQorICAgIHJldHVybiBUeXBlUHJvbW90ZUludGVnZXI7CisgIH0KKworICAvLyBUaGVyZSBhcmUgdHdvIGdlbmVyYWwgbWV0aG9kcyBmb3IgZXhwYW5kaW5nIGEgQlVJTERfVkVDVE9SIG5vZGU6CisgIC8vICAxLiBVc2UgU0NBTEFSX1RPX1ZFQ1RPUiBvbiB0aGUgZGVmaW5lZCBzY2FsYXIgdmFsdWVzIGFuZCB0aGVuIHNodWZmbGUKKyAgLy8gICAgIHRoZW0gdG9nZXRoZXIuCisgIC8vICAyLiBCdWlsZCB0aGUgdmVjdG9yIG9uIHRoZSBzdGFjayBhbmQgdGhlbiBsb2FkIGl0LgorICAvLyBJZiB0aGlzIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSwgdGhlbiBtZXRob2QgKDEpIHdpbGwgYmUgdXNlZCwgc3ViamVjdCB0bworICAvLyB0aGUgY29uc3RyYWludCB0aGF0IGFsbCBvZiB0aGUgbmVjZXNzYXJ5IHNodWZmbGVzIGFyZSBsZWdhbCAoYXMgZGV0ZXJtaW5lZAorICAvLyBieSBpc1NodWZmbGVNYXNrTGVnYWwpLiBJZiB0aGlzIGZ1bmN0aW9uIHJldHVybnMgZmFsc2UsIHRoZW4gbWV0aG9kICgyKSBpcworICAvLyBhbHdheXMgdXNlZC4gVGhlIHZlY3RvciB0eXBlLCBhbmQgdGhlIG51bWJlciBvZiBkZWZpbmVkIHZhbHVlcywgYXJlCisgIC8vIHByb3ZpZGVkLgorICB2aXJ0dWFsIGJvb2wKKyAgc2hvdWxkRXhwYW5kQnVpbGRWZWN0b3JXaXRoU2h1ZmZsZXMoRVZUIC8qIFZUICovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBEZWZpbmVkVmFsdWVzKSBjb25zdCB7CisgICAgcmV0dXJuIERlZmluZWRWYWx1ZXMgPCAzOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGludGVnZXIgZGl2aWRlIGlzIHVzdWFsbHkgY2hlYXBlciB0aGFuIGEgc2VxdWVuY2Ugb2YKKyAgLy8vIHNldmVyYWwgc2hpZnRzLCBhZGRzLCBhbmQgbXVsdGlwbGllcyBmb3IgdGhpcyB0YXJnZXQuCisgIC8vLyBUaGUgZGVmaW5pdGlvbiBvZiAiY2hlYXBlciIgbWF5IGRlcGVuZCBvbiB3aGV0aGVyIHdlJ3JlIG9wdGltaXppbmcKKyAgLy8vIGZvciBzcGVlZCBvciBmb3Igc2l6ZS4KKyAgdmlydHVhbCBib29sIGlzSW50RGl2Q2hlYXAoRVZUIFZULCBBdHRyaWJ1dGVMaXN0IEF0dHIpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSB0YXJnZXQgY2FuIGhhbmRsZSBhIHN0YW5kYWxvbmUgcmVtYWluZGVyIG9wZXJhdGlvbi4KKyAgdmlydHVhbCBib29sIGhhc1N0YW5kYWxvbmVSZW0oRVZUIFZUKSBjb25zdCB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgU1FSVChYKSBzaG91bGRuJ3QgYmUgcmVwbGFjZWQgd2l0aCBYKlJTUVJUKFgpLgorICB2aXJ0dWFsIGJvb2wgaXNGc3FydENoZWFwKFNEVmFsdWUgWCwgU2VsZWN0aW9uREFHICZEQUcpIGNvbnN0IHsKKyAgICAvLyBEZWZhdWx0IGJlaGF2aW9yIGlzIHRvIHJlcGxhY2UgU1FSVChYKSB3aXRoIFgqUlNRUlQoWCkuCisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJlY2lwcm9jYWwgZXN0aW1hdGUgc3RhdHVzIHZhbHVlcyB1c2VkIGJ5IHRoZSBmdW5jdGlvbnMgYmVsb3cuCisgIGVudW0gUmVjaXByb2NhbEVzdGltYXRlIDogaW50IHsKKyAgICBVbnNwZWNpZmllZCA9IC0xLAorICAgIERpc2FibGVkID0gMCwKKyAgICBFbmFibGVkID0gMQorICB9OworCisgIC8vLyBSZXR1cm4gYSBSZWNpcHJvY2FsRXN0aW1hdGUgZW51bSB2YWx1ZSBmb3IgYSBzcXVhcmUgcm9vdCBvZiB0aGUgZ2l2ZW4gdHlwZQorICAvLy8gYmFzZWQgb24gdGhlIGZ1bmN0aW9uJ3MgYXR0cmlidXRlcy4gSWYgdGhlIG9wZXJhdGlvbiBpcyBub3Qgb3ZlcnJpZGRlbiBieQorICAvLy8gdGhlIGZ1bmN0aW9uJ3MgYXR0cmlidXRlcywgIlVuc3BlY2lmaWVkIiBpcyByZXR1cm5lZCBhbmQgdGFyZ2V0IGRlZmF1bHRzCisgIC8vLyBhcmUgZXhwZWN0ZWQgdG8gYmUgdXNlZCBmb3IgaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uLgorICBpbnQgZ2V0UmVjaXBFc3RpbWF0ZVNxcnRFbmFibGVkKEVWVCBWVCwgTWFjaGluZUZ1bmN0aW9uICZNRikgY29uc3Q7CisKKyAgLy8vIFJldHVybiBhIFJlY2lwcm9jYWxFc3RpbWF0ZSBlbnVtIHZhbHVlIGZvciBhIGRpdmlzaW9uIG9mIHRoZSBnaXZlbiB0eXBlCisgIC8vLyBiYXNlZCBvbiB0aGUgZnVuY3Rpb24ncyBhdHRyaWJ1dGVzLiBJZiB0aGUgb3BlcmF0aW9uIGlzIG5vdCBvdmVycmlkZGVuIGJ5CisgIC8vLyB0aGUgZnVuY3Rpb24ncyBhdHRyaWJ1dGVzLCAiVW5zcGVjaWZpZWQiIGlzIHJldHVybmVkIGFuZCB0YXJnZXQgZGVmYXVsdHMKKyAgLy8vIGFyZSBleHBlY3RlZCB0byBiZSB1c2VkIGZvciBpbnN0cnVjdGlvbiBzZWxlY3Rpb24uCisgIGludCBnZXRSZWNpcEVzdGltYXRlRGl2RW5hYmxlZChFVlQgVlQsIE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdGhlIHJlZmluZW1lbnQgc3RlcCBjb3VudCBmb3IgYSBzcXVhcmUgcm9vdCBvZiB0aGUgZ2l2ZW4gdHlwZSBiYXNlZAorICAvLy8gb24gdGhlIGZ1bmN0aW9uJ3MgYXR0cmlidXRlcy4gSWYgdGhlIG9wZXJhdGlvbiBpcyBub3Qgb3ZlcnJpZGRlbiBieQorICAvLy8gdGhlIGZ1bmN0aW9uJ3MgYXR0cmlidXRlcywgIlVuc3BlY2lmaWVkIiBpcyByZXR1cm5lZCBhbmQgdGFyZ2V0IGRlZmF1bHRzCisgIC8vLyBhcmUgZXhwZWN0ZWQgdG8gYmUgdXNlZCBmb3IgaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uLgorICBpbnQgZ2V0U3FydFJlZmluZW1lbnRTdGVwcyhFVlQgVlQsIE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdGhlIHJlZmluZW1lbnQgc3RlcCBjb3VudCBmb3IgYSBkaXZpc2lvbiBvZiB0aGUgZ2l2ZW4gdHlwZSBiYXNlZAorICAvLy8gb24gdGhlIGZ1bmN0aW9uJ3MgYXR0cmlidXRlcy4gSWYgdGhlIG9wZXJhdGlvbiBpcyBub3Qgb3ZlcnJpZGRlbiBieQorICAvLy8gdGhlIGZ1bmN0aW9uJ3MgYXR0cmlidXRlcywgIlVuc3BlY2lmaWVkIiBpcyByZXR1cm5lZCBhbmQgdGFyZ2V0IGRlZmF1bHRzCisgIC8vLyBhcmUgZXhwZWN0ZWQgdG8gYmUgdXNlZCBmb3IgaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uLgorICBpbnQgZ2V0RGl2UmVmaW5lbWVudFN0ZXBzKEVWVCBWVCwgTWFjaGluZUZ1bmN0aW9uICZNRikgY29uc3Q7CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0YXJnZXQgaGFzIGluZGljYXRlZCBhdCBsZWFzdCBvbmUgdHlwZSBzaG91bGQgYmUgYnlwYXNzZWQuCisgIGJvb2wgaXNTbG93RGl2QnlwYXNzZWQoKSBjb25zdCB7IHJldHVybiAhQnlwYXNzU2xvd0RpdldpZHRocy5lbXB0eSgpOyB9CisKKyAgLy8vIFJldHVybnMgbWFwIG9mIHNsb3cgdHlwZXMgZm9yIGRpdmlzaW9uIG9yIHJlbWFpbmRlciB3aXRoIGNvcnJlc3BvbmRpbmcKKyAgLy8vIGZhc3QgdHlwZXMKKyAgY29uc3QgRGVuc2VNYXA8dW5zaWduZWQgaW50LCB1bnNpZ25lZCBpbnQ+ICZnZXRCeXBhc3NTbG93RGl2V2lkdGhzKCkgY29uc3QgeworICAgIHJldHVybiBCeXBhc3NTbG93RGl2V2lkdGhzOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIEZsb3cgQ29udHJvbCBpcyBhbiBleHBlbnNpdmUgb3BlcmF0aW9uIHRoYXQgc2hvdWxkIGJlCisgIC8vLyBhdm9pZGVkLgorICBib29sIGlzSnVtcEV4cGVuc2l2ZSgpIGNvbnN0IHsgcmV0dXJuIEp1bXBJc0V4cGVuc2l2ZTsgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBzZWxlY3RzIGFyZSBvbmx5IGNoZWFwZXIgdGhhbiBicmFuY2hlcyBpZiB0aGUgYnJhbmNoIGlzCisgIC8vLyB1bmxpa2VseSB0byBiZSBwcmVkaWN0ZWQgcmlnaHQuCisgIGJvb2wgaXNQcmVkaWN0YWJsZVNlbGVjdEV4cGVuc2l2ZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gUHJlZGljdGFibGVTZWxlY3RJc0V4cGVuc2l2ZTsKKyAgfQorCisgIC8vLyBJZiBhIGJyYW5jaCBvciBhIHNlbGVjdCBjb25kaXRpb24gaXMgc2tld2VkIGluIG9uZSBkaXJlY3Rpb24gYnkgbW9yZSB0aGFuCisgIC8vLyB0aGlzIGZhY3RvciwgaXQgaXMgdmVyeSBsaWtlbHkgdG8gYmUgcHJlZGljdGVkIGNvcnJlY3RseS4KKyAgdmlydHVhbCBCcmFuY2hQcm9iYWJpbGl0eSBnZXRQcmVkaWN0YWJsZUJyYW5jaFRocmVzaG9sZCgpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgZm9sbG93aW5nIHRyYW5zZm9ybSBpcyBiZW5lZmljaWFsOgorICAvLy8gZm9sZCAoY29udiAobG9hZCB4KSkgLT4gKGxvYWQgKGNvbnYqKXgpCisgIC8vLyBPbiBhcmNoaXRlY3R1cmVzIHRoYXQgZG9uJ3QgbmF0aXZlbHkgc3VwcG9ydCBzb21lIHZlY3RvciBsb2FkcworICAvLy8gZWZmaWNpZW50bHksIGNhc3RpbmcgdGhlIGxvYWQgdG8gYSBzbWFsbGVyIHZlY3RvciBvZiBsYXJnZXIgdHlwZXMgYW5kCisgIC8vLyBsb2FkaW5nIGlzIG1vcmUgZWZmaWNpZW50LCBob3dldmVyLCB0aGlzIGNhbiBiZSB1bmRvbmUgYnkgb3B0aW1pemF0aW9ucyBpbgorICAvLy8gZGFnIGNvbWJpbmVyLgorICB2aXJ0dWFsIGJvb2wgaXNMb2FkQml0Q2FzdEJlbmVmaWNpYWwoRVZUIExvYWRWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVWVCBCaXRjYXN0VlQpIGNvbnN0IHsKKyAgICAvLyBEb24ndCBkbyBpZiB3ZSBjb3VsZCBkbyBhbiBpbmRleGVkIGxvYWQgb24gdGhlIG9yaWdpbmFsIHR5cGUsIGJ1dCBub3Qgb24KKyAgICAvLyB0aGUgbmV3IG9uZS4KKyAgICBpZiAoIUxvYWRWVC5pc1NpbXBsZSgpIHx8ICFCaXRjYXN0VlQuaXNTaW1wbGUoKSkKKyAgICAgIHJldHVybiB0cnVlOworCisgICAgTVZUIExvYWRNVlQgPSBMb2FkVlQuZ2V0U2ltcGxlVlQoKTsKKworICAgIC8vIERvbid0IGJvdGhlciBkb2luZyB0aGlzIGlmIGl0J3MganVzdCBnb2luZyB0byBiZSBwcm9tb3RlZCBhZ2FpbiBsYXRlciwgYXMKKyAgICAvLyBkb2luZyBzbyBtaWdodCBpbnRlcmZlcmUgd2l0aCBvdGhlciBjb21iaW5lcy4KKyAgICBpZiAoZ2V0T3BlcmF0aW9uQWN0aW9uKElTRDo6TE9BRCwgTG9hZE1WVCkgPT0gUHJvbW90ZSAmJgorICAgICAgICBnZXRUeXBlVG9Qcm9tb3RlVG8oSVNEOjpMT0FELCBMb2FkTVZUKSA9PSBCaXRjYXN0VlQuZ2V0U2ltcGxlVlQoKSkKKyAgICAgIHJldHVybiBmYWxzZTsKKworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBmb2xsb3dpbmcgdHJhbnNmb3JtIGlzIGJlbmVmaWNpYWw6CisgIC8vLyAoc3RvcmUgKHkgKGNvbnYgeCkpLCB5KikpIC0+IChzdG9yZSB4LCAoeCopKQorICB2aXJ0dWFsIGJvb2wgaXNTdG9yZUJpdENhc3RCZW5lZmljaWFsKEVWVCBTdG9yZVZULCBFVlQgQml0Y2FzdFZUKSBjb25zdCB7CisgICAgLy8gRGVmYXVsdCB0byB0aGUgc2FtZSBsb2dpYyBhcyBsb2Fkcy4KKyAgICByZXR1cm4gaXNMb2FkQml0Q2FzdEJlbmVmaWNpYWwoU3RvcmVWVCwgQml0Y2FzdFZUKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBpdCBpcyBleHBlY3RlZCB0byBiZSBjaGVhcGVyIHRvIGRvIGEgc3RvcmUgb2YgYSBub24temVybworICAvLy8gdmVjdG9yIGNvbnN0YW50IHdpdGggdGhlIGdpdmVuIHNpemUgYW5kIHR5cGUgZm9yIHRoZSBhZGRyZXNzIHNwYWNlIHRoYW4gdG8KKyAgLy8vIHN0b3JlIHRoZSBpbmRpdmlkdWFsIHNjYWxhciBlbGVtZW50IGNvbnN0YW50cy4KKyAgdmlydHVhbCBib29sIHN0b3JlT2ZWZWN0b3JDb25zdGFudElzQ2hlYXAoRVZUIE1lbVZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBOdW1FbGVtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBBZGRyU3BhY2UpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gQWxsb3cgc3RvcmUgbWVyZ2luZyBhZnRlciBsZWdhbGl6YXRpb24gaW4gYWRkaXRpb24gdG8gYmVmb3JlIGxlZ2FsaXphdGlvbi4KKyAgLy8vIFRoaXMgbWF5IGNhdGNoIHN0b3JlcyB0aGF0IGRvIG5vdCBleGlzdCBlYXJsaWVyIChlZywgc3RvcmVzIGNyZWF0ZWQgZnJvbQorICAvLy8gaW50cmluc2ljcykuCisgIHZpcnR1YWwgYm9vbCBtZXJnZVN0b3Jlc0FmdGVyTGVnYWxpemF0aW9uKCkgY29uc3QgeyByZXR1cm4gdHJ1ZTsgfQorCisgIC8vLyBSZXR1cm5zIGlmIGl0J3MgcmVhc29uYWJsZSB0byBtZXJnZSBzdG9yZXMgdG8gTWVtVlQgc2l6ZS4KKyAgdmlydHVhbCBib29sIGNhbk1lcmdlU3RvcmVzVG8odW5zaWduZWQgQVMsIEVWVCBNZW1WVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2VsZWN0aW9uREFHICZEQUcpIGNvbnN0IHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vLyBcYnJpZWYgUmV0dXJuIHRydWUgaWYgaXQgaXMgY2hlYXAgdG8gc3BlY3VsYXRlIGEgY2FsbCB0byBpbnRyaW5zaWMgY3R0ei4KKyAgdmlydHVhbCBib29sIGlzQ2hlYXBUb1NwZWN1bGF0ZUN0dHooKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFxicmllZiBSZXR1cm4gdHJ1ZSBpZiBpdCBpcyBjaGVhcCB0byBzcGVjdWxhdGUgYSBjYWxsIHRvIGludHJpbnNpYyBjdGx6LgorICB2aXJ0dWFsIGJvb2wgaXNDaGVhcFRvU3BlY3VsYXRlQ3RseigpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gXGJyaWVmIFJldHVybiB0cnVlIGlmIGN0bHogaW5zdHJ1Y3Rpb24gaXMgZmFzdC4KKyAgdmlydHVhbCBib29sIGlzQ3RsekZhc3QoKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGl0IGlzIHNhZmUgdG8gdHJhbnNmb3JtIGFuIGludGVnZXItZG9tYWluIGJpdHdpc2Ugb3BlcmF0aW9uCisgIC8vLyBpbnRvIHRoZSBlcXVpdmFsZW50IGZsb2F0aW5nLXBvaW50IG9wZXJhdGlvbi4gVGhpcyBzaG91bGQgYmUgc2V0IHRvIHRydWUKKyAgLy8vIGlmIHRoZSB0YXJnZXQgaGFzIElFRUUtNzU0LWNvbXBsaWFudCBmYWJzL2ZuZWcgb3BlcmF0aW9ucyBmb3IgdGhlIGlucHV0CisgIC8vLyB0eXBlLgorICB2aXJ0dWFsIGJvb2wgaGFzQml0UHJlc2VydmluZ0ZQTG9naWMoRVZUIFZUKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFxicmllZiBSZXR1cm4gdHJ1ZSBpZiBpdCBpcyBjaGVhcGVyIHRvIHNwbGl0IHRoZSBzdG9yZSBvZiBhIG1lcmdlZCBpbnQgdmFsCisgIC8vLyBmcm9tIGEgcGFpciBvZiBzbWFsbGVyIHZhbHVlcyBpbnRvIG11bHRpcGxlIHN0b3Jlcy4KKyAgdmlydHVhbCBib29sIGlzTXVsdGlTdG9yZXNDaGVhcGVyVGhhbkJpdHNNZXJnZShFVlQgTFR5LCBFVlQgSFR5KSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFxicmllZiBSZXR1cm4gaWYgdGhlIHRhcmdldCBzdXBwb3J0cyBjb21iaW5pbmcgYQorICAvLy8gY2hhaW4gbGlrZToKKyAgLy8vIFxjb2RlCisgIC8vLyAgICVhbmRSZXN1bHQgPSBhbmQgJXZhbDEsICNtYXNrCisgIC8vLyAgICVpY21wUmVzdWx0ID0gaWNtcCAlYW5kUmVzdWx0LCAwCisgIC8vLyBcZW5kY29kZQorICAvLy8gaW50byBhIHNpbmdsZSBtYWNoaW5lIGluc3RydWN0aW9uIG9mIGEgZm9ybSBsaWtlOgorICAvLy8gXGNvZGUKKyAgLy8vICAgY2MgPSB0ZXN0ICVyZWdpc3RlciwgI21hc2sKKyAgLy8vIFxlbmRjb2RlCisgIHZpcnR1YWwgYm9vbCBpc01hc2tBbmRDbXAwRm9sZGluZ0JlbmVmaWNpYWwoY29uc3QgSW5zdHJ1Y3Rpb24gJkFuZEkpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gVXNlIGJpdHdpc2UgbG9naWMgdG8gbWFrZSBwYWlycyBvZiBjb21wYXJlcyBtb3JlIGVmZmljaWVudC4gRm9yIGV4YW1wbGU6CisgIC8vLyBhbmQgKHNldGVxIEEsIEIpLCAoc2V0ZXEgQywgRCkgLS0+IHNldGVxIChvciAoeG9yIEEsIEIpLCAoeG9yIEMsIEQpKSwgMAorICAvLy8gVGhpcyBzaG91bGQgYmUgdHJ1ZSB3aGVuIGl0IHRha2VzIG1vcmUgdGhhbiBvbmUgaW5zdHJ1Y3Rpb24gdG8gbG93ZXIKKyAgLy8vIHNldGNjIChjbXArc2V0IG9uIHg4NiBzY2FsYXIpLCB3aGVuIGJpdHdpc2Ugb3BzIGFyZSBmYXN0ZXIgdGhhbiBsb2dpYyBvbgorICAvLy8gY29uZGl0aW9uIGJpdHMgKGNyYW5kIG9uIFBvd2VyUEMpLCBhbmQvb3Igd2hlbiByZWR1Y2luZyBjbXArYnIgaXMgYSB3aW4uCisgIHZpcnR1YWwgYm9vbCBjb252ZXJ0U2V0Q0NMb2dpY1RvQml0d2lzZUxvZ2ljKEVWVCBWVCkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIHByZWZlcnJlZCBvcGVyYW5kIHR5cGUgaWYgdGhlIHRhcmdldCBoYXMgYSBxdWljayB3YXkgdG8gY29tcGFyZQorICAvLy8gaW50ZWdlciB2YWx1ZXMgb2YgdGhlIGdpdmVuIHNpemUuIEFzc3VtZSB0aGF0IGFueSBsZWdhbCBpbnRlZ2VyIHR5cGUgY2FuCisgIC8vLyBiZSBjb21wYXJlZCBlZmZpY2llbnRseS4gVGFyZ2V0cyBtYXkgb3ZlcnJpZGUgdGhpcyB0byBhbGxvdyBpbGxlZ2FsIHdpZGUKKyAgLy8vIHR5cGVzIHRvIHJldHVybiBhIHZlY3RvciB0eXBlIGlmIHRoZXJlIGlzIHN1cHBvcnQgdG8gY29tcGFyZSB0aGF0IHR5cGUuCisgIHZpcnR1YWwgTVZUIGhhc0Zhc3RFcXVhbGl0eUNvbXBhcmUodW5zaWduZWQgTnVtQml0cykgY29uc3QgeworICAgIE1WVCBWVCA9IE1WVDo6Z2V0SW50ZWdlclZUKE51bUJpdHMpOworICAgIHJldHVybiBpc1R5cGVMZWdhbChWVCkgPyBWVCA6IE1WVDo6SU5WQUxJRF9TSU1QTEVfVkFMVUVfVFlQRTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgdGFyZ2V0IHNob3VsZCB0cmFuc2Zvcm06CisgIC8vLyAoWCAmIFkpID09IFkgLS0tPiAoflggJiBZKSA9PSAwCisgIC8vLyAoWCAmIFkpICE9IFkgLS0tPiAoflggJiBZKSAhPSAwCisgIC8vLworICAvLy8gVGhpcyBtYXkgYmUgcHJvZml0YWJsZSBpZiB0aGUgdGFyZ2V0IGhhcyBhIGJpdHdpc2UgYW5kLW5vdCBvcGVyYXRpb24gdGhhdAorICAvLy8gc2V0cyBjb21wYXJpc29uIGZsYWdzLiBBIHRhcmdldCBtYXkgd2FudCB0byBsaW1pdCB0aGUgdHJhbnNmb3JtYXRpb24gYmFzZWQKKyAgLy8vIG9uIHRoZSB0eXBlIG9mIFkgb3IgaWYgWSBpcyBhIGNvbnN0YW50LgorICAvLy8KKyAgLy8vIE5vdGUgdGhhdCB0aGUgdHJhbnNmb3JtIHdpbGwgbm90IG9jY3VyIGlmIFkgaXMga25vd24gdG8gYmUgYSBwb3dlci1vZi0yCisgIC8vLyBiZWNhdXNlIGEgbWFzayBhbmQgY29tcGFyZSBvZiBhIHNpbmdsZSBiaXQgY2FuIGJlIGhhbmRsZWQgYnkgaW52ZXJ0aW5nIHRoZQorICAvLy8gcHJlZGljYXRlLCBmb3IgZXhhbXBsZToKKyAgLy8vIChYICYgOCkgPT0gOCAtLS0+IChYICYgOCkgIT0gMAorICB2aXJ0dWFsIGJvb2wgaGFzQW5kTm90Q29tcGFyZShTRFZhbHVlIFkpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHRhcmdldCBoYXMgYSBiaXR3aXNlIGFuZC1ub3Qgb3BlcmF0aW9uOgorICAvLy8gWCA9IH5BICYgQgorICAvLy8gVGhpcyBjYW4gYmUgdXNlZCB0byBzaW1wbGlmeSBzZWxlY3Qgb3Igb3RoZXIgaW5zdHJ1Y3Rpb25zLgorICB2aXJ0dWFsIGJvb2wgaGFzQW5kTm90KFNEVmFsdWUgWCkgY29uc3QgeworICAgIC8vIElmIHRoZSB0YXJnZXQgaGFzIHRoZSBtb3JlIGNvbXBsZXggdmVyc2lvbiBvZiB0aGlzIG9wZXJhdGlvbiwgYXNzdW1lIHRoYXQKKyAgICAvLyBpdCBoYXMgdGhpcyBvcGVyYXRpb24gdG9vLgorICAgIHJldHVybiBoYXNBbmROb3RDb21wYXJlKFgpOworICB9CisKKyAgLy8vIFxicmllZiBSZXR1cm4gdHJ1ZSBpZiB0aGUgdGFyZ2V0IHdhbnRzIHRvIHVzZSB0aGUgb3B0aW1pemF0aW9uIHRoYXQKKyAgLy8vIHR1cm5zIGV4dChwcm9tb3RhYmxlSW5zdDEoLi4uKHByb21vdGFibGVJbnN0Tihsb2FkKSkpKSBpbnRvCisgIC8vLyBwcm9tb3RlZEluc3QxKC4uLihwcm9tb3RlZEluc3ROKGV4dChsb2FkKSkpKS4KKyAgYm9vbCBlbmFibGVFeHRMZFByb21vdGlvbigpIGNvbnN0IHsgcmV0dXJuIEVuYWJsZUV4dExkUHJvbW90aW9uOyB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSB0YXJnZXQgY2FuIGNvbWJpbmUgc3RvcmUoZXh0cmFjdGVsZW1lbnQgVmVjdG9yVHksCisgIC8vLyBJZHgpLgorICAvLy8gXHAgQ29zdFtvdXRdIGdpdmVzIHRoZSBjb3N0IG9mIHRoYXQgdHJhbnNmb3JtYXRpb24gd2hlbiB0aGlzIGlzIHRydWUuCisgIHZpcnR1YWwgYm9vbCBjYW5Db21iaW5lU3RvcmVBbmRFeHRyYWN0KFR5cGUgKlZlY3RvclR5LCBWYWx1ZSAqSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCAmQ29zdCkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0YXJnZXQgc3VwcG9ydHMgZmxvYXRpbmcgcG9pbnQgZXhjZXB0aW9ucy4KKyAgYm9vbCBoYXNGbG9hdGluZ1BvaW50RXhjZXB0aW9ucygpIGNvbnN0IHsKKyAgICByZXR1cm4gSGFzRmxvYXRpbmdQb2ludEV4Y2VwdGlvbnM7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGFyZ2V0IGFsd2F5cyBiZW5lZmljaWF0ZXMgZnJvbSBjb21iaW5pbmcgaW50byBGTUEgZm9yIGEKKyAgLy8vIGdpdmVuIHZhbHVlIHR5cGUuIFRoaXMgbXVzdCB0eXBpY2FsbHkgcmV0dXJuIGZhbHNlIG9uIHRhcmdldHMgd2hlcmUgRk1BCisgIC8vLyB0YWtlcyBtb3JlIGN5Y2xlcyB0byBleGVjdXRlIHRoYW4gRkFERC4KKyAgdmlydHVhbCBib29sIGVuYWJsZUFnZ3Jlc3NpdmVGTUFGdXNpb24oRVZUIFZUKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgVmFsdWVUeXBlIG9mIHRoZSByZXN1bHQgb2YgU0VUQ0Mgb3BlcmF0aW9ucy4KKyAgdmlydHVhbCBFVlQgZ2V0U2V0Q0NSZXN1bHRUeXBlKGNvbnN0IERhdGFMYXlvdXQgJkRMLCBMTFZNQ29udGV4dCAmQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVWVCBWVCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0aGUgVmFsdWVUeXBlIGZvciBjb21wYXJpc29uIGxpYmNhbGxzLiBDb21wYXJpb25zIGxpYmNhbGxzIGluY2x1ZGUKKyAgLy8vIGZsb2F0aW5nIHBvaW50IGNvbXBhcmlvbiBjYWxscywgYW5kIE9yZGVyZWQvVW5vcmRlcmVkIGNoZWNrIGNhbGxzIG9uCisgIC8vLyBmbG9hdGluZyBwb2ludCBudW1iZXJzLgorICB2aXJ0dWFsCisgIE1WVDo6U2ltcGxlVmFsdWVUeXBlIGdldENtcExpYmNhbGxSZXR1cm5UeXBlKCkgY29uc3Q7CisKKyAgLy8vIEZvciB0YXJnZXRzIHdpdGhvdXQgaTEgcmVnaXN0ZXJzLCB0aGlzIGdpdmVzIHRoZSBuYXR1cmUgb2YgdGhlIGhpZ2gtYml0cworICAvLy8gb2YgYm9vbGVhbiB2YWx1ZXMgaGVsZCBpbiB0eXBlcyB3aWRlciB0aGFuIGkxLgorICAvLy8KKyAgLy8vICJCb29sZWFuIHZhbHVlcyIgYXJlIHNwZWNpYWwgdHJ1ZS9mYWxzZSB2YWx1ZXMgcHJvZHVjZWQgYnkgbm9kZXMgbGlrZQorICAvLy8gU0VUQ0MgYW5kIGNvbnN1bWVkIChhcyB0aGUgY29uZGl0aW9uKSBieSBub2RlcyBsaWtlIFNFTEVDVCBhbmQgQlJDT05ELgorICAvLy8gTm90IHRvIGJlIGNvbmZ1c2VkIHdpdGggZ2VuZXJhbCB2YWx1ZXMgcHJvbW90ZWQgZnJvbSBpMS4gIFNvbWUgY3B1cworICAvLy8gZGlzdGluZ3Vpc2ggYmV0d2VlbiB2ZWN0b3JzIG9mIGJvb2xlYW4gYW5kIHNjYWxhcnM7IHRoZSBpc1ZlYyBwYXJhbWV0ZXIKKyAgLy8vIHNlbGVjdHMgYmV0d2VlbiB0aGUgdHdvIGtpbmRzLiAgRm9yIGV4YW1wbGUgb24gWDg2IGEgc2NhbGFyIGJvb2xlYW4gc2hvdWxkCisgIC8vLyBiZSB6ZXJvIGV4dGVuZGVkIGZyb20gaTEsIHdoaWxlIHRoZSBlbGVtZW50cyBvZiBhIHZlY3RvciBvZiBib29sZWFucworICAvLy8gc2hvdWxkIGJlIHNpZ24gZXh0ZW5kZWQgZnJvbSBpMS4KKyAgLy8vCisgIC8vLyBTb21lIGNwdXMgYWxzbyB0cmVhdCBmbG9hdGluZyBwb2ludCB0eXBlcyB0aGUgc2FtZSB3YXkgYXMgdGhleSB0cmVhdAorICAvLy8gdmVjdG9ycyBpbnN0ZWFkIG9mIHRoZSB3YXkgdGhleSB0cmVhdCBzY2FsYXJzLgorICBCb29sZWFuQ29udGVudCBnZXRCb29sZWFuQ29udGVudHMoYm9vbCBpc1ZlYywgYm9vbCBpc0Zsb2F0KSBjb25zdCB7CisgICAgaWYgKGlzVmVjKQorICAgICAgcmV0dXJuIEJvb2xlYW5WZWN0b3JDb250ZW50czsKKyAgICByZXR1cm4gaXNGbG9hdCA/IEJvb2xlYW5GbG9hdENvbnRlbnRzIDogQm9vbGVhbkNvbnRlbnRzOworICB9CisKKyAgQm9vbGVhbkNvbnRlbnQgZ2V0Qm9vbGVhbkNvbnRlbnRzKEVWVCBUeXBlKSBjb25zdCB7CisgICAgcmV0dXJuIGdldEJvb2xlYW5Db250ZW50cyhUeXBlLmlzVmVjdG9yKCksIFR5cGUuaXNGbG9hdGluZ1BvaW50KCkpOworICB9CisKKyAgLy8vIFJldHVybiB0YXJnZXQgc2NoZWR1bGluZyBwcmVmZXJlbmNlLgorICBTY2hlZDo6UHJlZmVyZW5jZSBnZXRTY2hlZHVsaW5nUHJlZmVyZW5jZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gU2NoZWRQcmVmZXJlbmNlSW5mbzsKKyAgfQorCisgIC8vLyBTb21lIHNjaGVkdWxlciwgZS5nLiBoeWJyaWQsIGNhbiBzd2l0Y2ggdG8gZGlmZmVyZW50IHNjaGVkdWxpbmcgaGV1cmlzdGljcworICAvLy8gZm9yIGRpZmZlcmVudCBub2Rlcy4gVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBwcmVmZXJlbmNlIChvciBub25lKSBmb3IKKyAgLy8vIHRoZSBnaXZlbiBub2RlLgorICB2aXJ0dWFsIFNjaGVkOjpQcmVmZXJlbmNlIGdldFNjaGVkdWxpbmdQcmVmZXJlbmNlKFNETm9kZSAqKSBjb25zdCB7CisgICAgcmV0dXJuIFNjaGVkOjpOb25lOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgcmVnaXN0ZXIgY2xhc3MgdGhhdCBzaG91bGQgYmUgdXNlZCBmb3IgdGhlIHNwZWNpZmllZCB2YWx1ZQorICAvLy8gdHlwZS4KKyAgdmlydHVhbCBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpnZXRSZWdDbGFzc0ZvcihNVlQgVlQpIGNvbnN0IHsKKyAgICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQyA9IFJlZ0NsYXNzRm9yVlRbVlQuU2ltcGxlVHldOworICAgIGFzc2VydChSQyAmJiAiVGhpcyB2YWx1ZSB0eXBlIGlzIG5vdCBuYXRpdmVseSBzdXBwb3J0ZWQhIik7CisgICAgcmV0dXJuIFJDOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgJ3JlcHJlc2VudGF0aXZlJyByZWdpc3RlciBjbGFzcyBmb3IgdGhlIHNwZWNpZmllZCB2YWx1ZQorICAvLy8gdHlwZS4KKyAgLy8vCisgIC8vLyBUaGUgJ3JlcHJlc2VudGF0aXZlJyByZWdpc3RlciBjbGFzcyBpcyB0aGUgbGFyZ2VzdCBsZWdhbCBzdXBlci1yZWcKKyAgLy8vIHJlZ2lzdGVyIGNsYXNzIGZvciB0aGUgcmVnaXN0ZXIgY2xhc3Mgb2YgdGhlIHZhbHVlIHR5cGUuICBGb3IgZXhhbXBsZSwgb24KKyAgLy8vIGkzODYgdGhlIHJlcCByZWdpc3RlciBjbGFzcyBmb3IgaTgsIGkxNiwgYW5kIGkzMiBhcmUgR1IzMjsgd2hpbGUgdGhlIHJlcAorICAvLy8gcmVnaXN0ZXIgY2xhc3MgaXMgR1I2NCBvbiB4ODZfNjQuCisgIHZpcnR1YWwgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqZ2V0UmVwUmVnQ2xhc3NGb3IoTVZUIFZUKSBjb25zdCB7CisgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUkMgPSBSZXBSZWdDbGFzc0ZvclZUW1ZULlNpbXBsZVR5XTsKKyAgICByZXR1cm4gUkM7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBjb3N0IG9mIHRoZSAncmVwcmVzZW50YXRpdmUnIHJlZ2lzdGVyIGNsYXNzIGZvciB0aGUgc3BlY2lmaWVkCisgIC8vLyB2YWx1ZSB0eXBlLgorICB2aXJ0dWFsIHVpbnQ4X3QgZ2V0UmVwUmVnQ2xhc3NDb3N0Rm9yKE1WVCBWVCkgY29uc3QgeworICAgIHJldHVybiBSZXBSZWdDbGFzc0Nvc3RGb3JWVFtWVC5TaW1wbGVUeV07CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHRhcmdldCBoYXMgbmF0aXZlIHN1cHBvcnQgZm9yIHRoZSBzcGVjaWZpZWQgdmFsdWUgdHlwZS4KKyAgLy8vIFRoaXMgbWVhbnMgdGhhdCBpdCBoYXMgYSByZWdpc3RlciB0aGF0IGRpcmVjdGx5IGhvbGRzIGl0IHdpdGhvdXQKKyAgLy8vIHByb21vdGlvbnMgb3IgZXhwYW5zaW9ucy4KKyAgYm9vbCBpc1R5cGVMZWdhbChFVlQgVlQpIGNvbnN0IHsKKyAgICBhc3NlcnQoIVZULmlzU2ltcGxlKCkgfHwKKyAgICAgICAgICAgKHVuc2lnbmVkKVZULmdldFNpbXBsZVZUKCkuU2ltcGxlVHkgPCBhcnJheV9sZW5ndGhvZihSZWdDbGFzc0ZvclZUKSk7CisgICAgcmV0dXJuIFZULmlzU2ltcGxlKCkgJiYgUmVnQ2xhc3NGb3JWVFtWVC5nZXRTaW1wbGVWVCgpLlNpbXBsZVR5XSAhPSBudWxscHRyOworICB9CisKKyAgY2xhc3MgVmFsdWVUeXBlQWN0aW9uSW1wbCB7CisgICAgLy8vIFZhbHVlVHlwZUFjdGlvbnMgLSBGb3IgZWFjaCB2YWx1ZSB0eXBlLCBrZWVwIGEgTGVnYWxpemVUeXBlQWN0aW9uIGVudW0KKyAgICAvLy8gdGhhdCBpbmRpY2F0ZXMgaG93IGluc3RydWN0aW9uIHNlbGVjdGlvbiBzaG91bGQgZGVhbCB3aXRoIHRoZSB0eXBlLgorICAgIExlZ2FsaXplVHlwZUFjdGlvbiBWYWx1ZVR5cGVBY3Rpb25zW01WVDo6TEFTVF9WQUxVRVRZUEVdOworCisgIHB1YmxpYzoKKyAgICBWYWx1ZVR5cGVBY3Rpb25JbXBsKCkgeworICAgICAgc3RkOjpmaWxsKHN0ZDo6YmVnaW4oVmFsdWVUeXBlQWN0aW9ucyksIHN0ZDo6ZW5kKFZhbHVlVHlwZUFjdGlvbnMpLAorICAgICAgICAgICAgICAgIFR5cGVMZWdhbCk7CisgICAgfQorCisgICAgTGVnYWxpemVUeXBlQWN0aW9uIGdldFR5cGVBY3Rpb24oTVZUIFZUKSBjb25zdCB7CisgICAgICByZXR1cm4gVmFsdWVUeXBlQWN0aW9uc1tWVC5TaW1wbGVUeV07CisgICAgfQorCisgICAgdm9pZCBzZXRUeXBlQWN0aW9uKE1WVCBWVCwgTGVnYWxpemVUeXBlQWN0aW9uIEFjdGlvbikgeworICAgICAgVmFsdWVUeXBlQWN0aW9uc1tWVC5TaW1wbGVUeV0gPSBBY3Rpb247CisgICAgfQorICB9OworCisgIGNvbnN0IFZhbHVlVHlwZUFjdGlvbkltcGwgJmdldFZhbHVlVHlwZUFjdGlvbnMoKSBjb25zdCB7CisgICAgcmV0dXJuIFZhbHVlVHlwZUFjdGlvbnM7CisgIH0KKworICAvLy8gUmV0dXJuIGhvdyB3ZSBzaG91bGQgbGVnYWxpemUgdmFsdWVzIG9mIHRoaXMgdHlwZSwgZWl0aGVyIGl0IGlzIGFscmVhZHkKKyAgLy8vIGxlZ2FsIChyZXR1cm4gJ0xlZ2FsJykgb3Igd2UgbmVlZCB0byBwcm9tb3RlIGl0IHRvIGEgbGFyZ2VyIHR5cGUgKHJldHVybgorICAvLy8gJ1Byb21vdGUnKSwgb3Igd2UgbmVlZCB0byBleHBhbmQgaXQgaW50byBtdWx0aXBsZSByZWdpc3RlcnMgb2Ygc21hbGxlcgorICAvLy8gaW50ZWdlciB0eXBlIChyZXR1cm4gJ0V4cGFuZCcpLiAgJ0N1c3RvbScgaXMgbm90IGFuIG9wdGlvbi4KKyAgTGVnYWxpemVUeXBlQWN0aW9uIGdldFR5cGVBY3Rpb24oTExWTUNvbnRleHQgJkNvbnRleHQsIEVWVCBWVCkgY29uc3QgeworICAgIHJldHVybiBnZXRUeXBlQ29udmVyc2lvbihDb250ZXh0LCBWVCkuZmlyc3Q7CisgIH0KKyAgTGVnYWxpemVUeXBlQWN0aW9uIGdldFR5cGVBY3Rpb24oTVZUIFZUKSBjb25zdCB7CisgICAgcmV0dXJuIFZhbHVlVHlwZUFjdGlvbnMuZ2V0VHlwZUFjdGlvbihWVCk7CisgIH0KKworICAvLy8gRm9yIHR5cGVzIHN1cHBvcnRlZCBieSB0aGUgdGFyZ2V0LCB0aGlzIGlzIGFuIGlkZW50aXR5IGZ1bmN0aW9uLiAgRm9yCisgIC8vLyB0eXBlcyB0aGF0IG11c3QgYmUgcHJvbW90ZWQgdG8gbGFyZ2VyIHR5cGVzLCB0aGlzIHJldHVybnMgdGhlIGxhcmdlciB0eXBlCisgIC8vLyB0byBwcm9tb3RlIHRvLiAgRm9yIGludGVnZXIgdHlwZXMgdGhhdCBhcmUgbGFyZ2VyIHRoYW4gdGhlIGxhcmdlc3QgaW50ZWdlcgorICAvLy8gcmVnaXN0ZXIsIHRoaXMgY29udGFpbnMgb25lIHN0ZXAgaW4gdGhlIGV4cGFuc2lvbiB0byBnZXQgdG8gdGhlIHNtYWxsZXIKKyAgLy8vIHJlZ2lzdGVyLiBGb3IgaWxsZWdhbCBmbG9hdGluZyBwb2ludCB0eXBlcywgdGhpcyByZXR1cm5zIHRoZSBpbnRlZ2VyIHR5cGUKKyAgLy8vIHRvIHRyYW5zZm9ybSB0by4KKyAgRVZUIGdldFR5cGVUb1RyYW5zZm9ybVRvKExMVk1Db250ZXh0ICZDb250ZXh0LCBFVlQgVlQpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0VHlwZUNvbnZlcnNpb24oQ29udGV4dCwgVlQpLnNlY29uZDsKKyAgfQorCisgIC8vLyBGb3IgdHlwZXMgc3VwcG9ydGVkIGJ5IHRoZSB0YXJnZXQsIHRoaXMgaXMgYW4gaWRlbnRpdHkgZnVuY3Rpb24uICBGb3IKKyAgLy8vIHR5cGVzIHRoYXQgbXVzdCBiZSBleHBhbmRlZCAoaS5lLiBpbnRlZ2VyIHR5cGVzIHRoYXQgYXJlIGxhcmdlciB0aGFuIHRoZQorICAvLy8gbGFyZ2VzdCBpbnRlZ2VyIHJlZ2lzdGVyIG9yIGlsbGVnYWwgZmxvYXRpbmcgcG9pbnQgdHlwZXMpLCB0aGlzIHJldHVybnMKKyAgLy8vIHRoZSBsYXJnZXN0IGxlZ2FsIHR5cGUgaXQgd2lsbCBiZSBleHBhbmRlZCB0by4KKyAgRVZUIGdldFR5cGVUb0V4cGFuZFRvKExMVk1Db250ZXh0ICZDb250ZXh0LCBFVlQgVlQpIGNvbnN0IHsKKyAgICBhc3NlcnQoIVZULmlzVmVjdG9yKCkpOworICAgIHdoaWxlICh0cnVlKSB7CisgICAgICBzd2l0Y2ggKGdldFR5cGVBY3Rpb24oQ29udGV4dCwgVlQpKSB7CisgICAgICBjYXNlIFR5cGVMZWdhbDoKKyAgICAgICAgcmV0dXJuIFZUOworICAgICAgY2FzZSBUeXBlRXhwYW5kSW50ZWdlcjoKKyAgICAgICAgVlQgPSBnZXRUeXBlVG9UcmFuc2Zvcm1UbyhDb250ZXh0LCBWVCk7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgbGx2bV91bnJlYWNoYWJsZSgiVHlwZSBpcyBub3QgbGVnYWwgbm9yIGlzIGl0IHRvIGJlIGV4cGFuZGVkISIpOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vLyBWZWN0b3IgdHlwZXMgYXJlIGJyb2tlbiBkb3duIGludG8gc29tZSBudW1iZXIgb2YgbGVnYWwgZmlyc3QgY2xhc3MgdHlwZXMuCisgIC8vLyBGb3IgZXhhbXBsZSwgRVZUOjp2OGYzMiBtYXBzIHRvIDIgRVZUOjp2NGYzMiB3aXRoIEFsdGl2ZWMgb3IgU1NFMSwgb3IgOAorICAvLy8gcHJvbW90ZWQgRVZUOjpmNjQgdmFsdWVzIHdpdGggdGhlIFg4NiBGUCBzdGFjay4gIFNpbWlsYXJseSwgRVZUOjp2Mmk2NAorICAvLy8gdHVybnMgaW50byA0IEVWVDo6aTMyIHZhbHVlcyB3aXRoIGJvdGggUFBDIGFuZCBYODYuCisgIC8vLworICAvLy8gVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgbnVtYmVyIG9mIHJlZ2lzdGVycyBuZWVkZWQsIGFuZCB0aGUgVlQgZm9yIGVhY2gKKyAgLy8vIHJlZ2lzdGVyLiAgSXQgYWxzbyByZXR1cm5zIHRoZSBWVCBhbmQgcXVhbnRpdHkgb2YgdGhlIGludGVybWVkaWF0ZSB2YWx1ZXMKKyAgLy8vIGJlZm9yZSB0aGV5IGFyZSBwcm9tb3RlZC9leHBhbmRlZC4KKyAgdW5zaWduZWQgZ2V0VmVjdG9yVHlwZUJyZWFrZG93bihMTFZNQ29udGV4dCAmQ29udGV4dCwgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVWVCAmSW50ZXJtZWRpYXRlVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgJk51bUludGVybWVkaWF0ZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTVZUICZSZWdpc3RlclZUKSBjb25zdDsKKworICAvLy8gQ2VydGFpbiB0YXJnZXRzIHN1Y2ggYXMgTUlQUyByZXF1aXJlIHRoYXQgc29tZSB0eXBlcyBzdWNoIGFzIHZlY3RvcnMgYXJlCisgIC8vLyBhbHdheXMgYnJva2VuIGRvd24gaW50byBzY2FsYXJzIGluIHNvbWUgY29udGV4dHMuIFRoaXMgb2NjdXJzIGV2ZW4gaWYgdGhlCisgIC8vLyB2ZWN0b3IgdHlwZSBpcyBsZWdhbC4KKyAgdmlydHVhbCB1bnNpZ25lZCBnZXRWZWN0b3JUeXBlQnJlYWtkb3duRm9yQ2FsbGluZ0NvbnYoCisgICAgICBMTFZNQ29udGV4dCAmQ29udGV4dCwgRVZUIFZULCBFVlQgJkludGVybWVkaWF0ZVZULAorICAgICAgdW5zaWduZWQgJk51bUludGVybWVkaWF0ZXMsIE1WVCAmUmVnaXN0ZXJWVCkgY29uc3QgeworICAgIHJldHVybiBnZXRWZWN0b3JUeXBlQnJlYWtkb3duKENvbnRleHQsIFZULCBJbnRlcm1lZGlhdGVWVCwgTnVtSW50ZXJtZWRpYXRlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWdpc3RlclZUKTsKKyAgfQorCisgIHN0cnVjdCBJbnRyaW5zaWNJbmZvIHsKKyAgICB1bnNpZ25lZCAgICAgb3BjID0gMDsgICAgICAgICAgLy8gdGFyZ2V0IG9wY29kZQorICAgIEVWVCAgICAgICAgICBtZW1WVDsgICAgICAgICAgICAvLyBtZW1vcnkgVlQKKworICAgIC8vIHZhbHVlIHJlcHJlc2VudGluZyBtZW1vcnkgbG9jYXRpb24KKyAgICBQb2ludGVyVW5pb248Y29uc3QgVmFsdWUgKiwgY29uc3QgUHNldWRvU291cmNlVmFsdWUgKj4gcHRyVmFsOworCisgICAgaW50ICAgICAgICAgIG9mZnNldCA9IDA7ICAgICAgIC8vIG9mZnNldCBvZmYgb2YgcHRyVmFsCisgICAgdW5zaWduZWQgICAgIHNpemUgPSAwOyAgICAgICAgIC8vIHRoZSBzaXplIG9mIHRoZSBtZW1vcnkgbG9jYXRpb24KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gKHRha2VuIGZyb20gbWVtVlQgaWYgemVybykKKyAgICB1bnNpZ25lZCAgICAgYWxpZ24gPSAxOyAgICAgICAgLy8gYWxpZ25tZW50CisKKyAgICBNYWNoaW5lTWVtT3BlcmFuZDo6RmxhZ3MgZmxhZ3MgPSBNYWNoaW5lTWVtT3BlcmFuZDo6TU9Ob25lOworICAgIEludHJpbnNpY0luZm8oKSA9IGRlZmF1bHQ7CisgIH07CisKKyAgLy8vIEdpdmVuIGFuIGludHJpbnNpYywgY2hlY2tzIGlmIG9uIHRoZSB0YXJnZXQgdGhlIGludHJpbnNpYyB3aWxsIG5lZWQgdG8gbWFwCisgIC8vLyB0byBhIE1lbUludHJpbnNpY05vZGUgKHRvdWNoZXMgbWVtb3J5KS4gSWYgdGhpcyBpcyB0aGUgY2FzZSwgaXQgcmV0dXJucworICAvLy8gdHJ1ZSBhbmQgc3RvcmUgdGhlIGludHJpbnNpYyBpbmZvcm1hdGlvbiBpbnRvIHRoZSBJbnRyaW5zaWNJbmZvIHRoYXQgd2FzCisgIC8vLyBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uLgorICB2aXJ0dWFsIGJvb2wgZ2V0VGd0TWVtSW50cmluc2ljKEludHJpbnNpY0luZm8gJiwgY29uc3QgQ2FsbEluc3QgJiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lRnVuY3Rpb24gJiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCAvKkludHJpbnNpYyovKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgdGFyZ2V0IGNhbiBpbnN0cnVjdGlvbiBzZWxlY3QgdGhlIHNwZWNpZmllZCBGUAorICAvLy8gaW1tZWRpYXRlIG5hdGl2ZWx5LiBJZiBmYWxzZSwgdGhlIGxlZ2FsaXplciB3aWxsIG1hdGVyaWFsaXplIHRoZSBGUAorICAvLy8gaW1tZWRpYXRlIGFzIGEgbG9hZCBmcm9tIGEgY29uc3RhbnQgcG9vbC4KKyAgdmlydHVhbCBib29sIGlzRlBJbW1MZWdhbChjb25zdCBBUEZsb2F0ICYvKkltbSovLCBFVlQgLypWVCovKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFRhcmdldHMgY2FuIHVzZSB0aGlzIHRvIGluZGljYXRlIHRoYXQgdGhleSBvbmx5IHN1cHBvcnQgKnNvbWUqCisgIC8vLyBWRUNUT1JfU0hVRkZMRSBvcGVyYXRpb25zLCB0aG9zZSB3aXRoIHNwZWNpZmljIG1hc2tzLiAgQnkgZGVmYXVsdCwgaWYgYQorICAvLy8gdGFyZ2V0IHN1cHBvcnRzIHRoZSBWRUNUT1JfU0hVRkZMRSBub2RlLCBhbGwgbWFzayB2YWx1ZXMgYXJlIGFzc3VtZWQgdG8gYmUKKyAgLy8vIGxlZ2FsLgorICB2aXJ0dWFsIGJvb2wgaXNTaHVmZmxlTWFza0xlZ2FsKEFycmF5UmVmPGludD4gLypNYXNrKi8sIEVWVCAvKlZUKi8pIGNvbnN0IHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIG9wZXJhdGlvbiBjYW4gdHJhcCBmb3IgdGhlIHZhbHVlIHR5cGUuCisgIC8vLworICAvLy8gVlQgbXVzdCBiZSBhIGxlZ2FsIHR5cGUuIEJ5IGRlZmF1bHQsIHdlIG9wdGltaXN0aWNhbGx5IGFzc3VtZSBtb3N0CisgIC8vLyBvcGVyYXRpb25zIGRvbid0IHRyYXAgZXhjZXB0IGZvciBpbnRlZ2VyIGRpdmlkZSBhbmQgcmVtYWluZGVyLgorICB2aXJ0dWFsIGJvb2wgY2FuT3BUcmFwKHVuc2lnbmVkIE9wLCBFVlQgVlQpIGNvbnN0OworCisgIC8vLyBTaW1pbGFyIHRvIGlzU2h1ZmZsZU1hc2tMZWdhbC4gVGhpcyBpcyB1c2VkIGJ5IFRhcmdldHMgY2FuIHVzZSB0aGlzIHRvCisgIC8vLyBpbmRpY2F0ZSBpZiB0aGVyZSBpcyBhIHN1aXRhYmxlIFZFQ1RPUl9TSFVGRkxFIHRoYXQgY2FuIGJlIHVzZWQgdG8gcmVwbGFjZQorICAvLy8gYSBWQU5EIHdpdGggYSBjb25zdGFudCBwb29sIGVudHJ5LgorICB2aXJ0dWFsIGJvb2wgaXNWZWN0b3JDbGVhck1hc2tMZWdhbChjb25zdCBTbWFsbFZlY3RvckltcGw8aW50PiAmLypNYXNrKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVWVCAvKlZUKi8pIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJuIGhvdyB0aGlzIG9wZXJhdGlvbiBzaG91bGQgYmUgdHJlYXRlZDogZWl0aGVyIGl0IGlzIGxlZ2FsLCBuZWVkcyB0bworICAvLy8gYmUgcHJvbW90ZWQgdG8gYSBsYXJnZXIgc2l6ZSwgbmVlZHMgdG8gYmUgZXhwYW5kZWQgdG8gc29tZSBvdGhlciBjb2RlCisgIC8vLyBzZXF1ZW5jZSwgb3IgdGhlIHRhcmdldCBoYXMgYSBjdXN0b20gZXhwYW5kZXIgZm9yIGl0LgorICBMZWdhbGl6ZUFjdGlvbiBnZXRPcGVyYXRpb25BY3Rpb24odW5zaWduZWQgT3AsIEVWVCBWVCkgY29uc3QgeworICAgIGlmIChWVC5pc0V4dGVuZGVkKCkpIHJldHVybiBFeHBhbmQ7CisgICAgLy8gSWYgYSB0YXJnZXQtc3BlY2lmaWMgU0ROb2RlIHJlcXVpcmVzIGxlZ2FsaXphdGlvbiwgcmVxdWlyZSB0aGUgdGFyZ2V0CisgICAgLy8gdG8gcHJvdmlkZSBjdXN0b20gbGVnYWxpemF0aW9uIGZvciBpdC4KKyAgICBpZiAoT3AgPj0gYXJyYXlfbGVuZ3Rob2YoT3BBY3Rpb25zWzBdKSkgcmV0dXJuIEN1c3RvbTsKKyAgICByZXR1cm4gT3BBY3Rpb25zWyh1bnNpZ25lZClWVC5nZXRTaW1wbGVWVCgpLlNpbXBsZVR5XVtPcF07CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCBvcGVyYXRpb24gaXMgbGVnYWwgb24gdGhpcyB0YXJnZXQgb3IgY2FuIGJlCisgIC8vLyBtYWRlIGxlZ2FsIHdpdGggY3VzdG9tIGxvd2VyaW5nLiBUaGlzIGlzIHVzZWQgdG8gaGVscCBndWlkZSBoaWdoLWxldmVsCisgIC8vLyBsb3dlcmluZyBkZWNpc2lvbnMuCisgIGJvb2wgaXNPcGVyYXRpb25MZWdhbE9yQ3VzdG9tKHVuc2lnbmVkIE9wLCBFVlQgVlQpIGNvbnN0IHsKKyAgICByZXR1cm4gKFZUID09IE1WVDo6T3RoZXIgfHwgaXNUeXBlTGVnYWwoVlQpKSAmJgorICAgICAgKGdldE9wZXJhdGlvbkFjdGlvbihPcCwgVlQpID09IExlZ2FsIHx8CisgICAgICAgZ2V0T3BlcmF0aW9uQWN0aW9uKE9wLCBWVCkgPT0gQ3VzdG9tKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIG9wZXJhdGlvbiBpcyBsZWdhbCBvbiB0aGlzIHRhcmdldCBvciBjYW4gYmUKKyAgLy8vIG1hZGUgbGVnYWwgdXNpbmcgcHJvbW90aW9uLiBUaGlzIGlzIHVzZWQgdG8gaGVscCBndWlkZSBoaWdoLWxldmVsIGxvd2VyaW5nCisgIC8vLyBkZWNpc2lvbnMuCisgIGJvb2wgaXNPcGVyYXRpb25MZWdhbE9yUHJvbW90ZSh1bnNpZ25lZCBPcCwgRVZUIFZUKSBjb25zdCB7CisgICAgcmV0dXJuIChWVCA9PSBNVlQ6Ok90aGVyIHx8IGlzVHlwZUxlZ2FsKFZUKSkgJiYKKyAgICAgIChnZXRPcGVyYXRpb25BY3Rpb24oT3AsIFZUKSA9PSBMZWdhbCB8fAorICAgICAgIGdldE9wZXJhdGlvbkFjdGlvbihPcCwgVlQpID09IFByb21vdGUpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgb3BlcmF0aW9uIGlzIGxlZ2FsIG9uIHRoaXMgdGFyZ2V0IG9yIGNhbiBiZQorICAvLy8gbWFkZSBsZWdhbCB3aXRoIGN1c3RvbSBsb3dlcmluZyBvciB1c2luZyBwcm9tb3Rpb24uIFRoaXMgaXMgdXNlZCB0byBoZWxwCisgIC8vLyBndWlkZSBoaWdoLWxldmVsIGxvd2VyaW5nIGRlY2lzaW9ucy4KKyAgYm9vbCBpc09wZXJhdGlvbkxlZ2FsT3JDdXN0b21PclByb21vdGUodW5zaWduZWQgT3AsIEVWVCBWVCkgY29uc3QgeworICAgIHJldHVybiAoVlQgPT0gTVZUOjpPdGhlciB8fCBpc1R5cGVMZWdhbChWVCkpICYmCisgICAgICAoZ2V0T3BlcmF0aW9uQWN0aW9uKE9wLCBWVCkgPT0gTGVnYWwgfHwKKyAgICAgICBnZXRPcGVyYXRpb25BY3Rpb24oT3AsIFZUKSA9PSBDdXN0b20gfHwKKyAgICAgICBnZXRPcGVyYXRpb25BY3Rpb24oT3AsIFZUKSA9PSBQcm9tb3RlKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgb3BlcmF0aW9uIHVzZXMgY3VzdG9tIGxvd2VyaW5nLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIKKyAgLy8vIHRoZSB0eXBlIGlzIGxlZ2FsIG9yIG5vdC4KKyAgYm9vbCBpc09wZXJhdGlvbkN1c3RvbSh1bnNpZ25lZCBPcCwgRVZUIFZUKSBjb25zdCB7CisgICAgcmV0dXJuIGdldE9wZXJhdGlvbkFjdGlvbihPcCwgVlQpID09IEN1c3RvbTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBsb3dlcmluZyB0byBhIGp1bXAgdGFibGUgaXMgYWxsb3dlZC4KKyAgdmlydHVhbCBib29sIGFyZUpUc0FsbG93ZWQoY29uc3QgRnVuY3Rpb24gKkZuKSBjb25zdCB7CisgICAgaWYgKEZuLT5nZXRGbkF0dHJpYnV0ZSgibm8tanVtcC10YWJsZXMiKS5nZXRWYWx1ZUFzU3RyaW5nKCkgPT0gInRydWUiKQorICAgICAgcmV0dXJuIGZhbHNlOworCisgICAgcmV0dXJuIGlzT3BlcmF0aW9uTGVnYWxPckN1c3RvbShJU0Q6OkJSX0pULCBNVlQ6Ok90aGVyKSB8fAorICAgICAgICAgICBpc09wZXJhdGlvbkxlZ2FsT3JDdXN0b20oSVNEOjpCUklORCwgTVZUOjpPdGhlcik7CisgIH0KKworICAvLy8gQ2hlY2sgd2hldGhlciB0aGUgcmFuZ2UgW0xvdyxIaWdoXSBmaXRzIGluIGEgbWFjaGluZSB3b3JkLgorICBib29sIHJhbmdlRml0c0luV29yZChjb25zdCBBUEludCAmTG93LCBjb25zdCBBUEludCAmSGlnaCwKKyAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRGF0YUxheW91dCAmREwpIGNvbnN0IHsKKyAgICAvLyBGSVhNRTogVXNpbmcgdGhlIHBvaW50ZXIgdHlwZSBkb2Vzbid0IHNlZW0gaWRlYWwuCisgICAgdWludDY0X3QgQlcgPSBETC5nZXRJbmRleFNpemVJbkJpdHMoMHUpOworICAgIHVpbnQ2NF90IFJhbmdlID0gKEhpZ2ggLSBMb3cpLmdldExpbWl0ZWRWYWx1ZShVSU5UNjRfTUFYIC0gMSkgKyAxOworICAgIHJldHVybiBSYW5nZSA8PSBCVzsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBsb3dlcmluZyB0byBhIGp1bXAgdGFibGUgaXMgc3VpdGFibGUgZm9yIGEgc2V0IG9mIGNhc2UKKyAgLy8vIGNsdXN0ZXJzIHdoaWNoIG1heSBjb250YWluIFxwIE51bUNhc2VzIGNhc2VzLCBccCBSYW5nZSByYW5nZSBvZiB2YWx1ZXMuCisgIC8vLyBGSVhNRTogVGhpcyBmdW5jdGlvbiBjaGVjayB0aGUgbWF4aW11bSB0YWJsZSBzaXplIGFuZCBkZW5zaXR5LCBidXQgdGhlCisgIC8vLyBtaW5pbXVtIHNpemUgaXMgbm90IGNoZWNrZWQuIEl0IHdvdWxkIGJlIG5pY2UgaWYgdGhlIG1pbmltdW0gc2l6ZSBpcworICAvLy8gYWxzbyBjb21iaW5lZCB3aXRoaW4gdGhpcyBmdW5jdGlvbi4gQ3VycmVudGx5LCB0aGUgbWluaW11bSBzaXplIGNoZWNrIGlzCisgIC8vLyBwZXJmb3JtZWQgaW4gZmluZEp1bXBUYWJsZSgpIGluIFNlbGVjdGlvbkRBR0J1aWxlciBhbmQKKyAgLy8vIGdldEVzdGltYXRlZE51bWJlck9mQ2FzZUNsdXN0ZXJzKCkgaW4gQmFzaWNUVElJbXBsLgorICB2aXJ0dWFsIGJvb2wgaXNTdWl0YWJsZUZvckp1bXBUYWJsZShjb25zdCBTd2l0Y2hJbnN0ICpTSSwgdWludDY0X3QgTnVtQ2FzZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ2NF90IFJhbmdlKSBjb25zdCB7CisgICAgY29uc3QgYm9vbCBPcHRGb3JTaXplID0gU0ktPmdldFBhcmVudCgpLT5nZXRQYXJlbnQoKS0+b3B0Rm9yU2l6ZSgpOworICAgIGNvbnN0IHVuc2lnbmVkIE1pbkRlbnNpdHkgPSBnZXRNaW5pbXVtSnVtcFRhYmxlRGVuc2l0eShPcHRGb3JTaXplKTsKKyAgICBjb25zdCB1bnNpZ25lZCBNYXhKdW1wVGFibGVTaXplID0KKyAgICAgICAgT3B0Rm9yU2l6ZSB8fCBnZXRNYXhpbXVtSnVtcFRhYmxlU2l6ZSgpID09IDAKKyAgICAgICAgICAgID8gVUlOVF9NQVgKKyAgICAgICAgICAgIDogZ2V0TWF4aW11bUp1bXBUYWJsZVNpemUoKTsKKyAgICAvLyBDaGVjayB3aGV0aGVyIGEgcmFuZ2Ugb2YgY2x1c3RlcnMgaXMgZGVuc2UgZW5vdWdoIGZvciBhIGp1bXAgdGFibGUuCisgICAgaWYgKFJhbmdlIDw9IE1heEp1bXBUYWJsZVNpemUgJiYKKyAgICAgICAgKE51bUNhc2VzICogMTAwID49IFJhbmdlICogTWluRGVuc2l0eSkpIHsKKyAgICAgIHJldHVybiB0cnVlOworICAgIH0KKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgbG93ZXJpbmcgdG8gYSBiaXQgdGVzdCBpcyBzdWl0YWJsZSBmb3IgYSBzZXQgb2YgY2FzZQorICAvLy8gY2x1c3RlcnMgd2hpY2ggY29udGFpbnMgXHAgTnVtRGVzdHMgdW5pcXVlIGRlc3RpbmF0aW9ucywgXHAgTG93IGFuZAorICAvLy8gXHAgSGlnaCBhcyBpdHMgbG93ZXN0IGFuZCBoaWdoZXN0IGNhc2UgdmFsdWVzLCBhbmQgZXhwZWN0cyBccCBOdW1DbXBzCisgIC8vLyBjYXNlIHZhbHVlIGNvbXBhcmlzb25zLiBDaGVjayBpZiB0aGUgbnVtYmVyIG9mIGRlc3RpbmF0aW9ucywgY29tcGFyaXNvbgorICAvLy8gbWV0cmljLCBhbmQgcmFuZ2UgYXJlIGFsbCBzdWl0YWJsZS4KKyAgYm9vbCBpc1N1aXRhYmxlRm9yQml0VGVzdHModW5zaWduZWQgTnVtRGVzdHMsIHVuc2lnbmVkIE51bUNtcHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFQSW50ICZMb3csIGNvbnN0IEFQSW50ICZIaWdoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBEYXRhTGF5b3V0ICZETCkgY29uc3QgeworICAgIC8vIEZJWE1FOiBJIGRvbid0IHRoaW5rIE51bUNtcHMgaXMgdGhlIGNvcnJlY3QgbWV0cmljOiBhIHNpbmdsZSBjYXNlIGFuZCBhCisgICAgLy8gcmFuZ2Ugb2YgY2FzZXMgYm90aCByZXF1aXJlIG9ubHkgb25lIGJyYW5jaCB0byBsb3dlci4gSnVzdCBsb29raW5nIGF0IHRoZQorICAgIC8vIG51bWJlciBvZiBjbHVzdGVycyBhbmQgZGVzdGluYXRpb25zIHNob3VsZCBiZSBlbm91Z2ggdG8gZGVjaWRlIHdoZXRoZXIgdG8KKyAgICAvLyBidWlsZCBiaXQgdGVzdHMuCisKKyAgICAvLyBUbyBsb3dlciBhIHJhbmdlIHdpdGggYml0IHRlc3RzLCB0aGUgcmFuZ2UgbXVzdCBmaXQgdGhlIGJpdHdpZHRoIG9mIGEKKyAgICAvLyBtYWNoaW5lIHdvcmQuCisgICAgaWYgKCFyYW5nZUZpdHNJbldvcmQoTG93LCBIaWdoLCBETCkpCisgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAvLyBEZWNpZGUgd2hldGhlciBpdCdzIHByb2ZpdGFibGUgdG8gbG93ZXIgdGhpcyByYW5nZSB3aXRoIGJpdCB0ZXN0cy4gRWFjaAorICAgIC8vIGRlc3RpbmF0aW9uIHJlcXVpcmVzIGEgYml0IHRlc3QgYW5kIGJyYW5jaCwgYW5kIHRoZXJlIGlzIGFuIG92ZXJhbGwgcmFuZ2UKKyAgICAvLyBjaGVjayBicmFuY2guIEZvciBhIHNtYWxsIG51bWJlciBvZiBjbHVzdGVycywgc2VwYXJhdGUgY29tcGFyaXNvbnMgbWlnaHQKKyAgICAvLyBiZSBjaGVhcGVyLCBhbmQgZm9yIG1hbnkgZGVzdGluYXRpb25zLCBzcGxpdHRpbmcgdGhlIHJhbmdlIG1pZ2h0IGJlCisgICAgLy8gYmV0dGVyLgorICAgIHJldHVybiAoTnVtRGVzdHMgPT0gMSAmJiBOdW1DbXBzID49IDMpIHx8IChOdW1EZXN0cyA9PSAyICYmIE51bUNtcHMgPj0gNSkgfHwKKyAgICAgICAgICAgKE51bURlc3RzID09IDMgJiYgTnVtQ21wcyA+PSA2KTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIG9wZXJhdGlvbiBpcyBpbGxlZ2FsIG9uIHRoaXMgdGFyZ2V0IG9yCisgIC8vLyB1bmxpa2VseSB0byBiZSBtYWRlIGxlZ2FsIHdpdGggY3VzdG9tIGxvd2VyaW5nLiBUaGlzIGlzIHVzZWQgdG8gaGVscCBndWlkZQorICAvLy8gaGlnaC1sZXZlbCBsb3dlcmluZyBkZWNpc2lvbnMuCisgIGJvb2wgaXNPcGVyYXRpb25FeHBhbmQodW5zaWduZWQgT3AsIEVWVCBWVCkgY29uc3QgeworICAgIHJldHVybiAoIWlzVHlwZUxlZ2FsKFZUKSB8fCBnZXRPcGVyYXRpb25BY3Rpb24oT3AsIFZUKSA9PSBFeHBhbmQpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgb3BlcmF0aW9uIGlzIGxlZ2FsIG9uIHRoaXMgdGFyZ2V0LgorICBib29sIGlzT3BlcmF0aW9uTGVnYWwodW5zaWduZWQgT3AsIEVWVCBWVCkgY29uc3QgeworICAgIHJldHVybiAoVlQgPT0gTVZUOjpPdGhlciB8fCBpc1R5cGVMZWdhbChWVCkpICYmCisgICAgICAgICAgIGdldE9wZXJhdGlvbkFjdGlvbihPcCwgVlQpID09IExlZ2FsOworICB9CisKKyAgLy8vIFJldHVybiBob3cgdGhpcyBsb2FkIHdpdGggZXh0ZW5zaW9uIHNob3VsZCBiZSB0cmVhdGVkOiBlaXRoZXIgaXQgaXMgbGVnYWwsCisgIC8vLyBuZWVkcyB0byBiZSBwcm9tb3RlZCB0byBhIGxhcmdlciBzaXplLCBuZWVkcyB0byBiZSBleHBhbmRlZCB0byBzb21lIG90aGVyCisgIC8vLyBjb2RlIHNlcXVlbmNlLCBvciB0aGUgdGFyZ2V0IGhhcyBhIGN1c3RvbSBleHBhbmRlciBmb3IgaXQuCisgIExlZ2FsaXplQWN0aW9uIGdldExvYWRFeHRBY3Rpb24odW5zaWduZWQgRXh0VHlwZSwgRVZUIFZhbFZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVWVCBNZW1WVCkgY29uc3QgeworICAgIGlmIChWYWxWVC5pc0V4dGVuZGVkKCkgfHwgTWVtVlQuaXNFeHRlbmRlZCgpKSByZXR1cm4gRXhwYW5kOworICAgIHVuc2lnbmVkIFZhbEkgPSAodW5zaWduZWQpIFZhbFZULmdldFNpbXBsZVZUKCkuU2ltcGxlVHk7CisgICAgdW5zaWduZWQgTWVtSSA9ICh1bnNpZ25lZCkgTWVtVlQuZ2V0U2ltcGxlVlQoKS5TaW1wbGVUeTsKKyAgICBhc3NlcnQoRXh0VHlwZSA8IElTRDo6TEFTVF9MT0FERVhUX1RZUEUgJiYgVmFsSSA8IE1WVDo6TEFTVF9WQUxVRVRZUEUgJiYKKyAgICAgICAgICAgTWVtSSA8IE1WVDo6TEFTVF9WQUxVRVRZUEUgJiYgIlRhYmxlIGlzbid0IGJpZyBlbm91Z2ghIik7CisgICAgdW5zaWduZWQgU2hpZnQgPSA0ICogRXh0VHlwZTsKKyAgICByZXR1cm4gKExlZ2FsaXplQWN0aW9uKSgoTG9hZEV4dEFjdGlvbnNbVmFsSV1bTWVtSV0gPj4gU2hpZnQpICYgMHhmKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGxvYWQgd2l0aCBleHRlbnNpb24gaXMgbGVnYWwgb24gdGhpcyB0YXJnZXQuCisgIGJvb2wgaXNMb2FkRXh0TGVnYWwodW5zaWduZWQgRXh0VHlwZSwgRVZUIFZhbFZULCBFVlQgTWVtVlQpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0TG9hZEV4dEFjdGlvbihFeHRUeXBlLCBWYWxWVCwgTWVtVlQpID09IExlZ2FsOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgbG9hZCB3aXRoIGV4dGVuc2lvbiBpcyBsZWdhbCBvciBjdXN0b20KKyAgLy8vIG9uIHRoaXMgdGFyZ2V0LgorICBib29sIGlzTG9hZEV4dExlZ2FsT3JDdXN0b20odW5zaWduZWQgRXh0VHlwZSwgRVZUIFZhbFZULCBFVlQgTWVtVlQpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0TG9hZEV4dEFjdGlvbihFeHRUeXBlLCBWYWxWVCwgTWVtVlQpID09IExlZ2FsIHx8CisgICAgICAgICAgIGdldExvYWRFeHRBY3Rpb24oRXh0VHlwZSwgVmFsVlQsIE1lbVZUKSA9PSBDdXN0b207CisgIH0KKworICAvLy8gUmV0dXJuIGhvdyB0aGlzIHN0b3JlIHdpdGggdHJ1bmNhdGlvbiBzaG91bGQgYmUgdHJlYXRlZDogZWl0aGVyIGl0IGlzCisgIC8vLyBsZWdhbCwgbmVlZHMgdG8gYmUgcHJvbW90ZWQgdG8gYSBsYXJnZXIgc2l6ZSwgbmVlZHMgdG8gYmUgZXhwYW5kZWQgdG8gc29tZQorICAvLy8gb3RoZXIgY29kZSBzZXF1ZW5jZSwgb3IgdGhlIHRhcmdldCBoYXMgYSBjdXN0b20gZXhwYW5kZXIgZm9yIGl0LgorICBMZWdhbGl6ZUFjdGlvbiBnZXRUcnVuY1N0b3JlQWN0aW9uKEVWVCBWYWxWVCwgRVZUIE1lbVZUKSBjb25zdCB7CisgICAgaWYgKFZhbFZULmlzRXh0ZW5kZWQoKSB8fCBNZW1WVC5pc0V4dGVuZGVkKCkpIHJldHVybiBFeHBhbmQ7CisgICAgdW5zaWduZWQgVmFsSSA9ICh1bnNpZ25lZCkgVmFsVlQuZ2V0U2ltcGxlVlQoKS5TaW1wbGVUeTsKKyAgICB1bnNpZ25lZCBNZW1JID0gKHVuc2lnbmVkKSBNZW1WVC5nZXRTaW1wbGVWVCgpLlNpbXBsZVR5OworICAgIGFzc2VydChWYWxJIDwgTVZUOjpMQVNUX1ZBTFVFVFlQRSAmJiBNZW1JIDwgTVZUOjpMQVNUX1ZBTFVFVFlQRSAmJgorICAgICAgICAgICAiVGFibGUgaXNuJ3QgYmlnIGVub3VnaCEiKTsKKyAgICByZXR1cm4gVHJ1bmNTdG9yZUFjdGlvbnNbVmFsSV1bTWVtSV07CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCBzdG9yZSB3aXRoIHRydW5jYXRpb24gaXMgbGVnYWwgb24gdGhpcworICAvLy8gdGFyZ2V0LgorICBib29sIGlzVHJ1bmNTdG9yZUxlZ2FsKEVWVCBWYWxWVCwgRVZUIE1lbVZUKSBjb25zdCB7CisgICAgcmV0dXJuIGlzVHlwZUxlZ2FsKFZhbFZUKSAmJiBnZXRUcnVuY1N0b3JlQWN0aW9uKFZhbFZULCBNZW1WVCkgPT0gTGVnYWw7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCBzdG9yZSB3aXRoIHRydW5jYXRpb24gaGFzIHNvbHV0aW9uIG9uIHRoaXMKKyAgLy8vIHRhcmdldC4KKyAgYm9vbCBpc1RydW5jU3RvcmVMZWdhbE9yQ3VzdG9tKEVWVCBWYWxWVCwgRVZUIE1lbVZUKSBjb25zdCB7CisgICAgcmV0dXJuIGlzVHlwZUxlZ2FsKFZhbFZUKSAmJgorICAgICAgKGdldFRydW5jU3RvcmVBY3Rpb24oVmFsVlQsIE1lbVZUKSA9PSBMZWdhbCB8fAorICAgICAgIGdldFRydW5jU3RvcmVBY3Rpb24oVmFsVlQsIE1lbVZUKSA9PSBDdXN0b20pOworICB9CisKKyAgLy8vIFJldHVybiBob3cgdGhlIGluZGV4ZWQgbG9hZCBzaG91bGQgYmUgdHJlYXRlZDogZWl0aGVyIGl0IGlzIGxlZ2FsLCBuZWVkcworICAvLy8gdG8gYmUgcHJvbW90ZWQgdG8gYSBsYXJnZXIgc2l6ZSwgbmVlZHMgdG8gYmUgZXhwYW5kZWQgdG8gc29tZSBvdGhlciBjb2RlCisgIC8vLyBzZXF1ZW5jZSwgb3IgdGhlIHRhcmdldCBoYXMgYSBjdXN0b20gZXhwYW5kZXIgZm9yIGl0LgorICBMZWdhbGl6ZUFjdGlvbgorICBnZXRJbmRleGVkTG9hZEFjdGlvbih1bnNpZ25lZCBJZHhNb2RlLCBNVlQgVlQpIGNvbnN0IHsKKyAgICBhc3NlcnQoSWR4TW9kZSA8IElTRDo6TEFTVF9JTkRFWEVEX01PREUgJiYgVlQuaXNWYWxpZCgpICYmCisgICAgICAgICAgICJUYWJsZSBpc24ndCBiaWcgZW5vdWdoISIpOworICAgIHVuc2lnbmVkIFR5ID0gKHVuc2lnbmVkKVZULlNpbXBsZVR5OworICAgIHJldHVybiAoTGVnYWxpemVBY3Rpb24pKChJbmRleGVkTW9kZUFjdGlvbnNbVHldW0lkeE1vZGVdICYgMHhmMCkgPj4gNCk7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCBpbmRleGVkIGxvYWQgaXMgbGVnYWwgb24gdGhpcyB0YXJnZXQuCisgIGJvb2wgaXNJbmRleGVkTG9hZExlZ2FsKHVuc2lnbmVkIElkeE1vZGUsIEVWVCBWVCkgY29uc3QgeworICAgIHJldHVybiBWVC5pc1NpbXBsZSgpICYmCisgICAgICAoZ2V0SW5kZXhlZExvYWRBY3Rpb24oSWR4TW9kZSwgVlQuZ2V0U2ltcGxlVlQoKSkgPT0gTGVnYWwgfHwKKyAgICAgICBnZXRJbmRleGVkTG9hZEFjdGlvbihJZHhNb2RlLCBWVC5nZXRTaW1wbGVWVCgpKSA9PSBDdXN0b20pOworICB9CisKKyAgLy8vIFJldHVybiBob3cgdGhlIGluZGV4ZWQgc3RvcmUgc2hvdWxkIGJlIHRyZWF0ZWQ6IGVpdGhlciBpdCBpcyBsZWdhbCwgbmVlZHMKKyAgLy8vIHRvIGJlIHByb21vdGVkIHRvIGEgbGFyZ2VyIHNpemUsIG5lZWRzIHRvIGJlIGV4cGFuZGVkIHRvIHNvbWUgb3RoZXIgY29kZQorICAvLy8gc2VxdWVuY2UsIG9yIHRoZSB0YXJnZXQgaGFzIGEgY3VzdG9tIGV4cGFuZGVyIGZvciBpdC4KKyAgTGVnYWxpemVBY3Rpb24KKyAgZ2V0SW5kZXhlZFN0b3JlQWN0aW9uKHVuc2lnbmVkIElkeE1vZGUsIE1WVCBWVCkgY29uc3QgeworICAgIGFzc2VydChJZHhNb2RlIDwgSVNEOjpMQVNUX0lOREVYRURfTU9ERSAmJiBWVC5pc1ZhbGlkKCkgJiYKKyAgICAgICAgICAgIlRhYmxlIGlzbid0IGJpZyBlbm91Z2ghIik7CisgICAgdW5zaWduZWQgVHkgPSAodW5zaWduZWQpVlQuU2ltcGxlVHk7CisgICAgcmV0dXJuIChMZWdhbGl6ZUFjdGlvbikoSW5kZXhlZE1vZGVBY3Rpb25zW1R5XVtJZHhNb2RlXSAmIDB4MGYpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgaW5kZXhlZCBsb2FkIGlzIGxlZ2FsIG9uIHRoaXMgdGFyZ2V0LgorICBib29sIGlzSW5kZXhlZFN0b3JlTGVnYWwodW5zaWduZWQgSWR4TW9kZSwgRVZUIFZUKSBjb25zdCB7CisgICAgcmV0dXJuIFZULmlzU2ltcGxlKCkgJiYKKyAgICAgIChnZXRJbmRleGVkU3RvcmVBY3Rpb24oSWR4TW9kZSwgVlQuZ2V0U2ltcGxlVlQoKSkgPT0gTGVnYWwgfHwKKyAgICAgICBnZXRJbmRleGVkU3RvcmVBY3Rpb24oSWR4TW9kZSwgVlQuZ2V0U2ltcGxlVlQoKSkgPT0gQ3VzdG9tKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gaG93IHRoZSBjb25kaXRpb24gY29kZSBzaG91bGQgYmUgdHJlYXRlZDogZWl0aGVyIGl0IGlzIGxlZ2FsLCBuZWVkcworICAvLy8gdG8gYmUgZXhwYW5kZWQgdG8gc29tZSBvdGhlciBjb2RlIHNlcXVlbmNlLCBvciB0aGUgdGFyZ2V0IGhhcyBhIGN1c3RvbQorICAvLy8gZXhwYW5kZXIgZm9yIGl0LgorICBMZWdhbGl6ZUFjdGlvbgorICBnZXRDb25kQ29kZUFjdGlvbihJU0Q6OkNvbmRDb2RlIENDLCBNVlQgVlQpIGNvbnN0IHsKKyAgICBhc3NlcnQoKHVuc2lnbmVkKUNDIDwgYXJyYXlfbGVuZ3Rob2YoQ29uZENvZGVBY3Rpb25zKSAmJgorICAgICAgICAgICAoKHVuc2lnbmVkKVZULlNpbXBsZVR5ID4+IDMpIDwgYXJyYXlfbGVuZ3Rob2YoQ29uZENvZGVBY3Rpb25zWzBdKSAmJgorICAgICAgICAgICAiVGFibGUgaXNuJ3QgYmlnIGVub3VnaCEiKTsKKyAgICAvLyBTZWUgc2V0Q29uZENvZGVBY3Rpb24gZm9yIGhvdyB0aGlzIGlzIGVuY29kZWQuCisgICAgdWludDMyX3QgU2hpZnQgPSA0ICogKFZULlNpbXBsZVR5ICYgMHg3KTsKKyAgICB1aW50MzJfdCBWYWx1ZSA9IENvbmRDb2RlQWN0aW9uc1tDQ11bVlQuU2ltcGxlVHkgPj4gM107CisgICAgTGVnYWxpemVBY3Rpb24gQWN0aW9uID0gKExlZ2FsaXplQWN0aW9uKSAoKFZhbHVlID4+IFNoaWZ0KSAmIDB4Rik7CisgICAgYXNzZXJ0KEFjdGlvbiAhPSBQcm9tb3RlICYmICJDYW4ndCBwcm9tb3RlIGNvbmRpdGlvbiBjb2RlISIpOworICAgIHJldHVybiBBY3Rpb247CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjb25kaXRpb24gY29kZSBpcyBsZWdhbCBvbiB0aGlzIHRhcmdldC4KKyAgYm9vbCBpc0NvbmRDb2RlTGVnYWwoSVNEOjpDb25kQ29kZSBDQywgTVZUIFZUKSBjb25zdCB7CisgICAgcmV0dXJuIGdldENvbmRDb2RlQWN0aW9uKENDLCBWVCkgPT0gTGVnYWw7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCBjb25kaXRpb24gY29kZSBpcyBsZWdhbCBvciBjdXN0b20gb24gdGhpcworICAvLy8gdGFyZ2V0LgorICBib29sIGlzQ29uZENvZGVMZWdhbE9yQ3VzdG9tKElTRDo6Q29uZENvZGUgQ0MsIE1WVCBWVCkgY29uc3QgeworICAgIHJldHVybiBnZXRDb25kQ29kZUFjdGlvbihDQywgVlQpID09IExlZ2FsIHx8CisgICAgICAgICAgIGdldENvbmRDb2RlQWN0aW9uKENDLCBWVCkgPT0gQ3VzdG9tOworICB9CisKKyAgLy8vIElmIHRoZSBhY3Rpb24gZm9yIHRoaXMgb3BlcmF0aW9uIGlzIHRvIHByb21vdGUsIHRoaXMgbWV0aG9kIHJldHVybnMgdGhlCisgIC8vLyBWYWx1ZVR5cGUgdG8gcHJvbW90ZSB0by4KKyAgTVZUIGdldFR5cGVUb1Byb21vdGVUbyh1bnNpZ25lZCBPcCwgTVZUIFZUKSBjb25zdCB7CisgICAgYXNzZXJ0KGdldE9wZXJhdGlvbkFjdGlvbihPcCwgVlQpID09IFByb21vdGUgJiYKKyAgICAgICAgICAgIlRoaXMgb3BlcmF0aW9uIGlzbid0IHByb21vdGVkISIpOworCisgICAgLy8gU2VlIGlmIHRoaXMgaGFzIGFuIGV4cGxpY2l0IHR5cGUgc3BlY2lmaWVkLgorICAgIHN0ZDo6bWFwPHN0ZDo6cGFpcjx1bnNpZ25lZCwgTVZUOjpTaW1wbGVWYWx1ZVR5cGU+LAorICAgICAgICAgICAgIE1WVDo6U2ltcGxlVmFsdWVUeXBlPjo6Y29uc3RfaXRlcmF0b3IgUFRUSSA9CisgICAgICBQcm9tb3RlVG9UeXBlLmZpbmQoc3RkOjptYWtlX3BhaXIoT3AsIFZULlNpbXBsZVR5KSk7CisgICAgaWYgKFBUVEkgIT0gUHJvbW90ZVRvVHlwZS5lbmQoKSkgcmV0dXJuIFBUVEktPnNlY29uZDsKKworICAgIGFzc2VydCgoVlQuaXNJbnRlZ2VyKCkgfHwgVlQuaXNGbG9hdGluZ1BvaW50KCkpICYmCisgICAgICAgICAgICJDYW5ub3QgYXV0b3Byb21vdGUgdGhpcyB0eXBlLCBhZGQgaXQgd2l0aCBBZGRQcm9tb3RlZFRvVHlwZS4iKTsKKworICAgIE1WVCBOVlQgPSBWVDsKKyAgICBkbyB7CisgICAgICBOVlQgPSAoTVZUOjpTaW1wbGVWYWx1ZVR5cGUpKE5WVC5TaW1wbGVUeSsxKTsKKyAgICAgIGFzc2VydChOVlQuaXNJbnRlZ2VyKCkgPT0gVlQuaXNJbnRlZ2VyKCkgJiYgTlZUICE9IE1WVDo6aXNWb2lkICYmCisgICAgICAgICAgICAgIkRpZG4ndCBmaW5kIHR5cGUgdG8gcHJvbW90ZSB0byEiKTsKKyAgICB9IHdoaWxlICghaXNUeXBlTGVnYWwoTlZUKSB8fAorICAgICAgICAgICAgICBnZXRPcGVyYXRpb25BY3Rpb24oT3AsIE5WVCkgPT0gUHJvbW90ZSk7CisgICAgcmV0dXJuIE5WVDsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIEVWVCBjb3JyZXNwb25kaW5nIHRvIHRoaXMgTExWTSB0eXBlLiAgVGhpcyBpcyBmaXhlZCBieSB0aGUgTExWTQorICAvLy8gb3BlcmF0aW9ucyBleGNlcHQgZm9yIHRoZSBwb2ludGVyIHNpemUuICBJZiBBbGxvd1Vua25vd24gaXMgdHJ1ZSwgdGhpcworICAvLy8gd2lsbCByZXR1cm4gTVZUOjpPdGhlciBmb3IgdHlwZXMgd2l0aCBubyBFVlQgY291bnRlcnBhcnQgKGUuZy4gc3RydWN0cyksCisgIC8vLyBvdGhlcndpc2UgaXQgd2lsbCBhc3NlcnQuCisgIEVWVCBnZXRWYWx1ZVR5cGUoY29uc3QgRGF0YUxheW91dCAmREwsIFR5cGUgKlR5LAorICAgICAgICAgICAgICAgICAgIGJvb2wgQWxsb3dVbmtub3duID0gZmFsc2UpIGNvbnN0IHsKKyAgICAvLyBMb3dlciBzY2FsYXIgcG9pbnRlcnMgdG8gbmF0aXZlIHBvaW50ZXIgdHlwZXMuCisgICAgaWYgKFBvaW50ZXJUeXBlICpQVHkgPSBkeW5fY2FzdDxQb2ludGVyVHlwZT4oVHkpKQorICAgICAgcmV0dXJuIGdldFBvaW50ZXJUeShETCwgUFR5LT5nZXRBZGRyZXNzU3BhY2UoKSk7CisKKyAgICBpZiAoVHktPmlzVmVjdG9yVHkoKSkgeworICAgICAgVmVjdG9yVHlwZSAqVlR5ID0gY2FzdDxWZWN0b3JUeXBlPihUeSk7CisgICAgICBUeXBlICpFbG0gPSBWVHktPmdldEVsZW1lbnRUeXBlKCk7CisgICAgICAvLyBMb3dlciB2ZWN0b3JzIG9mIHBvaW50ZXJzIHRvIG5hdGl2ZSBwb2ludGVyIHR5cGVzLgorICAgICAgaWYgKFBvaW50ZXJUeXBlICpQVCA9IGR5bl9jYXN0PFBvaW50ZXJUeXBlPihFbG0pKSB7CisgICAgICAgIEVWVCBQb2ludGVyVHkoZ2V0UG9pbnRlclR5KERMLCBQVC0+Z2V0QWRkcmVzc1NwYWNlKCkpKTsKKyAgICAgICAgRWxtID0gUG9pbnRlclR5LmdldFR5cGVGb3JFVlQoVHktPmdldENvbnRleHQoKSk7CisgICAgICB9CisKKyAgICAgIHJldHVybiBFVlQ6OmdldFZlY3RvclZUKFR5LT5nZXRDb250ZXh0KCksIEVWVDo6Z2V0RVZUKEVsbSwgZmFsc2UpLAorICAgICAgICAgICAgICAgICAgICAgICBWVHktPmdldE51bUVsZW1lbnRzKCkpOworICAgIH0KKyAgICByZXR1cm4gRVZUOjpnZXRFVlQoVHksIEFsbG93VW5rbm93bik7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBNVlQgY29ycmVzcG9uZGluZyB0byB0aGlzIExMVk0gdHlwZS4gU2VlIGdldFZhbHVlVHlwZS4KKyAgTVZUIGdldFNpbXBsZVZhbHVlVHlwZShjb25zdCBEYXRhTGF5b3V0ICZETCwgVHlwZSAqVHksCisgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBBbGxvd1Vua25vd24gPSBmYWxzZSkgY29uc3QgeworICAgIHJldHVybiBnZXRWYWx1ZVR5cGUoREwsIFR5LCBBbGxvd1Vua25vd24pLmdldFNpbXBsZVZUKCk7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBkZXNpcmVkIGFsaWdubWVudCBmb3IgQnlWYWwgb3IgSW5BbGxvY2EgYWdncmVnYXRlIGZ1bmN0aW9uCisgIC8vLyBhcmd1bWVudHMgaW4gdGhlIGNhbGxlciBwYXJhbWV0ZXIgYXJlYS4gIFRoaXMgaXMgdGhlIGFjdHVhbCBhbGlnbm1lbnQsIG5vdAorICAvLy8gaXRzIGxvZ2FyaXRobS4KKyAgdmlydHVhbCB1bnNpZ25lZCBnZXRCeVZhbFR5cGVBbGlnbm1lbnQoVHlwZSAqVHksIGNvbnN0IERhdGFMYXlvdXQgJkRMKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRoZSB0eXBlIG9mIHJlZ2lzdGVycyB0aGF0IHRoaXMgVmFsdWVUeXBlIHdpbGwgZXZlbnR1YWxseSByZXF1aXJlLgorICBNVlQgZ2V0UmVnaXN0ZXJUeXBlKE1WVCBWVCkgY29uc3QgeworICAgIGFzc2VydCgodW5zaWduZWQpVlQuU2ltcGxlVHkgPCBhcnJheV9sZW5ndGhvZihSZWdpc3RlclR5cGVGb3JWVCkpOworICAgIHJldHVybiBSZWdpc3RlclR5cGVGb3JWVFtWVC5TaW1wbGVUeV07CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSB0eXBlIG9mIHJlZ2lzdGVycyB0aGF0IHRoaXMgVmFsdWVUeXBlIHdpbGwgZXZlbnR1YWxseSByZXF1aXJlLgorICBNVlQgZ2V0UmVnaXN0ZXJUeXBlKExMVk1Db250ZXh0ICZDb250ZXh0LCBFVlQgVlQpIGNvbnN0IHsKKyAgICBpZiAoVlQuaXNTaW1wbGUoKSkgeworICAgICAgYXNzZXJ0KCh1bnNpZ25lZClWVC5nZXRTaW1wbGVWVCgpLlNpbXBsZVR5IDwKKyAgICAgICAgICAgICAgICBhcnJheV9sZW5ndGhvZihSZWdpc3RlclR5cGVGb3JWVCkpOworICAgICAgcmV0dXJuIFJlZ2lzdGVyVHlwZUZvclZUW1ZULmdldFNpbXBsZVZUKCkuU2ltcGxlVHldOworICAgIH0KKyAgICBpZiAoVlQuaXNWZWN0b3IoKSkgeworICAgICAgRVZUIFZUMTsKKyAgICAgIE1WVCBSZWdpc3RlclZUOworICAgICAgdW5zaWduZWQgTnVtSW50ZXJtZWRpYXRlczsKKyAgICAgICh2b2lkKWdldFZlY3RvclR5cGVCcmVha2Rvd24oQ29udGV4dCwgVlQsIFZUMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtSW50ZXJtZWRpYXRlcywgUmVnaXN0ZXJWVCk7CisgICAgICByZXR1cm4gUmVnaXN0ZXJWVDsKKyAgICB9CisgICAgaWYgKFZULmlzSW50ZWdlcigpKSB7CisgICAgICByZXR1cm4gZ2V0UmVnaXN0ZXJUeXBlKENvbnRleHQsIGdldFR5cGVUb1RyYW5zZm9ybVRvKENvbnRleHQsIFZUKSk7CisgICAgfQorICAgIGxsdm1fdW5yZWFjaGFibGUoIlVuc3VwcG9ydGVkIGV4dGVuZGVkIHR5cGUhIik7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgcmVnaXN0ZXJzIHRoYXQgdGhpcyBWYWx1ZVR5cGUgd2lsbCBldmVudHVhbGx5CisgIC8vLyByZXF1aXJlLgorICAvLy8KKyAgLy8vIFRoaXMgaXMgb25lIGZvciBhbnkgdHlwZXMgcHJvbW90ZWQgdG8gbGl2ZSBpbiBsYXJnZXIgcmVnaXN0ZXJzLCBidXQgbWF5IGJlCisgIC8vLyBtb3JlIHRoYW4gb25lIGZvciB0eXBlcyAobGlrZSBpNjQpIHRoYXQgYXJlIHNwbGl0IGludG8gcGllY2VzLiAgRm9yIHR5cGVzCisgIC8vLyBsaWtlIGkxNDAsIHdoaWNoIGFyZSBmaXJzdCBwcm9tb3RlZCB0aGVuIGV4cGFuZGVkLCBpdCBpcyB0aGUgbnVtYmVyIG9mCisgIC8vLyByZWdpc3RlcnMgbmVlZGVkIHRvIGhvbGQgYWxsIHRoZSBiaXRzIG9mIHRoZSBvcmlnaW5hbCB0eXBlLiAgRm9yIGFuIGkxNDAKKyAgLy8vIG9uIGEgMzIgYml0IG1hY2hpbmUgdGhpcyBtZWFucyA1IHJlZ2lzdGVycy4KKyAgdW5zaWduZWQgZ2V0TnVtUmVnaXN0ZXJzKExMVk1Db250ZXh0ICZDb250ZXh0LCBFVlQgVlQpIGNvbnN0IHsKKyAgICBpZiAoVlQuaXNTaW1wbGUoKSkgeworICAgICAgYXNzZXJ0KCh1bnNpZ25lZClWVC5nZXRTaW1wbGVWVCgpLlNpbXBsZVR5IDwKKyAgICAgICAgICAgICAgICBhcnJheV9sZW5ndGhvZihOdW1SZWdpc3RlcnNGb3JWVCkpOworICAgICAgcmV0dXJuIE51bVJlZ2lzdGVyc0ZvclZUW1ZULmdldFNpbXBsZVZUKCkuU2ltcGxlVHldOworICAgIH0KKyAgICBpZiAoVlQuaXNWZWN0b3IoKSkgeworICAgICAgRVZUIFZUMTsKKyAgICAgIE1WVCBWVDI7CisgICAgICB1bnNpZ25lZCBOdW1JbnRlcm1lZGlhdGVzOworICAgICAgcmV0dXJuIGdldFZlY3RvclR5cGVCcmVha2Rvd24oQ29udGV4dCwgVlQsIFZUMSwgTnVtSW50ZXJtZWRpYXRlcywgVlQyKTsKKyAgICB9CisgICAgaWYgKFZULmlzSW50ZWdlcigpKSB7CisgICAgICB1bnNpZ25lZCBCaXRXaWR0aCA9IFZULmdldFNpemVJbkJpdHMoKTsKKyAgICAgIHVuc2lnbmVkIFJlZ1dpZHRoID0gZ2V0UmVnaXN0ZXJUeXBlKENvbnRleHQsIFZUKS5nZXRTaXplSW5CaXRzKCk7CisgICAgICByZXR1cm4gKEJpdFdpZHRoICsgUmVnV2lkdGggLSAxKSAvIFJlZ1dpZHRoOworICAgIH0KKyAgICBsbHZtX3VucmVhY2hhYmxlKCJVbnN1cHBvcnRlZCBleHRlbmRlZCB0eXBlISIpOworICB9CisKKyAgLy8vIENlcnRhaW4gY29tYmluYXRpb25zIG9mIEFCSXMsIFRhcmdldHMgYW5kIGZlYXR1cmVzIHJlcXVpcmUgdGhhdCB0eXBlcworICAvLy8gYXJlIGxlZ2FsIGZvciBzb21lIG9wZXJhdGlvbnMgYW5kIG5vdCBmb3Igb3RoZXIgb3BlcmF0aW9ucy4KKyAgLy8vIEZvciBNSVBTIGFsbCB2ZWN0b3IgdHlwZXMgbXVzdCBiZSBwYXNzZWQgdGhyb3VnaCB0aGUgaW50ZWdlciByZWdpc3RlciBzZXQuCisgIHZpcnR1YWwgTVZUIGdldFJlZ2lzdGVyVHlwZUZvckNhbGxpbmdDb252KE1WVCBWVCkgY29uc3QgeworICAgIHJldHVybiBnZXRSZWdpc3RlclR5cGUoVlQpOworICB9CisKKyAgdmlydHVhbCBNVlQgZ2V0UmVnaXN0ZXJUeXBlRm9yQ2FsbGluZ0NvbnYoTExWTUNvbnRleHQgJkNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVWVCBWVCkgY29uc3QgeworICAgIHJldHVybiBnZXRSZWdpc3RlclR5cGUoQ29udGV4dCwgVlQpOworICB9CisKKyAgLy8vIENlcnRhaW4gdGFyZ2V0cyByZXF1aXJlIHVudXN1YWwgYnJlYWtkb3ducyBvZiBjZXJ0YWluIHR5cGVzLiBGb3IgTUlQUywKKyAgLy8vIHRoaXMgb2NjdXJzIHdoZW4gYSB2ZWN0b3IgdHlwZSBpcyB1c2VkLCBhcyB2ZWN0b3IgYXJlIHBhc3NlZCB0aHJvdWdoIHRoZQorICAvLy8gaW50ZWdlciByZWdpc3RlciBzZXQuCisgIHZpcnR1YWwgdW5zaWduZWQgZ2V0TnVtUmVnaXN0ZXJzRm9yQ2FsbGluZ0NvbnYoTExWTUNvbnRleHQgJkNvbnRleHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVZUIFZUKSBjb25zdCB7CisgICAgcmV0dXJuIGdldE51bVJlZ2lzdGVycyhDb250ZXh0LCBWVCk7CisgIH0KKworICAvLy8gQ2VydGFpbiB0YXJnZXRzIGhhdmUgY29udGV4dCBzZW5zdGl2ZSBhbGlnbm1lbnQgcmVxdWlyZW1lbnRzLCB3aGVyZSBvbmUKKyAgLy8vIHR5cGUgaGFzIHRoZSBhbGlnbm1lbnQgcmVxdWlyZW1lbnQgb2YgYW5vdGhlciB0eXBlLgorICB2aXJ0dWFsIHVuc2lnbmVkIGdldEFCSUFsaWdubWVudEZvckNhbGxpbmdDb252KFR5cGUgKkFyZ1R5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGFMYXlvdXQgREwpIGNvbnN0IHsKKyAgICByZXR1cm4gREwuZ2V0QUJJVHlwZUFsaWdubWVudChBcmdUeSk7CisgIH0KKworICAvLy8gSWYgdHJ1ZSwgdGhlbiBpbnN0cnVjdGlvbiBzZWxlY3Rpb24gc2hvdWxkIHNlZWsgdG8gc2hyaW5rIHRoZSBGUCBjb25zdGFudAorICAvLy8gb2YgdGhlIHNwZWNpZmllZCB0eXBlIHRvIGEgc21hbGxlciB0eXBlIGluIG9yZGVyIHRvIHNhdmUgc3BhY2UgYW5kIC8gb3IKKyAgLy8vIHJlZHVjZSBydW50aW1lLgorICB2aXJ0dWFsIGJvb2wgU2hvdWxkU2hyaW5rRlBDb25zdGFudChFVlQpIGNvbnN0IHsgcmV0dXJuIHRydWU7IH0KKworICAvLyBSZXR1cm4gdHJ1ZSBpZiBpdCBpcyBwcm9maXRhYmxlIHRvIHJlZHVjZSB0aGUgZ2l2ZW4gbG9hZCBub2RlIHRvIGEgc21hbGxlcgorICAvLyB0eXBlLgorICAvLworICAvLyBlLmcuIChpMTYgKHRydW5jIChpMzIgKGxvYWQgeCkpKSAtPiBpMTYgbG9hZCB4IHNob3VsZCBiZSBwZXJmb3JtZWQKKyAgdmlydHVhbCBib29sIHNob3VsZFJlZHVjZUxvYWRXaWR0aChTRE5vZGUgKkxvYWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVNEOjpMb2FkRXh0VHlwZSBFeHRUeSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFVlQgTmV3VlQpIGNvbnN0IHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vLyBXaGVuIHNwbGl0dGluZyBhIHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgdHlwZSBpbnRvIHBhcnRzLCBkb2VzIHRoZSBMbworICAvLy8gb3IgSGkgcGFydCBjb21lIGZpcnN0PyAgVGhpcyB1c3VhbGx5IGZvbGxvd3MgdGhlIGVuZGlhbm5lc3MsIGV4Y2VwdAorICAvLy8gZm9yIHBwY2YxMjgsIHdoZXJlIHRoZSBIaSBwYXJ0IGFsd2F5cyBjb21lcyBmaXJzdC4KKyAgYm9vbCBoYXNCaWdFbmRpYW5QYXJ0T3JkZXJpbmcoRVZUIFZULCBjb25zdCBEYXRhTGF5b3V0ICZETCkgY29uc3QgeworICAgIHJldHVybiBETC5pc0JpZ0VuZGlhbigpIHx8IFZUID09IE1WVDo6cHBjZjEyODsKKyAgfQorCisgIC8vLyBJZiB0cnVlLCB0aGUgdGFyZ2V0IGhhcyBjdXN0b20gREFHIGNvbWJpbmUgdHJhbnNmb3JtYXRpb25zIHRoYXQgaXQgY2FuCisgIC8vLyBwZXJmb3JtIGZvciB0aGUgc3BlY2lmaWVkIG5vZGUuCisgIGJvb2wgaGFzVGFyZ2V0REFHQ29tYmluZShJU0Q6Ok5vZGVUeXBlIE5UKSBjb25zdCB7CisgICAgYXNzZXJ0KHVuc2lnbmVkKE5UID4+IDMpIDwgYXJyYXlfbGVuZ3Rob2YoVGFyZ2V0REFHQ29tYmluZUFycmF5KSk7CisgICAgcmV0dXJuIFRhcmdldERBR0NvbWJpbmVBcnJheVtOVCA+PiAzXSAmICgxIDw8IChOVCY3KSk7CisgIH0KKworICB1bnNpZ25lZCBnZXRHYXRoZXJBbGxBbGlhc2VzTWF4RGVwdGgoKSBjb25zdCB7CisgICAgcmV0dXJuIEdhdGhlckFsbEFsaWFzZXNNYXhEZXB0aDsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRoZSBzaXplIG9mIHRoZSBwbGF0Zm9ybSdzIHZhX2xpc3Qgb2JqZWN0LgorICB2aXJ0dWFsIHVuc2lnbmVkIGdldFZhTGlzdFNpemVJbkJpdHMoY29uc3QgRGF0YUxheW91dCAmREwpIGNvbnN0IHsKKyAgICByZXR1cm4gZ2V0UG9pbnRlclR5KERMKS5nZXRTaXplSW5CaXRzKCk7CisgIH0KKworICAvLy8gXGJyaWVmIEdldCBtYXhpbXVtICMgb2Ygc3RvcmUgb3BlcmF0aW9ucyBwZXJtaXR0ZWQgZm9yIGxsdm0ubWVtc2V0CisgIC8vLworICAvLy8gVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBtYXhpbXVtIG51bWJlciBvZiBzdG9yZSBvcGVyYXRpb25zIHBlcm1pdHRlZAorICAvLy8gdG8gcmVwbGFjZSBhIGNhbGwgdG8gbGx2bS5tZW1zZXQuIFRoZSB2YWx1ZSBpcyBzZXQgYnkgdGhlIHRhcmdldCBhdCB0aGUKKyAgLy8vIHBlcmZvcm1hbmNlIHRocmVzaG9sZCBmb3Igc3VjaCBhIHJlcGxhY2VtZW50LiBJZiBPcHRTaXplIGlzIHRydWUsCisgIC8vLyByZXR1cm4gdGhlIGxpbWl0IGZvciBmdW5jdGlvbnMgdGhhdCBoYXZlIE9wdFNpemUgYXR0cmlidXRlLgorICB1bnNpZ25lZCBnZXRNYXhTdG9yZXNQZXJNZW1zZXQoYm9vbCBPcHRTaXplKSBjb25zdCB7CisgICAgcmV0dXJuIE9wdFNpemUgPyBNYXhTdG9yZXNQZXJNZW1zZXRPcHRTaXplIDogTWF4U3RvcmVzUGVyTWVtc2V0OworICB9CisKKyAgLy8vIFxicmllZiBHZXQgbWF4aW11bSAjIG9mIHN0b3JlIG9wZXJhdGlvbnMgcGVybWl0dGVkIGZvciBsbHZtLm1lbWNweQorICAvLy8KKyAgLy8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgbWF4aW11bSBudW1iZXIgb2Ygc3RvcmUgb3BlcmF0aW9ucyBwZXJtaXR0ZWQKKyAgLy8vIHRvIHJlcGxhY2UgYSBjYWxsIHRvIGxsdm0ubWVtY3B5LiBUaGUgdmFsdWUgaXMgc2V0IGJ5IHRoZSB0YXJnZXQgYXQgdGhlCisgIC8vLyBwZXJmb3JtYW5jZSB0aHJlc2hvbGQgZm9yIHN1Y2ggYSByZXBsYWNlbWVudC4gSWYgT3B0U2l6ZSBpcyB0cnVlLAorICAvLy8gcmV0dXJuIHRoZSBsaW1pdCBmb3IgZnVuY3Rpb25zIHRoYXQgaGF2ZSBPcHRTaXplIGF0dHJpYnV0ZS4KKyAgdW5zaWduZWQgZ2V0TWF4U3RvcmVzUGVyTWVtY3B5KGJvb2wgT3B0U2l6ZSkgY29uc3QgeworICAgIHJldHVybiBPcHRTaXplID8gTWF4U3RvcmVzUGVyTWVtY3B5T3B0U2l6ZSA6IE1heFN0b3Jlc1Blck1lbWNweTsKKyAgfQorCisgIC8vLyBHZXQgbWF4aW11bSAjIG9mIGxvYWQgb3BlcmF0aW9ucyBwZXJtaXR0ZWQgZm9yIG1lbWNtcAorICAvLy8KKyAgLy8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgbWF4aW11bSBudW1iZXIgb2YgbG9hZCBvcGVyYXRpb25zIHBlcm1pdHRlZAorICAvLy8gdG8gcmVwbGFjZSBhIGNhbGwgdG8gbWVtY21wLiBUaGUgdmFsdWUgaXMgc2V0IGJ5IHRoZSB0YXJnZXQgYXQgdGhlCisgIC8vLyBwZXJmb3JtYW5jZSB0aHJlc2hvbGQgZm9yIHN1Y2ggYSByZXBsYWNlbWVudC4gSWYgT3B0U2l6ZSBpcyB0cnVlLAorICAvLy8gcmV0dXJuIHRoZSBsaW1pdCBmb3IgZnVuY3Rpb25zIHRoYXQgaGF2ZSBPcHRTaXplIGF0dHJpYnV0ZS4KKyAgdW5zaWduZWQgZ2V0TWF4RXhwYW5kU2l6ZU1lbWNtcChib29sIE9wdFNpemUpIGNvbnN0IHsKKyAgICByZXR1cm4gT3B0U2l6ZSA/IE1heExvYWRzUGVyTWVtY21wT3B0U2l6ZSA6IE1heExvYWRzUGVyTWVtY21wOworICB9CisKKyAgLy8vIEZvciBtZW1jbXAgZXhwYW5zaW9uIHdoZW4gdGhlIG1lbWNtcCByZXN1bHQgaXMgb25seSBjb21wYXJlZCBlcXVhbCBvcgorICAvLy8gbm90LWVxdWFsIHRvIDAsIGFsbG93IHVwIHRvIHRoaXMgbnVtYmVyIG9mIGxvYWQgcGFpcnMgcGVyIGJsb2NrLiBBcyBhbgorICAvLy8gZXhhbXBsZSwgdGhpcyBtYXkgYWxsb3cgJ21lbWNtcChhLCBiLCAzKSA9PSAwJyBpbiBhIHNpbmdsZSBibG9jazoKKyAgLy8vICAgYTAgPSBsb2FkMmJ5dGVzICZhWzBdCisgIC8vLyAgIGIwID0gbG9hZDJieXRlcyAmYlswXQorICAvLy8gICBhMiA9IGxvYWQxYnl0ZSAgJmFbMl0KKyAgLy8vICAgYjIgPSBsb2FkMWJ5dGUgICZiWzJdCisgIC8vLyAgIHIgID0gY21wIGVxIChhMCBeIGIwIHwgYTIgXiBiMiksIDAKKyAgdmlydHVhbCB1bnNpZ25lZCBnZXRNZW1jbXBFcVplcm9Mb2Fkc1BlckJsb2NrKCkgY29uc3QgeworICAgIHJldHVybiAxOworICB9CisKKyAgLy8vIFxicmllZiBHZXQgbWF4aW11bSAjIG9mIHN0b3JlIG9wZXJhdGlvbnMgcGVybWl0dGVkIGZvciBsbHZtLm1lbW1vdmUKKyAgLy8vCisgIC8vLyBUaGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIG1heGltdW0gbnVtYmVyIG9mIHN0b3JlIG9wZXJhdGlvbnMgcGVybWl0dGVkCisgIC8vLyB0byByZXBsYWNlIGEgY2FsbCB0byBsbHZtLm1lbW1vdmUuIFRoZSB2YWx1ZSBpcyBzZXQgYnkgdGhlIHRhcmdldCBhdCB0aGUKKyAgLy8vIHBlcmZvcm1hbmNlIHRocmVzaG9sZCBmb3Igc3VjaCBhIHJlcGxhY2VtZW50LiBJZiBPcHRTaXplIGlzIHRydWUsCisgIC8vLyByZXR1cm4gdGhlIGxpbWl0IGZvciBmdW5jdGlvbnMgdGhhdCBoYXZlIE9wdFNpemUgYXR0cmlidXRlLgorICB1bnNpZ25lZCBnZXRNYXhTdG9yZXNQZXJNZW1tb3ZlKGJvb2wgT3B0U2l6ZSkgY29uc3QgeworICAgIHJldHVybiBPcHRTaXplID8gTWF4U3RvcmVzUGVyTWVtbW92ZU9wdFNpemUgOiBNYXhTdG9yZXNQZXJNZW1tb3ZlOworICB9CisKKyAgLy8vIFxicmllZiBEZXRlcm1pbmUgaWYgdGhlIHRhcmdldCBzdXBwb3J0cyB1bmFsaWduZWQgbWVtb3J5IGFjY2Vzc2VzLgorICAvLy8KKyAgLy8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB0cnVlIGlmIHRoZSB0YXJnZXQgYWxsb3dzIHVuYWxpZ25lZCBtZW1vcnkgYWNjZXNzZXMKKyAgLy8vIG9mIHRoZSBzcGVjaWZpZWQgdHlwZSBpbiB0aGUgZ2l2ZW4gYWRkcmVzcyBzcGFjZS4gSWYgdHJ1ZSwgaXQgYWxzbyByZXR1cm5zCisgIC8vLyB3aGV0aGVyIHRoZSB1bmFsaWduZWQgbWVtb3J5IGFjY2VzcyBpcyAiZmFzdCIgaW4gdGhlIGxhc3QgYXJndW1lbnQgYnkKKyAgLy8vIHJlZmVyZW5jZS4gVGhpcyBpcyB1c2VkLCBmb3IgZXhhbXBsZSwgaW4gc2l0dWF0aW9ucyB3aGVyZSBhbiBhcnJheQorICAvLy8gY29weS9tb3ZlL3NldCBpcyBjb252ZXJ0ZWQgdG8gYSBzZXF1ZW5jZSBvZiBzdG9yZSBvcGVyYXRpb25zLiBJdHMgdXNlCisgIC8vLyBoZWxwcyB0byBlbnN1cmUgdGhhdCBzdWNoIHJlcGxhY2VtZW50cyBkb24ndCBnZW5lcmF0ZSBjb2RlIHRoYXQgY2F1c2VzIGFuCisgIC8vLyBhbGlnbm1lbnQgZXJyb3IgKHRyYXApIG9uIHRoZSB0YXJnZXQgbWFjaGluZS4KKyAgdmlydHVhbCBib29sIGFsbG93c01pc2FsaWduZWRNZW1vcnlBY2Nlc3NlcyhFVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgQWRkclNwYWNlID0gMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBBbGlnbiA9IDEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCAqIC8qRmFzdCovID0gbnVsbHB0cikgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgdGFyZ2V0IHN1cHBvcnRzIGEgbWVtb3J5IGFjY2VzcyBvZiB0aGlzIHR5cGUgZm9yIHRoZQorICAvLy8gZ2l2ZW4gYWRkcmVzcyBzcGFjZSBhbmQgYWxpZ25tZW50LiBJZiB0aGUgYWNjZXNzIGlzIGFsbG93ZWQsIHRoZSBvcHRpb25hbAorICAvLy8gZmluYWwgcGFyYW1ldGVyIHJldHVybnMgaWYgdGhlIGFjY2VzcyBpcyBhbHNvIGZhc3QgKGFzIGRlZmluZWQgYnkgdGhlCisgIC8vLyB0YXJnZXQpLgorICBib29sIGFsbG93c01lbW9yeUFjY2VzcyhMTFZNQ29udGV4dCAmQ29udGV4dCwgY29uc3QgRGF0YUxheW91dCAmREwsIEVWVCBWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgQWRkclNwYWNlID0gMCwgdW5zaWduZWQgQWxpZ25tZW50ID0gMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCAqRmFzdCA9IG51bGxwdHIpIGNvbnN0OworCisgIC8vLyBSZXR1cm5zIHRoZSB0YXJnZXQgc3BlY2lmaWMgb3B0aW1hbCB0eXBlIGZvciBsb2FkIGFuZCBzdG9yZSBvcGVyYXRpb25zIGFzCisgIC8vLyBhIHJlc3VsdCBvZiBtZW1zZXQsIG1lbWNweSwgYW5kIG1lbW1vdmUgbG93ZXJpbmcuCisgIC8vLworICAvLy8gSWYgRHN0QWxpZ24gaXMgemVybyB0aGF0IG1lYW5zIGl0J3Mgc2FmZSB0byBkZXN0aW5hdGlvbiBhbGlnbm1lbnQgY2FuCisgIC8vLyBzYXRpc2Z5IGFueSBjb25zdHJhaW50LiBTaW1pbGFybHkgaWYgU3JjQWxpZ24gaXMgemVybyBpdCBtZWFucyB0aGVyZSBpc24ndAorICAvLy8gYSBuZWVkIHRvIGNoZWNrIGl0IGFnYWluc3QgYWxpZ25tZW50IHJlcXVpcmVtZW50LCBwcm9iYWJseSBiZWNhdXNlIHRoZQorICAvLy8gc291cmNlIGRvZXMgbm90IG5lZWQgdG8gYmUgbG9hZGVkLiBJZiAnSXNNZW1zZXQnIGlzIHRydWUsIHRoYXQgbWVhbnMgaXQncworICAvLy8gZXhwYW5kaW5nIGEgbWVtc2V0LiBJZiAnWmVyb01lbXNldCcgaXMgdHJ1ZSwgdGhhdCBtZWFucyBpdCdzIGEgbWVtc2V0IG9mCisgIC8vLyB6ZXJvLiAnTWVtY3B5U3RyU3JjJyBpbmRpY2F0ZXMgd2hldGhlciB0aGUgbWVtY3B5IHNvdXJjZSBpcyBjb25zdGFudCBzbyBpdAorICAvLy8gZG9lcyBub3QgbmVlZCB0byBiZSBsb2FkZWQuICBJdCByZXR1cm5zIEVWVDo6T3RoZXIgaWYgdGhlIHR5cGUgc2hvdWxkIGJlCisgIC8vLyBkZXRlcm1pbmVkIHVzaW5nIGdlbmVyaWMgdGFyZ2V0LWluZGVwZW5kZW50IGxvZ2ljLgorICB2aXJ0dWFsIEVWVCBnZXRPcHRpbWFsTWVtT3BUeXBlKHVpbnQ2NF90IC8qU2l6ZSovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIC8qRHN0QWxpZ24qLywgdW5zaWduZWQgLypTcmNBbGlnbiovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgLypJc01lbXNldCovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgLypaZXJvTWVtc2V0Ki8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCAvKk1lbWNweVN0clNyYyovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVGdW5jdGlvbiAmLypNRiovKSBjb25zdCB7CisgICAgcmV0dXJuIE1WVDo6T3RoZXI7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIGl0J3Mgc2FmZSB0byB1c2UgbG9hZCAvIHN0b3JlIG9mIHRoZSBzcGVjaWZpZWQgdHlwZSB0bworICAvLy8gZXhwYW5kIG1lbWNweSAvIG1lbXNldCBpbmxpbmUuCisgIC8vLworICAvLy8gVGhpcyBpcyBtb3N0bHkgdHJ1ZSBmb3IgYWxsIHR5cGVzIGV4Y2VwdCBmb3Igc29tZSBzcGVjaWFsIGNhc2VzLiBGb3IKKyAgLy8vIGV4YW1wbGUsIG9uIFg4NiB0YXJnZXRzIHdpdGhvdXQgU1NFMiBmNjQgbG9hZCAvIHN0b3JlIGFyZSBkb25lIHdpdGggZmxkbCAvCisgIC8vLyBmc3RwbCB3aGljaCBhbHNvIGRvZXMgdHlwZSBjb252ZXJzaW9uLiBOb3RlIHRoZSBzcGVjaWZpZWQgdHlwZSBkb2Vzbid0CisgIC8vLyBoYXZlIHRvIGJlIGxlZ2FsIGFzIHRoZSBob29rIGlzIHVzZWQgYmVmb3JlIHR5cGUgbGVnYWxpemF0aW9uLgorICB2aXJ0dWFsIGJvb2wgaXNTYWZlTWVtT3BUeXBlKE1WVCAvKlZUKi8pIGNvbnN0IHsgcmV0dXJuIHRydWU7IH0KKworICAvLy8gRGV0ZXJtaW5lIGlmIHdlIHNob3VsZCB1c2UgX3NldGptcCBvciBzZXRqbXAgdG8gaW1wbGVtZW50IGxsdm0uc2V0am1wLgorICBib29sIHVzZXNVbmRlcnNjb3JlU2V0Sm1wKCkgY29uc3QgeworICAgIHJldHVybiBVc2VVbmRlcnNjb3JlU2V0Sm1wOworICB9CisKKyAgLy8vIERldGVybWluZSBpZiB3ZSBzaG91bGQgdXNlIF9sb25nam1wIG9yIGxvbmdqbXAgdG8gaW1wbGVtZW50IGxsdm0ubG9uZ2ptcC4KKyAgYm9vbCB1c2VzVW5kZXJzY29yZUxvbmdKbXAoKSBjb25zdCB7CisgICAgcmV0dXJuIFVzZVVuZGVyc2NvcmVMb25nSm1wOworICB9CisKKyAgLy8vIFJldHVybiBsb3dlciBsaW1pdCBmb3IgbnVtYmVyIG9mIGJsb2NrcyBpbiBhIGp1bXAgdGFibGUuCisgIHZpcnR1YWwgdW5zaWduZWQgZ2V0TWluaW11bUp1bXBUYWJsZUVudHJpZXMoKSBjb25zdDsKKworICAvLy8gUmV0dXJuIGxvd2VyIGxpbWl0IG9mIHRoZSBkZW5zaXR5IGluIGEganVtcCB0YWJsZS4KKyAgdW5zaWduZWQgZ2V0TWluaW11bUp1bXBUYWJsZURlbnNpdHkoYm9vbCBPcHRGb3JTaXplKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHVwcGVyIGxpbWl0IGZvciBudW1iZXIgb2YgZW50cmllcyBpbiBhIGp1bXAgdGFibGUuCisgIC8vLyBaZXJvIGlmIG5vIGxpbWl0LgorICB1bnNpZ25lZCBnZXRNYXhpbXVtSnVtcFRhYmxlU2l6ZSgpIGNvbnN0OworCisgIHZpcnR1YWwgYm9vbCBpc0p1bXBUYWJsZVJlbGF0aXZlKCkgY29uc3QgeworICAgIHJldHVybiBUTS5pc1Bvc2l0aW9uSW5kZXBlbmRlbnQoKTsKKyAgfQorCisgIC8vLyBJZiBhIHBoeXNpY2FsIHJlZ2lzdGVyLCB0aGlzIHNwZWNpZmllcyB0aGUgcmVnaXN0ZXIgdGhhdAorICAvLy8gbGx2bS5zYXZlc3RhY2svbGx2bS5yZXN0b3Jlc3RhY2sgc2hvdWxkIHNhdmUgYW5kIHJlc3RvcmUuCisgIHVuc2lnbmVkIGdldFN0YWNrUG9pbnRlclJlZ2lzdGVyVG9TYXZlUmVzdG9yZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gU3RhY2tQb2ludGVyUmVnaXN0ZXJUb1NhdmVSZXN0b3JlOworICB9CisKKyAgLy8vIElmIGEgcGh5c2ljYWwgcmVnaXN0ZXIsIHRoaXMgcmV0dXJucyB0aGUgcmVnaXN0ZXIgdGhhdCByZWNlaXZlcyB0aGUKKyAgLy8vIGV4Y2VwdGlvbiBhZGRyZXNzIG9uIGVudHJ5IHRvIGFuIEVIIHBhZC4KKyAgdmlydHVhbCB1bnNpZ25lZAorICBnZXRFeGNlcHRpb25Qb2ludGVyUmVnaXN0ZXIoY29uc3QgQ29uc3RhbnQgKlBlcnNvbmFsaXR5Rm4pIGNvbnN0IHsKKyAgICAvLyAwIGlzIGd1YXJhbnRlZWQgdG8gYmUgdGhlIE5vUmVnaXN0ZXIgdmFsdWUgb24gYWxsIHRhcmdldHMKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIC8vLyBJZiBhIHBoeXNpY2FsIHJlZ2lzdGVyLCB0aGlzIHJldHVybnMgdGhlIHJlZ2lzdGVyIHRoYXQgcmVjZWl2ZXMgdGhlCisgIC8vLyBleGNlcHRpb24gdHlwZWlkIG9uIGVudHJ5IHRvIGEgbGFuZGluZyBwYWQuCisgIHZpcnR1YWwgdW5zaWduZWQKKyAgZ2V0RXhjZXB0aW9uU2VsZWN0b3JSZWdpc3Rlcihjb25zdCBDb25zdGFudCAqUGVyc29uYWxpdHlGbikgY29uc3QgeworICAgIC8vIDAgaXMgZ3VhcmFudGVlZCB0byBiZSB0aGUgTm9SZWdpc3RlciB2YWx1ZSBvbiBhbGwgdGFyZ2V0cworICAgIHJldHVybiAwOworICB9CisKKyAgdmlydHVhbCBib29sIG5lZWRzRml4ZWRDYXRjaE9iamVjdHMoKSBjb25zdCB7CisgICAgcmVwb3J0X2ZhdGFsX2Vycm9yKCJGdW5jbGV0IEVIIGlzIG5vdCBpbXBsZW1lbnRlZCBmb3IgdGhpcyB0YXJnZXQiKTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRoZSB0YXJnZXQncyBqbXBfYnVmIHNpemUgaW4gYnl0ZXMgKGlmIG5ldmVyIHNldCwgdGhlIGRlZmF1bHQgaXMKKyAgLy8vIDIwMCkKKyAgdW5zaWduZWQgZ2V0SnVtcEJ1ZlNpemUoKSBjb25zdCB7CisgICAgcmV0dXJuIEp1bXBCdWZTaXplOworICB9CisKKyAgLy8vIFJldHVybnMgdGhlIHRhcmdldCdzIGptcF9idWYgYWxpZ25tZW50IGluIGJ5dGVzIChpZiBuZXZlciBzZXQsIHRoZSBkZWZhdWx0CisgIC8vLyBpcyAwKQorICB1bnNpZ25lZCBnZXRKdW1wQnVmQWxpZ25tZW50KCkgY29uc3QgeworICAgIHJldHVybiBKdW1wQnVmQWxpZ25tZW50OworICB9CisKKyAgLy8vIFJldHVybiB0aGUgbWluaW11bSBzdGFjayBhbGlnbm1lbnQgb2YgYW4gYXJndW1lbnQuCisgIHVuc2lnbmVkIGdldE1pblN0YWNrQXJndW1lbnRBbGlnbm1lbnQoKSBjb25zdCB7CisgICAgcmV0dXJuIE1pblN0YWNrQXJndW1lbnRBbGlnbm1lbnQ7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBtaW5pbXVtIGZ1bmN0aW9uIGFsaWdubWVudC4KKyAgdW5zaWduZWQgZ2V0TWluRnVuY3Rpb25BbGlnbm1lbnQoKSBjb25zdCB7CisgICAgcmV0dXJuIE1pbkZ1bmN0aW9uQWxpZ25tZW50OworICB9CisKKyAgLy8vIFJldHVybiB0aGUgcHJlZmVycmVkIGZ1bmN0aW9uIGFsaWdubWVudC4KKyAgdW5zaWduZWQgZ2V0UHJlZkZ1bmN0aW9uQWxpZ25tZW50KCkgY29uc3QgeworICAgIHJldHVybiBQcmVmRnVuY3Rpb25BbGlnbm1lbnQ7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBwcmVmZXJyZWQgbG9vcCBhbGlnbm1lbnQuCisgIHZpcnR1YWwgdW5zaWduZWQgZ2V0UHJlZkxvb3BBbGlnbm1lbnQoTWFjaGluZUxvb3AgKk1MID0gbnVsbHB0cikgY29uc3QgeworICAgIHJldHVybiBQcmVmTG9vcEFsaWdubWVudDsKKyAgfQorCisgIC8vLyBJZiB0aGUgdGFyZ2V0IGhhcyBhIHN0YW5kYXJkIGxvY2F0aW9uIGZvciB0aGUgc3RhY2sgcHJvdGVjdG9yIGd1YXJkLAorICAvLy8gcmV0dXJucyB0aGUgYWRkcmVzcyBvZiB0aGF0IGxvY2F0aW9uLiBPdGhlcndpc2UsIHJldHVybnMgbnVsbHB0ci4KKyAgLy8vIERFUFJFQ0FURUQ6IHBsZWFzZSBvdmVycmlkZSB1c2VMb2FkU3RhY2tHdWFyZE5vZGUgYW5kIGN1c3RvbWl6ZQorICAvLy8gICAgICAgICAgICAgTE9BRF9TVEFDS19HVUFSRCwgb3IgY3VzdG9taXplIEBsbHZtLnN0YWNrZ3VhcmQoKS4KKyAgdmlydHVhbCBWYWx1ZSAqZ2V0SVJTdGFja0d1YXJkKElSQnVpbGRlcjw+ICZJUkIpIGNvbnN0OworCisgIC8vLyBJbnNlcnRzIG5lY2Vzc2FyeSBkZWNsYXJhdGlvbnMgZm9yIFNTUCAoc3RhY2sgcHJvdGVjdGlvbikgcHVycG9zZS4KKyAgLy8vIFNob3VsZCBiZSB1c2VkIG9ubHkgd2hlbiBnZXRJUlN0YWNrR3VhcmQgcmV0dXJucyBudWxscHRyLgorICB2aXJ0dWFsIHZvaWQgaW5zZXJ0U1NQRGVjbGFyYXRpb25zKE1vZHVsZSAmTSkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0aGUgdmFyaWFibGUgdGhhdCdzIHByZXZpb3VzbHkgaW5zZXJ0ZWQgYnkgaW5zZXJ0U1NQRGVjbGFyYXRpb25zLAorICAvLy8gaWYgYW55LCBvdGhlcndpc2UgcmV0dXJuIG51bGxwdHIuIFNob3VsZCBiZSB1c2VkIG9ubHkgd2hlbgorICAvLy8gZ2V0SVJTdGFja0d1YXJkIHJldHVybnMgbnVsbHB0ci4KKyAgdmlydHVhbCBWYWx1ZSAqZ2V0U0RhZ1N0YWNrR3VhcmQoY29uc3QgTW9kdWxlICZNKSBjb25zdDsKKworICAvLy8gSWYgdGhpcyBmdW5jdGlvbiByZXR1cm5zIHRydWUsIHN0YWNrIHByb3RlY3Rpb24gY2hlY2tzIHNob3VsZCBYT1IgdGhlCisgIC8vLyBmcmFtZSBwb2ludGVyIChvciB3aGljaGV2ZXIgcG9pbnRlciBpcyB1c2VkIHRvIGFkZHJlc3MgbG9jYWxzKSBpbnRvIHRoZQorICAvLy8gc3RhY2sgZ3VhcmQgdmFsdWUgYmVmb3JlIGNoZWNraW5nIGl0LiBnZXRJUlN0YWNrR3VhcmQgbXVzdCByZXR1cm4gbnVsbHB0cgorICAvLy8gaWYgdGhpcyByZXR1cm5zIHRydWUuCisgIHZpcnR1YWwgYm9vbCB1c2VTdGFja0d1YXJkWG9yRlAoKSBjb25zdCB7IHJldHVybiBmYWxzZTsgfQorCisgIC8vLyBJZiB0aGUgdGFyZ2V0IGhhcyBhIHN0YW5kYXJkIHN0YWNrIHByb3RlY3Rpb24gY2hlY2sgZnVuY3Rpb24gdGhhdAorICAvLy8gcGVyZm9ybXMgdmFsaWRhdGlvbiBhbmQgZXJyb3IgaGFuZGxpbmcsIHJldHVybnMgdGhlIGZ1bmN0aW9uLiBPdGhlcndpc2UsCisgIC8vLyByZXR1cm5zIG51bGxwdHIuIE11c3QgYmUgcHJldmlvdXNseSBpbnNlcnRlZCBieSBpbnNlcnRTU1BEZWNsYXJhdGlvbnMuCisgIC8vLyBTaG91bGQgYmUgdXNlZCBvbmx5IHdoZW4gZ2V0SVJTdGFja0d1YXJkIHJldHVybnMgbnVsbHB0ci4KKyAgdmlydHVhbCBWYWx1ZSAqZ2V0U1NQU3RhY2tHdWFyZENoZWNrKGNvbnN0IE1vZHVsZSAmTSkgY29uc3Q7CisKK3Byb3RlY3RlZDoKKyAgVmFsdWUgKmdldERlZmF1bHRTYWZlU3RhY2tQb2ludGVyTG9jYXRpb24oSVJCdWlsZGVyPD4gJklSQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBVc2VUTFMpIGNvbnN0OworCitwdWJsaWM6CisgIC8vLyBSZXR1cm5zIHRoZSB0YXJnZXQtc3BlY2lmaWMgYWRkcmVzcyBvZiB0aGUgdW5zYWZlIHN0YWNrIHBvaW50ZXIuCisgIHZpcnR1YWwgVmFsdWUgKmdldFNhZmVTdGFja1BvaW50ZXJMb2NhdGlvbihJUkJ1aWxkZXI8PiAmSVJCKSBjb25zdDsKKworICAvLy8gUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgc3ltYm9sIHVzZWQgdG8gZW1pdCBzdGFjayBwcm9iZXMgb3IgdGhlIGVtcHR5CisgIC8vLyBzdHJpbmcgaWYgbm90IGFwcGxpY2FibGUuCisgIHZpcnR1YWwgU3RyaW5nUmVmIGdldFN0YWNrUHJvYmVTeW1ib2xOYW1lKE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0IHsKKyAgICByZXR1cm4gIiI7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIGEgY2FzdCBiZXR3ZWVuIFNyY0FTIGFuZCBEZXN0QVMgaXMgYSBub29wLgorICB2aXJ0dWFsIGJvb2wgaXNOb29wQWRkclNwYWNlQ2FzdCh1bnNpZ25lZCBTcmNBUywgdW5zaWduZWQgRGVzdEFTKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiBhIGNhc3QgZnJvbSBTcmNBUyB0byBEZXN0QVMgaXMgImNoZWFwIiwgc3VjaCB0aGF0IGUuZy4gd2UKKyAgLy8vIGFyZSBoYXBweSB0byBzaW5rIGl0IGludG8gYmFzaWMgYmxvY2tzLgorICB2aXJ0dWFsIGJvb2wgaXNDaGVhcEFkZHJTcGFjZUNhc3QodW5zaWduZWQgU3JjQVMsIHVuc2lnbmVkIERlc3RBUykgY29uc3QgeworICAgIHJldHVybiBpc05vb3BBZGRyU3BhY2VDYXN0KFNyY0FTLCBEZXN0QVMpOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBwb2ludGVyIGFyZ3VtZW50cyB0byBDSSBzaG91bGQgYmUgYWxpZ25lZCBieSBhbGlnbmluZworICAvLy8gdGhlIG9iamVjdCB3aG9zZSBhZGRyZXNzIGlzIGJlaW5nIHBhc3NlZC4gSWYgc28gdGhlbiBNaW5TaXplIGlzIHNldCB0byB0aGUKKyAgLy8vIG1pbmltdW0gc2l6ZSB0aGUgb2JqZWN0IG11c3QgYmUgdG8gYmUgYWxpZ25lZCBhbmQgUHJlZkFsaWduIGlzIHNldCB0byB0aGUKKyAgLy8vIHByZWZlcnJlZCBhbGlnbm1lbnQuCisgIHZpcnR1YWwgYm9vbCBzaG91bGRBbGlnblBvaW50ZXJBcmdzKENhbGxJbnN0ICogLypDSSovLCB1bnNpZ25lZCAmIC8qTWluU2l6ZSovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCAmIC8qUHJlZkFsaWduKi8pIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8vIFxuYW1lIEhlbHBlcnMgZm9yIFRhcmdldFRyYW5zZm9ybUluZm8gaW1wbGVtZW50YXRpb25zCisgIC8vLyBAeworCisgIC8vLyBHZXQgdGhlIElTRCBub2RlIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIEluc3RydWN0aW9uIGNsYXNzIG9wY29kZS4KKyAgaW50IEluc3RydWN0aW9uT3Bjb2RlVG9JU0QodW5zaWduZWQgT3Bjb2RlKSBjb25zdDsKKworICAvLy8gRXN0aW1hdGUgdGhlIGNvc3Qgb2YgdHlwZS1sZWdhbGl6YXRpb24gYW5kIHRoZSBsZWdhbGl6ZWQgdHlwZS4KKyAgc3RkOjpwYWlyPGludCwgTVZUPiBnZXRUeXBlTGVnYWxpemF0aW9uQ29zdChjb25zdCBEYXRhTGF5b3V0ICZETCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlICpUeSkgY29uc3Q7CisKKyAgLy8vIEB9CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vLyBcbmFtZSBIZWxwZXJzIGZvciBhdG9taWMgZXhwYW5zaW9uLgorICAvLy8gQHsKKworICAvLy8gUmV0dXJucyB0aGUgbWF4aW11bSBhdG9taWMgb3BlcmF0aW9uIHNpemUgKGluIGJpdHMpIHN1cHBvcnRlZCBieQorICAvLy8gdGhlIGJhY2tlbmQuIEF0b21pYyBvcGVyYXRpb25zIGdyZWF0ZXIgdGhhbiB0aGlzIHNpemUgKGFzIHdlbGwKKyAgLy8vIGFzIG9uZXMgdGhhdCBhcmUgbm90IG5hdHVyYWxseSBhbGlnbmVkKSwgd2lsbCBiZSBleHBhbmRlZCBieQorICAvLy8gQXRvbWljRXhwYW5kUGFzcyBpbnRvIGFuIF9fYXRvbWljXyogbGlicmFyeSBjYWxsLgorICB1bnNpZ25lZCBnZXRNYXhBdG9taWNTaXplSW5CaXRzU3VwcG9ydGVkKCkgY29uc3QgeworICAgIHJldHVybiBNYXhBdG9taWNTaXplSW5CaXRzU3VwcG9ydGVkOworICB9CisKKyAgLy8vIFJldHVybnMgdGhlIHNpemUgb2YgdGhlIHNtYWxsZXN0IGNtcHhjaGcgb3IgbGwvc2MgaW5zdHJ1Y3Rpb24KKyAgLy8vIHRoZSBiYWNrZW5kIHN1cHBvcnRzLiAgQW55IHNtYWxsZXIgb3BlcmF0aW9ucyBhcmUgd2lkZW5lZCBpbgorICAvLy8gQXRvbWljRXhwYW5kUGFzcy4KKyAgLy8vCisgIC8vLyBOb3RlIHRoYXQgKnVubGlrZSogb3BlcmF0aW9ucyBhYm92ZSB0aGUgbWF4aW11bSBzaXplLCBhdG9taWMgb3BzCisgIC8vLyBhcmUgc3RpbGwgbmF0aXZlbHkgc3VwcG9ydGVkIGJlbG93IHRoZSBtaW5pbXVtOyB0aGV5IGp1c3QKKyAgLy8vIHJlcXVpcmUgYSBtb3JlIGNvbXBsZXggZXhwYW5zaW9uLgorICB1bnNpZ25lZCBnZXRNaW5DbXBYY2hnU2l6ZUluQml0cygpIGNvbnN0IHsgcmV0dXJuIE1pbkNtcFhjaGdTaXplSW5CaXRzOyB9CisKKyAgLy8vIFdoZXRoZXIgdGhlIHRhcmdldCBzdXBwb3J0cyB1bmFsaWduZWQgYXRvbWljIG9wZXJhdGlvbnMuCisgIGJvb2wgc3VwcG9ydHNVbmFsaWduZWRBdG9taWNzKCkgY29uc3QgeyByZXR1cm4gU3VwcG9ydHNVbmFsaWduZWRBdG9taWNzOyB9CisKKyAgLy8vIFdoZXRoZXIgQXRvbWljRXhwYW5kUGFzcyBzaG91bGQgYXV0b21hdGljYWxseSBpbnNlcnQgZmVuY2VzIGFuZCByZWR1Y2UKKyAgLy8vIG9yZGVyaW5nIGZvciB0aGlzIGF0b21pYy4gVGhpcyBzaG91bGQgYmUgdHJ1ZSBmb3IgbW9zdCBhcmNoaXRlY3R1cmVzIHdpdGgKKyAgLy8vIHdlYWsgbWVtb3J5IG9yZGVyaW5nLiBEZWZhdWx0cyB0byBmYWxzZS4KKyAgdmlydHVhbCBib29sIHNob3VsZEluc2VydEZlbmNlc0ZvckF0b21pYyhjb25zdCBJbnN0cnVjdGlvbiAqSSkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBQZXJmb3JtIGEgbG9hZC1saW5rZWQgb3BlcmF0aW9uIG9uIEFkZHIsIHJldHVybmluZyBhICJWYWx1ZSAqIiB3aXRoIHRoZQorICAvLy8gY29ycmVzcG9uZGluZyBwb2ludGVlIHR5cGUuIFRoaXMgbWF5IGVudGFpbCBzb21lIG5vbi10cml2aWFsIG9wZXJhdGlvbnMgdG8KKyAgLy8vIHRydW5jYXRlIG9yIHJlY29uc3RydWN0IHR5cGVzIHRoYXQgd2lsbCBiZSBpbGxlZ2FsIGluIHRoZSBiYWNrZW5kLiBTZWUKKyAgLy8vIEFSTUlTZWxMb3dlcmluZyBmb3IgYW4gZXhhbXBsZSBpbXBsZW1lbnRhdGlvbi4KKyAgdmlydHVhbCBWYWx1ZSAqZW1pdExvYWRMaW5rZWQoSVJCdWlsZGVyPD4gJkJ1aWxkZXIsIFZhbHVlICpBZGRyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdG9taWNPcmRlcmluZyBPcmQpIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJMb2FkIGxpbmtlZCB1bmltcGxlbWVudGVkIG9uIHRoaXMgdGFyZ2V0Iik7CisgIH0KKworICAvLy8gUGVyZm9ybSBhIHN0b3JlLWNvbmRpdGlvbmFsIG9wZXJhdGlvbiB0byBBZGRyLiBSZXR1cm4gdGhlIHN0YXR1cyBvZiB0aGUKKyAgLy8vIHN0b3JlLiBUaGlzIHNob3VsZCBiZSAwIGlmIHRoZSBzdG9yZSBzdWNjZWVkZWQsIG5vbi16ZXJvIG90aGVyd2lzZS4KKyAgdmlydHVhbCBWYWx1ZSAqZW1pdFN0b3JlQ29uZGl0aW9uYWwoSVJCdWlsZGVyPD4gJkJ1aWxkZXIsIFZhbHVlICpWYWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlICpBZGRyLCBBdG9taWNPcmRlcmluZyBPcmQpIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJTdG9yZSBjb25kaXRpb25hbCB1bmltcGxlbWVudGVkIG9uIHRoaXMgdGFyZ2V0Iik7CisgIH0KKworICAvLy8gSW5zZXJ0cyBpbiB0aGUgSVIgYSB0YXJnZXQtc3BlY2lmaWMgaW50cmluc2ljIHNwZWNpZnlpbmcgYSBmZW5jZS4KKyAgLy8vIEl0IGlzIGNhbGxlZCBieSBBdG9taWNFeHBhbmRQYXNzIGJlZm9yZSBleHBhbmRpbmcgYW4KKyAgLy8vICAgQXRvbWljUk1XL0F0b21pY0NtcFhjaGcvQXRvbWljU3RvcmUvQXRvbWljTG9hZAorICAvLy8gICBpZiBzaG91bGRJbnNlcnRGZW5jZXNGb3JBdG9taWMgcmV0dXJucyB0cnVlLgorICAvLy8KKyAgLy8vIEluc3QgaXMgdGhlIG9yaWdpbmFsIGF0b21pYyBpbnN0cnVjdGlvbiwgcHJpb3IgdG8gb3RoZXIgZXhwYW5zaW9ucyB0aGF0CisgIC8vLyBtYXkgYmUgcGVyZm9ybWVkLgorICAvLy8KKyAgLy8vIFRoaXMgZnVuY3Rpb24gc2hvdWxkIGVpdGhlciByZXR1cm4gYSBudWxscHRyLCBvciBhIHBvaW50ZXIgdG8gYW4gSVItbGV2ZWwKKyAgLy8vICAgSW5zdHJ1Y3Rpb24qLiBFdmVuIGNvbXBsZXggZmVuY2Ugc2VxdWVuY2VzIGNhbiBiZSByZXByZXNlbnRlZCBieSBhCisgIC8vLyAgIHNpbmdsZSBJbnN0cnVjdGlvbiogdGhyb3VnaCBhbiBpbnRyaW5zaWMgdG8gYmUgbG93ZXJlZCBsYXRlci4KKyAgLy8vIEJhY2tlbmRzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byBwcm9kdWNlIHRhcmdldC1zcGVjaWZpYyBpbnRyaW5zaWMKKyAgLy8vICAgZm9yIHRoZWlyIGZlbmNlcy4KKyAgLy8vIEZJWE1FOiBQbGVhc2Ugbm90ZSB0aGF0IHRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGhlcmUgaW4gdGVybXMgb2YKKyAgLy8vICAgSVItbGV2ZWwgZmVuY2VzIGV4aXN0cyBmb3IgaGlzdG9yaWNhbC9jb21wYXRpYmlsaXR5IHJlYXNvbnMgYW5kIGlzCisgIC8vLyAgICp1bnNvdW5kKiAhIEZlbmNlcyBjYW5ub3QsIGluIGdlbmVyYWwsIGJlIHVzZWQgdG8gcmVzdG9yZSBzZXF1ZW50aWFsCisgIC8vLyAgIGNvbnNpc3RlbmN5LiBGb3IgZXhhbXBsZSwgY29uc2lkZXIgdGhlIGZvbGxvd2luZyBleGFtcGxlOgorICAvLy8gYXRvbWljPGludD4geCA9IHkgPSAwOworICAvLy8gaW50IHIxLCByMiwgcjMsIHI0OworICAvLy8gVGhyZWFkIDA6CisgIC8vLyAgIHguc3RvcmUoMSk7CisgIC8vLyBUaHJlYWQgMToKKyAgLy8vICAgeS5zdG9yZSgxKTsKKyAgLy8vIFRocmVhZCAyOgorICAvLy8gICByMSA9IHgubG9hZCgpOworICAvLy8gICByMiA9IHkubG9hZCgpOworICAvLy8gVGhyZWFkIDM6CisgIC8vLyAgIHIzID0geS5sb2FkKCk7CisgIC8vLyAgIHI0ID0geC5sb2FkKCk7CisgIC8vLyAgcjEgPSByMyA9IDEgYW5kIHIyID0gcjQgPSAwIGlzIGltcG9zc2libGUgYXMgbG9uZyBhcyB0aGUgYWNjZXNzZXMgYXJlIGFsbAorICAvLy8gIHNlcV9jc3QuIEJ1dCBpZiB0aGV5IGFyZSBsb3dlcmVkIHRvIG1vbm90b25pYyBhY2Nlc3Nlcywgbm8gYW1vdW50IG9mCisgIC8vLyAgSVItbGV2ZWwgZmVuY2VzIGNhbiBwcmV2ZW50IGl0LgorICAvLy8gQHsKKyAgdmlydHVhbCBJbnN0cnVjdGlvbiAqZW1pdExlYWRpbmdGZW5jZShJUkJ1aWxkZXI8PiAmQnVpbGRlciwgSW5zdHJ1Y3Rpb24gKkluc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljT3JkZXJpbmcgT3JkKSBjb25zdCB7CisgICAgaWYgKGlzUmVsZWFzZU9yU3Ryb25nZXIoT3JkKSAmJiBJbnN0LT5oYXNBdG9taWNTdG9yZSgpKQorICAgICAgcmV0dXJuIEJ1aWxkZXIuQ3JlYXRlRmVuY2UoT3JkKTsKKyAgICBlbHNlCisgICAgICByZXR1cm4gbnVsbHB0cjsKKyAgfQorCisgIHZpcnR1YWwgSW5zdHJ1Y3Rpb24gKmVtaXRUcmFpbGluZ0ZlbmNlKElSQnVpbGRlcjw+ICZCdWlsZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN0cnVjdGlvbiAqSW5zdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXRvbWljT3JkZXJpbmcgT3JkKSBjb25zdCB7CisgICAgaWYgKGlzQWNxdWlyZU9yU3Ryb25nZXIoT3JkKSkKKyAgICAgIHJldHVybiBCdWlsZGVyLkNyZWF0ZUZlbmNlKE9yZCk7CisgICAgZWxzZQorICAgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKyAgLy8vIEB9CisKKyAgLy8gRW1pdHMgY29kZSB0aGF0IGV4ZWN1dGVzIHdoZW4gdGhlIGNvbXBhcmlzb24gcmVzdWx0IGluIHRoZSBsbC9zYworICAvLyBleHBhbnNpb24gb2YgYSBjbXB4Y2hnIGluc3RydWN0aW9uIGlzIHN1Y2ggdGhhdCB0aGUgc3RvcmUtY29uZGl0aW9uYWwgd2lsbAorICAvLyBub3QgZXhlY3V0ZS4gIFRoaXMgbWFrZXMgaXQgcG9zc2libGUgdG8gYmFsYW5jZSBvdXQgdGhlIGxvYWQtbGlua2VkIHdpdGgKKyAgLy8gYSBkZWRpY2F0ZWQgaW5zdHJ1Y3Rpb24sIGlmIGRlc2lyZWQuCisgIC8vIEUuZy4sIG9uIEFSTSwgaWYgbGRyZXggaXNuJ3QgZm9sbG93ZWQgYnkgc3RyZXgsIHRoZSBleGNsdXNpdmUgbW9uaXRvciB3b3VsZAorICAvLyBiZSB1bm5lY2Vzc2FyaWx5IGhlbGQsIGV4Y2VwdCBpZiBjbHJleCwgaW5zZXJ0ZWQgYnkgdGhpcyBob29rLCBpcyBleGVjdXRlZC4KKyAgdmlydHVhbCB2b2lkIGVtaXRBdG9taWNDbXBYY2hnTm9TdG9yZUxMQmFsYW5jZShJUkJ1aWxkZXI8PiAmQnVpbGRlcikgY29uc3Qge30KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiAoYXRvbWljKSBzdG9yZSBzaG91bGQgYmUgZXhwYW5kZWQgYnkgdGhlCisgIC8vLyBJUi1sZXZlbCBBdG9taWNFeHBhbmQgcGFzcyBpbnRvIGFuICJhdG9taWMgeGNoZyIgd2hpY2ggaWdub3JlcyBpdHMgaW5wdXQuCisgIHZpcnR1YWwgYm9vbCBzaG91bGRFeHBhbmRBdG9taWNTdG9yZUluSVIoU3RvcmVJbnN0ICpTSSkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgYXJndW1lbnRzIHNob3VsZCBiZSBzaWduLWV4dGVuZGVkIGluIGxpYiBjYWxscy4KKyAgdmlydHVhbCBib29sIHNob3VsZFNpZ25FeHRlbmRUeXBlSW5MaWJDYWxsKEVWVCBUeXBlLCBib29sIElzU2lnbmVkKSBjb25zdCB7CisgICAgcmV0dXJuIElzU2lnbmVkOworICB9CisKKyAgLy8vIFJldHVybnMgaG93IHRoZSBnaXZlbiAoYXRvbWljKSBsb2FkIHNob3VsZCBiZSBleHBhbmRlZCBieSB0aGUKKyAgLy8vIElSLWxldmVsIEF0b21pY0V4cGFuZCBwYXNzLgorICB2aXJ0dWFsIEF0b21pY0V4cGFuc2lvbktpbmQgc2hvdWxkRXhwYW5kQXRvbWljTG9hZEluSVIoTG9hZEluc3QgKkxJKSBjb25zdCB7CisgICAgcmV0dXJuIEF0b21pY0V4cGFuc2lvbktpbmQ6Ok5vbmU7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBhdG9taWMgY21weGNoZyBzaG91bGQgYmUgZXhwYW5kZWQgYnkgdGhlCisgIC8vLyBJUi1sZXZlbCBBdG9taWNFeHBhbmQgcGFzcyBpbnRvIGEgbG9hZC1saW5rZWQvc3RvcmUtY29uZGl0aW9uYWwgc2VxdWVuY2UKKyAgLy8vICh0aHJvdWdoIGVtaXRMb2FkTGlua2VkKCkgYW5kIGVtaXRTdG9yZUNvbmRpdGlvbmFsKCkpLgorICB2aXJ0dWFsIGJvb2wgc2hvdWxkRXhwYW5kQXRvbWljQ21wWGNoZ0luSVIoQXRvbWljQ21wWGNoZ0luc3QgKkFJKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybnMgaG93IHRoZSBJUi1sZXZlbCBBdG9taWNFeHBhbmQgcGFzcyBzaG91bGQgZXhwYW5kIHRoZSBnaXZlbgorICAvLy8gQXRvbWljUk1XLCBpZiBhdCBhbGwuIERlZmF1bHQgaXMgdG8gbmV2ZXIgZXhwYW5kLgorICB2aXJ0dWFsIEF0b21pY0V4cGFuc2lvbktpbmQgc2hvdWxkRXhwYW5kQXRvbWljUk1XSW5JUihBdG9taWNSTVdJbnN0ICopIGNvbnN0IHsKKyAgICByZXR1cm4gQXRvbWljRXhwYW5zaW9uS2luZDo6Tm9uZTsKKyAgfQorCisgIC8vLyBPbiBzb21lIHBsYXRmb3JtcywgYW4gQXRvbWljUk1XIHRoYXQgbmV2ZXIgYWN0dWFsbHkgbW9kaWZpZXMgdGhlIHZhbHVlCisgIC8vLyAoc3VjaCBhcyBmZXRjaF9hZGQgb2YgMCkgY2FuIGJlIHR1cm5lZCBpbnRvIGEgZmVuY2UgZm9sbG93ZWQgYnkgYW4KKyAgLy8vIGF0b21pYyBsb2FkLiBUaGlzIG1heSBzb3VuZCB1c2VsZXNzLCBidXQgaXQgbWFrZXMgaXQgcG9zc2libGUgZm9yIHRoZQorICAvLy8gcHJvY2Vzc29yIHRvIGtlZXAgdGhlIGNhY2hlbGluZSBzaGFyZWQsIGRyYW1hdGljYWxseSBpbXByb3ZpbmcKKyAgLy8vIHBlcmZvcm1hbmNlLiBBbmQgc3VjaCBpZGVtcG90ZW50IFJNV3MgYXJlIHVzZWZ1bCBmb3IgaW1wbGVtZW50aW5nIHNvbWUKKyAgLy8vIGtpbmRzIG9mIGxvY2tzLCBzZWUgZm9yIGV4YW1wbGUgKGp1c3RpZmljYXRpb24gKyBiZW5jaG1hcmtzKToKKyAgLy8vIGh0dHA6Ly93d3cuaHBsLmhwLmNvbS90ZWNocmVwb3J0cy8yMDEyL0hQTC0yMDEyLTY4LnBkZgorICAvLy8gVGhpcyBtZXRob2QgdHJpZXMgZG9pbmcgdGhhdCB0cmFuc2Zvcm1hdGlvbiwgcmV0dXJuaW5nIHRoZSBhdG9taWMgbG9hZCBpZgorICAvLy8gaXQgc3VjY2VlZHMsIGFuZCBudWxscHRyIG90aGVyd2lzZS4KKyAgLy8vIElmIHNob3VsZEV4cGFuZEF0b21pY0xvYWRJbklSIHJldHVybnMgdHJ1ZSBvbiB0aGF0IGxvYWQsIGl0IHdpbGwgdW5kZXJnbworICAvLy8gYW5vdGhlciByb3VuZCBvZiBleHBhbnNpb24uCisgIHZpcnR1YWwgTG9hZEluc3QgKgorICBsb3dlcklkZW1wb3RlbnRSTVdJbnRvRmVuY2VkTG9hZChBdG9taWNSTVdJbnN0ICpSTVdJKSBjb25zdCB7CisgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKworICAvLy8gUmV0dXJucyBob3cgdGhlIHBsYXRmb3JtJ3MgYXRvbWljIG9wZXJhdGlvbnMgYXJlIGV4dGVuZGVkIChaRVJPX0VYVEVORCwKKyAgLy8vIFNJR05fRVhURU5ELCBvciBBTllfRVhURU5EKS4KKyAgdmlydHVhbCBJU0Q6Ok5vZGVUeXBlIGdldEV4dGVuZEZvckF0b21pY09wcygpIGNvbnN0IHsKKyAgICByZXR1cm4gSVNEOjpaRVJPX0VYVEVORDsKKyAgfQorCisgIC8vLyBAfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgd2Ugc2hvdWxkIG5vcm1hbGl6ZQorICAvLy8gc2VsZWN0KE4wJk4xLCBYLCBZKSA9PiBzZWxlY3QoTjAsIHNlbGVjdChOMSwgWCwgWSksIFkpIGFuZAorICAvLy8gc2VsZWN0KE4wfE4xLCBYLCBZKSA9PiBzZWxlY3QoTjAsIHNlbGVjdChOMSwgWCwgWSwgWSkpIGlmIGl0IGlzIGxpa2VseQorICAvLy8gdGhhdCBpdCBzYXZlcyB1cyBmcm9tIG1hdGVyaWFsaXppbmcgTjAgYW5kIE4xIGluIGFuIGludGVnZXIgcmVnaXN0ZXIuCisgIC8vLyBUYXJnZXRzIHRoYXQgYXJlIGFibGUgdG8gcGVyZm9ybSBhbmQvb3Igb24gZmxhZ3Mgc2hvdWxkIHJldHVybiBmYWxzZSBoZXJlLgorICB2aXJ0dWFsIGJvb2wgc2hvdWxkTm9ybWFsaXplVG9TZWxlY3RTZXF1ZW5jZShMTFZNQ29udGV4dCAmQ29udGV4dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVZUIFZUKSBjb25zdCB7CisgICAgLy8gSWYgYSB0YXJnZXQgaGFzIG11bHRpcGxlIGNvbmRpdGlvbiByZWdpc3RlcnMsIHRoZW4gaXQgbGlrZWx5IGhhcyBsb2dpY2FsCisgICAgLy8gb3BlcmF0aW9ucyBvbiB0aG9zZSByZWdpc3RlcnMuCisgICAgaWYgKGhhc011bHRpcGxlQ29uZGl0aW9uUmVnaXN0ZXJzKCkpCisgICAgICByZXR1cm4gZmFsc2U7CisgICAgLy8gT25seSBkbyB0aGUgdHJhbnNmb3JtIGlmIHRoZSB2YWx1ZSB3b24ndCBiZSBzcGxpdCBpbnRvIG11bHRpcGxlCisgICAgLy8gcmVnaXN0ZXJzLgorICAgIExlZ2FsaXplVHlwZUFjdGlvbiBBY3Rpb24gPSBnZXRUeXBlQWN0aW9uKENvbnRleHQsIFZUKTsKKyAgICByZXR1cm4gQWN0aW9uICE9IFR5cGVFeHBhbmRJbnRlZ2VyICYmIEFjdGlvbiAhPSBUeXBlRXhwYW5kRmxvYXQgJiYKKyAgICAgIEFjdGlvbiAhPSBUeXBlU3BsaXRWZWN0b3I7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgYSBzZWxlY3Qgb2YgY29uc3RhbnRzIChzZWxlY3QgQ29uZCwgQzEsIEMyKSBzaG91bGQgYmUKKyAgLy8vIHRyYW5zZm9ybWVkIGludG8gc2ltcGxlIG1hdGggb3BzIHdpdGggdGhlIGNvbmRpdGlvbiB2YWx1ZS4gRm9yIGV4YW1wbGU6CisgIC8vLyBzZWxlY3QgQ29uZCwgQzEsIEMxLTEgLS0+IGFkZCAoemV4dCBDb25kKSwgQzEtMQorICB2aXJ0dWFsIGJvb2wgY29udmVydFNlbGVjdE9mQ29uc3RhbnRzVG9NYXRoKEVWVCBWVCkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLyBUYXJnZXRMb3dlcmluZyBDb25maWd1cmF0aW9uIE1ldGhvZHMgLSBUaGVzZSBtZXRob2RzIHNob3VsZCBiZSBpbnZva2VkIGJ5CisgIC8vIHRoZSBkZXJpdmVkIGNsYXNzIGNvbnN0cnVjdG9yIHRvIGNvbmZpZ3VyZSB0aGlzIG9iamVjdCBmb3IgdGhlIHRhcmdldC4KKyAgLy8KK3Byb3RlY3RlZDoKKyAgLy8vIFNwZWNpZnkgaG93IHRoZSB0YXJnZXQgZXh0ZW5kcyB0aGUgcmVzdWx0IG9mIGludGVnZXIgYW5kIGZsb2F0aW5nIHBvaW50CisgIC8vLyBib29sZWFuIHZhbHVlcyBmcm9tIGkxIHRvIGEgd2lkZXIgdHlwZS4gIFNlZSBnZXRCb29sZWFuQ29udGVudHMuCisgIHZvaWQgc2V0Qm9vbGVhbkNvbnRlbnRzKEJvb2xlYW5Db250ZW50IFR5KSB7CisgICAgQm9vbGVhbkNvbnRlbnRzID0gVHk7CisgICAgQm9vbGVhbkZsb2F0Q29udGVudHMgPSBUeTsKKyAgfQorCisgIC8vLyBTcGVjaWZ5IGhvdyB0aGUgdGFyZ2V0IGV4dGVuZHMgdGhlIHJlc3VsdCBvZiBpbnRlZ2VyIGFuZCBmbG9hdGluZyBwb2ludAorICAvLy8gYm9vbGVhbiB2YWx1ZXMgZnJvbSBpMSB0byBhIHdpZGVyIHR5cGUuICBTZWUgZ2V0Qm9vbGVhbkNvbnRlbnRzLgorICB2b2lkIHNldEJvb2xlYW5Db250ZW50cyhCb29sZWFuQ29udGVudCBJbnRUeSwgQm9vbGVhbkNvbnRlbnQgRmxvYXRUeSkgeworICAgIEJvb2xlYW5Db250ZW50cyA9IEludFR5OworICAgIEJvb2xlYW5GbG9hdENvbnRlbnRzID0gRmxvYXRUeTsKKyAgfQorCisgIC8vLyBTcGVjaWZ5IGhvdyB0aGUgdGFyZ2V0IGV4dGVuZHMgdGhlIHJlc3VsdCBvZiBhIHZlY3RvciBib29sZWFuIHZhbHVlIGZyb20gYQorICAvLy8gdmVjdG9yIG9mIGkxIHRvIGEgd2lkZXIgdHlwZS4gIFNlZSBnZXRCb29sZWFuQ29udGVudHMuCisgIHZvaWQgc2V0Qm9vbGVhblZlY3RvckNvbnRlbnRzKEJvb2xlYW5Db250ZW50IFR5KSB7CisgICAgQm9vbGVhblZlY3RvckNvbnRlbnRzID0gVHk7CisgIH0KKworICAvLy8gU3BlY2lmeSB0aGUgdGFyZ2V0IHNjaGVkdWxpbmcgcHJlZmVyZW5jZS4KKyAgdm9pZCBzZXRTY2hlZHVsaW5nUHJlZmVyZW5jZShTY2hlZDo6UHJlZmVyZW5jZSBQcmVmKSB7CisgICAgU2NoZWRQcmVmZXJlbmNlSW5mbyA9IFByZWY7CisgIH0KKworICAvLy8gSW5kaWNhdGUgd2hldGhlciB0aGlzIHRhcmdldCBwcmVmZXJzIHRvIHVzZSBfc2V0am1wIHRvIGltcGxlbWVudAorICAvLy8gbGx2bS5zZXRqbXAgb3IgdGhlIHZlcnNpb24gd2l0aG91dCBfLiAgRGVmYXVsdHMgdG8gZmFsc2UuCisgIHZvaWQgc2V0VXNlVW5kZXJzY29yZVNldEptcChib29sIFZhbCkgeworICAgIFVzZVVuZGVyc2NvcmVTZXRKbXAgPSBWYWw7CisgIH0KKworICAvLy8gSW5kaWNhdGUgd2hldGhlciB0aGlzIHRhcmdldCBwcmVmZXJzIHRvIHVzZSBfbG9uZ2ptcCB0byBpbXBsZW1lbnQKKyAgLy8vIGxsdm0ubG9uZ2ptcCBvciB0aGUgdmVyc2lvbiB3aXRob3V0IF8uICBEZWZhdWx0cyB0byBmYWxzZS4KKyAgdm9pZCBzZXRVc2VVbmRlcnNjb3JlTG9uZ0ptcChib29sIFZhbCkgeworICAgIFVzZVVuZGVyc2NvcmVMb25nSm1wID0gVmFsOworICB9CisKKyAgLy8vIEluZGljYXRlIHRoZSBtaW5pbXVtIG51bWJlciBvZiBibG9ja3MgdG8gZ2VuZXJhdGUganVtcCB0YWJsZXMuCisgIHZvaWQgc2V0TWluaW11bUp1bXBUYWJsZUVudHJpZXModW5zaWduZWQgVmFsKTsKKworICAvLy8gSW5kaWNhdGUgdGhlIG1heGltdW0gbnVtYmVyIG9mIGVudHJpZXMgaW4ganVtcCB0YWJsZXMuCisgIC8vLyBTZXQgdG8gemVybyB0byBnZW5lcmF0ZSB1bmxpbWl0ZWQganVtcCB0YWJsZXMuCisgIHZvaWQgc2V0TWF4aW11bUp1bXBUYWJsZVNpemUodW5zaWduZWQpOworCisgIC8vLyBJZiBzZXQgdG8gYSBwaHlzaWNhbCByZWdpc3RlciwgdGhpcyBzcGVjaWZpZXMgdGhlIHJlZ2lzdGVyIHRoYXQKKyAgLy8vIGxsdm0uc2F2ZXN0YWNrL2xsdm0ucmVzdG9yZXN0YWNrIHNob3VsZCBzYXZlIGFuZCByZXN0b3JlLgorICB2b2lkIHNldFN0YWNrUG9pbnRlclJlZ2lzdGVyVG9TYXZlUmVzdG9yZSh1bnNpZ25lZCBSKSB7CisgICAgU3RhY2tQb2ludGVyUmVnaXN0ZXJUb1NhdmVSZXN0b3JlID0gUjsKKyAgfQorCisgIC8vLyBUZWxscyB0aGUgY29kZSBnZW5lcmF0b3IgdGhhdCB0aGUgdGFyZ2V0IGhhcyBtdWx0aXBsZSAoYWxsb2NhdGFibGUpCisgIC8vLyBjb25kaXRpb24gcmVnaXN0ZXJzIHRoYXQgY2FuIGJlIHVzZWQgdG8gc3RvcmUgdGhlIHJlc3VsdHMgb2YgY29tcGFyaXNvbnMKKyAgLy8vIGZvciB1c2UgYnkgc2VsZWN0cyBhbmQgY29uZGl0aW9uYWwgYnJhbmNoZXMuIFdpdGggbXVsdGlwbGUgY29uZGl0aW9uCisgIC8vLyByZWdpc3RlcnMsIHRoZSBjb2RlIGdlbmVyYXRvciB3aWxsIG5vdCBhZ2dyZXNzaXZlbHkgc2luayBjb21wYXJpc29ucyBpbnRvCisgIC8vLyB0aGUgYmxvY2tzIG9mIHRoZWlyIHVzZXJzLgorICB2b2lkIHNldEhhc011bHRpcGxlQ29uZGl0aW9uUmVnaXN0ZXJzKGJvb2wgaGFzTWFueVJlZ3MgPSB0cnVlKSB7CisgICAgSGFzTXVsdGlwbGVDb25kaXRpb25SZWdpc3RlcnMgPSBoYXNNYW55UmVnczsKKyAgfQorCisgIC8vLyBUZWxscyB0aGUgY29kZSBnZW5lcmF0b3IgdGhhdCB0aGUgdGFyZ2V0IGhhcyBCaXRFeHRyYWN0IGluc3RydWN0aW9ucy4KKyAgLy8vIFRoZSBjb2RlIGdlbmVyYXRvciB3aWxsIGFnZ3Jlc3NpdmVseSBzaW5rICJzaGlmdCJzIGludG8gdGhlIGJsb2NrcyBvZgorICAvLy8gdGhlaXIgdXNlcnMgaWYgdGhlIHVzZXJzIHdpbGwgZ2VuZXJhdGUgImFuZCIgaW5zdHJ1Y3Rpb25zIHdoaWNoIGNhbiBiZQorICAvLy8gY29tYmluZWQgd2l0aCAic2hpZnQiIHRvIEJpdEV4dHJhY3QgaW5zdHJ1Y3Rpb25zLgorICB2b2lkIHNldEhhc0V4dHJhY3RCaXRzSW5zbihib29sIGhhc0V4dHJhY3RJbnNuID0gdHJ1ZSkgeworICAgIEhhc0V4dHJhY3RCaXRzSW5zbiA9IGhhc0V4dHJhY3RJbnNuOworICB9CisKKyAgLy8vIFRlbGxzIHRoZSBjb2RlIGdlbmVyYXRvciBub3QgdG8gZXhwYW5kIGxvZ2ljIG9wZXJhdGlvbnMgb24gY29tcGFyaXNvbgorICAvLy8gcHJlZGljYXRlcyBpbnRvIHNlcGFyYXRlIHNlcXVlbmNlcyB0aGF0IGluY3JlYXNlIHRoZSBhbW91bnQgb2YgZmxvdworICAvLy8gY29udHJvbC4KKyAgdm9pZCBzZXRKdW1wSXNFeHBlbnNpdmUoYm9vbCBpc0V4cGVuc2l2ZSA9IHRydWUpOworCisgIC8vLyBUZWxscyB0aGUgY29kZSBnZW5lcmF0b3IgdGhhdCB0aGlzIHRhcmdldCBzdXBwb3J0cyBmbG9hdGluZyBwb2ludAorICAvLy8gZXhjZXB0aW9ucyBhbmQgY2FyZXMgYWJvdXQgcHJlc2VydmluZyBmbG9hdGluZyBwb2ludCBleGNlcHRpb24gYmVoYXZpb3IuCisgIHZvaWQgc2V0SGFzRmxvYXRpbmdQb2ludEV4Y2VwdGlvbnMoYm9vbCBGUEV4Y2VwdGlvbnMgPSB0cnVlKSB7CisgICAgSGFzRmxvYXRpbmdQb2ludEV4Y2VwdGlvbnMgPSBGUEV4Y2VwdGlvbnM7CisgIH0KKworICAvLy8gVGVsbHMgdGhlIGNvZGUgZ2VuZXJhdG9yIHdoaWNoIGJpdHdpZHRocyB0byBieXBhc3MuCisgIHZvaWQgYWRkQnlwYXNzU2xvd0Rpdih1bnNpZ25lZCBpbnQgU2xvd0JpdFdpZHRoLCB1bnNpZ25lZCBpbnQgRmFzdEJpdFdpZHRoKSB7CisgICAgQnlwYXNzU2xvd0RpdldpZHRoc1tTbG93Qml0V2lkdGhdID0gRmFzdEJpdFdpZHRoOworICB9CisKKyAgLy8vIEFkZCB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyIGNsYXNzIGFzIGFuIGF2YWlsYWJsZSByZWdjbGFzcyBmb3IgdGhlCisgIC8vLyBzcGVjaWZpZWQgdmFsdWUgdHlwZS4gVGhpcyBpbmRpY2F0ZXMgdGhlIHNlbGVjdG9yIGNhbiBoYW5kbGUgdmFsdWVzIG9mCisgIC8vLyB0aGF0IGNsYXNzIG5hdGl2ZWx5LgorICB2b2lkIGFkZFJlZ2lzdGVyQ2xhc3MoTVZUIFZULCBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQykgeworICAgIGFzc2VydCgodW5zaWduZWQpVlQuU2ltcGxlVHkgPCBhcnJheV9sZW5ndGhvZihSZWdDbGFzc0ZvclZUKSk7CisgICAgUmVnQ2xhc3NGb3JWVFtWVC5TaW1wbGVUeV0gPSBSQzsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIGxhcmdlc3QgbGVnYWwgc3VwZXItcmVnIHJlZ2lzdGVyIGNsYXNzIG9mIHRoZSByZWdpc3RlciBjbGFzcworICAvLy8gZm9yIHRoZSBzcGVjaWZpZWQgdHlwZSBhbmQgaXRzIGFzc29jaWF0ZWQgImNvc3QiLgorICB2aXJ0dWFsIHN0ZDo6cGFpcjxjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICosIHVpbnQ4X3Q+CisgIGZpbmRSZXByZXNlbnRhdGl2ZUNsYXNzKGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJLCBNVlQgVlQpIGNvbnN0OworCisgIC8vLyBPbmNlIGFsbCBvZiB0aGUgcmVnaXN0ZXIgY2xhc3NlcyBhcmUgYWRkZWQsIHRoaXMgYWxsb3dzIHVzIHRvIGNvbXB1dGUKKyAgLy8vIGRlcml2ZWQgcHJvcGVydGllcyB3ZSBleHBvc2UuCisgIHZvaWQgY29tcHV0ZVJlZ2lzdGVyUHJvcGVydGllcyhjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSk7CisKKyAgLy8vIEluZGljYXRlIHRoYXQgdGhlIHNwZWNpZmllZCBvcGVyYXRpb24gZG9lcyBub3Qgd29yayB3aXRoIHRoZSBzcGVjaWZpZWQKKyAgLy8vIHR5cGUgYW5kIGluZGljYXRlIHdoYXQgdG8gZG8gYWJvdXQgaXQuIE5vdGUgdGhhdCBWVCBtYXkgcmVmZXIgdG8gZWl0aGVyCisgIC8vLyB0aGUgdHlwZSBvZiBhIHJlc3VsdCBvciB0aGF0IG9mIGFuIG9wZXJhbmQgb2YgT3AuCisgIHZvaWQgc2V0T3BlcmF0aW9uQWN0aW9uKHVuc2lnbmVkIE9wLCBNVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIExlZ2FsaXplQWN0aW9uIEFjdGlvbikgeworICAgIGFzc2VydChPcCA8IGFycmF5X2xlbmd0aG9mKE9wQWN0aW9uc1swXSkgJiYgIlRhYmxlIGlzbid0IGJpZyBlbm91Z2ghIik7CisgICAgT3BBY3Rpb25zWyh1bnNpZ25lZClWVC5TaW1wbGVUeV1bT3BdID0gQWN0aW9uOworICB9CisKKyAgLy8vIEluZGljYXRlIHRoYXQgdGhlIHNwZWNpZmllZCBsb2FkIHdpdGggZXh0ZW5zaW9uIGRvZXMgbm90IHdvcmsgd2l0aCB0aGUKKyAgLy8vIHNwZWNpZmllZCB0eXBlIGFuZCBpbmRpY2F0ZSB3aGF0IHRvIGRvIGFib3V0IGl0LgorICB2b2lkIHNldExvYWRFeHRBY3Rpb24odW5zaWduZWQgRXh0VHlwZSwgTVZUIFZhbFZULCBNVlQgTWVtVlQsCisgICAgICAgICAgICAgICAgICAgICAgICBMZWdhbGl6ZUFjdGlvbiBBY3Rpb24pIHsKKyAgICBhc3NlcnQoRXh0VHlwZSA8IElTRDo6TEFTVF9MT0FERVhUX1RZUEUgJiYgVmFsVlQuaXNWYWxpZCgpICYmCisgICAgICAgICAgIE1lbVZULmlzVmFsaWQoKSAmJiAiVGFibGUgaXNuJ3QgYmlnIGVub3VnaCEiKTsKKyAgICBhc3NlcnQoKHVuc2lnbmVkKUFjdGlvbiA8IDB4MTAgJiYgInRvbyBtYW55IGJpdHMgZm9yIGJpdGZpZWxkIGFycmF5Iik7CisgICAgdW5zaWduZWQgU2hpZnQgPSA0ICogRXh0VHlwZTsKKyAgICBMb2FkRXh0QWN0aW9uc1tWYWxWVC5TaW1wbGVUeV1bTWVtVlQuU2ltcGxlVHldICY9IH4oKHVpbnQxNl90KTB4RiA8PCBTaGlmdCk7CisgICAgTG9hZEV4dEFjdGlvbnNbVmFsVlQuU2ltcGxlVHldW01lbVZULlNpbXBsZVR5XSB8PSAodWludDE2X3QpQWN0aW9uIDw8IFNoaWZ0OworICB9CisKKyAgLy8vIEluZGljYXRlIHRoYXQgdGhlIHNwZWNpZmllZCB0cnVuY2F0aW5nIHN0b3JlIGRvZXMgbm90IHdvcmsgd2l0aCB0aGUKKyAgLy8vIHNwZWNpZmllZCB0eXBlIGFuZCBpbmRpY2F0ZSB3aGF0IHRvIGRvIGFib3V0IGl0LgorICB2b2lkIHNldFRydW5jU3RvcmVBY3Rpb24oTVZUIFZhbFZULCBNVlQgTWVtVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBMZWdhbGl6ZUFjdGlvbiBBY3Rpb24pIHsKKyAgICBhc3NlcnQoVmFsVlQuaXNWYWxpZCgpICYmIE1lbVZULmlzVmFsaWQoKSAmJiAiVGFibGUgaXNuJ3QgYmlnIGVub3VnaCEiKTsKKyAgICBUcnVuY1N0b3JlQWN0aW9uc1sodW5zaWduZWQpVmFsVlQuU2ltcGxlVHldW01lbVZULlNpbXBsZVR5XSA9IEFjdGlvbjsKKyAgfQorCisgIC8vLyBJbmRpY2F0ZSB0aGF0IHRoZSBzcGVjaWZpZWQgaW5kZXhlZCBsb2FkIGRvZXMgb3IgZG9lcyBub3Qgd29yayB3aXRoIHRoZQorICAvLy8gc3BlY2lmaWVkIHR5cGUgYW5kIGluZGljYXRlIHdoYXQgdG8gZG8gYWJvcnQgaXQuCisgIC8vLworICAvLy8gTk9URTogQWxsIGluZGV4ZWQgbW9kZSBsb2FkcyBhcmUgaW5pdGlhbGl6ZWQgdG8gRXhwYW5kIGluCisgIC8vLyBUYXJnZXRMb3dlcmluZy5jcHAKKyAgdm9pZCBzZXRJbmRleGVkTG9hZEFjdGlvbih1bnNpZ25lZCBJZHhNb2RlLCBNVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGVnYWxpemVBY3Rpb24gQWN0aW9uKSB7CisgICAgYXNzZXJ0KFZULmlzVmFsaWQoKSAmJiBJZHhNb2RlIDwgSVNEOjpMQVNUX0lOREVYRURfTU9ERSAmJgorICAgICAgICAgICAodW5zaWduZWQpQWN0aW9uIDwgMHhmICYmICJUYWJsZSBpc24ndCBiaWcgZW5vdWdoISIpOworICAgIC8vIExvYWQgYWN0aW9uIGFyZSBrZXB0IGluIHRoZSB1cHBlciBoYWxmLgorICAgIEluZGV4ZWRNb2RlQWN0aW9uc1sodW5zaWduZWQpVlQuU2ltcGxlVHldW0lkeE1vZGVdICY9IH4weGYwOworICAgIEluZGV4ZWRNb2RlQWN0aW9uc1sodW5zaWduZWQpVlQuU2ltcGxlVHldW0lkeE1vZGVdIHw9ICgodWludDhfdClBY3Rpb24pIDw8NDsKKyAgfQorCisgIC8vLyBJbmRpY2F0ZSB0aGF0IHRoZSBzcGVjaWZpZWQgaW5kZXhlZCBzdG9yZSBkb2VzIG9yIGRvZXMgbm90IHdvcmsgd2l0aCB0aGUKKyAgLy8vIHNwZWNpZmllZCB0eXBlIGFuZCBpbmRpY2F0ZSB3aGF0IHRvIGRvIGFib3V0IGl0LgorICAvLy8KKyAgLy8vIE5PVEU6IEFsbCBpbmRleGVkIG1vZGUgc3RvcmVzIGFyZSBpbml0aWFsaXplZCB0byBFeHBhbmQgaW4KKyAgLy8vIFRhcmdldExvd2VyaW5nLmNwcAorICB2b2lkIHNldEluZGV4ZWRTdG9yZUFjdGlvbih1bnNpZ25lZCBJZHhNb2RlLCBNVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExlZ2FsaXplQWN0aW9uIEFjdGlvbikgeworICAgIGFzc2VydChWVC5pc1ZhbGlkKCkgJiYgSWR4TW9kZSA8IElTRDo6TEFTVF9JTkRFWEVEX01PREUgJiYKKyAgICAgICAgICAgKHVuc2lnbmVkKUFjdGlvbiA8IDB4ZiAmJiAiVGFibGUgaXNuJ3QgYmlnIGVub3VnaCEiKTsKKyAgICAvLyBTdG9yZSBhY3Rpb24gYXJlIGtlcHQgaW4gdGhlIGxvd2VyIGhhbGYuCisgICAgSW5kZXhlZE1vZGVBY3Rpb25zWyh1bnNpZ25lZClWVC5TaW1wbGVUeV1bSWR4TW9kZV0gJj0gfjB4MGY7CisgICAgSW5kZXhlZE1vZGVBY3Rpb25zWyh1bnNpZ25lZClWVC5TaW1wbGVUeV1bSWR4TW9kZV0gfD0gKCh1aW50OF90KUFjdGlvbik7CisgIH0KKworICAvLy8gSW5kaWNhdGUgdGhhdCB0aGUgc3BlY2lmaWVkIGNvbmRpdGlvbiBjb2RlIGlzIG9yIGlzbid0IHN1cHBvcnRlZCBvbiB0aGUKKyAgLy8vIHRhcmdldCBhbmQgaW5kaWNhdGUgd2hhdCB0byBkbyBhYm91dCBpdC4KKyAgdm9pZCBzZXRDb25kQ29kZUFjdGlvbihJU0Q6OkNvbmRDb2RlIENDLCBNVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgTGVnYWxpemVBY3Rpb24gQWN0aW9uKSB7CisgICAgYXNzZXJ0KFZULmlzVmFsaWQoKSAmJiAodW5zaWduZWQpQ0MgPCBhcnJheV9sZW5ndGhvZihDb25kQ29kZUFjdGlvbnMpICYmCisgICAgICAgICAgICJUYWJsZSBpc24ndCBiaWcgZW5vdWdoISIpOworICAgIGFzc2VydCgodW5zaWduZWQpQWN0aW9uIDwgMHgxMCAmJiAidG9vIG1hbnkgYml0cyBmb3IgYml0ZmllbGQgYXJyYXkiKTsKKyAgICAvLy8gVGhlIGxvd2VyIDMgYml0cyBvZiB0aGUgU2ltcGxlVHkgaW5kZXggaW50byBOdGggNGJpdCBzZXQgZnJvbSB0aGUgMzItYml0CisgICAgLy8vIHZhbHVlIGFuZCB0aGUgdXBwZXIgMjkgYml0cyBpbmRleCBpbnRvIHRoZSBzZWNvbmQgZGltZW5zaW9uIG9mIHRoZSBhcnJheQorICAgIC8vLyB0byBzZWxlY3Qgd2hhdCAzMi1iaXQgdmFsdWUgdG8gdXNlLgorICAgIHVpbnQzMl90IFNoaWZ0ID0gNCAqIChWVC5TaW1wbGVUeSAmIDB4Nyk7CisgICAgQ29uZENvZGVBY3Rpb25zW0NDXVtWVC5TaW1wbGVUeSA+PiAzXSAmPSB+KCh1aW50MzJfdCkweEYgPDwgU2hpZnQpOworICAgIENvbmRDb2RlQWN0aW9uc1tDQ11bVlQuU2ltcGxlVHkgPj4gM10gfD0gKHVpbnQzMl90KUFjdGlvbiA8PCBTaGlmdDsKKyAgfQorCisgIC8vLyBJZiBPcGMvT3JpZ1ZUIGlzIHNwZWNpZmllZCBhcyBiZWluZyBwcm9tb3RlZCwgdGhlIHByb21vdGlvbiBjb2RlIGRlZmF1bHRzCisgIC8vLyB0byB0cnlpbmcgYSBsYXJnZXIgaW50ZWdlci9mcCB1bnRpbCBpdCBjYW4gZmluZCBvbmUgdGhhdCB3b3Jrcy4gSWYgdGhhdAorICAvLy8gZGVmYXVsdCBpcyBpbnN1ZmZpY2llbnQsIHRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIGJ5IHRoZSB0YXJnZXQgdG8gb3ZlcnJpZGUKKyAgLy8vIHRoZSBkZWZhdWx0LgorICB2b2lkIEFkZFByb21vdGVkVG9UeXBlKHVuc2lnbmVkIE9wYywgTVZUIE9yaWdWVCwgTVZUIERlc3RWVCkgeworICAgIFByb21vdGVUb1R5cGVbc3RkOjptYWtlX3BhaXIoT3BjLCBPcmlnVlQuU2ltcGxlVHkpXSA9IERlc3RWVC5TaW1wbGVUeTsKKyAgfQorCisgIC8vLyBDb252ZW5pZW5jZSBtZXRob2QgdG8gc2V0IGFuIG9wZXJhdGlvbiB0byBQcm9tb3RlIGFuZCBzcGVjaWZ5IHRoZSB0eXBlCisgIC8vLyBpbiBhIHNpbmdsZSBjYWxsLgorICB2b2lkIHNldE9wZXJhdGlvblByb21vdGVkVG9UeXBlKHVuc2lnbmVkIE9wYywgTVZUIE9yaWdWVCwgTVZUIERlc3RWVCkgeworICAgIHNldE9wZXJhdGlvbkFjdGlvbihPcGMsIE9yaWdWVCwgUHJvbW90ZSk7CisgICAgQWRkUHJvbW90ZWRUb1R5cGUoT3BjLCBPcmlnVlQsIERlc3RWVCk7CisgIH0KKworICAvLy8gVGFyZ2V0cyBzaG91bGQgaW52b2tlIHRoaXMgbWV0aG9kIGZvciBlYWNoIHRhcmdldCBpbmRlcGVuZGVudCBub2RlIHRoYXQKKyAgLy8vIHRoZXkgd2FudCB0byBwcm92aWRlIGEgY3VzdG9tIERBRyBjb21iaW5lciBmb3IgYnkgaW1wbGVtZW50aW5nIHRoZQorICAvLy8gUGVyZm9ybURBR0NvbWJpbmUgdmlydHVhbCBtZXRob2QuCisgIHZvaWQgc2V0VGFyZ2V0REFHQ29tYmluZShJU0Q6Ok5vZGVUeXBlIE5UKSB7CisgICAgYXNzZXJ0KHVuc2lnbmVkKE5UID4+IDMpIDwgYXJyYXlfbGVuZ3Rob2YoVGFyZ2V0REFHQ29tYmluZUFycmF5KSk7CisgICAgVGFyZ2V0REFHQ29tYmluZUFycmF5W05UID4+IDNdIHw9IDEgPDwgKE5UJjcpOworICB9CisKKyAgLy8vIFNldCB0aGUgdGFyZ2V0J3MgcmVxdWlyZWQgam1wX2J1ZiBidWZmZXIgc2l6ZSAoaW4gYnl0ZXMpOyBkZWZhdWx0IGlzIDIwMAorICB2b2lkIHNldEp1bXBCdWZTaXplKHVuc2lnbmVkIFNpemUpIHsKKyAgICBKdW1wQnVmU2l6ZSA9IFNpemU7CisgIH0KKworICAvLy8gU2V0IHRoZSB0YXJnZXQncyByZXF1aXJlZCBqbXBfYnVmIGJ1ZmZlciBhbGlnbm1lbnQgKGluIGJ5dGVzKTsgZGVmYXVsdCBpcworICAvLy8gMAorICB2b2lkIHNldEp1bXBCdWZBbGlnbm1lbnQodW5zaWduZWQgQWxpZ24pIHsKKyAgICBKdW1wQnVmQWxpZ25tZW50ID0gQWxpZ247CisgIH0KKworICAvLy8gU2V0IHRoZSB0YXJnZXQncyBtaW5pbXVtIGZ1bmN0aW9uIGFsaWdubWVudCAoaW4gbG9nMihieXRlcykpCisgIHZvaWQgc2V0TWluRnVuY3Rpb25BbGlnbm1lbnQodW5zaWduZWQgQWxpZ24pIHsKKyAgICBNaW5GdW5jdGlvbkFsaWdubWVudCA9IEFsaWduOworICB9CisKKyAgLy8vIFNldCB0aGUgdGFyZ2V0J3MgcHJlZmVycmVkIGZ1bmN0aW9uIGFsaWdubWVudC4gIFRoaXMgc2hvdWxkIGJlIHNldCBpZgorICAvLy8gdGhlcmUgaXMgYSBwZXJmb3JtYW5jZSBiZW5lZml0IHRvIGhpZ2hlci10aGFuLW1pbmltdW0gYWxpZ25tZW50IChpbgorICAvLy8gbG9nMihieXRlcykpCisgIHZvaWQgc2V0UHJlZkZ1bmN0aW9uQWxpZ25tZW50KHVuc2lnbmVkIEFsaWduKSB7CisgICAgUHJlZkZ1bmN0aW9uQWxpZ25tZW50ID0gQWxpZ247CisgIH0KKworICAvLy8gU2V0IHRoZSB0YXJnZXQncyBwcmVmZXJyZWQgbG9vcCBhbGlnbm1lbnQuIERlZmF1bHQgYWxpZ25tZW50IGlzIHplcm8sIGl0CisgIC8vLyBtZWFucyB0aGUgdGFyZ2V0IGRvZXMgbm90IGNhcmUgYWJvdXQgbG9vcCBhbGlnbm1lbnQuICBUaGUgYWxpZ25tZW50IGlzCisgIC8vLyBzcGVjaWZpZWQgaW4gbG9nMihieXRlcykuIFRoZSB0YXJnZXQgbWF5IGFsc28gb3ZlcnJpZGUKKyAgLy8vIGdldFByZWZMb29wQWxpZ25tZW50IHRvIHByb3ZpZGUgcGVyLWxvb3AgdmFsdWVzLgorICB2b2lkIHNldFByZWZMb29wQWxpZ25tZW50KHVuc2lnbmVkIEFsaWduKSB7CisgICAgUHJlZkxvb3BBbGlnbm1lbnQgPSBBbGlnbjsKKyAgfQorCisgIC8vLyBTZXQgdGhlIG1pbmltdW0gc3RhY2sgYWxpZ25tZW50IG9mIGFuIGFyZ3VtZW50IChpbiBsb2cyKGJ5dGVzKSkuCisgIHZvaWQgc2V0TWluU3RhY2tBcmd1bWVudEFsaWdubWVudCh1bnNpZ25lZCBBbGlnbikgeworICAgIE1pblN0YWNrQXJndW1lbnRBbGlnbm1lbnQgPSBBbGlnbjsKKyAgfQorCisgIC8vLyBTZXQgdGhlIG1heGltdW0gYXRvbWljIG9wZXJhdGlvbiBzaXplIHN1cHBvcnRlZCBieSB0aGUKKyAgLy8vIGJhY2tlbmQuIEF0b21pYyBvcGVyYXRpb25zIGdyZWF0ZXIgdGhhbiB0aGlzIHNpemUgKGFzIHdlbGwgYXMKKyAgLy8vIG9uZXMgdGhhdCBhcmUgbm90IG5hdHVyYWxseSBhbGlnbmVkKSwgd2lsbCBiZSBleHBhbmRlZCBieQorICAvLy8gQXRvbWljRXhwYW5kUGFzcyBpbnRvIGFuIF9fYXRvbWljXyogbGlicmFyeSBjYWxsLgorICB2b2lkIHNldE1heEF0b21pY1NpemVJbkJpdHNTdXBwb3J0ZWQodW5zaWduZWQgU2l6ZUluQml0cykgeworICAgIE1heEF0b21pY1NpemVJbkJpdHNTdXBwb3J0ZWQgPSBTaXplSW5CaXRzOworICB9CisKKyAgLy8vIFNldHMgdGhlIG1pbmltdW0gY21weGNoZyBvciBsbC9zYyBzaXplIHN1cHBvcnRlZCBieSB0aGUgYmFja2VuZC4KKyAgdm9pZCBzZXRNaW5DbXBYY2hnU2l6ZUluQml0cyh1bnNpZ25lZCBTaXplSW5CaXRzKSB7CisgICAgTWluQ21wWGNoZ1NpemVJbkJpdHMgPSBTaXplSW5CaXRzOworICB9CisKKyAgLy8vIFNldHMgd2hldGhlciB1bmFsaWduZWQgYXRvbWljIG9wZXJhdGlvbnMgYXJlIHN1cHBvcnRlZC4KKyAgdm9pZCBzZXRTdXBwb3J0c1VuYWxpZ25lZEF0b21pY3MoYm9vbCBVbmFsaWduZWRTdXBwb3J0ZWQpIHsKKyAgICBTdXBwb3J0c1VuYWxpZ25lZEF0b21pY3MgPSBVbmFsaWduZWRTdXBwb3J0ZWQ7CisgIH0KKworcHVibGljOgorICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gQWRkcmVzc2luZyBtb2RlIGRlc2NyaXB0aW9uIGhvb2tzICh1c2VkIGJ5IExTUiBldGMpLgorICAvLworCisgIC8vLyBDb2RlR2VuUHJlcGFyZSBzaW5rcyBhZGRyZXNzIGNhbGN1bGF0aW9ucyBpbnRvIHRoZSBzYW1lIEJCIGFzIExvYWQvU3RvcmUKKyAgLy8vIGluc3RydWN0aW9ucyByZWFkaW5nIHRoZSBhZGRyZXNzLiBUaGlzIGFsbG93cyBhcyBtdWNoIGNvbXB1dGF0aW9uIGFzCisgIC8vLyBwb3NzaWJsZSB0byBiZSBkb25lIGluIHRoZSBhZGRyZXNzIG1vZGUgZm9yIHRoYXQgb3BlcmFuZC4gVGhpcyBob29rIGxldHMKKyAgLy8vIHRhcmdldHMgYWxzbyBwYXNzIGJhY2sgd2hlbiB0aGlzIHNob3VsZCBiZSBkb25lIG9uIGludHJpbnNpY3Mgd2hpY2gKKyAgLy8vIGxvYWQvc3RvcmUuCisgIHZpcnR1YWwgYm9vbCBnZXRBZGRyTW9kZUFyZ3VtZW50cyhJbnRyaW5zaWNJbnN0ICogLypJKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8VmFsdWUqPiAmLypPcHMqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgKiYvKkFjY2Vzc1R5Ki8pIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gVGhpcyByZXByZXNlbnRzIGFuIGFkZHJlc3NpbmcgbW9kZSBvZjoKKyAgLy8vICAgIEJhc2VHViArIEJhc2VPZmZzICsgQmFzZVJlZyArIFNjYWxlKlNjYWxlUmVnCisgIC8vLyBJZiBCYXNlR1YgaXMgbnVsbCwgIHRoZXJlIGlzIG5vIEJhc2VHVi4KKyAgLy8vIElmIEJhc2VPZmZzIGlzIHplcm8sIHRoZXJlIGlzIG5vIGJhc2Ugb2Zmc2V0LgorICAvLy8gSWYgSGFzQmFzZVJlZyBpcyBmYWxzZSwgdGhlcmUgaXMgbm8gYmFzZSByZWdpc3Rlci4KKyAgLy8vIElmIFNjYWxlIGlzIHplcm8sIHRoZXJlIGlzIG5vIFNjYWxlUmVnLiAgU2NhbGUgb2YgMSBpbmRpY2F0ZXMgYSByZWcgd2l0aAorICAvLy8gbm8gc2NhbGUuCisgIHN0cnVjdCBBZGRyTW9kZSB7CisgICAgR2xvYmFsVmFsdWUgKkJhc2VHViA9IG51bGxwdHI7CisgICAgaW50NjRfdCAgICAgIEJhc2VPZmZzID0gMDsKKyAgICBib29sICAgICAgICAgSGFzQmFzZVJlZyA9IGZhbHNlOworICAgIGludDY0X3QgICAgICBTY2FsZSA9IDA7CisgICAgQWRkck1vZGUoKSA9IGRlZmF1bHQ7CisgIH07CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBhZGRyZXNzaW5nIG1vZGUgcmVwcmVzZW50ZWQgYnkgQU0gaXMgbGVnYWwgZm9yIHRoaXMKKyAgLy8vIHRhcmdldCwgZm9yIGEgbG9hZC9zdG9yZSBvZiB0aGUgc3BlY2lmaWVkIHR5cGUuCisgIC8vLworICAvLy8gVGhlIHR5cGUgbWF5IGJlIFZvaWRUeSwgaW4gd2hpY2ggY2FzZSBvbmx5IHJldHVybiB0cnVlIGlmIHRoZSBhZGRyZXNzaW5nCisgIC8vLyBtb2RlIGlzIGxlZ2FsIGZvciBhIGxvYWQvc3RvcmUgb2YgYW55IGxlZ2FsIHR5cGUuICBUT0RPOiBIYW5kbGUKKyAgLy8vIHByZS9wb3N0aW5jIGFzIHdlbGwuCisgIC8vLworICAvLy8gSWYgdGhlIGFkZHJlc3Mgc3BhY2UgY2Fubm90IGJlIGRldGVybWluZWQsIGl0IHdpbGwgYmUgLTEuCisgIC8vLworICAvLy8gVE9ETzogUmVtb3ZlIGRlZmF1bHQgYXJndW1lbnQKKyAgdmlydHVhbCBib29sIGlzTGVnYWxBZGRyZXNzaW5nTW9kZShjb25zdCBEYXRhTGF5b3V0ICZETCwgY29uc3QgQWRkck1vZGUgJkFNLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUgKlR5LCB1bnNpZ25lZCBBZGRyU3BhY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5zdHJ1Y3Rpb24gKkkgPSBudWxscHRyKSBjb25zdDsKKworICAvLy8gXGJyaWVmIFJldHVybiB0aGUgY29zdCBvZiB0aGUgc2NhbGluZyBmYWN0b3IgdXNlZCBpbiB0aGUgYWRkcmVzc2luZyBtb2RlCisgIC8vLyByZXByZXNlbnRlZCBieSBBTSBmb3IgdGhpcyB0YXJnZXQsIGZvciBhIGxvYWQvc3RvcmUgb2YgdGhlIHNwZWNpZmllZCB0eXBlLgorICAvLy8KKyAgLy8vIElmIHRoZSBBTSBpcyBzdXBwb3J0ZWQsIHRoZSByZXR1cm4gdmFsdWUgbXVzdCBiZSA+PSAwLgorICAvLy8gSWYgdGhlIEFNIGlzIG5vdCBzdXBwb3J0ZWQsIGl0IHJldHVybnMgYSBuZWdhdGl2ZSB2YWx1ZS4KKyAgLy8vIFRPRE86IEhhbmRsZSBwcmUvcG9zdGluYyBhcyB3ZWxsLgorICAvLy8gVE9ETzogUmVtb3ZlIGRlZmF1bHQgYXJndW1lbnQKKyAgdmlydHVhbCBpbnQgZ2V0U2NhbGluZ0ZhY3RvckNvc3QoY29uc3QgRGF0YUxheW91dCAmREwsIGNvbnN0IEFkZHJNb2RlICZBTSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHlwZSAqVHksIHVuc2lnbmVkIEFTID0gMCkgY29uc3QgeworICAgIC8vIERlZmF1bHQ6IGFzc3VtZSB0aGF0IGFueSBzY2FsaW5nIGZhY3RvciB1c2VkIGluIGEgbGVnYWwgQU0gaXMgZnJlZS4KKyAgICBpZiAoaXNMZWdhbEFkZHJlc3NpbmdNb2RlKERMLCBBTSwgVHksIEFTKSkKKyAgICAgIHJldHVybiAwOworICAgIHJldHVybiAtMTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIGltbWVkaWF0ZSBpcyBsZWdhbCBpY21wIGltbWVkaWF0ZSwgdGhhdCBpcworICAvLy8gdGhlIHRhcmdldCBoYXMgaWNtcCBpbnN0cnVjdGlvbnMgd2hpY2ggY2FuIGNvbXBhcmUgYSByZWdpc3RlciBhZ2FpbnN0IHRoZQorICAvLy8gaW1tZWRpYXRlIHdpdGhvdXQgaGF2aW5nIHRvIG1hdGVyaWFsaXplIHRoZSBpbW1lZGlhdGUgaW50byBhIHJlZ2lzdGVyLgorICB2aXJ0dWFsIGJvb2wgaXNMZWdhbElDbXBJbW1lZGlhdGUoaW50NjRfdCkgY29uc3QgeworICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgaW1tZWRpYXRlIGlzIGxlZ2FsIGFkZCBpbW1lZGlhdGUsIHRoYXQgaXMgdGhlCisgIC8vLyB0YXJnZXQgaGFzIGFkZCBpbnN0cnVjdGlvbnMgd2hpY2ggY2FuIGFkZCBhIHJlZ2lzdGVyIHdpdGggdGhlIGltbWVkaWF0ZQorICAvLy8gd2l0aG91dCBoYXZpbmcgdG8gbWF0ZXJpYWxpemUgdGhlIGltbWVkaWF0ZSBpbnRvIGEgcmVnaXN0ZXIuCisgIHZpcnR1YWwgYm9vbCBpc0xlZ2FsQWRkSW1tZWRpYXRlKGludDY0X3QpIGNvbnN0IHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBpdCdzIHNpZ25pZmljYW50bHkgY2hlYXBlciB0byBzaGlmdCBhIHZlY3RvciBieSBhIHVuaWZvcm0KKyAgLy8vIHNjYWxhciB0aGFuIGJ5IGFuIGFtb3VudCB3aGljaCB3aWxsIHZhcnkgYWNyb3NzIGVhY2ggbGFuZS4gT24geDg2LCBmb3IKKyAgLy8vIGV4YW1wbGUsIHRoZXJlIGlzIGEgInBzbGx3IiBpbnN0cnVjdGlvbiBmb3IgdGhlIGZvcm1lciBjYXNlLCBidXQgbm8gc2ltcGxlCisgIC8vLyBpbnN0cnVjdGlvbiBmb3IgYSBnZW5lcmFsICJhIDw8IGIiIG9wZXJhdGlvbiBvbiB2ZWN0b3JzLgorICB2aXJ0dWFsIGJvb2wgaXNWZWN0b3JTaGlmdEJ5U2NhbGFyQ2hlYXAoVHlwZSAqVHkpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBvcGNvZGUgaXMgYSBjb21tdXRhdGl2ZSBiaW5hcnkgb3BlcmF0aW9uLgorICB2aXJ0dWFsIGJvb2wgaXNDb21tdXRhdGl2ZUJpbk9wKHVuc2lnbmVkIE9wY29kZSkgY29uc3QgeworICAgIC8vIEZJWE1FOiBUaGlzIHNob3VsZCBnZXQgaXRzIGluZm8gZnJvbSB0aGUgdGQgZmlsZS4KKyAgICBzd2l0Y2ggKE9wY29kZSkgeworICAgIGNhc2UgSVNEOjpBREQ6CisgICAgY2FzZSBJU0Q6OlNNSU46CisgICAgY2FzZSBJU0Q6OlNNQVg6CisgICAgY2FzZSBJU0Q6OlVNSU46CisgICAgY2FzZSBJU0Q6OlVNQVg6CisgICAgY2FzZSBJU0Q6Ok1VTDoKKyAgICBjYXNlIElTRDo6TVVMSFU6CisgICAgY2FzZSBJU0Q6Ok1VTEhTOgorICAgIGNhc2UgSVNEOjpTTVVMX0xPSEk6CisgICAgY2FzZSBJU0Q6OlVNVUxfTE9ISToKKyAgICBjYXNlIElTRDo6RkFERDoKKyAgICBjYXNlIElTRDo6Rk1VTDoKKyAgICBjYXNlIElTRDo6QU5EOgorICAgIGNhc2UgSVNEOjpPUjoKKyAgICBjYXNlIElTRDo6WE9SOgorICAgIGNhc2UgSVNEOjpTQURETzoKKyAgICBjYXNlIElTRDo6VUFERE86CisgICAgY2FzZSBJU0Q6OkFEREM6CisgICAgY2FzZSBJU0Q6OkFEREU6CisgICAgY2FzZSBJU0Q6OkZNSU5OVU06CisgICAgY2FzZSBJU0Q6OkZNQVhOVU06CisgICAgY2FzZSBJU0Q6OkZNSU5OQU46CisgICAgY2FzZSBJU0Q6OkZNQVhOQU46CisgICAgICByZXR1cm4gdHJ1ZTsKKyAgICBkZWZhdWx0OiByZXR1cm4gZmFsc2U7CisgICAgfQorICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGl0J3MgZnJlZSB0byB0cnVuY2F0ZSBhIHZhbHVlIG9mIHR5cGUgRnJvbVR5IHRvIHR5cGUKKyAgLy8vIFRvVHkuIGUuZy4gT24geDg2IGl0J3MgZnJlZSB0byB0cnVuY2F0ZSBhIGkzMiB2YWx1ZSBpbiByZWdpc3RlciBFQVggdG8gaTE2CisgIC8vLyBieSByZWZlcmVuY2luZyBpdHMgc3ViLXJlZ2lzdGVyIEFYLgorICAvLy8gVGFyZ2V0cyBtdXN0IHJldHVybiBmYWxzZSB3aGVuIEZyb21UeSA8PSBUb1R5LgorICB2aXJ0dWFsIGJvb2wgaXNUcnVuY2F0ZUZyZWUoVHlwZSAqRnJvbVR5LCBUeXBlICpUb1R5KSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGEgdHJ1bmNhdGlvbiBmcm9tIEZyb21UeSB0byBUb1R5IGlzIHBlcm1pdHRlZCB3aGVuIGRlY2lkaW5nCisgIC8vLyB3aGV0aGVyIGEgY2FsbCBpcyBpbiB0YWlsIHBvc2l0aW9uLiBUeXBpY2FsbHkgdGhpcyBtZWFucyB0aGF0IGJvdGggcmVzdWx0cworICAvLy8gd291bGQgYmUgYXNzaWduZWQgdG8gdGhlIHNhbWUgcmVnaXN0ZXIgb3Igc3RhY2sgc2xvdCwgYnV0IGl0IGNvdWxkIG1lYW4KKyAgLy8vIHRoZSB0YXJnZXQgcGVyZm9ybXMgYWRlcXVhdGUgY2hlY2tzIG9mIGl0cyBvd24gYmVmb3JlIHByb2NlZWRpbmcgd2l0aCB0aGUKKyAgLy8vIHRhaWwgY2FsbC4gIFRhcmdldHMgbXVzdCByZXR1cm4gZmFsc2Ugd2hlbiBGcm9tVHkgPD0gVG9UeS4KKyAgdmlydHVhbCBib29sIGFsbG93VHJ1bmNhdGVGb3JUYWlsQ2FsbChUeXBlICpGcm9tVHksIFR5cGUgKlRvVHkpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICB2aXJ0dWFsIGJvb2wgaXNUcnVuY2F0ZUZyZWUoRVZUIEZyb21WVCwgRVZUIFRvVlQpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICB2aXJ0dWFsIGJvb2wgaXNQcm9maXRhYmxlVG9Ib2lzdChJbnN0cnVjdGlvbiAqSSkgY29uc3QgeyByZXR1cm4gdHJ1ZTsgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgZXh0ZW5zaW9uIHJlcHJlc2VudGVkIGJ5IFxwIEkgaXMgZnJlZS4KKyAgLy8vIFVubGlrZWx5IHRoZSBpc1tafEZQXUV4dEZyZWUgZmFtaWx5IHdoaWNoIGlzIGJhc2VkIG9uIHR5cGVzLAorICAvLy8gdGhpcyBtZXRob2QgY2FuIHVzZSB0aGUgY29udGV4dCBwcm92aWRlZCBieSBccCBJIHRvIGRlY2lkZQorICAvLy8gd2hldGhlciBvciBub3QgXHAgSSBpcyBmcmVlLgorICAvLy8gVGhpcyBtZXRob2QgZXh0ZW5kcyB0aGUgYmVoYXZpb3Igb2YgdGhlIGlzW1p8RlBdRXh0RnJlZSBmYW1pbHkuCisgIC8vLyBJbiBvdGhlciB3b3JkcywgaWYgaXNbWnxGUF1GcmVlIHJldHVybnMgdHJ1ZSwgdGhlbiB0aGlzIG1ldGhvZAorICAvLy8gcmV0dXJucyB0cnVlIGFzIHdlbGwuIFRoZSBjb252ZXJzZSBpcyBub3QgdHJ1ZS4KKyAgLy8vIFRoZSB0YXJnZXQgY2FuIHBlcmZvcm0gdGhlIGFkZXF1YXRlIGNoZWNrcyBieSBvdmVycmlkaW5nIGlzRXh0RnJlZUltcGwuCisgIC8vLyBccHJlIFxwIEkgbXVzdCBiZSBhIHNpZ24sIHplcm8sIG9yIGZwIGV4dGVuc2lvbi4KKyAgYm9vbCBpc0V4dEZyZWUoY29uc3QgSW5zdHJ1Y3Rpb24gKkkpIGNvbnN0IHsKKyAgICBzd2l0Y2ggKEktPmdldE9wY29kZSgpKSB7CisgICAgY2FzZSBJbnN0cnVjdGlvbjo6RlBFeHQ6CisgICAgICBpZiAoaXNGUEV4dEZyZWUoRVZUOjpnZXRFVlQoSS0+Z2V0VHlwZSgpKSwKKyAgICAgICAgICAgICAgICAgICAgICBFVlQ6OmdldEVWVChJLT5nZXRPcGVyYW5kKDApLT5nZXRUeXBlKCkpKSkKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICBicmVhazsKKyAgICBjYXNlIEluc3RydWN0aW9uOjpaRXh0OgorICAgICAgaWYgKGlzWkV4dEZyZWUoSS0+Z2V0T3BlcmFuZCgwKS0+Z2V0VHlwZSgpLCBJLT5nZXRUeXBlKCkpKQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgSW5zdHJ1Y3Rpb246OlNFeHQ6CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgbGx2bV91bnJlYWNoYWJsZSgiSW5zdHJ1Y3Rpb24gaXMgbm90IGFuIGV4dGVuc2lvbiIpOworICAgIH0KKyAgICByZXR1cm4gaXNFeHRGcmVlSW1wbChJKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBccCBMb2FkIGFuZCBccCBFeHQgY2FuIGZvcm0gYW4gRXh0TG9hZC4KKyAgLy8vIEZvciBleGFtcGxlLCBpbiBBQXJjaDY0CisgIC8vLyAgICVMID0gbG9hZCBpOCwgaTgqICVwdHIKKyAgLy8vICAgJUUgPSB6ZXh0IGk4ICVMIHRvIGkzMgorICAvLy8gY2FuIGJlIGxvd2VyZWQgaW50byBvbmUgbG9hZCBpbnN0cnVjdGlvbgorICAvLy8gICBsZHJiIHcwLCBbeDBdCisgIGJvb2wgaXNFeHRMb2FkKGNvbnN0IExvYWRJbnN0ICpMb2FkLCBjb25zdCBJbnN0cnVjdGlvbiAqRXh0LAorICAgICAgICAgICAgICAgICBjb25zdCBEYXRhTGF5b3V0ICZETCkgY29uc3QgeworICAgIEVWVCBWVCA9IGdldFZhbHVlVHlwZShETCwgRXh0LT5nZXRUeXBlKCkpOworICAgIEVWVCBMb2FkVlQgPSBnZXRWYWx1ZVR5cGUoREwsIExvYWQtPmdldFR5cGUoKSk7CisKKyAgICAvLyBJZiB0aGUgbG9hZCBoYXMgb3RoZXIgdXNlcnMgYW5kIHRoZSB0cnVuY2F0ZSBpcyBub3QgZnJlZSwgdGhlIGV4dAorICAgIC8vIHByb2JhYmx5IGlzbid0IGZyZWUuCisgICAgaWYgKCFMb2FkLT5oYXNPbmVVc2UoKSAmJiAoaXNUeXBlTGVnYWwoTG9hZFZUKSB8fCAhaXNUeXBlTGVnYWwoVlQpKSAmJgorICAgICAgICAhaXNUcnVuY2F0ZUZyZWUoRXh0LT5nZXRUeXBlKCksIExvYWQtPmdldFR5cGUoKSkpCisgICAgICByZXR1cm4gZmFsc2U7CisKKyAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSB0YXJnZXQgc3VwcG9ydHMgY2FzdHMgZm9sZGVkIGludG8gbG9hZHMuCisgICAgdW5zaWduZWQgTFR5cGU7CisgICAgaWYgKGlzYTxaRXh0SW5zdD4oRXh0KSkKKyAgICAgIExUeXBlID0gSVNEOjpaRVhUTE9BRDsKKyAgICBlbHNlIHsKKyAgICAgIGFzc2VydChpc2E8U0V4dEluc3Q+KEV4dCkgJiYgIlVuZXhwZWN0ZWQgZXh0IHR5cGUhIik7CisgICAgICBMVHlwZSA9IElTRDo6U0VYVExPQUQ7CisgICAgfQorCisgICAgcmV0dXJuIGlzTG9hZEV4dExlZ2FsKExUeXBlLCBWVCwgTG9hZFZUKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBhbnkgYWN0dWFsIGluc3RydWN0aW9uIHRoYXQgZGVmaW5lcyBhIHZhbHVlIG9mIHR5cGUgRnJvbVR5CisgIC8vLyBpbXBsaWNpdGx5IHplcm8tZXh0ZW5kcyB0aGUgdmFsdWUgdG8gVG9UeSBpbiB0aGUgcmVzdWx0IHJlZ2lzdGVyLgorICAvLy8KKyAgLy8vIFRoZSBmdW5jdGlvbiBzaG91bGQgcmV0dXJuIHRydWUgd2hlbiBpdCBpcyBsaWtlbHkgdGhhdCB0aGUgdHJ1bmNhdGUgY2FuCisgIC8vLyBiZSBmcmVlbHkgZm9sZGVkIHdpdGggYW4gaW5zdHJ1Y3Rpb24gZGVmaW5pbmcgYSB2YWx1ZSBvZiBGcm9tVHkuIElmCisgIC8vLyB0aGUgZGVmaW5pbmcgaW5zdHJ1Y3Rpb24gaXMgdW5rbm93biAoYmVjYXVzZSB5b3UncmUgbG9va2luZyBhdCBhCisgIC8vLyBmdW5jdGlvbiBhcmd1bWVudCwgUEhJLCBldGMuKSB0aGVuIHRoZSB0YXJnZXQgbWF5IHJlcXVpcmUgYW4KKyAgLy8vIGV4cGxpY2l0IHRydW5jYXRlLCB3aGljaCBpcyBub3QgbmVjZXNzYXJpbHkgZnJlZSwgYnV0IHRoaXMgZnVuY3Rpb24KKyAgLy8vIGRvZXMgbm90IGRlYWwgd2l0aCB0aG9zZSBjYXNlcy4KKyAgLy8vIFRhcmdldHMgbXVzdCByZXR1cm4gZmFsc2Ugd2hlbiBGcm9tVHkgPj0gVG9UeS4KKyAgdmlydHVhbCBib29sIGlzWkV4dEZyZWUoVHlwZSAqRnJvbVR5LCBUeXBlICpUb1R5KSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgdmlydHVhbCBib29sIGlzWkV4dEZyZWUoRVZUIEZyb21UeSwgRVZUIFRvVHkpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHRhcmdldCBzdXBwbGllcyBhbmQgY29tYmluZXMgdG8gYSBwYWlyZWQgbG9hZAorICAvLy8gdHdvIGxvYWRlZCB2YWx1ZXMgb2YgdHlwZSBMb2FkZWRUeXBlIG5leHQgdG8gZWFjaCBvdGhlciBpbiBtZW1vcnkuCisgIC8vLyBSZXF1aXJlZEFsaWdubWVudCBnaXZlcyB0aGUgbWluaW1hbCBhbGlnbm1lbnQgY29uc3RyYWludHMgdGhhdCBtdXN0IGJlIG1ldAorICAvLy8gdG8gYmUgYWJsZSB0byBzZWxlY3QgdGhpcyBwYWlyZWQgbG9hZC4KKyAgLy8vCisgIC8vLyBUaGlzIGluZm9ybWF0aW9uIGlzICpub3QqIHVzZWQgdG8gZ2VuZXJhdGUgYWN0dWFsIHBhaXJlZCBsb2FkcywgYnV0IGl0IGlzCisgIC8vLyB1c2VkIHRvIGdlbmVyYXRlIGEgc2VxdWVuY2Ugb2YgbG9hZHMgdGhhdCBpcyBlYXNpZXIgdG8gY29tYmluZSBpbnRvIGEKKyAgLy8vIHBhaXJlZCBsb2FkLgorICAvLy8gRm9yIGluc3RhbmNlLCBzb21ldGhpbmcgbGlrZSB0aGlzOgorICAvLy8gYSA9IGxvYWQgaTY0KiBhZGRyCisgIC8vLyBiID0gdHJ1bmMgaTY0IGEgdG8gaTMyCisgIC8vLyBjID0gbHNociBpNjQgYSwgMzIKKyAgLy8vIGQgPSB0cnVuYyBpNjQgYyB0byBpMzIKKyAgLy8vIHdpbGwgYmUgb3B0aW1pemVkIGludG86CisgIC8vLyBiID0gbG9hZCBpMzIqIGFkZHIxCisgIC8vLyBkID0gbG9hZCBpMzIqIGFkZHIyCisgIC8vLyBXaGVyZSBhZGRyMSA9IGFkZHIyICsvLSBzaXplb2YoaTMyKS4KKyAgLy8vCisgIC8vLyBJbiBvdGhlciB3b3JkcywgdW5sZXNzIHRoZSB0YXJnZXQgcGVyZm9ybXMgYSBwb3N0LWlzZWwgbG9hZCBjb21iaW5pbmcsCisgIC8vLyB0aGlzIGluZm9ybWF0aW9uIHNob3VsZCBub3QgYmUgcHJvdmlkZWQgYmVjYXVzZSBpdCB3aWxsIGdlbmVyYXRlIG1vcmUKKyAgLy8vIGxvYWRzLgorICB2aXJ0dWFsIGJvb2wgaGFzUGFpcmVkTG9hZChFVlQgLypMb2FkZWRUeXBlKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkICYgLypSZXF1aXJlZEFsaWdubWVudCovKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSB0YXJnZXQgaGFzIGEgdmVjdG9yIGJsZW5kIGluc3RydWN0aW9uLgorICB2aXJ0dWFsIGJvb2wgaGFzVmVjdG9yQmxlbmQoKSBjb25zdCB7IHJldHVybiBmYWxzZTsgfQorCisgIC8vLyBcYnJpZWYgR2V0IHRoZSBtYXhpbXVtIHN1cHBvcnRlZCBmYWN0b3IgZm9yIGludGVybGVhdmVkIG1lbW9yeSBhY2Nlc3Nlcy4KKyAgLy8vIERlZmF1bHQgdG8gYmUgdGhlIG1pbmltdW0gaW50ZXJsZWF2ZSBmYWN0b3I6IDIuCisgIHZpcnR1YWwgdW5zaWduZWQgZ2V0TWF4U3VwcG9ydGVkSW50ZXJsZWF2ZUZhY3RvcigpIGNvbnN0IHsgcmV0dXJuIDI7IH0KKworICAvLy8gXGJyaWVmIExvd2VyIGFuIGludGVybGVhdmVkIGxvYWQgdG8gdGFyZ2V0IHNwZWNpZmljIGludHJpbnNpY3MuIFJldHVybgorICAvLy8gdHJ1ZSBvbiBzdWNjZXNzLgorICAvLy8KKyAgLy8vIFxwIExJIGlzIHRoZSB2ZWN0b3IgbG9hZCBpbnN0cnVjdGlvbi4KKyAgLy8vIFxwIFNodWZmbGVzIGlzIHRoZSBzaHVmZmxldmVjdG9yIGxpc3QgdG8gREUtaW50ZXJsZWF2ZSB0aGUgbG9hZGVkIHZlY3Rvci4KKyAgLy8vIFxwIEluZGljZXMgaXMgdGhlIGNvcnJlc3BvbmRpbmcgaW5kaWNlcyBmb3IgZWFjaCBzaHVmZmxldmVjdG9yLgorICAvLy8gXHAgRmFjdG9yIGlzIHRoZSBpbnRlcmxlYXZlIGZhY3Rvci4KKyAgdmlydHVhbCBib29sIGxvd2VySW50ZXJsZWF2ZWRMb2FkKExvYWRJbnN0ICpMSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFNodWZmbGVWZWN0b3JJbnN0ICo+IFNodWZmbGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8dW5zaWduZWQ+IEluZGljZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBGYWN0b3IpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gXGJyaWVmIExvd2VyIGFuIGludGVybGVhdmVkIHN0b3JlIHRvIHRhcmdldCBzcGVjaWZpYyBpbnRyaW5zaWNzLiBSZXR1cm4KKyAgLy8vIHRydWUgb24gc3VjY2Vzcy4KKyAgLy8vCisgIC8vLyBccCBTSSBpcyB0aGUgdmVjdG9yIHN0b3JlIGluc3RydWN0aW9uLgorICAvLy8gXHAgU1ZJIGlzIHRoZSBzaHVmZmxldmVjdG9yIHRvIFJFLWludGVybGVhdmUgdGhlIHN0b3JlZCB2ZWN0b3IuCisgIC8vLyBccCBGYWN0b3IgaXMgdGhlIGludGVybGVhdmUgZmFjdG9yLgorICB2aXJ0dWFsIGJvb2wgbG93ZXJJbnRlcmxlYXZlZFN0b3JlKFN0b3JlSW5zdCAqU0ksIFNodWZmbGVWZWN0b3JJbnN0ICpTVkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgRmFjdG9yKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHplcm8tZXh0ZW5kaW5nIHRoZSBzcGVjaWZpYyBub2RlIFZhbCB0byB0eXBlIFZUMiBpcyBmcmVlCisgIC8vLyAoZWl0aGVyIGJlY2F1c2UgaXQncyBpbXBsaWNpdGx5IHplcm8tZXh0ZW5kZWQgc3VjaCBhcyBBUk0gbGRyYiAvIGxkcmggb3IKKyAgLy8vIGJlY2F1c2UgaXQncyBmb2xkZWQgc3VjaCBhcyBYODYgemVyby1leHRlbmRpbmcgbG9hZHMpLgorICB2aXJ0dWFsIGJvb2wgaXNaRXh0RnJlZShTRFZhbHVlIFZhbCwgRVZUIFZUMikgY29uc3QgeworICAgIHJldHVybiBpc1pFeHRGcmVlKFZhbC5nZXRWYWx1ZVR5cGUoKSwgVlQyKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBhbiBmcGV4dCBvcGVyYXRpb24gaXMgZnJlZSAoZm9yIGluc3RhbmNlLCBiZWNhdXNlCisgIC8vLyBzaW5nbGUtcHJlY2lzaW9uIGZsb2F0aW5nLXBvaW50IG51bWJlcnMgYXJlIGltcGxpY2l0bHkgZXh0ZW5kZWQgdG8KKyAgLy8vIGRvdWJsZS1wcmVjaXNpb24pLgorICB2aXJ0dWFsIGJvb2wgaXNGUEV4dEZyZWUoRVZUIERlc3RWVCwgRVZUIFNyY1ZUKSBjb25zdCB7CisgICAgYXNzZXJ0KFNyY1ZULmlzRmxvYXRpbmdQb2ludCgpICYmIERlc3RWVC5pc0Zsb2F0aW5nUG9pbnQoKSAmJgorICAgICAgICAgICAiaW52YWxpZCBmcGV4dCB0eXBlcyIpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBhbiBmcGV4dCBvcGVyYXRpb24gaW5wdXQgdG8gYW4gXHAgT3Bjb2RlIG9wZXJhdGlvbiBpcyBmcmVlCisgIC8vLyAoZm9yIGluc3RhbmNlLCBiZWNhdXNlIGhhbGYtcHJlY2lzaW9uIGZsb2F0aW5nLXBvaW50IG51bWJlcnMgYXJlCisgIC8vLyBpbXBsaWNpdGx5IGV4dGVuZGVkIHRvIGZsb2F0LXByZWNpc2lvbikgZm9yIGFuIEZNQSBpbnN0cnVjdGlvbi4KKyAgdmlydHVhbCBib29sIGlzRlBFeHRGb2xkYWJsZSh1bnNpZ25lZCBPcGNvZGUsIEVWVCBEZXN0VlQsIEVWVCBTcmNWVCkgY29uc3QgeworICAgIGFzc2VydChEZXN0VlQuaXNGbG9hdGluZ1BvaW50KCkgJiYgU3JjVlQuaXNGbG9hdGluZ1BvaW50KCkgJiYKKyAgICAgICAgICAgImludmFsaWQgZnBleHQgdHlwZXMiKTsKKyAgICByZXR1cm4gaXNGUEV4dEZyZWUoRGVzdFZULCBTcmNWVCk7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgZm9sZGluZyBhIHZlY3RvciBsb2FkIGludG8gRXh0VmFsIChhIHNpZ24sIHplcm8sIG9yIGFueQorICAvLy8gZXh0ZW5kIG5vZGUpIGlzIHByb2ZpdGFibGUuCisgIHZpcnR1YWwgYm9vbCBpc1ZlY3RvckxvYWRFeHREZXNpcmFibGUoU0RWYWx1ZSBFeHRWYWwpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGFuIGZuZWcgb3BlcmF0aW9uIGlzIGZyZWUgdG8gdGhlIHBvaW50IHdoZXJlIGl0IGlzIG5ldmVyCisgIC8vLyB3b3J0aHdoaWxlIHRvIHJlcGxhY2UgaXQgd2l0aCBhIGJpdHdpc2Ugb3BlcmF0aW9uLgorICB2aXJ0dWFsIGJvb2wgaXNGTmVnRnJlZShFVlQgVlQpIGNvbnN0IHsKKyAgICBhc3NlcnQoVlQuaXNGbG9hdGluZ1BvaW50KCkpOworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBhbiBmYWJzIG9wZXJhdGlvbiBpcyBmcmVlIHRvIHRoZSBwb2ludCB3aGVyZSBpdCBpcyBuZXZlcgorICAvLy8gd29ydGh3aGlsZSB0byByZXBsYWNlIGl0IHdpdGggYSBiaXR3aXNlIG9wZXJhdGlvbi4KKyAgdmlydHVhbCBib29sIGlzRkFic0ZyZWUoRVZUIFZUKSBjb25zdCB7CisgICAgYXNzZXJ0KFZULmlzRmxvYXRpbmdQb2ludCgpKTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgYW4gRk1BIG9wZXJhdGlvbiBpcyBmYXN0ZXIgdGhhbiBhIHBhaXIgb2YgZm11bCBhbmQgZmFkZAorICAvLy8gaW5zdHJ1Y3Rpb25zLiBmbXVsYWRkIGludHJpbnNpY3Mgd2lsbCBiZSBleHBhbmRlZCB0byBGTUFzIHdoZW4gdGhpcyBtZXRob2QKKyAgLy8vIHJldHVybnMgdHJ1ZSwgb3RoZXJ3aXNlIGZtdWxhZGQgaXMgZXhwYW5kZWQgdG8gZm11bCArIGZhZGQuCisgIC8vLworICAvLy8gTk9URTogVGhpcyBtYXkgYmUgY2FsbGVkIGJlZm9yZSBsZWdhbGl6YXRpb24gb24gdHlwZXMgZm9yIHdoaWNoIEZNQXMgYXJlCisgIC8vLyBub3QgbGVnYWwsIGJ1dCBzaG91bGQgcmV0dXJuIHRydWUgaWYgdGhvc2UgdHlwZXMgd2lsbCBldmVudHVhbGx5IGxlZ2FsaXplCisgIC8vLyB0byB0eXBlcyB0aGF0IHN1cHBvcnQgRk1Bcy4gQWZ0ZXIgbGVnYWxpemF0aW9uLCBpdCB3aWxsIG9ubHkgYmUgY2FsbGVkIG9uCisgIC8vLyB0eXBlcyB0aGF0IHN1cHBvcnQgRk1BcyAodmlhIExlZ2FsIG9yIEN1c3RvbSBhY3Rpb25zKQorICB2aXJ0dWFsIGJvb2wgaXNGTUFGYXN0ZXJUaGFuRk11bEFuZEZBZGQoRVZUKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGl0J3MgcHJvZml0YWJsZSB0byBuYXJyb3cgb3BlcmF0aW9ucyBvZiB0eXBlIFZUMSB0bworICAvLy8gVlQyLiBlLmcuIG9uIHg4NiwgaXQncyBwcm9maXRhYmxlIHRvIG5hcnJvdyBmcm9tIGkzMiB0byBpOCBidXQgbm90IGZyb20KKyAgLy8vIGkzMiB0byBpMTYuCisgIHZpcnR1YWwgYm9vbCBpc05hcnJvd2luZ1Byb2ZpdGFibGUoRVZUIC8qVlQxKi8sIEVWVCAvKlZUMiovKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFxicmllZiBSZXR1cm4gdHJ1ZSBpZiBpdCBpcyBiZW5lZmljaWFsIHRvIGNvbnZlcnQgYSBsb2FkIG9mIGEgY29uc3RhbnQgdG8KKyAgLy8vIGp1c3QgdGhlIGNvbnN0YW50IGl0c2VsZi4KKyAgLy8vIE9uIHNvbWUgdGFyZ2V0cyBpdCBtaWdodCBiZSBtb3JlIGVmZmljaWVudCB0byB1c2UgYSBjb21iaW5hdGlvbiBvZgorICAvLy8gYXJpdGhtZXRpYyBpbnN0cnVjdGlvbnMgdG8gbWF0ZXJpYWxpemUgdGhlIGNvbnN0YW50IGluc3RlYWQgb2YgbG9hZGluZyBpdAorICAvLy8gZnJvbSBhIGNvbnN0YW50IHBvb2wuCisgIHZpcnR1YWwgYm9vbCBzaG91bGRDb252ZXJ0Q29uc3RhbnRMb2FkVG9JbnRJbW0oY29uc3QgQVBJbnQgJkltbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlICpUeSkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBFWFRSQUNUX1NVQlZFQ1RPUiBpcyBjaGVhcCBmb3IgZXh0cmFjdGluZyB0aGlzIHJlc3VsdCB0eXBlCisgIC8vLyBmcm9tIHRoaXMgc291cmNlIHR5cGUgd2l0aCB0aGlzIGluZGV4LiBUaGlzIGlzIG5lZWRlZCBiZWNhdXNlCisgIC8vLyBFWFRSQUNUX1NVQlZFQ1RPUiB1c3VhbGx5IGhhcyBjdXN0b20gbG93ZXJpbmcgdGhhdCBkZXBlbmRzIG9uIHRoZSBpbmRleCBvZgorICAvLy8gdGhlIGZpcnN0IGVsZW1lbnQsIGFuZCBvbmx5IHRoZSB0YXJnZXQga25vd3Mgd2hpY2ggbG93ZXJpbmcgaXMgY2hlYXAuCisgIHZpcnR1YWwgYm9vbCBpc0V4dHJhY3RTdWJ2ZWN0b3JDaGVhcChFVlQgUmVzVlQsIEVWVCBTcmNWVCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIEluZGV4KSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8gUmV0dXJuIHRydWUgaWYgaXQgaXMgcHJvZml0YWJsZSB0byB1c2UgYSBzY2FsYXIgaW5wdXQgdG8gYSBCVUlMRF9WRUNUT1IKKyAgLy8gZXZlbiBpZiB0aGUgdmVjdG9yIGl0c2VsZiBoYXMgbXVsdGlwbGUgdXNlcy4KKyAgdmlydHVhbCBib29sIGFnZ3Jlc3NpdmVseVByZWZlckJ1aWxkVmVjdG9yU291cmNlcyhFVlQgVmVjVlQpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gUnVudGltZSBMaWJyYXJ5IGhvb2tzCisgIC8vCisKKyAgLy8vIFJlbmFtZSB0aGUgZGVmYXVsdCBsaWJjYWxsIHJvdXRpbmUgbmFtZSBmb3IgdGhlIHNwZWNpZmllZCBsaWJjYWxsLgorICB2b2lkIHNldExpYmNhbGxOYW1lKFJUTElCOjpMaWJjYWxsIENhbGwsIGNvbnN0IGNoYXIgKk5hbWUpIHsKKyAgICBMaWJjYWxsUm91dGluZU5hbWVzW0NhbGxdID0gTmFtZTsKKyAgfQorCisgIC8vLyBHZXQgdGhlIGxpYmNhbGwgcm91dGluZSBuYW1lIGZvciB0aGUgc3BlY2lmaWVkIGxpYmNhbGwuCisgIGNvbnN0IGNoYXIgKmdldExpYmNhbGxOYW1lKFJUTElCOjpMaWJjYWxsIENhbGwpIGNvbnN0IHsKKyAgICByZXR1cm4gTGliY2FsbFJvdXRpbmVOYW1lc1tDYWxsXTsKKyAgfQorCisgIC8vLyBPdmVycmlkZSB0aGUgZGVmYXVsdCBDb25kQ29kZSB0byBiZSB1c2VkIHRvIHRlc3QgdGhlIHJlc3VsdCBvZiB0aGUKKyAgLy8vIGNvbXBhcmlzb24gbGliY2FsbCBhZ2FpbnN0IHplcm8uCisgIHZvaWQgc2V0Q21wTGliY2FsbENDKFJUTElCOjpMaWJjYWxsIENhbGwsIElTRDo6Q29uZENvZGUgQ0MpIHsKKyAgICBDbXBMaWJjYWxsQ0NzW0NhbGxdID0gQ0M7CisgIH0KKworICAvLy8gR2V0IHRoZSBDb25kQ29kZSB0aGF0J3MgdG8gYmUgdXNlZCB0byB0ZXN0IHRoZSByZXN1bHQgb2YgdGhlIGNvbXBhcmlzb24KKyAgLy8vIGxpYmNhbGwgYWdhaW5zdCB6ZXJvLgorICBJU0Q6OkNvbmRDb2RlIGdldENtcExpYmNhbGxDQyhSVExJQjo6TGliY2FsbCBDYWxsKSBjb25zdCB7CisgICAgcmV0dXJuIENtcExpYmNhbGxDQ3NbQ2FsbF07CisgIH0KKworICAvLy8gU2V0IHRoZSBDYWxsaW5nQ29udiB0aGF0IHNob3VsZCBiZSB1c2VkIGZvciB0aGUgc3BlY2lmaWVkIGxpYmNhbGwuCisgIHZvaWQgc2V0TGliY2FsbENhbGxpbmdDb252KFJUTElCOjpMaWJjYWxsIENhbGwsIENhbGxpbmdDb252OjpJRCBDQykgeworICAgIExpYmNhbGxDYWxsaW5nQ29udnNbQ2FsbF0gPSBDQzsKKyAgfQorCisgIC8vLyBHZXQgdGhlIENhbGxpbmdDb252IHRoYXQgc2hvdWxkIGJlIHVzZWQgZm9yIHRoZSBzcGVjaWZpZWQgbGliY2FsbC4KKyAgQ2FsbGluZ0NvbnY6OklEIGdldExpYmNhbGxDYWxsaW5nQ29udihSVExJQjo6TGliY2FsbCBDYWxsKSBjb25zdCB7CisgICAgcmV0dXJuIExpYmNhbGxDYWxsaW5nQ29udnNbQ2FsbF07CisgIH0KKworICAvLy8gRXhlY3V0ZSB0YXJnZXQgc3BlY2lmaWMgYWN0aW9ucyB0byBmaW5hbGl6ZSB0YXJnZXQgbG93ZXJpbmcuCisgIC8vLyBUaGlzIGlzIHVzZWQgdG8gc2V0IGV4dHJhIGZsYWdzIGluIE1hY2hpbmVGcmFtZUluZm9ybWF0aW9uIGFuZCBmcmVlemluZworICAvLy8gdGhlIHNldCBvZiByZXNlcnZlZCByZWdpc3RlcnMuCisgIC8vLyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBqdXN0IGZyZWV6ZXMgdGhlIHNldCBvZiByZXNlcnZlZCByZWdpc3RlcnMuCisgIHZpcnR1YWwgdm9pZCBmaW5hbGl6ZUxvd2VyaW5nKE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0OworCitwcml2YXRlOgorICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTTsKKworICAvLy8gVGVsbHMgdGhlIGNvZGUgZ2VuZXJhdG9yIHRoYXQgdGhlIHRhcmdldCBoYXMgbXVsdGlwbGUgKGFsbG9jYXRhYmxlKQorICAvLy8gY29uZGl0aW9uIHJlZ2lzdGVycyB0aGF0IGNhbiBiZSB1c2VkIHRvIHN0b3JlIHRoZSByZXN1bHRzIG9mIGNvbXBhcmlzb25zCisgIC8vLyBmb3IgdXNlIGJ5IHNlbGVjdHMgYW5kIGNvbmRpdGlvbmFsIGJyYW5jaGVzLiBXaXRoIG11bHRpcGxlIGNvbmRpdGlvbgorICAvLy8gcmVnaXN0ZXJzLCB0aGUgY29kZSBnZW5lcmF0b3Igd2lsbCBub3QgYWdncmVzc2l2ZWx5IHNpbmsgY29tcGFyaXNvbnMgaW50bworICAvLy8gdGhlIGJsb2NrcyBvZiB0aGVpciB1c2Vycy4KKyAgYm9vbCBIYXNNdWx0aXBsZUNvbmRpdGlvblJlZ2lzdGVyczsKKworICAvLy8gVGVsbHMgdGhlIGNvZGUgZ2VuZXJhdG9yIHRoYXQgdGhlIHRhcmdldCBoYXMgQml0RXh0cmFjdCBpbnN0cnVjdGlvbnMuCisgIC8vLyBUaGUgY29kZSBnZW5lcmF0b3Igd2lsbCBhZ2dyZXNzaXZlbHkgc2luayAic2hpZnQicyBpbnRvIHRoZSBibG9ja3Mgb2YKKyAgLy8vIHRoZWlyIHVzZXJzIGlmIHRoZSB1c2VycyB3aWxsIGdlbmVyYXRlICJhbmQiIGluc3RydWN0aW9ucyB3aGljaCBjYW4gYmUKKyAgLy8vIGNvbWJpbmVkIHdpdGggInNoaWZ0IiB0byBCaXRFeHRyYWN0IGluc3RydWN0aW9ucy4KKyAgYm9vbCBIYXNFeHRyYWN0Qml0c0luc247CisKKyAgLy8vIFRlbGxzIHRoZSBjb2RlIGdlbmVyYXRvciB0byBieXBhc3Mgc2xvdyBkaXZpZGUgb3IgcmVtYWluZGVyCisgIC8vLyBpbnN0cnVjdGlvbnMuIEZvciBleGFtcGxlLCBCeXBhc3NTbG93RGl2V2lkdGhzWzMyLDhdIHRlbGxzIHRoZSBjb2RlCisgIC8vLyBnZW5lcmF0b3IgdG8gYnlwYXNzIDMyLWJpdCBpbnRlZ2VyIGRpdi9yZW0gd2l0aCBhbiA4LWJpdCB1bnNpZ25lZCBpbnRlZ2VyCisgIC8vLyBkaXYvcmVtIHdoZW4gdGhlIG9wZXJhbmRzIGFyZSBwb3NpdGl2ZSBhbmQgbGVzcyB0aGFuIDI1Ni4KKyAgRGVuc2VNYXAgPHVuc2lnbmVkIGludCwgdW5zaWduZWQgaW50PiBCeXBhc3NTbG93RGl2V2lkdGhzOworCisgIC8vLyBUZWxscyB0aGUgY29kZSBnZW5lcmF0b3IgdGhhdCBpdCBzaG91bGRuJ3QgZ2VuZXJhdGUgZXh0cmEgZmxvdyBjb250cm9sCisgIC8vLyBpbnN0cnVjdGlvbnMgYW5kIHNob3VsZCBhdHRlbXB0IHRvIGNvbWJpbmUgZmxvdyBjb250cm9sIGluc3RydWN0aW9ucyB2aWEKKyAgLy8vIHByZWRpY2F0aW9uLgorICBib29sIEp1bXBJc0V4cGVuc2l2ZTsKKworICAvLy8gV2hldGhlciB0aGUgdGFyZ2V0IHN1cHBvcnRzIG9yIGNhcmVzIGFib3V0IHByZXNlcnZpbmcgZmxvYXRpbmcgcG9pbnQKKyAgLy8vIGV4Y2VwdGlvbiBiZWhhdmlvci4KKyAgYm9vbCBIYXNGbG9hdGluZ1BvaW50RXhjZXB0aW9uczsKKworICAvLy8gVGhpcyB0YXJnZXQgcHJlZmVycyB0byB1c2UgX3NldGptcCB0byBpbXBsZW1lbnQgbGx2bS5zZXRqbXAuCisgIC8vLworICAvLy8gRGVmYXVsdHMgdG8gZmFsc2UuCisgIGJvb2wgVXNlVW5kZXJzY29yZVNldEptcDsKKworICAvLy8gVGhpcyB0YXJnZXQgcHJlZmVycyB0byB1c2UgX2xvbmdqbXAgdG8gaW1wbGVtZW50IGxsdm0ubG9uZ2ptcC4KKyAgLy8vCisgIC8vLyBEZWZhdWx0cyB0byBmYWxzZS4KKyAgYm9vbCBVc2VVbmRlcnNjb3JlTG9uZ0ptcDsKKworICAvLy8gSW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvbnRlbnRzIG9mIHRoZSBoaWdoLWJpdHMgaW4gYm9vbGVhbiB2YWx1ZXMgaGVsZCBpbgorICAvLy8gYSB0eXBlIHdpZGVyIHRoYW4gaTEuIFNlZSBnZXRCb29sZWFuQ29udGVudHMuCisgIEJvb2xlYW5Db250ZW50IEJvb2xlYW5Db250ZW50czsKKworICAvLy8gSW5mb3JtYXRpb24gYWJvdXQgdGhlIGNvbnRlbnRzIG9mIHRoZSBoaWdoLWJpdHMgaW4gYm9vbGVhbiB2YWx1ZXMgaGVsZCBpbgorICAvLy8gYSB0eXBlIHdpZGVyIHRoYW4gaTEuIFNlZSBnZXRCb29sZWFuQ29udGVudHMuCisgIEJvb2xlYW5Db250ZW50IEJvb2xlYW5GbG9hdENvbnRlbnRzOworCisgIC8vLyBJbmZvcm1hdGlvbiBhYm91dCB0aGUgY29udGVudHMgb2YgdGhlIGhpZ2gtYml0cyBpbiBib29sZWFuIHZlY3RvciB2YWx1ZXMKKyAgLy8vIHdoZW4gdGhlIGVsZW1lbnQgdHlwZSBpcyB3aWRlciB0aGFuIGkxLiBTZWUgZ2V0Qm9vbGVhbkNvbnRlbnRzLgorICBCb29sZWFuQ29udGVudCBCb29sZWFuVmVjdG9yQ29udGVudHM7CisKKyAgLy8vIFRoZSB0YXJnZXQgc2NoZWR1bGluZyBwcmVmZXJlbmNlOiBzaG9ydGVzdCBwb3NzaWJsZSB0b3RhbCBjeWNsZXMgb3IgbG93ZXN0CisgIC8vLyByZWdpc3RlciB1c2FnZS4KKyAgU2NoZWQ6OlByZWZlcmVuY2UgU2NoZWRQcmVmZXJlbmNlSW5mbzsKKworICAvLy8gVGhlIHNpemUsIGluIGJ5dGVzLCBvZiB0aGUgdGFyZ2V0J3Mgam1wX2J1ZiBidWZmZXJzCisgIHVuc2lnbmVkIEp1bXBCdWZTaXplOworCisgIC8vLyBUaGUgYWxpZ25tZW50LCBpbiBieXRlcywgb2YgdGhlIHRhcmdldCdzIGptcF9idWYgYnVmZmVycworICB1bnNpZ25lZCBKdW1wQnVmQWxpZ25tZW50OworCisgIC8vLyBUaGUgbWluaW11bSBhbGlnbm1lbnQgdGhhdCBhbnkgYXJndW1lbnQgb24gdGhlIHN0YWNrIG5lZWRzIHRvIGhhdmUuCisgIHVuc2lnbmVkIE1pblN0YWNrQXJndW1lbnRBbGlnbm1lbnQ7CisKKyAgLy8vIFRoZSBtaW5pbXVtIGZ1bmN0aW9uIGFsaWdubWVudCAodXNlZCB3aGVuIG9wdGltaXppbmcgZm9yIHNpemUsIGFuZCB0bworICAvLy8gcHJldmVudCBleHBsaWNpdGx5IHByb3ZpZGVkIGFsaWdubWVudCBmcm9tIGxlYWRpbmcgdG8gaW5jb3JyZWN0IGNvZGUpLgorICB1bnNpZ25lZCBNaW5GdW5jdGlvbkFsaWdubWVudDsKKworICAvLy8gVGhlIHByZWZlcnJlZCBmdW5jdGlvbiBhbGlnbm1lbnQgKHVzZWQgd2hlbiBhbGlnbm1lbnQgdW5zcGVjaWZpZWQgYW5kCisgIC8vLyBvcHRpbWl6aW5nIGZvciBzcGVlZCkuCisgIHVuc2lnbmVkIFByZWZGdW5jdGlvbkFsaWdubWVudDsKKworICAvLy8gVGhlIHByZWZlcnJlZCBsb29wIGFsaWdubWVudC4KKyAgdW5zaWduZWQgUHJlZkxvb3BBbGlnbm1lbnQ7CisKKyAgLy8vIFNpemUgaW4gYml0cyBvZiB0aGUgbWF4aW11bSBhdG9taWNzIHNpemUgdGhlIGJhY2tlbmQgc3VwcG9ydHMuCisgIC8vLyBBY2Nlc3NlcyBsYXJnZXIgdGhhbiB0aGlzIHdpbGwgYmUgZXhwYW5kZWQgYnkgQXRvbWljRXhwYW5kUGFzcy4KKyAgdW5zaWduZWQgTWF4QXRvbWljU2l6ZUluQml0c1N1cHBvcnRlZDsKKworICAvLy8gU2l6ZSBpbiBiaXRzIG9mIHRoZSBtaW5pbXVtIGNtcHhjaGcgb3IgbGwvc2Mgb3BlcmF0aW9uIHRoZQorICAvLy8gYmFja2VuZCBzdXBwb3J0cy4KKyAgdW5zaWduZWQgTWluQ21wWGNoZ1NpemVJbkJpdHM7CisKKyAgLy8vIFRoaXMgaW5kaWNhdGVzIGlmIHRoZSB0YXJnZXQgc3VwcG9ydHMgdW5hbGlnbmVkIGF0b21pYyBvcGVyYXRpb25zLgorICBib29sIFN1cHBvcnRzVW5hbGlnbmVkQXRvbWljczsKKworICAvLy8gSWYgc2V0IHRvIGEgcGh5c2ljYWwgcmVnaXN0ZXIsIHRoaXMgc3BlY2lmaWVzIHRoZSByZWdpc3RlciB0aGF0CisgIC8vLyBsbHZtLnNhdmVzdGFjay9sbHZtLnJlc3RvcmVzdGFjayBzaG91bGQgc2F2ZSBhbmQgcmVzdG9yZS4KKyAgdW5zaWduZWQgU3RhY2tQb2ludGVyUmVnaXN0ZXJUb1NhdmVSZXN0b3JlOworCisgIC8vLyBUaGlzIGluZGljYXRlcyB0aGUgZGVmYXVsdCByZWdpc3RlciBjbGFzcyB0byB1c2UgZm9yIGVhY2ggVmFsdWVUeXBlIHRoZQorICAvLy8gdGFyZ2V0IHN1cHBvcnRzIG5hdGl2ZWx5LgorICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSZWdDbGFzc0ZvclZUW01WVDo6TEFTVF9WQUxVRVRZUEVdOworICB1bnNpZ25lZCBjaGFyIE51bVJlZ2lzdGVyc0ZvclZUW01WVDo6TEFTVF9WQUxVRVRZUEVdOworICBNVlQgUmVnaXN0ZXJUeXBlRm9yVlRbTVZUOjpMQVNUX1ZBTFVFVFlQRV07CisKKyAgLy8vIFRoaXMgaW5kaWNhdGVzIHRoZSAicmVwcmVzZW50YXRpdmUiIHJlZ2lzdGVyIGNsYXNzIHRvIHVzZSBmb3IgZWFjaAorICAvLy8gVmFsdWVUeXBlIHRoZSB0YXJnZXQgc3VwcG9ydHMgbmF0aXZlbHkuIFRoaXMgaW5mb3JtYXRpb24gaXMgdXNlZCBieSB0aGUKKyAgLy8vIHNjaGVkdWxlciB0byB0cmFjayByZWdpc3RlciBwcmVzc3VyZS4gQnkgZGVmYXVsdCwgdGhlIHJlcHJlc2VudGF0aXZlCisgIC8vLyByZWdpc3RlciBjbGFzcyBpcyB0aGUgbGFyZ2VzdCBsZWdhbCBzdXBlci1yZWcgcmVnaXN0ZXIgY2xhc3Mgb2YgdGhlCisgIC8vLyByZWdpc3RlciBjbGFzcyBvZiB0aGUgc3BlY2lmaWVkIHR5cGUuIGUuZy4gT24geDg2LCBpOCwgaTE2LCBhbmQgaTMyJ3MKKyAgLy8vIHJlcHJlc2VudGF0aXZlIGNsYXNzIHdvdWxkIGJlIEdSMzIuCisgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJlcFJlZ0NsYXNzRm9yVlRbTVZUOjpMQVNUX1ZBTFVFVFlQRV07CisKKyAgLy8vIFRoaXMgaW5kaWNhdGVzIHRoZSAiY29zdCIgb2YgdGhlICJyZXByZXNlbnRhdGl2ZSIgcmVnaXN0ZXIgY2xhc3MgZm9yIGVhY2gKKyAgLy8vIFZhbHVlVHlwZS4gVGhlIGNvc3QgaXMgdXNlZCBieSB0aGUgc2NoZWR1bGVyIHRvIGFwcHJveGltYXRlIHJlZ2lzdGVyCisgIC8vLyBwcmVzc3VyZS4KKyAgdWludDhfdCBSZXBSZWdDbGFzc0Nvc3RGb3JWVFtNVlQ6OkxBU1RfVkFMVUVUWVBFXTsKKworICAvLy8gRm9yIGFueSB2YWx1ZSB0eXBlcyB3ZSBhcmUgcHJvbW90aW5nIG9yIGV4cGFuZGluZywgdGhpcyBjb250YWlucyB0aGUgdmFsdWUKKyAgLy8vIHR5cGUgdGhhdCB3ZSBhcmUgY2hhbmdpbmcgdG8uICBGb3IgRXhwYW5kZWQgdHlwZXMsIHRoaXMgY29udGFpbnMgb25lIHN0ZXAKKyAgLy8vIG9mIHRoZSBleHBhbmQgKGUuZy4gaTY0IC0+IGkzMiksIGV2ZW4gaWYgdGhlcmUgYXJlIG11bHRpcGxlIHN0ZXBzIHJlcXVpcmVkCisgIC8vLyAoZS5nLiBpNjQgLT4gaTE2KS4gIEZvciB0eXBlcyBuYXRpdmVseSBzdXBwb3J0ZWQgYnkgdGhlIHN5c3RlbSwgdGhpcyBob2xkcworICAvLy8gdGhlIHNhbWUgdHlwZSAoZS5nLiBpMzIgLT4gaTMyKS4KKyAgTVZUIFRyYW5zZm9ybVRvVHlwZVtNVlQ6OkxBU1RfVkFMVUVUWVBFXTsKKworICAvLy8gRm9yIGVhY2ggb3BlcmF0aW9uIGFuZCBlYWNoIHZhbHVlIHR5cGUsIGtlZXAgYSBMZWdhbGl6ZUFjdGlvbiB0aGF0CisgIC8vLyBpbmRpY2F0ZXMgaG93IGluc3RydWN0aW9uIHNlbGVjdGlvbiBzaG91bGQgZGVhbCB3aXRoIHRoZSBvcGVyYXRpb24uICBNb3N0CisgIC8vLyBvcGVyYXRpb25zIGFyZSBMZWdhbCAoYWthLCBzdXBwb3J0ZWQgbmF0aXZlbHkgYnkgdGhlIHRhcmdldCksIGJ1dAorICAvLy8gb3BlcmF0aW9ucyB0aGF0IGFyZSBub3Qgc2hvdWxkIGJlIGRlc2NyaWJlZC4gIE5vdGUgdGhhdCBvcGVyYXRpb25zIG9uCisgIC8vLyBub24tbGVnYWwgdmFsdWUgdHlwZXMgYXJlIG5vdCBkZXNjcmliZWQgaGVyZS4KKyAgTGVnYWxpemVBY3Rpb24gT3BBY3Rpb25zW01WVDo6TEFTVF9WQUxVRVRZUEVdW0lTRDo6QlVJTFRJTl9PUF9FTkRdOworCisgIC8vLyBGb3IgZWFjaCBsb2FkIGV4dGVuc2lvbiB0eXBlIGFuZCBlYWNoIHZhbHVlIHR5cGUsIGtlZXAgYSBMZWdhbGl6ZUFjdGlvbgorICAvLy8gdGhhdCBpbmRpY2F0ZXMgaG93IGluc3RydWN0aW9uIHNlbGVjdGlvbiBzaG91bGQgZGVhbCB3aXRoIGEgbG9hZCBvZiBhCisgIC8vLyBzcGVjaWZpYyB2YWx1ZSB0eXBlIGFuZCBleHRlbnNpb24gdHlwZS4gVXNlcyA0LWJpdHMgdG8gc3RvcmUgdGhlIGFjdGlvbgorICAvLy8gZm9yIGVhY2ggb2YgdGhlIDQgbG9hZCBleHQgdHlwZXMuCisgIHVpbnQxNl90IExvYWRFeHRBY3Rpb25zW01WVDo6TEFTVF9WQUxVRVRZUEVdW01WVDo6TEFTVF9WQUxVRVRZUEVdOworCisgIC8vLyBGb3IgZWFjaCB2YWx1ZSB0eXBlIHBhaXIga2VlcCBhIExlZ2FsaXplQWN0aW9uIHRoYXQgaW5kaWNhdGVzIHdoZXRoZXIgYQorICAvLy8gdHJ1bmNhdGluZyBzdG9yZSBvZiBhIHNwZWNpZmljIHZhbHVlIHR5cGUgYW5kIHRydW5jYXRpbmcgdHlwZSBpcyBsZWdhbC4KKyAgTGVnYWxpemVBY3Rpb24gVHJ1bmNTdG9yZUFjdGlvbnNbTVZUOjpMQVNUX1ZBTFVFVFlQRV1bTVZUOjpMQVNUX1ZBTFVFVFlQRV07CisKKyAgLy8vIEZvciBlYWNoIGluZGV4ZWQgbW9kZSBhbmQgZWFjaCB2YWx1ZSB0eXBlLCBrZWVwIGEgcGFpciBvZiBMZWdhbGl6ZUFjdGlvbgorICAvLy8gdGhhdCBpbmRpY2F0ZXMgaG93IGluc3RydWN0aW9uIHNlbGVjdGlvbiBzaG91bGQgZGVhbCB3aXRoIHRoZSBsb2FkIC8KKyAgLy8vIHN0b3JlLgorICAvLy8KKyAgLy8vIFRoZSBmaXJzdCBkaW1lbnNpb24gaXMgdGhlIHZhbHVlX3R5cGUgZm9yIHRoZSByZWZlcmVuY2UuIFRoZSBzZWNvbmQKKyAgLy8vIGRpbWVuc2lvbiByZXByZXNlbnRzIHRoZSB2YXJpb3VzIG1vZGVzIGZvciBsb2FkIHN0b3JlLgorICB1aW50OF90IEluZGV4ZWRNb2RlQWN0aW9uc1tNVlQ6OkxBU1RfVkFMVUVUWVBFXVtJU0Q6OkxBU1RfSU5ERVhFRF9NT0RFXTsKKworICAvLy8gRm9yIGVhY2ggY29uZGl0aW9uIGNvZGUgKElTRDo6Q29uZENvZGUpIGtlZXAgYSBMZWdhbGl6ZUFjdGlvbiB0aGF0CisgIC8vLyBpbmRpY2F0ZXMgaG93IGluc3RydWN0aW9uIHNlbGVjdGlvbiBzaG91bGQgZGVhbCB3aXRoIHRoZSBjb25kaXRpb24gY29kZS4KKyAgLy8vCisgIC8vLyBCZWNhdXNlIGVhY2ggQ0MgYWN0aW9uIHRha2VzIHVwIDQgYml0cywgd2UgbmVlZCB0byBoYXZlIHRoZSBhcnJheSBzaXplIGJlCisgIC8vLyBsYXJnZSBlbm91Z2ggdG8gZml0IGFsbCBvZiB0aGUgdmFsdWUgdHlwZXMuIFRoaXMgY2FuIGJlIGRvbmUgYnkgcm91bmRpbmcKKyAgLy8vIHVwIHRoZSBNVlQ6OkxBU1RfVkFMVUVUWVBFIHZhbHVlIHRvIHRoZSBuZXh0IG11bHRpcGxlIG9mIDguCisgIHVpbnQzMl90IENvbmRDb2RlQWN0aW9uc1tJU0Q6OlNFVENDX0lOVkFMSURdWyhNVlQ6OkxBU1RfVkFMVUVUWVBFICsgNykgLyA4XTsKKworcHJvdGVjdGVkOgorICBWYWx1ZVR5cGVBY3Rpb25JbXBsIFZhbHVlVHlwZUFjdGlvbnM7CisKK3ByaXZhdGU6CisgIExlZ2FsaXplS2luZCBnZXRUeXBlQ29udmVyc2lvbihMTFZNQ29udGV4dCAmQ29udGV4dCwgRVZUIFZUKSBjb25zdDsKKworICAvLy8gVGFyZ2V0cyBjYW4gc3BlY2lmeSBJU0Qgbm9kZXMgdGhhdCB0aGV5IHdvdWxkIGxpa2UgUGVyZm9ybURBR0NvbWJpbmUKKyAgLy8vIGNhbGxiYWNrcyBmb3IgYnkgY2FsbGluZyBzZXRUYXJnZXREQUdDb21iaW5lKCksIHdoaWNoIHNldHMgYSBiaXQgaW4gdGhpcworICAvLy8gYXJyYXkuCisgIHVuc2lnbmVkIGNoYXIKKyAgVGFyZ2V0REFHQ29tYmluZUFycmF5WyhJU0Q6OkJVSUxUSU5fT1BfRU5EK0NIQVJfQklULTEpL0NIQVJfQklUXTsKKworICAvLy8gRm9yIG9wZXJhdGlvbnMgdGhhdCBtdXN0IGJlIHByb21vdGVkIHRvIGEgc3BlY2lmaWMgdHlwZSwgdGhpcyBob2xkcyB0aGUKKyAgLy8vIGRlc3RpbmF0aW9uIHR5cGUuICBUaGlzIG1hcCBzaG91bGQgYmUgc3BhcnNlLCBzbyBkb24ndCBob2xkIGl0IGFzIGFuCisgIC8vLyBhcnJheS4KKyAgLy8vCisgIC8vLyBUYXJnZXRzIGFkZCBlbnRyaWVzIHRvIHRoaXMgbWFwIHdpdGggQWRkUHJvbW90ZWRUb1R5cGUoLi4pLCBjbGllbnRzIGFjY2VzcworICAvLy8gdGhpcyB3aXRoIGdldFR5cGVUb1Byb21vdGVUbyguLikuCisgIHN0ZDo6bWFwPHN0ZDo6cGFpcjx1bnNpZ25lZCwgTVZUOjpTaW1wbGVWYWx1ZVR5cGU+LCBNVlQ6OlNpbXBsZVZhbHVlVHlwZT4KKyAgICBQcm9tb3RlVG9UeXBlOworCisgIC8vLyBTdG9yZXMgdGhlIG5hbWUgZWFjaCBsaWJjYWxsLgorICBjb25zdCBjaGFyICpMaWJjYWxsUm91dGluZU5hbWVzW1JUTElCOjpVTktOT1dOX0xJQkNBTEwgKyAxXTsKKworICAvLy8gVGhlIElTRDo6Q29uZENvZGUgdGhhdCBzaG91bGQgYmUgdXNlZCB0byB0ZXN0IHRoZSByZXN1bHQgb2YgZWFjaCBvZiB0aGUKKyAgLy8vIGNvbXBhcmlzb24gbGliY2FsbCBhZ2FpbnN0IHplcm8uCisgIElTRDo6Q29uZENvZGUgQ21wTGliY2FsbENDc1tSVExJQjo6VU5LTk9XTl9MSUJDQUxMXTsKKworICAvLy8gU3RvcmVzIHRoZSBDYWxsaW5nQ29udiB0aGF0IHNob3VsZCBiZSB1c2VkIGZvciBlYWNoIGxpYmNhbGwuCisgIENhbGxpbmdDb252OjpJRCBMaWJjYWxsQ2FsbGluZ0NvbnZzW1JUTElCOjpVTktOT1dOX0xJQkNBTExdOworCisgIC8vLyBTZXQgZGVmYXVsdCBsaWJjYWxsIG5hbWVzIGFuZCBjYWxsaW5nIGNvbnZlbnRpb25zLgorICB2b2lkIEluaXRMaWJjYWxscyhjb25zdCBUcmlwbGUgJlRUKTsKKworcHJvdGVjdGVkOgorICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIGV4dGVuc2lvbiByZXByZXNlbnRlZCBieSBccCBJIGlzIGZyZWUuCisgIC8vLyBccHJlIFxwIEkgaXMgYSBzaWduLCB6ZXJvLCBvciBmcCBleHRlbnNpb24gYW5kCisgIC8vLyAgICAgIGlzW1p8RlBdRXh0RnJlZSBvZiB0aGUgcmVsYXRlZCB0eXBlcyBpcyBub3QgdHJ1ZS4KKyAgdmlydHVhbCBib29sIGlzRXh0RnJlZUltcGwoY29uc3QgSW5zdHJ1Y3Rpb24gKkkpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgLy8vIERlcHRoIHRoYXQgR2F0aGVyQWxsQWxpYXNlcyBzaG91bGQgc2hvdWxkIGNvbnRpbnVlIGxvb2tpbmcgZm9yIGNoYWluCisgIC8vLyBkZXBlbmRlbmNpZXMgd2hlbiB0cnlpbmcgdG8gZmluZCBhIG1vcmUgcHJlZmVyYWJsZSBjaGFpbi4gQXMgYW4KKyAgLy8vIGFwcHJveGltYXRpb24sIHRoaXMgc2hvdWxkIGJlIG1vcmUgdGhhbiB0aGUgbnVtYmVyIG9mIGNvbnNlY3V0aXZlIHN0b3JlcworICAvLy8gZXhwZWN0ZWQgdG8gYmUgbWVyZ2VkLgorICB1bnNpZ25lZCBHYXRoZXJBbGxBbGlhc2VzTWF4RGVwdGg7CisKKyAgLy8vIFxicmllZiBTcGVjaWZ5IG1heGltdW0gbnVtYmVyIG9mIHN0b3JlIGluc3RydWN0aW9ucyBwZXIgbWVtc2V0IGNhbGwuCisgIC8vLworICAvLy8gV2hlbiBsb3dlcmluZyBcQGxsdm0ubWVtc2V0IHRoaXMgZmllbGQgc3BlY2lmaWVzIHRoZSBtYXhpbXVtIG51bWJlciBvZgorICAvLy8gc3RvcmUgb3BlcmF0aW9ucyB0aGF0IG1heSBiZSBzdWJzdGl0dXRlZCBmb3IgdGhlIGNhbGwgdG8gbWVtc2V0LiBUYXJnZXRzCisgIC8vLyBtdXN0IHNldCB0aGlzIHZhbHVlIGJhc2VkIG9uIHRoZSBjb3N0IHRocmVzaG9sZCBmb3IgdGhhdCB0YXJnZXQuIFRhcmdldHMKKyAgLy8vIHNob3VsZCBhc3N1bWUgdGhhdCB0aGUgbWVtc2V0IHdpbGwgYmUgZG9uZSB1c2luZyBhcyBtYW55IG9mIHRoZSBsYXJnZXN0CisgIC8vLyBzdG9yZSBvcGVyYXRpb25zIGZpcnN0LCBmb2xsb3dlZCBieSBzbWFsbGVyIG9uZXMsIGlmIG5lY2Vzc2FyeSwgcGVyCisgIC8vLyBhbGlnbm1lbnQgcmVzdHJpY3Rpb25zLiBGb3IgZXhhbXBsZSwgc3RvcmluZyA5IGJ5dGVzIG9uIGEgMzItYml0IG1hY2hpbmUKKyAgLy8vIHdpdGggMTYtYml0IGFsaWdubWVudCB3b3VsZCByZXN1bHQgaW4gZm91ciAyLWJ5dGUgc3RvcmVzIGFuZCBvbmUgMS1ieXRlCisgIC8vLyBzdG9yZS4gIFRoaXMgb25seSBhcHBsaWVzIHRvIHNldHRpbmcgYSBjb25zdGFudCBhcnJheSBvZiBhIGNvbnN0YW50IHNpemUuCisgIHVuc2lnbmVkIE1heFN0b3Jlc1Blck1lbXNldDsKKworICAvLy8gTWF4aW11bSBudW1iZXIgb2Ygc3RvcmVzIG9wZXJhdGlvbnMgdGhhdCBtYXkgYmUgc3Vic3RpdHV0ZWQgZm9yIHRoZSBjYWxsCisgIC8vLyB0byBtZW1zZXQsIHVzZWQgZm9yIGZ1bmN0aW9ucyB3aXRoIE9wdFNpemUgYXR0cmlidXRlLgorICB1bnNpZ25lZCBNYXhTdG9yZXNQZXJNZW1zZXRPcHRTaXplOworCisgIC8vLyBcYnJpZWYgU3BlY2lmeSBtYXhpbXVtIGJ5dGVzIG9mIHN0b3JlIGluc3RydWN0aW9ucyBwZXIgbWVtY3B5IGNhbGwuCisgIC8vLworICAvLy8gV2hlbiBsb3dlcmluZyBcQGxsdm0ubWVtY3B5IHRoaXMgZmllbGQgc3BlY2lmaWVzIHRoZSBtYXhpbXVtIG51bWJlciBvZgorICAvLy8gc3RvcmUgb3BlcmF0aW9ucyB0aGF0IG1heSBiZSBzdWJzdGl0dXRlZCBmb3IgYSBjYWxsIHRvIG1lbWNweS4gVGFyZ2V0cworICAvLy8gbXVzdCBzZXQgdGhpcyB2YWx1ZSBiYXNlZCBvbiB0aGUgY29zdCB0aHJlc2hvbGQgZm9yIHRoYXQgdGFyZ2V0LiBUYXJnZXRzCisgIC8vLyBzaG91bGQgYXNzdW1lIHRoYXQgdGhlIG1lbWNweSB3aWxsIGJlIGRvbmUgdXNpbmcgYXMgbWFueSBvZiB0aGUgbGFyZ2VzdAorICAvLy8gc3RvcmUgb3BlcmF0aW9ucyBmaXJzdCwgZm9sbG93ZWQgYnkgc21hbGxlciBvbmVzLCBpZiBuZWNlc3NhcnksIHBlcgorICAvLy8gYWxpZ25tZW50IHJlc3RyaWN0aW9ucy4gRm9yIGV4YW1wbGUsIHN0b3JpbmcgNyBieXRlcyBvbiBhIDMyLWJpdCBtYWNoaW5lCisgIC8vLyB3aXRoIDMyLWJpdCBhbGlnbm1lbnQgd291bGQgcmVzdWx0IGluIG9uZSA0LWJ5dGUgc3RvcmUsIGEgb25lIDItYnl0ZSBzdG9yZQorICAvLy8gYW5kIG9uZSAxLWJ5dGUgc3RvcmUuIFRoaXMgb25seSBhcHBsaWVzIHRvIGNvcHlpbmcgYSBjb25zdGFudCBhcnJheSBvZgorICAvLy8gY29uc3RhbnQgc2l6ZS4KKyAgdW5zaWduZWQgTWF4U3RvcmVzUGVyTWVtY3B5OworCisgIC8vLyBNYXhpbXVtIG51bWJlciBvZiBzdG9yZSBvcGVyYXRpb25zIHRoYXQgbWF5IGJlIHN1YnN0aXR1dGVkIGZvciBhIGNhbGwgdG8KKyAgLy8vIG1lbWNweSwgdXNlZCBmb3IgZnVuY3Rpb25zIHdpdGggT3B0U2l6ZSBhdHRyaWJ1dGUuCisgIHVuc2lnbmVkIE1heFN0b3Jlc1Blck1lbWNweU9wdFNpemU7CisgIHVuc2lnbmVkIE1heExvYWRzUGVyTWVtY21wOworICB1bnNpZ25lZCBNYXhMb2Fkc1Blck1lbWNtcE9wdFNpemU7CisKKyAgLy8vIFxicmllZiBTcGVjaWZ5IG1heGltdW0gYnl0ZXMgb2Ygc3RvcmUgaW5zdHJ1Y3Rpb25zIHBlciBtZW1tb3ZlIGNhbGwuCisgIC8vLworICAvLy8gV2hlbiBsb3dlcmluZyBcQGxsdm0ubWVtbW92ZSB0aGlzIGZpZWxkIHNwZWNpZmllcyB0aGUgbWF4aW11bSBudW1iZXIgb2YKKyAgLy8vIHN0b3JlIGluc3RydWN0aW9ucyB0aGF0IG1heSBiZSBzdWJzdGl0dXRlZCBmb3IgYSBjYWxsIHRvIG1lbW1vdmUuIFRhcmdldHMKKyAgLy8vIG11c3Qgc2V0IHRoaXMgdmFsdWUgYmFzZWQgb24gdGhlIGNvc3QgdGhyZXNob2xkIGZvciB0aGF0IHRhcmdldC4gVGFyZ2V0cworICAvLy8gc2hvdWxkIGFzc3VtZSB0aGF0IHRoZSBtZW1tb3ZlIHdpbGwgYmUgZG9uZSB1c2luZyBhcyBtYW55IG9mIHRoZSBsYXJnZXN0CisgIC8vLyBzdG9yZSBvcGVyYXRpb25zIGZpcnN0LCBmb2xsb3dlZCBieSBzbWFsbGVyIG9uZXMsIGlmIG5lY2Vzc2FyeSwgcGVyCisgIC8vLyBhbGlnbm1lbnQgcmVzdHJpY3Rpb25zLiBGb3IgZXhhbXBsZSwgbW92aW5nIDkgYnl0ZXMgb24gYSAzMi1iaXQgbWFjaGluZQorICAvLy8gd2l0aCA4LWJpdCBhbGlnbm1lbnQgd291bGQgcmVzdWx0IGluIG5pbmUgMS1ieXRlIHN0b3Jlcy4gIFRoaXMgb25seQorICAvLy8gYXBwbGllcyB0byBjb3B5aW5nIGEgY29uc3RhbnQgYXJyYXkgb2YgY29uc3RhbnQgc2l6ZS4KKyAgdW5zaWduZWQgTWF4U3RvcmVzUGVyTWVtbW92ZTsKKworICAvLy8gTWF4aW11bSBudW1iZXIgb2Ygc3RvcmUgaW5zdHJ1Y3Rpb25zIHRoYXQgbWF5IGJlIHN1YnN0aXR1dGVkIGZvciBhIGNhbGwgdG8KKyAgLy8vIG1lbW1vdmUsIHVzZWQgZm9yIGZ1bmN0aW9ucyB3aXRoIE9wdFNpemUgYXR0cmlidXRlLgorICB1bnNpZ25lZCBNYXhTdG9yZXNQZXJNZW1tb3ZlT3B0U2l6ZTsKKworICAvLy8gVGVsbHMgdGhlIGNvZGUgZ2VuZXJhdG9yIHRoYXQgc2VsZWN0IGlzIG1vcmUgZXhwZW5zaXZlIHRoYW4gYSBicmFuY2ggaWYKKyAgLy8vIHRoZSBicmFuY2ggaXMgdXN1YWxseSBwcmVkaWN0ZWQgcmlnaHQuCisgIGJvb2wgUHJlZGljdGFibGVTZWxlY3RJc0V4cGVuc2l2ZTsKKworICAvLy8gXHNlZSBlbmFibGVFeHRMZFByb21vdGlvbi4KKyAgYm9vbCBFbmFibGVFeHRMZFByb21vdGlvbjsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHZhbHVlIHR5cGVzIHRoYXQgY2FuIGJlIHJlcHJlc2VudGVkIGJ5IHRoZSBzcGVjaWZpZWQKKyAgLy8vIHJlZ2lzdGVyIGNsYXNzIGFyZSBhbGwgbGVnYWwuCisgIGJvb2wgaXNMZWdhbFJDKGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAmVFJJLAorICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICZSQykgY29uc3Q7CisKKyAgLy8vIFJlcGxhY2UvbW9kaWZ5IGFueSBUYXJnZXRGcmFtZUluZGV4IG9wZXJhbmRzIHdpdGggYSB0YXJndGUtZGVwZW5kZW50CisgIC8vLyBzZXF1ZW5jZSBvZiBtZW1vcnkgb3BlcmFuZHMgdGhhdCBpcyByZWNvZ25pemVkIGJ5IFByb2xvZ0VwaWxvZ0luc2VydGVyLgorICBNYWNoaW5lQmFzaWNCbG9jayAqZW1pdFBhdGNoUG9pbnQoTWFjaGluZUluc3RyICZNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVCYXNpY0Jsb2NrICpNQkIpIGNvbnN0OworCisgIC8vLyBSZXBsYWNlL21vZGlmeSB0aGUgWFJheSBjdXN0b20gZXZlbnQgb3BlcmFuZHMgd2l0aCB0YXJnZXQtZGVwZW5kZW50CisgIC8vLyBkZXRhaWxzLgorICBNYWNoaW5lQmFzaWNCbG9jayAqZW1pdFhSYXlDdXN0b21FdmVudChNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lQmFzaWNCbG9jayAqTUJCKSBjb25zdDsKK307CisKKy8vLyBUaGlzIGNsYXNzIGRlZmluZXMgaW5mb3JtYXRpb24gdXNlZCB0byBsb3dlciBMTFZNIGNvZGUgdG8gbGVnYWwgU2VsZWN0aW9uREFHCisvLy8gb3BlcmF0b3JzIHRoYXQgdGhlIHRhcmdldCBpbnN0cnVjdGlvbiBzZWxlY3RvciBjYW4gYWNjZXB0IG5hdGl2ZWx5LgorLy8vCisvLy8gVGhpcyBjbGFzcyBhbHNvIGRlZmluZXMgY2FsbGJhY2tzIHRoYXQgdGFyZ2V0cyBtdXN0IGltcGxlbWVudCB0byBsb3dlcgorLy8vIHRhcmdldC1zcGVjaWZpYyBjb25zdHJ1Y3RzIHRvIFNlbGVjdGlvbkRBRyBvcGVyYXRvcnMuCitjbGFzcyBUYXJnZXRMb3dlcmluZyA6IHB1YmxpYyBUYXJnZXRMb3dlcmluZ0Jhc2UgeworcHVibGljOgorICBzdHJ1Y3QgREFHQ29tYmluZXJJbmZvOworCisgIFRhcmdldExvd2VyaW5nKGNvbnN0IFRhcmdldExvd2VyaW5nICYpID0gZGVsZXRlOworICBUYXJnZXRMb3dlcmluZyAmb3BlcmF0b3I9KGNvbnN0IFRhcmdldExvd2VyaW5nICYpID0gZGVsZXRlOworCisgIC8vLyBOT1RFOiBUaGUgVGFyZ2V0TWFjaGluZSBvd25zIFRMT0YuCisgIGV4cGxpY2l0IFRhcmdldExvd2VyaW5nKGNvbnN0IFRhcmdldE1hY2hpbmUgJlRNKTsKKworICBib29sIGlzUG9zaXRpb25JbmRlcGVuZGVudCgpIGNvbnN0OworCisgIHZpcnR1YWwgYm9vbCBpc1NETm9kZVNvdXJjZU9mRGl2ZXJnZW5jZShjb25zdCBTRE5vZGUgKk4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGdW5jdGlvbkxvd2VyaW5nSW5mbyAqRkxJLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGl2ZXJnZW5jZUFuYWx5c2lzICpEQSkgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIHZpcnR1YWwgYm9vbCBpc1NETm9kZUFsd2F5c1VuaWZvcm0oY29uc3QgU0ROb2RlICogTikgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgYnkgdmFsdWUsIGJhc2UgcG9pbnRlciBhbmQgb2Zmc2V0IHBvaW50ZXIgYW5kIGFkZHJlc3NpbmcgbW9kZQorICAvLy8gYnkgcmVmZXJlbmNlIGlmIHRoZSBub2RlJ3MgYWRkcmVzcyBjYW4gYmUgbGVnYWxseSByZXByZXNlbnRlZCBhcworICAvLy8gcHJlLWluZGV4ZWQgbG9hZCAvIHN0b3JlIGFkZHJlc3MuCisgIHZpcnR1YWwgYm9vbCBnZXRQcmVJbmRleGVkQWRkcmVzc1BhcnRzKFNETm9kZSAqIC8qTiovLCBTRFZhbHVlICYvKkJhc2UqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSAmLypPZmZzZXQqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVNEOjpNZW1JbmRleGVkTW9kZSAmLypBTSovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3Rpb25EQUcgJi8qREFHKi8pIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJucyB0cnVlIGJ5IHZhbHVlLCBiYXNlIHBvaW50ZXIgYW5kIG9mZnNldCBwb2ludGVyIGFuZCBhZGRyZXNzaW5nIG1vZGUKKyAgLy8vIGJ5IHJlZmVyZW5jZSBpZiB0aGlzIG5vZGUgY2FuIGJlIGNvbWJpbmVkIHdpdGggYSBsb2FkIC8gc3RvcmUgdG8gZm9ybSBhCisgIC8vLyBwb3N0LWluZGV4ZWQgbG9hZCAvIHN0b3JlLgorICB2aXJ0dWFsIGJvb2wgZ2V0UG9zdEluZGV4ZWRBZGRyZXNzUGFydHMoU0ROb2RlICogLypOKi8sIFNETm9kZSAqIC8qT3AqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgJi8qQmFzZSovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSAmLypPZmZzZXQqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElTRDo6TWVtSW5kZXhlZE1vZGUgJi8qQU0qLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdGlvbkRBRyAmLypEQUcqLykgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIGVudHJ5IGVuY29kaW5nIGZvciBhIGp1bXAgdGFibGUgaW4gdGhlIGN1cnJlbnQgZnVuY3Rpb24uICBUaGUKKyAgLy8vIHJldHVybmVkIHZhbHVlIGlzIGEgbWVtYmVyIG9mIHRoZSBNYWNoaW5lSnVtcFRhYmxlSW5mbzo6SlRFbnRyeUtpbmQgZW51bS4KKyAgdmlydHVhbCB1bnNpZ25lZCBnZXRKdW1wVGFibGVFbmNvZGluZygpIGNvbnN0OworCisgIHZpcnR1YWwgY29uc3QgTUNFeHByICoKKyAgTG93ZXJDdXN0b21KdW1wVGFibGVFbnRyeShjb25zdCBNYWNoaW5lSnVtcFRhYmxlSW5mbyAqIC8qTUpUSSovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVCYXNpY0Jsb2NrICogLypNQkIqLywgdW5zaWduZWQgLyp1aWQqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQ0NvbnRleHQgJi8qQ3R4Ki8pIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJOZWVkIHRvIGltcGxlbWVudCB0aGlzIGhvb2sgaWYgdGFyZ2V0IGhhcyBjdXN0b20gSlRJcyIpOworICB9CisKKyAgLy8vIFJldHVybnMgcmVsb2NhdGlvbiBiYXNlIGZvciB0aGUgZ2l2ZW4gUElDIGp1bXB0YWJsZS4KKyAgdmlydHVhbCBTRFZhbHVlIGdldFBJQ0p1bXBUYWJsZVJlbG9jQmFzZShTRFZhbHVlIFRhYmxlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdGlvbkRBRyAmREFHKSBjb25zdDsKKworICAvLy8gVGhpcyByZXR1cm5zIHRoZSByZWxvY2F0aW9uIGJhc2UgZm9yIHRoZSBnaXZlbiBQSUMganVtcHRhYmxlLCB0aGUgc2FtZSBhcworICAvLy8gZ2V0UElDSnVtcFRhYmxlUmVsb2NCYXNlLCBidXQgYXMgYW4gTUNFeHByLgorICB2aXJ0dWFsIGNvbnN0IE1DRXhwciAqCisgIGdldFBJQ0p1bXBUYWJsZVJlbG9jQmFzZUV4cHIoY29uc3QgTWFjaGluZUZ1bmN0aW9uICpNRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBKVEksIE1DQ29udGV4dCAmQ3R4KSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgZm9sZGluZyBhIGNvbnN0YW50IG9mZnNldCB3aXRoIHRoZSBnaXZlbiBHbG9iYWxBZGRyZXNzIGlzCisgIC8vLyBsZWdhbC4gIEl0IGlzIGZyZXF1ZW50bHkgbm90IGxlZ2FsIGluIFBJQyByZWxvY2F0aW9uIG1vZGVscy4KKyAgdmlydHVhbCBib29sIGlzT2Zmc2V0Rm9sZGluZ0xlZ2FsKGNvbnN0IEdsb2JhbEFkZHJlc3NTRE5vZGUgKkdBKSBjb25zdDsKKworICBib29sIGlzSW5UYWlsQ2FsbFBvc2l0aW9uKFNlbGVjdGlvbkRBRyAmREFHLCBTRE5vZGUgKk5vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSAmQ2hhaW4pIGNvbnN0OworCisgIHZvaWQgc29mdGVuU2V0Q0NPcGVyYW5kcyhTZWxlY3Rpb25EQUcgJkRBRywgRVZUIFZULCBTRFZhbHVlICZOZXdMSFMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlICZOZXdSSFMsIElTRDo6Q29uZENvZGUgJkNDQ29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNETG9jICZETCkgY29uc3Q7CisKKyAgLy8vIFJldHVybnMgYSBwYWlyIG9mIChyZXR1cm4gdmFsdWUsIGNoYWluKS4KKyAgLy8vIEl0IGlzIGFuIGVycm9yIHRvIHBhc3MgUlRMSUI6OlVOS05PV05fTElCQ0FMTCBhcyBccCBMQy4KKyAgc3RkOjpwYWlyPFNEVmFsdWUsIFNEVmFsdWU+IG1ha2VMaWJDYWxsKFNlbGVjdGlvbkRBRyAmREFHLCBSVExJQjo6TGliY2FsbCBMQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVWVCBSZXRWVCwgQXJyYXlSZWY8U0RWYWx1ZT4gT3BzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBpc1NpZ25lZCwgY29uc3QgU0RMb2MgJmRsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBkb2VzTm90UmV0dXJuID0gZmFsc2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGlzUmV0dXJuVmFsdWVVc2VkID0gdHJ1ZSkgY29uc3Q7CisKKyAgLy8vIENoZWNrIHdoZXRoZXIgcGFyYW1ldGVycyB0byBhIGNhbGwgdGhhdCBhcmUgcGFzc2VkIGluIGNhbGxlZSBzYXZlZAorICAvLy8gcmVnaXN0ZXJzIGFyZSB0aGUgc2FtZSBhcyBmcm9tIHRoZSBjYWxsaW5nIGZ1bmN0aW9uLiAgVGhpcyBuZWVkcyB0byBiZQorICAvLy8gY2hlY2tlZCBmb3IgdGFpbCBjYWxsIGVsaWdpYmlsaXR5LgorICBib29sIHBhcmFtZXRlcnNJbkNTUk1hdGNoKGNvbnN0IE1hY2hpbmVSZWdpc3RlckluZm8gJk1SSSwKKyAgICAgIGNvbnN0IHVpbnQzMl90ICpDYWxsZXJQcmVzZXJ2ZWRNYXNrLAorICAgICAgY29uc3QgU21hbGxWZWN0b3JJbXBsPENDVmFsQXNzaWduPiAmQXJnTG9jcywKKyAgICAgIGNvbnN0IFNtYWxsVmVjdG9ySW1wbDxTRFZhbHVlPiAmT3V0VmFscykgY29uc3Q7CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIFRhcmdldExvd2VyaW5nIE9wdGltaXphdGlvbiBNZXRob2RzCisgIC8vCisKKyAgLy8vIEEgY29udmVuaWVuY2Ugc3RydWN0IHRoYXQgZW5jYXBzdWxhdGVzIGEgREFHLCBhbmQgdHdvIFNEVmFsdWVzIGZvcgorICAvLy8gcmV0dXJuaW5nIGluZm9ybWF0aW9uIGZyb20gVGFyZ2V0TG93ZXJpbmcgdG8gaXRzIGNsaWVudHMgdGhhdCB3YW50IHRvCisgIC8vLyBjb21iaW5lLgorICBzdHJ1Y3QgVGFyZ2V0TG93ZXJpbmdPcHQgeworICAgIFNlbGVjdGlvbkRBRyAmREFHOworICAgIGJvb2wgTGVnYWxUeXM7CisgICAgYm9vbCBMZWdhbE9wczsKKyAgICBTRFZhbHVlIE9sZDsKKyAgICBTRFZhbHVlIE5ldzsKKworICAgIGV4cGxpY2l0IFRhcmdldExvd2VyaW5nT3B0KFNlbGVjdGlvbkRBRyAmSW5EQUcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBMVCwgYm9vbCBMTykgOgorICAgICAgREFHKEluREFHKSwgTGVnYWxUeXMoTFQpLCBMZWdhbE9wcyhMTykge30KKworICAgIGJvb2wgTGVnYWxUeXBlcygpIGNvbnN0IHsgcmV0dXJuIExlZ2FsVHlzOyB9CisgICAgYm9vbCBMZWdhbE9wZXJhdGlvbnMoKSBjb25zdCB7IHJldHVybiBMZWdhbE9wczsgfQorCisgICAgYm9vbCBDb21iaW5lVG8oU0RWYWx1ZSBPLCBTRFZhbHVlIE4pIHsKKyAgICAgIE9sZCA9IE87CisgICAgICBOZXcgPSBOOworICAgICAgcmV0dXJuIHRydWU7CisgICAgfQorICB9OworCisgIC8vLyBDaGVjayB0byBzZWUgaWYgdGhlIHNwZWNpZmllZCBvcGVyYW5kIG9mIHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24gaXMgYQorICAvLy8gY29uc3RhbnQgaW50ZWdlci4gIElmIHNvLCBjaGVjayB0byBzZWUgaWYgdGhlcmUgYXJlIGFueSBiaXRzIHNldCBpbiB0aGUKKyAgLy8vIGNvbnN0YW50IHRoYXQgYXJlIG5vdCBkZW1hbmRlZC4gIElmIHNvLCBzaHJpbmsgdGhlIGNvbnN0YW50IGFuZCByZXR1cm4KKyAgLy8vIHRydWUuCisgIGJvb2wgU2hyaW5rRGVtYW5kZWRDb25zdGFudChTRFZhbHVlIE9wLCBjb25zdCBBUEludCAmRGVtYW5kZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUYXJnZXRMb3dlcmluZ09wdCAmVExPKSBjb25zdDsKKworICAvLyBUYXJnZXQgaG9vayB0byBkbyB0YXJnZXQtc3BlY2lmaWMgY29uc3Qgb3B0aW1pemF0aW9uLCB3aGljaCBpcyBjYWxsZWQgYnkKKyAgLy8gU2hyaW5rRGVtYW5kZWRDb25zdGFudC4gVGhpcyBmdW5jdGlvbiBzaG91bGQgcmV0dXJuIHRydWUgaWYgdGhlIHRhcmdldAorICAvLyBkb2Vzbid0IHdhbnQgU2hyaW5rRGVtYW5kZWRDb25zdGFudCB0byBmdXJ0aGVyIG9wdGltaXplIHRoZSBjb25zdGFudC4KKyAgdmlydHVhbCBib29sIHRhcmdldFNocmlua0RlbWFuZGVkQ29uc3RhbnQoU0RWYWx1ZSBPcCwgY29uc3QgQVBJbnQgJkRlbWFuZGVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUYXJnZXRMb3dlcmluZ09wdCAmVExPKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIENvbnZlcnQgeCt5IHRvIChWVCkoKFNtYWxsVlQpeCsoU21hbGxWVCl5KSBpZiB0aGUgY2FzdHMgYXJlIGZyZWUuICBUaGlzCisgIC8vLyB1c2VzIGlzWkV4dEZyZWUgYW5kIFpFUk9fRVhURU5EIGZvciB0aGUgd2lkZW5pbmcgY2FzdCwgYnV0IGl0IGNvdWxkIGJlCisgIC8vLyBnZW5lcmFsaXplZCBmb3IgdGFyZ2V0cyB3aXRoIG90aGVyIHR5cGVzIG9mIGltcGxpY2l0IHdpZGVuaW5nIGNhc3RzLgorICBib29sIFNocmlua0RlbWFuZGVkT3AoU0RWYWx1ZSBPcCwgdW5zaWduZWQgQml0V2lkdGgsIGNvbnN0IEFQSW50ICZEZW1hbmRlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFRhcmdldExvd2VyaW5nT3B0ICZUTE8pIGNvbnN0OworCisgIC8vLyBIZWxwZXIgZm9yIFNpbXBsaWZ5RGVtYW5kZWRCaXRzIHRoYXQgY2FuIHNpbXBsaWZ5IGFuIG9wZXJhdGlvbiB3aXRoCisgIC8vLyBtdWx0aXBsZSB1c2VzLiAgVGhpcyBmdW5jdGlvbiBzaW1wbGlmaWVzIG9wZXJhbmQgXHAgT3BJZHggb2YgXHAgVXNlciBhbmQKKyAgLy8vIHRoZW4gdXBkYXRlcyBccCBVc2VyIHdpdGggdGhlIHNpbXBsaWZpZWQgdmVyc2lvbi4gTm8gb3RoZXIgdXNlcyBvZgorICAvLy8gXHAgT3BJZHggYXJlIHVwZGF0ZWQuIElmIFxwIFVzZXIgaXMgdGhlIG9ubHkgdXNlciBvZiBccCBPcElkeCwgdGhpcworICAvLy8gZnVuY3Rpb24gYmVoYXZlcyBleGFjdGx5IGxpa2UgZnVuY3Rpb24gU2ltcGxpZnlEZW1hbmRlZEJpdHMgZGVjbGFyZWQKKyAgLy8vIGJlbG93IGV4Y2VwdCB0aGF0IGl0IGFsc28gdXBkYXRlcyB0aGUgREFHIGJ5IGNhbGxpbmcKKyAgLy8vIERDSS5Db21taXRUYXJnZXRMb3dlcmluZ09wdC4KKyAgYm9vbCBTaW1wbGlmeURlbWFuZGVkQml0cyhTRE5vZGUgKlVzZXIsIHVuc2lnbmVkIE9wSWR4LCBjb25zdCBBUEludCAmRGVtYW5kZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgREFHQ29tYmluZXJJbmZvICZEQ0ksIFRhcmdldExvd2VyaW5nT3B0ICZUTE8pIGNvbnN0OworCisgIC8vLyBMb29rIGF0IE9wLiAgQXQgdGhpcyBwb2ludCwgd2Uga25vdyB0aGF0IG9ubHkgdGhlIERlbWFuZGVkTWFzayBiaXRzIG9mIHRoZQorICAvLy8gcmVzdWx0IG9mIE9wIGFyZSBldmVyIHVzZWQgZG93bnN0cmVhbS4gIElmIHdlIGNhbiB1c2UgdGhpcyBpbmZvcm1hdGlvbiB0bworICAvLy8gc2ltcGxpZnkgT3AsIGNyZWF0ZSBhIG5ldyBzaW1wbGlmaWVkIERBRyBub2RlIGFuZCByZXR1cm4gdHJ1ZSwgcmV0dXJuaW5nCisgIC8vLyB0aGUgb3JpZ2luYWwgYW5kIG5ldyBub2RlcyBpbiBPbGQgYW5kIE5ldy4gIE90aGVyd2lzZSwgYW5hbHl6ZSB0aGUKKyAgLy8vIGV4cHJlc3Npb24gYW5kIHJldHVybiBhIG1hc2sgb2YgS25vd25PbmUgYW5kIEtub3duWmVybyBiaXRzIGZvciB0aGUKKyAgLy8vIGV4cHJlc3Npb24gKHVzZWQgdG8gc2ltcGxpZnkgdGhlIGNhbGxlcikuICBUaGUgS25vd25aZXJvL09uZSBiaXRzIG1heSBvbmx5CisgIC8vLyBiZSBhY2N1cmF0ZSBmb3IgdGhvc2UgYml0cyBpbiB0aGUgRGVtYW5kZWRNYXNrLgorICAvLy8gXHAgQXNzdW1lU2luZ2xlVXNlIFdoZW4gdGhpcyBwYXJhbWV0ZXIgaXMgdHJ1ZSwgdGhpcyBmdW5jdGlvbiB3aWxsCisgIC8vLyAgICBhdHRlbXB0IHRvIHNpbXBsaWZ5IFxwIE9wIGV2ZW4gaWYgdGhlcmUgYXJlIG11bHRpcGxlIHVzZXMuCisgIC8vLyAgICBDYWxsZXJzIGFyZSByZXNwb25zaWJsZSBmb3IgY29ycmVjdGx5IHVwZGF0aW5nIHRoZSBEQUcgYmFzZWQgb24gdGhlCisgIC8vLyAgICByZXN1bHRzIG9mIHRoaXMgZnVuY3Rpb24sIGJlY2F1c2Ugc2ltcGx5IHJlcGxhY2luZyByZXBsYWNpbmcgVExPLk9sZAorICAvLy8gICAgd2l0aCBUTE8uTmV3IHdpbGwgYmUgaW5jb3JyZWN0IHdoZW4gdGhpcyBwYXJhbWV0ZXIgaXMgdHJ1ZSBhbmQgVExPLk9sZAorICAvLy8gICAgaGFzIG11bHRpcGxlIHVzZXMuCisgIGJvb2wgU2ltcGxpZnlEZW1hbmRlZEJpdHMoU0RWYWx1ZSBPcCwgY29uc3QgQVBJbnQgJkRlbWFuZGVkTWFzaywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBLbm93bkJpdHMgJktub3duLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRhcmdldExvd2VyaW5nT3B0ICZUTE8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgRGVwdGggPSAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgQXNzdW1lU2luZ2xlVXNlID0gZmFsc2UpIGNvbnN0OworCisgIC8vLyBIZWxwZXIgd3JhcHBlciBhcm91bmQgU2ltcGxpZnlEZW1hbmRlZEJpdHMKKyAgYm9vbCBTaW1wbGlmeURlbWFuZGVkQml0cyhTRFZhbHVlIE9wLCBjb25zdCBBUEludCAmRGVtYW5kZWRNYXNrLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIERBR0NvbWJpbmVySW5mbyAmRENJKSBjb25zdDsKKworICAvLy8gTG9vayBhdCBWZWN0b3IgT3AuIEF0IHRoaXMgcG9pbnQsIHdlIGtub3cgdGhhdCBvbmx5IHRoZSBEZW1hbmRlZEVsdHMKKyAgLy8vIGVsZW1lbnRzIG9mIHRoZSByZXN1bHQgb2YgT3AgYXJlIGV2ZXIgdXNlZCBkb3duc3RyZWFtLiAgSWYgd2UgY2FuIHVzZQorICAvLy8gdGhpcyBpbmZvcm1hdGlvbiB0byBzaW1wbGlmeSBPcCwgY3JlYXRlIGEgbmV3IHNpbXBsaWZpZWQgREFHIG5vZGUgYW5kCisgIC8vLyByZXR1cm4gdHJ1ZSwgc3RvcmluZyB0aGUgb3JpZ2luYWwgYW5kIG5ldyBub2RlcyBpbiBUTE8uCisgIC8vLyBPdGhlcndpc2UsIGFuYWx5emUgdGhlIGV4cHJlc3Npb24gYW5kIHJldHVybiBhIG1hc2sgb2YgS25vd25VbmRlZiBhbmQKKyAgLy8vIEtub3duWmVybyBlbGVtZW50cyBmb3IgdGhlIGV4cHJlc3Npb24gKHVzZWQgdG8gc2ltcGxpZnkgdGhlIGNhbGxlcikuCisgIC8vLyBUaGUgS25vd25VbmRlZi9aZXJvIGVsZW1lbnRzIG1heSBvbmx5IGJlIGFjY3VyYXRlIGZvciB0aG9zZSBiaXRzCisgIC8vLyBpbiB0aGUgRGVtYW5kZWRNYXNrLgorICAvLy8gXHAgQXNzdW1lU2luZ2xlVXNlIFdoZW4gdGhpcyBwYXJhbWV0ZXIgaXMgdHJ1ZSwgdGhpcyBmdW5jdGlvbiB3aWxsCisgIC8vLyAgICBhdHRlbXB0IHRvIHNpbXBsaWZ5IFxwIE9wIGV2ZW4gaWYgdGhlcmUgYXJlIG11bHRpcGxlIHVzZXMuCisgIC8vLyAgICBDYWxsZXJzIGFyZSByZXNwb25zaWJsZSBmb3IgY29ycmVjdGx5IHVwZGF0aW5nIHRoZSBEQUcgYmFzZWQgb24gdGhlCisgIC8vLyAgICByZXN1bHRzIG9mIHRoaXMgZnVuY3Rpb24sIGJlY2F1c2Ugc2ltcGx5IHJlcGxhY2luZyByZXBsYWNpbmcgVExPLk9sZAorICAvLy8gICAgd2l0aCBUTE8uTmV3IHdpbGwgYmUgaW5jb3JyZWN0IHdoZW4gdGhpcyBwYXJhbWV0ZXIgaXMgdHJ1ZSBhbmQgVExPLk9sZAorICAvLy8gICAgaGFzIG11bHRpcGxlIHVzZXMuCisgIGJvb2wgU2ltcGxpZnlEZW1hbmRlZFZlY3RvckVsdHMoU0RWYWx1ZSBPcCwgY29uc3QgQVBJbnQgJkRlbWFuZGVkRWx0cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBUEludCAmS25vd25VbmRlZiwgQVBJbnQgJktub3duWmVybywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUYXJnZXRMb3dlcmluZ09wdCAmVExPLCB1bnNpZ25lZCBEZXB0aCA9IDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBBc3N1bWVTaW5nbGVVc2UgPSBmYWxzZSkgY29uc3Q7CisKKyAgLy8vIEhlbHBlciB3cmFwcGVyIGFyb3VuZCBTaW1wbGlmeURlbWFuZGVkVmVjdG9yRWx0cworICBib29sIFNpbXBsaWZ5RGVtYW5kZWRWZWN0b3JFbHRzKFNEVmFsdWUgT3AsIGNvbnN0IEFQSW50ICZEZW1hbmRlZEVsdHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVBJbnQgJktub3duVW5kZWYsIEFQSW50ICZLbm93blplcm8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgREFHQ29tYmluZXJJbmZvICZEQ0kpIGNvbnN0OworCisgIC8vLyBEZXRlcm1pbmUgd2hpY2ggb2YgdGhlIGJpdHMgc3BlY2lmaWVkIGluIE1hc2sgYXJlIGtub3duIHRvIGJlIGVpdGhlciB6ZXJvCisgIC8vLyBvciBvbmUgYW5kIHJldHVybiB0aGVtIGluIHRoZSBLbm93blplcm8vS25vd25PbmUgYml0c2V0cy4gVGhlIERlbWFuZGVkRWx0cworICAvLy8gYXJndW1lbnQgYWxsb3dzIHVzIHRvIG9ubHkgY29sbGVjdCB0aGUga25vd24gYml0cyB0aGF0IGFyZSBzaGFyZWQgYnkgdGhlCisgIC8vLyByZXF1ZXN0ZWQgdmVjdG9yIGVsZW1lbnRzLgorICB2aXJ0dWFsIHZvaWQgY29tcHV0ZUtub3duQml0c0ZvclRhcmdldE5vZGUoY29uc3QgU0RWYWx1ZSBPcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtub3duQml0cyAmS25vd24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBUEludCAmRGVtYW5kZWRFbHRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2VsZWN0aW9uREFHICZEQUcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBEZXB0aCA9IDApIGNvbnN0OworCisgIC8vLyBEZXRlcm1pbmUgd2hpY2ggb2YgdGhlIGJpdHMgb2YgRnJhbWVJbmRleCBccCBGSU9wIGFyZSBrbm93biB0byBiZSAwLgorICAvLy8gRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBjb21wdXRlcyBsb3cgYml0cyBiYXNlZCBvbiBhbGlnbm1lbnQKKyAgLy8vIGluZm9ybWF0aW9uLiBUaGlzIHNob3VsZCBwcmVzZXJ2ZSBrbm93biBiaXRzIHBhc3NlZCBpbnRvIGl0LgorICB2aXJ0dWFsIHZvaWQgY29tcHV0ZUtub3duQml0c0ZvckZyYW1lSW5kZXgoY29uc3QgU0RWYWx1ZSBGSU9wLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS25vd25CaXRzICZLbm93biwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFQSW50ICZEZW1hbmRlZEVsdHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTZWxlY3Rpb25EQUcgJkRBRywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIERlcHRoID0gMCkgY29uc3Q7CisKKyAgLy8vIFRoaXMgbWV0aG9kIGNhbiBiZSBpbXBsZW1lbnRlZCBieSB0YXJnZXRzIHRoYXQgd2FudCB0byBleHBvc2UgYWRkaXRpb25hbAorICAvLy8gaW5mb3JtYXRpb24gYWJvdXQgc2lnbiBiaXRzIHRvIHRoZSBEQUcgQ29tYmluZXIuIFRoZSBEZW1hbmRlZEVsdHMKKyAgLy8vIGFyZ3VtZW50IGFsbG93cyB1cyB0byBvbmx5IGNvbGxlY3QgdGhlIG1pbmltdW0gc2lnbiBiaXRzIHRoYXQgYXJlIHNoYXJlZAorICAvLy8gYnkgdGhlIHJlcXVlc3RlZCB2ZWN0b3IgZWxlbWVudHMuCisgIHZpcnR1YWwgdW5zaWduZWQgQ29tcHV0ZU51bVNpZ25CaXRzRm9yVGFyZ2V0Tm9kZShTRFZhbHVlIE9wLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQVBJbnQgJkRlbWFuZGVkRWx0cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNlbGVjdGlvbkRBRyAmREFHLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgRGVwdGggPSAwKSBjb25zdDsKKworICAvLy8gQXR0ZW1wdCB0byBzaW1wbGlmeSBhbnkgdGFyZ2V0IG5vZGVzIGJhc2VkIG9uIHRoZSBkZW1hbmRlZCB2ZWN0b3IKKyAgLy8vIGVsZW1lbnRzLCByZXR1cm5pbmcgdHJ1ZSBvbiBzdWNjZXNzLiBPdGhlcndpc2UsIGFuYWx5emUgdGhlIGV4cHJlc3Npb24gYW5kCisgIC8vLyByZXR1cm4gYSBtYXNrIG9mIEtub3duVW5kZWYgYW5kIEtub3duWmVybyBlbGVtZW50cyBmb3IgdGhlIGV4cHJlc3Npb24KKyAgLy8vICh1c2VkIHRvIHNpbXBsaWZ5IHRoZSBjYWxsZXIpLiBUaGUgS25vd25VbmRlZi9aZXJvIGVsZW1lbnRzIG1heSBvbmx5IGJlCisgIC8vLyBhY2N1cmF0ZSBmb3IgdGhvc2UgYml0cyBpbiB0aGUgRGVtYW5kZWRNYXNrCisgIHZpcnR1YWwgYm9vbCBTaW1wbGlmeURlbWFuZGVkVmVjdG9yRWx0c0ZvclRhcmdldE5vZGUoCisgICAgICBTRFZhbHVlIE9wLCBjb25zdCBBUEludCAmRGVtYW5kZWRFbHRzLCBBUEludCAmS25vd25VbmRlZiwKKyAgICAgIEFQSW50ICZLbm93blplcm8sIFRhcmdldExvd2VyaW5nT3B0ICZUTE8sIHVuc2lnbmVkIERlcHRoID0gMCkgY29uc3Q7CisKKyAgc3RydWN0IERBR0NvbWJpbmVySW5mbyB7CisgICAgdm9pZCAqREM7ICAvLyBUaGUgREFHIENvbWJpbmVyIG9iamVjdC4KKyAgICBDb21iaW5lTGV2ZWwgTGV2ZWw7CisgICAgYm9vbCBDYWxsZWRCeUxlZ2FsaXplcjsKKworICBwdWJsaWM6CisgICAgU2VsZWN0aW9uREFHICZEQUc7CisKKyAgICBEQUdDb21iaW5lckluZm8oU2VsZWN0aW9uREFHICZkYWcsIENvbWJpbmVMZXZlbCBsZXZlbCwgIGJvb2wgY2wsIHZvaWQgKmRjKQorICAgICAgOiBEQyhkYyksIExldmVsKGxldmVsKSwgQ2FsbGVkQnlMZWdhbGl6ZXIoY2wpLCBEQUcoZGFnKSB7fQorCisgICAgYm9vbCBpc0JlZm9yZUxlZ2FsaXplKCkgY29uc3QgeyByZXR1cm4gTGV2ZWwgPT0gQmVmb3JlTGVnYWxpemVUeXBlczsgfQorICAgIGJvb2wgaXNCZWZvcmVMZWdhbGl6ZU9wcygpIGNvbnN0IHsgcmV0dXJuIExldmVsIDwgQWZ0ZXJMZWdhbGl6ZVZlY3Rvck9wczsgfQorICAgIGJvb2wgaXNBZnRlckxlZ2FsaXplREFHKCkgY29uc3QgeworICAgICAgcmV0dXJuIExldmVsID09IEFmdGVyTGVnYWxpemVEQUc7CisgICAgfQorICAgIENvbWJpbmVMZXZlbCBnZXREQUdDb21iaW5lTGV2ZWwoKSB7IHJldHVybiBMZXZlbDsgfQorICAgIGJvb2wgaXNDYWxsZWRCeUxlZ2FsaXplcigpIGNvbnN0IHsgcmV0dXJuIENhbGxlZEJ5TGVnYWxpemVyOyB9CisKKyAgICB2b2lkIEFkZFRvV29ya2xpc3QoU0ROb2RlICpOKTsKKyAgICBTRFZhbHVlIENvbWJpbmVUbyhTRE5vZGUgKk4sIEFycmF5UmVmPFNEVmFsdWU+IFRvLCBib29sIEFkZFRvID0gdHJ1ZSk7CisgICAgU0RWYWx1ZSBDb21iaW5lVG8oU0ROb2RlICpOLCBTRFZhbHVlIFJlcywgYm9vbCBBZGRUbyA9IHRydWUpOworICAgIFNEVmFsdWUgQ29tYmluZVRvKFNETm9kZSAqTiwgU0RWYWx1ZSBSZXMwLCBTRFZhbHVlIFJlczEsIGJvb2wgQWRkVG8gPSB0cnVlKTsKKworICAgIHZvaWQgQ29tbWl0VGFyZ2V0TG93ZXJpbmdPcHQoY29uc3QgVGFyZ2V0TG93ZXJpbmdPcHQgJlRMTyk7CisgIH07CisKKyAgLy8vIFJldHVybiBpZiB0aGUgTiBpcyBhIGNvbnN0YW50IG9yIGNvbnN0YW50IHZlY3RvciBlcXVhbCB0byB0aGUgdHJ1ZSB2YWx1ZQorICAvLy8gZnJvbSBnZXRCb29sZWFuQ29udGVudHMoKS4KKyAgYm9vbCBpc0NvbnN0VHJ1ZVZhbChjb25zdCBTRE5vZGUgKk4pIGNvbnN0OworCisgIC8vLyBSZXR1cm4gaWYgdGhlIE4gaXMgYSBjb25zdGFudCBvciBjb25zdGFudCB2ZWN0b3IgZXF1YWwgdG8gdGhlIGZhbHNlIHZhbHVlCisgIC8vLyBmcm9tIGdldEJvb2xlYW5Db250ZW50cygpLgorICBib29sIGlzQ29uc3RGYWxzZVZhbChjb25zdCBTRE5vZGUgKk4pIGNvbnN0OworCisgIC8vLyBSZXR1cm4gaWYgXHAgTiBpcyBhIFRydWUgdmFsdWUgd2hlbiBleHRlbmRlZCB0byBccCBWVC4KKyAgYm9vbCBpc0V4dGVuZGVkVHJ1ZVZhbChjb25zdCBDb25zdGFudFNETm9kZSAqTiwgRVZUIFZULCBib29sIFNpZ25lZCkgY29uc3Q7CisKKyAgLy8vIFRyeSB0byBzaW1wbGlmeSBhIHNldGNjIGJ1aWx0IHdpdGggdGhlIHNwZWNpZmllZCBvcGVyYW5kcyBhbmQgY2MuIElmIGl0IGlzCisgIC8vLyB1bmFibGUgdG8gc2ltcGxpZnkgaXQsIHJldHVybiBhIG51bGwgU0RWYWx1ZS4KKyAgU0RWYWx1ZSBTaW1wbGlmeVNldENDKEVWVCBWVCwgU0RWYWx1ZSBOMCwgU0RWYWx1ZSBOMSwgSVNEOjpDb25kQ29kZSBDb25kLAorICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBmb2xkQm9vbGVhbnMsIERBR0NvbWJpbmVySW5mbyAmRENJLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU0RMb2MgJmRsKSBjb25zdDsKKworICAvLyBGb3IgdGFyZ2V0cyB3aGljaCB3cmFwIGFkZHJlc3MsIHVud3JhcCBmb3IgYW5hbHlzaXMuCisgIHZpcnR1YWwgU0RWYWx1ZSB1bndyYXBBZGRyZXNzKFNEVmFsdWUgTikgY29uc3QgeyByZXR1cm4gTjsgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgKGFuZCB0aGUgR2xvYmFsVmFsdWUgYW5kIHRoZSBvZmZzZXQpIGlmIHRoZSBub2RlIGlzIGEKKyAgLy8vIEdsb2JhbEFkZHJlc3MgKyBvZmZzZXQuCisgIHZpcnR1YWwgYm9vbAorICBpc0dBUGx1c09mZnNldChTRE5vZGUgKk4sIGNvbnN0IEdsb2JhbFZhbHVlKiAmR0EsIGludDY0X3QgJk9mZnNldCkgY29uc3Q7CisKKyAgLy8vIFRoaXMgbWV0aG9kIHdpbGwgYmUgaW52b2tlZCBmb3IgYWxsIHRhcmdldCBub2RlcyBhbmQgZm9yIGFueQorICAvLy8gdGFyZ2V0LWluZGVwZW5kZW50IG5vZGVzIHRoYXQgdGhlIHRhcmdldCBoYXMgcmVnaXN0ZXJlZCB3aXRoIGludm9rZSBpdAorICAvLy8gZm9yLgorICAvLy8KKyAgLy8vIFRoZSBzZW1hbnRpY3MgYXJlIGFzIGZvbGxvd3M6CisgIC8vLyBSZXR1cm4gVmFsdWU6CisgIC8vLyAgIFNEVmFsdWUuVmFsID09IDAgICAtIE5vIGNoYW5nZSB3YXMgbWFkZQorICAvLy8gICBTRFZhbHVlLlZhbCA9PSBOICAgLSBOIHdhcyByZXBsYWNlZCwgaXMgZGVhZCwgYW5kIGlzIGFscmVhZHkgaGFuZGxlZC4KKyAgLy8vICAgb3RoZXJ3aXNlICAgICAgICAgIC0gTiBzaG91bGQgYmUgcmVwbGFjZWQgYnkgdGhlIHJldHVybmVkIE9wZXJhbmQuCisgIC8vLworICAvLy8gSW4gYWRkaXRpb24sIG1ldGhvZHMgcHJvdmlkZWQgYnkgREFHQ29tYmluZXJJbmZvIG1heSBiZSB1c2VkIHRvIHBlcmZvcm0KKyAgLy8vIG1vcmUgY29tcGxleCB0cmFuc2Zvcm1hdGlvbnMuCisgIC8vLworICB2aXJ0dWFsIFNEVmFsdWUgUGVyZm9ybURBR0NvbWJpbmUoU0ROb2RlICpOLCBEQUdDb21iaW5lckluZm8gJkRDSSkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIGl0IGlzIHByb2ZpdGFibGUgdG8gbW92ZSBhIGZvbGxvd2luZyBzaGlmdCB0aHJvdWdoIHRoaXMKKyAgLy8gIG5vZGUsIGFkanVzdGluZyBhbnkgaW1tZWRpYXRlIG9wZXJhbmRzIGFzIG5lY2Vzc2FyeSB0byBwcmVzZXJ2ZSBzZW1hbnRpY3MuCisgIC8vICBUaGlzIHRyYW5zZm9ybWF0aW9uIG1heSBub3QgYmUgZGVzaXJhYmxlIGlmIGl0IGRpc3J1cHRzIGEgcGFydGljdWxhcmx5CisgIC8vICBhdXNwaWNpb3VzIHRhcmdldC1zcGVjaWZpYyB0cmVlIChlLmcuIGJpdGZpZWxkIGV4dHJhY3Rpb24gaW4gQUFyY2g2NCkuCisgIC8vICBCeSBkZWZhdWx0LCBpdCByZXR1cm5zIHRydWUuCisgIHZpcnR1YWwgYm9vbCBpc0Rlc2lyYWJsZVRvQ29tbXV0ZVdpdGhTaGlmdChjb25zdCBTRE5vZGUgKk4pIGNvbnN0IHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vIFJldHVybiB0cnVlIGlmIGl0IGlzIHByb2ZpdGFibGUgdG8gY29tYmluZSBhIEJVSUxEX1ZFQ1RPUiB3aXRoIGEgc3RyaWRlLXBhdHRlcm4KKyAgLy8gdG8gYSBzaHVmZmxlIGFuZCBhIHRydW5jYXRlLgorICAvLyBFeGFtcGxlIG9mIHN1Y2ggYSBjb21iaW5lOgorICAvLyB2NGkzMiBidWlsZF92ZWN0b3IoKGV4dHJhY3RfZWx0IFYsIDEpLAorICAvLyAgICAgICAgICAgICAgICAgICAgKGV4dHJhY3RfZWx0IFYsIDMpLAorICAvLyAgICAgICAgICAgICAgICAgICAgKGV4dHJhY3RfZWx0IFYsIDUpLAorICAvLyAgICAgICAgICAgICAgICAgICAgKGV4dHJhY3RfZWx0IFYsIDcpKQorICAvLyAgLS0+CisgIC8vIHY0aTMyIHRydW5jYXRlIChiaXRjYXN0IChzaHVmZmxlPDEsdSwzLHUsNSx1LDcsdT4gViwgdSkgdG8gdjRpNjQpCisgIHZpcnR1YWwgYm9vbCBpc0Rlc2lyYWJsZVRvQ29tYmluZUJ1aWxkVmVjdG9yVG9TaHVmZmxlVHJ1bmNhdGUoCisgICAgICBBcnJheVJlZjxpbnQ+IFNodWZmbGVNYXNrLCBFVlQgU3JjVlQsIEVWVCBUcnVuY1ZUKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSB0YXJnZXQgaGFzIG5hdGl2ZSBzdXBwb3J0IGZvciB0aGUgc3BlY2lmaWVkIHZhbHVlIHR5cGUKKyAgLy8vIGFuZCBpdCBpcyAnZGVzaXJhYmxlJyB0byB1c2UgdGhlIHR5cGUgZm9yIHRoZSBnaXZlbiBub2RlIHR5cGUuIGUuZy4gT24geDg2CisgIC8vLyBpMTYgaXMgbGVnYWwsIGJ1dCB1bmRlc2lyYWJsZSBzaW5jZSBpMTYgaW5zdHJ1Y3Rpb24gZW5jb2RpbmdzIGFyZSBsb25nZXIKKyAgLy8vIGFuZCBzb21lIGkxNiBpbnN0cnVjdGlvbnMgYXJlIHNsb3cuCisgIHZpcnR1YWwgYm9vbCBpc1R5cGVEZXNpcmFibGVGb3JPcCh1bnNpZ25lZCAvKk9wYyovLCBFVlQgVlQpIGNvbnN0IHsKKyAgICAvLyBCeSBkZWZhdWx0LCBhc3N1bWUgYWxsIGxlZ2FsIHR5cGVzIGFyZSBkZXNpcmFibGUuCisgICAgcmV0dXJuIGlzVHlwZUxlZ2FsKFZUKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBpdCBpcyBwcm9maXRhYmxlIGZvciBkYWcgY29tYmluZXIgdG8gdHJhbnNmb3JtIGEgZmxvYXRpbmcKKyAgLy8vIHBvaW50IG9wIG9mIHNwZWNpZmllZCBvcGNvZGUgdG8gYSBlcXVpdmFsZW50IG9wIG9mIGFuIGludGVnZXIKKyAgLy8vIHR5cGUuIGUuZy4gZjMyIGxvYWQgLT4gaTMyIGxvYWQgY2FuIGJlIHByb2ZpdGFibGUgb24gQVJNLgorICB2aXJ0dWFsIGJvb2wgaXNEZXNpcmFibGVUb1RyYW5zZm9ybVRvSW50ZWdlck9wKHVuc2lnbmVkIC8qT3BjKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVZUIC8qVlQqLykgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBUaGlzIG1ldGhvZCBxdWVyeSB0aGUgdGFyZ2V0IHdoZXRoZXIgaXQgaXMgYmVuZWZpY2lhbCBmb3IgZGFnIGNvbWJpbmVyIHRvCisgIC8vLyBwcm9tb3RlIHRoZSBzcGVjaWZpZWQgbm9kZS4gSWYgdHJ1ZSwgaXQgc2hvdWxkIHJldHVybiB0aGUgZGVzaXJlZAorICAvLy8gcHJvbW90aW9uIHR5cGUgYnkgcmVmZXJlbmNlLgorICB2aXJ0dWFsIGJvb2wgSXNEZXNpcmFibGVUb1Byb21vdGVPcChTRFZhbHVlIC8qT3AqLywgRVZUICYvKlBWVCovKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSB0YXJnZXQgc3VwcG9ydHMgc3dpZnRlcnJvciBhdHRyaWJ1dGUuIEl0IG9wdGltaXplcworICAvLy8gbG9hZHMgYW5kIHN0b3JlcyB0byByZWFkaW5nIGFuZCB3cml0aW5nIGEgc3BlY2lmaWMgcmVnaXN0ZXIuCisgIHZpcnR1YWwgYm9vbCBzdXBwb3J0U3dpZnRFcnJvcigpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHRhcmdldCBzdXBwb3J0cyB0aGF0IGEgc3Vic2V0IG9mIENTUnMgZm9yIHRoZSBnaXZlbgorICAvLy8gbWFjaGluZSBmdW5jdGlvbiBpcyBoYW5kbGVkIGV4cGxpY2l0bHkgdmlhIGNvcGllcy4KKyAgdmlydHVhbCBib29sIHN1cHBvcnRTcGxpdENTUihNYWNoaW5lRnVuY3Rpb24gKk1GKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFBlcmZvcm0gbmVjZXNzYXJ5IGluaXRpYWxpemF0aW9uIHRvIGhhbmRsZSBhIHN1YnNldCBvZiBDU1JzIGV4cGxpY2l0bHkKKyAgLy8vIHZpYSBjb3BpZXMuIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgaW5zdHJ1Y3Rpb24KKyAgLy8vIHNlbGVjdGlvbi4KKyAgdmlydHVhbCB2b2lkIGluaXRpYWxpemVTcGxpdENTUihNYWNoaW5lQmFzaWNCbG9jayAqRW50cnkpIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJOb3QgSW1wbGVtZW50ZWQiKTsKKyAgfQorCisgIC8vLyBJbnNlcnQgZXhwbGljaXQgY29waWVzIGluIGVudHJ5IGFuZCBleGl0IGJsb2Nrcy4gV2UgY29weSBhIHN1YnNldCBvZgorICAvLy8gQ1NScyB0byB2aXJ0dWFsIHJlZ2lzdGVycyBpbiB0aGUgZW50cnkgYmxvY2ssIGFuZCBjb3B5IHRoZW0gYmFjayB0bworICAvLy8gcGh5c2ljYWwgcmVnaXN0ZXJzIGluIHRoZSBleGl0IGJsb2Nrcy4gVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYXQgdGhlIGVuZAorICAvLy8gb2YgaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uLgorICB2aXJ0dWFsIHZvaWQgaW5zZXJ0Q29waWVzU3BsaXRDU1IoCisgICAgICBNYWNoaW5lQmFzaWNCbG9jayAqRW50cnksCisgICAgICBjb25zdCBTbWFsbFZlY3RvckltcGw8TWFjaGluZUJhc2ljQmxvY2sgKj4gJkV4aXRzKSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgiTm90IEltcGxlbWVudGVkIik7CisgIH0KKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gTG93ZXJpbmcgbWV0aG9kcyAtIFRoZXNlIG1ldGhvZHMgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSB0YXJnZXRzIHNvIHRoYXQKKyAgLy8gdGhlIFNlbGVjdGlvbkRBR0J1aWxkZXIgY29kZSBrbm93cyBob3cgdG8gbG93ZXIgdGhlc2UuCisgIC8vCisKKyAgLy8vIFRoaXMgaG9vayBtdXN0IGJlIGltcGxlbWVudGVkIHRvIGxvd2VyIHRoZSBpbmNvbWluZyAoZm9ybWFsKSBhcmd1bWVudHMsCisgIC8vLyBkZXNjcmliZWQgYnkgdGhlIElucyBhcnJheSwgaW50byB0aGUgc3BlY2lmaWVkIERBRy4gVGhlIGltcGxlbWVudGF0aW9uCisgIC8vLyBzaG91bGQgZmlsbCBpbiB0aGUgSW5WYWxzIGFycmF5IHdpdGggbGVnYWwtdHlwZSBhcmd1bWVudCB2YWx1ZXMsIGFuZAorICAvLy8gcmV0dXJuIHRoZSByZXN1bHRpbmcgdG9rZW4gY2hhaW4gdmFsdWUuCisgIHZpcnR1YWwgU0RWYWx1ZSBMb3dlckZvcm1hbEFyZ3VtZW50cygKKyAgICAgIFNEVmFsdWUgLypDaGFpbiovLCBDYWxsaW5nQ29udjo6SUQgLypDYWxsQ29udiovLCBib29sIC8qaXNWYXJBcmcqLywKKyAgICAgIGNvbnN0IFNtYWxsVmVjdG9ySW1wbDxJU0Q6OklucHV0QXJnPiAmIC8qSW5zKi8sIGNvbnN0IFNETG9jICYgLypkbCovLAorICAgICAgU2VsZWN0aW9uREFHICYgLypEQUcqLywgU21hbGxWZWN0b3JJbXBsPFNEVmFsdWU+ICYgLypJblZhbHMqLykgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIk5vdCBJbXBsZW1lbnRlZCIpOworICB9CisKKyAgLy8vIFRoaXMgc3RydWN0dXJlIGNvbnRhaW5zIGFsbCBpbmZvcm1hdGlvbiB0aGF0IGlzIG5lY2Vzc2FyeSBmb3IgbG93ZXJpbmcKKyAgLy8vIGNhbGxzLiBJdCBpcyBwYXNzZWQgdG8gVExJOjpMb3dlckNhbGxUbyB3aGVuIHRoZSBTZWxlY3Rpb25EQUcgYnVpbGRlcgorICAvLy8gbmVlZHMgdG8gbG93ZXIgYSBjYWxsLCBhbmQgdGFyZ2V0cyB3aWxsIHNlZSB0aGlzIHN0cnVjdCBpbiB0aGVpciBMb3dlckNhbGwKKyAgLy8vIGltcGxlbWVudGF0aW9uLgorICBzdHJ1Y3QgQ2FsbExvd2VyaW5nSW5mbyB7CisgICAgU0RWYWx1ZSBDaGFpbjsKKyAgICBUeXBlICpSZXRUeSA9IG51bGxwdHI7CisgICAgYm9vbCBSZXRTRXh0ICAgICAgICAgICA6IDE7CisgICAgYm9vbCBSZXRaRXh0ICAgICAgICAgICA6IDE7CisgICAgYm9vbCBJc1ZhckFyZyAgICAgICAgICA6IDE7CisgICAgYm9vbCBJc0luUmVnICAgICAgICAgICA6IDE7CisgICAgYm9vbCBEb2VzTm90UmV0dXJuICAgICA6IDE7CisgICAgYm9vbCBJc1JldHVyblZhbHVlVXNlZCA6IDE7CisgICAgYm9vbCBJc0NvbnZlcmdlbnQgICAgICA6IDE7CisgICAgYm9vbCBJc1BhdGNoUG9pbnQgICAgICA6IDE7CisKKyAgICAvLyBJc1RhaWxDYWxsIHNob3VsZCBiZSBtb2RpZmllZCBieSBpbXBsZW1lbnRhdGlvbnMgb2YKKyAgICAvLyBUYXJnZXRMb3dlcmluZzo6TG93ZXJDYWxsIHRoYXQgcGVyZm9ybSB0YWlsIGNhbGwgY29udmVyc2lvbnMuCisgICAgYm9vbCBJc1RhaWxDYWxsID0gZmFsc2U7CisKKyAgICAvLyBJcyBDYWxsIGxvd2VyaW5nIGRvbmUgcG9zdCBTZWxlY3Rpb25EQUcgdHlwZSBsZWdhbGl6YXRpb24uCisgICAgYm9vbCBJc1Bvc3RUeXBlTGVnYWxpemF0aW9uID0gZmFsc2U7CisKKyAgICB1bnNpZ25lZCBOdW1GaXhlZEFyZ3MgPSAtMTsKKyAgICBDYWxsaW5nQ29udjo6SUQgQ2FsbENvbnYgPSBDYWxsaW5nQ29udjo6QzsKKyAgICBTRFZhbHVlIENhbGxlZTsKKyAgICBBcmdMaXN0VHkgQXJnczsKKyAgICBTZWxlY3Rpb25EQUcgJkRBRzsKKyAgICBTRExvYyBETDsKKyAgICBJbW11dGFibGVDYWxsU2l0ZSBDUzsKKyAgICBTbWFsbFZlY3RvcjxJU0Q6Ok91dHB1dEFyZywgMzI+IE91dHM7CisgICAgU21hbGxWZWN0b3I8U0RWYWx1ZSwgMzI+IE91dFZhbHM7CisgICAgU21hbGxWZWN0b3I8SVNEOjpJbnB1dEFyZywgMzI+IEluczsKKyAgICBTbWFsbFZlY3RvcjxTRFZhbHVlLCA0PiBJblZhbHM7CisKKyAgICBDYWxsTG93ZXJpbmdJbmZvKFNlbGVjdGlvbkRBRyAmREFHKQorICAgICAgICA6IFJldFNFeHQoZmFsc2UpLCBSZXRaRXh0KGZhbHNlKSwgSXNWYXJBcmcoZmFsc2UpLCBJc0luUmVnKGZhbHNlKSwKKyAgICAgICAgICBEb2VzTm90UmV0dXJuKGZhbHNlKSwgSXNSZXR1cm5WYWx1ZVVzZWQodHJ1ZSksIElzQ29udmVyZ2VudChmYWxzZSksCisgICAgICAgICAgSXNQYXRjaFBvaW50KGZhbHNlKSwgREFHKERBRykge30KKworICAgIENhbGxMb3dlcmluZ0luZm8gJnNldERlYnVnTG9jKGNvbnN0IFNETG9jICZkbCkgeworICAgICAgREwgPSBkbDsKKyAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisKKyAgICBDYWxsTG93ZXJpbmdJbmZvICZzZXRDaGFpbihTRFZhbHVlIEluQ2hhaW4pIHsKKyAgICAgIENoYWluID0gSW5DaGFpbjsKKyAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisKKyAgICAvLyBzZXRDYWxsZWUgd2l0aCB0YXJnZXQvbW9kdWxlLXNwZWNpZmljIGF0dHJpYnV0ZXMKKyAgICBDYWxsTG93ZXJpbmdJbmZvICZzZXRMaWJDYWxsZWUoQ2FsbGluZ0NvbnY6OklEIENDLCBUeXBlICpSZXN1bHRUeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIFRhcmdldCwgQXJnTGlzdFR5ICYmQXJnc0xpc3QpIHsKKyAgICAgIFJldFR5ID0gUmVzdWx0VHlwZTsKKyAgICAgIENhbGxlZSA9IFRhcmdldDsKKyAgICAgIENhbGxDb252ID0gQ0M7CisgICAgICBOdW1GaXhlZEFyZ3MgPSBBcmdzTGlzdC5zaXplKCk7CisgICAgICBBcmdzID0gc3RkOjptb3ZlKEFyZ3NMaXN0KTsKKworICAgICAgREFHLmdldFRhcmdldExvd2VyaW5nSW5mbygpLm1hcmtMaWJDYWxsQXR0cmlidXRlcygKKyAgICAgICAgICAmKERBRy5nZXRNYWNoaW5lRnVuY3Rpb24oKSksIENDLCBBcmdzKTsKKyAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisKKyAgICBDYWxsTG93ZXJpbmdJbmZvICZzZXRDYWxsZWUoQ2FsbGluZ0NvbnY6OklEIENDLCBUeXBlICpSZXN1bHRUeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIFRhcmdldCwgQXJnTGlzdFR5ICYmQXJnc0xpc3QpIHsKKyAgICAgIFJldFR5ID0gUmVzdWx0VHlwZTsKKyAgICAgIENhbGxlZSA9IFRhcmdldDsKKyAgICAgIENhbGxDb252ID0gQ0M7CisgICAgICBOdW1GaXhlZEFyZ3MgPSBBcmdzTGlzdC5zaXplKCk7CisgICAgICBBcmdzID0gc3RkOjptb3ZlKEFyZ3NMaXN0KTsKKyAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisKKyAgICBDYWxsTG93ZXJpbmdJbmZvICZzZXRDYWxsZWUoVHlwZSAqUmVzdWx0VHlwZSwgRnVuY3Rpb25UeXBlICpGVHksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgVGFyZ2V0LCBBcmdMaXN0VHkgJiZBcmdzTGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW1tdXRhYmxlQ2FsbFNpdGUgQ2FsbCkgeworICAgICAgUmV0VHkgPSBSZXN1bHRUeXBlOworCisgICAgICBJc0luUmVnID0gQ2FsbC5oYXNSZXRBdHRyKEF0dHJpYnV0ZTo6SW5SZWcpOworICAgICAgRG9lc05vdFJldHVybiA9CisgICAgICAgICAgQ2FsbC5kb2VzTm90UmV0dXJuKCkgfHwKKyAgICAgICAgICAoIUNhbGwuaXNJbnZva2UoKSAmJgorICAgICAgICAgICBpc2E8VW5yZWFjaGFibGVJbnN0PihDYWxsLmdldEluc3RydWN0aW9uKCktPmdldE5leHROb2RlKCkpKTsKKyAgICAgIElzVmFyQXJnID0gRlR5LT5pc1ZhckFyZygpOworICAgICAgSXNSZXR1cm5WYWx1ZVVzZWQgPSAhQ2FsbC5nZXRJbnN0cnVjdGlvbigpLT51c2VfZW1wdHkoKTsKKyAgICAgIFJldFNFeHQgPSBDYWxsLmhhc1JldEF0dHIoQXR0cmlidXRlOjpTRXh0KTsKKyAgICAgIFJldFpFeHQgPSBDYWxsLmhhc1JldEF0dHIoQXR0cmlidXRlOjpaRXh0KTsKKworICAgICAgQ2FsbGVlID0gVGFyZ2V0OworCisgICAgICBDYWxsQ29udiA9IENhbGwuZ2V0Q2FsbGluZ0NvbnYoKTsKKyAgICAgIE51bUZpeGVkQXJncyA9IEZUeS0+Z2V0TnVtUGFyYW1zKCk7CisgICAgICBBcmdzID0gc3RkOjptb3ZlKEFyZ3NMaXN0KTsKKworICAgICAgQ1MgPSBDYWxsOworCisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorCisgICAgQ2FsbExvd2VyaW5nSW5mbyAmc2V0SW5SZWdpc3Rlcihib29sIFZhbHVlID0gdHJ1ZSkgeworICAgICAgSXNJblJlZyA9IFZhbHVlOworICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KKworICAgIENhbGxMb3dlcmluZ0luZm8gJnNldE5vUmV0dXJuKGJvb2wgVmFsdWUgPSB0cnVlKSB7CisgICAgICBEb2VzTm90UmV0dXJuID0gVmFsdWU7CisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorCisgICAgQ2FsbExvd2VyaW5nSW5mbyAmc2V0VmFyQXJnKGJvb2wgVmFsdWUgPSB0cnVlKSB7CisgICAgICBJc1ZhckFyZyA9IFZhbHVlOworICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KKworICAgIENhbGxMb3dlcmluZ0luZm8gJnNldFRhaWxDYWxsKGJvb2wgVmFsdWUgPSB0cnVlKSB7CisgICAgICBJc1RhaWxDYWxsID0gVmFsdWU7CisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorCisgICAgQ2FsbExvd2VyaW5nSW5mbyAmc2V0RGlzY2FyZFJlc3VsdChib29sIFZhbHVlID0gdHJ1ZSkgeworICAgICAgSXNSZXR1cm5WYWx1ZVVzZWQgPSAhVmFsdWU7CisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorCisgICAgQ2FsbExvd2VyaW5nSW5mbyAmc2V0Q29udmVyZ2VudChib29sIFZhbHVlID0gdHJ1ZSkgeworICAgICAgSXNDb252ZXJnZW50ID0gVmFsdWU7CisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorCisgICAgQ2FsbExvd2VyaW5nSW5mbyAmc2V0U0V4dFJlc3VsdChib29sIFZhbHVlID0gdHJ1ZSkgeworICAgICAgUmV0U0V4dCA9IFZhbHVlOworICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KKworICAgIENhbGxMb3dlcmluZ0luZm8gJnNldFpFeHRSZXN1bHQoYm9vbCBWYWx1ZSA9IHRydWUpIHsKKyAgICAgIFJldFpFeHQgPSBWYWx1ZTsKKyAgICAgIHJldHVybiAqdGhpczsKKyAgICB9CisKKyAgICBDYWxsTG93ZXJpbmdJbmZvICZzZXRJc1BhdGNoUG9pbnQoYm9vbCBWYWx1ZSA9IHRydWUpIHsKKyAgICAgIElzUGF0Y2hQb2ludCA9IFZhbHVlOworICAgICAgcmV0dXJuICp0aGlzOworICAgIH0KKworICAgIENhbGxMb3dlcmluZ0luZm8gJnNldElzUG9zdFR5cGVMZWdhbGl6YXRpb24oYm9vbCBWYWx1ZT10cnVlKSB7CisgICAgICBJc1Bvc3RUeXBlTGVnYWxpemF0aW9uID0gVmFsdWU7CisgICAgICByZXR1cm4gKnRoaXM7CisgICAgfQorCisgICAgQXJnTGlzdFR5ICZnZXRBcmdzKCkgeworICAgICAgcmV0dXJuIEFyZ3M7CisgICAgfQorICB9OworCisgIC8vLyBUaGlzIGZ1bmN0aW9uIGxvd2VycyBhbiBhYnN0cmFjdCBjYWxsIHRvIGEgZnVuY3Rpb24gaW50byBhbiBhY3R1YWwgY2FsbC4KKyAgLy8vIFRoaXMgcmV0dXJucyBhIHBhaXIgb2Ygb3BlcmFuZHMuICBUaGUgZmlyc3QgZWxlbWVudCBpcyB0aGUgcmV0dXJuIHZhbHVlCisgIC8vLyBmb3IgdGhlIGZ1bmN0aW9uIChpZiBSZXRUeSBpcyBub3QgVm9pZFR5KS4gIFRoZSBzZWNvbmQgZWxlbWVudCBpcyB0aGUKKyAgLy8vIG91dGdvaW5nIHRva2VuIGNoYWluLiBJdCBjYWxscyBMb3dlckNhbGwgdG8gZG8gdGhlIGFjdHVhbCBsb3dlcmluZy4KKyAgc3RkOjpwYWlyPFNEVmFsdWUsIFNEVmFsdWU+IExvd2VyQ2FsbFRvKENhbGxMb3dlcmluZ0luZm8gJkNMSSkgY29uc3Q7CisKKyAgLy8vIFRoaXMgaG9vayBtdXN0IGJlIGltcGxlbWVudGVkIHRvIGxvd2VyIGNhbGxzIGludG8gdGhlIHNwZWNpZmllZAorICAvLy8gREFHLiBUaGUgb3V0Z29pbmcgYXJndW1lbnRzIHRvIHRoZSBjYWxsIGFyZSBkZXNjcmliZWQgYnkgdGhlIE91dHMgYXJyYXksCisgIC8vLyBhbmQgdGhlIHZhbHVlcyB0byBiZSByZXR1cm5lZCBieSB0aGUgY2FsbCBhcmUgZGVzY3JpYmVkIGJ5IHRoZSBJbnMKKyAgLy8vIGFycmF5LiBUaGUgaW1wbGVtZW50YXRpb24gc2hvdWxkIGZpbGwgaW4gdGhlIEluVmFscyBhcnJheSB3aXRoIGxlZ2FsLXR5cGUKKyAgLy8vIHJldHVybiB2YWx1ZXMgZnJvbSB0aGUgY2FsbCwgYW5kIHJldHVybiB0aGUgcmVzdWx0aW5nIHRva2VuIGNoYWluIHZhbHVlLgorICB2aXJ0dWFsIFNEVmFsdWUKKyAgICBMb3dlckNhbGwoQ2FsbExvd2VyaW5nSW5mbyAmLypDTEkqLywKKyAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPFNEVmFsdWU+ICYvKkluVmFscyovKSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgiTm90IEltcGxlbWVudGVkIik7CisgIH0KKworICAvLy8gVGFyZ2V0LXNwZWNpZmljIGNsZWFudXAgZm9yIGZvcm1hbCBCeVZhbCBwYXJhbWV0ZXJzLgorICB2aXJ0dWFsIHZvaWQgSGFuZGxlQnlWYWwoQ0NTdGF0ZSAqLCB1bnNpZ25lZCAmLCB1bnNpZ25lZCkgY29uc3Qge30KKworICAvLy8gVGhpcyBob29rIHNob3VsZCBiZSBpbXBsZW1lbnRlZCB0byBjaGVjayB3aGV0aGVyIHRoZSByZXR1cm4gdmFsdWVzCisgIC8vLyBkZXNjcmliZWQgYnkgdGhlIE91dHMgYXJyYXkgY2FuIGZpdCBpbnRvIHRoZSByZXR1cm4gcmVnaXN0ZXJzLiAgSWYgZmFsc2UKKyAgLy8vIGlzIHJldHVybmVkLCBhbiBzcmV0LWRlbW90aW9uIGlzIHBlcmZvcm1lZC4KKyAgdmlydHVhbCBib29sIENhbkxvd2VyUmV0dXJuKENhbGxpbmdDb252OjpJRCAvKkNhbGxDb252Ki8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lRnVuY3Rpb24gJi8qTUYqLywgYm9vbCAvKmlzVmFyQXJnKi8sCisgICAgICAgICAgICAgICBjb25zdCBTbWFsbFZlY3RvckltcGw8SVNEOjpPdXRwdXRBcmc+ICYvKk91dHMqLywKKyAgICAgICAgICAgICAgIExMVk1Db250ZXh0ICYvKkNvbnRleHQqLykgY29uc3QKKyAgeworICAgIC8vIFJldHVybiB0cnVlIGJ5IGRlZmF1bHQgdG8gZ2V0IHByZWV4aXN0aW5nIGJlaGF2aW9yLgorICAgIHJldHVybiB0cnVlOworICB9CisKKyAgLy8vIFRoaXMgaG9vayBtdXN0IGJlIGltcGxlbWVudGVkIHRvIGxvd2VyIG91dGdvaW5nIHJldHVybiB2YWx1ZXMsIGRlc2NyaWJlZAorICAvLy8gYnkgdGhlIE91dHMgYXJyYXksIGludG8gdGhlIHNwZWNpZmllZCBEQUcuIFRoZSBpbXBsZW1lbnRhdGlvbiBzaG91bGQKKyAgLy8vIHJldHVybiB0aGUgcmVzdWx0aW5nIHRva2VuIGNoYWluIHZhbHVlLgorICB2aXJ0dWFsIFNEVmFsdWUgTG93ZXJSZXR1cm4oU0RWYWx1ZSAvKkNoYWluKi8sIENhbGxpbmdDb252OjpJRCAvKkNhbGxDb252Ki8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIC8qaXNWYXJBcmcqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNtYWxsVmVjdG9ySW1wbDxJU0Q6Ok91dHB1dEFyZz4gJiAvKk91dHMqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNtYWxsVmVjdG9ySW1wbDxTRFZhbHVlPiAmIC8qT3V0VmFscyovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU0RMb2MgJiAvKmRsKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3Rpb25EQUcgJiAvKkRBRyovKSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgiTm90IEltcGxlbWVudGVkIik7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgcmVzdWx0IG9mIHRoZSBzcGVjaWZpZWQgbm9kZSBpcyB1c2VkIGJ5IGEgcmV0dXJuIG5vZGUKKyAgLy8vIG9ubHkuIEl0IGFsc28gY29tcHV0ZSBhbmQgcmV0dXJuIHRoZSBpbnB1dCBjaGFpbiBmb3IgdGhlIHRhaWwgY2FsbC4KKyAgLy8vCisgIC8vLyBUaGlzIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgaXQgaXMgcG9zc2libGUgdG8gY29kZWdlbiBhIGxpYmNhbGwgYXMKKyAgLy8vIHRhaWwgY2FsbCBhdCBsZWdhbGl6YXRpb24gdGltZS4KKyAgdmlydHVhbCBib29sIGlzVXNlZEJ5UmV0dXJuT25seShTRE5vZGUgKiwgU0RWYWx1ZSAmLypDaGFpbiovKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSB0YXJnZXQgbWF5IGJlIGFibGUgZW1pdCB0aGUgY2FsbCBpbnN0cnVjdGlvbiBhcyBhIHRhaWwKKyAgLy8vIGNhbGwuIFRoaXMgaXMgdXNlZCBieSBvcHRpbWl6YXRpb24gcGFzc2VzIHRvIGRldGVybWluZSBpZiBpdCdzIHByb2ZpdGFibGUKKyAgLy8vIHRvIGR1cGxpY2F0ZSByZXR1cm4gaW5zdHJ1Y3Rpb25zIHRvIGVuYWJsZSB0YWlsY2FsbCBvcHRpbWl6YXRpb24uCisgIHZpcnR1YWwgYm9vbCBtYXlCZUVtaXR0ZWRBc1RhaWxDYWxsKGNvbnN0IENhbGxJbnN0ICopIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBidWlsdGluIG5hbWUgZm9yIHRoZSBfX2J1aWx0aW5fX19jbGVhcl9jYWNoZSBpbnRyaW5zaWMKKyAgLy8vIERlZmF1bHQgaXMgdG8gaW52b2tlIHRoZSBjbGVhciBjYWNoZSBsaWJyYXJ5IGNhbGwKKyAgdmlydHVhbCBjb25zdCBjaGFyICogZ2V0Q2xlYXJDYWNoZUJ1aWx0aW5OYW1lKCkgY29uc3QgeworICAgIHJldHVybiAiX19jbGVhcl9jYWNoZSI7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSByZWdpc3RlciBJRCBvZiB0aGUgbmFtZSBwYXNzZWQgaW4uIFVzZWQgYnkgbmFtZWQgcmVnaXN0ZXIKKyAgLy8vIGdsb2JhbCB2YXJpYWJsZXMgZXh0ZW5zaW9uLiBUaGVyZSBpcyBubyB0YXJnZXQtaW5kZXBlbmRlbnQgYmVoYXZpb3VyCisgIC8vLyBzbyB0aGUgZGVmYXVsdCBhY3Rpb24gaXMgdG8gYmFpbC4KKyAgdmlydHVhbCB1bnNpZ25lZCBnZXRSZWdpc3RlckJ5TmFtZShjb25zdCBjaGFyKiBSZWdOYW1lLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VsZWN0aW9uREFHICZEQUcpIGNvbnN0IHsKKyAgICByZXBvcnRfZmF0YWxfZXJyb3IoIk5hbWVkIHJlZ2lzdGVycyBub3QgaW1wbGVtZW50ZWQgZm9yIHRoaXMgdGFyZ2V0Iik7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSB0eXBlIHRoYXQgc2hvdWxkIGJlIHVzZWQgdG8gemVybyBvciBzaWduIGV4dGVuZCBhCisgIC8vLyB6ZXJvZXh0L3NpZ25leHQgaW50ZWdlciByZXR1cm4gdmFsdWUuICBGSVhNRTogU29tZSBDIGNhbGxpbmcgY29udmVudGlvbnMKKyAgLy8vIHJlcXVpcmUgdGhlIHJldHVybiB0eXBlIHRvIGJlIHByb21vdGVkLCBidXQgdGhpcyBpcyBub3QgdHJ1ZSBhbGwgdGhlIHRpbWUsCisgIC8vLyBlLmcuIGkxL2k4L2kxNiBvbiB4ODYveDg2XzY0LiBJdCBpcyBhbHNvIG5vdCBuZWNlc3NhcnkgZm9yIG5vbi1DIGNhbGxpbmcKKyAgLy8vIGNvbnZlbnRpb25zLiBUaGUgZnJvbnRlbmQgc2hvdWxkIGhhbmRsZSB0aGlzIGFuZCBpbmNsdWRlIGFsbCBvZiB0aGUKKyAgLy8vIG5lY2Vzc2FyeSBpbmZvcm1hdGlvbi4KKyAgdmlydHVhbCBFVlQgZ2V0VHlwZUZvckV4dFJldHVybihMTFZNQ29udGV4dCAmQ29udGV4dCwgRVZUIFZULAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVNEOjpOb2RlVHlwZSAvKkV4dGVuZEtpbmQqLykgY29uc3QgeworICAgIEVWVCBNaW5WVCA9IGdldFJlZ2lzdGVyVHlwZShDb250ZXh0LCBNVlQ6OmkzMik7CisgICAgcmV0dXJuIFZULmJpdHNMVChNaW5WVCkgPyBNaW5WVCA6IFZUOworICB9CisKKyAgLy8vIEZvciBzb21lIHRhcmdldHMsIGFuIExMVk0gc3RydWN0IHR5cGUgbXVzdCBiZSBicm9rZW4gZG93biBpbnRvIG11bHRpcGxlCisgIC8vLyBzaW1wbGUgdHlwZXMsIGJ1dCB0aGUgY2FsbGluZyBjb252ZW50aW9uIHNwZWNpZmllcyB0aGF0IHRoZSBlbnRpcmUgc3RydWN0CisgIC8vLyBtdXN0IGJlIHBhc3NlZCBpbiBhIGJsb2NrIG9mIGNvbnNlY3V0aXZlIHJlZ2lzdGVycy4KKyAgdmlydHVhbCBib29sCisgIGZ1bmN0aW9uQXJndW1lbnROZWVkc0NvbnNlY3V0aXZlUmVnaXN0ZXJzKFR5cGUgKlR5LCBDYWxsaW5nQ29udjo6SUQgQ2FsbENvbnYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgaXNWYXJBcmcpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJucyBhIDAgdGVybWluYXRlZCBhcnJheSBvZiByZWdpc3RlcnMgdGhhdCBjYW4gYmUgc2FmZWx5IHVzZWQgYXMKKyAgLy8vIHNjcmF0Y2ggcmVnaXN0ZXJzLgorICB2aXJ0dWFsIGNvbnN0IE1DUGh5c1JlZyAqZ2V0U2NyYXRjaFJlZ2lzdGVycyhDYWxsaW5nQ29udjo6SUQgQ0MpIGNvbnN0IHsKKyAgICByZXR1cm4gbnVsbHB0cjsKKyAgfQorCisgIC8vLyBUaGlzIGNhbGxiYWNrIGlzIHVzZWQgdG8gcHJlcGFyZSBmb3IgYSB2b2xhdGlsZSBvciBhdG9taWMgbG9hZC4KKyAgLy8vIEl0IHRha2VzIGEgY2hhaW4gbm9kZSBhcyBpbnB1dCBhbmQgcmV0dXJucyB0aGUgY2hhaW4gZm9yIHRoZSBsb2FkIGl0c2VsZi4KKyAgLy8vCisgIC8vLyBIYXZpbmcgYSBjYWxsYmFjayBsaWtlIHRoaXMgaXMgbmVjZXNzYXJ5IGZvciB0YXJnZXRzIGxpa2UgU3lzdGVtWiwKKyAgLy8vIHdoaWNoIGFsbG93cyBhIENQVSB0byByZXVzZSB0aGUgcmVzdWx0IG9mIGEgcHJldmlvdXMgbG9hZCBpbmRlZmluaXRlbHksCisgIC8vLyBldmVuIGlmIGEgY2FjaGUtY29oZXJlbnQgc3RvcmUgaXMgcGVyZm9ybWVkIGJ5IGFub3RoZXIgQ1BVLiAgVGhlIGRlZmF1bHQKKyAgLy8vIGltcGxlbWVudGF0aW9uIGRvZXMgbm90aGluZy4KKyAgdmlydHVhbCBTRFZhbHVlIHByZXBhcmVWb2xhdGlsZU9yQXRvbWljTG9hZChTRFZhbHVlIENoYWluLCBjb25zdCBTRExvYyAmREwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VsZWN0aW9uREFHICZEQUcpIGNvbnN0IHsKKyAgICByZXR1cm4gQ2hhaW47CisgIH0KKworICAvLy8gVGhpcyBjYWxsYmFjayBpcyB1c2VkIHRvIGluc3BlY3QgbG9hZC9zdG9yZSBpbnN0cnVjdGlvbnMgYW5kIGFkZAorICAvLy8gdGFyZ2V0LXNwZWNpZmljIE1hY2hpbmVNZW1PcGVyYW5kIGZsYWdzIHRvIHRoZW0uICBUaGUgZGVmYXVsdAorICAvLy8gaW1wbGVtZW50YXRpb24gZG9lcyBub3RoaW5nLgorICB2aXJ0dWFsIE1hY2hpbmVNZW1PcGVyYW5kOjpGbGFncyBnZXRNTU9GbGFncyhjb25zdCBJbnN0cnVjdGlvbiAmSSkgY29uc3QgeworICAgIHJldHVybiBNYWNoaW5lTWVtT3BlcmFuZDo6TU9Ob25lOworICB9CisKKyAgLy8vIFRoaXMgY2FsbGJhY2sgaXMgaW52b2tlZCBieSB0aGUgdHlwZSBsZWdhbGl6ZXIgdG8gbGVnYWxpemUgbm9kZXMgd2l0aCBhbgorICAvLy8gaWxsZWdhbCBvcGVyYW5kIHR5cGUgYnV0IGxlZ2FsIHJlc3VsdCB0eXBlcy4gIEl0IHJlcGxhY2VzIHRoZQorICAvLy8gTG93ZXJPcGVyYXRpb24gY2FsbGJhY2sgaW4gdGhlIHR5cGUgTGVnYWxpemVyLiAgVGhlIHJlYXNvbiB3ZSBjYW4gbm90IGRvCisgIC8vLyBhd2F5IHdpdGggTG93ZXJPcGVyYXRpb24gZW50aXJlbHkgaXMgdGhhdCBMZWdhbGl6ZURBRyBpc24ndCB5ZXQgcmVhZHkgdG8KKyAgLy8vIHVzZSB0aGlzIGNhbGxiYWNrLgorICAvLy8KKyAgLy8vIFRPRE86IENvbnNpZGVyIG1lcmdpbmcgd2l0aCBSZXBsYWNlTm9kZVJlc3VsdHMuCisgIC8vLworICAvLy8gVGhlIHRhcmdldCBwbGFjZXMgbmV3IHJlc3VsdCB2YWx1ZXMgZm9yIHRoZSBub2RlIGluIFJlc3VsdHMgKHRoZWlyIG51bWJlcgorICAvLy8gYW5kIHR5cGVzIG11c3QgZXhhY3RseSBtYXRjaCB0aG9zZSBvZiB0aGUgb3JpZ2luYWwgcmV0dXJuIHZhbHVlcyBvZgorICAvLy8gdGhlIG5vZGUpLCBvciBsZWF2ZXMgUmVzdWx0cyBlbXB0eSwgd2hpY2ggaW5kaWNhdGVzIHRoYXQgdGhlIG5vZGUgaXMgbm90CisgIC8vLyB0byBiZSBjdXN0b20gbG93ZXJlZCBhZnRlciBhbGwuCisgIC8vLyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBjYWxscyBMb3dlck9wZXJhdGlvbi4KKyAgdmlydHVhbCB2b2lkIExvd2VyT3BlcmF0aW9uV3JhcHBlcihTRE5vZGUgKk4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPFNEVmFsdWU+ICZSZXN1bHRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdGlvbkRBRyAmREFHKSBjb25zdDsKKworICAvLy8gVGhpcyBjYWxsYmFjayBpcyBpbnZva2VkIGZvciBvcGVyYXRpb25zIHRoYXQgYXJlIHVuc3VwcG9ydGVkIGJ5IHRoZQorICAvLy8gdGFyZ2V0LCB3aGljaCBhcmUgcmVnaXN0ZXJlZCB0byB1c2UgJ2N1c3RvbScgbG93ZXJpbmcsIGFuZCB3aG9zZSBkZWZpbmVkCisgIC8vLyB2YWx1ZXMgYXJlIGFsbCBsZWdhbC4gIElmIHRoZSB0YXJnZXQgaGFzIG5vIG9wZXJhdGlvbnMgdGhhdCByZXF1aXJlIGN1c3RvbQorICAvLy8gbG93ZXJpbmcsIGl0IG5lZWQgbm90IGltcGxlbWVudCB0aGlzLiAgVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2YgdGhpcworICAvLy8gYWJvcnRzLgorICB2aXJ0dWFsIFNEVmFsdWUgTG93ZXJPcGVyYXRpb24oU0RWYWx1ZSBPcCwgU2VsZWN0aW9uREFHICZEQUcpIGNvbnN0OworCisgIC8vLyBUaGlzIGNhbGxiYWNrIGlzIGludm9rZWQgd2hlbiBhIG5vZGUgcmVzdWx0IHR5cGUgaXMgaWxsZWdhbCBmb3IgdGhlCisgIC8vLyB0YXJnZXQsIGFuZCB0aGUgb3BlcmF0aW9uIHdhcyByZWdpc3RlcmVkIHRvIHVzZSAnY3VzdG9tJyBsb3dlcmluZyBmb3IgdGhhdAorICAvLy8gcmVzdWx0IHR5cGUuICBUaGUgdGFyZ2V0IHBsYWNlcyBuZXcgcmVzdWx0IHZhbHVlcyBmb3IgdGhlIG5vZGUgaW4gUmVzdWx0cworICAvLy8gKHRoZWlyIG51bWJlciBhbmQgdHlwZXMgbXVzdCBleGFjdGx5IG1hdGNoIHRob3NlIG9mIHRoZSBvcmlnaW5hbCByZXR1cm4KKyAgLy8vIHZhbHVlcyBvZiB0aGUgbm9kZSksIG9yIGxlYXZlcyBSZXN1bHRzIGVtcHR5LCB3aGljaCBpbmRpY2F0ZXMgdGhhdCB0aGUKKyAgLy8vIG5vZGUgaXMgbm90IHRvIGJlIGN1c3RvbSBsb3dlcmVkIGFmdGVyIGFsbC4KKyAgLy8vCisgIC8vLyBJZiB0aGUgdGFyZ2V0IGhhcyBubyBvcGVyYXRpb25zIHRoYXQgcmVxdWlyZSBjdXN0b20gbG93ZXJpbmcsIGl0IG5lZWQgbm90CisgIC8vLyBpbXBsZW1lbnQgdGhpcy4gIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGFib3J0cy4KKyAgdmlydHVhbCB2b2lkIFJlcGxhY2VOb2RlUmVzdWx0cyhTRE5vZGUgKiAvKk4qLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTbWFsbFZlY3RvckltcGw8U0RWYWx1ZT4gJi8qUmVzdWx0cyovLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdGlvbkRBRyAmLypEQUcqLykgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIlJlcGxhY2VOb2RlUmVzdWx0cyBub3QgaW1wbGVtZW50ZWQgZm9yIHRoaXMgdGFyZ2V0ISIpOworICB9CisKKyAgLy8vIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIG5hbWUgb2YgYSB0YXJnZXQgc3BlY2lmaWMgREFHIG5vZGUuCisgIHZpcnR1YWwgY29uc3QgY2hhciAqZ2V0VGFyZ2V0Tm9kZU5hbWUodW5zaWduZWQgT3Bjb2RlKSBjb25zdDsKKworICAvLy8gVGhpcyBtZXRob2QgcmV0dXJucyBhIHRhcmdldCBzcGVjaWZpYyBGYXN0SVNlbCBvYmplY3QsIG9yIG51bGwgaWYgdGhlCisgIC8vLyB0YXJnZXQgZG9lcyBub3Qgc3VwcG9ydCAiZmFzdCIgSVNlbC4KKyAgdmlydHVhbCBGYXN0SVNlbCAqY3JlYXRlRmFzdElTZWwoRnVuY3Rpb25Mb3dlcmluZ0luZm8gJiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0TGlicmFyeUluZm8gKikgY29uc3QgeworICAgIHJldHVybiBudWxscHRyOworICB9CisKKyAgYm9vbCB2ZXJpZnlSZXR1cm5BZGRyZXNzQXJndW1lbnRJc0NvbnN0YW50KFNEVmFsdWUgT3AsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3Rpb25EQUcgJkRBRykgY29uc3Q7CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIElubGluZSBBc20gU3VwcG9ydCBob29rcworICAvLworCisgIC8vLyBUaGlzIGhvb2sgYWxsb3dzIHRoZSB0YXJnZXQgdG8gZXhwYW5kIGFuIGlubGluZSBhc20gY2FsbCB0byBiZSBleHBsaWNpdAorICAvLy8gbGx2bSBjb2RlIGlmIGl0IHdhbnRzIHRvLiAgVGhpcyBpcyB1c2VmdWwgZm9yIHR1cm5pbmcgc2ltcGxlIGlubGluZSBhc21zCisgIC8vLyBpbnRvIExMVk0gaW50cmluc2ljcywgd2hpY2ggZ2l2ZXMgdGhlIGNvbXBpbGVyIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlCisgIC8vLyBiZWhhdmlvciBvZiB0aGUgY29kZS4KKyAgdmlydHVhbCBib29sIEV4cGFuZElubGluZUFzbShDYWxsSW5zdCAqKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgZW51bSBDb25zdHJhaW50VHlwZSB7CisgICAgQ19SZWdpc3RlciwgICAgICAgICAgICAvLyBDb25zdHJhaW50IHJlcHJlc2VudHMgc3BlY2lmaWMgcmVnaXN0ZXIocykuCisgICAgQ19SZWdpc3RlckNsYXNzLCAgICAgICAvLyBDb25zdHJhaW50IHJlcHJlc2VudHMgYW55IG9mIHJlZ2lzdGVyKHMpIGluIGNsYXNzLgorICAgIENfTWVtb3J5LCAgICAgICAgICAgICAgLy8gTWVtb3J5IGNvbnN0cmFpbnQuCisgICAgQ19PdGhlciwgICAgICAgICAgICAgICAvLyBTb21ldGhpbmcgZWxzZS4KKyAgICBDX1Vua25vd24gICAgICAgICAgICAgIC8vIFVuc3VwcG9ydGVkIGNvbnN0cmFpbnQuCisgIH07CisKKyAgZW51bSBDb25zdHJhaW50V2VpZ2h0IHsKKyAgICAvLyBHZW5lcmljIHdlaWdodHMuCisgICAgQ1dfSW52YWxpZCAgPSAtMSwgICAgIC8vIE5vIG1hdGNoLgorICAgIENXX09rYXkgICAgID0gMCwgICAgICAvLyBBY2NlcHRhYmxlLgorICAgIENXX0dvb2QgICAgID0gMSwgICAgICAvLyBHb29kIHdlaWdodC4KKyAgICBDV19CZXR0ZXIgICA9IDIsICAgICAgLy8gQmV0dGVyIHdlaWdodC4KKyAgICBDV19CZXN0ICAgICA9IDMsICAgICAgLy8gQmVzdCB3ZWlnaHQuCisKKyAgICAvLyBXZWxsLWtub3duIHdlaWdodHMuCisgICAgQ1dfU3BlY2lmaWNSZWcgID0gQ1dfT2theSwgICAgLy8gU3BlY2lmaWMgcmVnaXN0ZXIgb3BlcmFuZHMuCisgICAgQ1dfUmVnaXN0ZXIgICAgID0gQ1dfR29vZCwgICAgLy8gUmVnaXN0ZXIgb3BlcmFuZHMuCisgICAgQ1dfTWVtb3J5ICAgICAgID0gQ1dfQmV0dGVyLCAgLy8gTWVtb3J5IG9wZXJhbmRzLgorICAgIENXX0NvbnN0YW50ICAgICA9IENXX0Jlc3QsICAgIC8vIENvbnN0YW50IG9wZXJhbmQuCisgICAgQ1dfRGVmYXVsdCAgICAgID0gQ1dfT2theSAgICAgLy8gRGVmYXVsdCBvciBkb24ndCBrbm93IHR5cGUuCisgIH07CisKKyAgLy8vIFRoaXMgY29udGFpbnMgaW5mb3JtYXRpb24gZm9yIGVhY2ggY29uc3RyYWludCB0aGF0IHdlIGFyZSBsb3dlcmluZy4KKyAgc3RydWN0IEFzbU9wZXJhbmRJbmZvIDogcHVibGljIElubGluZUFzbTo6Q29uc3RyYWludEluZm8geworICAgIC8vLyBUaGlzIGNvbnRhaW5zIHRoZSBhY3R1YWwgc3RyaW5nIGZvciB0aGUgY29kZSwgbGlrZSAibSIuICBUYXJnZXRMb3dlcmluZworICAgIC8vLyBwaWNrcyB0aGUgJ2Jlc3QnIGNvZGUgZnJvbSBDb25zdHJhaW50SW5mbzo6Q29kZXMgdGhhdCBtb3N0IGNsb3NlbHkKKyAgICAvLy8gbWF0Y2hlcyB0aGUgb3BlcmFuZC4KKyAgICBzdGQ6OnN0cmluZyBDb25zdHJhaW50Q29kZTsKKworICAgIC8vLyBJbmZvcm1hdGlvbiBhYm91dCB0aGUgY29uc3RyYWludCBjb2RlLCBlLmcuIFJlZ2lzdGVyLCBSZWdpc3RlckNsYXNzLAorICAgIC8vLyBNZW1vcnksIE90aGVyLCBVbmtub3duLgorICAgIFRhcmdldExvd2VyaW5nOjpDb25zdHJhaW50VHlwZSBDb25zdHJhaW50VHlwZSA9IFRhcmdldExvd2VyaW5nOjpDX1Vua25vd247CisKKyAgICAvLy8gSWYgdGhpcyBpcyB0aGUgcmVzdWx0IG91dHB1dCBvcGVyYW5kIG9yIGEgY2xvYmJlciwgdGhpcyBpcyBudWxsLAorICAgIC8vLyBvdGhlcndpc2UgaXQgaXMgdGhlIGluY29taW5nIG9wZXJhbmQgdG8gdGhlIENhbGxJbnN0LiAgVGhpcyBnZXRzCisgICAgLy8vIG1vZGlmaWVkIGFzIHRoZSBhc20gaXMgcHJvY2Vzc2VkLgorICAgIFZhbHVlICpDYWxsT3BlcmFuZFZhbCA9IG51bGxwdHI7CisKKyAgICAvLy8gVGhlIFZhbHVlVHlwZSBmb3IgdGhlIG9wZXJhbmQgdmFsdWUuCisgICAgTVZUIENvbnN0cmFpbnRWVCA9IE1WVDo6T3RoZXI7CisKKyAgICAvLy8gQ29weSBjb25zdHJ1Y3RvciBmb3IgY29weWluZyBmcm9tIGEgQ29uc3RyYWludEluZm8uCisgICAgQXNtT3BlcmFuZEluZm8oSW5saW5lQXNtOjpDb25zdHJhaW50SW5mbyBJbmZvKQorICAgICAgICA6IElubGluZUFzbTo6Q29uc3RyYWludEluZm8oc3RkOjptb3ZlKEluZm8pKSB7fQorCisgICAgLy8vIFJldHVybiB0cnVlIG9mIHRoaXMgaXMgYW4gaW5wdXQgb3BlcmFuZCB0aGF0IGlzIGEgbWF0Y2hpbmcgY29uc3RyYWludAorICAgIC8vLyBsaWtlICI0Ii4KKyAgICBib29sIGlzTWF0Y2hpbmdJbnB1dENvbnN0cmFpbnQoKSBjb25zdDsKKworICAgIC8vLyBJZiB0aGlzIGlzIGFuIGlucHV0IG1hdGNoaW5nIGNvbnN0cmFpbnQsIHRoaXMgbWV0aG9kIHJldHVybnMgdGhlIG91dHB1dAorICAgIC8vLyBvcGVyYW5kIGl0IG1hdGNoZXMuCisgICAgdW5zaWduZWQgZ2V0TWF0Y2hlZE9wZXJhbmQoKSBjb25zdDsKKyAgfTsKKworICB1c2luZyBBc21PcGVyYW5kSW5mb1ZlY3RvciA9IHN0ZDo6dmVjdG9yPEFzbU9wZXJhbmRJbmZvPjsKKworICAvLy8gU3BsaXQgdXAgdGhlIGNvbnN0cmFpbnQgc3RyaW5nIGZyb20gdGhlIGlubGluZSBhc3NlbWJseSB2YWx1ZSBpbnRvIHRoZQorICAvLy8gc3BlY2lmaWMgY29uc3RyYWludHMgYW5kIHRoZWlyIHByZWZpeGVzLCBhbmQgYWxzbyB0aWUgaW4gdGhlIGFzc29jaWF0ZWQKKyAgLy8vIG9wZXJhbmQgdmFsdWVzLiAgSWYgdGhpcyByZXR1cm5zIGFuIGVtcHR5IHZlY3RvciwgYW5kIGlmIHRoZSBjb25zdHJhaW50CisgIC8vLyBzdHJpbmcgaXRzZWxmIGlzbid0IGVtcHR5LCB0aGVyZSB3YXMgYW4gZXJyb3IgcGFyc2luZy4KKyAgdmlydHVhbCBBc21PcGVyYW5kSW5mb1ZlY3RvciBQYXJzZUNvbnN0cmFpbnRzKGNvbnN0IERhdGFMYXlvdXQgJkRMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbW11dGFibGVDYWxsU2l0ZSBDUykgY29uc3Q7CisKKyAgLy8vIEV4YW1pbmUgY29uc3RyYWludCB0eXBlIGFuZCBvcGVyYW5kIHR5cGUgYW5kIGRldGVybWluZSBhIHdlaWdodCB2YWx1ZS4KKyAgLy8vIFRoZSBvcGVyYW5kIG9iamVjdCBtdXN0IGFscmVhZHkgaGF2ZSBiZWVuIHNldCB1cCB3aXRoIHRoZSBvcGVyYW5kIHR5cGUuCisgIHZpcnR1YWwgQ29uc3RyYWludFdlaWdodCBnZXRNdWx0aXBsZUNvbnN0cmFpbnRNYXRjaFdlaWdodCgKKyAgICAgIEFzbU9wZXJhbmRJbmZvICZpbmZvLCBpbnQgbWFJbmRleCkgY29uc3Q7CisKKyAgLy8vIEV4YW1pbmUgY29uc3RyYWludCBzdHJpbmcgYW5kIG9wZXJhbmQgdHlwZSBhbmQgZGV0ZXJtaW5lIGEgd2VpZ2h0IHZhbHVlLgorICAvLy8gVGhlIG9wZXJhbmQgb2JqZWN0IG11c3QgYWxyZWFkeSBoYXZlIGJlZW4gc2V0IHVwIHdpdGggdGhlIG9wZXJhbmQgdHlwZS4KKyAgdmlydHVhbCBDb25zdHJhaW50V2VpZ2h0IGdldFNpbmdsZUNvbnN0cmFpbnRNYXRjaFdlaWdodCgKKyAgICAgIEFzbU9wZXJhbmRJbmZvICZpbmZvLCBjb25zdCBjaGFyICpjb25zdHJhaW50KSBjb25zdDsKKworICAvLy8gRGV0ZXJtaW5lcyB0aGUgY29uc3RyYWludCBjb2RlIGFuZCBjb25zdHJhaW50IHR5cGUgdG8gdXNlIGZvciB0aGUgc3BlY2lmaWMKKyAgLy8vIEFzbU9wZXJhbmRJbmZvLCBzZXR0aW5nIE9wSW5mby5Db25zdHJhaW50Q29kZSBhbmQgT3BJbmZvLkNvbnN0cmFpbnRUeXBlLgorICAvLy8gSWYgdGhlIGFjdHVhbCBvcGVyYW5kIGJlaW5nIHBhc3NlZCBpbiBpcyBhdmFpbGFibGUsIGl0IGNhbiBiZSBwYXNzZWQgaW4gYXMKKyAgLy8vIE9wLCBvdGhlcndpc2UgYW4gZW1wdHkgU0RWYWx1ZSBjYW4gYmUgcGFzc2VkLgorICB2aXJ0dWFsIHZvaWQgQ29tcHV0ZUNvbnN0cmFpbnRUb1VzZShBc21PcGVyYW5kSW5mbyAmT3BJbmZvLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTRFZhbHVlIE9wLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3Rpb25EQUcgKkRBRyA9IG51bGxwdHIpIGNvbnN0OworCisgIC8vLyBHaXZlbiBhIGNvbnN0cmFpbnQsIHJldHVybiB0aGUgdHlwZSBvZiBjb25zdHJhaW50IGl0IGlzIGZvciB0aGlzIHRhcmdldC4KKyAgdmlydHVhbCBDb25zdHJhaW50VHlwZSBnZXRDb25zdHJhaW50VHlwZShTdHJpbmdSZWYgQ29uc3RyYWludCkgY29uc3Q7CisKKyAgLy8vIEdpdmVuIGEgcGh5c2ljYWwgcmVnaXN0ZXIgY29uc3RyYWludCAoZS5nLiAge2VkeH0pLCByZXR1cm4gdGhlIHJlZ2lzdGVyCisgIC8vLyBudW1iZXIgYW5kIHRoZSByZWdpc3RlciBjbGFzcyBmb3IgdGhlIHJlZ2lzdGVyLgorICAvLy8KKyAgLy8vIEdpdmVuIGEgcmVnaXN0ZXIgY2xhc3MgY29uc3RyYWludCwgbGlrZSAncicsIGlmIHRoaXMgY29ycmVzcG9uZHMgZGlyZWN0bHkKKyAgLy8vIHRvIGFuIExMVk0gcmVnaXN0ZXIgY2xhc3MsIHJldHVybiBhIHJlZ2lzdGVyIG9mIDAgYW5kIHRoZSByZWdpc3RlciBjbGFzcworICAvLy8gcG9pbnRlci4KKyAgLy8vCisgIC8vLyBUaGlzIHNob3VsZCBvbmx5IGJlIHVzZWQgZm9yIENfUmVnaXN0ZXIgY29uc3RyYWludHMuICBPbiBlcnJvciwgdGhpcworICAvLy8gcmV0dXJucyBhIHJlZ2lzdGVyIG51bWJlciBvZiAwIGFuZCBhIG51bGwgcmVnaXN0ZXIgY2xhc3MgcG9pbnRlci4KKyAgdmlydHVhbCBzdGQ6OnBhaXI8dW5zaWduZWQsIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKj4KKyAgZ2V0UmVnRm9ySW5saW5lQXNtQ29uc3RyYWludChjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdSZWYgQ29uc3RyYWludCwgTVZUIFZUKSBjb25zdDsKKworICB2aXJ0dWFsIHVuc2lnbmVkIGdldElubGluZUFzbU1lbUNvbnN0cmFpbnQoU3RyaW5nUmVmIENvbnN0cmFpbnRDb2RlKSBjb25zdCB7CisgICAgaWYgKENvbnN0cmFpbnRDb2RlID09ICJpIikKKyAgICAgIHJldHVybiBJbmxpbmVBc206OkNvbnN0cmFpbnRfaTsKKyAgICBlbHNlIGlmIChDb25zdHJhaW50Q29kZSA9PSAibSIpCisgICAgICByZXR1cm4gSW5saW5lQXNtOjpDb25zdHJhaW50X207CisgICAgcmV0dXJuIElubGluZUFzbTo6Q29uc3RyYWludF9Vbmtub3duOworICB9CisKKyAgLy8vIFRyeSB0byByZXBsYWNlIGFuIFggY29uc3RyYWludCwgd2hpY2ggbWF0Y2hlcyBhbnl0aGluZywgd2l0aCBhbm90aGVyIHRoYXQKKyAgLy8vIGhhcyBtb3JlIHNwZWNpZmljIHJlcXVpcmVtZW50cyBiYXNlZCBvbiB0aGUgdHlwZSBvZiB0aGUgY29ycmVzcG9uZGluZworICAvLy8gb3BlcmFuZC4gIFRoaXMgcmV0dXJucyBudWxsIGlmIHRoZXJlIGlzIG5vIHJlcGxhY2VtZW50IHRvIG1ha2UuCisgIHZpcnR1YWwgY29uc3QgY2hhciAqTG93ZXJYQ29uc3RyYWludChFVlQgQ29uc3RyYWludFZUKSBjb25zdDsKKworICAvLy8gTG93ZXIgdGhlIHNwZWNpZmllZCBvcGVyYW5kIGludG8gdGhlIE9wcyB2ZWN0b3IuICBJZiBpdCBpcyBpbnZhbGlkLCBkb24ndAorICAvLy8gYWRkIGFueXRoaW5nIHRvIE9wcy4KKyAgdmlydHVhbCB2b2lkIExvd2VyQXNtT3BlcmFuZEZvckNvbnN0cmFpbnQoU0RWYWx1ZSBPcCwgc3RkOjpzdHJpbmcgJkNvbnN0cmFpbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPFNEVmFsdWU+ICZPcHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdGlvbkRBRyAmREFHKSBjb25zdDsKKworICAvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKyAgLy8gRGl2IHV0aWxpdHkgZnVuY3Rpb25zCisgIC8vCisgIFNEVmFsdWUgQnVpbGRTRElWKFNETm9kZSAqTiwgY29uc3QgQVBJbnQgJkRpdmlzb3IsIFNlbGVjdGlvbkRBRyAmREFHLAorICAgICAgICAgICAgICAgICAgICBib29sIElzQWZ0ZXJMZWdhbGl6YXRpb24sCisgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPFNETm9kZSAqPiAqQ3JlYXRlZCkgY29uc3Q7CisgIFNEVmFsdWUgQnVpbGRVRElWKFNETm9kZSAqTiwgY29uc3QgQVBJbnQgJkRpdmlzb3IsIFNlbGVjdGlvbkRBRyAmREFHLAorICAgICAgICAgICAgICAgICAgICBib29sIElzQWZ0ZXJMZWdhbGl6YXRpb24sCisgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPFNETm9kZSAqPiAqQ3JlYXRlZCkgY29uc3Q7CisKKyAgLy8vIFRhcmdldHMgbWF5IG92ZXJyaWRlIHRoaXMgZnVuY3Rpb24gdG8gcHJvdmlkZSBjdXN0b20gU0RJViBsb3dlcmluZyBmb3IKKyAgLy8vIHBvd2VyLW9mLTIgZGVub21pbmF0b3JzLiAgSWYgdGhlIHRhcmdldCByZXR1cm5zIGFuIGVtcHR5IFNEVmFsdWUsIExMVk0KKyAgLy8vIGFzc3VtZXMgU0RJViBpcyBleHBlbnNpdmUgYW5kIHJlcGxhY2VzIGl0IHdpdGggYSBzZXJpZXMgb2Ygb3RoZXIgaW50ZWdlcgorICAvLy8gb3BlcmF0aW9ucy4KKyAgdmlydHVhbCBTRFZhbHVlIEJ1aWxkU0RJVlBvdzIoU0ROb2RlICpOLCBjb25zdCBBUEludCAmRGl2aXNvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VsZWN0aW9uREFHICZEQUcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dmVjdG9yPFNETm9kZSAqPiAqQ3JlYXRlZCkgY29uc3Q7CisKKyAgLy8vIEluZGljYXRlIHdoZXRoZXIgdGhpcyB0YXJnZXQgcHJlZmVycyB0byBjb21iaW5lIEZESVZzIHdpdGggdGhlIHNhbWUKKyAgLy8vIGRpdmlzb3IuIElmIHRoZSB0cmFuc2Zvcm0gc2hvdWxkIG5ldmVyIGJlIGRvbmUsIHJldHVybiB6ZXJvLiBJZiB0aGUKKyAgLy8vIHRyYW5zZm9ybSBzaG91bGQgYmUgZG9uZSwgcmV0dXJuIHRoZSBtaW5pbXVtIG51bWJlciBvZiBkaXZpc29yIHVzZXMKKyAgLy8vIHRoYXQgbXVzdCBleGlzdC4KKyAgdmlydHVhbCB1bnNpZ25lZCBjb21iaW5lUmVwZWF0ZWRGUERpdmlzb3JzKCkgY29uc3QgeworICAgIHJldHVybiAwOworICB9CisKKyAgLy8vIEhvb2tzIGZvciBidWlsZGluZyBlc3RpbWF0ZXMgaW4gcGxhY2Ugb2Ygc2xvd2VyIGRpdmlzaW9ucyBhbmQgc3F1YXJlCisgIC8vLyByb290cy4KKworICAvLy8gUmV0dXJuIGVpdGhlciBhIHNxdWFyZSByb290IG9yIGl0cyByZWNpcHJvY2FsIGVzdGltYXRlIHZhbHVlIGZvciB0aGUgaW5wdXQKKyAgLy8vIG9wZXJhbmQuCisgIC8vLyBccCBFbmFibGVkIGlzIGEgUmVjaXByb2NhbEVzdGltYXRlIGVudW0gd2l0aCB2YWx1ZSBlaXRoZXIgJ1Vuc3BlY2lmaWVkJyBvcgorICAvLy8gJ0VuYWJsZWQnIGFzIHNldCBieSBhIHBvdGVudGlhbCBkZWZhdWx0IG92ZXJyaWRlIGF0dHJpYnV0ZS4KKyAgLy8vIElmIFxwIFJlZmluZW1lbnRTdGVwcyBpcyAnVW5zcGVjaWZpZWQnLCB0aGUgbnVtYmVyIG9mIE5ld3Rvbi1SYXBoc29uCisgIC8vLyByZWZpbmVtZW50IGl0ZXJhdGlvbnMgcmVxdWlyZWQgdG8gZ2VuZXJhdGUgYSBzdWZmaWNpZW50ICh0aG91Z2ggbm90CisgIC8vLyBuZWNlc3NhcmlseSBJRUVFLTc1NCBjb21wbGlhbnQpIGVzdGltYXRlIGlzIHJldHVybmVkIGluIHRoYXQgcGFyYW1ldGVyLgorICAvLy8gVGhlIGJvb2xlYW4gVXNlT25lQ29uc3ROUiBvdXRwdXQgaXMgdXNlZCB0byBzZWxlY3QgYSBOZXd0b24tUmFwaHNvbgorICAvLy8gYWxnb3JpdGhtIGltcGxlbWVudGF0aW9uIHRoYXQgdXNlcyBlaXRoZXIgb25lIG9yIHR3byBjb25zdGFudHMuCisgIC8vLyBUaGUgYm9vbGVhbiBSZWNpcHJvY2FsIGlzIHVzZWQgdG8gc2VsZWN0IHdoZXRoZXIgdGhlIGVzdGltYXRlIGlzIGZvciB0aGUKKyAgLy8vIHNxdWFyZSByb290IG9mIHRoZSBpbnB1dCBvcGVyYW5kIG9yIHRoZSByZWNpcHJvY2FsIG9mIGl0cyBzcXVhcmUgcm9vdC4KKyAgLy8vIEEgdGFyZ2V0IG1heSBjaG9vc2UgdG8gaW1wbGVtZW50IGl0cyBvd24gcmVmaW5lbWVudCB3aXRoaW4gdGhpcyBmdW5jdGlvbi4KKyAgLy8vIElmIHRoYXQncyB0cnVlLCB0aGVuIHJldHVybiAnMCcgYXMgdGhlIG51bWJlciBvZiBSZWZpbmVtZW50U3RlcHMgdG8gYXZvaWQKKyAgLy8vIGFueSBmdXJ0aGVyIHJlZmluZW1lbnQgb2YgdGhlIGVzdGltYXRlLgorICAvLy8gQW4gZW1wdHkgU0RWYWx1ZSByZXR1cm4gbWVhbnMgbm8gZXN0aW1hdGUgc2VxdWVuY2UgY2FuIGJlIGNyZWF0ZWQuCisgIHZpcnR1YWwgU0RWYWx1ZSBnZXRTcXJ0RXN0aW1hdGUoU0RWYWx1ZSBPcGVyYW5kLCBTZWxlY3Rpb25EQUcgJkRBRywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgRW5hYmxlZCwgaW50ICZSZWZpbmVtZW50U3RlcHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCAmVXNlT25lQ29uc3ROUiwgYm9vbCBSZWNpcHJvY2FsKSBjb25zdCB7CisgICAgcmV0dXJuIFNEVmFsdWUoKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gYSByZWNpcHJvY2FsIGVzdGltYXRlIHZhbHVlIGZvciB0aGUgaW5wdXQgb3BlcmFuZC4KKyAgLy8vIFxwIEVuYWJsZWQgaXMgYSBSZWNpcHJvY2FsRXN0aW1hdGUgZW51bSB3aXRoIHZhbHVlIGVpdGhlciAnVW5zcGVjaWZpZWQnIG9yCisgIC8vLyAnRW5hYmxlZCcgYXMgc2V0IGJ5IGEgcG90ZW50aWFsIGRlZmF1bHQgb3ZlcnJpZGUgYXR0cmlidXRlLgorICAvLy8gSWYgXHAgUmVmaW5lbWVudFN0ZXBzIGlzICdVbnNwZWNpZmllZCcsIHRoZSBudW1iZXIgb2YgTmV3dG9uLVJhcGhzb24KKyAgLy8vIHJlZmluZW1lbnQgaXRlcmF0aW9ucyByZXF1aXJlZCB0byBnZW5lcmF0ZSBhIHN1ZmZpY2llbnQgKHRob3VnaCBub3QKKyAgLy8vIG5lY2Vzc2FyaWx5IElFRUUtNzU0IGNvbXBsaWFudCkgZXN0aW1hdGUgaXMgcmV0dXJuZWQgaW4gdGhhdCBwYXJhbWV0ZXIuCisgIC8vLyBBIHRhcmdldCBtYXkgY2hvb3NlIHRvIGltcGxlbWVudCBpdHMgb3duIHJlZmluZW1lbnQgd2l0aGluIHRoaXMgZnVuY3Rpb24uCisgIC8vLyBJZiB0aGF0J3MgdHJ1ZSwgdGhlbiByZXR1cm4gJzAnIGFzIHRoZSBudW1iZXIgb2YgUmVmaW5lbWVudFN0ZXBzIHRvIGF2b2lkCisgIC8vLyBhbnkgZnVydGhlciByZWZpbmVtZW50IG9mIHRoZSBlc3RpbWF0ZS4KKyAgLy8vIEFuIGVtcHR5IFNEVmFsdWUgcmV0dXJuIG1lYW5zIG5vIGVzdGltYXRlIHNlcXVlbmNlIGNhbiBiZSBjcmVhdGVkLgorICB2aXJ0dWFsIFNEVmFsdWUgZ2V0UmVjaXBFc3RpbWF0ZShTRFZhbHVlIE9wZXJhbmQsIFNlbGVjdGlvbkRBRyAmREFHLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgRW5hYmxlZCwgaW50ICZSZWZpbmVtZW50U3RlcHMpIGNvbnN0IHsKKyAgICByZXR1cm4gU0RWYWx1ZSgpOworICB9CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vIExlZ2FsaXphdGlvbiB1dGlsaXR5IGZ1bmN0aW9ucworICAvLworCisgIC8vLyBFeHBhbmQgYSBNVUwgb3IgW1VTXU1VTF9MT0hJIG9mIG4tYml0IHZhbHVlcyBpbnRvIHR3byBvciBmb3VyIG5vZGVzLAorICAvLy8gcmVzcGVjdGl2ZWx5LCBlYWNoIGNvbXB1dGluZyBhbiBuLzItYml0IHBhcnQgb2YgdGhlIHJlc3VsdC4KKyAgLy8vIFxwYXJhbSBSZXN1bHQgQSB2ZWN0b3IgdGhhdCB3aWxsIGJlIGZpbGxlZCB3aXRoIHRoZSBwYXJ0cyBvZiB0aGUgcmVzdWx0CisgIC8vLyAgICAgICAgaW4gbGl0dGxlLWVuZGlhbiBvcmRlci4KKyAgLy8vIFxwYXJhbSBMTCBMb3cgYml0cyBvZiB0aGUgTEhTIG9mIHRoZSBNVUwuICBZb3UgY2FuIHVzZSB0aGlzIHBhcmFtZXRlcgorICAvLy8gICAgICAgIGlmIHlvdSB3YW50IHRvIGNvbnRyb2wgaG93IGxvdyBiaXRzIGFyZSBleHRyYWN0ZWQgZnJvbSB0aGUgTEhTLgorICAvLy8gXHBhcmFtIExIIEhpZ2ggYml0cyBvZiB0aGUgTEhTIG9mIHRoZSBNVUwuICBTZWUgTEwgZm9yIG1lYW5pbmcuCisgIC8vLyBccGFyYW0gUkwgTG93IGJpdHMgb2YgdGhlIFJIUyBvZiB0aGUgTVVMLiAgU2VlIExMIGZvciBtZWFuaW5nCisgIC8vLyBccGFyYW0gUkggSGlnaCBiaXRzIG9mIHRoZSBSSFMgb2YgdGhlIE1VTC4gIFNlZSBMTCBmb3IgbWVhbmluZy4KKyAgLy8vIFxyZXR1cm5zIHRydWUgaWYgdGhlIG5vZGUgaGFzIGJlZW4gZXhwYW5kZWQsIGZhbHNlIGlmIGl0IGhhcyBub3QKKyAgYm9vbCBleHBhbmRNVUxfTE9ISSh1bnNpZ25lZCBPcGNvZGUsIEVWVCBWVCwgU0RMb2MgZGwsIFNEVmFsdWUgTEhTLAorICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgUkhTLCBTbWFsbFZlY3RvckltcGw8U0RWYWx1ZT4gJlJlc3VsdCwgRVZUIEhpTG9WVCwKKyAgICAgICAgICAgICAgICAgICAgICBTZWxlY3Rpb25EQUcgJkRBRywgTXVsRXhwYW5zaW9uS2luZCBLaW5kLAorICAgICAgICAgICAgICAgICAgICAgIFNEVmFsdWUgTEwgPSBTRFZhbHVlKCksIFNEVmFsdWUgTEggPSBTRFZhbHVlKCksCisgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBSTCA9IFNEVmFsdWUoKSwgU0RWYWx1ZSBSSCA9IFNEVmFsdWUoKSkgY29uc3Q7CisKKyAgLy8vIEV4cGFuZCBhIE1VTCBpbnRvIHR3byBub2Rlcy4gIE9uZSB0aGF0IGNvbXB1dGVzIHRoZSBoaWdoIGJpdHMgb2YKKyAgLy8vIHRoZSByZXN1bHQgYW5kIG9uZSB0aGF0IGNvbXB1dGVzIHRoZSBsb3cgYml0cy4KKyAgLy8vIFxwYXJhbSBIaUxvVlQgVGhlIHZhbHVlIHR5cGUgdG8gdXNlIGZvciB0aGUgTG8gYW5kIEhpIG5vZGVzLgorICAvLy8gXHBhcmFtIExMIExvdyBiaXRzIG9mIHRoZSBMSFMgb2YgdGhlIE1VTC4gIFlvdSBjYW4gdXNlIHRoaXMgcGFyYW1ldGVyCisgIC8vLyAgICAgICAgaWYgeW91IHdhbnQgdG8gY29udHJvbCBob3cgbG93IGJpdHMgYXJlIGV4dHJhY3RlZCBmcm9tIHRoZSBMSFMuCisgIC8vLyBccGFyYW0gTEggSGlnaCBiaXRzIG9mIHRoZSBMSFMgb2YgdGhlIE1VTC4gIFNlZSBMTCBmb3IgbWVhbmluZy4KKyAgLy8vIFxwYXJhbSBSTCBMb3cgYml0cyBvZiB0aGUgUkhTIG9mIHRoZSBNVUwuICBTZWUgTEwgZm9yIG1lYW5pbmcKKyAgLy8vIFxwYXJhbSBSSCBIaWdoIGJpdHMgb2YgdGhlIFJIUyBvZiB0aGUgTVVMLiAgU2VlIExMIGZvciBtZWFuaW5nLgorICAvLy8gXHJldHVybnMgdHJ1ZSBpZiB0aGUgbm9kZSBoYXMgYmVlbiBleHBhbmRlZC4gZmFsc2UgaWYgaXQgaGFzIG5vdAorICBib29sIGV4cGFuZE1VTChTRE5vZGUgKk4sIFNEVmFsdWUgJkxvLCBTRFZhbHVlICZIaSwgRVZUIEhpTG9WVCwKKyAgICAgICAgICAgICAgICAgU2VsZWN0aW9uREFHICZEQUcsIE11bEV4cGFuc2lvbktpbmQgS2luZCwKKyAgICAgICAgICAgICAgICAgU0RWYWx1ZSBMTCA9IFNEVmFsdWUoKSwgU0RWYWx1ZSBMSCA9IFNEVmFsdWUoKSwKKyAgICAgICAgICAgICAgICAgU0RWYWx1ZSBSTCA9IFNEVmFsdWUoKSwgU0RWYWx1ZSBSSCA9IFNEVmFsdWUoKSkgY29uc3Q7CisKKyAgLy8vIEV4cGFuZCBmbG9hdChmMzIpIHRvIFNJTlQoaTY0KSBjb252ZXJzaW9uCisgIC8vLyBccGFyYW0gTiBOb2RlIHRvIGV4cGFuZAorICAvLy8gXHBhcmFtIFJlc3VsdCBvdXRwdXQgYWZ0ZXIgY29udmVyc2lvbgorICAvLy8gXHJldHVybnMgVHJ1ZSwgaWYgdGhlIGV4cGFuc2lvbiB3YXMgc3VjY2Vzc2Z1bCwgZmFsc2Ugb3RoZXJ3aXNlCisgIGJvb2wgZXhwYW5kRlBfVE9fU0lOVChTRE5vZGUgKk4sIFNEVmFsdWUgJlJlc3VsdCwgU2VsZWN0aW9uREFHICZEQUcpIGNvbnN0OworCisgIC8vLyBUdXJuIGxvYWQgb2YgdmVjdG9yIHR5cGUgaW50byBhIGxvYWQgb2YgdGhlIGluZGl2aWR1YWwgZWxlbWVudHMuCisgIC8vLyBccGFyYW0gTEQgbG9hZCB0byBleHBhbmQKKyAgLy8vIFxyZXR1cm5zIE1FUkdFX1ZBTFVFcyBvZiB0aGUgc2NhbGFyIGxvYWRzIHdpdGggdGhlaXIgY2hhaW5zLgorICBTRFZhbHVlIHNjYWxhcml6ZVZlY3RvckxvYWQoTG9hZFNETm9kZSAqTEQsIFNlbGVjdGlvbkRBRyAmREFHKSBjb25zdDsKKworICAvLyBUdXJuIGEgc3RvcmUgb2YgYSB2ZWN0b3IgdHlwZSBpbnRvIHN0b3JlcyBvZiB0aGUgaW5kaXZpZHVhbCBlbGVtZW50cy4KKyAgLy8vIFxwYXJhbSBTVCBTdG9yZSB3aXRoIGEgdmVjdG9yIHZhbHVlIHR5cGUKKyAgLy8vIFxyZXR1cm5zIE1FUkdFX1ZBTFVzIG9mIHRoZSBpbmRpdmlkdWFsIHN0b3JlIGNoYWlucy4KKyAgU0RWYWx1ZSBzY2FsYXJpemVWZWN0b3JTdG9yZShTdG9yZVNETm9kZSAqU1QsIFNlbGVjdGlvbkRBRyAmREFHKSBjb25zdDsKKworICAvLy8gRXhwYW5kcyBhbiB1bmFsaWduZWQgbG9hZCB0byAyIGhhbGYtc2l6ZSBsb2FkcyBmb3IgYW4gaW50ZWdlciwgYW5kCisgIC8vLyBwb3NzaWJseSBtb3JlIGZvciB2ZWN0b3JzLgorICBzdGQ6OnBhaXI8U0RWYWx1ZSwgU0RWYWx1ZT4gZXhwYW5kVW5hbGlnbmVkTG9hZChMb2FkU0ROb2RlICpMRCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VsZWN0aW9uREFHICZEQUcpIGNvbnN0OworCisgIC8vLyBFeHBhbmRzIGFuIHVuYWxpZ25lZCBzdG9yZSB0byAyIGhhbGYtc2l6ZSBzdG9yZXMgZm9yIGludGVnZXIgdmFsdWVzLCBhbmQKKyAgLy8vIHBvc3NpYmx5IG1vcmUgZm9yIHZlY3RvcnMuCisgIFNEVmFsdWUgZXhwYW5kVW5hbGlnbmVkU3RvcmUoU3RvcmVTRE5vZGUgKlNULCBTZWxlY3Rpb25EQUcgJkRBRykgY29uc3Q7CisKKyAgLy8vIEluY3JlbWVudHMgbWVtb3J5IGFkZHJlc3MgXHAgQWRkciBhY2NvcmRpbmcgdG8gdGhlIHR5cGUgb2YgdGhlIHZhbHVlCisgIC8vLyBccCBEYXRhVlQgdGhhdCBzaG91bGQgYmUgc3RvcmVkLiBJZiB0aGUgZGF0YSBpcyBzdG9yZWQgaW4gY29tcHJlc3NlZAorICAvLy8gZm9ybSwgdGhlIG1lbW9yeSBhZGRyZXNzIHNob3VsZCBiZSBpbmNyZW1lbnRlZCBhY2NvcmRpbmcgdG8gdGhlIG51bWJlciBvZgorICAvLy8gdGhlIHN0b3JlZCBlbGVtZW50cy4gVGhpcyBudW1iZXIgaXMgZXF1YWwgdG8gdGhlIG51bWJlciBvZiAnMSdzIGJpdHMKKyAgLy8vIGluIHRoZSBccCBNYXNrLgorICAvLy8gXHAgRGF0YVZUIGlzIGEgdmVjdG9yIHR5cGUuIFxwIE1hc2sgaXMgYSB2ZWN0b3IgdmFsdWUuCisgIC8vLyBccCBEYXRhVlQgYW5kIFxwIE1hc2sgaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgdmVjdG9yIGVsZW1lbnRzLgorICBTRFZhbHVlIEluY3JlbWVudE1lbW9yeUFkZHJlc3MoU0RWYWx1ZSBBZGRyLCBTRFZhbHVlIE1hc2ssIGNvbnN0IFNETG9jICZETCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVWVCBEYXRhVlQsIFNlbGVjdGlvbkRBRyAmREFHLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBJc0NvbXByZXNzZWRNZW1vcnkpIGNvbnN0OworCisgIC8vLyBHZXQgYSBwb2ludGVyIHRvIHZlY3RvciBlbGVtZW50IFxwIElkeCBsb2NhdGVkIGluIG1lbW9yeSBmb3IgYSB2ZWN0b3Igb2YKKyAgLy8vIHR5cGUgXHAgVmVjVlQgc3RhcnRpbmcgYXQgYSBiYXNlIGFkZHJlc3Mgb2YgXHAgVmVjUHRyLiBJZiBccCBJZHggaXMgb3V0IG9mCisgIC8vLyBib3VuZHMgdGhlIHJldHVybmVkIHBvaW50ZXIgaXMgdW5zcGVjaWZpZWQsIGJ1dCB3aWxsIGJlIHdpdGhpbiB0aGUgdmVjdG9yCisgIC8vLyBib3VuZHMuCisgIFNEVmFsdWUgZ2V0VmVjdG9yRWxlbWVudFBvaW50ZXIoU2VsZWN0aW9uREFHICZEQUcsIFNEVmFsdWUgVmVjUHRyLCBFVlQgVmVjVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0RWYWx1ZSBJZHgpIGNvbnN0OworCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLyBJbnN0cnVjdGlvbiBFbWl0dGluZyBIb29rcworICAvLworCisgIC8vLyBUaGlzIG1ldGhvZCBzaG91bGQgYmUgaW1wbGVtZW50ZWQgYnkgdGFyZ2V0cyB0aGF0IG1hcmsgaW5zdHJ1Y3Rpb25zIHdpdGgKKyAgLy8vIHRoZSAndXNlc0N1c3RvbUluc2VydGVyJyBmbGFnLiAgVGhlc2UgaW5zdHJ1Y3Rpb25zIGFyZSBzcGVjaWFsIGluIHZhcmlvdXMKKyAgLy8vIHdheXMsIHdoaWNoIHJlcXVpcmUgc3BlY2lhbCBzdXBwb3J0IHRvIGluc2VydC4gIFRoZSBzcGVjaWZpZWQgTWFjaGluZUluc3RyCisgIC8vLyBpcyBjcmVhdGVkIGJ1dCBub3QgaW5zZXJ0ZWQgaW50byBhbnkgYmFzaWMgYmxvY2tzLCBhbmQgdGhpcyBtZXRob2QgaXMKKyAgLy8vIGNhbGxlZCB0byBleHBhbmQgaXQgaW50byBhIHNlcXVlbmNlIG9mIGluc3RydWN0aW9ucywgcG90ZW50aWFsbHkgYWxzbworICAvLy8gY3JlYXRpbmcgbmV3IGJhc2ljIGJsb2NrcyBhbmQgY29udHJvbCBmbG93LgorICAvLy8gQXMgbG9uZyBhcyB0aGUgcmV0dXJuZWQgYmFzaWMgYmxvY2sgaXMgZGlmZmVyZW50IChpLmUuLCB3ZSBjcmVhdGVkIGEgbmV3CisgIC8vLyBvbmUpLCB0aGUgY3VzdG9tIGluc2VydGVyIGlzIGZyZWUgdG8gbW9kaWZ5IHRoZSByZXN0IG9mIFxwIE1CQi4KKyAgdmlydHVhbCBNYWNoaW5lQmFzaWNCbG9jayAqCisgIEVtaXRJbnN0cldpdGhDdXN0b21JbnNlcnRlcihNYWNoaW5lSW5zdHIgJk1JLCBNYWNoaW5lQmFzaWNCbG9jayAqTUJCKSBjb25zdDsKKworICAvLy8gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIGltcGxlbWVudGVkIGJ5IHRhcmdldHMgdGhhdCBtYXJrIGluc3RydWN0aW9ucyB3aXRoCisgIC8vLyB0aGUgJ2hhc1Bvc3RJU2VsSG9vaycgZmxhZy4gVGhlc2UgaW5zdHJ1Y3Rpb25zIG11c3QgYmUgYWRqdXN0ZWQgYWZ0ZXIKKyAgLy8vIGluc3RydWN0aW9uIHNlbGVjdGlvbiBieSB0YXJnZXQgaG9va3MuICBlLmcuIFRvIGZpbGwgaW4gb3B0aW9uYWwgZGVmcyBmb3IKKyAgLy8vIEFSTSAncycgc2V0dGluZyBpbnN0cnVjdGlvbnMuCisgIHZpcnR1YWwgdm9pZCBBZGp1c3RJbnN0clBvc3RJbnN0clNlbGVjdGlvbihNYWNoaW5lSW5zdHIgJk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0ROb2RlICpOb2RlKSBjb25zdDsKKworICAvLy8gSWYgdGhpcyBmdW5jdGlvbiByZXR1cm5zIHRydWUsIFNlbGVjdGlvbkRBR0J1aWxkZXIgZW1pdHMgYQorICAvLy8gTE9BRF9TVEFDS19HVUFSRCBub2RlIHdoZW4gaXQgaXMgbG93ZXJpbmcgSW50cmluc2ljOjpzdGFja3Byb3RlY3Rvci4KKyAgdmlydHVhbCBib29sIHVzZUxvYWRTdGFja0d1YXJkTm9kZSgpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICB2aXJ0dWFsIFNEVmFsdWUgZW1pdFN0YWNrR3VhcmRYb3JGUChTZWxlY3Rpb25EQUcgJkRBRywgU0RWYWx1ZSBWYWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNETG9jICZETCkgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIm5vdCBpbXBsZW1lbnRlZCBmb3IgdGhpcyB0YXJnZXQiKTsKKyAgfQorCisgIC8vLyBMb3dlciBUTFMgZ2xvYmFsIGFkZHJlc3MgU0ROb2RlIGZvciB0YXJnZXQgaW5kZXBlbmRlbnQgZW11bGF0ZWQgVExTIG1vZGVsLgorICB2aXJ0dWFsIFNEVmFsdWUgTG93ZXJUb1RMU0VtdWxhdGVkTW9kZWwoY29uc3QgR2xvYmFsQWRkcmVzc1NETm9kZSAqR0EsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWxlY3Rpb25EQUcgJkRBRykgY29uc3Q7CisKKyAgLy8vIEV4cGFuZHMgdGFyZ2V0IHNwZWNpZmljIGluZGlyZWN0IGJyYW5jaCBmb3IgdGhlIGNhc2Ugb2YgSnVtcFRhYmxlCisgIC8vLyBleHBhbmFzaW9uLgorICB2aXJ0dWFsIFNEVmFsdWUgZXhwYW5kSW5kaXJlY3RKVEJyYW5jaChjb25zdCBTRExvYyYgZGwsIFNEVmFsdWUgVmFsdWUsIFNEVmFsdWUgQWRkciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VsZWN0aW9uREFHICZEQUcpIGNvbnN0IHsKKyAgICByZXR1cm4gREFHLmdldE5vZGUoSVNEOjpCUklORCwgZGwsIE1WVDo6T3RoZXIsIFZhbHVlLCBBZGRyKTsKKyAgfQorCisgIC8vIHNldGVxKHgsIDApIC0+IHRydW5jYXRlKHNybChjdGx6KHpleHQoeCkpLCBsb2cyKCNiaXRzKSkpCisgIC8vIElmIHdlJ3JlIGNvbXBhcmluZyBmb3IgZXF1YWxpdHkgdG8gemVybyBhbmQgaXNDdGx6RmFzdCBpcyB0cnVlLCBleHBvc2UgdGhlCisgIC8vIGZhY3QgdGhhdCB0aGlzIGNhbiBiZSBpbXBsZW1lbnRlZCBhcyBhIGN0bHovc3JsIHBhaXIsIHNvIHRoYXQgdGhlIGRhZworICAvLyBjb21iaW5lciBjYW4gZm9sZCB0aGUgbmV3IG5vZGVzLgorICBTRFZhbHVlIGxvd2VyQ21wRXFaZXJvVG9DdGx6U3JsKFNEVmFsdWUgT3AsIFNlbGVjdGlvbkRBRyAmREFHKSBjb25zdDsKKworcHJpdmF0ZToKKyAgU0RWYWx1ZSBzaW1wbGlmeVNldENDV2l0aEFuZChFVlQgVlQsIFNEVmFsdWUgTjAsIFNEVmFsdWUgTjEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVNEOjpDb25kQ29kZSBDb25kLCBEQUdDb21iaW5lckluZm8gJkRDSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTRExvYyAmREwpIGNvbnN0OworfTsKKworLy8vIEdpdmVuIGFuIExMVk0gSVIgdHlwZSBhbmQgcmV0dXJuIHR5cGUgYXR0cmlidXRlcywgY29tcHV0ZSB0aGUgcmV0dXJuIHZhbHVlCisvLy8gRVZUcyBhbmQgZmxhZ3MsIGFuZCBvcHRpb25hbGx5IGFsc28gdGhlIG9mZnNldHMsIGlmIHRoZSByZXR1cm4gdmFsdWUgaXMKKy8vLyBiZWluZyBsb3dlcmVkIHRvIG1lbW9yeS4KK3ZvaWQgR2V0UmV0dXJuSW5mbyhUeXBlICpSZXR1cm5UeXBlLCBBdHRyaWJ1dGVMaXN0IGF0dHIsCisgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPElTRDo6T3V0cHV0QXJnPiAmT3V0cywKKyAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRMb3dlcmluZyAmVExJLCBjb25zdCBEYXRhTGF5b3V0ICZETCk7CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fVEFSR0VUTE9XRVJJTkdfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhcmdldExvd2VyaW5nT2JqZWN0RmlsZUltcGwuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9UYXJnZXRMb3dlcmluZ09iamVjdEZpbGVJbXBsLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzhkYTc3ZgotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9UYXJnZXRMb3dlcmluZ09iamVjdEZpbGVJbXBsLmgKQEAgLTAsMCArMSwyMDAgQEAKKy8vPT0tIGxsdm0vQ29kZUdlbi9UYXJnZXRMb3dlcmluZ09iamVjdEZpbGVJbXBsLmggLSBPYmplY3QgSW5mbyAtLSotIEMrKyAtKi09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGltcGxlbWVudHMgY2xhc3NlcyB1c2VkIHRvIGhhbmRsZSBsb3dlcmluZ3Mgc3BlY2lmaWMgdG8gY29tbW9uCisvLyBvYmplY3QgZmlsZSBmb3JtYXRzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1RBUkdFVExPV0VSSU5HT0JKRUNURklMRUlNUExfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fVEFSR0VUTE9XRVJJTkdPQkpFQ1RGSUxFSU1QTF9ICisKKyNpbmNsdWRlICJsbHZtL0lSL01vZHVsZS5oIgorI2luY2x1ZGUgImxsdm0vTUMvTUNFeHByLmgiCisjaW5jbHVkZSAibGx2bS9UYXJnZXQvVGFyZ2V0TG93ZXJpbmdPYmplY3RGaWxlLmgiCisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgR2xvYmFsVmFsdWU7CitjbGFzcyBNYWNoaW5lTW9kdWxlSW5mbzsKK2NsYXNzIE1hbmdsZXI7CitjbGFzcyBNQ0NvbnRleHQ7CitjbGFzcyBNQ1NlY3Rpb247CitjbGFzcyBNQ1N5bWJvbDsKK2NsYXNzIFRhcmdldE1hY2hpbmU7CisKK2NsYXNzIFRhcmdldExvd2VyaW5nT2JqZWN0RmlsZUVMRiA6IHB1YmxpYyBUYXJnZXRMb3dlcmluZ09iamVjdEZpbGUgeworICBib29sIFVzZUluaXRBcnJheSA9IGZhbHNlOworICBtdXRhYmxlIHVuc2lnbmVkIE5leHRVbmlxdWVJRCA9IDE7ICAvLyBJRCAwIGlzIHJlc2VydmVkIGZvciBleGVjdXRlLW9ubHkgc2VjdGlvbnMKKworcHJvdGVjdGVkOgorICBNQ1N5bWJvbFJlZkV4cHI6OlZhcmlhbnRLaW5kIFBMVFJlbGF0aXZlVmFyaWFudEtpbmQgPQorICAgICAgTUNTeW1ib2xSZWZFeHByOjpWS19Ob25lOworCitwdWJsaWM6CisgIFRhcmdldExvd2VyaW5nT2JqZWN0RmlsZUVMRigpID0gZGVmYXVsdDsKKyAgflRhcmdldExvd2VyaW5nT2JqZWN0RmlsZUVMRigpIG92ZXJyaWRlID0gZGVmYXVsdDsKKworICAvLy8gRW1pdCBPYmotQyBnYXJiYWdlIGNvbGxlY3Rpb24gYW5kIGxpbmtlciBvcHRpb25zLgorICB2b2lkIGVtaXRNb2R1bGVNZXRhZGF0YShNQ1N0cmVhbWVyICZTdHJlYW1lciwgTW9kdWxlICZNLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgdm9pZCBlbWl0UGVyc29uYWxpdHlWYWx1ZShNQ1N0cmVhbWVyICZTdHJlYW1lciwgY29uc3QgRGF0YUxheW91dCAmVE0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTUNTeW1ib2wgKlN5bSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgLy8vIEdpdmVuIGEgY29uc3RhbnQgd2l0aCB0aGUgU2VjdGlvbktpbmQsIHJldHVybiBhIHNlY3Rpb24gdGhhdCBpdCBzaG91bGQgYmUKKyAgLy8vIHBsYWNlZCBpbi4KKyAgTUNTZWN0aW9uICpnZXRTZWN0aW9uRm9yQ29uc3RhbnQoY29uc3QgRGF0YUxheW91dCAmREwsIFNlY3Rpb25LaW5kIEtpbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENvbnN0YW50ICpDLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCAmQWxpZ24pIGNvbnN0IG92ZXJyaWRlOworCisgIE1DU2VjdGlvbiAqZ2V0RXhwbGljaXRTZWN0aW9uR2xvYmFsKGNvbnN0IEdsb2JhbE9iamVjdCAqR08sIFNlY3Rpb25LaW5kIEtpbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldE1hY2hpbmUgJlRNKSBjb25zdCBvdmVycmlkZTsKKworICBNQ1NlY3Rpb24gKlNlbGVjdFNlY3Rpb25Gb3JHbG9iYWwoY29uc3QgR2xvYmFsT2JqZWN0ICpHTywgU2VjdGlvbktpbmQgS2luZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldE1hY2hpbmUgJlRNKSBjb25zdCBvdmVycmlkZTsKKworICBNQ1NlY3Rpb24gKmdldFNlY3Rpb25Gb3JKdW1wVGFibGUoY29uc3QgRnVuY3Rpb24gJkYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgYm9vbCBzaG91bGRQdXRKdW1wVGFibGVJbkZ1bmN0aW9uU2VjdGlvbihib29sIFVzZXNMYWJlbERpZmZlcmVuY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRnVuY3Rpb24gJkYpIGNvbnN0IG92ZXJyaWRlOworCisgIC8vLyBSZXR1cm4gYW4gTUNFeHByIHRvIHVzZSBmb3IgYSByZWZlcmVuY2UgdG8gdGhlIHNwZWNpZmllZCB0eXBlIGluZm8gZ2xvYmFsCisgIC8vLyB2YXJpYWJsZSBmcm9tIGV4Y2VwdGlvbiBoYW5kbGluZyBpbmZvcm1hdGlvbi4KKyAgY29uc3QgTUNFeHByICpnZXRUVHlwZUdsb2JhbFJlZmVyZW5jZShjb25zdCBHbG9iYWxWYWx1ZSAqR1YsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgRW5jb2RpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0TWFjaGluZSAmVE0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZU1vZHVsZUluZm8gKk1NSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQ1N0cmVhbWVyICZTdHJlYW1lcikgY29uc3Qgb3ZlcnJpZGU7CisKKyAgLy8gVGhlIHN5bWJvbCB0aGF0IGdldHMgcGFzc2VkIHRvIC5jZmlfcGVyc29uYWxpdHkuCisgIE1DU3ltYm9sICpnZXRDRklQZXJzb25hbGl0eVN5bWJvbChjb25zdCBHbG9iYWxWYWx1ZSAqR1YsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVNb2R1bGVJbmZvICpNTUkpIGNvbnN0IG92ZXJyaWRlOworCisgIHZvaWQgSW5pdGlhbGl6ZUVMRihib29sIFVzZUluaXRBcnJheV8pOworICBNQ1NlY3Rpb24gKmdldFN0YXRpY0N0b3JTZWN0aW9uKHVuc2lnbmVkIFByaW9yaXR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1DU3ltYm9sICpLZXlTeW0pIGNvbnN0IG92ZXJyaWRlOworICBNQ1NlY3Rpb24gKmdldFN0YXRpY0R0b3JTZWN0aW9uKHVuc2lnbmVkIFByaW9yaXR5LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1DU3ltYm9sICpLZXlTeW0pIGNvbnN0IG92ZXJyaWRlOworCisgIGNvbnN0IE1DRXhwciAqbG93ZXJSZWxhdGl2ZVJlZmVyZW5jZShjb25zdCBHbG9iYWxWYWx1ZSAqTEhTLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgR2xvYmFsVmFsdWUgKlJIUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldE1hY2hpbmUgJlRNKSBjb25zdCBvdmVycmlkZTsKK307CisKK2NsYXNzIFRhcmdldExvd2VyaW5nT2JqZWN0RmlsZU1hY2hPIDogcHVibGljIFRhcmdldExvd2VyaW5nT2JqZWN0RmlsZSB7CitwdWJsaWM6CisgIFRhcmdldExvd2VyaW5nT2JqZWN0RmlsZU1hY2hPKCk7CisgIH5UYXJnZXRMb3dlcmluZ09iamVjdEZpbGVNYWNoTygpIG92ZXJyaWRlID0gZGVmYXVsdDsKKworICB2b2lkIEluaXRpYWxpemUoTUNDb250ZXh0ICZDdHgsIGNvbnN0IFRhcmdldE1hY2hpbmUgJlRNKSBvdmVycmlkZTsKKworICAvLy8gRW1pdCB0aGUgbW9kdWxlIGZsYWdzIHRoYXQgc3BlY2lmeSB0aGUgZ2FyYmFnZSBjb2xsZWN0aW9uIGluZm9ybWF0aW9uLgorICB2b2lkIGVtaXRNb2R1bGVNZXRhZGF0YShNQ1N0cmVhbWVyICZTdHJlYW1lciwgTW9kdWxlICZNLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgTUNTZWN0aW9uICpTZWxlY3RTZWN0aW9uRm9yR2xvYmFsKGNvbnN0IEdsb2JhbE9iamVjdCAqR08sIFNlY3Rpb25LaW5kIEtpbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgTUNTZWN0aW9uICpnZXRFeHBsaWNpdFNlY3Rpb25HbG9iYWwoY29uc3QgR2xvYmFsT2JqZWN0ICpHTywgU2VjdGlvbktpbmQgS2luZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0TWFjaGluZSAmVE0pIGNvbnN0IG92ZXJyaWRlOworCisgIE1DU2VjdGlvbiAqZ2V0U2VjdGlvbkZvckNvbnN0YW50KGNvbnN0IERhdGFMYXlvdXQgJkRMLCBTZWN0aW9uS2luZCBLaW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDb25zdGFudCAqQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgJkFsaWduKSBjb25zdCBvdmVycmlkZTsKKworICAvLy8gVGhlIG1hY2gtbyB2ZXJzaW9uIG9mIHRoaXMgbWV0aG9kIGRlZmF1bHRzIHRvIHJldHVybmluZyBhIHN0dWIgcmVmZXJlbmNlLgorICBjb25zdCBNQ0V4cHIgKmdldFRUeXBlR2xvYmFsUmVmZXJlbmNlKGNvbnN0IEdsb2JhbFZhbHVlICpHViwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBFbmNvZGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYWNoaW5lTW9kdWxlSW5mbyAqTU1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1DU3RyZWFtZXIgJlN0cmVhbWVyKSBjb25zdCBvdmVycmlkZTsKKworICAvLyBUaGUgc3ltYm9sIHRoYXQgZ2V0cyBwYXNzZWQgdG8gLmNmaV9wZXJzb25hbGl0eS4KKyAgTUNTeW1ib2wgKmdldENGSVBlcnNvbmFsaXR5U3ltYm9sKGNvbnN0IEdsb2JhbFZhbHVlICpHViwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldE1hY2hpbmUgJlRNLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZU1vZHVsZUluZm8gKk1NSSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgLy8vIEdldCBNYWNoTyBQQyByZWxhdGl2ZSBHT1QgZW50cnkgcmVsb2NhdGlvbgorICBjb25zdCBNQ0V4cHIgKmdldEluZGlyZWN0U3ltVmlhR09UUENSZWwoY29uc3QgTUNTeW1ib2wgKlN5bSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1DVmFsdWUgJk1WLCBpbnQ2NF90IE9mZnNldCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVNb2R1bGVJbmZvICpNTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQ1N0cmVhbWVyICZTdHJlYW1lcikgY29uc3Qgb3ZlcnJpZGU7CisKKyAgdm9pZCBnZXROYW1lV2l0aFByZWZpeChTbWFsbFZlY3RvckltcGw8Y2hhcj4gJk91dE5hbWUsIGNvbnN0IEdsb2JhbFZhbHVlICpHViwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTSkgY29uc3Qgb3ZlcnJpZGU7Cit9OworCitjbGFzcyBUYXJnZXRMb3dlcmluZ09iamVjdEZpbGVDT0ZGIDogcHVibGljIFRhcmdldExvd2VyaW5nT2JqZWN0RmlsZSB7CisgIG11dGFibGUgdW5zaWduZWQgTmV4dFVuaXF1ZUlEID0gMDsKKworcHVibGljOgorICB+VGFyZ2V0TG93ZXJpbmdPYmplY3RGaWxlQ09GRigpIG92ZXJyaWRlID0gZGVmYXVsdDsKKworICB2b2lkIEluaXRpYWxpemUoTUNDb250ZXh0ICZDdHgsIGNvbnN0IFRhcmdldE1hY2hpbmUgJlRNKSBvdmVycmlkZTsKKyAgTUNTZWN0aW9uICpnZXRFeHBsaWNpdFNlY3Rpb25HbG9iYWwoY29uc3QgR2xvYmFsT2JqZWN0ICpHTywgU2VjdGlvbktpbmQgS2luZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0TWFjaGluZSAmVE0pIGNvbnN0IG92ZXJyaWRlOworCisgIE1DU2VjdGlvbiAqU2VsZWN0U2VjdGlvbkZvckdsb2JhbChjb25zdCBHbG9iYWxPYmplY3QgKkdPLCBTZWN0aW9uS2luZCBLaW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0TWFjaGluZSAmVE0pIGNvbnN0IG92ZXJyaWRlOworCisgIHZvaWQgZ2V0TmFtZVdpdGhQcmVmaXgoU21hbGxWZWN0b3JJbXBsPGNoYXI+ICZPdXROYW1lLCBjb25zdCBHbG9iYWxWYWx1ZSAqR1YsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0TWFjaGluZSAmVE0pIGNvbnN0IG92ZXJyaWRlOworCisgIE1DU2VjdGlvbiAqZ2V0U2VjdGlvbkZvckp1bXBUYWJsZShjb25zdCBGdW5jdGlvbiAmRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldE1hY2hpbmUgJlRNKSBjb25zdCBvdmVycmlkZTsKKworICAvLy8gRW1pdCBPYmotQyBnYXJiYWdlIGNvbGxlY3Rpb24gYW5kIGxpbmtlciBvcHRpb25zLgorICB2b2lkIGVtaXRNb2R1bGVNZXRhZGF0YShNQ1N0cmVhbWVyICZTdHJlYW1lciwgTW9kdWxlICZNLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgTUNTZWN0aW9uICpnZXRTdGF0aWNDdG9yU2VjdGlvbih1bnNpZ25lZCBQcmlvcml0eSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNQ1N5bWJvbCAqS2V5U3ltKSBjb25zdCBvdmVycmlkZTsKKyAgTUNTZWN0aW9uICpnZXRTdGF0aWNEdG9yU2VjdGlvbih1bnNpZ25lZCBQcmlvcml0eSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNQ1N5bWJvbCAqS2V5U3ltKSBjb25zdCBvdmVycmlkZTsKKworICB2b2lkIGVtaXRMaW5rZXJGbGFnc0Zvckdsb2JhbChyYXdfb3N0cmVhbSAmT1MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEdsb2JhbFZhbHVlICpHVikgY29uc3Qgb3ZlcnJpZGU7CisKKyAgdm9pZCBlbWl0TGlua2VyRmxhZ3NGb3JVc2VkKHJhd19vc3RyZWFtICZPUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEdsb2JhbFZhbHVlICpHVikgY29uc3Qgb3ZlcnJpZGU7Cit9OworCitjbGFzcyBUYXJnZXRMb3dlcmluZ09iamVjdEZpbGVXYXNtIDogcHVibGljIFRhcmdldExvd2VyaW5nT2JqZWN0RmlsZSB7CisgIG11dGFibGUgdW5zaWduZWQgTmV4dFVuaXF1ZUlEID0gMDsKKworcHVibGljOgorICBUYXJnZXRMb3dlcmluZ09iamVjdEZpbGVXYXNtKCkgPSBkZWZhdWx0OworICB+VGFyZ2V0TG93ZXJpbmdPYmplY3RGaWxlV2FzbSgpIG92ZXJyaWRlID0gZGVmYXVsdDsKKworICBNQ1NlY3Rpb24gKmdldEV4cGxpY2l0U2VjdGlvbkdsb2JhbChjb25zdCBHbG9iYWxPYmplY3QgKkdPLCBTZWN0aW9uS2luZCBLaW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgTUNTZWN0aW9uICpTZWxlY3RTZWN0aW9uRm9yR2xvYmFsKGNvbnN0IEdsb2JhbE9iamVjdCAqR08sIFNlY3Rpb25LaW5kIEtpbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTSkgY29uc3Qgb3ZlcnJpZGU7CisKKyAgYm9vbCBzaG91bGRQdXRKdW1wVGFibGVJbkZ1bmN0aW9uU2VjdGlvbihib29sIFVzZXNMYWJlbERpZmZlcmVuY2UsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRnVuY3Rpb24gJkYpIGNvbnN0IG92ZXJyaWRlOworCisgIHZvaWQgSW5pdGlhbGl6ZVdhc20oKTsKKyAgTUNTZWN0aW9uICpnZXRTdGF0aWNDdG9yU2VjdGlvbih1bnNpZ25lZCBQcmlvcml0eSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNQ1N5bWJvbCAqS2V5U3ltKSBjb25zdCBvdmVycmlkZTsKKyAgTUNTZWN0aW9uICpnZXRTdGF0aWNEdG9yU2VjdGlvbih1bnNpZ25lZCBQcmlvcml0eSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNQ1N5bWJvbCAqS2V5U3ltKSBjb25zdCBvdmVycmlkZTsKKworICBjb25zdCBNQ0V4cHIgKmxvd2VyUmVsYXRpdmVSZWZlcmVuY2UoY29uc3QgR2xvYmFsVmFsdWUgKkxIUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEdsb2JhbFZhbHVlICpSSFMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRNYWNoaW5lICZUTSkgY29uc3Qgb3ZlcnJpZGU7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1RBUkdFVExPV0VSSU5HT0JKRUNURklMRUlNUExfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhcmdldE9wY29kZXMuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9UYXJnZXRPcGNvZGVzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDBkOTU5YwotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9UYXJnZXRPcGNvZGVzLmgKQEAgLTAsMCArMSw0MiBAQAorLy89PT0tLSBsbHZtL0NvZGVHZW4vVGFyZ2V0T3Bjb2Rlcy5oIC0gVGFyZ2V0IEluZGVwIE9wY29kZXMgLS0tLS0qLSBDKysgLSotPT09Ly8KKy8vCisvLyAgICAgICAgICAgICAgICAgICAgIFRoZSBMTFZNIENvbXBpbGVyIEluZnJhc3RydWN0dXJlCisvLworLy8gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBVbml2ZXJzaXR5IG9mIElsbGlub2lzIE9wZW4gU291cmNlCisvLyBMaWNlbnNlLiBTZWUgTElDRU5TRS5UWFQgZm9yIGRldGFpbHMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBUaGlzIGZpbGUgZGVmaW5lcyB0aGUgdGFyZ2V0IGluZGVwZW5kZW50IGluc3RydWN0aW9uIG9wY29kZXMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fVEFSR0VUT1BDT0RFU19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9UQVJHRVRPUENPREVTX0gKKworbmFtZXNwYWNlIGxsdm0geworCisvLy8gSW52YXJpYW50IG9wY29kZXM6IEFsbCBpbnN0cnVjdGlvbiBzZXRzIGhhdmUgdGhlc2UgYXMgdGhlaXIgbG93IG9wY29kZXMuCisvLy8KK25hbWVzcGFjZSBUYXJnZXRPcGNvZGUgeworZW51bSB7CisjZGVmaW5lIEhBTkRMRV9UQVJHRVRfT1BDT0RFKE9QQykgT1BDLAorI2RlZmluZSBIQU5ETEVfVEFSR0VUX09QQ09ERV9NQVJLRVIoSURFTlQsIE9QQykgSURFTlQgPSBPUEMsCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L1RhcmdldE9wY29kZXMuZGVmIgorfTsKK30gLy8gZW5kIG5hbWVzcGFjZSBUYXJnZXRPcGNvZGUKKworLy8vIENoZWNrIHdoZXRoZXIgdGhlIGdpdmVuIE9wY29kZSBpcyBhIGdlbmVyaWMgb3Bjb2RlIHRoYXQgaXMgbm90IHN1cHBvc2VkCisvLy8gdG8gYXBwZWFyIGFmdGVyIElTZWwuCitpbmxpbmUgYm9vbCBpc1ByZUlTZWxHZW5lcmljT3Bjb2RlKHVuc2lnbmVkIE9wY29kZSkgeworICByZXR1cm4gT3Bjb2RlID49IFRhcmdldE9wY29kZTo6UFJFX0lTRUxfR0VORVJJQ19PUENPREVfU1RBUlQgJiYKKyAgICAgICAgIE9wY29kZSA8PSBUYXJnZXRPcGNvZGU6OlBSRV9JU0VMX0dFTkVSSUNfT1BDT0RFX0VORDsKK30KKworLy8vIENoZWNrIHdoZXRoZXIgdGhlIGdpdmVuIE9wY29kZSBpcyBhIHRhcmdldC1zcGVjaWZpYyBvcGNvZGUuCitpbmxpbmUgYm9vbCBpc1RhcmdldFNwZWNpZmljT3Bjb2RlKHVuc2lnbmVkIE9wY29kZSkgeworICByZXR1cm4gT3Bjb2RlID4gVGFyZ2V0T3Bjb2RlOjpQUkVfSVNFTF9HRU5FUklDX09QQ09ERV9FTkQ7Cit9Cit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9UYXJnZXRQYXNzQ29uZmlnLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vVGFyZ2V0UGFzc0NvbmZpZy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU5MThjNTIKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vVGFyZ2V0UGFzc0NvbmZpZy5oCkBAIC0wLDAgKzEsNDMzIEBACisvLz09PS0gVGFyZ2V0UGFzc0NvbmZpZy5oIC0gQ29kZSBHZW5lcmF0aW9uIHBhc3Mgb3B0aW9ucyAtLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vLyBUYXJnZXQtSW5kZXBlbmRlbnQgQ29kZSBHZW5lcmF0b3IgUGFzcyBDb25maWd1cmF0aW9uIE9wdGlvbnMgcGFzcy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9UQVJHRVRQQVNTQ09ORklHX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1RBUkdFVFBBU1NDT05GSUdfSAorCisjaW5jbHVkZSAibGx2bS9QYXNzLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L0NvZGVHZW4uaCIKKyNpbmNsdWRlIDxjYXNzZXJ0PiAKKyNpbmNsdWRlIDxzdHJpbmc+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgTExWTVRhcmdldE1hY2hpbmU7CitzdHJ1Y3QgTWFjaGluZVNjaGVkQ29udGV4dDsKK2NsYXNzIFBhc3NDb25maWdJbXBsOworY2xhc3MgU2NoZWR1bGVEQUdJbnN0cnM7CisKKy8vIFRoZSBvbGQgcGFzcyBtYW5hZ2VyIGluZnJhc3RydWN0dXJlIGlzIGhpZGRlbiBpbiBhIGxlZ2FjeSBuYW1lc3BhY2Ugbm93LgorbmFtZXNwYWNlIGxlZ2FjeSB7CisKK2NsYXNzIFBhc3NNYW5hZ2VyQmFzZTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxlZ2FjeQorCit1c2luZyBsZWdhY3k6OlBhc3NNYW5hZ2VyQmFzZTsKKworLy8vIERpc2NyaW1pbmF0ZWQgdW5pb24gb2YgUGFzcyBJRCB0eXBlcy4KKy8vLworLy8vIFRoZSBQYXNzQ29uZmlnIEFQSSBwcmVmZXJzIGRlYWxpbmcgd2l0aCBJRHMgYmVjYXVzZSB0aGV5IGFyZSBzYWZlciBhbmQgbW9yZQorLy8vIGVmZmljaWVudC4gSURzIGRlY291cGxlIGNvbmZpZ3VyYXRpb24gZnJvbSBpbnN0YW50aWF0aW9uLiBUaGlzIHdheSwgd2hlbiBhCisvLy8gcGFzcyBpcyBvdmVycmlkZW4sIGl0IGlzbid0IHVubmVjZXNzYXJpbHkgaW5zdGFudGlhdGVkLiBJdCBpcyBhbHNvIHVuc2FmZSB0bworLy8vIHJlZmVyIHRvIGEgUGFzcyBwb2ludGVyIGFmdGVyIGFkZGluZyBpdCB0byBhIHBhc3MgbWFuYWdlciwgd2hpY2ggZGVsZXRlcworLy8vIHJlZHVuZGFudCBwYXNzIGluc3RhbmNlcy4KKy8vLworLy8vIEhvd2V2ZXIsIGl0IGlzIGNvbnZpZW50IHRvIGRpcmVjdGx5IGluc3RhbnRpYXRlIHRhcmdldCBwYXNzZXMgd2l0aAorLy8vIG5vbi1kZWZhdWx0IGN0b3JzLiBUaGVzZSBvZnRlbiBkb24ndCBoYXZlIGEgcmVnaXN0ZXJlZCBQYXNzSW5mby4gUmF0aGVyIHRoYW4KKy8vLyBmb3JjZSBhbGwgdGFyZ2V0IHBhc3NlcyB0byBpbXBsZW1lbnQgdGhlIHBhc3MgcmVnaXN0cnkgYm9pbGVycGxhdGUsIGFsbG93CisvLy8gdGhlIFBhc3NDb25maWcgQVBJIHRvIGhhbmRsZSBlaXRoZXIgdHlwZS4KKy8vLworLy8vIEFuYWx5c2lzSUQgaXMgc2FkbHkgY2hhciosIHNvIFBvaW50ZXJJbnRQYWlyIHdvbid0IHdvcmsuCitjbGFzcyBJZGVudGlmeWluZ1Bhc3NQdHIgeworICB1bmlvbiB7CisgICAgQW5hbHlzaXNJRCBJRDsKKyAgICBQYXNzICpQOworICB9OworICBib29sIElzSW5zdGFuY2UgPSBmYWxzZTsKKworcHVibGljOgorICBJZGVudGlmeWluZ1Bhc3NQdHIoKSA6IFAobnVsbHB0cikge30KKyAgSWRlbnRpZnlpbmdQYXNzUHRyKEFuYWx5c2lzSUQgSURQdHIpIDogSUQoSURQdHIpIHt9CisgIElkZW50aWZ5aW5nUGFzc1B0cihQYXNzICpJbnN0YW5jZVB0cikgOiBQKEluc3RhbmNlUHRyKSwgSXNJbnN0YW5jZSh0cnVlKSB7fQorCisgIGJvb2wgaXNWYWxpZCgpIGNvbnN0IHsgcmV0dXJuIFA7IH0KKyAgYm9vbCBpc0luc3RhbmNlKCkgY29uc3QgeyByZXR1cm4gSXNJbnN0YW5jZTsgfQorCisgIEFuYWx5c2lzSUQgZ2V0SUQoKSBjb25zdCB7CisgICAgYXNzZXJ0KCFJc0luc3RhbmNlICYmICJOb3QgYSBQYXNzIElEIik7CisgICAgcmV0dXJuIElEOworICB9CisKKyAgUGFzcyAqZ2V0SW5zdGFuY2UoKSBjb25zdCB7CisgICAgYXNzZXJ0KElzSW5zdGFuY2UgJiYgIk5vdCBhIFBhc3MgSW5zdGFuY2UiKTsKKyAgICByZXR1cm4gUDsKKyAgfQorfTsKKwordGVtcGxhdGUgPD4gc3RydWN0IGlzUG9kTGlrZTxJZGVudGlmeWluZ1Bhc3NQdHI+IHsKKyAgc3RhdGljIGNvbnN0IGJvb2wgdmFsdWUgPSB0cnVlOworfTsKKworLy8vIFRhcmdldC1JbmRlcGVuZGVudCBDb2RlIEdlbmVyYXRvciBQYXNzIENvbmZpZ3VyYXRpb24gT3B0aW9ucy4KKy8vLworLy8vIFRoaXMgaXMgYW4gSW1tdXRhYmxlUGFzcyBzb2xlbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGV4cG9zaW5nIENvZGVHZW4gb3B0aW9ucworLy8vIHRvIHRoZSBpbnRlcm5hbHMgb2Ygb3RoZXIgQ29kZUdlbiBwYXNzZXMuCitjbGFzcyBUYXJnZXRQYXNzQ29uZmlnIDogcHVibGljIEltbXV0YWJsZVBhc3MgeworcHJpdmF0ZToKKyAgUGFzc01hbmFnZXJCYXNlICpQTSA9IG51bGxwdHI7CisgIEFuYWx5c2lzSUQgU3RhcnRCZWZvcmUgPSBudWxscHRyOworICBBbmFseXNpc0lEIFN0YXJ0QWZ0ZXIgPSBudWxscHRyOworICBBbmFseXNpc0lEIFN0b3BCZWZvcmUgPSBudWxscHRyOworICBBbmFseXNpc0lEIFN0b3BBZnRlciA9IG51bGxwdHI7CisgIGJvb2wgU3RhcnRlZCA9IHRydWU7CisgIGJvb2wgU3RvcHBlZCA9IGZhbHNlOworICBib29sIEFkZGluZ01hY2hpbmVQYXNzZXMgPSBmYWxzZTsKKworICAvLy8gU2V0IHRoZSBTdGFydEFmdGVyLCBTdGFydEJlZm9yZSBhbmQgU3RvcEFmdGVyIHBhc3NlcyB0byBhbGxvdyBydW5uaW5nIG9ubHkKKyAgLy8vIGEgcG9ydGlvbiBvZiB0aGUgbm9ybWFsIGNvZGUtZ2VuIHBhc3Mgc2VxdWVuY2UuCisgIC8vLworICAvLy8gSWYgdGhlIFN0YXJ0QWZ0ZXIgYW5kIFN0YXJ0QmVmb3JlIHBhc3MgSUQgaXMgemVybywgdGhlbiBjb21waWxhdGlvbiB3aWxsCisgIC8vLyBiZWdpbiBhdCB0aGUgbm9ybWFsIHBvaW50OyBvdGhlcndpc2UsIGNsZWFyIHRoZSBTdGFydGVkIGZsYWcgdG8gaW5kaWNhdGUKKyAgLy8vIHRoYXQgcGFzc2VzIHNob3VsZCBub3QgYmUgYWRkZWQgdW50aWwgdGhlIHN0YXJ0aW5nIHBhc3MgaXMgc2Vlbi4gIElmIHRoZQorICAvLy8gU3RvcCBwYXNzIElEIGlzIHplcm8sIHRoZW4gY29tcGlsYXRpb24gd2lsbCBjb250aW51ZSB0byB0aGUgZW5kLgorICAvLy8KKyAgLy8vIFRoaXMgZnVuY3Rpb24gZXhwZWN0cyB0aGF0IGF0IGxlYXN0IG9uZSBvZiB0aGUgU3RhcnRBZnRlciBvciB0aGUKKyAgLy8vIFN0YXJ0QmVmb3JlIHBhc3MgSURzIGlzIG51bGwuCisgIHZvaWQgc2V0U3RhcnRTdG9wUGFzc2VzKCk7CisKK3Byb3RlY3RlZDoKKyAgTExWTVRhcmdldE1hY2hpbmUgKlRNOworICBQYXNzQ29uZmlnSW1wbCAqSW1wbCA9IG51bGxwdHI7IC8vIEludGVybmFsIGRhdGEgc3RydWN0dXJlcworICBib29sIEluaXRpYWxpemVkID0gZmFsc2U7IC8vIEZsYWdnZWQgYWZ0ZXIgYWxsIHBhc3NlcyBhcmUgY29uZmlndXJlZC4KKworICAvLyBUYXJnZXQgUGFzcyBPcHRpb25zCisgIC8vIFRhcmdldHMgcHJvdmlkZSBhIGRlZmF1bHQgc2V0dGluZywgdXNlciBmbGFncyBvdmVycmlkZS4KKyAgYm9vbCBEaXNhYmxlVmVyaWZ5ID0gZmFsc2U7CisKKyAgLy8vIERlZmF1bHQgc2V0dGluZyBmb3IgLWVuYWJsZS10YWlsLW1lcmdlIG9uIHRoaXMgdGFyZ2V0LgorICBib29sIEVuYWJsZVRhaWxNZXJnZSA9IHRydWU7CisKKyAgLy8vIFJlcXVpcmUgcHJvY2Vzc2luZyBvZiBmdW5jdGlvbnMgc3VjaCB0aGF0IGNhbGxlZXMgYXJlIGdlbmVyYXRlZCBiZWZvcmUKKyAgLy8vIGNhbGxlcnMuCisgIGJvb2wgUmVxdWlyZUNvZGVHZW5TQ0NPcmRlciA9IGZhbHNlOworCisgIC8vLyBBZGQgdGhlIGFjdHVhbCBpbnN0cnVjdGlvbiBzZWxlY3Rpb24gcGFzc2VzLiBUaGlzIGRvZXMgbm90IGluY2x1ZGUKKyAgLy8vIHByZXBhcmF0aW9uIHBhc3NlcyBvbiBJUi4KKyAgYm9vbCBhZGRDb3JlSVNlbFBhc3NlcygpOworCitwdWJsaWM6CisgIFRhcmdldFBhc3NDb25maWcoTExWTVRhcmdldE1hY2hpbmUgJlRNLCBQYXNzTWFuYWdlckJhc2UgJnBtKTsKKyAgLy8gRHVtbXkgY29uc3RydWN0b3IuCisgIFRhcmdldFBhc3NDb25maWcoKTsKKworICB+VGFyZ2V0UGFzc0NvbmZpZygpIG92ZXJyaWRlOworCisgIHN0YXRpYyBjaGFyIElEOworCisgIC8vLyBHZXQgdGhlIHJpZ2h0IHR5cGUgb2YgVGFyZ2V0TWFjaGluZSBmb3IgdGhpcyB0YXJnZXQuCisgIHRlbXBsYXRlPHR5cGVuYW1lIFRNQz4gVE1DICZnZXRUTSgpIGNvbnN0IHsKKyAgICByZXR1cm4gKnN0YXRpY19jYXN0PFRNQyo+KFRNKTsKKyAgfQorCisgIC8vCisgIHZvaWQgc2V0SW5pdGlhbGl6ZWQoKSB7IEluaXRpYWxpemVkID0gdHJ1ZTsgfQorCisgIENvZGVHZW5PcHQ6OkxldmVsIGdldE9wdExldmVsKCkgY29uc3Q7CisKKyAgLy8vIERlc2NyaWJlIHRoZSBzdGF0dXMgb2YgdGhlIGNvZGVnZW4KKyAgLy8vIHBpcGVsaW5lIHNldCBieSB0aGlzIHRhcmdldCBwYXNzIGNvbmZpZy4KKyAgLy8vIEhhdmluZyBhIGxpbWl0ZWQgY29kZWdlbiBwaXBlbGluZSBtZWFucyB0aGF0IG9wdGlvbnMKKyAgLy8vIGhhdmUgYmVlbiB1c2VkIHRvIHJlc3RyaWN0IHdoYXQgY29kZWdlbiBpcyBkb2luZy4KKyAgLy8vIEluIHBhcnRpY3VsYXIsIHRoYXQgbWVhbnMgdGhhdCBjb2RlZ2VuIHdvbid0IGVtaXQKKyAgLy8vIGFzc2VtYmx5IGNvZGUuCisgIGJvb2wgaGFzTGltaXRlZENvZGVHZW5QaXBlbGluZSgpIGNvbnN0OworCisgIC8vLyBJZiBoYXNMaW1pdGVkQ29kZUdlblBpcGVsaW5lIGlzIHRydWUsIHRoaXMgbWV0aG9kCisgIC8vLyByZXR1cm5zIGEgc3RyaW5nIHdpdGggdGhlIG5hbWUgb2YgdGhlIG9wdGlvbnMsIHNlcGFyYXRlZAorICAvLy8gYnkgXHAgU2VwYXJhdG9yIHRoYXQgY2F1c2VkIHRoaXMgcGlwZWxpbmUgdG8gYmUgbGltaXRlZC4KKyAgc3RkOjpzdHJpbmcKKyAgZ2V0TGltaXRlZENvZGVHZW5QaXBlbGluZVJlYXNvbihjb25zdCBjaGFyICpTZXBhcmF0b3IgPSAiLyIpIGNvbnN0OworCisgIC8vLyBDaGVjayBpZiB0aGUgY29kZWdlbiBwaXBlbGluZSBpcyBsaW1pdGVkIGluIHN1Y2ggYSB3YXkgdGhhdCBpdAorICAvLy8gd29uJ3QgYmUgY29tcGxldGUuIFdoZW4gdGhlIGNvZGVnZW4gcGlwZWxpbmUgaXMgbm90IGNvbXBsZXRlLAorICAvLy8gdGhpcyBtZWFucyBpdCBtYXkgbm90IGJlIHBvc3NpYmxlIHRvIGdlbmVyYXRlIGFzc2VtYmx5IGZyb20gaXQuCisgIGJvb2wgd2lsbENvbXBsZXRlQ29kZUdlblBpcGVsaW5lKCkgY29uc3QgeworICAgIHJldHVybiAhaGFzTGltaXRlZENvZGVHZW5QaXBlbGluZSgpIHx8ICghU3RvcEFmdGVyICYmICFTdG9wQmVmb3JlKTsKKyAgfQorCisgIHZvaWQgc2V0RGlzYWJsZVZlcmlmeShib29sIERpc2FibGUpIHsgc2V0T3B0KERpc2FibGVWZXJpZnksIERpc2FibGUpOyB9CisKKyAgYm9vbCBnZXRFbmFibGVUYWlsTWVyZ2UoKSBjb25zdCB7IHJldHVybiBFbmFibGVUYWlsTWVyZ2U7IH0KKyAgdm9pZCBzZXRFbmFibGVUYWlsTWVyZ2UoYm9vbCBFbmFibGUpIHsgc2V0T3B0KEVuYWJsZVRhaWxNZXJnZSwgRW5hYmxlKTsgfQorCisgIGJvb2wgcmVxdWlyZXNDb2RlR2VuU0NDT3JkZXIoKSBjb25zdCB7IHJldHVybiBSZXF1aXJlQ29kZUdlblNDQ09yZGVyOyB9CisgIHZvaWQgc2V0UmVxdWlyZXNDb2RlR2VuU0NDT3JkZXIoYm9vbCBFbmFibGUgPSB0cnVlKSB7CisgICAgc2V0T3B0KFJlcXVpcmVDb2RlR2VuU0NDT3JkZXIsIEVuYWJsZSk7CisgIH0KKworICAvLy8gQWxsb3cgdGhlIHRhcmdldCB0byBvdmVycmlkZSBhIHNwZWNpZmljIHBhc3Mgd2l0aG91dCBvdmVycmlkaW5nIHRoZSBwYXNzCisgIC8vLyBwaXBlbGluZS4gV2hlbiBwYXNzZXMgYXJlIGFkZGVkIHRvIHRoZSBzdGFuZGFyZCBwaXBlbGluZSBhdCB0aGUKKyAgLy8vIHBvaW50IHdoZXJlIFN0YW5kYXJkSUQgaXMgZXhwZWN0ZWQsIGFkZCBUYXJnZXRJRCBpbiBpdHMgcGxhY2UuCisgIHZvaWQgc3Vic3RpdHV0ZVBhc3MoQW5hbHlzaXNJRCBTdGFuZGFyZElELCBJZGVudGlmeWluZ1Bhc3NQdHIgVGFyZ2V0SUQpOworCisgIC8vLyBJbnNlcnQgSW5zZXJ0ZWRQYXNzSUQgcGFzcyBhZnRlciBUYXJnZXRQYXNzSUQgcGFzcy4KKyAgdm9pZCBpbnNlcnRQYXNzKEFuYWx5c2lzSUQgVGFyZ2V0UGFzc0lELCBJZGVudGlmeWluZ1Bhc3NQdHIgSW5zZXJ0ZWRQYXNzSUQsCisgICAgICAgICAgICAgICAgICBib29sIFZlcmlmeUFmdGVyID0gdHJ1ZSwgYm9vbCBQcmludEFmdGVyID0gdHJ1ZSk7CisKKyAgLy8vIEFsbG93IHRoZSB0YXJnZXQgdG8gZW5hYmxlIGEgc3BlY2lmaWMgc3RhbmRhcmQgcGFzcyBieSBkZWZhdWx0LgorICB2b2lkIGVuYWJsZVBhc3MoQW5hbHlzaXNJRCBQYXNzSUQpIHsgc3Vic3RpdHV0ZVBhc3MoUGFzc0lELCBQYXNzSUQpOyB9CisKKyAgLy8vIEFsbG93IHRoZSB0YXJnZXQgdG8gZGlzYWJsZSBhIHNwZWNpZmljIHN0YW5kYXJkIHBhc3MgYnkgZGVmYXVsdC4KKyAgdm9pZCBkaXNhYmxlUGFzcyhBbmFseXNpc0lEIFBhc3NJRCkgeworICAgIHN1YnN0aXR1dGVQYXNzKFBhc3NJRCwgSWRlbnRpZnlpbmdQYXNzUHRyKCkpOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgcGFzcyBzdWJzdGl0dXRlZCBmb3IgU3RhbmRhcmRJRCBieSB0aGUgdGFyZ2V0LgorICAvLy8gSWYgbm8gc3Vic3RpdHV0aW9uIGV4aXN0cywgcmV0dXJuIFN0YW5kYXJkSUQuCisgIElkZW50aWZ5aW5nUGFzc1B0ciBnZXRQYXNzU3Vic3RpdHV0aW9uKEFuYWx5c2lzSUQgU3RhbmRhcmRJRCkgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBwYXNzIGhhcyBiZWVuIHN1YnN0aXR1dGVkIGJ5IHRoZSB0YXJnZXQgb3IKKyAgLy8vIG92ZXJyaWRkZW4gb24gdGhlIGNvbW1hbmQgbGluZS4KKyAgYm9vbCBpc1Bhc3NTdWJzdGl0dXRlZE9yT3ZlcnJpZGRlbihBbmFseXNpc0lEIElEKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIG9wdGltaXplZCByZWdhbGxvYyBwaXBlbGluZSBpcyBlbmFibGVkLgorICBib29sIGdldE9wdGltaXplUmVnQWxsb2MoKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIGRlZmF1bHQgZ2xvYmFsIHJlZ2lzdGVyIGFsbG9jYXRvciBpcyBpbiB1c2UgYW5kCisgIC8vLyBoYXMgbm90IGJlIG92ZXJyaWRlbiBvbiB0aGUgY29tbWFuZCBsaW5lIHdpdGggJy1yZWdhbGxvYz0uLi4nCisgIGJvb2wgdXNpbmdEZWZhdWx0UmVnQWxsb2MoKSBjb25zdDsKKworICAvLy8gSGlnaCBsZXZlbCBmdW5jdGlvbiB0aGF0IGFkZHMgYWxsIHBhc3NlcyBuZWNlc3NhcnkgdG8gZ28gZnJvbSBsbHZtIElSCisgIC8vLyByZXByZXNlbnRhdGlvbiB0byB0aGUgTUkgcmVwcmVzZW50YXRpb24uCisgIC8vLyBBZGRzIElSIGJhc2VkIGxvd2VyaW5nIGFuZCB0YXJnZXQgc3BlY2lmaWMgb3B0aW1pemF0aW9uIHBhc3NlcyBhbmQgZmluYWxseQorICAvLy8gdGhlIGNvcmUgaW5zdHJ1Y3Rpb24gc2VsZWN0aW9uIHBhc3Nlcy4KKyAgLy8vIFxyZXR1cm5zIHRydWUgaWYgYW4gZXJyb3Igb2NjdXJyZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgYm9vbCBhZGRJU2VsUGFzc2VzKCk7CisKKyAgLy8vIEFkZCBjb21tb24gdGFyZ2V0IGNvbmZpZ3VyYWJsZSBwYXNzZXMgdGhhdCBwZXJmb3JtIExMVk0gSVIgdG8gSVIKKyAgLy8vIHRyYW5zZm9ybXMgZm9sbG93aW5nIG1hY2hpbmUgaW5kZXBlbmRlbnQgb3B0aW1pemF0aW9uLgorICB2aXJ0dWFsIHZvaWQgYWRkSVJQYXNzZXMoKTsKKworICAvLy8gQWRkIHBhc3NlcyB0byBsb3dlciBleGNlcHRpb24gaGFuZGxpbmcgZm9yIHRoZSBjb2RlIGdlbmVyYXRvci4KKyAgdm9pZCBhZGRQYXNzZXNUb0hhbmRsZUV4Y2VwdGlvbnMoKTsKKworICAvLy8gQWRkIHBhc3MgdG8gcHJlcGFyZSB0aGUgTExWTSBJUiBmb3IgY29kZSBnZW5lcmF0aW9uLiBUaGlzIHNob3VsZCBiZSBkb25lCisgIC8vLyBiZWZvcmUgZXhjZXB0aW9uIGhhbmRsaW5nIHByZXBhcmF0aW9uIHBhc3Nlcy4KKyAgdmlydHVhbCB2b2lkIGFkZENvZGVHZW5QcmVwYXJlKCk7CisKKyAgLy8vIEFkZCBjb21tb24gcGFzc2VzIHRoYXQgcGVyZm9ybSBMTFZNIElSIHRvIElSIHRyYW5zZm9ybXMgaW4gcHJlcGFyYXRpb24gZm9yCisgIC8vLyBpbnN0cnVjdGlvbiBzZWxlY3Rpb24uCisgIHZpcnR1YWwgdm9pZCBhZGRJU2VsUHJlcGFyZSgpOworCisgIC8vLyBhZGRJbnN0U2VsZWN0b3IgLSBUaGlzIG1ldGhvZCBzaG91bGQgaW5zdGFsbCBhbiBpbnN0cnVjdGlvbiBzZWxlY3RvciBwYXNzLAorICAvLy8gd2hpY2ggY29udmVydHMgZnJvbSBMTFZNIGNvZGUgdG8gbWFjaGluZSBpbnN0cnVjdGlvbnMuCisgIHZpcnR1YWwgYm9vbCBhZGRJbnN0U2VsZWN0b3IoKSB7CisgICAgcmV0dXJuIHRydWU7CisgIH0KKworICAvLy8gVGhpcyBtZXRob2Qgc2hvdWxkIGluc3RhbGwgYW4gSVIgdHJhbnNsYXRvciBwYXNzLCB3aGljaCBjb252ZXJ0cyBmcm9tCisgIC8vLyBMTFZNIGNvZGUgdG8gbWFjaGluZSBpbnN0cnVjdGlvbnMgd2l0aCBwb3NzaWJseSBnZW5lcmljIG9wY29kZXMuCisgIHZpcnR1YWwgYm9vbCBhZGRJUlRyYW5zbGF0b3IoKSB7IHJldHVybiB0cnVlOyB9CisKKyAgLy8vIFRoaXMgbWV0aG9kIG1heSBiZSBpbXBsZW1lbnRlZCBieSB0YXJnZXRzIHRoYXQgd2FudCB0byBydW4gcGFzc2VzCisgIC8vLyBpbW1lZGlhdGVseSBiZWZvcmUgbGVnYWxpemF0aW9uLgorICB2aXJ0dWFsIHZvaWQgYWRkUHJlTGVnYWxpemVNYWNoaW5lSVIoKSB7fQorCisgIC8vLyBUaGlzIG1ldGhvZCBzaG91bGQgaW5zdGFsbCBhIGxlZ2FsaXplIHBhc3MsIHdoaWNoIGNvbnZlcnRzIHRoZSBpbnN0cnVjdGlvbgorICAvLy8gc2VxdWVuY2UgaW50byBvbmUgdGhhdCBjYW4gYmUgc2VsZWN0ZWQgYnkgdGhlIHRhcmdldC4KKyAgdmlydHVhbCBib29sIGFkZExlZ2FsaXplTWFjaGluZUlSKCkgeyByZXR1cm4gdHJ1ZTsgfQorCisgIC8vLyBUaGlzIG1ldGhvZCBtYXkgYmUgaW1wbGVtZW50ZWQgYnkgdGFyZ2V0cyB0aGF0IHdhbnQgdG8gcnVuIHBhc3NlcworICAvLy8gaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSByZWdpc3RlciBiYW5rIHNlbGVjdGlvbi4KKyAgdmlydHVhbCB2b2lkIGFkZFByZVJlZ0JhbmtTZWxlY3QoKSB7fQorCisgIC8vLyBUaGlzIG1ldGhvZCBzaG91bGQgaW5zdGFsbCBhIHJlZ2lzdGVyIGJhbmsgc2VsZWN0b3IgcGFzcywgd2hpY2gKKyAgLy8vIGFzc2lnbnMgcmVnaXN0ZXIgYmFua3MgdG8gdmlydHVhbCByZWdpc3RlcnMgd2l0aG91dCBhIHJlZ2lzdGVyCisgIC8vLyBjbGFzcyBvciByZWdpc3RlciBiYW5rcy4KKyAgdmlydHVhbCBib29sIGFkZFJlZ0JhbmtTZWxlY3QoKSB7IHJldHVybiB0cnVlOyB9CisKKyAgLy8vIFRoaXMgbWV0aG9kIG1heSBiZSBpbXBsZW1lbnRlZCBieSB0YXJnZXRzIHRoYXQgd2FudCB0byBydW4gcGFzc2VzCisgIC8vLyBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIChnbG9iYWwpIGluc3RydWN0aW9uIHNlbGVjdGlvbi4KKyAgdmlydHVhbCB2b2lkIGFkZFByZUdsb2JhbEluc3RydWN0aW9uU2VsZWN0KCkge30KKworICAvLy8gVGhpcyBtZXRob2Qgc2hvdWxkIGluc3RhbGwgYSAoZ2xvYmFsKSBpbnN0cnVjdGlvbiBzZWxlY3RvciBwYXNzLCB3aGljaAorICAvLy8gY29udmVydHMgcG9zc2libHkgZ2VuZXJpYyBpbnN0cnVjdGlvbnMgdG8gZnVsbHkgdGFyZ2V0LXNwZWNpZmljCisgIC8vLyBpbnN0cnVjdGlvbnMsIHRoZXJlYnkgY29uc3RyYWluaW5nIGFsbCBnZW5lcmljIHZpcnR1YWwgcmVnaXN0ZXJzIHRvCisgIC8vLyByZWdpc3RlciBjbGFzc2VzLgorICB2aXJ0dWFsIGJvb2wgYWRkR2xvYmFsSW5zdHJ1Y3Rpb25TZWxlY3QoKSB7IHJldHVybiB0cnVlOyB9CisKKyAgLy8vIEFkZCB0aGUgY29tcGxldGUsIHN0YW5kYXJkIHNldCBvZiBMTFZNIENvZGVHZW4gcGFzc2VzLgorICAvLy8gRnVsbHkgZGV2ZWxvcGVkIHRhcmdldHMgd2lsbCBub3QgZ2VuZXJhbGx5IG92ZXJyaWRlIHRoaXMuCisgIHZpcnR1YWwgdm9pZCBhZGRNYWNoaW5lUGFzc2VzKCk7CisKKyAgLy8vIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiBTY2hlZHVsZURBR0luc3RycyB0byBiZSBydW4gd2l0aGluIHRoZSBzdGFuZGFyZAorICAvLy8gTWFjaGluZVNjaGVkdWxlciBwYXNzIGZvciB0aGlzIGZ1bmN0aW9uIGFuZCB0YXJnZXQgYXQgdGhlIGN1cnJlbnQKKyAgLy8vIG9wdGltaXphdGlvbiBsZXZlbC4KKyAgLy8vCisgIC8vLyBUaGlzIGNhbiBhbHNvIGJlIHVzZWQgdG8gcGx1ZyBhIG5ldyBNYWNoaW5lU2NoZWRTdHJhdGVneSBpbnRvIGFuIGluc3RhbmNlCisgIC8vLyBvZiB0aGUgc3RhbmRhcmQgU2NoZWR1bGVEQUdNSToKKyAgLy8vICAgcmV0dXJuIG5ldyBTY2hlZHVsZURBR01JKEMsIG1ha2VfdW5pcXVlPE15U3RyYXRlZ3k+KEMpLCAvKlJlbW92ZUtpbGxGbGFncz0qL2ZhbHNlKQorICAvLy8KKyAgLy8vIFJldHVybiBOVUxMIHRvIHNlbGVjdCB0aGUgZGVmYXVsdCAoZ2VuZXJpYykgbWFjaGluZSBzY2hlZHVsZXIuCisgIHZpcnR1YWwgU2NoZWR1bGVEQUdJbnN0cnMgKgorICBjcmVhdGVNYWNoaW5lU2NoZWR1bGVyKE1hY2hpbmVTY2hlZENvbnRleHQgKkMpIGNvbnN0IHsKKyAgICByZXR1cm4gbnVsbHB0cjsKKyAgfQorCisgIC8vLyBTaW1pbGFyIHRvIGNyZWF0ZU1hY2hpbmVTY2hlZHVsZXIgYnV0IHVzZWQgd2hlbiBwb3N0UkEgbWFjaGluZSBzY2hlZHVsaW5nCisgIC8vLyBpcyBlbmFibGVkLgorICB2aXJ0dWFsIFNjaGVkdWxlREFHSW5zdHJzICoKKyAgY3JlYXRlUG9zdE1hY2hpbmVTY2hlZHVsZXIoTWFjaGluZVNjaGVkQ29udGV4dCAqQykgY29uc3QgeworICAgIHJldHVybiBudWxscHRyOworICB9CisKKyAgLy8vIHByaW50QW5kVmVyaWZ5IC0gQWRkIGEgcGFzcyB0byBkdW1wIHRoZW4gdmVyaWZ5IHRoZSBtYWNoaW5lIGZ1bmN0aW9uLCBpZgorICAvLy8gdGhvc2Ugc3RlcHMgYXJlIGVuYWJsZWQuCisgIHZvaWQgcHJpbnRBbmRWZXJpZnkoY29uc3Qgc3RkOjpzdHJpbmcgJkJhbm5lcik7CisKKyAgLy8vIEFkZCBhIHBhc3MgdG8gcHJpbnQgdGhlIG1hY2hpbmUgZnVuY3Rpb24gaWYgcHJpbnRpbmcgaXMgZW5hYmxlZC4KKyAgdm9pZCBhZGRQcmludFBhc3MoY29uc3Qgc3RkOjpzdHJpbmcgJkJhbm5lcik7CisKKyAgLy8vIEFkZCBhIHBhc3MgdG8gcGVyZm9ybSBiYXNpYyB2ZXJpZmljYXRpb24gb2YgdGhlIG1hY2hpbmUgZnVuY3Rpb24gaWYKKyAgLy8vIHZlcmlmaWNhdGlvbiBpcyBlbmFibGVkLgorICB2b2lkIGFkZFZlcmlmeVBhc3MoY29uc3Qgc3RkOjpzdHJpbmcgJkJhbm5lcik7CisKKyAgLy8vIENoZWNrIHdoZXRoZXIgb3Igbm90IEdsb2JhbElTZWwgc2hvdWxkIGFib3J0IG9uIGVycm9yLgorICAvLy8gV2hlbiB0aGlzIGlzIGRpc2FibGVkLCBHbG9iYWxJU2VsIHdpbGwgZmFsbCBiYWNrIG9uIFNESVNlbCBpbnN0ZWFkIG9mCisgIC8vLyBlcnJvcmluZyBvdXQuCisgIGJvb2wgaXNHbG9iYWxJU2VsQWJvcnRFbmFibGVkKCkgY29uc3Q7CisKKyAgLy8vIENoZWNrIHdoZXRoZXIgb3Igbm90IGEgZGlhZ25vc3RpYyBzaG91bGQgYmUgZW1pdHRlZCB3aGVuIEdsb2JhbElTZWwKKyAgLy8vIHVzZXMgdGhlIGZhbGxiYWNrIHBhdGguIEluIG90aGVyIHdvcmRzLCBpdCB3aWxsIGVtaXQgYSBkaWFnbm9zdGljCisgIC8vLyB3aGVuIEdsb2JhbElTZWwgZmFpbGVkIGFuZCBpc0dsb2JhbElTZWxBYm9ydEVuYWJsZWQgaXMgZmFsc2UuCisgIHZpcnR1YWwgYm9vbCByZXBvcnREaWFnbm9zdGljV2hlbkdsb2JhbElTZWxGYWxsYmFjaygpIGNvbnN0OworCitwcm90ZWN0ZWQ6CisgIC8vIEhlbHBlciB0byB2ZXJpZnkgdGhlIGFuYWx5c2lzIGlzIHJlYWxseSBpbW11dGFibGUuCisgIHZvaWQgc2V0T3B0KGJvb2wgJk9wdCwgYm9vbCBWYWwpOworCisgIC8vLyBNZXRob2RzIHdpdGggdHJpdmlhbCBpbmxpbmUgcmV0dXJucyBhcmUgY29udmVuaWVudCBwb2ludHMgaW4gdGhlIGNvbW1vbgorICAvLy8gY29kZWdlbiBwYXNzIHBpcGVsaW5lIHdoZXJlIHRhcmdldHMgbWF5IGluc2VydCBwYXNzZXMuIE1ldGhvZHMgd2l0aAorICAvLy8gb3V0LW9mLWxpbmUgc3RhbmRhcmQgaW1wbGVtZW50YXRpb25zIGFyZSBtYWpvciBDb2RlR2VuIHN0YWdlcyBjYWxsZWQgYnkKKyAgLy8vIGFkZE1hY2hpbmVQYXNzZXMuIFNvbWUgdGFyZ2V0cyBtYXkgb3ZlcnJpZGUgbWFqb3Igc3RhZ2VzIHdoZW4gaW5zZXJ0aW5nCisgIC8vLyBwYXNzZXMgaXMgaW5zdWZmaWNpZW50LCBidXQgbWFpbnRhaW5pbmcgb3ZlcnJpZGVuIHN0YWdlcyBpcyBtb3JlIHdvcmsuCisgIC8vLworCisgIC8vLyBhZGRQcmVJU2VsUGFzc2VzIC0gVGhpcyBtZXRob2Qgc2hvdWxkIGFkZCBhbnkgImxhc3QgbWludXRlIiBMTFZNLT5MTFZNCisgIC8vLyBwYXNzZXMgKHdoaWNoIGFyZSBydW4ganVzdCBiZWZvcmUgaW5zdHJ1Y3Rpb24gc2VsZWN0b3IpLgorICB2aXJ0dWFsIGJvb2wgYWRkUHJlSVNlbCgpIHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vLyBhZGRNYWNoaW5lU1NBT3B0aW1pemF0aW9uIC0gQWRkIHN0YW5kYXJkIHBhc3NlcyB0aGF0IG9wdGltaXplIG1hY2hpbmUKKyAgLy8vIGluc3RydWN0aW9ucyBpbiBTU0EgZm9ybS4KKyAgdmlydHVhbCB2b2lkIGFkZE1hY2hpbmVTU0FPcHRpbWl6YXRpb24oKTsKKworICAvLy8gQWRkIHBhc3NlcyB0aGF0IG9wdGltaXplIGluc3RydWN0aW9uIGxldmVsIHBhcmFsbGVsaXNtIGZvciBvdXQtb2Ytb3JkZXIKKyAgLy8vIHRhcmdldHMuIFRoZXNlIHBhc3NlcyBhcmUgcnVuIHdoaWxlIHRoZSBtYWNoaW5lIGNvZGUgaXMgc3RpbGwgaW4gU1NBCisgIC8vLyBmb3JtLCBzbyB0aGV5IGNhbiB1c2UgTWFjaGluZVRyYWNlTWV0cmljcyB0byBjb250cm9sIHRoZWlyIGhldXJpc3RpY3MuCisgIC8vLworICAvLy8gQWxsIHBhc3NlcyBhZGRlZCBoZXJlIHNob3VsZCBwcmVzZXJ2ZSB0aGUgTWFjaGluZURvbWluYXRvclRyZWUsCisgIC8vLyBNYWNoaW5lTG9vcEluZm8sIGFuZCBNYWNoaW5lVHJhY2VNZXRyaWNzIGFuYWx5c2VzLgorICB2aXJ0dWFsIGJvb2wgYWRkSUxQT3B0cygpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gVGhpcyBtZXRob2QgbWF5IGJlIGltcGxlbWVudGVkIGJ5IHRhcmdldHMgdGhhdCB3YW50IHRvIHJ1biBwYXNzZXMKKyAgLy8vIGltbWVkaWF0ZWx5IGJlZm9yZSByZWdpc3RlciBhbGxvY2F0aW9uLgorICB2aXJ0dWFsIHZvaWQgYWRkUHJlUmVnQWxsb2MoKSB7IH0KKworICAvLy8gY3JlYXRlVGFyZ2V0UmVnaXN0ZXJBbGxvY2F0b3IgLSBDcmVhdGUgdGhlIHJlZ2lzdGVyIGFsbG9jYXRvciBwYXNzIGZvcgorICAvLy8gdGhpcyB0YXJnZXQgYXQgdGhlIGN1cnJlbnQgb3B0aW1pemF0aW9uIGxldmVsLgorICB2aXJ0dWFsIEZ1bmN0aW9uUGFzcyAqY3JlYXRlVGFyZ2V0UmVnaXN0ZXJBbGxvY2F0b3IoYm9vbCBPcHRpbWl6ZWQpOworCisgIC8vLyBhZGRGYXN0UmVnQWxsb2MgLSBBZGQgdGhlIG1pbmltdW0gc2V0IG9mIHRhcmdldC1pbmRlcGVuZGVudCBwYXNzZXMgdGhhdAorICAvLy8gYXJlIHJlcXVpcmVkIGZvciBmYXN0IHJlZ2lzdGVyIGFsbG9jYXRpb24uCisgIHZpcnR1YWwgdm9pZCBhZGRGYXN0UmVnQWxsb2MoRnVuY3Rpb25QYXNzICpSZWdBbGxvY1Bhc3MpOworCisgIC8vLyBhZGRPcHRpbWl6ZWRSZWdBbGxvYyAtIEFkZCBwYXNzZXMgcmVsYXRlZCB0byByZWdpc3RlciBhbGxvY2F0aW9uLgorICAvLy8gTExWTVRhcmdldE1hY2hpbmUgcHJvdmlkZXMgc3RhbmRhcmQgcmVnYWxsb2MgcGFzc2VzIGZvciBtb3N0IHRhcmdldHMuCisgIHZpcnR1YWwgdm9pZCBhZGRPcHRpbWl6ZWRSZWdBbGxvYyhGdW5jdGlvblBhc3MgKlJlZ0FsbG9jUGFzcyk7CisKKyAgLy8vIGFkZFByZVJld3JpdGUgLSBBZGQgcGFzc2VzIHRvIHRoZSBvcHRpbWl6ZWQgcmVnaXN0ZXIgYWxsb2NhdGlvbiBwaXBlbGluZQorICAvLy8gYWZ0ZXIgcmVnaXN0ZXIgYWxsb2NhdGlvbiBpcyBjb21wbGV0ZSwgYnV0IGJlZm9yZSB2aXJ0dWFsIHJlZ2lzdGVycyBhcmUKKyAgLy8vIHJld3JpdHRlbiB0byBwaHlzaWNhbCByZWdpc3RlcnMuCisgIC8vLworICAvLy8gVGhlc2UgcGFzc2VzIG11c3QgcHJlc2VydmUgVmlydFJlZ01hcCBhbmQgTGl2ZUludGVydmFscywgYW5kIHdoZW4gcnVubmluZworICAvLy8gYWZ0ZXIgUkFCYXNpYyBvciBSQUdyZWVkeSwgdGhleSBzaG91bGQgdGFrZSBhZHZhbnRhZ2Ugb2YgTGl2ZVJlZ01hdHJpeC4KKyAgLy8vIFdoZW4gdGhlc2UgcGFzc2VzIHJ1biwgVmlydFJlZ01hcCBjb250YWlucyBsZWdhbCBwaHlzcmVnIGFzc2lnbm1lbnRzIGZvcgorICAvLy8gYWxsIHZpcnR1YWwgcmVnaXN0ZXJzLgorICB2aXJ0dWFsIGJvb2wgYWRkUHJlUmV3cml0ZSgpIHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gVGhpcyBtZXRob2QgbWF5IGJlIGltcGxlbWVudGVkIGJ5IHRhcmdldHMgdGhhdCB3YW50IHRvIHJ1biBwYXNzZXMgYWZ0ZXIKKyAgLy8vIHJlZ2lzdGVyIGFsbG9jYXRpb24gcGFzcyBwaXBlbGluZSBidXQgYmVmb3JlIHByb2xvZy1lcGlsb2cgaW5zZXJ0aW9uLgorICB2aXJ0dWFsIHZvaWQgYWRkUG9zdFJlZ0FsbG9jKCkgeyB9CisKKyAgLy8vIEFkZCBwYXNzZXMgdGhhdCBvcHRpbWl6ZSBtYWNoaW5lIGluc3RydWN0aW9ucyBhZnRlciByZWdpc3RlciBhbGxvY2F0aW9uLgorICB2aXJ0dWFsIHZvaWQgYWRkTWFjaGluZUxhdGVPcHRpbWl6YXRpb24oKTsKKworICAvLy8gVGhpcyBtZXRob2QgbWF5IGJlIGltcGxlbWVudGVkIGJ5IHRhcmdldHMgdGhhdCB3YW50IHRvIHJ1biBwYXNzZXMgYWZ0ZXIKKyAgLy8vIHByb2xvZy1lcGlsb2cgaW5zZXJ0aW9uIGFuZCBiZWZvcmUgdGhlIHNlY29uZCBpbnN0cnVjdGlvbiBzY2hlZHVsaW5nIHBhc3MuCisgIHZpcnR1YWwgdm9pZCBhZGRQcmVTY2hlZDIoKSB7IH0KKworICAvLy8gYWRkR0NQYXNzZXMgLSBBZGQgbGF0ZSBjb2RlZ2VuIHBhc3NlcyB0aGF0IGFuYWx5emUgY29kZSBmb3IgZ2FyYmFnZQorICAvLy8gY29sbGVjdGlvbi4gVGhpcyBzaG91bGQgcmV0dXJuIHRydWUgaWYgR0MgaW5mbyBzaG91bGQgYmUgcHJpbnRlZCBhZnRlcgorICAvLy8gdGhlc2UgcGFzc2VzLgorICB2aXJ0dWFsIGJvb2wgYWRkR0NQYXNzZXMoKTsKKworICAvLy8gQWRkIHN0YW5kYXJkIGJhc2ljIGJsb2NrIHBsYWNlbWVudCBwYXNzZXMuCisgIHZpcnR1YWwgdm9pZCBhZGRCbG9ja1BsYWNlbWVudCgpOworCisgIC8vLyBUaGlzIHBhc3MgbWF5IGJlIGltcGxlbWVudGVkIGJ5IHRhcmdldHMgdGhhdCB3YW50IHRvIHJ1biBwYXNzZXMKKyAgLy8vIGltbWVkaWF0ZWx5IGJlZm9yZSBtYWNoaW5lIGNvZGUgaXMgZW1pdHRlZC4KKyAgdmlydHVhbCB2b2lkIGFkZFByZUVtaXRQYXNzKCkgeyB9CisKKyAgLy8vIFRhcmdldHMgbWF5IGFkZCBwYXNzZXMgaW1tZWRpYXRlbHkgYmVmb3JlIG1hY2hpbmUgY29kZSBpcyBlbWl0dGVkIGluIHRoaXMKKyAgLy8vIGNhbGxiYWNrLiBUaGlzIGlzIGNhbGxlZCBldmVuIGxhdGVyIHRoYW4gYGFkZFByZUVtaXRQYXNzYC4KKyAgLy8gRklYTUU6IFJlbmFtZSBgYWRkUHJlRW1pdFBhc3NgIHRvIHNvbWV0aGluZyBtb3JlIHNlbnNpYmxlIGdpdmVuIGl0cyBhY3R1YWwKKyAgLy8gcG9zaXRpb24gYW5kIHJlbW92ZSB0aGUgYDJgIHN1ZmZpeCBoZXJlIGFzIHRoaXMgY2FsbGJhY2sgaXMgd2hhdAorICAvLyBgYWRkUHJlRW1pdFBhc3NgICpzaG91bGQqIGJlIGJ1dCBpbiByZWFsaXR5IGlzbid0LgorICB2aXJ0dWFsIHZvaWQgYWRkUHJlRW1pdFBhc3MyKCkge30KKworICAvLy8gVXRpbGl0aWVzIGZvciB0YXJnZXRzIHRvIGFkZCBwYXNzZXMgdG8gdGhlIHBhc3MgbWFuYWdlci4KKyAgLy8vCisKKyAgLy8vIEFkZCBhIENvZGVHZW4gcGFzcyBhdCB0aGlzIHBvaW50IGluIHRoZSBwaXBlbGluZSBhZnRlciBjaGVja2luZyBvdmVycmlkZXMuCisgIC8vLyBSZXR1cm4gdGhlIHBhc3MgdGhhdCB3YXMgYWRkZWQsIG9yIHplcm8gaWYgbm8gcGFzcyB3YXMgYWRkZWQuCisgIC8vLyBAcCBwcmludEFmdGVyICAgIGlmIHRydWUgYW5kIGFkZGluZyBhIG1hY2hpbmUgZnVuY3Rpb24gcGFzcyBhZGQgYW4gZXh0cmEKKyAgLy8vICAgICAgICAgICAgICAgICAgbWFjaGluZSBwcmludGVyIHBhc3MgYWZ0ZXJ3YXJkcworICAvLy8gQHAgdmVyaWZ5QWZ0ZXIgICBpZiB0cnVlIGFuZCBhZGRpbmcgYSBtYWNoaW5lIGZ1bmN0aW9uIHBhc3MgYWRkIGFuIGV4dHJhCisgIC8vLyAgICAgICAgICAgICAgICAgIG1hY2hpbmUgdmVyaWZpY2F0aW9uIHBhc3MgYWZ0ZXJ3YXJkcy4KKyAgQW5hbHlzaXNJRCBhZGRQYXNzKEFuYWx5c2lzSUQgUGFzc0lELCBib29sIHZlcmlmeUFmdGVyID0gdHJ1ZSwKKyAgICAgICAgICAgICAgICAgICAgIGJvb2wgcHJpbnRBZnRlciA9IHRydWUpOworCisgIC8vLyBBZGQgYSBwYXNzIHRvIHRoZSBQYXNzTWFuYWdlciBpZiB0aGF0IHBhc3MgaXMgc3VwcG9zZWQgdG8gYmUgcnVuLCBhcworICAvLy8gZGV0ZXJtaW5lZCBieSB0aGUgU3RhcnRBZnRlciBhbmQgU3RvcEFmdGVyIG9wdGlvbnMuIFRha2VzIG93bmVyc2hpcCBvZiB0aGUKKyAgLy8vIHBhc3MuCisgIC8vLyBAcCBwcmludEFmdGVyICAgIGlmIHRydWUgYW5kIGFkZGluZyBhIG1hY2hpbmUgZnVuY3Rpb24gcGFzcyBhZGQgYW4gZXh0cmEKKyAgLy8vICAgICAgICAgICAgICAgICAgbWFjaGluZSBwcmludGVyIHBhc3MgYWZ0ZXJ3YXJkcworICAvLy8gQHAgdmVyaWZ5QWZ0ZXIgICBpZiB0cnVlIGFuZCBhZGRpbmcgYSBtYWNoaW5lIGZ1bmN0aW9uIHBhc3MgYWRkIGFuIGV4dHJhCisgIC8vLyAgICAgICAgICAgICAgICAgIG1hY2hpbmUgdmVyaWZpY2F0aW9uIHBhc3MgYWZ0ZXJ3YXJkcy4KKyAgdm9pZCBhZGRQYXNzKFBhc3MgKlAsIGJvb2wgdmVyaWZ5QWZ0ZXIgPSB0cnVlLCBib29sIHByaW50QWZ0ZXIgPSB0cnVlKTsKKworICAvLy8gYWRkTWFjaGluZVBhc3NlcyBoZWxwZXIgdG8gY3JlYXRlIHRoZSB0YXJnZXQtc2VsZWN0ZWQgb3Igb3ZlcnJpZGVuCisgIC8vLyByZWdhbGxvYyBwYXNzLgorICBGdW5jdGlvblBhc3MgKmNyZWF0ZVJlZ0FsbG9jUGFzcyhib29sIE9wdGltaXplZCk7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1RBUkdFVFBBU1NDT05GSUdfSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhcmdldFJlZ2lzdGVySW5mby5oIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhcmdldFJlZ2lzdGVySW5mby5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhNDdhMjQKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vVGFyZ2V0UmVnaXN0ZXJJbmZvLmgKQEAgLTAsMCArMSwxMTg4IEBACisvLz09LSBDb2RlR2VuL1RhcmdldFJlZ2lzdGVySW5mby5oIC0gVGFyZ2V0IFJlZ2lzdGVyIEluZm9ybWF0aW9uIC0qLSBDKysgLSotPT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZXNjcmliZXMgYW4gYWJzdHJhY3QgaW50ZXJmYWNlIHVzZWQgdG8gZ2V0IGluZm9ybWF0aW9uIGFib3V0IGEKKy8vIHRhcmdldCBtYWNoaW5lcyByZWdpc3RlciBmaWxlLiAgVGhpcyBpbmZvcm1hdGlvbiBpcyB1c2VkIGZvciBhIHZhcmlldHkgb2YKKy8vIHB1cnBvc2VkLCBlc3BlY2lhbGx5IHJlZ2lzdGVyIGFsbG9jYXRpb24uCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fVEFSR0VUUkVHSVNURVJJTkZPX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1RBUkdFVFJFR0lTVEVSSU5GT19ICisKKyNpbmNsdWRlICJsbHZtL0FEVC9BcnJheVJlZi5oIgorI2luY2x1ZGUgImxsdm0vQURUL1NtYWxsVmVjdG9yLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU3RyaW5nUmVmLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvaXRlcmF0b3JfcmFuZ2UuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUJhc2ljQmxvY2suaCIKKyNpbmNsdWRlICJsbHZtL0lSL0NhbGxpbmdDb252LmgiCisjaW5jbHVkZSAibGx2bS9NQy9MYW5lQml0bWFzay5oIgorI2luY2x1ZGUgImxsdm0vTUMvTUNSZWdpc3RlckluZm8uaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvRXJyb3JIYW5kbGluZy5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9NYWNoaW5lVmFsdWVUeXBlLmgiCisjaW5jbHVkZSAibGx2bS9TdXBwb3J0L01hdGhFeHRyYXMuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvUHJpbnRhYmxlLmgiCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgQml0VmVjdG9yOworY2xhc3MgTGl2ZVJlZ01hdHJpeDsKK2NsYXNzIE1hY2hpbmVGdW5jdGlvbjsKK2NsYXNzIE1hY2hpbmVJbnN0cjsKK2NsYXNzIFJlZ1NjYXZlbmdlcjsKK2NsYXNzIFZpcnRSZWdNYXA7CitjbGFzcyBMaXZlSW50ZXJ2YWxzOworCitjbGFzcyBUYXJnZXRSZWdpc3RlckNsYXNzIHsKK3B1YmxpYzoKKyAgdXNpbmcgaXRlcmF0b3IgPSBjb25zdCBNQ1BoeXNSZWcgKjsKKyAgdXNpbmcgY29uc3RfaXRlcmF0b3IgPSBjb25zdCBNQ1BoeXNSZWcgKjsKKyAgdXNpbmcgc2NfaXRlcmF0b3IgPSBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzKiBjb25zdCAqOworCisgIC8vIEluc3RhbmNlIHZhcmlhYmxlcyBmaWxsZWQgYnkgdGFibGVnZW4sIGRvIG5vdCB1c2UhCisgIGNvbnN0IE1DUmVnaXN0ZXJDbGFzcyAqTUM7CisgIGNvbnN0IHVpbnQzMl90ICpTdWJDbGFzc01hc2s7CisgIGNvbnN0IHVpbnQxNl90ICpTdXBlclJlZ0luZGljZXM7CisgIGNvbnN0IExhbmVCaXRtYXNrIExhbmVNYXNrOworICAvLy8gQ2xhc3NlcyB3aXRoIGEgaGlnaGVyIHByaW9yaXR5IHZhbHVlIGFyZSBhc3NpZ25lZCBmaXJzdCBieSByZWdpc3RlcgorICAvLy8gYWxsb2NhdG9ycyB1c2luZyBhIGdyZWVkeSBoZXVyaXN0aWMuIFRoZSB2YWx1ZSBpcyBpbiB0aGUgcmFuZ2UgWzAsNjNdLgorICBjb25zdCB1aW50OF90IEFsbG9jYXRpb25Qcmlvcml0eTsKKyAgLy8vIFdoZXRoZXIgdGhlIGNsYXNzIHN1cHBvcnRzIHR3byAob3IgbW9yZSkgZGlzanVuY3Qgc3VicmVnaXN0ZXIgaW5kaWNlcy4KKyAgY29uc3QgYm9vbCBIYXNEaXNqdW5jdFN1YlJlZ3M7CisgIC8vLyBXaGV0aGVyIGEgY29tYmluYXRpb24gb2Ygc3VicmVnaXN0ZXJzIGNhbiBjb3ZlciBldmVyeSByZWdpc3RlciBpbiB0aGUKKyAgLy8vIGNsYXNzLiBTZWUgYWxzbyB0aGUgQ292ZXJlZEJ5U3ViUmVncyBkZXNjcmlwdGlvbiBpbiBUYXJnZXQudGQuCisgIGNvbnN0IGJvb2wgQ292ZXJlZEJ5U3ViUmVnczsKKyAgY29uc3Qgc2NfaXRlcmF0b3IgU3VwZXJDbGFzc2VzOworICBBcnJheVJlZjxNQ1BoeXNSZWc+ICgqT3JkZXJGdW5jKShjb25zdCBNYWNoaW5lRnVuY3Rpb24mKTsKKworICAvLy8gUmV0dXJuIHRoZSByZWdpc3RlciBjbGFzcyBJRCBudW1iZXIuCisgIHVuc2lnbmVkIGdldElEKCkgY29uc3QgeyByZXR1cm4gTUMtPmdldElEKCk7IH0KKworICAvLy8gYmVnaW4vZW5kIC0gUmV0dXJuIGFsbCBvZiB0aGUgcmVnaXN0ZXJzIGluIHRoaXMgY2xhc3MuCisgIC8vLworICBpdGVyYXRvciAgICAgICBiZWdpbigpIGNvbnN0IHsgcmV0dXJuIE1DLT5iZWdpbigpOyB9CisgIGl0ZXJhdG9yICAgICAgICAgZW5kKCkgY29uc3QgeyByZXR1cm4gTUMtPmVuZCgpOyB9CisKKyAgLy8vIFJldHVybiB0aGUgbnVtYmVyIG9mIHJlZ2lzdGVycyBpbiB0aGlzIGNsYXNzLgorICB1bnNpZ25lZCBnZXROdW1SZWdzKCkgY29uc3QgeyByZXR1cm4gTUMtPmdldE51bVJlZ3MoKTsgfQorCisgIGl0ZXJhdG9yX3JhbmdlPFNtYWxsVmVjdG9ySW1wbDxNQ1BoeXNSZWc+Ojpjb25zdF9pdGVyYXRvcj4KKyAgZ2V0UmVnaXN0ZXJzKCkgY29uc3QgeworICAgIHJldHVybiBtYWtlX3JhbmdlKE1DLT5iZWdpbigpLCBNQy0+ZW5kKCkpOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyIGluIHRoZSBjbGFzcy4KKyAgdW5zaWduZWQgZ2V0UmVnaXN0ZXIodW5zaWduZWQgaSkgY29uc3QgeworICAgIHJldHVybiBNQy0+Z2V0UmVnaXN0ZXIoaSk7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCByZWdpc3RlciBpcyBpbmNsdWRlZCBpbiB0aGlzIHJlZ2lzdGVyIGNsYXNzLgorICAvLy8gVGhpcyBkb2VzIG5vdCBpbmNsdWRlIHZpcnR1YWwgcmVnaXN0ZXJzLgorICBib29sIGNvbnRhaW5zKHVuc2lnbmVkIFJlZykgY29uc3QgeworICAgIHJldHVybiBNQy0+Y29udGFpbnMoUmVnKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBib3RoIHJlZ2lzdGVycyBhcmUgaW4gdGhpcyBjbGFzcy4KKyAgYm9vbCBjb250YWlucyh1bnNpZ25lZCBSZWcxLCB1bnNpZ25lZCBSZWcyKSBjb25zdCB7CisgICAgcmV0dXJuIE1DLT5jb250YWlucyhSZWcxLCBSZWcyKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIGNvc3Qgb2YgY29weWluZyBhIHZhbHVlIGJldHdlZW4gdHdvIHJlZ2lzdGVycyBpbiB0aGlzIGNsYXNzLgorICAvLy8gQSBuZWdhdGl2ZSBudW1iZXIgbWVhbnMgdGhlIHJlZ2lzdGVyIGNsYXNzIGlzIHZlcnkgZXhwZW5zaXZlCisgIC8vLyB0byBjb3B5IGUuZy4gc3RhdHVzIGZsYWcgcmVnaXN0ZXIgY2xhc3Nlcy4KKyAgaW50IGdldENvcHlDb3N0KCkgY29uc3QgeyByZXR1cm4gTUMtPmdldENvcHlDb3N0KCk7IH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyByZWdpc3RlciBjbGFzcyBtYXkgYmUgdXNlZCB0byBjcmVhdGUgdmlydHVhbAorICAvLy8gcmVnaXN0ZXJzLgorICBib29sIGlzQWxsb2NhdGFibGUoKSBjb25zdCB7IHJldHVybiBNQy0+aXNBbGxvY2F0YWJsZSgpOyB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgVGFyZ2V0UmVnaXN0ZXJDbGFzcworICAvLy8gaXMgYSBwcm9wZXIgc3ViLWNsYXNzIG9mIHRoaXMgVGFyZ2V0UmVnaXN0ZXJDbGFzcy4KKyAgYm9vbCBoYXNTdWJDbGFzcyhjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQykgY29uc3QgeworICAgIHJldHVybiBSQyAhPSB0aGlzICYmIGhhc1N1YkNsYXNzRXEoUkMpOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiBSQyBpcyBhIHN1Yi1jbGFzcyBvZiBvciBlcXVhbCB0byB0aGlzIGNsYXNzLgorICBib29sIGhhc1N1YkNsYXNzRXEoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUkMpIGNvbnN0IHsKKyAgICB1bnNpZ25lZCBJRCA9IFJDLT5nZXRJRCgpOworICAgIHJldHVybiAoU3ViQ2xhc3NNYXNrW0lEIC8gMzJdID4+IChJRCAlIDMyKSkgJiAxOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgVGFyZ2V0UmVnaXN0ZXJDbGFzcyBpcyBhCisgIC8vLyBwcm9wZXIgc3VwZXItY2xhc3Mgb2YgdGhpcyBUYXJnZXRSZWdpc3RlckNsYXNzLgorICBib29sIGhhc1N1cGVyQ2xhc3MoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUkMpIGNvbnN0IHsKKyAgICByZXR1cm4gUkMtPmhhc1N1YkNsYXNzKHRoaXMpOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiBSQyBpcyBhIHN1cGVyLWNsYXNzIG9mIG9yIGVxdWFsIHRvIHRoaXMgY2xhc3MuCisgIGJvb2wgaGFzU3VwZXJDbGFzc0VxKGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKSBjb25zdCB7CisgICAgcmV0dXJuIFJDLT5oYXNTdWJDbGFzc0VxKHRoaXMpOworICB9CisKKyAgLy8vIFJldHVybnMgYSBiaXQgdmVjdG9yIG9mIHN1YmNsYXNzZXMsIGluY2x1ZGluZyB0aGlzIG9uZS4KKyAgLy8vIFRoZSB2ZWN0b3IgaXMgaW5kZXhlZCBieSBjbGFzcyBJRHMuCisgIC8vLworICAvLy8gVG8gdXNlIGl0LCBjb25zaWRlciB0aGUgcmV0dXJuZWQgYXJyYXkgYXMgYSBjaHVuayBvZiBtZW1vcnkgdGhhdAorICAvLy8gY29udGFpbnMgYW4gYXJyYXkgb2YgYml0cyBvZiBzaXplIE51bVJlZ0NsYXNzZXMuIEVhY2ggMzItYml0IGNodW5rCisgIC8vLyBjb250YWlucyBhIGJpdHNldCBvZiB0aGUgSUQgb2YgdGhlIHN1YmNsYXNzZXMgaW4gYmlnLWVuZGlhbiBzdHlsZS4KKworICAvLy8gSS5lLiwgdGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBtZW1vcnkgZnJvbSBsZWZ0IHRvIHJpZ2h0IGF0IHRoZQorICAvLy8gYml0IGxldmVsIGxvb2tzIGxpa2U6CisgIC8vLyBbMzEgMzAgLi4uIDEgMF0gWyA2MyA2MiAuLi4gMzMgMzJdIC4uLgorICAvLy8gICAgICAgICAgICAgICAgICAgICBbIFhYWCBOdW1SZWdDbGFzc2VzIE51bVJlZ0NsYXNzZXMgLSAxIC4uLiBdCisgIC8vLyBXaGVyZSB0aGUgbnVtYmVyIHJlcHJlc2VudHMgdGhlIGNsYXNzIElEIGFuZCBYWFggYml0cyB0aGF0CisgIC8vLyBzaG91bGQgYmUgaWdub3JlZC4KKyAgLy8vCisgIC8vLyBTZWUgdGhlIGltcGxlbWVudGF0aW9uIG9mIGhhc1N1YkNsYXNzRXEgZm9yIGFuIGV4YW1wbGUgb2YgaG93IGl0CisgIC8vLyBjYW4gYmUgdXNlZC4KKyAgY29uc3QgdWludDMyX3QgKmdldFN1YkNsYXNzTWFzaygpIGNvbnN0IHsKKyAgICByZXR1cm4gU3ViQ2xhc3NNYXNrOworICB9CisKKyAgLy8vIFJldHVybnMgYSAwLXRlcm1pbmF0ZWQgbGlzdCBvZiBzdWItcmVnaXN0ZXIgaW5kaWNlcyB0aGF0IHByb2plY3Qgc29tZQorICAvLy8gc3VwZXItcmVnaXN0ZXIgY2xhc3MgaW50byB0aGlzIHJlZ2lzdGVyIGNsYXNzLiBUaGUgbGlzdCBoYXMgYW4gZW50cnkgZm9yCisgIC8vLyBlYWNoIElkeCBzdWNoIHRoYXQ6CisgIC8vLworICAvLy8gICBUaGVyZSBleGlzdHMgU3VwZXJSQyB3aGVyZToKKyAgLy8vICAgICBGb3IgYWxsIFJlZyBpbiBTdXBlclJDOgorICAvLy8gICAgICAgdGhpcy0+Y29udGFpbnMoUmVnOklkeCkKKyAgY29uc3QgdWludDE2X3QgKmdldFN1cGVyUmVnSW5kaWNlcygpIGNvbnN0IHsKKyAgICByZXR1cm4gU3VwZXJSZWdJbmRpY2VzOworICB9CisKKyAgLy8vIFJldHVybnMgYSBOVUxMLXRlcm1pbmF0ZWQgbGlzdCBvZiBzdXBlci1jbGFzc2VzLiAgVGhlCisgIC8vLyBjbGFzc2VzIGFyZSBvcmRlcmVkIGJ5IElEIHdoaWNoIGlzIGFsc28gYSB0b3BvbG9naWNhbCBvcmRlcmluZyBmcm9tIGxhcmdlCisgIC8vLyB0byBzbWFsbCBjbGFzc2VzLiAgVGhlIGxpc3QgZG9lcyBOT1QgaW5jbHVkZSB0aGUgY3VycmVudCBjbGFzcy4KKyAgc2NfaXRlcmF0b3IgZ2V0U3VwZXJDbGFzc2VzKCkgY29uc3QgeworICAgIHJldHVybiBTdXBlckNsYXNzZXM7CisgIH0KKworICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBUYXJnZXRSZWdpc3RlckNsYXNzIGlzIGEgc3Vic2V0CisgIC8vLyBjbGFzcyBvZiBhdCBsZWFzdCBvbmUgb3RoZXIgVGFyZ2V0UmVnaXN0ZXJDbGFzcy4KKyAgYm9vbCBpc0FTdWJDbGFzcygpIGNvbnN0IHsKKyAgICByZXR1cm4gU3VwZXJDbGFzc2VzWzBdICE9IG51bGxwdHI7CisgIH0KKworICAvLy8gUmV0dXJucyB0aGUgcHJlZmVycmVkIG9yZGVyIGZvciBhbGxvY2F0aW5nIHJlZ2lzdGVycyBmcm9tIHRoaXMgcmVnaXN0ZXIKKyAgLy8vIGNsYXNzIGluIE1GLiBUaGUgcmF3IG9yZGVyIGNvbWVzIGRpcmVjdGx5IGZyb20gdGhlIC50ZCBmaWxlIGFuZCBtYXkKKyAgLy8vIGluY2x1ZGUgcmVzZXJ2ZWQgcmVnaXN0ZXJzIHRoYXQgYXJlIG5vdCBhbGxvY2F0YWJsZS4KKyAgLy8vIFJlZ2lzdGVyIGFsbG9jYXRvcnMgc2hvdWxkIGFsc28gbWFrZSBzdXJlIHRvIGFsbG9jYXRlCisgIC8vLyBjYWxsZWUtc2F2ZWQgcmVnaXN0ZXJzIG9ubHkgYWZ0ZXIgYWxsIHRoZSB2b2xhdGlsZXMgYXJlIHVzZWQuIFRoZQorICAvLy8gUmVnaXN0ZXJDbGFzc0luZm8gY2xhc3MgcHJvdmlkZXMgZmlsdGVyZWQgYWxsb2NhdGlvbiBvcmRlcnMgd2l0aAorICAvLy8gY2FsbGVlLXNhdmVkIHJlZ2lzdGVycyBtb3ZlZCB0byB0aGUgZW5kLgorICAvLy8KKyAgLy8vIFRoZSBNYWNoaW5lRnVuY3Rpb24gYXJndW1lbnQgY2FuIGJlIHVzZWQgdG8gdHVuZSB0aGUgYWxsb2NhdGFibGUKKyAgLy8vIHJlZ2lzdGVycyBiYXNlZCBvbiB0aGUgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBmdW5jdGlvbiwgc3VidGFyZ2V0LCBvcgorICAvLy8gb3RoZXIgY3JpdGVyaWEuCisgIC8vLworICAvLy8gQnkgZGVmYXVsdCwgdGhpcyBtZXRob2QgcmV0dXJucyBhbGwgcmVnaXN0ZXJzIGluIHRoZSBjbGFzcy4KKyAgQXJyYXlSZWY8TUNQaHlzUmVnPiBnZXRSYXdBbGxvY2F0aW9uT3JkZXIoY29uc3QgTWFjaGluZUZ1bmN0aW9uICZNRikgY29uc3QgeworICAgIHJldHVybiBPcmRlckZ1bmMgPyBPcmRlckZ1bmMoTUYpIDogbWFrZUFycmF5UmVmKGJlZ2luKCksIGdldE51bVJlZ3MoKSk7CisgIH0KKworICAvLy8gUmV0dXJucyB0aGUgY29tYmluYXRpb24gb2YgYWxsIGxhbmUgbWFza3Mgb2YgcmVnaXN0ZXIgaW4gdGhpcyBjbGFzcy4KKyAgLy8vIFRoZSBsYW5lIG1hc2tzIG9mIHRoZSByZWdpc3RlcnMgYXJlIHRoZSBjb21iaW5hdGlvbiBvZiBhbGwgbGFuZSBtYXNrcworICAvLy8gb2YgdGhlaXIgc3VicmVnaXN0ZXJzLiBSZXR1cm5zIDEgaWYgdGhlcmUgYXJlIG5vIHN1YnJlZ2lzdGVycy4KKyAgTGFuZUJpdG1hc2sgZ2V0TGFuZU1hc2soKSBjb25zdCB7CisgICAgcmV0dXJuIExhbmVNYXNrOworICB9Cit9OworCisvLy8gRXh0cmEgaW5mb3JtYXRpb24sIG5vdCBpbiBNQ1JlZ2lzdGVyRGVzYywgYWJvdXQgcmVnaXN0ZXJzLgorLy8vIFRoZXNlIGFyZSB1c2VkIGJ5IGNvZGVnZW4sIG5vdCBieSBNQy4KK3N0cnVjdCBUYXJnZXRSZWdpc3RlckluZm9EZXNjIHsKKyAgdW5zaWduZWQgQ29zdFBlclVzZTsgICAgICAgICAgLy8gRXh0cmEgY29zdCBvZiBpbnN0cnVjdGlvbnMgdXNpbmcgcmVnaXN0ZXIuCisgIGJvb2wgaW5BbGxvY2F0YWJsZUNsYXNzOyAgICAgIC8vIFJlZ2lzdGVyIGJlbG9uZ3MgdG8gYW4gYWxsb2NhdGFibGUgcmVnY2xhc3MuCit9OworCisvLy8gRWFjaCBUYXJnZXRSZWdpc3RlckNsYXNzIGhhcyBhIHBlciByZWdpc3RlciB3ZWlnaHQsIGFuZCB3ZWlnaHQKKy8vLyBsaW1pdCB3aGljaCBtdXN0IGJlIGxlc3MgdGhhbiB0aGUgbGltaXRzIG9mIGl0cyBwcmVzc3VyZSBzZXRzLgorc3RydWN0IFJlZ0NsYXNzV2VpZ2h0IHsKKyAgdW5zaWduZWQgUmVnV2VpZ2h0OworICB1bnNpZ25lZCBXZWlnaHRMaW1pdDsKK307CisKKy8vLyBUYXJnZXRSZWdpc3RlckluZm8gYmFzZSBjbGFzcyAtIFdlIGFzc3VtZSB0aGF0IHRoZSB0YXJnZXQgZGVmaW5lcyBhIHN0YXRpYworLy8vIGFycmF5IG9mIFRhcmdldFJlZ2lzdGVyRGVzYyBvYmplY3RzIHRoYXQgcmVwcmVzZW50IGFsbCBvZiB0aGUgbWFjaGluZQorLy8vIHJlZ2lzdGVycyB0aGF0IHRoZSB0YXJnZXQgaGFzLiAgQXMgc3VjaCwgd2Ugc2ltcGx5IGhhdmUgdG8gdHJhY2sgYSBwb2ludGVyCisvLy8gdG8gdGhpcyBhcnJheSBzbyB0aGF0IHdlIGNhbiB0dXJuIHJlZ2lzdGVyIG51bWJlciBpbnRvIGEgcmVnaXN0ZXIKKy8vLyBkZXNjcmlwdG9yLgorLy8vCitjbGFzcyBUYXJnZXRSZWdpc3RlckluZm8gOiBwdWJsaWMgTUNSZWdpc3RlckluZm8geworcHVibGljOgorICB1c2luZyByZWdjbGFzc19pdGVyYXRvciA9IGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKiBjb25zdCAqOworICB1c2luZyB2dF9pdGVyYXRvciA9IGNvbnN0IE1WVDo6U2ltcGxlVmFsdWVUeXBlICo7CisgIHN0cnVjdCBSZWdDbGFzc0luZm8geworICAgIHVuc2lnbmVkIFJlZ1NpemUsIFNwaWxsU2l6ZSwgU3BpbGxBbGlnbm1lbnQ7CisgICAgdnRfaXRlcmF0b3IgVlRMaXN0OworICB9OworcHJpdmF0ZToKKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvRGVzYyAqSW5mb0Rlc2M7ICAgICAvLyBFeHRyYSBkZXNjIGFycmF5IGZvciBjb2RlZ2VuCisgIGNvbnN0IGNoYXIgKmNvbnN0ICpTdWJSZWdJbmRleE5hbWVzOyAgICAgICAgLy8gTmFtZXMgb2Ygc3VicmVnIGluZGV4ZXMuCisgIC8vIFBvaW50ZXIgdG8gYXJyYXkgb2YgbGFuZSBtYXNrcywgb25lIHBlciBzdWItcmVnIGluZGV4LgorICBjb25zdCBMYW5lQml0bWFzayAqU3ViUmVnSW5kZXhMYW5lTWFza3M7CisKKyAgcmVnY2xhc3NfaXRlcmF0b3IgUmVnQ2xhc3NCZWdpbiwgUmVnQ2xhc3NFbmQ7ICAgLy8gTGlzdCBvZiByZWdjbGFzc2VzCisgIExhbmVCaXRtYXNrIENvdmVyaW5nTGFuZXM7CisgIGNvbnN0IFJlZ0NsYXNzSW5mbyAqY29uc3QgUkNJbmZvczsKKyAgdW5zaWduZWQgSHdNb2RlOworCitwcm90ZWN0ZWQ6CisgIFRhcmdldFJlZ2lzdGVySW5mbyhjb25zdCBUYXJnZXRSZWdpc3RlckluZm9EZXNjICpJRCwKKyAgICAgICAgICAgICAgICAgICAgIHJlZ2NsYXNzX2l0ZXJhdG9yIFJlZ0NsYXNzQmVnaW4sCisgICAgICAgICAgICAgICAgICAgICByZWdjbGFzc19pdGVyYXRvciBSZWdDbGFzc0VuZCwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmNvbnN0ICpTUklOYW1lcywKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExhbmVCaXRtYXNrICpTUklMYW5lTWFza3MsCisgICAgICAgICAgICAgICAgICAgICBMYW5lQml0bWFzayBDb3ZlcmluZ0xhbmVzLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgUmVnQ2xhc3NJbmZvICpjb25zdCBSU0ksCisgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBNb2RlID0gMCk7CisgIHZpcnR1YWwgflRhcmdldFJlZ2lzdGVySW5mbygpOworCitwdWJsaWM6CisgIC8vIFJlZ2lzdGVyIG51bWJlcnMgY2FuIHJlcHJlc2VudCBwaHlzaWNhbCByZWdpc3RlcnMsIHZpcnR1YWwgcmVnaXN0ZXJzLCBhbmQKKyAgLy8gc29tZXRpbWVzIHN0YWNrIHNsb3RzLiBUaGUgdW5zaWduZWQgdmFsdWVzIGFyZSBkaXZpZGVkIGludG8gdGhlc2UgcmFuZ2VzOgorICAvLworICAvLyAgIDAgICAgICAgICAgIE5vdCBhIHJlZ2lzdGVyLCBjYW4gYmUgdXNlZCBhcyBhIHNlbnRpbmVsLgorICAvLyAgIFsxOzJeMzApICAgIFBoeXNpY2FsIHJlZ2lzdGVycyBhc3NpZ25lZCBieSBUYWJsZUdlbi4KKyAgLy8gICBbMl4zMDsyXjMxKSBTdGFjayBzbG90cy4gKFJhcmVseSB1c2VkLikKKyAgLy8gICBbMl4zMTsyXjMyKSBWaXJ0dWFsIHJlZ2lzdGVycyBhc3NpZ25lZCBieSBNYWNoaW5lUmVnaXN0ZXJJbmZvLgorICAvLworICAvLyBGdXJ0aGVyIHNlbnRpbmVscyBjYW4gYmUgYWxsb2NhdGVkIGZyb20gdGhlIHNtYWxsIG5lZ2F0aXZlIGludGVnZXJzLgorICAvLyBEZW5zZU1hcEluZm88dW5zaWduZWQ+IHVzZXMgLTF1IGFuZCAtMnUuCisKKyAgLy8vIGlzU3RhY2tTbG90IC0gU29tZXRpbWVzIGl0IGlzIHVzZWZ1bCB0aGUgYmUgYWJsZSB0byBzdG9yZSBhIG5vbi1uZWdhdGl2ZQorICAvLy8gZnJhbWUgaW5kZXggaW4gYSB2YXJpYWJsZSB0aGF0IG5vcm1hbGx5IGhvbGRzIGEgcmVnaXN0ZXIuIGlzU3RhY2tTbG90KCkKKyAgLy8vIHJldHVybnMgdHJ1ZSBpZiBSZWcgaXMgaW4gdGhlIHJhbmdlIHVzZWQgZm9yIHN0YWNrIHNsb3RzLgorICAvLy8KKyAgLy8vIE5vdGUgdGhhdCBpc1ZpcnR1YWxSZWdpc3RlcigpIGFuZCBpc1BoeXNpY2FsUmVnaXN0ZXIoKSBjYW5ub3QgaGFuZGxlIHN0YWNrCisgIC8vLyBzbG90cywgc28gaWYgYSB2YXJpYWJsZSBtYXkgY29udGFpbnMgYSBzdGFjayBzbG90LCBhbHdheXMgY2hlY2sKKyAgLy8vIGlzU3RhY2tTbG90KCkgZmlyc3QuCisgIC8vLworICBzdGF0aWMgYm9vbCBpc1N0YWNrU2xvdCh1bnNpZ25lZCBSZWcpIHsKKyAgICByZXR1cm4gaW50KFJlZykgPj0gKDEgPDwgMzApOworICB9CisKKyAgLy8vIENvbXB1dGUgdGhlIGZyYW1lIGluZGV4IGZyb20gYSByZWdpc3RlciB2YWx1ZSByZXByZXNlbnRpbmcgYSBzdGFjayBzbG90LgorICBzdGF0aWMgaW50IHN0YWNrU2xvdDJJbmRleCh1bnNpZ25lZCBSZWcpIHsKKyAgICBhc3NlcnQoaXNTdGFja1Nsb3QoUmVnKSAmJiAiTm90IGEgc3RhY2sgc2xvdCIpOworICAgIHJldHVybiBpbnQoUmVnIC0gKDF1IDw8IDMwKSk7CisgIH0KKworICAvLy8gQ29udmVydCBhIG5vbi1uZWdhdGl2ZSBmcmFtZSBpbmRleCB0byBhIHN0YWNrIHNsb3QgcmVnaXN0ZXIgdmFsdWUuCisgIHN0YXRpYyB1bnNpZ25lZCBpbmRleDJTdGFja1Nsb3QoaW50IEZJKSB7CisgICAgYXNzZXJ0KEZJID49IDAgJiYgIkNhbm5vdCBob2xkIGEgbmVnYXRpdmUgZnJhbWUgaW5kZXguIik7CisgICAgcmV0dXJuIEZJICsgKDF1IDw8IDMwKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyIG51bWJlciBpcyBpbgorICAvLy8gdGhlIHBoeXNpY2FsIHJlZ2lzdGVyIG5hbWVzcGFjZS4KKyAgc3RhdGljIGJvb2wgaXNQaHlzaWNhbFJlZ2lzdGVyKHVuc2lnbmVkIFJlZykgeworICAgIGFzc2VydCghaXNTdGFja1Nsb3QoUmVnKSAmJiAiTm90IGEgcmVnaXN0ZXIhIENoZWNrIGlzU3RhY2tTbG90KCkgZmlyc3QuIik7CisgICAgcmV0dXJuIGludChSZWcpID4gMDsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyIG51bWJlciBpcyBpbgorICAvLy8gdGhlIHZpcnR1YWwgcmVnaXN0ZXIgbmFtZXNwYWNlLgorICBzdGF0aWMgYm9vbCBpc1ZpcnR1YWxSZWdpc3Rlcih1bnNpZ25lZCBSZWcpIHsKKyAgICBhc3NlcnQoIWlzU3RhY2tTbG90KFJlZykgJiYgIk5vdCBhIHJlZ2lzdGVyISBDaGVjayBpc1N0YWNrU2xvdCgpIGZpcnN0LiIpOworICAgIHJldHVybiBpbnQoUmVnKSA8IDA7CisgIH0KKworICAvLy8gQ29udmVydCBhIHZpcnR1YWwgcmVnaXN0ZXIgbnVtYmVyIHRvIGEgMC1iYXNlZCBpbmRleC4KKyAgLy8vIFRoZSBmaXJzdCB2aXJ0dWFsIHJlZ2lzdGVyIGluIGEgZnVuY3Rpb24gd2lsbCBnZXQgdGhlIGluZGV4IDAuCisgIHN0YXRpYyB1bnNpZ25lZCB2aXJ0UmVnMkluZGV4KHVuc2lnbmVkIFJlZykgeworICAgIGFzc2VydChpc1ZpcnR1YWxSZWdpc3RlcihSZWcpICYmICJOb3QgYSB2aXJ0dWFsIHJlZ2lzdGVyIik7CisgICAgcmV0dXJuIFJlZyAmIH4oMXUgPDwgMzEpOworICB9CisKKyAgLy8vIENvbnZlcnQgYSAwLWJhc2VkIGluZGV4IHRvIGEgdmlydHVhbCByZWdpc3RlciBudW1iZXIuCisgIC8vLyBUaGlzIGlzIHRoZSBpbnZlcnNlIG9wZXJhdGlvbiBvZiBWaXJ0UmVnMkluZGV4RnVuY3RvciBiZWxvdy4KKyAgc3RhdGljIHVuc2lnbmVkIGluZGV4MlZpcnRSZWcodW5zaWduZWQgSW5kZXgpIHsKKyAgICByZXR1cm4gSW5kZXggfCAoMXUgPDwgMzEpOworICB9CisKKyAgLy8vIFJldHVybiB0aGUgc2l6ZSBpbiBiaXRzIG9mIGEgcmVnaXN0ZXIgZnJvbSBjbGFzcyBSQy4KKyAgdW5zaWduZWQgZ2V0UmVnU2l6ZUluQml0cyhjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICZSQykgY29uc3QgeworICAgIHJldHVybiBnZXRSZWdDbGFzc0luZm8oUkMpLlJlZ1NpemU7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBzaXplIGluIGJ5dGVzIG9mIHRoZSBzdGFjayBzbG90IGFsbG9jYXRlZCB0byBob2xkIGEgc3BpbGxlZAorICAvLy8gY29weSBvZiBhIHJlZ2lzdGVyIGZyb20gY2xhc3MgUkMuCisgIHVuc2lnbmVkIGdldFNwaWxsU2l6ZShjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICZSQykgY29uc3QgeworICAgIHJldHVybiBnZXRSZWdDbGFzc0luZm8oUkMpLlNwaWxsU2l6ZSAvIDg7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSBtaW5pbXVtIHJlcXVpcmVkIGFsaWdubWVudCBpbiBieXRlcyBmb3IgYSBzcGlsbCBzbG90IGZvcgorICAvLy8gYSByZWdpc3RlciBvZiB0aGlzIGNsYXNzLgorICB1bnNpZ25lZCBnZXRTcGlsbEFsaWdubWVudChjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICZSQykgY29uc3QgeworICAgIHJldHVybiBnZXRSZWdDbGFzc0luZm8oUkMpLlNwaWxsQWxpZ25tZW50IC8gODsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgZ2l2ZW4gVGFyZ2V0UmVnaXN0ZXJDbGFzcyBoYXMgdGhlIFZhbHVlVHlwZSBULgorICBib29sIGlzVHlwZUxlZ2FsRm9yQ2xhc3MoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAmUkMsIE1WVCBUKSBjb25zdCB7CisgICAgZm9yIChhdXRvIEkgPSBsZWdhbGNsYXNzdHlwZXNfYmVnaW4oUkMpOyAqSSAhPSBNVlQ6Ok90aGVyOyArK0kpCisgICAgICBpZiAoTVZUKCpJKSA9PSBUKQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gTG9vcCBvdmVyIGFsbCBvZiB0aGUgdmFsdWUgdHlwZXMgdGhhdCBjYW4gYmUgcmVwcmVzZW50ZWQgYnkgdmFsdWVzCisgIC8vLyBpbiB0aGUgZ2l2ZW4gcmVnaXN0ZXIgY2xhc3MuCisgIHZ0X2l0ZXJhdG9yIGxlZ2FsY2xhc3N0eXBlc19iZWdpbihjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICZSQykgY29uc3QgeworICAgIHJldHVybiBnZXRSZWdDbGFzc0luZm8oUkMpLlZUTGlzdDsKKyAgfQorCisgIHZ0X2l0ZXJhdG9yIGxlZ2FsY2xhc3N0eXBlc19lbmQoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAmUkMpIGNvbnN0IHsKKyAgICB2dF9pdGVyYXRvciBJID0gbGVnYWxjbGFzc3R5cGVzX2JlZ2luKFJDKTsKKyAgICB3aGlsZSAoKkkgIT0gTVZUOjpPdGhlcikKKyAgICAgICsrSTsKKyAgICByZXR1cm4gSTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRoZSBSZWdpc3RlciBDbGFzcyBvZiBhIHBoeXNpY2FsIHJlZ2lzdGVyIG9mIHRoZSBnaXZlbiB0eXBlLAorICAvLy8gcGlja2luZyB0aGUgbW9zdCBzdWIgcmVnaXN0ZXIgY2xhc3Mgb2YgdGhlIHJpZ2h0IHR5cGUgdGhhdCBjb250YWlucyB0aGlzCisgIC8vLyBwaHlzcmVnLgorICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICoKKyAgICBnZXRNaW5pbWFsUGh5c1JlZ0NsYXNzKHVuc2lnbmVkIFJlZywgTVZUIFZUID0gTVZUOjpPdGhlcikgY29uc3Q7CisKKyAgLy8vIFJldHVybiB0aGUgbWF4aW1hbCBzdWJjbGFzcyBvZiB0aGUgZ2l2ZW4gcmVnaXN0ZXIgY2xhc3MgdGhhdCBpcworICAvLy8gYWxsb2NhdGFibGUgb3IgTlVMTC4KKyAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqCisgICAgZ2V0QWxsb2NhdGFibGVDbGFzcyhjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQykgY29uc3Q7CisKKyAgLy8vIFJldHVybnMgYSBiaXRzZXQgaW5kZXhlZCBieSByZWdpc3RlciBudW1iZXIgaW5kaWNhdGluZyBpZiBhIHJlZ2lzdGVyIGlzCisgIC8vLyBhbGxvY2F0YWJsZSBvciBub3QuIElmIGEgcmVnaXN0ZXIgY2xhc3MgaXMgc3BlY2lmaWVkLCByZXR1cm5zIHRoZSBzdWJzZXQKKyAgLy8vIGZvciB0aGUgY2xhc3MuCisgIEJpdFZlY3RvciBnZXRBbGxvY2F0YWJsZVNldChjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUkMgPSBudWxscHRyKSBjb25zdDsKKworICAvLy8gUmV0dXJuIHRoZSBhZGRpdGlvbmFsIGNvc3Qgb2YgdXNpbmcgdGhpcyByZWdpc3RlciBpbnN0ZWFkCisgIC8vLyBvZiBvdGhlciByZWdpc3RlcnMgaW4gaXRzIGNsYXNzLgorICB1bnNpZ25lZCBnZXRDb3N0UGVyVXNlKHVuc2lnbmVkIFJlZ05vKSBjb25zdCB7CisgICAgcmV0dXJuIEluZm9EZXNjW1JlZ05vXS5Db3N0UGVyVXNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSByZWdpc3RlciBpcyBpbiB0aGUgYWxsb2NhdGlvbiBvZiBhbnkgcmVnaXN0ZXIgY2xhc3MuCisgIGJvb2wgaXNJbkFsbG9jYXRhYmxlQ2xhc3ModW5zaWduZWQgUmVnTm8pIGNvbnN0IHsKKyAgICByZXR1cm4gSW5mb0Rlc2NbUmVnTm9dLmluQWxsb2NhdGFibGVDbGFzczsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIGh1bWFuLXJlYWRhYmxlIHN5bWJvbGljIHRhcmdldC1zcGVjaWZpYworICAvLy8gbmFtZSBmb3IgdGhlIHNwZWNpZmllZCBTdWJSZWdJbmRleC4KKyAgY29uc3QgY2hhciAqZ2V0U3ViUmVnSW5kZXhOYW1lKHVuc2lnbmVkIFN1YklkeCkgY29uc3QgeworICAgIGFzc2VydChTdWJJZHggJiYgU3ViSWR4IDwgZ2V0TnVtU3ViUmVnSW5kaWNlcygpICYmCisgICAgICAgICAgICJUaGlzIGlzIG5vdCBhIHN1YnJlZ2lzdGVyIGluZGV4Iik7CisgICAgcmV0dXJuIFN1YlJlZ0luZGV4TmFtZXNbU3ViSWR4LTFdOworICB9CisKKyAgLy8vIFJldHVybiBhIGJpdG1hc2sgcmVwcmVzZW50aW5nIHRoZSBwYXJ0cyBvZiBhIHJlZ2lzdGVyIHRoYXQgYXJlIGNvdmVyZWQgYnkKKyAgLy8vIFN1YklkeCBcc2VlIExhbmVCaXRtYXNrLgorICAvLy8KKyAgLy8vIFN1YklkeCA9PSAwIGlzIGFsbG93ZWQsIGl0IGhhcyB0aGUgbGFuZSBtYXNrIH4wdS4KKyAgTGFuZUJpdG1hc2sgZ2V0U3ViUmVnSW5kZXhMYW5lTWFzayh1bnNpZ25lZCBTdWJJZHgpIGNvbnN0IHsKKyAgICBhc3NlcnQoU3ViSWR4IDwgZ2V0TnVtU3ViUmVnSW5kaWNlcygpICYmICJUaGlzIGlzIG5vdCBhIHN1YnJlZ2lzdGVyIGluZGV4Iik7CisgICAgcmV0dXJuIFN1YlJlZ0luZGV4TGFuZU1hc2tzW1N1YklkeF07CisgIH0KKworICAvLy8gVGhlIGxhbmUgbWFza3MgcmV0dXJuZWQgYnkgZ2V0U3ViUmVnSW5kZXhMYW5lTWFzaygpIGFib3ZlIGNhbiBvbmx5IGJlCisgIC8vLyB1c2VkIHRvIGRldGVybWluZSBpZiBzdWItcmVnaXN0ZXJzIG92ZXJsYXAgLSB0aGV5IGNhbid0IGJlIHVzZWQgdG8KKyAgLy8vIGRldGVybWluZSBpZiBhIHNldCBvZiBzdWItcmVnaXN0ZXJzIGNvbXBsZXRlbHkgY292ZXIgYW5vdGhlcgorICAvLy8gc3ViLXJlZ2lzdGVyLgorICAvLy8KKyAgLy8vIFRoZSBYODYgZ2VuZXJhbCBwdXJwb3NlIHJlZ2lzdGVycyBoYXZlIHR3byBsYW5lcyBjb3JyZXNwb25kaW5nIHRvIHRoZQorICAvLy8gc3ViXzhiaXQgYW5kIHN1Yl84Yml0X2hpIHN1Yi1yZWdpc3RlcnMuIEJvdGggc3ViXzMyYml0IGFuZCBzdWJfMTZiaXQgaGF2ZQorICAvLy8gbGFuZSBtYXNrcyAnMycsIGJ1dCB0aGUgc3ViXzE2Yml0IHN1Yi1yZWdpc3RlciBkb2Vzbid0IGZ1bGx5IGNvdmVyIHRoZQorICAvLy8gc3ViXzMyYml0IHN1Yi1yZWdpc3Rlci4KKyAgLy8vCisgIC8vLyBPbiB0aGUgb3RoZXIgaGFuZCwgdGhlIEFSTSBORU9OIGxhbmVzIGZ1bGx5IGNvdmVyIHRoZWlyIHJlZ2lzdGVyczogVGhlCisgIC8vLyBkc3ViXzAgc3ViLXJlZ2lzdGVyIGlzIGNvbXBsZXRlbHkgY292ZXJlZCBieSB0aGUgc3N1Yl8wIGFuZCBzc3ViXzEgbGFuZXMuCisgIC8vLyBUaGlzIGlzIHJlbGF0ZWQgdG8gdGhlIENvdmVyZWRCeVN1YlJlZ3MgcHJvcGVydHkgb24gcmVnaXN0ZXIgZGVmaW5pdGlvbnMuCisgIC8vLworICAvLy8gVGhpcyBmdW5jdGlvbiByZXR1cm5zIGEgYml0IG1hc2sgb2YgbGFuZXMgdGhhdCBjb21wbGV0ZWx5IGNvdmVyIHRoZWlyCisgIC8vLyBzdWItcmVnaXN0ZXJzLiBNb3JlIHByZWNpc2VseSwgZ2l2ZW46CisgIC8vLworICAvLy8gICBDb3ZlcmluZyA9IGdldENvdmVyaW5nTGFuZXMoKTsKKyAgLy8vICAgTWFza0EgPSBnZXRTdWJSZWdJbmRleExhbmVNYXNrKFN1YkEpOworICAvLy8gICBNYXNrQiA9IGdldFN1YlJlZ0luZGV4TGFuZU1hc2soU3ViQik7CisgIC8vLworICAvLy8gSWYgKE1hc2tBICYgfihNYXNrQiAmIENvdmVyaW5nKSkgPT0gMCwgdGhlbiBTdWJBIGlzIGNvbXBsZXRlbHkgY292ZXJlZCBieQorICAvLy8gU3ViQi4KKyAgTGFuZUJpdG1hc2sgZ2V0Q292ZXJpbmdMYW5lcygpIGNvbnN0IHsgcmV0dXJuIENvdmVyaW5nTGFuZXM7IH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSB0d28gcmVnaXN0ZXJzIGFyZSBlcXVhbCBvciBhbGlhcyBlYWNoIG90aGVyLgorICAvLy8gVGhlIHJlZ2lzdGVycyBtYXkgYmUgdmlydHVhbCByZWdpc3RlcnMuCisgIGJvb2wgcmVnc092ZXJsYXAodW5zaWduZWQgcmVnQSwgdW5zaWduZWQgcmVnQikgY29uc3QgeworICAgIGlmIChyZWdBID09IHJlZ0IpIHJldHVybiB0cnVlOworICAgIGlmIChpc1ZpcnR1YWxSZWdpc3RlcihyZWdBKSB8fCBpc1ZpcnR1YWxSZWdpc3RlcihyZWdCKSkKKyAgICAgIHJldHVybiBmYWxzZTsKKworICAgIC8vIFJlZ3VuaXRzIGFyZSBudW1lcmljYWxseSBvcmRlcmVkLiBGaW5kIGEgY29tbW9uIHVuaXQuCisgICAgTUNSZWdVbml0SXRlcmF0b3IgUlVBKHJlZ0EsIHRoaXMpOworICAgIE1DUmVnVW5pdEl0ZXJhdG9yIFJVQihyZWdCLCB0aGlzKTsKKyAgICBkbyB7CisgICAgICBpZiAoKlJVQSA9PSAqUlVCKSByZXR1cm4gdHJ1ZTsKKyAgICAgIGlmICgqUlVBIDwgKlJVQikgKytSVUE7CisgICAgICBlbHNlICAgICAgICAgICAgICsrUlVCOworICAgIH0gd2hpbGUgKFJVQS5pc1ZhbGlkKCkgJiYgUlVCLmlzVmFsaWQoKSk7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiBSZWcgY29udGFpbnMgUmVnVW5pdC4KKyAgYm9vbCBoYXNSZWdVbml0KHVuc2lnbmVkIFJlZywgdW5zaWduZWQgUmVnVW5pdCkgY29uc3QgeworICAgIGZvciAoTUNSZWdVbml0SXRlcmF0b3IgVW5pdHMoUmVnLCB0aGlzKTsgVW5pdHMuaXNWYWxpZCgpOyArK1VuaXRzKQorICAgICAgaWYgKCpVbml0cyA9PSBSZWdVbml0KQorICAgICAgICByZXR1cm4gdHJ1ZTsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gUmV0dXJucyB0aGUgb3JpZ2luYWwgU3JjUmVnIHVubGVzcyBpdCBpcyB0aGUgdGFyZ2V0IG9mIGEgY29weS1saWtlCisgIC8vLyBvcGVyYXRpb24sIGluIHdoaWNoIGNhc2Ugd2UgY2hhaW4gYmFja3dhcmRzIHRocm91Z2ggYWxsIHN1Y2ggb3BlcmF0aW9ucworICAvLy8gdG8gdGhlIHVsdGltYXRlIHNvdXJjZSByZWdpc3Rlci4gIElmIGEgcGh5c2ljYWwgcmVnaXN0ZXIgaXMgZW5jb3VudGVyZWQsCisgIC8vLyB3ZSBzdG9wIHRoZSBzZWFyY2guCisgIHZpcnR1YWwgdW5zaWduZWQgbG9va1RocnVDb3B5TGlrZSh1bnNpZ25lZCBTcmNSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICpNUkkpIGNvbnN0OworCisgIC8vLyBSZXR1cm4gYSBudWxsLXRlcm1pbmF0ZWQgbGlzdCBvZiBhbGwgb2YgdGhlIGNhbGxlZS1zYXZlZCByZWdpc3RlcnMgb24KKyAgLy8vIHRoaXMgdGFyZ2V0LiBUaGUgcmVnaXN0ZXIgc2hvdWxkIGJlIGluIHRoZSBvcmRlciBvZiBkZXNpcmVkIGNhbGxlZS1zYXZlCisgIC8vLyBzdGFjayBmcmFtZSBvZmZzZXQuIFRoZSBmaXJzdCByZWdpc3RlciBpcyBjbG9zZXN0IHRvIHRoZSBpbmNvbWluZyBzdGFjaworICAvLy8gcG9pbnRlciBpZiBzdGFjayBncm93cyBkb3duLCBhbmQgdmljZSB2ZXJzYS4KKyAgLy8vIE5vdGljZTogVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCB0YWtlIGludG8gYWNjb3VudCBkaXNhYmxlZCBDU1JzLgorICAvLy8gICAgICAgICBJbiBtb3N0IGNhc2VzIHlvdSB3aWxsIHdhbnQgdG8gdXNlIGluc3RlYWQgdGhlIGZ1bmN0aW9uIAorICAvLy8gICAgICAgICBnZXRDYWxsZWVTYXZlZFJlZ3MgdGhhdCBpcyBpbXBsZW1lbnRlZCBpbiBNYWNoaW5lUmVnaXN0ZXJJbmZvLgorICB2aXJ0dWFsIGNvbnN0IE1DUGh5c1JlZyoKKyAgZ2V0Q2FsbGVlU2F2ZWRSZWdzKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAqTUYpIGNvbnN0ID0gMDsKKworICAvLy8gUmV0dXJuIGEgbWFzayBvZiBjYWxsLXByZXNlcnZlZCByZWdpc3RlcnMgZm9yIHRoZSBnaXZlbiBjYWxsaW5nIGNvbnZlbnRpb24KKyAgLy8vIG9uIHRoZSBjdXJyZW50IGZ1bmN0aW9uLiBUaGUgbWFzayBzaG91bGQgaW5jbHVkZSBhbGwgY2FsbC1wcmVzZXJ2ZWQKKyAgLy8vIGFsaWFzZXMuIFRoaXMgaXMgdXNlZCBieSB0aGUgcmVnaXN0ZXIgYWxsb2NhdG9yIHRvIGRldGVybWluZSB3aGljaAorICAvLy8gcmVnaXN0ZXJzIGNhbiBiZSBsaXZlIGFjcm9zcyBhIGNhbGwuCisgIC8vLworICAvLy8gVGhlIG1hc2sgaXMgYW4gYXJyYXkgY29udGFpbmluZyAoVFJJOjpnZXROdW1SZWdzKCkrMzEpLzMyIGVudHJpZXMuCisgIC8vLyBBIHNldCBiaXQgaW5kaWNhdGVzIHRoYXQgYWxsIGJpdHMgb2YgdGhlIGNvcnJlc3BvbmRpbmcgcmVnaXN0ZXIgYXJlCisgIC8vLyBwcmVzZXJ2ZWQgYWNyb3NzIHRoZSBmdW5jdGlvbiBjYWxsLiAgVGhlIGJpdCBtYXNrIGlzIGV4cGVjdGVkIHRvIGJlCisgIC8vLyBzdWItcmVnaXN0ZXIgY29tcGxldGUsIGkuZS4gaWYgQSBpcyBwcmVzZXJ2ZWQsIHNvIGFyZSBhbGwgaXRzCisgIC8vLyBzdWItcmVnaXN0ZXJzLgorICAvLy8KKyAgLy8vIEJpdHMgYXJlIG51bWJlcmVkIGZyb20gdGhlIExTQiwgc28gdGhlIGJpdCBmb3IgcGh5c2ljYWwgcmVnaXN0ZXIgUmVnIGNhbgorICAvLy8gYmUgZm91bmQgYXMgKE1hc2tbUmVnIC8gMzJdID4+IFJlZyAlIDMyKSAmIDEuCisgIC8vLworICAvLy8gQSBOVUxMIHBvaW50ZXIgbWVhbnMgdGhhdCBubyByZWdpc3RlciBtYXNrIHdpbGwgYmUgdXNlZCwgYW5kIGNhbGwKKyAgLy8vIGluc3RydWN0aW9ucyBzaG91bGQgdXNlIGltcGxpY2l0LWRlZiBvcGVyYW5kcyB0byBpbmRpY2F0ZSBjYWxsIGNsb2JiZXJlZAorICAvLy8gcmVnaXN0ZXJzLgorICAvLy8KKyAgdmlydHVhbCBjb25zdCB1aW50MzJfdCAqZ2V0Q2FsbFByZXNlcnZlZE1hc2soY29uc3QgTWFjaGluZUZ1bmN0aW9uICZNRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2FsbGluZ0NvbnY6OklEKSBjb25zdCB7CisgICAgLy8gVGhlIGRlZmF1bHQgbWFzayBjbG9iYmVycyBldmVyeXRoaW5nLiAgQWxsIHRhcmdldHMgc2hvdWxkIG92ZXJyaWRlLgorICAgIHJldHVybiBudWxscHRyOworICB9CisKKyAgLy8vIFJldHVybiBhIHJlZ2lzdGVyIG1hc2sgdGhhdCBjbG9iYmVycyBldmVyeXRoaW5nLgorICB2aXJ0dWFsIGNvbnN0IHVpbnQzMl90ICpnZXROb1ByZXNlcnZlZE1hc2soKSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgidGFyZ2V0IGRvZXMgbm90IHByb3ZpZGUgbm8gcHJlc2VydmVkIG1hc2siKTsKKyAgfQorCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiBhbGwgYml0cyB0aGF0IGFyZSBzZXQgaW4gbWFzayBccCBtYXNrMCBhcmUgYWxzbyBzZXQgaW4KKyAgLy8vIFxwIG1hc2sxLgorICBib29sIHJlZ21hc2tTdWJzZXRFcXVhbChjb25zdCB1aW50MzJfdCAqbWFzazAsIGNvbnN0IHVpbnQzMl90ICptYXNrMSkgY29uc3Q7CisKKyAgLy8vIFJldHVybiBhbGwgdGhlIGNhbGwtcHJlc2VydmVkIHJlZ2lzdGVyIG1hc2tzIGRlZmluZWQgZm9yIHRoaXMgdGFyZ2V0LgorICB2aXJ0dWFsIEFycmF5UmVmPGNvbnN0IHVpbnQzMl90ICo+IGdldFJlZ01hc2tzKCkgY29uc3QgPSAwOworICB2aXJ0dWFsIEFycmF5UmVmPGNvbnN0IGNoYXIgKj4gZ2V0UmVnTWFza05hbWVzKCkgY29uc3QgPSAwOworCisgIC8vLyBSZXR1cm5zIGEgYml0c2V0IGluZGV4ZWQgYnkgcGh5c2ljYWwgcmVnaXN0ZXIgbnVtYmVyIGluZGljYXRpbmcgaWYgYQorICAvLy8gcmVnaXN0ZXIgaXMgYSBzcGVjaWFsIHJlZ2lzdGVyIHRoYXQgaGFzIHBhcnRpY3VsYXIgdXNlcyBhbmQgc2hvdWxkIGJlCisgIC8vLyBjb25zaWRlcmVkIHVuYXZhaWxhYmxlIGF0IGFsbCB0aW1lcywgZS5nLiBzdGFjayBwb2ludGVyLCByZXR1cm4gYWRkcmVzcy4KKyAgLy8vIEEgcmVzZXJ2ZWQgcmVnaXN0ZXI6CisgIC8vLyAtIGlzIG5vdCBhbGxvY2F0YWJsZQorICAvLy8gLSBpcyBjb25zaWRlcmVkIGFsd2F5cyBsaXZlCisgIC8vLyAtIGlzIGlnbm9yZWQgYnkgbGl2ZW5lc3MgdHJhY2tpbmcKKyAgLy8vIEl0IGlzIG9mdGVuIG5lY2Vzc2FyeSB0byByZXNlcnZlIHRoZSBzdXBlciByZWdpc3RlcnMgb2YgYSByZXNlcnZlZAorICAvLy8gcmVnaXN0ZXIgYXMgd2VsbCwgdG8gYXZvaWQgdGhlbSBnZXR0aW5nIGFsbG9jYXRlZCBpbmRpcmVjdGx5LiBZb3UgbWF5IHVzZQorICAvLy8gbWFya1N1cGVyUmVncygpIGFuZCBjaGVja0FsbFN1cGVyUmVnc01hcmtlZCgpIGluIHRoaXMgY2FzZS4KKyAgdmlydHVhbCBCaXRWZWN0b3IgZ2V0UmVzZXJ2ZWRSZWdzKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0ID0gMDsKKworICAvLy8gUmV0dXJucyB0cnVlIGlmIFBoeXNSZWcgaXMgdW5hbGxvY2F0YWJsZSBhbmQgY29uc3RhbnQgdGhyb3VnaG91dCB0aGUKKyAgLy8vIGZ1bmN0aW9uLiAgVXNlZCBieSBNYWNoaW5lUmVnaXN0ZXJJbmZvOjppc0NvbnN0YW50UGh5c1JlZygpLgorICB2aXJ0dWFsIGJvb2wgaXNDb25zdGFudFBoeXNSZWcodW5zaWduZWQgUGh5c1JlZykgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KKworICAvLy8gUGh5c2ljYWwgcmVnaXN0ZXJzIHRoYXQgbWF5IGJlIG1vZGlmaWVkIHdpdGhpbiBhIGZ1bmN0aW9uIGJ1dCBhcmUKKyAgLy8vIGd1YXJhbnRlZWQgdG8gYmUgcmVzdG9yZWQgYmVmb3JlIGFueSB1c2VzLiBUaGlzIGlzIHVzZWZ1bCBmb3IgdGFyZ2V0cyB0aGF0CisgIC8vLyBoYXZlIGNhbGwgc2VxdWVuY2VzIHdoZXJlIGEgR09UIHJlZ2lzdGVyIG1heSBiZSB1cGRhdGVkIGJ5IHRoZSBjYWxsZXIKKyAgLy8vIHByaW9yIHRvIGEgY2FsbCBhbmQgaXMgZ3VhcmFudGVlZCB0byBiZSByZXN0b3JlZCAoYWxzbyBieSB0aGUgY2FsbGVyKQorICAvLy8gYWZ0ZXIgdGhlIGNhbGwuIAorICB2aXJ0dWFsIGJvb2wgaXNDYWxsZXJQcmVzZXJ2ZWRQaHlzUmVnKHVuc2lnbmVkIFBoeXNSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUZ1bmN0aW9uICZNRikgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBQcmlvciB0byBhZGRpbmcgdGhlIGxpdmUtb3V0IG1hc2sgdG8gYSBzdGFja21hcCBvciBwYXRjaHBvaW50CisgIC8vLyBpbnN0cnVjdGlvbiwgcHJvdmlkZSB0aGUgdGFyZ2V0IHRoZSBvcHBvcnR1bml0eSB0byBhZGp1c3QgaXQgKG1haW5seSB0bworICAvLy8gcmVtb3ZlIHBzZXVkby1yZWdpc3RlcnMgdGhhdCBzaG91bGQgYmUgaWdub3JlZCkuCisgIHZpcnR1YWwgdm9pZCBhZGp1c3RTdGFja01hcExpdmVPdXRNYXNrKHVpbnQzMl90ICpNYXNrKSBjb25zdCB7fQorCisgIC8vLyBSZXR1cm4gYSBzdXBlci1yZWdpc3RlciBvZiB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyCisgIC8vLyBSZWcgc28gaXRzIHN1Yi1yZWdpc3RlciBvZiBpbmRleCBTdWJJZHggaXMgUmVnLgorICB1bnNpZ25lZCBnZXRNYXRjaGluZ1N1cGVyUmVnKHVuc2lnbmVkIFJlZywgdW5zaWduZWQgU3ViSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKSBjb25zdCB7CisgICAgcmV0dXJuIE1DUmVnaXN0ZXJJbmZvOjpnZXRNYXRjaGluZ1N1cGVyUmVnKFJlZywgU3ViSWR4LCBSQy0+TUMpOworICB9CisKKyAgLy8vIFJldHVybiBhIHN1YmNsYXNzIG9mIHRoZSBzcGVjaWZpZWQgcmVnaXN0ZXIKKyAgLy8vIGNsYXNzIEEgc28gdGhhdCBlYWNoIHJlZ2lzdGVyIGluIGl0IGhhcyBhIHN1Yi1yZWdpc3RlciBvZiB0aGUKKyAgLy8vIHNwZWNpZmllZCBzdWItcmVnaXN0ZXIgaW5kZXggd2hpY2ggaXMgaW4gdGhlIHNwZWNpZmllZCByZWdpc3RlciBjbGFzcyBCLgorICAvLy8KKyAgLy8vIFRhYmxlR2VuIHdpbGwgc3ludGhlc2l6ZSBtaXNzaW5nIEEgc3ViLWNsYXNzZXMuCisgIHZpcnR1YWwgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqCisgIGdldE1hdGNoaW5nU3VwZXJSZWdDbGFzcyhjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpBLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqQiwgdW5zaWduZWQgSWR4KSBjb25zdDsKKworICAvLyBGb3IgYSBjb3B5LWxpa2UgaW5zdHJ1Y3Rpb24gdGhhdCBkZWZpbmVzIGEgcmVnaXN0ZXIgb2YgY2xhc3MgRGVmUkMgd2l0aAorICAvLyBzdWJyZWcgaW5kZXggRGVmU3ViUmVnLCByZWFkaW5nIGZyb20gYW5vdGhlciBzb3VyY2Ugd2l0aCBjbGFzcyBTcmNSQyBhbmQKKyAgLy8gc3VicmVnaXN0ZXIgU3JjU3ViUmVnIHJldHVybiB0cnVlIGlmIHRoaXMgaXMgYSBwcmVmZXJhYmxlIGNvcHkKKyAgLy8gaW5zdHJ1Y3Rpb24gb3IgYW4gZWFybGllciB1c2Ugc2hvdWxkIGJlIHVzZWQuCisgIHZpcnR1YWwgYm9vbCBzaG91bGRSZXdyaXRlQ29weVNyYyhjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpEZWZSQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIERlZlN1YlJlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlNyY1JDLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgU3JjU3ViUmVnKSBjb25zdDsKKworICAvLy8gUmV0dXJucyB0aGUgbGFyZ2VzdCBsZWdhbCBzdWItY2xhc3Mgb2YgUkMgdGhhdAorICAvLy8gc3VwcG9ydHMgdGhlIHN1Yi1yZWdpc3RlciBpbmRleCBJZHguCisgIC8vLyBJZiBubyBzdWNoIHN1Yi1jbGFzcyBleGlzdHMsIHJldHVybiBOVUxMLgorICAvLy8gSWYgYWxsIHJlZ2lzdGVycyBpbiBSQyBhbHJlYWR5IGhhdmUgYW4gSWR4IHN1Yi1yZWdpc3RlciwgcmV0dXJuIFJDLgorICAvLy8KKyAgLy8vIFRhYmxlR2VuIGdlbmVyYXRlcyBhIHZlcnNpb24gb2YgdGhpcyBmdW5jdGlvbiB0aGF0IGlzIGdvb2QgZW5vdWdoIGluIG1vc3QKKyAgLy8vIGNhc2VzLiAgVGFyZ2V0cyBjYW4gb3ZlcnJpZGUgaWYgdGhleSBoYXZlIGNvbnN0cmFpbnRzIHRoYXQgVGFibGVHZW4KKyAgLy8vIGRvZXNuJ3QgdW5kZXJzdGFuZC4gIEZvciBleGFtcGxlLCB0aGUgeDg2IHN1Yl84Yml0IHN1Yi1yZWdpc3RlciBpbmRleCBpcworICAvLy8gc3VwcG9ydGVkIGJ5IHRoZSBmdWxsIEdSMzIgcmVnaXN0ZXIgY2xhc3MgaW4gNjQtYml0IG1vZGUsIGJ1dCBvbmx5IGJ5IHRoZQorICAvLy8gR1IzMl9BQkNEIHJlZ2lpc3RlciBjbGFzcyBpbiAzMi1iaXQgbW9kZS4KKyAgLy8vCisgIC8vLyBUYWJsZUdlbiB3aWxsIHN5bnRoZXNpemUgbWlzc2luZyBSQyBzdWItY2xhc3Nlcy4KKyAgdmlydHVhbCBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICoKKyAgZ2V0U3ViQ2xhc3NXaXRoU3ViUmVnKGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDLCB1bnNpZ25lZCBJZHgpIGNvbnN0IHsKKyAgICBhc3NlcnQoSWR4ID09IDAgJiYgIlRhcmdldCBoYXMgbm8gc3ViLXJlZ2lzdGVycyIpOworICAgIHJldHVybiBSQzsKKyAgfQorCisgIC8vLyBSZXR1cm4gdGhlIHN1YnJlZ2lzdGVyIGluZGV4IHlvdSBnZXQgZnJvbSBjb21wb3NpbmcKKyAgLy8vIHR3byBzdWJyZWdpc3RlciBpbmRpY2VzLgorICAvLy8KKyAgLy8vIFRoZSBzcGVjaWFsIG51bGwgc3ViLXJlZ2lzdGVyIGluZGV4IGNvbXBvc2VzIGFzIHRoZSBpZGVudGl0eS4KKyAgLy8vCisgIC8vLyBJZiBSOmE6YiBpcyB0aGUgc2FtZSByZWdpc3RlciBhcyBSOmMsIHRoZW4gY29tcG9zZVN1YlJlZ0luZGljZXMoYSwgYikKKyAgLy8vIHJldHVybnMgYy4gTm90ZSB0aGF0IGNvbXBvc2VTdWJSZWdJbmRpY2VzIGRvZXMgbm90IHRlbGwgeW91IGFib3V0IGlsbGVnYWwKKyAgLy8vIGNvbXBvc2l0aW9ucy4gSWYgUiBkb2VzIG5vdCBoYXZlIGEgc3VicmVnIGEsIG9yIFI6YSBkb2VzIG5vdCBoYXZlIGEgc3VicmVnCisgIC8vLyBiLCBjb21wb3NlU3ViUmVnSW5kaWNlcyBkb2Vzbid0IHRlbGwgeW91LgorICAvLy8KKyAgLy8vIFRoZSBBUk0gcmVnaXN0ZXIgUTAgaGFzIHR3byBEIHN1YnJlZ3MgZHN1Yl8wOkQwIGFuZCBkc3ViXzE6RDEuIEl0IGFsc28gaGFzCisgIC8vLyBzc3ViXzA6UzAgLSBzc3ViXzM6UzMgc3VicmVncy4KKyAgLy8vIElmIHlvdSBjb21wb3NlIHN1YnJlZyBpbmRpY2VzIGRzdWJfMSwgc3N1Yl8wIHlvdSBnZXQgc3N1Yl8yLgorICB1bnNpZ25lZCBjb21wb3NlU3ViUmVnSW5kaWNlcyh1bnNpZ25lZCBhLCB1bnNpZ25lZCBiKSBjb25zdCB7CisgICAgaWYgKCFhKSByZXR1cm4gYjsKKyAgICBpZiAoIWIpIHJldHVybiBhOworICAgIHJldHVybiBjb21wb3NlU3ViUmVnSW5kaWNlc0ltcGwoYSwgYik7CisgIH0KKworICAvLy8gVHJhbnNmb3JtcyBhIExhbmVNYXNrIGNvbXB1dGVkIGZvciBvbmUgc3VicmVnaXN0ZXIgdG8gdGhlIGxhbmVtYXNrIHRoYXQKKyAgLy8vIHdvdWxkIGhhdmUgYmVlbiBjb21wdXRlZCB3aGVuIGNvbXBvc2luZyB0aGUgc3Vic3VicmVnaXN0ZXJzIHdpdGggSWR4QQorICAvLy8gZmlyc3QuIEBzYSBjb21wb3NlU3ViUmVnSW5kaWNlcygpCisgIExhbmVCaXRtYXNrIGNvbXBvc2VTdWJSZWdJbmRleExhbmVNYXNrKHVuc2lnbmVkIElkeEEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhbmVCaXRtYXNrIE1hc2spIGNvbnN0IHsKKyAgICBpZiAoIUlkeEEpCisgICAgICByZXR1cm4gTWFzazsKKyAgICByZXR1cm4gY29tcG9zZVN1YlJlZ0luZGV4TGFuZU1hc2tJbXBsKElkeEEsIE1hc2spOworICB9CisKKyAgLy8vIFRyYW5zZm9ybSBhIGxhbmVtYXNrIGdpdmVuIGZvciBhIHZpcnR1YWwgcmVnaXN0ZXIgdG8gdGhlIGNvcnJlc3BvbmRpbmcKKyAgLy8vIGxhbmVtYXNrIGJlZm9yZSB1c2luZyBzdWJyZWdpc3RlciB3aXRoIGluZGV4IFxwIElkeEEuCisgIC8vLyBUaGlzIGlzIHRoZSByZXZlcnNlIG9mIGNvbXBvc2VTdWJSZWdJbmRleExhbmVNYXNrKCksIGFzc3VtaW5nIE1hc2sgaXMgYQorICAvLy8gdmFsaWUgbGFuZSBtYXNrIChubyBpbnZhbGlkIGJpdHMgc2V0KSB0aGUgZm9sbG93aW5nIGhvbGRzOgorICAvLy8gWDAgPSBjb21wb3NlU3ViUmVnSW5kZXhMYW5lTWFzayhJZHgsIE1hc2spCisgIC8vLyBYMSA9IHJldmVyc2VDb21wb3NlU3ViUmVnSW5kZXhMYW5lTWFzayhJZHgsIFgwKQorICAvLy8gPT4gWDEgPT0gTWFzaworICBMYW5lQml0bWFzayByZXZlcnNlQ29tcG9zZVN1YlJlZ0luZGV4TGFuZU1hc2sodW5zaWduZWQgSWR4QSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExhbmVCaXRtYXNrIExhbmVNYXNrKSBjb25zdCB7CisgICAgaWYgKCFJZHhBKQorICAgICAgcmV0dXJuIExhbmVNYXNrOworICAgIHJldHVybiByZXZlcnNlQ29tcG9zZVN1YlJlZ0luZGV4TGFuZU1hc2tJbXBsKElkeEEsIExhbmVNYXNrKTsKKyAgfQorCisgIC8vLyBEZWJ1Z2dpbmcgaGVscGVyOiBkdW1wIHJlZ2lzdGVyIGluIGh1bWFuIHJlYWRhYmxlIGZvcm0gdG8gZGJncygpIHN0cmVhbS4KKyAgc3RhdGljIHZvaWQgZHVtcFJlZyh1bnNpZ25lZCBSZWcsIHVuc2lnbmVkIFN1YlJlZ0luZGV4ID0gMCwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8qIFRSSSA9IG51bGxwdHIpOworCitwcm90ZWN0ZWQ6CisgIC8vLyBPdmVycmlkZGVuIGJ5IFRhYmxlR2VuIGluIHRhcmdldHMgdGhhdCBoYXZlIHN1Yi1yZWdpc3RlcnMuCisgIHZpcnR1YWwgdW5zaWduZWQgY29tcG9zZVN1YlJlZ0luZGljZXNJbXBsKHVuc2lnbmVkLCB1bnNpZ25lZCkgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIlRhcmdldCBoYXMgbm8gc3ViLXJlZ2lzdGVycyIpOworICB9CisKKyAgLy8vIE92ZXJyaWRkZW4gYnkgVGFibGVHZW4gaW4gdGFyZ2V0cyB0aGF0IGhhdmUgc3ViLXJlZ2lzdGVycy4KKyAgdmlydHVhbCBMYW5lQml0bWFzaworICBjb21wb3NlU3ViUmVnSW5kZXhMYW5lTWFza0ltcGwodW5zaWduZWQsIExhbmVCaXRtYXNrKSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgiVGFyZ2V0IGhhcyBubyBzdWItcmVnaXN0ZXJzIik7CisgIH0KKworICB2aXJ0dWFsIExhbmVCaXRtYXNrIHJldmVyc2VDb21wb3NlU3ViUmVnSW5kZXhMYW5lTWFza0ltcGwodW5zaWduZWQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMYW5lQml0bWFzaykgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIlRhcmdldCBoYXMgbm8gc3ViLXJlZ2lzdGVycyIpOworICB9CisKK3B1YmxpYzoKKyAgLy8vIEZpbmQgYSBjb21tb24gc3VwZXItcmVnaXN0ZXIgY2xhc3MgaWYgaXQgZXhpc3RzLgorICAvLy8KKyAgLy8vIEZpbmQgYSByZWdpc3RlciBjbGFzcywgU3VwZXJSQyBhbmQgdHdvIHN1Yi1yZWdpc3RlciBpbmRpY2VzLCBQcmVBIGFuZAorICAvLy8gUHJlQiwgc3VjaCB0aGF0OgorICAvLy8KKyAgLy8vICAgMS4gUHJlQSArIFN1YkEgPT0gUHJlQiArIFN1YkIgICh1c2luZyBjb21wb3NlU3ViUmVnSW5kaWNlcygpKSwgYW5kCisgIC8vLworICAvLy8gICAyLiBGb3IgYWxsIFJlZyBpbiBTdXBlclJDOiBSZWc6UHJlQSBpbiBSQ0EgYW5kIFJlZzpQcmVCIGluIFJDQiwgYW5kCisgIC8vLworICAvLy8gICAzLiBTdXBlclJDLT5nZXRTaXplKCkgPj0gbWF4KFJDQS0+Z2V0U2l6ZSgpLCBSQ0ItPmdldFNpemUoKSkuCisgIC8vLworICAvLy8gU3VwZXJSQyB3aWxsIGJlIGNob3NlbiBzdWNoIHRoYXQgbm8gc3VwZXItY2xhc3Mgb2YgU3VwZXJSQyBzYXRpc2ZpZXMgdGhlCisgIC8vLyByZXF1aXJlbWVudHMsIGFuZCB0aGVyZSBpcyBubyByZWdpc3RlciBjbGFzcyB3aXRoIGEgc21hbGxlciBzcGlsbCBzaXplCisgIC8vLyB0aGF0IHNhdGlzZmllcyB0aGUgcmVxdWlyZW1lbnRzLgorICAvLy8KKyAgLy8vIFN1YkEgYW5kIFN1YkIgbXVzdCBub3QgYmUgMC4gVXNlIGdldE1hdGNoaW5nU3VwZXJSZWdDbGFzcygpIGluc3RlYWQuCisgIC8vLworICAvLy8gRWl0aGVyIG9mIHRoZSBQcmVBIGFuZCBQcmVCIHN1Yi1yZWdpc3RlciBpbmRpY2VzIG1heSBiZSByZXR1cm5lZCBhcyAwLiBJbgorICAvLy8gdGhhdCBjYXNlLCB0aGUgcmV0dXJuZWQgcmVnaXN0ZXIgY2xhc3Mgd2lsbCBiZSBhIHN1Yi1jbGFzcyBvZiB0aGUKKyAgLy8vIGNvcnJlc3BvbmRpbmcgYXJndW1lbnQgcmVnaXN0ZXIgY2xhc3MuCisgIC8vLworICAvLy8gVGhlIGZ1bmN0aW9uIHJldHVybnMgTlVMTCBpZiBubyByZWdpc3RlciBjbGFzcyBjYW4gYmUgZm91bmQuCisgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MqCisgIGdldENvbW1vblN1cGVyUmVnQ2xhc3MoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqUkNBLCB1bnNpZ25lZCBTdWJBLAorICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDQiwgdW5zaWduZWQgU3ViQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCAmUHJlQSwgdW5zaWduZWQgJlByZUIpIGNvbnN0OworCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLyBSZWdpc3RlciBDbGFzcyBJbmZvcm1hdGlvbgorICAvLworcHJvdGVjdGVkOgorICBjb25zdCBSZWdDbGFzc0luZm8gJmdldFJlZ0NsYXNzSW5mbyhjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICZSQykgY29uc3QgeworICAgIHJldHVybiBSQ0luZm9zW2dldE51bVJlZ0NsYXNzZXMoKSAqIEh3TW9kZSArIFJDLmdldElEKCldOworICB9CisKK3B1YmxpYzoKKyAgLy8vIFJlZ2lzdGVyIGNsYXNzIGl0ZXJhdG9ycworICByZWdjbGFzc19pdGVyYXRvciByZWdjbGFzc19iZWdpbigpIGNvbnN0IHsgcmV0dXJuIFJlZ0NsYXNzQmVnaW47IH0KKyAgcmVnY2xhc3NfaXRlcmF0b3IgcmVnY2xhc3NfZW5kKCkgY29uc3QgeyByZXR1cm4gUmVnQ2xhc3NFbmQ7IH0KKyAgaXRlcmF0b3JfcmFuZ2U8cmVnY2xhc3NfaXRlcmF0b3I+IHJlZ2NsYXNzZXMoKSBjb25zdCB7CisgICAgcmV0dXJuIG1ha2VfcmFuZ2UocmVnY2xhc3NfYmVnaW4oKSwgcmVnY2xhc3NfZW5kKCkpOworICB9CisKKyAgdW5zaWduZWQgZ2V0TnVtUmVnQ2xhc3NlcygpIGNvbnN0IHsKKyAgICByZXR1cm4gKHVuc2lnbmVkKShyZWdjbGFzc19lbmQoKS1yZWdjbGFzc19iZWdpbigpKTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRoZSByZWdpc3RlciBjbGFzcyBhc3NvY2lhdGVkIHdpdGggdGhlIGVudW1lcmF0aW9uIHZhbHVlLgorICAvLy8gU2VlIGNsYXNzIE1DT3BlcmFuZEluZm8uCisgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKmdldFJlZ0NsYXNzKHVuc2lnbmVkIGkpIGNvbnN0IHsKKyAgICBhc3NlcnQoaSA8IGdldE51bVJlZ0NsYXNzZXMoKSAmJiAiUmVnaXN0ZXIgQ2xhc3MgSUQgb3V0IG9mIHJhbmdlIik7CisgICAgcmV0dXJuIFJlZ0NsYXNzQmVnaW5baV07CisgIH0KKworICAvLy8gUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgcmVnaXN0ZXIgY2xhc3MuCisgIGNvbnN0IGNoYXIgKmdldFJlZ0NsYXNzTmFtZShjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpDbGFzcykgY29uc3QgeworICAgIHJldHVybiBNQ1JlZ2lzdGVySW5mbzo6Z2V0UmVnQ2xhc3NOYW1lKENsYXNzLT5NQyk7CisgIH0KKworICAvLy8gRmluZCB0aGUgbGFyZ2VzdCBjb21tb24gc3ViY2xhc3Mgb2YgQSBhbmQgQi4KKyAgLy8vIFJldHVybiBOVUxMIGlmIHRoZXJlIGlzIG5vIGNvbW1vbiBzdWJjbGFzcy4KKyAgLy8vIFRoZSBjb21tb24gc3ViY2xhc3Mgc2hvdWxkIGNvbnRhaW4KKyAgLy8vIHNpbXBsZSB2YWx1ZSB0eXBlIFNWVCBpZiBpdCBpcyBub3QgdGhlIEFueSB0eXBlLgorICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICoKKyAgZ2V0Q29tbW9uU3ViQ2xhc3MoY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqQSwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqQiwKKyAgICAgICAgICAgICAgICAgICAgY29uc3QgTVZUOjpTaW1wbGVWYWx1ZVR5cGUgU1ZUID0KKyAgICAgICAgICAgICAgICAgICAgTVZUOjpTaW1wbGVWYWx1ZVR5cGU6OkFueSkgY29uc3Q7CisKKyAgLy8vIFJldHVybnMgYSBUYXJnZXRSZWdpc3RlckNsYXNzIHVzZWQgZm9yIHBvaW50ZXIgdmFsdWVzLgorICAvLy8gSWYgYSB0YXJnZXQgc3VwcG9ydHMgbXVsdGlwbGUgZGlmZmVyZW50IHBvaW50ZXIgcmVnaXN0ZXIgY2xhc3NlcywKKyAgLy8vIGtpbmQgc3BlY2lmaWVzIHdoaWNoIG9uZSBpcyBpbmRpY2F0ZWQuCisgIHZpcnR1YWwgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqCisgIGdldFBvaW50ZXJSZWdDbGFzcyhjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GLCB1bnNpZ25lZCBLaW5kPTApIGNvbnN0IHsKKyAgICBsbHZtX3VucmVhY2hhYmxlKCJUYXJnZXQgZGlkbid0IGltcGxlbWVudCBnZXRQb2ludGVyUmVnQ2xhc3MhIik7CisgIH0KKworICAvLy8gUmV0dXJucyBhIGxlZ2FsIHJlZ2lzdGVyIGNsYXNzIHRvIGNvcHkgYSByZWdpc3RlciBpbiB0aGUgc3BlY2lmaWVkIGNsYXNzCisgIC8vLyB0byBvciBmcm9tLiBJZiBpdCBpcyBwb3NzaWJsZSB0byBjb3B5IHRoZSByZWdpc3RlciBkaXJlY3RseSB3aXRob3V0IHVzaW5nCisgIC8vLyBhIGNyb3NzIHJlZ2lzdGVyIGNsYXNzIGNvcHksIHJldHVybiB0aGUgc3BlY2lmaWVkIFJDLiBSZXR1cm5zIE5VTEwgaWYgaXQKKyAgLy8vIGlzIG5vdCBwb3NzaWJsZSB0byBjb3B5IGJldHdlZW4gdHdvIHJlZ2lzdGVycyBvZiB0aGUgc3BlY2lmaWVkIGNsYXNzLgorICB2aXJ0dWFsIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKgorICBnZXRDcm9zc0NvcHlSZWdDbGFzcyhjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQykgY29uc3QgeworICAgIHJldHVybiBSQzsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRoZSBsYXJnZXN0IHN1cGVyIGNsYXNzIG9mIFJDIHRoYXQgaXMgbGVnYWwgdG8gdXNlIGluIHRoZSBjdXJyZW50CisgIC8vLyBzdWItdGFyZ2V0IGFuZCBoYXMgdGhlIHNhbWUgc3BpbGwgc2l6ZS4KKyAgLy8vIFRoZSByZXR1cm5lZCByZWdpc3RlciBjbGFzcyBjYW4gYmUgdXNlZCB0byBjcmVhdGUgdmlydHVhbCByZWdpc3RlcnMgd2hpY2gKKyAgLy8vIG1lYW5zIHRoYXQgYWxsIGl0cyByZWdpc3RlcnMgY2FuIGJlIGNvcGllZCBhbmQgc3BpbGxlZC4KKyAgdmlydHVhbCBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICoKKyAgZ2V0TGFyZ2VzdExlZ2FsU3VwZXJDbGFzcyhjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNYWNoaW5lRnVuY3Rpb24gJikgY29uc3QgeworICAgIC8vLyBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBpcyB2ZXJ5IGNvbnNlcnZhdGl2ZSBhbmQgZG9lc24ndCBhbGxvdyB0aGUKKyAgICAvLy8gcmVnaXN0ZXIgYWxsb2NhdG9yIHRvIGluZmxhdGUgcmVnaXN0ZXIgY2xhc3Nlcy4KKyAgICByZXR1cm4gUkM7CisgIH0KKworICAvLy8gUmV0dXJuIHRoZSByZWdpc3RlciBwcmVzc3VyZSAiaGlnaCB3YXRlciBtYXJrIiBmb3IgdGhlIHNwZWNpZmljIHJlZ2lzdGVyCisgIC8vLyBjbGFzcy4gVGhlIHNjaGVkdWxlciBpcyBpbiBoaWdoIHJlZ2lzdGVyIHByZXNzdXJlIG1vZGUgKGZvciB0aGUgc3BlY2lmaWMKKyAgLy8vIHJlZ2lzdGVyIGNsYXNzKSBpZiBpdCBnb2VzIG92ZXIgdGhlIGxpbWl0LgorICAvLy8KKyAgLy8vIE5vdGU6IHRoaXMgaXMgdGhlIG9sZCByZWdpc3RlciBwcmVzc3VyZSBtb2RlbCB0aGF0IHJlbGllcyBvbiBhIG1hbnVhbGx5CisgIC8vLyBzcGVjaWZpZWQgcmVwcmVzZW50YXRpdmUgcmVnaXN0ZXIgY2xhc3MgcGVyIHZhbHVlIHR5cGUuCisgIHZpcnR1YWwgdW5zaWduZWQgZ2V0UmVnUHJlc3N1cmVMaW1pdChjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0IHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIC8vLyBSZXR1cm4gYSBoZXVyaXN0aWMgZm9yIHRoZSBtYWNoaW5lIHNjaGVkdWxlciB0byBjb21wYXJlIHRoZSBwcm9maXRhYmlsaXR5CisgIC8vLyBvZiBpbmNyZWFzaW5nIG9uZSByZWdpc3RlciBwcmVzc3VyZSBzZXQgdmVyc3VzIGFub3RoZXIuICBUaGUgc2NoZWR1bGVyCisgIC8vLyB3aWxsIHByZWZlciBpbmNyZWFzaW5nIHRoZSByZWdpc3RlciBwcmVzc3VyZSBvZiB0aGUgc2V0IHdoaWNoIHJldHVybnMKKyAgLy8vIHRoZSBsYXJnZXN0IHZhbHVlIGZvciB0aGlzIGZ1bmN0aW9uLgorICB2aXJ0dWFsIHVuc2lnbmVkIGdldFJlZ1ByZXNzdXJlU2V0U2NvcmUoY29uc3QgTWFjaGluZUZ1bmN0aW9uICZNRiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFBTZXRJRCkgY29uc3QgeworICAgIHJldHVybiBQU2V0SUQ7CisgIH0KKworICAvLy8gR2V0IHRoZSB3ZWlnaHQgaW4gdW5pdHMgb2YgcHJlc3N1cmUgZm9yIHRoaXMgcmVnaXN0ZXIgY2xhc3MuCisgIHZpcnR1YWwgY29uc3QgUmVnQ2xhc3NXZWlnaHQgJmdldFJlZ0NsYXNzV2VpZ2h0KAorICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKSBjb25zdCA9IDA7CisKKyAgLy8vIFJldHVybnMgc2l6ZSBpbiBiaXRzIG9mIGEgcGh5cy92aXJ0dWFsL2dlbmVyaWMgcmVnaXN0ZXIuCisgIHVuc2lnbmVkIGdldFJlZ1NpemVJbkJpdHModW5zaWduZWQgUmVnLCBjb25zdCBNYWNoaW5lUmVnaXN0ZXJJbmZvICZNUkkpIGNvbnN0OworCisgIC8vLyBHZXQgdGhlIHdlaWdodCBpbiB1bml0cyBvZiBwcmVzc3VyZSBmb3IgdGhpcyByZWdpc3RlciB1bml0LgorICB2aXJ0dWFsIHVuc2lnbmVkIGdldFJlZ1VuaXRXZWlnaHQodW5zaWduZWQgUmVnVW5pdCkgY29uc3QgPSAwOworCisgIC8vLyBHZXQgdGhlIG51bWJlciBvZiBkaW1lbnNpb25zIG9mIHJlZ2lzdGVyIHByZXNzdXJlLgorICB2aXJ0dWFsIHVuc2lnbmVkIGdldE51bVJlZ1ByZXNzdXJlU2V0cygpIGNvbnN0ID0gMDsKKworICAvLy8gR2V0IHRoZSBuYW1lIG9mIHRoaXMgcmVnaXN0ZXIgdW5pdCBwcmVzc3VyZSBzZXQuCisgIHZpcnR1YWwgY29uc3QgY2hhciAqZ2V0UmVnUHJlc3N1cmVTZXROYW1lKHVuc2lnbmVkIElkeCkgY29uc3QgPSAwOworCisgIC8vLyBHZXQgdGhlIHJlZ2lzdGVyIHVuaXQgcHJlc3N1cmUgbGltaXQgZm9yIHRoaXMgZGltZW5zaW9uLgorICAvLy8gVGhpcyBsaW1pdCBtdXN0IGJlIGFkanVzdGVkIGR5bmFtaWNhbGx5IGZvciByZXNlcnZlZCByZWdpc3RlcnMuCisgIHZpcnR1YWwgdW5zaWduZWQgZ2V0UmVnUHJlc3N1cmVTZXRMaW1pdChjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgSWR4KSBjb25zdCA9IDA7CisKKyAgLy8vIEdldCB0aGUgZGltZW5zaW9ucyBvZiByZWdpc3RlciBwcmVzc3VyZSBpbXBhY3RlZCBieSB0aGlzIHJlZ2lzdGVyIGNsYXNzLgorICAvLy8gUmV0dXJucyBhIC0xIHRlcm1pbmF0ZWQgYXJyYXkgb2YgcHJlc3N1cmUgc2V0IElEcy4KKyAgdmlydHVhbCBjb25zdCBpbnQgKmdldFJlZ0NsYXNzUHJlc3N1cmVTZXRzKAorICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKSBjb25zdCA9IDA7CisKKyAgLy8vIEdldCB0aGUgZGltZW5zaW9ucyBvZiByZWdpc3RlciBwcmVzc3VyZSBpbXBhY3RlZCBieSB0aGlzIHJlZ2lzdGVyIHVuaXQuCisgIC8vLyBSZXR1cm5zIGEgLTEgdGVybWluYXRlZCBhcnJheSBvZiBwcmVzc3VyZSBzZXQgSURzLgorICB2aXJ0dWFsIGNvbnN0IGludCAqZ2V0UmVnVW5pdFByZXNzdXJlU2V0cyh1bnNpZ25lZCBSZWdVbml0KSBjb25zdCA9IDA7CisKKyAgLy8vIEdldCBhIGxpc3Qgb2YgJ2hpbnQnIHJlZ2lzdGVycyB0aGF0IHRoZSByZWdpc3RlciBhbGxvY2F0b3Igc2hvdWxkIHRyeQorICAvLy8gZmlyc3Qgd2hlbiBhbGxvY2F0aW5nIGEgcGh5c2ljYWwgcmVnaXN0ZXIgZm9yIHRoZSB2aXJ0dWFsIHJlZ2lzdGVyCisgIC8vLyBWaXJ0UmVnLiBUaGVzZSByZWdpc3RlcnMgYXJlIGVmZmVjdGl2ZWx5IG1vdmVkIHRvIHRoZSBmcm9udCBvZiB0aGUKKyAgLy8vIGFsbG9jYXRpb24gb3JkZXIuIElmIHRydWUgaXMgcmV0dXJuZWQsIHJlZ2FsbG9jIHdpbGwgdHJ5IHRvIG9ubHkgdXNlCisgIC8vLyBoaW50cyB0byB0aGUgZ3JlYXRlc3QgZXh0ZW50IHBvc3NpYmxlIGV2ZW4gaWYgaXQgbWVhbnMgc3BpbGxpbmcuCisgIC8vLworICAvLy8gVGhlIE9yZGVyIGFyZ3VtZW50IGlzIHRoZSBhbGxvY2F0aW9uIG9yZGVyIGZvciBWaXJ0UmVnJ3MgcmVnaXN0ZXIgY2xhc3MKKyAgLy8vIGFzIHJldHVybmVkIGZyb20gUmVnaXN0ZXJDbGFzc0luZm86OmdldE9yZGVyKCkuIFRoZSBoaW50IHJlZ2lzdGVycyBtdXN0CisgIC8vLyBjb21lIGZyb20gT3JkZXIsIGFuZCB0aGV5IG11c3Qgbm90IGJlIHJlc2VydmVkLgorICAvLy8KKyAgLy8vIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIG9mIHRoaXMgZnVuY3Rpb24gd2lsbCBvbmx5IGFkZCB0YXJnZXQKKyAgLy8vIGluZGVwZW5kZW50IHJlZ2lzdGVyIGFsbG9jYXRpb24gaGludHMuIFRhcmdldHMgdGhhdCBvdmVycmlkZSB0aGlzCisgIC8vLyBmdW5jdGlvbiBzaG91bGQgdHlwaWNhbGx5IGNhbGwgdGhpcyBkZWZhdWx0IGltcGxlbWVudGF0aW9uIGFzIHdlbGwgYW5kCisgIC8vLyBleHBlY3QgdG8gc2VlIGdlbmVyaWMgY29weSBoaW50cyBhZGRlZC4KKyAgdmlydHVhbCBib29sIGdldFJlZ0FsbG9jYXRpb25IaW50cyh1bnNpZ25lZCBWaXJ0UmVnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPE1DUGh5c1JlZz4gT3JkZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU21hbGxWZWN0b3JJbXBsPE1DUGh5c1JlZz4gJkhpbnRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVmlydFJlZ01hcCAqVlJNID0gbnVsbHB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMaXZlUmVnTWF0cml4ICpNYXRyaXggPSBudWxscHRyKQorICAgIGNvbnN0OworCisgIC8vLyBBIGNhbGxiYWNrIHRvIGFsbG93IHRhcmdldCBhIGNoYW5jZSB0byB1cGRhdGUgcmVnaXN0ZXIgYWxsb2NhdGlvbiBoaW50cworICAvLy8gd2hlbiBhIHJlZ2lzdGVyIGlzICJjaGFuZ2VkIiAoZS5nLiBjb2FsZXNjZWQpIHRvIGFub3RoZXIgcmVnaXN0ZXIuCisgIC8vLyBlLmcuIE9uIEFSTSwgc29tZSB2aXJ0dWFsIHJlZ2lzdGVycyBzaG91bGQgdGFyZ2V0IHJlZ2lzdGVyIHBhaXJzLAorICAvLy8gaWYgb25lIG9mIHBhaXIgaXMgY29hbGVzY2VkIHRvIGFub3RoZXIgcmVnaXN0ZXIsIHRoZSBhbGxvY2F0aW9uIGhpbnQgb2YKKyAgLy8vIHRoZSBvdGhlciBoYWxmIG9mIHRoZSBwYWlyIHNob3VsZCBiZSBjaGFuZ2VkIHRvIHBvaW50IHRvIHRoZSBuZXcgcmVnaXN0ZXIuCisgIHZpcnR1YWwgdm9pZCB1cGRhdGVSZWdBbGxvY0hpbnQodW5zaWduZWQgUmVnLCB1bnNpZ25lZCBOZXdSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUZ1bmN0aW9uICZNRikgY29uc3QgeworICAgIC8vIERvIG5vdGhpbmcuCisgIH0KKworICAvLy8gVGhlIGNyZWF0aW9uIG9mIG11bHRpcGxlIGNvcHkgaGludHMgaGF2ZSBiZWVuIGltcGxlbWVudGVkIGluCisgIC8vLyB3ZWlnaHRDYWxjSGVscGVyKCksIGJ1dCBzaW5jZSB0aGlzIGFmZmVjdHMgc28gbWFueSB0ZXN0cyBmb3IgbWFueQorICAvLy8gdGFyZ2V0cywgdGhpcyBpcyB0ZW1wb3JhcmlseSBkaXNhYmxlZCBwZXIgZGVmYXVsdC4gVEhJUyBTSE9VTEQgQkUKKyAgLy8vICJHRU5FUkFMIEdPT0RORVNTIiBhbmQgaG9wZWZ1bGx5IGFsbCB0YXJnZXRzIHdpbGwgdXBkYXRlIHRoZWlyIHRlc3RzCisgIC8vLyBhbmQgZW5hYmxlIHRoaXMgc29vbi4gVGhpcyBob29rIHNob3VsZCB0aGVuIGJlIHJlbW92ZWQuCisgIHZpcnR1YWwgYm9vbCBlbmFibGVNdWx0aXBsZUNvcHlIaW50cygpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgLy8vIEFsbG93IHRoZSB0YXJnZXQgdG8gcmV2ZXJzZSBhbGxvY2F0aW9uIG9yZGVyIG9mIGxvY2FsIGxpdmUgcmFuZ2VzLiBUaGlzCisgIC8vLyB3aWxsIGdlbmVyYWxseSBhbGxvY2F0ZSBzaG9ydGVyIGxvY2FsIGxpdmUgcmFuZ2VzIGZpcnN0LiBGb3IgdGFyZ2V0cyB3aXRoCisgIC8vLyBtYW55IHJlZ2lzdGVycywgdGhpcyBjb3VsZCByZWR1Y2UgcmVnYWxsb2MgY29tcGlsZSB0aW1lIGJ5IGEgbGFyZ2UKKyAgLy8vIGZhY3Rvci4gSXQgaXMgZGlzYWJsZWQgYnkgZGVmYXVsdCBmb3IgdGhyZWUgcmVhc29uczoKKyAgLy8vICgxKSBUb3AtZG93biBhbGxvY2F0aW9uIGlzIHNpbXBsZXIgYW5kIGVhc2llciB0byBkZWJ1ZyBmb3IgdGFyZ2V0cyB0aGF0CisgIC8vLyBkb24ndCBiZW5lZml0IGZyb20gcmV2ZXJzaW5nIHRoZSBvcmRlci4KKyAgLy8vICgyKSBCb3R0b20tdXAgYWxsb2NhdGlvbiBjb3VsZCByZXN1bHQgaW4gcG9vciBldmljaXRpb24gZGVjaXNpb25zIG9uIHNvbWUKKyAgLy8vIHRhcmdldHMgYWZmZWN0aW5nIHRoZSBwZXJmb3JtYW5jZSBvZiBjb21waWxlZCBjb2RlLgorICAvLy8gKDMpIEJvdHRvbS11cCBhbGxvY2F0aW9uIGlzIG5vIGxvbmdlciBndWFyYW50ZWVkIHRvIG9wdGltYWxseSBjb2xvci4KKyAgdmlydHVhbCBib29sIHJldmVyc2VMb2NhbEFzc2lnbm1lbnQoKSBjb25zdCB7IHJldHVybiBmYWxzZTsgfQorCisgIC8vLyBBbGxvdyB0aGUgdGFyZ2V0IHRvIG92ZXJyaWRlIHRoZSBjb3N0IG9mIHVzaW5nIGEgY2FsbGVlLXNhdmVkIHJlZ2lzdGVyIGZvcgorICAvLy8gdGhlIGZpcnN0IHRpbWUuIERlZmF1bHQgdmFsdWUgb2YgMCBtZWFucyB3ZSB3aWxsIHVzZSBhIGNhbGxlZS1zYXZlZAorICAvLy8gcmVnaXN0ZXIgaWYgaXQgaXMgYXZhaWxhYmxlLgorICB2aXJ0dWFsIHVuc2lnbmVkIGdldENTUkZpcnN0VXNlQ29zdCgpIGNvbnN0IHsgcmV0dXJuIDA7IH0KKworICAvLy8gUmV0dXJucyB0cnVlIGlmIHRoZSB0YXJnZXQgcmVxdWlyZXMgKGFuZCBjYW4gbWFrZSB1c2Ugb2YpIHRoZSByZWdpc3RlcgorICAvLy8gc2NhdmVuZ2VyLgorICB2aXJ0dWFsIGJvb2wgcmVxdWlyZXNSZWdpc3RlclNjYXZlbmdpbmcoY29uc3QgTWFjaGluZUZ1bmN0aW9uICZNRikgY29uc3QgeworICAgIHJldHVybiBmYWxzZTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIHRhcmdldCB3YW50cyB0byB1c2UgZnJhbWUgcG9pbnRlciBiYXNlZCBhY2Nlc3NlcyB0bworICAvLy8gc3BpbGwgdG8gdGhlIHNjYXZlbmdlciBlbWVyZ2VuY3kgc3BpbGwgc2xvdC4KKyAgdmlydHVhbCBib29sIHVzZUZQRm9yU2NhdmVuZ2luZ0luZGV4KGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0IHsKKyAgICByZXR1cm4gdHJ1ZTsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIHRhcmdldCByZXF1aXJlcyBwb3N0IFBFSSBzY2F2ZW5naW5nIG9mIHJlZ2lzdGVycyBmb3IKKyAgLy8vIG1hdGVyaWFsaXppbmcgZnJhbWUgaW5kZXggY29uc3RhbnRzLgorICB2aXJ0dWFsIGJvb2wgcmVxdWlyZXNGcmFtZUluZGV4U2NhdmVuZ2luZyhjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgdGFyZ2V0IHJlcXVpcmVzIHVzaW5nIHRoZSBSZWdTY2F2ZW5nZXIgZGlyZWN0bHkgZm9yCisgIC8vLyBmcmFtZSBlbGltaW5hdGlvbiBkZXNwaXRlIHVzaW5nIHJlcXVpcmVzRnJhbWVJbmRleFNjYXZlbmdpbmcuCisgIHZpcnR1YWwgYm9vbCByZXF1aXJlc0ZyYW1lSW5kZXhSZXBsYWNlbWVudFNjYXZlbmdpbmcoCisgICAgICBjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgdGFyZ2V0IHdhbnRzIHRoZSBMb2NhbFN0YWNrQWxsb2NhdGlvbiBwYXNzIHRvIGJlIHJ1bgorICAvLy8gYW5kIHZpcnR1YWwgYmFzZSByZWdpc3RlcnMgdXNlZCBmb3IgbW9yZSBlZmZpY2llbnQgc3RhY2sgYWNjZXNzLgorICB2aXJ0dWFsIGJvb2wgcmVxdWlyZXNWaXJ0dWFsQmFzZVJlZ2lzdGVycyhjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybiB0cnVlIGlmIHRhcmdldCBoYXMgcmVzZXJ2ZWQgYSBzcGlsbCBzbG90IGluIHRoZSBzdGFjayBmcmFtZSBvZgorICAvLy8gdGhlIGdpdmVuIGZ1bmN0aW9uIGZvciB0aGUgc3BlY2lmaWVkIHJlZ2lzdGVyLiBlLmcuIE9uIHg4NiwgaWYgdGhlIGZyYW1lCisgIC8vLyByZWdpc3RlciBpcyByZXF1aXJlZCwgdGhlIGZpcnN0IGZpeGVkIHN0YWNrIG9iamVjdCBpcyByZXNlcnZlZCBhcyBpdHMKKyAgLy8vIHNwaWxsIHNsb3QuIFRoaXMgdGVsbHMgUEVJIG5vdCB0byBjcmVhdGUgYSBuZXcgc3RhY2sgZnJhbWUKKyAgLy8vIG9iamVjdCBmb3IgdGhlIGdpdmVuIHJlZ2lzdGVyLiBJdCBzaG91bGQgYmUgY2FsbGVkIG9ubHkgYWZ0ZXIKKyAgLy8vIGRldGVybWluZUNhbGxlZVNhdmVzKCkuCisgIHZpcnR1YWwgYm9vbCBoYXNSZXNlcnZlZFNwaWxsU2xvdChjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GLCB1bnNpZ25lZCBSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgJkZyYW1lSWR4KSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgbGl2ZS1pbnMgc2hvdWxkIGJlIHRyYWNrZWQgYWZ0ZXIgcmVnaXN0ZXIgYWxsb2NhdGlvbi4KKyAgdmlydHVhbCBib29sIHRyYWNrTGl2ZW5lc3NBZnRlclJlZ0FsbG9jKGNvbnN0IE1hY2hpbmVGdW5jdGlvbiAmTUYpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gVHJ1ZSBpZiB0aGUgc3RhY2sgY2FuIGJlIHJlYWxpZ25lZCBmb3IgdGhlIHRhcmdldC4KKyAgdmlydHVhbCBib29sIGNhblJlYWxpZ25TdGFjayhjb25zdCBNYWNoaW5lRnVuY3Rpb24gJk1GKSBjb25zdDsKKworICAvLy8gVHJ1ZSBpZiBzdG9yYWdlIHdpdGhpbiB0aGUgZnVuY3Rpb24gcmVxdWlyZXMgdGhlIHN0YWNrIHBvaW50ZXIgdG8gYmUKKyAgLy8vIGFsaWduZWQgbW9yZSB0aGFuIHRoZSBub3JtYWwgY2FsbGluZyBjb252ZW50aW9uIGNhbGxzIGZvci4KKyAgLy8vIFRoaXMgY2Fubm90IGJlIG92ZXJyaWRlbiBieSB0aGUgdGFyZ2V0LCBidXQgY2FuUmVhbGlnblN0YWNrIGNhbiBiZQorICAvLy8gb3ZlcnJpZGRlbi4KKyAgYm9vbCBuZWVkc1N0YWNrUmVhbGlnbm1lbnQoY29uc3QgTWFjaGluZUZ1bmN0aW9uICZNRikgY29uc3Q7CisKKyAgLy8vIEdldCB0aGUgb2Zmc2V0IGZyb20gdGhlIHJlZmVyZW5jZWQgZnJhbWUgaW5kZXggaW4gdGhlIGluc3RydWN0aW9uLAorICAvLy8gaWYgdGhlcmUgaXMgb25lLgorICB2aXJ0dWFsIGludDY0X3QgZ2V0RnJhbWVJbmRleEluc3RyT2Zmc2V0KGNvbnN0IE1hY2hpbmVJbnN0ciAqTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IElkeCkgY29uc3QgeworICAgIHJldHVybiAwOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgaW5zdHJ1Y3Rpb24ncyBmcmFtZSBpbmRleCByZWZlcmVuY2Ugd291bGQgYmUgYmV0dGVyCisgIC8vLyBzZXJ2ZWQgYnkgYSBiYXNlIHJlZ2lzdGVyIG90aGVyIHRoYW4gRlAgb3IgU1AuCisgIC8vLyBVc2VkIGJ5IExvY2FsU3RhY2tGcmFtZUFsbG9jYXRpb24gdG8gZGV0ZXJtaW5lIHdoaWNoIGZyYW1lIGluZGV4CisgIC8vLyByZWZlcmVuY2VzIGl0IHNob3VsZCBjcmVhdGUgbmV3IGJhc2UgcmVnaXN0ZXJzIGZvci4KKyAgdmlydHVhbCBib29sIG5lZWRzRnJhbWVCYXNlUmVnKE1hY2hpbmVJbnN0ciAqTUksIGludDY0X3QgT2Zmc2V0KSBjb25zdCB7CisgICAgcmV0dXJuIGZhbHNlOworICB9CisKKyAgLy8vIEluc2VydCBkZWZpbmluZyBpbnN0cnVjdGlvbihzKSBmb3IgQmFzZVJlZyB0byBiZSBhIHBvaW50ZXIgdG8gRnJhbWVJZHgKKyAgLy8vIGJlZm9yZSBpbnNlcnRpb24gcG9pbnQgSS4KKyAgdmlydHVhbCB2b2lkIG1hdGVyaWFsaXplRnJhbWVCYXNlUmVnaXN0ZXIoTWFjaGluZUJhc2ljQmxvY2sgKk1CQiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgQmFzZVJlZywgaW50IEZyYW1lSWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NF90IE9mZnNldCkgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoIm1hdGVyaWFsaXplRnJhbWVCYXNlUmVnaXN0ZXIgZG9lcyBub3QgZXhpc3Qgb24gdGhpcyAiCisgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0Iik7CisgIH0KKworICAvLy8gUmVzb2x2ZSBhIGZyYW1lIGluZGV4IG9wZXJhbmQgb2YgYW4gaW5zdHJ1Y3Rpb24KKyAgLy8vIHRvIHJlZmVyZW5jZSB0aGUgaW5kaWNhdGVkIGJhc2UgcmVnaXN0ZXIgcGx1cyBvZmZzZXQgaW5zdGVhZC4KKyAgdmlydHVhbCB2b2lkIHJlc29sdmVGcmFtZUluZGV4KE1hY2hpbmVJbnN0ciAmTUksIHVuc2lnbmVkIEJhc2VSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQ2NF90IE9mZnNldCkgY29uc3QgeworICAgIGxsdm1fdW5yZWFjaGFibGUoInJlc29sdmVGcmFtZUluZGV4IGRvZXMgbm90IGV4aXN0IG9uIHRoaXMgdGFyZ2V0Iik7CisgIH0KKworICAvLy8gRGV0ZXJtaW5lIHdoZXRoZXIgYSBnaXZlbiBiYXNlIHJlZ2lzdGVyIHBsdXMgb2Zmc2V0IGltbWVkaWF0ZSBpcworICAvLy8gZW5jb2RhYmxlIHRvIHJlc29sdmUgYSBmcmFtZSBpbmRleC4KKyAgdmlydHVhbCBib29sIGlzRnJhbWVPZmZzZXRMZWdhbChjb25zdCBNYWNoaW5lSW5zdHIgKk1JLCB1bnNpZ25lZCBCYXNlUmVnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDY0X3QgT2Zmc2V0KSBjb25zdCB7CisgICAgbGx2bV91bnJlYWNoYWJsZSgiaXNGcmFtZU9mZnNldExlZ2FsIGRvZXMgbm90IGV4aXN0IG9uIHRoaXMgdGFyZ2V0Iik7CisgIH0KKworICAvLy8gU3BpbGwgdGhlIHJlZ2lzdGVyIHNvIGl0IGNhbiBiZSB1c2VkIGJ5IHRoZSByZWdpc3RlciBzY2F2ZW5nZXIuCisgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgcmVnaXN0ZXIgd2FzIHNwaWxsZWQsIGZhbHNlIG90aGVyd2lzZS4KKyAgLy8vIElmIHRoaXMgZnVuY3Rpb24gZG9lcyBub3Qgc3BpbGwgdGhlIHJlZ2lzdGVyLCB0aGUgc2NhdmVuZ2VyCisgIC8vLyB3aWxsIGluc3RlYWQgc3BpbGwgaXQgdG8gdGhlIGVtZXJnZW5jeSBzcGlsbCBzbG90LgorICB2aXJ0dWFsIGJvb2wgc2F2ZVNjYXZlbmdlclJlZ2lzdGVyKE1hY2hpbmVCYXNpY0Jsb2NrICZNQkIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIEksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yICZVc2VNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpSQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBSZWcpIGNvbnN0IHsKKyAgICByZXR1cm4gZmFsc2U7CisgIH0KKworICAvLy8gVGhpcyBtZXRob2QgbXVzdCBiZSBvdmVycmlkZW4gdG8gZWxpbWluYXRlIGFic3RyYWN0IGZyYW1lIGluZGljZXMgZnJvbQorICAvLy8gaW5zdHJ1Y3Rpb25zIHdoaWNoIG1heSB1c2UgdGhlbS4gVGhlIGluc3RydWN0aW9uIHJlZmVyZW5jZWQgYnkgdGhlCisgIC8vLyBpdGVyYXRvciBjb250YWlucyBhbiBNT19GcmFtZUluZGV4IG9wZXJhbmQgd2hpY2ggbXVzdCBiZSBlbGltaW5hdGVkIGJ5CisgIC8vLyB0aGlzIG1ldGhvZC4gVGhpcyBtZXRob2QgbWF5IG1vZGlmeSBvciByZXBsYWNlIHRoZSBzcGVjaWZpZWQgaW5zdHJ1Y3Rpb24sCisgIC8vLyBhcyBsb25nIGFzIGl0IGtlZXBzIHRoZSBpdGVyYXRvciBwb2ludGluZyBhdCB0aGUgZmluaXNoZWQgcHJvZHVjdC4KKyAgLy8vIFNQQWRqIGlzIHRoZSBTUCBhZGp1c3RtZW50IGR1ZSB0byBjYWxsIGZyYW1lIHNldHVwIGluc3RydWN0aW9uLgorICAvLy8gRklPcGVyYW5kTnVtIGlzIHRoZSBGSSBvcGVyYW5kIG51bWJlci4KKyAgdmlydHVhbCB2b2lkIGVsaW1pbmF0ZUZyYW1lSW5kZXgoTWFjaGluZUJhc2ljQmxvY2s6Oml0ZXJhdG9yIE1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgU1BBZGosIHVuc2lnbmVkIEZJT3BlcmFuZE51bSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVnU2NhdmVuZ2VyICpSUyA9IG51bGxwdHIpIGNvbnN0ID0gMDsKKworICAvLy8gUmV0dXJuIHRoZSBhc3NlbWJseSBuYW1lIGZvciBccCBSZWcuCisgIHZpcnR1YWwgU3RyaW5nUmVmIGdldFJlZ0FzbU5hbWUodW5zaWduZWQgUmVnKSBjb25zdCB7CisgICAgLy8gRklYTUU6IFdlIGFyZSBhc3N1bWluZyB0aGF0IHRoZSBhc3NlbWJseSBuYW1lIGlzIGVxdWFsIHRvIHRoZSBUYWJsZUdlbgorICAgIC8vIG5hbWUgY29udmVydGVkIHRvIGxvd2VyIGNhc2UKKyAgICAvLworICAgIC8vIFRoZSBUYWJsZUdlbiBuYW1lIGlzIHRoZSBuYW1lIG9mIHRoZSBkZWZpbml0aW9uIGZvciB0aGlzIHJlZ2lzdGVyIGluIHRoZQorICAgIC8vIHRhcmdldCdzIHRhYmxlZ2VuIGZpbGVzLiAgRm9yIGV4YW1wbGUsIHRoZSBUYWJsZUdlbiBuYW1lIG9mCisgICAgLy8gZGVmIEVBWCA6IFJlZ2lzdGVyIDwuLi4+OyBpcyAiRUFYIgorICAgIHJldHVybiBTdHJpbmdSZWYoZ2V0TmFtZShSZWcpKTsKKyAgfQorCisgIC8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworICAvLy8gU3VidGFyZ2V0IEhvb2tzCisKKyAgLy8vIFxicmllZiBTcmNSQyBhbmQgRHN0UkMgd2lsbCBiZSBtb3JwaGVkIGludG8gTmV3UkMgaWYgdGhpcyByZXR1cm5zIHRydWUuCisgIHZpcnR1YWwgYm9vbCBzaG91bGRDb2FsZXNjZShNYWNoaW5lSW5zdHIgKk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJDbGFzcyAqU3JjUkMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBTdWJSZWcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRSZWdpc3RlckNsYXNzICpEc3RSQywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIERzdFN1YlJlZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKk5ld1JDLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGl2ZUludGVydmFscyAmTElTKSBjb25zdAorICB7IHJldHVybiB0cnVlOyB9CisKKyAgLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisgIC8vLyBEZWJ1ZyBpbmZvcm1hdGlvbiBxdWVyaWVzLgorCisgIC8vLyBnZXRGcmFtZVJlZ2lzdGVyIC0gVGhpcyBtZXRob2Qgc2hvdWxkIHJldHVybiB0aGUgcmVnaXN0ZXIgdXNlZCBhcyBhIGJhc2UKKyAgLy8vIGZvciB2YWx1ZXMgYWxsb2NhdGVkIGluIHRoZSBjdXJyZW50IHN0YWNrIGZyYW1lLgorICB2aXJ0dWFsIHVuc2lnbmVkIGdldEZyYW1lUmVnaXN0ZXIoY29uc3QgTWFjaGluZUZ1bmN0aW9uICZNRikgY29uc3QgPSAwOworCisgIC8vLyBNYXJrIGEgcmVnaXN0ZXIgYW5kIGFsbCBpdHMgYWxpYXNlcyBhcyByZXNlcnZlZCBpbiB0aGUgZ2l2ZW4gc2V0LgorICB2b2lkIG1hcmtTdXBlclJlZ3MoQml0VmVjdG9yICZSZWdpc3RlclNldCwgdW5zaWduZWQgUmVnKSBjb25zdDsKKworICAvLy8gUmV0dXJucyB0cnVlIGlmIGZvciBldmVyeSByZWdpc3RlciBpbiB0aGUgc2V0IGFsbCBzdXBlciByZWdpc3RlcnMgYXJlIHBhcnQKKyAgLy8vIG9mIHRoZSBzZXQgYXMgd2VsbC4KKyAgYm9vbCBjaGVja0FsbFN1cGVyUmVnc01hcmtlZChjb25zdCBCaXRWZWN0b3IgJlJlZ2lzdGVyU2V0LAorICAgICAgQXJyYXlSZWY8TUNQaHlzUmVnPiBFeGNlcHRpb25zID0gQXJyYXlSZWY8TUNQaHlzUmVnPigpKSBjb25zdDsKK307CisKKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgIFN1cGVyUmVnQ2xhc3NJdGVyYXRvcgorLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vCisvLyBJdGVyYXRlIG92ZXIgdGhlIHBvc3NpYmxlIHN1cGVyLXJlZ2lzdGVycyBmb3IgYSBnaXZlbiByZWdpc3RlciBjbGFzcy4gVGhlCisvLyBpdGVyYXRvciB3aWxsIHZpc2l0IGEgbGlzdCBvZiBwYWlycyAoSWR4LCBNYXNrKSBjb3JyZXNwb25kaW5nIHRvIHRoZQorLy8gcG9zc2libGUgY2xhc3NlcyBvZiBzdXBlci1yZWdpc3RlcnMuCisvLworLy8gRWFjaCBiaXQgbWFzayB3aWxsIGhhdmUgYXQgbGVhc3Qgb25lIHNldCBiaXQsIGFuZCBlYWNoIHNldCBiaXQgaW4gTWFzaworLy8gY29ycmVzcG9uZHMgdG8gYSBTdXBlclJDIHN1Y2ggdGhhdDoKKy8vCisvLyAgIEZvciBhbGwgUmVnIGluIFN1cGVyUkM6IFJlZzpJZHggaXMgaW4gUkMuCisvLworLy8gVGhlIGl0ZXJhdG9yIGNhbiBpbmNsdWRlIChPLCBSQy0+Z2V0U3ViQ2xhc3NNYXNrKCkpIGFzIHRoZSBmaXJzdCBlbnRyeSB3aGljaAorLy8gYWxzbyBzYXRpc2ZpZXMgdGhlIGFib3ZlIHJlcXVpcmVtZW50LCBhc3N1bWluZyBSZWc6MCA9PSBSZWcuCisvLworY2xhc3MgU3VwZXJSZWdDbGFzc0l0ZXJhdG9yIHsKKyAgY29uc3QgdW5zaWduZWQgUkNNYXNrV29yZHM7CisgIHVuc2lnbmVkIFN1YlJlZyA9IDA7CisgIGNvbnN0IHVpbnQxNl90ICpJZHg7CisgIGNvbnN0IHVpbnQzMl90ICpNYXNrOworCitwdWJsaWM6CisgIC8vLyBDcmVhdGUgYSBTdXBlclJlZ0NsYXNzSXRlcmF0b3IgdGhhdCB2aXNpdHMgYWxsIHRoZSBzdXBlci1yZWdpc3RlciBjbGFzc2VzCisgIC8vLyBvZiBSQy4gV2hlbiBJbmNsdWRlU2VsZiBpcyBzZXQsIGFsc28gaW5jbHVkZSB0aGUgKDAsIHN1Yi1jbGFzc2VzKSBlbnRyeS4KKyAgU3VwZXJSZWdDbGFzc0l0ZXJhdG9yKGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkksCisgICAgICAgICAgICAgICAgICAgICAgICBib29sIEluY2x1ZGVTZWxmID0gZmFsc2UpCisgICAgOiBSQ01hc2tXb3JkcygoVFJJLT5nZXROdW1SZWdDbGFzc2VzKCkgKyAzMSkgLyAzMiksCisgICAgICBJZHgoUkMtPmdldFN1cGVyUmVnSW5kaWNlcygpKSwgTWFzayhSQy0+Z2V0U3ViQ2xhc3NNYXNrKCkpIHsKKyAgICBpZiAoIUluY2x1ZGVTZWxmKQorICAgICAgKysqdGhpczsKKyAgfQorCisgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBpdGVyYXRvciBpcyBzdGlsbCBwb2ludGluZyBhdCBhIHZhbGlkIGVudHJ5LgorICBib29sIGlzVmFsaWQoKSBjb25zdCB7IHJldHVybiBJZHg7IH0KKworICAvLy8gUmV0dXJucyB0aGUgY3VycmVudCBzdWItcmVnaXN0ZXIgaW5kZXguCisgIHVuc2lnbmVkIGdldFN1YlJlZygpIGNvbnN0IHsgcmV0dXJuIFN1YlJlZzsgfQorCisgIC8vLyBSZXR1cm5zIHRoZSBiaXQgbWFzayBvZiByZWdpc3RlciBjbGFzc2VzIHRoYXQgZ2V0U3ViUmVnKCkgcHJvamVjdHMgaW50bworICAvLy8gUkMuCisgIC8vLyBTZWUgVGFyZ2V0UmVnaXN0ZXJDbGFzczo6Z2V0U3ViQ2xhc3NNYXNrKCkgZm9yIGhvdyB0byB1c2UgaXQuCisgIGNvbnN0IHVpbnQzMl90ICpnZXRNYXNrKCkgY29uc3QgeyByZXR1cm4gTWFzazsgfQorCisgIC8vLyBBZHZhbmNlIGl0ZXJhdG9yIHRvIHRoZSBuZXh0IGVudHJ5LgorICB2b2lkIG9wZXJhdG9yKysoKSB7CisgICAgYXNzZXJ0KGlzVmFsaWQoKSAmJiAiQ2Fubm90IG1vdmUgaXRlcmF0b3IgcGFzdCBlbmQuIik7CisgICAgTWFzayArPSBSQ01hc2tXb3JkczsKKyAgICBTdWJSZWcgPSAqSWR4Kys7CisgICAgaWYgKCFTdWJSZWcpCisgICAgICBJZHggPSBudWxscHRyOworICB9Cit9OworCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICBCaXRNYXNrQ2xhc3NJdGVyYXRvcgorLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKy8vLyBUaGlzIGNsYXNzIGVuY2FwdXNsYXRlcyB0aGUgbG9naWMgdG8gaXRlcmF0ZSBvdmVyIGJpdG1hc2sgcmV0dXJuZWQgYnkKKy8vLyB0aGUgdmFyaW91cyBSZWdDbGFzcyByZWxhdGVkIEFQSXMuCisvLy8gRS5nLiwgdGhpcyBjbGFzcyBjYW4gYmUgdXNlZCB0byBpdGVyYXRlIG92ZXIgdGhlIHN1YmNsYXNzZXMgcHJvdmlkZWQgYnkKKy8vLyBUYXJnZXRSZWdpc3RlckNsYXNzOjpnZXRTdWJDbGFzc01hc2sgb3IgU3VwZXJSZWdDbGFzc0l0ZXJhdG9yOjpnZXRNYXNrLgorY2xhc3MgQml0TWFza0NsYXNzSXRlcmF0b3IgeworICAvLy8gVG90YWwgbnVtYmVyIG9mIHJlZ2lzdGVyIGNsYXNzZXMuCisgIGNvbnN0IHVuc2lnbmVkIE51bVJlZ0NsYXNzZXM7CisgIC8vLyBCYXNlIGluZGV4IG9mIEN1cnJlbnRDaHVuay4KKyAgLy8vIEluIG90aGVyIHdvcmRzLCB0aGUgbnVtYmVyIG9mIGJpdCB3ZSByZWFkIHRvIGdldCBhdCB0aGUKKyAgLy8vIGJlZ2lubmluZyBvZiB0aGF0IGNodW5jay4KKyAgdW5zaWduZWQgQmFzZSA9IDA7CisgIC8vLyBBZGp1c3QgYmFzZSBpbmRleCBvZiBDdXJyZW50Q2h1bmsuCisgIC8vLyBCYXNlIGluZGV4ICsgaG93IG1hbnkgYml0IHdlIHJlYWQgd2l0aGluIEN1cnJlbnRDaHVuay4KKyAgdW5zaWduZWQgSWR4ID0gMDsKKyAgLy8vIEN1cnJlbnQgcmVnaXN0ZXIgY2xhc3MgSUQuCisgIHVuc2lnbmVkIElEID0gMDsKKyAgLy8vIE1hc2sgd2UgYXJlIGl0ZXJhdGluZyBvdmVyLgorICBjb25zdCB1aW50MzJfdCAqTWFzazsKKyAgLy8vIEN1cnJlbnQgY2h1bmsgb2YgdGhlIE1hc2sgd2UgYXJlIHRyYXZlcnNpbmcuCisgIHVpbnQzMl90IEN1cnJlbnRDaHVuazsKKworICAvLy8gTW92ZSBJRCB0byB0aGUgbmV4dCBzZXQgYml0LgorICB2b2lkIG1vdmVUb05leHRJRCgpIHsKKyAgICAvLyBJZiB0aGUgY3VycmVudCBjaHVuayBvZiBtZW1vcnkgaXMgZW1wdHksIG1vdmUgdG8gdGhlIG5leHQgb25lLAorICAgIC8vIHdoaWxlIG1ha2luZyBzdXJlIHdlIGRvIG5vdCBnbyBwYXNzIHRoZSBudW1iZXIgb2YgcmVnaXN0ZXIKKyAgICAvLyBjbGFzc2VzLgorICAgIHdoaWxlICghQ3VycmVudENodW5rKSB7CisgICAgICAvLyBNb3ZlIHRvIHRoZSBuZXh0IGNodW5rLgorICAgICAgQmFzZSArPSAzMjsKKyAgICAgIGlmIChCYXNlID49IE51bVJlZ0NsYXNzZXMpIHsKKyAgICAgICAgSUQgPSBOdW1SZWdDbGFzc2VzOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBDdXJyZW50Q2h1bmsgPSAqKytNYXNrOworICAgICAgSWR4ID0gQmFzZTsKKyAgICB9CisgICAgLy8gT3RoZXJ3aXNlIGxvb2sgZm9yIHRoZSBmaXJzdCBiaXQgc2V0IGZyb20gdGhlIHJpZ2h0CisgICAgLy8gKHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjbGFzcyBJRCBpcyBiaWcgZW5kaWFuKS4KKyAgICAvLyBTZWUgZ2V0U3ViQ2xhc3NNYXNrIGZvciBtb3JlIGRldGFpbHMgb24gdGhlIHJlcHJlc2VudGF0aW9uLgorICAgIHVuc2lnbmVkIE9mZnNldCA9IGNvdW50VHJhaWxpbmdaZXJvcyhDdXJyZW50Q2h1bmspOworICAgIC8vIEFkZCB0aGUgT2Zmc2V0IHRvIHRoZSBhZGp1c3RlZCBiYXNlIG51bWJlciBvZiB0aGlzIGNodW5rOiBJZHguCisgICAgLy8gVGhpcyBpcyB0aGUgSUQgb2YgdGhlIHJlZ2lzdGVyIGNsYXNzLgorICAgIElEID0gSWR4ICsgT2Zmc2V0OworCisgICAgLy8gQ29uc3VtZSB0aGUgemVyb3MsIGlmIGFueSwgYW5kIHRoZSBiaXQgd2UganVzdCByZWFkCisgICAgLy8gc28gdGhhdCB3ZSBhcmUgYXQgdGhlIHJpZ2h0IHNwb3QgZm9yIHRoZSBuZXh0IGNhbGwuCisgICAgLy8gRG8gbm90IGRvIE9mZnNldCArIDEgYmVjYXVzZSBPZmZzZXQgbWF5IGJlIDMxIGFuZCAzMgorICAgIC8vIHdpbGwgYmUgVUIgZm9yIHRoZSBzaGlmdCwgdGhvdWdoIGluIHRoYXQgY2FzZSB3ZSBjb3VsZAorICAgIC8vIGhhdmUgbWFrZSB0aGUgY2h1bmsgYmVpbmcgZXF1YWwgdG8gMCwgYnV0IHRoYXQgd291bGQKKyAgICAvLyBoYXZlIGludHJvZHVjZWQgYSBpZiBzdGF0ZW1lbnQuCisgICAgbW92ZU5CaXRzKE9mZnNldCk7CisgICAgbW92ZU5CaXRzKDEpOworICB9CisKKyAgLy8vIE1vdmUgXHAgTnVtQml0cyBCaXRzIGZvcndhcmQgaW4gQ3VycmVudENodW5rLgorICB2b2lkIG1vdmVOQml0cyh1bnNpZ25lZCBOdW1CaXRzKSB7CisgICAgYXNzZXJ0KE51bUJpdHMgPCAzMiAmJiAiVW5kZWZpbmVkIGJlaGF2aW9yIHNwb3R0ZWQhIik7CisgICAgLy8gQ29uc3VtZSB0aGUgYml0IHdlIHJlYWQgZm9yIHRoZSBuZXh0IGNhbGwuCisgICAgQ3VycmVudENodW5rID4+PSBOdW1CaXRzOworICAgIC8vIEFkanVzdCB0aGUgYmFzZSBmb3IgdGhlIGNodW5rLgorICAgIElkeCArPSBOdW1CaXRzOworICB9CisKK3B1YmxpYzoKKyAgLy8vIENyZWF0ZSBhIEJpdE1hc2tDbGFzc0l0ZXJhdG9yIHRoYXQgdmlzaXRzIGFsbCB0aGUgcmVnaXN0ZXIgY2xhc3NlcworICAvLy8gcmVwcmVzZW50ZWQgYnkgXHAgTWFzay4KKyAgLy8vCisgIC8vLyBccHJlIFxwIE1hc2sgIT0gbnVsbHB0cgorICBCaXRNYXNrQ2xhc3NJdGVyYXRvcihjb25zdCB1aW50MzJfdCAqTWFzaywgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICZUUkkpCisgICAgICA6IE51bVJlZ0NsYXNzZXMoVFJJLmdldE51bVJlZ0NsYXNzZXMoKSksIE1hc2soTWFzayksIEN1cnJlbnRDaHVuaygqTWFzaykgeworICAgIC8vIE1vdmUgdG8gdGhlIGZpcnN0IElELgorICAgIG1vdmVUb05leHRJRCgpOworICB9CisKKyAgLy8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGl0ZXJhdG9yIGlzIHN0aWxsIHBvaW50aW5nIGF0IGEgdmFsaWQgZW50cnkuCisgIGJvb2wgaXNWYWxpZCgpIGNvbnN0IHsgcmV0dXJuIGdldElEKCkgIT0gTnVtUmVnQ2xhc3NlczsgfQorCisgIC8vLyBSZXR1cm5zIHRoZSBjdXJyZW50IHJlZ2lzdGVyIGNsYXNzIElELgorICB1bnNpZ25lZCBnZXRJRCgpIGNvbnN0IHsgcmV0dXJuIElEOyB9CisKKyAgLy8vIEFkdmFuY2UgaXRlcmF0b3IgdG8gdGhlIG5leHQgZW50cnkuCisgIHZvaWQgb3BlcmF0b3IrKygpIHsKKyAgICBhc3NlcnQoaXNWYWxpZCgpICYmICJDYW5ub3QgbW92ZSBpdGVyYXRvciBwYXN0IGVuZC4iKTsKKyAgICBtb3ZlVG9OZXh0SUQoKTsKKyAgfQorfTsKKworLy8gVGhpcyBpcyB1c2VmdWwgd2hlbiBidWlsZGluZyBJbmRleGVkTWFwcyBrZXllZCBvbiB2aXJ0dWFsIHJlZ2lzdGVycworc3RydWN0IFZpcnRSZWcySW5kZXhGdW5jdG9yIHsKKyAgdXNpbmcgYXJndW1lbnRfdHlwZSA9IHVuc2lnbmVkOworICB1bnNpZ25lZCBvcGVyYXRvcigpKHVuc2lnbmVkIFJlZykgY29uc3QgeworICAgIHJldHVybiBUYXJnZXRSZWdpc3RlckluZm86OnZpcnRSZWcySW5kZXgoUmVnKTsKKyAgfQorfTsKKworLy8vIFByaW50cyB2aXJ0dWFsIGFuZCBwaHlzaWNhbCByZWdpc3RlcnMgd2l0aCBvciB3aXRob3V0IGEgVFJJIGluc3RhbmNlLgorLy8vCisvLy8gVGhlIGZvcm1hdCBpczoKKy8vLyAgICVub3JlZyAgICAgICAgICAtIE5vUmVnaXN0ZXIKKy8vLyAgICU1ICAgICAgICAgICAgICAtIGEgdmlydHVhbCByZWdpc3Rlci4KKy8vLyAgICU1OnN1Yl84Yml0ICAgICAtIGEgdmlydHVhbCByZWdpc3RlciB3aXRoIHN1Yi1yZWdpc3RlciBpbmRleCAod2l0aCBUUkkpLgorLy8vICAgJWVheCAgICAgICAgICAgIC0gYSBwaHlzaWNhbCByZWdpc3RlcgorLy8vICAgJXBoeXNyZWcxNyAgICAgIC0gYSBwaHlzaWNhbCByZWdpc3RlciB3aGVuIG5vIFRSSSBpbnN0YW5jZSBnaXZlbi4KKy8vLworLy8vIFVzYWdlOiBPUyA8PCBwcmludFJlZyhSZWcsIFRSSSwgU3ViUmVnSWR4KSA8PCAnXG4nOworUHJpbnRhYmxlIHByaW50UmVnKHVuc2lnbmVkIFJlZywgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpUUkkgPSBudWxscHRyLAorICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIFN1YlJlZ0lkeCA9IDAsCisgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAqTVJJID0gbnVsbHB0cik7CisKKy8vLyBDcmVhdGUgUHJpbnRhYmxlIG9iamVjdCB0byBwcmludCByZWdpc3RlciB1bml0cyBvbiBhIFxyZWYgcmF3X29zdHJlYW0uCisvLy8KKy8vLyBSZWdpc3RlciB1bml0cyBhcmUgbmFtZWQgYWZ0ZXIgdGhlaXIgcm9vdCByZWdpc3RlcnM6CisvLy8KKy8vLyAgIGFsICAgICAgLSBTaW5nbGUgcm9vdC4KKy8vLyAgIGZwMH5zdDcgLSBEdWFsIHJvb3RzLgorLy8vCisvLy8gVXNhZ2U6IE9TIDw8IHByaW50UmVnVW5pdChVbml0LCBUUkkpIDw8ICdcbic7CitQcmludGFibGUgcHJpbnRSZWdVbml0KHVuc2lnbmVkIFVuaXQsIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJKTsKKworLy8vIFxicmllZiBDcmVhdGUgUHJpbnRhYmxlIG9iamVjdCB0byBwcmludCB2aXJ0dWFsIHJlZ2lzdGVycyBhbmQgcGh5c2ljYWwKKy8vLyByZWdpc3RlcnMgb24gYSBccmVmIHJhd19vc3RyZWFtLgorUHJpbnRhYmxlIHByaW50VlJlZ09yVW5pdCh1bnNpZ25lZCBWUmVnT3JVbml0LCBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSSk7CisKKy8vLyBcYnJpZWYgQ3JlYXRlIFByaW50YWJsZSBvYmplY3QgdG8gcHJpbnQgcmVnaXN0ZXIgY2xhc3NlcyBvciByZWdpc3RlciBiYW5rcworLy8vIG9uIGEgXHJlZiByYXdfb3N0cmVhbS4KK1ByaW50YWJsZSBwcmludFJlZ0NsYXNzT3JCYW5rKHVuc2lnbmVkIFJlZywgY29uc3QgTWFjaGluZVJlZ2lzdGVySW5mbyAmUmVnSW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRhcmdldFJlZ2lzdGVySW5mbyAqVFJJKTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9UQVJHRVRSRUdJU1RFUklORk9fSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhcmdldFNjaGVkdWxlLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vVGFyZ2V0U2NoZWR1bGUuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMDQ0ZjBiCi0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1RhcmdldFNjaGVkdWxlLmgKQEAgLTAsMCArMSwyMDQgQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vVGFyZ2V0U2NoZWR1bGUuaCAtIFNjaGVkIE1hY2hpbmUgTW9kZWwgLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlZmluZXMgYSB3cmFwcGVyIGFyb3VuZCBNQ1NjaGVkTW9kZWwgdGhhdCBhbGxvd3MgdGhlIGludGVyZmFjZSB0bworLy8gYmVuZWZpdCBmcm9tIGluZm9ybWF0aW9uIGN1cnJlbnRseSBvbmx5IGF2YWlsYWJsZSBpbiBUYXJnZXRJbnN0ckluZm8uCisvLyBJZGVhbGx5LCB0aGUgc2NoZWR1bGluZyBpbnRlcmZhY2Ugd291bGQgYmUgZnVsbHkgZGVmaW5lZCBpbiB0aGUgTUMgbGF5ZXIuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fVEFSR0VUU0NIRURVTEVfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fVEFSR0VUU0NIRURVTEVfSAorCisjaW5jbHVkZSAibGx2bS9BRFQvT3B0aW9uYWwuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9UYXJnZXRTdWJ0YXJnZXRJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9NQy9NQ0luc3RySXRpbmVyYXJpZXMuaCIKKyNpbmNsdWRlICJsbHZtL01DL01DU2NoZWR1bGUuaCIKKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNYWNoaW5lSW5zdHI7CitjbGFzcyBUYXJnZXRJbnN0ckluZm87CisKKy8vLyBQcm92aWRlIGFuIGluc3RydWN0aW9uIHNjaGVkdWxpbmcgbWFjaGluZSBtb2RlbCB0byBDb2RlR2VuIHBhc3Nlcy4KK2NsYXNzIFRhcmdldFNjaGVkTW9kZWwgeworICAvLyBGb3IgZWZmaWNpZW5jeSwgaG9sZCBhIGNvcHkgb2YgdGhlIHN0YXRpY2FsbHkgZGVmaW5lZCBNQ1NjaGVkTW9kZWwgZm9yIHRoaXMKKyAgLy8gcHJvY2Vzc29yLgorICBNQ1NjaGVkTW9kZWwgU2NoZWRNb2RlbDsKKyAgSW5zdHJJdGluZXJhcnlEYXRhIEluc3RySXRpbnM7CisgIGNvbnN0IFRhcmdldFN1YnRhcmdldEluZm8gKlNUSSA9IG51bGxwdHI7CisgIGNvbnN0IFRhcmdldEluc3RySW5mbyAqVElJID0gbnVsbHB0cjsKKworICBTbWFsbFZlY3Rvcjx1bnNpZ25lZCwgMTY+IFJlc291cmNlRmFjdG9yczsKKyAgdW5zaWduZWQgTWljcm9PcEZhY3RvcjsgLy8gTXVsdGlwbHkgdG8gbm9ybWFsaXplIG1pY3Jvb3BzIHRvIHJlc291cmNlIHVuaXRzLgorICB1bnNpZ25lZCBSZXNvdXJjZUxDTTsgICAvLyBSZXNvdXJjZSB1bml0cyBwZXIgY3ljbGUuIExhdGVuY3kgbm9ybWFsaXphdGlvbiBmYWN0b3IuCisKKyAgdW5zaWduZWQgY29tcHV0ZUluc3RyTGF0ZW5jeShjb25zdCBNQ1NjaGVkQ2xhc3NEZXNjICZTQ0Rlc2MpIGNvbnN0OworCitwdWJsaWM6CisgIFRhcmdldFNjaGVkTW9kZWwoKSA6IFNjaGVkTW9kZWwoTUNTY2hlZE1vZGVsOjpHZXREZWZhdWx0U2NoZWRNb2RlbCgpKSB7fQorCisgIC8vLyBcYnJpZWYgSW5pdGlhbGl6ZSB0aGUgbWFjaGluZSBtb2RlbCBmb3IgaW5zdHJ1Y3Rpb24gc2NoZWR1bGluZy4KKyAgLy8vCisgIC8vLyBUaGUgbWFjaGluZSBtb2RlbCBBUEkga2VlcHMgYSBjb3B5IG9mIHRoZSB0b3AtbGV2ZWwgTUNTY2hlZE1vZGVsIHRhYmxlCisgIC8vLyBpbmRpY2VzIGFuZCBtYXkgcXVlcnkgVGFyZ2V0U3VidGFyZ2V0SW5mbyBhbmQgVGFyZ2V0SW5zdHJJbmZvIHRvIHJlc29sdmUKKyAgLy8vIGR5bmFtaWMgcHJvcGVydGllcy4KKyAgdm9pZCBpbml0KGNvbnN0IE1DU2NoZWRNb2RlbCAmc20sIGNvbnN0IFRhcmdldFN1YnRhcmdldEluZm8gKnN0aSwKKyAgICAgICAgICAgIGNvbnN0IFRhcmdldEluc3RySW5mbyAqdGlpKTsKKworICAvLy8gUmV0dXJuIHRoZSBNQ1NjaGVkQ2xhc3NEZXNjIGZvciB0aGlzIGluc3RydWN0aW9uLgorICBjb25zdCBNQ1NjaGVkQ2xhc3NEZXNjICpyZXNvbHZlU2NoZWRDbGFzcyhjb25zdCBNYWNoaW5lSW5zdHIgKk1JKSBjb25zdDsKKworICAvLy8gXGJyaWVmIFRhcmdldFN1YnRhcmdldEluZm8gZ2V0dGVyLgorICBjb25zdCBUYXJnZXRTdWJ0YXJnZXRJbmZvICpnZXRTdWJ0YXJnZXRJbmZvKCkgY29uc3QgeyByZXR1cm4gU1RJOyB9CisKKyAgLy8vIFxicmllZiBUYXJnZXRJbnN0ckluZm8gZ2V0dGVyLgorICBjb25zdCBUYXJnZXRJbnN0ckluZm8gKmdldEluc3RySW5mbygpIGNvbnN0IHsgcmV0dXJuIFRJSTsgfQorCisgIC8vLyBcYnJpZWYgUmV0dXJuIHRydWUgaWYgdGhpcyBtYWNoaW5lIG1vZGVsIGluY2x1ZGVzIGFuIGluc3RydWN0aW9uLWxldmVsCisgIC8vLyBzY2hlZHVsaW5nIG1vZGVsLgorICAvLy8KKyAgLy8vIFRoaXMgaXMgbW9yZSBkZXRhaWxlZCB0aGFuIHRoZSBjb3Vyc2UgZ3JhaW4gSXNzdWVXaWR0aCBhbmQgZGVmYXVsdAorICAvLy8gbGF0ZW5jeSBwcm9wZXJ0aWVzLCBidXQgc2VwYXJhdGUgZnJvbSB0aGUgcGVyLWN5Y2xlIGl0aW5lcmFyeSBkYXRhLgorICBib29sIGhhc0luc3RyU2NoZWRNb2RlbCgpIGNvbnN0OworCisgIGNvbnN0IE1DU2NoZWRNb2RlbCAqZ2V0TUNTY2hlZE1vZGVsKCkgY29uc3QgeyByZXR1cm4gJlNjaGVkTW9kZWw7IH0KKworICAvLy8gXGJyaWVmIFJldHVybiB0cnVlIGlmIHRoaXMgbWFjaGluZSBtb2RlbCBpbmNsdWRlcyBjeWNsZS10by1jeWNsZSBpdGluZXJhcnkKKyAgLy8vIGRhdGEuCisgIC8vLworICAvLy8gVGhpcyBtb2RlbHMgc2NoZWR1bGluZyBhdCBlYWNoIHN0YWdlIGluIHRoZSBwcm9jZXNzb3IgcGlwZWxpbmUuCisgIGJvb2wgaGFzSW5zdHJJdGluZXJhcmllcygpIGNvbnN0OworCisgIGNvbnN0IEluc3RySXRpbmVyYXJ5RGF0YSAqZ2V0SW5zdHJJdGluZXJhcmllcygpIGNvbnN0IHsKKyAgICBpZiAoaGFzSW5zdHJJdGluZXJhcmllcygpKQorICAgICAgcmV0dXJuICZJbnN0ckl0aW5zOworICAgIHJldHVybiBudWxscHRyOworICB9CisKKyAgLy8vIFxicmllZiBSZXR1cm4gdHJ1ZSBpZiB0aGlzIG1hY2hpbmUgbW9kZWwgaW5jbHVkZXMgYW4gaW5zdHJ1Y3Rpb24tbGV2ZWwKKyAgLy8vIHNjaGVkdWxpbmcgbW9kZWwgb3IgY3ljbGUtdG8tY3ljbGUgaXRpbmVyYXJ5IGRhdGEuCisgIGJvb2wgaGFzSW5zdHJTY2hlZE1vZGVsT3JJdGluZXJhcmllcygpIGNvbnN0IHsKKyAgICByZXR1cm4gaGFzSW5zdHJTY2hlZE1vZGVsKCkgfHwgaGFzSW5zdHJJdGluZXJhcmllcygpOworICB9CisKKyAgLy8vIFxicmllZiBJZGVudGlmeSB0aGUgcHJvY2Vzc29yIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGN1cnJlbnQgc3VidGFyZ2V0LgorICB1bnNpZ25lZCBnZXRQcm9jZXNzb3JJRCgpIGNvbnN0IHsgcmV0dXJuIFNjaGVkTW9kZWwuZ2V0UHJvY2Vzc29ySUQoKTsgfQorCisgIC8vLyBcYnJpZWYgTWF4aW11bSBudW1iZXIgb2YgbWljcm8tb3BzIHRoYXQgbWF5IGJlIHNjaGVkdWxlZCBwZXIgY3ljbGUuCisgIHVuc2lnbmVkIGdldElzc3VlV2lkdGgoKSBjb25zdCB7IHJldHVybiBTY2hlZE1vZGVsLklzc3VlV2lkdGg7IH0KKworICAvLy8gXGJyaWVmIFJldHVybiB0cnVlIGlmIG5ldyBncm91cCBtdXN0IGJlZ2luLgorICBib29sIG11c3RCZWdpbkdyb3VwKGNvbnN0IE1hY2hpbmVJbnN0ciAqTUksCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1DU2NoZWRDbGFzc0Rlc2MgKlNDID0gbnVsbHB0cikgY29uc3Q7CisgIC8vLyBcYnJpZWYgUmV0dXJuIHRydWUgaWYgY3VycmVudCBncm91cCBtdXN0IGVuZC4KKyAgYm9vbCBtdXN0RW5kR3JvdXAoY29uc3QgTWFjaGluZUluc3RyICpNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTUNTY2hlZENsYXNzRGVzYyAqU0MgPSBudWxscHRyKSBjb25zdDsKKworICAvLy8gXGJyaWVmIFJldHVybiB0aGUgbnVtYmVyIG9mIGlzc3VlIHNsb3RzIHJlcXVpcmVkIGZvciB0aGlzIE1JLgorICB1bnNpZ25lZCBnZXROdW1NaWNyb09wcyhjb25zdCBNYWNoaW5lSW5zdHIgKk1JLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNQ1NjaGVkQ2xhc3NEZXNjICpTQyA9IG51bGxwdHIpIGNvbnN0OworCisgIC8vLyBcYnJpZWYgR2V0IHRoZSBudW1iZXIgb2Yga2luZHMgb2YgcmVzb3VyY2VzIGZvciB0aGlzIHRhcmdldC4KKyAgdW5zaWduZWQgZ2V0TnVtUHJvY1Jlc291cmNlS2luZHMoKSBjb25zdCB7CisgICAgcmV0dXJuIFNjaGVkTW9kZWwuZ2V0TnVtUHJvY1Jlc291cmNlS2luZHMoKTsKKyAgfQorCisgIC8vLyBcYnJpZWYgR2V0IGEgcHJvY2Vzc29yIHJlc291cmNlIGJ5IElEIGZvciBjb252ZW5pZW5jZS4KKyAgY29uc3QgTUNQcm9jUmVzb3VyY2VEZXNjICpnZXRQcm9jUmVzb3VyY2UodW5zaWduZWQgUElkeCkgY29uc3QgeworICAgIHJldHVybiBTY2hlZE1vZGVsLmdldFByb2NSZXNvdXJjZShQSWR4KTsKKyAgfQorCisjaWYgIWRlZmluZWQoTkRFQlVHKSB8fCBkZWZpbmVkKExMVk1fRU5BQkxFX0RVTVApCisgIGNvbnN0IGNoYXIgKmdldFJlc291cmNlTmFtZSh1bnNpZ25lZCBQSWR4KSBjb25zdCB7CisgICAgaWYgKCFQSWR4KQorICAgICAgcmV0dXJuICJNT3BzIjsKKyAgICByZXR1cm4gU2NoZWRNb2RlbC5nZXRQcm9jUmVzb3VyY2UoUElkeCktPk5hbWU7CisgIH0KKyNlbmRpZgorCisgIHVzaW5nIFByb2NSZXNJdGVyID0gY29uc3QgTUNXcml0ZVByb2NSZXNFbnRyeSAqOworCisgIC8vIFxicmllZiBHZXQgYW4gaXRlcmF0b3IgaW50byB0aGUgcHJvY2Vzc29yIHJlc291cmNlcyBjb25zdW1lZCBieSB0aGlzCisgIC8vIHNjaGVkdWxpbmcgY2xhc3MuCisgIFByb2NSZXNJdGVyIGdldFdyaXRlUHJvY1Jlc0JlZ2luKGNvbnN0IE1DU2NoZWRDbGFzc0Rlc2MgKlNDKSBjb25zdCB7CisgICAgLy8gVGhlIHN1YnRhcmdldCBob2xkcyBhIHNpbmdsZSByZXNvdXJjZSB0YWJsZSBmb3IgYWxsIHByb2Nlc3NvcnMuCisgICAgcmV0dXJuIFNUSS0+Z2V0V3JpdGVQcm9jUmVzQmVnaW4oU0MpOworICB9CisgIFByb2NSZXNJdGVyIGdldFdyaXRlUHJvY1Jlc0VuZChjb25zdCBNQ1NjaGVkQ2xhc3NEZXNjICpTQykgY29uc3QgeworICAgIHJldHVybiBTVEktPmdldFdyaXRlUHJvY1Jlc0VuZChTQyk7CisgIH0KKworICAvLy8gXGJyaWVmIE11bHRpcGx5IHRoZSBudW1iZXIgb2YgdW5pdHMgY29uc3VtZWQgZm9yIGEgcmVzb3VyY2UgYnkgdGhpcyBmYWN0b3IKKyAgLy8vIHRvIG5vcm1hbGl6ZSBpdCByZWxhdGl2ZSB0byBvdGhlciByZXNvdXJjZXMuCisgIHVuc2lnbmVkIGdldFJlc291cmNlRmFjdG9yKHVuc2lnbmVkIFJlc0lkeCkgY29uc3QgeworICAgIHJldHVybiBSZXNvdXJjZUZhY3RvcnNbUmVzSWR4XTsKKyAgfQorCisgIC8vLyBcYnJpZWYgTXVsdGlwbHkgbnVtYmVyIG9mIG1pY3JvLW9wcyBieSB0aGlzIGZhY3RvciB0byBub3JtYWxpemUgaXQKKyAgLy8vIHJlbGF0aXZlIHRvIG90aGVyIHJlc291cmNlcy4KKyAgdW5zaWduZWQgZ2V0TWljcm9PcEZhY3RvcigpIGNvbnN0IHsKKyAgICByZXR1cm4gTWljcm9PcEZhY3RvcjsKKyAgfQorCisgIC8vLyBcYnJpZWYgTXVsdGlwbHkgY3ljbGUgY291bnQgYnkgdGhpcyBmYWN0b3IgdG8gbm9ybWFsaXplIGl0IHJlbGF0aXZlIHRvCisgIC8vLyBvdGhlciByZXNvdXJjZXMuIFRoaXMgaXMgdGhlIG51bWJlciBvZiByZXNvdXJjZSB1bml0cyBwZXIgY3ljbGUuCisgIHVuc2lnbmVkIGdldExhdGVuY3lGYWN0b3IoKSBjb25zdCB7CisgICAgcmV0dXJuIFJlc291cmNlTENNOworICB9CisKKyAgLy8vIFxicmllZiBOdW1iZXIgb2YgbWljcm8tb3BzIHRoYXQgbWF5IGJlIGJ1ZmZlcmVkIGZvciBPT08gZXhlY3V0aW9uLgorICB1bnNpZ25lZCBnZXRNaWNyb09wQnVmZmVyU2l6ZSgpIGNvbnN0IHsgcmV0dXJuIFNjaGVkTW9kZWwuTWljcm9PcEJ1ZmZlclNpemU7IH0KKworICAvLy8gXGJyaWVmIE51bWJlciBvZiByZXNvdXJjZSB1bml0cyB0aGF0IG1heSBiZSBidWZmZXJlZCBmb3IgT09PIGV4ZWN1dGlvbi4KKyAgLy8vIFxyZXR1cm4gVGhlIGJ1ZmZlciBzaXplIGluIHJlc291cmNlIHVuaXRzIG9yIC0xIGZvciB1bmxpbWl0ZWQuCisgIGludCBnZXRSZXNvdXJjZUJ1ZmZlclNpemUodW5zaWduZWQgUElkeCkgY29uc3QgeworICAgIHJldHVybiBTY2hlZE1vZGVsLmdldFByb2NSZXNvdXJjZShQSWR4KS0+QnVmZmVyU2l6ZTsKKyAgfQorCisgIC8vLyBcYnJpZWYgQ29tcHV0ZSBvcGVyYW5kIGxhdGVuY3kgYmFzZWQgb24gdGhlIGF2YWlsYWJsZSBtYWNoaW5lIG1vZGVsLgorICAvLy8KKyAgLy8vIENvbXB1dGUgYW5kIHJldHVybiB0aGUgbGF0ZW5jeSBvZiB0aGUgZ2l2ZW4gZGF0YSBkZXBlbmRlbnQgZGVmIGFuZCB1c2UKKyAgLy8vIHdoZW4gdGhlIG9wZXJhbmQgaW5kaWNlcyBhcmUgYWxyZWFkeSBrbm93bi4gVXNlTUkgbWF5IGJlIE5VTEwgZm9yIGFuCisgIC8vLyB1bmtub3duIHVzZXIuCisgIHVuc2lnbmVkIGNvbXB1dGVPcGVyYW5kTGF0ZW5jeShjb25zdCBNYWNoaW5lSW5zdHIgKkRlZk1JLCB1bnNpZ25lZCBEZWZPcGVySWR4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUluc3RyICpVc2VNSSwgdW5zaWduZWQgVXNlT3BlcklkeCkKKyAgICBjb25zdDsKKworICAvLy8gXGJyaWVmIENvbXB1dGUgdGhlIGluc3RydWN0aW9uIGxhdGVuY3kgYmFzZWQgb24gdGhlIGF2YWlsYWJsZSBtYWNoaW5lCisgIC8vLyBtb2RlbC4KKyAgLy8vCisgIC8vLyBDb21wdXRlIGFuZCByZXR1cm4gdGhlIGV4cGVjdGVkIGxhdGVuY3kgb2YgdGhpcyBpbnN0cnVjdGlvbiBpbmRlcGVuZGVudCBvZgorICAvLy8gYSBwYXJ0aWN1bGFyIHVzZS4gY29tcHV0ZU9wZXJhbmRMYXRlbmN5IGlzIHRoZSBwcmVmZXJyZWQgQVBJLCBidXQgdGhpcyBpcworICAvLy8gb2NjYXNpb25hbGx5IHVzZWZ1bCB0byBoZWxwIGVzdGltYXRlIGluc3RydWN0aW9uIGNvc3QuCisgIC8vLworICAvLy8gSWYgVXNlRGVmYXVsdERlZkxhdGVuY3kgaXMgZmFsc2UgYW5kIG5vIG5ldyBtYWNoaW5lIHNjaGVkIG1vZGVsIGlzCisgIC8vLyBwcmVzZW50IHRoaXMgbWV0aG9kIGZhbGxzIGJhY2sgdG8gVElJLT5nZXRJbnN0ckxhdGVuY3kgd2l0aCBhbiBlbXB0eQorICAvLy8gaW5zdHJ1Y3Rpb24gaXRpbmVyYXJ5ICh0aGlzIGlzIHNvIHdlIHByZXNlcnZlIHRoZSBwcmV2aW91cyBiZWhhdmlvciBvZiB0aGUKKyAgLy8vIGlmIGNvbnZlcnRlciBhZnRlciBtb3ZpbmcgaXQgdG8gVGFyZ2V0U2NoZWRNb2RlbCkuCisgIHVuc2lnbmVkIGNvbXB1dGVJbnN0ckxhdGVuY3koY29uc3QgTWFjaGluZUluc3RyICpNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIFVzZURlZmF1bHREZWZMYXRlbmN5ID0gdHJ1ZSkgY29uc3Q7CisgIHVuc2lnbmVkIGNvbXB1dGVJbnN0ckxhdGVuY3kodW5zaWduZWQgT3Bjb2RlKSBjb25zdDsKKworCisgIC8vLyBcYnJpZWYgT3V0cHV0IGRlcGVuZGVuY3kgbGF0ZW5jeSBvZiBhIHBhaXIgb2YgZGVmcyBvZiB0aGUgc2FtZSByZWdpc3Rlci4KKyAgLy8vCisgIC8vLyBUaGlzIGlzIHR5cGljYWxseSBvbmUgY3ljbGUuCisgIHVuc2lnbmVkIGNvbXB1dGVPdXRwdXRMYXRlbmN5KGNvbnN0IE1hY2hpbmVJbnN0ciAqRGVmTUksIHVuc2lnbmVkIERlZklkeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUluc3RyICpEZXBNSSkgY29uc3Q7CisKKyAgLy8vIFxicmllZiBDb21wdXRlIHRoZSByZWNpcHJvY2FsIHRocm91Z2hwdXQgb2YgdGhlIGdpdmVuIGluc3RydWN0aW9uLgorICBPcHRpb25hbDxkb3VibGU+IGNvbXB1dGVJbnN0clJUaHJvdWdocHV0KGNvbnN0IE1hY2hpbmVJbnN0ciAqTUkpIGNvbnN0OworICBPcHRpb25hbDxkb3VibGU+IGNvbXB1dGVJbnN0clJUaHJvdWdocHV0KHVuc2lnbmVkIE9wY29kZSkgY29uc3Q7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1RBUkdFVFNDSEVEVUxFX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9UYXJnZXRTdWJ0YXJnZXRJbmZvLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vVGFyZ2V0U3VidGFyZ2V0SW5mby5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVlNWZhYWMKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vVGFyZ2V0U3VidGFyZ2V0SW5mby5oCkBAIC0wLDAgKzEsMjYxIEBACisvLz09PS0gbGx2bS9Db2RlR2VuL1RhcmdldFN1YnRhcmdldEluZm8uaCAtIFRhcmdldCBJbmZvcm1hdGlvbiAtLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFRoaXMgZmlsZSBkZXNjcmliZXMgdGhlIHN1YnRhcmdldCBvcHRpb25zIG9mIGEgVGFyZ2V0IG1hY2hpbmUuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fVEFSR0VUU1VCVEFSR0VUSU5GT19ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9UQVJHRVRTVUJUQVJHRVRJTkZPX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0FycmF5UmVmLmgiCisjaW5jbHVkZSAibGx2bS9BRFQvU21hbGxWZWN0b3IuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TdHJpbmdSZWYuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vUEJRUFJBQ29uc3RyYWludC5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9TY2hlZHVsZURBR011dGF0aW9uLmgiCisjaW5jbHVkZSAibGx2bS9Db2RlR2VuL1NjaGVkdWxlclJlZ2lzdHJ5LmgiCisjaW5jbHVkZSAibGx2bS9NQy9NQ1N1YnRhcmdldEluZm8uaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvQ29kZUdlbi5oIgorI2luY2x1ZGUgPG1lbW9yeT4KKyNpbmNsdWRlIDx2ZWN0b3I+CisKKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBDYWxsTG93ZXJpbmc7CitjbGFzcyBJbnN0ckl0aW5lcmFyeURhdGE7CitzdHJ1Y3QgSW5zdHJTdGFnZTsKK2NsYXNzIEluc3RydWN0aW9uU2VsZWN0b3I7CitjbGFzcyBMZWdhbGl6ZXJJbmZvOworY2xhc3MgTWFjaGluZUluc3RyOworc3RydWN0IE1hY2hpbmVTY2hlZFBvbGljeTsKK3N0cnVjdCBNQ1JlYWRBZHZhbmNlRW50cnk7CitzdHJ1Y3QgTUNXcml0ZUxhdGVuY3lFbnRyeTsKK3N0cnVjdCBNQ1dyaXRlUHJvY1Jlc0VudHJ5OworY2xhc3MgUmVnaXN0ZXJCYW5rSW5mbzsKK2NsYXNzIFNEZXA7CitjbGFzcyBTZWxlY3Rpb25EQUdUYXJnZXRJbmZvOworc3RydWN0IFN1YnRhcmdldEZlYXR1cmVLVjsKK3N0cnVjdCBTdWJ0YXJnZXRJbmZvS1Y7CitjbGFzcyBTVW5pdDsKK2NsYXNzIFRhcmdldEZyYW1lTG93ZXJpbmc7CitjbGFzcyBUYXJnZXRJbnN0ckluZm87CitjbGFzcyBUYXJnZXRMb3dlcmluZzsKK2NsYXNzIFRhcmdldFJlZ2lzdGVyQ2xhc3M7CitjbGFzcyBUYXJnZXRSZWdpc3RlckluZm87CitjbGFzcyBUYXJnZXRTY2hlZE1vZGVsOworY2xhc3MgVHJpcGxlOworCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8vCisvLy8gVGFyZ2V0U3VidGFyZ2V0SW5mbyAtIEdlbmVyaWMgYmFzZSBjbGFzcyBmb3IgYWxsIHRhcmdldCBzdWJ0YXJnZXRzLiAgQWxsCisvLy8gVGFyZ2V0LXNwZWNpZmljIG9wdGlvbnMgdGhhdCBjb250cm9sIGNvZGUgZ2VuZXJhdGlvbiBhbmQgcHJpbnRpbmcgc2hvdWxkCisvLy8gYmUgZXhwb3NlZCB0aHJvdWdoIGEgVGFyZ2V0U3VidGFyZ2V0SW5mby1kZXJpdmVkIGNsYXNzLgorLy8vCitjbGFzcyBUYXJnZXRTdWJ0YXJnZXRJbmZvIDogcHVibGljIE1DU3VidGFyZ2V0SW5mbyB7Citwcm90ZWN0ZWQ6IC8vIENhbiBvbmx5IGNyZWF0ZSBzdWJjbGFzc2VzLi4uCisgIFRhcmdldFN1YnRhcmdldEluZm8oY29uc3QgVHJpcGxlICZUVCwgU3RyaW5nUmVmIENQVSwgU3RyaW5nUmVmIEZTLAorICAgICAgICAgICAgICAgICAgICAgIEFycmF5UmVmPFN1YnRhcmdldEZlYXR1cmVLVj4gUEYsCisgICAgICAgICAgICAgICAgICAgICAgQXJyYXlSZWY8U3VidGFyZ2V0RmVhdHVyZUtWPiBQRCwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTdWJ0YXJnZXRJbmZvS1YgKlByb2NTY2hlZCwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBNQ1dyaXRlUHJvY1Jlc0VudHJ5ICpXUFIsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTUNXcml0ZUxhdGVuY3lFbnRyeSAqV0wsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTUNSZWFkQWR2YW5jZUVudHJ5ICpSQSwgY29uc3QgSW5zdHJTdGFnZSAqSVMsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgKk9DLCBjb25zdCB1bnNpZ25lZCAqRlApOworCitwdWJsaWM6CisgIC8vIEFudGlEZXBCcmVha01vZGUgLSBUeXBlIG9mIGFudGktZGVwZW5kZW5jZSBicmVha2luZyB0aGF0IHNob3VsZAorICAvLyBiZSBwZXJmb3JtZWQgYmVmb3JlIHBvc3QtUkEgc2NoZWR1bGluZy4KKyAgdXNpbmcgQW50aURlcEJyZWFrTW9kZSA9IGVudW0geyBBTlRJREVQX05PTkUsIEFOVElERVBfQ1JJVElDQUwsIEFOVElERVBfQUxMIH07CisgIHVzaW5nIFJlZ0NsYXNzVmVjdG9yID0gU21hbGxWZWN0b3JJbXBsPGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKj47CisKKyAgVGFyZ2V0U3VidGFyZ2V0SW5mbygpID0gZGVsZXRlOworICBUYXJnZXRTdWJ0YXJnZXRJbmZvKGNvbnN0IFRhcmdldFN1YnRhcmdldEluZm8gJikgPSBkZWxldGU7CisgIFRhcmdldFN1YnRhcmdldEluZm8gJm9wZXJhdG9yPShjb25zdCBUYXJnZXRTdWJ0YXJnZXRJbmZvICYpID0gZGVsZXRlOworICB+VGFyZ2V0U3VidGFyZ2V0SW5mbygpIG92ZXJyaWRlOworCisgIHZpcnR1YWwgYm9vbCBpc1hSYXlTdXBwb3J0ZWQoKSBjb25zdCB7IHJldHVybiBmYWxzZTsgfQorCisgIC8vIEludGVyZmFjZXMgdG8gdGhlIG1ham9yIGFzcGVjdHMgb2YgdGFyZ2V0IG1hY2hpbmUgaW5mb3JtYXRpb246CisgIC8vCisgIC8vIC0tIEluc3RydWN0aW9uIG9wY29kZSBhbmQgb3BlcmFuZCBpbmZvcm1hdGlvbgorICAvLyAtLSBQaXBlbGluZXMgYW5kIHNjaGVkdWxpbmcgaW5mb3JtYXRpb24KKyAgLy8gLS0gU3RhY2sgZnJhbWUgaW5mb3JtYXRpb24KKyAgLy8gLS0gU2VsZWN0aW9uIERBRyBsb3dlcmluZyBpbmZvcm1hdGlvbgorICAvLyAtLSBDYWxsIGxvd2VyaW5nIGluZm9ybWF0aW9uCisgIC8vCisgIC8vIE4uQi4gVGhlc2Ugb2JqZWN0cyBtYXkgY2hhbmdlIGR1cmluZyBjb21waWxhdGlvbi4gSXQncyBub3Qgc2FmZSB0byBjYWNoZQorICAvLyB0aGVtIGJldHdlZW4gZnVuY3Rpb25zLgorICB2aXJ0dWFsIGNvbnN0IFRhcmdldEluc3RySW5mbyAqZ2V0SW5zdHJJbmZvKCkgY29uc3QgeyByZXR1cm4gbnVsbHB0cjsgfQorICB2aXJ0dWFsIGNvbnN0IFRhcmdldEZyYW1lTG93ZXJpbmcgKmdldEZyYW1lTG93ZXJpbmcoKSBjb25zdCB7CisgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKyAgdmlydHVhbCBjb25zdCBUYXJnZXRMb3dlcmluZyAqZ2V0VGFyZ2V0TG93ZXJpbmcoKSBjb25zdCB7IHJldHVybiBudWxscHRyOyB9CisgIHZpcnR1YWwgY29uc3QgU2VsZWN0aW9uREFHVGFyZ2V0SW5mbyAqZ2V0U2VsZWN0aW9uREFHSW5mbygpIGNvbnN0IHsKKyAgICByZXR1cm4gbnVsbHB0cjsKKyAgfQorICB2aXJ0dWFsIGNvbnN0IENhbGxMb3dlcmluZyAqZ2V0Q2FsbExvd2VyaW5nKCkgY29uc3QgeyByZXR1cm4gbnVsbHB0cjsgfQorCisgIC8vIEZJWE1FOiBUaGlzIGxldHMgdGFyZ2V0cyBzcGVjaWFsaXplIHRoZSBzZWxlY3RvciBieSBzdWJ0YXJnZXQgKHdoaWNoIGxldHMKKyAgLy8gdXMgZG8gdGhpbmdzIGxpa2UgYSBkZWRpY2F0ZWQgYXZ4NTEyIHNlbGVjdG9yKS4gIEhvd2V2ZXIsIHdlIG1pZ2h0IHdhbnQKKyAgLy8gdG8gYWxzbyBzcGVjaWFsaXplIHNlbGVjdG9ycyBieSBNYWNoaW5lRnVuY3Rpb24sIHdoaWNoIHdvdWxkIGxldCB1cyBiZQorICAvLyBhd2FyZSBvZiBvcHRzaXplL29wdG5vbmUgYW5kIHN1Y2guCisgIHZpcnR1YWwgY29uc3QgSW5zdHJ1Y3Rpb25TZWxlY3RvciAqZ2V0SW5zdHJ1Y3Rpb25TZWxlY3RvcigpIGNvbnN0IHsKKyAgICByZXR1cm4gbnVsbHB0cjsKKyAgfQorCisgIHZpcnR1YWwgdW5zaWduZWQgZ2V0SHdNb2RlKCkgY29uc3QgeyByZXR1cm4gMDsgfQorCisgIC8vLyBUYXJnZXQgY2FuIHN1YmNsYXNzIHRoaXMgaG9vayB0byBzZWxlY3QgYSBkaWZmZXJlbnQgREFHIHNjaGVkdWxlci4KKyAgdmlydHVhbCBSZWdpc3RlclNjaGVkdWxlcjo6RnVuY3Rpb25QYXNzQ3RvcgorICAgICAgZ2V0REFHU2NoZWR1bGVyKENvZGVHZW5PcHQ6OkxldmVsKSBjb25zdCB7CisgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKworICB2aXJ0dWFsIGNvbnN0IExlZ2FsaXplckluZm8gKmdldExlZ2FsaXplckluZm8oKSBjb25zdCB7IHJldHVybiBudWxscHRyOyB9CisKKyAgLy8vIGdldFJlZ2lzdGVySW5mbyAtIElmIHJlZ2lzdGVyIGluZm9ybWF0aW9uIGlzIGF2YWlsYWJsZSwgcmV0dXJuIGl0LiAgSWYKKyAgLy8vIG5vdCwgcmV0dXJuIG51bGwuCisgIHZpcnR1YWwgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICpnZXRSZWdpc3RlckluZm8oKSBjb25zdCB7IHJldHVybiBudWxscHRyOyB9CisKKyAgLy8vIElmIHRoZSBpbmZvcm1hdGlvbiBmb3IgdGhlIHJlZ2lzdGVyIGJhbmtzIGlzIGF2YWlsYWJsZSwgcmV0dXJuIGl0LgorICAvLy8gT3RoZXJ3aXNlIHJldHVybiBudWxscHRyLgorICB2aXJ0dWFsIGNvbnN0IFJlZ2lzdGVyQmFua0luZm8gKmdldFJlZ0JhbmtJbmZvKCkgY29uc3QgeyByZXR1cm4gbnVsbHB0cjsgfQorCisgIC8vLyBnZXRJbnN0ckl0aW5lcmFyeURhdGEgLSBSZXR1cm5zIGluc3RydWN0aW9uIGl0aW5lcmFyeSBkYXRhIGZvciB0aGUgdGFyZ2V0CisgIC8vLyBvciBzcGVjaWZpYyBzdWJ0YXJnZXQuCisgIHZpcnR1YWwgY29uc3QgSW5zdHJJdGluZXJhcnlEYXRhICpnZXRJbnN0ckl0aW5lcmFyeURhdGEoKSBjb25zdCB7CisgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKworICAvLy8gUmVzb2x2ZSBhIFNjaGVkQ2xhc3MgYXQgcnVudGltZSwgd2hlcmUgU2NoZWRDbGFzcyBpZGVudGlmaWVzIGFuCisgIC8vLyBNQ1NjaGVkQ2xhc3NEZXNjIHdpdGggdGhlIGlzVmFyaWFudCBwcm9wZXJ0eS4gVGhpcyBtYXkgcmV0dXJuIHRoZSBJRCBvZgorICAvLy8gYW5vdGhlciB2YXJpYW50IFNjaGVkQ2xhc3MsIGJ1dCByZXBlYXRlZCBpbnZvY2F0aW9uIG11c3QgcXVpY2tseSB0ZXJtaW5hdGUKKyAgLy8vIGluIGEgbm9udmFyaWFudCBTY2hlZENsYXNzLgorICB2aXJ0dWFsIHVuc2lnbmVkIHJlc29sdmVTY2hlZENsYXNzKHVuc2lnbmVkIFNjaGVkQ2xhc3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTWFjaGluZUluc3RyICpNSSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBUYXJnZXRTY2hlZE1vZGVsICpTY2hlZE1vZGVsKSBjb25zdCB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICAvLy8gXGJyaWVmIFRydWUgaWYgdGhlIHN1YnRhcmdldCBzaG91bGQgcnVuIE1hY2hpbmVTY2hlZHVsZXIgYWZ0ZXIgYWdncmVzc2l2ZQorICAvLy8gY29hbGVzY2luZy4KKyAgLy8vCisgIC8vLyBUaGlzIGN1cnJlbnRseSByZXBsYWNlcyB0aGUgU2VsZWN0aW9uREFHIHNjaGVkdWxlciB3aXRoIHRoZSAic291cmNlIiBvcmRlcgorICAvLy8gc2NoZWR1bGVyICh0aG91Z2ggc2VlIGJlbG93IGZvciBhbiBvcHRpb24gdG8gdHVybiB0aGlzIG9mZiBhbmQgdXNlIHRoZQorICAvLy8gVGFyZ2V0TG93ZXJpbmcgcHJlZmVyZW5jZSkuIEl0IGRvZXMgbm90IHlldCBkaXNhYmxlIHRoZSBwb3N0UkEgc2NoZWR1bGVyLgorICB2aXJ0dWFsIGJvb2wgZW5hYmxlTWFjaGluZVNjaGVkdWxlcigpIGNvbnN0OworCisgIC8vLyBcYnJpZWYgU3VwcG9ydCBwcmludGluZyBvZiBbbGF0ZW5jeTp0aHJvdWdocHV0XSBjb21tZW50IGluIG91dHB1dCAuUyBmaWxlLgorICB2aXJ0dWFsIGJvb2wgc3VwcG9ydFByaW50U2NoZWRJbmZvKCkgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KKworICAvLy8gXGJyaWVmIFRydWUgaWYgdGhlIG1hY2hpbmUgc2NoZWR1bGVyIHNob3VsZCBkaXNhYmxlIHRoZSBUTEkgcHJlZmVyZW5jZQorICAvLy8gZm9yIHByZVJBIHNjaGVkdWxpbmcgd2l0aCB0aGUgc291cmNlIGxldmVsIHNjaGVkdWxlci4KKyAgdmlydHVhbCBib29sIGVuYWJsZU1hY2hpbmVTY2hlZERlZmF1bHRTY2hlZCgpIGNvbnN0IHsgcmV0dXJuIHRydWU7IH0KKworICAvLy8gXGJyaWVmIFRydWUgaWYgdGhlIHN1YnRhcmdldCBzaG91bGQgZW5hYmxlIGpvaW5pbmcgZ2xvYmFsIGNvcGllcy4KKyAgLy8vCisgIC8vLyBCeSBkZWZhdWx0IHRoaXMgaXMgZW5hYmxlZCBpZiB0aGUgbWFjaGluZSBzY2hlZHVsZXIgaXMgZW5hYmxlZCwgYnV0CisgIC8vLyBjYW4gYmUgb3ZlcnJpZGRlbi4KKyAgdmlydHVhbCBib29sIGVuYWJsZUpvaW5HbG9iYWxDb3BpZXMoKSBjb25zdDsKKworICAvLy8gVHJ1ZSBpZiB0aGUgc3VidGFyZ2V0IHNob3VsZCBydW4gYSBzY2hlZHVsZXIgYWZ0ZXIgcmVnaXN0ZXIgYWxsb2NhdGlvbi4KKyAgLy8vCisgIC8vLyBCeSBkZWZhdWx0IHRoaXMgcXVlcmllcyB0aGUgUG9zdFJBU2NoZWR1bGluZyBiaXQgaW4gdGhlIHNjaGVkdWxpbmcgbW9kZWwKKyAgLy8vIHdoaWNoIGlzIHRoZSBwcmVmZXJyZWQgd2F5IHRvIGluZmx1ZW5jZSB0aGlzLgorICB2aXJ0dWFsIGJvb2wgZW5hYmxlUG9zdFJBU2NoZWR1bGVyKCkgY29uc3Q7CisKKyAgLy8vIFxicmllZiBUcnVlIGlmIHRoZSBzdWJ0YXJnZXQgc2hvdWxkIHJ1biB0aGUgYXRvbWljIGV4cGFuc2lvbiBwYXNzLgorICB2aXJ0dWFsIGJvb2wgZW5hYmxlQXRvbWljRXhwYW5kKCkgY29uc3Q7CisKKyAgLy8vIFRydWUgaWYgdGhlIHN1YnRhcmdldCBzaG91bGQgcnVuIHRoZSBpbmRpcmVjdGJyIGV4cGFuc2lvbiBwYXNzLgorICB2aXJ0dWFsIGJvb2wgZW5hYmxlSW5kaXJlY3RCckV4cGFuZCgpIGNvbnN0OworCisgIC8vLyBcYnJpZWYgT3ZlcnJpZGUgZ2VuZXJpYyBzY2hlZHVsaW5nIHBvbGljeSB3aXRoaW4gYSByZWdpb24uCisgIC8vLworICAvLy8gVGhpcyBpcyBhIGNvbnZlbmllbnQgd2F5IGZvciB0YXJnZXRzIHRoYXQgZG9uJ3QgcHJvdmlkZSBhbnkgY3VzdG9tCisgIC8vLyBzY2hlZHVsaW5nIGhldXJpc3RpY3MgKG5vIGN1c3RvbSBNYWNoaW5lU2NoZWRTdHJhdGVneSkgdG8gbWFrZQorICAvLy8gY2hhbmdlcyB0byB0aGUgZ2VuZXJpYyBzY2hlZHVsaW5nIHBvbGljeS4KKyAgdmlydHVhbCB2b2lkIG92ZXJyaWRlU2NoZWRQb2xpY3koTWFjaGluZVNjaGVkUG9saWN5ICZQb2xpY3ksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIE51bVJlZ2lvbkluc3RycykgY29uc3Qge30KKworICAvLyBcYnJpZWYgUGVyZm9ybSB0YXJnZXQgc3BlY2lmaWMgYWRqdXN0bWVudHMgdG8gdGhlIGxhdGVuY3kgb2YgYSBzY2hlZHVsZQorICAvLyBkZXBlbmRlbmN5LgorICB2aXJ0dWFsIHZvaWQgYWRqdXN0U2NoZWREZXBlbmRlbmN5KFNVbml0ICpkZWYsIFNVbml0ICp1c2UsIFNEZXAgJmRlcCkgY29uc3Qge30KKworICAvLyBGb3IgdXNlIHdpdGggUG9zdFJBU2NoZWR1bGluZzogZ2V0IHRoZSBhbnRpLWRlcGVuZGVuY2UgYnJlYWtpbmcgdGhhdCBzaG91bGQKKyAgLy8gYmUgcGVyZm9ybWVkIGJlZm9yZSBwb3N0LVJBIHNjaGVkdWxpbmcuCisgIHZpcnR1YWwgQW50aURlcEJyZWFrTW9kZSBnZXRBbnRpRGVwQnJlYWtNb2RlKCkgY29uc3QgeyByZXR1cm4gQU5USURFUF9OT05FOyB9CisKKyAgLy8gRm9yIHVzZSB3aXRoIFBvc3RSQVNjaGVkdWxpbmc6IGluIENyaXRpY2FsUGF0aFJDcywgcmV0dXJuIGFueSByZWdpc3RlcgorICAvLyBjbGFzc2VzIHRoYXQgc2hvdWxkIG9ubHkgYmUgY29uc2lkZXJlZCBmb3IgYW50aS1kZXBlbmRlbmNlIGJyZWFraW5nIGlmIHRoZXkKKyAgLy8gYXJlIG9uIHRoZSBjcml0aWNhbCBwYXRoLgorICB2aXJ0dWFsIHZvaWQgZ2V0Q3JpdGljYWxQYXRoUkNzKFJlZ0NsYXNzVmVjdG9yICZDcml0aWNhbFBhdGhSQ3MpIGNvbnN0IHsKKyAgICByZXR1cm4gQ3JpdGljYWxQYXRoUkNzLmNsZWFyKCk7CisgIH0KKworICAvLyBcYnJpZWYgUHJvdmlkZSBhbiBvcmRlcmVkIGxpc3Qgb2Ygc2NoZWR1bGUgREFHIG11dGF0aW9ucyBmb3IgdGhlIHBvc3QtUkEKKyAgLy8gc2NoZWR1bGVyLgorICB2aXJ0dWFsIHZvaWQgZ2V0UG9zdFJBTXV0YXRpb25zKAorICAgICAgc3RkOjp2ZWN0b3I8c3RkOjp1bmlxdWVfcHRyPFNjaGVkdWxlREFHTXV0YXRpb24+PiAmTXV0YXRpb25zKSBjb25zdCB7CisgIH0KKworICAvLyBcYnJpZWYgUHJvdmlkZSBhbiBvcmRlcmVkIGxpc3Qgb2Ygc2NoZWR1bGUgREFHIG11dGF0aW9ucyBmb3IgdGhlIG1hY2hpbmUKKyAgLy8gcGlwZWxpbmVyLgorICB2aXJ0dWFsIHZvaWQgZ2V0U01TTXV0YXRpb25zKAorICAgICAgc3RkOjp2ZWN0b3I8c3RkOjp1bmlxdWVfcHRyPFNjaGVkdWxlREFHTXV0YXRpb24+PiAmTXV0YXRpb25zKSBjb25zdCB7CisgIH0KKworICAvLyBGb3IgdXNlIHdpdGggUG9zdFJBU2NoZWR1bGluZzogZ2V0IHRoZSBtaW5pbXVtIG9wdGltaXphdGlvbiBsZXZlbCBuZWVkZWQKKyAgLy8gdG8gZW5hYmxlIHBvc3QtUkEgc2NoZWR1bGluZy4KKyAgdmlydHVhbCBDb2RlR2VuT3B0OjpMZXZlbCBnZXRPcHRMZXZlbFRvRW5hYmxlUG9zdFJBU2NoZWR1bGVyKCkgY29uc3QgeworICAgIHJldHVybiBDb2RlR2VuT3B0OjpEZWZhdWx0OworICB9CisKKyAgLy8vIFxicmllZiBUcnVlIGlmIHRoZSBzdWJ0YXJnZXQgc2hvdWxkIHJ1biB0aGUgbG9jYWwgcmVhc3NpZ25tZW50CisgIC8vLyBoZXVyaXN0aWMgb2YgdGhlIHJlZ2lzdGVyIGFsbG9jYXRvci4KKyAgLy8vIFRoaXMgaGV1cmlzdGljIG1heSBiZSBjb21waWxlIHRpbWUgaW50ZW5zaXZlLCBccCBPcHRMZXZlbCBwcm92aWRlcworICAvLy8gYSBmaW5lciBncmFpbiB0byB0dW5lIHRoZSByZWdpc3RlciBhbGxvY2F0b3IuCisgIHZpcnR1YWwgYm9vbCBlbmFibGVSQUxvY2FsUmVhc3NpZ25tZW50KENvZGVHZW5PcHQ6OkxldmVsIE9wdExldmVsKSBjb25zdDsKKworICAvLy8gXGJyaWVmIFRydWUgaWYgdGhlIHN1YnRhcmdldCBzaG91bGQgY29uc2lkZXIgdGhlIGNvc3Qgb2YgbG9jYWwgaW50ZXJ2YWxzCisgIC8vLyBjcmVhdGVkIGJ5IGEgc3BsaXQgY2FuZGlkYXRlIHdoZW4gY2hvb3NpbmcgdGhlIGJlc3Qgc3BsaXQgY2FuZGlkYXRlLiBUaGlzCisgIC8vLyBoZXVyaXN0aWMgbWF5IGJlIGNvbXBpbGUgdGltZSBpbnRlbnNpdmUuCisgIHZpcnR1YWwgYm9vbCBlbmFibGVBZHZhbmNlZFJBU3BsaXRDb3N0KCkgY29uc3Q7CisKKyAgLy8vIFxicmllZiBFbmFibGUgdXNlIG9mIGFsaWFzIGFuYWx5c2lzIGR1cmluZyBjb2RlIGdlbmVyYXRpb24gKGR1cmluZyBNSQorICAvLy8gc2NoZWR1bGluZywgREFHQ29tYmluZSwgZXRjLikuCisgIHZpcnR1YWwgYm9vbCB1c2VBQSgpIGNvbnN0OworCisgIC8vLyBcYnJpZWYgRW5hYmxlIHRoZSB1c2Ugb2YgdGhlIGVhcmx5IGlmIGNvbnZlcnNpb24gcGFzcy4KKyAgdmlydHVhbCBib29sIGVuYWJsZUVhcmx5SWZDb252ZXJzaW9uKCkgY29uc3QgeyByZXR1cm4gZmFsc2U7IH0KKworICAvLy8gXGJyaWVmIFJldHVybiBQQlFQQ29uc3RyYWludChzKSBmb3IgdGhlIHRhcmdldC4KKyAgLy8vCisgIC8vLyBPdmVycmlkZSB0byBwcm92aWRlIGN1c3RvbSBQQlFQIGNvbnN0cmFpbnRzLgorICB2aXJ0dWFsIHN0ZDo6dW5pcXVlX3B0cjxQQlFQUkFDb25zdHJhaW50PiBnZXRDdXN0b21QQlFQQ29uc3RyYWludHMoKSBjb25zdCB7CisgICAgcmV0dXJuIG51bGxwdHI7CisgIH0KKworICAvLy8gRW5hYmxlIHRyYWNraW5nIG9mIHN1YnJlZ2lzdGVyIGxpdmVuZXNzIGluIHJlZ2lzdGVyIGFsbG9jYXRvci4KKyAgLy8vIFBsZWFzZSB1c2UgTWFjaGluZVJlZ2lzdGVySW5mbzo6c3ViUmVnTGl2ZW5lc3NFbmFibGVkKCkgaW5zdGVhZCB3aGVyZQorICAvLy8gcG9zc2libGUuCisgIHZpcnR1YWwgYm9vbCBlbmFibGVTdWJSZWdMaXZlbmVzcygpIGNvbnN0IHsgcmV0dXJuIGZhbHNlOyB9CisKKyAgLy8vIFJldHVybnMgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHNjaGVkdWxlciBjb21tZW50CisgIHN0ZDo6c3RyaW5nIGdldFNjaGVkSW5mb1N0cihjb25zdCBNYWNoaW5lSW5zdHIgJk1JKSBjb25zdCBvdmVycmlkZTsKKyAgc3RkOjpzdHJpbmcgZ2V0U2NoZWRJbmZvU3RyKE1DSW5zdCBjb25zdCAmTUNJKSBjb25zdCBvdmVycmlkZTsKKworICAvLy8gVGhpcyBpcyBjYWxsZWQgYWZ0ZXIgYSAubWlyIGZpbGUgd2FzIGxvYWRlZC4KKyAgdmlydHVhbCB2b2lkIG1pckZpbGVMb2FkZWQoTWFjaGluZUZ1bmN0aW9uICZNRikgY29uc3Q7Cit9OworCit9IC8vIGVuZCBuYW1lc3BhY2UgbGx2bQorCisjZW5kaWYgLy8gTExWTV9DT0RFR0VOX1RBUkdFVFNVQlRBUkdFVElORk9fSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1VucmVhY2hhYmxlQmxvY2tFbGltLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vVW5yZWFjaGFibGVCbG9ja0VsaW0uaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zZTdhZmQ0Ci0tLSAvZGV2L251bGwKKysrIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1VucmVhY2hhYmxlQmxvY2tFbGltLmgKQEAgLTAsMCArMSwzNyBAQAorLy89PT0tLSBVbnJlYWNoYWJsZUJsb2NrRWxpbS5oIC0gUmVtb3ZlIHVucmVhY2hhYmxlIGJsb2NrcyBmb3IgY29kZWdlbiAtLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBwYXNzIGlzIGFuIGV4dHJlbWVseSBzaW1wbGUgdmVyc2lvbiBvZiB0aGUgU2ltcGxpZnlDRkcgcGFzcy4gIEl0cyBzb2xlCisvLyBqb2IgaXMgdG8gZGVsZXRlIExMVk0gYmFzaWMgYmxvY2tzIHRoYXQgYXJlIG5vdCByZWFjaGFibGUgZnJvbSB0aGUgZW50cnkKKy8vIG5vZGUuICBUbyBkbyB0aGlzLCBpdCBwZXJmb3JtcyBhIHNpbXBsZSBkZXB0aCBmaXJzdCB0cmF2ZXJzYWwgb2YgdGhlIENGRywKKy8vIHRoZW4gZGVsZXRlcyBhbnkgdW52aXNpdGVkIG5vZGVzLgorLy8KKy8vIE5vdGUgdGhhdCB0aGlzIHBhc3MgaXMgcmVhbGx5IGEgaGFjay4gIEluIHBhcnRpY3VsYXIsIHRoZSBpbnN0cnVjdGlvbgorLy8gc2VsZWN0b3JzIGZvciB2YXJpb3VzIHRhcmdldHMgc2hvdWxkIGp1c3Qgbm90IGdlbmVyYXRlIGNvZGUgZm9yIHVucmVhY2hhYmxlCisvLyBibG9ja3MuICBVbnRpbCBMTFZNIGhhcyBhIG1vcmUgc3lzdGVtYXRpYyB3YXkgb2YgZGVmaW5pbmcgaW5zdHJ1Y3Rpb24KKy8vIHNlbGVjdG9ycywgaG93ZXZlciwgd2UgY2Fubm90IHJlYWxseSBleHBlY3QgdGhlbSB0byBoYW5kbGUgYWRkaXRpb25hbAorLy8gY29tcGxleGl0eS4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fTElCX0NPREVHRU5fVU5SRUFDSEFCTEVCTE9DS0VMSU1fSAorI2RlZmluZSBMTFZNX0xJQl9DT0RFR0VOX1VOUkVBQ0hBQkxFQkxPQ0tFTElNX0gKKworI2luY2x1ZGUgImxsdm0vSVIvUGFzc01hbmFnZXIuaCIKKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBVbnJlYWNoYWJsZUJsb2NrRWxpbVBhc3MKKyAgICA6IHB1YmxpYyBQYXNzSW5mb01peGluPFVucmVhY2hhYmxlQmxvY2tFbGltUGFzcz4geworcHVibGljOgorICBQcmVzZXJ2ZWRBbmFseXNlcyBydW4oRnVuY3Rpb24gJkYsIEZ1bmN0aW9uQW5hbHlzaXNNYW5hZ2VyICZBTSk7Cit9OworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fTElCX0NPREVHRU5fVU5SRUFDSEFCTEVCTE9DS0VMSU1fSApkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1ZhbHVlVHlwZXMuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9WYWx1ZVR5cGVzLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDJlZjRhOQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9WYWx1ZVR5cGVzLmgKQEAgLTAsMCArMSw0MzcgQEAKKy8vPT09LSBDb2RlR2VuL1ZhbHVlVHlwZXMuaCAtIExvdy1MZXZlbCBUYXJnZXQgaW5kZXBlbmQuIHR5cGVzIC0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGRlZmluZXMgdGhlIHNldCBvZiBsb3ctbGV2ZWwgdGFyZ2V0IGluZGVwZW5kZW50IHR5cGVzIHdoaWNoIHZhcmlvdXMKKy8vIHZhbHVlcyBpbiB0aGUgY29kZSBnZW5lcmF0b3IgYXJlLiAgVGhpcyBhbGxvd3MgdGhlIHRhcmdldCBzcGVjaWZpYyBiZWhhdmlvcgorLy8gb2YgaW5zdHJ1Y3Rpb25zIHRvIGJlIGRlc2NyaWJlZCB0byB0YXJnZXQgaW5kZXBlbmRlbnQgcGFzc2VzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKKyNpZm5kZWYgTExWTV9DT0RFR0VOX1ZBTFVFVFlQRVNfSAorI2RlZmluZSBMTFZNX0NPREVHRU5fVkFMVUVUWVBFU19ICisKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvQ29tcGlsZXIuaCIKKyNpbmNsdWRlICJsbHZtL1N1cHBvcnQvTWFjaGluZVZhbHVlVHlwZS5oIgorI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9NYXRoRXh0cmFzLmgiCisjaW5jbHVkZSA8Y2Fzc2VydD4KKyNpbmNsdWRlIDxjc3RkaW50PgorI2luY2x1ZGUgPHN0cmluZz4KKworbmFtZXNwYWNlIGxsdm0geworCisgIGNsYXNzIExMVk1Db250ZXh0OworICBjbGFzcyBUeXBlOworCisgIC8vLyBFeHRlbmRlZCBWYWx1ZSBUeXBlLiBDYXBhYmxlIG9mIGhvbGRpbmcgdmFsdWUgdHlwZXMgd2hpY2ggYXJlIG5vdCBuYXRpdmUKKyAgLy8vIGZvciBhbnkgcHJvY2Vzc29yIChzdWNoIGFzIHRoZSBpMTIzNDUgdHlwZSksIGFzIHdlbGwgYXMgdGhlIHR5cGVzIGFuIE1WVAorICAvLy8gY2FuIHJlcHJlc2VudC4KKyAgc3RydWN0IEVWVCB7CisgIHByaXZhdGU6CisgICAgTVZUIFYgPSBNVlQ6OklOVkFMSURfU0lNUExFX1ZBTFVFX1RZUEU7CisgICAgVHlwZSAqTExWTVR5ID0gbnVsbHB0cjsKKworICBwdWJsaWM6CisgICAgY29uc3RleHByIEVWVCgpID0gZGVmYXVsdDsKKyAgICBjb25zdGV4cHIgRVZUKE1WVDo6U2ltcGxlVmFsdWVUeXBlIFNWVCkgOiBWKFNWVCkge30KKyAgICBjb25zdGV4cHIgRVZUKE1WVCBTKSA6IFYoUykge30KKworICAgIGJvb2wgb3BlcmF0b3I9PShFVlQgVlQpIGNvbnN0IHsKKyAgICAgIHJldHVybiAhKCp0aGlzICE9IFZUKTsKKyAgICB9CisgICAgYm9vbCBvcGVyYXRvciE9KEVWVCBWVCkgY29uc3QgeworICAgICAgaWYgKFYuU2ltcGxlVHkgIT0gVlQuVi5TaW1wbGVUeSkKKyAgICAgICAgcmV0dXJuIHRydWU7CisgICAgICBpZiAoVi5TaW1wbGVUeSA9PSBNVlQ6OklOVkFMSURfU0lNUExFX1ZBTFVFX1RZUEUpCisgICAgICAgIHJldHVybiBMTFZNVHkgIT0gVlQuTExWTVR5OworICAgICAgcmV0dXJuIGZhbHNlOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRoZSBFVlQgdGhhdCByZXByZXNlbnRzIGEgZmxvYXRpbmctcG9pbnQgdHlwZSB3aXRoIHRoZSBnaXZlbgorICAgIC8vLyBudW1iZXIgb2YgYml0cy4gVGhlcmUgYXJlIHR3byBmbG9hdGluZy1wb2ludCB0eXBlcyB3aXRoIDEyOCBiaXRzIC0gdGhpcworICAgIC8vLyByZXR1cm5zIGYxMjggcmF0aGVyIHRoYW4gcHBjZjEyOC4KKyAgICBzdGF0aWMgRVZUIGdldEZsb2F0aW5nUG9pbnRWVCh1bnNpZ25lZCBCaXRXaWR0aCkgeworICAgICAgcmV0dXJuIE1WVDo6Z2V0RmxvYXRpbmdQb2ludFZUKEJpdFdpZHRoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0aGUgRVZUIHRoYXQgcmVwcmVzZW50cyBhbiBpbnRlZ2VyIHdpdGggdGhlIGdpdmVuIG51bWJlciBvZgorICAgIC8vLyBiaXRzLgorICAgIHN0YXRpYyBFVlQgZ2V0SW50ZWdlclZUKExMVk1Db250ZXh0ICZDb250ZXh0LCB1bnNpZ25lZCBCaXRXaWR0aCkgeworICAgICAgTVZUIE0gPSBNVlQ6OmdldEludGVnZXJWVChCaXRXaWR0aCk7CisgICAgICBpZiAoTS5TaW1wbGVUeSAhPSBNVlQ6OklOVkFMSURfU0lNUExFX1ZBTFVFX1RZUEUpCisgICAgICAgIHJldHVybiBNOworICAgICAgcmV0dXJuIGdldEV4dGVuZGVkSW50ZWdlclZUKENvbnRleHQsIEJpdFdpZHRoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJucyB0aGUgRVZUIHRoYXQgcmVwcmVzZW50cyBhIHZlY3RvciBOdW1FbGVtZW50cyBpbiBsZW5ndGgsIHdoZXJlCisgICAgLy8vIGVhY2ggZWxlbWVudCBpcyBvZiB0eXBlIFZULgorICAgIHN0YXRpYyBFVlQgZ2V0VmVjdG9yVlQoTExWTUNvbnRleHQgJkNvbnRleHQsIEVWVCBWVCwgdW5zaWduZWQgTnVtRWxlbWVudHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIElzU2NhbGFibGUgPSBmYWxzZSkgeworICAgICAgTVZUIE0gPSBNVlQ6OmdldFZlY3RvclZUKFZULlYsIE51bUVsZW1lbnRzLCBJc1NjYWxhYmxlKTsKKyAgICAgIGlmIChNLlNpbXBsZVR5ICE9IE1WVDo6SU5WQUxJRF9TSU1QTEVfVkFMVUVfVFlQRSkKKyAgICAgICAgcmV0dXJuIE07CisKKyAgICAgIGFzc2VydCghSXNTY2FsYWJsZSAmJiAiV2UgZG9uJ3Qgc3VwcG9ydCBleHRlbmRlZCBzY2FsYWJsZSB0eXBlcyB5ZXQiKTsKKyAgICAgIHJldHVybiBnZXRFeHRlbmRlZFZlY3RvclZUKENvbnRleHQsIFZULCBOdW1FbGVtZW50cyk7CisgICAgfQorCisgICAgLy8vIFJldHVybnMgdGhlIEVWVCB0aGF0IHJlcHJlc2VudHMgYSB2ZWN0b3IgRUMuTWluIGVsZW1lbnRzIGluIGxlbmd0aCwKKyAgICAvLy8gd2hlcmUgZWFjaCBlbGVtZW50IGlzIG9mIHR5cGUgVlQuCisgICAgc3RhdGljIEVWVCBnZXRWZWN0b3JWVChMTFZNQ29udGV4dCAmQ29udGV4dCwgRVZUIFZULCBNVlQ6OkVsZW1lbnRDb3VudCBFQykgeworICAgICAgTVZUIE0gPSBNVlQ6OmdldFZlY3RvclZUKFZULlYsIEVDKTsKKyAgICAgIGlmIChNLlNpbXBsZVR5ICE9IE1WVDo6SU5WQUxJRF9TSU1QTEVfVkFMVUVfVFlQRSkKKyAgICAgICAgcmV0dXJuIE07CisgICAgICBhc3NlcnQgKCFFQy5TY2FsYWJsZSAmJiAiV2UgZG9uJ3Qgc3VwcG9ydCBleHRlbmRlZCBzY2FsYWJsZSB0eXBlcyB5ZXQiKTsKKyAgICAgIHJldHVybiBnZXRFeHRlbmRlZFZlY3RvclZUKENvbnRleHQsIFZULCBFQy5NaW4pOworICAgIH0KKworICAgIC8vLyBSZXR1cm4gYSB2ZWN0b3Igd2l0aCB0aGUgc2FtZSBudW1iZXIgb2YgZWxlbWVudHMgYXMgdGhpcyB2ZWN0b3IsIGJ1dAorICAgIC8vLyB3aXRoIHRoZSBlbGVtZW50IHR5cGUgY29udmVydGVkIHRvIGFuIGludGVnZXIgdHlwZSB3aXRoIHRoZSBzYW1lCisgICAgLy8vIGJpdHdpZHRoLgorICAgIEVWVCBjaGFuZ2VWZWN0b3JFbGVtZW50VHlwZVRvSW50ZWdlcigpIGNvbnN0IHsKKyAgICAgIGlmICghaXNTaW1wbGUoKSkgeworICAgICAgICBhc3NlcnQgKCFpc1NjYWxhYmxlVmVjdG9yKCkgJiYKKyAgICAgICAgICAgICAgICAiV2UgZG9uJ3Qgc3VwcG9ydCBleHRlbmRlZCBzY2FsYWJsZSB0eXBlcyB5ZXQiKTsKKyAgICAgICAgcmV0dXJuIGNoYW5nZUV4dGVuZGVkVmVjdG9yRWxlbWVudFR5cGVUb0ludGVnZXIoKTsKKyAgICAgIH0KKyAgICAgIE1WVCBFbHRUeSA9IGdldFNpbXBsZVZUKCkuZ2V0VmVjdG9yRWxlbWVudFR5cGUoKTsKKyAgICAgIHVuc2lnbmVkIEJpdFdpZHRoID0gRWx0VHkuZ2V0U2l6ZUluQml0cygpOworICAgICAgTVZUIEludFR5ID0gTVZUOjpnZXRJbnRlZ2VyVlQoQml0V2lkdGgpOworICAgICAgTVZUIFZlY1R5ID0gTVZUOjpnZXRWZWN0b3JWVChJbnRUeSwgZ2V0VmVjdG9yTnVtRWxlbWVudHMoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNTY2FsYWJsZVZlY3RvcigpKTsKKyAgICAgIGFzc2VydChWZWNUeS5TaW1wbGVUeSAhPSBNVlQ6OklOVkFMSURfU0lNUExFX1ZBTFVFX1RZUEUgJiYKKyAgICAgICAgICAgICAiU2ltcGxlIHZlY3RvciBWVCBub3QgcmVwcmVzZW50YWJsZSBieSBzaW1wbGUgaW50ZWdlciB2ZWN0b3IgVlQhIik7CisgICAgICByZXR1cm4gVmVjVHk7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0aGUgdHlwZSBjb252ZXJ0ZWQgdG8gYW4gZXF1aXZhbGVudGx5IHNpemVkIGludGVnZXIgb3IgdmVjdG9yCisgICAgLy8vIHdpdGggaW50ZWdlciBlbGVtZW50IHR5cGUuIFNpbWlsYXIgdG8gY2hhbmdlVmVjdG9yRWxlbWVudFR5cGVUb0ludGVnZXIsCisgICAgLy8vIGJ1dCBhbHNvIGhhbmRsZXMgc2NhbGFycy4KKyAgICBFVlQgY2hhbmdlVHlwZVRvSW50ZWdlcigpIHsKKyAgICAgIGlmIChpc1ZlY3RvcigpKQorICAgICAgICByZXR1cm4gY2hhbmdlVmVjdG9yRWxlbWVudFR5cGVUb0ludGVnZXIoKTsKKworICAgICAgaWYgKGlzU2ltcGxlKCkpCisgICAgICAgIHJldHVybiBNVlQ6OmdldEludGVnZXJWVChnZXRTaXplSW5CaXRzKCkpOworCisgICAgICByZXR1cm4gY2hhbmdlRXh0ZW5kZWRUeXBlVG9JbnRlZ2VyKCk7CisgICAgfQorCisgICAgLy8vIFRlc3QgaWYgdGhlIGdpdmVuIEVWVCBpcyBzaW1wbGUgKGFzIG9wcG9zZWQgdG8gYmVpbmcgZXh0ZW5kZWQpLgorICAgIGJvb2wgaXNTaW1wbGUoKSBjb25zdCB7CisgICAgICByZXR1cm4gVi5TaW1wbGVUeSAhPSBNVlQ6OklOVkFMSURfU0lNUExFX1ZBTFVFX1RZUEU7CisgICAgfQorCisgICAgLy8vIFRlc3QgaWYgdGhlIGdpdmVuIEVWVCBpcyBleHRlbmRlZCAoYXMgb3Bwb3NlZCB0byBiZWluZyBzaW1wbGUpLgorICAgIGJvb2wgaXNFeHRlbmRlZCgpIGNvbnN0IHsKKyAgICAgIHJldHVybiAhaXNTaW1wbGUoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIEZQIG9yIGEgdmVjdG9yIEZQIHR5cGUuCisgICAgYm9vbCBpc0Zsb2F0aW5nUG9pbnQoKSBjb25zdCB7CisgICAgICByZXR1cm4gaXNTaW1wbGUoKSA/IFYuaXNGbG9hdGluZ1BvaW50KCkgOiBpc0V4dGVuZGVkRmxvYXRpbmdQb2ludCgpOworICAgIH0KKworICAgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGFuIGludGVnZXIgb3IgYSB2ZWN0b3IgaW50ZWdlciB0eXBlLgorICAgIGJvb2wgaXNJbnRlZ2VyKCkgY29uc3QgeworICAgICAgcmV0dXJuIGlzU2ltcGxlKCkgPyBWLmlzSW50ZWdlcigpIDogaXNFeHRlbmRlZEludGVnZXIoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhbiBpbnRlZ2VyLCBidXQgbm90IGEgdmVjdG9yLgorICAgIGJvb2wgaXNTY2FsYXJJbnRlZ2VyKCkgY29uc3QgeworICAgICAgcmV0dXJuIGlzU2ltcGxlKCkgPyBWLmlzU2NhbGFySW50ZWdlcigpIDogaXNFeHRlbmRlZFNjYWxhckludGVnZXIoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIHZlY3RvciB2YWx1ZSB0eXBlLgorICAgIGJvb2wgaXNWZWN0b3IoKSBjb25zdCB7CisgICAgICByZXR1cm4gaXNTaW1wbGUoKSA/IFYuaXNWZWN0b3IoKSA6IGlzRXh0ZW5kZWRWZWN0b3IoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIHZlY3RvciB0eXBlIHdoZXJlIHRoZSBydW50aW1lCisgICAgLy8vIGxlbmd0aCBpcyBtYWNoaW5lIGRlcGVuZGVudAorICAgIGJvb2wgaXNTY2FsYWJsZVZlY3RvcigpIGNvbnN0IHsKKyAgICAgIC8vIEZJWE1FOiBXZSBkb24ndCBzdXBwb3J0IGV4dGVuZGVkIHNjYWxhYmxlIHR5cGVzIHlldCwgYmVjYXVzZSB0aGUKKyAgICAgIC8vIG1hdGNoaW5nIElSIHR5cGUgZG9lc24ndCBleGlzdC4gT25jZSBpdCBoYXMgYmVlbiBhZGRlZCwgdGhpcyBjYW4KKyAgICAgIC8vIGJlIGNoYW5nZWQgdG8gY2FsbCBpc0V4dGVuZGVkU2NhbGFibGVWZWN0b3IuCisgICAgICBpZiAoIWlzU2ltcGxlKCkpCisgICAgICAgIHJldHVybiBmYWxzZTsKKyAgICAgIHJldHVybiBWLmlzU2NhbGFibGVWZWN0b3IoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIDE2LWJpdCB2ZWN0b3IgdHlwZS4KKyAgICBib29sIGlzMTZCaXRWZWN0b3IoKSBjb25zdCB7CisgICAgICByZXR1cm4gaXNTaW1wbGUoKSA/IFYuaXMxNkJpdFZlY3RvcigpIDogaXNFeHRlbmRlZDE2Qml0VmVjdG9yKCk7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaXMgYSAzMi1iaXQgdmVjdG9yIHR5cGUuCisgICAgYm9vbCBpczMyQml0VmVjdG9yKCkgY29uc3QgeworICAgICAgcmV0dXJuIGlzU2ltcGxlKCkgPyBWLmlzMzJCaXRWZWN0b3IoKSA6IGlzRXh0ZW5kZWQzMkJpdFZlY3RvcigpOworICAgIH0KKworICAgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGEgNjQtYml0IHZlY3RvciB0eXBlLgorICAgIGJvb2wgaXM2NEJpdFZlY3RvcigpIGNvbnN0IHsKKyAgICAgIHJldHVybiBpc1NpbXBsZSgpID8gVi5pczY0Qml0VmVjdG9yKCkgOiBpc0V4dGVuZGVkNjRCaXRWZWN0b3IoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIDEyOC1iaXQgdmVjdG9yIHR5cGUuCisgICAgYm9vbCBpczEyOEJpdFZlY3RvcigpIGNvbnN0IHsKKyAgICAgIHJldHVybiBpc1NpbXBsZSgpID8gVi5pczEyOEJpdFZlY3RvcigpIDogaXNFeHRlbmRlZDEyOEJpdFZlY3RvcigpOworICAgIH0KKworICAgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGlzIGlzIGEgMjU2LWJpdCB2ZWN0b3IgdHlwZS4KKyAgICBib29sIGlzMjU2Qml0VmVjdG9yKCkgY29uc3QgeworICAgICAgcmV0dXJuIGlzU2ltcGxlKCkgPyBWLmlzMjU2Qml0VmVjdG9yKCkgOiBpc0V4dGVuZGVkMjU2Qml0VmVjdG9yKCk7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0cnVlIGlmIHRoaXMgaXMgYSA1MTItYml0IHZlY3RvciB0eXBlLgorICAgIGJvb2wgaXM1MTJCaXRWZWN0b3IoKSBjb25zdCB7CisgICAgICByZXR1cm4gaXNTaW1wbGUoKSA/IFYuaXM1MTJCaXRWZWN0b3IoKSA6IGlzRXh0ZW5kZWQ1MTJCaXRWZWN0b3IoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIDEwMjQtYml0IHZlY3RvciB0eXBlLgorICAgIGJvb2wgaXMxMDI0Qml0VmVjdG9yKCkgY29uc3QgeworICAgICAgcmV0dXJuIGlzU2ltcGxlKCkgPyBWLmlzMTAyNEJpdFZlY3RvcigpIDogaXNFeHRlbmRlZDEwMjRCaXRWZWN0b3IoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhIDIwNDgtYml0IHZlY3RvciB0eXBlLgorICAgIGJvb2wgaXMyMDQ4Qml0VmVjdG9yKCkgY29uc3QgeworICAgICAgcmV0dXJuIGlzU2ltcGxlKCkgPyBWLmlzMjA0OEJpdFZlY3RvcigpIDogaXNFeHRlbmRlZDIwNDhCaXRWZWN0b3IoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBhbiBvdmVybG9hZGVkIHR5cGUgZm9yIFRhYmxlR2VuLgorICAgIGJvb2wgaXNPdmVybG9hZGVkKCkgY29uc3QgeworICAgICAgcmV0dXJuIChWPT1NVlQ6OmlBbnkgfHwgVj09TVZUOjpmQW55IHx8IFY9PU1WVDo6dkFueSB8fCBWPT1NVlQ6OmlQVFJBbnkpOworICAgIH0KKworICAgIC8vLyBSZXR1cm4gdHJ1ZSBpZiB0aGUgYml0IHNpemUgaXMgYSBtdWx0aXBsZSBvZiA4LgorICAgIGJvb2wgaXNCeXRlU2l6ZWQoKSBjb25zdCB7CisgICAgICByZXR1cm4gKGdldFNpemVJbkJpdHMoKSAmIDcpID09IDA7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0cnVlIGlmIHRoZSBzaXplIGlzIGEgcG93ZXItb2YtdHdvIG51bWJlciBvZiBieXRlcy4KKyAgICBib29sIGlzUm91bmQoKSBjb25zdCB7CisgICAgICB1bnNpZ25lZCBCaXRTaXplID0gZ2V0U2l6ZUluQml0cygpOworICAgICAgcmV0dXJuIEJpdFNpemUgPj0gOCAmJiAhKEJpdFNpemUgJiAoQml0U2l6ZSAtIDEpKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBoYXMgdGhlIHNhbWUgbnVtYmVyIG9mIGJpdHMgYXMgVlQuCisgICAgYm9vbCBiaXRzRXEoRVZUIFZUKSBjb25zdCB7CisgICAgICBpZiAoRVZUOjpvcGVyYXRvcj09KFZUKSkgcmV0dXJuIHRydWU7CisgICAgICByZXR1cm4gZ2V0U2l6ZUluQml0cygpID09IFZULmdldFNpemVJbkJpdHMoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBoYXMgbW9yZSBiaXRzIHRoYW4gVlQuCisgICAgYm9vbCBiaXRzR1QoRVZUIFZUKSBjb25zdCB7CisgICAgICBpZiAoRVZUOjpvcGVyYXRvcj09KFZUKSkgcmV0dXJuIGZhbHNlOworICAgICAgcmV0dXJuIGdldFNpemVJbkJpdHMoKSA+IFZULmdldFNpemVJbkJpdHMoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBoYXMgbm8gbGVzcyBiaXRzIHRoYW4gVlQuCisgICAgYm9vbCBiaXRzR0UoRVZUIFZUKSBjb25zdCB7CisgICAgICBpZiAoRVZUOjpvcGVyYXRvcj09KFZUKSkgcmV0dXJuIHRydWU7CisgICAgICByZXR1cm4gZ2V0U2l6ZUluQml0cygpID49IFZULmdldFNpemVJbkJpdHMoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBoYXMgbGVzcyBiaXRzIHRoYW4gVlQuCisgICAgYm9vbCBiaXRzTFQoRVZUIFZUKSBjb25zdCB7CisgICAgICBpZiAoRVZUOjpvcGVyYXRvcj09KFZUKSkgcmV0dXJuIGZhbHNlOworICAgICAgcmV0dXJuIGdldFNpemVJbkJpdHMoKSA8IFZULmdldFNpemVJbkJpdHMoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRydWUgaWYgdGhpcyBoYXMgbm8gbW9yZSBiaXRzIHRoYW4gVlQuCisgICAgYm9vbCBiaXRzTEUoRVZUIFZUKSBjb25zdCB7CisgICAgICBpZiAoRVZUOjpvcGVyYXRvcj09KFZUKSkgcmV0dXJuIHRydWU7CisgICAgICByZXR1cm4gZ2V0U2l6ZUluQml0cygpIDw9IFZULmdldFNpemVJbkJpdHMoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRoZSBTaW1wbGVWYWx1ZVR5cGUgaGVsZCBpbiB0aGUgc3BlY2lmaWVkIHNpbXBsZSBFVlQuCisgICAgTVZUIGdldFNpbXBsZVZUKCkgY29uc3QgeworICAgICAgYXNzZXJ0KGlzU2ltcGxlKCkgJiYgIkV4cGVjdGVkIGEgU2ltcGxlVmFsdWVUeXBlISIpOworICAgICAgcmV0dXJuIFY7CisgICAgfQorCisgICAgLy8vIElmIHRoaXMgaXMgYSB2ZWN0b3IgdHlwZSwgcmV0dXJuIHRoZSBlbGVtZW50IHR5cGUsIG90aGVyd2lzZSByZXR1cm4KKyAgICAvLy8gdGhpcy4KKyAgICBFVlQgZ2V0U2NhbGFyVHlwZSgpIGNvbnN0IHsKKyAgICAgIHJldHVybiBpc1ZlY3RvcigpID8gZ2V0VmVjdG9yRWxlbWVudFR5cGUoKSA6ICp0aGlzOworICAgIH0KKworICAgIC8vLyBHaXZlbiBhIHZlY3RvciB0eXBlLCByZXR1cm4gdGhlIHR5cGUgb2YgZWFjaCBlbGVtZW50LgorICAgIEVWVCBnZXRWZWN0b3JFbGVtZW50VHlwZSgpIGNvbnN0IHsKKyAgICAgIGFzc2VydChpc1ZlY3RvcigpICYmICJJbnZhbGlkIHZlY3RvciB0eXBlISIpOworICAgICAgaWYgKGlzU2ltcGxlKCkpCisgICAgICAgIHJldHVybiBWLmdldFZlY3RvckVsZW1lbnRUeXBlKCk7CisgICAgICByZXR1cm4gZ2V0RXh0ZW5kZWRWZWN0b3JFbGVtZW50VHlwZSgpOworICAgIH0KKworICAgIC8vLyBHaXZlbiBhIHZlY3RvciB0eXBlLCByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpdCBjb250YWlucy4KKyAgICB1bnNpZ25lZCBnZXRWZWN0b3JOdW1FbGVtZW50cygpIGNvbnN0IHsKKyAgICAgIGFzc2VydChpc1ZlY3RvcigpICYmICJJbnZhbGlkIHZlY3RvciB0eXBlISIpOworICAgICAgaWYgKGlzU2ltcGxlKCkpCisgICAgICAgIHJldHVybiBWLmdldFZlY3Rvck51bUVsZW1lbnRzKCk7CisgICAgICByZXR1cm4gZ2V0RXh0ZW5kZWRWZWN0b3JOdW1FbGVtZW50cygpOworICAgIH0KKworICAgIC8vIEdpdmVuIGEgKHBvc3NpYmx5IHNjYWxhYmxlKSB2ZWN0b3IgdHlwZSwgcmV0dXJuIHRoZSBFbGVtZW50Q291bnQKKyAgICBNVlQ6OkVsZW1lbnRDb3VudCBnZXRWZWN0b3JFbGVtZW50Q291bnQoKSBjb25zdCB7CisgICAgICBhc3NlcnQoKGlzVmVjdG9yKCkpICYmICJJbnZhbGlkIHZlY3RvciB0eXBlISIpOworICAgICAgaWYgKGlzU2ltcGxlKCkpCisgICAgICAgIHJldHVybiBWLmdldFZlY3RvckVsZW1lbnRDb3VudCgpOworCisgICAgICBhc3NlcnQoIWlzU2NhbGFibGVWZWN0b3IoKSAmJgorICAgICAgICAgICAgICJXZSBkb24ndCBzdXBwb3J0IGV4dGVuZGVkIHNjYWxhYmxlIHR5cGVzIHlldCIpOworICAgICAgcmV0dXJuIHtnZXRFeHRlbmRlZFZlY3Rvck51bUVsZW1lbnRzKCksIGZhbHNlfTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRoZSBzaXplIG9mIHRoZSBzcGVjaWZpZWQgdmFsdWUgdHlwZSBpbiBiaXRzLgorICAgIHVuc2lnbmVkIGdldFNpemVJbkJpdHMoKSBjb25zdCB7CisgICAgICBpZiAoaXNTaW1wbGUoKSkKKyAgICAgICAgcmV0dXJuIFYuZ2V0U2l6ZUluQml0cygpOworICAgICAgcmV0dXJuIGdldEV4dGVuZGVkU2l6ZUluQml0cygpOworICAgIH0KKworICAgIHVuc2lnbmVkIGdldFNjYWxhclNpemVJbkJpdHMoKSBjb25zdCB7CisgICAgICByZXR1cm4gZ2V0U2NhbGFyVHlwZSgpLmdldFNpemVJbkJpdHMoKTsKKyAgICB9CisKKyAgICAvLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgb3ZlcndyaXR0ZW4gYnkgYSBzdG9yZSBvZiB0aGUgc3BlY2lmaWVkIHZhbHVlCisgICAgLy8vIHR5cGUuCisgICAgdW5zaWduZWQgZ2V0U3RvcmVTaXplKCkgY29uc3QgeworICAgICAgcmV0dXJuIChnZXRTaXplSW5CaXRzKCkgKyA3KSAvIDg7CisgICAgfQorCisgICAgLy8vIFJldHVybiB0aGUgbnVtYmVyIG9mIGJpdHMgb3ZlcndyaXR0ZW4gYnkgYSBzdG9yZSBvZiB0aGUgc3BlY2lmaWVkIHZhbHVlCisgICAgLy8vIHR5cGUuCisgICAgdW5zaWduZWQgZ2V0U3RvcmVTaXplSW5CaXRzKCkgY29uc3QgeworICAgICAgcmV0dXJuIGdldFN0b3JlU2l6ZSgpICogODsKKyAgICB9CisKKyAgICAvLy8gUm91bmRzIHRoZSBiaXQtd2lkdGggb2YgdGhlIGdpdmVuIGludGVnZXIgRVZUIHVwIHRvIHRoZSBuZWFyZXN0IHBvd2VyIG9mCisgICAgLy8vIHR3byAoYW5kIGF0IGxlYXN0IHRvIGVpZ2h0KSwgYW5kIHJldHVybnMgdGhlIGludGVnZXIgRVZUIHdpdGggdGhhdAorICAgIC8vLyBudW1iZXIgb2YgYml0cy4KKyAgICBFVlQgZ2V0Um91bmRJbnRlZ2VyVHlwZShMTFZNQ29udGV4dCAmQ29udGV4dCkgY29uc3QgeworICAgICAgYXNzZXJ0KGlzSW50ZWdlcigpICYmICFpc1ZlY3RvcigpICYmICJJbnZhbGlkIGludGVnZXIgdHlwZSEiKTsKKyAgICAgIHVuc2lnbmVkIEJpdFdpZHRoID0gZ2V0U2l6ZUluQml0cygpOworICAgICAgaWYgKEJpdFdpZHRoIDw9IDgpCisgICAgICAgIHJldHVybiBFVlQoTVZUOjppOCk7CisgICAgICByZXR1cm4gZ2V0SW50ZWdlclZUKENvbnRleHQsIDEgPDwgTG9nMl8zMl9DZWlsKEJpdFdpZHRoKSk7CisgICAgfQorCisgICAgLy8vIEZpbmRzIHRoZSBzbWFsbGVzdCBzaW1wbGUgdmFsdWUgdHlwZSB0aGF0IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0bworICAgIC8vLyBoYWxmIHRoZSB3aWR0aCBvZiB0aGlzIEVWVC4gSWYgbm8gc2ltcGxlIHZhbHVlIHR5cGUgY2FuIGJlIGZvdW5kLCBhbgorICAgIC8vLyBleHRlbmRlZCBpbnRlZ2VyIHZhbHVlIHR5cGUgb2YgaGFsZiB0aGUgc2l6ZSAocm91bmRlZCB1cCkgaXMgcmV0dXJuZWQuCisgICAgRVZUIGdldEhhbGZTaXplZEludGVnZXJWVChMTFZNQ29udGV4dCAmQ29udGV4dCkgY29uc3QgeworICAgICAgYXNzZXJ0KGlzSW50ZWdlcigpICYmICFpc1ZlY3RvcigpICYmICJJbnZhbGlkIGludGVnZXIgdHlwZSEiKTsKKyAgICAgIHVuc2lnbmVkIEVWVFNpemUgPSBnZXRTaXplSW5CaXRzKCk7CisgICAgICBmb3IgKHVuc2lnbmVkIEludFZUID0gTVZUOjpGSVJTVF9JTlRFR0VSX1ZBTFVFVFlQRTsKKyAgICAgICAgICBJbnRWVCA8PSBNVlQ6OkxBU1RfSU5URUdFUl9WQUxVRVRZUEU7ICsrSW50VlQpIHsKKyAgICAgICAgRVZUIEhhbGZWVCA9IEVWVCgoTVZUOjpTaW1wbGVWYWx1ZVR5cGUpSW50VlQpOworICAgICAgICBpZiAoSGFsZlZULmdldFNpemVJbkJpdHMoKSAqIDIgPj0gRVZUU2l6ZSkKKyAgICAgICAgICByZXR1cm4gSGFsZlZUOworICAgICAgfQorICAgICAgcmV0dXJuIGdldEludGVnZXJWVChDb250ZXh0LCAoRVZUU2l6ZSArIDEpIC8gMik7CisgICAgfQorCisgICAgLy8vIFJldHVybiBhIFZUIGZvciBhbiBpbnRlZ2VyIHZlY3RvciB0eXBlIHdpdGggdGhlIHNpemUgb2YgdGhlCisgICAgLy8vIGVsZW1lbnRzIGRvdWJsZWQuIFRoZSB0eXBlZCByZXR1cm5lZCBtYXkgYmUgYW4gZXh0ZW5kZWQgdHlwZS4KKyAgICBFVlQgd2lkZW5JbnRlZ2VyVmVjdG9yRWxlbWVudFR5cGUoTExWTUNvbnRleHQgJkNvbnRleHQpIGNvbnN0IHsKKyAgICAgIEVWVCBFbHRWVCA9IGdldFZlY3RvckVsZW1lbnRUeXBlKCk7CisgICAgICBFbHRWVCA9IEVWVDo6Z2V0SW50ZWdlclZUKENvbnRleHQsIDIgKiBFbHRWVC5nZXRTaXplSW5CaXRzKCkpOworICAgICAgcmV0dXJuIEVWVDo6Z2V0VmVjdG9yVlQoQ29udGV4dCwgRWx0VlQsIGdldFZlY3RvckVsZW1lbnRDb3VudCgpKTsKKyAgICB9CisKKyAgICAvLyBSZXR1cm4gYSBWVCBmb3IgYSB2ZWN0b3IgdHlwZSB3aXRoIHRoZSBzYW1lIGVsZW1lbnQgdHlwZSBidXQKKyAgICAvLyBoYWxmIHRoZSBudW1iZXIgb2YgZWxlbWVudHMuIFRoZSB0eXBlIHJldHVybmVkIG1heSBiZSBhbgorICAgIC8vIGV4dGVuZGVkIHR5cGUuCisgICAgRVZUIGdldEhhbGZOdW1WZWN0b3JFbGVtZW50c1ZUKExMVk1Db250ZXh0ICZDb250ZXh0KSBjb25zdCB7CisgICAgICBFVlQgRWx0VlQgPSBnZXRWZWN0b3JFbGVtZW50VHlwZSgpOworICAgICAgYXV0byBFbHRDbnQgPSBnZXRWZWN0b3JFbGVtZW50Q291bnQoKTsKKyAgICAgIGFzc2VydCghKEVsdENudC5NaW4gJiAxKSAmJiAiU3BsaXR0aW5nIHZlY3RvciwgYnV0IG5vdCBpbiBoYWxmISIpOworICAgICAgcmV0dXJuIEVWVDo6Z2V0VmVjdG9yVlQoQ29udGV4dCwgRWx0VlQsIEVsdENudCAvIDIpOworICAgIH0KKworICAgIC8vLyBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHZlY3RvciBpcyBhIHBvd2VyIG9mIDIuCisgICAgYm9vbCBpc1BvdzJWZWN0b3JUeXBlKCkgY29uc3QgeworICAgICAgdW5zaWduZWQgTkVsdHMgPSBnZXRWZWN0b3JOdW1FbGVtZW50cygpOworICAgICAgcmV0dXJuICEoTkVsdHMgJiAoTkVsdHMgLSAxKSk7CisgICAgfQorCisgICAgLy8vIFdpZGVucyB0aGUgbGVuZ3RoIG9mIHRoZSBnaXZlbiB2ZWN0b3IgRVZUIHVwIHRvIHRoZSBuZWFyZXN0IHBvd2VyIG9mIDIKKyAgICAvLy8gYW5kIHJldHVybnMgdGhhdCB0eXBlLgorICAgIEVWVCBnZXRQb3cyVmVjdG9yVHlwZShMTFZNQ29udGV4dCAmQ29udGV4dCkgY29uc3QgeworICAgICAgaWYgKCFpc1BvdzJWZWN0b3JUeXBlKCkpIHsKKyAgICAgICAgdW5zaWduZWQgTkVsdHMgPSBnZXRWZWN0b3JOdW1FbGVtZW50cygpOworICAgICAgICB1bnNpZ25lZCBQb3cyTkVsdHMgPSAxIDw8ICBMb2cyXzMyX0NlaWwoTkVsdHMpOworICAgICAgICByZXR1cm4gRVZUOjpnZXRWZWN0b3JWVChDb250ZXh0LCBnZXRWZWN0b3JFbGVtZW50VHlwZSgpLCBQb3cyTkVsdHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU2NhbGFibGVWZWN0b3IoKSk7CisgICAgICB9CisgICAgICBlbHNlIHsKKyAgICAgICAgcmV0dXJuICp0aGlzOworICAgICAgfQorICAgIH0KKworICAgIC8vLyBUaGlzIGZ1bmN0aW9uIHJldHVybnMgdmFsdWUgdHlwZSBhcyBhIHN0cmluZywgZS5nLiAiaTMyIi4KKyAgICBzdGQ6OnN0cmluZyBnZXRFVlRTdHJpbmcoKSBjb25zdDsKKworICAgIC8vLyBUaGlzIG1ldGhvZCByZXR1cm5zIGFuIExMVk0gdHlwZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBzcGVjaWZpZWQgRVZULgorICAgIC8vLyBGb3IgaW50ZWdlciB0eXBlcywgdGhpcyByZXR1cm5zIGFuIHVuc2lnbmVkIHR5cGUuIE5vdGUgdGhhdCB0aGlzIHdpbGwKKyAgICAvLy8gYWJvcnQgZm9yIHR5cGVzIHRoYXQgY2Fubm90IGJlIHJlcHJlc2VudGVkLgorICAgIFR5cGUgKmdldFR5cGVGb3JFVlQoTExWTUNvbnRleHQgJkNvbnRleHQpIGNvbnN0OworCisgICAgLy8vIFJldHVybiB0aGUgdmFsdWUgdHlwZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBzcGVjaWZpZWQgdHlwZS4KKyAgICAvLy8gVGhpcyByZXR1cm5zIGFsbCBwb2ludGVycyBhcyBpUFRSLiAgSWYgSGFuZGxlVW5rbm93biBpcyB0cnVlLCB1bmtub3duCisgICAgLy8vIHR5cGVzIGFyZSByZXR1cm5lZCBhcyBPdGhlciwgb3RoZXJ3aXNlIHRoZXkgYXJlIGludmFsaWQuCisgICAgc3RhdGljIEVWVCBnZXRFVlQoVHlwZSAqVHksIGJvb2wgSGFuZGxlVW5rbm93biA9IGZhbHNlKTsKKworICAgIGludHB0cl90IGdldFJhd0JpdHMoKSBjb25zdCB7CisgICAgICBpZiAoaXNTaW1wbGUoKSkKKyAgICAgICAgcmV0dXJuIFYuU2ltcGxlVHk7CisgICAgICBlbHNlCisgICAgICAgIHJldHVybiAoaW50cHRyX3QpKExMVk1UeSk7CisgICAgfQorCisgICAgLy8vIEEgbWVhbmluZ2xlc3MgYnV0IHdlbGwtYmVoYXZlZCBvcmRlciwgdXNlZnVsIGZvciBjb25zdHJ1Y3RpbmcKKyAgICAvLy8gY29udGFpbmVycy4KKyAgICBzdHJ1Y3QgY29tcGFyZVJhd0JpdHMgeworICAgICAgYm9vbCBvcGVyYXRvcigpKEVWVCBMLCBFVlQgUikgY29uc3QgeworICAgICAgICBpZiAoTC5WLlNpbXBsZVR5ID09IFIuVi5TaW1wbGVUeSkKKyAgICAgICAgICByZXR1cm4gTC5MTFZNVHkgPCBSLkxMVk1UeTsKKyAgICAgICAgZWxzZQorICAgICAgICAgIHJldHVybiBMLlYuU2ltcGxlVHkgPCBSLlYuU2ltcGxlVHk7CisgICAgICB9CisgICAgfTsKKworICBwcml2YXRlOgorICAgIC8vIE1ldGhvZHMgZm9yIGhhbmRsaW5nIHRoZSBFeHRlbmRlZC10eXBlIGNhc2UgaW4gZnVuY3Rpb25zIGFib3ZlLgorICAgIC8vIFRoZXNlIGFyZSBhbGwgb3V0LW9mLWxpbmUgdG8gcHJldmVudCB1c2VycyBvZiB0aGlzIGhlYWRlciBmaWxlCisgICAgLy8gZnJvbSBoYXZpbmcgYSBkZXBlbmRlbmN5IG9uIFR5cGUuaC4KKyAgICBFVlQgY2hhbmdlRXh0ZW5kZWRUeXBlVG9JbnRlZ2VyKCkgY29uc3Q7CisgICAgRVZUIGNoYW5nZUV4dGVuZGVkVmVjdG9yRWxlbWVudFR5cGVUb0ludGVnZXIoKSBjb25zdDsKKyAgICBzdGF0aWMgRVZUIGdldEV4dGVuZGVkSW50ZWdlclZUKExMVk1Db250ZXh0ICZDLCB1bnNpZ25lZCBCaXRXaWR0aCk7CisgICAgc3RhdGljIEVWVCBnZXRFeHRlbmRlZFZlY3RvclZUKExMVk1Db250ZXh0ICZDLCBFVlQgVlQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIE51bUVsZW1lbnRzKTsKKyAgICBib29sIGlzRXh0ZW5kZWRGbG9hdGluZ1BvaW50KCkgY29uc3QgTExWTV9SRUFET05MWTsKKyAgICBib29sIGlzRXh0ZW5kZWRJbnRlZ2VyKCkgY29uc3QgTExWTV9SRUFET05MWTsKKyAgICBib29sIGlzRXh0ZW5kZWRTY2FsYXJJbnRlZ2VyKCkgY29uc3QgTExWTV9SRUFET05MWTsKKyAgICBib29sIGlzRXh0ZW5kZWRWZWN0b3IoKSBjb25zdCBMTFZNX1JFQURPTkxZOworICAgIGJvb2wgaXNFeHRlbmRlZDE2Qml0VmVjdG9yKCkgY29uc3QgTExWTV9SRUFET05MWTsKKyAgICBib29sIGlzRXh0ZW5kZWQzMkJpdFZlY3RvcigpIGNvbnN0IExMVk1fUkVBRE9OTFk7CisgICAgYm9vbCBpc0V4dGVuZGVkNjRCaXRWZWN0b3IoKSBjb25zdCBMTFZNX1JFQURPTkxZOworICAgIGJvb2wgaXNFeHRlbmRlZDEyOEJpdFZlY3RvcigpIGNvbnN0IExMVk1fUkVBRE9OTFk7CisgICAgYm9vbCBpc0V4dGVuZGVkMjU2Qml0VmVjdG9yKCkgY29uc3QgTExWTV9SRUFET05MWTsKKyAgICBib29sIGlzRXh0ZW5kZWQ1MTJCaXRWZWN0b3IoKSBjb25zdCBMTFZNX1JFQURPTkxZOworICAgIGJvb2wgaXNFeHRlbmRlZDEwMjRCaXRWZWN0b3IoKSBjb25zdCBMTFZNX1JFQURPTkxZOworICAgIGJvb2wgaXNFeHRlbmRlZDIwNDhCaXRWZWN0b3IoKSBjb25zdCBMTFZNX1JFQURPTkxZOworICAgIEVWVCBnZXRFeHRlbmRlZFZlY3RvckVsZW1lbnRUeXBlKCkgY29uc3Q7CisgICAgdW5zaWduZWQgZ2V0RXh0ZW5kZWRWZWN0b3JOdW1FbGVtZW50cygpIGNvbnN0IExMVk1fUkVBRE9OTFk7CisgICAgdW5zaWduZWQgZ2V0RXh0ZW5kZWRTaXplSW5CaXRzKCkgY29uc3QgTExWTV9SRUFET05MWTsKKyAgfTsKKworfSAvLyBlbmQgbmFtZXNwYWNlIGxsdm0KKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9WQUxVRVRZUEVTX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9WYWx1ZVR5cGVzLnRkIGIvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1ZhbHVlVHlwZXMudGQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjczZWVjOQotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9WYWx1ZVR5cGVzLnRkCkBAIC0wLDAgKzEsMTY5IEBACisvLz09PS0gVmFsdWVUeXBlcy50ZCAtIFZhbHVlVHlwZSBkZWZpbml0aW9ucyAtLS0tLS0tLS0tLS0tLS0qLSB0YWJsZWdlbiAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIFZhbHVlIHR5cGVzIC0gVGhlc2UgdmFsdWVzIGNvcnJlc3BvbmQgdG8gdGhlIHJlZ2lzdGVyIHR5cGVzIGRlZmluZWQgaW4gdGhlCisvLyBWYWx1ZVR5cGVzLmggZmlsZS4gIElmIHlvdSB1cGRhdGUgYW55dGhpbmcgaGVyZSwgeW91IG11c3QgdXBkYXRlIGl0IHRoZXJlIGFzCisvLyB3ZWxsIQorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisKK2NsYXNzIFZhbHVlVHlwZTxpbnQgc2l6ZSwgaW50IHZhbHVlPiB7CisgIHN0cmluZyBOYW1lc3BhY2UgPSAiTVZUIjsKKyAgaW50IFNpemUgPSBzaXplOworICBpbnQgVmFsdWUgPSB2YWx1ZTsKK30KKworZGVmIE90aGVyVlQ6IFZhbHVlVHlwZTwwICAsICAxPjsgICAvLyAiT3RoZXIiIHZhbHVlCitkZWYgaTEgICAgIDogVmFsdWVUeXBlPDEgICwgIDI+OyAgIC8vIE9uZSBiaXQgYm9vbGVhbiB2YWx1ZQorZGVmIGk4ICAgICA6IFZhbHVlVHlwZTw4ICAsICAzPjsgICAvLyA4LWJpdCBpbnRlZ2VyIHZhbHVlCitkZWYgaTE2ICAgIDogVmFsdWVUeXBlPDE2ICwgIDQ+OyAgIC8vIDE2LWJpdCBpbnRlZ2VyIHZhbHVlCitkZWYgaTMyICAgIDogVmFsdWVUeXBlPDMyICwgIDU+OyAgIC8vIDMyLWJpdCBpbnRlZ2VyIHZhbHVlCitkZWYgaTY0ICAgIDogVmFsdWVUeXBlPDY0ICwgIDY+OyAgIC8vIDY0LWJpdCBpbnRlZ2VyIHZhbHVlCitkZWYgaTEyOCAgIDogVmFsdWVUeXBlPDEyOCwgIDc+OyAgIC8vIDEyOC1iaXQgaW50ZWdlciB2YWx1ZQorZGVmIGYxNiAgICA6IFZhbHVlVHlwZTwxNiAsICA4PjsgICAvLyAxNi1iaXQgZmxvYXRpbmcgcG9pbnQgdmFsdWUKK2RlZiBmMzIgICAgOiBWYWx1ZVR5cGU8MzIgLCAgOT47ICAgLy8gMzItYml0IGZsb2F0aW5nIHBvaW50IHZhbHVlCitkZWYgZjY0ICAgIDogVmFsdWVUeXBlPDY0ICwgMTA+OyAgIC8vIDY0LWJpdCBmbG9hdGluZyBwb2ludCB2YWx1ZQorZGVmIGY4MCAgICA6IFZhbHVlVHlwZTw4MCAsIDExPjsgICAvLyA4MC1iaXQgZmxvYXRpbmcgcG9pbnQgdmFsdWUKK2RlZiBmMTI4ICAgOiBWYWx1ZVR5cGU8MTI4LCAxMj47ICAgLy8gMTI4LWJpdCBmbG9hdGluZyBwb2ludCB2YWx1ZQorZGVmIHBwY2YxMjg6IFZhbHVlVHlwZTwxMjgsIDEzPjsgICAvLyBQUEMgMTI4LWJpdCBmbG9hdGluZyBwb2ludCB2YWx1ZQorCitkZWYgdjFpMSAgIDogVmFsdWVUeXBlPDEgLCAgMTQ+OyAgIC8vICAgMSB4IGkxIHZlY3RvciB2YWx1ZQorZGVmIHYyaTEgICA6IFZhbHVlVHlwZTwyICwgIDE1PjsgICAvLyAgIDIgeCBpMSB2ZWN0b3IgdmFsdWUKK2RlZiB2NGkxICAgOiBWYWx1ZVR5cGU8NCAsICAxNj47ICAgLy8gICA0IHggaTEgdmVjdG9yIHZhbHVlCitkZWYgdjhpMSAgIDogVmFsdWVUeXBlPDggLCAgMTc+OyAgIC8vICAgOCB4IGkxIHZlY3RvciB2YWx1ZQorZGVmIHYxNmkxICA6IFZhbHVlVHlwZTwxNiwgIDE4PjsgICAvLyAgMTYgeCBpMSB2ZWN0b3IgdmFsdWUKK2RlZiB2MzJpMSAgOiBWYWx1ZVR5cGU8MzIgLCAxOT47ICAgLy8gIDMyIHggaTEgdmVjdG9yIHZhbHVlCitkZWYgdjY0aTEgIDogVmFsdWVUeXBlPDY0ICwgMjA+OyAgIC8vICA2NCB4IGkxIHZlY3RvciB2YWx1ZQorZGVmIHYxMjhpMSA6IFZhbHVlVHlwZTwxMjgsIDIxPjsgICAvLyAxMjggeCBpMSB2ZWN0b3IgdmFsdWUKK2RlZiB2NTEyaTEgOiBWYWx1ZVR5cGU8NTEyLCAyMj47ICAgLy8gNTEyIHggaTEgdmVjdG9yIHZhbHVlCitkZWYgdjEwMjRpMTogVmFsdWVUeXBlPDEwMjQsMjM+OyAgIC8vMTAyNCB4IGkxIHZlY3RvciB2YWx1ZQorCitkZWYgdjFpOCAgIDogVmFsdWVUeXBlPDgsICAgMjQ+OyAgIC8vICAxIHggaTggIHZlY3RvciB2YWx1ZQorZGVmIHYyaTggICA6IFZhbHVlVHlwZTwxNiAsIDI1PjsgICAvLyAgMiB4IGk4ICB2ZWN0b3IgdmFsdWUKK2RlZiB2NGk4ICAgOiBWYWx1ZVR5cGU8MzIgLCAyNj47ICAgLy8gIDQgeCBpOCAgdmVjdG9yIHZhbHVlCitkZWYgdjhpOCAgIDogVmFsdWVUeXBlPDY0ICwgMjc+OyAgIC8vICA4IHggaTggIHZlY3RvciB2YWx1ZQorZGVmIHYxNmk4ICA6IFZhbHVlVHlwZTwxMjgsIDI4PjsgICAvLyAxNiB4IGk4ICB2ZWN0b3IgdmFsdWUKK2RlZiB2MzJpOCAgOiBWYWx1ZVR5cGU8MjU2LCAyOT47ICAgLy8gMzIgeCBpOCAgdmVjdG9yIHZhbHVlCitkZWYgdjY0aTggIDogVmFsdWVUeXBlPDUxMiwgMzA+OyAgIC8vIDY0IHggaTggIHZlY3RvciB2YWx1ZQorZGVmIHYxMjhpOCA6IFZhbHVlVHlwZTwxMDI0LDMxPjsgICAvLzEyOCB4IGk4ICB2ZWN0b3IgdmFsdWUKK2RlZiB2MjU2aTggOiBWYWx1ZVR5cGU8MjA0OCwzMj47ICAgLy8yNTYgeCBpOCAgdmVjdG9yIHZhbHVlCisKK2RlZiB2MWkxNiAgOiBWYWx1ZVR5cGU8MTYgLCAzMz47ICAgLy8gIDEgeCBpMTYgdmVjdG9yIHZhbHVlCitkZWYgdjJpMTYgIDogVmFsdWVUeXBlPDMyICwgMzQ+OyAgIC8vICAyIHggaTE2IHZlY3RvciB2YWx1ZQorZGVmIHY0aTE2ICA6IFZhbHVlVHlwZTw2NCAsIDM1PjsgICAvLyAgNCB4IGkxNiB2ZWN0b3IgdmFsdWUKK2RlZiB2OGkxNiAgOiBWYWx1ZVR5cGU8MTI4LCAzNj47ICAgLy8gIDggeCBpMTYgdmVjdG9yIHZhbHVlCitkZWYgdjE2aTE2IDogVmFsdWVUeXBlPDI1NiwgMzc+OyAgIC8vIDE2IHggaTE2IHZlY3RvciB2YWx1ZQorZGVmIHYzMmkxNiA6IFZhbHVlVHlwZTw1MTIsIDM4PjsgICAvLyAzMiB4IGkxNiB2ZWN0b3IgdmFsdWUKK2RlZiB2NjRpMTYgOiBWYWx1ZVR5cGU8MTAyNCwzOT47ICAgLy8gNjQgeCBpMTYgdmVjdG9yIHZhbHVlCitkZWYgdjEyOGkxNjogVmFsdWVUeXBlPDIwNDgsNDA+OyAgIC8vMTI4IHggaTE2IHZlY3RvciB2YWx1ZQorCitkZWYgdjFpMzIgIDogVmFsdWVUeXBlPDMyICwgNDE+OyAgIC8vICAxIHggaTMyIHZlY3RvciB2YWx1ZQorZGVmIHYyaTMyICA6IFZhbHVlVHlwZTw2NCAsIDQyPjsgICAvLyAgMiB4IGkzMiB2ZWN0b3IgdmFsdWUKK2RlZiB2NGkzMiAgOiBWYWx1ZVR5cGU8MTI4LCA0Mz47ICAgLy8gIDQgeCBpMzIgdmVjdG9yIHZhbHVlCitkZWYgdjhpMzIgIDogVmFsdWVUeXBlPDI1NiwgNDQ+OyAgIC8vICA4IHggaTMyIHZlY3RvciB2YWx1ZQorZGVmIHYxNmkzMiA6IFZhbHVlVHlwZTw1MTIsIDQ1PjsgICAvLyAxNiB4IGkzMiB2ZWN0b3IgdmFsdWUKK2RlZiB2MzJpMzIgOiBWYWx1ZVR5cGU8MTAyNCw0Nj47ICAgLy8gMzIgeCBpMzIgdmVjdG9yIHZhbHVlCitkZWYgdjY0aTMyIDogVmFsdWVUeXBlPDIwNDgsNDc+OyAgIC8vIDY0IHggaTMyIHZlY3RvciB2YWx1ZQorCitkZWYgdjFpNjQgIDogVmFsdWVUeXBlPDY0ICwgNDg+OyAgIC8vICAxIHggaTY0IHZlY3RvciB2YWx1ZQorZGVmIHYyaTY0ICA6IFZhbHVlVHlwZTwxMjgsIDQ5PjsgICAvLyAgMiB4IGk2NCB2ZWN0b3IgdmFsdWUKK2RlZiB2NGk2NCAgOiBWYWx1ZVR5cGU8MjU2LCA1MD47ICAgLy8gIDQgeCBpNjQgdmVjdG9yIHZhbHVlCitkZWYgdjhpNjQgIDogVmFsdWVUeXBlPDUxMiwgNTE+OyAgIC8vICA4IHggaTY0IHZlY3RvciB2YWx1ZQorZGVmIHYxNmk2NCA6IFZhbHVlVHlwZTwxMDI0LDUyPjsgICAvLyAxNiB4IGk2NCB2ZWN0b3IgdmFsdWUKK2RlZiB2MzJpNjQgOiBWYWx1ZVR5cGU8MjA0OCw1Mz47ICAgLy8gMzIgeCBpNjQgdmVjdG9yIHZhbHVlCisKK2RlZiB2MWkxMjggOiBWYWx1ZVR5cGU8MTI4LCA1ND47ICAgLy8gIDEgeCBpMTI4IHZlY3RvciB2YWx1ZQorCitkZWYgbnh2MWkxICA6IFZhbHVlVHlwZTwxLCAgIDU1PjsgIC8vIG4geCAgMSB4IGkxICB2ZWN0b3IgdmFsdWUKK2RlZiBueHYyaTEgIDogVmFsdWVUeXBlPDIsICAgNTY+OyAgLy8gbiB4ICAyIHggaTEgIHZlY3RvciB2YWx1ZQorZGVmIG54djRpMSAgOiBWYWx1ZVR5cGU8NCwgICA1Nz47ICAvLyBuIHggIDQgeCBpMSAgdmVjdG9yIHZhbHVlCitkZWYgbnh2OGkxICA6IFZhbHVlVHlwZTw4LCAgIDU4PjsgIC8vIG4geCAgOCB4IGkxICB2ZWN0b3IgdmFsdWUKK2RlZiBueHYxNmkxIDogVmFsdWVUeXBlPDE2LCAgNTk+OyAgLy8gbiB4IDE2IHggaTEgIHZlY3RvciB2YWx1ZQorZGVmIG54djMyaTEgOiBWYWx1ZVR5cGU8MzIsICA2MD47ICAvLyBuIHggMzIgeCBpMSAgdmVjdG9yIHZhbHVlCisKK2RlZiBueHYxaTggIDogVmFsdWVUeXBlPDgsICAgNjE+OyAgLy8gbiB4ICAxIHggaTggIHZlY3RvciB2YWx1ZQorZGVmIG54djJpOCAgOiBWYWx1ZVR5cGU8MTYsICA2Mj47ICAvLyBuIHggIDIgeCBpOCAgdmVjdG9yIHZhbHVlCitkZWYgbnh2NGk4ICA6IFZhbHVlVHlwZTwzMiwgIDYzPjsgIC8vIG4geCAgNCB4IGk4ICB2ZWN0b3IgdmFsdWUKK2RlZiBueHY4aTggIDogVmFsdWVUeXBlPDY0LCAgNjQ+OyAgLy8gbiB4ICA4IHggaTggIHZlY3RvciB2YWx1ZQorZGVmIG54djE2aTggOiBWYWx1ZVR5cGU8MTI4LCA2NT47ICAvLyBuIHggMTYgeCBpOCAgdmVjdG9yIHZhbHVlCitkZWYgbnh2MzJpOCA6IFZhbHVlVHlwZTwyNTYsIDY2PjsgIC8vIG4geCAzMiB4IGk4ICB2ZWN0b3IgdmFsdWUKKworZGVmIG54djFpMTYgOiBWYWx1ZVR5cGU8MTYsICA2Nz47ICAvLyBuIHggIDEgeCBpMTYgdmVjdG9yIHZhbHVlCitkZWYgbnh2MmkxNiA6IFZhbHVlVHlwZTwzMiwgIDY4PjsgIC8vIG4geCAgMiB4IGkxNiB2ZWN0b3IgdmFsdWUKK2RlZiBueHY0aTE2IDogVmFsdWVUeXBlPDY0LCAgNjk+OyAgLy8gbiB4ICA0IHggaTE2IHZlY3RvciB2YWx1ZQorZGVmIG54djhpMTYgOiBWYWx1ZVR5cGU8MTI4LCA3MD47ICAvLyBuIHggIDggeCBpMTYgdmVjdG9yIHZhbHVlCitkZWYgbnh2MTZpMTY6IFZhbHVlVHlwZTwyNTYsIDcxPjsgIC8vIG4geCAxNiB4IGkxNiB2ZWN0b3IgdmFsdWUKK2RlZiBueHYzMmkxNjogVmFsdWVUeXBlPDUxMiwgNzI+OyAgLy8gbiB4IDMyIHggaTE2IHZlY3RvciB2YWx1ZQorCitkZWYgbnh2MWkzMiA6IFZhbHVlVHlwZTwzMiwgIDczPjsgIC8vIG4geCAgMSB4IGkzMiB2ZWN0b3IgdmFsdWUKK2RlZiBueHYyaTMyIDogVmFsdWVUeXBlPDY0LCAgNzQ+OyAgLy8gbiB4ICAyIHggaTMyIHZlY3RvciB2YWx1ZQorZGVmIG54djRpMzIgOiBWYWx1ZVR5cGU8MTI4LCA3NT47ICAvLyBuIHggIDQgeCBpMzIgdmVjdG9yIHZhbHVlCitkZWYgbnh2OGkzMiA6IFZhbHVlVHlwZTwyNTYsIDc2PjsgIC8vIG4geCAgOCB4IGkzMiB2ZWN0b3IgdmFsdWUKK2RlZiBueHYxNmkzMjogVmFsdWVUeXBlPDUxMiwgNzc+OyAgLy8gbiB4IDE2IHggaTMyIHZlY3RvciB2YWx1ZQorZGVmIG54djMyaTMyOiBWYWx1ZVR5cGU8MTAyNCw3OD47ICAvLyBuIHggMzIgeCBpMzIgdmVjdG9yIHZhbHVlCisKK2RlZiBueHYxaTY0IDogVmFsdWVUeXBlPDY0LCAgNzk+OyAgLy8gbiB4ICAxIHggaTY0IHZlY3RvciB2YWx1ZQorZGVmIG54djJpNjQgOiBWYWx1ZVR5cGU8MTI4LCA4MD47ICAvLyBuIHggIDIgeCBpNjQgdmVjdG9yIHZhbHVlCitkZWYgbnh2NGk2NCA6IFZhbHVlVHlwZTwyNTYsIDgxPjsgIC8vIG4geCAgNCB4IGk2NCB2ZWN0b3IgdmFsdWUKK2RlZiBueHY4aTY0IDogVmFsdWVUeXBlPDUxMiwgODI+OyAgLy8gbiB4ICA4IHggaTY0IHZlY3RvciB2YWx1ZQorZGVmIG54djE2aTY0OiBWYWx1ZVR5cGU8MTAyNCw4Mz47ICAvLyBuIHggMTYgeCBpNjQgdmVjdG9yIHZhbHVlCitkZWYgbnh2MzJpNjQ6IFZhbHVlVHlwZTwyMDQ4LDg0PjsgIC8vIG4geCAzMiB4IGk2NCB2ZWN0b3IgdmFsdWUKKworZGVmIHYyZjE2ICA6IFZhbHVlVHlwZTwzMiAsIDg1PjsgICAvLyAgMiB4IGYxNiB2ZWN0b3IgdmFsdWUKK2RlZiB2NGYxNiAgOiBWYWx1ZVR5cGU8NjQgLCA4Nj47ICAgLy8gIDQgeCBmMTYgdmVjdG9yIHZhbHVlCitkZWYgdjhmMTYgIDogVmFsdWVUeXBlPDEyOCwgODc+OyAgIC8vICA4IHggZjE2IHZlY3RvciB2YWx1ZQorZGVmIHYxZjMyICA6IFZhbHVlVHlwZTwzMiAsIDg4PjsgICAvLyAgMSB4IGYzMiB2ZWN0b3IgdmFsdWUKK2RlZiB2MmYzMiAgOiBWYWx1ZVR5cGU8NjQgLCA4OT47ICAgLy8gIDIgeCBmMzIgdmVjdG9yIHZhbHVlCitkZWYgdjRmMzIgIDogVmFsdWVUeXBlPDEyOCwgOTA+OyAgIC8vICA0IHggZjMyIHZlY3RvciB2YWx1ZQorZGVmIHY4ZjMyICA6IFZhbHVlVHlwZTwyNTYsIDkxPjsgICAvLyAgOCB4IGYzMiB2ZWN0b3IgdmFsdWUKK2RlZiB2MTZmMzIgOiBWYWx1ZVR5cGU8NTEyLCA5Mj47ICAgLy8gMTYgeCBmMzIgdmVjdG9yIHZhbHVlCitkZWYgdjFmNjQgIDogVmFsdWVUeXBlPDY0LCAgOTM+OyAgIC8vICAxIHggZjY0IHZlY3RvciB2YWx1ZQorZGVmIHYyZjY0ICA6IFZhbHVlVHlwZTwxMjgsIDk0PjsgICAvLyAgMiB4IGY2NCB2ZWN0b3IgdmFsdWUKK2RlZiB2NGY2NCAgOiBWYWx1ZVR5cGU8MjU2LCA5NT47ICAgLy8gIDQgeCBmNjQgdmVjdG9yIHZhbHVlCitkZWYgdjhmNjQgIDogVmFsdWVUeXBlPDUxMiwgOTY+OyAgIC8vICA4IHggZjY0IHZlY3RvciB2YWx1ZQorCitkZWYgbnh2MmYxNiAgOiBWYWx1ZVR5cGU8MzIgLCAgOTc+OyAvLyBuIHggIDIgeCBmMTYgdmVjdG9yIHZhbHVlCitkZWYgbnh2NGYxNiAgOiBWYWx1ZVR5cGU8NjQgLCAgOTg+OyAvLyBuIHggIDQgeCBmMTYgdmVjdG9yIHZhbHVlCitkZWYgbnh2OGYxNiAgOiBWYWx1ZVR5cGU8MTI4LCAgOTk+OyAvLyBuIHggIDggeCBmMTYgdmVjdG9yIHZhbHVlCitkZWYgbnh2MWYzMiAgOiBWYWx1ZVR5cGU8MzIgLCAxMDA+OyAvLyBuIHggIDEgeCBmMzIgdmVjdG9yIHZhbHVlCitkZWYgbnh2MmYzMiAgOiBWYWx1ZVR5cGU8NjQgLCAxMDE+OyAvLyBuIHggIDIgeCBmMzIgdmVjdG9yIHZhbHVlCitkZWYgbnh2NGYzMiAgOiBWYWx1ZVR5cGU8MTI4LCAxMDI+OyAvLyBuIHggIDQgeCBmMzIgdmVjdG9yIHZhbHVlCitkZWYgbnh2OGYzMiAgOiBWYWx1ZVR5cGU8MjU2LCAxMDM+OyAvLyBuIHggIDggeCBmMzIgdmVjdG9yIHZhbHVlCitkZWYgbnh2MTZmMzIgOiBWYWx1ZVR5cGU8NTEyLCAxMDQ+OyAvLyBuIHggMTYgeCBmMzIgdmVjdG9yIHZhbHVlCitkZWYgbnh2MWY2NCAgOiBWYWx1ZVR5cGU8NjQsICAxMDU+OyAvLyBuIHggIDEgeCBmNjQgdmVjdG9yIHZhbHVlCitkZWYgbnh2MmY2NCAgOiBWYWx1ZVR5cGU8MTI4LCAxMDY+OyAvLyBuIHggIDIgeCBmNjQgdmVjdG9yIHZhbHVlCitkZWYgbnh2NGY2NCAgOiBWYWx1ZVR5cGU8MjU2LCAxMDc+OyAvLyBuIHggIDQgeCBmNjQgdmVjdG9yIHZhbHVlCitkZWYgbnh2OGY2NCAgOiBWYWx1ZVR5cGU8NTEyLCAxMDg+OyAvLyBuIHggIDggeCBmNjQgdmVjdG9yIHZhbHVlCisKK2RlZiB4ODZtbXggOiBWYWx1ZVR5cGU8NjQgLCAxMDk+OyAgIC8vIFg4NiBNTVggdmFsdWUKK2RlZiBGbGFnVlQgOiBWYWx1ZVR5cGU8MCAgLCAxMTA+OyAgIC8vIFByZS1SQSBzY2hlZCBnbHVlCitkZWYgaXNWb2lkIDogVmFsdWVUeXBlPDAgICwgMTExPjsgICAvLyBQcm9kdWNlcyBubyB2YWx1ZQorZGVmIHVudHlwZWQ6IFZhbHVlVHlwZTw4ICAsIDExMj47ICAgLy8gUHJvZHVjZXMgYW4gdW50eXBlZCB2YWx1ZQorZGVmIEV4Y2VwdFJlZjogVmFsdWVUeXBlPDAsIDExMz47ICAgLy8gV2ViQXNzZW1ibHkncyBleGNlcHRfcmVmIHR5cGUKK2RlZiB0b2tlbiAgOiBWYWx1ZVR5cGU8MCAgLCAyNDg+OyAgIC8vIFRva2VuVHkKK2RlZiBNZXRhZGF0YVZUOiBWYWx1ZVR5cGU8MCwgMjQ5PjsgIC8vIE1ldGFkYXRhCisKKy8vIFBzZXVkbyB2YWx1ZXR5cGUgbWFwcGVkIHRvIHRoZSBjdXJyZW50IHBvaW50ZXIgc2l6ZSB0byBhbnkgYWRkcmVzcyBzcGFjZS4KKy8vIFNob3VsZCBvbmx5IGJlIHVzZWQgaW4gVGFibGVHZW4uCitkZWYgaVBUUkFueSAgIDogVmFsdWVUeXBlPDAsIDI1MD47CisKKy8vIFBzZXVkbyB2YWx1ZXR5cGUgdG8gcmVwcmVzZW50ICJ2ZWN0b3Igb2YgYW55IHNpemUiCitkZWYgdkFueSAgIDogVmFsdWVUeXBlPDAgICwgMjUxPjsKKworLy8gUHNldWRvIHZhbHVldHlwZSB0byByZXByZXNlbnQgImZsb2F0IG9mIGFueSBmb3JtYXQiCitkZWYgZkFueSAgIDogVmFsdWVUeXBlPDAgICwgMjUyPjsKKworLy8gUHNldWRvIHZhbHVldHlwZSB0byByZXByZXNlbnQgImludGVnZXIgb2YgYW55IGJpdCB3aWR0aCIKK2RlZiBpQW55ICAgOiBWYWx1ZVR5cGU8MCAgLCAyNTM+OworCisvLyBQc2V1ZG8gdmFsdWV0eXBlIG1hcHBlZCB0byB0aGUgY3VycmVudCBwb2ludGVyIHNpemUuCitkZWYgaVBUUiAgIDogVmFsdWVUeXBlPDAgICwgMjU0PjsKKworLy8gUHNldWRvIHZhbHVldHlwZSB0byByZXByZXNlbnQgImFueSB0eXBlIG9mIGFueSBzaXplIi4KK2RlZiBBbnkgICAgOiBWYWx1ZVR5cGU8MCAgLCAyNTU+OwpkaWZmIC0tZ2l0IGEvbGludXgteDY0L2NsYW5nL2luY2x1ZGUvbGx2bS9Db2RlR2VuL1ZpcnRSZWdNYXAuaCBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9WaXJ0UmVnTWFwLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uM2IwNmYwMwotLS0gL2Rldi9udWxsCisrKyBiL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9WaXJ0UmVnTWFwLmgKQEAgLTAsMCArMSwxODggQEAKKy8vPT09LSBsbHZtL0NvZGVHZW4vVmlydFJlZ01hcC5oIC0gVmlydHVhbCBSZWdpc3RlciBNYXAgLS0tLS0tLS0tKi0gQysrIC0qLT09PS8vCisvLworLy8gICAgICAgICAgICAgICAgICAgICBUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQorLy8KKy8vIFRoaXMgZmlsZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgVW5pdmVyc2l0eSBvZiBJbGxpbm9pcyBPcGVuIFNvdXJjZQorLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgorLy8KKy8vPT09LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLT09PS8vCisvLworLy8gVGhpcyBmaWxlIGltcGxlbWVudHMgYSB2aXJ0dWFsIHJlZ2lzdGVyIG1hcC4gVGhpcyBtYXBzIHZpcnR1YWwgcmVnaXN0ZXJzIHRvCisvLyBwaHlzaWNhbCByZWdpc3RlcnMgYW5kIHZpcnR1YWwgcmVnaXN0ZXJzIHRvIHN0YWNrIHNsb3RzLiBJdCBpcyBjcmVhdGVkIGFuZAorLy8gdXBkYXRlZCBieSBhIHJlZ2lzdGVyIGFsbG9jYXRvciBhbmQgdGhlbiB1c2VkIGJ5IGEgbWFjaGluZSBjb2RlIHJld3JpdGVyIHRoYXQKKy8vIGFkZHMgc3BpbGwgY29kZSBhbmQgcmV3cml0ZXMgdmlydHVhbCBpbnRvIHBoeXNpY2FsIHJlZ2lzdGVyIHJlZmVyZW5jZXMuCisvLworLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KKworI2lmbmRlZiBMTFZNX0NPREVHRU5fVklSVFJFR01BUF9ICisjZGVmaW5lIExMVk1fQ09ERUdFTl9WSVJUUkVHTUFQX0gKKworI2luY2x1ZGUgImxsdm0vQURUL0luZGV4ZWRNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0NvZGVHZW4vTWFjaGluZUZ1bmN0aW9uUGFzcy5oIgorI2luY2x1ZGUgImxsdm0vQ29kZUdlbi9UYXJnZXRSZWdpc3RlckluZm8uaCIKKyNpbmNsdWRlICJsbHZtL01DL01DUmVnaXN0ZXJJbmZvLmgiCisjaW5jbHVkZSAibGx2bS9QYXNzLmgiCisjaW5jbHVkZSA8Y2Fzc2VydD4KKworbmFtZXNwYWNlIGxsdm0geworCitjbGFzcyBNYWNoaW5lRnVuY3Rpb247CitjbGFzcyBNYWNoaW5lUmVnaXN0ZXJJbmZvOworY2xhc3MgcmF3X29zdHJlYW07CitjbGFzcyBUYXJnZXRJbnN0ckluZm87CisKKyAgY2xhc3MgVmlydFJlZ01hcCA6IHB1YmxpYyBNYWNoaW5lRnVuY3Rpb25QYXNzIHsKKyAgcHVibGljOgorICAgIGVudW0geworICAgICAgTk9fUEhZU19SRUcgPSAwLAorICAgICAgTk9fU1RBQ0tfU0xPVCA9ICgxTCA8PCAzMCktMSwKKyAgICAgIE1BWF9TVEFDS19TTE9UID0gKDFMIDw8IDE4KS0xCisgICAgfTsKKworICBwcml2YXRlOgorICAgIE1hY2hpbmVSZWdpc3RlckluZm8gKk1SSTsKKyAgICBjb25zdCBUYXJnZXRJbnN0ckluZm8gKlRJSTsKKyAgICBjb25zdCBUYXJnZXRSZWdpc3RlckluZm8gKlRSSTsKKyAgICBNYWNoaW5lRnVuY3Rpb24gKk1GOworCisgICAgLy8vIFZpcnQyUGh5c01hcCAtIFRoaXMgaXMgYSB2aXJ0dWFsIHRvIHBoeXNpY2FsIHJlZ2lzdGVyCisgICAgLy8vIG1hcHBpbmcuIEVhY2ggdmlydHVhbCByZWdpc3RlciBpcyByZXF1aXJlZCB0byBoYXZlIGFuIGVudHJ5IGluCisgICAgLy8vIGl0OyBldmVuIHNwaWxsZWQgdmlydHVhbCByZWdpc3RlcnMgKHRoZSByZWdpc3RlciBtYXBwZWQgdG8gYQorICAgIC8vLyBzcGlsbGVkIHJlZ2lzdGVyIGlzIHRoZSB0ZW1wb3JhcnkgdXNlZCB0byBsb2FkIGl0IGZyb20gdGhlCisgICAgLy8vIHN0YWNrKS4KKyAgICBJbmRleGVkTWFwPHVuc2lnbmVkLCBWaXJ0UmVnMkluZGV4RnVuY3Rvcj4gVmlydDJQaHlzTWFwOworCisgICAgLy8vIFZpcnQyU3RhY2tTbG90TWFwIC0gVGhpcyBpcyB2aXJ0dWFsIHJlZ2lzdGVyIHRvIHN0YWNrIHNsb3QKKyAgICAvLy8gbWFwcGluZy4gRWFjaCBzcGlsbGVkIHZpcnR1YWwgcmVnaXN0ZXIgaGFzIGFuIGVudHJ5IGluIGl0CisgICAgLy8vIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSBzdGFjayBzbG90IHRoaXMgcmVnaXN0ZXIgaXMgc3BpbGxlZAorICAgIC8vLyBhdC4KKyAgICBJbmRleGVkTWFwPGludCwgVmlydFJlZzJJbmRleEZ1bmN0b3I+IFZpcnQyU3RhY2tTbG90TWFwOworCisgICAgLy8vIFZpcnQyU3BsaXRNYXAgLSBUaGlzIGlzIHZpcnR1YWwgcmVnaXN0ZXIgdG8gc3BsaXR0ZWQgdmlydHVhbCByZWdpc3RlcgorICAgIC8vLyBtYXBwaW5nLgorICAgIEluZGV4ZWRNYXA8dW5zaWduZWQsIFZpcnRSZWcySW5kZXhGdW5jdG9yPiBWaXJ0MlNwbGl0TWFwOworCisgICAgLy8vIGNyZWF0ZVNwaWxsU2xvdCAtIEFsbG9jYXRlIGEgc3BpbGwgc2xvdCBmb3IgUkMgZnJvbSBNRkkuCisgICAgdW5zaWduZWQgY3JlYXRlU3BpbGxTbG90KGNvbnN0IFRhcmdldFJlZ2lzdGVyQ2xhc3MgKlJDKTsKKworICBwdWJsaWM6CisgICAgc3RhdGljIGNoYXIgSUQ7CisKKyAgICBWaXJ0UmVnTWFwKCkgOiBNYWNoaW5lRnVuY3Rpb25QYXNzKElEKSwgVmlydDJQaHlzTWFwKE5PX1BIWVNfUkVHKSwKKyAgICAgICAgICAgICAgICAgICBWaXJ0MlN0YWNrU2xvdE1hcChOT19TVEFDS19TTE9UKSwgVmlydDJTcGxpdE1hcCgwKSB7fQorICAgIFZpcnRSZWdNYXAoY29uc3QgVmlydFJlZ01hcCAmKSA9IGRlbGV0ZTsKKyAgICBWaXJ0UmVnTWFwICZvcGVyYXRvcj0oY29uc3QgVmlydFJlZ01hcCAmKSA9IGRlbGV0ZTsKKworICAgIGJvb2wgcnVuT25NYWNoaW5lRnVuY3Rpb24oTWFjaGluZUZ1bmN0aW9uICZNRikgb3ZlcnJpZGU7CisKKyAgICB2b2lkIGdldEFuYWx5c2lzVXNhZ2UoQW5hbHlzaXNVc2FnZSAmQVUpIGNvbnN0IG92ZXJyaWRlIHsKKyAgICAgIEFVLnNldFByZXNlcnZlc0FsbCgpOworICAgICAgTWFjaGluZUZ1bmN0aW9uUGFzczo6Z2V0QW5hbHlzaXNVc2FnZShBVSk7CisgICAgfQorCisgICAgTWFjaGluZUZ1bmN0aW9uICZnZXRNYWNoaW5lRnVuY3Rpb24oKSBjb25zdCB7CisgICAgICBhc3NlcnQoTUYgJiYgImdldE1hY2hpbmVGdW5jdGlvbiBjYWxsZWQgYmVmb3JlIHJ1bk9uTWFjaGluZUZ1bmN0aW9uIik7CisgICAgICByZXR1cm4gKk1GOworICAgIH0KKworICAgIE1hY2hpbmVSZWdpc3RlckluZm8gJmdldFJlZ0luZm8oKSBjb25zdCB7IHJldHVybiAqTVJJOyB9CisgICAgY29uc3QgVGFyZ2V0UmVnaXN0ZXJJbmZvICZnZXRUYXJnZXRSZWdJbmZvKCkgY29uc3QgeyByZXR1cm4gKlRSSTsgfQorCisgICAgdm9pZCBncm93KCk7CisKKyAgICAvLy8gQGJyaWVmIHJldHVybnMgdHJ1ZSBpZiB0aGUgc3BlY2lmaWVkIHZpcnR1YWwgcmVnaXN0ZXIgaXMKKyAgICAvLy8gbWFwcGVkIHRvIGEgcGh5c2ljYWwgcmVnaXN0ZXIKKyAgICBib29sIGhhc1BoeXModW5zaWduZWQgdmlydFJlZykgY29uc3QgeworICAgICAgcmV0dXJuIGdldFBoeXModmlydFJlZykgIT0gTk9fUEhZU19SRUc7CisgICAgfQorCisgICAgLy8vIEBicmllZiByZXR1cm5zIHRoZSBwaHlzaWNhbCByZWdpc3RlciBtYXBwZWQgdG8gdGhlIHNwZWNpZmllZAorICAgIC8vLyB2aXJ0dWFsIHJlZ2lzdGVyCisgICAgdW5zaWduZWQgZ2V0UGh5cyh1bnNpZ25lZCB2aXJ0UmVnKSBjb25zdCB7CisgICAgICBhc3NlcnQoVGFyZ2V0UmVnaXN0ZXJJbmZvOjppc1ZpcnR1YWxSZWdpc3Rlcih2aXJ0UmVnKSk7CisgICAgICByZXR1cm4gVmlydDJQaHlzTWFwW3ZpcnRSZWddOworICAgIH0KKworICAgIC8vLyBAYnJpZWYgY3JlYXRlcyBhIG1hcHBpbmcgZm9yIHRoZSBzcGVjaWZpZWQgdmlydHVhbCByZWdpc3RlciB0bworICAgIC8vLyB0aGUgc3BlY2lmaWVkIHBoeXNpY2FsIHJlZ2lzdGVyCisgICAgdm9pZCBhc3NpZ25WaXJ0MlBoeXModW5zaWduZWQgdmlydFJlZywgTUNQaHlzUmVnIHBoeXNSZWcpOworCisgICAgLy8vIEBicmllZiBjbGVhcnMgdGhlIHNwZWNpZmllZCB2aXJ0dWFsIHJlZ2lzdGVyJ3MsIHBoeXNpY2FsCisgICAgLy8vIHJlZ2lzdGVyIG1hcHBpbmcKKyAgICB2b2lkIGNsZWFyVmlydCh1bnNpZ25lZCB2aXJ0UmVnKSB7CisgICAgICBhc3NlcnQoVGFyZ2V0UmVnaXN0ZXJJbmZvOjppc1ZpcnR1YWxSZWdpc3Rlcih2aXJ0UmVnKSk7CisgICAgICBhc3NlcnQoVmlydDJQaHlzTWFwW3ZpcnRSZWddICE9IE5PX1BIWVNfUkVHICYmCisgICAgICAgICAgICAgImF0dGVtcHQgdG8gY2xlYXIgYSBub3QgYXNzaWduZWQgdmlydHVhbCByZWdpc3RlciIpOworICAgICAgVmlydDJQaHlzTWFwW3ZpcnRSZWddID0gTk9fUEhZU19SRUc7CisgICAgfQorCisgICAgLy8vIEBicmllZiBjbGVhcnMgYWxsIHZpcnR1YWwgdG8gcGh5c2ljYWwgcmVnaXN0ZXIgbWFwcGluZ3MKKyAgICB2b2lkIGNsZWFyQWxsVmlydCgpIHsKKyAgICAgIFZpcnQyUGh5c01hcC5jbGVhcigpOworICAgICAgZ3JvdygpOworICAgIH0KKworICAgIC8vLyBAYnJpZWYgcmV0dXJucyB0cnVlIGlmIFZpcnRSZWcgaXMgYXNzaWduZWQgdG8gaXRzIHByZWZlcnJlZCBwaHlzcmVnLgorICAgIGJvb2wgaGFzUHJlZmVycmVkUGh5cyh1bnNpZ25lZCBWaXJ0UmVnKTsKKworICAgIC8vLyBAYnJpZWYgcmV0dXJucyB0cnVlIGlmIFZpcnRSZWcgaGFzIGEga25vd24gcHJlZmVycmVkIHJlZ2lzdGVyLgorICAgIC8vLyBUaGlzIHJldHVybnMgZmFsc2UgaWYgVmlydFJlZyBoYXMgYSBwcmVmZXJlbmNlIHRoYXQgaXMgYSB2aXJ0dWFsCisgICAgLy8vIHJlZ2lzdGVyIHRoYXQgaGFzbid0IGJlZW4gYXNzaWduZWQgeWV0LgorICAgIGJvb2wgaGFzS25vd25QcmVmZXJlbmNlKHVuc2lnbmVkIFZpcnRSZWcpOworCisgICAgLy8vIEBicmllZiByZWNvcmRzIHZpcnRSZWcgaXMgYSBzcGxpdCBsaXZlIGludGVydmFsIGZyb20gU1JlZy4KKyAgICB2b2lkIHNldElzU3BsaXRGcm9tUmVnKHVuc2lnbmVkIHZpcnRSZWcsIHVuc2lnbmVkIFNSZWcpIHsKKyAgICAgIFZpcnQyU3BsaXRNYXBbdmlydFJlZ10gPSBTUmVnOworICAgIH0KKworICAgIC8vLyBAYnJpZWYgcmV0dXJucyB0aGUgbGl2ZSBpbnRlcnZhbCB2aXJ0UmVnIGlzIHNwbGl0IGZyb20uCisgICAgdW5zaWduZWQgZ2V0UHJlU3BsaXRSZWcodW5zaWduZWQgdmlydFJlZykgY29uc3QgeworICAgICAgcmV0dXJuIFZpcnQyU3BsaXRNYXBbdmlydFJlZ107CisgICAgfQorCisgICAgLy8vIGdldE9yaWdpbmFsIC0gUmV0dXJuIHRoZSBvcmlnaW5hbCB2aXJ0dWFsIHJlZ2lzdGVyIHRoYXQgVmlydFJlZyBkZXNjZW5kcworICAgIC8vLyBmcm9tIHRocm91Z2ggc3BsaXR0aW5nLgorICAgIC8vLyBBIHJlZ2lzdGVyIHRoYXQgd2FzIG5vdCBjcmVhdGVkIGJ5IHNwbGl0dGluZyBpcyBpdHMgb3duIG9yaWdpbmFsLgorICAgIC8vLyBUaGlzIG9wZXJhdGlvbiBpcyBpZGVtcG90ZW50LgorICAgIHVuc2lnbmVkIGdldE9yaWdpbmFsKHVuc2lnbmVkIFZpcnRSZWcpIGNvbnN0IHsKKyAgICAgIHVuc2lnbmVkIE9yaWcgPSBnZXRQcmVTcGxpdFJlZyhWaXJ0UmVnKTsKKyAgICAgIHJldHVybiBPcmlnID8gT3JpZyA6IFZpcnRSZWc7CisgICAgfQorCisgICAgLy8vIEBicmllZiByZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2aXJ0dWFsIHJlZ2lzdGVyIGlzIG5vdAorICAgIC8vLyBtYXBwZWQgdG8gYSBzdGFjayBzbG90IG9yIHJlbWF0ZXJpYWxpemVkLgorICAgIGJvb2wgaXNBc3NpZ25lZFJlZyh1bnNpZ25lZCB2aXJ0UmVnKSBjb25zdCB7CisgICAgICBpZiAoZ2V0U3RhY2tTbG90KHZpcnRSZWcpID09IE5PX1NUQUNLX1NMT1QpCisgICAgICAgIHJldHVybiB0cnVlOworICAgICAgLy8gU3BsaXQgcmVnaXN0ZXIgY2FuIGJlIGFzc2lnbmVkIGEgcGh5c2ljYWwgcmVnaXN0ZXIgYXMgd2VsbCBhcyBhCisgICAgICAvLyBzdGFjayBzbG90IG9yIHJlbWF0IGlkLgorICAgICAgcmV0dXJuIChWaXJ0MlNwbGl0TWFwW3ZpcnRSZWddICYmIFZpcnQyUGh5c01hcFt2aXJ0UmVnXSAhPSBOT19QSFlTX1JFRyk7CisgICAgfQorCisgICAgLy8vIEBicmllZiByZXR1cm5zIHRoZSBzdGFjayBzbG90IG1hcHBlZCB0byB0aGUgc3BlY2lmaWVkIHZpcnR1YWwKKyAgICAvLy8gcmVnaXN0ZXIKKyAgICBpbnQgZ2V0U3RhY2tTbG90KHVuc2lnbmVkIHZpcnRSZWcpIGNvbnN0IHsKKyAgICAgIGFzc2VydChUYXJnZXRSZWdpc3RlckluZm86OmlzVmlydHVhbFJlZ2lzdGVyKHZpcnRSZWcpKTsKKyAgICAgIHJldHVybiBWaXJ0MlN0YWNrU2xvdE1hcFt2aXJ0UmVnXTsKKyAgICB9CisKKyAgICAvLy8gQGJyaWVmIGNyZWF0ZSBhIG1hcHBpbmcgZm9yIHRoZSBzcGVjaWZlZCB2aXJ0dWFsIHJlZ2lzdGVyIHRvCisgICAgLy8vIHRoZSBuZXh0IGF2YWlsYWJsZSBzdGFjayBzbG90CisgICAgaW50IGFzc2lnblZpcnQyU3RhY2tTbG90KHVuc2lnbmVkIHZpcnRSZWcpOworCisgICAgLy8vIEBicmllZiBjcmVhdGUgYSBtYXBwaW5nIGZvciB0aGUgc3BlY2lmaWVkIHZpcnR1YWwgcmVnaXN0ZXIgdG8KKyAgICAvLy8gdGhlIHNwZWNpZmllZCBzdGFjayBzbG90CisgICAgdm9pZCBhc3NpZ25WaXJ0MlN0YWNrU2xvdCh1bnNpZ25lZCB2aXJ0UmVnLCBpbnQgZnJhbWVJbmRleCk7CisKKyAgICB2b2lkIHByaW50KHJhd19vc3RyZWFtICZPUywgY29uc3QgTW9kdWxlKiBNID0gbnVsbHB0cikgY29uc3Qgb3ZlcnJpZGU7CisgICAgdm9pZCBkdW1wKCkgY29uc3Q7CisgIH07CisKKyAgaW5saW5lIHJhd19vc3RyZWFtICZvcGVyYXRvcjw8KHJhd19vc3RyZWFtICZPUywgY29uc3QgVmlydFJlZ01hcCAmVlJNKSB7CisgICAgVlJNLnByaW50KE9TKTsKKyAgICByZXR1cm4gT1M7CisgIH0KKworfSAvLyBlbmQgbGx2bSBuYW1lc3BhY2UKKworI2VuZGlmIC8vIExMVk1fQ09ERUdFTl9WSVJUUkVHTUFQX0gKZGlmZiAtLWdpdCBhL2xpbnV4LXg2NC9jbGFuZy9pbmNsdWRlL2xsdm0vQ29kZUdlbi9XaW5FSEZ1bmNJbmZvLmggYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vV2luRUhGdW5jSW5mby5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgwNDMwMjQKLS0tIC9kZXYvbnVsbAorKysgYi9saW51eC14NjQvY2xhbmcvaW5jbHVkZS9sbHZtL0NvZGVHZW4vV2luRUhGdW5jSW5mby5oCkBAIC0wLDAgKzEsMTI5IEBACisvLz09PS0gbGx2bS9Db2RlR2VuL1dpbkVIRnVuY0luZm8uaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSotIEMrKyAtKi09PT0vLworLy8KKy8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0gQ29tcGlsZXIgSW5mcmFzdHJ1Y3R1cmUKKy8vCisvLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKKy8vIExpY2Vuc2UuIFNlZSBMSUNFTlNFLlRYVCBmb3IgZGV0YWlscy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworLy8KKy8vIERhdGEgc3RydWN0dXJlcyBhbmQgYXNzb2NpYXRlZCBzdGF0ZSBmb3IgV2luZG93cyBleGNlcHRpb24gaGFuZGxpbmcgc2NoZW1lcy4KKy8vCisvLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLworCisjaWZuZGVmIExMVk1fQ09ERUdFTl9XSU5FSEZVTkNJTkZPX0gKKyNkZWZpbmUgTExWTV9DT0RFR0VOX1dJTkVIRlVOQ0lORk9fSAorCisjaW5jbHVkZSAibGx2bS9BRFQvRGVuc2VNYXAuaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9Qb2ludGVyVW5pb24uaCIKKyNpbmNsdWRlICJsbHZtL0FEVC9TbWFsbFZlY3Rvci5oIgorI2luY2x1ZGUgPGNzdGRpbnQ+CisjaW5jbHVkZSA8bGltaXRzPgorI2luY2x1ZGUgPHV0aWxpdHk+CisKK25hbWVzcGFjZSBsbHZtIHsKKworY2xhc3MgQWxsb2NhSW5zdDsKK2NsYXNzIEJhc2ljQmxvY2s7CitjbGFzcyBGdW5jbGV0UGFkSW5zdDsKK2NsYXNzIEZ1bmN0aW9uOworY2xhc3MgR2xvYmFsVmFyaWFibGU7CitjbGFzcyBJbnN0cnVjdGlvbjsKK2NsYXNzIEludm9rZUluc3Q7CitjbGFzcyBNYWNoaW5lQmFzaWNCbG9jazsKK2NsYXNzIE1DU3ltYm9sOworCisvLyBUaGUgZm9sbG93aW5nIHN0cnVjdHMgcmVzcHJlc2VudCB0aGUgLnhkYXRhIHRhYmxlcyBmb3IgdmFyaW91cworLy8gV2luZG93cy1yZWxhdGVkIEVIIHBlcnNvbmFsaXRpZXMuCisKK3VzaW5nIE1CQk9yQmFzaWNCbG9jayA9IFBvaW50ZXJVbmlvbjxjb25zdCBCYXNpY0Jsb2NrICosIE1hY2hpbmVCYXNpY0Jsb2NrICo+OworCitzdHJ1Y3QgQ3h4VW53aW5kTWFwRW50cnkgeworICBpbnQgVG9TdGF0ZTsKKyAgTUJCT3JCYXNpY0Jsb2NrIENsZWFudXA7Cit9OworCisvLy8gU2ltaWxhciB0byBDeHhVbndpbmRNYXBFbnRyeSwgYnV0IHN1cHBvcnRzIFNFSCBmaWx0ZXJzLgorc3RydWN0IFNFSFVud2luZE1hcEVudHJ5IHsKKyAgLy8vIElmIHVud2luZGluZyBjb250aW51ZXMgdGhyb3VnaCB0aGlzIGhhbmRsZXIsIHRyYW5zaXRpb24gdG8gdGhlIGhhbmRsZXIgYXQKKyAgLy8vIHRoaXMgc3RhdGUuIFRoaXMgaW5kZXhlcyBpbnRvIFNFSFVud2luZE1hcC4KKyAgaW50IFRvU3RhdGUgPSAtMTsKKworICBib29sIElzRmluYWxseSA9IGZhbHNlOworCisgIC8vLyBIb2xkcyB0aGUgZmlsdGVyIGV4cHJlc3Npb24gZnVuY3Rpb24uCisgIGNvbnN0IEZ1bmN0aW9uICpGaWx0ZXIgPSBudWxscHRyOworCisgIC8vLyBIb2xkcyB0aGUgX19leGNlcHQgb3IgX19maW5hbGx5IGJhc2ljIGJsb2NrLgorICBNQkJPckJhc2ljQmxvY2sgSGFuZGxlcjsKK307CisKK3N0cnVjdCBXaW5FSEhhbmRsZXJUeXBlIHsKKyAgaW50IEFkamVjdGl2ZXM7CisgIC8vLyBUaGUgQ2F0Y2hPYmogc3RhcnRzIG91dCBsaWZlIGFzIGFuIExMVk0gYWxsb2NhIGFuZCBpcyBldmVudHVhbGx5IHR1cm5lZAorICAvLy8gZnJhbWUgaW5kZXguCisgIHVuaW9uIHsKKyAgICBjb25zdCBBbGxvY2FJbnN0ICpBbGxvY2E7CisgICAgaW50IEZyYW1lSW5kZXg7CisgIH0gQ2F0Y2hPYmogPSB7fTsKKyAgR2xvYmFsVmFyaWFibGUgKlR5cGVEZXNjcmlwdG9yOworICBNQkJPckJhc2ljQmxvY2sgSGFuZGxlcjsKK307CisKK3N0cnVjdCBXaW5FSFRyeUJsb2NrTWFwRW50cnkgeworICBpbnQgVHJ5TG93ID0gLTE7CisgIGludCBUcnlIaWdoID0gLTE7CisgIGludCBDYXRjaEhpZ2ggPSAtMTsKKyAgU21hbGxWZWN0b3I8V2luRUhIYW5kbGVyVHlwZSwgMT4gSGFuZGxlckFycmF5OworfTsKKworZW51bSBjbGFzcyBDbHJIYW5kbGVyVHlwZSB7IENhdGNoLCBGaW5hbGx5LCBGYXVsdCwgRmlsdGVyIH07CisKK3N0cnVjdCBDbHJFSFVud2luZE1hcEVudHJ5IHsKKyAgTUJCT3JCYXNpY0Jsb2NrIEhhbmRsZXI7CisgIHVpbnQzMl90IFR5cGVUb2tlbjsKKyAgaW50IEhhbmRsZXJQYXJlbnRTdGF0ZTsgLy8vPCBPdXRlciBoYW5kbGVyIGVuY2xvc2luZyB0aGlzIGVudHJ5J3MgaGFuZGxlcgorICBpbnQgVHJ5UGFyZW50U3RhdGU7IC8vLzwgT3V0ZXIgdHJ5IHJlZ2lvbiBlbmNsb3NpbmcgdGhpcyBlbnRyeSdzIHRyeSByZWdpb24sCisgICAgICAgICAgICAgICAgICAgICAgLy8vPCB0cmVhdGluZyBsYXRlciBjYXRjaGVzIG9uIHNhbWUgdHJ5IGFzICJvdXRlciIKKyAgQ2xySGFuZGxlclR5cGUgSGFuZGxlclR5cGU7Cit9OworCitzdHJ1Y3QgV2luRUhGdW5jSW5mbyB7CisgIERlbnNlTWFwPGNvbnN0IEluc3RydWN0aW9uICosIGludD4gRUhQYWRTdGF0ZU1hcDsKKyAgRGVuc2VNYXA8Y29uc3QgRnVuY2xldFBhZEluc3QgKiwgaW50PiBGdW5jbGV0QmFzZVN0YXRlTWFwOworICBEZW5zZU1hcDxjb25zdCBJbnZva2VJbnN0ICosIGludD4gSW52b2tlU3RhdGVNYXA7CisgIERlbnNlTWFwPE1DU3ltYm9sICosIHN0ZDo6cGFpcjxpbnQsIE1DU3ltYm9sICo+PiBMYWJlbFRvU3RhdGVNYXA7CisgIFNtYWxsVmVjdG9yPEN4eFVud2luZE1hcEVudHJ5LCA0PiBDeHhVbndpbmRNYXA7CisgIFNtYWxsVmVjdG9yPFdpbkVIVHJ5QmxvY2tNYXBFbnRyeSwgND4gVHJ5QmxvY2tNYXA7CisgIFNtYWxsVmVjdG9yPFNFSFVud2luZE1hcEVudHJ5LCA0PiBTRUhVbndpbmRNYXA7CisgIFNtYWxsVmVjdG9yPENsckVIVW53aW5kTWFwRW50cnksIDQ+IENsckVIVW53aW5kTWFwOworICBpbnQgVW53aW5kSGVscEZyYW1lSWR4ID0gc3RkOjpudW1lcmljX2xpbWl0czxpbnQ+OjptYXgoKTsKKyAgaW50IFBTUFN5bUZyYW1lSWR4ID0gc3RkOjpudW1lcmljX2xpbWl0czxpbnQ+OjptYXgoKTsKKworICBpbnQgZ2V0TGFzdFN0YXRlTnVtYmVyKCkgY29uc3QgeyByZXR1cm4gQ3h4VW53aW5kTWFwLnNpemUoKSAtIDE7IH0KKworICB2b2lkIGFkZElQVG9TdGF0ZVJhbmdlKGNvbnN0IEludm9rZUluc3QgKklJLCBNQ1N5bWJvbCAqSW52b2tlQmVnaW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgTUNTeW1ib2wgKkludm9rZUVuZCk7CisKKyAgaW50IEVIUmVnTm9kZUZyYW1lSW5kZXggPSBzdGQ6Om51bWVyaWNfbGltaXRzPGludD46Om1heCgpOworICBpbnQgRUhSZWdOb2RlRW5kT2Zmc2V0ID0gc3RkOjpudW1lcmljX2xpbWl0czxpbnQ+OjptYXgoKTsKKyAgaW50IEVIR3VhcmRGcmFtZUluZGV4ID0gc3RkOjpudW1lcmljX2xpbWl0czxpbnQ+OjptYXgoKTsKKyAgaW50IFNFSFNldEZyYW1lT2Zmc2V0ID0gc3RkOjpudW1lcmljX2xpbWl0czxpbnQ+OjptYXgoKTsKKworICBXaW5FSEZ1bmNJbmZvKCk7Cit9OworCisvLy8gQW5hbHl6ZSB0aGUgSVIgaW4gUGFyZW50Rm4gYW5kIGl0J3MgaGFuZGxlcnMgdG8gYnVpbGQgV2luRUhGdW5jSW5mbywgd2hpY2gKKy8vLyBkZXNjcmliZXMgdGhlIHN0YXRlIG51bWJlcnMgYW5kIHRhYmxlcyB1c2VkIGJ5IF9fQ3h4RnJhbWVIYW5kbGVyMy4gVGhpcworLy8vIGFuYWx5c2lzIGFzc3VtZXMgdGhhdCBXaW5FSFByZXBhcmUgaGFzIGFscmVhZHkgYmVlbiBydW4uCit2b2lkIGNhbGN1bGF0ZVdpbkNYWEVIU3RhdGVOdW1iZXJzKGNvbnN0IEZ1bmN0aW9uICpQYXJlbnRGbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV2luRUhGdW5jSW5mbyAmRnVuY0luZm8pOworCit2b2lkIGNhbGN1bGF0ZVNFSFN0YXRlTnVtYmVycyhjb25zdCBGdW5jdGlvbiAqUGFyZW50Rm4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaW5FSEZ1bmNJbmZvICZGdW5jSW5mbyk7CisKK3ZvaWQgY2FsY3VsYXRlQ2xyRUhTdGF0ZU51bWJlcnMoY29uc3QgRnVuY3Rpb24gKkZuLCBXaW5FSEZ1bmNJbmZvICZGdW5jSW5mbyk7CisKK30gLy8gZW5kIG5hbWVzcGFjZSBsbHZtCisKKyNlbmRpZiAvLyBMTFZNX0NPREVHRU5fV0lORUhGVU5DSU5GT19ICg==