LyoqIEBuYW1lIHVpbWF0ZXN0X2xhbmd1YWdlLmNwcAoKICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZQogKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KICogcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuICBUaGUgQVNGIGxpY2Vuc2VzIHRoaXMgZmlsZQogKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCiAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKICogd2l0aCB0aGUgTGljZW5zZS4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCiAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCiAqICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQogKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucwogKiB1bmRlciB0aGUgTGljZW5zZS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiAgICAgICBJbmNsdWRlIGRlcGVuZGVuY2llcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPGlvbWFuaXA+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgojaW5jbHVkZSAidWltYS9hc3NlcnRtc2cuaCIKI2luY2x1ZGUgInVpbWEvY29uc29sZXVpLmhwcCIKCiNpbmNsdWRlICJ1aW1hL2Z0b29scy5ocHAiCiNpbmNsdWRlICJ1aW1hL2Vycl9pZHMuaCIKI2luY2x1ZGUgInVpbWEvc3RydG9vbHMuaHBwIgojaW5jbHVkZSAidWltYS9zdHJjb252ZXJ0LmhwcCIKI2luY2x1ZGUgInVpbWEvbGFuZ3VhZ2UuaHBwIgoKdXNpbmcgbmFtZXNwYWNlIHVpbWE7CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiAgICAgICBDb25zdGFudHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKI2RlZmluZSBNQUlOX1RJVExFICAgICAgICAgICAgX1RFWFQoIkxhbmd1YWdlIENsYXNzIFVuaXQgVGVzdGVyIikKCmNvbnN0IFRDSEFSICogZ3Nfc3pVc2FnZSA9IF9URVhUKCJcdFstLXZlcmJvc2VdIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CgpzdGF0aWMgY29uc3QgVENIQVIgKiAgICAgICAgICBnc19zekhlbHAgPSBfVEVYVCgiXHQiCiAgICAiUGVyZm9ybSBzb21lIHRlc3Qgd2l0aCB0aGUgTGFuZ3VhZ2UgY2xhc3MuXG5cdCIKICAgICJcblx0IgogICAgIlstLXZlcmJvc2VdICAgICAgICAgICAgICAgICB2ZXJib3NlIGRpc3BsYXkgbW9kZVxuXHQiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKCnN0YXRpYyBib29sICAgICAgICAgICAgICAgICAgIGdzX2JWZXJib3NlID0gZmFsc2U7CgojZGVmaW5lIEFTU0VSVCh4KSBpZiAoISh4KSkgeyBjZXJyIDw8ICJGQUlMRUQgQVNTRVJUSU9OICciIDw8IFVJTUFfU1RSSU5HSUZZKHgpIFwKIDw8ICInIGluICIgPDwgX19GSUxFX18gPDwgIiBhdCBsaW5lICIgPDwgX19MSU5FX18gPDwgZW5kbDsgZXhpdCgxKTsgfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KLyogICAgICAgVHlwZXMgLyBDbGFzc2VzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi8qICAgICAgIEltcGxlbWVudGF0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgp2b2lkIG1haW5EaXNwbGF5KHV0aWw6OkNvbnNvbGVVSSAmIHJjbENvbnNvbGUsIExhbmd1YWdlICYgcmNsTGFuZykKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KewogIGNoYXIgICBzMVs1MF07CiAgc3RyaW5nIHN0cjI7CiAgaW50IGlkID0gcmNsTGFuZy5hc051bWJlcigpOwogIHNwcmludGYoczEsIjB4JTA4eCAlZCIsaWQsaWQpOwogIGlmIChyY2xMYW5nLmhhc0xhbmd1YWdlKCkpCiAgICBzdHIyID0gcmNsTGFuZy5nZXRMYW5ndWFnZUNvZGUoKTsKICBlbHNlCiAgICBzdHIyID0gIioqIjsKICBpZiAoIHJjbExhbmcuaGFzVGVycml0b3J5KCkgKQogICAgc3RyMiArPSAiIC0gIiArIChzdHJpbmcpcmNsTGFuZy5nZXRUZXJyaXRvcnlDb2RlKCk7CgogIHJjbENvbnNvbGUuZm9ybWF0KHMxLCBzdHIyLmNfc3RyKCkpOwp9CgovLyBEaXNwbGF5IGFuIGFycmF5IG9mIFVuaWNvZGUgY2hhcmFjdGVycwp2b2lkIHVjaGFyRGlzcGxheSh1dGlsOjpDb25zb2xlVUkgJiByY2xDb25zb2xlLCBjb25zdCBjaGFyKiB0YWcsIGNvbnN0IFVDaGFyKiB1Y2J1ZmYsIGludCBsZW4pIHsKICBjaGFyIGNidWZbMTAyNF07CiAgY2hhciogcyA9IGNidWY7CiAgKnMrKyA9ICdcIic7CiAgZm9yICggaW50IGkgPSAwOyBpIDwgbGVuOyArK2kgKSB7CiAgICBpZiAodWNidWZmW2ldIDwgMTI4KQogICAgICBzICs9IHNwcmludGYocywiJWMiLHVjYnVmZltpXSk7CiAgICBlbHNlCiAgICAgIHMgKz0gc3ByaW50ZihzLCJcXHUlMDR4Iix1Y2J1ZmZbaV0pOwogIH0KICAqcysrID0gJ1wiJzsKICAqcyA9ICdcMCc7CiAgcmNsQ29uc29sZS5mb3JtYXQodGFnLCBjYnVmKTsKfQoKClR5RXJyb3JJZAptYWluVGVzdCgKICB1dGlsOjpDb25zb2xlVUkgJiAgICAgICByY2xDb25zb2xlLAogIGJvb2wgICAgICAgICAgICAgICAgICBiVmVyYm9zZQopIHsKICBUeUVycm9ySWQgICAgICAgICAgICAgICBlbkVycm9ySWQgPSBVSU1BX0VSUl9OT05FOwoKICByY2xDb25zb2xlLmZvcm1hdEhlYWRlcihfVEVYVCgiUGVyZm9ybWluZyBsYW5ndWFnZSB0ZXN0czoiKSk7CgogIExhbmd1YWdlIGNsVGVzdExhbmcxKCJlbi1VUyIpOwogIExhbmd1YWdlIGNsVGVzdExhbmcyKCJFbl91cyIpOwogIExhbmd1YWdlIGNsVGVzdExhbmczKCJlbi1HQiIpOwogIExhbmd1YWdlIGNsVGVzdExhbmc0KCJlbiIpOwogIExhbmd1YWdlIGNsVGVzdExhbmc1KCJmciIpOwogIExhbmd1YWdlIGNsVGVzdExhbmc2OwoKICBMYW5ndWFnZSBjbEludmFsaWQxKCJmb28iKTsKICBMYW5ndWFnZSBjbEludmFsaWQyKCJmdS1iYXIiKTsKICBMYW5ndWFnZSBjbEludmFsaWQzKCJmMC1iYSIpOwogIExhbmd1YWdlIGNsSW52YWxpZDQoImVuIHVzIik7CiAgTGFuZ3VhZ2UgY2xJbnZhbGlkNSgi6XMtY2EiKTsKCiAgQVNTRVJUKCAhY2xJbnZhbGlkMS5pc1ZhbGlkKCkpOwogIEFTU0VSVCggIWNsSW52YWxpZDIuaXNWYWxpZCgpKTsKICBBU1NFUlQoICFjbEludmFsaWQzLmlzVmFsaWQoKSk7CiAgQVNTRVJUKCAhY2xJbnZhbGlkNC5pc1ZhbGlkKCkpOwogIEFTU0VSVCggIWNsSW52YWxpZDUuaXNWYWxpZCgpKTsKICBBU1NFUlQoIGNsVGVzdExhbmcxLmlzVmFsaWQoKSk7CiAgQVNTRVJUKCBjbFRlc3RMYW5nMy5oYXNUZXJyaXRvcnkoKSk7CiAgQVNTRVJUKCFjbFRlc3RMYW5nNC5oYXNUZXJyaXRvcnkoKSk7CgogIG1haW5EaXNwbGF5ICggcmNsQ29uc29sZSwgY2xUZXN0TGFuZzEgKTsKICBtYWluRGlzcGxheSAoIHJjbENvbnNvbGUsIGNsVGVzdExhbmcyICk7CiAgbWFpbkRpc3BsYXkgKCByY2xDb25zb2xlLCBjbFRlc3RMYW5nMyApOwogIG1haW5EaXNwbGF5ICggcmNsQ29uc29sZSwgY2xUZXN0TGFuZzQgKTsKICBtYWluRGlzcGxheSAoIHJjbENvbnNvbGUsIGNsVGVzdExhbmc1ICk7CiAgbWFpbkRpc3BsYXkgKCByY2xDb25zb2xlLCBjbFRlc3RMYW5nNiApOwoKICByY2xDb25zb2xlLmZvcm1hdCgiY29uc3RydWN0IHRlc3RzIiwgIk9LIik7CgogIC8vIFRlc3QgdGhlIHByZWZpeC1tYXRjaCBjb25jZXB0LCBlLmcuICJlbiIgbWF0Y2hlcyAiZW4tVVMiCiAgQVNTRVJUKCFjbFRlc3RMYW5nMS5tYXRjaGVzKGNsVGVzdExhbmczKSk7CiAgQVNTRVJUKCBjbFRlc3RMYW5nMS5tYXRjaGVzKGNsVGVzdExhbmcyKSk7CiAgQVNTRVJUKCBjbFRlc3RMYW5nMS5tYXRjaGVzKGNsVGVzdExhbmc0KSk7CiAgQVNTRVJUKCFjbFRlc3RMYW5nMS5tYXRjaGVzKGNsVGVzdExhbmc1KSk7CiAgQVNTRVJUKCBjbFRlc3RMYW5nMS5tYXRjaGVzKGNsVGVzdExhbmc2KSk7CgogIHJjbENvbnNvbGUuZm9ybWF0KCJtYXRjaCB0ZXN0cyIsICJPSyIpOwoKICAvLyBUZXN0IHRoZSBjb21wYXJpc29uIG9wZXJhdG9ycwogIEFTU0VSVChjbFRlc3RMYW5nMSA9PSBjbFRlc3RMYW5nMik7CiAgQVNTRVJUKGNsVGVzdExhbmcxICE9IGNsVGVzdExhbmczKTsKICBBU1NFUlQoY2xUZXN0TGFuZzQgPCBjbFRlc3RMYW5nMyk7CiAgQVNTRVJUKGNsVGVzdExhbmczIDwgY2xUZXN0TGFuZzEpOwoKICByY2xDb25zb2xlLmZvcm1hdCgiY29tcGFyaXNvbiB0ZXN0cyIsICJPSyIpOwoKICAvLyBUZXN0IHRoZSBjb25zdHJ1Y3Rpb24gZnJvbSB0aGUgbnVtZXJpYyBmb3JtCiAgTGFuZ3VhZ2UgY2xUZXN0TGFuZzcoY2xUZXN0TGFuZzEuYXNOdW1iZXIoKSk7CiAgQVNTRVJUKGNsVGVzdExhbmc3ID09IGNsVGVzdExhbmcxKTsKCiAgLy8gVGVzdCB0aGUgY29uc3RydWN0aW9uIG9mIG9uZSBmcm9tIGp1c3QgdGhlIGxhbmd1YWdlIHBhcnQgb2YgYW5vdGhlcgogIExhbmd1YWdlIGNsVGVzdExhbmc4KGNsVGVzdExhbmcxLmdldExhbmd1YWdlQ29kZSgpKTsKICBBU1NFUlQoY2xUZXN0TGFuZzEubWF0Y2hlcyhjbFRlc3RMYW5nOCkpOwogIEFTU0VSVChjbFRlc3RMYW5nOCA9PSBjbFRlc3RMYW5nNCk7CgogIC8vIFNhbWUgdGVzdCBidXQgY29uc3RydWN0IGZyb20gdGhlIG51bWVyaWMgZm9ybSBvZiB0aGUgbGFuZ3VhZ2UKICBMYW5ndWFnZSBjbFRlc3RMYW5nOShjbFRlc3RMYW5nMS5nZXRMYW5ndWFnZSgpKTsKICBBU1NFUlQoY2xUZXN0TGFuZzEubWF0Y2hlcyhjbFRlc3RMYW5nOSkpOwogIEFTU0VSVChjbFRlc3RMYW5nOSA9PSBjbFRlc3RMYW5nNCk7CgogIHJjbENvbnNvbGUuZm9ybWF0KCJudW1lcmljIGNvbnN0cnVjdCB0ZXN0cyIsICJPSyIpOwoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIFRlc3Qgc29tZSBVbmljb2RlU3RyaW5nUmVmIGNvcHkgZnVuY3Rpb25zCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgaW50IGxlbjsKICBVQ2hhciB1Y2J1ZlsxMDBdOwogIFVFcnJvckNvZGUgZXJyOwogIHN0ZDo6c3RyaW5nIHNzOwoKICBjb25zdCBjaGFyKiBjc3RyID0gImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ5enl6IDAxMjM0NTY3ODkiOwogIGljdTo6VW5pY29kZVN0cmluZyB1czEoY3N0cik7CiAgVW5pY29kZVN0cmluZ1JlZiB1c3IodXMxKTsKCiAgLy8gaW50byBzdGQ6OnN0cmluZyB3aXRoIGRlZmF1bHQgY29udmVyc2lvbgogIHVzci5leHRyYWN0KHNzKTsKICBpZiAoYlZlcmJvc2UpIHJjbENvbnNvbGUuZm9ybWF0KCJleHRyYWN0IHRvIHN0ZDo6c3RyaW5nIixzcy5jX3N0cigpKTsKICBBU1NFUlQgKHN0cmxlbihjc3RyKSA9PSBzcy5sZW5ndGgoKSk7CgogIC8vIHN1YnN0cmluZyBpbnRvIGljdTo6VW5pY29kZVN0cmluZwogIGljdTo6VW5pY29kZVN0cmluZyB1czIoImluaXRpYWxWYWx1ZSIpOwogIGljdTo6VW5pY29kZVN0cmluZyB1czMoInogMCIpOwogIHVzci5leHRyYWN0QmV0d2VlbigyNSwyOCx1czIpOyAgICAgICAgICAgICAgIC8vIFNob3VsZCBiZSAieiAwIgogIGlmIChiVmVyYm9zZSkgdWNoYXJEaXNwbGF5KHJjbENvbnNvbGUsICJleHRyYWN0QmV0d2VlbiBpbnRvIFVDaGFyIGJ1ZmZlciIsIHVzMi5nZXRCdWZmZXIoKSwgdXMyLmxlbmd0aCgpKTsKICBBU1NFUlQgKCB1czIgPT0gdXMzICk7CgogIC8vIHN1YnN0cmluZyBpbnRvIFVDaGFyIGJ1ZmZlcgogIGVyciA9IFVfWkVST19FUlJPUjsKICBsZW4gPSB1czEuZXh0cmFjdCh1Y2J1ZiwxMDAsZXJyKTsgICAgICAgICAvLyBQcmUtZmlsbCBidWZmZXIKCiAgdXNyLmV4dHJhY3QoMjcsMyx1Y2J1Ziw1KTsgICAgICAgICAgICAgICAgLy8gZXh0cmFjdCBwYXJ0IG9mIFVTUiBpbnRvIHRoZSBidWZmZXIKICBpY3U6OlVuaWNvZGVTdHJpbmcgdXM0KCJhYmNkZTAxMmlqa2xtIik7CiAgaWYgKGJWZXJib3NlKSB1Y2hhckRpc3BsYXkocmNsQ29uc29sZSwgImV4dHJhY3QgaW50byBVQ2hhciBidWZmZXIiLCB1Y2J1ZiwgMTMpOwogIEFTU0VSVCAoIHVzNC5jb21wYXJlKHVjYnVmLDEzKSA9PSAwICk7CgogIC8vIGV4dHJhY3QgaW50byB0b28tc21hbGwgVUNoYXIgYnVmZmVyCiAgZXJyID0gVV9aRVJPX0VSUk9SOwogIGxlbiA9IHVzci5leHRyYWN0KHVjYnVmLDM2LGVycik7ICAgICAgICAgICAgICAgIC8vIHRvbyBzbWFsbAogIEFTU0VSVChlcnIgPT0gVV9CVUZGRVJfT1ZFUkZMT1dfRVJST1IpOwogIGVyciA9IFVfWkVST19FUlJPUjsKICBsZW4gPSB1c3IuZXh0cmFjdCh1Y2J1ZiwzNyxlcnIpOyAgICAgICAgICAgICAgICAvLyBubyByb29tIGZvciBmaW5hbCAwCiAgQVNTRVJUKGVyciA9PSBVX1NUUklOR19OT1RfVEVSTUlOQVRFRF9XQVJOSU5HKTsKICBlcnIgPSBVX1pFUk9fRVJST1I7CiAgbGVuID0gdXNyLmV4dHJhY3QodWNidWYsMzgsZXJyKTsgICAgICAgICAgICAgICAgLy8ganVzdCByaWdodAogIEFTU0VSVChlcnIgPT0gVV9aRVJPX0VSUk9SKTsKICBpZiAoYlZlcmJvc2UpIHVjaGFyRGlzcGxheShyY2xDb25zb2xlLCAiZXh0cmFjdCBpbnRvIFVDaGFyIGJ1ZmZlciIsIHVjYnVmLCBsZW4pOwogIEFTU0VSVCAoIHVzMS5jb21wYXJlKHVjYnVmLGxlbikgPT0gMCApOwoKCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAvLyBUZXN0IHNvbWUgVW5pY29kZVN0cmluZ1JlZiBjb252ZXJzaW9uIGZ1bmN0aW9ucwogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8vIENyZWF0ZSBhIGljdTo6VW5pY29kZVN0cmluZyB3aXRoIDggQXJhYmljIGNoYXJhY3RlcnMgZm9sbG93ZWQgYnkgYSBibGFuay4KICAvLyBBbHNvIGdldCB0aGUgdXRmLTggZm9ybSBhcyBhIHJlZmVyZW5jZQogIFVDaGFyIHVjW10gPSB7MHgwNjJjLCAweDA2NDgsIDB4MDYzMSwgMHgwNjJjLCAweDA2MmEsIDB4MDYyNywgMHgwNjQ4LCAweDA2NDYsIDB4MDAyMH07CiAgaW50IG5jaGFycyA9IHNpemVvZih1Yykvc2l6ZW9mKFVDaGFyKTsKICBpY3U6OlVuaWNvZGVTdHJpbmcgVVMxKHVjLCBuY2hhcnMpOwogIGNoYXIgdThbMTAwXTsKICBVUzEuZXh0cmFjdCgwLCBVUzEubGVuZ3RoKCksIHU4LCAxMDAsICJ1dGYtOCIpOwoKICAvLyBDcmVhdGUgdHdvIFVuaWNvZGVTdHJpbmdSZWYgYW5kIGNvbXBhcmUgdGhlbQogIFVuaWNvZGVTdHJpbmdSZWYgVVNSMShVUzEpOwogIFVuaWNvZGVTdHJpbmdSZWYgVVNSMih1YywgbmNoYXJzKTsKICBpZiAoYlZlcmJvc2UpIHVjaGFyRGlzcGxheShyY2xDb25zb2xlLCAiQ29uc3RydWN0IGZyb20gaWN1OjpVbmljb2RlU3RyaW5nIiwgVVNSMS5nZXRCdWZmZXIoKSwgVVNSMS5sZW5ndGgoKSk7CiAgaWYgKGJWZXJib3NlKSB1Y2hhckRpc3BsYXkocmNsQ29uc29sZSwgIkNvbnN0cnVjdCBmcm9tIFVDaGFyIGFycmF5IiwgICBVU1IyLmdldEJ1ZmZlcigpLCBVU1IyLmxlbmd0aCgpKTsKICBBU1NFUlQgKCBVU1IxLmNvbXBhcmUoVVMxKSA9PSAwICk7CgogIC8vIEV4dHJhY3QgaW50byBhIGJ1ZmZlciB1c2luZyB0aGUgdXRmLTggY29udmVydGVyCiAgY2hhciBjYnVmWzEwMF07CiAgKmNidWYgPSAwOwogIGxlbiA9IFVTUjEuZXh0cmFjdCgwLCBVU1IxLmxlbmd0aCgpLCBjYnVmLCAxMDAsICJ1dGYtOCIpOwogIGlmIChiVmVyYm9zZSkgcmNsQ29uc29sZS5mb3JtYXQoImV4dHJhY3QgaW50byBidWZmZXIgd2l0aCB1dGYtOCBjb252ZXJ0ZXIiLCBjYnVmKTsKICBBU1NFUlQgKCBzdHJjbXAodTgsY2J1ZikgPT0gMCApOwoKICAvLyBFeHRyYWN0IGludG8gYSBzdHJpbmcgdXNpbmcgdGhlIHV0Zi04IGNvbnZlcnRlcgogIFVTUjEuZXh0cmFjdChzcywgInV0Zi04Iik7CiAgaWYgKGJWZXJib3NlKSByY2xDb25zb2xlLmZvcm1hdCgiZXh0cmFjdCBpbnRvIHN0cmluZyB3aXRoIHV0Zi04IGNvbnZlcnRlciIsIHNzLmNfc3RyKCkpOwogIEFTU0VSVCAoIHN0cmxlbih1OCkgPT0gc3MubGVuZ3RoKCkgKTsKICBBU1NFUlQgKCBzdHJuY21wKHU4LHNzLmRhdGEoKSxzdHJsZW4odTgpKSA9PSAwICk7CgogIC8vIFRlc3QgdGhlICJyZS10cnkgd2hlbiBvdmVyZmxvd3MiIGxvZ2ljIGluIHVuaXN0cnJlZi5jcHAKICAvLyBDcmVhdGUgYSBzdHJpbmcgdGhhdCBjb252ZXJ0cyB0byA+MjU1IGNoYXJzCiAgaWN1OjpVbmljb2RlU3RyaW5nIFVTMih1YywgbmNoYXJzKTsKICBmb3IgKCBpbnQgaT0wOyBpIDwgMTU7ICsraSApCiAgICBVUzIuYXBwZW5kKHVjLCBuY2hhcnMpOwoKICAvLyBFeHRyYWN0IHRoZSAxMnRoIHJlcGVhdAogIFVuaWNvZGVTdHJpbmdSZWYgVVNSMyhVUzIpOwogIFVTUjMuZXh0cmFjdCgxMSpuY2hhcnMsIG5jaGFycywgc3MsICJ1dGYtOCIpOwogIGlmIChiVmVyYm9zZSkgcmNsQ29uc29sZS5mb3JtYXQoImV4dHJhY3QgcGFydCBpbnRvIHN0cmluZyB3aXRoIHV0Zi04IGNvbnZlcnRlciIsIHNzLmNfc3RyKCkpOwogIEFTU0VSVCAoIHN0cmxlbih1OCkgPT0gc3MubGVuZ3RoKCkgKTsKCiAgLy8gRXh0cmFjdCBhbGwgdG8gc3RyaW5nIHdpdGggY29udmVydGVyCiAgVVNSMy5leHRyYWN0KHNzLCAidXRmLTgiKTsKICBBU1NFUlQgKCAxNipzdHJsZW4odTgpID09IHNzLmxlbmd0aCgpICk7CgogIC8vIEV4cGxpY2l0IGV4dHJhY3QgdG8gdXRmLTggKG5vIElDVSBjb252ZXJ0ZXIpCiAgc3RkOjpzdHJpbmcgc3MyOwogIFVTUjMuZXh0cmFjdFVURjgoc3MyKTsKICBBU1NFUlQgKCBzczIgPT0gc3MgKTsKCiAgLy8gQ29udmVydCB0byB1dGYtOCAobm8gSUNVIGNvbnZlcnRlcikKICBzdGQ6OnN0cmluZyBzczMgPSBVU1IzLmFzVVRGOCgpOwogIEFTU0VSVCAoIHNzMyA9PSBzcyApOwoKICByY2xDb25zb2xlLmZvcm1hdCgiVW5pY29kZVN0cmluZ1JlZiB0ZXN0cyIsICJPSyIpOwoKICByZXR1cm4gZW5FcnJvcklkOwp9CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciAqIGFyZ3ZbXSkgLyoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwp7CiAgdXRpbDo6Q29uc29sZVVJICAgICAgICAgY2xDb25zb2xlKGFyZ2MsIGFyZ3YsIE1BSU5fVElUTEUsICIiKTsKICBUeUVycm9ySWQgICAgICAgICAgICAgICBlbkVycm9ySWQ7CgogIGNsQ29uc29sZS5oYW5kbGVVc2FnZUhlbHAoZ3Nfc3pVc2FnZSwgZ3Nfc3pIZWxwKTsKICBnc19iVmVyYm9zZSA9IGNsQ29uc29sZS5oYXNBcmdTd2l0Y2goX1RFWFQoInZlcmJvc2UiKSk7CgogIGVuRXJyb3JJZCA9IG1haW5UZXN0KGNsQ29uc29sZSwgZ3NfYlZlcmJvc2UpOwoKICBpZiAoZW5FcnJvcklkID09IFVJTUFfRVJSX05PTkUpIHsKICAgIGNsQ29uc29sZS5pbmZvKF9URVhUKCJUaGUgcHJvZ3JhbSB0ZXJtaW5hdGVkIHN1Y2Nlc3NmdWxseS4iKSk7CiAgfSBlbHNlIHsKICAgIGNsQ29uc29sZS5pbmZvKF9URVhUKCJUaGUgcHJvZ3JhbSB0ZXJtaW5hdGVkIHdpdGggYW4gZXJyb3IuIikpOwogIH0KICByZXR1cm4oaW50KSBlbkVycm9ySWQ7Cn0gLy9saW50ICFlNTI5IHJjbFJlc01nciBub3Qgc3Vic2VxdWVudGx5IHJlZmVyZW5jZWQKCi8qIDxFT0Y+ICovCgo=