LyoKICogQUlYNCBtZW1vcnkgc3RhdGlzdGljcyBtb2R1bGUgZm9yIG5ldC1zbm1wCiAqCiAqIFZlcnNpb24gMC4xIC0gSW5pdGlhbCByZWxlYXNlIC0gMDUvSnVuLzIwMDMKICoKICogRGVyaXZlZCBmcm9tIG1lbW9yeV9zb2xhcmlzMi5jCiAqIFVzaW5nIGxpYnBlcmZzdGF0IGZvciBzdGF0aXN0aWNzIChSZWRib29rIFNHMjQtNjAzOSkKICoKICogUG9ydGVkIHRvIEFJWCBieSBNaWNoYWVsIEt1a2F0IDxtaWNoYWVsLmt1a2F0QHRvLmNvbT4KICogVGhpbmtpbmcgT2JqZWN0cyBTb2Z0d2FyZSBHbWJICiAqIExpbGllbnRoYWxzdHJh32UgMgogKiA3MDgyNSBTdHV0dGdhcnQtS29ybnRhbAogKiBodHRwOi8vd3d3LnRvLmNvbS8KICoKICogVGhhbmtzIGdvIHRvIEpvY2hlbiBLbWlldHNjaCBmb3IgdGhlIHNvbGFyaXMyIHN1cHBvcnQgYW5kCiAqIHRvIERhaW1sZXJDaHJ5c2xlciBBRyBTdHV0dGdhcnQgZm9yIG1ha2luZyB0aGlzIHBvcnQgcG9zc2libGUKICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+ICAgLyogbG9jYWwgU05NUCBjb25maWd1cmF0aW9uIGRldGFpbHMgKi8KI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZW5kaWYKI2lmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L2F1dG9fbmxpc3QuaD4KCiNpbmNsdWRlICJ1dGlsX2Z1bmNzL2hlYWRlcl9nZW5lcmljLmgiIC8qIHV0aWxpdHkgZnVuY3Rpb24gZGVjbGFyYXRpb25zICovCiNpbmNsdWRlICJtZW1vcnkuaCIgICAgICAgICAgICAgLyogdGhlIG1vZHVsZS1zcGVjaWZpYyBoZWFkZXIgKi8KI2luY2x1ZGUgIm1lbW9yeV9haXg0LmgiICAgIC8qIHRoZSBtb2R1bGUtc3BlY2lmaWMgaGVhZGVyICovCgojaW5jbHVkZSA8bGlicGVyZnN0YXQuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KCiNkZWZpbmUgTUFYU1RSU0laRQk4MAoKaW50ICAgICAgICAgICAgIG1pbmltdW1zd2FwOwpzdGF0aWMgY2hhciAgICAgZXJybXNnWzEwMjRdOwoKc3RhdGljIEZpbmRWYXJNZXRob2QgdmFyX2V4dGVuc2libGVfbWVtOwpzdGF0aWMgbG9uZyAgICAgZ2V0RnJlZVN3YXAodm9pZCk7CnN0YXRpYyBsb25nICAgICBnZXRUb3RhbEZyZWUodm9pZCk7CnN0YXRpYyBsb25nICAgICBnZXRUb3RhbFN3YXAodm9pZCk7CnN0YXRpYyBsb25nICAgICBnZXRGcmVlUmVhbCh2b2lkKTsKc3RhdGljIGxvbmcgICAgIGdldFRvdGFsUmVhbCh2b2lkKTsKCnZvaWQKaW5pdF9tZW1vcnlfYWl4NCh2b2lkKQp7CgogICAgc3RydWN0IHZhcmlhYmxlMiBleHRlbnNpYmxlX21lbV92YXJpYWJsZXNbXSA9IHsKICAgICAgICB7TUlCSU5ERVgsIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICAgICAgdmFyX2V4dGVuc2libGVfbWVtLCAxLCB7TUlCSU5ERVh9fSwKICAgICAgICB7RVJST1JOQU1FLCBBU05fT0NURVRfU1RSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICAgICAgdmFyX2V4dGVuc2libGVfbWVtLCAxLCB7RVJST1JOQU1FfX0sCiAgICAgICAge01FTVRPVEFMU1dBUCwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsIHtNRU1UT1RBTFNXQVB9fSwKICAgICAgICB7TUVNQVZBSUxTV0FQLCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9leHRlbnNpYmxlX21lbSwgMSwge01FTUFWQUlMU1dBUH19LAogICAgICAgIHtNRU1UT1RBTFJFQUwsIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICAgICAgdmFyX2V4dGVuc2libGVfbWVtLCAxLCB7TUVNVE9UQUxSRUFMfX0sCiAgICAgICAge01FTUFWQUlMUkVBTCwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsIHtNRU1BVkFJTFJFQUx9fSwKICAgICAgICB7TUVNVE9UQUxTV0FQVFhULCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9leHRlbnNpYmxlX21lbSwgMSwge01FTVRPVEFMU1dBUFRYVH19LAogICAgICAgIHtNRU1VU0VEU1dBUFRYVCwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsIHtNRU1VU0VEU1dBUFRYVH19LAogICAgICAgIHtNRU1UT1RBTFJFQUxUWFQsIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICAgICAgdmFyX2V4dGVuc2libGVfbWVtLCAxLCB7TUVNVE9UQUxSRUFMVFhUfX0sCiAgICAgICAge01FTVVTRURSRUFMVFhULCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9leHRlbnNpYmxlX21lbSwgMSwge01FTVVTRURSRUFMVFhUfX0sCiAgICAgICAge01FTVRPVEFMRlJFRSwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsIHtNRU1UT1RBTEZSRUV9fSwKICAgICAgICB7TUVNU1dBUE1JTklNVU0sIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICAgICAgdmFyX2V4dGVuc2libGVfbWVtLCAxLCB7TUVNU1dBUE1JTklNVU19fSwKICAgICAgICB7TUVNU0hBUkVELCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9leHRlbnNpYmxlX21lbSwgMSwge01FTVNIQVJFRH19LAogICAgICAgIHtNRU1CVUZGRVIsIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICAgICAgdmFyX2V4dGVuc2libGVfbWVtLCAxLCB7TUVNQlVGRkVSfX0sCiAgICAgICAge01FTUNBQ0hFRCwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZXh0ZW5zaWJsZV9tZW0sIDEsIHtNRU1DQUNIRUR9fSwKICAgICAgICB7RVJST1JGTEFHLCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9leHRlbnNpYmxlX21lbSwgMSwge0VSUk9SRkxBR319LAogICAgICAgIHtFUlJPUk1TRywgQVNOX09DVEVUX1NUUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9leHRlbnNpYmxlX21lbSwgMSwge0VSUk9STVNHfX0KICAgIH07CgogICAgLyoKICAgICAqIERlZmluZSB0aGUgT0lEIHBvaW50ZXIgdG8gdGhlIHRvcCBvZiB0aGUgbWliIHRyZWUgdGhhdCB3ZSdyZQogICAgICogcmVnaXN0ZXJpbmcgdW5kZXJuZWF0aCAKICAgICAqLwogICAgb2lkICAgICAgICAgICAgIG1lbV92YXJpYWJsZXNfb2lkW10gPSB7IE5FVFNOTVBfVUNEQVZJU19NSUIsIE5FVFNOTVBfTUVNTUlCTlVNIH07CgogICAgLyoKICAgICAqIHJlZ2lzdGVyIG91cnNlbHZlcyB3aXRoIHRoZSBhZ2VudCB0byBoYW5kbGUgb3VyIG1pYiB0cmVlIAogICAgICovCiAgICBSRUdJU1RFUl9NSUIoInVjZC1zbm1wL21lbW9yeSIsIGV4dGVuc2libGVfbWVtX3ZhcmlhYmxlcywgdmFyaWFibGUyLAogICAgICAgICAgICAgICAgIG1lbV92YXJpYWJsZXNfb2lkKTsKCiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigic3dhcCIsIG1lbW9yeV9wYXJzZV9jb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1vcnlfZnJlZV9jb25maWcsICJtaW4tYXZhaWwiKTsKCn0KCnN0YXRpYyB1X2NoYXIgICoKdmFyX2V4dGVuc2libGVfbWVtKHN0cnVjdCB2YXJpYWJsZSAqdnAsCiAgICAgICAgICAgICAgICAgICBvaWQgKiBuYW1lLAogICAgICAgICAgICAgICAgICAgc2l6ZV90ICogbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgaW50IGV4YWN0LAogICAgICAgICAgICAgICAgICAgc2l6ZV90ICogdmFyX2xlbiwgV3JpdGVNZXRob2QgKiogd3JpdGVfbWV0aG9kKQp7CiAgICBzdGF0aWMgbG9uZyAgICAgbG9uZ19yZXQ7CgogICAgLyoKICAgICAqIEluaXRpYWxpemUgdGhlIHJldHVybiB2YWx1ZSB0byAwIAogICAgICovCiAgICBsb25nX3JldCA9IDA7CgogICAgaWYgKGhlYWRlcl9nZW5lcmljKHZwLCBuYW1lLCBsZW5ndGgsIGV4YWN0LCB2YXJfbGVuLCB3cml0ZV9tZXRob2QpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgc3dpdGNoICh2cC0+bWFnaWMpIHsKICAgIGNhc2UgTUlCSU5ERVg6CiAgICAgICAgbG9uZ19yZXQgPSAwOwogICAgICAgIHJldHVybiAoKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CiAgICBjYXNlIEVSUk9STkFNRTogICAgICAgICAgICAvKiBkdW1teSBuYW1lICovCiAgICAgICAgc3ByaW50ZihlcnJtc2csICJzd2FwIik7CiAgICAgICAgKnZhcl9sZW4gPSBzdHJsZW4oZXJybXNnKTsKICAgICAgICByZXR1cm4gKCh1X2NoYXIgKikgKGVycm1zZykpOwogICAgY2FzZSBNRU1UT1RBTFNXQVA6CiAgICAgICAgbG9uZ19yZXQgPSBnZXRUb3RhbFN3YXAoKSAqIChnZXRwYWdlc2l6ZSgpIC8gMTAyNCk7CiAgICAgICAgcmV0dXJuICgodV9jaGFyICopICgmbG9uZ19yZXQpKTsKICAgIGNhc2UgTUVNQVZBSUxTV0FQOgogICAgICAgIGxvbmdfcmV0ID0gZ2V0RnJlZVN3YXAoKSAqIChnZXRwYWdlc2l6ZSgpIC8gMTAyNCk7CiAgICAgICAgcmV0dXJuICgodV9jaGFyICopICgmbG9uZ19yZXQpKTsKICAgIGNhc2UgTUVNU1dBUE1JTklNVU06CiAgICAgICAgbG9uZ19yZXQgPSBtaW5pbXVtc3dhcDsKICAgICAgICByZXR1cm4gKCh1X2NoYXIgKikgKCZsb25nX3JldCkpOwogICAgY2FzZSBNRU1UT1RBTFJFQUw6CgkJICBsb25nX3JldCA9IGdldFRvdGFsUmVhbCgpICogKGdldHBhZ2VzaXplKCkgLyAxMDI0KTsKCQkgIHJldHVybiAoKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CiAgICBjYXNlIE1FTUFWQUlMUkVBTDoKCQkgIGxvbmdfcmV0ID0gZ2V0RnJlZVJlYWwoKSAqIChnZXRwYWdlc2l6ZSgpIC8gMTAyNCk7CgkJICByZXR1cm4gKCh1X2NoYXIgKikgKCZsb25nX3JldCkpOwogICAgY2FzZSBNRU1UT1RBTEZSRUU6CiAgICAgICAgbG9uZ19yZXQgPSBnZXRUb3RhbEZyZWUoKSAqIChnZXRwYWdlc2l6ZSgpIC8gMTAyNCk7CiAgICAgICAgcmV0dXJuICgodV9jaGFyICopICgmbG9uZ19yZXQpKTsKCiAgICBjYXNlIEVSUk9SRkxBRzoKICAgICAgICBsb25nX3JldCA9IGdldFRvdGFsRnJlZSgpICogKGdldHBhZ2VzaXplKCkgLyAxMDI0KTsKICAgICAgICBsb25nX3JldCA9IChsb25nX3JldCA+IG1pbmltdW1zd2FwKSA/IDAgOiAxOwogICAgICAgIHJldHVybiAoKHVfY2hhciAqKSAoJmxvbmdfcmV0KSk7CgogICAgY2FzZSBFUlJPUk1TRzoKICAgICAgICBsb25nX3JldCA9IGdldFRvdGFsRnJlZSgpICogKGdldHBhZ2VzaXplKCkgLyAxMDI0KTsKICAgICAgICBpZiAoKGxvbmdfcmV0ID4gbWluaW11bXN3YXApID8gMCA6IDEpCiAgICAgICAgICAgIHNwcmludGYoZXJybXNnLCAiUnVubmluZyBvdXQgb2Ygc3dhcCBzcGFjZSAoJWxkKSIsIGxvbmdfcmV0KTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGVycm1zZ1swXSA9IDA7CiAgICAgICAgKnZhcl9sZW4gPSBzdHJsZW4oZXJybXNnKTsKICAgICAgICByZXR1cm4gKCh1X2NoYXIgKikgKGVycm1zZykpOwoKICAgIH0KCiAgICByZXR1cm4gKE5VTEwpOwp9CgojZGVmaW5lIERFRkFVTFRNSU5JTVVNU1dBUCAxNjAwMCAgICAgICAgLyoga2lsb2J5dGVzICovCgp2b2lkCm1lbW9yeV9wYXJzZV9jb25maWcoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIpCnsKICAgIG1pbmltdW1zd2FwID0gYXRvaShjcHRyKTsKfQoKdm9pZAptZW1vcnlfZnJlZV9jb25maWcodm9pZCkKewogICAgbWluaW11bXN3YXAgPSBERUZBVUxUTUlOSU1VTVNXQVA7Cn0KCnN0YXRpYyBsb25nCmdldFRvdGFsU3dhcCh2b2lkKQp7CiAgICBsb25nICAgICAgICAgICAgdG90YWxfbWVtID0gLTE7CgkgcGVyZnN0YXRfbWVtb3J5X3RvdGFsX3QgbWVtOwoKCSBpZihwZXJmc3RhdF9tZW1vcnlfdG90YWwoKHBlcmZzdGF0X2lkX3QgKilOVUxMLCAmbWVtLCBzaXplb2YocGVyZnN0YXRfbWVtb3J5X3RvdGFsX3QpLCAxKSA+PSAxKSB7CgkJIHRvdGFsX21lbSA9IG1lbS5wZ3NwX3RvdGFsOwoJIH0KCiAgICByZXR1cm4gKHRvdGFsX21lbSk7Cn0KCnN0YXRpYyBsb25nCmdldEZyZWVTd2FwKHZvaWQpCnsKICAgIGxvbmcgICAgICAgICAgICBmcmVlX21lbSA9IC0xOwoJIHBlcmZzdGF0X21lbW9yeV90b3RhbF90IG1lbTsKCgkgaWYocGVyZnN0YXRfbWVtb3J5X3RvdGFsKChwZXJmc3RhdF9pZF90ICopTlVMTCwgJm1lbSwgc2l6ZW9mKHBlcmZzdGF0X21lbW9yeV90b3RhbF90KSwgMSkgPj0gMSkgewoJCSBmcmVlX21lbSA9IG1lbS5wZ3NwX2ZyZWU7CgkgfQoKICAgIHJldHVybiAoZnJlZV9tZW0pOwp9CgpzdGF0aWMgbG9uZwpnZXRUb3RhbEZyZWUodm9pZCkKewogICAgbG9uZyAgICAgICAgICAgIGZyZWVfbWVtID0gLTE7CgkgcGVyZnN0YXRfbWVtb3J5X3RvdGFsX3QgbWVtOwoKCSBpZihwZXJmc3RhdF9tZW1vcnlfdG90YWwoKHBlcmZzdGF0X2lkX3QgKilOVUxMLCAmbWVtLCBzaXplb2YocGVyZnN0YXRfbWVtb3J5X3RvdGFsX3QpLCAxKSA+PSAxKSB7CgkJIGZyZWVfbWVtID0gbWVtLnBnc3BfZnJlZSArIG1lbS5yZWFsX2ZyZWU7CgkgfQoKICAgIHJldHVybiAoZnJlZV9tZW0pOwp9CgpzdGF0aWMgbG9uZwpnZXRUb3RhbFJlYWwodm9pZCkKewogICAgbG9uZyAgICAgICAgICAgIHRvdGFsX21lbSA9IC0xOwoJIHBlcmZzdGF0X21lbW9yeV90b3RhbF90IG1lbTsKCgkgaWYocGVyZnN0YXRfbWVtb3J5X3RvdGFsKChwZXJmc3RhdF9pZF90ICopTlVMTCwgJm1lbSwgc2l6ZW9mKHBlcmZzdGF0X21lbW9yeV90b3RhbF90KSwgMSkgPj0gMSkgewoJCSB0b3RhbF9tZW0gPSBtZW0ucmVhbF90b3RhbDsKCSB9CgogICAgcmV0dXJuICh0b3RhbF9tZW0pOwp9CgpzdGF0aWMgbG9uZwpnZXRGcmVlUmVhbCh2b2lkKQp7CiAgICBsb25nICAgICAgICAgICAgZnJlZV9tZW0gPSAtMTsKCSBwZXJmc3RhdF9tZW1vcnlfdG90YWxfdCBtZW07CgoJIGlmKHBlcmZzdGF0X21lbW9yeV90b3RhbCgocGVyZnN0YXRfaWRfdCAqKU5VTEwsICZtZW0sIHNpemVvZihwZXJmc3RhdF9tZW1vcnlfdG90YWxfdCksIDEpID49IDEpIHsKCQkgZnJlZV9tZW0gPSBtZW0ucmVhbF9mcmVlOwoJIH0KCiAgICByZXR1cm4gKGZyZWVfbWVtKTsKfQo=