LyoKICogRGVidWdnZXIgc3RhY2sgaGFuZGxpbmcKICoKICogQ29weXJpZ2h0IDE5OTUgQWxleGFuZHJlIEp1bGxpYXJkCiAqIENvcHlyaWdodCAxOTk2IEVyaWMgWW91bmdkYWxlCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CgojaW5jbHVkZSAiZGVidWdnZXIuaCIKI2luY2x1ZGUgInN0YWNrZnJhbWUuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHdpbmVkYmcpOwoKc3RhdGljIGludCAgICAgICAgICAgICAgICAgICAgICBuZnJhbWU7CnN0YXRpYyBJTUFHRUhMUF9TVEFDS19GUkFNRSogICAgZnJhbWVzID0gTlVMTDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgc3RhY2tfaW5mbwogKgogKiBEdW1wIHRoZSB0b3Agb2YgdGhlIHN0YWNrCiAqLwp2b2lkIHN0YWNrX2luZm8odm9pZCkKewogICAgc3RydWN0IGRiZ19sdmFsdWUgICAgbHZhbHVlOwoKICAgIGx2YWx1ZS50eXBlaWQgPSBkYmdfaXR5cGVfbm9uZTsKICAgIGx2YWx1ZS5jb29raWUgPSBETFZfVEFSR0VUOwogICAgLyogRklYTUU6IHdlIGFzc3VtZSBzdGFjayBncm93cyB0aGUgc2FtZSB3YXkgYXMgb24gaTM4NiAqLwogICAgaWYgKCFtZW1vcnlfZ2V0X2N1cnJlbnRfc3RhY2soJmx2YWx1ZS5hZGRyKSkKICAgICAgICBkYmdfcHJpbnRmKCJCYWQgc2VnbWVudCAoJWQpXG4iLCBsdmFsdWUuYWRkci5TZWdtZW50KTsKCiAgICBkYmdfcHJpbnRmKCJTdGFjayBkdW1wOlxuIik7CiAgICBzd2l0Y2ggKGx2YWx1ZS5hZGRyLk1vZGUpCiAgICB7CiAgICBjYXNlIEFkZHJNb2RlRmxhdDogLyogMzItYml0IG1vZGUgKi8KICAgIGNhc2UgQWRkck1vZGUxNjMyOiAvKiAzMi1iaXQgbW9kZSAqLwogICAgICAgIG1lbW9yeV9leGFtaW5lKCZsdmFsdWUsIDI0LCAneCcpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBZGRyTW9kZVJlYWw6ICAvKiAxNi1iaXQgbW9kZSAqLwogICAgY2FzZSBBZGRyTW9kZTE2MTY6CiAgICAgICAgbWVtb3J5X2V4YW1pbmUoJmx2YWx1ZSwgMjQsICd3Jyk7CglicmVhazsKICAgIH0KICAgIGRiZ19wcmludGYoIlxuIik7Cn0KCmludCBzdGFja19zZXRfZnJhbWUoaW50IG5ld2ZyYW1lKQp7CiAgICBBRERSRVNTICAgICBhZGRyOwoKICAgIGRiZ19jdXJyX2ZyYW1lID0gbmV3ZnJhbWU7CiAgICBpZiAoZGJnX2N1cnJfZnJhbWUgPj0gbmZyYW1lKSBkYmdfY3Vycl9mcmFtZSA9IG5mcmFtZSAtIDE7CiAgICBpZiAoZGJnX2N1cnJfZnJhbWUgPCAwKSAgICAgICBkYmdfY3Vycl9mcmFtZSA9IDA7CgogICAgYWRkci5Nb2RlID0gQWRkck1vZGVGbGF0OwogICAgYWRkci5PZmZzZXQgPSBmcmFtZXNbZGJnX2N1cnJfZnJhbWVdLkluc3RydWN0aW9uT2Zmc2V0OwogICAgc291cmNlX2xpc3RfZnJvbV9hZGRyKCZhZGRyLCAwKTsKICAgIHJldHVybiBUUlVFOwp9CgppbnQgc3RhY2tfZ2V0X2ZyYW1lKFNZTUJPTF9JTkZPKiBzeW1ib2wsIElNQUdFSExQX1NUQUNLX0ZSQU1FKiBpaHNmKQp7CiAgICAvKgogICAgICogSWYgd2UgZG9uJ3QgaGF2ZSBhIHZhbGlkIGJhY2t0cmFjZSwgdGhlbiBqdXN0IHJldHVybi4KICAgICAqLwogICAgaWYgKGZyYW1lcyA9PSBOVUxMKSByZXR1cm4gRkFMU0U7CgogICAgLyoKICAgICAqIElmIHdlIGRvbid0IGtub3cgd2hhdCB0aGUgY3VycmVudCBmdW5jdGlvbiBpcywgdGhlbiB3ZSBhbHNvIGhhdmUKICAgICAqIG5vdGhpbmcgdG8gcmVwb3J0IGhlcmUuCiAgICAgKi8KICAgIFN5bUZyb21BZGRyKGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgZnJhbWVzW2RiZ19jdXJyX2ZyYW1lXS5JbnN0cnVjdGlvbk9mZnNldCwKICAgICAgICAgICAgICAgIE5VTEwsIHN5bWJvbCk7CiAgICBpZiAoaWhzZikgKmloc2YgPSBmcmFtZXNbZGJnX2N1cnJfZnJhbWVdOwoKICAgIHJldHVybiBUUlVFOwp9Cgp2b2lkIHN0YWNrX2JhY2t0cmFjZShEV09SRCB0aWQsIEJPT0wgbm9pc3kpCnsKICAgIFNUQUNLRlJBTUUgICAgICAgICAgICAgICAgICBzZjsKICAgIENPTlRFWFQgICAgICAgICAgICAgICAgICAgICBjdHg7CiAgICBzdHJ1Y3QgZGJnX3RocmVhZCogICAgICAgICAgdGhyZWFkOwogICAgdW5zaWduZWQgICAgICAgICAgICAgICAgICAgIG5mOwoKICAgIGlmICh0aWQgPT0gZGJnX2N1cnJfdGlkKQogICAgewogICAgICAgIGN0eCA9IGRiZ19jb250ZXh0OyAvKiBhcyBTdGFja1dhbGsgbWF5IG1vZGlmeSBpdC4uLiAqLwogICAgICAgIHRocmVhZCA9IGRiZ19jdXJyX3RocmVhZDsKICAgICAgICBpZiAoZnJhbWVzKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBmcmFtZXMpOwogICAgICAgIGZyYW1lcyA9IE5VTEw7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgIHRocmVhZCA9IGRiZ19nZXRfdGhyZWFkKGRiZ19jdXJyX3Byb2Nlc3MsIHRpZCk7CiAgICAgICAgIGlmICghdGhyZWFkKQogICAgICAgICB7CiAgICAgICAgICAgICAgZGJnX3ByaW50ZigiVW5rbm93biB0aHJlYWQgaWQgKDB4JTA4bHgpIGluIGN1cnJlbnQgcHJvY2Vzc1xuIiwgdGlkKTsKICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgIH0KICAgICAgICAgbWVtc2V0KCZjdHgsIDAsIHNpemVvZihjdHgpKTsKICAgICAgICAgY3R4LkNvbnRleHRGbGFncyA9IENPTlRFWFRfQ09OVFJPTCB8IENPTlRFWFRfU0VHTUVOVFM7CgogICAgICAgICBpZiAoU3VzcGVuZFRocmVhZCh0aHJlYWQtPmhhbmRsZSkgPT0gLTEgfHwgCiAgICAgICAgICAgICAhR2V0VGhyZWFkQ29udGV4dCh0aHJlYWQtPmhhbmRsZSwgJmN0eCkpCiAgICAgICAgIHsKICAgICAgICAgICAgIGRiZ19wcmludGYoIkNhbid0IGdldCBjb250ZXh0IGZvciB0aHJlYWQgMHglbHggaW4gY3VycmVudCBwcm9jZXNzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICB0aWQpOwogICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICB9CiAgICB9CgogICAgbmYgPSAwOwogICAgbWVtc2V0KCZzZiwgMCwgc2l6ZW9mKHNmKSk7CiAgICBtZW1vcnlfZ2V0X2N1cnJlbnRfZnJhbWUoJnNmLkFkZHJGcmFtZSk7CiAgICBtZW1vcnlfZ2V0X2N1cnJlbnRfcGMoJnNmLkFkZHJQQyk7CgogICAgaWYgKG5vaXN5KSBkYmdfcHJpbnRmKCJCYWNrdHJhY2U6XG4iKTsKICAgIHdoaWxlIChTdGFja1dhbGsoSU1BR0VfRklMRV9NQUNISU5FX0kzODYsIGRiZ19jdXJyX3Byb2Nlc3MtPmhhbmRsZSwgCiAgICAgICAgICAgICAgICAgICAgIHRocmVhZC0+aGFuZGxlLCAmc2YsICZjdHgsIE5VTEwsIFN5bUZ1bmN0aW9uVGFibGVBY2Nlc3MsCiAgICAgICAgICAgICAgICAgICAgIFN5bUdldE1vZHVsZUJhc2UsIE5VTEwpKQogICAgewogICAgICAgIGlmICh0aWQgPT0gZGJnX2N1cnJfdGlkKQogICAgICAgIHsKICAgICAgICAgICAgZnJhbWVzID0gZGJnX2hlYXBfcmVhbGxvYyhmcmFtZXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZiArIDEpICogc2l6ZW9mKElNQUdFSExQX1NUQUNLX0ZSQU1FKSk7CgogICAgICAgICAgICBmcmFtZXNbbmZdLkluc3RydWN0aW9uT2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZzZi5BZGRyUEMpOwogICAgICAgICAgICBmcmFtZXNbbmZdLkZyYW1lT2Zmc2V0ID0gKHVuc2lnbmVkIGxvbmcpbWVtb3J5X3RvX2xpbmVhcl9hZGRyKCZzZi5BZGRyRnJhbWUpOwogICAgICAgIH0KICAgICAgICBpZiAobm9pc3kpCiAgICAgICAgewogICAgICAgICAgICBkYmdfcHJpbnRmKCIlcyVkICIsIAogICAgICAgICAgICAgICAgICAgICAgICh0aWQgPT0gZGJnX2N1cnJfdGlkICYmIG5mID09IGRiZ19jdXJyX2ZyYW1lID8gIj0+IiA6ICIgICIpLAogICAgICAgICAgICAgICAgICAgICAgIG5mICsgMSk7CiAgICAgICAgICAgIHByaW50X2FkZHJfYW5kX2FyZ3MoJnNmLkFkZHJQQywgJnNmLkFkZHJGcmFtZSk7CiAgICAgICAgICAgIGRiZ19wcmludGYoIiAoIik7CiAgICAgICAgICAgIHByaW50X2JhcmVfYWRkcmVzcygmc2YuQWRkckZyYW1lKTsKICAgICAgICAgICAgZGJnX3ByaW50ZigiKVxuIik7CiAgICAgICAgfQogICAgICAgIG5mKys7CiAgICB9CgogICAgaWYgKHRpZCA9PSBkYmdfY3Vycl90aWQpCiAgICB7CiAgICAgICAgbmZyYW1lID0gbmY7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgUmVzdW1lVGhyZWFkKHRocmVhZC0+aGFuZGxlKTsKICAgIH0KfQo=