Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogTVBFRyBBdWRpbyBFbmNvZGVyICoqKioqKioqKioqKioqKioqKioqKioqKioqCgogICBJbml0aWFsIGF1dGhvcjogICAgICAgQWxleCBHcm9lc2NoZWwsIFRvYmlhcyBDaGFsdXBrYQogICBjb250ZW50cy9kZXNjcmlwdGlvbjogVGVtcG9yYWwgbm9pc2Ugc2hhcGluZwoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgImFhY2VuY190bnMuaCIKI2luY2x1ZGUgInBzeV9jb25zdC5oIgojaW5jbHVkZSAicHN5X2NvbmZpZ3VyYXRpb24uaCIKI2luY2x1ZGUgInRuc19mdW5jLmgiCiNpbmNsdWRlICJhYWNFbmNfcm9tLmgiCiNpbmNsdWRlICJhYWNlbmNfdG5zLmgiCgojZGVmaW5lIEZJTFRFUl9ESVJFQ1RJT04gMCAvKiAwID0gdXAsIDEgPSBkb3duICovCgpzdGF0aWMgY29uc3QgRklYUF9EQkwgYWNmV2luZG93TG9uZ1sxMiszKzFdID0gewogIDB4N2ZmZmZmZmYsMHg3ZmI4MDAwMCwweDdlZTAwMDAwLDB4N2Q3ODAwMDAsMHg3YjgwMDAwMCwweDc4ZjgwMDAwLDB4NzVlMDAwMDAsMHg3MjM4MDAwMCwKICAweDZlMDAwMDAwLDB4NjkzODAwMDAsMHg2M2UwMDAwMCwweDVkZjgwMDAwLDB4NTc4MDAwMDAsMHg1MDc4MDAwMCwweDQ4ZTAwMDAwLDB4NDBiODAwMDAKfTsKCnN0YXRpYyBjb25zdCBGSVhQX0RCTCBhY2ZXaW5kb3dTaG9ydFs0KzMrMV0gPSB7CiAgMHg3ZmZmZmZmZiwweDdlMDAwMDAwLDB4NzgwMDAwMDAsMHg2ZTAwMDAwMCwweDYwMDAwMDAwLDB4NGUwMDAwMDAsMHgzODAwMDAwMCwweDFlMDAwMDAwCn07Cgp0eXBlZGVmIHN0cnVjdHsKICBJTlQgICAgICAgICAgICAgICAgICAgICAgYml0UmF0ZUZyb21bMl07ICAvKiBub25lU2JyPTAsIHVzZVNicj0xICovCiAgSU5UICAgICAgICAgICAgICAgICAgICAgIGJpdFJhdGVUb1syXTsgICAgLyogbm9uZVNicj0wLCB1c2VTYnI9MSAqLwogIFROU19QQVJBTUVURVJfVEFCVUxBVEVEICBwYXJhbVRhYlsyXTsgICAgIC8qIG1vbm89MCwgc3RlcmVvPTEgKi8KCn0gVE5TX0lORk9fVEFCOwoKI2RlZmluZSBUTlNfVElNRVJFU19TQ0FMRSAgICAoMSkKI2RlZmluZSBGTDJfVElNRVJFU19GSVgoYSkgICAoIEZMMkZYQ09OU1RfREJMKGEvKGZsb2F0KSgxPDxUTlNfVElNRVJFU19TQ0FMRSkpICkKCnN0YXRpYyBjb25zdCBUTlNfSU5GT19UQUIgdG5zSW5mb1RhYltdID0KewogIHsKICAgIHsgIDE2MDAwLCAgMTM1MDB9LAogICAgeyAgMzIwMDAsICAyODAwMH0sCiAgICB7CiAgICAgIHsgezEsIDF9LCB7MTQzNywgMTUwMH0sIHsxNDAwLCA2MDB9LCB7MTIsIDEyfSwge0ZJTFRFUl9ESVJFQ1RJT04sIEZJTFRFUl9ESVJFQ1RJT059LCB7MywgMX0sIHtGTDJfVElNRVJFU19GSVgoMC40ZiksIEZMMl9USU1FUkVTX0ZJWCgxLjJmKX0sIDEgfSwKICAgICAgeyB7MSwgMX0sIHsxNDM3LCAxNTAwfSwgezE0MDAsIDYwMH0sIHsxMiwgMTJ9LCB7RklMVEVSX0RJUkVDVElPTiwgRklMVEVSX0RJUkVDVElPTn0sIHszLCAxfSwge0ZMMl9USU1FUkVTX0ZJWCgwLjRmKSwgRkwyX1RJTUVSRVNfRklYKDEuMmYpfSwgMSB9CiAgICB9CiAgfSwKICB7CiAgICB7ICAzMjAwMSwgIDI4MDAxfSwKICAgIHsgIDYwMDAwLCAgNTIwMDB9LAogICAgewogICAgICB7IHsxLCAxfSwgezE0MzcsIDE1MDB9LCB7MTQwMCwgNjAwfSwgezEyLCAxMH0sIHtGSUxURVJfRElSRUNUSU9OLCBGSUxURVJfRElSRUNUSU9OfSwgezMsIDF9LCB7RkwyX1RJTUVSRVNfRklYKDAuNGYpLCBGTDJfVElNRVJFU19GSVgoMS4wZil9LCAxIH0sCiAgICAgIHsgezEsIDF9LCB7MTQzNywgMTUwMH0sIHsxNDAwLCA2MDB9LCB7MTIsIDEwfSwge0ZJTFRFUl9ESVJFQ1RJT04sIEZJTFRFUl9ESVJFQ1RJT059LCB7MywgMX0sIHtGTDJfVElNRVJFU19GSVgoMC40ZiksIEZMMl9USU1FUkVTX0ZJWCgxLjBmKX0sIDEgfQogICAgfQogIH0sCiAgewogICAgeyAgNjAwMDEsICA1MjAwMX0sCiAgICB7IDM4NDAwMCwgMzg0MDAwfSwKICAgIHsKICAgICAgeyB7MSwgMX0sIHsxNDM3LCAxNTAwfSwgezE0MDAsIDYwMH0sIHsxMiwgIDh9LCB7RklMVEVSX0RJUkVDVElPTiwgRklMVEVSX0RJUkVDVElPTn0sIHszLCAxfSwge0ZMMl9USU1FUkVTX0ZJWCgwLjRmKSwgRkwyX1RJTUVSRVNfRklYKDEuMGYpfSwgMSB9LAogICAgICB7IHsxLCAxfSwgezE0MzcsIDE1MDB9LCB7MTQwMCwgNjAwfSwgezEyLCAgOH0sIHtGSUxURVJfRElSRUNUSU9OLCBGSUxURVJfRElSRUNUSU9OfSwgezMsIDF9LCB7RkwyX1RJTUVSRVNfRklYKDAuNGYpLCBGTDJfVElNRVJFU19GSVgoMS4wZil9LCAxIH0KICAgIH0KICB9Cn07Cgp0eXBlZGVmIHN0cnVjdCB7CiAgSU5UICAgc2FtcGxpbmdSYXRlOwogIFNDSEFSIG1heEJhbmRzWzJdOyAvKiBsb25nPTA7IHNob3J0PTEgKi8KCn0gVE5TX01BWF9UQUJfRU5UUlk7CgpzdGF0aWMgY29uc3QgVE5TX01BWF9UQUJfRU5UUlkgdG5zTWF4QmFuZHNUYWIxMDI0W10gPQp7CiAgeyA5NjAwMCwgeyAzMSwgIDl9fSwKICB7IDg4MjAwLCB7IDMxLCAgOX19LAogIHsgNjQwMDAsIHsgMzQsIDEwfX0sCiAgeyA0ODAwMCwgeyA0MCwgMTR9fSwKICB7IDQ0MTAwLCB7IDQyLCAxNH19LAogIHsgMzIwMDAsIHsgNTEsIDE0fX0sCiAgeyAyNDAwMCwgeyA0NiwgMTR9fSwKICB7IDIyMDUwLCB7IDQ2LCAxNH19LAogIHsgMTYwMDAsIHsgNDIsIDE0fX0sCiAgeyAxMjAwMCwgeyA0MiwgMTR9fSwKICB7IDExMDI1LCB7IDQyLCAxNH19LAogIHsgODAwMCwgIHsgMzksIDE0fX0KfTsKCnN0YXRpYyBjb25zdCBUTlNfTUFYX1RBQl9FTlRSWSB0bnNNYXhCYW5kc1RhYjQ4MFtdID0KewogIHsgNDgwMDAsIHsgMzEsIC0xfX0sCiAgeyA0NDEwMCwgeyAzMiwgLTF9fSwKICB7IDMyMDAwLCB7IDM3LCAtMX19LAogIHsgMjQwMDAsIHsgMzAsIC0xfX0sCiAgeyAyMjA1MCwgeyAzMCwgLTF9fQp9OwoKc3RhdGljIGNvbnN0IFROU19NQVhfVEFCX0VOVFJZIHRuc01heEJhbmRzVGFiNTEyW10gPQp7CiAgeyA0ODAwMCwgeyAzMSwgLTF9fSwKICB7IDQ0MTAwLCB7IDMyLCAtMX19LAogIHsgMzIwMDAsIHsgMzcsIC0xfX0sCiAgeyAyNDAwMCwgeyAzMSwgLTF9fSwKICB7IDIyMDUwLCB7IDMxLCAtMX19Cn07CgpzdGF0aWMgSU5UIEZES2FhY0VuY19BdXRvVG9QYXJjb3IoCiAgICAgICAgRklYUF9EQkwgKlJFU1RSSUNUIGlucHV0LAogICAgICAgIEZJWFBfREJMICpSRVNUUklDVCByZWZsQ29lZmYsCiAgICAgICAgY29uc3QgSU5UIG51bU9mQ29lZmYKICAgICAgICApOwoKc3RhdGljIHZvaWQgRkRLYWFjRW5jX1BhcmNvcjJJbmRleCgKICAgICAgICBjb25zdCBGSVhQX0RCTCAqcGFyY29yLAogICAgICAgIElOVCAqUkVTVFJJQ1QgaW5kZXgsCiAgICAgICAgY29uc3QgSU5UIG9yZGVyLAogICAgICAgIGNvbnN0IElOVCBiaXRzUGVyQ29lZmYKICAgICAgICApOwoKc3RhdGljIHZvaWQgRkRLYWFjRW5jX0luZGV4MlBhcmNvcigKICAgICAgICBjb25zdCBJTlQgKmluZGV4LAogICAgICAgIEZJWFBfREJMICpSRVNUUklDVCBwYXJjb3IsCiAgICAgICAgY29uc3QgSU5UIG9yZGVyLAogICAgICAgIGNvbnN0IElOVCBiaXRzUGVyQ29lZmYKICAgICAgICApOwoKc3RhdGljIElOVCBGREthYWNFbmNfUGFyY29yVG9McGMoCiAgICAgICAgY29uc3QgRklYUF9EQkwgKnJlZmxDb2VmZiwKICAgICAgICBGSVhQX0RCTCAqUkVTVFJJQ1QgTHBjQ29lZmYsCiAgICAgICAgY29uc3QgSU5UIG51bU9mQ29lZmYsCiAgICAgICAgRklYUF9EQkwgKlJFU1RSSUNUIHdvcmtCdWZmZXIKICAgICAgICApOwoKc3RhdGljIHZvaWQgRkRLYWFjRW5jX0FuYWx5c2lzRmlsdGVyKAogICAgICAgIEZJWFBfREJMICpSRVNUUklDVCBzaWduYWwsCiAgICAgICAgY29uc3QgSU5UIG51bU9mTGluZXMsCiAgICAgICAgY29uc3QgRklYUF9EQkwgKnByZWRpY3RvckNvZWZmLAogICAgICAgIGNvbnN0IElOVCBvcmRlciwKICAgICAgICBjb25zdCBJTlQgbHBjR2FpbkZhY3RvcgogICAgICAgICk7CgpzdGF0aWMgdm9pZCBGREthYWNFbmNfQ2FsY0dhdXNzV2luZG93KAogICAgICAgIEZJWFBfREJMICp3aW4sCiAgICAgICAgY29uc3QgaW50IHdpblNpemUsCiAgICAgICAgY29uc3QgSU5UIHNhbXBsaW5nUmF0ZSwKICAgICAgICBjb25zdCBJTlQgdHJhbnNmb3JtUmVzb2x1dGlvbiwKICAgICAgICBjb25zdCBGSVhQX0RCTCB0aW1lUmVzb2x1dGlvbiwKICAgICAgICBjb25zdCBJTlQgdGltZVJlc29sdXRpb25fZQogICAgICAgICk7CgpzdGF0aWMgY29uc3QgVE5TX1BBUkFNRVRFUl9UQUJVTEFURUQqIEZES2FhY0VuY19HZXRUbnNQYXJhbSgKICAgICAgICBjb25zdCBJTlQgYml0UmF0ZSwKICAgICAgICBjb25zdCBJTlQgY2hhbm5lbHMsCiAgICAgICAgY29uc3QgSU5UIHNickxkCiAgICAgICAgKQp7CiAgaW50IGk7CiAgY29uc3QgVE5TX1BBUkFNRVRFUl9UQUJVTEFURUQgKnRuc0NvbmZpZ1RhYiA9IE5VTEw7CgogIGZvciAoaSA9IDA7IGkgPCAoaW50KSAoc2l6ZW9mKHRuc0luZm9UYWIpL3NpemVvZihUTlNfSU5GT19UQUIpKTsgaSsrKSB7CiAgICBpZiAoKGJpdFJhdGUgPj0gdG5zSW5mb1RhYltpXS5iaXRSYXRlRnJvbVtzYnJMZD8xOjBdKSAmJgogICAgICAgICBiaXRSYXRlIDw9IHRuc0luZm9UYWJbaV0uYml0UmF0ZVRvW3NickxkPzE6MF0pCiAgICB7CiAgICAgIHRuc0NvbmZpZ1RhYiA9ICZ0bnNJbmZvVGFiW2ldLnBhcmFtVGFiWyhjaGFubmVscz09MSk/MDoxXTsKICAgIH0KICB9CgogIHJldHVybiB0bnNDb25maWdUYWI7Cn0KCgpzdGF0aWMgSU5UIGdldFRuc01heEJhbmRzKAogICAgICAgIGNvbnN0IElOVCBzYW1wbGVSYXRlLAogICAgICAgIGNvbnN0IElOVCBncmFudWxlTGVuZ3RoLAogICAgICAgIGNvbnN0IElOVCBpc1Nob3J0QmxvY2sKICAgICAgICApCnsKICBpbnQgaTsKICBJTlQgbnVtQmFuZHMgPSAtMTsKICBjb25zdCBUTlNfTUFYX1RBQl9FTlRSWSAqcE1heEJhbmRzVGFiID0gTlVMTDsKICBpbnQgbWF4QmFuZHNUYWJTaXplID0gMDsKCiAgc3dpdGNoIChncmFudWxlTGVuZ3RoKSB7CiAgICBjYXNlIDEwMjQ6CiAgICAgIHBNYXhCYW5kc1RhYiA9IHRuc01heEJhbmRzVGFiMTAyNDsKICAgICAgbWF4QmFuZHNUYWJTaXplID0gc2l6ZW9mKHRuc01heEJhbmRzVGFiMTAyNCkvc2l6ZW9mKFROU19NQVhfVEFCX0VOVFJZKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIDQ4MDoKICAgICAgcE1heEJhbmRzVGFiID0gdG5zTWF4QmFuZHNUYWI0ODA7CiAgICAgIG1heEJhbmRzVGFiU2l6ZSA9IHNpemVvZih0bnNNYXhCYW5kc1RhYjQ4MCkvc2l6ZW9mKFROU19NQVhfVEFCX0VOVFJZKTsKICAgICAgYnJlYWs7CiAgICBjYXNlIDUxMjoKICAgICAgcE1heEJhbmRzVGFiID0gdG5zTWF4QmFuZHNUYWI1MTI7CiAgICAgIG1heEJhbmRzVGFiU2l6ZSA9IHNpemVvZih0bnNNYXhCYW5kc1RhYjUxMikvc2l6ZW9mKFROU19NQVhfVEFCX0VOVFJZKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBudW1CYW5kcyA9IC0xOwogIH0KCiAgaWYgKHBNYXhCYW5kc1RhYiE9TlVMTCkgewogICAgZm9yIChpPTA7IGk8bWF4QmFuZHNUYWJTaXplOyBpKyspIHsKICAgICAgbnVtQmFuZHMgPSBwTWF4QmFuZHNUYWJbaV0ubWF4QmFuZHNbKCFpc1Nob3J0QmxvY2spPzA6MV07CiAgICAgIGlmIChzYW1wbGVSYXRlID49IHBNYXhCYW5kc1RhYltpXS5zYW1wbGluZ1JhdGUpIHsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIG51bUJhbmRzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIEZES2FhY0VuY19GcmVxVG9CYW5kV2l0aFJvdW5kaW5nCgogIFJldHVybnMgaW5kZXggb2YgbmVhcmVzdCBiYW5kIGJvcmRlcgoKICBccGFyYW0gZnJlcXVlbmN5CiAgXHBhcmFtIHNhbXBsaW5nIGZyZXF1ZW5jeQogIFxwYXJhbSB0b3RhbCBudW1iZXIgb2YgYmFuZHMKICBccGFyYW0gcG9pbnRlciB0byB0YWJsZSBvZiBiYW5kIGJvcmRlcnMKCiAgXHJldHVybiBiYW5kIGJvcmRlcgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKSU5UIEZES2FhY0VuY19GcmVxVG9CYW5kV2l0aFJvdW5kaW5nKAogICAgICAgIGNvbnN0IElOVCBmcmVxLAogICAgICAgIGNvbnN0IElOVCBmcywKICAgICAgICBjb25zdCBJTlQgbnVtT2ZCYW5kcywKICAgICAgICBjb25zdCBJTlQgKmJhbmRTdGFydE9mZnNldAogICAgICAgICkKewogIElOVCBsaW5lTnVtYmVyLCBiYW5kOwoKICAvKiAgYXNzZXJ0KGZyZXEgPj0gMCk7ICAqLwogIGxpbmVOdW1iZXIgPSAoZnJlcSpiYW5kU3RhcnRPZmZzZXRbbnVtT2ZCYW5kc10qNC9mcysxKS8yOwoKICAvKiBmcmVxID4gZnMvMiAqLwogIGlmIChsaW5lTnVtYmVyID49IGJhbmRTdGFydE9mZnNldFtudW1PZkJhbmRzXSkKICAgIHJldHVybiBudW1PZkJhbmRzOwoKICAvKiBmaW5kIGJhbmQgdGhlIGxpbmUgbnVtYmVyIGxpZXMgaW4gKi8KICBmb3IgKGJhbmQ9MDsgYmFuZDxudW1PZkJhbmRzOyBiYW5kKyspIHsKICAgIGlmIChiYW5kU3RhcnRPZmZzZXRbYmFuZCsxXT5saW5lTnVtYmVyKSBicmVhazsKICB9CgogIC8qIHJvdW5kIHRvIG5lYXJlc3QgYmFuZCBib3JkZXIgKi8KICBpZiAobGluZU51bWJlciAtIGJhbmRTdGFydE9mZnNldFtiYW5kXSA+CiAgICAgIGJhbmRTdGFydE9mZnNldFtiYW5kKzFdIC0gbGluZU51bWJlciApCiAgICB7CiAgICAgIGJhbmQrKzsKICAgIH0KCiAgcmV0dXJuKGJhbmQpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgZnVuY3Rpb25uYW1lOiBGREthYWNFbmNfSW5pdFRuc0NvbmZpZ3VyYXRpb24KICAgIGRlc2NyaXB0aW9uOiAgZmlsbCBUTlNfQ09ORklHIHN0cnVjdHVyZSB3aXRoIHNlbnNpYmxlIGNvbnRlbnQKICAgIHJldHVybnM6CiAgICBpbnB1dDogICAgICAgIGJpdHJhdGUsIHNhbXBsZXJhdGUsIG51bWJlciBvZiBjaGFubmVscywKICAgICAgICAgICAgICAgICAgYmxvY2t0eXBlIChsb25nIG9yIHNob3J0KSwKICAgICAgICAgICAgICAgICAgVE5TIENvbmZpZyBzdHJ1Y3QgKG1vZGlmaWVkKSwKICAgICAgICAgICAgICAgICAgcHN5IGNvbmZpZyBzdHJ1Y3QsCiAgICAgICAgICAgICAgICAgIHRucyBhY3RpdmUgZmxhZwogICAgb3V0cHV0OgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkFBQ19FTkNPREVSX0VSUk9SIEZES2FhY0VuY19Jbml0VG5zQ29uZmlndXJhdGlvbihJTlQgYml0UmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzYW1wbGVSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGJsb2NrVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBncmFudWxlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGlzTG93RGVsYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbGRTYnJQcmVzZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVE5TX0NPTkZJRyAqdEMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU1lfQ09ORklHVVJBVElPTiAqcEMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgYWN0aXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHVzZVRuc1BlYWspCnsKICBpbnQgaTsKICAvL2Zsb2F0IGFjZlRpbWVSZXMgICA9IChibG9ja1R5cGUgPT0gU0hPUlRfV0lORE9XKSA/IDAuMTI1ZiA6IDAuMDQ2ODc1ZjsKCiAgaWYgKGNoYW5uZWxzIDw9IDApCiAgICByZXR1cm4gKEFBQ19FTkNPREVSX0VSUk9SKTE7CgogIHRDLT5pc0xvd0RlbGF5ID0gaXNMb3dEZWxheTsKCiAgLyogaW5pdGlhbGl6ZSBUTlMgZmlsdGVyIGZsYWcsIG9yZGVyLCBhbmQgY29lZmZpY2llbnQgcmVzb2x1dGlvbiAoaW4gYml0cyBwZXIgY29lZmYpICovCiAgdEMtPnRuc0FjdGl2ZSAgICAgID0gKGFjdGl2ZSkgPyBUUlVFIDogRkFMU0U7CiAgdEMtPm1heE9yZGVyICAgICAgID0gKGJsb2NrVHlwZSA9PSBTSE9SVF9XSU5ET1cpID8gNSA6IDEyOyAgLyogbWF4aW11bTogNywgMjAgKi8KICBpZiAoYml0UmF0ZSA8IDE2MDAwKQogICAgdEMtPm1heE9yZGVyIC09IDI7CiAgdEMtPmNvZWZSZXMgICAgICAgID0gKGJsb2NrVHlwZSA9PSBTSE9SVF9XSU5ET1cpID8gMyA6IDQ7CgogIC8qIExQQyBzdG9wIGxpbmU6IGhpZ2hlc3QgTURDVCBsaW5lIHRvIGJlIGNvZGVkLCBidXQgZG8gbm90IGdvIGJleW9uZCBUTlNfTUFYX0JBTkRTISAqLwogIHRDLT5scGNTdG9wQmFuZCA9IGdldFRuc01heEJhbmRzKHNhbXBsZVJhdGUsIGdyYW51bGVMZW5ndGgsIChibG9ja1R5cGUgPT0gU0hPUlRfV0lORE9XKSA/IDEgOiAwKTsKCiAgaWYgKHRDLT5scGNTdG9wQmFuZCA8IDApIHsKICAgIHJldHVybiAoQUFDX0VOQ09ERVJfRVJST1IpMTsKICB9CgogIHRDLT5scGNTdG9wQmFuZCA9IEZES21pbih0Qy0+bHBjU3RvcEJhbmQsIHBDLT5zZmJBY3RpdmUpOwogIHRDLT5scGNTdG9wTGluZSAgICA9IHBDLT5zZmJPZmZzZXRbdEMtPmxwY1N0b3BCYW5kXTsKCiAgc3dpdGNoIChncmFudWxlTGVuZ3RoKSB7CiAgICBjYXNlIDEwMjQ6CiAgICAgIC8qIFROUyBzdGFydCBsaW5lOiBza2lwIGxvd2VyIE1EQ1QgbGluZXMgdG8gcHJldmVudCBhcnRpZmFjdHMgZHVlIHRvIGZpbHRlciBtaXNtYXRjaCAqLwogICAgICB0Qy0+bHBjU3RhcnRCYW5kW0xPRklMVF0gICA9IChibG9ja1R5cGUgPT0gU0hPUlRfV0lORE9XKSA/IDAgOiAoKHNhbXBsZVJhdGUgPCAxODc4MykgPyA0IDogOCk7CiAgICAgIHRDLT5scGNTdGFydExpbmVbTE9GSUxUXSAgID0gcEMtPnNmYk9mZnNldFt0Qy0+bHBjU3RhcnRCYW5kW0xPRklMVF1dOwoKICAgICAgaSA9IHRDLT5scGNTdG9wQmFuZDsKICAgICAgd2hpbGUgKHBDLT5zZmJPZmZzZXRbaV0gPiAodEMtPmxwY1N0YXJ0TGluZVtMT0ZJTFRdICsgKHRDLT5scGNTdG9wTGluZSAtIHRDLT5scGNTdGFydExpbmVbTE9GSUxUXSkgLyA0KSkgaS0tOwogICAgICB0Qy0+bHBjU3RhcnRCYW5kW0hJRklMVF0gICA9IGk7CiAgICAgIHRDLT5scGNTdGFydExpbmVbSElGSUxUXSAgID0gcEMtPnNmYk9mZnNldFtpXTsKCiAgICAgIHRDLT5jb25mVGFiLnRocmVzaE9uW0hJRklMVF0gPSAxNDM3OwogICAgICB0Qy0+Y29uZlRhYi50aHJlc2hPbltMT0ZJTFRdID0gMTUwMDsKCiAgICAgIHRDLT5jb25mVGFiLnRuc0xpbWl0T3JkZXJbSElGSUxUXSA9IHRDLT5tYXhPcmRlcjsKICAgICAgdEMtPmNvbmZUYWIudG5zTGltaXRPcmRlcltMT0ZJTFRdID0gdEMtPm1heE9yZGVyIC0gNzsKCiAgICAgIHRDLT5jb25mVGFiLnRuc0ZpbHRlckRpcmVjdGlvbltISUZJTFRdID0gRklMVEVSX0RJUkVDVElPTjsKICAgICAgdEMtPmNvbmZUYWIudG5zRmlsdGVyRGlyZWN0aW9uW0xPRklMVF0gPSBGSUxURVJfRElSRUNUSU9OOwoKICAgICAgdEMtPmNvbmZUYWIuYWNmU3BsaXRbSElGSUxUXSA9IC0xOyAgLyogc2lnbmFsIE1lcmdlZDR0bzJRdWFydGVyc0F1dG9Db3JyZWxhdGlvbiBpbiBGREthYWNFbmNfTWVyZ2VkQXV0b0NvcnJlbGF0aW9uKi8KICAgICAgdEMtPmNvbmZUYWIuYWNmU3BsaXRbTE9GSUxUXSA9IC0xOyAgLyogc2lnbmFsIE1lcmdlZDR0bzJRdWFydGVyc0F1dG9Db3JyZWxhdGlvbiBpbiBGREthYWNFbmNfTWVyZ2VkQXV0b0NvcnJlbGF0aW9uICovCgogICAgICB0Qy0+Y29uZlRhYi5maWx0ZXJFbmFibGVkW0hJRklMVF0gPSAxOwogICAgICB0Qy0+Y29uZlRhYi5maWx0ZXJFbmFibGVkW0xPRklMVF0gPSAxOwogICAgICB0Qy0+Y29uZlRhYi5zZXBlcmF0ZUZpbHRlcnNBbGxvd2VkID0gMTsKCiAgICAgIC8qIGNvbXB1dGUgYXV0b2NvcnJlbGF0aW9uIHdpbmRvdyBiYXNlZCBvbiBtYXhpbXVtIGZpbHRlciBvcmRlciBmb3IgZ2l2ZW4gYmxvY2sgdHlwZSAqLwogICAgICAvKiBmb3IgKGkgPSAwOyBpIDw9IHRDLT5tYXhPcmRlciArIDM7IGkrKykgewogICAgICAgICAgIGZsb2F0IGFjZldpblRlbXAgPSBhY2ZUaW1lUmVzICogaTsKICAgICAgICAgICBhY2ZXaW5kb3dbaV0gPSBGTDJGWENPTlNUX0RCTCgxLjBmIC0gYWNmV2luVGVtcCAqIGFjZldpblRlbXApOwogICAgICAgICB9CiAgICAgICovCiAgICAgIGlmIChibG9ja1R5cGUgPT0gU0hPUlRfV0lORE9XKSB7CiAgICAgICAgRkRLbWVtY3B5KHRDLT5hY2ZXaW5kb3dbSElGSUxUXSwgYWNmV2luZG93U2hvcnQsIEZES21pbihzaXplb2YoYWNmV2luZG93U2hvcnQpLCBzaXplb2YodEMtPmFjZldpbmRvd1tISUZJTFRdKSkpOwogICAgICAgIEZES21lbWNweSh0Qy0+YWNmV2luZG93W0xPRklMVF0sIGFjZldpbmRvd1Nob3J0LCBGREttaW4oc2l6ZW9mKGFjZldpbmRvd1Nob3J0KSwgc2l6ZW9mKHRDLT5hY2ZXaW5kb3dbSElGSUxUXSkpKTsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBGREttZW1jcHkodEMtPmFjZldpbmRvd1tISUZJTFRdLCBhY2ZXaW5kb3dMb25nLCBGREttaW4oc2l6ZW9mKGFjZldpbmRvd0xvbmcpLCBzaXplb2YodEMtPmFjZldpbmRvd1tISUZJTFRdKSkpOwogICAgICAgIEZES21lbWNweSh0Qy0+YWNmV2luZG93W0xPRklMVF0sIGFjZldpbmRvd0xvbmcsIEZES21pbihzaXplb2YoYWNmV2luZG93TG9uZyksIHNpemVvZih0Qy0+YWNmV2luZG93W0hJRklMVF0pKSk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIDQ4MDoKICAgIGNhc2UgNTEyOgogICAgICB7CiAgICAgICAgY29uc3QgVE5TX1BBUkFNRVRFUl9UQUJVTEFURUQqIHBDZmcgPSBGREthYWNFbmNfR2V0VG5zUGFyYW0oYml0UmF0ZSwgY2hhbm5lbHMsIGxkU2JyUHJlc2VudCk7CgogICAgICAgIGlmICggcENmZyAhPSBOVUxMICkgewoKICAgICAgICAgIEZES21lbWNweSgmKHRDLT5jb25mVGFiKSwgcENmZywgc2l6ZW9mKHRDLT5jb25mVGFiKSk7CgogICAgICAgICAgdEMtPmxwY1N0YXJ0QmFuZFtISUZJTFRdICAgICAgICAgPSBGREthYWNFbmNfRnJlcVRvQmFuZFdpdGhSb3VuZGluZyhwQ2ZnLT5maWx0ZXJTdGFydEZyZXFbSElGSUxUXSwgc2FtcGxlUmF0ZSwgcEMtPnNmYkNudCwgcEMtPnNmYk9mZnNldCk7CiAgICAgICAgICB0Qy0+bHBjU3RhcnRMaW5lW0hJRklMVF0gICAgICAgICA9IHBDLT5zZmJPZmZzZXRbdEMtPmxwY1N0YXJ0QmFuZFtISUZJTFRdXTsKICAgICAgICAgIHRDLT5scGNTdGFydEJhbmRbTE9GSUxUXSAgICAgICAgID0gRkRLYWFjRW5jX0ZyZXFUb0JhbmRXaXRoUm91bmRpbmcocENmZy0+ZmlsdGVyU3RhcnRGcmVxW0xPRklMVF0sIHNhbXBsZVJhdGUsIHBDLT5zZmJDbnQsIHBDLT5zZmJPZmZzZXQpOwogICAgICAgICAgdEMtPmxwY1N0YXJ0TGluZVtMT0ZJTFRdICAgICAgICAgPSBwQy0+c2ZiT2Zmc2V0W3RDLT5scGNTdGFydEJhbmRbTE9GSUxUXV07CgogICAgICAgICAgRkRLYWFjRW5jX0NhbGNHYXVzc1dpbmRvdyh0Qy0+YWNmV2luZG93W0hJRklMVF0sIHRDLT5tYXhPcmRlcisxLCBzYW1wbGVSYXRlLCBncmFudWxlTGVuZ3RoLCBwQ2ZnLT50bnNUaW1lUmVzb2x1dGlvbltISUZJTFRdLCBUTlNfVElNRVJFU19TQ0FMRSk7CiAgICAgICAgICBGREthYWNFbmNfQ2FsY0dhdXNzV2luZG93KHRDLT5hY2ZXaW5kb3dbTE9GSUxUXSwgdEMtPm1heE9yZGVyKzEsIHNhbXBsZVJhdGUsIGdyYW51bGVMZW5ndGgsIHBDZmctPnRuc1RpbWVSZXNvbHV0aW9uW0xPRklMVF0sIFROU19USU1FUkVTX1NDQUxFKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICB0Qy0+dG5zQWN0aXZlID0gRkFMU0U7IC8qIG5vIGNvbmZpZ3VyYXRpb24gYXZhaWxhYmxlLCBkaXNhYmxlIHRucyB0b29sICovCiAgICAgICAgfQogICAgICB9CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdEMtPnRuc0FjdGl2ZSA9IEZBTFNFOyAvKiBubyBjb25maWd1cmF0aW9uIGF2YWlsYWJsZSwgZGlzYWJsZSB0bnMgdG9vbCAqLwogIH0KCiAgcmV0dXJuIEFBQ19FTkNfT0s7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIEZES2FhY0VuY19TY2FsZVVwU3BlY3RydW0KCiAgU2NhbGVzIHVwIHNwZWN0cnVtIGxpbmVzIGluIGEgZ2l2ZW4gZnJlcXVlbmN5IHNlY3Rpb24KCiAgXHBhcmFtIHNjYWxlZCBzcGVjdHJ1bQogIFxwYXJhbSBvcmlnaW5hbCBzcGVjdHJ1bQogIFxwYXJhbSBmcmVxdWVuY3kgbGluZSB0byBzdGFydCBzY2FsaW5nCiAgXHBhcmFtIGZyZXF1ZW5jeSBsaW5lIHRvIGVuYyBzY2FsaW5nCgogIFxyZXR1cm4gc2NhbGUgZmFjdG9yCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgaW5saW5lIElOVCBGREthYWNFbmNfU2NhbGVVcFNwZWN0cnVtKAogICAgICAgIEZJWFBfREJMICAgICAgICAgICAgICAgICAqZGVzdCwKICAgICAgICBjb25zdCBGSVhQX0RCTCAgICAgICAgICAgKnNyYywKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgIHN0YXJ0TGluZSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgIHN0b3BMaW5lCiAgICAgICAgKQp7CiAgICBJTlQgaSwgc2NhbGU7CgogICAgRklYUF9EQkwgbWF4VmFsID0gRkwyRlhDT05TVF9EQkwoMC5mKTsKCiAgICAvKiBHZXQgaGlnaGVzdCB2YWx1ZSBpbiBnaXZlbiBzcGVjdHJ1bSAqLwogICAgZm9yIChpPXN0YXJ0TGluZTsgaTxzdG9wTGluZTsgaSsrKSB7CiAgICAgIG1heFZhbCA9IGZpeE1heChtYXhWYWwsZml4cF9hYnMoc3JjW2ldKSk7CiAgICB9CiAgICBzY2FsZSA9IENvdW50TGVhZGluZ0JpdHMobWF4VmFsKTsKCiAgICAvKiBTY2FsZSBzcGVjdHJ1bSBhY2NvcmRpbmcgdG8gaGlnaGVzdCB2YWx1ZSAqLwogICAgZm9yIChpPXN0YXJ0TGluZTsgaTxzdG9wTGluZTsgaSsrKSB7CiAgICAgIGRlc3RbaV0gPSBzcmNbaV08PHNjYWxlOwogICAgfQoKICAgIHJldHVybiBzY2FsZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBGREthYWNFbmNfQ2FsY0F1dG9Db3JyVmFsdWUKCiAgQ2FsY3VsYXRlIGF1dG9jb3JlbGxhdGlvbiB2YWx1ZSBmb3Igb25lIGxhZwoKICBccGFyYW0gcG9pbnRlciB0byBzcGVjdHJ1bQogIFxwYXJhbSBzdGFydCBsaW5lCiAgXHBhcmFtIHN0b3AgbGluZQogIFxwYXJhbSBsYWcgdG8gYmUgY2FsY3VsYXRlZAogIFxwYXJhbSBzY2FsaW5nIG9mIHRoZSBsYWcKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBpbmxpbmUgRklYUF9EQkwgRkRLYWFjRW5jX0NhbGNBdXRvQ29yclZhbHVlKAogICAgICAgIGNvbnN0IEZJWFBfREJMICAgICAgICAgICAqc3BlY3RydW0sCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBzdGFydExpbmUsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBzdG9wTGluZSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgIGxhZywKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgIHNjYWxlCiAgICAgICAgKQp7CiAgICBpbnQgaTsKICAgIEZJWFBfREJMIHJlc3VsdCA9IEZMMkZYQ09OU1RfREJMKDAuZik7CgogICAgaWYgKGxhZz09MCkgewogICAgICBmb3IgKGk9c3RhcnRMaW5lOyBpPHN0b3BMaW5lOyBpKyspIHsKICAgICAgICByZXN1bHQgKz0gKGZQb3cyKHNwZWN0cnVtW2ldKT4+c2NhbGUpOwogICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgZm9yIChpPXN0YXJ0TGluZTsgaTwoc3RvcExpbmUtbGFnKTsgaSsrKSB7CiAgICAgICAgcmVzdWx0ICs9IChmTXVsdChzcGVjdHJ1bVtpXSwgc3BlY3RydW1baStsYWddKT4+c2NhbGUpOwogICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJlc3VsdDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBGREthYWNFbmNfQXV0b0NvcnJOb3JtRmFjCgogIEF1dG9jb3JyZWxhdGlvbiBmdW5jdGlvbiBmb3IgMXN0IGFuZCAybmQgaGFsZiBvZiB0aGUgc3BlY3RydW0KCiAgXHBhcmFtIHBvaW50ZXIgdG8gc3BlY3RydW0KICBccGFyYW0gcG9pbnRlciB0byBhdXRvY29ycmVsYXRpb24gd2luZG93CiAgXHBhcmFtIGZpbHRlciBzdGFydCBsaW5lCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgaW5saW5lIEZJWFBfREJMIEZES2FhY0VuY19BdXRvQ29yck5vcm1GYWMoCiAgICAgICAgY29uc3QgRklYUF9EQkwgICAgICAgICAgICB2YWx1ZSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgIHNjYWxlLAogICAgICAgIElOVCAgICAgICAgICAgICAgICAgICAgICAqc2MKICAgICAgICApCnsKICAgICNkZWZpbmUgSExNX01JTl9OUkcgMC4wMDAwMDAwMDM3MjUyOTAyOTg0NjE5MTQwNjI1ZiAvKiAyXi0yOCAqLwogICAgI2RlZmluZSBNQVhfSU5WX05SR0ZBQyAoMS5mL0hMTV9NSU5fTlJHKQoKICAgIEZJWFBfREJMIHJldFZhbHVlOwogICAgRklYUF9EQkwgQSwgQjsKCiAgICBpZiAoc2NhbGU+PTApIHsKICAgICAgQSA9IHZhbHVlOwogICAgICBCID0gRkwyRlhDT05TVF9EQkwoSExNX01JTl9OUkcpPj5maXhNaW4oREZSQUNUX0JJVFMtMSxzY2FsZSk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgQSA9IHZhbHVlPj5maXhNaW4oREZSQUNUX0JJVFMtMSwoLXNjYWxlKSk7CiAgICAgIEIgPSBGTDJGWENPTlNUX0RCTChITE1fTUlOX05SRyk7CiAgICB9CgogICAgaWYgKEEgPiBCKSB7CiAgICAgIGludCBzaGlmdCA9IDA7CiAgICAgIEZJWFBfREJMIHRtcCA9IGludlNxcnROb3JtMih2YWx1ZSwmc2hpZnQpOwoKICAgICAgcmV0VmFsdWUgPSBmTXVsdCh0bXAsdG1wKTsKICAgICAgKnNjICs9ICgyKnNoaWZ0KTsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBNQVhfSU5WX05SR0ZBQypGREtwb3coMiwtMjgpID0gMS8yXi0yOCAqIDJeLTI4ID0gMS4wICovCiAgICAgIHJldFZhbHVlID0gLypGTDJGWENPTlNUX0RCTChNQVhfSU5WX05SR0ZBQypGREtwb3coMiwtMjgpKSovIChGSVhQX0RCTClNQVhWQUxfREJMOwogICAgICAqc2MgKz0gc2NhbGUrMjg7CiAgICB9CgogICAgcmV0dXJuIHJldFZhbHVlOwp9CgpzdGF0aWMgdm9pZCBGREthYWNFbmNfTWVyZ2VkQXV0b0NvcnJlbGF0aW9uKAogICAgICAgIGNvbnN0IEZJWFBfREJMICAgICAgICAgICAqc3BlY3RydW0sCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBpc0xvd0RlbGF5LAogICAgICAgIGNvbnN0IEZJWFBfREJMICAgICAgICAgICAgYWNmV2luZG93W01BWF9OVU1fT0ZfRklMVEVSU11bVE5TX01BWF9PUkRFUiszKzFdLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgbHBjU3RhcnRMaW5lW01BWF9OVU1fT0ZfRklMVEVSU10sCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBscGNTdG9wTGluZSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgIG1heE9yZGVyLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgYWNmU3BsaXRbTUFYX05VTV9PRl9GSUxURVJTXSwKICAgICAgICBGSVhQX0RCTCAgICAgICAgICAgICAgICAgKl9yeHgxLAogICAgICAgIEZJWFBfREJMICAgICAgICAgICAgICAgICAqX3J4eDIKICAgICAgICApCnsKICAgIGludCBpLCBpZHgwLCBpZHgxLCBpZHgyLCBpZHgzLCBpZHg0LCBsYWc7CiAgICBGSVhQX0RCTCByeHgxXzAsIHJ4eDJfMCwgcnh4M18wLCByeHg0XzA7CgogICAgLyogYnVmZmVyIGZvciB0ZW1wb3JhbCBzcGVjdHJ1bSAqLwogICAgQ19BTExPQ19TQ1JBVENIX1NUQVJUKHBTcGVjdHJ1bSwgRklYUF9EQkwsICgxMDI0KSk7CgogICAgLyogcHJlLWluaXRpYWxpemF0aW9uIG91dHB1dCAqLwogICAgRkRLbWVtY2xlYXIoJl9yeHgxWzBdLCBzaXplb2YoRklYUF9EQkwpKihtYXhPcmRlcisxKSk7CiAgICBGREttZW1jbGVhcigmX3J4eDJbMF0sIHNpemVvZihGSVhQX0RCTCkqKG1heE9yZGVyKzEpKTsKCiAgICBpZHgwID0gaWR4MSA9IGlkeDIgPSBpZHgzID0gaWR4NCA9IDA7CgogICAgLyogTURDVCBsaW5lIGluZGljZXMgc2VwYXJhdGluZyB0aGUgMXN0LCAybmQsIDNyZCwgYW5kIDR0aCBhbmFseXNpcyBxdWFydGVycyAqLwogICAgaWYgKCAoYWNmU3BsaXRbTE9GSUxUXT09LTEpIHx8IChhY2ZTcGxpdFtISUZJTFRdPT0tMSkgKSB7CiAgICAgIC8qIGF1dG9jb3JyZWxhdGlvbiBmdW5jdGlvbiBmb3IgMXN0LCAybmQsIDNyZCwgYW5kIDR0aCBxdWFydGVyIG9mIHRoZSBzcGVjdHJ1bSAqLwogICAgICBpZHgwID0gbHBjU3RhcnRMaW5lW0xPRklMVF07CiAgICAgIGkgICAgPSBscGNTdG9wTGluZSAtIGxwY1N0YXJ0TGluZVtMT0ZJTFRdOwogICAgICBpZHgxID0gaWR4MCArIGkgLyA0OwogICAgICBpZHgyID0gaWR4MCArIGkgLyAyOwogICAgICBpZHgzID0gaWR4MCArIGkgKiAzIC8gNDsKICAgICAgaWR4NCA9IGxwY1N0b3BMaW5lOwogICAgfQogICAgZWxzZSB7CiAgICAgIEZES19BU1NFUlQoYWNmU3BsaXRbTE9GSUxUXT09MSk7CiAgICAgIEZES19BU1NFUlQoYWNmU3BsaXRbSElGSUxUXT09Myk7CiAgICAgIGkgICAgPSAobHBjU3RvcExpbmUgLSBscGNTdGFydExpbmVbSElGSUxUXSkgLyAzOwogICAgICBpZHgwID0gbHBjU3RhcnRMaW5lW0xPRklMVF07CiAgICAgIGlkeDEgPSBscGNTdGFydExpbmVbSElGSUxUXTsKICAgICAgaWR4MiA9IGlkeDEgKyBpOwogICAgICBpZHgzID0gaWR4MiArIGk7CiAgICAgIGlkeDQgPSBscGNTdG9wTGluZTsKICAgIH0KCiAgICAvKiBjb3B5IHNwZWN0cnVtIHRvIHRlbXBvcmFsIGJ1ZmZlciBhbmQgc2NhbGUgdXAgYXMgbXVjaCBhcyBwb3NzaWJsZSAqLwogICAgSU5UIHNjMSA9IEZES2FhY0VuY19TY2FsZVVwU3BlY3RydW0ocFNwZWN0cnVtLCBzcGVjdHJ1bSwgaWR4MCwgaWR4MSk7CiAgICBJTlQgc2MyID0gRkRLYWFjRW5jX1NjYWxlVXBTcGVjdHJ1bShwU3BlY3RydW0sIHNwZWN0cnVtLCBpZHgxLCBpZHgyKTsKICAgIElOVCBzYzMgPSBGREthYWNFbmNfU2NhbGVVcFNwZWN0cnVtKHBTcGVjdHJ1bSwgc3BlY3RydW0sIGlkeDIsIGlkeDMpOwogICAgSU5UIHNjNCA9IEZES2FhY0VuY19TY2FsZVVwU3BlY3RydW0ocFNwZWN0cnVtLCBzcGVjdHJ1bSwgaWR4MywgaWR4NCk7CgogICAgLyogZ2V0IHNjYWxpbmcgdmFsdWVzIGZvciBzdW1tYXRpb24gKi8KICAgIElOVCBuc2MxLCBuc2MyLCBuc2MzLCBuc2M0OwogICAgZm9yIChuc2MxPTE7ICgxPDxuc2MxKTwoaWR4MS1pZHgwKTsgbnNjMSsrKTsKICAgIGZvciAobnNjMj0xOyAoMTw8bnNjMik8KGlkeDItaWR4MSk7IG5zYzIrKyk7CiAgICBmb3IgKG5zYzM9MTsgKDE8PG5zYzMpPChpZHgzLWlkeDIpOyBuc2MzKyspOwogICAgZm9yIChuc2M0PTE7ICgxPDxuc2M0KTwoaWR4NC1pZHgzKTsgbnNjNCsrKTsKCiAgICAvKiBjb21wdXRlIGF1dG9jb3JyZWxhdGlvbiB2YWx1ZSBhdCBsYWcgemVybywgaS4gZS4gZW5lcmd5LCBmb3IgZWFjaCBxdWFydGVyICovCiAgICByeHgxXzAgPSBGREthYWNFbmNfQ2FsY0F1dG9Db3JyVmFsdWUocFNwZWN0cnVtLCBpZHgwLCBpZHgxLCAwLCBuc2MxKTsKICAgIHJ4eDJfMCA9IEZES2FhY0VuY19DYWxjQXV0b0NvcnJWYWx1ZShwU3BlY3RydW0sIGlkeDEsIGlkeDIsIDAsIG5zYzIpOwogICAgcnh4M18wID0gRkRLYWFjRW5jX0NhbGNBdXRvQ29yclZhbHVlKHBTcGVjdHJ1bSwgaWR4MiwgaWR4MywgMCwgbnNjMyk7CiAgICByeHg0XzAgPSBGREthYWNFbmNfQ2FsY0F1dG9Db3JyVmFsdWUocFNwZWN0cnVtLCBpZHgzLCBpZHg0LCAwLCBuc2M0KTsKCiAgICAvKiBjb21wdXRlIGVuZXJneSBub3JtYWxpemF0aW9uIGZhY3RvcnMsIGkuIGUuIDEvZW5lcmd5IChzYXZlcyBzb21lIGRpdmlzaW9ucykgKi8KICAgIGlmIChyeHgxXzAgIT0gRkwyRlhDT05TVF9EQkwoMC5mKSkKICAgIHsKICAgICAgSU5UIHNjX2ZhYzEgPSAtMTsKICAgICAgRklYUF9EQkwgZmFjMSA9IEZES2FhY0VuY19BdXRvQ29yck5vcm1GYWMocnh4MV8wLCAoKC0yKnNjMSkrbnNjMSksICZzY19mYWMxKTsKICAgICAgX3J4eDFbMF0gPSBzY2FsZVZhbHVlKGZNdWx0KHJ4eDFfMCxmYWMxKSxzY19mYWMxKTsKCiAgICAgIGlmIChpc0xvd0RlbGF5KQogICAgICB7CiAgICAgICAgZm9yIChsYWcgPSAxOyBsYWcgPD0gbWF4T3JkZXI7IGxhZysrKSB7CiAgICAgICAgICAvKiBjb21wdXRlIGVuZXJneS1ub3JtYWxpemVkIGFuZCB3aW5kb3dlZCBhdXRvY29ycmVsYXRpb24gdmFsdWVzIGF0IHRoaXMgbGFnICovCiAgICAgICAgICBGSVhQX0RCTCB4MSA9IEZES2FhY0VuY19DYWxjQXV0b0NvcnJWYWx1ZShwU3BlY3RydW0sIGlkeDAsIGlkeDEsIGxhZywgbnNjMSk7CiAgICAgICAgICBfcnh4MVtsYWddID0gZk11bHQoc2NhbGVWYWx1ZShmTXVsdCh4MSxmYWMxKSxzY19mYWMxKSwgYWNmV2luZG93W0xPRklMVF1bbGFnXSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgIGZvciAobGFnID0gMTsgbGFnIDw9IG1heE9yZGVyOyBsYWcrKykgewogICAgICAgICAgaWYgKCgzICogbGFnKSA8PSBtYXhPcmRlciArIDMpIHsKICAgICAgICAgICAgICBGSVhQX0RCTCB4MSA9IEZES2FhY0VuY19DYWxjQXV0b0NvcnJWYWx1ZShwU3BlY3RydW0sIGlkeDAsIGlkeDEsIGxhZywgbnNjMSk7CiAgICAgICAgICAgICAgX3J4eDFbbGFnXSA9IGZNdWx0KHNjYWxlVmFsdWUoZk11bHQoeDEsZmFjMSksc2NfZmFjMSksIGFjZldpbmRvd1tMT0ZJTFRdWzMqbGFnXSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgLyogYXV0byBjb3JyIG92ZXIgdXBwZXIgMy80IG9mIHNwZWN0cnVtICovCiAgICBpZiAoICEoKHJ4eDJfMCA9PSBGTDJGWENPTlNUX0RCTCgwLmYpKSAmJiAocnh4M18wID09IEZMMkZYQ09OU1RfREJMKDAuZikpICYmIChyeHg0XzAgPT0gRkwyRlhDT05TVF9EQkwoMC5mKSkpICkKICAgIHsKICAgICAgICBGSVhQX0RCTCBmYWMyLCBmYWMzLCBmYWM0OwogICAgICAgIGZhYzIgPSBmYWMzID0gZmFjNCA9IEZMMkZYQ09OU1RfREJMKDAuZik7CiAgICAgICAgSU5UIHNjX2ZhYzIsIHNjX2ZhYzMsIHNjX2ZhYzQ7CiAgICAgICAgc2NfZmFjMiA9IHNjX2ZhYzMgPSBzY19mYWM0ID0gMDsKCiAgICAgICAgaWYgKHJ4eDJfMCE9RkwyRlhDT05TVF9EQkwoMC5mKSkgewogICAgICAgICAgZmFjMiA9IEZES2FhY0VuY19BdXRvQ29yck5vcm1GYWMocnh4Ml8wLCAoKC0yKnNjMikrbnNjMiksICZzY19mYWMyKTsKICAgICAgICAgIHNjX2ZhYzIgLT0gMjsKICAgICAgICB9CiAgICAgICAgaWYgKHJ4eDNfMCE9RkwyRlhDT05TVF9EQkwoMC5mKSkgewogICAgICAgICAgZmFjMyA9IEZES2FhY0VuY19BdXRvQ29yck5vcm1GYWMocnh4M18wLCAoKC0yKnNjMykrbnNjMyksICZzY19mYWMzKTsKICAgICAgICAgIHNjX2ZhYzMgLT0gMjsKICAgICAgICB9CiAgICAgICAgaWYgKHJ4eDRfMCE9RkwyRlhDT05TVF9EQkwoMC5mKSkgewogICAgICAgICAgZmFjNCA9IEZES2FhY0VuY19BdXRvQ29yck5vcm1GYWMocnh4NF8wLCAoKC0yKnNjNCkrbnNjNCksICZzY19mYWM0KTsKICAgICAgICAgIHNjX2ZhYzQgLT0gMjsKICAgICAgICB9CgogICAgICAgIF9yeHgyWzBdID0gc2NhbGVWYWx1ZShmTXVsdChyeHgyXzAsZmFjMiksc2NfZmFjMikgKwogICAgICAgICAgICAgICAgICAgc2NhbGVWYWx1ZShmTXVsdChyeHgzXzAsZmFjMyksc2NfZmFjMykgKwogICAgICAgICAgICAgICAgICAgc2NhbGVWYWx1ZShmTXVsdChyeHg0XzAsZmFjNCksc2NfZmFjNCk7CgogICAgICAgIGZvciAobGFnID0gMTsgbGFnIDw9IG1heE9yZGVyOyBsYWcrKykgewogICAgICAgICAgLyogbWVyZ2UgcXVhcnRlcnMgMiwgMywgNCBpbnRvIG9uZSBhdXRvY29ycmVsYXRpb247IHF1YXJ0ZXIgMSBzdGF5cyBzZXBhcmF0ZSAqLwogICAgICAgICAgRklYUF9EQkwgeDIgPSBzY2FsZVZhbHVlKGZNdWx0KEZES2FhY0VuY19DYWxjQXV0b0NvcnJWYWx1ZShwU3BlY3RydW0sIGlkeDEsIGlkeDIsIGxhZywgbnNjMiksIGZhYzIpLHNjX2ZhYzIpICsKICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVWYWx1ZShmTXVsdChGREthYWNFbmNfQ2FsY0F1dG9Db3JyVmFsdWUocFNwZWN0cnVtLCBpZHgyLCBpZHgzLCBsYWcsIG5zYzMpLCBmYWMzKSxzY19mYWMzKSArCiAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlVmFsdWUoZk11bHQoRkRLYWFjRW5jX0NhbGNBdXRvQ29yclZhbHVlKHBTcGVjdHJ1bSwgaWR4MywgaWR4NCwgbGFnLCBuc2M0KSwgZmFjNCksc2NfZmFjNCk7CgogICAgICAgICAgX3J4eDJbbGFnXSA9IGZNdWx0KHgyLCBhY2ZXaW5kb3dbSElGSUxUXVtsYWddKTsKICAgICAgICB9CiAgICB9CgogICAgQ19BTExPQ19TQ1JBVENIX0VORChwU3BlY3RydW0sIEZJWFBfREJMLCAoMTAyNCkpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19UbnNEZXRlY3QKICAgIGRlc2NyaXB0aW9uOiAgZG8gZGVjaXNpb24sIGlmIFROUyBzaGFsbCBiZSB1c2VkIG9yIG5vdAogICAgcmV0dXJuczoKICAgIGlucHV0OiAgICAgICAgdG5zIGRhdGEgc3RydWN0dXJlIChtb2RpZmllZCksCiAgICAgICAgICAgICAgICAgIHRucyBjb25maWcgc3RydWN0dXJlLAogICAgICAgICAgICAgICAgICBzY2FsZWZhY3RvciBzaXplIGFuZCB0YWJsZSwKICAgICAgICAgICAgICAgICAgc3BlY3RydW0sCiAgICAgICAgICAgICAgICAgIHN1YmJsb2NrIG51bSwgYmxvY2t0eXBlLAogICAgICAgICAgICAgICAgICBzZmItd2lzZSBlbmVyZ3kuCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSU5UIEZES2FhY0VuY19UbnNEZXRlY3QoCiAgICAgICAgICAgICAgVE5TX0RBVEEgKnRuc0RhdGEsCiAgICAgICAgICAgICAgY29uc3QgVE5TX0NPTkZJRyAqdEMsCiAgICAgICAgICAgICAgVE5TX0lORk8qIHRuc0luZm8sCiAgICAgICAgICAgICAgSU5UIHNmYkNudCwKICAgICAgICAgICAgICBGSVhQX0RCTCAqc3BlY3RydW0sCiAgICAgICAgICAgICAgSU5UIHN1YkJsb2NrTnVtYmVyLAogICAgICAgICAgICAgIElOVCBibG9ja1R5cGUKICAgICAgICAgICAgICApCnsKICAvKiBhdXRvY29ycmVsYXRpb24gZnVuY3Rpb24gZm9yIDFzdCwgMm5kLCAzcmQsIGFuZCA0dGggcXVhcnRlciBvZiB0aGUgc3BlY3RydW0uICovCiAgRklYUF9EQkwgcnh4MVtUTlNfTUFYX09SREVSKzFdOyAvKiBoaWdoZXIgcGFydCAqLwogIEZJWFBfREJMIHJ4eDJbVE5TX01BWF9PUkRFUisxXTsgLyogbG93ZXIgcGFydCAqLwogIEZJWFBfREJMIHBhcmNvcl90bXBbVE5TX01BWF9PUkRFUl07CgogIGludCBpOwoKICBUTlNfU1VCQkxPQ0tfSU5GTyAqdHNiaSA9IChibG9ja1R5cGUgPT0gU0hPUlRfV0lORE9XKQogICAgPyAmdG5zRGF0YS0+ZGF0YVJhdy5TaG9ydC5zdWJCbG9ja0luZm9bc3ViQmxvY2tOdW1iZXJdCiAgICA6ICZ0bnNEYXRhLT5kYXRhUmF3Lkxvbmcuc3ViQmxvY2tJbmZvOwoKICB0bnNEYXRhLT5maWx0ZXJzTWVyZ2VkICA9IEZBTFNFOwoKICB0c2JpLT50bnNBY3RpdmVbSElGSUxUXSAgICAgICAgID0gRkFMU0U7CiAgdHNiaS0+cHJlZGljdGlvbkdhaW5bSElGSUxUXSAgICA9IDEwMDA7CiAgdHNiaS0+dG5zQWN0aXZlW0xPRklMVF0gICAgICAgICA9IEZBTFNFOwogIHRzYmktPnByZWRpY3Rpb25HYWluW0xPRklMVF0gICAgPSAxMDAwOwoKICB0bnNJbmZvLT5udW1PZkZpbHRlcnNbc3ViQmxvY2tOdW1iZXJdID0gMDsKICB0bnNJbmZvLT5jb2VmUmVzW3N1YkJsb2NrTnVtYmVyXSAgICAgID0gdEMtPmNvZWZSZXM7CiAgZm9yIChpID0gMDsgaSA8IHRDLT5tYXhPcmRlcjsgaSsrKSB7CiAgICB0bnNJbmZvLT5jb2VmW3N1YkJsb2NrTnVtYmVyXVtISUZJTFRdW2ldID0gdG5zSW5mby0+Y29lZltzdWJCbG9ja051bWJlcl1bTE9GSUxUXVtpXSA9IDA7CiAgfQoKICB0bnNJbmZvLT5sZW5ndGhbc3ViQmxvY2tOdW1iZXJdW0hJRklMVF0gPSB0bnNJbmZvLT5sZW5ndGhbc3ViQmxvY2tOdW1iZXJdW0xPRklMVF0gPSAwOwogIHRuc0luZm8tPm9yZGVyIFtzdWJCbG9ja051bWJlcl1bSElGSUxUXSA9IHRuc0luZm8tPm9yZGVyIFtzdWJCbG9ja051bWJlcl1bTE9GSUxUXSA9IDA7CgogIGlmICggKHRDLT50bnNBY3RpdmUpICYmICh0Qy0+bWF4T3JkZXI+MCkgKQogIHsKICAgIGludCBzdW1TcXJDb2VmOwoKICAgIEZES2FhY0VuY19NZXJnZWRBdXRvQ29ycmVsYXRpb24oCiAgICAgICAgICBzcGVjdHJ1bSwKICAgICAgICAgIHRDLT5pc0xvd0RlbGF5LAogICAgICAgICAgdEMtPmFjZldpbmRvdywKICAgICAgICAgIHRDLT5scGNTdGFydExpbmUsCiAgICAgICAgICB0Qy0+bHBjU3RvcExpbmUsCiAgICAgICAgICB0Qy0+bWF4T3JkZXIsCiAgICAgICAgICB0Qy0+Y29uZlRhYi5hY2ZTcGxpdCwKICAgICAgICAgIHJ4eDEsCiAgICAgICAgICByeHgyKTsKCiAgICAvKiBjb21wdXRlIGhpZ2hlciBUTlMgZmlsdGVyIGluIGxhdHRpY2UgKFBhckNvcikgZm9ybSB3aXRoIExlUm91eC1HdWVndWVuIGFsZ29yaXRobSAqLwogICAgdHNiaS0+cHJlZGljdGlvbkdhaW5bSElGSUxUXSA9IEZES2FhY0VuY19BdXRvVG9QYXJjb3Iocnh4MiwgcGFyY29yX3RtcCwgdEMtPmNvbmZUYWIudG5zTGltaXRPcmRlcltISUZJTFRdKTsKCiAgICAvKiBub24tbGluZWFyIHF1YW50aXphdGlvbiBvZiBUTlMgbGF0dGljZSBjb2VmZmljaWVudHMgd2l0aCBnaXZlbiByZXNvbHV0aW9uICovCiAgICBGREthYWNFbmNfUGFyY29yMkluZGV4KAogICAgICAgICAgICBwYXJjb3JfdG1wLAogICAgICAgICAgICB0bnNJbmZvLT5jb2VmW3N1YkJsb2NrTnVtYmVyXVtISUZJTFRdLAogICAgICAgICAgICB0Qy0+Y29uZlRhYi50bnNMaW1pdE9yZGVyW0hJRklMVF0sCiAgICAgICAgICAgIHRDLT5jb2VmUmVzKTsKCiAgICAvKiByZWR1Y2UgZmlsdGVyIG9yZGVyIGJ5IHRydW5jYXRpbmcgdHJhaWxpbmcgemVyb3MsIGNvbXB1dGUgc3VtKGFicyhjb2VmcykpICovCiAgICBmb3IgKGkgPSB0Qy0+Y29uZlRhYi50bnNMaW1pdE9yZGVyW0hJRklMVF0gLSAxOyBpID49IDA7IGktLSkgewogICAgICBpZiAodG5zSW5mby0+Y29lZltzdWJCbG9ja051bWJlcl1bSElGSUxUXVtpXSAhPSAwKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KCiAgICB0bnNJbmZvLT5vcmRlcltzdWJCbG9ja051bWJlcl1bSElGSUxUXSA9IGkgKyAxOwoKICAgIHN1bVNxckNvZWYgPSAwOwogICAgZm9yICg7IGkgPj0gMDsgaS0tKSB7CiAgICAgIHN1bVNxckNvZWYgKz0gdG5zSW5mby0+Y29lZltzdWJCbG9ja051bWJlcl1bSElGSUxUXVtpXSAqIHRuc0luZm8tPmNvZWZbc3ViQmxvY2tOdW1iZXJdW0hJRklMVF1baV07CiAgICB9CgogICAgdG5zSW5mby0+ZGlyZWN0aW9uW3N1YkJsb2NrTnVtYmVyXVtISUZJTFRdID0gdEMtPmNvbmZUYWIudG5zRmlsdGVyRGlyZWN0aW9uW0hJRklMVF07CiAgICB0bnNJbmZvLT5sZW5ndGhbc3ViQmxvY2tOdW1iZXJdW0hJRklMVF0gPSBzZmJDbnQgLSB0Qy0+bHBjU3RhcnRCYW5kW0hJRklMVF07CgogICAgLyogZGlzYWJsZSBUTlMgaWYgcHJlZGljdGlvbkdhaW4gaXMgbGVzcyB0aGFuIDNkQiBvciBzdW1TcXJDb2VmIGlzIHRvbyBzbWFsbCAqLwogICAgaWYgKCh0c2JpLT5wcmVkaWN0aW9uR2FpbltISUZJTFRdID4gdEMtPmNvbmZUYWIudGhyZXNoT25bSElGSUxUXSkgfHwgKHN1bVNxckNvZWYgPiAodEMtPmNvbmZUYWIudG5zTGltaXRPcmRlcltISUZJTFRdLzIgKyAyKSkpCiAgICB7CiAgICAgIHRzYmktPnRuc0FjdGl2ZVtISUZJTFRdID0gVFJVRTsKICAgICAgdG5zSW5mby0+bnVtT2ZGaWx0ZXJzW3N1YkJsb2NrTnVtYmVyXSsrOwoKICAgICAgLyogY29tcHV0ZSBzZWNvbmQgZmlsdGVyIGZvciBsb3dlciBxdWFydGVyOyBvbmx5IGFsbG93ZWQgZm9yIGxvbmcgd2luZG93cyEgKi8KICAgICAgaWYgKCAoYmxvY2tUeXBlICE9IFNIT1JUX1dJTkRPVykgJiYKICAgICAgICAgICAodEMtPmNvbmZUYWIuZmlsdGVyRW5hYmxlZFtMT0ZJTFRdKSAmJiAodEMtPmNvbmZUYWIuc2VwZXJhdGVGaWx0ZXJzQWxsb3dlZCkgKQogICAgICB7CiAgICAgICAgLyogY29tcHV0ZSBzZWNvbmQgZmlsdGVyIGZvciBsb3dlciBmcmVxdWVuY2llcyAqLwoKICAgICAgICAvKiBjb21wdXRlIFROUyBmaWx0ZXIgaW4gbGF0dGljZSAoUGFyQ29yKSBmb3JtIHdpdGggTGVSb3V4LUd1ZWd1ZW4gYWxnb3JpdGhtICovCiAgICAgICAgSU5UIHByZWRHYWluID0gRkRLYWFjRW5jX0F1dG9Ub1BhcmNvcihyeHgxLCBwYXJjb3JfdG1wLCB0Qy0+Y29uZlRhYi50bnNMaW1pdE9yZGVyW0xPRklMVF0pOwoKICAgICAgICAvKiBub24tbGluZWFyIHF1YW50aXphdGlvbiBvZiBUTlMgbGF0dGljZSBjb2VmZmljaWVudHMgd2l0aCBnaXZlbiByZXNvbHV0aW9uICovCiAgICAgICAgRkRLYWFjRW5jX1BhcmNvcjJJbmRleCgKICAgICAgICAgICAgICAgIHBhcmNvcl90bXAsCiAgICAgICAgICAgICAgICB0bnNJbmZvLT5jb2VmW3N1YkJsb2NrTnVtYmVyXVtMT0ZJTFRdLAogICAgICAgICAgICAgICAgdEMtPmNvbmZUYWIudG5zTGltaXRPcmRlcltMT0ZJTFRdLAogICAgICAgICAgICAgICAgdEMtPmNvZWZSZXMpOwoKICAgICAgICAvKiByZWR1Y2UgZmlsdGVyIG9yZGVyIGJ5IHRydW5jYXRpbmcgdHJhaWxpbmcgemVyb3MsIGNvbXB1dGUgc3VtKGFicyhjb2VmcykpICovCiAgICAgICAgZm9yIChpID0gdEMtPmNvbmZUYWIudG5zTGltaXRPcmRlcltMT0ZJTFRdIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgIGlmICh0bnNJbmZvLT5jb2VmW3N1YkJsb2NrTnVtYmVyXVtMT0ZJTFRdW2ldICE9IDApIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHRuc0luZm8tPm9yZGVyW3N1YkJsb2NrTnVtYmVyXVtMT0ZJTFRdID0gaSArIDE7CgogICAgICAgIHN1bVNxckNvZWYgPSAwOwogICAgICAgIGZvciAoOyBpID49IDA7IGktLSkgewogICAgICAgICAgc3VtU3FyQ29lZiArPSB0bnNJbmZvLT5jb2VmW3N1YkJsb2NrTnVtYmVyXVtMT0ZJTFRdW2ldICogdG5zSW5mby0+Y29lZltzdWJCbG9ja051bWJlcl1bTE9GSUxUXVtpXTsKICAgICAgICB9CgogICAgICAgIHRuc0luZm8tPmRpcmVjdGlvbltzdWJCbG9ja051bWJlcl1bTE9GSUxUXSA9IHRDLT5jb25mVGFiLnRuc0ZpbHRlckRpcmVjdGlvbltMT0ZJTFRdOwogICAgICAgIHRuc0luZm8tPmxlbmd0aFtzdWJCbG9ja051bWJlcl1bTE9GSUxUXSA9IHRDLT5scGNTdGFydEJhbmRbSElGSUxUXSAtIHRDLT5scGNTdGFydEJhbmRbTE9GSUxUXTsKCiAgICAgICAgLyogZmlsdGVyIGxvd2VyIHF1YXJ0ZXIgaWYgZ2FpbiBpcyBoaWdoIGVub3VnaCwgYnV0IG5vdCBpZiBpdCdzIHRvbyBoaWdoICovCiAgICAgICAgaWYgKCAoIChwcmVkR2FpbiA+IHRDLT5jb25mVGFiLnRocmVzaE9uW0xPRklMVF0pICYmIChwcmVkR2FpbiA8ICgxNjAwMCAqIHRDLT5jb25mVGFiLnRuc0xpbWl0T3JkZXJbTE9GSUxUXSkpICkKICAgICAgICAgIHx8ICggKHN1bVNxckNvZWYgPiA5KSAgJiYgKHN1bVNxckNvZWYgPCAyMiAqIHRDLT5jb25mVGFiLnRuc0xpbWl0T3JkZXJbTE9GSUxUXSkgKSApCiAgICAgICAgewogICAgICAgICAgLyogY29tcGFyZSBsb3dlciB0byB1cHBlciBmaWx0ZXI7IGlmIHRoZXkgYXJlIHZlcnkgc2ltaWxhciwgbWVyZ2UgdGhlbSAqLwogICAgICAgICAgdHNiaS0+dG5zQWN0aXZlW0xPRklMVF0gPSBUUlVFOwogICAgICAgICAgc3VtU3FyQ29lZiA9IDA7CiAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdEMtPmNvbmZUYWIudG5zTGltaXRPcmRlcltMT0ZJTFRdOyBpKyspIHsKICAgICAgICAgICAgc3VtU3FyQ29lZiArPSBGREthYnModG5zSW5mby0+Y29lZltzdWJCbG9ja051bWJlcl1bSElGSUxUXVtpXSAtIHRuc0luZm8tPmNvZWZbc3ViQmxvY2tOdW1iZXJdW0xPRklMVF1baV0pOwogICAgICAgICAgfQogICAgICAgICAgaWYgKCAoc3VtU3FyQ29lZiA8IDIpICYmCiAgICAgICAgICAgICAgICh0bnNJbmZvLT5kaXJlY3Rpb25bc3ViQmxvY2tOdW1iZXJdW0xPRklMVF0gPT0gdG5zSW5mby0+ZGlyZWN0aW9uW3N1YkJsb2NrTnVtYmVyXVtISUZJTFRdKSApCiAgICAgICAgICB7CiAgICAgICAgICAgIHRuc0RhdGEtPmZpbHRlcnNNZXJnZWQgPSBUUlVFOwogICAgICAgICAgICB0bnNJbmZvLT5sZW5ndGhbc3ViQmxvY2tOdW1iZXJdW0hJRklMVF0gPSBzZmJDbnQgLSB0Qy0+bHBjU3RhcnRCYW5kW0xPRklMVF07CiAgICAgICAgICAgIGZvciAoOyBpIDwgdG5zSW5mby0+b3JkZXJbc3ViQmxvY2tOdW1iZXJdW0hJRklMVF07IGkrKykgewogICAgICAgICAgICAgIGlmIChGREthYnModG5zSW5mby0+Y29lZltzdWJCbG9ja051bWJlcl1bSElGSUxUXVtpXSkgPiAxKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yIChpLS07IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgICAgICAgaWYgKHRuc0luZm8tPmNvZWZbc3ViQmxvY2tOdW1iZXJdW0hJRklMVF1baV0gIT0gMCkgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpIDwgdG5zSW5mby0+b3JkZXJbc3ViQmxvY2tOdW1iZXJdW0hJRklMVF0pIHsKICAgICAgICAgICAgICB0bnNJbmZvLT5vcmRlcltzdWJCbG9ja051bWJlcl1bSElGSUxUXSA9IGkgKyAxOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgdG5zSW5mby0+bnVtT2ZGaWx0ZXJzW3N1YkJsb2NrTnVtYmVyXSsrOwogICAgICAgICAgfQogICAgICAgIH0gLyogZmlsdGVyIGxvd2VyIHBhcnQgKi8KICAgICAgICB0c2JpLT5wcmVkaWN0aW9uR2FpbltMT0ZJTFRdPXByZWRHYWluOwoKICAgICAgfSAvKiBzZWNvbmQgZmlsdGVyIGFsbG93ZWQgICovCiAgICB9IC8qIGlmIHByZWRpY3Rpb25HYWluID4gMTQzNyAuLi4gKi8KICB9IC8qIG1heE9yZGVyID4gMCAmJiB0bnNBY3RpdmUgKi8KCiAgcmV0dXJuIDA7Cgp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBGREthYWNMZEVuY19UbnNTeW5jCgogIHN5bmNocm9uaXplIFROUyBwYXJhbWV0ZXJzIHdoZW4gVE5TIGdhaW4gZGlmZmVyZW5jZSBzbWFsbCAocmVsYXRpdmUpCgogIFxwYXJhbSBwb2ludGVyIHRvIFROUyBkYXRhIHN0cnVjdHVyZSAoZGVzdGluYXRpb24pCiAgXHBhcmFtIHBvaW50ZXIgdG8gVE5TIGRhdGEgc3RydWN0dXJlIChzb3VyY2UpCiAgXHBhcmFtIHBvaW50ZXIgdG8gVE5TIGNvbmZpZyBzdHJ1Y3R1cmUKICBccGFyYW0gbnVtYmVyIG9mIHN1Yi1ibG9jawogIFxwYXJhbSBibG9jayB0eXBlCgogIFxyZXR1cm4gdm9pZAoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkIEZES2FhY0VuY19UbnNTeW5jKAogICAgICAgICAgICAgVE5TX0RBVEEgKnRuc0RhdGFEZXN0LAogICAgICAgICAgICAgY29uc3QgVE5TX0RBVEEgKnRuc0RhdGFTcmMsCiAgICAgICAgICAgICBUTlNfSU5GTyAqdG5zSW5mb0Rlc3QsCiAgICAgICAgICAgICBUTlNfSU5GTyAqdG5zSW5mb1NyYywKICAgICAgICAgICAgIGNvbnN0IElOVCBibG9ja1R5cGVEZXN0LAogICAgICAgICAgICAgY29uc3QgSU5UIGJsb2NrVHlwZVNyYywKICAgICAgICAgICAgIGNvbnN0IFROU19DT05GSUcgKnRDCiAgICAgICAgICAgICApCnsKICBpbnQgaSwgdywgYWJzRGlmZiwgbldpbmRvd3M7CiAgVE5TX1NVQkJMT0NLX0lORk8gKnNiSW5mb0Rlc3Q7CiAgY29uc3QgVE5TX1NVQkJMT0NLX0lORk8gKnNiSW5mb1NyYzsKCiAgLyogaWYgb25lIGNoYW5uZWwgY29udGFpbnMgc2hvcnQgYmxvY2tzIGFuZCB0aGUgb3RoZXIgbm90LCBkbyBub3Qgc3luY2hyb25pemUgKi8KICBpZiAoIChibG9ja1R5cGVTcmMgPT0gU0hPUlRfV0lORE9XICYmIGJsb2NrVHlwZURlc3QgIT0gU0hPUlRfV0lORE9XKSB8fAogICAgICAgKGJsb2NrVHlwZURlc3QgPT0gU0hPUlRfV0lORE9XICYmIGJsb2NrVHlwZVNyYyAhPSBTSE9SVF9XSU5ET1cpICkKICB7CiAgICByZXR1cm47CiAgfQoKICBpZiAoYmxvY2tUeXBlRGVzdCAhPSBTSE9SVF9XSU5ET1cpIHsKICAgIHNiSW5mb0Rlc3QgPSAmdG5zRGF0YURlc3QtPmRhdGFSYXcuTG9uZy5zdWJCbG9ja0luZm87CiAgICBzYkluZm9TcmMgID0gJnRuc0RhdGFTcmMtPmRhdGFSYXcuTG9uZy5zdWJCbG9ja0luZm87CiAgICBuV2luZG93cyAgID0gMTsKICB9IGVsc2UgewogICAgc2JJbmZvRGVzdCA9ICZ0bnNEYXRhRGVzdC0+ZGF0YVJhdy5TaG9ydC5zdWJCbG9ja0luZm9bMF07CiAgICBzYkluZm9TcmMgID0gJnRuc0RhdGFTcmMtPmRhdGFSYXcuU2hvcnQuc3ViQmxvY2tJbmZvWzBdOwogICAgbldpbmRvd3MgICA9IDg7CiAgfQoKICBmb3IgKHc9MDsgdzxuV2luZG93czsgdysrKSB7CiAgICAgIGNvbnN0IFROU19TVUJCTE9DS19JTkZPICpwU2JJbmZvU3JjVyAgPSBzYkluZm9TcmMgICsgdzsKICAgICAgVE5TX1NVQkJMT0NLX0lORk8gICAgICAgKnBTYkluZm9EZXN0VyA9IHNiSW5mb0Rlc3QgKyB3OwogICAgICBJTlQgZG9TeW5jID0gMSwgYWJzRGlmZlN1bSA9IDA7CgogICAgICAvKiBpZiBUTlMgaXMgYWN0aXZlIGluIGF0IGxlYXN0IG9uZSBjaGFubmVsLCBjaGVjayBpZiBQYXJDb3IgY29lZmZpY2llbnRzIG9mIGhpZ2hlciBmaWx0ZXIgYXJlIHNpbWlsYXIgKi8KICAgICAgaWYgKHBTYkluZm9EZXN0Vy0+dG5zQWN0aXZlW0hJRklMVF0gfHwgcFNiSW5mb1NyY1ctPnRuc0FjdGl2ZVtISUZJTFRdKSB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IHRDLT5tYXhPcmRlcjsgaSsrKSB7CiAgICAgICAgICBhYnNEaWZmID0gRkRLYWJzKHRuc0luZm9EZXN0LT5jb2VmW3ddW0hJRklMVF1baV0gLSB0bnNJbmZvU3JjLT5jb2VmW3ddW0hJRklMVF1baV0pOwogICAgICAgICAgYWJzRGlmZlN1bSArPSBhYnNEaWZmOwogICAgICAgICAgLyogaWYgY29lZmZpY2llbnRzIGRpdmVyZ2UgdG9vIG11Y2ggYmV0d2VlbiBjaGFubmVscywgZG8gbm90IHN5bmNocm9uaXplICovCiAgICAgICAgICBpZiAoKGFic0RpZmYgPiAxKSB8fCAoYWJzRGlmZlN1bSA+IDIpKSB7CiAgICAgICAgICAgIGRvU3luYyA9IDA7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGRvU3luYykgewogICAgICAgICAgICAvKiBpZiBubyBzaWduaWZpY2FudCBkaWZmZXJlbmNlIHdhcyBkZXRlY3RlZCwgc3luY2hyb25pemUgY29lZmZpY2llbnQgc2V0cyAqLwogICAgICAgICAgICBpZiAocFNiSW5mb1NyY1ctPnRuc0FjdGl2ZVtISUZJTFRdKSB7CiAgICAgICAgICAgICAgLyogbm8gZGVzdCBmaWx0ZXIsIG9yIG1vcmUgZGVzdCB0aGFuIHNvdXJjZSBmaWx0ZXJzOiB1c2Ugb25lIGRlc3QgZmlsdGVyICovCiAgICAgICAgICAgICAgaWYgKCghcFNiSW5mb0Rlc3RXLT50bnNBY3RpdmVbSElGSUxUXSkgfHwKICAgICAgICAgICAgICAgICAgKChwU2JJbmZvRGVzdFctPnRuc0FjdGl2ZVtISUZJTFRdKSAmJiAodG5zSW5mb0Rlc3QtPm51bU9mRmlsdGVyc1t3XSA+IHRuc0luZm9TcmMtPm51bU9mRmlsdGVyc1t3XSkpKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHBTYkluZm9EZXN0Vy0+dG5zQWN0aXZlW0hJRklMVF0gPSB0bnNJbmZvRGVzdC0+bnVtT2ZGaWx0ZXJzW3ddID0gMTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgdG5zRGF0YURlc3QtPmZpbHRlcnNNZXJnZWQgPSB0bnNEYXRhU3JjLT5maWx0ZXJzTWVyZ2VkOwogICAgICAgICAgICAgIHRuc0luZm9EZXN0LT5vcmRlciAgICAgICBbd11bSElGSUxUXSA9IHRuc0luZm9TcmMtPm9yZGVyICAgICAgIFt3XVtISUZJTFRdOwogICAgICAgICAgICAgIHRuc0luZm9EZXN0LT5sZW5ndGggICAgICBbd11bSElGSUxUXSA9IHRuc0luZm9TcmMtPmxlbmd0aCAgICAgIFt3XVtISUZJTFRdOwogICAgICAgICAgICAgIHRuc0luZm9EZXN0LT5kaXJlY3Rpb24gICBbd11bSElGSUxUXSA9IHRuc0luZm9TcmMtPmRpcmVjdGlvbiAgIFt3XVtISUZJTFRdOwogICAgICAgICAgICAgIHRuc0luZm9EZXN0LT5jb2VmQ29tcHJlc3Nbd11bSElGSUxUXSA9IHRuc0luZm9TcmMtPmNvZWZDb21wcmVzc1t3XVtISUZJTFRdOwoKICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdEMtPm1heE9yZGVyOyBpKyspIHsKICAgICAgICAgICAgICAgIHRuc0luZm9EZXN0LT5jb2VmW3ddW0hJRklMVF1baV0gPSB0bnNJbmZvU3JjLT5jb2VmW3ddW0hJRklMVF1baV07CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICBwU2JJbmZvRGVzdFctPnRuc0FjdGl2ZVtISUZJTFRdID0gdG5zSW5mb0Rlc3QtPm51bU9mRmlsdGVyc1t3XSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIEZES2FhY0VuY19UbnNFbmNvZGUKCiAgcGVyZm9ybSBUTlMgZW5jb2RpbmcKCiAgXHBhcmFtIHBvaW50ZXIgdG8gVE5TIGluZm8gc3RydWN0dXJlCiAgXHBhcmFtIHBvaW50ZXIgdG8gVE5TIGRhdGEgc3RydWN0dXJlCiAgXHBhcmFtIG51bWJlciBvZiBzZmJzCiAgXHBhcmFtIHBvaW50ZXIgdG8gVE5TIGNvbmZpZyBzdHJ1Y3R1cmUKICBccGFyYW0gbG93LXBhc3MgbGluZQogIFxwYXJhbSBwb2ludGVyIHRvIHNwZWN0cnVtCiAgXHBhcmFtIG51bWJlciBvZiBzdWItYmxvY2sKICBccGFyYW0gYmxvY2sgdHlwZQoKICBccmV0dXJuIEVSUk9SIFNUQVRVUwoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpJTlQgRkRLYWFjRW5jX1Ruc0VuY29kZSgKICAgICAgICBUTlNfSU5GTyogdG5zSW5mbywKICAgICAgICBUTlNfREFUQSogdG5zRGF0YSwKICAgICAgICBjb25zdCBJTlQgbnVtT2ZTZmIsCiAgICAgICAgY29uc3QgVE5TX0NPTkZJRyAqdEMsCiAgICAgICAgY29uc3QgSU5UIGxvd1Bhc3NMaW5lLAogICAgICAgIEZJWFBfREJMKiBzcGVjdHJ1bSwKICAgICAgICBjb25zdCBJTlQgc3ViQmxvY2tOdW1iZXIsCiAgICAgICAgY29uc3QgSU5UIGJsb2NrVHlwZQogICAgICAgICkKewogICAgSU5UIGksIHN0YXJ0TGluZSwgc3RvcExpbmU7CgogICAgaWYgKCAoIChibG9ja1R5cGUgPT0gU0hPUlRfV0lORE9XKSAmJiAoIXRuc0RhdGEtPmRhdGFSYXcuU2hvcnQuc3ViQmxvY2tJbmZvW3N1YkJsb2NrTnVtYmVyXS50bnNBY3RpdmVbSElGSUxUXSkgKQogICAgICB8fCAoIChibG9ja1R5cGUgIT0gU0hPUlRfV0lORE9XKSAmJiAoIXRuc0RhdGEtPmRhdGFSYXcuTG9uZy5zdWJCbG9ja0luZm8udG5zQWN0aXZlW0hJRklMVF0pICkgKQogICAgewogICAgICByZXR1cm4gMTsKICAgIH0KCiAgICBzdGFydExpbmUgPSAodG5zRGF0YS0+ZmlsdGVyc01lcmdlZCkgPyB0Qy0+bHBjU3RhcnRMaW5lW0xPRklMVF0gOiB0Qy0+bHBjU3RhcnRMaW5lW0hJRklMVF07CiAgICBzdG9wTGluZSAgPSB0Qy0+bHBjU3RvcExpbmU7CgogICAgZm9yIChpPTA7IGk8dG5zSW5mby0+bnVtT2ZGaWx0ZXJzW3N1YkJsb2NrTnVtYmVyXTsgaSsrKSB7CgogICAgICAgIElOVCBscGNHYWluRmFjdG9yOwogICAgICAgIEZJWFBfREJMIExwY0NvZWZmW1ROU19NQVhfT1JERVJdOwogICAgICAgIEZJWFBfREJMIHdvcmtCdWZmZXJbVE5TX01BWF9PUkRFUl07CiAgICAgICAgRklYUF9EQkwgcGFyY29yX3RtcFtUTlNfTUFYX09SREVSXTsKCiAgICAgICAgRkRLYWFjRW5jX0luZGV4MlBhcmNvcigKICAgICAgICAgICAgICAgIHRuc0luZm8tPmNvZWZbc3ViQmxvY2tOdW1iZXJdW2ldLAogICAgICAgICAgICAgICAgcGFyY29yX3RtcCwKICAgICAgICAgICAgICAgIHRuc0luZm8tPm9yZGVyW3N1YkJsb2NrTnVtYmVyXVtpXSwKICAgICAgICAgICAgICAgIHRDLT5jb2VmUmVzKTsKCiAgICAgICAgbHBjR2FpbkZhY3RvciA9IEZES2FhY0VuY19QYXJjb3JUb0xwYygKICAgICAgICAgICAgICAgIHBhcmNvcl90bXAsCiAgICAgICAgICAgICAgICBMcGNDb2VmZiwKICAgICAgICAgICAgICAgIHRuc0luZm8tPm9yZGVyW3N1YkJsb2NrTnVtYmVyXVtpXSwKICAgICAgICAgICAgICAgIHdvcmtCdWZmZXIpOwoKICAgICAgICBGREthYWNFbmNfQW5hbHlzaXNGaWx0ZXIoCiAgICAgICAgICAgICAgICAmc3BlY3RydW1bc3RhcnRMaW5lXSwKICAgICAgICAgICAgICAgIHN0b3BMaW5lIC0gc3RhcnRMaW5lLAogICAgICAgICAgICAgICAgTHBjQ29lZmYsCiAgICAgICAgICAgICAgICB0bnNJbmZvLT5vcmRlcltzdWJCbG9ja051bWJlcl1baV0sCiAgICAgICAgICAgICAgICBscGNHYWluRmFjdG9yKTsKCiAgICAgICAgLyogdXBkYXRlIGZvciBzZWNvbmQgZmlsdGVyICovCiAgICAgICAgc3RhcnRMaW5lID0gdEMtPmxwY1N0YXJ0TGluZVtMT0ZJTFRdOwogICAgICAgIHN0b3BMaW5lICA9IHRDLT5scGNTdGFydExpbmVbSElGSUxUXTsKICAgIH0KCiAgICByZXR1cm4oMCk7Cgp9CgpzdGF0aWMgdm9pZCBGREthYWNFbmNfQ2FsY0dhdXNzV2luZG93KAogICAgICAgIEZJWFBfREJMICp3aW4sCiAgICAgICAgY29uc3QgaW50IHdpblNpemUsCiAgICAgICAgY29uc3QgSU5UIHNhbXBsaW5nUmF0ZSwKICAgICAgICBjb25zdCBJTlQgdHJhbnNmb3JtUmVzb2x1dGlvbiwKICAgICAgICBjb25zdCBGSVhQX0RCTCB0aW1lUmVzb2x1dGlvbiwKICAgICAgICBjb25zdCBJTlQgdGltZVJlc29sdXRpb25fZQogICAgICAgICkKewogICNkZWZpbmUgUElfRSAgICAgICAgICAgKDIpCiAgI2RlZmluZSBQSV9NICAgICAgICAgICBGTDJGWENPTlNUX0RCTCgzLjE0MTZmLyhmbG9hdCkoMTw8UElfRSkpCgogICNkZWZpbmUgRVVMRVJfRSAgICAgICAgKDIpCiAgI2RlZmluZSBFVUxFUl9NICAgICAgICBGTDJGWENPTlNUX0RCTCgyLjcxODMvKGZsb2F0KSgxPDxFVUxFUl9FKSkKCiAgI2RlZmluZSBDT0VGRl9MT09QX1NDQUxFICg0KQoKICBJTlQgaSwgZTEsIGUyLCBnYXVzc0V4cF9lOwogIEZJWFBfREJMIGdhdXNzRXhwX207CgogIC8qIGNhbGMuIHdpbmRvdyBleHBvbmVudCBmcm9tIHRpbWUgcmVzb2x1dGlvbjoKICAgKgogICAqICAgZ2F1c3NFeHAgPSBQSSAqIHNhbXBsaW5nUmF0ZSAqIDAuMDAxZiAqIHRpbWVSZXNvbHV0aW9uIC8gdHJhbnNmb3JtUmVzb2x1dGlvbjsKICAgKiAgIGdhdXNzRXhwID0gLTAuNWYgKiBnYXVzc0V4cCAqIGdhdXNzRXhwOwogICAqLwogIGdhdXNzRXhwX20gPSBmTXVsdE5vcm0odGltZVJlc29sdXRpb24sIGZNdWx0KFBJX00sIGZEaXZOb3JtKCAoRklYUF9EQkwpKHNhbXBsaW5nUmF0ZSksIChGSVhQX0RCTCkoTE9ORykodHJhbnNmb3JtUmVzb2x1dGlvbioxMDAwLmYpLCAmZTEpKSwgJmUyKTsKICBnYXVzc0V4cF9tID0gLWZQb3cyRGl2MihnYXVzc0V4cF9tKTsKICBnYXVzc0V4cF9lID0gMiooZTErZTIrdGltZVJlc29sdXRpb25fZStQSV9FKTsKCiAgRkRLX0FTU0VSVCggd2luU2l6ZSA8ICgxPDxDT0VGRl9MT09QX1NDQUxFKSApOwoKICAvKiBjYWxjLiB3aW5kb3cgY29lZmZpY2llbnRzCiAgICogICB3aW5baV0gPSAoZmxvYXQpZXhwKCBnYXVzc0V4cCAqIChpKzAuNSkgKiAoaSswLjUpICk7CiAgICovCiAgZm9yKCBpPTA7IGk8d2luU2l6ZTsgaSsrKSB7CgogICAgd2luW2ldID0gZlBvdygKICAgICAgICAgICAgRVVMRVJfTSwKICAgICAgICAgICAgRVVMRVJfRSwKICAgICAgICAgICAgZk11bHQoZ2F1c3NFeHBfbSwgZlBvdzIoKGkqRkwyRlhDT05TVF9EQkwoMS5mLyhmbG9hdCkoMTw8Q09FRkZfTE9PUF9TQ0FMRSkpICsgRkwyRlhDT05TVF9EQkwoLjVmLyhmbG9hdCkoMTw8Q09FRkZfTE9PUF9TQ0FMRSkpKSkpLAogICAgICAgICAgICBnYXVzc0V4cF9lICsgMipDT0VGRl9MT09QX1NDQUxFLAogICAgICAgICAgICZlMSk7CgogICAgd2luW2ldID0gc2NhbGVWYWx1ZVNhdHVyYXRlKHdpbltpXSwgZTEpOwogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgRkRLYWFjRW5jX0F1dG9Ub1BhcmNvcgoKICBjb252ZXJzaW9uIGF1dG9jb3JyZWxhdGlvbiB0byByZWZsZWN0aW9uIGNvZWZmaWNpZW50cwoKICBccGFyYW0gcG9pbnRlciB0byBpbnB1dCAoYWNmKQogIFxwYXJhbSBwb2ludGVyIHRvIG91dHB1dCAocmVmbGVjdGlvbiBjb2VmZmljaWVudHMpCiAgXHBhcmFtIG51bWJlciBvZiBjb2VmZmljaWVudHMKCiAgXHJldHVybiBwcmVkaWN0aW9uIGdhaW4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIElOVCBGREthYWNFbmNfQXV0b1RvUGFyY29yKAogICAgICAgIEZJWFBfREJMICpSRVNUUklDVCBpbnB1dCwKICAgICAgICBGSVhQX0RCTCAqUkVTVFJJQ1QgcmVmbENvZWZmLAogICAgICAgIGNvbnN0IElOVCBudW1PZkNvZWZmCiAgICAgICAgKQp7CiAgSU5UICAgICAgIGksIGosIHNjYWxlPTA7CiAgRklYUF9EQkwgIHRtcCwgcGFyY29yV29ya0J1ZmZlcltUTlNfTUFYX09SREVSXTsKICBJTlQgICAgICAgcHJlZGljdGlvbkdhaW4gPSAoSU5UKShUTlNfUFJFREdBSU5fU0NBTEUpOwoKICBGSVhQX0RCTCAqUkVTVFJJQ1Qgd29ya0J1ZmZlciA9IHBhcmNvcldvcmtCdWZmZXI7CiAgY29uc3QgRklYUF9EQkwgIGF1dG9Db3JyXzAgPSBpbnB1dFswXTsKCiAgRkRLbWVtY2xlYXIocmVmbENvZWZmLG51bU9mQ29lZmYqc2l6ZW9mKEZJWFBfREJMKSk7CgogIGlmKChGSVhQX0RCTClpbnB1dFswXSA9PSBGTDJGWENPTlNUX0RCTCgwLjApKSB7CiAgICByZXR1cm4ocHJlZGljdGlvbkdhaW4pOwogIH0KCiAgRkRLbWVtY3B5KHdvcmtCdWZmZXIsJmlucHV0WzFdLG51bU9mQ29lZmYqc2l6ZW9mKEZJWFBfREJMKSk7CiAgZm9yKGk9MDsgaTxudW1PZkNvZWZmOyBpKyspIHsKICAgIExPTkcgc2lnbiA9ICgoTE9ORyl3b3JrQnVmZmVyWzBdID4+IChERlJBQ1RfQklUUy0xKSk7CiAgICB0bXAgPSAoRklYUF9EQkwpKChMT05HKXdvcmtCdWZmZXJbMF1ec2lnbik7CgogICAgaWYoaW5wdXRbMF08dG1wKQogICAgICBicmVhazsKCiAgICB0bXAgPSAoRklYUF9EQkwpKChMT05HKXNjaHVyX2Rpdih0bXAsIGlucHV0WzBdLCBGUkFDVF9CSVRTKV4ofnNpZ24pKTsKICAgIHJlZmxDb2VmZltpXSA9IHRtcDsKCiAgICBmb3Ioaj1udW1PZkNvZWZmLWktMTsgaj49MDsgai0tKSB7CiAgICAgIEZJWFBfREJMIGFjY3UxID0gZk11bHQodG1wLCBpbnB1dFtqXSk7CiAgICAgIEZJWFBfREJMIGFjY3UyID0gZk11bHQodG1wLCB3b3JrQnVmZmVyW2pdKTsKICAgICAgd29ya0J1ZmZlcltqXSArPSBhY2N1MTsKICAgICAgaW5wdXRbal0gKz0gYWNjdTI7CiAgICB9CgogICAgd29ya0J1ZmZlcisrOwogIH0KCiAgdG1wID0gZk11bHQoKEZJWFBfREJMKSgoTE9ORylUTlNfUFJFREdBSU5fU0NBTEU8PDIxKSwgZkRpdk5vcm0oZkFicyhhdXRvQ29ycl8wKSwgZkFicyhpbnB1dFswXSksICZzY2FsZSkpOwogIGlmICggZk11bHREaXYyKGF1dG9Db3JyXzAsIGlucHV0WzBdKTxGTDJGWENPTlNUX0RCTCgwLjBmKSApIHsKICAgIHRtcCA9IC10bXA7CiAgfQogIHByZWRpY3Rpb25HYWluID0gKExPTkcpc2NhbGVWYWx1ZSh0bXAsc2NhbGUtMjEpOwoKICByZXR1cm4gKHByZWRpY3Rpb25HYWluKTsKfQoKCnN0YXRpYyBJTlQgRkRLYWFjRW5jX1NlYXJjaDMoRklYUF9EQkwgcGFyY29yKQp7CiAgSU5UIGksIGluZGV4PTA7CgogIGZvcihpPTA7aTw4O2krKyl7CiAgICBpZihwYXJjb3IgPiBGREthYWNFbmNfdG5zQ29lZmYzQm9yZGVyc1tpXSkKICAgICAgaW5kZXg9aTsKICB9CiAgcmV0dXJuKGluZGV4LTQpOwp9CgpzdGF0aWMgSU5UIEZES2FhY0VuY19TZWFyY2g0KEZJWFBfREJMIHBhcmNvcikKewogIElOVCBpLCBpbmRleD0wOwoKICBmb3IoaT0wO2k8MTY7aSsrKXsKICAgIGlmKHBhcmNvciA+IEZES2FhY0VuY190bnNDb2VmZjRCb3JkZXJzW2ldKQogICAgICBpbmRleD1pOwogIH0KICByZXR1cm4oaW5kZXgtOCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19QYXJjb3IySW5kZXgKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBGREthYWNFbmNfUGFyY29yMkluZGV4KAogICAgICAgIGNvbnN0IEZJWFBfREJMICpwYXJjb3IsCiAgICAgICAgSU5UICpSRVNUUklDVCBpbmRleCwKICAgICAgICBjb25zdCBJTlQgb3JkZXIsCiAgICAgICAgY29uc3QgSU5UIGJpdHNQZXJDb2VmZgogICAgICAgICkKewogIElOVCBpOwogIGZvcihpPTA7IGk8b3JkZXI7IGkrKykgewogICAgaWYoYml0c1BlckNvZWZmID09IDMpCiAgICAgIGluZGV4W2ldID0gRkRLYWFjRW5jX1NlYXJjaDMocGFyY29yW2ldKTsKICAgIGVsc2UKICAgICAgaW5kZXhbaV0gPSBGREthYWNFbmNfU2VhcmNoNChwYXJjb3JbaV0pOwogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX0luZGV4MlBhcmNvcgogICAgZGVzY3JpcHRpb246ICBpbnZlcnNlIHF1YW50aXphdGlvbiBmb3IgcmVmbGVjdGlvbiBjb2VmZmljaWVudHMKICAgIHJldHVybnM6ICAgICAgLQogICAgaW5wdXQ6ICAgICAgICBxdWFudGl6ZWQgdmFsdWVzLCBwdHIuIHRvIHJlZmxlY3Rpb24gY29lZmZpY2llbnRzLAogICAgICAgICAgICAgICAgICBuby4gb2YgY29lZmZpY2llbnRzLCByZXNvbHV0aW9uCiAgICBvdXRwdXQ6ICAgICAgIHJlZmxlY3Rpb24gY29lZmZpY2llbnRzCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgRkRLYWFjRW5jX0luZGV4MlBhcmNvcigKICAgICAgICBjb25zdCBJTlQgKmluZGV4LAogICAgICAgIEZJWFBfREJMICpSRVNUUklDVCBwYXJjb3IsCiAgICAgICAgY29uc3QgSU5UIG9yZGVyLAogICAgICAgIGNvbnN0IElOVCBiaXRzUGVyQ29lZmYKICAgICAgICApCnsKICBJTlQgaTsKICBmb3IoaT0wOyBpPG9yZGVyOyBpKyspCiAgICBwYXJjb3JbaV0gPSBiaXRzUGVyQ29lZmYgPT0gNCA/IEZES2FhY0VuY190bnNFbmNDb2VmZjRbaW5kZXhbaV0rOF0gOiBGREthYWNFbmNfdG5zRW5jQ29lZmYzW2luZGV4W2ldKzRdOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgZnVuY3Rpb25uYW1lOiBGREthYWNFbmNfUGFyY29yVG9McGMKICAgIGRlc2NyaXB0aW9uOiAgY29udmVyc2lvbiByZWZsZWN0aW9uIGNvZWZmaWNpZW50cyB0byBMUEMgY29lZmZpY2llbnRzCiAgICByZXR1cm5zOiAgICAgIEdhaW4gZmFjdG9yCiAgICBpbnB1dDogICAgICAgIHJlZmxlY3Rpb24gY29lZmZpY2llbnRzLCBuby4gb2YgcmVmbGVjdGlvbiBjb2VmZmljaWVudHMgPG9yZGVyPiwKICAgICAgICAgICAgICAgICAgcHRyLiB0byB3b3JrIGJ1ZmZlciAocmVxdWlyZWQgc2l6ZTogb3JkZXIpCiAgICBvdXRwdXQ6ICAgICAgIDxvcmRlcj4gTFBDIGNvZWZmaWNpZW50cwoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBJTlQgRkRLYWFjRW5jX1BhcmNvclRvTHBjKAogICAgICAgIGNvbnN0IEZJWFBfREJMICpyZWZsQ29lZmYsCiAgICAgICAgRklYUF9EQkwgKlJFU1RSSUNUIExwY0NvZWZmLAogICAgICAgIGNvbnN0IElOVCBudW1PZkNvZWZmLAogICAgICAgIEZJWFBfREJMICpSRVNUUklDVCB3b3JrQnVmZmVyCiAgICAgICAgKQp7CiAgSU5UIGksIGo7CiAgSU5UIHNoaWZ0dmFsLCBwYXIyTHBjU2hpZnRWYWwgPSA2OyAgLyogNiBzaG91bGQgYmUgZW5vdWdoLCBiZWMuIG1heChudW1PZkNvZWZmKSA9IDIwICovCiAgRklYUF9EQkwgbWF4VmFsID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CgogIExwY0NvZWZmWzBdID0gcmVmbENvZWZmWzBdID4+IHBhcjJMcGNTaGlmdFZhbDsKICBmb3IoaT0xOyBpPG51bU9mQ29lZmY7IGkrKykgewogICAgZm9yKGo9MDsgajxpOyBqKyspIHsKICAgICAgICB3b3JrQnVmZmVyW2pdID0gTHBjQ29lZmZbaS0xLWpdOwogICAgfQoKICAgIGZvcihqPTA7IGo8aTsgaisrKSB7CiAgICAgICAgTHBjQ29lZmZbal0gKz0gZk11bHQocmVmbENvZWZmW2ldLHdvcmtCdWZmZXJbal0pOwogICAgfQoKICAgIExwY0NvZWZmW2ldID0gcmVmbENvZWZmW2ldID4+IHBhcjJMcGNTaGlmdFZhbDsKICB9CgogIC8qIG5vcm1hbGl6ZSBMcGNDb2VmZiBhbmQgY2FsYyBzaGlmdGZhY3RvciAqLwogIGZvcihpPTA7IGk8bnVtT2ZDb2VmZjsgaSsrKSB7CiAgICAgIG1heFZhbCA9IGZpeE1heChtYXhWYWwsKEZJWFBfREJMKWZpeHBfYWJzKExwY0NvZWZmW2ldKSk7CiAgfQoKICBzaGlmdHZhbCA9IENvdW50TGVhZGluZ0JpdHMobWF4VmFsKTsKICBzaGlmdHZhbCA9IChzaGlmdHZhbD49cGFyMkxwY1NoaWZ0VmFsKSA/IHBhcjJMcGNTaGlmdFZhbCA6IHNoaWZ0dmFsOwoKICBmb3IoaT0wOyBpPG51bU9mQ29lZmY7IGkrKykKICAgICAgTHBjQ29lZmZbaV0gPSBMcGNDb2VmZltpXTw8c2hpZnR2YWw7CgogIHJldHVybiAocGFyMkxwY1NoaWZ0VmFsIC0gc2hpZnR2YWwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIEZES2FhY0VuY19BbmFseXNpc0ZpbHRlcgoKICBUTlMgYW5hbHlzaXMgZmlsdGVyIChhbGwtemVybyBmaWx0ZXIpCgogIFxwYXJhbSBwb2ludGVyIHRvIHNpZ25hbCBzcGVjdHJ1bQogIFxwYXJhbSBudW1iZXIgb2YgbGluZXMKICBccGFyYW0gcG9pbnRlciB0byBscGMgY29lZmZpY2llbnRzCiAgXHBhcmFtIGZpbHRlciBvcmRlcgogIFxwYXJhbSBscGMgZ2FpbiBmYWN0b3IKCiAgXHJldHVybiB2b2lkCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIE5vdGU6IGluLXBsYWNlIGNvbXB1dGF0aW9uIHBvc3NpYmxlICovCnN0YXRpYyB2b2lkIEZES2FhY0VuY19BbmFseXNpc0ZpbHRlcigKICAgICAgICBGSVhQX0RCTCAqUkVTVFJJQ1Qgc2lnbmFsLAogICAgICAgIGNvbnN0IElOVCBudW1PZkxpbmVzLAogICAgICAgIGNvbnN0IEZJWFBfREJMICpwcmVkaWN0b3JDb2VmZiwKICAgICAgICBjb25zdCBJTlQgb3JkZXIsCiAgICAgICAgY29uc3QgSU5UIGxwY0dhaW5GYWN0b3IKICAgICAgICApCnsKICBGSVhQX0RCTCBzdGF0dXNWYXJbVE5TX01BWF9PUkRFUl07CiAgSU5UIGksIGo7CiAgY29uc3QgSU5UIHNoaWZ0ID0gbHBjR2FpbkZhY3RvciArIDE7ICAgICAgLyogKzEsIGJlY2F1c2UgZk11bHREaXYyICovCiAgRklYUF9EQkwgdG1wOwoKICBpZiAob3JkZXI+MCkgewoKICAgIElOVCBpZHggPSAwOwoKICAgIC8qIGtlZXAgZmlsdGVyIGNvZWZmaWNpZW50cyB0d2ljZSBhbmQgc2F2ZSBtZW1vcnkgY29weSBvcGVyYXRpb24gaW4KICAgICAgIG1vZHVsbyBzdGF0ZSBidWZmZXIgKi8KI2lmIGRlZmluZWQoQVJDSF9QUkVGRVJfTVVMVF8zMngxNikKICAgIEZJWFBfU0dMICBjb2VmZlsyKlROU19NQVhfT1JERVJdOwogICAgY29uc3QgRklYUF9TR0wgKnBDb2VmZjsKICAgIGZvcihpPTA7aTxvcmRlcjtpKyspIHsKICAgICAgY29lZmZbaV0gICAgICAgPSBGWF9EQkwyRlhfU0dMKHByZWRpY3RvckNvZWZmW2ldKTsKICAgIH0KICAgIEZES21lbWNweSgmY29lZmZbb3JkZXJdLCBjb2VmZiwgb3JkZXIqc2l6ZW9mKEZJWFBfU0dMKSk7CiNlbHNlCiAgICBGSVhQX0RCTCAgY29lZmZbMipUTlNfTUFYX09SREVSXTsKICAgIGNvbnN0IEZJWFBfREJMICpwQ29lZmY7CiAgICBGREttZW1jcHkoJmNvZWZmWzBdLCAgICAgcHJlZGljdG9yQ29lZmYsIG9yZGVyKnNpemVvZihGSVhQX0RCTCkpOwogICAgRkRLbWVtY3B5KCZjb2VmZltvcmRlcl0sIHByZWRpY3RvckNvZWZmLCBvcmRlcipzaXplb2YoRklYUF9EQkwpKTsKI2VuZGlmCiAgICBGREttZW1jbGVhcihzdGF0dXNWYXIsIG9yZGVyKnNpemVvZihGSVhQX0RCTCkpOwoKICAgIGZvcihqPTA7IGo8bnVtT2ZMaW5lczsgaisrKSB7CiAgICAgIHBDb2VmZiA9ICZjb2VmZlsob3JkZXItaWR4KV07CiAgICAgIHRtcCA9IEZMMkZYQ09OU1RfREJMKDApOwogICAgICBmb3IoaT0wOyBpPG9yZGVyOyBpKyspIHsKICAgICAgICAgIHRtcCA9IGZNdWx0QWRkRGl2Mih0bXAsIHBDb2VmZltpXSwgc3RhdHVzVmFyW2ldKSA7CiAgICAgIH0KCiAgICAgIGlmKC0taWR4PDApIHsgaWR4ID0gb3JkZXItMTsgfQogICAgICBzdGF0dXNWYXJbaWR4XSA9IHNpZ25hbFtqXTsKCiAgICAgIEZES19BU1NFUlQobHBjR2FpbkZhY3Rvcj49MCk7CiAgICAgIHNpZ25hbFtqXSA9ICh0bXA8PHNoaWZ0KSArIHNpZ25hbFtqXTsKICAgIH0KICB9Cn0KCgo=