LyoKICogQ29weXJpZ2h0IChDKSAyMDEwIE5YUCBTZW1pY29uZHVjdG9ycwogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICovCgovKiEKICogXGZpbGUgIHBoRnJpTmZjX01hcFRvb2xzLmMKICogXGJyaWVmIE5GQyBOZGVmIEludGVybmFsIE1hcHBpbmcgRmlsZS4KICoKICogUHJvamVjdDogTkZDLUZSSQogKgogKiAkRGF0ZTogRnJpIE9jdCAxNSAxMzo1MDo1NCAyMDEwICQKICogJEF1dGhvcjogaW5nMDIyNjAgJAogKiAkUmV2aXNpb246IDEuNiAkCiAqICRBbGlhc2VzOiAgJAogKgogKi8KCiNpbmNsdWRlIDxwaEZyaU5mY19OZGVmTWFwLmg+CiNpbmNsdWRlIDxwaEZyaU5mY19NYXBUb29scy5oPgoKI2lmbmRlZiBQSF9GUklORkNfTUFQX01JRkFSRVVMX0RJU0FCTEVECiNpbmNsdWRlIDxwaEZyaU5mY19NaWZhcmVVTE1hcC5oPgojZW5kaWYgIC8qIFBIX0ZSSU5GQ19NQVBfTUlGQVJFVUxfRElTQUJMRUQqLwoKI2lmbmRlZiBQSF9GUklORkNfTUFQX01JRkFSRVNURF9ESVNBQkxFRAojaW5jbHVkZSA8cGhGcmlOZmNfTWlmYXJlU3RkTWFwLmg+CiNlbmRpZiAgLyogUEhfRlJJTkZDX01BUF9NSUZBUkVTVERfRElTQUJMRUQgKi8KCiNpZm5kZWYgUEhfRlJJTkZDX01BUF9ERVNGSVJFX0RJU0FCTEVECiNpbmNsdWRlIDxwaEZyaU5mY19EZXNmaXJlTWFwLmg+CiNlbmRpZiAgLyogUEhfRlJJTkZDX01BUF9ERVNGSVJFX0RJU0FCTEVEICovCgojaWZuZGVmIFBIX0ZSSU5GQ19NQVBfRkVMSUNBX0RJU0FCTEVECiNpbmNsdWRlIDxwaEZyaU5mY19GZWxpY2FNYXAuaD4KI2VuZGlmICAvKiBQSF9GUklORkNfTUFQX0ZFTElDQV9ESVNBQkxFRCAqLwoKI2luY2x1ZGUgPHBoRnJpTmZjX092ckhhbC5oPgoKLyohIFxpbmdyb3VwIGdycF9maWxlX2F0dHJpYnV0ZXMKICogIFxuYW1lIE5ERUYgTWFwcGluZwogKgogKiBGaWxlOiBccmVmIHBoRnJpTmZjX01hcFRvb2xzLmMKICogICAgICAgVGhpcyBmaWxlIGhhcyBmdW5jdGlvbnMgd2hpY2ggYXJlIHVzZWQgY29tbW9uIGFjcm9zcyBhbGwgdGhlCiAqICAgICAgIHR5cDEvdHlwZTIvdHlwZTMvdHlwZTQgdGFncy4KICoKICovCi8qQHsqLwojZGVmaW5lIFBIRlJJTkZDTkRFRk1BUF9GSUxFUkVWSVNJT04gIiRSZXZpc2lvbjogMS42ICQiCiNkZWZpbmUgUEhGUklORkNOREVGTUFQX0ZJTEVBTElBU0VTICAiJEFsaWFzZXM6ICAkIgovKkB9Ki8KCk5GQ1NUQVRVUyBwaEZyaU5mY19NYXBUb29sX1NldENhcmRTdGF0ZShwaEZyaU5mY19OZGVmTWFwX3QgICpOZGVmTWFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDMyX3QgICAgICAgICAgICBMZW5ndGgpCnsKICAgIE5GQ1NUQVRVUyAgIFJlc3VsdCA9IE5GQ1NUQVRVU19TVUNDRVNTOwogICAgaWYoTGVuZ3RoID09IFBIX0ZSSU5GQ19OREVGTUFQX01GVUxfVkFMMCkKICAgIHsKICAgICAgICAvKiBBcyB0aGUgTkRFRiBMRU4gLyBUTFYgTGVuIGlzIFplcm8sIGlycmVzcGVjdGl2ZSBvZiBhbnkgc3RhdGUgdGhlIGNhcmQKICAgICAgICAgICBzaGFsbCBiZSBzZXQgdG8gSU5JVElBTElaRUQgU1RBVEUqLwogICAgICAgIE5kZWZNYXAtPkNhcmRTdGF0ZSA9KHVpbnQ4X3QpICgoKE5kZWZNYXAtPkNhcmRTdGF0ZSA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBIX05ERUZNQVBfQ0FSRF9TVEFURV9SRUFEX09OTFkpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE5kZWZNYXAtPkNhcmRTdGF0ZSA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBIX05ERUZNQVBfQ0FSRF9TVEFURV9JTlZBTElEKSk/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEhfTkRFRk1BUF9DQVJEX1NUQVRFX0lOVkFMSUQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEhfTkRFRk1BUF9DQVJEX1NUQVRFX0lOSVRJQUxJWkVEKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzd2l0Y2goTmRlZk1hcC0+Q2FyZFN0YXRlKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBQSF9OREVGTUFQX0NBUkRfU1RBVEVfSU5JVElBTElaRUQ6CiAgICAgICAgICAgICAgICBOZGVmTWFwLT5DYXJkU3RhdGUgPSh1aW50OF90KSAoKE5kZWZNYXAtPkNhcmRTdGF0ZSA9PQogICAgICAgICAgICAgICAgICAgIFBIX05ERUZNQVBfQ0FSRF9TVEFURV9JTlZBTElEKT8KICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5DYXJkU3RhdGU6CiAgICAgICAgICAgICAgICAgICAgUEhfTkRFRk1BUF9DQVJEX1NUQVRFX1JFQURfV1JJVEUpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgUEhfTkRFRk1BUF9DQVJEX1NUQVRFX1JFQURfT05MWToKICAgICAgICAgICAgICAgIE5kZWZNYXAtPkNhcmRTdGF0ZSA9ICh1aW50OF90KSgoTmRlZk1hcC0+Q2FyZFN0YXRlID09CiAgICAgICAgICAgICAgICAgICAgUEhfTkRFRk1BUF9DQVJEX1NUQVRFX0lOVkFMSUQpPwogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkNhcmRTdGF0ZToKICAgICAgICAgICAgICAgICAgICBQSF9OREVGTUFQX0NBUkRfU1RBVEVfUkVBRF9PTkxZKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFBIX05ERUZNQVBfQ0FSRF9TVEFURV9SRUFEX1dSSVRFOgogICAgICAgICAgICAgICAgTmRlZk1hcC0+Q2FyZFN0YXRlID0gKHVpbnQ4X3QpKChOZGVmTWFwLT5DYXJkU3RhdGUgPT0KICAgICAgICAgICAgICAgICAgICBQSF9OREVGTUFQX0NBUkRfU1RBVEVfSU5WQUxJRCk/CiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+Q2FyZFN0YXRlOgogICAgICAgICAgICAgICAgICAgIFBIX05ERUZNQVBfQ0FSRF9TVEFURV9SRUFEX1dSSVRFKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgTmRlZk1hcC0+Q2FyZFN0YXRlID0gUEhfTkRFRk1BUF9DQVJEX1NUQVRFX0lOVkFMSUQ7CiAgICAgICAgICAgICAgICBSZXN1bHQgPSBQSE5GQ1NUVkFMKENJRF9GUklfTkZDX05ERUZfTUFQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX05PX05ERUZfU1VQUE9SVCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIFJlc3VsdCA9ICgoTmRlZk1hcC0+Q2FyZFN0YXRlID09CiAgICAgICAgICAgICAgICBQSF9OREVGTUFQX0NBUkRfU1RBVEVfSU5WQUxJRCk/CiAgICAgICAgICAgICAgICBQSE5GQ1NUVkFMKENJRF9GUklfTkZDX05ERUZfTUFQLAogICAgICAgICAgICAgICAgTkZDU1RBVFVTX05PX05ERUZfU1VQUE9SVCk6CiAgICAgICAgICAgICAgICBSZXN1bHQpOwogICAgcmV0dXJuIFJlc3VsdDsKfQoKLyogIFRvIGNoZWNrIG1hcHBpbmcgc3BlYyB2ZXJzaW9uICovCgpORkNTVEFUVVMgICBwaEZyaU5mY19NYXBUb29sX0Noa1NwY1ZlciggY29uc3QgcGhGcmlOZmNfTmRlZk1hcF90ICAqTmRlZk1hcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgICAgICAgICAgICAgVmVyc2lvbkluZGV4KQp7CiAgICBORkNTVEFUVVMgc3RhdHVzID0gTkZDU1RBVFVTX1NVQ0NFU1M7CgogICAgdWludDhfdCBUYWdWZXJObyA9IE5kZWZNYXAtPlNlbmRSZWN2QnVmW1ZlcnNpb25JbmRleF07CgogICAgaWYgKCBUYWdWZXJObyA9PSAwICkKICAgIHsKICAgICAgICAvKlJldHVybiBTdGF0dXMgRXJyb3IgkyBJbnZhbGlkIEZvcm1hdJQqLwogICAgICAgIHN0YXR1cyA9IFBITkZDU1RWQUwoQ0lEX0ZSSV9ORkNfTkRFRl9NQVAsTkZDU1RBVFVTX0lOVkFMSURfRk9STUFUKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzd2l0Y2ggKE5kZWZNYXAtPkNhcmRUeXBlKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBQSF9GUklORkNfTkRFRk1BUF9NSUZBUkVfU1REXzFLX0NBUkQ6CiAgICAgICAgICAgIGNhc2UgUEhfRlJJTkZDX05ERUZNQVBfTUlGQVJFX1NURF80S19DQVJEOgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBjYWxjdWxhdGUgdGhlIG1ham9yIGFuZCBtaW5vciB2ZXJzaW9uIG51bWJlciBvZiBNaWZhcmUgc3RkIHZlcnNpb24gbnVtYmVyICovCiAgICAgICAgICAgICAgICBzdGF0dXMgPSAoKCAoKCBQSF9ORkNGUklfTUZTVERNQVBfTkZDREVWX01BSk9SX1ZFUl9OVU0gPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSF9ORkNGUklfTUZTVERNQVBfR0VUX01BSk9SX1RBR19WRVJOTyhUYWdWZXJObyApICkmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgKCBQSF9ORkNGUklfTUZTVERNQVBfTkZDREVWX01JTk9SX1ZFUl9OVU0gPT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSF9ORkNGUklfTUZTVERNQVBfR0VUX01JTk9SX1RBR19WRVJOTyhUYWdWZXJObykpKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKCggUEhfTkZDRlJJX01GU1RETUFQX05GQ0RFVl9NQUpPUl9WRVJfTlVNID09CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEhfTkZDRlJJX01GU1RETUFQX0dFVF9NQUpPUl9UQUdfVkVSTk8oVGFnVmVyTm8gKSApJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICggUEhfTkZDRlJJX01GU1RETUFQX05GQ0RFVl9NSU5PUl9WRVJfTlVNIDwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSF9ORkNGUklfTUZTVERNQVBfR0VUX01JTk9SX1RBR19WRVJOTyhUYWdWZXJObykgKSkpPwogICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfU1VDQ0VTUzoKICAgICAgICAgICAgICAgICAgICAgICAgUEhORkNTVFZBTChDSURfRlJJX05GQ19OREVGX01BUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX0lOVkFMSURfRk9STUFUKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKI2lmZGVmIERFU0ZJUkVfRVYxCiAgICAgICAgICAgIGNhc2UgUEhfRlJJTkZDX05ERUZNQVBfSVNPMTQ0NDNfNEFfQ0FSRF9FVjE6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIGNhbGN1bGF0ZSB0aGUgbWFqb3IgYW5kIG1pbm9yIHZlcnNpb24gbnVtYmVyIG9mIFQzVmVyTm8gKi8KICAgICAgICAgICAgICAgIGlmKCAoKCBQSF9ORkNGUklfTkRFRk1BUF9ORkNERVZfTUFKT1JfVkVSX05VTV8yID09CiAgICAgICAgICAgICAgICAgICAgICAgIFBIX05GQ0ZSSV9OREVGTUFQX0dFVF9NQUpPUl9UQUdfVkVSTk8oVGFnVmVyTm8gKSApJiYKICAgICAgICAgICAgICAgICAgICAoIFBIX05GQ0ZSSV9OREVGTUFQX05GQ0RFVl9NSU5PUl9WRVJfTlVNID09CiAgICAgICAgICAgICAgICAgICAgICAgIFBIX05GQ0ZSSV9OREVGTUFQX0dFVF9NSU5PUl9UQUdfVkVSTk8oVGFnVmVyTm8pKSkgfHwKICAgICAgICAgICAgICAgICAgICAoKCBQSF9ORkNGUklfTkRFRk1BUF9ORkNERVZfTUFKT1JfVkVSX05VTV8yID09CiAgICAgICAgICAgICAgICAgICAgICAgIFBIX05GQ0ZSSV9OREVGTUFQX0dFVF9NQUpPUl9UQUdfVkVSTk8oVGFnVmVyTm8gKSApJiYKICAgICAgICAgICAgICAgICAgICAoIFBIX05GQ0ZSSV9OREVGTUFQX05GQ0RFVl9NSU5PUl9WRVJfTlVNIDwKICAgICAgICAgICAgICAgICAgICAgICAgUEhfTkZDRlJJX05ERUZNQVBfR0VUX01JTk9SX1RBR19WRVJOTyhUYWdWZXJObykgKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gUEhORkNTVFZBTChDSURfTkZDX05PTkUsTkZDU1RBVFVTX1NVQ0NFU1MpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICgoIFBIX05GQ0ZSSV9OREVGTUFQX05GQ0RFVl9NQUpPUl9WRVJfTlVNXzIgPAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUEhfTkZDRlJJX05ERUZNQVBfR0VUX01BSk9SX1RBR19WRVJOTyhUYWdWZXJObykgKSB8fAogICAgICAgICAgICAgICAgICAgICggUEhfTkZDRlJJX05ERUZNQVBfTkZDREVWX01BSk9SX1ZFUl9OVU1fMiA+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSF9ORkNGUklfTkRFRk1BUF9HRVRfTUFKT1JfVEFHX1ZFUk5PKFRhZ1Zlck5vKSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9GUklfTkZDX05ERUZfTUFQLE5GQ1NUQVRVU19JTlZBTElEX0ZPUk1BVCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KI2VuZGlmIC8qICNpZmRlZiBERVNGSVJFX0VWMSAqLwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogY2FsY3VsYXRlIHRoZSBtYWpvciBhbmQgbWlub3IgdmVyc2lvbiBudW1iZXIgb2YgVDNWZXJObyAqLwogICAgICAgICAgICAgICAgaWYoICgoIFBIX05GQ0ZSSV9OREVGTUFQX05GQ0RFVl9NQUpPUl9WRVJfTlVNID09CiAgICAgICAgICAgICAgICAgICAgICAgIFBIX05GQ0ZSSV9OREVGTUFQX0dFVF9NQUpPUl9UQUdfVkVSTk8oVGFnVmVyTm8gKSApJiYKICAgICAgICAgICAgICAgICAgICAoIFBIX05GQ0ZSSV9OREVGTUFQX05GQ0RFVl9NSU5PUl9WRVJfTlVNID09CiAgICAgICAgICAgICAgICAgICAgICAgIFBIX05GQ0ZSSV9OREVGTUFQX0dFVF9NSU5PUl9UQUdfVkVSTk8oVGFnVmVyTm8pKSkgfHwKICAgICAgICAgICAgICAgICAgICAoKCBQSF9ORkNGUklfTkRFRk1BUF9ORkNERVZfTUFKT1JfVkVSX05VTSA9PQogICAgICAgICAgICAgICAgICAgICAgICBQSF9ORkNGUklfTkRFRk1BUF9HRVRfTUFKT1JfVEFHX1ZFUk5PKFRhZ1Zlck5vICkgKSYmCiAgICAgICAgICAgICAgICAgICAgKCBQSF9ORkNGUklfTkRFRk1BUF9ORkNERVZfTUlOT1JfVkVSX05VTSA8CiAgICAgICAgICAgICAgICAgICAgICAgIFBIX05GQ0ZSSV9OREVGTUFQX0dFVF9NSU5PUl9UQUdfVkVSTk8oVGFnVmVyTm8pICkpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IFBITkZDU1RWQUwoQ0lEX05GQ19OT05FLE5GQ1NUQVRVU19TVUNDRVNTKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoKCBQSF9ORkNGUklfTkRFRk1BUF9ORkNERVZfTUFKT1JfVkVSX05VTSA8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSF9ORkNGUklfTkRFRk1BUF9HRVRfTUFKT1JfVEFHX1ZFUk5PKFRhZ1Zlck5vKSApIHx8CiAgICAgICAgICAgICAgICAgICAgKCBQSF9ORkNGUklfTkRFRk1BUF9ORkNERVZfTUFKT1JfVkVSX05VTSA+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSF9ORkNGUklfTkRFRk1BUF9HRVRfTUFKT1JfVEFHX1ZFUk5PKFRhZ1Zlck5vKSkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9GUklfTkZDX05ERUZfTUFQLE5GQ1NUQVRVU19JTlZBTElEX0ZPUk1BVCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCgogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gKHN0YXR1cyk7Cn0K