LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCiAgIHVuaWNvZGVkYXRhIC0tIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgVW5pY29kZSA1LjIgZGF0YSBiYXNlLg0KDQogICBEYXRhIHdhcyBleHRyYWN0ZWQgZnJvbSB0aGUgVW5pY29kZSA1LjIgVW5pY29kZURhdGEudHh0IGZpbGUuDQoNCiAgIFdyaXR0ZW4gYnkgTWFyYy1BbmRyZSBMZW1idXJnIChtYWxAbGVtYnVyZy5jb20pLg0KICAgTW9kaWZpZWQgZm9yIFB5dGhvbiAyLjAgYnkgRnJlZHJpayBMdW5kaCAoZnJlZHJpa0BweXRob253YXJlLmNvbSkNCiAgIE1vZGlmaWVkIGJ5IE1hcnRpbiB2LiBM9ndpcyAobWFydGluQHYubG9ld2lzLmRlKQ0KDQogICBDb3B5cmlnaHQgKGMpIENvcnBvcmF0aW9uIGZvciBOYXRpb25hbCBSZXNlYXJjaCBJbml0aWF0aXZlcy4NCg0KICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQoNCiNpbmNsdWRlICJQeXRob24uaCINCiNpbmNsdWRlICJ1Y25oYXNoLmgiDQojaW5jbHVkZSAic3RydWN0bWVtYmVyLmgiDQoNCi8qIGNoYXJhY3RlciBwcm9wZXJ0aWVzICovDQoNCnR5cGVkZWYgc3RydWN0IHsNCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIGNhdGVnb3J5OyAgICAgICAvKiBpbmRleCBpbnRvDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX1B5VW5pY29kZV9DYXRlZ29yeU5hbWVzICovDQogICAgY29uc3QgdW5zaWduZWQgY2hhciBjb21iaW5pbmc7ICAgICAgLyogY29tYmluaW5nIGNsYXNzIHZhbHVlIDAgLSAyNTUgKi8NCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIGJpZGlyZWN0aW9uYWw7ICAvKiBpbmRleCBpbnRvDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX1B5VW5pY29kZV9CaWRpcmVjdGlvbmFsTmFtZXMgKi8NCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIG1pcnJvcmVkOyAgICAgICAvKiB0cnVlIGlmIG1pcnJvcmVkIGluIGJpZGlyIG1vZGUgKi8NCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIGVhc3RfYXNpYW5fd2lkdGg7ICAgICAgIC8qIGluZGV4IGludG8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9QeVVuaWNvZGVfRWFzdEFzaWFuV2lkdGggKi8NCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIG5vcm1hbGl6YXRpb25fcXVpY2tfY2hlY2s7IC8qIHNlZSBpc19ub3JtYWxpemVkKCkgKi8NCn0gX1B5VW5pY29kZV9EYXRhYmFzZVJlY29yZDsNCg0KdHlwZWRlZiBzdHJ1Y3QgY2hhbmdlX3JlY29yZCB7DQogICAgLyogc2VxdWVuY2Ugb2YgZmllbGRzIHNob3VsZCBiZSB0aGUgc2FtZSBhcyBpbiBtZXJnZV9vbGRfdmVyc2lvbiAqLw0KICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgYmlkaXJfY2hhbmdlZDsNCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIGNhdGVnb3J5X2NoYW5nZWQ7DQogICAgY29uc3QgdW5zaWduZWQgY2hhciBkZWNpbWFsX2NoYW5nZWQ7DQogICAgY29uc3QgdW5zaWduZWQgY2hhciBtaXJyb3JlZF9jaGFuZ2VkOw0KICAgIGNvbnN0IGRvdWJsZSBudW1lcmljX2NoYW5nZWQ7DQp9IGNoYW5nZV9yZWNvcmQ7DQoNCi8qIGRhdGEgZmlsZSBnZW5lcmF0ZWQgYnkgVG9vbHMvdW5pY29kZS9tYWtldW5pY29kZWRhdGEucHkgKi8NCiNpbmNsdWRlICJ1bmljb2RlZGF0YV9kYi5oIg0KDQpzdGF0aWMgY29uc3QgX1B5VW5pY29kZV9EYXRhYmFzZVJlY29yZCoNCl9nZXRyZWNvcmRfZXgoUHlfVUNTNCBjb2RlKQ0Kew0KICAgIGludCBpbmRleDsNCiAgICBpZiAoY29kZSA+PSAweDExMDAwMCkNCiAgICAgICAgaW5kZXggPSAwOw0KICAgIGVsc2Ugew0KICAgICAgICBpbmRleCA9IGluZGV4MVsoY29kZT4+U0hJRlQpXTsNCiAgICAgICAgaW5kZXggPSBpbmRleDJbKGluZGV4PDxTSElGVCkrKGNvZGUmKCgxPDxTSElGVCktMSkpXTsNCiAgICB9DQoNCiAgICByZXR1cm4gJl9QeVVuaWNvZGVfRGF0YWJhc2VfUmVjb3Jkc1tpbmRleF07DQp9DQoNCi8qIC0tLS0tLS0tLS0tLS0gUHJldmlvdXMtdmVyc2lvbiBBUEkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KdHlwZWRlZiBzdHJ1Y3QgcHJldmlvdXNfdmVyc2lvbiB7DQogICAgUHlPYmplY3RfSEVBRA0KICAgIGNvbnN0IGNoYXIgKm5hbWU7DQogICAgY29uc3QgY2hhbmdlX3JlY29yZCogKCpnZXRyZWNvcmQpKFB5X1VDUzQpOw0KICAgIFB5X1VDUzQgKCpub3JtYWxpemF0aW9uKShQeV9VQ1M0KTsNCn0gUHJldmlvdXNEQlZlcnNpb247DQoNCiNkZWZpbmUgZ2V0X29sZF9yZWNvcmQoc2VsZiwgdikgICAgKCgoKFByZXZpb3VzREJWZXJzaW9uKilzZWxmKS0+Z2V0cmVjb3JkKSh2KSkNCg0Kc3RhdGljIFB5TWVtYmVyRGVmIERCX21lbWJlcnNbXSA9IHsNCiAgICAgICAgeyJ1bmlkYXRhX3ZlcnNpb24iLCBUX1NUUklORywgb2Zmc2V0b2YoUHJldmlvdXNEQlZlcnNpb24sIG5hbWUpLCBSRUFET05MWX0sDQogICAgICAgIHtOVUxMfQ0KfTsNCg0KLyogZm9yd2FyZCBkZWNsYXJhdGlvbiAqLw0Kc3RhdGljIFB5VHlwZU9iamVjdCBVQ0RfVHlwZTsNCg0Kc3RhdGljIFB5T2JqZWN0Kg0KbmV3X3ByZXZpb3VzX3ZlcnNpb24oY29uc3QgY2hhcipuYW1lLCBjb25zdCBjaGFuZ2VfcmVjb3JkKiAoKmdldHJlY29yZCkoUHlfVUNTNCksDQogICAgICAgICAgICAgICAgICAgICBQeV9VQ1M0ICgqbm9ybWFsaXphdGlvbikoUHlfVUNTNCkpDQp7DQogICAgICAgIFByZXZpb3VzREJWZXJzaW9uICpzZWxmOw0KICAgICAgICBzZWxmID0gUHlPYmplY3RfTmV3KFByZXZpb3VzREJWZXJzaW9uLCAmVUNEX1R5cGUpOw0KICAgICAgICBpZiAoc2VsZiA9PSBOVUxMKQ0KICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOw0KICAgICAgICBzZWxmLT5uYW1lID0gbmFtZTsNCiAgICAgICAgc2VsZi0+Z2V0cmVjb3JkID0gZ2V0cmVjb3JkOw0KICAgICAgICBzZWxmLT5ub3JtYWxpemF0aW9uID0gbm9ybWFsaXphdGlvbjsNCiAgICAgICAgcmV0dXJuIChQeU9iamVjdCopc2VsZjsNCn0NCg0KDQpzdGF0aWMgUHlfVUNTNCBnZXR1Y2hhcihQeVVuaWNvZGVPYmplY3QgKm9iaikNCnsNCiAgICBQeV9VTklDT0RFICp2ID0gUHlVbmljb2RlX0FTX1VOSUNPREUob2JqKTsNCg0KICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUob2JqKSA9PSAxKQ0KICAgICAgICByZXR1cm4gKnY7DQojaWZuZGVmIFB5X1VOSUNPREVfV0lERQ0KICAgIGVsc2UgaWYgKChQeVVuaWNvZGVfR0VUX1NJWkUob2JqKSA9PSAyKSAmJg0KICAgICAgICAgICAgICgweEQ4MDAgPD0gdlswXSAmJiB2WzBdIDw9IDB4REJGRikgJiYNCiAgICAgICAgICAgICAoMHhEQzAwIDw9IHZbMV0gJiYgdlsxXSA8PSAweERGRkYpKQ0KICAgICAgICByZXR1cm4gKCgodlswXSAmIDB4M0ZGKTw8MTApIHwgKHZbMV0gJiAweDNGRikpICsgMHgxMDAwMDsNCiNlbmRpZg0KICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsDQogICAgICAgICAgICAgICAgICAgICJuZWVkIGEgc2luZ2xlIFVuaWNvZGUgY2hhcmFjdGVyIGFzIHBhcmFtZXRlciIpOw0KICAgIHJldHVybiAoUHlfVUNTNCktMTsNCn0NCg0KLyogLS0tIE1vZHVsZSBBUEkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovDQoNClB5RG9jX1NUUlZBUih1bmljb2RlZGF0YV9kZWNpbWFsX19kb2NfXywNCiJkZWNpbWFsKHVuaWNoclssIGRlZmF1bHRdKVxuXA0KXG5cDQpSZXR1cm5zIHRoZSBkZWNpbWFsIHZhbHVlIGFzc2lnbmVkIHRvIHRoZSBVbmljb2RlIGNoYXJhY3RlciB1bmljaHJcblwNCmFzIGludGVnZXIuIElmIG5vIHN1Y2ggdmFsdWUgaXMgZGVmaW5lZCwgZGVmYXVsdCBpcyByZXR1cm5lZCwgb3IsIGlmXG5cDQpub3QgZ2l2ZW4sIFZhbHVlRXJyb3IgaXMgcmFpc2VkLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QgKg0KdW5pY29kZWRhdGFfZGVjaW1hbChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpDQp7DQogICAgUHlVbmljb2RlT2JqZWN0ICp2Ow0KICAgIFB5T2JqZWN0ICpkZWZvYmogPSBOVUxMOw0KICAgIGludCBoYXZlX29sZCA9IDA7DQogICAgbG9uZyByYzsNCiAgICBQeV9VQ1M0IGM7DQoNCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hfE86ZGVjaW1hbCIsICZQeVVuaWNvZGVfVHlwZSwgJnYsICZkZWZvYmopKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBjID0gZ2V0dWNoYXIodik7DQogICAgaWYgKGMgPT0gKFB5X1VDUzQpLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KDQogICAgaWYgKHNlbGYpIHsNCiAgICAgICAgY29uc3QgY2hhbmdlX3JlY29yZCAqb2xkID0gZ2V0X29sZF9yZWNvcmQoc2VsZiwgYyk7DQogICAgICAgIGlmIChvbGQtPmNhdGVnb3J5X2NoYW5nZWQgPT0gMCkgew0KICAgICAgICAgICAgLyogdW5hc3NpZ25lZCAqLw0KICAgICAgICAgICAgaGF2ZV9vbGQgPSAxOw0KICAgICAgICAgICAgcmMgPSAtMTsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlIGlmIChvbGQtPmRlY2ltYWxfY2hhbmdlZCAhPSAweEZGKSB7DQogICAgICAgICAgICBoYXZlX29sZCA9IDE7DQogICAgICAgICAgICByYyA9IG9sZC0+ZGVjaW1hbF9jaGFuZ2VkOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgaWYgKCFoYXZlX29sZCkNCiAgICAgICAgcmMgPSBQeV9VTklDT0RFX1RPREVDSU1BTChjKTsNCiAgICBpZiAocmMgPCAwKSB7DQogICAgICAgIGlmIChkZWZvYmogPT0gTlVMTCkgew0KICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5vdCBhIGRlY2ltYWwiKTsNCiAgICAgICAgICAgIHJldHVybiBOVUxMOw0KICAgICAgICB9DQogICAgICAgIGVsc2Ugew0KICAgICAgICAgICAgUHlfSU5DUkVGKGRlZm9iaik7DQogICAgICAgICAgICByZXR1cm4gZGVmb2JqOw0KICAgICAgICB9DQogICAgfQ0KICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhyYyk7DQp9DQoNClB5RG9jX1NUUlZBUih1bmljb2RlZGF0YV9kaWdpdF9fZG9jX18sDQoiZGlnaXQodW5pY2hyWywgZGVmYXVsdF0pXG5cDQpcblwNClJldHVybnMgdGhlIGRpZ2l0IHZhbHVlIGFzc2lnbmVkIHRvIHRoZSBVbmljb2RlIGNoYXJhY3RlciB1bmljaHIgYXNcblwNCmludGVnZXIuIElmIG5vIHN1Y2ggdmFsdWUgaXMgZGVmaW5lZCwgZGVmYXVsdCBpcyByZXR1cm5lZCwgb3IsIGlmXG5cDQpub3QgZ2l2ZW4sIFZhbHVlRXJyb3IgaXMgcmFpc2VkLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QgKg0KdW5pY29kZWRhdGFfZGlnaXQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQ0Kew0KICAgIFB5VW5pY29kZU9iamVjdCAqdjsNCiAgICBQeU9iamVjdCAqZGVmb2JqID0gTlVMTDsNCiAgICBsb25nIHJjOw0KICAgIFB5X1VDUzQgYzsNCg0KICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyF8TzpkaWdpdCIsICZQeVVuaWNvZGVfVHlwZSwgJnYsICZkZWZvYmopKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBjID0gZ2V0dWNoYXIodik7DQogICAgaWYgKGMgPT0gKFB5X1VDUzQpLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIHJjID0gUHlfVU5JQ09ERV9UT0RJR0lUKGMpOw0KICAgIGlmIChyYyA8IDApIHsNCiAgICAgICAgaWYgKGRlZm9iaiA9PSBOVUxMKSB7DQogICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIm5vdCBhIGRpZ2l0Iik7DQogICAgICAgICAgICByZXR1cm4gTlVMTDsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlIHsNCiAgICAgICAgICAgIFB5X0lOQ1JFRihkZWZvYmopOw0KICAgICAgICAgICAgcmV0dXJuIGRlZm9iajsNCiAgICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcocmMpOw0KfQ0KDQpQeURvY19TVFJWQVIodW5pY29kZWRhdGFfbnVtZXJpY19fZG9jX18sDQoibnVtZXJpYyh1bmljaHJbLCBkZWZhdWx0XSlcblwNClxuXA0KUmV0dXJucyB0aGUgbnVtZXJpYyB2YWx1ZSBhc3NpZ25lZCB0byB0aGUgVW5pY29kZSBjaGFyYWN0ZXIgdW5pY2hyXG5cDQphcyBmbG9hdC4gSWYgbm8gc3VjaCB2YWx1ZSBpcyBkZWZpbmVkLCBkZWZhdWx0IGlzIHJldHVybmVkLCBvciwgaWZcblwNCm5vdCBnaXZlbiwgVmFsdWVFcnJvciBpcyByYWlzZWQuIik7DQoNCnN0YXRpYyBQeU9iamVjdCAqDQp1bmljb2RlZGF0YV9udW1lcmljKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykNCnsNCiAgICBQeVVuaWNvZGVPYmplY3QgKnY7DQogICAgUHlPYmplY3QgKmRlZm9iaiA9IE5VTEw7DQogICAgaW50IGhhdmVfb2xkID0gMDsNCiAgICBkb3VibGUgcmM7DQogICAgUHlfVUNTNCBjOw0KDQogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPIXxPOm51bWVyaWMiLCAmUHlVbmljb2RlX1R5cGUsICZ2LCAmZGVmb2JqKSkNCiAgICAgICAgcmV0dXJuIE5VTEw7DQogICAgYyA9IGdldHVjaGFyKHYpOw0KICAgIGlmIChjID09IChQeV9VQ1M0KS0xKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCg0KICAgIGlmIChzZWxmKSB7DQogICAgICAgIGNvbnN0IGNoYW5nZV9yZWNvcmQgKm9sZCA9IGdldF9vbGRfcmVjb3JkKHNlbGYsIGMpOw0KICAgICAgICBpZiAob2xkLT5jYXRlZ29yeV9jaGFuZ2VkID09IDApIHsNCiAgICAgICAgICAgIC8qIHVuYXNzaWduZWQgKi8NCiAgICAgICAgICAgIGhhdmVfb2xkID0gMTsNCiAgICAgICAgICAgIHJjID0gLTEuMDsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlIGlmIChvbGQtPmRlY2ltYWxfY2hhbmdlZCAhPSAweEZGKSB7DQogICAgICAgICAgICBoYXZlX29sZCA9IDE7DQogICAgICAgICAgICByYyA9IG9sZC0+ZGVjaW1hbF9jaGFuZ2VkOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgaWYgKCFoYXZlX29sZCkNCiAgICAgICAgcmMgPSBQeV9VTklDT0RFX1RPTlVNRVJJQyhjKTsNCiAgICBpZiAocmMgPT0gLTEuMCkgew0KICAgICAgICBpZiAoZGVmb2JqID09IE5VTEwpIHsNCiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAibm90IGEgbnVtZXJpYyBjaGFyYWN0ZXIiKTsNCiAgICAgICAgICAgIHJldHVybiBOVUxMOw0KICAgICAgICB9DQogICAgICAgIGVsc2Ugew0KICAgICAgICAgICAgUHlfSU5DUkVGKGRlZm9iaik7DQogICAgICAgICAgICByZXR1cm4gZGVmb2JqOw0KICAgICAgICB9DQogICAgfQ0KICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUocmMpOw0KfQ0KDQpQeURvY19TVFJWQVIodW5pY29kZWRhdGFfY2F0ZWdvcnlfX2RvY19fLA0KImNhdGVnb3J5KHVuaWNocilcblwNClxuXA0KUmV0dXJucyB0aGUgZ2VuZXJhbCBjYXRlZ29yeSBhc3NpZ25lZCB0byB0aGUgVW5pY29kZSBjaGFyYWN0ZXJcblwNCnVuaWNociBhcyBzdHJpbmcuIik7DQoNCnN0YXRpYyBQeU9iamVjdCAqDQp1bmljb2RlZGF0YV9jYXRlZ29yeShQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpDQp7DQogICAgUHlVbmljb2RlT2JqZWN0ICp2Ow0KICAgIGludCBpbmRleDsNCiAgICBQeV9VQ1M0IGM7DQoNCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hOmNhdGVnb3J5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgJlB5VW5pY29kZV9UeXBlLCAmdikpDQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIGMgPSBnZXR1Y2hhcih2KTsNCiAgICBpZiAoYyA9PSAoUHlfVUNTNCktMSkNCiAgICAgICAgcmV0dXJuIE5VTEw7DQogICAgaW5kZXggPSAoaW50KSBfZ2V0cmVjb3JkX2V4KGMpLT5jYXRlZ29yeTsNCiAgICBpZiAoc2VsZikgew0KICAgICAgICBjb25zdCBjaGFuZ2VfcmVjb3JkICpvbGQgPSBnZXRfb2xkX3JlY29yZChzZWxmLCBjKTsNCiAgICAgICAgaWYgKG9sZC0+Y2F0ZWdvcnlfY2hhbmdlZCAhPSAweEZGKQ0KICAgICAgICAgICAgaW5kZXggPSBvbGQtPmNhdGVnb3J5X2NoYW5nZWQ7DQogICAgfQ0KICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKF9QeVVuaWNvZGVfQ2F0ZWdvcnlOYW1lc1tpbmRleF0pOw0KfQ0KDQpQeURvY19TVFJWQVIodW5pY29kZWRhdGFfYmlkaXJlY3Rpb25hbF9fZG9jX18sDQoiYmlkaXJlY3Rpb25hbCh1bmljaHIpXG5cDQpcblwNClJldHVybnMgdGhlIGJpZGlyZWN0aW9uYWwgY2F0ZWdvcnkgYXNzaWduZWQgdG8gdGhlIFVuaWNvZGUgY2hhcmFjdGVyXG5cDQp1bmljaHIgYXMgc3RyaW5nLiBJZiBubyBzdWNoIHZhbHVlIGlzIGRlZmluZWQsIGFuIGVtcHR5IHN0cmluZyBpc1xuXA0KcmV0dXJuZWQuIik7DQoNCnN0YXRpYyBQeU9iamVjdCAqDQp1bmljb2RlZGF0YV9iaWRpcmVjdGlvbmFsKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykNCnsNCiAgICBQeVVuaWNvZGVPYmplY3QgKnY7DQogICAgaW50IGluZGV4Ow0KICAgIFB5X1VDUzQgYzsNCg0KICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyE6YmlkaXJlY3Rpb25hbCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICZQeVVuaWNvZGVfVHlwZSwgJnYpKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBjID0gZ2V0dWNoYXIodik7DQogICAgaWYgKGMgPT0gKFB5X1VDUzQpLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIGluZGV4ID0gKGludCkgX2dldHJlY29yZF9leChjKS0+YmlkaXJlY3Rpb25hbDsNCiAgICBpZiAoc2VsZikgew0KICAgICAgICBjb25zdCBjaGFuZ2VfcmVjb3JkICpvbGQgPSBnZXRfb2xkX3JlY29yZChzZWxmLCBjKTsNCiAgICAgICAgaWYgKG9sZC0+Y2F0ZWdvcnlfY2hhbmdlZCA9PSAwKQ0KICAgICAgICAgICAgaW5kZXggPSAwOyAvKiB1bmFzc2lnbmVkICovDQogICAgICAgIGVsc2UgaWYgKG9sZC0+YmlkaXJfY2hhbmdlZCAhPSAweEZGKQ0KICAgICAgICAgICAgaW5kZXggPSBvbGQtPmJpZGlyX2NoYW5nZWQ7DQogICAgfQ0KICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKF9QeVVuaWNvZGVfQmlkaXJlY3Rpb25hbE5hbWVzW2luZGV4XSk7DQp9DQoNClB5RG9jX1NUUlZBUih1bmljb2RlZGF0YV9jb21iaW5pbmdfX2RvY19fLA0KImNvbWJpbmluZyh1bmljaHIpXG5cDQpcblwNClJldHVybnMgdGhlIGNhbm9uaWNhbCBjb21iaW5pbmcgY2xhc3MgYXNzaWduZWQgdG8gdGhlIFVuaWNvZGVcblwNCmNoYXJhY3RlciB1bmljaHIgYXMgaW50ZWdlci4gUmV0dXJucyAwIGlmIG5vIGNvbWJpbmluZyBjbGFzcyBpc1xuXA0KZGVmaW5lZC4iKTsNCg0Kc3RhdGljIFB5T2JqZWN0ICoNCnVuaWNvZGVkYXRhX2NvbWJpbmluZyhQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpDQp7DQogICAgUHlVbmljb2RlT2JqZWN0ICp2Ow0KICAgIGludCBpbmRleDsNCiAgICBQeV9VQ1M0IGM7DQoNCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hOmNvbWJpbmluZyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICZQeVVuaWNvZGVfVHlwZSwgJnYpKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBjID0gZ2V0dWNoYXIodik7DQogICAgaWYgKGMgPT0gKFB5X1VDUzQpLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIGluZGV4ID0gKGludCkgX2dldHJlY29yZF9leChjKS0+Y29tYmluaW5nOw0KICAgIGlmIChzZWxmKSB7DQogICAgICAgIGNvbnN0IGNoYW5nZV9yZWNvcmQgKm9sZCA9IGdldF9vbGRfcmVjb3JkKHNlbGYsIGMpOw0KICAgICAgICBpZiAob2xkLT5jYXRlZ29yeV9jaGFuZ2VkID09IDApDQogICAgICAgICAgICBpbmRleCA9IDA7IC8qIHVuYXNzaWduZWQgKi8NCiAgICB9DQogICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKGluZGV4KTsNCn0NCg0KUHlEb2NfU1RSVkFSKHVuaWNvZGVkYXRhX21pcnJvcmVkX19kb2NfXywNCiJtaXJyb3JlZCh1bmljaHIpXG5cDQpcblwNClJldHVybnMgdGhlIG1pcnJvcmVkIHByb3BlcnR5IGFzc2lnbmVkIHRvIHRoZSBVbmljb2RlIGNoYXJhY3RlclxuXA0KdW5pY2hyIGFzIGludGVnZXIuIFJldHVybnMgMSBpZiB0aGUgY2hhcmFjdGVyIGhhcyBiZWVuIGlkZW50aWZpZWQgYXNcblwNCmEgXCJtaXJyb3JlZFwiIGNoYXJhY3RlciBpbiBiaWRpcmVjdGlvbmFsIHRleHQsIDAgb3RoZXJ3aXNlLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QgKg0KdW5pY29kZWRhdGFfbWlycm9yZWQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQ0Kew0KICAgIFB5VW5pY29kZU9iamVjdCAqdjsNCiAgICBpbnQgaW5kZXg7DQogICAgUHlfVUNTNCBjOw0KDQogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPITptaXJyb3JlZCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICZQeVVuaWNvZGVfVHlwZSwgJnYpKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBjID0gZ2V0dWNoYXIodik7DQogICAgaWYgKGMgPT0gKFB5X1VDUzQpLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIGluZGV4ID0gKGludCkgX2dldHJlY29yZF9leChjKS0+bWlycm9yZWQ7DQogICAgaWYgKHNlbGYpIHsNCiAgICAgICAgY29uc3QgY2hhbmdlX3JlY29yZCAqb2xkID0gZ2V0X29sZF9yZWNvcmQoc2VsZiwgYyk7DQogICAgICAgIGlmIChvbGQtPmNhdGVnb3J5X2NoYW5nZWQgPT0gMCkNCiAgICAgICAgICAgIGluZGV4ID0gMDsgLyogdW5hc3NpZ25lZCAqLw0KICAgICAgICBlbHNlIGlmIChvbGQtPm1pcnJvcmVkX2NoYW5nZWQgIT0gMHhGRikNCiAgICAgICAgICAgIGluZGV4ID0gb2xkLT5taXJyb3JlZF9jaGFuZ2VkOw0KICAgIH0NCiAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoaW5kZXgpOw0KfQ0KDQpQeURvY19TVFJWQVIodW5pY29kZWRhdGFfZWFzdF9hc2lhbl93aWR0aF9fZG9jX18sDQoiZWFzdF9hc2lhbl93aWR0aCh1bmljaHIpXG5cDQpcblwNClJldHVybnMgdGhlIGVhc3QgYXNpYW4gd2lkdGggYXNzaWduZWQgdG8gdGhlIFVuaWNvZGUgY2hhcmFjdGVyXG5cDQp1bmljaHIgYXMgc3RyaW5nLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QgKg0KdW5pY29kZWRhdGFfZWFzdF9hc2lhbl93aWR0aChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpDQp7DQogICAgUHlVbmljb2RlT2JqZWN0ICp2Ow0KICAgIGludCBpbmRleDsNCiAgICBQeV9VQ1M0IGM7DQoNCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hOmVhc3RfYXNpYW5fd2lkdGgiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAmUHlVbmljb2RlX1R5cGUsICZ2KSkNCiAgICAgICAgcmV0dXJuIE5VTEw7DQogICAgYyA9IGdldHVjaGFyKHYpOw0KICAgIGlmIChjID09IChQeV9VQ1M0KS0xKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBpbmRleCA9IChpbnQpIF9nZXRyZWNvcmRfZXgoYyktPmVhc3RfYXNpYW5fd2lkdGg7DQogICAgaWYgKHNlbGYpIHsNCiAgICAgICAgY29uc3QgY2hhbmdlX3JlY29yZCAqb2xkID0gZ2V0X29sZF9yZWNvcmQoc2VsZiwgYyk7DQogICAgICAgIGlmIChvbGQtPmNhdGVnb3J5X2NoYW5nZWQgPT0gMCkNCiAgICAgICAgICAgIGluZGV4ID0gMDsgLyogdW5hc3NpZ25lZCAqLw0KICAgIH0NCiAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZyhfUHlVbmljb2RlX0Vhc3RBc2lhbldpZHRoTmFtZXNbaW5kZXhdKTsNCn0NCg0KUHlEb2NfU1RSVkFSKHVuaWNvZGVkYXRhX2RlY29tcG9zaXRpb25fX2RvY19fLA0KImRlY29tcG9zaXRpb24odW5pY2hyKVxuXA0KXG5cDQpSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgZGVjb21wb3NpdGlvbiBtYXBwaW5nIGFzc2lnbmVkIHRvIHRoZSBVbmljb2RlXG5cDQpjaGFyYWN0ZXIgdW5pY2hyIGFzIHN0cmluZy4gQW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkIGluIGNhc2Ugbm9cblwNCnN1Y2ggbWFwcGluZyBpcyBkZWZpbmVkLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QgKg0KdW5pY29kZWRhdGFfZGVjb21wb3NpdGlvbihQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpDQp7DQogICAgUHlVbmljb2RlT2JqZWN0ICp2Ow0KICAgIGNoYXIgZGVjb21wWzI1Nl07DQogICAgaW50IGNvZGUsIGluZGV4LCBjb3VudCwgaTsNCiAgICB1bnNpZ25lZCBpbnQgcHJlZml4X2luZGV4Ow0KICAgIFB5X1VDUzQgYzsNCg0KICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyE6ZGVjb21wb3NpdGlvbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICZQeVVuaWNvZGVfVHlwZSwgJnYpKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBjID0gZ2V0dWNoYXIodik7DQogICAgaWYgKGMgPT0gKFB5X1VDUzQpLTEpDQogICAgICAgIHJldHVybiBOVUxMOw0KDQogICAgY29kZSA9IChpbnQpYzsNCg0KICAgIGlmIChzZWxmKSB7DQogICAgICAgIGNvbnN0IGNoYW5nZV9yZWNvcmQgKm9sZCA9IGdldF9vbGRfcmVjb3JkKHNlbGYsIGMpOw0KICAgICAgICBpZiAob2xkLT5jYXRlZ29yeV9jaGFuZ2VkID09IDApDQogICAgICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiIik7IC8qIHVuYXNzaWduZWQgKi8NCiAgICB9DQoNCiAgICBpZiAoY29kZSA8IDAgfHwgY29kZSA+PSAweDExMDAwMCkNCiAgICAgICAgaW5kZXggPSAwOw0KICAgIGVsc2Ugew0KICAgICAgICBpbmRleCA9IGRlY29tcF9pbmRleDFbKGNvZGU+PkRFQ09NUF9TSElGVCldOw0KICAgICAgICBpbmRleCA9IGRlY29tcF9pbmRleDJbKGluZGV4PDxERUNPTVBfU0hJRlQpKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29kZSYoKDE8PERFQ09NUF9TSElGVCktMSkpXTsNCiAgICB9DQoNCiAgICAvKiBoaWdoIGJ5dGUgaXMgbnVtYmVyIG9mIGhleCBieXRlcyAodXN1YWxseSBvbmUgb3IgdHdvKSwgbG93IGJ5dGUNCiAgICAgICBpcyBwcmVmaXggY29kZSAoZnJvbSovDQogICAgY291bnQgPSBkZWNvbXBfZGF0YVtpbmRleF0gPj4gODsNCg0KICAgIC8qIFhYWDogY291bGQgYWxsb2NhdGUgdGhlIFB5U3RyaW5nIHVwIGZyb250IGluc3RlYWQNCiAgICAgICAoc3RybGVuKHByZWZpeCkgKyA1ICogY291bnQgKyAxIGJ5dGVzKSAqLw0KDQogICAgLyogQmFzZWQgb24gaG93IGluZGV4IGlzIGNhbGN1bGF0ZWQgYWJvdmUgYW5kIGRlY29tcF9kYXRhIGlzIGdlbmVyYXRlZA0KICAgICAgIGZyb20gVG9vbHMvdW5pY29kZS9tYWtldW5pY29kZWRhdGEucHksIGl0IHNob3VsZCBub3QgYmUgcG9zc2libGUNCiAgICAgICB0byBvdmVyZmxvdyBkZWNvbXBfcHJlZml4LiAqLw0KICAgIHByZWZpeF9pbmRleCA9IGRlY29tcF9kYXRhW2luZGV4XSAmIDI1NTsNCiAgICBhc3NlcnQocHJlZml4X2luZGV4IDwgKHNpemVvZihkZWNvbXBfcHJlZml4KS9zaXplb2YoKmRlY29tcF9wcmVmaXgpKSk7DQoNCiAgICAvKiBjb3B5IHByZWZpeCAqLw0KICAgIGkgPSBzdHJsZW4oZGVjb21wX3ByZWZpeFtwcmVmaXhfaW5kZXhdKTsNCiAgICBtZW1jcHkoZGVjb21wLCBkZWNvbXBfcHJlZml4W3ByZWZpeF9pbmRleF0sIGkpOw0KDQogICAgd2hpbGUgKGNvdW50LS0gPiAwKSB7DQogICAgICAgIGlmIChpKQ0KICAgICAgICAgICAgZGVjb21wW2krK10gPSAnICc7DQogICAgICAgIGFzc2VydCgoc2l6ZV90KWkgPCBzaXplb2YoZGVjb21wKSk7DQogICAgICAgIFB5T1Nfc25wcmludGYoZGVjb21wICsgaSwgc2l6ZW9mKGRlY29tcCkgLSBpLCAiJTA0WCIsDQogICAgICAgICAgICAgICAgICAgICAgZGVjb21wX2RhdGFbKytpbmRleF0pOw0KICAgICAgICBpICs9IHN0cmxlbihkZWNvbXAgKyBpKTsNCiAgICB9DQoNCiAgICBkZWNvbXBbaV0gPSAnXDAnOw0KDQogICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmcoZGVjb21wKTsNCn0NCg0Kc3RhdGljIHZvaWQNCmdldF9kZWNvbXBfcmVjb3JkKFB5T2JqZWN0ICpzZWxmLCBQeV9VQ1M0IGNvZGUsIGludCAqaW5kZXgsIGludCAqcHJlZml4LCBpbnQgKmNvdW50KQ0Kew0KICAgIGlmIChjb2RlID49IDB4MTEwMDAwKSB7DQogICAgICAgICppbmRleCA9IDA7DQogICAgfSBlbHNlIGlmIChzZWxmICYmIGdldF9vbGRfcmVjb3JkKHNlbGYsIGNvZGUpLT5jYXRlZ29yeV9jaGFuZ2VkPT0wKSB7DQogICAgICAgIC8qIHVuYXNzaWduZWQgaW4gb2xkIHZlcnNpb24gKi8NCiAgICAgICAgKmluZGV4ID0gMDsNCiAgICB9DQogICAgZWxzZSB7DQogICAgICAgICppbmRleCA9IGRlY29tcF9pbmRleDFbKGNvZGU+PkRFQ09NUF9TSElGVCldOw0KICAgICAgICAqaW5kZXggPSBkZWNvbXBfaW5kZXgyWygqaW5kZXg8PERFQ09NUF9TSElGVCkrDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvZGUmKCgxPDxERUNPTVBfU0hJRlQpLTEpKV07DQogICAgfQ0KDQogICAgLyogaGlnaCBieXRlIGlzIG51bWJlciBvZiBoZXggYnl0ZXMgKHVzdWFsbHkgb25lIG9yIHR3byksIGxvdyBieXRlDQogICAgICAgaXMgcHJlZml4IGNvZGUgKGZyb20qLw0KICAgICpjb3VudCA9IGRlY29tcF9kYXRhWyppbmRleF0gPj4gODsNCiAgICAqcHJlZml4ID0gZGVjb21wX2RhdGFbKmluZGV4XSAmIDI1NTsNCg0KICAgICgqaW5kZXgpKys7DQp9DQoNCiNkZWZpbmUgU0Jhc2UgICAweEFDMDANCiNkZWZpbmUgTEJhc2UgICAweDExMDANCiNkZWZpbmUgVkJhc2UgICAweDExNjENCiNkZWZpbmUgVEJhc2UgICAweDExQTcNCiNkZWZpbmUgTENvdW50ICAxOQ0KI2RlZmluZSBWQ291bnQgIDIxDQojZGVmaW5lIFRDb3VudCAgMjgNCiNkZWZpbmUgTkNvdW50ICAoVkNvdW50KlRDb3VudCkNCiNkZWZpbmUgU0NvdW50ICAoTENvdW50Kk5Db3VudCkNCg0Kc3RhdGljIFB5T2JqZWN0Kg0KbmZkX25ma2QoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICppbnB1dCwgaW50IGspDQp7DQogICAgUHlPYmplY3QgKnJlc3VsdDsNCiAgICBQeV9VTklDT0RFICppLCAqZW5kLCAqbzsNCiAgICAvKiBMb25nZXN0IGRlY29tcG9zaXRpb24gaW4gVW5pY29kZSAzLjI6IFUrRkRGQSAqLw0KICAgIFB5X1VOSUNPREUgc3RhY2tbMjBdOw0KICAgIFB5X3NzaXplX3Qgc3BhY2UsIGlzaXplOw0KICAgIGludCBpbmRleCwgcHJlZml4LCBjb3VudCwgc3RhY2twdHI7DQogICAgdW5zaWduZWQgY2hhciBwcmV2LCBjdXI7DQoNCiAgICBzdGFja3B0ciA9IDA7DQogICAgaXNpemUgPSBQeVVuaWNvZGVfR0VUX1NJWkUoaW5wdXQpOw0KICAgIC8qIE92ZXJhbGxvY2F0ZSBhdG1vc3QgMTAgY2hhcmFjdGVycy4gKi8NCiAgICBzcGFjZSA9IChpc2l6ZSA+IDEwID8gMTAgOiBpc2l6ZSkgKyBpc2l6ZTsNCiAgICByZXN1bHQgPSBQeVVuaWNvZGVfRnJvbVVuaWNvZGUoTlVMTCwgc3BhY2UpOw0KICAgIGlmICghcmVzdWx0KQ0KICAgICAgICByZXR1cm4gTlVMTDsNCiAgICBpID0gUHlVbmljb2RlX0FTX1VOSUNPREUoaW5wdXQpOw0KICAgIGVuZCA9IGkgKyBpc2l6ZTsNCiAgICBvID0gUHlVbmljb2RlX0FTX1VOSUNPREUocmVzdWx0KTsNCg0KICAgIHdoaWxlIChpIDwgZW5kKSB7DQogICAgICAgIHN0YWNrW3N0YWNrcHRyKytdID0gKmkrKzsNCiAgICAgICAgd2hpbGUoc3RhY2twdHIpIHsNCiAgICAgICAgICAgIFB5X1VOSUNPREUgY29kZSA9IHN0YWNrWy0tc3RhY2twdHJdOw0KICAgICAgICAgICAgLyogSGFuZ3VsIERlY29tcG9zaXRpb24gYWRkcyB0aHJlZSBjaGFyYWN0ZXJzIGluDQogICAgICAgICAgICAgICBhIHNpbmdsZSBzdGVwLCBzbyB3ZSBuZWVkIGF0bGVhc3QgdGhhdCBtdWNoIHJvb20uICovDQogICAgICAgICAgICBpZiAoc3BhY2UgPCAzKSB7DQogICAgICAgICAgICAgICAgUHlfc3NpemVfdCBuZXdzaXplID0gUHlTdHJpbmdfR0VUX1NJWkUocmVzdWx0KSArIDEwOw0KICAgICAgICAgICAgICAgIHNwYWNlICs9IDEwOw0KICAgICAgICAgICAgICAgIGlmIChQeVVuaWNvZGVfUmVzaXplKCZyZXN1bHQsIG5ld3NpemUpID09IC0xKQ0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsNCiAgICAgICAgICAgICAgICBvID0gUHlVbmljb2RlX0FTX1VOSUNPREUocmVzdWx0KSArIG5ld3NpemUgLSBzcGFjZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIC8qIEhhbmd1bCBEZWNvbXBvc2l0aW9uLiAqLw0KICAgICAgICAgICAgaWYgKFNCYXNlIDw9IGNvZGUgJiYgY29kZSA8IChTQmFzZStTQ291bnQpKSB7DQogICAgICAgICAgICAgICAgaW50IFNJbmRleCA9IGNvZGUgLSBTQmFzZTsNCiAgICAgICAgICAgICAgICBpbnQgTCA9IExCYXNlICsgU0luZGV4IC8gTkNvdW50Ow0KICAgICAgICAgICAgICAgIGludCBWID0gVkJhc2UgKyAoU0luZGV4ICUgTkNvdW50KSAvIFRDb3VudDsNCiAgICAgICAgICAgICAgICBpbnQgVCA9IFRCYXNlICsgU0luZGV4ICUgVENvdW50Ow0KICAgICAgICAgICAgICAgICpvKysgPSBMOw0KICAgICAgICAgICAgICAgICpvKysgPSBWOw0KICAgICAgICAgICAgICAgIHNwYWNlIC09IDI7DQogICAgICAgICAgICAgICAgaWYgKFQgIT0gVEJhc2UpIHsNCiAgICAgICAgICAgICAgICAgICAgKm8rKyA9IFQ7DQogICAgICAgICAgICAgICAgICAgIHNwYWNlIC0tOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIC8qIG5vcm1hbGl6YXRpb24gY2hhbmdlcyAqLw0KICAgICAgICAgICAgaWYgKHNlbGYpIHsNCiAgICAgICAgICAgICAgICBQeV9VQ1M0IHZhbHVlID0gKChQcmV2aW91c0RCVmVyc2lvbiopc2VsZiktPm5vcm1hbGl6YXRpb24oY29kZSk7DQogICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9IDApIHsNCiAgICAgICAgICAgICAgICAgICAgc3RhY2tbc3RhY2twdHIrK10gPSB2YWx1ZTsNCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvKiBPdGhlciBkZWNvbXBvc2l0aW9ucy4gKi8NCiAgICAgICAgICAgIGdldF9kZWNvbXBfcmVjb3JkKHNlbGYsIGNvZGUsICZpbmRleCwgJnByZWZpeCwgJmNvdW50KTsNCg0KICAgICAgICAgICAgLyogQ29weSBjaGFyYWN0ZXIgaWYgaXQgaXMgbm90IGRlY29tcG9zYWJsZSwgb3IgaGFzIGENCiAgICAgICAgICAgICAgIGNvbXBhdGliaWxpdHkgZGVjb21wb3NpdGlvbiwgYnV0IHdlIGRvIE5GRC4gKi8NCiAgICAgICAgICAgIGlmICghY291bnQgfHwgKHByZWZpeCAmJiAhaykpIHsNCiAgICAgICAgICAgICAgICAqbysrID0gY29kZTsNCiAgICAgICAgICAgICAgICBzcGFjZS0tOw0KICAgICAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgLyogQ29weSBkZWNvbXBvc2l0aW9uIG9udG8gdGhlIHN0YWNrLCBpbiByZXZlcnNlDQogICAgICAgICAgICAgICBvcmRlci4gICovDQogICAgICAgICAgICB3aGlsZShjb3VudCkgew0KICAgICAgICAgICAgICAgIGNvZGUgPSBkZWNvbXBfZGF0YVtpbmRleCArICgtLWNvdW50KV07DQogICAgICAgICAgICAgICAgc3RhY2tbc3RhY2twdHIrK10gPSBjb2RlOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfQ0KDQogICAgLyogRHJvcCBvdmVyYWxsb2NhdGlvbi4gQ2Fubm90IGZhaWwuICovDQogICAgUHlVbmljb2RlX1Jlc2l6ZSgmcmVzdWx0LCBQeVVuaWNvZGVfR0VUX1NJWkUocmVzdWx0KSAtIHNwYWNlKTsNCg0KICAgIC8qIFNvcnQgY2Fub25pY2FsbHkuICovDQogICAgaSA9IFB5VW5pY29kZV9BU19VTklDT0RFKHJlc3VsdCk7DQogICAgcHJldiA9IF9nZXRyZWNvcmRfZXgoKmkpLT5jb21iaW5pbmc7DQogICAgZW5kID0gaSArIFB5VW5pY29kZV9HRVRfU0laRShyZXN1bHQpOw0KICAgIGZvciAoaSsrOyBpIDwgZW5kOyBpKyspIHsNCiAgICAgICAgY3VyID0gX2dldHJlY29yZF9leCgqaSktPmNvbWJpbmluZzsNCiAgICAgICAgaWYgKHByZXYgPT0gMCB8fCBjdXIgPT0gMCB8fCBwcmV2IDw9IGN1cikgew0KICAgICAgICAgICAgcHJldiA9IGN1cjsNCiAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICB9DQogICAgICAgIC8qIE5vbi1jYW5vbmljYWwgb3JkZXIuIE5lZWQgdG8gc3dpdGNoICppIHdpdGggcHJldmlvdXMuICovDQogICAgICAgIG8gPSBpIC0gMTsNCiAgICAgICAgd2hpbGUgKDEpIHsNCiAgICAgICAgICAgIFB5X1VOSUNPREUgdG1wID0gb1sxXTsNCiAgICAgICAgICAgIG9bMV0gPSBvWzBdOw0KICAgICAgICAgICAgb1swXSA9IHRtcDsNCiAgICAgICAgICAgIG8tLTsNCiAgICAgICAgICAgIGlmIChvIDwgUHlVbmljb2RlX0FTX1VOSUNPREUocmVzdWx0KSkNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgIHByZXYgPSBfZ2V0cmVjb3JkX2V4KCpvKS0+Y29tYmluaW5nOw0KICAgICAgICAgICAgaWYgKHByZXYgPT0gMCB8fCBwcmV2IDw9IGN1cikNCiAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgICBwcmV2ID0gX2dldHJlY29yZF9leCgqaSktPmNvbWJpbmluZzsNCiAgICB9DQogICAgcmV0dXJuIHJlc3VsdDsNCn0NCg0Kc3RhdGljIGludA0KZmluZF9uZmNfaW5kZXgoUHlPYmplY3QgKnNlbGYsIHN0cnVjdCByZWluZGV4KiBuZmMsIFB5X1VOSUNPREUgY29kZSkNCnsNCiAgICBpbnQgaW5kZXg7DQogICAgZm9yIChpbmRleCA9IDA7IG5mY1tpbmRleF0uc3RhcnQ7IGluZGV4KyspIHsNCiAgICAgICAgaW50IHN0YXJ0ID0gbmZjW2luZGV4XS5zdGFydDsNCiAgICAgICAgaWYgKGNvZGUgPCBzdGFydCkNCiAgICAgICAgICAgIHJldHVybiAtMTsNCiAgICAgICAgaWYgKGNvZGUgPD0gc3RhcnQgKyBuZmNbaW5kZXhdLmNvdW50KSB7DQogICAgICAgICAgICBpbnQgZGVsdGEgPSBjb2RlIC0gc3RhcnQ7DQogICAgICAgICAgICByZXR1cm4gbmZjW2luZGV4XS5pbmRleCArIGRlbHRhOw0KICAgICAgICB9DQogICAgfQ0KICAgIHJldHVybiAtMTsNCn0NCg0Kc3RhdGljIFB5T2JqZWN0Kg0KbmZjX25ma2MoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICppbnB1dCwgaW50IGspDQp7DQogICAgUHlPYmplY3QgKnJlc3VsdDsNCiAgICBQeV9VTklDT0RFICppLCAqaTEsICpvLCAqZW5kOw0KICAgIGludCBmLGwsaW5kZXgsaW5kZXgxLGNvbWI7DQogICAgUHlfVU5JQ09ERSBjb2RlOw0KICAgIFB5X1VOSUNPREUgKnNraXBwZWRbMjBdOw0KICAgIGludCBjc2tpcHBlZCA9IDA7DQoNCiAgICByZXN1bHQgPSBuZmRfbmZrZChzZWxmLCBpbnB1dCwgayk7DQogICAgaWYgKCFyZXN1bHQpDQogICAgICAgIHJldHVybiBOVUxMOw0KDQogICAgLyogV2UgYXJlIGdvaW5nIHRvIG1vZGlmeSByZXN1bHQgaW4tcGxhY2UuDQogICAgICAgSWYgbmZkX25ma2QgaXMgY2hhbmdlZCB0byBzb21ldGltZXMgcmV0dXJuIHRoZSBpbnB1dCwNCiAgICAgICB0aGlzIGNvZGUgbmVlZHMgdG8gYmUgcmV2aWV3ZWQuICovDQogICAgYXNzZXJ0KHJlc3VsdCAhPSBpbnB1dCk7DQoNCiAgICBpID0gUHlVbmljb2RlX0FTX1VOSUNPREUocmVzdWx0KTsNCiAgICBlbmQgPSBpICsgUHlVbmljb2RlX0dFVF9TSVpFKHJlc3VsdCk7DQogICAgbyA9IFB5VW5pY29kZV9BU19VTklDT0RFKHJlc3VsdCk7DQoNCiAgYWdhaW46DQogICAgd2hpbGUgKGkgPCBlbmQpIHsNCiAgICAgIGZvciAoaW5kZXggPSAwOyBpbmRleCA8IGNza2lwcGVkOyBpbmRleCsrKSB7DQogICAgICAgICAgaWYgKHNraXBwZWRbaW5kZXhdID09IGkpIHsNCiAgICAgICAgICAgICAgLyogKmkgY2hhcmFjdGVyIGlzIHNraXBwZWQuDQogICAgICAgICAgICAgICAgIFJlbW92ZSBmcm9tIGxpc3QuICovDQogICAgICAgICAgICAgIHNraXBwZWRbaW5kZXhdID0gc2tpcHBlZFtjc2tpcHBlZC0xXTsNCiAgICAgICAgICAgICAgY3NraXBwZWQtLTsNCiAgICAgICAgICAgICAgaSsrOw0KICAgICAgICAgICAgICBnb3RvIGFnYWluOyAvKiBjb250aW51ZSB3aGlsZSAqLw0KICAgICAgICAgIH0NCiAgICAgIH0NCiAgICAgIC8qIEhhbmd1bCBDb21wb3NpdGlvbi4gV2UgZG9uJ3QgbmVlZCB0byBjaGVjayBmb3IgPExWLFQ+DQogICAgICAgICBwYWlycywgc2luY2Ugd2UgYWx3YXlzIGhhdmUgZGVjb21wb3NlZCBkYXRhLiAqLw0KICAgICAgaWYgKExCYXNlIDw9ICppICYmICppIDwgKExCYXNlK0xDb3VudCkgJiYNCiAgICAgICAgICBpICsgMSA8IGVuZCAmJg0KICAgICAgICAgIFZCYXNlIDw9IGlbMV0gJiYgaVsxXSA8PSAoVkJhc2UrVkNvdW50KSkgew0KICAgICAgICAgIGludCBMSW5kZXgsIFZJbmRleDsNCiAgICAgICAgICBMSW5kZXggPSBpWzBdIC0gTEJhc2U7DQogICAgICAgICAgVkluZGV4ID0gaVsxXSAtIFZCYXNlOw0KICAgICAgICAgIGNvZGUgPSBTQmFzZSArIChMSW5kZXgqVkNvdW50K1ZJbmRleCkqVENvdW50Ow0KICAgICAgICAgIGkrPTI7DQogICAgICAgICAgaWYgKGkgPCBlbmQgJiYNCiAgICAgICAgICAgICAgVEJhc2UgPD0gKmkgJiYgKmkgPD0gKFRCYXNlK1RDb3VudCkpIHsNCiAgICAgICAgICAgICAgY29kZSArPSAqaS1UQmFzZTsNCiAgICAgICAgICAgICAgaSsrOw0KICAgICAgICAgIH0NCiAgICAgICAgICAqbysrID0gY29kZTsNCiAgICAgICAgICBjb250aW51ZTsNCiAgICAgIH0NCg0KICAgICAgZiA9IGZpbmRfbmZjX2luZGV4KHNlbGYsIG5mY19maXJzdCwgKmkpOw0KICAgICAgaWYgKGYgPT0gLTEpIHsNCiAgICAgICAgICAqbysrID0gKmkrKzsNCiAgICAgICAgICBjb250aW51ZTsNCiAgICAgIH0NCiAgICAgIC8qIEZpbmQgbmV4dCB1bmJsb2NrZWQgY2hhcmFjdGVyLiAqLw0KICAgICAgaTEgPSBpKzE7DQogICAgICBjb21iID0gMDsNCiAgICAgIHdoaWxlIChpMSA8IGVuZCkgew0KICAgICAgICAgIGludCBjb21iMSA9IF9nZXRyZWNvcmRfZXgoKmkxKS0+Y29tYmluaW5nOw0KICAgICAgICAgIGlmIChjb21iKSB7DQogICAgICAgICAgICAgIGlmIChjb21iMSA9PSAwKQ0KICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgIGlmIChjb21iID49IGNvbWIxKSB7DQogICAgICAgICAgICAgICAgICAvKiBDaGFyYWN0ZXIgaXMgYmxvY2tlZC4gKi8NCiAgICAgICAgICAgICAgICAgIGkxKys7DQogICAgICAgICAgICAgICAgICBjb250aW51ZTsNCiAgICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgICBsID0gZmluZF9uZmNfaW5kZXgoc2VsZiwgbmZjX2xhc3QsICppMSk7DQogICAgICAgICAgLyogKmkxIGNhbm5vdCBiZSBjb21iaW5lZCB3aXRoICppLiBJZiAqaTENCiAgICAgICAgICAgICBpcyBhIHN0YXJ0ZXIsIHdlIGRvbid0IG5lZWQgdG8gbG9vayBmdXJ0aGVyLg0KICAgICAgICAgICAgIE90aGVyd2lzZSwgcmVjb3JkIHRoZSBjb21iaW5pbmcgY2xhc3MuICovDQogICAgICAgICAgaWYgKGwgPT0gLTEpIHsNCiAgICAgICAgICAgIG5vdF9jb21iaW5hYmxlOg0KICAgICAgICAgICAgICBpZiAoY29tYjEgPT0gMCkNCiAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICBjb21iID0gY29tYjE7DQogICAgICAgICAgICAgIGkxKys7DQogICAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICAgIH0NCiAgICAgICAgICBpbmRleCA9IGYqVE9UQUxfTEFTVCArIGw7DQogICAgICAgICAgaW5kZXgxID0gY29tcF9pbmRleFtpbmRleCA+PiBDT01QX1NISUZUXTsNCiAgICAgICAgICBjb2RlID0gY29tcF9kYXRhWyhpbmRleDE8PENPTVBfU0hJRlQpKw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgKGluZGV4JigoMTw8Q09NUF9TSElGVCktMSkpXTsNCiAgICAgICAgICBpZiAoY29kZSA9PSAwKQ0KICAgICAgICAgICAgICBnb3RvIG5vdF9jb21iaW5hYmxlOw0KDQogICAgICAgICAgLyogUmVwbGFjZSB0aGUgb3JpZ2luYWwgY2hhcmFjdGVyLiAqLw0KICAgICAgICAgICppID0gY29kZTsNCiAgICAgICAgICAvKiBNYXJrIHRoZSBzZWNvbmQgY2hhcmFjdGVyIHVudXNlZC4gKi8NCiAgICAgICAgICBhc3NlcnQoY3NraXBwZWQgPCAyMCk7DQogICAgICAgICAgc2tpcHBlZFtjc2tpcHBlZCsrXSA9IGkxOw0KICAgICAgICAgIGkxKys7DQogICAgICAgICAgZiA9IGZpbmRfbmZjX2luZGV4KHNlbGYsIG5mY19maXJzdCwgKmkpOw0KICAgICAgICAgIGlmIChmID09IC0xKQ0KICAgICAgICAgICAgICBicmVhazsNCiAgICAgIH0NCiAgICAgICpvKysgPSAqaSsrOw0KICAgIH0NCiAgICBpZiAobyAhPSBlbmQpDQogICAgICAgIFB5VW5pY29kZV9SZXNpemUoJnJlc3VsdCwgbyAtIFB5VW5pY29kZV9BU19VTklDT0RFKHJlc3VsdCkpOw0KICAgIHJldHVybiByZXN1bHQ7DQp9DQoNCi8qIFJldHVybiAxIGlmIHRoZSBpbnB1dCBpcyBjZXJ0YWlubHkgbm9ybWFsaXplZCwgMCBpZiBpdCBtaWdodCBub3QgYmUuICovDQpzdGF0aWMgaW50DQppc19ub3JtYWxpemVkKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqaW5wdXQsIGludCBuZmMsIGludCBrKQ0Kew0KICAgIFB5X1VOSUNPREUgKmksICplbmQ7DQogICAgdW5zaWduZWQgY2hhciBwcmV2X2NvbWJpbmluZyA9IDAsIHF1aWNrY2hlY2tfbWFzazsNCg0KICAgIC8qIEFuIG9sZGVyIHZlcnNpb24gb2YgdGhlIGRhdGFiYXNlIGlzIHJlcXVlc3RlZCwgcXVpY2tjaGVja3MgbXVzdCBiZQ0KICAgICAgIGRpc2FibGVkLiAqLw0KICAgIGlmIChzZWxmICE9IE5VTEwpDQogICAgICAgIHJldHVybiAwOw0KDQogICAgLyogVGhlIHR3byBxdWlja2NoZWNrIGJpdHMgYXQgdGhpcyBzaGlmdCBtZWFuIDA9WWVzLCAxPU1heWJlLCAyPU5vLA0KICAgICAgIGFzIGRlc2NyaWJlZCBpbiBodHRwOi8vdW5pY29kZS5vcmcvcmVwb3J0cy90cjE1LyNBbm5leDguICovDQogICAgcXVpY2tjaGVja19tYXNrID0gMyA8PCAoKG5mYyA/IDQgOiAwKSArIChrID8gMiA6IDApKTsNCg0KICAgIGkgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShpbnB1dCk7DQogICAgZW5kID0gaSArIFB5VW5pY29kZV9HRVRfU0laRShpbnB1dCk7DQogICAgd2hpbGUgKGkgPCBlbmQpIHsNCiAgICAgICAgY29uc3QgX1B5VW5pY29kZV9EYXRhYmFzZVJlY29yZCAqcmVjb3JkID0gX2dldHJlY29yZF9leCgqaSsrKTsNCiAgICAgICAgdW5zaWduZWQgY2hhciBjb21iaW5pbmcgPSByZWNvcmQtPmNvbWJpbmluZzsNCiAgICAgICAgdW5zaWduZWQgY2hhciBxdWlja2NoZWNrID0gcmVjb3JkLT5ub3JtYWxpemF0aW9uX3F1aWNrX2NoZWNrOw0KDQogICAgICAgIGlmIChxdWlja2NoZWNrICYgcXVpY2tjaGVja19tYXNrKQ0KICAgICAgICAgICAgcmV0dXJuIDA7IC8qIHRoaXMgc3RyaW5nIG1pZ2h0IG5lZWQgbm9ybWFsaXphdGlvbiAqLw0KICAgICAgICBpZiAoY29tYmluaW5nICYmIHByZXZfY29tYmluaW5nID4gY29tYmluaW5nKQ0KICAgICAgICAgICAgcmV0dXJuIDA7IC8qIG5vbi1jYW5vbmljYWwgc29ydCBvcmRlciwgbm90IG5vcm1hbGl6ZWQgKi8NCiAgICAgICAgcHJldl9jb21iaW5pbmcgPSBjb21iaW5pbmc7DQogICAgfQ0KICAgIHJldHVybiAxOyAvKiBjZXJ0YWlubHkgbm9ybWFsaXplZCAqLw0KfQ0KDQpQeURvY19TVFJWQVIodW5pY29kZWRhdGFfbm9ybWFsaXplX19kb2NfXywNCiJub3JtYWxpemUoZm9ybSwgdW5pc3RyKVxuXA0KXG5cDQpSZXR1cm4gdGhlIG5vcm1hbCBmb3JtICdmb3JtJyBmb3IgdGhlIFVuaWNvZGUgc3RyaW5nIHVuaXN0ci4gIFZhbGlkXG5cDQp2YWx1ZXMgZm9yIGZvcm0gYXJlICdORkMnLCAnTkZLQycsICdORkQnLCBhbmQgJ05GS0QnLiIpOw0KDQpzdGF0aWMgUHlPYmplY3QqDQp1bmljb2RlZGF0YV9ub3JtYWxpemUoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQ0Kew0KICAgIGNoYXIgKmZvcm07DQogICAgUHlPYmplY3QgKmlucHV0Ow0KDQogICAgaWYoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInNPITpub3JtYWxpemUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICZmb3JtLCAmUHlVbmljb2RlX1R5cGUsICZpbnB1dCkpDQogICAgICAgIHJldHVybiBOVUxMOw0KDQogICAgaWYgKFB5VW5pY29kZV9HZXRTaXplKGlucHV0KSA9PSAwKSB7DQogICAgICAgIC8qIFNwZWNpYWwgY2FzZSBlbXB0eSBpbnB1dCBzdHJpbmdzLCBzaW5jZSByZXNpemluZw0KICAgICAgICAgICB0aGVtICBsYXRlciB3b3VsZCBjYXVzZSBpbnRlcm5hbCBlcnJvcnMuICovDQogICAgICAgIFB5X0lOQ1JFRihpbnB1dCk7DQogICAgICAgIHJldHVybiBpbnB1dDsNCiAgICB9DQoNCiAgICBpZiAoc3RyY21wKGZvcm0sICJORkMiKSA9PSAwKSB7DQogICAgICAgIGlmIChpc19ub3JtYWxpemVkKHNlbGYsIGlucHV0LCAxLCAwKSkgew0KICAgICAgICAgICAgUHlfSU5DUkVGKGlucHV0KTsNCiAgICAgICAgICAgIHJldHVybiBpbnB1dDsNCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gbmZjX25ma2Moc2VsZiwgaW5wdXQsIDApOw0KICAgIH0NCiAgICBpZiAoc3RyY21wKGZvcm0sICJORktDIikgPT0gMCkgew0KICAgICAgICBpZiAoaXNfbm9ybWFsaXplZChzZWxmLCBpbnB1dCwgMSwgMSkpIHsNCiAgICAgICAgICAgIFB5X0lOQ1JFRihpbnB1dCk7DQogICAgICAgICAgICByZXR1cm4gaW5wdXQ7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIG5mY19uZmtjKHNlbGYsIGlucHV0LCAxKTsNCiAgICB9DQogICAgaWYgKHN0cmNtcChmb3JtLCAiTkZEIikgPT0gMCkgew0KICAgICAgICBpZiAoaXNfbm9ybWFsaXplZChzZWxmLCBpbnB1dCwgMCwgMCkpIHsNCiAgICAgICAgICAgIFB5X0lOQ1JFRihpbnB1dCk7DQogICAgICAgICAgICByZXR1cm4gaW5wdXQ7DQogICAgICAgIH0NCiAgICAgICAgcmV0dXJuIG5mZF9uZmtkKHNlbGYsIGlucHV0LCAwKTsNCiAgICB9DQogICAgaWYgKHN0cmNtcChmb3JtLCAiTkZLRCIpID09IDApIHsNCiAgICAgICAgaWYgKGlzX25vcm1hbGl6ZWQoc2VsZiwgaW5wdXQsIDAsIDEpKSB7DQogICAgICAgICAgICBQeV9JTkNSRUYoaW5wdXQpOw0KICAgICAgICAgICAgcmV0dXJuIGlucHV0Ow0KICAgICAgICB9DQogICAgICAgIHJldHVybiBuZmRfbmZrZChzZWxmLCBpbnB1dCwgMSk7DQogICAgfQ0KICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiaW52YWxpZCBub3JtYWxpemF0aW9uIGZvcm0iKTsNCiAgICByZXR1cm4gTlVMTDsNCn0NCg0KLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8NCi8qIHVuaWNvZGUgY2hhcmFjdGVyIG5hbWUgdGFibGVzICovDQoNCi8qIGRhdGEgZmlsZSBnZW5lcmF0ZWQgYnkgVG9vbHMvdW5pY29kZS9tYWtldW5pY29kZWRhdGEucHkgKi8NCiNpbmNsdWRlICJ1bmljb2RlbmFtZV9kYi5oIg0KDQovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLyogZGF0YWJhc2UgY29kZSAoY3V0IGFuZCBwYXN0ZWQgZnJvbSB0aGUgdW5pZGIgcGFja2FnZSkgKi8NCg0Kc3RhdGljIHVuc2lnbmVkIGxvbmcNCl9nZXRoYXNoKGNvbnN0IGNoYXIgKnMsIGludCBsZW4sIGludCBzY2FsZSkNCnsNCiAgICBpbnQgaTsNCiAgICB1bnNpZ25lZCBsb25nIGggPSAwOw0KICAgIHVuc2lnbmVkIGxvbmcgaXg7DQogICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7DQogICAgICAgIGggPSAoaCAqIHNjYWxlKSArICh1bnNpZ25lZCBjaGFyKSB0b3VwcGVyKFB5X0NIQVJNQVNLKHNbaV0pKTsNCiAgICAgICAgaXggPSBoICYgMHhmZjAwMDAwMDsNCiAgICAgICAgaWYgKGl4KQ0KICAgICAgICAgICAgaCA9IChoIF4gKChpeD4+MjQpICYgMHhmZikpICYgMHgwMGZmZmZmZjsNCiAgICB9DQogICAgcmV0dXJuIGg7DQp9DQoNCnN0YXRpYyBjaGFyICpoYW5ndWxfc3lsbGFibGVzW11bM10gPSB7DQogICAgeyAiRyIsICAiQSIsICAgIiIgICB9LA0KICAgIHsgIkdHIiwgIkFFIiwgICJHIiAgfSwNCiAgICB7ICJOIiwgICJZQSIsICAiR0ciIH0sDQogICAgeyAiRCIsICAiWUFFIiwgIkdTIiB9LA0KICAgIHsgIkREIiwgIkVPIiwgICJOIiwgfSwNCiAgICB7ICJSIiwgICJFIiwgICAiTkoiIH0sDQogICAgeyAiTSIsICAiWUVPIiwgIk5IIiB9LA0KICAgIHsgIkIiLCAgIllFIiwgICJEIiAgfSwNCiAgICB7ICJCQiIsICJPIiwgICAiTCIgIH0sDQogICAgeyAiUyIsICAiV0EiLCAgIkxHIiB9LA0KICAgIHsgIlNTIiwgIldBRSIsICJMTSIgfSwNCiAgICB7ICIiLCAgICJPRSIsICAiTEIiIH0sDQogICAgeyAiSiIsICAiWU8iLCAgIkxTIiB9LA0KICAgIHsgIkpKIiwgIlUiLCAgICJMVCIgfSwNCiAgICB7ICJDIiwgICJXRU8iLCAiTFAiIH0sDQogICAgeyAiSyIsICAiV0UiLCAgIkxIIiB9LA0KICAgIHsgIlQiLCAgIldJIiwgICJNIiAgfSwNCiAgICB7ICJQIiwgICJZVSIsICAiQiIgIH0sDQogICAgeyAiSCIsICAiRVUiLCAgIkJTIiB9LA0KICAgIHsgMCwgICAgIllJIiwgICJTIiAgfSwNCiAgICB7IDAsICAgICJJIiwgICAiU1MiIH0sDQogICAgeyAwLCAgICAwLCAgICAgIk5HIiB9LA0KICAgIHsgMCwgICAgMCwgICAgICJKIiAgfSwNCiAgICB7IDAsICAgIDAsICAgICAiQyIgIH0sDQogICAgeyAwLCAgICAwLCAgICAgIksiICB9LA0KICAgIHsgMCwgICAgMCwgICAgICJUIiAgfSwNCiAgICB7IDAsICAgIDAsICAgICAiUCIgIH0sDQogICAgeyAwLCAgICAwLCAgICAgIkgiICB9DQp9Ow0KDQpzdGF0aWMgaW50DQppc191bmlmaWVkX2lkZW9ncmFwaChQeV9VQ1M0IGNvZGUpDQp7DQogICAgcmV0dXJuICgNCiAgICAgICAgKDB4MzQwMCA8PSBjb2RlICYmIGNvZGUgPD0gMHg0REI1KSB8fCAvKiBDSksgSWRlb2dyYXBoIEV4dGVuc2lvbiBBICovDQogICAgICAgICgweDRFMDAgPD0gY29kZSAmJiBjb2RlIDw9IDB4OUZDQikgfHwgLyogQ0pLIElkZW9ncmFwaCwgVW5pY29kZSA1LjIgKi8NCiAgICAgICAgKDB4MjAwMDAgPD0gY29kZSAmJiBjb2RlIDw9IDB4MkE2RDYpIHx8IC8qIENKSyBJZGVvZ3JhcGggRXh0ZW5zaW9uIEIgKi8NCiAgICAgICAgKDB4MkE3MDAgPD0gY29kZSAmJiBjb2RlIDw9IDB4MkI3MzQpKTsgIC8qIENKSyBJZGVvZ3JhcGggRXh0ZW5zaW9uIEMgKi8NCn0NCg0Kc3RhdGljIGludA0KX2dldHVjbmFtZShQeU9iamVjdCAqc2VsZiwgUHlfVUNTNCBjb2RlLCBjaGFyKiBidWZmZXIsIGludCBidWZsZW4pDQp7DQogICAgaW50IG9mZnNldDsNCiAgICBpbnQgaTsNCiAgICBpbnQgd29yZDsNCiAgICB1bnNpZ25lZCBjaGFyKiB3Ow0KDQogICAgaWYgKGNvZGUgPj0gMHgxMTAwMDApDQogICAgICAgIHJldHVybiAwOw0KDQogICAgaWYgKHNlbGYpIHsNCiAgICAgICAgY29uc3QgY2hhbmdlX3JlY29yZCAqb2xkID0gZ2V0X29sZF9yZWNvcmQoc2VsZiwgY29kZSk7DQogICAgICAgIGlmIChvbGQtPmNhdGVnb3J5X2NoYW5nZWQgPT0gMCkgew0KICAgICAgICAgICAgLyogdW5hc3NpZ25lZCAqLw0KICAgICAgICAgICAgcmV0dXJuIDA7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICBpZiAoU0Jhc2UgPD0gY29kZSAmJiBjb2RlIDwgU0Jhc2UrU0NvdW50KSB7DQogICAgICAgIC8qIEhhbmd1bCBzeWxsYWJsZS4gKi8NCiAgICAgICAgaW50IFNJbmRleCA9IGNvZGUgLSBTQmFzZTsNCiAgICAgICAgaW50IEwgPSBTSW5kZXggLyBOQ291bnQ7DQogICAgICAgIGludCBWID0gKFNJbmRleCAlIE5Db3VudCkgLyBUQ291bnQ7DQogICAgICAgIGludCBUID0gU0luZGV4ICUgVENvdW50Ow0KDQogICAgICAgIGlmIChidWZsZW4gPCAyNykNCiAgICAgICAgICAgIC8qIFdvcnN0IGNhc2U6IEhBTkdVTCBTWUxMQUJMRSA8MTBjaGFycz4uICovDQogICAgICAgICAgICByZXR1cm4gMDsNCiAgICAgICAgc3RyY3B5KGJ1ZmZlciwgIkhBTkdVTCBTWUxMQUJMRSAiKTsNCiAgICAgICAgYnVmZmVyICs9IDE2Ow0KICAgICAgICBzdHJjcHkoYnVmZmVyLCBoYW5ndWxfc3lsbGFibGVzW0xdWzBdKTsNCiAgICAgICAgYnVmZmVyICs9IHN0cmxlbihoYW5ndWxfc3lsbGFibGVzW0xdWzBdKTsNCiAgICAgICAgc3RyY3B5KGJ1ZmZlciwgaGFuZ3VsX3N5bGxhYmxlc1tWXVsxXSk7DQogICAgICAgIGJ1ZmZlciArPSBzdHJsZW4oaGFuZ3VsX3N5bGxhYmxlc1tWXVsxXSk7DQogICAgICAgIHN0cmNweShidWZmZXIsIGhhbmd1bF9zeWxsYWJsZXNbVF1bMl0pOw0KICAgICAgICBidWZmZXIgKz0gc3RybGVuKGhhbmd1bF9zeWxsYWJsZXNbVF1bMl0pOw0KICAgICAgICAqYnVmZmVyID0gJ1wwJzsNCiAgICAgICAgcmV0dXJuIDE7DQogICAgfQ0KDQogICAgaWYgKGlzX3VuaWZpZWRfaWRlb2dyYXBoKGNvZGUpKSB7DQogICAgICAgIGlmIChidWZsZW4gPCAyOCkNCiAgICAgICAgICAgIC8qIFdvcnN0IGNhc2U6IENKSyBVTklGSUVEIElERU9HUkFQSC0yMDAwMCAqLw0KICAgICAgICAgICAgcmV0dXJuIDA7DQogICAgICAgIHNwcmludGYoYnVmZmVyLCAiQ0pLIFVOSUZJRUQgSURFT0dSQVBILSVYIiwgY29kZSk7DQogICAgICAgIHJldHVybiAxOw0KICAgIH0NCg0KICAgIC8qIGdldCBvZmZzZXQgaW50byBwaHJhc2Vib29rICovDQogICAgb2Zmc2V0ID0gcGhyYXNlYm9va19vZmZzZXQxWyhjb2RlPj5waHJhc2Vib29rX3NoaWZ0KV07DQogICAgb2Zmc2V0ID0gcGhyYXNlYm9va19vZmZzZXQyWyhvZmZzZXQ8PHBocmFzZWJvb2tfc2hpZnQpICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29kZSYoKDE8PHBocmFzZWJvb2tfc2hpZnQpLTEpKV07DQogICAgaWYgKCFvZmZzZXQpDQogICAgICAgIHJldHVybiAwOw0KDQogICAgaSA9IDA7DQoNCiAgICBmb3IgKDs7KSB7DQogICAgICAgIC8qIGdldCB3b3JkIGluZGV4ICovDQogICAgICAgIHdvcmQgPSBwaHJhc2Vib29rW29mZnNldF0gLSBwaHJhc2Vib29rX3Nob3J0Ow0KICAgICAgICBpZiAod29yZCA+PSAwKSB7DQogICAgICAgICAgICB3b3JkID0gKHdvcmQgPDwgOCkgKyBwaHJhc2Vib29rW29mZnNldCsxXTsNCiAgICAgICAgICAgIG9mZnNldCArPSAyOw0KICAgICAgICB9IGVsc2UNCiAgICAgICAgICAgIHdvcmQgPSBwaHJhc2Vib29rW29mZnNldCsrXTsNCiAgICAgICAgaWYgKGkpIHsNCiAgICAgICAgICAgIGlmIChpID4gYnVmbGVuKQ0KICAgICAgICAgICAgICAgIHJldHVybiAwOyAvKiBidWZmZXIgb3ZlcmZsb3cgKi8NCiAgICAgICAgICAgIGJ1ZmZlcltpKytdID0gJyAnOw0KICAgICAgICB9DQogICAgICAgIC8qIGNvcHkgd29yZCBzdHJpbmcgZnJvbSBsZXhpY29uLiAgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZQ0KICAgICAgICAgICB3b3JkIGhhcyBiaXQgNyBzZXQuICB0aGUgbGFzdCB3b3JkIGluIGEgc3RyaW5nIGVuZHMgd2l0aA0KICAgICAgICAgICAweDgwICovDQogICAgICAgIHcgPSBsZXhpY29uICsgbGV4aWNvbl9vZmZzZXRbd29yZF07DQogICAgICAgIHdoaWxlICgqdyA8IDEyOCkgew0KICAgICAgICAgICAgaWYgKGkgPj0gYnVmbGVuKQ0KICAgICAgICAgICAgICAgIHJldHVybiAwOyAvKiBidWZmZXIgb3ZlcmZsb3cgKi8NCiAgICAgICAgICAgIGJ1ZmZlcltpKytdID0gKncrKzsNCiAgICAgICAgfQ0KICAgICAgICBpZiAoaSA+PSBidWZsZW4pDQogICAgICAgICAgICByZXR1cm4gMDsgLyogYnVmZmVyIG92ZXJmbG93ICovDQogICAgICAgIGJ1ZmZlcltpKytdID0gKncgJiAxMjc7DQogICAgICAgIGlmICgqdyA9PSAxMjgpDQogICAgICAgICAgICBicmVhazsgLyogZW5kIG9mIHdvcmQgKi8NCiAgICB9DQoNCiAgICByZXR1cm4gMTsNCn0NCg0Kc3RhdGljIGludA0KX2NtcG5hbWUoUHlPYmplY3QgKnNlbGYsIGludCBjb2RlLCBjb25zdCBjaGFyKiBuYW1lLCBpbnQgbmFtZWxlbikNCnsNCiAgICAvKiBjaGVjayBpZiBjb2RlIGNvcnJlc3BvbmRzIHRvIHRoZSBnaXZlbiBuYW1lICovDQogICAgaW50IGk7DQogICAgY2hhciBidWZmZXJbTkFNRV9NQVhMRU5dOw0KICAgIGlmICghX2dldHVjbmFtZShzZWxmLCBjb2RlLCBidWZmZXIsIHNpemVvZihidWZmZXIpKSkNCiAgICAgICAgcmV0dXJuIDA7DQogICAgZm9yIChpID0gMDsgaSA8IG5hbWVsZW47IGkrKykgew0KICAgICAgICBpZiAodG91cHBlcihQeV9DSEFSTUFTSyhuYW1lW2ldKSkgIT0gYnVmZmVyW2ldKQ0KICAgICAgICAgICAgcmV0dXJuIDA7DQogICAgfQ0KICAgIHJldHVybiBidWZmZXJbbmFtZWxlbl0gPT0gJ1wwJzsNCn0NCg0Kc3RhdGljIHZvaWQNCmZpbmRfc3lsbGFibGUoY29uc3QgY2hhciAqc3RyLCBpbnQgKmxlbiwgaW50ICpwb3MsIGludCBjb3VudCwgaW50IGNvbHVtbikNCnsNCiAgICBpbnQgaSwgbGVuMTsNCiAgICAqbGVuID0gLTE7DQogICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHsNCiAgICAgICAgY2hhciAqcyA9IGhhbmd1bF9zeWxsYWJsZXNbaV1bY29sdW1uXTsNCiAgICAgICAgbGVuMSA9IHN0cmxlbihzKTsNCiAgICAgICAgaWYgKGxlbjEgPD0gKmxlbikNCiAgICAgICAgICAgIGNvbnRpbnVlOw0KICAgICAgICBpZiAoc3RybmNtcChzdHIsIHMsIGxlbjEpID09IDApIHsNCiAgICAgICAgICAgICpsZW4gPSBsZW4xOw0KICAgICAgICAgICAgKnBvcyA9IGk7DQogICAgICAgIH0NCiAgICB9DQogICAgaWYgKCpsZW4gPT0gLTEpIHsNCiAgICAgICAgKmxlbiA9IDA7DQogICAgfQ0KfQ0KDQpzdGF0aWMgaW50DQpfZ2V0Y29kZShQeU9iamVjdCogc2VsZiwgY29uc3QgY2hhciogbmFtZSwgaW50IG5hbWVsZW4sIFB5X1VDUzQqIGNvZGUpDQp7DQogICAgdW5zaWduZWQgaW50IGgsIHY7DQogICAgdW5zaWduZWQgaW50IG1hc2sgPSBjb2RlX3NpemUtMTsNCiAgICB1bnNpZ25lZCBpbnQgaSwgaW5jcjsNCg0KICAgIC8qIENoZWNrIGZvciBoYW5ndWwgc3lsbGFibGVzLiAqLw0KICAgIGlmIChzdHJuY21wKG5hbWUsICJIQU5HVUwgU1lMTEFCTEUgIiwgMTYpID09IDApIHsNCiAgICAgICAgaW50IGxlbiwgTCA9IC0xLCBWID0gLTEsIFQgPSAtMTsNCiAgICAgICAgY29uc3QgY2hhciAqcG9zID0gbmFtZSArIDE2Ow0KICAgICAgICBmaW5kX3N5bGxhYmxlKHBvcywgJmxlbiwgJkwsIExDb3VudCwgMCk7DQogICAgICAgIHBvcyArPSBsZW47DQogICAgICAgIGZpbmRfc3lsbGFibGUocG9zLCAmbGVuLCAmViwgVkNvdW50LCAxKTsNCiAgICAgICAgcG9zICs9IGxlbjsNCiAgICAgICAgZmluZF9zeWxsYWJsZShwb3MsICZsZW4sICZULCBUQ291bnQsIDIpOw0KICAgICAgICBwb3MgKz0gbGVuOw0KICAgICAgICBpZiAoTCAhPSAtMSAmJiBWICE9IC0xICYmIFQgIT0gLTEgJiYgcG9zLW5hbWUgPT0gbmFtZWxlbikgew0KICAgICAgICAgICAgKmNvZGUgPSBTQmFzZSArIChMKlZDb3VudCtWKSpUQ291bnQgKyBUOw0KICAgICAgICAgICAgcmV0dXJuIDE7DQogICAgICAgIH0NCiAgICAgICAgLyogT3RoZXJ3aXNlLCBpdCdzIGFuIGlsbGVnYWwgc3lsbGFibGUgbmFtZS4gKi8NCiAgICAgICAgcmV0dXJuIDA7DQogICAgfQ0KDQogICAgLyogQ2hlY2sgZm9yIHVuaWZpZWQgaWRlb2dyYXBocy4gKi8NCiAgICBpZiAoc3RybmNtcChuYW1lLCAiQ0pLIFVOSUZJRUQgSURFT0dSQVBILSIsIDIyKSA9PSAwKSB7DQogICAgICAgIC8qIEZvdXIgb3IgZml2ZSBoZXhkaWdpdHMgbXVzdCBmb2xsb3cuICovDQogICAgICAgIHYgPSAwOw0KICAgICAgICBuYW1lICs9IDIyOw0KICAgICAgICBuYW1lbGVuIC09IDIyOw0KICAgICAgICBpZiAobmFtZWxlbiAhPSA0ICYmIG5hbWVsZW4gIT0gNSkNCiAgICAgICAgICAgIHJldHVybiAwOw0KICAgICAgICB3aGlsZSAobmFtZWxlbi0tKSB7DQogICAgICAgICAgICB2ICo9IDE2Ow0KICAgICAgICAgICAgaWYgKCpuYW1lID49ICcwJyAmJiAqbmFtZSA8PSAnOScpDQogICAgICAgICAgICAgICAgdiArPSAqbmFtZSAtICcwJzsNCiAgICAgICAgICAgIGVsc2UgaWYgKCpuYW1lID49ICdBJyAmJiAqbmFtZSA8PSAnRicpDQogICAgICAgICAgICAgICAgdiArPSAqbmFtZSAtICdBJyArIDEwOw0KICAgICAgICAgICAgZWxzZQ0KICAgICAgICAgICAgICAgIHJldHVybiAwOw0KICAgICAgICAgICAgbmFtZSsrOw0KICAgICAgICB9DQogICAgICAgIGlmICghaXNfdW5pZmllZF9pZGVvZ3JhcGgodikpDQogICAgICAgICAgICByZXR1cm4gMDsNCiAgICAgICAgKmNvZGUgPSB2Ow0KICAgICAgICByZXR1cm4gMTsNCiAgICB9DQoNCiAgICAvKiB0aGUgZm9sbG93aW5nIGlzIHRoZSBzYW1lIGFzIHB5dGhvbidzIGRpY3Rpb25hcnkgbG9va3VwLCB3aXRoDQogICAgICAgb25seSBtaW5vciBjaGFuZ2VzLiAgc2VlIHRoZSBtYWtldW5pY29kZWRhdGEgc2NyaXB0IGZvciBtb3JlDQogICAgICAgZGV0YWlscyAqLw0KDQogICAgaCA9ICh1bnNpZ25lZCBpbnQpIF9nZXRoYXNoKG5hbWUsIG5hbWVsZW4sIGNvZGVfbWFnaWMpOw0KICAgIGkgPSAofmgpICYgbWFzazsNCiAgICB2ID0gY29kZV9oYXNoW2ldOw0KICAgIGlmICghdikNCiAgICAgICAgcmV0dXJuIDA7DQogICAgaWYgKF9jbXBuYW1lKHNlbGYsIHYsIG5hbWUsIG5hbWVsZW4pKSB7DQogICAgICAgICpjb2RlID0gdjsNCiAgICAgICAgcmV0dXJuIDE7DQogICAgfQ0KICAgIGluY3IgPSAoaCBeIChoID4+IDMpKSAmIG1hc2s7DQogICAgaWYgKCFpbmNyKQ0KICAgICAgICBpbmNyID0gbWFzazsNCiAgICBmb3IgKDs7KSB7DQogICAgICAgIGkgPSAoaSArIGluY3IpICYgbWFzazsNCiAgICAgICAgdiA9IGNvZGVfaGFzaFtpXTsNCiAgICAgICAgaWYgKCF2KQ0KICAgICAgICAgICAgcmV0dXJuIDA7DQogICAgICAgIGlmIChfY21wbmFtZShzZWxmLCB2LCBuYW1lLCBuYW1lbGVuKSkgew0KICAgICAgICAgICAgKmNvZGUgPSB2Ow0KICAgICAgICAgICAgcmV0dXJuIDE7DQogICAgICAgIH0NCiAgICAgICAgaW5jciA9IGluY3IgPDwgMTsNCiAgICAgICAgaWYgKGluY3IgPiBtYXNrKQ0KICAgICAgICAgICAgaW5jciA9IGluY3IgXiBjb2RlX3BvbHk7DQogICAgfQ0KfQ0KDQpzdGF0aWMgY29uc3QgX1B5VW5pY29kZV9OYW1lX0NBUEkgaGFzaEFQSSA9DQp7DQogICAgc2l6ZW9mKF9QeVVuaWNvZGVfTmFtZV9DQVBJKSwNCiAgICBfZ2V0dWNuYW1lLA0KICAgIF9nZXRjb2RlDQp9Ow0KDQovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLw0KLyogUHl0aG9uIGJpbmRpbmdzICovDQoNClB5RG9jX1NUUlZBUih1bmljb2RlZGF0YV9uYW1lX19kb2NfXywNCiJuYW1lKHVuaWNoclssIGRlZmF1bHRdKVxuXA0KUmV0dXJucyB0aGUgbmFtZSBhc3NpZ25lZCB0byB0aGUgVW5pY29kZSBjaGFyYWN0ZXIgdW5pY2hyIGFzIGFcblwNCnN0cmluZy4gSWYgbm8gbmFtZSBpcyBkZWZpbmVkLCBkZWZhdWx0IGlzIHJldHVybmVkLCBvciwgaWYgbm90XG5cDQpnaXZlbiwgVmFsdWVFcnJvciBpcyByYWlzZWQuIik7DQoNCnN0YXRpYyBQeU9iamVjdCAqDQp1bmljb2RlZGF0YV9uYW1lKFB5T2JqZWN0KiBzZWxmLCBQeU9iamVjdCogYXJncykNCnsNCiAgICBjaGFyIG5hbWVbTkFNRV9NQVhMRU5dOw0KICAgIFB5X1VDUzQgYzsNCg0KICAgIFB5VW5pY29kZU9iamVjdCogdjsNCiAgICBQeU9iamVjdCogZGVmb2JqID0gTlVMTDsNCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hfE86bmFtZSIsICZQeVVuaWNvZGVfVHlwZSwgJnYsICZkZWZvYmopKQ0KICAgICAgICByZXR1cm4gTlVMTDsNCg0KICAgIGMgPSBnZXR1Y2hhcih2KTsNCiAgICBpZiAoYyA9PSAoUHlfVUNTNCktMSkNCiAgICAgICAgcmV0dXJuIE5VTEw7DQoNCiAgICBpZiAoIV9nZXR1Y25hbWUoc2VsZiwgYywgbmFtZSwgc2l6ZW9mKG5hbWUpKSkgew0KICAgICAgICBpZiAoZGVmb2JqID09IE5VTEwpIHsNCiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAibm8gc3VjaCBuYW1lIik7DQogICAgICAgICAgICByZXR1cm4gTlVMTDsNCiAgICAgICAgfQ0KICAgICAgICBlbHNlIHsNCiAgICAgICAgICAgIFB5X0lOQ1JFRihkZWZvYmopOw0KICAgICAgICAgICAgcmV0dXJuIGRlZm9iajsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIHJldHVybiBQeV9CdWlsZFZhbHVlKCJzIiwgbmFtZSk7DQp9DQoNClB5RG9jX1NUUlZBUih1bmljb2RlZGF0YV9sb29rdXBfX2RvY19fLA0KImxvb2t1cChuYW1lKVxuXA0KXG5cDQpMb29rIHVwIGNoYXJhY3RlciBieSBuYW1lLiAgSWYgYSBjaGFyYWN0ZXIgd2l0aCB0aGVcblwNCmdpdmVuIG5hbWUgaXMgZm91bmQsIHJldHVybiB0aGUgY29ycmVzcG9uZGluZyBVbmljb2RlXG5cDQpjaGFyYWN0ZXIuICBJZiBub3QgZm91bmQsIEtleUVycm9yIGlzIHJhaXNlZC4iKTsNCg0Kc3RhdGljIFB5T2JqZWN0ICoNCnVuaWNvZGVkYXRhX2xvb2t1cChQeU9iamVjdCogc2VsZiwgUHlPYmplY3QqIGFyZ3MpDQp7DQogICAgUHlfVUNTNCBjb2RlOw0KICAgIFB5X1VOSUNPREUgc3RyWzJdOw0KDQogICAgY2hhciogbmFtZTsNCiAgICBpbnQgbmFtZWxlbjsNCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInMjOmxvb2t1cCIsICZuYW1lLCAmbmFtZWxlbikpDQogICAgICAgIHJldHVybiBOVUxMOw0KDQogICAgaWYgKCFfZ2V0Y29kZShzZWxmLCBuYW1lLCBuYW1lbGVuLCAmY29kZSkpIHsNCiAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX0tleUVycm9yLCAidW5kZWZpbmVkIGNoYXJhY3RlciBuYW1lICclcyciLA0KICAgICAgICAgICAgICAgICAgICAgbmFtZSk7DQogICAgICAgIHJldHVybiBOVUxMOw0KICAgIH0NCg0KI2lmbmRlZiBQeV9VTklDT0RFX1dJREUNCiAgICBpZiAoY29kZSA+PSAweDEwMDAwKSB7DQogICAgICAgIHN0clswXSA9IDB4ZDgwMCArICgoY29kZSAtIDB4MTAwMDApID4+IDEwKTsNCiAgICAgICAgc3RyWzFdID0gMHhkYzAwICsgKChjb2RlIC0gMHgxMDAwMCkgJiAweDNmZik7DQogICAgICAgIHJldHVybiBQeVVuaWNvZGVfRnJvbVVuaWNvZGUoc3RyLCAyKTsNCiAgICB9DQojZW5kaWYNCiAgICBzdHJbMF0gPSAoUHlfVU5JQ09ERSkgY29kZTsNCiAgICByZXR1cm4gUHlVbmljb2RlX0Zyb21Vbmljb2RlKHN0ciwgMSk7DQp9DQoNCi8qIFhYWCBBZGQgZG9jIHN0cmluZ3MuICovDQoNCnN0YXRpYyBQeU1ldGhvZERlZiB1bmljb2RlZGF0YV9mdW5jdGlvbnNbXSA9IHsNCiAgICB7ImRlY2ltYWwiLCB1bmljb2RlZGF0YV9kZWNpbWFsLCBNRVRIX1ZBUkFSR1MsIHVuaWNvZGVkYXRhX2RlY2ltYWxfX2RvY19ffSwNCiAgICB7ImRpZ2l0IiwgdW5pY29kZWRhdGFfZGlnaXQsIE1FVEhfVkFSQVJHUywgdW5pY29kZWRhdGFfZGlnaXRfX2RvY19ffSwNCiAgICB7Im51bWVyaWMiLCB1bmljb2RlZGF0YV9udW1lcmljLCBNRVRIX1ZBUkFSR1MsIHVuaWNvZGVkYXRhX251bWVyaWNfX2RvY19ffSwNCiAgICB7ImNhdGVnb3J5IiwgdW5pY29kZWRhdGFfY2F0ZWdvcnksIE1FVEhfVkFSQVJHUywNCiAgICAgICAgICAgICAgICAgdW5pY29kZWRhdGFfY2F0ZWdvcnlfX2RvY19ffSwNCiAgICB7ImJpZGlyZWN0aW9uYWwiLCB1bmljb2RlZGF0YV9iaWRpcmVjdGlvbmFsLCBNRVRIX1ZBUkFSR1MsDQogICAgICAgICAgICAgICAgICAgICAgdW5pY29kZWRhdGFfYmlkaXJlY3Rpb25hbF9fZG9jX199LA0KICAgIHsiY29tYmluaW5nIiwgdW5pY29kZWRhdGFfY29tYmluaW5nLCBNRVRIX1ZBUkFSR1MsDQogICAgICAgICAgICAgICAgICB1bmljb2RlZGF0YV9jb21iaW5pbmdfX2RvY19ffSwNCiAgICB7Im1pcnJvcmVkIiwgdW5pY29kZWRhdGFfbWlycm9yZWQsIE1FVEhfVkFSQVJHUywNCiAgICAgICAgICAgICAgICAgdW5pY29kZWRhdGFfbWlycm9yZWRfX2RvY19ffSwNCiAgICB7ImVhc3RfYXNpYW5fd2lkdGgiLCB1bmljb2RlZGF0YV9lYXN0X2FzaWFuX3dpZHRoLCBNRVRIX1ZBUkFSR1MsDQogICAgICAgICAgICAgICAgICAgICAgICAgdW5pY29kZWRhdGFfZWFzdF9hc2lhbl93aWR0aF9fZG9jX199LA0KICAgIHsiZGVjb21wb3NpdGlvbiIsIHVuaWNvZGVkYXRhX2RlY29tcG9zaXRpb24sIE1FVEhfVkFSQVJHUywNCiAgICAgICAgICAgICAgICAgICAgICB1bmljb2RlZGF0YV9kZWNvbXBvc2l0aW9uX19kb2NfX30sDQogICAgeyJuYW1lIiwgdW5pY29kZWRhdGFfbmFtZSwgTUVUSF9WQVJBUkdTLCB1bmljb2RlZGF0YV9uYW1lX19kb2NfX30sDQogICAgeyJsb29rdXAiLCB1bmljb2RlZGF0YV9sb29rdXAsIE1FVEhfVkFSQVJHUywgdW5pY29kZWRhdGFfbG9va3VwX19kb2NfX30sDQogICAgeyJub3JtYWxpemUiLCB1bmljb2RlZGF0YV9ub3JtYWxpemUsIE1FVEhfVkFSQVJHUywNCiAgICAgICAgICAgICAgICAgIHVuaWNvZGVkYXRhX25vcm1hbGl6ZV9fZG9jX199LA0KICAgIHtOVUxMLCBOVUxMfSAgICAgICAgICAgICAgICAvKiBzZW50aW5lbCAqLw0KfTsNCg0Kc3RhdGljIFB5VHlwZU9iamVjdCBVQ0RfVHlwZSA9IHsNCiAgICAgICAgLyogVGhlIG9iX3R5cGUgZmllbGQgbXVzdCBiZSBpbml0aWFsaXplZCBpbiB0aGUgbW9kdWxlIGluaXQgZnVuY3Rpb24NCiAgICAgICAgICogdG8gYmUgcG9ydGFibGUgdG8gV2luZG93cyB3aXRob3V0IHVzaW5nIEMrKy4gKi8NCiAgICAgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKE5VTEwsIDApDQogICAgICAgICJ1bmljb2RlZGF0YS5VQ0QiLCAgICAgICAgICAgICAgLyp0cF9uYW1lKi8NCiAgICAgICAgc2l6ZW9mKFByZXZpb3VzREJWZXJzaW9uKSwgICAgICAvKnRwX2Jhc2ljc2l6ZSovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaXRlbXNpemUqLw0KICAgICAgICAvKiBtZXRob2RzICovDQogICAgICAgIChkZXN0cnVjdG9yKVB5T2JqZWN0X0RlbCwgLyp0cF9kZWFsbG9jKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9wcmludCovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZ2V0YXR0ciovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfc2V0YXR0ciovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY29tcGFyZSovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfcmVwciovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfbnVtYmVyKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hc19zZXF1ZW5jZSovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfbWFwcGluZyovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaGFzaCovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY2FsbCovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfc3RyKi8NCiAgICAgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsLyp0cF9nZXRhdHRybyovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfc2V0YXR0cm8qLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FzX2J1ZmZlciovDQogICAgICAgIFB5X1RQRkxBR1NfREVGQVVMVCwgICAgIC8qdHBfZmxhZ3MqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2RvYyovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfdHJhdmVyc2UqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2NsZWFyKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9yaWNoY29tcGFyZSovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfd2Vha2xpc3RvZmZzZXQqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2l0ZXIqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2l0ZXJuZXh0Ki8NCiAgICAgICAgdW5pY29kZWRhdGFfZnVuY3Rpb25zLCAgLyp0cF9tZXRob2RzKi8NCiAgICAgICAgREJfbWVtYmVycywgICAgICAgICAgICAgLyp0cF9tZW1iZXJzKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9nZXRzZXQqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Jhc2UqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2RpY3QqLw0KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Rlc2NyX2dldCovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGVzY3Jfc2V0Ki8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kaWN0b2Zmc2V0Ki8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pbml0Ki8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hbGxvYyovDQogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfbmV3Ki8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9mcmVlKi8NCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pc19nYyovDQp9Ow0KDQpQeURvY19TVFJWQVIodW5pY29kZWRhdGFfZG9jc3RyaW5nLA0KIlRoaXMgbW9kdWxlIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgVW5pY29kZSBDaGFyYWN0ZXIgRGF0YWJhc2Ugd2hpY2hcblwNCmRlZmluZXMgY2hhcmFjdGVyIHByb3BlcnRpZXMgZm9yIGFsbCBVbmljb2RlIGNoYXJhY3RlcnMuIFRoZSBkYXRhIGluXG5cDQp0aGlzIGRhdGFiYXNlIGlzIGJhc2VkIG9uIHRoZSBVbmljb2RlRGF0YS50eHQgZmlsZSB2ZXJzaW9uXG5cDQo1LjIuMCB3aGljaCBpcyBwdWJsaWNhbGx5IGF2YWlsYWJsZSBmcm9tIGZ0cDovL2Z0cC51bmljb2RlLm9yZy8uXG5cDQpcblwNClRoZSBtb2R1bGUgdXNlcyB0aGUgc2FtZSBuYW1lcyBhbmQgc3ltYm9scyBhcyBkZWZpbmVkIGJ5IHRoZVxuXA0KVW5pY29kZURhdGEgRmlsZSBGb3JtYXQgNS4yLjAgKHNlZVxuXA0KaHR0cDovL3d3dy51bmljb2RlLm9yZy9yZXBvcnRzL3RyNDQvdHI0NC00Lmh0bWwpLiIpOw0KDQpQeU1PRElOSVRfRlVOQw0KaW5pdHVuaWNvZGVkYXRhKHZvaWQpDQp7DQogICAgUHlPYmplY3QgKm0sICp2Ow0KDQogICAgUHlfVFlQRSgmVUNEX1R5cGUpID0gJlB5VHlwZV9UeXBlOw0KDQogICAgbSA9IFB5X0luaXRNb2R1bGUzKA0KICAgICAgICAidW5pY29kZWRhdGEiLCB1bmljb2RlZGF0YV9mdW5jdGlvbnMsIHVuaWNvZGVkYXRhX2RvY3N0cmluZyk7DQogICAgaWYgKCFtKQ0KICAgICAgICByZXR1cm47DQoNCiAgICBQeU1vZHVsZV9BZGRTdHJpbmdDb25zdGFudChtLCAidW5pZGF0YV92ZXJzaW9uIiwgVU5JREFUQV9WRVJTSU9OKTsNCiAgICBQeV9JTkNSRUYoJlVDRF9UeXBlKTsNCiAgICBQeU1vZHVsZV9BZGRPYmplY3QobSwgIlVDRCIsIChQeU9iamVjdCopJlVDRF9UeXBlKTsNCg0KICAgIC8qIFByZXZpb3VzIHZlcnNpb25zICovDQogICAgdiA9IG5ld19wcmV2aW91c192ZXJzaW9uKCIzLjIuMCIsIGdldF9jaGFuZ2VfM18yXzAsIG5vcm1hbGl6YXRpb25fM18yXzApOw0KICAgIGlmICh2ICE9IE5VTEwpDQogICAgICAgIFB5TW9kdWxlX0FkZE9iamVjdChtLCAidWNkXzNfMl8wIiwgdik7DQoNCiAgICAvKiBFeHBvcnQgQyBBUEkgKi8NCiAgICB2ID0gUHlDYXBzdWxlX05ldygodm9pZCAqKSZoYXNoQVBJLCBQeVVuaWNvZGVEYXRhX0NBUFNVTEVfTkFNRSwgTlVMTCk7DQogICAgaWYgKHYgIT0gTlVMTCkNCiAgICAgICAgUHlNb2R1bGVfQWRkT2JqZWN0KG0sICJ1Y25oYXNoX0NBUEkiLCB2KTsNCn0NCg0KLyoNCkxvY2FsIHZhcmlhYmxlczoNCmMtYmFzaWMtb2Zmc2V0OiA0DQppbmRlbnQtdGFicy1tb2RlOiBuaWwNCkVuZDoNCiovDQo=