Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBDaHJpc3RpYW4gR3JpZWJlbAogICBEZXNjcmlwdGlvbjogRHluYW1pYyByYW5nZSBjb250cm9sIChEUkMpIGRlY29kZXIgdG9vbCBmb3IgQUFDCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAiYWFjZGVjX2RyYy5oIgoKCiNpbmNsdWRlICJjaGFubmVsaW5mby5oIgojaW5jbHVkZSAiYWFjX3JvbS5oIgoKICNpbmNsdWRlICJzYnJkZWNvZGVyLmgiCgovKgogKiBEeW5hbWljIFJhbmdlIENvbnRyb2wKICovCgovKiBGb3IgcGFyYW1ldGVyIGNvbnZlcnNpb24gKi8KI2RlZmluZSBEUkNfUEFSQU1FVEVSX0JJVFMgICAgICAgICggNyApCiNkZWZpbmUgRFJDX01BWF9RVUFOVF9TVEVQUyAgICAgICAoIDE8PERSQ19QQVJBTUVURVJfQklUUyApCiNkZWZpbmUgRFJDX01BWF9RVUFOVF9GQUNUT1IgICAgICAoIERSQ19NQVhfUVVBTlRfU1RFUFMtMSApCiNkZWZpbmUgRFJDX1BBUkFNX1FVQU5UX1NURVAgICAgICAoIEZMMkZYQ09OU1RfREJMKDEuMGYvKGZsb2F0KURSQ19NQVhfUVVBTlRfRkFDVE9SKSApCiNkZWZpbmUgRFJDX1BBUkFNX1NDQUxFICAgICAgICAgICAoIDEgKQoKI2RlZmluZSBNQVhfUkVGRVJFTkNFX0xFVkVMICAgICAgICggMTI3ICkKCiAjZGVmaW5lIERWQl9BTkNfREFUQV9TWU5DX0JZVEUgICAoIDB4QkMgKSAgICAvKiBEVkIgYW5jaWxsYXJ5IGRhdGEgc3luYyBieXRlLiAqLwoKLyohCiAgXGJyaWVmIEluaXRpYWxpemUgRFJDIGluZm9ybWF0aW9uCgogIFxzZWxmIEhhbmRsZSBvZiBEUkMgaW5mbwoKICBccmV0dXJuIG5vbmUKKi8Kdm9pZCBhYWNEZWNvZGVyX2RyY0luaXQgKAogICAgSEFORExFX0FBQ19EUkMgc2VsZiApCnsKICBDRHJjUGFyYW1zICpwUGFyYW1zOwoKICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICByZXR1cm47CiAgfQoKICAvKiBpbml0IGNvbnRyb2wgZmllbGRzICovCiAgc2VsZi0+ZW5hYmxlID0gMDsKICBzZWxmLT5udW1UaHJlYWRzID0gMDsKICBzZWxmLT5kaWdpdGFsTm9ybSA9IDA7CgogIC8qIGluaXQgcGFyYW1zICovCiAgcFBhcmFtcyA9ICZzZWxmLT5wYXJhbXM7CiAgcFBhcmFtcy0+YnNEZWxheUVuYWJsZSA9IDA7CiAgcFBhcmFtcy0+Y3V0ICAgICAgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICBwUGFyYW1zLT51c3JDdXQgICA9IEZMMkZYQ09OU1RfREJMKDAuMGYpOwogIHBQYXJhbXMtPmJvb3N0ICAgID0gRkwyRlhDT05TVF9EQkwoMC4wZik7CiAgcFBhcmFtcy0+dXNyQm9vc3QgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICBwUGFyYW1zLT50YXJnZXRSZWZMZXZlbCA9IEFBQ0RFQ19EUkNfREVGQVVMVF9SRUZfTEVWRUw7CiAgcFBhcmFtcy0+ZXhwaXJ5RnJhbWUgPSBBQUNERUNfRFJDX0RGTFRfRVhQSVJZX0ZSQU1FUzsKICBwUGFyYW1zLT5hcHBseUhlYXZ5Q29tcHJlc3Npb24gPSAwOwoKICAvKiBpbml0aWFsIHByb2dyYW0gcmVmIGxldmVsID0gdGFyZ2V0IHJlZiBsZXZlbCAqLwogIHNlbGYtPnByb2dSZWZMZXZlbCA9IHBQYXJhbXMtPnRhcmdldFJlZkxldmVsOwp9CgoKLyohCiAgXGJyaWVmIEluaXRpYWxpemUgRFJDIGNvbnRyb2wgZGF0YSBmb3Igb25lIGNoYW5uZWwKCiAgXHNlbGYgSGFuZGxlIG9mIERSQyBpbmZvCgogIFxyZXR1cm4gbm9uZQoqLwp2b2lkIGFhY0RlY29kZXJfZHJjSW5pdENoYW5uZWxEYXRhICgKICAgIENEcmNDaGFubmVsRGF0YSAqcERyY0NoRGF0YSApCnsKICBpZiAocERyY0NoRGF0YSAhPSBOVUxMKSB7CiAgICBwRHJjQ2hEYXRhLT5leHBpcnlDb3VudCA9IDA7CiAgICBwRHJjQ2hEYXRhLT5udW1CYW5kcyAgICA9IDE7CiAgICBwRHJjQ2hEYXRhLT5iYW5kVG9wWzBdICA9ICgxMDI0ID4+IDIpIC0gMTsKICAgIHBEcmNDaERhdGEtPmRyY1ZhbHVlWzBdID0gMDsKICAgIHBEcmNDaERhdGEtPmRyY0ludGVycG9sYXRpb25TY2hlbWUgPSAwOwogICAgcERyY0NoRGF0YS0+ZHJjRGF0YVR5cGUgPSBVTktOT1dOX1BBWUxPQUQ7CiAgfQp9CgoKLyohCiAgXGJyaWVmICBTZXQgb25lIHNpbmdsZSBEUkMgcGFyYW1ldGVyCgogIFxzZWxmICAgSGFuZGxlIG9mIERSQyBpbmZvLgogIFxwYXJhbSAgUGFyYW1ldGVyIHRvIGJlIHNldC4KICBcdmFsdWUgIFZhbHVlIHRvIGJlIHNldC4KCiAgXHJldHVybiBhbiBlcnJvciBjb2RlLgoqLwpBQUNfREVDT0RFUl9FUlJPUiBhYWNEZWNvZGVyX2RyY1NldFBhcmFtICgKICAgIEhBTkRMRV9BQUNfRFJDICAgIHNlbGYsCiAgICBBQUNERUNfRFJDX1BBUkFNICBwYXJhbSwKICAgIElOVCAgICAgICAgICAgICAgIHZhbHVlICkKewogIEFBQ19ERUNPREVSX0VSUk9SIEVycm9yU3RhdHVzID0gQUFDX0RFQ19PSzsKCiAgc3dpdGNoIChwYXJhbSkKICB7CiAgY2FzZSBEUkNfQ1VUX1NDQUxFOgogICAgLyogc2V0IGF0dGVudWF0aW9uIHNjYWxlIGZhY3RvciAqLwogICAgaWYgKCAodmFsdWUgPCAwKQogICAgICB8fCAodmFsdWUgPiBEUkNfTUFYX1FVQU5UX0ZBQ1RPUikgKSB7CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIH0KICAgIHNlbGYtPnBhcmFtcy51c3JDdXQgPSAoRklYUF9EQkwpKChJTlQpKERSQ19QQVJBTV9RVUFOVF9TVEVQPj5EUkNfUEFSQU1fU0NBTEUpICogKElOVCl2YWx1ZSk7CiAgICBpZiAoc2VsZi0+cGFyYW1zLmFwcGx5SGVhdnlDb21wcmVzc2lvbiA9PSAwKQogICAgICBzZWxmLT5wYXJhbXMuY3V0ID0gc2VsZi0+cGFyYW1zLnVzckN1dDsKICAgIGJyZWFrOwogIGNhc2UgRFJDX0JPT1NUX1NDQUxFOgogICAgLyogc2V0IGJvb3N0IGZhY3RvciAqLwogICAgaWYgKCAodmFsdWUgPCAwKQogICAgICB8fCAodmFsdWUgPiBEUkNfTUFYX1FVQU5UX0ZBQ1RPUikgKSB7CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIH0KICAgIHNlbGYtPnBhcmFtcy51c3JCb29zdCA9IChGSVhQX0RCTCkoKElOVCkoRFJDX1BBUkFNX1FVQU5UX1NURVA+PkRSQ19QQVJBTV9TQ0FMRSkgKiAoSU5UKXZhbHVlKTsKICAgIGlmIChzZWxmLT5wYXJhbXMuYXBwbHlIZWF2eUNvbXByZXNzaW9uID09IDApCiAgICAgIHNlbGYtPnBhcmFtcy5ib29zdCA9IHNlbGYtPnBhcmFtcy51c3JCb29zdDsKICAgIGJyZWFrOwogIGNhc2UgVEFSR0VUX1JFRl9MRVZFTDoKICAgIGlmICggdmFsdWUgPiAgTUFYX1JFRkVSRU5DRV9MRVZFTAogICAgICB8fCB2YWx1ZSA8IC1NQVhfUkVGRVJFTkNFX0xFVkVMICkgewogICAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgIH0KICAgIGlmIChzZWxmID09IE5VTEwpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CiAgICB9CiAgICBpZiAodmFsdWUgPCAwKSB7CiAgICAgIHNlbGYtPmRpZ2l0YWxOb3JtID0gMDsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiByZWZfbGV2ZWwgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIE1BWF9SRUZFUkVOQ0VfTEVWRUwsIGluY2x1c2l2ZSAqLwogICAgICBzZWxmLT5kaWdpdGFsTm9ybSAgICA9IDE7CiAgICAgIGlmIChzZWxmLT5wYXJhbXMudGFyZ2V0UmVmTGV2ZWwgIT0gKFNDSEFSKXZhbHVlKSB7CiAgICAgICAgc2VsZi0+cGFyYW1zLnRhcmdldFJlZkxldmVsID0gKFNDSEFSKXZhbHVlOwogICAgICAgIHNlbGYtPnByb2dSZWZMZXZlbCA9IChTQ0hBUil2YWx1ZTsgIC8qIEFsd2F5cyBzZXQgdGhlIHByb2dyYW0gcmVmZXJlbmNlIGxldmVsIGVxdWFsIHRvIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldCBsZXZlbCBhY2NvcmRpbmcgdG8gNC41LjIuNy4zIG9mIElTTy9JRUMgMTQ0OTYtMy4gKi8KICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSBBUFBMWV9IRUFWWV9DT01QUkVTU0lPTjoKICAgIGlmICh2YWx1ZSA8IDAgfHwgdmFsdWUgPiAxKSB7CiAgICAgIHJldHVybiBBQUNfREVDX1NFVF9QQVJBTV9GQUlMOwogICAgfQogICAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKICAgIH0KICAgIGlmIChzZWxmLT5wYXJhbXMuYXBwbHlIZWF2eUNvbXByZXNzaW9uICE9IChVQ0hBUil2YWx1ZSkgewogICAgICBpZiAodmFsdWUgPT0gMSkgewogICAgICAgIC8qIERpc2FibGUgc2NhbGluZyBvZiBEUkMgdmFsdWVzIGJ5IHNldHRpbmcgdGhlIG1heCB2YWx1ZXMgKi8KICAgICAgICBzZWxmLT5wYXJhbXMuYm9vc3QgPSBGTDJGWENPTlNUX0RCTCgxLjBmLyhmbG9hdCkoMTw8RFJDX1BBUkFNX1NDQUxFKSk7CiAgICAgICAgc2VsZi0+cGFyYW1zLmN1dCAgID0gRkwyRlhDT05TVF9EQkwoMS4wZi8oZmxvYXQpKDE8PERSQ19QQVJBTV9TQ0FMRSkpOwogICAgICB9IGVsc2UgewogICAgICAgIC8qIFJlc3RvcmUgdGhlIHVzZXIgcGFyYW1zICovCiAgICAgICAgc2VsZi0+cGFyYW1zLmJvb3N0ID0gc2VsZi0+cGFyYW1zLnVzckJvb3N0OwogICAgICAgIHNlbGYtPnBhcmFtcy5jdXQgICA9IHNlbGYtPnBhcmFtcy51c3JDdXQ7CiAgICAgIH0KICAgICAgLyogU3RvcmUgbmV3IHBhcmFtZXRlciB2YWx1ZSAqLwogICAgICBzZWxmLT5wYXJhbXMuYXBwbHlIZWF2eUNvbXByZXNzaW9uID0gKFVDSEFSKXZhbHVlOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBEUkNfQlNfREVMQVk6CiAgICBpZiAodmFsdWUgPCAwIHx8IHZhbHVlID4gMSkgewogICAgICByZXR1cm4gQUFDX0RFQ19TRVRfUEFSQU1fRkFJTDsKICAgIH0KICAgIGlmIChzZWxmID09IE5VTEwpIHsKICAgICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CiAgICB9CiAgICBzZWxmLT5wYXJhbXMuYnNEZWxheUVuYWJsZSA9IHZhbHVlOwogICAgYnJlYWs7CiAgY2FzZSBEUkNfREFUQV9FWFBJUllfRlJBTUU6CiAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwogICAgfQogICAgc2VsZi0+cGFyYW1zLmV4cGlyeUZyYW1lID0gKFVJTlQpdmFsdWU7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgcmV0dXJuIEFBQ19ERUNfU0VUX1BBUkFNX0ZBSUw7CiAgfSAgLyogc3dpdGNoKHBhcmFtKSAqLwoKICAvKiBzd2l0Y2ggb24vb2ZmIHByb2Nlc3NpbmcgKi8KICBzZWxmLT5lbmFibGUgPSAoIChzZWxmLT5wYXJhbXMuYm9vc3QgPiAoRklYUF9EQkwpMCkKICAgICAgICAgICAgICAgIHx8IChzZWxmLT5wYXJhbXMuY3V0ICAgPiAoRklYUF9EQkwpMCkKICAgICAgICAgICAgICAgIHx8IChzZWxmLT5wYXJhbXMuYXBwbHlIZWF2eUNvbXByZXNzaW9uICE9IDApCiAgICAgICAgICAgICAgICB8fCAoc2VsZi0+ZGlnaXRhbE5vcm0gPT0gMSkgKTsKCgogIHJldHVybiBFcnJvclN0YXR1czsKfQoKCnN0YXRpYyBpbnQgcGFyc2VFeGNsdWRlZENoYW5uZWxzKCBVSU5UICpleGNsdWRlZENobnNNYXNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMgKQp7CiAgVUlOVCBleGNsdWRlTWFzayA9IDA7CiAgVUlOVCBpLCBqOwogIGludCAgYml0Q250ID0gOTsKCiAgZm9yIChpID0gMCwgaiA9IDE7IGkgPCA3OyBpKyssIGo8PD0xKSB7CiAgICBpZiAoRkRLcmVhZEJpdHMoYnMsMSkpIHsKICAgICAgZXhjbHVkZU1hc2sgfD0gajsKICAgIH0KICB9CgogIC8qIGFkZGl0aW9uYWxfZXhjbHVkZWRfY2hucyAqLwogIHdoaWxlIChGREtyZWFkQml0cyhicywxKSkgewogICAgZm9yIChpID0gMDsgaSA8IDc7IGkrKywgajw8PTEpIHsKICAgICAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKSB7CiAgICAgICAgZXhjbHVkZU1hc2sgfD0gajsKICAgICAgfQogICAgfQogICAgYml0Q250ICs9IDk7CiAgICBGREtfQVNTRVJUKGogPCAoVUlOVCktMSk7CiAgfQoKICAqZXhjbHVkZWRDaG5zTWFzayA9IGV4Y2x1ZGVNYXNrOwoKICByZXR1cm4gKGJpdENudCk7Cn0KCgovKiEKICBcYnJpZWYgU2F2ZSBEUkMgcGF5bG9hZCBiaXRzdHJlYW0gcG9zaXRpb24KCiAgXHNlbGYgSGFuZGxlIG9mIERSQyBpbmZvCiAgXGJzIEhhbmRsZSBvZiBGREsgYml0c3RyZWFtCgogIFxyZXR1cm4gVGhlIG51bWJlciBvZiBEUkMgcGF5bG9hZCBiaXRzCiovCmludCBhYWNEZWNvZGVyX2RyY01hcmtQYXlsb2FkICgKICAgIEhBTkRMRV9BQUNfRFJDIHNlbGYsCiAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBicywKICAgIEFBQ0RFQ19EUkNfUEFZTE9BRF9UWVBFIHR5cGUgKQp7CiAgVUlOVCBic1N0YXJ0UG9zOwogIGludCAgaSwgbnVtQmFuZHMgPSAxLCBiaXRDbnQgPSAwOwoKICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICByZXR1cm4gMDsKICB9CgogIGJzU3RhcnRQb3MgPSBGREtnZXRWYWxpZEJpdHMoYnMpOwoKICBzd2l0Y2ggKHR5cGUpIHsKICAgIGNhc2UgTVBFR19EUkNfRVhUX0RBVEE6CiAgICB7CiAgICAgIGJpdENudCA9IDQ7CgogICAgICBpZiAoRkRLcmVhZEJpdHMoYnMsMSkpIHsgICAgICAgICAgLyogcGNlX3RhZ19wcmVzZW50ICovCiAgICAgICAgRkRLcmVhZEJpdHMoYnMsOCk7ICAgICAgICAgICAgICAvKiBwY2VfaW5zdGFuY2VfdGFnICsgZHJjX3RhZ19yZXNlcnZlZF9iaXRzICovCiAgICAgICAgYml0Q250Kz04OwogICAgICB9CgogICAgICBpZiAoRkRLcmVhZEJpdHMoYnMsMSkpIHsgICAgICAgICAgLyogZXhjbHVkZWRfY2huc19wcmVzZW50ICovCiAgICAgICAgRkRLcmVhZEJpdHMoYnMsNyk7ICAgICAgICAgICAgICAvKiBleGNsdWRlIG1hc2sgWzAuLjddICovCiAgICAgICAgYml0Q250Kz04OwogICAgICAgIHdoaWxlIChGREtyZWFkQml0cyhicywxKSkgeyAgICAgLyogYWRkaXRpb25hbF9leGNsdWRlZF9jaG5zICovCiAgICAgICAgICBGREtyZWFkQml0cyhicyw3KTsgICAgICAgICAgICAvKiBleGNsdWRlIG1hc2sgW3guLnldICovCiAgICAgICAgICBiaXRDbnQrPTg7CiAgICAgICAgfQogICAgICB9CgogICAgICBpZiAoRkRLcmVhZEJpdHMoYnMsMSkpIHsgICAgICAgICAgLyogZHJjX2JhbmRzX3ByZXNlbnQgKi8KICAgICAgICBudW1CYW5kcyArPSBGREtyZWFkQml0cyhicywgNCk7IC8qIGRyY19iYW5kX2luY3IgKi8KICAgICAgICBGREtyZWFkQml0cyhicyw0KTsgICAgICAgICAgICAgIC8qIHJlc2VydmVkICovCiAgICAgICAgYml0Q250Kz04OwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CiAgICAgICAgICBGREtyZWFkQml0cyhicyw4KTsgICAgICAgICAgICAvKiBkcmNfYmFuZF90b3BbaV0gKi8KICAgICAgICAgIGJpdENudCs9ODsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmIChGREtyZWFkQml0cyhicywxKSkgeyAgICAgICAgICAvKiBwcm9nX3JlZl9sZXZlbF9wcmVzZW50ICovCiAgICAgICAgRkRLcmVhZEJpdHMoYnMsOCk7ICAgICAgICAgICAgICAvKiBwcm9nX3JlZl9sZXZlbCArIHByb2dfcmVmX2xldmVsX3Jlc2VydmVkX2JpdHMgKi8KICAgICAgICBiaXRDbnQrPTg7CiAgICAgIH0KCiAgICAgIGZvciAoaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKSB7CiAgICAgICAgRkRLcmVhZEJpdHMoYnMsOCk7ICAgICAgICAgICAgICAvKiBkeW5fcm5nX3NnbltpXSArIGR5bl9ybmdfY3RsW2ldICovCiAgICAgICAgYml0Q250Kz04OwogICAgICB9CgogICAgICBpZiAoIChzZWxmLT5udW1QYXlsb2FkcyA8IE1BWF9EUkNfVEhSRUFEUykKICAgICAgICAmJiAoKElOVClGREtnZXRWYWxpZEJpdHMoYnMpID49IDApICkKICAgICAgewogICAgICAgIHNlbGYtPmRyY1BheWxvYWRQb3NpdGlvbltzZWxmLT5udW1QYXlsb2FkcysrXSA9IGJzU3RhcnRQb3M7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwoKICAgIGNhc2UgRFZCX0RSQ19BTkNfREFUQToKICAgICAgYml0Q250ICs9IDg7CiAgICAgIC8qIGNoZWNrIHN5bmMgd29yZCAqLwogICAgICBpZiAoRkRLcmVhZEJpdHMoYnMsIDgpID09IERWQl9BTkNfREFUQV9TWU5DX0JZVEUpCiAgICAgIHsKICAgICAgICBpbnQgZG14TGV2ZWxzUHJlc2VudCwgY29tcHJlc3Npb25QcmVzZW50OwogICAgICAgIGludCBjb2Fyc2VHcmFpblRjUHJlc2VudCwgZmluZUdyYWluVGNQcmVzZW50OwoKICAgICAgICAvKiBic19pbmZvIGZpZWxkICovIAogICAgICAgIEZES3JlYWRCaXRzKGJzLCA4KTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG1wZWdfYXVkaW9fdHlwZSwgZG9sYnlfc3Vycm91bmRfbW9kZSwgcHJlc2VudGF0aW9uX21vZGUgKi8KICAgICAgICBiaXRDbnQrPTg7CgogICAgICAgIC8qIEV2YWx1YXRlIGFuY2lsbGFyeV9kYXRhX3N0YXR1cyAqLwogICAgICAgIEZES3JlYWRCaXRzKGJzLCAzKTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHJlc2VydmVkLCBzZXQgdG8gMCAqLwogICAgICAgIGRteExldmVsc1ByZXNlbnQgPSBGREtyZWFkQml0cyhicywgMSk7ICAgICAgIC8qIGRvd25taXhpbmdfbGV2ZWxzX01QRUc0X3N0YXR1cyAqLwogICAgICAgIEZES3JlYWRCaXRzKGJzLCAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHJlc2VydmVkLCBzZXQgdG8gMCAqLwogICAgICAgIGNvbXByZXNzaW9uUHJlc2VudCAgID0gRkRLcmVhZEJpdHMoYnMsIDEpOyAgIC8qIGF1ZGlvX2NvZGluZ19tb2RlX2FuZF9jb21wcmVzc2lvbiBzdGF0dXMgKi8KICAgICAgICBjb2Fyc2VHcmFpblRjUHJlc2VudCA9IEZES3JlYWRCaXRzKGJzLCAxKTsgICAvKiBjb2Fyc2VfZ3JhaW5fdGltZWNvZGVfc3RhdHVzICovCiAgICAgICAgZmluZUdyYWluVGNQcmVzZW50ICAgPSBGREtyZWFkQml0cyhicywgMSk7ICAgLyogZmluZV9ncmFpbl90aW1lY29kZV9zdGF0dXMgKi8KICAgICAgICBiaXRDbnQrPTg7CgogICAgICAgIC8qIE1QRUc0IGRvd25taXhpbmcgbGV2ZWxzICovCiAgICAgICAgaWYgKGRteExldmVsc1ByZXNlbnQpIHsKICAgICAgICAgIEZES3JlYWRCaXRzKGJzLCA4KTsgICAgICAgICAgICAgICAgICAgICAgICAvKiBkb3dubWl4aW5nX2xldmVsc19NUEVHNCAqLwogICAgICAgICAgYml0Q250Kz04OwogICAgICAgIH0KICAgICAgICAvKiBhdWRpbyBjb2RpbmcgbW9kZSBhbmQgY29tcHJlc3Npb24gc3RhdHVzICovCiAgICAgICAgaWYgKGNvbXByZXNzaW9uUHJlc2VudCkgewogICAgICAgICAgRkRLcmVhZEJpdHMoYnMsIDE2KTsgICAgICAgICAgICAgICAgICAgICAgICAvKiBhdWRpb19jb2RpbmdfbW9kZSwgQ29tcHJlc3Npb25fdmFsdWUgKi8KICAgICAgICAgIGJpdENudCs9MTY7CiAgICAgICAgfQogICAgICAgIC8qIGNvYXJzZSBncmFpbiB0aW1lY29kZSAqLwogICAgICAgIGlmIChjb2Fyc2VHcmFpblRjUHJlc2VudCkgewogICAgICAgICAgRkRLcmVhZEJpdHMoYnMsIDE2KTsgICAgICAgICAgICAgICAgICAgICAgIC8qIGNvYXJzZV9ncmFpbl90aW1lY29kZSAqLwogICAgICAgICAgYml0Q250Kz0xNjsKICAgICAgICB9CiAgICAgICAgLyogZmluZSBncmFpbiB0aW1lY29kZSAqLwogICAgICAgIGlmIChmaW5lR3JhaW5UY1ByZXNlbnQpIHsKICAgICAgICAgIEZES3JlYWRCaXRzKGJzLCAxNik7ICAgICAgICAgICAgICAgICAgICAgICAvKiBmaW5lX2dyYWluX3RpbWVjb2RlICovCiAgICAgICAgICBiaXRDbnQrPTE2OwogICAgICAgIH0KICAgICAgICBpZiAoICFzZWxmLT5kdmJBbmNEYXRhQXZhaWxhYmxlCiAgICAgICAgICAmJiAoKElOVClGREtnZXRWYWxpZEJpdHMoYnMpID49IDApICkKICAgICAgICB7CiAgICAgICAgICBzZWxmLT5kdmJBbmNEYXRhUG9zaXRpb24gID0gYnNTdGFydFBvczsKICAgICAgICAgIHNlbGYtPmR2YkFuY0RhdGFBdmFpbGFibGUgPSAxOwogICAgICAgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICBicmVhazsKICB9CgogIHJldHVybiAoYml0Q250KTsKfQoKCi8qIQogIFxicmllZiBQYXJzZSBEUkMgcGFyYW1ldGVycyBmcm9tIGJpdHN0cmVhbQoKICBcYnMgSGFuZGxlIG9mIEZESyBiaXRzdHJlYW0gKGluKQogIFxwRHJjQnMgUG9pbnRlciB0byBEUkMgcGF5bG9hZCBkYXRhIGNvbnRhaW5lciAob3V0KQogIFxwYXlsb2FkUG9zaXRpb24gQml0c3RyZWFtIHBvc2l0aW9uIG9mIE1QRUcgRFJDIGRhdGEganVuayAoaW4pCgogIFxyZXR1cm4gTnVtYmVyIG9mIGJpdHMgcmVhZCAoMCBpbiBjYXNlIG9mIGEgcGFyc2UgZXJyb3IpCiovCnN0YXRpYyBpbnQgYWFjRGVjb2Rlcl9kcmNQYXJzZSAoCiAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgYnMsCiAgICBDRHJjUGF5bG9hZCAgICAgICAgICAqcERyY0JzLAogICAgVUlOVCAgICAgICAgICAgICAgICAgIHBheWxvYWRQb3NpdGlvbiApCnsKICBpbnQgaSwgbnVtQmFuZHMsIGJpdENudCA9IDQ7CgogIC8qIE1vdmUgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgRFJDIHBheWxvYWQgZmllbGQgKi8KICBGREtwdXNoQmlEaXJlY3Rpb25hbChicywgRkRLZ2V0VmFsaWRCaXRzKGJzKS1wYXlsb2FkUG9zaXRpb24pOwoKICAvKiBwY2VfdGFnX3ByZXNlbnQgKi8KICBpZiAoRkRLcmVhZEJpdHMoYnMsMSkpCiAgewogICAgcERyY0JzLT5wY2VJbnN0YW5jZVRhZyA9IEZES3JlYWRCaXRzKGJzLCA0KTsgIC8qIHBjZV9pbnN0YW5jZV90YWcgKi8KICAgIC8qIG9ubHkgb25lIHByb2dyYW0gc3VwcG9ydGVkICovCiAgICBGREtyZWFkQml0cyhicywgNCk7ICAvKiBkcmNfdGFnX3Jlc2VydmVkX2JpdHMgKi8KICAgIGJpdENudCArPSA4OwogIH0gZWxzZSB7CiAgICBwRHJjQnMtPnBjZUluc3RhbmNlVGFnID0gLTE7ICAvKiBub3QgcHJlc2VudCAqLwogIH0KCiAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKSB7ICAgICAgICAvKiBleGNsdWRlZF9jaG5zX3ByZXNlbnQgKi8KICAgIC8qIGdldCBleGNsdWRlZF9jaG5fbWFzayAqLwogICAgYml0Q250ICs9IHBhcnNlRXhjbHVkZWRDaGFubmVscygmcERyY0JzLT5leGNsdWRlZENobnNNYXNrLCBicyk7CiAgfSBlbHNlIHsKICAgIHBEcmNCcy0+ZXhjbHVkZWRDaG5zTWFzayA9IDA7CiAgfQoKICBudW1CYW5kcyA9IDE7CiAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKSAgLyogZHJjX2JhbmRzX3ByZXNlbnQgKi8KICB7CiAgICAvKiBnZXQgYmFuZF9pbmNyICovCiAgICBudW1CYW5kcyArPSBGREtyZWFkQml0cyhicywgNCk7ICAvKiBkcmNfYmFuZF9pbmNyICovCiAgICBwRHJjQnMtPmNoYW5uZWxEYXRhLmRyY0ludGVycG9sYXRpb25TY2hlbWUgPSBGREtyZWFkQml0cyhicywgNCk7ICAvKiBkcmNfaW50ZXJwb2xhdGlvbl9zY2hlbWUgKi8KICAgIGJpdENudCArPSA4OwogICAgLyogYmFuZF90b3AgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBudW1CYW5kczsgaSsrKQogICAgewogICAgICBwRHJjQnMtPmNoYW5uZWxEYXRhLmJhbmRUb3BbaV0gPSBGREtyZWFkQml0cyhicywgOCk7ICAvKiBkcmNfYmFuZF90b3BbaV0gKi8KICAgICAgYml0Q250ICs9IDg7CiAgICB9CiAgfQogIGVsc2UgewogICAgcERyY0JzLT5jaGFubmVsRGF0YS5iYW5kVG9wWzBdID0gKDEwMjQgPj4gMikgLSAxOyAgLyogLi4uIGNvbXByaXNpbmcgdGhlIHdob2xlIHNwZWN0cnVtLiAqLzsKICB9CgogIHBEcmNCcy0+Y2hhbm5lbERhdGEubnVtQmFuZHMgPSBudW1CYW5kczsKCiAgaWYgKEZES3JlYWRCaXRzKGJzLDEpKSAgICAgICAgICAgICAgICAgICAgICAgIC8qIHByb2dfcmVmX2xldmVsX3ByZXNlbnQgKi8KICB7CiAgICBwRHJjQnMtPnByb2dSZWZMZXZlbCA9IEZES3JlYWRCaXRzKGJzLCA3KTsgIC8qIHByb2dfcmVmX2xldmVsICovCiAgICBGREtyZWFkQml0cyhicywgMSk7ICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHByb2dfcmVmX2xldmVsX3Jlc2VydmVkX2JpdHMgKi8KICAgIGJpdENudCArPSA4OwogIH0gZWxzZSB7CiAgICBwRHJjQnMtPnByb2dSZWZMZXZlbCA9IC0xOwogIH0KCiAgZm9yIChpID0gMDsgaSA8IG51bUJhbmRzOyBpKyspCiAgewogICAgcERyY0JzLT5jaGFubmVsRGF0YS5kcmNWYWx1ZVtpXSAgPSBGREtyZWFkQml0cyhicywgMSkgPDwgNzsgICAvKiBkeW5fcm5nX3NnbltpXSAqLwogICAgcERyY0JzLT5jaGFubmVsRGF0YS5kcmNWYWx1ZVtpXSB8PSBGREtyZWFkQml0cyhicywgNykgJiAweDdGOyAvKiBkeW5fcm5nX2N0bFtpXSAqLwogICAgYml0Q250ICs9IDg7CiAgfQoKICAvKiBTZXQgRFJDIHBheWxvYWQgdHlwZSAqLwogIHBEcmNCcy0+Y2hhbm5lbERhdGEuZHJjRGF0YVR5cGUgPSBNUEVHX0RSQ19FWFRfREFUQTsKCiAgcmV0dXJuIChiaXRDbnQpOwp9CgoKLyohCiAgXGJyaWVmIFBhcnNlIGhlYXZ5IGNvbXByZXNzaW9uIHZhbHVlIHRyYW5zcG9ydGVkIGluIERTRXMgb2YgRFZCIHN0cmVhbXMgd2l0aCBNUEVHLTQgY29udGVudC4KCiAgXGJzIEhhbmRsZSBvZiBGREsgYml0c3RyZWFtIChpbikKICBccERyY0JzIFBvaW50ZXIgdG8gRFJDIHBheWxvYWQgZGF0YSBjb250YWluZXIgKG91dCkKICBccGF5bG9hZFBvc2l0aW9uIEJpdHN0cmVhbSBwb3NpdGlvbiBvZiBEVkIgYW5jaWxsYXJ5IGRhdGEganVuawoKICBccmV0dXJuIE51bWJlciBvZiBiaXRzIHJlYWQgKDAgaW4gY2FzZSBvZiBhIHBhcnNlIGVycm9yKQoqLwojZGVmaW5lIERWQl9DT01QUkVTU0lPTl9TQ0FMRSAgICggOCApICAgICAgIC8qIDQ4LDE2NCBkQiAqLwoKc3RhdGljIGludCBhYWNEZWNvZGVyX2RyY1JlYWRDb21wcmVzc2lvbiAoCiAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgYnMsCiAgICBDRHJjUGF5bG9hZCAgICAgICAgICAqcERyY0JzLAogICAgVUlOVCAgICAgICAgICAgICAgICAgIHBheWxvYWRQb3NpdGlvbiApCnsKICBpbnQgIGJpdENudCA9IDA7CiAgaW50ICBkbXhMZXZlbHNQcmVzZW50LCBjb21wcmVzc2lvblByZXNlbnQ7CiAgaW50ICBjb2Fyc2VHcmFpblRjUHJlc2VudCwgZmluZUdyYWluVGNQcmVzZW50OwoKICAvKiBNb3ZlIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIERSQyBwYXlsb2FkIGZpZWxkICovCiAgRkRLcHVzaEJpRGlyZWN0aW9uYWwoYnMsIEZES2dldFZhbGlkQml0cyhicyktcGF5bG9hZFBvc2l0aW9uKTsKCiAgLyogU2FuaXR5IGNoZWNrcyAqLwogIGlmICggRkRLZ2V0VmFsaWRCaXRzKGJzKSA8IDI0ICkgewogICAgcmV0dXJuIDA7CiAgfQoKICAvKiBDaGVjayBzeW5jIHdvcmQgKi8KICBpZiAoRkRLcmVhZEJpdHMoYnMsIDgpICE9IERWQl9BTkNfREFUQV9TWU5DX0JZVEUpIHsKICAgIHJldHVybiAwOwogIH0KCiAgLyogRXZhbHVhdGUgYnNfaW5mbyBmaWVsZCAqLyAKICBpZiAoRkRLcmVhZEJpdHMoYnMsIDIpICE9IDMpIHsgICAgICAgICAgICAgICAvKiBtcGVnX2F1ZGlvX3R5cGUgKi8KICAgIC8qIE5vIE1QRUctNCBhdWRpbyBkYXRhICovCiAgICByZXR1cm4gMDsKICB9CiAgRkRLcmVhZEJpdHMoYnMsIDIpOyAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZG9sYnlfc3Vycm91bmRfbW9kZSAqLwogIEZES3JlYWRCaXRzKGJzLCAyKTsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHByZXNlbnRhdGlvbl9tb2RlICovCiAgaWYgKEZES3JlYWRCaXRzKGJzLCAyKSAhPSAwKSB7ICAgICAgICAgICAgICAgLyogcmVzZXJ2ZWQsIHNldCB0byAwICovCiAgICByZXR1cm4gMDsKICB9CgogIC8qIEV2YWx1YXRlIGFuY2lsbGFyeV9kYXRhX3N0YXR1cyAqLwogIGlmIChGREtyZWFkQml0cyhicywgMykgIT0gMCkgeyAgICAgICAgICAgICAgIC8qIHJlc2VydmVkLCBzZXQgdG8gMCAqLwogICAgcmV0dXJuIDA7CiAgfQogIGRteExldmVsc1ByZXNlbnQgPSBGREtyZWFkQml0cyhicywgMSk7ICAgICAgIC8qIGRvd25taXhpbmdfbGV2ZWxzX01QRUc0X3N0YXR1cyAqLwogIGlmIChGREtyZWFkQml0cyhicywgMSkgIT0gMCkgeyAgICAgICAgICAgICAgIC8qIHJlc2VydmVkLCBzZXQgdG8gMCAqLwogICAgcmV0dXJuIDA7CiAgfQogIGNvbXByZXNzaW9uUHJlc2VudCAgID0gRkRLcmVhZEJpdHMoYnMsIDEpOyAgIC8qIGF1ZGlvX2NvZGluZ19tb2RlX2FuZF9jb21wcmVzc2lvbiBzdGF0dXMgKi8KICBjb2Fyc2VHcmFpblRjUHJlc2VudCA9IEZES3JlYWRCaXRzKGJzLCAxKTsgICAvKiBjb2Fyc2VfZ3JhaW5fdGltZWNvZGVfc3RhdHVzICovCiAgZmluZUdyYWluVGNQcmVzZW50ICAgPSBGREtyZWFkQml0cyhicywgMSk7ICAgLyogZmluZV9ncmFpbl90aW1lY29kZV9zdGF0dXMgKi8KICBiaXRDbnQgKz0gMjQ7CgogIGlmIChkbXhMZXZlbHNQcmVzZW50KSB7CiAgICBGREtyZWFkQml0cyhicywgOCk7ICAgICAgICAgICAgICAgICAgICAgICAgLyogZG93bm1peGluZ19sZXZlbHNfTVBFRzQgKi8KICAgIGJpdENudCArPSA4OwogIH0KCiAgLyogYXVkaW9fY29kaW5nX21vZGVfYW5kX2NvbXByZXNzaW9uX3N0YXR1cyAqLwogIGlmIChjb21wcmVzc2lvblByZXNlbnQpCiAgewogICAgVUNIQVIgY29tcHJlc3Npb25PbiwgY29tcHJlc3Npb25WYWx1ZTsKCiAgICAvKiBhdWRpb19jb2RpbmdfbW9kZSAqLwogICAgaWYgKCBGREtyZWFkQml0cyhicywgNykgIT0gMCApIHsgIC8qIFRoZSByZXNlcnZlZCBiaXRzIHNoYWxsIGJlIHNldCB0byAiMCIuICovCiAgICAgIHJldHVybiAwOwogICAgfQogICAgY29tcHJlc3Npb25PbiAgICA9IChVQ0hBUilGREtyZWFkQml0cyhicywgMSk7ICAvKiBjb21wcmVzc2lvbl9vbiAqLwogICAgY29tcHJlc3Npb25WYWx1ZSA9IChVQ0hBUilGREtyZWFkQml0cyhicywgOCk7ICAvKiBDb21wcmVzc2lvbl92YWx1ZSAqLwogICAgYml0Q250ICs9IDE2OwoKICAgIGlmICggY29tcHJlc3Npb25PbiApIHsKICAgICAgLyogQSBjb21wcmVzc2lvbiB2YWx1ZSBpcyBhdmFpbGFibGUgc28gc3RvcmUgdGhlIGRhdGEganVzdCBsaWtlIE1QRUcgRFJDIGRhdGEgKi8KICAgICAgcERyY0JzLT5jaGFubmVsRGF0YS5udW1CYW5kcyAgICA9ICAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBPbmUgYmFuZCAuLi4gKi8KICAgICAgcERyY0JzLT5jaGFubmVsRGF0YS5kcmNWYWx1ZVswXSA9ICBjb21wcmVzc2lvblZhbHVlOyAgICAgICAgICAgICAvKiAuLi4gd2l0aCBvbmUgdmFsdWUgLi4uICovCiAgICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEuYmFuZFRvcFswXSAgPSAoMTAyNCA+PiAyKSAtIDE7ICAvKiAuLi4gY29tcHJpc2luZyB0aGUgd2hvbGUgc3BlY3RydW0uICovCiAgICAgIHBEcmNCcy0+cGNlSW5zdGFuY2VUYWcgICAgICAgICAgPSAtMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTm90IHByZXNlbnQgKi8KICAgICAgcERyY0JzLT5wcm9nUmVmTGV2ZWwgICAgICAgICAgICA9IC0xOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBOb3QgcHJlc2VudCAqLwogICAgICBwRHJjQnMtPmNoYW5uZWxEYXRhLmRyY0RhdGFUeXBlID0gIERWQl9EUkNfQU5DX0RBVEE7ICAgICAgICAgICAgIC8qIFNldCBEUkMgcGF5bG9hZCB0eXBlIHRvIERWQi4gKi8KICAgIH0gZWxzZSB7CiAgICAgIC8qIE5vIGNvbXByZXNzaW9uIHZhbHVlIGF2YWlsYWJsZSAqLwogICAgICAvKiBDQVVUSU9OOiBJdCBpcyBub3QgY2xlYXJseSBkZWZpbmVkIGJ5IHN0YW5kYXJkIGhvdyB0byByZWFjdCBpbiB0aGlzIHNpdHVhdGlvbi4gKi8KICAgICAgLyogVHVybiBkb3duIHRoZSBjb21wcmVzc2lvbiB2YWx1ZSB0byBhcHJveC4gMGRCICovCiAgICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEubnVtQmFuZHMgICAgPSAgMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogT25lIGJhbmQgLi4uICovCiAgICAgIHBEcmNCcy0+Y2hhbm5lbERhdGEuZHJjVmFsdWVbMF0gPSAgMHg4MDsgICAgICAgICAgICAgICAgICAgICAgICAgLyogLi4uIHdpdGggYXByb3guIDBkQiAuLi4gKi8KICAgICAgcERyY0JzLT5jaGFubmVsRGF0YS5iYW5kVG9wWzBdICA9ICgxMDI0ID4+IDIpIC0gMTsgIC8qIC4uLiBjb21wcmlzaW5nIHRoZSB3aG9sZSBzcGVjdHJ1bS4gKi8KICAgICAgcERyY0JzLT5jaGFubmVsRGF0YS5kcmNEYXRhVHlwZSA9ICBEVkJfRFJDX0FOQ19EQVRBOyAgICAgICAgICAgICAvKiBTZXQgRFJDIHBheWxvYWQgdHlwZSB0byBEVkIuICovCgogICAgICAvKiBJZiBjb21wcmVzc2lvbl9vbiBmaWVsZCBpcyBzZXQgdG8gIjAiIHRoZSBjb21wcmVzc2lvbl92YWx1ZSBmaWVsZCBzaGFsbCBiZSAiMDAwMCAwMDAwIi4gKi8KICAgICAgaWYgKGNvbXByZXNzaW9uVmFsdWUgIT0gMCkgewogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICB9CiAgfQoKICAvKiBSZWFkIHRpbWVjb2RlcyBpZiBhdmFpbGFibGUganVzdCB0byBnZXQgdGhlIHJpZ2h0IGFtb3VudCBvZiBiaXRzLiAqLwogIGlmIChjb2Fyc2VHcmFpblRjUHJlc2VudCkgewogICAgRkRLcmVhZEJpdHMoYnMsIDE2KTsgICAgICAvKiBjb2Fyc2VfZ3JhaW5fdGltZWNvZGUgKi8KICAgIGJpdENudCArPSAxNjsKICB9CiAgaWYgKGZpbmVHcmFpblRjUHJlc2VudCkgewogICAgRkRLcmVhZEJpdHMoYnMsIDE2KTsgICAgICAvKiBmaW5lX2dyYWluX3RpbWVjb2RlICovCiAgICBiaXRDbnQgKz0gMTY7CiAgfQoKICByZXR1cm4gKGJpdENudCk7Cn0KCgovKiAKICogUHJlcGFyZSBEUkMgcHJvY2Vzc2luZwogKi8Kc3RhdGljIGludCBhYWNEZWNvZGVyX2RyY0V4dHJhY3RBbmRNYXAgKAogICAgICAgIEhBTkRMRV9BQUNfRFJDICBzZWxmLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywKICAgICAgICBDQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvICpwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW10sCiAgICAgICAgVUNIQVIgIHBjZUluc3RhbmNlVGFnLAogICAgICAgIFVDSEFSICBjaGFubmVsTWFwcGluZ1tdLCAvKiBDaGFubmVsIG1hcHBpbmcgdHJhbnNsYXRpbmcgZHJjQ2hhbm5lbCBpbmRleCB0byBjYW5vbmljYWwgY2hhbm5lbCBpbmRleCAqLwogICAgICAgIGludCAgICB2YWxpZENoYW5uZWxzICkKewogIENEcmNQYXlsb2FkICB0aHJlYWRCc1tNQVhfRFJDX1RIUkVBRFNdOwogIENEcmNQYXlsb2FkICp2YWxpZFRocmVhZEJzW01BWF9EUkNfVEhSRUFEU107CiAgQ0RyY1BhcmFtcyAgKnBQYXJhbXM7CiAgVUlOVCBiYWNrdXBCc1Bvc2l0aW9uOwogIGludCAgaSwgdGhyZWFkLCB2YWxpZFRocmVhZHMgPSAwOwogIGludCAgbnVtRXhjbHVkZWRDaG5zW01BWF9EUkNfVEhSRUFEU107CgogIEZES19BU1NFUlQoc2VsZiAhPSBOVUxMKTsKICBGREtfQVNTRVJUKGhCcyAhPSBOVUxMKTsKICBGREtfQVNTRVJUKHBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8gIT0gTlVMTCk7CgogIHBQYXJhbXMgPSAmc2VsZi0+cGFyYW1zOwoKICBzZWxmLT5udW1UaHJlYWRzID0gMDsKICBiYWNrdXBCc1Bvc2l0aW9uID0gRkRLZ2V0VmFsaWRCaXRzKGhCcyk7CgogIGZvciAoaSA9IDA7IGkgPCBzZWxmLT5udW1QYXlsb2FkcyAmJiBzZWxmLT5udW1UaHJlYWRzIDwgTUFYX0RSQ19USFJFQURTOyBpKyspIHsKICAgIGludCBiaXRzUGFyc2VkOwoKICAgIC8qIEluaXQgcGF5bG9hZCBkYXRhIGNodW5rLiBUaGUgbWVtY2xlYXIgaXMgdmVyeSBpbXBvcnRhbnQgYmVjYXVzZSBpdCBpbml0aWFsaXplcwogICAgICAgdGhlIG1vc3QgdmFsdWVzLiBXaXRob3V0IGl0IHRoZSBtb2R1bGUgd291bGRuJ3Qgd29yayBwcm9wZXJseSBvciBjcmFzaC4gKi8KICAgIEZES21lbWNsZWFyKCZ0aHJlYWRCc1tzZWxmLT5udW1UaHJlYWRzXSwgc2l6ZW9mKENEcmNQYXlsb2FkKSk7CiAgICB0aHJlYWRCc1tzZWxmLT5udW1UaHJlYWRzXS5jaGFubmVsRGF0YS5iYW5kVG9wWzBdICA9ICgxMDI0ID4+IDIpIC0gMTsKCiAgICAvKiBFeHRyYWN0IHBheWxvYWQgKi8KICAgIGJpdHNQYXJzZWQgPSBhYWNEZWNvZGVyX2RyY1BhcnNlKCBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdGhyZWFkQnNbc2VsZi0+bnVtVGhyZWFkc10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZHJjUGF5bG9hZFBvc2l0aW9uW2ldICk7CiAgICBpZiAoYml0c1BhcnNlZCA+IDApIHsKICAgICAgc2VsZi0+bnVtVGhyZWFkcysrOwogICAgfQogIH0KICBzZWxmLT5udW1QYXlsb2FkcyA9IDA7CgogIGlmIChzZWxmLT5kdmJBbmNEYXRhQXZhaWxhYmxlKQogIHsgLyogQXBwZW5kIGEgRFZCIGhlYXZ5IGNvbXByZXNzaW9uIHBheWxvYWQgdGhyZWFkIGlmIGF2YWlsYWJsZS4gKi8KICAgIGludCBiaXRzUGFyc2VkOwoKICAgIC8qIEluaXQgcGF5bG9hZCBkYXRhIGNodW5rLiBUaGUgbWVtY2xlYXIgaXMgdmVyeSBpbXBvcnRhbnQgYmVjYXVzZSBpdCBpbml0aWFsaXplcwogICAgICAgdGhlIG1vc3QgdmFsdWVzLiBXaXRob3V0IGl0IHRoZSBtb2R1bGUgd291bGRuJ3Qgd29yayBwcm9wZXJseSBvciBjcmFzaC4gKi8KICAgIEZES21lbWNsZWFyKCZ0aHJlYWRCc1tzZWxmLT5udW1UaHJlYWRzXSwgc2l6ZW9mKENEcmNQYXlsb2FkKSk7CiAgICB0aHJlYWRCc1tzZWxmLT5udW1UaHJlYWRzXS5jaGFubmVsRGF0YS5iYW5kVG9wWzBdICA9ICgxMDI0ID4+IDIpIC0gMTsKCiAgICAvKiBFeHRyYWN0IHBheWxvYWQgKi8KICAgIGJpdHNQYXJzZWQgPSBhYWNEZWNvZGVyX2RyY1JlYWRDb21wcmVzc2lvbiggaEJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0aHJlYWRCc1tzZWxmLT5udW1UaHJlYWRzXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZHZiQW5jRGF0YVBvc2l0aW9uICk7CiAgICBpZiAoYml0c1BhcnNlZCA+IDApIHsKICAgICAgc2VsZi0+bnVtVGhyZWFkcysrOwogICAgfQogIH0KICBzZWxmLT5kdmJBbmNEYXRhQXZhaWxhYmxlID0gMDsKCiAgLyogUmVzZXQgdGhlIGJpdGJ1ZmZmZXIgKi8KICBGREtwdXNoQmlEaXJlY3Rpb25hbChoQnMsIEZES2dldFZhbGlkQml0cyhoQnMpIC0gYmFja3VwQnNQb3NpdGlvbik7CgogIC8qIGNhbGN1bGF0ZSBudW1iZXIgb2YgdmFsaWQgYml0cyBpbiBleGNsX2Nobl9tYXNrICovCgogIC8qIGNvdXBsaW5nIGNoYW5uZWxzIG5vdCBzdXBwb3J0ZWQgKi8KCiAgLyogY2hlY2sgZm9yIHZhbGlkIHRocmVhZHMgKi8KICBmb3IgKHRocmVhZCA9IDA7IHRocmVhZCA8IHNlbGYtPm51bVRocmVhZHM7IHRocmVhZCsrKSB7CiAgICBDRHJjUGF5bG9hZCAqcFRocmVhZEJzID0gJnRocmVhZEJzW3RocmVhZF07CiAgICBpbnQgbnVtRXhjbENobnMgPSAwOwoKICAgIHN3aXRjaCAoKEFBQ0RFQ19EUkNfUEFZTE9BRF9UWVBFKXBUaHJlYWRCcy0+Y2hhbm5lbERhdGEuZHJjRGF0YVR5cGUpIHsKICAgICAgZGVmYXVsdDoKICAgICAgICBjb250aW51ZTsKICAgICAgY2FzZSBNUEVHX0RSQ19FWFRfREFUQToKICAgICAgY2FzZSBEVkJfRFJDX0FOQ19EQVRBOgogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChwVGhyZWFkQnMtPnBjZUluc3RhbmNlVGFnID49IDApIHsgIC8qIGlmIFBDRSB0YWcgcHJlc2VudCAqLwogICAgICBpZiAocFRocmVhZEJzLT5wY2VJbnN0YW5jZVRhZyAhPSBwY2VJbnN0YW5jZVRhZykgewogICAgICAgIGNvbnRpbnVlOyAgLyogZG9uJ3QgYWNjZXB0ICovCiAgICAgIH0KICAgIH0KCiAgICAvKiBjYWxjdWxhdGUgbnVtYmVyIG9mIGV4Y2x1ZGVkIGNoYW5uZWxzICovCiAgICBpZiAocFRocmVhZEJzLT5leGNsdWRlZENobnNNYXNrID4gMCkgewogICAgICBJTlQgZXhjbE1hc2sgPSBwVGhyZWFkQnMtPmV4Y2x1ZGVkQ2huc01hc2s7CiAgICAgIGludCBjaDsKICAgICAgZm9yIChjaCA9IDA7IGNoIDwgdmFsaWRDaGFubmVsczsgY2grKykgewogICAgICAgIG51bUV4Y2xDaG5zICs9IGV4Y2xNYXNrICYgMHgxOwogICAgICAgIGV4Y2xNYXNrID4+PSAxOwogICAgICB9CiAgICB9CiAgICBpZiAobnVtRXhjbENobnMgPCB2YWxpZENoYW5uZWxzKSB7CiAgICAgIHZhbGlkVGhyZWFkQnNbdmFsaWRUaHJlYWRzXSAgID0gcFRocmVhZEJzOwogICAgICBudW1FeGNsdWRlZENobnNbdmFsaWRUaHJlYWRzXSA9IG51bUV4Y2xDaG5zOwogICAgICB2YWxpZFRocmVhZHMrKzsKICAgIH0KICB9CgogIGlmICh2YWxpZFRocmVhZHMgPiAxKSB7CiAgICBpbnQgY2g7CgogICAgLyogY2hlY2sgY29uc2lzdGVuY3kgb2YgZXhjbF9jaG5fbWFzayBhbW9uZ3N0IHZhbGlkIERSQyB0aHJlYWRzICovCiAgICBmb3IgKGNoID0gMDsgY2ggPCB2YWxpZENoYW5uZWxzOyBjaCsrKSB7CiAgICAgIGludCBwcmVzZW50ID0gMDsKCiAgICAgIGZvciAodGhyZWFkID0gMDsgdGhyZWFkIDwgdmFsaWRUaHJlYWRzOyB0aHJlYWQrKykgewogICAgICAgIENEcmNQYXlsb2FkICpwVGhyZWFkQnMgPSB2YWxpZFRocmVhZEJzW3RocmVhZF07CgoKICAgICAgICAvKiB0aHJlYWQgYXBwbGllcyB0byB0aGlzIGNoYW5uZWwgKi8KICAgICAgICBpZiAoIChwVGhyZWFkQnMtPmNoYW5uZWxEYXRhLmRyY0RhdGFUeXBlID09IE1QRUdfRFJDX0VYVF9EQVRBKQogICAgICAgICAgJiYgKCAobnVtRXhjbHVkZWRDaG5zW3RocmVhZF0gPT0gMCkKICAgICAgICAgICAgfHwgKCEocFRocmVhZEJzLT5leGNsdWRlZENobnNNYXNrICYgKDE8PGNoKSkpICkgKSB7CiAgICAgICAgICBwcmVzZW50Kys7CiAgICAgICAgfQogICAgICB9CgoKICAgICAgaWYgKHByZXNlbnQgPiAxKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgICB9CiAgICB9CiAgfQoKICAvKiBtYXAgRFJDIGJpdHN0cmVhbSBpbmZvcm1hdGlvbiBvbnRvIERSQyBjaGFubmVsIGluZm9ybWF0aW9uICovCiAgZm9yICh0aHJlYWQgPSAwOyB0aHJlYWQgPCB2YWxpZFRocmVhZHM7IHRocmVhZCsrKQogIHsKICAgIENEcmNQYXlsb2FkICpwVGhyZWFkQnMgPSB2YWxpZFRocmVhZEJzW3RocmVhZF07CiAgICBJTlQgZXhjbE1hc2sgPSBwVGhyZWFkQnMtPmV4Y2x1ZGVkQ2huc01hc2s7CiAgICBBQUNERUNfRFJDX1BBWUxPQURfVFlQRSBkcmNQYXlsb2FkVHlwZSA9IChBQUNERUNfRFJDX1BBWUxPQURfVFlQRSlwVGhyZWFkQnMtPmNoYW5uZWxEYXRhLmRyY0RhdGFUeXBlOwogICAgaW50IGNoOwoKICAgIC8qIGxhc3QgcHJvZ1JlZkxldmVsIHRyYW5zbWl0dGVkIGlzIHRoZSBvbmUgdGhhdCBpcyB1c2VkCiAgICAgKiAoYnV0IGl0IHNob3VsZCByZWFsbHkgb25seSBiZSB0cmFuc21pdHRlZCBvbmNlIHBlciBibG9jayEpCiAgICAgKi8KICAgIGlmIChwVGhyZWFkQnMtPnByb2dSZWZMZXZlbCA+PSAwKSB7CiAgICAgIHNlbGYtPnByb2dSZWZMZXZlbCA9IHBUaHJlYWRCcy0+cHJvZ1JlZkxldmVsOwogICAgICBzZWxmLT5wcmxFeHBpcnlDb3VudCA9IDA7ICAvKiBHb3QgYSBuZXcgdmFsdWUgLT4gUmVzZXQgY291bnRlciAqLwogICAgfQoKICAgIC8qIFNDRSwgQ1BFIGFuZCBMRkUgKi8KICAgIGZvciAoY2ggPSAwOyBjaCA8IHZhbGlkQ2hhbm5lbHM7IGNoKyspIHsKICAgICAgaW50IG1hcGVkQ2hhbm5lbCA9IGNoYW5uZWxNYXBwaW5nW2NoXTsKCiAgICAgIGlmICggKChleGNsTWFzayAmICgxPDxtYXBlZENoYW5uZWwpKSA9PSAwKQogICAgICAgICYmICggKGRyY1BheWxvYWRUeXBlID09IE1QRUdfRFJDX0VYVF9EQVRBKQogICAgICAgICAgfHwgKChkcmNQYXlsb2FkVHlwZSA9PSBEVkJfRFJDX0FOQ19EQVRBKSAmJiBzZWxmLT5wYXJhbXMuYXBwbHlIZWF2eUNvbXByZXNzaW9uKQogICAgICAgICApICkgewogICAgICAgIC8qIGNvcHkgdGhyZWFkIHRvIGNoYW5uZWwgKi8KICAgICAgICBwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+ZHJjRGF0YSA9IHBUaHJlYWRCcy0+Y2hhbm5lbERhdGE7CiAgICAgIH0KICAgIH0KICAgIC8qIENDRXMgbm90IHN1cHBvcnRlZCBieSBub3cgKi8KICB9CgogIC8qIEluY3JlbWVudCBhbmQgY2hlY2sgZXhwaXJ5IGNvdW50ZXIgZm9yIHRoZSBwcm9ncmFtIHJlZmVyZW5jZSBsZXZlbDogKi8KICBpZiAoIChwUGFyYW1zLT5leHBpcnlGcmFtZSA+IDApCiAgICAmJiAoc2VsZi0+cHJsRXhwaXJ5Q291bnQrKyA+IHBQYXJhbXMtPmV4cGlyeUZyYW1lKSApCiAgeyAvKiBUaGUgcHJvZ3JhbSByZWZlcmVuY2UgbGV2ZWwgaXMgdG9vIG9sZCwgc28gc2V0IGl0IGJhY2sgdG8gdGhlIHRhcmdldCBsZXZlbC4gKi8KICAgIHNlbGYtPnByb2dSZWZMZXZlbCA9IHBQYXJhbXMtPnRhcmdldFJlZkxldmVsOwogICAgc2VsZi0+cHJsRXhwaXJ5Q291bnQgPSAwOwogIH0KCiAgcmV0dXJuIDA7Cn0KCgp2b2lkIGFhY0RlY29kZXJfZHJjQXBwbHkgKAogICAgICAgIEhBTkRMRV9BQUNfRFJDICAgICAgICAgIHNlbGYsCiAgICAgICAgdm9pZCAgICAgICAgICAgICAgICAgICAqcFNickRlYywKICAgICAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgICAgIENEcmNDaGFubmVsRGF0YSAgICAgICAgKnBEcmNDaERhdGEsCiAgICAgICAgaW50ICBjaCwgICAvKiBuZWVkZWQgb25seSBmb3IgU0JSICovCiAgICAgICAgaW50ICBhYWNGcmFtZVNpemUsCiAgICAgICAgaW50ICBiU2JyUHJlc2VudCApCnsKICBpbnQgYmFuZCwgdG9wLCBiaW4sIG51bUJhbmRzOwogIGludCBib3R0b20gPSAwOwogIGludCBtb2RpZnlCaW5zID0gMDsKCiAgRklYUF9EQkwgbWF4X21hbnRpc3NhOwogIElOVCBtYXhfZXhwb25lbnQ7CgogIEZJWFBfREJMIG5vcm1fbWFudGlzc2EgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICBJTlQgIG5vcm1fZXhwb25lbnQgPSAwOwoKICBGSVhQX0RCTCBmYWN0X21hbnRpc3NhW01BWF9EUkNfQkFORFNdOwogIElOVCAgZmFjdF9leHBvbmVudFtNQVhfRFJDX0JBTkRTXTsKCiAgQ0RyY1BhcmFtcyAgKnBQYXJhbXMgPSAmc2VsZi0+cGFyYW1zOwoKICBGSVhQX0RCTCAgICAqcFNwZWN0cmFsQ29lZmZpY2llbnQgID0gIFNQRUNfTE9ORyhwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wU3BlY3RyYWxDb2VmZmljaWVudCk7CiAgQ0ljc0luZm8gICAgKnBJY3NJbmZvICAgICAgICAgICAgICA9ICZwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5pY3NJbmZvOwogIFNIT1JUICAgICAgICpwU3BlY1NjYWxlICAgICAgICAgICAgPSAgcEFhY0RlY29kZXJDaGFubmVsSW5mby0+c3BlY1NjYWxlOwoKICBpbnQgd2luU2VxID0gcEljc0luZm8tPldpbmRvd1NlcXVlbmNlOwoKICAvKiBJbmNyZW1lbnQgYW5kIGNoZWNrIGV4cGlyeSBjb3VudGVyICovCiAgaWYgKCAocFBhcmFtcy0+ZXhwaXJ5RnJhbWUgPiAwKQogICAgJiYgKCsrcERyY0NoRGF0YS0+ZXhwaXJ5Q291bnQgPiBwUGFyYW1zLT5leHBpcnlGcmFtZSkgKQogIHsgLyogVGhlIERSQyBkYXRhIGlzIHRvbyBvbGQsIHNvIGRlbGV0ZSBpdC4gKi8KICAgIGFhY0RlY29kZXJfZHJjSW5pdENoYW5uZWxEYXRhKCBwRHJjQ2hEYXRhICk7CiAgfQoKICBpZiAoIXNlbGYtPmVuYWJsZSkgewogICAgc2JyRGVjb2Rlcl9kcmNEaXNhYmxlKCAoSEFORExFX1NCUkRFQ09ERVIpcFNickRlYywgY2ggKTsKICAgIHJldHVybjsKICB9CgogIG51bUJhbmRzID0gcERyY0NoRGF0YS0+bnVtQmFuZHM7CiAgdG9wID0gRkRLbWF4KDAsIG51bUJhbmRzLTEpOwoKICBwRHJjQ2hEYXRhLT5iYW5kVG9wWzBdID0gZml4TWluKHBEcmNDaERhdGEtPmJhbmRUb3BbMF0sIChhYWNGcmFtZVNpemUgPj4gMikgLSAxKTsKCiAgLyogSWYgcHJvZ3JhbSByZWZlcmVuY2Ugbm9ybWFsaXphdGlvbiBpcyBkb25lIGluIHRoZSBkaWdpdGFsIGRvbWFpbiwKICBtb2RpZnkgZmFjdG9yIHRvIHBlcmZvcm0gbm9ybWFsaXphdGlvbi4gIHByb2dfcmVmX2xldmVsIGNhbgogIGFsdGVybmF0aXZlbHkgYmUgcGFzc2VkIHRvIHRoZSBzeXN0ZW0gZm9yIG1vZGlmaWNhdGlvbiBvZiB0aGUgbGV2ZWwgaW4KICB0aGUgYW5hbG9nIGRvbWFpbi4gIEFuYWxvZyBsZXZlbCBtb2RpZmljYXRpb24gYXZvaWRzIHByb2JsZW1zIHdpdGgKICByZWR1Y2VkIERBQyBTTlIgKGlmIHNpZ25hbCBpcyBhdHRlbnVhdGVkKSBvciBjbGlwcGluZyAoaWYgc2lnbmFsIGlzCiAgYm9vc3RlZCkgKi8KCiAgaWYgKHNlbGYtPmRpZ2l0YWxOb3JtID09IDEpCiAgewogICAgLyogMC41XigodGFyZ2V0UmVmTGV2ZWwgLSBwcm9nUmVmTGV2ZWwpLzI0KSAqLwogICAgbm9ybV9tYW50aXNzYSA9IGZMZFBvdygKICAgICAgICAgICAgRkwyRlhDT05TVF9EQkwoLTEuMCksIC8qIGxvZzIoMC41KSAqLwogICAgICAgICAgICAwLAogICAgICAgICAgICAoRklYUF9EQkwpKChJTlQpKEZMMkZYQ09OU1RfREJMKDEuMGYvMjQuMCk+PjMpICogKElOVCkocFBhcmFtcy0+dGFyZ2V0UmVmTGV2ZWwtc2VsZi0+cHJvZ1JlZkxldmVsKSksCiAgICAgICAgICAgIDMsCiAgICAgICAgICAgJm5vcm1fZXhwb25lbnQgKTsKICB9CiAgZWxzZSB7CiAgICBub3JtX21hbnRpc3NhID0gRkwyRlhDT05TVF9EQkwoMC41Zik7CiAgICBub3JtX2V4cG9uZW50ID0gMTsKICB9CgoKICAvKiBjYWxjIHNjYWxlIGZhY3RvcnMgKi8KICBmb3IgKGJhbmQgPSAwOyBiYW5kIDwgbnVtQmFuZHM7IGJhbmQrKykKICB7CiAgICBVQ0hBUiBkcmNWYWwgPSBwRHJjQ2hEYXRhLT5kcmNWYWx1ZVtiYW5kXTsKICAgIHRvcCA9IGZpeE1pbigoaW50KSggKHBEcmNDaERhdGEtPmJhbmRUb3BbYmFuZF0rMSk8PDIgKSwgYWFjRnJhbWVTaXplKTsKCiAgICBmYWN0X21hbnRpc3NhW2JhbmRdID0gRkwyRlhDT05TVF9EQkwoMC41Zik7CiAgICBmYWN0X2V4cG9uZW50W2JhbmRdID0gMTsKCiAgICBpZiAoICBwUGFyYW1zLT5hcHBseUhlYXZ5Q29tcHJlc3Npb24KICAgICAgJiYgKChBQUNERUNfRFJDX1BBWUxPQURfVFlQRSlwRHJjQ2hEYXRhLT5kcmNEYXRhVHlwZSA9PSBEVkJfRFJDX0FOQ19EQVRBKSApCiAgICB7CiAgICAgIElOVCBjb21wcmVzc2lvbkZhY3RvclZhbF9lOwogICAgICBpbnQgdmFsWCwgdmFsWTsKCiAgICAgIHZhbFggPSBkcmNWYWwgPj4gNDsKICAgICAgdmFsWSA9IGRyY1ZhbCAmIDB4MEY7CgogICAgICAvKiBjYWxjdWxhdGUgdGhlIHVuc2NhbGVkIGhlYXZ5IGNvbXByZXNzaW9uIGZhY3Rvci4KICAgICAgICAgY29tcHJlc3Npb25GYWN0b3IgPSA0OC4xNjQgLSA2LjAyMDYqdmFsWCAtIDAuNDAxNCp2YWxZIGRCCiAgICAgICAgIHJhbmdlOiAtNDguMTY2IGRCIHRvIDQ4LjE2NCBkQiAqLwogICAgICBpZiAoIGRyY1ZhbCAhPSAweDdGICkgewogICAgICAgIGZhY3RfbWFudGlzc2FbYmFuZF0gPQogICAgICAgICAgZlBvd0ludCggRkwyRlhDT05TVF9EQkwoMC45NTQ4Mzg2NzE4MSksIC8qIC0wLjQwMTRkQiA9IDAuOTU0ODM4NjcxODEgKi8KICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICB2YWxZLAogICAgICAgICAgICAgICAgICAmY29tcHJlc3Npb25GYWN0b3JWYWxfZSApOwoKICAgICAgICAvKiAtMC4wMDA4ZEIgKDQ4LjE2NCAtIDYuMDIwNio4ID0gLTAuMDAwOCkgKi8KICAgICAgICBmYWN0X21hbnRpc3NhW2JhbmRdID0gZk11bHQoRkwyRlhDT05TVF9EQkwoMC45OTk5MDc5MDA4NCksIGZhY3RfbWFudGlzc2FbYmFuZF0pOwoKICAgICAgICBmYWN0X2V4cG9uZW50W2JhbmRdID0gRFZCX0NPTVBSRVNTSU9OX1NDQUxFIC0gdmFsWCArIGNvbXByZXNzaW9uRmFjdG9yVmFsX2U7CiAgICAgIH0KICAgIH0gZWxzZQogICAgaWYgKChBQUNERUNfRFJDX1BBWUxPQURfVFlQRSlwRHJjQ2hEYXRhLT5kcmNEYXRhVHlwZSA9PSBNUEVHX0RSQ19FWFRfREFUQSkKICAgIHsKICAgIC8qIGFwcGx5IHRoZSBzY2FsZWQgZHluYW1pYyByYW5nZSBjb250cm9sIHdvcmRzIHRvIGZhY3Rvci4KICAgICAqIGlmIHNjYWxpbmcgZHJjX2N1dCAob3IgZHJjX2Jvb3N0KSwgb3IgY29udHJvbCB3b3JkIGRyY19tYW50aXNzYSBpcyAwCiAgICAgKiB0aGVuIHRoZXJlIGlzIG5vIGR5bmFtaWMgcmFuZ2UgY29tcHJlc3Npb24KICAgICAqCiAgICAgKiBpZiBwRHJjQ2hEYXRhLT5kcmNTZ25bYmFuZF0gaXMgCiAgICAgKiAgMSB0aGVuIGdhaW4gaXMgPCAxIDogIGZhY3RvciA9IDJeKC1zZWxmLT5jdXQgICAqIHBEcmNDaERhdGEtPmRyY01hZ1tiYW5kXSAvIDI0KQogICAgICogIDAgdGhlbiBnYWluIGlzID4gMSA6ICBmYWN0b3IgPSAyXiggc2VsZi0+Ym9vc3QgKiBwRHJjQ2hEYXRhLT5kcmNNYWdbYmFuZF0gLyAyNCkKICAgICAqLwoKICAgIGlmICgoZHJjVmFsJjB4N0YpID4gMCkgewogICAgICBGSVhQX0RCTCB0UGFyYW1WYWwgPSAoZHJjVmFsICYgMHg4MCkgPyAtcFBhcmFtcy0+Y3V0IDogcFBhcmFtcy0+Ym9vc3Q7CgogICAgICBmYWN0X21hbnRpc3NhW2JhbmRdID0KICAgICAgICBmMlBvdyggKEZJWFBfREJMKSgoSU5UKWZNdWx0KEZMMkZYQ09OU1RfREJMKDEuMGYvMTkyLjBmKSwgdFBhcmFtVmFsKSAqIChkcmNWYWwmMHg3RikpLAogICAgICAgICAgICAgICAgIDMrRFJDX1BBUkFNX1NDQUxFLAogICAgICAgICAgICAgICAgJmZhY3RfZXhwb25lbnRbYmFuZF0gKTsKICAgIH0KICAgIH0KCiAgICBmYWN0X21hbnRpc3NhW2JhbmRdICA9IGZNdWx0KGZhY3RfbWFudGlzc2FbYmFuZF0sIG5vcm1fbWFudGlzc2EpOwogICAgZmFjdF9leHBvbmVudFtiYW5kXSArPSBub3JtX2V4cG9uZW50OwoKCiAgICBib3R0b20gPSB0b3A7CgogIH0gIC8qIGVuZCBsb29wIG92ZXIgYmFuZHMgKi8KCgogIC8qIG5vcm1hbGl6YXRpb25zICovCiAgewogICAgaW50IHJlczsKCiAgICBtYXhfbWFudGlzc2EgPSBGTDJGWENPTlNUX0RCTCgwLjBmKTsKICAgIG1heF9leHBvbmVudCA9IDA7CiAgICBmb3IgKGJhbmQgPSAwOyBiYW5kIDwgbnVtQmFuZHM7IGJhbmQrKykgewogICAgICBtYXhfbWFudGlzc2EgPSBmaXhNYXgobWF4X21hbnRpc3NhLCBmYWN0X21hbnRpc3NhW2JhbmRdKTsKICAgICAgbWF4X2V4cG9uZW50ID0gZml4TWF4KG1heF9leHBvbmVudCwgZmFjdF9leHBvbmVudFtiYW5kXSk7CiAgICB9CgogICAgLyogbGVmdCBzaGlmdCBmYWN0b3JzIHRvIGdhaW4gYWNjdXJhbmN5ICovCiAgICByZXMgPSBDbnRMZWFkaW5nWmVyb3MobWF4X21hbnRpc3NhKSAtIDE7CgogICAgLyogYWJvdmUgdG9wbW9zdCBEUkMgYmFuZCBnYWluIGZhY3RvciBpcyAxICovCiAgICBpZiAoKChwRHJjQ2hEYXRhLT5iYW5kVG9wW251bUJhbmRzLTFdKzEpPDwyKSA8IGFhY0ZyYW1lU2l6ZSkgcmVzID0gMDsKCiAgICBpZiAocmVzID4gMCkgewogICAgICByZXMgPSBmaXhNaW4ocmVzLCBtYXhfZXhwb25lbnQpOwogICAgICBtYXhfZXhwb25lbnQgLT0gcmVzOwoKICAgICAgZm9yIChiYW5kID0gMDsgYmFuZCA8IG51bUJhbmRzOyBiYW5kKyspIHsKICAgICAgICBmYWN0X21hbnRpc3NhW2JhbmRdIDw8PSByZXM7CiAgICAgICAgZmFjdF9leHBvbmVudFtiYW5kXSAgLT0gcmVzOwogICAgICB9CiAgICB9CgogICAgLyogbm9ybWFsaXplIG1hZ25pdHVkZXMgdG8gb25lIHNjYWxlIGZhY3RvciAqLwogICAgZm9yIChiYW5kID0gMDsgYmFuZCA8IG51bUJhbmRzOyBiYW5kKyspIHsKICAgICAgaWYgKGZhY3RfZXhwb25lbnRbYmFuZF0gPCBtYXhfZXhwb25lbnQpIHsKICAgICAgICBmYWN0X21hbnRpc3NhW2JhbmRdID4+PSBtYXhfZXhwb25lbnQgLSBmYWN0X2V4cG9uZW50W2JhbmRdOwogICAgICB9CiAgICAgIGlmIChmYWN0X21hbnRpc3NhW2JhbmRdICE9IEZMMkZYQ09OU1RfREJMKDAuNWYpKSB7CiAgICAgICAgbW9kaWZ5QmlucyA9IDE7CiAgICAgIH0KICAgIH0KICAgIGlmIChtYXhfZXhwb25lbnQgIT0gMSkgewogICAgICBtb2RpZnlCaW5zID0gMTsKICAgIH0KICB9CgogIC8qICBhcHBseSBmYWN0b3IgdG8gc3BlY3RyYWwgbGluZXMKICAgKiAgc2hvcnQgYmxvY2tzIG11c3QgdGFrZSBjYXJlIHRoYXQgYmFuZHMgZmFsbCBvbiAKICAgKiAgYmxvY2sgYm91bmRhcmllcyEKICAgKi8KICBpZiAoIWJTYnJQcmVzZW50KQogIHsKICAgIGJvdHRvbSA9IDA7CgogICAgaWYgKCFtb2RpZnlCaW5zKSB7CiAgICAgIC8qIFdlIGRvbid0IGhhdmUgdG8gbW9kaWZ5IHRoZSBzcGVjdHJhbCBiaW5zIGJlY2F1c2UgdGhlIGZyYWN0aW9uYWwgcGFydCBvZiBhbGwgZmFjdG9ycyBpcyAwLjUuCiAgICAgICAgIEluIG9yZGVyIHRvIGtlZXAgYWNjdXJhbmN5IHdlIGRvbid0IGFwcGx5IHRoZSBmYWN0b3IgYnV0IGRlY3JlYXNlIHRoZSBleHBvbmVudCBpbnN0ZWFkLiAqLwogICAgICBtYXhfZXhwb25lbnQgLT0gMTsKICAgIH0gZWxzZQogICAgewogICAgICBmb3IgKGJhbmQgPSAwOyBiYW5kIDwgbnVtQmFuZHM7IGJhbmQrKykKICAgICAgewogICAgICAgIHRvcCA9IGZpeE1pbigoaW50KSggKHBEcmNDaERhdGEtPmJhbmRUb3BbYmFuZF0rMSk8PDIgKSwgYWFjRnJhbWVTaXplKTsgICAvKiAuLi4gKiBEUkNfQkFORF9NVUxUOyAqLwoKICAgICAgICBmb3IgKGJpbiA9IGJvdHRvbTsgYmluIDwgdG9wOyBiaW4rKykgewogICAgICAgICAgcFNwZWN0cmFsQ29lZmZpY2llbnRbYmluXSA9IGZNdWx0KHBTcGVjdHJhbENvZWZmaWNpZW50W2Jpbl0sIGZhY3RfbWFudGlzc2FbYmFuZF0pOwogICAgICAgIH0KCiAgICAgICAgYm90dG9tID0gdG9wOwogICAgICB9CiAgICB9CgogICAgLyogYWJvdmUgdG9wbW9zdCBEUkMgYmFuZCBnYWluIGZhY3RvciBpcyAxICovCiAgICBpZiAobWF4X2V4cG9uZW50ID4gMCkgewogICAgICBmb3IgKGJpbiA9IGJvdHRvbTsgYmluIDwgYWFjRnJhbWVTaXplOyBiaW4rPTEpIHsKICAgICAgICBwU3BlY3RyYWxDb2VmZmljaWVudFtiaW5dID4+PSBtYXhfZXhwb25lbnQ7CiAgICAgIH0KICAgIH0KCiAgICAvKiBhZGp1c3Qgc2NhbGluZyAqLwogICAgcFNwZWNTY2FsZVswXSArPSBtYXhfZXhwb25lbnQ7CgogICAgaWYgKHdpblNlcSA9PSBFaWdodFNob3J0U2VxdWVuY2UpIHsKICAgICAgaW50IHdpbjsKICAgICAgZm9yICh3aW4gPSAxOyB3aW4gPCA4OyB3aW4rKykgewogICAgICAgIHBTcGVjU2NhbGVbd2luXSArPSBtYXhfZXhwb25lbnQ7CiAgICAgIH0KICAgIH0KICB9CiAgZWxzZSB7CiAgICBIQU5ETEVfU0JSREVDT0RFUiBoU2JyRGVjb2RlciA9IChIQU5ETEVfU0JSREVDT0RFUilwU2JyRGVjOwogICAgVUlOVCBudW1CYW5kcyA9IHBEcmNDaERhdGEtPm51bUJhbmRzOwoKICAgIC8qIGZlZWQgZmFjdG9ycyBpbnRvIFNCUiBkZWNvZGVyIGZvciBhcHBsaWNhdGlvbiBpbiBRTUYgZG9tYWluLiAqLwogICAgc2JyRGVjb2Rlcl9kcmNGZWVkQ2hhbm5lbCAoCiAgICAgICAgICAgIGhTYnJEZWNvZGVyLAogICAgICAgICAgICBjaCwKICAgICAgICAgICAgbnVtQmFuZHMsCiAgICAgICAgICAgIGZhY3RfbWFudGlzc2EsCiAgICAgICAgICAgIG1heF9leHBvbmVudCwKICAgICAgICAgICAgcERyY0NoRGF0YS0+ZHJjSW50ZXJwb2xhdGlvblNjaGVtZSwKICAgICAgICAgICAgd2luU2VxLAogICAgICAgICAgICBwRHJjQ2hEYXRhLT5iYW5kVG9wCiAgICAgICAgICApOwogIH0KCiAgcmV0dXJuOwp9CgoKLyogCiAqIFByZXBhcmUgRFJDIHByb2Nlc3NpbmcKICovCmludCBhYWNEZWNvZGVyX2RyY1Byb2xvZyAoCiAgICAgICAgSEFORExFX0FBQ19EUkMgIHNlbGYsCiAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzLAogICAgICAgIENBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bXSwKICAgICAgICBVQ0hBUiAgcGNlSW5zdGFuY2VUYWcsCiAgICAgICAgVUNIQVIgIGNoYW5uZWxNYXBwaW5nW10sIC8qIENoYW5uZWwgbWFwcGluZyB0cmFuc2xhdGluZyBkcmNDaGFubmVsIGluZGV4IHRvIGNhbm9uaWNhbCBjaGFubmVsIGluZGV4ICovCiAgICAgICAgaW50ICAgIHZhbGlkQ2hhbm5lbHMgKQp7CiAgaW50IGVyciA9IDA7CgogIGlmIChzZWxmID09IE5VTEwpIHsKICAgIHJldHVybiAtMTsKICB9CgogIGlmICghc2VsZi0+cGFyYW1zLmJzRGVsYXlFbmFibGUpCiAgewogICAgZXJyID0gYWFjRGVjb2Rlcl9kcmNFeHRyYWN0QW5kTWFwICgKICAgICAgICAgICAgc2VsZiwKICAgICAgICAgICAgaEJzLAogICAgICAgICAgICBwQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvLAogICAgICAgICAgICBwY2VJbnN0YW5jZVRhZywKICAgICAgICAgICAgY2hhbm5lbE1hcHBpbmcsCiAgICAgICAgICAgIHZhbGlkQ2hhbm5lbHMgKTsKICB9CgogIHJldHVybiBlcnI7Cn0KCgovKiAKICogRmluYWxpemUgRFJDIHByb2Nlc3NpbmcKICovCmludCBhYWNEZWNvZGVyX2RyY0VwaWxvZyAoCiAgICAgICAgSEFORExFX0FBQ19EUkMgIHNlbGYsCiAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzLAogICAgICAgIENBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bXSwKICAgICAgICBVQ0hBUiAgcGNlSW5zdGFuY2VUYWcsCiAgICAgICAgVUNIQVIgIGNoYW5uZWxNYXBwaW5nW10sIC8qIENoYW5uZWwgbWFwcGluZyB0cmFuc2xhdGluZyBkcmNDaGFubmVsIGluZGV4IHRvIGNhbm9uaWNhbCBjaGFubmVsIGluZGV4ICovCiAgICAgICAgaW50ICAgIHZhbGlkQ2hhbm5lbHMgKQp7CiAgaW50IGVyciA9IDA7CgogIGlmIChzZWxmID09IE5VTEwpIHsKICAgIHJldHVybiAtMTsKICB9CgogIGlmIChzZWxmLT5wYXJhbXMuYnNEZWxheUVuYWJsZSkKICB7CiAgICBlcnIgPSBhYWNEZWNvZGVyX2RyY0V4dHJhY3RBbmRNYXAgKAogICAgICAgICAgICBzZWxmLAogICAgICAgICAgICBoQnMsCiAgICAgICAgICAgIHBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8sCiAgICAgICAgICAgIHBjZUluc3RhbmNlVGFnLAogICAgICAgICAgICBjaGFubmVsTWFwcGluZywKICAgICAgICAgICAgdmFsaWRDaGFubmVscyApOwogIH0KCiAgcmV0dXJuIGVycjsKfQoK