Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiEKICBcZmlsZQogIFxicmllZiAgRW52ZWxvcGUgZXh0cmFjdGlvbiAgCiAgVGhlIGZ1bmN0aW9ucyBwcm92aWRlZCBieSB0aGlzIG1vZHVsZSBhcmUgbW9zdGx5IGNhbGxlZCBieSBhcHBseVNCUigpLiBBZnRlciBpdCBpcwogIGRldGVybWluZWQgdGhhdCB0aGVyZSBpcyB2YWxpZCBTQlIgZGF0YSwgc2JyR2V0SGVhZGVyRGF0YSgpIG1pZ2h0IGJlIGNhbGxlZCBpZiB0aGUgY3VycmVudAogIFNCUiBkYXRhIGNvbnRhaW5zIGFuIFxyZWYgU0JSX0hFQURFUl9FTEVNRU5UIGFzIG9wcG9zZWQgdG8gYSBccmVmIFNCUl9TVEFOREFSRF9FTEVNRU5ULiBUaGlzIGZ1bmN0aW9uCiAgbWF5IHJldHVybiB2YXJpb3VzIGVycm9yIGNvZGVzIGFzIGRlZmluZWQgaW4gI1NCUl9IRUFERVJfU1RBVFVTIC4gTW9zdCBpbXBvcnRhbnRseSBpdCByZXR1cm5zIEhFQURFUl9SRVNFVCB3aGVuIGRlY29kZXIKICBzZXR0aW5ncyBuZWVkIHRvIGJlIHJlY2FsY3VsYXRlZCBhY2NvcmRpbmcgdG8gdGhlIFNCUiBzcGVjaWZpY2F0aW9ucy4gSW4gdGhhdCBjYXNlIGFwcGx5U0JSKCkKICB3aWxsIGluaXRpYXRpdGUgdGhlIHJlcXVpcmVkIHJlLWNvbmZpZ3VyYXRpb24uCgogIFRoZSBoZWFkZXIgZGF0YSBpcyBzdG9yZWQgaW4gYSAjU0JSX0hFQURFUl9EQVRBIHN0cnVjdHVyZS4KCiAgVGhlIGFjdHVhbCBTQlIgZGF0YSBmb3IgdGhlIGN1cnJlbnQgZnJhbWUgaXMgZGVjb2RlZCBpbnRvIFNCUl9GUkFNRV9EQVRBIHN0dWN0dXJlcyBieSBzYnJHZXRDaGFubmVsUGFpckVsZW1lbnQoKQogIFtmb3Igc3RlcmVvIHN0cmVhbXNdIGFuZCBzYnJHZXRTaW5nbGVDaGFubmVsRWxlbWVudCgpIFtmb3IgbW9ubyBzdHJlYW1zXS4gVGhlcmUgaXMgbm8gZnJhY3Rpb25hbCBhcml0aG1ldGljIGludm9sdmVkLgoKICBPbmNlIHRoZSBpbmZvcm1hdGlvbiBpcyBleHRyYWN0ZWQsIHRoZSBkYXRhIG5lZWRzIHRvIGJlIGZ1cnRoZXIgcHJlcGFyZWQgYmVmb3JlIHRoZSBhY3R1YWwgZGVjb2RpbmcgcHJvY2Vzcy4KICBUaGlzIGlzIGRvbmUgaW4gZGVjb2RlU2JyRGF0YSgpLgoKICBcc2EgRGVzY3JpcHRpb24gb2YgYnVmZmVyIG1hbmFnZW1lbnQgaW4gYXBwbHlTQlIoKS4gXHJlZiBkb2N1bWVudGF0aW9uT3ZlcnZpZXcKCiAgPGgxPkFib3V0IHRoZSBTQlIgZGF0YSBmb3JtYXQ6PC9oMT4KCiAgRWFjaCBmcmFtZSBpbmNsdWRlcyBTQlIgZGF0YSAoc2lkZSBjaGFpbiBpbmZvcm1hdGlvbiksIGFuZCBjYW4gYmUgZWl0aGVyIHRoZSBccmVmIFNCUl9IRUFERVJfRUxFTUVOVCBvciB0aGUgXHJlZiBTQlJfU1RBTkRBUkRfRUxFTUVOVC4KICBQYXJ0cyBvZiB0aGUgZGF0YSBjYW4gYmUgcHJvdGVjdGVkIGJ5IGEgQ1JDIGNoZWNrc3VtLgoKICBcYW5jaG9yIFNCUl9IRUFERVJfRUxFTUVOVCA8aDI+VGhlIFNCUl9IRUFERVJfRUxFTUVOVDwvaDI+CgogIFRoZSBTQlJfSEVBREVSX0VMRU1FTlQgY2FuIGJlIHRyYW5zbWl0dGVkIHdpdGggZXZlcnkgZnJhbWUsIGhvd2V2ZXIsIGl0IHR5cGljYWxseSBpcyBzZW5kIGV2ZXJ5IHNlY29uZCBvciBzby4gSXQgY29udGFpbnMgZnVuZGFtZW50YWwKICBpbmZvcm1hdGlvbiBzdWNoIGFzIFNCUiBzYW1wbGluZyBmcmVxdWVuY3kgYW5kIGZyZXF1ZW5jeSByYW5nZSBhcyB3ZWxsIGFzIGNvbnRyb2wgc2lnbmFscyB0aGF0IGRvIG5vdCByZXF1aXJlIGZyZXF1ZW50IGNoYW5nZXMuIEl0IGFsc28KICBpbmNsdWRlcyB0aGUgXHJlZiBTQlJfU1RBTkRBUkRfRUxFTUVOVC4KCiAgRGVwZW5kaW5nIG9uIHRoZSBjaGFuZ2VzIGJldHdlZW4gdGhlIGluZm9ybWF0aW9uIGluIGEgY3VycmVudCBTQlJfSEVBREVSX0VMRU1FTlQgYW5kIHRoZSBwcmV2aW91cyBTQlJfSEVBREVSX0VMRU1FTlQsIHRoZSBTQlIgZGVjb2RlciBtaWdodCBuZWVkCiAgdG8gYmUgcmVzZXQgYW5kIHJlY29uZmlndXJlZCAoZS5nLiBuZXcgdGFibGVzIG5lZWQgdG8gYmUgY2FsY3VsYXRlZCkuCgogIFxhbmNob3IgU0JSX1NUQU5EQVJEX0VMRU1FTlQgPGgyPlRoZSBTQlJfU1RBTkRBUkRfRUxFTUVOVDwvaDI+CgogIFRoaXMgZGF0YSBjYW4gYmUgc3ViZGl2aWRlZCBpbnRvICJzaWRlIGluZm8iIGFuZCAicmF3IGRhdGEiLCB3aGVyZSBzaWRlIGluZm8gaXMgZGVmaW5lZCBhcyBzaWduYWxzIG5lZWRlZCB0byBkZWNvZGUgdGhlIHJhdyBkYXRhCiAgYW5kIHNvbWUgZGVjb2RlciB0dW5pbmcgc2lnbmFscy4gUmF3IGRhdGEgaXMgcmVmZXJyZWQgdG8gYXMgUENNIGFuZCBIdWZmbWFuIGNvZGVkIGVudmVsb3BlIGFuZCBub2lzZSBmbG9vciBlc3RpbWF0ZXMuIFRoZSBzaWRlIGluZm8gYWxzbwogIGluY2x1ZGVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSB0aW1lLWZyZXF1ZW5jeSBncmlkIGZvciB0aGUgY3VycmVudCBmcmFtZS4KCiAgXHNhIFxyZWYgZG9jdW1lbnRhdGlvbk92ZXJ2aWV3CiovCgojaW5jbHVkZSAiZW52X2V4dHIuaCIKCiNpbmNsdWRlICJzYnJfcmFtLmgiCiNpbmNsdWRlICJzYnJfcm9tLmgiCiNpbmNsdWRlICJodWZmX2RlYy5oIgoKCiNpbmNsdWRlICJwc2JpdGRlYy5oIgoKI2RlZmluZSBEUk1fUEFSQU1FVFJJQ19TVEVSRU8gICAwCiNkZWZpbmUgRVhURU5TSU9OX0lEX1BTX0NPRElORyAgMgoKCnN0YXRpYyBpbnQgZXh0cmFjdEZyYW1lSW5mbyAoSEFORExFX0ZES19CSVRTVFJFQU0gICBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgIGhfZnJhbWVfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVSU5UICAgICAgICAgICAgIG5yT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVSU5UICAgICAgICAgICAgIGZsYWdzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwoKCnN0YXRpYyBpbnQgc2JyR2V0RW52ZWxvcGUgKEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSAgaF9mcmFtZV9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUlOVCBmbGFncyk7CgpzdGF0aWMgdm9pZCBzYnJHZXREaXJlY3Rpb25Db250cm9sRGF0YSAoSEFORExFX1NCUl9GUkFNRV9EQVRBIGhGcmFtZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMpOwoKc3RhdGljIHZvaWQgc2JyR2V0Tm9pc2VGbG9vckRhdGEgKEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgIGhfZnJhbWVfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNICAgaEJzKTsKCnN0YXRpYyBpbnQgY2hlY2tGcmFtZUluZm8gKEZSQU1FX0lORk8gKnBGcmFtZUluZm8sIGludCBudW1iZXJPZlRpbWVTbG90cywgaW50IG92ZXJsYXAsIGludCB0aW1lU3RlcCk7CgpTQlJfRVJST1IKaW5pdEhlYWRlckRhdGEgKAogICAgICAgIEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgIGhIZWFkZXJEYXRhLAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgICAgIHNhbXBsZVJhdGVJbiwKICAgICAgICBjb25zdCBpbnQgICAgICAgICAgICAgICBzYW1wbGVSYXRlT3V0LAogICAgICAgIGNvbnN0IGludCAgICAgICAgICAgICAgIHNhbXBsZXNQZXJGcmFtZSwKICAgICAgICBjb25zdCBVSU5UICAgICAgICAgICAgICBmbGFncwogICAgICAgICkKewogIEhBTkRMRV9GUkVRX0JBTkRfREFUQSBoRnJlcSA9ICZoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhOwogIFNCUl9FUlJPUiBzYnJFcnJvciA9IFNCUkRFQ19PSzsKICBpbnQgbnVtQW5hbHlzaXNCYW5kczsKCiAgaWYgKCBzYW1wbGVSYXRlSW4gPT0gc2FtcGxlUmF0ZU91dCApIHsKICAgIGhIZWFkZXJEYXRhLT5zYnJQcm9jU21wbFJhdGUgPSBzYW1wbGVSYXRlT3V0PDwxOwogICAgbnVtQW5hbHlzaXNCYW5kcyA9IDMyOwogIH0gZWxzZSB7CiAgICBoSGVhZGVyRGF0YS0+c2JyUHJvY1NtcGxSYXRlID0gc2FtcGxlUmF0ZU91dDsKICAgIGlmICggKHNhbXBsZVJhdGVPdXQ+PjEpID09IHNhbXBsZVJhdGVJbikgewogICAgICAvKiAxOjIgKi8KICAgICAgbnVtQW5hbHlzaXNCYW5kcyA9IDMyOwogICAgfSBlbHNlIGlmICggKHNhbXBsZVJhdGVPdXQ+PjIpID09IHNhbXBsZVJhdGVJbiApIHsKICAgICAgLyogMTo0ICovCiAgICAgIG51bUFuYWx5c2lzQmFuZHMgPSAzMjsKICAgIH0gZWxzZSBpZiAoIChzYW1wbGVSYXRlT3V0KjMpPj4zID09IChzYW1wbGVSYXRlSW4qOCk+PjMgKSB7CiAgICAgIC8qIDM6OCwgMy80IGNvcmUgZnJhbWUgbGVuZ3RoICovCiAgICAgIG51bUFuYWx5c2lzQmFuZHMgPSAyNDsKICAgIH0gZWxzZSB7CiAgICAgIHNickVycm9yID0gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgICAgZ290byBiYWlsOwogICAgfQogIH0KCiAgLyogRmlsbCBpbiBkZWZhdWx0IHZhbHVlcyBmaXJzdCAqLwogIGhIZWFkZXJEYXRhLT5zeW5jU3RhdGUgICAgICAgICAgPSBTQlJfTk9UX0lOSVRJQUxJWkVEOwogIGhIZWFkZXJEYXRhLT5zdGF0dXMgICAgICAgICAgICAgPSAwOwogIGhIZWFkZXJEYXRhLT5mcmFtZUVycm9yRmxhZyAgICAgPSAwOwoKICBoSGVhZGVyRGF0YS0+YnNfaW5mby5hbXBSZXNvbHV0aW9uICAgICA9IDE7CiAgaEhlYWRlckRhdGEtPmJzX2luZm8ueG92ZXJfYmFuZCAgICAgICAgPSAwOwogIGhIZWFkZXJEYXRhLT5ic19pbmZvLnNicl9wcmVwcm9jZXNzaW5nID0gMDsKCiAgaEhlYWRlckRhdGEtPmJzX2RhdGEuc3RhcnRGcmVxICAgICAgID0gNTsKICBoSGVhZGVyRGF0YS0+YnNfZGF0YS5zdG9wRnJlcSAgICAgICAgPSAwOwogIGhIZWFkZXJEYXRhLT5ic19kYXRhLmZyZXFTY2FsZSAgICAgICA9IDI7CiAgaEhlYWRlckRhdGEtPmJzX2RhdGEuYWx0ZXJTY2FsZSAgICAgID0gMTsKICBoSGVhZGVyRGF0YS0+YnNfZGF0YS5ub2lzZV9iYW5kcyAgICAgPSAyOwogIGhIZWFkZXJEYXRhLT5ic19kYXRhLmxpbWl0ZXJCYW5kcyAgICA9IDI7CiAgaEhlYWRlckRhdGEtPmJzX2RhdGEubGltaXRlckdhaW5zICAgID0gMjsKICBoSGVhZGVyRGF0YS0+YnNfZGF0YS5pbnRlcnBvbEZyZXEgICAgPSAxOwogIGhIZWFkZXJEYXRhLT5ic19kYXRhLnNtb290aGluZ0xlbmd0aCA9IDE7CgogIGhIZWFkZXJEYXRhLT50aW1lU3RlcCA9IChmbGFncyAmIFNCUkRFQ19FTERfR1JJRCkgPyAxIDogMjsKCiAgLyogU2V0dXAgcG9pbnRlcnMgdG8gZnJlcXVlbmN5IGJhbmQgdGFibGVzICovCiAgaEZyZXEtPmZyZXFCYW5kVGFibGVbMF0gID0gaEZyZXEtPmZyZXFCYW5kVGFibGVMbzsKICBoRnJlcS0+ZnJlcUJhbmRUYWJsZVsxXSA9IGhGcmVxLT5mcmVxQmFuZFRhYmxlSGk7CgogIC8qIFBhdGNoIHNvbWUgZW50cmllcyAqLwogIGlmIChzYW1wbGVSYXRlT3V0ID4gMjQwMDApIHsgICAgLyogVHJpZ2dlciBhbiBlcnJvciBpZiBTQlIgaXMgZ29pbmcgdG8gYmUgcHJvY2Vzc2VkIHdpdGhvdXQgICAgICovCiAgICBoSGVhZGVyRGF0YS0+YnNfZGF0YS5zdGFydEZyZXEgPSA3OyAgIC8qICAgaGF2aW5nIHJlYWQgdGhlc2UgZnJlcXVlbmN5IHZhbHVlcyBmcm9tIGJpdCBzdHJlYW0gYmVmb3JlLiAqLwogICAgaEhlYWRlckRhdGEtPmJzX2RhdGEuc3RvcEZyZXEgID0gMzsKICB9CgogIC8qIE9uZSBTQlIgdGltZXNsb3QgY29ycmVzcG9uZHMgdG8gdGhlIGFtb3VudCBvZiBzYW1wbGVzIGVxdWFsIHRvIHRoZSBhbW91bnQgb2YgYW5hbHlzaXMgYmFuZHMsIGRpdmlkZWQgYnkgdGhlIHRpbWVzdGVwLiAqLwogIGhIZWFkZXJEYXRhLT5udW1iZXJUaW1lU2xvdHMgPSAoc2FtcGxlc1BlckZyYW1lL251bUFuYWx5c2lzQmFuZHMpID4+IChoSGVhZGVyRGF0YS0+dGltZVN0ZXAgLSAxKTsKICBpZiAoaEhlYWRlckRhdGEtPm51bWJlclRpbWVTbG90cyA+ICgxNikpIHsKICAgIHNickVycm9yID0gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICB9CgogIGhIZWFkZXJEYXRhLT5udW1iZXJPZkFuYWx5c2lzQmFuZHMgPSBudW1BbmFseXNpc0JhbmRzOwoKYmFpbDoKICByZXR1cm4gc2JyRXJyb3I7Cn0KCgovKiEKICBcYnJpZWYgICBJbml0aWFsaXplIHRoZSBTQlJfUFJFVl9GUkFNRV9EQVRBIHN0cnVjdAoqLwp2b2lkCmluaXRTYnJQcmV2RnJhbWVEYXRhIChIQU5ETEVfU0JSX1BSRVZfRlJBTUVfREFUQSBoX3ByZXZfZGF0YSwgLyohPCBoYW5kbGUgdG8gc3RydWN0IFNCUl9QUkVWX0ZSQU1FX0RBVEEgKi8KICAgICAgICAgICAgICAgICAgICAgIGludCB0aW1lU2xvdHMpICAgICAgICAgICAgICAgICAgICAgICAgICAvKiE8IEZyYW1lbGVuZ3RoIGluIFNCUi10aW1lc2xvdHMgKi8KewogIGludCBpOwoKICAvKiBTZXQgcHJldmlvdXMgZW5lcmd5IGFuZCBub2lzZSBsZXZlbHMgdG8gMCBmb3IgdGhlIGNhc2UKICAgICB0aGF0IGRlY29kaW5nIHN0YXJ0cyBpbiB0aGUgbWlkZGxlIG9mIGEgYml0c3RyZWFtICovCiAgZm9yIChpPTA7IGkgPCBNQVhfRlJFUV9DT0VGRlM7IGkrKykKICAgIGhfcHJldl9kYXRhLT5zZmJfbnJnX3ByZXZbaV0gPSAoRklYUF9EQkwpMDsKICBmb3IgKGk9MDsgaSA8IE1BWF9OT0lTRV9DT0VGRlM7IGkrKykKICAgIGhfcHJldl9kYXRhLT5wcmV2Tm9pc2VMZXZlbFtpXSA9IChGSVhQX0RCTCkwOwogIGZvciAoaT0wOyBpIDwgTUFYX0lOVkZfQkFORFM7IGkrKykKICAgIGhfcHJldl9kYXRhLT5zYnJfaW52Zl9tb2RlW2ldID0gSU5WRl9PRkY7CgogIGhfcHJldl9kYXRhLT5zdG9wUG9zID0gdGltZVNsb3RzOwogIGhfcHJldl9kYXRhLT5jb3VwbGluZyA9IENPVVBMSU5HX09GRjsKICBoX3ByZXZfZGF0YS0+YW1wUmVzID0gMDsKfQoKCi8qIQogIFxicmllZiAgIFJlYWQgaGVhZGVyIGRhdGEgZnJvbSBiaXRzdHJlYW0KCiAgXHJldHVybiAgZXJyb3Igc3RhdHVzIC0gMCBpZiBvawoqLwpTQlJfSEVBREVSX1NUQVRVUwpzYnJHZXRIZWFkZXJEYXRhIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLAogICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgIGhCcywKICAgICAgICAgICAgICAgICAgY29uc3QgVUlOVCAgICAgICAgICAgICBmbGFncywKICAgICAgICAgICAgICAgICAgY29uc3QgaW50ICAgICAgICAgICAgICBmSXNTYnJEYXRhKQp7CiAgU0JSX0hFQURFUl9EQVRBX0JTICpwQnNEYXRhOwogIFNCUl9IRUFERVJfREFUQV9CUyBsYXN0SGVhZGVyOwogIFNCUl9IRUFERVJfREFUQV9CU19JTkZPIGxhc3RJbmZvOwogIGludCBoZWFkZXJFeHRyYTE9MCwgaGVhZGVyRXh0cmEyPTA7CgogIC8qIENvcHkgU0JSIGJpdCBzdHJlYW0gaGVhZGVyIHRvIHRlbXBvcmFyeSBoZWFkZXIgKi8KICBsYXN0SGVhZGVyID0gaEhlYWRlckRhdGEtPmJzX2RhdGE7CiAgbGFzdEluZm8gICA9IGhIZWFkZXJEYXRhLT5ic19pbmZvOwoKICAvKiBSZWFkIG5ldyBoZWFkZXIgZnJvbSBiaXRzdHJlYW0gKi8KICB7CiAgICBwQnNEYXRhID0gJmhIZWFkZXJEYXRhLT5ic19kYXRhOwogIH0KCiAgewogICAgaEhlYWRlckRhdGEtPmJzX2luZm8uYW1wUmVzb2x1dGlvbiA9IEZES3JlYWRCaXRzIChoQnMsIDEpOwogIH0KCiAgcEJzRGF0YS0+c3RhcnRGcmVxID0gRkRLcmVhZEJpdHMgKGhCcywgNCk7CiAgcEJzRGF0YS0+c3RvcEZyZXEgPSBGREtyZWFkQml0cyAoaEJzLCA0KTsKCiAgewogICAgaEhlYWRlckRhdGEtPmJzX2luZm8ueG92ZXJfYmFuZCA9IEZES3JlYWRCaXRzIChoQnMsIDMpOwogICAgRkRLcmVhZEJpdHMgKGhCcywgMik7CiAgfQoKICBoZWFkZXJFeHRyYTEgPSBGREtyZWFkQml0cyAoaEJzLCAxKTsKICBoZWFkZXJFeHRyYTIgPSBGREtyZWFkQml0cyAoaEJzLCAxKTsKCiAgLyogSGFuZGxlIGV4dHJhIGhlYWRlciBpbmZvcm1hdGlvbiAqLwogIGlmKCBoZWFkZXJFeHRyYTEpIAogIHsKICAgIHBCc0RhdGEtPmZyZXFTY2FsZSA9IEZES3JlYWRCaXRzIChoQnMsIDIpOwogICAgcEJzRGF0YS0+YWx0ZXJTY2FsZSA9IEZES3JlYWRCaXRzIChoQnMsIDEpOwogICAgcEJzRGF0YS0+bm9pc2VfYmFuZHMgPSBGREtyZWFkQml0cyAoaEJzLCAyKTsKICB9CiAgZWxzZSB7CiAgICBwQnNEYXRhLT5mcmVxU2NhbGUgICA9IDI7CiAgICBwQnNEYXRhLT5hbHRlclNjYWxlICA9IDE7CiAgICBwQnNEYXRhLT5ub2lzZV9iYW5kcyA9IDI7CiAgfQoKICBpZiAoaGVhZGVyRXh0cmEyKSB7CiAgICBwQnNEYXRhLT5saW1pdGVyQmFuZHMgPSBGREtyZWFkQml0cyAoaEJzLCAyKTsKICAgIHBCc0RhdGEtPmxpbWl0ZXJHYWlucyA9IEZES3JlYWRCaXRzIChoQnMsIDIpOwogICAgcEJzRGF0YS0+aW50ZXJwb2xGcmVxID0gRkRLcmVhZEJpdHMgKGhCcywgMSk7CiAgICBwQnNEYXRhLT5zbW9vdGhpbmdMZW5ndGggPSBGREtyZWFkQml0cyAoaEJzLCAxKTsKICB9CiAgZWxzZSB7CiAgICBwQnNEYXRhLT5saW1pdGVyQmFuZHMgICAgPSAyOwogICAgcEJzRGF0YS0+bGltaXRlckdhaW5zICAgID0gMjsKICAgIHBCc0RhdGEtPmludGVycG9sRnJlcSAgICA9IDE7CiAgICBwQnNEYXRhLT5zbW9vdGhpbmdMZW5ndGggPSAxOwogIH0KCiAgLyogTG9vayBmb3IgbmV3IHNldHRpbmdzLiBJRUMgMTQ0OTYtMywgNC42LjE4LjMuMSAqLwogIGlmKGhIZWFkZXJEYXRhLT5zeW5jU3RhdGUgIT0gU0JSX0FDVElWRSB8fAogICAgIGxhc3RIZWFkZXIuc3RhcnRGcmVxICAgIT0gcEJzRGF0YS0+c3RhcnRGcmVxICAgfHwKICAgICBsYXN0SGVhZGVyLnN0b3BGcmVxICAgICE9IHBCc0RhdGEtPnN0b3BGcmVxICAgIHx8CiAgICAgbGFzdEhlYWRlci5mcmVxU2NhbGUgICAhPSBwQnNEYXRhLT5mcmVxU2NhbGUgICB8fAogICAgIGxhc3RIZWFkZXIuYWx0ZXJTY2FsZSAgIT0gcEJzRGF0YS0+YWx0ZXJTY2FsZSAgfHwKICAgICBsYXN0SGVhZGVyLm5vaXNlX2JhbmRzICE9IHBCc0RhdGEtPm5vaXNlX2JhbmRzIHx8CiAgICAgbGFzdEluZm8ueG92ZXJfYmFuZCAgICAhPSBoSGVhZGVyRGF0YS0+YnNfaW5mby54b3Zlcl9iYW5kKSB7CiAgICByZXR1cm4gSEVBREVSX1JFU0VUOyAvKiBOZXcgc2V0dGluZ3MgKi8KICB9CgogIHJldHVybiBIRUFERVJfT0s7Cn0KCi8qIQogIFxicmllZiAgIEdldCBtaXNzaW5nIGhhcm1vbmljcyBwYXJhbWV0ZXJzIChvbmx5IHVzZWQgZm9yIEFBQytTQlIpCgogIFxyZXR1cm4gIGVycm9yIHN0YXR1cyAtIDAgaWYgb2sKKi8KaW50CnNickdldFN5bnRoZXRpY0NvZGVkRGF0YShIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBICBoRnJhbWVEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gICBoQnMpCnsKICBpbnQgaSwgYml0c1JlYWQgPSAwOwoKICBpbnQgZmxhZyA9IEZES3JlYWRCaXRzKGhCcywxKTsKICBiaXRzUmVhZCsrOwoKICBpZihmbGFnKXsKICAgIGZvcihpPTA7aTxoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5TZmJbMV07aSsrKXsKICAgICAgaEZyYW1lRGF0YS0+YWRkSGFybW9uaWNzW2ldICA9IEZES3JlYWRCaXRzIChoQnMsIDEgKTsKICAgICAgYml0c1JlYWQrKzsKICAgIH0KICB9CiAgZWxzZSB7CiAgICBmb3IoaT0wOyBpPE1BWF9GUkVRX0NPRUZGUzsgaSsrKQogICAgICBoRnJhbWVEYXRhLT5hZGRIYXJtb25pY3NbaV0gID0gMDsKICB9CiAgcmV0dXJuKGJpdHNSZWFkKTsKfQoKLyohCiAgXGJyaWVmICAgICAgUmVhZHMgZXh0ZW5zaW9uIGRhdGEgZnJvbSB0aGUgYml0c3RyZWFtCgogIFRoZSBiaXRzdHJlYW0gZm9ybWF0IGFsbG93cyB1cCB0byA0IGtpbmRzIG9mIGV4dGVuZGVkIGRhdGEgZWxlbWVudC4KICBFeHRlbmRlZCBkYXRhIG1heSBjb250YWluIHNldmVyYWwgZWxlbWVudHMsIGVhY2ggaWRlbnRpZmllZCBieSBhIDItYml0LUlELgogIFNvIGZhciwgbm8gZXh0ZW5kZWQgZGF0YSBlbGVtZW50cyBhcmUgZGVmaW5lZCBoZW5jZSB0aGUgZmlyc3QgMiBwYXJhbWV0ZXJzCiAgYXJlIHVudXNlZC4gVGhlIGRhdGEgc2hvdWxkIGJlIHNraXBwZWQgaW4gb3JkZXIgdG8gdXBkYXRlIHRoZSBudW1iZXIKICBvZiByZWFkIGJpdHMgZm9yIHRoZSBjb25zaXN0ZW5jeSBjaGVjayBpbiBhcHBseVNCUigpLgoqLwpzdGF0aWMgaW50ICBleHRyYWN0RXh0ZW5kZWREYXRhKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsICAgIC8qITwgaGFuZGxlIHRvIFNCUiBoZWFkZXIgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgIGhCcyAgICAgICAgICAgICAvKiE8IEhhbmRsZSB0byB0aGUgYml0IGJ1ZmZlciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLEhBTkRMRV9QU19ERUMgaFBhcmFtZXRyaWNTdGVyZW9EZWMgICAgIC8qITwgUGFyYW1ldHJpYyBTdGVyZW8gRGVjb2RlciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgewogIElOVCBuQml0c0xlZnQ7CiAgaW50IGV4dGVuZGVkX2RhdGE7CiAgaW50IGksIGZyYW1lT2sgPSAxOwoKCiAgZXh0ZW5kZWRfZGF0YSA9IEZES3JlYWRCaXRzKGhCcywgMSk7CgogIGlmIChleHRlbmRlZF9kYXRhKSB7CiAgICBpbnQgY250OwogICAgaW50IGJQc1JlYWQgPSAwOwoKICAgIGNudCA9IEZES3JlYWRCaXRzKGhCcywgNCk7CiAgICBpZiAoY250ID09ICgxPDw0KS0xKQogICAgICBjbnQgKz0gRkRLcmVhZEJpdHMoaEJzLCA4KTsKCgogICAgbkJpdHNMZWZ0ID0gOCAqIGNudDsKCiAgICAvKiBzYW5pdHkgY2hlY2sgZm9yIGNudCAqLwogICAgaWYgKG5CaXRzTGVmdCA+IChJTlQpRkRLZ2V0VmFsaWRCaXRzKGhCcykpIHsKICAgICAgLyogbGltaXQgbkJpdHNMZWZ0ICovCiAgICAgIG5CaXRzTGVmdCA9IChJTlQpRkRLZ2V0VmFsaWRCaXRzKGhCcyk7CiAgICAgIC8qIHNldCBmcmFtZSBlcnJvciAqLwogICAgICBmcmFtZU9rID0gMDsKICAgIH0KCiAgICB3aGlsZSAobkJpdHNMZWZ0ID4gNykgewogICAgICBpbnQgZXh0ZW5zaW9uX2lkID0gRkRLcmVhZEJpdHMoaEJzLCAyKTsKICAgICAgbkJpdHNMZWZ0IC09IDI7CgogICAgICBzd2l0Y2goZXh0ZW5zaW9uX2lkKSB7CgoKCiAgICAgICAgY2FzZSBFWFRFTlNJT05fSURfUFNfQ09ESU5HOgoKICAgICAgICAvKiBSZWFkIFBTIGRhdGEgZnJvbSBiaXRzdHJlYW0gKi8KCiAgICAgICAgaWYgKGhQYXJhbWV0cmljU3RlcmVvRGVjICE9IE5VTEwpIHsKICAgICAgICAgIGlmKGJQc1JlYWQgJiYgIWhQYXJhbWV0cmljU3RlcmVvRGVjLT5ic0RhdGFbaFBhcmFtZXRyaWNTdGVyZW9EZWMtPmJzUmVhZFNsb3RdLm1wZWcuYlBzSGVhZGVyVmFsaWQpIHsKICAgICAgICAgICAgY250ID0gbkJpdHNMZWZ0ID4+IDM7IC8qIG51bWJlciBvZiByZW1haW5pbmcgYnl0ZXMgKi8KICAgICAgICAgICAgZm9yIChpPTA7IGk8Y250OyBpKyspCiAgICAgICAgICAgICAgRkRLcmVhZEJpdHMoaEJzLCA4KTsKICAgICAgICAgICAgbkJpdHNMZWZ0IC09IGNudCAqIDg7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBuQml0c0xlZnQgLT0gUmVhZFBzRGF0YShoUGFyYW1ldHJpY1N0ZXJlb0RlYywgaEJzLCBuQml0c0xlZnQpOwogICAgICAgICAgICBiUHNSZWFkID0gMTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICAgLyogcGFyYW1ldHJpYyBzdGVyZW8gZGV0ZWN0ZWQsIGNvdWxkIHNldCBjaGFubmVsTW9kZSBhY2NvcmRpbmdseSBoZXJlICAqLwogICAgICAgICAgLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgLyogIlRoZSB1c2FnZSBvZiB0aGlzIHBhcmFtZXRyaWMgc3RlcmVvIGV4dGVuc2lvbiB0byBIRS1BQUMgaXMgICAgICAgICAqLwogICAgICAgICAgLyogc2lnbmFsbGVkIGltcGxpY2l0bHkgaW4gdGhlIGJpdHN0cmVhbS4gSGVuY2UsIGlmIGFuIHNicl9leHRlbnNpb24oKSAqLwogICAgICAgICAgLyogd2l0aCBic19leHRlbnNpb25faWQ9PUVYVEVOU0lPTl9JRF9QUyBpcyBmb3VuZCBpbiB0aGUgU0JSIHBhcnQgb2YgICAqLwogICAgICAgICAgLyogdGhlIGJpdHN0cmVhbSwgYSBkZWNvZGVyIHN1cHBvcnRpbmcgdGhlIGNvbWJpbmF0aW9uIG9mIFNCUiBhbmQgUFMgICAqLwogICAgICAgICAgLyogc2hhbGwgb3BlcmF0ZSB0aGUgUFMgdG9vbCB0byBnZW5lcmF0ZSBhIHN0ZXJlbyBvdXRwdXQgc2lnbmFsLiIgICAgICAqLwogICAgICAgICAgLyogc291cmNlOiBJU08vSUVDIDE0NDk2LTM6MjAwMS9GREFNIDI6MjAwNChFKSAgICAgICAgICAgICAgICAgICAgICAgICAqLwoKICAgICAgICBicmVhazsKCgogICAgICBkZWZhdWx0OgogICAgICAgIGNudCA9IG5CaXRzTGVmdCA+PiAzOyAvKiBudW1iZXIgb2YgcmVtYWluaW5nIGJ5dGVzICovCiAgICAgICAgZm9yIChpPTA7IGk8Y250OyBpKyspCiAgICAgICAgICBGREtyZWFkQml0cyhoQnMsIDgpOwogICAgICAgIG5CaXRzTGVmdCAtPSBjbnQgKiA4OwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CgogICAgaWYgKG5CaXRzTGVmdCA8IDApIHsKICAgICAgZnJhbWVPayA9IDA7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBSZWFkIGZpbGwgYml0cyBmb3IgYnl0ZSBhbGlnbm1lbnQgKi8KICAgICAgRkRLcmVhZEJpdHMoaEJzLCBuQml0c0xlZnQpOwogICAgfQogIH0KCmJhaWw6CiAgcmV0dXJuIChmcmFtZU9rKTsKfQoKCi8qIQogIFxicmllZiAgIFJlYWQgYml0c3RyZWFtIGVsZW1lbnRzIG9mIG9uZSBjaGFubmVsCgogIFxyZXR1cm4gIFNickZyYW1lT0s6ICAxPW9rLCAwPWVycm9yCiovCmludApzYnJHZXRTaW5nbGVDaGFubmVsRWxlbWVudCAoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwgICAgICAgICAgLyohPCBTdGF0aWMgY29udHJvbCBkYXRhICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgIGhGcmFtZURhdGEsICAgICAgICAgICAvKiE8IENvbnRyb2wgZGF0YSBvZiBjdXJyZW50IGZyYW1lICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgIGhCcywgICAgICAgICAgICAgICAgICAvKiE8IEhhbmRsZSB0byBzdHJ1Y3QgQklUX0JVRiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1BTX0RFQyAgICAgICAgICBoUGFyYW1ldHJpY1N0ZXJlb0RlYywgLyohPCBIYW5kbGUgdG8gUFMgZGVjb2RlciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUlOVCAgICAgICAgICAgICBmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludCAgICAgICAgICAgICAgb3ZlcmxhcAogICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICBpbnQgaTsKCgogIGhGcmFtZURhdGEtPmNvdXBsaW5nID0gQ09VUExJTkdfT0ZGOwoKICB7CiAgICAvKiBSZXNlcnZlZCBiaXRzICovCiAgICBpZiAoRkRLcmVhZEJpdHMoaEJzLCAxKSkgeyAgLyogYnNfZGF0YV9leHRyYSAqLwogICAgICBGREtyZWFkQml0cyhoQnMsIDQpOwogICAgICBpZiAoZmxhZ3MgJiBTQlJERUNfU1lOVEFYX1NDQUwpIHsKICAgICAgICBGREtyZWFkQml0cyhoQnMsIDQpOwogICAgICB9CiAgICB9CiAgfQoKICBpZiAoZmxhZ3MgJiBTQlJERUNfU1lOVEFYX1NDQUwpIHsKICAgIEZES3JlYWRCaXRzIChoQnMsIDEpOyAgICAgLyogYnNfY291cGxpbmcgKi8KICB9CgogIC8qCiAgICBHcmlkIGNvbnRyb2wKICAqLwogIGlmICggIWV4dHJhY3RGcmFtZUluZm8gKCBoQnMsIGhIZWFkZXJEYXRhLCBoRnJhbWVEYXRhLCAxLCBmbGFncykgKQogICByZXR1cm4gMDsKCiAgaWYgKCAhY2hlY2tGcmFtZUluZm8gKCZoRnJhbWVEYXRhLT5mcmFtZUluZm8sIGhIZWFkZXJEYXRhLT5udW1iZXJUaW1lU2xvdHMsIG92ZXJsYXAsIGhIZWFkZXJEYXRhLT50aW1lU3RlcCkgKQogICAgcmV0dXJuIDA7CgoKICAvKgogICAgRmV0Y2ggZG9tYWluIHZlY3RvcnMgKHRpbWUgb3IgZnJlcXVlbmN5IGRpcmVjdGlvbiBmb3IgZGVsdGEtY29kaW5nKQogICovCiAgc2JyR2V0RGlyZWN0aW9uQ29udHJvbERhdGEgKGhGcmFtZURhdGEsIGhCcyk7CgogIGZvciAoaT0wOyBpPGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEubkludmZCYW5kczsgaSsrKSB7CiAgICBoRnJhbWVEYXRhLT5zYnJfaW52Zl9tb2RlW2ldID0KICAgICAgKElOVkZfTU9ERSkgRkRLcmVhZEJpdHMgKGhCcywgMik7CiAgfQoKCgogIC8qIHJhdyBkYXRhICovCiAgaWYgKCAhc2JyR2V0RW52ZWxvcGUgKGhIZWFkZXJEYXRhLCBoRnJhbWVEYXRhLCBoQnMsIGZsYWdzKSApCiAgICByZXR1cm4gMDsKCgogIHNickdldE5vaXNlRmxvb3JEYXRhIChoSGVhZGVyRGF0YSwgaEZyYW1lRGF0YSwgaEJzKTsKCiAgc2JyR2V0U3ludGhldGljQ29kZWREYXRhKGhIZWFkZXJEYXRhLCBoRnJhbWVEYXRhLCBoQnMpOwoKICB7CiAgICAvKiBzYnIgZXh0ZW5kZWQgZGF0YSAqLwogICAgaWYgKCEgZXh0cmFjdEV4dGVuZGVkRGF0YSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhIZWFkZXJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxoUGFyYW1ldHJpY1N0ZXJlb0RlYwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkgewogICAgICByZXR1cm4gMDsKICAgIH0KICB9CgogIHJldHVybiAxOwp9CgoKCi8qIQogIFxicmllZiAgICAgIFJlYWQgYml0c3RyZWFtIGVsZW1lbnRzIG9mIGEgY2hhbm5lbCBwYWlyCiAgXHJldHVybiAgICAgU2JyRnJhbWVPSwoqLwppbnQKc2JyR2V0Q2hhbm5lbFBhaXJFbGVtZW50IChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLCAgICAvKiE8IFN0YXRpYyBjb250cm9sIGRhdGEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgIGhGcmFtZURhdGFMZWZ0LCAvKiE8IER5bmFtaWMgY29udHJvbCBkYXRhIGZvciBmaXJzdCBjaGFubmVsICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBICBoRnJhbWVEYXRhUmlnaHQsLyohPCBEeW5hbWljIGNvbnRyb2wgZGF0YSBmb3Igc2Vjb25kIGNoYW5uZWwgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgIGhCcywgICAgICAgICAgICAvKiE8IGhhbmRsZSB0byBzdHJ1Y3QgQklUX0JVRiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVJTlQgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IG92ZXJsYXAgKQp7CiAgaW50IGksIGJpdDsKCgogIC8qIFJlc2VydmVkIGJpdHMgKi8KICBpZiAoRkRLcmVhZEJpdHMoaEJzLCAxKSkgeyAgLyogYnNfZGF0YV9leHRyYSAqLwogICAgRkRLcmVhZEJpdHMoaEJzLCA0KTsKICAgIEZES3JlYWRCaXRzKGhCcywgNCk7CiAgfQoKICAvKiBSZWFkIGNvdXBsaW5nIGZsYWcgKi8KICBiaXQgPSBGREtyZWFkQml0cyAoaEJzLCAxKTsKCiAgaWYgKGJpdCkgewogICAgaEZyYW1lRGF0YUxlZnQtPmNvdXBsaW5nID0gQ09VUExJTkdfTEVWRUw7CiAgICBoRnJhbWVEYXRhUmlnaHQtPmNvdXBsaW5nID0gQ09VUExJTkdfQkFMOwogIH0KICBlbHNlIHsKICAgIGhGcmFtZURhdGFMZWZ0LT5jb3VwbGluZyA9IENPVVBMSU5HX09GRjsKICAgIGhGcmFtZURhdGFSaWdodC0+Y291cGxpbmcgPSBDT1VQTElOR19PRkY7CiAgfQoKCiAgLyoKICAgIEdyaWQgY29udHJvbAogICovCiAgaWYgKCAhZXh0cmFjdEZyYW1lSW5mbyAoaEJzLCBoSGVhZGVyRGF0YSwgaEZyYW1lRGF0YUxlZnQsIDIsIGZsYWdzKSApCiAgICByZXR1cm4gMDsKCiAgaWYgKCAhY2hlY2tGcmFtZUluZm8gKCZoRnJhbWVEYXRhTGVmdC0+ZnJhbWVJbmZvLCBoSGVhZGVyRGF0YS0+bnVtYmVyVGltZVNsb3RzLCBvdmVybGFwLCBoSGVhZGVyRGF0YS0+dGltZVN0ZXApICkKICAgIHJldHVybiAwOwoKICBpZiAoaEZyYW1lRGF0YUxlZnQtPmNvdXBsaW5nKSB7CiAgICBGREttZW1jcHkgKCZoRnJhbWVEYXRhUmlnaHQtPmZyYW1lSW5mbywgJmhGcmFtZURhdGFMZWZ0LT5mcmFtZUluZm8sIHNpemVvZihGUkFNRV9JTkZPKSk7CiAgICBoRnJhbWVEYXRhUmlnaHQtPmFtcFJlc29sdXRpb25DdXJyZW50RnJhbWUgPSBoRnJhbWVEYXRhTGVmdC0+YW1wUmVzb2x1dGlvbkN1cnJlbnRGcmFtZTsKICB9CiAgZWxzZSB7CiAgICBpZiAoICFleHRyYWN0RnJhbWVJbmZvIChoQnMsIGhIZWFkZXJEYXRhLCBoRnJhbWVEYXRhUmlnaHQsIDIsIGZsYWdzKSApCiAgICAgIHJldHVybiAwOwoKICAgIGlmICggIWNoZWNrRnJhbWVJbmZvICgmaEZyYW1lRGF0YVJpZ2h0LT5mcmFtZUluZm8sIGhIZWFkZXJEYXRhLT5udW1iZXJUaW1lU2xvdHMsIG92ZXJsYXAsIGhIZWFkZXJEYXRhLT50aW1lU3RlcCkgKQogICAgICByZXR1cm4gMDsKICB9CgogIC8qCiAgICBGZXRjaCBkb21haW4gdmVjdG9ycyAodGltZSBvciBmcmVxdWVuY3kgZGlyZWN0aW9uIGZvciBkZWx0YS1jb2RpbmcpCiAgKi8KICBzYnJHZXREaXJlY3Rpb25Db250cm9sRGF0YSAoaEZyYW1lRGF0YUxlZnQsIGhCcyk7CiAgc2JyR2V0RGlyZWN0aW9uQ29udHJvbERhdGEgKGhGcmFtZURhdGFSaWdodCwgaEJzKTsKCiAgZm9yIChpPTA7IGk8aEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5uSW52ZkJhbmRzOyBpKyspIHsKICAgIGhGcmFtZURhdGFMZWZ0LT5zYnJfaW52Zl9tb2RlW2ldID0gKElOVkZfTU9ERSkgRkRLcmVhZEJpdHMgKGhCcywgMik7CiAgfQoKICBpZiAoaEZyYW1lRGF0YUxlZnQtPmNvdXBsaW5nKSB7CiAgICBmb3IgKGk9MDsgaTxoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5JbnZmQmFuZHM7IGkrKykgewogICAgICBoRnJhbWVEYXRhUmlnaHQtPnNicl9pbnZmX21vZGVbaV0gPSBoRnJhbWVEYXRhTGVmdC0+c2JyX2ludmZfbW9kZVtpXTsKICAgIH0KCgogICAgaWYgKCAhc2JyR2V0RW52ZWxvcGUgKGhIZWFkZXJEYXRhLCBoRnJhbWVEYXRhTGVmdCwgaEJzLCBmbGFncykgKSB7CiAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHNickdldE5vaXNlRmxvb3JEYXRhIChoSGVhZGVyRGF0YSwgaEZyYW1lRGF0YUxlZnQsIGhCcyk7CgogICAgaWYgKCAhc2JyR2V0RW52ZWxvcGUgKGhIZWFkZXJEYXRhLCBoRnJhbWVEYXRhUmlnaHQsIGhCcywgZmxhZ3MpICkgewogICAgICByZXR1cm4gMDsKICAgIH0KICB9CiAgZWxzZSB7CgogICAgZm9yIChpPTA7IGk8aEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5uSW52ZkJhbmRzOyBpKyspIHsKICAgICAgaEZyYW1lRGF0YVJpZ2h0LT5zYnJfaW52Zl9tb2RlW2ldID0gKElOVkZfTU9ERSkgRkRLcmVhZEJpdHMgKGhCcywgMik7CiAgICB9CgoKCiAgICBpZiAoICFzYnJHZXRFbnZlbG9wZSAoaEhlYWRlckRhdGEsIGhGcmFtZURhdGFMZWZ0LCBoQnMsIGZsYWdzKSApCiAgICAgIHJldHVybiAwOwoKICAgIGlmICggIXNickdldEVudmVsb3BlIChoSGVhZGVyRGF0YSwgaEZyYW1lRGF0YVJpZ2h0LCBoQnMsIGZsYWdzKSApCiAgICAgIHJldHVybiAwOwoKICAgIHNickdldE5vaXNlRmxvb3JEYXRhIChoSGVhZGVyRGF0YSwgaEZyYW1lRGF0YUxlZnQsIGhCcyk7CgogIH0KICBzYnJHZXROb2lzZUZsb29yRGF0YSAoaEhlYWRlckRhdGEsIGhGcmFtZURhdGFSaWdodCwgaEJzKTsKCiAgc2JyR2V0U3ludGhldGljQ29kZWREYXRhKGhIZWFkZXJEYXRhLCBoRnJhbWVEYXRhTGVmdCwgaEJzKTsKICBzYnJHZXRTeW50aGV0aWNDb2RlZERhdGEoaEhlYWRlckRhdGEsIGhGcmFtZURhdGFSaWdodCwgaEJzKTsKCiAgewogICAgaWYgKCEgZXh0cmFjdEV4dGVuZGVkRGF0YSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhIZWFkZXJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEJzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxOVUxMCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSApIHsKICAgICAgcmV0dXJuIDA7CiAgICB9CiAgfQoKICByZXR1cm4gMTsKfQoKCgoKLyohCiAgXGJyaWVmICAgUmVhZCBkaXJlY3Rpb24gY29udHJvbCBkYXRhIGZyb20gYml0c3RyZWFtCiovCnZvaWQKc2JyR2V0RGlyZWN0aW9uQ29udHJvbERhdGEgKEhBTkRMRV9TQlJfRlJBTUVfREFUQSBoX2ZyYW1lX2RhdGEsIC8qITwgaGFuZGxlIHRvIHN0cnVjdCBTQlJfRlJBTUVfREFUQSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gIGhCcykgICAgICAgICAgLyohPCBoYW5kbGUgdG8gc3RydWN0IEJJVF9CVUYgKi8KewogIGludCBpOwoKICBmb3IgKGkgPSAwOyBpIDwgaF9mcmFtZV9kYXRhLT5mcmFtZUluZm8ubkVudmVsb3BlczsgaSsrKSB7CiAgICBoX2ZyYW1lX2RhdGEtPmRvbWFpbl92ZWNbaV0gPSBGREtyZWFkQml0cyAoaEJzLCAxKTsKICB9CgogIGZvciAoaSA9IDA7IGkgPCBoX2ZyYW1lX2RhdGEtPmZyYW1lSW5mby5uTm9pc2VFbnZlbG9wZXM7IGkrKykgewogICAgaF9mcmFtZV9kYXRhLT5kb21haW5fdmVjX25vaXNlW2ldID0gRkRLcmVhZEJpdHMgKGhCcywgMSk7CiAgfQp9CgoKCi8qIQogIFxicmllZiAgIFJlYWQgbm9pc2UtZmxvb3ItbGV2ZWwgZGF0YSBmcm9tIGJpdHN0cmVhbQoqLwp2b2lkCnNickdldE5vaXNlRmxvb3JEYXRhIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLCAgLyohPCBTdGF0aWMgY29udHJvbCBkYXRhICovCiAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgIGhfZnJhbWVfZGF0YSwgLyohPCBoYW5kbGUgdG8gc3RydWN0IFNCUl9GUkFNRV9EQVRBICovCiAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgIGhCcykgICAgICAgICAgLyohPCBoYW5kbGUgdG8gc3RydWN0IEJJVF9CVUYgKi8KewogIGludCBpLGo7CiAgaW50IGRlbHRhOwogIENPVVBMSU5HX01PREUgY291cGxpbmc7CiAgaW50IG5vTm9pc2VCYW5kcyA9IGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEubk5mYjsKCiAgSHVmZm1hbiBoY2Jfbm9pc2VGOwogIEh1ZmZtYW4gaGNiX25vaXNlOwogIGludCBlbnZEYXRhVGFibGVDb21wRmFjdG9yOwoKICBjb3VwbGluZyA9IGhfZnJhbWVfZGF0YS0+Y291cGxpbmc7CgoKICAvKgogICAgU2VsZWN0IGh1ZmZtYW4gY29kZWJvb2sgZGVwZW5kaW5nIG9uIGNvdXBsaW5nIG1vZGUKICAqLwogIGlmIChjb3VwbGluZyA9PSBDT1VQTElOR19CQUwpIHsKICAgIGhjYl9ub2lzZSA9IChIdWZmbWFuKSZGREtfc2JyRGVjb2Rlcl9zYnJfaHVmZkJvb2tfTm9pc2VCYWxhbmNlMTFUOwogICAgaGNiX25vaXNlRiA9IChIdWZmbWFuKSZGREtfc2JyRGVjb2Rlcl9zYnJfaHVmZkJvb2tfRW52QmFsYW5jZTExRjsgIC8qICJzYnJfaHVmZkJvb2tfTm9pc2VCYWxhbmNlMTFGIiAqLwogICAgZW52RGF0YVRhYmxlQ29tcEZhY3RvciA9IDE7CiAgfQogIGVsc2UgewogICAgaGNiX25vaXNlID0gKEh1ZmZtYW4pJkZES19zYnJEZWNvZGVyX3Nicl9odWZmQm9va19Ob2lzZUxldmVsMTFUOwogICAgaGNiX25vaXNlRiA9IChIdWZmbWFuKSZGREtfc2JyRGVjb2Rlcl9zYnJfaHVmZkJvb2tfRW52TGV2ZWwxMUY7ICAgIC8qICJzYnJfaHVmZkJvb2tfTm9pc2VMZXZlbDExRiIgKi8KICAgIGVudkRhdGFUYWJsZUNvbXBGYWN0b3IgPSAwOwogIH0KCiAgLyoKICAgIFJlYWQgcmF3IG5vaXNlLWVudmVsb3BlIGRhdGEKICAqLwogIGZvciAoaT0wOyBpPGhfZnJhbWVfZGF0YS0+ZnJhbWVJbmZvLm5Ob2lzZUVudmVsb3BlczsgaSsrKSB7CgoKICAgIGlmIChoX2ZyYW1lX2RhdGEtPmRvbWFpbl92ZWNfbm9pc2VbaV0gPT0gMCkgewogICAgICBpZiAoY291cGxpbmcgPT0gQ09VUExJTkdfQkFMKSB7CiAgICAgICAgaF9mcmFtZV9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbaSpub05vaXNlQmFuZHNdID0KICAgICAgICAgIChGSVhQX1NHTCkgKCgoaW50KUZES3JlYWRCaXRzIChoQnMsIDUpKSA8PCBlbnZEYXRhVGFibGVDb21wRmFjdG9yKTsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBoX2ZyYW1lX2RhdGEtPnNick5vaXNlRmxvb3JMZXZlbFtpKm5vTm9pc2VCYW5kc10gPQogICAgICAgICAgKEZJWFBfU0dMKSAoaW50KUZES3JlYWRCaXRzIChoQnMsIDUpOwogICAgICB9CgogICAgICBmb3IgKGogPSAxOyBqIDwgbm9Ob2lzZUJhbmRzOyBqKyspIHsKICAgICAgICBkZWx0YSA9IERlY29kZUh1ZmZtYW5DVyhoY2Jfbm9pc2VGLCBoQnMpOwogICAgICAgIGhfZnJhbWVfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsW2kqbm9Ob2lzZUJhbmRzK2pdID0gKEZJWFBfU0dMKSAoZGVsdGEgPDwgZW52RGF0YVRhYmxlQ29tcEZhY3Rvcik7CiAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICBmb3IgKGogPSAwOyBqIDwgbm9Ob2lzZUJhbmRzOyBqKyspIHsKICAgICAgICBkZWx0YSA9IERlY29kZUh1ZmZtYW5DVyhoY2Jfbm9pc2UsIGhCcyk7CiAgICAgICAgaF9mcmFtZV9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbaSpub05vaXNlQmFuZHMral0gPSAoRklYUF9TR0wpIChkZWx0YSA8PCBlbnZEYXRhVGFibGVDb21wRmFjdG9yKTsKICAgICAgfQogICAgfQogIH0KfQoKCi8qIQogIFxicmllZiAgIFJlYWQgZW52ZWxvcGUgZGF0YSBmcm9tIGJpdHN0cmVhbQoqLwpzdGF0aWMgaW50CnNickdldEVudmVsb3BlIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLCAgLyohPCBTdGF0aWMgY29udHJvbCBkYXRhICovCiAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgIGhfZnJhbWVfZGF0YSwgLyohPCBoYW5kbGUgdG8gc3RydWN0IFNCUl9GUkFNRV9EQVRBICovCiAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgIGhCcywgICAgICAgICAgLyohPCBoYW5kbGUgdG8gc3RydWN0IEJJVF9CVUYgKi8KICAgICAgICAgICAgICAgIGNvbnN0IFVJTlQgICAgICAgICAgICAgZmxhZ3MpCnsKICBpbnQgaSwgajsKICBVQ0hBUiBub19iYW5kW01BWF9FTlZFTE9QRVNdOwogIGludCBkZWx0YSA9IDA7CiAgaW50IG9mZnNldCA9IDA7CiAgQ09VUExJTkdfTU9ERSBjb3VwbGluZyA9IGhfZnJhbWVfZGF0YS0+Y291cGxpbmc7CiAgaW50IGFtcFJlcyA9IGhIZWFkZXJEYXRhLT5ic19pbmZvLmFtcFJlc29sdXRpb247CiAgaW50IG5FbnZlbG9wZXMgPSBoX2ZyYW1lX2RhdGEtPmZyYW1lSW5mby5uRW52ZWxvcGVzOwogIGludCBlbnZEYXRhVGFibGVDb21wRmFjdG9yOwogIGludCBzdGFydF9iaXRzLCBzdGFydF9iaXRzX2JhbGFuY2U7CiAgSHVmZm1hbiBoY2JfdCwgaGNiX2Y7CgogIGhfZnJhbWVfZGF0YS0+blNjYWxlRmFjdG9ycyA9IDA7CgogIGlmICggKGhfZnJhbWVfZGF0YS0+ZnJhbWVJbmZvLmZyYW1lQ2xhc3MgPT0gMCkgJiYgKG5FbnZlbG9wZXMgPT0gMSkgKSB7CiAgICBpZiAoZmxhZ3MgJiBTQlJERUNfRUxEX0dSSUQpCiAgICAgIGFtcFJlcyA9IGhfZnJhbWVfZGF0YS0+YW1wUmVzb2x1dGlvbkN1cnJlbnRGcmFtZTsKICAgIGVsc2UKICAgICAgYW1wUmVzID0gMDsKICB9CiAgaF9mcmFtZV9kYXRhLT5hbXBSZXNvbHV0aW9uQ3VycmVudEZyYW1lID0gYW1wUmVzOwoKICAvKgogICAgU2V0IG51bWJlciBvZiBiaXRzIGZvciBmaXJzdCB2YWx1ZSBkZXBlbmRpbmcgb24gYW1wbGl0dWRlIHJlc29sdXRpb24KICAqLwogIGlmKGFtcFJlcyA9PSAxKQogIHsKICAgIHN0YXJ0X2JpdHMgPSA2OwogICAgc3RhcnRfYml0c19iYWxhbmNlID0gNTsKICB9CiAgZWxzZQogIHsKICAgIHN0YXJ0X2JpdHMgPSA3OwogICAgc3RhcnRfYml0c19iYWxhbmNlID0gNjsKICB9CgogIC8qCiAgICBDYWxjdWxhdGUgbnVtYmVyIG9mIHZhbHVlcyBmb3IgZWFjaCBlbnZlbG9wZSBhbmQgYWxsdG9nZXRoZXIKICAqLwogIGZvciAoaSA9IDA7IGkgPCBuRW52ZWxvcGVzOyBpKyspIHsKICAgIG5vX2JhbmRbaV0gPSBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5TZmJbaF9mcmFtZV9kYXRhLT5mcmFtZUluZm8uZnJlcVJlc1tpXV07CiAgICBoX2ZyYW1lX2RhdGEtPm5TY2FsZUZhY3RvcnMgKz0gbm9fYmFuZFtpXTsKICB9CiAgaWYgKGhfZnJhbWVfZGF0YS0+blNjYWxlRmFjdG9ycyA+IE1BWF9OVU1fRU5WRUxPUEVfVkFMVUVTKQogICAgcmV0dXJuIDA7CgogIC8qCiAgICBTZWxlY3QgSHVmZm1hbiBjb2RlYm9vayBkZXBlbmRpbmcgb24gY291cGxpbmcgbW9kZSBhbmQgYW1wbGl0dWRlIHJlc29sdXRpb24KICAqLwogIGlmIChjb3VwbGluZyA9PSBDT1VQTElOR19CQUwpIHsKICAgIGVudkRhdGFUYWJsZUNvbXBGYWN0b3IgPSAxOwogICAgaWYgKGFtcFJlcyA9PSAwKSB7CiAgICAgIGhjYl90ID0gKEh1ZmZtYW4pJkZES19zYnJEZWNvZGVyX3Nicl9odWZmQm9va19FbnZCYWxhbmNlMTBUOwogICAgICBoY2JfZiA9IChIdWZmbWFuKSZGREtfc2JyRGVjb2Rlcl9zYnJfaHVmZkJvb2tfRW52QmFsYW5jZTEwRjsKICAgIH0KICAgIGVsc2UgewogICAgICBoY2JfdCA9IChIdWZmbWFuKSZGREtfc2JyRGVjb2Rlcl9zYnJfaHVmZkJvb2tfRW52QmFsYW5jZTExVDsKICAgICAgaGNiX2YgPSAoSHVmZm1hbikmRkRLX3NickRlY29kZXJfc2JyX2h1ZmZCb29rX0VudkJhbGFuY2UxMUY7CiAgICB9CiAgfQogIGVsc2UgewogICAgZW52RGF0YVRhYmxlQ29tcEZhY3RvciA9IDA7CiAgICBpZiAoYW1wUmVzID09IDApIHsKICAgICAgaGNiX3QgPSAoSHVmZm1hbikmRkRLX3NickRlY29kZXJfc2JyX2h1ZmZCb29rX0VudkxldmVsMTBUOwogICAgICBoY2JfZiA9IChIdWZmbWFuKSZGREtfc2JyRGVjb2Rlcl9zYnJfaHVmZkJvb2tfRW52TGV2ZWwxMEY7CiAgICB9CiAgICBlbHNlIHsKICAgICAgaGNiX3QgPSAoSHVmZm1hbikmRkRLX3NickRlY29kZXJfc2JyX2h1ZmZCb29rX0VudkxldmVsMTFUOwogICAgICBoY2JfZiA9IChIdWZmbWFuKSZGREtfc2JyRGVjb2Rlcl9zYnJfaHVmZkJvb2tfRW52TGV2ZWwxMUY7CiAgICB9CiAgfQoKICAvKgogICAgTm93IHJlYWQgcmF3IGVudmVsb3BlIGRhdGEKICAqLwogIGZvciAoaiA9IDAsIG9mZnNldCA9IDA7IGogPCBuRW52ZWxvcGVzOyBqKyspIHsKCgogICAgaWYgKGhfZnJhbWVfZGF0YS0+ZG9tYWluX3ZlY1tqXSA9PSAwKSB7CiAgICAgIGlmIChjb3VwbGluZyA9PSBDT1VQTElOR19CQUwpIHsKICAgICAgICBoX2ZyYW1lX2RhdGEtPmlFbnZlbG9wZVtvZmZzZXRdID0KICAgICAgICAgIChGSVhQX1NHTCkgKCggKGludClGREtyZWFkQml0cyhoQnMsIHN0YXJ0X2JpdHNfYmFsYW5jZSkpIDw8IGVudkRhdGFUYWJsZUNvbXBGYWN0b3IpOwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIGhfZnJhbWVfZGF0YS0+aUVudmVsb3BlW29mZnNldF0gPQogICAgICAgICAgKEZJWFBfU0dMKSAoaW50KUZES3JlYWRCaXRzIChoQnMsIHN0YXJ0X2JpdHMpOwogICAgICB9CiAgICB9CgogICAgZm9yIChpID0gKDEgLSBoX2ZyYW1lX2RhdGEtPmRvbWFpbl92ZWNbal0pOyBpIDwgbm9fYmFuZFtqXTsgaSsrKSB7CgogICAgICBpZiAoaF9mcmFtZV9kYXRhLT5kb21haW5fdmVjW2pdID09IDApIHsKICAgICAgICBkZWx0YSA9IERlY29kZUh1ZmZtYW5DVyhoY2JfZiwgaEJzKTsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBkZWx0YSA9IERlY29kZUh1ZmZtYW5DVyhoY2JfdCwgaEJzKTsKICAgICAgfQoKICAgICAgaF9mcmFtZV9kYXRhLT5pRW52ZWxvcGVbb2Zmc2V0ICsgaV0gPSAoRklYUF9TR0wpIChkZWx0YSA8PCBlbnZEYXRhVGFibGVDb21wRmFjdG9yKTsKICAgIH0KICAgIG9mZnNldCArPSBub19iYW5kW2pdOwogIH0KCiNpZiBFTlZfRVhQX0ZSQUNUCiAgLyogQ29udmVydCBmcm9tIGludCB0byBzY2FsZWQgZnJhY3QgKEVOVl9FWFBfRlJBQ1QgYml0cyBmb3IgdGhlIGZyYWN0aW9uYWwgcGFydCkgKi8KICBmb3IgKGkgPSAwOyBpIDwgaF9mcmFtZV9kYXRhLT5uU2NhbGVGYWN0b3JzOyBpKyspIHsKICAgIGhfZnJhbWVfZGF0YS0+aUVudmVsb3BlW2ldIDw8PSBFTlZfRVhQX0ZSQUNUOwogIH0KI2VuZGlmCgogIHJldHVybiAxOwp9CgoKLy9zdGF0aWMgY29uc3QgRlJBTUVfSU5GTyB2X2ZyYW1lX2luZm8xXzggPSB7IDAsIDEsIHswLCA4fSwgezF9LCAtMSwgMSwgezAsIDh9IH07CnN0YXRpYyBjb25zdCBGUkFNRV9JTkZPIHZfZnJhbWVfaW5mbzJfOCA9IHsgMCwgMiwgezAsIDQsIDh9LCB7MSwgMX0sIC0xLCAyLCB7MCwgNCwgOH0gfTsKc3RhdGljIGNvbnN0IEZSQU1FX0lORk8gdl9mcmFtZV9pbmZvNF84ID0geyAwLCA0LCB7MCwgMiwgNCwgNiwgOH0sIHsxLCAxLCAxLCAxfSwgLTEsIDIsIHswLCA0LCA4fSB9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyohCiAgXGJyaWVmICAgIEdlbmVyYXRlcyBmcmFtZSBpbmZvIGZvciBGSVhGSVhvbmx5IGZyYW1lIGNsYXNzIHVzZWQgZm9yIGxvdyBkZWxheSB2ZXJzaW9uCgogIFxyZXR1cm4gICBub3RoaW5nCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogc3RhdGljIHZvaWQgZ2VuZXJhdGVGaXhGaXhPbmx5ICggRlJBTUVfSU5GTyAqaFNickZyYW1lSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB0cmFuUG9zSW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtYmVyVGltZVNsb3RzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQp7CiAgICBpbnQgbkVudiwgaSwgdHJhbklkeDsKICAgIGNvbnN0IGludCAqcFRhYmxlOwoKICAgIHN3aXRjaCAobnVtYmVyVGltZVNsb3RzKSB7CiAgICAgICAgY2FzZSA4OgogICAgICAgICAgICBwVGFibGUgPSBGREtfc2JyRGVjb2Rlcl9lbnZlbG9wZVRhYmxlXzhbdHJhblBvc0ludGVybmFsXTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxNToKICAgICAgICAgICAgcFRhYmxlID0gRkRLX3NickRlY29kZXJfZW52ZWxvcGVUYWJsZV8xNVt0cmFuUG9zSW50ZXJuYWxdOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE2OgogICAgICAgICAgICBwVGFibGUgPSBGREtfc2JyRGVjb2Rlcl9lbnZlbG9wZVRhYmxlXzE2W3RyYW5Qb3NJbnRlcm5hbF07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZES19BU1NFUlQoMCk7CiAgICAgICAgICAgIC8qIGluIGNhc2UgYXNzZXJ0aW9uIGNoZWNrcyBhcmUgZGlzYWJsZWQsIGZvcmNlIGEgZGVmaW5pdGUgbWVtb3J5IGZhdWx0IGF0IGZpcnN0IGFjY2VzcyAqLwogICAgICAgICAgICBwVGFibGUgPSBOVUxMOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKiBsb29rIG51bWJlciBvZiBlbnZlbG9wZXMgaW4gdGFibGUgKi8KICAgIG5FbnYgPSBwVGFibGVbMF07CiAgICAvKiBsb29rIHVwIGVudmVsb3BlIGRpc3RyaWJ1dGlvbiBpbiB0YWJsZSAqLwogICAgZm9yIChpPTE7IGk8bkVudjsgaSsrKQogICAgICAgIGhTYnJGcmFtZUluZm8tPmJvcmRlcnNbaV0gPSBwVGFibGVbaSsyXTsKICAgIC8qIG9wZW4gYW5kIGNsb3NlIGZyYW1lIGJvcmRlciAqLwogICAgaFNickZyYW1lSW5mby0+Ym9yZGVyc1swXSAgICA9IDA7CiAgICBoU2JyRnJhbWVJbmZvLT5ib3JkZXJzW25FbnZdID0gbnVtYmVyVGltZVNsb3RzOwogICAgaFNickZyYW1lSW5mby0+bkVudmVsb3BlcyA9IG5FbnY7CgogICAvKiB0cmFuc2llbnQgaWR4ICovCiAgICB0cmFuSWR4ID0gaFNickZyYW1lSW5mby0+dHJhbkVudiA9IHBUYWJsZVsxXTsKCiAgICAvKiBhZGQgbm9pc2UgZmxvb3JzICovCiAgICBoU2JyRnJhbWVJbmZvLT5ib3JkZXJzTm9pc2VbMF0gPSAwOwogICAgaFNickZyYW1lSW5mby0+Ym9yZGVyc05vaXNlWzFdID0gaFNickZyYW1lSW5mby0+Ym9yZGVyc1t0cmFuSWR4P3RyYW5JZHg6MV07CiAgICBoU2JyRnJhbWVJbmZvLT5ib3JkZXJzTm9pc2VbMl0gPSBudW1iZXJUaW1lU2xvdHM7CiAgICAvKiBuRW52IGlzIGFsd2F5cyA+IDEsIHNvIG5Ob2lzZUVudmVsb3BlcyBpcyBhbHdheXMgMiAoSUVDIDE0NDk2LTMgNC42LjE5LjMuMikgKi8KICAgIGhTYnJGcmFtZUluZm8tPm5Ob2lzZUVudmVsb3BlcyA9IDI7Cn0KCi8qIQogIFxicmllZiAgRXh0cmFjdHMgTG93RGVsYXlTQlIgY29udHJvbCBkYXRhIGZyb20gdGhlIGJpdHN0cmVhbS4KCiAgXHJldHVybiB6ZXJvIGZvciBiaXRzdHJlYW0gZXJyb3IsIG9uZSBmb3IgY29ycmVjdC4KKi8Kc3RhdGljIGludApleHRyYWN0TG93RGVsYXlHcmlkIChIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQml0QnVmLCAgICAgICAgICAvKiE8IGJpdGJ1ZmZlciBoYW5kbGUgKi8KICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwKICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBIGhfZnJhbWVfZGF0YSwgLyohPCBjb250YWlucyB0aGUgRlJBTUVfSU5GTyBzdHJ1Y3QgdG8gYmUgZmlsbGVkICovCiAgICAgICAgICAgICAgICAgICAgIGludCB0aW1lU2xvdHMKICAgICAgICAgICAgICAgICAgICApCnsKICBGUkFNRV9JTkZPICogcEZyYW1lSW5mbyA9ICZoX2ZyYW1lX2RhdGEtPmZyYW1lSW5mbzsKICBJTlQgbnVtYmVyVGltZVNsb3RzID0gaEhlYWRlckRhdGEtPm51bWJlclRpbWVTbG90czsKICBJTlQgdGVtcCA9IDAsIGs7CgogICAgICAvKiBGSVhGSVhvbmx5IGZyYW1pbmcgY2FzZSAqLwogICAgICBoX2ZyYW1lX2RhdGEtPmZyYW1lSW5mby5mcmFtZUNsYXNzID0gMDsKCiAgICAgIC8qIGdldCB0aGUgdHJhbnNpZW50IHBvc2l0aW9uIGZyb20gdGhlIGJpdHN0cmVhbSAqLwogICAgICBzd2l0Y2ggKHRpbWVTbG90cyl7CiAgICAgICAgY2FzZSA4OgogICAgICAgICAgLyogM2JpdCB0cmFuc2llbnQgcG9zaXRpb24gKHRlbXA9ezA7Li47N30pICovCiAgICAgICAgICB0ZW1wID0gRkRLcmVhZEJpdHMoIGhCaXRCdWYsIDMpOwogICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgMTY6CiAgICAgICAgY2FzZSAxNToKICAgICAgICAgIC8qIDRiaXQgdHJhbnNpZW50IHBvc2l0aW9uICh0ZW1wPXswOy4uOzE1fSkgKi8KICAgICAgICAgIHRlbXAgPSBGREtyZWFkQml0cyggaEJpdEJ1ZiwgNCk7CiAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHJldHVybiAwOwogICAgICB9CgogICAgICAvKiBjYWxjdWxhdGUgYm9yZGVycyBhY2NvcmRpbmcgdG8gdGhlIHRyYW5zaWVudCBwb3NpdGlvbiAqLwogICAgICBnZW5lcmF0ZUZpeEZpeE9ubHkgKCBwRnJhbWVJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wLAogICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXJUaW1lU2xvdHMKICAgICAgICAgICAgICAgICAgICAgICAgICk7CgogICAgICAvKiBkZWNvZGUgZnJlcSByZXM6ICovCiAgICAgIGZvciAoayA9IDA7IGsgPCBwRnJhbWVJbmZvLT5uRW52ZWxvcGVzOyBrKyspIHsKICAgICAgICAgIHBGcmFtZUluZm8tPmZyZXFSZXNba10gPSAoVUNIQVIpIEZES3JlYWRCaXRzIChoQml0QnVmLCAxKTsgLyogZiA9IEYgWzEgYml0c10gKi8gICAgICAgICAgCiAgICAgIH0KCgogIHJldHVybiAxOwp9CgovKiEKICBcYnJpZWYgICBFeHRyYWN0IHRoZSBmcmFtZSBpbmZvcm1hdGlvbiAoc3RydWN0dXJlIEZSQU1FX0lORk8pIGZyb20gdGhlIGJpdHN0cmVhbQogIFxyZXR1cm4gIFplcm8gZm9yIGJpdHN0cmVhbSBlcnJvciwgb25lIGZvciBjb3JyZWN0LgoqLwppbnQKZXh0cmFjdEZyYW1lSW5mbyAoIEhBTkRMRV9GREtfQklUU1RSRUFNICAgaEJzLCAgICAgICAgICAvKiE8IGJpdGJ1ZmZlciBoYW5kbGUgKi8KICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsICAvKiE8IFN0YXRpYyBjb250cm9sIGRhdGEgKi8KICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSAgaF9mcmFtZV9kYXRhLCAvKiE8IHBvaW50ZXIgdG8gbWVtb3J5IHdoZXJlIHRoZSBmcmFtZS1pbmZvIHdpbGwgYmUgc3RvcmVkICovCiAgICAgICAgICAgICAgICAgICBjb25zdCBVSU5UICAgICAgICAgICAgIG5yT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgIGNvbnN0IFVJTlQgICAgICAgICAgICAgZmxhZ3MKICAgICAgICAgICAgICAgICApCnsKICBGUkFNRV9JTkZPICogcEZyYW1lSW5mbyA9ICZoX2ZyYW1lX2RhdGEtPmZyYW1lSW5mbzsKICBpbnQgbnVtYmVyVGltZVNsb3RzID0gaEhlYWRlckRhdGEtPm51bWJlclRpbWVTbG90czsKICBpbnQgcG9pbnRlcl9iaXRzID0gMCwgbkVudiA9IDAsIGIgPSAwLCBib3JkZXIsIGksIG4gPSAwLAogICAgaywgcCwgYUwsIGFSLCBuTCwgblIsCiAgICB0ZW1wID0gMCwgc3RhdGljRnJlcVJlczsKICBVQ0hBUiBmcmFtZUNsYXNzOwoKICBpZiAoZmxhZ3MgJiBTQlJERUNfRUxEX0dSSUQpIHsKICAgICAgLyogQ09ERUNfQUFDTEQgKExEK1NCUikgb25seSB1c2VzIHRoZSBub3JtYWwgMCBHcmlkIGZvciBub24tdHJhbnNpZW50IEZyYW1lcyBhbmQgdGhlIExvd0RlbGF5R3JpZCBmb3IgdHJhbnNpZW50IEZyYW1lcyAqLwogICAgICBmcmFtZUNsYXNzID0gRkRLcmVhZEJpdHMgKGhCcywgMSk7IC8qIGZyYW1lQ2xhc3MgPSBbMSBiaXRdICovCiAgICAgIGlmICggZnJhbWVDbGFzcyA9PSAxICkgewogICAgICAgIC8qIGlmIGZyYW1lQ2xhc3MgPT0gMSwgZXh0cmFjdCBMb3dEZWxheVNickdyaWQsIG90aGVyd2lzZSBleHRyYWN0IG5vcm1hbCBTQlItR3JpZCBmb3IgRklYSUZYICovCiAgICAgICAgLyogZXh0cmFjdCB0aGUgQUFDTEQtU2JyLUdyaWQgKi8KICAgICAgICBwRnJhbWVJbmZvLT5mcmFtZUNsYXNzID0gZnJhbWVDbGFzczsKICAgICAgICBleHRyYWN0TG93RGVsYXlHcmlkIChoQnMsIGhIZWFkZXJEYXRhLCBoX2ZyYW1lX2RhdGEsIG51bWJlclRpbWVTbG90cyk7CiAgICAgICAgcmV0dXJuIDE7CiAgICAgIH0KICB9IGVsc2UKICB7CiAgICBmcmFtZUNsYXNzID0gRkRLcmVhZEJpdHMgKGhCcywgMik7IC8qIGZyYW1lQ2xhc3MgPSBDIFsyIGJpdHNdICovCiAgfQoKCiAgc3dpdGNoIChmcmFtZUNsYXNzKSB7CiAgY2FzZSAwOgogICAgdGVtcCA9IEZES3JlYWRCaXRzIChoQnMsIDIpOyAgICAgLyogRSBbMiBiaXRzIF0gKi8KICAgIG5FbnYgPSAoaW50KSAoMSA8PCB0ZW1wKTsgICAgLyogRSAtPiBlICovCgogICAgaWYgKChmbGFncyAmIFNCUkRFQ19FTERfR1JJRCkgJiYgKG5FbnYgPT0gMSkpCiAgICAgIGhfZnJhbWVfZGF0YS0+YW1wUmVzb2x1dGlvbkN1cnJlbnRGcmFtZSA9IEZES3JlYWRCaXRzKCBoQnMsIDEpOyAvKiBuZXcgRUxEIFN5bnRheCAwNy0xMS0wOSAqLwoKICAgIHN0YXRpY0ZyZXFSZXMgPSBGREtyZWFkQml0cyAoaEJzLCAxKTsKCiAgICB7CiAgICAgIGlmIChuRW52ID4gTUFYX0VOVkVMT1BFU19IRUFBQykKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBiID0gbkVudiArIDE7CiAgICBzd2l0Y2ggKG5FbnYpIHsKICAgIGNhc2UgMToKICAgICAgc3dpdGNoIChudW1iZXJUaW1lU2xvdHMpIHsKICAgICAgICBjYXNlIDE1OgogICAgICAgICAgRkRLbWVtY3B5IChwRnJhbWVJbmZvLCAmRkRLX3NickRlY29kZXJfc2JyX2ZyYW1lX2luZm8xXzE1LCBzaXplb2YoRlJBTUVfSU5GTykpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxNjoKICAgICAgICAgIEZES21lbWNweSAocEZyYW1lSW5mbywgJkZES19zYnJEZWNvZGVyX3Nicl9mcmFtZV9pbmZvMV8xNiwgc2l6ZW9mKEZSQU1FX0lORk8pKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBGREtfQVNTRVJUKDApOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgY2FzZSAyOgogICAgICBzd2l0Y2ggKG51bWJlclRpbWVTbG90cykgewogICAgICAgIGNhc2UgMTU6CiAgICAgICAgICBGREttZW1jcHkgKHBGcmFtZUluZm8sICZGREtfc2JyRGVjb2Rlcl9zYnJfZnJhbWVfaW5mbzJfMTUsIHNpemVvZihGUkFNRV9JTkZPKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE2OgogICAgICAgICAgRkRLbWVtY3B5IChwRnJhbWVJbmZvLCAmRkRLX3NickRlY29kZXJfc2JyX2ZyYW1lX2luZm8yXzE2LCBzaXplb2YoRlJBTUVfSU5GTykpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIEZES19BU1NFUlQoMCk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIDQ6CiAgICAgIHN3aXRjaCAobnVtYmVyVGltZVNsb3RzKSB7CiAgICAgICAgY2FzZSAxNToKICAgICAgICAgIEZES21lbWNweSAocEZyYW1lSW5mbywgJkZES19zYnJEZWNvZGVyX3Nicl9mcmFtZV9pbmZvNF8xNSwgc2l6ZW9mKEZSQU1FX0lORk8pKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTY6CiAgICAgICAgICBGREttZW1jcHkgKHBGcmFtZUluZm8sICZGREtfc2JyRGVjb2Rlcl9zYnJfZnJhbWVfaW5mbzRfMTYsIHNpemVvZihGUkFNRV9JTkZPKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgRkRLX0FTU0VSVCgwKTsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgODoKI2lmIChNQVhfRU5WRUxPUEVTID49IDgpCiAgICAgIHN3aXRjaCAobnVtYmVyVGltZVNsb3RzKSB7CiAgICAgICAgY2FzZSAxNToKICAgICAgICAgIEZES21lbWNweSAocEZyYW1lSW5mbywgJkZES19zYnJEZWNvZGVyX3Nicl9mcmFtZV9pbmZvOF8xNSwgc2l6ZW9mKEZSQU1FX0lORk8pKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMTY6CiAgICAgICAgICBGREttZW1jcHkgKHBGcmFtZUluZm8sICZGREtfc2JyRGVjb2Rlcl9zYnJfZnJhbWVfaW5mbzhfMTYsIHNpemVvZihGUkFNRV9JTkZPKSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgRkRLX0FTU0VSVCgwKTsKICAgICAgfQogICAgICBicmVhazsKI2Vsc2UKICAgICAgcmV0dXJuIDA7CiNlbmRpZgogICAgfQogICAgLyogQXBwbHkgY29ycmVjdCBmcmVxUmVzIChIaWdoIGlzIGRlZmF1bHQpICovCiAgICBpZiAoIXN0YXRpY0ZyZXFSZXMpIHsKICAgICAgZm9yIChpID0gMDsgaSA8IG5FbnYgOyBpKyspCiAgICAgICAgcEZyYW1lSW5mby0+ZnJlcVJlc1tpXSA9IDA7CiAgICB9CgogICAgYnJlYWs7CiAgY2FzZSAxOgogIGNhc2UgMjoKICAgIHRlbXAgPSBGREtyZWFkQml0cyAoaEJzLCAyKTsgIC8qIEEgWzIgYml0c10gKi8KCiAgICBuICAgID0gRkRLcmVhZEJpdHMgKGhCcywgMik7ICAvKiBuID0gTiBbMiBiaXRzXSAqLwoKICAgIG5FbnYgPSBuICsgMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qICMgZW52ZWxvcGVzICovCiAgICBiID0gbkVudiArIDE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAjIGJvcmRlcnMgICAqLwoKICAgIGJyZWFrOwogIH0KCiAgc3dpdGNoIChmcmFtZUNsYXNzKSB7CiAgY2FzZSAxOgogICAgLyogRGVjb2RlIGJvcmRlcnM6ICovCiAgICBwRnJhbWVJbmZvLT5ib3JkZXJzWzBdID0gMDsgICAgICAgICAgICAgICAvKiBmaXJzdCBib3JkZXIgICAgICAgICAgKi8KICAgIGJvcmRlciA9IHRlbXAgKyBudW1iZXJUaW1lU2xvdHM7ICAgICAgICAgIC8qIEEgLT4gYVIgICAgICAgICAgICAgICAqLwogICAgaSA9IGItMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZnJhbWUgaW5mbyBpbmRleCBmb3IgbGFzdCBib3JkZXIgKi8KICAgIHBGcmFtZUluZm8tPmJvcmRlcnNbaV0gPSBib3JkZXI7ICAgICAgICAgIC8qIGxhc3QgYm9yZGVyICAgICAgICAgICAgICAgICAgICAgICovCgogICAgZm9yIChrID0gMDsgayA8IG47IGsrKykgewogICAgICB0ZW1wID0gRkRLcmVhZEJpdHMgKGhCcywgMik7LyogUiBbMiBiaXRzXSAqLwogICAgICBib3JkZXIgLT0gKDIgKiB0ZW1wICsgMik7ICAgICAgICAgICAgICAgLyogUiAtPiByICAgICAgICAgICAgICAgICovCiAgICAgIHBGcmFtZUluZm8tPmJvcmRlcnNbLS1pXSA9IGJvcmRlcjsKICAgIH0KCgogICAgLyogRGVjb2RlIHBvaW50ZXI6ICovCiAgICBwb2ludGVyX2JpdHMgPSBERlJBQ1RfQklUUyAtIDEgLSBDb3VudExlYWRpbmdCaXRzKChGSVhQX0RCTCkobisxKSk7CiAgICBwID0gRkRLcmVhZEJpdHMgKGhCcywgcG9pbnRlcl9iaXRzKTsgICAgIC8qIHAgPSBQIFtwb2ludGVyX2JpdHMgYml0c10gKi8KCiAgICBpZiAocCA+IG4rMSkKICAgICAgcmV0dXJuIDA7CgogICAgcEZyYW1lSW5mby0+dHJhbkVudiA9IHAgPyBuICsgMiAtIHAgOiAtMTsKCgogICAgLyogRGVjb2RlIGZyZXEgcmVzOiAqLwogICAgZm9yIChrID0gbjsgayA+PSAwOyBrLS0pIHsKICAgICAgcEZyYW1lSW5mby0+ZnJlcVJlc1trXSA9IEZES3JlYWRCaXRzIChoQnMsIDEpOyAvKiBmID0gRiBbMSBiaXRzXSAqLwogICAgfQoKCiAgICAvKiBDYWxjdWxhdGUgbm9pc2UgZmxvb3IgbWlkZGxlIGJvcmRlcjogKi8KICAgIGlmIChwID09IDAgfHwgcCA9PSAxKQogICAgICBwRnJhbWVJbmZvLT5ib3JkZXJzTm9pc2VbMV0gPSBwRnJhbWVJbmZvLT5ib3JkZXJzW25dOwogICAgZWxzZQogICAgICBwRnJhbWVJbmZvLT5ib3JkZXJzTm9pc2VbMV0gPSBwRnJhbWVJbmZvLT5ib3JkZXJzW3BGcmFtZUluZm8tPnRyYW5FbnZdOwoKICAgIGJyZWFrOwoKICBjYXNlIDI6CiAgICAvKiBEZWNvZGUgYm9yZGVyczogKi8KICAgIGJvcmRlciA9IHRlbXA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEEgLT4gYUwgKi8KICAgIHBGcmFtZUluZm8tPmJvcmRlcnNbMF0gPSBib3JkZXI7ICAgICAgICAgIC8qIGZpcnN0IGJvcmRlciAqLwoKICAgIGZvciAoayA9IDE7IGsgPD0gbjsgaysrKSB7CiAgICAgIHRlbXAgPSBGREtyZWFkQml0cyAoaEJzLCAyKTsvKiBSIFsyIGJpdHNdICovCiAgICAgIGJvcmRlciArPSAoMiAqIHRlbXAgKyAyKTsgICAgICAgICAgICAgICAvKiBSIC0+IHIgICAgICAgICAgICAgICAgKi8KICAgICAgcEZyYW1lSW5mby0+Ym9yZGVyc1trXSA9IGJvcmRlcjsKICAgIH0KICAgIHBGcmFtZUluZm8tPmJvcmRlcnNba10gPSBudW1iZXJUaW1lU2xvdHM7IC8qIGxhc3QgYm9yZGVyICovCgoKICAgIC8qIERlY29kZSBwb2ludGVyOiAqLwogICAgcG9pbnRlcl9iaXRzID0gREZSQUNUX0JJVFMgLSAxIC0gQ291bnRMZWFkaW5nQml0cygoRklYUF9EQkwpKG4rMSkpOwogICAgcCA9IEZES3JlYWRCaXRzIChoQnMsIHBvaW50ZXJfYml0cyk7ICAgICAvKiBwID0gUCBbcG9pbnRlcl9iaXRzIGJpdHNdICovCiAgICBpZiAocCA+IG4rMSkKICAgICAgcmV0dXJuIDA7CgogICAgaWYgKHAgPT0gMCB8fCBwID09IDEpCiAgICAgIHBGcmFtZUluZm8tPnRyYW5FbnYgPSAtMTsKICAgIGVsc2UKICAgICAgcEZyYW1lSW5mby0+dHJhbkVudiA9IHAgLSAxOwoKCgogICAgLyogRGVjb2RlIGZyZXEgcmVzOiAqLwogICAgZm9yIChrID0gMDsgayA8PSBuOyBrKyspIHsKICAgICAgcEZyYW1lSW5mby0+ZnJlcVJlc1trXSA9IEZES3JlYWRCaXRzKGhCcywgMSk7IC8qIGYgPSBGIFsxIGJpdHNdICovCiAgICB9CgoKCiAgICAvKiBDYWxjdWxhdGUgbm9pc2UgZmxvb3IgbWlkZGxlIGJvcmRlcjogKi8KICAgIHN3aXRjaCAocCkgewogICAgY2FzZSAwOgogICAgICBwRnJhbWVJbmZvLT5ib3JkZXJzTm9pc2VbMV0gPSBwRnJhbWVJbmZvLT5ib3JkZXJzWzFdOwogICAgICBicmVhazsKICAgIGNhc2UgMToKICAgICAgcEZyYW1lSW5mby0+Ym9yZGVyc05vaXNlWzFdID0gcEZyYW1lSW5mby0+Ym9yZGVyc1tuXTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBwRnJhbWVJbmZvLT5ib3JkZXJzTm9pc2VbMV0gPSBwRnJhbWVJbmZvLT5ib3JkZXJzW3BGcmFtZUluZm8tPnRyYW5FbnZdOwogICAgICBicmVhazsKICAgIH0KCiAgICBicmVhazsKCiAgY2FzZSAzOgogICAgLyogdl9jdHJsU2lnbmFsID0gW2ZyYW1lQ2xhc3MsYUwsYVIsbkwsblIsdl9yTCx2X3JSLHAsdl9mTFJdOyAqLwoKICAgIGFMID0gRkRLcmVhZEJpdHMgKGhCcywgMik7ICAgICAgIC8qIEFMIFsyIGJpdHNdLCBBTCAtPiBhTCAqLwoKICAgIGFSID0gRkRLcmVhZEJpdHMgKGhCcywgMikgKyBudW1iZXJUaW1lU2xvdHM7ICAgICAvKiBBUiBbMiBiaXRzXSwgQVIgLT4gYVIgKi8KCiAgICBuTCA9IEZES3JlYWRCaXRzIChoQnMsIDIpOyAgICAgICAvKiBuTCA9IE5MIFsyIGJpdHNdICovCgogICAgblIgPSBGREtyZWFkQml0cyAoaEJzLCAyKTsgICAgICAgLyogblIgPSBOUiBbMiBiaXRzXSAqLwoKCgogICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgIENhbGN1bGF0ZSBoZWxwIHZhcmlhYmxlcwogICAgICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgogICAgLyogZ2VuZXJhbDogKi8KICAgIG5FbnYgPSBuTCArIG5SICsgMTsgICAgICAgICAgICAvKiAjIGVudmVsb3BlcyAqLwogICAgaWYgKG5FbnYgPiBNQVhfRU5WRUxPUEVTKQogICAgICByZXR1cm4gMDsKICAgIGIgPSBuRW52ICsgMTsgICAgICAgICAgICAgICAgICAvKiAjIGJvcmRlcnMgICAqLwoKCgogICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgIERlY29kZSBlbnZlbG9wZXMKICAgICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKCiAgICAvKiBMLWJvcmRlcnM6ICAgKi8KICAgIGJvcmRlciAgICAgICAgICAgID0gYUw7ICAgICAgICAgICAgICAgICAgIC8qIGZpcnN0IGJvcmRlciAqLwogICAgcEZyYW1lSW5mby0+Ym9yZGVyc1swXSA9IGJvcmRlcjsKCiAgICBmb3IgKGsgPSAxOyBrIDw9IG5MOyBrKyspIHsKICAgICAgdGVtcCA9IEZES3JlYWRCaXRzIChoQnMsIDIpOy8qIFIgWzIgYml0c10gKi8KICAgICAgYm9yZGVyICs9ICgyICogdGVtcCArIDIpOyAgICAgICAgICAgICAgIC8qIFIgLT4gciAgICAgICAgICAgICAgICAqLwogICAgICBwRnJhbWVJbmZvLT5ib3JkZXJzW2tdID0gYm9yZGVyOwogICAgfQoKCiAgICAvKiBSLWJvcmRlcnM6ICAqLwogICAgYm9yZGVyID0gYVI7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbGFzdCBib3JkZXIgKi8KICAgIGkgICAgICA9IG5FbnY7CgogICAgcEZyYW1lSW5mby0+Ym9yZGVyc1tpXSA9IGJvcmRlcjsKCiAgICBmb3IgKGsgPSAwOyBrIDwgblI7IGsrKykgewogICAgICB0ZW1wID0gRkRLcmVhZEJpdHMgKGhCcywgMik7LyogUiBbMiBiaXRzXSAqLwogICAgICBib3JkZXIgLT0gKDIgKiB0ZW1wICsgMik7ICAgICAgICAgICAgICAgLyogUiAtPiByICAgICAgICAgICAgICAgICovCiAgICAgIHBGcmFtZUluZm8tPmJvcmRlcnNbLS1pXSA9IGJvcmRlcjsKICAgIH0KCgogICAgLyogZGVjb2RlIHBvaW50ZXI6ICovCiAgICBwb2ludGVyX2JpdHMgPSBERlJBQ1RfQklUUyAtIDEgLSBDb3VudExlYWRpbmdCaXRzKChGSVhQX0RCTCkobkwrblIrMSkpOwogICAgcCA9IEZES3JlYWRCaXRzIChoQnMsIHBvaW50ZXJfYml0cyk7ICAgICAvKiBwID0gUCBbcG9pbnRlcl9iaXRzIGJpdHNdICovCgogICAgaWYgKHAgPiBuTCtuUisxKQogICAgICByZXR1cm4gMDsKCiAgICBwRnJhbWVJbmZvLT50cmFuRW52ID0gcCA/IGIgLSBwIDogLTE7CgoKCiAgICAvKiBkZWNvZGUgZnJlcSByZXM6ICovCiAgICBmb3IgKGsgPSAwOyBrIDwgbkVudjsgaysrKSB7CiAgICAgIHBGcmFtZUluZm8tPmZyZXFSZXNba10gPSBGREtyZWFkQml0cyhoQnMsIDEpOyAvKiBmID0gRiBbMSBiaXRzXSAqLwogICAgfQoKCgogICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgIERlY29kZSBub2lzZSBmbG9vcnMKICAgICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwogICAgcEZyYW1lSW5mby0+Ym9yZGVyc05vaXNlWzBdID0gYUw7CgogICAgaWYgKG5FbnYgPT0gMSkgewogICAgICAvKiAxIG5vaXNlIGZsb29yIGVudmVsb3BlOiAqLwogICAgICBwRnJhbWVJbmZvLT5ib3JkZXJzTm9pc2VbMV0gPSBhUjsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiAyIG5vaXNlIGZsb29yIGVudmVsb3BlcyAqLwogICAgICBpZiAocCA9PSAwIHx8IHAgPT0gMSkKICAgICAgICBwRnJhbWVJbmZvLT5ib3JkZXJzTm9pc2VbMV0gPSBwRnJhbWVJbmZvLT5ib3JkZXJzW25FbnYgLSAxXTsKICAgICAgZWxzZQogICAgICAgIHBGcmFtZUluZm8tPmJvcmRlcnNOb2lzZVsxXSA9IHBGcmFtZUluZm8tPmJvcmRlcnNbcEZyYW1lSW5mby0+dHJhbkVudl07CiAgICAgIHBGcmFtZUluZm8tPmJvcmRlcnNOb2lzZVsyXSA9IGFSOwogICAgfQogICAgYnJlYWs7CiAgfQoKCiAgLyoKICAgIFN0b3JlIG51bWJlciBvZiBlbnZlbG9wZXMsIG5vaXNlIGZsb29yIGVudmVsb3BlcyBhbmQgZnJhbWUgY2xhc3MKICAqLwogIHBGcmFtZUluZm8tPm5FbnZlbG9wZXMgPSBuRW52OwoKICBpZiAobkVudiA9PSAxKQogICAgcEZyYW1lSW5mby0+bk5vaXNlRW52ZWxvcGVzID0gMTsKICBlbHNlCiAgICBwRnJhbWVJbmZvLT5uTm9pc2VFbnZlbG9wZXMgPSAyOwoKICBwRnJhbWVJbmZvLT5mcmFtZUNsYXNzID0gZnJhbWVDbGFzczsKCiAgaWYgKHBGcmFtZUluZm8tPmZyYW1lQ2xhc3MgPT0gMiB8fCBwRnJhbWVJbmZvLT5mcmFtZUNsYXNzID09IDEpIHsKICAgIC8qIGNhbGN1bGF0ZSBub2lzZSBmbG9vciBmaXJzdCBhbmQgbGFzdCBib3JkZXJzOiAqLwogICAgcEZyYW1lSW5mby0+Ym9yZGVyc05vaXNlWzBdID0gcEZyYW1lSW5mby0+Ym9yZGVyc1swXTsKICAgIHBGcmFtZUluZm8tPmJvcmRlcnNOb2lzZVtwRnJhbWVJbmZvLT5uTm9pc2VFbnZlbG9wZXNdID0gcEZyYW1lSW5mby0+Ym9yZGVyc1tuRW52XTsKICB9CgoKICByZXR1cm4gMTsKfQoKCi8qIQogIFxicmllZiAgIENoZWNrIGlmIHRoZSBmcmFtZUluZm8gdmVjdG9yIGhhcyByZWFzb25hYmxlIHZhbHVlcy4KICBccmV0dXJuICBaZXJvIGZvciBlcnJvciwgb25lIGZvciBjb3JyZWN0CiovCnN0YXRpYyBpbnQKY2hlY2tGcmFtZUluZm8gKEZSQU1FX0lORk8gKiBwRnJhbWVJbmZvLCAvKiE8IHBvaW50ZXIgdG8gZnJhbWVJbmZvICovCiAgICAgICAgICAgICAgICBpbnQgbnVtYmVyT2ZUaW1lU2xvdHMsICAgLyohPCBRTUYgdGltZSBzbG90cyBwZXIgZnJhbWUgKi8KICAgICAgICAgICAgICAgIGludCBvdmVybGFwLCAgICAgICAgICAgICAvKiE8IEFtb3VudCBvZiBvdmVybGFwIFFNRiB0aW1lIHNsb3RzICovCiAgICAgICAgICAgICAgICBpbnQgdGltZVN0ZXApICAgICAgICAgICAgLyohPCBRTUYgc2xvdHMgdG8gU0JSIHNsb3RzIHN0ZXAgZmFjdG9yICovCnsKICBpbnQgbWF4UG9zLGksajsKICBpbnQgc3RhcnRQb3M7CiAgaW50IHN0b3BQb3M7CiAgaW50IHRyYW5FbnY7CiAgaW50IHN0YXJ0UG9zTm9pc2U7CiAgaW50IHN0b3BQb3NOb2lzZTsKICBpbnQgbkVudmVsb3BlcyA9IHBGcmFtZUluZm8tPm5FbnZlbG9wZXM7CiAgaW50IG5Ob2lzZUVudmVsb3BlcyA9IHBGcmFtZUluZm8tPm5Ob2lzZUVudmVsb3BlczsKCiAgaWYobkVudmVsb3BlcyA8IDEgfHwgbkVudmVsb3BlcyA+IE1BWF9FTlZFTE9QRVMpCiAgICByZXR1cm4gMDsKCiAgaWYobk5vaXNlRW52ZWxvcGVzID4gTUFYX05PSVNFX0VOVkVMT1BFUykKICAgIHJldHVybiAwOwoKICBzdGFydFBvcyAgICAgICAgPSBwRnJhbWVJbmZvLT5ib3JkZXJzWzBdOwogIHN0b3BQb3MgICAgICAgICA9IHBGcmFtZUluZm8tPmJvcmRlcnNbbkVudmVsb3Blc107CiAgdHJhbkVudiAgICAgICAgID0gcEZyYW1lSW5mby0+dHJhbkVudjsKICBzdGFydFBvc05vaXNlICAgPSBwRnJhbWVJbmZvLT5ib3JkZXJzTm9pc2VbMF07CiAgc3RvcFBvc05vaXNlICAgID0gcEZyYW1lSW5mby0+Ym9yZGVyc05vaXNlW25Ob2lzZUVudmVsb3Blc107CgogIGlmIChvdmVybGFwIDwgMCB8fCBvdmVybGFwID4gKDYpKSB7CiAgICByZXR1cm4gMDsKICB9CiAgaWYgKHRpbWVTdGVwIDwgMSB8fCB0aW1lU3RlcCA+IDIpIHsKICAgIHJldHVybiAwOwogIH0KICBtYXhQb3MgPSBudW1iZXJPZlRpbWVTbG90cyArIChvdmVybGFwL3RpbWVTdGVwKTsKCiAgLyogQ2hlY2sgdGhhdCB0aGUgc3RhcnQgYW5kIHN0b3AgcG9zaXRpb25zIG9mIHRoZSBmcmFtZSBhcmUgcmVhc29uYWJsZSB2YWx1ZXMuICovCiAgaWYoIChzdGFydFBvcyA8IDApIHx8IChzdGFydFBvcyA+PSBzdG9wUG9zKSApCiAgICByZXR1cm4gMDsKICBpZiggc3RhcnRQb3MgPiBtYXhQb3MtbnVtYmVyT2ZUaW1lU2xvdHMgKSAvKiBGaXJzdCBlbnYuIG11c3Qgc3RhcnQgaW4gb3IgZGlyZWN0bHkgYWZ0ZXIgdGhlIG92ZXJsYXAgYnVmZmVyICovCiAgICByZXR1cm4gMDsKICBpZiggc3RvcFBvcyA8IG51bWJlck9mVGltZVNsb3RzICkgLyogT25lIGNvbXBsZXRlIGZyYW1lIG11c3QgYmUgcmVhZHkgZm9yIG91dHB1dCBhZnRlciBwcm9jZXNzaW5nICovCiAgICByZXR1cm4gMDsKICBpZihzdG9wUG9zID4gbWF4UG9zKQogICAgcmV0dXJuIDA7CgogIC8qIENoZWNrIHRoYXQgdGhlICBzdGFydCBib3JkZXIgZm9yIGV2ZXJ5IGVudmVsb3BlIGlzIHN0cmljdGx5IGxhdGVyIGluIHRpbWUgKi8KICBmb3IoaT0wO2k8bkVudmVsb3BlcztpKyspIHsKICAgIGlmKHBGcmFtZUluZm8tPmJvcmRlcnNbaV0gPj0gcEZyYW1lSW5mby0+Ym9yZGVyc1tpKzFdKQogICAgICByZXR1cm4gMDsKICB9CgogIC8qIENoZWNrIHRoYXQgdGhlIGVudmVsb3BlIHRvIGJlIHNob3J0ZW5lZCBpcyBhY3R1YWxseSBhbW9uZyB0aGUgZW52ZWxvcGVzICovCiAgaWYodHJhbkVudj5uRW52ZWxvcGVzKQogICAgcmV0dXJuIDA7CgoKICAvKiBDaGVjayB0aGUgbm9pc2UgYm9yZGVycyAqLwogIGlmKG5FbnZlbG9wZXM9PTEgJiYgbk5vaXNlRW52ZWxvcGVzPjEpCiAgICByZXR1cm4gMDsKCiAgaWYoc3RhcnRQb3MgIT0gc3RhcnRQb3NOb2lzZSB8fCBzdG9wUG9zICE9IHN0b3BQb3NOb2lzZSkKICAgIHJldHVybiAwOwoKCiAgLyogQ2hlY2sgdGhhdCB0aGUgIHN0YXJ0IGJvcmRlciBmb3IgZXZlcnkgbm9pc2UtZW52ZWxvcGUgaXMgc3RyaWN0bHkgbGF0ZXIgaW4gdGltZSovCiAgZm9yKGk9MDsgaTxuTm9pc2VFbnZlbG9wZXM7IGkrKykgewogICAgaWYocEZyYW1lSW5mby0+Ym9yZGVyc05vaXNlW2ldID49IHBGcmFtZUluZm8tPmJvcmRlcnNOb2lzZVtpKzFdKQogICAgICByZXR1cm4gMDsKICB9CgogIC8qIENoZWNrIHRoYXQgZXZlcnkgbm9pc2UgYm9yZGVyIGlzIHRoZSBzYW1lIGFzIGFuIGVudmVsb3BlIGJvcmRlciovCiAgZm9yKGk9MDsgaTxuTm9pc2VFbnZlbG9wZXM7IGkrKykgewogICAgc3RhcnRQb3NOb2lzZSA9IHBGcmFtZUluZm8tPmJvcmRlcnNOb2lzZVtpXTsKCiAgICBmb3Ioaj0wOyBqPG5FbnZlbG9wZXM7IGorKykgewogICAgICBpZihwRnJhbWVJbmZvLT5ib3JkZXJzW2pdID09IHN0YXJ0UG9zTm9pc2UpCiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBpZihqPT1uRW52ZWxvcGVzKQogICAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiAxOwp9Cg==