Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBKb3NlZiBIb2VwZmwKICAgRGVzY3JpcHRpb246IEFEVFMgaW50ZXJmYWNlCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAidHBkZWNfYWR0cy5oIgoKCiNpbmNsdWRlICJGREtfYml0c3RyZWFtLmgiCgoKCnZvaWQgYWR0c1JlYWRfQ3JjSW5pdChIQU5ETEVfQURUUyBwQWR0cykgLyohPCBwb2ludGVyIHRvIGFkdHMgY3JjIGluZm8gc3R1Y3R1cmUgKi8KewogIEZES2NyY0luaXQoJnBBZHRzLT5jcmNJbmZvLCAweDgwMDUsIDB4RkZGRiwgMTYpOwp9CgppbnQgYWR0c1JlYWRfQ3JjU3RhcnRSZWcoCiAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9BRFRTIHBBZHRzLCAgICAgICAgICAvKiE8IHBvaW50ZXIgdG8gYWR0cyBzdHVjdHVyZSAqLwogICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsICAgLyohPCBoYW5kbGUgdG8gY3VycmVudCBiaXQgYnVmZmVyIHN0cnVjdHVyZSAqLwogICAgICAgICAgICAgICAgICAgICBpbnQgbUJpdHMgICAgICAgICAgICAgICAgICAgLyohPCBudW1iZXIgb2YgYml0cyBpbiBjcmMgcmVnaW9uICovCiAgICAgICAgICAgICAgICAgICApCnsKICBpZiAocEFkdHMtPmJzLnByb3RlY3Rpb25fYWJzZW50KSB7CiAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiAoIEZES2NyY1N0YXJ0UmVnKCZwQWR0cy0+Y3JjSW5mbywgaEJzLCBtQml0cykgKTsKCn0KCnZvaWQgYWR0c1JlYWRfQ3JjRW5kUmVnKAogICAgICAgICAgICAgICAgICAgIEhBTkRMRV9BRFRTIHBBZHRzLCAvKiE8IHBvaW50ZXIgdG8gYWR0cyBjcmMgaW5mbyBzdHVjdHVyZSAqLwogICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywgICAvKiE8IGhhbmRsZSB0byBjdXJyZW50IGJpdCBidWZmZXIgc3RydWN0dXJlICovCiAgICAgICAgICAgICAgICAgICAgaW50IHJlZyAgICAgICAgICAgICAgICAgICAgLyohPCBjcmMgcmVnaW9uICovCiAgICAgICAgICAgICAgICAgICkKewogIGlmIChwQWR0cy0+YnMucHJvdGVjdGlvbl9hYnNlbnQgPT0gMCkKICB7CiAgICBGREtjcmNFbmRSZWcoJnBBZHRzLT5jcmNJbmZvLCBoQnMsIHJlZyk7CiAgfQp9CgpUUkFOU1BPUlRERUNfRVJST1IgYWR0c1JlYWRfQ3JjQ2hlY2soIEhBTkRMRV9BRFRTIHBBZHRzICkKewogIFRSQU5TUE9SVERFQ19FUlJPUiBFcnJvclN0YXR1cyA9IFRSQU5TUE9SVERFQ19PSzsKICBVU0hPUlQgY3JjOwoKICBpZiAocEFkdHMtPmJzLnByb3RlY3Rpb25fYWJzZW50KQogICAgcmV0dXJuIFRSQU5TUE9SVERFQ19PSzsKCiAgY3JjID0gRkRLY3JjR2V0Q1JDKCZwQWR0cy0+Y3JjSW5mbyk7CiAgaWYgKGNyYyAhPSBwQWR0cy0+Y3JjUmVhZFZhbHVlKQogIHsKICAgIHJldHVybiAoVFJBTlNQT1JUREVDX0NSQ19FUlJPUik7CiAgfQoKICByZXR1cm4gKEVycm9yU3RhdHVzKTsKfQoKCgojZGVmaW5lIEFkdHNfTGVuZ3RoX1N5bmNXb3JkICAgICAgICAgICAgICAgICAgICAgMTIKI2RlZmluZSBBZHRzX0xlbmd0aF9JZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAxCiNkZWZpbmUgQWR0c19MZW5ndGhfTGF5ZXIgICAgICAgICAgICAgICAgICAgICAgICAgMgojZGVmaW5lIEFkdHNfTGVuZ3RoX1Byb3RlY3Rpb25BYnNlbnQgICAgICAgICAgICAgIDEKI2RlZmluZSBBZHRzX0xlbmd0aF9Qcm9maWxlICAgICAgICAgICAgICAgICAgICAgICAyCiNkZWZpbmUgQWR0c19MZW5ndGhfU2FtcGxpbmdGcmVxdWVuY3lJbmRleCAgICAgICAgNAojZGVmaW5lIEFkdHNfTGVuZ3RoX1ByaXZhdGVCaXQgICAgICAgICAgICAgICAgICAgIDEKI2RlZmluZSBBZHRzX0xlbmd0aF9DaGFubmVsQ29uZmlndXJhdGlvbiAgICAgICAgICAzCiNkZWZpbmUgQWR0c19MZW5ndGhfT3JpZ2luYWxDb3B5ICAgICAgICAgICAgICAgICAgMQojZGVmaW5lIEFkdHNfTGVuZ3RoX0hvbWUgICAgICAgICAgICAgICAgICAgICAgICAgIDEKI2RlZmluZSBBZHRzX0xlbmd0aF9Db3B5cmlnaHRJZGVudGlmaWNhdGlvbkJpdCAgICAxCiNkZWZpbmUgQWR0c19MZW5ndGhfQ29weXJpZ2h0SWRlbnRpZmljYXRpb25TdGFydCAgMQojZGVmaW5lIEFkdHNfTGVuZ3RoX0ZyYW1lTGVuZ3RoICAgICAgICAgICAgICAgICAgMTMKI2RlZmluZSBBZHRzX0xlbmd0aF9CdWZmZXJGdWxsbmVzcyAgICAgICAgICAgICAgIDExCiNkZWZpbmUgQWR0c19MZW5ndGhfTnVtYmVyT2ZSYXdEYXRhQmxvY2tzSW5GcmFtZSAgMgojZGVmaW5lIEFkdHNfTGVuZ3RoX0NyY0NoZWNrICAgICAgICAgICAgICAgICAgICAgMTYKClRSQU5TUE9SVERFQ19FUlJPUiBhZHRzUmVhZF9EZWNvZGVIZWFkZXIoCiAgICAgICAgSEFORExFX0FEVFMgICAgICAgICAgIHBBZHRzLAogICAgICAgIENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqcEFzYywKICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgaEJzLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICBpZ25vcmVCdWZmZXJGdWxsbmVzcwogICAgICAgICkKewogIElOVCBjcmNSZWc7CgogIElOVCB2YWxCaXRzOwogIElOVCBjbXBfYnVmZmVyX2Z1bGxuZXNzOwogIGludCBpLCBhZHRzSGVhZGVyTGVuZ3RoOwoKICBTVFJVQ1RfQURUU19CUyBiczsKCiNpZmRlZiBUUF9QQ0VfRU5BQkxFCiAgQ1Byb2dyYW1Db25maWcgb2xkUGNlOwogIC8qIFN0b3JlIHRoZSBvbGQgUENFIHRlbXBvcmFyaWx5LiBNYXliZSB3ZSdsbCBuZWVkIGl0IGxhdGVyIGlmIHdlCiAgICAgaGF2ZSBjaGFubmVsQ29uZmlnPTAgYW5kIG5vIFBDRSBpbiB0aGlzIGZyYW1lLiAqLwogIEZES21lbWNweSgmb2xkUGNlLCAmcEFzYy0+bV9wcm9nckNvbmZpZ0VsZW1lbnQsIHNpemVvZihDUHJvZ3JhbUNvbmZpZykpOwojZW5kaWYKCiAgdmFsQml0cyA9IEZES2dldFZhbGlkQml0cyhoQnMpOwoKICAvKiBhZHRzX2ZpeGVkX2hlYWRlciAqLwogIGJzLm1wZWdfaWQgICAgICAgICAgID0gRkRLcmVhZEJpdHMoaEJzLCBBZHRzX0xlbmd0aF9JZCk7CiAgYnMubGF5ZXIgICAgICAgICAgICAgPSBGREtyZWFkQml0cyhoQnMsIEFkdHNfTGVuZ3RoX0xheWVyKTsKICBicy5wcm90ZWN0aW9uX2Fic2VudCA9IEZES3JlYWRCaXRzKGhCcywgQWR0c19MZW5ndGhfUHJvdGVjdGlvbkFic2VudCk7CiAgYnMucHJvZmlsZSAgICAgICAgICAgPSBGREtyZWFkQml0cyhoQnMsIEFkdHNfTGVuZ3RoX1Byb2ZpbGUpOwogIGJzLnNhbXBsZV9mcmVxX2luZGV4ID0gRkRLcmVhZEJpdHMoaEJzLCBBZHRzX0xlbmd0aF9TYW1wbGluZ0ZyZXF1ZW5jeUluZGV4KTsKICBicy5wcml2YXRlX2JpdCAgICAgICA9IEZES3JlYWRCaXRzKGhCcywgQWR0c19MZW5ndGhfUHJpdmF0ZUJpdCk7CiAgYnMuY2hhbm5lbF9jb25maWcgICAgPSBGREtyZWFkQml0cyhoQnMsIEFkdHNfTGVuZ3RoX0NoYW5uZWxDb25maWd1cmF0aW9uKTsKICBicy5vcmlnaW5hbCAgICAgICAgICA9IEZES3JlYWRCaXRzKGhCcywgQWR0c19MZW5ndGhfT3JpZ2luYWxDb3B5KTsKICBicy5ob21lICAgICAgICAgICAgICA9IEZES3JlYWRCaXRzKGhCcywgQWR0c19MZW5ndGhfSG9tZSk7CgogIC8qIGFkdHNfdmFyaWFibGVfaGVhZGVyICovCiAgYnMuY29weXJpZ2h0X2lkICAgID0gRkRLcmVhZEJpdHMoaEJzLCBBZHRzX0xlbmd0aF9Db3B5cmlnaHRJZGVudGlmaWNhdGlvbkJpdCk7CiAgYnMuY29weXJpZ2h0X3N0YXJ0ID0gRkRLcmVhZEJpdHMoaEJzLCBBZHRzX0xlbmd0aF9Db3B5cmlnaHRJZGVudGlmaWNhdGlvblN0YXJ0KTsKICBicy5mcmFtZV9sZW5ndGggICAgPSBGREtyZWFkQml0cyhoQnMsIEFkdHNfTGVuZ3RoX0ZyYW1lTGVuZ3RoKTsKICBicy5hZHRzX2Z1bGxuZXNzICAgPSBGREtyZWFkQml0cyhoQnMsIEFkdHNfTGVuZ3RoX0J1ZmZlckZ1bGxuZXNzKTsKICBicy5udW1fcmF3X2Jsb2NrcyAgPSBGREtyZWFkQml0cyhoQnMsIEFkdHNfTGVuZ3RoX051bWJlck9mUmF3RGF0YUJsb2Nrc0luRnJhbWUpOwogIGJzLm51bV9wY2VfYml0cyAgICA9IDA7CgogIGFkdHNIZWFkZXJMZW5ndGggPSBBRFRTX0hFQURFUkxFTkdUSDsKCiAgaWYgKCFicy5wcm90ZWN0aW9uX2Fic2VudCkgewogICAgRkRLY3JjUmVzZXQoJnBBZHRzLT5jcmNJbmZvKTsKICAgIEZES3B1c2hCYWNrKGhCcywgNTYpOyAgIC8qIGNvbXBsZXRlIGZpeGVkIGFuZCB2YXJpYWJsZSBoZWFkZXIhICovCiAgICBjcmNSZWcgPSBGREtjcmNTdGFydFJlZygmcEFkdHMtPmNyY0luZm8sIGhCcywgMCk7CiAgICBGREtwdXNoRm9yKGhCcywgNTYpOwogIH0KCiAgaWYgKCEgYnMucHJvdGVjdGlvbl9hYnNlbnQgJiYgYnMubnVtX3Jhd19ibG9ja3M+MCkgewogICAgZm9yIChpPTA7IGk8YnMubnVtX3Jhd19ibG9ja3M7IGkrKykgewogICAgICBwQWR0cy0+cmF3RGF0YUJsb2NrRGlzdFtpXSA9IChVU0hPUlQpRkRLcmVhZEJpdHMoaEJzLCAxNik7CiAgICAgIGFkdHNIZWFkZXJMZW5ndGggKz0gMTY7CiAgICB9CiAgICAvKiBDaGFuZ2UgcmF3IGRhdGEgYmxvY2tzIHRvIGRlbHRhIHZhbHVlcyAqLwogICAgcEFkdHMtPnJhd0RhdGFCbG9ja0Rpc3RbYnMubnVtX3Jhd19ibG9ja3NdID0gYnMuZnJhbWVfbGVuZ3RoIC0gNyAtIGJzLm51bV9yYXdfYmxvY2tzKjIgLSAyIDsKICAgIGZvciAoaT1icy5udW1fcmF3X2Jsb2NrczsgaT4wOyBpLS0pIHsKICAgICAgcEFkdHMtPnJhd0RhdGFCbG9ja0Rpc3RbaV0gLT0gcEFkdHMtPnJhd0RhdGFCbG9ja0Rpc3RbaS0xXTsKICAgIH0KICB9CgogIC8qIGFkdHNfZXJyb3JfY2hlY2sgKi8KICBpZiAoIWJzLnByb3RlY3Rpb25fYWJzZW50KQogIHsKICAgIFVTSE9SVCBjcmNfY2hlY2s7CgogICAgRkRLY3JjRW5kUmVnKCZwQWR0cy0+Y3JjSW5mbywgaEJzLCBjcmNSZWcpOwogICAgY3JjX2NoZWNrID0gRkRLcmVhZEJpdHMoaEJzLCBBZHRzX0xlbmd0aF9DcmNDaGVjayk7CiAgICBhZHRzSGVhZGVyTGVuZ3RoICs9IEFkdHNfTGVuZ3RoX0NyY0NoZWNrOwoKICAgIHBBZHRzLT5jcmNSZWFkVmFsdWUgPSBjcmNfY2hlY2s7CiAgICAvKiBDaGVjayBoZWFkZXIgQ1JDIGluIGNhc2Ugb2YgbXVsdGlwbGUgcmF3IGRhdGEgYmxvY2tzICovCiAgICBpZiAoYnMubnVtX3Jhd19ibG9ja3MgPiAwKSB7CiAgICAgIGlmIChwQWR0cy0+Y3JjUmVhZFZhbHVlICE9IEZES2NyY0dldENSQygmcEFkdHMtPmNyY0luZm8pKSB7CiAgICAgICAgcmV0dXJuIFRSQU5TUE9SVERFQ19DUkNfRVJST1I7CiAgICAgIH0KICAgICAgLyogUmVzZXQgQ1JDIGZvciB0aGUgdXBjb21pbmcgcmF3X2RhdGFfYmxvY2soKSAqLwogICAgICBGREtjcmNSZXNldCgmcEFkdHMtPmNyY0luZm8pOwogICAgfQogIH0KCgogIC8qIGNoZWNrIGlmIHZhbGlkIGhlYWRlciAqLwogIGlmICgKICAgICAgKGJzLmxheWVyICE9IDApIHx8ICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB3ZSBvbmx5IHN1cHBvcnQgTVBFRyBBRFRTCiAgICAgIChicy5zYW1wbGVfZnJlcV9pbmRleCA+PSAxMykgICAgICAgICAgICAgICAgLy8gd2Ugb25seSBzdXBwb3J0IDk2a0h6IC0gNzM1MGtIegogICAgICApIHsKICAgIEZES3B1c2hGb3IoaEJzLCBicy5mcmFtZV9sZW5ndGggKiA4KTsgICAvLyB0cnkgYWdhaW4gb25lIGZyYW1lIGxhdGVyCiAgICByZXR1cm4gVFJBTlNQT1JUREVDX1VOU1VQUE9SVEVEX0ZPUk1BVDsKICB9CgogIC8qIHNwZWNpYWwgdHJlYXRtZW50IG9mIGlkLWJpdCAqLwogIGlmICggKGJzLm1wZWdfaWQgPT0gMCkgJiYgKHBBZHRzLT5kZWNvZGVyQ2FuRG9NcGVnNCA9PSAwKSApCiAgewogICAgLyogTVBFRy0yIGRlY29kZXIgY2Fubm90IHBsYXkgTVBFRy00IGJpdHN0cmVhbXMgKi8KCgogICAgRkRLcHVzaEZvcihoQnMsIGJzLmZyYW1lX2xlbmd0aCAqIDgpOyAgLy8gdHJ5IGFnYWluIG9uZSBmcmFtZSBsYXRlcgogICAgcmV0dXJuIFRSQU5TUE9SVERFQ19VTlNVUFBPUlRFRF9GT1JNQVQ7CiAgfQoKICBpZiAoIWlnbm9yZUJ1ZmZlckZ1bGxuZXNzKQogIHsKICAgIGNtcF9idWZmZXJfZnVsbG5lc3MgPSBicy5mcmFtZV9sZW5ndGgqOCArIGJzLmFkdHNfZnVsbG5lc3MqMzIqZ2V0TnVtYmVyT2ZFZmZlY3RpdmVDaGFubmVscyhicy5jaGFubmVsX2NvbmZpZyk7CgoKICAgIC8qIEV2YWx1YXRlIGJ1ZmZlciBmdWxsbmVzcyAqLwogICAgaWYgKGJzLmFkdHNfZnVsbG5lc3MgIT0gMHg3RkYpCiAgICB7CiAgICAgIGlmIChwQWR0cy0+QnVmZmVyRnVsbG5lc1N0YXJ0RmxhZykKICAgICAgewogICAgICAgIGlmICggdmFsQml0cyA8IGNtcF9idWZmZXJfZnVsbG5lc3MgKQogICAgICAgIHsKICAgICAgICAgIC8qIENvbmRpdGlvbiBmb3Igc3RhcnQgb2YgZGVjb2RpbmcgaXMgbm90IGZ1bGZpbGxlZCAqLwoKICAgICAgICAgIC8qIFRoZSBjdXJyZW50IGZyYW1lIHdpbGwgbm90IGJlIGRlY29kZWQgKi8KICAgICAgICAgIEZES3B1c2hCYWNrKGhCcywgYWR0c0hlYWRlckxlbmd0aCk7CgogICAgICAgICAgaWYgKCAoY21wX2J1ZmZlcl9mdWxsbmVzcythZHRzSGVhZGVyTGVuZ3RoKSA+ICgoVFJBTlNQT1JUREVDX0lOQlVGX1NJWkU8PDMpLTcpICkgewogICAgICAgICAgICByZXR1cm4gVFJBTlNQT1JUREVDX1NZTkNfRVJST1I7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gVFJBTlNQT1JUREVDX05PVF9FTk9VR0hfQklUUzsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgIHBBZHRzLT5CdWZmZXJGdWxsbmVzU3RhcnRGbGFnID0gMDsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgoKICAvKiBHZXQgaW5mbyBmcm9tIEFEVFMgaGVhZGVyICovCiAgQXVkaW9TcGVjaWZpY0NvbmZpZ19Jbml0KHBBc2MpOwogIHBBc2MtPm1fYW90ICAgICAgICAgICAgICAgICAgICA9IChBVURJT19PQkpFQ1RfVFlQRSkoYnMucHJvZmlsZSArIDEpOwogIHBBc2MtPm1fc2FtcGxpbmdGcmVxdWVuY3lJbmRleCA9IGJzLnNhbXBsZV9mcmVxX2luZGV4OwogIHBBc2MtPm1fc2FtcGxpbmdGcmVxdWVuY3kgICAgICA9IFNhbXBsaW5nUmF0ZVRhYmxlW2JzLnNhbXBsZV9mcmVxX2luZGV4XTsKICBwQXNjLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uICAgPSBicy5jaGFubmVsX2NvbmZpZzsKICBwQXNjLT5tX3NhbXBsZXNQZXJGcmFtZSAgICAgICAgPSAxMDI0OwoKI2lmZGVmIFRQX1BDRV9FTkFCTEUKICBpZiAoYnMuY2hhbm5lbF9jb25maWcgPT0gMCkKICB7CiAgICBpbnQgcGNlQml0cyA9IDA7CiAgICBVSU5UIGFsaWduQW5jaG9yID0gRkRLZ2V0VmFsaWRCaXRzKGhCcyk7CiAgICAKICAgIGlmIChGREtyZWFkQml0cyhoQnMsMykgPT0gSURfUENFKSB7CiAgICAgIC8qIEdvdCBsdWNrISBQYXJzZSB0aGUgUENFICovCiAgICAgIGludCBjcmNSZWc7CiAgICAgIGNyY1JlZyA9IGFkdHNSZWFkX0NyY1N0YXJ0UmVnKHBBZHRzLCBoQnMsIDApOwoKICAgICAgQ1Byb2dyYW1Db25maWdfUmVhZCgmcEFzYy0+bV9wcm9nckNvbmZpZ0VsZW1lbnQsIGhCcywgYWxpZ25BbmNob3IpOwoKICAgICAgYWR0c1JlYWRfQ3JjRW5kUmVnKHBBZHRzLCBoQnMsIGNyY1JlZyk7CiAgICAgIHBjZUJpdHMgPSBhbGlnbkFuY2hvciAtIEZES2dldFZhbGlkQml0cyhoQnMpOwogICAgICAvKiBzdG9yZSB0aGUgbnVtYmVyIG9mIFBDRSBiaXRzICovCiAgICAgIGJzLm51bV9wY2VfYml0cyA9IHBjZUJpdHM7CiAgICB9CiAgICBlbHNlIHsKICAgICAgLyogTm8gUENFIGluIHRoaXMgZnJhbWUhIFB1c2ggYmFjayB0aGUgSUQgdGFnIGJpdHMuICovCiAgICAgIEZES3B1c2hCYWNrKGhCcywzKTsKCiAgICAgIC8qIEVuY29kZXJzIGRvIG5vdCBoYXZlIHRvIHdyaXRlIGEgUENFIGluIGVhY2ggZnJhbWUuCiAgICAgICAgIFNvIGlmIHdlIGFscmVhZHkgaGF2ZSBhIHZhbGlkIFBDRSB3ZSBoYXZlIHRvIHVzZSBpdC4gKi8KICAgICAgaWYgKCAgb2xkUGNlLmlzVmFsaWQKICAgICAgICAmJiAoYnMuc2FtcGxlX2ZyZXFfaW5kZXggPT0gcEFkdHMtPmJzLnNhbXBsZV9mcmVxX2luZGV4KSAgLyogd2UgY291bGQgY29tcGFyZSB0aGUgY29tcGxldGUgZml4ZWQgaGVhZGVyIChieXRlcykgaGVyZSEgKi8KICAgICAgICAmJiAoYnMuY2hhbm5lbF9jb25maWcgICAgPT0gcEFkdHMtPmJzLmNoYW5uZWxfY29uZmlnKSAvKiA9PSAwICovCiAgICAgICAgJiYgKGJzLm1wZWdfaWQgICAgICAgICAgID09IHBBZHRzLT5icy5tcGVnX2lkKSApCiAgICAgIHsgLyogUmVzdG9yZSBwcmV2aW91cyBQQ0Ugd2hpY2ggaXMgc3RpbGwgdmFsaWQgKi8KICAgICAgICBGREttZW1jcHkoJnBBc2MtPm1fcHJvZ3JDb25maWdFbGVtZW50LCAmb2xkUGNlLCBzaXplb2YoQ1Byb2dyYW1Db25maWcpKTsKICAgICAgfQogICAgICBlbHNlIGlmIChicy5tcGVnX2lkID09IDApIHsKICAgICAgICAvKiBJZiBub3QgaXQgc2VlbXMgdGhhdCB3ZSBoYXZlIGEgaW1wbGljaXQgY2hhbm5lbCBjb25maWd1cmF0aW9uLgogICAgICAgICAgIFRoaXMgbW9kZSBpcyBub3QgYWxsb3dlZCBpbiB0aGUgY29udGV4dCBvZiBJU08vSUVDIDE0NDk2LTMuCiAgICAgICAgICAgU2tpcCB0aGlzIGZyYW1lIGFuZCB0cnkgdGhlIG5leHQgb25lLiAqLwogICAgICAgIEZES3B1c2hGb3IoaEJzLCAoYnMuZnJhbWVfbGVuZ3RoPDwzKSAtIGFkdHNIZWFkZXJMZW5ndGggLSAzKTsKICAgICAgICByZXR1cm4gVFJBTlNQT1JUREVDX1VOU1VQUE9SVEVEX0ZPUk1BVDsKICAgICAgfQogICAgICAvKiBlbHNlIHsKICAgICAgICAgSVNPL0lFQyAxMzgxOC03IGltcGxpY2l0IGNoYW5uZWwgbWFwcGluZyBpcyBhbGxvd2VkLgogICAgICAgICBTbyBqdXN0IG9wZW4gdGhlIGJveCBvZiBjaG9jb2xhdGVzIHRvIHNlZSB3aGF0IHdlIGdvdC4KICAgICAgfSAqLwogICAgfQogIH0KI2VuZGlmIC8qIFRQX1BDRV9FTkFCTEUgKi8KCiAgLyogQ29weSBiaXQgc3RyZWFtIGRhdGEgc3RydWN0IHRvIHBlcnNpc3RlbnQgbWVtb3J5IG5vdywgb25jZSB3ZSBwYXNzZWQgYWxsIHNhbml0eSBjaGVja3MgYWJvdmUuICovCiAgRkRLbWVtY3B5KCZwQWR0cy0+YnMsICZicywgc2l6ZW9mKFNUUlVDVF9BRFRTX0JTKSk7CgogIHJldHVybiBUUkFOU1BPUlRERUNfT0s7Cn0KCmludCBhZHRzUmVhZF9HZXRSYXdEYXRhQmxvY2tMZW5ndGgoCiAgICAgICAgSEFORExFX0FEVFMgcEFkdHMsCiAgICAgICAgSU5UICAgICAgICAgYmxvY2tOdW0KICAgICAgICApCnsKICBpbnQgbGVuZ3RoOwoKICBpZiAocEFkdHMtPmJzLm51bV9yYXdfYmxvY2tzID09IDApIHsKICAgIGxlbmd0aCA9IChwQWR0cy0+YnMuZnJhbWVfbGVuZ3RoIC0gNykgPDwgMzsgICAgLyogYWFjX2ZyYW1lX2xlbmd0aCBzdWJ0cmFjdGVkIGJ5IHRoZSBoZWFkZXIgc2l6ZSAoNyBieXRlcykuICovCiAgICBpZiAocEFkdHMtPmJzLnByb3RlY3Rpb25fYWJzZW50ID09IDApCiAgICAgIGxlbmd0aCAtPSAxNjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3Vic3RyYWN0IDE2IGJpdCBDUkMgKi8KICB9IGVsc2UgewogICAgaWYgKHBBZHRzLT5icy5wcm90ZWN0aW9uX2Fic2VudCkgewogICAgICBsZW5ndGggPSAtMTsgLyogcmF3IGRhdGEgYmxvY2sgbGVuZ3RoIGlzIHVua25vd24gKi8KICAgIH0gZWxzZSB7CiAgICAgIGlmIChibG9ja051bSA8IDAgfHwgYmxvY2tOdW0gPiAzKSB7CiAgICAgICAgbGVuZ3RoID0gLTE7CiAgICAgIH0KICAgICAgbGVuZ3RoID0gKHBBZHRzLT5yYXdEYXRhQmxvY2tEaXN0W2Jsb2NrTnVtXSA8PCAzKSAtIDE2OwogICAgfQogIH0KICBpZiAoYmxvY2tOdW0gPT0gMCAmJiBsZW5ndGggPiAwKSB7CiAgICBsZW5ndGggLT0gcEFkdHMtPmJzLm51bV9wY2VfYml0czsKICB9CiAgcmV0dXJuIGxlbmd0aDsKfQoKCg==