Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEyIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogTVBFRyBBdWRpbyBFbmNvZGVyICoqKioqKioqKioqKioqKioqKioqKioqKioqCgogICBJbml0aWFsIGF1dGhvcjogICAgICAgQWxleCBHcm9lc2NoZWwKICAgY29udGVudHMvZGVzY3JpcHRpb246IFRlbXBvcmFsIG5vaXNlIHNoYXBpbmcKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJhYWNlbmNfdG5zLmgiCiNpbmNsdWRlICJwc3lfY29uc3QuaCIKI2luY2x1ZGUgInBzeV9jb25maWd1cmF0aW9uLmgiCiNpbmNsdWRlICJ0bnNfZnVuYy5oIgojaW5jbHVkZSAiYWFjRW5jX3JvbS5oIgojaW5jbHVkZSAiYWFjZW5jX3Rucy5oIgoKZW51bSB7CiAgICBISUZJTFQgPSAwLCAvKiBpbmRleCBvZiBoaWdoZXIgZmlsdGVyICovCiAgICBMT0ZJTFQgPSAxIC8qIGluZGV4IG9mIGxvd2VyIGZpbHRlciAqLwp9OwoKCiNkZWZpbmUgRklMVEVSX0RJUkVDVElPTiAwCgpzdGF0aWMgY29uc3QgRklYUF9EQkwgYWNmV2luZG93TG9uZ1sxMiszKzFdID0gewogIDB4N2ZmZmZmZmYsMHg3ZmI4MDAwMCwweDdlZTAwMDAwLDB4N2Q3ODAwMDAsMHg3YjgwMDAwMCwweDc4ZjgwMDAwLDB4NzVlMDAwMDAsMHg3MjM4MDAwMCwKICAweDZlMDAwMDAwLDB4NjkzODAwMDAsMHg2M2UwMDAwMCwweDVkZjgwMDAwLDB4NTc4MDAwMDAsMHg1MDc4MDAwMCwweDQ4ZTAwMDAwLDB4NDBiODAwMDAKfTsKCnN0YXRpYyBjb25zdCBGSVhQX0RCTCBhY2ZXaW5kb3dTaG9ydFs0KzMrMV0gPSB7CiAgMHg3ZmZmZmZmZiwweDdlMDAwMDAwLDB4NzgwMDAwMDAsMHg2ZTAwMDAwMCwweDYwMDAwMDAwLDB4NGUwMDAwMDAsMHgzODAwMDAwMCwweDFlMDAwMDAwCn07CgoKdHlwZWRlZiBzdHJ1Y3QgewogIElOVCAgICAgIGZpbHRlckVuYWJsZWRbTUFYX05VTV9PRl9GSUxURVJTXTsKICBJTlQgICAgICB0aHJlc2hPbltNQVhfTlVNX09GX0ZJTFRFUlNdOyAgICAgICAgICAgICAgICAvKiBtaW4uIHByZWRpY3Rpb24gZ2FpbiBmb3IgdXNpbmcgdG5zIFRBQlVMKi8KICBJTlQgICAgICBmaWx0ZXJTdGFydEZyZXFbTUFYX05VTV9PRl9GSUxURVJTXTsgICAgICAgICAvKiBsb3dlc3QgZnJlcSBmb3IgbHBjIFRBQlVMKi8KICBJTlQgICAgICB0bnNMaW1pdE9yZGVyW01BWF9OVU1fT0ZfRklMVEVSU107ICAgICAgICAgICAvKiBMaW1pdCBmb3IgVE5TIG9yZGVyIFRBQlVMKi8KICBJTlQgICAgICB0bnNGaWx0ZXJEaXJlY3Rpb25bTUFYX05VTV9PRl9GSUxURVJTXTsgICAgICAvKiBGaWx0ZXJpbmcgZGlyZWN0aW9uLCAwPXVwLCAxPWRvd24gVEFCVUwgKi8KICBJTlQgICAgICBhY2ZTcGxpdFtNQVhfTlVNX09GX0ZJTFRFUlNdOwogIEZJWFBfREJMIHRuc1RpbWVSZXNvbHV0aW9uW01BWF9OVU1fT0ZfRklMVEVSU107ICAgICAgIC8qIFROUyBtYXguIHRpbWUgcmVzb2x1dGlvbiBUQUJVTC4gU2hvdWxkIGJlIGZyYWN0IGJ1dCBNU1ZDIHdvbid0IGNvbXBpbGUgdGhlbiAqLwogIElOVCAgICAgIHNlcGVyYXRlRmlsdGVyc0FsbG93ZWQ7Cgp9IFROU19QQVJBTUVURVJfVEFCVUxBVEVEOwoKCnR5cGVkZWYgc3RydWN0ewogIElOVCAgICAgICAgICAgICAgICAgICAgICBiaXRSYXRlRnJvbVsyXTsgIC8qIG5vbmVTYnI9MCwgdXNlU2JyPTEgKi8KICBJTlQgICAgICAgICAgICAgICAgICAgICAgYml0UmF0ZVRvWzJdOyAgICAvKiBub25lU2JyPTAsIHVzZVNicj0xICovCiAgVE5TX1BBUkFNRVRFUl9UQUJVTEFURUQgIHBhcmFtVGFiWzJdOyAgICAgLyogbW9ubz0wLCBzdGVyZW89MSAqLwoKfSBUTlNfSU5GT19UQUI7CgojZGVmaW5lIFROU19USU1FUkVTX1NDQUxFICAgICgxKQojZGVmaW5lIEZMMl9USU1FUkVTX0ZJWChhKSAgICggRkwyRlhDT05TVF9EQkwoYS8oZmxvYXQpKDE8PFROU19USU1FUkVTX1NDQUxFKSkgKQoKc3RhdGljIGNvbnN0IFROU19JTkZPX1RBQiB0bnNJbmZvVGFiW10gPQp7CiAgewogICAgeyAgMTYwMDAsICAxMzUwMH0sCiAgICB7ICAzMjAwMCwgIDI4MDAwfSwKICAgIHsKICAgICAgeyB7MSwgMX0sIHsxNDM3LCAxNTAwfSwgezE0MDAsIDYwMH0sIHsxMiwgMTJ9LCB7RklMVEVSX0RJUkVDVElPTiwgRklMVEVSX0RJUkVDVElPTn0sIHszLCAxfSwge0ZMMl9USU1FUkVTX0ZJWCgwLjRmKSwgRkwyX1RJTUVSRVNfRklYKDEuMmYpfSwgMSB9LAogICAgICB7IHsxLCAxfSwgezE0MzcsIDE1MDB9LCB7MTQwMCwgNjAwfSwgezEyLCAxMn0sIHtGSUxURVJfRElSRUNUSU9OLCBGSUxURVJfRElSRUNUSU9OfSwgezMsIDF9LCB7RkwyX1RJTUVSRVNfRklYKDAuNGYpLCBGTDJfVElNRVJFU19GSVgoMS4yZil9LCAxIH0KICAgIH0KICB9LAogIHsKICAgIHsgIDMyMDAxLCAgMjgwMDF9LAogICAgeyAgNjAwMDAsICA1MjAwMH0sCiAgICB7CiAgICAgIHsgezEsIDF9LCB7MTQzNywgMTUwMH0sIHsxNDAwLCA2MDB9LCB7MTIsIDEwfSwge0ZJTFRFUl9ESVJFQ1RJT04sIEZJTFRFUl9ESVJFQ1RJT059LCB7MywgMX0sIHtGTDJfVElNRVJFU19GSVgoMC40ZiksIEZMMl9USU1FUkVTX0ZJWCgxLjBmKX0sIDEgfSwKICAgICAgeyB7MSwgMX0sIHsxNDM3LCAxNTAwfSwgezE0MDAsIDYwMH0sIHsxMiwgMTB9LCB7RklMVEVSX0RJUkVDVElPTiwgRklMVEVSX0RJUkVDVElPTn0sIHszLCAxfSwge0ZMMl9USU1FUkVTX0ZJWCgwLjRmKSwgRkwyX1RJTUVSRVNfRklYKDEuMGYpfSwgMSB9CiAgICB9CiAgfSwKICB7CiAgICB7ICA2MDAwMSwgIDUyMDAxfSwKICAgIHsgMzg0MDAwLCAzODQwMDB9LAogICAgewogICAgICB7IHsxLCAxfSwgezE0MzcsIDE1MDB9LCB7MTQwMCwgNjAwfSwgezEyLCAgOH0sIHtGSUxURVJfRElSRUNUSU9OLCBGSUxURVJfRElSRUNUSU9OfSwgezMsIDF9LCB7RkwyX1RJTUVSRVNfRklYKDAuNGYpLCBGTDJfVElNRVJFU19GSVgoMS4wZil9LCAxIH0sCiAgICAgIHsgezEsIDF9LCB7MTQzNywgMTUwMH0sIHsxNDAwLCA2MDB9LCB7MTIsICA4fSwge0ZJTFRFUl9ESVJFQ1RJT04sIEZJTFRFUl9ESVJFQ1RJT059LCB7MywgMX0sIHtGTDJfVElNRVJFU19GSVgoMC40ZiksIEZMMl9USU1FUkVTX0ZJWCgxLjBmKX0sIDEgfQogICAgfQogIH0KfTsKCnR5cGVkZWYgc3RydWN0IHsKICBJTlQgICBzYW1wbGluZ1JhdGU7CiAgU0NIQVIgbWF4QmFuZHNbMl07IC8qIGxvbmc9MDsgc2hvcnQ9MSAqLwoKfSBUTlNfTUFYX1RBQl9FTlRSWTsKCnN0YXRpYyBjb25zdCBUTlNfTUFYX1RBQl9FTlRSWSB0bnNNYXhCYW5kc1RhYjEwMjRbXSA9CnsKICB7IDk2MDAwLCB7IDMxLCAgOX19LAogIHsgODgyMDAsIHsgMzEsICA5fX0sCiAgeyA2NDAwMCwgeyAzNCwgMTB9fSwKICB7IDQ4MDAwLCB7IDQwLCAxNH19LAogIHsgNDQxMDAsIHsgNDIsIDE0fX0sCiAgeyAzMjAwMCwgeyA1MSwgMTR9fSwKICB7IDI0MDAwLCB7IDQ2LCAxNH19LAogIHsgMjIwNTAsIHsgNDYsIDE0fX0sCiAgeyAxNjAwMCwgeyA0MiwgMTR9fSwKICB7IDEyMDAwLCB7IDQyLCAxNH19LAogIHsgMTEwMjUsIHsgNDIsIDE0fX0sCiAgeyA4MDAwLCAgeyAzOSwgMTR9fQp9OwoKc3RhdGljIGNvbnN0IFROU19NQVhfVEFCX0VOVFJZIHRuc01heEJhbmRzVGFiNDgwW10gPQp7CiAgeyA0ODAwMCwgeyAzMSwgLTF9fSwKICB7IDQ0MTAwLCB7IDMyLCAtMX19LAogIHsgMzIwMDAsIHsgMzcsIC0xfX0sCiAgeyAyNDAwMCwgeyAzMCwgLTF9fSwKICB7IDIyMDUwLCB7IDMwLCAtMX19Cn07CgpzdGF0aWMgY29uc3QgVE5TX01BWF9UQUJfRU5UUlkgdG5zTWF4QmFuZHNUYWI1MTJbXSA9CnsKICB7IDQ4MDAwLCB7IDMxLCAtMX19LAogIHsgNDQxMDAsIHsgMzIsIC0xfX0sCiAgeyAzMjAwMCwgeyAzNywgLTF9fSwKICB7IDI0MDAwLCB7IDMxLCAtMX19LAogIHsgMjIwNTAsIHsgMzEsIC0xfX0KfTsKCnN0YXRpYyBJTlQgRkRLYWFjRW5jX0F1dG9Ub1BhcmNvcigKICAgICAgICBGSVhQX0RCTCAqUkVTVFJJQ1QgaW5wdXQsCiAgICAgICAgRklYUF9EQkwgKlJFU1RSSUNUIHJlZmxDb2VmZiwKICAgICAgICBjb25zdCBJTlQgbnVtT2ZDb2VmZgogICAgICAgICk7CgpzdGF0aWMgdm9pZCBGREthYWNFbmNfUGFyY29yMkluZGV4KAogICAgICAgIGNvbnN0IEZJWFBfREJMICpwYXJjb3IsCiAgICAgICAgSU5UICpSRVNUUklDVCBpbmRleCwKICAgICAgICBjb25zdCBJTlQgb3JkZXIsCiAgICAgICAgY29uc3QgSU5UIGJpdHNQZXJDb2VmZgogICAgICAgICk7CgpzdGF0aWMgdm9pZCBGREthYWNFbmNfSW5kZXgyUGFyY29yKAogICAgICAgIGNvbnN0IElOVCAqaW5kZXgsCiAgICAgICAgRklYUF9EQkwgKlJFU1RSSUNUIHBhcmNvciwKICAgICAgICBjb25zdCBJTlQgb3JkZXIsCiAgICAgICAgY29uc3QgSU5UIGJpdHNQZXJDb2VmZgogICAgICAgICk7CgpzdGF0aWMgSU5UIEZES2FhY0VuY19QYXJjb3JUb0xwYygKICAgICAgICBjb25zdCBGSVhQX0RCTCAqcmVmbENvZWZmLAogICAgICAgIEZJWFBfREJMICpSRVNUUklDVCBMcGNDb2VmZiwKICAgICAgICBjb25zdCBJTlQgbnVtT2ZDb2VmZiwKICAgICAgICBGSVhQX0RCTCAqUkVTVFJJQ1Qgd29ya0J1ZmZlcgogICAgICAgICk7CgpzdGF0aWMgdm9pZCBGREthYWNFbmNfQW5hbHlzaXNGaWx0ZXIoCiAgICAgICAgRklYUF9EQkwgKlJFU1RSSUNUIHNpZ25hbCwKICAgICAgICBjb25zdCBJTlQgbnVtT2ZMaW5lcywKICAgICAgICBjb25zdCBGSVhQX0RCTCAqcHJlZGljdG9yQ29lZmYsCiAgICAgICAgY29uc3QgSU5UIG9yZGVyLAogICAgICAgIGNvbnN0IElOVCBscGNHYWluRmFjdG9yCiAgICAgICAgKTsKCnN0YXRpYyB2b2lkIEZES2FhY0VuY19DYWxjR2F1c3NXaW5kb3coCiAgICAgICAgRklYUF9EQkwgKndpbiwKICAgICAgICBjb25zdCBpbnQgd2luU2l6ZSwKICAgICAgICBjb25zdCBJTlQgc2FtcGxpbmdSYXRlLAogICAgICAgIGNvbnN0IElOVCB0cmFuc2Zvcm1SZXNvbHV0aW9uLAogICAgICAgIGNvbnN0IEZJWFBfREJMIHRpbWVSZXNvbHV0aW9uLAogICAgICAgIGNvbnN0IElOVCB0aW1lUmVzb2x1dGlvbl9lCiAgICAgICAgKTsKCnN0YXRpYyBjb25zdCBUTlNfUEFSQU1FVEVSX1RBQlVMQVRFRCogRkRLYWFjRW5jX0dldFRuc1BhcmFtKAogICAgICAgIGNvbnN0IElOVCBiaXRSYXRlLAogICAgICAgIGNvbnN0IElOVCBjaGFubmVscywKICAgICAgICBjb25zdCBJTlQgc2JyTGQKICAgICAgICApCnsKICBpbnQgaTsKICBjb25zdCBUTlNfUEFSQU1FVEVSX1RBQlVMQVRFRCAqdG5zQ29uZmlnVGFiID0gTlVMTDsKCiAgZm9yIChpID0gMDsgaSA8IChpbnQpIChzaXplb2YodG5zSW5mb1RhYikvc2l6ZW9mKFROU19JTkZPX1RBQikpOyBpKyspIHsKICAgIGlmICgoYml0UmF0ZSA+PSB0bnNJbmZvVGFiW2ldLmJpdFJhdGVGcm9tW3NickxkPzE6MF0pICYmCiAgICAgICAgIGJpdFJhdGUgPD0gdG5zSW5mb1RhYltpXS5iaXRSYXRlVG9bc2JyTGQ/MTowXSkKICAgIHsKICAgICAgdG5zQ29uZmlnVGFiID0gJnRuc0luZm9UYWJbaV0ucGFyYW1UYWJbKGNoYW5uZWxzPT0xKT8wOjFdOwogICAgfQogIH0KCiAgcmV0dXJuIHRuc0NvbmZpZ1RhYjsKfQoKCnN0YXRpYyBJTlQgZ2V0VG5zTWF4QmFuZHMoCiAgICAgICAgY29uc3QgSU5UIHNhbXBsZVJhdGUsCiAgICAgICAgY29uc3QgSU5UIGdyYW51bGVMZW5ndGgsCiAgICAgICAgY29uc3QgSU5UIGlzU2hvcnRCbG9jawogICAgICAgICkKewogIGludCBpOwogIElOVCBudW1CYW5kcyA9IC0xOwogIGNvbnN0IFROU19NQVhfVEFCX0VOVFJZICpwTWF4QmFuZHNUYWIgPSBOVUxMOwogIGludCBtYXhCYW5kc1RhYlNpemUgPSAwOwoKICBzd2l0Y2ggKGdyYW51bGVMZW5ndGgpIHsKICAgIGNhc2UgOTYwOgogICAgY2FzZSAxMDI0OgogICAgICBwTWF4QmFuZHNUYWIgPSB0bnNNYXhCYW5kc1RhYjEwMjQ7CiAgICAgIG1heEJhbmRzVGFiU2l6ZSA9IHNpemVvZih0bnNNYXhCYW5kc1RhYjEwMjQpL3NpemVvZihUTlNfTUFYX1RBQl9FTlRSWSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSA0ODA6CiAgICAgIHBNYXhCYW5kc1RhYiA9IHRuc01heEJhbmRzVGFiNDgwOwogICAgICBtYXhCYW5kc1RhYlNpemUgPSBzaXplb2YodG5zTWF4QmFuZHNUYWI0ODApL3NpemVvZihUTlNfTUFYX1RBQl9FTlRSWSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSA1MTI6CiAgICAgIHBNYXhCYW5kc1RhYiA9IHRuc01heEJhbmRzVGFiNTEyOwogICAgICBtYXhCYW5kc1RhYlNpemUgPSBzaXplb2YodG5zTWF4QmFuZHNUYWI1MTIpL3NpemVvZihUTlNfTUFYX1RBQl9FTlRSWSk7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgbnVtQmFuZHMgPSAtMTsKICB9CgogIGlmIChwTWF4QmFuZHNUYWIhPU5VTEwpIHsKICAgIGZvciAoaT0wOyBpPG1heEJhbmRzVGFiU2l6ZTsgaSsrKSB7CiAgICAgIG51bUJhbmRzID0gcE1heEJhbmRzVGFiW2ldLm1heEJhbmRzWyghaXNTaG9ydEJsb2NrKT8wOjFdOwogICAgICBpZiAoc2FtcGxlUmF0ZSA+PSBwTWF4QmFuZHNUYWJbaV0uc2FtcGxpbmdSYXRlKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBudW1CYW5kczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBGREthYWNFbmNfRnJlcVRvQmFuZFdpdGhSb3VuZGluZwoKICBSZXR1cm5zIGluZGV4IG9mIG5lYXJlc3QgYmFuZCBib3JkZXIKCiAgXHBhcmFtIGZyZXF1ZW5jeQogIFxwYXJhbSBzYW1wbGluZyBmcmVxdWVuY3kKICBccGFyYW0gdG90YWwgbnVtYmVyIG9mIGJhbmRzCiAgXHBhcmFtIHBvaW50ZXIgdG8gdGFibGUgb2YgYmFuZCBib3JkZXJzCgogIFxyZXR1cm4gYmFuZCBib3JkZXIKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCklOVCBGREthYWNFbmNfRnJlcVRvQmFuZFdpdGhSb3VuZGluZygKICAgICAgICBjb25zdCBJTlQgZnJlcSwKICAgICAgICBjb25zdCBJTlQgZnMsCiAgICAgICAgY29uc3QgSU5UIG51bU9mQmFuZHMsCiAgICAgICAgY29uc3QgSU5UICpiYW5kU3RhcnRPZmZzZXQKICAgICAgICApCnsKICBJTlQgbGluZU51bWJlciwgYmFuZDsKCiAgLyogIGFzc2VydChmcmVxID49IDApOyAgKi8KICBsaW5lTnVtYmVyID0gKGZyZXEqYmFuZFN0YXJ0T2Zmc2V0W251bU9mQmFuZHNdKjQvZnMrMSkvMjsKCiAgLyogZnJlcSA+IGZzLzIgKi8KICBpZiAobGluZU51bWJlciA+PSBiYW5kU3RhcnRPZmZzZXRbbnVtT2ZCYW5kc10pCiAgICByZXR1cm4gbnVtT2ZCYW5kczsKCiAgLyogZmluZCBiYW5kIHRoZSBsaW5lIG51bWJlciBsaWVzIGluICovCiAgZm9yIChiYW5kPTA7IGJhbmQ8bnVtT2ZCYW5kczsgYmFuZCsrKSB7CiAgICBpZiAoYmFuZFN0YXJ0T2Zmc2V0W2JhbmQrMV0+bGluZU51bWJlcikgYnJlYWs7CiAgfQoKICAvKiByb3VuZCB0byBuZWFyZXN0IGJhbmQgYm9yZGVyICovCiAgaWYgKGxpbmVOdW1iZXIgLSBiYW5kU3RhcnRPZmZzZXRbYmFuZF0gPgogICAgICBiYW5kU3RhcnRPZmZzZXRbYmFuZCsxXSAtIGxpbmVOdW1iZXIgKQogICAgewogICAgICBiYW5kKys7CiAgICB9CgogIHJldHVybihiYW5kKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX0luaXRUbnNDb25maWd1cmF0aW9uCiAgICBkZXNjcmlwdGlvbjogIGZpbGwgVE5TX0NPTkZJRyBzdHJ1Y3R1cmUgd2l0aCBzZW5zaWJsZSBjb250ZW50CiAgICByZXR1cm5zOgogICAgaW5wdXQ6ICAgICAgICBiaXRyYXRlLCBzYW1wbGVyYXRlLCBudW1iZXIgb2YgY2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgIGJsb2NrdHlwZSAobG9uZyBvciBzaG9ydCksCiAgICAgICAgICAgICAgICAgIFROUyBDb25maWcgc3RydWN0IChtb2RpZmllZCksCiAgICAgICAgICAgICAgICAgIHBzeSBjb25maWcgc3RydWN0LAogICAgICAgICAgICAgICAgICB0bnMgYWN0aXZlIGZsYWcKICAgIG91dHB1dDoKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfSW5pdFRuc0NvbmZpZ3VyYXRpb24oSU5UIGJpdFJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgc2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBjaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBibG9ja1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgZ3JhbnVsZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBsZFNiclByZXNlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUTlNfQ09ORklHICp0QywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTWV9DT05GSUdVUkFUSU9OICpwQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBhY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgdXNlVG5zUGVhaykKewogIGludCBpOwogIC8vZmxvYXQgYWNmVGltZVJlcyAgID0gKGJsb2NrVHlwZSA9PSBTSE9SVF9XSU5ET1cpID8gMC4xMjVmIDogMC4wNDY4NzVmOwoKICBpZiAoY2hhbm5lbHMgPD0gMCkKICAgIHJldHVybiAoQUFDX0VOQ09ERVJfRVJST1IpMTsKCiAgLyogaW5pdGlhbGl6ZSBUTlMgZmlsdGVyIGZsYWcsIG9yZGVyLCBhbmQgY29lZmZpY2llbnQgcmVzb2x1dGlvbiAoaW4gYml0cyBwZXIgY29lZmYpICovCiAgdEMtPnRuc0FjdGl2ZSAgICAgID0gKGFjdGl2ZSkgPyBUUlVFIDogRkFMU0U7CiAgdEMtPm1heE9yZGVyICAgICAgID0gKGJsb2NrVHlwZSA9PSBTSE9SVF9XSU5ET1cpID8gNSA6IDEyOyAgLyogbWF4aW11bTogNywgMjAgKi8KICBpZiAoYml0UmF0ZSA8IDE2MDAwKQogICAgdEMtPm1heE9yZGVyIC09IDI7CiAgdEMtPmNvZWZSZXMgICAgICAgID0gKGJsb2NrVHlwZSA9PSBTSE9SVF9XSU5ET1cpID8gMyA6IDQ7CgogIC8qIExQQyBzdG9wIGxpbmU6IGhpZ2hlc3QgTURDVCBsaW5lIHRvIGJlIGNvZGVkLCBidXQgZG8gbm90IGdvIGJleW9uZCBUTlNfTUFYX0JBTkRTISAqLwogIHRDLT5scGNTdG9wQmFuZCA9IGdldFRuc01heEJhbmRzKHNhbXBsZVJhdGUsIGdyYW51bGVMZW5ndGgsIChibG9ja1R5cGUgPT0gU0hPUlRfV0lORE9XKSA/IDEgOiAwKTsKCiAgaWYgKHRDLT5scGNTdG9wQmFuZCA8IDApIHsKICAgIHJldHVybiAoQUFDX0VOQ09ERVJfRVJST1IpMTsKICB9CgogIHRDLT5scGNTdG9wQmFuZCA9IEZES21pbih0Qy0+bHBjU3RvcEJhbmQsIHBDLT5zZmJBY3RpdmUpOwogIHRDLT5scGNTdG9wTGluZSAgICA9IHBDLT5zZmJPZmZzZXRbdEMtPmxwY1N0b3BCYW5kXTsKCiAgc3dpdGNoIChncmFudWxlTGVuZ3RoKSB7CiAgICBjYXNlIDk2MDoKICAgIGNhc2UgMTAyNDoKICAgICAgLyogVE5TIHN0YXJ0IGxpbmU6IHNraXAgbG93ZXIgTURDVCBsaW5lcyB0byBwcmV2ZW50IGFydGlmYWN0cyBkdWUgdG8gZmlsdGVyIG1pc21hdGNoICovCiAgICAgIHRDLT5scGNTdGFydEJhbmRbTE9GSUxUXSAgID0gKGJsb2NrVHlwZSA9PSBTSE9SVF9XSU5ET1cpID8gMCA6ICgoc2FtcGxlUmF0ZSA8IDE4NzgzKSA/IDQgOiA4KTsKICAgICAgdEMtPmxwY1N0YXJ0TGluZVtMT0ZJTFRdICAgPSBwQy0+c2ZiT2Zmc2V0W3RDLT5scGNTdGFydEJhbmRbTE9GSUxUXV07CgogICAgICBpID0gdEMtPmxwY1N0b3BCYW5kOwogICAgICB3aGlsZSAocEMtPnNmYk9mZnNldFtpXSA+ICh0Qy0+bHBjU3RhcnRMaW5lW0xPRklMVF0gKyAodEMtPmxwY1N0b3BMaW5lIC0gdEMtPmxwY1N0YXJ0TGluZVtMT0ZJTFRdKSAvIDQpKSBpLS07CiAgICAgIHRDLT5scGNTdGFydEJhbmRbSElGSUxUXSAgID0gaTsKICAgICAgdEMtPmxwY1N0YXJ0TGluZVtISUZJTFRdICAgPSBwQy0+c2ZiT2Zmc2V0W2ldOwoKICAgICAgdEMtPmNvbmZUYWIudGhyZXNoT25bSElGSUxUXSA9IDE0Mzc7CiAgICAgIHRDLT5jb25mVGFiLnRocmVzaE9uW0xPRklMVF0gPSAxNTAwOwoKICAgICAgdEMtPmNvbmZUYWIudG5zTGltaXRPcmRlcltISUZJTFRdID0gdEMtPm1heE9yZGVyOwogICAgICB0Qy0+Y29uZlRhYi50bnNMaW1pdE9yZGVyW0xPRklMVF0gPSB0Qy0+bWF4T3JkZXIgLSA3OwoKICAgICAgdEMtPmNvbmZUYWIudG5zRmlsdGVyRGlyZWN0aW9uW0hJRklMVF0gPSBGSUxURVJfRElSRUNUSU9OOwogICAgICB0Qy0+Y29uZlRhYi50bnNGaWx0ZXJEaXJlY3Rpb25bTE9GSUxUXSA9IEZJTFRFUl9ESVJFQ1RJT047CgogICAgICB0Qy0+Y29uZlRhYi5hY2ZTcGxpdFtISUZJTFRdID0gLTE7ICAvKiBzaWduYWwgTWVyZ2VkNHRvMlF1YXJ0ZXJzQXV0b0NvcnJlbGF0aW9uIGluIEZES2FhY0VuY19NZXJnZWRBdXRvQ29ycmVsYXRpb24qLwogICAgICB0Qy0+Y29uZlRhYi5hY2ZTcGxpdFtMT0ZJTFRdID0gLTE7ICAvKiBzaWduYWwgTWVyZ2VkNHRvMlF1YXJ0ZXJzQXV0b0NvcnJlbGF0aW9uIGluIEZES2FhY0VuY19NZXJnZWRBdXRvQ29ycmVsYXRpb24gKi8KCiAgICAgIHRDLT5jb25mVGFiLmZpbHRlckVuYWJsZWRbSElGSUxUXSA9IDE7CiAgICAgIHRDLT5jb25mVGFiLmZpbHRlckVuYWJsZWRbTE9GSUxUXSA9IDE7CiAgICAgIHRDLT5jb25mVGFiLnNlcGVyYXRlRmlsdGVyc0FsbG93ZWQgPSAxOwoKICAgICAgLyogY29tcHV0ZSBhdXRvY29ycmVsYXRpb24gd2luZG93IGJhc2VkIG9uIG1heGltdW0gZmlsdGVyIG9yZGVyIGZvciBnaXZlbiBibG9jayB0eXBlICovCiAgICAgIC8qIGZvciAoaSA9IDA7IGkgPD0gdEMtPm1heE9yZGVyICsgMzsgaSsrKSB7CiAgICAgICAgICAgZmxvYXQgYWNmV2luVGVtcCA9IGFjZlRpbWVSZXMgKiBpOwogICAgICAgICAgIGFjZldpbmRvd1tpXSA9IEZMMkZYQ09OU1RfREJMKDEuMGYgLSBhY2ZXaW5UZW1wICogYWNmV2luVGVtcCk7CiAgICAgICAgIH0KICAgICAgKi8KICAgICAgaWYgKGJsb2NrVHlwZSA9PSBTSE9SVF9XSU5ET1cpIHsKICAgICAgICBGREttZW1jcHkodEMtPmFjZldpbmRvd1tISUZJTFRdLCBhY2ZXaW5kb3dTaG9ydCwgRkRLbWluKHNpemVvZihhY2ZXaW5kb3dTaG9ydCksIHNpemVvZih0Qy0+YWNmV2luZG93W0hJRklMVF0pKSk7CiAgICAgICAgRkRLbWVtY3B5KHRDLT5hY2ZXaW5kb3dbTE9GSUxUXSwgYWNmV2luZG93U2hvcnQsIEZES21pbihzaXplb2YoYWNmV2luZG93U2hvcnQpLCBzaXplb2YodEMtPmFjZldpbmRvd1tISUZJTFRdKSkpOwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIEZES21lbWNweSh0Qy0+YWNmV2luZG93W0hJRklMVF0sIGFjZldpbmRvd0xvbmcsIEZES21pbihzaXplb2YoYWNmV2luZG93TG9uZyksIHNpemVvZih0Qy0+YWNmV2luZG93W0hJRklMVF0pKSk7CiAgICAgICAgRkRLbWVtY3B5KHRDLT5hY2ZXaW5kb3dbTE9GSUxUXSwgYWNmV2luZG93TG9uZywgRkRLbWluKHNpemVvZihhY2ZXaW5kb3dMb25nKSwgc2l6ZW9mKHRDLT5hY2ZXaW5kb3dbSElGSUxUXSkpKTsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgNDgwOgogICAgY2FzZSA1MTI6CiAgICAgIHsKICAgICAgICBjb25zdCBUTlNfUEFSQU1FVEVSX1RBQlVMQVRFRCogcENmZyA9IEZES2FhY0VuY19HZXRUbnNQYXJhbShiaXRSYXRlLCBjaGFubmVscywgbGRTYnJQcmVzZW50KTsKCiAgICAgICAgaWYgKCBwQ2ZnICE9IE5VTEwgKSB7CiAgICAgICAgICB0Qy0+bHBjU3RhcnRCYW5kW0hJRklMVF0gICAgICAgICA9IEZES2FhY0VuY19GcmVxVG9CYW5kV2l0aFJvdW5kaW5nKHBDZmctPmZpbHRlclN0YXJ0RnJlcVtISUZJTFRdLCBzYW1wbGVSYXRlLCBwQy0+c2ZiQ250LCBwQy0+c2ZiT2Zmc2V0KTsKICAgICAgICAgIHRDLT5scGNTdGFydExpbmVbSElGSUxUXSAgICAgICAgID0gcEMtPnNmYk9mZnNldFt0Qy0+bHBjU3RhcnRCYW5kW0hJRklMVF1dOwogICAgICAgICAgdEMtPmxwY1N0YXJ0QmFuZFtMT0ZJTFRdICAgICAgICAgPSBGREthYWNFbmNfRnJlcVRvQmFuZFdpdGhSb3VuZGluZyhwQ2ZnLT5maWx0ZXJTdGFydEZyZXFbTE9GSUxUXSwgc2FtcGxlUmF0ZSwgcEMtPnNmYkNudCwgcEMtPnNmYk9mZnNldCk7CiAgICAgICAgICB0Qy0+bHBjU3RhcnRMaW5lW0xPRklMVF0gICAgICAgICA9IHBDLT5zZmJPZmZzZXRbdEMtPmxwY1N0YXJ0QmFuZFtMT0ZJTFRdXTsKCiAgICAgICAgICB0Qy0+Y29uZlRhYi50aHJlc2hPbltISUZJTFRdID0gcENmZy0+dGhyZXNoT25bSElGSUxUXTsKICAgICAgICAgIHRDLT5jb25mVGFiLnRocmVzaE9uW0xPRklMVF0gPSBwQ2ZnLT50aHJlc2hPbltMT0ZJTFRdOwoKICAgICAgICAgIHRDLT5jb25mVGFiLnRuc0xpbWl0T3JkZXJbSElGSUxUXSA9IHBDZmctPnRuc0xpbWl0T3JkZXJbSElGSUxUXTsKICAgICAgICAgIHRDLT5jb25mVGFiLnRuc0xpbWl0T3JkZXJbTE9GSUxUXSA9IHBDZmctPnRuc0xpbWl0T3JkZXJbTE9GSUxUXTsKCiAgICAgICAgICB0Qy0+Y29uZlRhYi50bnNGaWx0ZXJEaXJlY3Rpb25bSElGSUxUXSA9IHBDZmctPnRuc0ZpbHRlckRpcmVjdGlvbltISUZJTFRdOwogICAgICAgICAgdEMtPmNvbmZUYWIudG5zRmlsdGVyRGlyZWN0aW9uW0xPRklMVF0gPSBwQ2ZnLT50bnNGaWx0ZXJEaXJlY3Rpb25bTE9GSUxUXTsKCiAgICAgICAgICB0Qy0+Y29uZlRhYi5hY2ZTcGxpdFtISUZJTFRdID0gcENmZy0+YWNmU3BsaXRbSElGSUxUXTsKICAgICAgICAgIHRDLT5jb25mVGFiLmFjZlNwbGl0W0xPRklMVF0gPSBwQ2ZnLT5hY2ZTcGxpdFtMT0ZJTFRdOwoKICAgICAgICAgIHRDLT5jb25mVGFiLmZpbHRlckVuYWJsZWRbSElGSUxUXSA9IHBDZmctPmZpbHRlckVuYWJsZWRbSElGSUxUXTsKICAgICAgICAgIHRDLT5jb25mVGFiLmZpbHRlckVuYWJsZWRbTE9GSUxUXSA9IHBDZmctPmZpbHRlckVuYWJsZWRbTE9GSUxUXTsKICAgICAgICAgIHRDLT5jb25mVGFiLnNlcGVyYXRlRmlsdGVyc0FsbG93ZWQgPSBwQ2ZnLT5zZXBlcmF0ZUZpbHRlcnNBbGxvd2VkOwoKICAgICAgICAgIEZES2FhY0VuY19DYWxjR2F1c3NXaW5kb3codEMtPmFjZldpbmRvd1tISUZJTFRdLCB0Qy0+bWF4T3JkZXIrMSwgc2FtcGxlUmF0ZSwgZ3JhbnVsZUxlbmd0aCwgcENmZy0+dG5zVGltZVJlc29sdXRpb25bSElGSUxUXSwgVE5TX1RJTUVSRVNfU0NBTEUpOwogICAgICAgICAgRkRLYWFjRW5jX0NhbGNHYXVzc1dpbmRvdyh0Qy0+YWNmV2luZG93W0xPRklMVF0sIHRDLT5tYXhPcmRlcisxLCBzYW1wbGVSYXRlLCBncmFudWxlTGVuZ3RoLCBwQ2ZnLT50bnNUaW1lUmVzb2x1dGlvbltMT0ZJTFRdLCBUTlNfVElNRVJFU19TQ0FMRSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgdEMtPnRuc0FjdGl2ZSA9IEZBTFNFOyAvKiBubyBjb25maWd1cmF0aW9uIGF2YWlsYWJsZSwgZGlzYWJsZSB0bnMgdG9vbCAqLwogICAgICAgIH0KICAgICAgfQogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIHRDLT50bnNBY3RpdmUgPSBGQUxTRTsgLyogbm8gY29uZmlndXJhdGlvbiBhdmFpbGFibGUsIGRpc2FibGUgdG5zIHRvb2wgKi8KICB9CgogIHJldHVybiBBQUNfRU5DX09LOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBGREthYWNFbmNfU2NhbGVVcFNwZWN0cnVtCgogIFNjYWxlcyB1cCBzcGVjdHJ1bSBsaW5lcyBpbiBhIGdpdmVuIGZyZXF1ZW5jeSBzZWN0aW9uCgogIFxwYXJhbSBzY2FsZWQgc3BlY3RydW0KICBccGFyYW0gb3JpZ2luYWwgc3BlY3RydW0KICBccGFyYW0gZnJlcXVlbmN5IGxpbmUgdG8gc3RhcnQgc2NhbGluZwogIFxwYXJhbSBmcmVxdWVuY3kgbGluZSB0byBlbmMgc2NhbGluZwoKICBccmV0dXJuIHNjYWxlIGZhY3RvcgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIGlubGluZSBJTlQgRkRLYWFjRW5jX1NjYWxlVXBTcGVjdHJ1bSgKICAgICAgICBGSVhQX0RCTCAgICAgICAgICAgICAgICAgKmRlc3QsCiAgICAgICAgY29uc3QgRklYUF9EQkwgICAgICAgICAgICpzcmMsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBzdGFydExpbmUsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBzdG9wTGluZQogICAgICAgICkKewogICAgSU5UIGksIHNjYWxlOwoKICAgIEZJWFBfREJMIG1heFZhbCA9IEZMMkZYQ09OU1RfREJMKDAuZik7CgogICAgLyogR2V0IGhpZ2hlc3QgdmFsdWUgaW4gZ2l2ZW4gc3BlY3RydW0gKi8KICAgIGZvciAoaT1zdGFydExpbmU7IGk8c3RvcExpbmU7IGkrKykgewogICAgICBtYXhWYWwgPSBmaXhNYXgobWF4VmFsLGZpeHBfYWJzKHNyY1tpXSkpOwogICAgfQogICAgc2NhbGUgPSBDb3VudExlYWRpbmdCaXRzKG1heFZhbCk7CgogICAgLyogU2NhbGUgc3BlY3RydW0gYWNjb3JkaW5nIHRvIGhpZ2hlc3QgdmFsdWUgKi8KICAgIGZvciAoaT1zdGFydExpbmU7IGk8c3RvcExpbmU7IGkrKykgewogICAgICBkZXN0W2ldID0gc3JjW2ldPDxzY2FsZTsKICAgIH0KCiAgICByZXR1cm4gc2NhbGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgRkRLYWFjRW5jX0NhbGNBdXRvQ29yclZhbHVlCgogIENhbGN1bGF0ZSBhdXRvY29yZWxsYXRpb24gdmFsdWUgZm9yIG9uZSBsYWcKCiAgXHBhcmFtIHBvaW50ZXIgdG8gc3BlY3RydW0KICBccGFyYW0gc3RhcnQgbGluZQogIFxwYXJhbSBzdG9wIGxpbmUKICBccGFyYW0gbGFnIHRvIGJlIGNhbGN1bGF0ZWQKICBccGFyYW0gc2NhbGluZyBvZiB0aGUgbGFnCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgaW5saW5lIEZJWFBfREJMIEZES2FhY0VuY19DYWxjQXV0b0NvcnJWYWx1ZSgKICAgICAgICBjb25zdCBGSVhQX0RCTCAgICAgICAgICAgKnNwZWN0cnVtLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgc3RhcnRMaW5lLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgc3RvcExpbmUsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBsYWcsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBzY2FsZQogICAgICAgICkKewogICAgaW50IGk7CiAgICBGSVhQX0RCTCByZXN1bHQgPSBGTDJGWENPTlNUX0RCTCgwLmYpOwoKICAgIGlmIChsYWc9PTApIHsKICAgICAgZm9yIChpPXN0YXJ0TGluZTsgaTxzdG9wTGluZTsgaSsrKSB7CiAgICAgICAgcmVzdWx0ICs9IChmUG93MihzcGVjdHJ1bVtpXSk+PnNjYWxlKTsKICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgIGZvciAoaT1zdGFydExpbmU7IGk8KHN0b3BMaW5lLWxhZyk7IGkrKykgewogICAgICAgIHJlc3VsdCArPSAoZk11bHQoc3BlY3RydW1baV0sIHNwZWN0cnVtW2krbGFnXSk+PnNjYWxlKTsKICAgICAgfQogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgRkRLYWFjRW5jX0F1dG9Db3JyTm9ybUZhYwoKICBBdXRvY29ycmVsYXRpb24gZnVuY3Rpb24gZm9yIDFzdCBhbmQgMm5kIGhhbGYgb2YgdGhlIHNwZWN0cnVtCgogIFxwYXJhbSBwb2ludGVyIHRvIHNwZWN0cnVtCiAgXHBhcmFtIHBvaW50ZXIgdG8gYXV0b2NvcnJlbGF0aW9uIHdpbmRvdwogIFxwYXJhbSBmaWx0ZXIgc3RhcnQgbGluZQoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIGlubGluZSBGSVhQX0RCTCBGREthYWNFbmNfQXV0b0NvcnJOb3JtRmFjKAogICAgICAgIGNvbnN0IEZJWFBfREJMICAgICAgICAgICAgdmFsdWUsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBzY2FsZSwKICAgICAgICBJTlQgICAgICAgICAgICAgICAgICAgICAgKnNjCiAgICAgICAgKQp7CiAgICAjZGVmaW5lIEhMTV9NSU5fTlJHIDAuMDAwMDAwMDAzNzI1MjkwMjk4NDYxOTE0MDYyNWYgLyogMl4tMjggKi8KICAgICNkZWZpbmUgTUFYX0lOVl9OUkdGQUMgKDEuZi9ITE1fTUlOX05SRykKCiAgICBGSVhQX0RCTCByZXRWYWx1ZTsKICAgIEZJWFBfREJMIEEsIEI7CgogICAgaWYgKHNjYWxlPj0wKSB7CiAgICAgIEEgPSB2YWx1ZTsKICAgICAgQiA9IEZMMkZYQ09OU1RfREJMKEhMTV9NSU5fTlJHKT4+Zml4TWluKERGUkFDVF9CSVRTLTEsc2NhbGUpOwogICAgfQogICAgZWxzZSB7CiAgICAgIEEgPSB2YWx1ZT4+Zml4TWluKERGUkFDVF9CSVRTLTEsKC1zY2FsZSkpOwogICAgICBCID0gRkwyRlhDT05TVF9EQkwoSExNX01JTl9OUkcpOwogICAgfQoKICAgIGlmIChBID4gQikgewogICAgICBpbnQgc2hpZnQgPSAwOwogICAgICBGSVhQX0RCTCB0bXAgPSBpbnZTcXJ0Tm9ybTIodmFsdWUsJnNoaWZ0KTsKCiAgICAgIHJldFZhbHVlID0gZk11bHQodG1wLHRtcCk7CiAgICAgICpzYyArPSAoMipzaGlmdCk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgLyogTUFYX0lOVl9OUkdGQUMqRkRLcG93KDIsLTI4KSA9IDEvMl4tMjggKiAyXi0yOCA9IDEuMCAqLwogICAgICByZXRWYWx1ZSA9IC8qRkwyRlhDT05TVF9EQkwoTUFYX0lOVl9OUkdGQUMqRkRLcG93KDIsLTI4KSkqLyAoRklYUF9EQkwpTUFYVkFMX0RCTDsKICAgICAgKnNjICs9IHNjYWxlKzI4OwogICAgfQoKICAgIHJldHVybiByZXRWYWx1ZTsKfQoKc3RhdGljIHZvaWQgRkRLYWFjRW5jX01lcmdlZEF1dG9Db3JyZWxhdGlvbigKICAgICAgICBjb25zdCBGSVhQX0RCTCAgICAgICAgICAgKnNwZWN0cnVtLAogICAgICAgIGNvbnN0IEZJWFBfREJMICAgICAgICAgICAgYWNmV2luZG93W01BWF9OVU1fT0ZfRklMVEVSU11bVE5TX01BWF9PUkRFUiszKzFdLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgbHBjU3RhcnRMaW5lW01BWF9OVU1fT0ZfRklMVEVSU10sCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICBscGNTdG9wTGluZSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgIG1heE9yZGVyLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgYWNmU3BsaXRbTUFYX05VTV9PRl9GSUxURVJTXSwKICAgICAgICBGSVhQX0RCTCAgICAgICAgICAgICAgICAgKl9yeHgxLAogICAgICAgIEZJWFBfREJMICAgICAgICAgICAgICAgICAqX3J4eDIKICAgICAgICApCnsKICAgIGludCBpLCBpZHgwLCBpZHgxLCBpZHgyLCBpZHgzLCBpZHg0LCBsYWc7CiAgICBGSVhQX0RCTCByeHgxXzAsIHJ4eDJfMCwgcnh4M18wLCByeHg0XzA7CgogICAgLyogYnVmZmVyIGZvciB0ZW1wb3JhbCBzcGVjdHJ1bSAqLwogICAgQ19BTExPQ19TQ1JBVENIX1NUQVJUKHBTcGVjdHJ1bSwgRklYUF9EQkwsICgxMDI0KSk7CgogICAgLyogcHJlLWluaXRpYWxpemF0aW9uIG91dHB1dCAqLwogICAgRkRLbWVtY2xlYXIoJl9yeHgxWzBdLCBzaXplb2YoRklYUF9EQkwpKihtYXhPcmRlcisxKSk7CiAgICBGREttZW1jbGVhcigmX3J4eDJbMF0sIHNpemVvZihGSVhQX0RCTCkqKG1heE9yZGVyKzEpKTsKCiAgICAvKiBNRENUIGxpbmUgaW5kaWNlcyBzZXBhcmF0aW5nIHRoZSAxc3QsIDJuZCwgM3JkLCBhbmQgNHRoIGFuYWx5c2lzIHF1YXJ0ZXJzICovCiAgICBpZiAoIChhY2ZTcGxpdFtMT0ZJTFRdPT0tMSkgfHwgKGFjZlNwbGl0W0hJRklMVF09PS0xKSApIHsKICAgICAgLyogYXV0b2NvcnJlbGF0aW9uIGZ1bmN0aW9uIGZvciAxc3QsIDJuZCwgM3JkLCBhbmQgNHRoIHF1YXJ0ZXIgb2YgdGhlIHNwZWN0cnVtICovCiAgICAgIGlkeDAgPSBscGNTdGFydExpbmVbTE9GSUxUXTsKICAgICAgaSAgICA9IGxwY1N0b3BMaW5lIC0gbHBjU3RhcnRMaW5lW0xPRklMVF07CiAgICAgIGlkeDEgPSBpZHgwICsgaSAvIDQ7CiAgICAgIGlkeDIgPSBpZHgwICsgaSAvIDI7CiAgICAgIGlkeDMgPSBpZHgwICsgaSAqIDMgLyA0OwogICAgICBpZHg0ID0gbHBjU3RvcExpbmU7CiAgICB9CiAgICBlbHNlIHsKICAgICAgRkRLX0FTU0VSVChhY2ZTcGxpdFtMT0ZJTFRdPT0xKTsKICAgICAgRkRLX0FTU0VSVChhY2ZTcGxpdFtISUZJTFRdPT0zKTsKICAgICAgaSAgICA9IChscGNTdG9wTGluZSAtIGxwY1N0YXJ0TGluZVtISUZJTFRdKSAvIDM7CiAgICAgIGlkeDAgPSBscGNTdGFydExpbmVbTE9GSUxUXTsKICAgICAgaWR4MSA9IGxwY1N0YXJ0TGluZVtISUZJTFRdOwogICAgICBpZHgyID0gaWR4MSArIGk7CiAgICAgIGlkeDMgPSBpZHgyICsgaTsKICAgICAgaWR4NCA9IGxwY1N0b3BMaW5lOwogICAgfQoKICAgIC8qIGNvcHkgc3BlY3RydW0gdG8gdGVtcG9yYWwgYnVmZmVyIGFuZCBzY2FsZSB1cCBhcyBtdWNoIGFzIHBvc3NpYmxlICovCiAgICBJTlQgc2MxID0gRkRLYWFjRW5jX1NjYWxlVXBTcGVjdHJ1bShwU3BlY3RydW0sIHNwZWN0cnVtLCBpZHgwLCBpZHgxKTsKICAgIElOVCBzYzIgPSBGREthYWNFbmNfU2NhbGVVcFNwZWN0cnVtKHBTcGVjdHJ1bSwgc3BlY3RydW0sIGlkeDEsIGlkeDIpOwogICAgSU5UIHNjMyA9IEZES2FhY0VuY19TY2FsZVVwU3BlY3RydW0ocFNwZWN0cnVtLCBzcGVjdHJ1bSwgaWR4MiwgaWR4Myk7CiAgICBJTlQgc2M0ID0gRkRLYWFjRW5jX1NjYWxlVXBTcGVjdHJ1bShwU3BlY3RydW0sIHNwZWN0cnVtLCBpZHgzLCBpZHg0KTsKCiAgICAvKiBnZXQgc2NhbGluZyB2YWx1ZXMgZm9yIHN1bW1hdGlvbiAqLwogICAgSU5UIG5zYzEsIG5zYzIsIG5zYzMsIG5zYzQ7CiAgICBmb3IgKG5zYzE9MTsgKDE8PG5zYzEpPChpZHgxLWlkeDApOyBuc2MxKyspOwogICAgZm9yIChuc2MyPTE7ICgxPDxuc2MyKTwoaWR4Mi1pZHgxKTsgbnNjMisrKTsKICAgIGZvciAobnNjMz0xOyAoMTw8bnNjMyk8KGlkeDMtaWR4Mik7IG5zYzMrKyk7CiAgICBmb3IgKG5zYzQ9MTsgKDE8PG5zYzQpPChpZHg0LWlkeDMpOyBuc2M0KyspOwoKICAgIC8qIGNvbXB1dGUgYXV0b2NvcnJlbGF0aW9uIHZhbHVlIGF0IGxhZyB6ZXJvLCBpLiBlLiBlbmVyZ3ksIGZvciBlYWNoIHF1YXJ0ZXIgKi8KICAgIHJ4eDFfMCA9IEZES2FhY0VuY19DYWxjQXV0b0NvcnJWYWx1ZShwU3BlY3RydW0sIGlkeDAsIGlkeDEsIDAsIG5zYzEpOwogICAgcnh4Ml8wID0gRkRLYWFjRW5jX0NhbGNBdXRvQ29yclZhbHVlKHBTcGVjdHJ1bSwgaWR4MSwgaWR4MiwgMCwgbnNjMik7CiAgICByeHgzXzAgPSBGREthYWNFbmNfQ2FsY0F1dG9Db3JyVmFsdWUocFNwZWN0cnVtLCBpZHgyLCBpZHgzLCAwLCBuc2MzKTsKICAgIHJ4eDRfMCA9IEZES2FhY0VuY19DYWxjQXV0b0NvcnJWYWx1ZShwU3BlY3RydW0sIGlkeDMsIGlkeDQsIDAsIG5zYzQpOwoKICAgIC8qIGNvbXB1dGUgZW5lcmd5IG5vcm1hbGl6YXRpb24gZmFjdG9ycywgaS4gZS4gMS9lbmVyZ3kgKHNhdmVzIHNvbWUgZGl2aXNpb25zKSAqLwogICAgaWYgKHJ4eDFfMCAhPSBGTDJGWENPTlNUX0RCTCgwLmYpKQogICAgewogICAgICAgIElOVCBzY19mYWMxID0gLTE7CiAgICAgICAgRklYUF9EQkwgZmFjMSA9IEZES2FhY0VuY19BdXRvQ29yck5vcm1GYWMocnh4MV8wLCAoKC0yKnNjMSkrbnNjMSksICZzY19mYWMxKTsKICAgICAgICBfcnh4MVswXSA9IHNjYWxlVmFsdWUoZk11bHQocnh4MV8wLGZhYzEpLHNjX2ZhYzEpOwoKICAgICAgICBmb3IgKGxhZyA9IDE7IGxhZyA8PSBtYXhPcmRlcjsgbGFnKyspIHsKICAgICAgICAgIC8qIGNvbXB1dGUgZW5lcmd5LW5vcm1hbGl6ZWQgYW5kIHdpbmRvd2VkIGF1dG9jb3JyZWxhdGlvbiB2YWx1ZXMgYXQgdGhpcyBsYWcgKi8KICAgICAgICAgIGlmICgoMyAqIGxhZykgPD0gbWF4T3JkZXIgKyAzKSB7CiAgICAgICAgICAgICAgRklYUF9EQkwgeDEgPSBGREthYWNFbmNfQ2FsY0F1dG9Db3JyVmFsdWUocFNwZWN0cnVtLCBpZHgwLCBpZHgxLCBsYWcsIG5zYzEpOwogICAgICAgICAgICAgIF9yeHgxW2xhZ10gPSBmTXVsdChzY2FsZVZhbHVlKGZNdWx0KHgxLGZhYzEpLHNjX2ZhYzEpLCBhY2ZXaW5kb3dbTE9GSUxUXVszKmxhZ10pOwogICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiBhdXRvIGNvcnIgb3ZlciB1cHBlciAzLzQgb2Ygc3BlY3RydW0gKi8KICAgIGlmICggISgocnh4Ml8wID09IEZMMkZYQ09OU1RfREJMKDAuZikpICYmIChyeHgzXzAgPT0gRkwyRlhDT05TVF9EQkwoMC5mKSkgJiYgKHJ4eDRfMCA9PSBGTDJGWENPTlNUX0RCTCgwLmYpKSkgKQogICAgewogICAgICAgIEZJWFBfREJMIGZhYzIsIGZhYzMsIGZhYzQ7CiAgICAgICAgZmFjMiA9IGZhYzMgPSBmYWM0ID0gRkwyRlhDT05TVF9EQkwoMC5mKTsKICAgICAgICBJTlQgc2NfZmFjMiwgc2NfZmFjMywgc2NfZmFjNDsKICAgICAgICBzY19mYWMyID0gc2NfZmFjMyA9IHNjX2ZhYzQgPSAwOwoKICAgICAgICBpZiAocnh4Ml8wIT1GTDJGWENPTlNUX0RCTCgwLmYpKSB7CiAgICAgICAgICBmYWMyID0gRkRLYWFjRW5jX0F1dG9Db3JyTm9ybUZhYyhyeHgyXzAsICgoLTIqc2MyKStuc2MyKSwgJnNjX2ZhYzIpOwogICAgICAgICAgc2NfZmFjMiAtPSAyOwogICAgICAgIH0KICAgICAgICBpZiAocnh4M18wIT1GTDJGWENPTlNUX0RCTCgwLmYpKSB7CiAgICAgICAgICBmYWMzID0gRkRLYWFjRW5jX0F1dG9Db3JyTm9ybUZhYyhyeHgzXzAsICgoLTIqc2MzKStuc2MzKSwgJnNjX2ZhYzMpOwogICAgICAgICAgc2NfZmFjMyAtPSAyOwogICAgICAgIH0KICAgICAgICBpZiAocnh4NF8wIT1GTDJGWENPTlNUX0RCTCgwLmYpKSB7CiAgICAgICAgICBmYWM0ID0gRkRLYWFjRW5jX0F1dG9Db3JyTm9ybUZhYyhyeHg0XzAsICgoLTIqc2M0KStuc2M0KSwgJnNjX2ZhYzQpOwogICAgICAgICAgc2NfZmFjNCAtPSAyOwogICAgICAgIH0KCiAgICAgICAgX3J4eDJbMF0gPSBzY2FsZVZhbHVlKGZNdWx0KHJ4eDJfMCxmYWMyKSxzY19mYWMyKSArCiAgICAgICAgICAgICAgICAgICBzY2FsZVZhbHVlKGZNdWx0KHJ4eDNfMCxmYWMzKSxzY19mYWMzKSArCiAgICAgICAgICAgICAgICAgICBzY2FsZVZhbHVlKGZNdWx0KHJ4eDRfMCxmYWM0KSxzY19mYWM0KTsKCiAgICAgICAgZm9yIChsYWcgPSAxOyBsYWcgPD0gbWF4T3JkZXI7IGxhZysrKSB7CiAgICAgICAgICAvKiBtZXJnZSBxdWFydGVycyAyLCAzLCA0IGludG8gb25lIGF1dG9jb3JyZWxhdGlvbjsgcXVhcnRlciAxIHN0YXlzIHNlcGFyYXRlICovCiAgICAgICAgICBGSVhQX0RCTCB4MiA9IHNjYWxlVmFsdWUoZk11bHQoRkRLYWFjRW5jX0NhbGNBdXRvQ29yclZhbHVlKHBTcGVjdHJ1bSwgaWR4MSwgaWR4MiwgbGFnLCBuc2MyKSwgZmFjMiksc2NfZmFjMikgKwogICAgICAgICAgICAgICAgICAgICAgICBzY2FsZVZhbHVlKGZNdWx0KEZES2FhY0VuY19DYWxjQXV0b0NvcnJWYWx1ZShwU3BlY3RydW0sIGlkeDIsIGlkeDMsIGxhZywgbnNjMyksIGZhYzMpLHNjX2ZhYzMpICsKICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVWYWx1ZShmTXVsdChGREthYWNFbmNfQ2FsY0F1dG9Db3JyVmFsdWUocFNwZWN0cnVtLCBpZHgzLCBpZHg0LCBsYWcsIG5zYzQpLCBmYWM0KSxzY19mYWM0KTsKCiAgICAgICAgICBfcnh4MltsYWddID0gZk11bHQoeDIsIGFjZldpbmRvd1tISUZJTFRdW2xhZ10pOwogICAgICAgIH0KICAgIH0KCiAgICBDX0FMTE9DX1NDUkFUQ0hfRU5EKHBTcGVjdHJ1bSwgRklYUF9EQkwsICgxMDI0KSk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX1Ruc0RldGVjdAogICAgZGVzY3JpcHRpb246ICBkbyBkZWNpc2lvbiwgaWYgVE5TIHNoYWxsIGJlIHVzZWQgb3Igbm90CiAgICByZXR1cm5zOgogICAgaW5wdXQ6ICAgICAgICB0bnMgZGF0YSBzdHJ1Y3R1cmUgKG1vZGlmaWVkKSwKICAgICAgICAgICAgICAgICAgdG5zIGNvbmZpZyBzdHJ1Y3R1cmUsCiAgICAgICAgICAgICAgICAgIHNjYWxlZmFjdG9yIHNpemUgYW5kIHRhYmxlLAogICAgICAgICAgICAgICAgICBzcGVjdHJ1bSwKICAgICAgICAgICAgICAgICAgc3ViYmxvY2sgbnVtLCBibG9ja3R5cGUsCiAgICAgICAgICAgICAgICAgIHNmYi13aXNlIGVuZXJneS4KCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpJTlQgRkRLYWFjRW5jX1Ruc0RldGVjdCgKICAgICAgICAgICAgICBUTlNfREFUQSAqdG5zRGF0YSwKICAgICAgICAgICAgICBjb25zdCBUTlNfQ09ORklHICp0QywKICAgICAgICAgICAgICBUTlNfSU5GTyogdG5zSW5mbywKICAgICAgICAgICAgICBJTlQgc2ZiQ250LAogICAgICAgICAgICAgIEZJWFBfREJMICpzcGVjdHJ1bSwKICAgICAgICAgICAgICBJTlQgc3ViQmxvY2tOdW1iZXIsCiAgICAgICAgICAgICAgSU5UIGJsb2NrVHlwZQogICAgICAgICAgICAgICkKewogIC8qIGF1dG9jb3JyZWxhdGlvbiBmdW5jdGlvbiBmb3IgMXN0LCAybmQsIDNyZCwgYW5kIDR0aCBxdWFydGVyIG9mIHRoZSBzcGVjdHJ1bS4gKi8KICBGSVhQX0RCTCByeHgxW1ROU19NQVhfT1JERVIrMV07IC8qIGhpZ2hlciBwYXJ0ICovCiAgRklYUF9EQkwgcnh4MltUTlNfTUFYX09SREVSKzFdOyAvKiBsb3dlciBwYXJ0ICovCiAgRklYUF9EQkwgcGFyY29yX3RtcFtUTlNfTUFYX09SREVSXTsKCiAgaW50IGk7CgogIFROU19TVUJCTE9DS19JTkZPICp0c2JpID0gKGJsb2NrVHlwZSA9PSBTSE9SVF9XSU5ET1cpCiAgICA/ICZ0bnNEYXRhLT5kYXRhUmF3LlNob3J0LnN1YkJsb2NrSW5mb1tzdWJCbG9ja051bWJlcl0KICAgIDogJnRuc0RhdGEtPmRhdGFSYXcuTG9uZy5zdWJCbG9ja0luZm87CgogIHRuc0RhdGEtPmZpbHRlcnNNZXJnZWQgID0gRkFMU0U7CiAgdHNiaS0+dG5zQWN0aXZlICAgICAgICAgPSBGQUxTRTsKICB0c2JpLT5wcmVkaWN0aW9uR2FpbiAgICA9IDEwMDA7CiAgdG5zSW5mby0+bnVtT2ZGaWx0ZXJzW3N1YkJsb2NrTnVtYmVyXSA9IDA7CiAgdG5zSW5mby0+Y29lZlJlc1tzdWJCbG9ja051bWJlcl0gICAgICA9IHRDLT5jb2VmUmVzOwogIGZvciAoaSA9IDA7IGkgPCB0Qy0+bWF4T3JkZXI7IGkrKykgewogICAgdG5zSW5mby0+Y29lZltzdWJCbG9ja051bWJlcl1bSElGSUxUXVtpXSA9IHRuc0luZm8tPmNvZWZbc3ViQmxvY2tOdW1iZXJdW0xPRklMVF1baV0gPSAwOwogIH0KCiAgdG5zSW5mby0+bGVuZ3RoW3N1YkJsb2NrTnVtYmVyXVtISUZJTFRdID0gdG5zSW5mby0+bGVuZ3RoW3N1YkJsb2NrTnVtYmVyXVtMT0ZJTFRdID0gMDsKICB0bnNJbmZvLT5vcmRlciBbc3ViQmxvY2tOdW1iZXJdW0hJRklMVF0gPSB0bnNJbmZvLT5vcmRlciBbc3ViQmxvY2tOdW1iZXJdW0xPRklMVF0gPSAwOwoKICBpZiAoICh0Qy0+dG5zQWN0aXZlKSAmJiAodEMtPm1heE9yZGVyPjApICkKICB7CiAgICBpbnQgc3VtU3FyQ29lZjsKCiAgICBGREthYWNFbmNfTWVyZ2VkQXV0b0NvcnJlbGF0aW9uKAogICAgICAgICAgc3BlY3RydW0sCiAgICAgICAgICB0Qy0+YWNmV2luZG93LAogICAgICAgICAgdEMtPmxwY1N0YXJ0TGluZSwKICAgICAgICAgIHRDLT5scGNTdG9wTGluZSwKICAgICAgICAgIHRDLT5tYXhPcmRlciwKICAgICAgICAgIHRDLT5jb25mVGFiLmFjZlNwbGl0LAogICAgICAgICAgcnh4MSwKICAgICAgICAgIHJ4eDIpOwoKICAgIC8qIGNvbXB1dGUgaGlnaGVyIFROUyBmaWx0ZXIgaW4gbGF0dGljZSAoUGFyQ29yKSBmb3JtIHdpdGggTGVSb3V4LUd1ZWd1ZW4gYWxnb3JpdGhtICovCiAgICB0c2JpLT5wcmVkaWN0aW9uR2FpbiA9IEZES2FhY0VuY19BdXRvVG9QYXJjb3Iocnh4MiwgcGFyY29yX3RtcCwgdEMtPmNvbmZUYWIudG5zTGltaXRPcmRlcltISUZJTFRdKTsKCiAgICAvKiBub24tbGluZWFyIHF1YW50aXphdGlvbiBvZiBUTlMgbGF0dGljZSBjb2VmZmljaWVudHMgd2l0aCBnaXZlbiByZXNvbHV0aW9uICovCiAgICBGREthYWNFbmNfUGFyY29yMkluZGV4KAogICAgICAgICAgICBwYXJjb3JfdG1wLAogICAgICAgICAgICB0bnNJbmZvLT5jb2VmW3N1YkJsb2NrTnVtYmVyXVtISUZJTFRdLAogICAgICAgICAgICB0Qy0+Y29uZlRhYi50bnNMaW1pdE9yZGVyW0hJRklMVF0sCiAgICAgICAgICAgIHRDLT5jb2VmUmVzKTsKCiAgICAvKiByZWR1Y2UgZmlsdGVyIG9yZGVyIGJ5IHRydW5jYXRpbmcgdHJhaWxpbmcgemVyb3MsIGNvbXB1dGUgc3VtKGFicyhjb2VmcykpICovCiAgICBmb3IgKGkgPSB0Qy0+Y29uZlRhYi50bnNMaW1pdE9yZGVyW0hJRklMVF0gLSAxOyBpID49IDA7IGktLSkgewogICAgICBpZiAodG5zSW5mby0+Y29lZltzdWJCbG9ja051bWJlcl1bSElGSUxUXVtpXSAhPSAwKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KCiAgICB0bnNJbmZvLT5vcmRlcltzdWJCbG9ja051bWJlcl1bSElGSUxUXSA9IGkgKyAxOwoKICAgIHN1bVNxckNvZWYgPSAwOwogICAgZm9yICg7IGkgPj0gMDsgaS0tKSB7CiAgICAgIHN1bVNxckNvZWYgKz0gdG5zSW5mby0+Y29lZltzdWJCbG9ja051bWJlcl1bSElGSUxUXVtpXSAqIHRuc0luZm8tPmNvZWZbc3ViQmxvY2tOdW1iZXJdW0hJRklMVF1baV07CiAgICB9CgogICAgdG5zSW5mby0+ZGlyZWN0aW9uW3N1YkJsb2NrTnVtYmVyXVtISUZJTFRdID0gdEMtPmNvbmZUYWIudG5zRmlsdGVyRGlyZWN0aW9uW0hJRklMVF07CiAgICB0bnNJbmZvLT5sZW5ndGhbc3ViQmxvY2tOdW1iZXJdW0hJRklMVF0gPSBzZmJDbnQgLSB0Qy0+bHBjU3RhcnRCYW5kW0hJRklMVF07CgogICAgLyogZGlzYWJsZSBUTlMgaWYgcHJlZGljdGlvbkdhaW4gaXMgbGVzcyB0aGFuIDNkQiBvciBzdW1TcXJDb2VmIGlzIHRvbyBzbWFsbCAqLwogICAgaWYgKCh0c2JpLT5wcmVkaWN0aW9uR2FpbiA+IHRDLT5jb25mVGFiLnRocmVzaE9uW0hJRklMVF0pIHx8IChzdW1TcXJDb2VmID4gKHRDLT5jb25mVGFiLnRuc0xpbWl0T3JkZXJbSElGSUxUXS8yICsgMikpKQogICAgewogICAgICB0c2JpLT50bnNBY3RpdmUgPSBUUlVFOwogICAgICB0bnNJbmZvLT5udW1PZkZpbHRlcnNbc3ViQmxvY2tOdW1iZXJdKys7CgogICAgICAvKiBjb21wdXRlIHNlY29uZCBmaWx0ZXIgZm9yIGxvd2VyIHF1YXJ0ZXI7IG9ubHkgYWxsb3dlZCBmb3IgbG9uZyB3aW5kb3dzISAqLwogICAgICBpZiAoIChibG9ja1R5cGUgIT0gU0hPUlRfV0lORE9XKSAmJgogICAgICAgICAgICh0Qy0+Y29uZlRhYi5maWx0ZXJFbmFibGVkW0xPRklMVF0pICYmICh0Qy0+Y29uZlRhYi5zZXBlcmF0ZUZpbHRlcnNBbGxvd2VkKSApCiAgICAgIHsKICAgICAgICAvKiBjb21wdXRlIHNlY29uZCBmaWx0ZXIgZm9yIGxvd2VyIGZyZXF1ZW5jaWVzICovCgogICAgICAgIC8qIGNvbXB1dGUgVE5TIGZpbHRlciBpbiBsYXR0aWNlIChQYXJDb3IpIGZvcm0gd2l0aCBMZVJvdXgtR3VlZ3VlbiBhbGdvcml0aG0gKi8KICAgICAgICBJTlQgcHJlZEdhaW4gPSBGREthYWNFbmNfQXV0b1RvUGFyY29yKHJ4eDEsIHBhcmNvcl90bXAsIHRDLT5jb25mVGFiLnRuc0xpbWl0T3JkZXJbTE9GSUxUXSk7CgogICAgICAgIC8qIG5vbi1saW5lYXIgcXVhbnRpemF0aW9uIG9mIFROUyBsYXR0aWNlIGNvZWZmaWNpZW50cyB3aXRoIGdpdmVuIHJlc29sdXRpb24gKi8KICAgICAgICBGREthYWNFbmNfUGFyY29yMkluZGV4KAogICAgICAgICAgICAgICAgcGFyY29yX3RtcCwKICAgICAgICAgICAgICAgIHRuc0luZm8tPmNvZWZbc3ViQmxvY2tOdW1iZXJdW0xPRklMVF0sCiAgICAgICAgICAgICAgICB0Qy0+Y29uZlRhYi50bnNMaW1pdE9yZGVyW0xPRklMVF0sCiAgICAgICAgICAgICAgICB0Qy0+Y29lZlJlcyk7CgogICAgICAgIC8qIHJlZHVjZSBmaWx0ZXIgb3JkZXIgYnkgdHJ1bmNhdGluZyB0cmFpbGluZyB6ZXJvcywgY29tcHV0ZSBzdW0oYWJzKGNvZWZzKSkgKi8KICAgICAgICBmb3IgKGkgPSB0Qy0+Y29uZlRhYi50bnNMaW1pdE9yZGVyW0xPRklMVF0gLSAxOyBpID49IDA7IGktLSkgewogICAgICAgICAgaWYgKHRuc0luZm8tPmNvZWZbc3ViQmxvY2tOdW1iZXJdW0xPRklMVF1baV0gIT0gMCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgdG5zSW5mby0+b3JkZXJbc3ViQmxvY2tOdW1iZXJdW0xPRklMVF0gPSBpICsgMTsKCiAgICAgICAgc3VtU3FyQ29lZiA9IDA7CiAgICAgICAgZm9yICg7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgICBzdW1TcXJDb2VmICs9IHRuc0luZm8tPmNvZWZbc3ViQmxvY2tOdW1iZXJdW0xPRklMVF1baV0gKiB0bnNJbmZvLT5jb2VmW3N1YkJsb2NrTnVtYmVyXVtMT0ZJTFRdW2ldOwogICAgICAgIH0KCiAgICAgICAgdG5zSW5mby0+ZGlyZWN0aW9uW3N1YkJsb2NrTnVtYmVyXVtMT0ZJTFRdID0gdEMtPmNvbmZUYWIudG5zRmlsdGVyRGlyZWN0aW9uW0xPRklMVF07CiAgICAgICAgdG5zSW5mby0+bGVuZ3RoW3N1YkJsb2NrTnVtYmVyXVtMT0ZJTFRdID0gdEMtPmxwY1N0YXJ0QmFuZFtISUZJTFRdIC0gdEMtPmxwY1N0YXJ0QmFuZFtMT0ZJTFRdOwoKICAgICAgICAvKiBmaWx0ZXIgbG93ZXIgcXVhcnRlciBpZiBnYWluIGlzIGhpZ2ggZW5vdWdoLCBidXQgbm90IGlmIGl0J3MgdG9vIGhpZ2ggKi8KICAgICAgICBpZiAoICggKHByZWRHYWluID4gdEMtPmNvbmZUYWIudGhyZXNoT25bTE9GSUxUXSkgJiYgKHByZWRHYWluIDwgKDE2MDAwICogdEMtPmNvbmZUYWIudG5zTGltaXRPcmRlcltMT0ZJTFRdKSkgKQogICAgICAgICAgfHwgKCAoc3VtU3FyQ29lZiA+IDkpICAmJiAoc3VtU3FyQ29lZiA8IDIyICogdEMtPmNvbmZUYWIudG5zTGltaXRPcmRlcltMT0ZJTFRdKSApICkKICAgICAgICB7CiAgICAgICAgICAvKiBjb21wYXJlIGxvd2VyIHRvIHVwcGVyIGZpbHRlcjsgaWYgdGhleSBhcmUgdmVyeSBzaW1pbGFyLCBtZXJnZSB0aGVtICovCiAgICAgICAgICBzdW1TcXJDb2VmID0gMDsKICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0Qy0+Y29uZlRhYi50bnNMaW1pdE9yZGVyW0xPRklMVF07IGkrKykgewogICAgICAgICAgICBzdW1TcXJDb2VmICs9IEZES2Ficyh0bnNJbmZvLT5jb2VmW3N1YkJsb2NrTnVtYmVyXVtISUZJTFRdW2ldIC0gdG5zSW5mby0+Y29lZltzdWJCbG9ja051bWJlcl1bTE9GSUxUXVtpXSk7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIChzdW1TcXJDb2VmIDwgMikgJiYKICAgICAgICAgICAgICAgKHRuc0luZm8tPmRpcmVjdGlvbltzdWJCbG9ja051bWJlcl1bTE9GSUxUXSA9PSB0bnNJbmZvLT5kaXJlY3Rpb25bc3ViQmxvY2tOdW1iZXJdW0hJRklMVF0pICkKICAgICAgICAgIHsKICAgICAgICAgICAgdG5zRGF0YS0+ZmlsdGVyc01lcmdlZCA9IFRSVUU7CiAgICAgICAgICAgIHRuc0luZm8tPmxlbmd0aFtzdWJCbG9ja051bWJlcl1bSElGSUxUXSA9IHNmYkNudCAtIHRDLT5scGNTdGFydEJhbmRbTE9GSUxUXTsKICAgICAgICAgICAgZm9yICg7IGkgPCB0bnNJbmZvLT5vcmRlcltzdWJCbG9ja051bWJlcl1bSElGSUxUXTsgaSsrKSB7CiAgICAgICAgICAgICAgaWYgKEZES2Ficyh0bnNJbmZvLT5jb2VmW3N1YkJsb2NrTnVtYmVyXVtISUZJTFRdW2ldKSA+IDEpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGktLTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgICBpZiAodG5zSW5mby0+Y29lZltzdWJCbG9ja051bWJlcl1bSElGSUxUXVtpXSAhPSAwKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGkgPCB0bnNJbmZvLT5vcmRlcltzdWJCbG9ja051bWJlcl1bSElGSUxUXSkgewogICAgICAgICAgICAgIHRuc0luZm8tPm9yZGVyW3N1YkJsb2NrTnVtYmVyXVtISUZJTFRdID0gaSArIDE7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgewogICAgICAgICAgICB0bnNJbmZvLT5udW1PZkZpbHRlcnNbc3ViQmxvY2tOdW1iZXJdKys7CiAgICAgICAgICB9CiAgICAgICAgfSAvKiBmaWx0ZXIgbG93ZXIgcGFydCAqLwogICAgICB9IC8qIHNlY29uZCBmaWx0ZXIgYWxsb3dlZCAgKi8KICAgIH0gLyogaWYgcHJlZGljdGlvbkdhaW4gPiAxNDM3IC4uLiAqLwogIH0gLyogbWF4T3JkZXIgPiAwICYmIHRuc0FjdGl2ZSAqLwoKICByZXR1cm4gMDsKCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIEZES2FhY0xkRW5jX1Ruc1N5bmMKCiAgc3luY2hyb25pemUgVE5TIHBhcmFtZXRlcnMgd2hlbiBUTlMgZ2FpbiBkaWZmZXJlbmNlIHNtYWxsIChyZWxhdGl2ZSkKCiAgXHBhcmFtIHBvaW50ZXIgdG8gVE5TIGRhdGEgc3RydWN0dXJlIChkZXN0aW5hdGlvbikKICBccGFyYW0gcG9pbnRlciB0byBUTlMgZGF0YSBzdHJ1Y3R1cmUgKHNvdXJjZSkKICBccGFyYW0gcG9pbnRlciB0byBUTlMgY29uZmlnIHN0cnVjdHVyZQogIFxwYXJhbSBudW1iZXIgb2Ygc3ViLWJsb2NrCiAgXHBhcmFtIGJsb2NrIHR5cGUKCiAgXHJldHVybiB2b2lkCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnZvaWQgRkRLYWFjRW5jX1Ruc1N5bmMoCiAgICAgICAgICAgICBUTlNfREFUQSAqdG5zRGF0YURlc3QsCiAgICAgICAgICAgICBjb25zdCBUTlNfREFUQSAqdG5zRGF0YVNyYywKICAgICAgICAgICAgIFROU19JTkZPICp0bnNJbmZvRGVzdCwKICAgICAgICAgICAgIFROU19JTkZPICp0bnNJbmZvU3JjLAogICAgICAgICAgICAgY29uc3QgSU5UIGJsb2NrVHlwZURlc3QsCiAgICAgICAgICAgICBjb25zdCBJTlQgYmxvY2tUeXBlU3JjLAogICAgICAgICAgICAgY29uc3QgVE5TX0NPTkZJRyAqdEMKICAgICAgICAgICAgICkKewogIGludCBpLCB3LCBhYnNEaWZmLCBuV2luZG93czsKICBUTlNfU1VCQkxPQ0tfSU5GTyAqc2JJbmZvRGVzdDsKICBjb25zdCBUTlNfU1VCQkxPQ0tfSU5GTyAqc2JJbmZvU3JjOwoKICAvKiBpZiBvbmUgY2hhbm5lbCBjb250YWlucyBzaG9ydCBibG9ja3MgYW5kIHRoZSBvdGhlciBub3QsIGRvIG5vdCBzeW5jaHJvbml6ZSAqLwogIGlmICggKGJsb2NrVHlwZVNyYyA9PSBTSE9SVF9XSU5ET1cgJiYgYmxvY2tUeXBlRGVzdCAhPSBTSE9SVF9XSU5ET1cpIHx8CiAgICAgICAoYmxvY2tUeXBlRGVzdCA9PSBTSE9SVF9XSU5ET1cgJiYgYmxvY2tUeXBlU3JjICE9IFNIT1JUX1dJTkRPVykgKQogIHsKICAgIHJldHVybjsKICB9CgogIGlmIChibG9ja1R5cGVEZXN0ICE9IFNIT1JUX1dJTkRPVykgewogICAgc2JJbmZvRGVzdCA9ICZ0bnNEYXRhRGVzdC0+ZGF0YVJhdy5Mb25nLnN1YkJsb2NrSW5mbzsKICAgIHNiSW5mb1NyYyAgPSAmdG5zRGF0YVNyYy0+ZGF0YVJhdy5Mb25nLnN1YkJsb2NrSW5mbzsKICAgIG5XaW5kb3dzICAgPSAxOwogIH0gZWxzZSB7CiAgICBzYkluZm9EZXN0ID0gJnRuc0RhdGFEZXN0LT5kYXRhUmF3LlNob3J0LnN1YkJsb2NrSW5mb1swXTsKICAgIHNiSW5mb1NyYyAgPSAmdG5zRGF0YVNyYy0+ZGF0YVJhdy5TaG9ydC5zdWJCbG9ja0luZm9bMF07CiAgICBuV2luZG93cyAgID0gODsKICB9CgogIGZvciAodz0wOyB3PG5XaW5kb3dzOyB3KyspIHsKICAgICAgY29uc3QgVE5TX1NVQkJMT0NLX0lORk8gKnBTYkluZm9TcmNXICA9IHNiSW5mb1NyYyAgKyB3OwogICAgICBUTlNfU1VCQkxPQ0tfSU5GTyAgICAgICAqcFNiSW5mb0Rlc3RXID0gc2JJbmZvRGVzdCArIHc7CiAgICAgIElOVCBkb1N5bmMgPSAxLCBhYnNEaWZmU3VtID0gMDsKCiAgICAgIC8qIGlmIFROUyBpcyBhY3RpdmUgaW4gYXQgbGVhc3Qgb25lIGNoYW5uZWwsIGNoZWNrIGlmIFBhckNvciBjb2VmZmljaWVudHMgb2YgaGlnaGVyIGZpbHRlciBhcmUgc2ltaWxhciAqLwogICAgICBpZiAocFNiSW5mb0Rlc3RXLT50bnNBY3RpdmUgfHwgcFNiSW5mb1NyY1ctPnRuc0FjdGl2ZSkgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCB0Qy0+bWF4T3JkZXI7IGkrKykgewogICAgICAgICAgYWJzRGlmZiA9IEZES2Ficyh0bnNJbmZvRGVzdC0+Y29lZlt3XVtISUZJTFRdW2ldIC0gdG5zSW5mb1NyYy0+Y29lZlt3XVtISUZJTFRdW2ldKTsKICAgICAgICAgIGFic0RpZmZTdW0gKz0gYWJzRGlmZjsKICAgICAgICAgIC8qIGlmIGNvZWZmaWNpZW50cyBkaXZlcmdlIHRvbyBtdWNoIGJldHdlZW4gY2hhbm5lbHMsIGRvIG5vdCBzeW5jaHJvbml6ZSAqLwogICAgICAgICAgaWYgKChhYnNEaWZmID4gMSkgfHwgKGFic0RpZmZTdW0gPiAyKSkgewogICAgICAgICAgICBkb1N5bmMgPSAwOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChkb1N5bmMpIHsKICAgICAgICAgICAgLyogaWYgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSB3YXMgZGV0ZWN0ZWQsIHN5bmNocm9uaXplIGNvZWZmaWNpZW50IHNldHMgKi8KICAgICAgICAgICAgaWYgKHBTYkluZm9TcmNXLT50bnNBY3RpdmUpIHsKICAgICAgICAgICAgICAvKiBubyBkZXN0IGZpbHRlciwgb3IgbW9yZSBkZXN0IHRoYW4gc291cmNlIGZpbHRlcnM6IHVzZSBvbmUgZGVzdCBmaWx0ZXIgKi8KICAgICAgICAgICAgICBpZiAoKCFwU2JJbmZvRGVzdFctPnRuc0FjdGl2ZSkgfHwKICAgICAgICAgICAgICAgICAgKChwU2JJbmZvRGVzdFctPnRuc0FjdGl2ZSkgJiYgKHRuc0luZm9EZXN0LT5udW1PZkZpbHRlcnNbd10gPiB0bnNJbmZvU3JjLT5udW1PZkZpbHRlcnNbd10pKSkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwU2JJbmZvRGVzdFctPnRuc0FjdGl2ZSA9IHRuc0luZm9EZXN0LT5udW1PZkZpbHRlcnNbd10gPSAxOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB0bnNEYXRhRGVzdC0+ZmlsdGVyc01lcmdlZCA9IHRuc0RhdGFTcmMtPmZpbHRlcnNNZXJnZWQ7CiAgICAgICAgICAgICAgdG5zSW5mb0Rlc3QtPm9yZGVyICAgICAgIFt3XVtISUZJTFRdID0gdG5zSW5mb1NyYy0+b3JkZXIgICAgICAgW3ddW0hJRklMVF07CiAgICAgICAgICAgICAgdG5zSW5mb0Rlc3QtPmxlbmd0aCAgICAgIFt3XVtISUZJTFRdID0gdG5zSW5mb1NyYy0+bGVuZ3RoICAgICAgW3ddW0hJRklMVF07CiAgICAgICAgICAgICAgdG5zSW5mb0Rlc3QtPmRpcmVjdGlvbiAgIFt3XVtISUZJTFRdID0gdG5zSW5mb1NyYy0+ZGlyZWN0aW9uICAgW3ddW0hJRklMVF07CiAgICAgICAgICAgICAgdG5zSW5mb0Rlc3QtPmNvZWZDb21wcmVzc1t3XVtISUZJTFRdID0gdG5zSW5mb1NyYy0+Y29lZkNvbXByZXNzW3ddW0hJRklMVF07CgogICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0Qy0+bWF4T3JkZXI7IGkrKykgewogICAgICAgICAgICAgICAgdG5zSW5mb0Rlc3QtPmNvZWZbd11bSElGSUxUXVtpXSA9IHRuc0luZm9TcmMtPmNvZWZbd11bSElGSUxUXVtpXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgIHBTYkluZm9EZXN0Vy0+dG5zQWN0aXZlID0gdG5zSW5mb0Rlc3QtPm51bU9mRmlsdGVyc1t3XSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIEZES2FhY0VuY19UbnNFbmNvZGUKCiAgcGVyZm9ybSBUTlMgZW5jb2RpbmcKCiAgXHBhcmFtIHBvaW50ZXIgdG8gVE5TIGluZm8gc3RydWN0dXJlCiAgXHBhcmFtIHBvaW50ZXIgdG8gVE5TIGRhdGEgc3RydWN0dXJlCiAgXHBhcmFtIG51bWJlciBvZiBzZmJzCiAgXHBhcmFtIHBvaW50ZXIgdG8gVE5TIGNvbmZpZyBzdHJ1Y3R1cmUKICBccGFyYW0gbG93LXBhc3MgbGluZQogIFxwYXJhbSBwb2ludGVyIHRvIHNwZWN0cnVtCiAgXHBhcmFtIG51bWJlciBvZiBzdWItYmxvY2sKICBccGFyYW0gYmxvY2sgdHlwZQoKICBccmV0dXJuIEVSUk9SIFNUQVRVUwoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpJTlQgRkRLYWFjRW5jX1Ruc0VuY29kZSgKICAgICAgICBUTlNfSU5GTyogdG5zSW5mbywKICAgICAgICBUTlNfREFUQSogdG5zRGF0YSwKICAgICAgICBjb25zdCBJTlQgbnVtT2ZTZmIsCiAgICAgICAgY29uc3QgVE5TX0NPTkZJRyAqdEMsCiAgICAgICAgY29uc3QgSU5UIGxvd1Bhc3NMaW5lLAogICAgICAgIEZJWFBfREJMKiBzcGVjdHJ1bSwKICAgICAgICBjb25zdCBJTlQgc3ViQmxvY2tOdW1iZXIsCiAgICAgICAgY29uc3QgSU5UIGJsb2NrVHlwZQogICAgICAgICkKewogICAgSU5UIGksIHN0YXJ0TGluZSwgc3RvcExpbmU7CgogICAgaWYgKCAoIChibG9ja1R5cGUgPT0gU0hPUlRfV0lORE9XKSAmJiAoIXRuc0RhdGEtPmRhdGFSYXcuU2hvcnQuc3ViQmxvY2tJbmZvW3N1YkJsb2NrTnVtYmVyXS50bnNBY3RpdmUpICkKICAgICAgfHwgKCAoYmxvY2tUeXBlICE9IFNIT1JUX1dJTkRPVykgJiYgKCF0bnNEYXRhLT5kYXRhUmF3Lkxvbmcuc3ViQmxvY2tJbmZvLnRuc0FjdGl2ZSkgKSApCiAgICB7CiAgICAgIHJldHVybiAxOwogICAgfQoKICAgIHN0YXJ0TGluZSA9ICh0bnNEYXRhLT5maWx0ZXJzTWVyZ2VkKSA/IHRDLT5scGNTdGFydExpbmVbTE9GSUxUXSA6IHRDLT5scGNTdGFydExpbmVbSElGSUxUXTsKICAgIHN0b3BMaW5lICA9IHRDLT5scGNTdG9wTGluZTsKCiAgICBmb3IgKGk9MDsgaTx0bnNJbmZvLT5udW1PZkZpbHRlcnNbc3ViQmxvY2tOdW1iZXJdOyBpKyspIHsKCiAgICAgICAgSU5UIGxwY0dhaW5GYWN0b3I7CiAgICAgICAgRklYUF9EQkwgTHBjQ29lZmZbVE5TX01BWF9PUkRFUl07CiAgICAgICAgRklYUF9EQkwgd29ya0J1ZmZlcltUTlNfTUFYX09SREVSXTsKICAgICAgICBGSVhQX0RCTCBwYXJjb3JfdG1wW1ROU19NQVhfT1JERVJdOwoKICAgICAgICBGREthYWNFbmNfSW5kZXgyUGFyY29yKAogICAgICAgICAgICAgICAgdG5zSW5mby0+Y29lZltzdWJCbG9ja051bWJlcl1baV0sCiAgICAgICAgICAgICAgICBwYXJjb3JfdG1wLAogICAgICAgICAgICAgICAgdG5zSW5mby0+b3JkZXJbc3ViQmxvY2tOdW1iZXJdW2ldLAogICAgICAgICAgICAgICAgdEMtPmNvZWZSZXMpOwoKICAgICAgICBscGNHYWluRmFjdG9yID0gRkRLYWFjRW5jX1BhcmNvclRvTHBjKAogICAgICAgICAgICAgICAgcGFyY29yX3RtcCwKICAgICAgICAgICAgICAgIExwY0NvZWZmLAogICAgICAgICAgICAgICAgdG5zSW5mby0+b3JkZXJbc3ViQmxvY2tOdW1iZXJdW2ldLAogICAgICAgICAgICAgICAgd29ya0J1ZmZlcik7CgogICAgICAgIEZES2FhY0VuY19BbmFseXNpc0ZpbHRlcigKICAgICAgICAgICAgICAgICZzcGVjdHJ1bVtzdGFydExpbmVdLAogICAgICAgICAgICAgICAgc3RvcExpbmUgLSBzdGFydExpbmUsCiAgICAgICAgICAgICAgICBMcGNDb2VmZiwKICAgICAgICAgICAgICAgIHRuc0luZm8tPm9yZGVyW3N1YkJsb2NrTnVtYmVyXVtpXSwKICAgICAgICAgICAgICAgIGxwY0dhaW5GYWN0b3IpOwoKICAgICAgICAvKiB1cGRhdGUgZm9yIHNlY29uZCBmaWx0ZXIgKi8KICAgICAgICBzdGFydExpbmUgPSB0Qy0+bHBjU3RhcnRMaW5lW0xPRklMVF07CiAgICAgICAgc3RvcExpbmUgID0gdEMtPmxwY1N0YXJ0TGluZVtISUZJTFRdOwogICAgfQoKICAgIHJldHVybigwKTsKCn0KCnN0YXRpYyB2b2lkIEZES2FhY0VuY19DYWxjR2F1c3NXaW5kb3coCiAgICAgICAgRklYUF9EQkwgKndpbiwKICAgICAgICBjb25zdCBpbnQgd2luU2l6ZSwKICAgICAgICBjb25zdCBJTlQgc2FtcGxpbmdSYXRlLAogICAgICAgIGNvbnN0IElOVCB0cmFuc2Zvcm1SZXNvbHV0aW9uLAogICAgICAgIGNvbnN0IEZJWFBfREJMIHRpbWVSZXNvbHV0aW9uLAogICAgICAgIGNvbnN0IElOVCB0aW1lUmVzb2x1dGlvbl9lCiAgICAgICAgKQp7CiAgI2RlZmluZSBQSV9FICAgICAgICAgICAoMikKICAjZGVmaW5lIFBJX00gICAgICAgICAgIEZMMkZYQ09OU1RfREJMKDMuMTQxNmYvKGZsb2F0KSgxPDxQSV9FKSkKCiAgI2RlZmluZSBFVUxFUl9FICAgICAgICAoMikKICAjZGVmaW5lIEVVTEVSX00gICAgICAgIEZMMkZYQ09OU1RfREJMKDIuNzE4My8oZmxvYXQpKDE8PEVVTEVSX0UpKQoKICAjZGVmaW5lIENPRUZGX0xPT1BfU0NBTEUgKDQpCgogIElOVCBpLCBlMSwgZTIsIGdhdXNzRXhwX2U7CiAgRklYUF9EQkwgZ2F1c3NFeHBfbTsKCiAgLyogY2FsYy4gd2luZG93IGV4cG9uZW50IGZyb20gdGltZSByZXNvbHV0aW9uOgogICAqCiAgICogICBnYXVzc0V4cCA9IFBJICogc2FtcGxpbmdSYXRlICogMC4wMDFmICogdGltZVJlc29sdXRpb24gLyB0cmFuc2Zvcm1SZXNvbHV0aW9uOwogICAqICAgZ2F1c3NFeHAgPSAtMC41ZiAqIGdhdXNzRXhwICogZ2F1c3NFeHA7CiAgICovCiAgZ2F1c3NFeHBfbSA9IGZNdWx0Tm9ybSh0aW1lUmVzb2x1dGlvbiwgZk11bHQoUElfTSwgZkRpdk5vcm0oIChGSVhQX0RCTCkoc2FtcGxpbmdSYXRlKSwgKEZJWFBfREJMKShMT05HKSh0cmFuc2Zvcm1SZXNvbHV0aW9uKjEwMDAuZiksICZlMSkpLCAmZTIpOwogIGdhdXNzRXhwX20gPSAtZlBvdzJEaXYyKGdhdXNzRXhwX20pOwogIGdhdXNzRXhwX2UgPSAyKihlMStlMit0aW1lUmVzb2x1dGlvbl9lK1BJX0UpOwoKICBGREtfQVNTRVJUKCB3aW5TaXplIDwgKDE8PENPRUZGX0xPT1BfU0NBTEUpICk7CgogIC8qIGNhbGMuIHdpbmRvdyBjb2VmZmljaWVudHMKICAgKiAgIHdpbltpXSA9IChmbG9hdClleHAoIGdhdXNzRXhwICogKGkrMC41KSAqIChpKzAuNSkgKTsKICAgKi8KICBmb3IoIGk9MDsgaTx3aW5TaXplOyBpKyspIHsKCiAgICB3aW5baV0gPSBmUG93KAogICAgICAgICAgICBFVUxFUl9NLAogICAgICAgICAgICBFVUxFUl9FLAogICAgICAgICAgICBmTXVsdChnYXVzc0V4cF9tLCBmUG93MigoaSpGTDJGWENPTlNUX0RCTCgxLmYvKGZsb2F0KSgxPDxDT0VGRl9MT09QX1NDQUxFKSkgKyBGTDJGWENPTlNUX0RCTCguNWYvKGZsb2F0KSgxPDxDT0VGRl9MT09QX1NDQUxFKSkpKSksCiAgICAgICAgICAgIGdhdXNzRXhwX2UgKyAyKkNPRUZGX0xPT1BfU0NBTEUsCiAgICAgICAgICAgJmUxKTsKCiAgICB3aW5baV0gPSBzY2FsZVZhbHVlU2F0dXJhdGUod2luW2ldLCBlMSk7CiAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBGREthYWNFbmNfQXV0b1RvUGFyY29yCgogIGNvbnZlcnNpb24gYXV0b2NvcnJlbGF0aW9uIHRvIHJlZmxlY3Rpb24gY29lZmZpY2llbnRzCgogIFxwYXJhbSBwb2ludGVyIHRvIGlucHV0IChhY2YpCiAgXHBhcmFtIHBvaW50ZXIgdG8gb3V0cHV0IChyZWZsZWN0aW9uIGNvZWZmaWNpZW50cykKICBccGFyYW0gbnVtYmVyIG9mIGNvZWZmaWNpZW50cwoKICBccmV0dXJuIHByZWRpY3Rpb24gZ2FpbgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSU5UIEZES2FhY0VuY19BdXRvVG9QYXJjb3IoCiAgICAgICAgRklYUF9EQkwgKlJFU1RSSUNUIGlucHV0LAogICAgICAgIEZJWFBfREJMICpSRVNUUklDVCByZWZsQ29lZmYsCiAgICAgICAgY29uc3QgSU5UIG51bU9mQ29lZmYKICAgICAgICApCnsKICBJTlQgICAgICAgaSwgaiwgc2NhbGU9MDsKICBGSVhQX0RCTCAgdG1wLCBwYXJjb3JXb3JrQnVmZmVyW1ROU19NQVhfT1JERVJdOwogIElOVCAgICAgICBwcmVkaWN0aW9uR2FpbiA9IChJTlQpKFROU19QUkVER0FJTl9TQ0FMRSk7CgogIEZJWFBfREJMICpSRVNUUklDVCB3b3JrQnVmZmVyID0gcGFyY29yV29ya0J1ZmZlcjsKICBjb25zdCBGSVhQX0RCTCAgYXV0b0NvcnJfMCA9IGlucHV0WzBdOwoKICBpZigoRklYUF9EQkwpaW5wdXRbMF0gPT0gRkwyRlhDT05TVF9EQkwoMC4wKSkgewogICAgRkRLbWVtY2xlYXIocmVmbENvZWZmLG51bU9mQ29lZmYqc2l6ZW9mKEZJWFBfREJMKSk7CiAgICByZXR1cm4ocHJlZGljdGlvbkdhaW4pOwogIH0KCiAgRkRLbWVtY3B5KHdvcmtCdWZmZXIsJmlucHV0WzFdLG51bU9mQ29lZmYqc2l6ZW9mKEZJWFBfREJMKSk7CiAgZm9yKGk9MDsgaTxudW1PZkNvZWZmOyBpKyspIHsKICAgIExPTkcgc2lnbiA9ICgoTE9ORyl3b3JrQnVmZmVyWzBdID4+IChERlJBQ1RfQklUUy0xKSk7CiAgICB0bXAgPSAoRklYUF9EQkwpKChMT05HKXdvcmtCdWZmZXJbMF1ec2lnbik7CgogICAgaWYoaW5wdXRbMF08dG1wKQogICAgICBicmVhazsKCiAgICB0bXAgPSAoRklYUF9EQkwpKChMT05HKXNjaHVyX2Rpdih0bXAsIGlucHV0WzBdLCBGUkFDVF9CSVRTKV4ofnNpZ24pKTsKICAgIHJlZmxDb2VmZltpXSA9IHRtcDsKCiAgICBmb3Ioaj1udW1PZkNvZWZmLWktMTsgaj49MDsgai0tKSB7CiAgICAgIEZJWFBfREJMIGFjY3UxID0gZk11bHQodG1wLCBpbnB1dFtqXSk7CiAgICAgIEZJWFBfREJMIGFjY3UyID0gZk11bHQodG1wLCB3b3JrQnVmZmVyW2pdKTsKICAgICAgd29ya0J1ZmZlcltqXSArPSBhY2N1MTsKICAgICAgaW5wdXRbal0gKz0gYWNjdTI7CiAgICB9CgogICAgd29ya0J1ZmZlcisrOwogIH0KCiAgdG1wID0gZk11bHQoKEZJWFBfREJMKSgoTE9ORylUTlNfUFJFREdBSU5fU0NBTEU8PDIxKSwgZkRpdk5vcm0oZkFicyhhdXRvQ29ycl8wKSwgZkFicyhpbnB1dFswXSksICZzY2FsZSkpOwogIGlmICggZk11bHREaXYyKGF1dG9Db3JyXzAsIGlucHV0WzBdKTxGTDJGWENPTlNUX0RCTCgwLjBmKSApIHsKICAgIHRtcCA9IC10bXA7CiAgfQogIHByZWRpY3Rpb25HYWluID0gKExPTkcpc2NhbGVWYWx1ZSh0bXAsc2NhbGUtMjEpOwoKICByZXR1cm4gKHByZWRpY3Rpb25HYWluKTsKfQoKCnN0YXRpYyBJTlQgRkRLYWFjRW5jX1NlYXJjaDMoRklYUF9EQkwgcGFyY29yKQp7CiAgSU5UIGksIGluZGV4PTA7CgogIGZvcihpPTA7aTw4O2krKyl7CiAgICBpZihwYXJjb3IgPiBGREthYWNFbmNfdG5zQ29lZmYzQm9yZGVyc1tpXSkKICAgICAgaW5kZXg9aTsKICB9CiAgcmV0dXJuKGluZGV4LTQpOwp9CgpzdGF0aWMgSU5UIEZES2FhY0VuY19TZWFyY2g0KEZJWFBfREJMIHBhcmNvcikKewogIElOVCBpLCBpbmRleD0wOwoKICBmb3IoaT0wO2k8MTY7aSsrKXsKICAgIGlmKHBhcmNvciA+IEZES2FhY0VuY190bnNDb2VmZjRCb3JkZXJzW2ldKQogICAgICBpbmRleD1pOwogIH0KICByZXR1cm4oaW5kZXgtOCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19QYXJjb3IySW5kZXgKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBGREthYWNFbmNfUGFyY29yMkluZGV4KAogICAgICAgIGNvbnN0IEZJWFBfREJMICpwYXJjb3IsCiAgICAgICAgSU5UICpSRVNUUklDVCBpbmRleCwKICAgICAgICBjb25zdCBJTlQgb3JkZXIsCiAgICAgICAgY29uc3QgSU5UIGJpdHNQZXJDb2VmZgogICAgICAgICkKewogIElOVCBpOwogIGZvcihpPTA7IGk8b3JkZXI7IGkrKykgewogICAgaWYoYml0c1BlckNvZWZmID09IDMpCiAgICAgIGluZGV4W2ldID0gRkRLYWFjRW5jX1NlYXJjaDMocGFyY29yW2ldKTsKICAgIGVsc2UKICAgICAgaW5kZXhbaV0gPSBGREthYWNFbmNfU2VhcmNoNChwYXJjb3JbaV0pOwogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX0luZGV4MlBhcmNvcgogICAgZGVzY3JpcHRpb246ICBpbnZlcnNlIHF1YW50aXphdGlvbiBmb3IgcmVmbGVjdGlvbiBjb2VmZmljaWVudHMKICAgIHJldHVybnM6ICAgICAgLQogICAgaW5wdXQ6ICAgICAgICBxdWFudGl6ZWQgdmFsdWVzLCBwdHIuIHRvIHJlZmxlY3Rpb24gY29lZmZpY2llbnRzLAogICAgICAgICAgICAgICAgICBuby4gb2YgY29lZmZpY2llbnRzLCByZXNvbHV0aW9uCiAgICBvdXRwdXQ6ICAgICAgIHJlZmxlY3Rpb24gY29lZmZpY2llbnRzCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgRkRLYWFjRW5jX0luZGV4MlBhcmNvcigKICAgICAgICBjb25zdCBJTlQgKmluZGV4LAogICAgICAgIEZJWFBfREJMICpSRVNUUklDVCBwYXJjb3IsCiAgICAgICAgY29uc3QgSU5UIG9yZGVyLAogICAgICAgIGNvbnN0IElOVCBiaXRzUGVyQ29lZmYKICAgICAgICApCnsKICBJTlQgaTsKICBmb3IoaT0wOyBpPG9yZGVyOyBpKyspCiAgICBwYXJjb3JbaV0gPSBiaXRzUGVyQ29lZmYgPT0gNCA/IEZES2FhY0VuY190bnNFbmNDb2VmZjRbaW5kZXhbaV0rOF0gOiBGREthYWNFbmNfdG5zRW5jQ29lZmYzW2luZGV4W2ldKzRdOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgZnVuY3Rpb25uYW1lOiBGREthYWNFbmNfUGFyY29yVG9McGMKICAgIGRlc2NyaXB0aW9uOiAgY29udmVyc2lvbiByZWZsZWN0aW9uIGNvZWZmaWNpZW50cyB0byBMUEMgY29lZmZpY2llbnRzCiAgICByZXR1cm5zOiAgICAgIEdhaW4gZmFjdG9yCiAgICBpbnB1dDogICAgICAgIHJlZmxlY3Rpb24gY29lZmZpY2llbnRzLCBuby4gb2YgcmVmbGVjdGlvbiBjb2VmZmljaWVudHMgPG9yZGVyPiwKICAgICAgICAgICAgICAgICAgcHRyLiB0byB3b3JrIGJ1ZmZlciAocmVxdWlyZWQgc2l6ZTogb3JkZXIpCiAgICBvdXRwdXQ6ICAgICAgIDxvcmRlcj4gTFBDIGNvZWZmaWNpZW50cwoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBJTlQgRkRLYWFjRW5jX1BhcmNvclRvTHBjKAogICAgICAgIGNvbnN0IEZJWFBfREJMICpyZWZsQ29lZmYsCiAgICAgICAgRklYUF9EQkwgKlJFU1RSSUNUIExwY0NvZWZmLAogICAgICAgIGNvbnN0IElOVCBudW1PZkNvZWZmLAogICAgICAgIEZJWFBfREJMICpSRVNUUklDVCB3b3JrQnVmZmVyCiAgICAgICAgKQp7CiAgSU5UIGksIGo7CiAgSU5UIHNoaWZ0dmFsLCBwYXIyTHBjU2hpZnRWYWwgPSA2OyAgLyogNiBzaG91bGQgYmUgZW5vdWdoLCBiZWMuIG1heChudW1PZkNvZWZmKSA9IDIwICovCiAgRklYUF9EQkwgbWF4VmFsID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CgogIExwY0NvZWZmWzBdID0gcmVmbENvZWZmWzBdID4+IHBhcjJMcGNTaGlmdFZhbDsKICBmb3IoaT0xOyBpPG51bU9mQ29lZmY7IGkrKykgewogICAgZm9yKGo9MDsgajxpOyBqKyspIHsKICAgICAgICB3b3JrQnVmZmVyW2pdID0gTHBjQ29lZmZbaS0xLWpdOwogICAgfQoKICAgIGZvcihqPTA7IGo8aTsgaisrKSB7CiAgICAgICAgTHBjQ29lZmZbal0gKz0gZk11bHQocmVmbENvZWZmW2ldLHdvcmtCdWZmZXJbal0pOwogICAgfQoKICAgIExwY0NvZWZmW2ldID0gcmVmbENvZWZmW2ldID4+IHBhcjJMcGNTaGlmdFZhbDsKICB9CgogIC8qIG5vcm1hbGl6ZSBMcGNDb2VmZiBhbmQgY2FsYyBzaGlmdGZhY3RvciAqLwogIGZvcihpPTA7IGk8bnVtT2ZDb2VmZjsgaSsrKSB7CiAgICAgIG1heFZhbCA9IGZpeE1heChtYXhWYWwsKEZJWFBfREJMKWZpeHBfYWJzKExwY0NvZWZmW2ldKSk7CiAgfQoKICBzaGlmdHZhbCA9IENvdW50TGVhZGluZ0JpdHMobWF4VmFsKTsKICBzaGlmdHZhbCA9IChzaGlmdHZhbD49cGFyMkxwY1NoaWZ0VmFsKSA/IHBhcjJMcGNTaGlmdFZhbCA6IHNoaWZ0dmFsOwoKICBmb3IoaT0wOyBpPG51bU9mQ29lZmY7IGkrKykKICAgICAgTHBjQ29lZmZbaV0gPSBMcGNDb2VmZltpXTw8c2hpZnR2YWw7CgogIHJldHVybiAocGFyMkxwY1NoaWZ0VmFsIC0gc2hpZnR2YWwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIEZES2FhY0VuY19BbmFseXNpc0ZpbHRlcgoKICBUTlMgYW5hbHlzaXMgZmlsdGVyIChhbGwtemVybyBmaWx0ZXIpCgogIFxwYXJhbSBwb2ludGVyIHRvIHNpZ25hbCBzcGVjdHJ1bQogIFxwYXJhbSBudW1iZXIgb2YgbGluZXMKICBccGFyYW0gcG9pbnRlciB0byBscGMgY29lZmZpY2llbnRzCiAgXHBhcmFtIGZpbHRlciBvcmRlcgogIFxwYXJhbSBscGMgZ2FpbiBmYWN0b3IKCiAgXHJldHVybiB2b2lkCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIE5vdGU6IGluLXBsYWNlIGNvbXB1dGF0aW9uIHBvc3NpYmxlICovCnN0YXRpYyB2b2lkIEZES2FhY0VuY19BbmFseXNpc0ZpbHRlcigKICAgICAgICBGSVhQX0RCTCAqUkVTVFJJQ1Qgc2lnbmFsLAogICAgICAgIGNvbnN0IElOVCBudW1PZkxpbmVzLAogICAgICAgIGNvbnN0IEZJWFBfREJMICpwcmVkaWN0b3JDb2VmZiwKICAgICAgICBjb25zdCBJTlQgb3JkZXIsCiAgICAgICAgY29uc3QgSU5UIGxwY0dhaW5GYWN0b3IKICAgICAgICApCnsKICBGSVhQX0RCTCBzdGF0dXNWYXJbVE5TX01BWF9PUkRFUl07CiAgSU5UIGksIGo7CiAgY29uc3QgSU5UIHNoaWZ0ID0gbHBjR2FpbkZhY3RvciArIDE7ICAgICAgLyogKzEsIGJlY2F1c2UgZk11bHREaXYyICovCiAgRklYUF9EQkwgdG1wOwoKICBpZiAob3JkZXI+MCkgewoKICAgIElOVCBpZHggPSAwOwoKICAgIC8qIGtlZXAgZmlsdGVyIGNvZWZmaWNpZW50cyB0d2ljZSBhbmQgc2F2ZSBtZW1vcnkgY29weSBvcGVyYXRpb24gaW4KICAgICAgIG1vZHVsbyBzdGF0ZSBidWZmZXIgKi8KI2lmIGRlZmluZWQoQVJDSF9QUkVGRVJfTVVMVF8zMngxNikKICAgIEZJWFBfU0dMICBjb2VmZlsyKlROU19NQVhfT1JERVJdOwogICAgY29uc3QgRklYUF9TR0wgKnBDb2VmZjsKICAgIGZvcihpPTA7aTxvcmRlcjtpKyspIHsKICAgICAgY29lZmZbaV0gICAgICAgPSBGWF9EQkwyRlhfU0dMKHByZWRpY3RvckNvZWZmW2ldKTsKICAgIH0KICAgIEZES21lbWNweSgmY29lZmZbb3JkZXJdLCBjb2VmZiwgb3JkZXIqc2l6ZW9mKEZJWFBfU0dMKSk7CiNlbHNlCiAgICBGSVhQX0RCTCAgY29lZmZbMipUTlNfTUFYX09SREVSXTsKICAgIGNvbnN0IEZJWFBfREJMICpwQ29lZmY7CiAgICBGREttZW1jcHkoJmNvZWZmWzBdLCAgICAgcHJlZGljdG9yQ29lZmYsIG9yZGVyKnNpemVvZihGSVhQX0RCTCkpOwogICAgRkRLbWVtY3B5KCZjb2VmZltvcmRlcl0sIHByZWRpY3RvckNvZWZmLCBvcmRlcipzaXplb2YoRklYUF9EQkwpKTsKI2VuZGlmCiAgICBGREttZW1jbGVhcihzdGF0dXNWYXIsIG9yZGVyKnNpemVvZihGSVhQX0RCTCkpOwoKICAgIGZvcihqPTA7IGo8bnVtT2ZMaW5lczsgaisrKSB7CiAgICAgIHBDb2VmZiA9ICZjb2VmZlsob3JkZXItaWR4KV07CiAgICAgIHRtcCA9IEZMMkZYQ09OU1RfREJMKDApOwogICAgICBmb3IoaT0wOyBpPG9yZGVyOyBpKyspIHsKICAgICAgICAgIHRtcCA9IGZNdWx0QWRkRGl2Mih0bXAsIHBDb2VmZltpXSwgc3RhdHVzVmFyW2ldKSA7CiAgICAgIH0KCiAgICAgIGlmKC0taWR4PDApIHsgaWR4ID0gb3JkZXItMTsgfQogICAgICBzdGF0dXNWYXJbaWR4XSA9IHNpZ25hbFtqXTsKCiAgICAgIEZES19BU1NFUlQobHBjR2FpbkZhY3Rvcj49MCk7CiAgICAgIHNpZ25hbFtqXSA9ICh0bXA8PHNoaWZ0KSArIHNpZ25hbFtqXTsKICAgIH0KICB9Cn0KCgo=