Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiEKICBcZmlsZQogIFxicmllZiAgU2JyIGRlY29kZXIgIAogIFRoaXMgbW9kdWxlIHByb3ZpZGVzIHRoZSBhY3R1YWwgZGVjb2RlciBpbXBsZW1lbnRhdGlvbi4gVGhlIFNCUiBkYXRhIChzaWRlIGluZm9ybWF0aW9uKSBpcyBhbHJlYWR5CiAgZGVjb2RlZC4gT25seSB0aHJlZSBmdW5jdGlvbnMgYXJlIHByb3ZpZGVkOgoKICBcbGkgMS4pIGNyZWF0ZVNickRlYygpOiBPbmUgdGltZSBpbml0aWFsaXphdGlvbgogIFxsaSAyLikgcmVzZXRTYnJEZWMoKTogQ2FsbGVkIGJ5IHNicl9BcHBseSgpIHdoZW4gdGhlIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBpbiBhbiBTQlJfSEVBREVSX0VMRU1FTlQgcmVxdWlyZXMgYSByZXNldAogIGFuZCByZWNhbGN1bGF0aW9uIG9mIGltcG9ydGFudCBTQlIgc3RydWN0dXJlcy4KICBcbGkgMy4pIHNicl9kZWMoKTogVGhlIGFjdHVhbCBkZWNvZGVyLiBDYWxscyB0aGUgZGlmZmVyZW50IHRvb2xzIHN1Y2ggYXMgZmlsdGVyYmFua3MsIGxwcFRyYW5zcG9zZXIoKSwgYW5kIGNhbGN1bGF0ZVNickVudmVsb3BlKCkKICBbdGhlIGVudmVsb3BlIGFkanVzdGVyXS4KCiAgXHNhIHNicl9kZWMoKSwgXHJlZiBkb2N1bWVudGF0aW9uT3ZlcnZpZXcKKi8KCiNpbmNsdWRlICJzYnJfZGVjLmgiCgojaW5jbHVkZSAic2JyX3JhbS5oIgojaW5jbHVkZSAiZW52X2V4dHIuaCIKI2luY2x1ZGUgImVudl9jYWxjLmgiCiNpbmNsdWRlICJzY2FsZS5oIgoKI2luY2x1ZGUgImdlbmVyaWNTdGRzLmgiCgojaW5jbHVkZSAic2JyZGVjX2RyYy5oIgoKCgpzdGF0aWMgdm9pZCBhc3NpZ25MY1RpbWVTbG90cyggSEFORExFX1NCUl9ERUMgaFNickRlYywgICAgICAgICAgICAgICAgICAgICAvKiE8IGhhbmRsZSB0byBEZWNvZGVyIGNoYW5uZWwgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWFBfREJMICAqKlFtZkJ1ZmZlclJlYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbm9Db2xzICkKewogIGludCBzbG90LCBpOwogIEZJWFBfREJMICAqcHRyOwoKICAvKiBOdW1iZXIgb2YgUU1GIHRpbWVzbG90cyBpbiB0aGUgb3ZlcmxhcCBidWZmZXI6ICovCiAgcHRyID0gaFNickRlYy0+cFNick92ZXJsYXBCdWZmZXI7CiAgZm9yKHNsb3Q9MDsgc2xvdDxoU2JyRGVjLT5McHBUcmFucy5wU2V0dGluZ3MtPm92ZXJsYXA7IHNsb3QrKykgewogICAgUW1mQnVmZmVyUmVhbFtzbG90XSA9IHB0cjsgcHRyICs9ICg2NCk7CiAgfQoKICAvKiBBc3NpZ24gdGltZXNsb3RzIHRvIFdvcmtidWZmZXIxICovCiAgcHRyID0gaFNickRlYy0+V29ya0J1ZmZlcjE7CiAgZm9yKGk9MDsgaTxub0NvbHM7IGkrKykgewogICAgUW1mQnVmZmVyUmVhbFtzbG90XSA9IHB0cjsgcHRyICs9ICg2NCk7CiAgICBzbG90Kys7CiAgfQp9CgoKc3RhdGljIHZvaWQgYXNzaWduSHFUaW1lU2xvdHMoIEhBTkRMRV9TQlJfREVDIGhTYnJEZWMsICAgICAgICAgICAgICAgICAgICAgLyohPCBoYW5kbGUgdG8gRGVjb2RlciBjaGFubmVsICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhQX0RCTCAgKipRbWZCdWZmZXJSZWFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9EQkwgICoqUW1mQnVmZmVySW1hZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBub0NvbHMgKQp7CiAgRklYUF9EQkwgICpwdHI7CiAgaW50IHNsb3Q7CgogIC8qIE51bWJlciBvZiBRTUYgdGltZXNsb3RzIGluIG9uZSBoYWxmIG9mIGEgZnJhbWUgKHNpemUgb2YgV29ya2J1ZmZlcjEgb3IgMik6ICovCiAgaW50IGhhbGZsZW4gPSAobm9Db2xzID4+IDEpICsgaFNickRlYy0+THBwVHJhbnMucFNldHRpbmdzLT5vdmVybGFwOwogIGludCB0b3RDb2xzID0gbm9Db2xzICsgaFNickRlYy0+THBwVHJhbnMucFNldHRpbmdzLT5vdmVybGFwOwoKICAvKiBOdW1iZXIgb2YgUU1GIHRpbWVzbG90cyBpbiB0aGUgb3ZlcmxhcCBidWZmZXI6ICovCiAgcHRyID0gaFNickRlYy0+cFNick92ZXJsYXBCdWZmZXI7CiAgZm9yKHNsb3Q9MDsgc2xvdDxoU2JyRGVjLT5McHBUcmFucy5wU2V0dGluZ3MtPm92ZXJsYXA7IHNsb3QrKykgewogICAgUW1mQnVmZmVyUmVhbFtzbG90XSA9IHB0cjsgcHRyICs9ICg2NCk7CiAgICBRbWZCdWZmZXJJbWFnW3Nsb3RdID0gcHRyOyBwdHIgKz0gKDY0KTsKICB9CgogIC8qIEFzc2lnbiBmaXJzdCBoYWxmIG9mIHRpbWVzbG90cyB0byBXb3JrYnVmZmVyMSAqLwogIHB0ciA9IGhTYnJEZWMtPldvcmtCdWZmZXIxOwogIGZvcig7IHNsb3Q8aGFsZmxlbjsgc2xvdCsrKSB7CiAgICBRbWZCdWZmZXJSZWFsW3Nsb3RdID0gcHRyOyBwdHIgKz0gKDY0KTsKICAgIFFtZkJ1ZmZlckltYWdbc2xvdF0gPSBwdHI7IHB0ciArPSAoNjQpOwogIH0KCiAgLyogQXNzaWduIHNlY29uZCBoYWxmIG9mIHRpbWVzbG90cyB0byBXb3JrYnVmZmVyMiAqLwogIHB0ciA9IGhTYnJEZWMtPldvcmtCdWZmZXIyOwogIGZvcig7IHNsb3Q8dG90Q29sczsgc2xvdCsrKSB7CiAgICBRbWZCdWZmZXJSZWFsW3Nsb3RdID0gcHRyOyBwdHIgKz0gKDY0KTsKICAgIFFtZkJ1ZmZlckltYWdbc2xvdF0gPSBwdHI7IHB0ciArPSAoNjQpOwogIH0KfQoKCnN0YXRpYyB2b2lkIGFzc2lnblRpbWVTbG90cyggSEFORExFX1NCUl9ERUMgaFNickRlYywgICAgICAgICAgICAgICAgICAgICAvKiE8IGhhbmRsZSB0byBEZWNvZGVyIGNoYW5uZWwgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbm9Db2xzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCB1c2VMUCApCnsKIC8qIGFzc2lnbiBxbWYgdGltZSBzbG90cyAqLwogIGhTYnJEZWMtPnVzZUxQID0gdXNlTFA7CiAgaWYgKHVzZUxQKSB7CiAgICBoU2JyRGVjLT5TeW50aGVzaXNRTUYuZmxhZ3MgfD0gUU1GX0ZMQUdfTFA7CiAgICBoU2JyRGVjLT5BbmFseXNpc2NRTUYuZmxhZ3MgfD0gUU1GX0ZMQUdfTFA7CiAgfSBlbHNlIHsKICAgIGhTYnJEZWMtPlN5bnRoZXNpc1FNRi5mbGFncyAmPSB+UU1GX0ZMQUdfTFA7CiAgICBoU2JyRGVjLT5BbmFseXNpc2NRTUYuZmxhZ3MgJj0gflFNRl9GTEFHX0xQOwogIH0KICBpZiAoIXVzZUxQKQogICAgYXNzaWduSHFUaW1lU2xvdHMoIGhTYnJEZWMsIGhTYnJEZWMtPlFtZkJ1ZmZlclJlYWwsIGhTYnJEZWMtPlFtZkJ1ZmZlckltYWcsIG5vQ29scyApOwogIGVsc2UKICB7CiAgICBhc3NpZ25MY1RpbWVTbG90cyggaFNickRlYywgaFNickRlYy0+UW1mQnVmZmVyUmVhbCwgbm9Db2xzICk7CiAgfQp9CgpzdGF0aWMgdm9pZCBjaGFuZ2VRbWZUeXBlKCBIQU5ETEVfU0JSX0RFQyBoU2JyRGVjLCAgICAgICAgICAgICAgICAgICAgIC8qITwgaGFuZGxlIHRvIERlY29kZXIgY2hhbm5lbCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdXNlTGRUaW1lQWxpZ24gKQp7CiAgVUlOVCBzeW5RbWZGbGFncyA9IGhTYnJEZWMtPlN5bnRoZXNpc1FNRi5mbGFnczsKICBVSU5UIGFuYVFtZkZsYWdzID0gaFNickRlYy0+QW5hbHlzaXNjUU1GLmZsYWdzOwogIGludCAgcmVzZXRTeW5RbWYgPSAwOwogIGludCAgcmVzZXRBbmFRbWYgPSAwOwoKICAvKiBhc3NpZ24gcW1mIHR5cGUgKi8KICBpZiAodXNlTGRUaW1lQWxpZ24pIHsKICAgIGlmIChzeW5RbWZGbGFncyAmIFFNRl9GTEFHX0NMREZCKSB7CiAgICAgIC8qIGNoYW5nZSB0aGUgdHlwZSB0byBNUFNMRCAqLwogICAgICBzeW5RbWZGbGFncyAmPSB+UU1GX0ZMQUdfQ0xERkI7CiAgICAgIHN5blFtZkZsYWdzIHw9ICBRTUZfRkxBR19NUFNMREZCOwogICAgICByZXNldFN5blFtZiA9IDE7CiAgICB9CiAgICBpZiAoYW5hUW1mRmxhZ3MgJiBRTUZfRkxBR19DTERGQikgewogICAgICAvKiBjaGFuZ2UgdGhlIHR5cGUgdG8gTVBTTEQgKi8KICAgICAgYW5hUW1mRmxhZ3MgJj0gflFNRl9GTEFHX0NMREZCOwogICAgICBhbmFRbWZGbGFncyB8PSAgUU1GX0ZMQUdfTVBTTERGQjsKICAgICAgcmVzZXRBbmFRbWYgPSAxOwogICAgfQogIH0gZWxzZSB7CiAgICBpZiAoc3luUW1mRmxhZ3MgJiBRTUZfRkxBR19NUFNMREZCKSB7CiAgICAgIC8qIGNoYW5nZSB0aGUgdHlwZSB0byBDTERGQiAqLwogICAgICBzeW5RbWZGbGFncyAmPSB+UU1GX0ZMQUdfTVBTTERGQjsKICAgICAgc3luUW1mRmxhZ3MgfD0gIFFNRl9GTEFHX0NMREZCOwogICAgICByZXNldFN5blFtZiA9IDE7CiAgICB9CiAgICBpZiAoYW5hUW1mRmxhZ3MgJiBRTUZfRkxBR19NUFNMREZCKSB7CiAgICAgIC8qIGNoYW5nZSB0aGUgdHlwZSB0byBDTERGQiAqLwogICAgICBhbmFRbWZGbGFncyAmPSB+UU1GX0ZMQUdfTVBTTERGQjsKICAgICAgYW5hUW1mRmxhZ3MgfD0gIFFNRl9GTEFHX0NMREZCOwogICAgICByZXNldEFuYVFtZiA9IDE7CiAgICB9CiAgfQoKICBpZiAocmVzZXRBbmFRbWYpIHsKICAgIFFNRl9GSUxURVJfQkFOSyBwcnZBbmFRbWY7CiAgICBpbnQgIHFtZkVycjsKCiAgICAvKiBTdG9yZSBjdXJyZW50IGNvbmZpZ3VyYXRpb24gKi8KICAgIEZES21lbWNweSgmcHJ2QW5hUW1mLCAmaFNickRlYy0+QW5hbHlzaXNjUU1GLCBzaXplb2YoUU1GX0ZJTFRFUl9CQU5LKSk7CgogICAgLyogUmVzZXQgYW5hbHlzaXMgUU1GICovCiAgICBxbWZFcnIgPSBxbWZJbml0QW5hbHlzaXNGaWx0ZXJCYW5rICgKICAgICAgICAgICAmaFNickRlYy0+QW5hbHlzaXNjUU1GLAogICAgICAgICAgICBoU2JyRGVjLT5hbmFRbWZTdGF0ZXMsCiAgICAgICAgICAgIGhTYnJEZWMtPkFuYWx5c2lzY1FNRi5ub19jb2wsCiAgICAgICAgICAgIGhTYnJEZWMtPkFuYWx5c2lzY1FNRi5sc2IsCiAgICAgICAgICAgIGhTYnJEZWMtPkFuYWx5c2lzY1FNRi51c2IsCiAgICAgICAgICAgIGhTYnJEZWMtPkFuYWx5c2lzY1FNRi5ub19jaGFubmVscywKICAgICAgICAgICAgYW5hUW1mRmxhZ3MgfCBRTUZfRkxBR19LRUVQX1NUQVRFUwogICAgICAgICAgICApOwoKICAgIGlmIChxbWZFcnIgIT0gMCkgewogICAgICAvKiBSZXN0b3JlIG9sZCBjb25maWd1cmF0aW9uIG9mIGFuYWx5c2lzIFFNRiAqLwogICAgICBGREttZW1jcHkoJmhTYnJEZWMtPkFuYWx5c2lzY1FNRiwgJnBydkFuYVFtZiwgc2l6ZW9mKFFNRl9GSUxURVJfQkFOSykpOwogICAgfQogIH0KCiAgaWYgKHJlc2V0U3luUW1mKSB7CiAgICBRTUZfRklMVEVSX0JBTksgcHJ2U3luUW1mOwogICAgaW50ICBxbWZFcnI7CgogICAgLyogU3RvcmUgY3VycmVudCBjb25maWd1cmF0aW9uICovCiAgICBGREttZW1jcHkoJnBydlN5blFtZiwgJmhTYnJEZWMtPlN5bnRoZXNpc1FNRiwgc2l6ZW9mKFFNRl9GSUxURVJfQkFOSykpOwoKICAgIC8qIFJlc2V0IHN5bnRoZXNpcyBRTUYgKi8KICAgIHFtZkVyciA9IHFtZkluaXRTeW50aGVzaXNGaWx0ZXJCYW5rICgKICAgICAgICAgICAmaFNickRlYy0+U3ludGhlc2lzUU1GLAogICAgICAgICAgICBoU2JyRGVjLT5wU3luUW1mU3RhdGVzLAogICAgICAgICAgICBoU2JyRGVjLT5TeW50aGVzaXNRTUYubm9fY29sLAogICAgICAgICAgICBoU2JyRGVjLT5TeW50aGVzaXNRTUYubHNiLAogICAgICAgICAgICBoU2JyRGVjLT5TeW50aGVzaXNRTUYudXNiLAogICAgICAgICAgICBoU2JyRGVjLT5TeW50aGVzaXNRTUYubm9fY2hhbm5lbHMsCiAgICAgICAgICAgIHN5blFtZkZsYWdzIHwgUU1GX0ZMQUdfS0VFUF9TVEFURVMKICAgICAgICAgICAgKTsKCiAgICBpZiAocW1mRXJyICE9IDApIHsKICAgICAgLyogUmVzdG9yZSBvbGQgY29uZmlndXJhdGlvbiBvZiBzeW50aGVzaXMgUU1GICovCiAgICAgIEZES21lbWNweSgmaFNickRlYy0+U3ludGhlc2lzUU1GLCAmcHJ2U3luUW1mLCBzaXplb2YoUU1GX0ZJTFRFUl9CQU5LKSk7CiAgICB9CiAgfQp9CgoKLyohCiAgXGJyaWVmICAgICAgU0JSIGRlY29kZXIgY29yZSBmdW5jdGlvbiBmb3Igb25lIGNoYW5uZWwKCiAgXGltYWdlIGh0bWwgIEJ1ZmZlck1nbXREZXRhaWxlZC0xNjMyLnBuZwoKICBCZXNpZGVzIHRoZSBmaWx0ZXIgc3RhdGVzIG9mIHRoZSBRTUYgZmlsdGVyIGJhbmsgYW5kIHRoZSBMUEMtc3RhdGVzIG9mCiAgdGhlIExQUC1UcmFuc3Bvc2VyLCBwcm9jZXNzaW5nIGlzIG1haW5seSBiYXNlZCBvbiBmb3VyIGJ1ZmZlcnM6CiAgI3RpbWVJbiwgI3RpbWVPdXQsICNXb3JrQnVmZmVyMiBhbmQgI092ZXJsYXBCdWZmZXIuIFRoZSAjV29ya0J1ZmZlcjIKICBpcyByZXVzZWQgZm9yIGFsbCBjaGFubmVscyBhbmQgbWlnaHQgYmUgdXNlZCBieSB0aGUgY29yZSBkZWNvZGVyLCBhCiAgc3RhdGljIG92ZXJsYXAgYnVmZmVyIGlzIHJlcXVpcmVkIGZvciBlYWNoIGNoYW5uZWwuIER1IHRvIGluLXBsYWNlCiAgcHJvY2Vzc2luZywgI3RpbWVJbiBhbmQgI3RpbWVPdXQgcG9pbnQgdG8gaWRlbnRpY2FsIGxvY2F0aW9ucy4KCiAgVGhlIHNwZWN0cmFsIGRhdGEgaXMgb3JnYW5pemVkIGluIHNvLWNhbGxlZCBzbG90cywgZWFjaCBzbG90CiAgY29udGFpbmluZyA2NCBiYW5kcyBvZiBjb21wbGV4IGRhdGEuIFRoZSBudW1iZXIgb2Ygc2xvdHMgcGVyIGZyYW1lIGlzCiAgZGVwZW5kZW5kIG9uIHRoZSBmcmFtZSBzaXplLiBGb3IgbXAzUFJPLCB0aGVyZSBhcmUgMTggc2xvdHMgcGVyIGZyYW1lCiAgYW5kIDYgc2xvdHMgcGVyICNPdmVybGFwQnVmZmVyLiBJdCBpcyBub3QgbmVjZXNzYXJ5IHRvIGhhdmUgdGhlIHNsb3RzCiAgaW4gbG9jYXRlZCBjb25zZWN1dGl2ZSBhZGRyZXNzIHJhbmdlcy4KCiAgVG8gb3B0aW1pemUgbWVtb3J5IHVzYWdlIGFuZCB0byBtaW5pbWl6ZSB0aGUgbnVtYmVyIG9mIG1lbW9yeQogIGFjY2Vzc2VzLCB0aGUgbWVtb3J5IG1hbmFnZW1lbnQgaXMgb3JnYW5pemVkIGFzIGZvbGxvd3MgKFNsb3QgbnVtYmVycwogIGJhc2VkIG9uIG1wM1BSTyk6CgogIDEuKSBJbnB1dCB0aW1lIGRvbWFpbiBzaWduYWwgaXMgbG9jYXRlZCBpbiAjdGltZUluLCB0aGUgbGFzdCBzbG90cwogICgwLi41KSBvZiB0aGUgc3BlY3RyYWwgZGF0YSBvZiB0aGUgcHJldmlvdXMgZnJhbWUgYXJlIGxvY2F0ZWQgaW4gdGhlCiAgI092ZXJsYXBCdWZmZXIuIEluIGFkZGl0aW9uLCAjZnJhbWVEYXRhIG9mIHRoZSBjdXJyZW50IGZyYW1lIHJlc2lkZXMKICBpbiB0aGUgdXBwZXIgcGFydCBvZiAjdGltZUluLgoKICAyLikgRHVyaW5nIHRoZSBjcGx4QW5hbHlzaXNRbWZGaWx0ZXJpbmcoKSwgMzIgc2FtcGxlcyBmcm9tICN0aW1lSW4gYXJlIHRyYW5zZm9ybWVkCiAgaW50byBhIHNsb3Qgb2YgdXAgdG8gMzIgY29tcGxleCBzcGVjdHJhbCBsb3cgYmFuZCB2YWx1ZXMgYXQgYQogIHRpbWUuIFRoZSBmaXJzdCBzcGVjdHJhbCBzbG90IC0tIG5yLiA2IC0tIGlzIHdyaXR0ZW4gYXQgc2xvdCBudW1iZXIKICB6ZXJvIG9mICNXb3JrQnVmZmVyMi4gI1dvcmtCdWZmZXIyIHdpbGwgYmUgY29tcGxldGVseSBmaWxsZWQgd2l0aAogIHNwZWN0cmFsIGRhdGEuCgogIDMuKSBMUFAtVHJhbnNwb3NpdGlvbiBpbiBscHBUcmFuc3Bvc2VyKCkgaXMgcHJvY2Vzc2VkIG9uIDI0IHNsb3RzLiBEdXJpbmcgdGhlCiAgdHJhbnNwb3NpdGlvbiwgdGhlIGhpZ2ggYmFuZCBwYXJ0IG9mIHRoZSBzcGVjdHJhbCBkYXRhIGlzIHJlcGxpY2F0ZWQKICBiYXNlZCBvbiB0aGUgbG93IGJhbmQgZGF0YS4KCiAgRW52ZWxvcGUgQWRqdXN0bWVudCBpcyBwcm9jZXNzZWQgb24gdGhlIGhpZ2ggYmFuZCBwYXJ0IG9mIHRoZSBzcGVjdHJhbAogIGRhdGEgb25seSBieSBjYWxjdWxhdGVTYnJFbnZlbG9wZSgpLgoKICA0LikgVGhlIGNwbHhTeW50aGVzaXNRbWZGaWx0ZXJpbmcoKSBjcmVhdGVzIDY0IHRpbWUgZG9tYWluIHNhbXBsZXMgb3V0CiAgb2YgYSBzbG90IG9mIDY0IGNvbXBsZXggc3BlY3RyYWwgdmFsdWVzIGF0IGEgdGltZS4gVGhlIGZpcnN0IDYgc2xvdHMKICBpbiAjdGltZU91dCBhcmUgZmlsbGVkIGZyb20gdGhlIHJlc3VsdHMgb2Ygc3BlY3RyYWwgc2xvdHMgMC4uNSBpbiB0aGUKICAjT3ZlcmxhcEJ1ZmZlci4gVGhlIGNvbnNlY3V0aXZlIHNsb3RzIGluIHRpbWVPdXQgYXJlIG5vdyBmaWxsZWQgd2l0aAogIHRoZSByZXN1bHRzIG9mIHNwZWN0cmFsIHNsb3RzIDYuLjE3LgoKICA1LikgVGhlIHByZXByb2Nlc3NlZCBzbG90cyAxOC4uMjMgaGF2ZSB0byBiZSBzdG9yZWQgaW4gdGhlCiAgI092ZXJsYXBCdWZmZXIuCgoqLwoKdm9pZApzYnJfZGVjICggSEFORExFX1NCUl9ERUMgaFNickRlYywgICAgICAgICAgICAvKiE8IGhhbmRsZSB0byBEZWNvZGVyIGNoYW5uZWwgKi8KICAgICAgICAgIElOVF9QQ00gKnRpbWVJbiwgICAgICAgICAgICAgICAgICAgLyohPCBwb2ludGVyIHRvIGlucHV0IHRpbWUgc2lnbmFsICovCiAgICAgICAgICBJTlRfUENNICp0aW1lT3V0LCAgICAgICAgICAgICAgICAgIC8qITwgcG9pbnRlciB0byBvdXRwdXQgdGltZSBzaWduYWwgKi8KICAgICAgICAgIEhBTkRMRV9TQlJfREVDIGhTYnJEZWNSaWdodCwgICAgICAgLyohPCBoYW5kbGUgdG8gRGVjb2RlciBjaGFubmVsIHJpZ2h0ICovCiAgICAgICAgICBJTlRfUENNICp0aW1lT3V0UmlnaHQsICAgICAgICAgICAgIC8qITwgcG9pbnRlciB0byBvdXRwdXQgdGltZSBzaWduYWwgKi8KICAgICAgICAgIGNvbnN0IGludCBzdHJpZGVJbiwgICAgICAgICAgICAgICAgLyohPCBUaW1lIGRhdGEgdHJhdmVyc2FsIHN0cmlkZUluICovCiAgICAgICAgICBjb25zdCBpbnQgc3RyaWRlT3V0LCAgICAgICAgICAgICAgIC8qITwgVGltZSBkYXRhIHRyYXZlcnNhbCBzdHJpZGVPdXQgKi8KICAgICAgICAgIEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsLyohPCBTdGF0aWMgY29udHJvbCBkYXRhICovCiAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaEZyYW1lRGF0YSwgIC8qITwgQ29udHJvbCBkYXRhIG9mIGN1cnJlbnQgZnJhbWUgKi8KICAgICAgICAgIEhBTkRMRV9TQlJfUFJFVl9GUkFNRV9EQVRBIGhQcmV2RnJhbWVEYXRhLCAgLyohPCBTb21lIGNvbnRyb2wgZGF0YSBvZiBsYXN0IGZyYW1lICovCiAgICAgICAgICBjb25zdCBpbnQgYXBwbHlQcm9jZXNzaW5nLCAgICAgICAgIC8qITwgRmxhZyBmb3IgU0JSIG9wZXJhdGlvbiAqLwogICAgICAgICAgSEFORExFX1BTX0RFQyBoX3BzX2QsCiAgICAgICAgICBjb25zdCBVSU5UIGZsYWdzLAogICAgICAgICAgY29uc3QgaW50IGNvZGVjRnJhbWVTaXplCiAgICAgICAgICkKewogIGludCBpLCBzbG90LCByZXNlcnZlOwogIGludCBzYXZlTGJTY2FsZTsKICBpbnQgb3ZfbGVuOwogIGludCBsYXN0U2xvdE9mZnM7CiAgRklYUF9EQkwgbWF4VmFsOwoKICAvKiAxKzEvMyBmcmFtZXMgb2Ygc3BlY3RyYWwgZGF0YTogKi8KICBGSVhQX0RCTCAqKlFtZkJ1ZmZlclJlYWwgPSBoU2JyRGVjLT5RbWZCdWZmZXJSZWFsOwogIEZJWFBfREJMICoqUW1mQnVmZmVySW1hZyA9IGhTYnJEZWMtPlFtZkJ1ZmZlckltYWc7CgogLyogTnVtYmVyIG9mIFFNRiB0aW1lc2xvdHMgaW4gdGhlIG92ZXJsYXAgYnVmZmVyOiAqLwogb3ZfbGVuID0gaFNickRlYy0+THBwVHJhbnMucFNldHRpbmdzLT5vdmVybGFwOwoKIC8qIE51bWJlciBvZiBRTUYgc2xvdHMgcGVyIGZyYW1lICovCiAgaW50IG5vQ29scyA9IGhIZWFkZXJEYXRhLT5udW1iZXJUaW1lU2xvdHMgKiBoSGVhZGVyRGF0YS0+dGltZVN0ZXA7CgogLyogYXNzaWduIHFtZiB0aW1lIHNsb3RzICovCiAgaWYgKCAoKGZsYWdzICYgU0JSREVDX0xPV19QT1dFUiApID8gMSA6IDApICE9ICgoaFNickRlYy0+U3ludGhlc2lzUU1GLmZsYWdzICYgUU1GX0ZMQUdfTFApID8gMSA6IDApICkgewogICAgYXNzaWduVGltZVNsb3RzKCBoU2JyRGVjLCBoSGVhZGVyRGF0YS0+bnVtYmVyVGltZVNsb3RzICogaEhlYWRlckRhdGEtPnRpbWVTdGVwLCBmbGFncyAmIFNCUkRFQ19MT1dfUE9XRVIpOwogIH0KCiAgaWYgKGZsYWdzICYgU0JSREVDX0VMRF9HUklEKSB7CiAgICAvKiBDaG9vc2UgdGhlIHJpZ2h0IGxvdyBkZWxheSBmaWx0ZXIgYmFuayAqLwogICAgY2hhbmdlUW1mVHlwZSggaFNickRlYywgKGZsYWdzICYgU0JSREVDX0xEX01QU19RTUYpID8gMSA6IDAgKTsKCiAgICAvKiBJZiB0aGUgTEQtTVBTIFFNRiBpcyBub3QgYXZhaWxhYmxlIGRlbGF5IHRoZSBzaWduYWwgYnkgKDk2LTQ4KmxkU2JyU2FtcGxpbmdSYXRlKQogICAgICogc2FtcGxlcyBhY2NvcmRpbmcgdG8gSVNPL0lFQyAxNDQ5Ni0zOjIwMDkvRkRBTSAyOjIwMTAoRSkgY2hhcHRlciA0LjUuMi4xMy4gKi8KICAgIGlmICggKGZsYWdzICYgU0JSREVDX0xEX01QU19RTUYpCiAgICAgICYmIChoU2JyRGVjLT5BbmFseXNpc2NRTUYuZmxhZ3MgJiBRTUZfRkxBR19DTERGQikgKQogICAgewogICAgICBJTlRfUENNICpwRGx5QnVmID0gaFNickRlYy0+Y29yZURlbGF5QnVmOyAgLyogRExZQlVGICovCiAgICAgIGludCBzbXBsLCBkZWxheSA9IDk2ID4+ICghKGZsYWdzICYgU0JSREVDX0RPV05TQU1QTEUpID8gMSA6IDApOwogICAgICAvKiBDcmVhdGUgVE1QQlVGICovCiAgICAgIENfQUFMTE9DX1NDUkFUQ0hfU1RBUlQocGNtVGVtcCwgSU5UX1BDTSwgKDk2KSk7CiAgICAgIC8qIENvcHkgZGVsYXkgc2FtcGxlcyBmcm9tIElOQlVGIHRvIFRNUEJVRiAqLwogICAgICBmb3IgKHNtcGwgPSAwOyBzbXBsIDwgZGVsYXk7IHNtcGwgKz0gMSkgewogICAgICAgIHBjbVRlbXBbc21wbF0gPSB0aW1lSW5bKGNvZGVjRnJhbWVTaXplLWRlbGF5K3NtcGwpKnN0cmlkZUluXTsKICAgICAgfQogICAgICAvKiBNb3ZlIGlucHV0IHNpZ25hbCByZW1haW5kZXIgdG8gdGhlIHZlcnkgZW5kIG9mIElOQlVGICovCiAgICAgIGZvciAoc21wbCA9IChjb2RlY0ZyYW1lU2l6ZS1kZWxheS0xKSpzdHJpZGVJbjsgc21wbCA+PSAwOyBzbXBsIC09IHN0cmlkZUluKSB7CiAgICAgICAgdGltZUluW3NtcGwrZGVsYXldID0gdGltZUluW3NtcGxdOwogICAgICB9CiAgICAgIC8qIENvcHkgZGVsYXllZCBzYW1wbGVzIGZyb20gbGFzdCBmcmFtZSBmcm9tIERMWUJVRiB0byB0aGUgdmVyeSBiZWdpbm5pbmcgb2YgSU5CVUYgKi8KICAgICAgZm9yIChzbXBsID0gMDsgc21wbCA8IGRlbGF5OyBzbXBsICs9IDEpIHsKICAgICAgICB0aW1lSW5bc21wbCpzdHJpZGVJbl0gPSBwRGx5QnVmW3NtcGxdOwogICAgICB9CiAgICAgIC8qIENvcHkgVE1QQlVGIHRvIERMWUJVRiAqLwogICAgICBGREttZW1jcHkocERseUJ1ZiwgcGNtVGVtcCwgZGVsYXkqc2l6ZW9mKElOVF9QQ00pKTsKICAgICAgLyogRGVzdG9yeSBUTVBCVUYgKi8KICAgICAgQ19BQUxMT0NfU0NSQVRDSF9FTkQocGNtVGVtcCwgSU5UX1BDTSwgKDk2KSk7CiAgICB9CiAgfQoKICAvKgogICAgbG93IGJhbmQgY29kZWMgc2lnbmFsIHN1YmJhbmQgZmlsdGVyaW5nCiAgICovCgogIHsKICAgIENfQUFMTE9DX1NDUkFUQ0hfU1RBUlQocW1mVGVtcCwgRklYUF9EQkwsIDIqKDY0KSk7CgogICAgcW1mQW5hbHlzaXNGaWx0ZXJpbmcoICZoU2JyRGVjLT5BbmFseXNpc2NRTUYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFFtZkJ1ZmZlclJlYWwgKyBvdl9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFFtZkJ1ZmZlckltYWcgKyBvdl9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgJmhTYnJEZWMtPnNiclNjYWxlRmFjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lSW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmlkZUluLAogICAgICAgICAgICAgICAgICAgICAgICAgICBxbWZUZW1wCiAgICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgIENfQUFMTE9DX1NDUkFUQ0hfRU5EKHFtZlRlbXAsIEZJWFBfREJMLCAyKig2NCkpOwogIH0KCiAgLyoKICAgIENsZWFyIHVwcGVyIGhhbGYgb2Ygc3BlY3RydW0KICAqLwogIHsKICAgIGludCBuQW5hbHlzaXNCYW5kcyA9IGhIZWFkZXJEYXRhLT5udW1iZXJPZkFuYWx5c2lzQmFuZHM7CgogICAgaWYgKCEgKGZsYWdzICYgU0JSREVDX0xPV19QT1dFUikpIHsKICAgICAgZm9yIChzbG90ID0gb3ZfbGVuOyBzbG90IDwgbm9Db2xzK292X2xlbjsgc2xvdCsrKSB7CiAgICAgICAgRkRLbWVtY2xlYXIoJlFtZkJ1ZmZlclJlYWxbc2xvdF1bbkFuYWx5c2lzQmFuZHNdLCgoNjQpLW5BbmFseXNpc0JhbmRzKSpzaXplb2YoRklYUF9EQkwpKTsKICAgICAgICBGREttZW1jbGVhcigmUW1mQnVmZmVySW1hZ1tzbG90XVtuQW5hbHlzaXNCYW5kc10sKCg2NCktbkFuYWx5c2lzQmFuZHMpKnNpemVvZihGSVhQX0RCTCkpOwogICAgICB9CiAgICB9IGVsc2UKICAgIGZvciAoc2xvdCA9IG92X2xlbjsgc2xvdCA8IG5vQ29scytvdl9sZW47IHNsb3QrKykgewogICAgICBGREttZW1jbGVhcigmUW1mQnVmZmVyUmVhbFtzbG90XVtuQW5hbHlzaXNCYW5kc10sKCg2NCktbkFuYWx5c2lzQmFuZHMpKnNpemVvZihGSVhQX0RCTCkpOwogICAgfQogIH0KCgoKICAvKgogICAgU2hpZnQgc3BlY3RyYWwgZGF0YSBsZWZ0IHRvIGdhaW4gYWNjdXJhY3kgaW4gdHJhbnNwb3NlciBhbmQgYWRqdXN0b3IKICAqLwogIG1heFZhbCA9IG1heFN1YmJhbmRTYW1wbGUoIFFtZkJ1ZmZlclJlYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZmxhZ3MgJiBTQlJERUNfTE9XX1BPV0VSKSA/IE5VTEwgOiBRbWZCdWZmZXJJbWFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFNickRlYy0+QW5hbHlzaXNjUU1GLmxzYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdl9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9Db2xzK292X2xlbiApOwoKICByZXNlcnZlID0gZml4TWF4KDAsQ250TGVhZGluZ1plcm9zKG1heFZhbCktMSkgOwogIHJlc2VydmUgPSBmaXhNaW4ocmVzZXJ2ZSxERlJBQ1RfQklUUy0xLWhTYnJEZWMtPnNiclNjYWxlRmFjdG9yLmxiX3NjYWxlKTsKCiAgLyogSWYgYWxsIGRhdGEgaXMgemVybywgbGJfc2NhbGUgY291bGQgYmVjb21lIHRvbyBsYXJnZSAqLwogIHJlc2NhbGVTdWJiYW5kU2FtcGxlcyggUW1mQnVmZmVyUmVhbCwKICAgICAgICAgICAgICAgICAgICAgICAgIChmbGFncyAmIFNCUkRFQ19MT1dfUE9XRVIpID8gTlVMTCA6IFFtZkJ1ZmZlckltYWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgaFNickRlYy0+QW5hbHlzaXNjUU1GLmxzYiwKICAgICAgICAgICAgICAgICAgICAgICAgIG92X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgIG5vQ29scytvdl9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICByZXNlcnZlKTsKCiAgaFNickRlYy0+c2JyU2NhbGVGYWN0b3IubGJfc2NhbGUgKz0gcmVzZXJ2ZTsKCiAgLyoKICAgIHNhdmUgbG93IGJhbmQgc2NhbGUsIHdhdmVjb2Rpbmcgb3IgcGFyYW1ldHJpYyBzdGVyZW8gbWF5IG1vZGlmeSBpdAogICovCiAgc2F2ZUxiU2NhbGUgPSBoU2JyRGVjLT5zYnJTY2FsZUZhY3Rvci5sYl9zY2FsZTsKCgogIGlmIChhcHBseVByb2Nlc3NpbmcpCiAgewogICAgVUNIQVIgKiBib3JkZXJzID0gaEZyYW1lRGF0YS0+ZnJhbWVJbmZvLmJvcmRlcnM7CiAgICBsYXN0U2xvdE9mZnMgPSAgYm9yZGVyc1toRnJhbWVEYXRhLT5mcmFtZUluZm8ubkVudmVsb3Blc10gLSBoSGVhZGVyRGF0YS0+bnVtYmVyVGltZVNsb3RzOwoKICAgIEZJWFBfREJMIGRlZ3JlZUFsaWFzWyg2NCldOwoKICAgIC8qIFRoZSB0cmFuc3Bvc2VyIHdpbGwgb3ZlcnJpZGUgbW9zdCB2YWx1ZXMgaW4gZGVncmVlQWxpYXNbXS4KICAgICAgIFRoZSBhcnJheSBuZWVkcyB0byBiZSBjbGVhcmVkIGF0IGxlYXN0IGZyb20gbG93U3ViYmFuZCB0byBoaWdoU3ViYmFuZCBiZWZvcmUuICovCiAgICBpZiAoZmxhZ3MgJiBTQlJERUNfTE9XX1BPV0VSKQogICAgICBGREttZW1jbGVhcigmZGVncmVlQWxpYXNbaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5sb3dTdWJiYW5kXSwgKGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEuaGlnaFN1YmJhbmQtaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5sb3dTdWJiYW5kKSpzaXplb2YoRklYUF9EQkwpKTsKCiAgICAvKgogICAgICBJbnZlcnNlIGZpbHRlcmluZyBvZiBsb3diYW5kIGFuZCB0cmFuc3Bvc2l0aW9uIGludG8gdGhlIFNCUi1mcmVxdWVuY3kgcmFuZ2UKICAgICovCgogICAgbHBwVHJhbnNwb3NlciAoICZoU2JyRGVjLT5McHBUcmFucywKICAgICAgICAgICAgICAgICAgICAmaFNickRlYy0+c2JyU2NhbGVGYWN0b3IsCiAgICAgICAgICAgICAgICAgICAgUW1mQnVmZmVyUmVhbCwKICAgICAgICAgICAgICAgICAgICBkZWdyZWVBbGlhcywgICAgICAgICAgICAgICAgICAvLyBvbmx5IHVzZWQgaWYgdXNlTFAgPSAxCiAgICAgICAgICAgICAgICAgICAgUW1mQnVmZmVySW1hZywKICAgICAgICAgICAgICAgICAgICBmbGFncyAmIFNCUkRFQ19MT1dfUE9XRVIsCiAgICAgICAgICAgICAgICAgICAgaEhlYWRlckRhdGEtPnRpbWVTdGVwLAogICAgICAgICAgICAgICAgICAgIGJvcmRlcnNbMF0sCiAgICAgICAgICAgICAgICAgICAgbGFzdFNsb3RPZmZzLAogICAgICAgICAgICAgICAgICAgIGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEubkludmZCYW5kcywKICAgICAgICAgICAgICAgICAgICBoRnJhbWVEYXRhLT5zYnJfaW52Zl9tb2RlLAogICAgICAgICAgICAgICAgICAgIGhQcmV2RnJhbWVEYXRhLT5zYnJfaW52Zl9tb2RlICk7CgoKCgoKICAgIC8qCiAgICAgIEFkanVzdCBlbnZlbG9wZSBvZiBjdXJyZW50IGZyYW1lLgogICAgKi8KCiAgICBjYWxjdWxhdGVTYnJFbnZlbG9wZSAoJmhTYnJEZWMtPnNiclNjYWxlRmFjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICZoU2JyRGVjLT5TYnJDYWxjdWxhdGVFbnZlbG9wZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBoSGVhZGVyRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICBoRnJhbWVEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgIFFtZkJ1ZmZlclJlYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgUW1mQnVmZmVySW1hZywKICAgICAgICAgICAgICAgICAgICAgICAgICBmbGFncyAmIFNCUkRFQ19MT1dfUE9XRVIsCgogICAgICAgICAgICAgICAgICAgICAgICAgIGRlZ3JlZUFsaWFzLAogICAgICAgICAgICAgICAgICAgICAgICAgIGZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgIChoSGVhZGVyRGF0YS0+ZnJhbWVFcnJvckZsYWcgfHwgaFByZXZGcmFtZURhdGEtPmZyYW1lRXJyb3JGbGFnKSk7CgoKICAgIC8qCiAgICAgIFVwZGF0ZSBoUHJldkZyYW1lRGF0YSAodG8gYmUgdXNlZCBpbiB0aGUgbmV4dCBmcmFtZSkKICAgICovCiAgICBmb3IgKGk9MDsgaTxoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5JbnZmQmFuZHM7IGkrKykgewogICAgICBoUHJldkZyYW1lRGF0YS0+c2JyX2ludmZfbW9kZVtpXSA9IGhGcmFtZURhdGEtPnNicl9pbnZmX21vZGVbaV07CiAgICB9CiAgICBoUHJldkZyYW1lRGF0YS0+Y291cGxpbmcgPSBoRnJhbWVEYXRhLT5jb3VwbGluZzsKICAgIGhQcmV2RnJhbWVEYXRhLT5zdG9wUG9zID0gYm9yZGVyc1toRnJhbWVEYXRhLT5mcmFtZUluZm8ubkVudmVsb3Blc107CiAgICBoUHJldkZyYW1lRGF0YS0+YW1wUmVzID0gaEZyYW1lRGF0YS0+YW1wUmVzb2x1dGlvbkN1cnJlbnRGcmFtZTsKICB9CiAgZWxzZSB7CiAgICAvKiBSZXNldCBoYl9zY2FsZSBpZiBubyBoaWdoYmFuZCBpcyBwcmVzZW50LCBiZWNhdXNlIGhiX3NjYWxlIGlzIGNvbnNpZGVyZWQgaW4gdGhlIFFNRi1zeW50aGVzaXMgKi8KICAgIGhTYnJEZWMtPnNiclNjYWxlRmFjdG9yLmhiX3NjYWxlID0gc2F2ZUxiU2NhbGU7CiAgfQoKCiAgZm9yIChpPTA7IGk8TFBDX09SREVSOyBpKyspewogICAgLyoKICAgICAgU3RvcmUgdGhlIHVubW9kaWZpZWQgcW1mIFNsb3RzIHZhbHVlcyAocmVxdWlyZWQgZm9yIExQQyBmaWx0ZXJpbmcpCiAgICAqLwogICAgaWYgKCEgKGZsYWdzICYgU0JSREVDX0xPV19QT1dFUikpIHsKICAgICAgRkRLbWVtY3B5KGhTYnJEZWMtPkxwcFRyYW5zLmxwY0ZpbHRlclN0YXRlc1JlYWxbaV0sIFFtZkJ1ZmZlclJlYWxbbm9Db2xzLUxQQ19PUkRFUitpXSwgaFNickRlYy0+QW5hbHlzaXNjUU1GLmxzYipzaXplb2YoRklYUF9EQkwpKTsKICAgICAgRkRLbWVtY3B5KGhTYnJEZWMtPkxwcFRyYW5zLmxwY0ZpbHRlclN0YXRlc0ltYWdbaV0sIFFtZkJ1ZmZlckltYWdbbm9Db2xzLUxQQ19PUkRFUitpXSwgaFNickRlYy0+QW5hbHlzaXNjUU1GLmxzYipzaXplb2YoRklYUF9EQkwpKTsKICAgIH0gZWxzZQogICAgRkRLbWVtY3B5KGhTYnJEZWMtPkxwcFRyYW5zLmxwY0ZpbHRlclN0YXRlc1JlYWxbaV0sIFFtZkJ1ZmZlclJlYWxbbm9Db2xzLUxQQ19PUkRFUitpXSwgaFNickRlYy0+QW5hbHlzaXNjUU1GLmxzYipzaXplb2YoRklYUF9EQkwpKTsKICB9CgogIC8qCiAgICBTeW50aGVzaXMgc3ViYmFuZCBmaWx0ZXJpbmcuCiAgKi8KCiAgaWYgKCAhIChmbGFncyAmIFNCUkRFQ19QU19ERUNPREVEKSApIHsKCiAgICB7CiAgICAgIGludCBvdXRTY2FsZWZhY3RvciA9IDA7CgogICAgICBpZiAoaF9wc19kICE9IE5VTEwpIHsKICAgICAgICBoX3BzX2QtPnByb2NGcmFtZUJhc2VkID0gMTsgIC8qIHdlIGhlcmUgZG8gZnJhbWUgYmFzZWQgcHJvY2Vzc2luZyAqLwogICAgICB9CgoKICAgICAgc2JyRGVjb2Rlcl9kcmNBcHBseSgmaFNickRlYy0+c2JyRHJjQ2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgUW1mQnVmZmVyUmVhbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZsYWdzICYgU0JSREVDX0xPV19QT1dFUikgPyBOVUxMIDogUW1mQnVmZmVySW1hZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgaFNickRlYy0+U3ludGhlc2lzUU1GLm5vX2NvbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAmb3V0U2NhbGVmYWN0b3IKICAgICAgICAgICAgICAgICAgICAgICAgICApOwoKCgogICAgICBxbWZDaGFuZ2VPdXRTY2FsZWZhY3RvcigmaFNickRlYy0+U3ludGhlc2lzUU1GLCBvdXRTY2FsZWZhY3RvciApOwoKICAgICAgewogICAgICAgIENfQUFMTE9DX1NDUkFUQ0hfU1RBUlQocW1mVGVtcCwgRklYUF9EQkwsIDIqKDY0KSk7CgogICAgICAgIHFtZlN5bnRoZXNpc0ZpbHRlcmluZyggJmhTYnJEZWMtPlN5bnRoZXNpc1FNRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRbWZCdWZmZXJSZWFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmbGFncyAmIFNCUkRFQ19MT1dfUE9XRVIpID8gTlVMTCA6IFFtZkJ1ZmZlckltYWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaFNickRlYy0+c2JyU2NhbGVGYWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFNickRlYy0+THBwVHJhbnMucFNldHRpbmdzLT5vdmVybGFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaWRlT3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFtZlRlbXApOwoKICAgICAgICBDX0FBTExPQ19TQ1JBVENIX0VORChxbWZUZW1wLCBGSVhQX0RCTCwgMiooNjQpKTsKICAgICAgfQoKICAgIH0KCiAgfSBlbHNlIHsgLyogKGZsYWdzICYgU0JSREVDX1BTX0RFQ09ERUQpICovCiAgICBJTlQgaSwgc2RpZmYsIG91dFNjYWxlZmFjdG9yLCBzY2FsZUZhY3Rvckxvd0JhbmQsIHNjYWxlRmFjdG9ySGlnaEJhbmQ7CiAgICBTQ0hBUiBzY2FsZUZhY3Rvckxvd0JhbmRfb3YsIHNjYWxlRmFjdG9yTG93QmFuZF9ub19vdjsKCiAgICBIQU5ETEVfUU1GX0ZJTFRFUl9CQU5LIHN5blFtZiAgICAgID0gJmhTYnJEZWMtPlN5bnRoZXNpc1FNRjsKICAgIEhBTkRMRV9RTUZfRklMVEVSX0JBTksgc3luUW1mUmlnaHQgPSAmaFNickRlY1JpZ2h0LT5TeW50aGVzaXNRTUY7CgogICAgLyogYWRhcHQgc2NhbGluZyAqLwogICAgc2RpZmYgPSBoU2JyRGVjLT5zYnJTY2FsZUZhY3Rvci5sYl9zY2FsZSAtIHJlc2VydmU7ICAgICAgICAgICAgICAgICAgLyogU2NhbGluZyBkaWZmZXJlbmNlICAgICAgICAgKi8KICAgIHNjYWxlRmFjdG9ySGlnaEJhbmQgICA9IHNkaWZmIC0gaFNickRlYy0+c2JyU2NhbGVGYWN0b3IuaGJfc2NhbGU7ICAgIC8qIFNjYWxlIG9mIGN1cnJlbnQgaGlnaCBiYW5kICovCiAgICBzY2FsZUZhY3Rvckxvd0JhbmRfb3YgPSBzZGlmZiAtIGhTYnJEZWMtPnNiclNjYWxlRmFjdG9yLm92X2xiX3NjYWxlOyAvKiBTY2FsZSBvZiBsb3cgYmFuZCBvdmVybGFwcGluZyBRTUYgZGF0YSAqLwogICAgc2NhbGVGYWN0b3JMb3dCYW5kX25vX292ID0gc2RpZmYgLSBoU2JyRGVjLT5zYnJTY2FsZUZhY3Rvci5sYl9zY2FsZTsgLyogU2NhbGUgb2YgbG93IGJhbmQgY3VycmVudCBRTUYgZGF0YSAgICAgKi8KICAgIG91dFNjYWxlZmFjdG9yICA9IDA7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEluaXRpYWwgb3V0cHV0IHNjYWxlICovCgogICAgaWYgKGhfcHNfZC0+cHJvY0ZyYW1lQmFzZWQgPT0gMSkgICAgLyogSWYgd2UgaGF2ZSBzd2l0Y2hlZCBmcm9tIGZyYW1lIHRvIHNsb3QgYmFzZWQgcHJvY2Vzc2luZyBjb3B5IGZpbHRlciBzdGF0ZXMgKi8KICAgIHsgLyogcHJvY0ZyYW1lQmFzZWQgd2lsbCBiZSB1bnNldCBsYXRlciAqLwogICAgICAvKiBjb3B5IGZpbHRlciBzdGF0ZXMgZnJvbSBsZWZ0IHRvIHJpZ2h0ICovCiAgICAgIEZES21lbWNweShzeW5RbWZSaWdodC0+RmlsdGVyU3RhdGVzLCBzeW5RbWYtPkZpbHRlclN0YXRlcywgKCg2NDApLSg2NCkpKnNpemVvZihGSVhQX1FTUykpOwogICAgfQoKICAgIC8qIHNjYWxlIEFMTCBxbWYgdmFsZXMgKCByZWFsIGFuZCBpbWFnICkgb2YgbW9ubyAvIGxlZnQgY2hhbm5lbCB0byB0aGUKICAgICAgIHNhbWUgc2NhbGUgZmFjdG9yICggb3ZfbGJfc2YsIGxiX3NmIGFuZCBocV9zZiApICAgICAgICAgICAgICAgICAgICAgICovCiAgICBzY2FsRmlsdGVyQmFua1ZhbHVlcyggaF9wc19kLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogcGFyYW1ldHJpYyBzdGVyZW8gZGVjb2RlciBoYW5kbGUgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgUW1mQnVmZmVyUmVhbCwgICAgICAgICAgICAgICAgICAgICAgLyogcW1mIGZpbHRlcmJhbmsgdmFsdWVzICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgUW1mQnVmZmVySW1hZywgICAgICAgICAgICAgICAgICAgICAgLyogcW1mIGZpbHRlcmJhbmsgdmFsdWVzICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3luUW1mLT5sc2IsICAgICAgICAgICAgICAgICAgICAgICAgLyogc2JyIHN0YXJ0IHN1YmJhbmQgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgaFNickRlYy0+c2JyU2NhbGVGYWN0b3Iub3ZfbGJfc2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaFNickRlYy0+c2JyU2NhbGVGYWN0b3IubGJfc2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAmc2NhbGVGYWN0b3JMb3dCYW5kX292LCAgICAgICAgICAgICAgLyogYWRhcHQgc2NhbGluZyB2YWx1ZXMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICZzY2FsZUZhY3Rvckxvd0JhbmRfbm9fb3YsICAgICAgICAgICAvKiBhZGFwdCBzY2FsaW5nIHZhbHVlcyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgIGhTYnJEZWMtPnNiclNjYWxlRmFjdG9yLmhiX3NjYWxlLCAgIC8qIGN1cnJlbnQgZnJhbWUgKCBoaWdoYmFuZCApICovCiAgICAgICAgICAgICAgICAgICAgICAgICAmc2NhbGVGYWN0b3JIaWdoQmFuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBzeW5RbWYtPm5vX2NvbCk7CgogICAgLyogdXNlIHRoZSBzYW1lIHN5bnRoZXNlIHFtZiB2YWx1ZXMgZm9yIGxlZnQgYW5kIHJpZ2h0IGNoYW5uZWwgKi8KICAgIHN5blFtZlJpZ2h0LT5ub19jb2wgPSBzeW5RbWYtPm5vX2NvbDsKICAgIHN5blFtZlJpZ2h0LT5sc2IgICAgPSBzeW5RbWYtPmxzYjsKICAgIHN5blFtZlJpZ2h0LT51c2IgICAgPSBzeW5RbWYtPnVzYjsKCiAgICBpbnQgZW52PTA7CgogICAgICBvdXRTY2FsZWZhY3RvciArPSAoU0NBTF9IRUFEUk9PTSsxKTsgLyogcHNEaWZmU2NhbGUhICovCgogICAgewogICAgICBDX0FBTExPQ19TQ1JBVENIX1NUQVJUKHBXb3JrQnVmZmVyLCBGSVhQX0RCTCwgMiooNjQpKTsKCiAgICAgIGludCBtYXhTaGlmdCA9IDA7CgogICAgICBpZiAoaFNickRlYy0+c2JyRHJjQ2hhbm5lbC5lbmFibGUgIT0gMCkgewogICAgICAgIGlmIChoU2JyRGVjLT5zYnJEcmNDaGFubmVsLnByZXZGYWN0X2V4cCA+IG1heFNoaWZ0KSB7CiAgICAgICAgICBtYXhTaGlmdCA9IGhTYnJEZWMtPnNickRyY0NoYW5uZWwucHJldkZhY3RfZXhwOwogICAgICAgIH0KICAgICAgICBpZiAoaFNickRlYy0+c2JyRHJjQ2hhbm5lbC5jdXJyRmFjdF9leHAgPiBtYXhTaGlmdCkgewogICAgICAgICAgbWF4U2hpZnQgPSBoU2JyRGVjLT5zYnJEcmNDaGFubmVsLmN1cnJGYWN0X2V4cDsKICAgICAgICB9CiAgICAgICAgaWYgKGhTYnJEZWMtPnNickRyY0NoYW5uZWwubmV4dEZhY3RfZXhwID4gbWF4U2hpZnQpIHsKICAgICAgICAgIG1heFNoaWZ0ID0gaFNickRlYy0+c2JyRHJjQ2hhbm5lbC5uZXh0RmFjdF9leHA7CiAgICAgICAgfQogICAgICB9CgogICAgICAvKiBjb3B5IERSQyBkYXRhIHRvIHJpZ2h0IGNoYW5uZWwgKHdpdGggUFMgYm90aCBjaGFubmVscyB1c2UgdGhlIHNhbWUgRFJDIGdhaW5zKSAqLwogICAgICBGREttZW1jcHkoJmhTYnJEZWNSaWdodC0+c2JyRHJjQ2hhbm5lbCwgJmhTYnJEZWMtPnNickRyY0NoYW5uZWwsIHNpemVvZihTQlJERUNfRFJDX0NIQU5ORUwpKTsKCiAgICAgIGZvciAoaSA9IDA7IGkgPCBzeW5RbWYtPm5vX2NvbDsgaSsrKSB7ICAvKiAtLS0tLSBub19jb2wgbG9vcCAtLS0tLSAqLwoKICAgICAgICBJTlQgb3V0U2NhbGVmYWN0b3JSLCBvdXRTY2FsZWZhY3Rvckw7CiAgICAgICAgb3V0U2NhbGVmYWN0b3JSID0gb3V0U2NhbGVmYWN0b3JMID0gb3V0U2NhbGVmYWN0b3I7CgogICAgICAgIC8qIHFtZiB0aW1lc2xvdCBvZiByaWdodCBjaGFubmVsICovCiAgICAgICAgRklYUF9EQkwqIHJRbWZSZWFsID0gcFdvcmtCdWZmZXI7CiAgICAgICAgRklYUF9EQkwqIHJRbWZJbWFnID0gcFdvcmtCdWZmZXIgKyA2NDsKCgogICAgICAgIHsKICAgICAgICAgIGlmICggaSA9PSBoX3BzX2QtPmJzRGF0YVtoX3BzX2QtPnByb2Nlc3NTbG90XS5tcGVnLmFFbnZTdGFydFN0b3BbZW52XSApIHsKICAgICAgICAgICAgaW5pdFNsb3RCYXNlZFJvdGF0aW9uKCBoX3BzX2QsIGVudiwgaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5oaWdoU3ViYmFuZCApOwogICAgICAgICAgICBlbnYrKzsKICAgICAgICAgIH0KCiAgICAgICAgICBBcHBseVBzU2xvdCggaF9wc19kLCAgICAgICAgICAgICAgICAgICAvKiBwYXJhbWV0cmljIHN0ZXJlbyBkZWNvZGVyIGhhbmRsZSAgKi8KICAgICAgICAgICAgICAgICAgICAgIChRbWZCdWZmZXJSZWFsICsgaSksICAgICAgIC8qIG9uZSB0aW1lc2xvdCBvZiBsZWZ0L21vbm8gY2hhbm5lbCAqLwogICAgICAgICAgICAgICAgICAgICAgKFFtZkJ1ZmZlckltYWcgKyBpKSwgICAgICAgLyogb25lIHRpbWVzbG90IG9mIGxlZnQvbW9ubyBjaGFubmVsICovCiAgICAgICAgICAgICAgICAgICAgICAgclFtZlJlYWwsICAgICAgICAgICAgICAgICAvKiBvbmUgdGltZXNsb3Qgb3IgcmlnaHQgY2hhbm5lbCAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICByUW1mSW1hZyk7ICAgICAgICAgICAgICAgIC8qIG9uZSB0aW1lc2xvdCBvciByaWdodCBjaGFubmVsICAgICAqLwogICAgICAgIH0KCgogICAgICAgIHNjYWxlRmFjdG9yTG93QmFuZCA9IChpPCg2KSkgPyBzY2FsZUZhY3Rvckxvd0JhbmRfb3YgOiBzY2FsZUZhY3Rvckxvd0JhbmRfbm9fb3Y7CgoKICAgICAgICBzYnJEZWNvZGVyX2RyY0FwcGx5U2xvdCAoIC8qIHJpZ2h0IGNoYW5uZWwgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmhTYnJEZWNSaWdodC0+c2JyRHJjQ2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJRbWZSZWFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgclFtZkltYWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3luUW1mUmlnaHQtPm5vX2NvbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heFNoaWZ0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgb3V0U2NhbGVmYWN0b3JSICs9IG1heFNoaWZ0OwoKICAgICAgICBzYnJEZWNvZGVyX2RyY0FwcGx5U2xvdCAoIC8qIGxlZnQgY2hhbm5lbCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaFNickRlYy0+c2JyRHJjQ2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKihRbWZCdWZmZXJSZWFsICsgaSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICooUW1mQnVmZmVySW1hZyArIGkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5blFtZi0+bm9fY29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4U2hpZnQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICBvdXRTY2FsZWZhY3RvckwgKz0gbWF4U2hpZnQ7CgoKICAgICAgICAvKiBzY2FsZSBmaWx0ZXIgc3RhdGVzIGZvciBsZWZ0IGFuZCByaWdodCBjaGFubmVsICovCiAgICAgICAgcW1mQ2hhbmdlT3V0U2NhbGVmYWN0b3IoIHN5blFtZiwgb3V0U2NhbGVmYWN0b3JMICk7CiAgICAgICAgcW1mQ2hhbmdlT3V0U2NhbGVmYWN0b3IoIHN5blFtZlJpZ2h0LCBvdXRTY2FsZWZhY3RvclIgKTsKCiAgICAgICAgewoKICAgICAgICAgIHFtZlN5bnRoZXNpc0ZpbHRlcmluZ1Nsb3QoIHN5blFtZlJpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgclFtZlJlYWwsICAgICAgICAgICAgICAgIC8qIFFNRiByZWFsIGJ1ZmZlciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgclFtZkltYWcsICAgICAgICAgICAgICAgIC8qIFFNRiBpbWFnIGJ1ZmZlciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVGYWN0b3JMb3dCYW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVGYWN0b3JIaWdoQmFuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVPdXRSaWdodCsoaSpzeW5RbWYtPm5vX2NoYW5uZWxzKnN0cmlkZU91dCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpZGVPdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwV29ya0J1ZmZlcik7CgogICAgICAgICAgcW1mU3ludGhlc2lzRmlsdGVyaW5nU2xvdCggc3luUW1mLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICooUW1mQnVmZmVyUmVhbCArIGkpLCAgICAgIC8qIFFNRiByZWFsIGJ1ZmZlciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICooUW1mQnVmZmVySW1hZyArIGkpLCAgICAgIC8qIFFNRiBpbWFnIGJ1ZmZlciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVGYWN0b3JMb3dCYW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVGYWN0b3JIaWdoQmFuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVPdXQrKGkqc3luUW1mLT5ub19jaGFubmVscypzdHJpZGVPdXQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaWRlT3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFdvcmtCdWZmZXIpOwoKICAgICAgICB9CiAgICAgIH0gLyogbm9fY29sIGxvb3AgIGkgICovCgogICAgICAvKiBzY2FsZSBiYWNrICg2KSB0aW1lc2xvdHMgbG9vayBhaGVhZCBmb3IgaHlicmlkIGZpbHRlcmJhbmsgdG8gb3JpZ2luYWwgdmFsdWUgKi8KICAgICAgcmVzY2FsRmlsdGVyQmFua1ZhbHVlcyggaF9wc19kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRbWZCdWZmZXJSZWFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRbWZCdWZmZXJJbWFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeW5RbWYtPmxzYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3luUW1mLT5ub19jb2wgKTsKCiAgICAgIENfQUFMTE9DX1NDUkFUQ0hfRU5EKHBXb3JrQnVmZmVyLCBGSVhQX0RCTCwgMiooNjQpKTsKICAgIH0KICB9CgogIHNickRlY29kZXJfZHJjVXBkYXRlQ2hhbm5lbCggJmhTYnJEZWMtPnNickRyY0NoYW5uZWwgKTsKCgogIC8qCiAgICBVcGRhdGUgb3ZlcmxhcCBidWZmZXIKICAgIEV2ZW4gYmFuZHMgYWJvdmUgdXNiIGFyZSBjb3BpZWQgdG8gYXZvaWQgb3V0ZGF0ZWQgc3BlY3RyYWwgZGF0YSBpbiBjYXNlCiAgICB0aGUgc3RvcCBmcmVxdWVuY3kgcmFpc2VzLgogICovCgogIGlmIChoU2JyRGVjLT5McHBUcmFucy5wU2V0dGluZ3MtPm92ZXJsYXAgPiAwKQogIHsKICAgIGlmICghIChmbGFncyAmIFNCUkRFQ19MT1dfUE9XRVIpKSB7CiAgICAgIGZvciAoIGk9MDsgaTxoU2JyRGVjLT5McHBUcmFucy5wU2V0dGluZ3MtPm92ZXJsYXA7IGkrKyApIHsKICAgICAgICBGREttZW1jcHkoUW1mQnVmZmVyUmVhbFtpXSwgUW1mQnVmZmVyUmVhbFtpK25vQ29sc10sICg2NCkqc2l6ZW9mKEZJWFBfREJMKSk7CiAgICAgICAgRkRLbWVtY3B5KFFtZkJ1ZmZlckltYWdbaV0sIFFtZkJ1ZmZlckltYWdbaStub0NvbHNdLCAoNjQpKnNpemVvZihGSVhQX0RCTCkpOwogICAgICB9CiAgICB9IGVsc2UKICAgICAgZm9yICggaT0wOyBpPGhTYnJEZWMtPkxwcFRyYW5zLnBTZXR0aW5ncy0+b3ZlcmxhcDsgaSsrICkgewogICAgICAgIEZES21lbWNweShRbWZCdWZmZXJSZWFsW2ldLCBRbWZCdWZmZXJSZWFsW2krbm9Db2xzXSwgKDY0KSpzaXplb2YoRklYUF9EQkwpKTsKICAgICAgfQogIH0KCiAgaFNickRlYy0+c2JyU2NhbGVGYWN0b3Iub3ZfbGJfc2NhbGUgPSBzYXZlTGJTY2FsZTsKCiAgLyogU2F2ZSBjdXJyZW50IGZyYW1lIHN0YXR1cyAqLwogIGhQcmV2RnJhbWVEYXRhLT5mcmFtZUVycm9yRmxhZyA9IGhIZWFkZXJEYXRhLT5mcmFtZUVycm9yRmxhZzsKCn0gLy8gc2JyX2RlYygpCgoKLyohCiAgXGJyaWVmICAgICBDcmVhdGVzIHNiciBkZWNvZGVyIHN0cnVjdHVyZQogIFxyZXR1cm4gICAgZXJyb3JDb2RlLCAwIGlmIHN1Y2Nlc3NmdWwKKi8KU0JSX0VSUk9SCmNyZWF0ZVNickRlYyAoU0JSX0NIQU5ORUwgKiBoU2JyQ2hhbm5lbCwKICAgICAgICAgICAgICBIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLCAvKiE8IFN0YXRpYyBjb250cm9sIGRhdGEgKi8KICAgICAgICAgICAgICBUUkFOU1BPU0VSX1NFVFRJTkdTICpwU2V0dGluZ3MsCiAgICAgICAgICAgICAgY29uc3QgaW50ICAgICBkb3duc2FtcGxlRmFjLCAgICAgICAgLyohPCBEb3duc2FtcGxpbmcgZmFjdG9yICovCiAgICAgICAgICAgICAgY29uc3QgVUlOVCAgICBxbWZGbGFncywgICAgICAgICAgICAgLyohPCBmbGFncyAtPiAxOiBIUS9MUCBzZWxlY3RvciwgMjogQ0xERkIgKi8KICAgICAgICAgICAgICBjb25zdCBVSU5UICAgIGZsYWdzLAogICAgICAgICAgICAgIGNvbnN0IGludCAgICAgb3ZlcmxhcCwgCiAgICAgICAgICAgICAgaW50ICAgICAgICAgICBjaGFuKSAgICAgICAgICAgICAgICAgLyohPCBDaGFubmVsIGZvciB3aGljaCB0byBhc3NpZ24gYnVmZmVycyBldGMuICovCgp7CiAgU0JSX0VSUk9SIGVyciA9IFNCUkRFQ19PSzsKICBpbnQgdGltZVNsb3RzID0gaEhlYWRlckRhdGEtPm51bWJlclRpbWVTbG90czsgICAvKiBOdW1iZXIgb2YgU0JSIHNsb3RzIHBlciBmcmFtZSAqLwogIGludCBub0NvbHMgPSB0aW1lU2xvdHMgKiBoSGVhZGVyRGF0YS0+dGltZVN0ZXA7IC8qIE51bWJlciBvZiBRTUYgc2xvdHMgcGVyIGZyYW1lICovCiAgSEFORExFX1NCUl9ERUMgaHMgPSAmKGhTYnJDaGFubmVsLT5TYnJEZWMpOwoKICAvKiBJbml0aWFsaXplIHNjYWxlIGZhY3RvcnMgKi8KICBocy0+c2JyU2NhbGVGYWN0b3Iub3ZfbGJfc2NhbGUgID0gMDsKICBocy0+c2JyU2NhbGVGYWN0b3Iub3ZfaGJfc2NhbGUgID0gMDsKICBocy0+c2JyU2NhbGVGYWN0b3IuaGJfc2NhbGUgICAgID0gMDsKCgogIC8qCiAgICBjcmVhdGUgZW52ZWxvcGUgY2FsY3VsYXRvcgogICovCiAgZXJyID0gY3JlYXRlU2JyRW52ZWxvcGVDYWxjICgmaHMtPlNickNhbGN1bGF0ZUVudmVsb3BlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEhlYWRlckRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxhZ3MpOwogIGlmIChlcnIgIT0gU0JSREVDX09LKSB7CiAgICByZXR1cm4gZXJyOwogIH0KCiAgLyoKICAgIGNyZWF0ZSBRTUYgZmlsdGVyIGJhbmtzCiAgKi8KICB7CiAgICBpbnQgcW1mRXJyOwogICAgLyogQWRhcHRlZCBRTUYgYW5hbHlzaXMgcG9zdC10d2lkZGxlcyBmb3IgZG93bi1zYW1wbGVkIEhRIFNCUiAqLwogICAgY29uc3QgVUlOVCBkb3duU2FtcGxlZEZsYWcgPSAoZmxhZ3MgJiBTQlJERUNfRE9XTlNBTVBMRSkgPyBRTUZfRkxBR19ET1dOU0FNUExFRCA6IDA7CgogICAgcW1mRXJyID0gcW1mSW5pdEFuYWx5c2lzRmlsdGVyQmFuayAoCiAgICAgICAgICAgICAgICAgICAgJmhzLT5BbmFseXNpc2NRTUYsCiAgICAgICAgICAgICAgICAgICAgIGhzLT5hbmFRbWZTdGF0ZXMsCiAgICAgICAgICAgICAgICAgICAgIG5vQ29scywKICAgICAgICAgICAgICAgICAgICAgaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5sb3dTdWJiYW5kLAogICAgICAgICAgICAgICAgICAgICBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLmhpZ2hTdWJiYW5kLAogICAgICAgICAgICAgICAgICAgICBoSGVhZGVyRGF0YS0+bnVtYmVyT2ZBbmFseXNpc0JhbmRzLAogICAgICAgICAgICAgICAgICAgICAocW1mRmxhZ3MgJiAoflFNRl9GTEFHX0tFRVBfU1RBVEVTKSkgfCBkb3duU2FtcGxlZEZsYWcKICAgICAgICAgICAgICAgICAgICAgKTsKICAgIGlmIChxbWZFcnIgIT0gMCkgewogICAgICByZXR1cm4gU0JSREVDX1VOU1VQUE9SVEVEX0NPTkZJRzsKICAgIH0KICB9CiAgaWYgKGhzLT5wU3luUW1mU3RhdGVzID09IE5VTEwpIHsKICAgIGhzLT5wU3luUW1mU3RhdGVzID0gR2V0UmFtX3Nicl9RbWZTdGF0ZXNTeW50aGVzaXMoY2hhbik7CiAgICBpZiAoaHMtPnBTeW5RbWZTdGF0ZXMgPT0gTlVMTCkKICAgICAgcmV0dXJuIFNCUkRFQ19NRU1fQUxMT0NfRkFJTEVEOwogIH0KCiAgewogICAgaW50IHFtZkVycjsKCiAgICBxbWZFcnIgPSBxbWZJbml0U3ludGhlc2lzRmlsdGVyQmFuayAoCiAgICAgICAgICAgJmhzLT5TeW50aGVzaXNRTUYsCiAgICAgICAgICAgIGhzLT5wU3luUW1mU3RhdGVzLAogICAgICAgICAgICBub0NvbHMsCiAgICAgICAgICAgIGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEubG93U3ViYmFuZCwKICAgICAgICAgICAgaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5oaWdoU3ViYmFuZCwKICAgICAgICAgICAgKDY0KSAvIGRvd25zYW1wbGVGYWMsCiAgICAgICAgICAgIHFtZkZsYWdzICYgKH5RTUZfRkxBR19LRUVQX1NUQVRFUykKICAgICAgICAgICAgKTsKCiAgICBpZiAocW1mRXJyICE9IDApIHsKICAgICAgcmV0dXJuIFNCUkRFQ19VTlNVUFBPUlRFRF9DT05GSUc7CiAgICB9CiAgfQogIGluaXRTYnJQcmV2RnJhbWVEYXRhICgmaFNickNoYW5uZWwtPnByZXZGcmFtZURhdGEsIHRpbWVTbG90cyk7CgogIC8qCiAgICBjcmVhdGUgdHJhbnNwb3NlcgogICovCiAgZXJyID0gY3JlYXRlTHBwVHJhbnNwb3NlciAoJmhzLT5McHBUcmFucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2V0dGluZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5sb3dTdWJiYW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEudl9rX21hc3RlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm51bU1hc3RlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBocy0+U3ludGhlc2lzUU1GLnVzYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lU2xvdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHMtPkFuYWx5c2lzY1FNRi5ub19jb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5mcmVxQmFuZFRhYmxlTm9pc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5uTmZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhIZWFkZXJEYXRhLT5zYnJQcm9jU21wbFJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdmVybGFwICk7CiAgaWYgKGVyciAhPSBTQlJERUNfT0spIHsKICAgIHJldHVybiBlcnI7CiAgfQoKICAvKiBUaGUgQ0xERkIgZG9lcyBub3QgaGF2ZSBvdmVybGFwICovCiAgaWYgKChxbWZGbGFncyAmIFFNRl9GTEFHX0NMREZCKSA9PSAwKSB7CiAgICBpZiAoaHMtPnBTYnJPdmVybGFwQnVmZmVyID09IE5VTEwpIHsKICAgICAgaHMtPnBTYnJPdmVybGFwQnVmZmVyID0gR2V0UmFtX3Nicl9PdmVybGFwQnVmZmVyKGNoYW4pOwogICAgICBpZiAoaHMtPnBTYnJPdmVybGFwQnVmZmVyID09IE5VTEwpICB7CiAgICAgICAgcmV0dXJuIFNCUkRFQ19NRU1fQUxMT0NfRkFJTEVEOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAvKiBDbGVhciBvdmVybGFwIGJ1ZmZlciAqLwogICAgICBGREttZW1jbGVhciggaHMtPnBTYnJPdmVybGFwQnVmZmVyLAogICAgICAgICAgICAgICAgICAgc2l6ZW9mKEZJWFBfREJMKSAqIDIgKiAoNikgKiAoNjQpCiAgICAgICAgICAgICAgICAgKTsKICAgIH0KICB9CgogIC8qIENsZWFyIGlucHV0IGRlbGF5IGxpbmUgKi8KICBGREttZW1jbGVhcihocy0+Y29yZURlbGF5QnVmLCAoOTYpKnNpemVvZihJTlRfUENNKSk7CgogIC8qIGFzc2lnbiBxbWYgdGltZSBzbG90cyAqLwogIGFzc2lnblRpbWVTbG90cyggJmhTYnJDaGFubmVsLT5TYnJEZWMsIGhIZWFkZXJEYXRhLT5udW1iZXJUaW1lU2xvdHMgKiBoSGVhZGVyRGF0YS0+dGltZVN0ZXAsIHFtZkZsYWdzICYgUU1GX0ZMQUdfTFApOwoKICByZXR1cm4gZXJyOwp9CgovKiEKICBcYnJpZWYgICAgIERlbGV0ZSBzYnIgZGVjb2RlciBzdHJ1Y3R1cmUKICBccmV0dXJuICAgIGVycm9yQ29kZSwgMCBpZiBzdWNjZXNzZnVsCiovCmludApkZWxldGVTYnJEZWMgKFNCUl9DSEFOTkVMICogaFNickNoYW5uZWwpCnsKICBIQU5ETEVfU0JSX0RFQyBocyA9ICZoU2JyQ2hhbm5lbC0+U2JyRGVjOwoKICBkZWxldGVTYnJFbnZlbG9wZUNhbGMgKCZocy0+U2JyQ2FsY3VsYXRlRW52ZWxvcGUpOwoKICAvKiBkZWxldGUgUU1GIGZpbHRlciBzdGF0ZXMgKi8KICBpZiAoaHMtPnBTeW5RbWZTdGF0ZXMgIT0gTlVMTCkgewogICAgRnJlZVJhbV9zYnJfUW1mU3RhdGVzU3ludGhlc2lzKCZocy0+cFN5blFtZlN0YXRlcyk7CiAgfQoKCiAgaWYgKGhzLT5wU2JyT3ZlcmxhcEJ1ZmZlciAhPSBOVUxMKSB7CiAgICBGcmVlUmFtX3Nicl9PdmVybGFwQnVmZmVyKCZocy0+cFNick92ZXJsYXBCdWZmZXIpOwogIH0KCiAgcmV0dXJuIDA7Cn0KCgovKiEKICBcYnJpZWYgICAgIHJlc2V0cyBzYnIgZGVjb2RlciBzdHJ1Y3R1cmUKICBccmV0dXJuICAgIGVycm9yQ29kZSwgMCBpZiBzdWNjZXNzZnVsCiovClNCUl9FUlJPUgpyZXNldFNickRlYyAoSEFORExFX1NCUl9ERUMgaFNickRlYywKICAgICAgICAgICAgIEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsCiAgICAgICAgICAgICBIQU5ETEVfU0JSX1BSRVZfRlJBTUVfREFUQSBoUHJldkZyYW1lRGF0YSwKICAgICAgICAgICAgIGNvbnN0IGludCB1c2VMUCwKICAgICAgICAgICAgIGNvbnN0IGludCBkb3duc2FtcGxlRmFjCiAgICAgICAgICAgICApCnsKICBTQlJfRVJST1Igc2JyRXJyb3IgPSBTQlJERUNfT0s7CiAgCiAgaW50IG9sZF9sc2IgPSBoU2JyRGVjLT5TeW50aGVzaXNRTUYubHNiOwogIGludCBuZXdfbHNiID0gaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5sb3dTdWJiYW5kOwogIGludCBsLCBzdGFydEJhbmQsIHN0b3BCYW5kLCBzdGFydFNsb3QsIHNpemU7CgogIGludCBzb3VyY2Vfc2NhbGUsIHRhcmdldF9zY2FsZSwgZGVsdGFfc2NhbGUsIHRhcmdldF9sc2IsIHRhcmdldF91c2IsIHJlc2VydmU7CiAgRklYUF9EQkwgbWF4VmFsOwoKICAvKiBvdmVybGFwQnVmZmVyIHBvaW50IHRvIGZpcnN0ICg2KSBzbG90cyAqLwogIEZJWFBfREJMICAqKk92ZXJsYXBCdWZmZXJSZWFsID0gaFNickRlYy0+UW1mQnVmZmVyUmVhbDsKICBGSVhQX0RCTCAgKipPdmVybGFwQnVmZmVySW1hZyA9IGhTYnJEZWMtPlFtZkJ1ZmZlckltYWc7CgogIC8qIGFzc2lnbiBxbWYgdGltZSBzbG90cyAqLwogIGFzc2lnblRpbWVTbG90cyggaFNickRlYywgaEhlYWRlckRhdGEtPm51bWJlclRpbWVTbG90cyAqIGhIZWFkZXJEYXRhLT50aW1lU3RlcCwgdXNlTFApOwoKCgogIHJlc2V0U2JyRW52ZWxvcGVDYWxjICgmaFNickRlYy0+U2JyQ2FsY3VsYXRlRW52ZWxvcGUpOwoKICBoU2JyRGVjLT5TeW50aGVzaXNRTUYubHNiID0gaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5sb3dTdWJiYW5kOwogIGhTYnJEZWMtPlN5bnRoZXNpc1FNRi51c2IgPSBmaXhNaW4oKElOVCloU2JyRGVjLT5TeW50aGVzaXNRTUYubm9fY2hhbm5lbHMsIChJTlQpaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5oaWdoU3ViYmFuZCk7CgogIGhTYnJEZWMtPkFuYWx5c2lzY1FNRi5sc2IgPSBoU2JyRGVjLT5TeW50aGVzaXNRTUYubHNiOwogIGhTYnJEZWMtPkFuYWx5c2lzY1FNRi51c2IgPSBoU2JyRGVjLT5TeW50aGVzaXNRTUYudXNiOwoKCiAgLyoKICAgIFRoZSBmb2xsb3dpbmcgaW5pdGlhbGl6YXRpb24gb2Ygc3BlY3RyYWwgZGF0YSBpbiB0aGUgb3ZlcmxhcCBidWZmZXIKICAgIGlzIHJlcXVpcmVkIGZvciBkeW5hbWljIHgtb3ZlciBvciBhIGNoYW5nZSBvZiB0aGUgc3RhcnQtZnJlcSBmb3IgMiByZWFzb25zOgoKICAgIDEuIElmIHRoZSBsb3diYW5kIGdldHMgX3dpZGVyXywgdW5hZGp1c3RlZCBkYXRhIHdvdWxkIHJlbWFpbgoKICAgIDIuIElmIHRoZSBsb3diYW5kIGJlY29tZXMgX3NtYWxsZXJfLCB0aGUgaGlnaGVzdCBiYW5kcyBvZiB0aGUgb2xkIGxvd2JhbmQKICAgICAgIG11c3QgYmUgY2xlYXJlZCBiZWNhdXNlIHRoZSB3aGl0ZW5pbmcgd291bGQgYmUgYWZmZWN0ZWQKICAqLwogIHN0YXJ0QmFuZCA9IG9sZF9sc2I7CiAgc3RvcEJhbmQgID0gbmV3X2xzYjsKICBzdGFydFNsb3QgPSBoSGVhZGVyRGF0YS0+dGltZVN0ZXAgKiAoaFByZXZGcmFtZURhdGEtPnN0b3BQb3MgLSBoSGVhZGVyRGF0YS0+bnVtYmVyVGltZVNsb3RzKTsKICBzaXplICAgICAgPSBmaXhNYXgoMCxzdG9wQmFuZC1zdGFydEJhbmQpOwoKICAvKiBrZWVwIGFscmVhZHkgYWRqdXN0ZWQgZGF0YSBpbiB0aGUgeC1vdmVyLWFyZWEgKi8KICBpZiAoIXVzZUxQKSB7CiAgICBmb3IgKGw9c3RhcnRTbG90OyBsPGhTYnJEZWMtPkxwcFRyYW5zLnBTZXR0aW5ncy0+b3ZlcmxhcDsgbCsrKSB7CiAgICAgIEZES21lbWNsZWFyKCZPdmVybGFwQnVmZmVyUmVhbFtsXVtzdGFydEJhbmRdLCBzaXplKnNpemVvZihGSVhQX0RCTCkpOwogICAgICBGREttZW1jbGVhcigmT3ZlcmxhcEJ1ZmZlckltYWdbbF1bc3RhcnRCYW5kXSwgc2l6ZSpzaXplb2YoRklYUF9EQkwpKTsKICAgIH0KICB9IGVsc2UKICBmb3IgKGw9c3RhcnRTbG90OyBsPGhTYnJEZWMtPkxwcFRyYW5zLnBTZXR0aW5ncy0+b3ZlcmxhcCA7IGwrKykgewogICAgRkRLbWVtY2xlYXIoJk92ZXJsYXBCdWZmZXJSZWFsW2xdW3N0YXJ0QmFuZF0sIHNpemUqc2l6ZW9mKEZJWFBfREJMKSk7CiAgfQoKCiAgLyoKICAgIHJlc2V0IExQQyBmaWx0ZXIgc3RhdGVzCiAgKi8KICBzdGFydEJhbmQgPSBmaXhNaW4ob2xkX2xzYixuZXdfbHNiKTsKICBzdG9wQmFuZCAgPSBmaXhNYXgob2xkX2xzYixuZXdfbHNiKTsKICBzaXplICAgICAgPSBmaXhNYXgoMCxzdG9wQmFuZC1zdGFydEJhbmQpOwoKICBGREttZW1jbGVhcigmaFNickRlYy0+THBwVHJhbnMubHBjRmlsdGVyU3RhdGVzUmVhbFswXVtzdGFydEJhbmRdLCBzaXplKnNpemVvZihGSVhQX0RCTCkpOwogIEZES21lbWNsZWFyKCZoU2JyRGVjLT5McHBUcmFucy5scGNGaWx0ZXJTdGF0ZXNSZWFsWzFdW3N0YXJ0QmFuZF0sIHNpemUqc2l6ZW9mKEZJWFBfREJMKSk7CiAgaWYgKCF1c2VMUCkgewogICAgRkRLbWVtY2xlYXIoJmhTYnJEZWMtPkxwcFRyYW5zLmxwY0ZpbHRlclN0YXRlc0ltYWdbMF1bc3RhcnRCYW5kXSwgc2l6ZSpzaXplb2YoRklYUF9EQkwpKTsKICAgIEZES21lbWNsZWFyKCZoU2JyRGVjLT5McHBUcmFucy5scGNGaWx0ZXJTdGF0ZXNJbWFnWzFdW3N0YXJ0QmFuZF0sIHNpemUqc2l6ZW9mKEZJWFBfREJMKSk7CiAgfQoKCiAgLyoKICAgIFJlc2NhbGUgYWxyZWFkeSBwcm9jZXNzZWQgc3BlY3RyYWwgZGF0YSBiZXR3ZWVuIG9sZCBhbmQgbmV3IHgtb3ZlciBmcmVxdWVuY3kuCiAgICBUaGlzIG11c3QgYmUgZG9uZSBiZWNhdXNlIG9mIHRoZSBzZXBhcmF0ZSBzY2FsZWZhY3RvcnMgZm9yIGxvd2JhbmQgYW5kIGhpZ2hiYW5kLgogICovCiAgc3RhcnRCYW5kID0gZml4TWluKG9sZF9sc2IsbmV3X2xzYik7CiAgc3RvcEJhbmQgPSAgZml4TWF4KG9sZF9sc2IsbmV3X2xzYik7CgogIGlmIChuZXdfbHNiID4gb2xkX2xzYikgewogICAgLyogVGhlIHgtb3Zlci1hcmVhIHdhcyBwYXJ0IG9mIHRoZSBoaWdoYmFuZCBiZWZvcmUgYW5kIHdpbGwgbm93IGJlbG9uZyB0byB0aGUgbG93YmFuZCAqLwogICAgc291cmNlX3NjYWxlID0gaFNickRlYy0+c2JyU2NhbGVGYWN0b3Iub3ZfaGJfc2NhbGU7CiAgICB0YXJnZXRfc2NhbGUgPSBoU2JyRGVjLT5zYnJTY2FsZUZhY3Rvci5vdl9sYl9zY2FsZTsKICAgIHRhcmdldF9sc2IgICA9IDA7CiAgICB0YXJnZXRfdXNiICAgPSBvbGRfbHNiOwogIH0KICBlbHNlIHsKICAgIC8qIFRoZSB4LW92ZXItYXJlYSB3YXMgcGFydCBvZiB0aGUgbG93YmFuZCBiZWZvcmUgYW5kIHdpbGwgbm93IGJlbG9uZyB0byB0aGUgaGlnaGJhbmQgKi8KICAgIHNvdXJjZV9zY2FsZSA9IGhTYnJEZWMtPnNiclNjYWxlRmFjdG9yLm92X2xiX3NjYWxlOwogICAgdGFyZ2V0X3NjYWxlID0gaFNickRlYy0+c2JyU2NhbGVGYWN0b3Iub3ZfaGJfc2NhbGU7CiAgICAvKiBqZHI6IFRoZSB2YWx1ZXMgb2xkX2xzYiBhbmQgb2xkX3VzYiBtaWdodCBiZSB3cm9uZyBiZWNhdXNlIHRoZSBwcmV2aW91cyBmcmFtZSBtaWdodCBoYXZlIGJlZW4gInVwc2FtbGluZyIuICovCiAgICB0YXJnZXRfbHNiICAgPSBoU2JyRGVjLT5TeW50aGVzaXNRTUYubHNiOwogICAgdGFyZ2V0X3VzYiAgID0gaFNickRlYy0+U3ludGhlc2lzUU1GLnVzYjsKICB9CgogIC8qIFNoaWZ0IGxlZnQgYWxsIHNhbXBsZXMgb2YgdGhlIHgtb3Zlci1hcmVhIGFzIG11Y2ggYXMgcG9zc2libGUKICAgICBBbiB1bm5lY2Vzc2FyeSBjb2Fyc2Ugc2NhbGUgY291bGQgY2F1c2Ugb3ZfbGJfc2NhbGUgb3Igb3ZfaGJfc2NhbGUgdG8gYmUKICAgICBhZGFwdGVkIGFuZCB0aGUgYWNjdXJhY3kgaW4gdGhlIG5leHQgZnJhbWUgd291bGQgc2VyaW91c2x5IHN1ZmZlciEgKi8KCiAgbWF4VmFsID0gbWF4U3ViYmFuZFNhbXBsZSggT3ZlcmxhcEJ1ZmZlclJlYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVzZUxQKSA/IE5VTEwgOiBPdmVybGFwQnVmZmVySW1hZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydEJhbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcEJhbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydFNsb3QpOwoKICByZXNlcnZlID0gQ250TGVhZGluZ1plcm9zKG1heFZhbCktMTsKICByZXNlcnZlID0gZml4TWluKHJlc2VydmUsREZSQUNUX0JJVFMtMS1zb3VyY2Vfc2NhbGUpOwoKICByZXNjYWxlU3ViYmFuZFNhbXBsZXMoIE92ZXJsYXBCdWZmZXJSZWFsLAogICAgICAgICAgICAgICAgICAgICAgICAgKHVzZUxQKSA/IE5VTEwgOiBPdmVybGFwQnVmZmVySW1hZywKICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0QmFuZCwKICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3BCYW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0U2xvdCwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2VydmUpOwogIHNvdXJjZV9zY2FsZSArPSByZXNlcnZlOwoKICBkZWx0YV9zY2FsZSA9IHRhcmdldF9zY2FsZSAtIHNvdXJjZV9zY2FsZTsKCiAgaWYgKGRlbHRhX3NjYWxlID4gMCkgeyAvKiB4LW92ZXItYXJlYSBpcyBkb21pbmFudCAqLwogICAgZGVsdGFfc2NhbGUgPSAtZGVsdGFfc2NhbGU7CiAgICBzdGFydEJhbmQgPSB0YXJnZXRfbHNiOwogICAgc3RvcEJhbmQgPSB0YXJnZXRfdXNiOwoKICAgIGlmIChuZXdfbHNiID4gb2xkX2xzYikgewogICAgICAvKiBUaGUgbG93YmFuZCBoYXMgdG8gYmUgcmVzY2FsZWQgKi8KICAgICAgaFNickRlYy0+c2JyU2NhbGVGYWN0b3Iub3ZfbGJfc2NhbGUgPSBzb3VyY2Vfc2NhbGU7CiAgICB9CiAgICBlbHNlIHsKICAgICAgLyogVGhlIGhpZ2hiYW5kIGhhcyBiZSBiZSByZXNjYWxlZCAqLwogICAgICBoU2JyRGVjLT5zYnJTY2FsZUZhY3Rvci5vdl9oYl9zY2FsZSA9IHNvdXJjZV9zY2FsZTsKICAgIH0KICB9CgogIEZES19BU1NFUlQoc3RhcnRCYW5kIDw9IHN0b3BCYW5kKTsKCiAgaWYgKCF1c2VMUCkgewogICAgZm9yIChsPTA7IGw8c3RhcnRTbG90OyBsKyspIHsKICAgICAgc2NhbGVWYWx1ZXMoIE92ZXJsYXBCdWZmZXJSZWFsW2xdICsgc3RhcnRCYW5kLCBzdG9wQmFuZC1zdGFydEJhbmQsIGRlbHRhX3NjYWxlICk7CiAgICAgIHNjYWxlVmFsdWVzKCBPdmVybGFwQnVmZmVySW1hZ1tsXSArIHN0YXJ0QmFuZCwgc3RvcEJhbmQtc3RhcnRCYW5kLCBkZWx0YV9zY2FsZSApOwogICAgfQogIH0gZWxzZQogIGZvciAobD0wOyBsPHN0YXJ0U2xvdDsgbCsrKSB7CiAgICBzY2FsZVZhbHVlcyggT3ZlcmxhcEJ1ZmZlclJlYWxbbF0gKyBzdGFydEJhbmQsIHN0b3BCYW5kLXN0YXJ0QmFuZCwgZGVsdGFfc2NhbGUgKTsKICB9CgoKICAvKgogICAgSW5pdGlhbGl6ZSB0cmFuc3Bvc2VyIGFuZCBsaW1pdGVyCiAgKi8KICBzYnJFcnJvciA9IHJlc2V0THBwVHJhbnNwb3NlciAoJmhTYnJEZWMtPkxwcFRyYW5zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLmxvd1N1YmJhbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEudl9rX21hc3RlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5udW1NYXN0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEuZnJlcUJhbmRUYWJsZU5vaXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5OZmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEuaGlnaFN1YmJhbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhIZWFkZXJEYXRhLT5zYnJQcm9jU21wbFJhdGUpOwogIGlmIChzYnJFcnJvciAhPSBTQlJERUNfT0spCiAgICByZXR1cm4gc2JyRXJyb3I7CgogIHNickVycm9yID0gUmVzZXRMaW1pdGVyQmFuZHMgKCBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLmxpbWl0ZXJCYW5kVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5vTGltaXRlckJhbmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLmZyZXFCYW5kVGFibGVbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEublNmYlswXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaFNickRlYy0+THBwVHJhbnMucFNldHRpbmdzLT5wYXRjaFBhcmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoU2JyRGVjLT5McHBUcmFucy5wU2V0dGluZ3MtPm5vT2ZQYXRjaGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoSGVhZGVyRGF0YS0+YnNfZGF0YS5saW1pdGVyQmFuZHMpOwoKCiAgcmV0dXJuIHNickVycm9yOwp9Cg==