Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiEKICBcZmlsZQogIFxicmllZiAgZW52ZWxvcGUgZGVjb2RpbmcgIAogIFRoaXMgbW9kdWxlIHByb3ZpZGVzIGVudmVsb3BlIGRlY29kaW5nIGFuZCBlcnJvciBjb25jZWFsbWVudCBhbGdvcml0aG1zLiBUaGUgbWFpbgogIGVudHJ5IHBvaW50IGlzIGRlY29kZVNickRhdGEoKS4KCiAgXHNhIGRlY29kZVNickRhdGEoKSxccmVmIGRvY3VtZW50YXRpb25PdmVydmlldwoqLwoKI2luY2x1ZGUgImVudl9kZWMuaCIKCiNpbmNsdWRlICJlbnZfZXh0ci5oIgojaW5jbHVkZSAidHJhbnNjZW5kZW50LmgiCgojaW5jbHVkZSAiZ2VuZXJpY1N0ZHMuaCIKCgpzdGF0aWMgdm9pZCBkZWNvZGVFbnZlbG9wZSAoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSBoX3Nicl9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgaF9wcmV2X2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX1BSRVZfRlJBTUVfREFUQSBoX3ByZXZfZGF0YV9vdGhlckNoYW5uZWwpOwpzdGF0aWMgdm9pZCBzYnJfZW52ZWxvcGVfdW5tYXBwaW5nIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9kYXRhX2xlZnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSBoX2RhdGFfcmlnaHQpOwpzdGF0aWMgdm9pZCByZXF1YW50aXplRW52ZWxvcGVEYXRhIChIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9zYnJfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGFtcFJlc29sdXRpb24pOwpzdGF0aWMgdm9pZCBkZWx0YVRvTGluZWFyUGNtRW52ZWxvcGVEZWNvZGluZyAoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSBoX3Nicl9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgaF9wcmV2X2RhdGEpOwpzdGF0aWMgdm9pZCBkZWNvZGVOb2lzZUZsb29ybGV2ZWxzIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9zYnJfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgaF9wcmV2X2RhdGEpOwpzdGF0aWMgdm9pZCB0aW1lQ29tcGVuc2F0ZUZpcnN0RW52ZWxvcGUgKEhBTkRMRV9TQlJfSEVBREVSX0RBVEEgaEhlYWRlckRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBIGhfc2JyX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgaF9wcmV2X2RhdGEpOwpzdGF0aWMgaW50IGNoZWNrRW52ZWxvcGVEYXRhIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9zYnJfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgaF9wcmV2X2RhdGEpOwoKCgojZGVmaW5lIFNCUl9FTkVSR1lfUEFOX09GRlNFVCAgICgxMiA8PCBFTlZfRVhQX0ZSQUNUKQojZGVmaW5lIFNCUl9NQVhfRU5FUkdZICAgICAgICAgICgzNSA8PCBFTlZfRVhQX0ZSQUNUKQoKI2RlZmluZSBERUNBWSAgICAgICAgICAgICAgICAgICAoIDEgPDwgRU5WX0VYUF9GUkFDVCkKCiNpZiBFTlZfRVhQX0ZSQUNUCiNkZWZpbmUgREVDQVlfQ09VUExJTkcgICAgICAgICAgKCAxIDw8IChFTlZfRVhQX0ZSQUNULTEpICkgLyohPCBjb3JyZXNwb25kcyB0byBhIHZhbHVlIG9mIDAuNSAqLwojZWxzZQojZGVmaW5lIERFQ0FZX0NPVVBMSU5HICAgICAgICAgICAgMSAgLyohPCBJZiB0aGUgZW5lcmd5IGRhdGEgaXMgbm90IHNoaWZ0ZWQsIHVzZSAxIGluc3RlYWQgb2YgMC41ICovCiNlbmRpZgoKCi8qIQogIFxicmllZiAgQ29udmVydCB0YWJsZSBpbmRleAoqLwpzdGF0aWMgaW50IGluZGV4TG93MkhpZ2goaW50IG9mZnNldCwgLyohPCBtYXBwaW5nIGZhY3RvciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluZGV4LCAgLyohPCBpbmRleCB0byBzY2FsZWZhY3RvciBiYW5kICovCiAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgcmVzKSAgICAvKiE8IGZyZXF1ZW5jeSByZXNvbHV0aW9uICovCnsKICBpZihyZXMgPT0gMCkKICB7CiAgICBpZiAob2Zmc2V0ID49IDApCiAgICB7CiAgICAgICAgaWYgKGluZGV4IDwgb2Zmc2V0KQogICAgICAgICAgcmV0dXJuKGluZGV4KTsKICAgICAgICBlbHNlCiAgICAgICAgICByZXR1cm4oMippbmRleCAtIG9mZnNldCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgb2Zmc2V0ID0gLW9mZnNldDsKICAgICAgICBpZiAoaW5kZXggPCBvZmZzZXQpCiAgICAgICAgICByZXR1cm4oMippbmRleCtpbmRleCk7CiAgICAgICAgZWxzZQogICAgICAgICAgcmV0dXJuKDIqaW5kZXggKyBvZmZzZXQpOwogICAgfQogIH0KICBlbHNlCiAgICByZXR1cm4oaW5kZXgpOwp9CgoKLyohCiAgXGJyaWVmICBVcGRhdGUgcHJldmlvdXMgZW52ZWxvcGUgdmFsdWUgZm9yIGRlbHRhLWNvZGluZwoKICBUaGUgY3VycmVudCBlbnZlbG9wZSB2YWx1ZXMgbmVlZHMgdG8gYmUgc3RvcmVkIGZvciBkZWx0YS1jb2RpbmcKICBpbiB0aGUgbmV4dCBmcmFtZS4gIFRoZSBzdG9yZWQgZW52ZWxvcGUgaXMgYWx3YXlzIHJlcHJlc2VudGVkIHdpdGgKICB0aGUgaGlnaCBmcmVxdWVuY3kgcmVzb2x1dGlvbi4gIElmIHRoZSBjdXJyZW50IGVudmVsb3BlIHVzZXMgdGhlCiAgbG93IGZyZXF1ZW5jeSByZXNvbHV0aW9uLCB0aGUgZW5lcmd5IHZhbHVlIHdpbGwgYmUgbWFwcGVkIHRvIHRoZQogIGNvcnJlc3BvbmRpbmcgaGlnaC1yZXMgYmFuZHMuCiovCnN0YXRpYyB2b2lkIG1hcExvd1Jlc0VuZXJneVZhbChGSVhQX1NHTCBjdXJyVmFsLCAgLyohPCBjdXJyZW50IGVuZXJneSB2YWx1ZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYUF9TR0wqIHByZXZEYXRhLC8qITwgcG9pbnRlciB0byBwcmV2aW91cyBkYXRhIHZlY3RvciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG9mZnNldCwgICAgICAvKiE8IG1hcHBpbmcgZmFjdG9yICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW5kZXgsICAgICAgIC8qITwgaW5kZXggdG8gc2NhbGVmYWN0b3IgYmFuZCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHJlcykgICAgICAgICAvKiE8IGZyZXF1ZW55IHJlc29sdXRpb24gKi8KewogIGlmKHJlcyA9PSAwKQogIHsKICAgIGlmIChvZmZzZXQgPj0gMCkKICAgIHsKICAgICAgICBpZihpbmRleCA8IG9mZnNldCkKICAgICAgICAgICAgcHJldkRhdGFbaW5kZXhdID0gY3VyclZhbDsKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBwcmV2RGF0YVsyKmluZGV4IC0gb2Zmc2V0XSA9IGN1cnJWYWw7CiAgICAgICAgICAgIHByZXZEYXRhWzIqaW5kZXgrMSAtIG9mZnNldF0gPSBjdXJyVmFsOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBvZmZzZXQgPSAtb2Zmc2V0OwogICAgICAgIGlmIChpbmRleCA8IG9mZnNldCkKICAgICAgICB7CiAgICAgICAgICAgIHByZXZEYXRhWzMqaW5kZXhdID0gY3VyclZhbDsKICAgICAgICAgICAgcHJldkRhdGFbMyppbmRleCsxXSA9IGN1cnJWYWw7CiAgICAgICAgICAgIHByZXZEYXRhWzMqaW5kZXgrMl0gPSBjdXJyVmFsOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBwcmV2RGF0YVsyKmluZGV4ICsgb2Zmc2V0XSA9IGN1cnJWYWw7CiAgICAgICAgICAgIHByZXZEYXRhWzIqaW5kZXggKyAxICsgb2Zmc2V0XSA9IGN1cnJWYWw7CiAgICAgICAgfQogICAgfQogIH0KICBlbHNlCiAgICBwcmV2RGF0YVtpbmRleF0gPSBjdXJyVmFsOwp9CgoKCi8qIQogIFxicmllZiAgICBDb252ZXJ0IHJhdyBlbnZlbG9wZSBhbmQgbm9pc2VmbG9vciBkYXRhIHRvIGVuZXJneSBsZXZlbHMKCiAgVGhpcyBmdW5jdGlvbiBpcyBiZWluZyBjYWxsZWQgYnkgc2JyRGVjb2Rlcl9QYXJzZUVsZW1lbnQoKSBhbmQgcHJvdmlkZXMgdHdvIGltcG9ydGFudCBhbGdvcml0aG1zOgoKICBGaXJzdCB0aGUgZnVuY3Rpb24gZGVjb2RlcyBlbnZlbG9wZXMgYW5kIG5vaXNlIGZsb29yIGxldmVscyBhcyBkZXNjcmliZWQgaW4gcmVxdWFudGl6ZUVudmVsb3BlRGF0YSgpCiAgYW5kIHNicl9lbnZlbG9wZV91bm1hcHBpbmcoKS4gVGhlIGZ1bmN0aW9uIGFsc28gaW1wbGVtZW50cyBjb25jZWFsbWVudCBhbGdvcml0aG1zIGluIGNhc2UgdGhlcmUgYXJlIGVycm9ycwogIHdpdGhpbiB0aGUgc2JyIGRhdGEuIEZvciBib3RoIG9wZXJhdGlvbnMgZnJhY3Rpb25hbCBhcml0aG1ldGljIGlzIHVzZWQuCiAgVGhlcmVmb3JlIHlvdSBtaWdodCBlbmNvdW50ZXIgZGlmZmVyZW50IG91dHB1dCB2YWx1ZXMgb24geW91ciB0YXJnZXQKICBzeXN0ZW0gY29tcGFyZWQgdG8gdGhlIHJlZmVyZW5jZSBpbXBsZW1lbnRhdGlvbi4KKi8Kdm9pZApkZWNvZGVTYnJEYXRhIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLCAgICAgICAgICAvKiE8IFN0YXRpYyBjb250cm9sIGRhdGEgKi8KICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBIGhfZGF0YV9sZWZ0LCAgICAgICAgICAgLyohPCBwb2ludGVyIHRvIGxlZnQgY2hhbm5lbCBmcmFtZSBkYXRhICovCiAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfUFJFVl9GUkFNRV9EQVRBIGhfcHJldl9kYXRhX2xlZnQsIC8qITwgcG9pbnRlciB0byBsZWZ0IGNoYW5uZWwgcHJldmlvdXMgZnJhbWUgZGF0YSAqLwogICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9kYXRhX3JpZ2h0LCAgICAgICAgICAvKiE8IHBvaW50ZXIgdG8gcmlnaHQgY2hhbm5lbCBmcmFtZSBkYXRhICovCiAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfUFJFVl9GUkFNRV9EQVRBIGhfcHJldl9kYXRhX3JpZ2h0KS8qITwgcG9pbnRlciB0byByaWdodCBjaGFubmVsIHByZXZpb3VzIGZyYW1lIGRhdGEgKi8KewogIEZJWFBfU0dMIHRlbXBTZmJOcmdQcmV2W01BWF9GUkVRX0NPRUZGU107CiAgaW50IGVyckxlZnQ7CgogIC8qIFNhdmUgcHJldmlvdXMgZW5lcmd5IHZhbHVlcyB0byBiZSBhYmxlIHRvIHJldXNlIHRoZW0gbGF0ZXIgZm9yIGNvbmNlYWxtZW50LiAqLwogIEZES21lbWNweSAodGVtcFNmYk5yZ1ByZXYsIGhfcHJldl9kYXRhX2xlZnQtPnNmYl9ucmdfcHJldiwgTUFYX0ZSRVFfQ09FRkZTICogc2l6ZW9mKEZJWFBfU0dMKSk7CgogIGRlY29kZUVudmVsb3BlIChoSGVhZGVyRGF0YSwgaF9kYXRhX2xlZnQsIGhfcHJldl9kYXRhX2xlZnQsIGhfcHJldl9kYXRhX3JpZ2h0KTsKICBkZWNvZGVOb2lzZUZsb29ybGV2ZWxzIChoSGVhZGVyRGF0YSwgaF9kYXRhX2xlZnQsIGhfcHJldl9kYXRhX2xlZnQpOwoKICBpZihoX2RhdGFfcmlnaHQgIT0gTlVMTCkgewogICAgZXJyTGVmdCA9IGhIZWFkZXJEYXRhLT5mcmFtZUVycm9yRmxhZzsKICAgIGRlY29kZUVudmVsb3BlIChoSGVhZGVyRGF0YSwgaF9kYXRhX3JpZ2h0LCBoX3ByZXZfZGF0YV9yaWdodCwgaF9wcmV2X2RhdGFfbGVmdCk7CiAgICBkZWNvZGVOb2lzZUZsb29ybGV2ZWxzIChoSGVhZGVyRGF0YSwgaF9kYXRhX3JpZ2h0LCBoX3ByZXZfZGF0YV9yaWdodCk7CgogICAgaWYgKCFlcnJMZWZ0ICYmIGhIZWFkZXJEYXRhLT5mcmFtZUVycm9yRmxhZykgewogICAgICAvKiBJZiBhbiBlcnJvciBvY2N1cnMgaW4gdGhlIHJpZ2h0IGNoYW5uZWwgd2hlcmUgdGhlIGxlZnQgY2hhbm5lbCBzZWVtZWQgb2ssCiAgICAgICAgIHdlIGFwcGx5IGNvbmNlYWxtZW50IGFsc28gb24gdGhlIGxlZnQgY2hhbm5lbC4gVGhpcyBlbnN1cmVzIHRoYXQgdGhlIGNvdXBsaW5nCiAgICAgICAgIG1vZGVzIG9mIGJvdGggY2hhbm5lbHMgbWF0Y2ggYW5kIHRoYXQgd2UgaGF2ZSB0aGUgc2FtZSBudW1iZXIgb2YgZW52ZWxvcGVzIGluCiAgICAgICAgIGNvdXBsaW5nIG1vZGUuCiAgICAgICAgIEhvd2V2ZXIsIGFzIHRoZSBsZWZ0IGNoYW5uZWwgaGFzIGFscmVhZHkgYmVlbiBwcm9jZXNzZWQgYmVmb3JlLCB0aGUgcmVzdWx0aW5nCiAgICAgICAgIGVuZXJneSBsZXZlbHMgYXJlIG5vdCB0aGUgc2FtZSBhcyBpZiB0aGUgbGVmdCBjaGFubmVsIGhhZCBiZWVuIGNvbmNlYWxlZAogICAgICAgICBkdXJpbmcgdGhlIGZpcnN0IGNhbGwgb2YgZGVjb2RlRW52ZWxvcGUoKS4KICAgICAgKi8KICAgICAgLyogUmVzdG9yZSBwcmV2aW91cyBlbmVyZ3kgdmFsdWVzIGZvciBjb25jZWFsbWVudCwgYmVjYXVzZSB0aGUgdmFsdWVzIGhhdmUgYmVlbgogICAgICAgICBvdmVyd3JpdHRlbiBieSB0aGUgZmlyc3QgY2FsbCBvZiBkZWNvZGVFbnZlbG9wZSgpLiAqLwogICAgICBGREttZW1jcHkgKGhfcHJldl9kYXRhX2xlZnQtPnNmYl9ucmdfcHJldiwgdGVtcFNmYk5yZ1ByZXYsIE1BWF9GUkVRX0NPRUZGUyAqIHNpemVvZihGSVhQX1NHTCkpOwogICAgICAvKiBEbyBjb25jZWFsbWVudCAqLwogICAgICBkZWNvZGVFbnZlbG9wZSAoaEhlYWRlckRhdGEsIGhfZGF0YV9sZWZ0LCBoX3ByZXZfZGF0YV9sZWZ0LCBoX3ByZXZfZGF0YV9yaWdodCk7CiAgICB9CgogICAgaWYgKGhfZGF0YV9sZWZ0LT5jb3VwbGluZykgewogICAgICBzYnJfZW52ZWxvcGVfdW5tYXBwaW5nIChoSGVhZGVyRGF0YSwgaF9kYXRhX2xlZnQsIGhfZGF0YV9yaWdodCk7CiAgICB9CiAgfQoKICAvKiBEaXNwbGF5IHRoZSBkYXRhIGZvciBkZWJ1Z2dpbmc6ICovCn0KCgovKiEKICBcYnJpZWYgICBDb252ZXJ0IGZyb20gY291cGxlZCBjaGFubmVscyB0byBpbmRlcGVuZGVudCBML1IgZGF0YQoqLwpzdGF0aWMgdm9pZApzYnJfZW52ZWxvcGVfdW5tYXBwaW5nIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLCAvKiE8IFN0YXRpYyBjb250cm9sIGRhdGEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBIGhfZGF0YV9sZWZ0LCAgLyohPCBwb2ludGVyIHRvIGxlZnQgY2hhbm5lbCAqLwogICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9kYXRhX3JpZ2h0KSAvKiE8IHBvaW50ZXIgdG8gcmlnaHQgY2hhbm5lbCAqLwp7CiAgaW50IGk7CiAgRklYUF9TR0wgdGVtcExfbSwgdGVtcFJfbSwgdGVtcFJwbHVzMV9tLCBuZXdMX20sIG5ld1JfbTsKICBTQ0hBUiAgIHRlbXBMX2UsIHRlbXBSX2UsIHRlbXBScGx1czFfZSwgbmV3TF9lLCBuZXdSX2U7CgoKICAvKiAxLiBVbm1hcCAoYWxyZWFkeSBkZXF1YW50aXplZCkgY291cGxlZCBlbnZlbG9wZSBlbmVyZ2llcyAqLwoKICBmb3IgKGkgPSAwOyBpIDwgaF9kYXRhX2xlZnQtPm5TY2FsZUZhY3RvcnM7IGkrKykgewogICAgdGVtcFJfbSA9IChGSVhQX1NHTCkoKExPTkcpaF9kYXRhX3JpZ2h0LT5pRW52ZWxvcGVbaV0gJiBNQVNLX00pOwogICAgdGVtcFJfZSA9IChTQ0hBUikoKExPTkcpaF9kYXRhX3JpZ2h0LT5pRW52ZWxvcGVbaV0gJiBNQVNLX0UpOwoKICAgIHRlbXBSX2UgLT0gKDE4ICsgTlJHX0VYUF9PRkZTRVQpOyAgLyogLTE4ID0gbGQoVU5NQVBQSU5HX1NDQUxFIC8gaF9kYXRhX3JpZ2h0LT5uQ2hhbm5lbHMpICovCiAgICB0ZW1wTF9tID0gKEZJWFBfU0dMKSgoTE9ORyloX2RhdGFfbGVmdC0+aUVudmVsb3BlW2ldICYgTUFTS19NKTsKICAgIHRlbXBMX2UgPSAoU0NIQVIpKChMT05HKWhfZGF0YV9sZWZ0LT5pRW52ZWxvcGVbaV0gJiBNQVNLX0UpOwoKICAgIHRlbXBMX2UgLT0gTlJHX0VYUF9PRkZTRVQ7CgogICAgLyogQ2FsY3VsYXRlIHRlbXBSaWdodCsxICovCiAgICBGREtfYWRkX01hbnRFeHAoIHRlbXBSX20sIHRlbXBSX2UsCiAgICAgICAgICAgICAgICAgICAgIEZMMkZYQ09OU1RfU0dMKDAuNWYpLCAxLCAgLyogMS4wICovCiAgICAgICAgICAgICAgICAgICAgICZ0ZW1wUnBsdXMxX20sICZ0ZW1wUnBsdXMxX2UpOwoKICAgIEZES19kaXZpZGVfTWFudEV4cCggdGVtcExfbSwgdGVtcExfZSsxLCAgLyogIDIgKiB0ZW1wTGVmdCAqLwogICAgICAgICAgICAgICAgICAgICAgIHRlbXBScGx1czFfbSwgdGVtcFJwbHVzMV9lLAogICAgICAgICAgICAgICAgICAgICAgICZuZXdSX20sICZuZXdSX2UgKTsKCiAgICBpZiAobmV3Ul9tID49ICgoRklYUF9TR0wpTUFYVkFMX1NHTCAtIFJPVU5ESU5HKSkgewogICAgICBuZXdSX20gPj49IDE7CiAgICAgIG5ld1JfZSArPSAxOwogICAgfQoKICAgIG5ld0xfbSA9IEZYX0RCTDJGWF9TR0woZk11bHQodGVtcFJfbSxuZXdSX20pKTsKICAgIG5ld0xfZSA9IHRlbXBSX2UgKyBuZXdSX2U7CgogICAgaF9kYXRhX3JpZ2h0LT5pRW52ZWxvcGVbaV0gPSAoKEZJWFBfU0dMKSgoU0hPUlQpKEZJWFBfU0dMKShuZXdSX20gKyBST1VORElORykgJiBNQVNLX00pKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRklYUF9TR0wpKChTSE9SVCkoRklYUF9TR0wpKG5ld1JfZSArIE5SR19FWFBfT0ZGU0VUKSAmIE1BU0tfRSk7CiAgICBoX2RhdGFfbGVmdC0+aUVudmVsb3BlW2ldID0gICgoRklYUF9TR0wpKChTSE9SVCkoRklYUF9TR0wpKG5ld0xfbSArIFJPVU5ESU5HKSAmIE1BU0tfTSkpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChGSVhQX1NHTCkoKFNIT1JUKShGSVhQX1NHTCkobmV3TF9lICsgTlJHX0VYUF9PRkZTRVQpICYgTUFTS19FKTsKICB9CgogIC8qIDIuIERlcXVhbnRpemUgYW5kIHVubWFwIGNvdXBsZWQgbm9pc2UgZmxvb3IgbGV2ZWxzICovCgogIGZvciAoaSA9IDA7IGkgPCBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5OZmIgKiBoX2RhdGFfbGVmdC0+ZnJhbWVJbmZvLm5Ob2lzZUVudmVsb3BlczsgaSsrKSB7CgogICAgdGVtcExfZSA9IChTQ0hBUikoNiAtIChMT05HKWhfZGF0YV9sZWZ0LT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0pOwogICAgdGVtcFJfZSA9IChTQ0hBUikoKExPTkcpaF9kYXRhX3JpZ2h0LT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0gLSAxMikgLypTQlJfRU5FUkdZX1BBTl9PRkZTRVQqLzsKCiAgICAvKiBDYWxjdWxhdGUgdGVtcFIrMSAqLwogICAgRkRLX2FkZF9NYW50RXhwKCBGTDJGWENPTlNUX1NHTCgwLjVmKSwgMSt0ZW1wUl9lLCAvKiB0ZW1wUiAqLwogICAgICAgICAgICAgICAgICAgICBGTDJGWENPTlNUX1NHTCgwLjVmKSwgMSwgICAgICAgICAvKiAgMS4wICAqLwogICAgICAgICAgICAgICAgICAgICAmdGVtcFJwbHVzMV9tLCAmdGVtcFJwbHVzMV9lKTsKCiAgICAvKiBDYWxjdWxhdGUgMip0ZW1wTGVmdC8odGVtcFIrMSkgKi8KICAgIEZES19kaXZpZGVfTWFudEV4cCggRkwyRlhDT05TVF9TR0woMC41ZiksIHRlbXBMX2UrMiwgIC8qICAyICogdGVtcExlZnQgKi8KICAgICAgICAgICAgICAgICAgICAgICB0ZW1wUnBsdXMxX20sIHRlbXBScGx1czFfZSwKICAgICAgICAgICAgICAgICAgICAgICAmbmV3Ul9tLCAmbmV3Ul9lICk7CgogICAgLyogaWYgKG5ld1JfbSA+PSAoKEZJWFBfU0dMKU1BWFZBTF9TR0wgLSBST1VORElORykpIHsKICAgICAgbmV3Ul9tID4+PSAxOwogICAgICBuZXdSX2UgKz0gMTsKICAgIH0gKi8KCiAgICAvKiBMID0gdGVtcFIgKiBSICovCiAgICBuZXdMX20gPSBuZXdSX207CiAgICBuZXdMX2UgPSBuZXdSX2UgKyB0ZW1wUl9lOwogICAgaF9kYXRhX3JpZ2h0LT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0gPSAoKEZJWFBfU0dMKSgoU0hPUlQpKEZJWFBfU0dMKShuZXdSX20gKyBST1VORElORykgJiBNQVNLX00pKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRklYUF9TR0wpKChTSE9SVCkoRklYUF9TR0wpKG5ld1JfZSArIE5PSVNFX0VYUF9PRkZTRVQpICYgTUFTS19FKTsKICAgIGhfZGF0YV9sZWZ0LT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0gPSAgKChGSVhQX1NHTCkoKFNIT1JUKShGSVhQX1NHTCkobmV3TF9tICsgUk9VTkRJTkcpICYgTUFTS19NKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEZJWFBfU0dMKSgoU0hPUlQpKEZJWFBfU0dMKShuZXdMX2UgKyBOT0lTRV9FWFBfT0ZGU0VUKSAmIE1BU0tfRSk7CiAgfQp9CgoKLyohCiAgXGJyaWVmICAgIFNpbXBsZSBhbHRlcm5hdGl2ZSB0byB0aGUgcmVhbCBTQlIgY29uY2VhbG1lbnQKCiAgSWYgdGhlIHJlYWwgZnJhbWVJbmZvIGlzIG5vdCBhdmFpbGFibGUgZHVlIHRvIGEgZnJhbWUgbG9zcywgYSByZXBsYWNlbWVudCB3aWxsCiAgYmUgY29uc3RydWN0ZWQgd2l0aCAxIGVudmVsb3BlIHNwYW5uaW5nIHRoZSB3aG9sZSBmcmFtZSAoRklYLUZJWCkuCiAgVGhlIGRlbHRhLWNvZGVkIGVuZXJnaWVzIGFyZSBzZXQgdG8gbmVnYXRpdmUgdmFsdWVzLCByZXN1bHRpbmcgaW4gYSBmYWRlLWRvd24uCiAgSW4gY2FzZSBvZiBjb3VwbGluZywgdGhlIGJhbGFuY2UtY2hhbm5lbCB3aWxsIG1vdmUgdG93YXJkcyB0aGUgY2VudGVyLgoqLwpzdGF0aWMgdm9pZApsZWFuU2JyQ29uY2VhbG1lbnQoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwgICAgIC8qITwgU3RhdGljIGNvbnRyb2wgZGF0YSAqLwogICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBICBoX3Nicl9kYXRhLCAgICAgIC8qITwgcG9pbnRlciB0byBjdXJyZW50IGRhdGEgKi8KICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfUFJFVl9GUkFNRV9EQVRBIGhfcHJldl9kYXRhICAvKiE8IHBvaW50ZXIgdG8gZGF0YSBvZiBsYXN0IGZyYW1lICovCiAgICAgICAgICAgICAgICAgICApCnsKICBGSVhQX1NHTCB0YXJnZXQ7ICAvKiB0YXJnZXRlZCBsZXZlbCBmb3Igc2ZiX25yZ19wcmV2IGR1cmluZyBmYWRlLWRvd24gKi8KICBGSVhQX1NHTCBzdGVwOyAgICAvKiBzcGVlZCBvZiBmYWRlICovCiAgaW50IGk7CgogIGludCBjdXJyZW50U3RhcnRQb3MgPSBGREttYXgoMCwgaF9wcmV2X2RhdGEtPnN0b3BQb3MgLSBoSGVhZGVyRGF0YS0+bnVtYmVyVGltZVNsb3RzKTsKICBpbnQgY3VycmVudFN0b3BQb3MgPSBoSGVhZGVyRGF0YS0+bnVtYmVyVGltZVNsb3RzOwoKCiAgLyogVXNlIHNvbWUgc2V0dGluZ3Mgb2YgdGhlIHByZXZpb3VzIGZyYW1lICovCiAgaF9zYnJfZGF0YS0+YW1wUmVzb2x1dGlvbkN1cnJlbnRGcmFtZSA9IGhfcHJldl9kYXRhLT5hbXBSZXM7CiAgaF9zYnJfZGF0YS0+Y291cGxpbmcgPSBoX3ByZXZfZGF0YS0+Y291cGxpbmc7CiAgZm9yKGk9MDtpPE1BWF9JTlZGX0JBTkRTO2krKykKICAgIGhfc2JyX2RhdGEtPnNicl9pbnZmX21vZGVbaV0gPSBoX3ByZXZfZGF0YS0+c2JyX2ludmZfbW9kZVtpXTsKCiAgLyogR2VuZXJhdGUgY29uY2VhbGluZyBjb250cm9sIGRhdGEgKi8KCiAgaF9zYnJfZGF0YS0+ZnJhbWVJbmZvLm5FbnZlbG9wZXMgPSAxOwogIGhfc2JyX2RhdGEtPmZyYW1lSW5mby5ib3JkZXJzWzBdID0gY3VycmVudFN0YXJ0UG9zOwogIGhfc2JyX2RhdGEtPmZyYW1lSW5mby5ib3JkZXJzWzFdID0gY3VycmVudFN0b3BQb3M7CiAgaF9zYnJfZGF0YS0+ZnJhbWVJbmZvLmZyZXFSZXNbMF0gPSAxOwogIGhfc2JyX2RhdGEtPmZyYW1lSW5mby50cmFuRW52ID0gLTE7ICAvKiBubyB0cmFuc2llbnQgKi8KICBoX3Nicl9kYXRhLT5mcmFtZUluZm8ubk5vaXNlRW52ZWxvcGVzID0gMTsKICBoX3Nicl9kYXRhLT5mcmFtZUluZm8uYm9yZGVyc05vaXNlWzBdID0gY3VycmVudFN0YXJ0UG9zOwogIGhfc2JyX2RhdGEtPmZyYW1lSW5mby5ib3JkZXJzTm9pc2VbMV0gPSBjdXJyZW50U3RvcFBvczsKCiAgaF9zYnJfZGF0YS0+blNjYWxlRmFjdG9ycyA9IGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEublNmYlsxXTsKCiAgLyogR2VuZXJhdGUgZmFrZSBlbnZlbG9wZSBkYXRhICovCgogIGhfc2JyX2RhdGEtPmRvbWFpbl92ZWNbMF0gPSAxOwoKICBpZiAoaF9zYnJfZGF0YS0+Y291cGxpbmcgPT0gQ09VUExJTkdfQkFMKSB7CiAgICB0YXJnZXQgPSAoRklYUF9TR0wpU0JSX0VORVJHWV9QQU5fT0ZGU0VUOwogICAgc3RlcCA9IChGSVhQX1NHTClERUNBWV9DT1VQTElORzsKICB9CiAgZWxzZSB7CiAgICB0YXJnZXQgPSBGTDJGWENPTlNUX1NHTCgwLjBmKTsKICAgIHN0ZXAgICA9IChGSVhQX1NHTClERUNBWTsKICB9CiAgaWYgKGhIZWFkZXJEYXRhLT5ic19pbmZvLmFtcFJlc29sdXRpb24gPT0gMCkgewogICAgdGFyZ2V0IDw8PSAxOwogICAgc3RlcCAgIDw8PSAxOwogIH0KCiAgZm9yIChpPTA7IGkgPCBoX3Nicl9kYXRhLT5uU2NhbGVGYWN0b3JzOyBpKyspIHsKICAgIGlmIChoX3ByZXZfZGF0YS0+c2ZiX25yZ19wcmV2W2ldID4gdGFyZ2V0KQogICAgICBoX3Nicl9kYXRhLT5pRW52ZWxvcGVbaV0gPSAtc3RlcDsKICAgIGVsc2UKICAgICAgaF9zYnJfZGF0YS0+aUVudmVsb3BlW2ldID0gc3RlcDsKICB9CgogIC8qIE5vaXNlZmxvb3IgbGV2ZWxzIGFyZSBhbHdheXMgY2xlYXJlZCAuLi4gKi8KCiAgaF9zYnJfZGF0YS0+ZG9tYWluX3ZlY19ub2lzZVswXSA9IDE7CiAgZm9yIChpPTA7IGkgPCBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5OZmI7IGkrKykKICAgIGhfc2JyX2RhdGEtPnNick5vaXNlRmxvb3JMZXZlbFtpXSA9IEZMMkZYQ09OU1RfU0dMKDAuMGYpOwoKICAvKiAuLi4gYW5kIHNvIGFyZSB0aGUgc2luZXMgKi8KICBGREttZW1jbGVhcihoX3Nicl9kYXRhLT5hZGRIYXJtb25pY3MsIE1BWF9GUkVRX0NPRUZGUyk7Cn0KCgovKiEKICBcYnJpZWYgICBCdWlsZCByZWZlcmVuY2UgZW5lcmdpZXMgYW5kIG5vaXNlIGxldmVscyBmcm9tIGJpdHN0cmVhbSBlbGVtZW50cwoqLwpzdGF0aWMgdm9pZApkZWNvZGVFbnZlbG9wZSAoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwgICAgIC8qITwgU3RhdGljIGNvbnRyb2wgZGF0YSAqLwogICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBICBoX3Nicl9kYXRhLCAgICAgIC8qITwgcG9pbnRlciB0byBjdXJyZW50IGRhdGEgKi8KICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfUFJFVl9GUkFNRV9EQVRBIGhfcHJldl9kYXRhLCAvKiE8IHBvaW50ZXIgdG8gZGF0YSBvZiBsYXN0IGZyYW1lICovCiAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX1BSRVZfRlJBTUVfREFUQSBvdGhlckNoYW5uZWwgLyohPCBvdGhlciBjaGFubmVsJ3MgbGFzdCBmcmFtZSBkYXRhICovCiAgICAgICAgICAgICAgICApCnsKICBpbnQgaTsKICBpbnQgZkZyYW1lRXJyb3IgPSBoSGVhZGVyRGF0YS0+ZnJhbWVFcnJvckZsYWc7CiAgRklYUF9TR0wgdGVtcFNmYk5yZ1ByZXZbTUFYX0ZSRVFfQ09FRkZTXTsKCiAgaWYgKCFmRnJhbWVFcnJvcikgewogICAgLyoKICAgICAgVG8gYXZvaWQgZGlzdG9ydGlvbnMgYWZ0ZXIgYmFkIGZyYW1lcywgc2V0IHRoZSBlcnJvciBmbGFnIGlmIGRlbHRhIGNvZGluZyBpbiB0aW1lIG9jY3Vycy4KICAgICAgSG93ZXZlciwgU0JSIGNhbiB0YWtlIGEgbGl0dGxlIGxvbmdlciB0byBjb21lIHVwIGFnYWluLgogICAgKi8KICAgIGlmICggaF9wcmV2X2RhdGEtPmZyYW1lRXJyb3JGbGFnICkgewogICAgICBpZiAoaF9zYnJfZGF0YS0+ZG9tYWluX3ZlY1swXSAhPSAwKSB7CiAgICAgICAgZkZyYW1lRXJyb3IgPSAxOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAvKiBDaGVjayB0aGF0IHRoZSBwcmV2aW91cyBzdG9wIHBvc2l0aW9uIGFuZCB0aGUgY3VycmVudCBzdGFydCBwb3NpdGlvbiBtYXRjaC4KICAgICAgICAgKENvdWxkIGJlIGRvbmUgaW4gY2hlY2tGcmFtZUluZm8oKSwgYnV0IHRoZSBwcmV2aW91cyBmcmFtZSBkYXRhIGlzIG5vdCBhdmFpbGFibGUgdGhlcmUpICovCiAgICAgIGlmICggaF9zYnJfZGF0YS0+ZnJhbWVJbmZvLmJvcmRlcnNbMF0gIT0gaF9wcmV2X2RhdGEtPnN0b3BQb3MgLSBoSGVhZGVyRGF0YS0+bnVtYmVyVGltZVNsb3RzICkgewogICAgICAgIC8qIEJvdGggdGhlIHByZXZpb3VzIGFzIHdlbGwgYXMgdGhlIGN1cnJlbnQgZnJhbWUgYXJlIGZsYWdnZWQgdG8gYmUgb2ssIGJ1dCB0aGV5IGRvIG5vdCBtYXRjaCEgKi8KICAgICAgICBpZiAoaF9zYnJfZGF0YS0+ZG9tYWluX3ZlY1swXSA9PSAxKSB7CiAgICAgICAgICAvKiBQcmVmZXIgY29uY2VhbG1lbnQgb3ZlciBkZWx0YS10aW1lIGNvZGluZyBiZXR3ZWVuIHRoZSBtaXNtYXRjaGluZyBmcmFtZXMgKi8KICAgICAgICAgIGZGcmFtZUVycm9yID0gMTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAvKiBDbG9zZSB0aGUgZ2FwIGluIHRpbWUgYnkgdHJpZ2dlcmluZyB0aW1lQ29tcGVuc2F0ZUZpcnN0RW52ZWxvcGUoKSAqLwogICAgICAgICAgZkZyYW1lRXJyb3IgPSAxOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCgogIGlmIChmRnJhbWVFcnJvcikgICAgICAgLyogRXJyb3IgaXMgZGV0ZWN0ZWQgKi8KICAgIHsKICAgICAgbGVhblNickNvbmNlYWxtZW50KGhIZWFkZXJEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgaF9zYnJfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgIGhfcHJldl9kYXRhKTsKCiAgICAgIC8qIGRlY29kZSB0aGUgZW52ZWxvcGUgZGF0YSB0byBsaW5lYXIgUENNICovCiAgICAgIGRlbHRhVG9MaW5lYXJQY21FbnZlbG9wZURlY29kaW5nIChoSGVhZGVyRGF0YSwgaF9zYnJfZGF0YSwgaF9wcmV2X2RhdGEpOwogICAgfQogIGVsc2UgICAgICAgICAgICAgICAgICAgICAgICAgIC8qRG8gYSB0ZW1wb3JhcnkgZHVtbXkgZGVjb2RpbmcgYW5kIGNoZWNrIHRoYXQgdGhlIGVudmVsb3BlIHZhbHVlcyBhcmUgd2l0aGluIGxpbWl0cyAqLwogICAgewogICAgICBpZiAoaF9wcmV2X2RhdGEtPmZyYW1lRXJyb3JGbGFnKSB7CiAgICAgICAgdGltZUNvbXBlbnNhdGVGaXJzdEVudmVsb3BlIChoSGVhZGVyRGF0YSwgaF9zYnJfZGF0YSwgaF9wcmV2X2RhdGEpOwogICAgICAgIGlmIChoX3Nicl9kYXRhLT5jb3VwbGluZyAhPSBoX3ByZXZfZGF0YS0+Y291cGxpbmcpIHsKICAgICAgICAgIC8qCiAgICAgICAgICAgIENvdXBsaW5nIG1vZGUgaGFzIGNoYW5nZWQgZHVyaW5nIGNvbmNlYWxtZW50LgogICAgICAgICAgICAgVGhlIHN0b3JlZCBlbmVyZ3kgbGV2ZWxzIG5lZWQgdG8gYmUgY29udmVydGVkLgogICAgICAgICAgICovCiAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5uU2ZiWzFdOyBpKyspIHsKICAgICAgICAgICAgLyogRm9ybWVyIExldmVsLUNoYW5uZWwgd2lsbCBiZSB1c2VkIGZvciBib3RoIGNoYW5uZWxzICovCiAgICAgICAgICAgIGlmIChoX3ByZXZfZGF0YS0+Y291cGxpbmcgPT0gQ09VUExJTkdfQkFMKQogICAgICAgICAgICAgIGhfcHJldl9kYXRhLT5zZmJfbnJnX3ByZXZbaV0gPSBvdGhlckNoYW5uZWwtPnNmYl9ucmdfcHJldltpXTsKICAgICAgICAgICAgLyogRm9ybWVyIEwvUiB3aWxsIGJlIGNvbWJpbmVkIGFzIHRoZSBuZXcgTGV2ZWwtQ2hhbm5lbCAqLwogICAgICAgICAgICBlbHNlIGlmIChoX3Nicl9kYXRhLT5jb3VwbGluZyA9PSBDT1VQTElOR19MRVZFTCkKICAgICAgICAgICAgICBoX3ByZXZfZGF0YS0+c2ZiX25yZ19wcmV2W2ldID0gKGhfcHJldl9kYXRhLT5zZmJfbnJnX3ByZXZbaV0gKyBvdGhlckNoYW5uZWwtPnNmYl9ucmdfcHJldltpXSkgPj4gMTsKICAgICAgICAgICAgZWxzZSBpZiAoaF9zYnJfZGF0YS0+Y291cGxpbmcgPT0gQ09VUExJTkdfQkFMKQogICAgICAgICAgICAgIGhfcHJldl9kYXRhLT5zZmJfbnJnX3ByZXZbaV0gPSAoRklYUF9TR0wpU0JSX0VORVJHWV9QQU5fT0ZGU0VUOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBGREttZW1jcHkgKHRlbXBTZmJOcmdQcmV2LCBoX3ByZXZfZGF0YS0+c2ZiX25yZ19wcmV2LAogICAgICAgICAgICAgIE1BWF9GUkVRX0NPRUZGUyAqIHNpemVvZiAoRklYUF9TR0wpKTsKCiAgICAgIGRlbHRhVG9MaW5lYXJQY21FbnZlbG9wZURlY29kaW5nIChoSGVhZGVyRGF0YSwgaF9zYnJfZGF0YSwgaF9wcmV2X2RhdGEpOwoKICAgICAgZkZyYW1lRXJyb3IgPSBjaGVja0VudmVsb3BlRGF0YSAoaEhlYWRlckRhdGEsIGhfc2JyX2RhdGEsIGhfcHJldl9kYXRhKTsKCiAgICAgIGlmIChmRnJhbWVFcnJvcikKICAgICAgICB7CiAgICAgICAgICBoSGVhZGVyRGF0YS0+ZnJhbWVFcnJvckZsYWcgPSAxOwogICAgICAgICAgRkRLbWVtY3B5IChoX3ByZXZfZGF0YS0+c2ZiX25yZ19wcmV2LCB0ZW1wU2ZiTnJnUHJldiwKICAgICAgICAgICAgICAgICAgTUFYX0ZSRVFfQ09FRkZTICogc2l6ZW9mIChGSVhQX1NHTCkpOwogICAgICAgICAgZGVjb2RlRW52ZWxvcGUgKGhIZWFkZXJEYXRhLCBoX3Nicl9kYXRhLCBoX3ByZXZfZGF0YSwgb3RoZXJDaGFubmVsKTsKICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogIHJlcXVhbnRpemVFbnZlbG9wZURhdGEgKGhfc2JyX2RhdGEsIGhfc2JyX2RhdGEtPmFtcFJlc29sdXRpb25DdXJyZW50RnJhbWUpOwoKICBoSGVhZGVyRGF0YS0+ZnJhbWVFcnJvckZsYWcgPSBmRnJhbWVFcnJvcjsKfQoKCi8qIQogIFxicmllZiAgIFZlcmlmeSB0aGF0IGVudmVsb3BlIGVuZXJnaWVzIGFyZSB3aXRoaW4gdGhlIGFsbG93ZWQgcmFuZ2UKICBccmV0dXJuICAwIGlmIGFsbCBpcyBmaW5lLCAxIGlmIGFuIGVudmVsb3BlIHZhbHVlIHdhcyB0b28gaGlnaAoqLwpzdGF0aWMgaW50CmNoZWNrRW52ZWxvcGVEYXRhIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLCAgICAgLyohPCBTdGF0aWMgY29udHJvbCBkYXRhICovCiAgICAgICAgICAgICAgICAgICBIQU5ETEVfU0JSX0ZSQU1FX0RBVEEgaF9zYnJfZGF0YSwgICAgICAgLyohPCBwb2ludGVyIHRvIGN1cnJlbnQgZGF0YSAqLwogICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgaF9wcmV2X2RhdGEgIC8qITwgcG9pbnRlciB0byBkYXRhIG9mIGxhc3QgZnJhbWUgKi8KICAgICAgICAgICAgICAgICAgICkKewogIEZJWFBfU0dMICppRW52ZWxvcGUgPSBoX3Nicl9kYXRhLT5pRW52ZWxvcGU7CiAgRklYUF9TR0wgKnNmYl9ucmdfcHJldiA9IGhfcHJldl9kYXRhLT5zZmJfbnJnX3ByZXY7CiAgaW50ICAgIGkgPSAwLCBlcnJvckZsYWcgPSAwOwogIEZJWFBfU0dMIHNicl9tYXhfZW5lcmd5ID0KICAgIChoX3Nicl9kYXRhLT5hbXBSZXNvbHV0aW9uQ3VycmVudEZyYW1lID09IDEpID8gU0JSX01BWF9FTkVSR1kgOiAoU0JSX01BWF9FTkVSR1kgPDwgMSk7CgogIC8qCiAgICBSYW5nZSBjaGVjayBmb3IgY3VycmVudCBlbmVyZ2llcwogICovCiAgZm9yIChpID0gMDsgaSA8IGhfc2JyX2RhdGEtPm5TY2FsZUZhY3RvcnM7IGkrKykgewogICAgaWYgKGlFbnZlbG9wZVtpXSA+IHNicl9tYXhfZW5lcmd5KSB7CiAgICAgIGVycm9yRmxhZyA9IDE7CiAgICB9CiAgICBpZiAoaUVudmVsb3BlW2ldIDwgRkwyRlhDT05TVF9TR0woMC4wZikpIHsKICAgICAgZXJyb3JGbGFnID0gMTsKICAgICAgLyogaUVudmVsb3BlW2ldID0gRkwyRlhDT05TVF9TR0woMC4wZik7ICovCiAgICB9CiAgfQoKICAvKgogICAgUmFuZ2UgY2hlY2sgZm9yIHByZXZpb3VzIGVuZXJnaWVzCiAgKi8KICBmb3IgKGkgPSAwOyBpIDwgaEhlYWRlckRhdGEtPmZyZXFCYW5kRGF0YS5uU2ZiWzFdOyBpKyspIHsKICAgIHNmYl9ucmdfcHJldltpXSA9IGZpeE1heChzZmJfbnJnX3ByZXZbaV0sIEZMMkZYQ09OU1RfU0dMKDAuMGYpKTsKICAgIHNmYl9ucmdfcHJldltpXSA9IGZpeE1pbihzZmJfbnJnX3ByZXZbaV0sIHNicl9tYXhfZW5lcmd5KTsKICB9CgogIHJldHVybiAoZXJyb3JGbGFnKTsKfQoKCi8qIQogIFxicmllZiAgIFZlcmlmeSB0aGF0IHRoZSBub2lzZSBsZXZlbHMgYXJlIHdpdGhpbiB0aGUgYWxsb3dlZCByYW5nZQoKICBUaGUgZnVuY3Rpb24gaXMgZXF1aXZhbGVudCB0byBjaGVja0VudmVsb3BlRGF0YSgpLgogIFdoZW4gdGhlIG5vaXNlLWxldmVscyBhcmUgYmVpbmcgZGVjb2RlZCwgaXQgaXMgYWxyZWFkeSB0b28gbGF0ZSBmb3IKICBjb25jZWFsbWVudC4gVGhlcmVmb3JlIHRoZSBub2lzZSBsZXZlbHMgYXJlIHNpbXBseSBsaW1pdGVkIGhlcmUuCiovCnN0YXRpYyB2b2lkCmxpbWl0Tm9pc2VMZXZlbHMoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwgICAgIC8qITwgU3RhdGljIGNvbnRyb2wgZGF0YSAqLwogICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSBoX3Nicl9kYXRhKSAgICAgICAvKiE8IHBvaW50ZXIgdG8gY3VycmVudCBkYXRhICovCnsKICBpbnQgaTsKICBpbnQgbk5mYiA9IGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEubk5mYjsKCiAgLyoKICAgIFNldCByYW5nZSBsaW1pdHMuIFRoZSBleGFjdCB2YWx1ZXMgZGVwZW5kIG9uIHRoZSBjb3VwbGluZyBtb2RlLgogICAgSG93ZXZlciB0aGlzIGxpbWl0YXRpb24gaXMgcHJpbWFyaWx5IGludGVuZGVkIHRvIGF2b2lkIHVubGltaXRlZAogICAgYWNjdW11bGF0aW9uIG9mIHRoZSBkZWx0YS1jb2RlZCBub2lzZSBsZXZlbHMuCiAgKi8KICAjZGVmaW5lIGxvd2VyTGltaXQgICAoKEZJWFBfU0dMKTApICAgICAvKiBsb3dlckxpbWl0IGFjdHVhbGx5IHJlZmVycyB0byB0aGUgX2hpZ2hlc3RfIG5vaXNlIGVuZXJneSAqLwogICNkZWZpbmUgdXBwZXJMaW1pdCAgICgoRklYUF9TR0wpMzUpICAgIC8qIHVwcGVyTGltaXQgYWN0dWFsbHkgcmVmZXJzIHRvIHRoZSBfbG93ZXN0XyBub2lzZSBlbmVyZ3kgKi8KCiAgLyoKICAgIFJhbmdlIGNoZWNrIGZvciBjdXJyZW50IG5vaXNlIGxldmVscwogICovCiAgZm9yIChpID0gMDsgaSA8IGhfc2JyX2RhdGEtPmZyYW1lSW5mby5uTm9pc2VFbnZlbG9wZXMgKiBuTmZiOyBpKyspIHsKICAgIGhfc2JyX2RhdGEtPnNick5vaXNlRmxvb3JMZXZlbFtpXSA9IGZpeE1pbihoX3Nicl9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0sIHVwcGVyTGltaXQpOwogICAgaF9zYnJfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsW2ldID0gZml4TWF4KGhfc2JyX2RhdGEtPnNick5vaXNlRmxvb3JMZXZlbFtpXSwgbG93ZXJMaW1pdCk7CiAgfQp9CgoKLyohCiAgXGJyaWVmICAgQ29tcGVuc2F0ZSBmb3IgdGhlIHdyb25nIHRpbWluZyB0aGF0IG1pZ2h0IG9jY3VyIGFmdGVyIGEgZnJhbWUgZXJyb3IuCiovCnN0YXRpYyB2b2lkCnRpbWVDb21wZW5zYXRlRmlyc3RFbnZlbG9wZSAoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwgLyohPCBTdGF0aWMgY29udHJvbCBkYXRhICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBIGhfc2JyX2RhdGEsICAgLyohPCBwb2ludGVyIHRvIGFjdHVhbCBkYXRhICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9QUkVWX0ZSQU1FX0RBVEEgaF9wcmV2X2RhdGEpICAvKiE8IHBvaW50ZXIgdG8gZGF0YSBvZiBsYXN0IGZyYW1lICovCnsKICBpbnQgaSwgblNjYWxlZmFjdG9yczsKICBGUkFNRV9JTkZPICpwRnJhbWVJbmZvID0gJmhfc2JyX2RhdGEtPmZyYW1lSW5mbzsKICBVQ0hBUiAqblNmYiA9IGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEublNmYjsKICBpbnQgZXN0aW1hdGVkU3RhcnRQb3MgPSBoX3ByZXZfZGF0YS0+c3RvcFBvcyAtIGhIZWFkZXJEYXRhLT5udW1iZXJUaW1lU2xvdHM7CiAgaW50IHJlZkxlbiwgbmV3TGVuLCBzaGlmdDsKICBGSVhQX1NHTCAgZGVsdGFFeHA7CgogIC8qIE9yaWdpbmFsIGxlbmd0aCBvZiBmaXJzdCBlbnZlbG9wZSBhY2NvcmRpbmcgdG8gYml0c3RyZWFtICovCiAgcmVmTGVuID0gcEZyYW1lSW5mby0+Ym9yZGVyc1sxXSAtIHBGcmFtZUluZm8tPmJvcmRlcnNbMF07CiAgLyogQ29ycmVjdGVkIGxlbmd0aCBvZiBmaXJzdCBlbnZlbG9wZSAoY29uY2VhbGluZyBjYW4gbWFrZSB0aGUgZmlyc3QgZW52ZWxvcGUgbG9uZ2VyKSAqLwogIG5ld0xlbiA9IHBGcmFtZUluZm8tPmJvcmRlcnNbMV0gLSBlc3RpbWF0ZWRTdGFydFBvczsKCiAgaWYgKG5ld0xlbiA8PSAwKSB7CiAgICAvKiBBbiBlbnZlbG9wZSBsZW5ndGggb2YgPD0gMCB3b3VsZCBub3Qgd29yaywgc28gd2UgZG9uJ3QgdXNlIGl0LgogICAgICAgTWF5IG9jY3VyIGlmIHRoZSBwcmV2aW91cyBmcmFtZSB3YXMgZmxhZ2dlZCBiYWQgZHVlIHRvIGEgbWlzbWF0Y2gKICAgICAgIG9mIHRoZSBvbGQgYW5kIG5ldyBmcmFtZSBpbmZvcy4gKi8KICAgIG5ld0xlbiA9IHJlZkxlbjsKICAgIGVzdGltYXRlZFN0YXJ0UG9zID0gcEZyYW1lSW5mby0+Ym9yZGVyc1swXTsKICB9CgogIGRlbHRhRXhwID0gRkRLX2dldE51bU9jdGF2ZXNEaXY4KG5ld0xlbiwgcmVmTGVuKTsKCiAgLyogU2hpZnQgYnkgLTMgdG8gcmVzY2FsZSBsZC10YWJsZSwgYW1wUmVzLTEgdG8gZW5hYmxlIGNvYXJzZXIgc3RlcHMgKi8KICBzaGlmdCA9IChGUkFDVF9CSVRTIC0gMSAtIEVOVl9FWFBfRlJBQ1QgLSAxICsgaF9zYnJfZGF0YS0+YW1wUmVzb2x1dGlvbkN1cnJlbnRGcmFtZSAtIDMpOwogIGRlbHRhRXhwID0gZGVsdGFFeHAgPj4gc2hpZnQ7CiAgcEZyYW1lSW5mby0+Ym9yZGVyc1swXSA9IGVzdGltYXRlZFN0YXJ0UG9zOwogIHBGcmFtZUluZm8tPmJvcmRlcnNOb2lzZVswXSA9IGVzdGltYXRlZFN0YXJ0UG9zOwoKICBpZiAoaF9zYnJfZGF0YS0+Y291cGxpbmcgIT0gQ09VUExJTkdfQkFMKSB7CiAgICBuU2NhbGVmYWN0b3JzID0gKHBGcmFtZUluZm8tPmZyZXFSZXNbMF0pID8gblNmYlsxXSA6IG5TZmJbMF07CgogICAgZm9yIChpID0gMDsgaSA8IG5TY2FsZWZhY3RvcnM7IGkrKykKICAgICAgaF9zYnJfZGF0YS0+aUVudmVsb3BlW2ldID0gaF9zYnJfZGF0YS0+aUVudmVsb3BlW2ldICsgZGVsdGFFeHA7CiAgfQp9CgoKCi8qIQogIFxicmllZiAgIENvbnZlcnQgZWFjaCBlbnZlbG9wZSB2YWx1ZSBmcm9tIGxvZ2FyaXRobWljIHRvIGxpbmVhciBkb21haW4KCiAgRW5lcmd5IGxldmVscyBhcmUgdHJhbnNtaXR0ZWQgaW4gcG93ZXJzIG9mIDIsIGkuZS4gb25seSB0aGUgZXhwb25lbnQKICBpcyBleHRyYWN0ZWQgZnJvbSB0aGUgYml0c3RyZWFtLgogIFRoZXJlZm9yZSwgbm9ybWFsbHkgb25seSBpbnRlZ2VyIGV4cG9uZW50cyBjYW4gb2NjdXIuIEhvd2V2ZXIgZHVyaW5nCiAgZmFkaW5nIChpbiBjYXNlIG9mIGEgY29ycnVwdCBiaXRzdHJlYW0pLCBhIGZyYWN0aW9uYWwgcGFydCBjYW4gYWxzbwogIG9jY3VyLiBUaGUgZGF0YSBpbiB0aGUgYXJyYXkgaUVudmVsb3BlIGlzIHNoaWZ0ZWQgbGVmdCBieSBFTlZfRVhQX0ZSQUNUCiAgY29tcGFyZWQgdG8gYW4gaW50ZWdlciByZXByZXNlbnRhdGlvbiBzbyB0aGF0IG51bWJlcnMgc21hbGxlciB0aGFuIDEKICBjYW4gYmUgcmVwcmVzZW50ZWQuCgogIFRoaXMgZnVuY3Rpb24gY2FsY3VsYXRlcyBhIG1hbnRpc3NhIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGZyYWN0aW9uYWwKICBwYXJ0IG9mIHRoZSBleHBvbmVudCBmb3IgZWFjaCByZWZlcmVuY2UgZW5lcmd5LiBUaGUgYXJyYXkgaUVudmVsb3BlCiAgaXMgY29udmVydGVkIGluIHBsYWNlIHRvIHNhdmUgbWVtb3J5LiBJbnB1dCBhbmQgb3V0cHV0IGRhdGEgbXVzdAogIGJlIGludGVycHJldGVkIGRpZmZlcmVudGx5LCBhcyBzaG93biBpbiB0aGUgYmVsb3cgZmlndXJlOgoKICBcaW1hZ2UgaHRtbCAgRW52ZWxvcGVEYXRhLnBuZwoKICBUaGUgZGF0YSBpcyB0aGVuIHVzZWQgaW4gY2FsY3VsYXRlU2JyRW52ZWxvcGUoKS4KKi8Kc3RhdGljIHZvaWQKcmVxdWFudGl6ZUVudmVsb3BlRGF0YSAoSEFORExFX1NCUl9GUkFNRV9EQVRBIGhfc2JyX2RhdGEsIGludCBhbXBSZXNvbHV0aW9uKQp7CiAgaW50IGk7CiAgRklYUF9TR0wgbWFudGlzc2E7CiAgaW50IGFtcFNoaWZ0ID0gMSAtIGFtcFJlc29sdXRpb247CiAgaW50IGV4cG9uZW50OwoKICAvKiBJbiBjYXNlIHRoYXQgRU5WX0VYUF9GUkFDVCBpcyBjaGFuZ2VkIHRvIHNvbWV0aGluZyBlbHNlIGJ1dCAwIG9yIDgsCiAgICAgdGhlIGluaXRpYWxpemF0aW9uIG9mIHRoaXMgYXJyYXkgaGFzIHRvIGJlIGFkYXB0ZWQhCiAgKi8KI2lmIEVOVl9FWFBfRlJBQ1QKICBzdGF0aWMgY29uc3QgRklYUF9TR0wgcG93MltFTlZfRVhQX0ZSQUNUXSA9CiAgewogICAgRkwyRlhDT05TVF9TR0woMC41ZiAqIHBvdygyLjBmLCBwb3coMC41ZiwgMSkpKSwgLyogMC43MDcxICovCiAgICBGTDJGWENPTlNUX1NHTCgwLjVmICogcG93KDIuMGYsIHBvdygwLjVmLCAyKSkpLCAvKiAwLjU5NDYgKi8KICAgIEZMMkZYQ09OU1RfU0dMKDAuNWYgKiBwb3coMi4wZiwgcG93KDAuNWYsIDMpKSksCiAgICBGTDJGWENPTlNUX1NHTCgwLjVmICogcG93KDIuMGYsIHBvdygwLjVmLCA0KSkpLAogICAgRkwyRlhDT05TVF9TR0woMC41ZiAqIHBvdygyLjBmLCBwb3coMC41ZiwgNSkpKSwKICAgIEZMMkZYQ09OU1RfU0dMKDAuNWYgKiBwb3coMi4wZiwgcG93KDAuNWYsIDYpKSksCiAgICBGTDJGWENPTlNUX1NHTCgwLjVmICogcG93KDIuMGYsIHBvdygwLjVmLCA3KSkpLAogICAgRkwyRlhDT05TVF9TR0woMC41ZiAqIHBvdygyLjBmLCBwb3coMC41ZiwgOCkpKSAgLyogMC41MDEzICovCiAgfTsKCiAgaW50IGJpdCwgbWFzazsKI2VuZGlmCgogIGZvciAoaSA9IDA7IGkgPCBoX3Nicl9kYXRhLT5uU2NhbGVGYWN0b3JzOyBpKyspIHsKICAgIGV4cG9uZW50ID0gKExPTkcpaF9zYnJfZGF0YS0+aUVudmVsb3BlW2ldOwoKI2lmIEVOVl9FWFBfRlJBQ1QKCiAgICBleHBvbmVudCA9IGV4cG9uZW50ID4+IGFtcFNoaWZ0OwogICAgbWFudGlzc2EgPSAwLjVmOwoKICAgIC8qIEFtcGxpZnkgbWFudGlzc2EgYWNjb3JkaW5nIHRvIHRoZSBmcmFjdGlvbmFsIHBhcnQgb2YgdGhlCiAgICAgICBleHBvbmVudCAocmVzdWx0IHdpbGwgYmUgYmV0d2VlbiAwLjUwMDAwMCBhbmQgMC45OTk5OTkpCiAgICAqLwogICAgbWFzayA9IDE7ICAvKiBiZWdpbiB3aXRoIGxvd2VzdCBiaXQgb2YgZXhwb25lbnQgKi8KCiAgICBmb3IgKCBiaXQ9RU5WX0VYUF9GUkFDVC0xOyBiaXQ+PTA7IGJpdC0tICkgewogICAgICBpZiAoZXhwb25lbnQgJiBtYXNrKSB7CiAgICAgICAgLyogVGhlIGN1cnJlbnQgYml0IG9mIHRoZSBleHBvbmVudCBpcyBzZXQsCiAgICAgICAgICAgbXVsdGlwbHkgbWFudGlzc2Egd2l0aCB0aGUgY29ycmVzcG9uZGluZyBmYWN0b3I6ICovCiAgICAgICAgbWFudGlzc2EgPSAoRklYUF9TR0wpKCAobWFudGlzc2EgKiBwb3cyW2JpdF0pIDw8IDEpOwogICAgICB9CiAgICAgIC8qIEFkdmFuY2UgdG8gbmV4dCBiaXQgKi8KICAgICAgbWFzayA9IG1hc2sgPDwgMTsKICAgIH0KCiAgICAvKiBNYWtlIGludGVnZXIgcGFydCBvZiBleHBvbmVudCByaWdodCBhbGlnbmVkICovCiAgICBleHBvbmVudCA9IGV4cG9uZW50ID4+IEVOVl9FWFBfRlJBQ1Q7CgojZWxzZQogICAgLyogSW4gY2FzZSBvZiB0aGUgaGlnaCBhbXBsaXR1ZGUgcmVzb2x1dGlvbiwgMSBiaXQgb2YgdGhlIGV4cG9uZW50IGdldHMgbG9zdCBieSB0aGUgc2hpZnQuCiAgICAgICBUaGlzIHdpbGwgYmUgY29tcGVuc2F0ZWQgYnkgYSBtYW50aXNzYSBvZiAwLjUqc3FydCgyKSBpbnN0ZWFkIG9mIDAuNSBpZiB0aGF0IGJpdCBpcyAxLiAqLwogICAgbWFudGlzc2EgPSAoZXhwb25lbnQgJiBhbXBTaGlmdCkgPyBGTDJGWENPTlNUX1NHTCgwLjcwNzEwNjc4MTE4NjU0OGYpIDogRkwyRlhDT05TVF9TR0woMC41Zik7CiAgICBleHBvbmVudCA9IGV4cG9uZW50ID4+IGFtcFNoaWZ0OwojZW5kaWYKCiAgICAvKgogICAgICBNYW50aXNzYSB3YXMgc2V0IHRvIDAuNSAoaW5zdGVhZCBvZiAxLjAsIHRoZXJlZm9yZSBpbmNyZWFzZSBleHBvbmVudCBieSAxKS4KICAgICAgTXVsdGlwbHkgYnkgTD1uQ2hhbm5lbHM9NjQgYnkgaW5jcmVhc2luZyBleHBvbmVudCBieSBhbm90aGVyIDYuCiAgICAgID0+IEluY3JlYXNlIGV4cG9uZW50IGJ5IDcKICAgICovCiAgICBleHBvbmVudCArPSA3ICsgTlJHX0VYUF9PRkZTRVQ7CgogICAgLyogQ29tYmluZSBtYW50aXNzYSBhbmQgZXhwb25lbnQgYW5kIHdyaXRlIGJhY2sgdGhlIHJlc3VsdCAqLwogICAgaF9zYnJfZGF0YS0+aUVudmVsb3BlW2ldID0gKEZJWFBfU0dMKSgoKExPTkcpbWFudGlzc2EgJiBNQVNLX00pIHwgKGV4cG9uZW50ICYgTUFTS19FKSk7CgogIH0KfQoKCi8qIQogIFxicmllZiAgIEJ1aWxkIG5ldyByZWZlcmVuY2UgZW5lcmdpZXMgZnJvbSBvbGQgb25lcyBhbmQgZGVsdGEgY29kZWQgZGF0YQoqLwpzdGF0aWMgdm9pZApkZWx0YVRvTGluZWFyUGNtRW52ZWxvcGVEZWNvZGluZyAoSEFORExFX1NCUl9IRUFERVJfREFUQSBoSGVhZGVyRGF0YSwgICAgIC8qITwgU3RhdGljIGNvbnRyb2wgZGF0YSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX1NCUl9GUkFNRV9EQVRBIGhfc2JyX2RhdGEsICAgICAgIC8qITwgcG9pbnRlciB0byBjdXJyZW50IGRhdGEgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfUFJFVl9GUkFNRV9EQVRBIGhfcHJldl9kYXRhKSAvKiE8IHBvaW50ZXIgdG8gcHJldmlvdXMgZGF0YSAqLwp7CiAgaW50IGksIGRvbWFpbiwgbm9fb2ZfYmFuZHMsIGJhbmQsIGZyZXFSZXM7CgogIEZJWFBfU0dMICpzZmJfbnJnX3ByZXYgPSBoX3ByZXZfZGF0YS0+c2ZiX25yZ19wcmV2OwogIEZJWFBfU0dMICpwdHJfbnJnID0gaF9zYnJfZGF0YS0+aUVudmVsb3BlOwoKICBpbnQgb2Zmc2V0ID0gMiAqIGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEublNmYlswXSAtIGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEublNmYlsxXTsKCiAgZm9yIChpID0gMDsgaSA8IGhfc2JyX2RhdGEtPmZyYW1lSW5mby5uRW52ZWxvcGVzOyBpKyspIHsKICAgIGRvbWFpbiA9IGhfc2JyX2RhdGEtPmRvbWFpbl92ZWNbaV07CiAgICBmcmVxUmVzID0gaF9zYnJfZGF0YS0+ZnJhbWVJbmZvLmZyZXFSZXNbaV07CgogICAgRkRLX0FTU0VSVChmcmVxUmVzID49IDAgJiYgZnJlcVJlcyA8PSAxKTsKCiAgICBub19vZl9iYW5kcyA9IGhIZWFkZXJEYXRhLT5mcmVxQmFuZERhdGEublNmYltmcmVxUmVzXTsKCiAgICBGREtfQVNTRVJUKG5vX29mX2JhbmRzIDwgKDY0KSk7CgogICAgaWYgKGRvbWFpbiA9PSAwKQogICAgewogICAgICBtYXBMb3dSZXNFbmVyZ3lWYWwoKnB0cl9ucmcsIHNmYl9ucmdfcHJldiwgb2Zmc2V0LCAwLCBmcmVxUmVzKTsKICAgICAgcHRyX25yZysrOwogICAgICBmb3IgKGJhbmQgPSAxOyBiYW5kIDwgbm9fb2ZfYmFuZHM7IGJhbmQrKykKICAgICAgewogICAgICAgICpwdHJfbnJnID0gKnB0cl9ucmcgKyAqKHB0cl9ucmctMSk7CiAgICAgICAgbWFwTG93UmVzRW5lcmd5VmFsKCpwdHJfbnJnLCBzZmJfbnJnX3ByZXYsIG9mZnNldCwgYmFuZCwgZnJlcVJlcyk7CiAgICAgICAgcHRyX25yZysrOwogICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgIGZvciAoYmFuZCA9IDA7IGJhbmQgPCBub19vZl9iYW5kczsgYmFuZCsrKQogICAgICB7CiAgICAgICAgKnB0cl9ucmcgPSAqcHRyX25yZyArIHNmYl9ucmdfcHJldltpbmRleExvdzJIaWdoKG9mZnNldCwgYmFuZCwgZnJlcVJlcyldOwogICAgICAgIG1hcExvd1Jlc0VuZXJneVZhbCgqcHRyX25yZywgc2ZiX25yZ19wcmV2LCBvZmZzZXQsIGJhbmQsIGZyZXFSZXMpOwogICAgICAgIHB0cl9ucmcrKzsKICAgICAgfQogICAgfQogIH0KfQoKCi8qIQogIFxicmllZiAgIEJ1aWxkIG5ldyBub2lzZSBsZXZlbHMgZnJvbSBvbGQgb25lcyBhbmQgZGVsdGEgY29kZWQgZGF0YQoqLwpzdGF0aWMgdm9pZApkZWNvZGVOb2lzZUZsb29ybGV2ZWxzIChIQU5ETEVfU0JSX0hFQURFUl9EQVRBIGhIZWFkZXJEYXRhLCAgICAgLyohPCBTdGF0aWMgY29udHJvbCBkYXRhICovCiAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfRlJBTUVfREFUQSBoX3Nicl9kYXRhLCAgICAgICAvKiE8IHBvaW50ZXIgdG8gY3VycmVudCBkYXRhICovCiAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9TQlJfUFJFVl9GUkFNRV9EQVRBIGhfcHJldl9kYXRhKSAvKiE8IHBvaW50ZXIgdG8gcHJldmlvdXMgZGF0YSAqLwp7CiAgaW50IGk7CiAgaW50IG5OZmIgPSBoSGVhZGVyRGF0YS0+ZnJlcUJhbmREYXRhLm5OZmI7CiAgaW50IG5Ob2lzZUZsb29yRW52ZWxvcGVzID0gaF9zYnJfZGF0YS0+ZnJhbWVJbmZvLm5Ob2lzZUVudmVsb3BlczsKCiAgLyogRGVjb2RlIGZpcnN0IG5vaXNlIGVudmVsb3BlICovCgogIGlmIChoX3Nicl9kYXRhLT5kb21haW5fdmVjX25vaXNlWzBdID09IDApIHsKICAgIEZJWFBfU0dMIG5vaXNlTGV2ZWwgPSBoX3Nicl9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbMF07CiAgICBmb3IgKGkgPSAxOyBpIDwgbk5mYjsgaSsrKSB7CiAgICAgIG5vaXNlTGV2ZWwgKz0gaF9zYnJfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsW2ldOwogICAgICBoX3Nicl9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0gPSBub2lzZUxldmVsOwogICAgfQogIH0KICBlbHNlIHsKICAgIGZvciAoaSA9IDA7IGkgPCBuTmZiOyBpKyspIHsKICAgICAgaF9zYnJfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsW2ldICs9IGhfcHJldl9kYXRhLT5wcmV2Tm9pc2VMZXZlbFtpXTsKICAgIH0KICB9CgogIC8qIElmIHByZXNlbnQsIGRlY29kZSB0aGUgc2Vjb25kIG5vaXNlIGVudmVsb3BlCiAgICAgTm90ZTogIG5Ob2lzZUZsb29yRW52ZWxvcGVzIGNhbiBvbmx5IGJlIDEgb3IgMiAqLwoKICBpZiAobk5vaXNlRmxvb3JFbnZlbG9wZXMgPiAxKSB7CiAgICBpZiAoaF9zYnJfZGF0YS0+ZG9tYWluX3ZlY19ub2lzZVsxXSA9PSAwKSB7CiAgICAgIEZJWFBfU0dMIG5vaXNlTGV2ZWwgPSBoX3Nicl9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbbk5mYl07CiAgICAgIGZvciAoaSA9IG5OZmIgKyAxOyBpIDwgMipuTmZiOyBpKyspIHsKICAgICAgICBub2lzZUxldmVsICs9IGhfc2JyX2RhdGEtPnNick5vaXNlRmxvb3JMZXZlbFtpXTsKICAgICAgICBoX3Nicl9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0gPSBub2lzZUxldmVsOwogICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgZm9yIChpID0gMDsgaSA8IG5OZmI7IGkrKykgewogICAgICAgIGhfc2JyX2RhdGEtPnNick5vaXNlRmxvb3JMZXZlbFtpICsgbk5mYl0gKz0gaF9zYnJfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsW2ldOwogICAgICB9CiAgICB9CiAgfQoKICBsaW1pdE5vaXNlTGV2ZWxzKGhIZWFkZXJEYXRhLCBoX3Nicl9kYXRhKTsKCiAgLyogVXBkYXRlIHByZXZOb2lzZUxldmVsIHdpdGggdGhlIGxhc3Qgbm9pc2UgZW52ZWxvcGUgKi8KICBmb3IgKGkgPSAwOyBpIDwgbk5mYjsgaSsrKQogICAgaF9wcmV2X2RhdGEtPnByZXZOb2lzZUxldmVsW2ldID0gaF9zYnJfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsW2kgKyBuTmZiKihuTm9pc2VGbG9vckVudmVsb3Blcy0xKV07CgoKICAvKiBSZXF1YW50aXplIHRoZSBub2lzZSBmbG9vciBsZXZlbHMgaW4gQ09VUExJTkdfT0ZGLW1vZGUgKi8KICBpZiAoIWhfc2JyX2RhdGEtPmNvdXBsaW5nKSB7CiAgICBpbnQgbmZfZTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbk5vaXNlRmxvb3JFbnZlbG9wZXMqbk5mYjsgaSsrKSB7CiAgICAgIG5mX2UgPSA2IC0gKExPTkcpaF9zYnJfZGF0YS0+c2JyTm9pc2VGbG9vckxldmVsW2ldICsgMSArIE5PSVNFX0VYUF9PRkZTRVQ7CiAgICAgIC8qICsxIHRvIGNvbXBlbnNhdGUgZm9yIGEgbWFudGlzc2Egb2YgMC41IGluc3RlYWQgb2YgMS4wICovCgogICAgICBoX3Nicl9kYXRhLT5zYnJOb2lzZUZsb29yTGV2ZWxbaV0gPQogICAgICAgIChGSVhQX1NHTCkoICgoTE9ORylGTDJGWENPTlNUX1NHTCgwLjVmKSkgKyAgLyogbWFudGlzc2EgKi8KICAgICAgICAgICAgICAgICAgKG5mX2UgJiBNQVNLX0UpICk7IC8qIGV4cG9uZW50ICovCgogICAgfQogIH0KfQo=