Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRW5jb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKToKICAgRGVzY3JpcHRpb246CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAidHBlbmNfbGF0bS5oIgoKCiNpbmNsdWRlICJnZW5lcmljU3Rkcy5oIgoKc3RhdGljIGNvbnN0IHNob3J0IGNlbHBGcmFtZUxlbmd0aFRhYmxlWzY0XSA9IHsKIDE1NCwgMTcwLCAxODYsIDE0NywgMTU2LCAxNjUsIDExNCwgMTIwLAogMTg2LCAxMjYsIDEzMiwgMTM4LCAxNDIsIDE0NiwgMTU0LCAxNjYsCiAxNzQsIDE4MiwgMTkwLCAxOTgsIDIwNiwgMjEwLCAyMTQsIDExMCwKIDExNCwgMTE4LCAxMjAsIDEyMiwgMjE4LCAyMzAsIDI0MiwgMjU0LAogMjY2LCAyNzgsIDI4NiwgMjk0LCAzMTgsIDM0MiwgMzU4LCAzNzQsCiAzOTAsIDQwNiwgNDIyLCAxMzYsIDE0MiwgMTQ4LCAxNTQsIDE2MCwKIDE2NiwgMTcwLCAxNzQsIDE4NiwgMTk4LCAyMDYsIDIxNCwgMjIyLAogMjMwLCAyMzgsIDIxNiwgMTYwLCAyODAsIDMzOCwgMCwgICAwCn07CgovKioqKioqKgogd3JpdGUgdmFsdWUgdG8gdHJhbnNwb3J0IHN0cmVhbQogZmlyc3QgdHdvIGJpdHMgZGVmaW5lIHRoZSBzaXplIG9mIHRoZSB2YWx1ZSBpdHNlbGYKIHRoZW4gdGhlIHZhbHVlIGl0c2VsZiwgd2l0aCBhIHNpemUgb2YgMC0zIGJ5dGVzCioqKioqKiovCnN0YXRpYwpVSU5UIHRyYW5zcG9ydEVuY19MYXRtV3JpdGVWYWx1ZShIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsIGludCB2YWx1ZSkKewogIFVDSEFSIHZhbHVlQnl0ZXMgPSA0OwogIHVuc2lnbmVkIGludCBiaXRzV3JpdHRlbiA9IDA7CiAgaW50IGk7CgogIGlmICggdmFsdWUgPCAoMTw8OCkgKSB7CiAgICB2YWx1ZUJ5dGVzID0gMTsKICB9IGVsc2UgaWYgKCB2YWx1ZSA8ICgxPDwxNikgKSB7CiAgICB2YWx1ZUJ5dGVzID0gMjsKICB9IGVsc2UgaWYgKCB2YWx1ZSA8ICgxPDwyNCkgKSB7CiAgICB2YWx1ZUJ5dGVzID0gMzsKICB9IGVsc2UgewogICAgdmFsdWVCeXRlcyA9IDQ7CiAgfQoKICBGREt3cml0ZUJpdHMoaEJzLCB2YWx1ZUJ5dGVzLTEsIDIgKTsgLyogc2l6ZSBvZiB2YWx1ZSBpbiBCeXRlcyAqLwogIGZvciAoaT0wOyBpPHZhbHVlQnl0ZXM7IGkrKykgewogICAgLyogd3JpdGUgbW9zdCBzaWduaWZpY2FudCBCeXRlIGZpcnN0ICovCiAgICBGREt3cml0ZUJpdHMoaEJzLCAoVUNIQVIpKHZhbHVlPj4oKHZhbHVlQnl0ZXMtMS1pKTw8MykpLCA4KTsKICB9CgogIGJpdHNXcml0dGVuID0gKHZhbHVlQnl0ZXM8PDMpKzI7CgogIHJldHVybiBiaXRzV3JpdHRlbjsKfQoKc3RhdGljClVJTlQgdHJhbnNwb3J0RW5jX0xhdG1Db3VudEZpeEJpdERlbWFuZEhlYWRlciAoIEhBTkRMRV9MQVRNX1NUUkVBTSBoQXNzICkKewogIGludCBiaXREZW1hbmQgPSAwOwogIGludCBpbnNlcnRTZXR1cERhdGEgPSAwIDsKCiAgLyogb25seSBpZiBzdGFydCBvZiBuZXcgbGF0bSBmcmFtZSAqLwogIGlmIChoQXNzLT5zdWJGcmFtZUNudD09MCkKICB7CiAgICAvKiBBdWRpb1N5bmNTdHJlYW0gKi8KCiAgICBpZiAoaEFzcy0+dHQgPT0gVFRfTVA0X0xPQVMpIHsKICAgICAgYml0RGVtYW5kICs9IDExIDsgICAgICAgICAgICAgLyogc3luY3dvcmQgKi8KICAgICAgYml0RGVtYW5kICs9IDEzIDsgICAgICAgICAgICAgLyogYXVkaW9NdXhMZW5ndGhCeXRlcyAqLwogICAgfQoKICAgIC8qIEF1ZGlvTXV4RWxlbWVudCovCgogICAgLyogQXVkaW9NdXhFbGVtZW50OjpTdHJlYW0gTXV4IENvbmZpZyAqLwogICAgaWYgKGhBc3MtPm11eENvbmZpZ1BlcmlvZCA+IDApIHsKICAgICAgaW5zZXJ0U2V0dXBEYXRhID0gKGhBc3MtPmxhdG1GcmFtZUNvdW50ZXIgPT0gMCk7CiAgICB9IGVsc2UgewogICAgICBpbnNlcnRTZXR1cERhdGEgPSAwOwogICAgfQoKICAgIGlmIChoQXNzLT50dCAhPSBUVF9NUDRfTEFUTV9NQ1AwKSB7CiAgICAgIC8qIEF1ZGlvTXV4RWxlbWVudDo6dXNlU2FtZVN0cmVhbU11eCBGbGFnICovCiAgICAgIGJpdERlbWFuZCs9MTsKCiAgICAgIGlmKCBpbnNlcnRTZXR1cERhdGEgKSB7CiAgICAgICAgYml0RGVtYW5kICs9IGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHM7CiAgICAgIH0KICAgIH0KCiAgICAvKiBBdWRpb011eEVsZW1lbnQ6Om90aGVyRGF0YUJpdHMgKi8KICAgIGJpdERlbWFuZCArPSA4KmhBc3MtPm90aGVyRGF0YUxlbkJ5dGVzOwoKICAgIC8qIEF1ZGlvTXV4RWxlbWVudDo6Qnl0ZUFsaWduICovCiAgICBpZiAoIGJpdERlbWFuZCAlIDggKSB7CiAgICAgICBoQXNzLT5maWxsQml0cyA9IDggLSAoYml0RGVtYW5kICUgOCk7CiAgICAgICBiaXREZW1hbmQgKz0gaEFzcy0+ZmlsbEJpdHMgOwogICAgfSBlbHNlIHsKICAgICAgaEFzcy0+ZmlsbEJpdHMgPSAwOwogICAgfQogIH0KCiAgcmV0dXJuIGJpdERlbWFuZCA7Cn0KCnN0YXRpYwpVSU5UIHRyYW5zcG9ydEVuY19MYXRtQ291bnRWYXJCaXREZW1hbmRIZWFkZXIgKCBIQU5ETEVfTEFUTV9TVFJFQU0gaEFzcyAsIHVuc2lnbmVkIGludCBzdHJlYW1EYXRhTGVuZ3RoICkKewogIGludCBiaXREZW1hbmQgPSAwOwogIGludCAgcHJvZywgbGF5ZXI7CgogIC8qIFBheWxvYWQgTGVuZ3RoIEluZm8qLwogIGlmKCBoQXNzLT5hbGxTdHJlYW1zU2FtZVRpbWVGcmFtaW5nICkgewogICAgZm9yKCBwcm9nPTA7IHByb2c8aEFzcy0+bm9Qcm9ncmFtOyBwcm9nKysgKSB7CiAgICAgIGZvciggbGF5ZXI9MDsgbGF5ZXI8TEFUTV9NQVhfTEFZRVJTOyBsYXllcisrICkgewogICAgICAgIExBVE1fTEFZRVJfSU5GTyAqcF9saW5mbyA9ICYoaEFzcy0+bV9saW5mb1twcm9nXVtsYXllcl0pOwoKICAgICAgICBpZiggcF9saW5mby0+c3RyZWFtSUQgPj0gMCApIHsKICAgICAgICAgIHN3aXRjaCggcF9saW5mby0+ZnJhbWVMZW5ndGhUeXBlICkgewogICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICBpZiAoIHN0cmVhbURhdGFMZW5ndGggPiAwICkgewogICAgICAgICAgICAgIHN0cmVhbURhdGFMZW5ndGggLT0gYml0RGVtYW5kIDsKICAgICAgICAgICAgICB3aGlsZSggc3RyZWFtRGF0YUxlbmd0aCA+PSAoMjU1PDwzKSApIHsKICAgICAgICAgICAgICAgIGJpdERlbWFuZCs9ODsKICAgICAgICAgICAgICAgIHN0cmVhbURhdGFMZW5ndGggLT0gKDI1NTw8Myk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGJpdERlbWFuZCArPSA4OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGNhc2UgMToKICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgICAgYml0RGVtYW5kICs9IDI7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICAvKiB0aGVyZSBhcmUgbWFueSBwb3NzaWJpbGl0aWVzIHRvIHVzZSB0aGlzIG1lY2hhbmlzbS4gICovCiAgICBzd2l0Y2goIGhBc3MtPnZhck1vZGUgKSB7CiAgICBjYXNlIExBVE1WQVJfU0lNUExFX1NFUVVFTkNFOiB7CiAgICAgIC8qIFVzZSB0aGUgc2VxdWVuY2UgZ2VuZXJhdGVkIGJ5IHRoZSBlbmNvZGVyICovCiAgICAgIC8vaW50IHN0cmVhbUNudFBvc2l0aW9uID0gdHJhbnNwb3J0RW5jX1NldFdyaXRlUG9pbnRlciggaEFzcy0+aEFzc2VtYmxlLCAwICk7CiAgICAgIC8vaW50IHN0cmVhbUNudFBvc2l0aW9uID0gRkRLZ2V0VmFsaWRCaXRzKCBoQXNzLT5oQXNzZW1ibGUgKTsKICAgICAgYml0RGVtYW5kKz00OwoKICAgICAgaEFzcy0+dmFyU3RyZWFtQ250ID0gMDsKICAgICAgZm9yKCBwcm9nPTA7IHByb2c8aEFzcy0+bm9Qcm9ncmFtOyBwcm9nKysgKSB7CiAgICAgICAgZm9yKCBsYXllcj0wOyBsYXllcjxMQVRNX01BWF9MQVlFUlM7IGxheWVyKysgKSB7CiAgICAgICAgICBMQVRNX0xBWUVSX0lORk8gKnBfbGluZm8gPSAmKGhBc3MtPm1fbGluZm9bcHJvZ11bbGF5ZXJdKTsKCiAgICAgICAgICBpZiggcF9saW5mby0+c3RyZWFtSUQgPj0gMCApIHsKCiAgICAgICAgICAgIGJpdERlbWFuZCs9NDsgLyogc3RyZWFtSUQgKi8KICAgICAgICAgICAgc3dpdGNoKCBwX2xpbmZvLT5mcmFtZUxlbmd0aFR5cGUgKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBzdHJlYW1EYXRhTGVuZ3RoIC09IGJpdERlbWFuZCA7CiAgICAgICAgICAgICAgd2hpbGUoIHN0cmVhbURhdGFMZW5ndGggPj0gKDI1NTw8MykgKSB7CiAgICAgICAgICAgICAgICBiaXREZW1hbmQrPTg7CiAgICAgICAgICAgICAgICBzdHJlYW1EYXRhTGVuZ3RoIC09ICgyNTU8PDMpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgYml0RGVtYW5kICs9IDg7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgLypiaXREZW1hbmQgKz0gMTsgZW5kRmxhZwogICAgICAgICAgICAgIGJyZWFrOyovCgogICAgICAgICAgICBjYXNlIDE6CiAgICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgY2FzZSA2OgoKICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgcmV0dXJuICAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGhBc3MtPnZhclN0cmVhbUNudCsrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBiaXREZW1hbmQrPTQ7CiAgICAgIC8vdHJhbnNwb3J0RW5jX1VwZGF0ZUJpdHN0cmVhbUZpZWxkKCBoQXNzLT5oQXNzZW1ibGUsIHN0cmVhbUNudFBvc2l0aW9uLCBoQXNzLT52YXJTdHJlYW1DbnQtMSwgNCApOwogICAgICAvL1VJTlQgcG9zID0gc3RyZWFtQ250UG9zaXRpb24tRkRLZ2V0VmFsaWRCaXRzKGhBc3MtPmhBc3NlbWJsZSk7CiAgICAgIC8vRkRLcHVzaEJhY2soIGhBc3MtPmhBc3NlbWJsZSwgIHBvcyk7CiAgICAgIC8vRkRLd3JpdGVCaXRzKCBoQXNzLT5oQXNzZW1ibGUsIGhBc3MtPnZhclN0cmVhbUNudC0xLCA0KTsKICAgICAgLy9GREtwdXNoRm9yKCBoQXNzLT5oQXNzZW1ibGUsIHBvcy00KTsKICAgIH0KICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiAgMDsKICAgIH0KICB9CgogIHJldHVybiBiaXREZW1hbmQgOwp9CgpUUkFOU1BPUlRFTkNfRVJST1IKQ3JlYXRlU3RyZWFtTXV4Q29uZmlnKAogICAgICAgICAgICAgICAgICAgICAgSEFORExFX0xBVE1fU1RSRUFNIGhBc3MsCiAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsCiAgICAgICAgICAgICAgICAgICAgICBpbnQgYnVmZmVyRnVsbG5lc3MsCiAgICAgICAgICAgICAgICAgICAgICBDU1RwQ2FsbEJhY2tzICpjYgogICAgICAgICAgICAgICAgICAgICApCnsKICBJTlQgc3RyZWFtSURjbnQsIHRtcDsKICBpbnQgbGF5ZXIsIHByb2c7CgogIFVTSE9SVCBjb3JlRnJhbWVPZmZzZXQ9MDsKCiAgaEFzcy0+YXVkaW9NdXhWZXJzaW9uQSAgICA9IDA7IC8qIGZvciBmdXR1cmUgZXh0ZW5zaW9ucyAqLwogIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMgPSAwOwoKICBGREt3cml0ZUJpdHMoIGhCcywgaEFzcy0+YXVkaW9NdXhWZXJzaW9uLCAxICk7ICAgICAgICAgICAgICAgICAgIC8qIGF1ZGlvTXV4VmVyc2lvbiAqLwogIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMgKz0gMTsKCiAgaWYgKCBoQXNzLT5hdWRpb011eFZlcnNpb24gPT0gMSApIHsKICAgIEZES3dyaXRlQml0cyggaEJzLCBoQXNzLT5hdWRpb011eFZlcnNpb25BLCAxICk7ICAgICAgICAgICAgICAgIC8qIGF1ZGlvTXV4VmVyc2lvbkEgKi8KICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMrPTE7CiAgfQoKICBpZiAoIGhBc3MtPmF1ZGlvTXV4VmVyc2lvbkEgPT0gMCApCiAgewogICAgaWYgKCBoQXNzLT5hdWRpb011eFZlcnNpb24gPT0gMSApIHsKICAgICAgaEFzcy0+c3RyZWFtTXV4Q29uZmlnQml0cys9IHRyYW5zcG9ydEVuY19MYXRtV3JpdGVWYWx1ZSggaEJzLCBoQXNzLT50YXJhQnVmZmVyRnVsbG5lc3MgKTsvKiB0YXJhQnVmZmVyRnVsbG5lc3MgKi8KICAgIH0KICAgIEZES3dyaXRlQml0cyggaEJzLCBoQXNzLT5hbGxTdHJlYW1zU2FtZVRpbWVGcmFtaW5nID8gMTowLCAxICk7IC8qIGFsbFN0cmVhbXNTYW1lVGltZUZyYW1pbmcgKi8KICAgIEZES3dyaXRlQml0cyggaEJzLCBoQXNzLT5ub1N1YmZyYW1lcy0xLCA2ICk7ICAgICAgICAgICAgICAgICAgIC8qIE51bWJlciBvZiBTdWJmcmFtZXMgKi8KICAgIEZES3dyaXRlQml0cyggaEJzLCBoQXNzLT5ub1Byb2dyYW0tMSwgNCApOyAgICAgICAgICAgICAgICAgICAgIC8qIE51bWJlciBvZiBQcm9ncmFtcyAqLwoKICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMrPTExOwoKICAgIHN0cmVhbUlEY250ID0gMDsKICAgIGZvciggcHJvZz0wOyBwcm9nPGhBc3MtPm5vUHJvZ3JhbTsgcHJvZysrICkgewogICAgICBpbnQgdHJhbnNMYXllciA9IDA7CgogICAgICBGREt3cml0ZUJpdHMoIGhCcywgaEFzcy0+bm9MYXllcltwcm9nXS0xLCAzICk7CiAgICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMrPTM7CgogICAgICBmb3IoIGxheWVyPTA7IGxheWVyPExBVE1fTUFYX0xBWUVSUzsgbGF5ZXIrKyApIHsKICAgICAgICBMQVRNX0xBWUVSX0lORk8gICAqcF9saW5mbyA9ICYoaEFzcy0+bV9saW5mb1twcm9nXVtsYXllcl0pOwogICAgICAgIENPREVSX0NPTkZJRyAqcF9sY2kgICA9IGhBc3MtPmNvbmZpZ1twcm9nXVtsYXllcl07CgogICAgICAgIHBfbGluZm8tPnN0cmVhbUlEID0gLTE7CgogICAgICAgIGlmKCBoQXNzLT5jb25maWdbcHJvZ11bbGF5ZXJdICE9IE5VTEwgKSB7CiAgICAgICAgICBpbnQgdXNlU2FtZUNvbmZpZyA9IDA7CgogICAgICAgICAgaWYoIHRyYW5zTGF5ZXIgPiAwICkgewogICAgICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgdXNlU2FtZUNvbmZpZyA/IDEgOiAwLCAxICk7CiAgICAgICAgICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMrPTE7CiAgICAgICAgICB9CiAgICAgICAgICBpZiggKHVzZVNhbWVDb25maWcgPT0gMCkgfHwgKHRyYW5zTGF5ZXI9PTApICkgewogICAgICAgICAgICBVSU5UIGJpdHM7CgogICAgICAgICAgICBpZiAoIGhBc3MtPmF1ZGlvTXV4VmVyc2lvbiA9PSAxICkgewogICAgICAgICAgICAgIEZES3B1c2hGb3IoaEJzLCAyKTsgLyogYWxpZ24gdG8gQVNDLCBldmVuIGlmIHdlIGRvIG5vdCBrbm93IHRoZSBsZW5ndGggb2YgdGhlICJhc2NMZW4iIGZpZWxkIHlldCAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICBiaXRzID0gRkRLZ2V0VmFsaWRCaXRzKCBoQnMgKTsKCiAgICAgICAgICAgIHRyYW5zcG9ydEVuY193cml0ZUFTQygKICAgICAgICAgICAgICAgICAgICBoQnMsCiAgICAgICAgICAgICAgICAgICAgaEFzcy0+Y29uZmlnW3Byb2ddW2xheWVyXSwKICAgICAgICAgICAgICAgICAgICBjYgogICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICBiaXRzID0gRkRLZ2V0VmFsaWRCaXRzKCBoQnMgKSAtIGJpdHM7CgogICAgICAgICAgICBpZiAoIGhBc3MtPmF1ZGlvTXV4VmVyc2lvbiA9PSAxICkgewogICAgICAgICAgICAgIEZES3B1c2hCYWNrKGhCcywgYml0cysyKTsKICAgICAgICAgICAgICBoQXNzLT5zdHJlYW1NdXhDb25maWdCaXRzICs9IHRyYW5zcG9ydEVuY19MYXRtV3JpdGVWYWx1ZSggaEJzLCBiaXRzICk7CiAgICAgICAgICAgICAgdHJhbnNwb3J0RW5jX3dyaXRlQVNDKAogICAgICAgICAgICAgICAgICAgICAgaEJzLAogICAgICAgICAgICAgICAgICAgICAgaEFzcy0+Y29uZmlnW3Byb2ddW2xheWVyXSwKICAgICAgICAgICAgICAgICAgICAgIGNiCiAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CgogICAgICAgICAgICBoQXNzLT5zdHJlYW1NdXhDb25maWdCaXRzICs9IGJpdHM7IC8qIGFkZCBhc2MgbGVuZ3RoIHRvIHNtYyBzdW1tYXJ5ICovCiAgICAgICAgICB9CiAgICAgICAgICB0cmFuc0xheWVyKys7CgogICAgICAgICAgaWYoICFoQXNzLT5hbGxTdHJlYW1zU2FtZVRpbWVGcmFtaW5nICkgewogICAgICAgICAgICBpZiggc3RyZWFtSURjbnQgPj0gTEFUTV9NQVhfU1RSRUFNX0lEICkKICAgICAgICAgICAgICByZXR1cm4gVFJBTlNQT1JURU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgfQogICAgICAgICAgcF9saW5mby0+c3RyZWFtSUQgPSBzdHJlYW1JRGNudCsrOwoKICAgICAgICAgIHN3aXRjaCggcF9sY2ktPmFvdCApIHsKICAgICAgICAgIGNhc2UgQU9UX0FBQ19NQUlOICAgICAgOgogICAgICAgICAgY2FzZSBBT1RfQUFDX0xDICAgICAgICA6CiAgICAgICAgICBjYXNlIEFPVF9BQUNfU1NSICAgICAgIDoKICAgICAgICAgIGNhc2UgQU9UX0FBQ19MVFAgICAgICAgOgogICAgICAgICAgY2FzZSBBT1RfQUFDX1NDQUwgICAgICA6CiAgICAgICAgICBjYXNlIEFPVF9FUl9BQUNfTEQgICAgIDoKICAgICAgICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQgICAgOgogICAgICAgICAgY2FzZSBBT1RfVVNBQzoKICAgICAgICAgIGNhc2UgQU9UX1JTVkQ1MDoKICAgICAgICAgICAgcF9saW5mby0+ZnJhbWVMZW5ndGhUeXBlID0gMDsKCiAgICAgICAgICAgIEZES3dyaXRlQml0cyggaEJzLCBwX2xpbmZvLT5mcmFtZUxlbmd0aFR5cGUsIDMgKTsgICAgICAgICAgICAgICAgICAgICAgICAvKiBmcmFtZUxlbmd0aFR5cGUgKi8KICAgICAgICAgICAgRkRLd3JpdGVCaXRzKCBoQnMsIGJ1ZmZlckZ1bGxuZXNzLCA4ICk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYnVmZmVyRnVsbG5lc3MgKi8KICAgICAgICAgICAgaEFzcy0+c3RyZWFtTXV4Q29uZmlnQml0cys9MTE7CgogICAgICAgICAgICBpZiAoICFoQXNzLT5hbGxTdHJlYW1zU2FtZVRpbWVGcmFtaW5nICkgewogICAgICAgICAgICAgIENPREVSX0NPTkZJRyAqcF9sY2lfcHJldiA9IGhBc3MtPmNvbmZpZ1twcm9nXVtsYXllci0xXTsKICAgICAgICAgICAgICBpZiAoICgocF9sY2ktPmFvdCA9PSBBT1RfQUFDX1NDQUwpIHx8IChwX2xjaS0+YW90ID09IEFPVF9FUl9BQUNfU0NBTCkpICYmCiAgICAgICAgICAgICAgICAgICAoKHBfbGNpX3ByZXYtPmFvdCA9PSBBT1RfQ0VMUCkgfHwgKHBfbGNpX3ByZXYtPmFvdCA9PSBBT1RfRVJfQ0VMUCkpICkgewogICAgICAgICAgICAgICAgRkRLd3JpdGVCaXRzKCBoQnMsIGNvcmVGcmFtZU9mZnNldCwgNiApOyAgICAgICAgICAgICAgICAgICAgICAvKiBjb3JlRnJhbWVPZmZzZXQgKi8KICAgICAgICAgICAgICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMrPTY7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGNhc2UgQU9UX1RXSU5fVlE6CiAgICAgICAgICAgIHBfbGluZm8tPmZyYW1lTGVuZ3RoVHlwZSA9IDE7CiAgICAgICAgICAgIHRtcCA9ICggKHBfbGNpLT5iaXRzRnJhbWUrNykgPj4gMyApIC0gMjA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRyYW5zbWlzc2lvbiBmcmFtZSBsZW5ndGggaW4gYnl0ZXMgKi8KICAgICAgICAgICAgaWYoICh0bXAgPCAwKSApIHsKICAgICAgICAgICAgICByZXR1cm4gVFJBTlNQT1JURU5DX0lOVkFMSURfVFJBTlNNSVNTSU9OX0ZSQU1FX0xFTkdUSDsKICAgICAgICAgICAgfQogICAgICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgcF9saW5mby0+ZnJhbWVMZW5ndGhUeXBlLCAzICk7ICAgICAgICAgIC8qIGZyYW1lTGVuZ3RoVHlwZSAqLwogICAgICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgdG1wLCA5ICk7CiAgICAgICAgICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMrPTEyOwoKICAgICAgICAgICAgcF9saW5mby0+ZnJhbWVMZW5ndGhCaXRzID0gKHRtcCsyMCkgPDwgMzsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgY2FzZSBBT1RfQ0VMUDoKICAgICAgICAgICAgcF9saW5mby0+ZnJhbWVMZW5ndGhUeXBlID0gNDsKICAgICAgICAgICAgRkRLd3JpdGVCaXRzKCBoQnMsIHBfbGluZm8tPmZyYW1lTGVuZ3RoVHlwZSwgMyApOyAgICAgICAgICAvKiBmcmFtZUxlbmd0aFR5cGUgKi8KICAgICAgICAgICAgaEFzcy0+c3RyZWFtTXV4Q29uZmlnQml0cys9MzsKICAgICAgICAgICAgewogICAgICAgICAgICAgIGludCBpOwogICAgICAgICAgICAgIGZvciggaT0wOyBpPDYyOyBpKysgKSB7CiAgICAgICAgICAgICAgICBpZiggY2VscEZyYW1lTGVuZ3RoVGFibGVbaV0gPT0gcF9sY2ktPmJpdHNGcmFtZSApCiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiggaT49NjIgKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gVFJBTlNQT1JURU5DX0lOVkFMSURfQ0VMUF9GUkFNRV9MRU5HVEg7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgaSwgNiApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogQ0VMUGZyYW1lTGVuZ3RoVGFiZWxJbmRleCAqLwogICAgICAgICAgICAgIGhBc3MtPnN0cmVhbU11eENvbmZpZ0JpdHMrPTY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcF9saW5mby0+ZnJhbWVMZW5ndGhCaXRzID0gcF9sY2ktPmJpdHNGcmFtZTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgY2FzZSBBT1RfSFZYQzoKICAgICAgICAgICAgcF9saW5mby0+ZnJhbWVMZW5ndGhUeXBlID0gNjsKICAgICAgICAgICAgRkRLd3JpdGVCaXRzKCBoQnMsIHBfbGluZm8tPmZyYW1lTGVuZ3RoVHlwZSwgMyApOyAgICAgICAgICAvKiBmcmFtZUxlbmd0aFR5cGUgKi8KICAgICAgICAgICAgaEFzcy0+c3RyZWFtTXV4Q29uZmlnQml0cys9MzsKICAgICAgICAgICAgewogICAgICAgICAgICAgIGludCBpOwoKICAgICAgICAgICAgICBpZiggcF9sY2ktPmJpdHNGcmFtZSA9PSA0MCApIHsKICAgICAgICAgICAgICAgIGkgPSAwOwogICAgICAgICAgICAgIH0gZWxzZSBpZiggcF9sY2ktPmJpdHNGcmFtZSA9PSA4MCApIHsKICAgICAgICAgICAgICAgIGkgPSAxOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXR1cm4gVFJBTlNQT1JURU5DX0lOVkFMSURfRlJBTUVfQklUUzsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgRkRLd3JpdGVCaXRzKCBoQnMsIGksIDEgKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEhWWENmcmFtZUxlbmd0aFRhYmxlSW5kZXggKi8KICAgICAgICAgICAgICBoQXNzLT5zdHJlYW1NdXhDb25maWdCaXRzKz0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHBfbGluZm8tPmZyYW1lTGVuZ3RoQml0cyA9IHBfbGNpLT5iaXRzRnJhbWU7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGNhc2UgQU9UX05VTExfT0JKRUNUOgogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIFRSQU5TUE9SVEVOQ19JTlZBTElEX0FPVDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBGREt3cml0ZUJpdHMoIGhCcywgKGhBc3MtPm90aGVyRGF0YUxlbkJ5dGVzPjApID8gMTowLCAxICk7ICAgICAgLyogb3RoZXJEYXRhUHJlc2VudCAqLwogICAgaEFzcy0+c3RyZWFtTXV4Q29uZmlnQml0cys9MTsKCiAgICBpZiggaEFzcy0+b3RoZXJEYXRhTGVuQnl0ZXMgPiAwICkgewoKICAgICAgSU5UIG90aGVyRGF0YUxlblRtcCA9IGhBc3MtPm90aGVyRGF0YUxlbkJ5dGVzOwogICAgICBJTlQgZXNjQ250ID0gMDsKICAgICAgSU5UIG90aGVyRGF0YUxlbkVzYyA9IDE7CgogICAgICB3aGlsZShvdGhlckRhdGFMZW5UbXApIHsKICAgICAgICBvdGhlckRhdGFMZW5UbXAgPj49IDg7CiAgICAgICAgZXNjQ250ICsrOwogICAgICB9CgogICAgICBkbyB7CiAgICAgICAgb3RoZXJEYXRhTGVuVG1wID0gKGhBc3MtPm90aGVyRGF0YUxlbkJ5dGVzPj4oZXNjQ250KjgpKSAmIDB4RkY7CiAgICAgICAgZXNjQ250LS07CiAgICAgICAgb3RoZXJEYXRhTGVuRXNjID0gZXNjQ250PjA7CgogICAgICAgIEZES3dyaXRlQml0cyggaEJzLCBvdGhlckRhdGFMZW5Fc2MsIDEgKTsKICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgb3RoZXJEYXRhTGVuVG1wLCA4ICk7CiAgICAgICAgaEFzcy0+c3RyZWFtTXV4Q29uZmlnQml0cys9OTsKICAgICAgfSB3aGlsZShvdGhlckRhdGFMZW5Fc2MpOwogICAgfQoKICAgIHsKICAgICAgVVNIT1JUIGNyY0NoZWNrUHJlc2VudD0wOwogICAgICBVU0hPUlQgY3JjQ2hlY2tTdW09MDsKCiAgICAgIEZES3dyaXRlQml0cyggaEJzLCBjcmNDaGVja1ByZXNlbnQsIDEgKTsgICAgICAgICAgICAgICAvKiBjcmNDaGVja1ByZXNlbnQgKi8KICAgICAgaEFzcy0+c3RyZWFtTXV4Q29uZmlnQml0cys9MTsKICAgICAgaWYgKCBjcmNDaGVja1ByZXNlbnQgKXsKICAgICAgICBGREt3cml0ZUJpdHMoIGhCcywgY3JjQ2hlY2tTdW0sIDggKTsgICAgICAgICAgICAgICAgIC8qIGNyY0NoZWNrU3VtICovCiAgICAgICAgaEFzcy0+c3RyZWFtTXV4Q29uZmlnQml0cys9ODsKICAgICAgfQogICAgfQoKICB9IGVsc2UgeyAgLyogaWYgKCBhdWRpb011eFZlcnNpb25BID09IDAgKSAqLwoKICAgIC8qIGZvciBmdXR1cmUgZXh0ZW5zaW9ucyAqLwoKICB9CgogIHJldHVybiBUUkFOU1BPUlRFTkNfT0s7Cn0KCgpzdGF0aWMgVFJBTlNQT1JURU5DX0VSUk9SCldyaXRlQXVQYXlsb2FkTGVuZ3RoSW5mbyggSEFORExFX0ZES19CSVRTVFJFQU0gaEJpdFN0cmVhbSwgaW50IEF1TGVuZ3RoQml0cyApCnsKICBpbnQgcmVzdEJ5dGVzOwoKICBpZiggQXVMZW5ndGhCaXRzICUgOCApCiAgICByZXR1cm4gVFJBTlNQT1JURU5DX0lOVkFMSURfQVVfTEVOR1RIOwoKICB3aGlsZSggQXVMZW5ndGhCaXRzID49IDI1NSo4ICkgewogICAgRkRLd3JpdGVCaXRzKCBoQml0U3RyZWFtLCAyNTUsIDggKTsgIC8qIDI1NSBzaG93cyBpbmNvbXBsZXRlIEFVICovCiAgICBBdUxlbmd0aEJpdHMgLT0gKDI1NSo4KTsKICB9CgogIHJlc3RCeXRlcyA9IChBdUxlbmd0aEJpdHMpID4+IDM7CiAgRkRLd3JpdGVCaXRzKCBoQml0U3RyZWFtLCByZXN0Qnl0ZXMsIDggKTsKCiAgcmV0dXJuIFRSQU5TUE9SVEVOQ19PSzsKfQoKc3RhdGljClRSQU5TUE9SVEVOQ19FUlJPUiB0cmFuc3BvcnRFbmNfTGF0bVNldE5yT2ZTdWJmcmFtZXMoIEhBTkRMRV9MQVRNX1NUUkVBTSBoQXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgbm9TdWJmcmFtZXNfbmV4dCkgICAgLyogbnIgb2YgYWNjZXNzIHVuaXRzIC8gcGF5bG9hZHMgd2l0aGluIGEgbGF0bSBmcmFtZSAqLwp7CiAgLyogc2FuaXR5IGNoayAqLwogIGlmIChub1N1YmZyYW1lc19uZXh0IDwgMSB8fCBub1N1YmZyYW1lc19uZXh0ID4gTUFYX05SX09GX1NVQkZSQU1FUykgewogICAgcmV0dXJuIFRSQU5TUE9SVEVOQ19MQVRNX0lOVkFMSURfTlJfT0ZfU1VCRlJBTUVTOwogIH0KCiAgaEFzcy0+bm9TdWJmcmFtZXNfbmV4dCA9IG5vU3ViZnJhbWVzX25leHQ7CgogIC8qIGlmIGF0IHN0YXJ0IHRoZW4gd2UgY2FuIHRha2Ugb3ZlciB0aGUgdmFsdWUgaW1tZWRpYXRlbHksIG90aGVyd2lzZSB3ZSBoYXZlIHRvIHdhaXQgZm9yIHRoZSBuZXh0IFNNQyAqLwogIGlmICggKGhBc3MtPnN1YkZyYW1lQ250ID09IDApICYmIChoQXNzLT5sYXRtRnJhbWVDb3VudGVyID09IDApICkgewogICAgaEFzcy0+bm9TdWJmcmFtZXMgPSBub1N1YmZyYW1lc19uZXh0OwogIH0KCiAgcmV0dXJuIFRSQU5TUE9SVEVOQ19PSzsKfQoKc3RhdGljCmludCBhbGxTdHJlYW1zU2FtZVRpbWVGcmFtaW5nKCBIQU5ETEVfTEFUTV9TVFJFQU0gaEFzcywgVUNIQVIgbm9Qcm9ncmFtLCBVQ0hBUiBub0xheWVyW10gLyogcmV0dXJuICovICkKewogIGludCBwcm9nLCBsYXllcjsKCiAgc2lnbmVkIGludCBsYXN0Tm9TYW1wbGVzICAgPSAtMTsKICBzaWduZWQgaW50IG1pbkZyYW1lU2FtcGxlcyA9IEZES19JTlRfTUFYOwogIHNpZ25lZCBpbnQgbWF4RnJhbWVTYW1wbGVzID0gMDsKCiAgc2lnbmVkIGludCBoaWdoZXN0U2FtcGxpbmdSYXRlID0gLTE7CgogIGZvciggcHJvZz0wOyBwcm9nPG5vUHJvZ3JhbTsgcHJvZysrICkgewogICAgbm9MYXllcltwcm9nXSA9IDA7CgogICAgZm9yKCBsYXllcj0wOyBsYXllcjxMQVRNX01BWF9MQVlFUlM7IGxheWVyKysgKQogICAgewogICAgICBpZiggaEFzcy0+Y29uZmlnW3Byb2ddW2xheWVyXSAhPSBOVUxMICkKICAgICAgewogICAgICAgIElOVCBoc2ZTYW1wbGVzRnJhbWU7CgogICAgICAgIG5vTGF5ZXJbcHJvZ10rKzsKCiAgICAgICAgaWYoIGhpZ2hlc3RTYW1wbGluZ1JhdGUgPCAwICkKICAgICAgICAgIGhpZ2hlc3RTYW1wbGluZ1JhdGUgPSBoQXNzLT5jb25maWdbcHJvZ11bbGF5ZXJdLT5zYW1wbGluZ1JhdGU7CgogICAgICAgIGhzZlNhbXBsZXNGcmFtZSA9IGhBc3MtPmNvbmZpZ1twcm9nXVtsYXllcl0tPnNhbXBsZXNQZXJGcmFtZSAgKiBoaWdoZXN0U2FtcGxpbmdSYXRlIC8gaEFzcy0+Y29uZmlnW3Byb2ddW2xheWVyXS0+c2FtcGxpbmdSYXRlOwoKICAgICAgICBpZiggaHNmU2FtcGxlc0ZyYW1lIDw9IG1pbkZyYW1lU2FtcGxlcyApIG1pbkZyYW1lU2FtcGxlcyA9IGhzZlNhbXBsZXNGcmFtZTsKICAgICAgICBpZiggaHNmU2FtcGxlc0ZyYW1lID49IG1heEZyYW1lU2FtcGxlcyApIG1heEZyYW1lU2FtcGxlcyA9IGhzZlNhbXBsZXNGcmFtZTsKCiAgICAgICAgaWYoIGxhc3ROb1NhbXBsZXMgPT0gLTEgKSB7CiAgICAgICAgICBsYXN0Tm9TYW1wbGVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGhzZlNhbXBsZXNGcmFtZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYoIGhzZlNhbXBsZXNGcmFtZSAhPSBsYXN0Tm9TYW1wbGVzICkgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiAxOwp9CgovKioKICogSW5pdGlhbGl6ZSBMQVRNL0xPQVMgU3RyZWFtIGFuZCBhZGQgbGF5ZXIgMCBhdCBwcm9ncmFtIDAuCiAqLwpzdGF0aWMKVFJBTlNQT1JURU5DX0VSUk9SIHRyYW5zcG9ydEVuY19Jbml0TGF0bVN0cmVhbSggSEFORExFX0xBVE1fU1RSRUFNIGhBc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAgICAgICAgICAgICAgICBmcmFjdERlbGF5UHJlc2VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lnbmVkIGludCAgICAgICAgIG11eENvbmZpZ1BlcmlvZCwgLyogaW5zZXJ0IHNldHVwIGRhdGEgZXZlcnkgbXV4Q29uZmlnUGVyaW9kIGZyYW1lcyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UICAgICAgICAgICAgICAgYXVkaW9NdXhWZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFOU1BPUlRfVFlQRSAgICAgdHQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKewogIFRSQU5TUE9SVEVOQ19FUlJPUiBFcnJvclN0YXR1cyA9IFRSQU5TUE9SVEVOQ19PSzsKCiAgaWYgKGhBc3MgPT0gTlVMTCkKICAgIHJldHVybiBUUkFOU1BPUlRFTkNfSU5WQUxJRF9QQVJBTUVURVI7CgogIGhBc3MtPnR0ID0gdHQ7CgogIGhBc3MtPm5vUHJvZ3JhbSA9IDE7CgogIGhBc3MtPmF1ZGlvTXV4VmVyc2lvbiA9IGF1ZGlvTXV4VmVyc2lvbjsKCiAgLyogRmlsbCBub0xheWVyIGFycmF5IHVzaW5nIGhBc3MtPmNvbmZpZyAqLwogIGhBc3MtPmFsbFN0cmVhbXNTYW1lVGltZUZyYW1pbmcgPSBhbGxTdHJlYW1zU2FtZVRpbWVGcmFtaW5nKCBoQXNzLCBoQXNzLT5ub1Byb2dyYW0sIGhBc3MtPm5vTGF5ZXIgKTsKICAvKiBPbmx5IGFsbFN0cmVhbXNTYW1lVGltZUZyYW1pbmc9PTEgaXMgc3VwcG9ydGVkICovCiAgRkRLX0FTU0VSVChoQXNzLT5hbGxTdHJlYW1zU2FtZVRpbWVGcmFtaW5nKTsKCiAgaEFzcy0+ZnJhY3REZWxheVByZXNlbnQgPSBmcmFjdERlbGF5UHJlc2VudDsKICBoQXNzLT5vdGhlckRhdGFMZW5CeXRlcyA9IDA7CgogIGhBc3MtPnZhck1vZGUgPSBMQVRNVkFSX1NJTVBMRV9TRVFVRU5DRTsKCiAgLyogaW5pdGlhbGl6ZSBjb3VudGVycyAqLwogIGhBc3MtPnN1YkZyYW1lQ250ICAgICAgICAgICAgICAgICAgPSAwOwogIGhBc3MtPm5vU3ViZnJhbWVzICAgICAgICAgICAgICAgICAgPSBERUZBVUxUX0xBVE1fTlJfT0ZfU1VCRlJBTUVTOwogIGhBc3MtPm5vU3ViZnJhbWVzX25leHQgICAgICAgICAgICAgPSBERUZBVUxUX0xBVE1fTlJfT0ZfU1VCRlJBTUVTOwoKICAvKiBzeW5jIGxheWVyIHJlbGF0ZWQgKi8KICBoQXNzLT5hdWRpb011eExlbmd0aEJ5dGVzICAgICA9IDA7CgogIGhBc3MtPmxhdG1GcmFtZUNvdW50ZXIgICAgICAgID0gMDsKICBoQXNzLT5tdXhDb25maWdQZXJpb2QgPSBtdXhDb25maWdQZXJpb2Q7CgogIHJldHVybiBFcnJvclN0YXR1czsKfQoKCi8qKgogKgogKi8KVUlOVCB0cmFuc3BvcnRFbmNfTGF0bUNvdW50VG90YWxCaXREZW1hbmRIZWFkZXIgKCBIQU5ETEVfTEFUTV9TVFJFQU0gaEFzcyAsIHVuc2lnbmVkIGludCBzdHJlYW1EYXRhTGVuZ3RoICkKewogIFVJTlQgYml0RGVtYW5kID0gMDsKCiAgc3dpdGNoIChoQXNzLT50dCkgewogIGNhc2UgVFRfTVA0X0xPQVM6CiAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AwOgogIGNhc2UgVFRfTVA0X0xBVE1fTUNQMToKICAgIGlmIChoQXNzLT5zdWJGcmFtZUNudCA9PSAwKSB7CiAgICAgIGJpdERlbWFuZCAgPSB0cmFuc3BvcnRFbmNfTGF0bUNvdW50Rml4Qml0RGVtYW5kSGVhZGVyICggaEFzcyApOwogICAgfQogICAgYml0RGVtYW5kICs9IHRyYW5zcG9ydEVuY19MYXRtQ291bnRWYXJCaXREZW1hbmRIZWFkZXIgKCBoQXNzICwgc3RyZWFtRGF0YUxlbmd0aCAvKi0gYml0RGVtYW5kKi8pOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIGJyZWFrOwogIH0KCiAgcmV0dXJuIGJpdERlbWFuZDsKfQoKc3RhdGljIFRSQU5TUE9SVEVOQ19FUlJPUgpBZHZhbmNlQXVkaW9NdXhFbGVtZW50ICgKICAgICAgICBIQU5ETEVfTEFUTV9TVFJFQU0gICBoQXNzLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywKICAgICAgICBpbnQgICAgICAgICAgICAgICAgICBhdUJpdHMsCiAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgYnVmZmVyRnVsbG5lc3MsCiAgICAgICAgQ1NUcENhbGxCYWNrcyAgICAqY2IKICAgICAgICApCnsKICBUUkFOU1BPUlRFTkNfRVJST1IgRXJyb3JTdGF0dXMgPSBUUkFOU1BPUlRFTkNfT0s7CiAgaW50IGluc2VydE11eFNldHVwOwoKICAvKiBJbnNlcnQgc2V0dXAgZGF0YSB0byBhc3NlbWJsZSBCdWZmZXIgKi8KICBpZiAoaEFzcy0+c3ViRnJhbWVDbnQgPT0gMCkKICB7CiAgICBpZiAoaEFzcy0+bXV4Q29uZmlnUGVyaW9kID4gMCkgewogICAgICBpbnNlcnRNdXhTZXR1cCA9IChoQXNzLT5sYXRtRnJhbWVDb3VudGVyID09IDApOwogICAgfSBlbHNlICB7CiAgICAgIGluc2VydE11eFNldHVwID0gMDsKICAgIH0KCiAgICBpZiAoaEFzcy0+dHQgIT0gVFRfTVA0X0xBVE1fTUNQMCkgewogICAgICBpZiggaW5zZXJ0TXV4U2V0dXAgKSB7CiAgICAgICAgRkRLd3JpdGVCaXRzKCBoQnMsIDAsIDEgKTsgIC8qIHVzZVNhbWVTdHJlYW1NdXggdXNlTmV3U3RyZWFtTXV4ICovCiAgICAgICAgQ3JlYXRlU3RyZWFtTXV4Q29uZmlnKGhBc3MsIGhCcywgYnVmZmVyRnVsbG5lc3MsIGNiKTsKICAgICAgICBpZiAoRXJyb3JTdGF0dXMgIT0gVFJBTlNQT1JURU5DX09LKQogICAgICAgICAgcmV0dXJuIEVycm9yU3RhdHVzOwogICAgICB9IGVsc2UgewogICAgICAgIEZES3dyaXRlQml0cyggaEJzLCAxLCAxICk7ICAgLyogdXNlU2FtZVN0cmVhbU11eCAqLwogICAgICB9CiAgICB9CiAgfQoKICAvKiBQYXlsb2FkTGVuZ3RoSW5mbyAqLwogIHsKICAgIGludCBwcm9nLCBsYXllcjsKCiAgICBmb3IgKHByb2cgPSAwOyBwcm9nIDwgaEFzcy0+bm9Qcm9ncmFtOyBwcm9nKyspIHsKICAgICAgZm9yIChsYXllciA9IDA7IGxheWVyIDwgaEFzcy0+bm9MYXllcltwcm9nXTsgbGF5ZXIrKykgewogICAgICAgIEVycm9yU3RhdHVzID0gV3JpdGVBdVBheWxvYWRMZW5ndGhJbmZvKCBoQnMsIGF1Qml0cyApOwogICAgICAgIGlmIChFcnJvclN0YXR1cyAhPSBUUkFOU1BPUlRFTkNfT0spCiAgICAgICAgICByZXR1cm4gRXJyb3JTdGF0dXM7CiAgICAgIH0KICAgIH0KICB9CiAgLyogQXQgdGhpcyBwb2ludCBjb21lcyB0aGUgYWNjZXNzIHVuaXQuICovCgogIHJldHVybiBUUkFOU1BPUlRFTkNfT0s7Cn0KClRSQU5TUE9SVEVOQ19FUlJPUgp0cmFuc3BvcnRFbmNfTGF0bVdyaXRlICgKICAgICAgICBIQU5ETEVfTEFUTV9TVFJFQU0gICAgaEFzcywKICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgaEJzLAogICAgICAgIGludCAgICAgICAgICAgICAgICAgICBhdUJpdHMsCiAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgIGJ1ZmZlckZ1bGxuZXNzLAogICAgICAgIENTVHBDYWxsQmFja3MgICAgICpjYgogICAgICAgICkKewogIFRSQU5TUE9SVEVOQ19FUlJPUiBFcnJvclN0YXR1czsKCiAgaWYgKGhBc3MtPnN1YkZyYW1lQ250ID09IDApIHsKICAgIC8qIFN0YXJ0IG5ldyBmcmFtZSAqLwogICAgRkRLcmVzZXRCaXRidWZmZXIoaEJzLCBCU19XUklURVIpOwogIH0KCiAgaEFzcy0+bGF0bVN1YmZyYW1lU3RhcnQgPSBGREtnZXRWYWxpZEJpdHMoaEJzKTsKCiAgLyogSW5zZXJ0IHN5bmN3b3JkIGFuZCBzeW5jd29yZCBkaXN0YW5jZQogICAgIC0gb25seSBpZiBsb2FzCiAgICAgLSB3ZSBtdXN0IHVwZGF0ZSB0aGUgc3luY3dvcmQgZGlzdGFuY2UgKD1hdWRpb211eGxlbmd0aGJ5dGVzKSBsYXRlcgogICAqLwogIGlmKCBoQXNzLT50dCA9PSBUVF9NUDRfTE9BUyAmJiBoQXNzLT5zdWJGcmFtZUNudCA9PSAwKQogIHsKICAgIC8qIFN0YXJ0IG5ldyBMT0FTIGZyYW1lICovCiAgICBGREt3cml0ZUJpdHMoIGhCcywgMHgyQjcsIDExICk7CiAgICBoQXNzLT5hdWRpb011eExlbmd0aEJ5dGVzID0gMDsKICAgIGhBc3MtPmF1ZGlvTXV4TGVuZ3RoQnl0ZXNQb3MgPSBGREtnZXRWYWxpZEJpdHMoIGhCcyApOyAgLyogc3RvcmUgcmVhZCBwb2ludGVyIHBvc2l0aW9uICovCiAgICBGREt3cml0ZUJpdHMoIGhCcywgaEFzcy0+YXVkaW9NdXhMZW5ndGhCeXRlcywgMTMgKTsKICB9CgogIEVycm9yU3RhdHVzID0gQWR2YW5jZUF1ZGlvTXV4RWxlbWVudCgKICAgICAgICAgIGhBc3MsCiAgICAgICAgICBoQnMsCiAgICAgICAgICBhdUJpdHMsCiAgICAgICAgICBidWZmZXJGdWxsbmVzcywKICAgICAgICAgIGNiCiAgICAgICAgICApOwoKICBpZiAoRXJyb3JTdGF0dXMgIT0gVFJBTlNQT1JURU5DX09LKQogICAgcmV0dXJuIEVycm9yU3RhdHVzOwoKICByZXR1cm4gRXJyb3JTdGF0dXM7Cn0KCnZvaWQgdHJhbnNwb3J0RW5jX0xhdG1BZGp1c3RTdWJmcmFtZUJpdHMoSEFORExFX0xBVE1fU1RSRUFNICAgIGhBc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgKmJpdHMpCnsKICAvKiBTdWJzdHJhY3QgYml0cyBmcm9tIHBvc3NpYmxlIHByZXZpb3VzIHN1YmZyYW1lICovCiAgKmJpdHMgLT0gaEFzcy0+bGF0bVN1YmZyYW1lU3RhcnQ7CiAgLyogQWRkIGZpbGwgYml0cyAqLwogIGlmIChoQXNzLT5zdWJGcmFtZUNudCA9PSAwKQogICAgKmJpdHMgKz0gaEFzcy0+ZmlsbEJpdHM7Cn0KCgp2b2lkIHRyYW5zcG9ydEVuY19MYXRtR2V0RnJhbWUoSEFORExFX0xBVE1fU1RSRUFNICAgIGhBc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgaEJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgICAgICAgKmJ5dGVzKQp7CgogIGhBc3MtPnN1YkZyYW1lQ250Kys7CiAgaWYgKGhBc3MtPnN1YkZyYW1lQ250ID49IGhBc3MtPm5vU3ViZnJhbWVzKQogIHsKCiAgICAvKiBBZGQgTE9BUyBmcmFtZSBsZW5ndGggaWYgcmVxdWlyZWQuICovCiAgICBpZiAoaEFzcy0+dHQgPT0gVFRfTVA0X0xPQVMpCiAgICB7CiAgICAgIGludCBsYXRtQnl0ZXM7CgogICAgICBsYXRtQnl0ZXMgPSAoRkRLZ2V0VmFsaWRCaXRzKGhCcykrNykgPj4gMzsKCiAgICAgIC8qIHdyaXRlIGxlbmd0aCBpbmZvIGludG8gYXNzZW1ibGVyIGJ1ZmZlciAqLwogICAgICBoQXNzLT5hdWRpb011eExlbmd0aEJ5dGVzID0gbGF0bUJ5dGVzIC0gMzsgLyogMz1TeW5jd29yZCArIGxlbmd0aCAqLwogICAgICB7CiAgICAgICAgRkRLX0JJVFNUUkVBTSB0bXBCdWY7CgogICAgICAgIEZES2luaXRCaXRTdHJlYW0oICZ0bXBCdWYsIGhCcy0+aEJpdEJ1Zi5CdWZmZXIsIGhCcy0+aEJpdEJ1Zi5idWZTaXplLCAwLCBCU19XUklURVIgKSA7CiAgICAgICAgRkRLcHVzaEZvciggJnRtcEJ1ZiwgaEFzcy0+YXVkaW9NdXhMZW5ndGhCeXRlc1BvcyApOwogICAgICAgIEZES3dyaXRlQml0cyggJnRtcEJ1ZiwgaEFzcy0+YXVkaW9NdXhMZW5ndGhCeXRlcywgMTMgKTsKICAgICAgICBGREtzeW5jQ2FjaGUoICZ0bXBCdWYgKTsKICAgICAgfQogICAgfQoKICAgIC8qIFdyaXRlIEF1ZGlvTXV4RWxlbWVudCBieXRlIGFsaWdubWVudCBmaWxsIGJpdHMgKi8KICAgIEZES3dyaXRlQml0cyhoQnMsIDAsIGhBc3MtPmZpbGxCaXRzKTsKCiAgICBGREtfQVNTRVJUKCAoRkRLZ2V0VmFsaWRCaXRzKGhCcykgJSA4KSA9PSAwKTsKCiAgICBoQXNzLT5zdWJGcmFtZUNudCA9IDA7CgogICAgRkRLc3luY0NhY2hlKGhCcyk7CiAgICAqYnl0ZXMgPSAoRkRLZ2V0VmFsaWRCaXRzKGhCcykgKyA3KT4+MzsKICAgIC8vRkRLZmV0Y2hCdWZmZXIoaEJzLCBidWZmZXIsIChVSU5UKilieXRlcyk7CgogICAgaWYgKGhBc3MtPm11eENvbmZpZ1BlcmlvZCA+IDApCiAgICB7CiAgICAgIGhBc3MtPmxhdG1GcmFtZUNvdW50ZXIrKzsKCiAgICAgIGlmIChoQXNzLT5sYXRtRnJhbWVDb3VudGVyID49IGhBc3MtPm11eENvbmZpZ1BlcmlvZCkgewogICAgICAgIGhBc3MtPmxhdG1GcmFtZUNvdW50ZXIgPSAwOwogICAgICAgIGhBc3MtPm5vU3ViZnJhbWVzID0gaEFzcy0+bm9TdWJmcmFtZXNfbmV4dDsKICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICAvKiBObyBkYXRhIHRoaXMgdGltZSAqLwogICAgKmJ5dGVzID0gMDsKICB9Cn0KCi8qKgogKiBJbml0IExBVE0vTE9BUwogKi8KVFJBTlNQT1JURU5DX0VSUk9SIHRyYW5zcG9ydEVuY19MYXRtX0luaXQoCiAgICAgICAgSEFORExFX0xBVE1fU1RSRUFNICBoQXNzLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywKICAgICAgICBDT0RFUl9DT05GSUcgICpsYXllckNvbmZpZywKICAgICAgICBVSU5UIGF1ZGlvTXV4VmVyc2lvbiwKICAgICAgICBUUkFOU1BPUlRfVFlQRSB0dCwKICAgICAgICBDU1RwQ2FsbEJhY2tzICpjYgogICAgICAgICkKewogIFRSQU5TUE9SVEVOQ19FUlJPUiBFcnJvclN0YXR1czsKICBpbnQgZnJhY3REZWxheVByZXNlbnQgPSAwOwogIGludCBwcm9nLCBsYXllcjsKCiAgaW50IHNldHVwRGF0YURpc3RhbmNlRnJhbWVzID0gbGF5ZXJDb25maWctPmhlYWRlclBlcmlvZDsKCiAgRkRLX0FTU0VSVChzZXR1cERhdGFEaXN0YW5jZUZyYW1lcz49MCk7CgogIGZvciAocHJvZz0wOyBwcm9nPExBVE1fTUFYX1BST0dSQU1TOyBwcm9nKyspIHsKICAgIGZvciAobGF5ZXI9MDsgbGF5ZXI8TEFUTV9NQVhfTEFZRVJTOyBsYXllcisrKSB7CiAgICAgIGhBc3MtPmNvbmZpZ1twcm9nXVtsYXllcl0gPSBOVUxMOwogICAgICBoQXNzLT5tX2xpbmZvW3Byb2ddW2xheWVyXS5zdHJlYW1JRCA9IC0xOwogICAgfQogIH0KCiAgaEFzcy0+Y29uZmlnWzBdWzBdID0gbGF5ZXJDb25maWc7CiAgaEFzcy0+bV9saW5mb1swXVswXS5zdHJlYW1JRCA9IDA7CgogIEVycm9yU3RhdHVzID0gdHJhbnNwb3J0RW5jX0luaXRMYXRtU3RyZWFtKCBoQXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFjdERlbGF5UHJlc2VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0dXBEYXRhRGlzdGFuY2VGcmFtZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhdWRpb011eFZlcnNpb24pPzE6MCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKICBpZiAoRXJyb3JTdGF0dXMgIT0gVFJBTlNQT1JURU5DX09LKQogICAgZ290byBiYWlsOwoKICBFcnJvclN0YXR1cyA9IHRyYW5zcG9ydEVuY19MYXRtU2V0TnJPZlN1YmZyYW1lcygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF5ZXJDb25maWctPm5TdWJGcmFtZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogIGlmIChFcnJvclN0YXR1cyAhPSBUUkFOU1BPUlRFTkNfT0spCiAgICBnb3RvIGJhaWw7CgogIC8qIEdldCB0aGUgc2l6ZSBvZiB0aGUgU3RyZWFtTXV4Q29uZmlnIHNvbWVob3cgKi8KICBBZHZhbmNlQXVkaW9NdXhFbGVtZW50KGhBc3MsIGhCcywgMCwgMCwgY2IpOwogIC8vQ3JlYXRlU3RyZWFtTXV4Q29uZmlnKGhBc3MsIGhCcywgMCk7CgpiYWlsOgogIHJldHVybiBFcnJvclN0YXR1czsKfQoKCgoKCgo=