Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogTVBFRyBBdWRpbyBFbmNvZGVyICoqKioqKioqKioqKioqKioqKioqKioqKioqCgogICBJbml0aWFsIGF1dGhvcjogICAgICAgTS5XZXJuZXIKICAgY29udGVudHMvZGVzY3JpcHRpb246IFBzeWNob2FjY291c3RpYyBtYWpvciBmdW5jdGlvbiBibG9jawoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgInBzeV9jb25zdC5oIgoKI2luY2x1ZGUgImJsb2NrX3N3aXRjaC5oIgojaW5jbHVkZSAidHJhbnNmb3JtLmgiCiNpbmNsdWRlICJzcHJlYWRpbmcuaCIKI2luY2x1ZGUgInByZV9lY2hvX2NvbnRyb2wuaCIKI2luY2x1ZGUgImJhbmRfbnJnLmgiCiNpbmNsdWRlICJwc3lfY29uZmlndXJhdGlvbi5oIgojaW5jbHVkZSAicHN5X2RhdGEuaCIKI2luY2x1ZGUgIm1zX3N0ZXJlby5oIgojaW5jbHVkZSAiaW50ZXJmYWNlLmgiCiNpbmNsdWRlICJwc3lfbWFpbi5oIgojaW5jbHVkZSAiZ3JwX2RhdGEuaCIKI2luY2x1ZGUgInRuc19mdW5jLmgiCiNpbmNsdWRlICJwbnNfZnVuYy5oIgojaW5jbHVkZSAidG9uYWxpdHkuaCIKI2luY2x1ZGUgImFhY0VuY19yYW0uaCIKI2luY2x1ZGUgImludGVuc2l0eS5oIgoKCgovKiBibGVuZGluZyB0byByZWR1Y2UgZ2liYnMgYXJ0aWZhY3RzICovCiNkZWZpbmUgRkFERV9PVVRfTEVOIDYKc3RhdGljIGNvbnN0IEZJWFBfREJMIGZhZGVPdXRGYWN0b3JbRkFERV9PVVRfTEVOXSA9IHsxODQwNjQ0MDk2LCAxNTMzODcwMDgwLCAxMjI3MDk2MDY0LCA5MjAzMjIwNDgsIDYxMzU0ODAzMiwgMzA2Nzc0MDE2fTsKCi8qIGZvcndhcmQgZGVmaW5pdGlvbnMgKi8KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgICBmdW5jdGlvbm5hbWU6IEZES2FhY0VuY19Qc3lOZXcKICAgIGRlc2NyaXB0aW9uOiAgYWxsb2NhdGVzIG1lbW9yeSBmb3IgcHN5Y2hvYWNvdXN0aWMKICAgIHJldHVybnM6ICAgICAgYW4gZXJyb3IgY29kZQogICAgaW5wdXQ6ICAgICAgICBwb2ludGVyIHRvIGEgcHN5Y2ggaGFuZGxlCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KQUFDX0VOQ09ERVJfRVJST1IgRkRLYWFjRW5jX1BzeU5ldyhQU1lfSU5URVJOQUwgICoqcGhwc3ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICAgICAgIG5FbGVtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICAgICAgbkNoYW5uZWxzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsVUNIQVIgICAgICAgICAgKmR5bmFtaWNfUkFNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICAgIEFBQ19FTkNPREVSX0VSUk9SIEVycm9yU3RhdHVzOwogICAgUFNZX0lOVEVSTkFMICpoUHN5OwogICAgSU5UIGk7CgogICAgaFBzeSA9IEdldFJhbV9hYWNFbmNfUHN5SW50ZXJuYWwoKTsKICAgICpwaHBzeSA9IGhQc3k7CiAgICBpZiAoaFBzeSA9PSBOVUxMKSB7CiAgICAgIEVycm9yU3RhdHVzID0gQUFDX0VOQ19OT19NRU1PUlk7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICBmb3IgKGk9MDsgaTxuRWxlbWVudHM7IGkrKykgewogICAgICAgIC8qIFBTWV9FTEVNRU5UICovCiAgICAgICAgaFBzeS0+cHN5RWxlbWVudFtpXSA9IEdldFJhbV9hYWNFbmNfUHN5RWxlbWVudChpKTsKICAgICAgICBpZiAoaFBzeS0+cHN5RWxlbWVudFtpXSA9PSBOVUxMKSB7CiAgICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19FTkNfTk9fTUVNT1JZOwogICAgICAgICAgZ290byBiYWlsOwogICAgICAgIH0KICAgIH0KCiAgICBmb3IgKGk9MDsgaTxuQ2hhbm5lbHM7IGkrKykgewogICAgICAgIC8qIFBTWV9TVEFUSUMgKi8KICAgICAgICBoUHN5LT5wU3RhdGljQ2hhbm5lbHNbaV0gPSBHZXRSYW1fYWFjRW5jX1BzeVN0YXRpYyhpKTsKICAgICAgICBpZiAoaFBzeS0+cFN0YXRpY0NoYW5uZWxzW2ldPT1OVUxMKSB7CiAgICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19FTkNfTk9fTUVNT1JZOwogICAgICAgICAgZ290byBiYWlsOwogICAgICAgIH0KICAgICAgICAvKiBBVURJTyBJTlBVVCBCVUZGRVIgKi8KICAgICAgICBoUHN5LT5wU3RhdGljQ2hhbm5lbHNbaV0tPnBzeUlucHV0QnVmZmVyID0gR2V0UmFtX2FhY0VuY19Qc3lJbnB1dEJ1ZmZlcihpKTsKICAgICAgICBpZiAoaFBzeS0+cFN0YXRpY0NoYW5uZWxzW2ldLT5wc3lJbnB1dEJ1ZmZlcj09TlVMTCkgewogICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfRU5DX05PX01FTU9SWTsKICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICB9CiAgICB9CgogICAgLyogcmV1c2FibGUgcHN5Y2ggbWVtb3J5ICovCiAgICBoUHN5LT5wc3lEeW5hbWljID0gR2V0UmFtX2FhY0VuY19Qc3lEeW5hbWljKDAsIGR5bmFtaWNfUkFNKTsKCiAgICByZXR1cm4gQUFDX0VOQ19PSzsKCmJhaWw6CiAgIEZES2FhY0VuY19Qc3lDbG9zZShwaHBzeSwgTlVMTCk7CgogICByZXR1cm4gRXJyb3JTdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX1BzeU91dE5ldwogICAgZGVzY3JpcHRpb246ICBhbGxvY2F0ZXMgbWVtb3J5IGZvciBwc3lPdXQgc3RydWMKICAgIHJldHVybnM6ICAgICAgYW4gZXJyb3IgY29kZQogICAgaW5wdXQ6ICAgICAgICBwb2ludGVyIHRvIGEgcHN5Y2ggaGFuZGxlCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KQUFDX0VOQ09ERVJfRVJST1IgRkRLYWFjRW5jX1BzeU91dE5ldyhQU1lfT1VUICAgKipwaHBzeU91dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICBuRWxlbWVudHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSU5UICAgbkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgIG5TdWJGcmFtZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxVQ0hBUiAgICAgICpkeW5hbWljX1JBTQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQp7CiAgQUFDX0VOQ09ERVJfRVJST1IgRXJyb3JTdGF0dXM7CiAgaW50IG4sIGk7CiAgaW50IGVsSW5jID0gMCwgY2hJbmMgPSAwOwoKICBmb3IgKG49MDsgbjxuU3ViRnJhbWVzOyBuKyspIHsKICAgIHBocHN5T3V0W25dID0gR2V0UmFtX2FhY0VuY19Qc3lPdXQobik7CgogICAgaWYgKHBocHN5T3V0W25dID09IE5VTEwpIHsKICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfRU5DX05PX01FTU9SWTsKICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIGZvciAoaT0wOyBpPG5DaGFubmVsczsgaSsrKSB7CiAgICAgIHBocHN5T3V0W25dLT5wUHN5T3V0Q2hhbm5lbHNbaV0gPSBHZXRSYW1fYWFjRW5jX1BzeU91dENoYW5uZWwoY2hJbmMrKyk7CiAgICB9CgogICAgZm9yIChpPTA7IGk8bkVsZW1lbnRzOyBpKyspIHsKICAgICAgcGhwc3lPdXRbbl0tPnBzeU91dEVsZW1lbnRbaV0gPSBHZXRSYW1fYWFjRW5jX1BzeU91dEVsZW1lbnRzKGVsSW5jKyspOwogICAgICBpZiAocGhwc3lPdXRbbl0tPnBzeU91dEVsZW1lbnRbaV0gPT0gTlVMTCkgewogICAgICAgIEVycm9yU3RhdHVzID0gQUFDX0VOQ19OT19NRU1PUlk7CiAgICAgICAgZ290byBiYWlsOwogICAgICB9CiAgICB9CiAgfSAvKiBuU3ViRnJhbWVzICovCgogIHJldHVybiBBQUNfRU5DX09LOwoKYmFpbDoKICBGREthYWNFbmNfUHN5Q2xvc2UoTlVMTCwgcGhwc3lPdXQpOwogIHJldHVybiBFcnJvclN0YXR1czsKfQoKCkFBQ19FTkNPREVSX0VSUk9SIEZES2FhY0VuY19wc3lJbml0U3RhdGVzKFBTWV9JTlRFUk5BTCAgICAqaFBzeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNZX1NUQVRJQyogcHN5U3RhdGljLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBVURJT19PQkpFQ1RfVFlQRSBhdWRpb09iamVjdFR5cGUpCnsKICAvKiBpbml0IGlucHV0IGJ1ZmZlciAqLwogIEZES21lbWNsZWFyKHBzeVN0YXRpYy0+cHN5SW5wdXRCdWZmZXIsIE1BWF9JTlBVVF9CVUZGRVJfU0laRSpzaXplb2YoSU5UX1BDTSkpOwoKICBGREthYWNFbmNfSW5pdEJsb2NrU3dpdGNoaW5nKCZwc3lTdGF0aWMtPmJsb2NrU3dpdGNoaW5nQ29udHJvbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0xvd0RlbGF5KGF1ZGlvT2JqZWN0VHlwZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CgogIHJldHVybiBBQUNfRU5DX09LOwp9CgoKQUFDX0VOQ09ERVJfRVJST1IgRkRLYWFjRW5jX3BzeUluaXQoUFNZX0lOVEVSTkFMICAgICpoUHN5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU1lfT1VUICAgICAgICAqKnBocHN5T3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJTlQgICAgICAgIG5TdWJGcmFtZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICAgICAgbk1heENoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBBVURJT19PQkpFQ1RfVFlQRSBhdWRpb09iamVjdFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIQU5ORUxfTUFQUElORyAqY20pCnsKICBBQUNfRU5DT0RFUl9FUlJPUiBFcnJvclN0YXR1cyA9IEFBQ19FTkNfT0s7CiAgaW50IGksIGNoLCBuLCBjaEluYyA9IDAsIHJlc2V0Q2hhbm5lbHMgPSAzOwoKICBpZiAoIChuTWF4Q2hhbm5lbHM+MikgJiYgKGNtLT5uQ2hhbm5lbHM9PTIpICkgewogICAgY2hJbmMgPSAxOwogICAgRkRLYWFjRW5jX3BzeUluaXRTdGF0ZXMoaFBzeSwgaFBzeS0+cFN0YXRpY0NoYW5uZWxzWzBdLCBhdWRpb09iamVjdFR5cGUpOwogIH0KCiAgaWYgKCAobk1heENoYW5uZWxzPT0yKSApIHsKICAgIHJlc2V0Q2hhbm5lbHMgPSAwOwogIH0KCiAgZm9yIChpPTA7IGk8Y20tPm5FbGVtZW50czsgaSsrKSB7CiAgICBmb3IgKGNoPTA7IGNoPGNtLT5lbEluZm9baV0ubkNoYW5uZWxzSW5FbDsgY2grKykgewogICAgICBpZiAoY20tPmVsSW5mb1tpXS5lbFR5cGUhPUlEX0xGRSkgewogICAgICAgIGhQc3ktPnBzeUVsZW1lbnRbaV0tPnBzeVN0YXRpY1tjaF0gPSBoUHN5LT5wU3RhdGljQ2hhbm5lbHNbY2hJbmNdOwogICAgICAgIGlmIChjaEluYz49cmVzZXRDaGFubmVscykgewogICAgICAgICAgICBGREthYWNFbmNfcHN5SW5pdFN0YXRlcyhoUHN5LCBoUHN5LT5wc3lFbGVtZW50W2ldLT5wc3lTdGF0aWNbY2hdLCBhdWRpb09iamVjdFR5cGUpOwogICAgICAgIH0KICAgICAgICBoUHN5LT5wc3lFbGVtZW50W2ldLT5wc3lTdGF0aWNbY2hdLT5pc0xGRSA9IDA7CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgaFBzeS0+cHN5RWxlbWVudFtpXS0+cHN5U3RhdGljW2NoXSA9IGhQc3ktPnBTdGF0aWNDaGFubmVsc1tuTWF4Q2hhbm5lbHMtMV07CiAgICAgICAgaFBzeS0+cHN5RWxlbWVudFtpXS0+cHN5U3RhdGljW2NoXS0+aXNMRkUgPSAxOwogICAgICB9CiAgICAgIGNoSW5jKys7CiAgICB9CiAgfQoKICBmb3IgKG49MDsgbjxuU3ViRnJhbWVzOyBuKyspIHsKICAgIGNoSW5jID0gMDsKICAgIGZvciAoaT0wOyBpPGNtLT5uRWxlbWVudHM7IGkrKykgewogICAgICBmb3IgKGNoPTA7IGNoPGNtLT5lbEluZm9baV0ubkNoYW5uZWxzSW5FbDsgY2grKykgewogICAgICAgIHBocHN5T3V0W25dLT5wc3lPdXRFbGVtZW50W2ldLT5wc3lPdXRDaGFubmVsW2NoXSA9IHBocHN5T3V0W25dLT5wUHN5T3V0Q2hhbm5lbHNbY2hJbmMrK107CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBFcnJvclN0YXR1czsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgIGZ1bmN0aW9ubmFtZTogRkRLYWFjRW5jX3BzeU1haW5Jbml0CiAgICBkZXNjcmlwdGlvbjogIGluaXRpYWxpemVzIHBzeWNob2Fjb3VzdGljCiAgICByZXR1cm5zOiAgICAgIGFuIGVycm9yIGNvZGUKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKQUFDX0VOQ09ERVJfRVJST1IgRkRLYWFjRW5jX3BzeU1haW5Jbml0KFBTWV9JTlRFUk5BTCAqaFBzeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFVRElPX09CSkVDVF9UWVBFIGF1ZGlvT2JqZWN0VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENIQU5ORUxfTUFQUElORyAqY20sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgc2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBncmFudWxlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIGJpdFJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgdG5zTWFzaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBiYW5kd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgdXNlUG5zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UIHVzZUlTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBzeW50YXhGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIGluaXRGbGFncykKewogIEFBQ19FTkNPREVSX0VSUk9SIEVycm9yU3RhdHVzOwogIGludCBpLCBjaDsKICBpbnQgY2hhbm5lbHNFZmYgPSBjbS0+bkNoYW5uZWxzRWZmOwogIGludCB0bnNDaGFubmVscyA9IDA7CiAgRkJfVFlQRSBmaWx0ZXJCYW5rOwoKCiAgc3dpdGNoKEZES2FhY0VuY19HZXRNb25vU3RlcmVvTW9kZShjbS0+ZW5jTW9kZSkpIHsKICAgIC8qIC4uLiBhbmQgbWFwIHRvIHRuc0NoYW5uZWxzICovCiAgICBjYXNlIEVMX01PREVfTU9OTzogICB0bnNDaGFubmVscyA9IDE7IGJyZWFrOwogICAgY2FzZSBFTF9NT0RFX1NURVJFTzogdG5zQ2hhbm5lbHMgPSAyOyBicmVhazsKICAgIGRlZmF1bHQ6ICAgICAgICAgICAgIHRuc0NoYW5uZWxzID0gMDsKICB9CgogIHN3aXRjaCAoYXVkaW9PYmplY3RUeXBlKQogIHsKICAgIGRlZmF1bHQ6IGZpbHRlckJhbmsgPSBGQl9MQzsgIGJyZWFrOwogICAgY2FzZSBBT1RfRVJfQUFDX0xEOiAgZmlsdGVyQmFuayA9IEZCX0xEOyAgYnJlYWs7CiAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOiBmaWx0ZXJCYW5rID0gRkJfRUxEOyBicmVhazsKICB9CgogIGhQc3ktPmdyYW51bGVMZW5ndGggPSBncmFudWxlTGVuZ3RoOwoKICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19Jbml0UHN5Q29uZmlndXJhdGlvbihiaXRSYXRlL2NoYW5uZWxzRWZmLCBzYW1wbGVSYXRlLCBiYW5kd2lkdGgsIExPTkdfV0lORE9XLCBoUHN5LT5ncmFudWxlTGVuZ3RoLCB1c2VJUywgJihoUHN5LT5wc3lDb25mWzBdKSwgZmlsdGVyQmFuayk7CiAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spCiAgICByZXR1cm4gRXJyb3JTdGF0dXM7CgogIEVycm9yU3RhdHVzID0gRkRLYWFjRW5jX0luaXRUbnNDb25maWd1cmF0aW9uKAogICAgICAgIChiaXRSYXRlKnRuc0NoYW5uZWxzKS9jaGFubmVsc0VmZiwKICAgICAgICBzYW1wbGVSYXRlLAogICAgICAgIHRuc0NoYW5uZWxzLAogICAgICAgIExPTkdfV0lORE9XLAogICAgICAgIGhQc3ktPmdyYW51bGVMZW5ndGgsCiAgICAgICAgKHN5bnRheEZsYWdzJkFDX1NCUl9QUkVTRU5UKT8xOjAsCiAgICAgICAmKGhQc3ktPnBzeUNvbmZbMF0udG5zQ29uZiksCiAgICAgICAmaFBzeS0+cHN5Q29uZlswXSwKICAgICAgICAoSU5UKSh0bnNNYXNrJjIpLAogICAgICAgIChJTlQpKHRuc01hc2smOCkgKTsKCiAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19FTkNfT0spCiAgICByZXR1cm4gRXJyb3JTdGF0dXM7CgogIGlmIChncmFudWxlTGVuZ3RoID4gNTEyKSB7CiAgICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19Jbml0UHN5Q29uZmlndXJhdGlvbihiaXRSYXRlL2NoYW5uZWxzRWZmLCBzYW1wbGVSYXRlLCBiYW5kd2lkdGgsIFNIT1JUX1dJTkRPVywgaFBzeS0+Z3JhbnVsZUxlbmd0aCwgdXNlSVMsICZoUHN5LT5wc3lDb25mWzFdLCBmaWx0ZXJCYW5rKTsKICAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgICByZXR1cm4gRXJyb3JTdGF0dXM7CgogICAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfSW5pdFRuc0NvbmZpZ3VyYXRpb24oCiAgICAgICAgICAgIChiaXRSYXRlKnRuc0NoYW5uZWxzKS9jaGFubmVsc0VmZiwKICAgICAgICAgICAgc2FtcGxlUmF0ZSwKICAgICAgICAgICAgdG5zQ2hhbm5lbHMsCiAgICAgICAgICAgIFNIT1JUX1dJTkRPVywKICAgICAgICAgICAgaFBzeS0+Z3JhbnVsZUxlbmd0aCwKICAgICAgICAgICAgKHN5bnRheEZsYWdzJkFDX1NCUl9QUkVTRU5UKT8xOjAsCiAgICAgICAgICAgJmhQc3ktPnBzeUNvbmZbMV0udG5zQ29uZiwKICAgICAgICAgICAmaFBzeS0+cHN5Q29uZlsxXSwKICAgICAgICAgICAgKElOVCkodG5zTWFzayYxKSwKICAgICAgICAgICAgKElOVCkodG5zTWFzayY0KSApOwoKICAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfRU5DX09LKQogICAgcmV0dXJuIEVycm9yU3RhdHVzOwoKICB9CgoKICBmb3IgKGk9MDsgaTxjbS0+bkVsZW1lbnRzOyBpKyspIHsKICAgIGZvciAoY2g9MDsgY2g8Y20tPmVsSW5mb1tpXS5uQ2hhbm5lbHNJbkVsOyBjaCsrKSB7CiAgICAgIGlmIChpbml0RmxhZ3MpIHsKICAgICAgICAvKiByZXNldCBzdGF0ZXMgKi8KICAgICAgICBGREthYWNFbmNfcHN5SW5pdFN0YXRlcyhoUHN5LCBoUHN5LT5wc3lFbGVtZW50W2ldLT5wc3lTdGF0aWNbY2hdLCBhdWRpb09iamVjdFR5cGUpOwogICAgICB9CgogICAgICBGREthYWNFbmNfSW5pdFByZUVjaG9Db250cm9sKGhQc3ktPnBzeUVsZW1lbnRbaV0tPnBzeVN0YXRpY1tjaF0tPnNmYlRocmVzaG9sZG5tMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoUHN5LT5wc3lFbGVtZW50W2ldLT5wc3lTdGF0aWNbY2hdLT5jYWxjUHJlRWNobywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoUHN5LT5wc3lDb25mWzBdLnNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoUHN5LT5wc3lDb25mWzBdLnNmYlBjbVF1YW50VGhyZXNob2xkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmhQc3ktPnBzeUVsZW1lbnRbaV0tPnBzeVN0YXRpY1tjaF0tPm1kY3RTY2FsZW5tMSk7CiAgICB9CiAgfQoKICBFcnJvclN0YXR1cyA9IEZES2FhY0VuY19Jbml0UG5zQ29uZmlndXJhdGlvbigmaFBzeS0+cHN5Q29uZlswXS5wbnNDb25mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpdFJhdGUvY2hhbm5lbHNFZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VQbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFBzeS0+cHN5Q29uZlswXS5zZmJDbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFBzeS0+cHN5Q29uZlswXS5zZmJPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY20tPmVsSW5mb1swXS5uQ2hhbm5lbHNJbkVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChoUHN5LT5wc3lDb25mWzBdLmZpbHRlcmJhbmsgPT0gRkJfTEMpKTsKICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0VOQ19PSykKICAgIHJldHVybiBFcnJvclN0YXR1czsKCiAgRXJyb3JTdGF0dXMgPSBGREthYWNFbmNfSW5pdFBuc0NvbmZpZ3VyYXRpb24oJmhQc3ktPnBzeUNvbmZbMV0ucG5zQ29uZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaXRSYXRlL2NoYW5uZWxzRWZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZVJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlUG5zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhQc3ktPnBzeUNvbmZbMV0uc2ZiQ250LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhQc3ktPnBzeUNvbmZbMV0uc2ZiT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtLT5lbEluZm9bMV0ubkNoYW5uZWxzSW5FbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaFBzeS0+cHN5Q29uZlsxXS5maWx0ZXJiYW5rID09IEZCX0xDKSk7CiAgcmV0dXJuIEVycm9yU3RhdHVzOwp9CgoKc3RhdGljCnZvaWQgRkRLYWFjRW5jX2RlaW50ZXJsZWF2ZUlucHV0QnVmZmVyKElOVF9QQ00gKnBPdXRwdXRTYW1wbGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlRfUENNICpwSW5wdXRTYW1wbGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTlQgblNhbXBsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCBuQ2hhbm5lbHMpCnsKICAgIElOVCBrOwogICAgLyogZGVpbnRlcmxhdmUgaW5wdXQgc2FtcGxlcyBhbmQgd3JpdGUgdG8gb3V0cHV0IGJ1ZmZlciAqLwogICAgZm9yIChrPTA7IGs8blNhbXBsZXM7IGsrKykgewogICAgICAgIHBPdXRwdXRTYW1wbGVzW2tdID0gcElucHV0U2FtcGxlc1trKm5DaGFubmVsc107CiAgICB9Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCgogICAgZnVuY3Rpb25uYW1lOiBGREthYWNFbmNfcHN5TWFpbgogICAgZGVzY3JpcHRpb246ICBwc3ljaG9hY291c3RpYwogICAgcmV0dXJuczogICAgICBhbiBlcnJvciBjb2RlCgogICAgICAgIFRoaXMgZnVuY3Rpb24gYXNzdW1lcyB0aGF0IGVub3VnaCBpbnB1dCBkYXRhIGlzIGluIHRoZSBtb2R1bG8gYnVmZmVyLgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpBQUNfRU5DT0RFUl9FUlJPUiBGREthYWNFbmNfcHN5TWFpbihJTlQgICAgICAgICAgICAgICAgIGNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU1lfRUxFTUVOVCAgICAgICAgKnBzeUVsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBTWV9EWU5BTUlDICAgICAgICAqcHN5RHluYW1pYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFNZX0NPTkZJR1VSQVRJT04gICpwc3lDb25mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQU1lfT1VUX0VMRU1FTlQgICAgKlJFU1RSSUNUIHBzeU91dEVsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVF9QQ00gICAgICAgICAgICAgKnBJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAgICAgICAgICAgICAqY2hJZHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElOVCAgICAgICAgICAgICAgICAgIHRvdGFsQ2hhbm5lbHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICAgIElOVCBjb21tb25XaW5kb3cgPSAxOwogICAgSU5UIG1heFNmYlBlckdyb3VwWygyKV07CiAgICBJTlQgbWRjdFNwZWN0cnVtX2U7CiAgICBJTlQgY2g7ICAgLyogY291bnRzIHRocm91Z2ggY2hhbm5lbHMgICAgICAgICAgKi8KICAgIElOVCB3OyAgICAvKiBjb3VudHMgdGhyb3VnaCB3aW5kb3dzICAgICAgICAgICAqLwogICAgSU5UIHNmYjsgIC8qIGNvdW50cyB0aHJvdWdoIHNjYWxlZmFjdG9yIGJhbmRzICovCiAgICBJTlQgbGluZTsgLyogY291bnRzIHRocm91Z2ggbGluZXMgICAgICAgICAgICAgKi8KCiAgICBQU1lfQ09ORklHVVJBVElPTiAqUkVTVFJJQ1QgaFBzeUNvbmZMb25nICA9ICZwc3lDb25mWzBdOwogICAgUFNZX0NPTkZJR1VSQVRJT04gKlJFU1RSSUNUIGhQc3lDb25mU2hvcnQgPSAmcHN5Q29uZlsxXTsKICAgIFBTWV9PVVRfQ0hBTk5FTCAgKipSRVNUUklDVCBwc3lPdXRDaGFubmVsID0gcHN5T3V0RWxlbWVudC0+cHN5T3V0Q2hhbm5lbDsKICAgIEZJWFBfU0dMIHNmYlRvbmFsaXR5WygyKV1bTUFYX1NGQl9MT05HXTsKCiAgICBQU1lfU1RBVElDICAgICAgICAqKlJFU1RSSUNUIHBzeVN0YXRpYyA9IHBzeUVsZW1lbnQtPnBzeVN0YXRpYzsKCiAgICBQU1lfREFUQSAgICAgICAgICAgKlJFU1RSSUNUIHBzeURhdGFbKDIpXTsKICAgIFROU19EQVRBICAgICAgICAgICAqUkVTVFJJQ1QgdG5zRGF0YVsoMildOwogICAgUE5TX0RBVEEgICAgICAgICAgICpSRVNUUklDVCBwbnNEYXRhWygyKV07CgogICAgSU5UIHplcm9TcGVjID0gVFJVRTsgLyogbWVhbnMgYWxsIHNwZWN0cmFsIGxpbmVzIGFyZSB6ZXJvICovCgogICAgSU5UIGJsb2NrU3dpdGNoaW5nT2Zmc2V0OwoKICAgIFBTWV9DT05GSUdVUkFUSU9OICpSRVNUUklDVCBoVGhpc1BzeUNvbmZbKDIpXTsKICAgIElOVCB3aW5kb3dMZW5ndGhbKDIpXTsKICAgIElOVCBuV2luZG93c1soMildOwogICAgSU5UIHdPZmZzZXQ7CgogICAgSU5UICAgICAgIG1heFNmYlsoMildOwogICAgSU5UICAgICAgKnBTZmJNYXhTY2FsZVNwZWNbKDIpXTsKICAgIEZJWFBfREJMICpwU2ZiRW5lcmd5WygyKV07CiAgICBGSVhQX0RCTCAqcFNmYlNwcmVhZEVuZXJneVsoMildOwogICAgRklYUF9EQkwgKnBTZmJFbmVyZ3lMZERhdGFbKDIpXTsKICAgIEZJWFBfREJMICpwU2ZiRW5lcmd5TVNbKDIpXTsKICAgIEZJWFBfREJMICpwU2ZiVGhyZXNob2xkWygyKV07CgogICAgSU5UIGlzU2hvcnRXaW5kb3dbKDIpXTsKCgogICAgaWYgKGhQc3lDb25mTG9uZy0+ZmlsdGVyYmFuayA9PSBGQl9MQykgewogICAgICBibG9ja1N3aXRjaGluZ09mZnNldCA9IHBzeUNvbmYtPmdyYW51bGVMZW5ndGggKyAoOSpwc3lDb25mLT5ncmFudWxlTGVuZ3RoLygyKlRSQU5TX0ZBQykpOwogICAgfSBlbHNlIHsKICAgICAgYmxvY2tTd2l0Y2hpbmdPZmZzZXQgPSBwc3lDb25mLT5ncmFudWxlTGVuZ3RoOwogICAgfQoKICAgIGZvcihjaCA9IDA7IGNoIDwgY2hhbm5lbHM7IGNoKyspCiAgICB7CiAgICAgICAgcHN5RGF0YVtjaF0gPSAmcHN5RHluYW1pYy0+cHN5RGF0YVtjaF07CiAgICAgICAgdG5zRGF0YVtjaF0gPSAmcHN5RHluYW1pYy0+dG5zRGF0YVtjaF07CiAgICAgICAgcG5zRGF0YVtjaF0gPSAmcHN5RHluYW1pYy0+cG5zRGF0YVtjaF07CgogICAgICAgIHBzeURhdGFbY2hdLT5tZGN0U3BlY3RydW0gPSBwc3lPdXRDaGFubmVsW2NoXS0+bWRjdFNwZWN0cnVtOwogICAgfQoKICAgIC8qIGJsb2NrIHN3aXRjaGluZyAqLwogICAgaWYgKGhQc3lDb25mTG9uZy0+ZmlsdGVyYmFuayAhPSBGQl9FTEQpCiAgICB7CiAgICAgIGludCBlcnI7CgogICAgICBmb3IoY2ggPSAwOyBjaCA8IGNoYW5uZWxzOyBjaCsrKQogICAgICB7CiAgICAgICAgICBDX0FMTE9DX1NDUkFUQ0hfU1RBUlQocFRpbWVTaWduYWwsIElOVF9QQ00sICgxMDI0KSkKCiAgICAgICAgICAvKiBkZWludGVybGVhdmUgaW5wdXQgZGF0YSBhbmQgdXNlIGZvciBibG9jayBzd2l0Y2hpbmcgKi8KICAgICAgICAgIEZES2FhY0VuY19kZWludGVybGVhdmVJbnB1dEJ1ZmZlciggcFRpbWVTaWduYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBJbnB1dFtjaElkeFtjaF1dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lDb25mLT5ncmFudWxlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbENoYW5uZWxzKTsKCgogICAgICAgICAgRkRLYWFjRW5jX0Jsb2NrU3dpdGNoaW5nICgmcHN5U3RhdGljW2NoXS0+YmxvY2tTd2l0Y2hpbmdDb250cm9sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5Q29uZi0+Z3JhbnVsZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeVN0YXRpY1tjaF0tPmlzTEZFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFRpbWVTaWduYWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwoKCiAgICAgICAgICAgIC8qIGZpbGwgdXAgaW50ZXJuYWwgaW5wdXQgYnVmZmVyLCB0byAyeGZyYW1lbGVuZ3RoIHNhbXBsZXMgKi8KICAgICAgICAgICAgRkRLbWVtY3B5KHBzeVN0YXRpY1tjaF0tPnBzeUlucHV0QnVmZmVyK2Jsb2NrU3dpdGNoaW5nT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgcFRpbWVTaWduYWwsCiAgICAgICAgICAgICAgICAgICAgICAoMipwc3lDb25mLT5ncmFudWxlTGVuZ3RoLWJsb2NrU3dpdGNoaW5nT2Zmc2V0KSpzaXplb2YoSU5UX1BDTSkpOwoKICAgICAgICAgICAgQ19BTExPQ19TQ1JBVENIX0VORChwVGltZVNpZ25hbCwgSU5UX1BDTSwgKDEwMjQpKQogICAgICB9CgogICAgICAvKiBzeW5jaCBsZWZ0IGFuZCByaWdodCBibG9jayB0eXBlICovCiAgICAgIGVyciA9IEZES2FhY0VuY19TeW5jQmxvY2tTd2l0Y2hpbmcoJnBzeVN0YXRpY1swXS0+YmxvY2tTd2l0Y2hpbmdDb250cm9sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwc3lTdGF0aWNbMV0tPmJsb2NrU3dpdGNoaW5nQ29udHJvbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1vbldpbmRvdyk7CgogICAgICBpZiAoZXJyKSB7CiAgICAgICAgICByZXR1cm4gQUFDX0VOQ19VTlNVUFBPUlRFRF9BT1Q7IC8qIG1peGVkIHVwIExDIGFuZCBMRCAqLwogICAgICB9CgogICAgfQogICAgZWxzZSB7CiAgICAgIGZvcihjaCA9IDA7IGNoIDwgY2hhbm5lbHM7IGNoKyspCiAgICAgIHsKICAgICAgICAvKiBkZWludGVybGVhdmUgaW5wdXQgZGF0YSBhbmQgdXNlIGZvciBibG9jayBzd2l0Y2hpbmcgKi8KICAgICAgICBGREthYWNFbmNfZGVpbnRlcmxlYXZlSW5wdXRCdWZmZXIoIHBzeVN0YXRpY1tjaF0tPnBzeUlucHV0QnVmZmVyICsgYmxvY2tTd2l0Y2hpbmdPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwSW5wdXRbY2hJZHhbY2hdXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeUNvbmYtPmdyYW51bGVMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbENoYW5uZWxzKTsKICAgICAgfQogICAgfQoKICAgIGZvcihjaCA9IDA7IGNoIDwgY2hhbm5lbHM7IGNoKyspCiAgICAgIGlzU2hvcnRXaW5kb3dbY2hdPShwc3lTdGF0aWNbY2hdLT5ibG9ja1N3aXRjaGluZ0NvbnRyb2wubGFzdFdpbmRvd1NlcXVlbmNlID09IFNIT1JUX1dJTkRPVyk7CgogICAgLyogc2V0IHBhcmFtZXRlcnMgYWNjb3JkaW5nIHRvIHdpbmRvdyBsZW5ndGggKi8KICAgIGZvcihjaCA9IDA7IGNoIDwgY2hhbm5lbHM7IGNoKyspCiAgICB7CiAgICAgICAgaWYoaXNTaG9ydFdpbmRvd1tjaF0pIHsKICAgICAgICAgICAgaFRoaXNQc3lDb25mW2NoXSAgICAgICA9IGhQc3lDb25mU2hvcnQ7CiAgICAgICAgICAgIHdpbmRvd0xlbmd0aFtjaF0gICAgICAgPSBwc3lDb25mLT5ncmFudWxlTGVuZ3RoL1RSQU5TX0ZBQzsKICAgICAgICAgICAgbldpbmRvd3NbY2hdICAgICAgICAgICA9IFRSQU5TX0ZBQzsKICAgICAgICAgICAgbWF4U2ZiW2NoXSAgICAgICAgICAgICA9IE1BWF9TRkJfU0hPUlQ7CgogICAgICAgICAgICBwU2ZiTWF4U2NhbGVTcGVjW2NoXSAgID0gcHN5RGF0YVtjaF0tPnNmYk1heFNjYWxlU3BlYy5TaG9ydFswXTsKICAgICAgICAgICAgcFNmYkVuZXJneVtjaF0gICAgICAgICA9IHBzeURhdGFbY2hdLT5zZmJFbmVyZ3kuU2hvcnRbMF07CiAgICAgICAgICAgIHBTZmJTcHJlYWRFbmVyZ3lbY2hdICAgPSBwc3lEYXRhW2NoXS0+c2ZiU3ByZWFkRW5lcmd5LlNob3J0WzBdOwogICAgICAgICAgICBwU2ZiRW5lcmd5TGREYXRhW2NoXSAgID0gcHN5RGF0YVtjaF0tPnNmYkVuZXJneUxkRGF0YS5TaG9ydFswXTsKICAgICAgICAgICAgcFNmYkVuZXJneU1TW2NoXSAgICAgICA9IHBzeURhdGFbY2hdLT5zZmJFbmVyZ3lNUy5TaG9ydFswXTsKICAgICAgICAgICAgcFNmYlRocmVzaG9sZFtjaF0gICAgICA9IHBzeURhdGFbY2hdLT5zZmJUaHJlc2hvbGQuU2hvcnRbMF07CgogICAgICAgIH0gZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaFRoaXNQc3lDb25mW2NoXSAgICAgICA9IGhQc3lDb25mTG9uZzsKICAgICAgICAgICAgd2luZG93TGVuZ3RoW2NoXSAgICAgICA9IHBzeUNvbmYtPmdyYW51bGVMZW5ndGg7CiAgICAgICAgICAgIG5XaW5kb3dzW2NoXSAgICAgICAgICAgPSAxOwogICAgICAgICAgICBtYXhTZmJbY2hdICAgICAgICAgICAgID0gTUFYX0dST1VQRURfU0ZCOwoKICAgICAgICAgICAgcFNmYk1heFNjYWxlU3BlY1tjaF0gICA9IHBzeURhdGFbY2hdLT5zZmJNYXhTY2FsZVNwZWMuTG9uZzsKICAgICAgICAgICAgcFNmYkVuZXJneVtjaF0gICAgICAgICA9IHBzeURhdGFbY2hdLT5zZmJFbmVyZ3kuTG9uZzsKICAgICAgICAgICAgcFNmYlNwcmVhZEVuZXJneVtjaF0gICA9IHBzeURhdGFbY2hdLT5zZmJTcHJlYWRFbmVyZ3kuTG9uZzsKICAgICAgICAgICAgcFNmYkVuZXJneUxkRGF0YVtjaF0gICA9IHBzeURhdGFbY2hdLT5zZmJFbmVyZ3lMZERhdGEuTG9uZzsKICAgICAgICAgICAgcFNmYkVuZXJneU1TW2NoXSAgICAgICA9IHBzeURhdGFbY2hdLT5zZmJFbmVyZ3lNUy5Mb25nOwogICAgICAgICAgICBwU2ZiVGhyZXNob2xkW2NoXSAgICAgID0gcHN5RGF0YVtjaF0tPnNmYlRocmVzaG9sZC5Mb25nOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBUcmFuc2Zvcm0gYW5kIGdldCBtZGN0U2NhbGluZyBmb3IgYWxsIGNoYW5uZWxzIGFuZCB3aW5kb3dzLiAqLwogICAgZm9yKGNoID0gMDsgY2ggPCBjaGFubmVsczsgY2grKykKICAgIHsKICAgICAgICAvKiB1cGRhdGUgbnVtYmVyIG9mIGFjdGl2ZSBiYW5kcyAqLwogICAgICAgIGlmIChwc3lTdGF0aWNbY2hdLT5pc0xGRSkgewogICAgICAgICAgICBwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlID0gaFRoaXNQc3lDb25mW2NoXS0+c2ZiQWN0aXZlTEZFOwogICAgICAgICAgICBwc3lEYXRhW2NoXS0+bG93cGFzc0xpbmUgPSBoVGhpc1BzeUNvbmZbY2hdLT5sb3dwYXNzTGluZUxGRTsKICAgICAgICB9IGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHBzeURhdGFbY2hdLT5zZmJBY3RpdmUgPSBoVGhpc1BzeUNvbmZbY2hdLT5zZmJBY3RpdmU7CiAgICAgICAgICAgIHBzeURhdGFbY2hdLT5sb3dwYXNzTGluZSA9IGhUaGlzUHN5Q29uZltjaF0tPmxvd3Bhc3NMaW5lOwogICAgICAgIH0KCiAgICAgICAgZm9yKHcgPSAwOyB3IDwgbldpbmRvd3NbY2hdOyB3KyspIHsKCiAgICAgICAgICB3T2Zmc2V0ID0gdyp3aW5kb3dMZW5ndGhbY2hdOwoKICAgICAgICAgIEZES2FhY0VuY19UcmFuc2Zvcm1fUmVhbCggcHN5U3RhdGljW2NoXS0+cHN5SW5wdXRCdWZmZXIgKyB3T2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhW2NoXS0+bWRjdFNwZWN0cnVtK3dPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeVN0YXRpY1tjaF0tPmJsb2NrU3dpdGNoaW5nQ29udHJvbC5sYXN0V2luZG93U2VxdWVuY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeVN0YXRpY1tjaF0tPmJsb2NrU3dpdGNoaW5nQ29udHJvbC53aW5kb3dTaGFwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcHN5U3RhdGljW2NoXS0+YmxvY2tTd2l0Y2hpbmdDb250cm9sLmxhc3RXaW5kb3dTaGFwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5Q29uZi0+Z3JhbnVsZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbWRjdFNwZWN0cnVtX2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhUaGlzUHN5Q29uZltjaF0tPmZpbHRlcmJhbmsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAscHN5U3RhdGljW2NoXS0+b3ZlcmxhcEFkZEJ1ZmZlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgLyogTG93IHBhc3MgLyBoaWdoZXN0IHNmYiAqLwogICAgICAgICAgRkRLbWVtY2xlYXIoJnBzeURhdGFbY2hdLT5tZGN0U3BlY3RydW1bcHN5RGF0YVtjaF0tPmxvd3Bhc3NMaW5lK3dPZmZzZXRdLAogICAgICAgICAgICAgICAgICAgICAgKHdpbmRvd0xlbmd0aFtjaF0tcHN5RGF0YVtjaF0tPmxvd3Bhc3NMaW5lKSpzaXplb2YoRklYUF9EQkwpKTsKCiAgICAgICAgICBpZiAoaFBzeUNvbmZMb25nLT5maWx0ZXJiYW5rICE9IEZCX0xDKSB7CiAgICAgICAgICAgIC8qIERvIGJsZW5kaW5nIHRvIHJlZHVjZSBnaWJicyBhcnRpZmFjdHMgKi8KICAgICAgICAgICAgZm9yIChpbnQgaT0wOyBpPEZBREVfT1VUX0xFTjsgaSsrKSB7CiAgICAgICAgICAgICAgcHN5RGF0YVtjaF0tPm1kY3RTcGVjdHJ1bVtwc3lEYXRhW2NoXS0+bG93cGFzc0xpbmUrd09mZnNldCAtIEZBREVfT1VUX0xFTiArIGldID0gZk11bHQocHN5RGF0YVtjaF0tPm1kY3RTcGVjdHJ1bVtwc3lEYXRhW2NoXS0+bG93cGFzc0xpbmUrd09mZnNldCAtIEZBREVfT1VUX0xFTiArIGldLCBmYWRlT3V0RmFjdG9yW2ldKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKCiAgICAgICAgICAvKiBDaGVjayBmb3IgemVybyBzcGVjdHJ1bS4gVGhlc2UgbG9vcHMgd2lsbCB1c3VhbGx5IHRlcm1pbmF0ZSB2ZXJ5LCB2ZXJ5IGVhcmx5LiAqLwogICAgICAgICAgZm9yKGxpbmU9MDsgKGxpbmU8cHN5RGF0YVtjaF0tPmxvd3Bhc3NMaW5lKSAmJiAoemVyb1NwZWM9PVRSVUUpOyBsaW5lKyspIHsKICAgICAgICAgICAgICBpZiAocHN5RGF0YVtjaF0tPm1kY3RTcGVjdHJ1bVtsaW5lK3dPZmZzZXRdICE9IChGSVhQX0RCTCkwKSB7CiAgICAgICAgICAgICAgICAgIHplcm9TcGVjID0gRkFMU0U7CiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgfSAvKiB3IGxvb3AgKi8KCiAgICAgICAgcHN5RGF0YVtjaF0tPm1kY3RTY2FsZSA9IG1kY3RTcGVjdHJ1bV9lOwoKICAgICAgICAvKiByb3RhdGUgaW50ZXJuYWwgdGltZSBzYW1wbGVzICovCiAgICAgICAgRkRLbWVtbW92ZShwc3lTdGF0aWNbY2hdLT5wc3lJbnB1dEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgIHBzeVN0YXRpY1tjaF0tPnBzeUlucHV0QnVmZmVyK3BzeUNvbmYtPmdyYW51bGVMZW5ndGgsCiAgICAgICAgICAgICAgICAgICBwc3lDb25mLT5ncmFudWxlTGVuZ3RoKnNpemVvZihJTlRfUENNKSk7CgoKICAgICAgICAvKiAuLi4gYW5kIGdldCByZW1haW5pbmcgc2FtcGxlcyBmcm9tIGlucHV0IGJ1ZmZlciAqLwogICAgICAgIEZES2FhY0VuY19kZWludGVybGVhdmVJbnB1dEJ1ZmZlciggcHN5U3RhdGljW2NoXS0+cHN5SW5wdXRCdWZmZXIrcHN5Q29uZi0+Z3JhbnVsZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBJbnB1dFsgKDIqcHN5Q29uZi0+Z3JhbnVsZUxlbmd0aC1ibG9ja1N3aXRjaGluZ09mZnNldCkqdG90YWxDaGFubmVscyArIGNoSWR4W2NoXSBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tTd2l0Y2hpbmdPZmZzZXQtcHN5Q29uZi0+Z3JhbnVsZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsQ2hhbm5lbHMpOwoKICAgIH0gLyogY2ggKi8KCiAgICAvKiBEbyBzb21lIHJlc2NhbGluZyB0byBnZXQgbWF4aW11bSBwb3NzaWJsZSBhY2N1cmFjeSBmb3IgZW5lcmdpZXMgKi8KICAgIGlmICggemVyb1NwZWMgPT0gRkFMU0UpIHsKCiAgICAgICAgLyogQ2FsYyBwb3NzaWJsZSBzcGVjdHJ1bSBsZWZ0c2hpZnQgZm9yIGVhY2ggc2ZiICgxIG1lYW5zOiAxIGJpdCBsZWZ0IHNoaWZ0IGlzIHBvc3NpYmxlIHdpdGhvdXQgb3ZlcmZsb3cpICovCiAgICAgICAgSU5UIG1pblNwZWNTaGlmdCA9IE1BWF9TSElGVF9EQkw7CiAgICAgICAgSU5UIG5yZ1NoaWZ0ICAgICA9IE1BWF9TSElGVF9EQkw7CiAgICAgICAgSU5UIGZpbmFsU2hpZnQgICA9IE1BWF9TSElGVF9EQkw7CiAgICAgICAgRklYUF9EQkwgY3Vyck5yZyA9IDA7CiAgICAgICAgRklYUF9EQkwgbWF4TnJnICA9IDA7CgogICAgICAgIGZvcihjaCA9IDA7IGNoIDwgY2hhbm5lbHM7IGNoKyspIHsKICAgICAgICAgICAgZm9yKHcgPSAwOyB3IDwgbldpbmRvd3NbY2hdOyB3KyspIHsKICAgICAgICAgICAgICAgIHdPZmZzZXQgPSB3KndpbmRvd0xlbmd0aFtjaF07CiAgICAgICAgICAgICAgICBGREthYWNFbmNfQ2FsY1NmYk1heFNjYWxlU3BlYyhwc3lEYXRhW2NoXS0+bWRjdFNwZWN0cnVtK3dPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoVGhpc1BzeUNvbmZbY2hdLT5zZmJPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2ZiTWF4U2NhbGVTcGVjW2NoXSt3Km1heFNmYltjaF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlKTsKCiAgICAgICAgICAgICAgICBmb3IgKHNmYiA9IDA7IHNmYjxwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlOyBzZmIrKykKICAgICAgICAgICAgICAgICAgICBtaW5TcGVjU2hpZnQgPSBmaXhNaW4obWluU3BlY1NoaWZ0LCAocFNmYk1heFNjYWxlU3BlY1tjaF0rdyptYXhTZmJbY2hdKVtzZmJdKTsKICAgICAgICAgICAgfQoKICAgICAgICB9CgogICAgICAgIC8qIENhbGMgcG9zc2libGUgZW5lcmd5IGxlZnRzaGlmdCBmb3IgZWFjaCBzZmIgKDEgbWVhbnM6IDEgYml0IGxlZnQgc2hpZnQgaXMgcG9zc2libGUgd2l0aG91dCBvdmVyZmxvdykgKi8KICAgICAgICBmb3IoY2ggPSAwOyBjaCA8IGNoYW5uZWxzOyBjaCsrKSB7CiAgICAgICAgICAgIGZvcih3ID0gMDsgdyA8IG5XaW5kb3dzW2NoXTsgdysrKSB7CiAgICAgICAgICAgICAgICB3T2Zmc2V0ID0gdyp3aW5kb3dMZW5ndGhbY2hdOwogICAgICAgICAgICAgICAgY3Vyck5yZyA9IEZES2FhY0VuY19DaGVja0JhbmRFbmVyZ3lPcHRpbShwc3lEYXRhW2NoXS0+bWRjdFNwZWN0cnVtK3dPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNmYk1heFNjYWxlU3BlY1tjaF0rdyptYXhTZmJbY2hdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhUaGlzUHN5Q29uZltjaF0tPnNmYk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTZmJFbmVyZ3lbY2hdK3cqbWF4U2ZiW2NoXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2ZiRW5lcmd5TGREYXRhW2NoXSt3Km1heFNmYltjaF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluU3BlY1NoaWZ0LTQpOwoKICAgICAgICAgICAgICAgIG1heE5yZyA9IGZpeE1heChtYXhOcmcsIGN1cnJOcmcpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIG1heE5yZyAhPSAoRklYUF9EQkwpMCApIHsKICAgICAgICAgICAgbnJnU2hpZnQgPSAoQ291bnRMZWFkaW5nQml0cyhtYXhOcmcpPj4xKSArIChtaW5TcGVjU2hpZnQtNCk7CiAgICAgICAgfQoKICAgICAgICAvKiAyY2hlY2s6IEhhc24ndCB0aGlzIGRlY2lzaW9uIHRvIGJlIG1hZGUgZm9yIGJvdGggY2hhbm5lbHM/ICovCiAgICAgICAgLyogRm9yIHNob3J0IHdpbmRvd3MgMSBhZGRpdGlvbmFsIGJpdCBoZWFkcm9vbSBpcyBuZWNlc3NhcnkgdG8gcHJldmVudCBvdmVyZmxvd3Mgd2hlbiBzdW1taW5nIHVwIGVuZXJnaWVzIGluIEZES2FhY0VuY19ncm91cFNob3J0RGF0YSgpICovCiAgICAgICAgaWYoaXNTaG9ydFdpbmRvd1swXSkgbnJnU2hpZnQtLTsKCiAgICAgICAgLyogYm90aCBzcGVjdHJ1bSBhbmQgZW5lcmdpZXMgbXVzdG4ndCBvdmVyZmxvdyAqLwogICAgICAgIGZpbmFsU2hpZnQgPSBmaXhNaW4obWluU3BlY1NoaWZ0LCBucmdTaGlmdCk7CgogICAgICAgIC8qIGRvIG5vdCBzaGlmdCBtb3JlIHRoYW4gMyBiaXRzIG1vcmUgdG8gdGhlIGxlZnQgdGhhbiBzaWduYWwgd2l0aG91dCBibG9ja2Zsb2F0aW5nIHBvaW50CiAgICAgICAgICogd291bGQgYmUgdG8gYXZvaWQgb3ZlcmZsb3cgb2Ygc2NhbGVkIFBDTSBxdWFudGl6YXRpb24gdGhyZXNob2xkcyAqLwogICAgICAgIGlmIChmaW5hbFNoaWZ0ID4gcHN5RGF0YVswXS0+bWRjdFNjYWxlICsgMyApCiAgICAgICAgICAgIGZpbmFsU2hpZnQgPSBwc3lEYXRhWzBdLT5tZGN0U2NhbGUgKyAzOwoKICAgICAgICBGREtfQVNTRVJUKGZpbmFsU2hpZnQgPj0gMCk7ICAgIC8qIHJpZ2h0IHNoaWZ0IGlzIG5vdCBhbGxvd2VkICovCgogICAgICAgIC8qIGNvcnJlY3Qgc2ZiRW5lcmd5IGFuZCBzZmJFbmVyZ3lMZERhdGEgd2l0aCBuZXcgZmluYWxTaGlmdCAqLwogICAgICAgIEZJWFBfREJMIGxkU2hpZnQgPSBmaW5hbFNoaWZ0ICogRkwyRlhDT05TVF9EQkwoMi4wLzY0KTsKICAgICAgICBmb3IoY2ggPSAwOyBjaCA8IGNoYW5uZWxzOyBjaCsrKSB7CiAgICAgICAgICAgIGZvcih3ID0gMDsgdyA8IG5XaW5kb3dzW2NoXTsgdysrKSB7CiAgICAgICAgICAgICAgICBmb3Ioc2ZiPTA7IHNmYjxwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlOyBzZmIrKykgewogICAgICAgICAgICAgICAgICAgIElOVCBzY2FsZSA9IGZpeE1heCgwLCAocFNmYk1heFNjYWxlU3BlY1tjaF0rdyptYXhTZmJbY2hdKVtzZmJdLTQpOwogICAgICAgICAgICAgICAgICAgIHNjYWxlICAgICA9IGZpeE1pbigoc2NhbGUtZmluYWxTaGlmdCk8PDEsIERGUkFDVF9CSVRTLTEpOwogICAgICAgICAgICAgICAgICAgIGlmIChzY2FsZSA+PSAwKSAocFNmYkVuZXJneVtjaF0rdyptYXhTZmJbY2hdKVtzZmJdID4+PSAoc2NhbGUpOwogICAgICAgICAgICAgICAgICAgIGVsc2UgICAgICAgICAgICAocFNmYkVuZXJneVtjaF0rdyptYXhTZmJbY2hdKVtzZmJdIDw8PSAoLXNjYWxlKTsKICAgICAgICAgICAgICAgICAgICAocFNmYlRocmVzaG9sZFtjaF0rdyptYXhTZmJbY2hdKVtzZmJdID0gZk11bHQoKHBTZmJFbmVyZ3lbY2hdK3cqbWF4U2ZiW2NoXSlbc2ZiXSwgQ19SQVRJTyk7CiAgICAgICAgICAgICAgICAgICAgKHBTZmJFbmVyZ3lMZERhdGFbY2hdK3cqbWF4U2ZiW2NoXSlbc2ZiXSArPSBsZFNoaWZ0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIGZpbmFsU2hpZnQgIT0gMCApIHsKICAgICAgICAgICAgZm9yIChjaCA9IDA7IGNoIDwgY2hhbm5lbHM7IGNoKyspIHsKICAgICAgICAgICAgICAgIGZvcih3ID0gMDsgdyA8IG5XaW5kb3dzW2NoXTsgdysrKSB7CiAgICAgICAgICAgICAgICAgICAgd09mZnNldCA9IHcqd2luZG93TGVuZ3RoW2NoXTsKICAgICAgICAgICAgICAgICAgICBmb3IobGluZT0wOyBsaW5lPHBzeURhdGFbY2hdLT5sb3dwYXNzTGluZTsgbGluZSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbY2hdLT5tZGN0U3BlY3RydW1bbGluZSt3T2Zmc2V0XSA8PD0gZmluYWxTaGlmdDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLyogdXBkYXRlIHNmYk1heFNjYWxlU3BlYyAqLwogICAgICAgICAgICAgICAgICAgIGZvciAoc2ZiID0gMDsgc2ZiPHBzeURhdGFbY2hdLT5zZmJBY3RpdmU7IHNmYisrKQogICAgICAgICAgICAgICAgICAgICAgICAocFNmYk1heFNjYWxlU3BlY1tjaF0rdyptYXhTZmJbY2hdKVtzZmJdIC09IGZpbmFsU2hpZnQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiB1cGRhdGUgbWRjdFNjYWxlICovCiAgICAgICAgICAgICAgICBwc3lEYXRhW2NoXS0+bWRjdFNjYWxlIC09IGZpbmFsU2hpZnQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfSBlbHNlIHsKICAgICAgICAvKiBhbGwgc3BlY3RyYWwgbGluZXMgYXJlIHplcm8gKi8KICAgICAgICBmb3IgKGNoID0gMDsgY2ggPCBjaGFubmVsczsgY2grKykgewogICAgICAgICAgICBwc3lEYXRhW2NoXS0+bWRjdFNjYWxlID0gMDsgICAgIC8qIG90aGVyd2lzZSBtZGN0U2NhbGUgd291bGQgYmUgZm9yIGV4YW1wbGUgNyBhbmQgUENNIHF1YW50aXphdGlvbiB0aHJlc2hvbGRzIHdvdWxkIGJlIHNoaWZ0ZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAxNCBiaXRzIHRvIHRoZSByaWdodCBjYXVzaW5nIHNvbWUgb2YgdGhlbSB0byBiZWNvbWUgMCAod2hpY2ggY2F1c2VzIHByb2JsZW1zIGxhdGVyKSAqLwogICAgICAgICAgICAvKiBjbGVhciBzZmJNYXhTY2FsZVNwZWMgKi8KICAgICAgICAgICAgZm9yKHcgPSAwOyB3IDwgbldpbmRvd3NbY2hdOyB3KyspIHsKICAgICAgICAgICAgICAgIGZvciAoc2ZiID0gMDsgc2ZiPHBzeURhdGFbY2hdLT5zZmJBY3RpdmU7IHNmYisrKSB7CiAgICAgICAgICAgICAgICAgICAgKHBTZmJNYXhTY2FsZVNwZWNbY2hdK3cqbWF4U2ZiW2NoXSlbc2ZiXSA9IDA7CiAgICAgICAgICAgICAgICAgICAgKHBTZmJFbmVyZ3lbY2hdK3cqbWF4U2ZiW2NoXSlbc2ZiXSAgICAgICA9IChGSVhQX0RCTCkwOwogICAgICAgICAgICAgICAgICAgIChwU2ZiRW5lcmd5TGREYXRhW2NoXSt3Km1heFNmYltjaF0pW3NmYl0gPSBGTDJGWENPTlNUX0RCTCgtMS4wZik7CiAgICAgICAgICAgICAgICAgICAgKHBTZmJUaHJlc2hvbGRbY2hdK3cqbWF4U2ZiW2NoXSlbc2ZiXSAgICA9IChGSVhQX0RCTCkwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qIEFkdmFuY2UgcHN5Y2hvYWNvdXN0aWNzOiBUb25hbGl0eSBhbmQgVE5TICovCiAgICBpZiAocHN5U3RhdGljWzBdLT5pc0xGRSkgewogICAgICAgIHRuc0RhdGFbMF0tPmRhdGFSYXcuTG9uZy5zdWJCbG9ja0luZm8udG5zQWN0aXZlID0gMDsKICAgIH0KICAgIGVsc2UKICAgIHsKCiAgICAgICAgZm9yKGNoID0gMDsgY2ggPCBjaGFubmVsczsgY2grKykgewogICAgICAgICAgICBpZiAoIWlzU2hvcnRXaW5kb3dbY2hdKSB7CiAgICAgICAgICAgICAgICAvKiB0b25hbGl0eSAqLwogICAgICAgICAgICAgICAgRkRLYWFjRW5jX0NhbGN1bGF0ZUZ1bGxUb25hbGl0eSggcHN5RGF0YVtjaF0tPm1kY3RTcGVjdHJ1bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNmYk1heFNjYWxlU3BlY1tjaF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTZmJFbmVyZ3lMZERhdGFbY2hdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZmJUb25hbGl0eVtjaF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbY2hdLT5zZmJBY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhUaGlzUHN5Q29uZltjaF0tPnNmYk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRoaXNQc3lDb25mW2NoXS0+cG5zQ29uZi51c2VQbnMpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoaFBzeUNvbmZMb25nLT50bnNDb25mLnRuc0FjdGl2ZSB8fCBoUHN5Q29uZlNob3J0LT50bnNDb25mLnRuc0FjdGl2ZSkgewogICAgICAgICAgICBJTlQgdG5zQWN0aXZlW1RSQU5TX0ZBQ107CiAgICAgICAgICAgIElOVCBucmdTY2FsaW5nWzJdID0gezAsMH07CiAgICAgICAgICAgIElOVCB0bnNTcGVjU2hpZnQgPSAwOwoKICAgICAgICAgICAgZm9yKGNoID0gMDsgY2ggPCBjaGFubmVsczsgY2grKykgewogICAgICAgICAgICAgICAgZm9yKHcgPSAwOyB3IDwgbldpbmRvd3NbY2hdOyB3KyspIHsKCiAgICAgICAgICAgICAgICAgICAgd09mZnNldCA9IHcqd2luZG93TGVuZ3RoW2NoXTsKICAgICAgICAgICAgICAgICAgICAvKiBUTlMgKi8KICAgICAgICAgICAgICAgICAgICBGREthYWNFbmNfVG5zRGV0ZWN0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRuc0RhdGFbY2hdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoVGhpc1BzeUNvbmZbY2hdLT50bnNDb25mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwc3lPdXRDaGFubmVsW2NoXS0+dG5zSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoVGhpc1BzeUNvbmZbY2hdLT5zZmJDbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5RGF0YVtjaF0tPm1kY3RTcGVjdHJ1bSt3T2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5U3RhdGljW2NoXS0+YmxvY2tTd2l0Y2hpbmdDb250cm9sLmxhc3RXaW5kb3dTZXF1ZW5jZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjaGFubmVscyA9PSAyKSB7CiAgICAgICAgICAgICAgRkRLYWFjRW5jX1Ruc1N5bmMoCiAgICAgICAgICAgICAgICAgICAgICB0bnNEYXRhWzFdLAogICAgICAgICAgICAgICAgICAgICAgdG5zRGF0YVswXSwKICAgICAgICAgICAgICAgICAgICAgICZwc3lPdXRDaGFubmVsWzFdLT50bnNJbmZvLAogICAgICAgICAgICAgICAgICAgICAgJnBzeU91dENoYW5uZWxbMF0tPnRuc0luZm8sCgogICAgICAgICAgICAgICAgICAgICAgcHN5U3RhdGljWzFdLT5ibG9ja1N3aXRjaGluZ0NvbnRyb2wubGFzdFdpbmRvd1NlcXVlbmNlLAogICAgICAgICAgICAgICAgICAgICAgcHN5U3RhdGljWzBdLT5ibG9ja1N3aXRjaGluZ0NvbnRyb2wubGFzdFdpbmRvd1NlcXVlbmNlLAogICAgICAgICAgICAgICAgICAgICAgJmhUaGlzUHN5Q29uZlsxXS0+dG5zQ29uZik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEZES19BU1NFUlQoY29tbW9uV2luZG93PTEpOyAvKiBhbGwgY2hlY2tzIGZvciBUTlMgZG8gb25seSB3b3JrIGZvciBjb21tb24gd2luZG93cyAod2hpY2ggaXMgYWx3YXlzIHNldCkqLwogICAgICAgICAgICBmb3IodyA9IDA7IHcgPCBuV2luZG93c1swXTsgdysrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoaXNTaG9ydFdpbmRvd1swXSkKICAgICAgICAgICAgICAgICAgICB0bnNBY3RpdmVbd10gPSB0bnNEYXRhWzBdLT5kYXRhUmF3LlNob3J0LnN1YkJsb2NrSW5mb1t3XS50bnNBY3RpdmUgfHwKICAgICAgICAgICAgICAgICAgICAoKGNoYW5uZWxzID09IDIpID8gdG5zRGF0YVsxXS0+ZGF0YVJhdy5TaG9ydC5zdWJCbG9ja0luZm9bd10udG5zQWN0aXZlIDogMCk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgdG5zQWN0aXZlW3ddID0gdG5zRGF0YVswXS0+ZGF0YVJhdy5Mb25nLnN1YkJsb2NrSW5mby50bnNBY3RpdmUgfHwKICAgICAgICAgICAgICAgICAgICAoKGNoYW5uZWxzID09IDIpID8gdG5zRGF0YVsxXS0+ZGF0YVJhdy5Mb25nLnN1YkJsb2NrSW5mby50bnNBY3RpdmUgOiAwKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yKGNoID0gMDsgY2ggPCBjaGFubmVsczsgY2grKykgewogICAgICAgICAgICAgICAgaWYgKHRuc0FjdGl2ZVswXSAmJiAhaXNTaG9ydFdpbmRvd1tjaF0pIHsKICAgICAgICAgICAgICAgICAgICAvKiBTY2FsZSBkb3duIHNwZWN0cnVtIGlmIHRucyBpcyBhY3RpdmUgaW4gb25lIG9mIHRoZSB0d28gY2hhbm5lbHMgd2l0aCBzYW1lIGxhc3RXaW5kb3dTZXF1ZW5jZSAqLwogICAgICAgICAgICAgICAgICAgIC8qIGZpcnN0IHBhcnQgb2YgdGhyZXNob2xkIGNhbGN1bGF0aW9uOyBpdCdzIG5vdCBuZWNlc3NhcnkgdG8gdXBkYXRlIHNmYk1heFNjYWxlU3BlYyAqLwogICAgICAgICAgICAgICAgICAgIElOVCBzaGlmdCA9IDE7CiAgICAgICAgICAgICAgICAgICAgZm9yKHNmYj0wOyBzZmI8aFRoaXNQc3lDb25mW2NoXS0+bG93cGFzc0xpbmU7IHNmYisrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbY2hdLT5tZGN0U3BlY3RydW1bc2ZiXSA9IHBzeURhdGFbY2hdLT5tZGN0U3BlY3RydW1bc2ZiXSA+PiBzaGlmdDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8qIHVwZGF0ZSB0aHJlc2hvbGRzICovCiAgICAgICAgICAgICAgICAgICAgZm9yIChzZmI9MDsgc2ZiPHBzeURhdGFbY2hdLT5zZmJBY3RpdmU7IHNmYisrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBTZmJUaHJlc2hvbGRbY2hdW3NmYl0gPj49ICgyKnNoaWZ0KTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHBzeURhdGFbY2hdLT5tZGN0U2NhbGUgKz0gc2hpZnQ7IC8qIHVwZGF0ZSBtZGN0U2NhbGUgKi8KCiAgICAgICAgICAgICAgICAgICAgLyogY2FsYyBzZmJFbmVyZ2llcyBhZnRlciB0bnNFbmNvZGUgYWdhaW4gISAqLwoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yKGNoID0gMDsgY2ggPCBjaGFubmVsczsgY2grKykgewogICAgICAgICAgICAgIGZvcih3ID0gMDsgdyA8IG5XaW5kb3dzW2NoXTsgdysrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHdPZmZzZXQgPSB3KndpbmRvd0xlbmd0aFtjaF07CiAgICAgICAgICAgICAgICAgICAgRkRLYWFjRW5jX1Ruc0VuY29kZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcHN5T3V0Q2hhbm5lbFtjaF0tPnRuc0luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG5zRGF0YVtjaF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRoaXNQc3lDb25mW2NoXS0+c2ZiQ250LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoVGhpc1BzeUNvbmZbY2hdLT50bnNDb25mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhUaGlzUHN5Q29uZltjaF0tPnNmYk9mZnNldFtwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlXSwvKmhUaGlzUHN5Q29uZltjaF0tPmxvd3Bhc3NMaW5lKi8gLyogZmlsdGVyIHN0b3BzIGJlZm9yZSB0aGF0IGxpbmUgISAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbY2hdLT5tZGN0U3BlY3RydW0rd09mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeVN0YXRpY1tjaF0tPmJsb2NrU3dpdGNoaW5nQ29udHJvbC5sYXN0V2luZG93U2VxdWVuY2UpOwoKICAgICAgICAgICAgICAgICAgICBpZih0bnNBY3RpdmVbd10pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIENhbGMgc2ZiLWJhbmR3aXNlIG1kY3QtZW5lcmdpZXMgZm9yIGxlZnQgYW5kIHJpZ2h0IGNoYW5uZWwgYWdhaW4sICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBpZiB0bnMgYWN0aXZlIGluIGN1cnJlbnQgY2hhbm5lbCBvciBpbiBvbmUgY2hhbm5lbCB3aXRoIHNhbWUgbGFzdFdpbmRvd1NlcXVlbmNlIGxlZnQgYW5kIHJpZ2h0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGREthYWNFbmNfQ2FsY1NmYk1heFNjYWxlU3BlYyhwc3lEYXRhW2NoXS0+bWRjdFNwZWN0cnVtK3dPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhUaGlzUHN5Q29uZltjaF0tPnNmYk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNmYk1heFNjYWxlU3BlY1tjaF0rdyptYXhTZmJbY2hdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvcihjaCA9IDA7IGNoIDwgY2hhbm5lbHM7IGNoKyspIHsKICAgICAgICAgICAgICBmb3IodyA9IDA7IHcgPCBuV2luZG93c1tjaF07IHcrKykgewoKICAgICAgICAgICAgICAgIGlmICh0bnNBY3RpdmVbd10pIHsKCiAgICAgICAgICAgICAgICAgIGlmIChpc1Nob3J0V2luZG93W2NoXSkgewogICAgICAgICAgICAgICAgICAgIEZES2FhY0VuY19DYWxjQmFuZEVuZXJneU9wdGltU2hvcnQocHN5RGF0YVtjaF0tPm1kY3RTcGVjdHJ1bSt3KndpbmRvd0xlbmd0aFtjaF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTZmJNYXhTY2FsZVNwZWNbY2hdK3cqbWF4U2ZiW2NoXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRoaXNQc3lDb25mW2NoXS0+c2ZiT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2ZiRW5lcmd5W2NoXSt3Km1heFNmYltjaF0pOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIG5yZ1NjYWxpbmdbY2hdID0gICAgICAgIC8qIHdpdGggdG5zLCBlbmVyZ3kgY2FsY3VsYXRpb24gY2FuIG92ZXJmbG93OyAtPiBzY2FsaW5nICovCiAgICAgICAgICAgICAgICAgICAgRkRLYWFjRW5jX0NhbGNCYW5kRW5lcmd5T3B0aW1Mb25nKHBzeURhdGFbY2hdLT5tZGN0U3BlY3RydW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2ZiTWF4U2NhbGVTcGVjW2NoXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhUaGlzUHN5Q29uZltjaF0tPnNmYk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbY2hdLT5zZmJBY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2ZiRW5lcmd5W2NoXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTZmJFbmVyZ3lMZERhdGFbY2hdKTsKICAgICAgICAgICAgICAgICAgICB0bnNTcGVjU2hpZnQgPSBmaXhNYXgodG5zU3BlY1NoaWZ0LCBucmdTY2FsaW5nW2NoXSk7ICAgICAgIC8qIG5yZ1NjYWxpbmcgaXMgc2V0IG9ubHkgaWYgbnJnIHdvdWxkIGhhdmUgYW4gb3ZlcmZsb3cgKi8KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSAvKiBpZiB0bnNBY3RpdmUgKi8KICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gLyogZW5kIGNoYW5uZWwgbG9vcCAqLwoKICAgICAgICAgICAgLyogYWRhcHQgc2NhbGluZyB0byBwcmV2ZW50IG5yZyBvdmVyZmxvdywgb25seSBmb3IgbG9uZyBibG9ja3MgKi8KICAgICAgICAgICAgZm9yKGNoID0gMDsgY2ggPCBjaGFubmVsczsgY2grKykgewogICAgICAgICAgICAgIGlmICggKHRuc1NwZWNTaGlmdCE9MCkgJiYgIWlzU2hvcnRXaW5kb3dbY2hdICkgewogICAgICAgICAgICAgICAgLyogc2NhbGUgZG93biBzcGVjdHJ1bSwgbnJnJ3MgYW5kIHRocmVzaG9sZHMsIGlmIHRoZXJlIHdhcyBhbiBvdmVyZmxvdyBpbiBzZmJOcmcgY2FsY3VsYXRpb24gYWZ0ZXIgdG5zICovCiAgICAgICAgICAgICAgICBmb3IobGluZT0wOyBsaW5lPGhUaGlzUHN5Q29uZltjaF0tPmxvd3Bhc3NMaW5lOyBsaW5lKyspIHsKICAgICAgICAgICAgICAgICAgcHN5RGF0YVtjaF0tPm1kY3RTcGVjdHJ1bVtsaW5lXSA+Pj0gdG5zU3BlY1NoaWZ0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgSU5UIHNjYWxlID0gKHRuc1NwZWNTaGlmdC1ucmdTY2FsaW5nW2NoXSk8PDE7CiAgICAgICAgICAgICAgICBmb3Ioc2ZiPTA7IHNmYjxwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlOyBzZmIrKykgewogICAgICAgICAgICAgICAgICBwU2ZiRW5lcmd5TGREYXRhW2NoXVtzZmJdICAgLT0gc2NhbGUqRkwyRlhDT05TVF9EQkwoMS4wL0xEX0RBVEFfU0NBTElORyk7CiAgICAgICAgICAgICAgICAgIHBTZmJFbmVyZ3lbY2hdW3NmYl0gICAgICAgID4+PSBzY2FsZTsKICAgICAgICAgICAgICAgICAgcFNmYlRocmVzaG9sZFtjaF1bc2ZiXSAgICAgPj49ICh0bnNTcGVjU2hpZnQ8PDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcHN5RGF0YVtjaF0tPm1kY3RTY2FsZSArPSB0bnNTcGVjU2hpZnQ7ICAvKiB1cGRhdGUgbWRjdFNjYWxlOyBub3QgbmVjZXNzYXJ5IHRvIHVwZGF0ZSBzZmJNYXhTY2FsZVNwZWMgKi8KCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IC8qIGVuZCBjaGFubmVsIGxvb3AgKi8KCiAgICAgICAgfSAvKiBUTlMgYWN0aXZlICovCiAgICB9ICAvKiAhaXNMRkUgKi8KCgoKCgoKICAgIC8qIEFkdmFuY2UgdGhyZXNob2xkcyAqLwogICAgZm9yKGNoID0gMDsgY2ggPCBjaGFubmVsczsgY2grKykgewogICAgICAgIElOVCBoZWFkcm9vbTsKCiAgICAgICAgRklYUF9EQkwgY2xpcEVuZXJneTsKICAgICAgICBJTlQgZW5lcmd5U2hpZnQgID0gcHN5RGF0YVtjaF0tPm1kY3RTY2FsZSoyIDsKICAgICAgICBJTlQgY2xpcE5yZ1NoaWZ0ID0gZW5lcmd5U2hpZnQgLSBUSFJfU0hJRlRCSVRTIDsKCiAgICAgICAgaWYoaXNTaG9ydFdpbmRvd1tjaF0pCiAgICAgICAgICAgIGhlYWRyb29tID0gNjsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGhlYWRyb29tID0gMDsKCiAgICAgICAgaWYgKGNsaXBOcmdTaGlmdCA+PSAwKQogICAgICAgICAgICBjbGlwRW5lcmd5ID0gaFRoaXNQc3lDb25mW2NoXS0+Y2xpcEVuZXJneSA+PiAgY2xpcE5yZ1NoaWZ0IDsKICAgICAgICBlbHNlIGlmIChjbGlwTnJnU2hpZnQ+PS1oZWFkcm9vbSkKICAgICAgICAgICAgY2xpcEVuZXJneSA9IGhUaGlzUHN5Q29uZltjaF0tPmNsaXBFbmVyZ3kgPDwgLWNsaXBOcmdTaGlmdCA7CiAgICAgICAgZWxzZQogICAgICAgICAgICBjbGlwRW5lcmd5ID0gKEZJWFBfREJMKU1BWFZBTF9EQkwgOwoKICAgICAgICBmb3IodyA9IDA7IHcgPCBuV2luZG93c1tjaF07IHcrKykKICAgICAgICB7CiAgICAgICAgICAgIElOVCBpOwogICAgICAgICAgICAvKiBsaW1pdCB0aHJlc2hvbGQgdG8gYXZvaWQgY2xpcHBpbmcgKi8KICAgICAgICAgICAgZm9yIChpPTA7IGk8cHN5RGF0YVtjaF0tPnNmYkFjdGl2ZTsgaSsrKSB7CiAgICAgICAgICAgICAgICAqKHBTZmJUaHJlc2hvbGRbY2hdK3cqbWF4U2ZiW2NoXStpKSA9IGZpeE1pbigqKHBTZmJUaHJlc2hvbGRbY2hdK3cqbWF4U2ZiW2NoXStpKSwgY2xpcEVuZXJneSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIHNwcmVhZGluZyAqLwogICAgICAgICAgICBGREthYWNFbmNfU3ByZWFkaW5nTWF4KHBzeURhdGFbY2hdLT5zZmJBY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoVGhpc1BzeUNvbmZbY2hdLT5zZmJNYXNrTG93RmFjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRoaXNQc3lDb25mW2NoXS0+c2ZiTWFza0hpZ2hGYWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2ZiVGhyZXNob2xkW2NoXSt3Km1heFNmYltjaF0pOwoKCiAgICAgICAgICAgIC8qIFBDTSBxdWFudGl6YXRpb24gdGhyZXNob2xkICovCiAgICAgICAgICAgIGVuZXJneVNoaWZ0ICs9IFBDTV9RVUFOVF9USFJfU0NBTEU7CiAgICAgICAgICAgIGlmIChlbmVyZ3lTaGlmdD49MCkgewogICAgICAgICAgICAgICBlbmVyZ3lTaGlmdCA9IGZpeE1pbihERlJBQ1RfQklUUy0xLGVuZXJneVNoaWZ0KTsKICAgICAgICAgICAgICAgZm9yIChpPTA7IGk8cHN5RGF0YVtjaF0tPnNmYkFjdGl2ZTtpKyspIHsKICAgICAgICAgICAgICAgICAgICoocFNmYlRocmVzaG9sZFtjaF0rdyptYXhTZmJbY2hdK2kpID0gZml4TWF4KCoocFNmYlRocmVzaG9sZFtjaF0rdyptYXhTZmJbY2hdK2kpID4+IFRIUl9TSElGVEJJVFMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaFRoaXNQc3lDb25mW2NoXS0+c2ZiUGNtUXVhbnRUaHJlc2hvbGRbaV0gPj4gZW5lcmd5U2hpZnQpKTsKICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICBlbmVyZ3lTaGlmdCA9IGZpeE1pbihERlJBQ1RfQklUUy0xLC1lbmVyZ3lTaGlmdCk7CiAgICAgICAgICAgICAgIGZvciAoaT0wOyBpPHBzeURhdGFbY2hdLT5zZmJBY3RpdmU7aSsrKSB7CiAgICAgICAgICAgICAgICAgICAqKHBTZmJUaHJlc2hvbGRbY2hdK3cqbWF4U2ZiW2NoXStpKSA9IGZpeE1heCgqKHBTZmJUaHJlc2hvbGRbY2hdK3cqbWF4U2ZiW2NoXStpKSA+PiBUSFJfU0hJRlRCSVRTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGhUaGlzUHN5Q29uZltjaF0tPnNmYlBjbVF1YW50VGhyZXNob2xkW2ldIDw8IGVuZXJneVNoaWZ0KSk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCFwc3lTdGF0aWNbY2hdLT5pc0xGRSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogcHJlZWNobyBjb250cm9sICovCiAgICAgICAgICAgICAgICBpZihwc3lTdGF0aWNbY2hdLT5ibG9ja1N3aXRjaGluZ0NvbnRyb2wubGFzdFdpbmRvd1NlcXVlbmNlID09IFNUT1BfV0lORE9XKSB7CiAgICAgICAgICAgICAgICAgICAgLyogcHJldmVudCBGREthYWNFbmNfUHJlRWNob0NvbnRyb2wgZnJvbSBjb21wYXJpbmcgc3RvcAogICAgICAgICAgICAgICAgICAgICAgIHRocmVzaG9sZHMgd2l0aCBzaG9ydCB0aHJlc2hvbGRzICovCiAgICAgICAgICAgICAgICAgICAgZm9yIChpPTA7IGk8cHN5RGF0YVtjaF0tPnNmYkFjdGl2ZTtpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgcHN5U3RhdGljW2NoXS0+c2ZiVGhyZXNob2xkbm0xW2ldID0gKEZJWFBfREJMKU1BWFZBTF9EQkw7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBwc3lTdGF0aWNbY2hdLT5tZGN0U2NhbGVubTEgPSAwOwogICAgICAgICAgICAgICAgICAgIHBzeVN0YXRpY1tjaF0tPmNhbGNQcmVFY2hvICA9IDA7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgRkRLYWFjRW5jX1ByZUVjaG9Db250cm9sKCBwc3lTdGF0aWNbY2hdLT5zZmJUaHJlc2hvbGRubTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5U3RhdGljW2NoXS0+Y2FsY1ByZUVjaG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5RGF0YVtjaF0tPnNmYkFjdGl2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoVGhpc1BzeUNvbmZbY2hdLT5tYXhBbGxvd2VkSW5jcmVhc2VGYWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFRoaXNQc3lDb25mW2NoXS0+bWluUmVtYWluaW5nVGhyZXNob2xkRmFjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTZmJUaHJlc2hvbGRbY2hdK3cqbWF4U2ZiW2NoXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhW2NoXS0+bWRjdFNjYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwc3lTdGF0aWNbY2hdLT5tZGN0U2NhbGVubTEpOwoKICAgICAgICAgICAgICAgIHBzeVN0YXRpY1tjaF0tPmNhbGNQcmVFY2hvID0gMTsKCiAgICAgICAgICAgICAgICBpZihwc3lTdGF0aWNbY2hdLT5ibG9ja1N3aXRjaGluZ0NvbnRyb2wubGFzdFdpbmRvd1NlcXVlbmNlID09IFNUQVJUX1dJTkRPVykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBwcmV2ZW50IEZES2FhY0VuY19QcmVFY2hvQ29udHJvbCBpbiBuZXh0IGZyYW1lIHRvIGNvbXBhcmUgc3RhcnQKICAgICAgICAgICAgICAgICAgICAgICB0aHJlc2hvbGRzIHdpdGggc2hvcnQgdGhyZXNob2xkcyAqLwogICAgICAgICAgICAgICAgICAgIGZvciAoaT0wOyBpPHBzeURhdGFbY2hdLT5zZmJBY3RpdmU7aSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBzeVN0YXRpY1tjaF0tPnNmYlRocmVzaG9sZG5tMVtpXSA9IChGSVhQX0RCTClNQVhWQUxfREJMOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgcHN5U3RhdGljW2NoXS0+bWRjdFNjYWxlbm0xID0gMDsKICAgICAgICAgICAgICAgICAgICBwc3lTdGF0aWNbY2hdLT5jYWxjUHJlRWNobyAgPSAwOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogc3ByZWFkIGVuZXJneSB0byBhdm9pZCBob2xlIGRldGVjdGlvbiAqLwogICAgICAgICAgICBGREttZW1jcHkocFNmYlNwcmVhZEVuZXJneVtjaF0rdyptYXhTZmJbY2hdLCBwU2ZiRW5lcmd5W2NoXSt3Km1heFNmYltjaF0sIHBzeURhdGFbY2hdLT5zZmJBY3RpdmUqc2l6ZW9mKEZJWFBfREJMKSk7CgogICAgICAgICAgICBGREthYWNFbmNfU3ByZWFkaW5nTWF4KHBzeURhdGFbY2hdLT5zZmJBY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICBoVGhpc1BzeUNvbmZbY2hdLT5zZmJNYXNrTG93RmFjdG9yU3ByRW4sCiAgICAgICAgICAgICAgICAgICAgICAgICBoVGhpc1BzeUNvbmZbY2hdLT5zZmJNYXNrSGlnaEZhY3RvclNwckVuLAogICAgICAgICAgICAgICAgICAgICAgICAgcFNmYlNwcmVhZEVuZXJneVtjaF0rdyptYXhTZmJbY2hdKTsKICAgICAgICB9CiAgICB9CgogICAgLyogQ2FsYyBiYW5kd2lzZSBlbmVyZ2llcyBmb3IgbWlkIGFuZCBzaWRlIGNoYW5uZWwuIERvIGl0IG9ubHkgaWYgMiBjaGFubmVscyBleGlzdCAqLwogICAgaWYgKGNoYW5uZWxzPT0yKSB7CiAgICAgICAgZm9yKHcgPSAwOyB3IDwgbldpbmRvd3NbMV07IHcrKykgewogICAgICAgICAgICB3T2Zmc2V0ID0gdyp3aW5kb3dMZW5ndGhbMV07CiAgICAgICAgICAgIEZES2FhY0VuY19DYWxjQmFuZE5yZ01TT3B0KHBzeURhdGFbMF0tPm1kY3RTcGVjdHJ1bSt3T2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbMV0tPm1kY3RTcGVjdHJ1bSt3T2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTZmJNYXhTY2FsZVNwZWNbMF0rdyptYXhTZmJbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNmYk1heFNjYWxlU3BlY1sxXSt3Km1heFNmYlsxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoVGhpc1BzeUNvbmZbMV0tPnNmYk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhWzBdLT5zZmJBY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNmYkVuZXJneU1TWzBdK3cqbWF4U2ZiWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTZmJFbmVyZ3lNU1sxXSt3Km1heFNmYlsxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocHN5U3RhdGljWzFdLT5ibG9ja1N3aXRjaGluZ0NvbnRyb2wubGFzdFdpbmRvd1NlcXVlbmNlICE9IFNIT1JUX1dJTkRPVyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5RGF0YVswXS0+c2ZiRW5lcmd5TVNMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5RGF0YVsxXS0+c2ZiRW5lcmd5TVNMZERhdGEpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBncm91cCBzaG9ydCBkYXRhIChtYXhTZmJbY2hdIGZvciBzaG9ydCBibG9ja3MgaXMgZGV0ZXJtaW5lZCBoZXJlKSAqLwogICAgZm9yKGNoPTA7Y2g8Y2hhbm5lbHM7Y2grKykKICAgIHsKICAgICAgICBJTlQgbm9TZmIsIGk7CiAgICAgICAgaWYoaXNTaG9ydFdpbmRvd1tjaF0pCiAgICAgICAgewogICAgICAgICAgICBpbnQgc2ZiR3JwOwogICAgICAgICAgICBub1NmYiA9IHBzeVN0YXRpY1tjaF0tPmJsb2NrU3dpdGNoaW5nQ29udHJvbC5ub09mR3JvdXBzICogaFBzeUNvbmZTaG9ydC0+c2ZiQ250OwogICAgICAgICAgICAvKiBBdCB0aGlzIHBvaW50LCBlbmVyZ2llcyBhbmQgdGhyZXNob2xkcyBhcmUgY29waWVkL3JlZ3JvdXBlZCBmcm9tIHRoZSAiLlNob3J0IiB0byB0aGUgIi5Mb25nIiBhcnJheXMgKi8KICAgICAgICAgICAgRkRLYWFjRW5jX2dyb3VwU2hvcnREYXRhKCBwc3lEYXRhW2NoXS0+bWRjdFNwZWN0cnVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBzeURhdGFbY2hdLT5zZmJUaHJlc2hvbGQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcHN5RGF0YVtjaF0tPnNmYkVuZXJneSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwc3lEYXRhW2NoXS0+c2ZiRW5lcmd5TVMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcHN5RGF0YVtjaF0tPnNmYlNwcmVhZEVuZXJneSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhQc3lDb25mU2hvcnQtPnNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbY2hdLT5zZmJBY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoUHN5Q29uZlNob3J0LT5zZmJPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoUHN5Q29uZlNob3J0LT5zZmJNaW5TbnJMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhW2NoXS0+Z3JvdXBlZFNmYk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZtYXhTZmJQZXJHcm91cFtjaF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFubmVsW2NoXS0+c2ZiTWluU25yTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5U3RhdGljW2NoXS0+YmxvY2tTd2l0Y2hpbmdDb250cm9sLm5vT2ZHcm91cHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lTdGF0aWNbY2hdLT5ibG9ja1N3aXRjaGluZ0NvbnRyb2wuZ3JvdXBMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lDb25mWzFdLmdyYW51bGVMZW5ndGgpOwoKCiAgICAgICAgICAgIC8qIGNhbGN1bGF0ZSBsZERhdGEgYXJyYXlzIChzaG9ydCB2YWx1ZXMgYXJlIGluIC5Mb25nLWFycmF5cyBhZnRlciBGREthYWNFbmNfZ3JvdXBTaG9ydERhdGEpICovCiAgICAgICAgICAgIGZvciAoc2ZiR3JwID0gMDsgc2ZiR3JwIDwgbm9TZmI7IHNmYkdycCArPSBoUHN5Q29uZlNob3J0LT5zZmJDbnQpIHsKICAgICAgICAgICAgICBMZERhdGFWZWN0b3IoJnBzeURhdGFbY2hdLT5zZmJFbmVyZ3kuTG9uZ1tzZmJHcnBdLCAmcHN5T3V0Q2hhbm5lbFtjaF0tPnNmYkVuZXJneUxkRGF0YVtzZmJHcnBdLCBwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogY2FsYyBzZmJUaHJsZCBhbmQgc2V0IFZhbHVlcyBzbWFsbGVyIDJeLTMxIHRvIDJeLTMzKi8KICAgICAgICAgICAgZm9yIChzZmJHcnAgPSAwOyBzZmJHcnAgPCBub1NmYjsgc2ZiR3JwICs9IGhQc3lDb25mU2hvcnQtPnNmYkNudCkgewogICAgICAgICAgICAgIExkRGF0YVZlY3RvcigmcHN5RGF0YVtjaF0tPnNmYlRocmVzaG9sZC5Mb25nW3NmYkdycF0sICZwc3lPdXRDaGFubmVsW2NoXS0+c2ZiVGhyZXNob2xkTGREYXRhW3NmYkdycF0sIHBzeURhdGFbY2hdLT5zZmJBY3RpdmUpOwogICAgICAgICAgICAgIGZvciAoc2ZiPTA7c2ZiPHBzeURhdGFbY2hdLT5zZmJBY3RpdmU7c2ZiKyspIHsKICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWxbY2hdLT5zZmJUaHJlc2hvbGRMZERhdGFbc2ZiR3JwK3NmYl0gPQogICAgICAgICAgICAgICAgICAgICAgICAgICBmaXhNYXgocHN5T3V0Q2hhbm5lbFtjaF0tPnNmYlRocmVzaG9sZExkRGF0YVtzZmJHcnArc2ZiXSwgRkwyRlhDT05TVF9EQkwoLTAuNTE1NjI1ZikpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCBjaGFubmVscz09MiApIHsKICAgICAgICAgICAgICBmb3IgKHNmYkdycCA9IDA7IHNmYkdycCA8IG5vU2ZiOyBzZmJHcnAgKz0gaFBzeUNvbmZTaG9ydC0+c2ZiQ250KSB7CiAgICAgICAgICAgICAgICBMZERhdGFWZWN0b3IoJnBzeURhdGFbY2hdLT5zZmJFbmVyZ3lNUy5Mb25nW3NmYkdycF0sICZwc3lEYXRhW2NoXS0+c2ZiRW5lcmd5TVNMZERhdGFbc2ZiR3JwXSwgcHN5RGF0YVtjaF0tPnNmYkFjdGl2ZSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBGREttZW1jcHkocHN5T3V0Q2hhbm5lbFtjaF0tPnNmYk9mZnNldHMsIHBzeURhdGFbY2hdLT5ncm91cGVkU2ZiT2Zmc2V0LCAoTUFYX0dST1VQRURfU0ZCKzEpKnNpemVvZihJTlQpKTsKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogbWF4U2ZiW2NoXSBmb3IgbG9uZyBibG9ja3MgKi8KICAgICAgICAgICAgZm9yIChzZmIgPSBwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlLTE7IHNmYiA+PSAwOyBzZmItLSkgewogICAgICAgICAgICAgICAgZm9yIChsaW5lID0gaFBzeUNvbmZMb25nLT5zZmJPZmZzZXRbc2ZiKzFdLTE7IGxpbmUgPj0gaFBzeUNvbmZMb25nLT5zZmJPZmZzZXRbc2ZiXTsgbGluZS0tKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBzeURhdGFbY2hdLT5tZGN0U3BlY3RydW1bbGluZV0gIT0gRkwyRlhDT05TVF9TR0woMC4wZikpIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGxpbmUgPiBoUHN5Q29uZkxvbmctPnNmYk9mZnNldFtzZmJdKSBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBtYXhTZmJQZXJHcm91cFtjaF0gPSBzZmIgKyAxOwogICAgICAgICAgICAvKiBlbnN1cmUgYXQgbGVhc3Qgb25lIHNlY3Rpb24gaW4gSUNTOyB3b3JrYXJvdW5kIGZvciBleGlzdGluZyBkZWNvZGVyIGNyYyBpbXBsZW1lbnRhdGlvbiAqLwogICAgICAgICAgICBtYXhTZmJQZXJHcm91cFtjaF0gPSBmaXhNYXgoZml4TWluKDUscHN5RGF0YVtjaF0tPnNmYkFjdGl2ZSksbWF4U2ZiUGVyR3JvdXBbY2hdKTsKCiAgICAgICAgICAgIC8qIHNmYk5yZ0xkRGF0YSBpcyBjYWxjdWxhdGVkIGluIEZES2FhY0VuY19hZHZhbmNlUHN5Y2hMb25nLCBjb3B5IGluIHBzeU91dCBzdHJ1Y3R1cmUgKi8KICAgICAgICAgICAgRkRLbWVtY3B5KHBzeU91dENoYW5uZWxbY2hdLT5zZmJFbmVyZ3lMZERhdGEsIHBzeURhdGFbY2hdLT5zZmJFbmVyZ3lMZERhdGEuTG9uZywgcHN5RGF0YVtjaF0tPnNmYkFjdGl2ZSpzaXplb2YoRklYUF9EQkwpKTsKCiAgICAgICAgICAgIEZES21lbWNweShwc3lPdXRDaGFubmVsW2NoXS0+c2ZiT2Zmc2V0cywgaFBzeUNvbmZMb25nLT5zZmJPZmZzZXQsIChNQVhfR1JPVVBFRF9TRkIrMSkqc2l6ZW9mKElOVCkpOwoKICAgICAgICAgICAgLyogc2ZiTWluU25yTGREYXRhIG1vZGlmaWVkIGluIGFkanVzdCB0aHJlc2hvbGQsIGNvcHkgbmVjZXNzYXJ5ICovCiAgICAgICAgICAgIEZES21lbWNweShwc3lPdXRDaGFubmVsW2NoXS0+c2ZiTWluU25yTGREYXRhLCBoUHN5Q29uZkxvbmctPnNmYk1pblNuckxkRGF0YSwgcHN5RGF0YVtjaF0tPnNmYkFjdGl2ZSpzaXplb2YoRklYUF9EQkwpKTsKCiAgICAgICAgICAgIC8qIHNmYkVuZXJneU1TTGREYXRhIGlzdCBhbHJlYWR5IGNhbGN1bGF0ZWQgaW4gRkRLYWFjRW5jX0NhbGNCYW5kTnJnTVNPcHQ7IG9ubHkgaW4gbG9uZyBjYXNlICovCgogICAgICAgICAgICAvKiBjYWxjIHNmYlRocmxkIGFuZCBzZXQgVmFsdWVzIHNtYWxsZXIgMl4tMzEgdG8gMl4tMzMqLwogICAgICAgICAgICBMZERhdGFWZWN0b3IocHN5RGF0YVtjaF0tPnNmYlRocmVzaG9sZC5Mb25nLCBwc3lPdXRDaGFubmVsW2NoXS0+c2ZiVGhyZXNob2xkTGREYXRhLCBwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlKTsKICAgICAgICAgICAgZm9yIChpPTA7aTxwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlO2krKykgewogICAgICAgICAgICAgIHBzeU91dENoYW5uZWxbY2hdLT5zZmJUaHJlc2hvbGRMZERhdGFbaV0gPQogICAgICAgICAgICAgICAgICAgICAgICAgICBmaXhNYXgocHN5T3V0Q2hhbm5lbFtjaF0tPnNmYlRocmVzaG9sZExkRGF0YVtpXSwgRkwyRlhDT05TVF9EQkwoLTAuNTE1NjI1ZikpOwogICAgICAgICAgICB9CgoKICAgICAgICB9CgoKICAgIH0KCgogICAgLyoKICAgICAgICBJbnRlbnNpdHkgcGFyYW1ldGVyIGludGlhbGl6YXRpb24uCiAgICAgKi8KICAgIGZvcihjaD0wO2NoPGNoYW5uZWxzO2NoKyspIHsKICAgICAgICBGREttZW1jbGVhcihwc3lPdXRDaGFubmVsW2NoXS0+aXNCb29rLCAgTUFYX0dST1VQRURfU0ZCKnNpemVvZihJTlQpKTsKICAgICAgICBGREttZW1jbGVhcihwc3lPdXRDaGFubmVsW2NoXS0+aXNTY2FsZSwgTUFYX0dST1VQRURfU0ZCKnNpemVvZihJTlQpKTsKICAgIH0KCiAgICBmb3IoY2g9MDtjaDxjaGFubmVscztjaCsrKSB7CiAgICAgICAgSU5UIHdpbiA9IChpc1Nob3J0V2luZG93W2NoXT8xOjApOwogICAgICAgIGlmICghcHN5U3RhdGljW2NoXS0+aXNMRkUpCiAgICAgICAgewogICAgICAgICAgICAvKiBQTlMgRGVjaXNpb24gKi8KICAgICAgICAgICAgRkRLYWFjRW5jX1Buc0RldGVjdCggJihwc3lDb25mWzBdLnBuc0NvbmYpLAogICAgICAgICAgICAgICAgICAgICAgIHBuc0RhdGFbY2hdLAogICAgICAgICAgICAgICAgICAgICAgIHBzeVN0YXRpY1tjaF0tPmJsb2NrU3dpdGNoaW5nQ29udHJvbC5sYXN0V2luZG93U2VxdWVuY2UsCiAgICAgICAgICAgICAgICAgICAgICAgcHN5RGF0YVtjaF0tPnNmYkFjdGl2ZSwKICAgICAgICAgICAgICAgICAgICAgICBtYXhTZmJQZXJHcm91cFtjaF0sIC8qIGNvdW50IG9mIFNmYiB3aGljaCBhcmUgbm90IHplcm8uICovCiAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFtjaF0tPnNmYlRocmVzaG9sZExkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICBwc3lDb25mW3dpbl0uc2ZiT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbY2hdLT5tZGN0U3BlY3RydW0sCiAgICAgICAgICAgICAgICAgICAgICAgcHN5RGF0YVtjaF0tPnNmYk1heFNjYWxlU3BlYy5Mb25nLAogICAgICAgICAgICAgICAgICAgICAgIHNmYlRvbmFsaXR5W2NoXSwKICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFubmVsW2NoXS0+dG5zSW5mby5vcmRlclswXVswXSwKICAgICAgICAgICAgICAgICAgICAgICB0bnNEYXRhW2NoXS0+ZGF0YVJhdy5Mb25nLnN1YkJsb2NrSW5mby5wcmVkaWN0aW9uR2FpbiwKICAgICAgICAgICAgICAgICAgICAgICB0bnNEYXRhW2NoXS0+ZGF0YVJhdy5Mb25nLnN1YkJsb2NrSW5mby50bnNBY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFtjaF0tPnNmYkVuZXJneUxkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFubmVsW2NoXS0+bm9pc2VOcmcgKTsKICAgICAgICB9IC8qICFpc0xGRSAqLwogICAgfQoKICAgIC8qCiAgICAgICAgc3RlcmVvIFByb2Nlc3NpbmcKICAgICovCiAgICBpZihjaGFubmVscyA9PSAyKQogICAgewogICAgICAgIHBzeU91dEVsZW1lbnQtPnRvb2xzSW5mby5tc0RpZ2VzdCA9IE1TX05PTkU7CiAgICAgICAgcHN5T3V0RWxlbWVudC0+Y29tbW9uV2luZG93ICAgICAgID0gY29tbW9uV2luZG93OwogICAgICAgIGlmIChwc3lPdXRFbGVtZW50LT5jb21tb25XaW5kb3cpCiAgICAgICAgICAgIG1heFNmYlBlckdyb3VwWzBdID0gbWF4U2ZiUGVyR3JvdXBbMV0gPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXhNYXgobWF4U2ZiUGVyR3JvdXBbMF0sIG1heFNmYlBlckdyb3VwWzFdKTsKCiAgICAgICAgaWYocHN5U3RhdGljWzBdLT5ibG9ja1N3aXRjaGluZ0NvbnRyb2wubGFzdFdpbmRvd1NlcXVlbmNlICE9IFNIT1JUX1dJTkRPVykKICAgICAgICB7CiAgICAgICAgICAgIC8qIFBOUyBwcmVwcm9jZXNzaW5nIGRlcGVuZGluZyBvbiBtcyBwcm9jZXNzaW5nOiBQTlMgbm90IGluIFNob3J0IFdpbmRvdyEgKi8KICAgICAgICAgICAgRkRLYWFjRW5jX1ByZVByb2Nlc3NQbnNDaGFubmVsUGFpcigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhWzBdLT5zZmJBY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCZwc3lEYXRhWzBdLT5zZmJFbmVyZ3kpLT5Mb25nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgmcHN5RGF0YVsxXS0+c2ZiRW5lcmd5KS0+TG9uZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFubmVsWzBdLT5zZmJFbmVyZ3lMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFsxXS0+c2ZiRW5lcmd5TGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbMF0tPnNmYkVuZXJneU1TLkxvbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJihwc3lDb25mWzBdLnBuc0NvbmYpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBuc0RhdGFbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG5zRGF0YVsxXSk7CgogICAgICAgICAgICBGREthYWNFbmNfSW50ZW5zaXR5U3RlcmVvUHJvY2Vzc2luZygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhWzBdLT5zZmJFbmVyZ3kuTG9uZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhWzFdLT5zZmJFbmVyZ3kuTG9uZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhWzBdLT5tZGN0U3BlY3RydW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5RGF0YVsxXS0+bWRjdFNwZWN0cnVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbMF0tPnNmYlRocmVzaG9sZC5Mb25nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbMV0tPnNmYlRocmVzaG9sZC5Mb25nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWxbMV0tPnNmYlRocmVzaG9sZExkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhWzBdLT5zZmJTcHJlYWRFbmVyZ3kuTG9uZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhWzFdLT5zZmJTcHJlYWRFbmVyZ3kuTG9uZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFubmVsWzBdLT5zZmJFbmVyZ3lMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFsxXS0+c2ZiRW5lcmd5TGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwc3lPdXRFbGVtZW50LT50b29sc0luZm8ubXNEaWdlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0RWxlbWVudC0+dG9vbHNJbmZvLm1zTWFzaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lDb25mWzBdLnNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lDb25mWzBdLnNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhTZmJQZXJHcm91cFswXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lDb25mWzBdLnNmYk9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lDb25mWzBdLmFsbG93SVMgJiYgY29tbW9uV2luZG93LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWxbMV0tPmlzQm9vaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFubmVsWzFdLT5pc1NjYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBuc0RhdGEpOwoKICAgICAgICAgICAgRkRLYWFjRW5jX01zU3RlcmVvUHJvY2Vzc2luZygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFsxXS0+aXNCb29rLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwc3lPdXRFbGVtZW50LT50b29sc0luZm8ubXNEaWdlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0RWxlbWVudC0+dG9vbHNJbmZvLm1zTWFzaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhWzBdLT5zZmJBY3RpdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5RGF0YVswXS0+c2ZiQWN0aXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heFNmYlBlckdyb3VwWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWxbMF0tPnNmYk9mZnNldHMpOwoKICAgICAgICAgICAgLyogUE5TIHBvc3Rwcm9jZXNzaW5nICovCiAgICAgICAgICAgIEZES2FhY0VuY19Qb3N0UHJvY2Vzc1Buc0NoYW5uZWxQYWlyKHBzeURhdGFbMF0tPnNmYkFjdGl2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKHBzeUNvbmZbMF0ucG5zQ29uZiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG5zRGF0YVswXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbnNEYXRhWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dEVsZW1lbnQtPnRvb2xzSW5mby5tc01hc2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBzeU91dEVsZW1lbnQtPnRvb2xzSW5mby5tc0RpZ2VzdCk7CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEZES2FhY0VuY19JbnRlbnNpdHlTdGVyZW9Qcm9jZXNzaW5nKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbMF0tPnNmYkVuZXJneS5Mb25nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbMV0tPnNmYkVuZXJneS5Mb25nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbMF0tPm1kY3RTcGVjdHJ1bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lEYXRhWzFdLT5tZGN0U3BlY3RydW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5RGF0YVswXS0+c2ZiVGhyZXNob2xkLkxvbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5RGF0YVsxXS0+c2ZiVGhyZXNob2xkLkxvbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFsxXS0+c2ZiVGhyZXNob2xkTGREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbMF0tPnNmYlNwcmVhZEVuZXJneS5Mb25nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbMV0tPnNmYlNwcmVhZEVuZXJneS5Mb25nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWxbMF0tPnNmYkVuZXJneUxkRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFubmVsWzFdLT5zZmJFbmVyZ3lMZERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBzeU91dEVsZW1lbnQtPnRvb2xzSW5mby5tc0RpZ2VzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRFbGVtZW50LT50b29sc0luZm8ubXNNYXNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeVN0YXRpY1swXS0+YmxvY2tTd2l0Y2hpbmdDb250cm9sLm5vT2ZHcm91cHMqaFBzeUNvbmZTaG9ydC0+c2ZiQ250LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeUNvbmZbMV0uc2ZiQ250LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heFNmYlBlckdyb3VwWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeURhdGFbMF0tPmdyb3VwZWRTZmJPZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5Q29uZlswXS5hbGxvd0lTICYmIGNvbW1vbldpbmRvdywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lPdXRDaGFubmVsWzFdLT5pc0Jvb2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFsxXS0+aXNTY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbnNEYXRhKTsKCiAgICAgICAgICAgIC8qIGl0J3MgT0sgdG8gcGFzcyB0aGUgIi5Mb25nIiBhcnJheXMgaGVyZS4gVGhleSBjb250YWluIGdyb3VwZWQgc2hvcnQgZGF0YSBzaW5jZSBGREthYWNFbmNfZ3JvdXBTaG9ydERhdGEoKSAqLwogICAgICAgICAgICBGREthYWNFbmNfTXNTdGVyZW9Qcm9jZXNzaW5nKCBwc3lEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzeU91dENoYW5uZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFsxXS0+aXNCb29rLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwc3lPdXRFbGVtZW50LT50b29sc0luZm8ubXNEaWdlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0RWxlbWVudC0+dG9vbHNJbmZvLm1zTWFzaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3lTdGF0aWNbMF0tPmJsb2NrU3dpdGNoaW5nQ29udHJvbC5ub09mR3JvdXBzKmhQc3lDb25mU2hvcnQtPnNmYkNudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoUHN5Q29uZlNob3J0LT5zZmJDbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4U2ZiUGVyR3JvdXBbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFswXS0+c2ZiT2Zmc2V0cyk7CiAgICAgICAgfQogICAgfQoKICAvKgogICAgUE5TIENvZGluZwogICovCiAgZm9yKGNoPTA7Y2g8Y2hhbm5lbHM7Y2grKykgewogICAgICBpZiAocHN5U3RhdGljW2NoXS0+aXNMRkUpIHsKICAgICAgICAgIC8qIG5vIFBOUyBjb2RpbmcgKi8KICAgICAgICAgIGZvcihzZmIgPSAwOyBzZmIgPCBwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlOyBzZmIrKykgewogICAgICAgICAgICBwc3lPdXRDaGFubmVsW2NoXS0+bm9pc2VOcmdbc2ZiXSA9IE5PX05PSVNFX1BOUzsKICAgICAgICAgIH0KICAgICAgfSBlbHNlCiAgICAgIHsKICAgICAgICAgIEZES2FhY0VuY19Db2RlUG5zQ2hhbm5lbChwc3lEYXRhW2NoXS0+c2ZiQWN0aXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgJihwc3lDb25mW2NoXS5wbnNDb25mKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBuc0RhdGFbY2hdLT5wbnNGbGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgcHN5RGF0YVtjaF0tPnNmYkVuZXJneUxkRGF0YS5Mb25nLAogICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFtjaF0tPm5vaXNlTnJnLCAvKiB0aGlzIGlzIHRoZSBlbmVyZ3kgdGhhdCB3aWxsIGJlIHdyaXR0ZW4gdG8gdGhlIGJpdHN0cmVhbSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFtjaF0tPnNmYlRocmVzaG9sZExkRGF0YSk7CiAgICAgIH0KICB9CgogICAgLyoKICAgICAgICBidWlsZCBvdXRwdXQKICAgICovCiAgICBmb3IoY2g9MDtjaDxjaGFubmVscztjaCsrKQogICAgewogICAgICAgIElOVCBqLCBncnAsIG1hc2s7CgogICAgICAgIHBzeU91dENoYW5uZWxbY2hdLT5tYXhTZmJQZXJHcm91cCAgICA9IG1heFNmYlBlckdyb3VwW2NoXTsKICAgICAgICBwc3lPdXRDaGFubmVsW2NoXS0+bWRjdFNjYWxlICAgICAgICAgPSBwc3lEYXRhW2NoXS0+bWRjdFNjYWxlOwoKICAgICAgICBpZihpc1Nob3J0V2luZG93W2NoXT09MCkgewoKICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFtjaF0tPnNmYkNudCAgICAgICAgID0gaFBzeUNvbmZMb25nLT5zZmJBY3RpdmU7CiAgICAgICAgICAgIHBzeU91dENoYW5uZWxbY2hdLT5zZmJQZXJHcm91cCAgICA9IGhQc3lDb25mTG9uZy0+c2ZiQWN0aXZlOwogICAgICAgICAgICBwc3lPdXRDaGFubmVsW2NoXS0+bGFzdFdpbmRvd1NlcXVlbmNlID0gcHN5U3RhdGljW2NoXS0+YmxvY2tTd2l0Y2hpbmdDb250cm9sLmxhc3RXaW5kb3dTZXF1ZW5jZTsKICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFtjaF0tPndpbmRvd1NoYXBlICAgID0gcHN5U3RhdGljW2NoXS0+YmxvY2tTd2l0Y2hpbmdDb250cm9sLndpbmRvd1NoYXBlOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgSU5UIHNmYkNudCA9IHBzeVN0YXRpY1tjaF0tPmJsb2NrU3dpdGNoaW5nQ29udHJvbC5ub09mR3JvdXBzKmhQc3lDb25mU2hvcnQtPnNmYkNudDsKCiAgICAgICAgICAgIHBzeU91dENoYW5uZWxbY2hdLT5zZmJDbnQgICAgICAgICA9IHNmYkNudDsKICAgICAgICAgICAgcHN5T3V0Q2hhbm5lbFtjaF0tPnNmYlBlckdyb3VwICAgID0gaFBzeUNvbmZTaG9ydC0+c2ZiQ250OwogICAgICAgICAgICBwc3lPdXRDaGFubmVsW2NoXS0+bGFzdFdpbmRvd1NlcXVlbmNlID0gU0hPUlRfV0lORE9XOwogICAgICAgICAgICBwc3lPdXRDaGFubmVsW2NoXS0+d2luZG93U2hhcGUgICAgPSBTSU5FX1dJTkRPVzsKICAgICAgICB9CgogICAgICAgIC8qIGdlbmVyYXRlIGdyb3VwaW5nIG1hc2sgKi8KICAgICAgICBtYXNrID0gMDsKICAgICAgICBmb3IgKGdycCA9IDA7IGdycCA8IHBzeVN0YXRpY1tjaF0tPmJsb2NrU3dpdGNoaW5nQ29udHJvbC5ub09mR3JvdXBzOyBncnArKykKICAgICAgICB7CiAgICAgICAgICBtYXNrIDw8PSAxOwogICAgICAgICAgZm9yIChqPTE7IGo8cHN5U3RhdGljW2NoXS0+YmxvY2tTd2l0Y2hpbmdDb250cm9sLmdyb3VwTGVuW2dycF07IGorKykgewogICAgICAgICAgICAgIG1hc2sgPSAobWFzazw8MSkgfCAxIDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcHN5T3V0Q2hhbm5lbFtjaF0tPmdyb3VwaW5nTWFzayA9IG1hc2s7CgogICAgICAgIC8qIGJ1aWxkIGludGVyZmFjZSAqLwogICAgICAgIEZES21lbWNweShwc3lPdXRDaGFubmVsW2NoXS0+Z3JvdXBMZW4scHN5U3RhdGljW2NoXS0+YmxvY2tTd2l0Y2hpbmdDb250cm9sLmdyb3VwTGVuLE1BWF9OT19PRl9HUk9VUFMqc2l6ZW9mKElOVCkpOwogICAgICAgIEZES21lbWNweShwc3lPdXRDaGFubmVsW2NoXS0+c2ZiRW5lcmd5LCgmcHN5RGF0YVtjaF0tPnNmYkVuZXJneSktPkxvbmcsIE1BWF9HUk9VUEVEX1NGQipzaXplb2YoRklYUF9EQkwpKTsKICAgICAgICBGREttZW1jcHkocHN5T3V0Q2hhbm5lbFtjaF0tPnNmYlNwcmVhZEVuZXJneSwoJnBzeURhdGFbY2hdLT5zZmJTcHJlYWRFbmVyZ3kpLT5Mb25nLCBNQVhfR1JPVVBFRF9TRkIqc2l6ZW9mKEZJWFBfREJMKSk7Ci8vICAgICAgICBGREttZW1jcHkocHN5T3V0Q2hhbm5lbFtjaF0tPm1kY3RTcGVjdHJ1bSwgcHN5RGF0YVtjaF0tPm1kY3RTcGVjdHJ1bSwgKDEwMjQpKnNpemVvZihGSVhQX0RCTCkpOwogICAgfQoKICAgIHJldHVybiBBQUNfRU5DX09LOwp9CgoKdm9pZCBGREthYWNFbmNfUHN5Q2xvc2UoUFNZX0lOVEVSTkFMICAgKipwaFBzeUludGVybmFsLAogICAgICAgICAgICAgICAgICAgICAgICBQU1lfT1VUICAgICAgICAqKnBoUHN5T3V0KQp7CiAgICBpbnQgbiwgaTsKCgogICAgaWYocGhQc3lJbnRlcm5hbCE9TlVMTCkgewogICAgICBQU1lfSU5URVJOQUwgKmhQc3lJbnRlcm5hbCA9ICpwaFBzeUludGVybmFsOwoKICAgICAgaWYgKGhQc3lJbnRlcm5hbCkKICAgICAgewogICAgICAgIGZvciAoaT0wOyBpPCg4KTsgaSsrKSB7CiAgICAgICAgICBpZiAoaFBzeUludGVybmFsLT5wU3RhdGljQ2hhbm5lbHNbaV0pIHsKICAgICAgICAgICAgaWYgKGhQc3lJbnRlcm5hbC0+cFN0YXRpY0NoYW5uZWxzW2ldLT5wc3lJbnB1dEJ1ZmZlcikKICAgICAgICAgICAgICBGcmVlUmFtX2FhY0VuY19Qc3lJbnB1dEJ1ZmZlcigmaFBzeUludGVybmFsLT5wU3RhdGljQ2hhbm5lbHNbaV0tPnBzeUlucHV0QnVmZmVyKTsgIC8qIEFVRElPIElOUFVUIEJVRkZFUiAqLwoKICAgICAgICAgICAgRnJlZVJhbV9hYWNFbmNfUHN5U3RhdGljKCZoUHN5SW50ZXJuYWwtPnBTdGF0aWNDaGFubmVsc1tpXSk7ICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFBTWV9TVEFUSUMgKi8KICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvciAoaT0wOyBpPCg4KTsgaSsrKSB7CiAgICAgICAgICBpZiAoaFBzeUludGVybmFsLT5wc3lFbGVtZW50W2ldKQogICAgICAgICAgICBGcmVlUmFtX2FhY0VuY19Qc3lFbGVtZW50KCZoUHN5SW50ZXJuYWwtPnBzeUVsZW1lbnRbaV0pOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogUFNZX0VMRU1FTlQgKi8KICAgICAgICB9CgoKICAgICAgICBGcmVlUmFtX2FhY0VuY19Qc3lJbnRlcm5hbChwaFBzeUludGVybmFsKTsKICAgICAgfQogICAgfQoKICAgIGlmIChwaFBzeU91dCE9TlVMTCkgewogICAgICBmb3IgKG49MDsgbjwoMSk7IG4rKykgewogICAgICAgIGlmIChwaFBzeU91dFtuXSkKICAgICAgICB7CiAgICAgICAgICBmb3IgKGk9MDsgaTwoOCk7IGkrKykgewogICAgICAgICAgICBpZiAocGhQc3lPdXRbbl0tPnBQc3lPdXRDaGFubmVsc1tpXSkKICAgICAgICAgICAgICBGcmVlUmFtX2FhY0VuY19Qc3lPdXRDaGFubmVsKCZwaFBzeU91dFtuXS0+cFBzeU91dENoYW5uZWxzW2ldKTsgICAgICAgICAgICAgICAgICAvKiBQU1lfT1VUX0NIQU5ORUwgKi8KICAgICAgICAgIH0KCiAgICAgICAgICBmb3IgKGk9MDsgaTwoOCk7IGkrKykgewogICAgICAgICAgICBpZiAocGhQc3lPdXRbbl0tPnBzeU91dEVsZW1lbnRbaV0pCiAgICAgICAgICAgICAgRnJlZVJhbV9hYWNFbmNfUHN5T3V0RWxlbWVudHMoJnBoUHN5T3V0W25dLT5wc3lPdXRFbGVtZW50W2ldKTsgICAgICAgICAgICAgICAgICAgLyogUFNZX09VVF9FTEVNRU5UUyAqLwogICAgICAgICAgfQoKICAgICAgICAgIEZyZWVSYW1fYWFjRW5jX1BzeU91dCgmcGhQc3lPdXRbbl0pOwogICAgICAgIH0KICAgICAgfQogICAgfQp9Cg==