Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBEYW5pZWwgSG9tbQogICBEZXNjcmlwdGlvbjoKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJ0cGRlY19saWIuaCIKI2luY2x1ZGUgInRwX2RhdGEuaCIKI2lmZGVmIFRQX1BDRV9FTkFCTEUKI2luY2x1ZGUgIkZES19jcmMuaCIKI2VuZGlmCgoKdm9pZCBDUHJvZ3JhbUNvbmZpZ19SZXNldChDUHJvZ3JhbUNvbmZpZyAqcFBjZSkKewogIHBQY2UtPmVsQ291bnRlciA9IDA7Cn0KCnZvaWQgQ1Byb2dyYW1Db25maWdfSW5pdChDUHJvZ3JhbUNvbmZpZyAqcFBjZSkKewogIEZES21lbWNsZWFyKHBQY2UsIHNpemVvZihDUHJvZ3JhbUNvbmZpZykpOwojaWZkZWYgVFBfUENFX0VOQUJMRQogIHBQY2UtPlNhbXBsaW5nRnJlcXVlbmN5SW5kZXggPSAweGY7CiNlbmRpZgp9CgppbnQgIENQcm9ncmFtQ29uZmlnX0lzVmFsaWQgKCBjb25zdCBDUHJvZ3JhbUNvbmZpZyAqcFBjZSApCnsKICByZXR1cm4gKCAocFBjZS0+aXNWYWxpZCkgPyAxIDogMCk7Cn0KCiNpZmRlZiBUUF9QQ0VfRU5BQkxFCiNkZWZpbmUgUENFX0hFSUdIVF9FWFRfU1lOQyAgKCAweEFDICkKCi8qCiAqIFJlYWQgdGhlIGV4dGVuc2lvbiBmb3IgaGVpZ2h0IGluZm8uCiAqIHJldHVybiAwIGlmIHN1Y2Nlc3NmdWxsIG9yIC0xIGlmIHRoZSBDUkMgZmFpbGVkLgogKi8Kc3RhdGljCmludCBDUHJvZ3JhbUNvbmZpZ19SZWFkSGVpZ2h0RXh0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1Byb2dyYW1Db25maWcgKnBQY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqIGNvbnN0IGJ5dGVzQXZhaWxhYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUlOVCBhbGlnbm1lbnRBbmNob3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApCnsKICBpbnQgZXJyID0gMDsKICBGREtfQ1JDSU5GTyBjcmNJbmZvOyAgICAvKiBDUkMgc3RhdGUgaW5mbyAqLwogIElOVCBjcmNSZWc7CiAgRkRLY3JjSW5pdCgmY3JjSW5mbywgMHgwNywgMHhGRiwgOCk7CiAgY3JjUmVnID0gRkRLY3JjU3RhcnRSZWcoJmNyY0luZm8sIGJzLCAwKTsKICBVSU5UIHN0YXJ0QW5jaG9yID0gRkRLZ2V0VmFsaWRCaXRzKGJzKTsKCiAgRkRLX0FTU0VSVChwUGNlICE9IE5VTEwpOwogIEZES19BU1NFUlQoYnMgIT0gTlVMTCk7CiAgRkRLX0FTU0VSVChieXRlc0F2YWlsYWJsZSAhPSBOVUxMKTsKCiAgaWYgKCAoc3RhcnRBbmNob3IgPj0gMjQpICYmICgqYnl0ZXNBdmFpbGFibGUgPj0gMykKICAgICYmIChGREtyZWFkQml0cyhicyw4KSA9PSBQQ0VfSEVJR0hUX0VYVF9TWU5DKSApCiAgewogICAgaW50IGk7CgogICAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50czsgaSsrKQogICAgewogICAgICBwUGNlLT5Gcm9udEVsZW1lbnRIZWlnaHRJbmZvW2ldID0gKFVDSEFSKSBGREtyZWFkQml0cyhicywyKTsKICAgIH0KICAgIGZvciAoaT0wOyBpIDwgcFBjZS0+TnVtU2lkZUNoYW5uZWxFbGVtZW50czsgaSsrKQogICAgewogICAgICBwUGNlLT5TaWRlRWxlbWVudEhlaWdodEluZm9baV0gPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDIpOwogICAgfQogICAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1CYWNrQ2hhbm5lbEVsZW1lbnRzOyBpKyspCiAgICB7CiAgICAgIHBQY2UtPkJhY2tFbGVtZW50SGVpZ2h0SW5mb1tpXSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsMik7CiAgICB9CiAgICBGREtieXRlQWxpZ24oYnMsIGFsaWdubWVudEFuY2hvcik7CgogICAgRkRLY3JjRW5kUmVnKCZjcmNJbmZvLCBicywgY3JjUmVnKTsKICAgIGlmICgoVVNIT1JUKUZES3JlYWRCaXRzKGJzLDgpICE9IEZES2NyY0dldENSQygmY3JjSW5mbykpIHsKICAgICAgLyogQ1JDIGZhaWxlZCAqLwogICAgICBlcnIgPSAtMTsKICAgIH0KICB9CiAgZWxzZSB7CiAgICAvKiBObyB2YWxpZCBleHRlbnNpb24gZGF0YSBmb3VuZCAtPiByZXN0b3JlIHRoZSBpbml0aWFsIGJpdGJ1ZmZlciBzdGF0ZSAqLwogICAgRkRLcHVzaEJhY2soYnMsIHN0YXJ0QW5jaG9yIC0gRkRLZ2V0VmFsaWRCaXRzKGJzKSk7CiAgfQoKICAvKiBBbHdheXMgcmVwb3J0IHRoZSBieXRlcyByZWFkLiAqLwogICpieXRlc0F2YWlsYWJsZSAtPSAoc3RhcnRBbmNob3IgLSBGREtnZXRWYWxpZEJpdHMoYnMpKSA+PiAzOwoKICByZXR1cm4gKGVycik7Cn0KCnZvaWQgQ1Byb2dyYW1Db25maWdfUmVhZCgKICAgICAgICAgICAgICAgICAgICAgICAgICBDUHJvZ3JhbUNvbmZpZyAqcFBjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBicywKICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIGFsaWdubWVudEFuY2hvcgogICAgICAgICAgICAgICAgICAgICAgICApCnsKICBpbnQgaSwgZXJyID0gMDsKICBpbnQgY29tbWVudEJ5dGVzOwoKICBwUGNlLT5OdW1FZmZlY3RpdmVDaGFubmVscyA9IDA7CiAgcFBjZS0+TnVtQ2hhbm5lbHMgPSAwOwogIHBQY2UtPkVsZW1lbnRJbnN0YW5jZVRhZyA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CiAgcFBjZS0+UHJvZmlsZSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsMik7CiAgcFBjZS0+U2FtcGxpbmdGcmVxdWVuY3lJbmRleCA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CiAgcFBjZS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHMgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDQpOwogIHBQY2UtPk51bVNpZGVDaGFubmVsRWxlbWVudHMgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDQpOwogIHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHMgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDQpOwogIHBQY2UtPk51bUxmZUNoYW5uZWxFbGVtZW50cyA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsMik7CiAgcFBjZS0+TnVtQXNzb2NEYXRhRWxlbWVudHMgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDMpOwogIHBQY2UtPk51bVZhbGlkQ2NFbGVtZW50cyA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CgogIGlmICgocFBjZS0+TW9ub01peGRvd25QcmVzZW50ID0gKFVDSEFSKSBGREtyZWFkQml0cyhicywxKSkgIT0gMCkKICB7CiAgICBwUGNlLT5Nb25vTWl4ZG93bkVsZW1lbnROdW1iZXIgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDQpOwogIH0KCiAgaWYgKChwUGNlLT5TdGVyZW9NaXhkb3duUHJlc2VudCA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsMSkpICE9IDApCiAgewogICAgcFBjZS0+U3RlcmVvTWl4ZG93bkVsZW1lbnROdW1iZXIgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDQpOwogIH0KCiAgaWYgKChwUGNlLT5NYXRyaXhNaXhkb3duSW5kZXhQcmVzZW50ID0gKFVDSEFSKSBGREtyZWFkQml0cyhicywxKSkgIT0gMCkKICB7CiAgICBwUGNlLT5NYXRyaXhNaXhkb3duSW5kZXggPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDIpOwogICAgcFBjZS0+UHNldWRvU3Vycm91bmRFbmFibGUgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDEpOwogIH0KCiAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50czsgaSsrKQogIHsKICAgIHBQY2UtPkZyb250RWxlbWVudElzQ3BlW2ldID0gKFVDSEFSKSBGREtyZWFkQml0cyhicywxKTsKICAgIHBQY2UtPkZyb250RWxlbWVudFRhZ1NlbGVjdFtpXSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CiAgICBwUGNlLT5OdW1DaGFubmVscyArPSBwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVtpXSA/IDIgOiAxOwogIH0KCiAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1TaWRlQ2hhbm5lbEVsZW1lbnRzOyBpKyspCiAgewogICAgcFBjZS0+U2lkZUVsZW1lbnRJc0NwZVtpXSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsMSk7CiAgICBwUGNlLT5TaWRlRWxlbWVudFRhZ1NlbGVjdFtpXSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CiAgICBwUGNlLT5OdW1DaGFubmVscyArPSBwUGNlLT5TaWRlRWxlbWVudElzQ3BlW2ldID8gMiA6IDE7CiAgfQoKICBmb3IgKGk9MDsgaSA8IHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHM7IGkrKykKICB7CiAgICBwUGNlLT5CYWNrRWxlbWVudElzQ3BlW2ldID0gKFVDSEFSKSBGREtyZWFkQml0cyhicywxKTsKICAgIHBQY2UtPkJhY2tFbGVtZW50VGFnU2VsZWN0W2ldID0gKFVDSEFSKSBGREtyZWFkQml0cyhicyw0KTsKICAgIHBQY2UtPk51bUNoYW5uZWxzICs9IHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbaV0gPyAyIDogMTsKICB9CgogIHBQY2UtPk51bUVmZmVjdGl2ZUNoYW5uZWxzID0gcFBjZS0+TnVtQ2hhbm5lbHM7CgogIGZvciAoaT0wOyBpIDwgcFBjZS0+TnVtTGZlQ2hhbm5lbEVsZW1lbnRzOyBpKyspCiAgewogICAgcFBjZS0+TGZlRWxlbWVudFRhZ1NlbGVjdFtpXSA9IChVQ0hBUikgRkRLcmVhZEJpdHMoYnMsNCk7CiAgICBwUGNlLT5OdW1DaGFubmVscyArPSAxOwogIH0KCiAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1Bc3NvY0RhdGFFbGVtZW50czsgaSsrKQogIHsKICAgIHBQY2UtPkFzc29jRGF0YUVsZW1lbnRUYWdTZWxlY3RbaV0gPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDQpOwogIH0KCiAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1WYWxpZENjRWxlbWVudHM7IGkrKykKICB7CiAgICBwUGNlLT5DY0VsZW1lbnRJc0luZFN3W2ldID0gKFVDSEFSKSBGREtyZWFkQml0cyhicywxKTsKICAgIHBQY2UtPlZhbGlkQ2NFbGVtZW50VGFnU2VsZWN0W2ldID0gKFVDSEFSKSBGREtyZWFkQml0cyhicyw0KTsKICB9CgogIEZES2J5dGVBbGlnbihicywgYWxpZ25tZW50QW5jaG9yKTsKCiAgcFBjZS0+Q29tbWVudEZpZWxkQnl0ZXMgPSAoVUNIQVIpIEZES3JlYWRCaXRzKGJzLDgpOwogIGNvbW1lbnRCeXRlcyA9IHBQY2UtPkNvbW1lbnRGaWVsZEJ5dGVzOwoKICAvKiBTZWFyY2ggZm9yIGhlaWdodCBpbmZvIGV4dGVuc2lvbiBhbmQgcmVhZCBpdCBpZiBhdmFpbGFibGUgKi8KICBlcnIgPSBDUHJvZ3JhbUNvbmZpZ19SZWFkSGVpZ2h0RXh0KCBwUGNlLCBicywgJmNvbW1lbnRCeXRlcywgYWxpZ25tZW50QW5jaG9yICk7CgogIGZvciAoaT0wOyBpIDwgY29tbWVudEJ5dGVzOyBpKyspCiAgewogICAgVUNIQVIgdGV4dDsKCiAgICB0ZXh0ID0gKFVDSEFSKUZES3JlYWRCaXRzKGJzLDgpOwoKICAgIGlmIChpIDwgUENfQ09NTUVOVExFTkdUSCkKICAgIHsKICAgICAgcFBjZS0+Q29tbWVudFtpXSA9IHRleHQ7CiAgICB9CiAgfQoKICBwUGNlLT5pc1ZhbGlkID0gKGVycikgPyAwIDogMTsKfQoKLyoKICogQ29tcGFyZSB0d28gcHJvZ3JhbSBjb25maWd1cmF0aW9ucy4KICogUmV0dXJucyB0aGUgcmVzdWx0IG9mIHRoZSBjb21wYXJpc29uOgogKiAgLTEgLSBjb21wbGV0ZWx5IGRpZmZlcmVudAogKiAgIDAgLSBjb21wbGV0ZWx5IGVxdWFsCiAqICAgMSAtIGRpZmZlcmVudCBidXQgc2FtZSBjaGFubmVsIGNvbmZpZ3VyYXRpb24KICogICAyIC0gZGlmZmVyZW50IGNoYW5uZWwgY29uZmlndXJhdGlvbiBidXQgc2FtZSBudW1iZXIgb2YgY2hhbm5lbHMKICovCmludCBDUHJvZ3JhbUNvbmZpZ19Db21wYXJlICggY29uc3QgQ1Byb2dyYW1Db25maWcgKiBjb25zdCBwUGNlMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDUHJvZ3JhbUNvbmZpZyAqIGNvbnN0IHBQY2UyICkKewogIGludCByZXN1bHQgPSAwOyAgLyogSW5ub2NlbnQgdW50aWwgcHJvdmVuIGZhbHNlLiAqLwoKICBpZiAoRkRLbWVtY21wKHBQY2UxLCBwUGNlMiwgc2l6ZW9mKENQcm9ncmFtQ29uZmlnKSkgIT0gMCkKICB7IC8qIENvbmZpZ3VyYXRpb25zIGFyZSBub3QgY29tcGxldGVseSBkaWZmZXJlbnQuCiAgICAgICBTbyBsb29rIGludG8gZGV0YWlscyBhbmQgYW5hbHlzZSB0aGUgY2hhbm5lbCBjb25maWd1cmF0aW9uczogKi8KICAgIHJlc3VsdCA9IC0xOwoKICAgIGlmIChwUGNlMS0+TnVtQ2hhbm5lbHMgPT0gcFBjZTItPk51bUNoYW5uZWxzKQogICAgeyAvKiBOb3cgdGhlIGxvZ2ljIGNoYW5nZXMuIFdlIGZpcnN0IGFzc3VtZSB0byBoYXZlIHRoZSBzYW1lIGNoYW5uZWwgY29uZmlndXJhdGlvbgogICAgICAgICBhbmQgdGhlbiBwcm92ZSBpZiB0aGlzIGFzc3VtcHRpb24gaXMgdHJ1ZS4gKi8KICAgICAgcmVzdWx0ID0gMTsKCiAgICAgIC8qIEZyb250IGNoYW5uZWxzICovCiAgICAgIGlmIChwUGNlMS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHMgIT0gcFBjZTItPk51bUZyb250Q2hhbm5lbEVsZW1lbnRzKSB7CiAgICAgICAgcmVzdWx0ID0gMjsgIC8qIGRpZmZlcmVudCBudW1iZXIgb2YgZnJvbnQgY2hhbm5lbCBlbGVtZW50cyAqLwogICAgICB9IGVsc2UgewogICAgICAgIGludCBlbCwgbnVtQ2gxID0gMCwgbnVtQ2gyID0gMDsKICAgICAgICBmb3IgKGVsID0gMDsgZWwgPCBwUGNlMS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHM7IGVsICs9IDEpIHsKICAgICAgICAgIGlmIChwUGNlMS0+RnJvbnRFbGVtZW50SGVpZ2h0SW5mb1tlbF0gIT0gcFBjZTItPkZyb250RWxlbWVudEhlaWdodEluZm9bZWxdKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IDI7IC8qIGRpZmZlcmVudCBoZWlnaHQgaW5mbyAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIG51bUNoMSArPSBwUGNlMS0+RnJvbnRFbGVtZW50SXNDcGVbZWxdID8gMiA6IDE7CiAgICAgICAgICBudW1DaDIgKz0gcFBjZTItPkZyb250RWxlbWVudElzQ3BlW2VsXSA/IDIgOiAxOwogICAgICAgIH0KICAgICAgICBpZiAobnVtQ2gxICE9IG51bUNoMikgewogICAgICAgICAgcmVzdWx0ID0gMjsgIC8qIGRpZmZlcmVudCBudW1iZXIgb2YgZnJvbnQgY2hhbm5lbHMgKi8KICAgICAgICB9CiAgICAgIH0KICAgICAgLyogU2lkZSBjaGFubmVscyAqLwogICAgICBpZiAocFBjZTEtPk51bVNpZGVDaGFubmVsRWxlbWVudHMgIT0gcFBjZTItPk51bVNpZGVDaGFubmVsRWxlbWVudHMpIHsKICAgICAgICByZXN1bHQgPSAyOyAgLyogZGlmZmVyZW50IG51bWJlciBvZiBzaWRlIGNoYW5uZWwgZWxlbWVudHMgKi8KICAgICAgfSBlbHNlIHsKICAgICAgICBpbnQgZWwsIG51bUNoMSA9IDAsIG51bUNoMiA9IDA7CiAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZTEtPk51bVNpZGVDaGFubmVsRWxlbWVudHM7IGVsICs9IDEpIHsKICAgICAgICAgIGlmIChwUGNlMS0+U2lkZUVsZW1lbnRIZWlnaHRJbmZvW2VsXSAhPSBwUGNlMi0+U2lkZUVsZW1lbnRIZWlnaHRJbmZvW2VsXSkgewogICAgICAgICAgICByZXN1bHQgPSAyOyAvKiBkaWZmZXJlbnQgaGVpZ2h0IGluZm8gKi8KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBudW1DaDEgKz0gcFBjZTEtPlNpZGVFbGVtZW50SXNDcGVbZWxdID8gMiA6IDE7CiAgICAgICAgICBudW1DaDIgKz0gcFBjZTItPlNpZGVFbGVtZW50SXNDcGVbZWxdID8gMiA6IDE7CiAgICAgICAgfQogICAgICAgIGlmIChudW1DaDEgIT0gbnVtQ2gyKSB7CiAgICAgICAgICByZXN1bHQgPSAyOyAgLyogZGlmZmVyZW50IG51bWJlciBvZiBzaWRlIGNoYW5uZWxzICovCiAgICAgICAgfQogICAgICB9CiAgICAgIC8qIEJhY2sgY2hhbm5lbHMgKi8KICAgICAgaWYgKHBQY2UxLT5OdW1CYWNrQ2hhbm5lbEVsZW1lbnRzICE9IHBQY2UyLT5OdW1CYWNrQ2hhbm5lbEVsZW1lbnRzKSB7CiAgICAgICAgcmVzdWx0ID0gMjsgIC8qIGRpZmZlcmVudCBudW1iZXIgb2YgYmFjayBjaGFubmVsIGVsZW1lbnRzICovCiAgICAgIH0gZWxzZSB7CiAgICAgICAgaW50IGVsLCBudW1DaDEgPSAwLCBudW1DaDIgPSAwOwogICAgICAgIGZvciAoZWwgPSAwOyBlbCA8IHBQY2UxLT5OdW1CYWNrQ2hhbm5lbEVsZW1lbnRzOyBlbCArPSAxKSB7CiAgICAgICAgICBpZiAocFBjZTEtPkJhY2tFbGVtZW50SGVpZ2h0SW5mb1tlbF0gIT0gcFBjZTItPkJhY2tFbGVtZW50SGVpZ2h0SW5mb1tlbF0pIHsKICAgICAgICAgICAgcmVzdWx0ID0gMjsgLyogZGlmZmVyZW50IGhlaWdodCBpbmZvICovCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgbnVtQ2gxICs9IHBQY2UxLT5CYWNrRWxlbWVudElzQ3BlW2VsXSA/IDIgOiAxOwogICAgICAgICAgbnVtQ2gyICs9IHBQY2UyLT5CYWNrRWxlbWVudElzQ3BlW2VsXSA/IDIgOiAxOwogICAgICAgIH0KICAgICAgICBpZiAobnVtQ2gxICE9IG51bUNoMikgewogICAgICAgICAgcmVzdWx0ID0gMjsgIC8qIGRpZmZlcmVudCBudW1iZXIgb2YgYmFjayBjaGFubmVscyAqLwogICAgICAgIH0KICAgICAgfQogICAgICAvKiBMRkUgY2hhbm5lbHMgKi8KICAgICAgaWYgKHBQY2UxLT5OdW1MZmVDaGFubmVsRWxlbWVudHMgIT0gcFBjZTItPk51bUxmZUNoYW5uZWxFbGVtZW50cykgewogICAgICAgIHJlc3VsdCA9IDI7ICAvKiBkaWZmZXJlbnQgbnVtYmVyIG9mIGxmZSBjaGFubmVscyAqLwogICAgICB9CiAgICAgIC8qIExGRXMgYXJlIGFsd2F5cyBTQ0VzIHNvIHdlIGRvbid0IG5lZWQgdG8gY291bnQgdGhlIGNoYW5uZWxzLiAqLwogICAgfQogIH0KCiAgcmV0dXJuIHJlc3VsdDsKfQoKdm9pZCBDUHJvZ3JhbUNvbmZpZ19HZXREZWZhdWx0KCBDUHJvZ3JhbUNvbmZpZyAqcFBjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVSU5UIGNoYW5uZWxDb25maWcgKQp7CiAgRkRLX0FTU0VSVChwUGNlICE9IE5VTEwpOwoKICAvKiBJbml0IFBDRSAqLwogIENQcm9ncmFtQ29uZmlnX0luaXQocFBjZSk7CiAgcFBjZS0+UHJvZmlsZSA9IDE7ICAvKiBTZXQgQUFDIExDIGJlY2F1c2UgaXQgaXMgdGhlIG9ubHkgc3VwcG9ydGVkIG9iamVjdCB0eXBlLiAqLwoKICBzd2l0Y2ggKGNoYW5uZWxDb25maWcpIHsKICAvKiAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCiAgY2FzZSAzMjogLyogNy4xIHNpZGUgY2hhbm5lbCBjb25maWd1cmF0aW9uIGFzIGRlZmluZWQgaW4gRkRLX2F1ZGlvLmggKi8KICAgIHBQY2UtPk51bUZyb250Q2hhbm5lbEVsZW1lbnRzICA9IDI7CiAgICBwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVswXSAgICAgPSAwOwogICAgcFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbMV0gICAgID0gMTsKICAgIHBQY2UtPk51bVNpZGVDaGFubmVsRWxlbWVudHMgICA9IDE7CiAgICBwUGNlLT5TaWRlRWxlbWVudElzQ3BlWzBdICAgICAgPSAxOwogICAgcFBjZS0+TnVtQmFja0NoYW5uZWxFbGVtZW50cyAgID0gMTsKICAgIHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbMF0gICAgICA9IDE7CiAgICBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHMgICAgPSAxOwogICAgcFBjZS0+TnVtQ2hhbm5lbHMgICAgICAgICAgICAgID0gODsKICAgIHBQY2UtPk51bUVmZmVjdGl2ZUNoYW5uZWxzICAgICA9IDc7CiAgICBwUGNlLT5pc1ZhbGlkICAgICAgICAgICAgICAgICAgPSAxOwogICAgYnJlYWs7CiAgLyogLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAqLwogIGNhc2UgMTI6ICAvKiAzLzAvNC4xY2ggc3Vycm91bmQgYmFjayAqLwogICAgcFBjZS0+QmFja0VsZW1lbnRJc0NwZVsxXSAgICAgID0gMTsKICAgIHBQY2UtPk51bUNoYW5uZWxzICAgICAgICAgICAgICs9IDE7CiAgICBwUGNlLT5OdW1FZmZlY3RpdmVDaGFubmVscyAgICArPSAxOwogIGNhc2UgMTE6ICAvKiAzLzAvMy4xY2ggKi8KICAgIHBQY2UtPk51bUZyb250Q2hhbm5lbEVsZW1lbnRzICs9IDI7CiAgICBwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVswXSAgICAgPSAwOwogICAgcFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbMV0gICAgID0gMTsKICAgIHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHMgICs9IDI7CiAgICBwUGNlLT5CYWNrRWxlbWVudElzQ3BlWzBdICAgICAgPSAxOwogICAgcFBjZS0+QmFja0VsZW1lbnRJc0NwZVsxXSAgICAgKz0gMDsKICAgIHBQY2UtPk51bUxmZUNoYW5uZWxFbGVtZW50cyAgICs9IDE7CiAgICBwUGNlLT5OdW1DaGFubmVscyAgICAgICAgICAgICArPSA3OwogICAgcFBjZS0+TnVtRWZmZWN0aXZlQ2hhbm5lbHMgICAgKz0gNjsKICAgIHBQY2UtPmlzVmFsaWQgICAgICAgICAgICAgICAgICA9IDE7CiAgICBicmVhazsKICAvKiAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCiAgY2FzZSAxNDogIC8qIDIvMC8wLTMvMC8yLTAuMWNoIGZyb250IGhlaWdodCAqLwogICAgcFBjZS0+RnJvbnRFbGVtZW50SGVpZ2h0SW5mb1syXSA9IDE7ICAgICAgLyogVG9wIHNwZWFrZXIgKi8KICBjYXNlIDc6ICAgLyogNS8wLzIuMWNoIGZyb250ICovCiAgICBwUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50cyArPSAxOwogICAgcFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbMl0gICAgID0gMTsKICAgIHBQY2UtPk51bUNoYW5uZWxzICAgICAgICAgICAgICs9IDI7CiAgICBwUGNlLT5OdW1FZmZlY3RpdmVDaGFubmVscyAgICArPSAyOwogIGNhc2UgNjogICAvKiAzLzAvMi4xY2ggKi8KICAgIHBQY2UtPk51bUxmZUNoYW5uZWxFbGVtZW50cyAgICs9IDE7CiAgICBwUGNlLT5OdW1DaGFubmVscyAgICAgICAgICAgICArPSAxOwogIGNhc2UgNTogICAvKiAzLzAvMi4wY2ggKi8KICBjYXNlIDQ6ICAgLyogMy8wLzEuMGNoICovCiAgICBwUGNlLT5OdW1CYWNrQ2hhbm5lbEVsZW1lbnRzICArPSAxOwogICAgcFBjZS0+QmFja0VsZW1lbnRJc0NwZVswXSAgICAgID0gKGNoYW5uZWxDb25maWc+NCkgPyAxIDogMDsKICAgIHBQY2UtPk51bUNoYW5uZWxzICAgICAgICAgICAgICs9IChjaGFubmVsQ29uZmlnPjQpID8gMiA6IDE7CiAgICBwUGNlLT5OdW1FZmZlY3RpdmVDaGFubmVscyAgICArPSAoY2hhbm5lbENvbmZpZz40KSA/IDIgOiAxOwogIGNhc2UgMzogICAvKiAzLzAvMC4wY2ggKi8KICAgIHBQY2UtPk51bUZyb250Q2hhbm5lbEVsZW1lbnRzICs9IDE7CiAgICBwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVsxXSAgICAgPSAxOwogICAgcFBjZS0+TnVtQ2hhbm5lbHMgICAgICAgICAgICAgKz0gMjsKICAgIHBQY2UtPk51bUVmZmVjdGl2ZUNoYW5uZWxzICAgICs9IDI7CiAgY2FzZSAxOiAgIC8qIDEvMC8wLjBjaCAqLwogICAgcFBjZS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHMgKz0gMTsKICAgIHBQY2UtPkZyb250RWxlbWVudElzQ3BlWzBdICAgICA9IDA7CiAgICBwUGNlLT5OdW1DaGFubmVscyAgICAgICAgICAgICArPSAxOwogICAgcFBjZS0+TnVtRWZmZWN0aXZlQ2hhbm5lbHMgICAgKz0gMTsKICAgIHBQY2UtPmlzVmFsaWQgICAgICAgICAgICAgICAgICA9IDE7CiAgICBicmVhazsKICAvKiAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCiAgY2FzZSAyOiAgIC8qIDIvMC8wLmNoICovCiAgICBwUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50cyAgPSAxOwogICAgcFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbMF0gICAgID0gMTsKICAgIHBQY2UtPk51bUNoYW5uZWxzICAgICAgICAgICAgICs9IDI7CiAgICBwUGNlLT5OdW1FZmZlY3RpdmVDaGFubmVscyAgICArPSAyOwogICAgcFBjZS0+aXNWYWxpZCAgICAgICAgICAgICAgICAgID0gMTsKICAgIGJyZWFrOwogIC8qIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gKi8KICBkZWZhdWx0OgogICAgcFBjZS0+aXNWYWxpZCAgICAgICAgICAgICAgICAgID0gMDsgICAvKiBUbyBiZSBleHBsaWNpdCEgKi8KICAgIGJyZWFrOwogIH0KCiAgaWYgKHBQY2UtPmlzVmFsaWQpIHsKICAgIC8qIENyZWF0ZSB2YWxpZCBlbGVtZW50IGluc3RhbmNlIHRhZ3MgKi8KICAgIGludCBlbCwgZWxUYWdTY2UgPSAwLCBlbFRhZ0NwZSA9IDA7CgogICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHM7IGVsICs9IDEpIHsKICAgICAgcFBjZS0+RnJvbnRFbGVtZW50VGFnU2VsZWN0W2VsXSA9IChwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVtlbF0pID8gZWxUYWdDcGUrKyA6IGVsVGFnU2NlKys7CiAgICB9CiAgICBmb3IgKGVsID0gMDsgZWwgPCBwUGNlLT5OdW1TaWRlQ2hhbm5lbEVsZW1lbnRzOyBlbCArPSAxKSB7CiAgICAgIHBQY2UtPlNpZGVFbGVtZW50VGFnU2VsZWN0W2VsXSA9IChwUGNlLT5TaWRlRWxlbWVudElzQ3BlW2VsXSkgPyBlbFRhZ0NwZSsrIDogZWxUYWdTY2UrKzsKICAgIH0KICAgIGZvciAoZWwgPSAwOyBlbCA8IHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHM7IGVsICs9IDEpIHsKICAgICAgcFBjZS0+QmFja0VsZW1lbnRUYWdTZWxlY3RbZWxdID0gKHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbZWxdKSA/IGVsVGFnQ3BlKysgOiBlbFRhZ1NjZSsrOwogICAgfQogICAgZWxUYWdTY2UgPSAwOwogICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtTGZlQ2hhbm5lbEVsZW1lbnRzOyBlbCArPSAxKSB7CiAgICAgIHBQY2UtPkxmZUVsZW1lbnRUYWdTZWxlY3RbZWxdID0gZWxUYWdTY2UrKzsKICAgIH0KICB9Cn0KI2VuZGlmIC8qIFRQX1BDRV9FTkFCTEUgKi8KCi8qKgogKiBcYnJpZWYgZ2V0IGltcGxpY2l0IGF1ZGlvIGNoYW5uZWwgdHlwZSBmb3IgZ2l2ZW4gY2hhbm5lbENvbmZpZyBhbmQgTVBFRyBvcmRlcmVkIGNoYW5uZWwgaW5kZXgKICogXHBhcmFtIGNoYW5uZWxDb25maWcgTVBFRyBjaGFubmVsQ29uZmlndXJhdGlvbiBmcm9tIDEgdXB0byAxNAogKiBccGFyYW0gaW5kZXggTVBFRyBjaGFubmVsIG9yZGVyIGluZGV4CiAqIFxyZXR1cm4gYXVkaW8gY2hhbm5lbCB0eXBlLgogKi8Kc3RhdGljCnZvaWQgZ2V0SW1wbGljaXRBdWRpb0NoYW5uZWxUeXBlQW5kSW5kZXgoCiAgICAgICAgQVVESU9fQ0hBTk5FTF9UWVBFICpjaFR5cGUsCiAgICAgICAgVUNIQVIgKmNoSW5kZXgsCiAgICAgICAgVUlOVCBjaGFubmVsQ29uZmlnLAogICAgICAgIFVJTlQgaW5kZXgKICAgICAgICApCnsKICBpZiAoaW5kZXggPCAzKSB7CiAgICAqY2hUeXBlID0gQUNUX0ZST05UOwogICAgKmNoSW5kZXggPSBpbmRleDsKICB9IGVsc2UgewogICAgc3dpdGNoIChjaGFubmVsQ29uZmlnKSB7CiAgICAgIGNhc2UgNDogIC8qIFNDRSwgQ1BFLCBTQ0UgKi8KICAgICAgY2FzZSA1OiAgLyogU0NFLCBDUEUsIENQRSAqLwogICAgICBjYXNlIDY6ICAvKiBTQ0UsIENQRSwgQ1BFLCBMRkUgKi8KICAgICAgICBzd2l0Y2ggKGluZGV4KSB7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICpjaFR5cGUgPSBBQ1RfQkFDSzsKICAgICAgICAgICAgKmNoSW5kZXggPSBpbmRleCAtIDM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICAqY2hUeXBlID0gQUNUX0xGRTsKICAgICAgICAgICAgKmNoSW5kZXggPSAwOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgNzogIC8qIFNDRSxDUEUsQ1BFLENQRSxMRkUgKi8KICAgICAgICBzd2l0Y2ggKGluZGV4KSB7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICpjaFR5cGUgPSBBQ1RfRlJPTlQ7CiAgICAgICAgICAgICpjaEluZGV4ID0gaW5kZXg7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgY2FzZSA2OgogICAgICAgICAgICAqY2hUeXBlID0gQUNUX0JBQ0s7CiAgICAgICAgICAgICpjaEluZGV4ID0gaW5kZXggLSA1OwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgKmNoVHlwZSA9IEFDVF9MRkU7CiAgICAgICAgICAgICpjaEluZGV4ID0gMDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDExOiAgLyogU0NFLENQRSxDUEUsU0NFLExGRSAqLwogICAgICAgIGlmIChpbmRleCA8IDYpIHsKICAgICAgICAgICpjaFR5cGUgPSBBQ1RfQkFDSzsKICAgICAgICAgICpjaEluZGV4ID0gaW5kZXggLSAzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAqY2hUeXBlID0gQUNUX0xGRTsKICAgICAgICAgICpjaEluZGV4ID0gMDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMTI6ICAvKiBTQ0UsQ1BFLENQRSxDUEUsTEZFICovCiAgICAgICAgaWYgKGluZGV4IDwgNykgewogICAgICAgICAgKmNoVHlwZSA9IEFDVF9CQUNLOwogICAgICAgICAgKmNoSW5kZXggPSBpbmRleCAtIDM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICpjaFR5cGUgPSBBQ1RfTEZFOwogICAgICAgICAgKmNoSW5kZXggPSAwOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSAxNDogIC8qIFNDRSxDUEUsQ1BFLExGRSxDUEUgKi8KICAgICAgICBzd2l0Y2ggKGluZGV4KSB7CiAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICpjaFR5cGUgPSBBQ1RfQkFDSzsKICAgICAgICAgICAgKmNoSW5kZXggPSBpbmRleCAtIDM7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgY2FzZSA1OgogICAgICAgICAgICAqY2hUeXBlID0gQUNUX0xGRTsKICAgICAgICAgICAgKmNoSW5kZXggPSAwOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgNjoKICAgICAgICAgIGNhc2UgNzoKICAgICAgICAgICAgKmNoVHlwZSA9IEFDVF9GUk9OVF9UT1A7CiAgICAgICAgICAgICpjaEluZGV4ID0gaW5kZXggLSA2OyAgLyogaGFuZGxlIHRoZSB0b3AgbGF5ZXIgaW5kZXBlbmRlbnRseSAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgKmNoVHlwZSA9IEFDVF9OT05FOwogICAgICAgIGJyZWFrOwogICAgfQogIH0KfQoKaW50IENQcm9ncmFtQ29uZmlnX0xvb2t1cEVsZW1lbnQoCiAgICAgICAgQ1Byb2dyYW1Db25maWcgKnBQY2UsCiAgICAgICAgVUlOVCAgICAgICAgICAgIGNoYW5uZWxDb25maWcsCiAgICAgICAgY29uc3QgVUlOVCAgICAgIHRhZywKICAgICAgICBjb25zdCBVSU5UICAgICAgY2hhbm5lbElkeCwKICAgICAgICBVQ0hBUiAgICAgICAgICAgY2hNYXBwaW5nW10sCiAgICAgICAgQVVESU9fQ0hBTk5FTF9UWVBFIGNoVHlwZVtdLAogICAgICAgIFVDSEFSICAgICAgICAgICBjaEluZGV4W10sCiAgICAgICAgVUNIQVIgICAgICAgICAgKmVsTWFwcGluZywKICAgICAgICBNUDRfRUxFTUVOVF9JRCAgZWxMaXN0W10sCiAgICAgICAgTVA0X0VMRU1FTlRfSUQgIGVsVHlwZQogICAgICAgKQp7CiAgaWYgKGNoYW5uZWxDb25maWcgPiAwKQogIHsKICAgIC8qIENvbnN0YW50IGNoYW5uZWwgbWFwcGluZyBtdXN0IGhhdmUKICAgICAgIGJlZW4gc2V0IGR1cmluZyBpbml0aWFsaXphdGlvbi4gKi8KICAgIGlmICggZWxUeXBlID09IElEX1NDRQogICAgICB8fCBlbFR5cGUgPT0gSURfQ1BFCiAgICAgIHx8IGVsVHlwZSA9PSBJRF9MRkUgKQogICAgewogICAgICAqZWxNYXBwaW5nID0gcFBjZS0+ZWxDb3VudGVyOwogICAgICBpZiAoZWxMaXN0W3BQY2UtPmVsQ291bnRlcl0gIT0gZWxUeXBlKSB7CiAgICAgICAgLyogTm90IGluIHRoZSBsaXN0ICovCiAgICAgICAgaWYgKCAoY2hhbm5lbENvbmZpZyA9PSAyKSAmJiAoZWxUeXBlID09IElEX1NDRSkgKQogICAgICAgIHsgLyogVGhpcyBzY2VuYXJpbyBvY2N1cnMgd2l0aCBIRS1BQUMgdjIgc3RyZWFtcyBvZiBidWdneSBlbmNvZGVycy4KICAgICAgICAgICAgIER1ZSB0byBvdGhlciBkZWNvZGVyIGltcGxlbWVudGF0aW9ucyBkZWNvZGluZyBvZiB0aGVzZSBraW5kIG9mIHN0cmVhbXMgaXMgZGVzaXJlZC4gKi8KICAgICAgICAgIGNoYW5uZWxDb25maWcgPSAxOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyogQXNzdW1lIGFsbCBmcm9udCBjaGFubmVscyAqLwogICAgICBnZXRJbXBsaWNpdEF1ZGlvQ2hhbm5lbFR5cGVBbmRJbmRleCgmY2hUeXBlW2NoYW5uZWxJZHhdLCAmY2hJbmRleFtjaGFubmVsSWR4XSwgY2hhbm5lbENvbmZpZywgY2hhbm5lbElkeCk7CiAgICAgIGlmIChlbFR5cGUgPT0gSURfQ1BFKSB7CiAgICAgICAgY2hUeXBlW2NoYW5uZWxJZHgrMV0gPSBjaFR5cGVbY2hhbm5lbElkeF07CiAgICAgICAgY2hJbmRleFtjaGFubmVsSWR4KzFdID0gY2hJbmRleFtjaGFubmVsSWR4XSsxOwogICAgICB9CiAgICAgIHBQY2UtPmVsQ291bnRlcisrOwogICAgfQogICAgLyogQWNjZXB0IGFsbCBub24tY2hhbm5lbCBlbGVtZW50cywgdG9vLiAqLwogICAgcmV0dXJuIDE7CiAgfQogIGVsc2UKICB7CiNpZmRlZiBUUF9QQ0VfRU5BQkxFCiAgICBpZiAoIXBQY2UtPmlzVmFsaWQpCiNlbmRpZiAvKiBUUF9QQ0VfRU5BQkxFICovCiAgICB7CiAgICAgIC8qIEltcGxpY2l0IGNoYW5uZWwgbWFwcGluZy4gKi8KICAgICAgaWYgKCBlbFR5cGUgPT0gSURfU0NFCiAgICAgICAgfHwgZWxUeXBlID09IElEX0NQRQogICAgICAgIHx8IGVsVHlwZSA9PSBJRF9MRkUgKQogICAgICB7CiAgICAgICAgLyogU3RvcmUgYWxsIGNoYW5uZWwgZWxlbWVudCBJRHMgKi8KICAgICAgICBlbExpc3RbcFBjZS0+ZWxDb3VudGVyXSA9IGVsVHlwZTsKICAgICAgICAqZWxNYXBwaW5nID0gcFBjZS0+ZWxDb3VudGVyKys7CiAgICAgIH0KICAgIH0KI2lmZGVmICBUUF9QQ0VfRU5BQkxFCiAgICBlbHNlIHsKICAgICAgLyogQWNjZXB0IHRoZSBhZGRpdGlvbmFsIGNoYW5uZWwocyksIG9ubHkgaWYgdGhlIHRhZyBpcyBpbiB0aGUgbGlzdHMgKi8KICAgICAgaW50IGlzQ3BlID0gMCwgaTsKICAgICAgLyogRWxlbWVudCBjb3VudGVyICovCiAgICAgIGludCBlY1tQQ19OVU1fSEVJR0hUX0xBWUVSXSA9IHswfTsKICAgICAgLyogQ2hhbm5lbCBjb3VudGVycyAqLwogICAgICBpbnQgY2NbUENfTlVNX0hFSUdIVF9MQVlFUl0gPSB7MH07CiAgICAgIGludCBmY1tQQ19OVU1fSEVJR0hUX0xBWUVSXSA9IHswfTsKICAgICAgaW50IHNjW1BDX05VTV9IRUlHSFRfTEFZRVJdID0gezB9OwogICAgICBpbnQgYmNbUENfTlVNX0hFSUdIVF9MQVlFUl0gPSB7MH07CiAgICAgIGludCBsYyA9IDA7OwoKICAgICAgLyogR2VuZXJhbCBNUEVHIChQQ0UpIGNvbXBvc2l0aW9uIHJ1bGVzOgogICAgICAgICAtIE92ZXIgYWxsOgogICAgICAgICAgICAgPG5vcm1hbCBoZWlnaHQgY2hhbm5lbHM+PHRvcCBoZWlnaHQgY2hhbm5lbHM+PGJvdHRvbSBoZWlnaHQgY2hhbm5lbHM+CiAgICAgICAgIC0gV2l0aGluIGVhY2ggaGVpZ2h0IGxheWVyOgogICAgICAgICAgICAgPGZyb250IGNoYW5uZWxzPjxzaWRlIGNoYW5uZWxzPjxiYWNrIGNoYW5uZWxzPgogICAgICAgICAtIEV4Y2VwdGlvbjoKICAgICAgICAgICAgIFRoZSBMRkUgY2hhbm5lbHMgaGF2ZSBubyBoZWlnaHQgaW5mbyBhbmQgdGh1cyB0aGV5IGFyZSBhcnJhbmdlZCBhdCB0aGUgdmVyeQogICAgICAgICAgICAgZW5kIG9mIHRoZSBub3JtYWwgaGVpZ2h0IGxheWVyIGNoYW5uZWxzLgogICAgICAgKi8KCiAgICAgIHN3aXRjaCAoZWxUeXBlKQogICAgICB7CiAgICAgIGNhc2UgSURfQ1BFOgogICAgICAgIGlzQ3BlID0gMTsKICAgICAgY2FzZSBJRF9TQ0U6CiAgICAgICAgLyogc2VhcmNoIGluIGZyb250IGNoYW5uZWxzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBQY2UtPk51bUZyb250Q2hhbm5lbEVsZW1lbnRzOyBpKyspIHsKICAgICAgICAgIGludCBoZWlnaHRMYXllciA9IHBQY2UtPkZyb250RWxlbWVudEhlaWdodEluZm9baV07CiAgICAgICAgICBpZiAoaXNDcGUgPT0gcFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbaV0gJiYgcFBjZS0+RnJvbnRFbGVtZW50VGFnU2VsZWN0W2ldID09IHRhZykgewogICAgICAgICAgICBpbnQgaCwgZWxJZHggPSBlY1toZWlnaHRMYXllcl0sIGNoSWR4ID0gY2NbaGVpZ2h0TGF5ZXJdOwogICAgICAgICAgICBBVURJT19DSEFOTkVMX1RZUEUgYUNoVHlwZSA9IChBVURJT19DSEFOTkVMX1RZUEUpKChoZWlnaHRMYXllcjw8NCkgfCBBQ1RfRlJPTlQpOwogICAgICAgICAgICBmb3IgKGggPSBoZWlnaHRMYXllci0xOyBoID49IDA7IGgtPTEpIHsKICAgICAgICAgICAgICBpbnQgZWw7CiAgICAgICAgICAgICAgLyogQ291bnQgZnJvbnQgY2hhbm5lbHMvZWxlbWVudHMgKi8KICAgICAgICAgICAgICBmb3IgKGVsID0gMDsgZWwgPCBwUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50czsgZWwrPTEpIHsKICAgICAgICAgICAgICAgIGlmIChwUGNlLT5Gcm9udEVsZW1lbnRIZWlnaHRJbmZvW2VsXSA9PSBoKSB7CiAgICAgICAgICAgICAgICAgIGVsSWR4ICs9IDE7CiAgICAgICAgICAgICAgICAgIGNoSWR4ICs9IChwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVtlbF0pID8gMiA6IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIC8qIENvdW50IHNpZGUgY2hhbm5lbHMvZWxlbWVudHMgKi8KICAgICAgICAgICAgICBmb3IgKGVsID0gMDsgZWwgPCBwUGNlLT5OdW1TaWRlQ2hhbm5lbEVsZW1lbnRzOyBlbCs9MSkgewogICAgICAgICAgICAgICAgaWYgKHBQY2UtPlNpZGVFbGVtZW50SGVpZ2h0SW5mb1tlbF0gPT0gaCkgewogICAgICAgICAgICAgICAgICBlbElkeCArPSAxOwogICAgICAgICAgICAgICAgICBjaElkeCArPSAocFBjZS0+U2lkZUVsZW1lbnRJc0NwZVtlbF0pID8gMiA6IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIC8qIENvdW50IGJhY2sgY2hhbm5lbHMvZWxlbWVudHMgKi8KICAgICAgICAgICAgICBmb3IgKGVsID0gMDsgZWwgPCBwUGNlLT5OdW1CYWNrQ2hhbm5lbEVsZW1lbnRzOyBlbCs9MSkgewogICAgICAgICAgICAgICAgaWYgKHBQY2UtPkJhY2tFbGVtZW50SGVpZ2h0SW5mb1tlbF0gPT0gaCkgewogICAgICAgICAgICAgICAgICBlbElkeCArPSAxOwogICAgICAgICAgICAgICAgICBjaElkeCArPSAocFBjZS0+QmFja0VsZW1lbnRJc0NwZVtlbF0pID8gMiA6IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChoID09IDApIHsgIC8qIG5vcm1hbCBoZWlnaHQgKi8KICAgICAgICAgICAgICAgIGVsSWR4ICs9IHBQY2UtPk51bUxmZUNoYW5uZWxFbGVtZW50czsKICAgICAgICAgICAgICAgIGNoSWR4ICs9IHBQY2UtPk51bUxmZUNoYW5uZWxFbGVtZW50czsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2hNYXBwaW5nW2NoSWR4XSA9IGNoYW5uZWxJZHg7CiAgICAgICAgICAgIGNoVHlwZVtjaElkeF0gPSBhQ2hUeXBlOwogICAgICAgICAgICBjaEluZGV4W2NoSWR4XSA9IGZjW2hlaWdodExheWVyXTsKICAgICAgICAgICAgaWYgKGlzQ3BlKSB7CiAgICAgICAgICAgICAgY2hNYXBwaW5nW2NoSWR4KzFdID0gY2hhbm5lbElkeCsxOwogICAgICAgICAgICAgIGNoVHlwZVtjaElkeCsxXSA9IGFDaFR5cGU7CiAgICAgICAgICAgICAgY2hJbmRleFtjaElkeCsxXSA9IGZjW2hlaWdodExheWVyXSsxOwogICAgICAgICAgICB9CiAgICAgICAgICAgICplbE1hcHBpbmcgPSBlbElkeDsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICB9CiAgICAgICAgICBlY1toZWlnaHRMYXllcl0gKz0gMTsKICAgICAgICAgIGlmIChwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVtpXSkgewogICAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gMjsKICAgICAgICAgICAgZmNbaGVpZ2h0TGF5ZXJdICs9IDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gMTsKICAgICAgICAgICAgZmNbaGVpZ2h0TGF5ZXJdICs9IDE7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qIHNlYXJjaCBpbiBzaWRlIGNoYW5uZWxzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBQY2UtPk51bVNpZGVDaGFubmVsRWxlbWVudHM7IGkrKykgewogICAgICAgICAgaW50IGhlaWdodExheWVyID0gcFBjZS0+U2lkZUVsZW1lbnRIZWlnaHRJbmZvW2ldOwogICAgICAgICAgaWYgKGlzQ3BlID09IHBQY2UtPlNpZGVFbGVtZW50SXNDcGVbaV0gJiYgcFBjZS0+U2lkZUVsZW1lbnRUYWdTZWxlY3RbaV0gPT0gdGFnKSB7CiAgICAgICAgICAgIGludCBoLCBlbElkeCA9IGVjW2hlaWdodExheWVyXSwgY2hJZHggPSBjY1toZWlnaHRMYXllcl07CiAgICAgICAgICAgIEFVRElPX0NIQU5ORUxfVFlQRSBhQ2hUeXBlID0gKEFVRElPX0NIQU5ORUxfVFlQRSkoKGhlaWdodExheWVyPDw0KSB8IEFDVF9TSURFKTsKICAgICAgICAgICAgZm9yIChoID0gaGVpZ2h0TGF5ZXItMTsgaCA+PSAwOyBoLT0xKSB7CiAgICAgICAgICAgICAgaW50IGVsOwogICAgICAgICAgICAgIC8qIENvdW50IGZyb250IGNoYW5uZWxzL2VsZW1lbnRzICovCiAgICAgICAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHM7IGVsKz0xKSB7CiAgICAgICAgICAgICAgICBpZiAocFBjZS0+RnJvbnRFbGVtZW50SGVpZ2h0SW5mb1tlbF0gPT0gaCkgewogICAgICAgICAgICAgICAgICBlbElkeCArPSAxOwogICAgICAgICAgICAgICAgICBjaElkeCArPSAocFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbZWxdKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAvKiBDb3VudCBzaWRlIGNoYW5uZWxzL2VsZW1lbnRzICovCiAgICAgICAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtU2lkZUNoYW5uZWxFbGVtZW50czsgZWwrPTEpIHsKICAgICAgICAgICAgICAgIGlmIChwUGNlLT5TaWRlRWxlbWVudEhlaWdodEluZm9bZWxdID09IGgpIHsKICAgICAgICAgICAgICAgICAgZWxJZHggKz0gMTsKICAgICAgICAgICAgICAgICAgY2hJZHggKz0gKHBQY2UtPlNpZGVFbGVtZW50SXNDcGVbZWxdKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAvKiBDb3VudCBiYWNrIGNoYW5uZWxzL2VsZW1lbnRzICovCiAgICAgICAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtQmFja0NoYW5uZWxFbGVtZW50czsgZWwrPTEpIHsKICAgICAgICAgICAgICAgIGlmIChwUGNlLT5CYWNrRWxlbWVudEhlaWdodEluZm9bZWxdID09IGgpIHsKICAgICAgICAgICAgICAgICAgZWxJZHggKz0gMTsKICAgICAgICAgICAgICAgICAgY2hJZHggKz0gKHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbZWxdKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoaCA9PSAwKSB7ICAvKiBMRkUgY2hhbm5lbHMgYmVsb25nIHRvIHRoZSBub3JtYWwgaGVpZ2h0IGxheWVyICovCiAgICAgICAgICAgICAgICBlbElkeCArPSBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHM7CiAgICAgICAgICAgICAgICBjaElkeCArPSBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHM7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGNoTWFwcGluZ1tjaElkeF0gPSBjaGFubmVsSWR4OwogICAgICAgICAgICBjaFR5cGVbY2hJZHhdID0gYUNoVHlwZTsKICAgICAgICAgICAgY2hJbmRleFtjaElkeF0gPSBzY1toZWlnaHRMYXllcl07CiAgICAgICAgICAgIGlmIChpc0NwZSkgewogICAgICAgICAgICAgIGNoTWFwcGluZ1tjaElkeCsxXSA9IGNoYW5uZWxJZHgrMTsKICAgICAgICAgICAgICBjaFR5cGVbY2hJZHgrMV0gPSBhQ2hUeXBlOwogICAgICAgICAgICAgIGNoSW5kZXhbY2hJZHgrMV0gPSBzY1toZWlnaHRMYXllcl0rMTsKICAgICAgICAgICAgfQogICAgICAgICAgICAqZWxNYXBwaW5nID0gZWxJZHg7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgfQogICAgICAgICAgZWNbaGVpZ2h0TGF5ZXJdICs9IDE7CiAgICAgICAgICBpZiAocFBjZS0+U2lkZUVsZW1lbnRJc0NwZVtpXSkgewogICAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gMjsKICAgICAgICAgICAgc2NbaGVpZ2h0TGF5ZXJdICs9IDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gMTsKICAgICAgICAgICAgc2NbaGVpZ2h0TGF5ZXJdICs9IDE7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qIHNlYXJjaCBpbiBiYWNrIGNoYW5uZWxzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHM7IGkrKykgewogICAgICAgICAgaW50IGhlaWdodExheWVyID0gcFBjZS0+QmFja0VsZW1lbnRIZWlnaHRJbmZvW2ldOwogICAgICAgICAgaWYgKGlzQ3BlID09IHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbaV0gJiYgcFBjZS0+QmFja0VsZW1lbnRUYWdTZWxlY3RbaV0gPT0gdGFnKSB7CiAgICAgICAgICAgIGludCBoLCBlbElkeCA9IGVjW2hlaWdodExheWVyXSwgY2hJZHggPSBjY1toZWlnaHRMYXllcl07CiAgICAgICAgICAgIEFVRElPX0NIQU5ORUxfVFlQRSBhQ2hUeXBlID0gKEFVRElPX0NIQU5ORUxfVFlQRSkoKGhlaWdodExheWVyPDw0KSB8IEFDVF9CQUNLKTsKICAgICAgICAgICAgZm9yIChoID0gaGVpZ2h0TGF5ZXItMTsgaCA+PSAwOyBoLT0xKSB7CiAgICAgICAgICAgICAgaW50IGVsOwogICAgICAgICAgICAgIC8qIENvdW50IGZyb250IGNoYW5uZWxzL2VsZW1lbnRzICovCiAgICAgICAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHM7IGVsKz0xKSB7CiAgICAgICAgICAgICAgICBpZiAocFBjZS0+RnJvbnRFbGVtZW50SGVpZ2h0SW5mb1tlbF0gPT0gaCkgewogICAgICAgICAgICAgICAgICBlbElkeCArPSAxOwogICAgICAgICAgICAgICAgICBjaElkeCArPSAocFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbZWxdKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAvKiBDb3VudCBzaWRlIGNoYW5uZWxzL2VsZW1lbnRzICovCiAgICAgICAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtU2lkZUNoYW5uZWxFbGVtZW50czsgZWwrPTEpIHsKICAgICAgICAgICAgICAgIGlmIChwUGNlLT5TaWRlRWxlbWVudEhlaWdodEluZm9bZWxdID09IGgpIHsKICAgICAgICAgICAgICAgICAgZWxJZHggKz0gMTsKICAgICAgICAgICAgICAgICAgY2hJZHggKz0gKHBQY2UtPlNpZGVFbGVtZW50SXNDcGVbZWxdKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAvKiBDb3VudCBiYWNrIGNoYW5uZWxzL2VsZW1lbnRzICovCiAgICAgICAgICAgICAgZm9yIChlbCA9IDA7IGVsIDwgcFBjZS0+TnVtQmFja0NoYW5uZWxFbGVtZW50czsgZWwrPTEpIHsKICAgICAgICAgICAgICAgIGlmIChwUGNlLT5CYWNrRWxlbWVudEhlaWdodEluZm9bZWxdID09IGgpIHsKICAgICAgICAgICAgICAgICAgZWxJZHggKz0gMTsKICAgICAgICAgICAgICAgICAgY2hJZHggKz0gKHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbZWxdKSA/IDIgOiAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoaCA9PSAwKSB7ICAvKiBub3JtYWwgaGVpZ2h0ICovCiAgICAgICAgICAgICAgICBlbElkeCArPSBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHM7CiAgICAgICAgICAgICAgICBjaElkeCArPSBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHM7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGNoTWFwcGluZ1tjaElkeF0gPSBjaGFubmVsSWR4OwogICAgICAgICAgICBjaFR5cGVbY2hJZHhdID0gYUNoVHlwZTsKICAgICAgICAgICAgY2hJbmRleFtjaElkeF0gPSBiY1toZWlnaHRMYXllcl07CiAgICAgICAgICAgIGlmIChpc0NwZSkgewogICAgICAgICAgICAgIGNoTWFwcGluZ1tjaElkeCsxXSA9IGNoYW5uZWxJZHgrMTsKICAgICAgICAgICAgICBjaFR5cGVbY2hJZHgrMV0gPSBhQ2hUeXBlOwogICAgICAgICAgICAgIGNoSW5kZXhbY2hJZHgrMV0gPSBiY1toZWlnaHRMYXllcl0rMTsKICAgICAgICAgICAgfQogICAgICAgICAgICAqZWxNYXBwaW5nID0gZWxJZHg7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgfQogICAgICAgICAgZWNbaGVpZ2h0TGF5ZXJdICs9IDE7CiAgICAgICAgICBpZiAocFBjZS0+QmFja0VsZW1lbnRJc0NwZVtpXSkgewogICAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gMjsKICAgICAgICAgICAgYmNbaGVpZ2h0TGF5ZXJdICs9IDI7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gMTsKICAgICAgICAgICAgYmNbaGVpZ2h0TGF5ZXJdICs9IDE7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBJRF9MRkU6CiAgICAgIHsgLyogVW5mb3J0dW5hdGVseSB3ZSBoYXZlIHRvIGdvIHRocm91Z2ggYWxsIG5vcm1hbCBoZWlnaHQKICAgICAgICAgICBsYXllciBlbGVtZW50cyB0byBnZXQgdGhlIHBvc2l0aW9uIG9mIHRoZSBMRkUgY2hhbm5lbHMuCiAgICAgICAgICAgU3RhcnQgd2l0aCBjb3VudGluZyB0aGUgZnJvbnQgY2hhbm5lbHMvZWxlbWVudHMgYXQgbm9ybWFsIGhlaWdodCAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBwUGNlLT5OdW1Gcm9udENoYW5uZWxFbGVtZW50czsgaSs9MSkgewogICAgICAgICAgaW50IGhlaWdodExheWVyID0gcFBjZS0+RnJvbnRFbGVtZW50SGVpZ2h0SW5mb1tpXTsKICAgICAgICAgIGVjW2hlaWdodExheWVyXSArPSAxOwogICAgICAgICAgY2NbaGVpZ2h0TGF5ZXJdICs9IChwUGNlLT5Gcm9udEVsZW1lbnRJc0NwZVtpXSkgPyAyIDogMTsKICAgICAgICB9CiAgICAgICAgLyogQ291bnQgc2lkZSBjaGFubmVscy9lbGVtZW50cyBhdCBub3JtYWwgaGVpZ2h0ICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBQY2UtPk51bVNpZGVDaGFubmVsRWxlbWVudHM7IGkrPTEpIHsKICAgICAgICAgIGludCBoZWlnaHRMYXllciA9IHBQY2UtPlNpZGVFbGVtZW50SGVpZ2h0SW5mb1tpXTsKICAgICAgICAgIGVjW2hlaWdodExheWVyXSArPSAxOwogICAgICAgICAgY2NbaGVpZ2h0TGF5ZXJdICs9IChwUGNlLT5TaWRlRWxlbWVudElzQ3BlW2ldKSA/IDIgOiAxOwogICAgICAgIH0KICAgICAgICAvKiBDb3VudCBiYWNrIGNoYW5uZWxzL2VsZW1lbnRzIGF0IG5vcm1hbCBoZWlnaHQgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcFBjZS0+TnVtQmFja0NoYW5uZWxFbGVtZW50czsgaSs9MSkgewogICAgICAgICAgaW50IGhlaWdodExheWVyID0gcFBjZS0+QmFja0VsZW1lbnRIZWlnaHRJbmZvW2ldOwogICAgICAgICAgZWNbaGVpZ2h0TGF5ZXJdICs9IDE7CiAgICAgICAgICBjY1toZWlnaHRMYXllcl0gKz0gKHBQY2UtPkJhY2tFbGVtZW50SXNDcGVbaV0pID8gMiA6IDE7CiAgICAgICAgfQoKICAgICAgICAvKiBzZWFyY2ggaW4gbGZlIGNoYW5uZWxzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBQY2UtPk51bUxmZUNoYW5uZWxFbGVtZW50czsgaSsrKSB7CiAgICAgICAgICBpbnQgZWxJZHggPSBlY1swXTsgIC8qIExGRSBjaGFubmVscyBiZWxvbmcgdG8gdGhlIG5vcm1hbCBoZWlnaHQgbGF5ZXIgKi8KICAgICAgICAgIGludCBjaElkeCA9IGNjWzBdOwogICAgICAgICAgaWYgKCBwUGNlLT5MZmVFbGVtZW50VGFnU2VsZWN0W2ldID09IHRhZyApIHsKICAgICAgICAgICAgY2hNYXBwaW5nW2NoSWR4XSA9IGNoYW5uZWxJZHg7CiAgICAgICAgICAgICplbE1hcHBpbmcgPSBlbElkeDsKICAgICAgICAgICAgY2hUeXBlW2NoSWR4XSA9IEFDVF9MRkU7CiAgICAgICAgICAgIGNoSW5kZXhbY2hJZHhdID0gbGM7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgfQogICAgICAgICAgZWNbMF0gKz0gMTsKICAgICAgICAgIGNjWzBdICs9IDE7CiAgICAgICAgICBsYyArPSAxOwogICAgICAgIH0KICAgICAgfSBicmVhazsKCiAgICAgIC8qIE5vbiBhdWRpbyBlbGVtZW50cyAqLwogICAgICBjYXNlIElEX0NDRToKICAgICAgICAvKiBzZWFyY2ggaW4gY2NlIGNoYW5uZWxzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBQY2UtPk51bVZhbGlkQ2NFbGVtZW50czsgaSsrKSB7CiAgICAgICAgICBpZiAocFBjZS0+VmFsaWRDY0VsZW1lbnRUYWdTZWxlY3RbaV0gPT0gdGFnKSB7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSBJRF9EU0U6CiAgICAgICAgLyogc2VhcmNoIGFzc29jaWF0ZWQgZGF0YSBlbGVtZW50cyAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBwUGNlLT5OdW1Bc3NvY0RhdGFFbGVtZW50czsgaSsrKSB7CiAgICAgICAgICBpZiAocFBjZS0+QXNzb2NEYXRhRWxlbWVudFRhZ1NlbGVjdFtpXSA9PSB0YWcpIHsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiAwOwogICAgICB9CiAgICAgIHJldHVybiAwOyAgLyogbm90IGZvdW5kIGluIGFueSBsaXN0ICovCiAgICB9CiNlbmRpZiAvKiBUUF9QQ0VfRU5BQkxFICovCiAgfQoKICByZXR1cm4gMTsKfQoKI2lmZGVmICBUUF9QQ0VfRU5BQkxFCmludCBDUHJvZ3JhbUNvbmZpZ19HZXRFbGVtZW50VGFibGUoCiAgICAgICAgY29uc3QgQ1Byb2dyYW1Db25maWcgKnBQY2UsCiAgICAgICAgTVA0X0VMRU1FTlRfSUQgIGVsTGlzdFtdLAogICAgICAgIGNvbnN0IElOVCBlbExpc3RTaXplLAogICAgICAgIFVDSEFSICpwQ2hNYXBJZHgKICAgICAgICkKewogIGludCBpLCBlbCA9IDA7CgogIEZES19BU1NFUlQoZWxMaXN0ICE9IE5VTEwpOwogIEZES19BU1NFUlQocENoTWFwSWR4ICE9IE5VTEwpOwoKICAqcENoTWFwSWR4ID0gMDsKCiAgaWYgKCBlbExpc3RTaXplCiAgICA8IHBQY2UtPk51bUZyb250Q2hhbm5lbEVsZW1lbnRzICsgcFBjZS0+TnVtU2lkZUNoYW5uZWxFbGVtZW50cyArIHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHMgKyBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHMKICAgICkKICB7CiAgICByZXR1cm4gMDsKICB9CgogIGZvciAoaT0wOyBpIDwgcFBjZS0+TnVtRnJvbnRDaGFubmVsRWxlbWVudHM7IGkrKykKICB7CiAgICBlbExpc3RbZWwrK10gPSAocFBjZS0+RnJvbnRFbGVtZW50SXNDcGVbaV0pID8gIElEX0NQRSA6IElEX1NDRTsKICB9CgogIGZvciAoaT0wOyBpIDwgcFBjZS0+TnVtU2lkZUNoYW5uZWxFbGVtZW50czsgaSsrKQogIHsKICAgIGVsTGlzdFtlbCsrXSA9IChwUGNlLT5TaWRlRWxlbWVudElzQ3BlW2ldKSA/ICBJRF9DUEUgOiBJRF9TQ0U7CiAgfQoKICBmb3IgKGk9MDsgaSA8IHBQY2UtPk51bUJhY2tDaGFubmVsRWxlbWVudHM7IGkrKykKICB7CiAgICBlbExpc3RbZWwrK10gPSAocFBjZS0+QmFja0VsZW1lbnRJc0NwZVtpXSkgPyAgSURfQ1BFIDogSURfU0NFOwogIH0KCiAgZm9yIChpPTA7IGkgPCBwUGNlLT5OdW1MZmVDaGFubmVsRWxlbWVudHM7IGkrKykKICB7CiAgICBlbExpc3RbZWwrK10gPSBJRF9MRkU7CiAgfQoKCiAgLyogRmluZCBhbiBjb3JyZXNwb25kaW5nIGNoYW5uZWwgY29uZmlndXJhdGlvbiBpZiBwb3NzaWJsZSAqLwogIHN3aXRjaCAocFBjZS0+TnVtQ2hhbm5lbHMpIHsKICBjYXNlIDE6IGNhc2UgMjogY2FzZSAzOiBjYXNlIDQ6IGNhc2UgNTogY2FzZSA2OgogICAgLyogT25lIGFuZCB0d28gY2hhbm5lbHMgaGF2ZSBubyBhbHRlcm5hdGl2ZXMuIFRoZSBvdGhlciBvbmVzIGFyZSBtYXBwZWQgZGlyZWN0bHkgdG8gdGhlCiAgICAgICBjb3JyZXNwb25kaW5nIGNoYW5uZWwgY29uZmlnLiBCZWNhdXNlIG9mIGxlZ2FjeSByZWFzb25zIG9yIGZvciBsYWNrIG9mIGFsdGVybmF0aXZlIG1hcHBpbmdzLiAqLwogICAgKnBDaE1hcElkeCA9IHBQY2UtPk51bUNoYW5uZWxzOwogICAgYnJlYWs7CiAgY2FzZSA3OgogICAgewogICAgICBDX0FMTE9DX1NDUkFUQ0hfU1RBUlQodG1wUGNlLCBDUHJvZ3JhbUNvbmZpZywgMSk7CiAgICAgIC8qIENyZWF0ZSBhIFBDRSBmb3IgdGhlIGNvbmZpZyB0byB0ZXN0IC4uLiAqLwogICAgICBDUHJvZ3JhbUNvbmZpZ19HZXREZWZhdWx0KHRtcFBjZSwgMTEpOwogICAgICAvKiAuLi4gYW5kIGNvbXBhcmUgaXQgd2l0aCB0aGUgZ2l2ZW4gb25lLiAqLwogICAgICAqcENoTWFwSWR4ID0gKCEoQ1Byb2dyYW1Db25maWdfQ29tcGFyZShwUGNlLCB0bXBQY2UpJjB4RSkpID8gMTEgOiAwOwogICAgICAvKiBJZiBjb21wYXJlIHJlc3VsdCBpcyAwIG9yIDEgd2UgY2FuIGJlIHN1cmUgdGhhdCBpdCBpcyBjaGFubmVsIGNvbmZpZyAxMS4gKi8KICAgICAgQ19BTExPQ19TQ1JBVENIX0VORCh0bXBQY2UsIENQcm9ncmFtQ29uZmlnLCAxKTsKICAgIH0KICAgIGJyZWFrOwogIGNhc2UgODoKICAgIHsgLyogVHJ5IHRoZSBmb3VyIHBvc3NpYmxlIDcuMWNoIGNvbmZpZ3VyYXRpb25zLiBPbmUgYWZ0ZXIgdGhlIG90aGVyLiAqLwogICAgICBVQ0hBUiB0ZXN0Q2ZnWzRdID0geyAzMiwgMTQsIDEyLCA3fTsKICAgICAgQ19BTExPQ19TQ1JBVENIX1NUQVJUKHRtcFBjZSwgQ1Byb2dyYW1Db25maWcsIDEpOwogICAgICBmb3IgKGk9MDsgaTw0OyBpKz0xKSB7CiAgICAgICAgLyogQ3JlYXRlIGEgUENFIGZvciB0aGUgY29uZmlnIHRvIHRlc3QgLi4uICovCiAgICAgICAgQ1Byb2dyYW1Db25maWdfR2V0RGVmYXVsdCh0bXBQY2UsIHRlc3RDZmdbaV0pOwogICAgICAgIC8qIC4uLiBhbmQgY29tcGFyZSBpdCB3aXRoIHRoZSBnaXZlbiBvbmUuICovCiAgICAgICAgaWYgKCEoQ1Byb2dyYW1Db25maWdfQ29tcGFyZShwUGNlLCB0bXBQY2UpJjB4RSkpIHsKICAgICAgICAgIC8qIElmIHRoZSBjb21wYXJlIHJlc3VsdCBpcyAwIG9yIDEgdGhhbiB0aGUgdHdvIGNoYW5uZWwgY29uZmlndXJhdGlvbnMgbWF0Y2guICovCiAgICAgICAgICAvKiBFeHBsaWNpdCBtYXBwaW5nIG9mIDcuMSBzaWRlIGNoYW5uZWwgY29uZmlndXJhdGlvbiB0byA3LjEgcmVhciBjaGFubmVsIG1hcHBpbmcuICovCiAgICAgICAgICAqcENoTWFwSWR4ID0gKHRlc3RDZmdbaV09PTMyKSA/IDEyIDogdGVzdENmZ1tpXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgQ19BTExPQ19TQ1JBVENIX0VORCh0bXBQY2UsIENQcm9ncmFtQ29uZmlnLCAxKTsKICAgIH0KICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICAvKiBUaGUgUENFIGRvZXMgbm90IG1hdGNoIGFueSBwcmVkZWZpbmVkIGNoYW5uZWwgY29uZmlndXJhdGlvbi4gKi8KICAgICpwQ2hNYXBJZHggPSAwOwogICAgYnJlYWs7CiAgfQoKICByZXR1cm4gZWw7Cn0KI2VuZGlmCgpzdGF0aWMgQVVESU9fT0JKRUNUX1RZUEUgZ2V0QU9UKEhBTkRMRV9GREtfQklUU1RSRUFNIGJzKQp7CiAgaW50IHRtcCA9IDA7CgogIHRtcCA9IEZES3JlYWRCaXRzKGJzLDUpOwogIGlmICh0bXAgPT0gQU9UX0VTQ0FQRSkgewogICAgaW50IHRtcDIgPSBGREtyZWFkQml0cyhicyw2KTsKICAgIHRtcCA9IDMyICsgdG1wMjsKICB9CgogIHJldHVybiAoQVVESU9fT0JKRUNUX1RZUEUpdG1wOwp9CgpzdGF0aWMgSU5UIGdldFNhbXBsZVJhdGUoSEFORExFX0ZES19CSVRTVFJFQU0gYnMsIFVDSEFSICppbmRleCwgaW50IG5CaXRzKQp7CiAgSU5UIHNhbXBsZVJhdGU7CiAgaW50IGlkeDsKCiAgaWR4ID0gRkRLcmVhZEJpdHMoYnMsIG5CaXRzKTsKICBpZiggaWR4ID09ICgxPDxuQml0cyktMSApIHsKICAgIGlmKEZES2dldFZhbGlkQml0cyhicykgPCAyNCkgewogICAgICByZXR1cm4gMDsKICAgIH0KICAgIHNhbXBsZVJhdGUgPSBGREtyZWFkQml0cyhicywyNCk7CiAgfSBlbHNlIHsKICAgIHNhbXBsZVJhdGUgPSBTYW1wbGluZ1JhdGVUYWJsZVtpZHhdOwogIH0KCiAgKmluZGV4ID0gaWR4OwoKICByZXR1cm4gc2FtcGxlUmF0ZTsKfQoKI2lmZGVmIFRQX0dBX0VOQUJMRQpzdGF0aWMKVFJBTlNQT1JUREVDX0VSUk9SIEdhU3BlY2lmaWNDb25maWdfUGFyc2UoIENTR2FTcGVjaWZpY0NvbmZpZyAgICAqc2VsZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqYXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gICBicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICAgICAgICAgICAgYXNjU3RhcnRBbmNob3IgKQp7CiAgVFJBTlNQT1JUREVDX0VSUk9SIEVycm9yU3RhdHVzID0gVFJBTlNQT1JUREVDX09LOwoKICBzZWxmLT5tX2ZyYW1lTGVuZ3RoRmxhZyA9IEZES3JlYWRCaXRzKGJzLDEpOwoKICBzZWxmLT5tX2RlcGVuZHNPbkNvcmVDb2RlciA9IEZES3JlYWRCaXRzKGJzLDEpOwoKICBpZiggc2VsZi0+bV9kZXBlbmRzT25Db3JlQ29kZXIgKQogICAgc2VsZi0+bV9jb3JlQ29kZXJEZWxheSA9IEZES3JlYWRCaXRzKGJzLDE0KTsKCiAgc2VsZi0+bV9leHRlbnNpb25GbGFnID0gRkRLcmVhZEJpdHMoYnMsMSk7CgogIGlmKCBhc2MtPm1fY2hhbm5lbENvbmZpZ3VyYXRpb24gPT0gMCApIHsKICAgIENQcm9ncmFtQ29uZmlnX1JlYWQoJmFzYy0+bV9wcm9nckNvbmZpZ0VsZW1lbnQsIGJzLCBhc2NTdGFydEFuY2hvcik7CiAgfQoKICBpZiAoKGFzYy0+bV9hb3QgPT0gQU9UX0FBQ19TQ0FMKSB8fCAoYXNjLT5tX2FvdCA9PSBBT1RfRVJfQUFDX1NDQUwpKSB7CiAgICBzZWxmLT5tX2xheWVyID0gRkRLcmVhZEJpdHMoYnMsMyk7CiAgfQoKICBpZiAoc2VsZi0+bV9leHRlbnNpb25GbGFnKSB7CiAgICBpZiAoYXNjLT5tX2FvdCA9PSBBT1RfRVJfQlNBQykgewogICAgICBzZWxmLT5tX251bU9mU3ViRnJhbWUgPSBGREtyZWFkQml0cyhicyw1KTsKICAgICAgc2VsZi0+bV9sYXllckxlbmd0aCAgID0gRkRLcmVhZEJpdHMoYnMsMTEpOwogICAgfQoKICAgIGlmICgoYXNjLT5tX2FvdCA9PSBBT1RfRVJfQUFDX0xDKSAgIHx8IChhc2MtPm1fYW90ID09IEFPVF9FUl9BQUNfTFRQKSAgfHwKICAgICAgICAoYXNjLT5tX2FvdCA9PSBBT1RfRVJfQUFDX1NDQUwpIHx8IChhc2MtPm1fYW90ID09IEFPVF9FUl9BQUNfTEQpKQogICAgewogICAgICBhc2MtPm1fdmNiMTFGbGFnID0gRkRLcmVhZEJpdHMoYnMsMSk7IC8qIGFhY1NlY3Rpb25EYXRhUmVzaWxpZW5jZUZsYWcgKi8KICAgICAgYXNjLT5tX3J2bGNGbGFnICA9IEZES3JlYWRCaXRzKGJzLDEpOyAvKiBhYWNTY2FsZWZhY3RvckRhdGFSZXNpbGllbmNlRmxhZyAqLwogICAgICBhc2MtPm1faGNyRmxhZyAgID0gRkRLcmVhZEJpdHMoYnMsMSk7IC8qIGFhY1NwZWN0cmFsRGF0YVJlc2lsaWVuY2VGbGFnICovCiAgICB9CgogICAgc2VsZi0+bV9leHRlbnNpb25GbGFnMyA9IEZES3JlYWRCaXRzKGJzLDEpOwoKICB9CiAgcmV0dXJuIChFcnJvclN0YXR1cyk7Cn0KI2VuZGlmIC8qIFRQX0dBX0VOQUJMRSAqLwoKCgoKCiNpZmRlZiBUUF9FTERfRU5BQkxFCgpzdGF0aWMgSU5UIGxkX3Nicl9oZWFkZXIoIGNvbnN0IENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqYXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIENTVHBDYWxsQmFja3MgKmNiICkKewogIGNvbnN0IGludCBjaGFubmVsQ29uZmlndXJhdGlvbiA9IGFzYy0+bV9jaGFubmVsQ29uZmlndXJhdGlvbjsKICBpbnQgaSA9IDA7CiAgSU5UIGVycm9yID0gMDsKCiAgaWYgKGNoYW5uZWxDb25maWd1cmF0aW9uID09IDIpIHsKICAgIGVycm9yID0gY2ItPmNiU2JyKGNiLT5jYlNickRhdGEsIGhCcywgYXNjLT5tX3NhbXBsaW5nRnJlcXVlbmN5LCBhc2MtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3ksIGFzYy0+bV9zYW1wbGVzUGVyRnJhbWUsIEFPVF9FUl9BQUNfRUxELCBJRF9DUEUsIGkrKyk7CiAgfSBlbHNlIHsKICAgIGVycm9yID0gY2ItPmNiU2JyKGNiLT5jYlNickRhdGEsIGhCcywgYXNjLT5tX3NhbXBsaW5nRnJlcXVlbmN5LCBhc2MtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3ksIGFzYy0+bV9zYW1wbGVzUGVyRnJhbWUsIEFPVF9FUl9BQUNfRUxELCBJRF9TQ0UsIGkrKyk7CiAgfQoKICBzd2l0Y2ggKCBjaGFubmVsQ29uZmlndXJhdGlvbiApIHsKICAgIGNhc2UgMTQ6CiAgICBjYXNlIDEyOgogICAgY2FzZSA3OgogICAgICBlcnJvciB8PSBjYi0+Y2JTYnIoY2ItPmNiU2JyRGF0YSwgaEJzLCBhc2MtPm1fc2FtcGxpbmdGcmVxdWVuY3ksIGFzYy0+bV9leHRlbnNpb25TYW1wbGluZ0ZyZXF1ZW5jeSwgYXNjLT5tX3NhbXBsZXNQZXJGcmFtZSwgQU9UX0VSX0FBQ19FTEQsIElEX0NQRSwgaSsrKTsKICAgIGNhc2UgNjoKICAgIGNhc2UgNToKICAgICAgZXJyb3IgfD0gY2ItPmNiU2JyKGNiLT5jYlNickRhdGEsIGhCcywgYXNjLT5tX3NhbXBsaW5nRnJlcXVlbmN5LCBhc2MtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3ksIGFzYy0+bV9zYW1wbGVzUGVyRnJhbWUsIEFPVF9FUl9BQUNfRUxELCBJRF9DUEUsIGkrKyk7CiAgICBjYXNlIDM6CiAgICAgIGVycm9yIHw9IGNiLT5jYlNicihjYi0+Y2JTYnJEYXRhLCBoQnMsIGFzYy0+bV9zYW1wbGluZ0ZyZXF1ZW5jeSwgYXNjLT5tX2V4dGVuc2lvblNhbXBsaW5nRnJlcXVlbmN5LCBhc2MtPm1fc2FtcGxlc1BlckZyYW1lLCBBT1RfRVJfQUFDX0VMRCwgSURfQ1BFLCBpKyspOwogICAgICBicmVhazsKCiAgICBjYXNlIDExOgogICAgICBlcnJvciB8PSBjYi0+Y2JTYnIoY2ItPmNiU2JyRGF0YSwgaEJzLCBhc2MtPm1fc2FtcGxpbmdGcmVxdWVuY3ksIGFzYy0+bV9leHRlbnNpb25TYW1wbGluZ0ZyZXF1ZW5jeSwgYXNjLT5tX3NhbXBsZXNQZXJGcmFtZSwgQU9UX0VSX0FBQ19FTEQsIElEX0NQRSwgaSsrKTsKICAgIGNhc2UgNDoKICAgICAgZXJyb3IgfD0gY2ItPmNiU2JyKGNiLT5jYlNickRhdGEsIGhCcywgYXNjLT5tX3NhbXBsaW5nRnJlcXVlbmN5LCBhc2MtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3ksIGFzYy0+bV9zYW1wbGVzUGVyRnJhbWUsIEFPVF9FUl9BQUNfRUxELCBJRF9DUEUsIGkrKyk7CiAgICAgIGVycm9yIHw9IGNiLT5jYlNicihjYi0+Y2JTYnJEYXRhLCBoQnMsIGFzYy0+bV9zYW1wbGluZ0ZyZXF1ZW5jeSwgYXNjLT5tX2V4dGVuc2lvblNhbXBsaW5nRnJlcXVlbmN5LCBhc2MtPm1fc2FtcGxlc1BlckZyYW1lLCBBT1RfRVJfQUFDX0VMRCwgSURfU0NFLCBpKyspOwogICAgICBicmVhazsKICB9CgogIHJldHVybiBlcnJvcjsKfQoKc3RhdGljClRSQU5TUE9SVERFQ19FUlJPUiBFbGRTcGVjaWZpY0NvbmZpZ19QYXJzZSgKICAgICAgICBDU0F1ZGlvU3BlY2lmaWNDb25maWcgKmFzYywKICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsCiAgICAgICAgQ1NUcENhbGxCYWNrcyAqY2IKICAgICAgICApCnsKICBUUkFOU1BPUlRERUNfRVJST1IgRXJyb3JTdGF0dXMgPSBUUkFOU1BPUlRERUNfT0s7CiAgQ1NFbGRTcGVjaWZpY0NvbmZpZyAqZXNjID0gJmFzYy0+bV9zYy5tX2VsZFNwZWNpZmljQ29uZmlnOwogIEFTQ19FTERfRVhUX1RZUEUgZWxkRXh0VHlwZTsKICBpbnQgZWxkRXh0TGVuLCBsZW4sIGNudDsKCiAgRkRLbWVtY2xlYXIoZXNjLCBzaXplb2YoQ1NFbGRTcGVjaWZpY0NvbmZpZykpOwoKICBlc2MtPm1fZnJhbWVMZW5ndGhGbGFnID0gRkRLcmVhZEJpdHMoaEJzLCAxICk7CiAgaWYgKGVzYy0+bV9mcmFtZUxlbmd0aEZsYWcpIHsKICAgIGFzYy0+bV9zYW1wbGVzUGVyRnJhbWUgPSA0ODA7CiAgfSBlbHNlIHsKICAgIGFzYy0+bV9zYW1wbGVzUGVyRnJhbWUgPSA1MTI7CiAgfQoKICBhc2MtPm1fdmNiMTFGbGFnID0gRkRLcmVhZEJpdHMoaEJzLCAxICk7CiAgYXNjLT5tX3J2bGNGbGFnICA9IEZES3JlYWRCaXRzKGhCcywgMSApOwogIGFzYy0+bV9oY3JGbGFnICAgPSBGREtyZWFkQml0cyhoQnMsIDEgKTsKCiAgZXNjLT5tX3NiclByZXNlbnRGbGFnICAgICA9IEZES3JlYWRCaXRzKGhCcywgMSApOwoKICBpZiAoZXNjLT5tX3NiclByZXNlbnRGbGFnID09IDEpIHsKICAgIGVzYy0+bV9zYnJTYW1wbGluZ1JhdGUgICAgPSBGREtyZWFkQml0cyhoQnMsIDEgKTsgLyogMDogc2luZ2xlIHJhdGUsIDE6IGR1YWwgcmF0ZSAqLwogICAgZXNjLT5tX3NickNyY0ZsYWcgICAgICAgICA9IEZES3JlYWRCaXRzKGhCcywgMSApOwoKICAgIGFzYy0+bV9leHRlbnNpb25TYW1wbGluZ0ZyZXF1ZW5jeSA9IGFzYy0+bV9zYW1wbGluZ0ZyZXF1ZW5jeSA8PCBlc2MtPm1fc2JyU2FtcGxpbmdSYXRlOwoKICAgIGlmIChjYi0+Y2JTYnIgIT0gTlVMTCl7CiAgICAgIGlmICggMCAhPSBsZF9zYnJfaGVhZGVyKGFzYywgaEJzLCBjYikgKSB7CiAgICAgICAgcmV0dXJuIFRSQU5TUE9SVERFQ19QQVJTRV9FUlJPUjsKICAgICAgfQogICAgfQogIH0KICBlc2MtPm1fdXNlTGRRbWZUaW1lQWxpZ24gPSAwOwoKICAvKiBuZXcgRUxEIHN5bnRheCAqLwogIC8qIHBhcnNlIEV4dFR5cGVDb25maWdEYXRhICovCiAgd2hpbGUgKChlbGRFeHRUeXBlID0gKEFTQ19FTERfRVhUX1RZUEUpRkRLcmVhZEJpdHMoaEJzLCA0ICkpICE9IEVMREVYVF9URVJNKSB7CiAgICBlbGRFeHRMZW4gPSBsZW4gPSBGREtyZWFkQml0cyhoQnMsIDQgKTsKICAgIGlmICggbGVuID09IDB4ZiApIHsKICAgICAgbGVuID0gRkRLcmVhZEJpdHMoaEJzLCA4ICk7CiAgICAgIGVsZEV4dExlbiArPSBsZW47CgogICAgICBpZiAoIGxlbiA9PSAweGZmICkgewogICAgICAgIGxlbiA9IEZES3JlYWRCaXRzKGhCcywgMTYgKTsKICAgICAgICBlbGRFeHRMZW4gKz0gbGVuOwogICAgICB9CiAgICB9CgogICAgc3dpdGNoIChlbGRFeHRUeXBlKSB7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgZm9yKGNudD0wOyBjbnQ8bGVuOyBjbnQrKykgewogICAgICAgICAgRkRLcmVhZEJpdHMoaEJzLCA4ICk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICAvKiBhZGQgZnV0dXJlIGVsZCBleHRlbnNpb24gY29uZmlncyBoZXJlICovCiAgICB9CiAgfQpiYWlsOgogIHJldHVybiAoRXJyb3JTdGF0dXMpOwp9CiNlbmRpZiAvKiBUUF9FTERfRU5BQkxFICovCgoKc3RhdGljClRSQU5TUE9SVERFQ19FUlJPUiBBdWRpb1NwZWNpZmljQ29uZmlnX0V4dGVuc2lvblBhcnNlKENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqc2VsZiwgSEFORExFX0ZES19CSVRTVFJFQU0gYnMsIENTVHBDYWxsQmFja3MgKmNiKQp7CiAgVFBfQVNDX0VYVEVOU0lPTl9JRCAgbGFzdEFzY0V4dCwgYXNjRXh0SWQgPSBBU0NFWFRfVU5LT1dOOwogIElOVCAgYml0c0F2YWlsYWJsZSA9IChJTlQpRkRLZ2V0VmFsaWRCaXRzKGJzKTsKCiAgd2hpbGUgKGJpdHNBdmFpbGFibGUgPj0gMTEpCiAgewogICAgbGFzdEFzY0V4dCA9IGFzY0V4dElkOwogICAgYXNjRXh0SWQgICA9IChUUF9BU0NfRVhURU5TSU9OX0lEKUZES3JlYWRCaXRzKGJzLCAxMSk7CiAgICBiaXRzQXZhaWxhYmxlIC09IDExOwoKICAgIHN3aXRjaCAoYXNjRXh0SWQpIHsKICAgIGNhc2UgQVNDRVhUX1NCUjogICAgLyogMHgyYjcgKi8KICAgICAgaWYgKCAoc2VsZi0+bV9leHRlbnNpb25BdWRpb09iamVjdFR5cGUgIT0gQU9UX1NCUikgJiYgKGJpdHNBdmFpbGFibGUgPj0gNSkgKSB7CiAgICAgICAgc2VsZi0+bV9leHRlbnNpb25BdWRpb09iamVjdFR5cGUgPSBnZXRBT1QoYnMpOwoKICAgICAgICBpZiAoIChzZWxmLT5tX2V4dGVuc2lvbkF1ZGlvT2JqZWN0VHlwZSA9PSBBT1RfU0JSKQogICAgICAgICAgfHwgKHNlbGYtPm1fZXh0ZW5zaW9uQXVkaW9PYmplY3RUeXBlID09IEFPVF9FUl9CU0FDKSApCiAgICAgICAgeyAvKiBHZXQgU0JSIGV4dGVuc2lvbiBjb25maWd1cmF0aW9uICovCiAgICAgICAgICBzZWxmLT5tX3NiclByZXNlbnRGbGFnID0gRkRLcmVhZEJpdHMoYnMsIDEpOwogICAgICAgICAgYml0c0F2YWlsYWJsZSAtPSAxOwoKICAgICAgICAgIGlmICggc2VsZi0+bV9zYnJQcmVzZW50RmxhZyA9PSAxICkgewogICAgICAgICAgICBzZWxmLT5tX2V4dGVuc2lvblNhbXBsaW5nRnJlcXVlbmN5ID0gZ2V0U2FtcGxlUmF0ZShicywgJnNlbGYtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3lJbmRleCwgNCk7CgogICAgICAgICAgICBpZiAoKElOVClzZWxmLT5tX2V4dGVuc2lvblNhbXBsaW5nRnJlcXVlbmN5IDw9IDApIHsKICAgICAgICAgICAgICByZXR1cm4gVFJBTlNQT1JUREVDX1BBUlNFX0VSUk9SOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIHNlbGYtPm1fZXh0ZW5zaW9uQXVkaW9PYmplY3RUeXBlID09IEFPVF9FUl9CU0FDICkgewogICAgICAgICAgICBzZWxmLT5tX2V4dGVuc2lvbkNoYW5uZWxDb25maWd1cmF0aW9uID0gRkRLcmVhZEJpdHMoYnMsIDQpOwogICAgICAgICAgICBiaXRzQXZhaWxhYmxlIC09IDQ7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qIFVwZGF0ZSBjb3VudGVyIGJlY2F1c2Ugb2YgdmFyaWFibGUgbGVuZ3RoIGZpZWxkcyAoQU9UIGFuZCBzYW1wbGluZyByYXRlKSAqLwogICAgICAgIGJpdHNBdmFpbGFibGUgPSAoSU5UKUZES2dldFZhbGlkQml0cyhicyk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIEFTQ0VYVF9QUzogICAgIC8qIDB4NTQ4ICovCiAgICAgIGlmICggKGxhc3RBc2NFeHQgPT0gQVNDRVhUX1NCUikKICAgICAgICAmJiAoc2VsZi0+bV9leHRlbnNpb25BdWRpb09iamVjdFR5cGUgPT0gQU9UX1NCUikKICAgICAgICAmJiAoYml0c0F2YWlsYWJsZSA+IDApICkKICAgICAgeyAvKiBHZXQgUFMgZXh0ZW5zaW9uIGNvbmZpZ3VyYXRpb24gKi8KICAgICAgICBzZWxmLT5tX3BzUHJlc2VudEZsYWcgPSBGREtyZWFkQml0cyhicywgMSk7CiAgICAgICAgYml0c0F2YWlsYWJsZSAtPSAxOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgLyogSnVzdCBpZ25vcmUgYW55dGhpbmcuICovCiAgICAgIHJldHVybiBUUkFOU1BPUlRERUNfT0s7CiAgICB9CiAgfQoKICByZXR1cm4gVFJBTlNQT1JUREVDX09LOwp9CgovKgogKiBBUEkgRnVuY3Rpb25zCiAqLwoKdm9pZCBBdWRpb1NwZWNpZmljQ29uZmlnX0luaXQoQ1NBdWRpb1NwZWNpZmljQ29uZmlnICphc2MpCnsKICBGREttZW1jbGVhcihhc2MsIHNpemVvZihDU0F1ZGlvU3BlY2lmaWNDb25maWcpKTsKCiAgLyogSW5pdCBhbGwgdmFsdWVzIHRoYXQgc2hvdWxkIG5vdCBiZSB6ZXJvLiAqLwogIGFzYy0+bV9hb3QgICAgICAgICAgICAgICAgICAgID0gQU9UX05PTkU7CiAgYXNjLT5tX3NhbXBsaW5nRnJlcXVlbmN5SW5kZXggPSAweGY7CiAgYXNjLT5tX2VwQ29uZmlnICAgICAgICAgICAgICAgPSAtMTsKICBhc2MtPm1fZXh0ZW5zaW9uQXVkaW9PYmplY3RUeXBlICAgICAgICA9IEFPVF9OVUxMX09CSkVDVDsKI2lmZGVmIFRQX1BDRV9FTkFCTEUKICBDUHJvZ3JhbUNvbmZpZ19Jbml0KCZhc2MtPm1fcHJvZ3JDb25maWdFbGVtZW50KTsKI2VuZGlmCn0KClRSQU5TUE9SVERFQ19FUlJPUiBBdWRpb1NwZWNpZmljQ29uZmlnX1BhcnNlKAogICAgICAgIENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqc2VsZiwKICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSAgIGJzLAogICAgICAgIGludCAgICAgICAgICAgICAgICAgICAgZkV4cGxpY2l0QmFja3dhcmRDb21wYXRpYmxlLAogICAgICAgIENTVHBDYWxsQmFja3MgICAgICAqY2IKICAgICAgICApCnsKICBUUkFOU1BPUlRERUNfRVJST1IgRXJyb3JTdGF0dXMgPSBUUkFOU1BPUlRERUNfT0s7CiAgVUlOVCBhc2NTdGFydEFuY2hvciA9IEZES2dldFZhbGlkQml0cyhicyk7CiAgaW50IGZyYW1lTGVuZ3RoRmxhZyA9IC0xOwoKICBBdWRpb1NwZWNpZmljQ29uZmlnX0luaXQoc2VsZik7CgogIHNlbGYtPm1fYW90ID0gZ2V0QU9UKGJzKTsKICBzZWxmLT5tX3NhbXBsaW5nRnJlcXVlbmN5ID0gZ2V0U2FtcGxlUmF0ZShicywgJnNlbGYtPm1fc2FtcGxpbmdGcmVxdWVuY3lJbmRleCwgNCk7CiAgaWYgKHNlbGYtPm1fc2FtcGxpbmdGcmVxdWVuY3kgPD0gMCkgewogICAgcmV0dXJuIFRSQU5TUE9SVERFQ19QQVJTRV9FUlJPUjsKICB9CgogIHNlbGYtPm1fY2hhbm5lbENvbmZpZ3VyYXRpb24gPSBGREtyZWFkQml0cyhicyw0KTsKCiAgLyogU0JSIGV4dGVuc2lvbiAoIGV4cGxpY2l0IG5vbi1iYWNrd2FyZHMgY29tcGF0aWJsZSBtb2RlICkgKi8KICBzZWxmLT5tX3NiclByZXNlbnRGbGFnID0gMDsKICBzZWxmLT5tX3BzUHJlc2VudEZsYWcgID0gMDsKCiAgaWYgKCBzZWxmLT5tX2FvdCA9PSBBT1RfU0JSIHx8IHNlbGYtPm1fYW90ID09IEFPVF9QUyApIHsKICAgIHNlbGYtPm1fZXh0ZW5zaW9uQXVkaW9PYmplY3RUeXBlID0gQU9UX1NCUjsKCiAgICBzZWxmLT5tX3NiclByZXNlbnRGbGFnID0gMTsKICAgIGlmICggc2VsZi0+bV9hb3QgPT0gQU9UX1BTICkgewogICAgICBzZWxmLT5tX3BzUHJlc2VudEZsYWcgPSAxOwogICAgfQoKICAgIHNlbGYtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3kgPSBnZXRTYW1wbGVSYXRlKGJzLCAmc2VsZi0+bV9leHRlbnNpb25TYW1wbGluZ0ZyZXF1ZW5jeUluZGV4LCA0KTsKICAgIHNlbGYtPm1fYW90ID0gZ2V0QU9UKGJzKTsKCiAgfSBlbHNlIHsKICAgIHNlbGYtPm1fZXh0ZW5zaW9uQXVkaW9PYmplY3RUeXBlID0gQU9UX05VTExfT0JKRUNUOwogIH0KCiAgLyogUGFyc2Ugd2hhdGV2ZXIgc3BlY2lmaWMgY29uZmlncyAqLwogIHN3aXRjaCAoc2VsZi0+bV9hb3QpCiAgewojaWZkZWYgVFBfR0FfRU5BQkxFCiAgICBjYXNlIEFPVF9BQUNfTEM6CiAgICBjYXNlIEFPVF9FUl9BQUNfTEM6CiAgICBjYXNlIEFPVF9FUl9BQUNfTEQ6CiAgICBjYXNlIEFPVF9FUl9BQUNfU0NBTDoKICAgIGNhc2UgQU9UX0VSX0JTQUM6CiAgICAgIGlmICgoRXJyb3JTdGF0dXMgPSBHYVNwZWNpZmljQ29uZmlnX1BhcnNlKCZzZWxmLT5tX3NjLm1fZ2FTcGVjaWZpY0NvbmZpZywgc2VsZiwgYnMsIGFzY1N0YXJ0QW5jaG9yKSkgIT0gVFJBTlNQT1JUREVDX09LICkgewogICAgICAgIHJldHVybiAoRXJyb3JTdGF0dXMpOwogICAgICB9CiAgICAgIGZyYW1lTGVuZ3RoRmxhZyA9IHNlbGYtPm1fc2MubV9nYVNwZWNpZmljQ29uZmlnLm1fZnJhbWVMZW5ndGhGbGFnOwogICAgICBicmVhazsKI2VuZGlmIC8qIFRQX0dBX0VOQUJMRSAqLwogICAgY2FzZSBBT1RfTVBFR1M6CiAgICAgIGlmIChjYi0+Y2JTc2MgIT0gTlVMTCkgewogICAgICAgIGNiLT5jYlNzYygKICAgICAgICAgICAgICAgIGNiLT5jYlNzY0RhdGEsCiAgICAgICAgICAgICAgICBicywKICAgICAgICAgICAgICAgIHNlbGYtPm1fYW90LAogICAgICAgICAgICAgICAgc2VsZi0+bV9zYW1wbGluZ0ZyZXF1ZW5jeSwKICAgICAgICAgICAgICAgIDEsCiAgICAgICAgICAgICAgICAwICAvKiBkb24ndCBrbm93IHRoZSBsZW5ndGggKi8KICAgICAgICAgICAgICAgICk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIFRSQU5TUE9SVERFQ19VTlNVUFBPUlRFRF9GT1JNQVQ7CiAgICAgIH0KICAgICAgYnJlYWs7CiNpZmRlZiBUUF9FTERfRU5BQkxFCiAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgICBpZiAoKEVycm9yU3RhdHVzID0gRWxkU3BlY2lmaWNDb25maWdfUGFyc2Uoc2VsZiwgYnMsIGNiKSkgIT0gVFJBTlNQT1JUREVDX09LICkgewogICAgICAgIHJldHVybiAoRXJyb3JTdGF0dXMpOwogICAgICB9CiAgICAgIGZyYW1lTGVuZ3RoRmxhZyA9IHNlbGYtPm1fc2MubV9lbGRTcGVjaWZpY0NvbmZpZy5tX2ZyYW1lTGVuZ3RoRmxhZzsKICAgICAgc2VsZi0+bV9zYnJQcmVzZW50RmxhZyA9IHNlbGYtPm1fc2MubV9lbGRTcGVjaWZpY0NvbmZpZy5tX3NiclByZXNlbnRGbGFnOwogICAgICBzZWxmLT5tX2V4dGVuc2lvblNhbXBsaW5nRnJlcXVlbmN5ID0gKHNlbGYtPm1fc2MubV9lbGRTcGVjaWZpY0NvbmZpZy5tX3NiclNhbXBsaW5nUmF0ZSsxKSAqIHNlbGYtPm1fc2FtcGxpbmdGcmVxdWVuY3k7CiAgICAgIGJyZWFrOwojZW5kaWYgLyogVFBfRUxEX0VOQUJMRSAqLwoKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiBUUkFOU1BPUlRERUNfVU5TVVBQT1JURURfRk9STUFUOwogICAgICBicmVhazsKICB9CgogIC8qIEZyYW1lIGxlbmd0aCAqLwogIHN3aXRjaCAoc2VsZi0+bV9hb3QpCiAgewojaWYgZGVmaW5lZChUUF9HQV9FTkFCTEUpIHx8IGRlZmluZWQoVFBfVVNBQ19FTkFCTEUpCiAgICBjYXNlIEFPVF9BQUNfTEM6CiAgICBjYXNlIEFPVF9FUl9BQUNfTEM6CiAgICBjYXNlIEFPVF9FUl9BQUNfU0NBTDoKICAgIGNhc2UgQU9UX0VSX0JTQUM6CiAgICAvKmNhc2UgQU9UX1VTQUM6Ki8KICAgICAgaWYgKCFmcmFtZUxlbmd0aEZsYWcpCiAgICAgICAgc2VsZi0+bV9zYW1wbGVzUGVyRnJhbWUgPSAxMDI0OwogICAgICBlbHNlCiAgICAgICAgc2VsZi0+bV9zYW1wbGVzUGVyRnJhbWUgPSA5NjA7CiAgICAgIGJyZWFrOwojZW5kaWYgLyogVFBfR0FfRU5BQkxFICovCiNpZiBkZWZpbmVkKFRQX0dBX0VOQUJMRSkKICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgICAgaWYgKCFmcmFtZUxlbmd0aEZsYWcpCiAgICAgICAgc2VsZi0+bV9zYW1wbGVzUGVyRnJhbWUgPSA1MTI7CiAgICAgIGVsc2UKICAgICAgICBzZWxmLT5tX3NhbXBsZXNQZXJGcmFtZSA9IDQ4MDsKICAgICAgYnJlYWs7CiNlbmRpZiAvKiBkZWZpbmVkKFRQX0dBX0VOQUJMRSkgKi8KICAgIGRlZmF1bHQ6CiAgICAgIGJyZWFrOwogIH0KCiAgc3dpdGNoIChzZWxmLT5tX2FvdCkKICB7CiAgICBjYXNlIEFPVF9FUl9BQUNfTEM6CiAgICBjYXNlIEFPVF9FUl9BQUNfTEQ6CiAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgY2FzZSBBT1RfRVJfQUFDX1NDQUw6CiAgICBjYXNlIEFPVF9FUl9DRUxQOgogICAgY2FzZSBBT1RfRVJfSFZYQzoKICAgIGNhc2UgQU9UX0VSX0JTQUM6CiAgICAgIHNlbGYtPm1fZXBDb25maWcgPSBGREtyZWFkQml0cyhicywyKTsKCiAgICAgIGlmIChzZWxmLT5tX2VwQ29uZmlnID4gMSkgewogICAgICAgIHJldHVybiBUUkFOU1BPUlRERUNfVU5TVVBQT1JURURfRk9STUFUOyAvLyBFUENPTkZJRzsKICAgICAgfQogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGJyZWFrOwogIH0KCiAgaWYgKGZFeHBsaWNpdEJhY2t3YXJkQ29tcGF0aWJsZSkgewogICAgRXJyb3JTdGF0dXMgPSBBdWRpb1NwZWNpZmljQ29uZmlnX0V4dGVuc2lvblBhcnNlKHNlbGYsIGJzLCBjYik7CiAgfQoKICByZXR1cm4gKEVycm9yU3RhdHVzKTsKfQoKCg==