LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQogKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovLyBNQVJLRVIodXBkYXRlX3ByZWNvbXAucHkpOiBhdXRvZ2VuIGluY2x1ZGUgc3RhdGVtZW50LCBkbyBub3QgcmVtb3ZlCiNpbmNsdWRlICJwcmVjb21waWxlZF9jbGlfdXJlLmh4eCIKCiNwcmFnbWEgd2FybmluZyhwdXNoLCAxKQojaW5jbHVkZSAid2luZG93cy5oIgojcHJhZ21hIHdhcm5pbmcocG9wKQoKI2luY2x1ZGUgPG1lbW9yeT4KCgojaW5jbHVkZSAicnRsL3VzdHJpbmcuaHh4IgojaW5jbHVkZSAicnRsL3VzdHJidWYuaHh4IgojaW5jbHVkZSAidW5vL3NlcXVlbmNlMi5oIgojaW5jbHVkZSAidHlwZWxpYi90eXBlZGVzY3JpcHRpb24uaHh4IgojaW5jbHVkZSAiY2xpX3Byb3h5LmgiCiNpbmNsdWRlICJjbGlfYmFzZS5oIgojaW5jbHVkZSAiY2xpX2JyaWRnZS5oIgoKI3VzaW5nIDxjbGlfdXJldHlwZXMuZGxsPgoKCiN1bmRlZiBWT0lECgpuYW1lc3BhY2UgY3NzID0gY29tOjpzdW46OnN0YXI7CgpuYW1lc3BhY2Ugc3JpID0gU3lzdGVtOjpSdW50aW1lOjpJbnRlcm9wU2VydmljZXM7Cm5hbWVzcGFjZSBzciA9IFN5c3RlbTo6UmVmbGVjdGlvbjsKbmFtZXNwYWNlIHN0ID0gU3lzdGVtOjpUZXh0OwpuYW1lc3BhY2UgdWNzcyA9IHVub2lkbDo6Y29tOjpzdW46OnN0YXI7Cgp1c2luZyBuYW1lc3BhY2UgcnRsOwp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKCm5hbWVzcGFjZSBjbGlfdW5vCnsKU3lzdGVtOjpTdHJpbmcqIG1hcFVub1BvbHltb3JwaGljTmFtZShTeXN0ZW06OlN0cmluZyogdW5vTmFtZSk7Ck9VU3RyaW5nIG1hcENsaVR5cGVOYW1lKFN5c3RlbTo6U3RyaW5nKiB0eXBlTmFtZSk7ClN5c3RlbTo6U3RyaW5nKiBtYXBDbGlQb2x5bW9ycGhpY05hbWUoU3lzdGVtOjpTdHJpbmcqIHVub05hbWUpOwpTeXN0ZW06OlN0cmluZyogbWFwUG9seW1vcnBoaWNOYW1lKFN5c3RlbTo6U3RyaW5nKiB1bm9OYW1lLCBib29sIGJDbGlUb1Vubyk7CgppbmxpbmUgYXV0b19wdHI8IHJ0bF9tZW0gPiBzZXFfYWxsb2NhdGUoIHNhbF9JbnQzMiBuRWxlbWVudHMsIHNhbF9JbnQzMiBuU2l6ZSApCnsKICAgIGF1dG9fcHRyPCBydGxfbWVtID4gc2VxKAogICAgICAgIHJ0bF9tZW06OmFsbG9jYXRlKCBTQUxfU0VRVUVOQ0VfSEVBREVSX1NJWkUgKyAobkVsZW1lbnRzICogblNpemUpICkgKTsKICAgIHVub19TZXF1ZW5jZSAqIHAgPSAodW5vX1NlcXVlbmNlICopc2VxLmdldCgpOwogICAgcC0+blJlZkNvdW50ID0gMTsKICAgIHAtPm5FbGVtZW50cyA9IG5FbGVtZW50czsKICAgIHJldHVybiBzZXE7Cn0KCgpTeXN0ZW06Ok9iamVjdCogQnJpZGdlOjptYXBfdW5vMmNsaSh1bm9fSW50ZXJmYWNlICogcFVub0ksIHR5cGVsaWJfSW50ZXJmYWNlVHlwZURlc2NyaXB0aW9uICpwVEQpIGNvbnN0CnsKICAgIFN5c3RlbTo6T2JqZWN0KiByZXRWYWw9IE5VTEw7Ci8vIGdldCBvaWQKICAgIHJ0bF91U3RyaW5nICogcE9pZCA9IDA7CiAgICAoKm1fdW5vX2Vudi0+Z2V0T2JqZWN0SWRlbnRpZmllcikoIG1fdW5vX2VudiwgJnBPaWQsIHBVbm9JICk7CiAgICBPU0xfQVNTRVJUKCAwICE9IHBPaWQgKTsKICAgIE9VU3RyaW5nIG9pZChwT2lkLCBTQUxfTk9fQUNRVUlSRSk7CgoJLy9zZWUgaWYgdGhlIGludGVyZmFjZSB3YXMgYWxyZWFkeSBtYXBwZWQKICAgIFN5c3RlbTo6VHlwZSogaWZhY2VUeXBlPSBtYXBVbm9UeXBlKHJlaW50ZXJwcmV0X2Nhc3Q8dHlwZWxpYl9UeXBlRGVzY3JpcHRpb24qPihwVEQpKTsKICAgIFN5c3RlbTo6U3RyaW5nKiBzT2lkPSBtYXBVbm9TdHJpbmcob2lkLnBEYXRhKTsKCglTeXN0ZW06OlRocmVhZGluZzo6TW9uaXRvcjo6RW50ZXIoIENsaUVudkhvbGRlcjo6Z19jbGlfZW52ICk7CiAgICB0cnkKICAgIHsKCQlyZXRWYWwgPSBDbGlFbnZIb2xkZXI6OmdfY2xpX2Vudi0+Z2V0UmVnaXN0ZXJlZEludGVyZmFjZShzT2lkLCBpZmFjZVR5cGUpOwogICAgICAgIGlmIChyZXRWYWwpCiAgICAgICAgewogICAgICAgICAgICAvLyBUaGVyZSBpcyBhbHJlYWR5IGFuIHJlZ2lzdGVyZWQgb2JqZWN0LiBJdCBjYW4gZWl0aGVyIGJlIGEgcHJveHkKICAgICAgICAgICAgLy8gZm9yIHRoZSBVTk8gb2JqZWN0IG9yIGEgcmVhbCBjbGkgb2JqZWN0LiBJbiB0aGUgZmlyc3QgY2FzZSB3ZQogICAgICAgICAgICAvLyB0ZWxsIHRoZSBwcm94eSB0aGF0IGl0IHNoYWxsIGFsc28gcmVwcmVzZW50IHRoZSBjdXJyZW50IFVOTwogICAgICAgICAgICAvLyBpbnRlcmZhY2UuIElmIGl0IGFscmVhZHkgZG9lcyB0aGF0LCB0aGVuIGl0IGRvZXMgbm90aGluZwogICAgICAgICAgICBpZiAoc3JyOjpSZW1vdGluZ1NlcnZpY2VzOjpJc1RyYW5zcGFyZW50UHJveHkocmV0VmFsKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVW5vSW50ZXJmYWNlUHJveHkqIHAgPSBzdGF0aWNfY2FzdDxVbm9JbnRlcmZhY2VQcm94eSo+KAogICAgICAgICAgICAgICAgICAgIHNycjo6UmVtb3RpbmdTZXJ2aWNlczo6R2V0UmVhbFByb3h5KHJldFZhbCkpOwogICAgICAgICAgICAgICAgcC0+YWRkVW5vSW50ZXJmYWNlKHBVbm9JLCBwVEQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldFZhbCA9IFVub0ludGVyZmFjZVByb3h5OjpjcmVhdGUoCiAgICAgICAgICAgICAgICAoQnJpZGdlICopIHRoaXMsIHBVbm9JLCBwVEQsIG9pZCApOwogICAgICAgIH0KICAgIH0KICAgIF9fZmluYWxseQogICAgewoJCVN5c3RlbTo6VGhyZWFkaW5nOjpNb25pdG9yOjpFeGl0KCBDbGlFbnZIb2xkZXI6OmdfY2xpX2VudiApOwogICAgfQoKICAgIHJldHVybiByZXRWYWw7Cn0KCnVub19JbnRlcmZhY2UqIEJyaWRnZTo6bWFwX2NsaTJ1bm8oU3lzdGVtOjpPYmplY3QqIGNsaU9iaiwgdHlwZWxpYl9UeXBlRGVzY3JpcHRpb24gKnBURCkgY29uc3QKewogICAgdW5vX0ludGVyZmFjZSogcmV0SWZhY2UgPSBOVUxMOwogICAgLy8gZ2V0IG9pZCBmcm9tIGRvdCBuZXQgZW52aXJvbm1lbnQKCVN5c3RlbTo6U3RyaW5nKiBkc19vaWQgPSBDbGlFbnZIb2xkZXI6OmdfY2xpX2Vudi0+Z2V0T2JqZWN0SWRlbnRpZmllciggY2xpT2JqKTsKICAgIE9VU3RyaW5nIG91c09pZCA9IG1hcENsaVN0cmluZyhkc19vaWQpOwogICAgLy8gbG9vayBpZiBpbnRlcmZhY2UgaXMgYWxyZWFkeSBtYXBwZWQKICAgIG1fdW5vX2Vudi0+Z2V0UmVnaXN0ZXJlZEludGVyZmFjZShtX3Vub19lbnYsICh2b2lkKiopICZyZXRJZmFjZSwgb3VzT2lkLnBEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0eXBlbGliX0ludGVyZmFjZVR5cGVEZXNjcmlwdGlvbiopIHBURCk7CiAgICBpZiAoICEgcmV0SWZhY2UpCiAgICB7CiAgICAgICAgU3lzdGVtOjpUaHJlYWRpbmc6Ok1vbml0b3I6OkVudGVyKF9fdHlwZW9mKENsaV9lbnZpcm9ubWVudCkpOwogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgbV91bm9fZW52LT5nZXRSZWdpc3RlcmVkSW50ZXJmYWNlKG1fdW5vX2VudiwgKHZvaWQqKikgJnJldElmYWNlLCBvdXNPaWQucERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHR5cGVsaWJfSW50ZXJmYWNlVHlwZURlc2NyaXB0aW9uKikgcFREKTsKICAgICAgICAgICAgaWYgKCAhIHJldElmYWNlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXRJZmFjZSA9IENsaVByb3h5OjpjcmVhdGUoKEJyaWRnZSopdGhpcywgY2xpT2JqLCBwVEQsIG91c09pZCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgX19maW5hbGx5CiAgICAgICAgewogICAgICAgICAgICBTeXN0ZW06OlRocmVhZGluZzo6TW9uaXRvcjo6RXhpdChfX3R5cGVvZihDbGlfZW52aXJvbm1lbnQpKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gcmV0SWZhY2U7Cn0KCmlubGluZSBTeXN0ZW06OlR5cGUqIGxvYWRDbGlUeXBlKHJ0bF91U3RyaW5nICogdW5vTmFtZSkKewogICAgIHJldHVybiBsb2FkQ2xpVHlwZShtYXBVbm9UeXBlTmFtZSh1bm9OYW1lKSk7Cn0KClN5c3RlbTo6VHlwZSogbG9hZENsaVR5cGUoU3lzdGVtOjpTdHJpbmcgKiB1bm9OYW1lKQp7CiAgICBTeXN0ZW06OlR5cGUqIHJldFZhbD0gTlVMTDsKICAgIHRyeQogICAgewogICAgICAgIC8vSWYgdW5vTmFtZSBkZW5vdGVzIGEgcG9seW1vcnBoaWMgdHlwZSwgZS5nIGNvbS5zdW4uc3Rhci5iZWFucy5EZWZhdWx0ZWQ8U3lzdGVtLkNoYXI+CiAgICAgICAgLy90aGVuIHdlIHJlbW92ZSB0aGUgdHlwZSBsaXN0LCBvdGhlcndpc2UgdGhlIHR5cGUgY291bGQgbm90IGJlIGxvYWRlZC4KICAgICAgICBib29sIGJJc1BvbHltb3JwaGljID0gZmFsc2U7CgogICAgICAgIFN5c3RlbTo6U3RyaW5nICogbG9hZE5hbWUgPSB1bm9OYW1lOwogICAgICAgIGludCBpbmRleCA9IHVub05hbWUtPkluZGV4T2YoJzwnKTsKICAgICAgICBpZiAoaW5kZXggIT0gLTEpCiAgICAgICAgewogICAgICAgICAgICBsb2FkTmFtZSA9IHVub05hbWUtPlN1YnN0cmluZygwLCBpbmRleCk7CiAgICAgICAgICAgIGJJc1BvbHltb3JwaGljID0gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgU3lzdGVtOjpBcHBEb21haW4qICBjdXJyZW50RG9tYWluID0gU3lzdGVtOjpBcHBEb21haW46OkN1cnJlbnREb21haW47CiAgICAgICAgc3I6OkFzc2VtYmx5KiAgYXNzZW1zW10gPSBjdXJyZW50RG9tYWluLT5HZXRBc3NlbWJsaWVzKCk7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhc3NlbXMtPkxlbmd0aDsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgcmV0VmFsID0gYXNzZW1zW2ldLT5HZXRUeXBlKGxvYWROYW1lLCBmYWxzZSk7CiAgICAgICAgICAgIGlmIChyZXRWYWwpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgoJCWlmIChyZXRWYWwgPT0gTlVMTCkKCQl7CiAgICAgICAgICAgIFN5c3RlbTo6U3RyaW5nICogbXNnID0gbmV3IFN5c3RlbTo6U3RyaW5nKFMiQSB0eXBlIGNvdWxkIG5vdCBiZSBsb2FkZWQ6ICIpOwogICAgICAgICAgICBtc2cgPSBTeXN0ZW06OlN0cmluZzo6Q29uY2F0KG1zZywgbG9hZE5hbWUpOwoJCQl0aHJvdyBCcmlkZ2VSdW50aW1lRXJyb3IobWFwQ2xpU3RyaW5nKG1zZykpOwoJCX0KCiAgICAgICAgaWYgKGJJc1BvbHltb3JwaGljKQogICAgICAgIHsKICAgICAgICAgICAgcmV0VmFsID0gdW5vOjpQb2x5bW9ycGhpY1R5cGU6OkdldFR5cGUocmV0VmFsLCB1bm9OYW1lKTsKICAgICAgICB9CiAgICB9CiAgICBjYXRjaCggU3lzdGVtOjpFeGNlcHRpb24gKiBlKQogICAgewogICAgICAgIHJ0bDo6T1VTdHJpbmcgb3VNZXNzYWdlKG1hcENsaVN0cmluZyhlLT5nZXRfTWVzc2FnZSgpKSk7CiAgICAgICAgdGhyb3cgQnJpZGdlUnVudGltZUVycm9yKG91TWVzc2FnZSk7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgoKU3lzdGVtOjpUeXBlKiBtYXBVbm9UeXBlKHR5cGVsaWJfVHlwZURlc2NyaXB0aW9uIGNvbnN0ICogcFREKQp7CiAgICByZXR1cm4gbWFwVW5vVHlwZShwVEQtPnBXZWFrUmVmKTsKfQoKU3lzdGVtOjpUeXBlKiBtYXBVbm9UeXBlKHR5cGVsaWJfVHlwZURlc2NyaXB0aW9uUmVmZXJlbmNlIGNvbnN0ICogcFREKQp7CiAgICBTeXN0ZW06OlR5cGUgKiByZXRWYWwgPSAwOwogICAgc3dpdGNoIChwVEQtPmVUeXBlQ2xhc3MpCiAgICB7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1ZPSUQ6CiAgICAgICAgcmV0VmFsPSBfX3R5cGVvZih2b2lkKTsgYnJlYWs7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0NIQVI6CiAgICAgICAgcmV0VmFsPSBfX3R5cGVvZihTeXN0ZW06OkNoYXIpOyBicmVhazsKICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQk9PTEVBTjoKICAgICAgICByZXRWYWw9IF9fdHlwZW9mKFN5c3RlbTo6Qm9vbGVhbik7IGJyZWFrOwogICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19CWVRFOgogICAgICAgIHJldFZhbD0gX190eXBlb2YoU3lzdGVtOjpCeXRlKTsgYnJlYWs7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NIT1JUOgogICAgICAgIHJldFZhbD0gX190eXBlb2YoU3lzdGVtOjpJbnQxNik7IGJyZWFrOwogICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19VTlNJR05FRF9TSE9SVDoKICAgICAgICByZXRWYWw9IF9fdHlwZW9mKFN5c3RlbTo6VUludDE2KTsgYnJlYWs7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0xPTkc6CiAgICAgICAgcmV0VmFsPSBfX3R5cGVvZihTeXN0ZW06OkludDMyKTsgYnJlYWs7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1VOU0lHTkVEX0xPTkc6CiAgICAgICAgcmV0VmFsPSBfX3R5cGVvZihTeXN0ZW06OlVJbnQzMik7IGJyZWFrOwogICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19IWVBFUjoKICAgICAgICByZXRWYWw9IF9fdHlwZW9mKFN5c3RlbTo6SW50NjQpOyBicmVhazsKICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfVU5TSUdORURfSFlQRVI6CiAgICAgICAgcmV0VmFsPSBfX3R5cGVvZihTeXN0ZW06OlVJbnQ2NCk7IGJyZWFrOwogICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19GTE9BVDoKICAgICAgICByZXRWYWw9IF9fdHlwZW9mKFN5c3RlbTo6U2luZ2xlKTsgYnJlYWs7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0RPVUJMRToKICAgICAgICByZXRWYWw9IF9fdHlwZW9mKFN5c3RlbTo6RG91YmxlKTsgYnJlYWs7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NUUklORzoKICAgICAgICByZXRWYWw9IF9fdHlwZW9mKFN5c3RlbTo6U3RyaW5nKTsgYnJlYWs7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1RZUEU6CiAgICAgICAgcmV0VmFsPSBfX3R5cGVvZihTeXN0ZW06OlR5cGUpOyBicmVhazsKICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQU5ZOgogICAgICAgIHJldFZhbD0gX190eXBlb2YodW5vOjpBbnkpOyBicmVhazsKICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRU5VTToKICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfU1RSVUNUOgogICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19FWENFUFRJT046CiAgICAgICAgcmV0VmFsPSBsb2FkQ2xpVHlwZShwVEQtPnBUeXBlTmFtZSk7IGJyZWFrOwogICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19JTlRFUkZBQ0U6CiAgICB7CiAgICAgICAgLy9zcGVjaWFsIGhhbmRsaW5nIGZvciBYSW50ZXJmYWNlLCBzaW5jZSBpdCBkb2VzIG5vdCBleGlzdCBpbiBjbGkuCgkJcnRsOjpPVVN0cmluZyB1c1hJbnRlcmZhY2UoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJjb20uc3VuLnN0YXIudW5vLlhJbnRlcmZhY2UiKSk7CgkJaWYgKHVzWEludGVyZmFjZS5lcXVhbHMocFRELT5wVHlwZU5hbWUpKQoJCQlyZXRWYWw9IF9fdHlwZW9mKFN5c3RlbTo6T2JqZWN0KTsKCQllbHNlCiAgICAgICAgICAgIHJldFZhbD0gbG9hZENsaVR5cGUocFRELT5wVHlwZU5hbWUpOwogICAgICAgIGJyZWFrOwogICAgfQogICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19TRVFVRU5DRToKICAgIHsKICAgICAgICBjc3M6OnVubzo6VHlwZURlc2NyaXB0aW9uIHNlcVR5cGUoCiAgICAgICAgICAgIGNvbnN0X2Nhc3Q8dHlwZWxpYl9UeXBlRGVzY3JpcHRpb25SZWZlcmVuY2UqPihwVEQpKTsKICAgICAgICB0eXBlbGliX1R5cGVEZXNjcmlwdGlvblJlZmVyZW5jZSogcEVsZW1lbnRURFJlZj0KICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDx0eXBlbGliX0luZGlyZWN0VHlwZURlc2NyaXB0aW9uKj4oc2VxVHlwZS5nZXQoKSktPnBUeXBlOwogICAgICAgIHN3aXRjaCAocEVsZW1lbnRURFJlZi0+ZVR5cGVDbGFzcykKICAgICAgICB7CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19DSEFSOgogICAgICAgICAgICByZXRWYWw9IFN5c3RlbTo6VHlwZTo6R2V0VHlwZShjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzQXJDaGFyKSk7IGJyZWFrOwogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQk9PTEVBTjoKICAgICAgICAgICAgcmV0VmFsPSBTeXN0ZW06OlR5cGU6OkdldFR5cGUoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c0FyQm9vbGVhbikpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0JZVEU6CiAgICAgICAgICAgIHJldFZhbD0gU3lzdGVtOjpUeXBlOjpHZXRUeXBlKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnNBckJ5dGUpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19TSE9SVDoKICAgICAgICAgICAgcmV0VmFsPSBTeXN0ZW06OlR5cGU6OkdldFR5cGUoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c0FySW50MTYpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19VTlNJR05FRF9TSE9SVDoKICAgICAgICAgICAgcmV0VmFsPSBTeXN0ZW06OlR5cGU6OkdldFR5cGUoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c0FyVUludDE2KSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfTE9ORzoKICAgICAgICAgICAgcmV0VmFsPSBTeXN0ZW06OlR5cGU6OkdldFR5cGUoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c0FySW50MzIpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19VTlNJR05FRF9MT05HOgogICAgICAgICAgICByZXRWYWw9IFN5c3RlbTo6VHlwZTo6R2V0VHlwZShjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzQXJVSW50MzIpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19IWVBFUjoKICAgICAgICAgICAgcmV0VmFsPSBTeXN0ZW06OlR5cGU6OkdldFR5cGUoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c0FySW50NjQpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19VTlNJR05FRF9IWVBFUjoKICAgICAgICAgICAgcmV0VmFsPSBTeXN0ZW06OlR5cGU6OkdldFR5cGUoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c0FyVUludDY0KSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRkxPQVQ6CiAgICAgICAgICAgIHJldFZhbD0gU3lzdGVtOjpUeXBlOjpHZXRUeXBlKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnNBclNpbmdsZSkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0RPVUJMRToKICAgICAgICAgICAgcmV0VmFsPSBTeXN0ZW06OlR5cGU6OkdldFR5cGUoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c0FyRG91YmxlKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfU1RSSU5HOgogICAgICAgICAgICByZXRWYWw9IFN5c3RlbTo6VHlwZTo6R2V0VHlwZShjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzQXJTdHJpbmcpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19UWVBFOgogICAgICAgICAgICByZXRWYWw9IFN5c3RlbTo6VHlwZTo6R2V0VHlwZShjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzQXJUeXBlKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQU5ZOgogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRU5VTToKICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0VYQ0VQVElPTjoKICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NUUlVDVDoKICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0lOVEVSRkFDRToKICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NFUVVFTkNFOgogICAgICAgIHsKICAgICAgICAgICAgcmV0VmFsPSBsb2FkQ2xpVHlwZShwVEQtPnBUeXBlTmFtZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAvL0FsbCBjYXNlcyBzaG91bGQgYmUgaGFuZGxlZCBieSB0aGUgY2FzZSBzdGF0ZW1lbnRzIGFib3ZlCiAgICAgICAgICAgIE9TTF9BU1NFUlQoMCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KICAgIGRlZmF1bHQ6CiAgICAgICAgT1NMX0FTU0VSVChmYWxzZSk7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgovKiogUmV0dXJucyBhbiBhY3F1aXJlZCB0ZC4KICovCnR5cGVsaWJfVHlwZURlc2NyaXB0aW9uUmVmZXJlbmNlKiBtYXBDbGlUeXBlKFN5c3RlbTo6VHlwZSogY2xpVHlwZSkKewogICAgdHlwZWxpYl9UeXBlRGVzY3JpcHRpb25SZWZlcmVuY2UqIHJldFZhbD0gTlVMTDsKICAgIGlmIChjbGlUeXBlID09IE5VTEwpCiAgICB7CiAgICAgICAgcmV0VmFsID0gKiB0eXBlbGliX3N0YXRpY190eXBlX2dldEJ5VHlwZUNsYXNzKAogICAgICAgICAgICB0eXBlbGliX1R5cGVDbGFzc19WT0lEICk7CiAgICAgICAgdHlwZWxpYl90eXBlZGVzY3JpcHRpb25yZWZlcmVuY2VfYWNxdWlyZSggcmV0VmFsICk7CiAgICAgICAgcmV0dXJuIHJldFZhbDsKICAgIH0KICAgIC8vY2hlY2sgZm9yIEVudW0gZmlyc3QsCiAgICAvL2JlY2F1c2Ugb3RoZXJ3aXNlIGNhc2UgU3lzdGVtOjpUeXBlQ29kZTo6SW50MzIgYXBwbGllcwogICAgaWYgKGNsaVR5cGUtPmdldF9Jc0VudW0oKSkKICAgIHsKICAgICAgICBPVVN0cmluZyB1c1R5cGVOYW1lPSBtYXBDbGlUeXBlTmFtZShjbGlUeXBlLT5nZXRfRnVsbE5hbWUoKSk7CiAgICAgICAgY3NzOjp1bm86OlR5cGUgdW5vVHlwZShjc3M6OnVubzo6VHlwZUNsYXNzX0VOVU0sIHVzVHlwZU5hbWUpOwogICAgICAgIHJldFZhbD0gdW5vVHlwZS5nZXRUeXBlTGliVHlwZSgpOwogICAgICAgIHR5cGVsaWJfdHlwZWRlc2NyaXB0aW9ucmVmZXJlbmNlX2FjcXVpcmUocmV0VmFsKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzd2l0Y2ggKFN5c3RlbTo6VHlwZTo6R2V0VHlwZUNvZGUoY2xpVHlwZSkpCiAgICAgICAgewogICAgICAgIGNhc2UgU3lzdGVtOjpUeXBlQ29kZTo6Qm9vbGVhbjoKICAgICAgICAgICAgcmV0VmFsID0gKiB0eXBlbGliX3N0YXRpY190eXBlX2dldEJ5VHlwZUNsYXNzKAogICAgICAgICAgICAgICAgdHlwZWxpYl9UeXBlQ2xhc3NfQk9PTEVBTiApOwogICAgICAgICAgICB0eXBlbGliX3R5cGVkZXNjcmlwdGlvbnJlZmVyZW5jZV9hY3F1aXJlKCByZXRWYWwgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBTeXN0ZW06OlR5cGVDb2RlOjpDaGFyOgogICAgICAgICAgICByZXRWYWwgPSAqIHR5cGVsaWJfc3RhdGljX3R5cGVfZ2V0QnlUeXBlQ2xhc3MoCiAgICAgICAgICAgICAgICB0eXBlbGliX1R5cGVDbGFzc19DSEFSICk7CiAgICAgICAgICAgIHR5cGVsaWJfdHlwZWRlc2NyaXB0aW9ucmVmZXJlbmNlX2FjcXVpcmUoIHJldFZhbCApOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFN5c3RlbTo6VHlwZUNvZGU6OkJ5dGU6CiAgICAgICAgICAgIHJldFZhbCA9ICogdHlwZWxpYl9zdGF0aWNfdHlwZV9nZXRCeVR5cGVDbGFzcygKICAgICAgICAgICAgICAgIHR5cGVsaWJfVHlwZUNsYXNzX0JZVEUgKTsKICAgICAgICAgICAgdHlwZWxpYl90eXBlZGVzY3JpcHRpb25yZWZlcmVuY2VfYWNxdWlyZSggcmV0VmFsICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgU3lzdGVtOjpUeXBlQ29kZTo6SW50MTY6CiAgICAgICAgICAgIHJldFZhbCA9ICogdHlwZWxpYl9zdGF0aWNfdHlwZV9nZXRCeVR5cGVDbGFzcygKICAgICAgICAgICAgICAgIHR5cGVsaWJfVHlwZUNsYXNzX1NIT1JUICk7CiAgICAgICAgICAgIHR5cGVsaWJfdHlwZWRlc2NyaXB0aW9ucmVmZXJlbmNlX2FjcXVpcmUoIHJldFZhbCApOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFN5c3RlbTo6VHlwZUNvZGU6OkludDMyOgogICAgICAgICAgICByZXRWYWwgPSAqIHR5cGVsaWJfc3RhdGljX3R5cGVfZ2V0QnlUeXBlQ2xhc3MoCiAgICAgICAgICAgICAgICB0eXBlbGliX1R5cGVDbGFzc19MT05HICk7CiAgICAgICAgICAgIHR5cGVsaWJfdHlwZWRlc2NyaXB0aW9ucmVmZXJlbmNlX2FjcXVpcmUoIHJldFZhbCApOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFN5c3RlbTo6VHlwZUNvZGU6OkludDY0OgogICAgICAgICAgICByZXRWYWwgPSAqIHR5cGVsaWJfc3RhdGljX3R5cGVfZ2V0QnlUeXBlQ2xhc3MoCiAgICAgICAgICAgICAgICB0eXBlbGliX1R5cGVDbGFzc19IWVBFUiApOwogICAgICAgICAgICB0eXBlbGliX3R5cGVkZXNjcmlwdGlvbnJlZmVyZW5jZV9hY3F1aXJlKCByZXRWYWwgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBTeXN0ZW06OlR5cGVDb2RlOjpVSW50MTY6CiAgICAgICAgICAgIHJldFZhbCA9ICogdHlwZWxpYl9zdGF0aWNfdHlwZV9nZXRCeVR5cGVDbGFzcygKICAgICAgICAgICAgICAgIHR5cGVsaWJfVHlwZUNsYXNzX1VOU0lHTkVEX1NIT1JUICk7CiAgICAgICAgICAgIHR5cGVsaWJfdHlwZWRlc2NyaXB0aW9ucmVmZXJlbmNlX2FjcXVpcmUoIHJldFZhbCApOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFN5c3RlbTo6VHlwZUNvZGU6OlVJbnQzMjoKICAgICAgICAgICAgcmV0VmFsID0gKiB0eXBlbGliX3N0YXRpY190eXBlX2dldEJ5VHlwZUNsYXNzKAogICAgICAgICAgICAgICAgdHlwZWxpYl9UeXBlQ2xhc3NfVU5TSUdORURfTE9ORyApOwogICAgICAgICAgICB0eXBlbGliX3R5cGVkZXNjcmlwdGlvbnJlZmVyZW5jZV9hY3F1aXJlKCByZXRWYWwgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBTeXN0ZW06OlR5cGVDb2RlOjpVSW50NjQ6CiAgICAgICAgICAgIHJldFZhbCA9ICogdHlwZWxpYl9zdGF0aWNfdHlwZV9nZXRCeVR5cGVDbGFzcygKICAgICAgICAgICAgICAgIHR5cGVsaWJfVHlwZUNsYXNzX1VOU0lHTkVEX0hZUEVSICk7CiAgICAgICAgICAgIHR5cGVsaWJfdHlwZWRlc2NyaXB0aW9ucmVmZXJlbmNlX2FjcXVpcmUoIHJldFZhbCApOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFN5c3RlbTo6VHlwZUNvZGU6OlNpbmdsZToKICAgICAgICAgICAgcmV0VmFsID0gKiB0eXBlbGliX3N0YXRpY190eXBlX2dldEJ5VHlwZUNsYXNzKAogICAgICAgICAgICAgICAgdHlwZWxpYl9UeXBlQ2xhc3NfRkxPQVQgKTsKICAgICAgICAgICAgdHlwZWxpYl90eXBlZGVzY3JpcHRpb25yZWZlcmVuY2VfYWNxdWlyZSggcmV0VmFsICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgU3lzdGVtOjpUeXBlQ29kZTo6RG91YmxlOgogICAgICAgICAgICByZXRWYWwgPSAqIHR5cGVsaWJfc3RhdGljX3R5cGVfZ2V0QnlUeXBlQ2xhc3MoCiAgICAgICAgICAgICAgICB0eXBlbGliX1R5cGVDbGFzc19ET1VCTEUgKTsKICAgICAgICAgICAgdHlwZWxpYl90eXBlZGVzY3JpcHRpb25yZWZlcmVuY2VfYWNxdWlyZSggcmV0VmFsICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgU3lzdGVtOjpUeXBlQ29kZTo6U3RyaW5nOgogICAgICAgICAgICByZXRWYWwgPSAqIHR5cGVsaWJfc3RhdGljX3R5cGVfZ2V0QnlUeXBlQ2xhc3MoCiAgICAgICAgICAgICAgICB0eXBlbGliX1R5cGVDbGFzc19TVFJJTkcgKTsKICAgICAgICAgICAgdHlwZWxpYl90eXBlZGVzY3JpcHRpb25yZWZlcmVuY2VfYWNxdWlyZSggcmV0VmFsICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIGlmIChyZXRWYWwgPT0gTlVMTCkKICAgIHsKICAgICAgICBTeXN0ZW06OlN0cmluZyogY2xpVHlwZU5hbWU9IGNsaVR5cGUtPmdldF9GdWxsTmFtZSgpOwogICAgICAgIC8vIFZvaWQKICAgICAgICBpZiAoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c1ZvaWQpLT5FcXVhbHMoCiAgICAgICAgICAgICAgICBjbGlUeXBlTmFtZSkpCiAgICAgICAgewogICAgICAgICAgICByZXRWYWwgPSAqIHR5cGVsaWJfc3RhdGljX3R5cGVfZ2V0QnlUeXBlQ2xhc3MoCiAgICAgICAgICAgICAgICB0eXBlbGliX1R5cGVDbGFzc19WT0lEICk7CiAgICAgICAgICAgIHR5cGVsaWJfdHlwZWRlc2NyaXB0aW9ucmVmZXJlbmNlX2FjcXVpcmUoIHJldFZhbCApOwogICAgICAgIH0KICAgICAgICAvLyBUeXBlCiAgICAgICAgZWxzZSBpZiAoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c1R5cGUpLT5FcXVhbHMoCiAgICAgICAgICAgICAgICAgICAgIGNsaVR5cGVOYW1lKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldFZhbCA9ICogdHlwZWxpYl9zdGF0aWNfdHlwZV9nZXRCeVR5cGVDbGFzcygKICAgICAgICAgICAgICAgIHR5cGVsaWJfVHlwZUNsYXNzX1RZUEUgKTsKICAgICAgICAgICAgdHlwZWxpYl90eXBlZGVzY3JpcHRpb25yZWZlcmVuY2VfYWNxdWlyZSggcmV0VmFsICk7CiAgICAgICAgfQogICAgICAgIC8vIEFueQogICAgICAgIGVsc2UgaWYgKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnNBbnkpLT5FcXVhbHMoCiAgICAgICAgICAgICAgICAgICAgIGNsaVR5cGVOYW1lKSkKICAgICAgICB7CiAgICAgICAgICAgIHJldFZhbCA9ICogdHlwZWxpYl9zdGF0aWNfdHlwZV9nZXRCeVR5cGVDbGFzcygKICAgICAgICAgICAgICAgIHR5cGVsaWJfVHlwZUNsYXNzX0FOWSApOwogICAgICAgICAgICB0eXBlbGliX3R5cGVkZXNjcmlwdGlvbnJlZmVyZW5jZV9hY3F1aXJlKCByZXRWYWwgKTsKICAgICAgICB9CiAgICAgICAgLy9zdHJ1Y3QsIGludGVyZmFjZXMsIHNlcXVlbmNlcwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIE9VU3RyaW5nIHVzVHlwZU5hbWU7CiAgICAgICAgICAgIHVubzo6UG9seW1vcnBoaWNUeXBlICogcG9seSA9IGR5bmFtaWNfY2FzdDx1bm86OlBvbHltb3JwaGljVHlwZSo+KGNsaVR5cGUpOwogICAgICAgICAgICBpZiAocG9seSAhPSBOVUxMKQogICAgICAgICAgICAgICAgdXNUeXBlTmFtZSA9IG1hcENsaVR5cGVOYW1lKCBwb2x5LT5Qb2x5bW9ycGhpY05hbWUpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB1c1R5cGVOYW1lID0gbWFwQ2xpVHlwZU5hbWUoY2xpVHlwZU5hbWUpOwogICAgICAgICAgICB0eXBlbGliX1R5cGVEZXNjcmlwdGlvbiogdGQgPSBOVUxMOwogICAgICAgICAgICB0eXBlbGliX3R5cGVkZXNjcmlwdGlvbl9nZXRCeU5hbWUoJnRkLCB1c1R5cGVOYW1lLnBEYXRhKTsKICAgICAgICAgICAgaWYgKHRkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXRWYWwgPSB0ZC0+cFdlYWtSZWY7CiAgICAgICAgICAgICAgICB0eXBlbGliX3R5cGVkZXNjcmlwdGlvbnJlZmVyZW5jZV9hY3F1aXJlKHJldFZhbCk7CiAgICAgICAgICAgICAgICB0eXBlbGliX3R5cGVkZXNjcmlwdGlvbl9yZWxlYXNlKHRkKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGlmIChyZXRWYWwgPT0gTlVMTCkKICAgIHsKICAgICAgICBPVVN0cmluZ0J1ZmZlciBidWYoIDEyOCApOwogICAgICAgIGJ1Zi5hcHBlbmRBc2NpaSgKICAgICAgICAgICAgUlRMX0NPTlNUQVNDSUlfU1RSSU5HUEFSQU0oIltjbGlfdW5vIGJyaWRnZV0gbWFwQ2xpVHlwZSgpOiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvdWxkIG5vdCBtYXAgdHlwZTogIikgKTsKICAgICAgICBidWYuYXBwZW5kKG1hcENsaVN0cmluZyhjbGlUeXBlLT5nZXRfRnVsbE5hbWUoKSkpOwogICAgICAgIHRocm93IEJyaWRnZVJ1bnRpbWVFcnJvciggYnVmLm1ha2VTdHJpbmdBbmRDbGVhcigpICk7CiAgICB9CiAgICByZXR1cm4gcmV0VmFsOwp9CgovKioKICAgIE90aGVyd2lzZSBhIGxlYWRpbmcgInVub2lkbC4iIGlzIHJlbW92ZWQuCiAqLwpTeXN0ZW06OlN0cmluZyogbWFwVW5vVHlwZU5hbWUocnRsX3VTdHJpbmcgY29uc3QgKiB0eXBlTmFtZSkKewogICAgT1VTdHJpbmcgdXNVbm9OYW1lKCBjb25zdF9jYXN0PCBydGxfdVN0cmluZyAqID4oIHR5cGVOYW1lICkgKTsKICAgIHN0OjpTdHJpbmdCdWlsZGVyKiBidWY9IG5ldyBzdDo6U3RyaW5nQnVpbGRlcigpOwogICAgLy9kZXRlcm1pbmUgaWYgdGhlIHR5cGUgaXMgYSBzZXF1ZW5jZSBhbmQgaXRzIGRpbWVuc2lvbnMKICAgIGludCBkaW1zPSAwOwogICAgaWYgKHVzVW5vTmFtZVswXSA9PSAnWycpCiAgICB7CiAgICAgICAgc2FsX0ludDMyIGluZGV4PSAxOwogICAgICAgIHdoaWxlICh0cnVlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHVzVW5vTmFtZVtpbmRleCsrXSA9PSAnXScpCiAgICAgICAgICAgICAgICBkaW1zKys7CiAgICAgICAgICAgIGlmICh1c1Vub05hbWVbaW5kZXgrK10gIT0gJ1snKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHVzVW5vTmFtZSA9IHVzVW5vTmFtZS5jb3B5KGluZGV4IC0gMSk7CiAgICB9CglTeXN0ZW06OlN0cmluZyAqIHNVbm9OYW1lID0gbWFwVW5vU3RyaW5nKHVzVW5vTmFtZS5wRGF0YSk7CglpZiAoc1Vub05hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c0Jvb2wpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzQm9vbGVhbikpOwogICAgZWxzZSBpZiAoc1Vub05hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c0NoYXIpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzQ2hhcikpOwogICAgZWxzZSBpZiAoc1Vub05hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c0J5dGUpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzQnl0ZSkpOwogICAgZWxzZSBpZiAoc1Vub05hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c1Nob3J0KSkpCiAgICAgICAgYnVmLT5BcHBlbmQoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c0ludDE2KSk7CiAgICBlbHNlIGlmIChzVW5vTmFtZS0+RXF1YWxzKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnVzVVNob3J0KSkpCiAgICAgICAgYnVmLT5BcHBlbmQoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c1VJbnQxNikpOwogICAgZWxzZSBpZiAoc1Vub05hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c0xvbmcpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzSW50MzIpKTsKICAgIGVsc2UgaWYgKHNVbm9OYW1lLT5FcXVhbHMoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6dXNVTG9uZykpKQogICAgICAgIGJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnNVSW50MzIpKTsKICAgIGVsc2UgaWYgKHNVbm9OYW1lLT5FcXVhbHMoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6dXNIeXBlcikpKQogICAgICAgIGJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnNJbnQ2NCkpOwogICAgZWxzZSBpZiAoc1Vub05hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c1VIeXBlcikpKQogICAgICAgIGJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnNVSW50NjQpKTsKICAgIGVsc2UgaWYgKHNVbm9OYW1lLT5FcXVhbHMoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6dXNGbG9hdCkpKQogICAgICAgIGJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnNTaW5nbGUpKTsKICAgIGVsc2UgaWYgKHNVbm9OYW1lLT5FcXVhbHMoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6dXNEb3VibGUpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzRG91YmxlKSk7CiAgICBlbHNlIGlmIChzVW5vTmFtZS0+RXF1YWxzKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnVzU3RyaW5nKSkpCiAgICAgICAgYnVmLT5BcHBlbmQoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c1N0cmluZykpOwogICAgZWxzZSBpZiAoc1Vub05hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c1ZvaWQpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzVm9pZCkpOwogICAgZWxzZSBpZiAoc1Vub05hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c1R5cGUpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzVHlwZSkpOwogICAgZWxzZSBpZiAoc1Vub05hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c1hJbnRlcmZhY2UpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzT2JqZWN0KSk7CiAgICBlbHNlIGlmIChzVW5vTmFtZS0+RXF1YWxzKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnVzQW55KSkpCiAgICB7CiAgICAgICAgYnVmLT5BcHBlbmQoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c0FueSkpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8vcHV0ICJ1bm9pZGwuIiBhdCB0aGUgYmVnaW5uaW5nCiAgICAgICAgYnVmLT5BcHBlbmQoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c1Vub2lkbCkpOwogICAgICAgIC8vZm9yIHBvbHltb3JwaGljIHN0cnVjdCB0eXBlcyByZW1vdmUgdGhlIGJyYWNrZXRzLCBlLmcgbXlzdHJ1Y3Q8Ym9vbD4gLT4gbXlzdHJ1Y3QKCQlTeXN0ZW06OlN0cmluZyAqIHNOYW1lID0gbWFwVW5vUG9seW1vcnBoaWNOYW1lKHNVbm9OYW1lKTsKICAgICAgICBidWYtPkFwcGVuZChzTmFtZSk7CiAgICB9CiAgICAvLyBhcGVuZCBbXQogICAgZm9yICg7ZGltcy0tOykKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzQnJhY2tldHMpKTsKCiAgICByZXR1cm4gYnVmLT5Ub1N0cmluZygpOwp9CgoKCgovKiogRm9yIGV4YW1wbGUsIHRoZXJlIGlzIGEgdW5vIHR5cGUKICAgIGNvbS5zdW4uc3Rhci5Gb288Y2hhciwgbG9uZz4uCiAgICBUaGUgdmFsdWVzIGluIHRoZSB0eXBlIGxpc3QKICAgIGFyZSB1bm8gdHlwZXMgYW5kIGFyZSByZXBsYWNlZCBieSBjbGkgdHlwZXMsIHN1Y2ggYXMgU3lzdGVtLkNoYXIsCiAgICBTeXN0ZW0uSW50MzIsIGV0Yy4KICAgIFRoZSBwcuRmaXggdW5vaWRsIGlzIG5vdCBhZGRlZC4KICovCmlubGluZSBTeXN0ZW06OlN0cmluZyogbWFwVW5vUG9seW1vcnBoaWNOYW1lKFN5c3RlbTo6U3RyaW5nKiB1bm9OYW1lKQp7CiAgICAgICByZXR1cm4gbWFwUG9seW1vcnBoaWNOYW1lKHVub05hbWUsIGZhbHNlKTsKfQovKiogRm9yIGV4YW1wbGUsIHRoZXJlIGlzIGEgdHlwZSBuYW1lIHN1Y2ggYXMKICAgIGNvbS5zdW4uc3Rhci5Gb288U3lzdGVtLkNoYXIsIFN5c3RlbS5JbnQzMj4uCiAgICBUaGUgdmFsdWVzIGluIHRoZSB0eXBlIGxpc3QKICAgIGFyZSBDTEkgdHlwZXMgYW5kIGFyZSByZXBsYWNlZCBieSB1bm8gdHlwZXMsIHN1Y2ggYXMgY2hhciwKICAgIGxvbmcsIGV0Yy4KICAgIFRoZSBwcuRmaXggdW5vaWRsIHJlbWFpbnMuCiAqLwppbmxpbmUgU3lzdGVtOjpTdHJpbmcqIG1hcENsaVBvbHltb3JwaGljTmFtZShTeXN0ZW06OlN0cmluZyogdW5vTmFtZSkKewogICAgcmV0dXJuIG1hcFBvbHltb3JwaGljTmFtZSh1bm9OYW1lLCB0cnVlKTsKfQoKU3lzdGVtOjpTdHJpbmcqIG1hcFBvbHltb3JwaGljTmFtZShTeXN0ZW06OlN0cmluZyogdW5vTmFtZSwgYm9vbCBiQ2xpVG9Vbm8pCnsKICAgIGludCBpbmRleCA9IHVub05hbWUtPkluZGV4T2YoJzwnKTsKICAgIGlmIChpbmRleCA9PSAtMSkKICAgICAgICByZXR1cm4gdW5vTmFtZTsKCiAgICBTeXN0ZW06OlRleHQ6OlN0cmluZ0J1aWxkZXIgKiBidWlsZGVyID0gbmV3IFN5c3RlbTo6VGV4dDo6U3RyaW5nQnVpbGRlcigyNTYpOwogICAgYnVpbGRlci0+QXBwZW5kKHVub05hbWUtPlN1YnN0cmluZygwLCBpbmRleCArMSApKTsKCgkvL0ZpbmQgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgJywnCgkvL0lmIHRoZSBwYXJhbWV0ZXIgaXMgYSBwb2x5bW9ycGhpYyBzdHJ1Y3QgdGhlbiB3ZSBuZWVkZSB0byBpZ25vcmUgZXZlcnl0aGluZwoJLy9iZXR3ZWVuIHRoZSBicmFja2V0cyBiZWNhdXNlIGl0IGNhbiBhbHNvIGNvbnRhaW4gY29tbWFzCiAgICAvL2dldCB0aGUgdHlwZSBsaXN0IHdpdGhpbiA8IGFuZCA+CglpbnQgZW5kSW5kZXggPSB1bm9OYW1lLT5MZW5ndGggLSAxOwoJaW5kZXgrKzsKCWludCBjdXIgPSBpbmRleDsKCWludCBjb3VudFBhcmFtcyA9IDA7Cgl3aGlsZSAoY3VyIDw9IGVuZEluZGV4KQoJewoJCVN5c3RlbTo6Q2hhciBjID0gdW5vTmFtZS0+Q2hhcnNbY3VyXTsKCQlpZiAoYyA9PSAnLCcgfHwgYyA9PSAnPicpCgkJewoJCQkvL2luc2VydCBhIGNvbW1hIGlmIG5lZWRlZAoJCQlpZiAoY291bnRQYXJhbXMgIT0gMCkKCQkJCWJ1aWxkZXItPkFwcGVuZChTIiwiKTsKCQkJY291bnRQYXJhbXMrKzsKCQkJU3lzdGVtOjpTdHJpbmcgKiBzUGFyYW0gPSB1bm9OYW1lLT5TdWJzdHJpbmcoaW5kZXgsIGN1ciAtIGluZGV4KTsKCQkJLy9za2lwIHRoZSBjb21tYQoJCQljdXIrKzsKCQkJLy90aGUgaW5kZXggdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgbmV4dCBwYXJhbQoJCQlpbmRleCA9IGN1cjsKICAgICAgICAgICAgaWYgKGJDbGlUb1VubykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYnVpbGRlci0+QXBwZW5kKCBtYXBDbGlUeXBlTmFtZShzUGFyYW0pLmdldFN0cigpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE9VU3RyaW5nIHMgPSBtYXBDbGlTdHJpbmcoc1BhcmFtKTsKICAgICAgICAgICAgICAgIGJ1aWxkZXItPkFwcGVuZChtYXBVbm9UeXBlTmFtZShzLnBEYXRhKSk7CiAgICAgICAgICAgIH0KCQl9CgkJZWxzZSBpZiAoYyA9PSAnPCcpCgkJewoJCQljdXIrKzsKCQkJLy9jb250aW51ZSB1bnRpbCB0aGUgbWF0Y2hpbmcgJz4nCgkJCWludCBudW1OZXN0ZWQgPSAwOwoJCQlmb3IgKDs7Y3VyKyspCgkJCXsKCQkJCVN5c3RlbTo6Q2hhciBjdXJDaGFyID0gdW5vTmFtZS0+Q2hhcnNbY3VyXTsKCQkJCWlmIChjdXJDaGFyID09ICc8JykKCQkJCXsKCQkJCQludW1OZXN0ZWQgKys7CgkJCQl9CgkJCQllbHNlIGlmIChjdXJDaGFyID09ICc+JykKCQkJCXsKCQkJCQlpZiAobnVtTmVzdGVkID4gMCkKCQkJCQkJbnVtTmVzdGVkLS07CgkJCQkJZWxzZQoJCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCQljdXIrKzsKCX0KCiAgICBidWlsZGVyLT5BcHBlbmQoKFN5c3RlbTo6Q2hhcikgJz4nKTsKICAgIHJldHVybiBidWlsZGVyLT5Ub1N0cmluZygpOwp9CgpPVVN0cmluZyBtYXBDbGlUeXBlTmFtZShTeXN0ZW06OlN0cmluZyogdHlwZU5hbWUpCnsKICAgIGludCBkaW1zPSAwOwogICAgLy8gQXJyYXk/IGRldGVybWluZSB0aGUgInJhbmsiIChudW1iZXIgb2YgIltdIikKICAgIC8vIG1vdmUgZnJvbSB0aGUgcmlnaHRtb3N0IGVuZCB0byB0aGUgbGVmdCwgZm9yIGV4YW1wbGUKICAgIC8vIHVub2lkbC5Qb2x5bW9ycGhpY1N0cnVjdDxTeXN0ZW0uQ2hhcltdPltdCiAgICAvLyBoYXMgb25seSBhICJkaW1lbnNpb24iIG9mIDEKCWludCBjdXIgPSB0eXBlTmFtZS0+TGVuZ3RoIC0gMTsKICAgIGJvb2wgYlJpZ2h0QnJhY2tldCA9IGZhbHNlOwoJd2hpbGUgKGN1ciA+PSAwKQoJewoJCVN5c3RlbTo6Q2hhciBjID0gdHlwZU5hbWUtPkNoYXJzW2N1cl07CgkJaWYgKGMgPT0gJ10nKQoJCXsKICAgICAgICAgICAgYlJpZ2h0QnJhY2tldCA9IHRydWU7CgkJfQogICAgICAgIGVsc2UgaWYgKGMgPT0gJ1snKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFiUmlnaHRCcmFja2V0KQogICAgICAgICAgICAgICAgdGhyb3cgQnJpZGdlUnVudGltZUVycm9yKAogICAgICAgICAgICAgICAgICAgIE9VU1RSKCJUeXBlbmFtZSBpcyB3cm9uZy4gTm8gbWF0Y2hpbmcgYnJhY2tldHMgZm9yIHNlcXVlbmNlLiBOYW1lIGlzOiAiKSArCiAgICAgICAgICAgICAgICAgICAgbWFwQ2xpU3RyaW5nKHR5cGVOYW1lKSk7CiAgICAgICAgICAgIGJSaWdodEJyYWNrZXQgPSBmYWxzZTsKICAgICAgICAgICAgZGltcyArKzsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGJSaWdodEJyYWNrZXQpCiAgICAgICAgICAgICAgICB0aHJvdyBCcmlkZ2VSdW50aW1lRXJyb3IoCiAgICAgICAgICAgICAgICAgICAgT1VTVFIoIlR5cGVuYW1lIGlzIHdyb25nLiBObyBtYXRjaGluZyBicmFja2V0cyBmb3Igc2VxdWVuY2UuIE5hbWUgaXM6ICIpICsKICAgICAgICAgICAgICAgICAgICBtYXBDbGlTdHJpbmcodHlwZU5hbWUpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGN1ci0tOwoJfQoKICAgIGlmIChiUmlnaHRCcmFja2V0IHx8IGN1ciA8IDApCiAgICAgICAgdGhyb3cgQnJpZGdlUnVudGltZUVycm9yKAogICAgICAgICAgICBPVVNUUigiVHlwZW5hbWUgaXMgd3JvbmcuICIpICsKICAgICAgICAgICAgbWFwQ2xpU3RyaW5nKHR5cGVOYW1lKSk7CgogICAgdHlwZU5hbWUgPSB0eXBlTmFtZS0+U3Vic3RyaW5nKDAsIGN1ciArIDEpOwoKCVN5c3RlbTo6VGV4dDo6U3RyaW5nQnVpbGRlciAqIGJ1ZiA9IG5ldyBTeXN0ZW06OlRleHQ6OlN0cmluZ0J1aWxkZXIoNTEyKTsKCiAgICAvL1B1dCB0aGUgIltdIiBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSB1bm8gdHlwZSBuYW1lCiAgICBmb3IgKDtkaW1zLS07KQoJCWJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnVzQnJhY2tldHMpKTsKCiAgICBpZiAodHlwZU5hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzQm9vbGVhbikpKQogICAgICAgIGJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnVzQm9vbCkpOwogICAgZWxzZSBpZiAodHlwZU5hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzQ2hhcikpKQogICAgICAgIGJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnVzQ2hhcikpOwogICAgZWxzZSBpZiAodHlwZU5hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzQnl0ZSkpKQogICAgICAgIGJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnVzQnl0ZSkpOwogICAgZWxzZSBpZiAodHlwZU5hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzSW50MTYpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c1Nob3J0KSk7CiAgICBlbHNlIGlmICh0eXBlTmFtZS0+RXF1YWxzKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnNVSW50MTYpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c1VTaG9ydCkpOwogICAgZWxzZSBpZiAodHlwZU5hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzSW50MzIpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c0xvbmcpKTsKICAgIGVsc2UgaWYgKHR5cGVOYW1lLT5FcXVhbHMoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c1VJbnQzMikpKQogICAgICAgIGJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnVzVUxvbmcpKTsKICAgIGVsc2UgaWYgKHR5cGVOYW1lLT5FcXVhbHMoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c0ludDY0KSkpCiAgICAgICAgYnVmLT5BcHBlbmQoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6dXNIeXBlcikpOwogICAgZWxzZSBpZiAodHlwZU5hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzVUludDY0KSkpCiAgICAgICAgYnVmLT5BcHBlbmQoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6dXNVSHlwZXIpKTsKICAgIGVsc2UgaWYgKHR5cGVOYW1lLT5FcXVhbHMoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c1NpbmdsZSkpKQogICAgICAgIGJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnVzRmxvYXQpKTsKICAgIGVsc2UgaWYgKHR5cGVOYW1lLT5FcXVhbHMoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6c0RvdWJsZSkpKQogICAgICAgIGJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnVzRG91YmxlKSk7CiAgICBlbHNlIGlmICh0eXBlTmFtZS0+RXF1YWxzKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnNTdHJpbmcpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c1N0cmluZykpOwogICAgZWxzZSBpZiAodHlwZU5hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzVm9pZCkpKQogICAgICAgIGJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnVzVm9pZCkpOwogICAgZWxzZSBpZiAodHlwZU5hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzVHlwZSkpKQogICAgICAgIGJ1Zi0+QXBwZW5kKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnVzVHlwZSkpOwogICAgZWxzZSBpZiAodHlwZU5hbWUtPkVxdWFscyhjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjpzT2JqZWN0KSkpCiAgICAgICAgYnVmLT5BcHBlbmQoY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KENvbnN0YW50czo6dXNYSW50ZXJmYWNlKSk7CiAgICBlbHNlIGlmICh0eXBlTmFtZS0+RXF1YWxzKGNvbnN0X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqPihDb25zdGFudHM6OnNBbnkpKSkKICAgICAgICBidWYtPkFwcGVuZChjb25zdF9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oQ29uc3RhbnRzOjp1c0FueSkpOwogICAgZWxzZQogICAgewogICAgICAgIFN5c3RlbTo6U3RyaW5nICogc05hbWUgPSBtYXBDbGlQb2x5bW9ycGhpY05hbWUodHlwZU5hbWUpOwogICAgICAgIGludCBpPSBzTmFtZS0+SW5kZXhPZihMJy4nKTsKICAgICAgICBidWYtPkFwcGVuZChzTmFtZS0+U3Vic3RyaW5nKGkgKyAxKSk7CiAgICB9CiAgICByZXR1cm4gbWFwQ2xpU3RyaW5nKGJ1Zi0+VG9TdHJpbmcoKSk7Cn0KLyoqIE1hcHMgdW5vIHR5cGVzIHRvIGRvdCBuZXQgdHlwZXMuCiAqICBJZiB1bm9fZGF0YSBpcyBudWxsIHRoZW4gdGhlIHR5cGUgZGVzY3JpcHRpb24gaXMgY29udmVydGVkIHRvIFN5c3RlbTo6VHlwZQogKi8KaW5saW5lIFN5c3RlbTo6U3RyaW5nKiBtYXBVbm9TdHJpbmcoIHJ0bF91U3RyaW5nIGNvbnN0ICogZGF0YSkKewogICAgT1NMX0FTU0VSVChkYXRhKTsKICAgIHJldHVybiBuZXcgU3lzdGVtOjpTdHJpbmcoKF9fd2NoYXJfdCopIGRhdGEtPmJ1ZmZlciwgMCwgZGF0YS0+bGVuZ3RoKTsKfQoKT1VTdHJpbmcgbWFwQ2xpU3RyaW5nKFN5c3RlbTo6U3RyaW5nIGNvbnN0ICogZGF0YSkKewoKICAgIGlmIChkYXRhICE9IE5VTEwpCiAgICB7CiAgICAgICAgT1NMX0FTU0VSVChzaXplb2Yod2NoYXJfdCkgPT0gc2l6ZW9mKHNhbF9Vbmljb2RlKSk7CiAgICAgICAgd2NoYXJfdCBjb25zdCBfX3BpbiAqIHBkYXRhPSBQdHJUb1N0cmluZ0NoYXJzKGRhdGEpOwogICAgICAgIHJldHVybiBPVVN0cmluZyhwZGF0YSwgY29uc3RfY2FzdDxTeXN0ZW06OlN0cmluZyo+KGRhdGEpLT5nZXRfTGVuZ3RoKCkpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHJldHVybiBPVVN0cmluZygpOwogICAgfQp9CgovLyBUb0RvIGNvbnZlcnQgY2xpIHR5cGVzIHRvIGV4cGVjdGVkIHR5cGVzLCBlLmcgYSBsb25nIHRvIGEgc2hvcnQgd2hlcmUgdGhlIHVubyB0eXBlCi8vIGlzIGEgc2FsX0ludDE2LiBUaGlzIGNvdWxkIGJlIG5lY2Vzc2FyeSBpZiBhIHNjcmlwdGluZyBsYW5ndWFnZSAodHlwZWxlc3MpIGlzIHVzZWQKLy8gQHBhcmFtIGFzc2lnbiB0aGUgdW5vX2RhdGEgaGFzIHRvIGJlIGRlc3RydWN0ZWQgKGluL291dCBhcmdzKQp2b2lkIEJyaWRnZTo6bWFwX3RvX3Vubyh2b2lkICogdW5vX2RhdGEsIFN5c3RlbTo6T2JqZWN0KiBjbGlfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZWxpYl9UeXBlRGVzY3JpcHRpb25SZWZlcmVuY2UgKiB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICBib29sIGFzc2lnbikgY29uc3QKewogICAgdHJ5ewogICAgICAgIHN3aXRjaCAodHlwZS0+ZVR5cGVDbGFzcykKICAgICAgICB7CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19WT0lEOgogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0NIQVI6CiAgICAgICAgewogICAgICAgICAgICBTeXN0ZW06OkNoYXIgYUNoYXI9ICpfX3RyeV9jYXN0PFN5c3RlbTo6Q2hhcio+KGNsaV9kYXRhKTsKICAgICAgICAgICAgKihzYWxfVW5pY29kZSopIHVub19kYXRhPSBhQ2hhcjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQk9PTEVBTjoKICAgICAgICB7CiAgICAgICAgICAgIFN5c3RlbTo6Qm9vbGVhbiBhQm9vbD0gKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpCb29sZWFuKj4oY2xpX2RhdGEpOwogICAgICAgICAgICAqKHNhbF9Cb29sKil1bm9fZGF0YT0gYUJvb2wgPT0gdHJ1ZSA/IHNhbF9UcnVlIDogc2FsX0ZhbHNlOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19CWVRFOgogICAgICAgIHsKICAgICAgICAgICAgU3lzdGVtOjpCeXRlIGFCeXRlPSAqX190cnlfY2FzdDxTeXN0ZW06OkJ5dGUqPihjbGlfZGF0YSk7CiAgICAgICAgICAgICooc2FsX0ludDgqKSB1bm9fZGF0YT0gYUJ5dGU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NIT1JUOgogICAgICAgIHsKICAgICAgICAgICAgU3lzdGVtOjpJbnQxNiBhU2hvcnQ9ICpfX3RyeV9jYXN0PFN5c3RlbTo6SW50MTYqPihjbGlfZGF0YSk7CiAgICAgICAgICAgICooc2FsX0ludDE2KikgdW5vX2RhdGE9IGFTaG9ydDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfVU5TSUdORURfU0hPUlQ6CiAgICAgICAgewogICAgICAgICAgICBTeXN0ZW06OlVJbnQxNiBhVVNob3J0PSAqX190cnlfY2FzdDxTeXN0ZW06OlVJbnQxNio+KGNsaV9kYXRhKTsKICAgICAgICAgICAgKihzYWxfdUludDE2KikgdW5vX2RhdGE9IGFVU2hvcnQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0xPTkc6CiAgICAgICAgewogICAgICAgICAgICBTeXN0ZW06OkludDMyIGFMb25nPSAqX190cnlfY2FzdDxTeXN0ZW06OkludDMyKj4oY2xpX2RhdGEpOwogICAgICAgICAgICAqKHNhbF9JbnQzMiopIHVub19kYXRhPSBhTG9uZzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfVU5TSUdORURfTE9ORzoKICAgICAgICB7CiAgICAgICAgICAgIFN5c3RlbTo6VUludDMyIGFVTG9uZz0gKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpVSW50MzIqPihjbGlfZGF0YSk7CiAgICAgICAgICAgICooc2FsX3VJbnQzMiopIHVub19kYXRhPSBhVUxvbmc7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0hZUEVSOgogICAgICAgIHsKICAgICAgICAgICAgU3lzdGVtOjpJbnQ2NCBhSHlwZXI9ICpfX3RyeV9jYXN0PFN5c3RlbTo6SW50NjQqPihjbGlfZGF0YSk7CiAgICAgICAgICAgICooc2FsX0ludDY0KikgdW5vX2RhdGE9IGFIeXBlcjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfVU5TSUdORURfSFlQRVI6CiAgICAgICAgewogICAgICAgICAgICBTeXN0ZW06OlVJbnQ2NCBhTG9uZz0gKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpVSW50NjQqPihjbGlfZGF0YSk7CiAgICAgICAgICAgICooc2FsX3VJbnQ2NCopIHVub19kYXRhPSBhTG9uZzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRkxPQVQ6CiAgICAgICAgewogICAgICAgICAgICBTeXN0ZW06OlNpbmdsZSBhRmxvYXQ9ICpfX3RyeV9jYXN0PFN5c3RlbTo6U2luZ2xlKj4oY2xpX2RhdGEpOwogICAgICAgICAgICAqKGZsb2F0KikgdW5vX2RhdGE9IGFGbG9hdDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRE9VQkxFOgogICAgICAgIHsKICAgICAgICAgICAgU3lzdGVtOjpEb3VibGUgYURvdWJsZT0gKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpEb3VibGUqPihjbGlfZGF0YSk7CiAgICAgICAgICAgICooZG91YmxlKikgdW5vX2RhdGE9IGFEb3VibGU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NUUklORzoKICAgICAgICB7CiAgICAgICAgICAgIGlmIChhc3NpZ24gJiYgKihydGxfdVN0cmluZyoqKSB1bm9fZGF0YSkKICAgICAgICAgICAgICAgIHJ0bF91U3RyaW5nX3JlbGVhc2UoKihydGxfdVN0cmluZyoqKSB1bm9fZGF0YSk7CgogICAgICAgICAgICAqKHJ0bF91U3RyaW5nICoqKXVub19kYXRhID0gMDsKICAgICAgICAgICAgaWYgKGNsaV9kYXRhID09IE5VTEwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICBydGxfdVN0cmluZ19uZXcoKHJ0bF91U3RyaW5nKiopIHVub19kYXRhKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFN5c3RlbTo6U3RyaW5nICpzPSBfX3RyeV9jYXN0PFN5c3RlbTo6U3RyaW5nKj4oY2xpX2RhdGEpOwogICAgICAgICAgICAgICAgd2NoYXJfdCBjb25zdCBfX3BpbiAqIHBkYXRhPSBQdHJUb1N0cmluZ0NoYXJzKHMpOwogICAgICAgICAgICAgICAgcnRsX3VTdHJpbmdfbmV3RnJvbVN0cl9XaXRoTGVuZ3RoKCAocnRsX3VTdHJpbmcqKikgdW5vX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGRhdGEsIHMtPmdldF9MZW5ndGgoKSApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1RZUEU6CiAgICAgICAgewogICAgICAgICAgICB0eXBlbGliX1R5cGVEZXNjcmlwdGlvblJlZmVyZW5jZSogdGQ9IG1hcENsaVR5cGUoX190cnlfY2FzdDxTeXN0ZW06OlR5cGUqPigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGlfZGF0YSkpOwogICAgICAgICAgICBpZiAoYXNzaWduKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0eXBlbGliX3R5cGVkZXNjcmlwdGlvbnJlZmVyZW5jZV9yZWxlYXNlKAogICAgICAgICAgICAgICAgICAgICoodHlwZWxpYl9UeXBlRGVzY3JpcHRpb25SZWZlcmVuY2UgKiopdW5vX2RhdGEgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAqKHR5cGVsaWJfVHlwZURlc2NyaXB0aW9uUmVmZXJlbmNlICoqKXVub19kYXRhID0gdGQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0FOWToKICAgICAgICB7CiAgICAgICAgICAgIHVub19BbnkgKiBwQW55ID0gKHVub19BbnkgKil1bm9fZGF0YTsKICAgICAgICAgICAgaWYgKGNsaV9kYXRhID09IE5VTEwpIC8vIG51bGwtcmVmIG9yIHVuaW5pdGlhbGl6ZWQgYW55IG1hcHMgdG8gZW1wdHkgYW55CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChhc3NpZ24pCiAgICAgICAgICAgICAgICAgICAgdW5vX2FueV9kZXN0cnVjdCggcEFueSwgMCApOwogICAgICAgICAgICAgICAgdW5vX2FueV9jb25zdHJ1Y3QoIHBBbnksIDAsIDAsIDAgKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHVubzo6QW55IGFBbnk9ICpfX3RyeV9jYXN0PHVubzo6QW55Kj4oY2xpX2RhdGEpOwogICAgICAgICAgICBjc3M6OnVubzo6VHlwZSAgdmFsdWVfdGQoIG1hcENsaVR5cGUoYUFueS5UeXBlKSwgU0FMX05PX0FDUVVJUkUpOwoKICAgICAgICAgICAgaWYgKGFzc2lnbikKICAgICAgICAgICAgICAgIHVub19hbnlfZGVzdHJ1Y3QoIHBBbnksIDAgKTsKCiAgICAgICAgICAgIHRyeQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHZhbHVlX3RkLmdldFR5cGVDbGFzcygpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19WT0lEOgogICAgICAgICAgICAgICAgICAgIHBBbnktPnBEYXRhID0gJnBBbnktPnBSZXNlcnZlZDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQ0hBUjoKICAgICAgICAgICAgICAgICAgICBwQW55LT5wRGF0YSA9ICZwQW55LT5wUmVzZXJ2ZWQ7CiAgICAgICAgICAgICAgICAgICAgKihzYWxfVW5pY29kZSopICZwQW55LT5wUmVzZXJ2ZWQgPSAqX190cnlfY2FzdDxTeXN0ZW06OkNoYXIqPihhQW55LlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQk9PTEVBTjoKICAgICAgICAgICAgICAgICAgICBwQW55LT5wRGF0YSA9ICZwQW55LT5wUmVzZXJ2ZWQ7CiAgICAgICAgICAgICAgICAgICAgKihzYWxfQm9vbCAqKSAmcEFueS0+cFJlc2VydmVkID0gKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpCb29sZWFuKj4oYUFueS5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0JZVEU6CiAgICAgICAgICAgICAgICAgICAgcEFueS0+cERhdGEgPSAmcEFueS0+cFJlc2VydmVkOwogICAgICAgICAgICAgICAgICAgICooc2FsX0ludDgqKSAmcEFueS0+cFJlc2VydmVkID0gICpfX3RyeV9jYXN0PFN5c3RlbTo6Qnl0ZSo+KGFBbnkuVmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19TSE9SVDoKICAgICAgICAgICAgICAgICAgICBwQW55LT5wRGF0YSA9ICZwQW55LT5wUmVzZXJ2ZWQ7CiAgICAgICAgICAgICAgICAgICAgKihzYWxfSW50MTYqKSAmcEFueS0+cFJlc2VydmVkID0gICpfX3RyeV9jYXN0PFN5c3RlbTo6SW50MTYqPihhQW55LlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfVU5TSUdORURfU0hPUlQ6CiAgICAgICAgICAgICAgICAgICAgcEFueS0+cERhdGEgPSAmcEFueS0+cFJlc2VydmVkOwogICAgICAgICAgICAgICAgICAgICooc2FsX3VJbnQxNiopICZwQW55LT5wUmVzZXJ2ZWQgPSAgKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpVSW50MTYqPihhQW55LlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfTE9ORzoKICAgICAgICAgICAgICAgICAgICBwQW55LT5wRGF0YSA9ICZwQW55LT5wUmVzZXJ2ZWQ7CiAgICAgICAgICAgICAgICAgICAgKihzYWxfSW50MzIqKSAmcEFueS0+cFJlc2VydmVkID0gICpfX3RyeV9jYXN0PFN5c3RlbTo6SW50MzIqPihhQW55LlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfVU5TSUdORURfTE9ORzoKICAgICAgICAgICAgICAgICAgICBwQW55LT5wRGF0YSA9ICZwQW55LT5wUmVzZXJ2ZWQ7CiAgICAgICAgICAgICAgICAgICAgKihzYWxfdUludDMyKikgJnBBbnktPnBSZXNlcnZlZCA9ICAqX190cnlfY2FzdDxTeXN0ZW06OlVJbnQzMio+KGFBbnkuVmFsdWUpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19IWVBFUjoKICAgICAgICAgICAgICAgICAgICBpZiAoc2l6ZW9mIChzYWxfSW50NjQpIDw9IHNpemVvZiAodm9pZCAqKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBBbnktPnBEYXRhID0gJnBBbnktPnBSZXNlcnZlZDsKICAgICAgICAgICAgICAgICAgICAgICAgKihzYWxfSW50NjQqKSAmcEFueS0+cFJlc2VydmVkID0gKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpJbnQ2NCo+KGFBbnkuVmFsdWUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhdXRvX3B0cjwgcnRsX21lbSA+IG1lbSggcnRsX21lbTo6YWxsb2NhdGUoIHNpemVvZiAoc2FsX0ludDY0KSApICk7CiAgICAgICAgICAgICAgICAgICAgICAgICooc2FsX0ludDY0ICopIG1lbS5nZXQoKT0gICpfX3RyeV9jYXN0PFN5c3RlbTo6SW50NjQqPihhQW55LlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgcEFueS0+cERhdGEgPSBtZW0ucmVsZWFzZSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfVU5TSUdORURfSFlQRVI6CiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemVvZiAoc2FsX3VJbnQ2NCkgPD0gc2l6ZW9mICh2b2lkICopKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcEFueS0+cERhdGEgPSAmcEFueS0+cFJlc2VydmVkOwogICAgICAgICAgICAgICAgICAgICAgICAqKHNhbF91SW50NjQqKSAmcEFueS0+cFJlc2VydmVkID0gKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpVSW50NjQqPihhQW55LlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXV0b19wdHI8IHJ0bF9tZW0gPiBtZW0oIHJ0bF9tZW06OmFsbG9jYXRlKCBzaXplb2YgKHNhbF91SW50NjQpICkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgKihzYWxfdUludDY0ICopIG1lbS5nZXQoKT0gICpfX3RyeV9jYXN0PFN5c3RlbTo6VUludDY0Kj4oYUFueS5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHBBbnktPnBEYXRhID0gbWVtLnJlbGVhc2UoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0ZMT0FUOgogICAgICAgICAgICAgICAgICAgIGlmIChzaXplb2YgKGZsb2F0KSA8PSBzaXplb2YgKHZvaWQgKikpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBwQW55LT5wRGF0YSA9ICZwQW55LT5wUmVzZXJ2ZWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICooZmxvYXQqKSAmcEFueS0+cFJlc2VydmVkID0gKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpTaW5nbGUqPihhQW55LlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXV0b19wdHI8IHJ0bF9tZW0gPiBtZW0oIHJ0bF9tZW06OmFsbG9jYXRlKCBzaXplb2YgKGZsb2F0KSApICk7CiAgICAgICAgICAgICAgICAgICAgICAgICooZmxvYXQqKSBtZW0uZ2V0KCkgPSAqX190cnlfY2FzdDxTeXN0ZW06OlNpbmdsZSo+KGFBbnkuVmFsdWUpOwogICAgICAgICAgICAgICAgICAgICAgICBwQW55LT5wRGF0YSA9IG1lbS5yZWxlYXNlKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19ET1VCTEU6CiAgICAgICAgICAgICAgICAgICAgaWYgKHNpemVvZiAoZG91YmxlKSA8PSBzaXplb2YgKHZvaWQgKikpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBwQW55LT5wRGF0YSA9ICZwQW55LT5wUmVzZXJ2ZWQ7CiAgICAgICAgICAgICAgICAgICAgICAgICooZG91YmxlKikgJnBBbnktPnBSZXNlcnZlZD0gKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpEb3VibGUqPihhQW55LlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXV0b19wdHI8IHJ0bF9tZW0gPiBtZW0oIHJ0bF9tZW06OmFsbG9jYXRlKCBzaXplb2YgKGRvdWJsZSkgKSApOwogICAgICAgICAgICAgICAgICAgICAgICAqKGRvdWJsZSopIG1lbS5nZXQoKT0gKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpEb3VibGUqPihhQW55LlZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgcEFueS0+cERhdGE9IG1lbS5yZWxlYXNlKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19TVFJJTkc6IC8vIGFuaWVzIG9mdGVuIGNvbnRhaW4gc3RyaW5nczsgY29weSBzdHJpbmcgZGlyZWN0bHkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBwQW55LT5wRGF0YT0gJnBBbnktPnBSZXNlcnZlZDsKICAgICAgICAgICAgICAgICAgICBPVVN0cmluZyBfcyA9IG1hcENsaVN0cmluZyhzdGF0aWNfY2FzdDxTeXN0ZW06OlN0cmluZyo+KGFBbnkuVmFsdWUpKTsKICAgICAgICAgICAgICAgICAgICBwQW55LT5wUmVzZXJ2ZWQ9IF9zLnBEYXRhOwogICAgICAgICAgICAgICAgICAgIHJ0bF91U3RyaW5nX2FjcXVpcmUoX3MucERhdGEpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19UWVBFOgogICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19FTlVNOiAgLy9Ub0RvIGNvcHkgZW51bSBkaXJlY3QKICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfU0VRVUVOQ0U6CiAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0lOVEVSRkFDRToKICAgICAgICAgICAgICAgICAgICBwQW55LT5wRGF0YSA9ICZwQW55LT5wUmVzZXJ2ZWQ7CiAgICAgICAgICAgICAgICAgICAgcEFueS0+cFJlc2VydmVkID0gMDsKICAgICAgICAgICAgICAgICAgICBtYXBfdG9fdW5vKAogICAgICAgICAgICAgICAgICAgICAgICAmcEFueS0+cFJlc2VydmVkLCBhQW55LlZhbHVlLCB2YWx1ZV90ZC5nZXRUeXBlTGliVHlwZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlIC8qIG5vIGFzc2lnbiAqLyk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NUUlVDVDoKICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRVhDRVBUSU9OOgogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNzczo6dW5vOjpUeXBlIGFueVR5cGUodmFsdWVfdGQpOwogICAgICAgICAgICAgICAgICAgIHR5cGVsaWJfVHlwZURlc2NyaXB0aW9uKiB0ZD0gTlVMTDsKICAgICAgICAgICAgICAgICAgICBhbnlUeXBlLmdldERlc2NyaXB0aW9uKCZ0ZCk7CiAgICAgICAgICAgICAgICAgICAgYXV0b19wdHI8IHJ0bF9tZW0gPiBtZW0ocnRsX21lbTo6YWxsb2NhdGUodGQtPm5TaXplKSk7CiAgICAgICAgICAgICAgICAgICAgdHlwZWxpYl90eXBlZGVzY3JpcHRpb25fcmVsZWFzZSh0ZCk7CiAgICAgICAgICAgICAgICAgICAgbWFwX3RvX3VubygKICAgICAgICAgICAgICAgICAgICAgICAgbWVtLmdldCgpLCBhQW55LlZhbHVlLCB2YWx1ZV90ZC5nZXRUeXBlTGliVHlwZSgpLAogICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSAvKiBubyBhc3NpZ24gKi8pOwogICAgICAgICAgICAgICAgICAgIHBBbnktPnBEYXRhID0gbWVtLnJlbGVhc2UoKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgT1VTdHJpbmdCdWZmZXIgYnVmKCAxMjggKTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kQXNjaWkoIFJUTF9DT05TVEFTQ0lJX1NUUklOR1BBUkFNKCJbbWFwX3RvX3VubygpOiIpICk7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCh2YWx1ZV90ZC5nZXRUeXBlTmFtZSgpKTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kQXNjaWkoIFJUTF9DT05TVEFTQ0lJX1NUUklOR1BBUkFNKCJdIHVuc3VwcG9ydGVkIHZhbHVlIHR5cGUgb2YgYW55ISIpICk7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgQnJpZGdlUnVudGltZUVycm9yKCBidWYubWFrZVN0cmluZ0FuZENsZWFyKCkgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBjYXRjaChTeXN0ZW06OkludmFsaWRDYXN0RXhjZXB0aW9uKiApCiAgICAgICAgICAgIHsKLy8gVG9EbyBjaGVjayB0aGlzCiAgICAgICAgICAgICAgICBpZiAoYXNzaWduKQogICAgICAgICAgICAgICAgICAgIHVub19hbnlfY29uc3RydWN0KCBwQW55LCAwLCAwLCAwICk7IC8vIHJlc3RvcmUgc29tZSB2YWxpZCBhbnkKICAgICAgICAgICAgICAgIE9VU3RyaW5nQnVmZmVyIGJ1ZiggMjU2ICk7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kQXNjaWkoIFJUTF9DT05TVEFTQ0lJX1NUUklOR1BBUkFNKCJbbWFwX3RvX3VubygpOkFueSIpICk7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKHZhbHVlX3RkLmdldFR5cGVOYW1lKCkpOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZEFzY2lpKCBSVExfQ09OU1RBU0NJSV9TVFJJTkdQQVJBTSgiXVRoZSBBbnkgdHlwZSAiKSk7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKHZhbHVlX3RkLmdldFR5cGVOYW1lKCkpOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZEFzY2lpKCBSVExfQ09OU1RBU0NJSV9TVFJJTkdQQVJBTSgiIGRvZXMgbm90IGNvcnJlc3BvbnQgICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRvIGl0cyB2YWx1ZSB0eXBlOiAiKSApOwogICAgICAgICAgICAgICAgaWYoYUFueS5WYWx1ZSAhPSBOVUxMKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNzczo6dW5vOjpUeXBlIHRkKG1hcENsaVR5cGUoYUFueS5WYWx1ZS0+R2V0VHlwZSgpKSwgU0FMX05PX0FDUVVJUkUpOwogICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQodGQuZ2V0VHlwZU5hbWUoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoYXNzaWduKQogICAgICAgICAgICAgICAgICAgIHVub19hbnlfY29uc3RydWN0KCBwQW55LCAwLCAwLCAwICk7IC8vIHJlc3RvcmUgc29tZSB2YWxpZCBhbnkKICAgICAgICAgICAgICAgIHRocm93IEJyaWRnZVJ1bnRpbWVFcnJvciggYnVmLm1ha2VTdHJpbmdBbmRDbGVhcigpICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2ggKEJyaWRnZVJ1bnRpbWVFcnJvciYgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoYXNzaWduKQogICAgICAgICAgICAgICAgICAgIHVub19hbnlfY29uc3RydWN0KCBwQW55LCAwLCAwLCAwICk7IC8vIHJlc3RvcmUgc29tZSB2YWxpZCBhbnkKICAgICAgICAgICAgICAgIHRocm93OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoICguLi4pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChhc3NpZ24pCiAgICAgICAgICAgICAgICAgICAgdW5vX2FueV9jb25zdHJ1Y3QoIHBBbnksIDAsIDAsIDAgKTsgLy8gcmVzdG9yZSBzb21lIHZhbGlkIGFueQogICAgICAgICAgICAgICAgdGhyb3c7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHBBbnktPnBUeXBlID0gdmFsdWVfdGQuZ2V0VHlwZUxpYlR5cGUoKTsKICAgICAgICAgICAgdHlwZWxpYl90eXBlZGVzY3JpcHRpb25yZWZlcmVuY2VfYWNxdWlyZShwQW55LT5wVHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0VOVU06CiAgICAgICAgewogICAgICAgICAgICAvLyBJbnZhbGlkQ2FzdEV4Y2VwdGlvbiBpcyBjYXVnaHQgYXQgdGhlIGVuZCBvZiB0aGlzIG1ldGhvZAogICAgICAgICAgICBTeXN0ZW06OkludDMyIGFFbnVtPSBTeXN0ZW06OkNvbnZlcnQ6OlRvSW50MzIoKGNsaV9kYXRhKSk7CiAgICAgICAgICAgICooc2FsX0ludDMyKikgdW5vX2RhdGEgPSBhRW51bTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfU1RSVUNUOgogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRVhDRVBUSU9OOgogICAgICAgIHsKICAgICAgICAgICAgY3NzOjp1bm86OlR5cGVEZXNjcmlwdGlvbiB0ZCh0eXBlKTsKICAgICAgICAgICAgdHlwZWxpYl9Db21wb3VuZFR5cGVEZXNjcmlwdGlvbiAqIGNvbXBfdGQgPQogICAgICAgICAgICAgICAgKHR5cGVsaWJfQ29tcG91bmRUeXBlRGVzY3JpcHRpb24qKSB0ZC5nZXQoKTsKCiAgICAgICAgICAgIHR5cGVsaWJfU3RydWN0VHlwZURlc2NyaXB0aW9uICogc3RydWN0X3RkID0gTlVMTDsKICAgICAgICAgICAgaWYgKHR5cGUtPmVUeXBlQ2xhc3MgPT0gdHlwZWxpYl9UeXBlQ2xhc3NfU1RSVUNUKQogICAgICAgICAgICAgICAgc3RydWN0X3RkID0gKHR5cGVsaWJfU3RydWN0VHlwZURlc2NyaXB0aW9uKikgdGQuZ2V0KCk7CgogICAgICAgICAgICBpZiAoICEgKCh0eXBlbGliX1R5cGVEZXNjcmlwdGlvbiopIGNvbXBfdGQpLT5iQ29tcGxldGUpCiAgICAgICAgICAgICAgICA6OnR5cGVsaWJfdHlwZWRlc2NyaXB0aW9uX2NvbXBsZXRlKAogICAgICAgICAgICAgICAgICAgICh0eXBlbGliX1R5cGVEZXNjcmlwdGlvbioqKSAmIGNvbXBfdGQgKTsKCiAgICAgICAgICAgIHNhbF9JbnQzMiBuTWVtYmVycyA9IGNvbXBfdGQtPm5NZW1iZXJzOwogICAgICAgICAgICBib29sZWFuIGJFeGNlcHRpb249IGZhbHNlOwogICAgICAgICAgICBTeXN0ZW06OlR5cGUqIGNsaVR5cGUgPSBOVUxMOwogICAgICAgICAgICBpZiAoY2xpX2RhdGEpCiAgICAgICAgICAgICAgICBjbGlUeXBlID0gY2xpX2RhdGEtPkdldFR5cGUoKTsKCiAgICAgICAgICAgIGlmICgwICE9IGNvbXBfdGQtPnBCYXNlVHlwZURlc2NyaXB0aW9uKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtYXBfdG9fdW5vKAogICAgICAgICAgICAgICAgICAgIHVub19kYXRhLCBjbGlfZGF0YSwKICAgICAgICAgICAgICAgICAgICAoKHR5cGVsaWJfVHlwZURlc2NyaXB0aW9uICopY29tcF90ZC0+cEJhc2VUeXBlRGVzY3JpcHRpb24pLT5wV2Vha1JlZiwKICAgICAgICAgICAgICAgICAgICBhc3NpZ24pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNhbF9JbnQzMiBuUG9zID0gMDsKICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHR5cGVsaWJfVHlwZURlc2NyaXB0aW9uUmVmZXJlbmNlICogbWVtYmVyX3R5cGU9IE5VTEw7CgoJCQkJcnRsOjpPVVN0cmluZyB1c1Vub0V4Y2VwdGlvbihSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oImNvbS5zdW4uc3Rhci51bm8uRXhjZXB0aW9uIikpOwogICAgICAgICAgICAgICAgZm9yICg7IG5Qb3MgPCBuTWVtYmVyczsgKytuUG9zKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG1lbWJlcl90eXBlPSBjb21wX3RkLT5wcFR5cGVSZWZzW25Qb3NdOwojaWYgT1NMX0RFQlVHX0xFVkVMID49IDIKICAgICAgICAgICAgICAgICAgICBTeXN0ZW06OlN0cmluZyogX19zOwogICAgICAgICAgICAgICAgICAgIHNyOjpGaWVsZEluZm8qIGFyRmllbGRzW107CiAgICAgICAgICAgICAgICAgICAgX19zID0gbWFwVW5vU3RyaW5nKGNvbXBfdGQtPnBwTWVtYmVyTmFtZXNbblBvc10pOwogICAgICAgICAgICAgICAgICAgIGFyRmllbGRzID0gY2xpVHlwZSAhPSBOVUxMID8gY2xpVHlwZS0+R2V0RmllbGRzKCkgOiBOVUxMOwojZW5kaWYKICAgICAgICAgICAgICAgICAgICBTeXN0ZW06Ok9iamVjdCogdmFsPSBOVUxMOwogICAgICAgICAgICAgICAgICAgIGlmIChjbGlfZGF0YSAhPSBOVUxMKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3I6OkZpZWxkSW5mbyogYUZpZWxkPSBjbGlUeXBlLT5HZXRGaWVsZCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcFVub1N0cmluZyhjb21wX3RkLT5wcE1lbWJlck5hbWVzW25Qb3NdKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNwZWNpYWwgY2FzZSBmb3IgRXhjZXB0aW9uLk1lc3NhZ2UgcHJvcGVydHkKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGNvbS5zdW4uc3Rhci51bm8uRXhjZXB0aW9uLk1lc3NhZ2UgZmllbGQgaXMgbWFwcGVkIHRvIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAvLyBTeXN0ZW0uRXhjZXB0aW9uIHByb3BlcnR5LiBUeXBlLkdldEZpZWxkKCJNZXNzYWdlIikgcmV0dXJucyBudWxsCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggISBhRmllbGQgJiYgdXNVbm9FeGNlcHRpb24uZXF1YWxzKHRkLmdldCgpLT5wVHlwZU5hbWUpKQogICAgICAgICAgICAgICAgICAgICAgICB7Ly8gZ2V0IEV4Y2VwdGlvbi5NZXNzYWdlIHByb3BlcnR5CgkJCQkJCQlydGw6Ok9VU3RyaW5nIHVzTWVzc2FnZU1lbWJlcihSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIk1lc3NhZ2UiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNNZXNzYWdlTWVtYmVyLmVxdWFscyhjb21wX3RkLT5wcE1lbWJlck5hbWVzW25Qb3NdKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcjo6UHJvcGVydHlJbmZvKiBwaT0gY2xpVHlwZS0+R2V0UHJvcGVydHkoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcFVub1N0cmluZyhjb21wX3RkLT5wcE1lbWJlck5hbWVzW25Qb3NdKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsPSBwaS0+R2V0VmFsdWUoY2xpX2RhdGEsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9VU3RyaW5nQnVmZmVyIGJ1Zig1MTIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmRBc2NpaShSVExfQ09OU1RBU0NJSV9TVFJJTkdQQVJBTSgiW21hcF90b191bm8oKTogTWVtYmVyOiAiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjb21wX3RkLT5wcE1lbWJlck5hbWVzW25Qb3NdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBCcmlkZ2VSdW50aW1lRXJyb3IoYnVmLm1ha2VTdHJpbmdBbmRDbGVhcigpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbD0gYUZpZWxkLT5HZXRWYWx1ZShjbGlfZGF0YSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdm9pZCAqIHAgPSAoY2hhciAqKSB1bm9fZGF0YSArIGNvbXBfdGQtPnBNZW1iZXJPZmZzZXRzWyBuUG9zIF07CiAgICAgICAgICAgICAgICAgICAgLy9XaGVuIHVzaW5nIHBvbHltb3JwaGljIHN0cnVjdHMgdGhlbiB0aGUgcGFyYW1ldGVyaXplZCBtZW1iZXJzIGNhbiBiZSBudWxsLgogICAgICAgICAgICAgICAgICAgIC8vVGhlbiB3ZSBzZXQgYSBkZWZhdWx0IHZhbHVlLgogICAgICAgICAgICAgICAgICAgIGJvb2wgYkRlZmF1bHQgPSAoKHN0cnVjdF90ZCAhPSBOVUxMCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBzdHJ1Y3RfdGQtPnBQYXJhbWV0ZXJpemVkVHlwZXMgIT0gTlVMTAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgc3RydWN0X3RkLT5wUGFyYW1ldGVyaXplZFR5cGVzW25Qb3NdID09IHNhbF9UcnVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgdmFsID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCBjbGlfZGF0YSA9PSBOVUxMKSA/IHRydWUgOiBmYWxzZTsKICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKG1lbWJlcl90eXBlLT5lVHlwZUNsYXNzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0NIQVI6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiRGVmYXVsdCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICooc2FsX1VuaWNvZGUqKSBwID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKihzYWxfVW5pY29kZSopIHAgPSAqX190cnlfY2FzdDxTeXN0ZW06OkNoYXIqPih2YWwpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0JPT0xFQU46CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiRGVmYXVsdCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICooc2FsX0Jvb2wqKSBwID0gc2FsX0ZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKHNhbF9Cb29sKikgcCA9ICpfX3RyeV9jYXN0PFN5c3RlbTo6Qm9vbGVhbio+KHZhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQllURToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJEZWZhdWx0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKihzYWxfSW50OCopIHAgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKHNhbF9JbnQ4KikgcCA9ICpfX3RyeV9jYXN0PFN5c3RlbTo6Qnl0ZSo+KHZhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfU0hPUlQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiRGVmYXVsdCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICooc2FsX0ludDE2KikgcCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICooc2FsX0ludDE2KikgcCA9ICpfX3RyeV9jYXN0PFN5c3RlbTo6SW50MTYqPih2YWwpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1VOU0lHTkVEX1NIT1JUOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYkRlZmF1bHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKHNhbF91SW50MTYqKSBwID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKihzYWxfdUludDE2KikgcCA9ICpfX3RyeV9jYXN0PFN5c3RlbTo6VUludDE2Kj4odmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19MT05HOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYkRlZmF1bHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKHNhbF9JbnQzMiopIHAgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKHNhbF9JbnQzMiopIHAgPSAqX190cnlfY2FzdDxTeXN0ZW06OkludDMyKj4odmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19VTlNJR05FRF9MT05HOgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYkRlZmF1bHQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKHNhbF91SW50MzIqKSBwID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKihzYWxfdUludDMyKikgcCA9ICpfX3RyeV9jYXN0PFN5c3RlbTo6VUludDMyKj4odmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19IWVBFUjoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJEZWZhdWx0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKihzYWxfSW50NjQqKSBwID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKihzYWxfSW50NjQqKSBwID0gKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpJbnQ2NCo+KHZhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfVU5TSUdORURfSFlQRVI6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiRGVmYXVsdCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICooc2FsX3VJbnQ2NCopIHAgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKHNhbF91SW50NjQqKSBwPSAqX190cnlfY2FzdDxTeXN0ZW06OlVJbnQ2NCo+KHZhbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRkxPQVQ6CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiRGVmYXVsdCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICooZmxvYXQqKSBwID0gMC47CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICooZmxvYXQqKSBwID0gKl9fdHJ5X2Nhc3Q8U3lzdGVtOjpTaW5nbGUqPih2YWwpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0RPVUJMRToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJEZWZhdWx0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKihkb3VibGUqKSBwID0gMC47CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICooZG91YmxlKikgcCA9ICpfX3RyeV9jYXN0PFN5c3RlbTo6RG91YmxlKj4odmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICB7ICAgLy8gVG9EbyBlbnVtLCBzaG91bGQgYmUgY29udmVydGVkIGhlcmUKICAgICAgICAgICAgICAgICAgICAgICAgIG1hcF90b191bm8ocCwgdmFsLCBtZW1iZXJfdHlwZSwgYXNzaWduKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBjYXRjaCAoQnJpZGdlUnVudGltZUVycm9yJiBlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBiRXhjZXB0aW9uPSB0cnVlOwogICAgICAgICAgICAgICAgT1VTdHJpbmdCdWZmZXIgYnVmKDUxMik7CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kQXNjaWkoUlRMX0NPTlNUQVNDSUlfU1RSSU5HUEFSQU0oIlttYXBfdG9fdW5vKCk6IikpOwogICAgICAgICAgICAgICAgaWYgKGNsaVR5cGUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChtYXBDbGlTdHJpbmcoY2xpVHlwZS0+Z2V0X0Z1bGxOYW1lKCkpKTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kQXNjaWkoUlRMX0NPTlNUQVNDSUlfU1RSSU5HUEFSQU0oIi4iKSk7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChjb21wX3RkLT5wcE1lbWJlck5hbWVzW25Qb3NdKTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kQXNjaWkoUlRMX0NPTlNUQVNDSUlfU1RSSU5HUEFSQU0oIiAiKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kKGUubV9tZXNzYWdlKTsKICAgICAgICAgICAgICAgIHRocm93IEJyaWRnZVJ1bnRpbWVFcnJvcihidWYubWFrZVN0cmluZ0FuZENsZWFyKCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNhdGNoIChTeXN0ZW06OkludmFsaWRDYXN0RXhjZXB0aW9uKiApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGJFeGNlcHRpb249IHRydWU7CiAgICAgICAgICAgICAgICBPVVN0cmluZ0J1ZmZlciBidWYoIDI1NiApOwogICAgICAgICAgICAgICAgYnVmLmFwcGVuZEFzY2lpKCBSVExfQ09OU1RBU0NJSV9TVFJJTkdQQVJBTSgiW21hcF90b191bm8oKToiKSApOwogICAgICAgICAgICAgICAgaWYgKGNsaVR5cGUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChtYXBDbGlTdHJpbmcoY2xpVHlwZS0+Z2V0X0Z1bGxOYW1lKCkpKTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kQXNjaWkoIFJUTF9DT05TVEFTQ0lJX1NUUklOR1BBUkFNKCIuIikpOwogICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoY29tcF90ZC0+cHBNZW1iZXJOYW1lc1tuUG9zXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBidWYuYXBwZW5kQXNjaWkoIFJUTF9DT05TVEFTQ0lJX1NUUklOR1BBUkFNKCJdIFZhbHVlIGhhcyBub3QgdGhlIHJlcXVpcmVkIHR5cGUuIikpOwogICAgICAgICAgICAgICAgdGhyb3cgQnJpZGdlUnVudGltZUVycm9yKGJ1Zi5tYWtlU3RyaW5nQW5kQ2xlYXIoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2F0Y2ggKC4uLikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgT1NMX0FTU0VSVCgwKTsKICAgICAgICAgICAgICAgIGJFeGNlcHRpb249IHRydWU7CiAgICAgICAgICAgICAgICB0aHJvdzsKICAgICAgICAgICAgfQogICAgICAgICAgICBfX2ZpbmFsbHkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGJFeGNlcHRpb24gJiYgIWFzc2lnbikgLy8gaWYgYXNzaWduIHRoZW4gY2FsbGVyIGNsZWFucyB1cAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIGNsZWFudXAgdGhlIG1lbWJlcnMgd2hpY2ggd2UgaGF2ZSBjb252ZXJ0ZWQgc28gZmFyCiAgICAgICAgICAgICAgICAgICAgZm9yICggc2FsX0ludDMyIG5DbGVhbnVwID0gMDsgbkNsZWFudXAgPCBuUG9zOyArK25DbGVhbnVwICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHVub190eXBlX2Rlc3RydWN0RGF0YSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVub19kYXRhLCBjb21wX3RkLT5wcFR5cGVSZWZzWyBuQ2xlYW51cCBdLCAwICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICgwICE9IGNvbXBfdGQtPnBCYXNlVHlwZURlc2NyaXB0aW9uKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdW5vX2Rlc3RydWN0RGF0YSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVub19kYXRhLCAodHlwZWxpYl9UeXBlRGVzY3JpcHRpb24gKiljb21wX3RkLT5wQmFzZVR5cGVEZXNjcmlwdGlvbiwgMCApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19TRVFVRU5DRToKICAgICAgICB7CiAgICAgICAgICAgIFR5cGVEZXNjciB0ZCggdHlwZSApOwogICAgICAgICAgICB0eXBlbGliX1R5cGVEZXNjcmlwdGlvblJlZmVyZW5jZSAqIGVsZW1lbnRfdHlwZSA9CiAgICAgICAgICAgICAgICAoKHR5cGVsaWJfSW5kaXJlY3RUeXBlRGVzY3JpcHRpb24gKil0ZC5nZXQoKSktPnBUeXBlOwoKICAgICAgICAgICAgYXV0b19wdHI8IHJ0bF9tZW0gPiBzZXE7CgogICAgICAgICAgICBTeXN0ZW06OkFycmF5KiBhciA9IE5VTEw7CiAgICAgICAgICAgIGlmIChjbGlfZGF0YSAhPSBOVUxMKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhciA9IF9fdHJ5X2Nhc3Q8U3lzdGVtOjpBcnJheSo+KGNsaV9kYXRhKTsKICAgICAgICAgICAgICAgIHNhbF9JbnQzMiBuRWxlbWVudHMgPSBhci0+R2V0TGVuZ3RoKDApOwoKICAgICAgICAgICAgICAgIHRyeQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoZWxlbWVudF90eXBlLT5lVHlwZUNsYXNzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0NIQVI6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlcSA9IHNlcV9hbGxvY2F0ZShuRWxlbWVudHMsIHNpemVvZiAoc2FsX1VuaWNvZGUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3JpOjpNYXJzaGFsOjpDb3B5KF9fdHJ5X2Nhc3Q8U3lzdGVtOjpDaGFyW10+KGNsaV9kYXRhKSwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYgKCh1bm9fU2VxdWVuY2UqKSBzZXEuZ2V0KCkpLT5lbGVtZW50cywgbkVsZW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19CT09MRUFOOgogICAgICAgICAgICAgICAgICAgICAgICBzZXEgPSBzZXFfYWxsb2NhdGUobkVsZW1lbnRzLCBzaXplb2YgKHNhbF9Cb29sKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNyaTo6TWFyc2hhbDo6Q29weShfX3RyeV9jYXN0PFN5c3RlbTo6Qm9vbGVhbltdPihjbGlfZGF0YSksIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmICgodW5vX1NlcXVlbmNlKikgc2VxLmdldCgpKS0+ZWxlbWVudHMsIG5FbGVtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQllURToKICAgICAgICAgICAgICAgICAgICAgICAgc2VxID0gc2VxX2FsbG9jYXRlKCBuRWxlbWVudHMsIHNpemVvZiAoc2FsX0ludDgpICk7CiAgICAgICAgICAgICAgICAgICAgc3JpOjpNYXJzaGFsOjpDb3B5KF9fdHJ5X2Nhc3Q8U3lzdGVtOjpCeXRlW10+KGNsaV9kYXRhKSwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiAoKHVub19TZXF1ZW5jZSopIHNlcS5nZXQoKSktPmVsZW1lbnRzLCBuRWxlbWVudHMpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfU0hPUlQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlcSA9IHNlcV9hbGxvY2F0ZShuRWxlbWVudHMsIHNpemVvZiAoc2FsX0ludDE2KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNyaTo6TWFyc2hhbDo6Q29weShfX3RyeV9jYXN0PFN5c3RlbTo6SW50MTZbXT4oY2xpX2RhdGEpLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiAoKHVub19TZXF1ZW5jZSopIHNlcS5nZXQoKSktPmVsZW1lbnRzLCBuRWxlbWVudHMpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1VOU0lHTkVEX1NIT1JUOgogICAgICAgICAgICAgICAgICAgICAgICBzZXEgPSBzZXFfYWxsb2NhdGUoIG5FbGVtZW50cywgc2l6ZW9mIChzYWxfdUludDE2KSApOwogICAgICAgICAgICAgICAgICAgICAgICBzcmk6Ok1hcnNoYWw6OkNvcHkoc3RhdGljX2Nhc3Q8U3lzdGVtOjpJbnQxNltdPigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX3RyeV9jYXN0PFN5c3RlbTo6VUludDE2W10+KGNsaV9kYXRhKSksIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmICgodW5vX1NlcXVlbmNlKikgc2VxLmdldCgpKS0+ZWxlbWVudHMsIG5FbGVtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfTE9ORzoKICAgICAgICAgICAgICAgICAgICAgICAgc2VxID0gc2VxX2FsbG9jYXRlKG5FbGVtZW50cywgc2l6ZW9mIChzYWxfSW50MzIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3JpOjpNYXJzaGFsOjpDb3B5KF9fdHJ5X2Nhc3Q8U3lzdGVtOjpJbnQzMltdPihjbGlfZGF0YSksIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmICgodW5vX1NlcXVlbmNlKikgc2VxLmdldCgpKS0+ZWxlbWVudHMsIG5FbGVtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfVU5TSUdORURfTE9ORzoKICAgICAgICAgICAgICAgICAgICAgICAgc2VxID0gc2VxX2FsbG9jYXRlKCBuRWxlbWVudHMsIHNpemVvZiAoc2FsX3VJbnQzMikgKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3JpOjpNYXJzaGFsOjpDb3B5KHN0YXRpY19jYXN0PFN5c3RlbTo6SW50MzJbXT4oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX190cnlfY2FzdDxTeXN0ZW06OlVJbnQzMltdPihjbGlfZGF0YSkpLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiAoKHVub19TZXF1ZW5jZSopIHNlcS5nZXQoKSktPmVsZW1lbnRzLCBuRWxlbWVudHMpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0hZUEVSOgogICAgICAgICAgICAgICAgICAgICAgICBzZXEgPSBzZXFfYWxsb2NhdGUobkVsZW1lbnRzLCBzaXplb2YgKHNhbF9JbnQ2NCkpOwogICAgICAgICAgICAgICAgICAgICAgICBzcmk6Ok1hcnNoYWw6OkNvcHkoX190cnlfY2FzdDxTeXN0ZW06OkludDY0W10+KGNsaV9kYXRhKSwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYgKCh1bm9fU2VxdWVuY2UqKSBzZXEuZ2V0KCkpLT5lbGVtZW50cywgbkVsZW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19VTlNJR05FRF9IWVBFUjoKICAgICAgICAgICAgICAgICAgICAgICAgc2VxID0gc2VxX2FsbG9jYXRlKG5FbGVtZW50cywgc2l6ZW9mIChzYWxfdUludDY0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNyaTo6TWFyc2hhbDo6Q29weShzdGF0aWNfY2FzdDxTeXN0ZW06OkludDY0W10+KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fdHJ5X2Nhc3Q8U3lzdGVtOjpVSW50NjRbXT4oY2xpX2RhdGEpKSwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYgKCh1bm9fU2VxdWVuY2UqKSBzZXEuZ2V0KCkpLT5lbGVtZW50cywgbkVsZW1lbnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19GTE9BVDoKICAgICAgICAgICAgICAgICAgICAgICAgc2VxID0gc2VxX2FsbG9jYXRlKG5FbGVtZW50cywgc2l6ZW9mIChmbG9hdCkpOwogICAgICAgICAgICAgICAgICAgICAgICBzcmk6Ok1hcnNoYWw6OkNvcHkoX190cnlfY2FzdDxTeXN0ZW06OlNpbmdsZVtdPihjbGlfZGF0YSksIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmICgodW5vX1NlcXVlbmNlKikgc2VxLmdldCgpKS0+ZWxlbWVudHMsIG5FbGVtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRE9VQkxFOgogICAgICAgICAgICAgICAgICAgICAgICBzZXEgPSBzZXFfYWxsb2NhdGUobkVsZW1lbnRzLCBzaXplb2YgKGRvdWJsZSkpOwogICAgICAgICAgICAgICAgICAgICAgICBzcmk6Ok1hcnNoYWw6OkNvcHkoX190cnlfY2FzdDxTeXN0ZW06OkRvdWJsZVtdPihjbGlfZGF0YSksIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmICgodW5vX1NlcXVlbmNlKikgc2VxLmdldCgpKS0+ZWxlbWVudHMsIG5FbGVtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfU1RSSU5HOgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2VxID0gc2VxX2FsbG9jYXRlKG5FbGVtZW50cywgc2l6ZW9mIChydGxfdVN0cmluZyopKTsKICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtOjpTdHJpbmcqIGFyU3RyW109IF9fdHJ5X2Nhc3Q8U3lzdGVtOjpTdHJpbmcqW10+KGNsaV9kYXRhKTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaT0gMDsgaSA8IG5FbGVtZW50czsgaSsrKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3Y2hhcl90IGNvbnN0IF9fcGluICogcGRhdGE9IFB0clRvU3RyaW5nQ2hhcnMoYXJTdHJbaV0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcnRsX3VTdHJpbmcqKiBwU3RyPSAgJiAoKHJ0bF91U3RyaW5nKiopICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgodW5vX1NlcXVlbmNlKikgc2VxLmdldCgpKS0+ZWxlbWVudHMpW2ldOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgKnBTdHI9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBydGxfdVN0cmluZ19uZXdGcm9tU3RyX1dpdGhMZW5ndGgoIHBTdHIsIHBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhclN0cltpXS0+Z2V0X0xlbmd0aCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19FTlVNOgogICAgICAgICAgICAgICAgICAgICAgICBzZXEgPSBzZXFfYWxsb2NhdGUobkVsZW1lbnRzLCBzaXplb2YgKHNhbF9JbnQzMikpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpPSAwOyBpIDwgbkVsZW1lbnRzOyBpKyspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoc2FsX0ludDMyKikgJigodW5vX1NlcXVlbmNlKikgc2VxLmdldCgpKS0+ZWxlbWVudHMpW2ldPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbTo6Q29udmVydDo6VG9JbnQzMihhci0+R2V0VmFsdWUoaSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfVFlQRToKICAgICAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0FOWToKICAgICAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NUUlVDVDoKICAgICAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0VYQ0VQVElPTjoKICAgICAgICAgICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NFUVVFTkNFOgogICAgICAgICAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfSU5URVJGQUNFOgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgVHlwZURlc2NyIGVsZW1lbnRfdGQoIGVsZW1lbnRfdHlwZSApOwogICAgICAgICAgICAgICAgICAgICAgICBzZXEgPSBzZXFfYWxsb2NhdGUoIG5FbGVtZW50cywgZWxlbWVudF90ZC5nZXQoKS0+blNpemUgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoc2FsX0ludDMyIG5Qb3MgPSAwOyBuUG9zIDwgbkVsZW1lbnRzOyArK25Qb3MpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKiBwPSAoKHVub19TZXF1ZW5jZSAqKSBzZXEuZ2V0KCkpLT5lbGVtZW50cyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuUG9zICogZWxlbWVudF90ZC5nZXQoKS0+blNpemUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbTo6T2JqZWN0KiBlbGVtRGF0YT0gZHluYW1pY19jYXN0PFN5c3RlbTo6QXJyYXkqPihjbGlfZGF0YSktPkdldFZhbHVlKG5Qb3MpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcF90b191bm8oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAsIGVsZW1EYXRhLCBlbGVtZW50X3RkLmdldCgpLT5wV2Vha1JlZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UgLyogbm8gYXNzaWduICovKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoICguLi4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2xlYW51cAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoIHNhbF9JbnQzMiBuQ2xlYW5Qb3MgPSAwOyBuQ2xlYW5Qb3MgPCBuUG9zOyArK25DbGVhblBvcyApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICogcCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKHVub19TZXF1ZW5jZSAqKXNlcS5nZXQoKSktPmVsZW1lbnRzICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuQ2xlYW5Qb3MgKiBlbGVtZW50X3RkLmdldCgpLT5uU2l6ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVub19kZXN0cnVjdERhdGEoIHAsIGVsZW1lbnRfdGQuZ2V0KCksIDAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3c7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBPVVN0cmluZ0J1ZmZlciBidWYoIDEyOCApOwogICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kQXNjaWkoIFJUTF9DT05TVEFTQ0lJX1NUUklOR1BBUkFNKCJbbWFwX3RvX3VubygpOiIpICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmQoICpyZWludGVycHJldF9jYXN0PCBPVVN0cmluZyBjb25zdCAqID4oICZ0eXBlLT5wVHlwZU5hbWUgKSApOwogICAgICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kQXNjaWkoIFJUTF9DT05TVEFTQ0lJX1NUUklOR1BBUkFNKCJdIHVuc3VwcG9ydGVkIHNlcXVlbmNlIGVsZW1lbnQgdHlwZTogIikgKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCggKnJlaW50ZXJwcmV0X2Nhc3Q8IE9VU3RyaW5nIGNvbnN0ICogPiggJmVsZW1lbnRfdHlwZS0+cFR5cGVOYW1lICkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgQnJpZGdlUnVudGltZUVycm9yKCBidWYubWFrZVN0cmluZ0FuZENsZWFyKCkgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2F0Y2ggKEJyaWRnZVJ1bnRpbWVFcnJvciYgZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBPVVN0cmluZ0J1ZmZlciBidWYoIDEyOCApOwogICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmRBc2NpaSggUlRMX0NPTlNUQVNDSUlfU1RSSU5HUEFSQU0oIlttYXBfdG9fdW5vKCk6IikgKTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCAqcmVpbnRlcnByZXRfY2FzdDwgT1VTdHJpbmcgY29uc3QgKiA+KCAmdHlwZS0+cFR5cGVOYW1lICkpOwogICAgICAgICAgICAgICAgICAgIGJ1Zi5hcHBlbmRBc2NpaSggUlRMX0NPTlNUQVNDSUlfU1RSSU5HUEFSQU0oIl0gY29udmVyc2lvbiBmYWlsZWRcbiAiKSk7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZChlLm1fbWVzc2FnZSk7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgQnJpZGdlUnVudGltZUVycm9yKGJ1Zi5tYWtlU3RyaW5nQW5kQ2xlYXIoKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXRjaCAoU3lzdGVtOjpJbnZhbGlkQ2FzdEV4Y2VwdGlvbiogKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIE9rLCBjaGVja2VkCiAgICAgICAgICAgICAgICAgICAgT1VTdHJpbmdCdWZmZXIgYnVmKCAxMjggKTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kQXNjaWkoIFJUTF9DT05TVEFTQ0lJX1NUUklOR1BBUkFNKCJbbWFwX3RvX3VubygpOiIpICk7CiAgICAgICAgICAgICAgICAgICAgYnVmLmFwcGVuZCggKnJlaW50ZXJwcmV0X2Nhc3Q8IE9VU3RyaW5nIGNvbnN0ICogPiggJnR5cGUtPnBUeXBlTmFtZSkgKTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kQXNjaWkoIFJUTF9DT05TVEFTQ0lJX1NUUklOR1BBUkFNKCJdIGNvdWxkIG5vdCBjb252ZXJ0IHNlcXVlbmNlIGVsZW1lbnQgdHlwZTogIikgKTsKICAgICAgICAgICAgICAgICAgICBidWYuYXBwZW5kKCAqcmVpbnRlcnByZXRfY2FzdDwgT1VTdHJpbmcgY29uc3QgKiA+KCAmZWxlbWVudF90eXBlLT5wVHlwZU5hbWUgKSApOwogICAgICAgICAgICAgICAgICAgIHRocm93IEJyaWRnZVJ1bnRpbWVFcnJvciggYnVmLm1ha2VTdHJpbmdBbmRDbGVhcigpICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXRjaCAoLi4uKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE9TTF9BU1NFUlQoMCk7CiAgICAgICAgICAgICAgICAgICAgdGhyb3c7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBfX2ZpbmFsbHkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhc3NpZ24pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bm9fZGVzdHJ1Y3REYXRhKCB1bm9fZGF0YSwgdGQuZ2V0KCksIDAgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzZXEgPSBzZXFfYWxsb2NhdGUoMCwgc2l6ZW9mIChzYWxfSW50MzIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAqKHVub19TZXF1ZW5jZSAqKil1bm9fZGF0YSA9ICh1bm9fU2VxdWVuY2UgKilzZXEucmVsZWFzZSgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19JTlRFUkZBQ0U6CiAgICAgICAgewogICAgICAgICAgICBpZiAoYXNzaWduKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB1bm9fSW50ZXJmYWNlICogcCA9ICoodW5vX0ludGVyZmFjZSAqKil1bm9fZGF0YTsKICAgICAgICAgICAgICAgIGlmICgwICE9IHApCiAgICAgICAgICAgICAgICAgICAgKCpwLT5yZWxlYXNlKSggcCApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgwID09IGNsaV9kYXRhKSAvLyBudWxsLXJlZgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAqKHVub19JbnRlcmZhY2UgKiopdW5vX2RhdGEgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVHlwZURlc2NyIHRkKCB0eXBlICk7CiAgICAgICAgICAgICAgICB1bm9fSW50ZXJmYWNlICogcFVub0kgPSBtYXBfY2xpMnVubyhjbGlfZGF0YSwgdGQuZ2V0KCkpOwogICAgICAgICAgICAgICAgKih1bm9fSW50ZXJmYWNlICoqKXVub19kYXRhID0gcFVub0k7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgewogICAgICAgICAgICAvL1RvRG8gY2hlY2sKICAgICAgICAgICAgT1VTdHJpbmdCdWZmZXIgYnVmKCAxMjggKTsKICAgICAgICAgICAgYnVmLmFwcGVuZEFzY2lpKCBSVExfQ09OU1RBU0NJSV9TVFJJTkdQQVJBTSgiW21hcF90b191bm8oKToiKSApOwogICAgICAgICAgICBidWYuYXBwZW5kKCAqcmVpbnRlcnByZXRfY2FzdDwgT1VTdHJpbmcgY29uc3QgKiA+KCAmdHlwZS0+cFR5cGVOYW1lICkgKTsKICAgICAgICAgICAgYnVmLmFwcGVuZEFzY2lpKCBSVExfQ09OU1RBU0NJSV9TVFJJTkdQQVJBTSgiXSB1bnN1cHBvcnRlZCB0eXBlISIpICk7CiAgICAgICAgICAgIHRocm93IEJyaWRnZVJ1bnRpbWVFcnJvciggYnVmLm1ha2VTdHJpbmdBbmRDbGVhcigpICk7CiAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8vIEJyaWRnZVJ1bnRpbWVFcnJvciBhcmUgYWxsb3dlZCB0byBiZSB0aHJvd24KICAgIGNhdGNoIChTeXN0ZW06OkludmFsaWRDYXN0RXhjZXB0aW9uKiApCiAgICB7CiAgICAgICAgLy9Ub0RvIGNoZWNrCiAgICAgICAgT1VTdHJpbmdCdWZmZXIgYnVmKCAxMjggKTsKICAgICAgICBidWYuYXBwZW5kQXNjaWkoIFJUTF9DT05TVEFTQ0lJX1NUUklOR1BBUkFNKCJbbWFwX3RvX3VubygpOiIpICk7CiAgICAgICAgYnVmLmFwcGVuZCggKnJlaW50ZXJwcmV0X2Nhc3Q8IE9VU3RyaW5nIGNvbnN0ICogPiggJnR5cGUtPnBUeXBlTmFtZSApICk7CiAgICAgICAgYnVmLmFwcGVuZEFzY2lpKCBSVExfQ09OU1RBU0NJSV9TVFJJTkdQQVJBTSgiXSBjb3VsZCBub3QgY29udmVydCB0eXBlISIpICk7CiAgICAgICAgdGhyb3cgQnJpZGdlUnVudGltZUVycm9yKCBidWYubWFrZVN0cmluZ0FuZENsZWFyKCkgKTsKICAgIH0KICAgIGNhdGNoIChTeXN0ZW06Ok51bGxSZWZlcmVuY2VFeGNlcHRpb24gKiBlKQogICAgewogICAgICAgIE9VU3RyaW5nQnVmZmVyIGJ1Zig1MTIpOwogICAgICAgIGJ1Zi5hcHBlbmRBc2NpaShSVExfQ09OU1RBU0NJSV9TVFJJTkdQQVJBTSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiW21hcF90b191bm8oKV0gSWxsZWdhbCBudWxsIHJlZmVyZW5jZSBwYXNzZWQhXG4iKSk7CiAgICAgICAgYnVmLmFwcGVuZChtYXBDbGlTdHJpbmcoZS0+Z2V0X1N0YWNrVHJhY2UoKSkpOwogICAgICAgIHRocm93IEJyaWRnZVJ1bnRpbWVFcnJvciggYnVmLm1ha2VTdHJpbmdBbmRDbGVhcigpICk7CiAgICB9CiAgICBjYXRjaCAoQnJpZGdlUnVudGltZUVycm9yJiApCiAgICB7CiAgICAgICAgdGhyb3c7CiAgICB9CiAgICBjYXRjaCAoLi4uKQogICAgewogICAgICAgIE9TTF9BU1NFUlQoMCk7CiAgICAgICAgdGhyb3c7CiAgICB9Cgp9CgovKioKICAgQHBhcmFtIGluZm8KICAgICAgIFRoZSBleHBlY3RlZCB0YXJnZXQgdHlwZS4gQ3VycmVudGx5IGluZm8gaXMgcHJvdmRpZGVkIHdoZW4gdGhpcyBtZXRob2QgaXMgY2FsbGVkCiAgICAgICB0byBjb252ZXJ0IHRoZSBpbi9vdXQgYW5kIG91dCBwYXJhbWV0ZXJzIG9mIGEgY2FsbCBmcm9tIGNsaSB0byB1bm8uIFRoZW4gaW5mbwogICAgICAgaXMgYWx3YXlzIGEgYnlyZWYgdHlwZSwgZS5nLiAiU3lzdGVtLlN0cmluZyYiLiBpbmZvIGlzIHVzZWQgZm9yIEFueSBhbmQgRW51bSBjb252ZXJzaW9uLgogICBAcGFyYW0gYkRvbnRDcmVhdGVPYmoKICAgICAgIGZhbHNlIC0gYSBuZXcgb2JqZWN0IGlzIGNyZWF0ZWQgd2hpY2ggaG9sZHMgdGhlIG1hcHBlZCB1bm8gdmFsdWUgYW5kIGlzIGFzc2lnbmVkIHRvCiAgICAgICBjbGlfZGF0YS4KICAgICAgIHRydWUgLSBjbGlfZGF0YSBhbHJlYWR5IGNvbnRhaW5zIHRoZSBuZXdseSBjb25zdHJ1Y3RlZCBvYmplY3QuIFRoaXMgaXMgdGhlIGNhc2UgaWYKICAgICAgIGEgc3RydWN0IGlzIGNvbnZlcnRlZCB0aGVuIG9uIHRoZSBmaXJzdCBjYWxsIHRvIG1hcF90b19jbGkgdGhlIG5ldyBvYmplY3QgaXMgY3JlYXRlZC4KICAgICAgIElmIHRoZSBzdHJ1Y3QgaW5oZXJpdHMgYW5vdGhlciBzdHJ1Y3QgdGhlbiB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCByZWN1cnNpdmx5IHdoaWxlIHRoZQogICAgICAgbmV3bHkgY3JlYXRlZCBvYmplY3QgaXMgcGFzc2VkIGluIGNsaV9kYXRhLgogKi8Kdm9pZCBCcmlkZ2U6Om1hcF90b19jbGkoCiAgICBTeXN0ZW06Ok9iamVjdCogKmNsaV9kYXRhLCB2b2lkIGNvbnN0ICogdW5vX2RhdGEsCiAgICB0eXBlbGliX1R5cGVEZXNjcmlwdGlvblJlZmVyZW5jZSAqIHR5cGUsIFN5c3RlbTo6VHlwZSogaW5mbywKICAgIGJvb2wgYkRvbnRDcmVhdGVPYmopIGNvbnN0CnsKICAgIHN3aXRjaCAodHlwZS0+ZVR5cGVDbGFzcykKICAgIHsKICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQ0hBUjoKICAgICAgICAqY2xpX2RhdGE9IF9fYm94KCooX193Y2hhcl90IGNvbnN0Kil1bm9fZGF0YSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0JPT0xFQU46CiAgICAgICAgKmNsaV9kYXRhID0gX19ib3goKCooYm9vbCBjb25zdCopdW5vX2RhdGEpID09IHNhbF9UcnVlID8gdHJ1ZSA6IGZhbHNlKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQllURToKICAgICAgICAqY2xpX2RhdGEgPSBfX2JveCgqKHVuc2lnbmVkIGNoYXIgY29uc3QqKSB1bm9fZGF0YSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NIT1JUOgogICAgICAgICpjbGlfZGF0YT0gX19ib3goKihzaG9ydCBjb25zdCopIHVub19kYXRhKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfVU5TSUdORURfU0hPUlQ6CiAgICAgICAgKmNsaV9kYXRhPSBfX2JveCgqKHVuc2lnbmVkIHNob3J0IGNvbnN0KikgdW5vX2RhdGEpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19MT05HOgogICAgICAgICpjbGlfZGF0YT0gX19ib3goKihpbnQgY29uc3QqKSB1bm9fZGF0YSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1VOU0lHTkVEX0xPTkc6CiAgICAgICAgKmNsaV9kYXRhPSBfX2JveCgqKHVuc2lnbmVkIGludCBjb25zdCopIHVub19kYXRhKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfSFlQRVI6CiAgICAgICAgKmNsaV9kYXRhPSBfX2JveCgqKF9faW50NjQgY29uc3QqKSB1bm9fZGF0YSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1VOU0lHTkVEX0hZUEVSOgogICAgICAgICpjbGlfZGF0YT0gX19ib3goKih1bnNpZ25lZCBfX2ludDY0IGNvbnN0KikgdW5vX2RhdGEpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19GTE9BVDoKICAgICAgICAqY2xpX2RhdGE9IF9fYm94KCooZmxvYXQgY29uc3QqKSB1bm9fZGF0YSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0RPVUJMRToKICAgICAgICAqY2xpX2RhdGE9IF9fYm94KCooZG91YmxlIGNvbnN0KikgdW5vX2RhdGEpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19TVFJJTkc6CiAgICB7CiAgICAgICAgcnRsX3VTdHJpbmcgY29uc3QqIHNWYWw9IE5VTEw7CiAgICAgICAgc1ZhbD0gKihydGxfdVN0cmluZyogY29uc3QqKSB1bm9fZGF0YTsKICAgICAgICAqY2xpX2RhdGE9IG5ldyBTeXN0ZW06OlN0cmluZygoX193Y2hhcl90Kikgc1ZhbC0+YnVmZmVyLDAsIHNWYWwtPmxlbmd0aCk7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1RZUEU6CiAgICAgewogICAgICAgICAqY2xpX2RhdGE9IG1hcFVub1R5cGUoICoodHlwZWxpYl9UeXBlRGVzY3JpcHRpb25SZWZlcmVuY2UgKiBjb25zdCAqKXVub19kYXRhICk7CiAgICAgICAgIGJyZWFrOwogICAgIH0KICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQU5ZOgogICAgewogICAgICAgIHVub19BbnkgY29uc3QgKiBwQW55ID0gKHVub19BbnkgY29uc3QgKil1bm9fZGF0YTsKICAgICAgICBpZiAodHlwZWxpYl9UeXBlQ2xhc3NfVk9JRCAhPSBwQW55LT5wVHlwZS0+ZVR5cGVDbGFzcykKICAgICAgICB7CiAgICAgICAgICAgIFN5c3RlbTo6T2JqZWN0KiBvYmpDbGk9IE5VTEw7CiAgICAgICAgICAgIG1hcF90b19jbGkoCiAgICAgICAgICAgICAgICAmb2JqQ2xpLCBwQW55LT5wRGF0YSwgcEFueS0+cFR5cGUsIDAsCiAgICAgICAgICAgICAgICBmYWxzZSk7CgogICAgICAgICAgICB1bm86OkFueSBhbnlWYWwobWFwVW5vVHlwZShwQW55LT5wVHlwZSksIG9iakNsaSk7CiAgICAgICAgICAgICpjbGlfZGF0YT0gX19ib3goYW55VmFsKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsgLy8gdm9pZCBhbnkKICAgICAgICAgICAgKmNsaV9kYXRhPSBfX2JveCh1bm86OkFueTo6Vk9JRCk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQogICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19FTlVNOgogICAgIHsKICAgICAgICAgaWYgKGluZm8gIT0gTlVMTCkKICAgICAgICAgewogICAgICAgICAgICAgT1NMX0FTU0VSVChpbmZvLT5nZXRfSXNCeVJlZigpKTsKICAgICAgICAgICAgIGluZm89IGluZm8tPkdldEVsZW1lbnRUeXBlKCk7CiAgICAgICAgICAgICAqY2xpX2RhdGE9IFN5c3RlbTo6RW51bTo6VG9PYmplY3QoaW5mbywgKihTeXN0ZW06OkludDMyKikgdW5vX2RhdGEpOwogICAgICAgICB9CiAgICAgICAgIGVsc2UKICAgICAgICAgICAgICpjbGlfZGF0YT0gU3lzdGVtOjpFbnVtOjpUb09iamVjdCgKICAgICAgICAgICAgICAgICBtYXBVbm9UeXBlKHR5cGUpLCAqKFN5c3RlbTo6SW50MzIqKSB1bm9fZGF0YSk7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NUUlVDVDoKICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRVhDRVBUSU9OOgogICAgewogICAgICAgIFR5cGVEZXNjciB0ZCggdHlwZSApOwogICAgICAgIHR5cGVsaWJfQ29tcG91bmRUeXBlRGVzY3JpcHRpb24gKiBjb21wX3RkID0KICAgICAgICAgICAgKHR5cGVsaWJfQ29tcG91bmRUeXBlRGVzY3JpcHRpb24gKikgdGQuZ2V0KCk7CiAgICAgICAgaWYgKCAhICgodHlwZWxpYl9UeXBlRGVzY3JpcHRpb24qKSBjb21wX3RkKS0+YkNvbXBsZXRlKQogICAgICAgICAgICAgICAgOjp0eXBlbGliX3R5cGVkZXNjcmlwdGlvbl9jb21wbGV0ZSgKICAgICAgICAgICAgICAgICAgICAodHlwZWxpYl9UeXBlRGVzY3JpcHRpb24qKikgJiBjb21wX3RkICk7CgoKICAgICAgICAvL2NyZWF0ZSB0aGUgdHlwZQogICAgICAgIFN5c3RlbTo6VHlwZSogY2xpVHlwZT0gbG9hZENsaVR5cGUodGQuZ2V0KCktPnBUeXBlTmFtZSk7CiAgICAgICAgLy9kZXRlY3QgaWYgd2UgcmVjdXJzaXZseSBjb252ZXJ0IGluaGVyaXRlZCBzdHJ1Y3R1cmVzCiAgICAgICAgLy9JZiB0aGlzIHBvaW50IGlzIHJlYWNoZWQgYmVjYXVzZSBvZiBhIHJlY3Vyc2l2ZSBjYWxsIGR1cmluZyBjb252ZXJpbmcgYQogICAgICAgIC8vc3RydWN0IHRoZW4gd2UgbXVzdCBub3QgY3JlYXRlIGEgbmV3IG9iamVjdCByYXRoZXIgd2UgdXNlIHRoZSBvbmUgaW4KICAgICAgICAvLyBjbGlfZGF0YSBhcmd1bWVudC4KICAgICAgICBTeXN0ZW06Ok9iamVjdCogY2xpT2JqOwogICAgICAgIGlmIChiRG9udENyZWF0ZU9iaikKICAgICAgICAgICAgY2xpT2JqID0gKmNsaV9kYXRhOyAvLyByZWN1cnNpdmUgY2FsbAogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8vU3BlY2lhbCBoYW5kbGluZyBmb3IgRXhjZXB0aW9uIGNvbnZlcnNpb24uIFdlIG11c3QgY2FsbCBjb25zdHJ1Y3RvciBTeXN0ZW06OkV4Y2VwdGlvbgogICAgICAgICAgICAvL3RvIHBhc3MgdGhlIG1lc3NhZ2Ugc3RyaW5nCiAgICAgICAgICAgIGlmIChfX3R5cGVvZih1Y3NzOjp1bm86OkV4Y2VwdGlvbiktPklzQXNzaWduYWJsZUZyb20oY2xpVHlwZSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vV2UgbmVlZCB0byBnZXQgdGhlIE1lc3NhZ2UgZmllbGQuIFRoZXJlZm9yZSB3ZSBtdXN0IG9idGFpbiB0aGUgb2Zmc2V0IGZyb20KICAgICAgICAgICAgICAgIC8vdGhlIHR5cGVkZXNjcmlwdGlvbi4gVGhlIGJhc2UgaW50ZXJmYWNlIG9mIGFsbCBleGNlcHRpb25zIGlzCiAgICAgICAgICAgICAgICAvL2NvbTo6c3VuOjpzdGFyOjp1bm86OkV4Y2VwdGlvbiB3aGljaCBjb250YWlucyB0aGUgbWVzc2FnZQogICAgICAgICAgICAgICAgdHlwZWxpYl9Db21wb3VuZFR5cGVEZXNjcmlwdGlvbiogcENURCA9IGNvbXBfdGQ7CiAgICAgICAgICAgICAgICB3aGlsZSAocENURC0+cEJhc2VUeXBlRGVzY3JpcHRpb24pCiAgICAgICAgICAgICAgICAgICAgcENURCA9IHBDVEQtPnBCYXNlVHlwZURlc2NyaXB0aW9uOwogICAgICAgICAgICAgICAgaW50IG5Qb3MgPSAtMTsKCgkJCQlydGw6Ok9VU3RyaW5nIHVzTWVzc2FnZU1lbWJlcihSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIk1lc3NhZ2UiKSk7CiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHBDVEQtPm5NZW1iZXJzOyBpICsrKQogICAgICAgICAgICAgICAgewojaWYgT1NMX0RFQlVHX0xFVkVMID49IDIKICAgICAgICAgICAgICAgICAgICBTeXN0ZW06OlN0cmluZyogc01lbWJlcjsKICAgICAgICAgICAgICAgICAgICBzTWVtYmVyID0gbWFwVW5vU3RyaW5nKHBDVEQtPnBwTWVtYmVyTmFtZXNbaV0pOwojZW5kaWYKICAgICAgICAgICAgICAgICAgICBpZiAodXNNZXNzYWdlTWVtYmVyLmVxdWFscyhwQ1RELT5wcE1lbWJlck5hbWVzW2ldKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG5Qb3MgPSBpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBPU0xfQVNTRVJUIChuUG9zICE9IC0xKTsKICAgICAgICAgICAgICAgIGludCBvZmZzZXQgPSBwQ1RELT5wTWVtYmVyT2Zmc2V0c1tuUG9zXTsKICAgICAgICAgICAgICAgIC8vV2l0aCB0aGUgb2Zmc2V0IHdpdGhpbiB0aGUgZXhjZXB0aW9uIHdlIGNhbiBnZXQgdGhlIG1lc3NhZ2Ugc3RyaW5nCiAgICAgICAgICAgICAgICBTeXN0ZW06OlN0cmluZyogc01lc3NhZ2UgPSBtYXBVbm9TdHJpbmcoKihydGxfdVN0cmluZyoqKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoY2hhciopIHVub19kYXRhICsgb2Zmc2V0KSk7CiAgICAgICAgICAgICAgICAvL1dlIG5lZWQgdG8gZmluZCBhIGNvbnN0cnVjdG9yIGZvciB0aGUgZXhjZXB0aW9uIHRoYXQgdGFrZXMgdGhlIG1lc3NhZ2Ugc3RyaW5nCiAgICAgICAgICAgICAgICAvL1dlIGFzc3VtZSB0aGF0IHRoZSBmaXJzdCBhcmd1bWVudCBpcyB0aGUgbWVzc2FnZSBzdHJpbmcKICAgICAgICAgICAgICAgIHNyOjpDb25zdHJ1Y3RvckluZm8qIGFyQ3RvckluZm9bXSA9IGNsaVR5cGUtPkdldENvbnN0cnVjdG9ycygpOwogICAgICAgICAgICAgICAgc3I6OkNvbnN0cnVjdG9ySW5mbyogY3RvckluZm8gPSBOVUxMOwogICAgICAgICAgICAgICAgaW50IG51bUN0b3JzID0gYXJDdG9ySW5mby0+Z2V0X0xlbmd0aCgpOwogICAgICAgICAgICAgICAgLy9Db25zdHJ1Y3RvciBtdXN0IGF0IGxlYXN0IGhhdmUgMiBwYXJhbXMgZm9yIHRoZSBiYXNlCiAgICAgICAgICAgICAgICAvL3Vub2lkbC5jb20uc3VuLnN0YXIudW5vLkV4Y2VwdGlvbiAoU3RyaW5nLCBPYmplY3QpOwogICAgICAgICAgICAgICAgc3I6OlBhcmFtZXRlckluZm8gKiBhclBhcmFtSW5mb1tdOwogICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBudW1DdG9yczsgaSsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFyUGFyYW1JbmZvID0gYXJDdG9ySW5mb1tpXS0+R2V0UGFyYW1ldGVycygpOwogICAgICAgICAgICAgICAgICAgIGlmIChhclBhcmFtSW5mby0+Z2V0X0xlbmd0aCgpIDwgMikKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgY3RvckluZm8gPSBhckN0b3JJbmZvW2ldOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgT1NMX0FTU0VSVChhclBhcmFtSW5mb1swXS0+Z2V0X1BhcmFtZXRlclR5cGUoKS0+RXF1YWxzKF9fdHlwZW9mKFN5c3RlbTo6U3RyaW5nKSkKICAgICAgICAgICAgICAgICAgICAmJiBhclBhcmFtSW5mb1sxXS0+Z2V0X1BhcmFtZXRlclR5cGUoKS0+RXF1YWxzKF9fdHlwZW9mKFN5c3RlbTo6T2JqZWN0KSkKICAgICAgICAgICAgICAgICAgICAmJiBhclBhcmFtSW5mb1swXS0+Z2V0X1Bvc2l0aW9uKCkgPT0gMAogICAgICAgICAgICAgICAgICAgICYmIGFyUGFyYW1JbmZvWzFdLT5nZXRfUG9zaXRpb24oKSA9PSAxKTsKICAgICAgICAgICAgICAgIC8vUHJlcGFyZSBwYXJhbWV0ZXJzIGZvciBjb25zdHJ1Y3RvcgogICAgICAgICAgICAgICAgaW50IG51bUFyZ3MgPSBhclBhcmFtSW5mby0+Z2V0X0xlbmd0aCgpOwogICAgICAgICAgICAgICAgU3lzdGVtOjpPYmplY3QgKiBhcmdzW10gPSBuZXcgU3lzdGVtOjpPYmplY3QqW251bUFyZ3NdOwogICAgICAgICAgICAgICAgLy9vbmx5IGluaXRpYWxpemUgdGhlIGZpcnN0IGFyZ3VtZW50IHdpdGggdGhlIG1lc3NhZ2UKICAgICAgICAgICAgICAgIGFyZ3NbMF0gPSBzTWVzc2FnZTsKICAgICAgICAgICAgICAgIGNsaU9iaiA9IGN0b3JJbmZvLT5JbnZva2UoYXJncyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgY2xpT2JqID0gU3lzdGVtOjpBY3RpdmF0b3I6OkNyZWF0ZUluc3RhbmNlKGNsaVR5cGUpOwogICAgICAgIH0KICAgICAgICBzYWxfSW50MzIgKiBwTWVtYmVyT2Zmc2V0cyA9IGNvbXBfdGQtPnBNZW1iZXJPZmZzZXRzOwoKICAgICAgICBpZiAoY29tcF90ZC0+cEJhc2VUeXBlRGVzY3JpcHRpb24pCiAgICAgICAgewogICAgICAgICAgICAvL2NvbnZlcnQgaW5oZXJpdGVkIHN0cnVjdAogICAgICAgICAgICAvL2NsaU9iaiBpcyBwYXNzZWQgaW5vdXQgKGFyZ3MgaW5fcGFyYW0sIG91dF9wYXJhbSBhcmUgdHJ1ZSksIGhlbmNlIHRoZSBwYXNzZWQKICAgICAgICAgICAgLy8gY2xpT2JqIGlzIHVzZWQgYnkgdGhlIGNhbGxlZSBpbnN0ZWFkIG9mIGEgbmV3bHkgY3JlYXRlZCBzdHJ1Y3QKICAgICAgICAgICAgbWFwX3RvX2NsaSgKICAgICAgICAgICAgICAgICZjbGlPYmosIHVub19kYXRhLAogICAgICAgICAgICAgICAgKCh0eXBlbGliX1R5cGVEZXNjcmlwdGlvbiAqKWNvbXBfdGQtPnBCYXNlVHlwZURlc2NyaXB0aW9uKS0+cFdlYWtSZWYsIDAsCiAgICAgICAgICAgICAgICB0cnVlKTsKICAgICAgICB9CgkJcnRsOjpPVVN0cmluZyB1c1Vub0V4Y2VwdGlvbihSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oImNvbS5zdW4uc3Rhci51bm8uRXhjZXB0aW9uIikpOwogICAgICAgIGZvciAoc2FsX0ludDMyIG5Qb3MgPSBjb21wX3RkLT5uTWVtYmVyczsgblBvcy0tOyApCiAgICAgICAgewogICAgICAgICAgICB0eXBlbGliX1R5cGVEZXNjcmlwdGlvblJlZmVyZW5jZSAqIG1lbWJlcl90eXBlID0gY29tcF90ZC0+cHBUeXBlUmVmc1sgblBvcyBdOwogICAgICAgICAgICBTeXN0ZW06OlN0cmluZyogc01lbWJlck5hbWU9IG1hcFVub1N0cmluZyhjb21wX3RkLT5wcE1lbWJlck5hbWVzW25Qb3NdKTsKICAgICAgICAgICAgc3I6OkZpZWxkSW5mbyogYUZpZWxkPSBjbGlUeXBlLT5HZXRGaWVsZChzTWVtYmVyTmFtZSk7CiAgICAgICAgICAgIC8vIHNwZWNpYWwgY2FzZSBmb3IgRXhjZXB0aW9uLk1lc3NhZ2UuIFRoZSBmaWVsZCBoYXMgYWxyZWFkeSBiZWVuCiAgICAgICAgICAgIC8vIHNldCB3aGlsZSBjb25zdHJ1Y3RpbmcgY2xpIG9iamVjdAogICAgICAgICAgICBpZiAoICEgYUZpZWxkICYmIHVzVW5vRXhjZXB0aW9uLmVxdWFscyh0ZC5nZXQoKS0+cFR5cGVOYW1lKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdm9pZCBjb25zdCAqIHAgPSAoY2hhciBjb25zdCAqKXVub19kYXRhICsgcE1lbWJlck9mZnNldHNbIG5Qb3MgXTsKICAgICAgICAgICAgc3dpdGNoIChtZW1iZXJfdHlwZS0+ZVR5cGVDbGFzcykKICAgICAgICAgICAgewogICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0NIQVI6CiAgICAgICAgICAgICAgICBhRmllbGQtPlNldFZhbHVlKGNsaU9iaiwgX19ib3goKihTeXN0ZW06OkNoYXIqKSBwKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19CT09MRUFOOgogICAgICAgICAgICAgICAgYUZpZWxkLT5TZXRWYWx1ZShjbGlPYmosIF9fYm94KCooU3lzdGVtOjpCb29sZWFuKikgcCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQllURToKICAgICAgICAgICAgICAgIGFGaWVsZC0+U2V0VmFsdWUoY2xpT2JqLCBfX2JveCgqKFN5c3RlbTo6Qnl0ZSopIHApKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NIT1JUOgogICAgICAgICAgICAgICAgYUZpZWxkLT5TZXRWYWx1ZShjbGlPYmosIF9fYm94KCooU3lzdGVtOjpJbnQxNiopIHApKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1VOU0lHTkVEX1NIT1JUOgogICAgICAgICAgICAgICAgYUZpZWxkLT5TZXRWYWx1ZShjbGlPYmosIF9fYm94KCooU3lzdGVtOjpVSW50MTYqKSBwKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19MT05HOgogICAgICAgICAgICAgICAgYUZpZWxkLT5TZXRWYWx1ZShjbGlPYmosIF9fYm94KCooU3lzdGVtOjpJbnQzMiopIHApKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1VOU0lHTkVEX0xPTkc6CiAgICAgICAgICAgICAgICBhRmllbGQtPlNldFZhbHVlKGNsaU9iaiwgX19ib3goKihTeXN0ZW06OlVJbnQzMiopIHApKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0hZUEVSOgogICAgICAgICAgICAgICAgYUZpZWxkLT5TZXRWYWx1ZShjbGlPYmosIF9fYm94KCooU3lzdGVtOjpJbnQ2NCopIHApKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1VOU0lHTkVEX0hZUEVSOgogICAgICAgICAgICAgICAgYUZpZWxkLT5TZXRWYWx1ZShjbGlPYmosIF9fYm94KCooU3lzdGVtOjpVSW50NjQqKSBwKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19GTE9BVDoKICAgICAgICAgICAgICAgIGFGaWVsZC0+U2V0VmFsdWUoY2xpT2JqLCBfX2JveCgqKFN5c3RlbTo6U2luZ2xlKikgcCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRE9VQkxFOgogICAgICAgICAgICAgICAgYUZpZWxkLT5TZXRWYWx1ZShjbGlPYmosIF9fYm94KCooU3lzdGVtOjpEb3VibGUqKSBwKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU3lzdGVtOjpPYmplY3QqIGNsaV92YWw7CiAgICAgICAgICAgICAgICBtYXBfdG9fY2xpKAogICAgICAgICAgICAgICAgICAgICZjbGlfdmFsLCBwLCBtZW1iZXJfdHlwZSwgMCwKICAgICAgICAgICAgICAgICAgICBmYWxzZSk7CiAgICAgICAgICAgICAgICBhRmllbGQtPlNldFZhbHVlKGNsaU9iaiwgY2xpX3ZhbCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICpjbGlfZGF0YT0gY2xpT2JqOwogICAgICAgIGJyZWFrOwogICAgfQogICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19TRVFVRU5DRToKICAgIHsKICAgICAgICBzYWxfSW50MzIgbkVsZW1lbnRzOwogICAgICAgIHVub19TZXF1ZW5jZSBjb25zdCAqIHNlcSA9IDA7CiAgICAgICAgc2VxID0gKih1bm9fU2VxdWVuY2UgKiBjb25zdCAqKXVub19kYXRhOwogICAgICAgIG5FbGVtZW50cyA9IHNlcS0+bkVsZW1lbnRzOwoKICAgICAgICBUeXBlRGVzY3IgdGQoIHR5cGUgKTsKICAgICAgICB0eXBlbGliX1R5cGVEZXNjcmlwdGlvblJlZmVyZW5jZSAqIGVsZW1lbnRfdHlwZSA9CiAgICAgICAgICAgICgodHlwZWxpYl9JbmRpcmVjdFR5cGVEZXNjcmlwdGlvbiAqKXRkLmdldCgpKS0+cFR5cGU7CgogICAgICAgIHN3aXRjaCAoZWxlbWVudF90eXBlLT5lVHlwZUNsYXNzKQogICAgICAgIHsKICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0NIQVI6CiAgICAgICAgewogICAgICAgICAgICBTeXN0ZW06OkNoYXIgYXJDaGFyW109IG5ldyBTeXN0ZW06OkNoYXJbbkVsZW1lbnRzXTsKICAgICAgICAgICAgc3JpOjpNYXJzaGFsOjpDb3B5KCAodm9pZCopICZzZXEtPmVsZW1lbnRzLCBhckNoYXIsIDAsIG5FbGVtZW50cyk7CiAgICAgICAgICAgICpjbGlfZGF0YT0gYXJDaGFyOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19CT09MRUFOOgogICAgICAgIHsKICAgICAgICAgICAgU3lzdGVtOjpCb29sZWFuIGFyQm9vbFtdPSBuZXcgU3lzdGVtOjpCb29sZWFuW25FbGVtZW50c107CiAgICAgICAgICAgIHNyaTo6TWFyc2hhbDo6Q29weSggKHZvaWQqKSAmc2VxLT5lbGVtZW50cywgYXJCb29sLCAwLCBuRWxlbWVudHMpOwogICAgICAgICAgICAqY2xpX2RhdGE9IGFyQm9vbDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfQllURToKICAgICAgICB7CiAgICAgICAgICAgIFN5c3RlbTo6Qnl0ZSBhckJ5dGVbXT0gbmV3IFN5c3RlbTo6Qnl0ZVtuRWxlbWVudHNdOwogICAgICAgICAgICBzcmk6Ok1hcnNoYWw6OkNvcHkoICh2b2lkKikgJnNlcS0+ZWxlbWVudHMsIGFyQnl0ZSwgMCwgbkVsZW1lbnRzKTsKICAgICAgICAgICAgKmNsaV9kYXRhPSBhckJ5dGU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NIT1JUOgogICAgICAgIHsKICAgICAgICAgICAgU3lzdGVtOjpJbnQxNiBhclNob3J0W109IG5ldyBTeXN0ZW06OkludDE2W25FbGVtZW50c107CiAgICAgICAgICAgIHNyaTo6TWFyc2hhbDo6Q29weSggKHZvaWQqKSAmc2VxLT5lbGVtZW50cywgYXJTaG9ydCwgMCwgbkVsZW1lbnRzKTsKICAgICAgICAgICAgKmNsaV9kYXRhPSBhclNob3J0OwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19VTlNJR05FRF9TSE9SVDoKICAgICAgICB7CiAgICAgICAgICAgIFN5c3RlbTo6VUludDE2IGFyVUludDE2W109IG5ldyBTeXN0ZW06OlVJbnQxNltuRWxlbWVudHNdOwogICAgICAgICAgICBzcmk6Ok1hcnNoYWw6OkNvcHkoICh2b2lkKikgJnNlcS0+ZWxlbWVudHMsIHN0YXRpY19jYXN0PFN5c3RlbTo6SW50MTZbXT4oYXJVSW50MTYpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIG5FbGVtZW50cyk7CiAgICAgICAgICAgICpjbGlfZGF0YT0gYXJVSW50MTY7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0xPTkc6CiAgICAgICAgewogICAgICAgICAgICBTeXN0ZW06OkludDMyIGFySW50MzJbXT0gbmV3IFN5c3RlbTo6SW50MzJbbkVsZW1lbnRzXTsKICAgICAgICAgICAgc3JpOjpNYXJzaGFsOjpDb3B5KCAodm9pZCopICZzZXEtPmVsZW1lbnRzLCBhckludDMyLCAwLCBuRWxlbWVudHMpOwogICAgICAgICAgICAqY2xpX2RhdGE9IGFySW50MzI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1VOU0lHTkVEX0xPTkc6CiAgICAgICAgewogICAgICAgICAgICBTeXN0ZW06OlVJbnQzMiBhclVJbnQzMltdPSBuZXcgU3lzdGVtOjpVSW50MzJbbkVsZW1lbnRzXTsKICAgICAgICAgICAgc3JpOjpNYXJzaGFsOjpDb3B5KCAodm9pZCopICZzZXEtPmVsZW1lbnRzLCBzdGF0aWNfY2FzdDxTeXN0ZW06OkludDMyW10+KGFyVUludDMyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBuRWxlbWVudHMpOwogICAgICAgICAgICAqY2xpX2RhdGE9IGFyVUludDMyOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19IWVBFUjoKICAgICAgICB7CiAgICAgICAgICAgIFN5c3RlbTo6SW50NjQgYXJJbnQ2NFtdPSBuZXcgU3lzdGVtOjpJbnQ2NFtuRWxlbWVudHNdOwogICAgICAgICAgICBzcmk6Ok1hcnNoYWw6OkNvcHkoICh2b2lkKikgJnNlcS0+ZWxlbWVudHMsIGFySW50NjQsIDAsIG5FbGVtZW50cyk7CiAgICAgICAgICAgICpjbGlfZGF0YT0gYXJJbnQ2NDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfVU5TSUdORURfSFlQRVI6CiAgICAgICAgewogICAgICAgICAgICBTeXN0ZW06OlVJbnQ2NCBhclVJbnQ2NFtdPSBuZXcgU3lzdGVtOjpVSW50NjRbbkVsZW1lbnRzXTsKICAgICAgICAgICAgc3JpOjpNYXJzaGFsOjpDb3B5KCAodm9pZCopICZzZXEtPmVsZW1lbnRzLCBhclVJbnQ2NCwgMCwgbkVsZW1lbnRzKTsKICAgICAgICAgICAgKmNsaV9kYXRhPSBhclVJbnQ2NDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRkxPQVQ6CiAgICAgICAgewogICAgICAgICAgICBTeXN0ZW06OlNpbmdsZSBhclNpbmdsZVtdPSBuZXcgU3lzdGVtOjpTaW5nbGVbbkVsZW1lbnRzXTsKICAgICAgICAgICAgc3JpOjpNYXJzaGFsOjpDb3B5KCAodm9pZCopICZzZXEtPmVsZW1lbnRzLCBhclNpbmdsZSwgMCwgbkVsZW1lbnRzKTsKICAgICAgICAgICAgKmNsaV9kYXRhPSBhclNpbmdsZTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRE9VQkxFOgogICAgICAgIHsKICAgICAgICAgICAgU3lzdGVtOjpEb3VibGUgYXJEb3VibGVbXT0gbmV3IFN5c3RlbTo6RG91YmxlW25FbGVtZW50c107CiAgICAgICAgICAgIHNyaTo6TWFyc2hhbDo6Q29weSggKHZvaWQqKSAmc2VxLT5lbGVtZW50cywgYXJEb3VibGUsIDAsIG5FbGVtZW50cyk7CiAgICAgICAgICAgICpjbGlfZGF0YT0gYXJEb3VibGU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NUUklORzoKICAgICAgICB7CiAgICAgICAgICAgIFN5c3RlbTo6U3RyaW5nKiBhclN0cmluZ1tdPSBuZXcgU3lzdGVtOjpTdHJpbmcqW25FbGVtZW50c107CiAgICAgICAgICAgIGZvciAoaW50IGk9IDA7IGkgPCBuRWxlbWVudHM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcnRsX3VTdHJpbmcgKmFTdHI9ICgocnRsX3VTdHJpbmcqKikoJnNlcS0+ZWxlbWVudHMpKVtpXTsKICAgICAgICAgICAgICAgIGFyU3RyaW5nW2ldPSBuZXcgU3lzdGVtOjpTdHJpbmcoIChfX3djaGFyX3QgKikgJmFTdHItPmJ1ZmZlciwgMCwgYVN0ci0+bGVuZ3RoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAqY2xpX2RhdGE9IGFyU3RyaW5nOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19UWVBFOgogICAgICAgIHsKICAgICAgICAgICAgU3lzdGVtOjpUeXBlKiBhclR5cGVbXT0gbmV3IFN5c3RlbTo6VHlwZSpbbkVsZW1lbnRzXTsKICAgICAgICAgICAgZm9yIChpbnQgaT0gMDsgaSA8IG5FbGVtZW50czsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhclR5cGVbaV09CiAgICAgICAgICAgICAgICAgICAgbWFwVW5vVHlwZSggKCh0eXBlbGliX1R5cGVEZXNjcmlwdGlvblJlZmVyZW5jZSoqKSBzZXEtPmVsZW1lbnRzKVtpXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKmNsaV9kYXRhPSBhclR5cGU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0FOWToKICAgICAgICB7CiAgICAgICAgICAgIHVubzo6QW55IGFyQ2xpW109IG5ldyB1bm86OkFueVtuRWxlbWVudHNdOwogICAgICAgICAgICB1bm9fQW55IGNvbnN0ICogcCA9ICh1bm9fQW55IGNvbnN0ICopc2VxLT5lbGVtZW50czsKICAgICAgICAgICAgZm9yIChzYWxfSW50MzIgblBvcyA9IDA7IG5Qb3MgPCBuRWxlbWVudHM7ICsrblBvcyApCiAgICAgICAgICAgIHsKCQkJCVN5c3RlbTo6T2JqZWN0KiBjbGlfb2JqID0gTlVMTDsKICAgICAgICAgICAgICAgIG1hcF90b19jbGkoCiAgICAgICAgICAgICAgICAgICAgJmNsaV9vYmosICZwWyBuUG9zIF0sIGVsZW1lbnRfdHlwZSwgMCwgZmFsc2UpOwogICAgICAgICAgICAgICAgYXJDbGlbblBvc109ICpfX3RyeV9jYXN0PF9fYm94IHVubzo6QW55Kj4oY2xpX29iaik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKmNsaV9kYXRhPSBhckNsaTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgdHlwZWxpYl9UeXBlQ2xhc3NfRU5VTToKICAgICAgICB7CiAgICAgICAgICAgIC8vZ2V0IHRoZSBFbnVtIHR5cGUKICAgICAgICAgICAgU3lzdGVtOjpUeXBlKiBlbnVtVHlwZT0gTlVMTDsKICAgICAgICAgICAgaWYgKGluZm8gIT0gTlVMTCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy9pbmZvIGlzIEVudW1UeXBlW10mLCByZW1vdmUgJgogICAgICAgICAgICAgICAgT1NMX0FTU0VSVChpbmZvLT5Jc0J5UmVmKTsKICAgICAgICAgICAgICAgIGVudW1UeXBlID0gaW5mby0+R2V0RWxlbWVudFR5cGUoKTsKICAgICAgICAgICAgICAgIC8vZW51bVR5cGUgaXMgRW51bVR5cGVbXSwgcmVtb3ZlIFtdCiAgICAgICAgICAgICAgICBlbnVtVHlwZSA9IGVudW1UeXBlLT5HZXRFbGVtZW50VHlwZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGVudW1UeXBlPSBtYXBVbm9UeXBlKGVsZW1lbnRfdHlwZSk7CgogICAgICAgICAgICBTeXN0ZW06OkFycmF5KiBhckVudW0gPSBTeXN0ZW06OkFycmF5OjpDcmVhdGVJbnN0YW5jZSgKICAgICAgICAgICAgICAgIGVudW1UeXBlLCBuRWxlbWVudHMpOwogICAgICAgICAgICBmb3IgKGludCBpPSAwOyBpIDwgbkVsZW1lbnRzOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGFyRW51bS0+U2V0VmFsdWUoU3lzdGVtOjpFbnVtOjpUb09iamVjdChlbnVtVHlwZSwKICAgICAgICAgICAgICAgICAgICgoc2FsX0ludDMyKikgc2VxLT5lbGVtZW50cylbaV0pLCBpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAqY2xpX2RhdGEgPSBhckVudW07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX1NUUlVDVDoKICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0VYQ0VQVElPTjoKICAgICAgICB7CiAgICAgICAgICAgIFR5cGVEZXNjciBlbGVtZW50X3RkKCBlbGVtZW50X3R5cGUgKTsKICAgICAgICAgICAgU3lzdGVtOjpBcnJheSogYXI9IFN5c3RlbTo6QXJyYXk6OkNyZWF0ZUluc3RhbmNlKAogICAgICAgICAgICAgICAgbWFwVW5vVHlwZShlbGVtZW50X3R5cGUpLG5FbGVtZW50cyk7CiAgICAgICAgICAgIGlmICgwIDwgbkVsZW1lbnRzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBUb0RvIGNoZWNrIHRoaXMKICAgICAgICAgICAgICAgIGNoYXIgKiBwID0gKGNoYXIgKikgJnNlcS0+ZWxlbWVudHM7CiAgICAgICAgICAgICAgICBzYWxfSW50MzIgblNpemUgPSBlbGVtZW50X3RkLmdldCgpLT5uU2l6ZTsKICAgICAgICAgICAgICAgIGZvciAoIHNhbF9JbnQzMiBuUG9zID0gMDsgblBvcyA8IG5FbGVtZW50czsgKytuUG9zICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW06Ok9iamVjdCogdmFsOwogICAgICAgICAgICAgICAgICAgIG1hcF90b19jbGkoCiAgICAgICAgICAgICAgICAgICAgICAgICZ2YWwsIHAgKyAoblNpemUgKiBuUG9zKSwgZWxlbWVudF90eXBlLCAwLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgYXItPlNldFZhbHVlKHZhbCwgblBvcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCQkJKmNsaV9kYXRhID0gYXI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KLy8gVG9EbywgdmVyaWZ5CiAgICAgICAgY2FzZSB0eXBlbGliX1R5cGVDbGFzc19TRVFVRU5DRToKICAgICAgICB7CiAgICAgICAgICAgIFN5c3RlbTo6QXJyYXkgKmFyPSBTeXN0ZW06OkFycmF5OjpDcmVhdGVJbnN0YW5jZSgKICAgICAgICAgICAgICAgIG1hcFVub1R5cGUoZWxlbWVudF90eXBlKSwgbkVsZW1lbnRzKTsKICAgICAgICAgICAgaWYgKDAgPCBuRWxlbWVudHMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFR5cGVEZXNjciBlbGVtZW50X3RkKCBlbGVtZW50X3R5cGUgKTsKICAgICAgICAgICAgICAgIHVub19TZXF1ZW5jZSAqKiBlbGVtZW50cyA9ICh1bm9fU2VxdWVuY2UqKikgc2VxLT5lbGVtZW50czsKICAgICAgICAgICAgICAgIGZvciAoIHNhbF9JbnQzMiBuUG9zID0gMDsgblBvcyA8IG5FbGVtZW50czsgKytuUG9zICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBTeXN0ZW06Ok9iamVjdCogdmFsOwogICAgICAgICAgICAgICAgICAgIG1hcF90b19jbGkoCiAgICAgICAgICAgICAgICAgICAgICAgICZ2YWwsICZlbGVtZW50c1tuUG9zXSwgZWxlbWVudF90eXBlLCAwLCBmYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgYXItPlNldFZhbHVlKHZhbCwgblBvcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgKmNsaV9kYXRhID0gYXI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0lOVEVSRkFDRToKICAgICAgICB7CiAgICAgICAgICAgIFR5cGVEZXNjciBlbGVtZW50X3RkKCBlbGVtZW50X3R5cGUgKTsKICAgICAgICAgICAgU3lzdGVtOjpUeXBlICogaWZhY2VUeXBlPSBtYXBVbm9UeXBlKGVsZW1lbnRfdHlwZSk7CiAgICAgICAgICAgIFN5c3RlbTo6QXJyYXkqIGFyPSBTeXN0ZW06OkFycmF5OjpDcmVhdGVJbnN0YW5jZShpZmFjZVR5cGUsIG5FbGVtZW50cyk7CgogICAgICAgICAgICBjaGFyICogcCA9IChjaGFyICopc2VxLT5lbGVtZW50czsKICAgICAgICAgICAgc2FsX0ludDMyIG5TaXplID0gZWxlbWVudF90ZC5nZXQoKS0+blNpemU7CiAgICAgICAgICAgIGZvciAoIHNhbF9JbnQzMiBuUG9zID0gMDsgblBvcyA8IG5FbGVtZW50czsgKytuUG9zICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU3lzdGVtOjpPYmplY3QqIHZhbDsKICAgICAgICAgICAgICAgIG1hcF90b19jbGkoCiAgICAgICAgICAgICAgICAgICAgJnZhbCwgcCArIChuU2l6ZSAqIG5Qb3MpLCBlbGVtZW50X3R5cGUsIE5VTEwsIGZhbHNlKTsKCiAgICAgICAgICAgICAgICBhci0+U2V0VmFsdWUodmFsLCBuUG9zKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAqY2xpX2RhdGE9IGFyOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgZGVmYXVsdDoKICAgICAgICB7CiAgICAgICAgICAgIE9VU3RyaW5nQnVmZmVyIGJ1ZiggMTI4ICk7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmRBc2NpaSggUlRMX0NPTlNUQVNDSUlfU1RSSU5HUEFSQU0oIlttYXBfdG9fY2xpKCk6IikgKTsKICAgICAgICAgICAgYnVmLmFwcGVuZCggKnJlaW50ZXJwcmV0X2Nhc3Q8IE9VU3RyaW5nIGNvbnN0ICogPiggJnR5cGUtPnBUeXBlTmFtZSApICk7CiAgICAgICAgICAgIGJ1Zi5hcHBlbmRBc2NpaSggUlRMX0NPTlNUQVNDSUlfU1RSSU5HUEFSQU0oIl0gdW5zdXBwb3J0ZWQgZWxlbWVudCB0eXBlOiAiKSApOwogICAgICAgICAgICBidWYuYXBwZW5kKCAqcmVpbnRlcnByZXRfY2FzdDwgT1VTdHJpbmcgY29uc3QgKiA+KCAmZWxlbWVudF90eXBlLT5wVHlwZU5hbWUgKSApOwogICAgICAgICAgICB0aHJvdyBCcmlkZ2VSdW50aW1lRXJyb3IoIGJ1Zi5tYWtlU3RyaW5nQW5kQ2xlYXIoKSApOwogICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICBjYXNlIHR5cGVsaWJfVHlwZUNsYXNzX0lOVEVSRkFDRToKICAgIHsKICAgICAgICB1bm9fSW50ZXJmYWNlICogcFVub0kgPSAqKHVub19JbnRlcmZhY2UgKiBjb25zdCAqKXVub19kYXRhOwogICAgICAgIGlmICgwICE9IHBVbm9JKQogICAgICAgIHsKICAgICAgICAgICAgVHlwZURlc2NyIHRkKCB0eXBlICk7CiAgICAgICAgICAgICpjbGlfZGF0YT0gbWFwX3VubzJjbGkoIHBVbm9JLCByZWludGVycHJldF9jYXN0PAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlbGliX0ludGVyZmFjZVR5cGVEZXNjcmlwdGlvbio+KHRkLmdldCgpKSkgOwogICAgICAgIH0KCQllbHNlCgkJCSpjbGlfZGF0YT0gTlVMTDsKICAgICAgICBicmVhazsKICAgIH0KICAgIGRlZmF1bHQ6CiAgICB7CiAgICAgICAgLy9Ub0RvIGNoZWNrIHRoaXMgZXhjZXB0aW9uLiBUaGUgU3RyaW5nIGlzIHByb2JhYmx5IGNyaXBwbGVkCiAgICAgICAgT1VTdHJpbmdCdWZmZXIgYnVmKCAxMjggKTsKICAgICAgICBidWYuYXBwZW5kQXNjaWkoIFJUTF9DT05TVEFTQ0lJX1NUUklOR1BBUkFNKCJbbWFwX3RvX2NsaSgpOiIpICk7CiAgICAgICAgYnVmLmFwcGVuZCggKnJlaW50ZXJwcmV0X2Nhc3Q8IE9VU3RyaW5nIGNvbnN0ICogPiggJnR5cGUtPnBUeXBlTmFtZSApICk7CiAgICAgICAgYnVmLmFwcGVuZEFzY2lpKCBSVExfQ09OU1RBU0NJSV9TVFJJTkdQQVJBTSgiXSB1bnN1cHBvcnRlZCB0eXBlISIpICk7CiAgICAgICAgdGhyb3cgQnJpZGdlUnVudGltZUVycm9yKCBidWYubWFrZVN0cmluZ0FuZENsZWFyKCkgKTsKICAgIH0KICAgIH0KfQp9Cg==