Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiEKICBcZmlsZQogIFxicmllZiAgZW52ZWxvcGUgZGVjb2RpbmcgIAogIFRoaXMgbW9kdWxlIHByb3ZpZGVzIGVudmVsb3BlIGRlY29kaW5nIGFuZCBlcnJvciBjb25jZWFsbWVudCBhbGdvcml0aG1zLiBUaGUgbWFpbgogIGVudHJ5IHBvaW50IGlzIGRlY29kZVNickRhdGEoKS4KCiAgXHNhIGRlY29kZVNickRhdGEoKSxccmVmIGRvY3VtZW50YXRpb25PdmVydmlldwoqLwoKI2luY2x1ZGUgImVudl9kZWMuaCIKCiNpbmNsdWRlICJlbnZfZXh0ci5oIgojaW5jbHVkZSAidHJhbnNjZW5kZW50LmgiCgojaW5jbHVkZSAiZ2VuZXJpY1N0ZHMuaCIKCgpzdGF0aWMgdm9pZCBkZWNvZGVFbnZlbG9wZSAoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSBoX3Nicl9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgaF9wcmV2X2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX1BSRVZfRlJBTUVfREFUQSBoX3ByZXZfZGF0YV9vdGhlckNoYW5uZWwpOwpzdGF0aWMgdm9pZCBzYnJfZW52ZWxvcGVfdW5tYXBwaW5nIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9kYXRhX2xlZnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSBoX2RhdGFfcmlnaHQpOwpzdGF0aWMgdm9pZCByZXF1YW50aXplRW52ZWxvcGVEYXRhIChIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9zYnJfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGFtcFJlc29sdXRpb24pOwpzdGF0aWMgdm9pZCBkZWx0YVRvTGluZWFyUGNtRW52ZWxvcGVEZWNvZGluZyAoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSBoX3Nicl9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgaF9wcmV2X2RhdGEpOwpzdGF0aWMgdm9pZCBkZWNvZGVOb2lzZUZsb29ybGV2ZWxzIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9zYnJfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgaF9wcmV2X2RhdGEpOwpzdGF0aWMgdm9pZCB0aW1lQ29tcGVuc2F0ZUZpcnN0RW52ZWxvcGUgKEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBIGhfc2JyX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgaF9wcmV2X2RhdGEpOwpzdGF0aWMgaW50IGNoZWNrRW52ZWxvcGVEYXRhIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9zYnJfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgaF9wcmV2X2RhdGEpOwoKCgojZGVmaW5lIFNCUl9FTkVSR1lfUEFOX09GRlNFVCAgICgxMiA8PCBFTlZfRVhQX0ZSQUNUKQojZGVmaW5lIFNCUl9NQVhfRU5FUkdZICAgICAgICAgICgzNSA8PCBFTlZfRVhQX0ZSQUNUKQoKI2RlZmluZSBERUNBWSAgICAgICAgICAgICAgICAgICAoIDEgPDwgRU5WX0VYUF9GUkFDVCkKCiNpZiBFTlZfRVhQX0ZSQUNUCiNkZWZpbmUgREVDQVlfQ09VUExJTkcgICAgICAgICAgKCAxIDw8IChFTlZfRVhQX0ZSQUNULTEpICkgLyohPCBjb3JyZXNwb25kcyB0byBhIHZhbHVlIG9mIDAuNSAqLwojZWxzZQojZGVmaW5lIERFQ0FZX0NPVVBMSU5HICAgICAgICAgICAgMSAgLyohPCBJZiB0aGUgZW5lcmd5IGRhdGEgaXMgbm90IHNoaWZ0ZWQsIHVzZSAxIGluc3RlYWQgb2YgMC41ICovCiNlbmRpZgoKCi8qIQogIFxicmllZiAgQ29udmVydCB0YWJsZSBpbmRleAoqLwpzdGF0aWMgaW50IGluZGV4TG93MkhpZ2goaW50IG9mZnNldCwgLyohPCBtYXBwaW5nIGZhY3RvciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4LCAgLyohPCBpbmRleCB0byBzY2FsZWZhY3RvciBiYW5kICovCiAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcmVzKSAgICAvKiE8IGZyZXF1ZW5jeSByZXNvbHV0aW9uICovCnsKICBpZihyZXMgPT0gMCkKICB7CiAgICBpZiAob2Zmc2V0ID49IDApCiAgICB7CiAgICAgICAgaWYgKGluZGV4IDwgb2Zmc2V0KQogICAgICAgICAgcmV0dXJuKGluZGV4KTsKICAgICAgICBlbHNlCiAgICAgICAgICByZXR1cm4oMippbmRleCAtIG9mZnNldCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgb2Zmc2V0ID0gLW9mZnNldDsKICAgICAgICBpZiAoaW5kZXggPCBvZmZzZXQpCiAgICAgICAgICByZXR1cm4oMippbmRleCtpbmRleCk7CiAgICAgICAgZWxzZQogICAgICAgICAgcmV0dXJuKDIqaW5kZXggKyBvZmZzZXQpOwogICAgfQogIH0KICBlbHNlCiAgICByZXR1cm4oaW5kZXgpOwp9CgoKLyohCiAgXGJyaWVmICBVcGRhdGUgcHJldmlvdXMgZW52ZWxvcGUgdmFsdWUgZm9yIGRlbHRhLWNvZGluZwoKICBUaGUgY3VycmVudCBlbnZlbG9wZSB2YWx1ZXMgbmVlZHMgdG8gYmUgc3RvcmVkIGZvciBkZWx0YS1jb2RpbmcKICBpbiB0aGUgbmV4dCBmcmFtZS4gIFRoZSBzdG9yZWQgZW52ZWxvcGUgaXMgYWx3YXlzIHJlcHJlc2VudGVkIHdpdGgKICB0aGUgaGlnaCBmcmVxdWVuY3kgcmVzb2x1dGlvbi4gIElmIHRoZSBjdXJyZW50IGVudmVsb3BlIHVzZXMgdGhlCiAgbG93IGZyZXF1ZW5jeSByZXNvbHV0aW9uLCB0aGUgZW5lcmd5IHZhbHVlIHdpbGwgYmUgbWFwcGVkIHRvIHRoZQogIGNvcnJlc3BvbmRpbmcgaGlnaC1yZXMgYmFuZHMuCiovCnN0YXRpYyB2b2lkIG1hcExvd1Jlc0VuZXJneVZhbChGSVhQX1NHTCBjdXJyVmFsLCAgLyohPCBjdXJyZW50IGVuZXJneSB2YWx1ZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9TR0wqIHByZXZEYXRhLC8qITwgcG9pbnRlciB0byBwcmV2aW91cyBkYXRhIHZlY3RvciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldCwgICAgICAvKiE8IG1hcHBpbmcgZmFjdG9yICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgsICAgICAgIC8qITwgaW5kZXggdG8gc2NhbGVmYWN0b3IgYmFuZCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHJlcykgICAgICAgICAvKiE8IGZyZXF1ZW55IHJlc29sdXRpb24gKi8KewogIGlmKHJlcyA9PSAwKQogIHsKICAgIGlmIChvZmZzZXQgPj0gMCkKICAgIHsKICAgICAgICBpZihpbmRleCA8IG9mZnNldCkKICAgICAgICAgICAgcHJldkRhdGFbaW5kZXhdID0gY3VyclZhbDsKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBwcmV2RGF0YVsyKmluZGV4IC0gb2Zmc2V0XSA9IGN1cnJWYWw7CiAgICAgICAgICAgIHByZXZEYXRhWzIqaW5kZXgrMSAtIG9mZnNldF0gPSBjdXJyVmFsOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBvZmZzZXQgPSAtb2Zmc2V0OwogICAgICAgIGlmIChpbmRleCA8IG9mZnNldCkKICAgICAgICB7CiAgICAgICAgICAgIHByZXZEYXRhWzMqaW5kZXhdID0gY3VyclZhbDsKICAgICAgICAgICAgcHJldkRhdGFbMyppbmRleCsxXSA9IGN1cnJWYWw7CiAgICAgICAgICAgIHByZXZEYXRhWzMqaW5kZXgrMl0gPSBjdXJyVmFsOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBwcmV2RGF0YVsyKmluZGV4ICsgb2Zmc2V0XSA9IGN1cnJWYWw7CiAgICAgICAgICAgIHByZXZEYXRhWzIqaW5kZXggKyAxICsgb2Zmc2V0XSA9IGN1cnJWYWw7CiAgICAgICAgfQogICAgfQogIH0KICBlbHNlCiAgICBwcmV2RGF0YVtpbmRleF0gPSBjdXJyVmFsOwp9CgoKCi8qIQogIFxicmllZiAgICBDb252ZXJ0IHJhdyBlbnZlbG9wZSBhbmQgbm9pc2VmbG9vciBkYXRhIHRvIGVuZXJneSBsZXZlbHMKCiAgVGhpcyBmdW5jdGlvbiBpcyBiZWluZyBjYWxsZWQgYnkgc2JyRGVjb2Rlcl9QYXJzZUVsZW1lbnQoKSBhbmQgcHJvdmlkZXMgdHdvIGltcG9ydGFudCBhbGdvcml0aG1zOgoKICBGaXJzdCB0aGUgZnVuY3Rpb24gZGVjb2RlcyBlbnZlbG9wZXMgYW5kIG5vaXNlIGZsb29yIGxldmVscyBhcyBkZXNjcmliZWQgaW4gcmVxdWFudGl6ZUVudmVsb3BlRGF0YSgpCiAgYW5kIHNicl9lbnZlbG9wZV91bm1hcHBpbmcoKS4gVGhlIGZ1bmN0aW9uIGFsc28gaW1wbGVtZW50cyBjb25jZWFsbWVudCBhbGdvcml0aG1zIGluIGNhc2UgdGhlcmUgYXJlIGVycm9ycwogIHdpdGhpbiB0aGUgc2JyIGRhdGEuIEZvciBib3RoIG9wZXJhdGlvbnMgZnJhY3Rpb25hbCBhcml0aG1ldGljIGlzIHVzZWQuCiAgVGhlcmVmb3JlIHlvdSBtaWdodCBlbmNvdW50ZXIgZGlmZmVyZW50IG91dHB1dCB2YWx1ZXMgb24geW91ciB0YXJnZXQKICBzeXN0ZW0gY29tcGFyZWQgdG8gdGhlIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbi4KKi8Kdm9pZApkZWNvZGVTYnJEYXRhIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLCAgICAgICAgICAvKiE8IFN0YXRpYyBjb250cm9sIGRhdGEgKi8KICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBIGhfZGF0YV9sZWZ0LCAgICAgICAgICAgLyohPCBwb2ludGVyIHRvIGxlZnQgY2hhbm5lbCBmcmFtZSBkYXRhICovCiAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfUFJFVl9GUkFNRV9EQVRBIGhfcHJldl9kYXRhX2xlZnQsIC8qITwgcG9pbnRlciB0byBsZWZ0IGNoYW5uZWwgcHJldmlvdXMgZnJhbWUgZGF0YSAqLwogICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9kYXRhX3JpZ2h0LCAgICAgICAgICAvKiE8IHBvaW50ZXIgdG8gcmlnaHQgY2hhbm5lbCBmcmFtZSBkYXRhICovCiAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfUFJFVl9GUkFNRV9EQVRBIGhfcHJldl9kYXRhX3JpZ2h0KS8qITwgcG9pbnRlciB0byByaWdodCBjaGFubmVsIHByZXZpb3VzIGZyYW1lIGRhdGEgKi8KewogIEZJWFBfU0dMIHRlbXBTZmJOcmdQcmV2W01BWF9GUkVRX0NPRUZGU107CiAgaW50IGVyckxlZnQ7CgogIC8qIFNhdmUgcHJldmlvdXMgZW5lcmd5IHZhbHVlcyB0byBiZSBhYmxlIHRvIHJldXNlIHRoZW0gbGF0ZXIgZm9yIGNvbmNlYWxtZW50LiAqLwogIEZES21lbWNweSAodGVtcFNmYk5yZ1ByZXYsIGhfcHJldl9kYXRhX2xlZnQtPnNmYl9ucmdfcHJldiwgTUFYX0ZSRVFfQ09FRkZTICogc2l6ZW9mKEZJWFBfU0dMKSk7CgogIGRlY29kZUVudmVsb3BlIChoSGVhZGVyRGF0YSwgaF9kYXRhX2xlZnQsIGhfcHJldl9kYXRhX2xlZnQsIGhfcHJldl9kYXRhX3JpZ2h0KTsKICBkZWNvZGVOb2lzZUZsb29ybGV2ZWxzIChoSGVhZGVyRGF0YSwgaF9kYXRhX2xlZnQsIGhfcHJldl9kYXRhX2xlZnQpOwoKICBpZihoX2RhdGFfcmlnaHQgIT0gTlVMTCkgewogICAgZXJyTGVmdCA9IGhIZWFkZXJEYXRhLT5mcmFtZUVycm9yRmxhZzsKICAgIGRlY29kZUVudmVsb3BlIChoSGVhZGVyRGF0YSwgaF9kYXRhX3JpZ2h0LCBoX3ByZXZfZGF0YV9yaWdodCwgaF9wcmV2X2RhdGFfbGVmdCk7CiAgICBkZWNvZGVOb2lzZUZsb29ybGV2ZWxzIChoSGVhZGVyRGF0YSwgaF9kYXRhX3JpZ2h0LCBoX3ByZXZfZGF0YV9yaWdodCk7CgogICAgaWYgKCFlcnJMZWZ0ICYmIGhIZWFkZXJEYXRhLT5mcmFtZUVycm9yRmxhZykgewogICAgICAvKiBJZiBhbiBlcnJvciBvY2N1cnMgaW4gdGhlIHJpZ2h0IGNoYW5uZWwgd2hlcmUgdGhlIGxlZnQgY2hhbm5lbCBzZWVtZWQgb2ssCiAgICAgICAgIHdlIGFwcGx5IGNvbmNlYWxtZW50IGFsc28gb24gdGhlIGxlZnQgY2hhbm5lbC4gVGhpcyBlbnN1cmVzIHRoYXQgdGhlIGNvdXBsaW5nCiAgICAgICAgIG1vZGVzIG9mIGJvdGggY2hhbm5lbHMgbWF0Y2ggYW5kIHRoYXQgd2UgaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgZW52ZWxvcGVzIGluCiAgICAgICAgIGNvdXBsaW5nIG1vZGUuCiAgICAgICAgIEhvd2V2ZXIsIGFzIHRoZSBsZWZ0IGNoYW5uZWwgaGFzIGFscmVhZHkgYmVlbiBwcm9jZXNzZWQgYmVmb3JlLCB0aGUgcmVzdWx0aW5nCiAgICAgICAgIGVuZXJneSBsZXZlbHMgYXJlIG5vdCB0aGUgc2FtZSBhcyBpZiB0aGUgbGVmdCBjaGFubmVsIGhhZCBiZWVuIGNvbmNlYWxlZAogICAgICAgICBkdXJpbmcgdGhlIGZpcnN0IGNhbGwgb2YgZGVjb2RlRW52ZWxvcGUoKS4KICAgICAgKi8KICAgICAgLyogUmVzdG9yZSBwcmV2aW91cyBlbmVyZ3kgdmFsdWVzIGZvciBjb25jZWFsbWVudCwgYmVjYXVzZSB0aGUgdmFsdWVzIGhhdmUgYmVlbgogICAgICAgICBvdmVyd3JpdHRlbiBieSB0aGUgZmlyc3QgY2FsbCBvZiBkZWNvZGVFbnZlbG9wZSgpLiAqLwogICAgICBGREttZW1jcHkgKGhfcHJldl9kYXRhX2xlZnQtPnNmYl9ucmdfcHJldiwgdGVtcFNmYk5yZ1ByZXYsIE1BWF9GUkVRX0NPRUZGUyAqIHNpemVvZihGSVhQX1NHTCkpOwogICAgICAvKiBEbyBjb25jZWFsbWVudCAqLwogICAgICBkZWNvZGVFbnZlbG9wZSAoaEhlYWRlckRhdGEsIGhfZGF0YV9sZWZ0LCBoX3ByZXZfZGF0YV9sZWZ0LCBoX3ByZXZfZGF0YV9yaWdodCk7CiAgICB9CgogICAgaWYgKGhfZGF0YV9sZWZ0LT5jb3VwbGluZykgewogICAgICBzYnJfZW52ZWxvcGVfdW5tYXBwaW5nIChoSGVhZGVyRGF0YSwgaF9kYXRhX2xlZnQsIGhfZGF0YV9yaWdodCk7CiAgICB9CiAgfQoKICAvKiBEaXNwbGF5IHRoZSBkYXRhIGZvciBkZWJ1Z2dpbmc6ICovCn0KCgovKiEKICBcYnJpZWYgICBDb252ZXJ0IGZyb20gY291cGxlZCBjaGFubmVscyB0byBpbmRlcGVuZGVudCBML1IgZGF0YQoqLwpzdGF0aWMgdm9pZApzYnJfZW52ZWxvcGVfdW5tYXBwaW5nIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLCAvKiE8IFN0YXRpYyBjb250cm9sIGRhdGEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBIGhfZGF0YV9sZWZ0LCAgLyohPCBwb2ludGVyIHRvIGxlZnQgY2hhbm5lbCAqLwogICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9kYXRhX3JpZ2h0KSAvKiE8IHBvaW50ZXIgdG8gcmlnaHQgY2hhbm5lbCAqLwp7CiAgaW50IGk7CiAgRklYUF9TR0wgdGVtcExfbSwgdGVtcFJfbSwgdGVtcFJwbHVzMV9tLCBuZXdMX20sIG5ld1JfbTsKICBTQ0hBUiAgIHRlbXBMX2UsIHRlbXBSX2UsIHRlbXBScGx1czFfZSwgbmV3TF9lLCBuZXdSX2U7CgoKICAvKiAxLiBVbm1hcCAoYWxyZWFkeSBkZXF1YW50aXplZCkgY291cGxlZCBlbnZlbG9wZSBlbmVyZ2llcyAqLwoKICBmb3IgKGkgPSAwOyBpIDwgaF9kYXRhX2xlZnQtPm5TY2FsZUZhY3RvcnM7IGkrKykgewogICAgdGVtcFJfbSA9IChGSVhQX1NHTCkoKExPTkcpaF9kYXRhX3JpZ2h0LT5pRW52ZWxvcGVbaV0gJiBNQVNLX00pOwogICAgdGVtcFJfZSA9IChTQ0hBUikoKExPTkcpaF9kYXRhX3JpZ2h0LT5pRW52ZWxvcGVbaV0gJiBNQVNLX0UpOwoKICAgIHRlbXBSX2UgLT0gKDE4ICsgTlJHX0VYUF9PRkZTRVQpOyAgLyogLTE4ID0gbGQoVU5NQVBQSU5HX1NDQUxFIC8gaF9kYXRhX3JpZ2h0LT5uQ2hhbm5lbHMpICovCiAgICB0ZW1wTF9tID0gKEZJWFBfU0dMKSgoTE9ORyloX2RhdGFfbGVmdC0+aUVudmVsb3BlW2ldICYgTUFTS19NKTsKICAgIHRlbXBMX2UgPSAoU0NIQVIpKChMT05HKWhfZGF0YV9sZWZ0LT5pRW52ZWxvcGVbaV0gJiBNQVNLX0UpOwoKICAgIHRlbXBMX2UgLT0gTlJHX0VYUF9PRkZTRVQ7CgogICAgLyogQ2FsY3VsYXRlIHRlbXBSaWdodCsxICovCiAgICBGREtfYWRkX01hbnRFeHAoIHRlbXBSX20sIHRlbXBSX2UsCiAgICAgICAgICAgICAgICAgICAgIEZMMkZYQ09OU1RfU0dMKDAuNWYpLCAxLCAgLyogMS4wICovCiAgICAgICAgICAgICAgICAgICAgICZ0ZW1wUnBsdXMxX20sICZ0ZW1wUnBsdXMxX2UpOwoKICAgIEZES19kaXZpZGVfTWFudEV4cCggdGVtcExfbSwgdGVtcExfZSsxLCAgLyogIDIgKiB0ZW1wTGVmdCAqLwogICAgICAgICAgICAgICAgICAgICAgIHRlbXBScGx1czFfbSwgdGVtcFJwbHVzMV9lLAogICAgICAgICAgICAgICAgICAgICAgICZuZXdSX20sICZuZXdSX2UgKTsKCiAgICBpZiAobmV3Ul9tID49ICgoRklYUF9TR0wpTUFYVkFMX1NHTCAtIFJPVU5ESU5HKSkgewogICAgICBuZXdSX20gPj49IDE7CiAgICAgIG5ld1JfZSArPSAxOwogICAgfQoKICAgIG5ld0xfbSA9IEZYX0RCTDJGWF9TR0woZk11bHQodGVtcFJfbSxuZXdSX20pKTsKICAgIG5ld0xfZSA9IHRlbXBSX2UgKyBuZXdSX2U7CgogICAgaF9kYXRhX3JpZ2h0LT5pRW52ZWxvcGVbaV0gPSAoKEZJWFBfU0dMKSgoU0hPUlQpKEZJWFBfU0dMKShuZXdSX20gKyBST1VORElORykgJiBNQVNLX00pKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRklYUF9TR0wpKChTSE9SVCkoRklYUF9TR0wpKG5ld1JfZSArIE5SR19FWFBfT0ZGU0VUKSAmIE1BU0tfRSk7CiAgICBoX2RhdGFfbGVmdC0+aUVudmVsb3BlW2ldID0gICgoRklYUF9TR0wpKChTSE9SVCkoRklYUF9TR0wpKG5ld0xfbSArIFJPVU5ESU5HKSAmIE1BU0tfTSkpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChGSVhQX1NHTCkoKFNIT1JUKShGSVhQX1NHTCkobmV3TF9lICsgTlJHX0VYUF9PRkZTRVQpICYgTUFTS19FKTsKICB9CgogIC8qIDIuIERlcXVhbnRpemUgYW5kIHVubWFwIGNvdXBsZWQgbm9pc2UgZmxvb3IgbGV2ZWxzICovCgogIGZvciAoaSA9IDA7IGkgPCBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5OZmIgKiBoX2RhdGFfbGVmdC0+ZnJhbWVJbmZvLm5Ob2lzZUVudmVsb3BlczsgaSsrKSB7CgogICAgdGVtcExfZSA9IChTQ0hBUikoNiAtIChMT05HKWhfZGF0YV9sZWZ0LT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0pOwogICAgdGVtcFJfZSA9IChTQ0hBUikoKExPTkcpaF9kYXRhX3JpZ2h0LT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0gLSAxMikgLypTQlJfRU5FUkdZX1BBTl9PRkZTRVQqLzsKCiAgICAvKiBDYWxjdWxhdGUgdGVtcFIrMSAqLwogICAgRkRLX2FkZF9NYW50RXhwKCBGTDJGWENPTlNUX1NHTCgwLjVmKSwgMSt0ZW1wUl9lLCAvKiB0ZW1wUiAqLwogICAgICAgICAgICAgICAgICAgICBGTDJGWENPTlNUX1NHTCgwLjVmKSwgMSwgICAgICAgICAvKiAgMS4wICAqLwogICAgICAgICAgICAgICAgICAgICAmdGVtcFJwbHVzMV9tLCAmdGVtcFJwbHVzMV9lKTsKCiAgICAvKiBDYWxjdWxhdGUgMip0ZW1wTGVmdC8odGVtcFIrMSkgKi8KICAgIEZES19kaXZpZGVfTWFudEV4cCggRkwyRlhDT05TVF9TR0woMC41ZiksIHRlbXBMX2UrMiwgIC8qICAyICogdGVtcExlZnQgKi8KICAgICAgICAgICAgICAgICAgICAgICB0ZW1wUnBsdXMxX20sIHRlbXBScGx1czFfZSwKICAgICAgICAgICAgICAgICAgICAgICAmbmV3Ul9tLCAmbmV3Ul9lICk7CgogICAgLyogaWYgKG5ld1JfbSA+PSAoKEZJWFBfU0dMKU1BWFZBTF9TR0wgLSBST1VORElORykpIHsKICAgICAgbmV3Ul9tID4+PSAxOwogICAgICBuZXdSX2UgKz0gMTsKICAgIH0gKi8KCiAgICAvKiBMID0gdGVtcFIgKiBSICovCiAgICBuZXdMX20gPSBuZXdSX207CiAgICBuZXdMX2UgPSBuZXdSX2UgKyB0ZW1wUl9lOwogICAgaF9kYXRhX3JpZ2h0LT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0gPSAoKEZJWFBfU0dMKSgoU0hPUlQpKEZJWFBfU0dMKShuZXdSX20gKyBST1VORElORykgJiBNQVNLX00pKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRklYUF9TR0wpKChTSE9SVCkoRklYUF9TR0wpKG5ld1JfZSArIE5PSVNFX0VYUF9PRkZTRVQpICYgTUFTS19FKTsKICAgIGhfZGF0YV9sZWZ0LT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0gPSAgKChGSVhQX1NHTCkoKFNIT1JUKShGSVhQX1NHTCkobmV3TF9tICsgUk9VTkRJTkcpICYgTUFTS19NKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEZJWFBfU0dMKSgoU0hPUlQpKEZJWFBfU0dMKShuZXdMX2UgKyBOT0lTRV9FWFBfT0ZGU0VUKSAmIE1BU0tfRSk7CiAgfQp9CgoKLyohCiAgXGJyaWVmICAgIFNpbXBsZSBhbHRlcm5hdGl2ZSB0byB0aGUgcmVhbCBTQlIgY29uY2VhbG1lbnQKCiAgSWYgdGhlIHJlYWwgZnJhbWVJbmZvIGlzIG5vdCBhdmFpbGFibGUgZHVlIHRvIGEgZnJhbWUgbG9zcywgYSByZXBsYWNlbWVudCB3aWxsCiAgYmUgY29uc3RydWN0ZWQgd2l0aCAxIGVudmVsb3BlIHNwYW5uaW5nIHRoZSB3aG9sZSBmcmFtZSAoRklYLUZJWCkuCiAgVGhlIGRlbHRhLWNvZGVkIGVuZXJnaWVzIGFyZSBzZXQgdG8gbmVnYXRpdmUgdmFsdWVzLCByZXN1bHRpbmcgaW4gYSBmYWRlLWRvd24uCiAgSW4gY2FzZSBvZiBjb3VwbGluZywgdGhlIGJhbGFuY2UtY2hhbm5lbCB3aWxsIG1vdmUgdG93YXJkcyB0aGUgY2VudGVyLgoqLwpzdGF0aWMgdm9pZApsZWFuU2JyQ29uY2VhbG1lbnQoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwgICAgIC8qITwgU3RhdGljIGNvbnRyb2wgZGF0YSAqLwogICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBICBoX3Nicl9kYXRhLCAgICAgIC8qITwgcG9pbnRlciB0byBjdXJyZW50IGRhdGEgKi8KICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfUFJFVl9GUkFNRV9EQVRBIGhfcHJldl9kYXRhICAvKiE8IHBvaW50ZXIgdG8gZGF0YSBvZiBsYXN0IGZyYW1lICovCiAgICAgICAgICAgICAgICAgICApCnsKICBGSVhQX1NHTCB0YXJnZXQ7ICAvKiB0YXJnZXRlZCBsZXZlbCBmb3Igc2ZiX25yZ19wcmV2IGR1cmluZyBmYWRlLWRvd24gKi8KICBGSVhQX1NHTCBzdGVwOyAgICAvKiBzcGVlZCBvZiBmYWRlICovCiAgaW50IGk7CgogIGludCBjdXJyZW50U3RhcnRQb3MgPSBoX3ByZXZfZGF0YS0+c3RvcFBvcyAtIGhIZWFkZXJEYXRhLT5udW1iZXJUaW1lU2xvdHM7CiAgaW50IGN1cnJlbnRTdG9wUG9zID0gaEhlYWRlckRhdGEtPm51bWJlclRpbWVTbG90czsKCgogIC8qIFVzZSBzb21lIHNldHRpbmdzIG9mIHRoZSBwcmV2aW91cyBmcmFtZSAqLwogIGhfc2JyX2RhdGEtPmFtcFJlc29sdXRpb25DdXJyZW50RnJhbWUgPSBoX3ByZXZfZGF0YS0+YW1wUmVzOwogIGhfc2JyX2RhdGEtPmNvdXBsaW5nID0gaF9wcmV2X2RhdGEtPmNvdXBsaW5nOwogIGZvcihpPTA7aTxNQVhfSU5WRl9CQU5EUztpKyspCiAgICBoX3Nicl9kYXRhLT5zYnJfaW52Zl9tb2RlW2ldID0gaF9wcmV2X2RhdGEtPnNicl9pbnZmX21vZGVbaV07CgogIC8qIEdlbmVyYXRlIGNvbmNlYWxpbmcgY29udHJvbCBkYXRhICovCgogIGhfc2JyX2RhdGEtPmZyYW1lSW5mby5uRW52ZWxvcGVzID0gMTsKICBoX3Nicl9kYXRhLT5mcmFtZUluZm8uYm9yZGVyc1swXSA9IGN1cnJlbnRTdGFydFBvczsKICBoX3Nicl9kYXRhLT5mcmFtZUluZm8uYm9yZGVyc1sxXSA9IGN1cnJlbnRTdG9wUG9zOwogIGhfc2JyX2RhdGEtPmZyYW1lSW5mby5mcmVxUmVzWzBdID0gMTsKICBoX3Nicl9kYXRhLT5mcmFtZUluZm8udHJhbkVudiA9IC0xOyAgLyogbm8gdHJhbnNpZW50ICovCiAgaF9zYnJfZGF0YS0+ZnJhbWVJbmZvLm5Ob2lzZUVudmVsb3BlcyA9IDE7CiAgaF9zYnJfZGF0YS0+ZnJhbWVJbmZvLmJvcmRlcnNOb2lzZVswXSA9IGN1cnJlbnRTdGFydFBvczsKICBoX3Nicl9kYXRhLT5mcmFtZUluZm8uYm9yZGVyc05vaXNlWzFdID0gY3VycmVudFN0b3BQb3M7CgogIGhfc2JyX2RhdGEtPm5TY2FsZUZhY3RvcnMgPSBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5TZmJbMV07CgogIC8qIEdlbmVyYXRlIGZha2UgZW52ZWxvcGUgZGF0YSAqLwoKICBoX3Nicl9kYXRhLT5kb21haW5fdmVjWzBdID0gMTsKCiAgaWYgKGhfc2JyX2RhdGEtPmNvdXBsaW5nID09IENPVVBMSU5HX0JBTCkgewogICAgdGFyZ2V0ID0gKEZJWFBfU0dMKVNCUl9FTkVSR1lfUEFOX09GRlNFVDsKICAgIHN0ZXAgPSAoRklYUF9TR0wpREVDQVlfQ09VUExJTkc7CiAgfQogIGVsc2UgewogICAgdGFyZ2V0ID0gRkwyRlhDT05TVF9TR0woMC4wZik7CiAgICBzdGVwICAgPSAoRklYUF9TR0wpREVDQVk7CiAgfQogIGlmIChoSGVhZGVyRGF0YS0+YnNfaW5mby5hbXBSZXNvbHV0aW9uID09IDApIHsKICAgIHRhcmdldCA8PD0gMTsKICAgIHN0ZXAgICA8PD0gMTsKICB9CgogIGZvciAoaT0wOyBpIDwgaF9zYnJfZGF0YS0+blNjYWxlRmFjdG9yczsgaSsrKSB7CiAgICBpZiAoaF9wcmV2X2RhdGEtPnNmYl9ucmdfcHJldltpXSA+IHRhcmdldCkKICAgICAgaF9zYnJfZGF0YS0+aUVudmVsb3BlW2ldID0gLXN0ZXA7CiAgICBlbHNlCiAgICAgIGhfc2JyX2RhdGEtPmlFbnZlbG9wZVtpXSA9IHN0ZXA7CiAgfQoKICAvKiBOb2lzZWZsb29yIGxldmVscyBhcmUgYWx3YXlzIGNsZWFyZWQgLi4uICovCgogIGhfc2JyX2RhdGEtPmRvbWFpbl92ZWNfbm9pc2VbMF0gPSAxOwogIGZvciAoaT0wOyBpIDwgaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5uTmZiOyBpKyspCiAgICBoX3Nicl9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0gPSBGTDJGWENPTlNUX1NHTCgwLjBmKTsKCiAgLyogLi4uIGFuZCBzbyBhcmUgdGhlIHNpbmVzICovCiAgRkRLbWVtY2xlYXIoaF9zYnJfZGF0YS0+YWRkSGFybW9uaWNzLCBNQVhfRlJFUV9DT0VGRlMpOwp9CgoKLyohCiAgXGJyaWVmICAgQnVpbGQgcmVmZXJlbmNlIGVuZXJnaWVzIGFuZCBub2lzZSBsZXZlbHMgZnJvbSBiaXRzdHJlYW0gZWxlbWVudHMKKi8Kc3RhdGljIHZvaWQKZGVjb2RlRW52ZWxvcGUgKEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsICAgICAvKiE8IFN0YXRpYyBjb250cm9sIGRhdGEgKi8KICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSAgaF9zYnJfZGF0YSwgICAgICAvKiE8IHBvaW50ZXIgdG8gY3VycmVudCBkYXRhICovCiAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX1BSRVZfRlJBTUVfREFUQSBoX3ByZXZfZGF0YSwgLyohPCBwb2ludGVyIHRvIGRhdGEgb2YgbGFzdCBmcmFtZSAqLwogICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgb3RoZXJDaGFubmVsIC8qITwgb3RoZXIgY2hhbm5lbCdzIGxhc3QgZnJhbWUgZGF0YSAqLwogICAgICAgICAgICAgICAgKQp7CiAgaW50IGk7CiAgaW50IGZGcmFtZUVycm9yID0gaEhlYWRlckRhdGEtPmZyYW1lRXJyb3JGbGFnOwogIEZJWFBfU0dMIHRlbXBTZmJOcmdQcmV2W01BWF9GUkVRX0NPRUZGU107CgogIGlmICghZkZyYW1lRXJyb3IpIHsKICAgIC8qCiAgICAgIFRvIGF2b2lkIGRpc3RvcnRpb25zIGFmdGVyIGJhZCBmcmFtZXMsIHNldCB0aGUgZXJyb3IgZmxhZyBpZiBkZWx0YSBjb2RpbmcgaW4gdGltZSBvY2N1cnMuCiAgICAgIEhvd2V2ZXIsIFNCUiBjYW4gdGFrZSBhIGxpdHRsZSBsb25nZXIgdG8gY29tZSB1cCBhZ2Fpbi4KICAgICovCiAgICBpZiAoIGhfcHJldl9kYXRhLT5mcmFtZUVycm9yRmxhZyApIHsKICAgICAgaWYgKGhfc2JyX2RhdGEtPmRvbWFpbl92ZWNbMF0gIT0gMCkgewogICAgICAgIGZGcmFtZUVycm9yID0gMTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgLyogQ2hlY2sgdGhhdCB0aGUgcHJldmlvdXMgc3RvcCBwb3NpdGlvbiBhbmQgdGhlIGN1cnJlbnQgc3RhcnQgcG9zaXRpb24gbWF0Y2guCiAgICAgICAgIChDb3VsZCBiZSBkb25lIGluIGNoZWNrRnJhbWVJbmZvKCksIGJ1dCB0aGUgcHJldmlvdXMgZnJhbWUgZGF0YSBpcyBub3QgYXZhaWxhYmxlIHRoZXJlKSAqLwogICAgICBpZiAoIGhfc2JyX2RhdGEtPmZyYW1lSW5mby5ib3JkZXJzWzBdICE9IGhfcHJldl9kYXRhLT5zdG9wUG9zIC0gaEhlYWRlckRhdGEtPm51bWJlclRpbWVTbG90cyApIHsKICAgICAgICAvKiBCb3RoIHRoZSBwcmV2aW91cyBhcyB3ZWxsIGFzIHRoZSBjdXJyZW50IGZyYW1lIGFyZSBmbGFnZ2VkIHRvIGJlIG9rLCBidXQgdGhleSBkbyBub3QgbWF0Y2ghICovCiAgICAgICAgaWYgKGhfc2JyX2RhdGEtPmRvbWFpbl92ZWNbMF0gPT0gMSkgewogICAgICAgICAgLyogUHJlZmVyIGNvbmNlYWxtZW50IG92ZXIgZGVsdGEtdGltZSBjb2RpbmcgYmV0d2VlbiB0aGUgbWlzbWF0Y2hpbmcgZnJhbWVzICovCiAgICAgICAgICBmRnJhbWVFcnJvciA9IDE7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgLyogQ2xvc2UgdGhlIGdhcCBpbiB0aW1lIGJ5IHRyaWdnZXJpbmcgdGltZUNvbXBlbnNhdGVGaXJzdEVudmVsb3BlKCkgKi8KICAgICAgICAgIGZGcmFtZUVycm9yID0gMTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgoKICBpZiAoZkZyYW1lRXJyb3IpICAgICAgIC8qIEVycm9yIGlzIGRldGVjdGVkICovCiAgICB7CiAgICAgIGxlYW5TYnJDb25jZWFsbWVudChoSGVhZGVyRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgIGhfc2JyX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBoX3ByZXZfZGF0YSk7CgogICAgICAvKiBkZWNvZGUgdGhlIGVudmVsb3BlIGRhdGEgdG8gbGluZWFyIFBDTSAqLwogICAgICBkZWx0YVRvTGluZWFyUGNtRW52ZWxvcGVEZWNvZGluZyAoaEhlYWRlckRhdGEsIGhfc2JyX2RhdGEsIGhfcHJldl9kYXRhKTsKICAgIH0KICBlbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAvKkRvIGEgdGVtcG9yYXJ5IGR1bW15IGRlY29kaW5nIGFuZCBjaGVjayB0aGF0IHRoZSBlbnZlbG9wZSB2YWx1ZXMgYXJlIHdpdGhpbiBsaW1pdHMgKi8KICAgIHsKICAgICAgaWYgKGhfcHJldl9kYXRhLT5mcmFtZUVycm9yRmxhZykgewogICAgICAgIHRpbWVDb21wZW5zYXRlRmlyc3RFbnZlbG9wZSAoaEhlYWRlckRhdGEsIGhfc2JyX2RhdGEsIGhfcHJldl9kYXRhKTsKICAgICAgICBpZiAoaF9zYnJfZGF0YS0+Y291cGxpbmcgIT0gaF9wcmV2X2RhdGEtPmNvdXBsaW5nKSB7CiAgICAgICAgICAvKgogICAgICAgICAgICBDb3VwbGluZyBtb2RlIGhhcyBjaGFuZ2VkIGR1cmluZyBjb25jZWFsbWVudC4KICAgICAgICAgICAgIFRoZSBzdG9yZWQgZW5lcmd5IGxldmVscyBuZWVkIHRvIGJlIGNvbnZlcnRlZC4KICAgICAgICAgICAqLwogICAgICAgICAgZm9yIChpID0gMDsgaSA8IGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEublNmYlsxXTsgaSsrKSB7CiAgICAgICAgICAgIC8qIEZvcm1lciBMZXZlbC1DaGFubmVsIHdpbGwgYmUgdXNlZCBmb3IgYm90aCBjaGFubmVscyAqLwogICAgICAgICAgICBpZiAoaF9wcmV2X2RhdGEtPmNvdXBsaW5nID09IENPVVBMSU5HX0JBTCkKICAgICAgICAgICAgICBoX3ByZXZfZGF0YS0+c2ZiX25yZ19wcmV2W2ldID0gb3RoZXJDaGFubmVsLT5zZmJfbnJnX3ByZXZbaV07CiAgICAgICAgICAgIC8qIEZvcm1lciBML1Igd2lsbCBiZSBjb21iaW5lZCBhcyB0aGUgbmV3IExldmVsLUNoYW5uZWwgKi8KICAgICAgICAgICAgZWxzZSBpZiAoaF9zYnJfZGF0YS0+Y291cGxpbmcgPT0gQ09VUExJTkdfTEVWRUwpCiAgICAgICAgICAgICAgaF9wcmV2X2RhdGEtPnNmYl9ucmdfcHJldltpXSA9IChoX3ByZXZfZGF0YS0+c2ZiX25yZ19wcmV2W2ldICsgb3RoZXJDaGFubmVsLT5zZmJfbnJnX3ByZXZbaV0pID4+IDE7CiAgICAgICAgICAgIGVsc2UgaWYgKGhfc2JyX2RhdGEtPmNvdXBsaW5nID09IENPVVBMSU5HX0JBTCkKICAgICAgICAgICAgICBoX3ByZXZfZGF0YS0+c2ZiX25yZ19wcmV2W2ldID0gKEZJWFBfU0dMKVNCUl9FTkVSR1lfUEFOX09GRlNFVDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgRkRLbWVtY3B5ICh0ZW1wU2ZiTnJnUHJldiwgaF9wcmV2X2RhdGEtPnNmYl9ucmdfcHJldiwKICAgICAgICAgICAgICBNQVhfRlJFUV9DT0VGRlMgKiBzaXplb2YgKEZJWFBfU0dMKSk7CgogICAgICBkZWx0YVRvTGluZWFyUGNtRW52ZWxvcGVEZWNvZGluZyAoaEhlYWRlckRhdGEsIGhfc2JyX2RhdGEsIGhfcHJldl9kYXRhKTsKCiAgICAgIGZGcmFtZUVycm9yID0gY2hlY2tFbnZlbG9wZURhdGEgKGhIZWFkZXJEYXRhLCBoX3Nicl9kYXRhLCBoX3ByZXZfZGF0YSk7CgogICAgICBpZiAoZkZyYW1lRXJyb3IpCiAgICAgICAgewogICAgICAgICAgaEhlYWRlckRhdGEtPmZyYW1lRXJyb3JGbGFnID0gMTsKICAgICAgICAgIEZES21lbWNweSAoaF9wcmV2X2RhdGEtPnNmYl9ucmdfcHJldiwgdGVtcFNmYk5yZ1ByZXYsCiAgICAgICAgICAgICAgICAgIE1BWF9GUkVRX0NPRUZGUyAqIHNpemVvZiAoRklYUF9TR0wpKTsKICAgICAgICAgIGRlY29kZUVudmVsb3BlIChoSGVhZGVyRGF0YSwgaF9zYnJfZGF0YSwgaF9wcmV2X2RhdGEsIG90aGVyQ2hhbm5lbCk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICByZXF1YW50aXplRW52ZWxvcGVEYXRhIChoX3Nicl9kYXRhLCBoX3Nicl9kYXRhLT5hbXBSZXNvbHV0aW9uQ3VycmVudEZyYW1lKTsKCiAgaEhlYWRlckRhdGEtPmZyYW1lRXJyb3JGbGFnID0gZkZyYW1lRXJyb3I7Cn0KCgovKiEKICBcYnJpZWYgICBWZXJpZnkgdGhhdCBlbnZlbG9wZSBlbmVyZ2llcyBhcmUgd2l0aGluIHRoZSBhbGxvd2VkIHJhbmdlCiAgXHJldHVybiAgMCBpZiBhbGwgaXMgZmluZSwgMSBpZiBhbiBlbnZlbG9wZSB2YWx1ZSB3YXMgdG9vIGhpZ2gKKi8Kc3RhdGljIGludApjaGVja0VudmVsb3BlRGF0YSAoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwgICAgIC8qITwgU3RhdGljIGNvbnRyb2wgZGF0YSAqLwogICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBIGhfc2JyX2RhdGEsICAgICAgIC8qITwgcG9pbnRlciB0byBjdXJyZW50IGRhdGEgKi8KICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfUFJFVl9GUkFNRV9EQVRBIGhfcHJldl9kYXRhICAvKiE8IHBvaW50ZXIgdG8gZGF0YSBvZiBsYXN0IGZyYW1lICovCiAgICAgICAgICAgICAgICAgICApCnsKICBGSVhQX1NHTCAqaUVudmVsb3BlID0gaF9zYnJfZGF0YS0+aUVudmVsb3BlOwogIEZJWFBfU0dMICpzZmJfbnJnX3ByZXYgPSBoX3ByZXZfZGF0YS0+c2ZiX25yZ19wcmV2OwogIGludCAgICBpID0gMCwgZXJyb3JGbGFnID0gMDsKICBGSVhQX1NHTCBzYnJfbWF4X2VuZXJneSA9CiAgICAoaF9zYnJfZGF0YS0+YW1wUmVzb2x1dGlvbkN1cnJlbnRGcmFtZSA9PSAxKSA/IFNCUl9NQVhfRU5FUkdZIDogKFNCUl9NQVhfRU5FUkdZIDw8IDEpOwoKICAvKgogICAgUmFuZ2UgY2hlY2sgZm9yIGN1cnJlbnQgZW5lcmdpZXMKICAqLwogIGZvciAoaSA9IDA7IGkgPCBoX3Nicl9kYXRhLT5uU2NhbGVGYWN0b3JzOyBpKyspIHsKICAgIGlmIChpRW52ZWxvcGVbaV0gPiBzYnJfbWF4X2VuZXJneSkgewogICAgICBlcnJvckZsYWcgPSAxOwogICAgfQogICAgaWYgKGlFbnZlbG9wZVtpXSA8IEZMMkZYQ09OU1RfU0dMKDAuMGYpKSB7CiAgICAgIGVycm9yRmxhZyA9IDE7CiAgICAgIC8qIGlFbnZlbG9wZVtpXSA9IEZMMkZYQ09OU1RfU0dMKDAuMGYpOyAqLwogICAgfQogIH0KCiAgLyoKICAgIFJhbmdlIGNoZWNrIGZvciBwcmV2aW91cyBlbmVyZ2llcwogICovCiAgZm9yIChpID0gMDsgaSA8IGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEublNmYlsxXTsgaSsrKSB7CiAgICBzZmJfbnJnX3ByZXZbaV0gPSBmaXhNYXgoc2ZiX25yZ19wcmV2W2ldLCBGTDJGWENPTlNUX1NHTCgwLjBmKSk7CiAgICBzZmJfbnJnX3ByZXZbaV0gPSBmaXhNaW4oc2ZiX25yZ19wcmV2W2ldLCBzYnJfbWF4X2VuZXJneSk7CiAgfQoKICByZXR1cm4gKGVycm9yRmxhZyk7Cn0KCgovKiEKICBcYnJpZWYgICBWZXJpZnkgdGhhdCB0aGUgbm9pc2UgbGV2ZWxzIGFyZSB3aXRoaW4gdGhlIGFsbG93ZWQgcmFuZ2UKCiAgVGhlIGZ1bmN0aW9uIGlzIGVxdWl2YWxlbnQgdG8gY2hlY2tFbnZlbG9wZURhdGEoKS4KICBXaGVuIHRoZSBub2lzZS1sZXZlbHMgYXJlIGJlaW5nIGRlY29kZWQsIGl0IGlzIGFscmVhZHkgdG9vIGxhdGUgZm9yCiAgY29uY2VhbG1lbnQuIFRoZXJlZm9yZSB0aGUgbm9pc2UgbGV2ZWxzIGFyZSBzaW1wbHkgbGltaXRlZCBoZXJlLgoqLwpzdGF0aWMgdm9pZApsaW1pdE5vaXNlTGV2ZWxzKEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsICAgICAvKiE8IFN0YXRpYyBjb250cm9sIGRhdGEgKi8KICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9zYnJfZGF0YSkgICAgICAgLyohPCBwb2ludGVyIHRvIGN1cnJlbnQgZGF0YSAqLwp7CiAgaW50IGk7CiAgaW50IG5OZmIgPSBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5OZmI7CgogIC8qCiAgICBTZXQgcmFuZ2UgbGltaXRzLiBUaGUgZXhhY3QgdmFsdWVzIGRlcGVuZCBvbiB0aGUgY291cGxpbmcgbW9kZS4KICAgIEhvd2V2ZXIgdGhpcyBsaW1pdGF0aW9uIGlzIHByaW1hcmlseSBpbnRlbmRlZCB0byBhdm9pZCB1bmxpbWl0ZWQKICAgIGFjY3VtdWxhdGlvbiBvZiB0aGUgZGVsdGEtY29kZWQgbm9pc2UgbGV2ZWxzLgogICovCiAgI2RlZmluZSBsb3dlckxpbWl0ICAgKChGSVhQX1NHTCkwKSAgICAgLyogbG93ZXJMaW1pdCBhY3R1YWxseSByZWZlcnMgdG8gdGhlIF9oaWdoZXN0XyBub2lzZSBlbmVyZ3kgKi8KICAjZGVmaW5lIHVwcGVyTGltaXQgICAoKEZJWFBfU0dMKTM1KSAgICAvKiB1cHBlckxpbWl0IGFjdHVhbGx5IHJlZmVycyB0byB0aGUgX2xvd2VzdF8gbm9pc2UgZW5lcmd5ICovCgogIC8qCiAgICBSYW5nZSBjaGVjayBmb3IgY3VycmVudCBub2lzZSBsZXZlbHMKICAqLwogIGZvciAoaSA9IDA7IGkgPCBoX3Nicl9kYXRhLT5mcmFtZUluZm8ubk5vaXNlRW52ZWxvcGVzICogbk5mYjsgaSsrKSB7CiAgICBoX3Nicl9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0gPSBmaXhNaW4oaF9zYnJfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsW2ldLCB1cHBlckxpbWl0KTsKICAgIGhfc2JyX2RhdGEtPnNick5vaXNlRmxvb3JMZXZlbFtpXSA9IGZpeE1heChoX3Nicl9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0sIGxvd2VyTGltaXQpOwogIH0KfQoKCi8qIQogIFxicmllZiAgIENvbXBlbnNhdGUgZm9yIHRoZSB3cm9uZyB0aW1pbmcgdGhhdCBtaWdodCBvY2N1ciBhZnRlciBhIGZyYW1lIGVycm9yLgoqLwpzdGF0aWMgdm9pZAp0aW1lQ29tcGVuc2F0ZUZpcnN0RW52ZWxvcGUgKEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsIC8qITwgU3RhdGljIGNvbnRyb2wgZGF0YSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSBoX3Nicl9kYXRhLCAgIC8qITwgcG9pbnRlciB0byBhY3R1YWwgZGF0YSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfUFJFVl9GUkFNRV9EQVRBIGhfcHJldl9kYXRhKSAgLyohPCBwb2ludGVyIHRvIGRhdGEgb2YgbGFzdCBmcmFtZSAqLwp7CiAgaW50IGksIG5TY2FsZWZhY3RvcnM7CiAgRlJBTUVfSU5GTyAqcEZyYW1lSW5mbyA9ICZoX3Nicl9kYXRhLT5mcmFtZUluZm87CiAgVUNIQVIgKm5TZmIgPSBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5TZmI7CiAgaW50IGVzdGltYXRlZFN0YXJ0UG9zID0gaF9wcmV2X2RhdGEtPnN0b3BQb3MgLSBoSGVhZGVyRGF0YS0+bnVtYmVyVGltZVNsb3RzOwogIGludCByZWZMZW4sIG5ld0xlbiwgc2hpZnQ7CiAgRklYUF9TR0wgIGRlbHRhRXhwOwoKICAvKiBPcmlnaW5hbCBsZW5ndGggb2YgZmlyc3QgZW52ZWxvcGUgYWNjb3JkaW5nIHRvIGJpdHN0cmVhbSAqLwogIHJlZkxlbiA9IHBGcmFtZUluZm8tPmJvcmRlcnNbMV0gLSBwRnJhbWVJbmZvLT5ib3JkZXJzWzBdOwogIC8qIENvcnJlY3RlZCBsZW5ndGggb2YgZmlyc3QgZW52ZWxvcGUgKGNvbmNlYWxpbmcgY2FuIG1ha2UgdGhlIGZpcnN0IGVudmVsb3BlIGxvbmdlcikgKi8KICBuZXdMZW4gPSBwRnJhbWVJbmZvLT5ib3JkZXJzWzFdIC0gZXN0aW1hdGVkU3RhcnRQb3M7CgogIGlmIChuZXdMZW4gPD0gMCkgewogICAgLyogQW4gZW52ZWxvcGUgbGVuZ3RoIG9mIDw9IDAgd291bGQgbm90IHdvcmssIHNvIHdlIGRvbid0IHVzZSBpdC4KICAgICAgIE1heSBvY2N1ciBpZiB0aGUgcHJldmlvdXMgZnJhbWUgd2FzIGZsYWdnZWQgYmFkIGR1ZSB0byBhIG1pc21hdGNoCiAgICAgICBvZiB0aGUgb2xkIGFuZCBuZXcgZnJhbWUgaW5mb3MuICovCiAgICBuZXdMZW4gPSByZWZMZW47CiAgICBlc3RpbWF0ZWRTdGFydFBvcyA9IHBGcmFtZUluZm8tPmJvcmRlcnNbMF07CiAgfQoKICBkZWx0YUV4cCA9IEZES19nZXROdW1PY3RhdmVzRGl2OChuZXdMZW4sIHJlZkxlbik7CgogIC8qIFNoaWZ0IGJ5IC0zIHRvIHJlc2NhbGUgbGQtdGFibGUsIGFtcFJlcy0xIHRvIGVuYWJsZSBjb2Fyc2VyIHN0ZXBzICovCiAgc2hpZnQgPSAoRlJBQ1RfQklUUyAtIDEgLSBFTlZfRVhQX0ZSQUNUIC0gMSArIGhfc2JyX2RhdGEtPmFtcFJlc29sdXRpb25DdXJyZW50RnJhbWUgLSAzKTsKICBkZWx0YUV4cCA9IGRlbHRhRXhwID4+IHNoaWZ0OwogIHBGcmFtZUluZm8tPmJvcmRlcnNbMF0gPSBlc3RpbWF0ZWRTdGFydFBvczsKICBwRnJhbWVJbmZvLT5ib3JkZXJzTm9pc2VbMF0gPSBlc3RpbWF0ZWRTdGFydFBvczsKCiAgaWYgKGhfc2JyX2RhdGEtPmNvdXBsaW5nICE9IENPVVBMSU5HX0JBTCkgewogICAgblNjYWxlZmFjdG9ycyA9IChwRnJhbWVJbmZvLT5mcmVxUmVzWzBdKSA/IG5TZmJbMV0gOiBuU2ZiWzBdOwoKICAgIGZvciAoaSA9IDA7IGkgPCBuU2NhbGVmYWN0b3JzOyBpKyspCiAgICAgIGhfc2JyX2RhdGEtPmlFbnZlbG9wZVtpXSA9IGhfc2JyX2RhdGEtPmlFbnZlbG9wZVtpXSArIGRlbHRhRXhwOwogIH0KfQoKCgovKiEKICBcYnJpZWYgICBDb252ZXJ0IGVhY2ggZW52ZWxvcGUgdmFsdWUgZnJvbSBsb2dhcml0aG1pYyB0byBsaW5lYXIgZG9tYWluCgogIEVuZXJneSBsZXZlbHMgYXJlIHRyYW5zbWl0dGVkIGluIHBvd2VycyBvZiAyLCBpLmUuIG9ubHkgdGhlIGV4cG9uZW50CiAgaXMgZXh0cmFjdGVkIGZyb20gdGhlIGJpdHN0cmVhbS4KICBUaGVyZWZvcmUsIG5vcm1hbGx5IG9ubHkgaW50ZWdlciBleHBvbmVudHMgY2FuIG9jY3VyLiBIb3dldmVyIGR1cmluZwogIGZhZGluZyAoaW4gY2FzZSBvZiBhIGNvcnJ1cHQgYml0c3RyZWFtKSwgYSBmcmFjdGlvbmFsIHBhcnQgY2FuIGFsc28KICBvY2N1ci4gVGhlIGRhdGEgaW4gdGhlIGFycmF5IGlFbnZlbG9wZSBpcyBzaGlmdGVkIGxlZnQgYnkgRU5WX0VYUF9GUkFDVAogIGNvbXBhcmVkIHRvIGFuIGludGVnZXIgcmVwcmVzZW50YXRpb24gc28gdGhhdCBudW1iZXJzIHNtYWxsZXIgdGhhbiAxCiAgY2FuIGJlIHJlcHJlc2VudGVkLgoKICBUaGlzIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgYSBtYW50aXNzYSBjb3JyZXNwb25kaW5nIHRvIHRoZSBmcmFjdGlvbmFsCiAgcGFydCBvZiB0aGUgZXhwb25lbnQgZm9yIGVhY2ggcmVmZXJlbmNlIGVuZXJneS4gVGhlIGFycmF5IGlFbnZlbG9wZQogIGlzIGNvbnZlcnRlZCBpbiBwbGFjZSB0byBzYXZlIG1lbW9yeS4gSW5wdXQgYW5kIG91dHB1dCBkYXRhIG11c3QKICBiZSBpbnRlcnByZXRlZCBkaWZmZXJlbnRseSwgYXMgc2hvd24gaW4gdGhlIGJlbG93IGZpZ3VyZToKCiAgXGltYWdlIGh0bWwgIEVudmVsb3BlRGF0YS5wbmcKCiAgVGhlIGRhdGEgaXMgdGhlbiB1c2VkIGluIGNhbGN1bGF0ZVNickVudmVsb3BlKCkuCiovCnN0YXRpYyB2b2lkCnJlcXVhbnRpemVFbnZlbG9wZURhdGEgKEhBTkRMRV9TQlJfRlJBTUVfREFUQSBoX3Nicl9kYXRhLCBpbnQgYW1wUmVzb2x1dGlvbikKewogIGludCBpOwogIEZJWFBfU0dMIG1hbnRpc3NhOwogIGludCBhbXBTaGlmdCA9IDEgLSBhbXBSZXNvbHV0aW9uOwogIGludCBleHBvbmVudDsKCiAgLyogSW4gY2FzZSB0aGF0IEVOVl9FWFBfRlJBQ1QgaXMgY2hhbmdlZCB0byBzb21ldGhpbmcgZWxzZSBidXQgMCBvciA4LAogICAgIHRoZSBpbml0aWFsaXphdGlvbiBvZiB0aGlzIGFycmF5IGhhcyB0byBiZSBhZGFwdGVkIQogICovCiNpZiBFTlZfRVhQX0ZSQUNUCiAgc3RhdGljIGNvbnN0IEZJWFBfU0dMIHBvdzJbRU5WX0VYUF9GUkFDVF0gPQogIHsKICAgIEZMMkZYQ09OU1RfU0dMKDAuNWYgKiBwb3coMi4wZiwgcG93KDAuNWYsIDEpKSksIC8qIDAuNzA3MSAqLwogICAgRkwyRlhDT05TVF9TR0woMC41ZiAqIHBvdygyLjBmLCBwb3coMC41ZiwgMikpKSwgLyogMC41OTQ2ICovCiAgICBGTDJGWENPTlNUX1NHTCgwLjVmICogcG93KDIuMGYsIHBvdygwLjVmLCAzKSkpLAogICAgRkwyRlhDT05TVF9TR0woMC41ZiAqIHBvdygyLjBmLCBwb3coMC41ZiwgNCkpKSwKICAgIEZMMkZYQ09OU1RfU0dMKDAuNWYgKiBwb3coMi4wZiwgcG93KDAuNWYsIDUpKSksCiAgICBGTDJGWENPTlNUX1NHTCgwLjVmICogcG93KDIuMGYsIHBvdygwLjVmLCA2KSkpLAogICAgRkwyRlhDT05TVF9TR0woMC41ZiAqIHBvdygyLjBmLCBwb3coMC41ZiwgNykpKSwKICAgIEZMMkZYQ09OU1RfU0dMKDAuNWYgKiBwb3coMi4wZiwgcG93KDAuNWYsIDgpKSkgIC8qIDAuNTAxMyAqLwogIH07CgogIGludCBiaXQsIG1hc2s7CiNlbmRpZgoKICBmb3IgKGkgPSAwOyBpIDwgaF9zYnJfZGF0YS0+blNjYWxlRmFjdG9yczsgaSsrKSB7CiAgICBleHBvbmVudCA9IChMT05HKWhfc2JyX2RhdGEtPmlFbnZlbG9wZVtpXTsKCiNpZiBFTlZfRVhQX0ZSQUNUCgogICAgZXhwb25lbnQgPSBleHBvbmVudCA+PiBhbXBTaGlmdDsKICAgIG1hbnRpc3NhID0gMC41ZjsKCiAgICAvKiBBbXBsaWZ5IG1hbnRpc3NhIGFjY29yZGluZyB0byB0aGUgZnJhY3Rpb25hbCBwYXJ0IG9mIHRoZQogICAgICAgZXhwb25lbnQgKHJlc3VsdCB3aWxsIGJlIGJldHdlZW4gMC41MDAwMDAgYW5kIDAuOTk5OTk5KQogICAgKi8KICAgIG1hc2sgPSAxOyAgLyogYmVnaW4gd2l0aCBsb3dlc3QgYml0IG9mIGV4cG9uZW50ICovCgogICAgZm9yICggYml0PUVOVl9FWFBfRlJBQ1QtMTsgYml0Pj0wOyBiaXQtLSApIHsKICAgICAgaWYgKGV4cG9uZW50ICYgbWFzaykgewogICAgICAgIC8qIFRoZSBjdXJyZW50IGJpdCBvZiB0aGUgZXhwb25lbnQgaXMgc2V0LAogICAgICAgICAgIG11bHRpcGx5IG1hbnRpc3NhIHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgZmFjdG9yOiAqLwogICAgICAgIG1hbnRpc3NhID0gKEZJWFBfU0dMKSggKG1hbnRpc3NhICogcG93MltiaXRdKSA8PCAxKTsKICAgICAgfQogICAgICAvKiBBZHZhbmNlIHRvIG5leHQgYml0ICovCiAgICAgIG1hc2sgPSBtYXNrIDw8IDE7CiAgICB9CgogICAgLyogTWFrZSBpbnRlZ2VyIHBhcnQgb2YgZXhwb25lbnQgcmlnaHQgYWxpZ25lZCAqLwogICAgZXhwb25lbnQgPSBleHBvbmVudCA+PiBFTlZfRVhQX0ZSQUNUOwoKI2Vsc2UKICAgIC8qIEluIGNhc2Ugb2YgdGhlIGhpZ2ggYW1wbGl0dWRlIHJlc29sdXRpb24sIDEgYml0IG9mIHRoZSBleHBvbmVudCBnZXRzIGxvc3QgYnkgdGhlIHNoaWZ0LgogICAgICAgVGhpcyB3aWxsIGJlIGNvbXBlbnNhdGVkIGJ5IGEgbWFudGlzc2Egb2YgMC41KnNxcnQoMikgaW5zdGVhZCBvZiAwLjUgaWYgdGhhdCBiaXQgaXMgMS4gKi8KICAgIG1hbnRpc3NhID0gKGV4cG9uZW50ICYgYW1wU2hpZnQpID8gRkwyRlhDT05TVF9TR0woMC43MDcxMDY3ODExODY1NDhmKSA6IEZMMkZYQ09OU1RfU0dMKDAuNWYpOwogICAgZXhwb25lbnQgPSBleHBvbmVudCA+PiBhbXBTaGlmdDsKI2VuZGlmCgogICAgLyoKICAgICAgTWFudGlzc2Egd2FzIHNldCB0byAwLjUgKGluc3RlYWQgb2YgMS4wLCB0aGVyZWZvcmUgaW5jcmVhc2UgZXhwb25lbnQgYnkgMSkuCiAgICAgIE11bHRpcGx5IGJ5IEw9bkNoYW5uZWxzPTY0IGJ5IGluY3JlYXNpbmcgZXhwb25lbnQgYnkgYW5vdGhlciA2LgogICAgICA9PiBJbmNyZWFzZSBleHBvbmVudCBieSA3CiAgICAqLwogICAgZXhwb25lbnQgKz0gNyArIE5SR19FWFBfT0ZGU0VUOwoKICAgIC8qIENvbWJpbmUgbWFudGlzc2EgYW5kIGV4cG9uZW50IGFuZCB3cml0ZSBiYWNrIHRoZSByZXN1bHQgKi8KICAgIGhfc2JyX2RhdGEtPmlFbnZlbG9wZVtpXSA9IChGSVhQX1NHTCkoKChMT05HKW1hbnRpc3NhICYgTUFTS19NKSB8IChleHBvbmVudCAmIE1BU0tfRSkpOwoKICB9Cn0KCgovKiEKICBcYnJpZWYgICBCdWlsZCBuZXcgcmVmZXJlbmNlIGVuZXJnaWVzIGZyb20gb2xkIG9uZXMgYW5kIGRlbHRhIGNvZGVkIGRhdGEKKi8Kc3RhdGljIHZvaWQKZGVsdGFUb0xpbmVhclBjbUVudmVsb3BlRGVjb2RpbmcgKEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsICAgICAvKiE8IFN0YXRpYyBjb250cm9sIGRhdGEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSBoX3Nicl9kYXRhLCAgICAgICAvKiE8IHBvaW50ZXIgdG8gY3VycmVudCBkYXRhICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX1BSRVZfRlJBTUVfREFUQSBoX3ByZXZfZGF0YSkgLyohPCBwb2ludGVyIHRvIHByZXZpb3VzIGRhdGEgKi8KewogIGludCBpLCBkb21haW4sIG5vX29mX2JhbmRzLCBiYW5kLCBmcmVxUmVzOwoKICBGSVhQX1NHTCAqc2ZiX25yZ19wcmV2ID0gaF9wcmV2X2RhdGEtPnNmYl9ucmdfcHJldjsKICBGSVhQX1NHTCAqcHRyX25yZyA9IGhfc2JyX2RhdGEtPmlFbnZlbG9wZTsKCiAgaW50IG9mZnNldCA9IDIgKiBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5TZmJbMF0gLSBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5TZmJbMV07CgogIGZvciAoaSA9IDA7IGkgPCBoX3Nicl9kYXRhLT5mcmFtZUluZm8ubkVudmVsb3BlczsgaSsrKSB7CiAgICBkb21haW4gPSBoX3Nicl9kYXRhLT5kb21haW5fdmVjW2ldOwogICAgZnJlcVJlcyA9IGhfc2JyX2RhdGEtPmZyYW1lSW5mby5mcmVxUmVzW2ldOwoKICAgIEZES19BU1NFUlQoZnJlcVJlcyA+PSAwICYmIGZyZXFSZXMgPD0gMSk7CgogICAgbm9fb2ZfYmFuZHMgPSBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5TZmJbZnJlcVJlc107CgogICAgRkRLX0FTU0VSVChub19vZl9iYW5kcyA8ICg2NCkpOwoKICAgIGlmIChkb21haW4gPT0gMCkKICAgIHsKICAgICAgbWFwTG93UmVzRW5lcmd5VmFsKCpwdHJfbnJnLCBzZmJfbnJnX3ByZXYsIG9mZnNldCwgMCwgZnJlcVJlcyk7CiAgICAgIHB0cl9ucmcrKzsKICAgICAgZm9yIChiYW5kID0gMTsgYmFuZCA8IG5vX29mX2JhbmRzOyBiYW5kKyspCiAgICAgIHsKICAgICAgICAqcHRyX25yZyA9ICpwdHJfbnJnICsgKihwdHJfbnJnLTEpOwogICAgICAgIG1hcExvd1Jlc0VuZXJneVZhbCgqcHRyX25yZywgc2ZiX25yZ19wcmV2LCBvZmZzZXQsIGJhbmQsIGZyZXFSZXMpOwogICAgICAgIHB0cl9ucmcrKzsKICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICBmb3IgKGJhbmQgPSAwOyBiYW5kIDwgbm9fb2ZfYmFuZHM7IGJhbmQrKykKICAgICAgewogICAgICAgICpwdHJfbnJnID0gKnB0cl9ucmcgKyBzZmJfbnJnX3ByZXZbaW5kZXhMb3cySGlnaChvZmZzZXQsIGJhbmQsIGZyZXFSZXMpXTsKICAgICAgICBtYXBMb3dSZXNFbmVyZ3lWYWwoKnB0cl9ucmcsIHNmYl9ucmdfcHJldiwgb2Zmc2V0LCBiYW5kLCBmcmVxUmVzKTsKICAgICAgICBwdHJfbnJnKys7CiAgICAgIH0KICAgIH0KICB9Cn0KCgovKiEKICBcYnJpZWYgICBCdWlsZCBuZXcgbm9pc2UgbGV2ZWxzIGZyb20gb2xkIG9uZXMgYW5kIGRlbHRhIGNvZGVkIGRhdGEKKi8Kc3RhdGljIHZvaWQKZGVjb2RlTm9pc2VGbG9vcmxldmVscyAoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwgICAgIC8qITwgU3RhdGljIGNvbnRyb2wgZGF0YSAqLwogICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9zYnJfZGF0YSwgICAgICAgLyohPCBwb2ludGVyIHRvIGN1cnJlbnQgZGF0YSAqLwogICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX1BSRVZfRlJBTUVfREFUQSBoX3ByZXZfZGF0YSkgLyohPCBwb2ludGVyIHRvIHByZXZpb3VzIGRhdGEgKi8KewogIGludCBpOwogIGludCBuTmZiID0gaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5uTmZiOwogIGludCBuTm9pc2VGbG9vckVudmVsb3BlcyA9IGhfc2JyX2RhdGEtPmZyYW1lSW5mby5uTm9pc2VFbnZlbG9wZXM7CgogIC8qIERlY29kZSBmaXJzdCBub2lzZSBlbnZlbG9wZSAqLwoKICBpZiAoaF9zYnJfZGF0YS0+ZG9tYWluX3ZlY19ub2lzZVswXSA9PSAwKSB7CiAgICBGSVhQX1NHTCBub2lzZUxldmVsID0gaF9zYnJfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsWzBdOwogICAgZm9yIChpID0gMTsgaSA8IG5OZmI7IGkrKykgewogICAgICBub2lzZUxldmVsICs9IGhfc2JyX2RhdGEtPnNick5vaXNlRmxvb3JMZXZlbFtpXTsKICAgICAgaF9zYnJfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsW2ldID0gbm9pc2VMZXZlbDsKICAgIH0KICB9CiAgZWxzZSB7CiAgICBmb3IgKGkgPSAwOyBpIDwgbk5mYjsgaSsrKSB7CiAgICAgIGhfc2JyX2RhdGEtPnNick5vaXNlRmxvb3JMZXZlbFtpXSArPSBoX3ByZXZfZGF0YS0+cHJldk5vaXNlTGV2ZWxbaV07CiAgICB9CiAgfQoKICAvKiBJZiBwcmVzZW50LCBkZWNvZGUgdGhlIHNlY29uZCBub2lzZSBlbnZlbG9wZQogICAgIE5vdGU6ICBuTm9pc2VGbG9vckVudmVsb3BlcyBjYW4gb25seSBiZSAxIG9yIDIgKi8KCiAgaWYgKG5Ob2lzZUZsb29yRW52ZWxvcGVzID4gMSkgewogICAgaWYgKGhfc2JyX2RhdGEtPmRvbWFpbl92ZWNfbm9pc2VbMV0gPT0gMCkgewogICAgICBGSVhQX1NHTCBub2lzZUxldmVsID0gaF9zYnJfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsW25OZmJdOwogICAgICBmb3IgKGkgPSBuTmZiICsgMTsgaSA8IDIqbk5mYjsgaSsrKSB7CiAgICAgICAgbm9pc2VMZXZlbCArPSBoX3Nicl9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbaV07CiAgICAgICAgaF9zYnJfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsW2ldID0gbm9pc2VMZXZlbDsKICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgIGZvciAoaSA9IDA7IGkgPCBuTmZiOyBpKyspIHsKICAgICAgICBoX3Nicl9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbaSArIG5OZmJdICs9IGhfc2JyX2RhdGEtPnNick5vaXNlRmxvb3JMZXZlbFtpXTsKICAgICAgfQogICAgfQogIH0KCiAgbGltaXROb2lzZUxldmVscyhoSGVhZGVyRGF0YSwgaF9zYnJfZGF0YSk7CgogIC8qIFVwZGF0ZSBwcmV2Tm9pc2VMZXZlbCB3aXRoIHRoZSBsYXN0IG5vaXNlIGVudmVsb3BlICovCiAgZm9yIChpID0gMDsgaSA8IG5OZmI7IGkrKykKICAgIGhfcHJldl9kYXRhLT5wcmV2Tm9pc2VMZXZlbFtpXSA9IGhfc2JyX2RhdGEtPnNick5vaXNlRmxvb3JMZXZlbFtpICsgbk5mYioobk5vaXNlRmxvb3JFbnZlbG9wZXMtMSldOwoKCiAgLyogUmVxdWFudGl6ZSB0aGUgbm9pc2UgZmxvb3IgbGV2ZWxzIGluIENPVVBMSU5HX09GRi1tb2RlICovCiAgaWYgKCFoX3Nicl9kYXRhLT5jb3VwbGluZykgewogICAgaW50IG5mX2U7CgogICAgZm9yIChpID0gMDsgaSA8IG5Ob2lzZUZsb29yRW52ZWxvcGVzKm5OZmI7IGkrKykgewogICAgICBuZl9lID0gNiAtIChMT05HKWhfc2JyX2RhdGEtPnNick5vaXNlRmxvb3JMZXZlbFtpXSArIDEgKyBOT0lTRV9FWFBfT0ZGU0VUOwogICAgICAvKiArMSB0byBjb21wZW5zYXRlIGZvciBhIG1hbnRpc3NhIG9mIDAuNSBpbnN0ZWFkIG9mIDEuMCAqLwoKICAgICAgaF9zYnJfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsW2ldID0KICAgICAgICAoRklYUF9TR0wpKCAoKExPTkcpRkwyRlhDT05TVF9TR0woMC41ZikpICsgIC8qIG1hbnRpc3NhICovCiAgICAgICAgICAgICAgICAgIChuZl9lICYgTUFTS19FKSApOyAvKiBleHBvbmVudCAqLwoKICAgIH0KICB9Cn0K