You are viewing a single comment's thread from:

RE: testnet

in #test3 years ago (edited)

{ "id": "ssc-testnet-hive", "json": { "contractName":"contract", "contractAction":"update", "contractPayload":{"name":"mining","params":"","code":"LyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCAqLwovKiBlc2xpbnQgbm8tdW5kZXJzY29yZS1kYW5nbGU6IFsiZXJyb3IiLCB7ICJhbGxvdyI6IFsiX2lkIl0gfV0gKi8KLyogZ2xvYmFsIGFjdGlvbnMsIGFwaSAqLwoKY29uc3QgTUFYX0RJR0lUUyA9IDIwOwpjb25zdCBQUk9QRVJUWV9PUFMgPSB7CiAgQUREOiB7CiAgICBhZGQ6ICh4LCB5KSA9PiBhcGkuQmlnTnVtYmVyKHgpLnBsdXMoeSksCiAgICByZW1vdmU6ICh4LCB5KSA9PiBhcGkuQmlnTnVtYmVyKHgpLm1pbnVzKHkpLAogICAgZGVmYXVsdFZhbHVlOiAwLAogIH0sCiAgTVVMVElQTFk6IHsKICAgIGFkZDogKHgsIHkpID0+IGFwaS5CaWdOdW1iZXIoeCkubXVsdGlwbGllZEJ5KHkpLmRwKE1BWF9ESUdJVFMpLAogICAgcmVtb3ZlOiAoeCwgeSkgPT4gYXBpLkJpZ051bWJlcih4KS5kaXZpZGVkQnkoeSkuZHAoTUFYX0RJR0lUUyksCiAgICBkZWZhdWx0VmFsdWU6IDEsCiAgfSwKfTsKY29uc3QgTUlOSU5HX1BPV0VSX0ZJRUxEX0lOREVYID0gJ19taW5pbmdQb3dlcic7CgoKYWN0aW9ucy5jcmVhdGVTU0MgPSBhc3luYyAoKSA9PiB7CiAgY29uc3QgdGFibGVFeGlzdHMgPSBhd2FpdCBhcGkuZGIudGFibGVFeGlzdHMoJ21pbmluZ1Bvd2VyJyk7CiAgaWYgKHRhYmxlRXhpc3RzID09PSBmYWxzZSkgewogICAgYXdhaXQgYXBpLmRiLmNyZWF0ZVRhYmxlKCdtaW5pbmdQb3dlcicsIFsnaWQnLCAncG93ZXInXSk7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ3Bvb2xzJywgWydpZCddKTsKICAgIC8vIEdpdmVuIHN5bWJvbCwgb3V0cHV0IHdoaWNoIHBvb2xzIGFyZSB1c2luZyBpdC4KICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgndG9rZW5Qb29scycsIFsnc3ltYm9sJ10pOwogICAgYXdhaXQgYXBpLmRiLmNyZWF0ZVRhYmxlKCduZnRUb2tlblBvb2xzJywgWydzeW1ib2wnXSk7CiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ3BhcmFtcycpOwoKICAgIGNvbnN0IHBhcmFtcyA9IHt9OwogICAgcGFyYW1zLnBvb2xDcmVhdGlvbkZlZSA9ICcxMDAwJzsKICAgIHBhcmFtcy5wb29sVXBkYXRlRmVlID0gJzMwMCc7CiAgICBwYXJhbXMubWF4TG90dGVyaWVzUGVyQmxvY2sgPSAyMDsKICAgIHBhcmFtcy5tYXhCYWxhbmNlc1Byb2Nlc3NlZFBlckJsb2NrID0gMTAwMDA7CiAgICBwYXJhbXMucHJvY2Vzc1F1ZXJ5TGltaXQgPSAxMDAwOwogICAgYXdhaXQgYXBpLmRiLmluc2VydCgncGFyYW1zJywgcGFyYW1zKTsKICB9IGVsc2UgewogICAgY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKICAgIGlmICghcGFyYW1zLnVwZGF0ZUluZGV4KSB7CiAgICAgIC8vIHdvdWxkIHdhbnQgdGhpcyB0byBiZSBhIHByaW1hcnkga2V5LCBidXQgY2Fubm90IGFsdGVyIHByaW1hcnkga2V5cwogICAgICBhd2FpdCBhcGkuZGIuYWRkSW5kZXhlcygnbWluaW5nUG93ZXInLCBbeyBuYW1lOiAnYnlQb29sSWRBbmRBY2NvdW50JywgaW5kZXg6IHsgaWQ6IDEsIGFjY291bnQ6IDEgfSB9XSk7CiAgICAgIHBhcmFtcy51cGRhdGVJbmRleCA9IDE7CiAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3BhcmFtcycsIHBhcmFtcyk7CiAgICB9CiAgfQp9OwoKYWN0aW9ucy51cGRhdGVQYXJhbXMgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGlmIChhcGkuc2VuZGVyICE9PSBhcGkub3duZXIpIHJldHVybjsKCiAgY29uc3QgewogICAgcG9vbENyZWF0aW9uRmVlLAogICAgcG9vbFVwZGF0ZUZlZSwKICAgIG1heExvdHRlcmllc1BlckJsb2NrLAogICAgbWF4QmFsYW5jZXNQcm9jZXNzZWRQZXJCbG9jaywKICAgIHByb2Nlc3NRdWVyeUxpbWl0LAogIH0gPSBwYXlsb2FkOwoKICBjb25zdCBwYXJhbXMgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncGFyYW1zJywge30pOwoKICBpZiAocG9vbENyZWF0aW9uRmVlKSB7CiAgICBpZiAoIWFwaS5hc3NlcnQodHlwZW9mIHBvb2xDcmVhdGlvbkZlZSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocG9vbENyZWF0aW9uRmVlKS5pc05hTigpICYmIGFwaS5CaWdOdW1iZXIocG9vbENyZWF0aW9uRmVlKS5ndGUoMCksICdpbnZhbGlkIHBvb2xDcmVhdGlvbkZlZScpKSByZXR1cm47CiAgICBwYXJhbXMucG9vbENyZWF0aW9uRmVlID0gcG9vbENyZWF0aW9uRmVlOwogIH0KICBpZiAocG9vbFVwZGF0ZUZlZSkgewogICAgaWYgKCFhcGkuYXNzZXJ0KHR5cGVvZiBwb29sVXBkYXRlRmVlID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihwb29sVXBkYXRlRmVlKS5pc05hTigpICYmIGFwaS5CaWdOdW1iZXIocG9vbFVwZGF0ZUZlZSkuZ3RlKDApLCAnaW52YWxpZCBwb29sVXBkYXRlRmVlJykpIHJldHVybjsKICAgIHBhcmFtcy5wb29sVXBkYXRlRmVlID0gcG9vbFVwZGF0ZUZlZTsKICB9CiAgaWYgKG1heExvdHRlcmllc1BlckJsb2NrKSB7CiAgICBpZiAoIWFwaS5hc3NlcnQoTnVtYmVyLmlzSW50ZWdlcihtYXhMb3R0ZXJpZXNQZXJCbG9jaykgJiYgbWF4TG90dGVyaWVzUGVyQmxvY2sgPj0gMSwgJ2ludmFsaWQgbWF4TG90dGVyaWVzUGVyQmxvY2snKSkgcmV0dXJuOwogICAgcGFyYW1zLm1heExvdHRlcmllc1BlckJsb2NrID0gbWF4TG90dGVyaWVzUGVyQmxvY2s7CiAgfQogIGlmIChtYXhCYWxhbmNlc1Byb2Nlc3NlZFBlckJsb2NrKSB7CiAgICBpZiAoIWFwaS5hc3NlcnQoTnVtYmVyLmlzSW50ZWdlcihtYXhCYWxhbmNlc1Byb2Nlc3NlZFBlckJsb2NrKSAmJiBtYXhCYWxhbmNlc1Byb2Nlc3NlZFBlckJsb2NrID49IDEsICdpbnZhbGlkIG1heEJhbGFuY2VzUHJvY2Vzc2VkUGVyQmxvY2snKSkgcmV0dXJuOwogICAgcGFyYW1zLm1heEJhbGFuY2VzUHJvY2Vzc2VkUGVyQmxvY2sgPSBtYXhCYWxhbmNlc1Byb2Nlc3NlZFBlckJsb2NrOwogIH0KICBpZiAocHJvY2Vzc1F1ZXJ5TGltaXQpIHsKICAgIGlmICghYXBpLmFzc2VydChOdW1iZXIuaXNJbnRlZ2VyKHByb2Nlc3NRdWVyeUxpbWl0KSAmJiBwcm9jZXNzUXVlcnlMaW1pdCA+PSAxLCAnaW52YWxpZCBwcm9jZXNzUXVlcnlMaW1pdCcpKSByZXR1cm47CiAgICBwYXJhbXMucHJvY2Vzc1F1ZXJ5TGltaXQgPSBwcm9jZXNzUXVlcnlMaW1pdDsKICB9CgogIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3BhcmFtcycsIHBhcmFtcyk7Cn07Cgpjb25zdCBmaW5kQW5kUHJvY2Vzc0FsbCA9IGFzeW5jIChjb250cmFjdE5hbWUsIHRhYmxlLCBxdWVyeSwgY2FsbGJhY2spID0+IHsKICBsZXQgb2Zmc2V0ID0gMDsKICBsZXQgcmVzdWx0cyA9IFtdOwogIGxldCBkb25lID0gZmFsc2U7CiAgd2hpbGUgKCFkb25lKSB7CiAgICByZXN1bHRzID0gYXdhaXQgYXBpLmRiLmZpbmRJblRhYmxlKGNvbnRyYWN0TmFtZSwgdGFibGUsIHF1ZXJ5LCAxMDAwLCBvZmZzZXQpOwogICAgaWYgKHJlc3VsdHMpIHsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRzLmxlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgYXdhaXQgY2FsbGJhY2socmVzdWx0c1tpXSk7CiAgICAgIH0KICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoIDwgMTAwMCkgewogICAgICAgIGRvbmUgPSB0cnVlOwogICAgICB9IGVsc2UgewogICAgICAgIG9mZnNldCArPSAxMDAwOwogICAgICB9CiAgICB9CiAgfQp9OwoKYXN5bmMgZnVuY3Rpb24gdmFsaWRhdGVOZnRQcm9wZXJ0aWVzKHByb3BlcnRpZXMpIHsKICBpZiAoIWFwaS5hc3NlcnQocHJvcGVydGllcyAmJiBBcnJheS5pc0FycmF5KHByb3BlcnRpZXMpLCAnaW52YWxpZCBuZnRUb2tlbk1pbmVyIHByb3BlcnRpZXMnKSkgcmV0dXJuIGZhbHNlOwogIGlmICghYXBpLmFzc2VydChwcm9wZXJ0aWVzLmxlbmd0aCA+IDAgJiYgcHJvcGVydGllcy5sZW5ndGggPD0gNCwgJ25mdFRva2VuTWluZXIgcHJvcGVydGllcyBzaXplIG11c3QgYmUgYmV0d2VlbiAxIGFuZCA0JykpIHJldHVybiBmYWxzZTsKCiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm9wZXJ0aWVzLmxlbmd0aDsgaSArPSAxKSB7CiAgICBjb25zdCBwcm9wID0gcHJvcGVydGllc1tpXTsKICAgIGNvbnN0IHByb3BLZXlzID0gT2JqZWN0LmtleXMocHJvcCk7CiAgICBmb3IgKGxldCBqID0gMDsgaiA8IHByb3BLZXlzLmxlbmd0aDsgaiArPSAxKSB7CiAgICAgIGNvbnN0IHByb3BLZXkgPSBwcm9wS2V5c1tqXTsKICAgICAgaWYgKHByb3BLZXkgPT09ICdvcCcpIHsKICAgICAgICBpZiAoIWFwaS5hc3NlcnQodHlwZW9mIHByb3Aub3AgPT09ICdzdHJpbmcnICYmIFBST1BFUlRZX09QU1twcm9wLm9wXSwgJ25mdFRva2VuTWluZXIgcHJvcGVydGllcyBvcCBzaG91bGQgYmUgQUREIG9yIE1VTFRJUExZJykpIHJldHVybiBmYWxzZTsKICAgICAgfSBlbHNlIGlmIChwcm9wS2V5ID09PSAnbmFtZScpIHsKICAgICAgICBpZiAoIWFwaS5hc3NlcnQodHlwZW9mIHByb3AubmFtZSA9PT0gJ3N0cmluZycgJiYgcHJvcC5uYW1lLmxlbmd0aCA8PSAxNiwgJ25mdFRva2VuTWluZXIgcHJvcGVydGllcyBuYW1lIHNob3VsZCBiZSBhIHN0cmluZyBvZiBsZW5ndGggPD0gMTYnKSkgcmV0dXJuIGZhbHNlOwogICAgICB9IGVsc2UgaWYgKHByb3BLZXkgPT09ICdidXJuQ2hhbmdlJykgewogICAgICAgIGlmICghYXBpLmFzc2VydCh0eXBlb2YgcHJvcC5idXJuQ2hhbmdlID09PSAnb2JqZWN0JwogICAgICAgICAgICAmJiB0eXBlb2YgcHJvcC5idXJuQ2hhbmdlLnN5bWJvbCA9PT0gJ3N0cmluZycKICAgICAgICAgICAgJiYgYXBpLkJpZ051bWJlcihwcm9wLmJ1cm5DaGFuZ2UucXVhbnRpdHkpLmlzRmluaXRlKCkKICAgICAgICAgICAgJiYgYXBpLkJpZ051bWJlcihwcm9wLmJ1cm5DaGFuZ2UucXVhbnRpdHkpLmlzUG9zaXRpdmUoKSwgJ25mdFRva2VuTWluZXIgcHJvcGVydGllcyBidXJuQ2hhbmdlIGludmFsaWQnKSkgcmV0dXJuIGZhbHNlOwogICAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAndG9rZW5zJywgeyBzeW1ib2w6IHByb3AuYnVybkNoYW5nZS5zeW1ib2wgfSk7CiAgICAgICAgaWYgKCFhcGkuYXNzZXJ0KHRva2VuLCAnbmZ0VG9rZW5NaW5lciBwcm9wZXJ0aWVzIGJ1cm5DaGFuZ2Ugc3ltYm9sIG5vdCBmb3VuZCcpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYXBpLmFzc2VydChmYWxzZSwgJ25mdFRva2VuTWluZXIgcHJvcGVydGllcyBmaWVsZCBpbnZhbGlkJyk7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiB0cnVlOwp9CgpmdW5jdGlvbiB2YWxpZGF0ZU5mdFR5cGVNYXAodHlwZU1hcCwgcHJvcGVydGllcykgewogIGlmICghYXBpLmFzc2VydCh0eXBlTWFwICYmIHR5cGVvZiB0eXBlTWFwID09PSAnb2JqZWN0JywgJ2ludmFsaWQgbmZ0VG9rZW5NaW5lciB0eXBlTWFwJykpIHJldHVybiBmYWxzZTsKICBjb25zdCB0eXBlcyA9IE9iamVjdC5rZXlzKHR5cGVNYXApOwogIGZvciAobGV0IGogPSAwOyBqIDwgdHlwZXMubGVuZ3RoOyBqICs9IDEpIHsKICAgIGNvbnN0IHR5cGUgPSB0eXBlc1tqXTsKICAgIGNvbnN0IHR5cGVDb25maWcgPSB0eXBlTWFwW3R5cGVdOwogICAgaWYgKCFhcGkuYXNzZXJ0KEFycmF5LmlzQXJyYXkodHlwZUNvbmZpZykgJiYgdHlwZUNvbmZpZy5sZW5ndGggPT09IHByb3BlcnRpZXMubGVuZ3RoLCAnbmZ0VG9rZW5NaW5lciB0eXBlQ29uZmlnIGxlbmd0aCBtaXNtYXRjaCcpKSByZXR1cm4gZmFsc2U7CiAgICBmb3IgKGxldCBrID0gMDsgayA8IHR5cGVDb25maWcubGVuZ3RoOyBrICs9IDEpIHsKICAgICAgY29uc3QgdHlwZVByb3BlcnR5ID0gYXBpLkJpZ051bWJlcih0eXBlQ29uZmlnW2tdKTsKICAgICAgaWYgKCFhcGkuYXNzZXJ0KCF0eXBlUHJvcGVydHkuaXNOYU4oKSAmJiB0eXBlUHJvcGVydHkuaXNGaW5pdGUoKSwgJ25mdFRva2VuTWluZXIgdHlwZUNvbmZpZyBpbnZhbGlkJykpIHJldHVybiBmYWxzZTsKICAgICAgaWYgKHByb3BlcnRpZXNba10ub3AgPT09ICdNVUxUSVBMWScpIHsKICAgICAgICBpZiAoIWFwaS5hc3NlcnQodHlwZVByb3BlcnR5Lmd0ZSgwLjAxKSAmJiB0eXBlUHJvcGVydHkubHRlKDEwMCksCiAgICAgICAgICAnbmZ0VG9rZW5NaW5lciB0eXBlQ29uZmlnIE1VTFRJUExZIHByb3BlcnR5IHNob3VsZCBiZSBiZXR3ZWVuIDAuMDEgYW5kIDEwMCcpKSByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIHRydWU7Cn0KCmFzeW5jIGZ1bmN0aW9uIHZhbGlkYXRlVG9rZW5NaW5lcnModG9rZW5NaW5lcnMsIG5mdFRva2VuTWluZXIpIHsKICBpZiAoIWFwaS5hc3NlcnQodG9rZW5NaW5lcnMgJiYgQXJyYXkuaXNBcnJheSh0b2tlbk1pbmVycyksICd0b2tlbk1pbmVycyBpbnZhbGlkJykpIHJldHVybiBmYWxzZTsKICBpZiAoIWFwaS5hc3NlcnQoKHRva2VuTWluZXJzLmxlbmd0aCA+PSAxICYmIHRva2VuTWluZXJzLmxlbmd0aCA8PSAyKQogICAgICB8fCAobmZ0VG9rZW5NaW5lciAmJiB0b2tlbk1pbmVycy5sZW5ndGggPT09IDApLAogICdvbmx5IDEgb3IgMiB0b2tlbk1pbmVycyBhbGxvd2VkJykpIHJldHVybiBmYWxzZTsKICBjb25zdCB0b2tlbk1pbmVyU3ltYm9scyA9IG5ldyBTZXQoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHRva2VuTWluZXJzLmxlbmd0aDsgaSArPSAxKSB7CiAgICBjb25zdCB0b2tlbk1pbmVyQ29uZmlnID0gdG9rZW5NaW5lcnNbaV07CiAgICBpZiAoIWFwaS5hc3NlcnQodG9rZW5NaW5lckNvbmZpZyAmJiB0b2tlbk1pbmVyQ29uZmlnLnN5bWJvbAogICAgICAmJiB0eXBlb2YgKHRva2VuTWluZXJDb25maWcuc3ltYm9sKSA9PT0gJ3N0cmluZycsICd0b2tlbk1pbmVycyBpbnZhbGlkJykpIHJldHVybiBmYWxzZTsKICAgIGlmICghYXBpLmFzc2VydCghdG9rZW5NaW5lclN5bWJvbHMuaGFzKHRva2VuTWluZXJDb25maWcuc3ltYm9sKSwgJ3Rva2VuTWluZXJzIGNhbm5vdCBoYXZlIGR1cGxpY2F0ZSBzeW1ib2xzJykpIHJldHVybiBmYWxzZTsKICAgIHRva2VuTWluZXJTeW1ib2xzLmFkZCh0b2tlbk1pbmVyQ29uZmlnLnN5bWJvbCk7CiAgICBjb25zdCB7IHN5bWJvbCB9ID0gdG9rZW5NaW5lckNvbmZpZzsKICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAndG9rZW5zJywgeyBzeW1ib2wgfSk7CiAgICBpZiAoIWFwaS5hc3NlcnQodG9rZW4gJiYgdG9rZW4uc3Rha2luZ0VuYWJsZWQsICd0b2tlbk1pbmVycyBtdXN0IGhhdmUgc3Rha2luZyBlbmFibGVkJykpIHJldHVybiBmYWxzZTsKICAgIGlmICghYXBpLmFzc2VydChOdW1iZXIuaXNJbnRlZ2VyKHRva2VuTWluZXJDb25maWcubXVsdGlwbGllcikKICAgICAgJiYgdG9rZW5NaW5lckNvbmZpZy5tdWx0aXBsaWVyID49IDEgJiYgdG9rZW5NaW5lckNvbmZpZy5tdWx0aXBsaWVyIDw9IDEwMCwKICAgICd0b2tlbk1pbmVyIG11bHRpcGxpZXIgbXVzdCBiZSBhbiBpbnRlZ2VyIGZyb20gMSB0byAxMDAnKSkgcmV0dXJuIGZhbHNlOwogIH0KICBpZiAobmZ0VG9rZW5NaW5lcikgewogICAgaWYgKCFhcGkuYXNzZXJ0KG5mdFRva2VuTWluZXIuc3ltYm9sCiAgICAgICAgJiYgdHlwZW9mIChuZnRUb2tlbk1pbmVyLnN5bWJvbCkgPT09ICdzdHJpbmcnLCAnbmZ0VG9rZW5NaW5lciBpbnZhbGlkJykpIHJldHVybiBmYWxzZTsKICAgIGNvbnN0IHsKICAgICAgc3ltYm9sLCB0eXBlTWFwLCBwcm9wZXJ0aWVzLCB0eXBlRmllbGQsCiAgICAgIGVxdWlwRmllbGQsIG1pbmluZ1Bvd2VyRmllbGQsCiAgICB9ID0gbmZ0VG9rZW5NaW5lcjsKICAgIGNvbnN0IG5mdCA9IGF3YWl0IGFwaS5kYi5maW5kT25lSW5UYWJsZSgnbmZ0JywgJ25mdHMnLCB7IHN5bWJvbCB9KTsKICAgIGlmICghYXBpLmFzc2VydChuZnQgJiYgbmZ0LmRlbGVnYXRpb25FbmFibGVkLCAnbmZ0VG9rZW5NaW5lciBtdXN0IGhhdmUgZGVsZWdhdGlvbiBlbmFibGVkJykpIHJldHVybiBmYWxzZTsKICAgIGlmICghYXBpLmFzc2VydCh0eXBlRmllbGQgJiYgdHlwZW9mIHR5cGVGaWVsZCA9PT0gJ3N0cmluZycsICd0eXBlRmllbGQgbXVzdCBiZSBhIHN0cmluZycpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAoIWFwaS5hc3NlcnQobmZ0LnByb3BlcnRpZXNbdHlwZUZpZWxkXSAmJiBuZnQucHJvcGVydGllc1t0eXBlRmllbGRdLnR5cGUgPT09ICdzdHJpbmcnLCAnbmZ0VG9rZW5NaW5lciBtdXN0IGhhdmUgc3RyaW5nIHR5cGUgcHJvcGVydHknKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKGVxdWlwRmllbGQgIT09IHVuZGVmaW5lZCkgewogICAgICBpZiAoIWFwaS5hc3NlcnQoZXF1aXBGaWVsZCAmJiB0eXBlb2YgZXF1aXBGaWVsZCA9PT0gJ3N0cmluZycsICdlcXVpcEZpZWxkIG11c3QgYmUgYSBzdHJpbmcnKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWFwaS5hc3NlcnQobmZ0LnByb3BlcnRpZXNbZXF1aXBGaWVsZF0gJiYgbmZ0LnByb3BlcnRpZXNbZXF1aXBGaWVsZF0udHlwZSA9PT0gJ3N0cmluZycsICduZnRUb2tlbk1pbmVyIG11c3QgaGF2ZSBzdHJpbmcgZXF1aXAgcHJvcGVydHknKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKG1pbmluZ1Bvd2VyRmllbGQgIT09IHVuZGVmaW5lZCkgewogICAgICBpZiAoIWFwaS5hc3NlcnQobWluaW5nUG93ZXJGaWVsZCAmJiB0eXBlb2YgbWluaW5nUG93ZXJGaWVsZCA9PT0gJ3N0cmluZycsICdtaW5pbmdQb3dlckZpZWxkIG11c3QgYmUgYSBzdHJpbmcnKSkgcmV0dXJuIGZhbHNlOwogICAgICBpZiAoIWFwaS5hc3NlcnQobmZ0LnByb3BlcnRpZXNbbWluaW5nUG93ZXJGaWVsZF0gJiYgbmZ0LnByb3BlcnRpZXNbbWluaW5nUG93ZXJGaWVsZF0udHlwZSA9PT0gJ3N0cmluZycsICduZnRUb2tlbk1pbmVyIG11c3QgaGF2ZSBzdHJpbmcgbWluaW5nUG93ZXIgcHJvcGVydHknKSkgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKCEoYXdhaXQgdmFsaWRhdGVOZnRQcm9wZXJ0aWVzKHByb3BlcnRpZXMpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCF2YWxpZGF0ZU5mdFR5cGVNYXAodHlwZU1hcCwgcHJvcGVydGllcykpIHJldHVybiBmYWxzZTsKICB9CiAgcmV0dXJuIHRydWU7Cn0KCmFzeW5jIGZ1bmN0aW9uIHZhbGlkYXRlVG9rZW5NaW5lcnNDaGFuZ2Uob2xkVG9rZW5NaW5lcnMsIHRva2VuTWluZXJzLCBvbGROZnRUb2tlbk1pbmVyLAogIG5mdFRva2VuTWluZXIpIHsKICBpZiAoIWFwaS5hc3NlcnQodG9rZW5NaW5lcnMubGVuZ3RoID09PSBvbGRUb2tlbk1pbmVycy5sZW5ndGgsICdjYW5ub3QgY2hhbmdlIHdoaWNoIHRva2VucyBhcmUgaW4gdG9rZW5NaW5lcnMnKSkgcmV0dXJuIGZhbHNlOwogIGxldCBjaGFuZ2VkID0gZmFsc2U7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b2tlbk1pbmVycy5sZW5ndGg7IGkgKz0gMSkgewogICAgY29uc3Qgb2xkQ29uZmlnID0gb2xkVG9rZW5NaW5lcnNbaV07CiAgICBjb25zdCBuZXdDb25maWcgPSB0b2tlbk1pbmVyc1tpXTsKICAgIGlmICghYXBpLmFzc2VydChvbGRDb25maWcuc3ltYm9sID09PSBuZXdDb25maWcuc3ltYm9sLCAnY2Fubm90IGNoYW5nZSB3aGljaCB0b2tlbnMgYXJlIGluIHRva2VuTWluZXJzJykpIHJldHVybiBmYWxzZTsKICAgIGlmICghYXBpLmFzc2VydChOdW1iZXIuaXNJbnRlZ2VyKG5ld0NvbmZpZy5tdWx0aXBsaWVyKSAmJiBuZXdDb25maWcubXVsdGlwbGllciA+PSAxICYmIG5ld0NvbmZpZy5tdWx0aXBsaWVyIDw9IDEwMCwgJ3Rva2VuTWluZXIgbXVsdGlwbGllciBtdXN0IGJlIGFuIGludGVnZXIgZnJvbSAxIHRvIDEwMCcpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAob2xkQ29uZmlnLm11bHRpcGxpZXIgIT09IG5ld0NvbmZpZy5tdWx0aXBsaWVyKSB7CiAgICAgIGNoYW5nZWQgPSB0cnVlOwogICAgfQogIH0KICBpZiAoIWFwaS5hc3NlcnQoISFvbGROZnRUb2tlbk1pbmVyID09PSAhIW5mdFRva2VuTWluZXIsICdjYW5ub3QgY2hhbmdlIG5mdFRva2VuTWluZXIgdG9rZW4nKSkgcmV0dXJuIGZhbHNlOwogIGlmIChuZnRUb2tlbk1pbmVyKSB7CiAgICBpZiAoIWFwaS5hc3NlcnQob2xkTmZ0VG9rZW5NaW5lci5zeW1ib2wgPT09IG5mdFRva2VuTWluZXIuc3ltYm9sLCAnY2Fubm90IGNoYW5nZSBuZnRUb2tlbk1pbmVyIHRva2VuJykpIHJldHVybiBmYWxzZTsKICAgIGNvbnN0IHsKICAgICAgdHlwZU1hcCwgcHJvcGVydGllcywgdHlwZUZpZWxkLCBlcXVpcEZpZWxkLCBtaW5pbmdQb3dlckZpZWxkLAogICAgfSA9IG5mdFRva2VuTWluZXI7CiAgICBpZiAoIWFwaS5hc3NlcnQodHlwZUZpZWxkICYmIHR5cGVvZiB0eXBlRmllbGQgPT09ICdzdHJpbmcnCiAgICAgICAgJiYgdHlwZUZpZWxkID09PSBvbGROZnRUb2tlbk1pbmVyLnR5cGVGaWVsZCwgJ2Nhbm5vdCBjaGFuZ2UgbmZ0VG9rZW5NaW5lciB0eXBlRmllbGQnKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKG9sZE5mdFRva2VuTWluZXIuZXF1aXBGaWVsZCkgewogICAgICBpZiAoIWFwaS5hc3NlcnQoZXF1aXBGaWVsZCAmJiB0eXBlb2YgZXF1aXBGaWVsZCA9PT0gJ3N0cmluZycKICAgICAgICAgICYmIGVxdWlwRmllbGQgPT09IG9sZE5mdFRva2VuTWluZXIuZXF1aXBGaWVsZCwgJ2Nhbm5vdCBjaGFuZ2UgbmZ0VG9rZW5NaW5lciBlcXVpcEZpZWxkJykpIHJldHVybiBmYWxzZTsKICAgIH0gZWxzZSBpZiAoIWFwaS5hc3NlcnQoIWVxdWlwRmllbGQsICdjYW5ub3QgY2hhbmdlIG5mdFRva2VuTWluZXIgZXF1aXBGaWVsZCcpKSByZXR1cm4gZmFsc2U7CiAgICBpZiAob2xkTmZ0VG9rZW5NaW5lci5taW5pbmdQb3dlckZpZWxkKSB7CiAgICAgIGlmICghYXBpLmFzc2VydChtaW5pbmdQb3dlckZpZWxkICYmIHR5cGVvZiBtaW5pbmdQb3dlckZpZWxkID09PSAnc3RyaW5nJwogICAgICAgICAgICAmJiBtaW5pbmdQb3dlckZpZWxkID09PSBvbGROZnRUb2tlbk1pbmVyLm1pbmluZ1Bvd2VyRmllbGQsICdjYW5ub3QgY2hhbmdlIG5mdFRva2VuTWluZXIgbWluaW5nUG93ZXJGaWVsZCcpKSByZXR1cm4gZmFsc2U7CiAgICB9IGVsc2UgaWYgKCFhcGkuYXNzZXJ0KCFtaW5pbmdQb3dlckZpZWxkLCAnY2Fubm90IGNoYW5nZSBuZnRUb2tlbk1pbmVyIG1pbmluZ1Bvd2VyRmllbGQnKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCFhcGkuYXNzZXJ0KHR5cGVNYXAgJiYgdHlwZW9mIHR5cGVNYXAgPT09ICdvYmplY3QnLCAnaW52YWxpZCBuZnRUb2tlbk1pbmVyIHR5cGVNYXAnKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKCEoYXdhaXQgdmFsaWRhdGVOZnRQcm9wZXJ0aWVzKHByb3BlcnRpZXMpKSkgcmV0dXJuIGZhbHNlOwogICAgaWYgKHByb3BlcnRpZXMubGVuZ3RoICE9PSBvbGROZnRUb2tlbk1pbmVyLnByb3BlcnRpZXMubGVuZ3RoKSB7CiAgICAgIGNoYW5nZWQgPSB0cnVlOwogICAgfSBlbHNlIHsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm9wZXJ0aWVzLmxlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgY29uc3QgcHJvcCA9IHByb3BlcnRpZXNbaV07CiAgICAgICAgY29uc3Qgb2xkUHJvcCA9IG9sZE5mdFRva2VuTWluZXIucHJvcGVydGllc1tpXTsKICAgICAgICBpZiAocHJvcC5vcCAhPT0gb2xkUHJvcC5vcCkgY2hhbmdlZCA9IHRydWU7CiAgICAgIH0KICAgIH0KICAgIGlmICghdmFsaWRhdGVOZnRUeXBlTWFwKHR5cGVNYXAsIHByb3BlcnRpZXMpKSByZXR1cm4gZmFsc2U7CiAgICBjb25zdCBvbGRUeXBlcyA9IE9iamVjdC5rZXlzKG9sZE5mdFRva2VuTWluZXIudHlwZU1hcCk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9sZFR5cGVzLmxlbmd0aDsgaSArPSAxKSB7CiAgICAgIGNvbnN0IG9sZFR5cGUgPSBvbGRUeXBlc1tpXTsKICAgICAgY29uc3Qgb2xkVHlwZUNvbmZpZyA9IG9sZE5mdFRva2VuTWluZXIudHlwZU1hcFtvbGRUeXBlXTsKICAgICAgY29uc3QgdHlwZUNvbmZpZyA9IHR5cGVNYXBbb2xkVHlwZV07CiAgICAgIGlmICghYXBpLmFzc2VydCh0eXBlQ29uZmlnLCAndHlwZUNvbmZpZyB0eXBlcyBtdXN0IGJlIGEgc3VwZXJzZXQgb2Ygb2xkIHR5cGVDb25maWcgdHlwZXMnKSkgcmV0dXJuIGZhbHNlOwogICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHR5cGVDb25maWcubGVuZ3RoOyBqICs9IDEpIHsKICAgICAgICBpZiAob2xkVHlwZUNvbmZpZ1tqXSAhPT0gdHlwZUNvbmZpZ1tqXSkgY2hhbmdlZCA9IHRydWU7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIHsgY2hhbmdlZCB9Owp9CgpmdW5jdGlvbiBjb21wdXRlTWluaW5nUG93ZXIobWluaW5nUG93ZXIsIHRva2VuTWluZXJzLCBuZnRUb2tlbk1pbmVyKSB7CiAgbGV0IHBvd2VyID0gYXBpLkJpZ051bWJlcigwKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHRva2VuTWluZXJzLmxlbmd0aDsgaSArPSAxKSB7CiAgICBpZiAobWluaW5nUG93ZXIuYmFsYW5jZXNbaV0pIHsKICAgICAgcG93ZXIgPSBwb3dlci5wbHVzKGFwaS5CaWdOdW1iZXIobWluaW5nUG93ZXIuYmFsYW5jZXNbaV0pCiAgICAgICAgLm11bHRpcGxpZWRCeSh0b2tlbk1pbmVyc1tpXS5tdWx0aXBsaWVyKSk7CiAgICB9CiAgfQogIGlmIChuZnRUb2tlbk1pbmVyICYmIG1pbmluZ1Bvd2VyLm5mdEJhbGFuY2VzKSB7CiAgICBsZXQgbmZ0UG93ZXIgPSBhcGkuQmlnTnVtYmVyKDEpOwogICAgLy8gTm90ZSBuZnRCYWxhbmNlcyBpcyBvYmplY3QgdHlwZS4KICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmZ0VG9rZW5NaW5lci5wcm9wZXJ0aWVzLmxlbmd0aDsgaSArPSAxKSB7CiAgICAgIG5mdFBvd2VyID0gbmZ0UG93ZXIubXVsdGlwbGllZEJ5KG1pbmluZ1Bvd2VyLm5mdEJhbGFuY2VzW2ldKS5kcChNQVhfRElHSVRTKTsKICAgIH0KICAgIGlmICghbmZ0UG93ZXIuaXNGaW5pdGUoKSkgewogICAgICBuZnRQb3dlciA9IGFwaS5CaWdOdW1iZXIoMCk7CiAgICB9CiAgICBpZiAobWluaW5nUG93ZXIubmZ0QmFsYW5jZXNbTUlOSU5HX1BPV0VSX0ZJRUxEX0lOREVYXSkgewogICAgICBuZnRQb3dlciA9IG5mdFBvd2VyLnBsdXMobWluaW5nUG93ZXIubmZ0QmFsYW5jZXNbTUlOSU5HX1BPV0VSX0ZJRUxEX0lOREVYXSk7CiAgICB9CiAgICBwb3dlciA9IHBvd2VyLnBsdXMobmZ0UG93ZXIpOwogIH0KICBpZiAocG93ZXIuaXNQb3NpdGl2ZSgpICYmIHBvd2VyLmlzRmluaXRlKCkpIHsKICAgIHJldHVybiBwb3dlcjsKICB9CiAgcmV0dXJuIGFwaS5CaWdOdW1iZXIoMCk7Cn0KCmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZU1pbmluZ1Bvd2VyKAogIHBvb2wsIHRva2VuLCBhY2NvdW50LCBzdGFrZWRRdWFudGl0eSwgZGVsZWdhdGVkUXVhbnRpdHksIHVwZGF0ZVBvb2xUaW1lc3RhbXAsCikgewogIGxldCBtaW5pbmdQb3dlciA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdtaW5pbmdQb3dlcicsIHsgaWQ6IHBvb2wuaWQsIGFjY291bnQgfSk7CiAgbGV0IHN0YWtlID0gYXBpLkJpZ051bWJlcihzdGFrZWRRdWFudGl0eSk7CiAgbGV0IG9sZE1pbmluZ1Bvd2VyID0gYXBpLkJpZ051bWJlcigwKTsKICBzdGFrZSA9IHN0YWtlLnBsdXMoZGVsZWdhdGVkUXVhbnRpdHkpOwogIGNvbnN0IHRva2VuSW5kZXggPSBwb29sLnRva2VuTWluZXJzLmZpbmRJbmRleCh0ID0+IHQuc3ltYm9sID09PSB0b2tlbik7CiAgaWYgKCFtaW5pbmdQb3dlcikgewogICAgY29uc3QgYmFsYW5jZXMgPSB7fTsKICAgIGJhbGFuY2VzW3Rva2VuSW5kZXhdID0gc3Rha2U7CiAgICBtaW5pbmdQb3dlciA9IHsKICAgICAgaWQ6IHBvb2wuaWQsCiAgICAgIGFjY291bnQsCiAgICAgIGJhbGFuY2VzLAogICAgICBwb3dlcjogeyAkbnVtYmVyRGVjaW1hbDogJzAnIH0sCiAgICB9OwogICAgbWluaW5nUG93ZXIgPSBhd2FpdCBhcGkuZGIuaW5zZXJ0KCdtaW5pbmdQb3dlcicsIG1pbmluZ1Bvd2VyKTsKICB9IGVsc2UgewogICAgaWYgKHVwZGF0ZVBvb2xUaW1lc3RhbXAgJiYgbWluaW5nUG93ZXIudXBkYXRlUG9vbFRpbWVzdGFtcCAhPT0gdXBkYXRlUG9vbFRpbWVzdGFtcCkgewogICAgICAvLyByZXNldCBhbGwgYmFsYW5jZXMKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwb29sLnRva2VuTWluZXJzLmxlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgbWluaW5nUG93ZXIuYmFsYW5jZXNbaV0gPSAnMCc7CiAgICAgIH0KICAgICAgaWYgKG1pbmluZ1Bvd2VyLm5mdEJhbGFuY2VzKSB7CiAgICAgICAgbWluaW5nUG93ZXIubmZ0QmFsYW5jZXMgPSB7fTsKICAgICAgICBjb25zdCB7IG5mdEJhbGFuY2VzIH0gPSBtaW5pbmdQb3dlcjsKICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHBvb2wubmZ0VG9rZW5NaW5lci5wcm9wZXJ0aWVzLmxlbmd0aDsgaiArPSAxKSB7CiAgICAgICAgICBjb25zdCBwcm9wZXJ0eSA9IHBvb2wubmZ0VG9rZW5NaW5lci5wcm9wZXJ0aWVzW2pdOwogICAgICAgICAgY29uc3Qgb3BJbmZvID0gUFJPUEVSVFlfT1BTW3Byb3BlcnR5Lm9wXTsKICAgICAgICAgIG5mdEJhbGFuY2VzW2pdID0gb3BJbmZvLmRlZmF1bHRWYWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoIW1pbmluZ1Bvd2VyLmJhbGFuY2VzW3Rva2VuSW5kZXhdKSB7CiAgICAgIG1pbmluZ1Bvd2VyLmJhbGFuY2VzW3Rva2VuSW5kZXhdID0gJzAnOwogICAgfQogICAgb2xkTWluaW5nUG93ZXIgPSBjb21wdXRlTWluaW5nUG93ZXIobWluaW5nUG93ZXIsIHBvb2wudG9rZW5NaW5lcnMsIHBvb2wubmZ0VG9rZW5NaW5lcik7CiAgICBtaW5pbmdQb3dlci5iYWxhbmNlc1t0b2tlbkluZGV4XSA9IHN0YWtlLnBsdXMobWluaW5nUG93ZXIuYmFsYW5jZXNbdG9rZW5JbmRleF0pOwogIH0KICBjb25zdCBuZXdNaW5pbmdQb3dlciA9IGNvbXB1dGVNaW5pbmdQb3dlcihtaW5pbmdQb3dlciwgcG9vbC50b2tlbk1pbmVycywgcG9vbC5uZnRUb2tlbk1pbmVyKTsKICBtaW5pbmdQb3dlci5wb3dlciA9IHsgJG51bWJlckRlY2ltYWw6IG5ld01pbmluZ1Bvd2VyIH07CiAgaWYgKHVwZGF0ZVBvb2xUaW1lc3RhbXApIHsKICAgIG1pbmluZ1Bvd2VyLnVwZGF0ZVBvb2xUaW1lc3RhbXAgPSB1cGRhdGVQb29sVGltZXN0YW1wOwogIH0KICBhd2FpdCBhcGkuZGIudXBkYXRlKCdtaW5pbmdQb3dlcicsIG1pbmluZ1Bvd2VyKTsKICByZXR1cm4gbmV3TWluaW5nUG93ZXIubWludXMob2xkTWluaW5nUG93ZXIpOwp9CgpmdW5jdGlvbiBnZXROZnRBY2NvdW50KG5mdCkgewogIGlmIChuZnQuZGVsZWdhdGVkVG8uYWNjb3VudCA9PT0gJ21pbmluZycgJiYgbmZ0LmRlbGVnYXRlZFRvLm93bmVkQnkgPT09ICdjJykgewogICAgcmV0dXJuIG5mdC5hY2NvdW50OwogIH0gaWYgKG5mdC5kZWxlZ2F0ZWRUby5vd25lZEJ5ID09PSAndScpIHsKICAgIHJldHVybiBuZnQuZGVsZWdhdGVkVG8uYWNjb3VudDsKICB9CiAgcmV0dXJuIG51bGw7Cn0KCmZ1bmN0aW9uIHNhbml0aXplTmZ0TWluaW5nUG93ZXIobmZ0TWluaW5nUG93ZXIpIHsKICBsZXQgZXh0cmFOZnRNaW5pbmdQb3dlciA9IGFwaS5CaWdOdW1iZXIobmZ0TWluaW5nUG93ZXIpOwogIGlmIChleHRyYU5mdE1pbmluZ1Bvd2VyLmlzTmFOKCkgfHwgIWV4dHJhTmZ0TWluaW5nUG93ZXIuaXNGaW5pdGUoKSkgewogICAgZXh0cmFOZnRNaW5pbmdQb3dlciA9IGFwaS5CaWdOdW1iZXIoMCk7CiAgfQogIHJldHVybiBleHRyYU5mdE1pbmluZ1Bvd2VyLmRwKE1BWF9ESUdJVFMpOwp9CgovKioKICogUGFyYW1zOgogKiAgIC0gcG9vbDogcmV3YXJkIHBvb2wgb2JqZWN0CiAqICAgLSBuZnQ6IG5mdCBpbnN0YW5jZQogKiAgIC0gYWRkOiB3aGV0aGVyIHRvIGFkZCBvciByZW1vdmUgdGhlIG5mdAogKiAgIC0gdXBkYXRlUG9vbFRpbWVzdGFtcDogY29udHJvbHMgd2hldGhlciB0byByZXNldCB0aGUgbWluaW5nIHBvd2VyIChkdXJpbmcgYSBuZXcgdXBkYXRlIHJlcXVlc3QpCiAqICAgLSBhY2NvdW50T3ZlcnJpZGU6IG9wdGlvbmFsIG92ZXJyaWRlLCB1c2VkIGZvciBlcXVpcEZpZWxkIHBvb2xzCiAqLwphc3luYyBmdW5jdGlvbiB1cGRhdGVOZnRNaW5pbmdQb3dlcihwb29sLCBuZnQsIGFkZCwgdXBkYXRlUG9vbFRpbWVzdGFtcCwgYWNjb3VudE92ZXJyaWRlKSB7CiAgY29uc3QgYWNjb3VudCA9IGFjY291bnRPdmVycmlkZSB8fCBnZXROZnRBY2NvdW50KG5mdCk7CgogIGlmICghYWNjb3VudCkgcmV0dXJuIGFwaS5CaWdOdW1iZXIoMCk7CgogIGxldCBtaW5pbmdQb3dlciA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdtaW5pbmdQb3dlcicsIHsgaWQ6IHBvb2wuaWQsIGFjY291bnQgfSk7CiAgbGV0IG9sZE1pbmluZ1Bvd2VyID0gYXBpLkJpZ051bWJlcigwKTsKICBsZXQgZXh0cmFOZnRNaW5pbmdQb3dlciA9IGFwaS5CaWdOdW1iZXIoMCk7CiAgY29uc3QgewogICAgdHlwZU1hcCwKICAgIHByb3BlcnRpZXMsCiAgICB0eXBlRmllbGQsCiAgICBlcXVpcEZpZWxkLAogICAgbWluaW5nUG93ZXJGaWVsZCwKICB9ID0gcG9vbC5uZnRUb2tlbk1pbmVyOwoKICBjb25zdCBuZnRUeXBlID0gbmZ0LnByb3BlcnRpZXNbdHlwZUZpZWxkXTsKICBjb25zdCB0eXBlUHJvcGVydGllcyA9IHR5cGVNYXBbbmZ0VHlwZV07CiAgaWYgKG1pbmluZ1Bvd2VyRmllbGQpIHsKICAgIGV4dHJhTmZ0TWluaW5nUG93ZXIgPSBzYW5pdGl6ZU5mdE1pbmluZ1Bvd2VyKG5mdC5wcm9wZXJ0aWVzW21pbmluZ1Bvd2VyRmllbGRdKTsKICB9CiAgaWYgKCFtaW5pbmdQb3dlcikgewogICAgY29uc3QgbmZ0QmFsYW5jZXMgPSB7fTsKICAgIGNvbnN0IGVxdWlwcGVkTmZ0ID0geyB0eXBlOiBuZnRUeXBlIH07CgogICAgaWYgKHR5cGVQcm9wZXJ0aWVzKSB7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvcGVydGllcy5sZW5ndGg7IGkgKz0gMSkgewogICAgICAgIGNvbnN0IHByb3BlcnR5ID0gcHJvcGVydGllc1tpXTsKICAgICAgICBjb25zdCBvcEluZm8gPSBQUk9QRVJUWV9PUFNbcHJvcGVydHkub3BdOwogICAgICAgIGlmIChhZGQpIHsKICAgICAgICAgIG5mdEJhbGFuY2VzW2ldID0gb3BJbmZvLmFkZChvcEluZm8uZGVmYXVsdFZhbHVlLCB0eXBlUHJvcGVydGllc1tpXSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGFwaS5hc3NlcnQoZmFsc2UsICd1bmV4cGVjdGVkIGNvbmRpdGlvbjogcmVtb3ZlIHdpdGhvdXQgcHJldmlvdXMgbWluaW5nUG93ZXInKTsKICAgICAgICAgIHJldHVybiBhcGkuQmlnTnVtYmVyKDApOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgaWYgKG1pbmluZ1Bvd2VyRmllbGQpIHsKICAgICAgbmZ0QmFsYW5jZXNbTUlOSU5HX1BPV0VSX0ZJRUxEX0lOREVYXSA9IGV4dHJhTmZ0TWluaW5nUG93ZXI7CiAgICAgIGVxdWlwcGVkTmZ0LmV4dHJhTWluaW5nUG93ZXIgPSBleHRyYU5mdE1pbmluZ1Bvd2VyOwogICAgfQogICAgY29uc3QgZXF1aXBwZWROZnRzID0ge307CiAgICBlcXVpcHBlZE5mdHNbbmZ0Ll9pZF0gPSBlcXVpcHBlZE5mdDsKICAgIG1pbmluZ1Bvd2VyID0gewogICAgICBpZDogcG9vbC5pZCwKICAgICAgYWNjb3VudCwKICAgICAgYmFsYW5jZXM6IHt9LAogICAgICBuZnRCYWxhbmNlcywKICAgICAgcG93ZXI6IHsgJG51bWJlckRlY2ltYWw6ICcwJyB9LAogICAgICBlcXVpcHBlZE5mdHMsCiAgICB9OwogICAgbWluaW5nUG93ZXIgPSBhd2FpdCBhcGkuZGIuaW5zZXJ0KCdtaW5pbmdQb3dlcicsIG1pbmluZ1Bvd2VyKTsKICB9IGVsc2UgewogICAgaWYgKCFtaW5pbmdQb3dlci5uZnRCYWxhbmNlcykgewogICAgICBtaW5pbmdQb3dlci5uZnRCYWxhbmNlcyA9IHt9OwogICAgfQogICAgaWYgKCFtaW5pbmdQb3dlci5lcXVpcHBlZE5mdHMpIHsKICAgICAgbWluaW5nUG93ZXIuZXF1aXBwZWROZnRzID0ge307CiAgICB9CiAgICBjb25zdCBvbGRFeHRyYU5mdE1pbmluZ1Bvd2VyID0gMDsKICAgIGxldCBlcXVpcHBlZE5mdCA9IG1pbmluZ1Bvd2VyLmVxdWlwcGVkTmZ0c1tuZnQuX2lkXTsKICAgIGlmICghZXF1aXBwZWROZnQpIHsKICAgICAgLy8gSWYgdXNpbmcgZXF1aXAgZmllbGQsIHZlcmlmeSBhbHJlYWR5IHRyYWNrZWQgaW4gZXF1aXBwZWROZnRzCiAgICAgIC8vIFRoaXMgY29uZGl0aW9uIGNhbiBoYXBwZW4gaWYgYW4gTkZUIGlzIGlzc3VlZCB3aXRoIGVxdWlwIGZpZWxkIHBvcHVsYXRlZCB1cCBmcm9udC4KICAgICAgaWYgKGVxdWlwRmllbGQgJiYgIWFkZCkgewogICAgICAgIHJldHVybiBhcGkuQmlnTnVtYmVyKDApOwogICAgICB9CgogICAgICBlcXVpcHBlZE5mdCA9IHsgdHlwZTogbmZ0VHlwZSB9OwogICAgICBtaW5pbmdQb3dlci5lcXVpcHBlZE5mdHNbbmZ0Ll9pZF0gPSBlcXVpcHBlZE5mdDsKICAgIH0KICAgIGNvbnN0IHsgbmZ0QmFsYW5jZXMgfSA9IG1pbmluZ1Bvd2VyOwogICAgaWYgKHR5cGVQcm9wZXJ0aWVzKSB7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvcGVydGllcy5sZW5ndGg7IGkgKz0gMSkgewogICAgICAgIGNvbnN0IHByb3BlcnR5ID0gcHJvcGVydGllc1tpXTsKICAgICAgICBjb25zdCBvcEluZm8gPSBQUk9QRVJUWV9PUFNbcHJvcGVydHkub3BdOwogICAgICAgIGlmICghbmZ0QmFsYW5jZXNbaV0gfHwgbWluaW5nUG93ZXIudXBkYXRlUG9vbFRpbWVzdGFtcCAhPT0gdXBkYXRlUG9vbFRpbWVzdGFtcCkgewogICAgICAgICAgbmZ0QmFsYW5jZXNbaV0gPSBvcEluZm8uZGVmYXVsdFZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgaWYgKG1pbmluZ1Bvd2VyRmllbGQgJiYgbWluaW5nUG93ZXIudXBkYXRlUG9vbFRpbWVzdGFtcCAhPT0gdXBkYXRlUG9vbFRpbWVzdGFtcCkgewogICAgICBuZnRCYWxhbmNlc1tNSU5JTkdfUE9XRVJfRklFTERfSU5ERVhdID0gYXBpLkJpZ051bWJlcigwKTsKICAgIH0KICAgIG9sZE1pbmluZ1Bvd2VyID0gY29tcHV0ZU1pbmluZ1Bvd2VyKG1pbmluZ1Bvd2VyLCBwb29sLnRva2VuTWluZXJzLCBwb29sLm5mdFRva2VuTWluZXIpOwogICAgaWYgKHR5cGVQcm9wZXJ0aWVzKSB7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJvcGVydGllcy5sZW5ndGg7IGkgKz0gMSkgewogICAgICAgIGNvbnN0IHByb3BlcnR5ID0gcHJvcGVydGllc1tpXTsKICAgICAgICBjb25zdCBvcEluZm8gPSBQUk9QRVJUWV9PUFNbcHJvcGVydHkub3BdOwogICAgICAgIGlmIChhZGQpIHsKICAgICAgICAgIG5mdEJhbGFuY2VzW2ldID0gb3BJbmZvLmFkZChuZnRCYWxhbmNlc1tpXSwgdHlwZVByb3BlcnRpZXNbaV0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBuZnRCYWxhbmNlc1tpXSA9IG9wSW5mby5yZW1vdmUobmZ0QmFsYW5jZXNbaV0sIHR5cGVQcm9wZXJ0aWVzW2ldKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGlmIChtaW5pbmdQb3dlckZpZWxkKSB7CiAgICAgIGlmICghbmZ0QmFsYW5jZXNbTUlOSU5HX1BPV0VSX0ZJRUxEX0lOREVYXSkgewogICAgICAgIG5mdEJhbGFuY2VzW01JTklOR19QT1dFUl9GSUVMRF9JTkRFWF0gPSBhcGkuQmlnTnVtYmVyKDApOwogICAgICB9CiAgICAgIGlmIChhZGQpIHsKICAgICAgICBlcXVpcHBlZE5mdC5leHRyYU1pbmluZ1Bvd2VyID0gZXh0cmFOZnRNaW5pbmdQb3dlcjsKICAgICAgICBuZnRCYWxhbmNlc1tNSU5JTkdfUE9XRVJfRklFTERfSU5ERVhdID0gYXBpLkJpZ051bWJlcihuZnRCYWxhbmNlc1tNSU5JTkdfUE9XRVJfRklFTERfSU5ERVhdKQogICAgICAgICAgLm1pbnVzKG9sZEV4dHJhTmZ0TWluaW5nUG93ZXIpCiAgICAgICAgICAucGx1cyhleHRyYU5mdE1pbmluZ1Bvd2VyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBuZnRCYWxhbmNlc1tNSU5JTkdfUE9XRVJfRklFTERfSU5ERVhdID0gYXBpLkJpZ051bWJlcihuZnRCYWxhbmNlc1tNSU5JTkdfUE9XRVJfRklFTERfSU5ERVhdKQogICAgICAgICAgLm1pbnVzKGV4dHJhTmZ0TWluaW5nUG93ZXIpOwogICAgICB9CiAgICB9CiAgfQogIGNvbnN0IG5ld01pbmluZ1Bvd2VyID0gY29tcHV0ZU1pbmluZ1Bvd2VyKG1pbmluZ1Bvd2VyLCBwb29sLnRva2VuTWluZXJzLCBwb29sLm5mdFRva2VuTWluZXIpOwogIG1pbmluZ1Bvd2VyLnBvd2VyID0geyAkbnVtYmVyRGVjaW1hbDogbmV3TWluaW5nUG93ZXIgfTsKICBtaW5pbmdQb3dlci51cGRhdGVQb29sVGltZXN0YW1wID0gdXBkYXRlUG9vbFRpbWVzdGFtcDsKICBpZiAoIWFkZCkgewogICAgZGVsZXRlIG1pbmluZ1Bvd2VyLmVxdWlwcGVkTmZ0c1tuZnQuX2lkXTsKICB9CiAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnbWluaW5nUG93ZXInLCBtaW5pbmdQb3dlcik7CgogIHJldHVybiBuZXdNaW5pbmdQb3dlci5taW51cyhvbGRNaW5pbmdQb3dlcik7Cn0KCmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZU5mdE1pbmluZ1Bvd2VyRnJvbVByb3BlcnR5VXBkYXRlKHBvb2wsIG5mdCwgYWNjb3VudE92ZXJyaWRlKSB7CiAgY29uc3QgYWNjb3VudCA9IGFjY291bnRPdmVycmlkZSB8fCBnZXROZnRBY2NvdW50KG5mdCk7CgogIGlmICghYWNjb3VudCkgcmV0dXJuIGFwaS5CaWdOdW1iZXIoMCk7CgogIGxldCBtaW5pbmdQb3dlciA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdtaW5pbmdQb3dlcicsIHsgaWQ6IHBvb2wuaWQsIGFjY291bnQgfSk7CiAgbGV0IG9sZE1pbmluZ1Bvd2VyID0gYXBpLkJpZ051bWJlcigwKTsKICBsZXQgZXh0cmFOZnRNaW5pbmdQb3dlciA9IGFwaS5CaWdOdW1iZXIoMCk7CiAgY29uc3QgewogICAgdHlwZUZpZWxkLAogICAgZXF1aXBGaWVsZCwKICAgIG1pbmluZ1Bvd2VyRmllbGQsCiAgfSA9IHBvb2wubmZ0VG9rZW5NaW5lcjsKCiAgY29uc3QgbmZ0VHlwZSA9IG5mdC5wcm9wZXJ0aWVzW3R5cGVGaWVsZF07CiAgaWYgKG1pbmluZ1Bvd2VyRmllbGQpIHsKICAgIGV4dHJhTmZ0TWluaW5nUG93ZXIgPSBzYW5pdGl6ZU5mdE1pbmluZ1Bvd2VyKG5mdC5wcm9wZXJ0aWVzW21pbmluZ1Bvd2VyRmllbGRdKTsKICB9IGVsc2UgewogICAgcmV0dXJuIGFwaS5CaWdOdW1iZXIoMCk7CiAgfQogIGlmICghbWluaW5nUG93ZXIpIHsKICAgIGNvbnN0IG5mdEJhbGFuY2VzID0ge307CiAgICBjb25zdCBlcXVpcHBlZE5mdCA9IHsgdHlwZTogbmZ0VHlwZSB9OwoKICAgIG5mdEJhbGFuY2VzW01JTklOR19QT1dFUl9GSUVMRF9JTkRFWF0gPSBleHRyYU5mdE1pbmluZ1Bvd2VyOwogICAgZXF1aXBwZWROZnQuZXh0cmFNaW5pbmdQb3dlciA9IGV4dHJhTmZ0TWluaW5nUG93ZXI7CiAgICBjb25zdCBlcXVpcHBlZE5mdHMgPSB7fTsKICAgIGVxdWlwcGVkTmZ0c1tuZnQuX2lkXSA9IGVxdWlwcGVkTmZ0OwogICAgbWluaW5nUG93ZXIgPSB7CiAgICAgIGlkOiBwb29sLmlkLAogICAgICBhY2NvdW50LAogICAgICBiYWxhbmNlczoge30sCiAgICAgIG5mdEJhbGFuY2VzLAogICAgICBwb3dlcjogeyAkbnVtYmVyRGVjaW1hbDogJzAnIH0sCiAgICAgIGVxdWlwcGVkTmZ0cywKICAgIH07CiAgICBtaW5pbmdQb3dlciA9IGF3YWl0IGFwaS5kYi5pbnNlcnQoJ21pbmluZ1Bvd2VyJywgbWluaW5nUG93ZXIpOwogIH0gZWxzZSB7CiAgICBpZiAoIW1pbmluZ1Bvd2VyLm5mdEJhbGFuY2VzKSB7CiAgICAgIG1pbmluZ1Bvd2VyLm5mdEJhbGFuY2VzID0ge307CiAgICB9CiAgICBpZiAoIW1pbmluZ1Bvd2VyLmVxdWlwcGVkTmZ0cykgewogICAgICBtaW5pbmdQb3dlci5lcXVpcHBlZE5mdHMgPSB7fTsKICAgIH0KICAgIGxldCBvbGRFeHRyYU5mdE1pbmluZ1Bvd2VyID0gMDsKICAgIGxldCBlcXVpcHBlZE5mdCA9IG1pbmluZ1Bvd2VyLmVxdWlwcGVkTmZ0c1tuZnQuX2lkXTsKICAgIGlmICghZXF1aXBwZWROZnQpIHsKICAgICAgLy8gSWYgdXNpbmcgZXF1aXAgZmllbGQsIHZlcmlmeSBhbHJlYWR5IHRyYWNrZWQgaW4gZXF1aXBwZWROZnRzCiAgICAgIC8vIFRoaXMgY29uZGl0aW9uIGNhbiBoYXBwZW4gaWYgYW4gTkZUIGlzIGlzc3VlZCB3aXRoIGVxdWlwIGZpZWxkIHBvcHVsYXRlZCB1cCBmcm9udC4KICAgICAgaWYgKGVxdWlwRmllbGQpIHsKICAgICAgICByZXR1cm4gYXBpLkJpZ051bWJlcigwKTsKICAgICAgfQoKICAgICAgZXF1aXBwZWROZnQgPSB7IHR5cGU6IG5mdFR5cGUgfTsKICAgICAgbWluaW5nUG93ZXIuZXF1aXBwZWROZnRzW25mdC5faWRdID0gZXF1aXBwZWROZnQ7CiAgICB9IGVsc2UgewogICAgICBvbGRFeHRyYU5mdE1pbmluZ1Bvd2VyID0gZXF1aXBwZWROZnQuZXh0cmFNaW5pbmdQb3dlcjsKICAgIH0KICAgIGNvbnN0IHsgbmZ0QmFsYW5jZXMgfSA9IG1pbmluZ1Bvd2VyOwogICAgb2xkTWluaW5nUG93ZXIgPSBjb21wdXRlTWluaW5nUG93ZXIobWluaW5nUG93ZXIsIHBvb2wudG9rZW5NaW5lcnMsIHBvb2wubmZ0VG9rZW5NaW5lcik7CiAgICBpZiAoIW5mdEJhbGFuY2VzW01JTklOR19QT1dFUl9GSUVMRF9JTkRFWF0pIHsKICAgICAgbmZ0QmFsYW5jZXNbTUlOSU5HX1BPV0VSX0ZJRUxEX0lOREVYXSA9IGFwaS5CaWdOdW1iZXIoMCk7CiAgICB9CiAgICBlcXVpcHBlZE5mdC5leHRyYU1pbmluZ1Bvd2VyID0gZXh0cmFOZnRNaW5pbmdQb3dlcjsKICAgIG5mdEJhbGFuY2VzW01JTklOR19QT1dFUl9GSUVMRF9JTkRFWF0gPSBhcGkuQmlnTnVtYmVyKG5mdEJhbGFuY2VzW01JTklOR19QT1dFUl9GSUVMRF9JTkRFWF0pCiAgICAgIC5taW51cyhvbGRFeHRyYU5mdE1pbmluZ1Bvd2VyKQogICAgICAucGx1cyhleHRyYU5mdE1pbmluZ1Bvd2VyKTsKICB9CiAgY29uc3QgbmV3TWluaW5nUG93ZXIgPSBjb21wdXRlTWluaW5nUG93ZXIobWluaW5nUG93ZXIsIHBvb2wudG9rZW5NaW5lcnMsIHBvb2wubmZ0VG9rZW5NaW5lcik7CiAgbWluaW5nUG93ZXIucG93ZXIgPSB7ICRudW1iZXJEZWNpbWFsOiBuZXdNaW5pbmdQb3dlciB9OwogIGF3YWl0IGFwaS5kYi51cGRhdGUoJ21pbmluZ1Bvd2VyJywgbWluaW5nUG93ZXIpOwoKICByZXR1cm4gbmV3TWluaW5nUG93ZXIubWludXMob2xkTWluaW5nUG93ZXIpOwp9Cgphc3luYyBmdW5jdGlvbiBpbml0TWluaW5nUG93ZXIocG9vbCwgdXBkYXRlUG9vbFRpbWVzdGFtcCwgcGFyYW1zLCB0b2tlbiwgbGFzdElkKSB7CiAgbGV0IGFkanVzdGVkUG93ZXIgPSBhcGkuQmlnTnVtYmVyKDApOwogIGxldCBvZmZzZXQgPSAwOwogIGxldCBsYXN0SWRQcm9jZXNzZWQgPSBsYXN0SWQ7CiAgbGV0IGNvbXBsZXRlID0gZmFsc2U7CiAgbGV0IGJhbGFuY2VzOwogIHdoaWxlICghY29tcGxldGUgJiYgb2Zmc2V0IDwgcGFyYW1zLm1heEJhbGFuY2VzUHJvY2Vzc2VkUGVyQmxvY2spIHsKICAgIGJhbGFuY2VzID0gYXdhaXQgYXBpLmRiLmZpbmRJblRhYmxlKCd0b2tlbnMnLCAnYmFsYW5jZXMnLCB7IHN5bWJvbDogdG9rZW4sIF9pZDogeyAkZ3Q6IGxhc3RJZCB9IH0sIHBhcmFtcy5wcm9jZXNzUXVlcnlMaW1pdCwgb2Zmc2V0LCBbeyBpbmRleDogJ19pZCcsIGRlc2NlbmRpbmc6IGZhbHNlIH1dKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmFsYW5jZXMubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgY29uc3QgYmFsYW5jZSA9IGJhbGFuY2VzW2ldOwogICAgICBpZiAoYXBpLkJpZ051bWJlcihiYWxhbmNlLnN0YWtlKS5ndCgwKSB8fCBhcGkuQmlnTnVtYmVyKGJhbGFuY2UuZGVsZWdhdGlvbnNJbikuZ3QoMCkpIHsKICAgICAgICBjb25zdCBhZGp1c3RlZCA9IGF3YWl0IHVwZGF0ZU1pbmluZ1Bvd2VyKAogICAgICAgICAgcG9vbCwgdG9rZW4sIGJhbGFuY2UuYWNjb3VudCwgYmFsYW5jZS5zdGFrZSwgYmFsYW5jZS5kZWxlZ2F0aW9uc0luLCB1cGRhdGVQb29sVGltZXN0YW1wLAogICAgICAgICk7CiAgICAgICAgYWRqdXN0ZWRQb3dlciA9IGFkanVzdGVkUG93ZXIucGx1cyhhZGp1c3RlZCk7CiAgICAgIH0KICAgICAgbGFzdElkUHJvY2Vzc2VkID0gYmFsYW5jZS5faWQ7CiAgICB9CiAgICBpZiAoYmFsYW5jZXMubGVuZ3RoIDwgcGFyYW1zLnByb2Nlc3NRdWVyeUxpbWl0KSB7CiAgICAgIGNvbXBsZXRlID0gdHJ1ZTsKICAgIH0KICAgIG9mZnNldCArPSBwYXJhbXMucHJvY2Vzc1F1ZXJ5TGltaXQ7CiAgfQogIHJldHVybiB7IGFkanVzdGVkUG93ZXIsIG5leHRJZDogbGFzdElkUHJvY2Vzc2VkLCBjb21wbGV0ZSB9Owp9Cgphc3luYyBmdW5jdGlvbiBpbml0TmZ0TWluaW5nUG93ZXIocG9vbCwgdXBkYXRlUG9vbFRpbWVzdGFtcCwgcGFyYW1zLCBuZnRUb2tlbk1pbmVyLCBsYXN0SWQpIHsKICBsZXQgYWRqdXN0ZWRQb3dlciA9IGFwaS5CaWdOdW1iZXIoMCk7CiAgbGV0IG9mZnNldCA9IDA7CiAgbGV0IGxhc3RJZFByb2Nlc3NlZCA9IGxhc3RJZDsKICBsZXQgY29tcGxldGUgPSBmYWxzZTsKICBsZXQgbmZ0czsKICBjb25zdCB7CiAgICBzeW1ib2wsCiAgICBlcXVpcEZpZWxkLAogIH0gPSBuZnRUb2tlbk1pbmVyOwogIHdoaWxlICghY29tcGxldGUgJiYgb2Zmc2V0IDwgcGFyYW1zLm1heEJhbGFuY2VzUHJvY2Vzc2VkUGVyQmxvY2spIHsKICAgIGNvbnN0IG5mdFF1ZXJ5ID0gewogICAgICBfaWQ6IHsgJGd0OiBsYXN0SWQgfSwKICAgIH07CiAgICBpZiAoZXF1aXBGaWVsZCkgewogICAgICBuZnRRdWVyeVtgcHJvcGVydGllcy4ke2VxdWlwRmllbGR9YF0gPSB7ICRleGlzdHM6IHRydWUsICRuZTogJycgfTsKICAgIH0gZWxzZSB7CiAgICAgIG5mdFF1ZXJ5LmRlbGVnYXRlZFRvID0geyAkbmU6IG51bGwgfTsKICAgICAgbmZ0UXVlcnlbJ2RlbGVnYXRlZFRvLnVuZGVsZWdhdGVBdCddID0geyAkZXE6IG51bGwgfTsKICAgIH0KICAgIG5mdHMgPSBhd2FpdCBhcGkuZGIuZmluZEluVGFibGUoJ25mdCcsIGAke3N5bWJvbH1pbnN0YW5jZXNgLCBuZnRRdWVyeSwgcGFyYW1zLnByb2Nlc3NRdWVyeUxpbWl0LCBvZmZzZXQsIFt7IGluZGV4OiAnX2lkJywgZGVzY2VuZGluZzogZmFsc2UgfV0pOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZnRzLmxlbmd0aDsgaSArPSAxKSB7CiAgICAgIGNvbnN0IG5mdCA9IG5mdHNbaV07CiAgICAgIGlmICghZXF1aXBGaWVsZCB8fCBuZnQucHJvcGVydGllc1tlcXVpcEZpZWxkXSkgewogICAgICAgIGNvbnN0IGFkanVzdGVkID0gYXdhaXQgdXBkYXRlTmZ0TWluaW5nUG93ZXIoCiAgICAgICAgICBwb29sLAogICAgICAgICAgbmZ0LAogICAgICAgICAgLyogYWRkICovIHRydWUsCiAgICAgICAgICB1cGRhdGVQb29sVGltZXN0YW1wLAogICAgICAgICAgZXF1aXBGaWVsZCA/IG5mdC5wcm9wZXJ0aWVzW2VxdWlwRmllbGRdIDogbnVsbCwKICAgICAgICApOwogICAgICAgIGFkanVzdGVkUG93ZXIgPSBhZGp1c3RlZFBvd2VyLnBsdXMoYWRqdXN0ZWQpOwogICAgICB9CiAgICAgIGxhc3RJZFByb2Nlc3NlZCA9IG5mdC5faWQ7CiAgICB9CiAgICBpZiAobmZ0cy5sZW5ndGggPCBwYXJhbXMucHJvY2Vzc1F1ZXJ5TGltaXQpIHsKICAgICAgY29tcGxldGUgPSB0cnVlOwogICAgfQogICAgb2Zmc2V0ICs9IHBhcmFtcy5wcm9jZXNzUXVlcnlMaW1pdDsKICB9CiAgcmV0dXJuIHsgYWRqdXN0ZWRQb3dlciwgbmV4dElkOiBsYXN0SWRQcm9jZXNzZWQsIGNvbXBsZXRlIH07Cn0KCmFzeW5jIGZ1bmN0aW9uIHJlc3VtZVBvd2VyVXBkYXRlKHBvb2wsIHBhcmFtcykgewogIGxldCB7CiAgICBpblByb2dyZXNzLCB0b2tlbkluZGV4LCBuZnRUb2tlbkluZGV4LCBsYXN0SWQsCiAgfSA9IHBvb2wudXBkYXRpbmc7CiAgY29uc3QgeyB1cGRhdGVQb29sVGltZXN0YW1wIH0gPSBwb29sLnVwZGF0aW5nOwogIGlmICghaW5Qcm9ncmVzcykgewogICAgcmV0dXJuOwogIH0KCiAgaWYgKHRva2VuSW5kZXggPCBwb29sLnRva2VuTWluZXJzLmxlbmd0aCkgewogICAgY29uc3QgdG9rZW5Db25maWcgPSBwb29sLnRva2VuTWluZXJzW3Rva2VuSW5kZXhdOwogICAgY29uc3QgeyBhZGp1c3RlZFBvd2VyLCBuZXh0SWQsIGNvbXBsZXRlIH0gPSBhd2FpdCBpbml0TWluaW5nUG93ZXIoCiAgICAgIHBvb2wsIHVwZGF0ZVBvb2xUaW1lc3RhbXAsIHBhcmFtcywgdG9rZW5Db25maWcuc3ltYm9sLCBsYXN0SWQsCiAgICApOwogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduCiAgICBwb29sLnRvdGFsUG93ZXIgPSBhcGkuQmlnTnVtYmVyKHBvb2wudG90YWxQb3dlcikKICAgICAgLnBsdXMoYWRqdXN0ZWRQb3dlcik7CiAgICBpZiAoY29tcGxldGUpIHsKICAgICAgbGFzdElkID0gMDsKICAgICAgdG9rZW5JbmRleCArPSAxOwogICAgfSBlbHNlIHsKICAgICAgbGFzdElkID0gbmV4dElkOwogICAgfQogIH0gZWxzZSBpZiAocG9vbC5uZnRUb2tlbk1pbmVyICYmIG5mdFRva2VuSW5kZXggPCAxKSB7CiAgICBjb25zdCB7IG5mdFRva2VuTWluZXIgfSA9IHBvb2w7CiAgICBjb25zdCB7IGFkanVzdGVkUG93ZXIsIG5leHRJZCwgY29tcGxldGUgfSA9IGF3YWl0IGluaXROZnRNaW5pbmdQb3dlcigKICAgICAgcG9vbCwgdXBkYXRlUG9vbFRpbWVzdGFtcCwgcGFyYW1zLCBuZnRUb2tlbk1pbmVyLCBsYXN0SWQsCiAgICApOwogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduCiAgICBwb29sLnRvdGFsUG93ZXIgPSBhcGkuQmlnTnVtYmVyKHBvb2wudG90YWxQb3dlcikKICAgICAgLnBsdXMoYWRqdXN0ZWRQb3dlcik7CiAgICBpZiAoY29tcGxldGUpIHsKICAgICAgbGFzdElkID0gMDsKICAgICAgbmZ0VG9rZW5JbmRleCArPSAxOwogICAgfSBlbHNlIHsKICAgICAgbGFzdElkID0gbmV4dElkOwogICAgfQogIH0KCiAgaWYgKHRva2VuSW5kZXggPT09IHBvb2wudG9rZW5NaW5lcnMubGVuZ3RoCiAgICAgICYmICghcG9vbC5uZnRUb2tlbk1pbmVyIHx8IG5mdFRva2VuSW5kZXggPT09IDEpKSB7CiAgICBpblByb2dyZXNzID0gZmFsc2U7CiAgICB0b2tlbkluZGV4ID0gMDsKICAgIG5mdFRva2VuSW5kZXggPSAwOwogIH0KCiAgY29uc3QgeyB1cGRhdGluZyB9ID0gcG9vbDsKICB1cGRhdGluZy5pblByb2dyZXNzID0gaW5Qcm9ncmVzczsKICB1cGRhdGluZy50b2tlbkluZGV4ID0gdG9rZW5JbmRleDsKICB1cGRhdGluZy5uZnRUb2tlbkluZGV4ID0gbmZ0VG9rZW5JbmRleDsKICB1cGRhdGluZy5sYXN0SWQgPSBsYXN0SWQ7CiAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncG9vbHMnLCBwb29sKTsKfQoKYWN0aW9ucy5zZXRBY3RpdmUgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIGlkLAogICAgYWN0aXZlLAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoIWFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykpIHsKICAgIHJldHVybjsKICB9CiAgY29uc3QgcG9vbCA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwb29scycsIHsgaWQgfSk7CiAgaWYgKCFhcGkuYXNzZXJ0KHBvb2wsICdwb29sIGlkIG5vdCBmb3VuZCcpKSB7CiAgICByZXR1cm47CiAgfQogIGNvbnN0IG1pbmVkVG9rZW5PYmplY3QgPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ3Rva2VucycsICd0b2tlbnMnLCB7IHN5bWJvbDogcG9vbC5taW5lZFRva2VuIH0pOwogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10ZW1wbGF0ZS1jdXJseS1pbi1zdHJpbmcKICBpZiAoIWFwaS5hc3NlcnQobWluZWRUb2tlbk9iamVjdCAmJiAobWluZWRUb2tlbk9iamVjdC5pc3N1ZXIgPT09IGFwaS5zZW5kZXIgfHwgKG1pbmVkVG9rZW5PYmplY3Quc3ltYm9sID09PSAiQkVFIiAmJiBhcGkuc2VuZGVyID09PSBhcGkub3duZXIpKSwgJ211c3QgYmUgaXNzdWVyIG9mIG1pbmVkVG9rZW4nKSkgewogICAgcmV0dXJuOwogIH0KCiAgY29uc3QgeyBuZnRUb2tlbk1pbmVyIH0gPSBwb29sOwogIGlmIChuZnRUb2tlbk1pbmVyKSB7CiAgICBjb25zdCBuZnRUb2tlblBvb2wgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnbmZ0VG9rZW5Qb29scycsIHsgc3ltYm9sOiBuZnRUb2tlbk1pbmVyLnN5bWJvbCwgaWQ6IHBvb2wuaWQgfSk7CiAgICBpZiAoYWN0aXZlICYmICFuZnRUb2tlblBvb2wpIHsKICAgICAgY29uc3Qgb3RoZXJOZnRUb2tlblBvb2xzID0gYXdhaXQgYXBpLmRiLmZpbmQoJ25mdFRva2VuUG9vbHMnLCB7IHN5bWJvbDogbmZ0VG9rZW5NaW5lci5zeW1ib2wgfSk7CiAgICAgIGlmICghYXBpLmFzc2VydCghb3RoZXJOZnRUb2tlblBvb2xzIHx8IG90aGVyTmZ0VG9rZW5Qb29scy5sZW5ndGggPCAyLCAnY2FuIGhhdmUgYXQgbW9zdCAyIGFjdGl2ZSBuZnQgdG9rZW4gcG9vbHMgZm9yIG5mdCB0b2tlbicpKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgIGF3YWl0IGFwaS5kYi5pbnNlcnQoJ25mdFRva2VuUG9vbHMnLCB7IHN5bWJvbDogbmZ0VG9rZW5NaW5lci5zeW1ib2wsIGlkOiBwb29sLmlkIH0pOwogICAgfSBlbHNlIGlmICghYWN0aXZlICYmIG5mdFRva2VuUG9vbCkgewogICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCduZnRUb2tlblBvb2xzJywgbmZ0VG9rZW5Qb29sKTsKICAgIH0KICB9CiAgcG9vbC5hY3RpdmUgPSAhIWFjdGl2ZTsKICBjb25zdCBibG9ja0RhdGUgPSBuZXcgRGF0ZShgJHthcGkuaGl2ZUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgcG9vbC5uZXh0TG90dGVyeVRpbWVzdGFtcCA9IGFwaS5CaWdOdW1iZXIoYmxvY2tEYXRlLmdldFRpbWUoKSkKICAgIC5wbHVzKHBvb2wubG90dGVyeUludGVydmFsSG91cnMgKiAzNjAwICogMTAwMCkudG9OdW1iZXIoKTsKICBhd2FpdCBhcGkuZGIudXBkYXRlKCdwb29scycsIHBvb2wpOwp9OwoKYWN0aW9ucy51cGRhdGVQb29sID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBpZCwgbG90dGVyeVdpbm5lcnMsIGxvdHRlcnlJbnRlcnZhbEhvdXJzLCBsb3R0ZXJ5QW1vdW50LCB0b2tlbk1pbmVycywKICAgIG5mdFRva2VuTWluZXIsIGNhbGxpbmdDb250cmFjdEluZm8sIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgLy8gZ2V0IGNvbnRyYWN0IHBhcmFtcwogIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CiAgY29uc3QgeyBwb29sVXBkYXRlRmVlIH0gPSBwYXJhbXM7CiAgLy8gZ2V0IGFwaS5zZW5kZXIncyBVVElMSVRZX1RPS0VOX1NZTUJPTCBiYWxhbmNlCiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXRlbXBsYXRlLWN1cmx5LWluLXN0cmluZwogIGNvbnN0IHV0aWxpdHlUb2tlbkJhbGFuY2UgPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ3Rva2VucycsICdiYWxhbmNlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgc3ltYm9sOiAiQkVFIiB9KTsKCiAgY29uc3QgYXV0aG9yaXplZCA9IGFwaS5CaWdOdW1iZXIocG9vbFVwZGF0ZUZlZSkubHRlKDApIHx8IGFwaS5zZW5kZXIgPT09IGFwaS5vd25lcgogICAgPyB0cnVlCiAgICA6IHV0aWxpdHlUb2tlbkJhbGFuY2UgJiYgYXBpLkJpZ051bWJlcih1dGlsaXR5VG9rZW5CYWxhbmNlLmJhbGFuY2UpLmd0ZShwb29sVXBkYXRlRmVlKTsKCiAgaWYgKGFwaS5hc3NlcnQoYXV0aG9yaXplZCwgJ3lvdSBtdXN0IGhhdmUgZW5vdWdoIHRva2VucyB0byBjb3ZlciB0aGUgdXBkYXRlIGZlZScpCiAgICAmJiBhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KGlkICYmIHR5cGVvZiBpZCA9PT0gJ3N0cmluZycKICAgICAgJiYgbG90dGVyeUFtb3VudCAmJiB0eXBlb2YgbG90dGVyeUFtb3VudCA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIobG90dGVyeUFtb3VudCkuaXNOYU4oKSAmJiBhcGkuQmlnTnVtYmVyKGxvdHRlcnlBbW91bnQpLmd0KDApLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgaWYgKGFwaS5hc3NlcnQoTnVtYmVyLmlzSW50ZWdlcihsb3R0ZXJ5V2lubmVycykgJiYgbG90dGVyeVdpbm5lcnMgPj0gMSAmJiBsb3R0ZXJ5V2lubmVycyA8PSAyMCwgJ2ludmFsaWQgbG90dGVyeVdpbm5lcnM6IGludGVnZXIgYmV0d2VlbiAxIGFuZCAyMCBvbmx5JykKICAgICAgJiYgYXBpLmFzc2VydChOdW1iZXIuaXNJbnRlZ2VyKGxvdHRlcnlJbnRlcnZhbEhvdXJzKSAmJiBsb3R0ZXJ5SW50ZXJ2YWxIb3VycyA+PSAxICYmIGxvdHRlcnlJbnRlcnZhbEhvdXJzIDw9IDcyMCwgJ2ludmFsaWQgbG90dGVyeUludGVydmFsSG91cnM6IGludGVnZXIgYmV0d2VlbiAxIGFuZCA3MjAgb25seScpKSB7CiAgICAgIGNvbnN0IHBvb2wgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncG9vbHMnLCB7IGlkIH0pOwogICAgICBpZiAoYXBpLmFzc2VydChwb29sLCAncG9vbCBpZCBub3QgZm91bmQnKSkgewogICAgICAgIGNvbnN0IG1pbmVkVG9rZW5PYmplY3QgPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ3Rva2VucycsICd0b2tlbnMnLCB7IHN5bWJvbDogcG9vbC5taW5lZFRva2VuIH0pOwogICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10ZW1wbGF0ZS1jdXJseS1pbi1zdHJpbmcKICAgICAgICBpZiAoYXBpLmFzc2VydChtaW5lZFRva2VuT2JqZWN0ICYmIChtaW5lZFRva2VuT2JqZWN0Lmlzc3VlciA9PT0gYXBpLnNlbmRlciB8fCAobWluZWRUb2tlbk9iamVjdC5zeW1ib2wgPT09ICJCRUUiICYmIGFwaS5zZW5kZXIgPT09IGFwaS5vd25lcikpLCAnbXVzdCBiZSBpc3N1ZXIgb2YgbWluZWRUb2tlbicpCiAgICAgICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIobG90dGVyeUFtb3VudCkuZHAoKSA8PSBtaW5lZFRva2VuT2JqZWN0LnByZWNpc2lvbiwgJ21pbmVkVG9rZW4gcHJlY2lzaW9uIG1pc21hdGNoIGZvciBsb3R0ZXJ5QW1vdW50JykpIHsKICAgICAgICAgIGlmICghY2FsbGluZ0NvbnRyYWN0SW5mbykgewogICAgICAgICAgICBjb25zdCB2YWxpZE1pbmVyc0NoYW5nZSA9IGF3YWl0IHZhbGlkYXRlVG9rZW5NaW5lcnNDaGFuZ2UoCiAgICAgICAgICAgICAgcG9vbC50b2tlbk1pbmVycywgdG9rZW5NaW5lcnMsIHBvb2wubmZ0VG9rZW5NaW5lciwgbmZ0VG9rZW5NaW5lciwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKHZhbGlkTWluZXJzQ2hhbmdlKSB7CiAgICAgICAgICAgICAgcG9vbC5sb3R0ZXJ5V2lubmVycyA9IGxvdHRlcnlXaW5uZXJzOwogICAgICAgICAgICAgIHBvb2wubG90dGVyeUludGVydmFsSG91cnMgPSBsb3R0ZXJ5SW50ZXJ2YWxIb3VyczsKICAgICAgICAgICAgICBwb29sLmxvdHRlcnlBbW91bnQgPSBsb3R0ZXJ5QW1vdW50OwogICAgICAgICAgICAgIHBvb2wudG9rZW5NaW5lcnMgPSB0b2tlbk1pbmVyczsKICAgICAgICAgICAgICBwb29sLm5mdFRva2VuTWluZXIgPSBuZnRUb2tlbk1pbmVyOwoKICAgICAgICAgICAgICBjb25zdCBibG9ja0RhdGUgPSBuZXcgRGF0ZShgJHthcGkuaGl2ZUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CgogICAgICAgICAgICAgIGlmICh2YWxpZE1pbmVyc0NoYW5nZS5jaGFuZ2VkKSB7CiAgICAgICAgICAgICAgICBwb29sLnVwZGF0aW5nLnVwZGF0ZVBvb2xUaW1lc3RhbXAgPSBhcGkuQmlnTnVtYmVyKGJsb2NrRGF0ZS5nZXRUaW1lKCkpLnRvTnVtYmVyKCk7CiAgICAgICAgICAgICAgICBwb29sLnVwZGF0aW5nLmluUHJvZ3Jlc3MgPSB0cnVlOwogICAgICAgICAgICAgICAgcG9vbC51cGRhdGluZy50b2tlbkluZGV4ID0gMDsKICAgICAgICAgICAgICAgIHBvb2wudXBkYXRpbmcubmZ0VG9rZW5JbmRleCA9IDA7CiAgICAgICAgICAgICAgICBwb29sLnVwZGF0aW5nLmxhc3RJZCA9IDA7CiAgICAgICAgICAgICAgICBwb29sLnRvdGFsUG93ZXIgPSAnMCc7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBwb29sLm5leHRMb3R0ZXJ5VGltZXN0YW1wID0gYXBpLkJpZ051bWJlcihibG9ja0RhdGUuZ2V0VGltZSgpKQogICAgICAgICAgICAgICAgLnBsdXMobG90dGVyeUludGVydmFsSG91cnMgKiAzNjAwICogMTAwMCkudG9OdW1iZXIoKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcG9vbC5sb3R0ZXJ5V2lubmVycyA9IGxvdHRlcnlXaW5uZXJzOwogICAgICAgICAgICBwb29sLmxvdHRlcnlJbnRlcnZhbEhvdXJzID0gbG90dGVyeUludGVydmFsSG91cnM7CiAgICAgICAgICAgIHBvb2wubG90dGVyeUFtb3VudCA9IGxvdHRlcnlBbW91bnQ7CiAgICAgICAgICB9CiAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdwb29scycsIHBvb2wpOwoKICAgICAgICAgIC8vIGJ1cm4gdGhlIHRva2VuIGNyZWF0aW9uIGZlZXMKICAgICAgICAgIGlmIChhcGkuc2VuZGVyICE9PSBhcGkub3duZXIgJiYgYXBpLkJpZ051bWJlcihwb29sVXBkYXRlRmVlKS5ndCgwKSkgewogICAgICAgICAgICBhd2FpdCBhcGkuZXhlY3V0ZVNtYXJ0Q29udHJhY3QoJ3Rva2VucycsICd0cmFuc2ZlcicsIHsKICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdGVtcGxhdGUtY3VybHktaW4tc3RyaW5nCiAgICAgICAgICAgICAgdG86ICdudWxsJywgc3ltYm9sOiAiQkVFIiwgcXVhbnRpdHk6IHBvb2xVcGRhdGVGZWUsIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy5jaGFuZ2VOZnRQcm9wZXJ0eSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgaWQsIHR5cGUsIHByb3BlcnR5TmFtZSwgY2hhbmdlQW1vdW50LAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoIWFwaS5hc3NlcnQoaWQgJiYgdHlwZW9mIGlkID09PSAnc3RyaW5nJwogICAgICAmJiB0eXBlICYmIHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJwogICAgICAmJiBwcm9wZXJ0eU5hbWUgJiYgdHlwZW9mIHByb3BlcnR5TmFtZSA9PT0gJ3N0cmluZycKICAgICAgJiYgY2hhbmdlQW1vdW50ICYmIHR5cGVvZiBjaGFuZ2VBbW91bnQgPT09ICdzdHJpbmcnCiAgICAgICYmICFhcGkuQmlnTnVtYmVyKGNoYW5nZUFtb3VudCkuaXNOYU4oKQogICAgICAmJiBhcGkuQmlnTnVtYmVyKGNoYW5nZUFtb3VudCkuaXNGaW5pdGUoKSwgJ2ludmFsaWQgcGFyYW1zJykpIHJldHVybjsKICBpZiAoIWFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykpIHJldHVybjsKCiAgY29uc3QgcG9vbCA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwb29scycsIHsgaWQgfSk7CiAgaWYgKCFhcGkuYXNzZXJ0KHBvb2wsICdwb29sIGlkIG5vdCBmb3VuZCcpKSByZXR1cm47CgogIGNvbnN0IHByb3BlcnR5SW5kZXggPSBwb29sLm5mdFRva2VuTWluZXIucHJvcGVydGllcy5maW5kSW5kZXgocCA9PiBwLm5hbWUgPT09IHByb3BlcnR5TmFtZSk7CiAgY29uc3QgcHJvcGVydHkgPSBwb29sLm5mdFRva2VuTWluZXIucHJvcGVydGllc1twcm9wZXJ0eUluZGV4XTsKICBpZiAoIWFwaS5hc3NlcnQocHJvcGVydHkgJiYgcHJvcGVydHkuYnVybkNoYW5nZSwgJ3Byb3BlcnR5IG5vdCBlbmFibGVkIGZvciBidXJuIGNoYW5nZScpKSByZXR1cm47CgogIGNvbnN0IHR5cGVQcm9wZXJ0aWVzID0gcG9vbC5uZnRUb2tlbk1pbmVyLnR5cGVNYXBbdHlwZV07CiAgaWYgKCFhcGkuYXNzZXJ0KHR5cGVQcm9wZXJ0aWVzLCAndHlwZSBub3QgZm91bmQnKSkgcmV0dXJuOwoKICBjb25zdCBidXJuU3ltYm9sID0gcHJvcGVydHkuYnVybkNoYW5nZS5zeW1ib2w7CiAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ3Rva2VucycsICd0b2tlbnMnLCB7IHN5bWJvbDogYnVyblN5bWJvbCB9KTsKCiAgY29uc3QgZmVlID0gYXBpLkJpZ051bWJlcihjaGFuZ2VBbW91bnQpLmFicygpLm11bHRpcGxpZWRCeShwcm9wZXJ0eS5idXJuQ2hhbmdlLnF1YW50aXR5KTsKCiAgaWYgKCFhcGkuYXNzZXJ0KGZlZS5kcCgpIDw9IHRva2VuLnByZWNpc2lvbiwgYGZlZSBwcmVjaXNpb24gbWlzbWF0Y2ggZm9yIGFtb3VudCAke2ZlZX1gKSkgcmV0dXJuOwoKICBjb25zdCBiYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAnYmFsYW5jZXMnLCB7IGFjY291bnQ6IGFwaS5zZW5kZXIsIHN5bWJvbDogYnVyblN5bWJvbCB9KTsKICBjb25zdCBhdXRob3JpemVkID0gYXBpLkJpZ051bWJlcihmZWUpLmx0ZSgwKQogICAgICAgIHx8IChiYWxhbmNlICYmIGFwaS5CaWdOdW1iZXIoYmFsYW5jZS5iYWxhbmNlKS5ndGUoZmVlKSk7CgogIGlmICghYXBpLmFzc2VydChhdXRob3JpemVkLCBgeW91IG11c3QgaGF2ZSBlbm91Z2ggdG9rZW5zIHRvIGNvdmVyIHRoZSB1cGRhdGUgZmVlIG9mICR7ZmVlfSAke2J1cm5TeW1ib2x9YCkpIHJldHVybjsKCiAgdHlwZVByb3BlcnRpZXNbcHJvcGVydHlJbmRleF0gPSBhcGkuQmlnTnVtYmVyKHR5cGVQcm9wZXJ0aWVzW3Byb3BlcnR5SW5kZXhdKS5wbHVzKGNoYW5nZUFtb3VudCk7CgogIGlmICghdmFsaWRhdGVOZnRUeXBlTWFwKHBvb2wubmZ0VG9rZW5NaW5lci50eXBlTWFwLCBwb29sLm5mdFRva2VuTWluZXIucHJvcGVydGllcykpIHJldHVybjsKCiAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLmhpdmVCbG9ja1RpbWVzdGFtcH0uMDAwWmApOwogIHBvb2wudXBkYXRpbmcudXBkYXRlUG9vbFRpbWVzdGFtcCA9IGFwaS5CaWdOdW1iZXIoYmxvY2tEYXRlLmdldFRpbWUoKSkudG9OdW1iZXIoKTsKICBwb29sLnVwZGF0aW5nLmluUHJvZ3Jlc3MgPSB0cnVlOwogIHBvb2wudXBkYXRpbmcudG9rZW5JbmRleCA9IDA7CiAgcG9vbC51cGRhdGluZy5uZnRUb2tlbkluZGV4ID0gMDsKICBwb29sLnVwZGF0aW5nLmxhc3RJZCA9IDA7CiAgcG9vbC50b3RhbFBvd2VyID0gJzAnOwoKICBhd2FpdCBhcGkuZGIudXBkYXRlKCdwb29scycsIHBvb2wpOwoKICAvLyBidXJuIHRoZSB0b2tlbiBjcmVhdGlvbiBmZWVzCiAgaWYgKGFwaS5CaWdOdW1iZXIoZmVlKS5ndCgwKSkgewogICAgYXdhaXQgYXBpLmV4ZWN1dGVTbWFydENvbnRyYWN0KCd0b2tlbnMnLCAndHJhbnNmZXInLCB7CiAgICAgIHRvOiAnbnVsbCcsIHN5bWJvbDogYnVyblN5bWJvbCwgcXVhbnRpdHk6IGZlZSwgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogICAgfSk7CiAgfQp9OwoKZnVuY3Rpb24gZ2VuZXJhdGVQb29sSWQocG9vbCkgewogIGNvbnN0IHRva2VuTWluZXJTdHJpbmcgPSBwb29sLmV4dGVybmFsQ29udHJhY3QgJiYgcG9vbC5leHRlcm5hbE1pbmVycwogICAgPyBgRVhULSR7cG9vbC5leHRlcm5hbE1pbmVycy5yZXBsYWNlKCc6JywgJycpfWAKICAgIDogcG9vbC50b2tlbk1pbmVycy5tYXAodCA9PiB0LnN5bWJvbC5yZXBsYWNlKCcuJywgJy0nKSkuc29ydCgpLmpvaW4oJywnKTsKICBjb25zdCBuZnRUb2tlbk1pbmVyU3RyaW5nID0gcG9vbC5uZnRUb2tlbk1pbmVyID8gYDoke3Bvb2wubmZ0VG9rZW5NaW5lci5zeW1ib2x9YCA6ICcnOwogIHJldHVybiBgJHtwb29sLm1pbmVkVG9rZW4ucmVwbGFjZSgnLicsICctJyl9OiR7dG9rZW5NaW5lclN0cmluZ30ke25mdFRva2VuTWluZXJTdHJpbmd9YDsKfQoKYWN0aW9ucy5jcmVhdGVQb29sID0gYXN5bmMgKHBheWxvYWQpID0+IHsKICBjb25zdCB7CiAgICBsb3R0ZXJ5V2lubmVycywgbG90dGVyeUludGVydmFsSG91cnMsIGxvdHRlcnlBbW91bnQsIG1pbmVkVG9rZW4sIHRva2VuTWluZXJzLCBuZnRUb2tlbk1pbmVyLAogICAgZXh0ZXJuYWxNaW5lcnMsIGNhbGxpbmdDb250cmFjdEluZm8sIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgLy8gZ2V0IGNvbnRyYWN0IHBhcmFtcwogIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CiAgY29uc3QgeyBwb29sQ3JlYXRpb25GZWUgfSA9IHBhcmFtczsKCiAgaWYgKGV4dGVybmFsTWluZXJzICE9PSB1bmRlZmluZWQpIHsKICAgIGlmICghYXBpLmFzc2VydCh0eXBlb2YgZXh0ZXJuYWxNaW5lcnMgPT09ICdzdHJpbmcnLCAnZXh0ZXJuYWxNaW5lcnMgbXVzdCBiZSBhIHN0cmluZycpCiAgICB8fCAhYXBpLmFzc2VydChjYWxsaW5nQ29udHJhY3RJbmZvLCAnbXVzdCBiZSBjYWxsZWQgZnJvbSBhIGNvbnRyYWN0JykpIHJldHVybjsKICB9CgogIC8vIGdldCBhcGkuc2VuZGVyJ3MgVVRJTElUWV9UT0tFTl9TWU1CT0wgYmFsYW5jZQogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10ZW1wbGF0ZS1jdXJseS1pbi1zdHJpbmcKICBjb25zdCB1dGlsaXR5VG9rZW5CYWxhbmNlID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAnYmFsYW5jZXMnLCB7IGFjY291bnQ6IGFwaS5zZW5kZXIsIHN5bWJvbDogIkJFRSIgfSk7CgogIGNvbnN0IGF1dGhvcml6ZWRDcmVhdGlvbiA9IGFwaS5CaWdOdW1iZXIocG9vbENyZWF0aW9uRmVlKS5sdGUoMCkgfHwgYXBpLnNlbmRlciA9PT0gYXBpLm93bmVyCiAgICA/IHRydWUKICAgIDogdXRpbGl0eVRva2VuQmFsYW5jZSAmJiBhcGkuQmlnTnVtYmVyKHV0aWxpdHlUb2tlbkJhbGFuY2UuYmFsYW5jZSkuZ3RlKHBvb2xDcmVhdGlvbkZlZSk7CgogIGlmIChhcGkuYXNzZXJ0KGF1dGhvcml6ZWRDcmVhdGlvbiwgJ3lvdSBtdXN0IGhhdmUgZW5vdWdoIHRva2VucyB0byBjb3ZlciB0aGUgY3JlYXRpb24gZmVlJykKICAgICAgJiYgYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgICAmJiBhcGkuYXNzZXJ0KG1pbmVkVG9rZW4gJiYgdHlwZW9mIG1pbmVkVG9rZW4gPT09ICdzdHJpbmcnCiAgICAgICAgJiYgbG90dGVyeUFtb3VudCAmJiB0eXBlb2YgbG90dGVyeUFtb3VudCA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIobG90dGVyeUFtb3VudCkuaXNOYU4oKSAmJiBhcGkuQmlnTnVtYmVyKGxvdHRlcnlBbW91bnQpLmd0KDApLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgaWYgKGFwaS5hc3NlcnQobWluZWRUb2tlbi5sZW5ndGggPiAwICYmIG1pbmVkVG9rZW4ubGVuZ3RoIDw9IDEwLCAnaW52YWxpZCBzeW1ib2w6IHVwcGVyY2FzZSBsZXR0ZXJzIG9ubHksIG1heCBsZW5ndGggb2YgMTAnKQogICAgICAmJiBhcGkuYXNzZXJ0KE51bWJlci5pc0ludGVnZXIobG90dGVyeVdpbm5lcnMpICYmIGxvdHRlcnlXaW5uZXJzID49IDEgJiYgbG90dGVyeVdpbm5lcnMgPD0gMjAsICdpbnZhbGlkIGxvdHRlcnlXaW5uZXJzOiBpbnRlZ2VyIGJldHdlZW4gMSBhbmQgMjAgb25seScpCiAgICAgICYmIGFwaS5hc3NlcnQoTnVtYmVyLmlzSW50ZWdlcihsb3R0ZXJ5SW50ZXJ2YWxIb3VycykgJiYgbG90dGVyeUludGVydmFsSG91cnMgPj0gMSAmJiBsb3R0ZXJ5SW50ZXJ2YWxIb3VycyA8PSA3MjAsICdpbnZhbGlkIGxvdHRlcnlJbnRlcnZhbEhvdXJzOiBpbnRlZ2VyIGJldHdlZW4gMSBhbmQgNzIwIG9ubHknKQogICAgKSB7CiAgICAgIGNvbnN0IG1pbmVkVG9rZW5PYmplY3QgPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ3Rva2VucycsICd0b2tlbnMnLCB7IHN5bWJvbDogbWluZWRUb2tlbiB9KTsKCiAgICAgIGlmIChhcGkuYXNzZXJ0KG1pbmVkVG9rZW5PYmplY3QsICdtaW5lZFRva2VuIGRvZXMgbm90IGV4aXN0JykKICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdGVtcGxhdGUtY3VybHktaW4tc3RyaW5nCiAgICAgICAgJiYgYXBpLmFzc2VydChtaW5lZFRva2VuT2JqZWN0Lmlzc3VlciA9PT0gYXBpLnNlbmRlciB8fCAobWluZWRUb2tlbk9iamVjdC5zeW1ib2wgPT09ICJCRUUiICYmIGFwaS5zZW5kZXIgPT09IGFwaS5vd25lciksICdtdXN0IGJlIGlzc3VlciBvZiBtaW5lZFRva2VuJykKICAgICAgICAmJiBhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIobG90dGVyeUFtb3VudCkuZHAoKSA8PSBtaW5lZFRva2VuT2JqZWN0LnByZWNpc2lvbiwgJ21pbmVkVG9rZW4gcHJlY2lzaW9uIG1pc21hdGNoIGZvciBsb3R0ZXJ5QW1vdW50JykpIHsKICAgICAgICBpZiAoY2FsbGluZ0NvbnRyYWN0SW5mbyB8fCBhd2FpdCB2YWxpZGF0ZVRva2VuTWluZXJzKHRva2VuTWluZXJzLCBuZnRUb2tlbk1pbmVyKSkgewogICAgICAgICAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLmhpdmVCbG9ja1RpbWVzdGFtcH0uMDAwWmApOwogICAgICAgICAgY29uc3QgbmV3UG9vbCA9IHsKICAgICAgICAgICAgbWluZWRUb2tlbiwKICAgICAgICAgICAgbG90dGVyeVdpbm5lcnMsCiAgICAgICAgICAgIGxvdHRlcnlJbnRlcnZhbEhvdXJzLAogICAgICAgICAgICBsb3R0ZXJ5QW1vdW50LAogICAgICAgICAgICB0b2tlbk1pbmVyczogdG9rZW5NaW5lcnMgfHwgW10sCiAgICAgICAgICAgIG5mdFRva2VuTWluZXIsCiAgICAgICAgICAgIGFjdGl2ZTogZmFsc2UsCiAgICAgICAgICAgIG5leHRMb3R0ZXJ5VGltZXN0YW1wOiBhcGkuQmlnTnVtYmVyKGJsb2NrRGF0ZS5nZXRUaW1lKCkpCiAgICAgICAgICAgICAgLnBsdXMobG90dGVyeUludGVydmFsSG91cnMgKiAzNjAwICogMTAwMCkudG9OdW1iZXIoKSwKICAgICAgICAgICAgdG90YWxQb3dlcjogJzAnLAogICAgICAgICAgfTsKICAgICAgICAgIGlmIChjYWxsaW5nQ29udHJhY3RJbmZvKSB7CiAgICAgICAgICAgIGlmICghYXBpLmFzc2VydCghbmZ0VG9rZW5NaW5lciwgJ2V4dGVybmFsIG5mdFRva2VuTWluZXIgbm90IGN1cnJlbnRseSBzdXBwb3J0ZWQnKSkgcmV0dXJuOwogICAgICAgICAgICBuZXdQb29sLmV4dGVybmFsQ29udHJhY3QgPSBjYWxsaW5nQ29udHJhY3RJbmZvLm5hbWU7CiAgICAgICAgICAgIG5ld1Bvb2wuZXh0ZXJuYWxNaW5lcnMgPSBleHRlcm5hbE1pbmVyczsKICAgICAgICAgIH0KICAgICAgICAgIG5ld1Bvb2wuaWQgPSBnZW5lcmF0ZVBvb2xJZChuZXdQb29sKTsKCiAgICAgICAgICBjb25zdCBleGlzdGluZ1Bvb2wgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncG9vbHMnLCB7IGlkOiBuZXdQb29sLmlkIH0pOwogICAgICAgICAgaWYgKGFwaS5hc3NlcnQoIWV4aXN0aW5nUG9vbCwgJ3Bvb2wgYWxyZWFkeSBleGlzdHMnKSkgewogICAgICAgICAgICBpZiAodG9rZW5NaW5lcnMpIHsKICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRva2VuTWluZXJzLmxlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgICAgICAgICBjb25zdCB0b2tlbkNvbmZpZyA9IHRva2VuTWluZXJzW2ldOwogICAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLmluc2VydCgndG9rZW5Qb29scycsIHsgc3ltYm9sOiB0b2tlbkNvbmZpZy5zeW1ib2wsIGlkOiBuZXdQb29sLmlkIH0pOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBuZXdQb29sLnVwZGF0aW5nID0gewogICAgICAgICAgICAgIGluUHJvZ3Jlc3M6IHRydWUsCiAgICAgICAgICAgICAgdXBkYXRlUG9vbFRpbWVzdGFtcDogYXBpLkJpZ051bWJlcihibG9ja0RhdGUuZ2V0VGltZSgpKS50b051bWJlcigpLAogICAgICAgICAgICAgIHRva2VuSW5kZXg6IDAsCiAgICAgICAgICAgICAgbmZ0VG9rZW5JbmRleDogMCwKICAgICAgICAgICAgICBsYXN0SWQ6IDAsCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIGNvbnN0IGluc2VydGVkUG9vbCA9IGF3YWl0IGFwaS5kYi5pbnNlcnQoJ3Bvb2xzJywgbmV3UG9vbCk7CgogICAgICAgICAgICAvLyBidXJuIHRoZSB0b2tlbiBjcmVhdGlvbiBmZWVzCiAgICAgICAgICAgIGlmIChhcGkuc2VuZGVyICE9PSBhcGkub3duZXIgJiYgYXBpLkJpZ051bWJlcihwb29sQ3JlYXRpb25GZWUpLmd0KDApKSB7CiAgICAgICAgICAgICAgYXdhaXQgYXBpLmV4ZWN1dGVTbWFydENvbnRyYWN0KCd0b2tlbnMnLCAndHJhbnNmZXInLCB7CiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdGVtcGxhdGUtY3VybHktaW4tc3RyaW5nCiAgICAgICAgICAgICAgICB0bzogJ251bGwnLCBzeW1ib2w6ICJCRUUiLCBxdWFudGl0eTogcG9vbENyZWF0aW9uRmVlLCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYXBpLmVtaXQoJ2NyZWF0ZVBvb2wnLCB7IGlkOiBpbnNlcnRlZFBvb2wuaWQgfSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYXN5bmMgZnVuY3Rpb24gcnVuTG90dGVyeShwb29sLCBwYXJhbXMpIHsKICBjb25zdCBibG9ja0RhdGUgPSBuZXcgRGF0ZShgJHthcGkuaGl2ZUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgY29uc3Qgd2lubmluZ051bWJlcnMgPSBbXTsKICBjb25zdCBtaW5lZFRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAndG9rZW5zJywKICAgIHsgc3ltYm9sOiBwb29sLm1pbmVkVG9rZW4gfSk7CiAgY29uc3Qgd2lubmluZ0Ftb3VudCA9IGFwaS5CaWdOdW1iZXIocG9vbC5sb3R0ZXJ5QW1vdW50KS5kaXZpZGVkQnkocG9vbC5sb3R0ZXJ5V2lubmVycykKICAgIC50b0ZpeGVkKG1pbmVkVG9rZW4ucHJlY2lzaW9uLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0hBTEZfVVApOwogIC8vIGRldGVybWluZSB3aW5uaW5nIG51bWJlcnMKICBpZiAoIXBvb2wuZXh0ZXJuYWxDb250cmFjdCkgewogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwb29sLmxvdHRlcnlXaW5uZXJzOyBpICs9IDEpIHsKICAgICAgd2lubmluZ051bWJlcnNbaV0gPSBhcGkuQmlnTnVtYmVyKHBvb2wudG90YWxQb3dlcikubXVsdGlwbGllZEJ5KGFwaS5yYW5kb20oKSk7CiAgICB9CiAgfSBlbHNlIGlmIChwb29sLmV4dGVybmFsQ29udHJhY3QgPT09ICdtYXJrZXRwb29scycpIHsKICAgIGNvbnN0IG1hcmtldHBvb2wgPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ21hcmtldHBvb2xzJywgJ3Bvb2xzJywgeyB0b2tlblBhaXI6IHBvb2wuZXh0ZXJuYWxNaW5lcnMgfSk7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBvb2wubG90dGVyeVdpbm5lcnM7IGkgKz0gMSkgewogICAgICB3aW5uaW5nTnVtYmVyc1tpXSA9IGFwaS5CaWdOdW1iZXIobWFya2V0cG9vbC50b3RhbFNoYXJlcykubXVsdGlwbGllZEJ5KGFwaS5yYW5kb20oKSk7CiAgICB9CiAgfQogIGxldCBvZmZzZXQgPSAwOwogIGxldCBtaW5pbmdQb3dlcnM7CiAgbGV0IGN1bXVsYXRpdmVQb3dlciA9IGFwaS5CaWdOdW1iZXIoMCk7CiAgbGV0IG5leHRDdW11bGF0aXZlUG93ZXIgPSBhcGkuQmlnTnVtYmVyKDApOwogIGxldCBjb21wdXRlZFdpbm5lcnMgPSAwOwogIGNvbnN0IHdpbm5lcnMgPSBbXTsKICB3aGlsZSAoY29tcHV0ZWRXaW5uZXJzIDwgcG9vbC5sb3R0ZXJ5V2lubmVycykgewogICAgaWYgKCFwb29sLmV4dGVybmFsQ29udHJhY3QpIHsKICAgICAgbWluaW5nUG93ZXJzID0gYXdhaXQgYXBpLmRiLmZpbmQoJ21pbmluZ1Bvd2VyJywgeyBpZDogcG9vbC5pZCwgcG93ZXI6IHsgJGd0OiB7ICRudW1iZXJEZWNpbWFsOiAnMCcgfSB9IH0sCiAgICAgICAgcGFyYW1zLnByb2Nlc3NRdWVyeUxpbWl0LAogICAgICAgIG9mZnNldCwKICAgICAgICBbeyBpbmRleDogJ3Bvd2VyJywgZGVzY2VuZGluZzogdHJ1ZSB9LCB7IGluZGV4OiAnX2lkJywgZGVzY2VuZGluZzogZmFsc2UgfV0pOwogICAgfSBlbHNlIGlmIChwb29sLmV4dGVybmFsQ29udHJhY3QgPT09ICdtYXJrZXRwb29scycpIHsKICAgICAgbWluaW5nUG93ZXJzID0gYXdhaXQgYXBpLmRiLmZpbmRJblRhYmxlKCdtYXJrZXRwb29scycsICdsaXF1aWRpdHlQb3NpdGlvbnMnLCB7IHRva2VuUGFpcjogcG9vbC5leHRlcm5hbE1pbmVycyB9LAogICAgICAgIHBhcmFtcy5wcm9jZXNzUXVlcnlMaW1pdCwKICAgICAgICBvZmZzZXQsCiAgICAgICAgW3sgaW5kZXg6ICdfaWQnLCBkZXNjZW5kaW5nOiBmYWxzZSB9XSk7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWluaW5nUG93ZXJzLmxlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgbWluaW5nUG93ZXJzW2ldLnBvd2VyID0gewogICAgICAgICAgJG51bWJlckRlY2ltYWw6IGFwaS5CaWdOdW1iZXIobWluaW5nUG93ZXJzW2ldLnNoYXJlcykKICAgICAgICAgICAgLnRvRml4ZWQobWluZWRUb2tlbi5wcmVjaXNpb24sIGFwaS5CaWdOdW1iZXIuUk9VTkRfSEFMRl9VUCksCiAgICAgICAgfTsKICAgICAgfQogICAgfQogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtaW5pbmdQb3dlcnMubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgY29uc3QgbWluaW5nUG93ZXIgPSBtaW5pbmdQb3dlcnNbaV07CiAgICAgIG5leHRDdW11bGF0aXZlUG93ZXIgPSBjdW11bGF0aXZlUG93ZXIucGx1cyhtaW5pbmdQb3dlci5wb3dlci4kbnVtYmVyRGVjaW1hbCk7CiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgcG9vbC5sb3R0ZXJ5V2lubmVyczsgaiArPSAxKSB7CiAgICAgICAgY29uc3QgY3VycmVudFdpbm5pbmdOdW1iZXIgPSB3aW5uaW5nTnVtYmVyc1tqXTsKICAgICAgICBpZiAoY3VtdWxhdGl2ZVBvd2VyLmx0ZShjdXJyZW50V2lubmluZ051bWJlcikKICAgICAgICAgICAgJiYgbmV4dEN1bXVsYXRpdmVQb3dlci5ndChjdXJyZW50V2lubmluZ051bWJlcikpIHsKICAgICAgICAgIGNvbXB1dGVkV2lubmVycyArPSAxOwogICAgICAgICAgd2lubmVycy5wdXNoKHsKICAgICAgICAgICAgd2lubmVyOiBtaW5pbmdQb3dlci5hY2NvdW50LAogICAgICAgICAgICB3aW5uaW5nTnVtYmVyOiBjdXJyZW50V2lubmluZ051bWJlciwKICAgICAgICAgICAgd2lubmluZ0Ftb3VudCwKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgICBjdW11bGF0aXZlUG93ZXIgPSBuZXh0Q3VtdWxhdGl2ZVBvd2VyOwogICAgfQogICAgaWYgKGNvbXB1dGVkV2lubmVycyA9PT0gcG9vbC5sb3R0ZXJ5V2lubmVycyB8fCBtaW5pbmdQb3dlcnMubGVuZ3RoIDwgcGFyYW1zLnByb2Nlc3NRdWVyeUxpbWl0KSB7CiAgICAgIGJyZWFrOwogICAgfQogICAgb2Zmc2V0ICs9IHBhcmFtcy5wcm9jZXNzUXVlcnlMaW1pdDsKICB9CiAgYXBpLmVtaXQoJ21pbmluZ0xvdHRlcnknLCB7IHBvb2xJZDogcG9vbC5pZCwgd2lubmVycyB9KTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHdpbm5lcnMubGVuZ3RoOyBpICs9IDEpIHsKICAgIGNvbnN0IHdpbm5lciA9IHdpbm5lcnNbaV07CiAgICBhd2FpdCBhcGkuZXhlY3V0ZVNtYXJ0Q29udHJhY3QoJ3Rva2VucycsICdpc3N1ZScsCiAgICAgIHsgdG86IHdpbm5lci53aW5uZXIsIHN5bWJvbDogbWluZWRUb2tlbi5zeW1ib2wsIHF1YW50aXR5OiB3aW5uaW5nQW1vdW50IH0pOwogIH0KICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ24KICBwb29sLm5leHRMb3R0ZXJ5VGltZXN0YW1wID0gYXBpLkJpZ051bWJlcihibG9ja0RhdGUuZ2V0VGltZSgpKQogICAgLnBsdXMocG9vbC5sb3R0ZXJ5SW50ZXJ2YWxIb3VycyAqIDM2MDAgKiAxMDAwKS50b051bWJlcigpOwogIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Bvb2xzJywgcG9vbCk7Cn0KCmFjdGlvbnMuY2hlY2tQZW5kaW5nTG90dGVyaWVzID0gYXN5bmMgKCkgPT4gewogIGlmIChhcGkuYXNzZXJ0KGFwaS5zZW5kZXIgPT09ICdudWxsJywgJ25vdCBhdXRob3JpemVkJykpIHsKICAgIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5oaXZlQmxvY2tUaW1lc3RhbXB9LjAwMFpgKTsKICAgIGNvbnN0IHRpbWVzdGFtcCA9IGJsb2NrRGF0ZS5nZXRUaW1lKCk7CgogICAgY29uc3QgcGFyYW1zID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3BhcmFtcycsIHt9KTsKICAgIGNvbnN0IHVwZGF0aW5nTG90dGVyaWVzID0gYXdhaXQgYXBpLmRiLmZpbmQoJ3Bvb2xzJywKICAgICAgewogICAgICAgICd1cGRhdGluZy5pblByb2dyZXNzJzogdHJ1ZSwKICAgICAgfSwKICAgICAgcGFyYW1zLm1heExvdHRlcmllc1BlckJsb2NrLAogICAgICAwLAogICAgICBbeyBpbmRleDogJ2lkJywgZGVzY2VuZGluZzogZmFsc2UgfV0pOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCB1cGRhdGluZ0xvdHRlcmllcy5sZW5ndGg7IGkgKz0gMSkgewogICAgICBjb25zdCBwb29sID0gdXBkYXRpbmdMb3R0ZXJpZXNbaV07CiAgICAgIGF3YWl0IHJlc3VtZVBvd2VyVXBkYXRlKHBvb2wsIHBhcmFtcyk7CiAgICB9CiAgICBjb25zdCBwZW5kaW5nTG90dGVyaWVzID0gYXdhaXQgYXBpLmRiLmZpbmQoJ3Bvb2xzJywKICAgICAgewogICAgICAgIGFjdGl2ZTogdHJ1ZSwKICAgICAgICAndXBkYXRpbmcuaW5Qcm9ncmVzcyc6IGZhbHNlLAogICAgICAgIG5leHRMb3R0ZXJ5VGltZXN0YW1wOiB7CiAgICAgICAgICAkbHRlOiB0aW1lc3RhbXAsCiAgICAgICAgfSwKICAgICAgfSwKICAgICAgcGFyYW1zLm1heExvdHRlcmllc1BlckJsb2NrLAogICAgICAwLAogICAgICBbeyBpbmRleDogJ2lkJywgZGVzY2VuZGluZzogZmFsc2UgfV0pOwoKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGVuZGluZ0xvdHRlcmllcy5sZW5ndGg7IGkgKz0gMSkgewogICAgICBjb25zdCBwb29sID0gcGVuZGluZ0xvdHRlcmllc1tpXTsKICAgICAgYXdhaXQgcnVuTG90dGVyeShwb29sLCBwYXJhbXMpOwogICAgfQogIH0KfTsKCmFjdGlvbnMuaGFuZGxlU3Rha2VDaGFuZ2UgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIGFjY291bnQsIHN5bWJvbCwgcXVhbnRpdHksIGRlbGVnYXRlZCwgY2FsbGluZ0NvbnRyYWN0SW5mbywKICB9ID0gcGF5bG9hZDsKICBpZiAoYXBpLmFzc2VydChjYWxsaW5nQ29udHJhY3RJbmZvICYmIGNhbGxpbmdDb250cmFjdEluZm8ubmFtZSA9PT0gJ3Rva2VucycsCiAgICAnbXVzdCBiZSBjYWxsZWQgZnJvbSB0b2tlbnMgY29udHJhY3QnKSkgewogICAgYXdhaXQgZmluZEFuZFByb2Nlc3NBbGwoJ21pbmluZycsICd0b2tlblBvb2xzJywgeyBzeW1ib2wgfSwgYXN5bmMgKHRva2VuUG9vbCkgPT4gewogICAgICBjb25zdCBwb29sID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Bvb2xzJywgeyBpZDogdG9rZW5Qb29sLmlkIH0pOwogICAgICBsZXQgYWRqdXN0ZWQ7CiAgICAgIGlmIChkZWxlZ2F0ZWQpIHsKICAgICAgICBhZGp1c3RlZCA9IGF3YWl0IHVwZGF0ZU1pbmluZ1Bvd2VyKHBvb2wsIHN5bWJvbCwgYWNjb3VudCwgMCwgcXVhbnRpdHkpOwogICAgICB9IGVsc2UgewogICAgICAgIGFkanVzdGVkID0gYXdhaXQgdXBkYXRlTWluaW5nUG93ZXIocG9vbCwgc3ltYm9sLCBhY2NvdW50LCBxdWFudGl0eSwgMCk7CiAgICAgIH0KICAgICAgcG9vbC50b3RhbFBvd2VyID0gYWRqdXN0ZWQucGx1cyhwb29sLnRvdGFsUG93ZXIpOwogICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdwb29scycsIHBvb2wpOwogICAgfSk7CiAgfQp9OwoKYWN0aW9ucy5oYW5kbGVOZnRDaGFuZ2UgPSBhc3luYyAoKSA9PiB7fTsKCmFjdGlvbnMuaGFuZGxlTmZ0RGVsZWdhdGlvbkNoYW5nZSA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgc3ltYm9sLCBuZnQsIGFkZCwgY2FsbGluZ0NvbnRyYWN0SW5mbywKICB9ID0gcGF5bG9hZDsKICBpZiAoYXBpLmFzc2VydChjYWxsaW5nQ29udHJhY3RJbmZvICYmIGNhbGxpbmdDb250cmFjdEluZm8ubmFtZSA9PT0gJ25mdCcsCiAgICAnbXVzdCBiZSBjYWxsZWQgZnJvbSBuZnQgY29udHJhY3QnKSkgewogICAgYXdhaXQgZmluZEFuZFByb2Nlc3NBbGwoJ21pbmluZycsICduZnRUb2tlblBvb2xzJywgeyBzeW1ib2wgfSwgYXN5bmMgKHRva2VuUG9vbCkgPT4gewogICAgICBjb25zdCBwb29sID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ3Bvb2xzJywgeyBpZDogdG9rZW5Qb29sLmlkIH0pOwogICAgICBpZiAocG9vbC51cGRhdGluZy5pblByb2dyZXNzCiAgICAgICAgICAmJiBwb29sLnVwZGF0aW5nLnRva2VuSW5kZXggPT09IHBvb2wudG9rZW5NaW5lcnMubGVuZ3RoCiAgICAgICAgICAmJiBwb29sLnVwZGF0aW5nLmxhc3RJZCA8IG5mdC5faWQpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgaWYgKCFwb29sLmFjdGl2ZSkgewogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBpZiAoIXBvb2wubmZ0VG9rZW5NaW5lcikgewogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBjb25zdCB7CiAgICAgICAgZXF1aXBGaWVsZCwgdHlwZUZpZWxkLCB0eXBlTWFwLCBtaW5pbmdQb3dlckZpZWxkLAogICAgICB9ID0gcG9vbC5uZnRUb2tlbk1pbmVyOwogICAgICBpZiAoZXF1aXBGaWVsZCkgewogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgY29uc3QgdHlwZVByb3BlcnRpZXMgPSB0eXBlTWFwWwogICAgICAgIG5mdC5wcm9wZXJ0aWVzW3R5cGVGaWVsZF1dOwogICAgICBpZiAodHlwZVByb3BlcnRpZXMgfHwgbWluaW5nUG93ZXJGaWVsZCkgewogICAgICAgIGNvbnN0IGFkanVzdGVkID0gYXdhaXQgdXBkYXRlTmZ0TWluaW5nUG93ZXIoCiAgICAgICAgICBwb29sLAogICAgICAgICAgbmZ0LAogICAgICAgICAgYWRkLAogICAgICAgICAgcG9vbC51cGRhdGluZy51cGRhdGVQb29sVGltZXN0YW1wLAogICAgICAgICk7CiAgICAgICAgcG9vbC50b3RhbFBvd2VyID0gYWRqdXN0ZWQucGx1cyhwb29sLnRvdGFsUG93ZXIpOwogICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3Bvb2xzJywgcG9vbCk7CiAgICAgIH0KICAgIH0pOwogIH0KfTsKCmFjdGlvbnMuaGFuZGxlTmZ0U2V0UHJvcGVydHkgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHN5bWJvbCwgbmZ0LCBwcm9wZXJ0eU5hbWUsIG9sZFZhbHVlLCBjYWxsaW5nQ29udHJhY3RJbmZvLAogIH0gPSBwYXlsb2FkOwogIGlmIChhcGkuYXNzZXJ0KGNhbGxpbmdDb250cmFjdEluZm8gJiYgY2FsbGluZ0NvbnRyYWN0SW5mby5uYW1lID09PSAnbmZ0JywKICAgICdtdXN0IGJlIGNhbGxlZCBmcm9tIG5mdCBjb250cmFjdCcpKSB7CiAgICBjb25zdCBuZXdWYWx1ZSA9IG5mdC5wcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV07CiAgICBpZiAob2xkVmFsdWUgPT09IG5ld1ZhbHVlKSB7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGF3YWl0IGZpbmRBbmRQcm9jZXNzQWxsKCdtaW5pbmcnLCAnbmZ0VG9rZW5Qb29scycsIHsgc3ltYm9sIH0sIGFzeW5jICh0b2tlblBvb2wpID0+IHsKICAgICAgY29uc3QgcG9vbCA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwb29scycsIHsgaWQ6IHRva2VuUG9vbC5pZCB9KTsKICAgICAgaWYgKHBvb2wudXBkYXRpbmcuaW5Qcm9ncmVzcwogICAgICAgICAgJiYgcG9vbC51cGRhdGluZy50b2tlbkluZGV4ID09PSBwb29sLnRva2VuTWluZXJzLmxlbmd0aAogICAgICAgICAgJiYgcG9vbC51cGRhdGluZy5sYXN0SWQgPCBuZnQuX2lkKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgIGlmICghcG9vbC5hY3RpdmUpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgaWYgKCFwb29sLm5mdFRva2VuTWluZXIpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgY29uc3QgeyBlcXVpcEZpZWxkLCBtaW5pbmdQb3dlckZpZWxkIH0gPSBwb29sLm5mdFRva2VuTWluZXI7CiAgICAgIGlmIChlcXVpcEZpZWxkICYmIHByb3BlcnR5TmFtZSA9PT0gZXF1aXBGaWVsZCkgewogICAgICAgIGlmIChvbGRWYWx1ZSAmJiBhcGkuaXNWYWxpZEFjY291bnROYW1lKG9sZFZhbHVlKSkgewogICAgICAgICAgLy8gdW5lcXVpcCBmcm9tIHByZXZpb3VzIGFjY291bnQKICAgICAgICAgIGNvbnN0IGFkanVzdGVkID0gYXdhaXQgdXBkYXRlTmZ0TWluaW5nUG93ZXIoCiAgICAgICAgICAgIHBvb2wsCiAgICAgICAgICAgIG5mdCwKICAgICAgICAgICAgLyogYWRkPSAqLyBmYWxzZSwKICAgICAgICAgICAgcG9vbC51cGRhdGluZy51cGRhdGVQb29sVGltZXN0YW1wLAogICAgICAgICAgICAvKiBhY2NvdW50PSAqLyBvbGRWYWx1ZSwKICAgICAgICAgICk7CiAgICAgICAgICBwb29sLnRvdGFsUG93ZXIgPSBhZGp1c3RlZC5wbHVzKHBvb2wudG90YWxQb3dlcik7CiAgICAgICAgfQogICAgICAgIGlmIChuZXdWYWx1ZSAmJiBhcGkuaXNWYWxpZEFjY291bnROYW1lKG5ld1ZhbHVlKSkgewogICAgICAgICAgLy8gZXF1aXAgdG8gYWNjb3VudAogICAgICAgICAgY29uc3QgYWRqdXN0ZWQgPSBhd2FpdCB1cGRhdGVOZnRNaW5pbmdQb3dlcigKICAgICAgICAgICAgcG9vbCwKICAgICAgICAgICAgbmZ0LAogICAgICAgICAgICAvKiBhZGQ9ICovIHRydWUsCiAgICAgICAgICAgIHBvb2wudXBkYXRpbmcudXBkYXRlUG9vbFRpbWVzdGFtcCwKICAgICAgICAgICAgLyogYWNjb3VudD0gKi8gbmV3VmFsdWUsCiAgICAgICAgICApOwogICAgICAgICAgcG9vbC50b3RhbFBvd2VyID0gYWRqdXN0ZWQucGx1cyhwb29sLnRvdGFsUG93ZXIpOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChtaW5pbmdQb3dlckZpZWxkICYmIHByb3BlcnR5TmFtZSA9PT0gbWluaW5nUG93ZXJGaWVsZCkgewogICAgICAgIGlmICghZXF1aXBGaWVsZCB8fCBhcGkuaXNWYWxpZEFjY291bnROYW1lKG5mdC5wcm9wZXJ0aWVzW2VxdWlwRmllbGRdKSkgewogICAgICAgICAgY29uc3QgYWRqdXN0ZWQgPSBhd2FpdCB1cGRhdGVOZnRNaW5pbmdQb3dlckZyb21Qcm9wZXJ0eVVwZGF0ZSgKICAgICAgICAgICAgcG9vbCwKICAgICAgICAgICAgbmZ0LAogICAgICAgICAgICAvKiBhY2NvdW50PSAqLyBlcXVpcEZpZWxkID8gbmZ0LnByb3BlcnRpZXNbZXF1aXBGaWVsZF0gOiBudWxsLAogICAgICAgICAgKTsKICAgICAgICAgIHBvb2wudG90YWxQb3dlciA9IGFkanVzdGVkLnBsdXMocG9vbC50b3RhbFBvd2VyKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgncG9vbHMnLCBwb29sKTsKICAgIH0pOwogIH0KfTsK"}}}