Ly8gVFIyIDxib29sX3NldD4gLSotIEMrKyAtKi0KCi8vIENvcHlyaWdodCAoQykgMjAwOS0yMDEzIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLgovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgR05VIElTTyBDKysgTGlicmFyeS4gIFRoaXMgbGlicmFyeSBpcyBmcmVlCi8vIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyIHRoZQovLyB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZQovLyBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDMsIG9yIChhdCB5b3VyIG9wdGlvbikKLy8gYW55IGxhdGVyIHZlcnNpb24uCgovLyBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKLy8gYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKLy8gTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQovLyBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgoKLy8gVW5kZXIgU2VjdGlvbiA3IG9mIEdQTCB2ZXJzaW9uIDMsIHlvdSBhcmUgZ3JhbnRlZCBhZGRpdGlvbmFsCi8vIHBlcm1pc3Npb25zIGRlc2NyaWJlZCBpbiB0aGUgR0NDIFJ1bnRpbWUgTGlicmFyeSBFeGNlcHRpb24sIHZlcnNpb24KLy8gMy4xLCBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbi4KCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFuZAovLyBhIGNvcHkgb2YgdGhlIEdDQyBSdW50aW1lIExpYnJhcnkgRXhjZXB0aW9uIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOwovLyBzZWUgdGhlIGZpbGVzIENPUFlJTkczIGFuZCBDT1BZSU5HLlJVTlRJTUUgcmVzcGVjdGl2ZWx5LiAgSWYgbm90LCBzZWUKLy8gPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LgoKLyoqIEBmaWxlIHRyMi9ib29sX3NldAogKiAgVGhpcyBpcyBhIFRSMiBDKysgTGlicmFyeSBoZWFkZXIuCiAqLwoKI2lmbmRlZiBfR0xJQkNYWF9UUjJfQk9PTF9TRVQKI2RlZmluZSBfR0xJQkNYWF9UUjJfQk9PTF9TRVQgMQoKI3ByYWdtYSBHQ0Mgc3lzdGVtX2hlYWRlcgoKI2luY2x1ZGUgPHR5cGVpbmZvPgojaW5jbHVkZSA8aW9zdHJlYW0+CgpuYW1lc3BhY2Ugc3RkIF9HTElCQ1hYX1ZJU0lCSUxJVFkoZGVmYXVsdCkKewpuYW1lc3BhY2UgdHIyCnsKX0dMSUJDWFhfQkVHSU5fTkFNRVNQQUNFX1ZFUlNJT04KCiAgLyoqCiAgICogIGJvb2xfc2V0CiAgICoKICAgKiAgU2VlIE4yMTM2LCBCb29sX3NldDogbXVsdGktdmFsdWVkIGxvZ2ljCiAgICogIGJ5IEhlcnbpIEJy9m5uaW1hbm4sIEd1aWxsYXVtZSBNZWxxdWlvbmQsIFN5bHZhaW4gUGlvbi4KICAgKgogICAqICBUaGUgaW1wbGljaXQgY29udmVyc2lvbiB0byBib29sIGlzIHNsaXBwZXJ5ISAgSSBtYXkgdXNlIHRoZSBuZXcKICAgKiAgZXhwbGljaXQgY29udmVyc2lvbi4gIFRoaXMgaGFzIGJlZW4gc3BlY2lhbGl6ZWQgaW4gdGhlIGxhbmd1YWdlCiAgICogIHNvIHRoYXQgaW4gY29udGV4dHMgcmVxdWlyaW5nIGEgYm9vbCB0aGUgY29udmVyc2lvbiBoYXBwZW5zCiAgICogIGltcGxpY2l0bHkuICBUaHVzIG1vc3Qgb2JqZWN0aW9ucyBzaG91bGQgYmUgZWxpbWluYXRlZC4KICAgKi8KICBjbGFzcyBib29sX3NldAogIHsKICBwdWJsaWM6CgogICAgLy8vICBEZWZhdWx0IGNvbnN0cnVjdG9yLgogICAgY29uc3RleHByIGJvb2xfc2V0KCkgOiBfTV9iKF9TX2ZhbHNlKSB7IH0KCiAgICAvLy8gIENvbnN0cnVjdG9yIGZyb20gYm9vbC4KICAgIGNvbnN0ZXhwciBib29sX3NldChib29sIF9fdCkgOiBfTV9iKF9Cb29sX3NldF92YWwoX190KSkgeyB9CgogICAgLy8gSSdtIG5vdCBzdXJlIGFib3V0IHRoaXMuCiAgICBib29sIGNvbnRhaW5zKGJvb2xfc2V0IF9fYikgY29uc3QKICAgIHsgcmV0dXJuIHRoaXMtPmlzX3NpbmdsZXRvbigpICYmIHRoaXMtPmVxdWFscyhfX2IpOyB9CgogICAgLy8vICBSZXR1cm4gdHJ1ZSBpZiBzdGF0ZXMgYXJlIGVxdWFsLgogICAgYm9vbCBlcXVhbHMoYm9vbF9zZXQgX19iKSBjb25zdAogICAgeyByZXR1cm4gX19iLl9NX2IgPT0gX01fYjsgfQoKICAgIC8vLyAgUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBlbXB0eS4KICAgIGJvb2wgaXNfZW1wdHlzZXQoKSBjb25zdAogICAgeyByZXR1cm4gX01fYiA9PSBfU19lbXB0eTsgfQoKICAgIC8vLyAgUmV0dXJuIHRydWUgaWYgdGhpcyBpcyBpbmRldGVybWluYXRlLgogICAgYm9vbCBpc19pbmRldGVybWluYXRlKCkgY29uc3QKICAgIHsgcmV0dXJuIF9NX2IgPT0gX1NfaW5kZXQ7IH0KCiAgICAvLy8gIFJldHVybiB0cnVlIGlmIHRoaXMgaXMgZmFsc2Ugb3IgdHJ1ZSAobm9ybWFsIGJvb2xlYW4pLgogICAgYm9vbCBpc19zaW5nbGV0b24oKSBjb25zdAogICAgeyByZXR1cm4gX01fYiA9PSBfU19mYWxzZSB8fCBfTV9iID09IF9TX3RydWVfOyB9CgogICAgLy8vICBDb252ZXJzaW9uIHRvIGJvb2wuCiAgICAvL2V4cGxpY2l0CiAgICBvcGVyYXRvciBib29sKCkgY29uc3QKICAgIHsKICAgICAgaWYgKCEgaXNfc2luZ2xldG9uKCkpCgl0aHJvdyBzdGQ6OmJhZF9jYXN0KCk7CiAgICAgIHJldHVybiBfTV9iOwogICAgfQoKICAgIC8vLwogICAgc3RhdGljIGJvb2xfc2V0IGluZGV0ZXJtaW5hdGUoKQogICAgewogICAgICBib29sX3NldCBfX2I7CiAgICAgIF9fYi5fTV9iID0gX1NfaW5kZXQ7CiAgICAgIHJldHVybiBfX2I7CiAgICB9CgogICAgLy8vCiAgICBzdGF0aWMgYm9vbF9zZXQgZW1wdHlzZXQoKQogICAgewogICAgICBib29sX3NldCBfX2I7CiAgICAgIF9fYi5fTV9iID0gX1NfZW1wdHk7CiAgICAgIHJldHVybiBfX2I7CiAgICB9CgogICAgZnJpZW5kIGJvb2xfc2V0CiAgICBvcGVyYXRvciEoYm9vbF9zZXQgX19iKQogICAgeyByZXR1cm4gX19iLl9NX25vdCgpOyB9CgogICAgZnJpZW5kIGJvb2xfc2V0CiAgICBvcGVyYXRvcl4oYm9vbF9zZXQgX19zLCBib29sX3NldCBfX3QpCiAgICB7IHJldHVybiBfX3MuX01feG9yKF9fdCk7IH0KCiAgICBmcmllbmQgYm9vbF9zZXQKICAgIG9wZXJhdG9yfChib29sX3NldCBfX3MsIGJvb2xfc2V0IF9fdCkKICAgIHsgcmV0dXJuIF9fcy5fTV9vcihfX3QpOyB9CgogICAgZnJpZW5kIGJvb2xfc2V0CiAgICBvcGVyYXRvciYoYm9vbF9zZXQgX19zLCBib29sX3NldCBfX3QpCiAgICB7IHJldHVybiBfX3MuX01fYW5kKF9fdCk7IH0KCiAgICBmcmllbmQgYm9vbF9zZXQKICAgIG9wZXJhdG9yPT0oYm9vbF9zZXQgX19zLCBib29sX3NldCBfX3QpCiAgICB7IHJldHVybiBfX3MuX01fZXEoX190KTsgfQoKCiAgICAvLyAgVGhlc2Ugb3ZlcmxvYWRzIHJlcGxhY2UgdGhlIGZhY2V0IGFkZGl0aW9ucyBpbiB0aGUgcGFwZXIhCgogICAgdGVtcGxhdGU8dHlwZW5hbWUgQ2hhclQsIHR5cGVuYW1lIFRyYWl0cz4KICAgICAgZnJpZW5kIHN0ZDo6YmFzaWNfb3N0cmVhbTxDaGFyVCwgVHJhaXRzPiYKICAgICAgb3BlcmF0b3I8PChzdGQ6OmJhc2ljX29zdHJlYW08Q2hhclQsIFRyYWl0cz4mIF9fb3V0LCBib29sX3NldCBfX2IpCiAgICAgIHsKCWludCBfX2EgPSBfX2IuX01fYjsKCV9fb3V0IDw8IF9fYTsKICAgICAgfQoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIENoYXJULCB0eXBlbmFtZSBUcmFpdHM+CiAgICAgIGZyaWVuZCBzdGQ6OmJhc2ljX2lzdHJlYW08Q2hhclQsIFRyYWl0cz4mCiAgICAgIG9wZXJhdG9yPj4oc3RkOjpiYXNpY19pc3RyZWFtPENoYXJULCBUcmFpdHM+JiBfX2luLCBib29sX3NldCYgX19iKQogICAgICB7Cglsb25nIF9fYzsKCV9faW4gPj4gX19jOwoJaWYgKF9fYyA+PSBfU19mYWxzZSAmJiBfX2MgPCBfU19lbXB0eSkKCSAgX19iLl9NX2IgPSBzdGF0aWNfY2FzdDxfQm9vbF9zZXRfdmFsPihfX2MpOwogICAgICB9CgogIHByaXZhdGU6CgogICAgLy8vCiAgICBlbnVtIF9Cb29sX3NldF92YWw6IHVuc2lnbmVkIGNoYXIKICAgIHsKICAgICAgX1NfZmFsc2UgPSAwLAogICAgICBfU190cnVlXyA9IDEsCiAgICAgIF9TX2luZGV0ID0gMiwKICAgICAgX1NfZW1wdHkgPSAzCiAgICB9OwoKICAgIC8vLyAgQm9vbCBzZXQgc3RhdGUuCiAgICBfQm9vbF9zZXRfdmFsIF9NX2I7CgogICAgLy8vCiAgICBib29sX3NldChfQm9vbF9zZXRfdmFsIF9fYykgOiBfTV9iKF9fYykgeyB9CgogICAgLy8vCiAgICBib29sX3NldCBfTV9ub3QoKSBjb25zdAogICAgeyByZXR1cm4gX1Nfbm90W3RoaXMtPl9NX2JdOyB9CgogICAgLy8vCiAgICBib29sX3NldCBfTV94b3IoYm9vbF9zZXQgX19iKSBjb25zdAogICAgeyByZXR1cm4gX1NfeG9yW3RoaXMtPl9NX2JdW19fYi5fTV9iXTsgfQoKICAgIC8vLwogICAgYm9vbF9zZXQgX01fb3IoYm9vbF9zZXQgX19iKSBjb25zdAogICAgeyByZXR1cm4gX1Nfb3JbdGhpcy0+X01fYl1bX19iLl9NX2JdOyB9CgogICAgLy8vCiAgICBib29sX3NldCBfTV9hbmQoYm9vbF9zZXQgX19iKSBjb25zdAogICAgeyByZXR1cm4gX1NfYW5kW3RoaXMtPl9NX2JdW19fYi5fTV9iXTsgfQoKICAgIC8vLwogICAgYm9vbF9zZXQgX01fZXEoYm9vbF9zZXQgX19iKSBjb25zdAogICAgeyByZXR1cm4gX1NfZXFbdGhpcy0+X01fYl1bX19iLl9NX2JdOyB9CgogICAgLy8vCiAgICBzdGF0aWMgX0Jvb2xfc2V0X3ZhbCBfU19ub3RbNF07CgogICAgLy8vCiAgICBzdGF0aWMgX0Jvb2xfc2V0X3ZhbCBfU194b3JbNF1bNF07CgogICAgLy8vCiAgICBzdGF0aWMgX0Jvb2xfc2V0X3ZhbCBfU19vcls0XVs0XTsKCiAgICAvLy8KICAgIHN0YXRpYyBfQm9vbF9zZXRfdmFsIF9TX2FuZFs0XVs0XTsKCiAgICAvLy8KICAgIHN0YXRpYyBfQm9vbF9zZXRfdmFsIF9TX2VxWzRdWzRdOwogIH07CgogIC8vICAyMC4yLjMuMiBib29sX3NldCB2YWx1ZXMKCiAgaW5saW5lIGJvb2wKICBjb250YWlucyhib29sX3NldCBfX3MsIGJvb2xfc2V0IF9fdCkKICB7IHJldHVybiBfX3MuY29udGFpbnMoX190KTsgfQoKICBpbmxpbmUgYm9vbAogIGVxdWFscyhib29sX3NldCBfX3MsIGJvb2xfc2V0IF9fdCkKICB7IHJldHVybiBfX3MuZXF1YWxzKF9fdCk7IH0KCiAgaW5saW5lIGJvb2wKICBpc19lbXB0eXNldChib29sX3NldCBfX2IpCiAgeyByZXR1cm4gX19iLmlzX2VtcHR5c2V0KCk7IH0KCiAgaW5saW5lIGJvb2wKICBpc19pbmRldGVybWluYXRlKGJvb2xfc2V0IF9fYikKICB7IHJldHVybiBfX2IuaXNfaW5kZXRlcm1pbmF0ZSgpOyB9CgogIGlubGluZSBib29sCiAgaXNfc2luZ2xldG9uKGJvb2xfc2V0IF9fYikKICB7IHJldHVybiBfX2IuaXNfc2luZ2xldG9uKCk7IH0KCiAgaW5saW5lIGJvb2wKICBjZXJ0YWlubHkoYm9vbF9zZXQgX19iKQogIHsgcmV0dXJuICEgX19iLmNvbnRhaW5zKGZhbHNlKTsgfQoKICBpbmxpbmUgYm9vbAogIHBvc3NpYmx5KGJvb2xfc2V0IF9fYikKICB7IHJldHVybiBfX2IuY29udGFpbnModHJ1ZSk7IH0KCgogIC8vICAyMC4yLjMuMyBib29sX3NldCBzZXQgb3BlcmF0aW9ucwoKICBpbmxpbmUgYm9vbF9zZXQKICBzZXRfdW5pb24oYm9vbCBfX3MsIGJvb2xfc2V0IF9fdCkKICB7IHJldHVybiBib29sX3NldChfX3MpIHwgX190OyB9CgogIGlubGluZSBib29sX3NldAogIHNldF91bmlvbihib29sX3NldCBfX3MsIGJvb2wgX190KQogIHsgcmV0dXJuIF9fcyB8IGJvb2xfc2V0KF9fdCk7IH0KCiAgaW5saW5lIGJvb2xfc2V0CiAgc2V0X3VuaW9uKGJvb2xfc2V0IF9fcywgYm9vbF9zZXQgX190KQogIHsgcmV0dXJuIF9fcyB8IF9fdDsgfQoKICBpbmxpbmUgYm9vbF9zZXQKICBzZXRfaW50ZXJzZWN0aW9uKGJvb2wgX19zLCBib29sX3NldCBfX3QpCiAgeyByZXR1cm4gYm9vbF9zZXQoX19zKSAmIF9fdDsgfQoKICBpbmxpbmUgYm9vbF9zZXQKICBzZXRfaW50ZXJzZWN0aW9uKGJvb2xfc2V0IF9fcywgYm9vbCBfX3QpCiAgeyByZXR1cm4gX19zICYgYm9vbF9zZXQoX190KTsgfQoKICBpbmxpbmUgYm9vbF9zZXQKICBzZXRfaW50ZXJzZWN0aW9uKGJvb2xfc2V0IF9fcywgYm9vbF9zZXQgX190KQogIHsgcmV0dXJuIF9fcyAmIF9fdDsgfQoKICBpbmxpbmUgYm9vbF9zZXQKICBzZXRfY29tcGxlbWVudChib29sX3NldCBfX2IpCiAgeyByZXR1cm4gISBfX2I7IH0KCgogIC8vICAyMC4yLjMuNCBib29sX3NldCBsb2dpY2FsIG9wZXJhdG9ycwoKICBpbmxpbmUgYm9vbF9zZXQKICBvcGVyYXRvcl4oYm9vbCBfX3MsIGJvb2xfc2V0IF9fdCkKICB7IHJldHVybiBib29sX3NldChfX3MpIF4gX190OyB9CgogIGlubGluZSBib29sX3NldAogIG9wZXJhdG9yXihib29sX3NldCBfX3MsIGJvb2wgX190KQogIHsgcmV0dXJuIF9fcyBeIGJvb2xfc2V0KF9fdCk7IH0KCiAgaW5saW5lIGJvb2xfc2V0CiAgb3BlcmF0b3J8KGJvb2wgX19zLCBib29sX3NldCBfX3QpCiAgeyByZXR1cm4gYm9vbF9zZXQoX19zKSB8IF9fdDsgfQoKICBpbmxpbmUgYm9vbF9zZXQKICBvcGVyYXRvcnwoYm9vbF9zZXQgX19zLCBib29sIF9fdCkKICB7IHJldHVybiBfX3MgfCBib29sX3NldChfX3QpOyB9CgogIGlubGluZSBib29sX3NldAogIG9wZXJhdG9yJihib29sIF9fcywgYm9vbF9zZXQgX190KQogIHsgcmV0dXJuIGJvb2xfc2V0KF9fcykgJiBfX3Q7IH0KCiAgaW5saW5lIGJvb2xfc2V0CiAgb3BlcmF0b3ImKGJvb2xfc2V0IF9fcywgYm9vbCBfX3QpCiAgeyByZXR1cm4gX19zICYgYm9vbF9zZXQoX190KTsgfQoKCiAgLy8gIDIwLjIuMy41IGJvb2xfc2V0IHJlbGF0aW9uYWwgb3BlcmF0b3JzCgogIGlubGluZSBib29sX3NldAogIG9wZXJhdG9yPT0oYm9vbCBfX3MsIGJvb2xfc2V0IF9fdCkKICB7IHJldHVybiBib29sX3NldChfX3MpID09IF9fdDsgfQoKICBpbmxpbmUgYm9vbF9zZXQKICBvcGVyYXRvcj09KGJvb2xfc2V0IF9fcywgYm9vbCBfX3QpCiAgeyByZXR1cm4gX19zID09IGJvb2xfc2V0KF9fdCk7IH0KCiAgaW5saW5lIGJvb2xfc2V0CiAgb3BlcmF0b3IhPShib29sIF9fcywgYm9vbF9zZXQgX190KQogIHsgcmV0dXJuICEgKF9fcyA9PSBfX3QpOyB9CgogIGlubGluZSBib29sX3NldAogIG9wZXJhdG9yIT0oYm9vbF9zZXQgX19zLCBib29sIF9fdCkKICB7IHJldHVybiAhIChfX3MgPT0gX190KTsgfQoKICBpbmxpbmUgYm9vbF9zZXQKICBvcGVyYXRvciE9KGJvb2xfc2V0IF9fcywgYm9vbF9zZXQgX190KQogIHsgcmV0dXJuICEgKF9fcyA9PSBfX3QpOyB9CgpfR0xJQkNYWF9FTkRfTkFNRVNQQUNFX1ZFUlNJT04KfQp9CgojaW5jbHVkZSA8dHIyL2Jvb2xfc2V0LnRjYz4KCiNlbmRpZiAvLyBfR0xJQkNYWF9UUjJfQk9PTF9TRVQK