LyoKICogKEMpIENvcHlyaWdodCAyMDA4LTIwMTEKICogR3JhZW1lIFJ1c3MsIDxncmFlbWUucnVzc0BnbWFpbC5jb20+CiAqCiAqIChDKSBDb3B5cmlnaHQgMjAwMgogKiBEYW5pZWwgRW5nc3Ry9m0sIE9taWNyb24gQ2V0aSBBQiwgPGRhbmllbEBvbWljcm9uLnNlPgogKgogKiAoQykgQ29weXJpZ2h0IDIwMDIKICogU3lzZ28gUmVhbC1UaW1lIFNvbHV0aW9ucywgR21iSCA8d3d3LmVsaW5vcy5jb20+CiAqIE1hcml1cyBHcm9lZ2VyIDxtZ3JvZWdlckBzeXNnby5kZT4KICoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIFN5c2dvIFJlYWwtVGltZSBTb2x1dGlvbnMsIEdtYkggPHd3dy5lbGlub3MuY29tPgogKiBBbGV4IFp1ZXBrZSA8YXp1QHN5c2dvLmRlPgogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGNvbW1hbmQuaD4KI2luY2x1ZGUgPGFzbS9wcm9jZXNzb3IuaD4KI2luY2x1ZGUgPGFzbS9wcm9jZXNzb3ItZmxhZ3MuaD4KI2luY2x1ZGUgPGFzbS9pbnRlcnJ1cHQuaD4KCi8qCiAqIENvbnN0cnVjdG9yIGZvciBhIGNvbnZlbnRpb25hbCBzZWdtZW50IEdEVCAob3IgTERUKSBlbnRyeQogKiBUaGlzIGlzIGEgbWFjcm8gc28gaXQgY2FuIGJlIHVzZWQgaW4gaW5pdGlhbGlzZXJzCiAqLwojZGVmaW5lIEdEVF9FTlRSWShmbGFncywgYmFzZSwgbGltaXQpCQkJXAoJKCgoKGJhc2UpICAmIDB4ZmYwMDAwMDBVTEwpIDw8ICg1Ni0yNCkpIHwJXAoJICgoKGZsYWdzKSAmIDB4MDAwMGYwZmZVTEwpIDw8IDQwKSB8CQlcCgkgKCgobGltaXQpICYgMHgwMDBmMDAwMFVMTCkgPDwgKDQ4LTE2KSkgfAlcCgkgKCgoYmFzZSkgICYgMHgwMGZmZmZmZlVMTCkgPDwgMTYpIHwJCVwKCSAoKChsaW1pdCkgJiAweDAwMDBmZmZmVUxMKSkpCgpzdHJ1Y3QgZ2R0X3B0ciB7Cgl1MTYgbGVuOwoJdTMyIHB0cjsKfSBfX2F0dHJpYnV0ZV9fKChwYWNrZWQpKTsKCnN0YXRpYyB2b2lkIHJlbG9hZF9nZHQodm9pZCkKewoJLyoKCSAqIFRoZXJlIGFyZSBtYWNoaW5lcyB3aGljaCBhcmUga25vd24gdG8gbm90IGJvb3Qgd2l0aCB0aGUgR0RUCgkgKiBiZWluZyA4LWJ5dGUgdW5hbGlnbmVkLiAgSW50ZWwgcmVjb21tZW5kcyAxNiBieXRlIGFsaWdubWVudAoJICovCglzdGF0aWMgY29uc3QgdTY0IGJvb3RfZ2R0W10gX19hdHRyaWJ1dGVfXygoYWxpZ25lZCgxNikpKSA9IHsKCQkvKiBDUzogY29kZSwgcmVhZC9leGVjdXRlLCA0IEdCLCBiYXNlIDAgKi8KCQlbR0RUX0VOVFJZXzMyQklUX0NTXSA9IEdEVF9FTlRSWSgweGMwOWIsIDAsIDB4ZmZmZmYpLAoJCS8qIERTOiBkYXRhLCByZWFkL3dyaXRlLCA0IEdCLCBiYXNlIDAgKi8KCQlbR0RUX0VOVFJZXzMyQklUX0RTXSA9IEdEVF9FTlRSWSgweGMwOTMsIDAsIDB4ZmZmZmYpLAoJCS8qIDE2LWJpdCBDUzogY29kZSwgcmVhZC9leGVjdXRlLCA2NCBrQiwgYmFzZSAwICovCgkJW0dEVF9FTlRSWV8xNkJJVF9DU10gPSBHRFRfRU5UUlkoMHgxMDliLCAwLCAweDBmZmZmKSwKCQkvKiAxNi1iaXQgRFM6IGRhdGEsIHJlYWQvd3JpdGUsIDY0IGtCLCBiYXNlIDAgKi8KCQlbR0RUX0VOVFJZXzE2QklUX0RTXSA9IEdEVF9FTlRSWSgweDEwOTMsIDAsIDB4MGZmZmYpLAoJfTsKCXN0YXRpYyBzdHJ1Y3QgZ2R0X3B0ciBnZHQ7CgoJZ2R0LmxlbiA9IHNpemVvZihib290X2dkdCktMTsKCWdkdC5wdHIgPSAodTMyKSZib290X2dkdDsKCglhc20gdm9sYXRpbGUoImxnZHRsICUwXG4iIFwKCQkgICAgICJtb3ZsICQoKDIrMSkqOCksICUlZWN4XG4iIFwKCQkgICAgICJtb3ZsICUlZWN4LCAlJWRzXG4iIFwKCQkgICAgICJtb3ZsICUlZWN4LCAlJWVzXG4iIFwKCQkgICAgICJtb3ZsICUlZWN4LCAlJWZzXG4iIFwKCQkgICAgICJtb3ZsICUlZWN4LCAlJWdzXG4iIFwKCQkgICAgICJtb3ZsICUlZWN4LCAlJXNzIiBcCgkJICAgICA6IDogIm0iIChnZHQpIDogImVjeCIpOwp9CgppbnQgeDg2X2NwdV9pbml0X2Yodm9pZCkKewoJY29uc3QgdTMyIGVtX3JzdCA9IH5YODZfQ1IwX0VNOwoJY29uc3QgdTMyIG1wX25lX3NldCA9IFg4Nl9DUjBfTVAgfCBYODZfQ1IwX05FOwoKCS8qIGluaXRpYWxpemUgRlBVLCByZXNldCBFTSwgc2V0IE1QIGFuZCBORSAqLwoJYXNtICgiZm5pbml0XG4iIFwKCSAgICAgIm1vdmwgJSVjcjAsICUlZWF4XG4iIFwKCSAgICAgImFuZGwgJTAsICUlZWF4XG4iIFwKCSAgICAgIm9ybCAgJTEsICUlZWF4XG4iIFwKCSAgICAgIm1vdmwgJSVlYXgsICUlY3IwXG4iIFwKCSAgICAgOiA6ICJpIiAoZW1fcnN0KSwgImkiIChtcF9uZV9zZXQpIDogImVheCIpOwoKCXJldHVybiAwOwp9CmludCBjcHVfaW5pdF9mKHZvaWQpIF9fYXR0cmlidXRlX18oKHdlYWssIGFsaWFzKCJ4ODZfY3B1X2luaXRfZiIpKSk7CgppbnQgeDg2X2NwdV9pbml0X3Iodm9pZCkKewoJY29uc3QgdTMyIG53X2NkX3JzdCA9IH4oWDg2X0NSMF9OVyB8IFg4Nl9DUjBfQ0QpOwoKCS8qIHR1cm4gb24gdGhlIGNhY2hlIGFuZCBkaXNhYmxlIHdyaXRlIHRocm91Z2ggKi8KCWFzbSgibW92bAklJWNyMCwgJSVlYXhcbiIKCSAgICAiYW5kbAklMCwgJSVlYXhcbiIKCSAgICAibW92bAklJWVheCwgJSVjcjBcbiIKCSAgICAid2JpbnZkXG4iIDogOiAiaSIgKG53X2NkX3JzdCkgOiAiZWF4Iik7CgoJcmVsb2FkX2dkdCgpOwoKCS8qIEluaXRpYWxpemUgY29yZSBpbnRlcnJ1cHQgYW5kIGV4Y2VwdGlvbiBmdW5jdGlvbmFsaXR5IG9mIENQVSAqLwoJY3B1X2luaXRfaW50ZXJydXB0cyAoKTsKCXJldHVybiAwOwp9CmludCBjcHVfaW5pdF9yKHZvaWQpIF9fYXR0cmlidXRlX18oKHdlYWssIGFsaWFzKCJ4ODZfY3B1X2luaXRfciIpKSk7CgppbnQgZG9fcmVzZXQoY21kX3RibF90ICpjbWR0cCwgaW50IGZsYWcsIGludCBhcmdjLCBjaGFyICogY29uc3QgYXJndltdKQp7CglwcmludGYgKCJyZXNldHRpbmcgLi4uXG4iKTsKCgkvKiB3YWl0IDUwIG1zICovCgl1ZGVsYXkoNTAwMDApOwoJZGlzYWJsZV9pbnRlcnJ1cHRzKCk7CglyZXNldF9jcHUoMCk7CgoJLypOT1RSRUFDSEVEKi8KCXJldHVybiAwOwp9Cgp2b2lkICBmbHVzaF9jYWNoZSAodW5zaWduZWQgbG9uZyBkdW1teTEsIHVuc2lnbmVkIGxvbmcgZHVtbXkyKQp7Cglhc20oIndiaW52ZFxuIik7Cn0KCnZvaWQgX19hdHRyaWJ1dGVfXyAoKHJlZ3Bhcm0oMCkpKSBnZW5lcmF0ZV9ncGYodm9pZCk7CgovKiBzZWdtZW50IDB4NzAgaXMgYW4gYXJiaXRyYXJ5IHNlZ21lbnQgd2hpY2ggZG9lcyBub3QgZXhpc3QgKi8KYXNtKCIuZ2xvYmwgZ2VuZXJhdGVfZ3BmXG4iCiAgICAiLmhpZGRlbiBnZW5lcmF0ZV9ncGZcbiIKICAgICIudHlwZSBnZW5lcmF0ZV9ncGYsIEBmdW5jdGlvblxuIgogICAgImdlbmVyYXRlX2dwZjpcbiIKICAgICJsam1wICAgJDB4NzAsICQweDQ3MTE0NzExXG4iKTsKCnZvaWQgX19yZXNldF9jcHUodWxvbmcgYWRkcikKewoJcHJpbnRmKCJSZXNldHRpbmcgdXNpbmcgeDg2IFRyaXBsZSBGYXVsdFxuIik7CglzZXRfdmVjdG9yKDEzLCBnZW5lcmF0ZV9ncGYpOyAgLyogZ2VuZXJhbCBwcm90ZWN0aW9uIGZhdWx0IGhhbmRsZXIgKi8KCXNldF92ZWN0b3IoOCwgZ2VuZXJhdGVfZ3BmKTsgICAvKiBkb3VibGUgZmF1bHQgaGFuZGxlciAqLwoJZ2VuZXJhdGVfZ3BmKCk7ICAgICAgICAgICAgICAgIC8qIHN0YXJ0IHRoZSBzaG93ICovCn0Kdm9pZCByZXNldF9jcHUodWxvbmcgYWRkcikgX19hdHRyaWJ1dGVfXygod2VhaywgYWxpYXMoIl9fcmVzZXRfY3B1IikpKTsK