Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBKb3NlZiBIb2VwZmwKICAgRGVzY3JpcHRpb246IGluZGVwZW5kZW50IGNoYW5uZWwgY29uY2VhbG1lbnQKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIQogIFxwYWdlIGNvbmNlYWxtZW50IEFBQyBjb3JlIGNvbmNlYWxtZW50CgogIFRoaXMgQUFDIGNvcmUgaW1wbGVtZW50YXRpb24gaW5jbHVkZXMgYSBjb25jZWFsbWVudCBmdW5jdGlvbiwgd2hpY2ggY2FuIGJlIGVuYWJsZWQKICB1c2luZyB0aGUgc2V2ZXJhbCBkZWZpbmVzIGR1cmluZyBjb21waWxhdGlvbi4KCiAgVGhlcmUgYXJlIHZhcmlvdXMgdGVzdHMgaW5zaWRlIHRoZSBjb3JlLCBzdGFydGluZyB3aXRoIHNpbXBsZSBDUkMgdGVzdHMgYW5kIGVuZGluZyBpbgogIGEgdmFyaWV0eSBvZiBwbGF1c2liaWxpdHkgY2hlY2tzLiBJZiBzdWNoIGEgY2hlY2sgaW5kaWNhdGVzIGFuIGludmFsaWQgYml0c3RyZWFtLCB0aGVuCiAgY29uY2VhbG1lbnQgaXMgYXBwbGllZC4KCiAgQ29uY2VhbG1lbnQgaXMgYWxzbyBhcHBsaWVkIHdoZW4gdGhlIGNhbGxpbmcgbWFpbiBwcm9ncmFtIGluZGljYXRlcyBhIGRpc3RvcnRlZCBvciBtaXNzaW5nCiAgZGF0YSBmcmFtZSB1c2luZyB0aGUgZnJhbWVPSyBmbGFnLiBUaGlzIGlzIHVzZWQgZm9yIGVycm9yIGRldGVjdGlvbiBvbiB0aGUgdHJhbnNwb3J0IGxheWVyLgogIChTZWUgYmVsb3cpCgogIFRoZXJlIGFyZSB0aHJlZSBjb25jZWFsbWVudC1tb2RlczoKCiAgMSkgTXV0aW5nOiBUaGUgc3BlY3RyYWwgZGF0YSBpcyBzaW1wbHkgc2V0IHRvIHplcm8gaW4gY2FzZSBvZiBhbiBkZXRlY3RlZCBlcnJvci4KCiAgMikgTm9pc2Ugc3Vic3RpdHV0aW9uOiBJbiBjYXNlIG9mIGFuIGRldGVjdGVkIGVycm9yLCBjb25jZWFsbWVudCBjb3BpZXMgdGhlIGxhc3QgZnJhbWUgYW5kIGFkZHMKICAgICBhdHRlbnVhdGVzIHRoZSBzcGVjdHJhbCBkYXRhLiBGb3IgdGhpcyBtb2RlIHlvdSBoYXZlIHRvIHNldCB0aGUgI0NPTkNFQUxfTk9JU0UgZGVmaW5lLgogICAgIE5vaXNlIHN1YnN0aXR1dGlvbiBhZGRzIG5vIGFkZGl0aW9uYWwgZGVsYXkuCgogIDMpIEludGVycG9sYXRpb246IFRoZSBpbnRlcnBvbGF0aW9uIHJvdXRpbmUgc3dhcHMgdGhlIHNwZWN0cmFsIGRhdGEgZnJvbSB0aGUgcHJldmlvdXMgYW5kIHRoZQogICAgIGN1cnJlbnQgZnJhbWUganVzdCBiZWZvcmUgdGhlIGZpbmFsIGZyZXF1ZW5jeSB0byB0aW1lIGNvbnZlcnNpb24uIEluIGNhc2UgYSBzaW5nbGUgZnJhbWUgaXMKICAgICBjb3JydXB0ZWQsIGNvbmNlYWxtYW50IGludGVycG9sYXRlcyBiZXR3ZWVuIHRoZSBsYXN0IGdvb2QgYW5kIHRoZSBmaXJzdCBnb29kIGZyYW1lIHRvIGNyZWF0ZQogICAgIHRoZSBzcGVjdHJhbCBkYXRhIGZvciB0aGUgbWlzc2luZyBmcmFtZS4gSWYgbXVsdGlwbGUgZnJhbWVzIGFyZSBjb3JydXB0ZWQsIGNvbmNlYWxtZW50CiAgICAgaW1wbGVtZW50cyBmaXJzdCBhIGZhZGUgb3V0IGJhc2VkIG9uIHNsaWdodGx5IG1vZGlmaWVkIHNwZWN0cmFsIHZhbHVlcyBmcm9tIHRoZSBsYXN0IGdvb2QKICAgICBmcmFtZS4gQXMgc29vbiBhcyBnb29kIGZyYW1lcyBhcmUgYXZhaWxhYmxlLCBjb25jZWFsbWFudCBmYWRlcyBpbiB0aGUgbmV3IHNwZWN0cmFsIGRhdGEuCiAgICAgRm9yIHRoaXMgbW9kZSB5b3UgaGF2ZSB0byBzZXQgdGhlICNDT05DRUFMX0lOVEVSIGRlZmluZS4gTm90ZSB0aGF0IGluIHRoaXMgY2FzZSwgeW91IGFsc28KICAgICBuZWVkIHRvIHNldCAjU0JSX0JTX0RFTEFZX0VOQUJMRSwgd2hpY2ggYmFzaWNhbGx5IGFkZHMgYXBwcm9yaWF0ZSBkZWxheSBpbiB0aGUgU0JSIGRlY29kZXIuCiAgICAgTm90ZSB0aGF0IHRoZSBJbnRlcnBvbGF0aW5nLUNvbmNlYWxtZW50IGluY3JlYXNlcyB0aGUgZGVsYXkgb2YgeW91ciBkZWNvZGVyIGJ5IG9uZSBmcmFtZQogICAgIGFuZCB0aGF0IGl0IGRvZXMgcmVxdWlyZSBhZGRpdGlvbmFsIHJlc291cmNlcyBzdWNoIGFzIG1lbW9yeSBhbmQgY29tcHV0YXRpb25hbCBjb21wbGV4aXR5LgoKICA8aDI+SG93IGNvbmNlYWxtZW50IGNhbiBiZSB1c2VkIHdpdGggZXJyb3JzIG9uIHRoZSB0cmFuc3BvcnQgbGF5ZXI8L2gyPgoKICBNYW55IGVycm9ycyBjYW4gb3IgaGF2ZSB0byBiZSBkZXRlY3RlZCBvbiB0aGUgdHJhbnNwb3J0IGxheWVyLiBGb3IgZXhhbXBsZSBpbiBJUCBiYXNlZCBzeXN0ZW1zCiAgcGFja2V0IGxvc3MgY2FuIG9jY3VyLiBUaGUgdHJhbnNwb3J0IHByb3RvY29sIHVzZWQgc2hvdWxkIGluZGljYXRlIHN1Y2ggcGFja2V0IGxvc3MgYnkgaW5zZXJ0aW5nCiAgYW4gZW1wdHkgZnJhbWUgd2l0aCBmcmFtZU9LPTAuCiovCgojaW5jbHVkZSAiY29uY2VhbC5oIgoKI2luY2x1ZGUgImFhY19yb20uaCIKI2luY2x1ZGUgImdlbmVyaWNTdGRzLmgiCgoKLyogUE5TIChvZiBibG9jaykgKi8KI2luY2x1ZGUgImFhY2RlY19wbnMuaCIKI2luY2x1ZGUgImJsb2NrLmgiCgojaW5jbHVkZSAiRkRLX3Rvb2xzX3JvbS5oIgoKI2RlZmluZSBDT05DRUFMX0RGTFRfQ09NRl9OT0lTRV9MRVZFTCAgICAgKCA0NiApICAvKiB+PSAtNzAgZEIgKi8KCgovKiBkZWZhdWx0IHNldHRpbmdzICovCiNkZWZpbmUgQ09OQ0VBTF9ERkxUX0ZBREVPVVRfRlJBTUVTICAgICAgICggNSApCiNkZWZpbmUgQ09OQ0VBTF9ERkxUX0ZBREVJTl9GUkFNRVMgICAgICAgICggNSApCiNkZWZpbmUgQ09OQ0VBTF9ERkxUX01VVEVfUkVMRUFTRV9GUkFNRVMgICggMyApCgojZGVmaW5lIENPTkNFQUxfREZMVF9GQURFX0ZBQ1RPUiAgICAgICAgICAoIDAuNzA3MTA2NzgxMTg2NTQ4ZiApICAgLyogMS9zcXJ0KDIpICovCgovKiBzb21lIG9mdGVuIHVzZWQgY29uc3RhbnRzOiAqLwojZGVmaW5lIEZJWFBfWkVSTyAgICAgICAgICAgRkwyRlhDT05TVF9EQkwoMC4wZikKI2RlZmluZSBGSVhQX09ORSAgICAgICAgICAgIEZMMkZYQ09OU1RfREJMKDEuMGYpCiNkZWZpbmUgRklYUF9GTF9DT1JSRUNUSU9OICBGTDJGWENPTlNUX0RCTCgwLjUzMzMzMzMzMzMzMzMzMzMzZikKCi8qIEZvciBwYXJhbWV0ZXIgY29udmVyc2lvbiAqLwojZGVmaW5lIENPTkNFQUxfUEFSQU1FVEVSX0JJVFMgICAgICAgICAgICAgICggOCApCiNkZWZpbmUgQ09OQ0VBTF9NQVhfUVVBTlRfRkFDVE9SICAgICAgICAgICAgKCAoMTw8Q09OQ0VBTF9QQVJBTUVURVJfQklUUyktMSApCi8qI2RlZmluZSBDT05DRUFMX01JTl9BVFRFTlVBVElPTl9GQUNUT1JfMDI1ICAoIEZMMkZYQ09OU1RfREJMKDAuOTcxNjI3OTUxNTc3MTA2MTc0KSApKi8gIC8qIC0wLjI1IGRCICovCiNkZWZpbmUgQ09OQ0VBTF9NSU5fQVRURU5VQVRJT05fRkFDVE9SXzAyNV9MRCAgRkwyRlhDT05TVF9EQkwoLTAuMDQxNTI0MTAxMTg2MDkyMDI5NTk2ODUzNDQ1MjEyMjk5KQovKiNkZWZpbmUgQ09OQ0VBTF9NSU5fQVRURU5VQVRJT05fRkFDVE9SXzA1MCAgKCBGTDJGWENPTlNUX0RCTCgwLjk0NDA2MDg3NjI4NTkyMzM4MCkgKSovICAvKiAtMC41MCBkQiAqLwojZGVmaW5lIENPTkNFQUxfTUlOX0FUVEVOVUFUSU9OX0ZBQ1RPUl8wNTBfTEQgRkwyRlhDT05TVF9EQkwoLTAuMDgzMDQ4MjAyMzcyMTg0MDU5MjUzNTk3MDA4MTQ1MjkzKQoKdHlwZWRlZiBlbnVtIHsKICBDQ29uY2VhbG1lbnRfTm9FeHBhbmQsCiAgQ0NvbmNlYWxtZW50X0V4cGFuZCwKICBDQ29uY2VhbG1lbnRfQ29tcHJlc3MKfQpDQ29uY2VhbG1lbnRFeHBhbmRUeXBlOwoKc3RhdGljIGNvbnN0IEZJWFBfU0dMIGZhY01vZDRUYWJsZVs0XSA9IHsKICBGTDJGWENPTlNUX1NHTCgwLjUwMDAwMDAwMGYpLCAgIC8qIEZJWFBfU0dMKDB4NDAwMCksICAyXi0oMS0wLDAwKSAqLwogIEZMMkZYQ09OU1RfU0dMKDAuNTk0NjAzNTU4ZiksICAgLyogRklYUF9TR0woMHg0YzFiKSwgIDJeLSgxLTAsMjUpICovCiAgRkwyRlhDT05TVF9TR0woMC43MDcxMDY3ODFmKSwgICAvKiBGSVhQX1NHTCgweDVhODIpLCAgMl4tKDEtMCw1MCkgKi8KICBGTDJGWENPTlNUX1NHTCgwLjg0MDg5NjQxNWYpICAgIC8qIEZJWFBfU0dMKDB4NmJhMikgICAyXi0oMS0wLDc1KSAqLwp9OwoKCgoKc3RhdGljIHZvaWQKICBDQ29uY2VhbG1lbnRfQ2FsY0JhbmRFbmVyZ3kgKAogICAgRklYUF9EQkwgICAgICAgICAgICAgICAqc3BlY3RydW0sCiAgICBjb25zdCBTYW1wbGluZ1JhdGVJbmZvICpwU2FtcGxpbmdSYXRlSW5mbywKICAgIGNvbnN0IGludCAgICAgICAgICAgICAgIGJsb2NrVHlwZSwKICAgIENDb25jZWFsbWVudEV4cGFuZFR5cGUgIGV4LAogICAgaW50ICAgICAgICAgICAgICAgICAgICAqc2ZiRW5lcmd5CiAgKTsKCnN0YXRpYyB2b2lkCiAgQ0NvbmNlYWxtZW50X0ludGVycG9sYXRlQnVmZmVyICgKICAgIEZJWFBfREJMICAgICpzcGVjdHJ1bSwKICAgIFNIT1JUICAgICAgICpwU3BlY1NjYWxlUHJldiwKICAgIFNIT1JUICAgICAgICpwU3BlY1NjYWxlQWN0LAogICAgU0hPUlQgICAgICAgKnBTcGVjU2NhbGVPdXQsCiAgICBpbnQgICAgICAgICAqZW5QcnYsCiAgICBpbnQgICAgICAgICAqZW5BY3QsCiAgICBpbnQgICAgICAgICAgc2ZiQ250LAogICAgY29uc3QgU0hPUlQgKnBTZmJPZmZzZXQKICApOwoKc3RhdGljIGludAogIENDb25jZWFsbWVudF9BcHBseUludGVyICgKICAgIENDb25jZWFsbWVudEluZm8gICAgICAgKnBDb25jZWFsbWVudEluZm8sCiAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgY29uc3QgU2FtcGxpbmdSYXRlSW5mbyAqcFNhbXBsaW5nUmF0ZUluZm8sCiAgICBjb25zdCBpbnQgIHNhbXBsZXNQZXJGcmFtZSwKICAgIGNvbnN0IGludCAgaW1wcm92ZVRvbmFsLAogICAgY29uc3QgaW50ICBmcmFtZU9rCiAgKTsKCgoKc3RhdGljIGludAogIENDb25jZWFsbWVudF9BcHBseU5vaXNlICgKICAgIENDb25jZWFsbWVudEluZm8gKnBDb25jZWFsbWVudEluZm8sCiAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgQ0FhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbywKICAgIGNvbnN0IFNhbXBsaW5nUmF0ZUluZm8gKnBTYW1wbGluZ1JhdGVJbmZvLAogICAgY29uc3QgaW50ICAgIHNhbXBsZXNQZXJGcmFtZSwKICAgIGNvbnN0IFVJTlQgZmxhZ3MKICApOwoKc3RhdGljIHZvaWQKICBDQ29uY2VhbG1lbnRfVXBkYXRlU3RhdGUgKAogICAgQ0NvbmNlYWxtZW50SW5mbyAqcENvbmNlYWxtZW50SW5mbywKICAgIGludCBmcmFtZU9rCiAgKTsKCnN0YXRpYyB2b2lkCiAgQ0NvbmNlYWxtZW50X0FwcGx5UmFuZG9tU2lnbiAoCiAgICBpbnQgICAgICAgIGlSYW5kb21QaGFzZSwKICAgIEZJWFBfREJMICAqc3BlYywKICAgIGludCAgICAgICAgc2FtcGxlc1BlckZyYW1lCiAgKTsKCgpzdGF0aWMgaW50IENDb25jZWFsbWVudF9HZXRXaW5TZXEoaW50IHByZXZXaW5TZXEpCnsKICBpbnQgbmV3V2luU2VxID0gT25seUxvbmdTZXF1ZW5jZTsKCiAgLyogVHJ5IHRvIGhhdmUgb25seSBsb25nIGJsb2NrcyAqLwogIGlmICggcHJldldpblNlcSA9PSBMb25nU3RhcnRTZXF1ZW5jZQogICAgfHwgcHJldldpblNlcSA9PSBFaWdodFNob3J0U2VxdWVuY2UgKQogIHsKICAgIG5ld1dpblNlcSA9IExvbmdTdG9wU2VxdWVuY2U7CiAgfQoKICByZXR1cm4gKG5ld1dpblNlcSk7Cn0KCgovKiEKICBcYnJpZWYgSW5pdCBjb21tb24gY29uY2VhbG1lbnQgaW5mb3JtYXRpb24gZGF0YQoKICBccENvbmNlYWxDb21tb25EYXRhIFBvaW50ZXIgdG8gdGhlIGNvbmNlYWxtZW50IGNvbW1vbiBkYXRhIHN0cnVjdHVyZS4KCiAgXHJldHVybiAgbm9uZQoqLwp2b2lkCiAgQ0NvbmNlYWxtZW50X0luaXRDb21tb25EYXRhIChDQ29uY2VhbFBhcmFtcyAqcENvbmNlYWxDb21tb25EYXRhKQp7CiAgaWYgKHBDb25jZWFsQ29tbW9uRGF0YSAhPSBOVUxMKQogIHsKICAgIGludCBpOwoKICAgIC8qIFNldCBkZWZhdWx0IGVycm9yIGNvbmNlYWxtZW50IHRlY2huaXF1ZSAqLwogICAgcENvbmNlYWxDb21tb25EYXRhLT5tZXRob2QgPSBDb25jZWFsTWV0aG9kSW50ZXI7CgogICAgcENvbmNlYWxDb21tb25EYXRhLT5udW1GYWRlT3V0RnJhbWVzICAgICA9IENPTkNFQUxfREZMVF9GQURFT1VUX0ZSQU1FUzsKICAgIHBDb25jZWFsQ29tbW9uRGF0YS0+bnVtRmFkZUluRnJhbWVzICAgICAgPSBDT05DRUFMX0RGTFRfRkFERUlOX0ZSQU1FUzsKICAgIHBDb25jZWFsQ29tbW9uRGF0YS0+bnVtTXV0ZVJlbGVhc2VGcmFtZXMgPSBDT05DRUFMX0RGTFRfTVVURV9SRUxFQVNFX0ZSQU1FUzsKCiAgICBwQ29uY2VhbENvbW1vbkRhdGEtPmNvbWZvcnROb2lzZUxldmVsICAgID0gQ09OQ0VBTF9ERkxUX0NPTUZfTk9JU0VfTEVWRUw7CgogICAgLyogSW5pdCBmYWRlIGZhY3RvcnMgKHN5bWV0cmljKSAqLwogICAgcENvbmNlYWxDb21tb25EYXRhLT5mYWRlT3V0RmFjdG9yWzBdID0gRkwyRlhDT05TVF9TR0woIENPTkNFQUxfREZMVF9GQURFX0ZBQ1RPUiApOwogICAgcENvbmNlYWxDb21tb25EYXRhLT5mYWRlSW5GYWN0b3JbMF0gID0gcENvbmNlYWxDb21tb25EYXRhLT5mYWRlT3V0RmFjdG9yWzBdOwoKICAgIGZvciAoaSA9IDE7IGkgPCBDT05DRUFMX01BWF9OVU1fRkFERV9GQUNUT1JTOyBpKyspIHsKICAgICAgcENvbmNlYWxDb21tb25EYXRhLT5mYWRlT3V0RmFjdG9yW2ldID0gRlhfREJMMkZYX1NHTChmTXVsdChwQ29uY2VhbENvbW1vbkRhdGEtPmZhZGVPdXRGYWN0b3JbaS0xXSxGTDJGWENPTlNUX1NHTChDT05DRUFMX0RGTFRfRkFERV9GQUNUT1IpKSk7CiAgICAgIHBDb25jZWFsQ29tbW9uRGF0YS0+ZmFkZUluRmFjdG9yW2ldICA9IHBDb25jZWFsQ29tbW9uRGF0YS0+ZmFkZU91dEZhY3RvcltpXTsKICAgIH0KICB9Cn0KCgoKLyohCiAgXGJyaWVmIEdldCBjdXJyZW50IGNvbmNlYWxtZW50IG1ldGhvZC4KCiAgXHBDb25jZWFsQ29tbW9uRGF0YSBQb2ludGVyIHRvIGNvbW1vbiBjb25jZWFsbWVudCBkYXRhIChmb3IgYWxsIGNoYW5uZWxzKQoKICBccmV0dXJuIENvbmNlYWxtZW50IG1ldGhvZC4KKi8KQ0NvbmNlYWxtZW50TWV0aG9kCiAgQ0NvbmNlYWxtZW50X0dldE1ldGhvZCggQ0NvbmNlYWxQYXJhbXMgKnBDb25jZWFsQ29tbW9uRGF0YSApCnsKICBDQ29uY2VhbG1lbnRNZXRob2QgbWV0aG9kID0gQ29uY2VhbE1ldGhvZE5vbmU7CgogIGlmIChwQ29uY2VhbENvbW1vbkRhdGEgIT0gTlVMTCkgewogICAgbWV0aG9kID0gcENvbmNlYWxDb21tb25EYXRhLT5tZXRob2Q7CiAgfQoKICByZXR1cm4gKG1ldGhvZCk7Cn0KCgovKiEKICBcYnJpZWYgSW5pdCBjb25jZWFsbWVudCBpbmZvcm1hdGlvbiBmb3IgZWFjaCBjaGFubmVsCgogIFRoZSBmdW5jdGlvbiBpbml0aWFsaXplcyB0aGUgY29uY2VhbG1lbnQgaW5mb3JtYXRpb24uIFR3byBtZXRob2RzIGNhbiBiZSBjaG9zZW46CiAgICAgICAgICAgICAwID0gaW50ZXJwb2xhdGlvbiBtZXRob2QgKGFkZHMgZGVsYXkpCiAgICAgICAgICAgICAxID0gbm9pc2Ugc3Vic3RpdHV0aW9uIChubyBkZWxheSwgbG93IGNvbXBsZXhpdHkpCgogIFxyZXR1cm4gIG5vbmUKKi8Kdm9pZAogIENDb25jZWFsbWVudF9Jbml0Q2hhbm5lbERhdGEgKAogICAgQ0NvbmNlYWxtZW50SW5mbyAqcENvbmNlYWxDaGFubmVsSW5mbywKICAgIENDb25jZWFsUGFyYW1zICAgKnBDb25jZWFsQ29tbW9uRGF0YSwKICAgIGludCBzYW1wbGVzUGVyRnJhbWUgKQp7CiAgaW50IGk7CgogIHBDb25jZWFsQ2hhbm5lbEluZm8tPnBDb25jZWFsUGFyYW1zID0gcENvbmNlYWxDb21tb25EYXRhOwoKICBGREttZW1jbGVhcihwQ29uY2VhbENoYW5uZWxJbmZvLT5zcGVjdHJhbENvZWZmaWNpZW50LCAxMDI0ICogc2l6ZW9mKEZJWFBfQ05DTCkpOwoKICBmb3IgKGkgPSAwOyBpIDwgODsgaSsrKSB7CiAgICBwQ29uY2VhbENoYW5uZWxJbmZvLT5zcGVjU2NhbGVbaV0gPSAwOwogIH0KCiAgcENvbmNlYWxDaGFubmVsSW5mby0+aVJhbmRvbVBoYXNlICAgPSAwOwoKICBwQ29uY2VhbENoYW5uZWxJbmZvLT53aW5kb3dTZXF1ZW5jZSA9IDA7CiAgcENvbmNlYWxDaGFubmVsSW5mby0+d2luZG93U2hhcGUgICAgPSAwOwoKICBwQ29uY2VhbENoYW5uZWxJbmZvLT5wcmV2RnJhbWVPa1swXSA9IDE7CiAgcENvbmNlYWxDaGFubmVsSW5mby0+cHJldkZyYW1lT2tbMV0gPSAxOwoKICBwQ29uY2VhbENoYW5uZWxJbmZvLT5jbnRGYWRlRnJhbWVzICA9IDA7CiAgcENvbmNlYWxDaGFubmVsSW5mby0+Y250VmFsaWRGcmFtZXMgPSAwOwoKICBwQ29uY2VhbENoYW5uZWxJbmZvLT5jb25jZWFsU3RhdGUgICA9IENvbmNlYWxTdGF0ZV9PazsKCn0KCgovKiEKICBcYnJpZWYgU2V0IGVycm9yIGNvbmNlYWxtZW50IHBhcmFtZXRlcnMKCiAgXGNvbmNlYWxQYXJhbXMKICBcbWV0aG9kCiAgXGZhZGVPdXRTbG9wZQogIFxmYWRlSW5TbG9wZQogIFxtdXRlUmVsZWFzZQogIFxjb21mTm9pc2VMZXZlbAoKICBccmV0dXJuICBub25lCiovCkFBQ19ERUNPREVSX0VSUk9SCiAgQ0NvbmNlYWxtZW50X1NldFBhcmFtcyAoCiAgICBDQ29uY2VhbFBhcmFtcyAqY29uY2VhbFBhcmFtcywKICAgIGludCAgbWV0aG9kLAogICAgaW50ICBmYWRlT3V0U2xvcGUsCiAgICBpbnQgIGZhZGVJblNsb3BlLAogICAgaW50ICBtdXRlUmVsZWFzZSwKICAgIGludCAgY29tZk5vaXNlTGV2ZWwgKQp7CiAgLyogc2V0IGNvbmNlYWxtZW50IHRlY2huaXF1ZSAqLwogIGlmIChtZXRob2QgIT0gQUFDREVDX0NPTkNFQUxfUEFSQU1fTk9UX1NQRUNJRklFRCkgewogICAgc3dpdGNoICgoQ0NvbmNlYWxtZW50TWV0aG9kKW1ldGhvZCkKICAgIHsKICAgIGNhc2UgQ29uY2VhbE1ldGhvZE11dGU6CiAgICBjYXNlIENvbmNlYWxNZXRob2ROb2lzZToKICAgIGNhc2UgQ29uY2VhbE1ldGhvZEludGVyOgogICAgICAvKiBCZSBzdXJlIHRvIGVuYWJsZSBkZWxheSBhZGp1c3RtZW50IG9mIFNCUiBkZWNvZGVyISAqLwogICAgICBpZiAoY29uY2VhbFBhcmFtcyA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLyogc2V0IHBhcmFtICovCiAgICAgICAgY29uY2VhbFBhcmFtcy0+bWV0aG9kID0gKENDb25jZWFsbWVudE1ldGhvZCltZXRob2Q7CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICB9CiAgfQoKICAvKiBzZXQgbnVtYmVyIG9mIGZyYW1lcyBmb3IgZmFkZS1vdXQgc2xvcGUgKi8KICBpZiAoZmFkZU91dFNsb3BlICE9IEFBQ0RFQ19DT05DRUFMX1BBUkFNX05PVF9TUEVDSUZJRUQpIHsKICAgIGlmICggKGZhZGVPdXRTbG9wZSA8IENPTkNFQUxfTUFYX05VTV9GQURFX0ZBQ1RPUlMpCiAgICAgICYmIChmYWRlT3V0U2xvcGUgPj0gMCkgKQogICAgewogICAgICBpZiAoY29uY2VhbFBhcmFtcyA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLyogc2V0IHBhcmFtICovCiAgICAgICAgY29uY2VhbFBhcmFtcy0+bnVtRmFkZU91dEZyYW1lcyA9IGZhZGVPdXRTbG9wZTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICB9CiAgfQoKICAvKiBzZXQgbnVtYmVyIG9mIGZyYW1lcyBmb3IgZmFkZS1pbiBzbG9wZSAqLwogIGlmIChmYWRlSW5TbG9wZSAhPSBBQUNERUNfQ09OQ0VBTF9QQVJBTV9OT1RfU1BFQ0lGSUVEKSB7CiAgICBpZiAoIChmYWRlSW5TbG9wZSA8IENPTkNFQUxfTUFYX05VTV9GQURFX0ZBQ1RPUlMpCiAgICAgICYmIChmYWRlSW5TbG9wZSA+PSAxKSApCiAgICB7CiAgICAgIGlmIChjb25jZWFsUGFyYW1zID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBzZXQgcGFyYW0gKi8KICAgICAgICBjb25jZWFsUGFyYW1zLT5udW1GYWRlSW5GcmFtZXMgPSBmYWRlSW5TbG9wZTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICB9CiAgfQoKICAvKiBzZXQgbnVtYmVyIG9mIGVycm9yLWZyZWUgZnJhbWVzIGFmdGVyIHdoaWNoIHRoZSBtdXRpbmcgd2lsbCBiZSByZWxlYXNlZCAqLwogIGlmIChtdXRlUmVsZWFzZSAhPSBBQUNERUNfQ09OQ0VBTF9QQVJBTV9OT1RfU1BFQ0lGSUVEKSB7CiAgICBpZiAoIChtdXRlUmVsZWFzZSA8IChDT05DRUFMX01BWF9OVU1fRkFERV9GQUNUT1JTPDwxKSkKICAgICAgJiYgKG11dGVSZWxlYXNlID49IDApICkKICAgIHsKICAgICAgaWYgKGNvbmNlYWxQYXJhbXMgPT0gTlVMTCkgewogICAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgICB9IGVsc2UgewogICAgICAgIC8qIHNldCBwYXJhbSAqLwogICAgICAgIGNvbmNlYWxQYXJhbXMtPm51bU11dGVSZWxlYXNlRnJhbWVzID0gbXV0ZVJlbGVhc2U7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogIH0KCiAgLyogc2V0IGNvbmZvcnQgbm9pc2UgbGV2ZWwgd2hpY2ggd2lsbCBiZSBpbnNlcnRlZCB3aGlsZSBpbiBzdGF0ZSAnbXV0aW5nJyAqLwogIGlmIChjb21mTm9pc2VMZXZlbCAhPSBBQUNERUNfQ09OQ0VBTF9QQVJBTV9OT1RfU1BFQ0lGSUVEKSB7CiAgICBpZiAoIChjb21mTm9pc2VMZXZlbCA8IC0xKQogICAgICB8fCAoY29tZk5vaXNlTGV2ZWwgPiAxMjcpICkgewogICAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgIH0KICAgIGlmIChjb25jZWFsUGFyYW1zID09IE5VTEwpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CiAgICB9IGVsc2UgewogICAgICBjb25jZWFsUGFyYW1zLT5jb21mb3J0Tm9pc2VMZXZlbCA9IGNvbWZOb2lzZUxldmVsOwogICAgfQogIH0KCiAgcmV0dXJuIChBQUNfREVDX09LKTsKfQoKCi8qIQogIFxicmllZiBTZXQgZmFkZS1vdXQvaW4gYXR0ZW51YXRpb24gZmFjdG9yIHZlY3RvcnMKCiAgXGNvbmNlYWxQYXJhbXMKICBcZmFkZU91dEF0dGVudWF0aW9uVmVjdG9yCiAgXGZhZGVJbkF0dGVudWF0aW9uVmVjdG9yCgogIFxyZXR1cm4gMCBpZiBPSyBhbGwgb3RoZXIgdmFsdWVzIGluZGljYXRlIGVycm9ycwoqLwpBQUNfREVDT0RFUl9FUlJPUgogIENDb25jZWFsbWVudF9TZXRBdHRlbnVhdGlvbiAoCiAgICBDQ29uY2VhbFBhcmFtcyAqY29uY2VhbFBhcmFtcywKICAgIFNIT1JUICpmYWRlT3V0QXR0ZW51YXRpb25WZWN0b3IsCiAgICBTSE9SVCAqZmFkZUluQXR0ZW51YXRpb25WZWN0b3IgKQp7CiAgaWYgKCAoZmFkZU91dEF0dGVudWF0aW9uVmVjdG9yID09IE5VTEwpCiAgICAmJiAoZmFkZUluQXR0ZW51YXRpb25WZWN0b3IgID09IE5VTEwpICkgewogICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgfQoKICAvKiBGYWRlLW91dCBmYWN0b3JzICovCiAgaWYgKGZhZGVPdXRBdHRlbnVhdGlvblZlY3RvciAhPSBOVUxMKQogIHsKICAgIGludCBpOwoKICAgIC8qIGNoZWNrIHF1YW50aXplZCBmYWN0b3JzIGZpcnN0ICovCiAgICBmb3IgKGkgPSAwOyBpIDwgQ09OQ0VBTF9NQVhfTlVNX0ZBREVfRkFDVE9SUzsgaSsrKSB7CiAgICAgIGlmICgoZmFkZU91dEF0dGVudWF0aW9uVmVjdG9yW2ldIDwgMCkgfHwgKGZhZGVPdXRBdHRlbnVhdGlvblZlY3RvcltpXSA+IENPTkNFQUxfTUFYX1FVQU5UX0ZBQ1RPUikpIHsKICAgICAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgICAgfQogICAgfQogICAgaWYgKGNvbmNlYWxQYXJhbXMgPT0gTlVMTCkgewogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIH0KCiAgICAvKiBub3cgZGVxdWFudGl6ZSBmYWN0b3JzICovCiAgICBmb3IgKGkgPSAwOyBpIDwgQ09OQ0VBTF9NQVhfTlVNX0ZBREVfRkFDVE9SUzsgaSsrKSAKICAgIHsKICAgICAgY29uY2VhbFBhcmFtcy0+ZmFkZU91dEZhY3RvcltpXSA9CiAgICAgICAgRlhfREJMMkZYX1NHTCggZkxkUG93KCAgICBDT05DRUFMX01JTl9BVFRFTlVBVElPTl9GQUNUT1JfMDI1X0xELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChGSVhQX0RCTCkoKElOVCkoRkwyRlhDT05TVF9EQkwoMS4wLzIuMCk+PihDT05DRUFMX1BBUkFNRVRFUl9CSVRTLTEpKSAqIChJTlQpZmFkZU91dEF0dGVudWF0aW9uVmVjdG9yW2ldKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTkNFQUxfUEFSQU1FVEVSX0JJVFMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgKTsKICAgIH0KICB9CgogIC8qIEZhZGUtaW4gZmFjdG9ycyAqLwogIGlmIChmYWRlSW5BdHRlbnVhdGlvblZlY3RvciAhPSBOVUxMKQogIHsKICAgIGludCBpOwoKICAgIC8qIGNoZWNrIHF1YW50aXplZCBmYWN0b3JzIGZpcnN0ICovCiAgICBmb3IgKGkgPSAwOyBpIDwgQ09OQ0VBTF9NQVhfTlVNX0ZBREVfRkFDVE9SUzsgaSsrKSB7CiAgICAgIGlmICgoZmFkZUluQXR0ZW51YXRpb25WZWN0b3JbaV0gPCAwKSB8fCAoZmFkZUluQXR0ZW51YXRpb25WZWN0b3JbaV0gPiBDT05DRUFMX01BWF9RVUFOVF9GQUNUT1IpKSB7CiAgICAgICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgICAgIH0KICAgIH0KICAgIGlmIChjb25jZWFsUGFyYW1zID09IE5VTEwpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CiAgICB9CgogICAgLyogbm93IGRlcXVhbnRpemUgZmFjdG9ycyAqLwogICAgZm9yIChpID0gMDsgaSA8IENPTkNFQUxfTUFYX05VTV9GQURFX0ZBQ1RPUlM7IGkrKykKICAgIHsKICAgICAgY29uY2VhbFBhcmFtcy0+ZmFkZUluRmFjdG9yW2ldID0KICAgICAgICBGWF9EQkwyRlhfU0dMKCBmTGRQb3coIENPTkNFQUxfTUlOX0FUVEVOVUFUSU9OX0ZBQ1RPUl8wMjVfTEQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChGSVhQX0RCTCkoKElOVCkoRklYUF9PTkU+PkNPTkNFQUxfUEFSQU1FVEVSX0JJVFMpICogKElOVClmYWRlSW5BdHRlbnVhdGlvblZlY3RvcltpXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09OQ0VBTF9QQVJBTUVURVJfQklUUwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgKTsKICAgIH0KICB9CgogIHJldHVybiAoQUFDX0RFQ19PSyk7Cn0KCgovKiEKICBcYnJpZWYgR2V0IHN0YXRlIG9mIGNvbmNlYWxtZW50IG1vZHVsZS4KCiAgXHBDb25jZWFsQ2hhbm5lbEluZm8KCiAgXHJldHVybiBDb25jZWFsbWVudCBzdGF0ZS4KKi8KQ0NvbmNlYWxtZW50U3RhdGUKICBDQ29uY2VhbG1lbnRfR2V0U3RhdGUgKAogICAgQ0NvbmNlYWxtZW50SW5mbyAqcENvbmNlYWxDaGFubmVsSW5mbwogICkKewogIENDb25jZWFsbWVudFN0YXRlIHN0YXRlID0gQ29uY2VhbFN0YXRlX09rOwoKICBpZiAocENvbmNlYWxDaGFubmVsSW5mbyAhPSBOVUxMKSB7CiAgICBzdGF0ZSA9IHBDb25jZWFsQ2hhbm5lbEluZm8tPmNvbmNlYWxTdGF0ZTsKICB9CgogIHJldHVybiAoc3RhdGUpOwp9CgoKc3RhdGljIHZvaWQgQ0NvbmNlYWxtZW50X2Zha2VQbnNEYXRhICgKICAgQ1Buc0RhdGEgKnBQbnNEYXRhLAogICBDSWNzSW5mbyAqcEljc0luZm8sCiAgIGNvbnN0IFNhbXBsaW5nUmF0ZUluZm8gKnBTYW1wbGluZ1JhdGVJbmZvLAogICBTSE9SVCAqcFNwZWNTY2FsZSwKICAgU0hPUlQgKnBTY2FsZUZhY3RvciwKICAgY29uc3QgaW50IGxldmVsICkKewogIENQbnNJbnRlckNoYW5uZWxEYXRhICpwSW50ZXJDaGFubmVsRGF0YSA9IHBQbnNEYXRhLT5wUG5zSW50ZXJDaGFubmVsRGF0YTsKCiAgaW50ICBwbnNCYW5kLCBiYW5kLCBncm91cCwgd2luOwogIC8vaW50ICBkZWx0YSA9IDA7CiAgaW50ICB3aW5kb3dzUGVyRnJhbWUgPSBHZXRXaW5kb3dzUGVyRnJhbWUocEljc0luZm8pOwogIGludCAgcmVmTGV2ZWwgPSAod2luZG93c1BlckZyYW1lID4gMSkgPyA4MiA6IDkxOwoKICBGREtfQVNTRVJUKGxldmVsID49IDAgJiYgbGV2ZWwgPD0gMTI3KTsKCiAgZm9yICh3aW4gPSAwOyB3aW4gPCB3aW5kb3dzUGVyRnJhbWU7IHdpbisrKSB7CiAgICBwU3BlY1NjYWxlW3dpbl0gPSAzMTsKICB9CgogIC8qIGZha2UgSUNTIGluZm8gaWYgbmVjZXNzYXJ5ICovCiAgaWYgKCFJc1ZhbGlkKHBJY3NJbmZvKSkgewogICAgcEljc0luZm8tPldpbmRvd0dyb3VwcyA9IDE7CiAgICBpZiAoSXNMb25nQmxvY2socEljc0luZm8pKSB7CiAgICAgIHBJY3NJbmZvLT5Ub3RhbFNmQmFuZHMgPSBwU2FtcGxpbmdSYXRlSW5mby0+TnVtYmVyT2ZTY2FsZUZhY3RvckJhbmRzX0xvbmc7CiAgICAgIHBJY3NJbmZvLT5XaW5kb3dHcm91cExlbmd0aFswXSA9IDE7CiAgICB9CiAgICBlbHNlIHsKICAgICAgcEljc0luZm8tPlRvdGFsU2ZCYW5kcyA9IHBTYW1wbGluZ1JhdGVJbmZvLT5OdW1iZXJPZlNjYWxlRmFjdG9yQmFuZHNfU2hvcnQ7CiAgICAgIHBJY3NJbmZvLT5XaW5kb3dHcm91cExlbmd0aFswXSA9IDg7CiAgICB9CiAgICBwSWNzSW5mby0+TWF4U2ZCYW5kcyA9IHBJY3NJbmZvLT5Ub3RhbFNmQmFuZHM7CiAgfQoKICAvKiBnbG9iYWwgYWN0aXZhdGUgUE5TICovCiAgcFBuc0RhdGEtPlBuc0FjdGl2ZSA9IDE7CiAgLyogc2V0IGVuZXJneSBsZXZlbCAqLwogIHBQbnNEYXRhLT5DdXJyZW50RW5lcmd5ID0gZml4TWF4KCAwLCByZWZMZXZlbCAtIGxldmVsICk7CgogIC8qCiAgICB2YWx1ZTogfCBBdmcuIFJNUyBwb3dlciB8IEF2Zy4gUk1TIHBvd2VyIHwKICAgICAgICAgICB8IHNwZWNTY2FsZSA9IDIyIHwgc3BlY1NjYWxlID0gMzEgfAogICAgLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rCiAgICAgICAgNSAgfCAgICAgICAgICAgICAgICB8ICAtOTkuMCBkQgogICAgICAgMTUgIHwgICAgICAgICAgICAgICAgfCAgLTkwLjAgZEIKICAgICAgIDI1ICB8ICAgICAgICAgICAgICAgIHwgIC04OS43IGRCIAogICAgICAgMzUgIHwgICAgICAgICAgICAgICAgfCAgLTg1LjMgZEIKICAgICAgLi4uICB8ICAgIC4uLiAgICAgICAgIHwgICAuLi4KICAgICAgIDQ1ICB8ICAtNjkuOSBkQiAgICAgIHwgIC03MC4wIGRCCiAgICAgICA1MCAgfCAgLTYyLjIgZEIgICAgICB8ICAKICAgICAgIDU1ICB8ICAtNTUuNiBkQiAgICAgIHwgIC01NC42IGRCCiAgICAgICA2MCAgfCAgLTQ3LjAgZEIgICAgICB8CiAgICAgICA2NSAgfCAgLTM5LjUgZEIgICAgICB8ICAtMzkuNSBkQgogICAgICAgNzAgIHwgIC0zMS45IGRCICAgICAgfCAgCiAgICAgICA3NSAgfCAgLTI0LjQgZEIgICAgICB8ICAtMjQuNCBkQgogICAgICAgODAgIHwgIC0xNi45IGRCICAgICAgfCAgCiAgICAgICA4NSAgfCAgIC05LjQgZEIgKGMpICB8ICAgLTkuNCBkQgogICAgICAgOTAgIHwgICAtMy45IGRCIChjKSAgfCAgCiAgICAgICA5NSAgfCAgICAgICAgICAgICAgICB8ICAgLTIuMSBkQgogICAgICAxMDAgIHwgICAgICAgICAgICAgICAgfCAgIC0xLjYgZEIKICAgICAgMTA1ICB8ICAgICAgICAgICAgICAgIHwgICAtMS40IGRCCiAgKi8KCiAgZm9yIChncm91cD0wOyBncm91cCA8IEdldFdpbmRvd0dyb3VwcyhwSWNzSW5mbyk7IGdyb3VwKyspCiAgewogICAgZm9yIChiYW5kPTA7IGJhbmQgPCBHZXRTY2FsZUZhY3RvckJhbmRzVHJhbnNtaXR0ZWQocEljc0luZm8pOyBiYW5kKyspCiAgICB7CiAgICAgIHBuc0JhbmQgPSBncm91cCAqIDE2ICsgYmFuZDsKCiAgICAgIGlmIChwbnNCYW5kID49IE5PX09GQkFORFMpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgLy9wUG5zRGF0YS0+Q3VycmVudEVuZXJneSArPSBkZWx0YSA7CiAgICAgIHBTY2FsZUZhY3RvcltwbnNCYW5kXSA9IHBQbnNEYXRhLT5DdXJyZW50RW5lcmd5OwogICAgICBwSW50ZXJDaGFubmVsRGF0YS0+Y29ycmVsYXRlZFtwbnNCYW5kXSA9IDA7CiAgICAgIHBQbnNEYXRhLT5wbnNVc2VkW3Buc0JhbmRdID0gMTsKICAgIH0KICB9Cn0KCgovKiEKICBcYnJpZWYgU3RvcmUgZGF0YSBmb3IgY29uY2VhbG1lbnQgdGVjaG5pcXVlcyBhcHBsaWVkIGxhdGVyCgogIEludGVyZmFjZSBmdW5jdGlvbiB0byBzdG9yZSBkYXRhIGZvciBkaWZmZXJlbnQgY29uY2VhbG1lbnQgc3RyYXRlZ2llcwoKICAgXHJldHVybiAgbm9uZQogKi8Kdm9pZAogIENDb25jZWFsbWVudF9TdG9yZSAoCiAgICBDQ29uY2VhbG1lbnRJbmZvICpoQ29uY2VhbG1lbnRJbmZvLAogICAgQ0FhY0RlY29kZXJDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgIENBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8gKQp7CiAgaWYgKCAhKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnJlbmRlck1vZGUgPT0gQUFDREVDX1JFTkRFUl9MUEQKICAgICAgKSApCiAgewogICAgRklYUF9EQkwgKnBTcGVjdHJhbENvZWZmaWNpZW50ID0gIFNQRUNfTE9ORyhwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wU3BlY3RyYWxDb2VmZmljaWVudCk7CiAgICBTSE9SVCAgICAqcFNwZWNTY2FsZSAgICAgICAgICAgPSAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+c3BlY1NjYWxlOwogICAgQ0ljc0luZm8gKnBJY3NJbmZvICAgICAgICAgICAgID0gJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm87CgogICAgU0hPUlQgIHRTcGVjU2NhbGVbOF07CiAgICBVQ0hBUiAgdFdpbmRvd1NoYXBlLCB0V2luZG93U2VxdWVuY2U7CgogICAgLyogc3RvcmUgb2xkIHdpbmRvdyBpbmZvcyBmb3Igc3dhcHBpbmcgKi8KICAgIHRXaW5kb3dTZXF1ZW5jZSA9IGhDb25jZWFsbWVudEluZm8tPndpbmRvd1NlcXVlbmNlOwogICAgdFdpbmRvd1NoYXBlICAgID0gaENvbmNlYWxtZW50SW5mby0+d2luZG93U2hhcGU7CgogICAgLyogc3RvcmUgb2xkIHNjYWxlIGZhY3RvcnMgZm9yIHN3YXBwaW5nICovCiAgICBGREttZW1jcHkodFNwZWNTY2FsZSwgaENvbmNlYWxtZW50SW5mby0+c3BlY1NjYWxlLCA4KnNpemVvZihTSE9SVCkpOwoKICAgIC8qIHN0b3JlIG5ldyB3aW5kb3cgaW5mb3MgKi8KICAgIGhDb25jZWFsbWVudEluZm8tPndpbmRvd1NlcXVlbmNlID0gR2V0V2luZG93U2VxdWVuY2UocEljc0luZm8pOwogICAgaENvbmNlYWxtZW50SW5mby0+d2luZG93U2hhcGUgICAgPSBHZXRXaW5kb3dTaGFwZShwSWNzSW5mbyk7CiAgICBoQ29uY2VhbG1lbnRJbmZvLT5sYXN0V2luR3JwTGVuICA9ICooR2V0V2luZG93R3JvdXBMZW5ndGhUYWJsZShwSWNzSW5mbykrR2V0V2luZG93R3JvdXBzKHBJY3NJbmZvKS0xKTsKCiAgICAvKiBzdG9yZSBuZXcgc2NhbGUgZmFjdG9ycyAqLwogICAgRkRLbWVtY3B5KGhDb25jZWFsbWVudEluZm8tPnNwZWNTY2FsZSwgcFNwZWNTY2FsZSwgOCpzaXplb2YoU0hPUlQpKTsKCiAgICBpZiAoQ0NvbmNlYWxtZW50X0dldERlbGF5KGhDb25jZWFsbWVudEluZm8tPnBDb25jZWFsUGFyYW1zKSA9PSAwKQogICAgewogICAgICAvKiBzdG9yZSBuZXcgc3BlY3RyYWwgYmlucyAqLwojaWYgKENOQ0xfRlJBQ1RfQklUUyA9PSBERlJBQ1RfQklUUykKICAgICAgRkRLbWVtY3B5KGhDb25jZWFsbWVudEluZm8tPnNwZWN0cmFsQ29lZmZpY2llbnQsIHBTcGVjdHJhbENvZWZmaWNpZW50LCAxMDI0ICogc2l6ZW9mKEZJWFBfQ05DTCkpOwojZWxzZQogICAgICBGSVhQX0NOQ0wgKlJFU1RSSUNUIHBDbmNsID0gJmhDb25jZWFsbWVudEluZm8tPnNwZWN0cmFsQ29lZmZpY2llbnRbMTAyNC0xXTsKICAgICAgRklYUF9EQkwgICpSRVNUUklDVCBwU3BlYyA9ICZwU3BlY3RyYWxDb2VmZmljaWVudFsxMDI0LTFdOwogICAgICBpbnQgaTsKCiAgICAgIGZvciAoaSA9IDEwMjQ7IGkgIT0gMDsgaS0tKSB7CiAgICAgICAgKnBDbmNsLS0gPSBGWF9EQkwyRlhfQ05DTCgqcFNwZWMtLSk7CiAgICAgIH0KI2VuZGlmCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgIEZJWFBfQ05DTCAqUkVTVFJJQ1QgcENuY2wgPSAmaENvbmNlYWxtZW50SW5mby0+c3BlY3RyYWxDb2VmZmljaWVudFsxMDI0LTFdOwogICAgICBGSVhQX0RCTCAgKlJFU1RSSUNUIHBTcGVjID0gJnBTcGVjdHJhbENvZWZmaWNpZW50WzEwMjQtMV07CiAgICAgIGludCBpOwoKICAgICAgLyogc3dhcCBzcGVjdHJhbCBkYXRhICovCiAgICAgIGZvciAoaSA9IDEwMjQ7IGkgIT0gMDsgaS0tKSB7CiAgICAgICAgRklYUF9EQkwgdFNwZWMgPSAqcFNwZWM7CiAgICAgICAgKnBTcGVjLS0gPSBGWF9DTkNMMkZYX0RCTCgqcENuY2wpOwogICAgICAgICpwQ25jbC0tID0gRlhfREJMMkZYX0NOQ0woIHRTcGVjKTsKICAgICAgfQoKICAgICAgLyogY29tcGxldGUgc3dhcHBpbmcgb2Ygd2luZG93IGluZm9zICovCiAgICAgIHBJY3NJbmZvLT5XaW5kb3dTZXF1ZW5jZSA9IHRXaW5kb3dTZXF1ZW5jZTsKICAgICAgcEljc0luZm8tPldpbmRvd1NoYXBlICAgID0gdFdpbmRvd1NoYXBlOwoKICAgICAgLyogY29tcGxldGUgc3dhcHBpbmcgb2Ygc2NhbGUgZmFjdG9ycyAqLwogICAgICBGREttZW1jcHkocFNwZWNTY2FsZSwgdFNwZWNTY2FsZSwgOCpzaXplb2YoU0hPUlQpKTsKICAgIH0KICB9CiAgCn0KCgovKiEKICBcYnJpZWYgQXBwbHkgY29uY2VhbG1lbnQKCiAgSW50ZXJmYWNlIGZ1bmN0aW9uIHRvIGRpZmZlcmVudCBjb25jZWFsbWVudCBzdHJhdGVnaWVzCgogICBccmV0dXJuICBub25lCiAqLwppbnQKICBDQ29uY2VhbG1lbnRfQXBwbHkgKAogICAgQ0NvbmNlYWxtZW50SW5mbyAqaENvbmNlYWxtZW50SW5mbywKICAgIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICBDQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvICpwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvLAogICAgY29uc3QgU2FtcGxpbmdSYXRlSW5mbyAqcFNhbXBsaW5nUmF0ZUluZm8sCiAgICBjb25zdCBpbnQgc2FtcGxlc1BlckZyYW1lLAogICAgY29uc3QgVUNIQVIgbGFzdExwZE1vZGUsCiAgICBjb25zdCBpbnQgZnJhbWVPaywKICAgIGNvbnN0IFVJTlQgZmxhZ3MpCnsKICBpbnQgYXBwbGllZFByb2Nlc3NpbmcgPSAwOwoKICBpZiAoIChmcmFtZU9rID09IDApCiAgICAmJiAocEFhY0RlY29kZXJDaGFubmVsSW5mby0+cmVuZGVyTW9kZSAhPSAoQUFDREVDX1JFTkRFUl9NT0RFKWhDb25jZWFsbWVudEluZm8tPmxhc3RSZW5kZXJNb2RlKSApIHsKICAgIC8qIHJlc3RvcmUgdGhlIGxhc3QgcmVuZGVyIG1vZGUgdG8gc3RheSBpbiB0aGUgc2FtZSBkb21haW4gd2hpY2ggYWxsb3dzIHRvIGRvIGEgcHJvcGVyIGNvbmNlYWxtZW50ICovCiAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5yZW5kZXJNb2RlID0gKEFBQ0RFQ19SRU5ERVJfTU9ERSloQ29uY2VhbG1lbnRJbmZvLT5sYXN0UmVuZGVyTW9kZTsKICB9IGVsc2UgewogICAgLyogb3RoZXJ3aXNlIHN0b3JlIHRoZSBjdXJyZW50IG1vZGUgKi8KICAgIGhDb25jZWFsbWVudEluZm8tPmxhc3RSZW5kZXJNb2RlID0gKFNDSEFSKXBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnJlbmRlck1vZGU7CiAgfQoKICBpZiAoIGZyYW1lT2sgKQogIHsKICAgIC8qIFJlc2N1ZSBjdXJyZW50IGRhdGEgZm9yIGNvbmNlYWxtZW50IGluIGZ1dHVyZSBmcmFtZXMgKi8KICAgIENDb25jZWFsbWVudF9TdG9yZSAoIGhDb25jZWFsbWVudEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbyApOwogICAgLyogUmVzZXQgaW5kZXggdG8gcmFuZG9tIHNpZ24gdmVjdG9yIHRvIG1ha2Ugc2lnbiBjYWxjdWxhdGlvbiBmcmFtZSBhZ25vc3RpYyAKICAgICAgIChvbmx5IGRlcGVuZHMgb24gbnVtYmVyIG9mIHN1YnNlcXVlbnRseSBjb25jZWFsZWQgc3BlY3RyYWwgYmxvY2tzKSAqLwogICAgICAgIGhDb25jZWFsbWVudEluZm8tPmlSYW5kb21QaGFzZSA9IDA7CiAgfQoKICAvKiBoYW5kIGN1cnJlbnQgZnJhbWUgc3RhdHVzIHRvIHRoZSBzdGF0ZSBtYWNoaW5lICovCiAgQ0NvbmNlYWxtZW50X1VwZGF0ZVN0YXRlKCBoQ29uY2VhbG1lbnRJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWVPayApOwoKICB7CiAgICAvKiBDcmVhdGUgZGF0YSBmb3Igc2lnbmFsIHJlbmRlcmluZyBhY2NvcmRpbmcgdG8gdGhlIHNlbGVjdGVkIGNvbmNlYWxtZW50IG1ldGhvZCBhbmQgZGVjb2RlciBvcGVyYXRpbmcgbW9kZS4gKi8KCgogICAgaWYgKCAhKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnJlbmRlck1vZGUgPT0gQUFDREVDX1JFTkRFUl9MUEQKICAgICAgICApCiAgICAgICAgKQogICAgewogICAgICBzd2l0Y2ggKGhDb25jZWFsbWVudEluZm8tPnBDb25jZWFsUGFyYW1zLT5tZXRob2QpCiAgICAgIHsKICAgICAgZGVmYXVsdDoKICAgICAgY2FzZSBDb25jZWFsTWV0aG9kTXV0ZToKICAgICAgICBpZiAoIWZyYW1lT2spIHsKICAgICAgICAgIC8qIE11dGUgc3BlY3RyYWwgZGF0YSBpbiBjYXNlIG9mIGVycm9ycyAqLwogICAgICAgICAgRkRLbWVtY2xlYXIocEFhY0RlY29kZXJDaGFubmVsSW5mby0+cFNwZWN0cmFsQ29lZmZpY2llbnQsIHNhbXBsZXNQZXJGcmFtZSAqIHNpemVvZihGSVhQX0RCTCkpOwogICAgICAgICAgLyogU2V0IGxhc3Qgd2luZG93IHNoYXBlICovCiAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvLldpbmRvd1NoYXBlID0gaENvbmNlYWxtZW50SW5mby0+d2luZG93U2hhcGU7CiAgICAgICAgICBhcHBsaWVkUHJvY2Vzc2luZyA9IDE7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBDb25jZWFsTWV0aG9kTm9pc2U6CiAgICAgICAgLyogTm9pc2Ugc3Vic3RpdHV0aW9uIGVycm9yIGNvbmNlYWxtZW50IHRlY2huaXF1ZSAqLwogICAgICAgIGFwcGxpZWRQcm9jZXNzaW5nID0KICAgICAgICAgIENDb25jZWFsbWVudF9BcHBseU5vaXNlIChoQ29uY2VhbG1lbnRJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2FtcGxpbmdSYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ3MpOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBDb25jZWFsTWV0aG9kSW50ZXI6CiAgICAgICAgLyogRW5lcmd5IGludGVycG9sYXRpb24gY29uY2VhbG1lbnQgYmFzZWQgb24gM0dQUCAqLwogICAgICAgIGFwcGxpZWRQcm9jZXNzaW5nID0KICAgICAgICAgIENDb25jZWFsbWVudF9BcHBseUludGVyIChoQ29uY2VhbG1lbnRJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsICAvKiBkb24ndCB1c2UgdG9uYWwgaW1wcm92ZW1lbnQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZU9rKTsKICAgICAgICBicmVhazsKCiAgICAgIH0KICAgIH0KICB9CiAgLyogdXBkYXRlIGhpc3RvcnkgKi8KICBoQ29uY2VhbG1lbnRJbmZvLT5wcmV2RnJhbWVPa1swXSA9IGhDb25jZWFsbWVudEluZm8tPnByZXZGcmFtZU9rWzFdOwogIGhDb25jZWFsbWVudEluZm8tPnByZXZGcmFtZU9rWzFdID0gZnJhbWVPazsKCiAgcmV0dXJuIGFwcGxpZWRQcm9jZXNzaW5nOwp9CgovKiEKXGJyaWVmIEFwcGx5IGNvbmNlYWxtZW50IG5vaXNlIHN1YnN0aXR1dGlvbgoKICBJbiBjYXNlIG9mIGZyYW1lIGxvc3QgdGhpcyBmdW5jdGlvbiBwcm9kdWNlcyBhIG5vaXN5IGZyYW1lIHdpdGggcmVzcGVjdCB0byB0aGUKICBlbmVyZ2llcyB2YWx1ZXMgb2YgcGFzdCBmcmFtZS4KClxyZXR1cm4gIG5vbmUKICovCnN0YXRpYyBpbnQKICBDQ29uY2VhbG1lbnRfQXBwbHlOb2lzZSAoQ0NvbmNlYWxtZW50SW5mbyAqcENvbmNlYWxtZW50SW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0FhY0RlY29kZXJDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0FhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU2FtcGxpbmdSYXRlSW5mbyAqcFNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCBzYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVJTlQgZmxhZ3MpCnsKICBDQ29uY2VhbFBhcmFtcyAqcENvbmNlYWxDb21tb25EYXRhID0gcENvbmNlYWxtZW50SW5mby0+cENvbmNlYWxQYXJhbXM7CgogIEZJWFBfREJMICpwU3BlY3RyYWxDb2VmZmljaWVudCA9ICBTUEVDX0xPTkcocEFhY0RlY29kZXJDaGFubmVsSW5mby0+cFNwZWN0cmFsQ29lZmZpY2llbnQpOwogIFNIT1JUICAgICpwU3BlY1NjYWxlICAgICAgICAgICA9ICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5zcGVjU2NhbGU7CiAgQ0ljc0luZm8gKnBJY3NJbmZvICAgICAgICAgICAgID0gJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmljc0luZm87CgogIGludCBhcHBsaWVkUHJvY2Vzc2luZyA9IDA7CgogIEZES19BU1NFUlQoKHNhbXBsZXNQZXJGcmFtZT49NDgwKSAmJiAoc2FtcGxlc1BlckZyYW1lPD0xMDI0KSk7CiAgRkRLX0FTU0VSVCgoc2FtcGxlc1BlckZyYW1lJjB4MUYpID09IDApOwoKICBzd2l0Y2ggKHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSkKICB7CiAgY2FzZSBDb25jZWFsU3RhdGVfT2s6CiAgICAvKiBOb3RoaW5nIHRvIGRvIGhlcmUhICovCiAgICBicmVhazsKCiAgY2FzZSBDb25jZWFsU3RhdGVfU2luZ2xlOgogIGNhc2UgQ29uY2VhbFN0YXRlX0ZhZGVPdXQ6CiAgICB7CiAgICAgIC8qIHJlc3RvcmUgZnJlcXVlbmN5IGNvZWZmaWNpZW50cyBmcm9tIGJ1ZmZlciB3aXRoIGEgc3BlY2lmaWMgbXV0aW5nICovCiAgICAgIEZJWFBfU0dMICBmYWM7CiAgICAgIGludCB3aW4sIG51bVdpbmRvd3MgPSAxOwogICAgICBpbnQgd2luZG93TGVuID0gc2FtcGxlc1BlckZyYW1lOwogICAgICBpbnQgdEZhZGVGcmFtZXMsIGxhc3RXaW5kb3cgPSAwOwogICAgICBpbnQgd2luX2lkeF9zdHJpZGUgPSAxOwoKICAgICAgRkRLX0FTU0VSVChwQ29uY2VhbG1lbnRJbmZvICE9IE5VTEwpOwogICAgICBGREtfQVNTRVJUKHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgPj0gMCk7CiAgICAgIEZES19BU1NFUlQocENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcyA8IENPTkNFQUxfTUFYX05VTV9GQURFX0ZBQ1RPUlMpOwogICAgICBGREtfQVNTRVJUKHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgPD0gcENvbmNlYWxDb21tb25EYXRhLT5udW1GYWRlT3V0RnJhbWVzKTsKCiAgICAgIC8qIGdldCBhdHRlbnVhdGlvbiBmYWN0b3IgKi8KICAgICAgdEZhZGVGcmFtZXMgPSBwQ29uY2VhbG1lbnRJbmZvLT5jbnRGYWRlRnJhbWVzOwogICAgICBmYWMgPSBwQ29uY2VhbENvbW1vbkRhdGEtPmZhZGVPdXRGYWN0b3JbdEZhZGVGcmFtZXNdOwoKICAgICAgLyogc2V0IG9sZCB3aW5kb3cgcGFyYW1ldGVycyAqLwogICAgICB7CiAgICAgICAgcEljc0luZm8tPldpbmRvd1NoYXBlICAgID0gcENvbmNlYWxtZW50SW5mby0+d2luZG93U2hhcGU7CiAgICAgICAgcEljc0luZm8tPldpbmRvd1NlcXVlbmNlID0gcENvbmNlYWxtZW50SW5mby0+d2luZG93U2VxdWVuY2U7CgogICAgICAgIGlmIChwQ29uY2VhbG1lbnRJbmZvLT53aW5kb3dTZXF1ZW5jZSA9PSAyKSB7CiAgICAgICAgICAvKiBzaG9ydCBibG9jayBoYW5kbGluZyAqLwogICAgICAgICAgbnVtV2luZG93cyA9IDg7CiAgICAgICAgICB3aW5kb3dMZW4gID0gc2FtcGxlc1BlckZyYW1lID4+IDM7CiAgICAgICAgICBsYXN0V2luZG93ID0gbnVtV2luZG93cyAtIHBDb25jZWFsbWVudEluZm8tPmxhc3RXaW5HcnBMZW47CiAgICAgICAgfQogICAgICB9CgogICAgICBmb3IgKHdpbiA9IDA7IHdpbiA8IG51bVdpbmRvd3M7IHdpbisrKSB7CiAgICAgICAgRklYUF9DTkNMICpwQ25jbCA9IHBDb25jZWFsbWVudEluZm8tPnNwZWN0cmFsQ29lZmZpY2llbnQgKyAobGFzdFdpbmRvdyAqIHdpbmRvd0xlbik7CiAgICAgICAgRklYUF9EQkwgICpwT3V0ICA9IHBTcGVjdHJhbENvZWZmaWNpZW50ICsgKHdpbiAqIHdpbmRvd0xlbik7CiAgICAgICAgaW50IGk7CgogICAgICAgIEZES19BU1NFUlQoKGxhc3RXaW5kb3cgKiB3aW5kb3dMZW4gKyB3aW5kb3dMZW4pIDw9IHNhbXBsZXNQZXJGcmFtZSk7CgogICAgICAgIC8qIHJlc3RvcmUgZnJlcXVlbmN5IGNvZWZmaWNpZW50cyBmcm9tIGJ1ZmZlciB3aXRoIGEgc3BlY2lmaWMgYXR0ZW51YXRpb24gKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgd2luZG93TGVuOyBpKyspIHsKICAgICAgICAgIHBPdXRbaV0gPSBmTXVsdChwQ25jbFtpXSwgZmFjKTsKICAgICAgICB9CgogICAgICAgIC8qIGFwcGx5IHJhbmRvbSBjaGFuZ2Ugb2Ygc2lnbiBmb3Igc3BlY3RyYWwgY29lZmZpY2llbnRzICovCiAgICAgICAgQ0NvbmNlYWxtZW50X0FwcGx5UmFuZG9tU2lnbihwQ29uY2VhbG1lbnRJbmZvLT5pUmFuZG9tUGhhc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE91dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3dMZW4gKTsKCiAgICAgICAgLyogSW5jcmVtZW50IHJhbmRvbSBwaGFzZSBpbmRleCB0byBhdm9pZCByZXBldGl0aW9uIGFydGlmYWN0cy4gKi8KICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5pUmFuZG9tUGhhc2UgPSAocENvbmNlYWxtZW50SW5mby0+aVJhbmRvbVBoYXNlICsgMSkgJiAoQUFDX05GX05PX1JBTkRPTV9WQUwgLSAxKTsKCiAgICAgICAgLyogc2V0IG9sZCBzY2FsZSBmYWN0b3JzICovCiAgICAgICAgcFNwZWNTY2FsZVt3aW4qd2luX2lkeF9zdHJpZGVdID0gcENvbmNlYWxtZW50SW5mby0+c3BlY1NjYWxlW3dpbl9pZHhfc3RyaWRlKmxhc3RXaW5kb3crK107CgogICAgICAgIGlmICggKGxhc3RXaW5kb3cgPj0gbnVtV2luZG93cykKICAgICAgICAgICYmIChudW1XaW5kb3dzID4gIDEpICkKICAgICAgICB7CiAgICAgICAgICAvKiBlbmQgb2Ygc2VxdWVuY2UgLT4gcmV3aW5kICovCiAgICAgICAgICBsYXN0V2luZG93ID0gbnVtV2luZG93cyAtIHBDb25jZWFsbWVudEluZm8tPmxhc3RXaW5HcnBMZW47CiAgICAgICAgICAvKiB1cGRhdGUgdGhlIGF0dGVudWF0aW9uIGZhY3RvciB0byBnZXQgYSBmYXN0ZXIgZmFkZS1vdXQgKi8KICAgICAgICAgIHRGYWRlRnJhbWVzICs9IDE7CiAgICAgICAgICBpZiAodEZhZGVGcmFtZXMgPCBwQ29uY2VhbENvbW1vbkRhdGEtPm51bUZhZGVPdXRGcmFtZXMpIHsKICAgICAgICAgICAgZmFjID0gcENvbmNlYWxDb21tb25EYXRhLT5mYWRlT3V0RmFjdG9yW3RGYWRlRnJhbWVzXTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZhYyA9IChGSVhQX1NHTCkwOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgLyogc3RvcmUgdGVtcCB2YXJzICovCiAgICAgIHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgPSB0RmFkZUZyYW1lczsKICAgICAgYXBwbGllZFByb2Nlc3NpbmcgPSAxOwogICAgfQogICAgYnJlYWs7CgogIGNhc2UgQ29uY2VhbFN0YXRlX011dGU6CiAgICB7CiAgICAgIC8qIHNldCBkdW1teSB3aW5kb3cgcGFyYW1ldGVycyAqLwogICAgICBwSWNzSW5mby0+VmFsaWQgICAgICAgICAgPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogVHJpZ2dlciB0aGUgZ2VuZXJhdGlvbiBvZiBhIGNvbnNpdGVudCBJY3NJbmZvICovCiAgICAgIHBJY3NJbmZvLT5XaW5kb3dTaGFwZSAgICA9IHBDb25jZWFsbWVudEluZm8tPndpbmRvd1NoYXBlOyAgICAvKiBQcmV2ZW50IGFuIGludmFsaWQgV2luZG93U2hhcGUgKHJlcXVpcmVkIGZvciBGL1QgdHJhbnNmb3JtKSAqLwogICAgICBwSWNzSW5mby0+V2luZG93U2VxdWVuY2UgPSBDQ29uY2VhbG1lbnRfR2V0V2luU2VxKHBDb25jZWFsbWVudEluZm8tPndpbmRvd1NlcXVlbmNlKTsKICAgICAgcENvbmNlYWxtZW50SW5mby0+d2luZG93U2VxdWVuY2UgPSBwSWNzSW5mby0+V2luZG93U2VxdWVuY2U7IC8qIFN0b3JlIGZvciBuZXh0IGZyYW1lIChzcGVjdHJ1bSBpbiBjb25jZWFsbWVudCBidWZmZXIgY2FuJ3QgYmUgdXNlZCBhdCBhbGwpICovCgogICAgICAvKiBtdXRlIHNwZWN0cmFsIGRhdGEgKi8KICAgICAgRkRLbWVtY2xlYXIocFNwZWN0cmFsQ29lZmZpY2llbnQsIHNhbXBsZXNQZXJGcmFtZSAqIHNpemVvZihGSVhQX0RCTCkpOwoKICAgICAgaWYgKCAhKGZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwKSkgCiAgICAgICAgICAgJiYgcENvbmNlYWxDb21tb25EYXRhLT5jb21mb3J0Tm9pc2VMZXZlbCA+PSAwCiAgICAgICAgICAgJiYgcENvbmNlYWxDb21tb25EYXRhLT5jb21mb3J0Tm9pc2VMZXZlbCA8PSA2MSAvKiAtOTBkQiAqLykKICAgICAgICB7CiAgICAgICAgLyogaW5zZXJ0IGNvbWZvcnQgbm9pc2UgdXNpbmcgUE5TICovCiAgICAgICAgQ0NvbmNlYWxtZW50X2Zha2VQbnNEYXRhICgKICAgICAgICAgJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmRhdGEuYWFjLlBuc0RhdGEsCiAgICAgICAgICBwSWNzSW5mbywKICAgICAgICAgIHBTYW1wbGluZ1JhdGVJbmZvLAogICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPmFTZmJTY2FsZSwKICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hU2NhbGVGYWN0b3IsCiAgICAgICAgICBwQ29uY2VhbENvbW1vbkRhdGEtPmNvbWZvcnROb2lzZUxldmVsCiAgICAgICAgKTsKCiAgICAgICAgQ1Buc19BcHBseSAoCiAgICAgICAgICAgICAgICZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5kYXRhLmFhYy5QbnNEYXRhLAogICAgICAgICAgICAgICAgcEljc0luZm8sCiAgICAgICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wU3BlY3RyYWxDb2VmZmljaWVudCwKICAgICAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnNwZWNTY2FsZSwKICAgICAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBEeW5EYXRhLT5hU2NhbGVGYWN0b3IsCiAgICAgICAgICAgICAgICBwU2FtcGxpbmdSYXRlSW5mbywKICAgICAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmdyYW51bGVMZW5ndGgsCiAgICAgICAgICAgICAgICAwICAvKiBhbHdheXMgYXBwbHkgdG8gZmlyc3QgY2hhbm5lbCAqLwogICAgICAgICAgICAgICk7CiAgICAgIH0KICAgICAgYXBwbGllZFByb2Nlc3NpbmcgPSAxOwogICAgfQogICAgYnJlYWs7CgogIGNhc2UgQ29uY2VhbFN0YXRlX0ZhZGVJbjoKICAgIHsKICAgICAgRkRLX0FTU0VSVChwQ29uY2VhbG1lbnRJbmZvLT5jbnRGYWRlRnJhbWVzID49IDApOwogICAgICBGREtfQVNTRVJUKHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgPCBDT05DRUFMX01BWF9OVU1fRkFERV9GQUNUT1JTKTsKICAgICAgRkRLX0FTU0VSVChwQ29uY2VhbG1lbnRJbmZvLT5jbnRGYWRlRnJhbWVzIDwgcENvbmNlYWxDb21tb25EYXRhLT5udW1GYWRlSW5GcmFtZXMpOwoKICAgICAgLyogYXR0ZW51YXRlIHNpZ25hbCB0byBnZXQgYSBzbW9vdGggZmFkZS1pbiAqLwogICAgICBGSVhQX0RCTCAqUkVTVFJJQ1QgcE91dCA9ICZwU3BlY3RyYWxDb2VmZmljaWVudFtzYW1wbGVzUGVyRnJhbWUtMV07CiAgICAgIEZJWFBfU0dMIGZhYyA9IHBDb25jZWFsQ29tbW9uRGF0YS0+ZmFkZUluRmFjdG9yW3BDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXNdOwogICAgICBpbnQgaTsKCiAgICAgIGZvciAoaSA9IHNhbXBsZXNQZXJGcmFtZTsgaSAhPSAwOyBpLS0pIHsKICAgICAgICAqcE91dCA9IGZNdWx0KCpwT3V0LCBmYWMpOwogICAgICAgIHBPdXQtLTsKICAgICAgfQogICAgICBhcHBsaWVkUHJvY2Vzc2luZyA9IDE7CiAgICB9CiAgICBicmVhazsKCiAgZGVmYXVsdDoKICAgIC8qIHdlIHNob3VsZG4ndCBjb21lIGhlcmUgYW55d2F5ICovCiAgICBGREtfQVNTRVJUKDApOwogICAgYnJlYWs7CiAgfQoKICByZXR1cm4gYXBwbGllZFByb2Nlc3Npbmc7Cn0KCgovKiEKICBcYnJpZWYgQXBwbHkgY29uY2VhbG1lbnQgaW50ZXJwb2xhdGlvbgoKICBUaGUgZnVuY3Rpb24gc3dhcHMgdGhlIGRhdGEgZnJvbSB0aGUgY3VycmVudCBhbmQgdGhlIHByZXZpb3VzIGZyYW1lLiBJZiBhbgogIGVycm9yIGhhcyBvY2N1cmVkLCBmcmFtZSBpbnRlcnBvbGF0aW9uIGlzIHBlcmZvcm1lZCB0byByZXN0b3JlIHRoZSBtaXNzaW5nCiAgZnJhbWUuIEluIGNhc2Ugb2YgbXVsdGlwbGUgZmF1bHR5IGZyYW1lcywgZmFkZS1pbiBhbmQgZmFkZS1vdXQgaXMgYXBwbGllZC4KCiAgXHJldHVybiAgbm9uZQoqLwpzdGF0aWMgaW50CiAgQ0NvbmNlYWxtZW50X0FwcGx5SW50ZXIgKAogICAgQ0NvbmNlYWxtZW50SW5mbyAgICAgICAqcENvbmNlYWxtZW50SW5mbywKICAgIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICBjb25zdCBTYW1wbGluZ1JhdGVJbmZvICpwU2FtcGxpbmdSYXRlSW5mbywKICAgIGNvbnN0IGludCAgc2FtcGxlc1BlckZyYW1lLAogICAgY29uc3QgaW50ICBpbXByb3ZlVG9uYWwsCiAgICBjb25zdCBpbnQgIGZyYW1lT2sgKQp7CiAgQ0NvbmNlYWxQYXJhbXMgICAqcENvbmNlYWxDb21tb25EYXRhICAgID0gIHBDb25jZWFsbWVudEluZm8tPnBDb25jZWFsUGFyYW1zOwoKICBGSVhQX0RCTCAgICAgICAgICpwU3BlY3RyYWxDb2VmZmljaWVudCAgPSAgU1BFQ19MT05HKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBTcGVjdHJhbENvZWZmaWNpZW50KTsKICBDSWNzSW5mbyAgICAgICAgICpwSWNzSW5mbyAgICAgICAgICAgICAgPSAmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+aWNzSW5mbzsKICBTSE9SVCAgICAgICAgICAgICpwU3BlY1NjYWxlICAgICAgICAgICAgPSAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+c3BlY1NjYWxlOwoKCiAgaW50IHNmYkVuZXJneVByZXZbNjRdOwogIGludCBzZmJFbmVyZ3lBY3QgWzY0XTsKCiAgaW50IGksIGFwcGxpZWRQcm9jZXNzaW5nID0gMDsKCiAgLyogY2xlYXIvaW5pdCAqLwogIEZES21lbWNsZWFyKHNmYkVuZXJneVByZXYsIDY0ICogc2l6ZW9mKGludCkpOwogIEZES21lbWNsZWFyKHNmYkVuZXJneUFjdCwgIDY0ICogc2l6ZW9mKGludCkpOwoKCiAgaWYgKCFmcmFtZU9rKQogIHsKICAgIC8qIFJlc3RvcmUgbGFzdCBmcmFtZSBmcm9tIGNvbmNlYWxtZW50IGJ1ZmZlciAqLwogICAgcEljc0luZm8tPldpbmRvd1NoYXBlICAgID0gcENvbmNlYWxtZW50SW5mby0+d2luZG93U2hhcGU7CiAgICBwSWNzSW5mby0+V2luZG93U2VxdWVuY2UgPSBwQ29uY2VhbG1lbnRJbmZvLT53aW5kb3dTZXF1ZW5jZTsKCiAgICAvKiBSZXN0b3JlIHNwZWN0cmFsIGRhdGEgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBzYW1wbGVzUGVyRnJhbWU7IGkrKykgewogICAgICBwU3BlY3RyYWxDb2VmZmljaWVudFtpXSA9IEZYX0NOQ0wyRlhfREJMKHBDb25jZWFsbWVudEluZm8tPnNwZWN0cmFsQ29lZmZpY2llbnRbaV0pOwogICAgfQoKICAgIC8qIFJlc3RvcmUgc2NhbGUgZmFjdG9ycyAqLwogICAgRkRLbWVtY3B5KHBTcGVjU2NhbGUsIHBDb25jZWFsbWVudEluZm8tPnNwZWNTY2FsZSwgOCpzaXplb2YoU0hPUlQpKTsKICB9CgogIC8qIGlmIHByZXZpb3VzIGZyYW1lIHdhcyBub3Qgb2sgKi8KICBpZiAoIXBDb25jZWFsbWVudEluZm8tPnByZXZGcmFtZU9rWzFdKSB7CgogICAgLyogaWYgY3VycmVudCBmcmFtZSAoZl9uKSBpcyBvayBhbmQgdGhlIGxhc3QgYnV0IG9uZSBmcmFtZSAoZl8obi0yKSkKICAgICAgIHdhcyBvaywgdG9vLCB0aGVuIGludGVycG9sYXRlIGJvdGggZnJhbWVzIGluIG9yZGVyIHRvIGdlbmVyYXRlCiAgICAgICB0aGUgY3VycmVudCBvdXRwdXQgZnJhbWUgKGZfKG4tMSkpLiBPdGhlcndpc2UsIHVzZSB0aGUgbGFzdCBzdG9yZWQKICAgICAgIGZyYW1lIChmXyhuLTIpIG9yIGZfKG4tMykgb3IgLi4uKS4gKi8KICAgIGlmIChmcmFtZU9rICYmIHBDb25jZWFsbWVudEluZm8tPnByZXZGcmFtZU9rWzBdKQogICAgewogICAgICBhcHBsaWVkUHJvY2Vzc2luZyA9IDE7CgoKICAgICAgLyogSW50ZXJwb2xhdGUgYm90aCBmcmFtZXMgaW4gb3JkZXIgdG8gZ2VuZXJhdGUgdGhlIGN1cnJlbnQgb3V0cHV0IGZyYW1lIChmXyhuLTEpKS4gKi8KICAgICAgaWYgKHBJY3NJbmZvLT5XaW5kb3dTZXF1ZW5jZSA9PSBFaWdodFNob3J0U2VxdWVuY2UpIHsKICAgICAgICAvKiBmXyhuLTIpID09IEVpZ2h0U2hvcnRTZXF1ZW5jZSAqLwogICAgICAgIC8qIHNob3J0LS0/Pz8/Pz8tLXNob3J0LCBzaG9ydC0tPz8/Pz8/LS1sb25nIGludGVycG9sYXRpb24gKi8KICAgICAgICAvKiBzaG9ydC0tc2hvcnQtLS1zaG9ydCwgc2hvcnQtLS1sb25nLS0tbG9uZyBpbnRlcnBvbGF0aW9uICovCgogICAgICAgIGludCB3bmQ7CgogICAgICAgIGlmIChwQ29uY2VhbG1lbnRJbmZvLT53aW5kb3dTZXF1ZW5jZSA9PSBFaWdodFNob3J0U2VxdWVuY2UpIHsgLyogZl9uID09IEVpZ2h0U2hvcnRTZXF1ZW5jZSAqLwogICAgICAgICAgLyogc2hvcnQtLXNob3J0LS0tc2hvcnQgaW50ZXJwb2xhdGlvbiAqLwoKICAgICAgICAgIGludCBzY2FsZUZhY3RvckJhbmRzVG90YWwgPSBwU2FtcGxpbmdSYXRlSW5mby0+TnVtYmVyT2ZTY2FsZUZhY3RvckJhbmRzX1Nob3J0OwogICAgICAgICAgY29uc3QgU0hPUlQgKnBTZmJPZmZzZXQgICA9IHBTYW1wbGluZ1JhdGVJbmZvLT5TY2FsZUZhY3RvckJhbmRzX1Nob3J0OwogICAgICAgICAgcEljc0luZm8tPldpbmRvd1NoYXBlID0gMTsKICAgICAgICAgIHBJY3NJbmZvLT5XaW5kb3dTZXF1ZW5jZSA9IEVpZ2h0U2hvcnRTZXF1ZW5jZTsKCiAgICAgICAgICBmb3IgKHduZCA9IDA7IHduZCA8IDg7IHduZCsrKQogICAgICAgICAgewogICAgICAgICAgICBDQ29uY2VhbG1lbnRfQ2FsY0JhbmRFbmVyZ3koCiAgICAgICAgICAgICAgJnBTcGVjdHJhbENvZWZmaWNpZW50W3duZCAqIChzYW1wbGVzUGVyRnJhbWUgLyA4KV0sIC8qIHNwZWNfKG4tMikgKi8KICAgICAgICAgICAgICAgcFNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgIEVpZ2h0U2hvcnRTZXF1ZW5jZSwKICAgICAgICAgICAgICAgQ0NvbmNlYWxtZW50X05vRXhwYW5kLAogICAgICAgICAgICAgICBzZmJFbmVyZ3lQcmV2KTsKCiAgICAgICAgICAgIENDb25jZWFsbWVudF9DYWxjQmFuZEVuZXJneSgKICAgICAgICAgICAgICAmcENvbmNlYWxtZW50SW5mby0+c3BlY3RyYWxDb2VmZmljaWVudFt3bmQgKiAoc2FtcGxlc1BlckZyYW1lIC8gOCldLCAvKiBzcGVjX24gKi8KICAgICAgICAgICAgICAgcFNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgIEVpZ2h0U2hvcnRTZXF1ZW5jZSwKICAgICAgICAgICAgICAgQ0NvbmNlYWxtZW50X05vRXhwYW5kLAogICAgICAgICAgICAgICBzZmJFbmVyZ3lBY3QpOwoKICAgICAgICAgICAgQ0NvbmNlYWxtZW50X0ludGVycG9sYXRlQnVmZmVyKAogICAgICAgICAgICAgICZwU3BlY3RyYWxDb2VmZmljaWVudFt3bmQgKiAoc2FtcGxlc1BlckZyYW1lIC8gOCldLCAvKiBzcGVjXyhuLTEpICovCiAgICAgICAgICAgICAgJnBTcGVjU2NhbGVbd25kXSwKICAgICAgICAgICAgICAmcENvbmNlYWxtZW50SW5mby0+c3BlY1NjYWxlW3duZF0sCiAgICAgICAgICAgICAgJnBTcGVjU2NhbGVbd25kXSwKICAgICAgICAgICAgICAgc2ZiRW5lcmd5UHJldiwKICAgICAgICAgICAgICAgc2ZiRW5lcmd5QWN0LAogICAgICAgICAgICAgICBzY2FsZUZhY3RvckJhbmRzVG90YWwsCiAgICAgICAgICAgICAgIHBTZmJPZmZzZXQpOwoKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgeyAvKiBmX24gIT0gRWlnaHRTaG9ydFNlcXVlbmNlICovCiAgICAgICAgICAvKiBzaG9ydC0tLWxvbmctLS1sb25nIGludGVycG9sYXRpb24gKi8KCiAgICAgICAgICBpbnQgc2NhbGVGYWN0b3JCYW5kc1RvdGFsID0gcFNhbXBsaW5nUmF0ZUluZm8tPk51bWJlck9mU2NhbGVGYWN0b3JCYW5kc19Mb25nOwogICAgICAgICAgY29uc3QgU0hPUlQgKnBTZmJPZmZzZXQgICA9IHBTYW1wbGluZ1JhdGVJbmZvLT5TY2FsZUZhY3RvckJhbmRzX0xvbmc7CiAgICAgICAgICBTSE9SVCBzcGVjU2NhbGVPdXQ7CgogICAgICAgICAgQ0NvbmNlYWxtZW50X0NhbGNCYW5kRW5lcmd5KCZwU3BlY3RyYWxDb2VmZmljaWVudFtzYW1wbGVzUGVyRnJhbWUgLSAoc2FtcGxlc1BlckZyYW1lIC8gOCldLCAvKiBbd25kXSBzcGVjXyhuLTIpICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWlnaHRTaG9ydFNlcXVlbmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENDb25jZWFsbWVudF9FeHBhbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiRW5lcmd5QWN0KTsKCiAgICAgICAgICBDQ29uY2VhbG1lbnRfQ2FsY0JhbmRFbmVyZ3kocENvbmNlYWxtZW50SW5mby0+c3BlY3RyYWxDb2VmZmljaWVudCwgLyogc3BlY19uICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT25seUxvbmdTZXF1ZW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQ29uY2VhbG1lbnRfTm9FeHBhbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiRW5lcmd5UHJldik7CgogICAgICAgICAgcEljc0luZm8tPldpbmRvd1NoYXBlID0gMDsKICAgICAgICAgIHBJY3NJbmZvLT5XaW5kb3dTZXF1ZW5jZSA9IExvbmdTdG9wU2VxdWVuY2U7CgogICAgICAgICAgZm9yIChpID0gMDsgaSA8IHNhbXBsZXNQZXJGcmFtZSA7IGkrKykgewogICAgICAgICAgICBwU3BlY3RyYWxDb2VmZmljaWVudFtpXSA9IHBDb25jZWFsbWVudEluZm8tPnNwZWN0cmFsQ29lZmZpY2llbnRbaV07IC8qIHNwZWNfbiAqLwogICAgICAgICAgfQoKICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCA4OyBpKyspIHsgLyogc2VhcmNoIGZvciBtYXgoc3BlY1NjYWxlKSAqLwogICAgICAgICAgICBpZiAocFNwZWNTY2FsZVtpXSA+IHBTcGVjU2NhbGVbMF0pIHsKICAgICAgICAgICAgICBwU3BlY1NjYWxlWzBdID0gcFNwZWNTY2FsZVtpXTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIENDb25jZWFsbWVudF9JbnRlcnBvbGF0ZUJ1ZmZlcigKICAgICAgICAgICAgcFNwZWN0cmFsQ29lZmZpY2llbnQsIC8qIHNwZWNfKG4tMSkgKi8KICAgICAgICAgICAmcENvbmNlYWxtZW50SW5mby0+c3BlY1NjYWxlWzBdLAogICAgICAgICAgICZwU3BlY1NjYWxlWzBdLAogICAgICAgICAgICZzcGVjU2NhbGVPdXQsCiAgICAgICAgICAgIHNmYkVuZXJneVByZXYsCiAgICAgICAgICAgIHNmYkVuZXJneUFjdCwKICAgICAgICAgICAgc2NhbGVGYWN0b3JCYW5kc1RvdGFsLAogICAgICAgICAgICBwU2ZiT2Zmc2V0KTsKCiAgICAgICAgICBwU3BlY1NjYWxlWzBdID0gc3BlY1NjYWxlT3V0OwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBsb25nLS0/Pz8/Pz8tLXNob3J0LCBsb25nLS0/Pz8/Pz8tLWxvbmcgaW50ZXJwb2xhdGlvbiAqLwogICAgICAgIC8qIGxvbmctLS1sb25nLS0tc2hvcnQsIGxvbmctLS1sb25nLS0tbG9uZyBpbnRlcnBvbGF0aW9uICovCgogICAgICAgIGludCBzY2FsZUZhY3RvckJhbmRzVG90YWwgPSBwU2FtcGxpbmdSYXRlSW5mby0+TnVtYmVyT2ZTY2FsZUZhY3RvckJhbmRzX0xvbmc7CiAgICAgICAgY29uc3QgU0hPUlQgKnBTZmJPZmZzZXQgICA9IHBTYW1wbGluZ1JhdGVJbmZvLT5TY2FsZUZhY3RvckJhbmRzX0xvbmc7CiAgICAgICAgU0hPUlQgc3BlY1NjYWxlQWN0ICAgICAgICA9IHBDb25jZWFsbWVudEluZm8tPnNwZWNTY2FsZVswXTsKCiAgICAgICAgQ0NvbmNlYWxtZW50X0NhbGNCYW5kRW5lcmd5KHBTcGVjdHJhbENvZWZmaWNpZW50LCAgLyogc3BlY18obi0yKSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2FtcGxpbmdSYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT25seUxvbmdTZXF1ZW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0NvbmNlYWxtZW50X05vRXhwYW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJFbmVyZ3lQcmV2KTsKCiAgICAgICAgaWYgKHBDb25jZWFsbWVudEluZm8tPndpbmRvd1NlcXVlbmNlID09IEVpZ2h0U2hvcnRTZXF1ZW5jZSkgeyAgLyogZl9uID09IEVpZ2h0U2hvcnRTZXF1ZW5jZSAqLwogICAgICAgICAgLyogbG9uZy0tLWxvbmctLS1zaG9ydCBpbnRlcnBvbGF0aW9uICovCgogICAgICAgICAgcEljc0luZm8tPldpbmRvd1NoYXBlID0gMTsKICAgICAgICAgIHBJY3NJbmZvLT5XaW5kb3dTZXF1ZW5jZSA9IExvbmdTdGFydFNlcXVlbmNlOwoKICAgICAgICAgIGZvciAoaSA9IDE7IGkgPCA4OyBpKyspIHsgLyogc2VhcmNoIGZvciBtYXgoc3BlY1NjYWxlKSAqLwogICAgICAgICAgICBpZiAocENvbmNlYWxtZW50SW5mby0+c3BlY1NjYWxlW2ldID4gc3BlY1NjYWxlQWN0KSB7CiAgICAgICAgICAgICAgc3BlY1NjYWxlQWN0ID0gcENvbmNlYWxtZW50SW5mby0+c3BlY1NjYWxlW2ldOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgLyogRXhwYW5kIGZpcnN0IHNob3J0IHNwZWN0cnVtICovCiAgICAgICAgICBDQ29uY2VhbG1lbnRfQ2FsY0JhbmRFbmVyZ3kocENvbmNlYWxtZW50SW5mby0+c3BlY3RyYWxDb2VmZmljaWVudCwgIC8qIHNwZWNfbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTYW1wbGluZ1JhdGVJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVpZ2h0U2hvcnRTZXF1ZW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQ29uY2VhbG1lbnRfRXhwYW5kLCAgLyogISEhICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2ZiRW5lcmd5QWN0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLyogbG9uZy0tLWxvbmctLS1sb25nIGludGVycG9sYXRpb24gKi8KCiAgICAgICAgICBwSWNzSW5mby0+V2luZG93U2hhcGUgPSAwOwogICAgICAgICAgcEljc0luZm8tPldpbmRvd1NlcXVlbmNlID0gT25seUxvbmdTZXF1ZW5jZTsKCiAgICAgICAgICBDQ29uY2VhbG1lbnRfQ2FsY0JhbmRFbmVyZ3kocENvbmNlYWxtZW50SW5mby0+c3BlY3RyYWxDb2VmZmljaWVudCwgIC8qIHNwZWNfbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTYW1wbGluZ1JhdGVJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9ubHlMb25nU2VxdWVuY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0NvbmNlYWxtZW50X05vRXhwYW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNmYkVuZXJneUFjdCk7CiAgICAgICAgfQoKICAgICAgICAgIENDb25jZWFsbWVudF9JbnRlcnBvbGF0ZUJ1ZmZlcigKICAgICAgICAgICAgcFNwZWN0cmFsQ29lZmZpY2llbnQsICAvKiBzcGVjXyhuLTEpICovCiAgICAgICAgICAgJnBTcGVjU2NhbGVbMF0sCiAgICAgICAgICAgJnNwZWNTY2FsZUFjdCwKICAgICAgICAgICAmcFNwZWNTY2FsZVswXSwKICAgICAgICAgICAgc2ZiRW5lcmd5UHJldiwKICAgICAgICAgICAgc2ZiRW5lcmd5QWN0LAogICAgICAgICAgICBzY2FsZUZhY3RvckJhbmRzVG90YWwsCiAgICAgICAgICAgIHBTZmJPZmZzZXQpOwoKICAgICAgfQogICAgfQoKICAgICAgLyogTm9pc2Ugc3Vic3RpdHV0aW9uIG9mIHNpZ24gb2YgdGhlIG91dHB1dCBzcGVjdHJhbCBjb2VmZmljaWVudHMgKi8KICAgICAgQ0NvbmNlYWxtZW50X0FwcGx5UmFuZG9tU2lnbiAocENvbmNlYWxtZW50SW5mby0+aVJhbmRvbVBoYXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU3BlY3RyYWxDb2VmZmljaWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlc1BlckZyYW1lKTsKICAgICAgLyogSW5jcmVtZW50IHJhbmRvbSBwaGFzZSBpbmRleCB0byBhdm9pZCByZXBldGl0aW9uIGFydGlmYWN0cy4gKi8KICAgICAgcENvbmNlYWxtZW50SW5mby0+aVJhbmRvbVBoYXNlID0gKHBDb25jZWFsbWVudEluZm8tPmlSYW5kb21QaGFzZSArIDEpICYgKEFBQ19ORl9OT19SQU5ET01fVkFMIC0gMSk7CiAgfQoKICAvKiBzY2FsZSBzcGVjdHJ1bSBhY2NvcmRpbmcgdG8gY29uY2VhbG1lbnQgc3RhdGUgKi8KICBzd2l0Y2ggKHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSkKICB7CiAgY2FzZSBDb25jZWFsU3RhdGVfU2luZ2xlOgogICAgYXBwbGllZFByb2Nlc3NpbmcgPSAxOwogICAgYnJlYWs7CgogIGNhc2UgQ29uY2VhbFN0YXRlX0ZhZGVPdXQ6CiAgICB7CiAgICAgIEZES19BU1NFUlQocENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcyA+PSAwKTsKICAgICAgRkRLX0FTU0VSVChwQ29uY2VhbG1lbnRJbmZvLT5jbnRGYWRlRnJhbWVzIDwgQ09OQ0VBTF9NQVhfTlVNX0ZBREVfRkFDVE9SUyk7CiAgICAgIEZES19BU1NFUlQocENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcyA8IHBDb25jZWFsQ29tbW9uRGF0YS0+bnVtRmFkZU91dEZyYW1lcyk7CgogICAgICAvKiByZXN0b3JlIGZyZXF1ZW5jeSBjb2VmZmljaWVudHMgZnJvbSBidWZmZXIgd2l0aCBhIHNwZWNpZmljIG11dGluZyAqLwogICAgICBGSVhQX0RCTCAqUkVTVFJJQ1QgcE91dCA9ICZwU3BlY3RyYWxDb2VmZmljaWVudFtzYW1wbGVzUGVyRnJhbWUtMV07CiAgICAgIEZJWFBfU0dMIGZhYyA9IHBDb25jZWFsQ29tbW9uRGF0YS0+ZmFkZU91dEZhY3RvcltwQ29uY2VhbG1lbnRJbmZvLT5jbnRGYWRlRnJhbWVzXTsKCiAgICAgIGZvciAoaSA9IHNhbXBsZXNQZXJGcmFtZTsgaSAhPSAwOyBpLS0pIHsKICAgICAgICAqcE91dCA9IGZNdWx0KCpwT3V0LCBmYWMpOwogICAgICAgIHBPdXQtLTsKICAgICAgfQogICAgICBhcHBsaWVkUHJvY2Vzc2luZyA9IDE7CiAgICB9CiAgICBicmVhazsKCiAgY2FzZSBDb25jZWFsU3RhdGVfRmFkZUluOgogICAgewogICAgICBGREtfQVNTRVJUKHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgPj0gMCk7CiAgICAgIEZES19BU1NFUlQocENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcyA8IENPTkNFQUxfTUFYX05VTV9GQURFX0ZBQ1RPUlMpOwogICAgICBGREtfQVNTRVJUKHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgPCBwQ29uY2VhbENvbW1vbkRhdGEtPm51bUZhZGVJbkZyYW1lcyk7CgogICAgICAvKiBhdHRlbnVhdGUgc2lnbmFsIHRvIGdldCBhIHNtb290aCBmYWRlLWluICovCiAgICAgIEZJWFBfREJMICpSRVNUUklDVCBwT3V0ID0gJnBTcGVjdHJhbENvZWZmaWNpZW50W3NhbXBsZXNQZXJGcmFtZS0xXTsKICAgICAgRklYUF9TR0wgZmFjID0gcENvbmNlYWxDb21tb25EYXRhLT5mYWRlSW5GYWN0b3JbcENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lc107CgogICAgICBmb3IgKGkgPSBzYW1wbGVzUGVyRnJhbWU7IGkgIT0gMDsgaS0tKSB7CiAgICAgICAgKnBPdXQgPSBmTXVsdCgqcE91dCwgZmFjKTsKICAgICAgICBwT3V0LS07CiAgICAgIH0KICAgICAgYXBwbGllZFByb2Nlc3NpbmcgPSAxOwogICAgfQogICAgYnJlYWs7CgogIGNhc2UgQ29uY2VhbFN0YXRlX011dGU6CiAgICB7CiAgICAgIGludCBmYWMgPSBwQ29uY2VhbENvbW1vbkRhdGEtPmNvbWZvcnROb2lzZUxldmVsOwoKICAgICAgLyogc2V0IGR1bW15IHdpbmRvdyBwYXJhbWV0ZXJzICovCiAgICAgIHBJY3NJbmZvLT5WYWxpZCAgICAgICAgICA9IDA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBUcmlnZ2VyIHRoZSBnZW5lcmF0aW9uIG9mIGEgY29uc2l0ZW50IEljc0luZm8gKi8KICAgICAgcEljc0luZm8tPldpbmRvd1NoYXBlICAgID0gcENvbmNlYWxtZW50SW5mby0+d2luZG93U2hhcGU7ICAgIC8qIFByZXZlbnQgYW4gaW52YWxpZCBXaW5kb3dTaGFwZSAocmVxdWlyZWQgZm9yIEYvVCB0cmFuc2Zvcm0pICovCiAgICAgIHBJY3NJbmZvLT5XaW5kb3dTZXF1ZW5jZSA9IENDb25jZWFsbWVudF9HZXRXaW5TZXEocENvbmNlYWxtZW50SW5mby0+d2luZG93U2VxdWVuY2UpOwogICAgICBwQ29uY2VhbG1lbnRJbmZvLT53aW5kb3dTZXF1ZW5jZSA9IHBJY3NJbmZvLT5XaW5kb3dTZXF1ZW5jZTsgLyogU3RvcmUgZm9yIG5leHQgZnJhbWUgKHNwZWN0cnVtIGluIGNvbmNlYWxtZW50IGJ1ZmZlciBjYW4ndCBiZSB1c2VkIGF0IGFsbCkgKi8KCiAgICAgIC8qIG11dGUgc3BlY3RyYWwgZGF0YSAqLwogICAgICBGREttZW1jbGVhcihwU3BlY3RyYWxDb2VmZmljaWVudCwgc2FtcGxlc1BlckZyYW1lICogc2l6ZW9mKEZJWFBfREJMKSk7CgogICAgICBpZiAoZmFjID49IDAgJiYgZmFjIDw9IDYxKSB7CiAgICAgICAgLyogaW5zZXJ0IGNvbWZvcnQgbm9pc2UgdXNpbmcgUE5TICovCiAgICAgICAgQ0NvbmNlYWxtZW50X2Zha2VQbnNEYXRhICgKICAgICAgICAgJnBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPmRhdGEuYWFjLlBuc0RhdGEsCiAgICAgICAgICBwSWNzSW5mbywKICAgICAgICAgIHBTYW1wbGluZ1JhdGVJbmZvLAogICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+c3BlY1NjYWxlLAogICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cER5bkRhdGEtPmFTY2FsZUZhY3RvciwKICAgICAgICAgIGZhYwogICAgICAgICk7CgogICAgICAgIENQbnNfQXBwbHkgKAogICAgICAgICAgICAgICAmcEFhY0RlY29kZXJDaGFubmVsSW5mby0+ZGF0YS5hYWMuUG5zRGF0YSwKICAgICAgICAgICAgICAgIHBJY3NJbmZvLAogICAgICAgICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+cFNwZWN0cmFsQ29lZmZpY2llbnQsCiAgICAgICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5zcGVjU2NhbGUsCiAgICAgICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wRHluRGF0YS0+YVNjYWxlRmFjdG9yLAogICAgICAgICAgICAgICAgcFNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5ncmFudWxlTGVuZ3RoLAogICAgICAgICAgICAgICAgMCAgLyogYWx3YXlzIGFwcGx5IHRvIGZpcnN0IGNoYW5uZWwgKi8KICAgICAgICAgICAgICApOwogICAgICB9CiAgICAgIGFwcGxpZWRQcm9jZXNzaW5nID0gMTsKICAgIH0KICAgIGJyZWFrOwoKICBkZWZhdWx0OgogICAgLyogbm90aGluZyB0byBkbyBoZXJlICovCiAgICBicmVhazsKICB9CgogIHJldHVybiBhcHBsaWVkUHJvY2Vzc2luZzsKfQoKCi8qIQogIFxicmllZiBDYWxjdWxhdGUgdGhlIHNwZWN0cmFsIGVuZXJneQoKICBUaGUgZnVuY3Rpb24gY2FsY3VsYXRlcyBiYW5kLXdpc2UgdGhlIHNwZWN0cmFsIGVuZXJneS4gVGhpcyBpcyB1c2VkIGZvcgogIGZyYW1lIGludGVycG9sYXRpb24uCgogIFxyZXR1cm4gIG5vbmUKKi8Kc3RhdGljIHZvaWQKICBDQ29uY2VhbG1lbnRfQ2FsY0JhbmRFbmVyZ3kgKAogICAgRklYUF9EQkwgICAgICAgICAgICAgICAqc3BlY3RydW0sCiAgICBjb25zdCBTYW1wbGluZ1JhdGVJbmZvICpwU2FtcGxpbmdSYXRlSW5mbywKICAgIGNvbnN0IGludCAgICAgICAgICAgICAgIGJsb2NrVHlwZSwKICAgIENDb25jZWFsbWVudEV4cGFuZFR5cGUgIGV4cGFuZFR5cGUsCiAgICBpbnQgICAgICAgICAgICAgICAgICAgICpzZmJFbmVyZ3kgKQp7CiAgY29uc3QgU0hPUlQgKnBTZmJPZmZzZXQ7CiAgaW50IGxpbmUsIHNmYiwgc2NhbGVGYWN0b3JCYW5kc1RvdGFsID0gMDsKICAKICAvKiBJbiB0aGUgZm9sbG93aW5nIGNhbGN1bGF0aW9ucywgZW5BY2N1IGlzIGluaXRpYWxpemVkIHdpdGggTFNCLXZhbHVlIGluIG9yZGVyIHRvIGF2b2lkIHplcm8gZW5lcmd5LWxldmVsICovCgogIGxpbmUgPSAwOwoKICBzd2l0Y2goYmxvY2tUeXBlKSB7CgogIGNhc2UgT25seUxvbmdTZXF1ZW5jZToKICBjYXNlIExvbmdTdGFydFNlcXVlbmNlOgogIGNhc2UgTG9uZ1N0b3BTZXF1ZW5jZToKCiAgICBpZiAoZXhwYW5kVHlwZSA9PSBDQ29uY2VhbG1lbnRfTm9FeHBhbmQpIHsKICAgICAgLyogc3RhbmRhcmQgbG9uZyBjYWxjdWxhdGlvbiAqLwogICAgICBzY2FsZUZhY3RvckJhbmRzVG90YWwgPSBwU2FtcGxpbmdSYXRlSW5mby0+TnVtYmVyT2ZTY2FsZUZhY3RvckJhbmRzX0xvbmc7CiAgICAgIHBTZmJPZmZzZXQgICAgICAgICAgICA9IHBTYW1wbGluZ1JhdGVJbmZvLT5TY2FsZUZhY3RvckJhbmRzX0xvbmc7CgogICAgICBmb3IgKHNmYiA9IDA7IHNmYiA8IHNjYWxlRmFjdG9yQmFuZHNUb3RhbDsgc2ZiKyspIHsKICAgICAgICBGSVhQX0RCTCBlbkFjY3UgPSAoRklYUF9EQkwpKExPTkcpMTsKICAgICAgICBpbnQgc2ZiU2NhbGUgPSAoc2l6ZW9mKExPTkcpPDwzKSAtIENudExlYWRpbmdaZXJvcyhwU2ZiT2Zmc2V0W3NmYisxXSAtIHBTZmJPZmZzZXRbc2ZiXSkgLSAxOwogICAgICAgIC8qIHNjYWxpbmcgZGVwZW5kcyBvbiBzZmIgd2lkdGguICovCiAgICAgICAgZm9yICggOyBsaW5lIDwgcFNmYk9mZnNldFtzZmIrMV07IGxpbmUrKykgewogICAgICAgICAgZW5BY2N1ICs9IGZQb3cyRGl2MigqKHNwZWN0cnVtICsgbGluZSkpID4+IHNmYlNjYWxlOwogICAgICAgIH0KICAgICAgICAqKHNmYkVuZXJneSArIHNmYikgPSBDbnRMZWFkaW5nWmVyb3MoZW5BY2N1KSAtIDE7CiAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICAvKiBjb21wcmVzcyBsb25nIHRvIHNob3J0ICovCiAgICAgIHNjYWxlRmFjdG9yQmFuZHNUb3RhbCA9IHBTYW1wbGluZ1JhdGVJbmZvLT5OdW1iZXJPZlNjYWxlRmFjdG9yQmFuZHNfU2hvcnQ7CiAgICAgIHBTZmJPZmZzZXQgICAgICAgICAgICA9IHBTYW1wbGluZ1JhdGVJbmZvLT5TY2FsZUZhY3RvckJhbmRzX1Nob3J0OwoKICAgICAgZm9yIChzZmIgPSAwOyBzZmIgPCBzY2FsZUZhY3RvckJhbmRzVG90YWw7IHNmYisrKSB7CiAgICAgICAgRklYUF9EQkwgZW5BY2N1ID0gKEZJWFBfREJMKShMT05HKTE7CiAgICAgICAgaW50IHNmYlNjYWxlID0gKHNpemVvZihMT05HKTw8MykgLSBDbnRMZWFkaW5nWmVyb3MocFNmYk9mZnNldFtzZmIrMV0gLSBwU2ZiT2Zmc2V0W3NmYl0pIC0gMTsKICAgICAgICAvKiBzY2FsaW5nIGRlcGVuZHMgb24gc2ZiIHdpZHRoLiAqLwogICAgICAgIGZvciAoOyBsaW5lIDwgcFNmYk9mZnNldFtzZmIrMV0gPDwgMzsgbGluZSsrKSB7CiAgICAgICAgICBlbkFjY3UgKz0gKGVuQWNjdSArIChmUG93MkRpdjIoKihzcGVjdHJ1bSArIGxpbmUpKSA+PiBzZmJTY2FsZSkpID4+IDM7CiAgICAgICAgfQogICAgICAgICooc2ZiRW5lcmd5ICsgc2ZiKSA9IENudExlYWRpbmdaZXJvcyhlbkFjY3UpIC0gMTsKICAgICAgfQogICAgfQogICAgYnJlYWs7CgogIGNhc2UgRWlnaHRTaG9ydFNlcXVlbmNlOgoKICAgIGlmIChleHBhbmRUeXBlID09IENDb25jZWFsbWVudF9Ob0V4cGFuZCkgewogICAgICAvKiAgIHN0YW5kYXJkIHNob3J0IGNhbGN1bGF0aW9uICovCiAgICAgIHNjYWxlRmFjdG9yQmFuZHNUb3RhbCA9IHBTYW1wbGluZ1JhdGVJbmZvLT5OdW1iZXJPZlNjYWxlRmFjdG9yQmFuZHNfU2hvcnQ7CiAgICAgIHBTZmJPZmZzZXQgICAgICAgICAgICA9IHBTYW1wbGluZ1JhdGVJbmZvLT5TY2FsZUZhY3RvckJhbmRzX1Nob3J0OwoKICAgICAgZm9yIChzZmIgPSAwOyBzZmIgPCBzY2FsZUZhY3RvckJhbmRzVG90YWw7IHNmYisrKSB7CiAgICAgICAgRklYUF9EQkwgZW5BY2N1ID0gKEZJWFBfREJMKShMT05HKTE7CiAgICAgICAgaW50IHNmYlNjYWxlID0gKHNpemVvZihMT05HKTw8MykgLSBDbnRMZWFkaW5nWmVyb3MocFNmYk9mZnNldFtzZmIrMV0gLSBwU2ZiT2Zmc2V0W3NmYl0pIC0gMTsKICAgICAgICAvKiBzY2FsaW5nIGRlcGVuZHMgb24gc2ZiIHdpZHRoLiAqLwogICAgICAgIGZvciAoIDsgbGluZSA8IHBTZmJPZmZzZXRbc2ZiKzFdOyBsaW5lKyspIHsKICAgICAgICAgIGVuQWNjdSArPSBmUG93MkRpdjIoKihzcGVjdHJ1bSArIGxpbmUpKSA+PiBzZmJTY2FsZTsKICAgICAgICB9CiAgICAgICAgKihzZmJFbmVyZ3kgKyBzZmIpID0gQ250TGVhZGluZ1plcm9zKGVuQWNjdSkgLSAxOwogICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgLyogIGV4cGFuZCBzaG9ydCB0byBsb25nIHNwZWN0cnVtICovCiAgICAgIHNjYWxlRmFjdG9yQmFuZHNUb3RhbCA9IHBTYW1wbGluZ1JhdGVJbmZvLT5OdW1iZXJPZlNjYWxlRmFjdG9yQmFuZHNfTG9uZzsKICAgICAgcFNmYk9mZnNldCAgICAgICAgICAgID0gcFNhbXBsaW5nUmF0ZUluZm8tPlNjYWxlRmFjdG9yQmFuZHNfTG9uZzsKCiAgICAgIGZvciAoc2ZiID0gMDsgc2ZiIDwgc2NhbGVGYWN0b3JCYW5kc1RvdGFsOyBzZmIrKykgewogICAgICAgIEZJWFBfREJMIGVuQWNjdSA9IChGSVhQX0RCTCkoTE9ORykxOwogICAgICAgIGludCBzZmJTY2FsZSA9IChzaXplb2YoTE9ORyk8PDMpIC0gQ250TGVhZGluZ1plcm9zKHBTZmJPZmZzZXRbc2ZiKzFdIC0gcFNmYk9mZnNldFtzZmJdKSAtIDE7CiAgICAgICAgLyogc2NhbGluZyBkZXBlbmRzIG9uIHNmYiB3aWR0aC4gKi8KICAgICAgICBmb3IgKCA7IGxpbmUgPCBwU2ZiT2Zmc2V0W3NmYisxXTsgbGluZSsrKSB7CiAgICAgICAgICBlbkFjY3UgKz0gZlBvdzJEaXYyKCooc3BlY3RydW0gKyAobGluZSA+PiAzKSkpID4+IHNmYlNjYWxlOwogICAgICAgIH0KICAgICAgICAqKHNmYkVuZXJneSArIHNmYikgPSBDbnRMZWFkaW5nWmVyb3MoZW5BY2N1KSAtIDE7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIH0KfQoKCi8qIQogIFxicmllZiBJbnRlcnBvbGF0ZSBidWZmZXIKCiAgVGhlIGZ1bmN0aW9uIGNyZWF0ZXMgdGhlIGludGVycG9sYXRlZCBzcGVjdHJhbCBkYXRhIGFjY29yZGluZyB0byB0aGUKICBlbmVyZ3kgb2YgdGhlIGxhc3QgZ29vZCBmcmFtZSBhbmQgdGhlIGN1cnJlbnQgKGdvb2QpIGZyYW1lLgoKICBccmV0dXJuICBub25lCiovCnN0YXRpYyB2b2lkCiAgQ0NvbmNlYWxtZW50X0ludGVycG9sYXRlQnVmZmVyICgKICAgIEZJWFBfREJMICAgICpzcGVjdHJ1bSwKICAgIFNIT1JUICAgICAgICpwU3BlY1NjYWxlUHJ2LAogICAgU0hPUlQgICAgICAgKnBTcGVjU2NhbGVBY3QsCiAgICBTSE9SVCAgICAgICAqcFNwZWNTY2FsZU91dCwKICAgIGludCAgICAgICAgICplblBydiwKICAgIGludCAgICAgICAgICplbkFjdCwKICAgIGludCAgICAgICAgICBzZmJDbnQsCiAgICBjb25zdCBTSE9SVCAqcFNmYk9mZnNldCApCnsKICBpbnQgICAgc2ZiLCBsaW5lID0gMDsKICBpbnQgICAgZmFjX3NoaWZ0OwogIGludCAgICBmYWNfbW9kOwogIEZJWFBfREJMIGFjY3U7CgogIGZvciAoc2ZiID0gMDsgc2ZiIDwgc2ZiQ250OyBzZmIrKykgewoKICAgIGZhY19zaGlmdCA9IGVuUHJ2W3NmYl0gLSBlbkFjdFtzZmJdICsgKCgqcFNwZWNTY2FsZUFjdCAtICpwU3BlY1NjYWxlUHJ2KSA8PCAxKTsKICAgIGZhY19tb2QgICA9IGZhY19zaGlmdCAmIDM7CiAgICBmYWNfc2hpZnQgPSAoZmFjX3NoaWZ0ID4+IDIpICsgMTsKICAgIGZhY19zaGlmdCArPSAqcFNwZWNTY2FsZVBydiAtIGZpeE1heCgqcFNwZWNTY2FsZVBydiwgKnBTcGVjU2NhbGVBY3QpOwoKICAgIGZvciAoOyBsaW5lIDwgcFNmYk9mZnNldFtzZmIrMV07IGxpbmUrKykgewogICAgICBhY2N1ID0gZk11bHQoKihzcGVjdHJ1bStsaW5lKSwgZmFjTW9kNFRhYmxlW2ZhY19tb2RdKTsKICAgICAgaWYgKGZhY19zaGlmdCA8IDApIHsKICAgICAgICBhY2N1ID4+PSAtZmFjX3NoaWZ0OwogICAgICB9IGVsc2UgewogICAgICAgIGFjY3UgPDw9IGZhY19zaGlmdDsKICAgICAgfQogICAgICAqKHNwZWN0cnVtK2xpbmUpID0gYWNjdTsKICAgIH0KICB9CiAgKnBTcGVjU2NhbGVPdXQgPSBmaXhNYXgoKnBTcGVjU2NhbGVQcnYsICpwU3BlY1NjYWxlQWN0KTsKfQoKCgoKc3RhdGljIElOVCBmaW5kRXF1aUZhZGVGcmFtZSAoCiAgICBDQ29uY2VhbFBhcmFtcyAqcENvbmNlYWxDb21tb25EYXRhLAogICAgSU5UIGFjdEZhZGVJbmRleCwKICAgIGludCBkaXJlY3Rpb24gKQp7CiAgRklYUF9TR0wgKnBGYWN0b3I7CiAgRklYUF9TR0wgIHJlZmVyZW5jZVZhbDsKICBGSVhQX1NHTCAgbWluRGlmZiA9IChGSVhQX1NHTClNQVhWQUxfU0dMOwoKICBJTlQgIG51bUZyYW1lcyA9IDA7CiAgSU5UICBuZXh0RmFkZUluZGV4ID0gMDsKCiAgaW50ICBpOwoKICAvKiBpbml0IGRlcGVuZGluZyBvbiBkaXJlY3Rpb24gKi8KICBpZiAoZGlyZWN0aW9uID09IDApIHsgIC8qIEZBREUtT1VUID0+IEZBREUtSU4gKi8KICAgIG51bUZyYW1lcyA9IHBDb25jZWFsQ29tbW9uRGF0YS0+bnVtRmFkZUluRnJhbWVzOwogICAgcmVmZXJlbmNlVmFsID0gcENvbmNlYWxDb21tb25EYXRhLT5mYWRlT3V0RmFjdG9yW2FjdEZhZGVJbmRleF0gPj4gMTsKICAgIHBGYWN0b3IgPSBwQ29uY2VhbENvbW1vbkRhdGEtPmZhZGVJbkZhY3RvcjsKICB9CiAgZWxzZSB7ICAvKiBGQURFLUlOID0+IEZBREUtT1VUICovCiAgICBudW1GcmFtZXMgPSBwQ29uY2VhbENvbW1vbkRhdGEtPm51bUZhZGVPdXRGcmFtZXM7CiAgICByZWZlcmVuY2VWYWwgPSBwQ29uY2VhbENvbW1vbkRhdGEtPmZhZGVJbkZhY3RvclthY3RGYWRlSW5kZXhdID4+IDE7CiAgICBwRmFjdG9yID0gcENvbmNlYWxDb21tb25EYXRhLT5mYWRlT3V0RmFjdG9yOwogIH0KCiAgLyogc2VhcmNoIGZvciBtaW5pbXVtIGRpZmZlcmVuY2UgKi8KICBmb3IgKGkgPSAwOyBpIDwgbnVtRnJhbWVzOyBpKyspIHsKICAgIEZJWFBfU0dMIGRpZmYgPSBmaXhwX2FicygocEZhY3RvcltpXT4+MSkgLSByZWZlcmVuY2VWYWwpOwogICAgaWYgKGRpZmYgPCBtaW5EaWZmKSB7CiAgICAgIG1pbkRpZmYgPSBkaWZmOwogICAgICBuZXh0RmFkZUluZGV4ID0gaTsKICAgIH0KICB9CgogIC8qIGNoZWNrIGFuZCBhZGp1c3QgZGVwZW5kaW5nIG9uIGRpcmVjdGlvbiAqLwogIGlmIChkaXJlY3Rpb24gPT0gMCkgeyAgLyogRkFERS1PVVQgPT4gRkFERS1JTiAqLwogICAgaWYgKCgocEZhY3RvcltuZXh0RmFkZUluZGV4XT4+MSkgPD0gcmVmZXJlbmNlVmFsKSAmJiAobmV4dEZhZGVJbmRleCA+IDApKSB7CiAgICAgIG5leHRGYWRlSW5kZXggLT0gMTsKICAgIH0KICB9CiAgZWxzZSB7ICAvKiBGQURFLUlOID0+IEZBREUtT1VUICovCiAgICBpZiAoKChwRmFjdG9yW25leHRGYWRlSW5kZXhdPj4xKSA+PSByZWZlcmVuY2VWYWwpICYmIChuZXh0RmFkZUluZGV4IDwgbnVtRnJhbWVzLTEpKSB7CiAgICAgIG5leHRGYWRlSW5kZXggKz0gMTsKICAgIH0KICB9CgogIHJldHVybiAobmV4dEZhZGVJbmRleCk7Cn0KCgovKiEKICBcYnJpZWYgVXBkYXRlIHRoZSBjb25jZWFsbWVudCBzdGF0ZQoKICBUaGUgZnVuY3Rpb24gdXBkYXRlcyB0aGUgc3RhdGUgb2YgdGhlIGNvbmNlYWxtZW50IHN0YXRlLW1hY2hpbmUuIFRoZQogIHN0YXRlcyBhcmU6IG11dGUsIGZhZGUtaW4sIGZhZGUtb3V0LCBpbnRlcnBvbGF0ZSBhbmQgZnJhbWUtb2suCgogIFxyZXR1cm4gIG5vbmUKKi8Kc3RhdGljIHZvaWQKICBDQ29uY2VhbG1lbnRfVXBkYXRlU3RhdGUgKAogICAgQ0NvbmNlYWxtZW50SW5mbyAqcENvbmNlYWxtZW50SW5mbywKICAgIGludCBmcmFtZU9rICkKewogIENDb25jZWFsUGFyYW1zICpwQ29uY2VhbENvbW1vbkRhdGEgPSBwQ29uY2VhbG1lbnRJbmZvLT5wQ29uY2VhbFBhcmFtczsKCiAgc3dpdGNoIChwQ29uY2VhbENvbW1vbkRhdGEtPm1ldGhvZCkKICB7CiAgY2FzZSBDb25jZWFsTWV0aG9kTm9pc2U6CiAgICB7CiAgICAgIGlmIChwQ29uY2VhbG1lbnRJbmZvLT5jb25jZWFsU3RhdGUgIT0gQ29uY2VhbFN0YXRlX09rKSB7CiAgICAgICAgLyogY291bnQgdGhlIHZhbGlkIGZyYW1lcyBkdXJpbmcgY29uY2VhbG1lbnQgcHJvY2VzcyAqLwogICAgICAgIGlmIChmcmFtZU9rKSB7CiAgICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jbnRWYWxpZEZyYW1lcyArPSAxOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jbnRWYWxpZEZyYW1lcyAgPSAwOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLyogLS0gU1RBVEUgTUFDSElORSBmb3IgTm9pc2UgU3Vic3RpdHV0aW9uIC0tICovCiAgICAgIHN3aXRjaCAocENvbmNlYWxtZW50SW5mby0+Y29uY2VhbFN0YXRlKQogICAgICB7CiAgICAgIGNhc2UgQ29uY2VhbFN0YXRlX09rOgogICAgICAgIGlmICghZnJhbWVPaykgewogICAgICAgICAgaWYgKHBDb25jZWFsQ29tbW9uRGF0YS0+bnVtRmFkZU91dEZyYW1lcyA+IDApIHsKICAgICAgICAgICAgLyogY2hhbmdlIHRvIHN0YXRlIFNJTkdMRS1GUkFNRS1MT1NTICovCiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSAgID0gQ29uY2VhbFN0YXRlX1NpbmdsZTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIGNoYW5nZSB0byBzdGF0ZSBNVVRFICovCiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSA9IENvbmNlYWxTdGF0ZV9NdXRlOwogICAgICAgICAgfQogICAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcyAgPSAwOwogICAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y250VmFsaWRGcmFtZXMgPSAwOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgQ29uY2VhbFN0YXRlX1NpbmdsZTogIC8qIEp1c3QgYSBwcmUtc3RhZ2UgYmVmb3JlIGZhZGUtb3V0IGJlZ2lucy4gU3RheSBoZXJlIG9ubHkgb25lIGZyYW1lISAqLwogICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgKz0gMTsKICAgICAgICBpZiAoZnJhbWVPaykgewogICAgICAgICAgaWYgKHBDb25jZWFsbWVudEluZm8tPmNudFZhbGlkRnJhbWVzID4gcENvbmNlYWxDb21tb25EYXRhLT5udW1NdXRlUmVsZWFzZUZyYW1lcykgewogICAgICAgICAgICAvKiBjaGFuZ2UgdG8gc3RhdGUgRkFERS1JTiAqLwogICAgICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jb25jZWFsU3RhdGUgID0gQ29uY2VhbFN0YXRlX0ZhZGVJbjsKICAgICAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcyA9IGZpbmRFcXVpRmFkZUZyYW1lKCBwQ29uY2VhbENvbW1vbkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcy0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogRmFkZU91dCAtPiBGYWRlSW4gKi8pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogY2hhbmdlIHRvIHN0YXRlIE9LICovCiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSA9IENvbmNlYWxTdGF0ZV9PazsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgPj0gcENvbmNlYWxDb21tb25EYXRhLT5udW1GYWRlT3V0RnJhbWVzKSB7CiAgICAgICAgICAgIC8qIGNoYW5nZSB0byBzdGF0ZSBNVVRFICovCiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSA9IENvbmNlYWxTdGF0ZV9NdXRlOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogY2hhbmdlIHRvIHN0YXRlIEZBREUtT1VUICovCiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSA9IENvbmNlYWxTdGF0ZV9GYWRlT3V0OwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgQ29uY2VhbFN0YXRlX0ZhZGVPdXQ6CiAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcyArPSAxOyAgLyogdXNlZCB0byBhZGRyZXNzIHRoZSBmYWRlLW91dCBmYWN0b3JzICovCiAgICAgICAgaWYgKHBDb25jZWFsbWVudEluZm8tPmNudFZhbGlkRnJhbWVzID4gcENvbmNlYWxDb21tb25EYXRhLT5udW1NdXRlUmVsZWFzZUZyYW1lcykgewogICAgICAgICAgaWYgKHBDb25jZWFsQ29tbW9uRGF0YS0+bnVtRmFkZUluRnJhbWVzID4gMCkgewogICAgICAgICAgICAvKiBjaGFuZ2UgdG8gc3RhdGUgRkFERS1JTiAqLwogICAgICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jb25jZWFsU3RhdGUgID0gQ29uY2VhbFN0YXRlX0ZhZGVJbjsKICAgICAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcyA9IGZpbmRFcXVpRmFkZUZyYW1lKCBwQ29uY2VhbENvbW1vbkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcy0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogRmFkZU91dCAtPiBGYWRlSW4gKi8pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogY2hhbmdlIHRvIHN0YXRlIE9LICovCiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSA9IENvbmNlYWxTdGF0ZV9PazsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgPj0gcENvbmNlYWxDb21tb25EYXRhLT5udW1GYWRlT3V0RnJhbWVzKSB7CiAgICAgICAgICAgIC8qIGNoYW5nZSB0byBzdGF0ZSBNVVRFICovCiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSA9IENvbmNlYWxTdGF0ZV9NdXRlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgQ29uY2VhbFN0YXRlX011dGU6CiAgICAgICAgaWYgKHBDb25jZWFsbWVudEluZm8tPmNudFZhbGlkRnJhbWVzID4gcENvbmNlYWxDb21tb25EYXRhLT5udW1NdXRlUmVsZWFzZUZyYW1lcykgewogICAgICAgICAgaWYgKHBDb25jZWFsQ29tbW9uRGF0YS0+bnVtRmFkZUluRnJhbWVzID4gMCkgewogICAgICAgICAgICAvKiBjaGFuZ2UgdG8gc3RhdGUgRkFERS1JTiAqLwogICAgICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jb25jZWFsU3RhdGUgPSBDb25jZWFsU3RhdGVfRmFkZUluOwogICAgICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jbnRGYWRlRnJhbWVzID0gcENvbmNlYWxDb21tb25EYXRhLT5udW1GYWRlSW5GcmFtZXMgLSAxOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogY2hhbmdlIHRvIHN0YXRlIE9LICovCiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSA9IENvbmNlYWxTdGF0ZV9PazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIENvbmNlYWxTdGF0ZV9GYWRlSW46CiAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcyAtPSAxOyAgLyogdXNlZCB0byBhZGRyZXNzIHRoZSBmYWRlLWluIGZhY3RvcnMgKi8KICAgICAgICBpZiAoZnJhbWVPaykgewogICAgICAgICAgaWYgKHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgPCAwKSB7CiAgICAgICAgICAgIC8qIGNoYW5nZSB0byBzdGF0ZSBPSyAqLwogICAgICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jb25jZWFsU3RhdGUgPSBDb25jZWFsU3RhdGVfT2s7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChwQ29uY2VhbENvbW1vbkRhdGEtPm51bUZhZGVPdXRGcmFtZXMgPiAwKSB7CiAgICAgICAgICAgIC8qIGNoYW5nZSB0byBzdGF0ZSBGQURFLU9VVCAqLwogICAgICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jb25jZWFsU3RhdGUgID0gQ29uY2VhbFN0YXRlX0ZhZGVPdXQ7CiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgPSBmaW5kRXF1aUZhZGVGcmFtZSggcENvbmNlYWxDb21tb25EYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMrMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxIC8qIEZhZGVJbiAtPiBGYWRlT3V0ICovKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIGNoYW5nZSB0byBzdGF0ZSBNVVRFICovCiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSA9IENvbmNlYWxTdGF0ZV9NdXRlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgIGRlZmF1bHQ6CiAgICAgICAgRkRLX0FTU0VSVCgwKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgYnJlYWs7CgogIGNhc2UgQ29uY2VhbE1ldGhvZEludGVyOgogIGNhc2UgQ29uY2VhbE1ldGhvZFRvbmFsOgogICAgewogICAgICBpZiAocENvbmNlYWxtZW50SW5mby0+Y29uY2VhbFN0YXRlICE9IENvbmNlYWxTdGF0ZV9PaykgewogICAgICAgIC8qIGNvdW50IHRoZSB2YWxpZCBmcmFtZXMgZHVyaW5nIGNvbmNlYWxtZW50IHByb2Nlc3MgKi8KICAgICAgICBpZiAoIHBDb25jZWFsbWVudEluZm8tPnByZXZGcmFtZU9rWzFdIHx8CiAgICAgICAgICAgIChwQ29uY2VhbG1lbnRJbmZvLT5wcmV2RnJhbWVPa1swXSAmJiAhcENvbmNlYWxtZW50SW5mby0+cHJldkZyYW1lT2tbMV0gJiYgZnJhbWVPaykgKSB7CiAgICAgICAgICAvKiBUaGUgZnJhbWUgaXMgT0sgZXZlbiBpZiBpdCBjYW4gYmUgZXN0aW1hdGVkIGJ5IHRoZSBlbmVyZ3kgaW50ZXJwb2xhdGlvbiBhbGdvcml0aG0gKi8KICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNudFZhbGlkRnJhbWVzICs9IDE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNudFZhbGlkRnJhbWVzICA9IDA7CiAgICAgICAgfQogICAgICB9CgogICAgICAvKiAtLSBTVEFURSBNQUNISU5FIGZvciBlbmVyZ3kgaW50ZXJwb2xhdGlvbiAtLSAqLwogICAgICBzd2l0Y2ggKHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSkKICAgICAgewogICAgICBjYXNlIENvbmNlYWxTdGF0ZV9PazoKICAgICAgICBpZiAoIShwQ29uY2VhbG1lbnRJbmZvLT5wcmV2RnJhbWVPa1sxXSB8fAogICAgICAgICAgICAgKHBDb25jZWFsbWVudEluZm8tPnByZXZGcmFtZU9rWzBdICYmICFwQ29uY2VhbG1lbnRJbmZvLT5wcmV2RnJhbWVPa1sxXSAmJiBmcmFtZU9rKSkpIHsKICAgICAgICAgIGlmIChwQ29uY2VhbENvbW1vbkRhdGEtPm51bUZhZGVPdXRGcmFtZXMgPiAwKSB7CiAgICAgICAgICAgIC8qIEZhZGUgb3V0IG9ubHkgaWYgdGhlIGVuZXJneSBpbnRlcnBvbGF0aW9uIGFsZ29yaXRobSBjYW4gbm90IGJlIGFwcGxpZWQhICovCiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSAgID0gQ29uY2VhbFN0YXRlX0ZhZGVPdXQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKiBjaGFuZ2UgdG8gc3RhdGUgTVVURSAqLwogICAgICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jb25jZWFsU3RhdGUgPSBDb25jZWFsU3RhdGVfTXV0ZTsKICAgICAgICAgIH0KICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgID0gMDsKICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNudFZhbGlkRnJhbWVzID0gMDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIENvbmNlYWxTdGF0ZV9TaW5nbGU6CiAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y29uY2VhbFN0YXRlID0gQ29uY2VhbFN0YXRlX09rOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBDb25jZWFsU3RhdGVfRmFkZU91dDoKICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jbnRGYWRlRnJhbWVzICs9IDE7CgogICAgICAgIGlmIChwQ29uY2VhbG1lbnRJbmZvLT5jbnRWYWxpZEZyYW1lcyA+IHBDb25jZWFsQ29tbW9uRGF0YS0+bnVtTXV0ZVJlbGVhc2VGcmFtZXMpIHsKICAgICAgICAgIGlmIChwQ29uY2VhbENvbW1vbkRhdGEtPm51bUZhZGVJbkZyYW1lcyA+IDApIHsKICAgICAgICAgICAgLyogY2hhbmdlIHRvIHN0YXRlIEZBREUtSU4gKi8KICAgICAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y29uY2VhbFN0YXRlICA9IENvbmNlYWxTdGF0ZV9GYWRlSW47CiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgPSBmaW5kRXF1aUZhZGVGcmFtZSggcENvbmNlYWxDb21tb25EYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMtMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIEZhZGVPdXQgLT4gRmFkZUluICovKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIGNoYW5nZSB0byBzdGF0ZSBPSyAqLwogICAgICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jb25jZWFsU3RhdGUgPSBDb25jZWFsU3RhdGVfT2s7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmIChwQ29uY2VhbG1lbnRJbmZvLT5jbnRGYWRlRnJhbWVzID49IHBDb25jZWFsQ29tbW9uRGF0YS0+bnVtRmFkZU91dEZyYW1lcykgewogICAgICAgICAgICAvKiBjaGFuZ2UgdG8gc3RhdGUgTVVURSAqLwogICAgICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jb25jZWFsU3RhdGUgPSBDb25jZWFsU3RhdGVfTXV0ZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIENvbmNlYWxTdGF0ZV9NdXRlOgogICAgICAgIGlmIChwQ29uY2VhbG1lbnRJbmZvLT5jbnRWYWxpZEZyYW1lcyA+IHBDb25jZWFsQ29tbW9uRGF0YS0+bnVtTXV0ZVJlbGVhc2VGcmFtZXMpIHsKICAgICAgICAgIGlmIChwQ29uY2VhbENvbW1vbkRhdGEtPm51bUZhZGVJbkZyYW1lcyA+IDApIHsKICAgICAgICAgICAgLyogY2hhbmdlIHRvIHN0YXRlIEZBREUtSU4gKi8KICAgICAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y29uY2VhbFN0YXRlID0gQ29uY2VhbFN0YXRlX0ZhZGVJbjsKICAgICAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcyA9IHBDb25jZWFsQ29tbW9uRGF0YS0+bnVtRmFkZUluRnJhbWVzIC0gMTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIGNoYW5nZSB0byBzdGF0ZSBPSyAqLwogICAgICAgICAgICBwQ29uY2VhbG1lbnRJbmZvLT5jb25jZWFsU3RhdGUgPSBDb25jZWFsU3RhdGVfT2s7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBDb25jZWFsU3RhdGVfRmFkZUluOgogICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNudEZhZGVGcmFtZXMgLT0gMTsgIC8qIHVzZWQgdG8gYWRkcmVzcyB0aGUgZmFkZS1pbiBmYWN0b3JzICovCgogICAgICAgIGlmIChmcmFtZU9rIHx8IHBDb25jZWFsbWVudEluZm8tPnByZXZGcmFtZU9rWzFdKSB7CiAgICAgICAgICBpZiAocENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcyA8IDApIHsKICAgICAgICAgICAgLyogY2hhbmdlIHRvIHN0YXRlIE9LICovCiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSA9IENvbmNlYWxTdGF0ZV9PazsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHBDb25jZWFsQ29tbW9uRGF0YS0+bnVtRmFkZU91dEZyYW1lcyA+IDApIHsKICAgICAgICAgICAgLyogY2hhbmdlIHRvIHN0YXRlIEZBREUtT1VUICovCiAgICAgICAgICAgIHBDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSAgPSBDb25jZWFsU3RhdGVfRmFkZU91dDsKICAgICAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcyA9IGZpbmRFcXVpRmFkZUZyYW1lKCBwQ29uY2VhbENvbW1vbkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y250RmFkZUZyYW1lcysxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgLyogRmFkZUluIC0+IEZhZGVPdXQgKi8pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogY2hhbmdlIHRvIHN0YXRlIE1VVEUgKi8KICAgICAgICAgICAgcENvbmNlYWxtZW50SW5mby0+Y29uY2VhbFN0YXRlID0gQ29uY2VhbFN0YXRlX011dGU7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9IC8qIEVuZCBzd2l0Y2gocENvbmNlYWxtZW50SW5mby0+Y29uY2VhbFN0YXRlKSAqLwogICAgfQogICAgYnJlYWs7CgogIGRlZmF1bHQ6CiAgICAvKiBEb24ndCBuZWVkIGEgc3RhdGUgbWFjaGluZSBmb3Igb3RoZXIgY29uY2VhbG1lbnQgbWV0aG9kcy4gKi8KICAgIGJyZWFrOwogIH0KCn0KCgovKiEKXGJyaWVmIFJhbmRvbWl6ZXMgdGhlIHNpZ24gb2YgdGhlIHNwZWN0cmFsIGRhdGEKCiAgVGhlIGZ1bmN0aW9uIHRvZ2dsZXMgdGhlIHNpZ24gb2YgdGhlIHNwZWN0cmFsIGRhdGEgcmFuZG9tbHkuIFRoaXMgaXMKICB1c2VmdWwgdG8gZW5zdXJlIHRoZSBxdWFsaXR5IG9mIHRoZSBjb25jZWFsZWQgZnJhbWVzLgoKXHJldHVybiAgbm9uZQogKi8Kc3RhdGljCnZvaWQgQ0NvbmNlYWxtZW50X0FwcGx5UmFuZG9tU2lnbiAoaW50IHJhbmRvbVBoYXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICpzcGVjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzYW1wbGVzUGVyRnJhbWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICBpbnQgaTsKICBVU0hPUlQgcGFja2VkU2lnbj0wOwoKICAvKiByYW5kb20gdGFibGUgNTEyeDE2Yml0IGhhcyBiZWVuIHJlZHVjZWQgdG8gNTEyIHBhY2tlZCBzaWduIGJpdHMgPSAzMngxNiBiaXQgKi8KCiAgLyogcmVhZCBjdXJyZW50IHBhY2tlZCBzaWduIHdvcmQgKi8KICBwYWNrZWRTaWduID0gcmFuZG9tU2lnbltyYW5kb21QaGFzZT4+NF07CiAgcGFja2VkU2lnbiA+Pj0gKHJhbmRvbVBoYXNlJjB4Zik7CgogIGZvciAoaSA9IDA7IGkgPCBzYW1wbGVzUGVyRnJhbWUgOyBpKyspIHsKICAgIGlmICgocmFuZG9tUGhhc2UgJiAweGYpID09IDApIHsKICAgICAgcGFja2VkU2lnbiA9IHJhbmRvbVNpZ25bcmFuZG9tUGhhc2U+PjRdOwogICAgfQoKICAgIGlmIChwYWNrZWRTaWduICYgMHgxKSB7CiAgICAgIHNwZWNbaV0gPSAtc3BlY1tpXTsKICAgIH0KICAgIHBhY2tlZFNpZ24gPj49IDE7CgogICAgcmFuZG9tUGhhc2UgPSAocmFuZG9tUGhhc2UgKyAxKSAmIChBQUNfTkZfTk9fUkFORE9NX1ZBTCAtIDEpOwogIH0KfQoKCi8qIQogIFxicmllZiBHZXQgZmFkZWluZyBmYWN0b3IgZm9yIGN1cnJlbnQgY29uY2VhbG1lbnQgc3RhdGUuCgogIFRoZSBmdW5jdGlvbiByZXR1cm5zIHRoZSBmYWN0b3IgdXNlZCBmb3IgZmFkaW5nIHRoYXQgYmVsb25ncyB0byB0aGUgY3VycmVudCBpbnRlcm5hbCBzdGF0ZS4KCiAgXHJldHVybiBGYWRlIGZhY3RvcgogKi8KRklYUF9EQkwKICBDQ29uY2VhbG1lbnRfR2V0RmFkZUZhY3RvciAoCiAgICAgIENDb25jZWFsbWVudEluZm8gKmhDb25jZWFsbWVudEluZm8sCiAgICAgIGNvbnN0IGludCBmUHJldmlvdXNGYWN0b3IKICApCnsKICBGSVhQX0RCTCBmYWMgPSAoRklYUF9EQkwpMDsKCiAgQ0NvbmNlYWxQYXJhbXMgKnBDb25jZWFsQ29tbW9uRGF0YSA9IGhDb25jZWFsbWVudEluZm8tPnBDb25jZWFsUGFyYW1zOwoKICBpZiAoaENvbmNlYWxtZW50SW5mby0+cENvbmNlYWxQYXJhbXMtPm1ldGhvZCA+IENvbmNlYWxNZXRob2RNdXRlKSB7CiAgICBzd2l0Y2ggKGhDb25jZWFsbWVudEluZm8tPmNvbmNlYWxTdGF0ZSkgewogICAgICBkZWZhdWx0OgogICAgICBjYXNlIENvbmNlYWxTdGF0ZV9NdXRlOgogICAgICAgIC8qIE5vdGhpbmcgdG8gZG8gaGVyZSAqLwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIENvbmNlYWxTdGF0ZV9PazoKICAgICAgICBmYWMgPSAoRklYUF9EQkwpTUFYVkFMX0RCTDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBDb25jZWFsU3RhdGVfU2luZ2xlOgogICAgICBjYXNlIENvbmNlYWxTdGF0ZV9GYWRlT3V0OgogICAgICAgIHsKICAgICAgICAgIGludCBpZHggPSBoQ29uY2VhbG1lbnRJbmZvLT5jbnRGYWRlRnJhbWVzIC0gKChmUHJldmlvdXNGYWN0b3IgIT0gMCkgPyAxIDogMCk7CiAgICAgICAgICBmYWMgPSAoaWR4IDwgMCkgPyAoRklYUF9EQkwpTUFYVkFMX0RCTCA6IEZYX1NHTDJGWF9EQkwocENvbmNlYWxDb21tb25EYXRhLT5mYWRlT3V0RmFjdG9yW2lkeF0pOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSBDb25jZWFsU3RhdGVfRmFkZUluOgogICAgICAgIHsKICAgICAgICAgIGludCBpZHggPSBoQ29uY2VhbG1lbnRJbmZvLT5jbnRGYWRlRnJhbWVzICsgKChmUHJldmlvdXNGYWN0b3IgIT0gMCkgPyAxIDogMCk7CiAgICAgICAgICBmYWMgPSAoaWR4ID49IGhDb25jZWFsbWVudEluZm8tPnBDb25jZWFsUGFyYW1zLT5udW1GYWRlSW5GcmFtZXMpID8gKEZJWFBfREJMKTAgOiBGWF9TR0wyRlhfREJMKHBDb25jZWFsQ29tbW9uRGF0YS0+ZmFkZUluRmFjdG9yW2lkeF0pOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KICB9CgogIHJldHVybiAoZmFjKTsKfQoKCi8qIQogIFxicmllZiBHZXQgZmFkZWluZyBmYWN0b3IgZm9yIGN1cnJlbnQgY29uY2VhbG1lbnQgc3RhdGUuCgogIFRoZSBmdW5jdGlvbiByZXR1cm5zIHRoZSBzdGF0ZSAob2sgb3Igbm90KSBvZiB0aGUgcHJldmlvdXMgZnJhbWUuCiAgSWYgY2FsbGVkIGJlZm9yZSB0aGUgZnVuY3Rpb24gQ0NvbmNlYWxtZW50X0FwcGx5KCkgc2V0IHRoZSBmQmVmb3JlQXBwbHkKICBmbGFnIHRvIGdldCB0aGUgY29ycmVjdCB2YWx1ZS4KCiAgXHJldHVybiBGcmFtZSBPSyBmbGFnIG9mIHByZXZpb3VzIGZyYW1lLgogKi8KaW50CiAgQ0NvbmNlYWxtZW50X0dldExhc3RGcmFtZU9rICgKICAgICAgQ0NvbmNlYWxtZW50SW5mbyAqaENvbmNlYWxtZW50SW5mbywKICAgICAgY29uc3QgaW50IGZCZWZvcmVBcHBseQogICkKewogIGludCBwcmV2RnJhbWVPayA9IDE7CgogIGlmIChoQ29uY2VhbG1lbnRJbmZvICE9IE5VTEwpIHsKICAgIHByZXZGcmFtZU9rID0gaENvbmNlYWxtZW50SW5mby0+cHJldkZyYW1lT2tbZkJlZm9yZUFwcGx5ICYgMHgxXTsKICB9CgogIHJldHVybiBwcmV2RnJhbWVPazsKfQoKLyohCiAgXGJyaWVmIEdldCB0aGUgbnVtYmVyIG9mIGRlbGF5IGZyYW1lcyBpbnRyb2R1Y2VkIGJ5IGNvbmNlYWxtZW50IHRlY2huaXF1ZS4gCgogIFxyZXR1cm4gTnVtYmVyIG9mIGRlbGF5IGZyYW1lcy4KICovClVJTlQKICBDQ29uY2VhbG1lbnRfR2V0RGVsYXkgKAogICAgICBDQ29uY2VhbFBhcmFtcyAqcENvbmNlYWxDb21tb25EYXRhCiAgKQp7CiAgVUlOVCBmcmFtZURlbGF5ID0gMDsKCiAgaWYgKHBDb25jZWFsQ29tbW9uRGF0YSAhPSBOVUxMKSB7CiAgICBzd2l0Y2ggKHBDb25jZWFsQ29tbW9uRGF0YS0+bWV0aG9kKSB7CiAgICBjYXNlIENvbmNlYWxNZXRob2RUb25hbDoKICAgIGNhc2UgQ29uY2VhbE1ldGhvZEludGVyOgogICAgICBmcmFtZURlbGF5ID0gMTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBicmVhazsKICAgIH0KICB9CgogIHJldHVybiBmcmFtZURlbGF5Owp9Cgo=