Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBQQ1ggTG9hZGVyCi8vCi8vIERlc2lnbiBhbmQgaW1wbGVtZW50YXRpb24gYnkKLy8gLSBGbG9yaXMgdmFuIGRlbiBCZXJnIChmbHZkYmVyZ0B3eHMubmwpCi8vIC0gSmFuaSBLYWphbGEgKGphbmlrQHJlbWVkeS5maSkKLy8gLSBNYXJrdXMgTG9pYmwgKG1hcmt1cy5sb2libEBlcG9zdC5kZSkKLy8gLSBIZXJ26SBEcm9sb24gKGRyb2xvbkBpbmZvbmllLmZyKQovLyAtIEp1ZXJnZW4gUmllY2tlciAoai5yaWVja2VyQGdteC5kZSkKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSAiRnJlZUltYWdlLmgiCiNpbmNsdWRlICJVdGlsaXRpZXMuaCIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBDb25zdGFudHMgKyBoZWFkZXJzCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiNkZWZpbmUgSU9fQlVGX1NJWkUJMjA0OAoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKI2lmZGVmIF9XSU4zMgojcHJhZ21hIHBhY2socHVzaCwgMSkKI2Vsc2UKI3ByYWdtYSBwYWNrKDEpCiNlbmRpZgoKdHlwZWRlZiBzdHJ1Y3QgdGFnUENYSEVBREVSIHsKCUJZVEUgIG1hbnVmYWN0dXJlcjsJCS8vIE1hZ2ljIG51bWJlciAoMHgwQSA9IFpTb2Z0IFopCglCWVRFICB2ZXJzaW9uOwkJCS8vIFZlcnNpb24JMCA9PSAyLjUKCQkJCQkJCS8vICAgICAgICAgIDIgPT0gMi44IHdpdGggcGFsZXR0ZSBpbmZvCgkJCQkJCQkvLyAgICAgICAgICAzID09IDIuOCB3aXRob3V0IHBhbGV0dGUgaW5mbwoJCQkJCQkJLy8gICAgICAgICAgNSA9PSAzLjAgd2l0aCBwYWxldHRlIGluZm8KCUJZVEUgIGVuY29kaW5nOwkJCS8vIEVuY29kaW5nOiAwID0gdW5jb21wcmVzc2VkLCAxID0gUENYIHJsZSBjb21wcmVzc2VkCglCWVRFICBicHA7CQkJCS8vIEJpdHMgcGVyIHBpeGVsIHBlciBwbGFuZSAob25seSAxIG9yIDgpCglXT1JEICB3aW5kb3dbNF07CQkvLyBsZWZ0LCB1cHBlciwgcmlnaHQsbG93ZXIgcGl4ZWwgY29vcmQuCglXT1JEICBoZHBpOwkJCQkvLyBIb3Jpem9udGFsIHJlc29sdXRpb24KCVdPUkQgIHZkcGk7CQkJCS8vIFZlcnRpY2FsIHJlc29sdXRpb24KCUJZVEUgIGNvbG9yX21hcFs0OF07CS8vIENvbG9ybWFwIGZvciAxNi1jb2xvciBpbWFnZXMKCUJZVEUgIHJlc2VydmVkOwoJQllURSAgcGxhbmVzOwkJCS8vIE51bWJlciBvZiBwbGFuZXMgKDEsIDMgb3IgNCkKCVdPUkQgIGJ5dGVzX3Blcl9saW5lOwkvLyBCeXRlcyBwZXIgcm93IChhbHdheXMgZXZlbikKCVdPUkQgIHBhbGV0dGVfaW5mbzsJCS8vIFBhbGV0dGUgaW5mb3JtYXRpb24gKDEgPSBjb2xvciBvciBiJnc7IDIgPSBncmF5IHNjYWxlKQoJV09SRCAgaF9zY3JlZW5fc2l6ZTsKCVdPUkQgIHZfc2NyZWVuX3NpemU7CglCWVRFICBmaWxsZXJbNTRdOwkJLy8gUmVzZXJ2ZWQgZmlsbGVyCn0gUENYSEVBREVSOwoJCQojaWZkZWYgX1dJTjMyCiNwcmFnbWEgcGFjayhwb3ApCiNlbHNlCiNwcmFnbWEgcGFjaygpCiNlbmRpZgoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBJbnRlcm5hbCBmdW5jdGlvbnMKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKc3RhdGljIEJPT0wgCnBjeF92YWxpZGF0ZShGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUpIHsKCUJZVEUgcGN4X3NpZ25hdHVyZSA9IDB4MEE7CglCWVRFIHNpZ25hdHVyZVs0XSA9IHsgMCwgMCwgMCwgMCB9OwoKCWlmKGlvLT5yZWFkX3Byb2MoJnNpZ25hdHVyZSwgMSwgNCwgaGFuZGxlKSAhPSA0KSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoJLy8gbWFnaWMgbnVtYmVyICgweDBBID0gWlNvZnQgWikKCWlmKHNpZ25hdHVyZVswXSA9PSBwY3hfc2lnbmF0dXJlKSB7CgkJLy8gdmVyc2lvbgoJCWlmKHNpZ25hdHVyZVsxXSA8PSA1KSB7CgkJCS8vIGVuY29kaW5nCgkJCWlmKChzaWduYXR1cmVbMl0gPT0gMCkgfHwgKHNpZ25hdHVyZVsyXSA9PSAxKSkgewoJCQkJLy8gYml0cyBwZXIgcGl4ZWwgcGVyIHBsYW5lCgkJCQlpZigoc2lnbmF0dXJlWzNdID09IDEpIHx8IChzaWduYXR1cmVbM10gPT0gOCkpIHsKCQkJCQlyZXR1cm4gVFJVRTsKCQkJCX0KCQkJfQoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyB1bnNpZ25lZApyZWFkbGluZShGcmVlSW1hZ2VJTyAmaW8sIGZpX2hhbmRsZSBoYW5kbGUsIEJZVEUgKmJ1ZmZlciwgdW5zaWduZWQgbGVuZ3RoLCBCT09MIHJsZSwgQllURSAqIFJlYWRCdWYsIGludCAqIFJlYWRQb3MpIHsKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLy8KCS8vIFJlYWQgZWl0aGVyIHJ1bi1sZW5ndGggZW5jb2RlZCBvciBub3JtYWwgaW1hZ2UgZGF0YSAgICAgICAgLy8KCS8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KCS8vICAgICAgIFRISVMgSVMgSE9XIFJVTlRJTUUgTEVOR1RIIEVOQ09ESU5HIFdPUktTIElOIFBDWDogICAgLy8KCS8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KCS8vICAxKSBJZiB0aGUgdXBwZXIgMiBiaXRzIG9mIGEgYnl0ZSBhcmUgc2V0LCAgICAgICAgICAgICAgICAgLy8KCS8vICAgICB0aGUgbG93ZXIgNiBiaXRzIHNwZWNpZnkgdGhlIGNvdW50IGZvciB0aGUgbmV4dCBieXRlICAgLy8KCS8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KCS8vICAyKSBJZiB0aGUgdXBwZXIgMiBiaXRzIG9mIHRoZSBieXRlIGFyZSBjbGVhciwgICAgICAgICAgICAgLy8KCS8vICAgICB0aGUgYnl0ZSBpcyBhY3R1YWwgZGF0YSB3aXRoIGEgY291bnQgb2YgMSAgICAgICAgICAgICAgLy8KCS8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8KCS8vICBOb3RlIHRoYXQgYSBzY2FubGluZSBhbHdheXMgaGFzIGFuIGV2ZW4gbnVtYmVyIG9mIGJ5dGVzICAgLy8KCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCglCWVRFIGNvdW50ID0gMCwgdmFsdWUgPSAwOwoJdW5zaWduZWQgd3JpdHRlbiA9IDA7CgoJaWYgKHJsZSkgewoJCS8vIHJ1bi1sZW5ndGggZW5jb2RlZCByZWFkCgoJCXdoaWxlIChsZW5ndGgtLSkgewoJCQlpZiAoY291bnQgPT0gMCkgewoJCQkJaWYgKCpSZWFkUG9zID49IElPX0JVRl9TSVpFIC0gMSApIHsKCQkJCQlpZiAoKlJlYWRQb3MgPT0gSU9fQlVGX1NJWkUgLSAxKSB7CgkJCQkJCS8vIHdlIHN0aWxsIGhhdmUgb25lIEJZVEUsIGNvcHkgaXQgdG8gdGhlIHN0YXJ0IHBvcwoKCQkJCQkJKlJlYWRCdWYgPSBSZWFkQnVmW0lPX0JVRl9TSVpFIC0gMV07CgoJCQkJCQlpby5yZWFkX3Byb2MoUmVhZEJ1ZiArIDEsIDEsIElPX0JVRl9TSVpFIC0gMSwgaGFuZGxlKTsKCQkJCQl9IGVsc2UgewoJCQkJCQkvLyByZWFkIHRoZSBjb21wbGV0ZSBidWZmZXIKCgkJCQkJCWlvLnJlYWRfcHJvYyhSZWFkQnVmLCAxLCBJT19CVUZfU0laRSwgaGFuZGxlKTsKCQkJCQl9CgoJCQkJCSpSZWFkUG9zID0gMDsKCQkJCX0KCgkJCQl2YWx1ZSA9ICooUmVhZEJ1ZiArICgqUmVhZFBvcykrKyk7CgoJCQkJaWYgKCh2YWx1ZSAmIDB4QzApID09IDB4QzApIHsKCQkJCQljb3VudCA9IHZhbHVlICYgMHgzRjsKCQkJCQl2YWx1ZSA9ICooUmVhZEJ1ZiArICgqUmVhZFBvcykrKyk7CgkJCQl9IGVsc2UgewoJCQkJCWNvdW50ID0gMTsKCQkJCX0KCQkJfQoKCQkJY291bnQtLTsKCgkJCSooYnVmZmVyICsgd3JpdHRlbisrKSA9IHZhbHVlOwoJCX0KCgl9IGVsc2UgewoJCS8vIG5vcm1hbCByZWFkCgoJCXdyaXR0ZW4gPSBpby5yZWFkX3Byb2MoYnVmZmVyLCBsZW5ndGgsIDEsIGhhbmRsZSk7Cgl9CgoJcmV0dXJuIHdyaXR0ZW47Cn0KCiNpZmRlZiBGUkVFSU1BR0VfQklHRU5ESUFOCnN0YXRpYyB2b2lkClN3YXBIZWFkZXIoUENYSEVBREVSICpoZWFkZXIpIHsKCVN3YXBTaG9ydCgmaGVhZGVyLT53aW5kb3dbMF0pOwoJU3dhcFNob3J0KCZoZWFkZXItPndpbmRvd1sxXSk7CglTd2FwU2hvcnQoJmhlYWRlci0+d2luZG93WzJdKTsKCVN3YXBTaG9ydCgmaGVhZGVyLT53aW5kb3dbM10pOwoJU3dhcFNob3J0KCZoZWFkZXItPmhkcGkpOwoJU3dhcFNob3J0KCZoZWFkZXItPnZkcGkpOwoJU3dhcFNob3J0KCZoZWFkZXItPmJ5dGVzX3Blcl9saW5lKTsKCVN3YXBTaG9ydCgmaGVhZGVyLT5wYWxldHRlX2luZm8pOwoJU3dhcFNob3J0KCZoZWFkZXItPmhfc2NyZWVuX3NpemUpOwoJU3dhcFNob3J0KCZoZWFkZXItPnZfc2NyZWVuX3NpemUpOwp9CiNlbmRpZgoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBQbHVnaW4gSW50ZXJmYWNlCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCnN0YXRpYyBpbnQgc19mb3JtYXRfaWQ7CgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIFBsdWdpbiBJbXBsZW1lbnRhdGlvbgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgovKiEKICAgIFJldHVybnMgdGhlIGZvcm1hdCBzdHJpbmcgZm9yIHRoZSBwbHVnaW4uIEVhY2ggcGx1Z2luLAoJYm90aCBpbnRlcm5hbCBpbiB0aGUgRExMIGFuZCBleHRlcm5hbCBpbiBhIC5maXAgZmlsZSwgbXVzdCBoYXZlCglhIHVuaXF1ZSBmb3JtYXQgc3RyaW5nIHRvIGJlIGFkZHJlc3NhYmxlLgoqLwoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKRm9ybWF0KCkgewoJcmV0dXJuICJQQ1giOwp9CgovKiEKICAgIFJldHVybnMgYSBkZXNjcmlwdGlvbiBzdHJpbmcgZm9yIHRoZSBwbHVnaW4uIFRob3VnaCBhCglkZXNjcmlwdGlvbiBpcyBub3QgbmVjZXNzYXJ5IHBlci1zZSwKCWl0IGlzIGFkdmlzZWQgdG8gcmV0dXJuIGFuIHVuaXF1ZSBzdHJpbmcgaW4gb3JkZXIgdG8gdGVsbCB0aGUKCXVzZXIgd2hhdCB0eXBlIG9mIGJpdG1hcHMgdGhpcyBwbHVnaW4gd2lsbCByZWFkIGFuZC9vciB3cml0ZS4KKi8KCnN0YXRpYyBjb25zdCBjaGFyICogRExMX0NBTExDT05WCkRlc2NyaXB0aW9uKCkgewoJcmV0dXJuICJac29mdCBQYWludGJydXNoIjsKfQoKLyohCiAgICBSZXR1cm5zIGEgY29tbWEgc2VwYXJhdGVkIGxpc3Qgb2YgZmlsZQoJZXh0ZW5zaW9ucyBpbmRpY2F0aW5nIHdoYXQgZmlsZXMgdGhpcyBwbHVnaW4gY2FuIG9wZW4uIFRoZQoJbGlzdCwgYmVpbmcgdXNlZCBieSBGcmVlSW1hZ2VfR2V0RklGRnJvbUZpbGVuYW1lLCBpcyB1c3VhbGx5Cgl1c2VkIGFzIGEgbGFzdCByZXNvcnQgaW4gZmluZGluZyB0aGUgdHlwZSBvZiB0aGUgYml0bWFwIHdlCglhcmUgZGVhbGluZyB3aXRoLiBCZXN0IGlzIHRvIGNoZWNrIHRoZSBmaXJzdCBmZXcgYnl0ZXMgb24KCXRoZSBsb3ctbGV2ZWwgYml0cyBsZXZlbCBmaXJzdCBhbmQgY29tcGFyZSB0aGVtIHdpdGggYSBrbm93bgoJc2lnbmF0dXJlIC4gSWYgdGhpcyBmYWlscywgRnJlZUltYWdlX0dldEZJRkZyb21GaWxlbmFtZSBjYW4gYmUKCXVzZWQuCiovCgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpFeHRlbnNpb24oKSB7CglyZXR1cm4gInBjeCI7Cn0KCi8qIQogICAgUmV0dXJucyBhbiAob3B0aW9uYWwpIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBoZWxwCglzb2Z0d2FyZSBpZGVudGlmeWluZyBhIGJpdG1hcCB0eXBlLiBUaGUKCWV4cHJlc3Npb24gY2FuIGJlIGFwcGxpZWQgdG8gdGhlIGZpcnN0IGZldyBieXRlcyAoaGVhZGVyKSBvZgoJdGhlIGJpdG1hcC4gRnJlZUltYWdlIGlzIG5vdCBjYXBhYmxlIG9mIHByb2Nlc3NpbmcgcmVndWxhciBleHByZXNzaW9uIGl0c2VsZiwKCWJ1dCBGcmVlSW1hZ2VRdCwgdGhlIEZyZWVJbWFnZSBUcm9sbHRlY2ggc3VwcG9ydCBsaWJyYXJ5LCBjYW4uIElmIFJlZ0V4cHIKCXJldHVybnMgTlVMTCwgRnJlZUltYWdlUXQgd2lsbCBhdXRvbWF0aWNhbGx5IGJ5cGFzcyBUcm9sbHRlY2gncyByZWd1bGFyCglleHByZXNzaW9uIHN1cHBvcnQgYW5kIHVzZSBpdHMgaW50ZXJuYWwgZnVuY3Rpb25zIHRvIGZpbmQgdGhlIGJpdG1hcCB0eXBlLgoqLwoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKUmVnRXhwcigpIHsKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpNaW1lVHlwZSgpIHsKCXJldHVybiAiaW1hZ2UveC1wY3giOwp9CgovKiEKICAgIFZhbGlkYXRlcyBhIGJpdG1hcCBieSByZWFkaW5nIHRoZSBmaXJzdCBmZXcgYnl0ZXMKCWFuZCBjb21wYXJpbmcgdGhlbSB3aXRoIGEga25vd24gYml0bWFwIHNpZ25hdHVyZS4KCVRSVUUgaXMgcmV0dXJuZWQgaWYgdGhlIGJ5dGVzIG1hdGNoIHRoZSBzaWduYXR1cmUsIEZBTFNFIG90aGVyd2lzZS4KCVRoZSBWYWxpZGF0ZSBmdW5jdGlvbiBpcyB1c2VkIGJ5IHVzaW5nIEZyZWVJbWFnZV9HZXRGaWxlVHlwZS4KCQoJTm90ZTogYSBwbHVnaW4gY2FuIHNhZmVseSByZWFkIGRhdGEgYW55IGRhdGEgZnJvbSB0aGUgYml0bWFwIHdpdGhvdXQgc2Vla2luZyBiYWNrCgl0byB0aGUgb3JpZ2luYWwgZW50cnkgcG9pbnQ7IHRoZSBlbnRyeSBwb2ludCBpcyBzdG9yZWQgcHJpb3IgdG8gY2FsbGluZyB0aGlzCglmdW5jdGlvbiBhbmQgcmVzdG9yZWQgYWZ0ZXIuCgogICAgTm90ZTogYmVjYXVzZSBvZiBGcmVlSW1hZ2UncyBpbyByZWRpcmVjdGlvbiBzdXBwb3J0LCB0aGUgaGVhZGVyIGZvciB0aGUgYml0bWFwCgltdXN0IGJlIG9uIHRoZSBzdGFydCBvZiB0aGUgYml0bWFwIG9yIGF0IGxlYXN0IG9uIGEga25vd24gcGFydCBpbiB0aGUgYml0bWFwLiBJdCBpcwoJZm9yYmlkZGVuIHRvIHNlZWsgdG8gdGhlIGVuZCBvZiB0aGUgYml0bWFwIG9yIHRvIGEgcG9pbnQgcmVsYXRpdmUgdG8gdGhlIGVuZCBvZiBhIGJpdG1hcCwKCWJlY2F1c2UgdGhlIGVuZCBvZiB0aGUgYml0bWFwIGlzIG5vdCBhbHdheXMga25vd24uCiovCgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYKVmFsaWRhdGUoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlKSB7CglyZXR1cm4gcGN4X3ZhbGlkYXRlKGlvLCBoYW5kbGUpOwp9CgovKiEKICAgIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byAnYXNrJyB0aGUgcGx1Z2luIGlmIGl0IGNhbiB3cml0ZQoJYSBiaXRtYXAgaW4gYSBjZXJ0YWluIGJpdGRlcHRoLiBEaWZmZXJlbnQgYml0bWFwIHR5cGVzIGhhdmUgZGlmZmVyZW50CgljYXBhYmlsaXRpZXMsIGZvciBleGFtcGxlIG5vdCBhbGwgZm9ybWF0cyBhbGxvdyB3cml0aW5nIGluIHBhbGV0dGl6ZWQgbW9kZS4KCVRoaXMgZnVuY3Rpb24gaXMgdGhlcmUgcHJvdmlkZSBhbiB1bmlmb3JtIGludGVyZmFjZSB0byB0aGUgcGx1Z2luJ3MKCWNhcGFiaWxpdGllcy4gU3VwcG9ydHNFeHBvcnREZXB0aCByZXR1cm5zIFRSVUUgaWYgdGhlIHBsdWdpbiBzdXBwb3J0IHdyaXRpbmcKCWluIHRoZSBhc2tlZCBiaXRkZXB0aCwgb3IgRkFMU0UgaWYgaXQgZG9lc24ndC4gVGhlIGZ1bmN0aW9uIGFsc28KCXJldHVybnMgRkFMU0UgaWYgYml0bWFwIHNhdmluZyBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBwbHVnaW4gYXQgYWxsLgoqLwoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClN1cHBvcnRzRXhwb3J0RGVwdGgoaW50IGRlcHRoKSB7CglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBCT09MIERMTF9DQUxMQ09OViAKU3VwcG9ydHNFeHBvcnRUeXBlKEZSRUVfSU1BR0VfVFlQRSB0eXBlKSB7CglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBCT09MIERMTF9DQUxMQ09OVgpTdXBwb3J0c05vUGl4ZWxzKCkgewoJcmV0dXJuIFRSVUU7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qIQogICAgTG9hZHMgYSBiaXRtYXAgaW50byBtZW1vcnkuIE9uIGVudHJ5IGl0IGlzIGFzc3VtZWQgdGhhdAoJdGhlIGJpdG1hcCB0byBiZSBsb2FkZWQgaXMgb2YgdGhlIGNvcnJlY3QgdHlwZS4gSWYgdGhlIGJpdG1hcAoJaXMgb2YgYW4gaW5jb3JyZWN0IHR5cGUsIHRoZSBwbHVnaW4gbWlnaHQgbm90IGdyYWNlZnVsbHkgZmFpbCBidXQKCWNyYXNoIG9yIGVudGVyIGFuIGVuZGxlc3MgbG9vcC4gSXQgaXMgYWxzbyBhc3N1bWVkIHRoYXQgYWxsCgl0aGUgYml0bWFwIGRhdGEgaXMgYXZhaWxhYmxlIGF0IG9uZSB0aW1lLiBJZiB0aGUgYml0bWFwIGlzIG5vdCBjb21wbGV0ZSwKCWZvciBleGFtcGxlIGJlY2F1c2UgaXQgaXMgYmVpbmcgZG93bmxvYWRlZCB3aGlsZSBsb2FkZWQsIHRoZSBwbHVnaW4KCW1pZ2h0IGFsc28gbm90IGdyYWNlZnVsbHkgZmFpbC4KCglUaGUgTG9hZCBmdW5jdGlvbiBoYXMgdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzOgoKICAgIFRoZSBmaXJzdCBwYXJhbWV0ZXIgKEZyZWVJbWFnZUlPICppbykgaXMgYSBzdHJ1Y3R1cmUgcHJvdmlkaW5nCglmdW5jdGlvbiBwb2ludGVycyBpbiBvcmRlciB0byBtYWtlIHVzZSBvZiBGcmVlSW1hZ2UncyBJTyByZWRpcmVjdGlvbi4gVXNpbmcKCUZyZWVJbWFnZSdzIGZpbGUgaS9vIGZ1bmN0aW9ucyBpbnN0ZWFkIG9mIHN0YW5kYXJkIG9uZXMgaXQgaXMgZ2FyYW50dWVlZAoJdGhhdCBhbGwgYml0bWFwIHR5cGVzLCBib3RoIGN1cnJlbnQgYW5kIGZ1dHVyZSBvbmVzLCBjYW4gYmUgbG9hZGVkIGZyb20KCW1lbW9yeSwgZmlsZSBjYWJpbmV0cywgdGhlIGludGVybmV0IGFuZCBtb3JlLiBUaGUgc2Vjb25kIHBhcmFtZXRlciAoZmlfaGFuZGxlIGhhbmRsZSkKCWlzIGEgY29tcGFuaW9uIG9mIEZyZWVJbWFnZUlPIGFuZCBjYW4gYmUgYmVzdCBjb21wYXJlZCB3aXRoIHRoZSBzdGFuZGFyZCBGSUxFKiB0eXBlLAoJaW4gYSBnZW5lcmFsaXplZCBmb3JtLgoKCVRoZSB0aGlyZCBwYXJhbWV0ZXIgKGludCBwYWdlKSBpbmRpY2F0ZXMgd2V0aGVyIHdlIHdpbGwgYmUgbG9hZGluZyBhIGNlcnRhaW4gcGFnZQoJaW4gdGhlIGJpdG1hcCBvciBpZiB3ZSB3aWxsIGxvYWQgdGhlIGRlZmF1bHQgb25lLiBUaGlzIHBhcmFtZXRlciBpcyBvbmx5IHVzZWQgaWYKCXRoZSBwbHVnaW4gc3VwcG9ydHMgbXVsdGktcGFnZWQgYml0bWFwcywgZS5nLiBjYWJpbmV0IGJpdG1hcHMgdGhhdCBjb250YWluIGEgc2VyaWVzCglvZiBpbWFnZXMgb3IgcGFnZXMuIElmIHRoZSBwbHVnaW4gZG9lcyBzdXBwb3J0IG11bHRpLXBhZ2luZywgdGhlIHBhZ2UgcGFyYW1ldGVyCgljYW4gY29udGFpbiBlaXRoZXIgYSBudW1iZXIgaGlnaGVyIG9yIGVxdWFsIHRvIDAgdG8gbG9hZCBhIGNlcnRhaW4gcGFnZSwgb3IgLTEgdG8gCglsb2FkIHRoZSBkZWZhdWx0IHBhZ2UuIElmIHRoZSBwbHVnaW4gZG9lcyBub3Qgc3VwcG9ydCBtdWx0aS1wYWdpbmcsCgl0aGUgcGFnZSBwYXJhbWV0ZXIgaXMgYWx3YXlzIC0xLgoJCglUaGUgZm91cnRoIHBhcmFtZXRlciAoaW50IGZsYWdzKSBtYW5pcHVsYXRlcyB0aGUgbG9hZCBmdW5jdGlvbiB0byBsb2FkIGEgYml0bWFwCglpbiBhIGNlcnRhaW4gd2F5LiBFdmVyeSBwbHVnaW4gaGFzIGEgZGlmZmVyZW50IGZsYWcgcGFyYW1ldGVyIHdpdGggZGlmZmVyZW50IG1lYW5pbmdzLgoKCVRoZSBsYXN0IHBhcmFtZXRlciAodm9pZCAqZGF0YSkgY2FuIGNvbnRhaW4gYSBzcGVjaWFsIGRhdGEgYmxvY2sgdXNlZCB3aGVuCgl0aGUgZmlsZSBpcyByZWFkIG11bHRpLXBhZ2VkLiBCZWNhdXNlIG5vdCBldmVyeSBwbHVnaW4gc3VwcG9ydHMgbXVsdGktcGFnaW5nCglub3QgZXZlcnkgcGx1Z2luIHdpbGwgdXNlIHRoZSBkYXRhIHBhcmFtZXRlciBhbmQgaXQgd2lsbCBiZSBzZXQgdG8gTlVMTC5Ib3dldmVyLAoJd2hlbiB0aGUgcGx1Z2luIGRvZXMgc3VwcG9ydCBtdWx0aS1wYWdpbmcgdGhlIHBhcmFtZXRlciBjb250YWlucyBhIHBvaW50ZXIgdG8gYQoJYmxvY2sgb2YgZGF0YSBhbGxvY2F0ZWQgYnkgdGhlIE9wZW4gZnVuY3Rpb24uCiovCgpzdGF0aWMgRklCSVRNQVAgKiBETExfQ0FMTENPTlYKTG9hZChGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIGludCBwYWdlLCBpbnQgZmxhZ3MsIHZvaWQgKmRhdGEpIHsKCUZJQklUTUFQICpkaWIgPSBOVUxMOwoJQllURSAqYml0czsJCQkgIC8vIFBvaW50ZXIgdG8gZGliIGRhdGEKCVJHQlFVQUQgKnBhbDsJCSAgLy8gUG9pbnRlciB0byBkaWIgcGFsZXR0ZQoJQllURSAqbGluZSA9IE5VTEw7CSAgLy8gUENYIHJhc3RlciBsaW5lCglCWVRFICpSZWFkQnVmID0gTlVMTDsgLy8gYnVmZmVyOwoJQk9PTCBiSXNSTEU7CQkgIC8vIFRydWUgaWYgdGhlIGZpbGUgaXMgcnVuLWxlbmd0aCBlbmNvZGVkCgoJaWYoIWhhbmRsZSkgewoJCXJldHVybiBOVUxMOwoJfQoKCUJPT0wgaGVhZGVyX29ubHkgPSAoZmxhZ3MgJiBGSUZfTE9BRF9OT1BJWEVMUykgPT0gRklGX0xPQURfTk9QSVhFTFM7CgoJdHJ5IHsKCQkvLyBjaGVjayBQQ1ggaWRlbnRpZmllcgoKCQlsb25nIHN0YXJ0X3BvcyA9IGlvLT50ZWxsX3Byb2MoaGFuZGxlKTsKCQlCT09MIHZhbGlkYXRlZCA9IHBjeF92YWxpZGF0ZShpbywgaGFuZGxlKTsJCQoJCWlvLT5zZWVrX3Byb2MoaGFuZGxlLCBzdGFydF9wb3MsIFNFRUtfU0VUKTsKCQlpZighdmFsaWRhdGVkKSB7CgkJCXRocm93IEZJX01TR19FUlJPUl9NQUdJQ19OVU1CRVI7CgkJfQoKCQkvLyBwcm9jZXNzIHRoZSBoZWFkZXIKCgkJUENYSEVBREVSIGhlYWRlcjsKCgkJaWYoaW8tPnJlYWRfcHJvYygmaGVhZGVyLCBzaXplb2YoUENYSEVBREVSKSwgMSwgaGFuZGxlKSAhPSAxKSB7CgkJCXRocm93IEZJX01TR19FUlJPUl9QQVJTSU5HOwoJCX0KI2lmZGVmIEZSRUVJTUFHRV9CSUdFTkRJQU4KCQlTd2FwSGVhZGVyKCZoZWFkZXIpOwojZW5kaWYKCgkJLy8gYWxsb2NhdGUgYSBuZXcgRElCCgoJCXVuc2lnbmVkIHdpZHRoID0gaGVhZGVyLndpbmRvd1syXSAtIGhlYWRlci53aW5kb3dbMF0gKyAxOwoJCXVuc2lnbmVkIGhlaWdodCA9IGhlYWRlci53aW5kb3dbM10gLSBoZWFkZXIud2luZG93WzFdICsgMTsKCQl1bnNpZ25lZCBiaXRjb3VudCA9IGhlYWRlci5icHAgKiBoZWFkZXIucGxhbmVzOwoKCQlpZiAoYml0Y291bnQgPT0gMjQpIHsKCQkJZGliID0gRnJlZUltYWdlX0FsbG9jYXRlSGVhZGVyKGhlYWRlcl9vbmx5LCB3aWR0aCwgaGVpZ2h0LCBiaXRjb3VudCwgRklfUkdCQV9SRURfTUFTSywgRklfUkdCQV9HUkVFTl9NQVNLLCBGSV9SR0JBX0JMVUVfTUFTSyk7CgkJfSBlbHNlIHsKCQkJZGliID0gRnJlZUltYWdlX0FsbG9jYXRlSGVhZGVyKGhlYWRlcl9vbmx5LCB3aWR0aCwgaGVpZ2h0LCBiaXRjb3VudCk7CQkJCgkJfQoKCQkvLyBpZiB0aGUgZGliIGNvdWxkbid0IGJlIGFsbG9jYXRlZCwgdGhyb3cgYW4gZXJyb3IKCgkJaWYgKCFkaWIpIHsKCQkJdGhyb3cgRklfTVNHX0VSUk9SX0RJQl9NRU1PUlk7CgkJfQoKCQkvLyBtZXRyaWNzIGhhbmRsaW5nIGNvZGUKCgkJRnJlZUltYWdlX1NldERvdHNQZXJNZXRlclgoZGliLCAodW5zaWduZWQpICgoKGZsb2F0KWhlYWRlci5oZHBpKSAvIDAuMDI1NDAwMCArIDAuNSkpOwoJCUZyZWVJbWFnZV9TZXREb3RzUGVyTWV0ZXJZKGRpYiwgKHVuc2lnbmVkKSAoKChmbG9hdCloZWFkZXIudmRwaSkgLyAwLjAyNTQwMDAgKyAwLjUpKTsKCgkJLy8gU2V0IHVwIHRoZSBwYWxldHRlIGlmIG5lZWRlZAoJCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgkJc3dpdGNoKGJpdGNvdW50KSB7CgkJCWNhc2UgMToKCQkJewoJCQkJcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKTsKCQkJCXBhbFswXS5yZ2JSZWQgPSBwYWxbMF0ucmdiR3JlZW4gPSBwYWxbMF0ucmdiQmx1ZSA9IDA7CgkJCQlwYWxbMV0ucmdiUmVkID0gcGFsWzFdLnJnYkdyZWVuID0gcGFsWzFdLnJnYkJsdWUgPSAyNTU7CgkJCQlicmVhazsKCQkJfQoKCQkJY2FzZSA0OgoJCQl7CgkJCQlwYWwgPSBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkaWIpOwoKCQkJCUJZVEUgKnBDb2xvcm1hcCA9ICZoZWFkZXIuY29sb3JfbWFwWzBdOwoKCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykgewoJCQkJCXBhbFtpXS5yZ2JSZWQgICA9IHBDb2xvcm1hcFswXTsKCQkJCQlwYWxbaV0ucmdiR3JlZW4gPSBwQ29sb3JtYXBbMV07CgkJCQkJcGFsW2ldLnJnYkJsdWUgID0gcENvbG9ybWFwWzJdOwoJCQkJCXBDb2xvcm1hcCArPSAzOwoJCQkJfQoKCQkJCWJyZWFrOwoJCQl9CgoJCQljYXNlIDg6CgkJCXsKCQkJCUJZVEUgcGFsZXR0ZV9pZDsKCgkJCQlpby0+c2Vla19wcm9jKGhhbmRsZSwgLTc2OUwsIFNFRUtfRU5EKTsKCQkJCWlvLT5yZWFkX3Byb2MoJnBhbGV0dGVfaWQsIDEsIDEsIGhhbmRsZSk7CgoJCQkJaWYgKHBhbGV0dGVfaWQgPT0gMHgwQykgewoJCQkJCUJZVEUgKmNtYXAgPSAoQllURSopbWFsbG9jKDc2OCAqIHNpemVvZihCWVRFKSk7CgkJCQkJaW8tPnJlYWRfcHJvYyhjbWFwLCA3NjgsIDEsIGhhbmRsZSk7CgoJCQkJCXBhbCA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYik7CgkJCQkJQllURSAqcENvbG9ybWFwID0gJmNtYXBbMF07CgoJCQkJCWZvcihpbnQgaSA9IDA7IGkgPCAyNTY7IGkrKykgewoJCQkJCQlwYWxbaV0ucmdiUmVkICAgPSBwQ29sb3JtYXBbMF07CgkJCQkJCXBhbFtpXS5yZ2JHcmVlbiA9IHBDb2xvcm1hcFsxXTsKCQkJCQkJcGFsW2ldLnJnYkJsdWUgID0gcENvbG9ybWFwWzJdOwoJCQkJCQlwQ29sb3JtYXAgKz0gMzsKCQkJCQl9CgoJCQkJCWZyZWUoY21hcCk7CgkJCQl9CgoJCQkJLy8gd3JvbmcgcGFsZXR0ZSBJRCwgcGVyaGFwcyBhIGdyYXkgc2NhbGUgaXMgbmVlZGVkID8KCgkJCQllbHNlIGlmIChoZWFkZXIucGFsZXR0ZV9pbmZvID09IDIpIHsKCQkJCQlwYWwgPSBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkaWIpOwoKCQkJCQlmb3IoaW50IGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKCQkJCQkJcGFsW2ldLnJnYlJlZCAgID0gKEJZVEUpaTsKCQkJCQkJcGFsW2ldLnJnYkdyZWVuID0gKEJZVEUpaTsKCQkJCQkJcGFsW2ldLnJnYkJsdWUgID0gKEJZVEUpaTsKCQkJCQl9CgkJCQl9CgoJCQkJaW8tPnNlZWtfcHJvYyhoYW5kbGUsIChsb25nKXNpemVvZihQQ1hIRUFERVIpLCBTRUVLX1NFVCk7CgkJCX0KCQkJYnJlYWs7CgkJfQoKCQlpZihoZWFkZXJfb25seSkgewoJCQkvLyBoZWFkZXIgb25seSBtb2RlCgkJCXJldHVybiBkaWI7CgkJfQoKCQkvLyBjYWxjdWxhdGUgdGhlIGxpbmUgbGVuZ3RoIGZvciB0aGUgUENYIGFuZCB0aGUgRElCCgoJCS8vIGxlbmd0aCBvZiByYXN0ZXIgbGluZSBpbiBieXRlcwoJCXVuc2lnbmVkIGxpbmVsZW5ndGggPSBoZWFkZXIuYnl0ZXNfcGVyX2xpbmUgKiBoZWFkZXIucGxhbmVzOwoJCS8vIGxlbmd0aCBvZiBESUIgbGluZSAocm91bmRlZCB0byBEV09SRCkgaW4gYnl0ZXMKCQl1bnNpZ25lZCBwaXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChkaWIpOwoKCQkvLyBydW4tbGVuZ3RoIGVuY29kaW5nID8KCgkJYklzUkxFID0gKGhlYWRlci5lbmNvZGluZyA9PSAxKSA/IFRSVUUgOiBGQUxTRTsKCgkJLy8gbG9hZCBpbWFnZSBkYXRhCgkJLy8gLS0tLS0tLS0tLS0tLS0tCgoJCWxpbmUgPSAoQllURSopbWFsbG9jKGxpbmVsZW5ndGggKiBzaXplb2YoQllURSkpOwoJCWlmKCFsaW5lKSB0aHJvdyBGSV9NU0dfRVJST1JfTUVNT1JZOwoJCQoJCVJlYWRCdWYgPSAoQllURSopbWFsbG9jKElPX0JVRl9TSVpFICogc2l6ZW9mKEJZVEUpKTsKCQlpZighUmVhZEJ1ZikgdGhyb3cgRklfTVNHX0VSUk9SX01FTU9SWTsKCQkKCQliaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaGVpZ2h0IC0gMSk7CgoJCWludCBSZWFkUG9zID0gSU9fQlVGX1NJWkU7CgoJCWlmICgoaGVhZGVyLnBsYW5lcyA9PSAxKSAmJiAoKGhlYWRlci5icHAgPT0gMSkgfHwgKGhlYWRlci5icHAgPT0gOCkpKSB7CgkJCUJZVEUgc2tpcDsKCQkJdW5zaWduZWQgd3JpdHRlbjsKCgkJCWZvciAodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJd3JpdHRlbiA9IHJlYWRsaW5lKCppbywgaGFuZGxlLCBiaXRzLCBsaW5lbGVuZ3RoLCBiSXNSTEUsIFJlYWRCdWYsICZSZWFkUG9zKTsKCgkJCQkvLyBza2lwIHRyYWlsaW5nIGdhcmJhZ2UgYXQgdGhlIGVuZCBvZiB0aGUgc2NhbmxpbmUKCgkJCQlmb3IgKHVuc2lnbmVkIGNvdW50ID0gd3JpdHRlbjsgY291bnQgPCBsaW5lbGVuZ3RoOyBjb3VudCsrKSB7CgkJCQkJaWYgKFJlYWRQb3MgPCBJT19CVUZfU0laRSkgewoJCQkJCQlSZWFkUG9zKys7CgkJCQkJfSBlbHNlIHsKCQkJCQkJaW8tPnJlYWRfcHJvYygmc2tpcCwgc2l6ZW9mKEJZVEUpLCAxLCBoYW5kbGUpOwoJCQkJCX0KCQkJCX0KCgkJCQliaXRzIC09IHBpdGNoOwoJCQl9CgkJfSBlbHNlIGlmICgoaGVhZGVyLnBsYW5lcyA9PSA0KSAmJiAoaGVhZGVyLmJwcCA9PSAxKSkgewoJCQlCWVRFIGJpdCwgIG1hc2ssIHNraXA7CgkJCXVuc2lnbmVkIGluZGV4OwoJCQlCWVRFICpidWZmZXI7CgkJCXVuc2lnbmVkIHgsIHksIHdyaXR0ZW47CgoJCQlidWZmZXIgPSAoQllURSopbWFsbG9jKHdpZHRoICogc2l6ZW9mKEJZVEUpKTsKCQkJaWYoIWJ1ZmZlcikgdGhyb3cgRklfTVNHX0VSUk9SX01FTU9SWTsKCgkJCWZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJd3JpdHRlbiA9IHJlYWRsaW5lKCppbywgaGFuZGxlLCBsaW5lLCBsaW5lbGVuZ3RoLCBiSXNSTEUsIFJlYWRCdWYsICZSZWFkUG9zKTsKCgkJCQkvLyBidWlsZCBhIG5pYmJsZSB1c2luZyB0aGUgNCBwbGFuZXMKCgkJCQltZW1zZXQoYnVmZmVyLCAwLCB3aWR0aCAqIHNpemVvZihCWVRFKSk7CgoJCQkJZm9yKGludCBwbGFuZSA9IDA7IHBsYW5lIDwgNDsgcGxhbmUrKykgewoJCQkJCWJpdCA9IChCWVRFKSgxIDw8IHBsYW5lKTsKCgkJCQkJZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJaW5kZXggPSAodW5zaWduZWQpKCh4IC8gOCkgKyBwbGFuZSAqIGhlYWRlci5ieXRlc19wZXJfbGluZSk7CgkJCQkJCW1hc2sgPSAoQllURSkoMHg4MCA+PiAoeCAmIDB4MDcpKTsKCQkJCQkJYnVmZmVyW3hdIHw9IChsaW5lW2luZGV4XSAmIG1hc2spID8gYml0IDogMDsKCQkJCQl9CgkJCQl9CgoJCQkJLy8gdGhlbiB3cml0ZSB0aGUgRElCIHJvdwoKCQkJCWZvciAoeCA9IDA7IHggPCB3aWR0aCAvIDI7IHgrKykgewoJCQkJCWJpdHNbeF0gPSAoYnVmZmVyWzIqeF0gPDwgNCkgfCBidWZmZXJbMip4KzFdOwoJCQkJfQoKCQkJCS8vIHNraXAgdHJhaWxpbmcgZ2FyYmFnZSBhdCB0aGUgZW5kIG9mIHRoZSBzY2FubGluZQoKCQkJCWZvciAodW5zaWduZWQgY291bnQgPSB3cml0dGVuOyBjb3VudCA8IGxpbmVsZW5ndGg7IGNvdW50KyspIHsKCQkJCQlpZiAoUmVhZFBvcyA8IElPX0JVRl9TSVpFKSB7CgkJCQkJCVJlYWRQb3MrKzsKCQkJCQl9IGVsc2UgewoJCQkJCQlpby0+cmVhZF9wcm9jKCZza2lwLCBzaXplb2YoQllURSksIDEsIGhhbmRsZSk7CgkJCQkJfQoJCQkJfQoKCQkJCWJpdHMgLT0gcGl0Y2g7CgkJCX0KCgkJCWZyZWUoYnVmZmVyKTsKCgkJfSBlbHNlIGlmKChoZWFkZXIucGxhbmVzID09IDMpICYmIChoZWFkZXIuYnBwID09IDgpKSB7CgkJCUJZVEUgKnBsaW5lOwoKCQkJZm9yICh1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQlyZWFkbGluZSgqaW8sIGhhbmRsZSwgbGluZSwgbGluZWxlbmd0aCwgYklzUkxFLCBSZWFkQnVmLCAmUmVhZFBvcyk7CgoJCQkJLy8gY29udmVydCB0aGUgcGxhbmUgc3RyZWFtIHRvIEJHUiAoUlJSUkdHR0dCQkJCIC0+IEJHUkJHUkJHUkJHUikKCQkJCS8vIHdlbGwsIG5vdyB3aXRoIHRoZSBGSV9SR0JBX3ggbWFjcm9zLCBvbiBCSUdFTkRJQU4gd2UgY29udmVydCB0byBSR0IKCgkJCQlwbGluZSA9IGxpbmU7CgkJCQl1bnNpZ25lZCB4OwoKCQkJCWZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJYml0c1t4ICogMyArIEZJX1JHQkFfUkVEXSA9IHBsaW5lW3hdOwkJCQkJCQoJCQkJfQoJCQkJcGxpbmUgKz0gaGVhZGVyLmJ5dGVzX3Blcl9saW5lOwoKCQkJCWZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJYml0c1t4ICogMyArIEZJX1JHQkFfR1JFRU5dID0gcGxpbmVbeF07CgkJCQl9CgkJCQlwbGluZSArPSBoZWFkZXIuYnl0ZXNfcGVyX2xpbmU7CgoJCQkJZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQliaXRzW3ggKiAzICsgRklfUkdCQV9CTFVFXSA9IHBsaW5lW3hdOwoJCQkJfQoJCQkJcGxpbmUgKz0gaGVhZGVyLmJ5dGVzX3Blcl9saW5lOwoKCQkJCWJpdHMgLT0gcGl0Y2g7CgkJCX0KCQl9IGVsc2UgewoJCQl0aHJvdyBGSV9NU0dfRVJST1JfVU5TVVBQT1JURURfRk9STUFUOwoJCX0KCgkJZnJlZShsaW5lKTsKCQlmcmVlKFJlYWRCdWYpOwoKCQlyZXR1cm4gZGliOwoKCX0gY2F0Y2ggKGNvbnN0IGNoYXIgKnRleHQpIHsKCQkvLyBmcmVlIGFsbG9jYXRlZCBtZW1vcnkKCgkJaWYgKGRpYiAhPSBOVUxMKSB7CgkJCUZyZWVJbWFnZV9VbmxvYWQoZGliKTsKCQl9CgkJaWYgKGxpbmUgIT0gTlVMTCkgewoJCQlmcmVlKGxpbmUpOwoJCX0KCQlpZiAoUmVhZEJ1ZiAhPSBOVUxMKSB7CgkJCWZyZWUoUmVhZEJ1Zik7CgkJfQoKCQlGcmVlSW1hZ2VfT3V0cHV0TWVzc2FnZVByb2Moc19mb3JtYXRfaWQsIHRleHQpOwoJfQoJCglyZXR1cm4gTlVMTDsKfQoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyAgIEluaXQKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyohCiAgICBJbml0aWFsaXNlcyB0aGUgcGx1Z2luLiBUaGUgZmlyc3QgcGFyYW1ldGVyIChQbHVnaW4gKnBsdWdpbikKCWNvbnRhaW5zIGEgcG9pbnRlciB0byBhIHByZS1hbGxvY2F0ZWQgUGx1Z2luIHN0cnVjdHVyZQoJd2hlcmVpbiBwb2ludGVycyB0byB0aGUgYXZhaWxhYmxlIHBsdWdpbiBmdW5jdGlvbnMKCWhhcyB0byBiZSBzdG9yZWQuIFRoZSBzZWNvbmQgcGFyYW1ldGVyIChpbnQgZm9ybWF0X2lkKSBpcyBhbiBpZGVudGlmaWNhdGlvbgoJbnVtYmVyIHRoYXQgdGhlIHBsdWdpbiBtYXkgdXNlIHRvIHNob3cgcGx1Z2luIHNwZWNpZmljIHdhcm5pbmcgbWVzc2FnZXMKCW9yIG90aGVyIGluZm9ybWF0aW9uIHRvIHRoZSB1c2VyLiBUaGUgcGx1Z2luIG51bWJlcgoJaXMgZ2VuZXJhdGVkIGJ5IEZyZWVJbWFnZSBhbmQgY2FuIGRpZmZlciBldmVyeXRpbWUgdGhlIHBsdWdpbiBpcwoJaW5pdGlhbGlzZWQuCgogICAgSWYgeW91IHdhbnQgdG8gY3JlYXRlIHlvdXIgb3duIHBsdWdpbiB5b3UgaGF2ZSB0byB0YWtlIHNvbWUKCXJ1bGVzIGludG8gYWNjb3VudC4gUGx1Z2luIGZ1bmN0aW9ucyBoYXZlIHRvIGJlIGNvbXBpbGVkCglfX3N0ZGNhbGwgdXNpbmcgdGhlIG11bHRpdGhyZWFkZWQgYyBydW50aW1lIGxpYnJhcmllcy4gVGhyb3dpbmcKCWV4Y2VwdGlvbnMgaW4gcGx1Z2luIGZ1bmN0aW9ucyBpcyBhbGxvd2VkLCBhcyBsb25nIGFzIHRob3NlIGV4Y2VwdGlvbnMKCWFyZSBiZWluZyBjYXVnaHQgaW5zaWRlIHRoZSBzYW1lIHBsdWdpbi4gSXQgaXMgZm9yYmlkZGVuIGZvciBhIHBsdWdpbgoJZnVuY3Rpb24gdG8gZGlyZWN0bHkgY2FsbCBGcmVlSW1hZ2UgZnVuY3Rpb25zIG9yIHRvIGFsbG9jYXRlIG1lbW9yeQoJYW5kIHBhc3MgaXQgdG8gdGhlIG1haW4gRExMLiBFeGNlcHRpb24gdG8gdGhpcyBydWxlIGlzIHRoZSBzcGVjaWFsIGZpbGUgZGF0YQoJYmxvY2sgdGhhdCBtYXkgYmUgYWxsb2NhdGVkIHRoZSBPcGVuIGZ1bmN0aW9uLiBBbGxvY2F0aW5nIGEgRklCSVRNQVAgaW5zaWRlIGEKCXBsdWdpbiBjYW4gYmUgdXNpbmcgdGhlIGZ1bmN0aW9uIGFsbG9jYXRlX3Byb2MgaW4gdGhlIEZyZWVJbWFnZSBzdHJ1Y3R1cmUsCgl3aGljaCB3aWxsIGFsbG9jYXRlIHRoZSBtZW1vcnkgdXNpbmcgdGhlIERMTCdzIGMgcnVudGltZSBsaWJyYXJ5LgoqLwoKdm9pZCBETExfQ0FMTENPTlYKSW5pdFBDWChQbHVnaW4gKnBsdWdpbiwgaW50IGZvcm1hdF9pZCkgewoJc19mb3JtYXRfaWQgPSBmb3JtYXRfaWQ7CgoJcGx1Z2luLT5mb3JtYXRfcHJvYyA9IEZvcm1hdDsKCXBsdWdpbi0+ZGVzY3JpcHRpb25fcHJvYyA9IERlc2NyaXB0aW9uOwoJcGx1Z2luLT5leHRlbnNpb25fcHJvYyA9IEV4dGVuc2lvbjsKCXBsdWdpbi0+cmVnZXhwcl9wcm9jID0gUmVnRXhwcjsKCXBsdWdpbi0+b3Blbl9wcm9jID0gTlVMTDsKCXBsdWdpbi0+Y2xvc2VfcHJvYyA9IE5VTEw7CglwbHVnaW4tPnBhZ2Vjb3VudF9wcm9jID0gTlVMTDsKCXBsdWdpbi0+cGFnZWNhcGFiaWxpdHlfcHJvYyA9IE5VTEw7CglwbHVnaW4tPmxvYWRfcHJvYyA9IExvYWQ7CglwbHVnaW4tPnNhdmVfcHJvYyA9IE5VTEw7CglwbHVnaW4tPnZhbGlkYXRlX3Byb2MgPSBWYWxpZGF0ZTsKCXBsdWdpbi0+bWltZV9wcm9jID0gTWltZVR5cGU7CglwbHVnaW4tPnN1cHBvcnRzX2V4cG9ydF9icHBfcHJvYyA9IFN1cHBvcnRzRXhwb3J0RGVwdGg7CglwbHVnaW4tPnN1cHBvcnRzX2V4cG9ydF90eXBlX3Byb2MgPSBTdXBwb3J0c0V4cG9ydFR5cGU7CglwbHVnaW4tPnN1cHBvcnRzX2ljY19wcm9maWxlc19wcm9jID0gTlVMTDsKCXBsdWdpbi0+c3VwcG9ydHNfbm9fcGl4ZWxzX3Byb2MgPSBTdXBwb3J0c05vUGl4ZWxzOwp9Cg==