Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEyIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBNYW51ZWwgSmFuZGVyCiAgIERlc2NyaXB0aW9uOgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgImFhY2RlY29kZXJfbGliLmgiCgojaW5jbHVkZSAiYWFjX3JhbS5oIgojaW5jbHVkZSAiYWFjZGVjb2Rlci5oIgojaW5jbHVkZSAidHBkZWNfbGliLmgiCiNpbmNsdWRlICJGREtfY29yZS5oIiAvKiBGREtfdG9vbHMgdmVyc2lvbiBpbmZvICovCgoKICNpbmNsdWRlICJzYnJkZWNvZGVyLmgiCgoKCgojaW5jbHVkZSAiY29uY2VhbC5oIgoKICNpbmNsdWRlICJhYWNkZWNfZHJjLmgiCgoKCi8qIERlY29kZXIgbGlicmFyeSBpbmZvICovCiNkZWZpbmUgQUFDREVDT0RFUl9MSUJfVkwwIDIKI2RlZmluZSBBQUNERUNPREVSX0xJQl9WTDEgNAojZGVmaW5lIEFBQ0RFQ09ERVJfTElCX1ZMMiA1CiNkZWZpbmUgQUFDREVDT0RFUl9MSUJfVElUTEUgIkFBQyBEZWNvZGVyIExpYiIKI2RlZmluZSBBQUNERUNPREVSX0xJQl9CVUlMRF9EQVRFIF9fREFURV9fCiNkZWZpbmUgQUFDREVDT0RFUl9MSUJfQlVJTERfVElNRSBfX1RJTUVfXwoKc3RhdGljIEFBQ19ERUNPREVSX0VSUk9SCnNldENvbmNlYWxNZXRob2QgKCBjb25zdCBIQU5ETEVfQUFDREVDT0RFUiAgc2VsZiwKICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICBtZXRob2QgKTsKCgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IgYWFjRGVjb2Rlcl9HZXRGcmVlQnl0ZXMgKCBjb25zdCBIQU5ETEVfQUFDREVDT0RFUiAgc2VsZiwgVUlOVCAqcEZyZWVCeXRlcyl7CgogIC8qIHJlc2V0IGZyZWUgYnl0ZXMgKi8KICAqcEZyZWVCeXRlcyA9IDA7CgogIC8qIGNoZWNrIGhhbmRsZSAqLwogIGlmKCFzZWxmKQogICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CgogIC8qIHJldHVybiBuciBvZiBmcmVlIGJ5dGVzICovCiAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzID0gdHJhbnNwb3J0RGVjX0dldEJpdHN0cmVhbShzZWxmLT5oSW5wdXQsIDApOwogICpwRnJlZUJ5dGVzID0gRkRLZ2V0RnJlZUJpdHMoaEJzKSA+PiAzOwoKICAvKiBzdWNjZXNzICovCiAgcmV0dXJuIEFBQ19ERUNfT0s7Cn0KCi8qKgogKiBDb25maWcgRGVjb2RlciB1c2luZyBhIENTQXVkaW9TcGVjaWZpY0NvbmZpZyBzdHJ1Y3QuCiAqLwpzdGF0aWMKTElOS1NQRUNfQ1BQIEFBQ19ERUNPREVSX0VSUk9SIGFhY0RlY29kZXJfQ29uZmlnKEhBTkRMRV9BQUNERUNPREVSIHNlbGYsIGNvbnN0IENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqcEFzY1N0cnVjdCkKewogIEFBQ19ERUNPREVSX0VSUk9SIGVycjsKCiAgLyogSW5pdGlhbGl6ZSBBQUMgY29yZSBkZWNvZGVyLCBhbmQgdXBkYXRlIHNlbGYtPnN0cmVhbWluZm8gKi8KICBlcnIgPSBDQWFjRGVjb2Rlcl9Jbml0KHNlbGYsIHBBc2NTdHJ1Y3QpOwoKICByZXR1cm4gZXJyOwp9CgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IgYWFjRGVjb2Rlcl9Db25maWdSYXcgKAogICAgICAgIEhBTkRMRV9BQUNERUNPREVSIHNlbGYsCiAgICAgICAgVUNIQVIgKmNvbmZbXSwKICAgICAgICBjb25zdCBVSU5UIGxlbmd0aFtdICkKewogIEFBQ19ERUNPREVSX0VSUk9SIGVyciA9IEFBQ19ERUNfT0s7CiAgVFJBTlNQT1JUREVDX0VSUk9SICAgZXJyVHA7CiAgVUlOVCBsYXllciwgbnJPZkxheWVycyA9IHNlbGYtPm5yT2ZMYXllcnM7CgogIGZvcihsYXllciA9IDA7IGxheWVyIDwgbnJPZkxheWVyczsgbGF5ZXIrKyl7CiAgICBpZihsZW5ndGhbbGF5ZXJdID4gMCl7CiAgICAgIGVyclRwID0gdHJhbnNwb3J0RGVjX091dE9mQmFuZENvbmZpZyhzZWxmLT5oSW5wdXQsIGNvbmZbbGF5ZXJdLCBsZW5ndGhbbGF5ZXJdLCBsYXllcik7CiAgICAgIGlmIChlcnJUcCAhPSBUUkFOU1BPUlRERUNfT0spIHsKICAgICAgICBzd2l0Y2ggKGVyclRwKSB7CiAgICAgICAgY2FzZSBUUkFOU1BPUlRERUNfTkVFRF9UT19SRVNUQVJUOgogICAgICAgICAgZXJyID0gQUFDX0RFQ19ORUVEX1RPX1JFU1RBUlQ7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRSQU5TUE9SVERFQ19VTlNVUFBPUlRFRF9GT1JNQVQ6CiAgICAgICAgICBlcnIgPSBBQUNfREVDX1VOU1VQUE9SVEVEX0ZPUk1BVDsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBlcnIgPSBBQUNfREVDX1VOS05PV047CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgLyogaWYgYmFzZWxheWVyIGlzIE9LIHdlIGNvbnRpbnVlIGRlY29kaW5nICovCiAgICAgICAgaWYobGF5ZXIgID49IDEpewogICAgICAgICAgc2VsZi0+bnJPZkxheWVycyA9IGxheWVyOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIGVycjsKfQoKCgpzdGF0aWMgSU5UIGFhY0RlY29kZXJfQ29uZmlnQ2FsbGJhY2sodm9pZCAqaGFuZGxlLCBjb25zdCBDU0F1ZGlvU3BlY2lmaWNDb25maWcgKnBBc2NTdHJ1Y3QpCnsKICBIQU5ETEVfQUFDREVDT0RFUiBzZWxmID0gKEhBTkRMRV9BQUNERUNPREVSKWhhbmRsZTsKICBBQUNfREVDT0RFUl9FUlJPUiBlcnIgPSBBQUNfREVDX09LOwogIFRSQU5TUE9SVERFQ19FUlJPUiBlcnJUcDsKCiAgewogICAgewogICAgICBlcnIgPSBhYWNEZWNvZGVyX0NvbmZpZyhzZWxmLCBwQXNjU3RydWN0KTsKICAgIH0KICB9CiAgaWYgKGVyciA9PSBBQUNfREVDX09LKSB7CiAgICBpZiAoIHNlbGYtPmZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwfEFDX0xEfEFDX0VMRCkKICAgICAgJiYgQ0NvbmNlYWxtZW50X0dldERlbGF5KCZzZWxmLT5jb25jZWFsQ29tbW9uRGF0YSkgPiAwICkKICAgIHsKICAgICAgLyogUmV2ZXJ0IHRvIGVycm9yIGNvbmNlYWxtZW50IG1ldGhvZCBOb2lzZSBTdWJzdGl0dXRpb24uCiAgICAgICAgIEJlY2F1c2UgaW50ZXJwb2xhdGlvbiBpcyBub3QgaW1wbGVtZW50ZWQgZm9yIFVTQUMvUlNWRDUwIG9yCiAgICAgICAgIHRoZSBhZGRpdGlvbmFsIGRlbGF5IGlzIHVud2FudGVkIGZvciBsb3cgZGVsYXkgY29kZWNzLiAqLwogICAgICBzZXRDb25jZWFsTWV0aG9kKHNlbGYsIDEpOwojaWZkZWYgREVCVUcKICAgICAgRkRLcHJpbnRmKCIgIENvbmNlYWxtZW50IG1ldGhvZCB3YXMgcmV2ZXJ0ZWQgdG8gMSAhXG4iKTsKI2VuZGlmCiAgICB9CiAgICBlcnJUcCA9IFRSQU5TUE9SVERFQ19PSzsKICB9IGVsc2UgewogICAgaWYgKElTX0lOSVRfRVJST1IoZXJyKSkgewogICAgICBlcnJUcCA9IFRSQU5TUE9SVERFQ19VTlNVUFBPUlRFRF9GT1JNQVQ7CiAgICB9IC8qIEZhdGFsIGVycm9ycyAqLwogICAgZWxzZSBpZiAoZXJyID09IEFBQ19ERUNfTkVFRF9UT19SRVNUQVJUKSB7CiAgICAgIGVyclRwID0gVFJBTlNQT1JUREVDX05FRURfVE9fUkVTVEFSVDsKICAgIH0gZWxzZSB7CiAgICAgIGVyclRwID0gVFJBTlNQT1JUREVDX1VOS09XTl9FUlJPUjsKICAgIH0KICB9CgogIHJldHVybiBlcnJUcDsKfQoKCgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IKYWFjRGVjb2Rlcl9BbmNEYXRhSW5pdCAoIEhBTkRMRV9BQUNERUNPREVSIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAqYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNpemUgKQp7CiAgQ0FuY0RhdGEgKmFuY0RhdGEgPSAmc2VsZi0+YW5jRGF0YTsKCiAgcmV0dXJuIENBYWNEZWNvZGVyX0FuY0RhdGFJbml0KGFuY0RhdGEsIGJ1ZmZlciwgc2l6ZSk7Cn0KCgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IKYWFjRGVjb2Rlcl9BbmNEYXRhR2V0ICggSEFORExFX0FBQ0RFQ09ERVIgc2VsZiwKICAgICAgICAgICAgICAgICAgICAgICAgaW50ICAgICBpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgKipwdHIsCiAgICAgICAgICAgICAgICAgICAgICAgIGludCAgICAqc2l6ZSApCnsKICBDQW5jRGF0YSAqYW5jRGF0YSA9ICZzZWxmLT5hbmNEYXRhOwoKICByZXR1cm4gQ0FhY0RlY29kZXJfQW5jRGF0YUdldChhbmNEYXRhLCBpbmRleCwgcHRyLCBzaXplKTsKfQoKCnN0YXRpYyBBQUNfREVDT0RFUl9FUlJPUgpzZXRDb25jZWFsTWV0aG9kICggY29uc3QgSEFORExFX0FBQ0RFQ09ERVIgIHNlbGYsICAgLyohPCBIYW5kbGUgb2YgdGhlIGRlY29kZXIgaW5zdGFuY2UgKi8KICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICBtZXRob2QgKQp7CiAgQUFDX0RFQ09ERVJfRVJST1IgZXJyb3JTdGF0dXMgPSBBQUNfREVDX09LOwogIENDb25jZWFsUGFyYW1zICAqcENvbmNlYWxEYXRhID0gTlVMTDsKICBIQU5ETEVfU0JSREVDT0RFUiBoU2JyRGVjID0gTlVMTDsKICBIQU5ETEVfQUFDX0RSQyBoRHJjSW5mbyA9IE5VTEw7CiAgSEFORExFX1BDTV9ET1dOTUlYIGhQY21EbXggPSBOVUxMOwogIENDb25jZWFsbWVudE1ldGhvZCBiYWNrdXBNZXRob2Q7CiAgaW50IGJhY2t1cERlbGF5ID0gMDsKICBpbnQgYnNEZWxheSA9IDA7CgogIC8qIGNoZWNrIGRlY29kZXIgaGFuZGxlICovCiAgaWYgKHNlbGYgIT0gTlVMTCkgewogICAgcENvbmNlYWxEYXRhID0gJnNlbGYtPmNvbmNlYWxDb21tb25EYXRhOwogICAgaFNickRlYyA9IHNlbGYtPmhTYnJEZWNvZGVyOwogICAgaERyY0luZm8gPSBzZWxmLT5oRHJjSW5mbzsKICAgIGhQY21EbXggPSBzZWxmLT5oUGNtVXRpbHM7CiAgfQoKCiAgLyogR2V0IGN1cnJlbnQgbWV0aG9kL2RlbGF5ICovCiAgYmFja3VwTWV0aG9kID0gQ0NvbmNlYWxtZW50X0dldE1ldGhvZChwQ29uY2VhbERhdGEpOwogIGJhY2t1cERlbGF5ICA9IENDb25jZWFsbWVudF9HZXREZWxheShwQ29uY2VhbERhdGEpOwoKICAvKiBCZSBzdXJlIHRvIHNldCBBQUMgYW5kIFNCUiBjb25jZWFsbWVudCBtZXRob2Qgc2ltdWx0YW5lb3VzbHkhICovCiAgZXJyb3JTdGF0dXMgPQogICAgQ0NvbmNlYWxtZW50X1NldFBhcmFtcygKICAgICAgcENvbmNlYWxEYXRhLAogICAgICAoaW50KW1ldGhvZCwgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uY2VhbE1ldGhvZAogICAgICBBQUNERUNfQ09OQ0VBTF9QQVJBTV9OT1RfU1BFQ0lGSUVELCAgLy8gY29uY2VhbEZhZGVPdXRTbG9wZQogICAgICBBQUNERUNfQ09OQ0VBTF9QQVJBTV9OT1RfU1BFQ0lGSUVELCAgLy8gY29uY2VhbEZhZGVJblNsb3BlCiAgICAgIEFBQ0RFQ19DT05DRUFMX1BBUkFNX05PVF9TUEVDSUZJRUQsICAvLyBjb25jZWFsTXV0ZVJlbGVhc2UKICAgICAgQUFDREVDX0NPTkNFQUxfUEFSQU1fTk9UX1NQRUNJRklFRCAgIC8vIGNvbmNlYWxDb21mTm9pc2VMZXZlbAogICAgKTsKICBpZiAoIChlcnJvclN0YXR1cyAhPSBBQUNfREVDX09LKQogICAgJiYgKGVycm9yU3RhdHVzICE9IEFBQ19ERUNfSU5WQUxJRF9IQU5ETEUpICkgewogICAgZ290byBiYWlsOwogIH0KCiAgLyogR2V0IG5ldyBkZWxheSAqLwogIGJzRGVsYXkgPSBDQ29uY2VhbG1lbnRfR2V0RGVsYXkocENvbmNlYWxEYXRhKTsKCiAgewogICAgU0JSX0VSUk9SIHNickVyciA9IFNCUkRFQ19PSzsKCiAgICAvKiBzZXQgU0JSIGJpdHN0cmVhbSBkZWxheSAqLwogICAgc2JyRXJyID0gc2JyRGVjb2Rlcl9TZXRQYXJhbSAoCiAgICAgIGhTYnJEZWMsCiAgICAgIFNCUl9TWVNURU1fQklUU1RSRUFNX0RFTEFZLAogICAgICBic0RlbGF5CiAgICApOwoKICAgIHN3aXRjaCAoc2JyRXJyKSB7CiAgICBjYXNlIFNCUkRFQ19PSzoKICAgIGNhc2UgU0JSREVDX05PVF9JTklUSUFMSVpFRDoKICAgICAgaWYgKHNlbGYgIT0gTlVMTCkgewogICAgICAgIC8qIHNhdmUgdGhlIHBhcmFtIHZhbHVlIGFuZCBzZXQgbGF0ZXIKICAgICAgICAgICAod2hlbiBTQlIgaGFzIGJlZW4gaW5pdGlhbGl6ZWQpICovCiAgICAgICAgc2VsZi0+c2JyUGFyYW1zLmJzRGVsYXkgPSBic0RlbGF5OwogICAgICB9CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgZXJyb3JTdGF0dXMgPSBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgICBnb3RvIGJhaWw7CiAgICB9CiAgfQoKICBlcnJvclN0YXR1cyA9CiAgICBhYWNEZWNvZGVyX2RyY1NldFBhcmFtICgKICAgICAgaERyY0luZm8sCiAgICAgIERSQ19CU19ERUxBWSwKICAgICAgYnNEZWxheQogICAgKTsKICBpZiAoIChlcnJvclN0YXR1cyAhPSBBQUNfREVDX09LKQogICAgJiYgKGVycm9yU3RhdHVzICE9IEFBQ19ERUNfSU5WQUxJRF9IQU5ETEUpICkgewogICAgZ290byBiYWlsOwogIH0KCiAgaWYgKGVycm9yU3RhdHVzID09IEFBQ19ERUNfT0spIHsKICAgIFBDTURNWF9FUlJPUiBlcnIgPQogICAgICBwY21EbXhfU2V0UGFyYW0gKAogICAgICAgIGhQY21EbXgsCiAgICAgICAgRE1YX0JTX0RBVEFfREVMQVksCiAgICAgICAgYnNEZWxheQogICAgICApOwogICAgc3dpdGNoIChlcnIpIHsKICAgIGNhc2UgUENNRE1YX0lOVkFMSURfSEFORExFOgogICAgICBlcnJvclN0YXR1cyA9IEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CiAgICBjYXNlIFBDTURNWF9PSzoKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBlcnJvclN0YXR1cyA9IEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KICB9CgoKYmFpbDoKICBpZiAoIChlcnJvclN0YXR1cyAhPSBBQUNfREVDX09LKQogICAgJiYgKGVycm9yU3RhdHVzICE9IEFBQ19ERUNfSU5WQUxJRF9IQU5ETEUpICkKICB7CiAgICAvKiBSZXZlcnQgdG8gdGhlIGluaXRpYWwgc3RhdGUgKi8KICAgIENDb25jZWFsbWVudF9TZXRQYXJhbXMgKAogICAgICAgIHBDb25jZWFsRGF0YSwKICAgICAgICAoaW50KWJhY2t1cE1ldGhvZCwKICAgICAgICBBQUNERUNfQ09OQ0VBTF9QQVJBTV9OT1RfU1BFQ0lGSUVELAogICAgICAgIEFBQ0RFQ19DT05DRUFMX1BBUkFNX05PVF9TUEVDSUZJRUQsCiAgICAgICAgQUFDREVDX0NPTkNFQUxfUEFSQU1fTk9UX1NQRUNJRklFRCwKICAgICAgICBBQUNERUNfQ09OQ0VBTF9QQVJBTV9OT1RfU1BFQ0lGSUVECiAgICAgICk7CiAgICAvKiBSZXZlcnQgU0JSIGJpdHN0cmVhbSBkZWxheSAqLwogICAgc2JyRGVjb2Rlcl9TZXRQYXJhbSAoCiAgICAgICAgaFNickRlYywKICAgICAgICBTQlJfU1lTVEVNX0JJVFNUUkVBTV9ERUxBWSwKICAgICAgICBiYWNrdXBEZWxheQogICAgICApOwogICAgLyogUmV2ZXJ0IERSQyBiaXRzdHJlYW0gZGVsYXkgKi8KICAgIGFhY0RlY29kZXJfZHJjU2V0UGFyYW0gKAogICAgICAgIGhEcmNJbmZvLAogICAgICAgIERSQ19CU19ERUxBWSwKICAgICAgICBiYWNrdXBEZWxheQogICAgICApOwogICAgLyogUmV2ZXJ0IFBDTSBtaXhkb3duIGJpdHN0cmVhbSBkZWxheSAqLwogICAgcGNtRG14X1NldFBhcmFtICgKICAgICAgICBoUGNtRG14LAogICAgICAgIERNWF9CU19EQVRBX0RFTEFZLAogICAgICAgIGJhY2t1cERlbGF5CiAgICAgICk7CiAgfQoKICByZXR1cm4gZXJyb3JTdGF0dXM7Cn0KCgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IKYWFjRGVjb2Rlcl9TZXRQYXJhbSAoIGNvbnN0IEhBTkRMRV9BQUNERUNPREVSICBzZWxmLCAgIC8qITwgSGFuZGxlIG9mIHRoZSBkZWNvZGVyIGluc3RhbmNlICovCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBQUNERUNfUEFSQU0gICAgICAgcGFyYW0sICAvKiE8IFBhcmFtZXRlciB0byBzZXQgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgIHZhbHVlKSAgLyohPCBQYXJhbWV0ZXIgdmFsdWVkICAgICAgICAgICAgICAgKi8KewogIEFBQ19ERUNPREVSX0VSUk9SIGVycm9yU3RhdHVzID0gQUFDX0RFQ19PSzsKICBDQ29uY2VhbFBhcmFtcyAgKnBDb25jZWFsRGF0YSA9IE5VTEw7CiAgSEFORExFX0FBQ19EUkMgaERyY0luZm8gPSBOVUxMOwoKICAvKiBjaGVjayBkZWNvZGVyIGhhbmRsZSAqLwogIGlmIChzZWxmICE9IE5VTEwpIHsKICAgIHBDb25jZWFsRGF0YSA9ICZzZWxmLT5jb25jZWFsQ29tbW9uRGF0YTsKICAgIGhEcmNJbmZvID0gc2VsZi0+aERyY0luZm87CiAgfQoKICAvKiBjb25maWd1cmUgdGhlIHN1YnN5c3RlbXMgKi8KICBzd2l0Y2ggKHBhcmFtKQogIHsKICBjYXNlIEFBQ19QQ01fT1VUUFVUX0lOVEVSTEVBVkVEOgogICAgaWYgKHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICB9CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgfQogICAgc2VsZi0+b3V0cHV0SW50ZXJsZWF2ZWQgPSB2YWx1ZTsKICAgIGJyZWFrOwoKICBjYXNlIEFBQ19QQ01fT1VUUFVUX0NIQU5ORUxTOgogICAgewogICAgICBQQ01ETVhfRVJST1IgZXJyOwoKICAgICAgZXJyID0gcGNtRG14X1NldFBhcmFtICgKICAgICAgICAgICAgICBzZWxmLT5oUGNtVXRpbHMsCiAgICAgICAgICAgICAgTlVNQkVSX09GX09VVFBVVF9DSEFOTkVMUywKICAgICAgICAgICAgICB2YWx1ZSApOwoKICAgICAgc3dpdGNoIChlcnIpIHsKICAgICAgY2FzZSBQQ01ETVhfT0s6CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgUENNRE1YX0lOVkFMSURfSEFORExFOgogICAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgICB9CiAgICB9CiAgICBicmVhazsKCiAgY2FzZSBBQUNfUENNX0RVQUxfQ0hBTk5FTF9PVVRQVVRfTU9ERToKICAgIHsKICAgICAgUENNRE1YX0VSUk9SIGVycjsKCiAgICAgIGVyciA9IHBjbURteF9TZXRQYXJhbSAoCiAgICAgICAgICAgICAgc2VsZi0+aFBjbVV0aWxzLAogICAgICAgICAgICAgIERVQUxfQ0hBTk5FTF9ET1dOTUlYX01PREUsCiAgICAgICAgICAgICAgdmFsdWUgKTsKCiAgICAgIHN3aXRjaCAoZXJyKSB7CiAgICAgIGNhc2UgUENNRE1YX09LOgogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFBDTURNWF9JTlZBTElEX0hBTkRMRToKICAgICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgICAgfQogICAgfQogICAgYnJlYWs7CgogIGNhc2UgQUFDX1BDTV9PVVRQVVRfQ0hBTk5FTF9NQVBQSU5HOgogICAgc3dpdGNoICh2YWx1ZSkgewogICAgICBjYXNlIDA6CiAgICAgICAgc2VsZi0+Y2hhbm5lbE91dHB1dE1hcHBpbmcgPSBjaGFubmVsTWFwcGluZ1RhYmxlUGFzc3Rocm91Z2g7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMToKICAgICAgICBzZWxmLT5jaGFubmVsT3V0cHV0TWFwcGluZyA9IGNoYW5uZWxNYXBwaW5nVGFibGVXQVY7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgZXJyb3JTdGF0dXMgPSBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgICAgIGJyZWFrOwogICAgfQogICAgYnJlYWs7CgoKICBjYXNlIEFBQ19RTUZfTE9XUE9XRVI6CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IFFNRiBtb2RlIChtaWdodCBiZSBvdmVycmlkZW4pCiAgICAgKiAgMDpIUSAoY29tcGxleCkKICAgICAqICAxOkxQIChwYXJ0aWFsbHkgY29tcGxleCkKICAgICAqLwogICAgc2VsZi0+cW1mTW9kZVVzZXIgPSAoUU1GX01PREUpdmFsdWU7CiAgICBicmVhazsKCgogIGNhc2UgQUFDX0RSQ19BVFRFTlVBVElPTl9GQUNUT1I6CiAgICAvKiBEUkMgY29tcHJlc3Npb24gZmFjdG9yICh3aGVyZSAwIGlzIG5vIGFuZCAxMjcgaXMgbWF4IGNvbXByZXNzaW9uKSAqLwogICAgZXJyb3JTdGF0dXMgPQogICAgICBhYWNEZWNvZGVyX2RyY1NldFBhcmFtICgKICAgICAgICBoRHJjSW5mbywKICAgICAgICBEUkNfQ1VUX1NDQUxFLAogICAgICAgIHZhbHVlCiAgICAgICk7CiAgICBicmVhazsKCiAgY2FzZSBBQUNfRFJDX0JPT1NUX0ZBQ1RPUjoKICAgIC8qIERSQyBib29zdCBmYWN0b3IgKHdoZXJlIDAgaXMgbm8gYW5kIDEyNyBpcyBtYXggYm9vc3QpICovCiAgICBlcnJvclN0YXR1cyA9CiAgICAgIGFhY0RlY29kZXJfZHJjU2V0UGFyYW0gKAogICAgICAgIGhEcmNJbmZvLAogICAgICAgIERSQ19CT09TVF9TQ0FMRSwKICAgICAgICB2YWx1ZQogICAgICApOwogICAgYnJlYWs7CgogIGNhc2UgQUFDX0RSQ19SRUZFUkVOQ0VfTEVWRUw6CiAgICAvKiBEUkMgcmVmZXJlbmNlIGxldmVsIHF1YW50aXplZCBpbiAwLjI1ZEIgc3RlcHMgdXNpbmcgdmFsdWVzIFswLi4xMjddIGl0IGlzICctJyBmb3IgYW5hbG9nIHNjYWxpbmcgKi8KICAgIGVycm9yU3RhdHVzID0KICAgICAgYWFjRGVjb2Rlcl9kcmNTZXRQYXJhbSAoCiAgICAgICAgaERyY0luZm8sCiAgICAgICAgVEFSR0VUX1JFRl9MRVZFTCwKICAgICAgICB2YWx1ZQogICAgICApOwogICAgYnJlYWs7CgogIGNhc2UgQUFDX0RSQ19IRUFWWV9DT01QUkVTU0lPTjoKICAgIC8qIERvbid0IG5lZWQgdG8gb3ZlcndyaXRlIGN1dC9ib29zdCB2YWx1ZXMgKi8KICAgIGVycm9yU3RhdHVzID0KICAgICAgYWFjRGVjb2Rlcl9kcmNTZXRQYXJhbSAoCiAgICAgICAgaERyY0luZm8sCiAgICAgICAgQVBQTFlfSEVBVllfQ09NUFJFU1NJT04sCiAgICAgICAgdmFsdWUKICAgICAgKTsKICAgIGJyZWFrOwoKCiAgY2FzZSBBQUNfVFBERUNfQ0xFQVJfQlVGRkVSOgogICAgdHJhbnNwb3J0RGVjX1NldFBhcmFtKHNlbGYtPmhJbnB1dCwgVFBERUNfUEFSQU1fUkVTRVQsIDEpOwogICAgc2VsZi0+c3RyZWFtSW5mby5udW1Mb3N0QWNjZXNzVW5pdHMgPSAwOwogICAgc2VsZi0+c3RyZWFtSW5mby5udW1CYWRCeXRlcyA9IDA7CiAgICBzZWxmLT5zdHJlYW1JbmZvLm51bVRvdGFsQnl0ZXMgPSAwOwogICAgLyogYWFjRGVjb2Rlcl9TaWduYWxJbnRlcnJ1cHRpb24oc2VsZik7ICovCiAgICBicmVhazsKCiAgY2FzZSBBQUNfQ09OQ0VBTF9NRVRIT0Q6CiAgICAvKiBDaGFuZ2luZyB0aGUgY29uY2VhbG1lbnQgbWV0aG9kIGNhbiBpbnRyb2R1Y2UgYWRkaXRpb25hbCBiaXRzdHJlYW0gZGVsYXkuIEFuZAogICAgICAgdGhhdCBpbiB0dXJuIGFmZmVjdHMgc3ViIGxpYnJhcmllcyBhbmQgbW9kdWxlcyB3aGljaCBtYWtlcyB0aGUgd2hvbGUgdGhpbmcgcXVpdGUKICAgICAgIGNvbXBsZXguICBTbyB0aGUgY29tcGxldGUgY2hhbmdpbmcgcm91dGluZSBpcyBwYWNrZWQgaW50byBhIGhlbHBlciBmdW5jdGlvbiB3aGljaAogICAgICAga2VlcHMgYWxsIG1vZHVsZXMgYW5kIGxpYnMgaW4gYSBjb25zaXN0ZW50IHN0YXRlIGV2ZW4gaW4gdGhlIGNhc2UgYW4gZXJyb3Igb2NjdXJlcy4gKi8KICAgIGVycm9yU3RhdHVzID0gc2V0Q29uY2VhbE1ldGhvZCAoIHNlbGYsIHZhbHVlICk7CiAgICBicmVhazsKCiAgZGVmYXVsdDoKICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogIH0gIC8qIHN3aXRjaChwYXJhbSkgKi8KCiAgcmV0dXJuIChlcnJvclN0YXR1cyk7Cn0KCgpMSU5LU1BFQ19DUFAgSEFORExFX0FBQ0RFQ09ERVIgYWFjRGVjb2Rlcl9PcGVuKFRSQU5TUE9SVF9UWVBFIHRyYW5zcG9ydEZtdCwgVUlOVCBuck9mTGF5ZXJzKQp7CiAgQUFDX0RFQ09ERVJfSU5TVEFOQ0UgKmFhY0RlYyA9IE5VTEw7CiAgSEFORExFX1RSQU5TUE9SVERFQyBwSW47CiAgaW50IGVyciA9IDA7CgogIC8qIEFsbG9jYXRlIHRyYW5zcG9ydCBsYXllciBzdHJ1Y3QuICovCiAgcEluID0gdHJhbnNwb3J0RGVjX09wZW4odHJhbnNwb3J0Rm10LCBUUF9GTEFHX01QRUc0KTsKICBpZiAocEluID09IE5VTEwpIHsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgdHJhbnNwb3J0RGVjX1NldFBhcmFtKHBJbiwgVFBERUNfUEFSQU1fSUdOT1JFX0JVRkZFUkZVTExORVNTLCAxKTsKCiAgLyogQWxsb2NhdGUgQUFDIGRlY29kZXIgY29yZSBzdHJ1Y3QuICovCiAgYWFjRGVjID0gQ0FhY0RlY29kZXJfT3Blbih0cmFuc3BvcnRGbXQpOwoKICBpZiAoYWFjRGVjID09IE5VTEwpIHsKICAgIHRyYW5zcG9ydERlY19DbG9zZSgmcEluKTsKICAgIGdvdG8gYmFpbDsKICB9CiAgYWFjRGVjLT5oSW5wdXQgPSBwSW47CgogIGFhY0RlYy0+bnJPZkxheWVycyA9IG5yT2ZMYXllcnM7CgogIGFhY0RlYy0+Y2hhbm5lbE91dHB1dE1hcHBpbmcgPSBjaGFubmVsTWFwcGluZ1RhYmxlV0FWOwoKICAvKiBSZWdpc3RlciBDb25maWcgVXBkYXRlIGNhbGxiYWNrLiAqLwogIHRyYW5zcG9ydERlY19SZWdpc3RlckFzY0NhbGxiYWNrKHBJbiwgYWFjRGVjb2Rlcl9Db25maWdDYWxsYmFjaywgKHZvaWQqKWFhY0RlYyk7CgogIC8qIG9wZW4gU0JSIGRlY29kZXIgKi8KICBpZiAoIFNCUkRFQ19PSyAhPSBzYnJEZWNvZGVyX09wZW4gKCAmYWFjRGVjLT5oU2JyRGVjb2RlciApKSB7CiAgICBlcnIgPSAtMTsKICAgIGdvdG8gYmFpbDsKICB9CiAgYWFjRGVjLT5xbWZNb2RlVXNlciA9IE5PVF9ERUZJTkVEOwogIHRyYW5zcG9ydERlY19SZWdpc3RlclNickNhbGxiYWNrKGFhY0RlYy0+aElucHV0LCAoY2JTYnJfdClzYnJEZWNvZGVyX0hlYWRlciwgKHZvaWQqKWFhY0RlYy0+aFNickRlY29kZXIpOwoKCiAgcGNtRG14X09wZW4oICZhYWNEZWMtPmhQY21VdGlscyApOwogIGlmIChhYWNEZWMtPmhQY21VdGlscyA9PSBOVUxMKSB7CiAgICBlcnIgPSAtMTsKICAgIGdvdG8gYmFpbDsKICB9CgoKCiAgLyogQXNzdXJlIHRoYXQgYWxsIG1vZHVsZXMgaGF2ZSBzYW1lIGRlbGF5ICovCiAgaWYgKCBzZXRDb25jZWFsTWV0aG9kKGFhY0RlYywgQ0NvbmNlYWxtZW50X0dldE1ldGhvZCgmYWFjRGVjLT5jb25jZWFsQ29tbW9uRGF0YSkpICkgewogICAgZXJyID0gLTE7CiAgICBnb3RvIGJhaWw7CiAgfQoKYmFpbDoKICBpZiAoZXJyID09IC0xKSB7CiAgICBhYWNEZWNvZGVyX0Nsb3NlKGFhY0RlYyk7CiAgICBhYWNEZWMgPSBOVUxMOwogIH0KICByZXR1cm4gYWFjRGVjOwp9CgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IgYWFjRGVjb2Rlcl9GaWxsKAogICAgICAgIEhBTkRMRV9BQUNERUNPREVSICAgc2VsZiwKICAgICAgICBVQ0hBUiAgICAgICAgICAgICAgKnBCdWZmZXJbXSwKICAgICAgICBjb25zdCBVSU5UICAgICAgICAgIGJ1ZmZlclNpemVbXSwKICAgICAgICBVSU5UICAgICAgICAgICAgICAgKnBCeXRlc1ZhbGlkCiAgICAgICAgKQp7CiAgVFJBTlNQT1JUREVDX0VSUk9SIHRwRXJyOwogIC8qIGxvb3AgY291bnRlciBmb3IgbGF5ZXJzOyBpZiBub3QgVFRfTVA0X1JBV1BBQ0tFVFMgdXNlZCBhcyBpbmRleCBmb3Igb25seSAKICAgICBhdmFpbGFibGUgbGF5ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgSU5UIGxheWVyICAgICAgPSAwOwogIElOVCBuck9mTGF5ZXJzID0gc2VsZi0+bnJPZkxheWVyczsKCiAgewogICAgZm9yIChsYXllciA9IDA7IGxheWVyIDwgbnJPZkxheWVyczsgbGF5ZXIrKyl7CiAgICAgIHsKICAgICAgICB0cEVyciA9IHRyYW5zcG9ydERlY19GaWxsRGF0YSggc2VsZi0+aElucHV0LCBwQnVmZmVyW2xheWVyXSwgYnVmZmVyU2l6ZVtsYXllcl0sICZwQnl0ZXNWYWxpZFtsYXllcl0sIGxheWVyICk7CiAgICAgICAgaWYgKHRwRXJyICE9IFRSQU5TUE9SVERFQ19PSykgewogICAgICAgICAgcmV0dXJuIEFBQ19ERUNfVU5LTk9XTjsgIC8qIE11c3QgYmUgYW4gaW50ZXJuYWwgZXJyb3IgKi8KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBBQUNfREVDX09LOwp9CgoKc3RhdGljIHZvaWQgYWFjRGVjb2Rlcl9TaWduYWxJbnRlcnJ1cHRpb24oSEFORExFX0FBQ0RFQ09ERVIgc2VsZikKewogIENBYWNEZWNvZGVyX1NpZ25hbEludGVycnVwdGlvbihzZWxmKTsKCiAgaWYgKCBzZWxmLT5oU2JyRGVjb2RlciAhPSBOVUxMICkgewogICAgc2JyRGVjb2Rlcl9TZXRQYXJhbShzZWxmLT5oU2JyRGVjb2RlciwgU0JSX0JTX0lOVEVSUlVQVElPTiwgMCk7CiAgfQp9CgpzdGF0aWMgdm9pZCBhYWNEZWNvZGVyX1VwZGF0ZUJpdFN0cmVhbUNvdW50ZXJzKENTdHJlYW1JbmZvICpwU2ksIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywgaW50IG5CaXRzLCBBQUNfREVDT0RFUl9FUlJPUiBFcnJvclN0YXR1cykKewogIC8qIGNhbGN1bGF0ZSBiaXQgZGlmZmVyZW5jZSAoYW1vdW50IG9mIGJpdHMgbW92ZWQgZm9yd2FyZCkgKi8KICBuQml0cyA9IG5CaXRzIC0gRkRLZ2V0VmFsaWRCaXRzKGhCcyk7CgogIC8qIE5vdGU6IFRoZSBhbW91bnQgb2YgYml0cyBjb25zdW1lZCBtaWdodCBiZWNvbWUgbmVnYXRpdmUgd2hlbiBwYXJzaW5nIGEKICAgICBiaXQgc3RyZWFtIHdpdGggc2V2ZXJhbCBzdWIgZnJhbWVzLCBhbmQgd2UgZmluZCBvdXQgYXQgdGhlIGxhc3Qgc3ViIGZyYW1lCiAgICAgdGhhdCB0aGUgdG90YWwgZnJhbWUgbGVuZ3RoIGRvZXMgbm90IG1hdGNoIHRoZSBzdW0gb2Ygc3ViIGZyYW1lIGxlbmd0aC4gCiAgICAgSWYgdGhpcyBoYXBwZW5zLCB0aGUgdHJhbnNwb3J0IGRlY29kZXIgbWlnaHQgd2FudCB0byByZXdpbmQgdG8gdGhlIHN1cHBvc2VkCiAgICAgZW5kaW5nIG9mIHRoZSB0cmFuc3BvcnQgZnJhbWUsIGFuZCB0aGlzIHBvc2l0aW9uIG1pZ2h0IGJlIGJlZm9yZSB0aGUgbGFzdAogICAgIGFjY2VzcyB1bml0IGJlZ2lubmluZy4gKi8KCiAgLyogQ2FsYyBiaXRyYXRlLiAqLwogIGlmIChwU2ktPmZyYW1lU2l6ZSA+IDApIHsKICAgIHBTaS0+Yml0UmF0ZSA9IChuQml0cyAqIHBTaS0+c2FtcGxlUmF0ZSkvcFNpLT5mcmFtZVNpemU7CiAgfQoKICAvKiBiaXQvYnl0ZSBjb3VudGVycyAqLwogIHsKICAgIGludCBuQnl0ZXM7CgogICAgbkJ5dGVzID0gbkJpdHM+PjM7CiAgICBwU2ktPm51bVRvdGFsQnl0ZXMgKz0gbkJ5dGVzOwogICAgaWYgKElTX09VVFBVVF9WQUxJRChFcnJvclN0YXR1cykpIHsKICAgICAgcFNpLT5udW1Ub3RhbEFjY2Vzc1VuaXRzKys7CiAgICB9CiAgICBpZiAoSVNfREVDT0RFX0VSUk9SKEVycm9yU3RhdHVzKSkgewogICAgICBwU2ktPm51bUJhZEJ5dGVzICs9IG5CeXRlczsKICAgICAgcFNpLT5udW1CYWRBY2Nlc3NVbml0cysrOwogICAgfQogIH0KfQoKc3RhdGljIElOVCBhYWNEZWNvZGVyX0VzdGltYXRlTnVtYmVyT2ZMb3N0RnJhbWVzKEhBTkRMRV9BQUNERUNPREVSIHNlbGYpCnsKICBJTlQgbjsKCiAgdHJhbnNwb3J0RGVjX0dldE1pc3NpbmdBY2Nlc3NVbml0Q291bnQoICZuLCBzZWxmLT5oSW5wdXQpOwoKICByZXR1cm4gbjsKfQoKTElOS1NQRUNfQ1BQIEFBQ19ERUNPREVSX0VSUk9SIGFhY0RlY29kZXJfRGVjb2RlRnJhbWUoCiAgICAgICAgSEFORExFX0FBQ0RFQ09ERVIgIHNlbGYsCiAgICAgICAgSU5UX1BDTSAgICAgICAgICAgKnBUaW1lRGF0YSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgdGltZURhdGFTaXplLAogICAgICAgIGNvbnN0IFVJTlQgICAgICAgICBmbGFncykKewogICAgQUFDX0RFQ09ERVJfRVJST1IgRXJyb3JTdGF0dXM7CiAgICBJTlQgbGF5ZXI7CiAgICBJTlQgbkJpdHM7CiAgICBJTlQgaW50ZXJsZWF2ZWQgPSBzZWxmLT5vdXRwdXRJbnRlcmxlYXZlZDsKICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCczsKICAgIGludCBmVHBJbnRlcnJ1cHRpb24gPSAwOyAgLyogVHJhbnNwb3J0IG9yaWdpbmF0ZWQgaW50ZXJydXB0aW9uIGRldGVjdGlvbi4gKi8KICAgIGludCBmVHBDb25jZWFsID0gMDsgICAgICAgLyogVHJhbnNwb3J0IG9yaWdpbmF0ZWQgY29uY2VhbG1lbnQuICovCgoKICAgIGlmIChzZWxmID09IE5VTEwpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CiAgICB9CgogICAgaWYgKGZsYWdzICYgQUFDREVDX0lOVFIpIHsKICAgICAgc2VsZi0+c3RyZWFtSW5mby5udW1Mb3N0QWNjZXNzVW5pdHMgPSAwOwogICAgfQoKICAgIGhCcyA9IHRyYW5zcG9ydERlY19HZXRCaXRzdHJlYW0oc2VsZi0+aElucHV0LCAwKTsKCiAgICAvKiBHZXQgY3VycmVudCBiaXRzIHBvc2l0aW9uIGZvciBiaXRyYXRlIGNhbGN1bGF0aW9uLiAqLwogICAgbkJpdHMgPSBGREtnZXRWYWxpZEJpdHMoaEJzKTsKICAgIGlmICghIChmbGFncyAmIChBQUNERUNfQ09OQ0VBTCB8IEFBQ0RFQ19GTFVTSCkgKSApCiAgICB7CiAgICAgIFRSQU5TUE9SVERFQ19FUlJPUiBlcnI7CgogICAgICBmb3IobGF5ZXIgPSAwOyBsYXllciA8IHNlbGYtPm5yT2ZMYXllcnM7IGxheWVyKyspCiAgICAgIHsKICAgICAgICBlcnIgPSB0cmFuc3BvcnREZWNfUmVhZEFjY2Vzc1VuaXQoc2VsZi0+aElucHV0LCBsYXllcik7CiAgICAgICAgaWYgKGVyciAhPSBUUkFOU1BPUlRERUNfT0spIHsKICAgICAgICAgIHN3aXRjaCAoZXJyKSB7CiAgICAgICAgICBjYXNlIFRSQU5TUE9SVERFQ19OT1RfRU5PVUdIX0JJVFM6CiAgICAgICAgICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19OT1RfRU5PVUdIX0JJVFM7CiAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICAgIGNhc2UgVFJBTlNQT1JUREVDX1NZTkNfRVJST1I6CiAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8ubnVtTG9zdEFjY2Vzc1VuaXRzID0gYWFjRGVjb2Rlcl9Fc3RpbWF0ZU51bWJlck9mTG9zdEZyYW1lcyhzZWxmKTsKICAgICAgICAgICAgZlRwSW50ZXJydXB0aW9uID0gMTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlIFRSQU5TUE9SVERFQ19ORUVEX1RPX1JFU1RBUlQ6CiAgICAgICAgICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19ORUVEX1RPX1JFU1RBUlQ7CiAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICAgIGNhc2UgVFJBTlNQT1JUREVDX0NSQ19FUlJPUjoKICAgICAgICAgICAgZlRwQ29uY2VhbCA9IDE7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX1VOS05PV047CiAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGlmIChzZWxmLT5zdHJlYW1JbmZvLm51bUxvc3RBY2Nlc3NVbml0cyA+IDApIHsKICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLm51bUxvc3RBY2Nlc3NVbml0cy0tOwogICAgICB9CiAgICB9CgogICAgLyogU2lnbmFsIGJpdCBzdHJlYW0gaW50ZXJydXB0aW9uIHRvIG90aGVyIG1vZHVsZXMgaWYgcmVxdWlyZWQuICovCiAgICBpZiAoIGZUcEludGVycnVwdGlvbiB8fCAoZmxhZ3MgJiAoQUFDREVDX0lOVFJ8QUFDREVDX0NMUkhJU1QpKSApCiAgICB7CiAgICAgIGFhY0RlY29kZXJfU2lnbmFsSW50ZXJydXB0aW9uKHNlbGYpOwogICAgICBpZiAoICEgKGZsYWdzICYgQUFDREVDX0lOVFIpICkgewogICAgICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19UUkFOU1BPUlRfU1lOQ19FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICAgIH0KICAgIH0KCiAgICAvKiBFbXB0eSBiaXQgYnVmZmVyIGluIGNhc2Ugb2YgZmx1c2ggcmVxdWVzdC4gKi8KICAgIGlmIChmbGFncyAmIEFBQ0RFQ19GTFVTSCkKICAgIHsKICAgICAgdHJhbnNwb3J0RGVjX1NldFBhcmFtKHNlbGYtPmhJbnB1dCwgVFBERUNfUEFSQU1fUkVTRVQsIDEpOwogICAgICBzZWxmLT5zdHJlYW1JbmZvLm51bUxvc3RBY2Nlc3NVbml0cyA9IDA7CiAgICAgIHNlbGYtPnN0cmVhbUluZm8ubnVtQmFkQnl0ZXMgPSAwOwogICAgICBzZWxmLT5zdHJlYW1JbmZvLm51bVRvdGFsQnl0ZXMgPSAwOwogICAgfQoKCiAgICBFcnJvclN0YXR1cyA9IENBYWNEZWNvZGVyX0RlY29kZUZyYW1lKHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsYWdzIHwgKGZUcENvbmNlYWwgPyBBQUNERUNfQ09OQ0VBTCA6IDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwVGltZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVEYXRhU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJsZWF2ZWQpOwoKICAgIGlmICghKGZsYWdzICYgKEFBQ0RFQ19DT05DRUFMfEFBQ0RFQ19GTFVTSCkpKSB7CiAgICAgIFRSQU5TUE9SVERFQ19FUlJPUiB0cEVycjsKICAgICAgdHBFcnIgPSB0cmFuc3BvcnREZWNfRW5kQWNjZXNzVW5pdChzZWxmLT5oSW5wdXQpOwogICAgICBpZiAodHBFcnIgIT0gVFJBTlNQT1JUREVDX09LKSB7CiAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgIH0KICAgIH0KCiAgICAvKiBJZiB0aGUgY3VycmVudCBwVGltZURhdGEgZG9lcyBub3QgY29udGFpbiBhIHZhbGlkIHNpZ25hbCwgdGhlcmUgbm90aGluZyBlbHNlIHdlIGNhbiBkbywgc28gYmFpbC4gKi8KICAgIGlmICggISBJU19PVVRQVVRfVkFMSUQoRXJyb3JTdGF0dXMpICkgewogICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgewogICAgICAvKiBFeHBvcnQgZGF0YSBpbnRvIHN0cmVhbWluZm8gc3RydWN0dXJlICovCiAgICAgIHNlbGYtPnN0cmVhbUluZm8uc2FtcGxlUmF0ZSA9IHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlUmF0ZTsKICAgICAgc2VsZi0+c3RyZWFtSW5mby5mcmFtZVNpemUgID0gc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWU7CiAgICAgIHNlbGYtPnN0cmVhbUluZm8ubnVtQ2hhbm5lbHMgPSBzZWxmLT5hYWNDaGFubmVsczsKICAgIH0KCgoKICAgIENBYWNEZWNvZGVyX1N5bmNRbWZNb2RlKHNlbGYpOwoKLyogc2JyIGRlY29kZXIgKi8KCiAgICBpZiAoRXJyb3JTdGF0dXMgfHwgKGZsYWdzICYgQUFDREVDX0NPTkNFQUwpIHx8IHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bMF0tPmNvbmNlYWxtZW50SW5mby5jb25jZWFsU3RhdGUgPiBDb25jZWFsU3RhdGVfRmFkZUluKQogICAgewogICAgICBzZWxmLT5mcmFtZU9LID0gMDsgIC8qIGlmIGFuIGVycm9yIGhhcyBvY2N1cmVkIGRvIGNvbmNlYWxtZW50IGluIHRoZSBTQlIgZGVjb2RlciB0b28gKi8KICAgIH0KCiAgICBpZiAoc2VsZi0+c2JyRW5hYmxlZCkKICAgIHsKICAgICAgU0JSX0VSUk9SIHNickVycm9yID0gU0JSREVDX09LOwoKICAgICAgLyogc2V0IHBhcmFtcyAqLwogICAgICBzYnJEZWNvZGVyX1NldFBhcmFtICggc2VsZi0+aFNickRlY29kZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQlJfU1lTVEVNX0JJVFNUUkVBTV9ERUxBWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnNiclBhcmFtcy5ic0RlbGF5KTsKCiAgICAgIGlmICggc2VsZi0+c3RyZWFtSW5mby5hb3QgPT0gQU9UX0VSX0FBQ19FTEQgKSB7CiAgICAgICAgLyogQ29uZmlndXJlIFFNRiAqLwogICAgICAgIHNickRlY29kZXJfU2V0UGFyYW0gKCBzZWxmLT5oU2JyRGVjb2RlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0JSX0xEX1FNRl9USU1FX0FMSUdOLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc2VsZi0+ZmxhZ3MgJiBBQ19MRF9NUFMpID8gMSA6IDAgKTsKICAgICAgfQoKCgoKICAgICAgLyogYXBwbHkgU0JSIHByb2Nlc3NpbmcgKi8KICAgICAgc2JyRXJyb3IgPSBzYnJEZWNvZGVyX0FwcGx5ICggc2VsZi0+aFNickRlY29kZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBUaW1lRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+c3RyZWFtSW5mby5udW1DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+c3RyZWFtSW5mby5zYW1wbGVSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5jaGFubmVsT3V0cHV0TWFwcGluZ1tzZWxmLT5hYWNDaGFubmVscy0xXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJsZWF2ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZyYW1lT0ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPnBzUG9zc2libGUpOwoKCiAgICAgaWYgKHNickVycm9yID09IFNCUkRFQ19PSykgewoKICAgICAgIC8qIFVwZGF0ZSBkYXRhIGluIHN0cmVhbWluZm8gc3RydWN0dXJlLiBBc3N1bWUgdGhhdCB0aGUgU0JSIHVwc2FtcGxpbmcgZmFjdG9yIGlzIGVpdGhlciAxIG9yIDIgKi8KICAgICAgIHNlbGYtPmZsYWdzIHw9IEFDX1NCUl9QUkVTRU5UOwogICAgICAgaWYgKHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlUmF0ZSAhPSBzZWxmLT5zdHJlYW1JbmZvLnNhbXBsZVJhdGUpIHsKICAgICAgICAgaWYgKHNlbGYtPnN0cmVhbUluZm8uZnJhbWVTaXplID09IDc2OCkgewogICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uZnJhbWVTaXplID0gIChzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSAqIDgpIC8gMzsKICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmZyYW1lU2l6ZSA9ICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSA8PCAxOwogICAgICAgICB9CiAgICAgICB9CgogICAgICAgaWYgKHNlbGYtPnBzUG9zc2libGUpIHsKICAgICAgICAgc2VsZi0+ZmxhZ3MgfD0gQUNfUFNfUFJFU0VOVDsKICAgICAgICAgc2VsZi0+Y2hhbm5lbFR5cGVbMF0gPSBBQ1RfRlJPTlQ7CiAgICAgICAgIHNlbGYtPmNoYW5uZWxUeXBlWzFdID0gQUNUX0ZST05UOwogICAgICAgICBzZWxmLT5jaGFubmVsSW5kaWNlc1swXSA9IDA7CiAgICAgICAgIHNlbGYtPmNoYW5uZWxJbmRpY2VzWzFdID0gMTsKICAgICAgIH0gZWxzZSB7CiAgICAgICAgIHNlbGYtPmZsYWdzICY9IH5BQ19QU19QUkVTRU5UOwogICAgICAgfQogICAgIH0KICAgfQoKCiAgICBpZiAoIGZsYWdzICYgKEFBQ0RFQ19JTlRSIHwgQUFDREVDX0NMUkhJU1QpICkgewogICAgICAvKiBkZWxldGUgZGF0YSBmcm9tIHRoZSBwYXN0IChlLmcuIG1peGRvd24gY29lZmljaWVudHMpICovCiAgICAgIHBjbURteF9SZXNldCggc2VsZi0+aFBjbVV0aWxzLCBQQ01ETVhfUkVTRVRfQlNfREFUQSApOwogICAgfQogICAgLyogZG8gUENNIHBvc3QgcHJvY2Vzc2luZyAqLwogICAgcGNtRG14X0FwcGx5RnJhbWUgKAogICAgICAgICAgICBzZWxmLT5oUGNtVXRpbHMsCiAgICAgICAgICAgIHBUaW1lRGF0YSwKICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5mcmFtZVNpemUsCiAgICAgICAgICAgJnNlbGYtPnN0cmVhbUluZm8ubnVtQ2hhbm5lbHMsCiAgICAgICAgICAgIGludGVybGVhdmVkLAogICAgICAgICAgICBzZWxmLT5jaGFubmVsVHlwZSwKICAgICAgICAgICAgc2VsZi0+Y2hhbm5lbEluZGljZXMsCiAgICAgICAgICAgIHNlbGYtPmNoYW5uZWxPdXRwdXRNYXBwaW5nCiAgICAgICk7CgoKCiAgICAvKiBTaWduYWwgaW50ZXJydXB0aW9uIHRvIHRha2UgZWZmZWN0IGluIG5leHQgZnJhbWUuICovCiAgICBpZiAoIGZsYWdzICYgQUFDREVDX0ZMVVNIICkgewogICAgICBhYWNEZWNvZGVyX1NpZ25hbEludGVycnVwdGlvbihzZWxmKTsKICAgIH0KCiAgICAvKiBVcGRhdGUgZXh0ZXJuYWxseSB2aXNpYmxlIGNvcHkgb2YgZmxhZ3MgKi8KICAgIHNlbGYtPnN0cmVhbUluZm8uZmxhZ3MgPSBzZWxmLT5mbGFnczsKCmJhaWw6CgogICAgLyogVXBkYXRlIFN0YXRpc3RpY3MgKi8KICAgIGFhY0RlY29kZXJfVXBkYXRlQml0U3RyZWFtQ291bnRlcnMoJnNlbGYtPnN0cmVhbUluZm8sIGhCcywgbkJpdHMsIEVycm9yU3RhdHVzKTsKCiAgICByZXR1cm4gRXJyb3JTdGF0dXM7Cn0KCkxJTktTUEVDX0NQUCB2b2lkIGFhY0RlY29kZXJfQ2xvc2UgKCBIQU5ETEVfQUFDREVDT0RFUiBzZWxmICkKewogIGlmIChzZWxmID09IE5VTEwpCiAgICByZXR1cm47CgoKCiAgaWYgKHNlbGYtPmhQY21VdGlscyAhPSBOVUxMKSB7CiAgICBwY21EbXhfQ2xvc2UoICZzZWxmLT5oUGNtVXRpbHMgKTsKICB9CgoKCiAgaWYgKHNlbGYtPmhTYnJEZWNvZGVyICE9IE5VTEwpIHsKICAgIHNickRlY29kZXJfQ2xvc2UoJnNlbGYtPmhTYnJEZWNvZGVyKTsKICB9CgogIGlmIChzZWxmLT5oSW5wdXQgIT0gTlVMTCkgewogICAgdHJhbnNwb3J0RGVjX0Nsb3NlKCZzZWxmLT5oSW5wdXQpOwogIH0KCiAgQ0FhY0RlY29kZXJfQ2xvc2Uoc2VsZik7Cn0KCgpMSU5LU1BFQ19DUFAgQ1N0cmVhbUluZm8qIGFhY0RlY29kZXJfR2V0U3RyZWFtSW5mbyAoIEhBTkRMRV9BQUNERUNPREVSIHNlbGYgKQp7CiAgcmV0dXJuIENBYWNEZWNvZGVyX0dldFN0cmVhbUluZm8oc2VsZik7Cn0KCkxJTktTUEVDX0NQUCBJTlQgYWFjRGVjb2Rlcl9HZXRMaWJJbmZvICggTElCX0lORk8gKmluZm8gKQp7CiAgaW50IGk7CgogIGlmIChpbmZvID09IE5VTEwpIHsKICAgIHJldHVybiAtMTsKICB9CgogIHNickRlY29kZXJfR2V0TGliSW5mbyggaW5mbyApOwogIHRyYW5zcG9ydERlY19HZXRMaWJJbmZvKCBpbmZvICk7CiAgRkRLX3Rvb2xzR2V0TGliSW5mbyggaW5mbyApOwogIHBjbURteF9HZXRMaWJJbmZvKCBpbmZvICk7CgogIC8qIHNlYXJjaCBmb3IgbmV4dCBmcmVlIHRhYiAqLwogIGZvciAoaSA9IDA7IGkgPCBGREtfTU9EVUxFX0xBU1Q7IGkrKykgewogICAgaWYgKGluZm9baV0ubW9kdWxlX2lkID09IEZES19OT05FKSBicmVhazsKICB9CiAgaWYgKGkgPT0gRkRLX01PRFVMRV9MQVNUKSB7CiAgICByZXR1cm4gLTE7CiAgfQogIGluZm8gKz0gaTsKCiAgaW5mby0+bW9kdWxlX2lkID0gRkRLX0FBQ0RFQzsKICAvKiBidWlsZCBvd24gbGlicmFyeSBpbmZvICovCiAgaW5mby0+dmVyc2lvbiA9IExJQl9WRVJTSU9OKEFBQ0RFQ09ERVJfTElCX1ZMMCwgQUFDREVDT0RFUl9MSUJfVkwxLCBBQUNERUNPREVSX0xJQl9WTDIpOwogIExJQl9WRVJTSU9OX1NUUklORyhpbmZvKTsKICBpbmZvLT5idWlsZF9kYXRlID0gQUFDREVDT0RFUl9MSUJfQlVJTERfREFURTsKICBpbmZvLT5idWlsZF90aW1lID0gQUFDREVDT0RFUl9MSUJfQlVJTERfVElNRTsKICBpbmZvLT50aXRsZSA9IEFBQ0RFQ09ERVJfTElCX1RJVExFOwoKICAvKiBTZXQgZmxhZ3MgKi8KICBpbmZvLT5mbGFncyA9IDAKICAgICAgfCBDQVBGX0FBQ19MQwogICAgICB8IENBUEZfQUFDX1ZDQjExCiAgICAgIHwgQ0FQRl9BQUNfSENSCiAgICAgIHwgQ0FQRl9BQUNfUlZMQwogICAgICB8IENBUEZfRVJfQUFDX0xECiAgICAgIHwgQ0FQRl9FUl9BQUNfRUxECiAgICAgIHwgQ0FQRl9BQUNfQ09OQ0VBTE1FTlQKICAgICAgfCBDQVBGX0FBQ19EUkMKCiAgICAgIHwgQ0FQRl9BQUNfTVBFRzQKCgogICAgICB8IENBUEZfQUFDXzEwMjQKICAgICAgfCBDQVBGX0FBQ185NjAKCiAgICAgIHwgQ0FQRl9BQUNfNTEyCgogICAgICB8IENBUEZfQUFDXzQ4MAoKICAgICAgOwogIC8qIEVuZCBvZiBmbGFncyAqLwoKICByZXR1cm4gMDsKfQoKCgoK