Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBCaXRtYXAgcm90YXRpb24gYnkgbWVhbnMgb2YgMyBzaGVhcnMuCi8vCi8vIERlc2lnbiBhbmQgaW1wbGVtZW50YXRpb24gYnkKLy8gLSBIZXJ26SBEcm9sb24gKGRyb2xvbkBpbmZvbmllLmZyKQovLyAtIFRob3JzdGVuIFJhZGRlIChzdXBwb3J0QElkZWFsU29mdHdhcmUuY29tKQovLyAtIE1paGFpbCBOYXlkZW5vdiAobW5heWRlbm92QHVzZXJzLnNvdXJjZWZvcmdlLm5ldCkKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKiAKID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogUmVmZXJlbmNlcyA6IAogWzFdIFBhZXRoIEEuLCBBIEZhc3QgQWxnb3JpdGhtIGZvciBHZW5lcmFsIFJhc3RlciBSb3RhdGlvbi4gCiBHcmFwaGljcyBHZW1zLCBwLiAxNzksIEFuZHJldyBHbGFzc25lciBlZGl0b3IsIEFjYWRlbWljIFByZXNzLCAxOTkwLiAKIFsyXSBZYXJpdiBFLiwgSGlnaCBxdWFsaXR5IGltYWdlIHJvdGF0aW9uIChyb3RhdGUgYnkgc2hlYXIpLiAKIFtPbmxpbmVdIGh0dHA6Ly93d3cuY29kZXByb2plY3QuY29tL2JpdG1hcC9yb3RhdGVieXNoZWFyLmFzcAogWzNdIFRyZXNrdW5vdiBBLiwgRmFzdCBhbmQgaGlnaCBxdWFsaXR5IHRydWUtY29sb3IgYml0bWFwIHJvdGF0aW9uIGZ1bmN0aW9uLgogW09ubGluZV0gaHR0cDovL2FudG9uLnRyZXNrdW5vdi5uZXQvU29mdHdhcmUvZG9jL2Zhc3RfYW5kX2hpZ2hfcXVhbGl0eV90cnVlX2NvbG9yX2JpdG1hcF9yb3RhdGlvbl9mdW5jdGlvbi5odG1sCiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKi8KCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgoKI2RlZmluZSBSQkxPQ0sJCTY0CS8vIGltYWdlIGJsb2NrcyBvZiBSQkxPQ0sqUkJMT0NLIHBpeGVscwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgpTa2V3cyBhIHJvdyBob3Jpem9udGFsbHkgKHdpdGggZmlsdGVyZWQgd2VpZ2h0cykuIApMaW1pdGVkIHRvIDQ1IGRlZ3JlZSBza2V3aW5nIG9ubHkuIEZpbHRlcnMgdHdvIGFkamFjZW50IHBpeGVscy4KUGFyYW1ldGVyIFQgY2FuIGJlIEJZVEUsIFdPUkQgb2YgZmxvYXQuIApAcGFyYW0gc3JjIFBvaW50ZXIgdG8gc291cmNlIGltYWdlIHRvIHJvdGF0ZQpAcGFyYW0gZHN0IFBvaW50ZXIgdG8gZGVzdGluYXRpb24gaW1hZ2UKQHBhcmFtIHJvdyBSb3cgaW5kZXgKQHBhcmFtIGlPZmZzZXQgU2tldyBvZmZzZXQKQHBhcmFtIGRXZWlnaHQgUmVsYXRpdmUgd2VpZ2h0IG9mIHJpZ2h0IHBpeGVsCkBwYXJhbSBia2NvbG9yIEJhY2tncm91bmQgY29sb3IKKi8KdGVtcGxhdGUgPGNsYXNzIFQ+IHZvaWQgCkhvcml6b250YWxTa2V3VChGSUJJVE1BUCAqc3JjLCBGSUJJVE1BUCAqZHN0LCBpbnQgcm93LCBpbnQgaU9mZnNldCwgZG91YmxlIHdlaWdodCwgY29uc3Qgdm9pZCAqYmtjb2xvciA9IE5VTEwpIHsKCWludCBpWFBvczsKCgljb25zdCB1bnNpZ25lZCBzcmNfd2lkdGggID0gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7Cgljb25zdCB1bnNpZ25lZCBkc3Rfd2lkdGggID0gRnJlZUltYWdlX0dldFdpZHRoKGRzdCk7CgoJVCBweGxTcmNbNF0sIHB4bExlZnRbNF0sIHB4bE9sZExlZnRbNF07CS8vIDQgPSA0KnNpemVvZihUKSBtYXgKCQoJLy8gYmFja2dyb3VuZAoJY29uc3QgVCBweGxCbGFja1s0XSA9IHswLCAwLCAwLCAwIH07Cgljb25zdCBUICpweGxCa2cgPSBzdGF0aWNfY2FzdDxjb25zdCBUKj4oYmtjb2xvcik7IC8vIGFzc3VtZSBhdCBsZWFzdCBieXRlc3BwIGFuZCA0KnNpemVvZihUKSBtYXgKCWlmKCFweGxCa2cpIHsKCQkvLyBkZWZhdWx0IGJhY2tncm91bmQgY29sb3IgaXMgYmxhY2sKCQlweGxCa2cgPSBweGxCbGFjazsKCX0KCgkvLyBjYWxjdWxhdGUgdGhlIG51bWJlciBvZiBieXRlcyBwZXIgcGl4ZWwKCWNvbnN0IHVuc2lnbmVkIGJ5dGVzcHAgPSBGcmVlSW1hZ2VfR2V0TGluZShzcmMpIC8gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7CgkvLyBjYWxjdWxhdGUgdGhlIG51bWJlciBvZiBzYW1wbGVzIHBlciBwaXhlbAoJY29uc3QgdW5zaWduZWQgc2FtcGxlcyA9IGJ5dGVzcHAgLyBzaXplb2YoVCk7CgoJQllURSAqc3JjX2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCByb3cpOwoJQllURSAqZHN0X2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCByb3cpOwoKCS8vIGZpbGwgZ2FwIGxlZnQgb2Ygc2tldyB3aXRoIGJhY2tncm91bmQKCWlmKGJrY29sb3IpIHsKCQlmb3IoaW50IGsgPSAwOyBrIDwgaU9mZnNldDsgaysrKSB7CgkJCW1lbWNweSgmZHN0X2JpdHNbayAqIGJ5dGVzcHBdLCBia2NvbG9yLCBieXRlc3BwKTsKCQl9CgkJQXNzaWduUGl4ZWwoKEJZVEUqKSZweGxPbGRMZWZ0WzBdLCAoQllURSopYmtjb2xvciwgYnl0ZXNwcCk7Cgl9IGVsc2UgewoJCWlmKGlPZmZzZXQgPiAwKSB7CgkJCW1lbXNldChkc3RfYml0cywgMCwgaU9mZnNldCAqIGJ5dGVzcHApOwoJCX0JCQoJCW1lbXNldCgmcHhsT2xkTGVmdFswXSwgMCwgYnl0ZXNwcCk7Cgl9CgoJZm9yKHVuc2lnbmVkIGkgPSAwOyBpIDwgc3JjX3dpZHRoOyBpKyspIHsKCQkvLyBsb29wIHRocm91Z2ggcm93IHBpeGVscwoJCUFzc2lnblBpeGVsKChCWVRFKikmcHhsU3JjWzBdLCAoQllURSopc3JjX2JpdHMsIGJ5dGVzcHApOwoJCS8vIGNhbGN1bGF0ZSB3ZWlnaHRzCgkJZm9yKHVuc2lnbmVkIGogPSAwOyBqIDwgc2FtcGxlczsgaisrKSB7CgkJCXB4bExlZnRbal0gPSBzdGF0aWNfY2FzdDxUPihweGxCa2dbal0gKyAocHhsU3JjW2pdIC0gcHhsQmtnW2pdKSAqIHdlaWdodCArIDAuNSk7CgkJfQoJCS8vIGNoZWNrIGJvdW5kYXJpZXMgCgkJaVhQb3MgPSBpICsgaU9mZnNldDsKCQlpZigoaVhQb3MgPj0gMCkgJiYgKGlYUG9zIDwgKGludClkc3Rfd2lkdGgpKSB7CgkJCS8vIHVwZGF0ZSBsZWZ0IG92ZXIgb24gc291cmNlCgkJCWZvcih1bnNpZ25lZCBqID0gMDsgaiA8IHNhbXBsZXM7IGorKykgewoJCQkJcHhsU3JjW2pdID0gcHhsU3JjW2pdIC0gKHB4bExlZnRbal0gLSBweGxPbGRMZWZ0W2pdKTsKCQkJfQoJCQlBc3NpZ25QaXhlbCgoQllURSopJmRzdF9iaXRzW2lYUG9zKmJ5dGVzcHBdLCAoQllURSopJnB4bFNyY1swXSwgYnl0ZXNwcCk7CgkJfQoJCS8vIHNhdmUgbGVmdG92ZXIgZm9yIG5leHQgcGl4ZWwgaW4gc2NhbgoJCUFzc2lnblBpeGVsKChCWVRFKikmcHhsT2xkTGVmdFswXSwgKEJZVEUqKSZweGxMZWZ0WzBdLCBieXRlc3BwKTsKCgkJLy8gbmV4dCBwaXhlbCBpbiBzY2FuCgkJc3JjX2JpdHMgKz0gYnl0ZXNwcDsKCX0JCQkKCgkvLyBnbyB0byByaWdodG1vc3QgcG9pbnQgb2Ygc2tldwoJaVhQb3MgPSBzcmNfd2lkdGggKyBpT2Zmc2V0OyAKCglpZigoaVhQb3MgPj0gMCkgJiYgKGlYUG9zIDwgKGludClkc3Rfd2lkdGgpKSB7CgkJZHN0X2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCByb3cpICsgaVhQb3MgKiBieXRlc3BwOwoKCQkvLyBJZiBzdGlsbCBpbiBpbWFnZSBib3VuZHMsIHB1dCBsZWZ0b3ZlcnMgdGhlcmUKCQlBc3NpZ25QaXhlbCgoQllURSopZHN0X2JpdHMsIChCWVRFKikmcHhsT2xkTGVmdFswXSwgYnl0ZXNwcCk7CgoJCS8vIGNsZWFyIHRvIHRoZSByaWdodCBvZiB0aGUgc2tld2VkIGxpbmUgd2l0aCBiYWNrZ3JvdW5kCgkJZHN0X2JpdHMgKz0gYnl0ZXNwcDsKCQlpZihia2NvbG9yKSB7CgkJCWZvcih1bnNpZ25lZCBpID0gMDsgaSA8IGRzdF93aWR0aCAtIGlYUG9zIC0gMTsgaSsrKSB7CgkJCQltZW1jcHkoJmRzdF9iaXRzW2kgKiBieXRlc3BwXSwgYmtjb2xvciwgYnl0ZXNwcCk7CgkJCX0KCQl9IGVsc2UgewoJCQltZW1zZXQoZHN0X2JpdHMsIDAsIGJ5dGVzcHAgKiAoZHN0X3dpZHRoIC0gaVhQb3MgLSAxKSk7CgkJfQoKCX0KfQoKLyoqClNrZXdzIGEgcm93IGhvcml6b250YWxseSAod2l0aCBmaWx0ZXJlZCB3ZWlnaHRzKS4gCkxpbWl0ZWQgdG8gNDUgZGVncmVlIHNrZXdpbmcgb25seS4gRmlsdGVycyB0d28gYWRqYWNlbnQgcGl4ZWxzLgpAcGFyYW0gc3JjIFBvaW50ZXIgdG8gc291cmNlIGltYWdlIHRvIHJvdGF0ZQpAcGFyYW0gZHN0IFBvaW50ZXIgdG8gZGVzdGluYXRpb24gaW1hZ2UKQHBhcmFtIHJvdyBSb3cgaW5kZXgKQHBhcmFtIGlPZmZzZXQgU2tldyBvZmZzZXQKQHBhcmFtIGRXZWlnaHQgUmVsYXRpdmUgd2VpZ2h0IG9mIHJpZ2h0IHBpeGVsCkBwYXJhbSBia2NvbG9yIEJhY2tncm91bmQgY29sb3IKKi8Kc3RhdGljIHZvaWQgCkhvcml6b250YWxTa2V3KEZJQklUTUFQICpzcmMsIEZJQklUTUFQICpkc3QsIGludCByb3csIGludCBpT2Zmc2V0LCBkb3VibGUgZFdlaWdodCwgY29uc3Qgdm9pZCAqYmtjb2xvcikgewoJRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKHNyYyk7CgoJc3dpdGNoKGltYWdlX3R5cGUpIHsKCQljYXNlIEZJVF9CSVRNQVA6CgkJCXN3aXRjaChGcmVlSW1hZ2VfR2V0QlBQKHNyYykpIHsKCQkJCWNhc2UgODoKCQkJCWNhc2UgMjQ6CgkJCQljYXNlIDMyOgoJCQkJCUhvcml6b250YWxTa2V3VDxCWVRFPihzcmMsIGRzdCwgcm93LCBpT2Zmc2V0LCBkV2VpZ2h0LCBia2NvbG9yKTsKCQkJCWJyZWFrOwoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgRklUX1VJTlQxNjoKCQljYXNlIEZJVF9SR0IxNjoKCQljYXNlIEZJVF9SR0JBMTY6CgkJCUhvcml6b250YWxTa2V3VDxXT1JEPihzcmMsIGRzdCwgcm93LCBpT2Zmc2V0LCBkV2VpZ2h0LCBia2NvbG9yKTsKCQkJYnJlYWs7CgkJY2FzZSBGSVRfRkxPQVQ6CgkJY2FzZSBGSVRfUkdCRjoKCQljYXNlIEZJVF9SR0JBRjoKCQkJSG9yaXpvbnRhbFNrZXdUPGZsb2F0PihzcmMsIGRzdCwgcm93LCBpT2Zmc2V0LCBkV2VpZ2h0LCBia2NvbG9yKTsKCQkJYnJlYWs7Cgl9Cn0KCi8qKgpTa2V3cyBhIGNvbHVtbiB2ZXJ0aWNhbGx5ICh3aXRoIGZpbHRlcmVkIHdlaWdodHMpLiAKTGltaXRlZCB0byA0NSBkZWdyZWUgc2tld2luZyBvbmx5LiBGaWx0ZXJzIHR3byBhZGphY2VudCBwaXhlbHMuClBhcmFtZXRlciBUIGNhbiBiZSBCWVRFLCBXT1JEIG9mIGZsb2F0LiAKQHBhcmFtIHNyYyBQb2ludGVyIHRvIHNvdXJjZSBpbWFnZSB0byByb3RhdGUKQHBhcmFtIGRzdCBQb2ludGVyIHRvIGRlc3RpbmF0aW9uIGltYWdlCkBwYXJhbSBjb2wgQ29sdW1uIGluZGV4CkBwYXJhbSBpT2Zmc2V0IFNrZXcgb2Zmc2V0CkBwYXJhbSBkV2VpZ2h0IFJlbGF0aXZlIHdlaWdodCBvZiB1cHBlciBwaXhlbApAcGFyYW0gYmtjb2xvciBCYWNrZ3JvdW5kIGNvbG9yCiovCnRlbXBsYXRlIDxjbGFzcyBUPiB2b2lkIApWZXJ0aWNhbFNrZXdUKEZJQklUTUFQICpzcmMsIEZJQklUTUFQICpkc3QsIGludCBjb2wsIGludCBpT2Zmc2V0LCBkb3VibGUgd2VpZ2h0LCBjb25zdCB2b2lkICpia2NvbG9yID0gTlVMTCkgewoJaW50IGlZUG9zOwoKCXVuc2lnbmVkIHNyY19oZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYyk7Cgl1bnNpZ25lZCBkc3RfaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChkc3QpOwoKCVQgcHhsU3JjWzRdLCBweGxMZWZ0WzRdLCBweGxPbGRMZWZ0WzRdOwkvLyA0ID0gNCpzaXplb2YoVCkgbWF4CgoJLy8gYmFja2dyb3VuZAoJY29uc3QgVCBweGxCbGFja1s0XSA9IHswLCAwLCAwLCAwIH07Cgljb25zdCBUICpweGxCa2cgPSBzdGF0aWNfY2FzdDxjb25zdCBUKj4oYmtjb2xvcik7IC8vIGFzc3VtZSBhdCBsZWFzdCBieXRlc3BwIGFuZCA0KnNpemVvZihUKSBtYXgKCWlmKCFweGxCa2cpIHsKCQkvLyBkZWZhdWx0IGJhY2tncm91bmQgY29sb3IgaXMgYmxhY2sKCQlweGxCa2cgPSBweGxCbGFjazsKCX0KCgkvLyBjYWxjdWxhdGUgdGhlIG51bWJlciBvZiBieXRlcyBwZXIgcGl4ZWwKCWNvbnN0IHVuc2lnbmVkIGJ5dGVzcHAgPSBGcmVlSW1hZ2VfR2V0TGluZShzcmMpIC8gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7CgkvLyBjYWxjdWxhdGUgdGhlIG51bWJlciBvZiBzYW1wbGVzIHBlciBwaXhlbAoJY29uc3QgdW5zaWduZWQgc2FtcGxlcyA9IGJ5dGVzcHAgLyBzaXplb2YoVCk7CgoJY29uc3QgdW5zaWduZWQgc3JjX3BpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKHNyYyk7Cgljb25zdCB1bnNpZ25lZCBkc3RfcGl0Y2ggPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0KTsKCWNvbnN0IHVuc2lnbmVkIGluZGV4ID0gY29sICogYnl0ZXNwcDsKCglCWVRFICpzcmNfYml0cyA9IEZyZWVJbWFnZV9HZXRCaXRzKHNyYykgKyBpbmRleDsKCUJZVEUgKmRzdF9iaXRzID0gRnJlZUltYWdlX0dldEJpdHMoZHN0KSArIGluZGV4OwoKCS8vIGZpbGwgZ2FwIGFib3ZlIHNrZXcgd2l0aCBiYWNrZ3JvdW5kCglpZihia2NvbG9yKSB7CgkJZm9yKGludCBrID0gMDsgayA8IGlPZmZzZXQ7IGsrKykgewoJCQltZW1jcHkoZHN0X2JpdHMsIGJrY29sb3IsIGJ5dGVzcHApOwoJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJfQoJCW1lbWNweSgmcHhsT2xkTGVmdFswXSwgYmtjb2xvciwgYnl0ZXNwcCk7Cgl9IGVsc2UgewoJCWZvcihpbnQgayA9IDA7IGsgPCBpT2Zmc2V0OyBrKyspIHsKCQkJbWVtc2V0KGRzdF9iaXRzLCAwLCBieXRlc3BwKTsKCQkJZHN0X2JpdHMgKz0gZHN0X3BpdGNoOwoJCX0KCQltZW1zZXQoJnB4bE9sZExlZnRbMF0sIDAsIGJ5dGVzcHApOwoJfQoKCWZvcih1bnNpZ25lZCBpID0gMDsgaSA8IHNyY19oZWlnaHQ7IGkrKykgewoJCS8vIGxvb3AgdGhyb3VnaCBjb2x1bW4gcGl4ZWxzCgkJQXNzaWduUGl4ZWwoKEJZVEUqKSgmcHhsU3JjWzBdKSwgc3JjX2JpdHMsIGJ5dGVzcHApOwoJCS8vIGNhbGN1bGF0ZSB3ZWlnaHRzCgkJZm9yKHVuc2lnbmVkIGogPSAwOyBqIDwgc2FtcGxlczsgaisrKSB7CgkJCXB4bExlZnRbal0gPSBzdGF0aWNfY2FzdDxUPihweGxCa2dbal0gKyAocHhsU3JjW2pdIC0gcHhsQmtnW2pdKSAqIHdlaWdodCArIDAuNSk7CgkJfQoJCS8vIGNoZWNrIGJvdW5kYXJpZXMKCQlpWVBvcyA9IGkgKyBpT2Zmc2V0OwoJCWlmKChpWVBvcyA+PSAwKSAmJiAoaVlQb3MgPCAoaW50KWRzdF9oZWlnaHQpKSB7CgkJCS8vIHVwZGF0ZSBsZWZ0IG92ZXIgb24gc291cmNlCgkJCWZvcih1bnNpZ25lZCBqID0gMDsgaiA8IHNhbXBsZXM7IGorKykgewoJCQkJcHhsU3JjW2pdID0gcHhsU3JjW2pdIC0gKHB4bExlZnRbal0gLSBweGxPbGRMZWZ0W2pdKTsKCQkJfQoJCQlkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIGlZUG9zKSArIGluZGV4OwoJCQlBc3NpZ25QaXhlbChkc3RfYml0cywgKEJZVEUqKSgmcHhsU3JjWzBdKSwgYnl0ZXNwcCk7CgkJfQoJCS8vIHNhdmUgbGVmdG92ZXIgZm9yIG5leHQgcGl4ZWwgaW4gc2NhbgoJCUFzc2lnblBpeGVsKChCWVRFKikoJnB4bE9sZExlZnRbMF0pLCAoQllURSopKCZweGxMZWZ0WzBdKSwgYnl0ZXNwcCk7CgoJCS8vIG5leHQgcGl4ZWwgaW4gc2NhbgoJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCX0KCS8vIGdvIHRvIGJvdHRvbSBwb2ludCBvZiBza2V3CglpWVBvcyA9IHNyY19oZWlnaHQgKyBpT2Zmc2V0OwoKCWlmKChpWVBvcyA+PSAwKSAmJiAoaVlQb3MgPCAoaW50KWRzdF9oZWlnaHQpKSB7CgkJZHN0X2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZHN0LCBpWVBvcykgKyBpbmRleDsKCgkJLy8gaWYgc3RpbGwgaW4gaW1hZ2UgYm91bmRzLCBwdXQgbGVmdG92ZXJzIHRoZXJlCQkJCQoJCUFzc2lnblBpeGVsKChCWVRFKikoZHN0X2JpdHMpLCAoQllURSopKCZweGxPbGRMZWZ0WzBdKSwgYnl0ZXNwcCk7CgoJCS8vIGNsZWFyIGJlbG93IHNrZXdlZCBsaW5lIHdpdGggYmFja2dyb3VuZAoJCWlmKGJrY29sb3IpIHsKCQkJd2hpbGUoKytpWVBvcyA8IChpbnQpZHN0X2hlaWdodCkgewkJCQkJCgkJCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7CgkJCQlBc3NpZ25QaXhlbCgoQllURSopKGRzdF9iaXRzKSwgKEJZVEUqKShia2NvbG9yKSwgYnl0ZXNwcCk7CgkJCX0KCQl9IGVsc2UgewoJCQl3aGlsZSgrK2lZUG9zIDwgKGludClkc3RfaGVpZ2h0KSB7CQkJCQkKCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJCW1lbXNldChkc3RfYml0cywgMCwgYnl0ZXNwcCk7CgkJCX0KCQl9Cgl9Cn0KCi8qKgpTa2V3cyBhIGNvbHVtbiB2ZXJ0aWNhbGx5ICh3aXRoIGZpbHRlcmVkIHdlaWdodHMpLiAKTGltaXRlZCB0byA0NSBkZWdyZWUgc2tld2luZyBvbmx5LiBGaWx0ZXJzIHR3byBhZGphY2VudCBwaXhlbHMuCkBwYXJhbSBzcmMgUG9pbnRlciB0byBzb3VyY2UgaW1hZ2UgdG8gcm90YXRlCkBwYXJhbSBkc3QgUG9pbnRlciB0byBkZXN0aW5hdGlvbiBpbWFnZQpAcGFyYW0gY29sIENvbHVtbiBpbmRleApAcGFyYW0gaU9mZnNldCBTa2V3IG9mZnNldApAcGFyYW0gZFdlaWdodCBSZWxhdGl2ZSB3ZWlnaHQgb2YgdXBwZXIgcGl4ZWwKQHBhcmFtIGJrY29sb3IgQmFja2dyb3VuZCBjb2xvcgoqLwpzdGF0aWMgdm9pZCAKVmVydGljYWxTa2V3KEZJQklUTUFQICpzcmMsIEZJQklUTUFQICpkc3QsIGludCBjb2wsIGludCBpT2Zmc2V0LCBkb3VibGUgZFdlaWdodCwgY29uc3Qgdm9pZCAqYmtjb2xvcikgewoJRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKHNyYyk7CgoJc3dpdGNoKGltYWdlX3R5cGUpIHsKCQljYXNlIEZJVF9CSVRNQVA6CgkJCXN3aXRjaChGcmVlSW1hZ2VfR2V0QlBQKHNyYykpIHsKCQkJCWNhc2UgODoKCQkJCWNhc2UgMjQ6CgkJCQljYXNlIDMyOgoJCQkJCVZlcnRpY2FsU2tld1Q8QllURT4oc3JjLCBkc3QsIGNvbCwgaU9mZnNldCwgZFdlaWdodCwgYmtjb2xvcik7CgkJCQkJYnJlYWs7CgkJCX0KCQkJYnJlYWs7CgkJCWNhc2UgRklUX1VJTlQxNjoKCQkJY2FzZSBGSVRfUkdCMTY6CgkJCWNhc2UgRklUX1JHQkExNjoKCQkJCVZlcnRpY2FsU2tld1Q8V09SRD4oc3JjLCBkc3QsIGNvbCwgaU9mZnNldCwgZFdlaWdodCwgYmtjb2xvcik7CgkJCQlicmVhazsKCQkJY2FzZSBGSVRfRkxPQVQ6CgkJCWNhc2UgRklUX1JHQkY6CgkJCWNhc2UgRklUX1JHQkFGOgoJCQkJVmVydGljYWxTa2V3VDxmbG9hdD4oc3JjLCBkc3QsIGNvbCwgaU9mZnNldCwgZFdlaWdodCwgYmtjb2xvcik7CgkJCQlicmVhazsKCX0KfSAKCi8qKgpSb3RhdGVzIGFuIGltYWdlIGJ5IDkwIGRlZ3JlZXMgKGNvdW50ZXIgY2xvY2t3aXNlKS4gClByZWNpc2Ugcm90YXRpb24sIG5vIGZpbHRlcnMgcmVxdWlyZWQuPGJyPgpDb2RlIGFkYXB0ZWQgZnJvbSBDeEltYWdlIChodHRwOi8vd3d3LnhkcC5pdC9jeGltYWdlLmh0bSkKQHBhcmFtIHNyYyBQb2ludGVyIHRvIHNvdXJjZSBpbWFnZSB0byByb3RhdGUKQHJldHVybiBSZXR1cm5zIGEgcG9pbnRlciB0byBhIG5ld2x5IGFsbG9jYXRlZCByb3RhdGVkIGltYWdlIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgTlVMTCBvdGhlcndpc2UKKi8Kc3RhdGljIEZJQklUTUFQKiAKUm90YXRlOTAoRklCSVRNQVAgKnNyYykgewoKCWNvbnN0IHVuc2lnbmVkIGJwcCA9IEZyZWVJbWFnZV9HZXRCUFAoc3JjKTsKCgljb25zdCB1bnNpZ25lZCBzcmNfd2lkdGggID0gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7Cgljb25zdCB1bnNpZ25lZCBzcmNfaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChzcmMpOwkKCWNvbnN0IHVuc2lnbmVkIGRzdF93aWR0aCAgPSBzcmNfaGVpZ2h0OwoJY29uc3QgdW5zaWduZWQgZHN0X2hlaWdodCA9IHNyY193aWR0aDsKCglGUkVFX0lNQUdFX1RZUEUgaW1hZ2VfdHlwZSA9IEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoc3JjKTsKCgkvLyBhbGxvY2F0ZSBhbmQgY2xlYXIgZHN0IGltYWdlCglGSUJJVE1BUCAqZHN0ID0gRnJlZUltYWdlX0FsbG9jYXRlVChpbWFnZV90eXBlLCBkc3Rfd2lkdGgsIGRzdF9oZWlnaHQsIGJwcCk7CglpZihOVUxMID09IGRzdCkgcmV0dXJuIE5VTEw7CgoJLy8gZ2V0IHNyYyBhbmQgZHN0IHNjYW4gd2lkdGgKCWNvbnN0IHVuc2lnbmVkIHNyY19waXRjaCAgPSBGcmVlSW1hZ2VfR2V0UGl0Y2goc3JjKTsKCWNvbnN0IHVuc2lnbmVkIGRzdF9waXRjaCAgPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0KTsKCglzd2l0Y2goaW1hZ2VfdHlwZSkgewoJCWNhc2UgRklUX0JJVE1BUDoKCQkJaWYoYnBwID09IDEpIHsKCQkJCS8vIHNwZWVkeSByb3RhdGUgZm9yIEJXIGltYWdlcwoKCQkJCUJZVEUgKmJzcmMgID0gRnJlZUltYWdlX0dldEJpdHMoc3JjKTsgCgkJCQlCWVRFICpiZGVzdCA9IEZyZWVJbWFnZV9HZXRCaXRzKGRzdCk7CgoJCQkJQllURSAqZGJpdHNtYXggPSBiZGVzdCArIGRzdF9oZWlnaHQgKiBkc3RfcGl0Y2ggLSAxOwoKCQkJCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IHNyY19oZWlnaHQ7IHkrKykgewoJCQkJCS8vIGZpZ3VyZSBvdXQgdGhlIGNvbHVtbiB3ZSBhcmUgZ29pbmcgdG8gYmUgY29weWluZyB0bwoJCQkJCWNvbnN0IGRpdl90IGRpdl9yID0gZGl2KHksIDgpOwoJCQkJCS8vIHNldCBiaXQgcG9zIG9mIHNyYyBjb2x1bW4gYnl0ZQoJCQkJCWNvbnN0IEJZVEUgYml0cG9zID0gKEJZVEUpKDEyOCA+PiBkaXZfci5yZW0pOwoJCQkJCUJZVEUgKnNyY2Rpc3AgPSBic3JjICsgeSAqIHNyY19waXRjaDsKCQkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCBzcmNfcGl0Y2g7IHgrKykgewoJCQkJCQkvLyBnZXQgc291cmNlIGJpdHMKCQkJCQkJQllURSAqc2JpdHMgPSBzcmNkaXNwICsgeDsKCQkJCQkJLy8gZ2V0IGRlc3RpbmF0aW9uIGNvbHVtbgoJCQkJCQlCWVRFICpucm93ID0gYmRlc3QgKyAoZHN0X2hlaWdodCAtIDEgLSAoeCAqIDgpKSAqIGRzdF9waXRjaCArIGRpdl9yLnF1b3Q7CgkJCQkJCWZvciAoaW50IHogPSAwOyB6IDwgODsgeisrKSB7CgkJCQkJCSAgIC8vIGdldCBkZXN0aW5hdGlvbiBieXRlCgkJCQkJCQlCWVRFICpkYml0cyA9IG5yb3cgLSB6ICogZHN0X3BpdGNoOwoJCQkJCQkJaWYgKChkYml0cyA8IGJkZXN0KSB8fCAoZGJpdHMgPiBkYml0c21heCkpIGJyZWFrOwoJCQkJCQkJaWYgKCpzYml0cyAmICgxMjggPj4geikpICpkYml0cyB8PSBiaXRwb3M7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQkJZWxzZSBpZigoYnBwID09IDgpIHx8IChicHAgPT0gMjQpIHx8IChicHAgPT0gMzIpKSB7CgkJCQkvLyBhbnl0aGluZyBvdGhlciB0aGFuIEJXIDoKCQkJCS8vIFRoaXMgb3B0aW1pemVkIHZlcnNpb24gb2Ygcm90YXRpb24gcm90YXRlcyBpbWFnZSBieSBzbWFsbGVyIGJsb2Nrcy4gSXQgaXMgcXVpdGUKCQkJCS8vIGEgYml0IGZhc3RlciB0aGFuIG9idmlvdXMgYWxnb3JpdGhtLCBiZWNhdXNlIGl0IHByb2R1Y2VzIG11Y2ggbGVzcyBDUFUgY2FjaGUgbWlzc2VzLgoJCQkJLy8gVGhpcyBvcHRpbWl6YXRpb24gY2FuIGJlIHR1bmVkIGJ5IGNoYW5naW5nIGJsb2NrIHNpemUgKFJCTE9DSykuIDk2IGlzIGdvb2QgdmFsdWUgZm9yIGN1cnJlbnQKCQkJCS8vIENQVXMgKHRlc3RlZCBvbiBBdGhsb24gWFAgYW5kIENlbGVyb24gRCkuIExhcmdlciB2YWx1ZSAoaWYgQ1BVIGhhcyBlbm91Z2ggY2FjaGUpIHdpbGwgaW5jcmVhc2UKCQkJCS8vIHNwZWVkIHNvbWVob3csIGJ1dCBvbmNlIHlvdSBkcm9wIG91dCBvZiBDUFUncyBjYWNoZSwgdGhpbmdzIHdpbGwgc2xvdyBkb3duIGRyYXN0aWNhbGx5LgoJCQkJLy8gRm9yIG9sZGVyIENQVXMgd2l0aCBsZXNzIGNhY2hlLCBsb3dlciB2YWx1ZSB3b3VsZCB5aWVsZCBiZXR0ZXIgcmVzdWx0cy4KCgkJCQlCWVRFICpic3JjICA9IEZyZWVJbWFnZV9HZXRCaXRzKHNyYyk7ICAvLyBzb3VyY2UgcGl4ZWxzCgkJCQlCWVRFICpiZGVzdCA9IEZyZWVJbWFnZV9HZXRCaXRzKGRzdCk7ICAvLyBkZXN0aW5hdGlvbiBwaXhlbHMKCgkJCQkvLyBjYWxjdWxhdGUgdGhlIG51bWJlciBvZiBieXRlcyBwZXIgcGl4ZWwgKDEgZm9yIDgtYml0LCAzIGZvciAyNC1iaXQgb3IgNCBmb3IgMzItYml0KQoJCQkJY29uc3QgdW5zaWduZWQgYnl0ZXNwcCA9IEZyZWVJbWFnZV9HZXRMaW5lKHNyYykgLyBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsKCQkJCQoJCQkJLy8gZm9yIGFsbCBpbWFnZSBibG9ja3Mgb2YgUkJMT0NLKlJCTE9DSyBwaXhlbHMKCQkJCQoJCQkJLy8geC1zZWdtZW50CgkJCQlmb3IodW5zaWduZWQgeHMgPSAwOyB4cyA8IGRzdF93aWR0aDsgeHMgKz0gUkJMT0NLKSB7CgkJCQkJLy8geS1zZWdtZW50CgkJCQkJZm9yKHVuc2lnbmVkIHlzID0gMDsgeXMgPCBkc3RfaGVpZ2h0OyB5cyArPSBSQkxPQ0spIHsKCQkJCQkJZm9yKHVuc2lnbmVkIHkgPSB5czsgeSA8IE1JTihkc3RfaGVpZ2h0LCB5cyArIFJCTE9DSyk7IHkrKykgeyAgICAvLyBkbyByb3RhdGlvbgoJCQkJCQkJY29uc3QgdW5zaWduZWQgeTIgPSBkc3RfaGVpZ2h0IC0geSAtIDE7CgkJCQkJCQkvLyBwb2ludCB0byBzcmMgcGl4ZWwgYXQgKHkyLCB4cykKCQkJCQkJCUJZVEUgKnNyY19iaXRzID0gYnNyYyArICh4cyAqIHNyY19waXRjaCkgKyAoeTIgKiBieXRlc3BwKTsKCQkJCQkJCS8vIHBvaW50IHRvIGRzdCBwaXhlbCBhdCAoeHMsIHkpCgkJCQkJCQlCWVRFICpkc3RfYml0cyA9IGJkZXN0ICsgKHkgKiBkc3RfcGl0Y2gpICsgKHhzICogYnl0ZXNwcCk7CgkJCQkJCQlmb3IodW5zaWduZWQgeCA9IHhzOyB4IDwgTUlOKGRzdF93aWR0aCwgeHMgKyBSQkxPQ0spOyB4KyspIHsKCQkJCQkJCQkvLyBkc3QuU2V0UGl4ZWwoeCwgeSwgc3JjLkdldFBpeGVsKHkyLCB4KSk7CgkJCQkJCQkJQXNzaWduUGl4ZWwoZHN0X2JpdHMsIHNyY19iaXRzLCBieXRlc3BwKTsKCQkJCQkJCQlkc3RfYml0cyArPSBieXRlc3BwOwoJCQkJCQkJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCQlicmVhazsKCQljYXNlIEZJVF9VSU5UMTY6CgkJY2FzZSBGSVRfUkdCMTY6CgkJY2FzZSBGSVRfUkdCQTE2OgoJCWNhc2UgRklUX0ZMT0FUOgoJCWNhc2UgRklUX1JHQkY6CgkJY2FzZSBGSVRfUkdCQUY6CgkJewoJCQlCWVRFICpic3JjICA9IEZyZWVJbWFnZV9HZXRCaXRzKHNyYyk7ICAvLyBzb3VyY2UgcGl4ZWxzCgkJCUJZVEUgKmJkZXN0ID0gRnJlZUltYWdlX0dldEJpdHMoZHN0KTsgIC8vIGRlc3RpbmF0aW9uIHBpeGVscwoKCQkJLy8gY2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgcGVyIHBpeGVsCgkJCWNvbnN0IHVuc2lnbmVkIGJ5dGVzcHAgPSBGcmVlSW1hZ2VfR2V0TGluZShzcmMpIC8gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7CgoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBkc3RfaGVpZ2h0OyB5KyspIHsKCQkJCUJZVEUgKnNyY19iaXRzID0gYnNyYyArIChzcmNfd2lkdGggLSAxIC0geSkgKiBieXRlc3BwOwoJCQkJQllURSAqZHN0X2JpdHMgPSBiZGVzdCArICh5ICogZHN0X3BpdGNoKTsKCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IGRzdF93aWR0aDsgeCsrKSB7CgkJCQkJQXNzaWduUGl4ZWwoZHN0X2JpdHMsIHNyY19iaXRzLCBieXRlc3BwKTsKCQkJCQlzcmNfYml0cyArPSBzcmNfcGl0Y2g7CgkJCQkJZHN0X2JpdHMgKz0gYnl0ZXNwcDsKCQkJCX0KCQkJfQoJCX0KCQlicmVhazsKCX0KCglyZXR1cm4gZHN0Owp9CgovKioKUm90YXRlcyBhbiBpbWFnZSBieSAxODAgZGVncmVlcyAoY291bnRlciBjbG9ja3dpc2UpLiAKUHJlY2lzZSByb3RhdGlvbiwgbm8gZmlsdGVycyByZXF1aXJlZC4KQHBhcmFtIHNyYyBQb2ludGVyIHRvIHNvdXJjZSBpbWFnZSB0byByb3RhdGUKQHJldHVybiBSZXR1cm5zIGEgcG9pbnRlciB0byBhIG5ld2x5IGFsbG9jYXRlZCByb3RhdGVkIGltYWdlIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgTlVMTCBvdGhlcndpc2UKKi8Kc3RhdGljIEZJQklUTUFQKiAKUm90YXRlMTgwKEZJQklUTUFQICpzcmMpIHsKCWludCB4LCB5LCBrLCBwb3M7CgoJY29uc3QgaW50IGJwcCA9IEZyZWVJbWFnZV9HZXRCUFAoc3JjKTsKCgljb25zdCBpbnQgc3JjX3dpZHRoICA9IEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoJY29uc3QgaW50IHNyY19oZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYyk7Cgljb25zdCBpbnQgZHN0X3dpZHRoICA9IHNyY193aWR0aDsKCWNvbnN0IGludCBkc3RfaGVpZ2h0ID0gc3JjX2hlaWdodDsKCglGUkVFX0lNQUdFX1RZUEUgaW1hZ2VfdHlwZSA9IEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoc3JjKTsKCglGSUJJVE1BUCAqZHN0ID0gRnJlZUltYWdlX0FsbG9jYXRlVChpbWFnZV90eXBlLCBkc3Rfd2lkdGgsIGRzdF9oZWlnaHQsIGJwcCk7CglpZihOVUxMID09IGRzdCkgcmV0dXJuIE5VTEw7CgoJc3dpdGNoKGltYWdlX3R5cGUpIHsKCQljYXNlIEZJVF9CSVRNQVA6CgkJCWlmKGJwcCA9PSAxKSB7CgkJCQlmb3IoaW50IHkgPSAwOyB5IDwgc3JjX2hlaWdodDsgeSsrKSB7CgkJCQkJQllURSAqc3JjX2JpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJCQlCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIGRzdF9oZWlnaHQgLSB5IC0gMSk7CgkJCQkJZm9yKGludCB4ID0gMDsgeCA8IHNyY193aWR0aDsgeCsrKSB7CgkJCQkJCS8vIGdldCBiaXQgYXQgKHgsIHkpCgkJCQkJCWsgPSAoc3JjX2JpdHNbeCA+PiAzXSAmICgweDgwID4+ICh4ICYgMHgwNykpKSAhPSAwOwoJCQkJCQkvLyBzZXQgYml0IGF0IChkc3Rfd2lkdGggLSB4IC0gMSwgZHN0X2hlaWdodCAtIHkgLSAxKQoJCQkJCQlwb3MgPSBkc3Rfd2lkdGggLSB4IC0gMTsKCQkJCQkJayA/IGRzdF9iaXRzW3BvcyA+PiAzXSB8PSAoMHg4MCA+PiAocG9zICYgMHg3KSkgOiBkc3RfYml0c1twb3MgPj4gM10gJj0gKDB4RkY3RiA+PiAocG9zICYgMHg3KSk7CgkJCQkJfQkJCQoJCQkJfQoJCQkJYnJlYWs7CgkJCX0KCQkJLy8gZWxzZSBpZigoYnBwID09IDgpIHx8IChicHAgPT0gMjQpIHx8IChicHAgPT0gMzIpKSBGQUxMIFRST1VHSAoJCWNhc2UgRklUX1VJTlQxNjoKCQljYXNlIEZJVF9SR0IxNjoKCQljYXNlIEZJVF9SR0JBMTY6CgkJY2FzZSBGSVRfRkxPQVQ6CgkJY2FzZSBGSVRfUkdCRjoKCQljYXNlIEZJVF9SR0JBRjoKCQl7CgkJCSAvLyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiBieXRlcyBwZXIgcGl4ZWwKCQkJY29uc3QgaW50IGJ5dGVzcHAgPSBGcmVlSW1hZ2VfR2V0TGluZShzcmMpIC8gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7CgoJCQlmb3IoeSA9IDA7IHkgPCBzcmNfaGVpZ2h0OyB5KyspIHsKCQkJCUJZVEUgKnNyY19iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSk7CgkJCQlCWVRFICpkc3RfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkc3QsIGRzdF9oZWlnaHQgLSB5IC0gMSkgKyAoZHN0X3dpZHRoIC0gMSkgKiBieXRlc3BwOwoJCQkJZm9yKHggPSAwOyB4IDwgc3JjX3dpZHRoOyB4KyspIHsKCQkJCQkvLyBnZXQgcGl4ZWwgYXQgKHgsIHkpCgkJCQkJLy8gc2V0IHBpeGVsIGF0IChkc3Rfd2lkdGggLSB4IC0gMSwgZHN0X2hlaWdodCAtIHkgLSAxKQoJCQkJCUFzc2lnblBpeGVsKGRzdF9iaXRzLCBzcmNfYml0cywgYnl0ZXNwcCk7CgkJCQkJc3JjX2JpdHMgKz0gYnl0ZXNwcDsKCQkJCQlkc3RfYml0cyAtPSBieXRlc3BwOwkJCQkJCgkJCQl9CQkJCQoJCQl9CgkJfQoJCWJyZWFrOwoJfQoKCXJldHVybiBkc3Q7Cn0KCi8qKgpSb3RhdGVzIGFuIGltYWdlIGJ5IDI3MCBkZWdyZWVzIChjb3VudGVyIGNsb2Nrd2lzZSkuIApQcmVjaXNlIHJvdGF0aW9uLCBubyBmaWx0ZXJzIHJlcXVpcmVkLjxicj4KQ29kZSBhZGFwdGVkIGZyb20gQ3hJbWFnZSAoaHR0cDovL3d3dy54ZHAuaXQvY3hpbWFnZS5odG0pCkBwYXJhbSBzcmMgUG9pbnRlciB0byBzb3VyY2UgaW1hZ2UgdG8gcm90YXRlCkByZXR1cm4gUmV0dXJucyBhIHBvaW50ZXIgdG8gYSBuZXdseSBhbGxvY2F0ZWQgcm90YXRlZCBpbWFnZSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIE5VTEwgb3RoZXJ3aXNlCiovCnN0YXRpYyBGSUJJVE1BUCogClJvdGF0ZTI3MChGSUJJVE1BUCAqc3JjKSB7CglpbnQgeDIsIGRsaW5ldXA7CgoJY29uc3QgdW5zaWduZWQgYnBwID0gRnJlZUltYWdlX0dldEJQUChzcmMpOwoKCWNvbnN0IHVuc2lnbmVkIHNyY193aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsKCWNvbnN0IHVuc2lnbmVkIHNyY19oZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYyk7CQoJY29uc3QgdW5zaWduZWQgZHN0X3dpZHRoICA9IHNyY19oZWlnaHQ7Cgljb25zdCB1bnNpZ25lZCBkc3RfaGVpZ2h0ID0gc3JjX3dpZHRoOwoKCUZSRUVfSU1BR0VfVFlQRSBpbWFnZV90eXBlID0gRnJlZUltYWdlX0dldEltYWdlVHlwZShzcmMpOwoKCS8vIGFsbG9jYXRlIGFuZCBjbGVhciBkc3QgaW1hZ2UKCUZJQklUTUFQICpkc3QgPSBGcmVlSW1hZ2VfQWxsb2NhdGVUKGltYWdlX3R5cGUsIGRzdF93aWR0aCwgZHN0X2hlaWdodCwgYnBwKTsKCWlmKE5VTEwgPT0gZHN0KSByZXR1cm4gTlVMTDsKCgkvLyBnZXQgc3JjIGFuZCBkc3Qgc2NhbiB3aWR0aAoJY29uc3QgdW5zaWduZWQgc3JjX3BpdGNoICA9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmMpOwoJY29uc3QgdW5zaWduZWQgZHN0X3BpdGNoICA9IEZyZWVJbWFnZV9HZXRQaXRjaChkc3QpOwoJCglzd2l0Y2goaW1hZ2VfdHlwZSkgewoJCWNhc2UgRklUX0JJVE1BUDoKCQkJaWYoYnBwID09IDEpIHsKCQkJCS8vIHNwZWVkeSByb3RhdGUgZm9yIEJXIGltYWdlcwoJCQkJCgkJCQlCWVRFICpic3JjICA9IEZyZWVJbWFnZV9HZXRCaXRzKHNyYyk7IAoJCQkJQllURSAqYmRlc3QgPSBGcmVlSW1hZ2VfR2V0Qml0cyhkc3QpOwoJCQkJQllURSAqZGJpdHNtYXggPSBiZGVzdCArIGRzdF9oZWlnaHQgKiBkc3RfcGl0Y2ggLSAxOwoJCQkJZGxpbmV1cCA9IDggKiBkc3RfcGl0Y2ggLSBkc3Rfd2lkdGg7CgoJCQkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgc3JjX2hlaWdodDsgeSsrKSB7CgkJCQkJLy8gZmlndXJlIG91dCB0aGUgY29sdW1uIHdlIGFyZSBnb2luZyB0byBiZSBjb3B5aW5nIHRvCgkJCQkJY29uc3QgZGl2X3QgZGl2X3IgPSBkaXYoeSArIGRsaW5ldXAsIDgpOwoJCQkJCS8vIHNldCBiaXQgcG9zIG9mIHNyYyBjb2x1bW4gYnl0ZQoJCQkJCWNvbnN0IEJZVEUgYml0cG9zID0gKEJZVEUpKDEgPDwgZGl2X3IucmVtKTsKCQkJCQljb25zdCBCWVRFICpzcmNkaXNwID0gYnNyYyArIHkgKiBzcmNfcGl0Y2g7CgkJCQkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgc3JjX3BpdGNoOyB4KyspIHsKCQkJCQkJLy8gZ2V0IHNvdXJjZSBiaXRzCgkJCQkJCWNvbnN0IEJZVEUgKnNiaXRzID0gc3JjZGlzcCArIHg7CgkJCQkJCS8vIGdldCBkZXN0aW5hdGlvbiBjb2x1bW4KCQkJCQkJQllURSAqbnJvdyA9IGJkZXN0ICsgKHggKiA4KSAqIGRzdF9waXRjaCArIGRzdF9waXRjaCAtIDEgLSBkaXZfci5xdW90OwoJCQkJCQlmb3IodW5zaWduZWQgeiA9IDA7IHogPCA4OyB6KyspIHsKCQkJCQkJICAgLy8gZ2V0IGRlc3RpbmF0aW9uIGJ5dGUKCQkJCQkJCUJZVEUgKmRiaXRzID0gbnJvdyArIHogKiBkc3RfcGl0Y2g7CgkJCQkJCQlpZiAoKGRiaXRzIDwgYmRlc3QpIHx8IChkYml0cyA+IGRiaXRzbWF4KSkgYnJlYWs7CgkJCQkJCQlpZiAoKnNiaXRzICYgKDEyOCA+PiB6KSkgKmRiaXRzIHw9IGJpdHBvczsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfSAKCQkJZWxzZSBpZigoYnBwID09IDgpIHx8IChicHAgPT0gMjQpIHx8IChicHAgPT0gMzIpKSB7CgkJCQkvLyBhbnl0aGluZyBvdGhlciB0aGFuIEJXIDoKCQkJCS8vIFRoaXMgb3B0aW1pemVkIHZlcnNpb24gb2Ygcm90YXRpb24gcm90YXRlcyBpbWFnZSBieSBzbWFsbGVyIGJsb2Nrcy4gSXQgaXMgcXVpdGUKCQkJCS8vIGEgYml0IGZhc3RlciB0aGFuIG9idmlvdXMgYWxnb3JpdGhtLCBiZWNhdXNlIGl0IHByb2R1Y2VzIG11Y2ggbGVzcyBDUFUgY2FjaGUgbWlzc2VzLgoJCQkJLy8gVGhpcyBvcHRpbWl6YXRpb24gY2FuIGJlIHR1bmVkIGJ5IGNoYW5naW5nIGJsb2NrIHNpemUgKFJCTE9DSykuIDk2IGlzIGdvb2QgdmFsdWUgZm9yIGN1cnJlbnQKCQkJCS8vIENQVXMgKHRlc3RlZCBvbiBBdGhsb24gWFAgYW5kIENlbGVyb24gRCkuIExhcmdlciB2YWx1ZSAoaWYgQ1BVIGhhcyBlbm91Z2ggY2FjaGUpIHdpbGwgaW5jcmVhc2UKCQkJCS8vIHNwZWVkIHNvbWVob3csIGJ1dCBvbmNlIHlvdSBkcm9wIG91dCBvZiBDUFUncyBjYWNoZSwgdGhpbmdzIHdpbGwgc2xvdyBkb3duIGRyYXN0aWNhbGx5LgoJCQkJLy8gRm9yIG9sZGVyIENQVXMgd2l0aCBsZXNzIGNhY2hlLCBsb3dlciB2YWx1ZSB3b3VsZCB5aWVsZCBiZXR0ZXIgcmVzdWx0cy4KCgkJCQlCWVRFICpic3JjICA9IEZyZWVJbWFnZV9HZXRCaXRzKHNyYyk7ICAvLyBzb3VyY2UgcGl4ZWxzCgkJCQlCWVRFICpiZGVzdCA9IEZyZWVJbWFnZV9HZXRCaXRzKGRzdCk7ICAvLyBkZXN0aW5hdGlvbiBwaXhlbHMKCgkJCQkvLyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiBieXRlcyBwZXIgcGl4ZWwgKDEgZm9yIDgtYml0LCAzIGZvciAyNC1iaXQgb3IgNCBmb3IgMzItYml0KQoJCQkJY29uc3QgdW5zaWduZWQgYnl0ZXNwcCA9IEZyZWVJbWFnZV9HZXRMaW5lKHNyYykgLyBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsKCgkJCQkvLyBmb3IgYWxsIGltYWdlIGJsb2NrcyBvZiBSQkxPQ0sqUkJMT0NLIHBpeGVscwoKCQkJCS8vIHgtc2VnbWVudAoJCQkJZm9yKHVuc2lnbmVkIHhzID0gMDsgeHMgPCBkc3Rfd2lkdGg7IHhzICs9IFJCTE9DSykgewoJCQkJCS8vIHktc2VnbWVudAoJCQkJCWZvcih1bnNpZ25lZCB5cyA9IDA7IHlzIDwgZHN0X2hlaWdodDsgeXMgKz0gUkJMT0NLKSB7CgkJCQkJCWZvcih1bnNpZ25lZCB4ID0geHM7IHggPCBNSU4oZHN0X3dpZHRoLCB4cyArIFJCTE9DSyk7IHgrKykgeyAgICAvLyBkbyByb3RhdGlvbgoJCQkJCQkJeDIgPSBkc3Rfd2lkdGggLSB4IC0gMTsKCQkJCQkJCS8vIHBvaW50IHRvIHNyYyBwaXhlbCBhdCAoeXMsIHgyKQoJCQkJCQkJQllURSAqc3JjX2JpdHMgPSBic3JjICsgKHgyICogc3JjX3BpdGNoKSArICh5cyAqIGJ5dGVzcHApOwoJCQkJCQkJLy8gcG9pbnQgdG8gZHN0IHBpeGVsIGF0ICh4LCB5cykKCQkJCQkJCUJZVEUgKmRzdF9iaXRzID0gYmRlc3QgKyAoeXMgKiBkc3RfcGl0Y2gpICsgKHggKiBieXRlc3BwKTsKCQkJCQkJCWZvcih1bnNpZ25lZCB5ID0geXM7IHkgPCBNSU4oZHN0X2hlaWdodCwgeXMgKyBSQkxPQ0spOyB5KyspIHsKCQkJCQkJCQkvLyBkc3QuU2V0UGl4ZWwoeCwgeSwgc3JjLkdldFBpeGVsKHksIHgyKSk7CgkJCQkJCQkJQXNzaWduUGl4ZWwoZHN0X2JpdHMsIHNyY19iaXRzLCBieXRlc3BwKTsKCQkJCQkJCQlzcmNfYml0cyArPSBieXRlc3BwOwoJCQkJCQkJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCQlicmVhazsKCQljYXNlIEZJVF9VSU5UMTY6CgkJY2FzZSBGSVRfUkdCMTY6CgkJY2FzZSBGSVRfUkdCQTE2OgoJCWNhc2UgRklUX0ZMT0FUOgoJCWNhc2UgRklUX1JHQkY6CgkJY2FzZSBGSVRfUkdCQUY6CgkJewoJCQlCWVRFICpic3JjICA9IEZyZWVJbWFnZV9HZXRCaXRzKHNyYyk7ICAvLyBzb3VyY2UgcGl4ZWxzCgkJCUJZVEUgKmJkZXN0ID0gRnJlZUltYWdlX0dldEJpdHMoZHN0KTsgIC8vIGRlc3RpbmF0aW9uIHBpeGVscwoKCQkJLy8gY2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgcGVyIHBpeGVsCgkJCWNvbnN0IHVuc2lnbmVkIGJ5dGVzcHAgPSBGcmVlSW1hZ2VfR2V0TGluZShzcmMpIC8gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7CgoJCQlmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBkc3RfaGVpZ2h0OyB5KyspIHsKCQkJCUJZVEUgKnNyY19iaXRzID0gYnNyYyArIChzcmNfaGVpZ2h0IC0gMSkgKiBzcmNfcGl0Y2ggKyB5ICogYnl0ZXNwcDsKCQkJCUJZVEUgKmRzdF9iaXRzID0gYmRlc3QgKyAoeSAqIGRzdF9waXRjaCk7CgkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCBkc3Rfd2lkdGg7IHgrKykgewoJCQkJCUFzc2lnblBpeGVsKGRzdF9iaXRzLCBzcmNfYml0cywgYnl0ZXNwcCk7CgkJCQkJc3JjX2JpdHMgLT0gc3JjX3BpdGNoOwoJCQkJCWRzdF9iaXRzICs9IGJ5dGVzcHA7CgkJCQl9CgkJCX0KCQl9CgkJYnJlYWs7Cgl9CgoJcmV0dXJuIGRzdDsKfQoKLyoqClJvdGF0ZXMgYW4gaW1hZ2UgYnkgYSBnaXZlbiBkZWdyZWUgaW4gcmFuZ2UgWy00NSAuLiArNDVdIChjb3VudGVyIGNsb2Nrd2lzZSkgCnVzaW5nIHRoZSAzLXNoZWFyIHRlY2huaXF1ZS4KQHBhcmFtIHNyYyBQb2ludGVyIHRvIHNvdXJjZSBpbWFnZSB0byByb3RhdGUKQHBhcmFtIGRBbmdsZSBSb3RhdGlvbiBhbmdsZQpAcmV0dXJuIFJldHVybnMgYSBwb2ludGVyIHRvIGEgbmV3bHkgYWxsb2NhdGVkIHJvdGF0ZWQgaW1hZ2UgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBOVUxMIG90aGVyd2lzZQoqLwpzdGF0aWMgRklCSVRNQVAqIApSb3RhdGU0NShGSUJJVE1BUCAqc3JjLCBkb3VibGUgZEFuZ2xlLCBjb25zdCB2b2lkICpia2NvbG9yKSB7Cgljb25zdCBkb3VibGUgUk9UQVRFX1BJID0gZG91YmxlKDMuMTQxNTkyNjUzNTg5NzkzMjM4NDYyNjQzMzgzMjc5NSk7CgoJdW5zaWduZWQgdTsKCgljb25zdCB1bnNpZ25lZCBicHAgPSBGcmVlSW1hZ2VfR2V0QlBQKHNyYyk7CgoJY29uc3QgZG91YmxlIGRSYWRBbmdsZSA9IGRBbmdsZSAqIFJPVEFURV9QSSAvIGRvdWJsZSgxODApOyAvLyBBbmdsZSBpbiByYWRpYW5zCgljb25zdCBkb3VibGUgZFNpbkUgPSBzaW4oZFJhZEFuZ2xlKTsKCWNvbnN0IGRvdWJsZSBkVGFuID0gdGFuKGRSYWRBbmdsZSAvIDIpOwoKCWNvbnN0IHVuc2lnbmVkIHNyY193aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsKCWNvbnN0IHVuc2lnbmVkIHNyY19oZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYyk7CgoJRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKHNyYyk7CgoJLy8gQ2FsYyBmaXJzdCBzaGVhciAoaG9yaXpvbnRhbCkgZGVzdGluYXRpb24gaW1hZ2UgZGltZW5zaW9ucyAKCWNvbnN0IHVuc2lnbmVkIHdpZHRoXzEgID0gc3JjX3dpZHRoICsgdW5zaWduZWQoKGRvdWJsZSlzcmNfaGVpZ2h0ICogZmFicyhkVGFuKSArIDAuNSk7Cgljb25zdCB1bnNpZ25lZCBoZWlnaHRfMSA9IHNyY19oZWlnaHQ7IAoKCS8vIFBlcmZvcm0gMXN0IHNoZWFyIChob3Jpem9udGFsKQoJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCS8vIEFsbG9jYXRlIGltYWdlIGZvciAxc3Qgc2hlYXIKCUZJQklUTUFQICpkc3QxID0gRnJlZUltYWdlX0FsbG9jYXRlVChpbWFnZV90eXBlLCB3aWR0aF8xLCBoZWlnaHRfMSwgYnBwKTsKCWlmKE5VTEwgPT0gZHN0MSkgewoJCXJldHVybiBOVUxMOwoJfQoJCglmb3IodSA9IDA7IHUgPCBoZWlnaHRfMTsgdSsrKSB7ICAKCQlkb3VibGUgZFNoZWFyOwoKCQlpZihkVGFuID49IDApCXsKCQkJLy8gUG9zaXRpdmUgYW5nbGUKCQkJZFNoZWFyID0gKHUgKyAwLjUpICogZFRhbjsKCQl9CgkJZWxzZSB7CgkJCS8vIE5lZ2F0aXZlIGFuZ2xlCgkJCWRTaGVhciA9IChkb3VibGUodSkgLSBoZWlnaHRfMSArIDAuNSkgKiBkVGFuOwoJCX0KCQlpbnQgaVNoZWFyID0gaW50KGZsb29yKGRTaGVhcikpOwoJCUhvcml6b250YWxTa2V3KHNyYywgZHN0MSwgdSwgaVNoZWFyLCBkU2hlYXIgLSBkb3VibGUoaVNoZWFyKSwgYmtjb2xvcik7Cgl9CgoJLy8gUGVyZm9ybSAybmQgc2hlYXIgICh2ZXJ0aWNhbCkKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgkvLyBDYWxjIDJuZCBzaGVhciAodmVydGljYWwpIGRlc3RpbmF0aW9uIGltYWdlIGRpbWVuc2lvbnMKCWNvbnN0IHVuc2lnbmVkIHdpZHRoXzIgID0gd2lkdGhfMTsKCXVuc2lnbmVkIGhlaWdodF8yID0gdW5zaWduZWQoKGRvdWJsZSlzcmNfd2lkdGggKiBmYWJzKGRTaW5FKSArIChkb3VibGUpc3JjX2hlaWdodCAqIGNvcyhkUmFkQW5nbGUpICsgMC41KSArIDE7CgoJLy8gQWxsb2NhdGUgaW1hZ2UgZm9yIDJuZCBzaGVhcgoJRklCSVRNQVAgKmRzdDIgPSBGcmVlSW1hZ2VfQWxsb2NhdGVUKGltYWdlX3R5cGUsIHdpZHRoXzIsIGhlaWdodF8yLCBicHApOwoJaWYoTlVMTCA9PSBkc3QyKSB7CgkJRnJlZUltYWdlX1VubG9hZChkc3QxKTsKCQlyZXR1cm4gTlVMTDsKCX0KCglkb3VibGUgZE9mZnNldDsgICAgIC8vIFZhcmlhYmxlIHNrZXcgb2Zmc2V0CglpZihkU2luRSA+IDApCXsgICAKCQkvLyBQb3NpdGl2ZSBhbmdsZQoJCWRPZmZzZXQgPSAoc3JjX3dpZHRoIC0gMS4wKSAqIGRTaW5FOwoJfQoJZWxzZSB7CgkJLy8gTmVnYXRpdmUgYW5nbGUKCQlkT2Zmc2V0ID0gLWRTaW5FICogKGRvdWJsZShzcmNfd2lkdGgpIC0gd2lkdGhfMik7Cgl9CgoJZm9yKHUgPSAwOyB1IDwgd2lkdGhfMjsgdSsrLCBkT2Zmc2V0IC09IGRTaW5FKSB7CgkJaW50IGlTaGVhciA9IGludChmbG9vcihkT2Zmc2V0KSk7CgkJVmVydGljYWxTa2V3KGRzdDEsIGRzdDIsIHUsIGlTaGVhciwgZE9mZnNldCAtIGRvdWJsZShpU2hlYXIpLCBia2NvbG9yKTsKCX0KCgkvLyBQZXJmb3JtIDNyZCBzaGVhciAoaG9yaXpvbnRhbCkKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgkvLyBGcmVlIHJlc3VsdCBvZiAxc3Qgc2hlYXIKCUZyZWVJbWFnZV9VbmxvYWQoZHN0MSk7CgoJLy8gQ2FsYyAzcmQgc2hlYXIgKGhvcml6b250YWwpIGRlc3RpbmF0aW9uIGltYWdlIGRpbWVuc2lvbnMKCWNvbnN0IHVuc2lnbmVkIHdpZHRoXzMgID0gdW5zaWduZWQoZG91YmxlKHNyY19oZWlnaHQpICogZmFicyhkU2luRSkgKyBkb3VibGUoc3JjX3dpZHRoKSAqIGNvcyhkUmFkQW5nbGUpICsgMC41KSArIDE7Cgljb25zdCB1bnNpZ25lZCBoZWlnaHRfMyA9IGhlaWdodF8yOwoKCS8vIEFsbG9jYXRlIGltYWdlIGZvciAzcmQgc2hlYXIKCUZJQklUTUFQICpkc3QzID0gRnJlZUltYWdlX0FsbG9jYXRlVChpbWFnZV90eXBlLCB3aWR0aF8zLCBoZWlnaHRfMywgYnBwKTsKCWlmKE5VTEwgPT0gZHN0MykgewoJCUZyZWVJbWFnZV9VbmxvYWQoZHN0Mik7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJaWYoZFNpbkUgPj0gMCkgewoJCS8vIFBvc2l0aXZlIGFuZ2xlCgkJZE9mZnNldCA9IChzcmNfd2lkdGggLSAxLjApICogZFNpbkUgKiAtZFRhbjsKCX0KCWVsc2UgewoJCS8vIE5lZ2F0aXZlIGFuZ2xlCgkJZE9mZnNldCA9IGRUYW4gKiAoIChzcmNfd2lkdGggLSAxLjApICogLWRTaW5FICsgKDEuMCAtIGhlaWdodF8zKSApOwoJfQoJZm9yKHUgPSAwOyB1IDwgaGVpZ2h0XzM7IHUrKywgZE9mZnNldCArPSBkVGFuKSB7CgkJaW50IGlTaGVhciA9IGludChmbG9vcihkT2Zmc2V0KSk7CgkJSG9yaXpvbnRhbFNrZXcoZHN0MiwgZHN0MywgdSwgaVNoZWFyLCBkT2Zmc2V0IC0gZG91YmxlKGlTaGVhciksIGJrY29sb3IpOwoJfQoJLy8gRnJlZSByZXN1bHQgb2YgMm5kIHNoZWFyICAgIAoJRnJlZUltYWdlX1VubG9hZChkc3QyKTsKCgkvLyBSZXR1cm4gcmVzdWx0IG9mIDNyZCBzaGVhcgoJcmV0dXJuIGRzdDM7ICAgICAgCn0KCi8qKgpSb3RhdGVzIGEgMS0sIDgtLCAyNC0gb3IgMzItYml0IGltYWdlIGJ5IGEgZ2l2ZW4gYW5nbGUgKGdpdmVuIGluIGRlZ3JlZSkuIApBbmdsZSBpcyB1bmxpbWl0ZWQsIGV4Y2VwdCBmb3IgMS1iaXQgaW1hZ2VzIChsaW1pdGVkIHRvIGludGVnZXIgbXVsdGlwbGVzIG9mIDkwIGRlZ3JlZSkuIAozLXNoZWFycyB0ZWNobmlxdWUgaXMgdXNlZC4KQHBhcmFtIHNyYyBQb2ludGVyIHRvIHNvdXJjZSBpbWFnZSB0byByb3RhdGUKQHBhcmFtIGRBbmdsZSBSb3RhdGlvbiBhbmdsZQpAcmV0dXJuIFJldHVybnMgYSBwb2ludGVyIHRvIGEgbmV3bHkgYWxsb2NhdGVkIHJvdGF0ZWQgaW1hZ2UgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBOVUxMIG90aGVyd2lzZQoqLwpzdGF0aWMgRklCSVRNQVAqIApSb3RhdGVBbnkoRklCSVRNQVAgKnNyYywgZG91YmxlIGRBbmdsZSwgY29uc3Qgdm9pZCAqYmtjb2xvcikgewoJaWYoTlVMTCA9PSBzcmMpIHsKCQlyZXR1cm4gTlVMTDsKCX0KCglGSUJJVE1BUCAqaW1hZ2UgPSBzcmM7CgoJd2hpbGUoZEFuZ2xlID49IDM2MCkgewoJCS8vIEJyaW5nIGFuZ2xlIHRvIHJhbmdlIG9mICgtSU5GIC4uIDM2MCkKCQlkQW5nbGUgLT0gMzYwOwoJfQoJd2hpbGUoZEFuZ2xlIDwgMCkgewoJCS8vIEJyaW5nIGFuZ2xlIHRvIHJhbmdlIG9mIFswIC4uIDM2MCkgCgkJZEFuZ2xlICs9IDM2MDsKCX0KCWlmKChkQW5nbGUgPiA0NSkgJiYgKGRBbmdsZSA8PSAxMzUpKSB7CgkJLy8gQW5nbGUgaW4gKDQ1IC4uIDEzNV0gCgkJLy8gUm90YXRlIGltYWdlIGJ5IDkwIGRlZ3JlZXMgaW50byB0ZW1wb3JhcnkgaW1hZ2UsCgkJLy8gc28gaXQgcmVxdWlyZXMgb25seSBhbiBleHRyYSByb3RhdGlvbiBhbmdsZSAKCQkvLyBvZiAtNDUgLi4gKzQ1IHRvIGNvbXBsZXRlIHJvdGF0aW9uLgoJCWltYWdlID0gUm90YXRlOTAoc3JjKTsKCQlkQW5nbGUgLT0gOTA7Cgl9CgllbHNlIGlmKChkQW5nbGUgPiAxMzUpICYmIChkQW5nbGUgPD0gMjI1KSkgeyAKCQkvLyBBbmdsZSBpbiAoMTM1IC4uIDIyNV0gCgkJLy8gUm90YXRlIGltYWdlIGJ5IDE4MCBkZWdyZWVzIGludG8gdGVtcG9yYXJ5IGltYWdlLAoJCS8vIHNvIGl0IHJlcXVpcmVzIG9ubHkgYW4gZXh0cmEgcm90YXRpb24gYW5nbGUgCgkJLy8gb2YgLTQ1IC4uICs0NSB0byBjb21wbGV0ZSByb3RhdGlvbi4KCQlpbWFnZSA9IFJvdGF0ZTE4MChzcmMpOwoJCWRBbmdsZSAtPSAxODA7Cgl9CgllbHNlIGlmKChkQW5nbGUgPiAyMjUpICYmIChkQW5nbGUgPD0gMzE1KSkgeyAKCQkvLyBBbmdsZSBpbiAoMjI1IC4uIDMxNV0gCgkJLy8gUm90YXRlIGltYWdlIGJ5IDI3MCBkZWdyZWVzIGludG8gdGVtcG9yYXJ5IGltYWdlLAoJCS8vIHNvIGl0IHJlcXVpcmVzIG9ubHkgYW4gZXh0cmEgcm90YXRpb24gYW5nbGUgCgkJLy8gb2YgLTQ1IC4uICs0NSB0byBjb21wbGV0ZSByb3RhdGlvbi4KCQlpbWFnZSA9IFJvdGF0ZTI3MChzcmMpOwoJCWRBbmdsZSAtPSAyNzA7Cgl9CgoJLy8gSWYgd2UgZ290IGhlcmUsIGFuZ2xlIGlzIGluICgtNDUgLi4gKzQ1XQoKCWlmKE5VTEwgPT0gaW1hZ2UpCXsKCQkvLyBGYWlsZWQgdG8gYWxsb2NhdGUgbWlkZGxlIGltYWdlCgkJcmV0dXJuIE5VTEw7Cgl9CgoJaWYoMCA9PSBkQW5nbGUpIHsKCQlpZihpbWFnZSA9PSBzcmMpIHsKCQkJLy8gTm90aGluZyB0byBkbyAuLi4KCQkJcmV0dXJuIEZyZWVJbWFnZV9DbG9uZShzcmMpOwoJCX0gZWxzZSB7CgkJCS8vIE5vIG1vcmUgcm90YXRpb24gbmVlZGVkCgkJCXJldHVybiBpbWFnZTsKCQl9Cgl9CgllbHNlIHsKCQkvLyBQZXJmb3JtIGxhc3Qgcm90YXRpb24KCQlGSUJJVE1BUCAqZHN0ID0gUm90YXRlNDUoaW1hZ2UsIGRBbmdsZSwgYmtjb2xvcik7CgoJCWlmKHNyYyAhPSBpbWFnZSkgewoJCQkvLyBNaWRkbGUgaW1hZ2Ugd2FzIHJlcXVpcmVkLCBmcmVlIGl0IG5vdy4KCQkJRnJlZUltYWdlX1VubG9hZChpbWFnZSk7CgkJfQoKCQlyZXR1cm4gZHN0OwoJfQp9CgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgpGSUJJVE1BUCAqRExMX0NBTExDT05WIApGcmVlSW1hZ2VfUm90YXRlKEZJQklUTUFQICpkaWIsIGRvdWJsZSBhbmdsZSwgY29uc3Qgdm9pZCAqYmtjb2xvcikgewoJaWYoIUZyZWVJbWFnZV9IYXNQaXhlbHMoZGliKSkgcmV0dXJuIE5VTEw7CgoJaWYoMCA9PSBhbmdsZSkgewoJCXJldHVybiBGcmVlSW1hZ2VfQ2xvbmUoZGliKTsKCX0KCS8vIERJQiBhcmUgc3RvcmVkIHVwc2lkZSBkb3duIC4uLgoJYW5nbGUgKj0gLTE7CgoJdHJ5IHsKCQl1bnNpZ25lZCBicHAgPSBGcmVlSW1hZ2VfR2V0QlBQKGRpYik7CgkJRlJFRV9JTUFHRV9UWVBFIGltYWdlX3R5cGUgPSBGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRpYik7CgkJCgkJc3dpdGNoKGltYWdlX3R5cGUpIHsKCQkJY2FzZSBGSVRfQklUTUFQOgoJCQkJaWYoYnBwID09IDEpIHsKCQkJCQkvLyBvbmx5IHJvdGF0ZSBmb3IgaW50ZWdlciBtdWx0aXBsZXMgb2YgOTAgZGVncmVlCgkJCQkJaWYoZm1vZChhbmdsZSwgOTApICE9IDApCgkJCQkJCXJldHVybiBOVUxMOwoKCQkJCQkvLyBwZXJmb3JtIHRoZSByb3RhdGlvbgoJCQkJCUZJQklUTUFQICpkc3QgPSBSb3RhdGVBbnkoZGliLCBhbmdsZSwgYmtjb2xvcik7CgkJCQkJaWYoIWRzdCkgdGhyb3coMSk7CgoJCQkJCS8vIGJ1aWxkIGEgZ3JleXNjYWxlIHBhbGV0dGUKCQkJCQlSR0JRVUFEICpkc3RfcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoZHN0KTsKCQkJCQlpZihGcmVlSW1hZ2VfR2V0Q29sb3JUeXBlKGRpYikgPT0gRklDX01JTklTQkxBQ0spIHsKCQkJCQkJZHN0X3BhbFswXS5yZ2JSZWQgPSBkc3RfcGFsWzBdLnJnYkdyZWVuID0gZHN0X3BhbFswXS5yZ2JCbHVlID0gMDsKCQkJCQkJZHN0X3BhbFsxXS5yZ2JSZWQgPSBkc3RfcGFsWzFdLnJnYkdyZWVuID0gZHN0X3BhbFsxXS5yZ2JCbHVlID0gMjU1OwkJCQoJCQkJCX0gZWxzZSB7CgkJCQkJCWRzdF9wYWxbMF0ucmdiUmVkID0gZHN0X3BhbFswXS5yZ2JHcmVlbiA9IGRzdF9wYWxbMF0ucmdiQmx1ZSA9IDI1NTsKCQkJCQkJZHN0X3BhbFsxXS5yZ2JSZWQgPSBkc3RfcGFsWzFdLnJnYkdyZWVuID0gZHN0X3BhbFsxXS5yZ2JCbHVlID0gMDsJCQkKCQkJCQl9CgoJCQkJCS8vIGNvcHkgbWV0YWRhdGEgZnJvbSBzcmMgdG8gZHN0CgkJCQkJRnJlZUltYWdlX0Nsb25lTWV0YWRhdGEoZHN0LCBkaWIpOwoKCQkJCQlyZXR1cm4gZHN0OwoJCQkJfQoJCQkJZWxzZSBpZigoYnBwID09IDgpIHx8IChicHAgPT0gMjQpIHx8IChicHAgPT0gMzIpKSB7CgkJCQkJRklCSVRNQVAgKmRzdCA9IFJvdGF0ZUFueShkaWIsIGFuZ2xlLCBia2NvbG9yKTsKCQkJCQlpZighZHN0KSB0aHJvdygxKTsKCQkJCQkKCQkJCQlpZihicHAgPT0gOCkgewoJCQkJCQkvLyBjb3B5IG9yaWdpbmFsIHBhbGV0dGUgdG8gcm90YXRlZCBiaXRtYXAKCQkJCQkJUkdCUVVBRCAqc3JjX3BhbCA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYik7CgkJCQkJCVJHQlFVQUQgKmRzdF9wYWwgPSBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkc3QpOwoJCQkJCQltZW1jcHkoJmRzdF9wYWxbMF0sICZzcmNfcGFsWzBdLCAyNTYgKiBzaXplb2YoUkdCUVVBRCkpOwoKCQkJCQkJLy8gY29weSB0cmFuc3BhcmVuY3kgdGFibGUgCgkJCQkJCUZyZWVJbWFnZV9TZXRUcmFuc3BhcmVuY3lUYWJsZShkc3QsIEZyZWVJbWFnZV9HZXRUcmFuc3BhcmVuY3lUYWJsZShkaWIpLCBGcmVlSW1hZ2VfR2V0VHJhbnNwYXJlbmN5Q291bnQoZGliKSk7CgoJCQkJCQkvLyBjb3B5IGJhY2tncm91bmQgY29sb3IgCgkJCQkJCVJHQlFVQUQgYmtjb2xvcjsgCgkJCQkJCWlmKCBGcmVlSW1hZ2VfR2V0QmFja2dyb3VuZENvbG9yKGRpYiwgJmJrY29sb3IpICkgewoJCQkJCQkJRnJlZUltYWdlX1NldEJhY2tncm91bmRDb2xvcihkc3QsICZia2NvbG9yKTsgCgkJCQkJCX0KCgkJCQkJfQoKCQkJCQkvLyBjb3B5IG1ldGFkYXRhIGZyb20gc3JjIHRvIGRzdAoJCQkJCUZyZWVJbWFnZV9DbG9uZU1ldGFkYXRhKGRzdCwgZGliKTsKCgkJCQkJcmV0dXJuIGRzdDsKCQkJCX0KCQkJCWJyZWFrOwoJCQljYXNlIEZJVF9VSU5UMTY6CgkJCWNhc2UgRklUX1JHQjE2OgoJCQljYXNlIEZJVF9SR0JBMTY6CgkJCWNhc2UgRklUX0ZMT0FUOgoJCQljYXNlIEZJVF9SR0JGOgoJCQljYXNlIEZJVF9SR0JBRjoKCQkJewoJCQkJRklCSVRNQVAgKmRzdCA9IFJvdGF0ZUFueShkaWIsIGFuZ2xlLCBia2NvbG9yKTsKCQkJCWlmKCFkc3QpIHRocm93KDEpOwoKCQkJCS8vIGNvcHkgbWV0YWRhdGEgZnJvbSBzcmMgdG8gZHN0CgkJCQlGcmVlSW1hZ2VfQ2xvbmVNZXRhZGF0YShkc3QsIGRpYik7CgoJCQkJcmV0dXJuIGRzdDsKCQkJfQoJCQlicmVhazsKCQl9CgoJfSBjYXRjaChpbnQpIHsKCQlyZXR1cm4gTlVMTDsKCX0KCglyZXR1cm4gTlVMTDsKfQoK