Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKiAgRnJhdW5ob2ZlciBJSVMgRkRLIEFBQyBFbmNvZGVyIGxpYiAgKioqKioqKioqKioqKioqKioqCgogICBBdXRob3Iocyk6IFYuIEJhY2lnYWx1cG8KICAgRGVzY3JpcHRpb246IE1ldGFkYXRhIEVuY29kZXIgbGlicmFyeSBpbnRlcmZhY2UgZnVuY3Rpb25zCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKI2luY2x1ZGUgIm1ldGFkYXRhX21haW4uaCIKI2luY2x1ZGUgIm1ldGFkYXRhX2NvbXByZXNzb3IuaCIKI2luY2x1ZGUgIkZES19iaXRzdHJlYW0uaCIKI2luY2x1ZGUgIkZES19hdWRpby5oIgojaW5jbHVkZSAiZ2VuZXJpY1N0ZHMuaCIKCi8qLS0tLS0tLS0tLS0tLS0tLS0gZGVmaW5lcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KI2RlZmluZSBNQVhfRFJDX0JBTkRTICAgICAgICAoMTw8NCkKI2RlZmluZSBNQVhfRFJDX0NIQU5ORUxTICAgICAgICAoOCkKI2RlZmluZSBNQVhfRFJDX0ZSQU1FTEVOICAgKDIqMTAyNCkKCi8qLS0tLS0tLS0tLS0tLS0tIHN0cnVjdHVyZSBkZWZpbml0aW9ucyAtLS0tLS0tLS0tLS0tLS0tLS0tLSovCgp0eXBlZGVmIHN0cnVjdCBBQUNfTUVUQURBVEEKewogIC8qIE1QRUc6IER5bmFtaWMgUmFuZ2UgQ29udHJvbCAqLwogIHN0cnVjdCB7CiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBwcm9nX3JlZl9sZXZlbF9wcmVzZW50OwogICAgU0NIQVIgICAgICAgICAgICAgICAgICAgICAgICAgcHJvZ19yZWZfbGV2ZWw7CgogICAgVUNIQVIgICAgICAgICAgICAgICAgICAgICAgICAgZHluX3JuZ19zZ25bTUFYX0RSQ19CQU5EU107CiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBkeW5fcm5nX2N0bFtNQVhfRFJDX0JBTkRTXTsKCiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBkcmNfYmFuZHNfcHJlc2VudDsKICAgIFVDSEFSICAgICAgICAgICAgICAgICAgICAgICAgIGRyY19iYW5kX2luY3I7CiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBkcmNfYmFuZF90b3BbTUFYX0RSQ19CQU5EU107CiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBkcmNfaW50ZXJwb2xhdGlvbl9zY2hlbWU7CiAgICBBQUNFTkNfTUVUQURBVEFfRFJDX1BST0ZJTEUgICBkcmNfcHJvZmlsZTsKICAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyY19UYXJnZXRSZWZMZXZlbDsgICAgLyogdXNlZCBmb3IgTGltaXRlciAqLwoKICAgIC8qIGV4Y2x1ZGVkIGNoYW5uZWxzICovCiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBleGNsdWRlZF9jaG5zX3ByZXNlbnQ7CiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBleGNsdWRlX21hc2tbMl07ICAgICAgIC8qIE1BWF9OVU1CRVJfQ0hBTk5FTFMvOCAqLwogIH0gbXBlZ0RyYzsKCiAgLyogRVRTSTogYWRkdGwgYW5jaWxsYXJ5IGRhdGEgKi8KICBzdHJ1Y3QgewogICAgLyogSGVhdnkgQ29tcHJlc3Npb24gKi8KICAgIFVDSEFSICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXByZXNzaW9uX29uOyAgICAgICAgLyogZmxhZywgaWYgY29tcHJlc3Npb24gdmFsdWUgc2hvdWxkIGJlIHdyaXR0ZW4gKi8KICAgIFVDSEFSICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXByZXNzaW9uX3ZhbHVlOyAgICAgLyogY29tcHJlc3Npb24gdmFsdWUgKi8KICAgIEFBQ0VOQ19NRVRBREFUQV9EUkNfUFJPRklMRSAgIGNvbXBfcHJvZmlsZTsKICAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBfVGFyZ2V0UmVmTGV2ZWw7ICAgLyogdXNlZCBmb3IgTGltaXRlciAqLwogICAgSU5UICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZWNvZGVfY29hcnNlX3N0YXR1czsKICAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVjb2RlX2ZpbmVfc3RhdHVzOwogIH0gZXRzaUFuY0RhdGE7CgogIFNDSEFSICAgICAgICAgICAgICAgICAgICAgICAgIGNlbnRlck1peExldmVsOyAgICAgICAgICAvKiBjZW50ZXIgZG93bm1peCBsZXZlbCAoMC4uLjcsIGFjY29yZGluZyB0byB0YWJsZSkgKi8KICBTQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBzdXJyb3VuZE1peExldmVsOyAgICAgICAgLyogc3Vycm91bmQgZG93bm1peCBsZXZlbCAoMC4uLjcsIGFjY29yZGluZyB0byB0YWJsZSkgKi8KICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBXcml0ZVBDRU1peER3bklkeDsgICAgICAgLyogZmxhZyAqLwogIFVDSEFSICAgICAgICAgICAgICAgICAgICAgICAgIERteEx2bF9PbjsgICAgICAgICAgICAgICAvKiBmbGFnICovCgogIFVDSEFSICAgICAgICAgICAgICAgICAgICAgICAgIGRvbGJ5U3Vycm91bmRNb2RlOwoKICBVQ0hBUiAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YU1vZGU7ICAgICAgICAgICAgLyogaW5kaWNhdGUgbWV0YSBkYXRhIG1vZGUgaW4gY3VycmVudCBmcmFtZSAoZGVsYXkgbGluZSkgKi8KCn0gQUFDX01FVEFEQVRBOwoKc3RydWN0IEZES19NRVRBREFUQV9FTkNPREVSCnsKICBJTlQgICAgICAgICAgICAgICAgbWV0YWRhdGFNb2RlOwogIEhEUkNfQ09NUCAgICAgICAgICBoRHJjQ29tcDsKICBBQUNFTkNfTWV0YURhdGEgICAgc3VibWl0dGVkTWV0YURhdGE7CgogIElOVCAgICAgICAgICAgICAgICBuQXVkaW9EYXRhRGVsYXk7CiAgSU5UICAgICAgICAgICAgICAgIG5NZXRhRGF0YURlbGF5OwogIElOVCAgICAgICAgICAgICAgICBuQ2hhbm5lbHM7CgogIElOVF9QQ00gICAgICAgICAgICBhdWRpb0RlbGF5QnVmZmVyW01BWF9EUkNfQ0hBTk5FTFMqTUFYX0RSQ19GUkFNRUxFTl07CiAgaW50ICAgICAgICAgICAgICAgIGF1ZGlvRGVsYXlJZHg7CgogIEFBQ19NRVRBREFUQSAgICAgICBtZXRhRGF0YUJ1ZmZlclszXTsKICBpbnQgICAgICAgICAgICAgICAgbWV0YURhdGFEZWxheUlkeDsKCiAgVUNIQVIgICAgICAgICAgICAgIGRyY0luZm9QYXlsb2FkWzEyXTsKICBVQ0hBUiAgICAgICAgICAgICAgZHJjRHNlUGF5bG9hZFs4XTsKCiAgSU5UICAgICAgICAgICAgICAgIG1hdHJpeF9taXhkb3duX2lkeDsKICBBQUNFTkNfRVhUX1BBWUxPQUQgZXhQYXlsb2FkWzJdOwogIElOVCAgICAgICAgICAgICAgICBuRXh0ZW5zaW9uczsKCiAgSU5UICAgICAgICAgICAgICAgIGZpbmFsaXplTWV0YURhdGE7ICAgICAgICAgICAgICAgICAgIC8qIERlbGF5IHN3aXRjaCBvZmYgYnkgb25lIGZyYW1lIGFuZCB3cml0ZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gdG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxpemUgdGhlIG1ldGFkYXRhIHNldHVwLiAqLwp9OwoKCi8qLS0tLS0tLS0tLS0tLS0tLSBjb25zdGFudHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpzdGF0aWMgY29uc3QgQUFDRU5DX01ldGFEYXRhIGRlZmF1bHRNZXRhRGF0YVNldHVwID0gewogICAgQUFDRU5DX01FVEFEQVRBX0RSQ19OT05FLAogICAgQUFDRU5DX01FVEFEQVRBX0RSQ19OT05FLAogICAgLSgzMTw8MTYpLAogICAgLSgzMTw8MTYpLAogICAgMCwKICAgIC0oMzE8PDE2KSwKICAgIDAsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAwCn07CgpzdGF0aWMgY29uc3QgRklYUF9EQkwgZG14VGFibGVbOF0gPSB7CiAgICAoKEZJWFBfREJMKU1BWFZBTF9EQkwpLCBGTDJGWENPTlNUX0RCTCgwLjg0MWYpLCBGTDJGWENPTlNUX0RCTCgwLjcwN2YpLCBGTDJGWENPTlNUX0RCTCgwLjU5NmYpLAogICAgRkwyRlhDT05TVF9EQkwoMC41MDBmKSwgRkwyRlhDT05TVF9EQkwoMC40MjJmKSwgRkwyRlhDT05TVF9EQkwoMC4zNTVmKSwgRkwyRlhDT05TVF9EQkwoMC4wMDBmKQp9OwoKc3RhdGljIGNvbnN0IFVDSEFSIHN1cm1peDJtYXRyaXhfbWl4ZG93bl9pZHhbOF0gPSB7CiAgICAwLCAwLCAwLCAxLCAxLCAyLCAyLCAzCn07CgoKLyotLS0tLS0tLS0tLS0tLS0gZnVuY3Rpb24gZGVjbGFyYXRpb25zIC0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIEZES19NRVRBREFUQV9FUlJPUiBXcml0ZU1ldGFkYXRhUGF5bG9hZCgKICAgICAgICBjb25zdCBIQU5ETEVfRkRLX01FVEFEQVRBX0VOQ09ERVIgaE1ldGFEYXRhLAogICAgICAgIGNvbnN0IEFBQ19NRVRBREFUQSAqIGNvbnN0ICBwTWV0YWRhdGEKICAgICAgICApOwoKc3RhdGljIElOVCBXcml0ZUR5bmFtaWNSYW5nZUluZm9QYXlsb2FkKAogICAgICAgIGNvbnN0IEFBQ19NRVRBREFUQSogY29uc3QgcE1ldGFkYXRhLAogICAgICAgIFVDSEFSKiBjb25zdCAgICAgICAgICAgICAgcEV4dGVuc2lvblBheWxvYWQKICAgICAgICApOwoKc3RhdGljIElOVCBXcml0ZUV0c2lBbmNpbGxhcnlEYXRhUGF5bG9hZCgKICAgICAgICBjb25zdCBBQUNfTUVUQURBVEEqIGNvbnN0IHBNZXRhZGF0YSwKICAgICAgICBVQ0hBUiogY29uc3QgICAgICAgICAgICAgIHBFeHRlbnNpb25QYXlsb2FkCiAgICAgICAgKTsKCnN0YXRpYyBGREtfTUVUQURBVEFfRVJST1IgQ29tcGVuc2F0ZUF1ZGlvRGVsYXkoCiAgICAgICAgSEFORExFX0ZES19NRVRBREFUQV9FTkNPREVSIGhNZXRhRGF0YUVuYywKICAgICAgICBJTlRfUENNICogY29uc3QgICAgICAgICAgICAgcEF1ZGlvU2FtcGxlcywKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgbkF1ZGlvU2FtcGxlcwogICAgICAgICk7CgpzdGF0aWMgRkRLX01FVEFEQVRBX0VSUk9SIExvYWRTdWJtaXR0ZWRNZXRhZGF0YSgKICAgICAgICBjb25zdCBBQUNFTkNfTWV0YURhdGEgKiAgIGNvbnN0IGhNZXRhZGF0YSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgICAgIG5DaGFubmVscywKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhTW9kZSwKICAgICAgICBBQUNfTUVUQURBVEEgKiBjb25zdCAgICAgICAgICAgIHBBYWNNZXRhRGF0YQogICAgICAgICk7CgpzdGF0aWMgRkRLX01FVEFEQVRBX0VSUk9SIFByb2Nlc3NDb21wcmVzc29yKAogICAgICAgIEFBQ19NRVRBREFUQSAgICAgICAgICAgICAgICAgICAgKnBNZXRhZGF0YSwKICAgICAgICBIRFJDX0NPTVAgICAgICAgICAgICAgICAgICAgICAgICBoRHJjQ29tcCwKICAgICAgICBjb25zdCBJTlRfUENNICogY29uc3QgICAgICAgICAgICBwU2FtcGxlcywKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgICAgICBuU2FtcGxlcwogICAgICAgICk7CgovKi0tLS0tLS0tLS0tLS0gZnVuY3Rpb24gZGVmaW5pdGlvbnMgLS0tLS0tLS0tLS0tLS0tLSovCgpzdGF0aWMgRFJDX1BST0ZJTEUgY29udmVydFByb2ZpbGUoQUFDRU5DX01FVEFEQVRBX0RSQ19QUk9GSUxFIGFhY1Byb2ZpbGUpCnsKICAgIERSQ19QUk9GSUxFIGRyY1Byb2ZpbGUgPSBEUkNfTk9ORTsKCiAgICBzd2l0Y2goYWFjUHJvZmlsZSkgewogICAgICBjYXNlIEFBQ0VOQ19NRVRBREFUQV9EUkNfTk9ORTogICAgICAgICAgZHJjUHJvZmlsZSA9IERSQ19OT05FOyAgICAgICAgICBicmVhazsKICAgICAgY2FzZSBBQUNFTkNfTUVUQURBVEFfRFJDX0ZJTE1TVEFOREFSRDogIGRyY1Byb2ZpbGUgPSBEUkNfRklMTVNUQU5EQVJEOyAgYnJlYWs7CiAgICAgIGNhc2UgQUFDRU5DX01FVEFEQVRBX0RSQ19GSUxNTElHSFQ6ICAgICBkcmNQcm9maWxlID0gRFJDX0ZJTE1MSUdIVDsgICAgIGJyZWFrOwogICAgICBjYXNlIEFBQ0VOQ19NRVRBREFUQV9EUkNfTVVTSUNTVEFOREFSRDogZHJjUHJvZmlsZSA9IERSQ19NVVNJQ1NUQU5EQVJEOyBicmVhazsKICAgICAgY2FzZSBBQUNFTkNfTUVUQURBVEFfRFJDX01VU0lDTElHSFQ6ICAgIGRyY1Byb2ZpbGUgPSBEUkNfTVVTSUNMSUdIVDsgICAgYnJlYWs7CiAgICAgIGNhc2UgQUFDRU5DX01FVEFEQVRBX0RSQ19TUEVFQ0g6ICAgICAgICBkcmNQcm9maWxlID0gRFJDX1NQRUVDSDsgICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJjUHJvZmlsZSA9IERSQ19OT05FOyAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiBkcmNQcm9maWxlOwp9CgoKLyogY29udmVydCBkaWFsb2cgbm9ybWFsaXphdGlvbiB0byBwcm9ncmFtIHJlZmVyZW5jZSBsZXZlbCAqLwovKiBOT1RFOiB0aGlzIG9ubHkgaXMgY29ycmVjdCwgaWYgdGhlIGRlY29kZXIgdGFyZ2V0IGxldmVsIGlzIHNldCB0byAtMzFkQiBmb3IgbGluZSBtb2RlIC8gLTIwZEIgZm9yIFJGIG1vZGUgKi8Kc3RhdGljIFVDSEFSIGRpYWxub3JtMnByb2dyZWZsdmwoY29uc3QgSU5UIGQpCnsKICAgIHJldHVybiAoKFVDSEFSKUZES21heCgwLCBGREttaW4oKC1kICsgKDE8PDEzKSkgPj4gMTQsIDEyNykpKTsKfQoKLyogY29udmVydCBwcm9ncmFtIHJlZmVyZW5jZSBsZXZlbCB0byBkaWFsb2cgbm9ybWFsaXphdGlvbiAqLwpzdGF0aWMgSU5UIHByb2dyZWZsdmwyZGlhbG5vcm0oY29uc3QgVUNIQVIgcCkKewogICAgcmV0dXJuIC0oKElOVCkocDw8KDE2LTIpKSk7Cn0KCi8qIGVuY29kZSBkb3dubWl4IGxldmVscyB0byBEb3dubWl4aW5nX2xldmVsc19NUEVHNCAqLwpzdGF0aWMgU0NIQVIgZW5jb2RlRG14THZscyhjb25zdCBTQ0hBUiBjbWl4bGV2LCBjb25zdCBTQ0hBUiBzdXJtaXhsZXYpCnsKICAgIFNDSEFSIGRteEx2bHMgPSAwOwogICAgZG14THZscyB8PSAweDgwIHwgKGNtaXhsZXYgPDwgNCk7IC8qIGNlbnRlcl9taXhfbGV2ZWxfb24gKi8KICAgIGRteEx2bHMgfD0gMHgwOCB8IHN1cm1peGxldjsgICAgICAvKiBzdXJyb3VuZF9taXhfbGV2ZWxfb24gKi8KCiAgICByZXR1cm4gZG14THZsczsKfQoKLyogZW5jb2RlIEFBQyBEUkMgZ2FpbiAoSVNPL0lFQyAxNDQ5Ni0zOjIwMDUgIDQuNS4yLjcpICovCnN0YXRpYyB2b2lkIGVuY29kZUR5bnJuZyhJTlQgZ2FpbiwgVUNIQVIqIGNvbnN0IGR5bl9ybmdfY3RsLCBVQ0hBUiogY29uc3QgZHluX3JuZ19zZ24gKQp7CiAgICBpZihnYWluIDwgMCkKICAgIHsKICAgICAgKmR5bl9ybmdfc2duID0gMTsKICAgICAgZ2FpbiA9IC1nYWluOwogICAgfQogICAgZWxzZQogICAgewogICAgICAqZHluX3JuZ19zZ24gPSAwOwogICAgfQogICAgZ2FpbiA9IEZES21pbihnYWluLCgxMjc8PDE0KSk7CgogICAgKmR5bl9ybmdfY3RsID0gKFVDSEFSKSgoZ2FpbiArICgxPDwxMykpID4+IDE0KTsKfQoKLyogZGVjb2RlIEFBQyBEUkMgZ2FpbiAoSVNPL0lFQyAxNDQ5Ni0zOjIwMDUgIDQuNS4yLjcpICovCnN0YXRpYyBJTlQgZGVjb2RlRHlucm5nKGNvbnN0IFVDSEFSIGR5bl9ybmdfY3RsLCBjb25zdCBVQ0hBUiBkeW5fcm5nX3NnbikKewogICAgSU5UIHRtcCA9ICgoSU5UKWR5bl9ybmdfY3RsIDw8ICgxNi0yKSk7CiAgICBpZiAoZHluX3JuZ19zZ24pIHRtcCA9IC10bXA7CgogICAgcmV0dXJuIHRtcDsKfQoKLyogZW5jb2RlIEFBQyBjb21wcmVzc2lvbiB2YWx1ZSAoRVRTSSBUUyAxMDEgMTU0IHBhZ2UgOTkpICovCnN0YXRpYyBVQ0hBUiBlbmNvZGVDb21wcihJTlQgZ2FpbikKewogICAgVUNIQVIgeCwgeTsKICAgIElOVCB0bXA7CgogICAgLyogdG1wID0gKGludCkoKDQ4LjE2NGYgLSBnYWluKSAvIDYuMDIwNmYgKiAxNSArIDAuNWYpOyAqLwogICAgdG1wID0gKCgzMTU2NDc2IC0gZ2FpbikgKiAxNSArIDE5NzI4MykgLyAzOTQ1NjY7CgogICAgaWYgKHRtcCA+PSAyNDApIHsKICAgICAgICByZXR1cm4gMHhGRjsKICAgIH0KICAgIGVsc2UgaWYgKHRtcCA8IDApIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGVsc2UgewogICAgICAgIHggPSB0bXAgLyAxNTsKICAgICAgICB5ID0gdG1wICUgMTU7CiAgICB9CgogICAgcmV0dXJuICh4IDw8IDQpIHwgeTsKfQoKLyogZGVjb2RlIEFBQyBjb21wcmVzc2lvbiB2YWx1ZSAoRVRTSSBUUyAxMDEgMTU0IHBhZ2UgOTkpICovCnN0YXRpYyBJTlQgZGVjb2RlQ29tcHIoY29uc3QgVUNIQVIgY29tcHIpCnsKICAgIElOVCBnYWluOwogICAgU0NIQVIgeCA9IGNvbXByID4+IDQ7ICAgICAvKiA0IE1TQiBvZiBjb21wciAqLwogICAgVUNIQVIgeSA9IChjb21wciAmIDB4MEYpOyAvKiA0IExTQiBvZiBjb21wciAqLwoKICAgIC8qIGdhaW4gPSAoSU5UKSgoNDguMTY0ZiAtIDYuMDIwNmYgKiB4IC0gMC40MDE0ZiAqIHkpICk7ICovCiAgICBnYWluID0gKElOVCkoIHNjYWxlVmFsdWUoKChMT05HKUZMMkZYQ09OU1RfREJMKDYuMDIwNmYvMTI4LmYpKig4LXgpIC0gKExPTkcpRkwyRlhDT05TVF9EQkwoMC40MDE0Zi8xMjguZikqeSksIC0oREZSQUNUX0JJVFMtMS03LTE2KSkgKTsKCiAgICByZXR1cm4gZ2FpbjsKfQoKCkZES19NRVRBREFUQV9FUlJPUiBGREtfTWV0YWRhdGFFbmNfT3BlbigKICAgICAgICBIQU5ETEVfRkRLX01FVEFEQVRBX0VOQ09ERVIgKnBoTWV0YURhdGEKICAgICAgICApCnsKICAgIEZES19NRVRBREFUQV9FUlJPUiBlcnIgPSBNRVRBREFUQV9PSzsKICAgIEhBTkRMRV9GREtfTUVUQURBVEFfRU5DT0RFUiBoTWV0YURhdGEgPSBOVUxMOwoKICAgIGlmIChwaE1ldGFEYXRhID09IE5VTEwpIHsKICAgICAgZXJyID0gTUVUQURBVEFfSU5WQUxJRF9IQU5ETEU7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBhbGxvY2F0ZSBtZW1vcnkgKi8KICAgIGhNZXRhRGF0YSA9IChIQU5ETEVfRkRLX01FVEFEQVRBX0VOQ09ERVIpIEZES2NhbGxvYygxLCBzaXplb2YoRkRLX01FVEFEQVRBX0VOQ09ERVIpICk7CgogICAgaWYgKGhNZXRhRGF0YSA9PSBOVUxMKSB7CiAgICAgIGVyciA9IE1FVEFEQVRBX01FTU9SWV9FUlJPUjsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIEZES21lbWNsZWFyKGhNZXRhRGF0YSwgc2l6ZW9mKEZES19NRVRBREFUQV9FTkNPREVSKSk7CgogICAgLyogQWxsb2NhdGUgRFJDIENvbXByZXNzb3IuICovCiAgICBpZiAoRkRLX0RSQ19HZW5lcmF0b3JfT3BlbigmaE1ldGFEYXRhLT5oRHJjQ29tcCkhPTApIHsKICAgICAgZXJyID0gTUVUQURBVEFfTUVNT1JZX0VSUk9SOwogICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgLyogUmV0dXJuIG1ldGFkYXRhIGluc3RhbmNlICovCiAgICAqcGhNZXRhRGF0YSA9IGhNZXRhRGF0YTsKCiAgICByZXR1cm4gZXJyOwoKYmFpbDoKICAgIEZES19NZXRhZGF0YUVuY19DbG9zZSgmaE1ldGFEYXRhKTsKICAgIHJldHVybiBlcnI7Cn0KCkZES19NRVRBREFUQV9FUlJPUiBGREtfTWV0YWRhdGFFbmNfQ2xvc2UoCiAgICAgICAgSEFORExFX0ZES19NRVRBREFUQV9FTkNPREVSICpwaE1ldGFEYXRhCiAgICAgICAgKQp7CiAgICBGREtfTUVUQURBVEFfRVJST1IgZXJyID0gTUVUQURBVEFfT0s7CgogICAgaWYgKHBoTWV0YURhdGEgPT0gTlVMTCkgewogICAgICBlcnIgPSBNRVRBREFUQV9JTlZBTElEX0hBTkRMRTsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIGlmICgqcGhNZXRhRGF0YSAhPSBOVUxMKSB7CiAgICAgIEZES19EUkNfR2VuZXJhdG9yX0Nsb3NlKCYoKnBoTWV0YURhdGEpLT5oRHJjQ29tcCk7CiAgICAgIEZES2ZyZWUoKnBoTWV0YURhdGEpOwogICAgICAqcGhNZXRhRGF0YSA9IE5VTEw7CiAgICB9CmJhaWw6CiAgICByZXR1cm4gZXJyOwp9CgpGREtfTUVUQURBVEFfRVJST1IgRkRLX01ldGFkYXRhRW5jX0luaXQoCiAgICAgICAgSEFORExFX0ZES19NRVRBREFUQV9FTkNPREVSIGhNZXRhRGF0YSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgcmVzZXRTdGF0ZXMsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhTW9kZSwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICAgICAgYXVkaW9EZWxheSwKICAgICAgICBjb25zdCBVSU5UICAgICAgICAgICAgICAgICAgZnJhbWVMZW5ndGgsCiAgICAgICAgY29uc3QgVUlOVCAgICAgICAgICAgICAgICAgIHNhbXBsZVJhdGUsCiAgICAgICAgY29uc3QgVUlOVCAgICAgICAgICAgICAgICAgIG5DaGFubmVscywKICAgICAgICBjb25zdCBDSEFOTkVMX01PREUgICAgICAgICAgY2hhbm5lbE1vZGUsCiAgICAgICAgY29uc3QgQ0hBTk5FTF9PUkRFUiAgICAgICAgIGNoYW5uZWxPcmRlcgogICAgICAgICkKewogICAgRkRLX01FVEFEQVRBX0VSUk9SIGVyciA9IE1FVEFEQVRBX09LOwogICAgaW50IGksIG5GcmFtZXMsIGRlbGF5OwoKICAgIGlmIChoTWV0YURhdGE9PU5VTEwpIHsKICAgICAgZXJyID0gTUVUQURBVEFfSU5WQUxJRF9IQU5ETEU7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBEZXRlcm1pbmUgdmFsdWVzIGZvciBkZWxheSBjb21wZW5zYXRpb24uICovCiAgICBmb3IgKG5GcmFtZXM9MCwgZGVsYXk9YXVkaW9EZWxheS1mcmFtZUxlbmd0aDsgZGVsYXk+MDsgZGVsYXktPWZyYW1lTGVuZ3RoLCBuRnJhbWVzKyspOwoKICAgIGlmICggKGhNZXRhRGF0YS0+bkNoYW5uZWxzPk1BWF9EUkNfQ0hBTk5FTFMpIHx8ICgoLWRlbGF5KT5NQVhfRFJDX0ZSQU1FTEVOKSApIHsKICAgICAgZXJyID0gTUVUQURBVEFfSU5JVF9FUlJPUjsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIC8qIEluaXRpYWxpemUgd2l0aCBkZWZhdWx0IHNldHVwLiAqLwogICAgRkRLbWVtY3B5KCZoTWV0YURhdGEtPnN1Ym1pdHRlZE1ldGFEYXRhLCAmZGVmYXVsdE1ldGFEYXRhU2V0dXAsICBzaXplb2YoQUFDRU5DX01ldGFEYXRhKSk7CgogICAgaE1ldGFEYXRhLT5maW5hbGl6ZU1ldGFEYXRhID0gMDsgLyogZmluYWxpemUgbWV0YSBkYXRhIG9ubHkgd2hpbGUgb24vb2ZmIHN3aXRjaGluZywgZWxzZSBkaXNhYmxlZCAqLwoKICAgIC8qIFJlc2V0IGRlbGF5IGxpbmVzLiAqLwogICAgaWYgKCByZXNldFN0YXRlcyB8fCAoaE1ldGFEYXRhLT5uQXVkaW9EYXRhRGVsYXkhPS1kZWxheSkgfHwgKGhNZXRhRGF0YS0+bkNoYW5uZWxzIT0oSU5UKW5DaGFubmVscykgKQogICAgewogICAgICBGREttZW1jbGVhcihoTWV0YURhdGEtPmF1ZGlvRGVsYXlCdWZmZXIsIHNpemVvZihoTWV0YURhdGEtPmF1ZGlvRGVsYXlCdWZmZXIpKTsKICAgICAgRkRLbWVtY2xlYXIoaE1ldGFEYXRhLT5tZXRhRGF0YUJ1ZmZlciwgc2l6ZW9mKGhNZXRhRGF0YS0+bWV0YURhdGFCdWZmZXIpKTsKICAgICAgaE1ldGFEYXRhLT5hdWRpb0RlbGF5SWR4ID0gMDsKICAgICAgaE1ldGFEYXRhLT5tZXRhRGF0YURlbGF5SWR4ID0gMDsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBFbmFibGUgbWV0YSBkYXRhLiAqLwogICAgICBpZiAoIChoTWV0YURhdGEtPm1ldGFkYXRhTW9kZT09MCkgJiYgKG1ldGFkYXRhTW9kZSE9MCkgKSB7CiAgICAgICAgLyogZGlzYWJsZSBtZXRhIGRhdGEgaW4gYWxsIGRlbGF5IGxpbmVzICovCiAgICAgICAgZm9yIChpPTA7IGk8KGludCkoc2l6ZW9mKGhNZXRhRGF0YS0+bWV0YURhdGFCdWZmZXIpL3NpemVvZihBQUNfTUVUQURBVEEpKTsgaSsrKSB7CiAgICAgICAgICBMb2FkU3VibWl0dGVkTWV0YWRhdGEoJmhNZXRhRGF0YS0+c3VibWl0dGVkTWV0YURhdGEsIG5DaGFubmVscywgMCwgJmhNZXRhRGF0YS0+bWV0YURhdGFCdWZmZXJbaV0pOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLyogRGlzYWJsZSBtZXRhIGRhdGEuKi8KICAgICAgaWYgKCAoaE1ldGFEYXRhLT5tZXRhZGF0YU1vZGUhPTApICYmIChtZXRhZGF0YU1vZGU9PTApICkgewogICAgICAgIGhNZXRhRGF0YS0+ZmluYWxpemVNZXRhRGF0YSA9IGhNZXRhRGF0YS0+bWV0YWRhdGFNb2RlOwogICAgICB9CiAgICB9CgogICAgLyogSW5pdGlhbGl6ZSBkZWxheS4gKi8KICAgIGhNZXRhRGF0YS0+bkF1ZGlvRGF0YURlbGF5ID0gLWRlbGF5OwogICAgaE1ldGFEYXRhLT5uTWV0YURhdGFEZWxheSAgPSBuRnJhbWVzOwogICAgaE1ldGFEYXRhLT5uQ2hhbm5lbHMgICAgICAgPSBuQ2hhbm5lbHM7CiAgICBoTWV0YURhdGEtPm1ldGFkYXRhTW9kZSAgICA9IG1ldGFkYXRhTW9kZTsKCiAgICAvKiBJbml0aWFsaXplIGNvbXByZXNzb3IuICovCiAgICBpZiAobWV0YWRhdGFNb2RlICE9IDApIHsKICAgICAgICBpZiAoIEZES19EUkNfR2VuZXJhdG9yX0luaXRpYWxpemUoCiAgICAgICAgICAgICAgICAgICAgICAgICBoTWV0YURhdGEtPmhEcmNDb21wLAogICAgICAgICAgICAgICAgICAgICAgICAgRFJDX05PTkUsCiAgICAgICAgICAgICAgICAgICAgICAgICBEUkNfTk9ORSwKICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxNb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbE9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgMSkgIT0gMCkKICAgICAgICB7CiAgICAgICAgICBlcnIgPSBNRVRBREFUQV9JTklUX0VSUk9SOwogICAgICAgIH0KICAgIH0KYmFpbDoKICAgIHJldHVybiBlcnI7Cn0KCnN0YXRpYyBGREtfTUVUQURBVEFfRVJST1IgUHJvY2Vzc0NvbXByZXNzb3IoCiAgICAgICAgQUFDX01FVEFEQVRBICAgICAgICAgICAgICAgICAgICAqcE1ldGFkYXRhLAogICAgICAgIEhEUkNfQ09NUCAgICAgICAgICAgICAgICAgICAgICAgIGhEcmNDb21wLAogICAgICAgIGNvbnN0IElOVF9QQ00gKiBjb25zdCAgICAgICAgICAgIHBTYW1wbGVzLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgICAgICAgIG5TYW1wbGVzCiAgICAgICAgKQp7CiAgICBGREtfTUVUQURBVEFfRVJST1IgZXJyID0gTUVUQURBVEFfT0s7CgogICAgSU5UIGR5bnJuZywgY29tcHI7CiAgICBEUkNfUFJPRklMRSBwcm9maWxlRHJjICA9IGNvbnZlcnRQcm9maWxlKHBNZXRhZGF0YS0+bXBlZ0RyYy5kcmNfcHJvZmlsZSk7CiAgICBEUkNfUFJPRklMRSBwcm9maWxlQ29tcCA9IGNvbnZlcnRQcm9maWxlKHBNZXRhZGF0YS0+ZXRzaUFuY0RhdGEuY29tcF9wcm9maWxlKTsKCiAgICBpZiAoIChwTWV0YWRhdGE9PU5VTEwpIHx8IChoRHJjQ29tcD09TlVMTCkgKSB7CiAgICAgIGVyciA9IE1FVEFEQVRBX0lOVkFMSURfSEFORExFOwogICAgICByZXR1cm4gZXJyOwogICAgfQoKICAgIC8qIGZpcnN0LCBjaGVjayBpZiBwcm9maWxlIGlzIHNhbWUgYXMgbGFzdCBmcmFtZQogICAgICogb3RoZXJ3aXNlLCB1cGRhdGUgc2V0dXAgKi8KICAgIGlmICggKHByb2ZpbGVEcmMgIT0gRkRLX0RSQ19HZW5lcmF0b3JfZ2V0RHJjUHJvZmlsZShoRHJjQ29tcCkpCiAgICAgIHx8IChwcm9maWxlQ29tcCAhPSBGREtfRFJDX0dlbmVyYXRvcl9nZXRDb21wUHJvZmlsZShoRHJjQ29tcCkpICkKICAgIHsKICAgICAgRkRLX0RSQ19HZW5lcmF0b3Jfc2V0RHJjUHJvZmlsZShoRHJjQ29tcCwgcHJvZmlsZURyYywgcHJvZmlsZUNvbXApOwogICAgfQoKICAgIC8qIFNhbml0eSBjaGVjayAqLwogICAgaWYgKHByb2ZpbGVDb21wID09IERSQ19OT05FKSB7CiAgICAgIHBNZXRhZGF0YS0+ZXRzaUFuY0RhdGEuY29tcHJlc3Npb25fdmFsdWUgPSAweDgwOyAgLyogdG8gZW5zdXJlIG5vIGV4dGVybmFsIHZhbHVlcyB3aWxsIGJlIHdyaXR0ZW4gaWYgbm90IGNvbmZpZ3VyZWQgKi8KICAgIH0KCiAgICAvKiBpbiBjYXNlIG9mIGVtYmVkZGluZyBleHRlcm5hbCB2YWx1ZXMsIGNvcHkgdGhpcyBub3cgKGxpbWl0ZXIgbWF5IG92ZXJ3cml0ZSB0aGVtKSAqLwogICAgZHlucm5nID0gZGVjb2RlRHlucm5nKHBNZXRhZGF0YS0+bXBlZ0RyYy5keW5fcm5nX2N0bFswXSwgcE1ldGFkYXRhLT5tcGVnRHJjLmR5bl9ybmdfc2duWzBdKTsKICAgIGNvbXByICA9IGRlY29kZUNvbXByKHBNZXRhZGF0YS0+ZXRzaUFuY0RhdGEuY29tcHJlc3Npb25fdmFsdWUpOwoKICAgIC8qIENhbGwgY29tcHJlc3NvciAqLwogICAgaWYgKEZES19EUkNfR2VuZXJhdG9yX0NhbGMoaERyY0NvbXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTYW1wbGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9ncmVmbHZsMmRpYWxub3JtKHBNZXRhZGF0YS0+bXBlZ0RyYy5wcm9nX3JlZl9sZXZlbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNZXRhZGF0YS0+bXBlZ0RyYy5kcmNfVGFyZ2V0UmVmTGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNZXRhZGF0YS0+ZXRzaUFuY0RhdGEuY29tcF9UYXJnZXRSZWZMZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZG14VGFibGVbcE1ldGFkYXRhLT5jZW50ZXJNaXhMZXZlbF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRteFRhYmxlW3BNZXRhZGF0YS0+c3Vycm91bmRNaXhMZXZlbF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICZkeW5ybmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICZjb21wcikgIT0gMCkKICAgIHsKICAgICAgZXJyID0gTUVUQURBVEFfRU5DT0RFX0VSUk9SOwogICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgLyogV3JpdGUgRFJDIHZhbHVlcyAqLwogICAgcE1ldGFkYXRhLT5tcGVnRHJjLmRyY19iYW5kX2luY3IgPSAwOwogICAgZW5jb2RlRHlucm5nKGR5bnJuZywgcE1ldGFkYXRhLT5tcGVnRHJjLmR5bl9ybmdfY3RsLCBwTWV0YWRhdGEtPm1wZWdEcmMuZHluX3JuZ19zZ24pOwogICAgcE1ldGFkYXRhLT5ldHNpQW5jRGF0YS5jb21wcmVzc2lvbl92YWx1ZSA9IGVuY29kZUNvbXByKGNvbXByKTsKCmJhaWw6CiAgICByZXR1cm4gZXJyOwp9CgpGREtfTUVUQURBVEFfRVJST1IgRkRLX01ldGFkYXRhRW5jX1Byb2Nlc3MoCiAgICAgICAgSEFORExFX0ZES19NRVRBREFUQV9FTkNPREVSICAgICAgaE1ldGFEYXRhRW5jLAogICAgICAgIElOVF9QQ00gKiBjb25zdCAgICAgICAgICAgICAgICAgIHBBdWRpb1NhbXBsZXMsCiAgICAgICAgY29uc3QgSU5UICAgICAgICAgICAgICAgICAgICAgICAgbkF1ZGlvU2FtcGxlcywKICAgICAgICBjb25zdCBBQUNFTkNfTWV0YURhdGEgKiBjb25zdCAgICBwTWV0YWRhdGEsCiAgICAgICAgQUFDRU5DX0VYVF9QQVlMT0FEICoqICAgICAgICAgICAgcHBNZXRhRGF0YUV4dFBheWxvYWQsCiAgICAgICAgVUlOVCAqICAgICAgICAgICAgICAgICAgICAgICAgICAgbk1ldGFEYXRhRXh0ZW5zaW9ucywKICAgICAgICBJTlQgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXhfbWl4ZG93bl9pZHgKICAgICAgICApCnsKICAgIEZES19NRVRBREFUQV9FUlJPUiBlcnIgPSBNRVRBREFUQV9PSzsKICAgIGludCBtZXRhRGF0YURlbGF5V3JpdGVJZHgsIG1ldGFEYXRhRGVsYXlSZWFkSWR4LCBtZXRhZGF0YU1vZGU7CgogICAgLyogV2hlcmUgdG8gd3JpdGUgbmV3IG1ldGEgZGF0YSBpbmZvICovCiAgICBtZXRhRGF0YURlbGF5V3JpdGVJZHggPSBoTWV0YURhdGFFbmMtPm1ldGFEYXRhRGVsYXlJZHg7CgogICAgLyogSG93IHRvIHdyaXRlIHRoZSBkYXRhICovCiAgICBtZXRhZGF0YU1vZGUgPSBoTWV0YURhdGFFbmMtPm1ldGFkYXRhTW9kZTsKCiAgICAvKiBDb21wZW5zYXRlIG1ldGEgZGF0YSBkZWxheS4gKi8KICAgIGhNZXRhRGF0YUVuYy0+bWV0YURhdGFEZWxheUlkeCsrOwogICAgaWYgKGhNZXRhRGF0YUVuYy0+bWV0YURhdGFEZWxheUlkeCA+IGhNZXRhRGF0YUVuYy0+bk1ldGFEYXRhRGVsYXkpIGhNZXRhRGF0YUVuYy0+bWV0YURhdGFEZWxheUlkeCA9IDA7CgogICAgLyogV2hlcmUgdG8gcmVhZCBwZW5kaW5nIG1ldGEgZGF0YSBpbmZvIGZyb20uICovCiAgICBtZXRhRGF0YURlbGF5UmVhZElkeCA9IGhNZXRhRGF0YUVuYy0+bWV0YURhdGFEZWxheUlkeDsKCiAgICAvKiBTdWJtaXQgbmV3IGRhdGEgaWYgYXZhaWxhYmxlLiAqLwogICAgaWYgKHBNZXRhZGF0YSE9TlVMTCkgewogICAgICAgIEZES21lbWNweSgmaE1ldGFEYXRhRW5jLT5zdWJtaXR0ZWRNZXRhRGF0YSwgcE1ldGFkYXRhLCBzaXplb2YoQUFDRU5DX01ldGFEYXRhKSk7CiAgICB9CgogICAgLyogV3JpdGUgb25lIGFkZGl0aW9uYWwgZnJhbWUgd2l0aCBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gb2YgbWV0YSBkYXRhLiBFbnN1cmUgZGVmaW5lZCBiZWhhdmlvdXIgb24gZGVjb2RlciBzaWRlLiAqLwogICAgaWYgKCAoaE1ldGFEYXRhRW5jLT5maW5hbGl6ZU1ldGFEYXRhIT0wKSAmJiAoaE1ldGFEYXRhRW5jLT5tZXRhZGF0YU1vZGU9PTApKSB7CiAgICAgIEZES21lbWNweSgmaE1ldGFEYXRhRW5jLT5zdWJtaXR0ZWRNZXRhRGF0YSwgJmRlZmF1bHRNZXRhRGF0YVNldHVwLCAgc2l6ZW9mKEFBQ0VOQ19NZXRhRGF0YSkpOwogICAgICBtZXRhZGF0YU1vZGUgPSBoTWV0YURhdGFFbmMtPmZpbmFsaXplTWV0YURhdGE7CiAgICAgIGhNZXRhRGF0YUVuYy0+ZmluYWxpemVNZXRhRGF0YSA9IDA7CiAgICB9CgogICAgLyogR2V0IGxhc3Qgc3VibWl0dGVkIGRhdGEuICovCiAgICBpZiAoIChlcnIgPSBMb2FkU3VibWl0dGVkTWV0YWRhdGEoCiAgICAgICAgICAgICAgICAgICAgICAgICZoTWV0YURhdGFFbmMtPnN1Ym1pdHRlZE1ldGFEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgaE1ldGFEYXRhRW5jLT5uQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YU1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICZoTWV0YURhdGFFbmMtPm1ldGFEYXRhQnVmZmVyW21ldGFEYXRhRGVsYXlXcml0ZUlkeF0pKSAhPSBNRVRBREFUQV9PSyApCiAgICB7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIC8qIENhbGN1bGF0ZSBjb21wcmVzc29yIGlmIG5lY2Vzc2FyeSBhbmQgdXBkYXRhIG1ldGEgZGF0YSBpbmZvICovCiAgICBpZiAoaE1ldGFEYXRhRW5jLT5tZXRhRGF0YUJ1ZmZlclttZXRhRGF0YURlbGF5V3JpdGVJZHhdLm1ldGFkYXRhTW9kZSAhPSAwKSB7CiAgICAgIGlmICggKGVyciA9IFByb2Nlc3NDb21wcmVzc29yKAogICAgICAgICAgICAgICAgICAgICAgICAmaE1ldGFEYXRhRW5jLT5tZXRhRGF0YUJ1ZmZlclttZXRhRGF0YURlbGF5V3JpdGVJZHhdLAogICAgICAgICAgICAgICAgICAgICAgICAgaE1ldGFEYXRhRW5jLT5oRHJjQ29tcCwKICAgICAgICAgICAgICAgICAgICAgICAgIHBBdWRpb1NhbXBsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICBuQXVkaW9TYW1wbGVzKSkgIT0gTUVUQURBVEFfT0spCiAgICAgIHsKICAgICAgICAvKiBHZXQgbGFzdCBzdWJtaXR0ZWQgZGF0YSBhZ2Fpbi4gKi8KICAgICAgICBMb2FkU3VibWl0dGVkTWV0YWRhdGEoCiAgICAgICAgICAgICAgICAgICAgICAgICZoTWV0YURhdGFFbmMtPnN1Ym1pdHRlZE1ldGFEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgaE1ldGFEYXRhRW5jLT5uQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YU1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICZoTWV0YURhdGFFbmMtPm1ldGFEYXRhQnVmZmVyW21ldGFEYXRhRGVsYXlXcml0ZUlkeF0pOwogICAgICB9CiAgICB9CgogICAgLyogQ29udmVydCBNZXRhIERhdGEgc2lkZSBpbmZvIHRvIGJpdHN0cmVhbSBkYXRhLiAqLwogICAgaWYgKCAoZXJyID0gV3JpdGVNZXRhZGF0YVBheWxvYWQoaE1ldGFEYXRhRW5jLCAmaE1ldGFEYXRhRW5jLT5tZXRhRGF0YUJ1ZmZlclttZXRhRGF0YURlbGF5UmVhZElkeF0pKSAhPSBNRVRBREFUQV9PSyApIHsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIC8qIEFzc2lnbiBtZXRhIGRhdGEgdG8gb3V0cHV0ICovCiAgICAqcHBNZXRhRGF0YUV4dFBheWxvYWQgPSBoTWV0YURhdGFFbmMtPmV4UGF5bG9hZDsKICAgICpuTWV0YURhdGFFeHRlbnNpb25zICA9IGhNZXRhRGF0YUVuYy0+bkV4dGVuc2lvbnM7CiAgICAqbWF0cml4X21peGRvd25faWR4ICAgPSBoTWV0YURhdGFFbmMtPm1hdHJpeF9taXhkb3duX2lkeDsKCmJhaWw6CiAgICAvKiBDb21wZW5zYXRlIGF1ZGlvIGRlbGF5LCByZXNldCBlcnIgc3RhdHVzLiAqLwogICAgZXJyID0gQ29tcGVuc2F0ZUF1ZGlvRGVsYXkoaE1ldGFEYXRhRW5jLCBwQXVkaW9TYW1wbGVzLCBuQXVkaW9TYW1wbGVzKTsKCiAgICByZXR1cm4gZXJyOwp9CgoKc3RhdGljIEZES19NRVRBREFUQV9FUlJPUiBDb21wZW5zYXRlQXVkaW9EZWxheSgKICAgICAgICBIQU5ETEVfRkRLX01FVEFEQVRBX0VOQ09ERVIgaE1ldGFEYXRhRW5jLAogICAgICAgIElOVF9QQ00gKiBjb25zdCAgICAgICAgICAgICBwQXVkaW9TYW1wbGVzLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgICBuQXVkaW9TYW1wbGVzCiAgICAgICAgKQp7CiAgICBGREtfTUVUQURBVEFfRVJST1IgZXJyID0gTUVUQURBVEFfT0s7CgogICAgaWYgKGhNZXRhRGF0YUVuYy0+bkF1ZGlvRGF0YURlbGF5KSB7CiAgICAgIGludCBpLCBkZWxheVNhbXBsZXMgPSBoTWV0YURhdGFFbmMtPm5BdWRpb0RhdGFEZWxheSpoTWV0YURhdGFFbmMtPm5DaGFubmVsczsKCiAgICAgIGZvciAoaSA9IDA7IGkgPCBuQXVkaW9TYW1wbGVzOyBpKyspIHsKICAgICAgICBJTlRfUENNIHRtcCA9IHBBdWRpb1NhbXBsZXNbaV07CiAgICAgICAgcEF1ZGlvU2FtcGxlc1tpXSA9IGhNZXRhRGF0YUVuYy0+YXVkaW9EZWxheUJ1ZmZlcltoTWV0YURhdGFFbmMtPmF1ZGlvRGVsYXlJZHhdOwogICAgICAgIGhNZXRhRGF0YUVuYy0+YXVkaW9EZWxheUJ1ZmZlcltoTWV0YURhdGFFbmMtPmF1ZGlvRGVsYXlJZHhdID0gdG1wOwoKICAgICAgICBoTWV0YURhdGFFbmMtPmF1ZGlvRGVsYXlJZHgrKzsKICAgICAgICBpZiAoaE1ldGFEYXRhRW5jLT5hdWRpb0RlbGF5SWR4ID49IGRlbGF5U2FtcGxlcykgaE1ldGFEYXRhRW5jLT5hdWRpb0RlbGF5SWR4ID0gMDsKICAgICAgfQogICAgfQoKICAgIHJldHVybiBlcnI7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgZnVuY3Rpb25uYW1lOiBXcml0ZU1ldGFkYXRhUGF5bG9hZAogIGRlc2NyaXB0aW9uOiAgZmlsbHMgYW5jIGRhdGEgYW5kIGV4dGVuc2lvbiBwYXlsb2FkCiAgcmV0dXJuczogICAgICBFcnJvciBzdGF0dXMKCiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpzdGF0aWMgRkRLX01FVEFEQVRBX0VSUk9SIFdyaXRlTWV0YWRhdGFQYXlsb2FkKAogICAgICAgIGNvbnN0IEhBTkRMRV9GREtfTUVUQURBVEFfRU5DT0RFUiBoTWV0YURhdGEsCiAgICAgICAgY29uc3QgQUFDX01FVEFEQVRBICogY29uc3QgICAgICAgIHBNZXRhZGF0YQogICAgICAgICkKewogICAgRkRLX01FVEFEQVRBX0VSUk9SIGVyciA9IE1FVEFEQVRBX09LOwoKICAgIGlmICggKGhNZXRhRGF0YT09TlVMTCkgfHwgKHBNZXRhZGF0YT09TlVMTCkgKSB7CiAgICAgICAgZXJyID0gTUVUQURBVEFfSU5WQUxJRF9IQU5ETEU7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIGhNZXRhRGF0YS0+bkV4dGVuc2lvbnMgPSAwOwogICAgaE1ldGFEYXRhLT5tYXRyaXhfbWl4ZG93bl9pZHggPSAtMTsKCiAgICAvKiBBQUMtRFJDICovCiAgICBpZiAocE1ldGFkYXRhLT5tZXRhZGF0YU1vZGUgIT0gMCkKICAgIHsKICAgICAgICBoTWV0YURhdGEtPmV4UGF5bG9hZFtoTWV0YURhdGEtPm5FeHRlbnNpb25zXS5wRGF0YSAgICAgICAgICAgICAgID0gaE1ldGFEYXRhLT5kcmNJbmZvUGF5bG9hZDsKICAgICAgICBoTWV0YURhdGEtPmV4UGF5bG9hZFtoTWV0YURhdGEtPm5FeHRlbnNpb25zXS5kYXRhVHlwZSAgICAgICAgICAgID0gRVhUX0RZTkFNSUNfUkFOR0U7CiAgICAgICAgaE1ldGFEYXRhLT5leFBheWxvYWRbaE1ldGFEYXRhLT5uRXh0ZW5zaW9uc10uYXNzb2NpYXRlZENoRWxlbWVudCA9IC0xOwoKICAgICAgICBoTWV0YURhdGEtPmV4UGF5bG9hZFtoTWV0YURhdGEtPm5FeHRlbnNpb25zXS5kYXRhU2l6ZSA9CiAgICAgICAgICAgICAgV3JpdGVEeW5hbWljUmFuZ2VJbmZvUGF5bG9hZChwTWV0YWRhdGEsIGhNZXRhRGF0YS0+ZXhQYXlsb2FkW2hNZXRhRGF0YS0+bkV4dGVuc2lvbnNdLnBEYXRhKTsKCiAgICAgICAgaE1ldGFEYXRhLT5uRXh0ZW5zaW9ucysrOwoKICAgICAgICAvKiBNYXRyaXggTWl4ZG93biBDb2VmZmljaWVudCBpbiBQQ0UgKi8KICAgICAgICBpZiAocE1ldGFkYXRhLT5Xcml0ZVBDRU1peER3bklkeCkgewogICAgICAgICAgICBoTWV0YURhdGEtPm1hdHJpeF9taXhkb3duX2lkeCA9IHN1cm1peDJtYXRyaXhfbWl4ZG93bl9pZHhbcE1ldGFkYXRhLT5zdXJyb3VuZE1peExldmVsXTsKICAgICAgICB9CgogICAgICAgIC8qIEVUU0kgVFMgMTAxIDE1NCAoRFZCKSAtIE1QRUc0IGFuY2lsbGFyeV9kYXRhKCkgKi8KICAgICAgICBpZiAocE1ldGFkYXRhLT5tZXRhZGF0YU1vZGUgPT0gMikgLyogTVA0X01FVEFEQVRBX01QRUdfRVRTSSAqLwogICAgICAgIHsKICAgICAgICAgICAgaE1ldGFEYXRhLT5leFBheWxvYWRbaE1ldGFEYXRhLT5uRXh0ZW5zaW9uc10ucERhdGEgICAgICAgICAgICAgICA9IGhNZXRhRGF0YS0+ZHJjRHNlUGF5bG9hZDsKICAgICAgICAgICAgaE1ldGFEYXRhLT5leFBheWxvYWRbaE1ldGFEYXRhLT5uRXh0ZW5zaW9uc10uZGF0YVR5cGUgICAgICAgICAgICA9IEVYVF9EQVRBX0VMRU1FTlQ7CiAgICAgICAgICAgIGhNZXRhRGF0YS0+ZXhQYXlsb2FkW2hNZXRhRGF0YS0+bkV4dGVuc2lvbnNdLmFzc29jaWF0ZWRDaEVsZW1lbnQgPSAtMTsKCiAgICAgICAgICAgIGhNZXRhRGF0YS0+ZXhQYXlsb2FkW2hNZXRhRGF0YS0+bkV4dGVuc2lvbnNdLmRhdGFTaXplID0KICAgICAgICAgICAgICAgICBXcml0ZUV0c2lBbmNpbGxhcnlEYXRhUGF5bG9hZChwTWV0YWRhdGEsaE1ldGFEYXRhLT5leFBheWxvYWRbaE1ldGFEYXRhLT5uRXh0ZW5zaW9uc10ucERhdGEpOwoKICAgICAgICAgICAgaE1ldGFEYXRhLT5uRXh0ZW5zaW9ucysrOwogICAgICAgIH0gLyogbWV0YWRhdGFNb2RlID09IDIgKi8KCiAgICB9IC8qIG1ldGFkYXRhTW9kZSAhPSAwICovCgpiYWlsOgogICAgcmV0dXJuIGVycjsKfQoKc3RhdGljIElOVCBXcml0ZUR5bmFtaWNSYW5nZUluZm9QYXlsb2FkKAogICAgICAgIGNvbnN0IEFBQ19NRVRBREFUQSogY29uc3QgcE1ldGFkYXRhLAogICAgICAgIFVDSEFSKiBjb25zdCAgICAgICAgICAgICAgcEV4dGVuc2lvblBheWxvYWQKICAgICAgICApCnsKICAgIGNvbnN0IElOVCBwY2VfdGFnX3ByZXNlbnQgPSAwOyAgICAgICAgLyogeWV0IGZpeGVkIHNldHRpbmchICovCiAgICBjb25zdCBJTlQgcHJvZ19yZWZfbGV2X3Jlc19iaXRzID0gMDsKICAgIElOVCBpLCBkcmNfbnVtX2JhbmRzID0gMTsKCiAgICBGREtfQklUU1RSRUFNIGJzV3JpdGVyOwogICAgRkRLaW5pdEJpdFN0cmVhbSgmYnNXcml0ZXIsIHBFeHRlbnNpb25QYXlsb2FkLCAxNiwgMCwgQlNfV1JJVEVSKTsKCiAgICAvKiBkeW5hbWljX3JhbmdlX2luZm8oKSAqLwogICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgcGNlX3RhZ19wcmVzZW50LCAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHBjZV90YWdfcHJlc2VudCAqLwogICAgaWYgKHBjZV90YWdfcHJlc2VudCkgewogICAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCAweDAsIDQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHBjZV9pbnN0YW5jZV90YWcgKi8KICAgICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgMHgwLCA0KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBkcmNfdGFnX3Jlc2VydmVkX2JpdHMgKi8KICAgfQoKICAgIC8qIEV4Y2x1ZGUgY2hhbm5lbHMgKi8KICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIChwTWV0YWRhdGEtPm1wZWdEcmMuZXhjbHVkZWRfY2huc19wcmVzZW50KSA/IDEgOiAwLCAxKTsgICAgICAvKiBleGNsdWRlZF9jaG5zX3ByZXNlbnQqLwoKICAgIC8qIE11bHRpYmFuZCBEUkMgKi8KICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIChwTWV0YWRhdGEtPm1wZWdEcmMuZHJjX2JhbmRzX3ByZXNlbnQpID8gMSA6IDAsIDEpOyAgICAgICAgICAvKiBkcmNfYmFuZHNfcHJlc2VudCAqLwogICAgaWYgKHBNZXRhZGF0YS0+bXBlZ0RyYy5kcmNfYmFuZHNfcHJlc2VudCkKICAgIHsKICAgICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgcE1ldGFkYXRhLT5tcGVnRHJjLmRyY19iYW5kX2luY3IsIDQpOyAgICAgICAgICAgICAgICAgICAgICAvKiBkcmNfYmFuZF9pbmNyICovCiAgICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIHBNZXRhZGF0YS0+bXBlZ0RyYy5kcmNfaW50ZXJwb2xhdGlvbl9zY2hlbWUsIDQpOyAgICAgICAgICAgLyogZHJjX2ludGVycG9sYXRpb25fc2NoZW1lICovCiAgICAgIGRyY19udW1fYmFuZHMgKz0gcE1ldGFkYXRhLT5tcGVnRHJjLmRyY19iYW5kX2luY3I7CiAgICAgIGZvciAoaT0wOyBpPGRyY19udW1fYmFuZHM7IGkrKykgewogICAgICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIHBNZXRhZGF0YS0+bXBlZ0RyYy5kcmNfYmFuZF90b3BbaV0sIDgpOyAgICAgICAgICAgICAgICAgIC8qIGRyY19iYW5kX3RvcCAqLwogICAgICB9CiAgICB9CgogICAgLyogUHJvZ3JhbSBSZWZlcmVuY2UgTGV2ZWwgKi8KICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIHBNZXRhZGF0YS0+bXBlZ0RyYy5wcm9nX3JlZl9sZXZlbF9wcmVzZW50LCAxKTsgICAgICAgICAgICAgICAvKiBwcm9nX3JlZl9sZXZlbF9wcmVzZW50ICovCiAgICBpZiAocE1ldGFkYXRhLT5tcGVnRHJjLnByb2dfcmVmX2xldmVsX3ByZXNlbnQpCiAgICB7CiAgICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIHBNZXRhZGF0YS0+bXBlZ0RyYy5wcm9nX3JlZl9sZXZlbCwgNyk7ICAgICAgICAgICAgICAgICAgICAgLyogcHJvZ19yZWZfbGV2ZWwgKi8KICAgICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgcHJvZ19yZWZfbGV2X3Jlc19iaXRzLCAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBwcm9nX3JlZl9sZXZlbF9yZXNlcnZlZF9iaXRzICovCiAgICB9CgogICAgLyogRFJDIFZhbHVlcyAqLwogICAgZm9yIChpPTA7IGk8ZHJjX251bV9iYW5kczsgaSsrKSB7CiAgICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIChwTWV0YWRhdGEtPm1wZWdEcmMuZHluX3JuZ19zZ25baV0pID8gMSA6IDAsIDEpOyAgICAgICAgICAgLyogZHluX3JuZ19zZ25bICovCiAgICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIHBNZXRhZGF0YS0+bXBlZ0RyYy5keW5fcm5nX2N0bFtpXSwgNyk7ICAgICAgICAgICAgICAgICAgICAgLyogZHluX3JuZ19jdGwgKi8KICAgIH0KCiAgICAvKiByZXR1cm4gbnVtYmVyIG9mIHZhbGlkIGJpdHMgaW4gZXh0ZW5zaW9uIHBheWxvYWQuICovCiAgICByZXR1cm4gRkRLZ2V0VmFsaWRCaXRzKCZic1dyaXRlcik7Cn0KCnN0YXRpYyBJTlQgV3JpdGVFdHNpQW5jaWxsYXJ5RGF0YVBheWxvYWQoCiAgICAgICAgY29uc3QgQUFDX01FVEFEQVRBKiBjb25zdCBwTWV0YWRhdGEsCiAgICAgICAgVUNIQVIqIGNvbnN0ICAgICAgICAgICAgICBwRXh0ZW5zaW9uUGF5bG9hZAogICAgICAgICkKewogICAgRkRLX0JJVFNUUkVBTSBic1dyaXRlcjsKICAgIEZES2luaXRCaXRTdHJlYW0oJmJzV3JpdGVyLCBwRXh0ZW5zaW9uUGF5bG9hZCwgMTYsIDAsIEJTX1dSSVRFUik7CgogICAgLyogYW5jaWxsYXJ5X2RhdGFfc3luYyAqLwogICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgMHhCQywgOCk7CgogICAgLyogYnNfaW5mbyAqLwogICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgMHgzLCAyKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG1wZWdfYXVkaW9fdHlwZSAqLwogICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgcE1ldGFkYXRhLT5kb2xieVN1cnJvdW5kTW9kZSwgMik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGRvbGJ5X3N1cnJvdW5kX21vZGUgKi8KICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIDB4MCwgNCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiByZXNlcnZlZCAqLwoKICAgIC8qIGFuY2lsbGFyeV9kYXRhX3N0YXR1cyAqLwogICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgMCwgMyk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIDMgYml0IFJlc2VydmVkLCBzZXQgdG8gIjAiICovCiAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCAocE1ldGFkYXRhLT5EbXhMdmxfT24pID8gMSA6IDAsIDEpOyAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZG93bm1peGluZ19sZXZlbHNfTVBFRzRfc3RhdHVzICovCiAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCAwLCAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogUmVzZXJ2ZWQsIHNldCB0byAiMCIgKi8KICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIChwTWV0YWRhdGEtPmV0c2lBbmNEYXRhLmNvbXByZXNzaW9uX29uKSA/IDEgOiAwLCAxKTsgICAgICAgICAvKiBhdWRpb19jb2RpbmdfbW9kZV9hbmRfY29tcHJlc3Npb24gc3RhdHVzICovCiAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCAocE1ldGFkYXRhLT5ldHNpQW5jRGF0YS50aW1lY29kZV9jb2Fyc2Vfc3RhdHVzKSA/IDEgOiAwLCAxKTsgLyogY29hcnNlX2dyYWluX3RpbWVjb2RlX3N0YXR1cyAqLwogICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgKHBNZXRhZGF0YS0+ZXRzaUFuY0RhdGEudGltZWNvZGVfZmluZV9zdGF0dXMpID8gMSA6IDAsIDEpOyAgIC8qIGZpbmVfZ3JhaW5fdGltZWNvZGVfc3RhdHVzICovCgogICAgLyogZG93bm1peGluZ19sZXZlbHNfTVBFRzRfc3RhdHVzICovCiAgICBpZiAocE1ldGFkYXRhLT5EbXhMdmxfT24pIHsKICAgICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgZW5jb2RlRG14THZscyhwTWV0YWRhdGEtPmNlbnRlck1peExldmVsLCBwTWV0YWRhdGEtPnN1cnJvdW5kTWl4TGV2ZWwpLCA4KTsKICAgIH0KCiAgICAvKiBhdWRpb19jb2RpbmdfbW9kZV9hbmRfY29tcHJlc3Npb25fc3RhdHVzICovCiAgICBpZiAocE1ldGFkYXRhLT5ldHNpQW5jRGF0YS5jb21wcmVzc2lvbl9vbikgewogICAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCAweDAxLCA4KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGF1ZGlvIGNvZGluZyBtb2RlICovCiAgICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIHBNZXRhZGF0YS0+ZXRzaUFuY0RhdGEuY29tcHJlc3Npb25fdmFsdWUsIDgpOyAgICAgICAgICAgICAgLyogY29tcHJlc3Npb24gdmFsdWUgKi8KICAgIH0KCiAgICAvKiBncmFpbi10aW1lY29kZSBjb2Fyc2UvZmluZSAqLwogICAgaWYgKHBNZXRhZGF0YS0+ZXRzaUFuY0RhdGEudGltZWNvZGVfY29hcnNlX3N0YXR1cykgewogICAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCAweDAsIDE2KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5vdCB5ZXQgc3VwcG9ydGVkICovCiAgICB9CgogICAgaWYgKHBNZXRhZGF0YS0+ZXRzaUFuY0RhdGEudGltZWNvZGVfZmluZV9zdGF0dXMpIHsKICAgICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgMHgwLCAxNik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBub3QgeWV0IHN1cHBvcnRlZCAqLwogICAgfQoKICAgIHJldHVybiBGREtnZXRWYWxpZEJpdHMoJmJzV3JpdGVyKTsKfQoKCnN0YXRpYyBGREtfTUVUQURBVEFfRVJST1IgTG9hZFN1Ym1pdHRlZE1ldGFkYXRhKAogICAgICAgIGNvbnN0IEFBQ0VOQ19NZXRhRGF0YSAqIGNvbnN0ICAgaE1ldGFkYXRhLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgICAgICAgbkNoYW5uZWxzLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGFNb2RlLAogICAgICAgIEFBQ19NRVRBREFUQSAqIGNvbnN0ICAgICAgICAgICAgcEFhY01ldGFEYXRhCiAgICAgICAgKQp7CiAgICBGREtfTUVUQURBVEFfRVJST1IgZXJyID0gTUVUQURBVEFfT0s7CgogICAgaWYgKHBBYWNNZXRhRGF0YT09TlVMTCkgewogICAgICBlcnIgPSBNRVRBREFUQV9JTlZBTElEX0hBTkRMRTsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBpbml0IHN0cnVjdCAqLwogICAgICBGREttZW1jbGVhcihwQWFjTWV0YURhdGEsIHNpemVvZihBQUNfTUVUQURBVEEpKTsKCiAgICAgIGlmIChoTWV0YWRhdGEhPU5VTEwpIHsKICAgICAgICAvKiBjb252ZXJ0IGRhdGEgKi8KICAgICAgICBwQWFjTWV0YURhdGEtPm1wZWdEcmMuZHJjX3Byb2ZpbGUgICAgICAgICAgICA9IGhNZXRhZGF0YS0+ZHJjX3Byb2ZpbGU7CiAgICAgICAgcEFhY01ldGFEYXRhLT5ldHNpQW5jRGF0YS5jb21wX3Byb2ZpbGUgICAgICAgPSBoTWV0YWRhdGEtPmNvbXBfcHJvZmlsZTsKICAgICAgICBwQWFjTWV0YURhdGEtPm1wZWdEcmMuZHJjX1RhcmdldFJlZkxldmVsICAgICA9IGhNZXRhZGF0YS0+ZHJjX1RhcmdldFJlZkxldmVsOwogICAgICAgIHBBYWNNZXRhRGF0YS0+ZXRzaUFuY0RhdGEuY29tcF9UYXJnZXRSZWZMZXZlbD0gaE1ldGFkYXRhLT5jb21wX1RhcmdldFJlZkxldmVsOwogICAgICAgIHBBYWNNZXRhRGF0YS0+bXBlZ0RyYy5wcm9nX3JlZl9sZXZlbF9wcmVzZW50ID0gaE1ldGFkYXRhLT5wcm9nX3JlZl9sZXZlbF9wcmVzZW50OwogICAgICAgIHBBYWNNZXRhRGF0YS0+bXBlZ0RyYy5wcm9nX3JlZl9sZXZlbCAgICAgICAgID0gZGlhbG5vcm0ycHJvZ3JlZmx2bChoTWV0YWRhdGEtPnByb2dfcmVmX2xldmVsKTsKCiAgICAgICAgcEFhY01ldGFEYXRhLT5jZW50ZXJNaXhMZXZlbCAgICAgICAgICAgICAgICAgPSBoTWV0YWRhdGEtPmNlbnRlck1peExldmVsOwogICAgICAgIHBBYWNNZXRhRGF0YS0+c3Vycm91bmRNaXhMZXZlbCAgICAgICAgICAgICAgID0gaE1ldGFkYXRhLT5zdXJyb3VuZE1peExldmVsOwogICAgICAgIHBBYWNNZXRhRGF0YS0+V3JpdGVQQ0VNaXhEd25JZHggICAgICAgICAgICAgID0gaE1ldGFkYXRhLT5QQ0VfbWl4ZG93bl9pZHhfcHJlc2VudDsKICAgICAgICBwQWFjTWV0YURhdGEtPkRteEx2bF9PbiAgICAgICAgICAgICAgICAgICAgICA9IGhNZXRhZGF0YS0+RVRTSV9EbXhMdmxfcHJlc2VudDsKCiAgICAgICAgcEFhY01ldGFEYXRhLT5ldHNpQW5jRGF0YS5jb21wcmVzc2lvbl9vbiA9IDE7CgoKICAgICAgICBpZiAobkNoYW5uZWxzID09IDIpIHsKICAgICAgICAgIHBBYWNNZXRhRGF0YS0+ZG9sYnlTdXJyb3VuZE1vZGUgPSBoTWV0YWRhdGEtPmRvbGJ5U3Vycm91bmRNb2RlOyAgICAgLyogZG9sYnlfc3Vycm91bmRfbW9kZSAqLwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBwQWFjTWV0YURhdGEtPmRvbGJ5U3Vycm91bmRNb2RlID0gMDsKICAgICAgICB9CgogICAgICAgIHBBYWNNZXRhRGF0YS0+ZXRzaUFuY0RhdGEudGltZWNvZGVfY29hcnNlX3N0YXR1cyA9IDA7IC8qIG5vdCB5ZXQgc3VwcG9ydGVkIC0gYXR0ZW50aW9uOiBVcGRhdGUgR2V0RXN0TWV0YWRhdGFCeXRlc1BlckZyYW1lKCkgaWYgZW5hYmxlIHRoaXMhICovCiAgICAgICAgcEFhY01ldGFEYXRhLT5ldHNpQW5jRGF0YS50aW1lY29kZV9maW5lX3N0YXR1cyAgID0gMDsgLyogbm90IHlldCBzdXBwb3J0ZWQgLSBhdHRlbnRpb246IFVwZGF0ZSBHZXRFc3RNZXRhZGF0YUJ5dGVzUGVyRnJhbWUoKSBpZiBlbmFibGUgdGhpcyEgKi8KCiAgICAgICAgcEFhY01ldGFEYXRhLT5tZXRhZGF0YU1vZGUgPSBtZXRhZGF0YU1vZGU7CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgcEFhY01ldGFEYXRhLT5tZXRhZGF0YU1vZGUgPSAwOyAgICAgICAgICAgICAgICAgICAgICAvKiB0aGVyZSBpcyBubyBjb25maWd1cmF0aW9uIGF2YWlsYWJsZSAqLwogICAgICB9CiAgICB9CgogICAgcmV0dXJuIGVycjsKfQoKSU5UIEZES19NZXRhZGF0YUVuY19HZXREZWxheSgKICAgICAgICBIQU5ETEVfRkRLX01FVEFEQVRBX0VOQ09ERVIgaE1ldGFkYXRhRW5jCiAgICAgICAgKQp7CiAgICBJTlQgZGVsYXkgPSAwOwoKICAgIGlmIChoTWV0YWRhdGFFbmMhPU5VTEwpIHsKICAgICAgICBkZWxheSA9IGhNZXRhZGF0YUVuYy0+bkF1ZGlvRGF0YURlbGF5OwogICAgfQoKICAgIHJldHVybiBkZWxheTsKfQoKCg==