Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEyIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBKb3NlZiBIb2VwZmwKICAgRGVzY3JpcHRpb246CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKLyohCiAgXHBhZ2UgZGVmYXVsdCBHZW5lcmFsIE92ZXJ2aWV3IG9mIHRoZSBBQUMgRGVjb2RlciBJbXBsZW1lbnRhdGlvbgoKICBUaGUgbWFpbiBlbnRyeSBwb2ludCB0byBkZWNvZGUgYSBBQUMgZnJhbWUgaXMgQ0FhY0RlY29kZXJfRGVjb2RlRnJhbWUoKS4gSXQgaGFuZGxlcyB0aGUgZGlmZmVyZW50CiAgdHJhbnNwb3J0IG11bHRpcGxleGVzIGFuZCBiaXRzdHJlYW0gZm9ybWF0cyBzdXBwb3J0ZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbi4gSXQgZXh0cmFjdHMgdGhlCiAgQUFDX3Jhd19kYXRhX2Jsb2NrcyBmcm9tIHRoZXNlIGJpdHN0cmVhbXMgdG8gZnVydGhlciBwcm9jZXNzIHRoZW4gaW4gdGhlIGFjdHVhbCBkZWNvZGluZyBzdGFnZXMuCgogIE5vdGU6IENsaWNrIG9uIGEgZnVuY3Rpb24gb2YgZmlsZSBpbiB0aGUgYWJvdmUgaW1hZ2UgdG8gc2VlIGRldGFpbHMgYWJvdXQgdGhlIGZ1bmN0aW9uLiBBbHNvIG5vdGUsIHRoYXQKICB0aGlzIGlzIGp1c3QgYW4gb3ZlcnZpZXcgb2YgdGhlIG1vc3QgaW1wb3J0YW50IGZ1bmN0aW9ucyBhbmQgbm90IGEgY29tcGxldGUgY2FsbCBncmFwaC4KCiAgPGgyPjEgQml0c3RyZWFtIGRlZm9ybWF0dGVyPC9oMj4KICBUaGUgYmFzaWMgYml0IHN0cmVhbSBwYXJzZXIgZnVuY3Rpb24gQ0NoYW5uZWxFbGVtZW50X1JlYWQoKSBpcyBjYWxsZWQuIEl0IHVzZXMgb3RoZXIgc3ViY2FsbHMgaW4gb3JkZXIKICB0byBwYXJzZSBhbmQgdW5wYWNrIHRoZSBiaXRzdHJlYW1zLiBOb3RlLCB0aGF0IHRoaXMgaW5jbHVkZXMgaHVmZm1hbm4gZGVjb2Rpbmcgb2YgdGhlIGNvZGVkIHNwZWN0cmFsIGRhdGEuCiAgVGhpcyBvcGVyYXRpb24gY2FuIGJlIGNvbXB1dGF0aW9uYWwgc2lnbmlmaWNhbnQgc3BlY2lmaWNhbGx5IGF0IGhpZ2hlciBiaXRyYXRlcy4gT3B0aW1pemF0aW9uIGlzIGxpa2VseSBpbgogIENCbG9ja19SZWFkU3BlY3RyYWxEYXRhKCkuCgogIFRoZSBiaXRzdHJlYW0gZGVmb3JtYXR0ZXIgYWxzbyBpbmNsdWRlcyBtYW55IGJpdGZpZWxkIG9wZXJhdGlvbnMuIFByb2ZpbGluZyBvbiB0aGUgdGFyZ2V0IHdpbGwgZGV0ZXJtaW5lCiAgcmVxdWlyZWQgb3B0aW1pemF0aW9ucy4KCiAgPGgyPjIgQWN0dWFsIGRlY29kaW5nIHRvIHJldGFpbiB0aGUgdGltZSBkb21haW4gb3V0cHV0PC9oMj4KICBUaGUgYmFzaWMgYml0c3RyZWFtIGRlZm9ybWF0dGVyIGZ1bmN0aW9uIENDaGFubmVsRWxlbWVudF9EZWNvZGUoKSBmb3IgQ1BFIGVsZW1lbnRzIGFuZCBTQ0UgZWxlbWVudHMgYXJlIGNhbGxlZC4KICBFeGNlcHQgZm9yIHRoZSBzdGVyZW8gcHJvY2Vzc2luZyAoMi4xKSB3aGljaCBpcyBvbmx5IHVzZWQgZm9yIENQRSBlbGVtZW50cywgdGhlIGZ1bmN0aW9uIGNhbGxzIGZvciBDUEUgb3IgU0NFCiAgYXJlIHNpbWlsYXIsIGV4Y2VwdCB0aGF0IENQRSBhbHdheXMgcHJvY2Vzc2VzIHRvIGluZGVwZW5kZW50IGNoYW5uZWxzIHdoaWxlIFNDRSBvbmx5IHByb2Nlc3NlcyBvbmUgY2hhbm5lbC4KCiAgT2Z0ZW4gdGhlcmUgaXMgdGhlIGRpc3RpbmN0aW9uIGJldHdlZW4gbG9uZyBibG9ja3MgYW5kIHNob3J0IGJsb2Nrcy4gSG93ZXZlciwgY29tcHV0YXRpb25hbCBleHBlbnNpdmUgZnVuY3Rpb25zCiAgdGhhdCB1c3VzYWxseSByZXF1aXJlIG9wdGltaXphdGlvbiBhcmUgYmVpbmcgc2hhcmVkIGJ5IHRoZXNlIHR3byBncm91cHMsCgogIDxoMz4yLjEgU3RlcmVvIHByb2Nlc3NpbmcgZm9yIENQRSBlbGVtZW50czwvaDM+CiAgQ0NoYW5uZWxQYWlyRWxlbWVudF9EZWNvZGUoKSBmaXJzdCBjYWxsZXMgdGhlIGpvaW50IHN0ZXJlbyAgdG9vbHMgaW4gc3RlcmVvLmNwcCB3aGVuIHJlcXVpcmVkLgoKICA8aDM+Mi4yIFNjYWxpbmcgb2Ygc3BlY3RyYWwgZGF0YTwvaDM+CiAgQ0Jsb2NrX1NjYWxlU3BlY3RyYWxEYXRhKCkuCgogIDxoMz4yLjMgQXBwbHkgYWRkaXRpb25hbCBjb2RpbmcgdG9vbHM8L2gzPgogIEFwcGx5VG9vbHMoKSBjYWxsZXMgdGhlIFBOUyB0b29scyBpbiBjYXNlIG9mIE1QRUctNCBiaXRzdHJlYW1zLCBhbmQgVE5TIGZpbHRlcmluZyBDVG5zX0FwcGx5KCkgZm9yIE1QRUctMiBhbmQgTVBFRy00IGJpdHN0cmVhbXMuCiAgVGhlIGZ1bmN0aW9uIFRuc0ZpbHRlcklJUigpIHdoaWNoIGlzIGNhbGxlZCBieSBDVG5zX0FwcGx5KCkgKDIuMy4xKSBtaWdodCByZXF1aXJlIHNvbWUgb3B0aW1pemF0aW9uLgoKICA8aDI+MyBGcmVxdWVuY3ktVG8tVGltZSBjb252ZXJzaW9uPC9oMz4KICBUaGUgZmlsdGVyYmFuayBpcyBjYWxsZWQgdXNpbmcgQ0Jsb2NrX0ZyZXF1ZW5jeVRvVGltZSgpIHVzaW5nIHRoZSBNRENUIG1vZHVsZSBmcm9tIHRoZSBGREsgVG9vbHMKCiovCgoKCiNpbmNsdWRlICJhYWNkZWNvZGVyLmgiCgojaW5jbHVkZSAiYWFjX3JvbS5oIgojaW5jbHVkZSAiYWFjX3JhbS5oIgojaW5jbHVkZSAiY2hhbm5lbC5oIgojaW5jbHVkZSAiRkRLX2F1ZGlvLmgiCgojaW5jbHVkZSAiRkRLX3Rvb2xzX3JvbS5oIgoKICAjaW5jbHVkZSAiYWFjZGVjX3Bucy5oIgoKICAjaW5jbHVkZSAic2JyZGVjb2Rlci5oIgoKCgoKICAjaW5jbHVkZSAiYWFjZGVjX2hjci5oIgogICNpbmNsdWRlICJydmxjLmgiCgoKI2luY2x1ZGUgInRwZGVjX2xpYi5oIgoKI2luY2x1ZGUgImNvbmNlYWwuaCIKCgoKI2RlZmluZSBDQU5fRE9fUFMoYW90KSBcCiAgKChhb3QpID09IEFPVF9BQUNfTEMgXAp8fCAoYW90KSA9PSBBT1RfU0JSIFwKfHwgKGFvdCkgPT0gQU9UX1BTIFwKfHwgKGFvdCkgPT0gQU9UX0VSX0JTQUMgXAp8fCAoYW90KSA9PSBBT1RfRFJNX0FBQykKCiNkZWZpbmUgSVNfVVNBQyhhb3QpIFwKICAoKGFvdCkgPT0gQU9UX1VTQUMgXAp8fCAoYW90KSA9PSBBT1RfUlNWRDUwKQoKI2RlZmluZSBJU19MT1dERUxBWShhb3QpIFwKICAoKGFvdCkgPT0gQU9UX0VSX0FBQ19MRCBcCnx8IChhb3QpID09IEFPVF9FUl9BQUNfRUxEKQoKdm9pZCBDQWFjRGVjb2Rlcl9TeW5jUW1mTW9kZShIQU5ETEVfQUFDREVDT0RFUiBzZWxmKQp7CgogIC8qIEFzc2lnbiB1c2VyIHJlcXVlc3RlZCBtb2RlICovCiAgc2VsZi0+cW1mTW9kZUN1cnIgPSBzZWxmLT5xbWZNb2RlVXNlcjsKCiAgaWYgKCBzZWxmLT5xbWZNb2RlQ3VyciA9PSBOT1RfREVGSU5FRCApCiAgewogICAgaWYgKCAoSVNfTE9XREVMQVkoc2VsZi0+c3RyZWFtSW5mby5hb3QpICYmIChzZWxmLT5mbGFncyAmIEFDX01QU19QUkVTRU5UKSkKICAgICAgfHwgKCAoc2VsZi0+YXNjQ2hhbm5lbHMgPT0gMSkKICAgICAgICAmJiAoIChDQU5fRE9fUFMoc2VsZi0+c3RyZWFtSW5mby5hb3QpICYmICEoc2VsZi0+ZmxhZ3MgJiBBQ19NUFNfUFJFU0VOVCkpCiAgICAgICAgICB8fCAoICBJU19VU0FDKHNlbGYtPnN0cmVhbUluZm8uYW90KSAmJiAgKHNlbGYtPmZsYWdzICYgQUNfTVBTX1BSRVNFTlQpKSApICkgKQogICAgewogICAgICBzZWxmLT5xbWZNb2RlQ3VyciA9IE1PREVfSFE7CiAgICB9IGVsc2UgewogICAgICBzZWxmLT5xbWZNb2RlQ3VyciA9IE1PREVfTFA7CiAgICB9CiAgfQoKCiAgLyogU2V0IFNCUiB0byBjdXJyZW50IFFNRiBtb2RlLiBFcnJvciBkb2VzIG5vdCBtYXR0ZXIuICovCiAgc2JyRGVjb2Rlcl9TZXRQYXJhbShzZWxmLT5oU2JyRGVjb2RlciwgU0JSX1FNRl9NT0RFLCAoc2VsZi0+cW1mTW9kZUN1cnIgPT0gTU9ERV9MUCkpOwogIHNlbGYtPnBzUG9zc2libGUgPSAoKENBTl9ET19QUyhzZWxmLT5zdHJlYW1JbmZvLmFvdCkgJiYgc2VsZi0+YWFjQ2hhbm5lbHMgPT0gMSAmJiAhIChzZWxmLT5mbGFncyAmIEFDX01QU19QUkVTRU5UKSkpICYmIHNlbGYtPnFtZk1vZGVDdXJyID09IE1PREVfSFEgOwogIEZES19BU1NFUlQoICEgKCAoc2VsZi0+ZmxhZ3MgJiBBQ19NUFNfUFJFU0VOVCkgJiYgc2VsZi0+cHNQb3NzaWJsZSApICk7Cn0KCnZvaWQgQ0FhY0RlY29kZXJfU2lnbmFsSW50ZXJydXB0aW9uKEhBTkRMRV9BQUNERUNPREVSIHNlbGYpCnsKfQoKLyohCiAgXGJyaWVmIFJlc2V0IGFuY2lsbGFyeSBkYXRhIHN0cnVjdC4gQ2FsbCBiZWZvcmUgcGFyc2luZyBhIG5ldyBmcmFtZS4KCiAgXGFuY0RhdGEgUG9pbnRlciB0byBhbmNpbGxhcnkgZGF0YSBzdHJ1Y3R1cmUKCiAgXHJldHVybiAgRXJyb3IgY29kZQoqLwpzdGF0aWMgQUFDX0RFQ09ERVJfRVJST1IgQ0FhY0RlY29kZXJfQW5jRGF0YVJlc2V0KENBbmNEYXRhICphbmNEYXRhKQp7CiAgaW50IGk7CiAgZm9yIChpPTA7IGk8ODsgaSsrKQogIHsKICAgIGFuY0RhdGEtPm9mZnNldFtpXSA9IDA7CiAgfQogIGFuY0RhdGEtPm5yRWxlbWVudHMgPSAwOwoKICByZXR1cm4gQUFDX0RFQ19PSzsKfQoKLyohCiAgXGJyaWVmIEluaXRpYWxpemUgYW5jaWxsYXJ5IGJ1ZmZlcgoKICBcYW5jRGF0YSBQb2ludGVyIHRvIGFuY2lsbGFyeSBkYXRhIHN0cnVjdHVyZQogIFxidWZmZXIgUG9pbnRlciB0byAoZXh0ZXJuYWwpIGFuYyBkYXRhIGJ1ZmZlcgogIFxzaXplIFNpemUgb2YgdGhlIGJ1ZmZlciBwb2ludGVkIG9uIGJ5IGJ1ZmZlciBpbiBieXRlcwoKICBccmV0dXJuICBFcnJvciBjb2RlCiovCkFBQ19ERUNPREVSX0VSUk9SIENBYWNEZWNvZGVyX0FuY0RhdGFJbml0KENBbmNEYXRhICphbmNEYXRhLCB1bnNpZ25lZCBjaGFyICpidWZmZXIsIGludCBzaXplKQp7CiAgaWYgKHNpemUgPj0gMCkgewogICAgYW5jRGF0YS0+YnVmZmVyID0gYnVmZmVyOwogICAgYW5jRGF0YS0+YnVmZmVyU2l6ZSA9IHNpemU7CgogICAgQ0FhY0RlY29kZXJfQW5jRGF0YVJlc2V0KGFuY0RhdGEpOwoKICAgIHJldHVybiBBQUNfREVDX09LOwogIH0KCiAgcmV0dXJuIEFBQ19ERUNfQU5DX0RBVEFfRVJST1I7Cn0KCi8qIQogIFxicmllZiBHZXQgb25lIGFuY2lsbGFyeSBkYXRhIGVsZW1lbnQKCiAgXGFuY0RhdGEgUG9pbnRlciB0byBhbmNpbGxhcnkgZGF0YSBzdHJ1Y3R1cmUKICBcaW5kZXggSW5kZXggb2YgdGhlIGFuYyBkYXRhIGVsZW1lbnQgdG8gZ2V0CiAgXHB0ciBQb2ludGVyIHRvIGEgYnVmZmVyIHJlY2VpdmluZyBhIHBvaW50ZXIgdG8gdGhlIHJlcXVlc3RlZCBhbmMgZGF0YSBlbGVtZW50CiAgXHNpemUgUG9pbnRlciB0byBhIGJ1ZmZlciByZWNlaXZpbmcgdGhlIGxlbmd0aCBvZiB0aGUgcmVxdWVzdGVkIGFuYyBkYXRhIGVsZW1lbnQgaW4gYnl0ZXMKCiAgXHJldHVybiAgRXJyb3IgY29kZQoqLwpBQUNfREVDT0RFUl9FUlJPUiBDQWFjRGVjb2Rlcl9BbmNEYXRhR2V0KENBbmNEYXRhICphbmNEYXRhLCBpbnQgaW5kZXgsIHVuc2lnbmVkIGNoYXIgKipwdHIsIGludCAqc2l6ZSkKewogIEFBQ19ERUNPREVSX0VSUk9SIGVycm9yID0gQUFDX0RFQ19PSzsKCiAgKnB0ciAgPSBOVUxMOwogICpzaXplID0gMDsKCiAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCA4ICYmIGluZGV4IDwgYW5jRGF0YS0+bnJFbGVtZW50cykKICB7CiAgICAqcHRyICA9ICZhbmNEYXRhLT5idWZmZXJbYW5jRGF0YS0+b2Zmc2V0W2luZGV4XV07CiAgICAqc2l6ZSA9IGFuY0RhdGEtPm9mZnNldFtpbmRleCsxXSAtIGFuY0RhdGEtPm9mZnNldFtpbmRleF07CiAgfQoKICByZXR1cm4gZXJyb3I7Cn0KCgovKiEKICBcYnJpZWYgUGFyc2UgYW5jaWxsYXJ5IGRhdGEKCiAgXGFuY0RhdGEgUG9pbnRlciB0byBhbmNpbGxhcnkgZGF0YSBzdHJ1Y3R1cmUKICBcaEJzIEhhbmRsZSB0byBGREsgYml0c3RyZWFtCiAgXGFuY0J5dGVzIExlbmd0aCBvZiBhbmNpbGxhcnkgZGF0YSB0byByZWFkIGZyb20gdGhlIGJpdHN0cmVhbQoKICBccmV0dXJuICBFcnJvciBjb2RlCiovCnN0YXRpYwpBQUNfREVDT0RFUl9FUlJPUiBDQWFjRGVjb2Rlcl9BbmNEYXRhUGFyc2UgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQW5jRGF0YSAqYW5jRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgYW5jQnl0ZXMgKQp7CiAgQUFDX0RFQ09ERVJfRVJST1IgZXJyb3IgPSBBQUNfREVDX09LOwogIGludCByZWFkQnl0ZXMgPSAwOwoKICBpZiAoYW5jRGF0YS0+YnVmZmVyICE9IE5VTEwpCiAgewogICAgaWYgKGFuY0J5dGVzID4gMCkgewogICAgICAvKiB3cml0ZSBhbmNpbGxhcnkgZGF0YSB0byBleHRlcm5hbCBidWZmZXIgKi8KICAgICAgaW50IG9mZnNldCA9IGFuY0RhdGEtPm9mZnNldFthbmNEYXRhLT5uckVsZW1lbnRzXTsKCiAgICAgIGlmICgob2Zmc2V0ICsgYW5jQnl0ZXMpID4gYW5jRGF0YS0+YnVmZmVyU2l6ZSkKICAgICAgewogICAgICAgIGVycm9yID0gQUFDX0RFQ19UT09fU01BTExfQU5DX0JVRkZFUjsKICAgICAgfQogICAgICBlbHNlIGlmIChhbmNEYXRhLT5uckVsZW1lbnRzID49IDgtMSkKICAgICAgewogICAgICAgIGVycm9yID0gQUFDX0RFQ19UT09fTUFOWV9BTkNfRUxFTUVOVFM7CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgaW50IGk7CgogICAgICAgIGZvciAoaSA9IDA7IGkgPCBhbmNCeXRlczsgaSsrKSB7CiAgICAgICAgICBhbmNEYXRhLT5idWZmZXJbaStvZmZzZXRdID0gRkRLcmVhZEJpdHMoaEJzLCA4KTsKICAgICAgICAgIHJlYWRCeXRlcysrOwogICAgICAgIH0KCiAgICAgICAgYW5jRGF0YS0+bnJFbGVtZW50cysrOwogICAgICAgIGFuY0RhdGEtPm9mZnNldFthbmNEYXRhLT5uckVsZW1lbnRzXSA9IGFuY0J5dGVzICsgYW5jRGF0YS0+b2Zmc2V0W2FuY0RhdGEtPm5yRWxlbWVudHMtMV07CiAgICAgIH0KICAgIH0KICB9CgogIHJlYWRCeXRlcyA9IGFuY0J5dGVzIC0gcmVhZEJ5dGVzOwoKICBpZiAocmVhZEJ5dGVzID4gMCkgewogICAgLyogc2tpcCBkYXRhICovCiAgICBGREtwdXNoRm9yKGhCcywgcmVhZEJ5dGVzPDwzKTsKICB9CgogIHJldHVybiBlcnJvcjsKfQoKLyohCiAgXGJyaWVmIFJlYWQgU3RyZWFtIERhdGEgRWxlbWVudAoKICBcYnMgQml0c3RyZWFtIEhhbmRsZQoKICBccmV0dXJuICBFcnJvciBjb2RlCiovCnN0YXRpYyBBQUNfREVDT0RFUl9FUlJPUiBDRGF0YVN0cmVhbUVsZW1lbnRfUmVhZCAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0FuY0RhdGEgKmFuY0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0FBQ19EUkMgaERyY0luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1RSQU5TUE9SVERFQyBwVHAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgICAgKmVsZW1lbnRJbnN0YW5jZVRhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UICAgICAgYWxpZ25tZW50QW5jaG9yICkKewogIEFBQ19ERUNPREVSX0VSUk9SIGVycm9yID0gQUFDX0RFQ19PSzsKICBVSU5UIGRhdGFTdGFydDsKICBpbnQgZGF0YUJ5dGVBbGlnbkZsYWcsIGNvdW50OwoKICBpbnQgY3JjUmVnID0gdHJhbnNwb3J0RGVjX0NyY1N0YXJ0UmVnKHBUcCwgMCk7CgogIC8qIEVsZW1lbnQgSW5zdGFuY2UgVGFnICovCiAgKmVsZW1lbnRJbnN0YW5jZVRhZyA9IEZES3JlYWRCaXRzKGJzLDQpOwogIC8qIERhdGEgQnl0ZSBBbGlnbiBGbGFnICovCiAgZGF0YUJ5dGVBbGlnbkZsYWcgPSBGREtyZWFkQml0cyhicywxKTsKCiAgY291bnQgPSBGREtyZWFkQml0cyhicyw4KTsKCiAgaWYgKGNvdW50ID09IDI1NSkgewogICAgY291bnQgKz0gRkRLcmVhZEJpdHMoYnMsOCk7IC8qIEVzY0NvdW50ICovCiAgfQoKICBpZiAoZGF0YUJ5dGVBbGlnbkZsYWcpIHsKICAgIEZES2J5dGVBbGlnbihicywgYWxpZ25tZW50QW5jaG9yKTsKICB9CgogIGRhdGFTdGFydCA9IEZES2dldFZhbGlkQml0cyhicyk7CgogIGVycm9yID0gQ0FhY0RlY29kZXJfQW5jRGF0YVBhcnNlKGFuY0RhdGEsIGJzLCBjb3VudCk7CiAgdHJhbnNwb3J0RGVjX0NyY0VuZFJlZyhwVHAsIGNyY1JlZyk7CgogIHsKICAgIElOVCByZWFkQml0cywgZGF0YUJpdHMgPSBjb3VudDw8MzsKICAgIAogICAgLyogTW92ZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBkYXRhIGp1bmsgKi8KICAgIEZES3B1c2hCYWNrKGJzLCBkYXRhU3RhcnQtRkRLZ2V0VmFsaWRCaXRzKGJzKSk7CgogICAgLyogUmVhZCBBbmMgZGF0YSBpZiBhdmFpbGFibGUgKi8KICAgIHJlYWRCaXRzID0gYWFjRGVjb2Rlcl9kcmNNYXJrUGF5bG9hZCggaERyY0luZm8sIGJzLCBEVkJfRFJDX0FOQ19EQVRBICk7CgogICAgaWYgKHJlYWRCaXRzICE9IGRhdGFCaXRzKSB7CiAgICAgIC8qIE1vdmUgdG8gdGhlIGVuZCBhZ2Fpbi4gKi8KICAgICAgRkRLcHVzaEJpRGlyZWN0aW9uYWwoYnMsIEZES2dldFZhbGlkQml0cyhicyktZGF0YVN0YXJ0K2RhdGFCaXRzKTsKICAgIH0KICB9CgogIHJldHVybiBlcnJvcjsKfQoKI2lmZGVmIFRQX1BDRV9FTkFCTEUKLyohCiAgXGJyaWVmIFJlYWQgUHJvZ3JhbSBDb25maWcgRWxlbWVudAoKICBcYnMgQml0c3RyZWFtIEhhbmRsZQogIFxjb3VudCBQb2ludGVyIHRvIHByb2dyYW0gY29uZmlnIGVsZW1lbnQuCgogIFxyZXR1cm4gIEVycm9yIGNvZGUKKi8Kc3RhdGljIEFBQ19ERUNPREVSX0VSUk9SIENQcm9ncmFtQ29uZmlnRWxlbWVudF9SZWFkICgKICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLAogICAgSEFORExFX1RSQU5TUE9SVERFQyAgcFRwLAogICAgQ1Byb2dyYW1Db25maWcgICAgICAqcGNlLAogICAgVUlOVCAgICAgICAgICAgICAgICAgY2hhbm5lbENvbmZpZywKICAgIFVJTlQgICAgICAgICAgICAgICAgIGFsaWduQW5jaG9yICkKewogIEFBQ19ERUNPREVSX0VSUk9SIGVycm9yID0gQUFDX0RFQ19PSzsKICBpbnQgY3JjUmVnOwoKICAvKiByZWFkIFBDRSB0byB0ZW1wb3JhbCBidWZmZXIgZmlyc3QgKi8KICBDX0FMTE9DX1NDUkFUQ0hfU1RBUlQodG1wUGNlLCBDUHJvZ3JhbUNvbmZpZywgMSk7CiAgCiAgQ1Byb2dyYW1Db25maWdfSW5pdCh0bXBQY2UpOwogIENQcm9ncmFtQ29uZmlnX1Jlc2V0KHRtcFBjZSk7CgogIGNyY1JlZyA9IHRyYW5zcG9ydERlY19DcmNTdGFydFJlZyhwVHAsIDApOwoKICBDUHJvZ3JhbUNvbmZpZ19SZWFkKHRtcFBjZSwgYnMsIGFsaWduQW5jaG9yKTsKCiAgdHJhbnNwb3J0RGVjX0NyY0VuZFJlZyhwVHAsIGNyY1JlZyk7CgogIGlmICggIENQcm9ncmFtQ29uZmlnX0lzVmFsaWQodG1wUGNlKQogICAgJiYgKCAoY2hhbm5lbENvbmZpZyA9PSA2ICYmICh0bXBQY2UtPk51bUNoYW5uZWxzID09IDYpKQogICAgICB8fCAoY2hhbm5lbENvbmZpZyA9PSA1ICYmICh0bXBQY2UtPk51bUNoYW5uZWxzID09IDUpKQogICAgICB8fCAoY2hhbm5lbENvbmZpZyA9PSAwICYmICh0bXBQY2UtPk51bUNoYW5uZWxzID09IHBjZS0+TnVtQ2hhbm5lbHMpKSApCiAgICAmJiAodG1wUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50cyA9PSAyKQogICAgJiYgKHRtcFBjZS0+TnVtU2lkZUNoYW5uZWxFbGVtZW50cyAgPT0gMCkKICAgICYmICh0bXBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHMgID09IDEpCiAgICAmJiAodG1wUGNlLT5Qcm9maWxlID09IDEpICkKICB7IC8qIENvcHkgdGhlIGNvbXBsZXRlIFBDRSBpbmNsdWRpbmcgbWV0YWRhdGEuICovCiAgICBGREttZW1jcHkocGNlLCB0bXBQY2UsIHNpemVvZihDUHJvZ3JhbUNvbmZpZykpOwogIH0KCiAgQ19BTExPQ19TQ1JBVENIX0VORCh0bXBQY2UsIENQcm9ncmFtQ29uZmlnLCAxKTsKCiAgcmV0dXJuIGVycm9yOwp9CiNlbmRpZgoKLyohCiAgXGJyaWVmIFBhcnNlIEV4dGVuc2lvbiBQYXlsb2FkCgogIFxzZWxmIEhhbmRsZSBvZiBBQUMgZGVjb2RlcgogIFxjb3VudCBQb2ludGVyIHRvIGJpdCBjb3VudGVyLgogIFxwcmV2aW91c19lbGVtZW50IElEIG9mIHByZXZpb3VzIGVsZW1lbnQgKHJlcXVpcmVkIGJ5IHNvbWUgZXh0ZW5zaW9uIHBheWxvYWRzKQoKICBccmV0dXJuICBFcnJvciBjb2RlCiovCnN0YXRpYwpBQUNfREVDT0RFUl9FUlJPUiBDQWFjRGVjb2Rlcl9FeHRQYXlsb2FkUGFyc2UgKEhBTkRMRV9BQUNERUNPREVSIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqY291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTVA0X0VMRU1FTlRfSUQgcHJldmlvdXNfZWxlbWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZWxJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZklzRmlsbEVsZW1lbnQpCnsKICBBQUNfREVDT0RFUl9FUlJPUiBlcnJvciA9IEFBQ19ERUNfT0s7CiAgRVhUX1BBWUxPQURfVFlQRSBleHRlbnNpb25fdHlwZTsKICBpbnQgYnl0ZXMgPSAoKmNvdW50KSA+PiAzOwogIGludCBjcmNGbGFnID0gMDsKCiAgaWYgKCpjb3VudCA8IDQpIHsKICAgIHJldHVybiBBQUNfREVDX1BBUlNFX0VSUk9SOwogIH0gZWxzZSBpZiAoKElOVClGREtnZXRWYWxpZEJpdHMoaEJzKSA8ICpjb3VudCkgewogICAgcmV0dXJuIEFBQ19ERUNfREVDT0RFX0ZSQU1FX0VSUk9SOwogIH0KCiAgZXh0ZW5zaW9uX3R5cGUgPSAoRVhUX1BBWUxPQURfVFlQRSkgRkRLcmVhZEJpdHMoaEJzLCA0KTsgICAgLyogYnNfZXh0ZW5zaW9uX3R5cGUgKi8KICAqY291bnQgLT0gNDsKCiAgc3dpdGNoIChleHRlbnNpb25fdHlwZSkKICB7CiAgY2FzZSBFWFRfRFlOQU1JQ19SQU5HRToKICAgIHsKICAgICAgSU5UIHJlYWRCaXRzID0gYWFjRGVjb2Rlcl9kcmNNYXJrUGF5bG9hZCggc2VsZi0+aERyY0luZm8sIGhCcywgTVBFR19EUkNfRVhUX0RBVEEgKTsKCiAgICAgIGlmIChyZWFkQml0cyA+ICpjb3VudCkKICAgICAgeyAvKiBSZWFkIHRvbyBtdWNoLiBTb21ldGhpbmcgd2VudCB3cm9uZyEgKi8KICAgICAgICBlcnJvciA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgIH0KICAgICAgKmNvdW50IC09IHJlYWRCaXRzOwogICAgfQogICAgYnJlYWs7CgoKICBjYXNlIEVYVF9TQlJfREFUQV9DUkM6CiAgICBjcmNGbGFnID0gMTsKICBjYXNlIEVYVF9TQlJfREFUQToKICAgIGlmIChJU19DSEFOTkVMX0VMRU1FTlQocHJldmlvdXNfZWxlbWVudCkpIHsKICAgICAgU0JSX0VSUk9SIHNickVycm9yOwoKICAgICAgQ0FhY0RlY29kZXJfU3luY1FtZk1vZGUoc2VsZik7CgogICAgICBzYnJFcnJvciA9IHNickRlY29kZXJfSW5pdEVsZW1lbnQoCiAgICAgICAgICAgICAgc2VsZi0+aFNickRlY29kZXIsCiAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVSYXRlLAogICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uZXh0U2FtcGxpbmdSYXRlLAogICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYW90LAogICAgICAgICAgICAgIHByZXZpb3VzX2VsZW1lbnQsCiAgICAgICAgICAgICAgZWxJbmRleAogICAgICAgICAgICAgICk7CgogICAgICBpZiAoc2JyRXJyb3IgPT0gU0JSREVDX09LKSB7CiAgICAgICAgc2JyRXJyb3IgPSBzYnJEZWNvZGVyX1BhcnNlICgKICAgICAgICAgICAgICAgIHNlbGYtPmhTYnJEZWNvZGVyLAogICAgICAgICAgICAgICAgaEJzLAogICAgICAgICAgICAgICAgY291bnQsCiAgICAgICAgICAgICAgICpjb3VudCwKICAgICAgICAgICAgICAgIGNyY0ZsYWcsCiAgICAgICAgICAgICAgICBwcmV2aW91c19lbGVtZW50LAogICAgICAgICAgICAgICAgZWxJbmRleCwKICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzICYgQUNfSU5ERVAgKTsKICAgICAgICAvKiBFbmFibGUgU0JSIGZvciBpbXBsaWNpdCBTQlIgc2lnbmFsbGluZy4gKi8KICAgICAgICBpZiAoc2JyRXJyb3IgPT0gU0JSREVDX09LKSB7CiAgICAgICAgICBzZWxmLT5zYnJFbmFibGVkID0gMTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLyogRG8gbm90IHRyeSB0byBhcHBseSBTQlIgYmVjYXVzZSBpbml0aWFsaXppbmcgdGhlIGVsZW1lbnQgZmFpbGVkLiAqLwogICAgICAgIHNlbGYtPnNickVuYWJsZWQgPSAwOwogICAgICB9CiAgICAgIC8qIENpdGF0aW9uIGZyb20gSVNPL0lFQyAxNDQ5Ni0zIGNoYXB0ZXIgNC41LjIuMS41LjIKICAgICAgRmlsbCBlbGVtZW50cyBjb250YWluaW5nIGFuIGV4dGVuc2lvbl9wYXlsb2FkKCkgd2l0aCBhbiBleHRlbnNpb25fdHlwZSBvZiBFWFRfU0JSX0RBVEEKICAgICAgb3IgRVhUX1NCUl9EQVRBX0NSQyBzaGFsbCBub3QgY29udGFpbiBhbnkgb3RoZXIgZXh0ZW5zaW9uX3BheWxvYWQgb2YgYW55IG90aGVyIGV4dGVuc2lvbl90eXBlLgogICAgICAqLwogICAgICBpZiAoZklzRmlsbEVsZW1lbnQpIHsKICAgICAgICBGREtwdXNoQmlEaXJlY3Rpb25hbChoQnMsICpjb3VudCk7CiAgICAgICAgKmNvdW50ID0gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBJZiB0aGlzIGlzIG5vdCBhIGZpbGwgZWxlbWVudCB3aXRoIGEga25vd24gbGVuZ3RoLCB3ZSBhcmUgc2NyZXdlZCBhbiBubyBmdXJ0aGVyIHBhcnNpbmcgbWFrZXMgc2Vuc2UuICovCiAgICAgICAgaWYgKHNickVycm9yICE9IFNCUkRFQ19PSykgewogICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgfQogICAgICB9CiAgICB9IGVsc2UgewogICAgICBlcnJvciA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICB9CiAgICBicmVhazsKCiAgY2FzZSBFWFRfRklMTF9EQVRBOgogICAgewogICAgICBpbnQgdGVtcDsKCiAgICAgIHRlbXAgPSBGREtyZWFkQml0cyhoQnMsNCk7CiAgICAgIGJ5dGVzLS07CiAgICAgIGlmICh0ZW1wICE9IDApIHsKICAgICAgICBlcnJvciA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgd2hpbGUgKGJ5dGVzID4gMCkgewogICAgICAgIHRlbXAgPSBGREtyZWFkQml0cyhoQnMsOCk7CiAgICAgICAgYnl0ZXMtLTsKICAgICAgICBpZiAodGVtcCAhPSAweGE1KSB7CiAgICAgICAgICBlcnJvciA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgICAgKmNvdW50ID0gYnl0ZXM8PDM7CiAgICB9CiAgICBicmVhazsKCiAgY2FzZSBFWFRfREFUQV9FTEVNRU5UOgogICAgewogICAgICBpbnQgZGF0YUVsZW1lbnRWZXJzaW9uOwoKICAgICAgZGF0YUVsZW1lbnRWZXJzaW9uID0gRkRLcmVhZEJpdHMoaEJzLDQpOwogICAgICAqY291bnQgLT0gNDsKICAgICAgaWYgKGRhdGFFbGVtZW50VmVyc2lvbiA9PSAwKSAvKiBBTkNfREFUQSAqLwogICAgICB7CiAgICAgICAgaW50IHRlbXAsIGRhdGFFbGVtZW50TGVuZ3RoID0gMDsKICAgICAgICBkbyB7CiAgICAgICAgICB0ZW1wID0gRkRLcmVhZEJpdHMoaEJzLDgpOwogICAgICAgICAgKmNvdW50IC09IDg7CiAgICAgICAgICBkYXRhRWxlbWVudExlbmd0aCArPSB0ZW1wOwogICAgICAgIH0gd2hpbGUgKHRlbXAgPT0gMjU1ICk7CgogICAgICAgIENBYWNEZWNvZGVyX0FuY0RhdGFQYXJzZSgmc2VsZi0+YW5jRGF0YSwgaEJzLCBkYXRhRWxlbWVudExlbmd0aCk7CiAgICAgICAgKmNvdW50IC09IChkYXRhRWxlbWVudExlbmd0aDw8Myk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLyogYWxpZ24gPSAwICovCiAgICAgICAgZXJyb3IgPSBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgICAgIGdvdG8gYmFpbDsKICAgICAgfQogICAgfQogICAgYnJlYWs7CgogIGNhc2UgRVhUX0RBVEFfTEVOR1RIOgogICAgaWYgKCAhZklzRmlsbEVsZW1lbnQgICAgICAgICAgLyogTWFrZXMgbm8gc2VucyB0byBoYXZlIGFuIGFkZGl0aW9uYWwgbGVuZ3RoIGluIGEgZmlsbCAuLi4gICAqLwogICAgICAmJiAoc2VsZi0+ZmxhZ3MgJiBBQ19FUikgKSAgLyogLi4uIGVsZW1lbnQgYmVjYXVzZSB0aGlzIGV4dGVuc2lvbiBwYXlsb2FkIHR5cGUgd2FzIC4uLiAgICAqLwogICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogLi4uIGNyZWF0ZWQgdG8gY2lyY3VtdmVudCB0aGUgbWlzc2luZyBsZW5ndGggaW4gRVItU3ludGF4LiAqLwogICAgICBpbnQgYml0Q250LCBsZW4gPSBGREtyZWFkQml0cyhoQnMsIDQpOwogICAgICAqY291bnQgLT0gNDsKICAgICAgCiAgICAgIGlmIChsZW4gPT0gMTUpIHsKICAgICAgICBpbnQgYWRkX2xlbiA9IEZES3JlYWRCaXRzKGhCcywgOCk7CiAgICAgICAgKmNvdW50IC09IDg7CiAgICAgICAgbGVuICs9IGFkZF9sZW47CgogICAgICAgIGlmIChhZGRfbGVuID09IDI1NSkgewogICAgICAgICAgbGVuICs9IEZES3JlYWRCaXRzKGhCcywgMTYpOwogICAgICAgICAgKmNvdW50IC09IDE2OwogICAgICAgIH0KICAgICAgfQogICAgICBsZW4gPDw9IDM7CiAgICAgIGJpdENudCA9IGxlbjsKCiAgICAgIGlmICggKEVYVF9QQVlMT0FEX1RZUEUpRkRLcmVhZEJpdHMoaEJzLCA0KSA9PSBFWFRfREFUQV9MRU5HVEggKSB7CiAgICAgICAgLyogQ2hlY2sgTk9URSAyOiBUaGUgZXh0ZW5zaW9uX3BheWxvYWQoKSBpbmNsdWRlZCBoZXJlIG11c3QKICAgICAgICAgICAgICAgICAgICAgICAgIG5vdCBoYXZlIGV4dGVuc2lvbl90eXBlID09IEVYVF9EQVRBX0xFTkdUSC4gKi8KICAgICAgICBlcnJvciA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIC8qIHJld2luZCBhbmQgY2FsbCBteXNlbGYgYWdhaW4uICovCiAgICAgICAgRkRLcHVzaEJhY2soaEJzLCA0KTsKCiAgICAgICAgZXJyb3IgPQogICAgICAgICAgQ0FhY0RlY29kZXJfRXh0UGF5bG9hZFBhcnNlICgKICAgICAgICAgICAgICAgICAgc2VsZiwKICAgICAgICAgICAgICAgICAgaEJzLAogICAgICAgICAgICAgICAgICZiaXRDbnQsCiAgICAgICAgICAgICAgICAgIHByZXZpb3VzX2VsZW1lbnQsCiAgICAgICAgICAgICAgICAgIGVsSW5kZXgsCiAgICAgICAgICAgICAgICAgIDEgKTsgICAgICAvKiBUcmVhdCBzYW1lIGFzIGZpbGwgZWxlbWVudCAqLwoKICAgICAgICAqY291bnQgLT0gbGVuIC0gYml0Q250OwogICAgICB9CiAgICAgIC8qIE5vdGU6IHRoZSBmYWxsIHRocm91Z2ggaW4gY2FzZSB0aGUgaWYgc3RhdGVtZW50IGFib3ZlIGlzIG5vdCB0YWtlbiBpcyBpbnRlbnRpb25hbC4gKi8KICAgICAgYnJlYWs7CiAgICB9CgogIGNhc2UgRVhUX0ZJTDoKCiAgZGVmYXVsdDoKICAgIC8qIGFsaWduID0gNCAqLwogICAgRkRLcHVzaEZvcihoQnMsICpjb3VudCk7CiAgICAqY291bnQgPSAwOwogICAgYnJlYWs7CiAgfQoKYmFpbDoKICBpZiAoIChlcnJvciAhPSBBQUNfREVDX09LKQogICAgJiYgZklzRmlsbEVsZW1lbnQgKQogIHsgLyogU2tpcCB0aGUgcmVtYWluaW5nIGV4dGVuc2lvbiBieXRlcyAqLwogICAgRkRLcHVzaEJpRGlyZWN0aW9uYWwoaEJzLCAqY291bnQpOwogICAgKmNvdW50ID0gMDsKICAgIC8qIFBhdGNoIGVycm9yIGNvZGUgYmVjYXVzZSBkZWNvZGluZyBjYW4gZ28gb24uICovCiAgICBlcnJvciA9IEFBQ19ERUNfT0s7CiAgICAvKiBCZSBzdXJlIHRoYXQgcGFyc2luZyBlcnJvcnMgaGF2ZSBiZWVuIHN0b3JlZC4gKi8KICB9CiAgcmV0dXJuIGVycm9yOwp9CgovKiAgU3RyZWFtIENvbmZpZ3VyYXRpb24gYW5kIEluZm9ybWF0aW9uLgoKICAgIFRoaXMgY2xhc3MgaG9sZHMgY29uZmlndXJhdGlvbiBhbmQgaW5mb3JtYXRpb24gZGF0YSBmb3IgYSBzdHJlYW0gdG8gYmUgZGVjb2RlZC4gSXQKICAgIHByb3ZpZGVzIHRoZSBjYWxsaW5nIGFwcGxpY2F0aW9uIGFzIHdlbGwgYXMgdGhlIGRlY29kZXIgd2l0aCBzdWJzdGFudGlhbCBpbmZvcm1hdGlvbiwKICAgIGUuZy4gcHJvZmlsZSwgc2FtcGxpbmcgcmF0ZSwgbnVtYmVyIG9mIGNoYW5uZWxzIGZvdW5kIGluIHRoZSBiaXRzdHJlYW0gZXRjLgoqLwpzdGF0aWMKdm9pZCBDU3RyZWFtSW5mb0luaXQoQ1N0cmVhbUluZm8gKnBTdHJlYW1JbmZvKQp7CiAgcFN0cmVhbUluZm8tPmFhY1NhbXBsZVJhdGUgPSAwOwogIHBTdHJlYW1JbmZvLT5wcm9maWxlID0gLTE7CiAgcFN0cmVhbUluZm8tPmFvdCA9IEFPVF9OT05FOwoKICBwU3RyZWFtSW5mby0+Y2hhbm5lbENvbmZpZyA9IC0xOwogIHBTdHJlYW1JbmZvLT5iaXRSYXRlID0gMDsKICBwU3RyZWFtSW5mby0+YWFjU2FtcGxlc1BlckZyYW1lID0gMDsKCiAgcFN0cmVhbUluZm8tPmV4dEFvdCAgPSBBT1RfTk9ORTsKICBwU3RyZWFtSW5mby0+ZXh0U2FtcGxpbmdSYXRlID0gMDsKCiAgcFN0cmVhbUluZm8tPmZsYWdzID0gMDsKCiAgcFN0cmVhbUluZm8tPmVwQ29uZmlnID0gLTE7ICAgLyogZGVmYXVsdCBpcyBubyBFUiAqLwoKICBwU3RyZWFtSW5mby0+bnVtQ2hhbm5lbHMgPSAwOwogIHBTdHJlYW1JbmZvLT5zYW1wbGVSYXRlID0gMDsKICBwU3RyZWFtSW5mby0+ZnJhbWVTaXplID0gMDsKfQoKLyohCiAgXGJyaWVmIEluaXRpYWxpemF0aW9uIG9mIEFhY0RlY29kZXJDaGFubmVsSW5mbwoKICBUaGUgZnVuY3Rpb24gaW5pdGlhbGl6ZXMgdGhlIHBvaW50ZXJzIHRvIEFhY0RlY29kZXJDaGFubmVsSW5mbyBmb3IgZWFjaCBjaGFubmVsLAogIHNldCB0aGUgc3RhcnQgdmFsdWVzIGZvciB3aW5kb3cgc2hhcGUgYW5kIHdpbmRvdyBzZXF1ZW5jZSBvZiBvdmVybGFwJmFkZCB0byB6ZXJvLAogIHNldCB0aGUgb3ZlcmxhcCBidWZmZXIgdG8gemVybyBhbmQgaW5pdGlhbGl6ZXMgdGhlIHBvaW50ZXJzIHRvIHRoZSB3aW5kb3cgY29lZmZpY2llbnRzLgogIFxwYXJhbSBic0Zvcm1hdCBpcyB0aGUgZm9ybWF0IG9mIHRoZSBBQUMgYml0c3RyZWFtCgogIFxyZXR1cm4gIEFBQ0RFQ09ERVIgaW5zdGFuY2UKKi8KTElOS1NQRUNfQ1BQIEhBTkRMRV9BQUNERUNPREVSIENBYWNEZWNvZGVyX09wZW4oVFJBTlNQT1JUX1RZUEUgYnNGb3JtYXQpICAgIC8qITwgYml0c3RyZWFtIGZvcm1hdCAoYWRpZixhZHRzLGxvYXMsLi4uKS4gKi8KewogIEhBTkRMRV9BQUNERUNPREVSIHNlbGY7CgogIHNlbGYgPSBHZXRBYWNEZWNvZGVyKCk7CiAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgZ290byBiYWlsOwogIH0KCiAgLyogQXNzaWduIGNoYW5uZWwgbWFwcGluZyBpbmZvIGFycmF5cyAoZG9pbmcgc28gcmVtb3ZlcyBkZXBlbmRlbmN5IG9mIHNldHRpbmdzIGhlYWRlciBpbiBBUEkgaGVhZGVyKS4gKi8KICBzZWxmLT5zdHJlYW1JbmZvLnBDaGFubmVsSW5kaWNlcyA9IHNlbGYtPmNoYW5uZWxJbmRpY2VzOwogIHNlbGYtPnN0cmVhbUluZm8ucENoYW5uZWxUeXBlID0gc2VsZi0+Y2hhbm5lbFR5cGU7CgogIC8qIHNldCBkZWZhdWx0IG91dHB1dCBtb2RlICovCiAgc2VsZi0+b3V0cHV0SW50ZXJsZWF2ZWQgPSAxOyAgLyogaW50ZXJsZWF2ZWQgKi8KCiAgLyogaW5pdGlhbGl6ZSBhbmMgZGF0YSAqLwogIENBYWNEZWNvZGVyX0FuY0RhdGFJbml0KCZzZWxmLT5hbmNEYXRhLCBOVUxMLCAwKTsKCiAgLyogaW5pdGlhbGl6ZSBzdHJlYW0gaW5mbyAqLwogIENTdHJlYW1JbmZvSW5pdCgmc2VsZi0+c3RyZWFtSW5mbyk7CgogIC8qIGluaXRpYWxpemUgZXJyb3IgY29uY2VhbG1lbnQgY29tbW9uIGRhdGEgKi8KICBDQ29uY2VhbG1lbnRfSW5pdENvbW1vbkRhdGEoJnNlbGYtPmNvbmNlYWxDb21tb25EYXRhKTsKCiAgc2VsZi0+aERyY0luZm8gPSBHZXREcmNJbmZvKCk7CiAgaWYgKHNlbGYtPmhEcmNJbmZvID09IE5VTEwpIHsKICAgIGdvdG8gYmFpbDsKICB9CiAgLyogSW5pdCBjb21tb24gRFJDIHN0cnVjdHVyZSAqLwogIGFhY0RlY29kZXJfZHJjSW5pdCggc2VsZi0+aERyY0luZm8gKTsKICAvKiBTZXQgZGVmYXVsdCBmcmFtZSBkZWxheSAqLwogIGFhY0RlY29kZXJfZHJjU2V0UGFyYW0gKAogICAgICAgICAgc2VsZi0+aERyY0luZm8sCiAgICAgICAgICBEUkNfQlNfREVMQVksCiAgICAgICAgICBDQ29uY2VhbG1lbnRfR2V0RGVsYXkoJnNlbGYtPmNvbmNlYWxDb21tb25EYXRhKQogICAgICAgICk7CgoKICBzZWxmLT5hYWNDb21tb25EYXRhLndvcmtCdWZmZXJDb3JlMSA9IEdldFdvcmtCdWZmZXJDb3JlMSgpOwogIHNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUyID0gR2V0V29ya0J1ZmZlckNvcmUyKCk7CiAgaWYgKHNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUxID09IE5VTEwKICAgIHx8c2VsZi0+YWFjQ29tbW9uRGF0YS53b3JrQnVmZmVyQ29yZTIgPT0gTlVMTCApCiAgICBnb3RvIGJhaWw7CgogIHJldHVybiBzZWxmOwoKYmFpbDoKICBDQWFjRGVjb2Rlcl9DbG9zZSggc2VsZiApOwoKICByZXR1cm4gTlVMTDsKfQoKLyogRGVzdHJveSBhYWMgZGVjb2RlciAqLwpMSU5LU1BFQ19DUFAgdm9pZCBDQWFjRGVjb2Rlcl9DbG9zZShIQU5ETEVfQUFDREVDT0RFUiBzZWxmKQp7CiAgaW50IGNoOwoKICBpZiAoc2VsZiA9PSBOVUxMKQogICAgcmV0dXJuOwoKICBmb3IgKGNoPTA7IGNoPCg2KTsgY2grKykgewogICAgaWYgKHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdICE9IE5VTEwpIHsKICAgICAgRnJlZU92ZXJsYXBCdWZmZXIgKCZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+cE92ZXJsYXBCdWZmZXIpOwogICAgICBGcmVlQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvICgmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0pOwogICAgfQogICAgaWYgKHNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hdICE9IE5VTEwpIHsKICAgICAgRnJlZUFhY0RlY29kZXJDaGFubmVsSW5mbyAoJnNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hdKTsKICAgIH0KICB9CgogIHNlbGYtPmFhY0NoYW5uZWxzID0gMDsKCiAgaWYgKHNlbGYtPmhEcmNJbmZvKSB7CiAgICBGcmVlRHJjSW5mbygmc2VsZi0+aERyY0luZm8pOwogIH0KCiAgRnJlZVdvcmtCdWZmZXJDb3JlMSAoJnNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUxKTsKICBGcmVlV29ya0J1ZmZlckNvcmUyICgmc2VsZi0+YWFjQ29tbW9uRGF0YS53b3JrQnVmZmVyQ29yZTIpOwoKICBGcmVlQWFjRGVjb2RlciAoICZzZWxmKTsKfQoKCi8qIQogIFxicmllZiBJbml0aWFsaXphdGlvbiBvZiBkZWNvZGVyIGluc3RhbmNlCgogIFRoZSBmdW5jdGlvbiBpbml0aWFsaXplcyB0aGUgZGVjb2Rlci4KCiAgXHJldHVybiAgZXJyb3Igc3RhdHVzOiAwIGZvciBzdWNjZXNzLCA8PjAgZm9yIHVuc3VwcG9ydGVkIGNvbmZpZ3VyYXRpb25zCiovCkxJTktTUEVDX0NQUCBBQUNfREVDT0RFUl9FUlJPUiBDQWFjRGVjb2Rlcl9Jbml0KEhBTkRMRV9BQUNERUNPREVSIHNlbGYsIGNvbnN0IENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqYXNjKQp7CiAgQUFDX0RFQ09ERVJfRVJST1IgZXJyID0gQUFDX0RFQ19PSzsKICBJTlQgYXNjQ2hhbm5lbHMsIGNoLCBhc2NDaGFuZ2VkID0gMDsKCiAgaWYgKCFzZWxmKQogICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CgogIC8vIHNldCBwcm9maWxlIGFuZCBjaGVjayBmb3Igc3VwcG9ydGVkIGFvdAogIC8vIGxlYXZlIHByb2ZpbGUgb24gZGVmYXVsdCAoPS0xKSBmb3IgYWxsIG90aGVyIHN1cHBvcnRlZCBNUEVHLTQgYW90J3MgZXhjZXB0IGFvdD0yICg9QUFDLUxDKQogIHN3aXRjaCAoYXNjLT5tX2FvdCkgewogIGNhc2UgQU9UX0FBQ19MQzoKICAgIHNlbGYtPnN0cmVhbUluZm8ucHJvZmlsZSA9IDE7CiAgICBicmVhazsKCiAgY2FzZSBBT1RfU0JSOgogIGNhc2UgQU9UX1BTOgogIGNhc2UgQU9UX0VSX0FBQ19MRDoKICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgYnJlYWs7CgogIGRlZmF1bHQ6CiAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9BT1Q7CiAgfQoKICBDUHJvZ3JhbUNvbmZpZ19Jbml0KCZzZWxmLT5wY2UpOwoKICAvKiBzZXQgY2hhbm5lbHMgKi8KICBzd2l0Y2ggKGFzYy0+bV9jaGFubmVsQ29uZmlndXJhdGlvbikgewogIGNhc2UgMDoKI2lmZGVmIFRQX1BDRV9FTkFCTEUKICAgIC8qIGdldCBjaGFubmVscyBmcm9tIHByb2dyYW0gY29uZmlnIChBU0MpICovCiAgICBpZiAoQ1Byb2dyYW1Db25maWdfSXNWYWxpZCgmYXNjLT5tX3Byb2dyQ29uZmlnRWxlbWVudCkpIHsKICAgICAgYXNjQ2hhbm5lbHMgPSBhc2MtPm1fcHJvZ3JDb25maWdFbGVtZW50Lk51bUNoYW5uZWxzOwogICAgICBpZiAoYXNjQ2hhbm5lbHMgPiAwKSB7CiAgICAgICAgaW50IGVsOwogICAgICAgIC8qIHZhbGlkIG51bWJlciBvZiBjaGFubmVscyAtPiBjb3B5IHByb2dyYW0gY29uZmlnIGVsZW1lbnQgKFBDRSkgZnJvbSBBU0MgKi8KICAgICAgICBGREttZW1jcHkoJnNlbGYtPnBjZSwgJmFzYy0+bV9wcm9nckNvbmZpZ0VsZW1lbnQsIHNpemVvZihDUHJvZ3JhbUNvbmZpZykpOwogICAgICAgIC8qIEJ1aWx0IGVsZW1lbnQgdGFibGUgKi8KICAgICAgICBlbCA9IENQcm9ncmFtQ29uZmlnX0dldEVsZW1lbnRUYWJsZSgmYXNjLT5tX3Byb2dyQ29uZmlnRWxlbWVudCwgc2VsZi0+ZWxlbWVudHMsIDcpOwogICAgICAgIGZvciAoOyBlbDw3OyBlbCsrKSB7CiAgICAgICAgICBzZWxmLT5lbGVtZW50c1tlbF0gPSBJRF9OT05FOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9DSEFOTkVMQ09ORklHOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBpZiAodHJhbnNwb3J0RGVjX0dldEZvcm1hdChzZWxmLT5oSW5wdXQpID09IFRUX01QNF9BRFRTKSB7CiAgICAgICAgLyogc2V0IGRlZmF1bHQgbWF4X2NoYW5uZWxzIGZvciBtZW1vcnkgYWxsb2NhdGlvbiBiZWNhdXNlIGluIGltcGxpY2l0IGNoYW5uZWwgbWFwcGluZyBtb2RlCiAgICAgICAgICAgd2UgZG9uJ3Qga25vdyB0aGUgYWN0dWFsIG51bWJlciBvZiBjaGFubmVscyB1bnRpbCB3ZSBwcm9jZXNzZWQgYXQgbGVhc3Qgb25lIHJhd19kYXRhX2Jsb2NrKCkuICovCiAgICAgICAgYXNjQ2hhbm5lbHMgPSAoNik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEFBQ19ERUNfVU5TVVBQT1JURURfQ0hBTk5FTENPTkZJRzsKICAgICAgfQogICAgfQojZWxzZSAvKiBUUF9QQ0VfRU5BQkxFICovCiAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9DSEFOTkVMQ09ORklHOwojZW5kaWYgLyogVFBfUENFX0VOQUJMRSAqLwogICAgYnJlYWs7CiAgY2FzZSAxOiBjYXNlIDI6IGNhc2UgMzogY2FzZSA0OiBjYXNlIDU6IGNhc2UgNjoKICAgIGFzY0NoYW5uZWxzID0gYXNjLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uOwogICAgYnJlYWs7CiAgY2FzZSA3OgogICAgYXNjQ2hhbm5lbHMgPSA4OwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIHJldHVybiBBQUNfREVDX1VOU1VQUE9SVEVEX0NIQU5ORUxDT05GSUc7CiAgfQoKICAvKiBJbml0aWFsaXplIGNvbnN0YW50IG1hcHBpbmdzIGZvciBjaGFubmVsIGNvbmZpZyAxLTcgKi8KICBpZiAoYXNjLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uID4gMCkgewogICAgaW50IGVsOwogICAgRkRLbWVtY3B5KHNlbGYtPmVsZW1lbnRzLCBlbGVtZW50c1RhYlthc2MtPm1fY2hhbm5lbENvbmZpZ3VyYXRpb24tMV0sIHNpemVvZihNUDRfRUxFTUVOVF9JRCkqRkRLbWluKDcsNykpOwogICAgZm9yIChlbD03OyBlbDw3OyBlbCsrKSB7CiAgICAgIHNlbGYtPmVsZW1lbnRzW2VsXSA9IElEX05PTkU7CiAgICB9CiAgICBmb3IgKGNoPTA7IGNoPGFzY0NoYW5uZWxzOyBjaCsrKSB7CiAgICAgIHNlbGYtPmNoTWFwcGluZ1tjaF0gPSBjaDsKICAgIH0KICAgIGZvciAoOyBjaDwoNik7IGNoKyspIHsKICAgICAgc2VsZi0+Y2hNYXBwaW5nW2NoXSA9IDI1NTsKICAgIH0KICB9CgogIHNlbGYtPnN0cmVhbUluZm8uY2hhbm5lbENvbmZpZyA9IGFzYy0+bV9jaGFubmVsQ29uZmlndXJhdGlvbjsKCiAgaWYgKGFzY0NoYW5uZWxzID4gKDYpKSB7CiAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9DSEFOTkVMQ09ORklHOwogIH0KICBpZiAoc2VsZi0+c3RyZWFtSW5mby5hb3QgIT0gYXNjLT5tX2FvdCkgewogICAgc2VsZi0+c3RyZWFtSW5mby5hb3QgPSBhc2MtPm1fYW90OwogICAgYXNjQ2hhbmdlZCA9IDE7CiAgfQoKICBpZiAoc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUgIT0gKElOVClhc2MtPm1fc2FtcGxlc1BlckZyYW1lKSB7CiAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSA9IGFzYy0+bV9zYW1wbGVzUGVyRnJhbWU7CiAgICBhc2NDaGFuZ2VkID0gMTsKICB9CgogIHNlbGYtPnN0cmVhbUluZm8uYml0UmF0ZSAgICAgICAgICAgID0gMDsKCiAgLyogU2V0IHN5bnRheCBmbGFncyAqLwogIHNlbGYtPmZsYWdzID0gMDsKCiAgc2VsZi0+c3RyZWFtSW5mby5leHRBb3QgICAgICAgICAgICAgICA9IGFzYy0+bV9leHRlbnNpb25BdWRpb09iamVjdFR5cGU7CiAgc2VsZi0+c3RyZWFtSW5mby5leHRTYW1wbGluZ1JhdGUgICAgICA9IGFzYy0+bV9leHRlbnNpb25TYW1wbGluZ0ZyZXF1ZW5jeTsKICBzZWxmLT5mbGFncyB8PSAoYXNjLT5tX3NiclByZXNlbnRGbGFnKSA/IEFDX1NCUl9QUkVTRU5UIDogMDsKICBzZWxmLT5mbGFncyB8PSAoYXNjLT5tX3BzUHJlc2VudEZsYWcpID8gQUNfUFNfUFJFU0VOVCA6IDA7CiAgc2VsZi0+c2JyRW5hYmxlZCA9IDA7CgogIC8qIC0tLS0tLS0tLSB2Y2IxMSAtLS0tLS0tLS0tLS0gKi8KICBzZWxmLT5mbGFncyB8PSAoYXNjLT5tX3ZjYjExRmxhZykgPyBBQ19FUl9WQ0IxMSA6IDA7CgogIC8qIC0tLS0tLS0tLS0gcnZsYyAtLS0tLS0tLS0tLS0gKi8KICBzZWxmLT5mbGFncyB8PSAoYXNjLT5tX3J2bGNGbGFnKSA/IEFDX0VSX1JWTEMgOiAwOwoKICAvKiAtLS0tLS0tLS0tLSBoY3IgLS0tLS0tLS0tLS0tICovCiAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV9oY3JGbGFnKSA/IEFDX0VSX0hDUiA6IDA7CgogIGlmIChhc2MtPm1fYW90ID09IEFPVF9FUl9BQUNfRUxEKSB7CiAgICBzZWxmLT5mbGFncyB8PSAgQUNfRUxEOwogICAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV9zYy5tX2VsZFNwZWNpZmljQ29uZmlnLm1fc2JyQ3JjRmxhZykgPyBBQ19TQlJDUkMgOiAwOwogICAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV9zYy5tX2VsZFNwZWNpZmljQ29uZmlnLm1fdXNlTGRRbWZUaW1lQWxpZ24pID8gQUNfTERfTVBTIDogMDsKICB9CiAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV9hb3QgPT0gQU9UX0VSX0FBQ19MRCkgPyBBQ19MRCA6IDA7CiAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV9lcENvbmZpZyA+PSAwKSA/IEFDX0VSIDogMDsKCgogIGlmIChhc2MtPm1fc2JyUHJlc2VudEZsYWcpIHsKICAgIHNlbGYtPnNickVuYWJsZWQgPSAxOwogICAgc2VsZi0+c2JyRW5hYmxlZFByZXYgPSAxOwogIH0KICBpZiAoYXNjLT5tX3BzUHJlc2VudEZsYWcpIHsKICAgIHNlbGYtPmZsYWdzIHw9IEFDX1BTX1BSRVNFTlQ7CiAgfQoKICBpZiAoIChhc2MtPm1fZXBDb25maWcgPj0gMCkKICAgICYmIChhc2MtPm1fY2hhbm5lbENvbmZpZ3VyYXRpb24gPD0gMCkgKSB7CiAgICAvKiB3ZSBoYXZlIHRvIGtub3cgdGhlIG51bWJlciBvZiBjaGFubmVscyBvdGhlcndpc2Ugbm8gZGVjb2RpbmcgaXMgcG9zc2libGUgKi8KICAgIHJldHVybiBBQUNfREVDX1VOU1VQUE9SVEVEX0VSX0ZPUk1BVDsKICB9CgogIHNlbGYtPnN0cmVhbUluZm8uZXBDb25maWcgPSBhc2MtPm1fZXBDb25maWc7CiAgLyogc2VsZi0+aElucHV0LT5hc2MubV9lcENvbmZpZyA9IGFzYy0+bV9lcENvbmZpZzsgKi8KCiAgaWYgKGFzYy0+bV9lcENvbmZpZyA+IDEpCiAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9FUl9GT1JNQVQ7CgogIC8qIENoZWNrIGlmIHNhbXBsZXJhdGUgY2hhbmdlZC4gKi8KICBpZiAoc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVSYXRlICE9IChJTlQpYXNjLT5tX3NhbXBsaW5nRnJlcXVlbmN5KSB7CiAgICBBQUNfREVDT0RFUl9FUlJPUiBlcnJvcjsKCiAgICBhc2NDaGFuZ2VkID0gMTsKCiAgICAvKiBVcGRhdGUgc2FtcGxlcmF0ZSBpbmZvLiAqLwogICAgZXJyb3IgPSBnZXRTYW1wbGluZ1JhdGVJbmZvKCZzZWxmLT5zYW1wbGluZ1JhdGVJbmZvLCBhc2MtPm1fc2FtcGxlc1BlckZyYW1lLCBhc2MtPm1fc2FtcGxpbmdGcmVxdWVuY3lJbmRleCwgYXNjLT5tX3NhbXBsaW5nRnJlcXVlbmN5KTsKICAgIGlmIChlcnJvciAhPSBBQUNfREVDX09LKSB7CiAgICAgIHJldHVybiBlcnJvcjsKICAgIH0KICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlUmF0ZSA9IHNlbGYtPnNhbXBsaW5nUmF0ZUluZm8uc2FtcGxpbmdSYXRlOwogIH0KCiAgLyogQ2hlY2sgaWYgYW1vdW50IG9mIGNoYW5uZWxzIGhhcyBjaGFuZ2VkLiAqLwogIGlmIChzZWxmLT5hc2NDaGFubmVscyAhPSBhc2NDaGFubmVscykKICB7CiAgICAgYXNjQ2hhbmdlZCA9IDE7CgogICAgIC8qIEFsbG9jYXRlIGFsbCBtZW1vcnkgc3RydWN0dXJlcyBmb3IgZWFjaCBjaGFubmVsICovCiAgICAgewogICAgICAgZm9yIChjaCA9IDA7IGNoIDwgYXNjQ2hhbm5lbHM7IGNoKyspIHsKICAgICAgICAgQ0FhY0RlY29kZXJEeW5hbWljRGF0YSAqYWFjRGVjb2RlckR5bmFtaWNEYXRhID0gJnNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUxLT5wQWFjRGVjb2RlckR5bmFtaWNEYXRhW2NoJTJdOwoKICAgICAgICAgLyogaW5pdGlhbGl6ZSBwb2ludGVyIHRvIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKi8KICAgICAgICAgaWYgKHNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hdID09IE5VTEwpIHsKICAgICAgICAgICBzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoXSA9IEdldEFhY0RlY29kZXJDaGFubmVsSW5mbyhjaCk7CiAgICAgICAgICAgLyogVGhpcyBpcyB0ZW1wb3JhcnkgdW50aWwgdGhlIER5bmFtaWNEYXRhIGlzIHNwbGl0IGludG8gdHdvIG9yIG1vcmUgcmVnaW9ucyEKICAgICAgICAgICAgICBUaGUgbWVtb3J5IGNvdWxkIGJlIHJldXNlZCBhZnRlciBjb21wbGV0ZWQgY29yZSBkZWNvZGluZy4gKi8KICAgICAgICAgICBpZiAoc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaF0gPT0gTlVMTCkgewogICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgICAgIH0KICAgICAgICAgICAvKiBIb29rIHNoYXJlZCB3b3JrIG1lbW9yeSBpbnRvIGNoYW5uZWwgZGF0YSBzdHJ1Y3R1cmUgKi8KICAgICAgICAgICBzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoXS0+cER5bkRhdGEgPSAgYWFjRGVjb2RlckR5bmFtaWNEYXRhOwogICAgICAgICAgIHNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hdLT5wQ29tRGF0YSA9ICZzZWxmLT5hYWNDb21tb25EYXRhOwogICAgICAgICB9CgogICAgICAgICAvKiBBbGxvY2F0ZSBwZXJzaXN0ZW50IGNoYW5uZWwgbWVtb3J5ICovCiAgICAgICAgIGlmIChzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXSA9PSBOVUxMKSB7CiAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0gPSBHZXRBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8oY2gpOwogICAgICAgICAgIGlmIChzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXSA9PSBOVUxMKSB7CiAgICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgICAgfQogICAgICAgICAgIHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdLT5wT3ZlcmxhcEJ1ZmZlciA9IEdldE92ZXJsYXBCdWZmZXIoY2gpOyAvKiBUaGlzIGFyZWEgc2l6ZSBkZXBlbmRzIG9uIHRoZSBBT1QgKi8KICAgICAgICAgICBpZiAoc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0tPnBPdmVybGFwQnVmZmVyID09IE5VTEwpIHsKICAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICAgICB9CiAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaF0tPnBTcGVjdHJhbENvZWZmaWNpZW50ID0gKFNQRUNUUkFMX1BUUikgJnNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUyW2NoKjEwMjRdOwoKICAgICAgICAgfQogICAgICAgICBDUG5zX0luaXRQbnMoJnNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hdLT5kYXRhLmFhYy5QbnNEYXRhLCAmc2VsZi0+YWFjQ29tbW9uRGF0YS5wbnNJbnRlckNoYW5uZWxEYXRhLCAmc2VsZi0+YWFjQ29tbW9uRGF0YS5wbnNDdXJyZW50U2VlZCwgc2VsZi0+YWFjQ29tbW9uRGF0YS5wbnNSYW5kb21TZWVkKTsKICAgICAgIH0KCgogICAgICAgSGNySW5pdFJvbSgmc2VsZi0+YWFjQ29tbW9uRGF0YS5vdmVybGF5LmFhYy5lckhjckluZm8pOwogICAgICAgc2V0SGNyVHlwZSgmc2VsZi0+YWFjQ29tbW9uRGF0YS5vdmVybGF5LmFhYy5lckhjckluZm8sIElEX1NDRSk7CgogICAgICAgLyogTWFrZSBhbGxvY2F0ZWQgY2hhbm5lbCBjb3VudCBwZXJzaXN0ZW50IGluIGRlY29kZXIgY29udGV4dC4gKi8KICAgICAgIHNlbGYtPmFhY0NoYW5uZWxzID0gYXNjQ2hhbm5lbHM7CiAgICB9CgogICAgLyogTWFrZSBhbW91bnQgb2Ygc2lnbmFsbGVkIGNoYW5uZWxzIHBlcnNpc3RlbnQgaW4gZGVjb2RlciBjb250ZXh0LiAqLwogICAgc2VsZi0+YXNjQ2hhbm5lbHMgPSBhc2NDaGFubmVsczsKICB9CgogIC8qIFVwZGF0ZSBzdHJ1Y3R1cmVzICovCiAgaWYgKGFzY0NoYW5nZWQpIHsKCiAgICAgLyogVGhpbmdzIHRvIGJlIGRvbmUgZm9yIGVhY2ggY2hhbm5lbCwgd2hpY2ggZG8gbm90IGludm9sdmVkIGFsbG9jYXRpbmcgbWVtb3J5LiAqLwogICAgIGZvciAoY2ggPSAwOyBjaCA8IGFzY0NoYW5uZWxzOyBjaCsrKSB7CiAgICAgICBzd2l0Y2ggKHNlbGYtPnN0cmVhbUluZm8uYW90KSB7CiAgICAgICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICAgICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgICAgICAgICBzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoXS0+Z3JhbnVsZUxlbmd0aCA9IHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lOwogICAgICAgICAgIGJyZWFrOwogICAgICAgICBkZWZhdWx0OgogICAgICAgICAgIHNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hdLT5ncmFudWxlTGVuZ3RoID0gc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUgLyA4OwogICAgICAgICAgIGJyZWFrOwogICAgICAgfQogICAgICAgbWRjdF9pbml0KCAmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0tPklNZGN0LAogICAgICAgICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0tPnBPdmVybGFwQnVmZmVyLAogICAgICAgICAgICAgICAgICAgT3ZlcmxhcEJ1ZmZlclNpemUgKTsKCgogICAgICAgIC8qIFJlc2V0IERSQyBjb250cm9sIGRhdGEgZm9yIHRoaXMgY2hhbm5lbCAqLwogICAgICAgIGFhY0RlY29kZXJfZHJjSW5pdENoYW5uZWxEYXRhICggJnNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdLT5kcmNEYXRhICk7CgogICAgICAgLyogUmVzZXQgY29uY2VhbG1lbnQgb25seSBpZiBBU0MgY2hhbmdlZC4gT3RoZXJ3aXNlIGl0IHdpbGwgYmUgZG9uZSB3aXRoIGFueSBjb25maWcgY2FsbGJhY2suCiAgICAgICAgICBFLmcuIGV2ZXJ5IHRpbWUgdGhlIExBVE0gU01DIGlzIHByZXNlbnQuICovCiAgICAgICBDQ29uY2VhbG1lbnRfSW5pdENoYW5uZWxEYXRhKCZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+Y29uY2VhbG1lbnRJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+Y29uY2VhbENvbW1vbkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSApOwogICAgIH0KICB9CgogIC8qIFVwZGF0ZSBleHRlcm5hbGx5IHZpc2libGUgY29weSBvZiBmbGFncyAqLwogIHNlbGYtPnN0cmVhbUluZm8uZmxhZ3MgPSBzZWxmLT5mbGFnczsKCiAgcmV0dXJuIGVycjsKCmJhaWw6CiAgYWFjRGVjb2Rlcl9DbG9zZSggc2VsZiApOwogIHJldHVybiBBQUNfREVDX09VVF9PRl9NRU1PUlk7Cn0KCgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IgQ0FhY0RlY29kZXJfRGVjb2RlRnJhbWUoCiAgICAgICAgSEFORExFX0FBQ0RFQ09ERVIgc2VsZiwKICAgICAgICBjb25zdCBVSU5UIGZsYWdzLAogICAgICAgIElOVF9QQ00gKnBUaW1lRGF0YSwKICAgICAgICBjb25zdCBJTlQgIHRpbWVEYXRhU2l6ZSwKICAgICAgICBjb25zdCBJTlQgaW50ZXJsZWF2ZWQKICAgICAgICApCnsKICBBQUNfREVDT0RFUl9FUlJPUiBFcnJvclN0YXR1cyA9IEFBQ19ERUNfT0s7CgogIENQcm9ncmFtQ29uZmlnICpwY2U7CiAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMgPSB0cmFuc3BvcnREZWNfR2V0Qml0c3RyZWFtKHNlbGYtPmhJbnB1dCwgMCk7CgogIE1QNF9FTEVNRU5UX0lEIHR5cGUgPSBJRF9OT05FOyAgICAgICAgICAgIC8qIEN1cnJlbnQgZWxlbWVudCB0eXBlICovCiAgSU5UIGFhY0NoYW5uZWxzPTA7ICAgICAgICAgICAgICAgICAgICAgICAgLyogQ2hhbm5lbCBjb3VudGVyIGZvciBjaGFubmVscyBmb3VuZCBpbiB0aGUgYml0c3RyZWFtICovCgogIElOVCBhdVN0YXJ0QW5jaG9yID0gKElOVClGREtnZXRWYWxpZEJpdHMoYnMpOyAgLyogQVUgc3RhcnQgYml0IGJ1ZmZlciBwb3NpdGlvbiBmb3IgQVUgYnl0ZSBhbGlnbm1lbnQgKi8KCiAgc2VsZi0+ZnJhbWVPSyA9IDE7CgogIC8qIEFueSBzdXBwb3J0ZWQgYmFzZSBsYXllciB2YWxpZCBBVSB3aWxsIHJlcXVpcmUgbW9yZSB0aGFuIDE2IGJpdHMuICovCiAgaWYgKCAodHJhbnNwb3J0RGVjX0dldEF1Qml0c1JlbWFpbmluZyhzZWxmLT5oSW5wdXQsIDApIDwgMTUpICYmIChmbGFncyAmIChBQUNERUNfQ09OQ0VBTHxBQUNERUNfRkxVU0gpKSA9PSAwKSB7CiAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgfQoKCiAgLyogUmVzZXQgUHJvZ3JhbSBDb25maWcgc3RydWN0dXJlICovCiAgcGNlID0gJnNlbGYtPnBjZTsKICBDUHJvZ3JhbUNvbmZpZ19SZXNldChwY2UpOwoKICBDQWFjRGVjb2Rlcl9BbmNEYXRhUmVzZXQoJnNlbGYtPmFuY0RhdGEpOwoKICB7CiAgICBpbnQgY2g7CgogICAgaWYgKHNlbGYtPnN0cmVhbUluZm8uY2hhbm5lbENvbmZpZyA9PSAwKSB7CiAgICAgIC8qIEluaXQgQ2hhbm5lbC9FbGVtZW50IG1hcHBpbmcgdGFibGUgKi8KICAgICAgZm9yIChjaD0wOyBjaDwoNik7IGNoKyspIHsKICAgICAgICBzZWxmLT5jaE1hcHBpbmdbY2hdID0gMjU1OwogICAgICB9CiAgICAgIGlmICghQ1Byb2dyYW1Db25maWdfSXNWYWxpZChwY2UpKSB7CiAgICAgICAgaW50IGVsOwogICAgICAgIGZvciAoZWw9MDsgZWw8NzsgZWwrKykgewogICAgICAgICAgc2VsZi0+ZWxlbWVudHNbZWxdID0gSURfTk9ORTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIC8qIENoZWNrIHNhbXBsaW5nIGZyZXF1ZW5jeSAgKi8KICBzd2l0Y2ggKCBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZVJhdGUgKSB7CiAgICBjYXNlIDE2MDAwOgogICAgY2FzZSAxMjAwMDoKICAgY2FzZSAxMTAyNToKICAgY2FzZSAgODAwMDoKICAgIGNhc2UgIDczNTA6CiAgICBjYXNlIDQ4MDAwOgogICAgY2FzZSA0NDEwMDoKICAgIGNhc2UgMzIwMDA6CiAgICBjYXNlIDI0MDAwOgogICAgY2FzZSAyMjA1MDoKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBpZiAoICEgKHNlbGYtPmZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwKSkgKSB7CiAgICAgICAgcmV0dXJuIEFBQ19ERUNfVU5TVVBQT1JURURfU0FNUExJTkdSQVRFOwogICAgICB9CiAgICAgIGJyZWFrOwogIH0KCgogIGlmICggZmxhZ3MgJiBBQUNERUNfQ0xSSElTVCApCiAgewogICAgaW50IGNoOwogICAgLyogQ2xlYXIgaGlzdG9yeSAqLwogICAgZm9yIChjaCA9IDA7IGNoIDwgc2VsZi0+YWFjQ2hhbm5lbHM7IGNoKyspIHsKICAgICAgLyogUmVzZXQgY29uY2VhbG1lbnQgKi8KICAgICAgQ0NvbmNlYWxtZW50X0luaXRDaGFubmVsRGF0YSgmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0tPmNvbmNlYWxtZW50SW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+Y29uY2VhbENvbW1vbkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lICk7CiAgICAgIC8qIENsZWFyIGNvbmNlYWxtZW50IGJ1ZmZlcnMgdG8gZ2V0IHJpZCBvZiB0aGUgY29tcGxldGUgaGlzdG9yeSAqLwogICAgICBGREttZW1jbGVhcihzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+Y29uY2VhbG1lbnRJbmZvLnNwZWN0cmFsQ29lZmZpY2llbnQsIDEwMjQgKiBzaXplb2YoRklYUF9DTkNMKSk7CiAgICAgIEZES21lbWNsZWFyKHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdLT5jb25jZWFsbWVudEluZm8uc3BlY1NjYWxlLCA4ICogc2l6ZW9mKFNIT1JUKSk7CiAgICAgIC8qIENsZWFyIG92ZXJsYXAtYWRkIGJ1ZmZlcnMgdG8gYXZvaWQgY2xpY2tzLiAqLwogICAgICBGREttZW1jbGVhcihzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+SU1kY3Qub3ZlcmxhcC5mcmVxLCBPdmVybGFwQnVmZmVyU2l6ZSpzaXplb2YoRklYUF9EQkwpKTsKICAgICB9CiAgfQoKCgojaWZkZWYgVFBfUENFX0VOQUJMRQogIGludCBwY2VSZWFkID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEZsYWcgaW5kaWNhdGluZyBhIFBDRSBpbiB0aGUgY3VycmVudCByYXdfZGF0YV9ibG9jaygpICovCiNlbmRpZgoKCiAgSU5UIGhkYWFjRGVjb2RlZCA9IDA7CiAgTVA0X0VMRU1FTlRfSUQgcHJldmlvdXNfZWxlbWVudCA9IElEX0VORDsgLyogTGFzdCBlbGVtZW50IElEIChyZXF1aXJlZCBmb3IgZXh0ZW5zaW9uIHBheWxvYWQgbWFwcGluZyAqLwogIFVDSEFSIHByZXZpb3VzX2VsZW1lbnRfaW5kZXggPSAwOyAgICAgICAgIC8qIENhbm9uaWNhbCBpbmRleCBvZiBsYXN0IGVsZW1lbnQgKi8KICBpbnQgZWxlbWVudF9jb3VudCA9IDA7ICAgICAgICAgICAgICAgICAgICAvKiBFbGVtZW50IGNvdW50ZXIgZm9yIGVsZW1lbnRzIGZvdW5kIGluIHRoZSBiaXRzdHJlYW0gKi8KICBpbnQgZWxfY250W0lEX0xBU1RdID0geyAwIH07ICAgICAgICAgICAgICAvKiBlbGVtZW50IGNvdW50ZXIgKCByb2J1c3RuZXNzICkgKi8KCiAgd2hpbGUgKCAodHlwZSAhPSBJRF9FTkQpICYmICghIChmbGFncyAmIChBQUNERUNfQ09OQ0VBTCB8IEFBQ0RFQ19GTFVTSCkpKSAmJiBzZWxmLT5mcmFtZU9LICkKICB7CiAgICBpbnQgZWxfY2hhbm5lbHM7CgogICAgaWYgKCEgKHNlbGYtPmZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwfEFDX0VMRHxBQ19TQ0FMQUJMRXxBQ19FUikpKQogICAgICB0eXBlID0gKE1QNF9FTEVNRU5UX0lEKSBGREtyZWFkQml0cyhicywzKTsKICAgIGVsc2UgCiAgICAgIHR5cGUgPSBzZWxmLT5lbGVtZW50c1tlbGVtZW50X2NvdW50XTsKCiAgICBzZXRIY3JUeXBlKCZzZWxmLT5hYWNDb21tb25EYXRhLm92ZXJsYXkuYWFjLmVySGNySW5mbywgdHlwZSk7CgoKICAgIGlmICgoSU5UKUZES2dldFZhbGlkQml0cyhicykgPCAwKQogICAgICBzZWxmLT5mcmFtZU9LID0gMDsKCiAgICBzd2l0Y2ggKHR5cGUpCiAgICB7CiAgICAgIGNhc2UgSURfU0NFOgogICAgICBjYXNlIElEX0NQRToKICAgICAgY2FzZSBJRF9MRkU6CiAgICAgICAgLyoKICAgICAgICAgIENvbnNpc3RlbmN5IGNoZWNrCiAgICAgICAgKi8KCiAgICAgICAgaWYgKHR5cGUgPT0gSURfQ1BFKSB7CiAgICAgICAgICBlbF9jaGFubmVscyA9IDI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGVsX2NoYW5uZWxzID0gMTsKICAgICAgICB9CgogICAgICAgIGlmICggKGVsX2NudFt0eXBlXSA+PSAoc2VsZi0+YXNjQ2hhbm5lbHM+PihlbF9jaGFubmVscy0xKSkpIHx8IChhYWNDaGFubmVscyA+IChzZWxmLT5hc2NDaGFubmVscy1lbF9jaGFubmVscykpICkgewogICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKICAgICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAoICEoc2VsZi0+ZmxhZ3MgJiAoQUNfVVNBQ3xBQ19SU1ZENTApKSApIHsKICAgICAgICAgIGludCBjaDsKICAgICAgICAgIGZvciAoY2g9MDsgY2ggPCBlbF9jaGFubmVsczsgY2grPTEpIHsKICAgICAgICAgICAgQ1Buc19SZXNldERhdGEoJnNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bYWFjQ2hhbm5lbHMrY2hdLT5kYXRhLmFhYy5QbnNEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1thYWNDaGFubmVscytjaF0tPnBDb21EYXRhLT5wbnNJbnRlckNoYW5uZWxEYXRhKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmKHNlbGYtPmZyYW1lT0spIHsKICAgICAgICAgIEVycm9yU3RhdHVzID0gQ0NoYW5uZWxFbGVtZW50X1JlYWQoIGJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1thYWNDaGFubmVsc10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2FhY0NoYW5uZWxzXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+c2FtcGxpbmdSYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbF9jaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uZXBDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5oSW5wdXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICBpZiAoRXJyb3JTdGF0dXMpIHsKICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICB9CiAgICAgICAgfQoKCiAgICAgICAgaWYgKCBzZWxmLT5mcmFtZU9LKSB7CiAgICAgICAgICAvKiBMb29rdXAgdGhlIGVsZW1lbnQgYW5kIGRlY29kZSBpdCBvbmx5IGlmIGl0IGJlbG9uZ3MgdG8gdGhlIGN1cnJlbnQgcHJvZ3JhbSAqLwogICAgICAgICAgaWYgKCBDUHJvZ3JhbUNvbmZpZ19Mb29rdXBFbGVtZW50KAogICAgICAgICAgICAgICAgICBwY2UsCiAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uY2hhbm5lbENvbmZpZywKICAgICAgICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1thYWNDaGFubmVsc10tPkVsZW1lbnRJbnN0YW5jZVRhZywKICAgICAgICAgICAgICAgICAgYWFjQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgIHNlbGYtPmNoTWFwcGluZywKICAgICAgICAgICAgICAgICAgc2VsZi0+Y2hhbm5lbFR5cGUsCiAgICAgICAgICAgICAgICAgIHNlbGYtPmNoYW5uZWxJbmRpY2VzLAogICAgICAgICAgICAgICAgICZwcmV2aW91c19lbGVtZW50X2luZGV4LAogICAgICAgICAgICAgICAgICBzZWxmLT5lbGVtZW50cywKICAgICAgICAgICAgICAgICAgdHlwZSkgKQogICAgICAgICAgewogICAgICAgICAgICBpZiAoICFoZGFhY0RlY29kZWQgKSB7CiAgICAgICAgICAgICAgQ0NoYW5uZWxFbGVtZW50X0RlY29kZSgKICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bYWFjQ2hhbm5lbHNdLAogICAgICAgICAgICAgICAgICAgICAmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1thYWNDaGFubmVsc10sCiAgICAgICAgICAgICAgICAgICAgICZzZWxmLT5zYW1wbGluZ1JhdGVJbmZvLAogICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICBlbF9jaGFubmVscwogICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBhYWNDaGFubmVscyArPSAxOwogICAgICAgICAgICBpZiAodHlwZSA9PSBJRF9DUEUpIHsKICAgICAgICAgICAgICBhYWNDaGFubmVscyArPSAxOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICB9CiAgICAgICAgICAvKiBDcmVhdGUgU0JSIGVsZW1lbnQgZm9yIFNCUiBmb3IgdXBzYW1wbGluZy4gKi8KICAgICAgICAgIGlmICggKHR5cGUgPT0gSURfTEZFKQogICAgICAgICAgICAmJiAoIChzZWxmLT5mbGFncyAmIEFDX1NCUl9QUkVTRU5UKQogICAgICAgICAgICAgIHx8IChzZWxmLT5zYnJFbmFibGVkID09IDEpICkgKQogICAgICAgICAgewogICAgICAgICAgICBTQlJfRVJST1Igc2JyRXJyb3I7CgogICAgICAgICAgICBzYnJFcnJvciA9IHNickRlY29kZXJfSW5pdEVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+aFNickRlY29kZXIsCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVSYXRlLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uZXh0U2FtcGxpbmdSYXRlLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYW90LAogICAgICAgICAgICAgICAgICAgIElEX0xGRSwKICAgICAgICAgICAgICAgICAgICBwcmV2aW91c19lbGVtZW50X2luZGV4CiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKHNickVycm9yICE9IFNCUkRFQ19PSykgewogICAgICAgICAgICAgIC8qIERvIG5vdCB0cnkgdG8gYXBwbHkgU0JSIGJlY2F1c2UgaW5pdGlhbGl6aW5nIHRoZSBlbGVtZW50IGZhaWxlZC4gKi8KICAgICAgICAgICAgICBzZWxmLT5zYnJFbmFibGVkID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZWxfY250W3R5cGVdKys7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIElEX0NDRToKICAgICAgICAvKgogICAgICAgICAgQ29uc2lzdGVuY3kgY2hlY2sKICAgICAgICAqLwogICAgICAgIGlmICggZWxfY250W3R5cGVdID4gc2VsZi0+YXNjQ2hhbm5lbHMgKSB7CiAgICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfREVDT0RFX0ZSQU1FX0VSUk9SOwogICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmIChzZWxmLT5mcmFtZU9LKQogICAgICAgIHsKICAgICAgICAgIC8qIG1lbW9yeSBmb3Igc3BlY3RyYWwgbGluZXMgdGVtcG9yYWwgb24gc2NyYXRjaCAqLwogICAgICAgICAgQ19BTExPQ19TQ1JBVENIX1NUQVJUKG1kY3RTcGVjLCBGSVhQX0RCTCwgMTAyNCk7CgogICAgICAgICAgLyogY3JlYXRlIGR1bW15IGNoYW5uZWwgZm9yIENDRSBwYXJzaW5nIG9uIHN0YWNrICovCiAgICAgICAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICB0bXBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sICpwVG1wQWFjRGVjb2RlckNoYW5uZWxJbmZvOwoKICAgICAgICAgIEZES21lbWNsZWFyKG1kY3RTcGVjLCAxMDI0KnNpemVvZihGSVhQX0RCTCkpOwoKICAgICAgICAgIHRtcEFhY0RlY29kZXJDaGFubmVsSW5mby5wRHluRGF0YSA9ICAgc2VsZi0+YWFjQ29tbW9uRGF0YS53b3JrQnVmZmVyQ29yZTEtPnBBYWNEZWNvZGVyRHluYW1pY0RhdGE7CiAgICAgICAgICB0bXBBYWNEZWNvZGVyQ2hhbm5lbEluZm8ucENvbURhdGEgPSAgJnNlbGYtPmFhY0NvbW1vbkRhdGE7CiAgICAgICAgICB0bXBBYWNEZWNvZGVyQ2hhbm5lbEluZm8ucFNwZWN0cmFsQ29lZmZpY2llbnQgID0gKFNQRUNUUkFMX1BUUiltZGN0U3BlYzsKICAgICAgICAgIC8qIEFzc3VtZSBBQUMtTEMgKi8KICAgICAgICAgIHRtcEFhY0RlY29kZXJDaGFubmVsSW5mby5ncmFudWxlTGVuZ3RoID0gc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUgLyA4OwoKICAgICAgICAgIC8qIFJlc2V0IFBOUyBkYXRhLiAqLwogICAgICAgICAgQ1Buc19SZXNldERhdGEoJnRtcEFhY0RlY29kZXJDaGFubmVsSW5mby5kYXRhLmFhYy5QbnNEYXRhLCAmdG1wQWFjRGVjb2RlckNoYW5uZWxJbmZvLnBDb21EYXRhLT5wbnNJbnRlckNoYW5uZWxEYXRhKTsKCiAgICAgICAgICBwVG1wQWFjRGVjb2RlckNoYW5uZWxJbmZvID0gJnRtcEFhY0RlY29kZXJDaGFubmVsSW5mbzsKICAgICAgICAgIC8qIGRvIENDRSBwYXJzaW5nICovCiAgICAgICAgICBFcnJvclN0YXR1cyA9IENDaGFubmVsRWxlbWVudF9SZWFkKCBicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBUbXBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzZWxmLT5zYW1wbGluZ1JhdGVJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmVwQ29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+aElucHV0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgQ19BTExPQ19TQ1JBVENIX0VORChtZGN0U3BlYywgRklYUF9EQkwsIDEwMjQpOwoKICAgICAgICAgIGlmIChFcnJvclN0YXR1cykgewogICAgICAgICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgICAgICAgIH0KCiAgICAgICAgICBpZiAoc2VsZi0+ZnJhbWVPSykgewogICAgICAgICAgICAvKiBMb29rdXAgdGhlIGVsZW1lbnQgYW5kIGRlY29kZSBpdCBvbmx5IGlmIGl0IGJlbG9uZ3MgdG8gdGhlIGN1cnJlbnQgcHJvZ3JhbSAqLwogICAgICAgICAgICBpZiAoQ1Byb2dyYW1Db25maWdfTG9va3VwRWxlbWVudCgKICAgICAgICAgICAgICAgICAgICBwY2UsCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5jaGFubmVsQ29uZmlnLAogICAgICAgICAgICAgICAgICAgIHBUbXBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPkVsZW1lbnRJbnN0YW5jZVRhZywKICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPmNoTWFwcGluZywKICAgICAgICAgICAgICAgICAgICBzZWxmLT5jaGFubmVsVHlwZSwKICAgICAgICAgICAgICAgICAgICBzZWxmLT5jaGFubmVsSW5kaWNlcywKICAgICAgICAgICAgICAgICAgICZwcmV2aW91c19lbGVtZW50X2luZGV4LAogICAgICAgICAgICAgICAgICAgIHNlbGYtPmVsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgIHR5cGUpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgIC8qIGRlY29kaW5nIG9mIENDRSBub3Qgc3VwcG9ydGVkICovCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxfY250W3R5cGVdKys7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIElEX0RTRToKICAgICAgICB7CiAgICAgICAgICBVQ0hBUiBlbGVtZW50X2luc3RhbmNlX3RhZzsKCiAgICAgICAgICBDRGF0YVN0cmVhbUVsZW1lbnRfUmVhZCggYnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+YW5jRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5oRHJjSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5oSW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZWxlbWVudF9pbnN0YW5jZV90YWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVTdGFydEFuY2hvciApOwoKICAgICAgICAgIGlmICghQ1Byb2dyYW1Db25maWdfTG9va3VwRWxlbWVudCgKICAgICAgICAgICAgICAgICAgIHBjZSwKICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uY2hhbm5lbENvbmZpZywKICAgICAgICAgICAgICAgICAgIGVsZW1lbnRfaW5zdGFuY2VfdGFnLAogICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgIHNlbGYtPmNoTWFwcGluZywKICAgICAgICAgICAgICAgICAgIHNlbGYtPmNoYW5uZWxUeXBlLAogICAgICAgICAgICAgICAgICAgc2VsZi0+Y2hhbm5lbEluZGljZXMsCiAgICAgICAgICAgICAgICAgICZwcmV2aW91c19lbGVtZW50X2luZGV4LAogICAgICAgICAgICAgICAgICAgc2VsZi0+ZWxlbWVudHMsCiAgICAgICAgICAgICAgICAgICB0eXBlKSApCiAgICAgICAgICB7CiAgICAgICAgICAgIC8qIG1vc3QgbGlrZWx5IGFuIGVycm9yIGluIGJpdHN0cmVhbSBvY2N1cmVkICovCiAgICAgICAgICAgIC8vc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICB7CiAgICAgICAgICBVQ0hBUiAqcER2YkFuY0RhdGEgPSBOVUxMOwogICAgICAgICAgQUFDX0RFQ09ERVJfRVJST1IgYW5jRXJyOwogICAgICAgICAgaW50IGFuY0luZGV4OwogICAgICAgICAgaW50IGR2YkFuY0RhdGFTaXplID0gMDsKCiAgICAgICAgICAvKiBBc2sgaG93IG1hbnkgYW5jIGRhdGEgZWxlbWVudHMgYXJlIGluIGJ1ZmZlciAqLwogICAgICAgICAgYW5jSW5kZXggPSBzZWxmLT5hbmNEYXRhLm5yRWxlbWVudHMgLSAxOwogICAgICAgICAgLyogR2V0IHRoZSBsYXN0IG9uZSAoaWYgYXZhaWxhYmxlKSAqLwogICAgICAgICAgYW5jRXJyICAgPSBDQWFjRGVjb2Rlcl9BbmNEYXRhR2V0KCAmc2VsZi0+YW5jRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY0luZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcER2YkFuY0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkdmJBbmNEYXRhU2l6ZSApOwoKICAgICAgICAgIGlmIChhbmNFcnIgPT0gQUFDX0RFQ19PSykgewogICAgICAgICAgICBwY21EbXhfUmVhZER2YkFuY0RhdGEgKAogICAgICAgICAgICAgICAgICBzZWxmLT5oUGNtVXRpbHMsCiAgICAgICAgICAgICAgICAgIHBEdmJBbmNEYXRhLAogICAgICAgICAgICAgICAgICBkdmJBbmNEYXRhU2l6ZSwKICAgICAgICAgICAgICAgICAgMCAvKiBub3QgbXBlZzIgKi8gKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgojaWZkZWYgVFBfUENFX0VOQUJMRQogICAgICBjYXNlIElEX1BDRToKCiAgICAgICAgaWYgKCBDUHJvZ3JhbUNvbmZpZ0VsZW1lbnRfUmVhZCggYnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmhJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmNoYW5uZWxDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1U3RhcnRBbmNob3IgKSApCiAgICAgICAgeyAvKiBCdWlsdCBlbGVtZW50IHRhYmxlICovCiAgICAgICAgICBpbnQgZWxJZHggPSBDUHJvZ3JhbUNvbmZpZ19HZXRFbGVtZW50VGFibGUocGNlLCBzZWxmLT5lbGVtZW50cywgNyk7CiAgICAgICAgICAvKiBSZXNldCB0aGUgcmVtYWluaW5nIHRhYnMgKi8KICAgICAgICAgIGZvciAoIDsgZWxJZHg8NzsgZWxJZHgrKykgewogICAgICAgICAgICBzZWxmLT5lbGVtZW50c1tlbElkeF0gPSBJRF9OT05FOwogICAgICAgICAgfQogICAgICAgICAgLyogTWFrZSBuZXcgbnVtYmVyIG9mIGNoYW5uZWwgcGVyc2lzdGFudCAqLwogICAgICAgICAgc2VsZi0+YXNjQ2hhbm5lbHMgPSBwY2UtPk51bUNoYW5uZWxzOwogICAgICAgICAgLyogSWYgUENFIGlzIG5vdCBmaXJzdCBlbGVtZW50IGNvbmNlYWwgdGhpcyBmcmFtZSB0byBhdm9pZCBpbmNvbnNpc3RlbmNpZXMgKi8KICAgICAgICAgIGlmICggZWxlbWVudF9jb3VudCAhPSAwICkgewogICAgICAgICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcGNlUmVhZCA9IDE7CiAgICAgICAgYnJlYWs7CiNlbmRpZiAvKiBUUF9QQ0VfRU5BQkxFICovCgogICAgICBjYXNlIElEX0ZJTDoKICAgICAgICB7CiAgICAgICAgICBpbnQgYml0Q250ID0gRkRLcmVhZEJpdHMoYnMsNCk7ICAgICAgICAgICAvKiBic19jb3VudCAqLwoKICAgICAgICAgIGlmIChiaXRDbnQgPT0gMTUpCiAgICAgICAgICB7CiAgICAgICAgICAgIGludCBlc2NfY291bnQgPSBGREtyZWFkQml0cyhicyw4KTsgICAgIC8qIGJzX2VzY19jb3VudCAqLwogICAgICAgICAgICBiaXRDbnQgPSAgZXNjX2NvdW50ICsgMTQ7CiAgICAgICAgICB9CgogICAgICAgICAgLyogQ29udmVydCB0byBiaXRzICovCiAgICAgICAgICBiaXRDbnQgPDw9IDM7CgogICAgICAgICAgd2hpbGUgKGJpdENudCA+IDApIHsKICAgICAgICAgICAgRXJyb3JTdGF0dXMgPSBDQWFjRGVjb2Rlcl9FeHRQYXlsb2FkUGFyc2Uoc2VsZiwgYnMsICZiaXRDbnQsIHByZXZpb3VzX2VsZW1lbnQsIHByZXZpb3VzX2VsZW1lbnRfaW5kZXgsIDEpOwogICAgICAgICAgICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0RFQ19PSykgewogICAgICAgICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBJRF9FWFQ6CiAgICAgICAgewogICAgICAgICAgSU5UIGJpdENudCA9IDA7CgogICAgICAgICAgLyogZ2V0IHRoZSByZW1haW5pbmcgYml0cyBvZiB0aGlzIGZyYW1lICovCiAgICAgICAgICBiaXRDbnQgPSB0cmFuc3BvcnREZWNfR2V0QXVCaXRzUmVtYWluaW5nKHNlbGYtPmhJbnB1dCwgMCk7CgogICAgICAgICAgaWYgKCAoYml0Q250ID4gMCkgJiYgKHNlbGYtPmZsYWdzICYgQUNfU0JSX1BSRVNFTlQpICYmIChzZWxmLT5mbGFncyAmIChBQ19VU0FDfEFDX1JTVkQ1MHxBQ19FTEQpKSApCiAgICAgICAgICB7CiAgICAgICAgICAgIFNCUl9FUlJPUiBlcnIgPSBTQlJERUNfT0s7CiAgICAgICAgICAgIGludCAgZWxJZHgsIG51bUNoRWxlbWVudHMgPSBlbF9jbnRbSURfU0NFXSArIGVsX2NudFtJRF9DUEVdOwoKICAgICAgICAgICAgZm9yIChlbElkeCA9IDA7IGVsSWR4IDwgbnVtQ2hFbGVtZW50czsgZWxJZHggKz0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgIGVyciA9IHNickRlY29kZXJfUGFyc2UgKAogICAgICAgICAgICAgICAgICAgIHNlbGYtPmhTYnJEZWNvZGVyLAogICAgICAgICAgICAgICAgICAgIGJzLAogICAgICAgICAgICAgICAgICAgJmJpdENudCwKICAgICAgICAgICAgICAgICAgICAtMSwKICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncyAmIEFDX1NCUkNSQywKICAgICAgICAgICAgICAgICAgICBzZWxmLT5lbGVtZW50c1tlbElkeF0sCiAgICAgICAgICAgICAgICAgICAgZWxJZHgsCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MgJiBBQ19JTkRFUCApOwoKICAgICAgICAgICAgICBpZiAoZXJyICE9IFNCUkRFQ19PSykgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChlcnIgPT0gU0JSREVDX09LKSB7CiAgICAgICAgICAgICAgc2VsZi0+c2JyRW5hYmxlZCA9IDE7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCgogICAgICAgICAgaWYgKCAhIChzZWxmLT5mbGFncyAmIChBQ19VU0FDfEFDX1JTVkQ1MHxBQ19EUk0pKSApCiAgICAgICAgICB7CiAgICAgICAgICAgIHdoaWxlICggYml0Q250ID4gNyApIHsKICAgICAgICAgICAgICBFcnJvclN0YXR1cyA9IENBYWNEZWNvZGVyX0V4dFBheWxvYWRQYXJzZShzZWxmLCBicywgJmJpdENudCwgcHJldmlvdXNfZWxlbWVudCwgcHJldmlvdXNfZWxlbWVudF9pbmRleCwgMCk7CiAgICAgICAgICAgICAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19ERUNfT0spIHsKICAgICAgICAgICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBJRF9FTkQ6CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgcHJldmlvdXNfZWxlbWVudCA9IHR5cGU7CiAgICBlbGVtZW50X2NvdW50Kys7CgogIH0gICAvKiB3aGlsZSAoICh0eXBlICE9IElEX0VORCkgLi4uICkgKi8KCiAgaWYgKCAhKGZsYWdzICYgKEFBQ0RFQ19DT05DRUFMfEFBQ0RFQ19GTFVTSCkpICkKICB7CiAgICAvKiBCeXRlIGFsaWdubWVudCB3aXRoIHJlc3BlY3QgdG8gdGhlIGZpcnN0IGJpdCBvZiB0aGUgcmF3X2RhdGFfYmxvY2soKS4gKi8KICAgIHsKICAgICAgRkRLYnl0ZUFsaWduKGJzLCBhdVN0YXJ0QW5jaG9yKTsKICAgIH0KCiAgICAvKiBDaGVjayBpZiBhbGwgYml0cyBvZiB0aGUgcmF3X2RhdGFfYmxvY2soKSBoYXZlIGJlZW4gcmVhZC4gKi8KICAgIGlmICggdHJhbnNwb3J0RGVjX0dldEF1Qml0c1RvdGFsKHNlbGYtPmhJbnB1dCwgMCkgPiAwICkgewogICAgICBJTlQgdW5yZWFkQml0cyA9IHRyYW5zcG9ydERlY19HZXRBdUJpdHNSZW1haW5pbmcoc2VsZi0+aElucHV0LCAwKTsKICAgICAgaWYgKCB1bnJlYWRCaXRzICE9IDAgKSB7CgogICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgIC8qIERvIG5vdCBvdmVyd3JpdGUgY3VycmVudCBlcnJvciAqLwogICAgICAgIGlmIChFcnJvclN0YXR1cyA9PSBBQUNfREVDX09LICYmIHNlbGYtPmZyYW1lT0sgPT0gMCkgewogICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgICAgIH0KICAgICAgICAvKiBBbHdheXMgcHV0IHRoZSBiaXRidWZmZXIgYXQgdGhlIHJpZ2h0IHBvc2l0aW9uIGFmdGVyIHRoZSBjdXJyZW50IEFjY2VzcyBVbml0LiAqLwogICAgICAgIEZES3B1c2hCaURpcmVjdGlvbmFsKGJzLCB1bnJlYWRCaXRzKTsKICAgICAgfQogICAgfQoKICAgIC8qIENoZWNrIHRoZSBsYXN0IGVsZW1lbnQuIFRoZSB0ZXJtaW5hdG9yIChJRF9FTkQpIGhhcyB0byBiZSB0aGUgbGFzdCBvbmUgKGV2ZW4gaWYgRVIgc3ludGF4IGlzIHVzZWQpLiAqLwogICAgaWYgKCBzZWxmLT5mcmFtZU9LICYmIHR5cGUgIT0gSURfRU5EICkgewogICAgICAvKiBEbyBub3Qgb3ZlcndyaXRlIGN1cnJlbnQgZXJyb3IgKi8KICAgICAgaWYgKEVycm9yU3RhdHVzID09IEFBQ19ERUNfT0spIHsKICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgIH0KICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICB9CiAgfQoKICAvKiBNb3JlIEFBQyBjaGFubmVscyB0aGFuIHNwZWNpZmllZCBieSB0aGUgQVNDIG5vdCBhbGxvd2VkLiAqLwogIGlmICggKGFhY0NoYW5uZWxzID09IDAgfHwgYWFjQ2hhbm5lbHMgPiBzZWxmLT5hYWNDaGFubmVscykgJiYgIShmbGFncyAmIChBQUNERUNfQ09OQ0VBTHxBQUNERUNfRkxVU0gpKSApIHsKICAgIHsKICAgICAgLyogRG8gbm90IG92ZXJ3cml0ZSBjdXJyZW50IGVycm9yICovCiAgICAgIGlmIChFcnJvclN0YXR1cyA9PSBBQUNfREVDX09LKSB7CiAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKICAgICAgfQogICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgIH0KICAgIGFhY0NoYW5uZWxzID0gMDsKICB9CiAgZWxzZSBpZiAoIGFhY0NoYW5uZWxzID4gc2VsZi0+YXNjQ2hhbm5lbHMgKSB7CiAgICAvKiBEbyBub3Qgb3ZlcndyaXRlIGN1cnJlbnQgZXJyb3IgKi8KICAgIGlmIChFcnJvclN0YXR1cyA9PSBBQUNfREVDX09LKSB7CiAgICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19VTlNVUFBPUlRFRF9GT1JNQVQ7CiAgICB9CiAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgIGFhY0NoYW5uZWxzID0gMDsKICB9CgogIGlmICggVFJBTlNQT1JUREVDX09LICE9IHRyYW5zcG9ydERlY19DcmNDaGVjayhzZWxmLT5oSW5wdXQpICkKICB7CiAgICBzZWxmLT5mcmFtZU9LPTA7CiAgfQoKICAvKiBzdG9yZSBvciByZXN0b3JlIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMgKi8KICBpZiAoIHNlbGYtPmZyYW1lT0sgJiYgIShmbGFncyAmKEFBQ0RFQ19DT05DRUFMfEFBQ0RFQ19GTFVTSCkpICkgewogICAgc2VsZi0+Y29uY2VhbENoYW5uZWxzID0gYWFjQ2hhbm5lbHM7ICAvKiBzdG9yZSAqLwogICAgc2VsZi0+c2JyRW5hYmxlZFByZXYgPSBzZWxmLT5zYnJFbmFibGVkOwogIH0gZWxzZSB7CiAgICBpZiAoc2VsZi0+YWFjQ2hhbm5lbHMgPiAwKSB7CiAgICAgIGFhY0NoYW5uZWxzID0gc2VsZi0+Y29uY2VhbENoYW5uZWxzOyAgLyogcmVzdG9yZSAqLwogICAgICBzZWxmLT5zYnJFbmFibGVkID0gc2VsZi0+c2JyRW5hYmxlZFByZXY7CiAgICAgfQogIH0KCiAgLyogVXBkYXRlIG51bWJlciBvZiBvdXRwdXQgY2hhbm5lbHMgKi8KICBzZWxmLT5zdHJlYW1JbmZvLm51bUNoYW5uZWxzID0gYWFjQ2hhbm5lbHM7CgogI2lmZGVmIFRQX1BDRV9FTkFCTEUKICBpZiAocGNlUmVhZCA9PSAxIHx8IENQcm9ncmFtQ29uZmlnX0lzVmFsaWQocGNlKSkgewogICAgLyogU2V0IG1hdHJpeCBtaXhkb3duIGluZm9zIGlmIGF2YWlsYWJsZSBmcm9tIFBDRS4gKi8KICAgIHBjbURteF9TZXRNYXRyaXhNaXhkb3duRnJvbVBjZSAoIHNlbGYtPmhQY21VdGlscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjZS0+TWF0cml4TWl4ZG93bkluZGV4UHJlc2VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjZS0+TWF0cml4TWl4ZG93bkluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNlLT5Qc2V1ZG9TdXJyb3VuZEVuYWJsZSApOwogIH0KICNlbmRpZgoKICAvKiBJZiB0aGVyZSBpcyBubyB2YWxpZCBkYXRhIHRvIHRyYW5zZnJvbSBpbnRvIHRpbWUgZG9tYWluLCByZXR1cm4uICovCiAgaWYgKCAhIElTX09VVFBVVF9WQUxJRChFcnJvclN0YXR1cykgKSB7CiAgICByZXR1cm4gRXJyb3JTdGF0dXM7CiAgfQoKICAvKgogICAgSW52ZXJzZSB0cmFuc2Zvcm0KICAqLwogIHsKICAgIGludCBzdHJpZGUsIG9mZnNldCwgYzsKCiAgICAvKiBFeHRyYWN0IERSQyBjb250cm9sIGRhdGEgYW5kIG1hcCBpdCB0byBjaGFubmVscyAod2l0aG91dCBiaXRzdHJlYW0gZGVsYXkpICovCiAgICBhYWNEZWNvZGVyX2RyY1Byb2xvZyAoCiAgICAgICAgICAgIHNlbGYtPmhEcmNJbmZvLAogICAgICAgICAgICBicywKICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbywKICAgICAgICAgICAgc2VsZi0+cGNlLkVsZW1lbnRJbnN0YW5jZVRhZywKICAgICAgICAgICAgc2VsZi0+Y2hNYXBwaW5nLAogICAgICAgICAgICBhYWNDaGFubmVscwogICAgICAgICAgKTsKCiAgICAvKiAiYyIgaXRlcmF0ZXMgaW4gY2Fub25pY2FsIE1QRUcgY2hhbm5lbCBvcmRlciAqLwogICAgZm9yIChjPTA7IGMgPCBhYWNDaGFubmVsczsgYysrKQogICAgewogICAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvOwoKICAgICAgLyogU2VsZWN0IGNvcnJlY3QgcEFhY0RlY29kZXJDaGFubmVsSW5mbyBmb3IgY3VycmVudCBjaGFubmVsICovCiAgICAgIGlmIChzZWxmLT5jaE1hcHBpbmdbY10gPj0gYWFjQ2hhbm5lbHMpIHsKICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvID0gc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1tjXTsKICAgICAgfSBlbHNlIHsKICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvID0gc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1tzZWxmLT5jaE1hcHBpbmdbY11dOwogICAgICB9CgogICAgICAvKiBTZXR1cCBvZmZzZXQgYW5kIHN0cmlkZSBmb3IgdGltZSBidWZmZXIgdHJhdmVyc2FsLiAqLwogICAgICBpZiAoaW50ZXJsZWF2ZWQpIHsKICAgICAgICBzdHJpZGUgPSBhYWNDaGFubmVsczsKICAgICAgICBvZmZzZXQgPSBzZWxmLT5jaGFubmVsT3V0cHV0TWFwcGluZ1thYWNDaGFubmVscy0xXVtjXTsKICAgICAgfSBlbHNlIHsKICAgICAgICBzdHJpZGUgPSAxOwogICAgICAgIG9mZnNldCA9IHNlbGYtPmNoYW5uZWxPdXRwdXRNYXBwaW5nW2FhY0NoYW5uZWxzLTFdW2NdICogc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWU7CiAgICAgIH0KCgogICAgICAvKgogICAgICAgIENvbmNlYWwgZGVmZWN0aXZlIHNwZWN0cmFsIGRhdGEKICAgICAgKi8KICAgICAgQ0NvbmNlYWxtZW50X0FwcGx5KCZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NdLT5jb25jZWFsbWVudEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NdLAogICAgICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPnNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAoc2VsZi0+ZnJhbWVPSyAmJiAhKGZsYWdzJkFBQ0RFQ19DT05DRUFMKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MKICAgICAgICAgICAgICAgICAgICAgICAgKTsKCgogICAgICBpZiAoZmxhZ3MgJiAoQUFDREVDX0lOVFJ8QUFDREVDX0NMUkhJU1QpKSB7CiAgICAgICAgLyogUmVzZXQgRFJDIGNvbnRyb2wgZGF0YSBmb3IgdGhpcyBjaGFubmVsICovCiAgICAgICAgYWFjRGVjb2Rlcl9kcmNJbml0Q2hhbm5lbERhdGEgKCAmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjXS0+ZHJjRGF0YSApOwogICAgICB9CiAgICAgIC8qIERSQyBwcm9jZXNzaW5nICovCiAgICAgIGFhY0RlY29kZXJfZHJjQXBwbHkgKAogICAgICAgICAgICAgIHNlbGYtPmhEcmNJbmZvLAogICAgICAgICAgICAgIHNlbGYtPmhTYnJEZWNvZGVyLAogICAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjXS0+ZHJjRGF0YSwKICAgICAgICAgICAgICBjLAogICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgICAgIHNlbGYtPnNickVuYWJsZWQKICAgICAgICAgICAgKTsKCiAgICAgIGlmICggZmxhZ3MmQUFDREVDX0ZMVVNIICkgewogICAgICAgIEZES21lbWNsZWFyKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBTcGVjdHJhbENvZWZmaWNpZW50LCBzaXplb2YoRklYUF9EQkwpKnNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lKTsKICAgICAgfQoKICAgICAgc3dpdGNoIChwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5yZW5kZXJNb2RlKQogICAgICB7CiAgICAgICAgY2FzZSBBQUNERUNfUkVOREVSX0lNRENUOgogICAgICAgICAgQ0Jsb2NrX0ZyZXF1ZW5jeVRvVGltZSgKICAgICAgICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjXSwKICAgICAgICAgICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgcFRpbWVEYXRhICsgb2Zmc2V0LAogICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgc3RyaWRlLAogICAgICAgICAgICAgICAgICAoc2VsZi0+ZnJhbWVPSyAmJiAhKGZsYWdzJkFBQ0RFQ19DT05DRUFMKSksCiAgICAgICAgICAgICAgICAgIHNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUxLT5tZGN0T3V0VGVtcAogICAgICAgICAgICAgICAgICApOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBBQUNERUNfUkVOREVSX0VMREZCOgogICAgICAgICAgQ0Jsb2NrX0ZyZXF1ZW5jeVRvVGltZUxvd0RlbGF5KAogICAgICAgICAgICAgICAgICBzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NdLAogICAgICAgICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICBwVGltZURhdGEgKyBvZmZzZXQsCiAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgICAgICAgICBzdHJpZGUKICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfVU5LTk9XTjsKICAgICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGlmICggZmxhZ3MmQUFDREVDX0ZMVVNIICkgewogICAgICAgIEZES21lbWNsZWFyKHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY10tPnBPdmVybGFwQnVmZmVyLCBPdmVybGFwQnVmZmVyU2l6ZSpzaXplb2YoRklYUF9EQkwpKTsKICAgICAgfQogICAgfQoKCiAgICAvKiBFeHRyYWN0IERSQyBjb250cm9sIGRhdGEgYW5kIG1hcCBpdCB0byBjaGFubmVscyAod2l0aCBiaXRzdHJlYW0gZGVsYXkpICovCiAgICBhYWNEZWNvZGVyX2RyY0VwaWxvZyAoCiAgICAgICAgICAgIHNlbGYtPmhEcmNJbmZvLAogICAgICAgICAgICBicywKICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbywKICAgICAgICAgICAgc2VsZi0+cGNlLkVsZW1lbnRJbnN0YW5jZVRhZywKICAgICAgICAgICAgc2VsZi0+Y2hNYXBwaW5nLAogICAgICAgICAgICBhYWNDaGFubmVscwogICAgICAgICAgKTsKICB9CgoKICAvKiBSZW9yZGVyIGNoYW5uZWwgdHlwZSBpbmZvcm1hdGlvbiB0YWJsZXMuICAqLwogIHsKICAgIEFVRElPX0NIQU5ORUxfVFlQRSB0eXBlc1soNildOwogICAgVUNIQVIgaWR4Wyg2KV07CiAgICBpbnQgYzsKCiAgICBGREtfQVNTRVJUKHNpemVvZihzZWxmLT5jaGFubmVsVHlwZSkgPT0gc2l6ZW9mKHR5cGVzKSk7CiAgICBGREtfQVNTRVJUKHNpemVvZihzZWxmLT5jaGFubmVsSW5kaWNlcykgPT0gc2l6ZW9mKGlkeCkpOwoKICAgIEZES21lbWNweSh0eXBlcywgc2VsZi0+Y2hhbm5lbFR5cGUsIHNpemVvZih0eXBlcykpOwogICAgRkRLbWVtY3B5KGlkeCwgc2VsZi0+Y2hhbm5lbEluZGljZXMsIHNpemVvZihpZHgpKTsKCiAgICBmb3IgKGM9MDsgYzxhYWNDaGFubmVsczsgYysrKSB7CiAgICAgIHNlbGYtPmNoYW5uZWxUeXBlW3NlbGYtPmNoYW5uZWxPdXRwdXRNYXBwaW5nW2FhY0NoYW5uZWxzLTFdW2NdXSA9IHR5cGVzW2NdOwogICAgICBzZWxmLT5jaGFubmVsSW5kaWNlc1tzZWxmLT5jaGFubmVsT3V0cHV0TWFwcGluZ1thYWNDaGFubmVscy0xXVtjXV0gPSBpZHhbY107CiAgICB9CiAgfQoKICBzZWxmLT5ibG9ja051bWJlcisrOwoKICByZXR1cm4gRXJyb3JTdGF0dXM7Cn0KCi8qIQogIFxicmllZiByZXR1cm5zIHRoZSBzdHJlYW1pbmZvIHBvaW50ZXIKCiAgVGhlIGZ1bmN0aW9uIGhhbmRzIGJhY2sgYSBwb2ludGVyIHRvIHRoZSBzdHJlYW1pbmZvIHN0cnVjdHVyZQoKICBccmV0dXJuIHBvaW50ZXIgdG8gdGhlIHN0cnVjdAoqLwpMSU5LU1BFQ19DUFAgQ1N0cmVhbUluZm8qIENBYWNEZWNvZGVyX0dldFN0cmVhbUluZm8gKCBIQU5ETEVfQUFDREVDT0RFUiBzZWxmICkKewogIGlmICghc2VsZikgewogICAgcmV0dXJuIE5VTEw7CiAgfQogIHJldHVybiAmc2VsZi0+c3RyZWFtSW5mbzsKfQoKCgoK