Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogTVBFRyBBdWRpbyBFbmNvZGVyICoqKioqKioqKioqKioqKioqKioqKioqKioqCgogICBJbml0aWFsIGF1dGhvcjogICAgICAgTS4gTG9od2Fzc2VyCiAgIGNvbnRlbnRzL2Rlc2NyaXB0aW9uOiBwbnMuYwoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgImFhY2VuY19wbnMuaCIKI2luY2x1ZGUgInBzeV9kYXRhLmgiCiNpbmNsdWRlICJwbnNwYXJhbS5oIgojaW5jbHVkZSAibm9pc2VkZXQuaCIKI2luY2x1ZGUgImJpdF9jbnQuaCIKI2luY2x1ZGUgImludGVyZmFjZS5oIgoKCi8qIG1pbkNvcnJlbGF0aW9uRW5lcmd5ID0gKDEuMGUtMTBmKV4yIH4gMl4tNjcgPSAyXi00NyAqIDJeLTIwICovCnN0YXRpYyBjb25zdCBGSVhQX0RCTCBtaW5Db3JyZWxhdGlvbkVuZXJneSA9IEZMMkZYQ09OU1RfREJMKDAuMCk7IC8qIEZMMkZYQ09OU1RfREJMKChmbG9hdClGREtwb3coMi4wLC00NykpOyAqLwovKiBub2lzZUNvcnJlbGF0aW9uVGhyZXNoID0gMC42XjIgKi8Kc3RhdGljIGNvbnN0IEZJWFBfREJMIG5vaXNlQ29ycmVsYXRpb25UaHJlc2ggPSBGTDJGWENPTlNUX0RCTCgwLjM2KTsKCnN0YXRpYyB2b2lkIEZES2FhY0VuY19GREthYWNFbmNfbm9pc2VEZXRlY3Rpb24oIFBOU19DT05GSUcgICpwbnNDb25mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUE5TX0RBVEEgICAgKnBuc0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICBzZmJBY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICAqc2ZiT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgIHRuc09yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgdG5zUHJlZGljdGlvbkdhaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICB0bnNBY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAgICAqbWRjdFNwZWN0cnVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgKnNmYk1heFNjYWxlU3BlYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfU0dMICAgICpzZmJ0b25hbGl0eSApOwoKc3RhdGljIHZvaWQgRkRLYWFjRW5jX0NhbGNOb2lzZU5yZ3MoIGNvbnN0IElOVCAgIHNmYkFjdGl2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgKnBuc0ZsYWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICAgICpzZmJFbmVyZ3lMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICpub2lzZU5yZyApOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgZnVuY3Rpb25uYW1lOiBpbml0UG5zQ29uZmlndXJhdGlvbgogICAgZGVzY3JpcHRpb246ICBmaWxsIHBuc0NvbmYgd2l0aCBwbnMgcGFyYW1ldGVycwogICAgcmV0dXJuczogICAgICBlcnJvciBzdGF0dXMKICAgIGlucHV0OiAgICAgICAgUE5TIENvbmZpZyBzdHJ1Y3QgKG1vZGlmaWVkKQogICAgICAgICAgICAgICAgICBiaXRyYXRlLCBzYW1wbGVyYXRlLCB1c2VQbnMsCiAgICAgICAgICAgICAgICAgIG51bWJlciBvZiBzZmIncywgcG9pbnRlciB0byBzZmIgb2Zmc2V0CiAgICBvdXRwdXQ6ICAgICAgIGVycm9yIGNvZGUKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKQUFDX0VOQ09ERVJfRVJST1IgRkRLYWFjRW5jX0luaXRQbnNDb25maWd1cmF0aW9uKFBOU19DT05GSUcgKnBuc0NvbmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICBiaXRSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgc2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgIHVzZVBucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgIHNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgKnNmYk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgIG51bUNoYW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICBpc0xDKQp7CiAgQUFDX0VOQ09ERVJfRVJST1IgRXJyb3JTdGF0dXM7CgogIC8qIGluaXQgbm9pc2UgZGV0ZWN0aW9uICovCiAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfR2V0UG5zUGFyYW0oJnBuc0NvbmYtPm5wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpdFJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJDbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ1c2VQbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtQ2hhbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0xDKTsKICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0VOQ19PSykKICAgIHJldHVybiBFcnJvclN0YXR1czsKCiAgcG5zQ29uZi0+bWluQ29ycmVsYXRpb25FbmVyZ3kgPSBtaW5Db3JyZWxhdGlvbkVuZXJneTsKICBwbnNDb25mLT5ub2lzZUNvcnJlbGF0aW9uVGhyZXNoID0gbm9pc2VDb3JyZWxhdGlvblRocmVzaDsKCiAgcG5zQ29uZi0+dXNlUG5zID0gdXNlUG5zOwoKICByZXR1cm4gQUFDX0VOQ19PSzsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19QbnNEZXRlY3QKICAgIGRlc2NyaXB0aW9uOiAgZG8gZGVjaXNpb24sIGlmIFBOUyBzaGFsbCB1c2VkIG9yIG5vdAogICAgcmV0dXJuczoKICAgIGlucHV0OiAgICAgICAgcG5zIGNvbmZpZyBzdHJ1Y3R1cmUKICAgICAgICAgICAgICAgICAgcG5zIGRhdGEgc3RydWN0dXJlIChtb2RpZmllZCksCiAgICAgICAgICAgICAgICAgIGxhc3RXaW5kb3dTZXF1ZW5jZSAobG9uZyBvciBzaG9ydCBibG9ja3MpCiAgICAgICAgICAgICAgICAgIHNmYkFjdGl2ZQogICAgICAgICAgICAgICAgICBwb2ludGVyIHRvIFNmYiBFbmVyZ3ksIFRocmVzaG9sZCwgT2Zmc2V0CiAgICAgICAgICAgICAgICAgIHBvaW50ZXIgdG8gbWRjdCBTcGVjdHJ1bQogICAgICAgICAgICAgICAgICBsZW5ndGggb2YgZWFjaCBncm91cAogICAgICAgICAgICAgICAgICBwb2ludGVyIHRvIHRvbmFsaXR5IGNhbGN1bGF0ZWQgaW4gY2hhb3NtZWFzdXJlCiAgICAgICAgICAgICAgICAgIHRucyBvcmRlciBhbmQgcHJlZGljdGlvbiBnYWluCiAgICAgICAgICAgICAgICAgIGNhbGN1bGF0ZWQgbm9pc2VOcmcgYXQgYWN0aXZlIFBOUwogICAgb3V0cHV0OiAgICAgICBwbnNGbGFnIGluIHBucyBkYXRhIHN0cnVjdHVyZQoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnZvaWQgRkRLYWFjRW5jX1Buc0RldGVjdChQTlNfQ09ORklHICAqcG5zQ29uZiwKICAgICAgICAgICAgICAgICAgICAgICAgIFBOU19EQVRBICAgICpwbnNEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICAgIGxhc3RXaW5kb3dTZXF1ZW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICBzZmJBY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICAgbWF4U2ZiUGVyR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAgICAqc2ZiVGhyZXNob2xkTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICAgKnNmYk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICAgICptZGN0U3BlY3RydW0sCiAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAqc2ZiTWF4U2NhbGVTcGVjLAogICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9TR0wgICAgKnNmYnRvbmFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgIHRuc09yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgIHRuc1ByZWRpY3Rpb25HYWluLAogICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgIHRuc0FjdGl2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICAgICpzZmJFbmVyZ3lMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAqbm9pc2VOcmcgKQoKewogIGludCBzZmI7CiAgaW50IHN0YXJ0Tm9pc2VTZmI7CgogIGlmIChwbnNDb25mLT5ucC5kZXRlY3Rpb25BbGdvcml0aG1GbGFncyAmIElTX0xPV19DT01MRVhJVFkpIHsKICAgIGlmICggKCFwbnNDb25mLT51c2VQbnMpIHx8ICAgICAgICAgICAgICAvKiBwbnMgZW5hYmxlZD8gKi8KICAgICAgICAgICAobGFzdFdpbmRvd1NlcXVlbmNlID09IFNIT1JUX1dJTkRPVykgKSAvKiBjdXJyZW50bHkgb25seSBsb25nIGJsb2NrcyAqLwogICAgewogICAgICBGREttZW1jbGVhcihwbnNEYXRhLT5wbnNGbGFnLCBNQVhfR1JPVVBFRF9TRkIqc2l6ZW9mKElOVCkpOyAvKiBjbGVhciBhbGwgcG5zRmxhZ3MgKi8KICAgICAgZm9yIChzZmI9MDsgc2ZiPE1BWF9HUk9VUEVEX1NGQjsgc2ZiKyspIHsKICAgICAgICAgIG5vaXNlTnJnW3NmYl0gPSBOT19OT0lTRV9QTlM7ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY2xlYXIgbnJnJ3Mgb2YgcHJldmlvdXMgZnJhbWUgKi8KICAgICAgfQogICAgICByZXR1cm47CiAgICB9CiAgfQogIGVsc2UgewogICAgaWYoIXBuc0NvbmYtPnVzZVBucykKICAgICAgcmV0dXJuOwoKICAgIC8qIFBOUyBvbmx5IGZvciBsb25nIFdpbmRvd3MgKi8KICAgIGlmIChwbnNDb25mLT5ucC5kZXRlY3Rpb25BbGdvcml0aG1GbGFncyAmIEpVU1RfTE9OR19XSU5ET1cpIHsKICAgICAgaWYobGFzdFdpbmRvd1NlcXVlbmNlICE9IExPTkdfV0lORE9XKSB7CiAgICAgICAgZm9yIChzZmIgPSAwOyBzZmIgPCBzZmJBY3RpdmU7IHNmYisrKSB7CiAgICAgICAgICBwbnNEYXRhLT5wbnNGbGFnW3NmYl0gPSAwOyAgICAvKiBjbGVhciBhbGwgcG5zRmxhZ3MgKi8KICAgICAgICB9CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICB9CiAgfQogIC8qCiAgICBjYWxsIG5vaXNlIGRldGVjdGlvbgogICovCiAgRkRLYWFjRW5jX0ZES2FhY0VuY19ub2lzZURldGVjdGlvbiggcG5zQ29uZiwKICAgICAgICAgICAgICAgICAgcG5zRGF0YSwKICAgICAgICAgICAgICAgICAgc2ZiQWN0aXZlLAogICAgICAgICAgICAgICAgICBzZmJPZmZzZXQsCiAgICAgICAgICAgICAgICAgIHRuc09yZGVyLAogICAgICAgICAgICAgICAgICB0bnNQcmVkaWN0aW9uR2FpbiwKICAgICAgICAgICAgICAgICAgdG5zQWN0aXZlLAogICAgICAgICAgICAgICAgICBtZGN0U3BlY3RydW0sCiAgICAgICAgICAgICAgICAgIHNmYk1heFNjYWxlU3BlYywKICAgICAgICAgICAgICAgICAgc2ZidG9uYWxpdHkgKTsKCiAgLyogc2V0IHN0YXJ0Tm9pc2VTZmIgKGxvbmcpICovCiAgc3RhcnROb2lzZVNmYiA9IHBuc0NvbmYtPm5wLnN0YXJ0U2ZiOwoKICAvKiBTZXQgbm9pc2Ugc3Vic3RpdHV0aW9uIHN0YXR1cyAqLwogIGZvcihzZmIgPSAwOyBzZmIgPCBzZmJBY3RpdmU7IHNmYisrKSB7CgogICAgLyogTm8gUE5TIGJlbG93IHN0YXJ0Tm9pc2VTZmIgKi8KICAgIGlmKHNmYiA8IHN0YXJ0Tm9pc2VTZmIpewogICAgICBwbnNEYXRhLT5wbnNGbGFnW3NmYl0gPSAwOwogICAgICBjb250aW51ZTsKICAgIH0KCiAgICAvKgogICAgICBkbyBub2lzZSBzdWJzdGl0dXRpb24gaWYKICAgICAgZnV6enkgbWVhc3VyZSBpcyBoaWdoIGVub3VnaAogICAgICBzZmIgZnJlcSA+IG1pbmltdW0gc2ZiIGZyZXEKICAgICAgc2lnbmFsIGluIGNvZGVyIGJhbmQgaXMgbm90IG1hc2tlZAogICAgKi8KCiAgICBpZigocG5zRGF0YS0+bm9pc2VGdXp6eU1lYXN1cmVbc2ZiXSA+IEZMMkZYQ09OU1RfU0dMKDAuNSkpICYmCiAgICAgICAoIChzZmJUaHJlc2hvbGRMZERhdGFbc2ZiXSArIEZMMkZYQ09OU1RfREJMKDAuNTg0OTYyNWYvNjQuMGYpKSAgLyogdGhyICogMS41ID0gdGhyTGQgK2xkKDEuNSkvNjQgKi8KICAgICAgICAgPCBzZmJFbmVyZ3lMZERhdGFbc2ZiXSApICkKICAgIHsKICAgICAgLyoKICAgICAgICBtYXJrIGluIHBzeW91dCBmbGFnIGFycmF5IHRoYXQgd2Ugd2lsbCBjb2RlCiAgICAgICAgdGhpcyBiYW5kIHdpdGggUE5TCiAgICAgICovCiAgICAgIHBuc0RhdGEtPnBuc0ZsYWdbc2ZiXSA9IDE7IC8qIFBOU19PTiAqLwogICAgfQogICAgZWxzZXsKICAgICAgcG5zRGF0YS0+cG5zRmxhZ1tzZmJdID0gMDsgLyogUE5TX09GRiAqLwogICAgfQoKICAgIC8qIG5vIFBOUyBpZiBMVFAgaXMgYWN0aXZlICovCiAgfQoKICAvKiBhdm9pZCBQTlMgaG9sZXMgKi8KICBpZigocG5zRGF0YS0+bm9pc2VGdXp6eU1lYXN1cmVbMF0+RkwyRlhDT05TVF9TR0woMC41ZikpICYmIChwbnNEYXRhLT5wbnNGbGFnWzFdKSkgewogICAgcG5zRGF0YS0+cG5zRmxhZ1swXSA9IDE7CiAgfQoKICBmb3Ioc2ZiPTE7IHNmYjxtYXhTZmJQZXJHcm91cC0xOyBzZmIrKykgewogICAgaWYoKHBuc0RhdGEtPm5vaXNlRnV6enlNZWFzdXJlW3NmYl0+cG5zQ29uZi0+bnAuZ2FwRmlsbFRocikgJiYKICAgICAgIChwbnNEYXRhLT5wbnNGbGFnW3NmYi0xXSkgJiYgKHBuc0RhdGEtPnBuc0ZsYWdbc2ZiKzFdKSkgewogICAgICBwbnNEYXRhLT5wbnNGbGFnW3NmYl0gPSAxOwogICAgfQogIH0KCiAgaWYobWF4U2ZiUGVyR3JvdXA+MCkgewogICAgLyogYXZvaWQgUE5TIGhvbGUgKi8KICAgIGlmKChwbnNEYXRhLT5ub2lzZUZ1enp5TWVhc3VyZVttYXhTZmJQZXJHcm91cC0xXT5wbnNDb25mLT5ucC5nYXBGaWxsVGhyKSAmJiAocG5zRGF0YS0+cG5zRmxhZ1ttYXhTZmJQZXJHcm91cC0yXSkpIHsKICAgICAgcG5zRGF0YS0+cG5zRmxhZ1ttYXhTZmJQZXJHcm91cC0xXSA9IDE7CiAgICB9CiAgICAvKiBhdm9pZCBzaW5nbGUgUE5TIGJhbmQgKi8KICAgIGlmKHBuc0RhdGEtPnBuc0ZsYWdbbWF4U2ZiUGVyR3JvdXAtMl09PTApIHsKICAgICAgcG5zRGF0YS0+cG5zRmxhZ1ttYXhTZmJQZXJHcm91cC0xXSA9IDA7CiAgICB9CiAgfQoKICAvKiBhdm9pZCBzaW5nbGUgUE5TIGJhbmRzICovCiAgaWYocG5zRGF0YS0+cG5zRmxhZ1sxXT09MCkgewogICAgcG5zRGF0YS0+cG5zRmxhZ1swXSA9IDA7CiAgfQoKICBmb3Ioc2ZiPTE7IHNmYjxtYXhTZmJQZXJHcm91cC0xOyBzZmIrKykgewogICAgaWYoKHBuc0RhdGEtPnBuc0ZsYWdbc2ZiLTFdPT0wKSYmKHBuc0RhdGEtPnBuc0ZsYWdbc2ZiKzFdPT0wKSkgewogICAgICBwbnNEYXRhLT5wbnNGbGFnW3NmYl0gPSAwOwogICAgfQogIH0KCgogIC8qCiAgICBjYWxjdWxhdGUgbm9pc2VOcmcncwogICovCiAgRkRLYWFjRW5jX0NhbGNOb2lzZU5yZ3MoIHNmYkFjdGl2ZSwKICAgICAgICAgICAgICAgICBwbnNEYXRhLT5wbnNGbGFnLAogICAgICAgICAgICAgICAgIHNmYkVuZXJneUxkRGF0YSwKICAgICAgICAgICAgICAgICBub2lzZU5yZyApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgZnVuY3Rpb25uYW1lOkZES2FhY0VuY19GREthYWNFbmNfbm9pc2VEZXRlY3Rpb24KICAgIGRlc2NyaXB0aW9uOiB3cmFwcGVyIGZvciBub2lzZWRldC5jCiAgICByZXR1cm5zOgogICAgaW5wdXQ6ICAgICAgIHBucyBjb25maWcgc3RydWN0dXJlCiAgICAgICAgICAgICAgICAgcG5zIGRhdGEgc3RydWN0dXJlIChtb2RpZmllZCksCiAgICAgICAgICAgICAgICAgc2ZiQWN0aXZlCiAgICAgICAgICAgICAgICAgdG5zIG9yZGVyIGFuZCBwcmVkaWN0aW9uIGdhaW4KICAgICAgICAgICAgICAgICBwb2ludGVyIHRvIG1kY3QgU3BlY3RydW1hbmQgU2ZiIEVuZXJneQogICAgICAgICAgICAgICAgIHBvaW50ZXIgdG8gU2ZiIHRvbmFsaXR5CiAgICBvdXRwdXQ6ICAgICAgbm9pc2VGdXp6eU1lYXN1cmUgaW4gc3RydWN0dXJlIHBuc0RhdGEKICAgICAgICAgICAgICAgICBmbGFncyB0b25hbCAvIG5vbnRvbmFsCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgRkRLYWFjRW5jX0ZES2FhY0VuY19ub2lzZURldGVjdGlvbiggUE5TX0NPTkZJRyAgKnBuc0NvbmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTlNfREFUQSAgICAqcG5zRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgIHNmYkFjdGl2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICpzZmJPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgICAgICAgICAgdG5zT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICB0bnNQcmVkaWN0aW9uR2FpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgIHRuc0FjdGl2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICAgICptZGN0U3BlY3RydW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAqc2ZiTWF4U2NhbGVTcGVjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9TR0wgICAgKnNmYnRvbmFsaXR5ICkKewogICAgSU5UIGNvbmRpdGlvbiA9IFRSVUU7CiAgICBpZiAoICEocG5zQ29uZi0+bnAuZGV0ZWN0aW9uQWxnb3JpdGhtRmxhZ3MgJiBJU19MT1dfQ09NTEVYSVRZKSApIHsKICAgICAgY29uZGl0aW9uID0gKHRuc09yZGVyID4gMyk7CiAgICB9CiAgICAvKgogICAgbm8gUE5TIGlmIGhlYXZ5IFROUyBhY3Rpdml0eQogICAgY2xlYXIgcG5zRGF0YS0+bm9pc2VGdXp6eU1lYXN1cmUKICAgICovCiAgICBpZigocG5zQ29uZi0+bnAuZGV0ZWN0aW9uQWxnb3JpdGhtRmxhZ3MgJiBVU0VfVE5TX0dBSU5fVEhSKSAmJgogICAgICAodG5zUHJlZGljdGlvbkdhaW4gPj0gcG5zQ29uZi0+bnAudG5zR2FpblRocmVzaG9sZCkgJiYgY29uZGl0aW9uICYmCiAgICAgICEoKHBuc0NvbmYtPm5wLmRldGVjdGlvbkFsZ29yaXRobUZsYWdzICYgVVNFX1ROU19QTlMpICYmICh0bnNQcmVkaWN0aW9uR2FpbiA+PSBwbnNDb25mLT5ucC50bnNQTlNHYWluVGhyZXNob2xkKSAmJiAodG5zQWN0aXZlKSkgKQogICAgewogICAgICAgIC8qIGNsZWFyIGFsbCBub2lzZUZ1enp5TWVhc3VyZSAqLwogICAgICAgIEZES21lbWNsZWFyKHBuc0RhdGEtPm5vaXNlRnV6enlNZWFzdXJlLCBzZmJBY3RpdmUqc2l6ZW9mKEZJWFBfU0dMKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyoKICAgICAgICBjYWxsIG5vaXNlIGRldGVjdGlvbiwgb3V0cHV0IGluIHBuc0RhdGEtPm5vaXNlRnV6enlNZWFzdXJlLAogICAgICAgIHVzZSByZWFsIG1kY3Qgc3BlY3RyYWwgZGF0YQogICAgICAgICovCiAgICAgICAgRkRLYWFjRW5jX25vaXNlRGV0ZWN0KCBtZGN0U3BlY3RydW0sCiAgICAgICAgICAgIHNmYk1heFNjYWxlU3BlYywKICAgICAgICAgICAgc2ZiQWN0aXZlLAogICAgICAgICAgICBzZmJPZmZzZXQsCiAgICAgICAgICAgIHBuc0RhdGEtPm5vaXNlRnV6enlNZWFzdXJlLAogICAgICAgICAgICAmcG5zQ29uZi0+bnAsCiAgICAgICAgICAgIHNmYnRvbmFsaXR5KTsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTpGREthYWNFbmNfQ2FsY05vaXNlTnJncwogICAgZGVzY3JpcHRpb246IENhbGN1bGF0ZSB0aGUgTm9pc2VOcmcncwogICAgcmV0dXJuczoKICAgIGlucHV0OiAgICAgICBzZmJBY3RpdmUKICAgICAgICAgICAgICAgICBpZiBwbnNGbGFnIGNhbGN1bGF0ZSBOb2lzZU5yZwogICAgICAgICAgICAgICAgIHBvaW50ZXIgdG8gc2ZiRW5lcmd5IGFuZCBncm91cExlbgogICAgICAgICAgICAgICAgIHBvaW50ZXIgdG8gbm9pc2VOcmcgKG1vZGlmaWVkKQogICAgb3V0cHV0OiAgICAgIG5vaXNlTnJnJ3MgaW4gcG5zRmxhZ2VkIHNmYidzCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkIEZES2FhY0VuY19DYWxjTm9pc2VOcmdzKCBjb25zdCBJTlQgICAgc2ZiQWN0aXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAqUkVTVFJJQ1QgcG5zRmxhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgICAgKlJFU1RSSUNUIHNmYkVuZXJneUxkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgKlJFU1RSSUNUIG5vaXNlTnJnICkKewogIGludCBzZmI7CiAgSU5UIHRtcCA9ICgtTE9HX05PUk1fUENNKTw8MjsKCiAgZm9yKHNmYiA9IDA7IHNmYiA8IHNmYkFjdGl2ZTsgc2ZiKyspIHsKICAgIGlmKHBuc0ZsYWdbc2ZiXSkgewogICAgICBJTlQgbnJnID0gKC1zZmJFbmVyZ3lMZERhdGFbc2ZiXStGTDJGWENPTlNUX0RCTCgwLjVmLzY0LjBmKSk+PihERlJBQ1RfQklUUy0xLTcpOwogICAgICBub2lzZU5yZ1tzZmJdID0gdG1wIC0gbnJnOwogICAgfQogIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTpGREthYWNFbmNfQ29kZVBuc0NoYW5uZWwKICAgIGRlc2NyaXB0aW9uOiBFeGVjdXRlIHBucyBkZWNpc3Npb24KICAgIHJldHVybnM6CiAgICBpbnB1dDogICAgICAgc2ZiQWN0aXZlCiAgICAgICAgICAgICAgICAgcG5zIGNvbmZpZyBzdHJ1Y3R1cmUKICAgICAgICAgICAgICAgICB1c2UgUE5TIGlmIHBuc0ZsYWcKICAgICAgICAgICAgICAgICBwb2ludGVyIHRvIFNmYiBFbmVyZ3ksIG5vaXNlTnJnLCBUaHJlc2hvbGQKICAgIG91dHB1dDogICAgICBzZXQgc2ZiVGhyZXNob2xkIGhpZ2ggdG8gY29kZSBwZSB3aXRoIDAsCiAgICAgICAgICAgICAgICAgbm9pc2VOcmcgbWFya3MgZmxhZyBmb3IgcG5zIGNvZGluZwoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgp2b2lkIEZES2FhY0VuY19Db2RlUG5zQ2hhbm5lbChjb25zdCBJTlQgICAgIHNmYkFjdGl2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE5TX0NPTkZJRyAgICAqcG5zQ29uZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAqUkVTVFJJQ1QgcG5zRmxhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgICAgICAqUkVTVFJJQ1Qgc2ZiRW5lcmd5TGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAgICpSRVNUUklDVCBub2lzZU5yZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgICAgICAqUkVTVFJJQ1Qgc2ZiVGhyZXNob2xkTGREYXRhKQp7CiAgSU5UIHNmYjsKICBJTlQgbGFzdGlOb2lzZUVuZXJneSA9IDA7CiAgSU5UIGZpcnN0UE5TYmFuZCA9IDE7IC8qIFRSVUUgZm9yIGZpcnN0IFBOUy1jb2RlZCBiYW5kICovCgogIC8qIG5vIFBOUyAqLwogIGlmKCFwbnNDb25mLT51c2VQbnMpIHsKICAgIGZvcihzZmIgPSAwOyBzZmIgPCBzZmJBY3RpdmU7IHNmYisrKSB7CiAgICAgIC8qIG5vIFBOUyBjb2RpbmcgKi8KICAgICAgbm9pc2VOcmdbc2ZiXSA9IE5PX05PSVNFX1BOUzsKICAgIH0KICAgIHJldHVybjsKICB9CgogIC8qIGNvZGUgUE5TICovCiAgZm9yKHNmYiA9IDA7IHNmYiA8IHNmYkFjdGl2ZTsgc2ZiKyspIHsKICAgIGlmKHBuc0ZsYWdbc2ZiXSkgewogICAgICAvKiBoaWdoIHNmYlRocmVzaG9sZCBjYXVzZXMgcGUgPSAwICovCiAgICAgIGlmKG5vaXNlTnJnW3NmYl0gIT0gTk9fTk9JU0VfUE5TKQogICAgICAgIHNmYlRocmVzaG9sZExkRGF0YVtzZmJdID0gc2ZiRW5lcmd5TGREYXRhW3NmYl0gKyBGTDJGWENPTlNUX0RCTCgxLjBmL0xEX0RBVEFfU0NBTElORyk7CgogICAgICAvKiBzZXQgbm9pc2VOcmcgaW4gdmFsaWQgcmVnaW9uICovCiAgICAgIGlmKCFmaXJzdFBOU2JhbmQpIHsKICAgICAgICBJTlQgZGVsdGFpTm9pc2VFbmVyZ3kgPSBub2lzZU5yZ1tzZmJdIC0gbGFzdGlOb2lzZUVuZXJneTsKCiAgICAgICAgaWYoZGVsdGFpTm9pc2VFbmVyZ3kgPiBDT0RFX0JPT0tfUE5TX0xBVikKICAgICAgICAgICAgbm9pc2VOcmdbc2ZiXSAtPSBkZWx0YWlOb2lzZUVuZXJneSAtIENPREVfQk9PS19QTlNfTEFWOwogICAgICAgIGVsc2UgaWYoZGVsdGFpTm9pc2VFbmVyZ3kgPCAtQ09ERV9CT09LX1BOU19MQVYpCiAgICAgICAgICAgIG5vaXNlTnJnW3NmYl0gLT0gZGVsdGFpTm9pc2VFbmVyZ3kgKyBDT0RFX0JPT0tfUE5TX0xBVjsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBmaXJzdFBOU2JhbmQgPSAwOwogICAgICB9CiAgICAgIGxhc3RpTm9pc2VFbmVyZ3kgPSBub2lzZU5yZ1tzZmJdOwogICAgfQogICAgZWxzZSB7CiAgICAgIC8qIG5vIFBOUyBjb2RpbmcgKi8KICAgICAgbm9pc2VOcmdbc2ZiXSA9IE5PX05PSVNFX1BOUzsKICAgIH0KICB9Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICBmdW5jdGlvbm5hbWU6RkRLYWFjRW5jX1ByZVByb2Nlc3NQbnNDaGFubmVsUGFpcgogICAgZGVzY3JpcHRpb246IENhbGN1bGF0ZSB0aGUgY29ycmVsYXRpb24gb2Ygbm9pc2UgaW4gYSBjaGFubmVsIHBhaXIKCiAgICByZXR1cm5zOgogICAgaW5wdXQ6ICAgICAgIHNmYkFjdGl2ZQogICAgICAgICAgICAgICAgIHBvaW50ZXIgdG8gc2ZiIGVuZXJnaWVzIGxlZnQsIHJpZ2h0IGFuZCBtaWQgY2hhbm5lbAogICAgICAgICAgICAgICAgIHBucyBjb25maWcgc3RydWN0dXJlCiAgICAgICAgICAgICAgICAgcG5zIGRhdGEgc3RydWN0dXJlIGxlZnQgYW5kIHJpZ2h0IChtb2RpZmllZCkKCiAgICBvdXRwdXQ6ICAgICAgbm9pc2VFbmVyZ3lDb3JyZWxhdGlvbiBpbiBwbnMgZGF0YSBzdHJ1Y3R1cmUKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdm9pZCBGREthYWNFbmNfUHJlUHJvY2Vzc1Buc0NoYW5uZWxQYWlyKGNvbnN0IElOVCAgIHNmYkFjdGl2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICAgKlJFU1RSSUNUIHNmYkVuZXJneUxlZnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAgICpSRVNUUklDVCBzZmJFbmVyZ3lSaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICAgKlJFU1RSSUNUIHNmYkVuZXJneUxlZnRMRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICAgKlJFU1RSSUNUIHNmYkVuZXJneVJpZ2h0TEQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAgICpSRVNUUklDVCBzZmJFbmVyZ3lNaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTlNfQ09ORklHICpSRVNUUklDVCBwbnNDb25mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE5TX0RBVEEgICAqcG5zRGF0YUxlZnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTlNfREFUQSAgICpwbnNEYXRhUmlnaHQpCnsKICBJTlQgc2ZiOwogIEZJWFBfREJMIGNjZjsKCiAgaWYoIXBuc0NvbmYtPnVzZVBucykKICAgIHJldHVybjsKCiAgRklYUF9EQkwgKlJFU1RSSUNUIHBOb2lzZUVuZXJneUNvcnJlbGF0aW9uTCA9IHBuc0RhdGFMZWZ0LT5ub2lzZUVuZXJneUNvcnJlbGF0aW9uOwogIEZJWFBfREJMICpSRVNUUklDVCBwTm9pc2VFbmVyZ3lDb3JyZWxhdGlvblIgPSBwbnNEYXRhUmlnaHQtPm5vaXNlRW5lcmd5Q29ycmVsYXRpb247CgogIGZvcihzZmI9MDtzZmI8IHNmYkFjdGl2ZTtzZmIrKykgewogICAgRklYUF9EQkwgcXVvdCA9IChzZmJFbmVyZ3lMZWZ0TERbc2ZiXT4+MSkgKyAoc2ZiRW5lcmd5UmlnaHRMRFtzZmJdPj4xKTsKCiAgICBpZihxdW90IDwgRkwyRlhDT05TVF9EQkwoLTMyLjBmLyhmbG9hdClMRF9EQVRBX1NDQUxJTkcpKQogICAgICBjY2YgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgIGVsc2UgewogICAgICBGSVhQX0RCTCBhY2N1ID0gc2ZiRW5lcmd5TWlkW3NmYl0tICgoKHNmYkVuZXJneUxlZnRbc2ZiXT4+MSkrKHNmYkVuZXJneVJpZ2h0W3NmYl0+PjEpKT4+MSk7CiAgICAgIElOVCBzaWduID0gKGFjY3UgPCBGTDJGWENPTlNUX0RCTCgwLjBmKSkgPyAxIDogMCA7CiAgICAgIGFjY3UgPSBmaXhwX2FicyhhY2N1KTsKCiAgICAgIGNjZiA9IENhbGNMZERhdGEoYWNjdSkgKyBGTDJGWENPTlNUX0RCTCgoZmxvYXQpMS4wZi8oZmxvYXQpTERfREFUQV9TQ0FMSU5HKSAtIHF1b3Q7ICAgLyogbGQoYWNjdSoyKSA9IGxkKGFjY3UpICsgMSAqLwogICAgICBjY2YgPSAoY2NmPj1GTDJGWENPTlNUX0RCTCgwLjApKSA/ICgoRklYUF9EQkwpTUFYVkFMX0RCTCkgOiAoc2lnbikgPyAtQ2FsY0ludkxkRGF0YShjY2YpIDogQ2FsY0ludkxkRGF0YShjY2YpOwogICAgfQoKICAgIHBOb2lzZUVuZXJneUNvcnJlbGF0aW9uTFtzZmJdID0gY2NmOwogICAgcE5vaXNlRW5lcmd5Q29ycmVsYXRpb25SW3NmYl0gPSBjY2Y7CiAgfQp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTpGREthYWNFbmNfUG9zdFByb2Nlc3NQbnNDaGFubmVsUGFpcgogICAgZGVzY3JpcHRpb246IGlmIFBOUyB1c2VkIGF0IGxlZnQgYW5kIHJpZ2h0IGNoYW5uZWwsCiAgICAgICAgICAgICAgICAgdXNlIG1zTWFzayB0byBmbGFnIGNvcnJlbGF0aW9uCiAgICByZXR1cm5zOgogICAgaW5wdXQ6ICAgICAgIHNmYkFjdGl2ZQogICAgICAgICAgICAgICAgIHBucyBjb25maWcgc3RydWN0dXJlCiAgICAgICAgICAgICAgICAgcG5zIGRhdGEgc3RydWN0dXJlIGxlZnQgYW5kIHJpZ2h0IChtb2RpZmllZCkKICAgICAgICAgICAgICAgICBwb2ludGVyIHRvIG1zTWFzaywgZmxhZ3MgY29ycmVsYXRpb24gYnkgcG5zIGNvZGluZyAobW9kaWZpZWQpCiAgICAgICAgICAgICAgICAgRGlnZXN0IG9mIE1TIGNvZGluZwogICAgb3V0cHV0OiAgICAgIHBuc0ZsYWcgaW4gcG5zIGRhdGEgc3RydWN0dXJlLAogICAgICAgICAgICAgICAgIG1zRmxhZyBpbiBtc01hc2sgKGZsYWdzIGNvcnJlbGF0aW9uKQoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgp2b2lkIEZES2FhY0VuY19Qb3N0UHJvY2Vzc1Buc0NoYW5uZWxQYWlyKGNvbnN0IElOVCAgIHNmYkFjdGl2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTlNfQ09ORklHICAqcG5zQ29uZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTlNfREFUQSAgICAqcG5zRGF0YUxlZnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE5TX0RBVEEgICAgKnBuc0RhdGFSaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgICAgICAgICAqUkVTVFJJQ1QgbXNNYXNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICptc0RpZ2VzdCApCnsKICBJTlQgc2ZiOwoKICBpZighcG5zQ29uZi0+dXNlUG5zKQogICAgcmV0dXJuOwoKICBmb3Ioc2ZiPTA7c2ZiPHNmYkFjdGl2ZTtzZmIrKykgewogICAgLyoKICAgICAgTVMgcG9zdCBwcm9jZXNzaW5nCiAgICAqLwogICAgaWYoIG1zTWFza1tzZmJdICkgewogICAgICBpZiggKHBuc0RhdGFMZWZ0LT5wbnNGbGFnW3NmYl0pICYmCiAgICAgICAgICAocG5zRGF0YVJpZ2h0LT5wbnNGbGFnW3NmYl0pICkgewogICAgICAgIC8qIEFBQyBvbmx5OiBTdGFuZGFyZCAqLwogICAgICAgIC8qIGRvIHRoaXMgdG8gYXZvaWQgbXMgZmxhZ3MgaW4gbGF5ZXJzIHRoYXQgc2hvdWxkIG5vdCBoYXZlIGl0ICovCiAgICAgICAgaWYocG5zRGF0YUxlZnQtPm5vaXNlRW5lcmd5Q29ycmVsYXRpb25bc2ZiXSA8PSBwbnNDb25mLT5ub2lzZUNvcnJlbGF0aW9uVGhyZXNoKXsKICAgICAgICAgIG1zTWFza1tzZmJdID0gMDsKICAgICAgICAgICptc0RpZ2VzdCA9IE1TX1NPTUU7CiAgICAgICAgfQogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICBObyBQTlMgY29kaW5nCiAgICAgICAgKi8KICAgICAgICBwbnNEYXRhTGVmdC0+cG5zRmxhZ1tzZmJdID0gMDsKICAgICAgICBwbnNEYXRhUmlnaHQtPnBuc0ZsYWdbc2ZiXSA9IDA7CiAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICBVc2UgTVMgZmxhZyB0byBzaWduYWwgbm9pc2UgY29ycmVsYXRpb24gaWYKICAgICAgcG5zIGlzIGFjdGl2ZSBpbiBib3RoIGNoYW5uZWxzCiAgICAqLwogICAgaWYoIChwbnNEYXRhTGVmdC0+cG5zRmxhZ1tzZmJdKSAmJiAocG5zRGF0YVJpZ2h0LT5wbnNGbGFnW3NmYl0pICkgewogICAgICBpZihwbnNEYXRhTGVmdC0+bm9pc2VFbmVyZ3lDb3JyZWxhdGlvbltzZmJdID4gcG5zQ29uZi0+bm9pc2VDb3JyZWxhdGlvblRocmVzaCkgewogICAgICAgIG1zTWFza1tzZmJdID0gMTsKICAgICAgICAqbXNEaWdlc3QgPSBNU19TT01FOwogICAgICB9CiAgICB9CiAgfQp9Cg==