Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgojaW5jbHVkZSAibWhfZGV0LmgiCgojaW5jbHVkZSAic2JyX3JhbS5oIgojaW5jbHVkZSAic2JyX21pc2MuaCIKCgojaW5jbHVkZSAiZ2VuZXJpY1N0ZHMuaCIKCiNkZWZpbmUgU0ZNX1NISUZUIDIgICAgIC8qIEF0dGVudGlvbjogU0ZNX1NDQUxFIGRlcGVuZHMgb24gU0ZNX1NISUZUICovCiNkZWZpbmUgU0ZNX1NDQUxFIChNQVhWQUxfREJMID4+IFNGTV9TSElGVCkgICAvKiAxLjAgPj4gU0ZNX1NISUZUICovCgoKLyohPCBEZXRlY3RvciBQYXJhbWV0ZXJzIGZvciBBQUMgY29yZSBjb2RlYy4gKi8Kc3RhdGljIGNvbnN0IERFVEVDVE9SX1BBUkFNRVRFUlNfTUggcGFyYW1zQWFjID0gewo5LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qITwgZGVsdGFUaW1lICovCnsKRkwyRlhDT05TVF9EQkwoMjAuMGYqUkVMQVhBVElPTl9GTE9BVCksICAgICAgICAvKiE8IHRocmVzSG9sZERpZmYgKi8KRkwyRlhDT05TVF9EQkwoMS4yNmYqUkVMQVhBVElPTl9GTE9BVCksICAgICAgICAvKiE8IHRocmVzSG9sZERpZmZHdWlkZSAqLwpGTDJGWENPTlNUX0RCTCgxNS4wZipSRUxBWEFUSU9OX0ZMT0FUKSwgICAgICAgIC8qITwgdGhyZXNIb2xkVG9uZSAqLwpGTDJGWENPTlNUX0RCTCgoMS4wZi8xNS4wZikqUkVMQVhBVElPTl9GTE9BVCksIC8qITwgaW52VGhyZXNIb2xkVG9uZSAqLwpGTDJGWENPTlNUX0RCTCgxLjI2ZipSRUxBWEFUSU9OX0ZMT0FUKSwgICAgICAgIC8qITwgdGhyZXNIb2xkVG9uZUd1aWRlICovCkZMMkZYQ09OU1RfREJMKDAuM2YpPj5TRk1fU0hJRlQsICAgICAgICAgICAgICAgLyohPCBzZm1UaHJlc1NiciAqLwpGTDJGWENPTlNUX0RCTCgwLjFmKT4+U0ZNX1NISUZULCAgICAgICAgICAgICAgIC8qITwgc2ZtVGhyZXNPcmlnICovCkZMMkZYQ09OU1RfREJMKDAuM2YpLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyohPCBkZWNheUd1aWRlT3JpZyAqLwpGTDJGWENPTlNUX0RCTCgwLjVmKSwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qITwgZGVjYXlHdWlkZURpZmYgKi8KRkwyRlhDT05TVF9EQkwoLTAuMDAwMTEyOTkzMjY5KSwgIC8qIExENjQoRkwyRlhDT05TVF9EQkwoMC45OTVmKSkgKi8gLyohPCBkZXJpdlRocmVzTWF4TEQ2NCAqLwpGTDJGWENPTlNUX0RCTCgtMC4wMDAxMTI5OTMyNjkpLCAgLyogTEQ2NChGTDJGWENPTlNUX0RCTCgwLjk5NWYpKSAqLyAvKiE8IGRlcml2VGhyZXNCZWxvd0xENjQgKi8KRkwyRlhDT05TVF9EQkwoLTAuMDA1MDMwMTI2NDgzZikgLyogTEQ2NChGTDJGWENPTlNUX0RCTCgwLjhmKSkgKi8gICAgLyohPCBkZXJpdlRocmVzQWJvdmVMRDY0ICovCn0sCjUwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyohPCBtYXhDb21wICovCn07CgovKiE8IERldGVjdG9yIFBhcmFtZXRlcnMgZm9yIEFBQyBMRCBjb3JlIGNvZGVjLiAqLwpzdGF0aWMgY29uc3QgREVURUNUT1JfUEFSQU1FVEVSU19NSCBwYXJhbXNBYWNMZCA9IHsKMTYsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiE8IERlbHRhIHRpbWUuICovCnsKRkwyRlhDT05TVF9EQkwoMjUuMGYqUkVMQVhBVElPTl9GTE9BVCksICAgICAgICAvKiE8IHRocmVzSG9sZERpZmYgKi8KRkwyRlhDT05TVF9EQkwoMS4yNmYqUkVMQVhBVElPTl9GTE9BVCksICAgICAgICAvKiE8IHRyZXNIb2xkRGlmZkd1aWRlICovCkZMMkZYQ09OU1RfREJMKDE1LjBmKlJFTEFYQVRJT05fRkxPQVQpLCAgICAgICAgLyohPCB0aHJlc0hvbGRUb25lICovCkZMMkZYQ09OU1RfREJMKCgxLjBmLzE1LjBmKSpSRUxBWEFUSU9OX0ZMT0FUKSwgLyohPCBpbnZUaHJlc0hvbGRUb25lICovCkZMMkZYQ09OU1RfREJMKDEuMjZmKlJFTEFYQVRJT05fRkxPQVQpLCAgICAgICAgLyohPCB0aHJlc0hvbGRUb25lR3VpZGUgKi8KRkwyRlhDT05TVF9EQkwoMC4zZik+PlNGTV9TSElGVCwgICAgICAgICAgICAgICAvKiE8IHNmbVRocmVzU2JyICovCkZMMkZYQ09OU1RfREJMKDAuMWYpPj5TRk1fU0hJRlQsICAgICAgICAgICAgICAgLyohPCBzZm1UaHJlc09yaWcgKi8KRkwyRlhDT05TVF9EQkwoMC4zZiksICAgICAgICAgICAgICAgICAgICAgICAgICAvKiE8IGRlY2F5R3VpZGVPcmlnICovCkZMMkZYQ09OU1RfREJMKDAuMmYpLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyohPCBkZWNheUd1aWRlRGlmZiAqLwpGTDJGWENPTlNUX0RCTCgtMC4wMDAxMTI5OTMyNjkpLCAgLyogTEQ2NChGTDJGWENPTlNUX0RCTCgwLjk5NWYpKSAqLyAgLyohPCBkZXJpdlRocmVzTWF4TEQ2NCAqLwpGTDJGWENPTlNUX0RCTCgtMC4wMDAxMTI5OTMyNjkpLCAgLyogTEQ2NChGTDJGWENPTlNUX0RCTCgwLjk5NWYpKSAqLyAgLyohPCBkZXJpdlRocmVzQmVsb3dMRDY0ICovCkZMMkZYQ09OU1RfREJMKC0wLjAwNTAzMDEyNjQ4M2YpIC8qIExENjQoRkwyRlhDT05TVF9EQkwoMC44ZikpICovICAgICAvKiE8IGRlcml2VGhyZXNBYm92ZUxENjQgKi8KfSwKNTAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiE8IG1heENvbXAgKi8KfTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgQ2FsY3VsYXRlcyB0aGUgZGlmZmVyZW5jZSBpbiB0b25hbGl0eSBiZXR3ZWVuIG9yaWdpbmFsIGFuZCBTQlIKICAgICAgICAgICAgIGZvciBhIGdpdmVuIHRpbWUgYW5kIGZyZXF1ZW5jeSByZWdpb24uCgogICAgICAgICAgICAgVGhlIHZhbHVlcyBmb3IgcERpZmZNYXBwZWQyU2NmYiBhcmUgc2NhbGVkIGJ5IFJFTEFYQVRJT04KCiAgXHJldHVybiAgICBub25lLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBkaWZmKEZJWFBfREJMICpSRVNUUklDVCBwVG9uYWxpdHlPcmlnLAogICAgICAgICAgICAgICAgIEZJWFBfREJMICpwRGlmZk1hcHBlZDJTY2ZiLAogICAgICAgICAgICAgICAgIGNvbnN0IFVDSEFSICpSRVNUUklDVCBwRnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICBJTlQgICAgICAgblNjZmIsCiAgICAgICAgICAgICAgICAgU0NIQVIgICAgKmluZGV4VmVjdG9yKQp7CiAgVUNIQVIgaSwgbGwsIGx1LCBrOwogIEZJWFBfREJMIG1heFZhbE9yaWcsIG1heFZhbFNiciwgdG1wOwogIElOVCBzY2FsZTsKCiAgZm9yKGk9MDsgaSA8IG5TY2ZiOyBpKyspewogICAgbGwgPSBwRnJlcUJhbmRUYWJsZVtpXTsKICAgIGx1ID0gcEZyZXFCYW5kVGFibGVbaSsxXTsKCiAgICBtYXhWYWxPcmlnID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgICBtYXhWYWxTYnIgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKCiAgICBmb3Ioaz1sbDtrPGx1O2srKyl7CiAgICAgIG1heFZhbE9yaWcgPSBmaXhNYXgobWF4VmFsT3JpZywgcFRvbmFsaXR5T3JpZ1trXSk7CiAgICAgIG1heFZhbFNiciA9IGZpeE1heChtYXhWYWxTYnIsIHBUb25hbGl0eU9yaWdbaW5kZXhWZWN0b3Jba11dKTsKICAgIH0KCiAgICBpZiAoKG1heFZhbFNiciA+PSBSRUxBWEFUSU9OKSkgewogICAgICAgIHRtcCA9IGZEaXZOb3JtKG1heFZhbE9yaWcsIG1heFZhbFNiciwgJnNjYWxlKTsKICAgICAgICBwRGlmZk1hcHBlZDJTY2ZiW2ldID0gc2NhbGVWYWx1ZShmTXVsdCh0bXAsUkVMQVhBVElPTl9GUkFDVCksIGZpeE1heCgtKERGUkFDVF9CSVRTLTEpLChzY2FsZS1SRUxBWEFUSU9OX1NISUZUKSkpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgcERpZmZNYXBwZWQyU2NmYltpXSA9IG1heFZhbE9yaWc7CiAgICB9CiAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIENhbGN1bGF0ZXMgYSBmbGF0bmVzcyBtZWFzdXJlIG9mIHRoZSB0b25hbGl0eSBtZWFzdXJlcy4KCiAgQ2FsY3VsYXRpb24gb2YgdGhlIHBvd2VyIGZ1bmN0aW9uIGFuZCB1c2luZyBzY2FsZWZhY3RvciBmb3IgYmFzaXM6CiAgICBVc2luZyBsb2cyOgogICAgeiAgPSAoMl5rICogeCleeTsKICAgIHonID0gQ2FsY0xkKHopID0geSpDYWxjTGQoeCkgKyB5Kms7CiAgICB6ICA9IENhbGNJbnZMZCh6Jyk7CgogICAgVXNpbmcgbGQ2NDoKICAgIHogID0gKDJeayAqIHgpXnk7CiAgICB6JyA9IENhbGNMZDY0KHopID0geSpDYWxjTGQ2NCh4KS82NCArIHkqay82NDsKICAgIHogID0gQ2FsY0ludkxkNjQoeicpOwoKICBUaGUgdmFsdWVzIHBTZm1PcmlnVmVjIGFuZCBwU2ZtU2JyVmVjIGFyZSBzY2FsZWQgYnkgdGhlIGZhY3RvciAxLzQuMAoKICBccmV0dXJuICAgIG5vbmUuCgoqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIGNhbGN1bGF0ZUZsYXRuZXNzTWVhc3VyZShGSVhQX0RCTCAqcFF1b3RhQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0NIQVIgICAgKmluZGV4VmVjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnBTZm1PcmlnVmVjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnBTZm1TYnJWZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ0hBUiAqcEZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgblNmYikKewogIElOVCBpLGo7CiAgRklYUF9EQkwgaW52QmFuZHMsdG1wMSx0bXAyOwogIElOVCBzaGlmdEZhYzAsc2hpZnRGYWNTdW0wOwogIElOVCBzaGlmdEZhYzEsc2hpZnRGYWNTdW0xOwogIEZJWFBfREJMIGFjY3U7CgogIGZvcihpPTA7aTxuU2ZiO2krKykKICB7CiAgICBJTlQgbGwgPSBwRnJlcUJhbmRUYWJsZVtpXTsKICAgIElOVCBsdSA9IHBGcmVxQmFuZFRhYmxlW2krMV07CiAgICBwU2ZtT3JpZ1ZlY1tpXSA9IChGSVhQX0RCTCkoTUFYVkFMX0RCTD4+Mik7CiAgICBwU2ZtU2JyVmVjW2ldICA9IChGSVhQX0RCTCkoTUFYVkFMX0RCTD4+Mik7CgogICAgaWYobHUgLSBsbCA+IDEpewogICAgICBGSVhQX0RCTCBhbU9yaWcsYW1UcmFuc3AsZ21PcmlnLGdtVHJhbnNwLHNmbU9yaWcsc2ZtVHJhbnNwOwogICAgICBpbnZCYW5kcyA9IEdldEludkludChsdS1sbCk7CiAgICAgIHNoaWZ0RmFjU3VtMCA9IDA7CiAgICAgIHNoaWZ0RmFjU3VtMSA9IDA7CiAgICAgIGFtT3JpZyA9IGFtVHJhbnNwID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgICAgIGdtT3JpZyA9IGdtVHJhbnNwID0gKEZJWFBfREJMKU1BWFZBTF9EQkw7CgogICAgICBmb3Ioaj0gbGw7IGo8bHU7IGorKykgewogICAgICAgIHNmbU9yaWcgICA9IHBRdW90YUJ1ZmZlcltqXTsKICAgICAgICBzZm1UcmFuc3AgPSBwUXVvdGFCdWZmZXJbaW5kZXhWZWN0b3Jbal1dOwoKICAgICAgICBhbU9yaWcgICArPSBmTXVsdChzZm1PcmlnLCBpbnZCYW5kcyk7CiAgICAgICAgYW1UcmFuc3AgKz0gZk11bHQoc2ZtVHJhbnNwLCBpbnZCYW5kcyk7CgogICAgICAgIHNoaWZ0RmFjMCA9IENvdW50TGVhZGluZ0JpdHMoc2ZtT3JpZyk7CiAgICAgICAgc2hpZnRGYWMxID0gQ291bnRMZWFkaW5nQml0cyhzZm1UcmFuc3ApOwoKICAgICAgICBnbU9yaWcgICA9IGZNdWx0KGdtT3JpZywgc2ZtT3JpZzw8c2hpZnRGYWMwKTsKICAgICAgICBnbVRyYW5zcCA9IGZNdWx0KGdtVHJhbnNwLCBzZm1UcmFuc3A8PHNoaWZ0RmFjMSk7CgogICAgICAgIHNoaWZ0RmFjU3VtMCArPSBzaGlmdEZhYzA7CiAgICAgICAgc2hpZnRGYWNTdW0xICs9IHNoaWZ0RmFjMTsKICAgICAgfQoKICAgICAgaWYgKGdtT3JpZyA+IEZMMkZYQ09OU1RfREJMKDAuMGYpKSB7CgogICAgICAgIHRtcDEgPSBDYWxjTGREYXRhKGdtT3JpZyk7ICAgICAgLyogQ2FsY0xkNjQoeCkvNjQgKi8KICAgICAgICB0bXAxID0gZk11bHQoaW52QmFuZHMsIHRtcDEpOyAgIC8qIHkqQ2FsY0xkNjQoeCkvNjQgKi8KCiAgICAgICAgLyogeSprLzY0ICovCiAgICAgICAgYWNjdSA9IChGSVhQX0RCTCktc2hpZnRGYWNTdW0wIDw8IChERlJBQ1RfQklUUy0xLTgpOwogICAgICAgIHRtcDIgPSBmTXVsdERpdjIoaW52QmFuZHMsIGFjY3UpIDw8ICgyKzEpOwoKICAgICAgICB0bXAyID0gdG1wMSArIHRtcDI7ICAgICAgICAgICAgIC8qIHkqQ2FsY0xkNjQoeCkvNjQgKyB5KmsvNjQgKi8KICAgICAgICBnbU9yaWcgPSBDYWxjSW52TGREYXRhKHRtcDIpOyAgIC8qIENhbGNJbnZMZDY0KHonKTsgKi8KICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBnbU9yaWcgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgICAgfQoKICAgICAgaWYgKGdtVHJhbnNwID4gRkwyRlhDT05TVF9EQkwoMC4wZikpIHsKCiAgICAgICAgdG1wMSA9IENhbGNMZERhdGEoZ21UcmFuc3ApOyAgICAvKiBDYWxjTGQ2NCh4KS82NCAqLwogICAgICAgIHRtcDEgPSBmTXVsdChpbnZCYW5kcywgdG1wMSk7ICAgLyogeSpDYWxjTGQ2NCh4KS82NCAqLwoKICAgICAgICAvKiB5KmsvNjQgKi8KICAgICAgICBhY2N1ID0gKEZJWFBfREJMKS1zaGlmdEZhY1N1bTEgPDwgKERGUkFDVF9CSVRTLTEtOCk7CiAgICAgICAgdG1wMiA9IGZNdWx0RGl2MihpbnZCYW5kcywgYWNjdSkgPDwgKDIrMSk7CgogICAgICAgIHRtcDIgPSB0bXAxICsgdG1wMjsgICAgICAgICAgICAgLyogeSpDYWxjTGQ2NCh4KS82NCArIHkqay82NCAqLwogICAgICAgIGdtVHJhbnNwID0gQ2FsY0ludkxkRGF0YSh0bXAyKTsgLyogQ2FsY0ludkxkNjQoeicpOyAqLwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIGdtVHJhbnNwID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgICAgIH0KICAgICAgaWYgKCBhbU9yaWcgIT0gRkwyRlhDT05TVF9EQkwoMC4wZikgKQogICAgICAgIHBTZm1PcmlnVmVjW2ldID0gRkRLc2JyRW5jX0xTSV9kaXZpZGVfc2NhbGVfZnJhY3QoZ21PcmlnLGFtT3JpZyxTRk1fU0NBTEUpOwoKICAgICAgaWYgKCBhbVRyYW5zcCAhPSBGTDJGWENPTlNUX0RCTCgwLjBmKSApCiAgICAgICAgcFNmbVNiclZlY1tpXSA9IEZES3NickVuY19MU0lfZGl2aWRlX3NjYWxlX2ZyYWN0KGdtVHJhbnNwLGFtVHJhbnNwLFNGTV9TQ0FMRSk7CiAgICB9CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgQ2FsY3VsYXRlcyB0aGUgaW5wdXQgdG8gdGhlIG1pc3NpbmcgaGFybW9uaWNzIGRldGVjdGlvbi4KCgogIFxyZXR1cm4gICAgbm9uZS4KCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgY2FsY3VsYXRlRGV0ZWN0b3JJbnB1dChGSVhQX0RCTCAqKlJFU1RSSUNUIHBRdW90YUJ1ZmZlciwgIC8qITwgUG9pbnRlciB0byB0b25hbGl0eSBtYXRyaXguICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0NIQVIgICAgICpSRVNUUklDVCBpbmRleFZlY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqKlJFU1RSSUNUIHRvbmFsaXR5RGlmZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqKlJFU1RSSUNUIHBTZm1PcmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICoqUkVTVFJJQ1QgcFNmbVNiciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ0hBUiAqZnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgblNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbm9Fc3RQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbW92ZSkKewogIElOVCBlc3Q7CgogIC8qCiAgTmV3IGVzdGltYXRlLgogICovCiAgZm9yIChlc3Q9MDsgZXN0IDwgbm9Fc3RQZXJGcmFtZTsgZXN0KyspIHsKCiAgICBkaWZmKHBRdW90YUJ1ZmZlcltlc3QrbW92ZV0sCiAgICAgICAgIHRvbmFsaXR5RGlmZltlc3QrbW92ZV0sCiAgICAgICAgIGZyZXFCYW5kVGFibGUsCiAgICAgICAgIG5TZmIsCiAgICAgICAgIGluZGV4VmVjdG9yKTsKCiAgICBjYWxjdWxhdGVGbGF0bmVzc01lYXN1cmUocFF1b3RhQnVmZmVyW2VzdCsgbW92ZV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXhWZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNmbU9yaWdbZXN0ICsgbW92ZV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNmbVNicltlc3QgKyBtb3ZlXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmVxQmFuZFRhYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5TZmIpOwogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBDaGVja3MgdGhhdCB0aGUgZGV0ZWN0aW9uIGlzIG5vdCBkdWUgdG8gYSBMUCBmaWx0ZXIKCiAgVGhpcyBmdW5jdGlvbiBkZXRlcm1pbmVzIGlmIGEgbmV3bHkgZGV0ZWN0ZWQgbWlzc2luZyBoYXJtb25pY3MgaXMgbm90CiAgaW4gZmFjdCBqdXN0IGEgbG93LXBhc3MgZmlsdGVyZSBpbnB1dCBzaWduYWwuIElmIHNvLCB0aGUgZGV0ZWN0aW9uIGlzCiAgcmVtb3ZlZC4KCiAgXHJldHVybiAgICBub25lLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCByZW1vdmVMb3dQYXNzRGV0ZWN0aW9uKFVDSEFSICpSRVNUUklDVCBwQWRkSGFybVNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAqKlJFU1RSSUNUIHBEZXRlY3Rpb25WZWN0b3JzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgc3RvcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgblNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ0hBUiAqUkVTVFJJQ1QgcEZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKlJFU1RSSUNUIHBOcmdWZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVEhSRVNfSE9MRFMgbWhUaHJlc2gpCgp7CiAgSU5UIGksZXN0OwogIElOVCBtYXhEZXJpdlBvcyA9IHBGcmVxQmFuZFRhYmxlW25TZmJdOwogIElOVCBudW1CYW5kcyA9IHBGcmVxQmFuZFRhYmxlW25TZmJdOwogIEZJWFBfREJMIG5yZ0xvdyxucmdIaWdoOwogIEZJWFBfREJMIG5yZ0xENjQsbnJnTG93TEQ2NCxucmdIaWdoTEQ2NCxucmdEaWZmTEQ2NDsKICBGSVhQX0RCTCB2YWxMRDY0LG1heFZhbExENjQsbWF4VmFsQWJvdmVMRDY0OwogIElOVCBiTFBzaWduYWwgPSAwOwoKICBtYXhWYWxMRDY0ID0gRkwyRlhDT05TVF9EQkwoLTEuMGYpOwogIGZvcihpID0gbnVtQmFuZHMgLSAxIC0gMjsgaSA+IHBGcmVxQmFuZFRhYmxlWzBdO2ktLSl7CiAgICBucmdMb3cgID0gcE5yZ1ZlY3RvcltpXTsKICAgIG5yZ0hpZ2ggPSBwTnJnVmVjdG9yW2kgKyAyXTsKCiAgICBpZihucmdMb3cgIT0gRkwyRlhDT05TVF9EQkwoMC4wZikgJiYgbnJnTG93ID4gbnJnSGlnaCl7CiAgICAgIG5yZ0xvd0xENjQgPSBDYWxjTGREYXRhKG5yZ0xvdz4+MSk7CiAgICAgIG5yZ0RpZmZMRDY0ID0gQ2FsY0xkRGF0YSgobnJnTG93Pj4xKS0obnJnSGlnaD4+MSkpOwogICAgICB2YWxMRDY0ID0gbnJnRGlmZkxENjQtbnJnTG93TEQ2NDsKICAgICAgaWYodmFsTEQ2NCA+IG1heFZhbExENjQpewogICAgICAgIG1heERlcml2UG9zID0gaTsKICAgICAgICBtYXhWYWxMRDY0ID0gdmFsTEQ2NDsKICAgICAgfQogICAgICBpZihtYXhWYWxMRDY0ID4gbWhUaHJlc2guZGVyaXZUaHJlc01heExENjQpIHsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0KCiAgLyogRmluZCB0aGUgbGFyZ2VzdCAiZ3JhZGllbnQiIGFib3ZlLiAoc2hvdWxkIGJlIHJlbGF0aXZlbHkgZmxhdCwgaGVuY2Ugd2UgZXhwZWN0IGEgbG93IHZhbHVlCiAgICAgaWYgdGhlIHNpZ25hbCBpcyBMUC4qLwogIG1heFZhbEFib3ZlTEQ2NCA9IEZMMkZYQ09OU1RfREJMKC0xLjBmKTsKICBmb3IoaSA9IG51bUJhbmRzIC0gMSAtIDI7IGkgPiBtYXhEZXJpdlBvcyArIDI7aS0tKXsKICAgIG5yZ0xvdyAgPSBwTnJnVmVjdG9yW2ldOwogICAgbnJnSGlnaCA9IHBOcmdWZWN0b3JbaSArIDJdOwoKICAgIGlmKG5yZ0xvdyAhPSBGTDJGWENPTlNUX0RCTCgwLjBmKSAmJiBucmdMb3cgPiBucmdIaWdoKXsKCQkgICBucmdMb3dMRDY0ID0gQ2FsY0xkRGF0YShucmdMb3c+PjEpOwoJCSAgIG5yZ0RpZmZMRDY0ID0gQ2FsY0xkRGF0YSgobnJnTG93Pj4xKS0obnJnSGlnaD4+MSkpOwoJCQkgdmFsTEQ2NCA9IG5yZ0RpZmZMRDY0LW5yZ0xvd0xENjQ7CiAgICAgIGlmKHZhbExENjQgPiBtYXhWYWxBYm92ZUxENjQpewogICAgICAgIG1heFZhbEFib3ZlTEQ2NCA9IHZhbExENjQ7CiAgICAgIH0KICAgIH0KCQkgZWxzZSB7CiAgICAgIGlmKG5yZ0hpZ2ggIT0gRkwyRlhDT05TVF9EQkwoMC4wZikgJiYgbnJnSGlnaCA+IG5yZ0xvdyl7CgkJICAgICBucmdIaWdoTEQ2NCA9IENhbGNMZERhdGEobnJnSGlnaD4+MSk7CgkJICAgICBucmdEaWZmTEQ2NCA9IENhbGNMZERhdGEoKG5yZ0hpZ2g+PjEpLShucmdMb3c+PjEpKTsKCQkJICAgdmFsTEQ2NCA9IG5yZ0RpZmZMRDY0LW5yZ0hpZ2hMRDY0OwogICAgICAgIGlmKHZhbExENjQgPiBtYXhWYWxBYm92ZUxENjQpewogICAgICAgICAgbWF4VmFsQWJvdmVMRDY0ID0gdmFsTEQ2NDsKICAgICAgICB9CiAgICAgIH0KCQkgfQogIH0KCiAgaWYobWF4VmFsTEQ2NCA+IG1oVGhyZXNoLmRlcml2VGhyZXNNYXhMRDY0ICYmIG1heFZhbEFib3ZlTEQ2NCA8IG1oVGhyZXNoLmRlcml2VGhyZXNBYm92ZUxENjQpewogICAgYkxQc2lnbmFsID0gMTsKCiAgICBmb3IoaSA9IG1heERlcml2UG9zIC0gMTsgaSA+IG1heERlcml2UG9zIC0gNSAmJiBpID49IDAgOyBpLS0pewogICAgICBpZihwTnJnVmVjdG9yW2ldICE9IEZMMkZYQ09OU1RfREJMKDAuMGYpICYmIHBOcmdWZWN0b3JbaV0gPiBwTnJnVmVjdG9yW21heERlcml2UG9zICsgMl0pewoJCSAgICAgbnJnRGlmZkxENjQgPSBDYWxjTGREYXRhKChwTnJnVmVjdG9yW2ldPj4xKS0ocE5yZ1ZlY3RvclttYXhEZXJpdlBvcyArIDJdPj4xKSk7CgkJCQkgbnJnTEQ2NCA9IENhbGNMZERhdGEocE5yZ1ZlY3RvcltpXT4+MSk7CiAgCQkJIHZhbExENjQgPSBucmdEaWZmTEQ2NC1ucmdMRDY0OwogICAgICAgIGlmKHZhbExENjQgPCBtaFRocmVzaC5kZXJpdlRocmVzQmVsb3dMRDY0KSB7CiAgICAgICAgICBiTFBzaWduYWwgPSAwOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICAgIGVsc2V7CiAgICAgICAgYkxQc2lnbmFsID0gMDsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0KCiAgaWYoYkxQc2lnbmFsKXsKICAgIGZvcihpPTA7aTxuU2ZiO2krKyl7CiAgICAgIGlmKG1heERlcml2UG9zID49IHBGcmVxQmFuZFRhYmxlW2ldICYmIG1heERlcml2UG9zIDwgcEZyZXFCYW5kVGFibGVbaSsxXSkKICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZihwQWRkSGFybVNmYltpXSl7CiAgICAgIHBBZGRIYXJtU2ZiW2ldID0gMDsKICAgICAgZm9yKGVzdCA9IHN0YXJ0OyBlc3QgPCBzdG9wIDsgZXN0KyspewogICAgICAgIHBEZXRlY3Rpb25WZWN0b3JzW2VzdF1baV0gPSAwOwogICAgICB9CiAgICB9CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgQ2hlY2tzIGlmIGl0IGlzIGFsbG93ZWQgdG8gZGV0ZWN0IGEgbWlzc2luZyB0b25lLCB0aGF0IHdhc24ndAogICAgICAgICAgICAgZGV0ZWN0ZWQgcHJldmlvdXNseS4KCgogIFxyZXR1cm4gICAgbmV3RGV0ZWN0aW9uQWxsb3dlZCBmbGFnLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSU5UIGlzRGV0ZWN0aW9uT2ZOZXdUb25lQWxsb3dlZChjb25zdCBTQlJfRlJBTUVfSU5GTyAqcEZyYW1lSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICpwRGV0ZWN0aW9uU3RhcnRQb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBub0VzdFBlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgcHJldlRyYW5zaWVudEZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgcHJldlRyYW5zaWVudFBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHByZXZUcmFuc2llbnRGbGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgdHJhbnNpZW50UG9zT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgdHJhbnNpZW50RmxhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHRyYW5zaWVudFBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGRlbHRhVGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9NSVNTSU5HX0hBUk1PTklDU19ERVRFQ1RPUiBoX3Nick1pc3NpbmdIYXJtb25pY3NEZXRlY3RvcikKewogIElOVCB0cmFuc2llbnRGcmFtZSwgbmV3RGV0ZWN0aW9uQWxsb3dlZDsKCgogIC8qIERldGVybWluZSBpZiB0aGlzIGlzIGEgZnJhbWUgd2hlcmUgYSB0cmFuc2llbnQgc3RhcnRzLi4uCiAgICogSWYgdGhlIHRyYW5zaWVudCBmbGFnIHdhcyBzZXQgdGhlIHByZXZpb3VzIGZyYW1lIGJ1dCBub3QgdGhlCiAgICogdHJhbnNpZW50IGZyYW1lIGZsYWcsIHRoZSB0cmFuc2llbnQgZnJhbWUgZmxhZyBpcyBzZXQgaW4gdGhlIGN1cnJlbnQgZnJhbWUuCiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogIHRyYW5zaWVudEZyYW1lID0gMDsKICBpZih0cmFuc2llbnRGbGFnKXsKICAgIGlmKHRyYW5zaWVudFBvcyArIHRyYW5zaWVudFBvc09mZnNldCA8IHBGcmFtZUluZm8tPmJvcmRlcnNbcEZyYW1lSW5mby0+bkVudmVsb3Blc10pCiAgICAgIHRyYW5zaWVudEZyYW1lID0gMTsKICAgICAgaWYobm9Fc3RQZXJGcmFtZSA+IDEpewogICAgICAgIGlmKHRyYW5zaWVudFBvcyArIHRyYW5zaWVudFBvc09mZnNldCA+IGhfc2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT50aW1lU2xvdHMgPj4gMSl7CiAgICAgICAgICAqcERldGVjdGlvblN0YXJ0UG9zID0gbm9Fc3RQZXJGcmFtZTsKICAgICAgICB9CiAgICAgICAgZWxzZXsKICAgICAgICAgICpwRGV0ZWN0aW9uU3RhcnRQb3MgPSBub0VzdFBlckZyYW1lID4+IDE7CiAgICAgICAgfQoKICAgICAgfQogICAgICBlbHNlewogICAgICAgICpwRGV0ZWN0aW9uU3RhcnRQb3MgPSBub0VzdFBlckZyYW1lOwogICAgICB9CiAgfQogIGVsc2V7CiAgICBpZihwcmV2VHJhbnNpZW50RmxhZyAmJiAhcHJldlRyYW5zaWVudEZyYW1lKXsKICAgICAgdHJhbnNpZW50RnJhbWUgPSAxOwogICAgICAqcERldGVjdGlvblN0YXJ0UG9zID0gMDsKICAgIH0KICB9CgogIC8qCiAgICogRGV0ZXJtaW5lIGlmIGRldGVjdGlvbiBvZiBuZXcgbWlzc2luZyBoYXJtb25pY3MgYXJlIGFsbG93ZWQuCiAgICogSWYgdGhlIGZyYW1lIGNvbnRhaW5zIGEgdHJhbnNpZW50IGl0J3Mgb2suIElmIHRoZSBwcmV2aW91cwogICAqIGZyYW1lIGNvbnRhaW5lZCBhIHRyYW5zaWVudCBpdCBuZWVkcyB0byBiZSBzdWZmaWNpZW50bHkgY2xvc2UKICAgKiB0byB0aGUgc3RhcnQgb2YgdGhlIGN1cnJlbnQgZnJhbWUuCiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgbmV3RGV0ZWN0aW9uQWxsb3dlZCA9IDA7CiAgaWYodHJhbnNpZW50RnJhbWUpewogICAgbmV3RGV0ZWN0aW9uQWxsb3dlZCA9IDE7CiAgfQogIGVsc2UgewogICAgaWYocHJldlRyYW5zaWVudEZyYW1lICYmCiAgICAgICBmaXhwX2FicyhwRnJhbWVJbmZvLT5ib3JkZXJzWzBdIC0gKHByZXZUcmFuc2llbnRQb3MgKyB0cmFuc2llbnRQb3NPZmZzZXQgLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaF9zYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPnRpbWVTbG90cykpIDwgZGVsdGFUaW1lKQogICAgICBuZXdEZXRlY3Rpb25BbGxvd2VkID0gMTsKICAgICAgKnBEZXRlY3Rpb25TdGFydFBvcyA9IDA7CiAgfQoKICBoX3Nick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+cHJldmlvdXNUcmFuc2llbnRGbGFnICA9IHRyYW5zaWVudEZsYWc7CiAgaF9zYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPnByZXZpb3VzVHJhbnNpZW50RnJhbWUgPSB0cmFuc2llbnRGcmFtZTsKICBoX3Nick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+cHJldmlvdXNUcmFuc2llbnRQb3MgICA9IHRyYW5zaWVudFBvczsKCiAgcmV0dXJuIChuZXdEZXRlY3Rpb25BbGxvd2VkKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBDbGVhbnMgdXAgdGhlIGRldGVjdGlvbiBhZnRlciBhIHRyYW5zaWVudC4KCgogIFxyZXR1cm4gICAgbm9uZS4KCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgdHJhbnNpZW50Q2xlYW5VcChGSVhQX0RCTCAqKnF1b3RhQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICoqZGV0ZWN0aW9uVmVjdG9ycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAqcEFkZEhhcm1TZmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgKnBQcmV2QWRkSGFybVNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKiogc2lnbkJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ0hBUiAqcEZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBzdG9wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuZXdEZXRlY3Rpb25BbGxvd2VkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpwTnJnVmVjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRIUkVTX0hPTERTIG1oVGhyZXNoKQp7CiAgSU5UIGksaixsaSwgdWksZXN0OwoKICBmb3IoZXN0PXN0YXJ0OyBlc3QgPCBzdG9wOyBlc3QrKykgewogICAgZm9yKGk9MDsgaTxuU2ZiOyBpKyspIHsKICAgICAgcEFkZEhhcm1TZmJbaV0gPSBwQWRkSGFybVNmYltpXSB8fCBkZXRlY3Rpb25WZWN0b3JzW2VzdF1baV07CiAgICB9CiAgfQoKICBpZihuZXdEZXRlY3Rpb25BbGxvd2VkID09IDEpewogICAgLyoKICAgICAqIENoZWNrIGZvciBkdXBsaWNhdGlvbiBvZiBzaW5lcyBsb2NhdGVkCiAgICAgKiBvbiB0aGUgYm9yZGVyIG9mIHR3byBzY2YtYmFuZHMuCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIGZvcihpPTA7aTxuU2ZiLTE7aSsrKSB7CiAgICAgIGxpID0gcEZyZXFCYW5kVGFibGVbaV07CiAgICAgIHVpID0gcEZyZXFCYW5kVGFibGVbaSsxXTsKCiAgICAgIC8qIGRldGVjdGlvbiBpbiBhZGphY2VudCBjaGFubmVscy4qLwogICAgICBpZihwQWRkSGFybVNmYltpXSAmJiBwQWRkSGFybVNmYltpKzFdKSB7CiAgICAgICAgRklYUF9EQkwgbWF4VmFsMSwgbWF4VmFsMjsKICAgICAgICBJTlQgbWF4UG9zMSwgbWF4UG9zMiwgbWF4UG9zVGltZTEsIG1heFBvc1RpbWUyOwoKICAgICAgICBsaSA9IHBGcmVxQmFuZFRhYmxlW2ldOwogICAgICAgIHVpID0gcEZyZXFCYW5kVGFibGVbaSsxXTsKCiAgICAgICAgLyogRmluZCBtYXhpbXVtIHRvbmFsaXR5IGluIHRoZSB0aGUgdHdvIHNjZiBiYW5kcy4qLwogICAgICAgIG1heFBvc1RpbWUxID0gc3RhcnQ7CiAgICAgICAgbWF4UG9zMSA9IGxpOwogICAgICAgIG1heFZhbDEgPSBxdW90YUJ1ZmZlcltzdGFydF1bbGldOwogICAgICAgIGZvcihlc3QgPSBzdGFydDsgZXN0IDwgc3RvcDsgZXN0KyspewogICAgICAgICAgZm9yKGogPSBsaTsgajx1aTsgaisrKXsKICAgICAgICAgICAgaWYocXVvdGFCdWZmZXJbZXN0XVtqXSA+IG1heFZhbDEpewogICAgICAgICAgICAgIG1heFZhbDEgPSBxdW90YUJ1ZmZlcltlc3RdW2pdOwogICAgICAgICAgICAgIG1heFBvczEgPSBqOwogICAgICAgICAgICAgIG1heFBvc1RpbWUxID0gZXN0OwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBsaSA9IHBGcmVxQmFuZFRhYmxlW2krMV07CiAgICAgICAgdWkgPSBwRnJlcUJhbmRUYWJsZVtpKzJdOwoKICAgICAgICAvKiBGaW5kIG1heGltdW0gdG9uYWxpdHkgaW4gdGhlIHRoZSB0d28gc2NmIGJhbmRzLiovCiAgICAgICAgbWF4UG9zVGltZTIgPSBzdGFydDsKICAgICAgICBtYXhQb3MyID0gbGk7CiAgICAgICAgbWF4VmFsMiA9IHF1b3RhQnVmZmVyW3N0YXJ0XVtsaV07CiAgICAgICAgZm9yKGVzdCA9IHN0YXJ0OyBlc3QgPCBzdG9wOyBlc3QrKyl7CiAgICAgICAgICBmb3IoaiA9IGxpOyBqPHVpOyBqKyspewogICAgICAgICAgICBpZihxdW90YUJ1ZmZlcltlc3RdW2pdID4gbWF4VmFsMil7CiAgICAgICAgICAgICAgbWF4VmFsMiA9IHF1b3RhQnVmZmVyW2VzdF1bal07CiAgICAgICAgICAgICAgbWF4UG9zMiA9IGo7CiAgICAgICAgICAgICAgbWF4UG9zVGltZTIgPSBlc3Q7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIElmIHRoZSBtYXhpbXVtIHZhbHVlcyBhcmUgaW4gYWRqYWNlbnQgUU1GLWNoYW5uZWxzLCB3ZSBuZWVkIHRvIHJlbW92ZQogICAgICAgICAgIHRoZSBsb3dlc3Qgb2YgdGhlIHR3by4qLwogICAgICAgIGlmKG1heFBvczItbWF4UG9zMSA8IDIpewoKICAgICAgICAgIGlmKHBQcmV2QWRkSGFybVNmYltpXSA9PSAxICYmIHBQcmV2QWRkSGFybVNmYltpKzFdID09IDApewogICAgICAgICAgICAvKiBLZWVwIHRoZSBsb3dlciwgcmVtb3ZlIHRoZSB1cHBlci4qLwogICAgICAgICAgICBwQWRkSGFybVNmYltpKzFdID0gMDsKICAgICAgICAgICAgZm9yKGVzdD1zdGFydDsgZXN0PHN0b3A7IGVzdCsrKXsKICAgICAgICAgICAgICBkZXRlY3Rpb25WZWN0b3JzW2VzdF1baSsxXSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgIGlmKHBQcmV2QWRkSGFybVNmYltpXSA9PSAwICYmIHBQcmV2QWRkSGFybVNmYltpKzFdID09IDEpewogICAgICAgICAgICAgIC8qIEtlZXAgdGhlIHVwcGVyLCByZW1vdmUgdGhlIGxvd2VyLiovCiAgICAgICAgICAgICAgcEFkZEhhcm1TZmJbaV0gPSAwOwogICAgICAgICAgICAgIGZvcihlc3Q9c3RhcnQ7IGVzdDxzdG9wOyBlc3QrKyl7CiAgICAgICAgICAgICAgICBkZXRlY3Rpb25WZWN0b3JzW2VzdF1baV0gPSAwOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgLyogSWYgdGhlIG1heGltdW0gdmFsdWVzIGFyZSBpbiBhZGphY2VudCBRTUYtY2hhbm5lbHMsIGFuZCBpZiB0aGUgc2lnbnMgaW5kaWNhdGUgdGhhdCBpdCBpcyB0aGUgc2FtZSBzaW5lLAogICAgICAgICAgICAgICAgd2UgbmVlZCB0byByZW1vdmUgdGhlIGxvd2VzdCBvZiB0aGUgdHdvLiovCiAgICAgICAgICAgICAgaWYobWF4VmFsMSA+IG1heFZhbDIpewogICAgICAgICAgICAgICAgaWYoc2lnbkJ1ZmZlclttYXhQb3NUaW1lMV1bbWF4UG9zMl0gPCAwICYmIHNpZ25CdWZmZXJbbWF4UG9zVGltZTFdW21heFBvczFdID4gMCl7CiAgICAgICAgICAgICAgICAgIC8qIEtlZXAgdGhlIGxvd2VyLCByZW1vdmUgdGhlIHVwcGVyLiovCiAgICAgICAgICAgICAgICAgIHBBZGRIYXJtU2ZiW2krMV0gPSAwOwogICAgICAgICAgICAgICAgICBmb3IoZXN0PXN0YXJ0OyBlc3Q8c3RvcDsgZXN0KyspewogICAgICAgICAgICAgICAgICAgIGRldGVjdGlvblZlY3RvcnNbZXN0XVtpKzFdID0gMDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICAgaWYoc2lnbkJ1ZmZlclttYXhQb3NUaW1lMl1bbWF4UG9zMl0gPCAwICYmIHNpZ25CdWZmZXJbbWF4UG9zVGltZTJdW21heFBvczFdID4gMCl7CiAgICAgICAgICAgICAgICAgIC8qIEtlZXAgdGhlIHVwcGVyLCByZW1vdmUgdGhlIGxvd2VyLiovCiAgICAgICAgICAgICAgICAgIHBBZGRIYXJtU2ZiW2ldID0gMDsKICAgICAgICAgICAgICAgICAgZm9yKGVzdD1zdGFydDsgZXN0PHN0b3A7IGVzdCsrKXsKICAgICAgICAgICAgICAgICAgICBkZXRlY3Rpb25WZWN0b3JzW2VzdF1baV0gPSAwOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgLyogTWFrZSBzdXJlIHRoYXQgdGhlIGRldGVjdGlvbiBpcyBub3QgdGhlIGN1dC1vZmYgb2YgYSBsb3cgcGFzcyBmaWx0ZXIuICovCiAgICByZW1vdmVMb3dQYXNzRGV0ZWN0aW9uKHBBZGRIYXJtU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkZXRlY3Rpb25WZWN0b3JzLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgblNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcEZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOcmdWZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1oVGhyZXNoKTsKICB9CiAgZWxzZSB7CiAgIC8qCiAgICAqIElmIGEgbWlzc2luZyBoYXJtb25pYyB3YXNuJ3QgbWlzc2luZyB0aGUgcHJldmlvdXMgZnJhbWUKICAgICogdGhlIHRyYW5zaWVudC1mbGFnIG5lZWRzIHRvIGJlIHNldCBpbiBvcmRlciB0byBiZSBhbGxvd2VkIHRvIGRldGVjdCBpdC4KICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICBmb3IoaT0wO2k8blNmYjtpKyspewogICAgICBpZihwQWRkSGFybVNmYltpXSAtIHBQcmV2QWRkSGFybVNmYltpXSA+IDApCiAgICAgICAgcEFkZEhhcm1TZmJbaV0gPSAwOwogICAgfQogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBEZXRlY3Rpb24gZm9yIG9uZSB0b25hbGl0eSBlc3RpbWF0ZS4KCiAgVGhpcyBpcyB0aGUgYWN0dWFsIG1pc3NpbmcgaGFybW9uaWNzIGRldGVjdGlvbiwgdXNpbmcgaW5mb3JtYXRpb24gZnJvbSB0aGUKICBwcmV2aW91cyBkZXRlY3Rpb24uCgogIElmIGEgbWlzc2luZyBoYXJtb25pYyB3YXMgZGV0ZWN0ZWQgKGluIGEgcHJldmlvdXMgZnJhbWUpIGR1ZSB0byB0b28gaGlnaAogIHRvbmFsaXR5IGRpZmZlcmVuY2VzLCBidXQgdGhlcmUgd2FzIG5vdCBlbm91Z2ggdG9uYWxpdHkgZGlmZmVyZW5jZSBpbiB0aGUKICBjdXJyZW50IGZyYW1lLCB0aGUgZGV0ZWN0aW9uIGFsZ29yaXRobSBzdGlsbCBjb250aW51ZXMgdG8gdHJhY2UgdGhlIHN0cm9uZ2VzdAogIHRvbmUgaW4gdGhlIHNjYWxlZmFjdG9yIGJhbmQgKGFzc3VtaW5nIHRoYXQgdGhpcyBpcyB0aGUgdG9uZSB0aGF0IGlzIGdvaW5nIHRvCiAgYmUgcmVwbGFjZWQgaW4gdGhlIGRlY29kZXIpLiBUaGlzIGlzIGRvbmUgdG8gYXZvaWQgYWJydXB0IGVuZGluZ3Mgb2Ygc2luZXMKICBmYWRpbmcgb3V0IChlLmcuIGluIHRoZSBnbG9ja2Vuc3BpZWwpLgoKICBUaGUgZnVuY3Rpb24gYWxzbyB0cmllcyB0byBlc3RpbWF0ZSB3aGVyZSBvbmUgc2luZSBpcyBnb2luZyB0byBiZSByZXBsYWNlZAogIHdpdGggbXVsdGlwbGUgc2luZXMgKGR1ZSB0byB0aGUgcGF0Y2hpbmcpLiBUaGlzIGlzIGRvbmUgYnkgY29tcGFyaW5nIHRoZQogIHRvbmFsaXR5IGZsYXRuZXNzIG1lYXN1cmUgb2YgdGhlIG9yaWdpbmFsIGFuZCB0aGUgU0JSIHNpZ25hbC4KCiAgVGhlIGZ1bmN0aW9uIGFsc28gdHJpZXMgdG8gZXN0aW1hdGUgKGZvciB0aGUgc2NhbGVmYWN0b3IgYmFuZHMgb25seQogIGNvbnRhaW5pbmcgb25lIHFtZiBzdWJiYW5kKSB3aGVuIGEgc3Ryb25nIHRvbmUgaW4gdGhlIG9yaWdpbmFsIHdpbGwgYmUKICByZXBsYWNlZCBieSBhIHN0cm9uZyB0b25lIGluIHRoZSBhZGphY2VudCBRTUYgc3ViYmFuZC4KCiAgXHJldHVybiAgICBub25lLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBkZXRlY3Rpb24oRklYUF9EQkwgKnF1b3RhQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnBEaWZmVmVjU2NmYiwKICAgICAgICAgICAgICAgICAgICAgIElOVCBuU2ZiLAogICAgICAgICAgICAgICAgICAgICAgVUNIQVIgKnBIYXJtVmVjLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUNIQVIgKnBGcmVxQmFuZFRhYmxlLAogICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKnNmbU9yaWcsCiAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqc2ZtU2JyLAogICAgICAgICAgICAgICAgICAgICAgR1VJREVfVkVDVE9SUyBndWlkZVZlY3RvcnMsCiAgICAgICAgICAgICAgICAgICAgICBHVUlERV9WRUNUT1JTIG5ld0d1aWRlVmVjdG9ycywKICAgICAgICAgICAgICAgICAgICAgIFRIUkVTX0hPTERTIG1oVGhyZXNoKQp7CgogIElOVCBpLGosbGwsIGx1OwogIEZJWFBfREJMIHRocmVzVGVtcCx0aHJlc09yaWc7CgogIC8qCiAgICogRG8gZGV0ZWN0aW9uIG9uIHRoZSBkaWZmZXJlbmNlIHZlY3RvciwgaS5lLiB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuCiAgICogdGhlIG9yaWdpbmFsIGFuZCB0aGUgdHJhbnNwb3NlZC4KICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogIGZvcihpPTA7aTxuU2ZiO2krKyl7CgogICAgdGhyZXNUZW1wID0gKGd1aWRlVmVjdG9ycy5ndWlkZVZlY3RvckRpZmZbaV0gIT0gRkwyRlhDT05TVF9EQkwoMC4wZikpCiAgICAgICAgICAgICAgICAgID8gZk1heChmTXVsdChtaFRocmVzaC5kZWNheUd1aWRlRGlmZixndWlkZVZlY3RvcnMuZ3VpZGVWZWN0b3JEaWZmW2ldKSwgbWhUaHJlc2gudGhyZXNIb2xkRGlmZkd1aWRlKQogICAgICAgICAgICAgICAgICA6IG1oVGhyZXNoLnRocmVzSG9sZERpZmY7CgogICAgdGhyZXNUZW1wID0gZk1pbih0aHJlc1RlbXAsIG1oVGhyZXNoLnRocmVzSG9sZERpZmYpOwoKICAgIGlmKHBEaWZmVmVjU2NmYltpXSA+IHRocmVzVGVtcCl7CiAgICAgIHBIYXJtVmVjW2ldID0gMTsKICAgICAgbmV3R3VpZGVWZWN0b3JzLmd1aWRlVmVjdG9yRGlmZltpXSA9IHBEaWZmVmVjU2NmYltpXTsKICAgIH0KICAgIGVsc2V7CiAgICAgIC8qIElmIHRoZSBndWlkZSB3YXNuJ3QgemVybywgYnV0IHRoZSBjdXJyZW50IGxldmVsIGlzIHRvIGxvdywKICAgICAgICAgc3RhcnQgdHJhY2tpbmcgdGhlIGRlY2F5IG9uIHRoZSB0b25lIGluIHRoZSBvcmlnaW5hbCByYXRoZXIKICAgICAgICAgdGhhbiB0aGUgZGlmZmVyZW5jZS4qLwogICAgICBpZihndWlkZVZlY3RvcnMuZ3VpZGVWZWN0b3JEaWZmW2ldICE9IEZMMkZYQ09OU1RfREJMKDAuMGYpKXsKICAgICAgICBndWlkZVZlY3RvcnMuZ3VpZGVWZWN0b3JPcmlnW2ldID0gbWhUaHJlc2gudGhyZXNIb2xkVG9uZUd1aWRlOwogICAgICB9CiAgICB9CiAgfQoKICAvKgogICAqIFRyYWNlIHRvbmVzIGluIHRoZSBvcmlnaW5hbCBzaWduYWwgdGhhdCBhdCBvbmUgcG9pbnQKICAgKiBoYXZlIGJlZW4gZGV0ZWN0ZWQgYmVjYXVzZSB0aGV5IHdpbGwgYmUgcmVwbGFjZWQgYnkKICAgKiBtdWx0aXBsZSB0b25lcyBpbiB0aGUgc2JyIHNpZ25hbC4KICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgZm9yKGk9MDtpPG5TZmI7aSsrKXsKICAgIGxsID0gcEZyZXFCYW5kVGFibGVbaV07CiAgICBsdSA9IHBGcmVxQmFuZFRhYmxlW2krMV07CgogICAgdGhyZXNPcmlnID0gZml4TWF4KGZNdWx0KGd1aWRlVmVjdG9ycy5ndWlkZVZlY3Rvck9yaWdbaV0sIG1oVGhyZXNoLmRlY2F5R3VpZGVPcmlnKSwgbWhUaHJlc2gudGhyZXNIb2xkVG9uZUd1aWRlKTsKICAgIHRocmVzT3JpZyA9IGZpeE1pbih0aHJlc09yaWcsIG1oVGhyZXNoLnRocmVzSG9sZFRvbmUpOwoKICAgIGlmKGd1aWRlVmVjdG9ycy5ndWlkZVZlY3Rvck9yaWdbaV0gIT0gRkwyRlhDT05TVF9EQkwoMC4wZikpewogICAgICBmb3Ioaj0gbGw7ajxsdTtqKyspewogICAgICAgIGlmKHF1b3RhQnVmZmVyW2pdID4gdGhyZXNPcmlnKXsKICAgICAgICAgIHBIYXJtVmVjW2ldID0gMTsKICAgICAgICAgIG5ld0d1aWRlVmVjdG9ycy5ndWlkZVZlY3Rvck9yaWdbaV0gPSBxdW90YUJ1ZmZlcltqXTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIC8qCiAgICogQ2hlY2sgZm9yIG11bHRpcGxlIHNpbmVzIGluIHRoZSB0cmFuc3Bvc2VkIHNpZ25hbCwKICAgKiB3aGVyZSB0aGVyZSBpcyBvbmx5IG9uZSBpbiB0aGUgb3JpZ2luYWwuCiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgdGhyZXNPcmlnID0gbWhUaHJlc2gudGhyZXNIb2xkVG9uZTsKCiAgZm9yKGk9MDtpPG5TZmI7aSsrKXsKICAgIGxsID0gcEZyZXFCYW5kVGFibGVbaV07CiAgICBsdSA9IHBGcmVxQmFuZFRhYmxlW2krMV07CgogICAgaWYocEhhcm1WZWNbaV0gPT0gMCl7CiAgICAgIGlmKGx1IC1sbCA+IDEpewogICAgICAgIGZvcihqPSBsbDtqPGx1O2orKyl7CiAgICAgICAgICBpZihxdW90YUJ1ZmZlcltqXSA+IHRocmVzT3JpZyAmJiAoc2ZtU2JyW2ldID4gbWhUaHJlc2guc2ZtVGhyZXNTYnIgJiYgc2ZtT3JpZ1tpXSA8IG1oVGhyZXNoLnNmbVRocmVzT3JpZykpewogICAgICAgICAgICBwSGFybVZlY1tpXSA9IDE7CiAgICAgICAgICAgIG5ld0d1aWRlVmVjdG9ycy5ndWlkZVZlY3Rvck9yaWdbaV0gPSBxdW90YUJ1ZmZlcltqXTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZXsKICAgICAgICBpZihpIDwgblNmYiAtMSl7CiAgICAgICAgICBsbCA9IHBGcmVxQmFuZFRhYmxlW2ldOwoKICAgICAgICAgIGlmKGk+MCl7CiAgICAgICAgICAgIGlmKHF1b3RhQnVmZmVyW2xsXSA+IG1oVGhyZXNoLnRocmVzSG9sZFRvbmUgJiYgKHBEaWZmVmVjU2NmYltpKzFdIDwgbWhUaHJlc2guaW52VGhyZXNIb2xkVG9uZSB8fCBwRGlmZlZlY1NjZmJbaS0xXSA8IG1oVGhyZXNoLmludlRocmVzSG9sZFRvbmUpKXsKICAgICAgICAgICAgICAgIHBIYXJtVmVjW2ldID0gMTsKICAgICAgICAgICAgICAgIG5ld0d1aWRlVmVjdG9ycy5ndWlkZVZlY3Rvck9yaWdbaV0gPSBxdW90YUJ1ZmZlcltsbF07CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGVsc2V7CiAgICAgICAgICAgIGlmKHF1b3RhQnVmZmVyW2xsXSA+IG1oVGhyZXNoLnRocmVzSG9sZFRvbmUgJiYgcERpZmZWZWNTY2ZiW2krMV0gPCBtaFRocmVzaC5pbnZUaHJlc0hvbGRUb25lKXsKICAgICAgICAgICAgICAgIHBIYXJtVmVjW2ldID0gMTsKICAgICAgICAgICAgICAgIG5ld0d1aWRlVmVjdG9ycy5ndWlkZVZlY3Rvck9yaWdbaV0gPSBxdW90YUJ1ZmZlcltsbF07CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgRG8gZGV0ZWN0aW9uIGZvciBldmVyeSB0b25hbGl0eSBlc3RpbWF0ZSwgdXNpbmcgZm9yd2FyZCBwcmVkaWN0aW9uLgoKCiAgXHJldHVybiAgICBub25lLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBkZXRlY3Rpb25XaXRoUHJlZGljdGlvbihGSVhQX0RCTCAqKnF1b3RhQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqKnBEaWZmVmVjU2NmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICoqIHNpZ25CdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ0hBUiogcEZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICoqc2ZtT3JpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKipzZm1TYnIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICoqZGV0ZWN0aW9uVmVjdG9ycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgKnBQcmV2QWRkSGFybVNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR1VJREVfVkVDVE9SUyAqZ3VpZGVWZWN0b3JzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbm9Fc3RQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGRldGVjdGlvblN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgdG90Tm9Fc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuZXdEZXRlY3Rpb25BbGxvd2VkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKnBBZGRIYXJtRmxhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgKnBBZGRIYXJtU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqcE5yZ1ZlY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgREVURUNUT1JfUEFSQU1FVEVSU19NSCAqbWhQYXJhbXMpCnsKICBJTlQgZXN0ID0gMCxpOwogIElOVCBzdGFydDsKCiAgRkRLbWVtY2xlYXIocEFkZEhhcm1TZmIsblNmYipzaXplb2YoVUNIQVIpKTsKCiAgaWYobmV3RGV0ZWN0aW9uQWxsb3dlZCl7CgogICAgLyogU2luY2Ugd2UgZG9uJ3Qgd2FudCB0byB1c2UgdGhlIHRyYW5zaWVudCByZWdpb24gZm9yIGRldGVjdGlvbiAoc2luY2UgdGhlIHRvbmFsaXR5IHZhbHVlcwogICAgICAgdGVuZCB0byBiZSBhIGJpdCB1bnJlbGlhYmxlIGZvciB0aGlzIHJlZ2lvbikgdGhlIGd1aWRlLXZhbHVlcyBhcmUgY29waWVkIHRvIHRoZSBjdXJyZW50CiAgICAgICBzdGFydGluZyBwb2ludC4gKi8KICAgIGlmKHRvdE5vRXN0ID4gMSl7CiAgICAgIHN0YXJ0ID0gZGV0ZWN0aW9uU3RhcnQrMTsKCiAgICAgIGlmIChzdGFydCAhPSAwKSB7CiAgICAgICAgRkRLbWVtY3B5KGd1aWRlVmVjdG9yc1tzdGFydF0uZ3VpZGVWZWN0b3JEaWZmLGd1aWRlVmVjdG9yc1swXS5ndWlkZVZlY3RvckRpZmYsblNmYipzaXplb2YoRklYUF9EQkwpKTsKICAgICAgICBGREttZW1jcHkoZ3VpZGVWZWN0b3JzW3N0YXJ0XS5ndWlkZVZlY3Rvck9yaWcsZ3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yT3JpZyxuU2ZiKnNpemVvZihGSVhQX0RCTCkpOwogICAgICAgIEZES21lbWNsZWFyKGd1aWRlVmVjdG9yc1tzdGFydC0xXS5ndWlkZVZlY3RvckRldGVjdGVkLG5TZmIqc2l6ZW9mKFVDSEFSKSk7CiAgICAgIH0KICAgIH0KICAgIGVsc2V7CiAgICAgIHN0YXJ0ID0gMDsKICAgIH0KICB9CiAgZWxzZXsKICAgIHN0YXJ0ID0gMDsKICB9CgoKICBmb3IoZXN0ID0gc3RhcnQ7IGVzdCA8IHRvdE5vRXN0OyBlc3QrKyl7CgogICAgLyoKICAgICogRG8gZGV0ZWN0aW9uIG9uIHRoZSBjdXJyZW50IGZyYW1lIHVzaW5nCiAgICAqIGd1aWRlLWluZm8gZnJvbSB0aGUgcHJldmlvdXMuCiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgaWYoZXN0ID4gMCl7CiAgICAgIEZES21lbWNweShndWlkZVZlY3RvcnNbZXN0XS5ndWlkZVZlY3RvckRldGVjdGVkLGRldGVjdGlvblZlY3RvcnNbZXN0LTFdLG5TZmIqc2l6ZW9mKFVDSEFSKSk7CiAgICB9CgogICAgRkRLbWVtY2xlYXIoZGV0ZWN0aW9uVmVjdG9yc1tlc3RdLCBuU2ZiKnNpemVvZihVQ0hBUikpOwoKICAgIGlmKGVzdCA8IHRvdE5vRXN0LTEpewogICAgICBGREttZW1jbGVhcihndWlkZVZlY3RvcnNbZXN0KzFdLmd1aWRlVmVjdG9yRGlmZixuU2ZiKnNpemVvZihGSVhQX0RCTCkpOwogICAgICBGREttZW1jbGVhcihndWlkZVZlY3RvcnNbZXN0KzFdLmd1aWRlVmVjdG9yT3JpZyxuU2ZiKnNpemVvZihGSVhQX0RCTCkpOwogICAgICBGREttZW1jbGVhcihndWlkZVZlY3RvcnNbZXN0KzFdLmd1aWRlVmVjdG9yRGV0ZWN0ZWQsblNmYipzaXplb2YoVUNIQVIpKTsKCiAgICAgIGRldGVjdGlvbihxdW90YUJ1ZmZlcltlc3RdLAogICAgICAgICAgICAgICAgcERpZmZWZWNTY2ZiW2VzdF0sCiAgICAgICAgICAgICAgICBuU2ZiLAogICAgICAgICAgICAgICAgZGV0ZWN0aW9uVmVjdG9yc1tlc3RdLAogICAgICAgICAgICAgICAgcEZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICBzZm1PcmlnW2VzdF0sCiAgICAgICAgICAgICAgICBzZm1TYnJbZXN0XSwKICAgICAgICAgICAgICAgIGd1aWRlVmVjdG9yc1tlc3RdLAogICAgICAgICAgICAgICAgZ3VpZGVWZWN0b3JzW2VzdCsxXSwKICAgICAgICAgICAgICAgIG1oUGFyYW1zLT50aHJlc0hvbGRzKTsKICAgIH0KICAgIGVsc2V7CiAgICAgIEZES21lbWNsZWFyKGd1aWRlVmVjdG9yc1tlc3RdLmd1aWRlVmVjdG9yRGlmZixuU2ZiKnNpemVvZihGSVhQX0RCTCkpOwogICAgICBGREttZW1jbGVhcihndWlkZVZlY3RvcnNbZXN0XS5ndWlkZVZlY3Rvck9yaWcsblNmYipzaXplb2YoRklYUF9EQkwpKTsKICAgICAgRkRLbWVtY2xlYXIoZ3VpZGVWZWN0b3JzW2VzdF0uZ3VpZGVWZWN0b3JEZXRlY3RlZCxuU2ZiKnNpemVvZihVQ0hBUikpOwoKICAgICAgZGV0ZWN0aW9uKHF1b3RhQnVmZmVyW2VzdF0sCiAgICAgICAgICAgICAgICBwRGlmZlZlY1NjZmJbZXN0XSwKICAgICAgICAgICAgICAgIG5TZmIsCiAgICAgICAgICAgICAgICBkZXRlY3Rpb25WZWN0b3JzW2VzdF0sCiAgICAgICAgICAgICAgICBwRnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgIHNmbU9yaWdbZXN0XSwKICAgICAgICAgICAgICAgIHNmbVNicltlc3RdLAogICAgICAgICAgICAgICAgZ3VpZGVWZWN0b3JzW2VzdF0sCiAgICAgICAgICAgICAgICBndWlkZVZlY3RvcnNbZXN0XSwKICAgICAgICAgICAgICAgIG1oUGFyYW1zLT50aHJlc0hvbGRzKTsKICAgIH0KICB9CgoKICAvKiBDbGVhbiB1cCB0aGUgZGV0ZWN0aW9uLiovCiAgdHJhbnNpZW50Q2xlYW5VcChxdW90YUJ1ZmZlciwKICAgICAgICAgICAgICAgICAgIG5TZmIsCiAgICAgICAgICAgICAgICAgICBkZXRlY3Rpb25WZWN0b3JzLAogICAgICAgICAgICAgICAgICAgcEFkZEhhcm1TZmIsCiAgICAgICAgICAgICAgICAgICBwUHJldkFkZEhhcm1TZmIsCiAgICAgICAgICAgICAgICAgICBzaWduQnVmZmVyLAogICAgICAgICAgICAgICAgICAgcEZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICBzdGFydCwKICAgICAgICAgICAgICAgICAgIHRvdE5vRXN0LAogICAgICAgICAgICAgICAgICAgbmV3RGV0ZWN0aW9uQWxsb3dlZCwKICAgICAgICAgICAgICAgICAgIHBOcmdWZWN0b3IsCiAgICAgICAgICAgICAgICAgICBtaFBhcmFtcy0+dGhyZXNIb2xkcyk7CgoKICAvKiBTZXQgZmxhZy4uLiAqLwogICpwQWRkSGFybUZsYWcgPSAwOwogIGZvcihpPTA7IGk8blNmYjsgaSsrKXsKICAgIGlmKHBBZGRIYXJtU2ZiW2ldKXsKICAgICAgKnBBZGRIYXJtRmxhZyA9IDE7CiAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgRkRLbWVtY3B5KHBQcmV2QWRkSGFybVNmYiwgcEFkZEhhcm1TZmIsIG5TZmIqc2l6ZW9mKFVDSEFSKSk7CiAgRkRLbWVtY3B5KGd1aWRlVmVjdG9yc1swXS5ndWlkZVZlY3RvckRldGVjdGVkLHBBZGRIYXJtU2ZiLG5TZmIqc2l6ZW9mKElOVCkpOwoKICBmb3IoaT0wOyBpPG5TZmIgOyBpKyspewoKICAgIGd1aWRlVmVjdG9yc1swXS5ndWlkZVZlY3RvckRpZmZbaV0gPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgIGd1aWRlVmVjdG9yc1swXS5ndWlkZVZlY3Rvck9yaWdbaV0gPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKCiAgICBpZihwQWRkSGFybVNmYltpXSA9PSAxKXsKICAgICAgLyogSWYgd2UgaGFkIGEgZGV0ZWN0aW9uIHVzZSB0aGUgZ3VpZGUtdmFsdWUgaW4gdGhlIG5leHQgZnJhbWUgZnJvbSB0aGUgbGFzdCBlc3RpbWF0ZSB3ZXJlIHRoZSBkZXRlY3Rpb24KICAgICAgd2FzIGRvbmUuKi8KICAgICAgZm9yKGVzdD1zdGFydDsgZXN0IDwgdG90Tm9Fc3Q7IGVzdCsrKXsKICAgICAgICBpZihndWlkZVZlY3RvcnNbZXN0XS5ndWlkZVZlY3RvckRpZmZbaV0gIT0gRkwyRlhDT05TVF9EQkwoMC4wZikpewogICAgICAgICAgZ3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGlmZltpXSA9IGd1aWRlVmVjdG9yc1tlc3RdLmd1aWRlVmVjdG9yRGlmZltpXTsKICAgICAgICB9CiAgICAgICAgaWYoZ3VpZGVWZWN0b3JzW2VzdF0uZ3VpZGVWZWN0b3JPcmlnW2ldICE9IEZMMkZYQ09OU1RfREJMKDAuMGYpKXsKICAgICAgICAgIGd1aWRlVmVjdG9yc1swXS5ndWlkZVZlY3Rvck9yaWdbaV0gPSBndWlkZVZlY3RvcnNbZXN0XS5ndWlkZVZlY3Rvck9yaWdbaV07CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBDYWxjdWxhdGVzIGEgY29tcGVuc2F0aW9uIHZlY3RvciBmb3IgdGhlIGVuZXJneSBkYXRhLgoKICBUaGlzIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgYSBjb21wZW5zYXRpb24gdmVjdG9yIGZvciB0aGUgZW5lcmd5IGRhdGEgKGkuZS4KICBlbnZlbG9wZSBkYXRhKSB0aGF0IGlzIGNhbGN1bGF0ZWQgZWxzZXdoZXJlLiBUaGlzIGlzIHNpbmNlLCBvbmUgc2luZSBvbgogIHRoZSBib3JkZXIgb2YgdHdvIHNjYWxlZmFjdG9yIGJhbmRzLCB3aWxsIGJlIHJlcGxhY2UgYnkgb25lIHNpbmUgaW4gdGhlCiAgbWlkZGxlIG9mIGVpdGhlciBzY2FsZWZhY3RvciBiYW5kLiBIb3dldmVyLCBzaW5jZSB0aGUgc2luZSB0aGF0IGlzIHJlcGxhY2VkCiAgd2lsbCBpbmZsdWVuY2UgdGhlIGVuZXJneSBlc3RpbWF0ZSBpbiBib3RoIHNjYWxlZmFjdG9yIGJhbmRzIChpbiB0aGUgZW52ZWxvcHMKICBjYWxjdWxhdGlvbiBmdW5jdGlvbikgYSBjb21wZW5zYXRpb24gdmFsdWUgaXMgcmVxdWlyZWQgaW4gb3JkZXIgdG8gYXZvaWQKICBub2lzZSBzdWJzdGl0dXRpb24gaW4gdGhlIGRlY29kZXIgbmV4dCB0byB0aGUgc3ludGhldGljIHNpbmUuCgogIFxyZXR1cm4gICAgbm9uZS4KCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgY2FsY3VsYXRlQ29tcFZlY3RvcihVQ0hBUiAqcEFkZEhhcm1TZmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgKipwVG9uYWxpdHlNYXRyaXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICoqIHBTaWduTWF0cml4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICpwRW52Q29tcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgblNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ0hBUiAqZnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgdG90Tm9Fc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIG1heENvbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgKnBQcmV2RW52Q29tcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbmV3RGV0ZWN0aW9uQWxsb3dlZCkKewoKICBJTlQgc2NmQmFuZCxlc3QsbCxsbCxsdSxtYXhQb3NGLG1heFBvc1Q7CiAgRklYUF9EQkwgbWF4VmFsOwogIElOVCBjb21wVmFsdWU7CiAgRklYUF9EQkwgdG1wOwoKICBGREttZW1jbGVhcihwRW52Q29tcCxuU2ZiKnNpemVvZihVQ0hBUikpOwoKICBmb3Ioc2NmQmFuZD0wOyBzY2ZCYW5kIDwgblNmYjsgc2NmQmFuZCsrKXsKCiAgICBpZihwQWRkSGFybVNmYltzY2ZCYW5kXSl7IC8qIEEgbWlzc2luZyBzaW5lIHdhcyBkZXRlY3RlZCAqLwogICAgICBsbCA9IGZyZXFCYW5kVGFibGVbc2NmQmFuZF07CiAgICAgIGx1ID0gZnJlcUJhbmRUYWJsZVtzY2ZCYW5kKzFdOwoKICAgICAgbWF4UG9zRiA9IDA7ICAgICAgICAgICAgICAgICAgICAgICAgLyogRmlyc3QgZmluZCB0aGUgbWF4aW11bSovCiAgICAgIG1heFBvc1QgPSAwOwogICAgICBtYXhWYWwgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKCiAgICAgIGZvcihlc3Q9MDtlc3Q8dG90Tm9Fc3Q7ZXN0KyspewogICAgICAgIGZvcihsPWxsOyBsPGx1OyBsKyspewogICAgICAgICAgaWYocFRvbmFsaXR5TWF0cml4W2VzdF1bbF0gPiBtYXhWYWwpewogICAgICAgICAgICBtYXhWYWwgPSBwVG9uYWxpdHlNYXRyaXhbZXN0XVtsXTsKICAgICAgICAgICAgbWF4UG9zRiA9IGw7CiAgICAgICAgICAgIG1heFBvc1QgPSBlc3Q7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CgogICAgICAvKgogICAgICAgKiBJZiB0aGUgbWF4aW11bSB0b25hbGl0eSBpcyBhdCB0aGUgbG93ZXIgYm9yZGVyIG9mIHRoZQogICAgICAgKiBzY2FsZWZhY3RvciBiYW5kLCB3ZSBjaGVjayB0aGUgc2lnbiBvZiB0aGUgYWRqYWNlbnQgY2hhbm5lbHMKICAgICAgICogdG8gc2VlIGlmIHRoaXMgc2luZSBpcyBzaGFyZWQgYnkgdGhlIGxvd2VyIGNoYW5uZWwuIElmIHNvLCB0aGUKICAgICAgICogZW5lcmd5IG9mIHRoZSBzaW5nbGUgc2luZSB3aWxsIGJlIHByZXNlbnQgaW4gdHdvIHNjYWxlZmFjdG9yIGJhbmRzCiAgICAgICAqIGluIHRoZSBTQlIgZGF0YSwgd2hpY2ggd2lsbCBjYXVzZSBwcm9ibGVtcyBpbiB0aGUgZGVjb2Rlciwgd2hlbiB3ZQogICAgICAgKiBhZGQgYSBzaW5lIHRvIGp1c3Qgb25lIG9mIHRoZSBjaGFubmVscy4KICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgICAgaWYobWF4UG9zRiA9PSBsbCAmJiBzY2ZCYW5kKXsKICAgICAgICBpZighcEFkZEhhcm1TZmJbc2NmQmFuZCAtIDFdKSB7ICAgICAvKiBObyBkZXRlY3Rpb24gYmVsb3cqLwogICAgICAgICAgaWYgKHBTaWduTWF0cml4W21heFBvc1RdW21heFBvc0YgLSAxXSA+IDAgJiYgcFNpZ25NYXRyaXhbbWF4UG9zVF1bbWF4UG9zRl0gPCAwKSB7CiAgICAgICAgICAgIC8qIFRoZSBjb21wIHZhbHVlIGlzIGNhbHVsYXRlZCBhcyB0aGUgdG9uYWxsaXR5IHZhbHVlLCBpLmUgd2Ugd2FudCB0bwogICAgICAgICAgICAgICByZWR1Y2UgdGhlIGVudmVsb3BlIGRhdGEgZm9yIHRoaXMgY2hhbm5lbCB3aXRoIGFzIG11Y2ggYXMgdGhlIHRvbmFsaXR5CiAgICAgICAgICAgICAgIHRoYXQgaXMgc3ByZWFkIGZyb20gdGhlIGNoYW5uZWwgYWJvdmUuIChsZDY0KFJFTEFYQVRJT04pID0gMC4zMTE0MzA3NTg4OSkgKi8KICAgICAgICAgICAgdG1wID0gZml4cF9hYnMoKEZJWFBfREJMKUNhbGNMZERhdGEocFRvbmFsaXR5TWF0cml4W21heFBvc1RdW21heFBvc0YgLSAxXSkgKyBSRUxBWEFUSU9OX0xENjQpOwogICAgICAgICAgICB0bXAgPSAodG1wID4+IChERlJBQ1RfQklUUy0xLUxEX0RBVEFfU0hJRlQtMSkpICsgKEZJWFBfREJMKTE7ICAvKiBzaGlmdCBvbmUgYml0IGxlc3MgZm9yIHJvdW5kaW5nICovCiAgICAgICAgICAgIGNvbXBWYWx1ZSA9ICgoSU5UKShMT05HKXRtcCkgPj4gMTsKCgkJCQkJCSAgICAgIC8qIGxpbWl0IHRoZSBjb21wLXZhbHVlKi8KICAgICAgICAgICAgaWYgKGNvbXBWYWx1ZSA+IG1heENvbXApCiAgICAgICAgICAgICAgY29tcFZhbHVlID0gbWF4Q29tcDsKCiAgICAgICAgICAgIHBFbnZDb21wW3NjZkJhbmQtMV0gPSBjb21wVmFsdWU7CgkJCQkJICAgICB9CgkJCQkgICAgfQogICAgICB9CgogICAgICAvKgogICAgICAgKiBTYW1lIGFzIGFib3ZlLCBidXQgZm9yIHRoZSB1cHBlciBlbmQgb2YgdGhlIHNjYWxlZmFjdG9yLWJhbmQuCiAgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICAgIGlmKG1heFBvc0YgPT0gbHUtMSAmJiBzY2ZCYW5kKzEgPCBuU2ZiKXsgICAgICAgIC8qIFVwcGVyIGJvcmRlciovCiAgICAgICAgaWYoIXBBZGRIYXJtU2ZiW3NjZkJhbmQgKyAxXSkgewogICAgICAgICAgaWYgKHBTaWduTWF0cml4W21heFBvc1RdW21heFBvc0ZdID4gMCAmJiBwU2lnbk1hdHJpeFttYXhQb3NUXVttYXhQb3NGICsgMV0gPCAwKSB7CiAgICAgICAgICAgIHRtcCA9IGZpeHBfYWJzKChGSVhQX0RCTClDYWxjTGREYXRhKHBUb25hbGl0eU1hdHJpeFttYXhQb3NUXVttYXhQb3NGICsgMV0pICsgUkVMQVhBVElPTl9MRDY0KTsKICAgICAgICAgICAgdG1wID0gKHRtcCA+PiAoREZSQUNUX0JJVFMtMS1MRF9EQVRBX1NISUZULTEpKSArIChGSVhQX0RCTCkxOyAgLyogc2hpZnQgb25lIGJpdCBsZXNzIGZvciByb3VuZGluZyAqLwogICAgICAgICAgICBjb21wVmFsdWUgPSAoKElOVCkoTE9ORyl0bXApID4+IDE7CgogICAgICAgICAgICBpZiAoY29tcFZhbHVlID4gbWF4Q29tcCkKICAgICAgICAgICAgICBjb21wVmFsdWUgPSBtYXhDb21wOwoKICAgICAgICAgICAgcEVudkNvbXBbc2NmQmFuZCsxXSA9IGNvbXBWYWx1ZTsKCQkJCQkgfQoJCQkJIH0KICAgICAgfQoJCSB9CgkgfQoKICBpZihuZXdEZXRlY3Rpb25BbGxvd2VkID09IDApewogICAgZm9yKHNjZkJhbmQ9MDtzY2ZCYW5kPG5TZmI7c2NmQmFuZCsrKXsKICAgICAgaWYocEVudkNvbXBbc2NmQmFuZF0gIT0gMCAmJiBwUHJldkVudkNvbXBbc2NmQmFuZF0gPT0gMCkKICAgICAgICBwRW52Q29tcFtzY2ZCYW5kXSA9IDA7CiAgICB9CiAgfQoKICAvKiByZW1lbWJlciB0aGUgdmFsdWUgZm9yIHRoZSBuZXh0IGZyYW1lLiovCiAgRkRLbWVtY3B5KHBQcmV2RW52Q29tcCxwRW52Q29tcCxuU2ZiKnNpemVvZihVQ0hBUikpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiEKICBcYnJpZWYgICAgIERldGVjdHMgd2hlcmUgc3Ryb25nIHRvbmFsIGNvbXBvbmVudHMgd2lsbCBiZSBtaXNzaW5nIGFmdGVyCiAgICAgICAgICAgICBIRlIgaW4gdGhlIGRlY29kZXIuCgoKICBccmV0dXJuICAgIG5vbmUuCgoqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnZvaWQKRkRLc2JyRW5jX1Nick1pc3NpbmdIYXJtb25pY3NEZXRlY3RvclFtZihIQU5ETEVfU0JSX01JU1NJTkdfSEFSTU9OSUNTX0RFVEVDVE9SIGhfc2JyTUhEZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAqKiBwUXVvdGFCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgKiogcFNpZ25CdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQ0hBUiogaW5kZXhWZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTQlJfRlJBTUVfSU5GTyAqcEZyYW1lSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDSEFSKiBwVHJhbkluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQqIHBBZGRIYXJtb25pY3NGbGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIqIHBBZGRIYXJtb25pY3NTY2FsZUZhY3RvckJhbmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUNIQVIqIGZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgblNmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSKiBlbnZlbG9wZUNvbXBlbnNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpwTnJnVmVjdG9yKQp7CiAgSU5UIHRyYW5zaWVudEZsYWcgPSBwVHJhbkluZm9bMV07CiAgSU5UIHRyYW5zaWVudFBvcyAgPSBwVHJhbkluZm9bMF07CiAgSU5UIG5ld0RldGVjdGlvbkFsbG93ZWQ7CiAgSU5UIHRyYW5zaWVudERldFN0YXJ0ID0gMDsKCiAgVUNIQVIgKiogZGV0ZWN0aW9uVmVjdG9ycyAgPSBoX3Nick1IRGV0LT5kZXRlY3Rpb25WZWN0b3JzOwogIElOVCBtb3ZlICAgICAgICAgICAgICAgID0gaF9zYnJNSERldC0+bW92ZTsKICBJTlQgbm9Fc3RQZXJGcmFtZSAgICAgICA9IGhfc2JyTUhEZXQtPm5vRXN0UGVyRnJhbWU7CiAgSU5UIHRvdE5vRXN0ICAgICAgICAgICAgPSBoX3Nick1IRGV0LT50b3ROb0VzdDsKICBJTlQgcHJldlRyYW5zaWVudEZsYWcgICA9IGhfc2JyTUhEZXQtPnByZXZpb3VzVHJhbnNpZW50RmxhZzsKICBJTlQgcHJldlRyYW5zaWVudEZyYW1lICA9IGhfc2JyTUhEZXQtPnByZXZpb3VzVHJhbnNpZW50RnJhbWU7CiAgSU5UIHRyYW5zaWVudFBvc09mZnNldCAgPSBoX3Nick1IRGV0LT50cmFuc2llbnRQb3NPZmZzZXQ7CiAgSU5UIHByZXZUcmFuc2llbnRQb3MgICAgPSBoX3Nick1IRGV0LT5wcmV2aW91c1RyYW5zaWVudFBvczsKICBHVUlERV9WRUNUT1JTKiBndWlkZVZlY3RvcnMgPSBoX3Nick1IRGV0LT5ndWlkZVZlY3RvcnM7CiAgSU5UIGRlbHRhVGltZSA9IGhfc2JyTUhEZXQtPm1oUGFyYW1zLT5kZWx0YVRpbWU7CiAgSU5UIG1heENvbXAgPSBoX3Nick1IRGV0LT5taFBhcmFtcy0+bWF4Q29tcDsKCiAgaW50IGVzdDsKCiAgLyoKICBCdWZmZXIgdmFsdWVzLgogICovCiAgRkRLX0FTU0VSVChtb3ZlPD0oTUFYX05PX09GX0VTVElNQVRFUz4+MSkpOwogIEZES19BU1NFUlQobm9Fc3RQZXJGcmFtZTw9KE1BWF9OT19PRl9FU1RJTUFURVM+PjEpKTsKCiAgRklYUF9EQkwgKnNmbVNicltNQVhfTk9fT0ZfRVNUSU1BVEVTXTsKICBGSVhQX0RCTCAqc2ZtT3JpZ1tNQVhfTk9fT0ZfRVNUSU1BVEVTXTsKICBGSVhQX0RCTCAqdG9uYWxpdHlEaWZmW01BWF9OT19PRl9FU1RJTUFURVNdOwoKICBmb3IgKGVzdD0wOyBlc3QgPCBNQVhfTk9fT0ZfRVNUSU1BVEVTLzI7IGVzdCsrKSB7CiAgICBzZm1TYnJbZXN0XSAgICAgICA9IGhfc2JyTUhEZXQtPnNmbVNicltlc3RdOwogICAgc2ZtT3JpZ1tlc3RdICAgICAgPSBoX3Nick1IRGV0LT5zZm1PcmlnW2VzdF07CiAgICB0b25hbGl0eURpZmZbZXN0XSA9IGhfc2JyTUhEZXQtPnRvbmFsaXR5RGlmZltlc3RdOwogIH0KCiAgQ19BTExPQ19TQ1JBVENIX1NUQVJUKHNjcmF0Y2hfbWVtLCBGSVhQX0RCTCwgKDMqTUFYX05PX09GX0VTVElNQVRFUy8yKk1BWF9GUkVRX0NPRUZGUykpOwogIEZJWFBfREJMICpzY3JhdGNoID0gc2NyYXRjaF9tZW07CiAgZm9yICg7IGVzdCA8IE1BWF9OT19PRl9FU1RJTUFURVM7IGVzdCsrKSB7CiAgICBzZm1TYnJbZXN0XSAgICAgICA9IHNjcmF0Y2g7IHNjcmF0Y2grPU1BWF9GUkVRX0NPRUZGUzsKICAgIHNmbU9yaWdbZXN0XSAgICAgID0gc2NyYXRjaDsgc2NyYXRjaCs9TUFYX0ZSRVFfQ09FRkZTOwogICAgdG9uYWxpdHlEaWZmW2VzdF0gPSBzY3JhdGNoOyBzY3JhdGNoKz1NQVhfRlJFUV9DT0VGRlM7CiAgfQoKCgogIC8qIERldGVybWluZSBpZiB3ZSdyZSBhbGxvd2VkIHRvIGRldGVjdCAibWlzc2luZyBoYXJtb25pY3MiIHRoYXQgd2Fzbid0IGRldGVjdGVkIGJlZm9yZS4KICAgICBJbiBvcmRlciB0byBiZSBhbGxvd2VkIHRvIGRvIG5ldyBkZXRlY3Rpb24sIHRoZXJlIG11c3QgYmUgYSB0cmFuc2llbnQgaW4gdGhlIGN1cnJlbnQKICAgICBmcmFtZSwgb3IgYSB0cmFuc2llbnQgaW4gdGhlIHByZXZpb3VzIGZyYW1lIHN1ZmZpY2llbnRseSBjbG9zZSB0byB0aGUgY3VycmVudCBmcmFtZS4gKi8KICBuZXdEZXRlY3Rpb25BbGxvd2VkID0gaXNEZXRlY3Rpb25PZk5ld1RvbmVBbGxvd2VkKHBGcmFtZUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdHJhbnNpZW50RGV0U3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub0VzdFBlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldlRyYW5zaWVudEZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldlRyYW5zaWVudFBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZUcmFuc2llbnRGbGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNpZW50UG9zT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNpZW50RmxhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zaWVudFBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbHRhVGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhfc2JyTUhEZXQpOwoKICAvKiBDYWx1bGF0ZSB0aGUgdmFyaWFibGVzIHRoYXQgd2lsbCBiZSB1c2VkIHN1YnNlcXVlbnRseSBmb3IgdGhlIGFjdHVhbCBkZXRlY3Rpb24gKi8KICBjYWxjdWxhdGVEZXRlY3RvcklucHV0KHBRdW90YUJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4VmVjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgdG9uYWxpdHlEaWZmLAogICAgICAgICAgICAgICAgICAgICAgICAgc2ZtT3JpZywKICAgICAgICAgICAgICAgICAgICAgICAgIHNmbVNiciwKICAgICAgICAgICAgICAgICAgICAgICAgIGZyZXFCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICBuU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgbm9Fc3RQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIG1vdmUpOwoKICAvKiBEbyB0aGUgYWN0dWFsIGRldGVjdGlvbiB1c2luZyBpbmZvcm1hdGlvbiBmcm9tIHByZXZpb3VzIGRldGVjdGlvbnMgKi8KICBkZXRlY3Rpb25XaXRoUHJlZGljdGlvbihwUXVvdGFCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdG9uYWxpdHlEaWZmLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBTaWduQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5TZmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzZm1PcmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNmbVNiciwKICAgICAgICAgICAgICAgICAgICAgICAgICBkZXRlY3Rpb25WZWN0b3JzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGhfc2JyTUhEZXQtPmd1aWRlU2NmYiwKICAgICAgICAgICAgICAgICAgICAgICAgICBndWlkZVZlY3RvcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbm9Fc3RQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2llbnREZXRTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICB0b3ROb0VzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdEZXRlY3Rpb25BbGxvd2VkLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBBZGRIYXJtb25pY3NGbGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBBZGRIYXJtb25pY3NTY2FsZUZhY3RvckJhbmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBOcmdWZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaF9zYnJNSERldC0+bWhQYXJhbXMpOwoKICAvKiBDYWxjdWxhdGUgdGhlIGNvbXAgdmVjdG9yLCBzbyB0aGF0IHRoZSBlbmVyZ3kgY2FuIGJlCiAgICAgY29tcGVuc2F0ZWQgZm9yIGEgc2luZSBiZXR3ZWVuIHR3byBRTUYtYmFuZHMuICovCiAgY2FsY3VsYXRlQ29tcFZlY3RvcihwQWRkSGFybW9uaWNzU2NhbGVGYWN0b3JCYW5kcywKICAgICAgICAgICAgICAgICAgICAgIHBRdW90YUJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgIHBTaWduQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgZW52ZWxvcGVDb21wZW5zYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICBuU2ZiLAogICAgICAgICAgICAgICAgICAgICAgZnJlcUJhbmRUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgIHRvdE5vRXN0LAogICAgICAgICAgICAgICAgICAgICAgbWF4Q29tcCwKICAgICAgICAgICAgICAgICAgICAgIGhfc2JyTUhEZXQtPnByZXZFbnZlbG9wZUNvbXBlbnNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgIG5ld0RldGVjdGlvbkFsbG93ZWQpOwoKICBmb3IgKGVzdD0wOyBlc3QgPCBtb3ZlOyBlc3QrKykgewogICAgRkRLbWVtY3B5KHRvbmFsaXR5RGlmZltlc3RdLCB0b25hbGl0eURpZmZbZXN0ICsgbm9Fc3RQZXJGcmFtZV0sIHNpemVvZihGSVhQX0RCTCkqTUFYX0ZSRVFfQ09FRkZTKTsKICAgIEZES21lbWNweShzZm1PcmlnW2VzdF0sIHNmbU9yaWdbZXN0ICsgbm9Fc3RQZXJGcmFtZV0sIHNpemVvZihGSVhQX0RCTCkqTUFYX0ZSRVFfQ09FRkZTKTsKICAgIEZES21lbWNweShzZm1TYnJbZXN0XSwgc2ZtU2JyW2VzdCArIG5vRXN0UGVyRnJhbWVdLCBzaXplb2YoRklYUF9EQkwpKk1BWF9GUkVRX0NPRUZGUyk7CiAgfQogIENfQUxMT0NfU0NSQVRDSF9FTkQoc2NyYXRjaCwgRklYUF9EQkwsICgzKk1BWF9OT19PRl9FU1RJTUFURVMvMipNQVhfRlJFUV9DT0VGRlMpKTsKCgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgSW5pdGlhbGl6ZSBhbiBpbnN0YW5jZSBvZiB0aGUgbWlzc2luZyBoYXJtb25pY3MgZGV0ZWN0b3IuCgoKICBccmV0dXJuICAgIGVycm9yQ29kZSwgbm9FcnJvciBpZiBPSy4KCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSU5UCkZES3NickVuY19DcmVhdGVTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3IgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfTUlTU0lOR19IQVJNT05JQ1NfREVURUNUT1IgaFNick1IRGV0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBjaGFuKQp7CiAgSEFORExFX1NCUl9NSVNTSU5HX0hBUk1PTklDU19ERVRFQ1RPUiBocyA9IGhTYnJNSERldDsKICBJTlQgaTsKCiAgVUNIQVIqIGRldGVjdGlvblZlY3RvcnMgICAgPSBHZXRSYW1fU2JyX2RldGVjdGlvblZlY3RvcnMoY2hhbik7CiAgVUNIQVIqIGd1aWRlVmVjdG9yRGV0ZWN0ZWQgPSBHZXRSYW1fU2JyX2d1aWRlVmVjdG9yRGV0ZWN0ZWQoY2hhbik7CiAgRklYUF9EQkwqIGd1aWRlVmVjdG9yRGlmZiAgPSBHZXRSYW1fU2JyX2d1aWRlVmVjdG9yRGlmZihjaGFuKTsKICBGSVhQX0RCTCogZ3VpZGVWZWN0b3JPcmlnICA9IEdldFJhbV9TYnJfZ3VpZGVWZWN0b3JPcmlnKGNoYW4pOwoKICBGREttZW1jbGVhciAoaHMsc2l6ZW9mKFNCUl9NSVNTSU5HX0hBUk1PTklDU19ERVRFQ1RPUikpOwoKICBocy0+cHJldkVudmVsb3BlQ29tcGVuc2F0aW9uID0gR2V0UmFtX1Nicl9wcmV2RW52ZWxvcGVDb21wZW5zYXRpb24oY2hhbik7CiAgaHMtPmd1aWRlU2NmYiAgICAgICAgICAgICAgICA9IEdldFJhbV9TYnJfZ3VpZGVTY2ZiKGNoYW4pOwoKICBmb3IoaT0wOyBpPE1BWF9OT19PRl9FU1RJTUFURVM7IGkrKykgewogICAgaHMtPmd1aWRlVmVjdG9yc1tpXS5ndWlkZVZlY3RvckRpZmYgPSBndWlkZVZlY3RvckRpZmYgKyAoaSpNQVhfRlJFUV9DT0VGRlMpOwogICAgaHMtPmd1aWRlVmVjdG9yc1tpXS5ndWlkZVZlY3Rvck9yaWcgPSBndWlkZVZlY3Rvck9yaWcgKyAoaSpNQVhfRlJFUV9DT0VGRlMpOwogICAgaHMtPmRldGVjdGlvblZlY3RvcnNbaV0gPSBkZXRlY3Rpb25WZWN0b3JzICsgKGkqTUFYX0ZSRVFfQ09FRkZTKTsKICAgIGhzLT5ndWlkZVZlY3RvcnNbaV0uZ3VpZGVWZWN0b3JEZXRlY3RlZCA9IGd1aWRlVmVjdG9yRGV0ZWN0ZWQgKyAoaSpNQVhfRlJFUV9DT0VGRlMpOwogIH0KCiAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qIQogIFxicmllZiAgICAgSW5pdGlhbGl6ZSBhbiBpbnN0YW5jZSBvZiB0aGUgbWlzc2luZyBoYXJtb25pY3MgZGV0ZWN0b3IuCgoKICBccmV0dXJuICAgIGVycm9yQ29kZSwgbm9FcnJvciBpZiBPSy4KCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSU5UCkZES3NickVuY19Jbml0U2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX01JU1NJTkdfSEFSTU9OSUNTX0RFVEVDVE9SIGhTYnJNSERldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgc2FtcGxlRnJlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgZnJhbWVTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuU2ZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBxbWZOb0NoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCB0b3ROb0VzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbW92ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbm9Fc3RQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIHNiclN5bnRheEZsYWdzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICBIQU5ETEVfU0JSX01JU1NJTkdfSEFSTU9OSUNTX0RFVEVDVE9SIGhzID0gaFNick1IRGV0OwogIGludCBpOwoKICBGREtfQVNTRVJUKHRvdE5vRXN0IDw9IE1BWF9OT19PRl9FU1RJTUFURVMpOwoKICBpZiAoc2JyU3ludGF4RmxhZ3MgJiBTQlJfU1lOVEFYX0xPV19ERUxBWSkKICB7CiAgICBzd2l0Y2goZnJhbWVTaXplKXsKICAgIGNhc2UgMTAyNDoKICAgIGNhc2UgNTEyOgogICAgICAgIGhzLT50cmFuc2llbnRQb3NPZmZzZXQgPSBGUkFNRV9NSURETEVfU0xPVF81MTJMRDsKICAgICAgICBocy0+dGltZVNsb3RzICAgICAgICAgID0gMTY7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIDk2MDoKICAgIGNhc2UgNDgwOgogICAgICAgIGhzLT50cmFuc2llbnRQb3NPZmZzZXQgPSBGUkFNRV9NSURETEVfU0xPVF81MTJMRDsKICAgICAgICBocy0+dGltZVNsb3RzICAgICAgICAgID0gMTU7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiAtMTsKICAgIH0KICB9IGVsc2UKICB7CiAgICBzd2l0Y2goZnJhbWVTaXplKXsKICAgIGNhc2UgMjA0ODoKICAgIGNhc2UgMTAyNDoKICAgICAgICBocy0+dHJhbnNpZW50UG9zT2Zmc2V0ID0gRlJBTUVfTUlERExFX1NMT1RfMjA0ODsKICAgICAgICBocy0+dGltZVNsb3RzICAgICAgICAgID0gTlVNQkVSX1RJTUVfU0xPVFNfMjA0ODsKICAgICAgICBicmVhazsKICAgIGNhc2UgMTkyMDoKICAgIGNhc2UgOTYwOgogICAgICAgIGhzLT50cmFuc2llbnRQb3NPZmZzZXQgPSBGUkFNRV9NSURETEVfU0xPVF8xOTIwOwogICAgICAgIGhzLT50aW1lU2xvdHMgICAgICAgICAgPSBOVU1CRVJfVElNRV9TTE9UU18xOTIwOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gLTE7CiAgICB9CiAgfQoKICBpZiAoc2JyU3ludGF4RmxhZ3MgJiBTQlJfU1lOVEFYX0xPV19ERUxBWSkgewogICAgaHMtPm1oUGFyYW1zID0gJnBhcmFtc0FhY0xkOwogIH0gZWxzZQogIGhzLT5taFBhcmFtcyA9ICZwYXJhbXNBYWM7CgogIGhzLT5xbWZOb0NoYW5uZWxzID0gcW1mTm9DaGFubmVsczsKICBocy0+c2FtcGxlRnJlcSA9IHNhbXBsZUZyZXE7CiAgaHMtPm5TZmIgPSBuU2ZiOwoKICBocy0+dG90Tm9Fc3QgPSB0b3ROb0VzdDsKICBocy0+bW92ZSA9IG1vdmU7CiAgaHMtPm5vRXN0UGVyRnJhbWUgPSBub0VzdFBlckZyYW1lOwoKICBmb3IoaT0wOyBpPHRvdE5vRXN0OyBpKyspIHsKICAgIEZES21lbWNsZWFyIChocy0+Z3VpZGVWZWN0b3JzW2ldLmd1aWRlVmVjdG9yRGlmZixzaXplb2YoRklYUF9EQkwpKk1BWF9GUkVRX0NPRUZGUyk7CiAgICBGREttZW1jbGVhciAoaHMtPmd1aWRlVmVjdG9yc1tpXS5ndWlkZVZlY3Rvck9yaWcsc2l6ZW9mKEZJWFBfREJMKSpNQVhfRlJFUV9DT0VGRlMpOwogICAgRkRLbWVtY2xlYXIgKGhzLT5kZXRlY3Rpb25WZWN0b3JzW2ldLHNpemVvZihVQ0hBUikqTUFYX0ZSRVFfQ09FRkZTKTsKICAgIEZES21lbWNsZWFyIChocy0+Z3VpZGVWZWN0b3JzW2ldLmd1aWRlVmVjdG9yRGV0ZWN0ZWQsc2l6ZW9mKFVDSEFSKSpNQVhfRlJFUV9DT0VGRlMpOwogIH0KCiAgLy9mb3IoaT0wOyBpPHRvdE5vRXN0LzI7IGkrKykgewogIGZvcihpPTA7IGk8TUFYX05PX09GX0VTVElNQVRFUy8yOyBpKyspIHsKICAgIEZES21lbWNsZWFyIChocy0+dG9uYWxpdHlEaWZmW2ldLHNpemVvZihGSVhQX0RCTCkqTUFYX0ZSRVFfQ09FRkZTKTsKICAgIEZES21lbWNsZWFyIChocy0+c2ZtT3JpZ1tpXSxzaXplb2YoRklYUF9EQkwpKk1BWF9GUkVRX0NPRUZGUyk7CiAgICBGREttZW1jbGVhciAoaHMtPnNmbVNicltpXSxzaXplb2YoRklYUF9EQkwpKk1BWF9GUkVRX0NPRUZGUyk7CiAgfQoKICBGREttZW1jbGVhciAoIGhzLT5wcmV2RW52ZWxvcGVDb21wZW5zYXRpb24sIHNpemVvZihVQ0hBUikqTUFYX0ZSRVFfQ09FRkZTKTsKICBGREttZW1jbGVhciAoIGhzLT5ndWlkZVNjZmIsIHNpemVvZihVQ0hBUikqTUFYX0ZSRVFfQ09FRkZTKTsKCiAgaHMtPnByZXZpb3VzVHJhbnNpZW50RmxhZyA9IDA7CiAgaHMtPnByZXZpb3VzVHJhbnNpZW50RnJhbWUgPSAwOwogIGhzLT5wcmV2aW91c1RyYW5zaWVudFBvcyA9IDA7CgogIHJldHVybiAoMCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBEZWxldGVzIGFuIGluc3RhbmNlIG9mIHRoZSBtaXNzaW5nIGhhcm1vbmljcyBkZXRlY3Rvci4KCgogIFxyZXR1cm4gICAgbm9uZS4KCiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZApGREtzYnJFbmNfRGVsZXRlU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yKEhBTkRMRV9TQlJfTUlTU0lOR19IQVJNT05JQ1NfREVURUNUT1IgaFNick1IRGV0KQp7CiAgaWYgKGhTYnJNSERldCkgewogICAgSEFORExFX1NCUl9NSVNTSU5HX0hBUk1PTklDU19ERVRFQ1RPUiBocyA9IGhTYnJNSERldDsKCiAgICBGcmVlUmFtX1Nicl9kZXRlY3Rpb25WZWN0b3JzKCZocy0+ZGV0ZWN0aW9uVmVjdG9yc1swXSk7CiAgICBGcmVlUmFtX1Nicl9ndWlkZVZlY3RvckRldGVjdGVkKCZocy0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGV0ZWN0ZWQpOwogICAgRnJlZVJhbV9TYnJfZ3VpZGVWZWN0b3JEaWZmKCZocy0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGlmZik7CiAgICBGcmVlUmFtX1Nicl9ndWlkZVZlY3Rvck9yaWcoJmhzLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JPcmlnKTsKICAgIEZyZWVSYW1fU2JyX3ByZXZFbnZlbG9wZUNvbXBlbnNhdGlvbigmaHMtPnByZXZFbnZlbG9wZUNvbXBlbnNhdGlvbik7CiAgICBGcmVlUmFtX1Nicl9ndWlkZVNjZmIoJmhzLT5ndWlkZVNjZmIpOwoKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgICBSZXNldHMgYW4gaW5zdGFuY2Ugb2YgdGhlIG1pc3NpbmcgaGFybW9uaWNzIGRldGVjdG9yLgoKCiAgXHJldHVybiAgICBlcnJvciBjb2RlLCBub0Vycm9yIGlmIE9LLgoKKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpJTlQKRkRLc2JyRW5jX1Jlc2V0U2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yIChIQU5ETEVfU0JSX01JU1NJTkdfSEFSTU9OSUNTX0RFVEVDVE9SIGhTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgblNmYikKewogIGludCBpOwogIEZJWFBfREJMIHRlbXBHdWlkZVtNQVhfRlJFUV9DT0VGRlNdOwogIFVDSEFSIHRlbXBHdWlkZUludFtNQVhfRlJFUV9DT0VGRlNdOwogIElOVCBuU2ZiUHJldjsKCiAgblNmYlByZXYgPSBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5uU2ZiOwogIGhTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPm5TZmIgPSBuU2ZiOwoKICBGREttZW1jcHkoIHRlbXBHdWlkZUludCwgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVTY2ZiLCBuU2ZiUHJldiAqIHNpemVvZihVQ0hBUikgKTsKCiAgaWYgKCBuU2ZiID4gblNmYlByZXYgKSB7CiAgICBmb3IgKCBpID0gMDsgaSA8IChuU2ZiIC0gblNmYlByZXYpOyBpKysgKSB7CiAgICAgIGhTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPmd1aWRlU2NmYltpXSA9IDA7CiAgICB9CgogICAgZm9yICggaSA9IDA7IGkgPCBuU2ZiUHJldjsgaSsrICkgewogICAgICBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVNjZmJbaSArIChuU2ZiIC0gblNmYlByZXYpXSA9IHRlbXBHdWlkZUludFtpXTsKICAgIH0KICB9CiAgZWxzZSB7CiAgICBmb3IgKCBpID0gMDsgaSA8IG5TZmI7IGkrKyApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVTY2ZiW2ldID0gdGVtcEd1aWRlSW50W2kgKyAoblNmYlByZXYtblNmYildOwogICAgfQogIH0KCiAgRkRLbWVtY3B5ICggdGVtcEd1aWRlLCBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5ndWlkZVZlY3RvcnNbMF0uZ3VpZGVWZWN0b3JEaWZmLCBuU2ZiUHJldiAqIHNpemVvZihGSVhQX0RCTCkgKTsKCiAgaWYgKG5TZmIgPiBuU2ZiUHJldiApIHsKICAgIGZvciAoIGkgPSAwOyBpIDwgKG5TZmIgLSBuU2ZiUHJldik7IGkrKyApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGlmZltpXSA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogICAgfQoKICAgIGZvciAoIGkgPSAwOyBpIDwgblNmYlByZXY7IGkrKyApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGlmZltpICsgKG5TZmIgLSBuU2ZiUHJldildID0gdGVtcEd1aWRlW2ldOwogICAgfQogIH0KICBlbHNlIHsKICAgIGZvciAoIGkgPSAwOyBpIDwgblNmYjsgaSsrICApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGlmZltpXSA9IHRlbXBHdWlkZVtpICsgKG5TZmJQcmV2LW5TZmIpXTsKICAgIH0KICB9CgogIEZES21lbWNweSAoIHRlbXBHdWlkZSwgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yT3JpZywgblNmYlByZXYgKiBzaXplb2YoRklYUF9EQkwpICk7CgogIGlmICggblNmYiA+IG5TZmJQcmV2ICkgewogICAgZm9yICggaSA9IDA7IGk8IChuU2ZiIC0gblNmYlByZXYpOyBpKysgKSB7CiAgICAgIGhTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPmd1aWRlVmVjdG9yc1swXS5ndWlkZVZlY3Rvck9yaWdbaV0gPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgIH0KCiAgICBmb3IgKCBpID0gMDsgaSA8IG5TZmJQcmV2OyBpKysgKSB7CiAgICAgIGhTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPmd1aWRlVmVjdG9yc1swXS5ndWlkZVZlY3Rvck9yaWdbaSArIChuU2ZiIC0gblNmYlByZXYpXSA9IHRlbXBHdWlkZVtpXTsKICAgIH0KICB9CiAgZWxzZSB7CiAgICBmb3IgKCBpID0gMDsgaSA8IG5TZmI7IGkrKyApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yT3JpZ1tpXSA9IHRlbXBHdWlkZVtpICsgKG5TZmJQcmV2LW5TZmIpXTsKICAgIH0KICB9CgogIEZES21lbWNweSAoIHRlbXBHdWlkZUludCwgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGV0ZWN0ZWQsIG5TZmJQcmV2ICogc2l6ZW9mKFVDSEFSKSApOwoKICBpZiAoIG5TZmIgPiBuU2ZiUHJldiApIHsKICAgIGZvciAoIGkgPSAwOyBpIDwgKG5TZmIgLSBuU2ZiUHJldik7IGkrKyApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGV0ZWN0ZWRbaV0gPSAwOwogICAgfQoKICAgIGZvciAoIGkgPSAwOyBpIDwgblNmYlByZXY7IGkrKyApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGV0ZWN0ZWRbaSArIChuU2ZiIC0gblNmYlByZXYpXSA9IHRlbXBHdWlkZUludFtpXTsKICAgIH0KICB9CiAgZWxzZSB7CiAgICBmb3IgKCBpID0gMDsgaSA8IG5TZmI7IGkrKyApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+Z3VpZGVWZWN0b3JzWzBdLmd1aWRlVmVjdG9yRGV0ZWN0ZWRbaV0gPSB0ZW1wR3VpZGVJbnRbaSArIChuU2ZiUHJldi1uU2ZiKV07CiAgICB9CiAgfQoKICBGREttZW1jcHkgKCB0ZW1wR3VpZGVJbnQsIGhTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPnByZXZFbnZlbG9wZUNvbXBlbnNhdGlvbiwgblNmYlByZXYgKiBzaXplb2YoVUNIQVIpICk7CgogIGlmICggblNmYiA+IG5TZmJQcmV2ICkgewogICAgZm9yICggaSA9IDA7IGkgPCAoblNmYiAtIG5TZmJQcmV2KTsgaSsrICkgewogICAgICBoU2JyTWlzc2luZ0hhcm1vbmljc0RldGVjdG9yLT5wcmV2RW52ZWxvcGVDb21wZW5zYXRpb25baV0gPSAwOwogICAgfQoKICAgIGZvciAoIGkgPSAwOyBpIDwgblNmYlByZXY7IGkrKyApIHsKICAgICAgaFNick1pc3NpbmdIYXJtb25pY3NEZXRlY3Rvci0+cHJldkVudmVsb3BlQ29tcGVuc2F0aW9uW2kgKyAoblNmYiAtIG5TZmJQcmV2KV0gPSB0ZW1wR3VpZGVJbnRbaV07CiAgICB9CiAgfQogIGVsc2UgewogICAgZm9yICggaSA9IDA7IGkgPCBuU2ZiOyBpKysgKSB7CiAgICAgIGhTYnJNaXNzaW5nSGFybW9uaWNzRGV0ZWN0b3ItPnByZXZFbnZlbG9wZUNvbXBlbnNhdGlvbltpXSA9IHRlbXBHdWlkZUludFtpICsgKG5TZmJQcmV2LW5TZmIpXTsKICAgIH0KICB9CgogIHJldHVybiAwOwp9Cgo=