Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBNUEVHLTQgSEUtQUFDIEVuY29kZXIgKioqKioqKioqKioqKioqKioqKioqKioqKgoKICBJbml0aWFsIGF1dGhvcjogICAgICAgTS4gTG9od2Fzc2VyCiAgY29udGVudHMvZGVzY3JpcHRpb246IEZESyBIRS1BQUMgRW5jb2RlciBpbnRlcmZhY2UgbGlicmFyeSBmdW5jdGlvbnMKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAiYWFjZW5jX2xpYi5oIgojaW5jbHVkZSAiRkRLX2F1ZGlvLmgiCiNpbmNsdWRlICJhYWNlbmMuaCIKCiNpbmNsdWRlICJhYWNFbmNfcmFtLmgiCiNpbmNsdWRlICJGREtfY29yZS5oIiAvKiBGREtfdG9vbHMgdmVyc2lvbmluZyBpbmZvICovCgovKiBFbmNvZGVyIGxpYnJhcnkgaW5mbyAqLwojZGVmaW5lIEFBQ0VOQ09ERVJfTElCX1ZMMCAzCiNkZWZpbmUgQUFDRU5DT0RFUl9MSUJfVkwxIDQKI2RlZmluZSBBQUNFTkNPREVSX0xJQl9WTDIgMTIKI2RlZmluZSBBQUNFTkNPREVSX0xJQl9USVRMRSAiQUFDIEVuY29kZXIiCiNkZWZpbmUgQUFDRU5DT0RFUl9MSUJfQlVJTERfREFURSBfX0RBVEVfXwojZGVmaW5lIEFBQ0VOQ09ERVJfTElCX0JVSUxEX1RJTUUgX19USU1FX18KCgojaW5jbHVkZSAic2JyX2VuY29kZXIuaCIKI2luY2x1ZGUgIi4uL3NyYy9zYnJfcmFtLmgiCiNpbmNsdWRlICJjaGFubmVsX21hcC5oIgoKI2luY2x1ZGUgInBzeV9jb25zdC5oIgojaW5jbHVkZSAiYml0ZW5jLmgiCgojaW5jbHVkZSAidHBlbmNfbGliLmgiCgojaW5jbHVkZSAibWV0YWRhdGFfbWFpbi5oIgoKI2RlZmluZSBTQkwoZmwpICAgICAgICAgICAgKGZsLzgpICAgICAgICAgICAgICAgICAvKiE8IFNob3J0IGJsb2NrIGxlbmd0aCAoaGFyZGNvZGVkIHRvIDggc2hvcnQgYmxvY2tzIHBlciBsb25nIGJsb2NrKSAqLwojZGVmaW5lIEJTTEEoZmwpICAgICAgICAgICAoNCpTQkwoZmwpK1NCTChmbCkvMikgIC8qITwgQUFDIGJsb2NrIHN3aXRjaGluZyBsb29rLWFoZWFkICovCiNkZWZpbmUgREVMQVlfQUFDKGZsKSAgICAgIChmbCtCU0xBKGZsKSkgICAgICAgICAgLyohPCBNRENUICsgYmxvY2tzd2l0Y2hpbmcgKi8KI2RlZmluZSBERUxBWV9BQUNFTEQoZmwpICAgKChmbCkvMikgICAgICAgICAgICAgICAvKiE8IEVMRCBGQiBkZWxheSAobm8gZnJhbWluZyBkZWxheSBpbmNsdWRlZCkgKi8KCiNkZWZpbmUgSU5QVVRCVUZGRVJfU0laRSAoMTUzNysxMDArMjA0OCkKCiNkZWZpbmUgREVGQVVMVF9IRUFERVJfUEVSSU9EX1JFUEVUSVRJT05fUkFURSAgMTAgLyohPCBEZWZhdWx0IGhlYWRlciByZXBldGl0aW9uIHJhdGUgdXNlZCBpbiB0cmFuc3BvcnQgbGlicmFyeSBhbmQgZm9yIFNCUiBoZWFkZXIuICovCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLyoqCiAqIEZsYWdzIHRvIGNoYXJhY3Rlcml6ZSBlbmNvZGVyIG1vZHVsZXMgdG8gYmUgc3VwcG9ydGVkIGluIHByZXNlbnQgaW5zdGFuY2UuCiAqLwplbnVtIHsKICAgIEVOQ19NT0RFX0ZMQUdfQUFDICA9IDB4MDAwMSwKICAgIEVOQ19NT0RFX0ZMQUdfU0JSICA9IDB4MDAwMiwKICAgIEVOQ19NT0RFX0ZMQUdfUFMgICA9IDB4MDAwNCwKICAgIEVOQ19NT0RFX0ZMQUdfU0FDICA9IDB4MDAwOCwKICAgIEVOQ19NT0RFX0ZMQUdfTUVUQSA9IDB4MDAxMAp9OwoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCnR5cGVkZWYgc3RydWN0IHsKICAgIEFVRElPX09CSkVDVF9UWVBFIHVzZXJBT1Q7ICAgICAgICAgICAgICAgLyohPCBBdWRpbyBPYmplY3QgVHlwZS4gICAgICAgICAgICAgKi8KICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJTYW1wbGVyYXRlOyAgICAgICAgLyohPCBTYW1wbGluZyBmcmVxdWVuY3kuICAgICAgICAgICAgKi8KICAgIFVJTlQgICAgICAgICAgICAgIG5DaGFubmVsczsgICAgICAgICAgICAgLyohPCB3aWxsIGJlIHNldCB2aWEgY2hhbm5lbE1vZGUuICAgKi8KICAgIENIQU5ORUxfTU9ERSAgICAgIHVzZXJDaGFubmVsTW9kZTsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJCaXRyYXRlOwogICAgVUlOVCAgICAgICAgICAgICAgdXNlckJpdHJhdGVNb2RlOwogICAgVUlOVCAgICAgICAgICAgICAgdXNlckJhbmR3aWR0aDsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJBZnRlcmJ1cm5lcjsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJGcmFtZWxlbmd0aDsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJBbmNEYXRhUmF0ZTsKCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVG5zOyAgICAgICAgICAgICAgIC8qITwgVXNlIFROUyBjb2RpbmcuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyUG5zOyAgICAgICAgICAgICAgIC8qITwgVXNlIFBOUyBjb2RpbmcuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VySW50ZW5zaXR5OyAgICAgICAgIC8qITwgVXNlIEludGVuc2l0eSBjb2RpbmcuICovCgogICAgVFJBTlNQT1JUX1RZUEUgICAgdXNlclRwVHlwZTsgICAgICAgICAgICAvKiE8IFRyYW5zcG9ydCB0eXBlICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVHBTaWduYWxpbmc7ICAgICAgIC8qITwgRXh0ZW5zaW9uIEFPVCBzaWduYWxpbmcgbW9kZS4gKi8KICAgIFVDSEFSICAgICAgICAgICAgIHVzZXJUcE5zdWJGcmFtZXM7ICAgICAgLyohPCBOdW1iZXIgb2Ygc3ViIGZyYW1lcyBpbiBhIHRyYW5zcG9ydCBmcmFtZSBmb3IgTE9BUy9MQVRNIG9yIEFEVFMgKGRlZmF1bHQgMSkuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVHBBbXh2OyAgICAgICAgICAgIC8qITwgQXVkaW9NdXhWZXJzaW9uIHRvIGJlIHVzZWQgZm9yIExBVE0gKGRlZmF1bHQgMCkuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVHBQcm90ZWN0aW9uOwogICAgVUNIQVIgICAgICAgICAgICAgdXNlclRwSGVhZGVyUGVyaW9kOyAgICAvKiE8IFBhcmFtZXRlciB1c2VkIHRvIGNvbmZpZ3VyZSBMQVRNL0xPQVMgU01DIHJhdGUuIE1vcmVvdmVyIHRoaXMgcGFyYW1ldGVycyBpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZWQgdG8gY29uZmlndXJlIHJlcGV0aXRpb24gcmF0ZSBvZiBQQ0UgaW4gcmF3X2RhdGFfYmxvY2suICovCgogICAgVUNIQVIgICAgICAgICAgICAgdXNlckVyVG9vbHM7ICAgICAgICAgICAvKiE8IFVzZSBWQ0IxMSwgSENSIGFuZC9vciBSVkxDIEVSIHRvb2wuICovCiAgICBVSU5UICAgICAgICAgICAgICB1c2VyUGNlQWRkaXRpb25zOyAgICAgIC8qITwgQ29uZmlndXJlIGFkZGl0aW9uYWwgYml0cyBpbiBQQ0UuICovCgogICAgVUNIQVIgICAgICAgICAgICAgdXNlck1ldGFEYXRhTW9kZTsgICAgICAvKiE8IE1ldGEgZGF0YSBsaWJyYXJ5IGNvbmZpZ3VyYXRpb24uICovCgogICAgVUNIQVIgICAgICAgICAgICAgdXNlclNickVuYWJsZWQ7ICAgICAgICAvKiE8IEVuYWJsZSBTQlIgZm9yIEVMRC4gKi8KICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJTYnJSYXRpbzsgICAgICAgICAgLyohPCBTQlIgc2FtcGxpbmcgcmF0ZSByYXRpby4gRHVhbC0gb3Igc2luZ2xlLXJhdGUuICovCgp9IFVTRVJfUEFSQU07CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cnVjdHVyZSBEZWZpbml0aW9ucwoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdHlwZWRlZiBzdHJ1Y3QgIEFBQ0VOQ19DT05GSUcgICAgICpIQU5ETEVfQUFDRU5DX0NPTkZJRzsKCgpzdHJ1Y3QgQUFDRU5DT0RFUgp7CiAgICBVU0VSX1BBUkFNICAgICAgICAgICAgICAgZXh0UGFyYW07CiAgICBDT0RFUl9DT05GSUcgICAgICAgICAgICAgY29kZXJDb25maWc7CgogICAgLyogQUFDICovCiAgICBBQUNFTkNfQ09ORklHICAgICAgICAgICAgYWFjQ29uZmlnOwogICAgSEFORExFX0FBQ19FTkMgICAgICAgICAgIGhBYWNFbmM7CgogICAgLyogU0JSICovCiAgICBIQU5ETEVfU0JSX0VOQ09ERVIgICAgICAgaEVudkVuYzsKCiAgICAvKiBNZXRhIERhdGEgKi8KICAgIEhBTkRMRV9GREtfTUVUQURBVEFfRU5DT0RFUiAgaE1ldGFkYXRhRW5jOwogICAgSU5UICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhRGF0YUFsbG93ZWQ7IC8qIFNpZ25hbCB3aGV0aGVyIGNob3NlbiBjb25maWd1cmF0aW9uIGFsbG93cyBtZXRhZGF0YS4gTmVjZXNzYXJ5IGZvciBkZWxheQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBlbnNhdGlvbi4gTWV0YWRhdGEgbW9kZSBpcyBhIHNlcGFyYXRlIHBhcmFtZXRlci4gKi8KCiAgICAvKiBUcmFuc3BvcnQgKi8KICAgIEhBTkRMRV9UUkFOU1BPUlRFTkMgICAgICBoVHBFbmM7CgogICAgLyogT3V0cHV0ICovCiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAqb3V0QnVmZmVyOyAgICAgICAgIC8qIEludGVybmFsIGJpdHN0cmVhbSBidWZmZXIgKi8KICAgIElOVCAgICAgICAgICAgICAgICAgICAgICBvdXRCdWZmZXJJbkJ5dGVzOyAgIC8qIFNpemUgb2YgaW50ZXJuYWwgYml0c3RyZWFtIGJ1ZmZlciovCgogICAgLyogSW5wdXQgKi8KICAgIElOVF9QQ00gICAgICAgICAgICAgICAgICppbnB1dEJ1ZmZlcjsgICAgICAgIC8qIEludGVybmFsIGlucHV0IGJ1ZmZlci4gSW5wdXQgc291cmNlIGZvciBBQUMgZW5jb2RlciAqLwogICAgSU5UICAgICAgICAgICAgICAgICAgICAgIGlucHV0QnVmZmVyT2Zmc2V0OyAgLyogV2hlcmUgdG8gd3JpdGUgbmV3IGlucHV0IHNhbXBsZXMuICovCgogICAgSU5UICAgICAgICAgICAgICAgICAgICAgIG5TYW1wbGVzVG9SZWFkOyAgICAvKiBudW1iZXIgb2YgaW5wdXQgc2FtcGxlcyBuZWVlZGVkIGZvciBlbmNvZGluZyBvbmUgZnJhbWUgKi8KICAgIElOVCAgICAgICAgICAgICAgICAgICAgICBuU2FtcGxlc1JlYWQ7ICAgICAgLyogbnVtYmVyIG9mIGlucHV0IHNhbXBsZXMgYWxyZWFkeSBpbiBpbnB1dCBidWZmZXIgKi8KICAgIElOVCAgICAgICAgICAgICAgICAgICAgICBuWmVyb3NBcHBlbmRlZDsgICAgLyogYXBwZW5kZWQgemVyb3MgYXQgZW5kIG9mIGZpbGUqLwogICAgSU5UICAgICAgICAgICAgICAgICAgICAgIG5EZWxheTsgICAgICAgICAgICAvKiBlbmNvZGVyIGRlbGF5ICovCgogICAgQUFDRU5DX0VYVF9QQVlMT0FEICAgICAgIGV4dFBheWxvYWQgW01BWF9UT1RBTF9FWFRfUEFZTE9BRFNdOwogICAgLyogRXh0ZW5zaW9uIHBheWxvYWQgKi8KICAgIFVDSEFSICAgICAgICAgICAgICAgICAgICBleHRQYXlsb2FkRGF0YSBbKDEpXVsoOCldW01BWF9QQVlMT0FEX1NJWkVdOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgIGV4dFBheWxvYWRTaXplIFsoMSldWyg4KV07IC8qIHBheWxvYWQgc2l6ZXMgaW4gYml0cyAqLwoKICAgIFVMT05HICAgICAgICAgICAgICAgICAgICBJbml0RmxhZ3M7ICAgICAgICAgLyogaW50ZXJuYWwgc3RhdHVzIHRvIHRyZWdnaWVyIHJlLWluaXRpYWxpemF0aW9uICovCgoKICAgLyogTWVtb3J5IGFsbG9jYXRpb24gaW5mby4gKi8KICAgSU5UICAgICAgICAgICAgICAgICAgICAgICBuTWF4QWFjRWxlbWVudHM7CiAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgbk1heEFhY0NoYW5uZWxzOwogICBJTlQgICAgICAgICAgICAgICAgICAgICAgIG5NYXhTYnJFbGVtZW50czsKICAgSU5UICAgICAgICAgICAgICAgICAgICAgICBuTWF4U2JyQ2hhbm5lbHM7CiAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgbk1heFN1YkZyYW1lczsKCiAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgZW5jb2Rlcl9tb2RpczsKCiAgIC8qIENhcGFiaWxpdHkgZmxhZ3MgKi8KICAgVUlOVCAgICAgICAgICAgICAgICAgICAgICBDQVBGX3RwRW5jOwoKfSA7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBVTE9ORyAgICAgICAgICAgICAgIHNhbXBsaW5nUmF0ZTsgICAvKiE8IEVuY29kZXIgb3V0cHV0IHNhbXBsaW5nIHJhdGUuICovCiAgICBVTE9ORyAgICAgICAgICAgICAgIGJpdHJhdGVSYW5nZTsgICAvKiE8IExvd2VyIGJpdHJhdGUgcmFuZ2UgZm9yIGNvbmZpZyBlbnRyeS4gKi8KCiAgICBVQ0hBUiAgICAgICAgICAgICAgIGxvd0RlbGF5U2JyOyAgICAvKiE8IDA6IEVMRCBzYnIgb2ZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxOiBFTEQgc2JyIG9uICovCgogICAgVUNIQVIgICAgICAgICAgICAgICBkb3duc2FtcGxlZFNicjsgLyohPCAwOiBFTEQgd2l0aCBkdWFscmF0ZSBzYnIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDE6IEVMRCB3aXRoIGRvd25zYW1wbGVkIHNiciAqLwoKfSBFTERfU0JSX0NPTkZJR1VSQVRPUjsKCi8qKgogKiBcYnJpZWYgIFRoaXMgdGFibGUgZGVmaW5lcyBFTEQvU0JSIGRlZmF1bHQgY29uZmlndXJhdGlvbnMuCiAqLwpzdGF0aWMgY29uc3QgRUxEX1NCUl9DT05GSUdVUkFUT1IgZWxkU2JyQXV0b0NvbmZpZ1RhYltdID0KewogIHsgNDgwMDAsICAgICAwLCAxLCAwIH0sCiAgeyA0ODAwMCwgNjQwMDEsIDAsIDAgfSwKCiAgeyA0NDEwMCwgICAgIDAsIDEsIDAgfSwKICB7IDQ0MTAwLCA2NDAwMSwgMCwgMCB9LAoKICB7IDMyMDAwLCAgICAgMCwgMSwgMCB9LAogIHsgMzIwMDAsIDI4MDAwLCAxLCAxIH0sCiAgeyAzMjAwMCwgNTYwMDAsIDAsIDAgfSwKCiAgeyAyNDAwMCwgICAgIDAsIDEsIDEgfSwKICB7IDI0MDAwLCA0MDAwMCwgMCwgMCB9LAoKICB7IDE2MDAwLCAgICAgMCwgMSwgMSB9LAogIHsgMTYwMDAsIDI4MDAwLCAwLCAwIH0KCn07CgovKgogKiBcYnJpZWYgIENvbmZpZ3VyZSBTQlIgZm9yIEVMRCBjb25maWd1cmF0aW9uLgogKgogKiBUaGlzIGZ1bmN0aW9uIGZpbmRzIGRlZmF1bHQgU0JSIGNvbmZpZ3VyYXRpb24gZm9yIEVMRCBiYXNlZCBvbiBzYW1wbGluZyByYXRlIGFuZCBjaGFubmVsIGJpdHJhdGUuCiAqIE91dHB1dHBhcmFtZXRlcnMgYXJlIFNCUiBvbi9vZmYsIGFuZCBTQlIgcmF0aW8uCiAqCiAqIFxwYXJhbSBzYW1wbGluZ1JhdGUgICAgICAgICAgQXVkaW8gc2lnbmFsIHNhbXBsaW5nIHJhdGUuCiAqIFxwYXJhbSBjaGFubmVsTW9kZSAgICAgICAgICAgQ2hhbm5lbCBjb25maWd1cmF0aW9uIHRvIGJlIHVzZWQuCiAqIFxwYXJhbSB0b3RhbEJpdHJhdGUgICAgICAgICAgT3ZlcmFsbCBiaXRyYXRlLgogKiBccGFyYW0gZWxkU2JyICAgICAgICAgICAgICAgIFBvaW50ZXIgdG8gZWxkU2JyIHBhcmFtZXRlciwgZmlsbGVkIG9uIHJldHVybi4KICogXHBhcmFtIGVsZFNiclJhdGlvICAgICAgICAgICBQb2ludGVyIHRvIGVsZFNiclJhdGlvIHBhcmFtZXRlciwgZmlsbGVkIG9uIHJldHVybi4KICoKICogXHJldHVybiAtIEFBQ0VOQ19PSywgYWxsIGZpbmUuCiAqICAgICAgICAgLSBBQUNFTkNfSU5WQUxJRF9DT05GSUcsIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgQUFDRU5DX0VSUk9SIGVsZFNickNvbmZpZ3VyYXRvcigKICAgICAgICBjb25zdCBVTE9ORyAgICAgICAgICAgICAgICAgICAgICBzYW1wbGluZ1JhdGUsCiAgICAgICAgY29uc3QgQ0hBTk5FTF9NT0RFICAgICAgICAgICAgICAgY2hhbm5lbE1vZGUsCiAgICAgICAgY29uc3QgVUxPTkcgICAgICAgICAgICAgICAgICAgICAgdG90YWxCaXRyYXRlLAogICAgICAgIFVJTlQgKiBjb25zdCAgICAgICAgICAgICAgICAgICAgIGVsZFNiciwKICAgICAgICBVSU5UICogY29uc3QgICAgICAgICAgICAgICAgICAgICBlbGRTYnJSYXRpbwogICAgICAgICkKewogICAgQUFDRU5DX0VSUk9SIGVyciA9IEFBQ0VOQ19PSzsKICAgIGludCBpLCBjZmdJZHggPSAtMTsKICAgIGNvbnN0IFVMT05HIGNoYW5uZWxCaXRyYXRlID0gdG90YWxCaXRyYXRlIC8gRkRLYWFjRW5jX0dldENoYW5uZWxNb2RlQ29uZmlndXJhdGlvbihjaGFubmVsTW9kZSktPm5DaGFubmVsc0VmZjsKCiAgICBmb3IgKGk9MDsgaTwoc2l6ZW9mKGVsZFNickF1dG9Db25maWdUYWIpL3NpemVvZihFTERfU0JSX0NPTkZJR1VSQVRPUikpOyBpKyspIHsKICAgICAgaWYgKCAoc2FtcGxpbmdSYXRlIDw9IGVsZFNickF1dG9Db25maWdUYWJbaV0uc2FtcGxpbmdSYXRlKQogICAgICAgICYmIChjaGFubmVsQml0cmF0ZSA+PSBlbGRTYnJBdXRvQ29uZmlnVGFiW2ldLmJpdHJhdGVSYW5nZSkgKQogICAgICB7CiAgICAgICAgY2ZnSWR4ID0gaTsKICAgICAgfQogICAgfQoKICAgIGlmIChjZmdJZHggIT0gLTEpIHsKICAgICAgKmVsZFNiciAgICAgID0gKGVsZFNickF1dG9Db25maWdUYWJbY2ZnSWR4XS5sb3dEZWxheVNicj09MCkgPyAwIDogMTsKICAgICAgKmVsZFNiclJhdGlvID0gKGVsZFNickF1dG9Db25maWdUYWJbY2ZnSWR4XS5kb3duc2FtcGxlZFNicj09MCkgPyAyIDogMTsKICAgIH0KICAgIGVsc2UgewogICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7IC8qIG5vIGRlZmF1bHQgY29uZmlndXJhdGlvbiBmb3IgZWxkLXNiciBhdmFpbGFibGUuICovCiAgICB9CgogICAgcmV0dXJuIGVycjsKfQoKc3RhdGljIGlubGluZSBJTlQgaXNTYnJBY3RpdmUoY29uc3QgSEFORExFX0FBQ0VOQ19DT05GSUcgaEFhY0NvbmZpZykKewogICAgSU5UIHNiclVzZWQgPSAwOwoKICAgIGlmICggKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX1NCUikgICAgICAgICB8fCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfUFMpCiAgICAgIHx8IChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9NUDJfU0JSKSAgICAgfHwgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX01QMl9QUykKICAgICAgfHwgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX0RBQlBMVVNfU0JSKSB8fCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfREFCUExVU19QUykKICAgICAgfHwgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX0RSTV9TQlIpICAgICB8fCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfRFJNX01QRUdfUFMpICkKICAgIHsKICAgICAgICBzYnJVc2VkID0gMTsKICAgIH0KICAgIGlmIChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUgPT0gQU9UX0VSX0FBQ19FTEQgJiYgKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfU0JSX1BSRVNFTlQpKQogICAgewogICAgICAgIHNiclVzZWQgPSAxOwogICAgfQoKICAgIHJldHVybiAoIHNiclVzZWQgKTsKfQoKc3RhdGljIGlubGluZSBJTlQgaXNQc0FjdGl2ZShjb25zdCBBVURJT19PQkpFQ1RfVFlQRSBhdWRpb09iamVjdFR5cGUpCnsKICAgIElOVCBwc1VzZWQgPSAwOwoKICAgIGlmICggKGF1ZGlvT2JqZWN0VHlwZT09QU9UX1BTKQogICAgICB8fCAoYXVkaW9PYmplY3RUeXBlPT1BT1RfTVAyX1BTKQogICAgICB8fCAoYXVkaW9PYmplY3RUeXBlPT1BT1RfREFCUExVU19QUykKICAgICAgfHwgKGF1ZGlvT2JqZWN0VHlwZT09QU9UX0RSTV9NUEVHX1BTKSApCiAgICB7CiAgICAgICAgcHNVc2VkID0gMTsKICAgIH0KCiAgICByZXR1cm4gKCBwc1VzZWQgKTsKfQoKc3RhdGljIFNCUl9QU19TSUdOQUxJTkcgZ2V0U2JyU2lnbmFsaW5nTW9kZSgKICAgICAgICBjb25zdCBBVURJT19PQkpFQ1RfVFlQRSAgICAgICAgICBhdWRpb09iamVjdFR5cGUsCiAgICAgICAgY29uc3QgVFJBTlNQT1JUX1RZUEUgICAgICAgICAgICAgdHJhbnNwb3J0VHlwZSwKICAgICAgICBjb25zdCBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICB0cmFuc3BvcnRTaWduYWxpbmcsCiAgICAgICAgY29uc3QgVUlOVCAgICAgICAgICAgICAgICAgICAgICAgc2JyUmF0aW8KICAgICAgICApCgp7CiAgU0JSX1BTX1NJR05BTElORyBzYnJTaWduYWxpbmc7CgogIGlmICh0cmFuc3BvcnRUeXBlPT1UVF9VTktOT1dOIHx8IHNiclJhdGlvPT0wKSB7CiAgICBzYnJTaWduYWxpbmcgPSBTSUdfVU5LTk9XTjsgLyogTmVlZGVkIHBhcmFtZXRlcnMgaGF2ZSBub3QgYmVlbiBzZXQgKi8KICAgIHJldHVybiBzYnJTaWduYWxpbmc7CiAgfSBlbHNlIHsKICAgIHNiclNpZ25hbGluZyA9IFNJR19JTVBMSUNJVDsgLyogZGVmYXVsdDogaW1wbGljaXQgc2lnbmFsaW5nICovCiAgfQoKICBpZiAoKGF1ZGlvT2JqZWN0VHlwZT09QU9UX0FBQ19MQykgICAgIHx8IChhdWRpb09iamVjdFR5cGU9PUFPVF9TQlIpICAgICB8fCAoYXVkaW9PYmplY3RUeXBlPT1BT1RfUFMpICAgIHx8CiAgICAgIChhdWRpb09iamVjdFR5cGU9PUFPVF9NUDJfQUFDX0xDKSB8fCAoYXVkaW9PYmplY3RUeXBlPT1BT1RfTVAyX1NCUikgfHwgKGF1ZGlvT2JqZWN0VHlwZT09QU9UX01QMl9QUykgKSB7CiAgICBzd2l0Y2ggKHRyYW5zcG9ydFR5cGUpIHsKICAgICAgY2FzZSBUVF9NUDRfQURJRjoKICAgICAgY2FzZSBUVF9NUDRfQURUUzoKICAgICAgICBzYnJTaWduYWxpbmcgPSBTSUdfSU1QTElDSVQ7IC8qIEZvciBNUEVHLTIgdHJhbnNwb3J0IHR5cGVzLCBvbmx5IGltcGxpY2l0IHNpZ25hbGluZyBpcyBwb3NzaWJsZSAqLwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBUVF9NUDRfUkFXOgogICAgICBjYXNlIFRUX01QNF9MQVRNX01DUDE6CiAgICAgIGNhc2UgVFRfTVA0X0xBVE1fTUNQMDoKICAgICAgY2FzZSBUVF9NUDRfTE9BUzoKICAgICAgZGVmYXVsdDoKICAgICAgICBpZiAoIHRyYW5zcG9ydFNpZ25hbGluZz09MHhGRiApIHsKICAgICAgICAgIC8qIERlZmF1bHRzICovCiAgICAgICAgICBpZiAoIHNiclJhdGlvPT0xICkgewogICAgICAgICAgICBzYnJTaWduYWxpbmcgPSBTSUdfRVhQTElDSVRfSElFUkFSQ0hJQ0FMOyAvKiBGb3IgZG93bnNhbXBsZWQgU0JSLCBleHBsaWNpdCBzaWduYWxpbmcgaXMgbWFuZGF0b3J5ICovCiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzYnJTaWduYWxpbmcgPSBTSUdfSU1QTElDSVQ7IC8qIEZvciBkdWFsLXJhdGUgU0JSLCBpbXBsaWNpdCBzaWduYWxpbmcgaXMgZGVmYXVsdCAqLwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvKiBVc2VyIHNldCBwYXJhbWV0ZXJzICovCiAgICAgICAgICAvKiBBdHRlbnRpb246IEJhY2t3YXJkIGNvbXBhdGlibGUgZXhwbGljaXQgc2lnbmFsaW5nIGRvZXMgb25seSB3b3JrIHdpdGggQU1WMSBmb3IgTEFUTS9MT0FTICovCiAgICAgICAgICBzYnJTaWduYWxpbmcgPSAoU0JSX1BTX1NJR05BTElORyl0cmFuc3BvcnRTaWduYWxpbmc7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogIH0KCiAgcmV0dXJuIHNiclNpZ25hbGluZzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFsbG9jYXRlIEVuY29kZXIKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCkhfQUxMT0NfTUVNIChfQWFjRW5jb2RlciwgQUFDRU5DT0RFUikKQ19BTExPQ19NRU0gKF9BYWNFbmNvZGVyLCBBQUNFTkNPREVSLCAxKQoKCgoKLyoKICogTWFwIEVuY29kZXIgc3BlY2lmaWMgY29uZmlnIHN0cnVjdHVyZXMgdG8gQ09ERVJfQ09ORklHLgogKi8Kc3RhdGljIHZvaWQgRkRLYWFjRW5jX01hcENvbmZpZygKICAgICAgICBDT0RFUl9DT05GSUcgKmNvbnN0ICAgICAgICAgICAgICBjYywKICAgICAgICBjb25zdCBVU0VSX1BBUkFNICpjb25zdCAgICAgICAgICBleHRDZmcsCiAgICAgICAgY29uc3QgU0JSX1BTX1NJR05BTElORyAgICAgICAgICAgc2JyU2lnbmFsaW5nLAogICAgICAgIGNvbnN0IEhBTkRMRV9BQUNFTkNfQ09ORklHICAgICAgIGhBYWNDb25maWcKICAgICAgICApCnsKICBBVURJT19PQkpFQ1RfVFlQRSB0cmFuc3BvcnRfQU9UID0gQU9UX05VTExfT0JKRUNUOwogIEZES21lbWNsZWFyKGNjLCBzaXplb2YoQ09ERVJfQ09ORklHKSk7CgogIGNjLT5mbGFncyA9IDA7CgogIC8qIE1hcCB2aXJ0dWFsIGFvdCB0byB0cmFuc3BvcnQgYW90LiAqLwogIHN3aXRjaCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlKSB7CiAgICBjYXNlIEFPVF9NUDJfQUFDX0xDOgogICAgICB0cmFuc3BvcnRfQU9UID0gQU9UX0FBQ19MQzsKICAgICAgYnJlYWs7CiAgICBjYXNlIEFPVF9NUDJfU0JSOgogICAgICB0cmFuc3BvcnRfQU9UID0gQU9UX1NCUjsKICAgICAgY2MtPmZsYWdzIHw9IENDX1NCUjsKICAgICBicmVhazsKICAgIGNhc2UgQU9UX01QMl9QUzoKICAgICAgdHJhbnNwb3J0X0FPVCA9IEFPVF9QUzsKICAgICAgY2MtPmZsYWdzIHw9IENDX1NCUjsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB0cmFuc3BvcnRfQU9UID0gaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlOwogIH0KCiAgaWYgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSA9PSBBT1RfRVJfQUFDX0VMRCkgewogICAgY2MtPmZsYWdzIHw9IChoQWFjQ29uZmlnLT5zeW50YXhGbGFncyAmIEFDX1NCUl9QUkVTRU5UKSA/IENDX1NCUiA6IDA7CiAgfQoKICAvKiB0cmFuc3BvcnQgdHlwZSBpcyB1c3VhbGx5IEFBQy1MQy4gKi8KICBpZiAoICh0cmFuc3BvcnRfQU9UID09IEFPVF9TQlIpIHx8ICh0cmFuc3BvcnRfQU9UID09IEFPVF9QUykgKSB7CiAgICBjYy0+YW90ICAgICAgICAgICA9IEFPVF9BQUNfTEM7CiAgfQogIGVsc2UgewogICAgY2MtPmFvdCAgICAgICAgICAgPSB0cmFuc3BvcnRfQU9UOwogIH0KCiAgLyogQ29uZmlndXJlIGV4dGVuc2lvbiBhb3QuICovCiAgaWYgKHNiclNpZ25hbGluZz09U0lHX0lNUExJQ0lUKSB7CiAgICBjYy0+ZXh0QU9UID0gQU9UX05VTExfT0JKRUNUOyAgLyogaW1wbGljaXQgKi8KICB9CiAgZWxzZSB7CiAgICBpZiAoIChzYnJTaWduYWxpbmc9PVNJR19FWFBMSUNJVF9CV19DT01QQVRJQkxFKSAmJiAoICh0cmFuc3BvcnRfQU9UPT1BT1RfU0JSKSB8fCAodHJhbnNwb3J0X0FPVD09QU9UX1BTKSApICkgewogICAgICBjYy0+ZXh0QU9UID0gQU9UX1NCUjsgICAgICAgIC8qIGV4cGxpY2l0IGJhY2t3YXJkIGNvbXBhdGlibGUgKi8KICAgIH0KICAgIGVsc2UgewogICAgICBjYy0+ZXh0QU9UID0gdHJhbnNwb3J0X0FPVDsgIC8qIGV4cGxpY2l0IGhpZXJhcmNoaWNhbCAqLwogICAgfQogIH0KCiAgaWYgKCAodHJhbnNwb3J0X0FPVD09QU9UX1NCUikgfHwgKHRyYW5zcG9ydF9BT1Q9PUFPVF9QUykgKSB7CiAgICBjYy0+c2JyUHJlc2VudD0xOwogICAgaWYgKHRyYW5zcG9ydF9BT1Q9PUFPVF9QUykgewogICAgICBjYy0+cHNQcmVzZW50PTE7CiAgICB9CiAgfQogIGNjLT5zYnJTaWduYWxpbmcgICAgPSBzYnJTaWduYWxpbmc7CgogIGNjLT5leHRTYW1wbGluZ1JhdGUgPSBleHRDZmctPnVzZXJTYW1wbGVyYXRlOwogIGNjLT5iaXRSYXRlICAgICAgICAgPSBoQWFjQ29uZmlnLT5iaXRSYXRlOwogIGNjLT5ub0NoYW5uZWxzICAgICAgPSBoQWFjQ29uZmlnLT5uQ2hhbm5lbHM7CiAgY2MtPmZsYWdzICAgICAgICAgIHw9IENDX0lTX0JBU0VMQVlFUjsKICBjYy0+Y2hhbm5lbE1vZGUgICAgID0gaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGU7CgogIGNjLT5uU3ViRnJhbWVzID0gKGhBYWNDb25maWctPm5TdWJGcmFtZXMgPiAxICYmIGV4dENmZy0+dXNlclRwTnN1YkZyYW1lcyA9PSAxKQogICAgICAgICAgICAgICAgID8gaEFhY0NvbmZpZy0+blN1YkZyYW1lcwogICAgICAgICAgICAgICAgIDogZXh0Q2ZnLT51c2VyVHBOc3ViRnJhbWVzOwoKICBjYy0+ZmxhZ3MgICAgICAgICAgfD0gKGV4dENmZy0+dXNlclRwUHJvdGVjdGlvbikgPyBDQ19QUk9URUNUSU9OIDogMDsKCiAgaWYgKGV4dENmZy0+dXNlclRwSGVhZGVyUGVyaW9kIT0weEZGKSB7CiAgICBjYy0+aGVhZGVyUGVyaW9kICAgID0gZXh0Q2ZnLT51c2VyVHBIZWFkZXJQZXJpb2Q7CiAgfQogIGVsc2UgeyAvKiBhdXRvLW1vZGUgKi8KICAgIHN3aXRjaCAoZXh0Q2ZnLT51c2VyVHBUeXBlKSB7CiAgICAgIGNhc2UgVFRfTVA0X0FEVFM6CiAgICAgIGNhc2UgVFRfTVA0X0xPQVM6CiAgICAgIGNhc2UgVFRfTVA0X0xBVE1fTUNQMToKICAgICAgICBjYy0+aGVhZGVyUGVyaW9kID0gREVGQVVMVF9IRUFERVJfUEVSSU9EX1JFUEVUSVRJT05fUkFURTsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICBjYy0+aGVhZGVyUGVyaW9kID0gMDsKICAgIH0KICB9CgogIGNjLT5zYW1wbGVzUGVyRnJhbWUgPSBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aDsKICBjYy0+c2FtcGxpbmdSYXRlICAgID0gaEFhY0NvbmZpZy0+c2FtcGxlUmF0ZTsKCiAgLyogTXBlZy00IHNpZ25hbGluZyBmb3IgdHJhbnNwb3J0IGxpYnJhcnkuICovCiAgc3dpdGNoICggaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlICkgewogICAgY2FzZSBBT1RfTVAyX0FBQ19MQzoKICAgIGNhc2UgQU9UX01QMl9TQlI6CiAgICBjYXNlIEFPVF9NUDJfUFM6CiAgICAgIGNjLT5mbGFncyAmPSB+Q0NfTVBFR19JRDsgLyogUmVxdWlyZWQgZm9yIEFEVFMuICovCiAgICAgIGNjLT5leHRBT1QgPSBBT1RfTlVMTF9PQkpFQ1Q7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgY2MtPmZsYWdzIHw9IENDX01QRUdfSUQ7CiAgfQoKICAvKiBFUi10b29scyBzaWduYWxpbmcuICovCiAgY2MtPmZsYWdzICAgICB8PSAoaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgJiBBQ19FUl9WQ0IxMSkgPyBDQ19WQ0IxMSA6IDA7CiAgY2MtPmZsYWdzICAgICB8PSAoaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgJiBBQ19FUl9IQ1IpICAgPyBDQ19IQ1IgOiAwOwogIGNjLT5mbGFncyAgICAgfD0gKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfRVJfUlZMQykgID8gQ0NfUlZMQyA6IDA7CgogIC8qIE1hdHJpeCBtaXhkb3duIGNvZWZmaWNpZW50IGNvbmZpZ3VyYXRpb24uICovCiAgaWYgKCAoZXh0Q2ZnLT51c2VyUGNlQWRkaXRpb25zJjB4MSkgJiYgKGhBYWNDb25maWctPmVwQ29uZmlnPT0tMSkKICAgICAgJiYgKChjYy0+Y2hhbm5lbE1vZGU9PU1PREVfMV8yXzIpfHwoY2MtPmNoYW5uZWxNb2RlPT1NT0RFXzFfMl8yXzEpKSApCiAgewogICAgY2MtPm1hdHJpeE1peGRvd25BICAgICAgID0gKChleHRDZmctPnVzZXJQY2VBZGRpdGlvbnM+PjEpJjB4MykrMTsKICAgIGNjLT5mbGFncyB8PSAoZXh0Q2ZnLT51c2VyUGNlQWRkaXRpb25zPj4zKSYweDEgPyBDQ19QU0VVRE9fU1VSUk9VTkQgOiAwOwogIH0KICBlbHNlIHsKICAgIGNjLT5tYXRyaXhNaXhkb3duQSA9IDA7CiAgfQp9CgovKgogKiBFeGFtaW5lIGJ1ZmZlciBkZXNjcmlwdG9yIHJlZ2FyZGluZyBjaG9vc2VuIGlkZW50aWZpZXIuCiAqCiAqIFxwYXJhbSBwQnVmRGVzYyAgICAgICAgICAgICAgUG9pbnRlciB0byBidWZmZXIgZGVzY3JpcHRvcgogKiBccGFyYW0gaWRlbnRpZmllciAgICAgICAgICAgIEJ1ZmZlciBpZGVudGlmaWVyIHRvIGxvb2sgZm9yLgoKICogXHJldHVybiAtIEJ1ZmZlciBkZXNjcmlwdG9yIGluZGV4LgogKiAgICAgICAgIC0xLCBpZiB0aGVyZSBpcyBubyBlbnRyeSBhdmFpbGFibGUuCiAqLwpzdGF0aWMgSU5UIGdldEJ1ZkRlc2NJZHgoCiAgICAgICAgY29uc3QgQUFDRU5DX0J1ZkRlc2MgICAgICAgICAqcEJ1ZkRlc2MsCiAgICAgICAgY29uc3QgQUFDRU5DX0J1ZmZlcklkZW50aWZpZXIgaWRlbnRpZmllcgopCnsKICAgIElOVCBpLCBpZHggPSAtMTsKCiAgICBmb3IgKGk9MDsgaTxwQnVmRGVzYy0+bnVtQnVmczsgaSsrKSB7CiAgICAgIGlmICggKEFBQ0VOQ19CdWZmZXJJZGVudGlmaWVyKXBCdWZEZXNjLT5idWZmZXJJZGVudGlmaWVyc1tpXSA9PSBpZGVudGlmaWVyICkgewogICAgICAgIGlkeCA9IGk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBpZHg7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICAgICAgICAgICAgICAgICAgICAgICAgIEZ1bmN0aW9uIERlY2xhcmF0aW9ucwoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKQUFDX0VOQ09ERVJfRVJST1IgYWFjRW5jRGVmYXVsdENvbmZpZyhIQU5ETEVfQUFDRU5DX0NPTkZJRyBoQWFjQ29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTRVJfUEFSQU0gKmNvbmZpZykKewogICAgLyogbWFrZSByZWFzb25hYmxlIGRlZmF1bHQgc2V0dGluZ3MgKi8KICAgIEZES2FhY0VuY19BYWNJbml0RGVmYXVsdENvbmZpZyAoaEFhY0NvbmZpZyk7CgogICAgLyogY2xlYXIgY29uZmlndXJhdGlvbiBzdHJ1Y3R1cmUgYW5kIGNvcHkgZGVmYXVsdCBzZXR0aW5ncyAqLwogICAgRkRLbWVtY2xlYXIoY29uZmlnLCBzaXplb2YoVVNFUl9QQVJBTSkpOwoKICAgIC8qIGNvcHkgZW5jb2RlciBjb25maWd1cmF0aW9uIHNldHRpbmdzICovCiAgICBjb25maWctPm5DaGFubmVscyAgICAgICA9IGhBYWNDb25maWctPm5DaGFubmVsczsKICAgIGNvbmZpZy0+dXNlckFPVCA9IGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSA9IEFPVF9BQUNfTEM7CiAgICBjb25maWctPnVzZXJTYW1wbGVyYXRlICA9IGhBYWNDb25maWctPnNhbXBsZVJhdGU7CiAgICBjb25maWctPnVzZXJDaGFubmVsTW9kZSA9IGhBYWNDb25maWctPmNoYW5uZWxNb2RlOwogICAgY29uZmlnLT51c2VyQml0cmF0ZSAgICAgPSBoQWFjQ29uZmlnLT5iaXRSYXRlOwogICAgY29uZmlnLT51c2VyQml0cmF0ZU1vZGUgPSBoQWFjQ29uZmlnLT5iaXRyYXRlTW9kZTsKICAgIGNvbmZpZy0+dXNlckJhbmR3aWR0aCAgID0gaEFhY0NvbmZpZy0+YmFuZFdpZHRoOwogICAgY29uZmlnLT51c2VyVG5zICAgICAgICAgPSBoQWFjQ29uZmlnLT51c2VUbnM7CiAgICBjb25maWctPnVzZXJQbnMgICAgICAgICA9IGhBYWNDb25maWctPnVzZVBuczsKICAgIGNvbmZpZy0+dXNlckludGVuc2l0eSAgID0gaEFhY0NvbmZpZy0+dXNlSVM7CiAgICBjb25maWctPnVzZXJBZnRlcmJ1cm5lciA9IGhBYWNDb25maWctPnVzZVJlcXVhbnQ7CiAgICBjb25maWctPnVzZXJGcmFtZWxlbmd0aCA9IChVSU5UKS0xOwoKICAgIGlmIChoQWFjQ29uZmlnLT5zeW50YXhGbGFncyAmIEFDX0VSX1ZDQjExKSB7CiAgICAgIGNvbmZpZy0+dXNlckVyVG9vbHMgIHw9IDB4MDE7CiAgICB9CiAgICBpZiAoaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgJiBBQ19FUl9IQ1IpIHsKICAgICAgY29uZmlnLT51c2VyRXJUb29scyAgfD0gMHgwMjsKICAgIH0KCiAgICAvKiBpbml0aWFsaXplIHRyYW5zcG9ydCBwYXJhbWV0ZXJzICovCiAgICBjb25maWctPnVzZXJUcFR5cGUgICAgICAgICA9IFRUX1VOS05PV047CiAgICBjb25maWctPnVzZXJUcEFteHYgICAgICAgICA9IDA7CiAgICBjb25maWctPnVzZXJUcFNpZ25hbGluZyAgICA9IDB4RkY7ICAgIC8qIGNob29zZSBzaWduYWxpbmcgYXV0b21hdGljYWxseSAqLwogICAgY29uZmlnLT51c2VyVHBOc3ViRnJhbWVzICAgPSAxOwogICAgY29uZmlnLT51c2VyVHBQcm90ZWN0aW9uICAgPSAwOyAgICAvKiBub3QgY3JjIHByb3RlY3RlZCovCiAgICBjb25maWctPnVzZXJUcEhlYWRlclBlcmlvZCA9IDB4RkY7IC8qIGhlYWRlciBwZXJpb2QgaW4gYXV0byBtb2RlICovCiAgICBjb25maWctPnVzZXJQY2VBZGRpdGlvbnMgICA9IDA7ICAgIC8qIG5vIG1hdHJpeCBtaXhkb3duIGNvZWZmaWNpZW50ICovCiAgICBjb25maWctPnVzZXJNZXRhRGF0YU1vZGUgICA9IDA7ICAgIC8qIGRvIG5vdCBlbWJlZCBhbnkgbWV0YSBkYXRhIGluZm8gKi8KCiAgICBjb25maWctPnVzZXJBbmNEYXRhUmF0ZSAgICA9IDA7CgogICAgLyogU0JSIHJhdGUgaXMgc2V0IHRvIDAgaGVyZSwgd2hpY2ggbWVhbnMgaXQgc2hvdWxkIGJlIHNldCBhdXRvbWF0aWNhbGx5CiAgICAgICBpbiBGREthYWNFbmNfQWRqdXN0RW5jU2V0dGluZ3MoKSBpZiB0aGUgdXNlciBkaWQgbm90IHNldCBhIHJhdGUKICAgICAgIGV4cGlsaWNpdGVseS4gKi8KICAgIGNvbmZpZy0+dXNlclNiclJhdGlvID0gMDsKCiAgICAvKiBTQlIgZW5hYmxlIHNldCB0byAtMSBtZWFucyB0byBpbnF1aXJlIEVMRCBhdWRpbyBjb25maWd1cmF0b3IgZm9yIHJlYXNvbmFibGUgY29uZmlndXJhdGlvbi4gKi8KICAgIGNvbmZpZy0+dXNlclNickVuYWJsZWQgICAgID0gLTE7CgogICAgcmV0dXJuIEFBQ19FTkNfT0s7Cn0KCnN0YXRpYwp2b2lkIGFhY0VuY0Rpc3RyaWJ1dGVTYnJCaXRzKENIQU5ORUxfTUFQUElORyAqY2hhbm5lbE1hcHBpbmcsIFNCUl9FTEVNRU5UX0lORk8gKnNickVsSW5mbywgSU5UIGJpdFJhdGUpCnsKICBJTlQgY29kZWJpdHMgPSBiaXRSYXRlOwogIGludCBlbDsKCiAgLyogQ29weSBFbGVtZW50IGluZm8gKi8KICBmb3IgKGVsPTA7IGVsPGNoYW5uZWxNYXBwaW5nLT5uRWxlbWVudHM7IGVsKyspIHsKICAgICAgc2JyRWxJbmZvW2VsXS5DaGFubmVsSW5kZXhbMF0gPSBjaGFubmVsTWFwcGluZy0+ZWxJbmZvW2VsXS5DaGFubmVsSW5kZXhbMF07CiAgICAgIHNickVsSW5mb1tlbF0uQ2hhbm5lbEluZGV4WzFdID0gY2hhbm5lbE1hcHBpbmctPmVsSW5mb1tlbF0uQ2hhbm5lbEluZGV4WzFdOwogICAgICBzYnJFbEluZm9bZWxdLmVsVHlwZSAgICAgICAgICA9IGNoYW5uZWxNYXBwaW5nLT5lbEluZm9bZWxdLmVsVHlwZTsKICAgICAgc2JyRWxJbmZvW2VsXS5iaXRSYXRlICAgICAgICAgPSAoSU5UKShmTXVsdE5vcm0oY2hhbm5lbE1hcHBpbmctPmVsSW5mb1tlbF0ucmVsYXRpdmVCaXRzLCAoRklYUF9EQkwpYml0UmF0ZSkpOwogICAgICBzYnJFbEluZm9bZWxdLmluc3RhbmNlVGFnICAgICA9IGNoYW5uZWxNYXBwaW5nLT5lbEluZm9bZWxdLmluc3RhbmNlVGFnOwogICAgICBzYnJFbEluZm9bZWxdLm5DaGFubmVsc0luRWwgICA9IGNoYW5uZWxNYXBwaW5nLT5lbEluZm9bZWxdLm5DaGFubmVsc0luRWw7CgogICAgICBjb2RlYml0cyAtPSBzYnJFbEluZm9bZWxdLmJpdFJhdGU7CiAgfQogIHNickVsSW5mb1swXS5iaXRSYXRlICs9IGNvZGViaXRzOwp9CgoKc3RhdGljCklOVCBhYWNFbmNvZGVyX0xpbWl0Qml0cmF0ZSgKICAgICAgICBjb25zdCBIQU5ETEVfVFJBTlNQT1JURU5DIGhUcEVuYywKICAgICAgICBjb25zdCBJTlQgc2FtcGxpbmdSYXRlLAogICAgICAgIGNvbnN0IElOVCBmcmFtZUxlbmd0aCwKICAgICAgICBjb25zdCBJTlQgbkNoYW5uZWxzLAogICAgICAgIGNvbnN0IENIQU5ORUxfTU9ERSBjaGFubmVsTW9kZSwKICAgICAgICBJTlQgYml0UmF0ZSwKICAgICAgICBjb25zdCBJTlQgblN1YkZyYW1lcywKICAgICAgICBjb25zdCBJTlQgc2JyQWN0aXZlLAogICAgICAgIGNvbnN0IElOVCBzYnJEb3duU2FtcGxlUmF0ZSwKICAgICAgICBjb25zdCBBVURJT19PQkpFQ1RfVFlQRSBhb3QKICAgICAgICApCnsKICBJTlQgY29yZVNhbXBsaW5nUmF0ZTsKICBDSEFOTkVMX01BUFBJTkcgY207CgogIEZES2FhY0VuY19Jbml0Q2hhbm5lbE1hcHBpbmcoY2hhbm5lbE1vZGUsIENIX09SREVSX01QRUcsICZjbSk7CgogIGlmIChzYnJBY3RpdmUpIHsKICAgIGNvcmVTYW1wbGluZ1JhdGUgPSBzYW1wbGluZ1JhdGUgPj4gIChzYnJFbmNvZGVyX0lzU2luZ2xlUmF0ZVBvc3NpYmxlKGFvdCkgPyAoc2JyRG93blNhbXBsZVJhdGUtMSk6MSk7CiAgfSBlbHNlIHsKICAgIGNvcmVTYW1wbGluZ1JhdGUgPSBzYW1wbGluZ1JhdGU7CiAgfQoKICAvKiBDb25zaWRlciBiYW5kd2lkdGggY2hhbm5lbCBiaXQgcmF0ZSBsaW1pdCAoc2VlIGJhbmR3aWR0aC5jcHA6IEdldEJhbmR3aWR0aEVudHJ5KCkpICovCiAgaWYgKGFvdCA9PSBBT1RfRVJfQUFDX0xEIHx8IGFvdCA9PSBBT1RfRVJfQUFDX0VMRCkgewogICAgYml0UmF0ZSA9IEZES21pbigzNjAwMDAqbkNoYW5uZWxzLCBiaXRSYXRlKTsKICAgIGJpdFJhdGUgPSBGREttYXgoODAwMCpuQ2hhbm5lbHMsIGJpdFJhdGUpOwogIH0KCiAgaWYgKGFvdCA9PSBBT1RfQUFDX0xDIHx8IGFvdCA9PSBBT1RfU0JSIHx8IGFvdCA9PSBBT1RfUFMpICB7CiAgICBiaXRSYXRlID0gRkRLbWluKDU3NjAwMCpuQ2hhbm5lbHMsIGJpdFJhdGUpOwogICAgLypiaXRSYXRlID0gRkRLbWF4KDAqbkNoYW5uZWxzLCBiaXRSYXRlKTsqLwogIH0KCgogIC8qIExpbWl0IGJpdCByYXRlIGluIHJlc3BlY3QgdG8gdGhlIGNvcmUgY29kZXIgKi8KICBiaXRSYXRlID0gRkRLYWFjRW5jX0xpbWl0Qml0cmF0ZSgKICAgICAgICAgIGhUcEVuYywKICAgICAgICAgIGNvcmVTYW1wbGluZ1JhdGUsCiAgICAgICAgICBmcmFtZUxlbmd0aCwKICAgICAgICAgIG5DaGFubmVscywKICAgICAgICAgIGNtLm5DaGFubmVsc0VmZiwKICAgICAgICAgIGJpdFJhdGUsCiAgICAgICAgICAtMSwKICAgICAgICAgIE5VTEwsCiAgICAgICAgICAtMSwKICAgICAgICAgIG5TdWJGcmFtZXMKICAgICAgICAgICk7CgogIC8qIExpbWl0IGJpdCByYXRlIGluIHJlc3BlY3QgdG8gYXZhaWxhYmxlIFNCUiBtb2RlcyBpZiBhY3RpdmUgKi8KICBpZiAoc2JyQWN0aXZlKQogIHsKICAgIGludCBudW1JdGVyYXRpb25zID0gMDsKICAgIElOVCBpbml0aWFsQml0cmF0ZSwgYWRqdXN0ZWRCaXRyYXRlOwogICAgaW5pdGlhbEJpdHJhdGUgPSBhZGp1c3RlZEJpdHJhdGUgPSBiaXRSYXRlOwoKICAgIC8qIEZpbmQgdG90YWwgYml0cmF0ZSB3aGljaCBwcm92aWRlcyB2YWxpZCBjb25maWd1cmF0aW9uIGZvciBlYWNoIFNCUiBlbGVtZW50LiAqLwogICAgZG8gewogICAgICBpbnQgZTsKICAgICAgU0JSX0VMRU1FTlRfSU5GTyBzYnJFbEluZm9bKDgpXTsKICAgICAgRkRLX0FTU0VSVChjbS5uRWxlbWVudHMgPD0gKDgpKTsKCiAgICAgIGluaXRpYWxCaXRyYXRlID0gYWRqdXN0ZWRCaXRyYXRlOwoKICAgICAgLyogR2V0IGJpdCByYXRlIGZvciBlYWNoIFNCUiBlbGVtZW50ICovCiAgICAgIGFhY0VuY0Rpc3RyaWJ1dGVTYnJCaXRzKCZjbSwgc2JyRWxJbmZvLCBpbml0aWFsQml0cmF0ZSk7CgogICAgICBmb3IgKGU9MDsgZTxjbS5uRWxlbWVudHM7IGUrKykKICAgICAgewogICAgICAgIElOVCBzYnJFbGVtZW50Qml0UmF0ZUluLCBzYnJCaXRSYXRlT3V0OwoKICAgICAgICBpZiAoY20uZWxJbmZvW2VdLmVsVHlwZSAhPSBJRF9TQ0UgJiYgY20uZWxJbmZvW2VdLmVsVHlwZSAhPSBJRF9DUEUpIHsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBzYnJFbGVtZW50Qml0UmF0ZUluID0gc2JyRWxJbmZvW2VdLmJpdFJhdGU7CiAgICAgICAgc2JyQml0UmF0ZU91dCA9IHNickVuY29kZXJfTGltaXRCaXRSYXRlKHNickVsZW1lbnRCaXRSYXRlSW4gLCBjbS5lbEluZm9bZV0ubkNoYW5uZWxzSW5FbCwgY29yZVNhbXBsaW5nUmF0ZSwgYW90KTsKICAgICAgICBpZiAoc2JyQml0UmF0ZU91dCA9PSAwKSB7CiAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8qIElmIGJpdHJhdGVzIGRvbid0IG1hdGNoLCBkaXN0cmlidXRpb24gYW5kIGxpbWl0aW5nIG5lZWRzIHRvIGJlIGRldGVybWluZWQgYWdhaW4uCiAgICAgICAgICAgQWJvcnQgZWxlbWVudCBsb29wIGFuZCByZXN0YXJ0IHdpdGggYWRhcHRlZCBiaXRyYXRlLiAqLwogICAgICAgIGlmIChzYnJFbGVtZW50Qml0UmF0ZUluICE9IHNickJpdFJhdGVPdXQpIHsKCiAgICAgICAgICBpZiAoc2JyRWxlbWVudEJpdFJhdGVJbiA8IHNickJpdFJhdGVPdXQpIHsKICAgICAgICAgICAgYWRqdXN0ZWRCaXRyYXRlID0gZk1heChpbml0aWFsQml0cmF0ZSwgKElOVClmRGl2Tm9ybSgoRklYUF9EQkwpKHNickJpdFJhdGVPdXQrOCksIGNtLmVsSW5mb1tlXS5yZWxhdGl2ZUJpdHMpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CgogICAgICAgICAgaWYgKHNickVsZW1lbnRCaXRSYXRlSW4gPiBzYnJCaXRSYXRlT3V0KSB7CiAgICAgICAgICAgIGFkanVzdGVkQml0cmF0ZSA9IGZNaW4oaW5pdGlhbEJpdHJhdGUsIChJTlQpZkRpdk5vcm0oKEZJWFBfREJMKShzYnJCaXRSYXRlT3V0LTgpLCBjbS5lbEluZm9bZV0ucmVsYXRpdmVCaXRzKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQoKICAgICAgICB9IC8qIHNickVsZW1lbnRCaXRSYXRlSW4gIT0gc2JyQml0UmF0ZU91dCAqLwoKICAgICAgfSAvKiBlbGVtZW50cyAqLwoKICAgICAgbnVtSXRlcmF0aW9ucysrOyAvKiByZXN0cmljdCBpdGVyYXRpb24gdG8gd29yc3QgY2FzZSBvZiBudW0gZWxlbWVudHMgKi8KCiAgICB9IHdoaWxlICggKGluaXRpYWxCaXRyYXRlIT1hZGp1c3RlZEJpdHJhdGUpICYmIChudW1JdGVyYXRpb25zPD1jbS5uRWxlbWVudHMpICk7CgogICAgLyogVW5lcXVhbCBiaXRyYXRlcyBtZWFuIHRoYXQgbm8gcmVhc29uYWJsZSBiaXRyYXRlIGNvbmZpZ3VyYXRpb24gZm91bmQuICovCiAgICBiaXRSYXRlID0gKGluaXRpYWxCaXRyYXRlPT1hZGp1c3RlZEJpdHJhdGUpID8gYWRqdXN0ZWRCaXRyYXRlIDogMDsKICB9CgogIEZES19BU1NFUlQoYml0UmF0ZSA+IDApOwoKICByZXR1cm4gYml0UmF0ZTsKfQoKLyoKICogXGJyaWVmIENvbnNpc3RlbmN5IGNoZWNrIG9mIGdpdmVuIFVTRVJfUEFSQU0gc3RydWN0IGFuZAogKiAgIGNvcHkgYmFjayBjb25maWd1cmF0aW9uIGZyb20gcHVibGljIHN0cnVjdCBpbnRvIGludGVybmFsCiAqICAgZW5jb2RlciBjb25maWd1cmF0aW9uIHN0cnVjdC4KICoKICogXGhBYWNFbmNvZGVyIEludGVybmFsIGVuY29kZXIgY29uZmlnIHdoaWNoIGlzIHRvIGJlIHVwZGF0ZWQKICogXHBhcmFtIGNvbmZpZyBVc2VyIHByb3ZpZGVkIGNvbmZpZyAocHVibGljIHN0cnVjdCkKICogXHJldHVybiC0cmV0dXJucyBhbHdheXMgQUFDX0VOQ19PSwogKi8Kc3RhdGljCkFBQ0VOQ19FUlJPUiBGREthYWNFbmNfQWRqdXN0RW5jU2V0dGluZ3MoSEFORExFX0FBQ0VOQ09ERVIgaEFhY0VuY29kZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVNFUl9QQVJBTSAqY29uZmlnKQp7CiAgICBBQUNFTkNfRVJST1IgZXJyID0gQUFDRU5DX09LOwoKICAgIC8qIEdldCBzdHJ1Y3QgcG9pbnRlcnMuICovCiAgICBIQU5ETEVfQUFDRU5DX0NPTkZJRyAgICBoQWFjQ29uZmlnID0gJmhBYWNFbmNvZGVyLT5hYWNDb25maWc7CgogICAgaEFhY0NvbmZpZy0+bkNoYW5uZWxzICAgICAgID0gY29uZmlnLT5uQ2hhbm5lbHM7CgogICAgLyogRW5jb2RlciBzZXR0aW5ncyB1cGRhdGUuICovCiAgICBoQWFjQ29uZmlnLT5zYW1wbGVSYXRlICAgICAgPSBjb25maWctPnVzZXJTYW1wbGVyYXRlOwogICAgaEFhY0NvbmZpZy0+dXNlVG5zICAgICAgICAgID0gY29uZmlnLT51c2VyVG5zOwogICAgaEFhY0NvbmZpZy0+dXNlUG5zICAgICAgICAgID0gY29uZmlnLT51c2VyUG5zOwogICAgaEFhY0NvbmZpZy0+dXNlSVMgICAgICAgICAgID0gY29uZmlnLT51c2VySW50ZW5zaXR5OwogICAgaEFhY0NvbmZpZy0+Yml0UmF0ZSAgICAgICAgID0gY29uZmlnLT51c2VyQml0cmF0ZTsKICAgIGhBYWNDb25maWctPmNoYW5uZWxNb2RlICAgICA9IGNvbmZpZy0+dXNlckNoYW5uZWxNb2RlOwogICAgaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGUgICAgID0gY29uZmlnLT51c2VyQml0cmF0ZU1vZGU7CiAgICBoQWFjQ29uZmlnLT5iYW5kV2lkdGggICAgICAgPSBjb25maWctPnVzZXJCYW5kd2lkdGg7CiAgICBoQWFjQ29uZmlnLT51c2VSZXF1YW50ICAgICAgPSBjb25maWctPnVzZXJBZnRlcmJ1cm5lcjsKCiAgICBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUgPSBjb25maWctPnVzZXJBT1Q7CiAgICBoQWFjQ29uZmlnLT5hbmNfUmF0ZSAgICAgICAgPSBjb25maWctPnVzZXJBbmNEYXRhUmF0ZTsKICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzICAgICA9IDA7CiAgICBoQWFjQ29uZmlnLT5lcENvbmZpZyAgICAgICAgPSAtMTsKCiAgICAvKiBBZGFwdCBpbnRlcm5hbCBBT1Qgd2hlbiBuZWNlc3NhcnkuICovCiAgICBzd2l0Y2ggKCBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUgKSB7CiAgICAgIGNhc2UgQU9UX01QMl9BQUNfTEM6CiAgICAgIGNhc2UgQU9UX01QMl9TQlI6CiAgICAgIGNhc2UgQU9UX01QMl9QUzoKICAgICAgICAgIGhBYWNDb25maWctPnVzZVBucyA9IDA7CiAgICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgICAgY2FzZSBBT1RfU0JSOgogICAgICBjYXNlIEFPVF9QUzoKICAgICAgICAgIGNvbmZpZy0+dXNlclRwVHlwZSA9IChjb25maWctPnVzZXJUcFR5cGUhPVRUX1VOS05PV04pID8gY29uZmlnLT51c2VyVHBUeXBlIDogVFRfTVA0X0FEVFM7CiAgICAgICAgICBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCA9IChjb25maWctPnVzZXJGcmFtZWxlbmd0aCE9KFVJTlQpLTEpID8gY29uZmlnLT51c2VyRnJhbWVsZW5ndGggOiAxMDI0OwogICAgICAgICAgaWYgKGhBYWNDb25maWctPmZyYW1lbGVuZ3RoICE9IDEwMjQpIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOwogICAgICBjYXNlIEFPVF9FUl9BQUNfTEQ6CiAgICAgICAgICBoQWFjQ29uZmlnLT5lcENvbmZpZyA9IDA7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSBBQ19FUnxBQ19MRDsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9ICgoY29uZmlnLT51c2VyRXJUb29scyAmIDB4MSkgPyBBQ19FUl9WQ0IxMSA6IDApOwogICAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gKChjb25maWctPnVzZXJFclRvb2xzICYgMHgyKSA/IEFDX0VSX0hDUiA6IDApOwogICAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gKChjb25maWctPnVzZXJFclRvb2xzICYgMHg0KSA/IEFDX0VSX1JWTEMgOiAwKTsKICAgICAgICAgIGNvbmZpZy0+dXNlclRwVHlwZSA9IChjb25maWctPnVzZXJUcFR5cGUhPVRUX1VOS05PV04pID8gY29uZmlnLT51c2VyVHBUeXBlIDogVFRfTVA0X0xPQVM7CiAgICAgICAgICBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCA9IChjb25maWctPnVzZXJGcmFtZWxlbmd0aCE9KFVJTlQpLTEpID8gY29uZmlnLT51c2VyRnJhbWVsZW5ndGggOiA1MTI7CiAgICAgICAgICBpZiAoaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGggIT0gNTEyICYmIGhBYWNDb25maWctPmZyYW1lbGVuZ3RoICE9IDQ4MCkgewogICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICAgICAgICBoQWFjQ29uZmlnLT5lcENvbmZpZyA9IDA7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSBBQ19FUnxBQ19FTEQ7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSAoKGNvbmZpZy0+dXNlckVyVG9vbHMgJiAweDEpID8gQUNfRVJfVkNCMTEgOiAwKTsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9ICgoY29uZmlnLT51c2VyRXJUb29scyAmIDB4MikgPyBBQ19FUl9IQ1IgOiAwKTsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9ICgoY29uZmlnLT51c2VyRXJUb29scyAmIDB4NCkgPyBBQ19FUl9SVkxDIDogMCk7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSAoKGNvbmZpZy0+dXNlclNickVuYWJsZWQ9PTEpICA/IEFDX1NCUl9QUkVTRU5UIDogMCk7CiAgICAgICAgICBjb25maWctPnVzZXJUcFR5cGUgPSAoY29uZmlnLT51c2VyVHBUeXBlIT1UVF9VTktOT1dOKSA/IGNvbmZpZy0+dXNlclRwVHlwZSA6IFRUX01QNF9MT0FTOwogICAgICAgICAgaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGggPSAoY29uZmlnLT51c2VyRnJhbWVsZW5ndGghPShVSU5UKS0xKSA/IGNvbmZpZy0+dXNlckZyYW1lbGVuZ3RoIDogNTEyOwogICAgICAgICAgaWYgKGhBYWNDb25maWctPmZyYW1lbGVuZ3RoICE9IDUxMiAmJiBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCAhPSA0ODApIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgc3dpdGNoICggaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlICkgewogICAgICBjYXNlIEFPVF9FUl9BQUNfTEQ6CiAgICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICAgICAgaWYgKGNvbmZpZy0+dXNlckJpdHJhdGVNb2RlPT04KSB7CiAgICAgICAgICBoQWFjQ29uZmlnLT5iaXRyYXRlTW9kZSA9IDA7CiAgICAgICAgfQogICAgICAgIGlmIChjb25maWctPnVzZXJCaXRyYXRlTW9kZT09MCkgewogICAgICAgICAgaEFhY0NvbmZpZy0+Yml0cmVzZXJ2b2lyID0gMTAwKmNvbmZpZy0+bkNoYW5uZWxzOyAvKiBkZWZhdWx0LCByZWR1Y2VkIGJpdHJlc2Vydm9pciAqLwogICAgICAgIH0KICAgICAgICBpZiAoaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGUhPTApIHsKICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGhBYWNDb25maWctPmJpdFJhdGUgPSBjb25maWctPnVzZXJCaXRyYXRlOwoKICAgIC8qIGdldCBiaXRyYXRlIGluIFZCUiBjb25maWd1cmF0aW9uICovCiAgICBpZiAoIChoQWFjQ29uZmlnLT5iaXRyYXRlTW9kZT49MSkgJiYgKGhBYWNDb25maWctPmJpdHJhdGVNb2RlPD01KSApIHsKICAgICAgICAvKiBJbiBWQlIgbW9kZTsgU0JSLW1vZHVsIGRlcGVuZHMgb24gYml0cmF0ZSwgY29yZSBlbmNvZGVyIG9uIGJpdHJhdGVNb2RlLiAqLwogICAgICAgIGhBYWNDb25maWctPmJpdFJhdGUgPSBGREthYWNFbmNfR2V0VkJSQml0cmF0ZShoQWFjQ29uZmlnLT5iaXRyYXRlTW9kZSwgaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUpOwogICAgfQoKCgogICAgLyogU2V0IGRlZmF1bHQgYml0cmF0ZSBpZiBubyBleHRlcm5hbCBiaXRyYXRlIGRlY2xhcmVkLiAqLwogICAgaWYgKCAoaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGU9PTApICYmIChjb25maWctPnVzZXJCaXRyYXRlPT0oVUlOVCktMSkgKSB7CiAgICAgICAgSU5UIGJpdHJhdGUgPSBGREthYWNFbmNfR2V0Q2hhbm5lbE1vZGVDb25maWd1cmF0aW9uKGhBYWNDb25maWctPmNoYW5uZWxNb2RlKS0+bkNoYW5uZWxzRWZmICogaEFhY0NvbmZpZy0+c2FtcGxlUmF0ZTsKCiAgICAgICAgaWYgKCBpc1BzQWN0aXZlKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSkgKSB7CiAgICAgICAgICBoQWFjQ29uZmlnLT5iaXRSYXRlID0gKGJpdHJhdGU+PjEpOyAgICAgICAgICAgICAgICAgIC8qIDAuNSBiaXQgcGVyIHNhbXBsZSAqLwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICggaXNTYnJBY3RpdmUoaEFhY0NvbmZpZykgKQogICAgICAgIHsKICAgICAgICAgIGlmICggKGNvbmZpZy0+dXNlclNiclJhdGlvPT0yKSB8fCAoKGNvbmZpZy0+dXNlclNiclJhdGlvPT0wKSYmKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSE9QU9UX0VSX0FBQ19FTEQpKSApIHsKICAgICAgICAgICAgaEFhY0NvbmZpZy0+Yml0UmF0ZSA9IChiaXRyYXRlICsgKGJpdHJhdGU+PjIpKT4+MTsgLyogMC42MjUgYml0cyBwZXIgc2FtcGxlICovCiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIChjb25maWctPnVzZXJTYnJSYXRpbz09MSkgfHwgKChjb25maWctPnVzZXJTYnJSYXRpbz09MCkmJihoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9FUl9BQUNfRUxEKSkgKSB7CiAgICAgICAgICAgIGhBYWNDb25maWctPmJpdFJhdGUgPSAoYml0cmF0ZSArIChiaXRyYXRlPj4zKSk7ICAgIC8qIDEuMTI1IGJpdHMgcGVyIHNhbXBsZSAqLwogICAgICAgICAgfQogICAgICAgIH0gZWxzZQogICAgICAgIHsKICAgICAgICAgICAgICAgIGhBYWNDb25maWctPmJpdFJhdGUgPSBiaXRyYXRlICsgKGJpdHJhdGU+PjEpOyAgICAgICAgLyogMS41IGJpdHMgcGVyIHNhbXBsZSAqLwogICAgICAgIH0KICAgIH0KCiAgICAvKiBJbml0aWFsaXplIFNCUiBwYXJhbWV0ZXJzICovCiAgICBpZiAoIChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9FUl9BQUNfRUxEKQogICAgICAmJiAoY29uZmlnLT51c2VyU2JyRW5hYmxlZCA9PSAoVUNIQVIpLTEpICYmIChjb25maWctPnVzZXJTYnJSYXRpbz09MCkgKQogICAgewogICAgICBVSU5UIGVsZFNiciA9IDA7CiAgICAgIFVJTlQgZWxkU2JyUmF0aW8gPSAwOwoKICAgICAgaWYgKCBBQUNFTkNfT0shPShlcnI9ZWxkU2JyQ29uZmlndXJhdG9yKAogICAgICAgICAgICBoQWFjQ29uZmlnLT5zYW1wbGVSYXRlLAogICAgICAgICAgICBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSwKICAgICAgICAgICAgaEFhY0NvbmZpZy0+Yml0UmF0ZSwKICAgICAgICAgICAmZWxkU2JyLAogICAgICAgICAgICZlbGRTYnJSYXRpbykpICkKICAgICAgewogICAgICAgIHJldHVybiBlcnI7CiAgICAgIH0KCiAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9ICgoZWxkU2JyKSA/IEFDX1NCUl9QUkVTRU5UIDogMCk7CiAgICAgIGhBYWNDb25maWctPnNiclJhdGlvID0gZWxkU2JyUmF0aW87CiAgICB9CiAgICBlbHNlCiAgICBpZiAoIChjb25maWctPnVzZXJTYnJSYXRpbz09MCkgJiYgKGlzU2JyQWN0aXZlKGhBYWNDb25maWcpKSApIHsKICAgICAgLyogQXV0b21hdGljIFNCUiByYXRpbyBjb25maWd1cmF0aW9uCiAgICAgICAqIC0gZG93bnNhbXBsZWQgU0JSIGZvciBFTEQKICAgICAgICogLSBvdGhlcndpc2UgYWx3YXlzIGR1YWxyYXRlIFNCUgogICAgICAgKi8KICAgICAgICBoQWFjQ29uZmlnLT5zYnJSYXRpbyA9IChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9FUl9BQUNfRUxEKSA/IDEgOiAyOwogICAgfQogICAgZWxzZSB7CiAgICAgIC8qIFNCUiByYXRpbyBoYXMgYmVlbiBzZXQgYnkgdGhlIHVzZXIsIHNvIHVzZSBpdC4gKi8KICAgICAgaEFhY0NvbmZpZy0+c2JyUmF0aW8gPSBjb25maWctPnVzZXJTYnJSYXRpbzsKICAgIH0KCiAgICB7CiAgICAgIFVDSEFSIHRwU2lnbmFsaW5nPWdldFNiclNpZ25hbGluZ01vZGUoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlLCBjb25maWctPnVzZXJUcFR5cGUsIGNvbmZpZy0+dXNlclRwU2lnbmFsaW5nLCBoQWFjQ29uZmlnLT5zYnJSYXRpbyk7CgogICAgICBpZiAoIChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9BQUNfTEMgfHwgaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfU0JSIHx8IGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX1BTKSAmJgogICAgICAgICAgIChjb25maWctPnVzZXJUcFR5cGU9PVRUX01QNF9MQVRNX01DUDEgfHwgY29uZmlnLT51c2VyVHBUeXBlPT1UVF9NUDRfTEFUTV9NQ1AwIHx8IGNvbmZpZy0+dXNlclRwVHlwZT09VFRfTVA0X0xPQVMpICYmCiAgICAgICAgICAgKHRwU2lnbmFsaW5nPT0xKSAmJiAoY29uZmlnLT51c2VyVHBBbXh2PT0wKSApIHsKICAgICAgICAgICAgIC8qIEZvciBiYWNrd2FyZCBjb21wYXRpYmxlIGV4cGxpY2l0IHNpZ25hbGluZywgQU1WMSBoYXMgdG8gYmUgYWN0aXZlICovCiAgICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICB9CgogICAgICBpZiAoIChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9BQUNfTEMgfHwgaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfU0JSIHx8IGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX1BTKSAmJgogICAgICAgICAgICh0cFNpZ25hbGluZz09MCkgJiYgKGhBYWNDb25maWctPnNiclJhdGlvPT0xKSkgewogICAgICAgICAgICAgLyogRG93bnNhbXBsZWQgU0JSIGhhcyB0byBiZSBzaWduYWxlZCBleHBsaWNpdGVseSAoZm9yIHRyYW5zbWlzc2lvbiBvZiBTQlIgc2FtcGxpbmcgZmVxdWVuY3kpICovCiAgICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICB9CiAgICB9CgoKCiAgICAvKiBXZSBuZWVkIHRoZSBmcmFtZSBsZW5ndGggdG8gY2FsbCBhYWNFbmNvZGVyX0xpbWl0Qml0cmF0ZSgpICovCiAgICBoQWFjQ29uZmlnLT5iaXRSYXRlID0gYWFjRW5jb2Rlcl9MaW1pdEJpdHJhdGUoCiAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5zYW1wbGVSYXRlLAogICAgICAgICAgICAgIGhBYWNDb25maWctPmZyYW1lbGVuZ3RoLAogICAgICAgICAgICAgIGhBYWNDb25maWctPm5DaGFubmVscywKICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSwKICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5iaXRSYXRlLAogICAgICAgICAgICAgIGhBYWNDb25maWctPm5TdWJGcmFtZXMsCiAgICAgICAgICAgICAgaXNTYnJBY3RpdmUoaEFhY0NvbmZpZyksCiAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+c2JyUmF0aW8sCiAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlCiAgICAgICAgICAgICAgKTsKCiAgICAvKiBDb25maWd1cmUgUE5TICovCiAgICBpZiAoICgoaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGU+PTEpICYmIChoQWFjQ29uZmlnLT5iaXRyYXRlTW9kZTw9NSkpIC8qIFZCUiB3aXRob3V0IFBOUy4gKi8KICAgICAgICB8fCAoaEFhY0NvbmZpZy0+dXNlVG5zID09IDApICkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogVE5TIHJlcXVpcmVkLiAqLwogICAgewogICAgICAgIGhBYWNDb25maWctPnVzZVBucyA9IDA7CiAgICB9CgogICAgaWYgKGhBYWNDb25maWctPmVwQ29uZmlnID49IDApIHsKICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSBBQ19FUjsKICAgICAgICAgaWYgKCgoSU5UKWhBYWNDb25maWctPmNoYW5uZWxNb2RlIDwgMSkgfHwgKChJTlQpaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUgPiA3KSkgewogICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5WQUxJRF9DT05GSUc7ICAgICAgICAvKiBDYW5uZWwgY29uZmlnIDAgbm90IHN1cHBvcnRlZC4gKi8KICAgICAgICAgfQogICAgfQoKICAgIGlmICggRkRLYWFjRW5jX0RldGVybWluZUVuY29kZXJNb2RlKCZoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSwgaEFhY0NvbmZpZy0+bkNoYW5uZWxzKSAhPSBBQUNfRU5DX09LKSB7CiAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsgICAgICAgIC8qIG5DaGFubmVscyBkb2Vzbid0IG1hdGNoIGNoTW9kZSwgdGhpcyBpcyBqdXN0IGEgY2hlY2stdXAgKi8KICAgIH0KCiAgICBpZiAoIChoQWFjQ29uZmlnLT5uQ2hhbm5lbHMgPiBoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzKQogICAgICB8fCAoIChGREthYWNFbmNfR2V0Q2hhbm5lbE1vZGVDb25maWd1cmF0aW9uKGhBYWNDb25maWctPmNoYW5uZWxNb2RlKS0+bkNoYW5uZWxzRWZmID4gaEFhY0VuY29kZXItPm5NYXhTYnJDaGFubmVscykgJiYKICAgICAgICAgICAgaXNTYnJBY3RpdmUoaEFhY0NvbmZpZykgKQogICAgICAgICApCiAgICB7CiAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsgICAgICAvKiBub3QgZW5vdWdoIGNoYW5uZWxzIGFsbG9jYXRlZCAqLwogICAgfQoKICAgIC8qIE1ldGEgZGF0YSByZXN0cmljdGlvbi4gKi8KICAgIHN3aXRjaCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlKQogICAgewogICAgICAvKiBBbGxvdyBtZXRhZGF0YSBzdXBwb3J0ICovCiAgICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgICAgY2FzZSBBT1RfU0JSOgogICAgICBjYXNlIEFPVF9QUzoKICAgICAgICBoQWFjRW5jb2Rlci0+bWV0YURhdGFBbGxvd2VkID0gMTsKICAgICAgICBpZiAoKChJTlQpaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUgPCAxKSB8fCAoKElOVCloQWFjQ29uZmlnLT5jaGFubmVsTW9kZSA+IDcpKSB7CiAgICAgICAgICBjb25maWctPnVzZXJNZXRhRGF0YU1vZGUgPSAwOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgLyogUHJvaGliaXQgbWV0YWRhdGEgc3VwcG9ydCAqLwogICAgICBkZWZhdWx0OgogICAgICAgIGhBYWNFbmNvZGVyLT5tZXRhRGF0YUFsbG93ZWQgPSAwOwogICAgfQoKICAgIHJldHVybiBlcnI7Cn0KCnN0YXRpYwpJTlQgYWFjZW5jX1NickNhbGxiYWNrKAogICAgICAgIHZvaWQgKiAgICAgICAgICAgICAgICAgIHNlbGYsCiAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gICAgaEJzLAogICAgICAgIGNvbnN0IElOVCBzYW1wbGVSYXRlSW4sCiAgICAgICAgY29uc3QgSU5UIHNhbXBsZVJhdGVPdXQsCiAgICAgICAgY29uc3QgSU5UIHNhbXBsZXNQZXJGcmFtZSwKICAgICAgICBjb25zdCBBVURJT19PQkpFQ1RfVFlQRSBjb3JlQ29kZWMsCiAgICAgICAgY29uc3QgTVA0X0VMRU1FTlRfSUQgICAgZWxlbWVudElELAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgIGVsZW1lbnRJbmRleAogICAgICAgICkKewogIEhBTkRMRV9BQUNFTkNPREVSIGhBYWNFbmNvZGVyID0gKEhBTkRMRV9BQUNFTkNPREVSKXNlbGY7CgogIHNickVuY29kZXJfR2V0SGVhZGVyKGhBYWNFbmNvZGVyLT5oRW52RW5jLCBoQnMsIGVsZW1lbnRJbmRleCwgMCk7CgogIHJldHVybiAwOwp9CgpzdGF0aWMgQUFDRU5DX0VSUk9SIGFhY0VuY0luaXQoSEFORExFX0FBQ0VOQ09ERVIgIGhBYWNFbmNvZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgICAgICAgICAgICAgIEluaXRGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTRVJfUEFSQU0gICAgICAgICpjb25maWcpCnsKICAgIEFBQ0VOQ19FUlJPUiBlcnIgPSBBQUNFTkNfT0s7CgogICAgSU5UIGFhY0J1ZmZlck9mZnNldCA9IDA7CiAgICBIQU5ETEVfU0JSX0VOQ09ERVIgICAgICpoU2JyRW5jb2RlciA9ICZoQWFjRW5jb2Rlci0+aEVudkVuYzsKICAgIEhBTkRMRV9BQUNFTkNfQ09ORklHICAgIGhBYWNDb25maWcgID0gJmhBYWNFbmNvZGVyLT5hYWNDb25maWc7CgogICAgaEFhY0VuY29kZXItPm5aZXJvc0FwcGVuZGVkID0gMDsgICAgICAgICAgLyogY291bnQgYXBwZW5kZWQgemVyb3MgKi8KCiAgICBJTlQgZnJhbWVMZW5ndGggPSBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aDsKCiAgICBpZiAoIChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9DT05GSUcpICkKICAgIHsKICAgICAgICBDSEFOTkVMX01PREUgcHJldkNoTW9kZSA9IGhBYWNDb25maWctPmNoYW5uZWxNb2RlOwoKICAgICAgICAvKiBWZXJpZnkgc2V0dGluZ3MgYW5kIHVwZGF0ZTogY29uZmlnIC0+IGhlQWFjRW5jb2RlciAqLwogICAgICAgIGlmICggKGVycj1GREthYWNFbmNfQWRqdXN0RW5jU2V0dGluZ3MoaEFhY0VuY29kZXIsIGNvbmZpZykpICE9IEFBQ0VOQ19PSyApIHsKICAgICAgICAgICAgcmV0dXJuIGVycjsKICAgICAgICB9CiAgICAgICAgZnJhbWVMZW5ndGggPSBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aDsgLyogYWRhcHQgdGVtcG9yYWwgZnJhbWVsZW5ndGggKi8KCiAgICAgICAgLyogU2VhbWxlc3MgY2hhbm5lbCByZWNvbmZpZ3VyYXRpb24gaW4gc2JyIG5vdCBmdWxseSBpbXBsZW1lbnRlZCAqLwogICAgICAgIGlmICggKHByZXZDaE1vZGUhPWhBYWNDb25maWctPmNoYW5uZWxNb2RlKSAmJiBpc1NickFjdGl2ZShoQWFjQ29uZmlnKSApIHsKICAgICAgICAgICAgSW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX1NUQVRFUzsKICAgICAgICB9CiAgICB9CgogICAgLyogQ2xlYXIgaW5wdXQgYnVmZmVyICovCiAgICBpZiAoIChJbml0RmxhZ3MgPT0gQUFDRU5DX0lOSVRfQUxMKSApIHsKICAgICAgICBGREttZW1jbGVhcihoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIsIHNpemVvZihJTlRfUENNKSpoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzKklOUFVUQlVGRkVSX1NJWkUpOwogICAgfQoKICAgIGlmICggKEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX0NPTkZJRykgKQogICAgewogICAgICAgIGFhY0J1ZmZlck9mZnNldCA9IDA7CiAgICAgICAgaWYgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSA9PSBBT1RfRVJfQUFDX0VMRCkgewogICAgICAgICAgICBoQWFjRW5jb2Rlci0+bkRlbGF5ID0gREVMQVlfQUFDRUxEKGhBYWNDb25maWctPmZyYW1lbGVuZ3RoKTsKICAgICAgICB9IGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uRGVsYXkgPSBERUxBWV9BQUMoaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGgpOyAvKiBBQUMgZW5jb2RlciBkZWxheSAqLwogICAgICAgIH0KICAgICAgICBoQWFjQ29uZmlnLT5hbmNEYXRhQml0UmF0ZSA9IDA7CiAgICB9CgogICAgaWYgKCBpc1NickFjdGl2ZShoQWFjQ29uZmlnKSAmJgogICAgICAgICgoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfQ09ORklHKSB8fCAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfU1RBVEVTKSkgKQogICAgewogICAgICAgIElOVCBzYnJFcnJvcjsKICAgICAgICBTQlJfRUxFTUVOVF9JTkZPIHNickVsSW5mb1soOCldOwogICAgICAgIENIQU5ORUxfTUFQUElORyBjaGFubmVsTWFwcGluZzsKCiAgICAgICAgaWYgKCBGREthYWNFbmNfSW5pdENoYW5uZWxNYXBwaW5nKGhBYWNDb25maWctPmNoYW5uZWxNb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5jaGFubmVsT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNoYW5uZWxNYXBwaW5nKSAhPSBBQUNfRU5DX09LICkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5JVF9FUlJPUjsKICAgICAgICB9CgogICAgICAgIC8qIENoZWNrIHJldHVybiB2YWx1ZSBhbmQgaWYgdGhlIFNCUiBlbmNvZGVyIGNhbiBoYW5kbGUgZW5vdWdoIGVsZW1lbnRzICovCiAgICAgICAgaWYgKGNoYW5uZWxNYXBwaW5nLm5FbGVtZW50cyA+ICg4KSkgewogICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOSVRfRVJST1I7CiAgICAgICAgfQoKICAgICAgICBhYWNFbmNEaXN0cmlidXRlU2JyQml0cygmY2hhbm5lbE1hcHBpbmcsIHNickVsSW5mbywgaEFhY0NvbmZpZy0+Yml0UmF0ZSk7CgogICAgICAgIFVJTlQgaW5pdEZsYWcgPSAwOwogICAgICAgIGluaXRGbGFnICs9IChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9TVEFURVMpID8gMSA6IDA7CgogICAgICAgIC8qIExldCB0aGUgU0JSIGVuY29kZXIgdGFrZSBhIGxvb2sgYXQgdGhlIGNvbmZpZ3VyYXRpb24gYW5kIGNoYW5nZSBpZiByZXF1aXJlZC4gKi8KICAgICAgICBzYnJFcnJvciA9IHNickVuY29kZXJfSW5pdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqaFNickVuY29kZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNickVsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbE1hcHBpbmcubkVsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmhBYWNDb25maWctPmJhbmRXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYWFjQnVmZmVyT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoQWFjQ29uZmlnLT5uQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmhBYWNDb25maWctPnNhbXBsZVJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmhBYWNDb25maWctPnNiclJhdGlvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmcmFtZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoQWFjRW5jb2Rlci0+bkRlbGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlID09IEFPVF9FUl9BQUNfRUxEKSA/IDEgOiBUUkFOU19GQUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb25maWctPnVzZXJUcEhlYWRlclBlcmlvZCE9MHhGRikgPyBjb25maWctPnVzZXJUcEhlYWRlclBlcmlvZCA6IERFRkFVTFRfSEVBREVSX1BFUklPRF9SRVBFVElUSU9OX1JBVEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaXRGbGFnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgLyogU3VwcHJlc3MgQU9UIHJlY29uZmlndXJhdGlvbiBhbmQgY2hlY2sgZXJyb3Igc3RhdHVzLiAqLwogICAgICAgIGlmIChzYnJFcnJvcikgewogICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOSVRfU0JSX0VSUk9SOwogICAgICAgIH0KCiAgICAgICAgaWYgKGhBYWNDb25maWctPm5DaGFubmVscyA9PSAxKSB7CiAgICAgICAgICAgIGhBYWNDb25maWctPmNoYW5uZWxNb2RlID0gTU9ERV8xOwogICAgICAgIH0KCiAgICAgICAgLyogTmV2ZXIgdXNlIFBOUyBpZiBTQlIgaXMgYWN0aXZlICovCiAgICAgICAgaWYgKCBoQWFjQ29uZmlnLT51c2VQbnMgKSB7CiAgICAgICAgICAgaEFhY0NvbmZpZy0+dXNlUG5zID0gMDsKICAgICAgICB9CgogICAgICAgIC8qIGVzdGltYXRlZCBiaXRyYXRlIGNvbnN1bWVkIGJ5IFNCUiBvciBQUyAqLwogICAgICAgIGhBYWNDb25maWctPmFuY0RhdGFCaXRSYXRlID0gc2JyRW5jb2Rlcl9HZXRFc3RpbWF0ZUJpdHJhdGUoKmhTYnJFbmNvZGVyKSA7CgogICAgfSAvKiBzYnIgaW5pdGlhbGl6YXRpb24gKi8KCgogICAgLyoKICAgICAqIEluaXRpYWxpemUgVHJhbnNwb3J0IC0gTW9kdWxlLgogICAgICovCiAgICBpZiAoIChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9UUkFOU1BPUlQpICkKICAgIHsKICAgICAgICBVSU5UIGZsYWdzID0gMDsKCiAgICAgICAgRkRLYWFjRW5jX01hcENvbmZpZygKICAgICAgICAgICAgICAgICZoQWFjRW5jb2Rlci0+Y29kZXJDb25maWcsCiAgICAgICAgICAgICAgICBjb25maWcsCiAgICAgICAgICAgICAgICBnZXRTYnJTaWduYWxpbmdNb2RlKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSwgY29uZmlnLT51c2VyVHBUeXBlLCBjb25maWctPnVzZXJUcFNpZ25hbGluZywgaEFhY0NvbmZpZy0+c2JyUmF0aW8pLAogICAgICAgICAgICAgICAgaEFhY0NvbmZpZyk7CgogICAgICAgIC8qIGNyZWF0ZSBmbGFncyBmb3IgdHJhbnNwb3J0IGVuY29kZXIgKi8KICAgICAgICBpZiAoY29uZmlnLT51c2VyVHBBbXh2ID09IDEpIHsKICAgICAgICAgICAgZmxhZ3MgfD0gVFBfRkxBR19MQVRNX0FNVjsKICAgICAgICB9CiAgICAgICAgLyogQ2xlYXIgb3V0cHV0IGJ1ZmZlciAqLwogICAgICAgIEZES21lbWNsZWFyKGhBYWNFbmNvZGVyLT5vdXRCdWZmZXIsIGhBYWNFbmNvZGVyLT5vdXRCdWZmZXJJbkJ5dGVzKnNpemVvZihVQ0hBUikpOwoKICAgICAgICAvKiBJbml0aWFsaXplIEJpdHN0cmVhbSBlbmNvZGVyICovCiAgICAgICAgaWYgKCB0cmFuc3BvcnRFbmNfSW5pdChoQWFjRW5jb2Rlci0+aFRwRW5jLCBoQWFjRW5jb2Rlci0+b3V0QnVmZmVyLCBoQWFjRW5jb2Rlci0+b3V0QnVmZmVySW5CeXRlcywgY29uZmlnLT51c2VyVHBUeXBlLCAmaEFhY0VuY29kZXItPmNvZGVyQ29uZmlnLCBmbGFncykgIT0gMCkgewogICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOSVRfVFBfRVJST1I7CiAgICAgICAgfQoKICAgIH0gLyogdHJhbnNwb3J0IGluaXRpYWxpemF0aW9uICovCgogICAgLyoKICAgICAqIEluaXRpYWxpemUgQUFDIC0gQ29yZS4KICAgICAqLwogICAgaWYgKCAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfQ09ORklHKSB8fAogICAgICAgICAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfU1RBVEVTKSApCiAgICB7CiAgICAgICAgQUFDX0VOQ09ERVJfRVJST1IgZXJyOwogICAgICAgIGVyciA9IEZES2FhY0VuY19Jbml0aWFsaXplKGhBYWNFbmNvZGVyLT5oQWFjRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmhUcEVuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfU1RBVEVTKSA/IDEgOiAwKTsKCiAgICAgICAgaWYgKGVyciAhPSBBQUNfRU5DX09LKSB7CiAgICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5JVF9BQUNfRVJST1I7CiAgICAgICAgfQoKICAgIH0gLyogYWFjIGluaXRpYWxpemF0aW9uICovCgogICAgLyoKICAgICAqIEluaXRpYWxpemUgTWV0YSBEYXRhIC0gRW5jb2Rlci4KICAgICAqLwogICAgaWYgKCBoQWFjRW5jb2Rlci0+aE1ldGFkYXRhRW5jICYmIChoQWFjRW5jb2Rlci0+bWV0YURhdGFBbGxvd2VkIT0wKSAmJgogICAgICAgICgoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfQ09ORklHKSB8fChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9TVEFURVMpKSApCiAgICB7CiAgICAgICAgSU5UIGlucHV0RGF0YURlbGF5ID0gREVMQVlfQUFDKGhBYWNDb25maWctPmZyYW1lbGVuZ3RoKTsKCiAgICAgICAgaWYgKCBpc1NickFjdGl2ZShoQWFjQ29uZmlnKSAmJiBoU2JyRW5jb2RlciE9TlVMTCkgewogICAgICAgICAgaW5wdXREYXRhRGVsYXkgPSBoQWFjQ29uZmlnLT5zYnJSYXRpbyppbnB1dERhdGFEZWxheSArIHNickVuY29kZXJfR2V0SW5wdXREYXRhRGVsYXkoKmhTYnJFbmNvZGVyKTsKICAgICAgICB9CgogICAgICAgIGlmICggRkRLX01ldGFkYXRhRW5jX0luaXQoaEFhY0VuY29kZXItPmhNZXRhZGF0YUVuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChJbml0RmxhZ3MmQUFDRU5DX0lOSVRfU1RBVEVTKSA/IDEgOiAwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+dXNlck1ldGFEYXRhTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0RGF0YURlbGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWVMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWctPnVzZXJTYW1wbGVyYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT5uQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWctPnVzZXJDaGFubmVsTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNDb25maWctPmNoYW5uZWxPcmRlcikgIT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5JVF9NRVRBX0VSUk9SOwogICAgICAgIH0KCiAgICAgICAgaEFhY0VuY29kZXItPm5EZWxheSArPSBGREtfTWV0YWRhdGFFbmNfR2V0RGVsYXkoaEFhY0VuY29kZXItPmhNZXRhZGF0YUVuYyk7CiAgICB9CgogICAgLyoKICAgICAqIFVwZGF0ZSBwb2ludGVyIHRvIHdvcmtpbmcgYnVmZmVyLgogICAgICovCiAgICBpZiAoIChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9DT05GSUcpICkKICAgIHsKICAgICAgICBoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXJPZmZzZXQgPSBhYWNCdWZmZXJPZmZzZXQ7CgogICAgICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1RvUmVhZCA9IGZyYW1lTGVuZ3RoICogY29uZmlnLT5uQ2hhbm5lbHM7CgogICAgICAgIC8qIE1ha2UgbkRlbGF5IGNvbXBhcmlzb24gY29tcGF0aWJsZSB3aXRoIGNvbmZpZy0+blNhbXBsZXNSZWFkICovCiAgICAgICAgaEFhY0VuY29kZXItPm5EZWxheSAqPSBjb25maWctPm5DaGFubmVsczsKCiAgICB9IC8qIHBhcmFtZXRlciBjaGFuZ2VkICovCgogICAgcmV0dXJuIEFBQ0VOQ19PSzsKfQoKCkFBQ0VOQ19FUlJPUiBhYWNFbmNPcGVuKAogICAgICAgIEhBTkRMRV9BQUNFTkNPREVSICAgICAgICAqcGhBYWNFbmNvZGVyLAogICAgICAgIGNvbnN0IFVJTlQgICAgICAgICAgICAgICAgZW5jTW9kdWxlcywKICAgICAgICBjb25zdCBVSU5UICAgICAgICAgICAgICAgIG1heENoYW5uZWxzCiAgICAgICAgKQp7CiAgICBBQUNFTkNfRVJST1IgZXJyID0gQUFDRU5DX09LOwogICAgSEFORExFX0FBQ0VOQ09ERVIgIGhBYWNFbmNvZGVyID0gTlVMTDsKCiAgICBpZiAocGhBYWNFbmNvZGVyID09IE5VTEwpIHsKICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9IQU5ETEU7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIC8qIGFsbG9jYXRlIG1lbW9yeSAqLwogICAgaEFhY0VuY29kZXIgPSBHZXRfQWFjRW5jb2RlcigpOwoKICAgIGlmIChoQWFjRW5jb2RlciA9PSBOVUxMKSB7CiAgICAgICAgZXJyID0gQUFDRU5DX01FTU9SWV9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgRkRLbWVtY2xlYXIoaEFhY0VuY29kZXIsIHNpemVvZihBQUNFTkNPREVSKSk7CgogICAgLyogU3BlY2lmeSBlbmNvZGVyIG1vZHVsZXMgdG8gYmUgYWxsb2NhdGVkLiAqLwogICAgaWYgKGVuY01vZHVsZXM9PTApIHsKICAgICAgICBoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyA9IEVOQ19NT0RFX0ZMQUdfQUFDOwogICAgICAgIGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzIHw9IEVOQ19NT0RFX0ZMQUdfU0JSOwogICAgICAgIGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzIHw9IEVOQ19NT0RFX0ZMQUdfUFM7CiAgICAgICAgaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMgfD0gRU5DX01PREVfRkxBR19NRVRBOwogICAgfQogICAgZWxzZSB7CiAgICAgICAvKiBjb25zaWRlciBTQUMgYW5kIFBTIG1vZHVsZSAqLwogICAgICAgIGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzID0gZW5jTW9kdWxlczsKICAgIH0KCiAgICAvKiBEZXRlcm1pbmUgbWF4IGNoYW5uZWwgY29uZmlndXJhdGlvbi4gKi8KICAgIGlmIChtYXhDaGFubmVscz09MCkgewogICAgICAgIGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMgPSAoOCk7CiAgICAgICAgaEFhY0VuY29kZXItPm5NYXhTYnJDaGFubmVscyA9ICg4KTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMgPSAobWF4Q2hhbm5lbHMmMHgwMEZGKTsKICAgICAgICBpZiAoIChoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyZFTkNfTU9ERV9GTEFHX1NCUikgKSB7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uTWF4U2JyQ2hhbm5lbHMgPSAobWF4Q2hhbm5lbHMmMHhGRjAwKSA/IChtYXhDaGFubmVscz4+OCkgOiBoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzOwogICAgICAgIH0KCiAgICAgICAgaWYgKCAoaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscz4oOCkpIHx8IChoQWFjRW5jb2Rlci0+bk1heFNickNoYW5uZWxzPig4KSkgKSB7CiAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgIH0KICAgIH0gLyogbWF4Q2hhbm5lbHM9PTAgKi8KCiAgICAvKiBNYXggbnVtYmVyIG9mIGVsZW1lbnRzIGNvdWxkIGJlIHR1bmVkIGFueSBtb3JlLiAqLwogICAgaEFhY0VuY29kZXItPm5NYXhBYWNFbGVtZW50cyA9IGZpeE1pbigoOCksIGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMpOwogICAgaEFhY0VuY29kZXItPm5NYXhTYnJFbGVtZW50cyA9IGZpeE1pbigoOCksIGhBYWNFbmNvZGVyLT5uTWF4U2JyQ2hhbm5lbHMpOwogICAgaEFhY0VuY29kZXItPm5NYXhTdWJGcmFtZXMgPSAoMSk7CgoKICAgIC8qIEluIGNhc2Ugb2YgbWVtb3J5IG92ZXJsYXksIGFsbG9jYXRlIG1lbW9yeSBvdXQgb2YgbGlicmFyaWVzICovCgogICAgaEFhY0VuY29kZXItPmlucHV0QnVmZmVyID0gKElOVF9QQ00qKUZES2NhbGxvYyhoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzKklOUFVUQlVGRkVSX1NJWkUsIHNpemVvZihJTlRfUENNKSk7CgogICAgLyogT3BlbiBTQlIgRW5jb2RlciAqLwogICAgaWYgKGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzJkVOQ19NT0RFX0ZMQUdfU0JSKSB7CiAgICAgICAgaWYgKCBzYnJFbmNvZGVyX09wZW4oJmhBYWNFbmNvZGVyLT5oRW52RW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+bk1heFNickVsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+bk1heFNickNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyZFTkNfTU9ERV9GTEFHX1BTKSA/IDEgOiAwICkgKQogICAgICAgIHsKICAgICAgICAgIGVyciA9IEFBQ0VOQ19NRU1PUllfRVJST1I7CiAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgfQogICAgfSAvKiAoZW5jb2Rlcl9tb2RpcyZFTkNfTU9ERV9GTEFHX1NCUikgKi8KCgogICAgLyogT3BlbiBBYWMgRW5jb2RlciAqLwogICAgaWYgKCBGREthYWNFbmNfT3BlbigmaEFhY0VuY29kZXItPmhBYWNFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+bk1heEFhY0VsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICgxKSkgIT0gQUFDX0VOQ19PSyApCiAgICB7CiAgICAgICAgZXJyID0gQUFDRU5DX01FTU9SWV9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgeyAvKiBHZXQgYml0c3RyZWFtIG91dHB1dGJ1ZmZlciBzaXplICovCiAgICAgIFVJTlQgbGRfTTsKICAgICAgZm9yIChsZF9NPTE7IChVSU5UKSgxPDxsZF9NKSA8IChoQWFjRW5jb2Rlci0+bk1heFN1YkZyYW1lcypoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzKjYxNDQpPj4zOyBsZF9NKyspIDsKICAgICAgaEFhY0VuY29kZXItPm91dEJ1ZmZlckluQnl0ZXMgPSAoMTw8bGRfTSk7ICAvKiBidWZmZXIgaGFzIHRvIGJlIDJebiAqLwogICAgfQogICAgaEFhY0VuY29kZXItPm91dEJ1ZmZlciA9IEdldFJhbV9ic091dGJ1ZmZlcigpOwogICAgaWYgKE9VVFBVVEJVRkZFUl9TSVpFIDwgaEFhY0VuY29kZXItPm91dEJ1ZmZlckluQnl0ZXMgKSB7CiAgICAgIGVyciA9IEFBQ0VOQ19NRU1PUllfRVJST1I7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBPcGVuIE1ldGEgRGF0YSBFbmNvZGVyICovCiAgICBpZiAoaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMmRU5DX01PREVfRkxBR19NRVRBKSB7CiAgICAgIGlmICggRkRLX01ldGFkYXRhRW5jX09wZW4oJmhBYWNFbmNvZGVyLT5oTWV0YWRhdGFFbmMpICkKICAgICAgewogICAgICAgIGVyciA9IEFBQ0VOQ19NRU1PUllfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgICB9CiAgICB9IC8qIChlbmNvZGVyX21vZGlzJkVOQ19NT0RFX0ZMQUdfTUVUQSkgKi8KCiAgICAvKiBPcGVuIFRyYW5zcG9ydCBFbmNvZGVyICovCiAgICBpZiAoIHRyYW5zcG9ydEVuY19PcGVuKCZoQWFjRW5jb2Rlci0+aFRwRW5jKSAhPSAwICkKICAgIHsKICAgICAgICBlcnIgPSBBQUNFTkNfTUVNT1JZX0VSUk9SOwogICAgICAgIGdvdG8gYmFpbDsKICAgIH0KICAgIGVsc2UgewogICAgICAgIENfQUxMT0NfU0NSQVRDSF9TVEFSVChwTGliSW5mbywgTElCX0lORk8sIEZES19NT0RVTEVfTEFTVCk7CgogICAgICAgIEZES2luaXRMaWJJbmZvKCBwTGliSW5mbyk7CiAgICAgICAgdHJhbnNwb3J0RW5jX0dldExpYkluZm8oIHBMaWJJbmZvICk7CgogICAgICAgIC8qIEdldCBjYXBhYmlsdHkgZmxhZyBmb3IgdHJhbnNwb3J0IGVuY29kZXIuICovCiAgICAgICAgaEFhY0VuY29kZXItPkNBUEZfdHBFbmMgPSBGREtsaWJJbmZvX2dldENhcGFiaWxpdGllcyggcExpYkluZm8sIEZES19UUEVOQyk7CgogICAgICAgIENfQUxMT0NfU0NSQVRDSF9FTkQocExpYkluZm8sIExJQl9JTkZPLCBGREtfTU9EVUxFX0xBU1QpOwogICAgfQogICAgaWYgKCB0cmFuc3BvcnRFbmNfUmVnaXN0ZXJTYnJDYWxsYmFjayhoQWFjRW5jb2Rlci0+aFRwRW5jLCBhYWNlbmNfU2JyQ2FsbGJhY2ssIGhBYWNFbmNvZGVyKSAhPSAwICkgewogICAgICBlcnIgPSBBQUNFTkNfSU5JVF9UUF9FUlJPUjsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIC8qIEluaXRpYWxpemUgZW5jb2RlciBpbnN0YW5jZSB3aXRoIGRlZmF1bHQgcGFyYW1ldGVycy4gKi8KICAgIGFhY0VuY0RlZmF1bHRDb25maWcoJmhBYWNFbmNvZGVyLT5hYWNDb25maWcsICZoQWFjRW5jb2Rlci0+ZXh0UGFyYW0pOwoKICAgIC8qIEluaXRpYWxpemUgaGVhZGVyUGVyaW9kIGluIGNvZGVyQ29uZmlnIGZvciBhYWNFbmNvZGVyX0dldFBhcmFtKCkuICovCiAgICBoQWFjRW5jb2Rlci0+Y29kZXJDb25maWcuaGVhZGVyUGVyaW9kID0gaEFhY0VuY29kZXItPmV4dFBhcmFtLnVzZXJUcEhlYWRlclBlcmlvZDsKCiAgICAvKiBBbGwgZW5jb2RlciBtb2R1bGVzIGhhdmUgdG8gYmUgaW5pdGlhbGl6ZWQgKi8KICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgPSBBQUNFTkNfSU5JVF9BTEw7CgogICAgLyogUmV0dXJuIGVuY29kZXIgaW5zdGFuY2UgKi8KICAgICpwaEFhY0VuY29kZXIgPSBoQWFjRW5jb2RlcjsKCiAgICByZXR1cm4gZXJyOwoKYmFpbDoKICAgIGFhY0VuY0Nsb3NlKCZoQWFjRW5jb2Rlcik7CgogICAgcmV0dXJuIGVycjsKfQoKCgpBQUNFTkNfRVJST1IgYWFjRW5jQ2xvc2UoSEFORExFX0FBQ0VOQ09ERVIgKnBoQWFjRW5jb2RlcikKewogICAgQUFDRU5DX0VSUk9SIGVyciA9IEFBQ0VOQ19PSzsKCiAgICBpZiAocGhBYWNFbmNvZGVyID09IE5VTEwpIHsKICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9IQU5ETEU7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIGlmICgqcGhBYWNFbmNvZGVyICE9IE5VTEwpIHsKICAgICAgICBIQU5ETEVfQUFDRU5DT0RFUiBoQWFjRW5jb2RlciA9ICpwaEFhY0VuY29kZXI7CgoKICAgICAgIGlmIChoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIhPU5VTEwpIHsKICAgICAgICAgICBGREtmcmVlKGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlcik7CiAgICAgICAgICAgaEFhY0VuY29kZXItPmlucHV0QnVmZmVyID0gTlVMTDsKICAgICAgIH0KCiAgICAgICBpZiAoaEFhY0VuY29kZXItPm91dEJ1ZmZlcikgewogICAgICAgICBGcmVlUmFtX2JzT3V0YnVmZmVyKCZoQWFjRW5jb2Rlci0+b3V0QnVmZmVyKTsKICAgICAgIH0KCiAgICAgICAgaWYgKGhBYWNFbmNvZGVyLT5oRW52RW5jKSB7CiAgICAgICAgICAgIHNickVuY29kZXJfQ2xvc2UgKCZoQWFjRW5jb2Rlci0+aEVudkVuYyk7CiAgICAgICAgfQogICAgICAgIGlmIChoQWFjRW5jb2Rlci0+aEFhY0VuYykgewogICAgICAgICAgICBGREthYWNFbmNfQ2xvc2UgKCZoQWFjRW5jb2Rlci0+aEFhY0VuYyk7CiAgICAgICAgfQoKICAgICAgICB0cmFuc3BvcnRFbmNfQ2xvc2UoJmhBYWNFbmNvZGVyLT5oVHBFbmMpOwoKICAgICAgICBpZiAoaEFhY0VuY29kZXItPmhNZXRhZGF0YUVuYykgewogICAgICAgICAgICBGREtfTWV0YWRhdGFFbmNfQ2xvc2UgKCZoQWFjRW5jb2Rlci0+aE1ldGFkYXRhRW5jKTsKICAgICAgICB9CgogICAgICAgIEZyZWVfQWFjRW5jb2RlcihwaEFhY0VuY29kZXIpOwogICAgfQoKYmFpbDoKICAgIHJldHVybiBlcnI7Cn0KCkFBQ0VOQ19FUlJPUiBhYWNFbmNFbmNvZGUoCiAgICAgICAgY29uc3QgSEFORExFX0FBQ0VOQ09ERVIgICBoQWFjRW5jb2RlciwKICAgICAgICBjb25zdCBBQUNFTkNfQnVmRGVzYyAgICAgKmluQnVmRGVzYywKICAgICAgICBjb25zdCBBQUNFTkNfQnVmRGVzYyAgICAgKm91dEJ1ZkRlc2MsCiAgICAgICAgY29uc3QgQUFDRU5DX0luQXJncyAgICAgICppbmFyZ3MsCiAgICAgICAgQUFDRU5DX091dEFyZ3MgICAgICAgICAgICpvdXRhcmdzCiAgICAgICAgKQp7CiAgICBBQUNFTkNfRVJST1IgZXJyID0gQUFDRU5DX09LOwogICAgSU5UIGksIG5Cc0J5dGVzID0gMDsKICAgIElOVCAgb3V0Qnl0ZXNbKDEpXTsKICAgIGludCAgbkV4dGVuc2lvbnMgPSAwOwogICAgaW50ICBhbmNEYXRhRXh0SWR4ID0gLTE7CgogICAgLyogZGVhbCB3aXRoIHZhbGlkIGVuY29kZXIgaGFuZGxlICovCiAgICBpZiAoaEFhY0VuY29kZXI9PU5VTEwpIHsKICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9IQU5ETEU7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKCiAgICAvKgogICAgICogQWRqdXN0IHVzZXIgc2V0dGluZ3MgYW5kIHRyaWdnZXIgcmVpbml0aWFsaXphdGlvbi4KICAgICAqLwogICAgaWYgKGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MhPTApIHsKCiAgICAgICAgZXJyID0gYWFjRW5jSW5pdChoQWFjRW5jb2RlciwKICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICZoQWFjRW5jb2Rlci0+ZXh0UGFyYW0pOwoKICAgICAgICBpZiAoZXJyIT1BQUNFTkNfT0spIHsKICAgICAgICAgICAgLyoga2VlcCBpbml0IGZsYWdzIGFsaXZlISAqLwogICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgfQogICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgPSBBQUNFTkNfSU5JVF9OT05FOwogICAgfQoKICAgIGlmIChvdXRhcmdzIT1OVUxMKSB7CiAgICAgICAgRkRLbWVtY2xlYXIob3V0YXJncywgc2l6ZW9mKEFBQ0VOQ19PdXRBcmdzKSk7CiAgICB9CgogICAgaWYgKG91dEJ1ZkRlc2MhPU5VTEwpIHsKICAgICAgZm9yIChpPTA7IGk8b3V0QnVmRGVzYy0+bnVtQnVmczsgaSsrKSB7CiAgICAgICAgaWYgKG91dEJ1ZkRlc2MtPmJ1ZnNbaV0hPU5VTEwpIHsKICAgICAgICAgIEZES21lbWNsZWFyKG91dEJ1ZkRlc2MtPmJ1ZnNbaV0sIG91dEJ1ZkRlc2MtPmJ1ZlNpemVzW2ldKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogSWYgb25seSBlbmNvZGVyIGhhbmRsZSBnaXZlbiwgaW5kZXBlbmRlbnQgKHJlKWluaXRpYWxpemF0aW9uIGNhbiBiZSB0cmlnZ2VyZWQuCiAgICAgKi8KICAgIGlmICggKGhBYWNFbmNvZGVyIT1OVUxMKSAmIChpbkJ1ZkRlc2M9PU5VTEwpICYmIChvdXRCdWZEZXNjPT1OVUxMKSAmJiAoaW5hcmdzPT1OVUxMKSAmJiAob3V0YXJncz09TlVMTCkgKSB7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIC8qIHJlc2V0IGJ1ZmZlciB3aWNoIHNpZ25hbHMgbnVtYmVyIG9mIHZhbGlkIGJ5dGVzIGluIG91dHB1dCBiaXRzdHJlYW0gYnVmZmVyICovCiAgICBGREttZW1jbGVhcihvdXRCeXRlcywgaEFhY0VuY29kZXItPmFhY0NvbmZpZy5uU3ViRnJhbWVzKnNpemVvZihJTlQpKTsKCiAgICAvKgogICAgICogTWFuYWdlIGluY29taW5nIGF1ZGlvIHNhbXBsZXMuCiAgICAgKi8KICAgIGlmICggKGluYXJncy0+bnVtSW5TYW1wbGVzID4gMCkgJiYgKGdldEJ1ZkRlc2NJZHgoaW5CdWZEZXNjLElOX0FVRElPX0RBVEEpICE9IC0xKSApCiAgICB7CiAgICAgICAgLyogRmV0Y2ggZGF0YSB1bnRpbCBuU2FtcGxlc1RvUmVhZCByZWFjaGVkICovCiAgICAgICAgSU5UIGlkeCA9IGdldEJ1ZkRlc2NJZHgoaW5CdWZEZXNjLElOX0FVRElPX0RBVEEpOwogICAgICAgIElOVCBuZXdTYW1wbGVzID0gZml4TWF4KDAsZml4TWluKGluYXJncy0+bnVtSW5TYW1wbGVzLCBoQWFjRW5jb2Rlci0+blNhbXBsZXNUb1JlYWQtaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCkpOwogICAgICAgIElOVF9QQ00gKnBJbiA9IGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlcitoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXJPZmZzZXQraEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZDsKCiAgICAgICAgLyogQ29weSBuZXcgaW5wdXQgc2FtcGxlcyB0byBpbnRlcm5hbCBidWZmZXIgKi8KICAgICAgICBpZiAoaW5CdWZEZXNjLT5idWZFbFNpemVzW2lkeF09PShJTlQpc2l6ZW9mKElOVF9QQ00pKSB7CiAgICAgICAgICAgIEZES21lbWNweShwSW4sIChJTlRfUENNKilpbkJ1ZkRlc2MtPmJ1ZnNbaWR4XSwgbmV3U2FtcGxlcypzaXplb2YoSU5UX1BDTSkpOyAgLyogRmFzdCBjb3B5LiAqLwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChpbkJ1ZkRlc2MtPmJ1ZkVsU2l6ZXNbaWR4XT4oSU5UKXNpemVvZihJTlRfUENNKSkgewogICAgICAgICAgICBmb3IgKGk9MDsgaTxuZXdTYW1wbGVzOyBpKyspIHsKICAgICAgICAgICAgICAgIHBJbltpXSA9IChJTlRfUENNKSgoKExPTkcqKWluQnVmRGVzYy0+YnVmc1tpZHhdKVtpXT4+MTYpOyAgICAgICAgICAgICAgICAvKiBDb252ZXJ0IDMyIHRvIDE2IGJpdC4gKi8KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgZm9yIChpPTA7IGk8bmV3U2FtcGxlczsgaSsrKSB7CiAgICAgICAgICAgICAgICBwSW5baV0gPSAoKElOVF9QQ00pKCgoU0hPUlQqKWluQnVmRGVzYy0+YnVmc1tpZHhdKVtpXSkpPDwxNjsgICAgICAgICAgICAgLyogQ29udmVydCAxNiB0byAzMiBiaXQuICovCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCArPSBuZXdTYW1wbGVzOwoKICAgICAgICAvKiBOdW1iZXIgb2YgZmV0Y2hlZCBpbnB1dCBidWZmZXIgc2FtcGxlcy4gKi8KICAgICAgICBvdXRhcmdzLT5udW1JblNhbXBsZXMgPSBuZXdTYW1wbGVzOwogICAgfQoKICAgIC8qIGlucHV0IGJ1ZmZlciBjb21wbGV0ZWx5IGZpbGxlZCA/ICovCiAgICBpZiAoaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCA8IGhBYWNFbmNvZGVyLT5uU2FtcGxlc1RvUmVhZCkKICAgIHsKICAgICAgICAvKiAtIGVvZiByZWFjaGVkIGFuZCBmbHVzaGluZyBlbmFibGVkLCBvcgogICAgICAgICAgIC0gcmV0dXJuIHRvIG1haW4gYW5kIHdhaXQgZm9yIGZ1cnRoZXIgaW5jb21pbmcgYXVkaW8gc2FtcGxlcyAqLwogICAgICAgIGlmIChpbmFyZ3MtPm51bUluU2FtcGxlcz09LTEpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIChoQWFjRW5jb2Rlci0+blplcm9zQXBwZW5kZWQgPCBoQWFjRW5jb2Rlci0+bkRlbGF5KQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgaW50IG5aZXJvcyA9IGhBYWNFbmNvZGVyLT5uU2FtcGxlc1RvUmVhZCAtIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQ7CgogICAgICAgICAgICAgIEZES19BU1NFUlQoblplcm9zID49IDApOwoKICAgICAgICAgICAgICAvKiBjbGVhciBvdXQgdW50aWwgZW5kLW9mLWJ1ZmZlciAqLwogICAgICAgICAgICAgIGlmIChuWmVyb3MpIHsKICAgICAgICAgICAgICAgIEZES21lbWNsZWFyKGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlcitoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXJPZmZzZXQraEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCwgc2l6ZW9mKElOVF9QQ00pKm5aZXJvcyApOwogICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPm5aZXJvc0FwcGVuZGVkICs9IG5aZXJvczsKICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQgPSBoQWFjRW5jb2Rlci0+blNhbXBsZXNUb1JlYWQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgeyAvKiBmbHVzaGluZyBjb21wbGV0ZWQgKi8KICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfRU5DT0RFX0VPRjsgLyogZW9mIHJlYWNoZWQgKi8KICAgICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSB7IC8qIGluYXJncy0+bnVtSW5TYW1wbGVzIT0gLTEgKi8KICAgICAgICAgICAgZ290byBiYWlsOyAvKiBub3QgZW5vdWdoIHNhbXBsZXMgaW4gaW5wdXQgYnVmZmVyIGFuZCBubyBmbHVzaGluZyBlbmFibGVkICovCiAgICAgICAgfQogICAgfQoKICAgIC8qIGluaXQgcGF5bG9hZCAqLwogICAgRkRLbWVtY2xlYXIoaEFhY0VuY29kZXItPmV4dFBheWxvYWQsIHNpemVvZihBQUNFTkNfRVhUX1BBWUxPQUQpICogTUFYX1RPVEFMX0VYVF9QQVlMT0FEUyk7CiAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX1RPVEFMX0VYVF9QQVlMT0FEUzsgaSsrKSB7CiAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW2ldLmFzc29jaWF0ZWRDaEVsZW1lbnQgPSAtMTsKICAgIH0KICAgIEZES21lbWNsZWFyKGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkRGF0YSwgc2l6ZW9mKGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkRGF0YSkpOwogICAgRkRLbWVtY2xlYXIoaEFhY0VuY29kZXItPmV4dFBheWxvYWRTaXplLCBzaXplb2YoaEFhY0VuY29kZXItPmV4dFBheWxvYWRTaXplKSk7CgoKICAgIC8qCiAgICAgKiBDYWxjdWxhdGUgTWV0YSBEYXRhIGluZm8uCiAgICAgKi8KICAgIGlmICggKGhBYWNFbmNvZGVyLT5oTWV0YWRhdGFFbmMhPU5VTEwpICYmIChoQWFjRW5jb2Rlci0+bWV0YURhdGFBbGxvd2VkIT0wKSApIHsKCiAgICAgICAgY29uc3QgQUFDRU5DX01ldGFEYXRhICpwTWV0YURhdGEgPSBOVUxMOwogICAgICAgIEFBQ0VOQ19FWFRfUEFZTE9BRCAqcE1ldGFEYXRhRXh0UGF5bG9hZCA9IE5VTEw7CiAgICAgICAgVUlOVCBuTWV0YURhdGFFeHRlbnNpb25zID0gMDsKICAgICAgICBJTlQgIG1hdHJpeF9taXhkb3duX2lkeCA9IDA7CgogICAgICAgIC8qIE5ldyBtZXRhIGRhdGEgaW5mbyBhdmFpbGFibGUgPyAqLwogICAgICAgIGlmICggZ2V0QnVmRGVzY0lkeChpbkJ1ZkRlc2MsSU5fTUVUQURBVEFfU0VUVVApICE9IC0xICkgewogICAgICAgICAgcE1ldGFEYXRhID0gKEFBQ0VOQ19NZXRhRGF0YSopaW5CdWZEZXNjLT5idWZzW2dldEJ1ZkRlc2NJZHgoaW5CdWZEZXNjLElOX01FVEFEQVRBX1NFVFVQKV07CiAgICAgICAgfQoKICAgICAgICBGREtfTWV0YWRhdGFFbmNfUHJvY2VzcyhoQWFjRW5jb2Rlci0+aE1ldGFkYXRhRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlcitoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXJPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWV0YURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcE1ldGFEYXRhRXh0UGF5bG9hZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZuTWV0YURhdGFFeHRlbnNpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1hdHJpeF9taXhkb3duX2lkeAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgIGZvciAoaT0wOyBpPChJTlQpbk1ldGFEYXRhRXh0ZW5zaW9uczsgaSsrKSB7ICAvKiBHZXQgbWV0YSBkYXRhIGV4dGVuc2lvbiBwYXlsb2FkLiAqLwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9ucysrXSA9IHBNZXRhRGF0YUV4dFBheWxvYWRbaV07CiAgICAgICAgfQoKICAgICAgICBpZiAoIChtYXRyaXhfbWl4ZG93bl9pZHghPS0xKQogICAgICAgICAgJiYgKChoQWFjRW5jb2Rlci0+ZXh0UGFyYW0udXNlckNoYW5uZWxNb2RlPT1NT0RFXzFfMl8yKXx8KGhBYWNFbmNvZGVyLT5leHRQYXJhbS51c2VyQ2hhbm5lbE1vZGU9PU1PREVfMV8yXzJfMSkpICkKICAgICAgICB7CiAgICAgICAgICAvKiBTZXQgbWF0cml4IG1peGRvd24gY29lZmZpY2llbnQuICovCiAgICAgICAgICBVSU5UIHBjZVZhbHVlID0gKFVJTlQpKCAoMTw8MykgfCAoKG1hdHJpeF9taXhkb3duX2lkeCYweDMpPDwxKSB8IDEgKTsKICAgICAgICAgIGlmIChoQWFjRW5jb2Rlci0+ZXh0UGFyYW0udXNlclBjZUFkZGl0aW9ucyAhPSBwY2VWYWx1ZSkgewogICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGFyYW0udXNlclBjZUFkZGl0aW9ucyA9IHBjZVZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgoKICAgIGlmICggaXNTYnJBY3RpdmUoJmhBYWNFbmNvZGVyLT5hYWNDb25maWcpICkgewoKICAgICAgICBJTlQgblBheWxvYWQgPSAwOwoKICAgICAgICAvKgogICAgICAgICAqIEVuY29kZSBTQlIgZGF0YS4KICAgICAgICAgKi8KICAgICAgICBpZiAoc2JyRW5jb2Rlcl9FbmNvZGVGcmFtZShoQWFjRW5jb2Rlci0+aEVudkVuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmV4dFBhcmFtLm5DaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFNpemVbblBheWxvYWRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkRGF0YVtuUGF5bG9hZF0KI2lmIGRlZmluZWQoRVZBTF9QQUNLQUdFX1NJTEVOQ0UpIHx8IGRlZmluZWQoRVZBTF9QQUNLQUdFX1NCUl9TSUxFTkNFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLGhBYWNFbmNvZGVyLT5oQWFjRW5jLT5jbGVhck91dHB1dAojZW5kaWYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpCiAgICAgICAgewogICAgICAgICAgICBlcnIgPSBBQUNFTkNfRU5DT0RFX0VSUk9SOwogICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAvKiBBZGQgU0JSIGV4dGVuc2lvbiBwYXlsb2FkICovCiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCAoOCk7IGkrKykgewogICAgICAgICAgICAgICAgaWYgKGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkU2l6ZVtuUGF5bG9hZF1baV0gPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRbbkV4dGVuc2lvbnNdLnBEYXRhICAgID0gaEFhY0VuY29kZXItPmV4dFBheWxvYWREYXRhW25QYXlsb2FkXVtpXTsKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9uc10uZGF0YVNpemUgPSBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFNpemVbblBheWxvYWRdW2ldOwogICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRbbkV4dGVuc2lvbnNdLmFzc29jaWF0ZWRDaEVsZW1lbnQgPSBpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9uc10uZGF0YVR5cGUgPSBFWFRfU0JSX0RBVEE7ICAvKiBPbmNlIFNCUiBFbmNvZGVyIHN1cHBvcnRzIFNCUiBDUkMgc2V0IEVYVF9TQlJfREFUQV9DUkMgKi8KICAgICAgICAgICAgICAgICAgICBuRXh0ZW5zaW9ucysrOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBvciBFWFRfU0JSX0RBVEEgYWNjb3JkaW5nIHRvIGNvbmZpZ3VyYXRpb24uICovCiAgICAgICAgICAgICAgICAgICAgRkRLX0FTU0VSVChuRXh0ZW5zaW9uczw9TUFYX1RPVEFMX0VYVF9QQVlMT0FEUyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgblBheWxvYWQrKzsKICAgICAgICB9CiAgICB9IC8qIHNickVuYWJsZWQgKi8KCiAgICBpZiAoIChpbmFyZ3MtPm51bUFuY0J5dGVzID4gMCkgJiYgKCBnZXRCdWZEZXNjSWR4KGluQnVmRGVzYyxJTl9BTkNJTExSWV9EQVRBKSE9LTEgKSApIHsKICAgICAgICBJTlQgaWR4ID0gZ2V0QnVmRGVzY0lkeChpbkJ1ZkRlc2MsSU5fQU5DSUxMUllfREFUQSk7CiAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRbbkV4dGVuc2lvbnNdLmRhdGFTaXplID0gaW5hcmdzLT5udW1BbmNCeXRlcyAqIDg7CiAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRbbkV4dGVuc2lvbnNdLnBEYXRhICAgID0gKFVDSEFSKilpbkJ1ZkRlc2MtPmJ1ZnNbaWR4XTsKICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9uc10uZGF0YVR5cGUgPSBFWFRfREFUQV9FTEVNRU5UOwogICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW25FeHRlbnNpb25zXS5hc3NvY2lhdGVkQ2hFbGVtZW50ID0gLTE7CiAgICAgICAgYW5jRGF0YUV4dElkeCA9IG5FeHRlbnNpb25zOyAvKiBzdG9yZSBpbmRleCAqLwogICAgICAgIG5FeHRlbnNpb25zKys7CiAgICB9CgogICAgLyoKICAgICAqIEVuY29kZSBBQUMgLSBDb3JlLgogICAgICovCiAgICBpZiAoIEZES2FhY0VuY19FbmNvZGVGcmFtZSggaEFhY0VuY29kZXItPmhBYWNFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmhUcEVuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0Qnl0ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICE9IEFBQ19FTkNfT0sgKQogICAgewogICAgICAgIGVyciA9IEFBQ0VOQ19FTkNPREVfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIGlmIChhbmNEYXRhRXh0SWR4ID49IDApIHsKICAgICAgb3V0YXJncy0+bnVtQW5jQnl0ZXMgPSBpbmFyZ3MtPm51bUFuY0J5dGVzIC0gKGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW2FuY0RhdGFFeHRJZHhdLmRhdGFTaXplPj4zKTsKICAgIH0KCiAgICAvKiBzYW1wbGVzIGV4aGF1c3RlZCAqLwogICAgaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCAtPSBoQWFjRW5jb2Rlci0+blNhbXBsZXNUb1JlYWQ7CgogICAgLyoKICAgICAqIERlbGF5IGJhbGFuY2luZyBidWZmZXIgaGFuZGxpbmcKICAgICAqLwogICAgaWYgKGlzU2JyQWN0aXZlKCZoQWFjRW5jb2Rlci0+YWFjQ29uZmlnKSkgewogICAgICAgIHNickVuY29kZXJfVXBkYXRlQnVmZmVycyhoQWFjRW5jb2Rlci0+aEVudkVuYywgaEFhY0VuY29kZXItPmlucHV0QnVmZmVyKTsKICAgIH0KCiAgICAvKgogICAgICogTWFrZSBiaXRzdHJlYW0gcHVibGljCiAgICAgKi8KICAgIGlmIChvdXRCdWZEZXNjLT5udW1CdWZzPj0xKSB7CgogICAgICAgIElOVCBic0lkeCA9IGdldEJ1ZkRlc2NJZHgob3V0QnVmRGVzYyxPVVRfQklUU1RSRUFNX0RBVEEpOwogICAgICAgIElOVCBhdUlkeCA9IGdldEJ1ZkRlc2NJZHgob3V0QnVmRGVzYyxPVVRfQVVfU0laRVMpOwoKICAgICAgICBmb3IgKGk9MCxuQnNCeXRlcz0wOyBpPGhBYWNFbmNvZGVyLT5hYWNDb25maWcublN1YkZyYW1lczsgaSsrKSB7CiAgICAgICAgICBuQnNCeXRlcyArPSBvdXRCeXRlc1tpXTsKCiAgICAgICAgICBpZiAoYXVJZHghPS0xKSB7CiAgICAgICAgICAgKChJTlQqKW91dEJ1ZkRlc2MtPmJ1ZnNbYXVJZHhdKVtpXSA9IG91dEJ5dGVzW2ldOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCAoYnNJZHghPS0xKSAmJiAob3V0QnVmRGVzYy0+YnVmU2l6ZXNbYnNJZHhdPj1uQnNCeXRlcykgKSB7CiAgICAgICAgICBGREttZW1jcHkob3V0QnVmRGVzYy0+YnVmc1tic0lkeF0sIGhBYWNFbmNvZGVyLT5vdXRCdWZmZXIsIHNpemVvZihVQ0hBUikqbkJzQnl0ZXMpOwogICAgICAgICAgb3V0YXJncy0+bnVtT3V0Qnl0ZXMgPSBuQnNCeXRlczsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAvKiBvdXRwdXQgYnVmZmVyIHRvbyBzbWFsbCwgY2FuJ3Qgd3JpdGUgdmFsaWQgYml0c3RyZWFtICovCiAgICAgICAgICBlcnIgPSBBQUNFTkNfRU5DT0RFX0VSUk9SOwogICAgICAgICAgZ290byBiYWlsOwogICAgICAgIH0KICAgIH0KCmJhaWw6CiAgICBpZiAoZXJyID09IEFBQ0VOQ19FTkNPREVfRVJST1IpIHsKICAgICAgICAvKiBBbGwgZW5jb2RlciBtb2R1bGVzIGhhdmUgdG8gYmUgaW5pdGlhbGl6ZWQgKi8KICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzID0gQUFDRU5DX0lOSVRfQUxMOwogICAgfQoKICAgIHJldHVybiBlcnI7Cn0KCnN0YXRpYwpBQUNfRU5DT0RFUl9FUlJPUiBhYWNFbmNHZXRDb25mKEhBTkRMRV9BQUNFTkNPREVSICBoQWFjRW5jb2RlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UICAgICAgICAgICAgICAqc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAgICAgICAgICAgICAqY29uZkJ1ZmZlcikKewogICAgRkRLX0JJVFNUUkVBTSB0bXBDb25mOwogICAgVUlOVCBjb25mVHlwZTsKICAgIFVDSEFSIGJ1Zls2NF07CiAgICBpbnQgZXJyOwoKICAgIC8qIEluaXQgYml0IGJ1ZmZlciAqLwogICAgRkRLaW5pdEJpdFN0cmVhbSgmdG1wQ29uZiwgYnVmLCA2NCwgMCwgQlNfV1JJVEVSKTsKCiAgICAvKiB3cml0ZSBjb25mIGluIHRtcCBidWZmZXIgKi8KICAgIGVyciA9IHRyYW5zcG9ydEVuY19HZXRDb25mKGhBYWNFbmNvZGVyLT5oVHBFbmMsICZoQWFjRW5jb2Rlci0+Y29kZXJDb25maWcsICZ0bXBDb25mLCAmY29uZlR5cGUpOwoKICAgIC8qIGNvcHkgZGF0YSB0byBvdXRidWZmZXI6IGxlbmd0aCBpbiBieXRlcyAqLwogICAgRkRLYnl0ZUFsaWduKCZ0bXBDb25mLCAwKTsKCiAgICAvKiBDaGVjayBidWZmZXIgc2l6ZSAqLwogICAgaWYgKEZES2dldFZhbGlkQml0cygmdG1wQ29uZikgPiAoKCpzaXplKTw8MykpCiAgICAgIHJldHVybiBBQUNfRU5DX1VOS05PV047CgogICAgRkRLZmV0Y2hCdWZmZXIoJnRtcENvbmYsIGNvbmZCdWZmZXIsIHNpemUpOwoKICAgIGlmIChlcnIgIT0gMCkKICAgICAgcmV0dXJuIEFBQ19FTkNfVU5LTk9XTjsKICAgIGVsc2UKICAgICAgcmV0dXJuIEFBQ19FTkNfT0s7Cn0KCgpBQUNFTkNfRVJST1IgYWFjRW5jR2V0TGliSW5mbyhMSUJfSU5GTyAqaW5mbykKewogIGludCBpID0gMDsKCiAgaWYgKGluZm8gPT0gTlVMTCkgewogICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0hBTkRMRTsKICB9CgogIEZES190b29sc0dldExpYkluZm8oIGluZm8gKTsKICB0cmFuc3BvcnRFbmNfR2V0TGliSW5mbyggaW5mbyApOwoKICBzYnJFbmNvZGVyX0dldExpYkluZm8oIGluZm8gKTsKCiAgLyogc2VhcmNoIGZvciBuZXh0IGZyZWUgdGFiICovCiAgZm9yIChpID0gMDsgaSA8IEZES19NT0RVTEVfTEFTVDsgaSsrKSB7CiAgICBpZiAoaW5mb1tpXS5tb2R1bGVfaWQgPT0gRkRLX05PTkUpIGJyZWFrOwogIH0KICBpZiAoaSA9PSBGREtfTU9EVUxFX0xBU1QpIHsKICAgIHJldHVybiBBQUNFTkNfSU5JVF9FUlJPUjsKICB9CgogIGluZm9baV0ubW9kdWxlX2lkID0gRkRLX0FBQ0VOQzsKICBpbmZvW2ldLmJ1aWxkX2RhdGUgPSAoY2hhciopQUFDRU5DT0RFUl9MSUJfQlVJTERfREFURTsKICBpbmZvW2ldLmJ1aWxkX3RpbWUgPSAoY2hhciopQUFDRU5DT0RFUl9MSUJfQlVJTERfVElNRTsKICBpbmZvW2ldLnRpdGxlID0gKGNoYXIqKUFBQ0VOQ09ERVJfTElCX1RJVExFOwogIGluZm9baV0udmVyc2lvbiA9IExJQl9WRVJTSU9OKEFBQ0VOQ09ERVJfTElCX1ZMMCwgQUFDRU5DT0RFUl9MSUJfVkwxLCBBQUNFTkNPREVSX0xJQl9WTDIpOzsKICBMSUJfVkVSU0lPTl9TVFJJTkcoJmluZm9baV0pOwoKICAvKiBDYXBhYmlsaXR5IGZsYWdzICovCiAgaW5mb1tpXS5mbGFncyA9IDAKICAgIHwgQ0FQRl9BQUNfMTAyNCB8IENBUEZfQUFDX0xDCiAgICB8IENBUEZfQUFDXzUxMgogICAgfCBDQVBGX0FBQ180ODAKICAgIHwgQ0FQRl9BQUNfRFJDCiAgICAgIDsKICAvKiBFbmQgb2YgZmxhZ3MgKi8KCiAgcmV0dXJuIEFBQ0VOQ19PSzsKfQoKQUFDRU5DX0VSUk9SIGFhY0VuY29kZXJfU2V0UGFyYW0oCiAgICAgICAgY29uc3QgSEFORExFX0FBQ0VOQ09ERVIgICBoQWFjRW5jb2RlciwKICAgICAgICBjb25zdCBBQUNFTkNfUEFSQU0gICAgICAgIHBhcmFtLAogICAgICAgIGNvbnN0IFVJTlQgICAgICAgICAgICAgICAgdmFsdWUKICAgICAgICApCnsKICAgIEFBQ0VOQ19FUlJPUiBlcnIgPSBBQUNFTkNfT0s7CiAgICBVU0VSX1BBUkFNICpzZXR0aW5ncyA9ICZoQWFjRW5jb2Rlci0+ZXh0UGFyYW07CgogICAgLyogY2hlY2sgZW5jb2RlciBoYW5kbGUgKi8KICAgIGlmIChoQWFjRW5jb2RlciA9PSBOVUxMKSB7CiAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfSEFORExFOwogICAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBhcHBseSBwYXJhbSB2YWx1ZSAqLwogICAgc3dpdGNoIChwYXJhbSkKICAgIHsKICAgIGNhc2UgQUFDRU5DX0FPVDoKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJBT1QgIT0gKEFVRElPX09CSkVDVF9UWVBFKXZhbHVlKSB7CiAgICAgICAgICAgIC8qIGNoZWNrIGlmIEFPVCBtYXRjaGVzIHRoZSBhbGxvY2F0ZWQgbW9kdWxlcyAqLwogICAgICAgICAgICBzd2l0Y2ggKCB2YWx1ZSApIHsKICAgICAgICAgICAgICBjYXNlIEFPVF9QUzoKICAgICAgICAgICAgICBjYXNlIEFPVF9NUDJfUFM6CiAgICAgICAgICAgICAgICBpZiAoIShoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyAmIChFTkNfTU9ERV9GTEFHX1BTKSkpIHsKICAgICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgY2FzZSBBT1RfU0JSOgogICAgICAgICAgICAgIGNhc2UgQU9UX01QMl9TQlI6CiAgICAgICAgICAgICAgICBpZiAoIShoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyAmIChFTkNfTU9ERV9GTEFHX1NCUikpKSB7CiAgICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGNhc2UgQU9UX0FBQ19MQzoKICAgICAgICAgICAgICBjYXNlIEFPVF9NUDJfQUFDX0xDOgogICAgICAgICAgICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgICAgICAgICAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgICAgICAgICAgICAgaWYgKCEoaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMgJiAoRU5DX01PREVfRkxBR19BQUMpKSkgewogICAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgICAgIH0vKiBzd2l0Y2ggdmFsdWUgKi8KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJBT1QgPSAoQVVESU9fT0JKRUNUX1RZUEUpdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfU1RBVEVTIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0JJVFJBVEU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyQml0cmF0ZSAhPSB2YWx1ZSkgewogICAgICAgICAgICBzZXR0aW5ncy0+dXNlckJpdHJhdGUgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9DT05GSUcgfCBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQklUUkFURU1PREU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyQml0cmF0ZU1vZGUgIT0gdmFsdWUpIHsKICAgICAgICAgICAgc3dpdGNoICggdmFsdWUgKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgICAgIHNldHRpbmdzLT51c2VyQml0cmF0ZU1vZGUgPSB2YWx1ZTsKICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8qIHN3aXRjaCB2YWx1ZSAqLwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1NBTVBMRVJBVEU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyU2FtcGxlcmF0ZSAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoICEoICh2YWx1ZT09ODAwMCkgfHwgKHZhbHVlPT0xMTAyNSkgfHwgKHZhbHVlPT0xMjAwMCkgfHwgKHZhbHVlPT0xNjAwMCkgfHwgKHZhbHVlPT0yMjA1MCkgfHwgKHZhbHVlPT0yNDAwMCkgfHwKICAgICAgICAgICAgICAgICAgICh2YWx1ZT09MzIwMDApIHx8ICh2YWx1ZT09NDQxMDApIHx8ICh2YWx1ZT09NDgwMDApIHx8ICh2YWx1ZT09NjQwMDApIHx8ICh2YWx1ZT09ODgyMDApIHx8ICh2YWx1ZT09OTYwMDApICkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXR0aW5ncy0+dXNlclNhbXBsZXJhdGUgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCA9IDA7IC8qIHJlc2V0IGludGVybmFsIGlucHV0YnVmZmVyICovCiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfU1RBVEVTIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0NIQU5ORUxNT0RFOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlckNoYW5uZWxNb2RlICE9IChDSEFOTkVMX01PREUpdmFsdWUpIHsKICAgICAgICAgICAgY29uc3QgQ0hBTk5FTF9NT0RFX0NPTkZJR19UQUIqIHBDb25maWcgPSBGREthYWNFbmNfR2V0Q2hhbm5lbE1vZGVDb25maWd1cmF0aW9uKChDSEFOTkVMX01PREUpdmFsdWUpOwogICAgICAgICAgICBpZiAocENvbmZpZz09TlVMTCkgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCAocENvbmZpZy0+bkVsZW1lbnRzID4gaEFhY0VuY29kZXItPm5NYXhBYWNFbGVtZW50cykKICAgICAgICAgICAgICB8fCAocENvbmZpZy0+bkNoYW5uZWxzRWZmID4gaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscykKICAgICAgICAgICAgICB8fCAhKCgodmFsdWU+PTEpICYmICh2YWx1ZTw9NykpfHwoKHZhbHVlPj0zMykgJiYgKHZhbHVlPD0zNCkpKQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJDaGFubmVsTW9kZSA9IChDSEFOTkVMX01PREUpdmFsdWU7CiAgICAgICAgICAgIHNldHRpbmdzLT5uQ2hhbm5lbHMgPSBwQ29uZmlnLT5uQ2hhbm5lbHM7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQgPSAwOyAvKiByZXNldCBpbnRlcm5hbCBpbnB1dGJ1ZmZlciAqLwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRyB8IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19CQU5EV0lEVEg6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyQmFuZHdpZHRoICE9IHZhbHVlKSB7CiAgICAgICAgICBzZXR0aW5ncy0+dXNlckJhbmR3aWR0aCA9IHZhbHVlOwogICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9DT05GSUc7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQ0hBTk5FTE9SREVSOgogICAgICAgIGlmIChoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmNoYW5uZWxPcmRlciAhPSAoQ0hBTk5FTF9PUkRFUil2YWx1ZSkgewogICAgICAgICAgICBpZiAoISAoKHZhbHVlPT0wKSB8fCAodmFsdWU9PTEpKSApIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5hYWNDb25maWcuY2hhbm5lbE9yZGVyID0gKENIQU5ORUxfT1JERVIpdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQgPSAwOyAvKiByZXNldCBpbnRlcm5hbCBpbnB1dGJ1ZmZlciAqLwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRyB8IEFBQ0VOQ19JTklUX1NUQVRFUyB8IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19BRlRFUkJVUk5FUjoKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJBZnRlcmJ1cm5lciAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoISAoKHZhbHVlPT0wKSB8fCAodmFsdWU9PTEpKSApIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyQWZ0ZXJidXJuZXIgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9DT05GSUc7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfR1JBTlVMRV9MRU5HVEg6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyRnJhbWVsZW5ndGggIT0gdmFsdWUpIHsKICAgICAgICAgIHN3aXRjaCAodmFsdWUpIHsKICAgICAgICAgICAgY2FzZSAxMDI0OgogICAgICAgICAgICBjYXNlIDUxMjoKICAgICAgICAgICAgY2FzZSA0ODA6CiAgICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJGcmFtZWxlbmd0aCA9IHZhbHVlOwogICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19TQlJfUkFUSU86CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyU2JyUmF0aW8gIT0gdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCEgKCh2YWx1ZT09MCkgfHwgKHZhbHVlPT0xKSB8fCAodmFsdWU9PTIpKSApIHsKICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJTYnJSYXRpbyA9IHZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRyB8IEFBQ0VOQ19JTklUX1NUQVRFUyB8IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19TQlJfTU9ERToKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJTYnJFbmFibGVkICE9IHZhbHVlKSB7CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyU2JyRW5hYmxlZCA9IHZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRyB8IEFBQ0VOQ19JTklUX1NUQVRFUyB8IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19UUkFOU01VWDoKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJUcFR5cGUgIT0gKFRSQU5TUE9SVF9UWVBFKXZhbHVlKSB7CgogICAgICAgICAgICBUUkFOU1BPUlRfVFlQRSAgdHlwZSAgPSAoVFJBTlNQT1JUX1RZUEUpdmFsdWU7CiAgICAgICAgICAgIFVJTlQgICAgICAgICAgICBmbGFncyA9IGhBYWNFbmNvZGVyLT5DQVBGX3RwRW5jOwoKICAgICAgICAgICAgaWYgKCAhKCAoKHR5cGU9PVRUX01QNF9BRElGKSAgICAgICYmICAoZmxhZ3MmQ0FQRl9BRElGKSkKICAgICAgICAgICAgICAgICB8fCAoKHR5cGU9PVRUX01QNF9BRFRTKSAgICAgICYmICAoZmxhZ3MmQ0FQRl9BRFRTKSkKICAgICAgICAgICAgICAgICB8fCAoKHR5cGU9PVRUX01QNF9MQVRNX01DUDApICYmICgoZmxhZ3MmQ0FQRl9MQVRNKSAmJiAoZmxhZ3MmQ0FQRl9SQVdQQUNLRVRTKSkpCiAgICAgICAgICAgICAgICAgfHwgKCh0eXBlPT1UVF9NUDRfTEFUTV9NQ1AxKSAmJiAoKGZsYWdzJkNBUEZfTEFUTSkgJiYgKGZsYWdzJkNBUEZfUkFXUEFDS0VUUykpKQogICAgICAgICAgICAgICAgIHx8ICgodHlwZT09VFRfTVA0X0xPQVMpICAgICAgJiYgIChmbGFncyZDQVBGX0xPQVMpKQogICAgICAgICAgICAgICAgIHx8ICgodHlwZT09VFRfTVA0X1JBVykgICAgICAgJiYgIChmbGFncyZDQVBGX1JBV1BBQ0tFVFMpKQogICAgICAgICAgICAgICAgKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyVHBUeXBlID0gKFRSQU5TUE9SVF9UWVBFKXZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19TSUdOQUxJTkdfTU9ERToKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJUcFNpZ25hbGluZyAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoICEoKHZhbHVlPT0wKSB8fCAodmFsdWU9PTEpIHx8ICh2YWx1ZT09MikpICkgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJUcFNpZ25hbGluZyA9IHZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19QUk9URUNUSU9OOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlclRwUHJvdGVjdGlvbiAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoICEoKHZhbHVlPT0wKSB8fCAodmFsdWU9PTEpKSApIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyVHBQcm90ZWN0aW9uID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0hFQURFUl9QRVJJT0Q6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyVHBIZWFkZXJQZXJpb2QgIT0gdmFsdWUpIHsKICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJUcEhlYWRlclBlcmlvZCA9IHZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19UUFNVQkZSQU1FUzoKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJUcE5zdWJGcmFtZXMgIT0gdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCEgKCAodmFsdWU+PTEpICYmICh2YWx1ZTw9NCkgKSApIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyVHBOc3ViRnJhbWVzID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0FOQ0lMTEFSWV9CSVRSQVRFOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlckFuY0RhdGFSYXRlICE9IHZhbHVlKSB7CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyQW5jRGF0YVJhdGUgPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19DT05UUk9MX1NUQVRFOgogICAgICAgIGlmIChoQWFjRW5jb2Rlci0+SW5pdEZsYWdzICE9IHZhbHVlKSB7CiAgICAgICAgICAgIGlmICh2YWx1ZSZBQUNFTkNfUkVTRVRfSU5CVUZGRVIpIHsKICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgPSB2YWx1ZTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19NRVRBREFUQV9NT0RFOgogICAgICAgIGlmICgoVUlOVClzZXR0aW5ncy0+dXNlck1ldGFEYXRhTW9kZSAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoICEoKHZhbHVlPj0wKSAmJiAodmFsdWU8PTIpKSApIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyTWV0YURhdGFNb2RlID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGVyciA9IEFBQ0VOQ19VTlNVUFBPUlRFRF9QQVJBTUVURVI7CiAgICAgIGJyZWFrOwogICAgfSAgLyogc3dpdGNoKHBhcmFtKSAqLwoKYmFpbDoKICAgIHJldHVybiBlcnI7Cn0KClVJTlQgYWFjRW5jb2Rlcl9HZXRQYXJhbSgKICAgICAgICBjb25zdCBIQU5ETEVfQUFDRU5DT0RFUiAgIGhBYWNFbmNvZGVyLAogICAgICAgIGNvbnN0IEFBQ0VOQ19QQVJBTSAgICAgICAgcGFyYW0KICAgICAgICApCnsKICAgIFVJTlQgdmFsdWUgPSAwOwogICAgVVNFUl9QQVJBTSAqc2V0dGluZ3MgPSAmaEFhY0VuY29kZXItPmV4dFBhcmFtOwoKICAgIC8qIGNoZWNrIGVuY29kZXIgaGFuZGxlICovCiAgICBpZiAoaEFhY0VuY29kZXIgPT0gTlVMTCkgewogICAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBhcHBseSBwYXJhbSB2YWx1ZSAqLwogICAgc3dpdGNoIChwYXJhbSkKICAgIHsKICAgIGNhc2UgQUFDRU5DX0FPVDoKICAgICAgICB2YWx1ZSA9IChVSU5UKWhBYWNFbmNvZGVyLT5hYWNDb25maWcuYXVkaW9PYmplY3RUeXBlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQklUUkFURToKICAgICAgICB2YWx1ZSA9IChVSU5UKSgoaEFhY0VuY29kZXItPmFhY0NvbmZpZy5iaXRyYXRlTW9kZT09QUFDRU5DX0JSX01PREVfQ0JSKSA/IGhBYWNFbmNvZGVyLT5hYWNDb25maWcuYml0UmF0ZSA6IC0xKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0JJVFJBVEVNT0RFOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmFhY0NvbmZpZy5iaXRyYXRlTW9kZTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1NBTVBMRVJBVEU6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+Y29kZXJDb25maWcuZXh0U2FtcGxpbmdSYXRlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQ0hBTk5FTE1PREU6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmNoYW5uZWxNb2RlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQkFORFdJRFRIOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmFhY0NvbmZpZy5iYW5kV2lkdGg7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19DSEFOTkVMT1JERVI6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmNoYW5uZWxPcmRlcjsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0FGVEVSQlVSTkVSOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmFhY0NvbmZpZy51c2VSZXF1YW50OwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfR1JBTlVMRV9MRU5HVEg6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmZyYW1lbGVuZ3RoOwogICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19TQlJfUkFUSU86CiAgICAgICAgdmFsdWUgPSBpc1NickFjdGl2ZSgmaEFhY0VuY29kZXItPmFhY0NvbmZpZykgPyBoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLnNiclJhdGlvIDogMDsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1NCUl9NT0RFOgogICAgICAgIHZhbHVlID0gKFVJTlQpIChoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLnN5bnRheEZsYWdzICYgQUNfU0JSX1BSRVNFTlQpID8gMSA6IDA7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19UUkFOU01VWDoKICAgICAgICB2YWx1ZSA9IChVSU5UKXNldHRpbmdzLT51c2VyVHBUeXBlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfU0lHTkFMSU5HX01PREU6CiAgICAgICAgdmFsdWUgPSAoVUlOVClnZXRTYnJTaWduYWxpbmdNb2RlKGhBYWNFbmNvZGVyLT5hYWNDb25maWcuYXVkaW9PYmplY3RUeXBlLCBzZXR0aW5ncy0+dXNlclRwVHlwZSwgc2V0dGluZ3MtPnVzZXJUcFNpZ25hbGluZywgaEFhY0VuY29kZXItPmFhY0NvbmZpZy5zYnJSYXRpbyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19QUk9URUNUSU9OOgogICAgICAgIHZhbHVlID0gKFVJTlQpc2V0dGluZ3MtPnVzZXJUcFByb3RlY3Rpb247CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19IRUFERVJfUEVSSU9EOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmNvZGVyQ29uZmlnLmhlYWRlclBlcmlvZDsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1RQU1VCRlJBTUVTOgogICAgICAgIHZhbHVlID0gKFVJTlQpc2V0dGluZ3MtPnVzZXJUcE5zdWJGcmFtZXM7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19BTkNJTExBUllfQklUUkFURToKICAgICAgICB2YWx1ZSA9IChVSU5UKWhBYWNFbmNvZGVyLT5hYWNDb25maWcuYW5jX1JhdGU7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19DT05UUk9MX1NUQVRFOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPkluaXRGbGFnczsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX01FVEFEQVRBX01PREU6CiAgICAgICAgdmFsdWUgPSAoaEFhY0VuY29kZXItPm1ldGFEYXRhQWxsb3dlZD09MCkgPyAwIDogKFVJTlQpc2V0dGluZ3MtPnVzZXJNZXRhRGF0YU1vZGU7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAvL2VyciA9IE1QU19JTlZBTElEX1BBUkFNRVRFUjsKICAgICAgYnJlYWs7CiAgICB9ICAvKiBzd2l0Y2gocGFyYW0pICovCgpiYWlsOgogICAgcmV0dXJuIHZhbHVlOwp9CgpBQUNFTkNfRVJST1IgYWFjRW5jSW5mbygKICAgICAgICBjb25zdCBIQU5ETEVfQUFDRU5DT0RFUiAgIGhBYWNFbmNvZGVyLAogICAgICAgIEFBQ0VOQ19JbmZvU3RydWN0ICAgICAgICAqcEluZm8KICAgICAgICApCnsKICAgIEFBQ0VOQ19FUlJPUiBlcnIgPSBBQUNFTkNfT0s7CgogICAgRkRLbWVtY2xlYXIocEluZm8sIHNpemVvZihBQUNFTkNfSW5mb1N0cnVjdCkpOwogICAgcEluZm8tPmNvbmZTaXplID0gNjQ7IC8qIHByZS1pbml0aWFsaXplICovCgogICAgcEluZm8tPm1heE91dEJ1ZkJ5dGVzICAgID0gKChoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzKjYxNDQpKzcpPj4zOwogICAgcEluZm8tPm1heEFuY0J5dGVzICAgICAgID0gaEFhY0VuY29kZXItPmFhY0NvbmZpZy5tYXhBbmNCeXRlc1BlckFVOwogICAgcEluZm8tPmluQnVmRmlsbExldmVsICAgID0gaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZC9oQWFjRW5jb2Rlci0+ZXh0UGFyYW0ubkNoYW5uZWxzOwogICAgcEluZm8tPmlucHV0Q2hhbm5lbHMgICAgID0gaEFhY0VuY29kZXItPmV4dFBhcmFtLm5DaGFubmVsczsKICAgIHBJbmZvLT5mcmFtZUxlbmd0aCAgICAgICA9IGhBYWNFbmNvZGVyLT5uU2FtcGxlc1RvUmVhZC9oQWFjRW5jb2Rlci0+ZXh0UGFyYW0ubkNoYW5uZWxzOwogICAgcEluZm8tPmVuY29kZXJEZWxheSAgICAgID0gaEFhY0VuY29kZXItPm5EZWxheS9oQWFjRW5jb2Rlci0+ZXh0UGFyYW0ubkNoYW5uZWxzOwoKICAgIC8qIEdldCBlbmNvZGVyIGNvbmZpZ3VyYXRpb24gKi8KICAgIGlmICggYWFjRW5jR2V0Q29uZihoQWFjRW5jb2RlciwgJnBJbmZvLT5jb25mU2l6ZSwgJnBJbmZvLT5jb25mQnVmWzBdKSAhPSBBQUNfRU5DX09LKSB7CiAgICAgICAgZXJyID0gQUFDRU5DX0lOSVRfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgfQpiYWlsOgogICAgcmV0dXJuIGVycjsKfQoK