Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBDb2xvciBtYW5pcHVsYXRpb24gcm91dGluZXMKLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIC0gQ2Fyc3RlbiBLbGVpbiAoYy5rbGVpbkBkYXRhZ2lzLmNvbSkKLy8gLSBNaWhhaWwgTmF5ZGVub3YgKG1uYXlkZW5vdkB1c2Vycy5zb3VyY2Vmb3JnZS5uZXQpCi8vCi8vIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEZyZWVJbWFnZSAzCi8vCi8vIENPVkVSRUQgQ09ERSBJUyBQUk9WSURFRCBVTkRFUiBUSElTIExJQ0VOU0UgT04gQU4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5UWQovLyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1NFRCBPUiBJTVBMSUVELCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgV0FSUkFOVElFUwovLyBUSEFUIFRIRSBDT1ZFUkVEIENPREUgSVMgRlJFRSBPRiBERUZFQ1RTLCBNRVJDSEFOVEFCTEUsIEZJVCBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKLy8gT1IgTk9OLUlORlJJTkdJTkcuIFRIRSBFTlRJUkUgUklTSyBBUyBUTyBUSEUgUVVBTElUWSBBTkQgUEVSRk9STUFOQ0UgT0YgVEhFIENPVkVSRUQKLy8gQ09ERSBJUyBXSVRIIFlPVS4gU0hPVUxEIEFOWSBDT1ZFUkVEIENPREUgUFJPVkUgREVGRUNUSVZFIElOIEFOWSBSRVNQRUNULCBZT1UgKE5PVAovLyBUSEUgSU5JVElBTCBERVZFTE9QRVIgT1IgQU5ZIE9USEVSIENPTlRSSUJVVE9SKSBBU1NVTUUgVEhFIENPU1QgT0YgQU5ZIE5FQ0VTU0FSWQovLyBTRVJWSUNJTkcsIFJFUEFJUiBPUiBDT1JSRUNUSU9OLiBUSElTIERJU0NMQUlNRVIgT0YgV0FSUkFOVFkgQ09OU1RJVFVURVMgQU4gRVNTRU5USUFMCi8vIFBBUlQgT0YgVEhJUyBMSUNFTlNFLiBOTyBVU0UgT0YgQU5ZIENPVkVSRUQgQ09ERSBJUyBBVVRIT1JJWkVEIEhFUkVVTkRFUiBFWENFUFQgVU5ERVIKLy8gVEhJUyBESVNDTEFJTUVSLgovLwovLyBVc2UgYXQgeW91ciBvd24gcmlzayEKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2luY2x1ZGUgIkZyZWVJbWFnZS5oIgojaW5jbHVkZSAiVXRpbGl0aWVzLmgiCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgTWFjcm9zICsgc3RydWN0dXJlcwovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojZGVmaW5lIEdFVF9ISV9OSUJCTEUoYnl0ZSkgICAgICgoYnl0ZSkgPj4gNCkKI2RlZmluZSBTRVRfSElfTklCQkxFKGJ5dGUsIG4pICBieXRlICY9IDB4MEYsIGJ5dGUgfD0gKChuKSA8PCA0KQojZGVmaW5lIEdFVF9MT19OSUJCTEUoYnl0ZSkgICAgICgoYnl0ZSkgJiAweDBGKQojZGVmaW5lIFNFVF9MT19OSUJCTEUoYnl0ZSwgbikgIGJ5dGUgJj0gMHhGMCwgYnl0ZSB8PSAoKG4pICYgMHgwRikKI2RlZmluZSBHRVRfTklCQkxFKGNuLCBieXRlKSAgICAoKGNuKSA/IChHRVRfSElfTklCQkxFKGJ5dGUpKSA6IChHRVRfTE9fTklCQkxFKGJ5dGUpKSkgCiNkZWZpbmUgU0VUX05JQkJMRShjbiwgYnl0ZSwgbikgaWYgKGNuKSBTRVRfSElfTklCQkxFKGJ5dGUsIG4pOyBlbHNlIFNFVF9MT19OSUJCTEUoYnl0ZSwgbikgCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoKLyoqIEBicmllZiBJbnZlcnRzIGVhY2ggcGl4ZWwgZGF0YS4KCkBwYXJhbSBzcmMgSW5wdXQgaW1hZ2UgdG8gYmUgcHJvY2Vzc2VkLgpAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuCiovCkJPT0wgRExMX0NBTExDT05WIApGcmVlSW1hZ2VfSW52ZXJ0KEZJQklUTUFQICpzcmMpIHsKCglpZiAoIUZyZWVJbWFnZV9IYXNQaXhlbHMoc3JjKSkgcmV0dXJuIEZBTFNFOwoJCgl1bnNpZ25lZCBpLCB4LCB5LCBrOwoJCgljb25zdCB1bnNpZ25lZCB3aWR0aCA9IEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoJY29uc3QgdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChzcmMpOwoJY29uc3QgdW5zaWduZWQgYnBwID0gRnJlZUltYWdlX0dldEJQUChzcmMpOwoKCUZSRUVfSU1BR0VfVFlQRSBpbWFnZV90eXBlID0gRnJlZUltYWdlX0dldEltYWdlVHlwZShzcmMpOwoKCWlmKGltYWdlX3R5cGUgPT0gRklUX0JJVE1BUCkgewoJCXN3aXRjaChicHApIHsKCQkJY2FzZSAxIDoKCQkJY2FzZSA0IDoKCQkJY2FzZSA4IDoKCQkJewoJCQkJLy8gaWYgdGhlIGRpYiBoYXMgYSBjb2xvcm1hcCwganVzdCBpbnZlcnQgaXQKCQkJCS8vIGVsc2UsIGtlZXAgdGhlIGxpbmVhciBncmF5c2NhbGUKCgkJCQlpZiAoRnJlZUltYWdlX0dldENvbG9yVHlwZShzcmMpID09IEZJQ19QQUxFVFRFKSB7CgkJCQkJUkdCUVVBRCAqcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoc3JjKTsKCgkJCQkJZm9yKGkgPSAwOyBpIDwgRnJlZUltYWdlX0dldENvbG9yc1VzZWQoc3JjKTsgaSsrKSB7CgkJCQkJCXBhbFtpXS5yZ2JSZWQJPSAyNTUgLSBwYWxbaV0ucmdiUmVkOwoJCQkJCQlwYWxbaV0ucmdiR3JlZW4gPSAyNTUgLSBwYWxbaV0ucmdiR3JlZW47CgkJCQkJCXBhbFtpXS5yZ2JCbHVlCT0gMjU1IC0gcGFsW2ldLnJnYkJsdWU7CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQlmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSk7CgoJCQkJCQlmb3IgKHggPSAwOyB4IDwgRnJlZUltYWdlX0dldExpbmUoc3JjKTsgeCsrKSB7CgkJCQkJCQliaXRzW3hdID0gfmJpdHNbeF07CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgoJCQkJYnJlYWs7CgkJCX0JCQoKCQkJY2FzZSAyNCA6CgkJCWNhc2UgMzIgOgoJCQl7CgkJCQkvLyBDYWxjdWxhdGUgdGhlIG51bWJlciBvZiBieXRlcyBwZXIgcGl4ZWwgKDMgZm9yIDI0LWJpdCBvciA0IGZvciAzMi1iaXQpCgkJCQljb25zdCB1bnNpZ25lZCBieXRlc3BwID0gRnJlZUltYWdlX0dldExpbmUoc3JjKSAvIHdpZHRoOwoKCQkJCWZvcih5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkJQllURSAqYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQkJCWZvcih4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJZm9yKGsgPSAwOyBrIDwgYnl0ZXNwcDsgaysrKSB7CgkJCQkJCQliaXRzW2tdID0gfmJpdHNba107CgkJCQkJCX0KCQkJCQkJYml0cyArPSBieXRlc3BwOwoJCQkJCX0KCQkJCX0KCgkJCQlicmVhazsKCQkJfQoJCQlkZWZhdWx0OgoJCQkJcmV0dXJuIEZBTFNFOwoJCX0KCX0KCWVsc2UgaWYoKGltYWdlX3R5cGUgPT0gRklUX1VJTlQxNikgfHwgKGltYWdlX3R5cGUgPT0gRklUX1JHQjE2KSB8fCAoaW1hZ2VfdHlwZSA9PSBGSVRfUkdCQTE2KSkgewoJCS8vIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIHdvcmRzIHBlciBwaXhlbCAoMSBmb3IgMTYtYml0LCAzIGZvciA0OC1iaXQgb3IgNCBmb3IgNjQtYml0KQoJCWNvbnN0IHVuc2lnbmVkIHdvcmRzcHAgPSAoRnJlZUltYWdlX0dldExpbmUoc3JjKSAvIHdpZHRoKSAvIHNpemVvZihXT1JEKTsKCgkJZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJV09SRCAqYml0cyA9IChXT1JEKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJZm9yKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJZm9yKGsgPSAwOyBrIDwgd29yZHNwcDsgaysrKSB7CgkJCQkJYml0c1trXSA9IH5iaXRzW2tdOwoJCQkJfQoJCQkJYml0cyArPSB3b3Jkc3BwOwoJCQl9CgkJfQoJfQoJZWxzZSB7CgkJLy8gYW55dGhpbmcgZWxzZSAuLi4gCgkJcmV0dXJuIEZBTFNFOwoJfQoJCQoJcmV0dXJuIFRSVUU7Cn0KCi8qKiBAYnJpZWYgUGVyZm9tcyBhbiBoaXN0b2dyYW0gdHJhbnNmb3JtYXRpb24gb24gYSA4LCAyNCBvciAzMi1iaXQgaW1hZ2UgCmFjY29yZGluZyB0byB0aGUgdmFsdWVzIG9mIGEgbG9va3VwIHRhYmxlIChMVVQpLgoKVGhlIHRyYW5zZm9ybWF0aW9uIGlzIGRvbmUgYXMgZm9sbG93cy48YnI+CkltYWdlIDgtYml0IDogaWYgdGhlIGltYWdlIGhhcyBhIGNvbG9yIHBhbGV0dGUsIHRoZSBMVVQgaXMgYXBwbGllZCB0byB0aGlzIHBhbGV0dGUsIApvdGhlcndpc2UsIGl0IGlzIGFwcGxpZWQgdG8gdGhlIGdyZXkgdmFsdWVzLjxicj4KSW1hZ2UgMjQtYml0ICYgMzItYml0IDogaWYgY2hhbm5lbCA9PSBGSUNDX1JHQiwgdGhlIHNhbWUgTFVUIGlzIGFwcGxpZWQgdG8gZWFjaCBjb2xvcgpwbGFuZSAoUixHLCBhbmQgQikuIE90aGVyd2lzZSwgdGhlIExVVCBpcyBhcHBsaWVkIHRvIHRoZSBzcGVjaWZpZWQgY2hhbm5lbCBvbmx5LgpAcGFyYW0gc3JjIElucHV0IGltYWdlIHRvIGJlIHByb2Nlc3NlZC4KQHBhcmFtIExVVCBMb29rdXAgdGFibGUuIDxiPlRoZSBzaXplIG9mICdMVVQnIGlzIGFzc3VtZWQgdG8gYmUgMjU2LjwvYj4KQHBhcmFtIGNoYW5uZWwgVGhlIGNvbG9yIGNoYW5uZWwgdG8gYmUgcHJvY2Vzc2VkIChvbmx5IHVzZWQgd2l0aCAyNCAmIDMyLWJpdCBESUIpLgpAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuCkBzZWUgRlJFRV9JTUFHRV9DT0xPUl9DSEFOTkVMCiovCkJPT0wgRExMX0NBTExDT05WIApGcmVlSW1hZ2VfQWRqdXN0Q3VydmUoRklCSVRNQVAgKnNyYywgQllURSAqTFVULCBGUkVFX0lNQUdFX0NPTE9SX0NIQU5ORUwgY2hhbm5lbCkgewoJdW5zaWduZWQgeCwgeTsKCUJZVEUgKmJpdHMgPSBOVUxMOwoKCWlmKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKHNyYykgfHwgIUxVVCB8fCAoRnJlZUltYWdlX0dldEltYWdlVHlwZShzcmMpICE9IEZJVF9CSVRNQVApKQoJCXJldHVybiBGQUxTRTsKCglpbnQgYnBwID0gRnJlZUltYWdlX0dldEJQUChzcmMpOwoJaWYoKGJwcCAhPSA4KSAmJiAoYnBwICE9IDI0KSAmJiAoYnBwICE9IDMyKSkKCQlyZXR1cm4gRkFMU0U7CgoJLy8gYXBwbHkgdGhlIExVVAoJc3dpdGNoKGJwcCkgewoKCQljYXNlIDggOgoJCXsKCQkJLy8gaWYgdGhlIGRpYiBoYXMgYSBjb2xvcm1hcCwgYXBwbHkgdGhlIExVVCB0byBpdAoJCQkvLyBlbHNlLCBhcHBseSB0aGUgTFVUIHRvIHBpeGVsIHZhbHVlcwoKCQkJaWYoRnJlZUltYWdlX0dldENvbG9yVHlwZShzcmMpID09IEZJQ19QQUxFVFRFKSB7CgkJCQlSR0JRVUFEICpyZ2IgPSBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShzcmMpOwoJCQkJZm9yICh1bnNpZ25lZCBwYWwgPSAwOyBwYWwgPCBGcmVlSW1hZ2VfR2V0Q29sb3JzVXNlZChzcmMpOyBwYWwrKykgewoJCQkJCXJnYi0+cmdiUmVkICAgPSBMVVRbcmdiLT5yZ2JSZWRdOwoJCQkJCXJnYi0+cmdiR3JlZW4gPSBMVVRbcmdiLT5yZ2JHcmVlbl07CgkJCQkJcmdiLT5yZ2JCbHVlICA9IExVVFtyZ2ItPnJnYkJsdWVdOwoJCQkJCXJnYisrOwoJCQkJfQoJCQl9CgkJCWVsc2UgewoJCQkJZm9yKHkgPSAwOyB5IDwgRnJlZUltYWdlX0dldEhlaWdodChzcmMpOyB5KyspIHsKCQkJCQliaXRzID0gIEZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQkJCWZvcih4ID0gMDsgeCA8IEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOyB4KyspIHsKCQkJCQkJYml0c1t4XSA9IExVVFsgYml0c1t4XSBdOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJYnJlYWs7CgkJfQoKCQljYXNlIDI0IDoKCQljYXNlIDMyIDoKCQl7CgkJCWludCBieXRlc3BwID0gRnJlZUltYWdlX0dldExpbmUoc3JjKSAvIEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoKCQkJc3dpdGNoKGNoYW5uZWwpIHsKCQkJCWNhc2UgRklDQ19SR0IgOgoJCQkJCWZvcih5ID0gMDsgeSA8IEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjKTsgeSsrKSB7CgkJCQkJCWJpdHMgPSAgRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSk7CgkJCQkJCWZvcih4ID0gMDsgeCA8IEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOyB4KyspIHsKCQkJCQkJCWJpdHNbRklfUkdCQV9CTFVFXQk9IExVVFsgYml0c1tGSV9SR0JBX0JMVUVdIF07CS8vIEIKCQkJCQkJCWJpdHNbRklfUkdCQV9HUkVFTl0gPSBMVVRbIGJpdHNbRklfUkdCQV9HUkVFTl0gXTsJLy8gRwoJCQkJCQkJYml0c1tGSV9SR0JBX1JFRF0JPSBMVVRbIGJpdHNbRklfUkdCQV9SRURdIF07CQkvLyBSCgkJCQkJCQkKCQkJCQkJCWJpdHMgKz0gYnl0ZXNwcDsKCQkJCQkJfQoJCQkJCX0KCQkJCQlicmVhazsKCgkJCQljYXNlIEZJQ0NfQkxVRSA6CgkJCQkJZm9yKHkgPSAwOyB5IDwgRnJlZUltYWdlX0dldEhlaWdodChzcmMpOyB5KyspIHsKCQkJCQkJYml0cyA9ICBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJCQkJZm9yKHggPSAwOyB4IDwgRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7IHgrKykgewoJCQkJCQkJYml0c1tGSV9SR0JBX0JMVUVdID0gTFVUWyBiaXRzW0ZJX1JHQkFfQkxVRV0gXTsJCS8vIEIKCQkJCQkJCQoJCQkJCQkJYml0cyArPSBieXRlc3BwOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWJyZWFrOwoKCQkJCWNhc2UgRklDQ19HUkVFTiA6CgkJCQkJZm9yKHkgPSAwOyB5IDwgRnJlZUltYWdlX0dldEhlaWdodChzcmMpOyB5KyspIHsKCQkJCQkJYml0cyA9ICBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJCQkJZm9yKHggPSAwOyB4IDwgRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7IHgrKykgewoJCQkJCQkJYml0c1tGSV9SR0JBX0dSRUVOXSA9IExVVFsgYml0c1tGSV9SR0JBX0dSRUVOXSBdOwkvLyBHCgkJCQkJCQkKCQkJCQkJCWJpdHMgKz0gYnl0ZXNwcDsKCQkJCQkJfQoJCQkJCX0KCQkJCQlicmVhazsKCgkJCQljYXNlIEZJQ0NfUkVEIDoKCQkJCQlmb3IoeSA9IDA7IHkgPCBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYyk7IHkrKykgewoJCQkJCQliaXRzID0gIEZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQkJCQlmb3IoeCA9IDA7IHggPCBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsgeCsrKSB7CgkJCQkJCQliaXRzW0ZJX1JHQkFfUkVEXSA9IExVVFsgYml0c1tGSV9SR0JBX1JFRF0gXTsJCS8vIFIKCQkJCQkJCQoJCQkJCQkJYml0cyArPSBieXRlc3BwOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJCQoJCQkJY2FzZSBGSUNDX0FMUEhBIDoKCQkJCQlpZigzMiA9PSBicHApIHsKCQkJCQkJZm9yKHkgPSAwOyB5IDwgRnJlZUltYWdlX0dldEhlaWdodChzcmMpOyB5KyspIHsKCQkJCQkJCWJpdHMgPSAgRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSk7CgkJCQkJCQlmb3IoeCA9IDA7IHggPCBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsgeCsrKSB7CgkJCQkJCQkJYml0c1tGSV9SR0JBX0FMUEhBXSA9IExVVFsgYml0c1tGSV9SR0JBX0FMUEhBXSBdOwkvLyBBCgkJCQkJCQkJCgkJCQkJCQkJYml0cyArPSBieXRlc3BwOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJCWJyZWFrOwoKCQkJCWRlZmF1bHQ6CgkJCQkJYnJlYWs7CgkJCX0KCQkJYnJlYWs7CgkJfQoJfQoKCXJldHVybiBUUlVFOwp9CgovKiogQGJyaWVmIFBlcmZvcm1zIGdhbW1hIGNvcnJlY3Rpb24gb24gYSA4LCAyNCBvciAzMi1iaXQgaW1hZ2UuCgpAcGFyYW0gc3JjIElucHV0IGltYWdlIHRvIGJlIHByb2Nlc3NlZC4KQHBhcmFtIGdhbW1hIEdhbW1hIHZhbHVlIHRvIHVzZS4gQSB2YWx1ZSBvZiAxLjAgbGVhdmVzIHRoZSBpbWFnZSBhbG9uZSwgCmxlc3MgdGhhbiBvbmUgZGFya2VucyBpdCwgYW5kIGdyZWF0ZXIgdGhhbiBvbmUgbGlnaHRlbnMgaXQuCkByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4KKi8KQk9PTCBETExfQ0FMTENPTlYgCkZyZWVJbWFnZV9BZGp1c3RHYW1tYShGSUJJVE1BUCAqc3JjLCBkb3VibGUgZ2FtbWEpIHsKCUJZVEUgTFVUWzI1Nl07CQkvLyBMb29rdXAgdGFibGUKCglpZighRnJlZUltYWdlX0hhc1BpeGVscyhzcmMpIHx8IChnYW1tYSA8PSAwKSkKCQlyZXR1cm4gRkFMU0U7CgkKCS8vIEJ1aWxkIHRoZSBsb29rdXAgdGFibGUKCglkb3VibGUgZXhwb25lbnQgPSAxIC8gZ2FtbWE7Cglkb3VibGUgdiA9IDI1NS4wICogKGRvdWJsZSlwb3coKGRvdWJsZSkyNTUsIC1leHBvbmVudCk7Cglmb3IoaW50IGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKCQlkb3VibGUgY29sb3IgPSAoZG91YmxlKXBvdygoZG91YmxlKWksIGV4cG9uZW50KSAqIHY7CgkJaWYoY29sb3IgPiAyNTUpCgkJCWNvbG9yID0gMjU1OwoJCUxVVFtpXSA9IChCWVRFKWZsb29yKGNvbG9yICsgMC41KTsKCX0KCgkvLyBBcHBseSB0aGUgZ2FtbWEgY29ycmVjdGlvbgoJcmV0dXJuIEZyZWVJbWFnZV9BZGp1c3RDdXJ2ZShzcmMsIExVVCwgRklDQ19SR0IpOwp9CgovKiogQGJyaWVmIEFkanVzdHMgdGhlIGJyaWdodG5lc3Mgb2YgYSA4LCAyNCBvciAzMi1iaXQgaW1hZ2UgYnkgYSBjZXJ0YWluIGFtb3VudC4KCkBwYXJhbSBzcmMgSW5wdXQgaW1hZ2UgdG8gYmUgcHJvY2Vzc2VkLgpAcGFyYW0gcGVyY2VudGFnZSBXaGVyZSAtMTAwIDw9IHBlcmNlbnRhZ2UgPD0gMTAwPGJyPgpBIHZhbHVlIDAgbWVhbnMgbm8gY2hhbmdlLCBsZXNzIHRoYW4gMCB3aWxsIG1ha2UgdGhlIGltYWdlIGRhcmtlciAKYW5kIGdyZWF0ZXIgdGhhbiAwIHdpbGwgbWFrZSB0aGUgaW1hZ2UgYnJpZ2h0ZXIuCkByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZS4KKi8KQk9PTCBETExfQ0FMTENPTlYgCkZyZWVJbWFnZV9BZGp1c3RCcmlnaHRuZXNzKEZJQklUTUFQICpzcmMsIGRvdWJsZSBwZXJjZW50YWdlKSB7CglCWVRFIExVVFsyNTZdOwkJLy8gTG9va3VwIHRhYmxlCglkb3VibGUgdmFsdWU7CgoJaWYoIUZyZWVJbWFnZV9IYXNQaXhlbHMoc3JjKSkKCQlyZXR1cm4gRkFMU0U7CgkKCS8vIEJ1aWxkIHRoZSBsb29rdXAgdGFibGUKCWNvbnN0IGRvdWJsZSBzY2FsZSA9ICgxMDAgKyBwZXJjZW50YWdlKSAvIDEwMDsKCWZvcihpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgewoJCXZhbHVlID0gaSAqIHNjYWxlOwoJCXZhbHVlID0gTUFYKDAuMCwgTUlOKHZhbHVlLCAyNTUuMCkpOwoJCUxVVFtpXSA9IChCWVRFKWZsb29yKHZhbHVlICsgMC41KTsKCX0KCXJldHVybiBGcmVlSW1hZ2VfQWRqdXN0Q3VydmUoc3JjLCBMVVQsIEZJQ0NfUkdCKTsKfQoKLyoqIEBicmllZiBBZGp1c3RzIHRoZSBjb250cmFzdCBvZiBhIDgsIDI0IG9yIDMyLWJpdCBpbWFnZSBieSBhIGNlcnRhaW4gYW1vdW50LgoKQHBhcmFtIHNyYyBJbnB1dCBpbWFnZSB0byBiZSBwcm9jZXNzZWQuCkBwYXJhbSBwZXJjZW50YWdlIFdoZXJlIC0xMDAgPD0gcGVyY2VudGFnZSA8PSAxMDA8YnI+CkEgdmFsdWUgMCBtZWFucyBubyBjaGFuZ2UsIGxlc3MgdGhhbiAwIHdpbGwgZGVjcmVhc2UgdGhlIGNvbnRyYXN0IAphbmQgZ3JlYXRlciB0aGFuIDAgd2lsbCBpbmNyZWFzZSB0aGUgY29udHJhc3Qgb2YgdGhlIGltYWdlLgpAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuCiovCkJPT0wgRExMX0NBTExDT05WIApGcmVlSW1hZ2VfQWRqdXN0Q29udHJhc3QoRklCSVRNQVAgKnNyYywgZG91YmxlIHBlcmNlbnRhZ2UpIHsKCUJZVEUgTFVUWzI1Nl07CQkvLyBMb29rdXAgdGFibGUKCWRvdWJsZSB2YWx1ZTsKCglpZighRnJlZUltYWdlX0hhc1BpeGVscyhzcmMpKQoJCXJldHVybiBGQUxTRTsKCQoJLy8gQnVpbGQgdGhlIGxvb2t1cCB0YWJsZQoJY29uc3QgZG91YmxlIHNjYWxlID0gKDEwMCArIHBlcmNlbnRhZ2UpIC8gMTAwOwoJZm9yKGludCBpID0gMDsgaSA8IDI1NjsgaSsrKSB7CgkJdmFsdWUgPSAxMjggKyAoaSAtIDEyOCkgKiBzY2FsZTsKCQl2YWx1ZSA9IE1BWCgwLjAsIE1JTih2YWx1ZSwgMjU1LjApKTsKCQlMVVRbaV0gPSAoQllURSlmbG9vcih2YWx1ZSArIDAuNSk7Cgl9CglyZXR1cm4gRnJlZUltYWdlX0FkanVzdEN1cnZlKHNyYywgTFVULCBGSUNDX1JHQik7Cn0KCi8qKiBAYnJpZWYgQ29tcHV0ZXMgaW1hZ2UgaGlzdG9ncmFtCgpGb3IgMjQtYml0IGFuZCAzMi1iaXQgaW1hZ2VzLCBoaXN0b2dyYW0gY2FuIGJlIGNvbXB1dGVkIGZyb20gcmVkLCBncmVlbiwgYmx1ZSBhbmQgCmJsYWNrIGNoYW5uZWxzLiBGb3IgOC1iaXQgaW1hZ2VzLCBoaXN0b2dyYW0gaXMgY29tcHV0ZWQgZnJvbSB0aGUgYmxhY2sgY2hhbm5lbC4gT3RoZXIgCmJpdCBkZXB0aCBpcyBub3Qgc3VwcG9ydGVkIChub3RoaW5nIGlzIGRvbmUpLgpAcGFyYW0gc3JjIElucHV0IGltYWdlIHRvIGJlIHByb2Nlc3NlZC4KQHBhcmFtIGhpc3RvIEhpc3RvZ3JhbSBhcnJheSB0byBmaWxsLiA8Yj5UaGUgc2l6ZSBvZiAnaGlzdG8nIGlzIGFzc3VtZWQgdG8gYmUgMjU2LjwvYj4KQHBhcmFtIGNoYW5uZWwgQ29sb3IgY2hhbm5lbCB0byB1c2UKQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2VzZnVsLCByZXR1cm5zIEZBTFNFIGlmIHRoZSBpbWFnZSBiaXQgZGVwdGggaXNuJ3Qgc3VwcG9ydGVkLgoqLwpCT09MIERMTF9DQUxMQ09OViAKRnJlZUltYWdlX0dldEhpc3RvZ3JhbShGSUJJVE1BUCAqc3JjLCBEV09SRCAqaGlzdG8sIEZSRUVfSU1BR0VfQ09MT1JfQ0hBTk5FTCBjaGFubmVsKSB7CglCWVRFIHBpeGVsOwoJQllURSAqYml0cyA9IE5VTEw7Cgl1bnNpZ25lZCB4LCB5OwoKCWlmKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKHNyYykgfHwgIWhpc3RvKSByZXR1cm4gRkFMU0U7CgoJdW5zaWduZWQgd2lkdGggID0gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7Cgl1bnNpZ25lZCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYyk7Cgl1bnNpZ25lZCBicHAgICAgPSBGcmVlSW1hZ2VfR2V0QlBQKHNyYyk7CgoJaWYoYnBwID09IDgpIHsKCQkvLyBjbGVhciBoaXN0b2dyYW0gYXJyYXkKCQltZW1zZXQoaGlzdG8sIDAsIDI1NiAqIHNpemVvZihEV09SRCkpOwoJCS8vIGNvbXB1dGUgaGlzdG9ncmFtIGZvciBibGFjayBjaGFubmVsCgkJZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQlmb3IoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkvLyBnZXQgcGl4ZWwgdmFsdWUKCQkJCXBpeGVsID0gYml0c1t4XTsKCQkJCWhpc3RvW3BpeGVsXSsrOwoJCQl9CgkJfQoJCXJldHVybiBUUlVFOwoJfQoJZWxzZSBpZigoYnBwID09IDI0KSB8fCAoYnBwID09IDMyKSkgewoJCWludCBieXRlc3BwID0gYnBwIC8gODsJLy8gYnl0ZXMgLyBwaXhlbAoKCQkvLyBjbGVhciBoaXN0b2dyYW0gYXJyYXkKCQltZW1zZXQoaGlzdG8sIDAsIDI1NiAqIHNpemVvZihEV09SRCkpOwoKCQlzd2l0Y2goY2hhbm5lbCkgewoJCQljYXNlIEZJQ0NfUkVEOgoJCQkJLy8gY29tcHV0ZSBoaXN0b2dyYW0gZm9yIHJlZCBjaGFubmVsCgkJCQlmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCWJpdHMgPSAgRnJlZUltYWdlX0dldFNjYW5MaW5lKHNyYywgeSk7CgkJCQkJZm9yKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCQlwaXhlbCA9IGJpdHNbRklfUkdCQV9SRURdOwkvLyBSCgkJCQkJCWhpc3RvW3BpeGVsXSsrOwoJCQkJCQliaXRzICs9IGJ5dGVzcHA7CgkJCQkJfQoJCQkJfQoJCQkJcmV0dXJuIFRSVUU7CgoJCQljYXNlIEZJQ0NfR1JFRU46CgkJCQkvLyBjb21wdXRlIGhpc3RvZ3JhbSBmb3IgZ3JlZW4gY2hhbm5lbAoJCQkJZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQliaXRzID0gIEZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQkJCWZvcih4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJcGl4ZWwgPSBiaXRzW0ZJX1JHQkFfR1JFRU5dOwkvLyBHCgkJCQkJCWhpc3RvW3BpeGVsXSsrOwoJCQkJCQliaXRzICs9IGJ5dGVzcHA7CgkJCQkJfQoJCQkJfQoJCQkJcmV0dXJuIFRSVUU7CgoJCQljYXNlIEZJQ0NfQkxVRToKCQkJCS8vIGNvbXB1dGUgaGlzdG9ncmFtIGZvciBibHVlIGNoYW5uZWwKCQkJCWZvcih5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkJYml0cyA9ICBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoc3JjLCB5KTsKCQkJCQlmb3IoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCXBpeGVsID0gYml0c1tGSV9SR0JBX0JMVUVdOwkvLyBCCgkJCQkJCWhpc3RvW3BpeGVsXSsrOwoJCQkJCQliaXRzICs9IGJ5dGVzcHA7CgkJCQkJfQoJCQkJfQoJCQkJcmV0dXJuIFRSVUU7CgoJCQljYXNlIEZJQ0NfQkxBQ0s6CgkJCWNhc2UgRklDQ19SR0I6CgkJCQkvLyBjb21wdXRlIGhpc3RvZ3JhbSBmb3IgYmxhY2sgY2hhbm5lbAoJCQkJZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQliaXRzID0gIEZyZWVJbWFnZV9HZXRTY2FuTGluZShzcmMsIHkpOwoJCQkJCWZvcih4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJLy8gUkdCIHRvIEdSRVkgY29udmVyc2lvbgoJCQkJCQlwaXhlbCA9IEdSRVkoYml0c1tGSV9SR0JBX1JFRF0sIGJpdHNbRklfUkdCQV9HUkVFTl0sIGJpdHNbRklfUkdCQV9CTFVFXSk7CgkJCQkJCWhpc3RvW3BpeGVsXSsrOwoJCQkJCQliaXRzICs9IGJ5dGVzcHA7CgkJCQkJfQoJCQkJfQoJCQkJcmV0dXJuIFRSVUU7CgkJCQkKCQkJZGVmYXVsdDoKCQkJCXJldHVybiBGQUxTRTsKCQl9Cgl9CgoJcmV0dXJuIEZBTFNFOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoKLyoqIEBicmllZiBDcmVhdGVzIGEgbG9va3VwIHRhYmxlIHRvIGJlIHVzZWQgd2l0aCBGcmVlSW1hZ2VfQWRqdXN0Q3VydmUoKSB3aGljaAogbWF5IGFkanVzdCBicmlnaHRuZXNzIGFuZCBjb250cmFzdCwgY29ycmVjdCBnYW1tYSBhbmQgaW52ZXJ0IHRoZSBpbWFnZSB3aXRoIGEKIHNpbmdsZSBjYWxsIHRvIEZyZWVJbWFnZV9BZGp1c3RDdXJ2ZSgpLgogCiBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgYSBsb29rdXAgdGFibGUgdG8gYmUgdXNlZCB3aXRoIEZyZWVJbWFnZV9BZGp1c3RDdXJ2ZSgpCiB3aGljaCBtYXkgYWRqdXN0IGJyaWdodG5lc3MgYW5kIGNvbnRyYXN0LCBjb3JyZWN0IGdhbW1hIGFuZCBpbnZlcnQgdGhlIGltYWdlCiB3aXRoIGEgc2luZ2xlIGNhbGwgdG8gRnJlZUltYWdlX0FkanVzdEN1cnZlKCkuIElmIG1vcmUgdGhhbiBvbmUgb2YgdGhlc2UgaW1hZ2UKIGRpc3BsYXkgcHJvcGVydGllcyBuZWVkIHRvIGJlIGFkanVzdGVkLCB1c2luZyBhIGNvbWJpbmVkIGxvb2t1cCB0YWJsZSBzaG91bGQgYmUKIHByZWZlcnJlZCBvdmVyIGNhbGxpbmcgZWFjaCBhZGp1c3RtZW50IGZ1bmN0aW9uIHNlcGFyYXRlbHkuIFRoYXQncyBwYXJ0aWN1bGFybHkKIHRydWUgZm9yIGh1Z2UgaW1hZ2VzIG9yIGlmIHBlcmZvcm1hbmNlIGlzIGFuIGlzc3VlLiBUaGVuLCB0aGUgZXhwZW5zaXZlIHByb2Nlc3MKIG9mIGl0ZXJhdGluZyBvdmVyIGFsbCBwaXhlbHMgb2YgYW4gaW1hZ2UgaXMgcGVyZm9ybWVkIG9ubHkgb25jZSBhbmQgbm90IHVwIHRvCiBmb3VyIHRpbWVzLgogCiBGdXJ0aGVybW9yZSwgdGhlIGxvb2t1cCB0YWJsZSBjcmVhdGVkIGRvZXMgbm90IGRlcGVuZCBvbiB0aGUgb3JkZXIsIGluIHdoaWNoCiBlYWNoIHNpbmdsZSBhZGp1c3RtZW50IG9wZXJhdGlvbiBpcyBwZXJmb3JtZWQuIER1ZSB0byByb3VuZGluZyBhbmQgYnl0ZSBjYXN0aW5nCiBpc3N1ZXMsIGl0IGFjdHVhbGx5IG1hdHRlcnMgaW4gd2hpY2ggb3JkZXIgaW5kaXZpZHVhbCBhZGp1c3RtZW50IG9wZXJhdGlvbnMKIGFyZSBwZXJmb3JtZWQuIEJvdGggb2YgdGhlIGZvbGxvd2luZyBzbmlwcGV0cyBtb3N0IGxpa2VseSBwcm9kdWNlIGRpZmZlcmVudAogcmVzdWx0czoKIAogLy8gc25pcHBldCAxOiBjb250cmFzdCwgYnJpZ2h0bmVzcwogRnJlZUltYWdlX0FkanVzdENvbnRyYXN0KGRpYiwgMTUuMCk7CiBGcmVlSW1hZ2VfQWRqdXN0QnJpZ2h0bmVzcyhkaWIsIDUwLjApOyAKIAogLy8gc25pcHBldCAyOiBicmlnaHRuZXNzLCBjb250cmFzdAogRnJlZUltYWdlX0FkanVzdEJyaWdodG5lc3MoZGliLCA1MC4wKTsKIEZyZWVJbWFnZV9BZGp1c3RDb250cmFzdChkaWIsIDE1LjApOwogCiBCZXR0ZXIgYW5kIGV2ZW4gZmFzdGVyIHdvdWxkIGJlIHNuaXBwZXQgMzoKIAogLy8gc25pcHBldCAzOgogQllURSBMVVRbMjU2XTsKIEZyZWVJbWFnZV9HZXRBZGp1c3RDb2xvcnNMb29rdXBUYWJsZShMVVQsIDUwLjAsIDE1LjAsIDEuMCwgRkFMU0UpOyAKIEZyZWVJbWFnZV9BZGp1c3RDdXJ2ZShkaWIsIExVVCwgRklDQ19SR0IpOwogCiBUaGlzIGZ1bmN0aW9uIGlzIGFsc28gdXNlZCBpbnRlcm5hbGx5IGJ5IEZyZWVJbWFnZV9BZGp1c3RDb2xvcnMoKSwgd2hpY2ggZG9lcwogbm90IHJldHVybiB0aGUgbG9va3VwIHRhYmxlLCBidXQgdXNlcyBpdCB0byBjYWxsIEZyZWVJbWFnZV9BZGp1c3RDdXJ2ZSgpIG9uIHRoZQogcGFzc2VkIGltYWdlLgogCiBAcGFyYW0gTFVUIE91dHB1dCBsb29rdXAgdGFibGUgdG8gYmUgdXNlZCB3aXRoIEZyZWVJbWFnZV9BZGp1c3RDdXJ2ZSgpLiA8Yj5UaGUKIHNpemUgb2YgJ0xVVCcgaXMgYXNzdW1lZCB0byBiZSAyNTYuPC9iPgogQHBhcmFtIGJyaWdodG5lc3MgUGVyY2VudGFnZSBicmlnaHRuZXNzIHZhbHVlIHdoZXJlIC0xMDAgPD0gYnJpZ2h0bmVzcyA8PSAxMDA8YnI+CiBBIHZhbHVlIG9mIDAgbWVhbnMgbm8gY2hhbmdlLCBsZXNzIHRoYW4gMCB3aWxsIG1ha2UgdGhlIGltYWdlIGRhcmtlciBhbmQgZ3JlYXRlcgogdGhhbiAwIHdpbGwgbWFrZSB0aGUgaW1hZ2UgYnJpZ2h0ZXIuCiBAcGFyYW0gY29udHJhc3QgUGVyY2VudGFnZSBjb250cmFzdCB2YWx1ZSB3aGVyZSAtMTAwIDw9IGNvbnRyYXN0IDw9IDEwMDxicj4KIEEgdmFsdWUgb2YgMCBtZWFucyBubyBjaGFuZ2UsIGxlc3MgdGhhbiAwIHdpbGwgZGVjcmVhc2UgdGhlIGNvbnRyYXN0CiBhbmQgZ3JlYXRlciB0aGFuIDAgd2lsbCBpbmNyZWFzZSB0aGUgY29udHJhc3Qgb2YgdGhlIGltYWdlLgogQHBhcmFtIGdhbW1hIEdhbW1hIHZhbHVlIHRvIGJlIHVzZWQgZm9yIGdhbW1hIGNvcnJlY3Rpb24uIEEgdmFsdWUgb2YgMS4wIGxlYXZlcwogdGhlIGltYWdlIGFsb25lLCBsZXNzIHRoYW4gb25lIGRhcmtlbnMgaXQsIGFuZCBncmVhdGVyIHRoYW4gb25lIGxpZ2h0ZW5zIGl0LgogVGhpcyBwYXJhbWV0ZXIgbXVzdCBub3QgYmUgemVybyBvciBzbWFsbGVyIHRoYW4gemVyby4gSWYgc28sIGl0IHdpbGwgYmUgaWdub3JlZAogYW5kIG5vIGdhbW1hIGNvcnJlY3Rpb24gd2lsbCBiZSBwZXJmb3JtZWQgdXNpbmcgdGhlIGxvb2t1cCB0YWJsZSBjcmVhdGVkLgogQHBhcmFtIGludmVydCBJZiBzZXQgdG8gVFJVRSwgdGhlIGltYWdlIHdpbGwgYmUgaW52ZXJ0ZWQuCiBAcmV0dXJuIFJldHVybnMgdGhlIG51bWJlciBvZiBhZGp1c3RtZW50cyBhcHBsaWVkIHRvIHRoZSByZXN1bHRpbmcgbG9va3VwIHRhYmxlCiBjb21wYXJlZCB0byBhIGJsaW5kIGxvb2t1cCB0YWJsZS4KICovCmludCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldEFkanVzdENvbG9yc0xvb2t1cFRhYmxlKEJZVEUgKkxVVCwgZG91YmxlIGJyaWdodG5lc3MsIGRvdWJsZSBjb250cmFzdCwgZG91YmxlIGdhbW1hLCBCT09MIGludmVydCkgewoJZG91YmxlIGRibExVVFsyNTZdOwoJZG91YmxlIHZhbHVlOwoJaW50IHJlc3VsdCA9IDA7CgoJaWYgKChicmlnaHRuZXNzID09IDAuMCkgJiYgKGNvbnRyYXN0ID09IDAuMCkgJiYgKGdhbW1hID09IDEuMCkgJiYgKCFpbnZlcnQpKSB7CgkJLy8gbm90aGluZyB0byBkbywgaWYgYWxsIGFyZ3VtZW50cyBoYXZlIHRoZWlyIGRlZmF1bHQgdmFsdWVzCgkJLy8gcmV0dXJuIGEgYmxpbmQgTFVUCgkJZm9yIChpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgewoJCQlMVVRbaV0gPSAoQllURSlpOwoJCX0KCQlyZXR1cm4gMDsKCX0KCgkvLyBmaXJzdCwgY3JlYXRlIGEgYmxpbmQgTFVULCB3aGljaCBkb2VzIG5vdGhpbmcgdG8gdGhlIGltYWdlCglmb3IgKGludCBpID0gMDsgaSA8IDI1NjsgaSsrKSB7CgkJZGJsTFVUW2ldID0gaTsKCX0KCglpZiAoY29udHJhc3QgIT0gMC4wKSB7CgkJLy8gbW9kaWZ5IGxvb2t1cCB0YWJsZSB3aXRoIGNvbnRyYXN0IGFkanVzdG1lbnQgZGF0YQoJCWNvbnN0IGRvdWJsZSB2ID0gKDEwMC4wICsgY29udHJhc3QpIC8gMTAwLjA7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgewoJCQl2YWx1ZSA9IDEyOCArIChkYmxMVVRbaV0gLSAxMjgpICogdjsKCQkJZGJsTFVUW2ldID0gTUFYKDAuMCwgTUlOKHZhbHVlLCAyNTUuMCkpOwoJCX0KCQlyZXN1bHQrKzsKCX0KCglpZiAoYnJpZ2h0bmVzcyAhPSAwLjApIHsKCQkvLyBtb2RpZnkgbG9va3VwIHRhYmxlIHdpdGggYnJpZ2h0bmVzcyBhZGp1c3RtZW50IGRhdGEKCQljb25zdCBkb3VibGUgdiA9ICgxMDAuMCArIGJyaWdodG5lc3MpIC8gMTAwLjA7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgewoJCQl2YWx1ZSA9IGRibExVVFtpXSAqIHY7CgkJCWRibExVVFtpXSA9IE1BWCgwLjAsIE1JTih2YWx1ZSwgMjU1LjApKTsKCQl9CgkJcmVzdWx0Kys7Cgl9CgoJaWYgKChnYW1tYSA+IDApICYmIChnYW1tYSAhPSAxLjApKSB7CgkJLy8gbW9kaWZ5IGxvb2t1cCB0YWJsZSB3aXRoIGdhbW1hIGFkanVzdG1lbnQgZGF0YQoJCWRvdWJsZSBleHBvbmVudCA9IDEgLyBnYW1tYTsKCQljb25zdCBkb3VibGUgdiA9IDI1NS4wICogKGRvdWJsZSlwb3coKGRvdWJsZSkyNTUsIC1leHBvbmVudCk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgewoJCQl2YWx1ZSA9IHBvdyhkYmxMVVRbaV0sIGV4cG9uZW50KSAqIHY7CgkJCWRibExVVFtpXSA9IE1BWCgwLjAsIE1JTih2YWx1ZSwgMjU1LjApKTsKCQl9CgkJcmVzdWx0Kys7Cgl9CgoJaWYgKCFpbnZlcnQpIHsKCQlmb3IgKGludCBpID0gMDsgaSA8IDI1NjsgaSsrKSB7CgkJCUxVVFtpXSA9IChCWVRFKWZsb29yKGRibExVVFtpXSArIDAuNSk7CgkJfQoJfSBlbHNlIHsKCQlmb3IgKGludCBpID0gMDsgaSA8IDI1NjsgaSsrKSB7CgkJCUxVVFtpXSA9IDI1NSAtIChCWVRFKWZsb29yKGRibExVVFtpXSArIDAuNSk7CgkJfQoJCXJlc3VsdCsrOwoJfQoJLy8gcmV0dXJuIHRoZSBudW1iZXIgb2YgYWRqdXN0bWVudHMgbWFkZQoJcmV0dXJuIHJlc3VsdDsKfQoKLyoqIEBicmllZiBBZGp1c3RzIGFuIGltYWdlJ3MgYnJpZ2h0bmVzcywgY29udHJhc3QgYW5kIGdhbW1hIGFzIHdlbGwgYXMgaXQgbWF5CiBvcHRpb25hbGx5IGludmVydCB0aGUgaW1hZ2Ugd2l0aGluIGEgc2luZ2xlIG9wZXJhdGlvbi4KIAogVGhpcyBmdW5jdGlvbiBhZGp1c3RzIGFuIGltYWdlJ3MgYnJpZ2h0bmVzcywgY29udHJhc3QgYW5kIGdhbW1hIGFzIHdlbGwgYXMgaXQKIG1heSBvcHRpb25hbGx5IGludmVydCB0aGUgaW1hZ2Ugd2l0aGluIGEgc2luZ2xlIG9wZXJhdGlvbi4gSWYgbW9yZSB0aGFuIG9uZSBvZgogdGhlc2UgaW1hZ2UgZGlzcGxheSBwcm9wZXJ0aWVzIG5lZWQgdG8gYmUgYWRqdXN0ZWQsIHVzaW5nIHRoaXMgZnVuY3Rpb24gc2hvdWxkCiBiZSBwcmVmZXJyZWQgb3ZlciBjYWxsaW5nIGVhY2ggYWRqdXN0bWVudCBmdW5jdGlvbiBzZXBhcmF0ZWx5LiBUaGF0J3MKIHBhcnRpY3VsYXJseSB0cnVlIGZvciBodWdlIGltYWdlcyBvciBpZiBwZXJmb3JtYW5jZSBpcyBhbiBpc3N1ZS4KIAogVGhpcyBmdW5jdGlvbiByZWxpZXMgb24gRnJlZUltYWdlX0dldEFkanVzdENvbG9yc0xvb2t1cFRhYmxlKCksIHdoaWNoIGNyZWF0ZXMgYQogc2luZ2xlIGxvb2t1cCB0YWJsZSwgdGhhdCBjb21iaW5lcyBhbGwgYWRqdXN0bWVudCBvcGVyYXRpb25zIHJlcXVlc3RlZC4KIAogRnVydGhlcm1vcmUsIHRoZSBsb29rdXAgdGFibGUgY3JlYXRlZCBieSBGcmVlSW1hZ2VfR2V0QWRqdXN0Q29sb3JzTG9va3VwVGFibGUoKQogZG9lcyBub3QgZGVwZW5kIG9uIHRoZSBvcmRlciwgaW4gd2hpY2ggZWFjaCBzaW5nbGUgYWRqdXN0bWVudCBvcGVyYXRpb24gaXMKIHBlcmZvcm1lZC4gRHVlIHRvIHJvdW5kaW5nIGFuZCBieXRlIGNhc3RpbmcgaXNzdWVzLCBpdCBhY3R1YWxseSBtYXR0ZXJzIGluIHdoaWNoCiBvcmRlciBpbmRpdmlkdWFsIGFkanVzdG1lbnQgb3BlcmF0aW9ucyBhcmUgcGVyZm9ybWVkLiBCb3RoIG9mIHRoZSBmb2xsb3dpbmcKIHNuaXBwZXRzIG1vc3QgbGlrZWx5IHByb2R1Y2UgZGlmZmVyZW50IHJlc3VsdHM6CiAKIC8vIHNuaXBwZXQgMTogY29udHJhc3QsIGJyaWdodG5lc3MKIEZyZWVJbWFnZV9BZGp1c3RDb250cmFzdChkaWIsIDE1LjApOwogRnJlZUltYWdlX0FkanVzdEJyaWdodG5lc3MoZGliLCA1MC4wKTsgCiAKIC8vIHNuaXBwZXQgMjogYnJpZ2h0bmVzcywgY29udHJhc3QKIEZyZWVJbWFnZV9BZGp1c3RCcmlnaHRuZXNzKGRpYiwgNTAuMCk7CiBGcmVlSW1hZ2VfQWRqdXN0Q29udHJhc3QoZGliLCAxNS4wKTsKIAogQmV0dGVyIGFuZCBldmVuIGZhc3RlciB3b3VsZCBiZSBzbmlwcGV0IDM6CiAKIC8vIHNuaXBwZXQgMzoKIEZyZWVJbWFnZV9BZGp1c3RDb2xvcnMoZGliLCA1MC4wLCAxNS4wLCAxLjAsIEZBTFNFKTsKIAogQHBhcmFtIGRpYiBJbnB1dC9vdXRwdXQgaW1hZ2UgdG8gYmUgcHJvY2Vzc2VkLgogQHBhcmFtIGJyaWdodG5lc3MgUGVyY2VudGFnZSBicmlnaHRuZXNzIHZhbHVlIHdoZXJlIC0xMDAgPD0gYnJpZ2h0bmVzcyA8PSAxMDA8YnI+CiBBIHZhbHVlIG9mIDAgbWVhbnMgbm8gY2hhbmdlLCBsZXNzIHRoYW4gMCB3aWxsIG1ha2UgdGhlIGltYWdlIGRhcmtlciBhbmQgZ3JlYXRlcgogdGhhbiAwIHdpbGwgbWFrZSB0aGUgaW1hZ2UgYnJpZ2h0ZXIuCiBAcGFyYW0gY29udHJhc3QgUGVyY2VudGFnZSBjb250cmFzdCB2YWx1ZSB3aGVyZSAtMTAwIDw9IGNvbnRyYXN0IDw9IDEwMDxicj4KIEEgdmFsdWUgb2YgMCBtZWFucyBubyBjaGFuZ2UsIGxlc3MgdGhhbiAwIHdpbGwgZGVjcmVhc2UgdGhlIGNvbnRyYXN0CiBhbmQgZ3JlYXRlciB0aGFuIDAgd2lsbCBpbmNyZWFzZSB0aGUgY29udHJhc3Qgb2YgdGhlIGltYWdlLgogQHBhcmFtIGdhbW1hIEdhbW1hIHZhbHVlIHRvIGJlIHVzZWQgZm9yIGdhbW1hIGNvcnJlY3Rpb24uIEEgdmFsdWUgb2YgMS4wIGxlYXZlcwogdGhlIGltYWdlIGFsb25lLCBsZXNzIHRoYW4gb25lIGRhcmtlbnMgaXQsIGFuZCBncmVhdGVyIHRoYW4gb25lIGxpZ2h0ZW5zIGl0Ljxicj4KIFRoaXMgcGFyYW1ldGVyIG11c3Qgbm90IGJlIHplcm8gb3Igc21hbGxlciB0aGFuIHplcm8uIElmIHNvLCBpdCB3aWxsIGJlIGlnbm9yZWQKIGFuZCBubyBnYW1tYSBjb3JyZWN0aW9uIHdpbGwgYmUgcGVyZm9ybWVkIG9uIHRoZSBpbWFnZS4KIEBwYXJhbSBpbnZlcnQgSWYgc2V0IHRvIFRSVUUsIHRoZSBpbWFnZSB3aWxsIGJlIGludmVydGVkLgogQHJldHVybiBSZXR1cm5zIFRSVUUgb24gc3VjY2VzcywgRkFMU0Ugb3RoZXJ3aXNlIChlLmcuIHdoZW4gdGhlIGJpdGRlcGggb2YgdGhlCiBzb3VyY2UgZGliIGNhbm5vdCBiZSBoYW5kbGVkKS4KICovCkJPT0wgRExMX0NBTExDT05WCkZyZWVJbWFnZV9BZGp1c3RDb2xvcnMoRklCSVRNQVAgKmRpYiwgZG91YmxlIGJyaWdodG5lc3MsIGRvdWJsZSBjb250cmFzdCwgZG91YmxlIGdhbW1hLCBCT09MIGludmVydCkgewoJQllURSBMVVRbMjU2XTsKCglpZiAoIUZyZWVJbWFnZV9IYXNQaXhlbHMoZGliKSB8fCAoRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpICE9IEZJVF9CSVRNQVApKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCWludCBicHAgPSBGcmVlSW1hZ2VfR2V0QlBQKGRpYik7CglpZiAoKGJwcCAhPSA4KSAmJiAoYnBwICE9IDI0KSAmJiAoYnBwICE9IDMyKSkgewoJCXJldHVybiBGQUxTRTsKCX0KCglpZiAoRnJlZUltYWdlX0dldEFkanVzdENvbG9yc0xvb2t1cFRhYmxlKExVVCwgYnJpZ2h0bmVzcywgY29udHJhc3QsIGdhbW1hLCBpbnZlcnQpKSB7CgkJcmV0dXJuIEZyZWVJbWFnZV9BZGp1c3RDdXJ2ZShkaWIsIExVVCwgRklDQ19SR0IpOwoJfQoJcmV0dXJuIEZBTFNFOwp9CgovKiogQGJyaWVmIEFwcGxpZXMgY29sb3IgbWFwcGluZyBmb3Igb25lIG9yIHNldmVyYWwgY29sb3JzIG9uIGEgMS0sIDQtIG9yIDgtYml0CiBwYWxsZXRpemVkIG9yIGEgMTYtLCAyNC0gb3IgMzItYml0IGhpZ2ggY29sb3IgaW1hZ2UuCgogVGhpcyBmdW5jdGlvbiBtYXBzIHVwIHRvIDxpPmNvdW50PC9pPiBjb2xvcnMgc3BlY2lmaWVkIGluIDxpPnNyY2NvbG9yczwvaT4gdG8KIHRoZXNlIHNwZWNpZmllZCBpbiA8aT5kc3Rjb2xvcnM8L2k+LiBUaGVyZWJ5LCBjb2xvciA8aT5zcmNjb2xvcnNbTl08L2k+LAogaWYgZm91bmQgaW4gdGhlIGltYWdlLCB3aWxsIGJlIHJlcGxhY2VkIGJ5IGNvbG9yIDxpPmRzdGNvbG9yc1tOXTwvaT4uIElmCiBwYXJhbWV0ZXIgPGk+c3dhcDwvaT4gaXMgVFJVRSwgYWRkaXRpb25hbGx5IGFsbCBjb2xvcnMgc3BlY2lmaWVkIGluCiA8aT5kc3Rjb2xvcnM8L2k+IGFyZSBhbHNvIG1hcHBlZCB0byB0aGVzZSBzcGVjaWZpZWQgaW4gPGk+c3JjY29sb3JzPC9pPi4gRm9yCiBoaWdoIGNvbG9yIGltYWdlcywgdGhlIGFjdHVhbCBpbWFnZSBkYXRhIHdpbGwgYmUgbW9kaWZpZWQgd2hlcmVhcywgZm9yCiBwYWxsZXRpemVkIGltYWdlcyBvbmx5IHRoZSBwYWxldHRlIHdpbGwgYmUgY2hhbmdlZC48YnI+CgogVGhlIGZ1bmN0aW9uIHJldHVybnMgdGhlIG51bWJlciBvZiBwaXhlbHMgY2hhbmdlZCBvciB6ZXJvLCBpZiBubyBwaXhlbHMgd2VyZQogY2hhbmdlZC4gCgogQm90aCBhcnJheXMgPGk+c3JjY29sb3JzPC9pPiBhbmQgPGk+ZHN0Y29sb3JzPC9pPiBhcmUgYXNzdW1lZCBub3QgdG8gaG9sZCBsZXNzCiB0aGFuIDxpPmNvdW50PC9pPiBjb2xvcnMuPGJyPgoKIEZvciAxNi1iaXQgaW1hZ2VzLCBhbGwgY29sb3JzIHNwZWNpZmllZCBhcmUgdHJhbnNwYXJlbnRseSBjb252ZXJ0ZWQgdG8gdGhlaXIgCiBwcm9wZXIgMTYtYml0IHJlcHJlc2VudGF0aW9uIChlaXRoZXIgaW4gUkdCNTU1IG9yIFJHQjU2NSBmb3JtYXQsIHdoaWNoIGlzCiBkZXRlcm1pbmVkIGJ5IHRoZSBpbWFnZSdzIHJlZC0gZ3JlZW4tIGFuZCBibHVlLW1hc2spLjxicj4KCiA8Yj5Ob3RlLCB0aGF0IHRoaXMgYmVoYXZpb3VyIGlzIGRpZmZlcmVudCBmcm9tIHdoYXQgRnJlZUltYWdlX0FwcGx5UGFsZXR0ZUluZGV4TWFwcGluZygpCiBkb2VzLCB3aGljaCBtb2RpZmllcyB0aGUgYWN0dWFsIGltYWdlIGRhdGEgb24gcGFsbGV0aXplZCBpbWFnZXMuPC9iPgoKIEBwYXJhbSBkaWIgSW5wdXQvb3V0cHV0IGltYWdlIHRvIGJlIHByb2Nlc3NlZC4KIEBwYXJhbSBzcmNjb2xvcnMgQXJyYXkgb2YgY29sb3JzIHRvIGJlIHVzZWQgYXMgdGhlIG1hcHBpbmcgc291cmNlLgogQHBhcmFtIGRzdGNvbG9ycyBBcnJheSBvZiBjb2xvcnMgdG8gYmUgdXNlZCBhcyB0aGUgbWFwcGluZyBkZXN0aW5hdGlvbi4KIEBwYXJhbSBjb3VudCBUaGUgbnVtYmVyIG9mIGNvbG9ycyB0byBiZSBtYXBwZWQuIFRoaXMgaXMgdGhlIHNpemUgb2YgYm90aAogPGk+c3JjY29sb3JzPC9pPiBhbmQgPGk+ZHN0Y29sb3JzPC9pPi4gIAogQHBhcmFtIGlnbm9yZV9hbHBoYSBJZiBUUlVFLCAzMi1iaXQgaW1hZ2VzIGFuZCBjb2xvcnMgYXJlIHRyZWF0ZWQgYXMgMjQtYml0LgogQHBhcmFtIHN3YXAgSWYgVFJVRSwgc291cmNlIGFuZCBkZXN0aW5hdGlvbiBjb2xvcnMgYXJlIHN3YXBwZWQsIHRoYXQgaXMsCiBlYWNoIGRlc3RpbmF0aW9uIGNvbG9yIGlzIGFsc28gbWFwcGVkIHRvIHRoZSBjb3JyZXNwb25kaW5nIHNvdXJjZSBjb2xvci4gIAogQHJldHVybiBSZXR1cm5zIHRoZSB0b3RhbCBudW1iZXIgb2YgcGl4ZWxzIGNoYW5nZWQuIAogKi8KdW5zaWduZWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9BcHBseUNvbG9yTWFwcGluZyhGSUJJVE1BUCAqZGliLCBSR0JRVUFEICpzcmNjb2xvcnMsIFJHQlFVQUQgKmRzdGNvbG9ycywgdW5zaWduZWQgY291bnQsIEJPT0wgaWdub3JlX2FscGhhLCBCT09MIHN3YXApIHsKCXVuc2lnbmVkIHJlc3VsdCA9IDA7CgoJaWYgKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKGRpYikgfHwgKEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoZGliKSAhPSBGSVRfQklUTUFQKSkgewoJCXJldHVybiAwOwoJfQoKCS8vIHZhbGlkYXRlIHBhcmFtZXRlcnMKCWlmICgoIXNyY2NvbG9ycykgfHwgKCFkc3Rjb2xvcnMpfHwgKGNvdW50IDwgMSkpIHsKCQlyZXR1cm4gMDsKCX0KCglpbnQgYnBwID0gRnJlZUltYWdlX0dldEJQUChkaWIpOwoJc3dpdGNoIChicHApIHsKCQljYXNlIDE6CgkJY2FzZSA0OgoJCWNhc2UgODogewoJCQl1bnNpZ25lZCBzaXplID0gRnJlZUltYWdlX0dldENvbG9yc1VzZWQoZGliKTsKCQkJUkdCUVVBRCAqcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKTsKCQkJUkdCUVVBRCAqYSwgKmI7CgkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCBzaXplOyB4KyspIHsKCQkJCWZvciAodW5zaWduZWQgaiA9IDA7IGogPCBjb3VudDsgaisrKSB7CgkJCQkJYSA9IHNyY2NvbG9yczsKCQkJCQliID0gZHN0Y29sb3JzOwoJCQkJCWZvciAoaW50IGkgPSAoc3dhcCA/IDAgOiAxKTsgaSA8IDI7IGkrKykgewoJCQkJCQlpZiAoKHBhbFt4XS5yZ2JCbHVlID09IGFbal0ucmdiQmx1ZSkmJihwYWxbeF0ucmdiR3JlZW4gPT0gYVtqXS5yZ2JHcmVlbikgJiYocGFsW3hdLnJnYlJlZD09IGFbal0ucmdiUmVkKSkgewoJCQkJCQkJcGFsW3hdLnJnYkJsdWUgPSBiW2pdLnJnYkJsdWU7CgkJCQkJCQlwYWxbeF0ucmdiR3JlZW4gPSBiW2pdLnJnYkdyZWVuOwoJCQkJCQkJcGFsW3hdLnJnYlJlZCA9IGJbal0ucmdiUmVkOwoJCQkJCQkJcmVzdWx0Kys7CgkJCQkJCQlqID0gY291bnQ7CgkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCQlhID0gZHN0Y29sb3JzOwoJCQkJCQliID0gc3JjY29sb3JzOwoJCQkJCX0KCQkJCX0KCQkJfQoJCQlyZXR1cm4gcmVzdWx0OwoJCX0KCQljYXNlIDE2OiB7CgkJCVdPUkQgKnNyYzE2ID0gKFdPUkQgKiltYWxsb2Moc2l6ZW9mKFdPUkQpICogY291bnQpOwoJCQlpZiAoTlVMTCA9PSBzcmMxNikgewoJCQkJcmV0dXJuIDA7CgkJCX0KCgkJCVdPUkQgKmRzdDE2ID0gKFdPUkQgKiltYWxsb2Moc2l6ZW9mKFdPUkQpICogY291bnQpOwoJCQlpZiAoTlVMTCA9PSBkc3QxNikgewoJCQkJZnJlZShzcmMxNik7CgkJCQlyZXR1cm4gMDsKCQkJfQoKCQkJZm9yICh1bnNpZ25lZCBqID0gMDsgaiA8IGNvdW50OyBqKyspIHsKCQkJCXNyYzE2W2pdID0gUkdCUVVBRF9UT19XT1JEKGRpYiwgKHNyY2NvbG9ycyArIGopKTsKCQkJCWRzdDE2W2pdID0gUkdCUVVBRF9UT19XT1JEKGRpYiwgKGRzdGNvbG9ycyArIGopKTsKCQkJfQoKCQkJdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChkaWIpOwoJCQl1bnNpZ25lZCB3aWR0aCA9IEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpOwoJCQlXT1JEICphLCAqYjsKCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQlXT1JEICpiaXRzID0gKFdPUkQgKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB5KTsKCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrLCBiaXRzKyspIHsKCQkJCQlmb3IgKHVuc2lnbmVkIGogPSAwOyBqIDwgY291bnQ7IGorKykgewoJCQkJCQlhID0gc3JjMTY7CgkJCQkJCWIgPSBkc3QxNjsKCQkJCQkJZm9yIChpbnQgaSA9IChzd2FwID8gMCA6IDEpOyBpIDwgMjsgaSsrKSB7CgkJCQkJCQlpZiAoKmJpdHMgPT0gYVtqXSkgewoJCQkJCQkJCSpiaXRzID0gYltqXTsKCQkJCQkJCQlyZXN1bHQrKzsKCQkJCQkJCQlqID0gY291bnQ7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQl9CgkJCQkJCQlhID0gZHN0MTY7CgkJCQkJCQliID0gc3JjMTY7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQkJZnJlZShzcmMxNik7CgkJCWZyZWUoZHN0MTYpOwoJCQlyZXR1cm4gcmVzdWx0OwoJCX0KCQljYXNlIDI0OiB7CgkJCXVuc2lnbmVkIGhlaWdodCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoZGliKTsKCQkJdW5zaWduZWQgd2lkdGggPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsKCQkJUkdCUVVBRCAqYSwgKmI7CgkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJQllURSAqYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHkpOwoJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyssIGJpdHMgKz0gMykgewoJCQkJCWZvciAodW5zaWduZWQgaiA9IDA7IGogPCBjb3VudDsgaisrKSB7CgkJCQkJCWEgPSBzcmNjb2xvcnM7CgkJCQkJCWIgPSBkc3Rjb2xvcnM7CgkJCQkJCWZvciAoaW50IGkgPSAoc3dhcCA/IDAgOiAxKTsgaSA8IDI7IGkrKykgewoJCQkJCQkJaWYgKChiaXRzW0ZJX1JHQkFfQkxVRV0gPT0gYVtqXS5yZ2JCbHVlKSAmJiAoYml0c1tGSV9SR0JBX0dSRUVOXSA9PSBhW2pdLnJnYkdyZWVuKSAmJihiaXRzW0ZJX1JHQkFfUkVEXSA9PSBhW2pdLnJnYlJlZCkpIHsKCQkJCQkJCQliaXRzW0ZJX1JHQkFfQkxVRV0gPSBiW2pdLnJnYkJsdWU7CgkJCQkJCQkJYml0c1tGSV9SR0JBX0dSRUVOXSA9IGJbal0ucmdiR3JlZW47CgkJCQkJCQkJYml0c1tGSV9SR0JBX1JFRF0gPSBiW2pdLnJnYlJlZDsKCQkJCQkJCQlyZXN1bHQrKzsKCQkJCQkJCQlqID0gY291bnQ7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQl9CgkJCQkJCQlhID0gZHN0Y29sb3JzOwoJCQkJCQkJYiA9IHNyY2NvbG9yczsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCQlyZXR1cm4gcmVzdWx0OwoJCX0KCQljYXNlIDMyOiB7CgkJCXVuc2lnbmVkIGhlaWdodCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoZGliKTsKCQkJdW5zaWduZWQgd2lkdGggPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsKCQkJUkdCUVVBRCAqYSwgKmI7CgkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJQllURSAqYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHkpOwoJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyssIGJpdHMgKz0gNCkgewoJCQkJCWZvciAodW5zaWduZWQgaiA9IDA7IGogPCBjb3VudDsgaisrKSB7CgkJCQkJCWEgPSBzcmNjb2xvcnM7CgkJCQkJCWIgPSBkc3Rjb2xvcnM7CgkJCQkJCWZvciAoaW50IGkgPSAoc3dhcCA/IDAgOiAxKTsgaSA8IDI7IGkrKykgewoJCQkJCQkJaWYgKChiaXRzW0ZJX1JHQkFfQkxVRV0gPT0gYVtqXS5yZ2JCbHVlKSAmJihiaXRzW0ZJX1JHQkFfR1JFRU5dID09IGFbal0ucmdiR3JlZW4pICYmKGJpdHNbRklfUkdCQV9SRURdID09IGFbal0ucmdiUmVkKQoJCQkJCQkJCSYmKChpZ25vcmVfYWxwaGEpIHx8IChiaXRzW0ZJX1JHQkFfQUxQSEFdID09IGFbal0ucmdiUmVzZXJ2ZWQpKSkgewoJCQkJCQkJCWJpdHNbRklfUkdCQV9CTFVFXSA9IGJbal0ucmdiQmx1ZTsKCQkJCQkJCQliaXRzW0ZJX1JHQkFfR1JFRU5dID0gYltqXS5yZ2JHcmVlbjsKCQkJCQkJCQliaXRzW0ZJX1JHQkFfUkVEXSA9IGJbal0ucmdiUmVkOwoJCQkJCQkJCWlmICghaWdub3JlX2FscGhhKSB7CgkJCQkJCQkJCWJpdHNbRklfUkdCQV9BTFBIQV0gPSBiW2pdLnJnYlJlc2VydmVkOwoJCQkJCQkJCX0KCQkJCQkJCQlyZXN1bHQrKzsKCQkJCQkJCQlqID0gY291bnQ7CgkJCQkJCQkJYnJlYWs7CgkJCQkJCQl9CgkJCQkJCQlhID0gZHN0Y29sb3JzOwoJCQkJCQkJYiA9IHNyY2NvbG9yczsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCQlyZXR1cm4gcmVzdWx0OwoJCX0KCQlkZWZhdWx0OiB7CgkJCXJldHVybiAwOwoJCX0KCX0KfQoKLyoqIEBicmllZiBTd2FwcyB0d28gc3BlY2lmaWVkIGNvbG9ycyBvbiBhIDEtLCA0LSBvciA4LWJpdCBwYWxsZXRpemVkCiBvciBhIDE2LSwgMjQtIG9yIDMyLWJpdCBoaWdoIGNvbG9yIGltYWdlLgoKIFRoaXMgZnVuY3Rpb24gc3dhcHMgdGhlIHR3byBzcGVjaWZpZWQgY29sb3JzIDxpPmNvbG9yX2E8L2k+IGFuZCA8aT5jb2xvcl9iPC9pPgogb24gYSBwYWxsZXRpemVkIG9yIGhpZ2ggY29sb3IgaW1hZ2UuIEZvciBoaWdoIGNvbG9yIGltYWdlcywgdGhlIGFjdHVhbCBpbWFnZQogZGF0YSB3aWxsIGJlIG1vZGlmaWVkIHdoZXJlYXMsIGZvciBwYWxsZXRpemVkIGltYWdlcyBvbmx5IHRoZSBwYWxldHRlIHdpbGwgYmUKIGNoYW5nZWQuPGJyPgoKIDxiPk5vdGUsIHRoYXQgdGhpcyBiZWhhdmlvdXIgaXMgZGlmZmVyZW50IGZyb20gd2hhdCBGcmVlSW1hZ2VfU3dhcFBhbGV0dGVJbmRpY2VzKCkKIGRvZXMsIHdoaWNoIG1vZGlmaWVzIHRoZSBhY3R1YWwgaW1hZ2UgZGF0YSBvbiBwYWxsZXRpemVkIGltYWdlcy48L2I+PGJyPgoKIFRoaXMgaXMganVzdCBhIHRoaW4gd3JhcHBlciBmb3IgRnJlZUltYWdlX0FwcGx5Q29sb3JNYXBwaW5nKCkgYW5kIHJlc29sdmVzIHRvOjxicj4KIDxpPnJldHVybiBGcmVlSW1hZ2VfQXBwbHlDb2xvck1hcHBpbmcoZGliLCBjb2xvcl9hLCBjb2xvcl9iLCAxLCBpZ25vcmVfYWxwaGEsIFRSVUUpOzwvaT4KCiBAcGFyYW0gZGliIElucHV0L291dHB1dCBpbWFnZSB0byBiZSBwcm9jZXNzZWQuCiBAcGFyYW0gY29sb3JfYSBPbiBvZiB0aGUgdHdvIGNvbG9ycyB0byBiZSBzd2FwcGVkLgogQHBhcmFtIGNvbG9yX2IgVGhlIG90aGVyIG9mIHRoZSB0d28gY29sb3JzIHRvIGJlIHN3YXBwZWQuCiBAcGFyYW0gaWdub3JlX2FscGhhIElmIFRSVUUsIDMyLWJpdCBpbWFnZXMgYW5kIGNvbG9ycyBhcmUgdHJlYXRlZCBhcyAyNC1iaXQuIAogQHJldHVybiBSZXR1cm5zIHRoZSB0b3RhbCBudW1iZXIgb2YgcGl4ZWxzIGNoYW5nZWQuIAogKi8KdW5zaWduZWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9Td2FwQ29sb3JzKEZJQklUTUFQICpkaWIsIFJHQlFVQUQgKmNvbG9yX2EsIFJHQlFVQUQgKmNvbG9yX2IsIEJPT0wgaWdub3JlX2FscGhhKSB7CglyZXR1cm4gRnJlZUltYWdlX0FwcGx5Q29sb3JNYXBwaW5nKGRpYiwgY29sb3JfYSwgY29sb3JfYiwgMSwgaWdub3JlX2FscGhhLCBUUlVFKTsKfQoKLyoqIEBicmllZiBBcHBsaWVzIHBhbGV0dGUgaW5kZXggbWFwcGluZyBmb3Igb25lIG9yIHNldmVyYWwgaW5kaWNlcyBvbiBhIDEtLCA0LSAKIG9yIDgtYml0IHBhbGxldGl6ZWQgaW1hZ2UuCgogVGhpcyBmdW5jdGlvbiBtYXBzIHVwIHRvIDxpPmNvdW50PC9pPiBwYWxldHRlIGluZGljZXMgc3BlY2lmaWVkIGluCiA8aT5zcmNpbmRpY2VzPC9pPiB0byB0aGVzZSBzcGVjaWZpZWQgaW4gPGk+ZHN0aW5kaWNlczwvaT4uIFRoZXJlYnksIGluZGV4IAogPGk+c3JjaW5kaWNlc1tOXTwvaT4sIGlmIHByZXNlbnQgaW4gdGhlIGltYWdlLCB3aWxsIGJlIHJlcGxhY2VkIGJ5IGluZGV4CiA8aT5kc3RpbmRpY2VzW05dPC9pPi4gSWYgcGFyYW1ldGVyIDxpPnN3YXA8L2k+IGlzIFRSVUUsIGFkZGl0aW9uYWxseSBhbGwgaW5kaWNlcwogc3BlY2lmaWVkIGluIDxpPmRzdGluZGljZXM8L2k+IGFyZSBhbHNvIG1hcHBlZCB0byB0aGVzZSBzcGVjaWZpZWQgaW4gCiA8aT5zcmNpbmRpY2VzPC9pPi48YnI+CgogVGhlIGZ1bmN0aW9uIHJldHVybnMgdGhlIG51bWJlciBvZiBwaXhlbHMgY2hhbmdlZCBvciB6ZXJvLCBpZiBubyBwaXhlbHMgd2VyZQogY2hhbmdlZC4gCgogQm90aCBhcnJheXMgPGk+c3JjaW5kaWNlczwvaT4gYW5kIDxpPmRzdGluZGljZXM8L2k+IGFyZSBhc3N1bWVkIG5vdCB0byBob2xkIGxlc3MKIHRoYW4gPGk+Y291bnQ8L2k+IGluZGljZXMuPGJyPgoKIDxiPk5vdGUsIHRoYXQgdGhpcyBiZWhhdmlvdXIgaXMgZGlmZmVyZW50IGZyb20gd2hhdCBGcmVlSW1hZ2VfQXBwbHlDb2xvck1hcHBpbmcoKQogZG9lcywgd2hpY2ggbW9kaWZpZXMgdGhlIGFjdHVhbCBpbWFnZSBkYXRhIG9uIHBhbGxldGl6ZWQgaW1hZ2VzLjwvYj4KCiBAcGFyYW0gZGliIElucHV0L291dHB1dCBpbWFnZSB0byBiZSBwcm9jZXNzZWQuCiBAcGFyYW0gc3JjaW5kaWNlcyBBcnJheSBvZiBwYWxldHRlIGluZGljZXMgdG8gYmUgdXNlZCBhcyB0aGUgbWFwcGluZyBzb3VyY2UuCiBAcGFyYW0gZHN0aW5kaWNlcyBBcnJheSBvZiBwYWxldHRlIGluZGljZXMgdG8gYmUgdXNlZCBhcyB0aGUgbWFwcGluZyBkZXN0aW5hdGlvbi4KIEBwYXJhbSBjb3VudCBUaGUgbnVtYmVyIG9mIHBhbGV0dGUgaW5kaWNlcyB0byBiZSBtYXBwZWQuIFRoaXMgaXMgdGhlIHNpemUgb2YgYm90aAogPGk+c3JjaW5kaWNlczwvaT4gYW5kIDxpPmRzdGluZGljZXM8L2k+LiAgCiBAcGFyYW0gc3dhcCBJZiBUUlVFLCBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIHBhbGV0dGUgaW5kaWNlcyBhcmUgc3dhcHBlZCwgdGhhdCBpcywKIGVhY2ggZGVzdGluYXRpb24gaW5kZXggaXMgYWxzbyBtYXBwZWQgdG8gdGhlIGNvcnJlc3BvbmRpbmcgc291cmNlIGluZGV4LiAgCiBAcmV0dXJuIFJldHVybnMgdGhlIHRvdGFsIG51bWJlciBvZiBwaXhlbHMgY2hhbmdlZC4gCiAqLwp1bnNpZ25lZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0FwcGx5UGFsZXR0ZUluZGV4TWFwcGluZyhGSUJJVE1BUCAqZGliLCBCWVRFICpzcmNpbmRpY2VzLAlCWVRFICpkc3RpbmRpY2VzLCB1bnNpZ25lZCBjb3VudCwgQk9PTCBzd2FwKSB7Cgl1bnNpZ25lZCByZXN1bHQgPSAwOwoKCWlmICghRnJlZUltYWdlX0hhc1BpeGVscyhkaWIpIHx8IChGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRpYikgIT0gRklUX0JJVE1BUCkpIHsKCQlyZXR1cm4gMDsKCX0KCgkvLyB2YWxpZGF0ZSBwYXJhbWV0ZXJzCglpZiAoKCFzcmNpbmRpY2VzKSB8fCAoIWRzdGluZGljZXMpfHwgKGNvdW50IDwgMSkpIHsKCQlyZXR1cm4gMDsKCX0KCgl1bnNpZ25lZCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7Cgl1bnNpZ25lZCB3aWR0aCA9IEZyZWVJbWFnZV9HZXRMaW5lKGRpYik7CglCWVRFICphLCAqYjsKCglpbnQgYnBwID0gRnJlZUltYWdlX0dldEJQUChkaWIpOwoJc3dpdGNoIChicHApIHsKCQljYXNlIDE6IHsKCgkJCXJldHVybiByZXN1bHQ7CgkJfQoJCWNhc2UgNDogewoJCQlpbnQgc2tpcF9sYXN0ID0gKEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpICYgMHgwMSk7CgkJCXVuc2lnbmVkIG1heF94ID0gd2lkdGggLSAxOwoJCQlmb3IgKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCUJZVEUgKmJpdHMgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB5KTsKCQkJCWZvciAodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJaW50IHN0YXJ0ID0gKChza2lwX2xhc3QpICYmICh4ID09IG1heF94KSkgPyAxIDogMDsKCQkJCQlmb3IgKGludCBjbiA9IHN0YXJ0OyBjbiA8IDI7IGNuKyspIHsKCQkJCQkJZm9yICh1bnNpZ25lZCBqID0gMDsgaiA8IGNvdW50OyBqKyspIHsKCQkJCQkJCWEgPSBzcmNpbmRpY2VzOwoJCQkJCQkJYiA9IGRzdGluZGljZXM7CgkJCQkJCQlmb3IgKGludCBpID0gKChzd2FwKSA/IDAgOiAxKTsgaSA8IDI7IGkrKykgewoJCQkJCQkJCWlmIChHRVRfTklCQkxFKGNuLCBiaXRzW3hdKSA9PSAoYVtqXSAmIDB4MEYpKSB7CgkJCQkJCQkJCVNFVF9OSUJCTEUoY24sIGJpdHNbeF0sIGJbal0pOwoJCQkJCQkJCQlyZXN1bHQrKzsKCQkJCQkJCQkJaiA9IGNvdW50OwoJCQkJCQkJCQlicmVhazsKCQkJCQkJCQl9CgkJCQkJCQkJYSA9IGRzdGluZGljZXM7CgkJCQkJCQkJYiA9IHNyY2luZGljZXM7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQkJcmV0dXJuIHJlc3VsdDsKCQl9CgkJY2FzZSA4OiB7CgkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJQllURSAqYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHkpOwoJCQkJZm9yICh1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQlmb3IgKHVuc2lnbmVkIGogPSAwOyBqIDwgY291bnQ7IGorKykgewoJCQkJCQlhID0gc3JjaW5kaWNlczsKCQkJCQkJYiA9IGRzdGluZGljZXM7CgkJCQkJCWZvciAoaW50IGkgPSAoKHN3YXApID8gMCA6IDEpOyBpIDwgMjsgaSsrKSB7CgkJCQkJCQlpZiAoYml0c1t4XSA9PSBhW2pdKSB7CgkJCQkJCQkJYml0c1t4XSA9IGJbal07CgkJCQkJCQkJcmVzdWx0Kys7CgkJCQkJCQkJaiA9IGNvdW50OwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJfQoJCQkJCQkJYSA9IGRzdGluZGljZXM7CgkJCQkJCQliID0gc3JjaW5kaWNlczsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCQlyZXR1cm4gcmVzdWx0OwoJCX0KCQlkZWZhdWx0OiB7CgkJCXJldHVybiAwOwoJCX0KCX0KfQoKLyoqIEBicmllZiBTd2FwcyB0d28gc3BlY2lmaWVkIHBhbGV0dGUgaW5kaWNlcyBvbiBhIDEtLCA0LSBvciA4LWJpdCBwYWxsZXRpemVkCiBpbWFnZS4KCiBUaGlzIGZ1bmN0aW9uIHN3YXBzIHRoZSB0d28gc3BlY2lmaWVkIHBhbGV0dGUgaW5kaWNlcyA8aT5pbmRleF9hPC9pPiBhbmQKIDxpPmluZGV4X2I8L2k+IG9uIGEgcGFsbGV0aXplZCBpbWFnZS4gVGhlcmVmb3JlLCBub3QgdGhlIHBhbGV0dGUsIGJ1dCB0aGUKIGFjdHVhbCBpbWFnZSBkYXRhIHdpbGwgYmUgbW9kaWZpZWQuPGJyPgoKIDxiPk5vdGUsIHRoYXQgdGhpcyBiZWhhdmlvdXIgaXMgZGlmZmVyZW50IGZyb20gd2hhdCBGcmVlSW1hZ2VfU3dhcENvbG9ycygpIGRvZXMKIG9uIHBhbGxldGl6ZWQgaW1hZ2VzLCB3aGljaCBvbmx5IHN3YXBzIHRoZSBjb2xvcnMgaW4gdGhlIHBhbGV0dGUuPC9iPjxicj4KCiBUaGlzIGlzIGp1c3QgYSB0aGluIHdyYXBwZXIgZm9yIEZyZWVJbWFnZV9BcHBseUNvbG9yTWFwcGluZygpIGFuZCByZXNvbHZlcyB0bzo8YnI+CiA8aT5yZXR1cm4gRnJlZUltYWdlX0FwcGx5UGFsZXR0ZUluZGV4TWFwcGluZyhkaWIsIGluZGV4X2EsIGluZGV4X2IsIDEsIFRSVUUpOzwvaT4KCiBAcGFyYW0gZGliIElucHV0L291dHB1dCBpbWFnZSB0byBiZSBwcm9jZXNzZWQuCiBAcGFyYW0gaW5kZXhfYSBPbiBvZiB0aGUgdHdvIHBhbGV0dGUgaW5kaWNlcyB0byBiZSBzd2FwcGVkLgogQHBhcmFtIGluZGV4X2IgVGhlIG90aGVyIG9mIHRoZSB0d28gcGFsZXR0ZSBpbmRpY2VzIHRvIGJlIHN3YXBwZWQuCiBAcmV0dXJuIFJldHVybnMgdGhlIHRvdGFsIG51bWJlciBvZiBwaXhlbHMgY2hhbmdlZC4gCiAqLwp1bnNpZ25lZCBETExfQ0FMTENPTlYgCkZyZWVJbWFnZV9Td2FwUGFsZXR0ZUluZGljZXMoRklCSVRNQVAgKmRpYiwgQllURSAqaW5kZXhfYSwgQllURSAqaW5kZXhfYikgewoJcmV0dXJuIEZyZWVJbWFnZV9BcHBseVBhbGV0dGVJbmRleE1hcHBpbmcoZGliLCBpbmRleF9hLCBpbmRleF9iLCAxLCBUUlVFKTsKfQoK