LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQogKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovLyBNQVJLRVIodXBkYXRlX3ByZWNvbXAucHkpOiBhdXRvZ2VuIGluY2x1ZGUgc3RhdGVtZW50LCBkbyBub3QgcmVtb3ZlCiNpbmNsdWRlICJwcmVjb21waWxlZF9iYXNpYy5oeHgiCgoKI2luY2x1ZGUgPHRvb2xzL3NobC5oeHg+CiNpbmNsdWRlIDx0b29scy9zdHJlYW0uaHh4PgoKI2luY2x1ZGUgPGJhc2ljL3NieC5oeHg+CiNpbmNsdWRlIDxiYXNpYy9zYnhmYWMuaHh4PgojaW5jbHVkZSA8YmFzaWMvc2J4YmFzZS5oeHg+CgovLyBBcHBEYXRhLVN0cnVrdHVyIGZ1ZXIgU0JYOgoKU1ZfSU1QTF9QVFJBUlIoU2J4UGFyYW1zLFNieFBhcmFtSW5mbyopOwpTVl9JTVBMX1BUUkFSUihTYnhGYWNzLFNieEZhY3RvcnkqKTsKClRZUEVJTklUMChTYnhCYXNlKQoKLy8gU0JYLURhdGVuIGFuZm9yZGVybiBvZGVyIGdnZi4gYW5sZWdlbgovLyB3aXIgbGVnZW4gZGVuIEJlcmVpY2ggZWluZmFjaCBhbiB1bmQgdmVyemljaHRlbiBhdWYgZGllIEZyZWlnYWJlIQoKU2J4QXBwRGF0YSogR2V0U2J4RGF0YV9JbXBsKCkKewoJU2J4QXBwRGF0YSoqIHBwRGF0YSA9IChTYnhBcHBEYXRhKiopIDo6R2V0QXBwRGF0YSggU0hMX1NCWCApOwoJU2J4QXBwRGF0YSogcCA9ICpwcERhdGE7CglpZiggIXAgKQoJCXAgPSAqcHBEYXRhICA9IG5ldyBTYnhBcHBEYXRhOwoJcmV0dXJuIHA7Cn0KClNieEFwcERhdGE6On5TYnhBcHBEYXRhKCkKewoJaWYoIHBCYXNpY0Zvcm1hdGVyICkKCQlkZWxldGUgcEJhc2ljRm9ybWF0ZXI7Cn0KCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBTYnhCYXNlIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLwoKREJHX05BTUUoU2J4QmFzZSk7CgpTYnhCYXNlOjpTYnhCYXNlKCkKewoJREJHX0NUT1IoIFNieEJhc2UsIDAgKTsKCW5GbGFncyAgPSBTQlhfUkVBRFdSSVRFOwp9CgpTYnhCYXNlOjpTYnhCYXNlKCBjb25zdCBTYnhCYXNlJiByICkKICAgIDogU3ZSZWZCYXNlKCByICkKewoJREJHX0NUT1IoIFNieEJhc2UsIDAgKTsKCW5GbGFncyAgPSByLm5GbGFnczsKfQoKU2J4QmFzZTo6flNieEJhc2UoKQp7CglEQkdfRFRPUihTYnhCYXNlLDApOwp9CgpTYnhCYXNlJiBTYnhCYXNlOjpvcGVyYXRvcj0oIGNvbnN0IFNieEJhc2UmIHIgKQp7CglEQkdfQ0hLVEhJUyggU2J4QmFzZSwgMCApOwoJbkZsYWdzID0gci5uRmxhZ3M7CglyZXR1cm4gKnRoaXM7Cn0KClNieERhdGFUeXBlIFNieEJhc2U6OkdldFR5cGUoKSBjb25zdAp7CglEQkdfQ0hLVEhJUyggU2J4QmFzZSwgMCApOwoJcmV0dXJuIFNieEVNUFRZOwp9CgpTYnhDbGFzc1R5cGUgU2J4QmFzZTo6R2V0Q2xhc3MoKSBjb25zdAp7CglEQkdfQ0hLVEhJUyggU2J4QmFzZSwgMCApOwoJcmV0dXJuIFNieENMQVNTX0RPTlRDQVJFOwp9Cgp2b2lkIFNieEJhc2U6OkNsZWFyKCkKewoJREJHX0NIS1RISVMoIFNieEJhc2UsIDAgKTsKfQoKc2FsX0Jvb2wgU2J4QmFzZTo6SXNGaXhlZCgpIGNvbnN0CnsKCURCR19DSEtUSElTKCBTYnhCYXNlLCAwICk7CglyZXR1cm4gSXNTZXQoIFNCWF9GSVhFRCApOwp9Cgp2b2lkIFNieEJhc2U6OlNldE1vZGlmaWVkKCBzYWxfQm9vbCBiICkKewoJREJHX0NIS1RISVMoIFNieEJhc2UsIDAgKTsKCWlmKCBJc1NldCggU0JYX05PX01PRElGWSApICkKCQlyZXR1cm47CglpZiggYiApCgkJU2V0RmxhZyggU0JYX01PRElGSUVEICk7CgllbHNlCgkJUmVzZXRGbGFnKCBTQlhfTU9ESUZJRUQgKTsKfQoKU2J4RXJyb3IgU2J4QmFzZTo6R2V0RXJyb3IoKQp7CglyZXR1cm4gR2V0U2J4RGF0YV9JbXBsKCktPmVTYnhFcnJvcjsKfQoKdm9pZCBTYnhCYXNlOjpTZXRFcnJvciggU2J4RXJyb3IgZSApCnsKCVNieEFwcERhdGEqIHAgPSBHZXRTYnhEYXRhX0ltcGwoKTsKCWlmKCBlICYmIHAtPmVTYnhFcnJvciA9PSBTYnhFUlJfT0sgKQoJCXAtPmVTYnhFcnJvciA9IGU7Cn0KCnNhbF9Cb29sIFNieEJhc2U6OklzRXJyb3IoKQp7CglyZXR1cm4gc2FsX0Jvb2woIEdldFNieERhdGFfSW1wbCgpLT5lU2J4RXJyb3IgIT0gU2J4RVJSX09LICk7Cn0KCnZvaWQgU2J4QmFzZTo6UmVzZXRFcnJvcigpCnsKCUdldFNieERhdGFfSW1wbCgpLT5lU2J4RXJyb3IgPSBTYnhFUlJfT0s7Cn0KCnZvaWQgU2J4QmFzZTo6QWRkRmFjdG9yeSggU2J4RmFjdG9yeSogcEZhYyApCnsKCVNieEFwcERhdGEqIHAgPSBHZXRTYnhEYXRhX0ltcGwoKTsKCWNvbnN0IFNieEZhY3RvcnkqIHBUZW1wID0gcEZhYzsKCgkvLyBBQiwgNi4zLjk2OiBIYW5kbGVMYXN0LUZsYWcgYmVydWVja3NpY2h0aWdlbgoJc2FsX3VJbnQxNiBuUG9zID0gcC0+YUZhY3MuQ291bnQoKTsJCS8vIEVpbmZ1ZWdlLVBvc2l0aW9uCglpZiggIXBGYWMtPklzSGFuZGxlTGFzdCgpICkJCQkvLyBOdXIsIHdlbm4gbmljaHQgc2VsYnN0IEhhbmRsZUxhc3QKCXsKCQkvLyBOZXVlIEZhY3Rvcnkgdm9yIEZhY3RvcmllcyBtaXQgSGFuZGxlTGFzdCBlaW5vcmRuZW4KCQl3aGlsZSggblBvcyA+IDAgJiYKCQkJCShzdGF0aWNfY2FzdDxTYnhGYWN0b3J5Kj4ocC0+YUZhY3MuR2V0T2JqZWN0KCBuUG9zLTEgKSkpLT5Jc0hhbmRsZUxhc3QoKSApCgkJCW5Qb3MtLTsKCX0KCXAtPmFGYWNzLkluc2VydCggcFRlbXAsIG5Qb3MgKTsKfQoKdm9pZCBTYnhCYXNlOjpSZW1vdmVGYWN0b3J5KCBTYnhGYWN0b3J5KiBwRmFjICkKewoJU2J4QXBwRGF0YSogcCA9IEdldFNieERhdGFfSW1wbCgpOwoJZm9yKCBzYWxfdUludDE2IGkgPSAwOyBpIDwgcC0+YUZhY3MuQ291bnQoKTsgaSsrICkKCXsKCQlpZiggcC0+YUZhY3MuR2V0T2JqZWN0KCBpICkgPT0gcEZhYyApCgkJewoJCQlwLT5hRmFjcy5SZW1vdmUoIGksIDEgKTsgYnJlYWs7CgkJfQoJfQp9CgoKU2J4QmFzZSogU2J4QmFzZTo6Q3JlYXRlKCBzYWxfdUludDE2IG5TYnhJZCwgc2FsX3VJbnQzMiBuQ3JlYXRvciApCnsKICAgIC8vICM5MTYyNjogSGFjayB0byBza2lwIG9sZCBCYXNpYyBkaWFsb2dzCiAgICAvLyBQcm9ibGVtOiBUaGVyZSBkb2VzIG5vdCBleGlzdCBhIGZhY3RvcnkgYW55IG1vcmUsCiAgICAvLyBzbyB3ZSBoYXZlIHRvIGNyZWF0ZSBhIGR1bW15IFNieFZhcmlhYmxlIGluc3RlYWQKCWlmKCBuU2J4SWQgPT0gMHg2NSApICAgIC8vIERpYWxvZyBJZAogICAgICAgIHJldHVybiBuZXcgU2J4VmFyaWFibGU7CgoJWHViU3RyaW5nIGFFbXB0eVN0cjsKCWlmKCBuQ3JlYXRvciA9PSBTQlhDUl9TQlggKQoJICBzd2l0Y2goIG5TYnhJZCApCgl7CgkJY2FzZSBTQlhJRF9WQUxVRToJCXJldHVybiBuZXcgU2J4VmFsdWU7CgkJY2FzZSBTQlhJRF9WQVJJQUJMRToJcmV0dXJuIG5ldyBTYnhWYXJpYWJsZTsKCQljYXNlIFNCWElEX0FSUkFZOiAgCQlyZXR1cm4gbmV3IFNieEFycmF5OwoJCWNhc2UgU0JYSURfRElNQVJSQVk6CXJldHVybiBuZXcgU2J4RGltQXJyYXk7CgkJY2FzZSBTQlhJRF9PQkpFQ1Q6CQlyZXR1cm4gbmV3IFNieE9iamVjdCggYUVtcHR5U3RyICk7CgkJY2FzZSBTQlhJRF9DT0xMRUNUSU9OOglyZXR1cm4gbmV3IFNieENvbGxlY3Rpb24oIGFFbXB0eVN0ciApOwoJCWNhc2UgU0JYSURfRklYQ09MTEVDVElPTjoKCQkJCQkJCQlyZXR1cm4gbmV3IFNieFN0ZENvbGxlY3Rpb24oIGFFbXB0eVN0ciwgYUVtcHR5U3RyICk7CgkJY2FzZSBTQlhJRF9NRVRIT0Q6CQlyZXR1cm4gbmV3IFNieE1ldGhvZCggYUVtcHR5U3RyLCBTYnhFTVBUWSApOwoJCWNhc2UgU0JYSURfUFJPUEVSVFk6CXJldHVybiBuZXcgU2J4UHJvcGVydHkoIGFFbXB0eVN0ciwgU2J4RU1QVFkgKTsKCX0KCS8vIFVuYmVrYW50ZXIgVHlwOiCBYmVyIGRpZSBGYWN0b3JpZXMgZ2VoZW4hCglTYnhBcHBEYXRhKiBwID0gR2V0U2J4RGF0YV9JbXBsKCk7CglTYnhCYXNlKiBwTmV3ID0gTlVMTDsKCWZvciggc2FsX3VJbnQxNiBpID0gMDsgaSA8IHAtPmFGYWNzLkNvdW50KCk7IGkrKyApCgl7CgkJU2J4RmFjdG9yeSogcEZhYyA9IHAtPmFGYWNzLkdldE9iamVjdCggaSApOwoJCXBOZXcgPSBwRmFjLT5DcmVhdGUoIG5TYnhJZCwgbkNyZWF0b3IgKTsKCQlpZiggcE5ldyApCgkJCWJyZWFrOwoJfQojaWZkZWYgREJHX1VUSUwKCWlmKCAhcE5ldyApCgl7CgkJQnl0ZVN0cmluZyBhTXNnKCAiU0JYOiBLZWluZSBGYWN0b3J5IGZ1ZXIgU0JYLUlEICIgKTsKCQlhTXNnICs9IEJ5dGVTdHJpbmc6OkNyZWF0ZUZyb21JbnQzMihuU2J4SWQpOwoJCURiZ0Vycm9yKCBhTXNnLkdldEJ1ZmZlcigpICk7Cgl9CiNlbmRpZgoJcmV0dXJuIHBOZXc7Cn0KClNieE9iamVjdCogU2J4QmFzZTo6Q3JlYXRlT2JqZWN0KCBjb25zdCBYdWJTdHJpbmcmIHJDbGFzcyApCnsKCVNieEFwcERhdGEqIHAgPSBHZXRTYnhEYXRhX0ltcGwoKTsKCVNieE9iamVjdCogcE5ldyA9IE5VTEw7Cglmb3IoIHNhbF91SW50MTYgaSA9IDA7IGkgPCBwLT5hRmFjcy5Db3VudCgpOyBpKysgKQoJewoJCXBOZXcgPSBwLT5hRmFjcy5HZXRPYmplY3QoIGkgKS0+Q3JlYXRlT2JqZWN0KCByQ2xhc3MgKTsKCQlpZiggcE5ldyApCgkJCWJyZWFrOwoJfQojaWZkZWYgREJHX1VUSUwKCWlmKCAhcE5ldyApCgl7CgkJQnl0ZVN0cmluZyBhTXNnKCAiU0JYOiBLZWluZSBGYWN0b3J5IGZ1ZXIgT2JqZWt0a2xhc3NlICIgKTsKCQlCeXRlU3RyaW5nIGFDbGFzc1N0ciggKGNvbnN0IFVuaVN0cmluZyYpckNsYXNzLCBSVExfVEVYVEVOQ09ESU5HX0FTQ0lJX1VTICk7CgkJYU1zZyArPSBhQ2xhc3NTdHI7CgkJRGJnRXJyb3IoIChjb25zdCBjaGFyKilhTXNnLkdldEJ1ZmZlcigpICk7Cgl9CiNlbmRpZgoJcmV0dXJuIHBOZXc7Cn0KCnN0YXRpYyBzYWxfQm9vbCBiU3RhdGljRW5hYmxlQnJvYWRjYXN0aW5nID0gc2FsX1RydWU7CgovLyBTYngtTG9lc3VuZyBhbHMgRXJzYXR6IGZ1ZXIgU2Z4QnJvYWRjYXN0ZXI6OkVuYWJsZSgpCnZvaWQgU2J4QmFzZTo6U3RhdGljRW5hYmxlQnJvYWRjYXN0aW5nKCBzYWxfQm9vbCBiRW5hYmxlICkKewoJYlN0YXRpY0VuYWJsZUJyb2FkY2FzdGluZyA9IGJFbmFibGU7Cn0KCnNhbF9Cb29sIFNieEJhc2U6OlN0YXRpY0lzRW5hYmxlZEJyb2FkY2FzdGluZyggdm9pZCApCnsKCXJldHVybiBiU3RhdGljRW5hYmxlQnJvYWRjYXN0aW5nOwp9CgoKU2J4QmFzZSogU2J4QmFzZTo6TG9hZCggU3ZTdHJlYW0mIHJTdHJtICkKewoJc2FsX3VJbnQxNiBuU2J4SWQsIG5GbGFncywgblZlcjsKCXNhbF91SW50MzIgbkNyZWF0b3IsIG5TaXplOwoJclN0cm0gPj4gbkNyZWF0b3IgPj4gblNieElkID4+IG5GbGFncyA+PiBuVmVyOwoKCS8vIEVpbmUgRHVtbWhlaXQgbWVpbmVyc2VpdHMga29ycmlnaWVyZW46CglpZiggbkZsYWdzICYgU0JYX1JFU0VSVkVEICkKCQluRmxhZ3MgPSAoIG5GbGFncyAmIH5TQlhfUkVTRVJWRUQgKSB8IFNCWF9HQkxTRUFSQ0g7CgoJc2FsX3VJbnRQdHIgbk9sZFBvcyA9IHJTdHJtLlRlbGwoKTsKCXJTdHJtID4+IG5TaXplOwoJU2J4QmFzZSogcCA9IENyZWF0ZSggblNieElkLCBuQ3JlYXRvciApOwoJaWYoIHAgKQoJewoJCXAtPm5GbGFncyA9IG5GbGFnczsKCQlpZiggcC0+TG9hZERhdGEoIHJTdHJtLCBuVmVyICkgKQoJCXsKCQkJc2FsX3VJbnRQdHIgbk5ld1BvcyA9IHJTdHJtLlRlbGwoKTsKCQkJbk9sZFBvcyArPSBuU2l6ZTsKCQkJREJHX0FTU0VSVCggbk9sZFBvcyA+PSBuTmV3UG9zLCAiU0JYOiBadSB2aWVsZSBEYXRlbiBlaW5nZWxlc2VuIiApOwoJCQlpZiggbk9sZFBvcyAhPSBuTmV3UG9zICkKCQkJCXJTdHJtLlNlZWsoIG5PbGRQb3MgKTsKCQkJaWYoICFwLT5Mb2FkQ29tcGxldGVkKCkgKQoJCQl7CgkJCQkvLyBMb2VzY2hlbiBkZXMgT2JqZWt0cwoJCQkJU2J4QmFzZVJlZiBhUmVmKCBwICk7CgkJCQlwID0gTlVMTDsKCQkJfQoJCX0KCQllbHNlCgkJewoJCQlyU3RybS5TZXRFcnJvciggU1ZTVFJFQU1fRklMRUZPUk1BVF9FUlJPUiApOwoJCQkvLyBMb2VzY2hlbiBkZXMgT2JqZWt0cwoJCQlTYnhCYXNlUmVmIGFSZWYoIHAgKTsKCQkJcCA9IE5VTEw7CgkJfQoJfQoJZWxzZQoJCXJTdHJtLlNldEVycm9yKCBTVlNUUkVBTV9GSUxFRk9STUFUX0VSUk9SICk7CglyZXR1cm4gcDsKfQoKLy8gU2J4LU9iamVrdCBpbSBTdHJlYW0gdWViZXJzcHJpbmdlbgp2b2lkIFNieEJhc2U6OlNraXAoIFN2U3RyZWFtJiByU3RybSApCnsKCXNhbF91SW50MTYgblNieElkLCBuRmxhZ3MsIG5WZXI7CglzYWxfdUludDMyIG5DcmVhdG9yLCBuU2l6ZTsKCXJTdHJtID4+IG5DcmVhdG9yID4+IG5TYnhJZCA+PiBuRmxhZ3MgPj4gblZlcjsKCglzYWxfdUludFB0ciBuU3RhcnRQb3MgPSByU3RybS5UZWxsKCk7CglyU3RybSA+PiBuU2l6ZTsKCglyU3RybS5TZWVrKCBuU3RhcnRQb3MgKyBuU2l6ZSApOwp9CgpzYWxfQm9vbCBTYnhCYXNlOjpTdG9yZSggU3ZTdHJlYW0mIHJTdHJtICkKewoJREJHX0NIS1RISVMoIFNieEJhc2UsIDAgKTsKCWlmKCAhKCBuRmxhZ3MgJiBTQlhfRE9OVFNUT1JFICkgKQoJewoJCXJTdHJtIDw8IChzYWxfdUludDMyKSBHZXRDcmVhdG9yKCkKCQkJICA8PCAoc2FsX3VJbnQxNikgR2V0U2J4SWQoKQoJCQkgIDw8IChzYWxfdUludDE2KSBHZXRGbGFncygpCgkJCSAgPDwgKHNhbF91SW50MTYpIEdldFZlcnNpb24oKTsKCQlzYWxfdUludFB0ciBuT2xkUG9zID0gclN0cm0uVGVsbCgpOwoJCXJTdHJtIDw8IChzYWxfdUludDMyKSAwTDsKCQlzYWxfQm9vbCBiUmVzID0gU3RvcmVEYXRhKCByU3RybSApOwoJCXNhbF91SW50UHRyIG5OZXdQb3MgPSByU3RybS5UZWxsKCk7CgkJclN0cm0uU2Vlayggbk9sZFBvcyApOwoJCXJTdHJtIDw8IChzYWxfdUludDMyKSAoIG5OZXdQb3MgLSBuT2xkUG9zICk7CgkJclN0cm0uU2Vlayggbk5ld1BvcyApOwoJCWlmKCByU3RybS5HZXRFcnJvcigpICE9IFNWU1RSRUFNX09LICkKCQkJYlJlcyA9IHNhbF9GYWxzZTsKCQlpZiggYlJlcyApCgkJCWJSZXMgPSBTdG9yZUNvbXBsZXRlZCgpOwoJCXJldHVybiBiUmVzOwoJfQoJZWxzZQoJCXJldHVybiBzYWxfVHJ1ZTsKfQoKc2FsX0Jvb2wgU2J4QmFzZTo6TG9hZERhdGEoIFN2U3RyZWFtJiwgc2FsX3VJbnQxNiApCnsKCURCR19DSEtUSElTKCBTYnhCYXNlLCAwICk7CglyZXR1cm4gc2FsX0ZhbHNlOwp9CgpzYWxfQm9vbCBTYnhCYXNlOjpTdG9yZURhdGEoIFN2U3RyZWFtJiApIGNvbnN0CnsKCURCR19DSEtUSElTKCBTYnhCYXNlLCAwICk7CglyZXR1cm4gc2FsX0ZhbHNlOwp9CgpzYWxfQm9vbCBTYnhCYXNlOjpMb2FkUHJpdmF0ZURhdGEoIFN2U3RyZWFtJiwgc2FsX3VJbnQxNiApCnsKCURCR19DSEtUSElTKCBTYnhCYXNlLCAwICk7CglyZXR1cm4gc2FsX1RydWU7Cn0KCnNhbF9Cb29sIFNieEJhc2U6OlN0b3JlUHJpdmF0ZURhdGEoIFN2U3RyZWFtJiApIGNvbnN0CnsKCURCR19DSEtUSElTKCBTYnhCYXNlLCAwICk7CglyZXR1cm4gc2FsX1RydWU7Cn0KCnNhbF9Cb29sIFNieEJhc2U6OkxvYWRDb21wbGV0ZWQoKQp7CglEQkdfQ0hLVEhJUyggU2J4QmFzZSwgMCApOwoJcmV0dXJuIHNhbF9UcnVlOwp9CgpzYWxfQm9vbCBTYnhCYXNlOjpTdG9yZUNvbXBsZXRlZCgpCnsKCURCR19DSEtUSElTKCBTYnhCYXNlLCAwICk7CglyZXR1cm4gc2FsX1RydWU7Cn0KCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIFNieEZhY3RvcnkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KClNieEJhc2UqIFNieEZhY3Rvcnk6OkNyZWF0ZSggc2FsX3VJbnQxNiwgc2FsX3VJbnQzMiApCnsKCXJldHVybiBOVUxMOwp9CgpTYnhPYmplY3QqIFNieEZhY3Rvcnk6OkNyZWF0ZU9iamVjdCggY29uc3QgWHViU3RyaW5nJiApCnsKCXJldHVybiBOVUxMOwp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gU2J4SW5mbyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgpTYnhJbmZvOjp+U2J4SW5mbygpCnt9Cgp2b2lkIFNieEluZm86OkFkZFBhcmFtCgkJKCBjb25zdCBYdWJTdHJpbmcmIHJOYW1lLCBTYnhEYXRhVHlwZSBlVHlwZSwgc2FsX3VJbnQxNiBuRmxhZ3MgKQp7Cgljb25zdCBTYnhQYXJhbUluZm8qIHAgPSBuZXcgU2J4UGFyYW1JbmZvKCByTmFtZSwgZVR5cGUsIG5GbGFncyApOwoJYVBhcmFtcy5JbnNlcnQoIHAsIGFQYXJhbXMuQ291bnQoKSApOwp9Cgp2b2lkIFNieEluZm86OkFkZFBhcmFtKCBjb25zdCBTYnhQYXJhbUluZm8mIHIgKQp7Cgljb25zdCBTYnhQYXJhbUluZm8qIHAgPSBuZXcgU2J4UGFyYW1JbmZvCgkJKCByLmFOYW1lLCByLmVUeXBlLCByLm5GbGFncywgci5hVHlwZVJlZiApOwoJYVBhcmFtcy5JbnNlcnQoIHAsIGFQYXJhbXMuQ291bnQoKSApOwp9Cgpjb25zdCBTYnhQYXJhbUluZm8qIFNieEluZm86OkdldFBhcmFtKCBzYWxfdUludDE2IG4gKSBjb25zdAp7CglpZiggbiA8IDEgfHwgbiA+IGFQYXJhbXMuQ291bnQoKSApCgkJcmV0dXJuIE5VTEw7CgllbHNlCgkJcmV0dXJuIGFQYXJhbXMuR2V0T2JqZWN0KCBuLTEgKTsKfQoKc2FsX0Jvb2wgU2J4SW5mbzo6TG9hZERhdGEoIFN2U3RyZWFtJiByU3RybSwgc2FsX3VJbnQxNiBuVmVyICkKewoJYVBhcmFtcy5SZW1vdmUoIDAsIGFQYXJhbXMuQ291bnQoKSApOwoJc2FsX3VJbnQxNiBuUGFyYW07CglyU3RybS5SZWFkQnl0ZVN0cmluZyggYUNvbW1lbnQsIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKTsKCXJTdHJtLlJlYWRCeXRlU3RyaW5nKCBhSGVscEZpbGUsIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKTsKCXJTdHJtID4+IG5IZWxwSWQgPj4gblBhcmFtOwoJd2hpbGUoIG5QYXJhbS0tICkKCXsKCQlYdWJTdHJpbmcgYU5hbWU7CgkJc2FsX3VJbnQxNiBuVHlwZSwgbkZsYWdzOwoJCXNhbF91SW50MzIgblVzZXJEYXRhID0gMDsKCQlyU3RybS5SZWFkQnl0ZVN0cmluZyggYU5hbWUsIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKTsKCQlyU3RybSA+PiBuVHlwZSA+PiBuRmxhZ3M7CgkJaWYoIG5WZXIgPiAxICkKCQkJclN0cm0gPj4gblVzZXJEYXRhOwoJCUFkZFBhcmFtKCBhTmFtZSwgKFNieERhdGFUeXBlKSBuVHlwZSwgbkZsYWdzICk7CgkJU2J4UGFyYW1JbmZvKiBwID0gYVBhcmFtcy5HZXRPYmplY3QoIGFQYXJhbXMuQ291bnQoKSAtIDEgKTsKCQlwLT5uVXNlckRhdGEgPSBuVXNlckRhdGE7Cgl9CglyZXR1cm4gc2FsX1RydWU7Cn0KCnNhbF9Cb29sIFNieEluZm86OlN0b3JlRGF0YSggU3ZTdHJlYW0mIHJTdHJtICkgY29uc3QKewoJclN0cm0uV3JpdGVCeXRlU3RyaW5nKCBhQ29tbWVudCwgUlRMX1RFWFRFTkNPRElOR19BU0NJSV9VUyApOwoJclN0cm0uV3JpdGVCeXRlU3RyaW5nKCBhSGVscEZpbGUsIFJUTF9URVhURU5DT0RJTkdfQVNDSUlfVVMgKTsKCXJTdHJtIDw8IG5IZWxwSWQgPDwgYVBhcmFtcy5Db3VudCgpOwoJZm9yKCBzYWxfdUludDE2IGkgPSAwOyBpIDwgYVBhcmFtcy5Db3VudCgpOyBpKysgKQoJewoJCVNieFBhcmFtSW5mbyogcCA9IGFQYXJhbXMuR2V0T2JqZWN0KCBpICk7CgkJclN0cm0uV3JpdGVCeXRlU3RyaW5nKCBwLT5hTmFtZSwgUlRMX1RFWFRFTkNPRElOR19BU0NJSV9VUyApOwoJCXJTdHJtIDw8IChzYWxfdUludDE2KSBwLT5lVHlwZQoJCQkgIDw8IChzYWxfdUludDE2KSBwLT5uRmxhZ3MKCQkJICA8PCAoc2FsX3VJbnQzMikgcC0+blVzZXJEYXRhOwoJfQoJcmV0dXJuIHNhbF9UcnVlOwp9Cg==