From a4dfcd0db0834421b36f90f1996927406c0dea19 Mon Sep 17 00:00:00 2001 From: harpagon210 Date: Fri, 28 Jun 2019 10:55:32 -0500 Subject: [PATCH] fix delegations update --- contracts/tokens.js | 4 ++-- plugins/Blockchain.js | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/contracts/tokens.js b/contracts/tokens.js index b553fa4..2ba86f2 100644 --- a/contracts/tokens.js +++ b/contracts/tokens.js @@ -1002,7 +1002,7 @@ actions.delegate = async (payload) => { } // look for an existing delegation - let delegation = await api.db.findOne('delegations', { to, symbol }); + let delegation = await api.db.findOne('delegations', { to: finalTo, from: api.sender, symbol }); const blockDate = new Date(`${api.steemBlockTimestamp}.000Z`); const timestamp = blockDate.getTime(); @@ -1104,7 +1104,7 @@ actions.undelegate = async (payload) => { if (api.assert(balanceFrom !== null, 'balanceFrom does not exist')) { // look for an existing delegation - const delegation = await api.db.findOne('delegations', { to: finalFrom, symbol }); + const delegation = await api.db.findOne('delegations', { to: finalFrom, from: api.sender, symbol }); if (api.assert(delegation !== null, 'delegation does not exist') && api.assert(api.BigNumber(delegation.quantity).gte(quantity), 'overdrawn delegation')) { diff --git a/plugins/Blockchain.js b/plugins/Blockchain.js index 2bd8fe4..6ddf600 100644 --- a/plugins/Blockchain.js +++ b/plugins/Blockchain.js @@ -118,13 +118,38 @@ const produceNewBlockSync = async (block, callback = null) => { const newTransactions = []; transactions.forEach((transaction) => { + const finalTransaction = transaction; + + // update tokens contract to fix delegations update + if (finalTransaction.sender === 'steemsc' + && finalTransaction.contract === 'contract' + && finalTransaction.action === 'update') { + if (refSteemBlockNumber === 33923097) { + const transPayload = JSON.parse(finalTransaction.payload); + transPayload.code = 'LyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCAqLwovKiBnbG9iYWwgYWN0aW9ucywgYXBpICovCgphY3Rpb25zLmNyZWF0ZVNTQyA9IGFzeW5jICgpID0+IHsKICBsZXQgdGFibGVFeGlzdHMgPSBhd2FpdCBhcGkuZGIudGFibGVFeGlzdHMoJ3Rva2VucycpOwogIGlmICh0YWJsZUV4aXN0cyA9PT0gZmFsc2UpIHsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgndG9rZW5zJywgWydzeW1ib2wnXSk7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ2JhbGFuY2VzJywgWydhY2NvdW50J10pOwogICAgYXdhaXQgYXBpLmRiLmNyZWF0ZVRhYmxlKCdjb250cmFjdHNCYWxhbmNlcycsIFsnYWNjb3VudCddKTsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgncGFyYW1zJyk7CgogICAgY29uc3QgcGFyYW1zID0ge307CiAgICBwYXJhbXMudG9rZW5DcmVhdGlvbkZlZSA9ICcwJzsKICAgIC8vIHBhcmFtcy51cGRhdGVTdGFraW5nUGFyYW1zRmVlID0gJzEwMCc7CiAgICAvLyBwYXJhbXMudXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSA9ICcxMDAnOwogICAgYXdhaXQgYXBpLmRiLmluc2VydCgncGFyYW1zJywgcGFyYW1zKTsKICB9IGVsc2UgewogICAgLyogY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKICAgIHBhcmFtcy51cGRhdGVTdGFraW5nUGFyYW1zRmVlID0gJzEwMCc7CiAgICBwYXJhbXMudXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSA9ICcxMDAnOwogICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncGFyYW1zJywgcGFyYW1zKTsgKi8KICB9CgogIHRhYmxlRXhpc3RzID0gYXdhaXQgYXBpLmRiLnRhYmxlRXhpc3RzKCdwZW5kaW5nVW5zdGFrZXMnKTsKICBpZiAodGFibGVFeGlzdHMgPT09IGZhbHNlKSB7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ3BlbmRpbmdVbnN0YWtlcycsIFsnYWNjb3VudCcsICd1bnN0YWtlQ29tcGxldGVUaW1lc3RhbXAnXSk7CiAgfQoKICAvLyB1cGRhdGUgU1RFRU1QIGRlY2ltYWwgcGxhY2VzCiAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2w6ICdTVEVFTVAnIH0pOwoKICBpZiAodG9rZW4gJiYgdG9rZW4ucHJlY2lzaW9uIDwgOCkgewogICAgdG9rZW4ucHJlY2lzaW9uID0gODsKICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICB9CgogIHRhYmxlRXhpc3RzID0gYXdhaXQgYXBpLmRiLnRhYmxlRXhpc3RzKCdkZWxlZ2F0aW9ucycpOwogIGlmICh0YWJsZUV4aXN0cyA9PT0gZmFsc2UpIHsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgnZGVsZWdhdGlvbnMnLCBbJ2Zyb20nLCAndG8nXSk7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ3BlbmRpbmdVbmRlbGVnYXRpb25zJywgWydhY2NvdW50JywgJ2NvbXBsZXRlVGltZXN0YW1wJ10pOwogIH0KfTsKCmFjdGlvbnMudXBkYXRlUGFyYW1zID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBpZiAoYXBpLnNlbmRlciAhPT0gYXBpLm93bmVyKSByZXR1cm47CgogIGNvbnN0IHsgdG9rZW5DcmVhdGlvbkZlZSAvKiAsIHVwZGF0ZVN0YWtpbmdQYXJhbXNGZWUsIHVwZGF0ZURlbGVnYXRpb25QYXJhbXNGZWUgKi8gfSA9IHBheWxvYWQ7CgogIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CgogIHBhcmFtcy50b2tlbkNyZWF0aW9uRmVlID0gdG9rZW5DcmVhdGlvbkZlZTsKICAvLyBwYXJhbXMudXBkYXRlU3Rha2luZ1BhcmFtc0ZlZSA9IHVwZGF0ZVN0YWtpbmdQYXJhbXNGZWU7CiAgLy8gcGFyYW1zLnVwZGF0ZURlbGVnYXRpb25QYXJhbXNGZWUgPSB1cGRhdGVEZWxlZ2F0aW9uUGFyYW1zRmVlOwoKICBhd2FpdCBhcGkuZGIudXBkYXRlKCdwYXJhbXMnLCBwYXJhbXMpOwp9OwoKYWN0aW9ucy51cGRhdGVVcmwgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsgdXJsLCBzeW1ib2wgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgJiYgdXJsICYmIHR5cGVvZiB1cmwgPT09ICdzdHJpbmcnLCAnaW52YWxpZCBwYXJhbXMnKQogICAgJiYgYXBpLmFzc2VydCh1cmwubGVuZ3RoIDw9IDI1NSwgJ2ludmFsaWQgdXJsOiBtYXggbGVuZ3RoIG9mIDI1NScpKSB7CiAgICAvLyBjaGVjayBpZiB0aGUgdG9rZW4gZXhpc3RzCiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBpZiAodG9rZW4pIHsKICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbXVzdCBiZSB0aGUgaXNzdWVyJykpIHsKICAgICAgICB0cnkgewogICAgICAgICAgY29uc3QgbWV0YWRhdGEgPSBKU09OLnBhcnNlKHRva2VuLm1ldGFkYXRhKTsKCiAgICAgICAgICBpZiAoYXBpLmFzc2VydChtZXRhZGF0YSAmJiBtZXRhZGF0YS51cmwsICdhbiBlcnJvciBvY2N1cmVkIHdoZW4gdHJ5aW5nIHRvIHVwZGF0ZSB0aGUgdXJsJykpIHsKICAgICAgICAgICAgbWV0YWRhdGEudXJsID0gdXJsOwogICAgICAgICAgICB0b2tlbi5tZXRhZGF0YSA9IEpTT04uc3RyaW5naWZ5KG1ldGFkYXRhKTsKICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwogICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgIC8vIGVycm9yIHdoZW4gcGFyc2luZyB0aGUgbWV0YWRhdGEKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn07CgphY3Rpb25zLnVwZGF0ZU1ldGFkYXRhID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7IG1ldGFkYXRhLCBzeW1ib2wgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgJiYgbWV0YWRhdGEgJiYgdHlwZW9mIG1ldGFkYXRhID09PSAnb2JqZWN0JywgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIC8vIGNoZWNrIGlmIHRoZSB0b2tlbiBleGlzdHMKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgIGlmICh0b2tlbikgewogICAgICBpZiAoYXBpLmFzc2VydCh0b2tlbi5pc3N1ZXIgPT09IGFwaS5zZW5kZXIsICdtdXN0IGJlIHRoZSBpc3N1ZXInKSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICBjb25zdCBmaW5hbE1ldGFkYXRhID0gSlNPTi5zdHJpbmdpZnkobWV0YWRhdGEpOwoKICAgICAgICAgIGlmIChhcGkuYXNzZXJ0KGZpbmFsTWV0YWRhdGEubGVuZ3RoIDw9IDEwMDAsICdpbnZhbGlkIG1ldGFkYXRhOiBtYXggbGVuZ3RoIG9mIDEwMDAnKSkgewogICAgICAgICAgICB0b2tlbi5tZXRhZGF0YSA9IGZpbmFsTWV0YWRhdGE7CiAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAvLyBlcnJvciB3aGVuIHN0cmluZ2lmeWluZyB0aGUgbWV0YWRhdGEKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn07CgphY3Rpb25zLnVwZGF0ZVByZWNpc2lvbiA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgeyBzeW1ib2wsIHByZWNpc2lvbiwgaXNTaWduZWRXaXRoQWN0aXZlS2V5IH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycpCiAgICAmJiBhcGkuYXNzZXJ0KChwcmVjaXNpb24gPiAwICYmIHByZWNpc2lvbiA8PSA4KSAmJiAoTnVtYmVyLmlzSW50ZWdlcihwcmVjaXNpb24pKSwgJ2ludmFsaWQgcHJlY2lzaW9uJykpIHsKICAgIC8vIGNoZWNrIGlmIHRoZSB0b2tlbiBleGlzdHMKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgIGlmICh0b2tlbikgewogICAgICBpZiAoYXBpLmFzc2VydCh0b2tlbi5pc3N1ZXIgPT09IGFwaS5zZW5kZXIsICdtdXN0IGJlIHRoZSBpc3N1ZXInKQogICAgICAgICYmIGFwaS5hc3NlcnQocHJlY2lzaW9uID4gdG9rZW4ucHJlY2lzaW9uLCAncHJlY2lzaW9uIGNhbiBvbmx5IGJlIGluY3JlYXNlZCcpKSB7CiAgICAgICAgdG9rZW4ucHJlY2lzaW9uID0gcHJlY2lzaW9uOwogICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMudHJhbnNmZXJPd25lcnNoaXAgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsgc3ltYm9sLCB0bywgaXNTaWduZWRXaXRoQWN0aXZlS2V5IH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICAgJiYgdG8gJiYgdHlwZW9mIHRvID09PSAnc3RyaW5nJywgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIC8vIGNoZWNrIGlmIHRoZSB0b2tlbiBleGlzdHMKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgIGlmICh0b2tlbikgewogICAgICBpZiAoYXBpLmFzc2VydCh0b2tlbi5pc3N1ZXIgPT09IGFwaS5zZW5kZXIsICdtdXN0IGJlIHRoZSBpc3N1ZXInKSkgewogICAgICAgIGNvbnN0IGZpbmFsVG8gPSB0by50cmltKCk7CgogICAgICAgIC8vIGEgdmFsaWQgc3RlZW0gYWNjb3VudCBpcyBiZXR3ZWVuIDMgYW5kIDE2IGNoYXJhY3RlcnMgaW4gbGVuZ3RoCiAgICAgICAgaWYgKGFwaS5hc3NlcnQoZmluYWxUby5sZW5ndGggPj0gMyAmJiBmaW5hbFRvLmxlbmd0aCA8PSAxNiwgJ2ludmFsaWQgdG8nKSkgewogICAgICAgICAgdG9rZW4uaXNzdWVyID0gZmluYWxUbzsKICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn07CgphY3Rpb25zLmNyZWF0ZSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgbmFtZSwgc3ltYm9sLCB1cmwsIHByZWNpc2lvbiwgbWF4U3VwcGx5LCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIC8vIGdldCBjb250cmFjdCBwYXJhbXMKICBjb25zdCBwYXJhbXMgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncGFyYW1zJywge30pOwogIGNvbnN0IHsgdG9rZW5DcmVhdGlvbkZlZSB9ID0gcGFyYW1zOwoKICAvLyBnZXQgYXBpLnNlbmRlcidzIFVUSUxJVFlfVE9LRU5fU1lNQk9MIGJhbGFuY2UKICBjb25zdCB1dGlsaXR5VG9rZW5CYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50OiBhcGkuc2VuZGVyLCBzeW1ib2w6ICJFTkciIH0pOwoKICBjb25zdCBhdXRob3JpemVkQ3JlYXRpb24gPSBhcGkuQmlnTnVtYmVyKHRva2VuQ3JlYXRpb25GZWUpLmx0ZSgwKQogICAgPyB0cnVlCiAgICA6IHV0aWxpdHlUb2tlbkJhbGFuY2UgJiYgYXBpLkJpZ051bWJlcih1dGlsaXR5VG9rZW5CYWxhbmNlLmJhbGFuY2UpLmd0ZSh0b2tlbkNyZWF0aW9uRmVlKTsKCiAgaWYgKGFwaS5hc3NlcnQoYXV0aG9yaXplZENyZWF0aW9uLCAneW91IG11c3QgaGF2ZSBlbm91Z2ggdG9rZW5zIHRvIGNvdmVyIHRoZSBjcmVhdGlvbiBmZWVzJykKICAgICAgJiYgYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgICAmJiBhcGkuYXNzZXJ0KG5hbWUgJiYgdHlwZW9mIG5hbWUgPT09ICdzdHJpbmcnCiAgICAgICYmIHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgICAmJiAodXJsID09PSB1bmRlZmluZWQgfHwgKHVybCAmJiB0eXBlb2YgdXJsID09PSAnc3RyaW5nJykpCiAgICAgICYmICgocHJlY2lzaW9uICYmIHR5cGVvZiBwcmVjaXNpb24gPT09ICdudW1iZXInKSB8fCBwcmVjaXNpb24gPT09IDApCiAgICAgICYmIG1heFN1cHBseSAmJiB0eXBlb2YgbWF4U3VwcGx5ID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihtYXhTdXBwbHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICAvLyB0aGUgcHJlY2lzaW9uIG11c3QgYmUgYmV0d2VlbiAwIGFuZCA4IGFuZCBtdXN0IGJlIGFuIGludGVnZXIKICAgIC8vIHRoZSBtYXggc3VwcGx5IG11c3QgYmUgcG9zaXRpdmUKICAgIGlmIChhcGkuYXNzZXJ0KGFwaS52YWxpZGF0b3IuaXNBbHBoYShzeW1ib2wpICYmIGFwaS52YWxpZGF0b3IuaXNVcHBlcmNhc2Uoc3ltYm9sKSAmJiBzeW1ib2wubGVuZ3RoID4gMCAmJiBzeW1ib2wubGVuZ3RoIDw9IDEwLCAnaW52YWxpZCBzeW1ib2w6IHVwcGVyY2FzZSBsZXR0ZXJzIG9ubHksIG1heCBsZW5ndGggb2YgMTAnKQogICAgICAmJiBhcGkuYXNzZXJ0KGFwaS52YWxpZGF0b3IuaXNBbHBoYW51bWVyaWMoYXBpLnZhbGlkYXRvci5ibGFja2xpc3QobmFtZSwgJyAnKSkgJiYgbmFtZS5sZW5ndGggPiAwICYmIG5hbWUubGVuZ3RoIDw9IDUwLCAnaW52YWxpZCBuYW1lOiBsZXR0ZXJzLCBudW1iZXJzLCB3aGl0ZXNwYWNlcyBvbmx5LCBtYXggbGVuZ3RoIG9mIDUwJykKICAgICAgJiYgYXBpLmFzc2VydCh1cmwgPT09IHVuZGVmaW5lZCB8fCB1cmwubGVuZ3RoIDw9IDI1NSwgJ2ludmFsaWQgdXJsOiBtYXggbGVuZ3RoIG9mIDI1NScpCiAgICAgICYmIGFwaS5hc3NlcnQoKHByZWNpc2lvbiA+PSAwICYmIHByZWNpc2lvbiA8PSA4KSAmJiAoTnVtYmVyLmlzSW50ZWdlcihwcmVjaXNpb24pKSwgJ2ludmFsaWQgcHJlY2lzaW9uJykKICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKG1heFN1cHBseSkuZ3QoMCksICdtYXhTdXBwbHkgbXVzdCBiZSBwb3NpdGl2ZScpCiAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihtYXhTdXBwbHkpLmx0ZShOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiksIGBtYXhTdXBwbHkgbXVzdCBiZSBsb3dlciB0aGFuICR7TnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJ9YCkpIHsKICAgICAgLy8gY2hlY2sgaWYgdGhlIHRva2VuIGFscmVhZHkgZXhpc3RzCiAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gPT09IG51bGwsICdzeW1ib2wgYWxyZWFkeSBleGlzdHMnKSkgewogICAgICAgIGNvbnN0IGZpbmFsVXJsID0gdXJsID09PSB1bmRlZmluZWQgPyAnJyA6IHVybDsKCiAgICAgICAgbGV0IG1ldGFkYXRhID0gewogICAgICAgICAgdXJsOiBmaW5hbFVybCwKICAgICAgICB9OwoKICAgICAgICBtZXRhZGF0YSA9IEpTT04uc3RyaW5naWZ5KG1ldGFkYXRhKTsKICAgICAgICBjb25zdCBuZXdUb2tlbiA9IHsKICAgICAgICAgIGlzc3VlcjogYXBpLnNlbmRlciwKICAgICAgICAgIHN5bWJvbCwKICAgICAgICAgIG5hbWUsCiAgICAgICAgICBtZXRhZGF0YSwKICAgICAgICAgIHByZWNpc2lvbiwKICAgICAgICAgIG1heFN1cHBseTogYXBpLkJpZ051bWJlcihtYXhTdXBwbHkpLnRvRml4ZWQocHJlY2lzaW9uKSwKICAgICAgICAgIHN1cHBseTogJzAnLAogICAgICAgICAgY2lyY3VsYXRpbmdTdXBwbHk6ICcwJywKICAgICAgICAgIHN0YWtpbmdFbmFibGVkOiBmYWxzZSwKICAgICAgICAgIHVuc3Rha2luZ0Nvb2xkb3duOiAxLAogICAgICAgICAgZGVsZWdhdGlvbkVuYWJsZWQ6IGZhbHNlLAogICAgICAgICAgdW5kZWxlZ2F0aW9uQ29vbGRvd246IDAsCiAgICAgICAgfTsKCiAgICAgICAgYXdhaXQgYXBpLmRiLmluc2VydCgndG9rZW5zJywgbmV3VG9rZW4pOwoKICAgICAgICAvLyBidXJuIHRoZSB0b2tlbiBjcmVhdGlvbiBmZWVzCiAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIodG9rZW5DcmVhdGlvbkZlZSkuZ3QoMCkpIHsKICAgICAgICAgIGF3YWl0IGFjdGlvbnMudHJhbnNmZXIoewogICAgICAgICAgICB0bzogJ251bGwnLCBzeW1ib2w6ICJFTkciLCBxdWFudGl0eTogdG9rZW5DcmVhdGlvbkZlZSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy5pc3N1ZSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgdG8sIHN5bWJvbCwgcXVhbnRpdHksIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQodG8gJiYgdHlwZW9mIHRvID09PSAnc3RyaW5nJwogICAgICAmJiBzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICAgJiYgcXVhbnRpdHkgJiYgdHlwZW9mIHF1YW50aXR5ID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihxdWFudGl0eSkuaXNOYU4oKSwgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIGNvbnN0IGZpbmFsVG8gPSB0by50cmltKCk7CiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICAvLyB0aGUgc3ltYm9sIG11c3QgZXhpc3QKICAgIC8vIHRoZSBhcGkuc2VuZGVyIG11c3QgYmUgdGhlIGlzc3VlcgogICAgLy8gdGhlbiB3ZSBuZWVkIHRvIGNoZWNrIHRoYXQgdGhlIHF1YW50aXR5IGlzIGNvcnJlY3QKICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5pc3N1ZXIgPT09IGFwaS5zZW5kZXIsICdub3QgYWxsb3dlZCB0byBpc3N1ZSB0b2tlbnMnKQogICAgICAmJiBhcGkuYXNzZXJ0KGNvdW50RGVjaW1hbHMocXVhbnRpdHkpIDw9IHRva2VuLnByZWNpc2lvbiwgJ3N5bWJvbCBwcmVjaXNpb24gbWlzbWF0Y2gnKQogICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmd0KDApLCAnbXVzdCBpc3N1ZSBwb3NpdGl2ZSBxdWFudGl0eScpCiAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcih0b2tlbi5tYXhTdXBwbHkpLm1pbnVzKHRva2VuLnN1cHBseSkuZ3RlKHF1YW50aXR5KSwgJ3F1YW50aXR5IGV4Y2VlZHMgYXZhaWxhYmxlIHN1cHBseScpKSB7CgogICAgICAvLyBhIHZhbGlkIHN0ZWVtIGFjY291bnQgaXMgYmV0d2VlbiAzIGFuZCAxNiBjaGFyYWN0ZXJzIGluIGxlbmd0aAogICAgICBpZiAoYXBpLmFzc2VydChmaW5hbFRvLmxlbmd0aCA+PSAzICYmIGZpbmFsVG8ubGVuZ3RoIDw9IDE2LCAnaW52YWxpZCB0bycpKSB7CiAgICAgICAgLy8gd2UgbWFkZSBhbGwgdGhlIHJlcXVpcmVkIHZlcmlmaWNhdGlvbiwgbGV0J3Mgbm93IGlzc3VlIHRoZSB0b2tlbnMKCiAgICAgICAgbGV0IHJlcyA9IGF3YWl0IGFkZEJhbGFuY2UodG9rZW4uaXNzdWVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpOwoKICAgICAgICBpZiAocmVzID09PSB0cnVlICYmIGZpbmFsVG8gIT09IHRva2VuLmlzc3VlcikgewogICAgICAgICAgaWYgKGF3YWl0IHN1YkJhbGFuY2UodG9rZW4uaXNzdWVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpKSB7CiAgICAgICAgICAgIHJlcyA9IGF3YWl0IGFkZEJhbGFuY2UoZmluYWxUbywgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKTsKCiAgICAgICAgICAgIGlmIChyZXMgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgYXdhaXQgYWRkQmFsYW5jZSh0b2tlbi5pc3N1ZXIsIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChyZXMgPT09IHRydWUpIHsKICAgICAgICAgIHRva2VuLnN1cHBseSA9IGNhbGN1bGF0ZUJhbGFuY2UodG9rZW4uc3VwcGx5LCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlKTsKCiAgICAgICAgICBpZiAoZmluYWxUbyAhPT0gJ251bGwnKSB7CiAgICAgICAgICAgIHRva2VuLmNpcmN1bGF0aW5nU3VwcGx5ID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgICAgICB0b2tlbi5jaXJjdWxhdGluZ1N1cHBseSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICAgICAgICAgKTsKICAgICAgICAgIH0KCiAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CgogICAgICAgICAgYXBpLmVtaXQoJ3RyYW5zZmVyRnJvbUNvbnRyYWN0JywgewogICAgICAgICAgICBmcm9tOiAndG9rZW5zJywgdG86IGZpbmFsVG8sIHN5bWJvbCwgcXVhbnRpdHksCiAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn07CgphY3Rpb25zLnRyYW5zZmVyID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICB0bywgc3ltYm9sLCBxdWFudGl0eSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydCh0byAmJiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnCiAgICAgICYmIHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgICAmJiBxdWFudGl0eSAmJiB0eXBlb2YgcXVhbnRpdHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgY29uc3QgZmluYWxUbyA9IHRvLnRyaW0oKTsKICAgIGlmIChhcGkuYXNzZXJ0KGZpbmFsVG8gIT09IGFwaS5zZW5kZXIsICdjYW5ub3QgdHJhbnNmZXIgdG8gc2VsZicpKSB7CiAgICAgIC8vIGEgdmFsaWQgc3RlZW0gYWNjb3VudCBpcyBiZXR3ZWVuIDMgYW5kIDE2IGNoYXJhY3RlcnMgaW4gbGVuZ3RoCiAgICAgIGlmIChhcGkuYXNzZXJ0KGZpbmFsVG8ubGVuZ3RoID49IDMgJiYgZmluYWxUby5sZW5ndGggPD0gMTYsICdpbnZhbGlkIHRvJykpIHsKICAgICAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICAgICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAgICAgLy8gdGhlbiB3ZSBuZWVkIHRvIGNoZWNrIHRoYXQgdGhlIHF1YW50aXR5IGlzIGNvcnJlY3QKICAgICAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICAgICAmJiBhcGkuYXNzZXJ0KGNvdW50RGVjaW1hbHMocXVhbnRpdHkpIDw9IHRva2VuLnByZWNpc2lvbiwgJ3N5bWJvbCBwcmVjaXNpb24gbWlzbWF0Y2gnKQogICAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5ndCgwKSwgJ211c3QgdHJhbnNmZXIgcG9zaXRpdmUgcXVhbnRpdHknKSkgewogICAgICAgICAgaWYgKGF3YWl0IHN1YkJhbGFuY2UoYXBpLnNlbmRlciwgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKSkgewogICAgICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBhZGRCYWxhbmNlKGZpbmFsVG8sIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJyk7CgogICAgICAgICAgICBpZiAocmVzID09PSBmYWxzZSkgewogICAgICAgICAgICAgIGF3YWl0IGFkZEJhbGFuY2UoYXBpLnNlbmRlciwgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKTsKCiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoZmluYWxUbyA9PT0gJ251bGwnKSB7CiAgICAgICAgICAgICAgdG9rZW4uY2lyY3VsYXRpbmdTdXBwbHkgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgICAgdG9rZW4uY2lyY3VsYXRpbmdTdXBwbHksIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBhcGkuZW1pdCgndHJhbnNmZXInLCB7CiAgICAgICAgICAgICAgZnJvbTogYXBpLnNlbmRlciwgdG86IGZpbmFsVG8sIHN5bWJvbCwgcXVhbnRpdHksCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gZmFsc2U7Cn07CgphY3Rpb25zLnRyYW5zZmVyVG9Db250cmFjdCA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgdG8sIHN5bWJvbCwgcXVhbnRpdHksIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQodG8gJiYgdHlwZW9mIHRvID09PSAnc3RyaW5nJwogICAgICAmJiBzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICAgJiYgcXVhbnRpdHkgJiYgdHlwZW9mIHF1YW50aXR5ID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihxdWFudGl0eSkuaXNOYU4oKSwgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIGNvbnN0IGZpbmFsVG8gPSB0by50cmltKCk7CiAgICBpZiAoYXBpLmFzc2VydChmaW5hbFRvICE9PSBhcGkuc2VuZGVyLCAnY2Fubm90IHRyYW5zZmVyIHRvIHNlbGYnKSkgewogICAgICAvLyBhIHZhbGlkIGNvbnRyYWN0IGFjY291bnQgaXMgYmV0d2VlbiAzIGFuZCA1MCBjaGFyYWN0ZXJzIGluIGxlbmd0aAogICAgICBpZiAoYXBpLmFzc2VydChmaW5hbFRvLmxlbmd0aCA+PSAzICYmIGZpbmFsVG8ubGVuZ3RoIDw9IDUwLCAnaW52YWxpZCB0bycpKSB7CiAgICAgICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgICAgIC8vIHRoZSBzeW1ib2wgbXVzdCBleGlzdAogICAgICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAgICAgJiYgYXBpLmFzc2VydChjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdzeW1ib2wgcHJlY2lzaW9uIG1pc21hdGNoJykKICAgICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QoMCksICdtdXN0IHRyYW5zZmVyIHBvc2l0aXZlIHF1YW50aXR5JykpIHsKICAgICAgICAgIGlmIChhd2FpdCBzdWJCYWxhbmNlKGFwaS5zZW5kZXIsIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJykpIHsKICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgYWRkQmFsYW5jZShmaW5hbFRvLCB0b2tlbiwgcXVhbnRpdHksICdjb250cmFjdHNCYWxhbmNlcycpOwoKICAgICAgICAgICAgaWYgKHJlcyA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICBhd2FpdCBhZGRCYWxhbmNlKGFwaS5zZW5kZXIsIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgaWYgKGZpbmFsVG8gPT09ICdudWxsJykgewogICAgICAgICAgICAgICAgdG9rZW4uY2lyY3VsYXRpbmdTdXBwbHkgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgICAgICB0b2tlbi5jaXJjdWxhdGluZ1N1cHBseSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgZmFsc2UsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgYXBpLmVtaXQoJ3RyYW5zZmVyVG9Db250cmFjdCcsIHsKICAgICAgICAgICAgICAgIGZyb206IGFwaS5zZW5kZXIsIHRvOiBmaW5hbFRvLCBzeW1ib2wsIHF1YW50aXR5LAogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy50cmFuc2ZlckZyb21Db250cmFjdCA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgLy8gdGhpcyBhY3Rpb24gY2FuIG9ubHkgYmUgY2FsbGVkIGJ5IHRoZSAnbnVsbCcgYWNjb3VudCB3aGljaCBvbmx5IHRoZSBjb3JlIGNvZGUgY2FuIHVzZQogIGlmIChhcGkuYXNzZXJ0KGFwaS5zZW5kZXIgPT09ICdudWxsJywgJ25vdCBhdXRob3JpemVkJykpIHsKICAgIGNvbnN0IHsKICAgICAgZnJvbSwgdG8sIHN5bWJvbCwgcXVhbnRpdHksIHR5cGUsIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICAgIH0gPSBwYXlsb2FkOwogICAgY29uc3QgdHlwZXMgPSBbJ3VzZXInLCAnY29udHJhY3QnXTsKCiAgICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgICAmJiBhcGkuYXNzZXJ0KHRvICYmIHR5cGVvZiB0byA9PT0gJ3N0cmluZycKICAgICAgICAmJiBmcm9tICYmIHR5cGVvZiBmcm9tID09PSAnc3RyaW5nJwogICAgICAgICYmIHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgICAgICYmIHR5cGUgJiYgKHR5cGVzLmluY2x1ZGVzKHR5cGUpKQogICAgICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICAgIGNvbnN0IGZpbmFsVG8gPSB0by50cmltKCk7CiAgICAgIGNvbnN0IHRhYmxlID0gdHlwZSA9PT0gJ3VzZXInID8gJ2JhbGFuY2VzJyA6ICdjb250cmFjdHNCYWxhbmNlcyc7CgogICAgICBpZiAoYXBpLmFzc2VydCh0eXBlID09PSAndXNlcicgfHwgKHR5cGUgPT09ICdjb250cmFjdCcgJiYgZmluYWxUbyAhPT0gZnJvbSksICdjYW5ub3QgdHJhbnNmZXIgdG8gc2VsZicpKSB7CiAgICAgICAgLy8gdmFsaWRhdGUgdGhlICJ0byIKICAgICAgICBjb25zdCB0b1ZhbGlkID0gdHlwZSA9PT0gJ3VzZXInID8gZmluYWxUby5sZW5ndGggPj0gMyAmJiBmaW5hbFRvLmxlbmd0aCA8PSAxNiA6IGZpbmFsVG8ubGVuZ3RoID49IDMgJiYgZmluYWxUby5sZW5ndGggPD0gNTA7CgogICAgICAgIC8vIHRoZSBhY2NvdW50IG11c3QgZXhpc3QKICAgICAgICBpZiAoYXBpLmFzc2VydCh0b1ZhbGlkID09PSB0cnVlLCAnaW52YWxpZCB0bycpKSB7CiAgICAgICAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICAgICAgICAvLyB0aGUgc3ltYm9sIG11c3QgZXhpc3QKICAgICAgICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICAgICAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICAgICAgICYmIGFwaS5hc3NlcnQoY291bnREZWNpbWFscyhxdWFudGl0eSkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnc3ltYm9sIHByZWNpc2lvbiBtaXNtYXRjaCcpCiAgICAgICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QoMCksICdtdXN0IHRyYW5zZmVyIHBvc2l0aXZlIHF1YW50aXR5JykpIHsKCiAgICAgICAgICAgIGlmIChhd2FpdCBzdWJCYWxhbmNlKGZyb20sIHRva2VuLCBxdWFudGl0eSwgJ2NvbnRyYWN0c0JhbGFuY2VzJykpIHsKICAgICAgICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBhZGRCYWxhbmNlKGZpbmFsVG8sIHRva2VuLCBxdWFudGl0eSwgdGFibGUpOwoKICAgICAgICAgICAgICBpZiAocmVzID09PSBmYWxzZSkgewogICAgICAgICAgICAgICAgYXdhaXQgYWRkQmFsYW5jZShmcm9tLCB0b2tlbiwgcXVhbnRpdHksICdjb250cmFjdHNCYWxhbmNlcycpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoZmluYWxUbyA9PT0gJ251bGwnKSB7CiAgICAgICAgICAgICAgICAgIHRva2VuLmNpcmN1bGF0aW5nU3VwcGx5ID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgICAgICAgICAgICB0b2tlbi5jaXJjdWxhdGluZ1N1cHBseSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgZmFsc2UsCiAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBhcGkuZW1pdCgndHJhbnNmZXJGcm9tQ29udHJhY3QnLCB7CiAgICAgICAgICAgICAgICAgIGZyb20sIHRvOiBmaW5hbFRvLCBzeW1ib2wsIHF1YW50aXR5LAogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKY29uc3QgcHJvY2Vzc1Vuc3Rha2UgPSBhc3luYyAodW5zdGFrZSkgPT4gewogIGNvbnN0IHsKICAgIGFjY291bnQsCiAgICBzeW1ib2wsCiAgICBxdWFudGl0eSwKICAgIHF1YW50aXR5TGVmdCwKICAgIG51bWJlclRyYW5zYWN0aW9uc0xlZnQsCiAgfSA9IHVuc3Rha2U7CgogIGNvbnN0IG5ld1Vuc3Rha2UgPSB1bnN0YWtlOwoKICBjb25zdCBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50LCBzeW1ib2wgfSk7CiAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CiAgbGV0IHRva2Vuc1RvUmVsZWFzZSA9IDA7CgogIGlmIChhcGkuYXNzZXJ0KGJhbGFuY2UgIT09IG51bGwsICdiYWxhbmNlIGRvZXMgbm90IGV4aXN0JykpIHsKICAgIC8vIGlmIGxhc3QgdHJhbnNhY3Rpb24gdG8gcHJvY2VzcwogICAgaWYgKG51bWJlclRyYW5zYWN0aW9uc0xlZnQgPT09IDEpIHsKICAgICAgdG9rZW5zVG9SZWxlYXNlID0gcXVhbnRpdHlMZWZ0OwogICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCdwZW5kaW5nVW5zdGFrZXMnLCB1bnN0YWtlKTsKICAgIH0gZWxzZSB7CiAgICAgIHRva2Vuc1RvUmVsZWFzZSA9IGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpCiAgICAgICAgLmRpdmlkZWRCeSh0b2tlbi5udW1iZXJUcmFuc2FjdGlvbnMpCiAgICAgICAgLnRvRml4ZWQodG9rZW4ucHJlY2lzaW9uLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOwoKICAgICAgbmV3VW5zdGFrZS5xdWFudGl0eUxlZnQgPSBhcGkuQmlnTnVtYmVyKG5ld1Vuc3Rha2UucXVhbnRpdHlMZWZ0KQogICAgICAgIC5taW51cyh0b2tlbnNUb1JlbGVhc2UpCiAgICAgICAgLnRvRml4ZWQodG9rZW4ucHJlY2lzaW9uKTsKCiAgICAgIG5ld1Vuc3Rha2UubnVtYmVyVHJhbnNhY3Rpb25zTGVmdCAtPSAxOwoKICAgICAgbmV3VW5zdGFrZS5uZXh0VHJhbnNhY3Rpb25UaW1lc3RhbXAgPSBhcGkuQmlnTnVtYmVyKG5ld1Vuc3Rha2UubmV4dFRyYW5zYWN0aW9uVGltZXN0YW1wKQogICAgICAgIC5wbHVzKG5ld1Vuc3Rha2UubWlsbGlzZWNQZXJQZXJpb2QpCiAgICAgICAgLnRvTnVtYmVyKCk7CgogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdwZW5kaW5nVW5zdGFrZXMnLCBuZXdVbnN0YWtlKTsKICAgIH0KCiAgICBpZiAoYXBpLkJpZ051bWJlcih0b2tlbnNUb1JlbGVhc2UpLmd0KDApKSB7CiAgICAgIGNvbnN0IG9yaWdpbmFsQmFsYW5jZSA9IGJhbGFuY2UuYmFsYW5jZTsKICAgICAgY29uc3Qgb3JpZ2luYWxQZW5kaW5nU3Rha2UgPSBiYWxhbmNlLnBlbmRpbmdVbnN0YWtlOwoKICAgICAgYmFsYW5jZS5iYWxhbmNlID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICBiYWxhbmNlLmJhbGFuY2UsIHRva2Vuc1RvUmVsZWFzZSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlLAogICAgICApOwogICAgICBiYWxhbmNlLnBlbmRpbmdVbnN0YWtlID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICBiYWxhbmNlLnBlbmRpbmdVbnN0YWtlLCB0b2tlbnNUb1JlbGVhc2UsIHRva2VuLnByZWNpc2lvbiwgZmFsc2UsCiAgICAgICk7CgogICAgICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UpLmx0KG9yaWdpbmFsUGVuZGluZ1N0YWtlKQogICAgICAgICYmIGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5iYWxhbmNlKS5ndChvcmlnaW5hbEJhbGFuY2UpLCAnY2Fubm90IHN1YnRyYWN0JykpIHsKICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2UpOwoKICAgICAgICB0b2tlbi50b3RhbFN0YWtlZCA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICB0b2tlbi50b3RhbFN0YWtlZCwgdG9rZW5zVG9SZWxlYXNlLCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICk7CgogICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKCiAgICAgICAgYXBpLmVtaXQoJ3Vuc3Rha2UnLCB7IGFjY291bnQsIHN5bWJvbCwgcXVhbnRpdHk6IHRva2Vuc1RvUmVsZWFzZSB9KTsKICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMuY2hlY2tQZW5kaW5nVW5zdGFrZXMgPSBhc3luYyAoKSA9PiB7CiAgaWYgKGFwaS5hc3NlcnQoYXBpLnNlbmRlciA9PT0gJ251bGwnLCAnbm90IGF1dGhvcml6ZWQnKSkgewogICAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLnN0ZWVtQmxvY2tUaW1lc3RhbXB9LjAwMFpgKTsKICAgIGNvbnN0IHRpbWVzdGFtcCA9IGJsb2NrRGF0ZS5nZXRUaW1lKCk7CgogICAgLy8gZ2V0IGFsbCB0aGUgcGVuZGluZyB1bnN0YWtlcyB0aGF0IGFyZSByZWFkeSB0byBiZSByZWxlYXNlZAogICAgbGV0IHBlbmRpbmdVbnN0YWtlcyA9IGF3YWl0IGFwaS5kYi5maW5kKAogICAgICAncGVuZGluZ1Vuc3Rha2VzJywKICAgICAgewogICAgICAgIG5leHRUcmFuc2FjdGlvblRpbWVzdGFtcDogewogICAgICAgICAgJGx0ZTogdGltZXN0YW1wLAogICAgICAgIH0sCiAgICAgIH0pOwoKICAgIGxldCBuYlBlbmRpbmdVbnN0YWtlcyA9IHBlbmRpbmdVbnN0YWtlcy5sZW5ndGg7CiAgICB3aGlsZSAobmJQZW5kaW5nVW5zdGFrZXMgPiAwKSB7CiAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBuYlBlbmRpbmdVbnN0YWtlczsgaW5kZXggKz0gMSkgewogICAgICAgIGNvbnN0IHBlbmRpbmdVbnN0YWtlID0gcGVuZGluZ1Vuc3Rha2VzW2luZGV4XTsKICAgICAgICBhd2FpdCBwcm9jZXNzVW5zdGFrZShwZW5kaW5nVW5zdGFrZSk7CiAgICAgIH0KCiAgICAgIHBlbmRpbmdVbnN0YWtlcyA9IGF3YWl0IGFwaS5kYi5maW5kKAogICAgICAgICdwZW5kaW5nVW5zdGFrZXMnLAogICAgICAgIHsKICAgICAgICAgIG5leHRUcmFuc2FjdGlvblRpbWVzdGFtcDogewogICAgICAgICAgICAkbHRlOiB0aW1lc3RhbXAsCiAgICAgICAgICB9LAogICAgICAgIH0sCiAgICAgICk7CgogICAgICBuYlBlbmRpbmdVbnN0YWtlcyA9IHBlbmRpbmdVbnN0YWtlcy5sZW5ndGg7CiAgICB9CiAgfQp9OwoKYWN0aW9ucy5lbmFibGVTdGFraW5nID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICB1bnN0YWtpbmdDb29sZG93biwKICAgIG51bWJlclRyYW5zYWN0aW9ucywKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnLCAnaW52YWxpZCBzeW1ib2wnKQogICAgJiYgYXBpLmFzc2VydCh1bnN0YWtpbmdDb29sZG93biAmJiBOdW1iZXIuaXNJbnRlZ2VyKHVuc3Rha2luZ0Nvb2xkb3duKSAmJiB1bnN0YWtpbmdDb29sZG93biA+IDAgJiYgdW5zdGFraW5nQ29vbGRvd24gPD0gMzY1LCAndW5zdGFraW5nQ29vbGRvd24gbXVzdCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMSBhbmQgMzY1JykKICAgICYmIGFwaS5hc3NlcnQobnVtYmVyVHJhbnNhY3Rpb25zICYmIE51bWJlci5pc0ludGVnZXIobnVtYmVyVHJhbnNhY3Rpb25zKSAmJiBudW1iZXJUcmFuc2FjdGlvbnMgPiAwICYmIG51bWJlclRyYW5zYWN0aW9ucyA8PSAzNjUsICdudW1iZXJUcmFuc2FjdGlvbnMgbXVzdCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMSBhbmQgMzY1JykpIHsKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5pc3N1ZXIgPT09IGFwaS5zZW5kZXIsICdtdXN0IGJlIHRoZSBpc3N1ZXInKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLnN0YWtpbmdFbmFibGVkID09PSB1bmRlZmluZWQgfHwgdG9rZW4uc3Rha2luZ0VuYWJsZWQgPT09IGZhbHNlLCAnc3Rha2luZyBhbHJlYWR5IGVuYWJsZWQnKSkgewogICAgICB0b2tlbi5zdGFraW5nRW5hYmxlZCA9IHRydWU7CiAgICAgIHRva2VuLnRvdGFsU3Rha2VkID0gJzAnOwogICAgICB0b2tlbi51bnN0YWtpbmdDb29sZG93biA9IHVuc3Rha2luZ0Nvb2xkb3duOwogICAgICB0b2tlbi5udW1iZXJUcmFuc2FjdGlvbnMgPSBudW1iZXJUcmFuc2FjdGlvbnM7CiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICAgIH0KICB9Cn07CgovKgphY3Rpb25zLnVwZGF0ZVN0YWtpbmdQYXJhbXMgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHN5bWJvbCwKICAgIHVuc3Rha2luZ0Nvb2xkb3duLAogICAgbnVtYmVyVHJhbnNhY3Rpb25zLAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICAvLyBnZXQgY29udHJhY3QgcGFyYW1zCiAgY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKICBjb25zdCB7IHVwZGF0ZVN0YWtpbmdQYXJhbXNGZWUgfSA9IHBhcmFtczsKCiAgLy8gZ2V0IGFwaS5zZW5kZXIncyBVVElMSVRZX1RPS0VOX1NZTUJPTCBiYWxhbmNlCiAgY29uc3QgdXRpbGl0eVRva2VuQmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgc3ltYm9sOiAiRU5HIiB9KTsKCiAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcih1dGlsaXR5VG9rZW5CYWxhbmNlLmJhbGFuY2UpLmd0ZSh1cGRhdGVTdGFraW5nUGFyYW1zRmVlKSwgJ3lvdSBtdXN0IGhhdmUgZW5vdWdoIHRva2VucyB0byBjb3ZlciB0aGUgZmVlcycpCiAgICAmJiBhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJywgJ2ludmFsaWQgc3ltYm9sJykKICAgICYmIGFwaS5hc3NlcnQodW5zdGFraW5nQ29vbGRvd24gJiYgTnVtYmVyLmlzSW50ZWdlcih1bnN0YWtpbmdDb29sZG93bikgJiYgdW5zdGFraW5nQ29vbGRvd24gPiAwICYmIHVuc3Rha2luZ0Nvb2xkb3duIDw9IDM2NSwgJ3Vuc3Rha2luZ0Nvb2xkb3duIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDM2NScpCiAgICAmJiBhcGkuYXNzZXJ0KG51bWJlclRyYW5zYWN0aW9ucyAmJiBOdW1iZXIuaXNJbnRlZ2VyKG51bWJlclRyYW5zYWN0aW9ucykgJiYgbnVtYmVyVHJhbnNhY3Rpb25zID4gMCAmJiBudW1iZXJUcmFuc2FjdGlvbnMgPD0gMzY1LCAnbnVtYmVyVHJhbnNhY3Rpb25zIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDM2NScpKSB7CiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbXVzdCBiZSB0aGUgaXNzdWVyJykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5zdGFraW5nRW5hYmxlZCA9PT0gdHJ1ZSwgJ3N0YWtpbmcgbm90IGVuYWJsZWQnKSkgewogICAgICB0b2tlbi51bnN0YWtpbmdDb29sZG93biA9IHVuc3Rha2luZ0Nvb2xkb3duOwogICAgICB0b2tlbi5udW1iZXJUcmFuc2FjdGlvbnMgPSBudW1iZXJUcmFuc2FjdGlvbnM7CiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKCiAgICAgIC8vIGJ1cm4gdGhlIHRva2VuIGNyZWF0aW9uIGZlZXMKICAgICAgaWYgKGFwaS5CaWdOdW1iZXIodXBkYXRlU3Rha2luZ1BhcmFtc0ZlZSkuZ3QoMCkpIHsKICAgICAgICBhd2FpdCBhY3Rpb25zLnRyYW5zZmVyKHsKICAgICAgICAgIHRvOiAnbnVsbCcsIHN5bWJvbDogIkVORyIsIHF1YW50aXR5OiB1cGRhdGVTdGFraW5nUGFyYW1zRmVlLCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KICB9Cn07CiovCgphY3Rpb25zLnN0YWtlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICBxdWFudGl0eSwKICAgIHRvLAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICAvLyBhIHZhbGlkIHN0ZWVtIGFjY291bnQgaXMgYmV0d2VlbiAzIGFuZCAxNiBjaGFyYWN0ZXJzIGluIGxlbmd0aAogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgY29uc3QgZmluYWxUbyA9IHRvLnRyaW0oKTsKCiAgICAvLyB0aGUgc3ltYm9sIG11c3QgZXhpc3QKICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICBpZiAoYXBpLmFzc2VydChmaW5hbFRvLmxlbmd0aCA+PSAzICYmIGZpbmFsVG8ubGVuZ3RoIDw9IDE2LCAnaW52YWxpZCB0bycpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAmJiBhcGkuYXNzZXJ0KGNvdW50RGVjaW1hbHMocXVhbnRpdHkpIDw9IHRva2VuLnByZWNpc2lvbiwgJ3N5bWJvbCBwcmVjaXNpb24gbWlzbWF0Y2gnKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLnN0YWtpbmdFbmFibGVkID09PSB0cnVlLCAnc3Rha2luZyBub3QgZW5hYmxlZCcpCiAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QoMCksICdtdXN0IHN0YWtlIHBvc2l0aXZlIHF1YW50aXR5JykpIHsKICAgICAgaWYgKGF3YWl0IHN1YkJhbGFuY2UoYXBpLnNlbmRlciwgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKSkgewogICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFkZFN0YWtlKGZpbmFsVG8sIHRva2VuLCBxdWFudGl0eSk7CgogICAgICAgIGlmIChyZXMgPT09IGZhbHNlKSB7CiAgICAgICAgICBhd2FpdCBhZGRCYWxhbmNlKGFwaS5zZW5kZXIsIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGFwaS5lbWl0KCdzdGFrZScsIHsgYWNjb3VudDogZmluYWxUbywgc3ltYm9sLCBxdWFudGl0eSB9KTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn07Cgpjb25zdCBzdGFydFVuc3Rha2UgPSBhc3luYyAoYWNjb3VudCwgdG9rZW4sIHF1YW50aXR5KSA9PiB7CiAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLnN0ZWVtQmxvY2tUaW1lc3RhbXB9LjAwMFpgKTsKICBjb25zdCBjb29sZG93blBlcmlvZE1pbGxpc2VjID0gdG9rZW4udW5zdGFraW5nQ29vbGRvd24gKiAyNCAqIDM2MDAgKiAxMDAwOwogIGNvbnN0IG1pbGxpc2VjUGVyUGVyaW9kID0gYXBpLkJpZ051bWJlcihjb29sZG93blBlcmlvZE1pbGxpc2VjKQogICAgLmRpdmlkZWRCeSh0b2tlbi5udW1iZXJUcmFuc2FjdGlvbnMpCiAgICAuaW50ZWdlclZhbHVlKGFwaS5CaWdOdW1iZXIuUk9VTkRfRE9XTik7CgogIGNvbnN0IG5leHRUcmFuc2FjdGlvblRpbWVzdGFtcCA9IGFwaS5CaWdOdW1iZXIoYmxvY2tEYXRlLmdldFRpbWUoKSkKICAgIC5wbHVzKG1pbGxpc2VjUGVyUGVyaW9kKQogICAgLnRvTnVtYmVyKCk7CgogIGNvbnN0IHVuc3Rha2UgPSB7CiAgICBhY2NvdW50LAogICAgc3ltYm9sOiB0b2tlbi5zeW1ib2wsCiAgICBxdWFudGl0eSwKICAgIHF1YW50aXR5TGVmdDogcXVhbnRpdHksCiAgICBuZXh0VHJhbnNhY3Rpb25UaW1lc3RhbXAsCiAgICBudW1iZXJUcmFuc2FjdGlvbnNMZWZ0OiB0b2tlbi5udW1iZXJUcmFuc2FjdGlvbnMsCiAgICBtaWxsaXNlY1BlclBlcmlvZCwKICAgIHR4SUQ6IGFwaS50cmFuc2FjdGlvbklkLAogIH07CgogIGF3YWl0IGFwaS5kYi5pbnNlcnQoJ3BlbmRpbmdVbnN0YWtlcycsIHVuc3Rha2UpOwp9OwoKYWN0aW9ucy51bnN0YWtlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7IHN5bWJvbCwgcXVhbnRpdHksIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CgogICAgLy8gYSB2YWxpZCBzdGVlbSBhY2NvdW50IGlzIGJldHdlZW4gMyBhbmQgMTYgY2hhcmFjdGVycyBpbiBsZW5ndGgKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgIC8vIHRoZSBzeW1ib2wgbXVzdCBleGlzdAogICAgLy8gdGhlbiB3ZSBuZWVkIHRvIGNoZWNrIHRoYXQgdGhlIHF1YW50aXR5IGlzIGNvcnJlY3QKICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5zdGFraW5nRW5hYmxlZCA9PT0gdHJ1ZSwgJ3N0YWtpbmcgbm90IGVuYWJsZWQnKQogICAgICAmJiBhcGkuYXNzZXJ0KGNvdW50RGVjaW1hbHMocXVhbnRpdHkpIDw9IHRva2VuLnByZWNpc2lvbiwgJ3N5bWJvbCBwcmVjaXNpb24gbWlzbWF0Y2gnKQogICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmd0KDApLCAnbXVzdCB1bnN0YWtlIHBvc2l0aXZlIHF1YW50aXR5JykpIHsKCiAgICAgIGlmIChhd2FpdCBzdWJTdGFrZShhcGkuc2VuZGVyLCB0b2tlbiwgcXVhbnRpdHkpKSB7CiAgICAgICAgYXdhaXQgc3RhcnRVbnN0YWtlKGFwaS5zZW5kZXIsIHRva2VuLCBxdWFudGl0eSk7CgogICAgICAgIGFwaS5lbWl0KCd1bnN0YWtlU3RhcnQnLCB7IGFjY291bnQ6IGFwaS5zZW5kZXIsIHN5bWJvbCwgcXVhbnRpdHkgfSk7CiAgICAgIH0KICAgIH0KICB9Cn07Cgpjb25zdCBwcm9jZXNzQ2FuY2VsVW5zdGFrZSA9IGFzeW5jICh1bnN0YWtlKSA9PiB7CiAgY29uc3QgewogICAgYWNjb3VudCwKICAgIHN5bWJvbCwKICAgIHF1YW50aXR5TGVmdCwKICB9ID0gdW5zdGFrZTsKCiAgY29uc3QgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudCwgc3ltYm9sIH0pOwogIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICBpZiAoYXBpLmFzc2VydChiYWxhbmNlICE9PSBudWxsLCAnYmFsYW5jZSBkb2VzIG5vdCBleGlzdCcpCiAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSkuZ3RlKHF1YW50aXR5TGVmdCksICdvdmVyZHJhd24gcGVuZGluZ1Vuc3Rha2UnKSkgewogICAgY29uc3Qgb3JpZ2luYWxTdGFrZSA9IGJhbGFuY2Uuc3Rha2U7CiAgICBjb25zdCBvcmlnaW5hbFBlbmRpbmdTdGFrZSA9IGJhbGFuY2UucGVuZGluZ1Vuc3Rha2U7CgogICAgYmFsYW5jZS5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgIGJhbGFuY2Uuc3Rha2UsIHF1YW50aXR5TGVmdCwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlLAogICAgKTsKICAgIGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICBiYWxhbmNlLnBlbmRpbmdVbnN0YWtlLCBxdWFudGl0eUxlZnQsIHRva2VuLnByZWNpc2lvbiwgZmFsc2UsCiAgICApOwoKICAgIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSkubHQob3JpZ2luYWxQZW5kaW5nU3Rha2UpCiAgICAgICYmIGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5zdGFrZSkuZ3Qob3JpZ2luYWxTdGFrZSksICdjYW5ub3Qgc3VidHJhY3QnKSkgewogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2UpOwoKICAgICAgYXBpLmVtaXQoJ3Vuc3Rha2UnLCB7IGFjY291bnQsIHN5bWJvbCwgcXVhbnRpdHk6IHF1YW50aXR5TGVmdCB9KTsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQoKICByZXR1cm4gZmFsc2U7Cn07CgphY3Rpb25zLmNhbmNlbFVuc3Rha2UgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsgdHhJRCwgaXNTaWduZWRXaXRoQWN0aXZlS2V5IH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgICAmJiBhcGkuYXNzZXJ0KHR4SUQgJiYgdHlwZW9mIHR4SUQgPT09ICdzdHJpbmcnLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgLy8gZ2V0IHVuc3Rha2UKICAgIGNvbnN0IHVuc3Rha2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncGVuZGluZ1Vuc3Rha2VzJywgeyBhY2NvdW50OiBhcGkuc2VuZGVyLCB0eElEIH0pOwoKICAgIGlmIChhcGkuYXNzZXJ0KHVuc3Rha2UsICd1bnN0YWtlIGRvZXMgbm90IGV4aXN0JykpIHsKICAgICAgaWYgKGF3YWl0IHByb2Nlc3NDYW5jZWxVbnN0YWtlKHVuc3Rha2UpKSB7CiAgICAgICAgYXdhaXQgYXBpLmRiLnJlbW92ZSgncGVuZGluZ1Vuc3Rha2VzJywgdW5zdGFrZSk7CiAgICAgIH0KICAgIH0KICB9Cn07Cgpjb25zdCBiYWxhbmNlVGVtcGxhdGUgPSB7CiAgYWNjb3VudDogbnVsbCwKICBzeW1ib2w6IG51bGwsCiAgYmFsYW5jZTogJzAnLAogIHN0YWtlOiAnMCcsCiAgcGVuZGluZ1Vuc3Rha2U6ICcwJywKICBkZWxlZ2F0aW9uc0luOiAnMCcsCiAgZGVsZWdhdGlvbnNPdXQ6ICcwJywKICBwZW5kaW5nVW5kZWxlZ2F0aW9uczogJzAnLAp9OwoKY29uc3QgYWRkU3Rha2UgPSBhc3luYyAoYWNjb3VudCwgdG9rZW4sIHF1YW50aXR5KSA9PiB7CiAgbGV0IGJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQsIHN5bWJvbDogdG9rZW4uc3ltYm9sIH0pOwoKICBpZiAoYmFsYW5jZSA9PT0gbnVsbCkgewogICAgYmFsYW5jZSA9IGJhbGFuY2VUZW1wbGF0ZTsKICAgIGJhbGFuY2UuYWNjb3VudCA9IGFjY291bnQ7CiAgICBiYWxhbmNlLnN5bWJvbCA9IHRva2VuLnN5bWJvbDsKCiAgICBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmluc2VydCgnYmFsYW5jZXMnLCBiYWxhbmNlKTsKICB9CgogIGlmIChiYWxhbmNlLnN0YWtlID09PSB1bmRlZmluZWQpIHsKICAgIGJhbGFuY2Uuc3Rha2UgPSAnMCc7CiAgICBiYWxhbmNlLnBlbmRpbmdVbnN0YWtlID0gJzAnOwogIH0KCiAgY29uc3Qgb3JpZ2luYWxTdGFrZSA9IGJhbGFuY2Uuc3Rha2U7CgogIGJhbGFuY2Uuc3Rha2UgPSBjYWxjdWxhdGVCYWxhbmNlKGJhbGFuY2Uuc3Rha2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUpOwogIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5zdGFrZSkuZ3Qob3JpZ2luYWxTdGFrZSksICdjYW5ub3QgYWRkJykpIHsKICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2JhbGFuY2VzJywgYmFsYW5jZSk7CgogICAgaWYgKHRva2VuLnRvdGFsU3Rha2VkID09PSB1bmRlZmluZWQpIHsKICAgICAgdG9rZW4udG90YWxTdGFrZWQgPSAnMCc7CiAgICB9CgogICAgdG9rZW4udG90YWxTdGFrZWQgPSBjYWxjdWxhdGVCYWxhbmNlKHRva2VuLnRvdGFsU3Rha2VkLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlKTsKICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKCiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIHJldHVybiBmYWxzZTsKfTsKCmNvbnN0IHN1YlN0YWtlID0gYXN5bmMgKGFjY291bnQsIHRva2VuLCBxdWFudGl0eSkgPT4gewogIGNvbnN0IGJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQsIHN5bWJvbDogdG9rZW4uc3ltYm9sIH0pOwoKICBpZiAoYXBpLmFzc2VydChiYWxhbmNlICE9PSBudWxsLCAnYmFsYW5jZSBkb2VzIG5vdCBleGlzdCcpCiAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5zdGFrZSkuZ3RlKHF1YW50aXR5KSwgJ292ZXJkcmF3biBzdGFrZScpKSB7CiAgICBjb25zdCBvcmlnaW5hbFN0YWtlID0gYmFsYW5jZS5zdGFrZTsKICAgIGNvbnN0IG9yaWdpbmFsUGVuZGluZ1N0YWtlID0gYmFsYW5jZS5wZW5kaW5nVW5zdGFrZTsKCiAgICBiYWxhbmNlLnN0YWtlID0gY2FsY3VsYXRlQmFsYW5jZShiYWxhbmNlLnN0YWtlLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSk7CiAgICBiYWxhbmNlLnBlbmRpbmdVbnN0YWtlID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICk7CgogICAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlLnN0YWtlKS5sdChvcmlnaW5hbFN0YWtlKQogICAgICAmJiBhcGkuQmlnTnVtYmVyKGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UpLmd0KG9yaWdpbmFsUGVuZGluZ1N0YWtlKSwgJ2Nhbm5vdCBzdWJ0cmFjdCcpKSB7CiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2JhbGFuY2VzJywgYmFsYW5jZSk7CgogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICB9CgogIHJldHVybiBmYWxzZTsKfTsKCmNvbnN0IHN1YkJhbGFuY2UgPSBhc3luYyAoYWNjb3VudCwgdG9rZW4sIHF1YW50aXR5LCB0YWJsZSkgPT4gewogIGNvbnN0IGJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSh0YWJsZSwgeyBhY2NvdW50LCBzeW1ib2w6IHRva2VuLnN5bWJvbCB9KTsKCiAgaWYgKGFwaS5hc3NlcnQoYmFsYW5jZSAhPT0gbnVsbCwgJ2JhbGFuY2UgZG9lcyBub3QgZXhpc3QnKQogICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2UuYmFsYW5jZSkuZ3RlKHF1YW50aXR5KSwgJ292ZXJkcmF3biBiYWxhbmNlJykpIHsKICAgIGNvbnN0IG9yaWdpbmFsQmFsYW5jZSA9IGJhbGFuY2UuYmFsYW5jZTsKCiAgICBiYWxhbmNlLmJhbGFuY2UgPSBjYWxjdWxhdGVCYWxhbmNlKGJhbGFuY2UuYmFsYW5jZSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgZmFsc2UpOwoKICAgIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5iYWxhbmNlKS5sdChvcmlnaW5hbEJhbGFuY2UpLCAnY2Fubm90IHN1YnRyYWN0JykpIHsKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSh0YWJsZSwgYmFsYW5jZSk7CgogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICB9CgogIHJldHVybiBmYWxzZTsKfTsKCmNvbnN0IGFkZEJhbGFuY2UgPSBhc3luYyAoYWNjb3VudCwgdG9rZW4sIHF1YW50aXR5LCB0YWJsZSkgPT4gewogIGxldCBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUodGFibGUsIHsgYWNjb3VudCwgc3ltYm9sOiB0b2tlbi5zeW1ib2wgfSk7CiAgaWYgKGJhbGFuY2UgPT09IG51bGwpIHsKICAgIGJhbGFuY2UgPSBiYWxhbmNlVGVtcGxhdGU7CiAgICBiYWxhbmNlLmFjY291bnQgPSBhY2NvdW50OwogICAgYmFsYW5jZS5zeW1ib2wgPSB0b2tlbi5zeW1ib2w7CiAgICBiYWxhbmNlLmJhbGFuY2UgPSBxdWFudGl0eTsKCgogICAgYXdhaXQgYXBpLmRiLmluc2VydCh0YWJsZSwgYmFsYW5jZSk7CgogICAgcmV0dXJuIHRydWU7CiAgfQoKICBjb25zdCBvcmlnaW5hbEJhbGFuY2UgPSBiYWxhbmNlLmJhbGFuY2U7CgogIGJhbGFuY2UuYmFsYW5jZSA9IGNhbGN1bGF0ZUJhbGFuY2UoYmFsYW5jZS5iYWxhbmNlLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlKTsKICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2UuYmFsYW5jZSkuZ3Qob3JpZ2luYWxCYWxhbmNlKSwgJ2Nhbm5vdCBhZGQnKSkgewogICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSh0YWJsZSwgYmFsYW5jZSk7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIHJldHVybiBmYWxzZTsKfTsKCmNvbnN0IGNhbGN1bGF0ZUJhbGFuY2UgPSAoYmFsYW5jZSwgcXVhbnRpdHksIHByZWNpc2lvbiwgYWRkKSA9PiB7CiAgcmV0dXJuIGFkZAogICAgPyBhcGkuQmlnTnVtYmVyKGJhbGFuY2UpLnBsdXMocXVhbnRpdHkpLnRvRml4ZWQocHJlY2lzaW9uKQogICAgOiBhcGkuQmlnTnVtYmVyKGJhbGFuY2UpLm1pbnVzKHF1YW50aXR5KS50b0ZpeGVkKHByZWNpc2lvbik7Cn07Cgpjb25zdCBjb3VudERlY2ltYWxzID0gdmFsdWUgPT4gYXBpLkJpZ051bWJlcih2YWx1ZSkuZHAoKTsKCmFjdGlvbnMuZW5hYmxlRGVsZWdhdGlvbiA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgc3ltYm9sLAogICAgdW5kZWxlZ2F0aW9uQ29vbGRvd24sCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJywgJ2ludmFsaWQgc3ltYm9sJykKICAgICYmIGFwaS5hc3NlcnQodW5kZWxlZ2F0aW9uQ29vbGRvd24gJiYgTnVtYmVyLmlzSW50ZWdlcih1bmRlbGVnYXRpb25Db29sZG93bikgJiYgdW5kZWxlZ2F0aW9uQ29vbGRvd24gPiAwICYmIHVuZGVsZWdhdGlvbkNvb2xkb3duIDw9IDM2NSwgJ3VuZGVsZWdhdGlvbkNvb2xkb3duIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDM2NScpKSB7CiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbXVzdCBiZSB0aGUgaXNzdWVyJykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5zdGFraW5nRW5hYmxlZCA9PT0gdHJ1ZSwgJ3N0YWtpbmcgbm90IGVuYWJsZWQnKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLmRlbGVnYXRpb25FbmFibGVkID09PSB1bmRlZmluZWQgfHwgdG9rZW4uZGVsZWdhdGlvbkVuYWJsZWQgPT09IGZhbHNlLCAnZGVsZWdhdGlvbiBhbHJlYWR5IGVuYWJsZWQnKSkgewogICAgICB0b2tlbi5kZWxlZ2F0aW9uRW5hYmxlZCA9IHRydWU7CiAgICAgIHRva2VuLnVuZGVsZWdhdGlvbkNvb2xkb3duID0gdW5kZWxlZ2F0aW9uQ29vbGRvd247CiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICAgIH0KICB9Cn07CgovKgphY3Rpb25zLnVwZGF0ZURlbGVnYXRpb25QYXJhbXMgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHN5bWJvbCwKICAgIHVuZGVsZWdhdGlvbkNvb2xkb3duLAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICAvLyBnZXQgY29udHJhY3QgcGFyYW1zCiAgY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKICBjb25zdCB7IHVwZGF0ZURlbGVnYXRpb25QYXJhbXNGZWUgfSA9IHBhcmFtczsKCiAgLy8gZ2V0IGFwaS5zZW5kZXIncyBVVElMSVRZX1RPS0VOX1NZTUJPTCBiYWxhbmNlCiAgY29uc3QgdXRpbGl0eVRva2VuQmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgc3ltYm9sOiAiRU5HIiB9KTsKCiAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcih1dGlsaXR5VG9rZW5CYWxhbmNlLmJhbGFuY2UpLmd0ZSh1cGRhdGVEZWxlZ2F0aW9uUGFyYW1zRmVlKSwgJ3lvdSBtdXN0IGhhdmUgZW5vdWdoIHRva2VucyB0byBjb3ZlciB0aGUgZmVlcycpCiAgICAmJiBhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJywgJ2ludmFsaWQgc3ltYm9sJykKICAgICYmIGFwaS5hc3NlcnQodW5kZWxlZ2F0aW9uQ29vbGRvd24gJiYgTnVtYmVyLmlzSW50ZWdlcih1bmRlbGVnYXRpb25Db29sZG93bikgJiYgdW5kZWxlZ2F0aW9uQ29vbGRvd24gPiAwICYmIHVuZGVsZWdhdGlvbkNvb2xkb3duIDw9IDM2NSwgJ3VuZGVsZWdhdGlvbkNvb2xkb3duIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDM2NScpKSB7CiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbXVzdCBiZSB0aGUgaXNzdWVyJykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5kZWxlZ2F0aW9uRW5hYmxlZCA9PT0gdHJ1ZSwgJ2RlbGVnYXRpb24gbm90IGVuYWJsZWQnKSkgewogICAgICB0b2tlbi51bmRlbGVnYXRpb25Db29sZG93biA9IHVuZGVsZWdhdGlvbkNvb2xkb3duOwogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CgogICAgICAvLyBidXJuIHRoZSB0b2tlbiBjcmVhdGlvbiBmZWVzCiAgICAgIGlmIChhcGkuQmlnTnVtYmVyKHVwZGF0ZURlbGVnYXRpb25QYXJhbXNGZWUpLmd0KDApKSB7CiAgICAgICAgYXdhaXQgYWN0aW9ucy50cmFuc2Zlcih7CiAgICAgICAgICB0bzogJ251bGwnLCBzeW1ib2w6ICJFTkciLCBxdWFudGl0eTogdXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogICAgICAgIH0pOwogICAgICB9CiAgICB9CiAgfQp9OwoKKi8KCmFjdGlvbnMuZGVsZWdhdGUgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHN5bWJvbCwKICAgIHF1YW50aXR5LAogICAgdG8sCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgJiYgdG8gJiYgdHlwZW9mIHRvID09PSAnc3RyaW5nJwogICAgJiYgcXVhbnRpdHkgJiYgdHlwZW9mIHF1YW50aXR5ID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihxdWFudGl0eSkuaXNOYU4oKSwgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIGNvbnN0IGZpbmFsVG8gPSB0by50cmltKCk7CiAgICAvLyBhIHZhbGlkIHN0ZWVtIGFjY291bnQgaXMgYmV0d2VlbiAzIGFuZCAxNiBjaGFyYWN0ZXJzIGluIGxlbmd0aAogICAgaWYgKGFwaS5hc3NlcnQoZmluYWxUby5sZW5ndGggPj0gMyAmJiBmaW5hbFRvLmxlbmd0aCA8PSAxNiwgJ2ludmFsaWQgdG8nKSkgewogICAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICAgIC8vIHRoZSBzeW1ib2wgbXVzdCBleGlzdAogICAgICAvLyB0aGVuIHdlIG5lZWQgdG8gY2hlY2sgdGhhdCB0aGUgcXVhbnRpdHkgaXMgY29ycmVjdAogICAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICAgJiYgYXBpLmFzc2VydChjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdzeW1ib2wgcHJlY2lzaW9uIG1pc21hdGNoJykKICAgICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLmRlbGVnYXRpb25FbmFibGVkID09PSB0cnVlLCAnZGVsZWdhdGlvbiBub3QgZW5hYmxlZCcpCiAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5ndCgwKSwgJ211c3QgZGVsZWdhdGUgcG9zaXRpdmUgcXVhbnRpdHknKSkgewogICAgICAgIGNvbnN0IGJhbGFuY2VGcm9tID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50OiBhcGkuc2VuZGVyLCBzeW1ib2wgfSk7CgogICAgICAgIGlmIChhcGkuYXNzZXJ0KGJhbGFuY2VGcm9tICE9PSBudWxsLCAnYmFsYW5jZUZyb20gZG9lcyBub3QgZXhpc3QnKQogICAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2VGcm9tLnN0YWtlKS5ndGUocXVhbnRpdHkpLCAnb3ZlcmRyYXduIHN0YWtlJykpIHsKICAgICAgICAgIGlmIChiYWxhbmNlRnJvbS5zdGFrZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbGQgYmFsYW5jZXMgd2l0aCBuZXcgcHJvcGVydGllcwogICAgICAgICAgICBiYWxhbmNlRnJvbS5zdGFrZSA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZUZyb20ucGVuZGluZ1Vuc3Rha2UgPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VGcm9tLmRlbGVnYXRpb25zSW4gPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VGcm9tLmRlbGVnYXRpb25zT3V0ID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5wZW5kaW5nVW5kZWxlZ2F0aW9ucyA9ICcwJzsKICAgICAgICAgIH0gZWxzZSBpZiAoYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNJbiA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbGQgYmFsYW5jZXMgd2l0aCBuZXcgcHJvcGVydGllcwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc0luID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc091dCA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZUZyb20ucGVuZGluZ1VuZGVsZWdhdGlvbnMgPSAnMCc7CiAgICAgICAgICAgIGlmIChiYWxhbmNlRnJvbS5kZWxlZ2F0ZWRTdGFrZSkgewogICAgICAgICAgICAgIGRlbGV0ZSBiYWxhbmNlRnJvbS5kZWxlZ2F0ZWRTdGFrZTsKICAgICAgICAgICAgICBkZWxldGUgYmFsYW5jZUZyb20ucmVjZWl2ZWRTdGFrZTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIGxldCBiYWxhbmNlVG8gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQ6IHRvLCBzeW1ib2wgfSk7CgogICAgICAgICAgaWYgKGJhbGFuY2VUbyA9PT0gbnVsbCkgewogICAgICAgICAgICBiYWxhbmNlVG8gPSBiYWxhbmNlVGVtcGxhdGU7CiAgICAgICAgICAgIGJhbGFuY2VUby5hY2NvdW50ID0gdG87CiAgICAgICAgICAgIGJhbGFuY2VUby5zeW1ib2wgPSBzeW1ib2w7CgogICAgICAgICAgICBiYWxhbmNlVG8gPSBhd2FpdCBhcGkuZGIuaW5zZXJ0KCdiYWxhbmNlcycsIGJhbGFuY2VUbyk7CiAgICAgICAgICB9IGVsc2UgaWYgKGJhbGFuY2VUby5zdGFrZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbGQgYmFsYW5jZXMgd2l0aCBuZXcgcHJvcGVydGllcwogICAgICAgICAgICBiYWxhbmNlVG8uc3Rha2UgPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VUby5wZW5kaW5nVW5zdGFrZSA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zSW4gPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc091dCA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZVRvLnBlbmRpbmdVbmRlbGVnYXRpb25zID0gJzAnOwogICAgICAgICAgfSBlbHNlIGlmIChiYWxhbmNlVG8uZGVsZWdhdGlvbnNJbiA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbGQgYmFsYW5jZXMgd2l0aCBuZXcgcHJvcGVydGllcwogICAgICAgICAgICBiYWxhbmNlVG8uZGVsZWdhdGlvbnNJbiA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zT3V0ID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlVG8ucGVuZGluZ1VuZGVsZWdhdGlvbnMgPSAnMCc7CgogICAgICAgICAgICBpZiAoYmFsYW5jZVRvLmRlbGVnYXRlZFN0YWtlKSB7CiAgICAgICAgICAgICAgZGVsZXRlIGJhbGFuY2VUby5kZWxlZ2F0ZWRTdGFrZTsKICAgICAgICAgICAgICBkZWxldGUgYmFsYW5jZVRvLnJlY2VpdmVkU3Rha2U7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICAvLyBsb29rIGZvciBhbiBleGlzdGluZyBkZWxlZ2F0aW9uCiAgICAgICAgICBsZXQgZGVsZWdhdGlvbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdkZWxlZ2F0aW9ucycsIHsgdG86IGZpbmFsVG8sIGZyb206IGFwaS5zZW5kZXIsIHN5bWJvbCB9KTsKCiAgICAgICAgICBpZiAoZGVsZWdhdGlvbiA9PSBudWxsKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlRnJvbQogICAgICAgICAgICBiYWxhbmNlRnJvbS5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgYmFsYW5jZUZyb20uc3Rha2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICApOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc091dCA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNPdXQsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2VGcm9tKTsKCiAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlVG8KICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zSW4gPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc0luLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlVG8pOwoKICAgICAgICAgICAgZGVsZWdhdGlvbiA9IHt9OwogICAgICAgICAgICBkZWxlZ2F0aW9uLmZyb20gPSBhcGkuc2VuZGVyOwogICAgICAgICAgICBkZWxlZ2F0aW9uLnRvID0gdG87CiAgICAgICAgICAgIGRlbGVnYXRpb24uc3ltYm9sID0gc3ltYm9sOwogICAgICAgICAgICBkZWxlZ2F0aW9uLnF1YW50aXR5ID0gcXVhbnRpdHk7CgogICAgICAgICAgICBhd2FpdCBhcGkuZGIuaW5zZXJ0KCdkZWxlZ2F0aW9ucycsIGRlbGVnYXRpb24pOwoKICAgICAgICAgICAgYXBpLmVtaXQoJ2RlbGVnYXRlJywgeyB0bywgc3ltYm9sLCBxdWFudGl0eSB9KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIGlmIGEgZGVsZWdhdGlvbiBhbHJlYWR5IGV4aXN0cywgaW5jcmVhc2UgaXQKCiAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlRnJvbQogICAgICAgICAgICBiYWxhbmNlRnJvbS5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgYmFsYW5jZUZyb20uc3Rha2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICApOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc091dCA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNPdXQsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2VGcm9tKTsKCiAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlVG8KICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zSW4gPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc0luLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlVG8pOwoKICAgICAgICAgICAgLy8gdXBkYXRlIGRlbGVnYXRpb24KICAgICAgICAgICAgZGVsZWdhdGlvbi5xdWFudGl0eSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgZGVsZWdhdGlvbi5xdWFudGl0eSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2RlbGVnYXRpb25zJywgZGVsZWdhdGlvbik7CiAgICAgICAgICAgIGFwaS5lbWl0KCdkZWxlZ2F0ZScsIHsgdG8sIHN5bWJvbCwgcXVhbnRpdHkgfSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy51bmRlbGVnYXRlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICBxdWFudGl0eSwKICAgIGZyb20sCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgJiYgZnJvbSAmJiB0eXBlb2YgZnJvbSA9PT0gJ3N0cmluZycKICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICBjb25zdCBmaW5hbEZyb20gPSBmcm9tLnRyaW0oKTsKICAgIC8vIGEgdmFsaWQgc3RlZW0gYWNjb3VudCBpcyBiZXR3ZWVuIDMgYW5kIDE2IGNoYXJhY3RlcnMgaW4gbGVuZ3RoCiAgICBpZiAoYXBpLmFzc2VydChmaW5hbEZyb20ubGVuZ3RoID49IDMgJiYgZmluYWxGcm9tLmxlbmd0aCA8PSAxNiwgJ2ludmFsaWQgZnJvbScpKSB7CiAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgICAmJiBhcGkuYXNzZXJ0KGNvdW50RGVjaW1hbHMocXVhbnRpdHkpIDw9IHRva2VuLnByZWNpc2lvbiwgJ3N5bWJvbCBwcmVjaXNpb24gbWlzbWF0Y2gnKQogICAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uZGVsZWdhdGlvbkVuYWJsZWQgPT09IHRydWUsICdkZWxlZ2F0aW9uIG5vdCBlbmFibGVkJykKICAgICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmd0KDApLCAnbXVzdCB1bmRlbGVnYXRlIHBvc2l0aXZlIHF1YW50aXR5JykpIHsKICAgICAgICBjb25zdCBiYWxhbmNlVG8gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQ6IGFwaS5zZW5kZXIsIHN5bWJvbCB9KTsKCiAgICAgICAgaWYgKGFwaS5hc3NlcnQoYmFsYW5jZVRvICE9PSBudWxsLCAnYmFsYW5jZVRvIGRvZXMgbm90IGV4aXN0JykKICAgICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlVG8uZGVsZWdhdGlvbnNPdXQpLmd0ZShxdWFudGl0eSksICdvdmVyZHJhd24gZGVsZWdhdGlvbicpKSB7CiAgICAgICAgICBjb25zdCBiYWxhbmNlRnJvbSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudDogZmluYWxGcm9tLCBzeW1ib2wgfSk7CgogICAgICAgICAgaWYgKGFwaS5hc3NlcnQoYmFsYW5jZUZyb20gIT09IG51bGwsICdiYWxhbmNlRnJvbSBkb2VzIG5vdCBleGlzdCcpKSB7CiAgICAgICAgICAgIC8vIGxvb2sgZm9yIGFuIGV4aXN0aW5nIGRlbGVnYXRpb24KICAgICAgICAgICAgY29uc3QgZGVsZWdhdGlvbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdkZWxlZ2F0aW9ucycsIHsgdG86IGZpbmFsRnJvbSwgZnJvbTogYXBpLnNlbmRlciwgc3ltYm9sIH0pOwoKICAgICAgICAgICAgaWYgKGFwaS5hc3NlcnQoZGVsZWdhdGlvbiAhPT0gbnVsbCwgJ2RlbGVnYXRpb24gZG9lcyBub3QgZXhpc3QnKQogICAgICAgICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihkZWxlZ2F0aW9uLnF1YW50aXR5KS5ndGUocXVhbnRpdHkpLCAnb3ZlcmRyYXduIGRlbGVnYXRpb24nKSkgewogICAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlVG8KICAgICAgICAgICAgICBiYWxhbmNlVG8ucGVuZGluZ1VuZGVsZWdhdGlvbnMgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgICAgYmFsYW5jZUZyb20ucGVuZGluZ1VuZGVsZWdhdGlvbnMsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICBiYWxhbmNlVG8uZGVsZWdhdGlvbnNPdXQgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zT3V0LCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2VUbyk7CgogICAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlRnJvbQogICAgICAgICAgICAgIGJhbGFuY2VGcm9tLmRlbGVnYXRpb25zSW4gPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNJbiwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgZmFsc2UsCiAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlRnJvbSk7CgogICAgICAgICAgICAgIC8vIHVwZGF0ZSBkZWxlZ2F0aW9uCiAgICAgICAgICAgICAgZGVsZWdhdGlvbi5xdWFudGl0eSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgICBkZWxlZ2F0aW9uLnF1YW50aXR5LCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICBpZiAoYXBpLkJpZ051bWJlcihkZWxlZ2F0aW9uLnF1YW50aXR5KS5ndCgwKSkgewogICAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnZGVsZWdhdGlvbnMnLCBkZWxlZ2F0aW9uKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnJlbW92ZSgnZGVsZWdhdGlvbnMnLCBkZWxlZ2F0aW9uKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIGFkZCBwZW5kaW5nIHVuZGVsZWdhdGlvbgogICAgICAgICAgICAgIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5zdGVlbUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgICAgICAgICAgICAgY29uc3QgY29vbGRvd25QZXJpb2RNaWxsaXNlYyA9IHRva2VuLnVuZGVsZWdhdGlvbkNvb2xkb3duICogMjQgKiAzNjAwICogMTAwMDsKCiAgICAgICAgICAgICAgY29uc3QgY29tcGxldGVUaW1lc3RhbXAgPSBibG9ja0RhdGUuZ2V0VGltZSgpICsgY29vbGRvd25QZXJpb2RNaWxsaXNlYzsKCiAgICAgICAgICAgICAgY29uc3QgdW5kZWxlZ2F0aW9uID0gewogICAgICAgICAgICAgICAgYWNjb3VudDogYXBpLnNlbmRlciwKICAgICAgICAgICAgICAgIHN5bWJvbDogdG9rZW4uc3ltYm9sLAogICAgICAgICAgICAgICAgcXVhbnRpdHksCiAgICAgICAgICAgICAgICBjb21wbGV0ZVRpbWVzdGFtcCwKICAgICAgICAgICAgICAgIHR4SUQ6IGFwaS50cmFuc2FjdGlvbklkLAogICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgIGF3YWl0IGFwaS5kYi5pbnNlcnQoJ3BlbmRpbmdVbmRlbGVnYXRpb25zJywgdW5kZWxlZ2F0aW9uKTsKCiAgICAgICAgICAgICAgYXBpLmVtaXQoJ3VuZGVsZWdhdGVTdGFydCcsIHsgZnJvbTogZmluYWxGcm9tLCBzeW1ib2wsIHF1YW50aXR5IH0pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKY29uc3QgcHJvY2Vzc1VuZGVsZWdhdGlvbiA9IGFzeW5jICh1bmRlbGVnYXRpb24pID0+IHsKICBjb25zdCB7CiAgICBhY2NvdW50LAogICAgc3ltYm9sLAogICAgcXVhbnRpdHksCiAgfSA9IHVuZGVsZWdhdGlvbjsKCiAgY29uc3QgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudCwgc3ltYm9sIH0pOwogIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICBpZiAoYXBpLmFzc2VydChiYWxhbmNlICE9PSBudWxsLCAnYmFsYW5jZSBkb2VzIG5vdCBleGlzdCcpKSB7CiAgICBjb25zdCBvcmlnaW5hbFN0YWtlID0gYmFsYW5jZS5zdGFrZTsKICAgIGNvbnN0IG9yaWdpbmFsUGVuZGluZ1VuZGVsZWdhdGlvbnMgPSBiYWxhbmNlLnBlbmRpbmdVbmRlbGVnYXRpb25zOwoKICAgIC8vIHVwZGF0ZSB0aGUgYmFsYW5jZQogICAgYmFsYW5jZS5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgIGJhbGFuY2Uuc3Rha2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICApOwogICAgYmFsYW5jZS5wZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgIGJhbGFuY2UucGVuZGluZ1VuZGVsZWdhdGlvbnMsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgKTsKCiAgICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2UucGVuZGluZ1VuZGVsZWdhdGlvbnMpLmx0KG9yaWdpbmFsUGVuZGluZ1VuZGVsZWdhdGlvbnMpCiAgICAgICAgJiYgYXBpLkJpZ051bWJlcihiYWxhbmNlLnN0YWtlKS5ndChvcmlnaW5hbFN0YWtlKSwgJ2Nhbm5vdCBzdWJ0cmFjdCcpKSB7CiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2JhbGFuY2VzJywgYmFsYW5jZSk7CgogICAgICAvLyByZW1vdmUgcGVuZGluZ1VuZGVsZWdhdGlvbgogICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCdwZW5kaW5nVW5kZWxlZ2F0aW9ucycsIHVuZGVsZWdhdGlvbik7CgogICAgICBhcGkuZW1pdCgndW5kZWxlZ2F0ZURvbmUnLCB7IGFjY291bnQsIHN5bWJvbCwgcXVhbnRpdHkgfSk7CiAgICB9CiAgfQp9OwoKYWN0aW9ucy5jaGVja1BlbmRpbmdVbmRlbGVnYXRpb25zID0gYXN5bmMgKCkgPT4gewogIGlmIChhcGkuYXNzZXJ0KGFwaS5zZW5kZXIgPT09ICdudWxsJywgJ25vdCBhdXRob3JpemVkJykpIHsKICAgIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5zdGVlbUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgICBjb25zdCB0aW1lc3RhbXAgPSBibG9ja0RhdGUuZ2V0VGltZSgpOwoKICAgIC8vIGdldCBhbGwgdGhlIHBlbmRpbmcgdW5zdGFrZXMgdGhhdCBhcmUgcmVhZHkgdG8gYmUgcmVsZWFzZWQKICAgIGxldCBwZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IGF3YWl0IGFwaS5kYi5maW5kKAogICAgICAncGVuZGluZ1VuZGVsZWdhdGlvbnMnLAogICAgICB7CiAgICAgICAgY29tcGxldGVUaW1lc3RhbXA6IHsKICAgICAgICAgICRsdGU6IHRpbWVzdGFtcCwKICAgICAgICB9LAogICAgICB9LAogICAgKTsKCiAgICBsZXQgbmJQZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IHBlbmRpbmdVbmRlbGVnYXRpb25zLmxlbmd0aDsKICAgIHdoaWxlIChuYlBlbmRpbmdVbmRlbGVnYXRpb25zID4gMCkgewogICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbmJQZW5kaW5nVW5kZWxlZ2F0aW9uczsgaW5kZXggKz0gMSkgewogICAgICAgIGNvbnN0IHBlbmRpbmdVbmRlbGVnYXRpb24gPSBwZW5kaW5nVW5kZWxlZ2F0aW9uc1tpbmRleF07CiAgICAgICAgYXdhaXQgcHJvY2Vzc1VuZGVsZWdhdGlvbihwZW5kaW5nVW5kZWxlZ2F0aW9uKTsKICAgICAgfQoKICAgICAgcGVuZGluZ1VuZGVsZWdhdGlvbnMgPSBhd2FpdCBhcGkuZGIuZmluZCgKICAgICAgICAncGVuZGluZ1VuZGVsZWdhdGlvbnMnLAogICAgICAgIHsKICAgICAgICAgIGNvbXBsZXRlVGltZXN0YW1wOiB7CiAgICAgICAgICAgICRsdGU6IHRpbWVzdGFtcCwKICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgICAgKTsKCiAgICAgIG5iUGVuZGluZ1VuZGVsZWdhdGlvbnMgPSBwZW5kaW5nVW5kZWxlZ2F0aW9ucy5sZW5ndGg7CiAgICB9CiAgfQp9Owo=' + finalTransaction.payload = JSON.stringify(transPayload); + } else if (refSteemBlockNumber === 33996550) { + const transPayload = JSON.parse(finalTransaction.payload); + transPayload.code = 'LyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCAqLwovKiBnbG9iYWwgYWN0aW9ucywgYXBpICovCgphY3Rpb25zLmNyZWF0ZVNTQyA9IGFzeW5jICgpID0+IHsKICBsZXQgdGFibGVFeGlzdHMgPSBhd2FpdCBhcGkuZGIudGFibGVFeGlzdHMoJ3Rva2VucycpOwogIGlmICh0YWJsZUV4aXN0cyA9PT0gZmFsc2UpIHsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgndG9rZW5zJywgWydzeW1ib2wnXSk7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ2JhbGFuY2VzJywgWydhY2NvdW50J10pOwogICAgYXdhaXQgYXBpLmRiLmNyZWF0ZVRhYmxlKCdjb250cmFjdHNCYWxhbmNlcycsIFsnYWNjb3VudCddKTsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgncGFyYW1zJyk7CgogICAgY29uc3QgcGFyYW1zID0ge307CiAgICBwYXJhbXMudG9rZW5DcmVhdGlvbkZlZSA9ICcwJzsKICAgIC8vIHBhcmFtcy51cGRhdGVTdGFraW5nUGFyYW1zRmVlID0gJzEwMCc7CiAgICAvLyBwYXJhbXMudXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSA9ICcxMDAnOwogICAgYXdhaXQgYXBpLmRiLmluc2VydCgncGFyYW1zJywgcGFyYW1zKTsKICB9IGVsc2UgewogICAgLyogY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKICAgIHBhcmFtcy51cGRhdGVTdGFraW5nUGFyYW1zRmVlID0gJzEwMCc7CiAgICBwYXJhbXMudXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSA9ICcxMDAnOwogICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncGFyYW1zJywgcGFyYW1zKTsgKi8KICB9CgogIHRhYmxlRXhpc3RzID0gYXdhaXQgYXBpLmRiLnRhYmxlRXhpc3RzKCdwZW5kaW5nVW5zdGFrZXMnKTsKICBpZiAodGFibGVFeGlzdHMgPT09IGZhbHNlKSB7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ3BlbmRpbmdVbnN0YWtlcycsIFsnYWNjb3VudCcsICd1bnN0YWtlQ29tcGxldGVUaW1lc3RhbXAnXSk7CiAgfQoKICAvLyB1cGRhdGUgU1RFRU1QIGRlY2ltYWwgcGxhY2VzCiAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2w6ICdTVEVFTVAnIH0pOwoKICBpZiAodG9rZW4gJiYgdG9rZW4ucHJlY2lzaW9uIDwgOCkgewogICAgdG9rZW4ucHJlY2lzaW9uID0gODsKICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICB9CgogIHRhYmxlRXhpc3RzID0gYXdhaXQgYXBpLmRiLnRhYmxlRXhpc3RzKCdkZWxlZ2F0aW9ucycpOwogIGlmICh0YWJsZUV4aXN0cyA9PT0gZmFsc2UpIHsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgnZGVsZWdhdGlvbnMnLCBbJ2Zyb20nLCAndG8nXSk7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ3BlbmRpbmdVbmRlbGVnYXRpb25zJywgWydhY2NvdW50JywgJ2NvbXBsZXRlVGltZXN0YW1wJ10pOwogIH0KCiAgLy8gY2xlYW4gZGVsZWdhdGlvbnMKICBjb25zdCBkZWxlZ2F0aW9ucyA9IGF3YWl0IGFwaS5kYi5maW5kKCdkZWxlZ2F0aW9ucycsIHt9KTsKCiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGRlbGVnYXRpb25zLmxlbmd0aDsgaW5kZXggKz0gMSkgewogICAgY29uc3QgZGVsZWdhdGlvbiA9IGRlbGVnYXRpb25zW2luZGV4XTsKICAgIGlmIChkZWxlZ2F0aW9uLmZyb20gPT09IGRlbGVnYXRpb24udG8pIHsKICAgICAgY29uc3QgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudDogZGVsZWdhdGlvbi5mcm9tLCBzeW1ib2w6IGRlbGVnYXRpb24uc3ltYm9sIH0pOwogICAgICBjb25zdCB0a24gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2w6IGRlbGVnYXRpb24uc3ltYm9sIH0pOwogICAgICBiYWxhbmNlLmRlbGVnYXRpb25zSW4gPSBhcGkuQmlnTnVtYmVyKGJhbGFuY2UuZGVsZWdhdGlvbnNJbikKICAgICAgICAubWludXMoZGVsZWdhdGlvbi5xdWFudGl0eSkKICAgICAgICAudG9GaXhlZCh0a24ucHJlY2lzaW9uKTsKCiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2JhbGFuY2VzJywgYmFsYW5jZSk7CiAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ2RlbGVnYXRpb25zJywgZGVsZWdhdGlvbik7CiAgICB9CiAgfQp9OwoKYWN0aW9ucy51cGRhdGVQYXJhbXMgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGlmIChhcGkuc2VuZGVyICE9PSBhcGkub3duZXIpIHJldHVybjsKCiAgY29uc3QgeyB0b2tlbkNyZWF0aW9uRmVlIC8qICwgdXBkYXRlU3Rha2luZ1BhcmFtc0ZlZSwgdXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSAqLyB9ID0gcGF5bG9hZDsKCiAgY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKCiAgcGFyYW1zLnRva2VuQ3JlYXRpb25GZWUgPSB0b2tlbkNyZWF0aW9uRmVlOwogIC8vIHBhcmFtcy51cGRhdGVTdGFraW5nUGFyYW1zRmVlID0gdXBkYXRlU3Rha2luZ1BhcmFtc0ZlZTsKICAvLyBwYXJhbXMudXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSA9IHVwZGF0ZURlbGVnYXRpb25QYXJhbXNGZWU7CgogIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3BhcmFtcycsIHBhcmFtcyk7Cn07CgphY3Rpb25zLnVwZGF0ZVVybCA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgeyB1cmwsIHN5bWJvbCB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAmJiB1cmwgJiYgdHlwZW9mIHVybCA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHBhcmFtcycpCiAgICAmJiBhcGkuYXNzZXJ0KHVybC5sZW5ndGggPD0gMjU1LCAnaW52YWxpZCB1cmw6IG1heCBsZW5ndGggb2YgMjU1JykpIHsKICAgIC8vIGNoZWNrIGlmIHRoZSB0b2tlbiBleGlzdHMKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgIGlmICh0b2tlbikgewogICAgICBpZiAoYXBpLmFzc2VydCh0b2tlbi5pc3N1ZXIgPT09IGFwaS5zZW5kZXIsICdtdXN0IGJlIHRoZSBpc3N1ZXInKSkgewogICAgICAgIHRyeSB7CiAgICAgICAgICBjb25zdCBtZXRhZGF0YSA9IEpTT04ucGFyc2UodG9rZW4ubWV0YWRhdGEpOwoKICAgICAgICAgIGlmIChhcGkuYXNzZXJ0KG1ldGFkYXRhICYmIG1ldGFkYXRhLnVybCwgJ2FuIGVycm9yIG9jY3VyZWQgd2hlbiB0cnlpbmcgdG8gdXBkYXRlIHRoZSB1cmwnKSkgewogICAgICAgICAgICBtZXRhZGF0YS51cmwgPSB1cmw7CiAgICAgICAgICAgIHRva2VuLm1ldGFkYXRhID0gSlNPTi5zdHJpbmdpZnkobWV0YWRhdGEpOwogICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgLy8gZXJyb3Igd2hlbiBwYXJzaW5nIHRoZSBtZXRhZGF0YQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMudXBkYXRlTWV0YWRhdGEgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsgbWV0YWRhdGEsIHN5bWJvbCB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAmJiBtZXRhZGF0YSAmJiB0eXBlb2YgbWV0YWRhdGEgPT09ICdvYmplY3QnLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgLy8gY2hlY2sgaWYgdGhlIHRva2VuIGV4aXN0cwogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgaWYgKHRva2VuKSB7CiAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGNvbnN0IGZpbmFsTWV0YWRhdGEgPSBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7CgogICAgICAgICAgaWYgKGFwaS5hc3NlcnQoZmluYWxNZXRhZGF0YS5sZW5ndGggPD0gMTAwMCwgJ2ludmFsaWQgbWV0YWRhdGE6IG1heCBsZW5ndGggb2YgMTAwMCcpKSB7CiAgICAgICAgICAgIHRva2VuLm1ldGFkYXRhID0gZmluYWxNZXRhZGF0YTsKICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwogICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgIC8vIGVycm9yIHdoZW4gc3RyaW5naWZ5aW5nIHRoZSBtZXRhZGF0YQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMudXBkYXRlUHJlY2lzaW9uID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7IHN5bWJvbCwgcHJlY2lzaW9uLCBpc1NpZ25lZFdpdGhBY3RpdmVLZXkgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJykKICAgICYmIGFwaS5hc3NlcnQoKHByZWNpc2lvbiA+IDAgJiYgcHJlY2lzaW9uIDw9IDgpICYmIChOdW1iZXIuaXNJbnRlZ2VyKHByZWNpc2lvbikpLCAnaW52YWxpZCBwcmVjaXNpb24nKSkgewogICAgLy8gY2hlY2sgaWYgdGhlIHRva2VuIGV4aXN0cwogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgaWYgKHRva2VuKSB7CiAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpCiAgICAgICAgJiYgYXBpLmFzc2VydChwcmVjaXNpb24gPiB0b2tlbi5wcmVjaXNpb24sICdwcmVjaXNpb24gY2FuIG9ubHkgYmUgaW5jcmVhc2VkJykpIHsKICAgICAgICB0b2tlbi5wcmVjaXNpb24gPSBwcmVjaXNpb247CiAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy50cmFuc2Zlck93bmVyc2hpcCA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgeyBzeW1ib2wsIHRvLCBpc1NpZ25lZFdpdGhBY3RpdmVLZXkgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgICAmJiB0byAmJiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgLy8gY2hlY2sgaWYgdGhlIHRva2VuIGV4aXN0cwogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgaWYgKHRva2VuKSB7CiAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpKSB7CiAgICAgICAgY29uc3QgZmluYWxUbyA9IHRvLnRyaW0oKTsKCiAgICAgICAgLy8gYSB2YWxpZCBzdGVlbSBhY2NvdW50IGlzIGJldHdlZW4gMyBhbmQgMTYgY2hhcmFjdGVycyBpbiBsZW5ndGgKICAgICAgICBpZiAoYXBpLmFzc2VydChmaW5hbFRvLmxlbmd0aCA+PSAzICYmIGZpbmFsVG8ubGVuZ3RoIDw9IDE2LCAnaW52YWxpZCB0bycpKSB7CiAgICAgICAgICB0b2tlbi5pc3N1ZXIgPSBmaW5hbFRvOwogICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMuY3JlYXRlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBuYW1lLCBzeW1ib2wsIHVybCwgcHJlY2lzaW9uLCBtYXhTdXBwbHksIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgLy8gZ2V0IGNvbnRyYWN0IHBhcmFtcwogIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CiAgY29uc3QgeyB0b2tlbkNyZWF0aW9uRmVlIH0gPSBwYXJhbXM7CgogIC8vIGdldCBhcGkuc2VuZGVyJ3MgVVRJTElUWV9UT0tFTl9TWU1CT0wgYmFsYW5jZQogIGNvbnN0IHV0aWxpdHlUb2tlbkJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQ6IGFwaS5zZW5kZXIsIHN5bWJvbDogIkVORyIgfSk7CgogIGNvbnN0IGF1dGhvcml6ZWRDcmVhdGlvbiA9IGFwaS5CaWdOdW1iZXIodG9rZW5DcmVhdGlvbkZlZSkubHRlKDApCiAgICA/IHRydWUKICAgIDogdXRpbGl0eVRva2VuQmFsYW5jZSAmJiBhcGkuQmlnTnVtYmVyKHV0aWxpdHlUb2tlbkJhbGFuY2UuYmFsYW5jZSkuZ3RlKHRva2VuQ3JlYXRpb25GZWUpOwoKICBpZiAoYXBpLmFzc2VydChhdXRob3JpemVkQ3JlYXRpb24sICd5b3UgbXVzdCBoYXZlIGVub3VnaCB0b2tlbnMgdG8gY292ZXIgdGhlIGNyZWF0aW9uIGZlZXMnKQogICAgICAmJiBhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAgICYmIGFwaS5hc3NlcnQobmFtZSAmJiB0eXBlb2YgbmFtZSA9PT0gJ3N0cmluZycKICAgICAgJiYgc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAgICYmICh1cmwgPT09IHVuZGVmaW5lZCB8fCAodXJsICYmIHR5cGVvZiB1cmwgPT09ICdzdHJpbmcnKSkKICAgICAgJiYgKChwcmVjaXNpb24gJiYgdHlwZW9mIHByZWNpc2lvbiA9PT0gJ251bWJlcicpIHx8IHByZWNpc2lvbiA9PT0gMCkKICAgICAgJiYgbWF4U3VwcGx5ICYmIHR5cGVvZiBtYXhTdXBwbHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKG1heFN1cHBseSkuaXNOYU4oKSwgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIC8vIHRoZSBwcmVjaXNpb24gbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDggYW5kIG11c3QgYmUgYW4gaW50ZWdlcgogICAgLy8gdGhlIG1heCBzdXBwbHkgbXVzdCBiZSBwb3NpdGl2ZQogICAgaWYgKGFwaS5hc3NlcnQoYXBpLnZhbGlkYXRvci5pc0FscGhhKHN5bWJvbCkgJiYgYXBpLnZhbGlkYXRvci5pc1VwcGVyY2FzZShzeW1ib2wpICYmIHN5bWJvbC5sZW5ndGggPiAwICYmIHN5bWJvbC5sZW5ndGggPD0gMTAsICdpbnZhbGlkIHN5bWJvbDogdXBwZXJjYXNlIGxldHRlcnMgb25seSwgbWF4IGxlbmd0aCBvZiAxMCcpCiAgICAgICYmIGFwaS5hc3NlcnQoYXBpLnZhbGlkYXRvci5pc0FscGhhbnVtZXJpYyhhcGkudmFsaWRhdG9yLmJsYWNrbGlzdChuYW1lLCAnICcpKSAmJiBuYW1lLmxlbmd0aCA+IDAgJiYgbmFtZS5sZW5ndGggPD0gNTAsICdpbnZhbGlkIG5hbWU6IGxldHRlcnMsIG51bWJlcnMsIHdoaXRlc3BhY2VzIG9ubHksIG1heCBsZW5ndGggb2YgNTAnKQogICAgICAmJiBhcGkuYXNzZXJ0KHVybCA9PT0gdW5kZWZpbmVkIHx8IHVybC5sZW5ndGggPD0gMjU1LCAnaW52YWxpZCB1cmw6IG1heCBsZW5ndGggb2YgMjU1JykKICAgICAgJiYgYXBpLmFzc2VydCgocHJlY2lzaW9uID49IDAgJiYgcHJlY2lzaW9uIDw9IDgpICYmIChOdW1iZXIuaXNJbnRlZ2VyKHByZWNpc2lvbikpLCAnaW52YWxpZCBwcmVjaXNpb24nKQogICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIobWF4U3VwcGx5KS5ndCgwKSwgJ21heFN1cHBseSBtdXN0IGJlIHBvc2l0aXZlJykKICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKG1heFN1cHBseSkubHRlKE51bWJlci5NQVhfU0FGRV9JTlRFR0VSKSwgYG1heFN1cHBseSBtdXN0IGJlIGxvd2VyIHRoYW4gJHtOdW1iZXIuTUFYX1NBRkVfSU5URUdFUn1gKSkgewogICAgICAvLyBjaGVjayBpZiB0aGUgdG9rZW4gYWxyZWFkeSBleGlzdHMKICAgICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiA9PT0gbnVsbCwgJ3N5bWJvbCBhbHJlYWR5IGV4aXN0cycpKSB7CiAgICAgICAgY29uc3QgZmluYWxVcmwgPSB1cmwgPT09IHVuZGVmaW5lZCA/ICcnIDogdXJsOwoKICAgICAgICBsZXQgbWV0YWRhdGEgPSB7CiAgICAgICAgICB1cmw6IGZpbmFsVXJsLAogICAgICAgIH07CgogICAgICAgIG1ldGFkYXRhID0gSlNPTi5zdHJpbmdpZnkobWV0YWRhdGEpOwogICAgICAgIGNvbnN0IG5ld1Rva2VuID0gewogICAgICAgICAgaXNzdWVyOiBhcGkuc2VuZGVyLAogICAgICAgICAgc3ltYm9sLAogICAgICAgICAgbmFtZSwKICAgICAgICAgIG1ldGFkYXRhLAogICAgICAgICAgcHJlY2lzaW9uLAogICAgICAgICAgbWF4U3VwcGx5OiBhcGkuQmlnTnVtYmVyKG1heFN1cHBseSkudG9GaXhlZChwcmVjaXNpb24pLAogICAgICAgICAgc3VwcGx5OiAnMCcsCiAgICAgICAgICBjaXJjdWxhdGluZ1N1cHBseTogJzAnLAogICAgICAgICAgc3Rha2luZ0VuYWJsZWQ6IGZhbHNlLAogICAgICAgICAgdW5zdGFraW5nQ29vbGRvd246IDEsCiAgICAgICAgICBkZWxlZ2F0aW9uRW5hYmxlZDogZmFsc2UsCiAgICAgICAgICB1bmRlbGVnYXRpb25Db29sZG93bjogMCwKICAgICAgICB9OwoKICAgICAgICBhd2FpdCBhcGkuZGIuaW5zZXJ0KCd0b2tlbnMnLCBuZXdUb2tlbik7CgogICAgICAgIC8vIGJ1cm4gdGhlIHRva2VuIGNyZWF0aW9uIGZlZXMKICAgICAgICBpZiAoYXBpLkJpZ051bWJlcih0b2tlbkNyZWF0aW9uRmVlKS5ndCgwKSkgewogICAgICAgICAgYXdhaXQgYWN0aW9ucy50cmFuc2Zlcih7CiAgICAgICAgICAgIHRvOiAnbnVsbCcsIHN5bWJvbDogIkVORyIsIHF1YW50aXR5OiB0b2tlbkNyZWF0aW9uRmVlLCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn07CgphY3Rpb25zLmlzc3VlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICB0bywgc3ltYm9sLCBxdWFudGl0eSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydCh0byAmJiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnCiAgICAgICYmIHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgICAmJiBxdWFudGl0eSAmJiB0eXBlb2YgcXVhbnRpdHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgY29uc3QgZmluYWxUbyA9IHRvLnRyaW0oKTsKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgIC8vIHRoZSBzeW1ib2wgbXVzdCBleGlzdAogICAgLy8gdGhlIGFwaS5zZW5kZXIgbXVzdCBiZSB0aGUgaXNzdWVyCiAgICAvLyB0aGVuIHdlIG5lZWQgdG8gY2hlY2sgdGhhdCB0aGUgcXVhbnRpdHkgaXMgY29ycmVjdAogICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ25vdCBhbGxvd2VkIHRvIGlzc3VlIHRva2VucycpCiAgICAgICYmIGFwaS5hc3NlcnQoY291bnREZWNpbWFscyhxdWFudGl0eSkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnc3ltYm9sIHByZWNpc2lvbiBtaXNtYXRjaCcpCiAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QoMCksICdtdXN0IGlzc3VlIHBvc2l0aXZlIHF1YW50aXR5JykKICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHRva2VuLm1heFN1cHBseSkubWludXModG9rZW4uc3VwcGx5KS5ndGUocXVhbnRpdHkpLCAncXVhbnRpdHkgZXhjZWVkcyBhdmFpbGFibGUgc3VwcGx5JykpIHsKCiAgICAgIC8vIGEgdmFsaWQgc3RlZW0gYWNjb3VudCBpcyBiZXR3ZWVuIDMgYW5kIDE2IGNoYXJhY3RlcnMgaW4gbGVuZ3RoCiAgICAgIGlmIChhcGkuYXNzZXJ0KGZpbmFsVG8ubGVuZ3RoID49IDMgJiYgZmluYWxUby5sZW5ndGggPD0gMTYsICdpbnZhbGlkIHRvJykpIHsKICAgICAgICAvLyB3ZSBtYWRlIGFsbCB0aGUgcmVxdWlyZWQgdmVyaWZpY2F0aW9uLCBsZXQncyBub3cgaXNzdWUgdGhlIHRva2VucwoKICAgICAgICBsZXQgcmVzID0gYXdhaXQgYWRkQmFsYW5jZSh0b2tlbi5pc3N1ZXIsIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJyk7CgogICAgICAgIGlmIChyZXMgPT09IHRydWUgJiYgZmluYWxUbyAhPT0gdG9rZW4uaXNzdWVyKSB7CiAgICAgICAgICBpZiAoYXdhaXQgc3ViQmFsYW5jZSh0b2tlbi5pc3N1ZXIsIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJykpIHsKICAgICAgICAgICAgcmVzID0gYXdhaXQgYWRkQmFsYW5jZShmaW5hbFRvLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpOwoKICAgICAgICAgICAgaWYgKHJlcyA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICBhd2FpdCBhZGRCYWxhbmNlKHRva2VuLmlzc3VlciwgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKHJlcyA9PT0gdHJ1ZSkgewogICAgICAgICAgdG9rZW4uc3VwcGx5ID0gY2FsY3VsYXRlQmFsYW5jZSh0b2tlbi5zdXBwbHksIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUpOwoKICAgICAgICAgIGlmIChmaW5hbFRvICE9PSAnbnVsbCcpIHsKICAgICAgICAgICAgdG9rZW4uY2lyY3VsYXRpbmdTdXBwbHkgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgIHRva2VuLmNpcmN1bGF0aW5nU3VwcGx5LCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlLAogICAgICAgICAgICApOwogICAgICAgICAgfQoKICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKCiAgICAgICAgICBhcGkuZW1pdCgndHJhbnNmZXJGcm9tQ29udHJhY3QnLCB7CiAgICAgICAgICAgIGZyb206ICd0b2tlbnMnLCB0bzogZmluYWxUbywgc3ltYm9sLCBxdWFudGl0eSwKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMudHJhbnNmZXIgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHRvLCBzeW1ib2wsIHF1YW50aXR5LCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHRvICYmIHR5cGVvZiB0byA9PT0gJ3N0cmluZycKICAgICAgJiYgc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICBjb25zdCBmaW5hbFRvID0gdG8udHJpbSgpOwogICAgaWYgKGFwaS5hc3NlcnQoZmluYWxUbyAhPT0gYXBpLnNlbmRlciwgJ2Nhbm5vdCB0cmFuc2ZlciB0byBzZWxmJykpIHsKICAgICAgLy8gYSB2YWxpZCBzdGVlbSBhY2NvdW50IGlzIGJldHdlZW4gMyBhbmQgMTYgY2hhcmFjdGVycyBpbiBsZW5ndGgKICAgICAgaWYgKGFwaS5hc3NlcnQoZmluYWxUby5sZW5ndGggPj0gMyAmJiBmaW5hbFRvLmxlbmd0aCA8PSAxNiwgJ2ludmFsaWQgdG8nKSkgewogICAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgICAgICAvLyB0aGUgc3ltYm9sIG11c3QgZXhpc3QKICAgICAgICAvLyB0aGVuIHdlIG5lZWQgdG8gY2hlY2sgdGhhdCB0aGUgcXVhbnRpdHkgaXMgY29ycmVjdAogICAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgICAgICYmIGFwaS5hc3NlcnQoY291bnREZWNpbWFscyhxdWFudGl0eSkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnc3ltYm9sIHByZWNpc2lvbiBtaXNtYXRjaCcpCiAgICAgICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmd0KDApLCAnbXVzdCB0cmFuc2ZlciBwb3NpdGl2ZSBxdWFudGl0eScpKSB7CiAgICAgICAgICBpZiAoYXdhaXQgc3ViQmFsYW5jZShhcGkuc2VuZGVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpKSB7CiAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFkZEJhbGFuY2UoZmluYWxUbywgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKTsKCiAgICAgICAgICAgIGlmIChyZXMgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgYXdhaXQgYWRkQmFsYW5jZShhcGkuc2VuZGVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpOwoKICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChmaW5hbFRvID09PSAnbnVsbCcpIHsKICAgICAgICAgICAgICB0b2tlbi5jaXJjdWxhdGluZ1N1cHBseSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgICB0b2tlbi5jaXJjdWxhdGluZ1N1cHBseSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgZmFsc2UsCiAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGFwaS5lbWl0KCd0cmFuc2ZlcicsIHsKICAgICAgICAgICAgICBmcm9tOiBhcGkuc2VuZGVyLCB0bzogZmluYWxUbywgc3ltYm9sLCBxdWFudGl0eSwKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBmYWxzZTsKfTsKCmFjdGlvbnMudHJhbnNmZXJUb0NvbnRyYWN0ID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICB0bywgc3ltYm9sLCBxdWFudGl0eSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydCh0byAmJiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnCiAgICAgICYmIHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgICAmJiBxdWFudGl0eSAmJiB0eXBlb2YgcXVhbnRpdHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgY29uc3QgZmluYWxUbyA9IHRvLnRyaW0oKTsKICAgIGlmIChhcGkuYXNzZXJ0KGZpbmFsVG8gIT09IGFwaS5zZW5kZXIsICdjYW5ub3QgdHJhbnNmZXIgdG8gc2VsZicpKSB7CiAgICAgIC8vIGEgdmFsaWQgY29udHJhY3QgYWNjb3VudCBpcyBiZXR3ZWVuIDMgYW5kIDUwIGNoYXJhY3RlcnMgaW4gbGVuZ3RoCiAgICAgIGlmIChhcGkuYXNzZXJ0KGZpbmFsVG8ubGVuZ3RoID49IDMgJiYgZmluYWxUby5sZW5ndGggPD0gNTAsICdpbnZhbGlkIHRvJykpIHsKICAgICAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICAgICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAgICAgLy8gdGhlbiB3ZSBuZWVkIHRvIGNoZWNrIHRoYXQgdGhlIHF1YW50aXR5IGlzIGNvcnJlY3QKICAgICAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICAgICAmJiBhcGkuYXNzZXJ0KGNvdW50RGVjaW1hbHMocXVhbnRpdHkpIDw9IHRva2VuLnByZWNpc2lvbiwgJ3N5bWJvbCBwcmVjaXNpb24gbWlzbWF0Y2gnKQogICAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5ndCgwKSwgJ211c3QgdHJhbnNmZXIgcG9zaXRpdmUgcXVhbnRpdHknKSkgewogICAgICAgICAgaWYgKGF3YWl0IHN1YkJhbGFuY2UoYXBpLnNlbmRlciwgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKSkgewogICAgICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBhZGRCYWxhbmNlKGZpbmFsVG8sIHRva2VuLCBxdWFudGl0eSwgJ2NvbnRyYWN0c0JhbGFuY2VzJyk7CgogICAgICAgICAgICBpZiAocmVzID09PSBmYWxzZSkgewogICAgICAgICAgICAgIGF3YWl0IGFkZEJhbGFuY2UoYXBpLnNlbmRlciwgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBpZiAoZmluYWxUbyA9PT0gJ251bGwnKSB7CiAgICAgICAgICAgICAgICB0b2tlbi5jaXJjdWxhdGluZ1N1cHBseSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgICAgIHRva2VuLmNpcmN1bGF0aW5nU3VwcGx5LCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBhcGkuZW1pdCgndHJhbnNmZXJUb0NvbnRyYWN0JywgewogICAgICAgICAgICAgICAgZnJvbTogYXBpLnNlbmRlciwgdG86IGZpbmFsVG8sIHN5bWJvbCwgcXVhbnRpdHksCiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn07CgphY3Rpb25zLnRyYW5zZmVyRnJvbUNvbnRyYWN0ID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICAvLyB0aGlzIGFjdGlvbiBjYW4gb25seSBiZSBjYWxsZWQgYnkgdGhlICdudWxsJyBhY2NvdW50IHdoaWNoIG9ubHkgdGhlIGNvcmUgY29kZSBjYW4gdXNlCiAgaWYgKGFwaS5hc3NlcnQoYXBpLnNlbmRlciA9PT0gJ251bGwnLCAnbm90IGF1dGhvcml6ZWQnKSkgewogICAgY29uc3QgewogICAgICBmcm9tLCB0bywgc3ltYm9sLCBxdWFudGl0eSwgdHlwZSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogICAgfSA9IHBheWxvYWQ7CiAgICBjb25zdCB0eXBlcyA9IFsndXNlcicsICdjb250cmFjdCddOwoKICAgIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAgICYmIGFwaS5hc3NlcnQodG8gJiYgdHlwZW9mIHRvID09PSAnc3RyaW5nJwogICAgICAgICYmIGZyb20gJiYgdHlwZW9mIGZyb20gPT09ICdzdHJpbmcnCiAgICAgICAgJiYgc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAgICAgJiYgdHlwZSAmJiAodHlwZXMuaW5jbHVkZXModHlwZSkpCiAgICAgICAgJiYgcXVhbnRpdHkgJiYgdHlwZW9mIHF1YW50aXR5ID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihxdWFudGl0eSkuaXNOYU4oKSwgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgICAgY29uc3QgZmluYWxUbyA9IHRvLnRyaW0oKTsKICAgICAgY29uc3QgdGFibGUgPSB0eXBlID09PSAndXNlcicgPyAnYmFsYW5jZXMnIDogJ2NvbnRyYWN0c0JhbGFuY2VzJzsKCiAgICAgIGlmIChhcGkuYXNzZXJ0KHR5cGUgPT09ICd1c2VyJyB8fCAodHlwZSA9PT0gJ2NvbnRyYWN0JyAmJiBmaW5hbFRvICE9PSBmcm9tKSwgJ2Nhbm5vdCB0cmFuc2ZlciB0byBzZWxmJykpIHsKICAgICAgICAvLyB2YWxpZGF0ZSB0aGUgInRvIgogICAgICAgIGNvbnN0IHRvVmFsaWQgPSB0eXBlID09PSAndXNlcicgPyBmaW5hbFRvLmxlbmd0aCA+PSAzICYmIGZpbmFsVG8ubGVuZ3RoIDw9IDE2IDogZmluYWxUby5sZW5ndGggPj0gMyAmJiBmaW5hbFRvLmxlbmd0aCA8PSA1MDsKCiAgICAgICAgLy8gdGhlIGFjY291bnQgbXVzdCBleGlzdAogICAgICAgIGlmIChhcGkuYXNzZXJ0KHRvVmFsaWQgPT09IHRydWUsICdpbnZhbGlkIHRvJykpIHsKICAgICAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgICAgICAgIC8vIHRoZSBzeW1ib2wgbXVzdCBleGlzdAogICAgICAgICAgLy8gdGhlbiB3ZSBuZWVkIHRvIGNoZWNrIHRoYXQgdGhlIHF1YW50aXR5IGlzIGNvcnJlY3QKICAgICAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgICAgICAgJiYgYXBpLmFzc2VydChjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdzeW1ib2wgcHJlY2lzaW9uIG1pc21hdGNoJykKICAgICAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5ndCgwKSwgJ211c3QgdHJhbnNmZXIgcG9zaXRpdmUgcXVhbnRpdHknKSkgewoKICAgICAgICAgICAgaWYgKGF3YWl0IHN1YkJhbGFuY2UoZnJvbSwgdG9rZW4sIHF1YW50aXR5LCAnY29udHJhY3RzQmFsYW5jZXMnKSkgewogICAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFkZEJhbGFuY2UoZmluYWxUbywgdG9rZW4sIHF1YW50aXR5LCB0YWJsZSk7CgogICAgICAgICAgICAgIGlmIChyZXMgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgICBhd2FpdCBhZGRCYWxhbmNlKGZyb20sIHRva2VuLCBxdWFudGl0eSwgJ2NvbnRyYWN0c0JhbGFuY2VzJyk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChmaW5hbFRvID09PSAnbnVsbCcpIHsKICAgICAgICAgICAgICAgICAgdG9rZW4uY2lyY3VsYXRpbmdTdXBwbHkgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgICAgICAgIHRva2VuLmNpcmN1bGF0aW5nU3VwcGx5LCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGFwaS5lbWl0KCd0cmFuc2ZlckZyb21Db250cmFjdCcsIHsKICAgICAgICAgICAgICAgICAgZnJvbSwgdG86IGZpbmFsVG8sIHN5bWJvbCwgcXVhbnRpdHksCiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn07Cgpjb25zdCBwcm9jZXNzVW5zdGFrZSA9IGFzeW5jICh1bnN0YWtlKSA9PiB7CiAgY29uc3QgewogICAgYWNjb3VudCwKICAgIHN5bWJvbCwKICAgIHF1YW50aXR5LAogICAgcXVhbnRpdHlMZWZ0LAogICAgbnVtYmVyVHJhbnNhY3Rpb25zTGVmdCwKICB9ID0gdW5zdGFrZTsKCiAgY29uc3QgbmV3VW5zdGFrZSA9IHVuc3Rha2U7CgogIGNvbnN0IGJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQsIHN5bWJvbCB9KTsKICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKICBsZXQgdG9rZW5zVG9SZWxlYXNlID0gMDsKCiAgaWYgKGFwaS5hc3NlcnQoYmFsYW5jZSAhPT0gbnVsbCwgJ2JhbGFuY2UgZG9lcyBub3QgZXhpc3QnKSkgewogICAgLy8gaWYgbGFzdCB0cmFuc2FjdGlvbiB0byBwcm9jZXNzCiAgICBpZiAobnVtYmVyVHJhbnNhY3Rpb25zTGVmdCA9PT0gMSkgewogICAgICB0b2tlbnNUb1JlbGVhc2UgPSBxdWFudGl0eUxlZnQ7CiAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ3BlbmRpbmdVbnN0YWtlcycsIHVuc3Rha2UpOwogICAgfSBlbHNlIHsKICAgICAgdG9rZW5zVG9SZWxlYXNlID0gYXBpLkJpZ051bWJlcihxdWFudGl0eSkKICAgICAgICAuZGl2aWRlZEJ5KHRva2VuLm51bWJlclRyYW5zYWN0aW9ucykKICAgICAgICAudG9GaXhlZCh0b2tlbi5wcmVjaXNpb24sIGFwaS5CaWdOdW1iZXIuUk9VTkRfRE9XTik7CgogICAgICBuZXdVbnN0YWtlLnF1YW50aXR5TGVmdCA9IGFwaS5CaWdOdW1iZXIobmV3VW5zdGFrZS5xdWFudGl0eUxlZnQpCiAgICAgICAgLm1pbnVzKHRva2Vuc1RvUmVsZWFzZSkKICAgICAgICAudG9GaXhlZCh0b2tlbi5wcmVjaXNpb24pOwoKICAgICAgbmV3VW5zdGFrZS5udW1iZXJUcmFuc2FjdGlvbnNMZWZ0IC09IDE7CgogICAgICBuZXdVbnN0YWtlLm5leHRUcmFuc2FjdGlvblRpbWVzdGFtcCA9IGFwaS5CaWdOdW1iZXIobmV3VW5zdGFrZS5uZXh0VHJhbnNhY3Rpb25UaW1lc3RhbXApCiAgICAgICAgLnBsdXMobmV3VW5zdGFrZS5taWxsaXNlY1BlclBlcmlvZCkKICAgICAgICAudG9OdW1iZXIoKTsKCiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3BlbmRpbmdVbnN0YWtlcycsIG5ld1Vuc3Rha2UpOwogICAgfQoKICAgIGlmIChhcGkuQmlnTnVtYmVyKHRva2Vuc1RvUmVsZWFzZSkuZ3QoMCkpIHsKICAgICAgY29uc3Qgb3JpZ2luYWxCYWxhbmNlID0gYmFsYW5jZS5iYWxhbmNlOwogICAgICBjb25zdCBvcmlnaW5hbFBlbmRpbmdTdGFrZSA9IGJhbGFuY2UucGVuZGluZ1Vuc3Rha2U7CgogICAgICBiYWxhbmNlLmJhbGFuY2UgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgIGJhbGFuY2UuYmFsYW5jZSwgdG9rZW5zVG9SZWxlYXNlLCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICAgICk7CiAgICAgIGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgIGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UsIHRva2Vuc1RvUmVsZWFzZSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgKTsKCiAgICAgIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSkubHQob3JpZ2luYWxQZW5kaW5nU3Rha2UpCiAgICAgICAgJiYgYXBpLkJpZ051bWJlcihiYWxhbmNlLmJhbGFuY2UpLmd0KG9yaWdpbmFsQmFsYW5jZSksICdjYW5ub3Qgc3VidHJhY3QnKSkgewogICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2JhbGFuY2VzJywgYmFsYW5jZSk7CgogICAgICAgIHRva2VuLnRvdGFsU3Rha2VkID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgIHRva2VuLnRvdGFsU3Rha2VkLCB0b2tlbnNUb1JlbGVhc2UsIHRva2VuLnByZWNpc2lvbiwgZmFsc2UsCiAgICAgICAgKTsKCiAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwoKICAgICAgICBhcGkuZW1pdCgndW5zdGFrZScsIHsgYWNjb3VudCwgc3ltYm9sLCBxdWFudGl0eTogdG9rZW5zVG9SZWxlYXNlIH0pOwogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy5jaGVja1BlbmRpbmdVbnN0YWtlcyA9IGFzeW5jICgpID0+IHsKICBpZiAoYXBpLmFzc2VydChhcGkuc2VuZGVyID09PSAnbnVsbCcsICdub3QgYXV0aG9yaXplZCcpKSB7CiAgICBjb25zdCBibG9ja0RhdGUgPSBuZXcgRGF0ZShgJHthcGkuc3RlZW1CbG9ja1RpbWVzdGFtcH0uMDAwWmApOwogICAgY29uc3QgdGltZXN0YW1wID0gYmxvY2tEYXRlLmdldFRpbWUoKTsKCiAgICAvLyBnZXQgYWxsIHRoZSBwZW5kaW5nIHVuc3Rha2VzIHRoYXQgYXJlIHJlYWR5IHRvIGJlIHJlbGVhc2VkCiAgICBsZXQgcGVuZGluZ1Vuc3Rha2VzID0gYXdhaXQgYXBpLmRiLmZpbmQoCiAgICAgICdwZW5kaW5nVW5zdGFrZXMnLAogICAgICB7CiAgICAgICAgbmV4dFRyYW5zYWN0aW9uVGltZXN0YW1wOiB7CiAgICAgICAgICAkbHRlOiB0aW1lc3RhbXAsCiAgICAgICAgfSwKICAgICAgfSk7CgogICAgbGV0IG5iUGVuZGluZ1Vuc3Rha2VzID0gcGVuZGluZ1Vuc3Rha2VzLmxlbmd0aDsKICAgIHdoaWxlIChuYlBlbmRpbmdVbnN0YWtlcyA+IDApIHsKICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IG5iUGVuZGluZ1Vuc3Rha2VzOyBpbmRleCArPSAxKSB7CiAgICAgICAgY29uc3QgcGVuZGluZ1Vuc3Rha2UgPSBwZW5kaW5nVW5zdGFrZXNbaW5kZXhdOwogICAgICAgIGF3YWl0IHByb2Nlc3NVbnN0YWtlKHBlbmRpbmdVbnN0YWtlKTsKICAgICAgfQoKICAgICAgcGVuZGluZ1Vuc3Rha2VzID0gYXdhaXQgYXBpLmRiLmZpbmQoCiAgICAgICAgJ3BlbmRpbmdVbnN0YWtlcycsCiAgICAgICAgewogICAgICAgICAgbmV4dFRyYW5zYWN0aW9uVGltZXN0YW1wOiB7CiAgICAgICAgICAgICRsdGU6IHRpbWVzdGFtcCwKICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgICAgKTsKCiAgICAgIG5iUGVuZGluZ1Vuc3Rha2VzID0gcGVuZGluZ1Vuc3Rha2VzLmxlbmd0aDsKICAgIH0KICB9Cn07CgphY3Rpb25zLmVuYWJsZVN0YWtpbmcgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHN5bWJvbCwKICAgIHVuc3Rha2luZ0Nvb2xkb3duLAogICAgbnVtYmVyVHJhbnNhY3Rpb25zLAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHN5bWJvbCcpCiAgICAmJiBhcGkuYXNzZXJ0KHVuc3Rha2luZ0Nvb2xkb3duICYmIE51bWJlci5pc0ludGVnZXIodW5zdGFraW5nQ29vbGRvd24pICYmIHVuc3Rha2luZ0Nvb2xkb3duID4gMCAmJiB1bnN0YWtpbmdDb29sZG93biA8PSAzNjUsICd1bnN0YWtpbmdDb29sZG93biBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAzNjUnKQogICAgJiYgYXBpLmFzc2VydChudW1iZXJUcmFuc2FjdGlvbnMgJiYgTnVtYmVyLmlzSW50ZWdlcihudW1iZXJUcmFuc2FjdGlvbnMpICYmIG51bWJlclRyYW5zYWN0aW9ucyA+IDAgJiYgbnVtYmVyVHJhbnNhY3Rpb25zIDw9IDM2NSwgJ251bWJlclRyYW5zYWN0aW9ucyBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAzNjUnKSkgewogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uc3Rha2luZ0VuYWJsZWQgPT09IHVuZGVmaW5lZCB8fCB0b2tlbi5zdGFraW5nRW5hYmxlZCA9PT0gZmFsc2UsICdzdGFraW5nIGFscmVhZHkgZW5hYmxlZCcpKSB7CiAgICAgIHRva2VuLnN0YWtpbmdFbmFibGVkID0gdHJ1ZTsKICAgICAgdG9rZW4udG90YWxTdGFrZWQgPSAnMCc7CiAgICAgIHRva2VuLnVuc3Rha2luZ0Nvb2xkb3duID0gdW5zdGFraW5nQ29vbGRvd247CiAgICAgIHRva2VuLm51bWJlclRyYW5zYWN0aW9ucyA9IG51bWJlclRyYW5zYWN0aW9uczsKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwogICAgfQogIH0KfTsKCi8qCmFjdGlvbnMudXBkYXRlU3Rha2luZ1BhcmFtcyA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgc3ltYm9sLAogICAgdW5zdGFraW5nQ29vbGRvd24sCiAgICBudW1iZXJUcmFuc2FjdGlvbnMsCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIC8vIGdldCBjb250cmFjdCBwYXJhbXMKICBjb25zdCBwYXJhbXMgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncGFyYW1zJywge30pOwogIGNvbnN0IHsgdXBkYXRlU3Rha2luZ1BhcmFtc0ZlZSB9ID0gcGFyYW1zOwoKICAvLyBnZXQgYXBpLnNlbmRlcidzIFVUSUxJVFlfVE9LRU5fU1lNQk9MIGJhbGFuY2UKICBjb25zdCB1dGlsaXR5VG9rZW5CYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50OiBhcGkuc2VuZGVyLCBzeW1ib2w6ICJFTkciIH0pOwoKICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHV0aWxpdHlUb2tlbkJhbGFuY2UuYmFsYW5jZSkuZ3RlKHVwZGF0ZVN0YWtpbmdQYXJhbXNGZWUpLCAneW91IG11c3QgaGF2ZSBlbm91Z2ggdG9rZW5zIHRvIGNvdmVyIHRoZSBmZWVzJykKICAgICYmIGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnLCAnaW52YWxpZCBzeW1ib2wnKQogICAgJiYgYXBpLmFzc2VydCh1bnN0YWtpbmdDb29sZG93biAmJiBOdW1iZXIuaXNJbnRlZ2VyKHVuc3Rha2luZ0Nvb2xkb3duKSAmJiB1bnN0YWtpbmdDb29sZG93biA+IDAgJiYgdW5zdGFraW5nQ29vbGRvd24gPD0gMzY1LCAndW5zdGFraW5nQ29vbGRvd24gbXVzdCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMSBhbmQgMzY1JykKICAgICYmIGFwaS5hc3NlcnQobnVtYmVyVHJhbnNhY3Rpb25zICYmIE51bWJlci5pc0ludGVnZXIobnVtYmVyVHJhbnNhY3Rpb25zKSAmJiBudW1iZXJUcmFuc2FjdGlvbnMgPiAwICYmIG51bWJlclRyYW5zYWN0aW9ucyA8PSAzNjUsICdudW1iZXJUcmFuc2FjdGlvbnMgbXVzdCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMSBhbmQgMzY1JykpIHsKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5pc3N1ZXIgPT09IGFwaS5zZW5kZXIsICdtdXN0IGJlIHRoZSBpc3N1ZXInKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLnN0YWtpbmdFbmFibGVkID09PSB0cnVlLCAnc3Rha2luZyBub3QgZW5hYmxlZCcpKSB7CiAgICAgIHRva2VuLnVuc3Rha2luZ0Nvb2xkb3duID0gdW5zdGFraW5nQ29vbGRvd247CiAgICAgIHRva2VuLm51bWJlclRyYW5zYWN0aW9ucyA9IG51bWJlclRyYW5zYWN0aW9uczsKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwoKICAgICAgLy8gYnVybiB0aGUgdG9rZW4gY3JlYXRpb24gZmVlcwogICAgICBpZiAoYXBpLkJpZ051bWJlcih1cGRhdGVTdGFraW5nUGFyYW1zRmVlKS5ndCgwKSkgewogICAgICAgIGF3YWl0IGFjdGlvbnMudHJhbnNmZXIoewogICAgICAgICAgdG86ICdudWxsJywgc3ltYm9sOiAiRU5HIiwgcXVhbnRpdHk6IHVwZGF0ZVN0YWtpbmdQYXJhbXNGZWUsIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICAgICAgICB9KTsKICAgICAgfQogICAgfQogIH0KfTsKKi8KCmFjdGlvbnMuc3Rha2UgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHN5bWJvbCwKICAgIHF1YW50aXR5LAogICAgdG8sCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgJiYgdG8gJiYgdHlwZW9mIHRvID09PSAnc3RyaW5nJwogICAgJiYgcXVhbnRpdHkgJiYgdHlwZW9mIHF1YW50aXR5ID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihxdWFudGl0eSkuaXNOYU4oKSwgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIC8vIGEgdmFsaWQgc3RlZW0gYWNjb3VudCBpcyBiZXR3ZWVuIDMgYW5kIDE2IGNoYXJhY3RlcnMgaW4gbGVuZ3RoCiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBjb25zdCBmaW5hbFRvID0gdG8udHJpbSgpOwoKICAgIC8vIHRoZSBzeW1ib2wgbXVzdCBleGlzdAogICAgLy8gdGhlbiB3ZSBuZWVkIHRvIGNoZWNrIHRoYXQgdGhlIHF1YW50aXR5IGlzIGNvcnJlY3QKICAgIGlmIChhcGkuYXNzZXJ0KGZpbmFsVG8ubGVuZ3RoID49IDMgJiYgZmluYWxUby5sZW5ndGggPD0gMTYsICdpbnZhbGlkIHRvJykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICYmIGFwaS5hc3NlcnQoY291bnREZWNpbWFscyhxdWFudGl0eSkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnc3ltYm9sIHByZWNpc2lvbiBtaXNtYXRjaCcpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uc3Rha2luZ0VuYWJsZWQgPT09IHRydWUsICdzdGFraW5nIG5vdCBlbmFibGVkJykKICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5ndCgwKSwgJ211c3Qgc3Rha2UgcG9zaXRpdmUgcXVhbnRpdHknKSkgewogICAgICBpZiAoYXdhaXQgc3ViQmFsYW5jZShhcGkuc2VuZGVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpKSB7CiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgYWRkU3Rha2UoZmluYWxUbywgdG9rZW4sIHF1YW50aXR5KTsKCiAgICAgICAgaWYgKHJlcyA9PT0gZmFsc2UpIHsKICAgICAgICAgIGF3YWl0IGFkZEJhbGFuY2UoYXBpLnNlbmRlciwgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgYXBpLmVtaXQoJ3N0YWtlJywgeyBhY2NvdW50OiBmaW5hbFRvLCBzeW1ib2wsIHF1YW50aXR5IH0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmNvbnN0IHN0YXJ0VW5zdGFrZSA9IGFzeW5jIChhY2NvdW50LCB0b2tlbiwgcXVhbnRpdHkpID0+IHsKICBjb25zdCBibG9ja0RhdGUgPSBuZXcgRGF0ZShgJHthcGkuc3RlZW1CbG9ja1RpbWVzdGFtcH0uMDAwWmApOwogIGNvbnN0IGNvb2xkb3duUGVyaW9kTWlsbGlzZWMgPSB0b2tlbi51bnN0YWtpbmdDb29sZG93biAqIDI0ICogMzYwMCAqIDEwMDA7CiAgY29uc3QgbWlsbGlzZWNQZXJQZXJpb2QgPSBhcGkuQmlnTnVtYmVyKGNvb2xkb3duUGVyaW9kTWlsbGlzZWMpCiAgICAuZGl2aWRlZEJ5KHRva2VuLm51bWJlclRyYW5zYWN0aW9ucykKICAgIC5pbnRlZ2VyVmFsdWUoYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKCiAgY29uc3QgbmV4dFRyYW5zYWN0aW9uVGltZXN0YW1wID0gYXBpLkJpZ051bWJlcihibG9ja0RhdGUuZ2V0VGltZSgpKQogICAgLnBsdXMobWlsbGlzZWNQZXJQZXJpb2QpCiAgICAudG9OdW1iZXIoKTsKCiAgY29uc3QgdW5zdGFrZSA9IHsKICAgIGFjY291bnQsCiAgICBzeW1ib2w6IHRva2VuLnN5bWJvbCwKICAgIHF1YW50aXR5LAogICAgcXVhbnRpdHlMZWZ0OiBxdWFudGl0eSwKICAgIG5leHRUcmFuc2FjdGlvblRpbWVzdGFtcCwKICAgIG51bWJlclRyYW5zYWN0aW9uc0xlZnQ6IHRva2VuLm51bWJlclRyYW5zYWN0aW9ucywKICAgIG1pbGxpc2VjUGVyUGVyaW9kLAogICAgdHhJRDogYXBpLnRyYW5zYWN0aW9uSWQsCiAgfTsKCiAgYXdhaXQgYXBpLmRiLmluc2VydCgncGVuZGluZ1Vuc3Rha2VzJywgdW5zdGFrZSk7Cn07CgphY3Rpb25zLnVuc3Rha2UgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsgc3ltYm9sLCBxdWFudGl0eSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5IH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICAgJiYgcXVhbnRpdHkgJiYgdHlwZW9mIHF1YW50aXR5ID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihxdWFudGl0eSkuaXNOYU4oKSwgJ2ludmFsaWQgcGFyYW1zJykpIHsKCiAgICAvLyBhIHZhbGlkIHN0ZWVtIGFjY291bnQgaXMgYmV0d2VlbiAzIGFuZCAxNiBjaGFyYWN0ZXJzIGluIGxlbmd0aAogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAvLyB0aGVuIHdlIG5lZWQgdG8gY2hlY2sgdGhhdCB0aGUgcXVhbnRpdHkgaXMgY29ycmVjdAogICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLnN0YWtpbmdFbmFibGVkID09PSB0cnVlLCAnc3Rha2luZyBub3QgZW5hYmxlZCcpCiAgICAgICYmIGFwaS5hc3NlcnQoY291bnREZWNpbWFscyhxdWFudGl0eSkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnc3ltYm9sIHByZWNpc2lvbiBtaXNtYXRjaCcpCiAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QoMCksICdtdXN0IHVuc3Rha2UgcG9zaXRpdmUgcXVhbnRpdHknKSkgewoKICAgICAgaWYgKGF3YWl0IHN1YlN0YWtlKGFwaS5zZW5kZXIsIHRva2VuLCBxdWFudGl0eSkpIHsKICAgICAgICBhd2FpdCBzdGFydFVuc3Rha2UoYXBpLnNlbmRlciwgdG9rZW4sIHF1YW50aXR5KTsKCiAgICAgICAgYXBpLmVtaXQoJ3Vuc3Rha2VTdGFydCcsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgc3ltYm9sLCBxdWFudGl0eSB9KTsKICAgICAgfQogICAgfQogIH0KfTsKCmNvbnN0IHByb2Nlc3NDYW5jZWxVbnN0YWtlID0gYXN5bmMgKHVuc3Rha2UpID0+IHsKICBjb25zdCB7CiAgICBhY2NvdW50LAogICAgc3ltYm9sLAogICAgcXVhbnRpdHlMZWZ0LAogIH0gPSB1bnN0YWtlOwoKICBjb25zdCBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50LCBzeW1ib2wgfSk7CiAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogIGlmIChhcGkuYXNzZXJ0KGJhbGFuY2UgIT09IG51bGwsICdiYWxhbmNlIGRvZXMgbm90IGV4aXN0JykKICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlLnBlbmRpbmdVbnN0YWtlKS5ndGUocXVhbnRpdHlMZWZ0KSwgJ292ZXJkcmF3biBwZW5kaW5nVW5zdGFrZScpKSB7CiAgICBjb25zdCBvcmlnaW5hbFN0YWtlID0gYmFsYW5jZS5zdGFrZTsKICAgIGNvbnN0IG9yaWdpbmFsUGVuZGluZ1N0YWtlID0gYmFsYW5jZS5wZW5kaW5nVW5zdGFrZTsKCiAgICBiYWxhbmNlLnN0YWtlID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgYmFsYW5jZS5zdGFrZSwgcXVhbnRpdHlMZWZ0LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICApOwogICAgYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgIGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UsIHF1YW50aXR5TGVmdCwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICk7CgogICAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlLnBlbmRpbmdVbnN0YWtlKS5sdChvcmlnaW5hbFBlbmRpbmdTdGFrZSkKICAgICAgJiYgYXBpLkJpZ051bWJlcihiYWxhbmNlLnN0YWtlKS5ndChvcmlnaW5hbFN0YWtlKSwgJ2Nhbm5vdCBzdWJ0cmFjdCcpKSB7CiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2JhbGFuY2VzJywgYmFsYW5jZSk7CgogICAgICBhcGkuZW1pdCgndW5zdGFrZScsIHsgYWNjb3VudCwgc3ltYm9sLCBxdWFudGl0eTogcXVhbnRpdHlMZWZ0IH0pOwogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICB9CgogIHJldHVybiBmYWxzZTsKfTsKCmFjdGlvbnMuY2FuY2VsVW5zdGFrZSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgeyB0eElELCBpc1NpZ25lZFdpdGhBY3RpdmVLZXkgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAgICYmIGFwaS5hc3NlcnQodHhJRCAmJiB0eXBlb2YgdHhJRCA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICAvLyBnZXQgdW5zdGFrZQogICAgY29uc3QgdW5zdGFrZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwZW5kaW5nVW5zdGFrZXMnLCB7IGFjY291bnQ6IGFwaS5zZW5kZXIsIHR4SUQgfSk7CgogICAgaWYgKGFwaS5hc3NlcnQodW5zdGFrZSwgJ3Vuc3Rha2UgZG9lcyBub3QgZXhpc3QnKSkgewogICAgICBpZiAoYXdhaXQgcHJvY2Vzc0NhbmNlbFVuc3Rha2UodW5zdGFrZSkpIHsKICAgICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCdwZW5kaW5nVW5zdGFrZXMnLCB1bnN0YWtlKTsKICAgICAgfQogICAgfQogIH0KfTsKCmNvbnN0IGJhbGFuY2VUZW1wbGF0ZSA9IHsKICBhY2NvdW50OiBudWxsLAogIHN5bWJvbDogbnVsbCwKICBiYWxhbmNlOiAnMCcsCiAgc3Rha2U6ICcwJywKICBwZW5kaW5nVW5zdGFrZTogJzAnLAogIGRlbGVnYXRpb25zSW46ICcwJywKICBkZWxlZ2F0aW9uc091dDogJzAnLAogIHBlbmRpbmdVbmRlbGVnYXRpb25zOiAnMCcsCn07Cgpjb25zdCBhZGRTdGFrZSA9IGFzeW5jIChhY2NvdW50LCB0b2tlbiwgcXVhbnRpdHkpID0+IHsKICBsZXQgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudCwgc3ltYm9sOiB0b2tlbi5zeW1ib2wgfSk7CgogIGlmIChiYWxhbmNlID09PSBudWxsKSB7CiAgICBiYWxhbmNlID0gYmFsYW5jZVRlbXBsYXRlOwogICAgYmFsYW5jZS5hY2NvdW50ID0gYWNjb3VudDsKICAgIGJhbGFuY2Uuc3ltYm9sID0gdG9rZW4uc3ltYm9sOwoKICAgIGJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuaW5zZXJ0KCdiYWxhbmNlcycsIGJhbGFuY2UpOwogIH0KCiAgaWYgKGJhbGFuY2Uuc3Rha2UgPT09IHVuZGVmaW5lZCkgewogICAgYmFsYW5jZS5zdGFrZSA9ICcwJzsKICAgIGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UgPSAnMCc7CiAgfQoKICBjb25zdCBvcmlnaW5hbFN0YWtlID0gYmFsYW5jZS5zdGFrZTsKCiAgYmFsYW5jZS5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoYmFsYW5jZS5zdGFrZSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSk7CiAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlLnN0YWtlKS5ndChvcmlnaW5hbFN0YWtlKSwgJ2Nhbm5vdCBhZGQnKSkgewogICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlKTsKCiAgICBpZiAodG9rZW4udG90YWxTdGFrZWQgPT09IHVuZGVmaW5lZCkgewogICAgICB0b2tlbi50b3RhbFN0YWtlZCA9ICcwJzsKICAgIH0KCiAgICB0b2tlbi50b3RhbFN0YWtlZCA9IGNhbGN1bGF0ZUJhbGFuY2UodG9rZW4udG90YWxTdGFrZWQsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUpOwogICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwoKICAgIHJldHVybiB0cnVlOwogIH0KCiAgcmV0dXJuIGZhbHNlOwp9OwoKY29uc3Qgc3ViU3Rha2UgPSBhc3luYyAoYWNjb3VudCwgdG9rZW4sIHF1YW50aXR5KSA9PiB7CiAgY29uc3QgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudCwgc3ltYm9sOiB0b2tlbi5zeW1ib2wgfSk7CgogIGlmIChhcGkuYXNzZXJ0KGJhbGFuY2UgIT09IG51bGwsICdiYWxhbmNlIGRvZXMgbm90IGV4aXN0JykKICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlLnN0YWtlKS5ndGUocXVhbnRpdHkpLCAnb3ZlcmRyYXduIHN0YWtlJykpIHsKICAgIGNvbnN0IG9yaWdpbmFsU3Rha2UgPSBiYWxhbmNlLnN0YWtlOwogICAgY29uc3Qgb3JpZ2luYWxQZW5kaW5nU3Rha2UgPSBiYWxhbmNlLnBlbmRpbmdVbnN0YWtlOwoKICAgIGJhbGFuY2Uuc3Rha2UgPSBjYWxjdWxhdGVCYWxhbmNlKGJhbGFuY2Uuc3Rha2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlKTsKICAgIGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICBiYWxhbmNlLnBlbmRpbmdVbnN0YWtlLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlLAogICAgKTsKCiAgICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2Uuc3Rha2UpLmx0KG9yaWdpbmFsU3Rha2UpCiAgICAgICYmIGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSkuZ3Qob3JpZ2luYWxQZW5kaW5nU3Rha2UpLCAnY2Fubm90IHN1YnRyYWN0JykpIHsKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlKTsKCiAgICAgIHJldHVybiB0cnVlOwogICAgfQogIH0KCiAgcmV0dXJuIGZhbHNlOwp9OwoKY29uc3Qgc3ViQmFsYW5jZSA9IGFzeW5jIChhY2NvdW50LCB0b2tlbiwgcXVhbnRpdHksIHRhYmxlKSA9PiB7CiAgY29uc3QgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKHRhYmxlLCB7IGFjY291bnQsIHN5bWJvbDogdG9rZW4uc3ltYm9sIH0pOwoKICBpZiAoYXBpLmFzc2VydChiYWxhbmNlICE9PSBudWxsLCAnYmFsYW5jZSBkb2VzIG5vdCBleGlzdCcpCiAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5iYWxhbmNlKS5ndGUocXVhbnRpdHkpLCAnb3ZlcmRyYXduIGJhbGFuY2UnKSkgewogICAgY29uc3Qgb3JpZ2luYWxCYWxhbmNlID0gYmFsYW5jZS5iYWxhbmNlOwoKICAgIGJhbGFuY2UuYmFsYW5jZSA9IGNhbGN1bGF0ZUJhbGFuY2UoYmFsYW5jZS5iYWxhbmNlLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSk7CgogICAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlLmJhbGFuY2UpLmx0KG9yaWdpbmFsQmFsYW5jZSksICdjYW5ub3Qgc3VidHJhY3QnKSkgewogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKHRhYmxlLCBiYWxhbmNlKTsKCiAgICAgIHJldHVybiB0cnVlOwogICAgfQogIH0KCiAgcmV0dXJuIGZhbHNlOwp9OwoKY29uc3QgYWRkQmFsYW5jZSA9IGFzeW5jIChhY2NvdW50LCB0b2tlbiwgcXVhbnRpdHksIHRhYmxlKSA9PiB7CiAgbGV0IGJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSh0YWJsZSwgeyBhY2NvdW50LCBzeW1ib2w6IHRva2VuLnN5bWJvbCB9KTsKICBpZiAoYmFsYW5jZSA9PT0gbnVsbCkgewogICAgYmFsYW5jZSA9IGJhbGFuY2VUZW1wbGF0ZTsKICAgIGJhbGFuY2UuYWNjb3VudCA9IGFjY291bnQ7CiAgICBiYWxhbmNlLnN5bWJvbCA9IHRva2VuLnN5bWJvbDsKICAgIGJhbGFuY2UuYmFsYW5jZSA9IHF1YW50aXR5OwoKCiAgICBhd2FpdCBhcGkuZGIuaW5zZXJ0KHRhYmxlLCBiYWxhbmNlKTsKCiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIGNvbnN0IG9yaWdpbmFsQmFsYW5jZSA9IGJhbGFuY2UuYmFsYW5jZTsKCiAgYmFsYW5jZS5iYWxhbmNlID0gY2FsY3VsYXRlQmFsYW5jZShiYWxhbmNlLmJhbGFuY2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUpOwogIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5iYWxhbmNlKS5ndChvcmlnaW5hbEJhbGFuY2UpLCAnY2Fubm90IGFkZCcpKSB7CiAgICBhd2FpdCBhcGkuZGIudXBkYXRlKHRhYmxlLCBiYWxhbmNlKTsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgcmV0dXJuIGZhbHNlOwp9OwoKY29uc3QgY2FsY3VsYXRlQmFsYW5jZSA9IChiYWxhbmNlLCBxdWFudGl0eSwgcHJlY2lzaW9uLCBhZGQpID0+IHsKICByZXR1cm4gYWRkCiAgICA/IGFwaS5CaWdOdW1iZXIoYmFsYW5jZSkucGx1cyhxdWFudGl0eSkudG9GaXhlZChwcmVjaXNpb24pCiAgICA6IGFwaS5CaWdOdW1iZXIoYmFsYW5jZSkubWludXMocXVhbnRpdHkpLnRvRml4ZWQocHJlY2lzaW9uKTsKfTsKCmNvbnN0IGNvdW50RGVjaW1hbHMgPSB2YWx1ZSA9PiBhcGkuQmlnTnVtYmVyKHZhbHVlKS5kcCgpOwoKYWN0aW9ucy5lbmFibGVEZWxlZ2F0aW9uID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICB1bmRlbGVnYXRpb25Db29sZG93biwKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnLCAnaW52YWxpZCBzeW1ib2wnKQogICAgJiYgYXBpLmFzc2VydCh1bmRlbGVnYXRpb25Db29sZG93biAmJiBOdW1iZXIuaXNJbnRlZ2VyKHVuZGVsZWdhdGlvbkNvb2xkb3duKSAmJiB1bmRlbGVnYXRpb25Db29sZG93biA+IDAgJiYgdW5kZWxlZ2F0aW9uQ29vbGRvd24gPD0gMzY1LCAndW5kZWxlZ2F0aW9uQ29vbGRvd24gbXVzdCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMSBhbmQgMzY1JykpIHsKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5pc3N1ZXIgPT09IGFwaS5zZW5kZXIsICdtdXN0IGJlIHRoZSBpc3N1ZXInKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLnN0YWtpbmdFbmFibGVkID09PSB0cnVlLCAnc3Rha2luZyBub3QgZW5hYmxlZCcpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uZGVsZWdhdGlvbkVuYWJsZWQgPT09IHVuZGVmaW5lZCB8fCB0b2tlbi5kZWxlZ2F0aW9uRW5hYmxlZCA9PT0gZmFsc2UsICdkZWxlZ2F0aW9uIGFscmVhZHkgZW5hYmxlZCcpKSB7CiAgICAgIHRva2VuLmRlbGVnYXRpb25FbmFibGVkID0gdHJ1ZTsKICAgICAgdG9rZW4udW5kZWxlZ2F0aW9uQ29vbGRvd24gPSB1bmRlbGVnYXRpb25Db29sZG93bjsKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwogICAgfQogIH0KfTsKCi8qCmFjdGlvbnMudXBkYXRlRGVsZWdhdGlvblBhcmFtcyA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgc3ltYm9sLAogICAgdW5kZWxlZ2F0aW9uQ29vbGRvd24sCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIC8vIGdldCBjb250cmFjdCBwYXJhbXMKICBjb25zdCBwYXJhbXMgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncGFyYW1zJywge30pOwogIGNvbnN0IHsgdXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSB9ID0gcGFyYW1zOwoKICAvLyBnZXQgYXBpLnNlbmRlcidzIFVUSUxJVFlfVE9LRU5fU1lNQk9MIGJhbGFuY2UKICBjb25zdCB1dGlsaXR5VG9rZW5CYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50OiBhcGkuc2VuZGVyLCBzeW1ib2w6ICJFTkciIH0pOwoKICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHV0aWxpdHlUb2tlbkJhbGFuY2UuYmFsYW5jZSkuZ3RlKHVwZGF0ZURlbGVnYXRpb25QYXJhbXNGZWUpLCAneW91IG11c3QgaGF2ZSBlbm91Z2ggdG9rZW5zIHRvIGNvdmVyIHRoZSBmZWVzJykKICAgICYmIGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnLCAnaW52YWxpZCBzeW1ib2wnKQogICAgJiYgYXBpLmFzc2VydCh1bmRlbGVnYXRpb25Db29sZG93biAmJiBOdW1iZXIuaXNJbnRlZ2VyKHVuZGVsZWdhdGlvbkNvb2xkb3duKSAmJiB1bmRlbGVnYXRpb25Db29sZG93biA+IDAgJiYgdW5kZWxlZ2F0aW9uQ29vbGRvd24gPD0gMzY1LCAndW5kZWxlZ2F0aW9uQ29vbGRvd24gbXVzdCBiZSBhbiBpbnRlZ2VyIGJldHdlZW4gMSBhbmQgMzY1JykpIHsKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5pc3N1ZXIgPT09IGFwaS5zZW5kZXIsICdtdXN0IGJlIHRoZSBpc3N1ZXInKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLmRlbGVnYXRpb25FbmFibGVkID09PSB0cnVlLCAnZGVsZWdhdGlvbiBub3QgZW5hYmxlZCcpKSB7CiAgICAgIHRva2VuLnVuZGVsZWdhdGlvbkNvb2xkb3duID0gdW5kZWxlZ2F0aW9uQ29vbGRvd247CiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKCiAgICAgIC8vIGJ1cm4gdGhlIHRva2VuIGNyZWF0aW9uIGZlZXMKICAgICAgaWYgKGFwaS5CaWdOdW1iZXIodXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSkuZ3QoMCkpIHsKICAgICAgICBhd2FpdCBhY3Rpb25zLnRyYW5zZmVyKHsKICAgICAgICAgIHRvOiAnbnVsbCcsIHN5bWJvbDogIkVORyIsIHF1YW50aXR5OiB1cGRhdGVEZWxlZ2F0aW9uUGFyYW1zRmVlLCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KICB9Cn07CgoqLwoKYWN0aW9ucy5kZWxlZ2F0ZSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgc3ltYm9sLAogICAgcXVhbnRpdHksCiAgICB0bywKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAmJiB0byAmJiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnCiAgICAmJiBxdWFudGl0eSAmJiB0eXBlb2YgcXVhbnRpdHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgY29uc3QgZmluYWxUbyA9IHRvLnRyaW0oKTsKICAgIC8vIGEgdmFsaWQgc3RlZW0gYWNjb3VudCBpcyBiZXR3ZWVuIDMgYW5kIDE2IGNoYXJhY3RlcnMgaW4gbGVuZ3RoCiAgICBpZiAoYXBpLmFzc2VydChmaW5hbFRvLmxlbmd0aCA+PSAzICYmIGZpbmFsVG8ubGVuZ3RoIDw9IDE2LCAnaW52YWxpZCB0bycpKSB7CiAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgICAmJiBhcGkuYXNzZXJ0KGNvdW50RGVjaW1hbHMocXVhbnRpdHkpIDw9IHRva2VuLnByZWNpc2lvbiwgJ3N5bWJvbCBwcmVjaXNpb24gbWlzbWF0Y2gnKQogICAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uZGVsZWdhdGlvbkVuYWJsZWQgPT09IHRydWUsICdkZWxlZ2F0aW9uIG5vdCBlbmFibGVkJykKICAgICAgICAmJiBhcGkuYXNzZXJ0KGZpbmFsVG8gIT09IGFwaS5zZW5kZXIsICdjYW5ub3QgZGVsZWdhdGUgdG8geW91cnNlbGYnKQogICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QoMCksICdtdXN0IGRlbGVnYXRlIHBvc2l0aXZlIHF1YW50aXR5JykpIHsKICAgICAgICBjb25zdCBiYWxhbmNlRnJvbSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgc3ltYm9sIH0pOwoKICAgICAgICBpZiAoYXBpLmFzc2VydChiYWxhbmNlRnJvbSAhPT0gbnVsbCwgJ2JhbGFuY2VGcm9tIGRvZXMgbm90IGV4aXN0JykKICAgICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlRnJvbS5zdGFrZSkuZ3RlKHF1YW50aXR5KSwgJ292ZXJkcmF3biBzdGFrZScpKSB7CiAgICAgICAgICBpZiAoYmFsYW5jZUZyb20uc3Rha2UgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAvLyB1cGRhdGUgb2xkIGJhbGFuY2VzIHdpdGggbmV3IHByb3BlcnRpZXMKICAgICAgICAgICAgYmFsYW5jZUZyb20uc3Rha2UgPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VGcm9tLnBlbmRpbmdVbnN0YWtlID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc0luID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc091dCA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZUZyb20ucGVuZGluZ1VuZGVsZWdhdGlvbnMgPSAnMCc7CiAgICAgICAgICB9IGVsc2UgaWYgKGJhbGFuY2VGcm9tLmRlbGVnYXRpb25zSW4gPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAvLyB1cGRhdGUgb2xkIGJhbGFuY2VzIHdpdGggbmV3IHByb3BlcnRpZXMKICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNJbiA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNPdXQgPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VGcm9tLnBlbmRpbmdVbmRlbGVnYXRpb25zID0gJzAnOwogICAgICAgICAgICBpZiAoYmFsYW5jZUZyb20uZGVsZWdhdGVkU3Rha2UpIHsKICAgICAgICAgICAgICBkZWxldGUgYmFsYW5jZUZyb20uZGVsZWdhdGVkU3Rha2U7CiAgICAgICAgICAgICAgZGVsZXRlIGJhbGFuY2VGcm9tLnJlY2VpdmVkU3Rha2U7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICBsZXQgYmFsYW5jZVRvID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50OiB0bywgc3ltYm9sIH0pOwoKICAgICAgICAgIGlmIChiYWxhbmNlVG8gPT09IG51bGwpIHsKICAgICAgICAgICAgYmFsYW5jZVRvID0gYmFsYW5jZVRlbXBsYXRlOwogICAgICAgICAgICBiYWxhbmNlVG8uYWNjb3VudCA9IHRvOwogICAgICAgICAgICBiYWxhbmNlVG8uc3ltYm9sID0gc3ltYm9sOwoKICAgICAgICAgICAgYmFsYW5jZVRvID0gYXdhaXQgYXBpLmRiLmluc2VydCgnYmFsYW5jZXMnLCBiYWxhbmNlVG8pOwogICAgICAgICAgfSBlbHNlIGlmIChiYWxhbmNlVG8uc3Rha2UgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAvLyB1cGRhdGUgb2xkIGJhbGFuY2VzIHdpdGggbmV3IHByb3BlcnRpZXMKICAgICAgICAgICAgYmFsYW5jZVRvLnN0YWtlID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlVG8ucGVuZGluZ1Vuc3Rha2UgPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc0luID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlVG8uZGVsZWdhdGlvbnNPdXQgPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VUby5wZW5kaW5nVW5kZWxlZ2F0aW9ucyA9ICcwJzsKICAgICAgICAgIH0gZWxzZSBpZiAoYmFsYW5jZVRvLmRlbGVnYXRpb25zSW4gPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAvLyB1cGRhdGUgb2xkIGJhbGFuY2VzIHdpdGggbmV3IHByb3BlcnRpZXMKICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zSW4gPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc091dCA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZVRvLnBlbmRpbmdVbmRlbGVnYXRpb25zID0gJzAnOwoKICAgICAgICAgICAgaWYgKGJhbGFuY2VUby5kZWxlZ2F0ZWRTdGFrZSkgewogICAgICAgICAgICAgIGRlbGV0ZSBiYWxhbmNlVG8uZGVsZWdhdGVkU3Rha2U7CiAgICAgICAgICAgICAgZGVsZXRlIGJhbGFuY2VUby5yZWNlaXZlZFN0YWtlOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgLy8gbG9vayBmb3IgYW4gZXhpc3RpbmcgZGVsZWdhdGlvbgogICAgICAgICAgbGV0IGRlbGVnYXRpb24gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnZGVsZWdhdGlvbnMnLCB7IHRvOiBmaW5hbFRvLCBmcm9tOiBhcGkuc2VuZGVyLCBzeW1ib2wgfSk7CgogICAgICAgICAgaWYgKGRlbGVnYXRpb24gPT0gbnVsbCkgewogICAgICAgICAgICAvLyB1cGRhdGUgYmFsYW5jZUZyb20KICAgICAgICAgICAgYmFsYW5jZUZyb20uc3Rha2UgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgIGJhbGFuY2VGcm9tLnN0YWtlLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNPdXQgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgIGJhbGFuY2VGcm9tLmRlbGVnYXRpb25zT3V0LCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlRnJvbSk7CgogICAgICAgICAgICAvLyB1cGRhdGUgYmFsYW5jZVRvCiAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc0luID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgICAgICBiYWxhbmNlVG8uZGVsZWdhdGlvbnNJbiwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2JhbGFuY2VzJywgYmFsYW5jZVRvKTsKCiAgICAgICAgICAgIGRlbGVnYXRpb24gPSB7fTsKICAgICAgICAgICAgZGVsZWdhdGlvbi5mcm9tID0gYXBpLnNlbmRlcjsKICAgICAgICAgICAgZGVsZWdhdGlvbi50byA9IHRvOwogICAgICAgICAgICBkZWxlZ2F0aW9uLnN5bWJvbCA9IHN5bWJvbDsKICAgICAgICAgICAgZGVsZWdhdGlvbi5xdWFudGl0eSA9IHF1YW50aXR5OwoKICAgICAgICAgICAgYXdhaXQgYXBpLmRiLmluc2VydCgnZGVsZWdhdGlvbnMnLCBkZWxlZ2F0aW9uKTsKCiAgICAgICAgICAgIGFwaS5lbWl0KCdkZWxlZ2F0ZScsIHsgdG8sIHN5bWJvbCwgcXVhbnRpdHkgfSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBpZiBhIGRlbGVnYXRpb24gYWxyZWFkeSBleGlzdHMsIGluY3JlYXNlIGl0CgogICAgICAgICAgICAvLyB1cGRhdGUgYmFsYW5jZUZyb20KICAgICAgICAgICAgYmFsYW5jZUZyb20uc3Rha2UgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgIGJhbGFuY2VGcm9tLnN0YWtlLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNPdXQgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgIGJhbGFuY2VGcm9tLmRlbGVnYXRpb25zT3V0LCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlRnJvbSk7CgogICAgICAgICAgICAvLyB1cGRhdGUgYmFsYW5jZVRvCiAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc0luID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgICAgICBiYWxhbmNlVG8uZGVsZWdhdGlvbnNJbiwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2JhbGFuY2VzJywgYmFsYW5jZVRvKTsKCiAgICAgICAgICAgIC8vIHVwZGF0ZSBkZWxlZ2F0aW9uCiAgICAgICAgICAgIGRlbGVnYXRpb24ucXVhbnRpdHkgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgIGRlbGVnYXRpb24ucXVhbnRpdHksIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdkZWxlZ2F0aW9ucycsIGRlbGVnYXRpb24pOwogICAgICAgICAgICBhcGkuZW1pdCgnZGVsZWdhdGUnLCB7IHRvLCBzeW1ib2wsIHF1YW50aXR5IH0pOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMudW5kZWxlZ2F0ZSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgc3ltYm9sLAogICAgcXVhbnRpdHksCiAgICBmcm9tLAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICYmIGZyb20gJiYgdHlwZW9mIGZyb20gPT09ICdzdHJpbmcnCiAgICAmJiBxdWFudGl0eSAmJiB0eXBlb2YgcXVhbnRpdHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgY29uc3QgZmluYWxGcm9tID0gZnJvbS50cmltKCk7CiAgICAvLyBhIHZhbGlkIHN0ZWVtIGFjY291bnQgaXMgYmV0d2VlbiAzIGFuZCAxNiBjaGFyYWN0ZXJzIGluIGxlbmd0aAogICAgaWYgKGFwaS5hc3NlcnQoZmluYWxGcm9tLmxlbmd0aCA+PSAzICYmIGZpbmFsRnJvbS5sZW5ndGggPD0gMTYsICdpbnZhbGlkIGZyb20nKSkgewogICAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICAgIC8vIHRoZSBzeW1ib2wgbXVzdCBleGlzdAogICAgICAvLyB0aGVuIHdlIG5lZWQgdG8gY2hlY2sgdGhhdCB0aGUgcXVhbnRpdHkgaXMgY29ycmVjdAogICAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICAgJiYgYXBpLmFzc2VydChjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdzeW1ib2wgcHJlY2lzaW9uIG1pc21hdGNoJykKICAgICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLmRlbGVnYXRpb25FbmFibGVkID09PSB0cnVlLCAnZGVsZWdhdGlvbiBub3QgZW5hYmxlZCcpCiAgICAgICAgJiYgYXBpLmFzc2VydChmaW5hbEZyb20gIT09IGFwaS5zZW5kZXIsICdjYW5ub3QgdW5kZWxlZ2F0ZSBmcm9tIHlvdXJzZWxmJykKICAgICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmd0KDApLCAnbXVzdCB1bmRlbGVnYXRlIHBvc2l0aXZlIHF1YW50aXR5JykpIHsKICAgICAgICBjb25zdCBiYWxhbmNlVG8gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQ6IGFwaS5zZW5kZXIsIHN5bWJvbCB9KTsKCiAgICAgICAgaWYgKGFwaS5hc3NlcnQoYmFsYW5jZVRvICE9PSBudWxsLCAnYmFsYW5jZVRvIGRvZXMgbm90IGV4aXN0JykKICAgICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlVG8uZGVsZWdhdGlvbnNPdXQpLmd0ZShxdWFudGl0eSksICdvdmVyZHJhd24gZGVsZWdhdGlvbicpKSB7CiAgICAgICAgICBjb25zdCBiYWxhbmNlRnJvbSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudDogZmluYWxGcm9tLCBzeW1ib2wgfSk7CgogICAgICAgICAgaWYgKGFwaS5hc3NlcnQoYmFsYW5jZUZyb20gIT09IG51bGwsICdiYWxhbmNlRnJvbSBkb2VzIG5vdCBleGlzdCcpKSB7CiAgICAgICAgICAgIC8vIGxvb2sgZm9yIGFuIGV4aXN0aW5nIGRlbGVnYXRpb24KICAgICAgICAgICAgY29uc3QgZGVsZWdhdGlvbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdkZWxlZ2F0aW9ucycsIHsgdG86IGZpbmFsRnJvbSwgZnJvbTogYXBpLnNlbmRlciwgc3ltYm9sIH0pOwoKICAgICAgICAgICAgaWYgKGFwaS5hc3NlcnQoZGVsZWdhdGlvbiAhPT0gbnVsbCwgJ2RlbGVnYXRpb24gZG9lcyBub3QgZXhpc3QnKQogICAgICAgICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihkZWxlZ2F0aW9uLnF1YW50aXR5KS5ndGUocXVhbnRpdHkpLCAnb3ZlcmRyYXduIGRlbGVnYXRpb24nKSkgewogICAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlVG8KICAgICAgICAgICAgICBiYWxhbmNlVG8ucGVuZGluZ1VuZGVsZWdhdGlvbnMgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgICAgYmFsYW5jZUZyb20ucGVuZGluZ1VuZGVsZWdhdGlvbnMsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICBiYWxhbmNlVG8uZGVsZWdhdGlvbnNPdXQgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zT3V0LCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2VUbyk7CgogICAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlRnJvbQogICAgICAgICAgICAgIGJhbGFuY2VGcm9tLmRlbGVnYXRpb25zSW4gPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNJbiwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgZmFsc2UsCiAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlRnJvbSk7CgogICAgICAgICAgICAgIC8vIHVwZGF0ZSBkZWxlZ2F0aW9uCiAgICAgICAgICAgICAgZGVsZWdhdGlvbi5xdWFudGl0eSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgICBkZWxlZ2F0aW9uLnF1YW50aXR5LCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICBpZiAoYXBpLkJpZ051bWJlcihkZWxlZ2F0aW9uLnF1YW50aXR5KS5ndCgwKSkgewogICAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnZGVsZWdhdGlvbnMnLCBkZWxlZ2F0aW9uKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnJlbW92ZSgnZGVsZWdhdGlvbnMnLCBkZWxlZ2F0aW9uKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIGFkZCBwZW5kaW5nIHVuZGVsZWdhdGlvbgogICAgICAgICAgICAgIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5zdGVlbUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgICAgICAgICAgICAgY29uc3QgY29vbGRvd25QZXJpb2RNaWxsaXNlYyA9IHRva2VuLnVuZGVsZWdhdGlvbkNvb2xkb3duICogMjQgKiAzNjAwICogMTAwMDsKCiAgICAgICAgICAgICAgY29uc3QgY29tcGxldGVUaW1lc3RhbXAgPSBibG9ja0RhdGUuZ2V0VGltZSgpICsgY29vbGRvd25QZXJpb2RNaWxsaXNlYzsKCiAgICAgICAgICAgICAgY29uc3QgdW5kZWxlZ2F0aW9uID0gewogICAgICAgICAgICAgICAgYWNjb3VudDogYXBpLnNlbmRlciwKICAgICAgICAgICAgICAgIHN5bWJvbDogdG9rZW4uc3ltYm9sLAogICAgICAgICAgICAgICAgcXVhbnRpdHksCiAgICAgICAgICAgICAgICBjb21wbGV0ZVRpbWVzdGFtcCwKICAgICAgICAgICAgICAgIHR4SUQ6IGFwaS50cmFuc2FjdGlvbklkLAogICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgIGF3YWl0IGFwaS5kYi5pbnNlcnQoJ3BlbmRpbmdVbmRlbGVnYXRpb25zJywgdW5kZWxlZ2F0aW9uKTsKCiAgICAgICAgICAgICAgYXBpLmVtaXQoJ3VuZGVsZWdhdGVTdGFydCcsIHsgZnJvbTogZmluYWxGcm9tLCBzeW1ib2wsIHF1YW50aXR5IH0pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKY29uc3QgcHJvY2Vzc1VuZGVsZWdhdGlvbiA9IGFzeW5jICh1bmRlbGVnYXRpb24pID0+IHsKICBjb25zdCB7CiAgICBhY2NvdW50LAogICAgc3ltYm9sLAogICAgcXVhbnRpdHksCiAgfSA9IHVuZGVsZWdhdGlvbjsKCiAgY29uc3QgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudCwgc3ltYm9sIH0pOwogIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICBpZiAoYXBpLmFzc2VydChiYWxhbmNlICE9PSBudWxsLCAnYmFsYW5jZSBkb2VzIG5vdCBleGlzdCcpKSB7CiAgICBjb25zdCBvcmlnaW5hbFN0YWtlID0gYmFsYW5jZS5zdGFrZTsKICAgIGNvbnN0IG9yaWdpbmFsUGVuZGluZ1VuZGVsZWdhdGlvbnMgPSBiYWxhbmNlLnBlbmRpbmdVbmRlbGVnYXRpb25zOwoKICAgIC8vIHVwZGF0ZSB0aGUgYmFsYW5jZQogICAgYmFsYW5jZS5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgIGJhbGFuY2Uuc3Rha2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICApOwogICAgYmFsYW5jZS5wZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgIGJhbGFuY2UucGVuZGluZ1VuZGVsZWdhdGlvbnMsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgKTsKCiAgICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2UucGVuZGluZ1VuZGVsZWdhdGlvbnMpLmx0KG9yaWdpbmFsUGVuZGluZ1VuZGVsZWdhdGlvbnMpCiAgICAgICAgJiYgYXBpLkJpZ051bWJlcihiYWxhbmNlLnN0YWtlKS5ndChvcmlnaW5hbFN0YWtlKSwgJ2Nhbm5vdCBzdWJ0cmFjdCcpKSB7CiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2JhbGFuY2VzJywgYmFsYW5jZSk7CgogICAgICAvLyByZW1vdmUgcGVuZGluZ1VuZGVsZWdhdGlvbgogICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCdwZW5kaW5nVW5kZWxlZ2F0aW9ucycsIHVuZGVsZWdhdGlvbik7CgogICAgICBhcGkuZW1pdCgndW5kZWxlZ2F0ZURvbmUnLCB7IGFjY291bnQsIHN5bWJvbCwgcXVhbnRpdHkgfSk7CiAgICB9CiAgfQp9OwoKYWN0aW9ucy5jaGVja1BlbmRpbmdVbmRlbGVnYXRpb25zID0gYXN5bmMgKCkgPT4gewogIGlmIChhcGkuYXNzZXJ0KGFwaS5zZW5kZXIgPT09ICdudWxsJywgJ25vdCBhdXRob3JpemVkJykpIHsKICAgIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5zdGVlbUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgICBjb25zdCB0aW1lc3RhbXAgPSBibG9ja0RhdGUuZ2V0VGltZSgpOwoKICAgIC8vIGdldCBhbGwgdGhlIHBlbmRpbmcgdW5zdGFrZXMgdGhhdCBhcmUgcmVhZHkgdG8gYmUgcmVsZWFzZWQKICAgIGxldCBwZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IGF3YWl0IGFwaS5kYi5maW5kKAogICAgICAncGVuZGluZ1VuZGVsZWdhdGlvbnMnLAogICAgICB7CiAgICAgICAgY29tcGxldGVUaW1lc3RhbXA6IHsKICAgICAgICAgICRsdGU6IHRpbWVzdGFtcCwKICAgICAgICB9LAogICAgICB9LAogICAgKTsKCiAgICBsZXQgbmJQZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IHBlbmRpbmdVbmRlbGVnYXRpb25zLmxlbmd0aDsKICAgIHdoaWxlIChuYlBlbmRpbmdVbmRlbGVnYXRpb25zID4gMCkgewogICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbmJQZW5kaW5nVW5kZWxlZ2F0aW9uczsgaW5kZXggKz0gMSkgewogICAgICAgIGNvbnN0IHBlbmRpbmdVbmRlbGVnYXRpb24gPSBwZW5kaW5nVW5kZWxlZ2F0aW9uc1tpbmRleF07CiAgICAgICAgYXdhaXQgcHJvY2Vzc1VuZGVsZWdhdGlvbihwZW5kaW5nVW5kZWxlZ2F0aW9uKTsKICAgICAgfQoKICAgICAgcGVuZGluZ1VuZGVsZWdhdGlvbnMgPSBhd2FpdCBhcGkuZGIuZmluZCgKICAgICAgICAncGVuZGluZ1VuZGVsZWdhdGlvbnMnLAogICAgICAgIHsKICAgICAgICAgIGNvbXBsZXRlVGltZXN0YW1wOiB7CiAgICAgICAgICAgICRsdGU6IHRpbWVzdGFtcCwKICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgICAgKTsKCiAgICAgIG5iUGVuZGluZ1VuZGVsZWdhdGlvbnMgPSBwZW5kaW5nVW5kZWxlZ2F0aW9ucy5sZW5ndGg7CiAgICB9CiAgfQp9Owo='; + finalTransaction.payload = JSON.stringify(transPayload); + } else if (refSteemBlockNumber === 34141225) { + const transPayload = JSON.parse(finalTransaction.payload); + transPayload.code = 'LyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCAqLwovKiBnbG9iYWwgYWN0aW9ucywgYXBpICovCgphY3Rpb25zLmNyZWF0ZVNTQyA9IGFzeW5jICgpID0+IHsKICBsZXQgdGFibGVFeGlzdHMgPSBhd2FpdCBhcGkuZGIudGFibGVFeGlzdHMoJ3Rva2VucycpOwogIGlmICh0YWJsZUV4aXN0cyA9PT0gZmFsc2UpIHsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgndG9rZW5zJywgWydzeW1ib2wnXSk7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ2JhbGFuY2VzJywgWydhY2NvdW50J10pOwogICAgYXdhaXQgYXBpLmRiLmNyZWF0ZVRhYmxlKCdjb250cmFjdHNCYWxhbmNlcycsIFsnYWNjb3VudCddKTsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgncGFyYW1zJyk7CgogICAgY29uc3QgcGFyYW1zID0ge307CiAgICBwYXJhbXMudG9rZW5DcmVhdGlvbkZlZSA9ICcwJzsKICAgIC8vIHBhcmFtcy51cGRhdGVTdGFraW5nUGFyYW1zRmVlID0gJzEwMCc7CiAgICAvLyBwYXJhbXMudXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSA9ICcxMDAnOwogICAgYXdhaXQgYXBpLmRiLmluc2VydCgncGFyYW1zJywgcGFyYW1zKTsKICB9IGVsc2UgewogICAgLyogY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKICAgIHBhcmFtcy51cGRhdGVTdGFraW5nUGFyYW1zRmVlID0gJzEwMCc7CiAgICBwYXJhbXMudXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSA9ICcxMDAnOwogICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncGFyYW1zJywgcGFyYW1zKTsgKi8KICB9CgogIHRhYmxlRXhpc3RzID0gYXdhaXQgYXBpLmRiLnRhYmxlRXhpc3RzKCdwZW5kaW5nVW5zdGFrZXMnKTsKICBpZiAodGFibGVFeGlzdHMgPT09IGZhbHNlKSB7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ3BlbmRpbmdVbnN0YWtlcycsIFsnYWNjb3VudCcsICd1bnN0YWtlQ29tcGxldGVUaW1lc3RhbXAnXSk7CiAgfQoKICB0YWJsZUV4aXN0cyA9IGF3YWl0IGFwaS5kYi50YWJsZUV4aXN0cygnZGVsZWdhdGlvbnMnKTsKICBpZiAodGFibGVFeGlzdHMgPT09IGZhbHNlKSB7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ2RlbGVnYXRpb25zJywgWydmcm9tJywgJ3RvJ10pOwogICAgYXdhaXQgYXBpLmRiLmNyZWF0ZVRhYmxlKCdwZW5kaW5nVW5kZWxlZ2F0aW9ucycsIFsnYWNjb3VudCcsICdjb21wbGV0ZVRpbWVzdGFtcCddKTsKICB9CgogIC8vIHVwZGF0ZSBTVEVFTVAgZGVjaW1hbCBwbGFjZXMKICBsZXQgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2w6ICdTVEVFTVAnIH0pOwoKICBpZiAodG9rZW4gJiYgdG9rZW4ucHJlY2lzaW9uIDwgOCkgewogICAgdG9rZW4ucHJlY2lzaW9uID0gODsKICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICB9CgogIC8vIGVuYWJsZSBzdGFraW5nIGFuZCBkZWxlZ2F0aW9uIGZvciBFTkcKICB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbDogIkVORyIgfSk7CgogIGlmICh0b2tlbi5zdGFraW5nRW5hYmxlZCA9PT0gdW5kZWZpbmVkIHx8IHRva2VuLnN0YWtpbmdFbmFibGVkID09PSBmYWxzZSkgewogICAgdG9rZW4uc3Rha2luZ0VuYWJsZWQgPSB0cnVlOwogICAgdG9rZW4udG90YWxTdGFrZWQgPSAnMCc7CiAgICB0b2tlbi51bnN0YWtpbmdDb29sZG93biA9IDQwOwogICAgdG9rZW4ubnVtYmVyVHJhbnNhY3Rpb25zID0gNDsKICAgIHRva2VuLmRlbGVnYXRpb25FbmFibGVkID0gdHJ1ZTsKICAgIHRva2VuLnVuZGVsZWdhdGlvbkNvb2xkb3duID0gNzsKICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICB9Cn07CgphY3Rpb25zLnVwZGF0ZVBhcmFtcyA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgaWYgKGFwaS5zZW5kZXIgIT09IGFwaS5vd25lcikgcmV0dXJuOwoKICBjb25zdCB7IHRva2VuQ3JlYXRpb25GZWUgLyogLCB1cGRhdGVTdGFraW5nUGFyYW1zRmVlLCB1cGRhdGVEZWxlZ2F0aW9uUGFyYW1zRmVlICovIH0gPSBwYXlsb2FkOwoKICBjb25zdCBwYXJhbXMgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncGFyYW1zJywge30pOwoKICBwYXJhbXMudG9rZW5DcmVhdGlvbkZlZSA9IHRva2VuQ3JlYXRpb25GZWU7CiAgLy8gcGFyYW1zLnVwZGF0ZVN0YWtpbmdQYXJhbXNGZWUgPSB1cGRhdGVTdGFraW5nUGFyYW1zRmVlOwogIC8vIHBhcmFtcy51cGRhdGVEZWxlZ2F0aW9uUGFyYW1zRmVlID0gdXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZTsKCiAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncGFyYW1zJywgcGFyYW1zKTsKfTsKCmFjdGlvbnMudXBkYXRlVXJsID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7IHVybCwgc3ltYm9sIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICYmIHVybCAmJiB0eXBlb2YgdXJsID09PSAnc3RyaW5nJywgJ2ludmFsaWQgcGFyYW1zJykKICAgICYmIGFwaS5hc3NlcnQodXJsLmxlbmd0aCA8PSAyNTUsICdpbnZhbGlkIHVybDogbWF4IGxlbmd0aCBvZiAyNTUnKSkgewogICAgLy8gY2hlY2sgaWYgdGhlIHRva2VuIGV4aXN0cwogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgaWYgKHRva2VuKSB7CiAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGNvbnN0IG1ldGFkYXRhID0gSlNPTi5wYXJzZSh0b2tlbi5tZXRhZGF0YSk7CgogICAgICAgICAgaWYgKGFwaS5hc3NlcnQobWV0YWRhdGEgJiYgbWV0YWRhdGEudXJsLCAnYW4gZXJyb3Igb2NjdXJlZCB3aGVuIHRyeWluZyB0byB1cGRhdGUgdGhlIHVybCcpKSB7CiAgICAgICAgICAgIG1ldGFkYXRhLnVybCA9IHVybDsKICAgICAgICAgICAgdG9rZW4ubWV0YWRhdGEgPSBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7CiAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAvLyBlcnJvciB3aGVuIHBhcnNpbmcgdGhlIG1ldGFkYXRhCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy51cGRhdGVNZXRhZGF0YSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgeyBtZXRhZGF0YSwgc3ltYm9sIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICYmIG1ldGFkYXRhICYmIHR5cGVvZiBtZXRhZGF0YSA9PT0gJ29iamVjdCcsICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICAvLyBjaGVjayBpZiB0aGUgdG9rZW4gZXhpc3RzCiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBpZiAodG9rZW4pIHsKICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbXVzdCBiZSB0aGUgaXNzdWVyJykpIHsKICAgICAgICB0cnkgewogICAgICAgICAgY29uc3QgZmluYWxNZXRhZGF0YSA9IEpTT04uc3RyaW5naWZ5KG1ldGFkYXRhKTsKCiAgICAgICAgICBpZiAoYXBpLmFzc2VydChmaW5hbE1ldGFkYXRhLmxlbmd0aCA8PSAxMDAwLCAnaW52YWxpZCBtZXRhZGF0YTogbWF4IGxlbmd0aCBvZiAxMDAwJykpIHsKICAgICAgICAgICAgdG9rZW4ubWV0YWRhdGEgPSBmaW5hbE1ldGFkYXRhOwogICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgLy8gZXJyb3Igd2hlbiBzdHJpbmdpZnlpbmcgdGhlIG1ldGFkYXRhCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy51cGRhdGVQcmVjaXNpb24gPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsgc3ltYm9sLCBwcmVjaXNpb24sIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnKQogICAgJiYgYXBpLmFzc2VydCgocHJlY2lzaW9uID4gMCAmJiBwcmVjaXNpb24gPD0gOCkgJiYgKE51bWJlci5pc0ludGVnZXIocHJlY2lzaW9uKSksICdpbnZhbGlkIHByZWNpc2lvbicpKSB7CiAgICAvLyBjaGVjayBpZiB0aGUgdG9rZW4gZXhpc3RzCiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBpZiAodG9rZW4pIHsKICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbXVzdCBiZSB0aGUgaXNzdWVyJykKICAgICAgICAmJiBhcGkuYXNzZXJ0KHByZWNpc2lvbiA+IHRva2VuLnByZWNpc2lvbiwgJ3ByZWNpc2lvbiBjYW4gb25seSBiZSBpbmNyZWFzZWQnKSkgewogICAgICAgIHRva2VuLnByZWNpc2lvbiA9IHByZWNpc2lvbjsKICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICAgIH0KICAgIH0KICB9Cn07CgphY3Rpb25zLnRyYW5zZmVyT3duZXJzaGlwID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7IHN5bWJvbCwgdG8sIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAgICYmIHRvICYmIHR5cGVvZiB0byA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICAvLyBjaGVjayBpZiB0aGUgdG9rZW4gZXhpc3RzCiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBpZiAodG9rZW4pIHsKICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbXVzdCBiZSB0aGUgaXNzdWVyJykpIHsKICAgICAgICBjb25zdCBmaW5hbFRvID0gdG8udHJpbSgpOwoKICAgICAgICAvLyBhIHZhbGlkIHN0ZWVtIGFjY291bnQgaXMgYmV0d2VlbiAzIGFuZCAxNiBjaGFyYWN0ZXJzIGluIGxlbmd0aAogICAgICAgIGlmIChhcGkuYXNzZXJ0KGZpbmFsVG8ubGVuZ3RoID49IDMgJiYgZmluYWxUby5sZW5ndGggPD0gMTYsICdpbnZhbGlkIHRvJykpIHsKICAgICAgICAgIHRva2VuLmlzc3VlciA9IGZpbmFsVG87CiAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy5jcmVhdGUgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIG5hbWUsIHN5bWJvbCwgdXJsLCBwcmVjaXNpb24sIG1heFN1cHBseSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICAvLyBnZXQgY29udHJhY3QgcGFyYW1zCiAgY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKICBjb25zdCB7IHRva2VuQ3JlYXRpb25GZWUgfSA9IHBhcmFtczsKCiAgLy8gZ2V0IGFwaS5zZW5kZXIncyBVVElMSVRZX1RPS0VOX1NZTUJPTCBiYWxhbmNlCiAgY29uc3QgdXRpbGl0eVRva2VuQmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgc3ltYm9sOiAiRU5HIiB9KTsKCiAgY29uc3QgYXV0aG9yaXplZENyZWF0aW9uID0gYXBpLkJpZ051bWJlcih0b2tlbkNyZWF0aW9uRmVlKS5sdGUoMCkKICAgID8gdHJ1ZQogICAgOiB1dGlsaXR5VG9rZW5CYWxhbmNlICYmIGFwaS5CaWdOdW1iZXIodXRpbGl0eVRva2VuQmFsYW5jZS5iYWxhbmNlKS5ndGUodG9rZW5DcmVhdGlvbkZlZSk7CgogIGlmIChhcGkuYXNzZXJ0KGF1dGhvcml6ZWRDcmVhdGlvbiwgJ3lvdSBtdXN0IGhhdmUgZW5vdWdoIHRva2VucyB0byBjb3ZlciB0aGUgY3JlYXRpb24gZmVlcycpCiAgICAgICYmIGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICAgJiYgYXBpLmFzc2VydChuYW1lICYmIHR5cGVvZiBuYW1lID09PSAnc3RyaW5nJwogICAgICAmJiBzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICAgJiYgKHVybCA9PT0gdW5kZWZpbmVkIHx8ICh1cmwgJiYgdHlwZW9mIHVybCA9PT0gJ3N0cmluZycpKQogICAgICAmJiAoKHByZWNpc2lvbiAmJiB0eXBlb2YgcHJlY2lzaW9uID09PSAnbnVtYmVyJykgfHwgcHJlY2lzaW9uID09PSAwKQogICAgICAmJiBtYXhTdXBwbHkgJiYgdHlwZW9mIG1heFN1cHBseSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIobWF4U3VwcGx5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgLy8gdGhlIHByZWNpc2lvbiBtdXN0IGJlIGJldHdlZW4gMCBhbmQgOCBhbmQgbXVzdCBiZSBhbiBpbnRlZ2VyCiAgICAvLyB0aGUgbWF4IHN1cHBseSBtdXN0IGJlIHBvc2l0aXZlCiAgICBpZiAoYXBpLmFzc2VydChhcGkudmFsaWRhdG9yLmlzQWxwaGEoc3ltYm9sKSAmJiBhcGkudmFsaWRhdG9yLmlzVXBwZXJjYXNlKHN5bWJvbCkgJiYgc3ltYm9sLmxlbmd0aCA+IDAgJiYgc3ltYm9sLmxlbmd0aCA8PSAxMCwgJ2ludmFsaWQgc3ltYm9sOiB1cHBlcmNhc2UgbGV0dGVycyBvbmx5LCBtYXggbGVuZ3RoIG9mIDEwJykKICAgICAgJiYgYXBpLmFzc2VydChhcGkudmFsaWRhdG9yLmlzQWxwaGFudW1lcmljKGFwaS52YWxpZGF0b3IuYmxhY2tsaXN0KG5hbWUsICcgJykpICYmIG5hbWUubGVuZ3RoID4gMCAmJiBuYW1lLmxlbmd0aCA8PSA1MCwgJ2ludmFsaWQgbmFtZTogbGV0dGVycywgbnVtYmVycywgd2hpdGVzcGFjZXMgb25seSwgbWF4IGxlbmd0aCBvZiA1MCcpCiAgICAgICYmIGFwaS5hc3NlcnQodXJsID09PSB1bmRlZmluZWQgfHwgdXJsLmxlbmd0aCA8PSAyNTUsICdpbnZhbGlkIHVybDogbWF4IGxlbmd0aCBvZiAyNTUnKQogICAgICAmJiBhcGkuYXNzZXJ0KChwcmVjaXNpb24gPj0gMCAmJiBwcmVjaXNpb24gPD0gOCkgJiYgKE51bWJlci5pc0ludGVnZXIocHJlY2lzaW9uKSksICdpbnZhbGlkIHByZWNpc2lvbicpCiAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihtYXhTdXBwbHkpLmd0KDApLCAnbWF4U3VwcGx5IG11c3QgYmUgcG9zaXRpdmUnKQogICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIobWF4U3VwcGx5KS5sdGUoTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpLCBgbWF4U3VwcGx5IG11c3QgYmUgbG93ZXIgdGhhbiAke051bWJlci5NQVhfU0FGRV9JTlRFR0VSfWApKSB7CiAgICAgIC8vIGNoZWNrIGlmIHRoZSB0b2tlbiBhbHJlYWR5IGV4aXN0cwogICAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuID09PSBudWxsLCAnc3ltYm9sIGFscmVhZHkgZXhpc3RzJykpIHsKICAgICAgICBjb25zdCBmaW5hbFVybCA9IHVybCA9PT0gdW5kZWZpbmVkID8gJycgOiB1cmw7CgogICAgICAgIGxldCBtZXRhZGF0YSA9IHsKICAgICAgICAgIHVybDogZmluYWxVcmwsCiAgICAgICAgfTsKCiAgICAgICAgbWV0YWRhdGEgPSBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7CiAgICAgICAgY29uc3QgbmV3VG9rZW4gPSB7CiAgICAgICAgICBpc3N1ZXI6IGFwaS5zZW5kZXIsCiAgICAgICAgICBzeW1ib2wsCiAgICAgICAgICBuYW1lLAogICAgICAgICAgbWV0YWRhdGEsCiAgICAgICAgICBwcmVjaXNpb24sCiAgICAgICAgICBtYXhTdXBwbHk6IGFwaS5CaWdOdW1iZXIobWF4U3VwcGx5KS50b0ZpeGVkKHByZWNpc2lvbiksCiAgICAgICAgICBzdXBwbHk6ICcwJywKICAgICAgICAgIGNpcmN1bGF0aW5nU3VwcGx5OiAnMCcsCiAgICAgICAgICBzdGFraW5nRW5hYmxlZDogZmFsc2UsCiAgICAgICAgICB1bnN0YWtpbmdDb29sZG93bjogMSwKICAgICAgICAgIGRlbGVnYXRpb25FbmFibGVkOiBmYWxzZSwKICAgICAgICAgIHVuZGVsZWdhdGlvbkNvb2xkb3duOiAwLAogICAgICAgIH07CgogICAgICAgIGF3YWl0IGFwaS5kYi5pbnNlcnQoJ3Rva2VucycsIG5ld1Rva2VuKTsKCiAgICAgICAgLy8gYnVybiB0aGUgdG9rZW4gY3JlYXRpb24gZmVlcwogICAgICAgIGlmIChhcGkuQmlnTnVtYmVyKHRva2VuQ3JlYXRpb25GZWUpLmd0KDApKSB7CiAgICAgICAgICBhd2FpdCBhY3Rpb25zLnRyYW5zZmVyKHsKICAgICAgICAgICAgdG86ICdudWxsJywgc3ltYm9sOiAiRU5HIiwgcXVhbnRpdHk6IHRva2VuQ3JlYXRpb25GZWUsIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMuaXNzdWUgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHRvLCBzeW1ib2wsIHF1YW50aXR5LCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHRvICYmIHR5cGVvZiB0byA9PT0gJ3N0cmluZycKICAgICAgJiYgc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICBjb25zdCBmaW5hbFRvID0gdG8udHJpbSgpOwogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAvLyB0aGUgYXBpLnNlbmRlciBtdXN0IGJlIHRoZSBpc3N1ZXIKICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbm90IGFsbG93ZWQgdG8gaXNzdWUgdG9rZW5zJykKICAgICAgJiYgYXBpLmFzc2VydChjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdzeW1ib2wgcHJlY2lzaW9uIG1pc21hdGNoJykKICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5ndCgwKSwgJ211c3QgaXNzdWUgcG9zaXRpdmUgcXVhbnRpdHknKQogICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIodG9rZW4ubWF4U3VwcGx5KS5taW51cyh0b2tlbi5zdXBwbHkpLmd0ZShxdWFudGl0eSksICdxdWFudGl0eSBleGNlZWRzIGF2YWlsYWJsZSBzdXBwbHknKSkgewoKICAgICAgLy8gYSB2YWxpZCBzdGVlbSBhY2NvdW50IGlzIGJldHdlZW4gMyBhbmQgMTYgY2hhcmFjdGVycyBpbiBsZW5ndGgKICAgICAgaWYgKGFwaS5hc3NlcnQoZmluYWxUby5sZW5ndGggPj0gMyAmJiBmaW5hbFRvLmxlbmd0aCA8PSAxNiwgJ2ludmFsaWQgdG8nKSkgewogICAgICAgIC8vIHdlIG1hZGUgYWxsIHRoZSByZXF1aXJlZCB2ZXJpZmljYXRpb24sIGxldCdzIG5vdyBpc3N1ZSB0aGUgdG9rZW5zCgogICAgICAgIGxldCByZXMgPSBhd2FpdCBhZGRCYWxhbmNlKHRva2VuLmlzc3VlciwgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKTsKCiAgICAgICAgaWYgKHJlcyA9PT0gdHJ1ZSAmJiBmaW5hbFRvICE9PSB0b2tlbi5pc3N1ZXIpIHsKICAgICAgICAgIGlmIChhd2FpdCBzdWJCYWxhbmNlKHRva2VuLmlzc3VlciwgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKSkgewogICAgICAgICAgICByZXMgPSBhd2FpdCBhZGRCYWxhbmNlKGZpbmFsVG8sIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJyk7CgogICAgICAgICAgICBpZiAocmVzID09PSBmYWxzZSkgewogICAgICAgICAgICAgIGF3YWl0IGFkZEJhbGFuY2UodG9rZW4uaXNzdWVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAocmVzID09PSB0cnVlKSB7CiAgICAgICAgICB0b2tlbi5zdXBwbHkgPSBjYWxjdWxhdGVCYWxhbmNlKHRva2VuLnN1cHBseSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSk7CgogICAgICAgICAgaWYgKGZpbmFsVG8gIT09ICdudWxsJykgewogICAgICAgICAgICB0b2tlbi5jaXJjdWxhdGluZ1N1cHBseSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgdG9rZW4uY2lyY3VsYXRpbmdTdXBwbHksIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICAgICAgICAgICk7CiAgICAgICAgICB9CgogICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwoKICAgICAgICAgIGFwaS5lbWl0KCd0cmFuc2ZlckZyb21Db250cmFjdCcsIHsKICAgICAgICAgICAgZnJvbTogJ3Rva2VucycsIHRvOiBmaW5hbFRvLCBzeW1ib2wsIHF1YW50aXR5LAogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy50cmFuc2ZlciA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgdG8sIHN5bWJvbCwgcXVhbnRpdHksIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQodG8gJiYgdHlwZW9mIHRvID09PSAnc3RyaW5nJwogICAgICAmJiBzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICAgJiYgcXVhbnRpdHkgJiYgdHlwZW9mIHF1YW50aXR5ID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihxdWFudGl0eSkuaXNOYU4oKSwgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIGNvbnN0IGZpbmFsVG8gPSB0by50cmltKCk7CiAgICBpZiAoYXBpLmFzc2VydChmaW5hbFRvICE9PSBhcGkuc2VuZGVyLCAnY2Fubm90IHRyYW5zZmVyIHRvIHNlbGYnKSkgewogICAgICAvLyBhIHZhbGlkIHN0ZWVtIGFjY291bnQgaXMgYmV0d2VlbiAzIGFuZCAxNiBjaGFyYWN0ZXJzIGluIGxlbmd0aAogICAgICBpZiAoYXBpLmFzc2VydChmaW5hbFRvLmxlbmd0aCA+PSAzICYmIGZpbmFsVG8ubGVuZ3RoIDw9IDE2LCAnaW52YWxpZCB0bycpKSB7CiAgICAgICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgICAgIC8vIHRoZSBzeW1ib2wgbXVzdCBleGlzdAogICAgICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAgICAgJiYgYXBpLmFzc2VydChjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdzeW1ib2wgcHJlY2lzaW9uIG1pc21hdGNoJykKICAgICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QoMCksICdtdXN0IHRyYW5zZmVyIHBvc2l0aXZlIHF1YW50aXR5JykpIHsKICAgICAgICAgIGlmIChhd2FpdCBzdWJCYWxhbmNlKGFwaS5zZW5kZXIsIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJykpIHsKICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgYWRkQmFsYW5jZShmaW5hbFRvLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpOwoKICAgICAgICAgICAgaWYgKHJlcyA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICBhd2FpdCBhZGRCYWxhbmNlKGFwaS5zZW5kZXIsIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJyk7CgogICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGZpbmFsVG8gPT09ICdudWxsJykgewogICAgICAgICAgICAgIHRva2VuLmNpcmN1bGF0aW5nU3VwcGx5ID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgICAgICAgIHRva2VuLmNpcmN1bGF0aW5nU3VwcGx5LCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICAgICAgICApOwogICAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYXBpLmVtaXQoJ3RyYW5zZmVyJywgewogICAgICAgICAgICAgIGZyb206IGFwaS5zZW5kZXIsIHRvOiBmaW5hbFRvLCBzeW1ib2wsIHF1YW50aXR5LAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIGZhbHNlOwp9OwoKYWN0aW9ucy50cmFuc2ZlclRvQ29udHJhY3QgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHRvLCBzeW1ib2wsIHF1YW50aXR5LCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHRvICYmIHR5cGVvZiB0byA9PT0gJ3N0cmluZycKICAgICAgJiYgc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICBjb25zdCBmaW5hbFRvID0gdG8udHJpbSgpOwogICAgaWYgKGFwaS5hc3NlcnQoZmluYWxUbyAhPT0gYXBpLnNlbmRlciwgJ2Nhbm5vdCB0cmFuc2ZlciB0byBzZWxmJykpIHsKICAgICAgLy8gYSB2YWxpZCBjb250cmFjdCBhY2NvdW50IGlzIGJldHdlZW4gMyBhbmQgNTAgY2hhcmFjdGVycyBpbiBsZW5ndGgKICAgICAgaWYgKGFwaS5hc3NlcnQoZmluYWxUby5sZW5ndGggPj0gMyAmJiBmaW5hbFRvLmxlbmd0aCA8PSA1MCwgJ2ludmFsaWQgdG8nKSkgewogICAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgICAgICAvLyB0aGUgc3ltYm9sIG11c3QgZXhpc3QKICAgICAgICAvLyB0aGVuIHdlIG5lZWQgdG8gY2hlY2sgdGhhdCB0aGUgcXVhbnRpdHkgaXMgY29ycmVjdAogICAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgICAgICYmIGFwaS5hc3NlcnQoY291bnREZWNpbWFscyhxdWFudGl0eSkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnc3ltYm9sIHByZWNpc2lvbiBtaXNtYXRjaCcpCiAgICAgICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmd0KDApLCAnbXVzdCB0cmFuc2ZlciBwb3NpdGl2ZSBxdWFudGl0eScpKSB7CiAgICAgICAgICBpZiAoYXdhaXQgc3ViQmFsYW5jZShhcGkuc2VuZGVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpKSB7CiAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFkZEJhbGFuY2UoZmluYWxUbywgdG9rZW4sIHF1YW50aXR5LCAnY29udHJhY3RzQmFsYW5jZXMnKTsKCiAgICAgICAgICAgIGlmIChyZXMgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgYXdhaXQgYWRkQmFsYW5jZShhcGkuc2VuZGVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGlmIChmaW5hbFRvID09PSAnbnVsbCcpIHsKICAgICAgICAgICAgICAgIHRva2VuLmNpcmN1bGF0aW5nU3VwcGx5ID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgICAgICAgICAgdG9rZW4uY2lyY3VsYXRpbmdTdXBwbHksIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIGFwaS5lbWl0KCd0cmFuc2ZlclRvQ29udHJhY3QnLCB7CiAgICAgICAgICAgICAgICBmcm9tOiBhcGkuc2VuZGVyLCB0bzogZmluYWxUbywgc3ltYm9sLCBxdWFudGl0eSwKICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMudHJhbnNmZXJGcm9tQ29udHJhY3QgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIC8vIHRoaXMgYWN0aW9uIGNhbiBvbmx5IGJlIGNhbGxlZCBieSB0aGUgJ251bGwnIGFjY291bnQgd2hpY2ggb25seSB0aGUgY29yZSBjb2RlIGNhbiB1c2UKICBpZiAoYXBpLmFzc2VydChhcGkuc2VuZGVyID09PSAnbnVsbCcsICdub3QgYXV0aG9yaXplZCcpKSB7CiAgICBjb25zdCB7CiAgICAgIGZyb20sIHRvLCBzeW1ib2wsIHF1YW50aXR5LCB0eXBlLCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgICB9ID0gcGF5bG9hZDsKICAgIGNvbnN0IHR5cGVzID0gWyd1c2VyJywgJ2NvbnRyYWN0J107CgogICAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICAgJiYgYXBpLmFzc2VydCh0byAmJiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnCiAgICAgICAgJiYgZnJvbSAmJiB0eXBlb2YgZnJvbSA9PT0gJ3N0cmluZycKICAgICAgICAmJiBzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICAgICAmJiB0eXBlICYmICh0eXBlcy5pbmNsdWRlcyh0eXBlKSkKICAgICAgICAmJiBxdWFudGl0eSAmJiB0eXBlb2YgcXVhbnRpdHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgICBjb25zdCBmaW5hbFRvID0gdG8udHJpbSgpOwogICAgICBjb25zdCB0YWJsZSA9IHR5cGUgPT09ICd1c2VyJyA/ICdiYWxhbmNlcycgOiAnY29udHJhY3RzQmFsYW5jZXMnOwoKICAgICAgaWYgKGFwaS5hc3NlcnQodHlwZSA9PT0gJ3VzZXInIHx8ICh0eXBlID09PSAnY29udHJhY3QnICYmIGZpbmFsVG8gIT09IGZyb20pLCAnY2Fubm90IHRyYW5zZmVyIHRvIHNlbGYnKSkgewogICAgICAgIC8vIHZhbGlkYXRlIHRoZSAidG8iCiAgICAgICAgY29uc3QgdG9WYWxpZCA9IHR5cGUgPT09ICd1c2VyJyA/IGZpbmFsVG8ubGVuZ3RoID49IDMgJiYgZmluYWxUby5sZW5ndGggPD0gMTYgOiBmaW5hbFRvLmxlbmd0aCA+PSAzICYmIGZpbmFsVG8ubGVuZ3RoIDw9IDUwOwoKICAgICAgICAvLyB0aGUgYWNjb3VudCBtdXN0IGV4aXN0CiAgICAgICAgaWYgKGFwaS5hc3NlcnQodG9WYWxpZCA9PT0gdHJ1ZSwgJ2ludmFsaWQgdG8nKSkgewogICAgICAgICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgICAgICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAgICAgICAvLyB0aGVuIHdlIG5lZWQgdG8gY2hlY2sgdGhhdCB0aGUgcXVhbnRpdHkgaXMgY29ycmVjdAogICAgICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAgICAgICAmJiBhcGkuYXNzZXJ0KGNvdW50RGVjaW1hbHMocXVhbnRpdHkpIDw9IHRva2VuLnByZWNpc2lvbiwgJ3N5bWJvbCBwcmVjaXNpb24gbWlzbWF0Y2gnKQogICAgICAgICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmd0KDApLCAnbXVzdCB0cmFuc2ZlciBwb3NpdGl2ZSBxdWFudGl0eScpKSB7CgogICAgICAgICAgICBpZiAoYXdhaXQgc3ViQmFsYW5jZShmcm9tLCB0b2tlbiwgcXVhbnRpdHksICdjb250cmFjdHNCYWxhbmNlcycpKSB7CiAgICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgYWRkQmFsYW5jZShmaW5hbFRvLCB0b2tlbiwgcXVhbnRpdHksIHRhYmxlKTsKCiAgICAgICAgICAgICAgaWYgKHJlcyA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIGF3YWl0IGFkZEJhbGFuY2UoZnJvbSwgdG9rZW4sIHF1YW50aXR5LCAnY29udHJhY3RzQmFsYW5jZXMnKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGZpbmFsVG8gPT09ICdudWxsJykgewogICAgICAgICAgICAgICAgICB0b2tlbi5jaXJjdWxhdGluZ1N1cHBseSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgICAgICAgdG9rZW4uY2lyY3VsYXRpbmdTdXBwbHksIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgYXBpLmVtaXQoJ3RyYW5zZmVyRnJvbUNvbnRyYWN0JywgewogICAgICAgICAgICAgICAgICBmcm9tLCB0bzogZmluYWxUbywgc3ltYm9sLCBxdWFudGl0eSwKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmNvbnN0IHByb2Nlc3NVbnN0YWtlID0gYXN5bmMgKHVuc3Rha2UpID0+IHsKICBjb25zdCB7CiAgICBhY2NvdW50LAogICAgc3ltYm9sLAogICAgcXVhbnRpdHksCiAgICBxdWFudGl0eUxlZnQsCiAgICBudW1iZXJUcmFuc2FjdGlvbnNMZWZ0LAogIH0gPSB1bnN0YWtlOwoKICBjb25zdCBuZXdVbnN0YWtlID0gdW5zdGFrZTsKCiAgY29uc3QgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudCwgc3ltYm9sIH0pOwogIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwogIGxldCB0b2tlbnNUb1JlbGVhc2UgPSAwOwoKICBpZiAoYXBpLmFzc2VydChiYWxhbmNlICE9PSBudWxsLCAnYmFsYW5jZSBkb2VzIG5vdCBleGlzdCcpKSB7CiAgICAvLyBpZiBsYXN0IHRyYW5zYWN0aW9uIHRvIHByb2Nlc3MKICAgIGlmIChudW1iZXJUcmFuc2FjdGlvbnNMZWZ0ID09PSAxKSB7CiAgICAgIHRva2Vuc1RvUmVsZWFzZSA9IHF1YW50aXR5TGVmdDsKICAgICAgYXdhaXQgYXBpLmRiLnJlbW92ZSgncGVuZGluZ1Vuc3Rha2VzJywgdW5zdGFrZSk7CiAgICB9IGVsc2UgewogICAgICB0b2tlbnNUb1JlbGVhc2UgPSBhcGkuQmlnTnVtYmVyKHF1YW50aXR5KQogICAgICAgIC5kaXZpZGVkQnkodG9rZW4ubnVtYmVyVHJhbnNhY3Rpb25zKQogICAgICAgIC50b0ZpeGVkKHRva2VuLnByZWNpc2lvbiwgYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKCiAgICAgIG5ld1Vuc3Rha2UucXVhbnRpdHlMZWZ0ID0gYXBpLkJpZ051bWJlcihuZXdVbnN0YWtlLnF1YW50aXR5TGVmdCkKICAgICAgICAubWludXModG9rZW5zVG9SZWxlYXNlKQogICAgICAgIC50b0ZpeGVkKHRva2VuLnByZWNpc2lvbik7CgogICAgICBuZXdVbnN0YWtlLm51bWJlclRyYW5zYWN0aW9uc0xlZnQgLT0gMTsKCiAgICAgIG5ld1Vuc3Rha2UubmV4dFRyYW5zYWN0aW9uVGltZXN0YW1wID0gYXBpLkJpZ051bWJlcihuZXdVbnN0YWtlLm5leHRUcmFuc2FjdGlvblRpbWVzdGFtcCkKICAgICAgICAucGx1cyhuZXdVbnN0YWtlLm1pbGxpc2VjUGVyUGVyaW9kKQogICAgICAgIC50b051bWJlcigpOwoKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncGVuZGluZ1Vuc3Rha2VzJywgbmV3VW5zdGFrZSk7CiAgICB9CgogICAgaWYgKGFwaS5CaWdOdW1iZXIodG9rZW5zVG9SZWxlYXNlKS5ndCgwKSkgewogICAgICBjb25zdCBvcmlnaW5hbEJhbGFuY2UgPSBiYWxhbmNlLmJhbGFuY2U7CiAgICAgIGNvbnN0IG9yaWdpbmFsUGVuZGluZ1N0YWtlID0gYmFsYW5jZS5wZW5kaW5nVW5zdGFrZTsKCiAgICAgIGJhbGFuY2UuYmFsYW5jZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgYmFsYW5jZS5iYWxhbmNlLCB0b2tlbnNUb1JlbGVhc2UsIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICAgKTsKICAgICAgYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSwgdG9rZW5zVG9SZWxlYXNlLCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICApOwoKICAgICAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlLnBlbmRpbmdVbnN0YWtlKS5sdChvcmlnaW5hbFBlbmRpbmdTdGFrZSkKICAgICAgICAmJiBhcGkuQmlnTnVtYmVyKGJhbGFuY2UuYmFsYW5jZSkuZ3Qob3JpZ2luYWxCYWxhbmNlKSwgJ2Nhbm5vdCBzdWJ0cmFjdCcpKSB7CiAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlKTsKCiAgICAgICAgdG9rZW4udG90YWxTdGFrZWQgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgdG9rZW4udG90YWxTdGFrZWQsIHRva2Vuc1RvUmVsZWFzZSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICApOwoKICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CgogICAgICAgIGFwaS5lbWl0KCd1bnN0YWtlJywgeyBhY2NvdW50LCBzeW1ib2wsIHF1YW50aXR5OiB0b2tlbnNUb1JlbGVhc2UgfSk7CiAgICAgIH0KICAgIH0KICB9Cn07CgphY3Rpb25zLmNoZWNrUGVuZGluZ1Vuc3Rha2VzID0gYXN5bmMgKCkgPT4gewogIGlmIChhcGkuYXNzZXJ0KGFwaS5zZW5kZXIgPT09ICdudWxsJywgJ25vdCBhdXRob3JpemVkJykpIHsKICAgIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5zdGVlbUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgICBjb25zdCB0aW1lc3RhbXAgPSBibG9ja0RhdGUuZ2V0VGltZSgpOwoKICAgIC8vIGdldCBhbGwgdGhlIHBlbmRpbmcgdW5zdGFrZXMgdGhhdCBhcmUgcmVhZHkgdG8gYmUgcmVsZWFzZWQKICAgIGxldCBwZW5kaW5nVW5zdGFrZXMgPSBhd2FpdCBhcGkuZGIuZmluZCgKICAgICAgJ3BlbmRpbmdVbnN0YWtlcycsCiAgICAgIHsKICAgICAgICBuZXh0VHJhbnNhY3Rpb25UaW1lc3RhbXA6IHsKICAgICAgICAgICRsdGU6IHRpbWVzdGFtcCwKICAgICAgICB9LAogICAgICB9KTsKCiAgICBsZXQgbmJQZW5kaW5nVW5zdGFrZXMgPSBwZW5kaW5nVW5zdGFrZXMubGVuZ3RoOwogICAgd2hpbGUgKG5iUGVuZGluZ1Vuc3Rha2VzID4gMCkgewogICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbmJQZW5kaW5nVW5zdGFrZXM7IGluZGV4ICs9IDEpIHsKICAgICAgICBjb25zdCBwZW5kaW5nVW5zdGFrZSA9IHBlbmRpbmdVbnN0YWtlc1tpbmRleF07CiAgICAgICAgYXdhaXQgcHJvY2Vzc1Vuc3Rha2UocGVuZGluZ1Vuc3Rha2UpOwogICAgICB9CgogICAgICBwZW5kaW5nVW5zdGFrZXMgPSBhd2FpdCBhcGkuZGIuZmluZCgKICAgICAgICAncGVuZGluZ1Vuc3Rha2VzJywKICAgICAgICB7CiAgICAgICAgICBuZXh0VHJhbnNhY3Rpb25UaW1lc3RhbXA6IHsKICAgICAgICAgICAgJGx0ZTogdGltZXN0YW1wLAogICAgICAgICAgfSwKICAgICAgICB9LAogICAgICApOwoKICAgICAgbmJQZW5kaW5nVW5zdGFrZXMgPSBwZW5kaW5nVW5zdGFrZXMubGVuZ3RoOwogICAgfQogIH0KfTsKCmFjdGlvbnMuZW5hYmxlU3Rha2luZyA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgc3ltYm9sLAogICAgdW5zdGFraW5nQ29vbGRvd24sCiAgICBudW1iZXJUcmFuc2FjdGlvbnMsCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJywgJ2ludmFsaWQgc3ltYm9sJykKICAgICYmIGFwaS5hc3NlcnQodW5zdGFraW5nQ29vbGRvd24gJiYgTnVtYmVyLmlzSW50ZWdlcih1bnN0YWtpbmdDb29sZG93bikgJiYgdW5zdGFraW5nQ29vbGRvd24gPiAwICYmIHVuc3Rha2luZ0Nvb2xkb3duIDw9IDM2NSwgJ3Vuc3Rha2luZ0Nvb2xkb3duIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDM2NScpCiAgICAmJiBhcGkuYXNzZXJ0KG51bWJlclRyYW5zYWN0aW9ucyAmJiBOdW1iZXIuaXNJbnRlZ2VyKG51bWJlclRyYW5zYWN0aW9ucykgJiYgbnVtYmVyVHJhbnNhY3Rpb25zID4gMCAmJiBudW1iZXJUcmFuc2FjdGlvbnMgPD0gMzY1LCAnbnVtYmVyVHJhbnNhY3Rpb25zIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDM2NScpKSB7CiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbXVzdCBiZSB0aGUgaXNzdWVyJykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5zdGFraW5nRW5hYmxlZCA9PT0gdW5kZWZpbmVkIHx8IHRva2VuLnN0YWtpbmdFbmFibGVkID09PSBmYWxzZSwgJ3N0YWtpbmcgYWxyZWFkeSBlbmFibGVkJykpIHsKICAgICAgdG9rZW4uc3Rha2luZ0VuYWJsZWQgPSB0cnVlOwogICAgICB0b2tlbi50b3RhbFN0YWtlZCA9ICcwJzsKICAgICAgdG9rZW4udW5zdGFraW5nQ29vbGRvd24gPSB1bnN0YWtpbmdDb29sZG93bjsKICAgICAgdG9rZW4ubnVtYmVyVHJhbnNhY3Rpb25zID0gbnVtYmVyVHJhbnNhY3Rpb25zOwogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICB9CiAgfQp9OwoKLyoKYWN0aW9ucy51cGRhdGVTdGFraW5nUGFyYW1zID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICB1bnN0YWtpbmdDb29sZG93biwKICAgIG51bWJlclRyYW5zYWN0aW9ucywKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgLy8gZ2V0IGNvbnRyYWN0IHBhcmFtcwogIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CiAgY29uc3QgeyB1cGRhdGVTdGFraW5nUGFyYW1zRmVlIH0gPSBwYXJhbXM7CgogIC8vIGdldCBhcGkuc2VuZGVyJ3MgVVRJTElUWV9UT0tFTl9TWU1CT0wgYmFsYW5jZQogIGNvbnN0IHV0aWxpdHlUb2tlbkJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQ6IGFwaS5zZW5kZXIsIHN5bWJvbDogIkVORyIgfSk7CgogIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIodXRpbGl0eVRva2VuQmFsYW5jZS5iYWxhbmNlKS5ndGUodXBkYXRlU3Rha2luZ1BhcmFtc0ZlZSksICd5b3UgbXVzdCBoYXZlIGVub3VnaCB0b2tlbnMgdG8gY292ZXIgdGhlIGZlZXMnKQogICAgJiYgYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHN5bWJvbCcpCiAgICAmJiBhcGkuYXNzZXJ0KHVuc3Rha2luZ0Nvb2xkb3duICYmIE51bWJlci5pc0ludGVnZXIodW5zdGFraW5nQ29vbGRvd24pICYmIHVuc3Rha2luZ0Nvb2xkb3duID4gMCAmJiB1bnN0YWtpbmdDb29sZG93biA8PSAzNjUsICd1bnN0YWtpbmdDb29sZG93biBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAzNjUnKQogICAgJiYgYXBpLmFzc2VydChudW1iZXJUcmFuc2FjdGlvbnMgJiYgTnVtYmVyLmlzSW50ZWdlcihudW1iZXJUcmFuc2FjdGlvbnMpICYmIG51bWJlclRyYW5zYWN0aW9ucyA+IDAgJiYgbnVtYmVyVHJhbnNhY3Rpb25zIDw9IDM2NSwgJ251bWJlclRyYW5zYWN0aW9ucyBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAzNjUnKSkgewogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uc3Rha2luZ0VuYWJsZWQgPT09IHRydWUsICdzdGFraW5nIG5vdCBlbmFibGVkJykpIHsKICAgICAgdG9rZW4udW5zdGFraW5nQ29vbGRvd24gPSB1bnN0YWtpbmdDb29sZG93bjsKICAgICAgdG9rZW4ubnVtYmVyVHJhbnNhY3Rpb25zID0gbnVtYmVyVHJhbnNhY3Rpb25zOwogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CgogICAgICAvLyBidXJuIHRoZSB0b2tlbiBjcmVhdGlvbiBmZWVzCiAgICAgIGlmIChhcGkuQmlnTnVtYmVyKHVwZGF0ZVN0YWtpbmdQYXJhbXNGZWUpLmd0KDApKSB7CiAgICAgICAgYXdhaXQgYWN0aW9ucy50cmFuc2Zlcih7CiAgICAgICAgICB0bzogJ251bGwnLCBzeW1ib2w6ICJFTkciLCBxdWFudGl0eTogdXBkYXRlU3Rha2luZ1BhcmFtc0ZlZSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogICAgICAgIH0pOwogICAgICB9CiAgICB9CiAgfQp9OwoqLwoKYWN0aW9ucy5zdGFrZSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgc3ltYm9sLAogICAgcXVhbnRpdHksCiAgICB0bywKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAmJiB0byAmJiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnCiAgICAmJiBxdWFudGl0eSAmJiB0eXBlb2YgcXVhbnRpdHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgLy8gYSB2YWxpZCBzdGVlbSBhY2NvdW50IGlzIGJldHdlZW4gMyBhbmQgMTYgY2hhcmFjdGVycyBpbiBsZW5ndGgKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgIGNvbnN0IGZpbmFsVG8gPSB0by50cmltKCk7CgogICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAvLyB0aGVuIHdlIG5lZWQgdG8gY2hlY2sgdGhhdCB0aGUgcXVhbnRpdHkgaXMgY29ycmVjdAogICAgaWYgKGFwaS5hc3NlcnQoZmluYWxUby5sZW5ndGggPj0gMyAmJiBmaW5hbFRvLmxlbmd0aCA8PSAxNiwgJ2ludmFsaWQgdG8nKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgJiYgYXBpLmFzc2VydChjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdzeW1ib2wgcHJlY2lzaW9uIG1pc21hdGNoJykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5zdGFraW5nRW5hYmxlZCA9PT0gdHJ1ZSwgJ3N0YWtpbmcgbm90IGVuYWJsZWQnKQogICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmd0KDApLCAnbXVzdCBzdGFrZSBwb3NpdGl2ZSBxdWFudGl0eScpKSB7CiAgICAgIGlmIChhd2FpdCBzdWJCYWxhbmNlKGFwaS5zZW5kZXIsIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJykpIHsKICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBhZGRTdGFrZShmaW5hbFRvLCB0b2tlbiwgcXVhbnRpdHkpOwoKICAgICAgICBpZiAocmVzID09PSBmYWxzZSkgewogICAgICAgICAgYXdhaXQgYWRkQmFsYW5jZShhcGkuc2VuZGVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhcGkuZW1pdCgnc3Rha2UnLCB7IGFjY291bnQ6IGZpbmFsVG8sIHN5bWJvbCwgcXVhbnRpdHkgfSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKY29uc3Qgc3RhcnRVbnN0YWtlID0gYXN5bmMgKGFjY291bnQsIHRva2VuLCBxdWFudGl0eSkgPT4gewogIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5zdGVlbUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgY29uc3QgY29vbGRvd25QZXJpb2RNaWxsaXNlYyA9IHRva2VuLnVuc3Rha2luZ0Nvb2xkb3duICogMjQgKiAzNjAwICogMTAwMDsKICBjb25zdCBtaWxsaXNlY1BlclBlcmlvZCA9IGFwaS5CaWdOdW1iZXIoY29vbGRvd25QZXJpb2RNaWxsaXNlYykKICAgIC5kaXZpZGVkQnkodG9rZW4ubnVtYmVyVHJhbnNhY3Rpb25zKQogICAgLmludGVnZXJWYWx1ZShhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOwoKICBjb25zdCBuZXh0VHJhbnNhY3Rpb25UaW1lc3RhbXAgPSBhcGkuQmlnTnVtYmVyKGJsb2NrRGF0ZS5nZXRUaW1lKCkpCiAgICAucGx1cyhtaWxsaXNlY1BlclBlcmlvZCkKICAgIC50b051bWJlcigpOwoKICBjb25zdCB1bnN0YWtlID0gewogICAgYWNjb3VudCwKICAgIHN5bWJvbDogdG9rZW4uc3ltYm9sLAogICAgcXVhbnRpdHksCiAgICBxdWFudGl0eUxlZnQ6IHF1YW50aXR5LAogICAgbmV4dFRyYW5zYWN0aW9uVGltZXN0YW1wLAogICAgbnVtYmVyVHJhbnNhY3Rpb25zTGVmdDogdG9rZW4ubnVtYmVyVHJhbnNhY3Rpb25zLAogICAgbWlsbGlzZWNQZXJQZXJpb2QsCiAgICB0eElEOiBhcGkudHJhbnNhY3Rpb25JZCwKICB9OwoKICBhd2FpdCBhcGkuZGIuaW5zZXJ0KCdwZW5kaW5nVW5zdGFrZXMnLCB1bnN0YWtlKTsKfTsKCmFjdGlvbnMudW5zdGFrZSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgeyBzeW1ib2wsIHF1YW50aXR5LCBpc1NpZ25lZFdpdGhBY3RpdmVLZXkgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgICAmJiBxdWFudGl0eSAmJiB0eXBlb2YgcXVhbnRpdHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewoKICAgIC8vIGEgdmFsaWQgc3RlZW0gYWNjb3VudCBpcyBiZXR3ZWVuIDMgYW5kIDE2IGNoYXJhY3RlcnMgaW4gbGVuZ3RoCiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICAvLyB0aGUgc3ltYm9sIG11c3QgZXhpc3QKICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uc3Rha2luZ0VuYWJsZWQgPT09IHRydWUsICdzdGFraW5nIG5vdCBlbmFibGVkJykKICAgICAgJiYgYXBpLmFzc2VydChjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdzeW1ib2wgcHJlY2lzaW9uIG1pc21hdGNoJykKICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5ndCgwKSwgJ211c3QgdW5zdGFrZSBwb3NpdGl2ZSBxdWFudGl0eScpKSB7CgogICAgICBpZiAoYXdhaXQgc3ViU3Rha2UoYXBpLnNlbmRlciwgdG9rZW4sIHF1YW50aXR5KSkgewogICAgICAgIGF3YWl0IHN0YXJ0VW5zdGFrZShhcGkuc2VuZGVyLCB0b2tlbiwgcXVhbnRpdHkpOwoKICAgICAgICBhcGkuZW1pdCgndW5zdGFrZVN0YXJ0JywgeyBhY2NvdW50OiBhcGkuc2VuZGVyLCBzeW1ib2wsIHF1YW50aXR5IH0pOwogICAgICB9CiAgICB9CiAgfQp9OwoKY29uc3QgcHJvY2Vzc0NhbmNlbFVuc3Rha2UgPSBhc3luYyAodW5zdGFrZSkgPT4gewogIGNvbnN0IHsKICAgIGFjY291bnQsCiAgICBzeW1ib2wsCiAgICBxdWFudGl0eUxlZnQsCiAgfSA9IHVuc3Rha2U7CgogIGNvbnN0IGJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQsIHN5bWJvbCB9KTsKICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgaWYgKGFwaS5hc3NlcnQoYmFsYW5jZSAhPT0gbnVsbCwgJ2JhbGFuY2UgZG9lcyBub3QgZXhpc3QnKQogICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UpLmd0ZShxdWFudGl0eUxlZnQpLCAnb3ZlcmRyYXduIHBlbmRpbmdVbnN0YWtlJykpIHsKICAgIGNvbnN0IG9yaWdpbmFsU3Rha2UgPSBiYWxhbmNlLnN0YWtlOwogICAgY29uc3Qgb3JpZ2luYWxQZW5kaW5nU3Rha2UgPSBiYWxhbmNlLnBlbmRpbmdVbnN0YWtlOwoKICAgIGJhbGFuY2Uuc3Rha2UgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICBiYWxhbmNlLnN0YWtlLCBxdWFudGl0eUxlZnQsIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICk7CiAgICBiYWxhbmNlLnBlbmRpbmdVbnN0YWtlID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSwgcXVhbnRpdHlMZWZ0LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgKTsKCiAgICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UpLmx0KG9yaWdpbmFsUGVuZGluZ1N0YWtlKQogICAgICAmJiBhcGkuQmlnTnVtYmVyKGJhbGFuY2Uuc3Rha2UpLmd0KG9yaWdpbmFsU3Rha2UpLCAnY2Fubm90IHN1YnRyYWN0JykpIHsKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlKTsKCiAgICAgIGFwaS5lbWl0KCd1bnN0YWtlJywgeyBhY2NvdW50LCBzeW1ib2wsIHF1YW50aXR5OiBxdWFudGl0eUxlZnQgfSk7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogIH0KCiAgcmV0dXJuIGZhbHNlOwp9OwoKYWN0aW9ucy5jYW5jZWxVbnN0YWtlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7IHR4SUQsIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICAgJiYgYXBpLmFzc2VydCh0eElEICYmIHR5cGVvZiB0eElEID09PSAnc3RyaW5nJywgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIC8vIGdldCB1bnN0YWtlCiAgICBjb25zdCB1bnN0YWtlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BlbmRpbmdVbnN0YWtlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgdHhJRCB9KTsKCiAgICBpZiAoYXBpLmFzc2VydCh1bnN0YWtlLCAndW5zdGFrZSBkb2VzIG5vdCBleGlzdCcpKSB7CiAgICAgIGlmIChhd2FpdCBwcm9jZXNzQ2FuY2VsVW5zdGFrZSh1bnN0YWtlKSkgewogICAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ3BlbmRpbmdVbnN0YWtlcycsIHVuc3Rha2UpOwogICAgICB9CiAgICB9CiAgfQp9OwoKY29uc3QgYmFsYW5jZVRlbXBsYXRlID0gewogIGFjY291bnQ6IG51bGwsCiAgc3ltYm9sOiBudWxsLAogIGJhbGFuY2U6ICcwJywKICBzdGFrZTogJzAnLAogIHBlbmRpbmdVbnN0YWtlOiAnMCcsCiAgZGVsZWdhdGlvbnNJbjogJzAnLAogIGRlbGVnYXRpb25zT3V0OiAnMCcsCiAgcGVuZGluZ1VuZGVsZWdhdGlvbnM6ICcwJywKfTsKCmNvbnN0IGFkZFN0YWtlID0gYXN5bmMgKGFjY291bnQsIHRva2VuLCBxdWFudGl0eSkgPT4gewogIGxldCBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50LCBzeW1ib2w6IHRva2VuLnN5bWJvbCB9KTsKCiAgaWYgKGJhbGFuY2UgPT09IG51bGwpIHsKICAgIGJhbGFuY2UgPSBiYWxhbmNlVGVtcGxhdGU7CiAgICBiYWxhbmNlLmFjY291bnQgPSBhY2NvdW50OwogICAgYmFsYW5jZS5zeW1ib2wgPSB0b2tlbi5zeW1ib2w7CgogICAgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5pbnNlcnQoJ2JhbGFuY2VzJywgYmFsYW5jZSk7CiAgfQoKICBpZiAoYmFsYW5jZS5zdGFrZSA9PT0gdW5kZWZpbmVkKSB7CiAgICBiYWxhbmNlLnN0YWtlID0gJzAnOwogICAgYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSA9ICcwJzsKICB9CgogIGNvbnN0IG9yaWdpbmFsU3Rha2UgPSBiYWxhbmNlLnN0YWtlOwoKICBiYWxhbmNlLnN0YWtlID0gY2FsY3VsYXRlQmFsYW5jZShiYWxhbmNlLnN0YWtlLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlKTsKICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2Uuc3Rha2UpLmd0KG9yaWdpbmFsU3Rha2UpLCAnY2Fubm90IGFkZCcpKSB7CiAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2UpOwoKICAgIGlmICh0b2tlbi50b3RhbFN0YWtlZCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIHRva2VuLnRvdGFsU3Rha2VkID0gJzAnOwogICAgfQoKICAgIHRva2VuLnRvdGFsU3Rha2VkID0gY2FsY3VsYXRlQmFsYW5jZSh0b2tlbi50b3RhbFN0YWtlZCwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSk7CiAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CgogICAgcmV0dXJuIHRydWU7CiAgfQoKICByZXR1cm4gZmFsc2U7Cn07Cgpjb25zdCBzdWJTdGFrZSA9IGFzeW5jIChhY2NvdW50LCB0b2tlbiwgcXVhbnRpdHkpID0+IHsKICBjb25zdCBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50LCBzeW1ib2w6IHRva2VuLnN5bWJvbCB9KTsKCiAgaWYgKGFwaS5hc3NlcnQoYmFsYW5jZSAhPT0gbnVsbCwgJ2JhbGFuY2UgZG9lcyBub3QgZXhpc3QnKQogICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2Uuc3Rha2UpLmd0ZShxdWFudGl0eSksICdvdmVyZHJhd24gc3Rha2UnKSkgewogICAgY29uc3Qgb3JpZ2luYWxTdGFrZSA9IGJhbGFuY2Uuc3Rha2U7CiAgICBjb25zdCBvcmlnaW5hbFBlbmRpbmdTdGFrZSA9IGJhbGFuY2UucGVuZGluZ1Vuc3Rha2U7CgogICAgYmFsYW5jZS5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoYmFsYW5jZS5zdGFrZSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgZmFsc2UpOwogICAgYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgIGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICApOwoKICAgIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5zdGFrZSkubHQob3JpZ2luYWxTdGFrZSkKICAgICAgJiYgYXBpLkJpZ051bWJlcihiYWxhbmNlLnBlbmRpbmdVbnN0YWtlKS5ndChvcmlnaW5hbFBlbmRpbmdTdGFrZSksICdjYW5ub3Qgc3VidHJhY3QnKSkgewogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2UpOwoKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQoKICByZXR1cm4gZmFsc2U7Cn07Cgpjb25zdCBzdWJCYWxhbmNlID0gYXN5bmMgKGFjY291bnQsIHRva2VuLCBxdWFudGl0eSwgdGFibGUpID0+IHsKICBjb25zdCBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUodGFibGUsIHsgYWNjb3VudCwgc3ltYm9sOiB0b2tlbi5zeW1ib2wgfSk7CgogIGlmIChhcGkuYXNzZXJ0KGJhbGFuY2UgIT09IG51bGwsICdiYWxhbmNlIGRvZXMgbm90IGV4aXN0JykKICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlLmJhbGFuY2UpLmd0ZShxdWFudGl0eSksICdvdmVyZHJhd24gYmFsYW5jZScpKSB7CiAgICBjb25zdCBvcmlnaW5hbEJhbGFuY2UgPSBiYWxhbmNlLmJhbGFuY2U7CgogICAgYmFsYW5jZS5iYWxhbmNlID0gY2FsY3VsYXRlQmFsYW5jZShiYWxhbmNlLmJhbGFuY2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlKTsKCiAgICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2UuYmFsYW5jZSkubHQob3JpZ2luYWxCYWxhbmNlKSwgJ2Nhbm5vdCBzdWJ0cmFjdCcpKSB7CiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUodGFibGUsIGJhbGFuY2UpOwoKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQoKICByZXR1cm4gZmFsc2U7Cn07Cgpjb25zdCBhZGRCYWxhbmNlID0gYXN5bmMgKGFjY291bnQsIHRva2VuLCBxdWFudGl0eSwgdGFibGUpID0+IHsKICBsZXQgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKHRhYmxlLCB7IGFjY291bnQsIHN5bWJvbDogdG9rZW4uc3ltYm9sIH0pOwogIGlmIChiYWxhbmNlID09PSBudWxsKSB7CiAgICBiYWxhbmNlID0gYmFsYW5jZVRlbXBsYXRlOwogICAgYmFsYW5jZS5hY2NvdW50ID0gYWNjb3VudDsKICAgIGJhbGFuY2Uuc3ltYm9sID0gdG9rZW4uc3ltYm9sOwogICAgYmFsYW5jZS5iYWxhbmNlID0gcXVhbnRpdHk7CgoKICAgIGF3YWl0IGFwaS5kYi5pbnNlcnQodGFibGUsIGJhbGFuY2UpOwoKICAgIHJldHVybiB0cnVlOwogIH0KCiAgY29uc3Qgb3JpZ2luYWxCYWxhbmNlID0gYmFsYW5jZS5iYWxhbmNlOwoKICBiYWxhbmNlLmJhbGFuY2UgPSBjYWxjdWxhdGVCYWxhbmNlKGJhbGFuY2UuYmFsYW5jZSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSk7CiAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlLmJhbGFuY2UpLmd0KG9yaWdpbmFsQmFsYW5jZSksICdjYW5ub3QgYWRkJykpIHsKICAgIGF3YWl0IGFwaS5kYi51cGRhdGUodGFibGUsIGJhbGFuY2UpOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICByZXR1cm4gZmFsc2U7Cn07Cgpjb25zdCBjYWxjdWxhdGVCYWxhbmNlID0gKGJhbGFuY2UsIHF1YW50aXR5LCBwcmVjaXNpb24sIGFkZCkgPT4gewogIHJldHVybiBhZGQKICAgID8gYXBpLkJpZ051bWJlcihiYWxhbmNlKS5wbHVzKHF1YW50aXR5KS50b0ZpeGVkKHByZWNpc2lvbikKICAgIDogYXBpLkJpZ051bWJlcihiYWxhbmNlKS5taW51cyhxdWFudGl0eSkudG9GaXhlZChwcmVjaXNpb24pOwp9OwoKY29uc3QgY291bnREZWNpbWFscyA9IHZhbHVlID0+IGFwaS5CaWdOdW1iZXIodmFsdWUpLmRwKCk7CgphY3Rpb25zLmVuYWJsZURlbGVnYXRpb24gPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHN5bWJvbCwKICAgIHVuZGVsZWdhdGlvbkNvb2xkb3duLAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHN5bWJvbCcpCiAgICAmJiBhcGkuYXNzZXJ0KHVuZGVsZWdhdGlvbkNvb2xkb3duICYmIE51bWJlci5pc0ludGVnZXIodW5kZWxlZ2F0aW9uQ29vbGRvd24pICYmIHVuZGVsZWdhdGlvbkNvb2xkb3duID4gMCAmJiB1bmRlbGVnYXRpb25Db29sZG93biA8PSAzNjUsICd1bmRlbGVnYXRpb25Db29sZG93biBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAzNjUnKSkgewogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uc3Rha2luZ0VuYWJsZWQgPT09IHRydWUsICdzdGFraW5nIG5vdCBlbmFibGVkJykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5kZWxlZ2F0aW9uRW5hYmxlZCA9PT0gdW5kZWZpbmVkIHx8IHRva2VuLmRlbGVnYXRpb25FbmFibGVkID09PSBmYWxzZSwgJ2RlbGVnYXRpb24gYWxyZWFkeSBlbmFibGVkJykpIHsKICAgICAgdG9rZW4uZGVsZWdhdGlvbkVuYWJsZWQgPSB0cnVlOwogICAgICB0b2tlbi51bmRlbGVnYXRpb25Db29sZG93biA9IHVuZGVsZWdhdGlvbkNvb2xkb3duOwogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICB9CiAgfQp9OwoKLyoKYWN0aW9ucy51cGRhdGVEZWxlZ2F0aW9uUGFyYW1zID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICB1bmRlbGVnYXRpb25Db29sZG93biwKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgLy8gZ2V0IGNvbnRyYWN0IHBhcmFtcwogIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CiAgY29uc3QgeyB1cGRhdGVEZWxlZ2F0aW9uUGFyYW1zRmVlIH0gPSBwYXJhbXM7CgogIC8vIGdldCBhcGkuc2VuZGVyJ3MgVVRJTElUWV9UT0tFTl9TWU1CT0wgYmFsYW5jZQogIGNvbnN0IHV0aWxpdHlUb2tlbkJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQ6IGFwaS5zZW5kZXIsIHN5bWJvbDogIkVORyIgfSk7CgogIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIodXRpbGl0eVRva2VuQmFsYW5jZS5iYWxhbmNlKS5ndGUodXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSksICd5b3UgbXVzdCBoYXZlIGVub3VnaCB0b2tlbnMgdG8gY292ZXIgdGhlIGZlZXMnKQogICAgJiYgYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHN5bWJvbCcpCiAgICAmJiBhcGkuYXNzZXJ0KHVuZGVsZWdhdGlvbkNvb2xkb3duICYmIE51bWJlci5pc0ludGVnZXIodW5kZWxlZ2F0aW9uQ29vbGRvd24pICYmIHVuZGVsZWdhdGlvbkNvb2xkb3duID4gMCAmJiB1bmRlbGVnYXRpb25Db29sZG93biA8PSAzNjUsICd1bmRlbGVnYXRpb25Db29sZG93biBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAzNjUnKSkgewogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uZGVsZWdhdGlvbkVuYWJsZWQgPT09IHRydWUsICdkZWxlZ2F0aW9uIG5vdCBlbmFibGVkJykpIHsKICAgICAgdG9rZW4udW5kZWxlZ2F0aW9uQ29vbGRvd24gPSB1bmRlbGVnYXRpb25Db29sZG93bjsKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwoKICAgICAgLy8gYnVybiB0aGUgdG9rZW4gY3JlYXRpb24gZmVlcwogICAgICBpZiAoYXBpLkJpZ051bWJlcih1cGRhdGVEZWxlZ2F0aW9uUGFyYW1zRmVlKS5ndCgwKSkgewogICAgICAgIGF3YWl0IGFjdGlvbnMudHJhbnNmZXIoewogICAgICAgICAgdG86ICdudWxsJywgc3ltYm9sOiAiRU5HIiwgcXVhbnRpdHk6IHVwZGF0ZURlbGVnYXRpb25QYXJhbXNGZWUsIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICAgICAgICB9KTsKICAgICAgfQogICAgfQogIH0KfTsKCiovCgphY3Rpb25zLmRlbGVnYXRlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICBxdWFudGl0eSwKICAgIHRvLAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICYmIHRvICYmIHR5cGVvZiB0byA9PT0gJ3N0cmluZycKICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICBjb25zdCBmaW5hbFRvID0gdG8udHJpbSgpOwogICAgLy8gYSB2YWxpZCBzdGVlbSBhY2NvdW50IGlzIGJldHdlZW4gMyBhbmQgMTYgY2hhcmFjdGVycyBpbiBsZW5ndGgKICAgIGlmIChhcGkuYXNzZXJ0KGZpbmFsVG8ubGVuZ3RoID49IDMgJiYgZmluYWxUby5sZW5ndGggPD0gMTYsICdpbnZhbGlkIHRvJykpIHsKICAgICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgICAvLyB0aGUgc3ltYm9sIG11c3QgZXhpc3QKICAgICAgLy8gdGhlbiB3ZSBuZWVkIHRvIGNoZWNrIHRoYXQgdGhlIHF1YW50aXR5IGlzIGNvcnJlY3QKICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAgICYmIGFwaS5hc3NlcnQoY291bnREZWNpbWFscyhxdWFudGl0eSkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnc3ltYm9sIHByZWNpc2lvbiBtaXNtYXRjaCcpCiAgICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5kZWxlZ2F0aW9uRW5hYmxlZCA9PT0gdHJ1ZSwgJ2RlbGVnYXRpb24gbm90IGVuYWJsZWQnKQogICAgICAgICYmIGFwaS5hc3NlcnQoZmluYWxUbyAhPT0gYXBpLnNlbmRlciwgJ2Nhbm5vdCBkZWxlZ2F0ZSB0byB5b3Vyc2VsZicpCiAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5ndCgwKSwgJ211c3QgZGVsZWdhdGUgcG9zaXRpdmUgcXVhbnRpdHknKSkgewogICAgICAgIGNvbnN0IGJhbGFuY2VGcm9tID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50OiBhcGkuc2VuZGVyLCBzeW1ib2wgfSk7CgogICAgICAgIGlmIChhcGkuYXNzZXJ0KGJhbGFuY2VGcm9tICE9PSBudWxsLCAnYmFsYW5jZUZyb20gZG9lcyBub3QgZXhpc3QnKQogICAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2VGcm9tLnN0YWtlKS5ndGUocXVhbnRpdHkpLCAnb3ZlcmRyYXduIHN0YWtlJykpIHsKICAgICAgICAgIGlmIChiYWxhbmNlRnJvbS5zdGFrZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbGQgYmFsYW5jZXMgd2l0aCBuZXcgcHJvcGVydGllcwogICAgICAgICAgICBiYWxhbmNlRnJvbS5zdGFrZSA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZUZyb20ucGVuZGluZ1Vuc3Rha2UgPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VGcm9tLmRlbGVnYXRpb25zSW4gPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VGcm9tLmRlbGVnYXRpb25zT3V0ID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5wZW5kaW5nVW5kZWxlZ2F0aW9ucyA9ICcwJzsKICAgICAgICAgIH0gZWxzZSBpZiAoYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNJbiA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbGQgYmFsYW5jZXMgd2l0aCBuZXcgcHJvcGVydGllcwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc0luID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc091dCA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZUZyb20ucGVuZGluZ1VuZGVsZWdhdGlvbnMgPSAnMCc7CiAgICAgICAgICAgIGlmIChiYWxhbmNlRnJvbS5kZWxlZ2F0ZWRTdGFrZSkgewogICAgICAgICAgICAgIGRlbGV0ZSBiYWxhbmNlRnJvbS5kZWxlZ2F0ZWRTdGFrZTsKICAgICAgICAgICAgICBkZWxldGUgYmFsYW5jZUZyb20ucmVjZWl2ZWRTdGFrZTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIGxldCBiYWxhbmNlVG8gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQ6IHRvLCBzeW1ib2wgfSk7CgogICAgICAgICAgaWYgKGJhbGFuY2VUbyA9PT0gbnVsbCkgewogICAgICAgICAgICBiYWxhbmNlVG8gPSBiYWxhbmNlVGVtcGxhdGU7CiAgICAgICAgICAgIGJhbGFuY2VUby5hY2NvdW50ID0gdG87CiAgICAgICAgICAgIGJhbGFuY2VUby5zeW1ib2wgPSBzeW1ib2w7CgogICAgICAgICAgICBiYWxhbmNlVG8gPSBhd2FpdCBhcGkuZGIuaW5zZXJ0KCdiYWxhbmNlcycsIGJhbGFuY2VUbyk7CiAgICAgICAgICB9IGVsc2UgaWYgKGJhbGFuY2VUby5zdGFrZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbGQgYmFsYW5jZXMgd2l0aCBuZXcgcHJvcGVydGllcwogICAgICAgICAgICBiYWxhbmNlVG8uc3Rha2UgPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VUby5wZW5kaW5nVW5zdGFrZSA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zSW4gPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc091dCA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZVRvLnBlbmRpbmdVbmRlbGVnYXRpb25zID0gJzAnOwogICAgICAgICAgfSBlbHNlIGlmIChiYWxhbmNlVG8uZGVsZWdhdGlvbnNJbiA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbGQgYmFsYW5jZXMgd2l0aCBuZXcgcHJvcGVydGllcwogICAgICAgICAgICBiYWxhbmNlVG8uZGVsZWdhdGlvbnNJbiA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zT3V0ID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlVG8ucGVuZGluZ1VuZGVsZWdhdGlvbnMgPSAnMCc7CgogICAgICAgICAgICBpZiAoYmFsYW5jZVRvLmRlbGVnYXRlZFN0YWtlKSB7CiAgICAgICAgICAgICAgZGVsZXRlIGJhbGFuY2VUby5kZWxlZ2F0ZWRTdGFrZTsKICAgICAgICAgICAgICBkZWxldGUgYmFsYW5jZVRvLnJlY2VpdmVkU3Rha2U7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICAvLyBsb29rIGZvciBhbiBleGlzdGluZyBkZWxlZ2F0aW9uCiAgICAgICAgICBsZXQgZGVsZWdhdGlvbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdkZWxlZ2F0aW9ucycsIHsgdG86IGZpbmFsVG8sIGZyb206IGFwaS5zZW5kZXIsIHN5bWJvbCB9KTsKCiAgICAgICAgICBpZiAoZGVsZWdhdGlvbiA9PSBudWxsKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlRnJvbQogICAgICAgICAgICBiYWxhbmNlRnJvbS5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgYmFsYW5jZUZyb20uc3Rha2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICApOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc091dCA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNPdXQsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2VGcm9tKTsKCiAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlVG8KICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zSW4gPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc0luLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlVG8pOwoKICAgICAgICAgICAgZGVsZWdhdGlvbiA9IHt9OwogICAgICAgICAgICBkZWxlZ2F0aW9uLmZyb20gPSBhcGkuc2VuZGVyOwogICAgICAgICAgICBkZWxlZ2F0aW9uLnRvID0gdG87CiAgICAgICAgICAgIGRlbGVnYXRpb24uc3ltYm9sID0gc3ltYm9sOwogICAgICAgICAgICBkZWxlZ2F0aW9uLnF1YW50aXR5ID0gcXVhbnRpdHk7CgogICAgICAgICAgICBhd2FpdCBhcGkuZGIuaW5zZXJ0KCdkZWxlZ2F0aW9ucycsIGRlbGVnYXRpb24pOwoKICAgICAgICAgICAgYXBpLmVtaXQoJ2RlbGVnYXRlJywgeyB0bywgc3ltYm9sLCBxdWFudGl0eSB9KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIGlmIGEgZGVsZWdhdGlvbiBhbHJlYWR5IGV4aXN0cywgaW5jcmVhc2UgaXQKCiAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlRnJvbQogICAgICAgICAgICBiYWxhbmNlRnJvbS5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgYmFsYW5jZUZyb20uc3Rha2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICApOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc091dCA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNPdXQsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2VGcm9tKTsKCiAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlVG8KICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zSW4gPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc0luLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlVG8pOwoKICAgICAgICAgICAgLy8gdXBkYXRlIGRlbGVnYXRpb24KICAgICAgICAgICAgZGVsZWdhdGlvbi5xdWFudGl0eSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgZGVsZWdhdGlvbi5xdWFudGl0eSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2RlbGVnYXRpb25zJywgZGVsZWdhdGlvbik7CiAgICAgICAgICAgIGFwaS5lbWl0KCdkZWxlZ2F0ZScsIHsgdG8sIHN5bWJvbCwgcXVhbnRpdHkgfSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy51bmRlbGVnYXRlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICBxdWFudGl0eSwKICAgIGZyb20sCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgJiYgZnJvbSAmJiB0eXBlb2YgZnJvbSA9PT0gJ3N0cmluZycKICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICBjb25zdCBmaW5hbEZyb20gPSBmcm9tLnRyaW0oKTsKICAgIC8vIGEgdmFsaWQgc3RlZW0gYWNjb3VudCBpcyBiZXR3ZWVuIDMgYW5kIDE2IGNoYXJhY3RlcnMgaW4gbGVuZ3RoCiAgICBpZiAoYXBpLmFzc2VydChmaW5hbEZyb20ubGVuZ3RoID49IDMgJiYgZmluYWxGcm9tLmxlbmd0aCA8PSAxNiwgJ2ludmFsaWQgZnJvbScpKSB7CiAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgICAmJiBhcGkuYXNzZXJ0KGNvdW50RGVjaW1hbHMocXVhbnRpdHkpIDw9IHRva2VuLnByZWNpc2lvbiwgJ3N5bWJvbCBwcmVjaXNpb24gbWlzbWF0Y2gnKQogICAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uZGVsZWdhdGlvbkVuYWJsZWQgPT09IHRydWUsICdkZWxlZ2F0aW9uIG5vdCBlbmFibGVkJykKICAgICAgICAmJiBhcGkuYXNzZXJ0KGZpbmFsRnJvbSAhPT0gYXBpLnNlbmRlciwgJ2Nhbm5vdCB1bmRlbGVnYXRlIGZyb20geW91cnNlbGYnKQogICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QoMCksICdtdXN0IHVuZGVsZWdhdGUgcG9zaXRpdmUgcXVhbnRpdHknKSkgewogICAgICAgIGNvbnN0IGJhbGFuY2VUbyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgc3ltYm9sIH0pOwoKICAgICAgICBpZiAoYXBpLmFzc2VydChiYWxhbmNlVG8gIT09IG51bGwsICdiYWxhbmNlVG8gZG9lcyBub3QgZXhpc3QnKQogICAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2VUby5kZWxlZ2F0aW9uc091dCkuZ3RlKHF1YW50aXR5KSwgJ292ZXJkcmF3biBkZWxlZ2F0aW9uJykpIHsKICAgICAgICAgIGNvbnN0IGJhbGFuY2VGcm9tID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50OiBmaW5hbEZyb20sIHN5bWJvbCB9KTsKCiAgICAgICAgICBpZiAoYXBpLmFzc2VydChiYWxhbmNlRnJvbSAhPT0gbnVsbCwgJ2JhbGFuY2VGcm9tIGRvZXMgbm90IGV4aXN0JykpIHsKICAgICAgICAgICAgLy8gbG9vayBmb3IgYW4gZXhpc3RpbmcgZGVsZWdhdGlvbgogICAgICAgICAgICBjb25zdCBkZWxlZ2F0aW9uID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2RlbGVnYXRpb25zJywgeyB0bzogZmluYWxGcm9tLCBmcm9tOiBhcGkuc2VuZGVyLCBzeW1ib2wgfSk7CgogICAgICAgICAgICBpZiAoYXBpLmFzc2VydChkZWxlZ2F0aW9uICE9PSBudWxsLCAnZGVsZWdhdGlvbiBkb2VzIG5vdCBleGlzdCcpCiAgICAgICAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGRlbGVnYXRpb24ucXVhbnRpdHkpLmd0ZShxdWFudGl0eSksICdvdmVyZHJhd24gZGVsZWdhdGlvbicpKSB7CiAgICAgICAgICAgICAgLy8gdXBkYXRlIGJhbGFuY2VUbwogICAgICAgICAgICAgIGJhbGFuY2VUby5wZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgICBiYWxhbmNlRnJvbS5wZW5kaW5nVW5kZWxlZ2F0aW9ucywgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICAgICAgICAgICApOwogICAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc091dCA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgICBiYWxhbmNlVG8uZGVsZWdhdGlvbnNPdXQsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2JhbGFuY2VzJywgYmFsYW5jZVRvKTsKCiAgICAgICAgICAgICAgLy8gdXBkYXRlIGJhbGFuY2VGcm9tCiAgICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNJbiA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc0luLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2VGcm9tKTsKCiAgICAgICAgICAgICAgLy8gdXBkYXRlIGRlbGVnYXRpb24KICAgICAgICAgICAgICBkZWxlZ2F0aW9uLnF1YW50aXR5ID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgICAgICAgIGRlbGVnYXRpb24ucXVhbnRpdHksIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgIGlmIChhcGkuQmlnTnVtYmVyKGRlbGVnYXRpb24ucXVhbnRpdHkpLmd0KDApKSB7CiAgICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdkZWxlZ2F0aW9ucycsIGRlbGVnYXRpb24pOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCdkZWxlZ2F0aW9ucycsIGRlbGVnYXRpb24pOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gYWRkIHBlbmRpbmcgdW5kZWxlZ2F0aW9uCiAgICAgICAgICAgICAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLnN0ZWVtQmxvY2tUaW1lc3RhbXB9LjAwMFpgKTsKICAgICAgICAgICAgICBjb25zdCBjb29sZG93blBlcmlvZE1pbGxpc2VjID0gdG9rZW4udW5kZWxlZ2F0aW9uQ29vbGRvd24gKiAyNCAqIDM2MDAgKiAxMDAwOwoKICAgICAgICAgICAgICBjb25zdCBjb21wbGV0ZVRpbWVzdGFtcCA9IGJsb2NrRGF0ZS5nZXRUaW1lKCkgKyBjb29sZG93blBlcmlvZE1pbGxpc2VjOwoKICAgICAgICAgICAgICBjb25zdCB1bmRlbGVnYXRpb24gPSB7CiAgICAgICAgICAgICAgICBhY2NvdW50OiBhcGkuc2VuZGVyLAogICAgICAgICAgICAgICAgc3ltYm9sOiB0b2tlbi5zeW1ib2wsCiAgICAgICAgICAgICAgICBxdWFudGl0eSwKICAgICAgICAgICAgICAgIGNvbXBsZXRlVGltZXN0YW1wLAogICAgICAgICAgICAgICAgdHhJRDogYXBpLnRyYW5zYWN0aW9uSWQsCiAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLmluc2VydCgncGVuZGluZ1VuZGVsZWdhdGlvbnMnLCB1bmRlbGVnYXRpb24pOwoKICAgICAgICAgICAgICBhcGkuZW1pdCgndW5kZWxlZ2F0ZVN0YXJ0JywgeyBmcm9tOiBmaW5hbEZyb20sIHN5bWJvbCwgcXVhbnRpdHkgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn07Cgpjb25zdCBwcm9jZXNzVW5kZWxlZ2F0aW9uID0gYXN5bmMgKHVuZGVsZWdhdGlvbikgPT4gewogIGNvbnN0IHsKICAgIGFjY291bnQsCiAgICBzeW1ib2wsCiAgICBxdWFudGl0eSwKICB9ID0gdW5kZWxlZ2F0aW9uOwoKICBjb25zdCBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50LCBzeW1ib2wgfSk7CiAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogIGlmIChhcGkuYXNzZXJ0KGJhbGFuY2UgIT09IG51bGwsICdiYWxhbmNlIGRvZXMgbm90IGV4aXN0JykpIHsKICAgIGNvbnN0IG9yaWdpbmFsU3Rha2UgPSBiYWxhbmNlLnN0YWtlOwogICAgY29uc3Qgb3JpZ2luYWxQZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IGJhbGFuY2UucGVuZGluZ1VuZGVsZWdhdGlvbnM7CgogICAgLy8gdXBkYXRlIHRoZSBiYWxhbmNlCiAgICBiYWxhbmNlLnN0YWtlID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgYmFsYW5jZS5zdGFrZSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICk7CiAgICBiYWxhbmNlLnBlbmRpbmdVbmRlbGVnYXRpb25zID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgYmFsYW5jZS5wZW5kaW5nVW5kZWxlZ2F0aW9ucywgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgZmFsc2UsCiAgICApOwoKICAgIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5wZW5kaW5nVW5kZWxlZ2F0aW9ucykubHQob3JpZ2luYWxQZW5kaW5nVW5kZWxlZ2F0aW9ucykKICAgICAgICAmJiBhcGkuQmlnTnVtYmVyKGJhbGFuY2Uuc3Rha2UpLmd0KG9yaWdpbmFsU3Rha2UpLCAnY2Fubm90IHN1YnRyYWN0JykpIHsKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlKTsKCiAgICAgIC8vIHJlbW92ZSBwZW5kaW5nVW5kZWxlZ2F0aW9uCiAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ3BlbmRpbmdVbmRlbGVnYXRpb25zJywgdW5kZWxlZ2F0aW9uKTsKCiAgICAgIGFwaS5lbWl0KCd1bmRlbGVnYXRlRG9uZScsIHsgYWNjb3VudCwgc3ltYm9sLCBxdWFudGl0eSB9KTsKICAgIH0KICB9Cn07CgphY3Rpb25zLmNoZWNrUGVuZGluZ1VuZGVsZWdhdGlvbnMgPSBhc3luYyAoKSA9PiB7CiAgaWYgKGFwaS5hc3NlcnQoYXBpLnNlbmRlciA9PT0gJ251bGwnLCAnbm90IGF1dGhvcml6ZWQnKSkgewogICAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLnN0ZWVtQmxvY2tUaW1lc3RhbXB9LjAwMFpgKTsKICAgIGNvbnN0IHRpbWVzdGFtcCA9IGJsb2NrRGF0ZS5nZXRUaW1lKCk7CgogICAgLy8gZ2V0IGFsbCB0aGUgcGVuZGluZyB1bnN0YWtlcyB0aGF0IGFyZSByZWFkeSB0byBiZSByZWxlYXNlZAogICAgbGV0IHBlbmRpbmdVbmRlbGVnYXRpb25zID0gYXdhaXQgYXBpLmRiLmZpbmQoCiAgICAgICdwZW5kaW5nVW5kZWxlZ2F0aW9ucycsCiAgICAgIHsKICAgICAgICBjb21wbGV0ZVRpbWVzdGFtcDogewogICAgICAgICAgJGx0ZTogdGltZXN0YW1wLAogICAgICAgIH0sCiAgICAgIH0sCiAgICApOwoKICAgIGxldCBuYlBlbmRpbmdVbmRlbGVnYXRpb25zID0gcGVuZGluZ1VuZGVsZWdhdGlvbnMubGVuZ3RoOwogICAgd2hpbGUgKG5iUGVuZGluZ1VuZGVsZWdhdGlvbnMgPiAwKSB7CiAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBuYlBlbmRpbmdVbmRlbGVnYXRpb25zOyBpbmRleCArPSAxKSB7CiAgICAgICAgY29uc3QgcGVuZGluZ1VuZGVsZWdhdGlvbiA9IHBlbmRpbmdVbmRlbGVnYXRpb25zW2luZGV4XTsKICAgICAgICBhd2FpdCBwcm9jZXNzVW5kZWxlZ2F0aW9uKHBlbmRpbmdVbmRlbGVnYXRpb24pOwogICAgICB9CgogICAgICBwZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IGF3YWl0IGFwaS5kYi5maW5kKAogICAgICAgICdwZW5kaW5nVW5kZWxlZ2F0aW9ucycsCiAgICAgICAgewogICAgICAgICAgY29tcGxldGVUaW1lc3RhbXA6IHsKICAgICAgICAgICAgJGx0ZTogdGltZXN0YW1wLAogICAgICAgICAgfSwKICAgICAgICB9LAogICAgICApOwoKICAgICAgbmJQZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IHBlbmRpbmdVbmRlbGVnYXRpb25zLmxlbmd0aDsKICAgIH0KICB9Cn07Cg=='; + finalTransaction.payload = JSON.stringify(transPayload); + } else if (refSteemBlockNumber === 34174249) { + const transPayload = JSON.parse(finalTransaction.payload); + transPayload.code = 'LyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCAqLwovKiBnbG9iYWwgYWN0aW9ucywgYXBpICovCgphY3Rpb25zLmNyZWF0ZVNTQyA9IGFzeW5jICgpID0+IHsKICBsZXQgdGFibGVFeGlzdHMgPSBhd2FpdCBhcGkuZGIudGFibGVFeGlzdHMoJ3Rva2VucycpOwogIGlmICh0YWJsZUV4aXN0cyA9PT0gZmFsc2UpIHsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgndG9rZW5zJywgWydzeW1ib2wnXSk7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ2JhbGFuY2VzJywgWydhY2NvdW50J10pOwogICAgYXdhaXQgYXBpLmRiLmNyZWF0ZVRhYmxlKCdjb250cmFjdHNCYWxhbmNlcycsIFsnYWNjb3VudCddKTsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgncGFyYW1zJyk7CgogICAgY29uc3QgcGFyYW1zID0ge307CiAgICBwYXJhbXMudG9rZW5DcmVhdGlvbkZlZSA9ICcwJzsKICAgIC8vIHBhcmFtcy51cGRhdGVTdGFraW5nUGFyYW1zRmVlID0gJzEwMCc7CiAgICAvLyBwYXJhbXMudXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSA9ICcxMDAnOwogICAgYXdhaXQgYXBpLmRiLmluc2VydCgncGFyYW1zJywgcGFyYW1zKTsKICB9IGVsc2UgewogICAgLyogY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKICAgIHBhcmFtcy51cGRhdGVTdGFraW5nUGFyYW1zRmVlID0gJzEwMCc7CiAgICBwYXJhbXMudXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSA9ICcxMDAnOwogICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncGFyYW1zJywgcGFyYW1zKTsgKi8KICB9CgogIHRhYmxlRXhpc3RzID0gYXdhaXQgYXBpLmRiLnRhYmxlRXhpc3RzKCdwZW5kaW5nVW5zdGFrZXMnKTsKICBpZiAodGFibGVFeGlzdHMgPT09IGZhbHNlKSB7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ3BlbmRpbmdVbnN0YWtlcycsIFsnYWNjb3VudCcsICd1bnN0YWtlQ29tcGxldGVUaW1lc3RhbXAnXSk7CiAgfQoKICB0YWJsZUV4aXN0cyA9IGF3YWl0IGFwaS5kYi50YWJsZUV4aXN0cygnZGVsZWdhdGlvbnMnKTsKICBpZiAodGFibGVFeGlzdHMgPT09IGZhbHNlKSB7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ2RlbGVnYXRpb25zJywgWydmcm9tJywgJ3RvJ10pOwogICAgYXdhaXQgYXBpLmRiLmNyZWF0ZVRhYmxlKCdwZW5kaW5nVW5kZWxlZ2F0aW9ucycsIFsnYWNjb3VudCcsICdjb21wbGV0ZVRpbWVzdGFtcCddKTsKICB9CgogIC8vIHVwZGF0ZSBTVEVFTVAgZGVjaW1hbCBwbGFjZXMKICBsZXQgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2w6ICdTVEVFTVAnIH0pOwoKICBpZiAodG9rZW4gJiYgdG9rZW4ucHJlY2lzaW9uIDwgOCkgewogICAgdG9rZW4ucHJlY2lzaW9uID0gODsKICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICB9CgogIC8vIGVuYWJsZSBzdGFraW5nIGFuZCBkZWxlZ2F0aW9uIGZvciBFTkcKICB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbDogIkVORyIgfSk7CgogIGlmICh0b2tlbi5zdGFraW5nRW5hYmxlZCA9PT0gdW5kZWZpbmVkIHx8IHRva2VuLnN0YWtpbmdFbmFibGVkID09PSBmYWxzZSkgewogICAgdG9rZW4uc3Rha2luZ0VuYWJsZWQgPSB0cnVlOwogICAgdG9rZW4udG90YWxTdGFrZWQgPSAnMCc7CiAgICB0b2tlbi51bnN0YWtpbmdDb29sZG93biA9IDQwOwogICAgdG9rZW4ubnVtYmVyVHJhbnNhY3Rpb25zID0gNDsKICAgIHRva2VuLmRlbGVnYXRpb25FbmFibGVkID0gdHJ1ZTsKICAgIHRva2VuLnVuZGVsZWdhdGlvbkNvb2xkb3duID0gNzsKICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICB9Cn07CgphY3Rpb25zLnVwZGF0ZVBhcmFtcyA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgaWYgKGFwaS5zZW5kZXIgIT09IGFwaS5vd25lcikgcmV0dXJuOwoKICBjb25zdCB7IHRva2VuQ3JlYXRpb25GZWUgLyogLCB1cGRhdGVTdGFraW5nUGFyYW1zRmVlLCB1cGRhdGVEZWxlZ2F0aW9uUGFyYW1zRmVlICovIH0gPSBwYXlsb2FkOwoKICBjb25zdCBwYXJhbXMgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncGFyYW1zJywge30pOwoKICBwYXJhbXMudG9rZW5DcmVhdGlvbkZlZSA9IHRva2VuQ3JlYXRpb25GZWU7CiAgLy8gcGFyYW1zLnVwZGF0ZVN0YWtpbmdQYXJhbXNGZWUgPSB1cGRhdGVTdGFraW5nUGFyYW1zRmVlOwogIC8vIHBhcmFtcy51cGRhdGVEZWxlZ2F0aW9uUGFyYW1zRmVlID0gdXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZTsKCiAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncGFyYW1zJywgcGFyYW1zKTsKfTsKCmFjdGlvbnMudXBkYXRlVXJsID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7IHVybCwgc3ltYm9sIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICYmIHVybCAmJiB0eXBlb2YgdXJsID09PSAnc3RyaW5nJywgJ2ludmFsaWQgcGFyYW1zJykKICAgICYmIGFwaS5hc3NlcnQodXJsLmxlbmd0aCA8PSAyNTUsICdpbnZhbGlkIHVybDogbWF4IGxlbmd0aCBvZiAyNTUnKSkgewogICAgLy8gY2hlY2sgaWYgdGhlIHRva2VuIGV4aXN0cwogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgaWYgKHRva2VuKSB7CiAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGNvbnN0IG1ldGFkYXRhID0gSlNPTi5wYXJzZSh0b2tlbi5tZXRhZGF0YSk7CgogICAgICAgICAgaWYgKGFwaS5hc3NlcnQobWV0YWRhdGEgJiYgbWV0YWRhdGEudXJsLCAnYW4gZXJyb3Igb2NjdXJlZCB3aGVuIHRyeWluZyB0byB1cGRhdGUgdGhlIHVybCcpKSB7CiAgICAgICAgICAgIG1ldGFkYXRhLnVybCA9IHVybDsKICAgICAgICAgICAgdG9rZW4ubWV0YWRhdGEgPSBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7CiAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAvLyBlcnJvciB3aGVuIHBhcnNpbmcgdGhlIG1ldGFkYXRhCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy51cGRhdGVNZXRhZGF0YSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgeyBtZXRhZGF0YSwgc3ltYm9sIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICYmIG1ldGFkYXRhICYmIHR5cGVvZiBtZXRhZGF0YSA9PT0gJ29iamVjdCcsICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICAvLyBjaGVjayBpZiB0aGUgdG9rZW4gZXhpc3RzCiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBpZiAodG9rZW4pIHsKICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbXVzdCBiZSB0aGUgaXNzdWVyJykpIHsKICAgICAgICB0cnkgewogICAgICAgICAgY29uc3QgZmluYWxNZXRhZGF0YSA9IEpTT04uc3RyaW5naWZ5KG1ldGFkYXRhKTsKCiAgICAgICAgICBpZiAoYXBpLmFzc2VydChmaW5hbE1ldGFkYXRhLmxlbmd0aCA8PSAxMDAwLCAnaW52YWxpZCBtZXRhZGF0YTogbWF4IGxlbmd0aCBvZiAxMDAwJykpIHsKICAgICAgICAgICAgdG9rZW4ubWV0YWRhdGEgPSBmaW5hbE1ldGFkYXRhOwogICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgLy8gZXJyb3Igd2hlbiBzdHJpbmdpZnlpbmcgdGhlIG1ldGFkYXRhCiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy51cGRhdGVQcmVjaXNpb24gPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsgc3ltYm9sLCBwcmVjaXNpb24sIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnKQogICAgJiYgYXBpLmFzc2VydCgocHJlY2lzaW9uID4gMCAmJiBwcmVjaXNpb24gPD0gOCkgJiYgKE51bWJlci5pc0ludGVnZXIocHJlY2lzaW9uKSksICdpbnZhbGlkIHByZWNpc2lvbicpKSB7CiAgICAvLyBjaGVjayBpZiB0aGUgdG9rZW4gZXhpc3RzCiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBpZiAodG9rZW4pIHsKICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbXVzdCBiZSB0aGUgaXNzdWVyJykKICAgICAgICAmJiBhcGkuYXNzZXJ0KHByZWNpc2lvbiA+IHRva2VuLnByZWNpc2lvbiwgJ3ByZWNpc2lvbiBjYW4gb25seSBiZSBpbmNyZWFzZWQnKSkgewogICAgICAgIHRva2VuLnByZWNpc2lvbiA9IHByZWNpc2lvbjsKICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICAgIH0KICAgIH0KICB9Cn07CgphY3Rpb25zLnRyYW5zZmVyT3duZXJzaGlwID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7IHN5bWJvbCwgdG8sIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAgICYmIHRvICYmIHR5cGVvZiB0byA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICAvLyBjaGVjayBpZiB0aGUgdG9rZW4gZXhpc3RzCiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBpZiAodG9rZW4pIHsKICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbXVzdCBiZSB0aGUgaXNzdWVyJykpIHsKICAgICAgICBjb25zdCBmaW5hbFRvID0gdG8udHJpbSgpOwoKICAgICAgICAvLyBhIHZhbGlkIHN0ZWVtIGFjY291bnQgaXMgYmV0d2VlbiAzIGFuZCAxNiBjaGFyYWN0ZXJzIGluIGxlbmd0aAogICAgICAgIGlmIChhcGkuYXNzZXJ0KGZpbmFsVG8ubGVuZ3RoID49IDMgJiYgZmluYWxUby5sZW5ndGggPD0gMTYsICdpbnZhbGlkIHRvJykpIHsKICAgICAgICAgIHRva2VuLmlzc3VlciA9IGZpbmFsVG87CiAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy5jcmVhdGUgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIG5hbWUsIHN5bWJvbCwgdXJsLCBwcmVjaXNpb24sIG1heFN1cHBseSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICAvLyBnZXQgY29udHJhY3QgcGFyYW1zCiAgY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKICBjb25zdCB7IHRva2VuQ3JlYXRpb25GZWUgfSA9IHBhcmFtczsKCiAgLy8gZ2V0IGFwaS5zZW5kZXIncyBVVElMSVRZX1RPS0VOX1NZTUJPTCBiYWxhbmNlCiAgY29uc3QgdXRpbGl0eVRva2VuQmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgc3ltYm9sOiAiRU5HIiB9KTsKCiAgY29uc3QgYXV0aG9yaXplZENyZWF0aW9uID0gYXBpLkJpZ051bWJlcih0b2tlbkNyZWF0aW9uRmVlKS5sdGUoMCkKICAgID8gdHJ1ZQogICAgOiB1dGlsaXR5VG9rZW5CYWxhbmNlICYmIGFwaS5CaWdOdW1iZXIodXRpbGl0eVRva2VuQmFsYW5jZS5iYWxhbmNlKS5ndGUodG9rZW5DcmVhdGlvbkZlZSk7CgogIGlmIChhcGkuYXNzZXJ0KGF1dGhvcml6ZWRDcmVhdGlvbiwgJ3lvdSBtdXN0IGhhdmUgZW5vdWdoIHRva2VucyB0byBjb3ZlciB0aGUgY3JlYXRpb24gZmVlcycpCiAgICAgICYmIGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICAgJiYgYXBpLmFzc2VydChuYW1lICYmIHR5cGVvZiBuYW1lID09PSAnc3RyaW5nJwogICAgICAmJiBzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICAgJiYgKHVybCA9PT0gdW5kZWZpbmVkIHx8ICh1cmwgJiYgdHlwZW9mIHVybCA9PT0gJ3N0cmluZycpKQogICAgICAmJiAoKHByZWNpc2lvbiAmJiB0eXBlb2YgcHJlY2lzaW9uID09PSAnbnVtYmVyJykgfHwgcHJlY2lzaW9uID09PSAwKQogICAgICAmJiBtYXhTdXBwbHkgJiYgdHlwZW9mIG1heFN1cHBseSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIobWF4U3VwcGx5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgLy8gdGhlIHByZWNpc2lvbiBtdXN0IGJlIGJldHdlZW4gMCBhbmQgOCBhbmQgbXVzdCBiZSBhbiBpbnRlZ2VyCiAgICAvLyB0aGUgbWF4IHN1cHBseSBtdXN0IGJlIHBvc2l0aXZlCiAgICBpZiAoYXBpLmFzc2VydChhcGkudmFsaWRhdG9yLmlzQWxwaGEoc3ltYm9sKSAmJiBhcGkudmFsaWRhdG9yLmlzVXBwZXJjYXNlKHN5bWJvbCkgJiYgc3ltYm9sLmxlbmd0aCA+IDAgJiYgc3ltYm9sLmxlbmd0aCA8PSAxMCwgJ2ludmFsaWQgc3ltYm9sOiB1cHBlcmNhc2UgbGV0dGVycyBvbmx5LCBtYXggbGVuZ3RoIG9mIDEwJykKICAgICAgJiYgYXBpLmFzc2VydChhcGkudmFsaWRhdG9yLmlzQWxwaGFudW1lcmljKGFwaS52YWxpZGF0b3IuYmxhY2tsaXN0KG5hbWUsICcgJykpICYmIG5hbWUubGVuZ3RoID4gMCAmJiBuYW1lLmxlbmd0aCA8PSA1MCwgJ2ludmFsaWQgbmFtZTogbGV0dGVycywgbnVtYmVycywgd2hpdGVzcGFjZXMgb25seSwgbWF4IGxlbmd0aCBvZiA1MCcpCiAgICAgICYmIGFwaS5hc3NlcnQodXJsID09PSB1bmRlZmluZWQgfHwgdXJsLmxlbmd0aCA8PSAyNTUsICdpbnZhbGlkIHVybDogbWF4IGxlbmd0aCBvZiAyNTUnKQogICAgICAmJiBhcGkuYXNzZXJ0KChwcmVjaXNpb24gPj0gMCAmJiBwcmVjaXNpb24gPD0gOCkgJiYgKE51bWJlci5pc0ludGVnZXIocHJlY2lzaW9uKSksICdpbnZhbGlkIHByZWNpc2lvbicpCiAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihtYXhTdXBwbHkpLmd0KDApLCAnbWF4U3VwcGx5IG11c3QgYmUgcG9zaXRpdmUnKQogICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIobWF4U3VwcGx5KS5sdGUoTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpLCBgbWF4U3VwcGx5IG11c3QgYmUgbG93ZXIgdGhhbiAke051bWJlci5NQVhfU0FGRV9JTlRFR0VSfWApKSB7CiAgICAgIC8vIGNoZWNrIGlmIHRoZSB0b2tlbiBhbHJlYWR5IGV4aXN0cwogICAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuID09PSBudWxsLCAnc3ltYm9sIGFscmVhZHkgZXhpc3RzJykpIHsKICAgICAgICBjb25zdCBmaW5hbFVybCA9IHVybCA9PT0gdW5kZWZpbmVkID8gJycgOiB1cmw7CgogICAgICAgIGxldCBtZXRhZGF0YSA9IHsKICAgICAgICAgIHVybDogZmluYWxVcmwsCiAgICAgICAgfTsKCiAgICAgICAgbWV0YWRhdGEgPSBKU09OLnN0cmluZ2lmeShtZXRhZGF0YSk7CiAgICAgICAgY29uc3QgbmV3VG9rZW4gPSB7CiAgICAgICAgICBpc3N1ZXI6IGFwaS5zZW5kZXIsCiAgICAgICAgICBzeW1ib2wsCiAgICAgICAgICBuYW1lLAogICAgICAgICAgbWV0YWRhdGEsCiAgICAgICAgICBwcmVjaXNpb24sCiAgICAgICAgICBtYXhTdXBwbHk6IGFwaS5CaWdOdW1iZXIobWF4U3VwcGx5KS50b0ZpeGVkKHByZWNpc2lvbiksCiAgICAgICAgICBzdXBwbHk6ICcwJywKICAgICAgICAgIGNpcmN1bGF0aW5nU3VwcGx5OiAnMCcsCiAgICAgICAgICBzdGFraW5nRW5hYmxlZDogZmFsc2UsCiAgICAgICAgICB1bnN0YWtpbmdDb29sZG93bjogMSwKICAgICAgICAgIGRlbGVnYXRpb25FbmFibGVkOiBmYWxzZSwKICAgICAgICAgIHVuZGVsZWdhdGlvbkNvb2xkb3duOiAwLAogICAgICAgIH07CgogICAgICAgIGF3YWl0IGFwaS5kYi5pbnNlcnQoJ3Rva2VucycsIG5ld1Rva2VuKTsKCiAgICAgICAgLy8gYnVybiB0aGUgdG9rZW4gY3JlYXRpb24gZmVlcwogICAgICAgIGlmIChhcGkuQmlnTnVtYmVyKHRva2VuQ3JlYXRpb25GZWUpLmd0KDApKSB7CiAgICAgICAgICBhd2FpdCBhY3Rpb25zLnRyYW5zZmVyKHsKICAgICAgICAgICAgdG86ICdudWxsJywgc3ltYm9sOiAiRU5HIiwgcXVhbnRpdHk6IHRva2VuQ3JlYXRpb25GZWUsIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMuaXNzdWUgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHRvLCBzeW1ib2wsIHF1YW50aXR5LCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHRvICYmIHR5cGVvZiB0byA9PT0gJ3N0cmluZycKICAgICAgJiYgc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICBjb25zdCBmaW5hbFRvID0gdG8udHJpbSgpOwogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAvLyB0aGUgYXBpLnNlbmRlciBtdXN0IGJlIHRoZSBpc3N1ZXIKICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbm90IGFsbG93ZWQgdG8gaXNzdWUgdG9rZW5zJykKICAgICAgJiYgYXBpLmFzc2VydChjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdzeW1ib2wgcHJlY2lzaW9uIG1pc21hdGNoJykKICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5ndCgwKSwgJ211c3QgaXNzdWUgcG9zaXRpdmUgcXVhbnRpdHknKQogICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIodG9rZW4ubWF4U3VwcGx5KS5taW51cyh0b2tlbi5zdXBwbHkpLmd0ZShxdWFudGl0eSksICdxdWFudGl0eSBleGNlZWRzIGF2YWlsYWJsZSBzdXBwbHknKSkgewoKICAgICAgLy8gYSB2YWxpZCBzdGVlbSBhY2NvdW50IGlzIGJldHdlZW4gMyBhbmQgMTYgY2hhcmFjdGVycyBpbiBsZW5ndGgKICAgICAgaWYgKGFwaS5hc3NlcnQoZmluYWxUby5sZW5ndGggPj0gMyAmJiBmaW5hbFRvLmxlbmd0aCA8PSAxNiwgJ2ludmFsaWQgdG8nKSkgewogICAgICAgIC8vIHdlIG1hZGUgYWxsIHRoZSByZXF1aXJlZCB2ZXJpZmljYXRpb24sIGxldCdzIG5vdyBpc3N1ZSB0aGUgdG9rZW5zCgogICAgICAgIGxldCByZXMgPSBhd2FpdCBhZGRCYWxhbmNlKHRva2VuLmlzc3VlciwgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKTsKCiAgICAgICAgaWYgKHJlcyA9PT0gdHJ1ZSAmJiBmaW5hbFRvICE9PSB0b2tlbi5pc3N1ZXIpIHsKICAgICAgICAgIGlmIChhd2FpdCBzdWJCYWxhbmNlKHRva2VuLmlzc3VlciwgdG9rZW4sIHF1YW50aXR5LCAnYmFsYW5jZXMnKSkgewogICAgICAgICAgICByZXMgPSBhd2FpdCBhZGRCYWxhbmNlKGZpbmFsVG8sIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJyk7CgogICAgICAgICAgICBpZiAocmVzID09PSBmYWxzZSkgewogICAgICAgICAgICAgIGF3YWl0IGFkZEJhbGFuY2UodG9rZW4uaXNzdWVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAocmVzID09PSB0cnVlKSB7CiAgICAgICAgICB0b2tlbi5zdXBwbHkgPSBjYWxjdWxhdGVCYWxhbmNlKHRva2VuLnN1cHBseSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSk7CgogICAgICAgICAgaWYgKGZpbmFsVG8gIT09ICdudWxsJykgewogICAgICAgICAgICB0b2tlbi5jaXJjdWxhdGluZ1N1cHBseSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgdG9rZW4uY2lyY3VsYXRpbmdTdXBwbHksIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICAgICAgICAgICk7CiAgICAgICAgICB9CgogICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwoKICAgICAgICAgIGFwaS5lbWl0KCd0cmFuc2ZlckZyb21Db250cmFjdCcsIHsKICAgICAgICAgICAgZnJvbTogJ3Rva2VucycsIHRvOiBmaW5hbFRvLCBzeW1ib2wsIHF1YW50aXR5LAogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy50cmFuc2ZlciA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgdG8sIHN5bWJvbCwgcXVhbnRpdHksIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQodG8gJiYgdHlwZW9mIHRvID09PSAnc3RyaW5nJwogICAgICAmJiBzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICAgJiYgcXVhbnRpdHkgJiYgdHlwZW9mIHF1YW50aXR5ID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihxdWFudGl0eSkuaXNOYU4oKSwgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIGNvbnN0IGZpbmFsVG8gPSB0by50cmltKCk7CiAgICBpZiAoYXBpLmFzc2VydChmaW5hbFRvICE9PSBhcGkuc2VuZGVyLCAnY2Fubm90IHRyYW5zZmVyIHRvIHNlbGYnKSkgewogICAgICAvLyBhIHZhbGlkIHN0ZWVtIGFjY291bnQgaXMgYmV0d2VlbiAzIGFuZCAxNiBjaGFyYWN0ZXJzIGluIGxlbmd0aAogICAgICBpZiAoYXBpLmFzc2VydChmaW5hbFRvLmxlbmd0aCA+PSAzICYmIGZpbmFsVG8ubGVuZ3RoIDw9IDE2LCAnaW52YWxpZCB0bycpKSB7CiAgICAgICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgICAgIC8vIHRoZSBzeW1ib2wgbXVzdCBleGlzdAogICAgICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAgICAgJiYgYXBpLmFzc2VydChjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdzeW1ib2wgcHJlY2lzaW9uIG1pc21hdGNoJykKICAgICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QoMCksICdtdXN0IHRyYW5zZmVyIHBvc2l0aXZlIHF1YW50aXR5JykpIHsKICAgICAgICAgIGlmIChhd2FpdCBzdWJCYWxhbmNlKGFwaS5zZW5kZXIsIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJykpIHsKICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgYWRkQmFsYW5jZShmaW5hbFRvLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpOwoKICAgICAgICAgICAgaWYgKHJlcyA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICBhd2FpdCBhZGRCYWxhbmNlKGFwaS5zZW5kZXIsIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJyk7CgogICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGZpbmFsVG8gPT09ICdudWxsJykgewogICAgICAgICAgICAgIHRva2VuLmNpcmN1bGF0aW5nU3VwcGx5ID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgICAgICAgIHRva2VuLmNpcmN1bGF0aW5nU3VwcGx5LCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICAgICAgICApOwogICAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYXBpLmVtaXQoJ3RyYW5zZmVyJywgewogICAgICAgICAgICAgIGZyb206IGFwaS5zZW5kZXIsIHRvOiBmaW5hbFRvLCBzeW1ib2wsIHF1YW50aXR5LAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIGZhbHNlOwp9OwoKYWN0aW9ucy50cmFuc2ZlclRvQ29udHJhY3QgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHRvLCBzeW1ib2wsIHF1YW50aXR5LCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHRvICYmIHR5cGVvZiB0byA9PT0gJ3N0cmluZycKICAgICAgJiYgc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICBjb25zdCBmaW5hbFRvID0gdG8udHJpbSgpOwogICAgaWYgKGFwaS5hc3NlcnQoZmluYWxUbyAhPT0gYXBpLnNlbmRlciwgJ2Nhbm5vdCB0cmFuc2ZlciB0byBzZWxmJykpIHsKICAgICAgLy8gYSB2YWxpZCBjb250cmFjdCBhY2NvdW50IGlzIGJldHdlZW4gMyBhbmQgNTAgY2hhcmFjdGVycyBpbiBsZW5ndGgKICAgICAgaWYgKGFwaS5hc3NlcnQoZmluYWxUby5sZW5ndGggPj0gMyAmJiBmaW5hbFRvLmxlbmd0aCA8PSA1MCwgJ2ludmFsaWQgdG8nKSkgewogICAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgICAgICAvLyB0aGUgc3ltYm9sIG11c3QgZXhpc3QKICAgICAgICAvLyB0aGVuIHdlIG5lZWQgdG8gY2hlY2sgdGhhdCB0aGUgcXVhbnRpdHkgaXMgY29ycmVjdAogICAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgICAgICYmIGFwaS5hc3NlcnQoY291bnREZWNpbWFscyhxdWFudGl0eSkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnc3ltYm9sIHByZWNpc2lvbiBtaXNtYXRjaCcpCiAgICAgICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmd0KDApLCAnbXVzdCB0cmFuc2ZlciBwb3NpdGl2ZSBxdWFudGl0eScpKSB7CiAgICAgICAgICBpZiAoYXdhaXQgc3ViQmFsYW5jZShhcGkuc2VuZGVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpKSB7CiAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFkZEJhbGFuY2UoZmluYWxUbywgdG9rZW4sIHF1YW50aXR5LCAnY29udHJhY3RzQmFsYW5jZXMnKTsKCiAgICAgICAgICAgIGlmIChyZXMgPT09IGZhbHNlKSB7CiAgICAgICAgICAgICAgYXdhaXQgYWRkQmFsYW5jZShhcGkuc2VuZGVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGlmIChmaW5hbFRvID09PSAnbnVsbCcpIHsKICAgICAgICAgICAgICAgIHRva2VuLmNpcmN1bGF0aW5nU3VwcGx5ID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgICAgICAgICAgdG9rZW4uY2lyY3VsYXRpbmdTdXBwbHksIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Rva2VucycsIHRva2VuKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIGFwaS5lbWl0KCd0cmFuc2ZlclRvQ29udHJhY3QnLCB7CiAgICAgICAgICAgICAgICBmcm9tOiBhcGkuc2VuZGVyLCB0bzogZmluYWxUbywgc3ltYm9sLCBxdWFudGl0eSwKICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmFjdGlvbnMudHJhbnNmZXJGcm9tQ29udHJhY3QgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIC8vIHRoaXMgYWN0aW9uIGNhbiBvbmx5IGJlIGNhbGxlZCBieSB0aGUgJ251bGwnIGFjY291bnQgd2hpY2ggb25seSB0aGUgY29yZSBjb2RlIGNhbiB1c2UKICBpZiAoYXBpLmFzc2VydChhcGkuc2VuZGVyID09PSAnbnVsbCcsICdub3QgYXV0aG9yaXplZCcpKSB7CiAgICBjb25zdCB7CiAgICAgIGZyb20sIHRvLCBzeW1ib2wsIHF1YW50aXR5LCB0eXBlLCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgICB9ID0gcGF5bG9hZDsKICAgIGNvbnN0IHR5cGVzID0gWyd1c2VyJywgJ2NvbnRyYWN0J107CgogICAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICAgJiYgYXBpLmFzc2VydCh0byAmJiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnCiAgICAgICAgJiYgZnJvbSAmJiB0eXBlb2YgZnJvbSA9PT0gJ3N0cmluZycKICAgICAgICAmJiBzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICAgICAmJiB0eXBlICYmICh0eXBlcy5pbmNsdWRlcyh0eXBlKSkKICAgICAgICAmJiBxdWFudGl0eSAmJiB0eXBlb2YgcXVhbnRpdHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgICBjb25zdCBmaW5hbFRvID0gdG8udHJpbSgpOwogICAgICBjb25zdCB0YWJsZSA9IHR5cGUgPT09ICd1c2VyJyA/ICdiYWxhbmNlcycgOiAnY29udHJhY3RzQmFsYW5jZXMnOwoKICAgICAgaWYgKGFwaS5hc3NlcnQodHlwZSA9PT0gJ3VzZXInIHx8ICh0eXBlID09PSAnY29udHJhY3QnICYmIGZpbmFsVG8gIT09IGZyb20pLCAnY2Fubm90IHRyYW5zZmVyIHRvIHNlbGYnKSkgewogICAgICAgIC8vIHZhbGlkYXRlIHRoZSAidG8iCiAgICAgICAgY29uc3QgdG9WYWxpZCA9IHR5cGUgPT09ICd1c2VyJyA/IGZpbmFsVG8ubGVuZ3RoID49IDMgJiYgZmluYWxUby5sZW5ndGggPD0gMTYgOiBmaW5hbFRvLmxlbmd0aCA+PSAzICYmIGZpbmFsVG8ubGVuZ3RoIDw9IDUwOwoKICAgICAgICAvLyB0aGUgYWNjb3VudCBtdXN0IGV4aXN0CiAgICAgICAgaWYgKGFwaS5hc3NlcnQodG9WYWxpZCA9PT0gdHJ1ZSwgJ2ludmFsaWQgdG8nKSkgewogICAgICAgICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgICAgICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAgICAgICAvLyB0aGVuIHdlIG5lZWQgdG8gY2hlY2sgdGhhdCB0aGUgcXVhbnRpdHkgaXMgY29ycmVjdAogICAgICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAgICAgICAmJiBhcGkuYXNzZXJ0KGNvdW50RGVjaW1hbHMocXVhbnRpdHkpIDw9IHRva2VuLnByZWNpc2lvbiwgJ3N5bWJvbCBwcmVjaXNpb24gbWlzbWF0Y2gnKQogICAgICAgICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmd0KDApLCAnbXVzdCB0cmFuc2ZlciBwb3NpdGl2ZSBxdWFudGl0eScpKSB7CgogICAgICAgICAgICBpZiAoYXdhaXQgc3ViQmFsYW5jZShmcm9tLCB0b2tlbiwgcXVhbnRpdHksICdjb250cmFjdHNCYWxhbmNlcycpKSB7CiAgICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgYWRkQmFsYW5jZShmaW5hbFRvLCB0b2tlbiwgcXVhbnRpdHksIHRhYmxlKTsKCiAgICAgICAgICAgICAgaWYgKHJlcyA9PT0gZmFsc2UpIHsKICAgICAgICAgICAgICAgIGF3YWl0IGFkZEJhbGFuY2UoZnJvbSwgdG9rZW4sIHF1YW50aXR5LCAnY29udHJhY3RzQmFsYW5jZXMnKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKGZpbmFsVG8gPT09ICdudWxsJykgewogICAgICAgICAgICAgICAgICB0b2tlbi5jaXJjdWxhdGluZ1N1cHBseSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgICAgICAgdG9rZW4uY2lyY3VsYXRpbmdTdXBwbHksIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgYXBpLmVtaXQoJ3RyYW5zZmVyRnJvbUNvbnRyYWN0JywgewogICAgICAgICAgICAgICAgICBmcm9tLCB0bzogZmluYWxUbywgc3ltYm9sLCBxdWFudGl0eSwKICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KfTsKCmNvbnN0IHByb2Nlc3NVbnN0YWtlID0gYXN5bmMgKHVuc3Rha2UpID0+IHsKICBjb25zdCB7CiAgICBhY2NvdW50LAogICAgc3ltYm9sLAogICAgcXVhbnRpdHksCiAgICBxdWFudGl0eUxlZnQsCiAgICBudW1iZXJUcmFuc2FjdGlvbnNMZWZ0LAogIH0gPSB1bnN0YWtlOwoKICBjb25zdCBuZXdVbnN0YWtlID0gdW5zdGFrZTsKCiAgY29uc3QgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudCwgc3ltYm9sIH0pOwogIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwogIGxldCB0b2tlbnNUb1JlbGVhc2UgPSAwOwoKICBpZiAoYXBpLmFzc2VydChiYWxhbmNlICE9PSBudWxsLCAnYmFsYW5jZSBkb2VzIG5vdCBleGlzdCcpKSB7CiAgICAvLyBpZiBsYXN0IHRyYW5zYWN0aW9uIHRvIHByb2Nlc3MKICAgIGlmIChudW1iZXJUcmFuc2FjdGlvbnNMZWZ0ID09PSAxKSB7CiAgICAgIHRva2Vuc1RvUmVsZWFzZSA9IHF1YW50aXR5TGVmdDsKICAgICAgYXdhaXQgYXBpLmRiLnJlbW92ZSgncGVuZGluZ1Vuc3Rha2VzJywgdW5zdGFrZSk7CiAgICB9IGVsc2UgewogICAgICB0b2tlbnNUb1JlbGVhc2UgPSBhcGkuQmlnTnVtYmVyKHF1YW50aXR5KQogICAgICAgIC5kaXZpZGVkQnkodG9rZW4ubnVtYmVyVHJhbnNhY3Rpb25zKQogICAgICAgIC50b0ZpeGVkKHRva2VuLnByZWNpc2lvbiwgYXBpLkJpZ051bWJlci5ST1VORF9ET1dOKTsKCiAgICAgIG5ld1Vuc3Rha2UucXVhbnRpdHlMZWZ0ID0gYXBpLkJpZ051bWJlcihuZXdVbnN0YWtlLnF1YW50aXR5TGVmdCkKICAgICAgICAubWludXModG9rZW5zVG9SZWxlYXNlKQogICAgICAgIC50b0ZpeGVkKHRva2VuLnByZWNpc2lvbik7CgogICAgICBuZXdVbnN0YWtlLm51bWJlclRyYW5zYWN0aW9uc0xlZnQgLT0gMTsKCiAgICAgIG5ld1Vuc3Rha2UubmV4dFRyYW5zYWN0aW9uVGltZXN0YW1wID0gYXBpLkJpZ051bWJlcihuZXdVbnN0YWtlLm5leHRUcmFuc2FjdGlvblRpbWVzdGFtcCkKICAgICAgICAucGx1cyhuZXdVbnN0YWtlLm1pbGxpc2VjUGVyUGVyaW9kKQogICAgICAgIC50b051bWJlcigpOwoKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncGVuZGluZ1Vuc3Rha2VzJywgbmV3VW5zdGFrZSk7CiAgICB9CgogICAgaWYgKGFwaS5CaWdOdW1iZXIodG9rZW5zVG9SZWxlYXNlKS5ndCgwKSkgewogICAgICBjb25zdCBvcmlnaW5hbEJhbGFuY2UgPSBiYWxhbmNlLmJhbGFuY2U7CiAgICAgIGNvbnN0IG9yaWdpbmFsUGVuZGluZ1N0YWtlID0gYmFsYW5jZS5wZW5kaW5nVW5zdGFrZTsKCiAgICAgIGJhbGFuY2UuYmFsYW5jZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgYmFsYW5jZS5iYWxhbmNlLCB0b2tlbnNUb1JlbGVhc2UsIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICAgKTsKICAgICAgYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSwgdG9rZW5zVG9SZWxlYXNlLCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICApOwoKICAgICAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlLnBlbmRpbmdVbnN0YWtlKS5sdChvcmlnaW5hbFBlbmRpbmdTdGFrZSkKICAgICAgICAmJiBhcGkuQmlnTnVtYmVyKGJhbGFuY2UuYmFsYW5jZSkuZ3Qob3JpZ2luYWxCYWxhbmNlKSwgJ2Nhbm5vdCBzdWJ0cmFjdCcpKSB7CiAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlKTsKCiAgICAgICAgdG9rZW4udG90YWxTdGFrZWQgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgdG9rZW4udG90YWxTdGFrZWQsIHRva2Vuc1RvUmVsZWFzZSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICApOwoKICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CgogICAgICAgIGFwaS5lbWl0KCd1bnN0YWtlJywgeyBhY2NvdW50LCBzeW1ib2wsIHF1YW50aXR5OiB0b2tlbnNUb1JlbGVhc2UgfSk7CiAgICAgIH0KICAgIH0KICB9Cn07CgphY3Rpb25zLmNoZWNrUGVuZGluZ1Vuc3Rha2VzID0gYXN5bmMgKCkgPT4gewogIGlmIChhcGkuYXNzZXJ0KGFwaS5zZW5kZXIgPT09ICdudWxsJywgJ25vdCBhdXRob3JpemVkJykpIHsKICAgIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5zdGVlbUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgICBjb25zdCB0aW1lc3RhbXAgPSBibG9ja0RhdGUuZ2V0VGltZSgpOwoKICAgIC8vIGdldCBhbGwgdGhlIHBlbmRpbmcgdW5zdGFrZXMgdGhhdCBhcmUgcmVhZHkgdG8gYmUgcmVsZWFzZWQKICAgIGxldCBwZW5kaW5nVW5zdGFrZXMgPSBhd2FpdCBhcGkuZGIuZmluZCgKICAgICAgJ3BlbmRpbmdVbnN0YWtlcycsCiAgICAgIHsKICAgICAgICBuZXh0VHJhbnNhY3Rpb25UaW1lc3RhbXA6IHsKICAgICAgICAgICRsdGU6IHRpbWVzdGFtcCwKICAgICAgICB9LAogICAgICB9KTsKCiAgICBsZXQgbmJQZW5kaW5nVW5zdGFrZXMgPSBwZW5kaW5nVW5zdGFrZXMubGVuZ3RoOwogICAgd2hpbGUgKG5iUGVuZGluZ1Vuc3Rha2VzID4gMCkgewogICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbmJQZW5kaW5nVW5zdGFrZXM7IGluZGV4ICs9IDEpIHsKICAgICAgICBjb25zdCBwZW5kaW5nVW5zdGFrZSA9IHBlbmRpbmdVbnN0YWtlc1tpbmRleF07CiAgICAgICAgYXdhaXQgcHJvY2Vzc1Vuc3Rha2UocGVuZGluZ1Vuc3Rha2UpOwogICAgICB9CgogICAgICBwZW5kaW5nVW5zdGFrZXMgPSBhd2FpdCBhcGkuZGIuZmluZCgKICAgICAgICAncGVuZGluZ1Vuc3Rha2VzJywKICAgICAgICB7CiAgICAgICAgICBuZXh0VHJhbnNhY3Rpb25UaW1lc3RhbXA6IHsKICAgICAgICAgICAgJGx0ZTogdGltZXN0YW1wLAogICAgICAgICAgfSwKICAgICAgICB9LAogICAgICApOwoKICAgICAgbmJQZW5kaW5nVW5zdGFrZXMgPSBwZW5kaW5nVW5zdGFrZXMubGVuZ3RoOwogICAgfQogIH0KfTsKCmFjdGlvbnMuZW5hYmxlU3Rha2luZyA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgc3ltYm9sLAogICAgdW5zdGFraW5nQ29vbGRvd24sCiAgICBudW1iZXJUcmFuc2FjdGlvbnMsCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJywgJ2ludmFsaWQgc3ltYm9sJykKICAgICYmIGFwaS5hc3NlcnQodW5zdGFraW5nQ29vbGRvd24gJiYgTnVtYmVyLmlzSW50ZWdlcih1bnN0YWtpbmdDb29sZG93bikgJiYgdW5zdGFraW5nQ29vbGRvd24gPiAwICYmIHVuc3Rha2luZ0Nvb2xkb3duIDw9IDM2NSwgJ3Vuc3Rha2luZ0Nvb2xkb3duIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDM2NScpCiAgICAmJiBhcGkuYXNzZXJ0KG51bWJlclRyYW5zYWN0aW9ucyAmJiBOdW1iZXIuaXNJbnRlZ2VyKG51bWJlclRyYW5zYWN0aW9ucykgJiYgbnVtYmVyVHJhbnNhY3Rpb25zID4gMCAmJiBudW1iZXJUcmFuc2FjdGlvbnMgPD0gMzY1LCAnbnVtYmVyVHJhbnNhY3Rpb25zIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDM2NScpKSB7CiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uaXNzdWVyID09PSBhcGkuc2VuZGVyLCAnbXVzdCBiZSB0aGUgaXNzdWVyJykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5zdGFraW5nRW5hYmxlZCA9PT0gdW5kZWZpbmVkIHx8IHRva2VuLnN0YWtpbmdFbmFibGVkID09PSBmYWxzZSwgJ3N0YWtpbmcgYWxyZWFkeSBlbmFibGVkJykpIHsKICAgICAgdG9rZW4uc3Rha2luZ0VuYWJsZWQgPSB0cnVlOwogICAgICB0b2tlbi50b3RhbFN0YWtlZCA9ICcwJzsKICAgICAgdG9rZW4udW5zdGFraW5nQ29vbGRvd24gPSB1bnN0YWtpbmdDb29sZG93bjsKICAgICAgdG9rZW4ubnVtYmVyVHJhbnNhY3Rpb25zID0gbnVtYmVyVHJhbnNhY3Rpb25zOwogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICB9CiAgfQp9OwoKLyoKYWN0aW9ucy51cGRhdGVTdGFraW5nUGFyYW1zID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICB1bnN0YWtpbmdDb29sZG93biwKICAgIG51bWJlclRyYW5zYWN0aW9ucywKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgLy8gZ2V0IGNvbnRyYWN0IHBhcmFtcwogIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CiAgY29uc3QgeyB1cGRhdGVTdGFraW5nUGFyYW1zRmVlIH0gPSBwYXJhbXM7CgogIC8vIGdldCBhcGkuc2VuZGVyJ3MgVVRJTElUWV9UT0tFTl9TWU1CT0wgYmFsYW5jZQogIGNvbnN0IHV0aWxpdHlUb2tlbkJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQ6IGFwaS5zZW5kZXIsIHN5bWJvbDogIkVORyIgfSk7CgogIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIodXRpbGl0eVRva2VuQmFsYW5jZS5iYWxhbmNlKS5ndGUodXBkYXRlU3Rha2luZ1BhcmFtc0ZlZSksICd5b3UgbXVzdCBoYXZlIGVub3VnaCB0b2tlbnMgdG8gY292ZXIgdGhlIGZlZXMnKQogICAgJiYgYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHN5bWJvbCcpCiAgICAmJiBhcGkuYXNzZXJ0KHVuc3Rha2luZ0Nvb2xkb3duICYmIE51bWJlci5pc0ludGVnZXIodW5zdGFraW5nQ29vbGRvd24pICYmIHVuc3Rha2luZ0Nvb2xkb3duID4gMCAmJiB1bnN0YWtpbmdDb29sZG93biA8PSAzNjUsICd1bnN0YWtpbmdDb29sZG93biBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAzNjUnKQogICAgJiYgYXBpLmFzc2VydChudW1iZXJUcmFuc2FjdGlvbnMgJiYgTnVtYmVyLmlzSW50ZWdlcihudW1iZXJUcmFuc2FjdGlvbnMpICYmIG51bWJlclRyYW5zYWN0aW9ucyA+IDAgJiYgbnVtYmVyVHJhbnNhY3Rpb25zIDw9IDM2NSwgJ251bWJlclRyYW5zYWN0aW9ucyBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAzNjUnKSkgewogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uc3Rha2luZ0VuYWJsZWQgPT09IHRydWUsICdzdGFraW5nIG5vdCBlbmFibGVkJykpIHsKICAgICAgdG9rZW4udW5zdGFraW5nQ29vbGRvd24gPSB1bnN0YWtpbmdDb29sZG93bjsKICAgICAgdG9rZW4ubnVtYmVyVHJhbnNhY3Rpb25zID0gbnVtYmVyVHJhbnNhY3Rpb25zOwogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CgogICAgICAvLyBidXJuIHRoZSB0b2tlbiBjcmVhdGlvbiBmZWVzCiAgICAgIGlmIChhcGkuQmlnTnVtYmVyKHVwZGF0ZVN0YWtpbmdQYXJhbXNGZWUpLmd0KDApKSB7CiAgICAgICAgYXdhaXQgYWN0aW9ucy50cmFuc2Zlcih7CiAgICAgICAgICB0bzogJ251bGwnLCBzeW1ib2w6ICJFTkciLCBxdWFudGl0eTogdXBkYXRlU3Rha2luZ1BhcmFtc0ZlZSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogICAgICAgIH0pOwogICAgICB9CiAgICB9CiAgfQp9OwoqLwoKYWN0aW9ucy5zdGFrZSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgc3ltYm9sLAogICAgcXVhbnRpdHksCiAgICB0bywKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnCiAgICAmJiB0byAmJiB0eXBlb2YgdG8gPT09ICdzdHJpbmcnCiAgICAmJiBxdWFudGl0eSAmJiB0eXBlb2YgcXVhbnRpdHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgLy8gYSB2YWxpZCBzdGVlbSBhY2NvdW50IGlzIGJldHdlZW4gMyBhbmQgMTYgY2hhcmFjdGVycyBpbiBsZW5ndGgKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgIGNvbnN0IGZpbmFsVG8gPSB0by50cmltKCk7CgogICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAvLyB0aGVuIHdlIG5lZWQgdG8gY2hlY2sgdGhhdCB0aGUgcXVhbnRpdHkgaXMgY29ycmVjdAogICAgaWYgKGFwaS5hc3NlcnQoZmluYWxUby5sZW5ndGggPj0gMyAmJiBmaW5hbFRvLmxlbmd0aCA8PSAxNiwgJ2ludmFsaWQgdG8nKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgJiYgYXBpLmFzc2VydChjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdzeW1ib2wgcHJlY2lzaW9uIG1pc21hdGNoJykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5zdGFraW5nRW5hYmxlZCA9PT0gdHJ1ZSwgJ3N0YWtpbmcgbm90IGVuYWJsZWQnKQogICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmd0KDApLCAnbXVzdCBzdGFrZSBwb3NpdGl2ZSBxdWFudGl0eScpKSB7CiAgICAgIGlmIChhd2FpdCBzdWJCYWxhbmNlKGFwaS5zZW5kZXIsIHRva2VuLCBxdWFudGl0eSwgJ2JhbGFuY2VzJykpIHsKICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBhZGRTdGFrZShmaW5hbFRvLCB0b2tlbiwgcXVhbnRpdHkpOwoKICAgICAgICBpZiAocmVzID09PSBmYWxzZSkgewogICAgICAgICAgYXdhaXQgYWRkQmFsYW5jZShhcGkuc2VuZGVyLCB0b2tlbiwgcXVhbnRpdHksICdiYWxhbmNlcycpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhcGkuZW1pdCgnc3Rha2UnLCB7IGFjY291bnQ6IGZpbmFsVG8sIHN5bWJvbCwgcXVhbnRpdHkgfSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKY29uc3Qgc3RhcnRVbnN0YWtlID0gYXN5bmMgKGFjY291bnQsIHRva2VuLCBxdWFudGl0eSkgPT4gewogIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5zdGVlbUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgY29uc3QgY29vbGRvd25QZXJpb2RNaWxsaXNlYyA9IHRva2VuLnVuc3Rha2luZ0Nvb2xkb3duICogMjQgKiAzNjAwICogMTAwMDsKICBjb25zdCBtaWxsaXNlY1BlclBlcmlvZCA9IGFwaS5CaWdOdW1iZXIoY29vbGRvd25QZXJpb2RNaWxsaXNlYykKICAgIC5kaXZpZGVkQnkodG9rZW4ubnVtYmVyVHJhbnNhY3Rpb25zKQogICAgLmludGVnZXJWYWx1ZShhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOwoKICBjb25zdCBuZXh0VHJhbnNhY3Rpb25UaW1lc3RhbXAgPSBhcGkuQmlnTnVtYmVyKGJsb2NrRGF0ZS5nZXRUaW1lKCkpCiAgICAucGx1cyhtaWxsaXNlY1BlclBlcmlvZCkKICAgIC50b051bWJlcigpOwoKICBjb25zdCB1bnN0YWtlID0gewogICAgYWNjb3VudCwKICAgIHN5bWJvbDogdG9rZW4uc3ltYm9sLAogICAgcXVhbnRpdHksCiAgICBxdWFudGl0eUxlZnQ6IHF1YW50aXR5LAogICAgbmV4dFRyYW5zYWN0aW9uVGltZXN0YW1wLAogICAgbnVtYmVyVHJhbnNhY3Rpb25zTGVmdDogdG9rZW4ubnVtYmVyVHJhbnNhY3Rpb25zLAogICAgbWlsbGlzZWNQZXJQZXJpb2QsCiAgICB0eElEOiBhcGkudHJhbnNhY3Rpb25JZCwKICB9OwoKICBhd2FpdCBhcGkuZGIuaW5zZXJ0KCdwZW5kaW5nVW5zdGFrZXMnLCB1bnN0YWtlKTsKfTsKCmFjdGlvbnMudW5zdGFrZSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgeyBzeW1ib2wsIHF1YW50aXR5LCBpc1NpZ25lZFdpdGhBY3RpdmVLZXkgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgICAmJiBxdWFudGl0eSAmJiB0eXBlb2YgcXVhbnRpdHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5pc05hTigpLCAnaW52YWxpZCBwYXJhbXMnKSkgewoKICAgIC8vIGEgdmFsaWQgc3RlZW0gYWNjb3VudCBpcyBiZXR3ZWVuIDMgYW5kIDE2IGNoYXJhY3RlcnMgaW4gbGVuZ3RoCiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgICAvLyB0aGUgc3ltYm9sIG11c3QgZXhpc3QKICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICBpZiAoYXBpLmFzc2VydCh0b2tlbiAhPT0gbnVsbCwgJ3N5bWJvbCBkb2VzIG5vdCBleGlzdCcpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uc3Rha2luZ0VuYWJsZWQgPT09IHRydWUsICdzdGFraW5nIG5vdCBlbmFibGVkJykKICAgICAgJiYgYXBpLmFzc2VydChjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdzeW1ib2wgcHJlY2lzaW9uIG1pc21hdGNoJykKICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5ndCgwKSwgJ211c3QgdW5zdGFrZSBwb3NpdGl2ZSBxdWFudGl0eScpKSB7CgogICAgICBpZiAoYXdhaXQgc3ViU3Rha2UoYXBpLnNlbmRlciwgdG9rZW4sIHF1YW50aXR5KSkgewogICAgICAgIGF3YWl0IHN0YXJ0VW5zdGFrZShhcGkuc2VuZGVyLCB0b2tlbiwgcXVhbnRpdHkpOwoKICAgICAgICBhcGkuZW1pdCgndW5zdGFrZVN0YXJ0JywgeyBhY2NvdW50OiBhcGkuc2VuZGVyLCBzeW1ib2wsIHF1YW50aXR5IH0pOwogICAgICB9CiAgICB9CiAgfQp9OwoKY29uc3QgcHJvY2Vzc0NhbmNlbFVuc3Rha2UgPSBhc3luYyAodW5zdGFrZSkgPT4gewogIGNvbnN0IHsKICAgIGFjY291bnQsCiAgICBzeW1ib2wsCiAgICBxdWFudGl0eUxlZnQsCiAgfSA9IHVuc3Rha2U7CgogIGNvbnN0IGJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQsIHN5bWJvbCB9KTsKICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCd0b2tlbnMnLCB7IHN5bWJvbCB9KTsKCiAgaWYgKGFwaS5hc3NlcnQoYmFsYW5jZSAhPT0gbnVsbCwgJ2JhbGFuY2UgZG9lcyBub3QgZXhpc3QnKQogICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UpLmd0ZShxdWFudGl0eUxlZnQpLCAnb3ZlcmRyYXduIHBlbmRpbmdVbnN0YWtlJykpIHsKICAgIGNvbnN0IG9yaWdpbmFsU3Rha2UgPSBiYWxhbmNlLnN0YWtlOwogICAgY29uc3Qgb3JpZ2luYWxQZW5kaW5nU3Rha2UgPSBiYWxhbmNlLnBlbmRpbmdVbnN0YWtlOwoKICAgIGJhbGFuY2Uuc3Rha2UgPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICBiYWxhbmNlLnN0YWtlLCBxdWFudGl0eUxlZnQsIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICk7CiAgICBiYWxhbmNlLnBlbmRpbmdVbnN0YWtlID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSwgcXVhbnRpdHlMZWZ0LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgKTsKCiAgICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UpLmx0KG9yaWdpbmFsUGVuZGluZ1N0YWtlKQogICAgICAmJiBhcGkuQmlnTnVtYmVyKGJhbGFuY2Uuc3Rha2UpLmd0KG9yaWdpbmFsU3Rha2UpLCAnY2Fubm90IHN1YnRyYWN0JykpIHsKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlKTsKCiAgICAgIGFwaS5lbWl0KCd1bnN0YWtlJywgeyBhY2NvdW50LCBzeW1ib2wsIHF1YW50aXR5OiBxdWFudGl0eUxlZnQgfSk7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogIH0KCiAgcmV0dXJuIGZhbHNlOwp9OwoKYWN0aW9ucy5jYW5jZWxVbnN0YWtlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7IHR4SUQsIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICAgJiYgYXBpLmFzc2VydCh0eElEICYmIHR5cGVvZiB0eElEID09PSAnc3RyaW5nJywgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIC8vIGdldCB1bnN0YWtlCiAgICBjb25zdCB1bnN0YWtlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BlbmRpbmdVbnN0YWtlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgdHhJRCB9KTsKCiAgICBpZiAoYXBpLmFzc2VydCh1bnN0YWtlLCAndW5zdGFrZSBkb2VzIG5vdCBleGlzdCcpKSB7CiAgICAgIGlmIChhd2FpdCBwcm9jZXNzQ2FuY2VsVW5zdGFrZSh1bnN0YWtlKSkgewogICAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ3BlbmRpbmdVbnN0YWtlcycsIHVuc3Rha2UpOwogICAgICB9CiAgICB9CiAgfQp9OwoKY29uc3QgYmFsYW5jZVRlbXBsYXRlID0gewogIGFjY291bnQ6IG51bGwsCiAgc3ltYm9sOiBudWxsLAogIGJhbGFuY2U6ICcwJywKICBzdGFrZTogJzAnLAogIHBlbmRpbmdVbnN0YWtlOiAnMCcsCiAgZGVsZWdhdGlvbnNJbjogJzAnLAogIGRlbGVnYXRpb25zT3V0OiAnMCcsCiAgcGVuZGluZ1VuZGVsZWdhdGlvbnM6ICcwJywKfTsKCmNvbnN0IGFkZFN0YWtlID0gYXN5bmMgKGFjY291bnQsIHRva2VuLCBxdWFudGl0eSkgPT4gewogIGxldCBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50LCBzeW1ib2w6IHRva2VuLnN5bWJvbCB9KTsKCiAgaWYgKGJhbGFuY2UgPT09IG51bGwpIHsKICAgIGJhbGFuY2UgPSBiYWxhbmNlVGVtcGxhdGU7CiAgICBiYWxhbmNlLmFjY291bnQgPSBhY2NvdW50OwogICAgYmFsYW5jZS5zeW1ib2wgPSB0b2tlbi5zeW1ib2w7CgogICAgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5pbnNlcnQoJ2JhbGFuY2VzJywgYmFsYW5jZSk7CiAgfQoKICBpZiAoYmFsYW5jZS5zdGFrZSA9PT0gdW5kZWZpbmVkKSB7CiAgICBiYWxhbmNlLnN0YWtlID0gJzAnOwogICAgYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSA9ICcwJzsKICB9CgogIGNvbnN0IG9yaWdpbmFsU3Rha2UgPSBiYWxhbmNlLnN0YWtlOwoKICBiYWxhbmNlLnN0YWtlID0gY2FsY3VsYXRlQmFsYW5jZShiYWxhbmNlLnN0YWtlLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlKTsKICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2Uuc3Rha2UpLmd0KG9yaWdpbmFsU3Rha2UpLCAnY2Fubm90IGFkZCcpKSB7CiAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2UpOwoKICAgIGlmICh0b2tlbi50b3RhbFN0YWtlZCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIHRva2VuLnRvdGFsU3Rha2VkID0gJzAnOwogICAgfQoKICAgIHRva2VuLnRvdGFsU3Rha2VkID0gY2FsY3VsYXRlQmFsYW5jZSh0b2tlbi50b3RhbFN0YWtlZCwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSk7CiAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CgogICAgcmV0dXJuIHRydWU7CiAgfQoKICByZXR1cm4gZmFsc2U7Cn07Cgpjb25zdCBzdWJTdGFrZSA9IGFzeW5jIChhY2NvdW50LCB0b2tlbiwgcXVhbnRpdHkpID0+IHsKICBjb25zdCBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50LCBzeW1ib2w6IHRva2VuLnN5bWJvbCB9KTsKCiAgaWYgKGFwaS5hc3NlcnQoYmFsYW5jZSAhPT0gbnVsbCwgJ2JhbGFuY2UgZG9lcyBub3QgZXhpc3QnKQogICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2Uuc3Rha2UpLmd0ZShxdWFudGl0eSksICdvdmVyZHJhd24gc3Rha2UnKSkgewogICAgY29uc3Qgb3JpZ2luYWxTdGFrZSA9IGJhbGFuY2Uuc3Rha2U7CiAgICBjb25zdCBvcmlnaW5hbFBlbmRpbmdTdGFrZSA9IGJhbGFuY2UucGVuZGluZ1Vuc3Rha2U7CgogICAgYmFsYW5jZS5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoYmFsYW5jZS5zdGFrZSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgZmFsc2UpOwogICAgYmFsYW5jZS5wZW5kaW5nVW5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgIGJhbGFuY2UucGVuZGluZ1Vuc3Rha2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICApOwoKICAgIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5zdGFrZSkubHQob3JpZ2luYWxTdGFrZSkKICAgICAgJiYgYXBpLkJpZ051bWJlcihiYWxhbmNlLnBlbmRpbmdVbnN0YWtlKS5ndChvcmlnaW5hbFBlbmRpbmdTdGFrZSksICdjYW5ub3Qgc3VidHJhY3QnKSkgewogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2UpOwoKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQoKICByZXR1cm4gZmFsc2U7Cn07Cgpjb25zdCBzdWJCYWxhbmNlID0gYXN5bmMgKGFjY291bnQsIHRva2VuLCBxdWFudGl0eSwgdGFibGUpID0+IHsKICBjb25zdCBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUodGFibGUsIHsgYWNjb3VudCwgc3ltYm9sOiB0b2tlbi5zeW1ib2wgfSk7CgogIGlmIChhcGkuYXNzZXJ0KGJhbGFuY2UgIT09IG51bGwsICdiYWxhbmNlIGRvZXMgbm90IGV4aXN0JykKICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlLmJhbGFuY2UpLmd0ZShxdWFudGl0eSksICdvdmVyZHJhd24gYmFsYW5jZScpKSB7CiAgICBjb25zdCBvcmlnaW5hbEJhbGFuY2UgPSBiYWxhbmNlLmJhbGFuY2U7CgogICAgYmFsYW5jZS5iYWxhbmNlID0gY2FsY3VsYXRlQmFsYW5jZShiYWxhbmNlLmJhbGFuY2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlKTsKCiAgICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2UuYmFsYW5jZSkubHQob3JpZ2luYWxCYWxhbmNlKSwgJ2Nhbm5vdCBzdWJ0cmFjdCcpKSB7CiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUodGFibGUsIGJhbGFuY2UpOwoKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQoKICByZXR1cm4gZmFsc2U7Cn07Cgpjb25zdCBhZGRCYWxhbmNlID0gYXN5bmMgKGFjY291bnQsIHRva2VuLCBxdWFudGl0eSwgdGFibGUpID0+IHsKICBsZXQgYmFsYW5jZSA9IGF3YWl0IGFwaS5kYi5maW5kT25lKHRhYmxlLCB7IGFjY291bnQsIHN5bWJvbDogdG9rZW4uc3ltYm9sIH0pOwogIGlmIChiYWxhbmNlID09PSBudWxsKSB7CiAgICBiYWxhbmNlID0gYmFsYW5jZVRlbXBsYXRlOwogICAgYmFsYW5jZS5hY2NvdW50ID0gYWNjb3VudDsKICAgIGJhbGFuY2Uuc3ltYm9sID0gdG9rZW4uc3ltYm9sOwogICAgYmFsYW5jZS5iYWxhbmNlID0gcXVhbnRpdHk7CgoKICAgIGF3YWl0IGFwaS5kYi5pbnNlcnQodGFibGUsIGJhbGFuY2UpOwoKICAgIHJldHVybiB0cnVlOwogIH0KCiAgY29uc3Qgb3JpZ2luYWxCYWxhbmNlID0gYmFsYW5jZS5iYWxhbmNlOwoKICBiYWxhbmNlLmJhbGFuY2UgPSBjYWxjdWxhdGVCYWxhbmNlKGJhbGFuY2UuYmFsYW5jZSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSk7CiAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiYWxhbmNlLmJhbGFuY2UpLmd0KG9yaWdpbmFsQmFsYW5jZSksICdjYW5ub3QgYWRkJykpIHsKICAgIGF3YWl0IGFwaS5kYi51cGRhdGUodGFibGUsIGJhbGFuY2UpOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICByZXR1cm4gZmFsc2U7Cn07Cgpjb25zdCBjYWxjdWxhdGVCYWxhbmNlID0gKGJhbGFuY2UsIHF1YW50aXR5LCBwcmVjaXNpb24sIGFkZCkgPT4gewogIHJldHVybiBhZGQKICAgID8gYXBpLkJpZ051bWJlcihiYWxhbmNlKS5wbHVzKHF1YW50aXR5KS50b0ZpeGVkKHByZWNpc2lvbikKICAgIDogYXBpLkJpZ051bWJlcihiYWxhbmNlKS5taW51cyhxdWFudGl0eSkudG9GaXhlZChwcmVjaXNpb24pOwp9OwoKY29uc3QgY291bnREZWNpbWFscyA9IHZhbHVlID0+IGFwaS5CaWdOdW1iZXIodmFsdWUpLmRwKCk7CgphY3Rpb25zLmVuYWJsZURlbGVnYXRpb24gPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHN5bWJvbCwKICAgIHVuZGVsZWdhdGlvbkNvb2xkb3duLAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHN5bWJvbCcpCiAgICAmJiBhcGkuYXNzZXJ0KHVuZGVsZWdhdGlvbkNvb2xkb3duICYmIE51bWJlci5pc0ludGVnZXIodW5kZWxlZ2F0aW9uQ29vbGRvd24pICYmIHVuZGVsZWdhdGlvbkNvb2xkb3duID4gMCAmJiB1bmRlbGVnYXRpb25Db29sZG93biA8PSAzNjUsICd1bmRlbGVnYXRpb25Db29sZG93biBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAzNjUnKSkgewogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uc3Rha2luZ0VuYWJsZWQgPT09IHRydWUsICdzdGFraW5nIG5vdCBlbmFibGVkJykKICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5kZWxlZ2F0aW9uRW5hYmxlZCA9PT0gdW5kZWZpbmVkIHx8IHRva2VuLmRlbGVnYXRpb25FbmFibGVkID09PSBmYWxzZSwgJ2RlbGVnYXRpb24gYWxyZWFkeSBlbmFibGVkJykpIHsKICAgICAgdG9rZW4uZGVsZWdhdGlvbkVuYWJsZWQgPSB0cnVlOwogICAgICB0b2tlbi51bmRlbGVnYXRpb25Db29sZG93biA9IHVuZGVsZWdhdGlvbkNvb2xkb3duOwogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCd0b2tlbnMnLCB0b2tlbik7CiAgICB9CiAgfQp9OwoKLyoKYWN0aW9ucy51cGRhdGVEZWxlZ2F0aW9uUGFyYW1zID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICB1bmRlbGVnYXRpb25Db29sZG93biwKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgLy8gZ2V0IGNvbnRyYWN0IHBhcmFtcwogIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CiAgY29uc3QgeyB1cGRhdGVEZWxlZ2F0aW9uUGFyYW1zRmVlIH0gPSBwYXJhbXM7CgogIC8vIGdldCBhcGkuc2VuZGVyJ3MgVVRJTElUWV9UT0tFTl9TWU1CT0wgYmFsYW5jZQogIGNvbnN0IHV0aWxpdHlUb2tlbkJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQ6IGFwaS5zZW5kZXIsIHN5bWJvbDogIkVORyIgfSk7CgogIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIodXRpbGl0eVRva2VuQmFsYW5jZS5iYWxhbmNlKS5ndGUodXBkYXRlRGVsZWdhdGlvblBhcmFtc0ZlZSksICd5b3UgbXVzdCBoYXZlIGVub3VnaCB0b2tlbnMgdG8gY292ZXIgdGhlIGZlZXMnKQogICAgJiYgYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHN5bWJvbCcpCiAgICAmJiBhcGkuYXNzZXJ0KHVuZGVsZWdhdGlvbkNvb2xkb3duICYmIE51bWJlci5pc0ludGVnZXIodW5kZWxlZ2F0aW9uQ29vbGRvd24pICYmIHVuZGVsZWdhdGlvbkNvb2xkb3duID4gMCAmJiB1bmRlbGVnYXRpb25Db29sZG93biA8PSAzNjUsICd1bmRlbGVnYXRpb25Db29sZG93biBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAzNjUnKSkgewogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAmJiBhcGkuYXNzZXJ0KHRva2VuLmlzc3VlciA9PT0gYXBpLnNlbmRlciwgJ211c3QgYmUgdGhlIGlzc3VlcicpCiAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uZGVsZWdhdGlvbkVuYWJsZWQgPT09IHRydWUsICdkZWxlZ2F0aW9uIG5vdCBlbmFibGVkJykpIHsKICAgICAgdG9rZW4udW5kZWxlZ2F0aW9uQ29vbGRvd24gPSB1bmRlbGVnYXRpb25Db29sZG93bjsKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgndG9rZW5zJywgdG9rZW4pOwoKICAgICAgLy8gYnVybiB0aGUgdG9rZW4gY3JlYXRpb24gZmVlcwogICAgICBpZiAoYXBpLkJpZ051bWJlcih1cGRhdGVEZWxlZ2F0aW9uUGFyYW1zRmVlKS5ndCgwKSkgewogICAgICAgIGF3YWl0IGFjdGlvbnMudHJhbnNmZXIoewogICAgICAgICAgdG86ICdudWxsJywgc3ltYm9sOiAiRU5HIiwgcXVhbnRpdHk6IHVwZGF0ZURlbGVnYXRpb25QYXJhbXNGZWUsIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICAgICAgICB9KTsKICAgICAgfQogICAgfQogIH0KfTsKCiovCgphY3Rpb25zLmRlbGVnYXRlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICBxdWFudGl0eSwKICAgIHRvLAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycKICAgICYmIHRvICYmIHR5cGVvZiB0byA9PT0gJ3N0cmluZycKICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICBjb25zdCBmaW5hbFRvID0gdG8udHJpbSgpOwogICAgLy8gYSB2YWxpZCBzdGVlbSBhY2NvdW50IGlzIGJldHdlZW4gMyBhbmQgMTYgY2hhcmFjdGVycyBpbiBsZW5ndGgKICAgIGlmIChhcGkuYXNzZXJ0KGZpbmFsVG8ubGVuZ3RoID49IDMgJiYgZmluYWxUby5sZW5ndGggPD0gMTYsICdpbnZhbGlkIHRvJykpIHsKICAgICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogICAgICAvLyB0aGUgc3ltYm9sIG11c3QgZXhpc3QKICAgICAgLy8gdGhlbiB3ZSBuZWVkIHRvIGNoZWNrIHRoYXQgdGhlIHF1YW50aXR5IGlzIGNvcnJlY3QKICAgICAgaWYgKGFwaS5hc3NlcnQodG9rZW4gIT09IG51bGwsICdzeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAgICYmIGFwaS5hc3NlcnQoY291bnREZWNpbWFscyhxdWFudGl0eSkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnc3ltYm9sIHByZWNpc2lvbiBtaXNtYXRjaCcpCiAgICAgICAgJiYgYXBpLmFzc2VydCh0b2tlbi5kZWxlZ2F0aW9uRW5hYmxlZCA9PT0gdHJ1ZSwgJ2RlbGVnYXRpb24gbm90IGVuYWJsZWQnKQogICAgICAgICYmIGFwaS5hc3NlcnQoZmluYWxUbyAhPT0gYXBpLnNlbmRlciwgJ2Nhbm5vdCBkZWxlZ2F0ZSB0byB5b3Vyc2VsZicpCiAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5ndCgwKSwgJ211c3QgZGVsZWdhdGUgcG9zaXRpdmUgcXVhbnRpdHknKSkgewogICAgICAgIGNvbnN0IGJhbGFuY2VGcm9tID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50OiBhcGkuc2VuZGVyLCBzeW1ib2wgfSk7CgogICAgICAgIGlmIChhcGkuYXNzZXJ0KGJhbGFuY2VGcm9tICE9PSBudWxsLCAnYmFsYW5jZUZyb20gZG9lcyBub3QgZXhpc3QnKQogICAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2VGcm9tLnN0YWtlKS5ndGUocXVhbnRpdHkpLCAnb3ZlcmRyYXduIHN0YWtlJykpIHsKICAgICAgICAgIGlmIChiYWxhbmNlRnJvbS5zdGFrZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbGQgYmFsYW5jZXMgd2l0aCBuZXcgcHJvcGVydGllcwogICAgICAgICAgICBiYWxhbmNlRnJvbS5zdGFrZSA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZUZyb20ucGVuZGluZ1Vuc3Rha2UgPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VGcm9tLmRlbGVnYXRpb25zSW4gPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VGcm9tLmRlbGVnYXRpb25zT3V0ID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5wZW5kaW5nVW5kZWxlZ2F0aW9ucyA9ICcwJzsKICAgICAgICAgIH0gZWxzZSBpZiAoYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNJbiA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbGQgYmFsYW5jZXMgd2l0aCBuZXcgcHJvcGVydGllcwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc0luID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc091dCA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZUZyb20ucGVuZGluZ1VuZGVsZWdhdGlvbnMgPSAnMCc7CiAgICAgICAgICAgIGlmIChiYWxhbmNlRnJvbS5kZWxlZ2F0ZWRTdGFrZSkgewogICAgICAgICAgICAgIGRlbGV0ZSBiYWxhbmNlRnJvbS5kZWxlZ2F0ZWRTdGFrZTsKICAgICAgICAgICAgICBkZWxldGUgYmFsYW5jZUZyb20ucmVjZWl2ZWRTdGFrZTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIGxldCBiYWxhbmNlVG8gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYmFsYW5jZXMnLCB7IGFjY291bnQ6IHRvLCBzeW1ib2wgfSk7CgogICAgICAgICAgaWYgKGJhbGFuY2VUbyA9PT0gbnVsbCkgewogICAgICAgICAgICBiYWxhbmNlVG8gPSBiYWxhbmNlVGVtcGxhdGU7CiAgICAgICAgICAgIGJhbGFuY2VUby5hY2NvdW50ID0gdG87CiAgICAgICAgICAgIGJhbGFuY2VUby5zeW1ib2wgPSBzeW1ib2w7CgogICAgICAgICAgICBiYWxhbmNlVG8gPSBhd2FpdCBhcGkuZGIuaW5zZXJ0KCdiYWxhbmNlcycsIGJhbGFuY2VUbyk7CiAgICAgICAgICB9IGVsc2UgaWYgKGJhbGFuY2VUby5zdGFrZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbGQgYmFsYW5jZXMgd2l0aCBuZXcgcHJvcGVydGllcwogICAgICAgICAgICBiYWxhbmNlVG8uc3Rha2UgPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VUby5wZW5kaW5nVW5zdGFrZSA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zSW4gPSAnMCc7CiAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc091dCA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZVRvLnBlbmRpbmdVbmRlbGVnYXRpb25zID0gJzAnOwogICAgICAgICAgfSBlbHNlIGlmIChiYWxhbmNlVG8uZGVsZWdhdGlvbnNJbiA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgIC8vIHVwZGF0ZSBvbGQgYmFsYW5jZXMgd2l0aCBuZXcgcHJvcGVydGllcwogICAgICAgICAgICBiYWxhbmNlVG8uZGVsZWdhdGlvbnNJbiA9ICcwJzsKICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zT3V0ID0gJzAnOwogICAgICAgICAgICBiYWxhbmNlVG8ucGVuZGluZ1VuZGVsZWdhdGlvbnMgPSAnMCc7CgogICAgICAgICAgICBpZiAoYmFsYW5jZVRvLmRlbGVnYXRlZFN0YWtlKSB7CiAgICAgICAgICAgICAgZGVsZXRlIGJhbGFuY2VUby5kZWxlZ2F0ZWRTdGFrZTsKICAgICAgICAgICAgICBkZWxldGUgYmFsYW5jZVRvLnJlY2VpdmVkU3Rha2U7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICAvLyBsb29rIGZvciBhbiBleGlzdGluZyBkZWxlZ2F0aW9uCiAgICAgICAgICBsZXQgZGVsZWdhdGlvbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdkZWxlZ2F0aW9ucycsIHsgdG86IGZpbmFsVG8sIGZyb206IGFwaS5zZW5kZXIsIHN5bWJvbCB9KTsKICAgICAgICAgIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5zdGVlbUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgICAgICAgICBjb25zdCB0aW1lc3RhbXAgPSBibG9ja0RhdGUuZ2V0VGltZSgpOwoKICAgICAgICAgIGlmIChkZWxlZ2F0aW9uID09IG51bGwpIHsKICAgICAgICAgICAgLy8gdXBkYXRlIGJhbGFuY2VGcm9tCiAgICAgICAgICAgIGJhbGFuY2VGcm9tLnN0YWtlID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgICAgICBiYWxhbmNlRnJvbS5zdGFrZSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgZmFsc2UsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIGJhbGFuY2VGcm9tLmRlbGVnYXRpb25zT3V0ID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc091dCwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2JhbGFuY2VzJywgYmFsYW5jZUZyb20pOwoKICAgICAgICAgICAgLy8gdXBkYXRlIGJhbGFuY2VUbwogICAgICAgICAgICBiYWxhbmNlVG8uZGVsZWdhdGlvbnNJbiA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zSW4sIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2VUbyk7CgogICAgICAgICAgICBkZWxlZ2F0aW9uID0ge307CiAgICAgICAgICAgIGRlbGVnYXRpb24uZnJvbSA9IGFwaS5zZW5kZXI7CiAgICAgICAgICAgIGRlbGVnYXRpb24udG8gPSB0bzsKICAgICAgICAgICAgZGVsZWdhdGlvbi5zeW1ib2wgPSBzeW1ib2w7CiAgICAgICAgICAgIGRlbGVnYXRpb24ucXVhbnRpdHkgPSBxdWFudGl0eTsKICAgICAgICAgICAgZGVsZWdhdGlvbi5jcmVhdGVkID0gdGltZXN0YW1wOwogICAgICAgICAgICBkZWxlZ2F0aW9uLnVwZGF0ZWQgPSB0aW1lc3RhbXA7CgogICAgICAgICAgICBhd2FpdCBhcGkuZGIuaW5zZXJ0KCdkZWxlZ2F0aW9ucycsIGRlbGVnYXRpb24pOwoKICAgICAgICAgICAgYXBpLmVtaXQoJ2RlbGVnYXRlJywgeyB0bywgc3ltYm9sLCBxdWFudGl0eSB9KTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIGlmIGEgZGVsZWdhdGlvbiBhbHJlYWR5IGV4aXN0cywgaW5jcmVhc2UgaXQKCiAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlRnJvbQogICAgICAgICAgICBiYWxhbmNlRnJvbS5zdGFrZSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgYmFsYW5jZUZyb20uc3Rha2UsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICApOwogICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc091dCA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNPdXQsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIHRydWUsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2VGcm9tKTsKCiAgICAgICAgICAgIC8vIHVwZGF0ZSBiYWxhbmNlVG8KICAgICAgICAgICAgYmFsYW5jZVRvLmRlbGVnYXRpb25zSW4gPSBjYWxjdWxhdGVCYWxhbmNlKAogICAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc0luLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCB0cnVlLAogICAgICAgICAgICApOwoKICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlVG8pOwoKICAgICAgICAgICAgLy8gdXBkYXRlIGRlbGVnYXRpb24KICAgICAgICAgICAgZGVsZWdhdGlvbi5xdWFudGl0eSA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgZGVsZWdhdGlvbi5xdWFudGl0eSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgdGltZXN0YW1wCiAgICAgICAgICAgIGRlbGVnYXRpb24udXBkYXRlZCA9IHRpbWVzdGFtcDsKCiAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2RlbGVnYXRpb25zJywgZGVsZWdhdGlvbik7CiAgICAgICAgICAgIGFwaS5lbWl0KCdkZWxlZ2F0ZScsIHsgdG8sIHN5bWJvbCwgcXVhbnRpdHkgfSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy51bmRlbGVnYXRlID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICBxdWFudGl0eSwKICAgIGZyb20sCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KHN5bWJvbCAmJiB0eXBlb2Ygc3ltYm9sID09PSAnc3RyaW5nJwogICAgJiYgZnJvbSAmJiB0eXBlb2YgZnJvbSA9PT0gJ3N0cmluZycKICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICBjb25zdCBmaW5hbEZyb20gPSBmcm9tLnRyaW0oKTsKICAgIC8vIGEgdmFsaWQgc3RlZW0gYWNjb3VudCBpcyBiZXR3ZWVuIDMgYW5kIDE2IGNoYXJhY3RlcnMgaW4gbGVuZ3RoCiAgICBpZiAoYXBpLmFzc2VydChmaW5hbEZyb20ubGVuZ3RoID49IDMgJiYgZmluYWxGcm9tLmxlbmd0aCA8PSAxNiwgJ2ludmFsaWQgZnJvbScpKSB7CiAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Rva2VucycsIHsgc3ltYm9sIH0pOwoKICAgICAgLy8gdGhlIHN5bWJvbCBtdXN0IGV4aXN0CiAgICAgIC8vIHRoZW4gd2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZSBxdWFudGl0eSBpcyBjb3JyZWN0CiAgICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuICE9PSBudWxsLCAnc3ltYm9sIGRvZXMgbm90IGV4aXN0JykKICAgICAgICAmJiBhcGkuYXNzZXJ0KGNvdW50RGVjaW1hbHMocXVhbnRpdHkpIDw9IHRva2VuLnByZWNpc2lvbiwgJ3N5bWJvbCBwcmVjaXNpb24gbWlzbWF0Y2gnKQogICAgICAgICYmIGFwaS5hc3NlcnQodG9rZW4uZGVsZWdhdGlvbkVuYWJsZWQgPT09IHRydWUsICdkZWxlZ2F0aW9uIG5vdCBlbmFibGVkJykKICAgICAgICAmJiBhcGkuYXNzZXJ0KGZpbmFsRnJvbSAhPT0gYXBpLnNlbmRlciwgJ2Nhbm5vdCB1bmRlbGVnYXRlIGZyb20geW91cnNlbGYnKQogICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QoMCksICdtdXN0IHVuZGVsZWdhdGUgcG9zaXRpdmUgcXVhbnRpdHknKSkgewogICAgICAgIGNvbnN0IGJhbGFuY2VUbyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdiYWxhbmNlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgc3ltYm9sIH0pOwoKICAgICAgICBpZiAoYXBpLmFzc2VydChiYWxhbmNlVG8gIT09IG51bGwsICdiYWxhbmNlVG8gZG9lcyBub3QgZXhpc3QnKQogICAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGJhbGFuY2VUby5kZWxlZ2F0aW9uc091dCkuZ3RlKHF1YW50aXR5KSwgJ292ZXJkcmF3biBkZWxlZ2F0aW9uJykpIHsKICAgICAgICAgIGNvbnN0IGJhbGFuY2VGcm9tID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50OiBmaW5hbEZyb20sIHN5bWJvbCB9KTsKCiAgICAgICAgICBpZiAoYXBpLmFzc2VydChiYWxhbmNlRnJvbSAhPT0gbnVsbCwgJ2JhbGFuY2VGcm9tIGRvZXMgbm90IGV4aXN0JykpIHsKICAgICAgICAgICAgLy8gbG9vayBmb3IgYW4gZXhpc3RpbmcgZGVsZWdhdGlvbgogICAgICAgICAgICBjb25zdCBkZWxlZ2F0aW9uID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2RlbGVnYXRpb25zJywgeyB0bzogZmluYWxGcm9tLCBmcm9tOiBhcGkuc2VuZGVyLCBzeW1ib2wgfSk7CgogICAgICAgICAgICBpZiAoYXBpLmFzc2VydChkZWxlZ2F0aW9uICE9PSBudWxsLCAnZGVsZWdhdGlvbiBkb2VzIG5vdCBleGlzdCcpCiAgICAgICAgICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGRlbGVnYXRpb24ucXVhbnRpdHkpLmd0ZShxdWFudGl0eSksICdvdmVyZHJhd24gZGVsZWdhdGlvbicpKSB7CiAgICAgICAgICAgICAgLy8gdXBkYXRlIGJhbGFuY2VUbwogICAgICAgICAgICAgIGJhbGFuY2VUby5wZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgICBiYWxhbmNlRnJvbS5wZW5kaW5nVW5kZWxlZ2F0aW9ucywgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICAgICAgICAgICApOwogICAgICAgICAgICAgIGJhbGFuY2VUby5kZWxlZ2F0aW9uc091dCA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgICBiYWxhbmNlVG8uZGVsZWdhdGlvbnNPdXQsIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2JhbGFuY2VzJywgYmFsYW5jZVRvKTsKCiAgICAgICAgICAgICAgLy8gdXBkYXRlIGJhbGFuY2VGcm9tCiAgICAgICAgICAgICAgYmFsYW5jZUZyb20uZGVsZWdhdGlvbnNJbiA9IGNhbGN1bGF0ZUJhbGFuY2UoCiAgICAgICAgICAgICAgICBiYWxhbmNlRnJvbS5kZWxlZ2F0aW9uc0luLCBxdWFudGl0eSwgdG9rZW4ucHJlY2lzaW9uLCBmYWxzZSwKICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdiYWxhbmNlcycsIGJhbGFuY2VGcm9tKTsKCiAgICAgICAgICAgICAgLy8gdXBkYXRlIGRlbGVnYXRpb24KICAgICAgICAgICAgICBkZWxlZ2F0aW9uLnF1YW50aXR5ID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgICAgICAgICAgIGRlbGVnYXRpb24ucXVhbnRpdHksIHF1YW50aXR5LCB0b2tlbi5wcmVjaXNpb24sIGZhbHNlLAogICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgIGlmIChhcGkuQmlnTnVtYmVyKGRlbGVnYXRpb24ucXVhbnRpdHkpLmd0KDApKSB7CiAgICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdkZWxlZ2F0aW9ucycsIGRlbGVnYXRpb24pOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCdkZWxlZ2F0aW9ucycsIGRlbGVnYXRpb24pOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gYWRkIHBlbmRpbmcgdW5kZWxlZ2F0aW9uCiAgICAgICAgICAgICAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLnN0ZWVtQmxvY2tUaW1lc3RhbXB9LjAwMFpgKTsKICAgICAgICAgICAgICBjb25zdCBjb29sZG93blBlcmlvZE1pbGxpc2VjID0gdG9rZW4udW5kZWxlZ2F0aW9uQ29vbGRvd24gKiAyNCAqIDM2MDAgKiAxMDAwOwoKICAgICAgICAgICAgICBjb25zdCBjb21wbGV0ZVRpbWVzdGFtcCA9IGJsb2NrRGF0ZS5nZXRUaW1lKCkgKyBjb29sZG93blBlcmlvZE1pbGxpc2VjOwoKICAgICAgICAgICAgICBjb25zdCB1bmRlbGVnYXRpb24gPSB7CiAgICAgICAgICAgICAgICBhY2NvdW50OiBhcGkuc2VuZGVyLAogICAgICAgICAgICAgICAgc3ltYm9sOiB0b2tlbi5zeW1ib2wsCiAgICAgICAgICAgICAgICBxdWFudGl0eSwKICAgICAgICAgICAgICAgIGNvbXBsZXRlVGltZXN0YW1wLAogICAgICAgICAgICAgICAgdHhJRDogYXBpLnRyYW5zYWN0aW9uSWQsCiAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLmluc2VydCgncGVuZGluZ1VuZGVsZWdhdGlvbnMnLCB1bmRlbGVnYXRpb24pOwoKICAgICAgICAgICAgICBhcGkuZW1pdCgndW5kZWxlZ2F0ZVN0YXJ0JywgeyBmcm9tOiBmaW5hbEZyb20sIHN5bWJvbCwgcXVhbnRpdHkgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn07Cgpjb25zdCBwcm9jZXNzVW5kZWxlZ2F0aW9uID0gYXN5bmMgKHVuZGVsZWdhdGlvbikgPT4gewogIGNvbnN0IHsKICAgIGFjY291bnQsCiAgICBzeW1ib2wsCiAgICBxdWFudGl0eSwKICB9ID0gdW5kZWxlZ2F0aW9uOwoKICBjb25zdCBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2JhbGFuY2VzJywgeyBhY2NvdW50LCBzeW1ib2wgfSk7CiAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgndG9rZW5zJywgeyBzeW1ib2wgfSk7CgogIGlmIChhcGkuYXNzZXJ0KGJhbGFuY2UgIT09IG51bGwsICdiYWxhbmNlIGRvZXMgbm90IGV4aXN0JykpIHsKICAgIGNvbnN0IG9yaWdpbmFsU3Rha2UgPSBiYWxhbmNlLnN0YWtlOwogICAgY29uc3Qgb3JpZ2luYWxQZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IGJhbGFuY2UucGVuZGluZ1VuZGVsZWdhdGlvbnM7CgogICAgLy8gdXBkYXRlIHRoZSBiYWxhbmNlCiAgICBiYWxhbmNlLnN0YWtlID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgYmFsYW5jZS5zdGFrZSwgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgdHJ1ZSwKICAgICk7CiAgICBiYWxhbmNlLnBlbmRpbmdVbmRlbGVnYXRpb25zID0gY2FsY3VsYXRlQmFsYW5jZSgKICAgICAgYmFsYW5jZS5wZW5kaW5nVW5kZWxlZ2F0aW9ucywgcXVhbnRpdHksIHRva2VuLnByZWNpc2lvbiwgZmFsc2UsCiAgICApOwoKICAgIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5wZW5kaW5nVW5kZWxlZ2F0aW9ucykubHQob3JpZ2luYWxQZW5kaW5nVW5kZWxlZ2F0aW9ucykKICAgICAgICAmJiBhcGkuQmlnTnVtYmVyKGJhbGFuY2Uuc3Rha2UpLmd0KG9yaWdpbmFsU3Rha2UpLCAnY2Fubm90IHN1YnRyYWN0JykpIHsKICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYmFsYW5jZXMnLCBiYWxhbmNlKTsKCiAgICAgIC8vIHJlbW92ZSBwZW5kaW5nVW5kZWxlZ2F0aW9uCiAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ3BlbmRpbmdVbmRlbGVnYXRpb25zJywgdW5kZWxlZ2F0aW9uKTsKCiAgICAgIGFwaS5lbWl0KCd1bmRlbGVnYXRlRG9uZScsIHsgYWNjb3VudCwgc3ltYm9sLCBxdWFudGl0eSB9KTsKICAgIH0KICB9Cn07CgphY3Rpb25zLmNoZWNrUGVuZGluZ1VuZGVsZWdhdGlvbnMgPSBhc3luYyAoKSA9PiB7CiAgaWYgKGFwaS5hc3NlcnQoYXBpLnNlbmRlciA9PT0gJ251bGwnLCAnbm90IGF1dGhvcml6ZWQnKSkgewogICAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLnN0ZWVtQmxvY2tUaW1lc3RhbXB9LjAwMFpgKTsKICAgIGNvbnN0IHRpbWVzdGFtcCA9IGJsb2NrRGF0ZS5nZXRUaW1lKCk7CgogICAgLy8gZ2V0IGFsbCB0aGUgcGVuZGluZyB1bnN0YWtlcyB0aGF0IGFyZSByZWFkeSB0byBiZSByZWxlYXNlZAogICAgbGV0IHBlbmRpbmdVbmRlbGVnYXRpb25zID0gYXdhaXQgYXBpLmRiLmZpbmQoCiAgICAgICdwZW5kaW5nVW5kZWxlZ2F0aW9ucycsCiAgICAgIHsKICAgICAgICBjb21wbGV0ZVRpbWVzdGFtcDogewogICAgICAgICAgJGx0ZTogdGltZXN0YW1wLAogICAgICAgIH0sCiAgICAgIH0sCiAgICApOwoKICAgIGxldCBuYlBlbmRpbmdVbmRlbGVnYXRpb25zID0gcGVuZGluZ1VuZGVsZWdhdGlvbnMubGVuZ3RoOwogICAgd2hpbGUgKG5iUGVuZGluZ1VuZGVsZWdhdGlvbnMgPiAwKSB7CiAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBuYlBlbmRpbmdVbmRlbGVnYXRpb25zOyBpbmRleCArPSAxKSB7CiAgICAgICAgY29uc3QgcGVuZGluZ1VuZGVsZWdhdGlvbiA9IHBlbmRpbmdVbmRlbGVnYXRpb25zW2luZGV4XTsKICAgICAgICBhd2FpdCBwcm9jZXNzVW5kZWxlZ2F0aW9uKHBlbmRpbmdVbmRlbGVnYXRpb24pOwogICAgICB9CgogICAgICBwZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IGF3YWl0IGFwaS5kYi5maW5kKAogICAgICAgICdwZW5kaW5nVW5kZWxlZ2F0aW9ucycsCiAgICAgICAgewogICAgICAgICAgY29tcGxldGVUaW1lc3RhbXA6IHsKICAgICAgICAgICAgJGx0ZTogdGltZXN0YW1wLAogICAgICAgICAgfSwKICAgICAgICB9LAogICAgICApOwoKICAgICAgbmJQZW5kaW5nVW5kZWxlZ2F0aW9ucyA9IHBlbmRpbmdVbmRlbGVnYXRpb25zLmxlbmd0aDsKICAgIH0KICB9Cn07Cg=='; + finalTransaction.payload = JSON.stringify(transPayload); + } + } + newTransactions.push(new Transaction( - transaction.refSteemBlockNumber, - transaction.transactionId, - transaction.sender, - transaction.contract, - transaction.action, - transaction.payload, + finalTransaction.refSteemBlockNumber, + finalTransaction.transactionId, + finalTransaction.sender, + finalTransaction.contract, + finalTransaction.action, + finalTransaction.payload, )); });