IyAtKi0gY29kaW5nOiBrb2k4LXIgLSotCgppbXBvcnQgdW5pdHRlc3QKZnJvbSB0ZXN0LnN1cHBvcnQgaW1wb3J0IHNjcmlwdF9oZWxwZXIsIGNhcHR1cmVkX3N0ZG91dApmcm9tIHRlc3Quc3VwcG9ydC5vc19oZWxwZXIgaW1wb3J0IFRFU1RGTiwgdW5saW5rLCBybXRyZWUKZnJvbSB0ZXN0LnN1cHBvcnQuaW1wb3J0X2hlbHBlciBpbXBvcnQgdW5sb2FkCmltcG9ydCBpbXBvcnRsaWIKaW1wb3J0IG9zCmltcG9ydCBzeXMKaW1wb3J0IHN1YnByb2Nlc3MKaW1wb3J0IHRlbXBmaWxlCgpjbGFzcyBNaXNjU291cmNlRW5jb2RpbmdUZXN0KHVuaXR0ZXN0LlRlc3RDYXNlKToKCiAgICBkZWYgdGVzdF9wZXAyNjMoc2VsZik6CiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgKICAgICAgICAgICAgIvDJ1M/OIi5lbmNvZGUoInV0Zi04IiksCiAgICAgICAgICAgIGInXHhkMFx4OWZceGQwXHhiOFx4ZDFceDgyXHhkMFx4YmVceGQwXHhiZCcKICAgICAgICApCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCgKICAgICAgICAgICAgIlzwIi5lbmNvZGUoInV0Zi04IiksCiAgICAgICAgICAgIGInXFxceGQwXHg5ZicKICAgICAgICApCgogICAgZGVmIHRlc3RfY29tcGlsZXN0cmluZyhzZWxmKToKICAgICAgICAjIHNlZSAjMTg4MgogICAgICAgIGMgPSBjb21waWxlKGIiXG4jIGNvZGluZzogdXRmLThcbnUgPSAnXHhjM1x4YjMnXG4iLCAiZHVtbXkiLCAiZXhlYyIpCiAgICAgICAgZCA9IHt9CiAgICAgICAgZXhlYyhjLCBkKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoZFsndSddLCAnXHhmMycpCgogICAgZGVmIHRlc3RfaXNzdWUyMzAxKHNlbGYpOgogICAgICAgIHRyeToKICAgICAgICAgICAgY29tcGlsZShiIiMgY29kaW5nOiBjcDkzMlxucHJpbnQgJ1x4OTRceDRlJyIsICJkdW1teSIsICJleGVjIikKICAgICAgICBleGNlcHQgU3ludGF4RXJyb3IgYXMgdjoKICAgICAgICAgICAgc2VsZi5hc3NlcnRFcXVhbCh2LnRleHQucnN0cmlwKCdcbicpLCAicHJpbnQgJ1x1NWU3NCciKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYuZmFpbCgpCgogICAgZGVmIHRlc3RfaXNzdWU0NjI2KHNlbGYpOgogICAgICAgIGMgPSBjb21waWxlKCIjIGNvZGluZz1sYXRpbi0xXG5cdTAwYzYgPSAnXHUwMGM2JyIsICJkdW1teSIsICJleGVjIikKICAgICAgICBkID0ge30KICAgICAgICBleGVjKGMsIGQpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChkWydceGM2J10sICdceGM2JykKCiAgICBkZWYgdGVzdF9pc3N1ZTMyOTcoc2VsZik6CiAgICAgICAgYyA9IGNvbXBpbGUoImEsIGIgPSAnXFUwMDAxMDEwRicsICdcXFUwMDAxMDEwRiciLCAiZHVtbXkiLCAiZXhlYyIpCiAgICAgICAgZCA9IHt9CiAgICAgICAgZXhlYyhjLCBkKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwoZFsnYSddLCBkWydiJ10pCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChsZW4oZFsnYSddKSwgbGVuKGRbJ2InXSkpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChhc2NpaShkWydhJ10pLCBhc2NpaShkWydiJ10pKQoKICAgIGRlZiB0ZXN0X2lzc3VlNzgyMChzZWxmKToKICAgICAgICAjIEVuc3VyZSB0aGF0IGNoZWNrX2JvbSgpIHJlc3RvcmVzIGFsbCBieXRlcyBpbiB0aGUgcmlnaHQgb3JkZXIgaWYKICAgICAgICAjIGNoZWNrX2JvbSgpIGZhaWxzIGluIHB5ZGVidWcgbW9kZTogYSBidWZmZXIgc3RhcnRzIHdpdGggdGhlIGZpcnN0CiAgICAgICAgIyBieXRlIG9mIGEgdmFsaWQgQk9NLCBidXQgbmV4dCBieXRlcyBhcmUgZGlmZmVyZW50CgogICAgICAgICMgb25lIGJ5dGUgaW4gY29tbW9uIHdpdGggdGhlIFVURi0xNi1MRSBCT00KICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhTeW50YXhFcnJvciwgZXZhbCwgYidceGZmXHgyMCcpCgogICAgICAgICMgb25lIGJ5dGUgaW4gY29tbW9uIHdpdGggdGhlIFVURi04IEJPTQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFN5bnRheEVycm9yLCBldmFsLCBiJ1x4ZWZceDIwJykKCiAgICAgICAgIyB0d28gYnl0ZXMgaW4gY29tbW9uIHdpdGggdGhlIFVURi04IEJPTQogICAgICAgIHNlbGYuYXNzZXJ0UmFpc2VzKFN5bnRheEVycm9yLCBldmFsLCBiJ1x4ZWZceGJiXHgyMCcpCgogICAgZGVmIHRlc3RfMjA3MzEoc2VsZik6CiAgICAgICAgc3ViID0gc3VicHJvY2Vzcy5Qb3Blbihbc3lzLmV4ZWN1dGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgIG9zLnBhdGguam9pbihvcy5wYXRoLmRpcm5hbWUoX19maWxlX18pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2NvZGluZzIwNzMxLnB5JyldLAogICAgICAgICAgICAgICAgICAgICAgICBzdGRlcnI9c3VicHJvY2Vzcy5QSVBFKQogICAgICAgIGVyciA9IHN1Yi5jb21tdW5pY2F0ZSgpWzFdCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChzdWIucmV0dXJuY29kZSwgMCkKICAgICAgICBzZWxmLmFzc2VydE5vdEluKGInU3ludGF4RXJyb3InLCBlcnIpCgogICAgZGVmIHRlc3RfZXJyb3JfbWVzc2FnZShzZWxmKToKICAgICAgICBjb21waWxlKGInIyAtKi0gY29kaW5nOiBpc28tODg1OS0xNSAtKi1cbicsICdkdW1teScsICdleGVjJykKICAgICAgICBjb21waWxlKGInXHhlZlx4YmJceGJmXG4nLCAnZHVtbXknLCAnZXhlYycpCiAgICAgICAgY29tcGlsZShiJ1x4ZWZceGJiXHhiZiMgLSotIGNvZGluZzogdXRmLTggLSotXG4nLCAnZHVtbXknLCAnZXhlYycpCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlc1JlZ2V4KFN5bnRheEVycm9yLCAnZmFrZScpOgogICAgICAgICAgICBjb21waWxlKGInIyAtKi0gY29kaW5nOiBmYWtlIC0qLVxuJywgJ2R1bW15JywgJ2V4ZWMnKQogICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXNSZWdleChTeW50YXhFcnJvciwgJ2lzby04ODU5LTE1Jyk6CiAgICAgICAgICAgIGNvbXBpbGUoYidceGVmXHhiYlx4YmYjIC0qLSBjb2Rpbmc6IGlzby04ODU5LTE1IC0qLVxuJywKICAgICAgICAgICAgICAgICAgICAnZHVtbXknLCAnZXhlYycpCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlc1JlZ2V4KFN5bnRheEVycm9yLCAnQk9NJyk6CiAgICAgICAgICAgIGNvbXBpbGUoYidceGVmXHhiYlx4YmYjIC0qLSBjb2Rpbmc6IGlzby04ODU5LTE1IC0qLVxuJywKICAgICAgICAgICAgICAgICAgICAnZHVtbXknLCAnZXhlYycpCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlc1JlZ2V4KFN5bnRheEVycm9yLCAnZmFrZScpOgogICAgICAgICAgICBjb21waWxlKGInXHhlZlx4YmJceGJmIyAtKi0gY29kaW5nOiBmYWtlIC0qLVxuJywgJ2R1bW15JywgJ2V4ZWMnKQogICAgICAgIHdpdGggc2VsZi5hc3NlcnRSYWlzZXNSZWdleChTeW50YXhFcnJvciwgJ0JPTScpOgogICAgICAgICAgICBjb21waWxlKGInXHhlZlx4YmJceGJmIyAtKi0gY29kaW5nOiBmYWtlIC0qLVxuJywgJ2R1bW15JywgJ2V4ZWMnKQoKICAgIGRlZiB0ZXN0X2JhZF9jb2Rpbmcoc2VsZik6CiAgICAgICAgbW9kdWxlX25hbWUgPSAnYmFkX2NvZGluZycKICAgICAgICBzZWxmLnZlcmlmeV9iYWRfbW9kdWxlKG1vZHVsZV9uYW1lKQoKICAgIGRlZiB0ZXN0X2JhZF9jb2RpbmcyKHNlbGYpOgogICAgICAgIG1vZHVsZV9uYW1lID0gJ2JhZF9jb2RpbmcyJwogICAgICAgIHNlbGYudmVyaWZ5X2JhZF9tb2R1bGUobW9kdWxlX25hbWUpCgogICAgZGVmIHZlcmlmeV9iYWRfbW9kdWxlKHNlbGYsIG1vZHVsZV9uYW1lKToKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhTeW50YXhFcnJvciwgX19pbXBvcnRfXywgJ3Rlc3QuJyArIG1vZHVsZV9uYW1lKQoKICAgICAgICBwYXRoID0gb3MucGF0aC5kaXJuYW1lKF9fZmlsZV9fKQogICAgICAgIGZpbGVuYW1lID0gb3MucGF0aC5qb2luKHBhdGgsIG1vZHVsZV9uYW1lICsgJy5weScpCiAgICAgICAgd2l0aCBvcGVuKGZpbGVuYW1lLCAicmIiKSBhcyBmcDoKICAgICAgICAgICAgYnl0ZXMgPSBmcC5yZWFkKCkKICAgICAgICBzZWxmLmFzc2VydFJhaXNlcyhTeW50YXhFcnJvciwgY29tcGlsZSwgYnl0ZXMsIGZpbGVuYW1lLCAnZXhlYycpCgogICAgZGVmIHRlc3RfZXhlY192YWxpZF9jb2Rpbmcoc2VsZik6CiAgICAgICAgZCA9IHt9CiAgICAgICAgZXhlYyhiJyMgY29kaW5nOiBjcDk0OVxuYSA9ICJceGFhXHhhNyJcbicsIGQpCiAgICAgICAgc2VsZi5hc3NlcnRFcXVhbChkWydhJ10sICdcdTMwNDcnKQoKICAgIGRlZiB0ZXN0X2ZpbGVfcGFyc2Uoc2VsZik6CiAgICAgICAgIyBpc3N1ZTExMzQ6IGFsbCBlbmNvZGluZ3Mgb3V0c2lkZSBsYXRpbi0xIGFuZCB1dGYtOCBmYWlsIG9uCiAgICAgICAgIyBtdWx0aWxpbmUgc3RyaW5ncyBhbmQgbG9uZyBsaW5lcyAoPjUxMiBjb2x1bW5zKQogICAgICAgIHVubG9hZChURVNURk4pCiAgICAgICAgZmlsZW5hbWUgPSBURVNURk4gKyAiLnB5IgogICAgICAgIGYgPSBvcGVuKGZpbGVuYW1lLCAidyIsIGVuY29kaW5nPSJjcDEyNTIiKQogICAgICAgIHN5cy5wYXRoLmluc2VydCgwLCBvcy5jdXJkaXIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICB3aXRoIGY6CiAgICAgICAgICAgICAgICBmLndyaXRlKCIjIC0qLSBjb2Rpbmc6IGNwMTI1MiAtKi1cbiIpCiAgICAgICAgICAgICAgICBmLndyaXRlKCInJydBIHNob3J0IHN0cmluZ1xuIikKICAgICAgICAgICAgICAgIGYud3JpdGUoIicnJ1xuIikKICAgICAgICAgICAgICAgIGYud3JpdGUoIidBIHZlcnkgbG9uZyBzdHJpbmcgJXMnXG4iICUgKCJYIiAqIDEwMDApKQoKICAgICAgICAgICAgaW1wb3J0bGliLmludmFsaWRhdGVfY2FjaGVzKCkKICAgICAgICAgICAgX19pbXBvcnRfXyhURVNURk4pCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgZGVsIHN5cy5wYXRoWzBdCiAgICAgICAgICAgIHVubGluayhmaWxlbmFtZSkKICAgICAgICAgICAgdW5saW5rKGZpbGVuYW1lICsgImMiKQogICAgICAgICAgICB1bmxpbmsoZmlsZW5hbWUgKyAibyIpCiAgICAgICAgICAgIHVubG9hZChURVNURk4pCiAgICAgICAgICAgIHJtdHJlZSgnX19weWNhY2hlX18nKQoKICAgIGRlZiB0ZXN0X2Vycm9yX2Zyb21fc3RyaW5nKHNlbGYpOgogICAgICAgICMgU2VlIGh0dHA6Ly9idWdzLnB5dGhvbi5vcmcvaXNzdWU2Mjg5CiAgICAgICAgaW5wdXQgPSAiIyBjb2Rpbmc6IGFzY2lpXG5cTntTTk9XTUFOfSIuZW5jb2RlKCd1dGYtOCcpCiAgICAgICAgd2l0aCBzZWxmLmFzc2VydFJhaXNlcyhTeW50YXhFcnJvcikgYXMgYzoKICAgICAgICAgICAgY29tcGlsZShpbnB1dCwgIjxzdHJpbmc+IiwgImV4ZWMiKQogICAgICAgIGV4cGVjdGVkID0gIidhc2NpaScgY29kZWMgY2FuJ3QgZGVjb2RlIGJ5dGUgMHhlMiBpbiBwb3NpdGlvbiAxNjogIiBcCiAgICAgICAgICAgICAgICAgICAib3JkaW5hbCBub3QgaW4gcmFuZ2UoMTI4KSIKICAgICAgICBzZWxmLmFzc2VydFRydWUoYy5leGNlcHRpb24uYXJnc1swXS5zdGFydHN3aXRoKGV4cGVjdGVkKSwKICAgICAgICAgICAgICAgICAgICAgICAgbXNnPWMuZXhjZXB0aW9uLmFyZ3NbMF0pCgoKY2xhc3MgQWJzdHJhY3RTb3VyY2VFbmNvZGluZ1Rlc3Q6CgogICAgZGVmIHRlc3RfZGVmYXVsdF9jb2Rpbmcoc2VsZik6CiAgICAgICAgc3JjID0gKGIncHJpbnQoYXNjaWkoIlx4YzNceGE0IikpXG4nKQogICAgICAgIHNlbGYuY2hlY2tfc2NyaXB0X291dHB1dChzcmMsIGJyIidceGU0JyIpCgogICAgZGVmIHRlc3RfZmlyc3RfY29kaW5nX2xpbmUoc2VsZik6CiAgICAgICAgc3JjID0gKGInI2NvZGluZzppc284ODU5LTE1XG4nCiAgICAgICAgICAgICAgIGIncHJpbnQoYXNjaWkoIlx4YzNceGE0IikpXG4nKQogICAgICAgIHNlbGYuY2hlY2tfc2NyaXB0X291dHB1dChzcmMsIGJyIidceGMzXHUyMGFjJyIpCgogICAgZGVmIHRlc3Rfc2Vjb25kX2NvZGluZ19saW5lKHNlbGYpOgogICAgICAgIHNyYyA9IChiJyNcbicKICAgICAgICAgICAgICAgYicjY29kaW5nOmlzbzg4NTktMTVcbicKICAgICAgICAgICAgICAgYidwcmludChhc2NpaSgiXHhjM1x4YTQiKSlcbicpCiAgICAgICAgc2VsZi5jaGVja19zY3JpcHRfb3V0cHV0KHNyYywgYnIiJ1x4YzNcdTIwYWMnIikKCiAgICBkZWYgdGVzdF90aGlyZF9jb2RpbmdfbGluZShzZWxmKToKICAgICAgICAjIE9ubHkgZmlyc3QgdHdvIGxpbmVzIGFyZSB0ZXN0ZWQgZm9yIGEgbWFnaWMgY29tbWVudC4KICAgICAgICBzcmMgPSAoYicjXG4nCiAgICAgICAgICAgICAgIGInI1xuJwogICAgICAgICAgICAgICBiJyNjb2Rpbmc6aXNvODg1OS0xNVxuJwogICAgICAgICAgICAgICBiJ3ByaW50KGFzY2lpKCJceGMzXHhhNCIpKVxuJykKICAgICAgICBzZWxmLmNoZWNrX3NjcmlwdF9vdXRwdXQoc3JjLCBiciInXHhlNCciKQoKICAgIGRlZiB0ZXN0X2RvdWJsZV9jb2RpbmdfbGluZShzZWxmKToKICAgICAgICAjIElmIHRoZSBmaXJzdCBsaW5lIG1hdGNoZXMgdGhlIHNlY29uZCBsaW5lIGlzIGlnbm9yZWQuCiAgICAgICAgc3JjID0gKGInI2NvZGluZzppc284ODU5LTE1XG4nCiAgICAgICAgICAgICAgIGInI2NvZGluZzpsYXRpbjFcbicKICAgICAgICAgICAgICAgYidwcmludChhc2NpaSgiXHhjM1x4YTQiKSlcbicpCiAgICAgICAgc2VsZi5jaGVja19zY3JpcHRfb3V0cHV0KHNyYywgYnIiJ1x4YzNcdTIwYWMnIikKCiAgICBkZWYgdGVzdF9kb3VibGVfY29kaW5nX3NhbWVfbGluZShzZWxmKToKICAgICAgICBzcmMgPSAoYicjY29kaW5nOmlzbzg4NTktMTUgY29kaW5nOmxhdGluMVxuJwogICAgICAgICAgICAgICBiJ3ByaW50KGFzY2lpKCJceGMzXHhhNCIpKVxuJykKICAgICAgICBzZWxmLmNoZWNrX3NjcmlwdF9vdXRwdXQoc3JjLCBiciInXHhjM1x1MjBhYyciKQoKICAgIGRlZiB0ZXN0X2ZpcnN0X25vbl91dGY4X2NvZGluZ19saW5lKHNlbGYpOgogICAgICAgIHNyYyA9IChiJyNjb2Rpbmc6aXNvLTg4NTktMTUgXHhhNFxuJwogICAgICAgICAgICAgICBiJ3ByaW50KGFzY2lpKCJceGMzXHhhNCIpKVxuJykKICAgICAgICBzZWxmLmNoZWNrX3NjcmlwdF9vdXRwdXQoc3JjLCBiciInXHhjM1x1MjBhYyciKQoKICAgIGRlZiB0ZXN0X3NlY29uZF9ub25fdXRmOF9jb2RpbmdfbGluZShzZWxmKToKICAgICAgICBzcmMgPSAoYidcbicKICAgICAgICAgICAgICAgYicjY29kaW5nOmlzby04ODU5LTE1IFx4YTRcbicKICAgICAgICAgICAgICAgYidwcmludChhc2NpaSgiXHhjM1x4YTQiKSlcbicpCiAgICAgICAgc2VsZi5jaGVja19zY3JpcHRfb3V0cHV0KHNyYywgYnIiJ1x4YzNcdTIwYWMnIikKCiAgICBkZWYgdGVzdF91dGY4X2JvbShzZWxmKToKICAgICAgICBzcmMgPSAoYidceGVmXHhiYlx4YmZwcmludChhc2NpaSgiXHhjM1x4YTQiKSlcbicpCiAgICAgICAgc2VsZi5jaGVja19zY3JpcHRfb3V0cHV0KHNyYywgYnIiJ1x4ZTQnIikKCiAgICBkZWYgdGVzdF91dGY4X2JvbV9hbmRfdXRmOF9jb2RpbmdfbGluZShzZWxmKToKICAgICAgICBzcmMgPSAoYidceGVmXHhiYlx4YmYjY29kaW5nOnV0Zi04XG4nCiAgICAgICAgICAgICAgIGIncHJpbnQoYXNjaWkoIlx4YzNceGE0IikpXG4nKQogICAgICAgIHNlbGYuY2hlY2tfc2NyaXB0X291dHB1dChzcmMsIGJyIidceGU0JyIpCgoKY2xhc3MgQnl0ZXNTb3VyY2VFbmNvZGluZ1Rlc3QoQWJzdHJhY3RTb3VyY2VFbmNvZGluZ1Rlc3QsIHVuaXR0ZXN0LlRlc3RDYXNlKToKCiAgICBkZWYgY2hlY2tfc2NyaXB0X291dHB1dChzZWxmLCBzcmMsIGV4cGVjdGVkKToKICAgICAgICB3aXRoIGNhcHR1cmVkX3N0ZG91dCgpIGFzIHN0ZG91dDoKICAgICAgICAgICAgZXhlYyhzcmMpCiAgICAgICAgb3V0ID0gc3Rkb3V0LmdldHZhbHVlKCkuZW5jb2RlKCdsYXRpbjEnKQogICAgICAgIHNlbGYuYXNzZXJ0RXF1YWwob3V0LnJzdHJpcCgpLCBleHBlY3RlZCkKCgpjbGFzcyBGaWxlU291cmNlRW5jb2RpbmdUZXN0KEFic3RyYWN0U291cmNlRW5jb2RpbmdUZXN0LCB1bml0dGVzdC5UZXN0Q2FzZSk6CgogICAgZGVmIGNoZWNrX3NjcmlwdF9vdXRwdXQoc2VsZiwgc3JjLCBleHBlY3RlZCk6CiAgICAgICAgd2l0aCB0ZW1wZmlsZS5UZW1wb3JhcnlEaXJlY3RvcnkoKSBhcyB0bXBkOgogICAgICAgICAgICBmbiA9IG9zLnBhdGguam9pbih0bXBkLCAndGVzdC5weScpCiAgICAgICAgICAgIHdpdGggb3BlbihmbiwgJ3diJykgYXMgZnA6CiAgICAgICAgICAgICAgICBmcC53cml0ZShzcmMpCiAgICAgICAgICAgIHJlcyA9IHNjcmlwdF9oZWxwZXIuYXNzZXJ0X3B5dGhvbl9vayhmbikKICAgICAgICBzZWxmLmFzc2VydEVxdWFsKHJlcy5vdXQucnN0cmlwKCksIGV4cGVjdGVkKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICB1bml0dGVzdC5tYWluKCkK