LyoKICogTkRBIEFORCBORUVELVRPLUtOT1cgUkVRVUlSRUQKICoKICogQ29weXJpZ2h0IKkgMjAxMy0yMDE4IFN5bmFwdGljcyBJbmNvcnBvcmF0ZWQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFRoaXMgZmlsZSBjb250YWlucyBpbmZvcm1hdGlvbiB0aGF0IGlzIHByb3ByaWV0YXJ5IHRvIFN5bmFwdGljcwogKiBJbmNvcnBvcmF0ZWQgKCJTeW5hcHRpY3MiKS4gVGhlIGhvbGRlciBvZiB0aGlzIGZpbGUgc2hhbGwgdHJlYXQgYWxsCiAqIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gYXMgY29uZmlkZW50aWFsLCBzaGFsbCB1c2UgdGhlCiAqIGluZm9ybWF0aW9uIG9ubHkgZm9yIGl0cyBpbnRlbmRlZCBwdXJwb3NlLCBhbmQgc2hhbGwgbm90IGR1cGxpY2F0ZSwKICogZGlzY2xvc2UsIG9yIGRpc3NlbWluYXRlIGFueSBvZiB0aGlzIGluZm9ybWF0aW9uIGluIGFueSBtYW5uZXIKICogdW5sZXNzIFN5bmFwdGljcyBoYXMgb3RoZXJ3aXNlIHByb3ZpZGVkIGV4cHJlc3MsIHdyaXR0ZW4KICogcGVybWlzc2lvbi4KICoKICogVXNlIG9mIHRoZSBtYXRlcmlhbHMgbWF5IHJlcXVpcmUgYSBsaWNlbnNlIG9mIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiBmcm9tIGEgdGhpcmQgcGFydHkgb3IgZnJvbSBTeW5hcHRpY3MuIFRoaXMgZmlsZSBjb252ZXlzIG5vIGV4cHJlc3MKICogb3IgaW1wbGllZCBsaWNlbnNlcyB0byBhbnkgaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBiZWxvbmdpbmcKICogdG8gU3luYXB0aWNzLgogKgogKiBJTkZPUk1BVElPTiBDT05UQUlORUQgSU4gVEhJUyBET0NVTUVOVCBJUyBQUk9WSURFRCAiQVMtSVMsIiBBTkQKICogU1lOQVBUSUNTIEVYUFJFU1NMWSBESVNDTEFJTVMgQUxMIEVYUFJFU1MgQU5EIElNUExJRUQgV0FSUkFOVElFUywKICogSU5DTFVESU5HIEFOWSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwgQU5EIEFOWSBXQVJSQU5USUVTIE9GIE5PTi1JTkZSSU5HRU1FTlQgT0YgQU5ZCiAqIElOVEVMTEVDVFVBTCBQUk9QRVJUWSBSSUdIVFMuIElOIE5PIEVWRU5UIFNIQUxMIFNZTkFQVElDUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBQVU5JVElWRSwgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFCiAqIE9GIFRIRSBJTkZPUk1BVElPTiBDT05UQUlORUQgSU4gVEhJUyBET0NVTUVOVCwgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIEJBU0VEIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwKICogTkVHTElHRU5DRSBPUiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFORCBFVkVOIElGIFNZTkFQVElDUyBXQVMKICogQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuIElGIEEgVFJJQlVOQUwgT0YKICogQ09NUEVURU5UIEpVUklTRElDVElPTiBET0VTIE5PVCBQRVJNSVQgVEhFIERJU0NMQUlNRVIgT0YgRElSRUNUCiAqIERBTUFHRVMgT1IgQU5ZIE9USEVSIERBTUFHRVMsIFNZTkFQVElDUycgVE9UQUwgQ1VNVUxBVElWRSBMSUFCSUxJVFkKICogVE8gQU5ZIFBBUlRZIFNIQUxMIE5PVCBFWENFRUQgT05FIEhVTkRSRUQgVS5TLiBET0xMQVJTLgogKi8KI2luY2x1ZGUgImkyY19kcml2ZXIuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAiaW8uaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJtZW1tYXAuaCIKI2luY2x1ZGUgImNoaXBfdm9sdGFnZV9pbmZvLmgiCiNpbmNsdWRlICJTeXNNZ3IuaCIKI2luY2x1ZGUgImFwYlJlZ0Jhc2UuaCIKI2luY2x1ZGUgImFwYl90aW1lci5oIgojaW5jbHVkZSAibGdwbF9wcmludGYuaCIKCiNpbmNsdWRlICJwdl9jb21wLmgiCgpleHRlcm4gdm9pZCBkZWxheV9tcyh1bnNpZ25lZCBpbnQgbXMpOwoKI2lmbmRlZiBWT1VUX0NQVV9JRAojZGVmaW5lIFZPVVRfQ1BVX0lEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMikKI2VuZGlmCgojaWZuZGVmIFZPVVRfQ09SRV9JRAojZGVmaW5lIFZPVVRfQ09SRV9JRCAgICAgICAgICAgICAgICAgICAgKDApCiNlbmRpZgoKI2lmbmRlZiBWT1VUX0NQVV9DSEFOTkVMCiNkZWZpbmUgVk9VVF9DUFVfQ0hBTk5FTCAgICAgICAgICAgICAgICAoMCkKI2VuZGlmCgojaWZuZGVmIFZPVVRfQ09SRV9DSEFOTkVMCiNkZWZpbmUgVk9VVF9DT1JFX0NIQU5ORUwgICAgICAgICAgICAgICAoMSkKI2VuZGlmCgovLyBhbGwgZGVmaW5lZCB1bmRlciB1dgojaWZuZGVmIE1JTklNQUxfVk9MX1NURVBfU1kyMDI3OAojZGVmaW5lIE1JTklNQUxfVk9MX1NURVBfU1kyMDI3OCAxMjUwMAojZW5kaWYKI2RlZmluZSBNSU5fVk9MVEFHRSA3NjI1MDAKI2RlZmluZSBNQVhfVk9MVEFHRSAxMDUwMDAwCgojZGVmaW5lIFNMQVZFX0FERFIgMHg2MQojZGVmaW5lIFJTVkQgICAgICAgICAgICAweEZGRkZGRkZGCiNkZWZpbmUgUkVHX1ZTRUwwICAgICAgIDB4MAoKZXh0ZXJuIHZvaWQgdWRlbGF5KHVuc2lnbmVkIGxvbmcgdXNlYyk7CmV4dGVybiBpbnQgaTJjX21hc3Rlcl9pbml0KGludCBpZCwgaW50IHNwZWVkLCBpbnQgYl8xMGJpdF9hZGRyKTsKZXh0ZXJuIGludCBpMmNfbWFzdGVyX3dyaXRlX2FuZF9yZWFkKGludCBpZCwgaW50IHRhcmdldF9hZGRyLCB1bnNpZ25lZCBjaGFyKiBzZW5kX2J1ZmYsIGludCBzZW5kX2xlbiwgdW5zaWduZWQgY2hhciogcmVjdl9idWZmLCBpbnQgcmVjdl9sZW4pOwoKc3RhdGljIGludCBwbWljX3ZvbHQyZGF0YShpbnQgdm9sdCwgaW50ICpwX2RhdGEpCnsKCXVuc2lnbmVkIGludCBkYXRhOwoKCWlmICgodm9sdCA+PSBNSU5fVk9MVEFHRSkgJiYgKHZvbHQgPD0gTUFYX1ZPTFRBR0UpKQoJCWRhdGEgPSAodm9sdCAtIE1JTl9WT0xUQUdFKSAvIDEyNTAwOwoJZWxzZQoJCWRhdGEgPSBSU1ZEOwoKCWlmIChkYXRhID09IFJTVkQpCgkJcmV0dXJuIC0xOwoJZWxzZSB7CgkJKnBfZGF0YSA9IGRhdGE7CgkJcmV0dXJuIDA7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcG1pY19kYXRhMnZvbHQoaW50ICpwX3ZvbHQsIGludCB2ZGF0YSkKewoJdW5zaWduZWQgaW50IHZvbDsKCWludCBkYXRhID0gdmRhdGE7CgoJZGF0YSA9IGRhdGEgJiAweDNGOwoJaWYgKGRhdGEgPD0gMHgzZiAmJiAweDE3IDw9IGRhdGEpCgkJdm9sID0gTUFYX1ZPTFRBR0U7CgllbHNlIGlmIChkYXRhIDwgMHgxNykKCQl2b2wgPSBNSU5fVk9MVEFHRSArIGRhdGEgKiAxMjUwMDsKCWVsc2UKCQl2b2wgPSBSU1ZEOwoKCWlmICh2b2wgPT0gUlNWRCkKCQlyZXR1cm4gLTE7CgllbHNlIHsKCQkqcF92b2x0ID0gdm9sOwoJCXJldHVybiAwOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHN5MjAyNzhfc2V0X3ZvbChpbnQgbWFzdGVyX2lkLCBpbnQgc2xhdmVBZGRyLCBpbnQgdm9sdCkKewoJaW50IHRhcmdldCA9IHZvbHQsIHZkYXRhID0gMDsKCXVuc2lnbmVkIGNoYXIgYnVmZlsyXTsKCXVuc2lnbmVkIGNoYXIgZGF0YV9yZWcwLCBkYXRhOwoJdW5zaWduZWQgaW50IGJ1bGtfcmVnMCA9IFJFR19WU0VMMDsKCWludCByZXQgPSAxOwoKCS8vIHJlYWQsIHN5MjAyNzggc2xhdmUgYWRkcmVzcyBpcyAweDYxCglpMmNfbWFzdGVyX2luaXQobWFzdGVyX2lkLCAxMDAsIDApOyAgLy9pbnQgaWQsIGludCBzcGVlZCwgaW50IGJfMTBiaXRfYWRkcgoJcmV0ID0gaTJjX21hc3Rlcl93cml0ZV9hbmRfcmVhZChtYXN0ZXJfaWQsIHNsYXZlQWRkciwgKHVuc2lnbmVkIGNoYXIqKSZidWxrX3JlZzAsIDEsICh1bnNpZ25lZCBjaGFyKikmZGF0YV9yZWcwLCAxKTsKCWlmIChyZXQpCgl7CgkJbGdwbF9wcmludGYoIlBNSUMgaTJjIHJlYWQgZmFpbCAhXG4iKTsKCQlyZXR1cm4gcmV0OwoJfQoJZGF0YV9yZWcwID0gZGF0YV9yZWcwICYgMHhjMDsKCglyZXQgPSBwbWljX3ZvbHQyZGF0YSh0YXJnZXQsICZ2ZGF0YSk7CglpZiAocmV0ID09IDApIHsKCQlkYXRhX3JlZzAgPSBkYXRhX3JlZzAgfCAodW5zaWduZWQgY2hhcil2ZGF0YTsKCQlsZ3BsX3ByaW50ZiggImRhdGFfcmVnMCA9IDB4JXggXG4iLCBkYXRhX3JlZzApOwoKCQlidWZmWzBdID0gKHVuc2lnbmVkIGNoYXIpUkVHX1ZTRUwwOwoJCWJ1ZmZbMV0gPSAodW5zaWduZWQgY2hhcilkYXRhX3JlZzA7CgkJLy9pMmNfbWFzdGVyX2luaXQobWFzdGVyX2lkLCAxMDAsIDApOwoJCS8vIHdyaXRlCgkJcmV0ID0gaTJjX21hc3Rlcl93cml0ZV9hbmRfcmVhZChtYXN0ZXJfaWQsIHNsYXZlQWRkciwgYnVmZiwgMiwgKHVuc2lnbmVkIGNoYXIqKTAsIDApOwoJCWlmIChyZXQpIHsKCQkJbGdwbF9wcmludGYoIlBNSUMgaTJjIHdyaXRlIGZhaWwgIVxuIik7CgkJCXJldHVybiByZXQ7CgkJfQoKCQkvL2kyY19tYXN0ZXJfaW5pdChtYXN0ZXJfaWQsIDEwMCwgMCk7ICAvL2ludCBpZCwgaW50IHNwZWVkLCBpbnQgYl8xMGJpdF9hZGRyCgkJLy8gcmVhZAoJCWJ1ZmZbMF0gPSAodW5zaWduZWQgY2hhcilSRUdfVlNFTDA7CgkJcmV0ID0gaTJjX21hc3Rlcl93cml0ZV9hbmRfcmVhZChtYXN0ZXJfaWQsIHNsYXZlQWRkciwgYnVmZiwgMSwgKHVuc2lnbmVkIGNoYXIgKikmZGF0YSwgMSk7CgkJaWYgKHJldCkgewoJCQlsZ3BsX3ByaW50ZigiUE1JQyBpMmMgcmVhZCBmYWlsICFcbiIpOwoJCQlyZXR1cm4gcmV0OwoJCX0KCgkJaWYgKGRhdGFfcmVnMCAhPSBkYXRhKSB7CgkJCWxncGxfcHJpbnRmKCAiUE1JQyBzeTIwMjc4OiByZWFkOjB4JTAyeCAhPSB3cml0ZToweCUwMnhcbiIsIGRhdGEsIGRhdGFfcmVnMCk7CgkJCXJldHVybiAtMTsKCQl9CgoJCWxncGxfcHJpbnRmKCAic2V0IHRvICVkIG12XG4iLCB0YXJnZXQpOwoJCWRlbGF5X21zKDEpOwoJfQoJZWxzZSB7CgkJbGdwbF9wcmludGYoICJJbGxlZ2FsIHRhcmdldCB2b2x0YWdlIGZvciBQTUlDIHN5MjAyNzggIVxuIik7CgkJcmV0dXJuIC0xOwoJfQoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBzeTIwMjc4X2dldF92b2woaW50IG1hc3Rlcl9pZCwgaW50IHNsYXZlQWRkcikKewoJaW50IHJlYWQgPSAweGZmOwoJaW50IHZvbHQ7Cgl1bnNpZ25lZCBpbnQgYnVsa19yZWcgPSBSRUdfVlNFTDA7CglpbnQgcmV0ID0gMTsKCglpMmNfbWFzdGVyX2luaXQobWFzdGVyX2lkLCAxMDAsIDApOyAgLy9pbnQgaWQsIGludCBzcGVlZCwgaW50IGJfMTBiaXRfYWRkcgoJLy8gcmVhZCwgc3kyMDI3OCBzbGF2ZSBhZGRyZXNzIGlzIDB4NjEKCXJldCA9IGkyY19tYXN0ZXJfd3JpdGVfYW5kX3JlYWQobWFzdGVyX2lkLCBzbGF2ZUFkZHIsICh1bnNpZ25lZCBjaGFyKikmYnVsa19yZWcsIDEsICh1bnNpZ25lZCBjaGFyKikmcmVhZCwgMSk7CgoJbGdwbF9wcmludGYoICJcblJFR19WU0VMMCA9IDB4JXggXG4iLCByZWFkKTsKCXJldCB8PSBwbWljX2RhdGEydm9sdCgmdm9sdCwgcmVhZCk7CglpZihyZXQpIHsKCQlsZ3BsX3ByaW50ZigiIGkyYyByZWFkIGZhaWxcbiIpOwoJCXJldHVybiAtMTsKCX0KCglyZXR1cm4gdm9sdDsKfQoKc3RhdGljIGludCBpMmNfZ2V0X2NwdV92b2x0KHZvaWQpCnsKCWludCB2b2x0ID0gc3kyMDI3OF9nZXRfdm9sKFZPVVRfQ1BVX0lELCBTTEFWRV9BRERSKTsKCglpZih2b2x0IDwgMCkKCQlyZXR1cm4gMDsKCglyZXR1cm4gdm9sdDsKfQoKc3RhdGljIGludCBpMmNfZ2V0X2NvcmVfdm9sdCh2b2lkKQp7CglpbnQgdm9sdCA9IHN5MjAyNzhfZ2V0X3ZvbChWT1VUX0NPUkVfSUQsIFNMQVZFX0FERFIpOwoKCWlmKHZvbHQgPCAwKQoJCXJldHVybiAwOwoKCXJldHVybiB2b2x0Owp9CgpzdGF0aWMgaW50IGkyY19zZXRfdm9sdChpbnQgbWFzdGVyX2lkLCBpbnQgZnJvbSwgaW50IHRvKQp7CglpbnQgdm9sdCA9IGZyb207CgoJd2hpbGUgKHZvbHQgIT0gdG8pewoJCWlmICh2b2x0ID4gdG8pewoJCQl2b2x0IC09IE1JTklNQUxfVk9MX1NURVBfU1kyMDI3ODsKCQkJaWYgKHZvbHQgPCB0bykKCQkJCXZvbHQgPSB0bzsKCQl9ZWxzZXsKCQkJdm9sdCArPSBNSU5JTUFMX1ZPTF9TVEVQX1NZMjAyNzg7CgkJCWlmICh2b2x0ID4gdG8pCgkJCQl2b2x0ID0gdG87CgkJfQoKCQlpZigwICE9IHN5MjAyNzhfc2V0X3ZvbChtYXN0ZXJfaWQsIFNMQVZFX0FERFIsIHZvbHQpKQoJCQlyZXR1cm4gMTsKCQkvL3VkZWxheSg1MCk7IAkvL0ZJWE1FOiAxbXMgZGVsYXllZAoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGkyY19zZXRfdmNwdV92b2x0KGludCBmcm9tLCBpbnQgdG8pCnsKCXJldHVybiBpMmNfc2V0X3ZvbHQoVk9VVF9DUFVfSUQsIGZyb20gLHRvKTsKfQoKc3RhdGljIGludCBpMmNfc2V0X3Zjb3JlX3ZvbHQoaW50IGZyb20sIGludCB0bykKewoJcmV0dXJuIGkyY19zZXRfdm9sdChWT1VUX0NPUkVfSUQsIGZyb20gLHRvKTsKfQoKY29uc3QgZHZmc19vcHNfdCBzeTIwMjc4X29wcyA9IHsKCS5nZXRfdmNwdV92b2x0ID0gaTJjX2dldF9jcHVfdm9sdCwKCS5nZXRfdmNvcmVfdm9sdCA9IGkyY19nZXRfY29yZV92b2x0LAoJLnNldF92Y3B1X3ZvbHQgPSBpMmNfc2V0X3ZjcHVfdm9sdCwKCS5zZXRfdmNvcmVfdm9sdCA9aTJjX3NldF92Y29yZV92b2x0Cn07Cg==