diff --git a/assertions.js b/assertions.js deleted file mode 100644 index af2e9eb..0000000 --- a/assertions.js +++ /dev/null @@ -1,879 +0,0 @@ -"use strict" - -/** - * Core TDD-style assertions. These are done by a composition of DSLs, since - * there is *so* much repetition. - */ - -var match = require("clean-match") -var deprecate = require("./migrate/common").deprecate - -var toString = Object.prototype.toString -var hasOwn = Object.prototype.hasOwnProperty - -/* eslint-disable no-self-compare */ -// For better NaN handling -function strictIs(a, b) { - return a === b || a !== a && b !== b -} - -function looseIs(a, b) { - return a == b || a !== a && b !== b // eslint-disable-line eqeqeq -} - -/* eslint-enable no-self-compare */ - -var check = (function () { - function prefix(type) { - return (/^[aeiou]/.test(type) ? "an " : "a ") + type - } - - function check(value, type) { - if (type === "array") return Array.isArray(value) - if (type === "regexp") return toString.call(value) === "[object RegExp]" - if (type === "object") return value != null && typeof value === "object" - if (type === "null") return value === null - if (type === "none") return value == null - return typeof value === type - } - - function checkList(value, types) { - for (var i = 0; i < types.length; i++) { - if (check(value, types[i])) return true - } - - return false - } - - function checkSingle(value, name, type) { - if (!check(value, type)) { - throw new TypeError("`" + name + "` must be " + prefix(type)) - } - } - - function checkMany(value, name, types) { - if (!checkList(value, types)) { - var str = "`" + name + "` must be either" - - if (types.length === 2) { - str += prefix(types[0]) + " or " + prefix(types[1]) - } else { - str += prefix(types[0]) - - var end = types.length - 1 - - for (var i = 1; i < end; i++) { - str += ", " + prefix(types[i]) - } - - str += ", or " + prefix(types[end]) - } - - throw new TypeError(str) - } - } - - return function (value, name, type) { - if (!Array.isArray(type)) return checkSingle(value, name, type) - if (type.length === 1) return checkSingle(value, name, type[0]) - return checkMany(value, name, type) - } -})() - -function checkTypeOf(value, name) { - if (value === "boolean" || value === "function") return - if (value === "number" || value === "object" || value === "string") return - if (value === "symbol" || value === "undefined") return - throw new TypeError("`" + name + "` must be a valid `typeof` value") -} - -// This holds everything to be added. -var methods = [] -var aliases = [] - -function getAssertionDeprecation(name) { - var replacement = name - - switch (name) { - case "boolean": replacement = "isBoolean"; break - case "function": replacement = "isFunction"; break - case "number": replacement = "isNumber"; break - case "object": replacement = "isObject"; break - case "string": replacement = "isString"; break - case "symbol": replacement = "isSymbol"; break - case "instanceof": replacement = "is"; break - case "notInstanceof": replacement = "not"; break - case "hasLength": replacement = "equal"; break - case "notLength": replacement = "notEqual"; break - case "lengthAtLeast": replacement = "atLeast"; break - case "lengthAtMost": replacement = "atMost"; break - case "lengthAbove": replacement = "above"; break - case "lengthBelow": replacement = "below"; break - case "notIncludesAll": replacement = "notIncludesAll"; break - case "notIncludesLooseAll": replacement = "notIncludesAll"; break - case "notIncludesDeepAll": replacement = "notIncludesAllDeep"; break - case "notIncludesMatchAll": replacement = "notIncludesAllMatch"; break - case "includesAny": replacement = "includesAny"; break - case "includesLooseAny": replacement = "includesAny"; break - case "includesDeepAny": replacement = "includesAnyDeep"; break - case "includesMatchAny": replacement = "includesAnyMatch"; break - case "undefined": - return "`t.undefined()` is deprecated. Use " + - "`assert.equal(undefined, value)`. from `thallium/assert` instead." - case "type": - return "`t.type()` is deprecated. Use `assert.isBoolean()`/etc. from " + - "`thallium/assert` instead." - default: // ignore - } - - return "`t." + name + "()` is deprecated. Use `assert." + replacement + - "()` from `thallium/assert` instead." -} - -/** - * The core assertions export, as a plugin. - */ -module.exports = function (t) { - methods.forEach(function (m) { - t.define(m.name, deprecate(getAssertionDeprecation(m.name), m.callback)) - }) - aliases.forEach(function (alias) { t[alias.name] = t[alias.original] }) -} - -// Little helpers so that these functions only need to be created once. -function define(name, callback) { - check(name, "name", "string") - check(callback, "callback", "function") - methods.push({name: name, callback: callback}) -} - -// Much easier to type -function negate(name) { - check(name, "name", "string") - return "not" + name[0].toUpperCase() + name.slice(1) -} - -// The basic assert. It's almost there for looks, given how easy it is to -// define your own assertions. -function sanitize(message) { - return message ? String(message).replace(/(\{\w+\})/g, "\\$1") : "" -} - -define("assert", function (test, message) { - return {test: test, message: sanitize(message)} -}) - -define("fail", function (message) { - return {test: false, message: sanitize(message)} -}) - -/** - * These makes many of the common operators much easier to do. - */ -function unary(name, func, messages) { - define(name, function (value) { - return { - test: func(value), - actual: value, - message: messages[0], - } - }) - - define(negate(name), function (value) { - return { - test: !func(value), - actual: value, - message: messages[1], - } - }) -} - -function binary(name, func, messages) { - define(name, function (actual, expected) { - return { - test: func(actual, expected), - actual: actual, - expected: expected, - message: messages[0], - } - }) - - define(negate(name), function (actual, expected) { - return { - test: !func(actual, expected), - actual: actual, - expected: expected, - message: messages[1], - } - }) -} - -unary("ok", function (x) { return !!x }, [ - "Expected {actual} to be ok", - "Expected {actual} to not be ok", -]) - -"boolean function number object string symbol".split(" ") -.forEach(function (type) { - var name = (type[0] === "o" ? "an " : "a ") + type - - unary(type, function (x) { return typeof x === type }, [ - "Expected {actual} to be " + name, - "Expected {actual} to not be " + name, - ]) -}) - -;[true, false, null, undefined].forEach(function (value) { - unary(value + "", function (x) { return x === value }, [ - "Expected {actual} to be " + value, - "Expected {actual} to not be " + value, - ]) -}) - -unary("exists", function (x) { return x != null }, [ - "Expected {actual} to exist", - "Expected {actual} to not exist", -]) - -unary("array", Array.isArray, [ - "Expected {actual} to be an array", - "Expected {actual} to not be an array", -]) - -define("type", function (object, type) { - checkTypeOf(type, "type") - - return { - test: typeof object === type, - expected: type, - actual: typeof object, - o: object, - message: "Expected typeof {o} to be {expected}, but found {actual}", - } -}) - -define("notType", function (object, type) { - checkTypeOf(type, "type") - - return { - test: typeof object !== type, - expected: type, - o: object, - message: "Expected typeof {o} to not be {expected}", - } -}) - -define("instanceof", function (object, Type) { - check(Type, "Type", "function") - - return { - test: object instanceof Type, - expected: Type, - actual: object.constructor, - o: object, - message: "Expected {o} to be an instance of {expected}, but found {actual}", // eslint-disable-line max-len - } -}) - -define("notInstanceof", function (object, Type) { - check(Type, "Type", "function") - - return { - test: !(object instanceof Type), - expected: Type, - o: object, - message: "Expected {o} to not be an instance of {expected}", - } -}) - -binary("equal", strictIs, [ - "Expected {actual} to equal {expected}", - "Expected {actual} to not equal {expected}", -]) - -binary("equalLoose", looseIs, [ - "Expected {actual} to loosely equal {expected}", - "Expected {actual} to not loosely equal {expected}", -]) - -function comp(name, compare, message) { - define(name, function (actual, expected) { - check(actual, "actual", "number") - check(expected, "expected", "number") - - return { - test: compare(actual, expected), - actual: actual, - expected: expected, - message: message, - } - }) -} - -/* eslint-disable max-len */ - -comp("atLeast", function (a, b) { return a >= b }, "Expected {actual} to be at least {expected}") -comp("atMost", function (a, b) { return a <= b }, "Expected {actual} to be at most {expected}") -comp("above", function (a, b) { return a > b }, "Expected {actual} to be above {expected}") -comp("below", function (a, b) { return a < b }, "Expected {actual} to be below {expected}") - -define("between", function (actual, lower, upper) { - check(actual, "actual", "number") - check(lower, "lower", "number") - check(upper, "upper", "number") - - return { - test: actual >= lower && actual <= upper, - actual: actual, - lower: lower, - upper: upper, - message: "Expected {actual} to be between {lower} and {upper}", - } -}) - -/* eslint-enable max-len */ - -binary("deepEqual", match.strict, [ - "Expected {actual} to deeply equal {expected}", - "Expected {actual} to not deeply equal {expected}", -]) - -binary("match", match.loose, [ - "Expected {actual} to match {expected}", - "Expected {actual} to not match {expected}", -]) - -function has(name, _) { // eslint-disable-line max-len, max-params - if (_.equals === looseIs) { - define(name, function (object, key, value) { - return { - test: _.has(object, key) && _.is(_.get(object, key), value), - expected: value, - actual: object[key], - key: key, - object: object, - message: _.messages[0], - } - }) - - define(negate(name), function (object, key, value) { - return { - test: !_.has(object, key) || !_.is(_.get(object, key), value), - actual: value, - key: key, - object: object, - message: _.messages[2], - } - }) - } else { - define(name, function (object, key, value) { - var test = _.has(object, key) - - if (arguments.length >= 3) { - return { - test: test && _.is(_.get(object, key), value), - expected: value, - actual: object[key], - key: key, - object: object, - message: _.messages[0], - } - } else { - return { - test: test, - expected: key, - actual: object, - message: _.messages[1], - } - } - }) - - define(negate(name), function (object, key, value) { - var test = !_.has(object, key) - - if (arguments.length >= 3) { - return { - test: test || !_.is(_.get(object, key), value), - actual: value, - key: key, - object: object, - message: _.messages[2], - } - } else { - return { - test: test, - expected: key, - actual: object, - message: _.messages[3], - } - } - }) - } -} - -function hasOwnKey(object, key) { return hasOwn.call(object, key) } -function hasInKey(object, key) { return key in object } -function hasInColl(object, key) { return object.has(key) } -function hasObjectGet(object, key) { return object[key] } -function hasCollGet(object, key) { return object.get(key) } - -has("hasOwn", { - is: strictIs, - has: hasOwnKey, - get: hasObjectGet, - messages: [ - "Expected {object} to have own key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have own key {expected}", - "Expected {object} to not have own key {key} equal to {actual}", - "Expected {actual} to not have own key {expected}", - ], -}) - -has("hasOwnLoose", { - is: looseIs, - has: hasOwnKey, - get: hasObjectGet, - messages: [ - "Expected {object} to have own key {key} loosely equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have own key {expected}", - "Expected {object} to not have own key {key} loosely equal to {actual}", - "Expected {actual} to not have own key {expected}", - ], -}) - -has("hasKey", { - is: strictIs, - has: hasInKey, - get: hasObjectGet, - messages: [ - "Expected {object} to have key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have key {expected}", - "Expected {object} to not have key {key} equal to {actual}", - "Expected {actual} to not have key {expected}", - ], -}) - -has("hasKeyLoose", { - is: looseIs, - has: hasInKey, - get: hasObjectGet, - messages: [ - "Expected {object} to have key {key} loosely equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have key {expected}", - "Expected {object} to not have key {key} loosely equal to {actual}", - "Expected {actual} to not have key {expected}", - ], -}) - -has("has", { - is: strictIs, - has: hasInColl, - get: hasCollGet, - messages: [ - "Expected {object} to have key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have key {expected}", - "Expected {object} to not have key {key} equal to {actual}", - "Expected {actual} to not have key {expected}", - ], -}) - -has("hasLoose", { - is: looseIs, - has: hasInColl, - get: hasCollGet, - messages: [ - "Expected {object} to have key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have key {expected}", - "Expected {object} to not have key {key} equal to {actual}", - "Expected {actual} to not have key {expected}", - ], -}) - -function getName(func) { - if (func.name != null) return func.name || "" - if (func.displayName != null) return func.displayName || "" - return "" -} - -function throws(name, _) { - function run(invert) { - return function (func, matcher) { - check(func, "func", "function") - _.check(matcher) - - var test, error - - try { - func() - } catch (e) { - test = _.test(matcher, error = e) - - // Rethrow unknown errors that don't match when a matcher was - // passed - it's easier to debug unexpected errors when you have - // a stack trace. Don't rethrow non-errors, though. - if (_.rethrow(matcher, invert, test, e)) { - throw e - } - } - - return { - test: !!test ^ invert, - expected: matcher, - error: error, - message: _.message(matcher, invert, test), - } - } - } - - define(name, run(false)) - define(negate(name), run(true)) -} - -throws("throws", { - test: function (Type, e) { return Type == null || e instanceof Type }, - check: function (Type) { check(Type, "Type", ["none", "function"]) }, - - rethrow: function (matcher, invert, test, e) { - return matcher != null && !invert && !test && e instanceof Error - }, - - message: function (Type, invert, test) { - var str = "Expected callback to " - - if (invert) str += "not " - str += "throw" - - if (Type != null) { - str += " an instance of " + getName(Type) - if (!invert && test === false) str += ", but found {error}" - } - - return str - }, -}) - -throws("throwsMatch", { - test: function (matcher, e) { - if (typeof matcher === "string") return e.message === matcher - if (typeof matcher === "function") return !!matcher(e) - return matcher.test(e.message) - }, - - check: function (matcher) { - // Not accepting objects yet. - check(matcher, "matcher", ["string", "regexp", "function"]) - }, - - rethrow: function () { return false }, - - message: function (_, invert, test) { - if (invert) { - return "Expected callback to not throw an error that matches {expected}" // eslint-disable-line max-len - } else if (test === undefined) { - return "Expected callback to throw an error that matches {expected}, but found no error" // eslint-disable-line max-len - } else { - return "Expected callback to throw an error that matches {expected}, but found {error}" // eslint-disable-line max-len - } - }, -}) - -function len(name, compare, message) { - define(name, function (object, length) { - check(object, "object", "object") - check(length, "length", "number") - - var len = object.length - - return { - test: len != null && compare(len, +length), - expected: length, - actual: len, - object: object, - message: message, - } - }) -} - -/* eslint-disable max-len */ - -// Note: these always fail with NaNs. -len("length", function (a, b) { return a === b }, "Expected {object} to have length {expected}, but found {actual}") -len("notLength", function (a, b) { return a !== b }, "Expected {object} to not have length {actual}") -len("lengthAtLeast", function (a, b) { return a >= b }, "Expected {object} to have length at least {expected}, but found {actual}") -len("lengthAtMost", function (a, b) { return a <= b }, "Expected {object} to have length at most {expected}, but found {actual}") -len("lengthAbove", function (a, b) { return a > b }, "Expected {object} to have length above {expected}, but found {actual}") -len("lengthBelow", function (a, b) { return a < b }, "Expected {object} to have length below {expected}, but found {actual}") - -/* eslint-enable max-len */ - -// Note: these two always fail when dealing with NaNs. -define("closeTo", function (actual, expected, delta) { - check(actual, "actual", "number") - check(expected, "expected", "number") - check(delta, "delta", "number") - - return { - test: Math.abs(actual - expected) <= Math.abs(delta), - actual: actual, - expected: expected, - delta: delta, - message: "Expected {actual} to be within {delta} of {expected}", - } -}) - -define("notCloseTo", function (actual, expected, delta) { - check(actual, "actual", "number") - check(expected, "expected", "number") - check(delta, "delta", "number") - - return { - test: Math.abs(actual - expected) > Math.abs(delta), - actual: actual, - expected: expected, - delta: delta, - message: "Expected {actual} to not be within {delta} of {expected}", - } -}) - -/* eslint-disable max-len */ - -/** - * There's 4 sets of 4 permutations here for `includes` and `hasKeys`, instead - * of N sets of 2 (which would fit the `foo`/`notFoo` idiom better), so it's - * easier to just make a couple separate DSLs and use that to define everything. - * - * Here's the top level: - * - * - strict shallow - * - loose shallow - * - strict deep - * - structural deep - * - * And the second level: - * - * - includes all/not missing some - * - includes some/not missing all - * - not including all/missing some - * - not including some/missing all - * - * Here's an example using the naming scheme for `hasKeys`, etc. - * - * | strict shallow | loose shallow | strict deep | structural deep - * --------------|-----------------|----------------------|---------------------|------------------------- - * includes all | `hasKeys` | `hasLooseKeys` | `hasDeepKeys` | `hasMatchKeys` - * includes some | `hasAnyKeys` | `hasLooseAnyKeys` | `hasDeepAnyKeys` | `hasMatchAnyKeys` - * missing some | `notHasAllKeys` | `notHasLooseAllKeys` | `notHasDeepAllKeys` | `notHasMatchAllKeys` - * missing all | `notHasKeys` | `notHasLooseKeys` | `notHasDeepKeys` | `notHasMatchKeys` - * - * Note that the `hasKeys` shallow comparison variants are also overloaded to - * consume either an array (in which it simply checks against a list of keys) or - * an object (where it does a full deep comparison). - */ - -/* eslint-enable max-len */ - -function makeIncludes(all, func) { - return function (array, keys) { - function test(key) { - for (var i = 0; i < array.length; i++) { - if (func(key, array[i])) return true - } - return false - } - - if (all) { - if (array.length < keys.length) return false - - for (var i = 0; i < keys.length; i++) { - if (!test(keys[i])) return false - } - return true - } else { - for (var j = 0; j < keys.length; j++) { - if (test(keys[j])) return true - } - return false - } - } -} - -function defineIncludes(name, func, invert, message) { - function base(array, values) { - // Cheap cases first - if (!Array.isArray(array)) return false - if (array === values) return true - return func(array, values) - } - - define(name, function (array, values) { - check(array, "array", "array") - if (!Array.isArray(values)) values = [values] - - // exclusive or to invert the result if `invert` is true - return { - test: !values.length || invert ^ base(array, values), - actual: array, - values: values, - message: message, - } - }) -} - -var includesAll = makeIncludes(true, strictIs) -var includesAny = makeIncludes(false, strictIs) - -/* eslint-disable max-len */ - -defineIncludes("includes", includesAll, false, "Expected {actual} to have all values in {values}") -defineIncludes("notIncludesAll", includesAll, true, "Expected {actual} to not have all values in {values}") -defineIncludes("includesAny", includesAny, false, "Expected {actual} to have any value in {values}") -defineIncludes("notIncludes", includesAny, true, "Expected {actual} to not have any value in {values}") - -var includesLooseAll = makeIncludes(true, looseIs) -var includesLooseAny = makeIncludes(false, looseIs) - -defineIncludes("includesLoose", includesLooseAll, false, "Expected {actual} to loosely have all values in {values}") -defineIncludes("notIncludesLooseAll", includesLooseAll, true, "Expected {actual} to not loosely have all values in {values}") -defineIncludes("includesLooseAny", includesLooseAny, false, "Expected {actual} to loosely have any value in {values}") -defineIncludes("notIncludesLoose", includesLooseAny, true, "Expected {actual} to not loosely have any value in {values}") - -var includesDeepAll = makeIncludes(true, match.strict) -var includesDeepAny = makeIncludes(false, match.strict) - -defineIncludes("includesDeep", includesDeepAll, false, "Expected {actual} to match all values in {values}") -defineIncludes("notIncludesDeepAll", includesDeepAll, true, "Expected {actual} to not match all values in {values}") -defineIncludes("includesDeepAny", includesDeepAny, false, "Expected {actual} to match any value in {values}") -defineIncludes("notIncludesDeep", includesDeepAny, true, "Expected {actual} to not match any value in {values}") - -var includesMatchAll = makeIncludes(true, match.loose) -var includesMatchAny = makeIncludes(false, match.loose) - -defineIncludes("includesMatch", includesMatchAll, false, "Expected {actual} to match all values in {values}") -defineIncludes("notIncludesMatchAll", includesMatchAll, true, "Expected {actual} to not match all values in {values}") -defineIncludes("includesMatchAny", includesMatchAny, false, "Expected {actual} to match any value in {values}") -defineIncludes("notIncludesMatch", includesMatchAny, true, "Expected {actual} to not match any value in {values}") - -/* eslint-enable max-len */ - -function isEmpty(object) { - if (Array.isArray(object)) return object.length === 0 - if (typeof object !== "object" || object === null) return true - return Object.keys(object).length === 0 -} - -function makeHasOverload(name, methods, invert, message) { - function base(object, keys) { - // Cheap case first - if (object === keys) return true - if (Array.isArray(keys)) return methods.array(object, keys) - return methods.object(object, keys) - } - - define(name, function (object, keys) { - check(object, "object", "object") - return { - // exclusive or to invert the result if `invert` is true - test: isEmpty(keys) || invert ^ base(object, keys), - actual: object, - keys: keys, - message: message, - } - }) -} - -function makeHasKeys(name, func, invert, message) { - function base(object, keys) { - return object === keys || func(object, keys) - } - - define(name, function (object, keys) { - check(object, "object", "object") - return { - // exclusive or to invert the result if `invert` is true - test: isEmpty(keys) || invert ^ base(object, keys), - actual: object, - keys: keys, - message: message, - } - }) -} - -function hasKeysType(all, func) { - return function (object, keys) { - if (typeof keys !== "object") return true - if (keys === null) return true - - function check(key) { - return hasOwn.call(object, key) && func(keys[key], object[key]) - } - - if (all) { - for (var key1 in keys) { - if (hasOwn.call(keys, key1) && !check(key1)) { - return false - } - } - return true - } else { - for (var key2 in keys) { - if (hasOwn.call(keys, key2) && check(key2)) { - return true - } - } - return false - } - } -} - -function hasOverloadType(all, func) { - return { - object: hasKeysType(all, func), - array: function (object, keys) { - if (all) { - for (var i = 0; i < keys.length; i++) { - if (!hasOwn.call(object, keys[i])) return false - } - return true - } else { - for (var j = 0; j < keys.length; j++) { - if (hasOwn.call(object, keys[j])) return true - } - return false - } - }, - } -} - -/* eslint-disable max-len */ - -var hasAllKeys = hasOverloadType(true, strictIs) -var hasAnyKeys = hasOverloadType(false, strictIs) - -makeHasOverload("hasKeys", hasAllKeys, false, "Expected {actual} to have all keys in {keys}") -makeHasOverload("notHasAllKeys", hasAllKeys, true, "Expected {actual} to not have all keys in {keys}") -makeHasOverload("hasAnyKeys", hasAnyKeys, false, "Expected {actual} to have any key in {keys}") -makeHasOverload("notHasKeys", hasAnyKeys, true, "Expected {actual} to not have any key in {keys}") - -var hasLooseAllKeys = hasOverloadType(true, looseIs) -var hasLooseAnyKeys = hasOverloadType(false, looseIs) - -makeHasOverload("hasLooseKeys", hasLooseAllKeys, false, "Expected {actual} to loosely have all keys in {keys}") -makeHasOverload("notHasLooseAllKeys", hasLooseAllKeys, true, "Expected {actual} to not loosely have all keys in {keys}") -makeHasOverload("hasLooseAnyKeys", hasLooseAnyKeys, false, "Expected {actual} to loosely have any key in {keys}") -makeHasOverload("notHasLooseKeys", hasLooseAnyKeys, true, "Expected {actual} to not loosely have any key in {keys}") - -var hasDeepAllKeys = hasKeysType(true, match.strict) -var hasDeepAnyKeys = hasKeysType(false, match.strict) - -makeHasKeys("hasDeepKeys", hasDeepAllKeys, false, "Expected {actual} to have all keys in {keys}") -makeHasKeys("notHasDeepAllKeys", hasDeepAllKeys, true, "Expected {actual} to not have all keys in {keys}") -makeHasKeys("hasDeepAnyKeys", hasDeepAnyKeys, false, "Expected {actual} to have any key in {keys}") -makeHasKeys("notHasDeepKeys", hasDeepAnyKeys, true, "Expected {actual} to not have any key in {keys}") - -var hasMatchAllKeys = hasKeysType(true, match.loose) -var hasMatchAnyKeys = hasKeysType(false, match.loose) - -makeHasKeys("hasMatchKeys", hasMatchAllKeys, false, "Expected {actual} to match all keys in {keys}") -makeHasKeys("notHasMatchAllKeys", hasMatchAllKeys, true, "Expected {actual} to not match all keys in {keys}") -makeHasKeys("hasMatchAnyKeys", hasMatchAnyKeys, false, "Expected {actual} to match any key in {keys}") -makeHasKeys("notHasMatchKeys", hasMatchAnyKeys, true, "Expected {actual} to not match any key in {keys}") diff --git a/core.js b/core.js deleted file mode 100644 index 2f5ff90..0000000 --- a/core.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict" - -/** - * Main entry point, for those wanting to use this framework without the core - * assertions. - */ -var Thallium = require("./lib/api/thallium") - -require("./migrate/common").deprecate( - "`thallium/core` is deprecated. Use `thallium` + `thallium/assert` instead.", // eslint-disable-line max-len - function () {} -)() - -module.exports = new Thallium() diff --git a/docs/api/bundle.md b/docs/api/bundle.md index 54a020c..1ecf6c7 100644 --- a/docs/api/bundle.md +++ b/docs/api/bundle.md @@ -81,4 +81,4 @@ t.use(function (t) { You can also find the definitions for this module in `thallium.d.ts` next to the bundle, in case you're using TypeScript with this. -You can also use `thallium-migrate.js` in the root, which has most of the old API monkey-patched back in with deprecation warnings, to ease test migration. It also re-adds the old `assertions` and `create` functions to the exports. +You can also use `thallium-migrate.js` in the root, which has most of the old API monkey-patched back in with deprecation warnings, to ease test migration. It also exports `thallium/migrate/support` via `tl.support`. diff --git a/docs/api/reflect.md b/docs/api/reflect.md index d4d652b..bd43e81 100644 --- a/docs/api/reflect.md +++ b/docs/api/reflect.md @@ -14,12 +14,10 @@ Also note that `reflect` instances are persistent and tied to the backing test i - [`reflect.root`](#root) - [`reflect.isRoot`](#isroot) - [`reflect.isLocked`](#islocked) -- [`reflect.ownTimeout`](#owntimeout) - [`reflect.timeout`](#timeout) -- [`reflect.ownSlow`](#ownslow) - [`reflect.slow`](#slow) - [`reflect.attempts`](#attempts) -- [`reflect.isfailable`](#isfailable) +- [`reflect.isFailable`](#isfailable) - [`reflect` test hooks](#test-hooks) - [Tests with `reflect.test("name", callback)` and `reflect.testSkip("name", callback)`](#tests) - [Reporter management with `reflect.reporter(reporter, arg)`, `reflect.hasReporter(reporter)`, and `reflect.removeReporter(reporter)`](#reporters) @@ -97,16 +95,7 @@ Get the own timeout, `0` if it's inherited, or `Infinity` if it was disabled. reflect.timeout // getter ``` -Get the currently active timeout, or the framework default of 2000 ms. - - -## reflect.ownSlow - -```js -reflect.ownSlow // getter -``` - -Get the own slow threshold, `0` if it's inherited, or `Infinity` if it was disabled. +Get the current test timeout, `Infinity` if it was disabled, or the framework default of 2000 ms. ## reflect.slow @@ -115,7 +104,7 @@ Get the own slow threshold, `0` if it's inherited, or `Infinity` if it was disab reflect.slow // getter ``` -Get the currently active slow threshold, or the framework default of 2000 ms. +Get the current slow threshold, `Infinity` if it was disabled, or the framework default of 2000 ms. ## reflect.attempts diff --git a/fixtures/mid-coffee/spec/basic.coffee b/fixtures/mid-coffee/spec/basic.coffee index d0803b2..86eddf6 100644 --- a/fixtures/mid-coffee/spec/basic.coffee +++ b/fixtures/mid-coffee/spec/basic.coffee @@ -106,13 +106,6 @@ t.test 'core (basic)', -> tt.test 'test', -> assert.match slice, [] - t.test 'test()', -> - t.test 'returns a prototypal clone inside', -> - tt = create() - inner = undefined - tt.test 'test', -> inner = this - tt.run().then -> assert.equal Object.getPrototypeOf(inner), tt - t.test 'run()', -> t.test 'runs child tests', -> tt = create() diff --git a/fixtures/mid-coffee/spec/timeouts.coffee b/fixtures/mid-coffee/spec/timeouts.coffee index 0d6943d..8226d39 100644 --- a/fixtures/mid-coffee/spec/timeouts.coffee +++ b/fixtures/mid-coffee/spec/timeouts.coffee @@ -108,39 +108,33 @@ t.test 'core (timeouts) (FLAKE)', -> t.test 'gets own timeout', -> tt = create() - active = raw = undefined + active = undefined tt.test 'test', -> tt.timeout = 50 active = tt.call -> @timeout - raw = tt.call -> @ownTimeout tt.run().then -> assert.equal active, 50 - assert.equal raw, 50 t.test 'gets inherited timeout', -> tt = create() - active = raw = undefined + active = undefined tt.test 'test', -> tt.timeout = 50 tt.test 'inner', -> active = tt.call -> @timeout - raw = tt.call -> @ownTimeout tt.run().then -> assert.equal active, 50 - assert.equal raw, 0 t.test 'gets default timeout', -> tt = create() - active = raw = undefined + active = undefined tt.test 'test', -> active = tt.call -> @timeout - raw = tt.call -> @ownTimeout tt.run().then -> assert.equal active, 2000 - assert.equal raw, 0 diff --git a/index.d.ts b/index.d.ts index 56959e5..c29d6f1 100644 --- a/index.d.ts +++ b/index.d.ts @@ -270,24 +270,12 @@ interface ReflectCommon { */ isLocked: boolean; - /** - * Get the own, not necessarily active, timeout. 0 means inherit the - * parent's, and `Infinity` means it's disabled. - */ - ownTimeout: number; - /** * Get the active timeout in milliseconds, not necessarily own, or the * framework default of 2000, if none was set. */ timeout: number; - /** - * Get the own, not necessarily active, slow threshold. 0 means inherit the - * parent's, and `Infinity` means it's disabled. - */ - ownSlow: number; - /** * Get the active slow threshold in milliseconds, not necessarily own, or * the framework default of 75, if none was set. @@ -376,7 +364,7 @@ export interface ReflectRoot extends ReflectCommon { isRoot: true; /** - * Whether a particulare reporter was registered + * Whether a particular reporter was registered */ hasReporter(reporter: Reporter): boolean; @@ -394,6 +382,21 @@ export interface ReflectRoot extends ReflectCommon { * Remove a reporter. */ removeReporter(reporter: Reporter): void; + + /** + * Get the test name. + */ + name: void; + + /** + * Get the test index. + */ + index: void; + + /** + * Get the parent test as a Reflect. + */ + parent: void; } export interface ReflectChild extends ReflectCommon { diff --git a/internal.js b/internal.js index d30d72d..78f0f4a 100644 --- a/internal.js +++ b/internal.js @@ -2,7 +2,7 @@ var Thallium = require("./lib/api/thallium") var Reports = require("./lib/core/reports") -var Types = Reports.Types +var HookStage = Reports.HookStage exports.root = function () { return new Thallium() @@ -78,19 +78,19 @@ exports.reports = { */ exports.hookErrors = { beforeAll: function (func, value) { - return new Reports.HookError(Types.BeforeAll, func, value) + return new Reports.HookError(HookStage.BeforeAll, func, value) }, beforeEach: function (func, value) { - return new Reports.HookError(Types.BeforeEach, func, value) + return new Reports.HookError(HookStage.BeforeEach, func, value) }, afterEach: function (func, value) { - return new Reports.HookError(Types.AfterEach, func, value) + return new Reports.HookError(HookStage.AfterEach, func, value) }, afterAll: function (func, value) { - return new Reports.HookError(Types.AfterAll, func, value) + return new Reports.HookError(HookStage.AfterAll, func, value) }, } diff --git a/lib/api/common.js b/lib/api/common.js index 833800b..fa92115 100644 --- a/lib/api/common.js +++ b/lib/api/common.js @@ -26,22 +26,3 @@ exports.hasHook = function (list, callback) { if (list.length > 1) return list.indexOf(callback) >= 0 return list[0] === callback } - -// TODO: cache and remove these traversals for 0.4. -// Note that a timeout of 0 means to inherit the parent. -exports.getTimeout = function (test) { - while (!test.timeout && test.parent != null) { - test = test.parent - } - - return test.timeout || 2000 // ms - default timeout -} - -// Note that a slowness threshold of 0 means to inherit the parent. -exports.getSlow = function (test) { - while (!test.slow && test.parent != null) { - test = test.parent - } - - return test.slow || 75 // ms - default slow threshold -} diff --git a/lib/api/reflect.js b/lib/api/reflect.js index 2ef7584..b4d0cc5 100644 --- a/lib/api/reflect.js +++ b/lib/api/reflect.js @@ -13,11 +13,64 @@ function Reflect(test) { var reflect = test.reflect if (reflect != null) return reflect - if (test.root !== test) return test.reflect = new ReflectChild(test) - return test.reflect = new ReflectRoot(test) + test.reflect = this + this._ = test } methods(Reflect, { + /** + * Whether a reporter was registered. + */ + hasReporter: function (reporter) { + if (typeof reporter !== "function") { + throw new TypeError("Expected `reporter` to be a function") + } + + return this._.root.reporterIds.indexOf(reporter) >= 0 + }, + + /** + * Add a reporter. + */ + reporter: function (reporter, arg) { + if (typeof reporter !== "function") { + throw new TypeError("Expected `reporter` to be a function") + } + + var root = this._.root + + if (root.current !== root) { + throw new Error("Reporters may only be added to the root") + } + + if (root.reporterIds.indexOf(reporter) < 0) { + root.reporterIds.push(reporter) + root.reporters.push(reporter(arg)) + } + }, + + /** + * Remove a reporter. + */ + removeReporter: function (reporter) { + if (typeof reporter !== "function") { + throw new TypeError("Expected `reporter` to be a function") + } + + var root = this._.root + + if (root.current !== root) { + throw new Error("Reporters may only be added to the root") + } + + var index = root.reporterIds.indexOf(reporter) + + if (index >= 0) { + root.reporterIds.splice(index, 1) + root.reporters.splice(index, 1) + } + }, + /** * Get the currently executing test. */ @@ -44,10 +97,15 @@ methods(Reflect, { * intentionally a slice, so you can't mutate the real children. */ get children() { - if (this._.tests == null) return [] - return this._.tests.map(function (test) { - return new ReflectChild(test) - }) + var children = [] + + if (this._.tests != null) { + for (var i = 0; i < this._.tests.length; i++) { + children[i] = new Reflect(this._.tests[i]) + } + } + + return children }, /** @@ -64,28 +122,12 @@ methods(Reflect, { return !!this._.locked }, - /** - * Get the own, not necessarily active, timeout. 0 means inherit the - * parent's, and `Infinity` means it's disabled. - */ - get ownTimeout() { - return this._.timeout || 0 - }, - /** * Get the active timeout in milliseconds, not necessarily own, or the * framework default of 2000, if none was set. */ get timeout() { - return Common.getTimeout(this._) - }, - - /** - * Get the own, not necessarily active, slow threshold. 0 means inherit the - * parent's, and `Infinity` means it's disabled. - */ - get ownSlow() { - return this._.slow || 0 + return this._.timeout || Tests.defaultTimeout }, /** @@ -93,7 +135,7 @@ methods(Reflect, { * the framework default of 75, if none was set. */ get slow() { - return Common.getSlow(this._) + return this._.slow || Tests.defaultSlow }, /** @@ -112,6 +154,30 @@ methods(Reflect, { return this._.isFailable }, + /** + * Get the test name, or `undefined` if it's the root test. + */ + get name() { + if (this._.parent == null) return undefined + return this._.name + }, + + /** + * Get the test index, or `undefined` if it's the root test. + */ + get index() { + if (this._.parent == null) return undefined + return this._.index + }, + + /** + * Get the test's parent as a Reflect, or `undefined` if it's the root test. + */ + get parent() { + if (this._.parent == null) return undefined + return new Reflect(this._.parent) + }, + /** * Add a hook to be run before each subtest, including their subtests and so * on. @@ -276,89 +342,3 @@ methods(Reflect, { Tests.addSkipped(this._.root.current, name) }, }) - -function ReflectRoot(root) { - this._ = root -} - -methods(ReflectRoot, Reflect, { - /** - * Whether a reporter was registered. - */ - hasReporter: function (reporter) { - if (typeof reporter !== "function") { - throw new TypeError("Expected `reporter` to be a function") - } - - return this._.root.reporterIds.indexOf(reporter) >= 0 - }, - - /** - * Add a reporter. - */ - reporter: function (reporter, arg) { - if (typeof reporter !== "function") { - throw new TypeError("Expected `reporter` to be a function") - } - - var root = this._.root - - if (root.current !== root) { - throw new Error("Reporters may only be added to the root") - } - - if (root.reporterIds.indexOf(reporter) < 0) { - root.reporterIds.push(reporter) - root.reporters.push(reporter(arg)) - } - }, - - /** - * Remove a reporter. - */ - removeReporter: function (reporter) { - if (typeof reporter !== "function") { - throw new TypeError("Expected `reporter` to be a function") - } - - var root = this._.root - - if (root.current !== root) { - throw new Error("Reporters may only be added to the root") - } - - var index = root.reporterIds.indexOf(reporter) - - if (index >= 0) { - root.reporterIds.splice(index, 1) - root.reporters.splice(index, 1) - } - }, -}) - -function ReflectChild(root) { - this._ = root -} - -methods(ReflectChild, Reflect, { - /** - * Get the test name, or `undefined` if it's the root test. - */ - get name() { - return this._.name - }, - - /** - * Get the test index, or `-1` if it's the root test. - */ - get index() { - return this._.index - }, - - /** - * Get the parent test as a Reflect. - */ - get parent() { - return new Reflect(this._.parent) - }, -}) diff --git a/lib/api/thallium.js b/lib/api/thallium.js index 5f5a050..263b61c 100644 --- a/lib/api/thallium.js +++ b/lib/api/thallium.js @@ -8,7 +8,7 @@ var Reflect = require("./reflect") module.exports = Thallium function Thallium() { - this._ = Tests.createRoot(this) + this._ = Tests.createRoot() } methods(Thallium, { @@ -70,7 +70,7 @@ methods(Thallium, { * means it's disabled. */ get timeout() { - return Common.getTimeout(this._.root.current) + return this._.root.current.timeout || Tests.defaultTimeout }, /** @@ -87,7 +87,7 @@ methods(Thallium, { * `Infinity` means it's disabled. */ get slow() { - return Common.getSlow(this._.root.current) + return this._.root.current.slow || Tests.defaultSlow }, /** diff --git a/lib/cli/init-common.js b/lib/cli/init-common.js index a4112b4..df50f51 100644 --- a/lib/cli/init-common.js +++ b/lib/cli/init-common.js @@ -25,6 +25,7 @@ function Warning(message) { this.message = message } +// This avoids the `methods` helper to not load an additional module. Warning.prototype = Object.create(Error.prototype, { name: { configurable: true, diff --git a/lib/core/reports.js b/lib/core/reports.js index 732904f..024528e 100644 --- a/lib/core/reports.js +++ b/lib/core/reports.js @@ -17,13 +17,16 @@ var Types = exports.Types = Object.freeze({ End: 6, Error: 7, - // Note that `Hook` is denoted by the 4th bit set, to save some space (and - // to simplify the type representation). + // Note that `Hook` is actually a bit flag, to save some space (and to + // simplify the type representation). Hook: 8, - BeforeAll: 8 | 0, - BeforeEach: 8 | 1, - AfterEach: 8 | 2, - AfterAll: 8 | 3, +}) + +var HookStage = exports.HookStage = Object.freeze({ + BeforeAll: Types.Hook | 0, + BeforeEach: Types.Hook | 1, + AfterEach: Types.Hook | 2, + AfterAll: Types.Hook | 3, }) exports.Report = Report @@ -236,18 +239,18 @@ methods(ErrorReport, Report, { var HookMethods = { get stage() { switch (this._) { - case Types.BeforeAll: return "before all" - case Types.BeforeEach: return "before each" - case Types.AfterEach: return "after each" - case Types.AfterAll: return "after all" + case HookStage.BeforeAll: return "before all" + case HookStage.BeforeEach: return "before each" + case HookStage.AfterEach: return "after each" + case HookStage.AfterAll: return "after all" default: throw new Error("unreachable") } }, - get isBeforeAll() { return this._ === Types.BeforeAll }, - get isBeforeEach() { return this._ === Types.BeforeEach }, - get isAfterEach() { return this._ === Types.AfterEach }, - get isAfterAll() { return this._ === Types.AfterAll }, + get isBeforeAll() { return this._ === HookStage.BeforeAll }, + get isBeforeEach() { return this._ === HookStage.BeforeEach }, + get isAfterEach() { return this._ === HookStage.AfterEach }, + get isAfterAll() { return this._ === HookStage.AfterAll }, } exports.HookError = HookError diff --git a/lib/core/tests.js b/lib/core/tests.js index 5f9eed0..7e847ee 100644 --- a/lib/core/tests.js +++ b/lib/core/tests.js @@ -4,7 +4,7 @@ var methods = require("../methods") var peach = require("../util").peach var Reports = require("./reports") var Filter = require("./filter") -var Types = Reports.Types +var HookStage = Reports.HookStage /** * The tests are laid out in a very data-driven design. With exception of the @@ -42,7 +42,6 @@ function Result(time, attempt) { /** * Overview of the test properties: * - * - `methods` - A deprecated reference to the API methods * - `root` - The root test * - `reporters` - The list of reporters * - `current` - A reference to the currently active test @@ -59,12 +58,7 @@ function Result(time, attempt) { * Many of these properties aren't present on initialization to save memory. */ -// TODO: remove `test.methods` in 0.4 function Normal(name, index, parent, callback) { - var child = Object.create(parent.methods) - - child._ = this - this.methods = child this.locked = true this.root = parent.root this.name = name @@ -74,8 +68,8 @@ function Normal(name, index, parent, callback) { this.isFailable = parent.isFailable this.attempts = parent.attempts - this.timeout = 0 - this.slow = 0 + this.timeout = parent.timeout + this.slow = parent.slow this.tests = undefined this.beforeAll = undefined this.beforeEach = undefined @@ -99,10 +93,8 @@ function Skipped(name, index, parent) { this.reflect = undefined } -// TODO: remove `test.methods` in 0.4 -function Root(methods) { +function Root() { this.locked = false - this.methods = methods this.reporterIds = [] this.reporters = [] this.current = this @@ -179,24 +171,8 @@ exports.clearTests = function (parent) { * Execute the tests */ -// TODO: cache and remove these traversals for 0.4. -// Note that a timeout of 0 means to inherit the parent. -function findTimeout(tests) { - for (var i = tests.length - 1; i >= 0; i--) { - if (tests[i].timeout) return tests[i].timeout - } - - return 2000 // ms - default timeout -} - -// Note that a slowness threshold of 0 means to inherit the parent. -function findSlow(tests) { - for (var i = tests.length - 1; i >= 0; i--) { - if (tests[i].slow) return tests[i].slow - } - - return 75 // ms - default slow threshold -} +exports.defaultTimeout = 2000 // ms +exports.defaultSlow = 75 // ms function makeSlice(tests, length) { var ret = new Array(length) @@ -208,70 +184,95 @@ function makeSlice(tests, length) { return ret } -function report(context, type, arg1, arg2) { - function invokeReporter(reporter) { - switch (type) { - case Types.Start: - return reporter(new Reports.Start()) - - case Types.Enter: - return reporter( - new Reports.Enter( - makeSlice(context.tests, context.tests.length), arg1, - findSlow(context.tests))) - - case Types.Leave: - return reporter(new Reports.Leave( - makeSlice(context.tests, context.tests.length))) - - case Types.Pass: - return reporter( - new Reports.Pass( - makeSlice(context.tests, context.tests.length), arg1, - findSlow(context.tests))) - - case Types.Fail: - return reporter( - new Reports.Fail( - makeSlice(context.tests, context.tests.length), arg1, arg2, - findSlow(context.tests), - !!context.root.current.isFailable)) - - case Types.Skip: - return reporter(new Reports.Skip( - makeSlice(context.tests, context.tests.length))) - - case Types.End: - return reporter(new Reports.End()) - - case Types.Error: - return reporter(new Reports.Error(arg1)) - - case Types.Hook: - // Include the last test. This also implicitly sets the end to 0 for - // root tests. - return reporter(new Reports.Hook( - makeSlice(context.tests, context.tests.length), - makeSlice(context.tests, context.tests.indexOf(arg1) + 1), - arg2)) - - default: - throw new TypeError("unreachable") - } - } - +function reportWith(context, func) { return Promise.resolve() .then(function () { if (context.root.reporter == null) return undefined - return invokeReporter(context.root.reporter) + return func(context.root.reporter) }) .then(function () { var reporters = context.root.reporters // Two easy cases. if (reporters.length === 0) return undefined - if (reporters.length === 1) return invokeReporter(reporters[0]) - return Promise.all(reporters.map(invokeReporter)) + if (reporters.length === 1) return func(reporters[0]) + return Promise.all(reporters.map(func)) + }) +} + +function reportStart(context) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Start()) + }) +} + +function reportEnter(context, duration) { + var test = context.root.current + var slow = test.slow || exports.defaultSlow + + return reportWith(context, function (reporter) { + var path = makeSlice(context.tests, context.tests.length) + + return reporter(new Reports.Enter(path, duration, slow)) + }) +} + +function reportLeave(context) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Leave( + makeSlice(context.tests, context.tests.length))) + }) +} + +function reportPass(context, duration) { + var test = context.root.current + var slow = test.slow || exports.defaultSlow + + return reportWith(context, function (reporter) { + var path = makeSlice(context.tests, context.tests.length) + + return reporter(new Reports.Pass(path, duration, slow)) + }) +} + +function reportFail(context, error, duration) { + var test = context.root.current + var slow = test.slow || exports.defaultSlow + var isFailable = test.isFailable + + return reportWith(context, function (reporter) { + var path = makeSlice(context.tests, context.tests.length) + + return reporter(new Reports.Fail( + path, error, duration, slow, isFailable)) + }) +} + +function reportSkip(context) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Skip( + makeSlice(context.tests, context.tests.length))) + }) +} + +function reportEnd(context) { + return reportWith(context, function (reporter) { + return reporter(new Reports.End()) + }) +} + +function reportError(context, error) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Error(error)) + }) +} + +function reportHook(context, test, error) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Hook( + makeSlice(context.tests, context.tests.length), + makeSlice(context.tests, context.tests.indexOf(test) + 1), + error)) }) } @@ -333,7 +334,7 @@ function asyncFinish(state, attempt) { function invokeInit(context, count) { var test = context.root.current var start = now() - var tryBody = try1(test.callback, test.methods, test.methods) + var tryBody = try0(test.callback) var syncEnd = now() // Note: synchronous failures are test failures, not fatal errors. @@ -376,7 +377,7 @@ function invokeInit(context, count) { // Set the timeout *after* initialization. The timeout will likely be // specified during initialization. - var maxTimeout = findTimeout(context.tests) + var maxTimeout = test.timeout || exports.defaultTimeout // Setting a timeout is pointless if it's infinite. if (maxTimeout !== Infinity) { @@ -409,19 +410,19 @@ function invokeHook(test, list, stage) { function invokeBeforeEach(test) { if (test.root === test) { - return invokeHook(test, test.beforeEach, Types.BeforeEach) + return invokeHook(test, test.beforeEach, HookStage.BeforeEach) } else { return invokeBeforeEach(test.parent).then(function () { - return invokeHook(test, test.beforeEach, Types.BeforeEach) + return invokeHook(test, test.beforeEach, HookStage.BeforeEach) }) } } function invokeAfterEach(test) { if (test.root === test) { - return invokeHook(test, test.afterEach, Types.AfterEach) + return invokeHook(test, test.afterEach, HookStage.AfterEach) } else { - return invokeHook(test, test.afterEach, Types.AfterEach) + return invokeHook(test, test.afterEach, HookStage.AfterEach) .then(function () { return invokeAfterEach(test.parent) }) } } @@ -461,7 +462,7 @@ function runChildTests(test, context) { .then(function () { return invokeAfterEach(test) }) .catch(function (e) { if (!(e instanceof ErrorWrap)) throw e - return report(context, Types.Hook, e.test, e.error) + return reportHook(context, e.test, e.error) }) .then(leave, function (e) { leave(); throw e }) } @@ -474,7 +475,7 @@ function runChildTests(test, context) { test.root.current = child context.tests.push(child) - return report(context, Types.Skip) + return reportSkip(context) .then(leave, function (e) { leave(); throw e }) } else if (!isOnly(child)) { return Promise.resolve() @@ -482,12 +483,13 @@ function runChildTests(test, context) { return runChild(child) } else { ran = true - return invokeHook(test, test.beforeAll, Types.BeforeAll) + return invokeHook(test, test.beforeAll, HookStage.BeforeAll) .then(function () { return runChild(child) }) } }) .then(function () { - return ran ? invokeHook(test, test.afterAll, Types.AfterAll) : undefined + if (!ran) return undefined + return invokeHook(test, test.afterAll, HookStage.AfterAll) }) } @@ -508,21 +510,21 @@ function runNormalChild(test, context) { .then(function (result) { if (result.caught) { if (!test.isFailable) context.isSuccess = false - return report(context, Types.Fail, result.value, result.time) + return reportFail(context, result.value, result.time) } else if (test.tests != null) { // Report this as if it was a parent test if it's passing and has // children. - return report(context, Types.Enter, result.time) + return reportEnter(context, result.time) .then(function () { return runChildTests(test, context) }) - .then(function () { return report(context, Types.Leave) }) + .then(function () { return reportLeave(context) }) .catch(function (e) { if (!(e instanceof ErrorWrap)) throw e - return report(context, Types.Leave).then(function () { - return report(context, Types.Hook, e.test, e.error) + return reportLeave(context).then(function () { + return reportHook(context, e.test, e.error) }) }) } else { - return report(context, Types.Pass, result.time) + return reportPass(context, result.time) } }) .then( @@ -537,17 +539,17 @@ exports.runTest = function (root, opts) { var context = new Context(root, opts) root.locked = true - return report(context, Types.Start) + return reportStart(context) .then(function () { return runChildTests(root, context) }) .catch(function (e) { if (!(e instanceof ErrorWrap)) throw e - return report(context, Types.Hook, e.test, e.error) + return reportHook(context, e.test, e.error) }) - .then(function () { return report(context, Types.End) }) + .then(function () { return reportEnd(context) }) // Tell the reporter something happened. Otherwise, it'll have to wrap this // method in a plugin, which shouldn't be necessary. .catch(function (e) { - return report(context, Types.Error, e).then(function () { throw e }) + return reportError(context, e).then(function () { throw e }) }) .then( function () { @@ -574,6 +576,14 @@ function tryFail(e) { return {caught: true, value: e} } +function try0(f) { + try { + return tryPass(f()) + } catch (e) { + return tryFail(e) + } +} + function try1(f, inst, arg0) { try { return tryPass(f.call(inst, arg0)) diff --git a/migrate/bundle.js b/migrate/bundle.js index ed3fce1..14c7488 100644 --- a/migrate/bundle.js +++ b/migrate/bundle.js @@ -1,11 +1,5 @@ "use strict" module.exports = require("../lib/browser-bundle") - -require("../migrate/index") - -// Note: both of these are deprecated -module.exports.assertions = require("../assertions") -module.exports.create = require("../migrate/common").deprecate( - "`tl.create` is deprecated. Please use `tl.root` instead.", - module.exports.root) +require("./index") +module.exports.support = require("./support") diff --git a/migrate/index.js b/migrate/index.js index 65aed72..3c0911c 100644 --- a/migrate/index.js +++ b/migrate/index.js @@ -9,521 +9,5 @@ * requires. */ -var Common = require("./common") -var Internal = require("../internal") -var methods = require("../lib/methods") -var Report = require("../lib/core/reports").Report -var Reflect = require("../lib/api/reflect") -var Thallium = require("../lib/api/thallium") - -var assert = require("clean-assert") - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - `reflect.checkInit()` is deprecated in favor of `reflect.locked` and * - * either complaining yourself or just using `reflect.current` to add * - * things. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -methods(Reflect, { - checkInit: Common.deprecate( - "`reflect.checkInit` is deprecated. Use `reflect.current` for the " + - "current test or use `reflect.locked` and create and throw the error " + - "yourself.", - /** @this */ function () { - if (this.locked) { - throw new ReferenceError("It is only safe to call test " + - "methods during initialization") - } - }), -}) - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - `t.async` -> `t.test`, which now supports promises. * - * - All tests are now async. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -var test = Thallium.prototype.test - -function runAsync(callback, t, resolve, reject) { - var resolved = false - var gen = callback.call(t, t, function (err) { - if (resolved) return - Common.warn("`t.async` is deprecated. " + - "Use `t.test` and return a promise instead.") - - resolved = true - if (err != null) reject(err) - else resolve() - }) - - if (resolved) return - - if (typeof gen.next !== "function") { - // Allow the migration path to standard thenables. - resolve(gen) - return - } - - Common.warn("`t.async` is deprecated. Use `t.test` and either return a " + - "promise or use `co`/ES2017 async functions instead.") - - // This is a modified version of the async-await official, non-normative - // desugaring helper, for better error checking and adapted to accept an - // already-instantiated iterator instead of a generator. - function iterate(next) { - // finished with success, resolve the promise - if (next.done) return Promise.resolve(next.value) - - // not finished, chain off the yielded promise and step again - return Promise.resolve(next.value).then( - function (v) { return iterate(gen.next(v)) }, - function (e) { - if (typeof gen.throw === "function") { - return iterate(gen.throw(e)) - } else { - throw e - } - }) - } - - iterate(gen.next(undefined)).then(resolve, reject) -} - -methods(Thallium, { - async: function (name, callback) { - if (typeof callback !== "function") { - // Reuse the normal error handling. - return test.apply(this, arguments) - } else { - return test.call(this, name, function (t) { - return new Promise(function (resolve, reject) { - return runAsync(callback, t, resolve, reject) - }) - }) - } - }, - - asyncSkip: Common.deprecate( - "`t.asyncSkip` is deprecated. Use `t.testSkip` instead.", - Thallium.prototype.testSkip), -}) - -methods(Reflect, { - get isAsync() { - Common.warn("Tests are now always async. You no longer need to " + - "handle the other case") - return true - }, -}) - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * `reflect.define`, `t.define`, `reflect.wrap`, and `reflect.add`, are all * - * removed. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -function isLocked(method) { - return method === "_" || - method === "reflect" || - method === "only" || - method === "use" || - method === "reporter" || - method === "define" || - method === "timeout" || - method === "slow" || - method === "run" || - method === "test" || - method === "testSkip" || - method === "async" || - method === "asyncSkip" -} - -function getEnumerableSymbols(keys, object) { - var symbols = Object.getOwnPropertySymbols(object) - - for (var i = 0; i < symbols.length; i++) { - var sym = symbols[i] - - if (Object.getOwnPropertyDescriptor(sym).enumerable) keys.push(sym) - } -} - -// This handles name + func vs object with methods. -function iterateSetter(test, name, func, iterator) { - // Check both the name and function, so ES6 symbol polyfills (which use - // objects since it's impossible to fully polyfill primitives) work. - if (typeof name === "object" && name != null && func == null) { - var keys = Object.keys(name) - - if (typeof Object.getOwnPropertySymbols === "function") { - getEnumerableSymbols(keys, name) - } - - for (var i = 0; i < keys.length; i++) { - var key = keys[i] - - if (typeof name[key] !== "function") { - throw new TypeError("Expected body to be a function") - } - - test.methods[key] = iterator(test, key, name[key]) - } - } else { - if (typeof func !== "function") { - throw new TypeError("Expected body to be a function") - } - - test.methods[name] = iterator(test, name, func) - } -} - -/** - * @this {State} - * Run `func` with `...args` when assertions are run, only if the test isn't - * skipped. This is immediately for block and async tests, but deferred for - * inline tests. It's useful for inline assertions. - */ -function attempt(func, a, b, c/* , ...args */) { - switch (arguments.length) { - case 0: throw new TypeError("unreachable") - case 1: func(); return - case 2: func(a); return - case 3: func(a, b); return - case 4: func(a, b, c); return - default: - var args = [] - - for (var i = 1; i < arguments.length; i++) { - args.push(arguments[i]) - } - - func.apply(undefined, args) - } -} - -function defineAssertion(test, name, func) { - // Don't let native methods get overridden by assertions - if (isLocked(name)) { - throw new RangeError("Method '" + name + "' is locked!") - } - - function run() { - var res = func.apply(undefined, arguments) - - if (typeof res !== "object" || res === null) { - throw new TypeError("Expected result to be an object") - } - - if (!res.test) { - assert.fail(res.message, res) - } - } - - return /** @this */ function () { - var args = [run] - - args.push.apply(args, arguments) - attempt.apply(undefined, args) - return this - } -} - -function wrapAssertion(test, name, func) { - // Don't let `reflect` and `_` change. - if (name === "reflect" || name === "_") { - throw new RangeError("Method '" + name + "' is locked!") - } - - var old = test.methods[name] - - if (typeof old !== "function") { - throw new TypeError( - "Expected t." + name + " to already be a function") - } - - /** @this */ - function apply(a, b, c, d) { - switch (arguments.length) { - case 0: return func.call(this, old.bind(this)) - case 1: return func.call(this, old.bind(this), a) - case 2: return func.call(this, old.bind(this), a, b) - case 3: return func.call(this, old.bind(this), a, b, c) - case 4: return func.call(this, old.bind(this), a, b, c, d) - default: - var args = [old.bind(this)] - - for (var i = 0; i < arguments.length; i++) { - args.push(arguments[i]) - } - - return func.apply(this, args) - } - } - - return /** @this */ function () { - var ret = apply.apply(this, arguments) - - return ret !== undefined ? ret : this - } -} - -function addAssertion(test, name, func) { - if (typeof test.methods[name] !== "undefined") { - throw new TypeError("Method '" + name + "' already exists!") - } - - /** @this */ - function apply(a, b, c, d) { - switch (arguments.length) { - case 0: return func.call(this, this) - case 1: return func.call(this, this, a) - case 2: return func.call(this, this, a, b) - case 3: return func.call(this, this, a, b, c) - case 4: return func.call(this, this, a, b, c, d) - default: - var args = [this] - - for (var i = 0; i < arguments.length; i++) { - args.push(arguments[i]) - } - - return func.apply(this, args) - } - } - - return /** @this */ function () { - var ret = apply.apply(this, arguments) - - return ret !== undefined ? ret : this - } -} - -methods(Reflect, { - define: Common.deprecate( - "`reflect.define` is deprecated. Use external methods or direct assignment instead.", // eslint-disable-line max-len - /** @this */ function (name, func) { - iterateSetter(this._.current.value, name, func, defineAssertion) - }), - - wrap: Common.deprecate( - "`reflect.wrap` is deprecated. Use external methods or direct assignment instead.", // eslint-disable-line max-len - /** @this */ function (name, func) { - iterateSetter(this._.current.value, name, func, wrapAssertion) - }), - - add: Common.deprecate( - "`reflect.add` is deprecated. Use external methods or direct assignment instead.", // eslint-disable-line max-len - /** @this */ function (name, func) { - iterateSetter(this._.current.value, name, func, addAssertion) - }), -}) - -methods(Thallium, { - define: Common.deprecate( - "`t.define` is deprecated. Use external methods or direct assignment instead.", // eslint-disable-line max-len - /** @this */ function (name, func) { - iterateSetter(this._.current.value, name, func, defineAssertion) - return this - }), -}) - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - `reflect.do` is deprecated, with no replacement (inline tests are also * - * deprecated). * - * - `reflect.base` -> `internal.root` * - * - `reflect.AssertionError` -> `assert.AssertionError`. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -methods(Reflect, { - // Deprecated aliases - do: Common.deprecate( - "`reflect.do` is deprecated. Transition to block tests, if necessary, and run the code directly.", // eslint-disable-line max-len - /** @this */ function (func) { - if (typeof func !== "function") { - throw new TypeError("Expected callback to be a function") - } - - attempt.apply(undefined, arguments) - return this - }), - base: Common.deprecate( - "`reflect.base` is deprecated. Use `internal.root` from `thallium/internal` instead.", // eslint-disable-line max-len - Internal.root), -}) - -// ESLint oddly can't tell these are shadowed. -/* eslint-disable no-extend-native */ - -function lockError(AssertionError) { - Object.defineProperty(Reflect.prototype, "AssertionError", { - writable: true, - value: AssertionError, - }) - return AssertionError -} - -Object.defineProperty(Reflect.prototype, "AssertionError", { - configurable: true, - enumerable: false, - get: Common.deprecate( - "`reflect.AssertionError` is deprecated. Use `assert.AssertionError` from `thallium/assert` instead.", // eslint-disable-line max-len - function () { return lockError(assert.AssertionError) }), - set: Common.deprecate( - "`reflect.AssertionError` is deprecated. Use `assert.AssertionError` from `thallium/assert` instead.", // eslint-disable-line max-len - lockError), -}) - -/* eslint-enable no-extend-native */ - -methods(Thallium, { - base: Common.deprecate( - "`t.base` is deprecated. Use `t.create` instead.", - function () { return new Thallium() }), -}) - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - assertions defined on main export * - * - `t.*` assertions -> `assert.*` (some renamed) from `thallium/assert` * - * - `t.true`/etc. are gone (except `t.undefined` -> `assert.isUndefined`) * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -Common.hideDeprecation() -require("../assertions")(require("../index")) -Common.showDeprecation() - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * `extra` events are no longer a thing. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -methods(Report, { - get isInline() { - Common.warn("`extra` events no longer exist. You no longer need to " + - "handle them") - return false - }, -}) - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - `t.reflect` and `t.use` -> non-caching `t.call` * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -var call = Thallium.prototype.call - -function id(x) { return x } - -methods(Thallium, { - reflect: Common.deprecate( - "`t.reflect` is deprecated. Use `t.call` instead.", - /** @this */ function () { return call.call(this, id) }), - - use: Common.deprecate( - "`t.use` is deprecated. Use `t.call` instead.", - /** @this */ function () { - var reflect = call.call(this, id) - - if (!reflect.skipped) { - var test = this._.current.value - - for (var i = 0; i < arguments.length; i++) { - var plugin = arguments[i] - - if (typeof plugin !== "function") { - throw new TypeError( - "Expected `plugin` to be a function") - } - - if (test.plugins == null) test.plugins = [] - if (test.plugins.indexOf(plugin) === -1) { - // Add plugin before calling it. - test.plugins.push(plugin) - plugin.call(this, this) - } - } - } - - return this - }), -}) - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - `reflect.report` -> `internal.report.*` * - * - `reflect.loc` -> `internal.location` * - * - `reflect.scheduler` obsoleted. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -var reports = Internal.reports - -methods(Reflect, { - report: Common.deprecate( - "`reflect.report` is deprecated. Use `internal.report.*` from `thallium/internal` instead.", // eslint-disable-line max-len - function (type, path, value, duration, slow) { // eslint-disable-line max-params, max-len - if (typeof type !== "string") { - throw new TypeError("Expected `type` to be a string") - } - - switch (type) { - case "start": return reports.start() - case "enter": return reports.enter(path, duration, slow) - case "leave": return reports.leave(path) - case "pass": return reports.pass(path, duration, slow) - case "fail": return reports.fail(path, value, duration, slow) - case "skip": return reports.skip(path) - case "end": return reports.end() - case "error": return reports.error(value) - case "hook": return reports.hook(path, value) - default: throw new RangeError("Unknown report `type`: " + type) - } - }), - - loc: Common.deprecate( - "`reflect.loc` is deprecated. Use `internal.location` from `thallium/internal` instead.", // eslint-disable-line max-len - Internal.location), - - scheduler: Common.deprecate( - "`reflect.scheduler` is deprecated. It is no longer useful to the library, and can be safely removed.", // eslint-disable-line max-len - function () {}), -}) - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Inline tests are deprecated. This is "fixed" by just throwing, since it's * - * hard to patch back in and easy to fix on the user's end. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -methods(Thallium, { - test: function (name, func) { - if (func == null) { - // Catch this particular case, to throw with a more informative - // messsage. - throw new TypeError( - "Inline tests are deprecated. Use block tests instead.") - } - - return test.apply(this, arguments) - }, -}) - -methods(Reflect, { - get isInline() { - Common.warn("Tests are now never inline. You no longer need to " + - "handle this case") - return false - }, -}) - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * `reflect.methods` -> `reflect.current` and using new `reflect` methods * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -methods(Reflect, { - get methods() { - Common.warn("`reflect.methods` is deprecated. Use `reflect.current`, " + - "the return value of `t.call`, and the appropriate new `reflect` " + - "methods instead") - return this._.methods - }, -}) - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * `reflect.reporters` -> `reflect.hasReporter` * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -methods(Reflect, { - get reporters() { - Common.warn("`reflect.reporters` is deprecated. Use " + - "`reflect.hasReporter` instead to check for existence of a " + - "reporter.") - return this._.methods - }, -}) +// var Common = require("./common") +// var methods = require("../lib/methods") diff --git a/migrate/support.js b/migrate/support.js new file mode 100644 index 0000000..eebe0fb --- /dev/null +++ b/migrate/support.js @@ -0,0 +1 @@ +"use strict" diff --git a/roadmap.md b/roadmap.md index a88e0a9..e3f1ecd 100644 --- a/roadmap.md +++ b/roadmap.md @@ -12,49 +12,46 @@ See the [changelog](https://github.com/isiahmeadows/thallium/blob/master/CHANGEL Note that as of this version, only the primary API of the previous version will be supported as much as feasibly possible through `thallium/migrate`. Reporter and plugin APIs will not such have a wrapper available, but may use the utilities in `thallium/migrate/support` to use while transitioning. -1. Remove all the previously deprecated methods/etc. - - Additionally, seal all exposed API types, as a safety net - - Remove `reflect.own*` properties and make all properties own and parasitically inherited from their parent, to avoid costly lookups (already done for attempts) -2. Make this a monorepo using Lerna - - All dependencies merged in will encounter a minor version increment -3. Add `--respawn-as` to allow respawning via a binary other than the default (e.g. Electron) +1. ~~Remove all the previously deprecated methods/etc.~~ + - ~~Remove `reflect.own*` properties and make them parasitically inherited from their parent, to avoid costly lookups (already done for attempts)~~ +2. Add `--respawn-as` to allow respawning via a binary other than the default (e.g. Electron) - This will force a respawn using a PATH lookup if necessary -4. Add `--env` to allow setting environment on startup, before any respawning occurs +3. Add `--env` to allow setting environment on startup, before any respawning occurs - This will force a respawn -5. Make `t.only` also a `t.run()` option +4. Make `t.only` also a `t.run()` option - Now that `t.only` is detected at test run time, this is way easier to do, and it just makes more sense here than as a setter - Also, accept a `skip` option to skip certain tests. -6. Expose `thallium` as global `t` in bundle, tack existing `tl.*` exports onto it +5. Expose `thallium` as global `t` in bundle, tack existing `tl.*` exports onto it - Expose `thallium/assert` as global `assert` instead - Don't expose `require("thallium")` -7. Return in the promise a result object of various statistics +6. Return in the promise a result object of various statistics - Also, return these within the `end` report -8. Add some promise-aware assertions (in `clean-assert`) -9. Move `exports.files` config option to `t.files` +7. Add some promise-aware assertions (in `clean-assert`) +8. Move `exports.files` config option to `t.files` - Change `exports.thallium` to default export - Ignored by core, but will mildly simplify CLI interface - Will make parallel interface much more consistent -10. Allow full name matching of `t.only` +9. Allow full name matching of `t.only` - Detected via no array - Feature parity with most other heavy frameworks -11. Add `t.options` getter/setter for default run options -12. Add some useful things for test generation and reporters like getting the full test name -13. Make reports backed by a tree, and convert the public API to expose only getters +10. Add `t.options` getter/setter for default run options +11. Add some useful things for test generation and reporters like getting the full test name +12. Make reports backed by a tree, and convert the public API to expose only getters - Abstracts away the internal representation - Reduce reporter GC -14. Cache the settings for child tests after they are re-locked +13. Cache the settings for child tests after they are re-locked - This gets rid of all the tree climbing nonsense that currently exists - This will streamline settings a *lot* more -15. Add file watching support +14. Add file watching support - Just invoke the CLI with `--force-local` and the appropriate Node flags on each change. Way easier than trying to clean up `node_modules`, and you get more easily reproduced runs - Mocha's magical behavior isn't helpful when dealing with globals (I've had enough pains in this repo already) -16. Add the ability to programmatically skip a test before it completes +15. Add the ability to programmatically skip a test before it completes - Required for integration tests - `t.skip()`/`reflect.skip()` throws an `reflect.Skip` (an Error subclass) to skip a test -17. Expose `thallium/internal` as `reflect.internal()` -18. Expose a detached `reflect` via `t.reflect()` +16. Expose `thallium/internal` as `reflect.internal()` +17. Expose a detached `reflect` via `t.reflect()` - Mainly for easier testing/etc. -19. Load bundle automatically, and implement `data-*` attribute options +18. Load bundle automatically, and implement `data-*` attribute options ## 0.4.x (not blocking 0.4.0) @@ -104,6 +101,10 @@ Here's the nice-to-haves, and so these are in no particular order: - Downleveled async functions will drastically simplify both the runner and all the reporters - It'll be a *lot* easier when most of the deprecated dynamic stuff like test inheritance is finally removed +- Make this a monorepo using Lerna + - All dependencies merged in will encounter a minor version increment + - This will be a pretty non-trivial process. + - Self-host the runner - Write a few plugins/utilities for `describe`/`it` (likely trivial), etc diff --git a/test-util/globals.js b/test-util/globals.js index b735e6c..32ddd64 100644 --- a/test-util/globals.js +++ b/test-util/globals.js @@ -185,4 +185,6 @@ Util.basic = function (desc, callback) { }) } -if (settings.migrate) Thallium.migrate() +if (settings.migrate) { + require("../migrate") // eslint-disable-line global-require +} diff --git a/test/cli/e2e.js b/test/cli/e2e.js index ff6697e..edf7f5b 100644 --- a/test/cli/e2e.js +++ b/test/cli/e2e.js @@ -157,12 +157,9 @@ describe("cli end-to-end (FLAKE)", /** @this */ function () { "pass [0: core (basic)] > [0: reflect] > [4: get children] > [3: returns a copy] = undefined", "leave [0: core (basic)] > [0: reflect] > [4: get children] = undefined", "leave [0: core (basic)] > [0: reflect] = undefined", - "enter [0: core (basic)] > [1: test()] = undefined", - "pass [0: core (basic)] > [1: test()] > [0: returns a prototypal clone inside] = undefined", - "leave [0: core (basic)] > [1: test()] = undefined", - "enter [0: core (basic)] > [2: run()] = undefined", - "pass [0: core (basic)] > [2: run()] > [0: runs child tests] = undefined", - "leave [0: core (basic)] > [2: run()] = undefined", + "enter [0: core (basic)] > [1: run()] = undefined", + "pass [0: core (basic)] > [1: run()] > [0: runs child tests] = undefined", + "leave [0: core (basic)] > [1: run()] = undefined", "leave [0: core (basic)] = undefined", "enter [1: cli common] = undefined", "enter [1: cli common] > [0: isObjectLike()] = undefined", diff --git a/test/core/basic.js b/test/core/basic.js index 5066291..70397f1 100644 --- a/test/core/basic.js +++ b/test/core/basic.js @@ -179,23 +179,6 @@ describe("core (basic)", function () { }) }) - /** - * TODO: This is deprecated - */ - describe("test()", function () { - it("returns a prototypal clone inside", function () { - var tt = Util.create() - var test - - tt.test("test", function (tt) { test = tt }) - - return tt.run().then(function () { - assert.notEqual(test, tt) - assert.equal(Object.getPrototypeOf(test), tt) - }) - }) - }) - describe("run()", function () { it("runs child tests", function () { var tt = Util.create() diff --git a/test/core/slow.js b/test/core/slow.js index fe50377..3326300 100644 --- a/test/core/slow.js +++ b/test/core/slow.js @@ -155,60 +155,50 @@ describe("core (slow) (FLAKE)", /** @this */ function () { }) }) - function ownSlow(reflect) { - return reflect.ownSlow - } - function slow(reflect) { return reflect.slow } it("gets own slow", function () { var tt = Util.create() - var active, raw + var active tt.test("test", function () { tt.slow = 50 active = tt.call(slow) - raw = tt.call(ownSlow) }) return tt.run().then(function () { assert.equal(active, 50) - assert.equal(raw, 50) }) }) it("gets inherited slow", function () { var tt = Util.create() - var active, raw + var active tt.test("test", function () { tt.slow = 50 tt.test("inner", function () { active = tt.call(slow) - raw = tt.call(ownSlow) }) }) return tt.run().then(function () { assert.equal(active, 50) - assert.equal(raw, 0) }) }) it("gets default slow", function () { var tt = Util.create() - var active, raw + var active tt.test("test", function () { active = tt.call(slow) - raw = tt.call(ownSlow) }) return tt.run().then(function () { assert.equal(active, 75) - assert.equal(raw, 0) }) }) }) diff --git a/test/core/timeouts.js b/test/core/timeouts.js index f9e8c49..e8776bb 100644 --- a/test/core/timeouts.js +++ b/test/core/timeouts.js @@ -113,60 +113,50 @@ describe("core (timeouts) (FLAKE)", /** @this */ function () { }) }) - function ownTimeout(reflect) { - return reflect.ownTimeout - } - function timeout(reflect) { return reflect.timeout } it("gets own timeout", function () { var tt = Util.create() - var active, raw + var active tt.test("test", function () { tt.timeout = 50 active = tt.call(timeout) - raw = tt.call(ownTimeout) }) return tt.run().then(function () { assert.equal(active, 50) - assert.equal(raw, 50) }) }) it("gets inherited timeout", function () { var tt = Util.create() - var active, raw + var active tt.test("test", function () { tt.timeout = 50 tt.test("inner", function () { active = tt.call(timeout) - raw = tt.call(ownTimeout) }) }) return tt.run().then(function () { assert.equal(active, 50) - assert.equal(raw, 0) }) }) it("gets default timeout", function () { var tt = Util.create() - var active, raw + var active tt.test("test", function () { active = tt.call(timeout) - raw = tt.call(ownTimeout) }) return tt.run().then(function () { assert.equal(active, 2000) - assert.equal(raw, 0) }) }) }) diff --git a/thallium-migrate.js b/thallium-migrate.js index 5f0bf8f..6c2ef05 100644 --- a/thallium-migrate.js +++ b/thallium-migrate.js @@ -3,8119 +3,7198 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof requ module.exports = require("clean-assert") -},{"clean-assert":34}],2:[function(require,module,exports){ +},{"clean-assert":33}],2:[function(require,module,exports){ +"use strict" + +module.exports = require("./lib/dom") + +},{"./lib/dom":12}],3:[function(require,module,exports){ "use strict" /** - * Core TDD-style assertions. These are done by a composition of DSLs, since - * there is *so* much repetition. + * Main entry point, for those wanting to use this framework with the core + * assertions. */ +var Thallium = require("./lib/api/thallium") -var match = require("clean-match") -var deprecate = require("./migrate/common").deprecate +module.exports = new Thallium() -var toString = Object.prototype.toString -var hasOwn = Object.prototype.hasOwnProperty +},{"./lib/api/thallium":7}],4:[function(require,module,exports){ +"use strict" -/* eslint-disable no-self-compare */ -// For better NaN handling -function strictIs(a, b) { - return a === b || a !== a && b !== b -} +var Thallium = require("./lib/api/thallium") +var Reports = require("./lib/core/reports") +var HookStage = Reports.HookStage -function looseIs(a, b) { - return a == b || a !== a && b !== b // eslint-disable-line eqeqeq +exports.root = function () { + return new Thallium() } -/* eslint-enable no-self-compare */ - -var check = (function () { - function prefix(type) { - return (/^[aeiou]/.test(type) ? "an " : "a ") + type - } +function d(duration) { + if (duration == null) return 10 + if (typeof duration === "number") return duration|0 + throw new TypeError("Expected `duration` to be a number if it exists") +} - function check(value, type) { - if (type === "array") return Array.isArray(value) - if (type === "regexp") return toString.call(value) === "[object RegExp]" - if (type === "object") return value != null && typeof value === "object" - if (type === "null") return value === null - if (type === "none") return value == null - return typeof value === type - } +function s(slow) { + if (slow == null) return 75 + if (typeof slow === "number") return slow|0 + throw new TypeError("Expected `slow` to be a number if it exists") +} - function checkList(value, types) { - for (var i = 0; i < types.length; i++) { - if (check(value, types[i])) return true - } +function p(path) { + if (Array.isArray(path)) return path + throw new TypeError("Expected `path` to be an array of locations") +} - return false - } +function h(value) { + if (value != null && typeof value._ === "number") return value + throw new TypeError("Expected `value` to be a hook error") +} - function checkSingle(value, name, type) { - if (!check(value, type)) { - throw new TypeError("`" + name + "` must be " + prefix(type)) - } - } +/** + * Create a new report, mainly for testing reporters. + */ +exports.reports = { + start: function () { + return new Reports.Start() + }, - function checkMany(value, name, types) { - if (!checkList(value, types)) { - var str = "`" + name + "` must be either" + enter: function (path, duration, slow) { + return new Reports.Enter(p(path), d(duration), s(slow)) + }, - if (types.length === 2) { - str += prefix(types[0]) + " or " + prefix(types[1]) - } else { - str += prefix(types[0]) + leave: function (path) { + return new Reports.Leave(p(path)) + }, - var end = types.length - 1 + pass: function (path, duration, slow) { + return new Reports.Pass(p(path), d(duration), s(slow)) + }, - for (var i = 1; i < end; i++) { - str += ", " + prefix(types[i]) - } + fail: function (path, value, duration, slow, isFailable) { // eslint-disable-line max-params, max-len + return new Reports.Fail( + p(path), value, d(duration), s(slow), + !!isFailable) + }, - str += ", or " + prefix(types[end]) - } + skip: function (path) { + return new Reports.Skip(p(path)) + }, - throw new TypeError(str) - } - } + end: function () { + return new Reports.End() + }, - return function (value, name, type) { - if (!Array.isArray(type)) return checkSingle(value, name, type) - if (type.length === 1) return checkSingle(value, name, type[0]) - return checkMany(value, name, type) - } -})() + error: function (value) { + return new Reports.Error(value) + }, -function checkTypeOf(value, name) { - if (value === "boolean" || value === "function") return - if (value === "number" || value === "object" || value === "string") return - if (value === "symbol" || value === "undefined") return - throw new TypeError("`" + name + "` must be a valid `typeof` value") + hook: function (path, rootPath, value) { + return new Reports.Hook(p(path), p(rootPath), h(value)) + }, } -// This holds everything to be added. -var methods = [] -var aliases = [] +/** + * Create a new hook error, mainly for testing reporters. + */ +exports.hookErrors = { + beforeAll: function (func, value) { + return new Reports.HookError(HookStage.BeforeAll, func, value) + }, + + beforeEach: function (func, value) { + return new Reports.HookError(HookStage.BeforeEach, func, value) + }, -function getAssertionDeprecation(name) { - var replacement = name + afterEach: function (func, value) { + return new Reports.HookError(HookStage.AfterEach, func, value) + }, - switch (name) { - case "boolean": replacement = "isBoolean"; break - case "function": replacement = "isFunction"; break - case "number": replacement = "isNumber"; break - case "object": replacement = "isObject"; break - case "string": replacement = "isString"; break - case "symbol": replacement = "isSymbol"; break - case "instanceof": replacement = "is"; break - case "notInstanceof": replacement = "not"; break - case "hasLength": replacement = "equal"; break - case "notLength": replacement = "notEqual"; break - case "lengthAtLeast": replacement = "atLeast"; break - case "lengthAtMost": replacement = "atMost"; break - case "lengthAbove": replacement = "above"; break - case "lengthBelow": replacement = "below"; break - case "notIncludesAll": replacement = "notIncludesAll"; break - case "notIncludesLooseAll": replacement = "notIncludesAll"; break - case "notIncludesDeepAll": replacement = "notIncludesAllDeep"; break - case "notIncludesMatchAll": replacement = "notIncludesAllMatch"; break - case "includesAny": replacement = "includesAny"; break - case "includesLooseAny": replacement = "includesAny"; break - case "includesDeepAny": replacement = "includesAnyDeep"; break - case "includesMatchAny": replacement = "includesAnyMatch"; break - case "undefined": - return "`t.undefined()` is deprecated. Use " + - "`assert.equal(undefined, value)`. from `thallium/assert` instead." - case "type": - return "`t.type()` is deprecated. Use `assert.isBoolean()`/etc. from " + - "`thallium/assert` instead." - default: // ignore - } - - return "`t." + name + "()` is deprecated. Use `assert." + replacement + - "()` from `thallium/assert` instead." + afterAll: function (func, value) { + return new Reports.HookError(HookStage.AfterAll, func, value) + }, } /** - * The core assertions export, as a plugin. + * Creates a new location, mainly for testing reporters. */ -module.exports = function (t) { - methods.forEach(function (m) { - t.define(m.name, deprecate(getAssertionDeprecation(m.name), m.callback)) - }) - aliases.forEach(function (alias) { t[alias.name] = t[alias.original] }) +exports.location = function (name, index) { + if (typeof name !== "string") { + throw new TypeError("Expected `name` to be a string") + } + + if (typeof index !== "number") { + throw new TypeError("Expected `index` to be a number") + } + + return {name: name, index: index|0} } -// Little helpers so that these functions only need to be created once. -function define(name, callback) { - check(name, "name", "string") - check(callback, "callback", "function") - methods.push({name: name, callback: callback}) +},{"./lib/api/thallium":7,"./lib/core/reports":10}],5:[function(require,module,exports){ +"use strict" + +exports.addHook = function (list, callback) { + if (list != null) { + list.push(callback) + return list + } else { + return [callback] + } } -// Much easier to type -function negate(name) { - check(name, "name", "string") - return "not" + name[0].toUpperCase() + name.slice(1) +exports.removeHook = function (list, callback) { + if (list == null) return undefined + if (list.length === 1) { + if (list[0] === callback) return undefined + } else { + var index = list.indexOf(callback) + + if (index >= 0) list.splice(index, 1) + } + return list } -// The basic assert. It's almost there for looks, given how easy it is to -// define your own assertions. -function sanitize(message) { - return message ? String(message).replace(/(\{\w+\})/g, "\\$1") : "" +exports.hasHook = function (list, callback) { + if (list == null) return false + if (list.length > 1) return list.indexOf(callback) >= 0 + return list[0] === callback } -define("assert", function (test, message) { - return {test: test, message: sanitize(message)} -}) +},{}],6:[function(require,module,exports){ +"use strict" -define("fail", function (message) { - return {test: false, message: sanitize(message)} -}) +var methods = require("../methods") +var Tests = require("../core/tests") +var Common = require("./common") /** - * These makes many of the common operators much easier to do. + * This contains the low level, more arcane things that are generally not + * interesting to anyone other than plugin developers. */ -function unary(name, func, messages) { - define(name, function (value) { - return { - test: func(value), - actual: value, - message: messages[0], - } - }) +module.exports = Reflect +function Reflect(test) { + var reflect = test.reflect - define(negate(name), function (value) { - return { - test: !func(value), - actual: value, - message: messages[1], - } - }) + if (reflect != null) return reflect + test.reflect = this + this._ = test } -function binary(name, func, messages) { - define(name, function (actual, expected) { - return { - test: func(actual, expected), - actual: actual, - expected: expected, - message: messages[0], - } - }) - - define(negate(name), function (actual, expected) { - return { - test: !func(actual, expected), - actual: actual, - expected: expected, - message: messages[1], +methods(Reflect, { + /** + * Whether a reporter was registered. + */ + hasReporter: function (reporter) { + if (typeof reporter !== "function") { + throw new TypeError("Expected `reporter` to be a function") } - }) -} - -unary("ok", function (x) { return !!x }, [ - "Expected {actual} to be ok", - "Expected {actual} to not be ok", -]) -"boolean function number object string symbol".split(" ") -.forEach(function (type) { - var name = (type[0] === "o" ? "an " : "a ") + type + return this._.root.reporterIds.indexOf(reporter) >= 0 + }, - unary(type, function (x) { return typeof x === type }, [ - "Expected {actual} to be " + name, - "Expected {actual} to not be " + name, - ]) -}) + /** + * Add a reporter. + */ + reporter: function (reporter, arg) { + if (typeof reporter !== "function") { + throw new TypeError("Expected `reporter` to be a function") + } -;[true, false, null, undefined].forEach(function (value) { - unary(value + "", function (x) { return x === value }, [ - "Expected {actual} to be " + value, - "Expected {actual} to not be " + value, - ]) -}) + var root = this._.root -unary("exists", function (x) { return x != null }, [ - "Expected {actual} to exist", - "Expected {actual} to not exist", -]) + if (root.current !== root) { + throw new Error("Reporters may only be added to the root") + } -unary("array", Array.isArray, [ - "Expected {actual} to be an array", - "Expected {actual} to not be an array", -]) + if (root.reporterIds.indexOf(reporter) < 0) { + root.reporterIds.push(reporter) + root.reporters.push(reporter(arg)) + } + }, -define("type", function (object, type) { - checkTypeOf(type, "type") + /** + * Remove a reporter. + */ + removeReporter: function (reporter) { + if (typeof reporter !== "function") { + throw new TypeError("Expected `reporter` to be a function") + } - return { - test: typeof object === type, - expected: type, - actual: typeof object, - o: object, - message: "Expected typeof {o} to be {expected}, but found {actual}", - } -}) + var root = this._.root -define("notType", function (object, type) { - checkTypeOf(type, "type") + if (root.current !== root) { + throw new Error("Reporters may only be added to the root") + } - return { - test: typeof object !== type, - expected: type, - o: object, - message: "Expected typeof {o} to not be {expected}", - } -}) + var index = root.reporterIds.indexOf(reporter) -define("instanceof", function (object, Type) { - check(Type, "Type", "function") + if (index >= 0) { + root.reporterIds.splice(index, 1) + root.reporters.splice(index, 1) + } + }, - return { - test: object instanceof Type, - expected: Type, - actual: object.constructor, - o: object, - message: "Expected {o} to be an instance of {expected}, but found {actual}", // eslint-disable-line max-len - } -}) + /** + * Get the currently executing test. + */ + get current() { + return new Reflect(this._.root.current) + }, -define("notInstanceof", function (object, Type) { - check(Type, "Type", "function") + /** + * Get the root test. + */ + get root() { + return new Reflect(this._.root) + }, - return { - test: !(object instanceof Type), - expected: Type, - o: object, - message: "Expected {o} to not be an instance of {expected}", - } -}) + /** + * Get the current total test count. + */ + get count() { + return this._.tests == null ? 0 : this._.tests.length + }, -binary("equal", strictIs, [ - "Expected {actual} to equal {expected}", - "Expected {actual} to not equal {expected}", -]) + /** + * Get a copy of the current test list, as a Reflect collection. This is + * intentionally a slice, so you can't mutate the real children. + */ + get children() { + var children = [] -binary("equalLoose", looseIs, [ - "Expected {actual} to loosely equal {expected}", - "Expected {actual} to not loosely equal {expected}", -]) + if (this._.tests != null) { + for (var i = 0; i < this._.tests.length; i++) { + children[i] = new Reflect(this._.tests[i]) + } + } -function comp(name, compare, message) { - define(name, function (actual, expected) { - check(actual, "actual", "number") - check(expected, "expected", "number") + return children + }, - return { - test: compare(actual, expected), - actual: actual, - expected: expected, - message: message, - } - }) -} - -/* eslint-disable max-len */ + /** + * Is this test the root, i.e. top level? + */ + get isRoot() { + return this._.parent == null + }, -comp("atLeast", function (a, b) { return a >= b }, "Expected {actual} to be at least {expected}") -comp("atMost", function (a, b) { return a <= b }, "Expected {actual} to be at most {expected}") -comp("above", function (a, b) { return a > b }, "Expected {actual} to be above {expected}") -comp("below", function (a, b) { return a < b }, "Expected {actual} to be below {expected}") + /** + * Is this locked (i.e. unsafe to modify)? + */ + get isLocked() { + return !!this._.locked + }, -define("between", function (actual, lower, upper) { - check(actual, "actual", "number") - check(lower, "lower", "number") - check(upper, "upper", "number") + /** + * Get the active timeout in milliseconds, not necessarily own, or the + * framework default of 2000, if none was set. + */ + get timeout() { + return this._.timeout || Tests.defaultTimeout + }, - return { - test: actual >= lower && actual <= upper, - actual: actual, - lower: lower, - upper: upper, - message: "Expected {actual} to be between {lower} and {upper}", - } -}) + /** + * Get the active slow threshold in milliseconds, not necessarily own, or + * the framework default of 75, if none was set. + */ + get slow() { + return this._.slow || Tests.defaultSlow + }, -/* eslint-enable max-len */ + /** + * Get the test's own max attempt count. Note that this is parasitically + * inherited from its parent, not delegated. + */ + get attempts() { + return this._.attempts + }, -binary("deepEqual", match.strict, [ - "Expected {actual} to deeply equal {expected}", - "Expected {actual} to not deeply equal {expected}", -]) + /** + * Get whether this test is failable. Note that this is parasitically + * inherited from its parent, not delegated. + */ + get isFailable() { + return this._.isFailable + }, -binary("match", match.loose, [ - "Expected {actual} to match {expected}", - "Expected {actual} to not match {expected}", -]) + /** + * Get the test name, or `undefined` if it's the root test. + */ + get name() { + if (this._.parent == null) return undefined + return this._.name + }, -function has(name, _) { // eslint-disable-line max-len, max-params - if (_.equals === looseIs) { - define(name, function (object, key, value) { - return { - test: _.has(object, key) && _.is(_.get(object, key), value), - expected: value, - actual: object[key], - key: key, - object: object, - message: _.messages[0], - } - }) + /** + * Get the test index, or `undefined` if it's the root test. + */ + get index() { + if (this._.parent == null) return undefined + return this._.index + }, - define(negate(name), function (object, key, value) { - return { - test: !_.has(object, key) || !_.is(_.get(object, key), value), - actual: value, - key: key, - object: object, - message: _.messages[2], - } - }) - } else { - define(name, function (object, key, value) { - var test = _.has(object, key) + /** + * Get the test's parent as a Reflect, or `undefined` if it's the root test. + */ + get parent() { + if (this._.parent == null) return undefined + return new Reflect(this._.parent) + }, - if (arguments.length >= 3) { - return { - test: test && _.is(_.get(object, key), value), - expected: value, - actual: object[key], - key: key, - object: object, - message: _.messages[0], - } - } else { - return { - test: test, - expected: key, - actual: object, - message: _.messages[1], - } - } - }) + /** + * Add a hook to be run before each subtest, including their subtests and so + * on. + */ + before: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } - define(negate(name), function (object, key, value) { - var test = !_.has(object, key) + this._.beforeEach = Common.addHook(this._.beforeEach, callback) + }, - if (arguments.length >= 3) { - return { - test: test || !_.is(_.get(object, key), value), - actual: value, - key: key, - object: object, - message: _.messages[2], - } - } else { - return { - test: test, - expected: key, - actual: object, - message: _.messages[3], - } - } - }) - } -} + /** + * Add a hook to be run once before all subtests are run. + */ + beforeAll: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } -function hasOwnKey(object, key) { return hasOwn.call(object, key) } -function hasInKey(object, key) { return key in object } -function hasInColl(object, key) { return object.has(key) } -function hasObjectGet(object, key) { return object[key] } -function hasCollGet(object, key) { return object.get(key) } + this._.beforeAll = Common.addHook(this._.beforeAll, callback) + }, -has("hasOwn", { - is: strictIs, - has: hasOwnKey, - get: hasObjectGet, - messages: [ - "Expected {object} to have own key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have own key {expected}", - "Expected {object} to not have own key {key} equal to {actual}", - "Expected {actual} to not have own key {expected}", - ], -}) + /** + * Add a hook to be run after each subtest, including their subtests and so + * on. + */ + after: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } -has("hasOwnLoose", { - is: looseIs, - has: hasOwnKey, - get: hasObjectGet, - messages: [ - "Expected {object} to have own key {key} loosely equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have own key {expected}", - "Expected {object} to not have own key {key} loosely equal to {actual}", - "Expected {actual} to not have own key {expected}", - ], -}) + this._.afterEach = Common.addHook(this._.afterEach, callback) + }, -has("hasKey", { - is: strictIs, - has: hasInKey, - get: hasObjectGet, - messages: [ - "Expected {object} to have key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have key {expected}", - "Expected {object} to not have key {key} equal to {actual}", - "Expected {actual} to not have key {expected}", - ], -}) + /** + * Add a hook to be run once after all subtests are run. + */ + afterAll: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } -has("hasKeyLoose", { - is: looseIs, - has: hasInKey, - get: hasObjectGet, - messages: [ - "Expected {object} to have key {key} loosely equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have key {expected}", - "Expected {object} to not have key {key} loosely equal to {actual}", - "Expected {actual} to not have key {expected}", - ], -}) + this._.afterAll = Common.addHook(this._.afterAll, callback) + }, -has("has", { - is: strictIs, - has: hasInColl, - get: hasCollGet, - messages: [ - "Expected {object} to have key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have key {expected}", - "Expected {object} to not have key {key} equal to {actual}", - "Expected {actual} to not have key {expected}", - ], -}) + /** + * Remove a hook previously added with `t.before` or `reflect.before`. + */ + hasBefore: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } -has("hasLoose", { - is: looseIs, - has: hasInColl, - get: hasCollGet, - messages: [ - "Expected {object} to have key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have key {expected}", - "Expected {object} to not have key {key} equal to {actual}", - "Expected {actual} to not have key {expected}", - ], -}) + return Common.hasHook(this._.beforeEach, callback) + }, -function getName(func) { - if (func.name != null) return func.name || "" - if (func.displayName != null) return func.displayName || "" - return "" -} + /** + * Remove a hook previously added with `t.beforeAll` or `reflect.beforeAll`. + */ + hasBeforeAll: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } -function throws(name, _) { - function run(invert) { - return function (func, matcher) { - check(func, "func", "function") - _.check(matcher) + return Common.hasHook(this._.beforeAll, callback) + }, - var test, error + /** + * Remove a hook previously added with `t.after` or`reflect.after`. + */ + hasAfter: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } - try { - func() - } catch (e) { - test = _.test(matcher, error = e) - - // Rethrow unknown errors that don't match when a matcher was - // passed - it's easier to debug unexpected errors when you have - // a stack trace. Don't rethrow non-errors, though. - if (_.rethrow(matcher, invert, test, e)) { - throw e - } - } + return Common.hasHook(this._.afterEach, callback) + }, - return { - test: !!test ^ invert, - expected: matcher, - error: error, - message: _.message(matcher, invert, test), - } + /** + * Remove a hook previously added with `t.afterAll` or `reflect.afterAll`. + */ + hasAfterAll: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") } - } - define(name, run(false)) - define(negate(name), run(true)) -} + return Common.hasHook(this._.afterAll, callback) + }, -throws("throws", { - test: function (Type, e) { return Type == null || e instanceof Type }, - check: function (Type) { check(Type, "Type", ["none", "function"]) }, + /** + * Remove a hook previously added with `t.before` or `reflect.before`. + */ + removeBefore: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } - rethrow: function (matcher, invert, test, e) { - return matcher != null && !invert && !test && e instanceof Error + this._.beforeEach = Common.removeHook(this._.beforeEach, callback) }, - message: function (Type, invert, test) { - var str = "Expected callback to " + /** + * Remove a hook previously added with `t.beforeAll` or `reflect.beforeAll`. + */ + removeBeforeAll: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } - if (invert) str += "not " - str += "throw" + this._.beforeAll = Common.removeHook(this._.beforeAll, callback) + }, - if (Type != null) { - str += " an instance of " + getName(Type) - if (!invert && test === false) str += ", but found {error}" + /** + * Remove a hook previously added with `t.after` or`reflect.after`. + */ + removeAfter: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") } - return str + this._.afterEach = Common.removeHook(this._.afterEach, callback) }, -}) -throws("throwsMatch", { - test: function (matcher, e) { - if (typeof matcher === "string") return e.message === matcher - if (typeof matcher === "function") return !!matcher(e) - return matcher.test(e.message) - }, + /** + * Remove a hook previously added with `t.afterAll` or `reflect.afterAll`. + */ + removeAfterAll: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } - check: function (matcher) { - // Not accepting objects yet. - check(matcher, "matcher", ["string", "regexp", "function"]) + this._.afterAll = Common.removeHook(this._.afterAll, callback) }, - rethrow: function () { return false }, - - message: function (_, invert, test) { - if (invert) { - return "Expected callback to not throw an error that matches {expected}" // eslint-disable-line max-len - } else if (test === undefined) { - return "Expected callback to throw an error that matches {expected}, but found no error" // eslint-disable-line max-len - } else { - return "Expected callback to throw an error that matches {expected}, but found {error}" // eslint-disable-line max-len + /** + * Add a block or inline test. + */ + test: function (name, callback) { + if (typeof name !== "string") { + throw new TypeError("Expected `name` to be a string") } - }, -}) -function len(name, compare, message) { - define(name, function (object, length) { - check(object, "object", "object") - check(length, "length", "number") + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } - var len = object.length + Tests.addNormal(this._.root.current, name, callback) + }, - return { - test: len != null && compare(len, +length), - expected: length, - actual: len, - object: object, - message: message, + /** + * Add a skipped block or inline test. + */ + testSkip: function (name, callback) { + if (typeof name !== "string") { + throw new TypeError("Expected `name` to be a string") } - }) -} - -/* eslint-disable max-len */ -// Note: these always fail with NaNs. -len("length", function (a, b) { return a === b }, "Expected {object} to have length {expected}, but found {actual}") -len("notLength", function (a, b) { return a !== b }, "Expected {object} to not have length {actual}") -len("lengthAtLeast", function (a, b) { return a >= b }, "Expected {object} to have length at least {expected}, but found {actual}") -len("lengthAtMost", function (a, b) { return a <= b }, "Expected {object} to have length at most {expected}, but found {actual}") -len("lengthAbove", function (a, b) { return a > b }, "Expected {object} to have length above {expected}, but found {actual}") -len("lengthBelow", function (a, b) { return a < b }, "Expected {object} to have length below {expected}, but found {actual}") + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } -/* eslint-enable max-len */ - -// Note: these two always fail when dealing with NaNs. -define("closeTo", function (actual, expected, delta) { - check(actual, "actual", "number") - check(expected, "expected", "number") - check(delta, "delta", "number") - - return { - test: Math.abs(actual - expected) <= Math.abs(delta), - actual: actual, - expected: expected, - delta: delta, - message: "Expected {actual} to be within {delta} of {expected}", - } + Tests.addSkipped(this._.root.current, name) + }, }) -define("notCloseTo", function (actual, expected, delta) { - check(actual, "actual", "number") - check(expected, "expected", "number") - check(delta, "delta", "number") +},{"../core/tests":11,"../methods":18,"./common":5}],7:[function(require,module,exports){ +"use strict" - return { - test: Math.abs(actual - expected) > Math.abs(delta), - actual: actual, - expected: expected, - delta: delta, - message: "Expected {actual} to not be within {delta} of {expected}", - } -}) +var methods = require("../methods") +var Tests = require("../core/tests") +var Filter = require("../core/filter") +var Common = require("./common") +var Reflect = require("./reflect") -/* eslint-disable max-len */ +module.exports = Thallium +function Thallium() { + this._ = Tests.createRoot() +} -/** - * There's 4 sets of 4 permutations here for `includes` and `hasKeys`, instead - * of N sets of 2 (which would fit the `foo`/`notFoo` idiom better), so it's - * easier to just make a couple separate DSLs and use that to define everything. - * - * Here's the top level: - * - * - strict shallow - * - loose shallow - * - strict deep - * - structural deep - * - * And the second level: - * - * - includes all/not missing some - * - includes some/not missing all - * - not including all/missing some - * - not including some/missing all - * - * Here's an example using the naming scheme for `hasKeys`, etc. - * - * | strict shallow | loose shallow | strict deep | structural deep - * --------------|-----------------|----------------------|---------------------|------------------------- - * includes all | `hasKeys` | `hasLooseKeys` | `hasDeepKeys` | `hasMatchKeys` - * includes some | `hasAnyKeys` | `hasLooseAnyKeys` | `hasDeepAnyKeys` | `hasMatchAnyKeys` - * missing some | `notHasAllKeys` | `notHasLooseAllKeys` | `notHasDeepAllKeys` | `notHasMatchAllKeys` - * missing all | `notHasKeys` | `notHasLooseKeys` | `notHasDeepKeys` | `notHasMatchKeys` - * - * Note that the `hasKeys` shallow comparison variants are also overloaded to - * consume either an array (in which it simply checks against a list of keys) or - * an object (where it does a full deep comparison). - */ +methods(Thallium, { + /** + * Call a plugin and return the result. The plugin is called with a Reflect + * instance for access to plenty of potentially useful internal details. + */ + call: function (plugin, arg) { + var reflect = new Reflect(this._.root.current) -/* eslint-enable max-len */ + return plugin.call(reflect, reflect, arg) + }, -function makeIncludes(all, func) { - return function (array, keys) { - function test(key) { - for (var i = 0; i < array.length; i++) { - if (func(key, array[i])) return true - } - return false + /** + * Whitelist specific tests, using array-based selectors where each entry + * is either a string or regular expression. + */ + only: function (/* ...selectors */) { + this._.root.current.only = Filter.create.apply(undefined, arguments) + }, + + /** + * Add a reporter. + */ + reporter: function (reporter, arg) { + if (typeof reporter !== "function") { + throw new TypeError("Expected `reporter` to be a function.") } - if (all) { - if (array.length < keys.length) return false + var root = this._.root - for (var i = 0; i < keys.length; i++) { - if (!test(keys[i])) return false - } - return true - } else { - for (var j = 0; j < keys.length; j++) { - if (test(keys[j])) return true - } - return false + if (root.current !== root) { + throw new Error("Reporters may only be added to the root.") } - } -} - -function defineIncludes(name, func, invert, message) { - function base(array, values) { - // Cheap cases first - if (!Array.isArray(array)) return false - if (array === values) return true - return func(array, values) - } - define(name, function (array, values) { - check(array, "array", "array") - if (!Array.isArray(values)) values = [values] + var result = reporter(arg) - // exclusive or to invert the result if `invert` is true - return { - test: !values.length || invert ^ base(array, values), - actual: array, - values: values, - message: message, + // Don't assume it's a function. Verify it actually is, so we don't have + // inexplicable type errors internally after it's invoked, and so users + // won't get too confused. + if (typeof result !== "function") { + throw new TypeError( + "Expected `reporter` to return a function. Check with the " + + "reporter's author, and have them fix their reporter.") } - }) -} -var includesAll = makeIncludes(true, strictIs) -var includesAny = makeIncludes(false, strictIs) - -/* eslint-disable max-len */ + root.reporter = result + }, -defineIncludes("includes", includesAll, false, "Expected {actual} to have all values in {values}") -defineIncludes("notIncludesAll", includesAll, true, "Expected {actual} to not have all values in {values}") -defineIncludes("includesAny", includesAny, false, "Expected {actual} to have any value in {values}") -defineIncludes("notIncludes", includesAny, true, "Expected {actual} to not have any value in {values}") + /** + * Check if this has a reporter. + */ + get hasReporter() { + return this._.root.reporter != null + }, -var includesLooseAll = makeIncludes(true, looseIs) -var includesLooseAny = makeIncludes(false, looseIs) + /** + * Get the current timeout. 0 means inherit the parent's, and `Infinity` + * means it's disabled. + */ + get timeout() { + return this._.root.current.timeout || Tests.defaultTimeout + }, -defineIncludes("includesLoose", includesLooseAll, false, "Expected {actual} to loosely have all values in {values}") -defineIncludes("notIncludesLooseAll", includesLooseAll, true, "Expected {actual} to not loosely have all values in {values}") -defineIncludes("includesLooseAny", includesLooseAny, false, "Expected {actual} to loosely have any value in {values}") -defineIncludes("notIncludesLoose", includesLooseAny, true, "Expected {actual} to not loosely have any value in {values}") + /** + * Set the timeout in milliseconds, rounding negatives to 0. Setting the + * timeout to 0 means to inherit the parent timeout, and setting it to + * `Infinity` disables it. + */ + set timeout(timeout) { + this._.root.current.timeout = Math.floor(Math.max(+timeout, 0)) + }, -var includesDeepAll = makeIncludes(true, match.strict) -var includesDeepAny = makeIncludes(false, match.strict) + /** + * Get the current slow threshold. 0 means inherit the parent's, and + * `Infinity` means it's disabled. + */ + get slow() { + return this._.root.current.slow || Tests.defaultSlow + }, -defineIncludes("includesDeep", includesDeepAll, false, "Expected {actual} to match all values in {values}") -defineIncludes("notIncludesDeepAll", includesDeepAll, true, "Expected {actual} to not match all values in {values}") -defineIncludes("includesDeepAny", includesDeepAny, false, "Expected {actual} to match any value in {values}") -defineIncludes("notIncludesDeep", includesDeepAny, true, "Expected {actual} to not match any value in {values}") + /** + * Set the slow threshold in milliseconds, rounding negatives to 0. Setting + * the timeout to 0 means to inherit the parent threshold, and setting it to + * `Infinity` disables it. + */ + set slow(slow) { + this._.root.current.slow = Math.floor(Math.max(+slow, 0)) + }, -var includesMatchAll = makeIncludes(true, match.loose) -var includesMatchAny = makeIncludes(false, match.loose) + /** + * Get the current attempt count. `0` means inherit the parent's. + */ + get attempts() { + return this._.root.current.attempts + }, -defineIncludes("includesMatch", includesMatchAll, false, "Expected {actual} to match all values in {values}") -defineIncludes("notIncludesMatchAll", includesMatchAll, true, "Expected {actual} to not match all values in {values}") -defineIncludes("includesMatchAny", includesMatchAny, false, "Expected {actual} to match any value in {values}") -defineIncludes("notIncludesMatch", includesMatchAny, true, "Expected {actual} to not match any value in {values}") + /** + * Set the number of attempts allowed, rounding negatives to 0. Setting the + * count to `0` means to inherit the parent retry count. + */ + set attempts(attempts) { + // This is done differently to avoid a massive performance penalty. + var calculated = Math.floor(Math.max(attempts, 0)) + var test = this._.root.current -/* eslint-enable max-len */ + test.attempts = calculated || test.parent.attempts + }, -function isEmpty(object) { - if (Array.isArray(object)) return object.length === 0 - if (typeof object !== "object" || object === null) return true - return Object.keys(object).length === 0 -} + /** + * Get whether this test is failable. + */ + get isFailable() { + return this._.root.current.isFailable + }, -function makeHasOverload(name, methods, invert, message) { - function base(object, keys) { - // Cheap case first - if (object === keys) return true - if (Array.isArray(keys)) return methods.array(object, keys) - return methods.object(object, keys) - } + /** + * Get whether this test is failable. + */ + set isFailable(isFailable) { + this._.root.current.isFailable = !!isFailable + }, - define(name, function (object, keys) { - check(object, "object", "object") - return { - // exclusive or to invert the result if `invert` is true - test: isEmpty(keys) || invert ^ base(object, keys), - actual: object, - keys: keys, - message: message, + /** + * Run the tests (or the test's tests if it's not a base instance). + */ + run: function (opts) { + if (this._.root !== this._) { + throw new Error( + "Only the root test can be run - If you only want to run a " + + "subtest, use `t.only([\"selector1\", ...])` instead.") } - }) -} - -function makeHasKeys(name, func, invert, message) { - function base(object, keys) { - return object === keys || func(object, keys) - } - define(name, function (object, keys) { - check(object, "object", "object") - return { - // exclusive or to invert the result if `invert` is true - test: isEmpty(keys) || invert ^ base(object, keys), - actual: object, - keys: keys, - message: message, + if (this._.locked) { + throw new Error("Can't run while tests are already running.") } - }) -} -function hasKeysType(all, func) { - return function (object, keys) { - if (typeof keys !== "object") return true - if (keys === null) return true + return Tests.runTest(this._, opts) + }, - function check(key) { - return hasOwn.call(object, key) && func(keys[key], object[key]) + /** + * Add a test. + */ + test: function (name, callback) { + if (typeof name !== "string") { + throw new TypeError("Expected `name` to be a string") } - if (all) { - for (var key1 in keys) { - if (hasOwn.call(keys, key1) && !check(key1)) { - return false - } - } - return true - } else { - for (var key2 in keys) { - if (hasOwn.call(keys, key2) && check(key2)) { - return true - } - } - return false + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") } - } -} -function hasOverloadType(all, func) { - return { - object: hasKeysType(all, func), - array: function (object, keys) { - if (all) { - for (var i = 0; i < keys.length; i++) { - if (!hasOwn.call(object, keys[i])) return false - } - return true - } else { - for (var j = 0; j < keys.length; j++) { - if (hasOwn.call(object, keys[j])) return true - } - return false - } - }, - } -} + Tests.addNormal(this._.root.current, name, callback) + }, -/* eslint-disable max-len */ + /** + * Add a skipped test. + */ + testSkip: function (name, callback) { + if (typeof name !== "string") { + throw new TypeError("Expected `name` to be a string") + } -var hasAllKeys = hasOverloadType(true, strictIs) -var hasAnyKeys = hasOverloadType(false, strictIs) + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } -makeHasOverload("hasKeys", hasAllKeys, false, "Expected {actual} to have all keys in {keys}") -makeHasOverload("notHasAllKeys", hasAllKeys, true, "Expected {actual} to not have all keys in {keys}") -makeHasOverload("hasAnyKeys", hasAnyKeys, false, "Expected {actual} to have any key in {keys}") -makeHasOverload("notHasKeys", hasAnyKeys, true, "Expected {actual} to not have any key in {keys}") + Tests.addSkipped(this._.root.current, name) + }, -var hasLooseAllKeys = hasOverloadType(true, looseIs) -var hasLooseAnyKeys = hasOverloadType(false, looseIs) + /** + * Clear all existing tests. + */ + clearTests: function () { + if (this._.root !== this._) { + throw new Error("Tests may only be cleared at the root.") + } -makeHasOverload("hasLooseKeys", hasLooseAllKeys, false, "Expected {actual} to loosely have all keys in {keys}") -makeHasOverload("notHasLooseAllKeys", hasLooseAllKeys, true, "Expected {actual} to not loosely have all keys in {keys}") -makeHasOverload("hasLooseAnyKeys", hasLooseAnyKeys, false, "Expected {actual} to loosely have any key in {keys}") -makeHasOverload("notHasLooseKeys", hasLooseAnyKeys, true, "Expected {actual} to not loosely have any key in {keys}") + if (this._.locked) { + throw new Error("Can't clear tests while they are running.") + } -var hasDeepAllKeys = hasKeysType(true, match.strict) -var hasDeepAnyKeys = hasKeysType(false, match.strict) + Tests.clearTests(this._) + }, -makeHasKeys("hasDeepKeys", hasDeepAllKeys, false, "Expected {actual} to have all keys in {keys}") -makeHasKeys("notHasDeepAllKeys", hasDeepAllKeys, true, "Expected {actual} to not have all keys in {keys}") -makeHasKeys("hasDeepAnyKeys", hasDeepAnyKeys, false, "Expected {actual} to have any key in {keys}") -makeHasKeys("notHasDeepKeys", hasDeepAnyKeys, true, "Expected {actual} to not have any key in {keys}") + before: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } -var hasMatchAllKeys = hasKeysType(true, match.loose) -var hasMatchAnyKeys = hasKeysType(false, match.loose) + var test = this._.root.current -makeHasKeys("hasMatchKeys", hasMatchAllKeys, false, "Expected {actual} to match all keys in {keys}") -makeHasKeys("notHasMatchAllKeys", hasMatchAllKeys, true, "Expected {actual} to not match all keys in {keys}") -makeHasKeys("hasMatchAnyKeys", hasMatchAnyKeys, false, "Expected {actual} to match any key in {keys}") -makeHasKeys("notHasMatchKeys", hasMatchAnyKeys, true, "Expected {actual} to not match any key in {keys}") + test.beforeEach = Common.addHook(test.beforeEach, callback) + }, -},{"./migrate/common":28,"clean-match":41}],3:[function(require,module,exports){ -"use strict" + beforeAll: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } -module.exports = require("./lib/dom") + var test = this._.root.current -},{"./lib/dom":13}],4:[function(require,module,exports){ -"use strict" + test.beforeAll = Common.addHook(test.beforeAll, callback) + }, -/** - * Main entry point, for those wanting to use this framework with the core - * assertions. - */ -var Thallium = require("./lib/api/thallium") - -module.exports = new Thallium() - -},{"./lib/api/thallium":8}],5:[function(require,module,exports){ -"use strict" + after: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } -var Thallium = require("./lib/api/thallium") -var Reports = require("./lib/core/reports") -var Types = Reports.Types + var test = this._.root.current -exports.root = function () { - return new Thallium() -} + test.afterEach = Common.addHook(test.afterEach, callback) + }, -function d(duration) { - if (duration == null) return 10 - if (typeof duration === "number") return duration|0 - throw new TypeError("Expected `duration` to be a number if it exists") -} + afterAll: function (callback) { + if (typeof callback !== "function") { + throw new TypeError("Expected callback to be a function if passed") + } -function s(slow) { - if (slow == null) return 75 - if (typeof slow === "number") return slow|0 - throw new TypeError("Expected `slow` to be a number if it exists") -} + var test = this._.root.current -function p(path) { - if (Array.isArray(path)) return path - throw new TypeError("Expected `path` to be an array of locations") -} + test.afterAll = Common.addHook(test.afterAll, callback) + }, +}) -function h(value) { - if (value != null && typeof value._ === "number") return value - throw new TypeError("Expected `value` to be a hook error") -} +},{"../core/filter":9,"../core/tests":11,"../methods":18,"./common":5,"./reflect":6}],8:[function(require,module,exports){ +"use strict" /** - * Create a new report, mainly for testing reporters. + * This is the entry point for the Browserify bundle. Note that it *also* will + * run as part of the tests in Node (unbundled), and it theoretically could be + * run in Node or a runtime limited to only ES5 support (e.g. Rhino, Nashorn, or + * embedded V8), so do *not* assume browser globals are present. */ -exports.reports = { - start: function () { - return new Reports.Start() - }, - enter: function (path, duration, slow) { - return new Reports.Enter(p(path), d(duration), s(slow)) - }, +exports.t = require("../index") +exports.assert = require("../assert") +exports.r = require("../r") +var dom = require("../dom") - leave: function (path) { - return new Reports.Leave(p(path)) - }, +exports.dom = dom.create +// if (global.document != null && global.document.currentScript != null) { +// dom.autoload(global.document.currentScript) +// } - pass: function (path, duration, slow) { - return new Reports.Pass(p(path), d(duration), s(slow)) - }, +var Internal = require("../internal") - fail: function (path, value, duration, slow, isFailable) { // eslint-disable-line max-params, max-len - return new Reports.Fail( - p(path), value, d(duration), s(slow), - !!isFailable) +exports.root = Internal.root +exports.reports = Internal.reports +exports.hookErrors = Internal.hookErrors +exports.location = Internal.location + +// In case the user needs to adjust this (e.g. Nashorn + console output). +var Settings = require("./settings") + +exports.settings = { + windowWidth: { + get: Settings.windowWidth, + set: Settings.setWindowWidth, }, - skip: function (path) { - return new Reports.Skip(p(path)) + newline: { + get: Settings.newline, + set: Settings.setNewline, }, - end: function () { - return new Reports.End() + symbols: { + get: Settings.symbols, + set: Settings.setSymbols, }, - error: function (value) { - return new Reports.Error(value) + defaultOpts: { + get: Settings.defaultOpts, + set: Settings.setDefaultOpts, }, - hook: function (path, rootPath, value) { - return new Reports.Hook(p(path), p(rootPath), h(value)) + colorSupport: { + get: Settings.Colors.getSupport, + set: Settings.Colors.setSupport, }, } +},{"../assert":1,"../dom":2,"../index":3,"../internal":4,"../r":66,"./settings":25}],9:[function(require,module,exports){ +"use strict" + /** - * Create a new hook error, mainly for testing reporters. + * The filter is actually stored as a tree for faster lookup times when there + * are multiple selectors. Objects can't be used for the nodes, where keys + * represent values and values represent children, because regular expressions + * aren't possible to use. */ -exports.hookErrors = { - beforeAll: function (func, value) { - return new Reports.HookError(Types.BeforeAll, func, value) - }, - beforeEach: function (func, value) { - return new Reports.HookError(Types.BeforeEach, func, value) - }, +function isEquivalent(entry, item) { + if (typeof entry === "string" && typeof item === "string") { + return entry === item + } else if (entry instanceof RegExp && item instanceof RegExp) { + return entry.toString() === item.toString() + } else { + return false + } +} - afterEach: function (func, value) { - return new Reports.HookError(Types.AfterEach, func, value) - }, +function matches(entry, item) { + if (typeof entry === "string") { + return entry === item + } else { + return entry.test(item) + } +} - afterAll: function (func, value) { - return new Reports.HookError(Types.AfterAll, func, value) - }, +function Filter(value) { + this.value = value + this.children = undefined } -/** - * Creates a new location, mainly for testing reporters. - */ -exports.location = function (name, index) { - if (typeof name !== "string") { - throw new TypeError("Expected `name` to be a string") - } +function findEquivalent(node, entry) { + if (node.children == null) return undefined - if (typeof index !== "number") { - throw new TypeError("Expected `index` to be a number") + for (var i = 0; i < node.children.length; i++) { + var child = node.children[i] + + if (isEquivalent(child.value, entry)) return child } - return {name: name, index: index|0} + return undefined } -},{"./lib/api/thallium":8,"./lib/core/reports":11}],6:[function(require,module,exports){ -"use strict" +function findMatches(node, entry) { + if (node.children == null) return undefined -exports.addHook = function (list, callback) { - if (list != null) { - list.push(callback) - return list - } else { - return [callback] + for (var i = 0; i < node.children.length; i++) { + var child = node.children[i] + + if (matches(child.value, entry)) return child } + + return undefined } -exports.removeHook = function (list, callback) { - if (list == null) return undefined - if (list.length === 1) { - if (list[0] === callback) return undefined - } else { - var index = list.indexOf(callback) +/** + * Create a filter from a number of selectors + */ +exports.create = function (/* ...selectors */) { + var filter = new Filter() - if (index >= 0) list.splice(index, 1) + for (var i = 0; i < arguments.length; i++) { + var selector = arguments[i] + + if (!Array.isArray(selector)) { + throw new TypeError( + "Expected selector " + i + " to be an array") + } + + filterAddSingle(filter, selector, i) } - return list -} -exports.hasHook = function (list, callback) { - if (list == null) return false - if (list.length > 1) return list.indexOf(callback) >= 0 - return list[0] === callback + return filter } -// TODO: cache and remove these traversals for 0.4. -// Note that a timeout of 0 means to inherit the parent. -exports.getTimeout = function (test) { - while (!test.timeout && test.parent != null) { - test = test.parent - } +function filterAddSingle(node, selector, index) { + for (var i = 0; i < selector.length; i++) { + var entry = selector[i] + + // Strings and regular expressions are the only things allowed. + if (typeof entry !== "string" && !(entry instanceof RegExp)) { + throw new TypeError( + "Selector " + index + " must consist of only strings and/or " + + "regular expressions") + } + + var child = findEquivalent(node, entry) + + if (child == null) { + child = new Filter(entry) + if (node.children == null) { + node.children = [child] + } else { + node.children.push(child) + } + } - return test.timeout || 2000 // ms - default timeout + node = child + } } -// Note that a slowness threshold of 0 means to inherit the parent. -exports.getSlow = function (test) { - while (!test.slow && test.parent != null) { - test = test.parent +exports.test = function (filter, path) { + var length = path.length + + while (length !== 0) { + filter = findMatches(filter, path[--length]) + if (filter == null) return false } - return test.slow || 75 // ms - default slow threshold + return true } -},{}],7:[function(require,module,exports){ +},{}],10:[function(require,module,exports){ "use strict" var methods = require("../methods") -var Tests = require("../core/tests") -var Common = require("./common") /** - * This contains the low level, more arcane things that are generally not - * interesting to anyone other than plugin developers. + * All the report types. The only reason there are more than two types (normal + * and hook) is for the user's benefit (dev tools, `util.inspect`, etc.) */ -module.exports = Reflect -function Reflect(test) { - var reflect = test.reflect - - if (reflect != null) return reflect - if (test.root !== test) return test.reflect = new ReflectChild(test) - return test.reflect = new ReflectRoot(test) -} -methods(Reflect, { - /** - * Get the currently executing test. - */ - get current() { - return new Reflect(this._.root.current) - }, +var Types = exports.Types = Object.freeze({ + Start: 0, + Enter: 1, + Leave: 2, + Pass: 3, + Fail: 4, + Skip: 5, + End: 6, + Error: 7, - /** - * Get the root test. - */ - get root() { - return new Reflect(this._.root) - }, + // Note that `Hook` is actually a bit flag, to save some space (and to + // simplify the type representation). + Hook: 8, +}) - /** - * Get the current total test count. - */ - get count() { - return this._.tests == null ? 0 : this._.tests.length - }, +var HookStage = exports.HookStage = Object.freeze({ + BeforeAll: Types.Hook | 0, + BeforeEach: Types.Hook | 1, + AfterEach: Types.Hook | 2, + AfterAll: Types.Hook | 3, +}) - /** - * Get a copy of the current test list, as a Reflect collection. This is - * intentionally a slice, so you can't mutate the real children. - */ - get children() { - if (this._.tests == null) return [] - return this._.tests.map(function (test) { - return new ReflectChild(test) - }) - }, +exports.Report = Report +function Report(type) { + this._ = type +} - /** - * Is this test the root, i.e. top level? - */ - get isRoot() { - return this._.parent == null - }, +// Avoid a recursive call when `inspect`ing a result while still keeping it +// styled like it would be normally. Each type uses a named singleton factory to +// ensure engines show the correct `name`/`displayName` for the type. +function initInspect(inspect, report) { + var type = report._ + + if (type & Types.Hook) { + inspect.stage = report.stage + } + + if (type !== Types.Start && + type !== Types.End && + type !== Types.Error) { + inspect.path = report.path + } + + if (type & Types.Hook) { + inspect.rootPath = report.rootPath + } + + // Only add the relevant properties + if (type === Types.Fail || + type === Types.Error || + type & Types.Hook) { + inspect.value = report.value + } + + if (type === Types.Enter || + type === Types.Pass || + type === Types.Fail) { + inspect.duration = report.duration + inspect.slow = report.slow + } + + if (type === Types.Fail) { + inspect.isFailable = report.isFailable + } +} + +methods(Report, { + // The report types + get isStart() { return this._ === Types.Start }, + get isEnter() { return this._ === Types.Enter }, + get isLeave() { return this._ === Types.Leave }, + get isPass() { return this._ === Types.Pass }, + get isFail() { return this._ === Types.Fail }, + get isSkip() { return this._ === Types.Skip }, + get isEnd() { return this._ === Types.End }, + get isError() { return this._ === Types.Error }, + get isHook() { return (this._ & Types.Hook) !== 0 }, /** - * Is this locked (i.e. unsafe to modify)? + * Get a stringified description of the type. */ - get isLocked() { - return !!this._.locked + get type() { + switch (this._) { + case Types.Start: return "start" + case Types.Enter: return "enter" + case Types.Leave: return "leave" + case Types.Pass: return "pass" + case Types.Fail: return "fail" + case Types.Skip: return "skip" + case Types.End: return "end" + case Types.Error: return "error" + default: + if (this._ & Types.Hook) return "hook" + throw new Error("unreachable") + } }, +}) - /** - * Get the own, not necessarily active, timeout. 0 means inherit the - * parent's, and `Infinity` means it's disabled. - */ - get ownTimeout() { - return this._.timeout || 0 +exports.Start = StartReport +function StartReport() { + Report.call(this, Types.Start) +} +methods(StartReport, Report, { + inspect: function () { + return new function Report(report) { + initInspect(this, report) + }(this) }, +}) +exports.Enter = EnterReport +function EnterReport(path, duration, slow) { + Report.call(this, Types.Enter) + this.path = path + this.duration = duration + this.slow = slow +} +methods(EnterReport, Report, { /** - * Get the active timeout in milliseconds, not necessarily own, or the - * framework default of 2000, if none was set. + * So util.inspect provides more sensible output for testing/etc. */ - get timeout() { - return Common.getTimeout(this._) + inspect: function () { + return new function EnterReport(report) { + initInspect(this, report) + }(this) }, +}) +exports.Leave = LeaveReport +function LeaveReport(path) { + Report.call(this, Types.Leave) + this.path = path +} +methods(LeaveReport, Report, { /** - * Get the own, not necessarily active, slow threshold. 0 means inherit the - * parent's, and `Infinity` means it's disabled. + * So util.inspect provides more sensible output for testing/etc. */ - get ownSlow() { - return this._.slow || 0 + inspect: function () { + return new function LeaveReport(report) { + initInspect(this, report) + }(this) }, +}) +exports.Pass = PassReport +function PassReport(path, duration, slow) { + Report.call(this, Types.Pass) + this.path = path + this.duration = duration + this.slow = slow +} +methods(PassReport, Report, { /** - * Get the active slow threshold in milliseconds, not necessarily own, or - * the framework default of 75, if none was set. + * So util.inspect provides more sensible output for testing/etc. */ - get slow() { - return Common.getSlow(this._) + inspect: function () { + return new function PassReport(report) { + initInspect(this, report) + }(this) }, +}) +exports.Fail = FailReport +function FailReport(path, error, duration, slow, isFailable) { // eslint-disable-line max-params, max-len + Report.call(this, Types.Fail) + this.path = path + this.error = error + this.duration = duration + this.slow = slow + this.isFailable = isFailable +} +methods(FailReport, Report, { /** - * Get the test's own max attempt count. Note that this is parasitically - * inherited from its parent, not delegated. + * So util.inspect provides more sensible output for testing/etc. */ - get attempts() { - return this._.attempts + inspect: function () { + return new function FailReport(report) { + initInspect(this, report) + }(this) }, +}) +exports.Skip = SkipReport +function SkipReport(path) { + Report.call(this, Types.Skip) + this.path = path +} +methods(SkipReport, Report, { /** - * Get whether this test is failable. Note that this is parasitically - * inherited from its parent, not delegated. + * So util.inspect provides more sensible output for testing/etc. */ - get isFailable() { - return this._.isFailable + inspect: function () { + return new function SkipReport(report) { + initInspect(this, report) + }(this) }, +}) +exports.End = EndReport +function EndReport() { + Report.call(this, Types.End) +} +methods(EndReport, Report, { /** - * Add a hook to be run before each subtest, including their subtests and so - * on. + * So util.inspect provides more sensible output for testing/etc. */ - before: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } - - this._.beforeEach = Common.addHook(this._.beforeEach, callback) + inspect: function () { + return new function EndReport(report) { + initInspect(this, report) + }(this) }, +}) +exports.Error = ErrorReport +function ErrorReport(error) { + Report.call(this, Types.Error) + this.error = error +} +methods(ErrorReport, Report, { /** - * Add a hook to be run once before all subtests are run. + * So util.inspect provides more sensible output for testing/etc. */ - beforeAll: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } - - this._.beforeAll = Common.addHook(this._.beforeAll, callback) + inspect: function () { + return new function ErrorReport(report) { + initInspect(this, report) + }(this) }, +}) - /** - * Add a hook to be run after each subtest, including their subtests and so - * on. - */ - after: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") +var HookMethods = { + get stage() { + switch (this._) { + case HookStage.BeforeAll: return "before all" + case HookStage.BeforeEach: return "before each" + case HookStage.AfterEach: return "after each" + case HookStage.AfterAll: return "after all" + default: throw new Error("unreachable") } - - this._.afterEach = Common.addHook(this._.afterEach, callback) }, - /** - * Add a hook to be run once after all subtests are run. - */ - afterAll: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } - - this._.afterAll = Common.addHook(this._.afterAll, callback) - }, - - /** - * Remove a hook previously added with `t.before` or `reflect.before`. - */ - hasBefore: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } - - return Common.hasHook(this._.beforeEach, callback) - }, + get isBeforeAll() { return this._ === HookStage.BeforeAll }, + get isBeforeEach() { return this._ === HookStage.BeforeEach }, + get isAfterEach() { return this._ === HookStage.AfterEach }, + get isAfterAll() { return this._ === HookStage.AfterAll }, +} - /** - * Remove a hook previously added with `t.beforeAll` or `reflect.beforeAll`. - */ - hasBeforeAll: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } +exports.HookError = HookError +function HookError(stage, func, error) { + this._ = stage + this.name = func.name || func.displayName || "" + this.error = error +} +methods(HookError, HookMethods) - return Common.hasHook(this._.beforeAll, callback) - }, +exports.Hook = HookReport +function HookReport(path, rootPath, hookError) { + Report.call(this, hookError._) + this.path = path + this.rootPath = rootPath + this.name = hookError.name + this.error = hookError.error +} +methods(HookReport, Report, HookMethods, { + get hookError() { return new HookError(this._, this, this.error) }, +}) - /** - * Remove a hook previously added with `t.after` or`reflect.after`. - */ - hasAfter: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } +},{"../methods":18}],11:[function(require,module,exports){ +(function (global){ +"use strict" - return Common.hasHook(this._.afterEach, callback) - }, +var methods = require("../methods") +var peach = require("../util").peach +var Reports = require("./reports") +var Filter = require("./filter") +var HookStage = Reports.HookStage - /** - * Remove a hook previously added with `t.afterAll` or `reflect.afterAll`. - */ - hasAfterAll: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } +/** + * The tests are laid out in a very data-driven design. With exception of the + * reports, there is minimal object orientation and zero virtual dispatch. + * Here's a quick overview: + * + * - The test handling dispatches based on various attributes the test has. For + * example, roots are known by a circular root reference, and skipped tests + * are known by not having a callback. + * + * - The test evaluation is very procedural. Although it's very highly + * asynchronous, the use of promises linearize the logic, so it reads very + * much like a recursive set of steps. + * + * - The data types are mostly either plain objects or classes with no methods, + * the latter mostly for debugging help. This also avoids most of the + * indirection required to accommodate breaking abstractions, which the API + * methods frequently need to do. + */ - return Common.hasHook(this._.afterAll, callback) - }, +// Prevent Sinon interference when they install their mocks +var setTimeout = global.setTimeout +var clearTimeout = global.clearTimeout +var now = global.Date.now - /** - * Remove a hook previously added with `t.before` or `reflect.before`. - */ - removeBefore: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } +/** + * Basic data types + */ +function Result(time, attempt) { + this.time = time + this.caught = attempt.caught + this.value = attempt.caught ? attempt.value : undefined +} - this._.beforeEach = Common.removeHook(this._.beforeEach, callback) - }, +/** + * Overview of the test properties: + * + * - `root` - The root test + * - `reporters` - The list of reporters + * - `current` - A reference to the currently active test + * - `timeout` - The tests's timeout, or 0 if inherited + * - `slow` - The tests's slow threshold + * - `name` - The test's name + * - `index` - The test's index + * - `parent` - The test's parent + * - `callback` - The test's callback + * - `tests` - The test's child tests + * - `beforeAll`, `beforeEach`, `afterEach`, `afterAll` - The test's various + * scheduled hooks + * + * Many of these properties aren't present on initialization to save memory. + */ - /** - * Remove a hook previously added with `t.beforeAll` or `reflect.beforeAll`. - */ - removeBeforeAll: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } +function Normal(name, index, parent, callback) { + this.locked = true + this.root = parent.root + this.name = name + this.index = index|0 + this.parent = parent + this.callback = callback + this.isFailable = parent.isFailable + this.attempts = parent.attempts - this._.beforeAll = Common.removeHook(this._.beforeAll, callback) - }, + this.timeout = parent.timeout + this.slow = parent.slow + this.tests = undefined + this.beforeAll = undefined + this.beforeEach = undefined + this.afterEach = undefined + this.afterAll = undefined + this.reporter = undefined + this.reflect = undefined +} - /** - * Remove a hook previously added with `t.after` or`reflect.after`. - */ - removeAfter: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } +function Skipped(name, index, parent) { + this.locked = true + this.root = parent.root + this.name = name + this.index = index|0 + this.parent = parent - this._.afterEach = Common.removeHook(this._.afterEach, callback) - }, + // Only for reflection. + this.isFailable = parent.isFailable + this.attempts = parent.attempts + this.reporter = undefined + this.reflect = undefined +} - /** - * Remove a hook previously added with `t.afterAll` or `reflect.afterAll`. - */ - removeAfterAll: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } +function Root() { + this.locked = false + this.reporterIds = [] + this.reporters = [] + this.current = this + this.root = this + this.timeout = 0 + this.slow = 0 + this.attempts = 1 + this.isFailable = false - this._.afterAll = Common.removeHook(this._.afterAll, callback) - }, + this.tests = undefined + this.reporter = undefined + this.reflect = undefined + this.beforeAll = undefined + this.beforeEach = undefined + this.afterEach = undefined + this.afterAll = undefined +} - /** - * Add a block or inline test. - */ - test: function (name, callback) { - if (typeof name !== "string") { - throw new TypeError("Expected `name` to be a string") - } +function Context(root) { + this.root = root + this.tests = [] + this.isSuccess = true +} - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } +/** + * Base tests (i.e. default export, result of `internal.root()`). + */ - Tests.addNormal(this._.root.current, name, callback) - }, +exports.createRoot = function (methods) { + return new Root(methods) +} - /** - * Add a skipped block or inline test. - */ - testSkip: function (name, callback) { - if (typeof name !== "string") { - throw new TypeError("Expected `name` to be a string") - } +/** + * Set up each test type. + */ - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } +/** + * A normal test through `t.test()`. + */ - Tests.addSkipped(this._.root.current, name) - }, -}) +exports.addNormal = function (parent, name, callback) { + var index = parent.tests != null ? parent.tests.length : 0 + var base = new Normal(name, index, parent, callback) -function ReflectRoot(root) { - this._ = root + if (index) { + parent.tests.push(base) + } else { + parent.tests = [base] + } } -methods(ReflectRoot, Reflect, { - /** - * Whether a reporter was registered. - */ - hasReporter: function (reporter) { - if (typeof reporter !== "function") { - throw new TypeError("Expected `reporter` to be a function") - } - - return this._.root.reporterIds.indexOf(reporter) >= 0 - }, +/** + * A skipped test through `t.testSkip()`. + */ +exports.addSkipped = function (parent, name) { + var index = parent.tests != null ? parent.tests.length : 0 + var base = new Skipped(name, index, parent) - /** - * Add a reporter. - */ - reporter: function (reporter, arg) { - if (typeof reporter !== "function") { - throw new TypeError("Expected `reporter` to be a function") - } + if (index) { + parent.tests.push(base) + } else { + parent.tests = [base] + } +} - var root = this._.root +/** + * Clear the tests in place. + */ +exports.clearTests = function (parent) { + parent.tests = null +} - if (root.current !== root) { - throw new Error("Reporters may only be added to the root") - } +/** + * Execute the tests + */ - if (root.reporterIds.indexOf(reporter) < 0) { - root.reporterIds.push(reporter) - root.reporters.push(reporter(arg)) - } - }, +exports.defaultTimeout = 2000 // ms +exports.defaultSlow = 75 // ms - /** - * Remove a reporter. - */ - removeReporter: function (reporter) { - if (typeof reporter !== "function") { - throw new TypeError("Expected `reporter` to be a function") - } +function makeSlice(tests, length) { + var ret = new Array(length) - var root = this._.root + for (var i = 0; i < length; i++) { + ret[i] = {name: tests[i].name, index: tests[i].index} + } - if (root.current !== root) { - throw new Error("Reporters may only be added to the root") - } + return ret +} - var index = root.reporterIds.indexOf(reporter) +function reportWith(context, func) { + return Promise.resolve() + .then(function () { + if (context.root.reporter == null) return undefined + return func(context.root.reporter) + }) + .then(function () { + var reporters = context.root.reporters - if (index >= 0) { - root.reporterIds.splice(index, 1) - root.reporters.splice(index, 1) - } - }, -}) + // Two easy cases. + if (reporters.length === 0) return undefined + if (reporters.length === 1) return func(reporters[0]) + return Promise.all(reporters.map(func)) + }) +} -function ReflectChild(root) { - this._ = root +function reportStart(context) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Start()) + }) } -methods(ReflectChild, Reflect, { - /** - * Get the test name, or `undefined` if it's the root test. - */ - get name() { - return this._.name - }, +function reportEnter(context, duration) { + var test = context.root.current + var slow = test.slow || exports.defaultSlow - /** - * Get the test index, or `-1` if it's the root test. - */ - get index() { - return this._.index - }, + return reportWith(context, function (reporter) { + var path = makeSlice(context.tests, context.tests.length) - /** - * Get the parent test as a Reflect. - */ - get parent() { - return new Reflect(this._.parent) - }, -}) + return reporter(new Reports.Enter(path, duration, slow)) + }) +} -},{"../core/tests":12,"../methods":19,"./common":6}],8:[function(require,module,exports){ -"use strict" +function reportLeave(context) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Leave( + makeSlice(context.tests, context.tests.length))) + }) +} -var methods = require("../methods") -var Tests = require("../core/tests") -var Filter = require("../core/filter") -var Common = require("./common") -var Reflect = require("./reflect") +function reportPass(context, duration) { + var test = context.root.current + var slow = test.slow || exports.defaultSlow -module.exports = Thallium -function Thallium() { - this._ = Tests.createRoot(this) + return reportWith(context, function (reporter) { + var path = makeSlice(context.tests, context.tests.length) + + return reporter(new Reports.Pass(path, duration, slow)) + }) } -methods(Thallium, { - /** - * Call a plugin and return the result. The plugin is called with a Reflect - * instance for access to plenty of potentially useful internal details. - */ - call: function (plugin, arg) { - var reflect = new Reflect(this._.root.current) +function reportFail(context, error, duration) { + var test = context.root.current + var slow = test.slow || exports.defaultSlow + var isFailable = test.isFailable - return plugin.call(reflect, reflect, arg) - }, + return reportWith(context, function (reporter) { + var path = makeSlice(context.tests, context.tests.length) - /** - * Whitelist specific tests, using array-based selectors where each entry - * is either a string or regular expression. - */ - only: function (/* ...selectors */) { - this._.root.current.only = Filter.create.apply(undefined, arguments) - }, + return reporter(new Reports.Fail( + path, error, duration, slow, isFailable)) + }) +} - /** - * Add a reporter. - */ - reporter: function (reporter, arg) { - if (typeof reporter !== "function") { - throw new TypeError("Expected `reporter` to be a function.") - } +function reportSkip(context) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Skip( + makeSlice(context.tests, context.tests.length))) + }) +} - var root = this._.root +function reportEnd(context) { + return reportWith(context, function (reporter) { + return reporter(new Reports.End()) + }) +} - if (root.current !== root) { - throw new Error("Reporters may only be added to the root.") - } +function reportError(context, error) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Error(error)) + }) +} - var result = reporter(arg) +function reportHook(context, test, error) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Hook( + makeSlice(context.tests, context.tests.length), + makeSlice(context.tests, context.tests.indexOf(test) + 1), + error)) + }) +} - // Don't assume it's a function. Verify it actually is, so we don't have - // inexplicable type errors internally after it's invoked, and so users - // won't get too confused. - if (typeof result !== "function") { - throw new TypeError( - "Expected `reporter` to return a function. Check with the " + - "reporter's author, and have them fix their reporter.") +/** + * Normal tests + */ + +// PhantomJS and IE don't add the stack until it's thrown. In failing async +// tests, it's already thrown in a sense, so this should be normalized with +// other test types. +var addStack = typeof new Error().stack !== "string" + ? function addStack(e) { + try { + if (e instanceof Error && e.stack == null) throw e + } finally { + return e } + } + : function (e) { return e } - root.reporter = result - }, +function getThen(res) { + if (typeof res === "object" || typeof res === "function") { + return res.then + } else { + return undefined + } +} - /** - * Check if this has a reporter. - */ - get hasReporter() { - return this._.root.reporter != null - }, +function AsyncState(context, start, resolve, count) { + this.context = context + this.start = start + this.resolve = resolve + this.count = count + this.timer = undefined +} - /** - * Get the current timeout. 0 means inherit the parent's, and `Infinity` - * means it's disabled. - */ - get timeout() { - return Common.getTimeout(this._.root.current) - }, +var p = Promise.resolve() - /** - * Set the timeout in milliseconds, rounding negatives to 0. Setting the - * timeout to 0 means to inherit the parent timeout, and setting it to - * `Infinity` disables it. - */ - set timeout(timeout) { - this._.root.current.timeout = Math.floor(Math.max(+timeout, 0)) - }, +function asyncFinish(state, attempt) { + // Capture immediately. Worst case scenario, it gets thrown away. + var end = now() - /** - * Get the current slow threshold. 0 means inherit the parent's, and - * `Infinity` means it's disabled. - */ - get slow() { - return Common.getSlow(this._.root.current) - }, + if (state.timer) { + clearTimeout.call(global, state.timer) + state.timer = undefined + } - /** - * Set the slow threshold in milliseconds, rounding negatives to 0. Setting - * the timeout to 0 means to inherit the parent threshold, and setting it to - * `Infinity` disables it. - */ - set slow(slow) { - this._.root.current.slow = Math.floor(Math.max(+slow, 0)) - }, + if (attempt.caught && state.count < state.context.root.current.attempts) { + // Don't recurse synchronously, since it may be resolved synchronously + state.resolve(p.then(function () { + return invokeInit(state.context, state.count + 1) + })) + } else { + state.resolve(new Result(end - state.start, attempt)) + } +} - /** - * Get the current attempt count. `0` means inherit the parent's. - */ - get attempts() { - return this._.root.current.attempts - }, +// Avoid creating a closure if possible, in case it doesn't return a thenable. +function invokeInit(context, count) { + var test = context.root.current + var start = now() + var tryBody = try0(test.callback) + var syncEnd = now() - /** - * Set the number of attempts allowed, rounding negatives to 0. Setting the - * count to `0` means to inherit the parent retry count. - */ - set attempts(attempts) { - // This is done differently to avoid a massive performance penalty. - var calculated = Math.floor(Math.max(attempts, 0)) - var test = this._.root.current + // Note: synchronous failures are test failures, not fatal errors. + if (tryBody.caught) { + if (count < test.attempts) return invokeInit(context, count + 1) + return Promise.resolve(new Result(syncEnd - start, tryBody)) + } - test.attempts = calculated || test.parent.attempts - }, + var tryThen = try1(getThen, undefined, tryBody.value) - /** - * Get whether this test is failable. - */ - get isFailable() { - return this._.root.current.isFailable - }, + if (tryThen.caught) { + if (count < test.attempts) return invokeInit(context, count + 1) + return Promise.resolve(new Result(syncEnd - start, tryThen)) + } - /** - * Get whether this test is failable. - */ - set isFailable(isFailable) { - this._.root.current.isFailable = !!isFailable - }, + if (typeof tryThen.value !== "function") { + return Promise.resolve(new Result(syncEnd - start, tryThen)) + } - /** - * Run the tests (or the test's tests if it's not a base instance). - */ - run: function (opts) { - if (this._.root !== this._) { - throw new Error( - "Only the root test can be run - If you only want to run a " + - "subtest, use `t.only([\"selector1\", ...])` instead.") - } + return new Promise(function (resolve) { + var state = new AsyncState(context, start, resolve, count) + var result = try2(tryThen.value, tryBody.value, + function () { + if (state == null) return + asyncFinish(state, tryPass()) + state = undefined + }, + function (e) { + if (state == null) return + asyncFinish(state, tryFail(addStack(e))) + state = undefined + }) - if (this._.locked) { - throw new Error("Can't run while tests are already running.") + if (state == null) return + if (result.caught) { + asyncFinish(state, result) + state = undefined + return } - return Tests.runTest(this._, opts) - }, - - /** - * Add a test. - */ - test: function (name, callback) { - if (typeof name !== "string") { - throw new TypeError("Expected `name` to be a string") - } + // Set the timeout *after* initialization. The timeout will likely be + // specified during initialization. + var maxTimeout = test.timeout || exports.defaultTimeout - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") + // Setting a timeout is pointless if it's infinite. + if (maxTimeout !== Infinity) { + state.timer = setTimeout.call(global, function () { + if (state == null) return + asyncFinish(state, tryFail(addStack( + new Error("Timeout of " + maxTimeout + " reached")))) + state = undefined + }, maxTimeout) } + }) +} - Tests.addNormal(this._.root.current, name, callback) - }, +function ErrorWrap(test, error) { + this.test = test + this.error = error +} +methods(ErrorWrap, Error, {name: "ErrorWrap"}) - /** - * Add a skipped test. - */ - testSkip: function (name, callback) { - if (typeof name !== "string") { - throw new TypeError("Expected `name` to be a string") +function invokeHook(test, list, stage) { + if (list == null) return Promise.resolve() + return peach(list, function (hook) { + try { + return hook() + } catch (e) { + throw new ErrorWrap(test, new Reports.HookError(stage, hook, e)) } + }) +} - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } +function invokeBeforeEach(test) { + if (test.root === test) { + return invokeHook(test, test.beforeEach, HookStage.BeforeEach) + } else { + return invokeBeforeEach(test.parent).then(function () { + return invokeHook(test, test.beforeEach, HookStage.BeforeEach) + }) + } +} - Tests.addSkipped(this._.root.current, name) - }, +function invokeAfterEach(test) { + if (test.root === test) { + return invokeHook(test, test.afterEach, HookStage.AfterEach) + } else { + return invokeHook(test, test.afterEach, HookStage.AfterEach) + .then(function () { return invokeAfterEach(test.parent) }) + } +} - /** - * Clear all existing tests. - */ - clearTests: function () { - if (this._.root !== this._) { - throw new Error("Tests may only be cleared at the root.") - } +/** + * This checks if the test was whitelisted in a `t.only()` call, or for + * convenience, returns `true` if `t.only()` was never called. + */ +function isOnly(test) { + var path = [] - if (this._.locked) { - throw new Error("Can't clear tests while they are running.") - } + while (test.parent != null && test.only == null) { + path.push(test.name) + test = test.parent + } - Tests.clearTests(this._) - }, + // If there isn't any `only` active, then let's skip the check and return + // `true` for convenience. + if (test.only == null) return true + return Filter.test(test.only, path) +} - before: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } +function runChildTests(test, context) { + if (test.tests == null) return undefined - var test = this._.root.current + function leave() { + test.root.current = test + context.tests.pop() + } - test.beforeEach = Common.addHook(test.beforeEach, callback) - }, + function runChild(child) { + test.root.current = child + context.tests.push(child) - beforeAll: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") - } + return invokeBeforeEach(test) + .then(function () { return runNormalChild(child, context) }) + .then(function () { return invokeAfterEach(test) }) + .catch(function (e) { + if (!(e instanceof ErrorWrap)) throw e + return reportHook(context, e.test, e.error) + }) + .then(leave, function (e) { leave(); throw e }) + } - var test = this._.root.current + var ran = false - test.beforeAll = Common.addHook(test.beforeAll, callback) - }, + return peach(test.tests, function (child) { + // Only skipped tests have no callback + if (child.callback == null) { + test.root.current = child + context.tests.push(child) - after: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") + return reportSkip(context) + .then(leave, function (e) { leave(); throw e }) + } else if (!isOnly(child)) { + return Promise.resolve() + } else if (ran) { + return runChild(child) + } else { + ran = true + return invokeHook(test, test.beforeAll, HookStage.BeforeAll) + .then(function () { return runChild(child) }) } + }) + .then(function () { + if (!ran) return undefined + return invokeHook(test, test.afterAll, HookStage.AfterAll) + }) +} - var test = this._.root.current +function clearChildren(test) { + if (test.tests == null) return + for (var i = 0; i < test.tests.length; i++) { + test.tests[i].tests = undefined + } +} - test.afterEach = Common.addHook(test.afterEach, callback) - }, +function runNormalChild(test, context) { + test.locked = false - afterAll: function (callback) { - if (typeof callback !== "function") { - throw new TypeError("Expected callback to be a function if passed") + return invokeInit(context, 1) + .then( + function (result) { test.locked = true; return result }, + function (error) { test.locked = true; throw error }) + .then(function (result) { + if (result.caught) { + if (!test.isFailable) context.isSuccess = false + return reportFail(context, result.value, result.time) + } else if (test.tests != null) { + // Report this as if it was a parent test if it's passing and has + // children. + return reportEnter(context, result.time) + .then(function () { return runChildTests(test, context) }) + .then(function () { return reportLeave(context) }) + .catch(function (e) { + if (!(e instanceof ErrorWrap)) throw e + return reportLeave(context).then(function () { + return reportHook(context, e.test, e.error) + }) + }) + } else { + return reportPass(context, result.time) } - - var test = this._.root.current - - test.afterAll = Common.addHook(test.afterAll, callback) - }, -}) - -},{"../core/filter":10,"../core/tests":12,"../methods":19,"./common":6,"./reflect":7}],9:[function(require,module,exports){ -"use strict" + }) + .then( + function () { clearChildren(test) }, + function (e) { clearChildren(test); throw e }) +} /** - * This is the entry point for the Browserify bundle. Note that it *also* will - * run as part of the tests in Node (unbundled), and it theoretically could be - * run in Node or a runtime limited to only ES5 support (e.g. Rhino, Nashorn, or - * embedded V8), so do *not* assume browser globals are present. + * This runs the root test and returns a promise resolved when it's done. */ +exports.runTest = function (root, opts) { + var context = new Context(root, opts) -exports.t = require("../index") -exports.assert = require("../assert") -exports.r = require("../r") -var dom = require("../dom") + root.locked = true + return reportStart(context) + .then(function () { return runChildTests(root, context) }) + .catch(function (e) { + if (!(e instanceof ErrorWrap)) throw e + return reportHook(context, e.test, e.error) + }) + .then(function () { return reportEnd(context) }) + // Tell the reporter something happened. Otherwise, it'll have to wrap this + // method in a plugin, which shouldn't be necessary. + .catch(function (e) { + return reportError(context, e).then(function () { throw e }) + }) + .then( + function () { + clearChildren(root) + root.locked = false + return { + isSuccess: context.isSuccess, + } + }, + function (e) { + clearChildren(root) + root.locked = false + throw e + }) +} -exports.dom = dom.create -// if (global.document != null && global.document.currentScript != null) { -// dom.autoload(global.document.currentScript) -// } +// Help optimize for inefficient exception handling in V8 -var Internal = require("../internal") +function tryPass(value) { + return {caught: false, value: value} +} -exports.root = Internal.root -exports.reports = Internal.reports -exports.hookErrors = Internal.hookErrors -exports.location = Internal.location +function tryFail(e) { + return {caught: true, value: e} +} -// In case the user needs to adjust this (e.g. Nashorn + console output). -var Settings = require("./settings") +function try0(f) { + try { + return tryPass(f()) + } catch (e) { + return tryFail(e) + } +} -exports.settings = { - windowWidth: { - get: Settings.windowWidth, - set: Settings.setWindowWidth, - }, +function try1(f, inst, arg0) { + try { + return tryPass(f.call(inst, arg0)) + } catch (e) { + return tryFail(e) + } +} - newline: { - get: Settings.newline, - set: Settings.setNewline, - }, +function try2(f, inst, arg0, arg1) { + try { + return tryPass(f.call(inst, arg0, arg1)) + } catch (e) { + return tryFail(e) + } +} - symbols: { - get: Settings.symbols, - set: Settings.setSymbols, - }, +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - defaultOpts: { - get: Settings.defaultOpts, - set: Settings.setDefaultOpts, - }, +},{"../methods":18,"../util":26,"./filter":9,"./reports":10}],12:[function(require,module,exports){ +"use strict" - colorSupport: { - get: Settings.Colors.getSupport, - set: Settings.Colors.setSupport, - }, +/** + * The DOM reporter and loader entry point. See the README.md for more details. + */ + +var initialize = require("./initialize") +// var t = require("../../index") +// var assert = require("../../assert") + +exports.create = function (opts) { + if (opts == null) return initialize({}) + if (Array.isArray(opts)) return initialize({files: opts}) + if (typeof opts === "object") return initialize(opts) + throw new TypeError("`opts` must be an object or array of files if passed") } -},{"../assert":1,"../dom":3,"../index":4,"../internal":5,"../r":67,"./settings":26}],10:[function(require,module,exports){ +// Currently broken, because this isn't autoloaded yet. +// exports.autoload = function (script) { +// var files = script.getAttribute("data-files") +// +// if (!files) return +// +// function set(opts, attr, transform) { +// var value = script.getAttribute("data-" + attr) +// +// if (value) opts[attr] = transform(value) +// } +// +// var opts = {files: files.trim().split(/\s+/g)} +// +// set(opts, "timeout", Number) +// set(opts, "preload", Function) +// set(opts, "prerun", Function) +// set(opts, "postrun", Function) +// set(opts, "error", function (attr) { +// return new Function("err", attr) // eslint-disable-line +// }) +// +// // Convenience. +// global.t = t +// global.assert = assert +// +// if (global.document.readyState !== "loading") { +// initialize(opts).run() +// } else { +// global.document.addEventListener("DOMContentLoaded", function () { +// initialize(opts).run() +// }) +// } +// } + +},{"./initialize":13}],13:[function(require,module,exports){ "use strict" /** - * The filter is actually stored as a tree for faster lookup times when there - * are multiple selectors. Objects can't be used for the nodes, where keys - * represent values and values represent children, because regular expressions - * aren't possible to use. + * The reporter and test initialization sequence, and script loading. This + * doesn't understand anything view-wise. */ -function isEquivalent(entry, item) { - if (typeof entry === "string" && typeof item === "string") { - return entry === item - } else if (entry instanceof RegExp && item instanceof RegExp) { - return entry.toString() === item.toString() - } else { - return false - } -} +var defaultT = require("../../index") +var R = require("../reporter") +var D = require("./inject") +var runTests = require("./run-tests") +var injectStyles = require("./inject-styles") +var View = require("./view") +var methods = require("../methods") -function matches(entry, item) { - if (typeof entry === "string") { - return entry === item - } else { - return entry.test(item) - } +function Tree(name) { + this.name = name + this.status = R.Status.Unknown + this.node = null + this.children = Object.create(null) } -function Filter(value) { - this.value = value - this.children = undefined -} +var reporter = R.on("dom", { + accepts: [], + create: function (opts, methods) { + var reporter = new R.Reporter(Tree, undefined, methods) -function findEquivalent(node, entry) { - if (node.children == null) return undefined + reporter.opts = opts + return reporter + }, - for (var i = 0; i < node.children.length; i++) { - var child = node.children[i] + // Give the browser a chance to repaint before continuing (microtasks + // normally block rendering). + after: function () { + return new Promise(View.nextFrame) + }, - if (isEquivalent(child.value, entry)) return child - } + report: function (_, report) { + return View.report(_, report) + }, +}) - return undefined -} +function noop() {} -function findMatches(node, entry) { - if (node.children == null) return undefined +function setDefaultsChecked(opts) { + if (opts.title == null) opts.title = "Thallium tests" + if (opts.timeout == null) opts.timeout = 5000 + if (opts.files == null) opts.files = [] + if (opts.preload == null) opts.preload = noop + if (opts.prerun == null) opts.prerun = noop + if (opts.postrun == null) opts.postrun = noop + if (opts.error == null) opts.error = noop + if (opts.thallium == null) opts.thallium = defaultT - for (var i = 0; i < node.children.length; i++) { - var child = node.children[i] + if (typeof opts.title !== "string") { + throw new TypeError("`opts.title` must be a string if passed") + } - if (matches(child.value, entry)) return child + if (typeof opts.timeout !== "number") { + throw new TypeError("`opts.timeout` must be a number if passed") } - return undefined -} + if (!Array.isArray(opts.files)) { + throw new TypeError("`opts.files` must be an array if passed") + } -/** - * Create a filter from a number of selectors - */ -exports.create = function (/* ...selectors */) { - var filter = new Filter() + if (typeof opts.preload !== "function") { + throw new TypeError("`opts.preload` must be a function if passed") + } - for (var i = 0; i < arguments.length; i++) { - var selector = arguments[i] + if (typeof opts.prerun !== "function") { + throw new TypeError("`opts.prerun` must be a function if passed") + } - if (!Array.isArray(selector)) { - throw new TypeError( - "Expected selector " + i + " to be an array") - } + if (typeof opts.postrun !== "function") { + throw new TypeError("`opts.postrun` must be a function if passed") + } - filterAddSingle(filter, selector, i) + if (typeof opts.error !== "function") { + throw new TypeError("`opts.error` must be a function if passed") } - return filter + if (typeof opts.thallium !== "object") { + throw new TypeError( + "`opts.thallium` must be a Thallium instance if passed") + } } -function filterAddSingle(node, selector, index) { - for (var i = 0; i < selector.length; i++) { - var entry = selector[i] +function onReady(init) { + if (D.document.body != null) return Promise.resolve(init()) + return new Promise(function (resolve) { + D.document.addEventListener("DOMContentLoaded", function () { + resolve(init()) + }, false) + }) +} - // Strings and regular expressions are the only things allowed. - if (typeof entry !== "string" && !(entry instanceof RegExp)) { - throw new TypeError( - "Selector " + index + " must consist of only strings and/or " + - "regular expressions") - } +function DOM(opts) { + this._opts = opts + this._destroyPromise = undefined + this._data = onReady(function () { + setDefaultsChecked(opts) + if (!D.document.title) D.document.title = opts.title + injectStyles() + var data = View.init(opts) - var child = findEquivalent(node, entry) + opts.thallium.reporter(reporter, data.state) + return data + }) +} - if (child == null) { - child = new Filter(entry) - if (node.children == null) { - node.children = [child] - } else { - node.children.push(child) - } +methods(DOM, { + run: function () { + if (this._destroyPromise != null) { + return Promise.reject(new Error( + "The test suite must not be run after the view has been " + + "detached." + )) } - node = child - } -} + var opts = this._opts -exports.test = function (filter, path) { - var length = path.length + return this._data.then(function (data) { + return runTests(opts, data.state) + }) + }, - while (length !== 0) { - filter = findMatches(filter, path[--length]) - if (filter == null) return false - } + detach: function () { + if (this._destroyPromise != null) return this._destroyPromise + var self = this - return true + return this._destroyPromise = self._data.then(function (data) { + data.state.locked = true + if (data.state.currentPromise == null) return data + return data.state.currentPromise.then(function () { return data }) + }) + .then(function (data) { + self._opts = undefined + self._data = self._destroyPromise + + while (data.root.firstChild) { + data.root.removeChild(data.root.firstChild) + } + }) + }, +}) + +module.exports = function (opts) { + return new DOM(opts) } -},{}],11:[function(require,module,exports){ +},{"../../index":3,"../methods":18,"../reporter":21,"./inject":15,"./inject-styles":14,"./run-tests":16,"./view":17}],14:[function(require,module,exports){ "use strict" -var methods = require("../methods") +var Util = require("../util") +var D = require("./inject") /** - * All the report types. The only reason there are more than two types (normal - * and hook) is for the user's benefit (dev tools, `util.inspect`, etc.) + * The reporter stylesheet. Here's the format: + * + * // Single item + * ".selector": { + * // props... + * } + * + * // Duplicate entries + * ".selector": { + * "prop": [ + * // values... + * ], + * } + * + * // Duplicate selectors + * ".selector": [ + * // values... + * ] + * + * // Media query + * "@media screen": { + * // selectors... + * } + * + * Note that CSS strings *must* be quoted inside the value. */ -var Types = exports.Types = Object.freeze({ - Start: 0, - Enter: 1, - Leave: 2, - Pass: 3, - Fail: 4, - Skip: 5, - End: 6, - Error: 7, +var styles = Util.lazy(function () { + var hasOwn = Object.prototype.hasOwnProperty - // Note that `Hook` is denoted by the 4th bit set, to save some space (and - // to simplify the type representation). - Hook: 8, - BeforeAll: 8 | 0, - BeforeEach: 8 | 1, - AfterEach: 8 | 2, - AfterAll: 8 | 3, -}) + /** + * Partially taken and adapted from normalize.css (licensed under the MIT + * License). + * https://github.com/necolas/normalize.css + */ + var styleObject = { + "#tl": { + "font-family": "sans-serif", + "line-height": "1.15", + "-ms-text-size-adjust": "100%", + "-webkit-text-size-adjust": "100%", + }, -exports.Report = Report -function Report(type) { - this._ = type -} + "#tl button": { + "font-family": "sans-serif", + "line-height": "1.15", + "overflow": "visible", + "font-size": "100%", + "margin": "0", + "text-transform": "none", + "-webkit-appearance": "button", + }, -// Avoid a recursive call when `inspect`ing a result while still keeping it -// styled like it would be normally. Each type uses a named singleton factory to -// ensure engines show the correct `name`/`displayName` for the type. -function initInspect(inspect, report) { - var type = report._ + "#tl h1": { + "font-size": "2em", + "margin": "0.67em 0", + }, - if (type & Types.Hook) { - inspect.stage = report.stage - } + "#tl a": { + "background-color": "transparent", + "-webkit-text-decoration-skip": "objects", + }, - if (type !== Types.Start && - type !== Types.End && - type !== Types.Error) { - inspect.path = report.path - } + "#tl a:active, #tl a:hover": { + "outline-width": "0", + }, - if (type & Types.Hook) { - inspect.rootPath = report.rootPath - } + "#tl button::-moz-focus-inner": { + "border-style": "none", + "padding": "0", + }, - // Only add the relevant properties - if (type === Types.Fail || - type === Types.Error || - type & Types.Hook) { - inspect.value = report.value - } + "#tl button:-moz-focusring": { + outline: "1px dotted ButtonText", + }, - if (type === Types.Enter || - type === Types.Pass || - type === Types.Fail) { - inspect.duration = report.duration - inspect.slow = report.slow - } + /** + * Base styles. Note that this CSS is designed to intentionally override + * most things that could propagate. + */ + "#tl *": [ + {"text-align": "left"}, + {"text-align": "start"}, + ], - if (type === Types.Fail) { - inspect.isFailable = report.isFailable - } -} + "#tl .tl-report, #tl .tl-report ul": { + "list-style-type": "none", + }, -methods(Report, { - // The report types - get isStart() { return this._ === Types.Start }, - get isEnter() { return this._ === Types.Enter }, - get isLeave() { return this._ === Types.Leave }, - get isPass() { return this._ === Types.Pass }, - get isFail() { return this._ === Types.Fail }, - get isSkip() { return this._ === Types.Skip }, - get isEnd() { return this._ === Types.End }, - get isError() { return this._ === Types.Error }, - get isHook() { return (this._ & Types.Hook) !== 0 }, + "#tl li ~ .tl-suite": { + "padding-top": "1em", + }, - /** - * Get a stringified description of the type. - */ - get type() { - switch (this._) { - case Types.Start: return "start" - case Types.Enter: return "enter" - case Types.Leave: return "leave" - case Types.Pass: return "pass" - case Types.Fail: return "fail" - case Types.Skip: return "skip" - case Types.End: return "end" - case Types.Error: return "error" - default: - if (this._ & Types.Hook) return "hook" - throw new Error("unreachable") - } - }, -}) + "#tl .tl-suite > h2": { + "color": "black", + "font-size": "1.5em", + "font-weight": "bold", + "margin-bottom": "0.5em", + }, -exports.Start = StartReport -function StartReport() { - Report.call(this, Types.Start) -} -methods(StartReport, Report, { - inspect: function () { - return new function Report(report) { - initInspect(this, report) - }(this) - }, -}) + "#tl .tl-suite .tl-suite > h2": { + "font-size": "1.2em", + "margin-bottom": "0.3em", + }, -exports.Enter = EnterReport -function EnterReport(path, duration, slow) { - Report.call(this, Types.Enter) - this.path = path - this.duration = duration - this.slow = slow -} -methods(EnterReport, Report, { - /** - * So util.inspect provides more sensible output for testing/etc. - */ - inspect: function () { - return new function EnterReport(report) { - initInspect(this, report) - }(this) - }, -}) + "#tl .tl-suite .tl-suite .tl-suite > h2": { + "font-size": "1.2em", + "margin-bottom": "0.2em", + "font-weight": "normal", + }, -exports.Leave = LeaveReport -function LeaveReport(path) { - Report.call(this, Types.Leave) - this.path = path -} -methods(LeaveReport, Report, { - /** - * So util.inspect provides more sensible output for testing/etc. - */ - inspect: function () { - return new function LeaveReport(report) { - initInspect(this, report) - }(this) - }, -}) + "#tl .tl-test > h2": { + "color": "black", + "font-size": "1em", + "font-weight": "normal", + "margin": "0", + }, -exports.Pass = PassReport -function PassReport(path, duration, slow) { - Report.call(this, Types.Pass) - this.path = path - this.duration = duration - this.slow = slow -} -methods(PassReport, Report, { - /** - * So util.inspect provides more sensible output for testing/etc. - */ - inspect: function () { - return new function PassReport(report) { - initInspect(this, report) - }(this) - }, -}) + "#tl .tl-test > :first-child::before": { + "display": "inline-block", + "font-weight": "bold", + "width": "1.2em", + "text-align": "center", + "font-family": "sans-serif", + "text-shadow": "0 3px 2px #969696", + }, -exports.Fail = FailReport -function FailReport(path, error, duration, slow, isFailable) { // eslint-disable-line max-params, max-len - Report.call(this, Types.Fail) - this.path = path - this.error = error - this.duration = duration - this.slow = slow - this.isFailable = isFailable -} -methods(FailReport, Report, { - /** - * So util.inspect provides more sensible output for testing/etc. - */ - inspect: function () { - return new function FailReport(report) { - initInspect(this, report) - }(this) - }, -}) + "#tl .tl-test.tl-fail > h2, #tl .tl-test.tl-error > h2": { + color: "#c00", + }, -exports.Skip = SkipReport -function SkipReport(path) { - Report.call(this, Types.Skip) - this.path = path -} -methods(SkipReport, Report, { - /** - * So util.inspect provides more sensible output for testing/etc. - */ - inspect: function () { - return new function SkipReport(report) { - initInspect(this, report) - }(this) - }, -}) + "#tl .tl-test.tl-skip > h2": { + color: "#08c", + }, -exports.End = EndReport -function EndReport() { - Report.call(this, Types.End) -} -methods(EndReport, Report, { - /** - * So util.inspect provides more sensible output for testing/etc. - */ - inspect: function () { - return new function EndReport(report) { - initInspect(this, report) - }(this) - }, -}) + "#tl .tl-test.tl-pass > :first-child::before": { + content: "'✓'", + color: "#0c0", + }, -exports.Error = ErrorReport -function ErrorReport(error) { - Report.call(this, Types.Error) - this.error = error -} -methods(ErrorReport, Report, { - /** - * So util.inspect provides more sensible output for testing/etc. - */ - inspect: function () { - return new function ErrorReport(report) { - initInspect(this, report) - }(this) - }, -}) + "#tl .tl-test.tl-fail > :first-child::before": { + content: "'✖'", + }, -var HookMethods = { - get stage() { - switch (this._) { - case Types.BeforeAll: return "before all" - case Types.BeforeEach: return "before each" - case Types.AfterEach: return "after each" - case Types.AfterAll: return "after all" - default: throw new Error("unreachable") - } - }, + "#tl .tl-test.tl-error > :first-child::before": { + content: "'!'", + }, - get isBeforeAll() { return this._ === Types.BeforeAll }, - get isBeforeEach() { return this._ === Types.BeforeEach }, - get isAfterEach() { return this._ === Types.AfterEach }, - get isAfterAll() { return this._ === Types.AfterAll }, -} + "#tl .tl-test.tl-skip > :first-child::before": { + content: "'−'", + }, -exports.HookError = HookError -function HookError(stage, func, error) { - this._ = stage - this.name = func.name || func.displayName || "" - this.error = error -} -methods(HookError, HookMethods) + "#tl .tl-pre, #tl .tl-diff-header": { + // normalize.css: Correct the inheritance and scaling of font size + // in all browsers + "font-family": "monospace, monospace", + "background": "#f0f0f0", + "white-space": "pre", + "font-size": "0.85em", + }, -exports.Hook = HookReport -function HookReport(path, rootPath, hookError) { - Report.call(this, hookError._) - this.path = path - this.rootPath = rootPath - this.name = hookError.name - this.error = hookError.error -} -methods(HookReport, Report, HookMethods, { - get hookError() { return new HookError(this._, this, this.error) }, -}) + "#tl .tl-pre": { + "min-width": "100%", + "float": "left", + "clear": "left", + }, -},{"../methods":19}],12:[function(require,module,exports){ -(function (global){ -"use strict" + "#tl .tl-line": { + display: "block", + margin: "0 0.25em", + width: "99%", // Because Firefox sucks + }, -var methods = require("../methods") -var peach = require("../util").peach -var Reports = require("./reports") -var Filter = require("./filter") -var Types = Reports.Types + "#tl .tl-diff-header > *": { + padding: "0.25em", + }, -/** - * The tests are laid out in a very data-driven design. With exception of the - * reports, there is minimal object orientation and zero virtual dispatch. - * Here's a quick overview: - * - * - The test handling dispatches based on various attributes the test has. For - * example, roots are known by a circular root reference, and skipped tests - * are known by not having a callback. - * - * - The test evaluation is very procedural. Although it's very highly - * asynchronous, the use of promises linearize the logic, so it reads very - * much like a recursive set of steps. - * - * - The data types are mostly either plain objects or classes with no methods, - * the latter mostly for debugging help. This also avoids most of the - * indirection required to accommodate breaking abstractions, which the API - * methods frequently need to do. - */ + "#tl .tl-diff-header": { + "padding": "0.25em", + "margin-bottom": "0.5em", + "display": "inline-block", + }, -// Prevent Sinon interference when they install their mocks -var setTimeout = global.setTimeout -var clearTimeout = global.clearTimeout -var now = global.Date.now + "#tl .tl-line:first-child, #tl .tl-diff-header ~ .tl-line": { + "padding-top": "0.25em", + }, -/** - * Basic data types - */ -function Result(time, attempt) { - this.time = time - this.caught = attempt.caught - this.value = attempt.caught ? attempt.value : undefined -} + "#tl .tl-line:last-child": { + "padding-bottom": "0.25em", + }, -/** - * Overview of the test properties: - * - * - `methods` - A deprecated reference to the API methods - * - `root` - The root test - * - `reporters` - The list of reporters - * - `current` - A reference to the currently active test - * - `timeout` - The tests's timeout, or 0 if inherited - * - `slow` - The tests's slow threshold - * - `name` - The test's name - * - `index` - The test's index - * - `parent` - The test's parent - * - `callback` - The test's callback - * - `tests` - The test's child tests - * - `beforeAll`, `beforeEach`, `afterEach`, `afterAll` - The test's various - * scheduled hooks - * - * Many of these properties aren't present on initialization to save memory. - */ + "#tl .tl-fail .tl-display": { + margin: "0.5em", + }, -// TODO: remove `test.methods` in 0.4 -function Normal(name, index, parent, callback) { - var child = Object.create(parent.methods) + "#tl .tl-display > *": { + overflow: "auto", + }, - child._ = this - this.methods = child - this.locked = true - this.root = parent.root - this.name = name - this.index = index|0 - this.parent = parent - this.callback = callback - this.isFailable = parent.isFailable - this.attempts = parent.attempts + "#tl .tl-display > :not(:last-child)": { + "margin-bottom": "0.5em", + }, - this.timeout = 0 - this.slow = 0 - this.tests = undefined - this.beforeAll = undefined - this.beforeEach = undefined - this.afterEach = undefined - this.afterAll = undefined - this.reporter = undefined - this.reflect = undefined -} + "#tl .tl-diff-added": { + "color": "#0c0", + "font-weight": "bold", + }, -function Skipped(name, index, parent) { - this.locked = true - this.root = parent.root - this.name = name - this.index = index|0 - this.parent = parent + "#tl .tl-diff-removed": { + "color": "#c00", + "font-weight": "bold", + }, - // Only for reflection. - this.isFailable = parent.isFailable - this.attempts = parent.attempts - this.reporter = undefined - this.reflect = undefined -} + "#tl .tl-stack .tl-line": { + color: "#800", + }, -// TODO: remove `test.methods` in 0.4 -function Root(methods) { - this.locked = false - this.methods = methods - this.reporterIds = [] - this.reporters = [] - this.current = this - this.root = this - this.timeout = 0 - this.slow = 0 - this.attempts = 1 - this.isFailable = false + "#tl .tl-diff::before, #tl .tl-stack::before": { + "font-weight": "normal", + "margin": "0.25em 0.25em 0.25em 0", + "display": "block", + "font-style": "italic", + }, - this.tests = undefined - this.reporter = undefined - this.reflect = undefined - this.beforeAll = undefined - this.beforeEach = undefined - this.afterEach = undefined - this.afterAll = undefined -} + "#tl .tl-diff::before": { + content: "'Diff:'", + }, -function Context(root) { - this.root = root - this.tests = [] - this.isSuccess = true -} + "#tl .tl-stack::before": { + content: "'Stack:'", + }, -/** - * Base tests (i.e. default export, result of `internal.root()`). - */ + "#tl .tl-header": { + "text-align": "right", + }, -exports.createRoot = function (methods) { - return new Root(methods) -} + "#tl .tl-header > *": { + "display": "inline-block", + "text-align": "center", + "padding": "0.5em 0.75em", + "border": "2px solid #00c", + "border-radius": "1em", + "background-color": "transparent", + "margin": "0.25em 0.5em", + }, -/** - * Set up each test type. - */ + "#tl .tl-header > :focus": { + outline: "none", + }, -/** - * A normal test through `t.test()`. - */ + "#tl .tl-run": { + "border-color": "#080", + "background-color": "#0c0", + "color": "white", + "width": "6em", + }, -exports.addNormal = function (parent, name, callback) { - var index = parent.tests != null ? parent.tests.length : 0 - var base = new Normal(name, index, parent, callback) + "#tl .tl-run:hover": { + "background-color": "#8c8", + "color": "white", + }, - if (index) { - parent.tests.push(base) - } else { - parent.tests = [base] - } -} + "#tl .tl-toggle.tl-pass": { + "border-color": "#0c0", + }, -/** - * A skipped test through `t.testSkip()`. - */ -exports.addSkipped = function (parent, name) { - var index = parent.tests != null ? parent.tests.length : 0 - var base = new Skipped(name, index, parent) + "#tl .tl-toggle.tl-fail": { + "border-color": "#c00", + }, - if (index) { - parent.tests.push(base) - } else { - parent.tests = [base] - } -} + "#tl .tl-toggle.tl-skip": { + "border-color": "#08c", + }, -/** - * Clear the tests in place. - */ -exports.clearTests = function (parent) { - parent.tests = null -} + "#tl .tl-toggle.tl-pass.tl-active, #tl .tl-toggle.tl-pass:active": { + "border-color": "#080", + "background-color": "#0c0", + }, -/** - * Execute the tests - */ + "#tl .tl-toggle.tl-fail.tl-active, #tl .tl-toggle.tl-fail:active": { + "border-color": "#800", + "background-color": "#c00", + }, -// TODO: cache and remove these traversals for 0.4. -// Note that a timeout of 0 means to inherit the parent. -function findTimeout(tests) { - for (var i = tests.length - 1; i >= 0; i--) { - if (tests[i].timeout) return tests[i].timeout - } + "#tl .tl-toggle.tl-skip.tl-active, #tl .tl-toggle.tl-skip:active": { + "border-color": "#058", + "background-color": "#08c", + }, - return 2000 // ms - default timeout -} + "#tl .tl-toggle.tl-pass:hover": { + "border-color": "#0c0", + "background-color": "#afa", + }, -// Note that a slowness threshold of 0 means to inherit the parent. -function findSlow(tests) { - for (var i = tests.length - 1; i >= 0; i--) { - if (tests[i].slow) return tests[i].slow - } + "#tl .tl-toggle.tl-fail:hover": { + "border-color": "#c00", + "background-color": "#faa", + }, - return 75 // ms - default slow threshold -} + "#tl .tl-toggle.tl-skip:hover": { + "border-color": "#08c", + "background-color": "#bdf", + }, -function makeSlice(tests, length) { - var ret = new Array(length) + "#tl .tl-report.tl-pass .tl-test:not(.tl-pass)": { + display: "none", + }, - for (var i = 0; i < length; i++) { - ret[i] = {name: tests[i].name, index: tests[i].index} + "#tl .tl-report.tl-fail .tl-test:not(.tl-fail)": { + display: "none", + }, + + "#tl .tl-report.tl-skip .tl-test:not(.tl-skip)": { + display: "none", + }, } - return ret -} + var css = "" -function report(context, type, arg1, arg2) { - function invokeReporter(reporter) { - switch (type) { - case Types.Start: - return reporter(new Reports.Start()) - - case Types.Enter: - return reporter( - new Reports.Enter( - makeSlice(context.tests, context.tests.length), arg1, - findSlow(context.tests))) - - case Types.Leave: - return reporter(new Reports.Leave( - makeSlice(context.tests, context.tests.length))) - - case Types.Pass: - return reporter( - new Reports.Pass( - makeSlice(context.tests, context.tests.length), arg1, - findSlow(context.tests))) - - case Types.Fail: - return reporter( - new Reports.Fail( - makeSlice(context.tests, context.tests.length), arg1, arg2, - findSlow(context.tests), - !!context.root.current.isFailable)) - - case Types.Skip: - return reporter(new Reports.Skip( - makeSlice(context.tests, context.tests.length))) - - case Types.End: - return reporter(new Reports.End()) - - case Types.Error: - return reporter(new Reports.Error(arg1)) - - case Types.Hook: - // Include the last test. This also implicitly sets the end to 0 for - // root tests. - return reporter(new Reports.Hook( - makeSlice(context.tests, context.tests.length), - makeSlice(context.tests, context.tests.indexOf(arg1) + 1), - arg2)) + function appendBase(selector, props) { + css += selector + "{" - default: - throw new TypeError("unreachable") + if (Array.isArray(props)) { + for (var i = 0; i < props.length; i++) { + appendProps(props[i]) + } + } else { + appendProps(props) } - } - - return Promise.resolve() - .then(function () { - if (context.root.reporter == null) return undefined - return invokeReporter(context.root.reporter) - }) - .then(function () { - var reporters = context.root.reporters - - // Two easy cases. - if (reporters.length === 0) return undefined - if (reporters.length === 1) return invokeReporter(reporters[0]) - return Promise.all(reporters.map(invokeReporter)) - }) -} -/** - * Normal tests - */ + css += "}" + } -// PhantomJS and IE don't add the stack until it's thrown. In failing async -// tests, it's already thrown in a sense, so this should be normalized with -// other test types. -var addStack = typeof new Error().stack !== "string" - ? function addStack(e) { - try { - if (e instanceof Error && e.stack == null) throw e - } finally { - return e + function appendProps(props) { + for (var key in props) { + if (hasOwn.call(props, key)) { + if (typeof props[key] === "object") { + appendBase(key, props[key]) + } else { + css += key + ":" + props[key] + ";" + } + } } } - : function (e) { return e } -function getThen(res) { - if (typeof res === "object" || typeof res === "function") { - return res.then - } else { - return undefined + for (var selector in styleObject) { + if (hasOwn.call(styleObject, selector)) { + appendBase(selector, styleObject[selector]) + } } -} - -function AsyncState(context, start, resolve, count) { - this.context = context - this.start = start - this.resolve = resolve - this.count = count - this.timer = undefined -} -var p = Promise.resolve() + return css.concat() // Hint to flatten. +}) -function asyncFinish(state, attempt) { - // Capture immediately. Worst case scenario, it gets thrown away. - var end = now() +module.exports = function () { + if (D.document.head.querySelector("style[data-tl-style]") == null) { + var style = D.document.createElement("style") - if (state.timer) { - clearTimeout.call(global, state.timer) - state.timer = undefined - } + style.type = "text/css" + style.setAttribute("data-tl-style", "") + if (style.styleSheet) { + style.styleSheet.cssText = styles() + } else { + style.appendChild(D.document.createTextNode(styles())) + } - if (attempt.caught && state.count < state.context.root.current.attempts) { - // Don't recurse synchronously, since it may be resolved synchronously - state.resolve(p.then(function () { - return invokeInit(state.context, state.count + 1) - })) - } else { - state.resolve(new Result(end - state.start, attempt)) + D.document.head.appendChild(style) } } -// Avoid creating a closure if possible, in case it doesn't return a thenable. -function invokeInit(context, count) { - var test = context.root.current - var start = now() - var tryBody = try1(test.callback, test.methods, test.methods) - var syncEnd = now() +},{"../util":26,"./inject":15}],15:[function(require,module,exports){ +(function (global){ +"use strict" - // Note: synchronous failures are test failures, not fatal errors. - if (tryBody.caught) { - if (count < test.attempts) return invokeInit(context, count + 1) - return Promise.resolve(new Result(syncEnd - start, tryBody)) - } +/** + * The global injections for the DOM. Mainly for debugging. + */ - var tryThen = try1(getThen, undefined, tryBody.value) +exports.document = global.document +exports.window = global.window - if (tryThen.caught) { - if (count < test.attempts) return invokeInit(context, count + 1) - return Promise.resolve(new Result(syncEnd - start, tryThen)) - } +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - if (typeof tryThen.value !== "function") { - return Promise.resolve(new Result(syncEnd - start, tryThen)) - } +},{}],16:[function(require,module,exports){ +(function (global){ +"use strict" - return new Promise(function (resolve) { - var state = new AsyncState(context, start, resolve, count) - var result = try2(tryThen.value, tryBody.value, - function () { - if (state == null) return - asyncFinish(state, tryPass()) - state = undefined - }, - function (e) { - if (state == null) return - asyncFinish(state, tryFail(addStack(e))) - state = undefined - }) +var Util = require("../util") +var D = require("./inject") +var now = Date.now // Avoid Sinon's mock +var hasOwn = Object.prototype.hasOwnProperty - if (state == null) return - if (result.caught) { - asyncFinish(state, result) - state = undefined - return - } +/** + * Test runner and script loader + */ - // Set the timeout *after* initialization. The timeout will likely be - // specified during initialization. - var maxTimeout = findTimeout(context.tests) +function uncached(file) { + if (file.indexOf("?") < 0) { + return file + "?loaded=" + now() + } else { + return file + "&loaded=" + now() + } +} - // Setting a timeout is pointless if it's infinite. - if (maxTimeout !== Infinity) { - state.timer = setTimeout.call(global, function () { - if (state == null) return - asyncFinish(state, tryFail(addStack( - new Error("Timeout of " + maxTimeout + " reached")))) - state = undefined - }, maxTimeout) +function loadScript(file, timeout) { + return new Promise(function (resolve, reject) { + var script = D.document.createElement("script") + var timer = global.setTimeout(function () { + clear() + reject(new Error("Timeout exceeded loading '" + file + "'")) + }, timeout) + + function clear(ev) { + if (ev != null) ev.preventDefault() + if (ev != null) ev.stopPropagation() + global.clearTimeout(timer) + script.onload = undefined + script.onerror = undefined + D.document.head.removeChild(script) } - }) -} -function ErrorWrap(test, error) { - this.test = test - this.error = error -} -methods(ErrorWrap, Error, {name: "ErrorWrap"}) + script.src = uncached(file) + script.async = true + script.defer = true + script.onload = function (ev) { + clear(ev) + resolve() + } -function invokeHook(test, list, stage) { - if (list == null) return Promise.resolve() - return peach(list, function (hook) { - try { - return hook() - } catch (e) { - throw new ErrorWrap(test, new Reports.HookError(stage, hook, e)) + script.onerror = function (ev) { + clear(ev) + reject(ev) } + + D.document.head.appendChild(script) }) } -function invokeBeforeEach(test) { - if (test.root === test) { - return invokeHook(test, test.beforeEach, Types.BeforeEach) - } else { - return invokeBeforeEach(test.parent).then(function () { - return invokeHook(test, test.beforeEach, Types.BeforeEach) - }) +function tryDelete(key) { + try { + delete global[key] + } catch (_) { + // ignore } } -function invokeAfterEach(test) { - if (test.root === test) { - return invokeHook(test, test.afterEach, Types.AfterEach) - } else { - return invokeHook(test, test.afterEach, Types.AfterEach) - .then(function () { return invokeAfterEach(test.parent) }) - } +function descriptorChanged(a, b) { + // Note: if the descriptor was removed, it would've been deleted, anyways. + if (a == null) return false + if (a.configurable !== b.configurable) return true + if (a.enumerable !== b.enumerable) return true + if (a.writable !== b.writable) return true + if (a.get !== b.get) return true + if (a.set !== b.set) return true + if (a.value !== b.value) return true + return false } -/** - * This checks if the test was whitelisted in a `t.only()` call, or for - * convenience, returns `true` if `t.only()` was never called. - */ -function isOnly(test) { - var path = [] - - while (test.parent != null && test.only == null) { - path.push(test.name) - test = test.parent - } +// These fire deprecation warnings, and thus should be avoided. +var blacklist = Object.freeze({ + webkitStorageInfo: true, + webkitIndexedDB: true, +}) - // If there isn't any `only` active, then let's skip the check and return - // `true` for convenience. - if (test.only == null) return true - return Filter.test(test.only, path) -} +function findGlobals() { + var found = Object.keys(global) + var globals = Object.create(null) -function runChildTests(test, context) { - if (test.tests == null) return undefined + for (var i = 0; i < found.length; i++) { + var key = found[i] - function leave() { - test.root.current = test - context.tests.pop() + if (!hasOwn.call(blacklist, key)) { + globals[key] = Object.getOwnPropertyDescriptor(global, key) + } } - function runChild(child) { - test.root.current = child - context.tests.push(child) + return globals +} - return invokeBeforeEach(test) - .then(function () { return runNormalChild(child, context) }) - .then(function () { return invokeAfterEach(test) }) - .catch(function (e) { - if (!(e instanceof ErrorWrap)) throw e - return report(context, Types.Hook, e.test, e.error) - }) - .then(leave, function (e) { leave(); throw e }) +module.exports = function (opts, state) { + if (state.locked) { + return Promise.reject(new Error( + "The test suite must not be run after the view has been detached." + )) } - var ran = false + if (state.currentPromise != null) return state.currentPromise - return peach(test.tests, function (child) { - // Only skipped tests have no callback - if (child.callback == null) { - test.root.current = child - context.tests.push(child) + opts.thallium.clearTests() - return report(context, Types.Skip) - .then(leave, function (e) { leave(); throw e }) - } else if (!isOnly(child)) { - return Promise.resolve() - } else if (ran) { - return runChild(child) - } else { - ran = true - return invokeHook(test, test.beforeAll, Types.BeforeAll) - .then(function () { return runChild(child) }) - } - }) - .then(function () { - return ran ? invokeHook(test, test.afterAll, Types.AfterAll) : undefined - }) -} + // Detect and remove globals created by loaded scripts. + var globals = findGlobals() -function clearChildren(test) { - if (test.tests == null) return - for (var i = 0; i < test.tests.length; i++) { - test.tests[i].tests = undefined - } -} + function cleanup() { + var found = Object.keys(global) -function runNormalChild(test, context) { - test.locked = false + for (var i = 0; i < found.length; i++) { + var key = found[i] - return invokeInit(context, 1) - .then( - function (result) { test.locked = true; return result }, - function (error) { test.locked = true; throw error }) - .then(function (result) { - if (result.caught) { - if (!test.isFailable) context.isSuccess = false - return report(context, Types.Fail, result.value, result.time) - } else if (test.tests != null) { - // Report this as if it was a parent test if it's passing and has - // children. - return report(context, Types.Enter, result.time) - .then(function () { return runChildTests(test, context) }) - .then(function () { return report(context, Types.Leave) }) - .catch(function (e) { - if (!(e instanceof ErrorWrap)) throw e - return report(context, Types.Leave).then(function () { - return report(context, Types.Hook, e.test, e.error) - }) - }) - } else { - return report(context, Types.Pass, result.time) + if (!hasOwn.call(globals, key)) { + tryDelete(key) + } else if (descriptorChanged( + Object.getOwnPropertyDescriptor(global, key), + globals[key] + )) { + tryDelete(key) + } } - }) - .then( - function () { clearChildren(test) }, - function (e) { clearChildren(test); throw e }) -} -/** - * This runs the root test and returns a promise resolved when it's done. - */ -exports.runTest = function (root, opts) { - var context = new Context(root, opts) + state.currentPromise = undefined + } - root.locked = true - return report(context, Types.Start) - .then(function () { return runChildTests(root, context) }) - .catch(function (e) { - if (!(e instanceof ErrorWrap)) throw e - return report(context, Types.Hook, e.test, e.error) + return state.currentPromise = Promise.resolve() + .then(function () { + state.pass.textContent = "0" + state.fail.textContent = "0" + state.skip.textContent = "0" + return opts.preload() }) - .then(function () { return report(context, Types.End) }) - // Tell the reporter something happened. Otherwise, it'll have to wrap this - // method in a plugin, which shouldn't be necessary. + .then(function () { + return Util.peach(opts.files, function (file) { + return loadScript(file, opts.timeout) + }) + }) + .then(function () { return opts.prerun() }) + .then(function () { return opts.thallium.run() }) + .then(function () { return opts.postrun() }) .catch(function (e) { - return report(context, Types.Error, e).then(function () { throw e }) + return Promise.resolve(opts.error(e)).then(function () { throw e }) }) .then( - function () { - clearChildren(root) - root.locked = false - return { - isSuccess: context.isSuccess, - } - }, - function (e) { - clearChildren(root) - root.locked = false - throw e - }) -} - -// Help optimize for inefficient exception handling in V8 - -function tryPass(value) { - return {caught: false, value: value} -} - -function tryFail(e) { - return {caught: true, value: e} -} - -function try1(f, inst, arg0) { - try { - return tryPass(f.call(inst, arg0)) - } catch (e) { - return tryFail(e) - } -} - -function try2(f, inst, arg0, arg1) { - try { - return tryPass(f.call(inst, arg0, arg1)) - } catch (e) { - return tryFail(e) - } + function () { cleanup() }, + function (e) { cleanup(); throw e }) } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../methods":19,"../util":27,"./filter":10,"./reports":11}],13:[function(require,module,exports){ -"use strict" - -/** - * The DOM reporter and loader entry point. See the README.md for more details. - */ - -var initialize = require("./initialize") -// var t = require("../../index") -// var assert = require("../../assert") - -exports.create = function (opts) { - if (opts == null) return initialize({}) - if (Array.isArray(opts)) return initialize({files: opts}) - if (typeof opts === "object") return initialize(opts) - throw new TypeError("`opts` must be an object or array of files if passed") -} - -// Currently broken, because this isn't autoloaded yet. -// exports.autoload = function (script) { -// var files = script.getAttribute("data-files") -// -// if (!files) return -// -// function set(opts, attr, transform) { -// var value = script.getAttribute("data-" + attr) -// -// if (value) opts[attr] = transform(value) -// } -// -// var opts = {files: files.trim().split(/\s+/g)} -// -// set(opts, "timeout", Number) -// set(opts, "preload", Function) -// set(opts, "prerun", Function) -// set(opts, "postrun", Function) -// set(opts, "error", function (attr) { -// return new Function("err", attr) // eslint-disable-line -// }) -// -// // Convenience. -// global.t = t -// global.assert = assert -// -// if (global.document.readyState !== "loading") { -// initialize(opts).run() -// } else { -// global.document.addEventListener("DOMContentLoaded", function () { -// initialize(opts).run() -// }) -// } -// } - -},{"./initialize":14}],14:[function(require,module,exports){ +},{"../util":26,"./inject":15}],17:[function(require,module,exports){ +(function (global){ "use strict" -/** - * The reporter and test initialization sequence, and script loading. This - * doesn't understand anything view-wise. - */ - -var defaultT = require("../../index") +var diff = require("diff") var R = require("../reporter") var D = require("./inject") var runTests = require("./run-tests") -var injectStyles = require("./inject-styles") -var View = require("./view") -var methods = require("../methods") - -function Tree(name) { - this.name = name - this.status = R.Status.Unknown - this.node = null - this.children = Object.create(null) -} - -var reporter = R.on("dom", { - accepts: [], - create: function (opts, methods) { - var reporter = new R.Reporter(Tree, undefined, methods) - - reporter.opts = opts - return reporter - }, - - // Give the browser a chance to repaint before continuing (microtasks - // normally block rendering). - after: function () { - return new Promise(View.nextFrame) - }, - - report: function (_, report) { - return View.report(_, report) - }, -}) +var inspect = require("clean-assert-util").inspect -function noop() {} +/** + * View logic + */ -function setDefaultsChecked(opts) { - if (opts.title == null) opts.title = "Thallium tests" - if (opts.timeout == null) opts.timeout = 5000 - if (opts.files == null) opts.files = [] - if (opts.preload == null) opts.preload = noop - if (opts.prerun == null) opts.prerun = noop - if (opts.postrun == null) opts.postrun = noop - if (opts.error == null) opts.error = noop - if (opts.thallium == null) opts.thallium = defaultT +function t(text) { + return D.document.createTextNode(text) +} - if (typeof opts.title !== "string") { - throw new TypeError("`opts.title` must be a string if passed") - } +function h(type, attrs, children) { + var parts = type.split(/\s+/g) - if (typeof opts.timeout !== "number") { - throw new TypeError("`opts.timeout` must be a number if passed") + if (Array.isArray(attrs)) { + children = attrs + attrs = undefined } - if (!Array.isArray(opts.files)) { - throw new TypeError("`opts.files` must be an array if passed") - } + if (attrs == null) attrs = {} + if (children == null) children = [] - if (typeof opts.preload !== "function") { - throw new TypeError("`opts.preload` must be a function if passed") - } + type = parts[0] + attrs.className = parts.slice(1).join(" ") - if (typeof opts.prerun !== "function") { - throw new TypeError("`opts.prerun` must be a function if passed") - } + var elem = D.document.createElement(type) - if (typeof opts.postrun !== "function") { - throw new TypeError("`opts.postrun` must be a function if passed") - } + Object.keys(attrs).forEach(function (attr) { + elem[attr] = attrs[attr] + }) - if (typeof opts.error !== "function") { - throw new TypeError("`opts.error` must be a function if passed") - } + children.forEach(function (child) { + if (child != null) elem.appendChild(child) + }) - if (typeof opts.thallium !== "object") { - throw new TypeError( - "`opts.thallium` must be a Thallium instance if passed") - } + return elem } -function onReady(init) { - if (D.document.body != null) return Promise.resolve(init()) - return new Promise(function (resolve) { - D.document.addEventListener("DOMContentLoaded", function () { - resolve(init()) - }, false) - }) -} +function unifiedDiff(err) { + var actual = inspect(err.actual) + var expected = inspect(err.expected) + var msg = diff.createPatch("string", actual, expected) + .split(/\r?\n|\r/g).slice(4) + .filter(function (line) { return !/^\@\@|^\\ No newline/.test(line) }) + var end = msg.length -function DOM(opts) { - this._opts = opts - this._destroyPromise = undefined - this._data = onReady(function () { - setDefaultsChecked(opts) - if (!D.document.title) D.document.title = opts.title - injectStyles() - var data = View.init(opts) + while (end !== 0 && /^\s*$/g.test(msg[end - 1])) end-- + return h("div tl-diff", [ + h("div tl-diff-header", [ + h("span tl-diff-added", [t("+ expected")]), + h("span tl-diff-removed", [t("- actual")]), + ]), + h("div tl-pre", !end + ? [h("span tl-line tl-diff-added", [t(" (none)")])] + : msg.slice(0, end) + .map(function (line) { return line.trimRight() }) + .map(function (line) { + if (line[0] === "+") { + return h("span tl-line tl-diff-added", [t(line)]) + } else if (line[0] === "-") { + return h("span tl-line tl-diff-removed", [t(line)]) + } else { + return h("span tl-line tl-diff-none", [t(line)]) + } + }) + ), + ]) +} - opts.thallium.reporter(reporter, data.state) - return data - }) +function toLines(str) { + return h("div tl-pre", str.split(/\r?\n|\r/g).map(function (line) { + return h("span tl-line", [t(line.trimRight())]) + })) } -methods(DOM, { - run: function () { - if (this._destroyPromise != null) { - return Promise.reject(new Error( - "The test suite must not be run after the view has been " + - "detached." - )) - } +function formatError(e, showDiff) { + var stack = R.readStack(e) - var opts = this._opts + return h("div tl-display", [ + h("div tl-message", [toLines(e.name + ": " + e.message)]), + showDiff ? unifiedDiff(e) : undefined, + stack ? h("div tl-stack", [toLines(stack)]) : undefined, + ]) +} - return this._data.then(function (data) { - return runTests(opts, data.state) - }) - }, +function showTest(_, report, className, child) { + var end = report.path.length - 1 + var name = report.path[end].name + var parent = _.get(report.path, end) + var speed = R.speed(report) - detach: function () { - if (this._destroyPromise != null) return this._destroyPromise - var self = this + if (speed === "fast") { + parent.node.appendChild(h("li " + className + " tl-fast", [ + h("h2", [t(name)]), + child, + ])) + } else { + parent.node.appendChild(h("li " + className + " tl-" + speed, [ + h("h2", [ + t(name + " ("), + h("span tl-duration", [t(R.formatTime(report.duration))]), + t(")"), + ]), + child, + ])) + } - return this._destroyPromise = self._data.then(function (data) { - data.state.locked = true - if (data.state.currentPromise == null) return data - return data.state.currentPromise.then(function () { return data }) - }) - .then(function (data) { - self._opts = undefined - self._data = self._destroyPromise + _.opts.duration.textContent = R.formatTime(_.duration) +} - while (data.root.firstChild) { - data.root.removeChild(data.root.firstChild) - } - }) - }, -}) +function showSkip(_, report) { + var end = report.path.length - 1 + var name = report.path[end].name + var parent = _.get(report.path, end) -module.exports = function (opts) { - return new DOM(opts) + parent.node.appendChild(h("li tl-test tl-skip", [ + h("h2", [t(name)]), + ])) } -},{"../../index":4,"../methods":19,"../reporter":22,"./inject":16,"./inject-styles":15,"./run-tests":17,"./view":18}],15:[function(require,module,exports){ -"use strict" - -var Util = require("../util") -var D = require("./inject") +exports.nextFrame = nextFrame +function nextFrame(func) { + if (D.window.requestAnimationFrame) { + D.window.requestAnimationFrame(func) + } else { + global.setTimeout(func, 0) + } +} -/** - * The reporter stylesheet. Here's the format: - * - * // Single item - * ".selector": { - * // props... - * } - * - * // Duplicate entries - * ".selector": { - * "prop": [ - * // values... - * ], - * } - * - * // Duplicate selectors - * ".selector": [ - * // values... - * ] - * - * // Media query - * "@media screen": { - * // selectors... - * } - * - * Note that CSS strings *must* be quoted inside the value. - */ +exports.report = function (_, report) { + if (report.isStart) { + return new Promise(function (resolve) { + // Clear the element first, just in case. + while (_.opts.report.firstChild) { + _.opts.report.removeChild(_.opts.report.firstChild) + } -var styles = Util.lazy(function () { - var hasOwn = Object.prototype.hasOwnProperty + // Defer the next frame, so the current changes can be sent, in case + // it's clearing old test results from a large suite. (Chrome does + // better batching this way, at least.) + nextFrame(function () { + _.get(undefined, 0).node = _.opts.report + _.opts.duration.textContent = R.formatTime(0) + _.opts.pass.textContent = "0" + _.opts.fail.textContent = "0" + _.opts.skip.textContent = "0" + resolve() + }) + }) + } else if (report.isEnter) { + var child = h("ul") - /** - * Partially taken and adapted from normalize.css (licensed under the MIT - * License). - * https://github.com/necolas/normalize.css - */ - var styleObject = { - "#tl": { - "font-family": "sans-serif", - "line-height": "1.15", - "-ms-text-size-adjust": "100%", - "-webkit-text-size-adjust": "100%", - }, + _.get(report.path).node = child + showTest(_, report, "tl-suite tl-pass", child) + _.opts.pass.textContent = _.pass + } else if (report.isPass) { + showTest(_, report, "tl-test tl-pass") + _.opts.pass.textContent = _.pass + } else if (report.isFail) { + showTest(_, report, "tl-test tl-fail", formatError(report.error, + report.error.name === "AssertionError" && + report.error.showDiff !== false)) + _.opts.fail.textContent = _.fail + } else if (report.isSkip) { + showSkip(_, report, "tl-test tl-skip") + _.opts.skip.textContent = _.skip + } else if (report.isError) { + _.opts.report.appendChild(h("li tl-error", [ + h("h2", [t("Internal error")]), + formatError(report.error, false), + ])) + } - "#tl button": { - "font-family": "sans-serif", - "line-height": "1.15", - "overflow": "visible", - "font-size": "100%", - "margin": "0", - "text-transform": "none", - "-webkit-appearance": "button", - }, + return undefined +} - "#tl h1": { - "font-size": "2em", - "margin": "0.67em 0", - }, +function makeCounter(state, child, label, name) { + return h("button tl-toggle " + name, { + onclick: function (ev) { + ev.preventDefault() + ev.stopPropagation() - "#tl a": { - "background-color": "transparent", - "-webkit-text-decoration-skip": "objects", - }, + if (/\btl-active\b/.test(this.className)) { + this.className = this.className + .replace(/\btl-active\b/g, "") + .replace(/\s+/g, " ") + .trim() + state.report.className = state.report.className + .replace(new RegExp("\\b" + name + "\\b", "g"), "") + .replace(/\s+/g, " ") + .trim() + state.active = undefined + } else { + if (state.active != null) { + state.active.className = state.active.className + .replace(/\btl-active\b/g, "") + .replace(/\s+/g, " ") + .trim() + } - "#tl a:active, #tl a:hover": { - "outline-width": "0", + state.active = this + this.className += " tl-active" + state.report.className = state.report.className + .replace(/\btl-(pass|fail|skip)\b/g, "") + .replace(/\s+/g, " ") + .trim() + " " + name + } }, + }, [t(label), child]) +} - "#tl button::-moz-focus-inner": { - "border-style": "none", - "padding": "0", - }, +exports.init = function (opts) { + var state = { + currentPromise: undefined, + locked: false, + duration: h("em", [t(R.formatTime(0))]), + pass: h("em", [t("0")]), + fail: h("em", [t("0")]), + skip: h("em", [t("0")]), + report: h("ul tl-report"), + active: undefined, + } - "#tl button:-moz-focusring": { - outline: "1px dotted ButtonText", - }, + var header = h("div tl-header", [ + h("div tl-duration", [t("Duration: "), state.duration]), + makeCounter(state, state.pass, "Passes: ", "tl-pass"), + makeCounter(state, state.fail, "Failures: ", "tl-fail"), + makeCounter(state, state.skip, "Skipped: ", "tl-skip"), + h("button tl-run", { + onclick: function (ev) { + ev.preventDefault() + ev.stopPropagation() + runTests(opts, state) + }, + }, [t("Run")]), + ]) - /** - * Base styles. Note that this CSS is designed to intentionally override - * most things that could propagate. - */ - "#tl *": [ - {"text-align": "left"}, - {"text-align": "start"}, - ], + var root = D.document.getElementById("tl") - "#tl .tl-report, #tl .tl-report ul": { - "list-style-type": "none", - }, + if (root == null) { + D.document.body.appendChild(root = h("div", {id: "tl"}, [ + header, + state.report, + ])) + } else { + // Clear the element first, just in case. + while (root.firstChild) root.removeChild(root.firstChild) + root.appendChild(header) + root.appendChild(state.report) + } - "#tl li ~ .tl-suite": { - "padding-top": "1em", - }, + return { + root: root, + state: state, + } +} - "#tl .tl-suite > h2": { - "color": "black", - "font-size": "1.5em", - "font-weight": "bold", - "margin-bottom": "0.5em", - }, +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - "#tl .tl-suite .tl-suite > h2": { - "font-size": "1.2em", - "margin-bottom": "0.3em", - }, +},{"../reporter":21,"./inject":15,"./run-tests":16,"clean-assert-util":32,"diff":51}],18:[function(require,module,exports){ +"use strict" - "#tl .tl-suite .tl-suite .tl-suite > h2": { - "font-size": "1.2em", - "margin-bottom": "0.2em", - "font-weight": "normal", - }, +module.exports = function (Base, Super) { + var start = 2 - "#tl .tl-test > h2": { - "color": "black", - "font-size": "1em", - "font-weight": "normal", - "margin": "0", - }, + if (typeof Super === "function") { + Base.prototype = Object.create(Super.prototype) + Object.defineProperty(Base.prototype, "constructor", { + configurable: true, + writable: true, + enumerable: false, + value: Base, + }) + } else { + start = 1 + } - "#tl .tl-test > :first-child::before": { - "display": "inline-block", - "font-weight": "bold", - "width": "1.2em", - "text-align": "center", - "font-family": "sans-serif", - "text-shadow": "0 3px 2px #969696", - }, + for (var i = start; i < arguments.length; i++) { + var methods = arguments[i] - "#tl .tl-test.tl-fail > h2, #tl .tl-test.tl-error > h2": { - color: "#c00", - }, + if (methods != null) { + var keys = Object.keys(methods) - "#tl .tl-test.tl-skip > h2": { - color: "#08c", - }, + for (var k = 0; k < keys.length; k++) { + var key = keys[k] + var desc = Object.getOwnPropertyDescriptor(methods, key) - "#tl .tl-test.tl-pass > :first-child::before": { - content: "'✓'", - color: "#0c0", - }, + desc.enumerable = false + Object.defineProperty(Base.prototype, key, desc) + } + } + } +} - "#tl .tl-test.tl-fail > :first-child::before": { - content: "'✖'", - }, +},{}],19:[function(require,module,exports){ +(function (global){ +"use strict" - "#tl .tl-test.tl-error > :first-child::before": { - content: "'!'", - }, +/** + * This contains the browser console stuff. + */ - "#tl .tl-test.tl-skip > :first-child::before": { - content: "'−'", - }, +exports.Symbols = Object.freeze({ + Pass: "✓", + Fail: "✖", + Dot: "․", + DotFail: "!", +}) - "#tl .tl-pre, #tl .tl-diff-header": { - // normalize.css: Correct the inheritance and scaling of font size - // in all browsers - "font-family": "monospace, monospace", - "background": "#f0f0f0", - "white-space": "pre", - "font-size": "0.85em", - }, +exports.windowWidth = 75 +exports.newline = "\n" - "#tl .tl-pre": { - "min-width": "100%", - "float": "left", - "clear": "left", - }, +// Color support is unforced and unsupported, since you can only specify +// line-by-line colors via CSS, and even that isn't very portable. +exports.colorSupport = 0 - "#tl .tl-line": { - display: "block", - margin: "0 0.25em", - width: "99%", // Because Firefox sucks - }, +/** + * Since browsers don't have unbuffered output, this kind of simulates it. + */ - "#tl .tl-diff-header > *": { - padding: "0.25em", - }, +var acc = "" - "#tl .tl-diff-header": { - "padding": "0.25em", - "margin-bottom": "0.5em", - "display": "inline-block", - }, +exports.defaultOpts = { + write: function (str) { + acc += str - "#tl .tl-line:first-child, #tl .tl-diff-header ~ .tl-line": { - "padding-top": "0.25em", - }, + var index = str.indexOf("\n") - "#tl .tl-line:last-child": { - "padding-bottom": "0.25em", - }, + if (index >= 0) { + var lines = str.split("\n") - "#tl .tl-fail .tl-display": { - margin: "0.5em", - }, + acc = lines.pop() - "#tl .tl-display > *": { - overflow: "auto", - }, + for (var i = 0; i < lines.length; i++) { + global.console.log(lines[i]) + } + } + }, - "#tl .tl-display > :not(:last-child)": { - "margin-bottom": "0.5em", - }, + reset: function () { + if (acc !== "") { + global.console.log(acc) + acc = "" + } + }, +} - "#tl .tl-diff-added": { - "color": "#0c0", - "font-weight": "bold", - }, +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - "#tl .tl-diff-removed": { - "color": "#c00", - "font-weight": "bold", - }, +},{}],20:[function(require,module,exports){ +"use strict" - "#tl .tl-stack .tl-line": { - color: "#800", - }, +var diff = require("diff") - "#tl .tl-diff::before, #tl .tl-stack::before": { - "font-weight": "normal", - "margin": "0.25em 0.25em 0.25em 0", - "display": "block", - "font-style": "italic", - }, +var methods = require("../methods") +var inspect = require("clean-assert-util").inspect +var peach = require("../util").peach +var Reporter = require("./reporter") +var Util = require("./util") +var Settings = require("../settings") - "#tl .tl-diff::before": { - content: "'Diff:'", - }, - - "#tl .tl-stack::before": { - content: "'Stack:'", - }, - - "#tl .tl-header": { - "text-align": "right", - }, - - "#tl .tl-header > *": { - "display": "inline-block", - "text-align": "center", - "padding": "0.5em 0.75em", - "border": "2px solid #00c", - "border-radius": "1em", - "background-color": "transparent", - "margin": "0.25em 0.5em", - }, - - "#tl .tl-header > :focus": { - outline: "none", - }, +function printTime(_, p, str) { + if (!_.timePrinted) { + _.timePrinted = true + str += Util.color("light", " (" + Util.formatTime(_.duration) + ")") + } - "#tl .tl-run": { - "border-color": "#080", - "background-color": "#0c0", - "color": "white", - "width": "6em", - }, + return p.then(function () { return _.print(str) }) +} - "#tl .tl-run:hover": { - "background-color": "#8c8", - "color": "white", - }, +function unifiedDiff(err) { + var actual = inspect(err.actual) + var expected = inspect(err.expected) + var msg = diff.createPatch("string", actual, expected) + var header = Settings.newline() + + Util.color("diff added", "+ expected") + " " + + Util.color("diff removed", "- actual") + + Settings.newline() + Settings.newline() - "#tl .tl-toggle.tl-pass": { - "border-color": "#0c0", - }, + return header + msg.split(/\r?\n|\r/g).slice(4) + .filter(function (line) { return !/^\@\@|^\\ No newline/.test(line) }) + .map(function (line) { + if (line[0] === "+") return Util.color("diff added", line.trimRight()) + if (line[0] === "-") return Util.color("diff removed", line.trimRight()) + return line.trimRight() + }) + .join(Settings.newline()) +} - "#tl .tl-toggle.tl-fail": { - "border-color": "#c00", - }, +function formatFail(str) { + return str.trimRight() + .split(/\r?\n|\r/g) + .map(function (line) { return Util.color("fail", line.trimRight()) }) + .join(Settings.newline()) +} - "#tl .tl-toggle.tl-skip": { - "border-color": "#08c", - }, +function getDiffStack(e) { + var description = formatFail(e.name + ": " + e.message) - "#tl .tl-toggle.tl-pass.tl-active, #tl .tl-toggle.tl-pass:active": { - "border-color": "#080", - "background-color": "#0c0", - }, + if (e.name === "AssertionError" && e.showDiff !== false) { + description += Settings.newline() + unifiedDiff(e) + } - "#tl .tl-toggle.tl-fail.tl-active, #tl .tl-toggle.tl-fail:active": { - "border-color": "#800", - "background-color": "#c00", - }, + var stripped = formatFail(Util.readStack(e)) - "#tl .tl-toggle.tl-skip.tl-active, #tl .tl-toggle.tl-skip:active": { - "border-color": "#058", - "background-color": "#08c", - }, + if (stripped === "") return description + return description + Settings.newline() + stripped +} - "#tl .tl-toggle.tl-pass:hover": { - "border-color": "#0c0", - "background-color": "#afa", - }, +function inspectTrimmed(object) { + return inspect(object).trimRight() + .split(/\r?\n|\r/g) + .map(function (line) { return line.trimRight() }) + .join(Settings.newline()) +} - "#tl .tl-toggle.tl-fail:hover": { - "border-color": "#c00", - "background-color": "#faa", - }, +function printFailList(_, err) { + var str = err instanceof Error ? getDiffStack(err) : inspectTrimmed(err) + var parts = str.split(/\r?\n/g) - "#tl .tl-toggle.tl-skip:hover": { - "border-color": "#08c", - "background-color": "#bdf", - }, + return _.print(" " + parts[0]).then(function () { + return peach(parts.slice(1), function (part) { + return _.print(part ? " " + part : "") + }) + }) +} - "#tl .tl-report.tl-pass .tl-test:not(.tl-pass)": { - display: "none", - }, +module.exports = function (opts, methods) { + return new ConsoleReporter(opts, methods) +} - "#tl .tl-report.tl-fail .tl-test:not(.tl-fail)": { - display: "none", - }, +/** + * Base class for most console reporters. + * + * Note: printing is asynchronous, because otherwise, if enough errors exist, + * Node will eventually start dropping lines sent to its buffer, especially when + * stack traces get involved. If Thallium's output is redirected, that can be a + * big problem for consumers, as they only have part of the output, and won't be + * able to see all the errors later. Also, if console warnings come up en-masse, + * that would also contribute. So, we have to wait for each line to flush before + * we can continue, so the full output makes its way to the console. + * + * Some test frameworks like Tape miss this, though. + * + * @param {Object} opts The options for the reporter. + * @param {Function} opts.write The unbufferred writer for the reporter. + * @param {Function} opts.reset A reset function for the printer + writer. + * @param {String[]} accepts The options accepted. + * @param {Function} init The init function for the subclass reporter's + * isolated state (created by factory). + */ +function ConsoleReporter(opts, methods) { + Reporter.call(this, Util.Tree, opts, methods, true) - "#tl .tl-report.tl-skip .tl-test:not(.tl-skip)": { - display: "none", - }, + if (!Util.Colors.forced() && methods.accepts.indexOf("color") >= 0) { + this.opts.color = opts.color } - var css = "" + Util.defaultify(this, opts, "write") + this.reset() +} - function appendBase(selector, props) { - css += selector + "{" +methods(ConsoleReporter, Reporter, { + print: function (str) { + if (str == null) str = "" + return Promise.resolve(this.opts.write(str + "\n")) + }, - if (Array.isArray(props)) { - for (var i = 0; i < props.length; i++) { - appendProps(props[i]) - } + write: function (str) { + if (str != null) { + return Promise.resolve(this.opts.write(str)) } else { - appendProps(props) + return Promise.resolve() } + }, - css += "}" - } - - function appendProps(props) { - for (var key in props) { - if (hasOwn.call(props, key)) { - if (typeof props[key] === "object") { - appendBase(key, props[key]) - } else { - css += key + ":" + props[key] + ";" - } - } - } - } + printResults: function () { + var self = this - for (var selector in styleObject) { - if (hasOwn.call(styleObject, selector)) { - appendBase(selector, styleObject[selector]) + if (!this.tests && !this.skip) { + return this.print( + Util.color("plain", " 0 tests") + + Util.color("light", " (0ms)")) + .then(function () { return self.print() }) } - } - return css.concat() // Hint to flatten. -}) + return this.print().then(function () { + var p = Promise.resolve() -module.exports = function () { - if (D.document.head.querySelector("style[data-tl-style]") == null) { - var style = D.document.createElement("style") + if (self.pass) { + p = printTime(self, p, + Util.color("bright pass", " ") + + Util.color("green", self.pass + " passing")) + } - style.type = "text/css" - style.setAttribute("data-tl-style", "") - if (style.styleSheet) { - style.styleSheet.cssText = styles() - } else { - style.appendChild(D.document.createTextNode(styles())) - } + if (self.skip) { + p = printTime(self, p, + Util.color("skip", " " + self.skip + " skipped")) + } - D.document.head.appendChild(style) - } -} + if (self.fail) { + p = printTime(self, p, + Util.color("bright fail", " ") + + Util.color("fail", self.fail + " failing")) + } -},{"../util":27,"./inject":16}],16:[function(require,module,exports){ -(function (global){ -"use strict" + return p + }) + .then(function () { return self.print() }) + .then(function () { + return peach(self.errors, function (report, i) { + var name = i + 1 + ") " + Util.joinPath(report) + + Util.formatRest(report) -/** - * The global injections for the DOM. Mainly for debugging. - */ + return self.print(" " + Util.color("plain", name + ":")) + .then(function () { + return printFailList(self, report.error) + }) + .then(function () { return self.print() }) + }) + }) + }, -exports.document = global.document -exports.window = global.window + printError: function (report) { + var self = this + var lines = report.error instanceof Error + ? Util.getStack(report.error) + : inspectTrimmed(report.error) -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + return this.print().then(function () { + return peach(lines.split(/\r?\n/g), function (line) { + return self.print(line) + }) + }) + }, +}) -},{}],17:[function(require,module,exports){ -(function (global){ +},{"../methods":18,"../settings":25,"../util":26,"./reporter":23,"./util":24,"clean-assert-util":32,"diff":51}],21:[function(require,module,exports){ "use strict" -var Util = require("../util") -var D = require("./inject") -var now = Date.now // Avoid Sinon's mock -var hasOwn = Object.prototype.hasOwnProperty - -/** - * Test runner and script loader - */ - -function uncached(file) { - if (file.indexOf("?") < 0) { - return file + "?loaded=" + now() - } else { - return file + "&loaded=" + now() - } -} - -function loadScript(file, timeout) { - return new Promise(function (resolve, reject) { - var script = D.document.createElement("script") - var timer = global.setTimeout(function () { - clear() - reject(new Error("Timeout exceeded loading '" + file + "'")) - }, timeout) - - function clear(ev) { - if (ev != null) ev.preventDefault() - if (ev != null) ev.stopPropagation() - global.clearTimeout(timer) - script.onload = undefined - script.onerror = undefined - D.document.head.removeChild(script) - } +var Util = require("./util") - script.src = uncached(file) - script.async = true - script.defer = true - script.onload = function (ev) { - clear(ev) - resolve() - } +exports.on = require("./on") +exports.consoleReporter = require("./console-reporter") +exports.Reporter = require("./reporter") +exports.color = Util.color +exports.Colors = Util.Colors +exports.formatRest = Util.formatRest +exports.formatTime = Util.formatTime +exports.getStack = Util.getStack +exports.joinPath = Util.joinPath +exports.newline = Util.newline +exports.readStack = Util.readStack +exports.setColor = Util.setColor +exports.speed = Util.speed +exports.Status = Util.Status +exports.symbols = Util.symbols +exports.unsetColor = Util.unsetColor +exports.windowWidth = Util.windowWidth - script.onerror = function (ev) { - clear(ev) - reject(ev) - } +},{"./console-reporter":20,"./on":22,"./reporter":23,"./util":24}],22:[function(require,module,exports){ +"use strict" - D.document.head.appendChild(script) - }) -} +var Status = require("./util").Status -function tryDelete(key) { +// Because ES5 sucks. (And, it's breaking my PhantomJS builds) +function setName(reporter, name) { try { - delete global[key] - } catch (_) { + Object.defineProperty(reporter, "name", {value: name}) + } catch (e) { // ignore } } -function descriptorChanged(a, b) { - // Note: if the descriptor was removed, it would've been deleted, anyways. - if (a == null) return false - if (a.configurable !== b.configurable) return true - if (a.enumerable !== b.enumerable) return true - if (a.writable !== b.writable) return true - if (a.get !== b.get) return true - if (a.set !== b.set) return true - if (a.value !== b.value) return true - return false -} - -// These fire deprecation warnings, and thus should be avoided. -var blacklist = Object.freeze({ - webkitStorageInfo: true, - webkitIndexedDB: true, -}) +/** + * A macro of sorts, to simplify creating reporters. It accepts an object with + * the following parameters: + * + * `accepts: string[]` - The properties accepted. Everything else is ignored, + * and it's partially there for documentation. This parameter is required. + * + * `create(opts, methods)` - Create a new reporter instance. This parameter is + * required. Note that `methods` refers to the parameter object itself. + * + * `init(state, opts)` - Initialize extra reporter state, if applicable. + * + * `before(reporter)` - Do things before each event, returning a possible + * thenable when done. This defaults to a no-op. + * + * `after(reporter)` - Do things after each event, returning a possible + * thenable when done. This defaults to a no-op. + * + * `report(reporter, report)` - Handle a test report. This may return a possible + * thenable when done, and it is required. + */ +module.exports = function (name, methods) { + setName(reporter, name) + reporter[name] = reporter + return reporter + function reporter(opts) { + /** + * Instead of silently failing to work, let's error out when a report is + * passed in, and inform the user it needs initialized. Chances are, + * there's no legitimate reason to even pass a report, anyways. + */ + if (typeof opts === "object" && opts !== null && + typeof opts._ === "number") { + throw new TypeError( + "Options cannot be a report. Did you forget to call the " + + "factory first?") + } -function findGlobals() { - var found = Object.keys(global) - var globals = Object.create(null) + var _ = methods.create(opts, methods) - for (var i = 0; i < found.length; i++) { - var key = found[i] + return function (report) { + // Only some events have common steps. + if (report.isStart) { + _.running = true + } else if (report.isEnter || report.isPass) { + _.get(report.path).status = Status.Passing + _.duration += report.duration + _.tests++ + _.pass++ + } else if (report.isFail) { + _.get(report.path).status = Status.Failing + _.duration += report.duration + _.tests++ + _.fail++ + } else if (report.isHook) { + _.get(report.path).status = Status.Failing + _.get(report.rootPath).status = Status.Failing + _.fail++ + } else if (report.isSkip) { + _.get(report.path).status = Status.Skipped + // Skipped tests aren't counted in the total test count + _.skip++ + } - if (!hasOwn.call(blacklist, key)) { - globals[key] = Object.getOwnPropertyDescriptor(global, key) + return Promise.resolve( + typeof methods.before === "function" + ? methods.before(_) + : undefined) + .then(function () { return methods.report(_, report) }) + .then(function () { + return typeof methods.after === "function" + ? methods.after(_) + : undefined + }) + .then(function () { + if (report.isEnd || report.isError) { + _.reset() + if (typeof _.opts.reset === "function") { + return _.opts.reset() + } + } + return undefined + }) } } - - return globals } -module.exports = function (opts, state) { - if (state.locked) { - return Promise.reject(new Error( - "The test suite must not be run after the view has been detached." - )) - } - - if (state.currentPromise != null) return state.currentPromise - - opts.thallium.clearTests() +},{"./util":24}],23:[function(require,module,exports){ +"use strict" - // Detect and remove globals created by loaded scripts. - var globals = findGlobals() +var methods = require("../methods") +var defaultify = require("./util").defaultify +var hasOwn = Object.prototype.hasOwnProperty - function cleanup() { - var found = Object.keys(global) +function State(reporter) { + if (typeof reporter.methods.init === "function") { + (0, reporter.methods.init)(this, reporter.opts) + } +} - for (var i = 0; i < found.length; i++) { - var key = found[i] +/** + * This helps speed up getting previous trees, so a potentially expensive + * tree search doesn't have to be performed. + * + * (This does actually make a slight perf difference in the tests.) + */ +function isRepeat(cache, path) { + // Can't be a repeat the first time. + if (cache.path == null) return false + if (path.length !== cache.path.length) return false + if (path === cache.path) return true - if (!hasOwn.call(globals, key)) { - tryDelete(key) - } else if (descriptorChanged( - Object.getOwnPropertyDescriptor(global, key), - globals[key] - )) { - tryDelete(key) - } + // It's unlikely the nesting will be consistently more than a few levels + // deep (>= 5), so this shouldn't bog anything down. + for (var i = 0; i < path.length; i++) { + if (path[i] !== cache.path[i]) { + return false } - - state.currentPromise = undefined } - return state.currentPromise = Promise.resolve() - .then(function () { - state.pass.textContent = "0" - state.fail.textContent = "0" - state.skip.textContent = "0" - return opts.preload() - }) - .then(function () { - return Util.peach(opts.files, function (file) { - return loadScript(file, opts.timeout) - }) - }) - .then(function () { return opts.prerun() }) - .then(function () { return opts.thallium.run() }) - .then(function () { return opts.postrun() }) - .catch(function (e) { - return Promise.resolve(opts.error(e)).then(function () { throw e }) - }) - .then( - function () { cleanup() }, - function (e) { cleanup(); throw e }) + cache.path = path + return true } -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +/** + * Superclass for all reporters. This covers the state for pretty much every + * reporter. + * + * Note that if you delay the initial reset, you still must call it before the + * constructor finishes. + */ +module.exports = Reporter +function Reporter(Tree, opts, methods, delay) { + this.Tree = Tree + this.opts = {} + this.methods = methods + defaultify(this, opts, "reset") + if (!delay) this.reset() +} -},{"../util":27,"./inject":16}],18:[function(require,module,exports){ -(function (global){ -"use strict" +methods(Reporter, { + reset: function () { + this.running = false + this.timePrinted = false + this.tests = 0 + this.pass = 0 + this.fail = 0 + this.skip = 0 + this.duration = 0 + this.errors = [] + this.state = new State(this) + this.base = new this.Tree(undefined) + this.cache = {path: undefined, result: undefined, end: 0} + }, -var diff = require("diff") -var R = require("../reporter") -var D = require("./inject") -var runTests = require("./run-tests") -var inspect = require("clean-assert-util").inspect + pushError: function (report) { + this.errors.push(report) + }, -/** - * View logic - */ + get: function (path, end) { + if (end == null) end = path.length + if (end === 0) return this.base + if (isRepeat(this.cache, path, end)) { + return this.cache.result + } -function t(text) { - return D.document.createTextNode(text) -} + var child = this.base -function h(type, attrs, children) { - var parts = type.split(/\s+/g) + for (var i = 0; i < end; i++) { + var entry = path[i] - if (Array.isArray(attrs)) { - children = attrs - attrs = undefined - } + if (hasOwn.call(child.children, entry.index)) { + child = child.children[entry.index] + } else { + child = child.children[entry.index] = new this.Tree(entry.name) + } + } - if (attrs == null) attrs = {} - if (children == null) children = [] + this.cache.end = end + return this.cache.result = child + }, +}) - type = parts[0] - attrs.className = parts.slice(1).join(" ") +},{"../methods":18,"./util":24}],24:[function(require,module,exports){ +"use strict" - var elem = D.document.createElement(type) +var Util = require("../util") +var Settings = require("../settings") - Object.keys(attrs).forEach(function (attr) { - elem[attr] = attrs[attr] - }) +exports.symbols = Settings.symbols +exports.windowWidth = Settings.windowWidth +exports.newline = Settings.newline - children.forEach(function (child) { - if (child != null) elem.appendChild(child) - }) +/* + * Stack normalization + */ - return elem -} +// Exported for debugging +exports.readStack = readStack +function readStack(e) { + var stack = Util.getStack(e) -function unifiedDiff(err) { - var actual = inspect(err.actual) - var expected = inspect(err.expected) - var msg = diff.createPatch("string", actual, expected) - .split(/\r?\n|\r/g).slice(4) - .filter(function (line) { return !/^\@\@|^\\ No newline/.test(line) }) - var end = msg.length + // If it doesn't start with the message, just return the stack. + // Firefox, Safari Chrome, IE + if (/^(@)?\S+\:\d+/.test(stack) || /^\s*at/.test(stack)) { + return formatLineBreaks(stack) + } - while (end !== 0 && /^\s*$/g.test(msg[end - 1])) end-- - return h("div tl-diff", [ - h("div tl-diff-header", [ - h("span tl-diff-added", [t("+ expected")]), - h("span tl-diff-removed", [t("- actual")]), - ]), - h("div tl-pre", !end - ? [h("span tl-line tl-diff-added", [t(" (none)")])] - : msg.slice(0, end) - .map(function (line) { return line.trimRight() }) - .map(function (line) { - if (line[0] === "+") { - return h("span tl-line tl-diff-added", [t(line)]) - } else if (line[0] === "-") { - return h("span tl-line tl-diff-removed", [t(line)]) - } else { - return h("span tl-line tl-diff-none", [t(line)]) - } - }) - ), - ]) + var index = stack.indexOf(e.message) + + if (index < 0) return formatLineBreaks(Util.getStack(e)) + var re = /\r?\n/g + + re.lastIndex = index + e.message.length + if (!re.test(stack)) return "" + return formatLineBreaks(stack.slice(re.lastIndex)) } -function toLines(str) { - return h("div tl-pre", str.split(/\r?\n|\r/g).map(function (line) { - return h("span tl-line", [t(line.trimRight())]) - })) +function formatLineBreaks(str) { + return str.replace(/^\s+|[^\r\n\S]+$/g, "") + .replace(/\s*(\r?\n|\r)\s*/g, Settings.newline()) } -function formatError(e, showDiff) { - var stack = R.readStack(e) +exports.getStack = function (e) { + if (!(e instanceof Error)) return formatLineBreaks(Util.getStack(e)) + var description = (e.name + ": " + e.message) + .replace(/\s+$/gm, "") + .replace(/\r?\n|\r/g, Settings.newline()) + var stripped = readStack(e) - return h("div tl-display", [ - h("div tl-message", [toLines(e.name + ": " + e.message)]), - showDiff ? unifiedDiff(e) : undefined, - stack ? h("div tl-stack", [toLines(stack)]) : undefined, - ]) + if (stripped === "") return description + return description + Settings.newline() + stripped } -function showTest(_, report, className, child) { - var end = report.path.length - 1 - var name = report.path[end].name - var parent = _.get(report.path, end) - var speed = R.speed(report) +var Colors = exports.Colors = Settings.Colors - if (speed === "fast") { - parent.node.appendChild(h("li " + className + " tl-fast", [ - h("h2", [t(name)]), - child, - ])) - } else { - parent.node.appendChild(h("li " + className + " tl-" + speed, [ - h("h2", [ - t(name + " ("), - h("span tl-duration", [t(R.formatTime(report.duration))]), - t(")"), - ]), - child, - ])) - } +// Color palette pulled from Mocha +function colorToNumber(name) { + switch (name) { + case "pass": return 90 + case "fail": return 31 - _.opts.duration.textContent = R.formatTime(_.duration) -} + case "bright pass": return 92 + case "bright fail": return 91 + case "bright yellow": return 93 -function showSkip(_, report) { - var end = report.path.length - 1 - var name = report.path[end].name - var parent = _.get(report.path, end) + case "skip": return 36 + case "suite": return 0 + case "plain": return 0 - parent.node.appendChild(h("li tl-test tl-skip", [ - h("h2", [t(name)]), - ])) + case "error title": return 0 + case "error message": return 31 + case "error stack": return 90 + + case "checkmark": return 32 + case "fast": return 90 + case "medium": return 33 + case "slow": return 31 + case "green": return 32 + case "light": return 90 + + case "diff gutter": return 90 + case "diff added": return 32 + case "diff removed": return 31 + default: throw new TypeError("Invalid name: \"" + name + "\"") + } } -exports.nextFrame = nextFrame -function nextFrame(func) { - if (D.window.requestAnimationFrame) { - D.window.requestAnimationFrame(func) +exports.color = color +function color(name, str) { + if (Colors.supported()) { + return "\u001b[" + colorToNumber(name) + "m" + str + "\u001b[0m" } else { - global.setTimeout(func, 0) + return str + "" } } -exports.report = function (_, report) { - if (report.isStart) { - return new Promise(function (resolve) { - // Clear the element first, just in case. - while (_.opts.report.firstChild) { - _.opts.report.removeChild(_.opts.report.firstChild) - } +exports.setColor = function (_) { + if (_.opts.color != null) Colors.maybeSet(_.opts.color) +} - // Defer the next frame, so the current changes can be sent, in case - // it's clearing old test results from a large suite. (Chrome does - // better batching this way, at least.) - nextFrame(function () { - _.get(undefined, 0).node = _.opts.report - _.opts.duration.textContent = R.formatTime(0) - _.opts.pass.textContent = "0" - _.opts.fail.textContent = "0" - _.opts.skip.textContent = "0" - resolve() - }) - }) - } else if (report.isEnter) { - var child = h("ul") - - _.get(report.path).node = child - showTest(_, report, "tl-suite tl-pass", child) - _.opts.pass.textContent = _.pass - } else if (report.isPass) { - showTest(_, report, "tl-test tl-pass") - _.opts.pass.textContent = _.pass - } else if (report.isFail) { - showTest(_, report, "tl-test tl-fail", formatError(report.error, - report.error.name === "AssertionError" && - report.error.showDiff !== false)) - _.opts.fail.textContent = _.fail - } else if (report.isSkip) { - showSkip(_, report, "tl-test tl-skip") - _.opts.skip.textContent = _.skip - } else if (report.isError) { - _.opts.report.appendChild(h("li tl-error", [ - h("h2", [t("Internal error")]), - formatError(report.error, false), - ])) - } - - return undefined +exports.unsetColor = function (_) { + if (_.opts.color != null) Colors.maybeRestore() } -function makeCounter(state, child, label, name) { - return h("button tl-toggle " + name, { - onclick: function (ev) { - ev.preventDefault() - ev.stopPropagation() - - if (/\btl-active\b/.test(this.className)) { - this.className = this.className - .replace(/\btl-active\b/g, "") - .replace(/\s+/g, " ") - .trim() - state.report.className = state.report.className - .replace(new RegExp("\\b" + name + "\\b", "g"), "") - .replace(/\s+/g, " ") - .trim() - state.active = undefined - } else { - if (state.active != null) { - state.active.className = state.active.className - .replace(/\btl-active\b/g, "") - .replace(/\s+/g, " ") - .trim() - } +var Status = exports.Status = Object.freeze({ + Unknown: 0, + Skipped: 1, + Passing: 2, + Failing: 3, +}) - state.active = this - this.className += " tl-active" - state.report.className = state.report.className - .replace(/\btl-(pass|fail|skip)\b/g, "") - .replace(/\s+/g, " ") - .trim() + " " + name - } - }, - }, [t(label), child]) +exports.Tree = function (value) { + this.value = value + this.status = Status.Unknown + this.children = Object.create(null) } -exports.init = function (opts) { - var state = { - currentPromise: undefined, - locked: false, - duration: h("em", [t(R.formatTime(0))]), - pass: h("em", [t("0")]), - fail: h("em", [t("0")]), - skip: h("em", [t("0")]), - report: h("ul tl-report"), - active: undefined, - } +exports.defaultify = function (_, opts, prop) { + if (_.methods.accepts.indexOf(prop) >= 0) { + var used = opts != null && typeof opts[prop] === "function" + ? opts + : Settings.defaultOpts() - var header = h("div tl-header", [ - h("div tl-duration", [t("Duration: "), state.duration]), - makeCounter(state, state.pass, "Passes: ", "tl-pass"), - makeCounter(state, state.fail, "Failures: ", "tl-fail"), - makeCounter(state, state.skip, "Skipped: ", "tl-skip"), - h("button tl-run", { - onclick: function (ev) { - ev.preventDefault() - ev.stopPropagation() - runTests(opts, state) - }, - }, [t("Run")]), - ]) + _.opts[prop] = function () { + return Promise.resolve(used[prop].apply(used, arguments)) + } + } +} - var root = D.document.getElementById("tl") +function joinPath(reportPath) { + var path = "" - if (root == null) { - D.document.body.appendChild(root = h("div", {id: "tl"}, [ - header, - state.report, - ])) - } else { - // Clear the element first, just in case. - while (root.firstChild) root.removeChild(root.firstChild) - root.appendChild(header) - root.appendChild(state.report) + for (var i = 0; i < reportPath.length; i++) { + path += " " + reportPath[i].name } - return { - root: root, - state: state, - } + return path.slice(1) } -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +exports.joinPath = function (report) { + return joinPath(report.path) +} -},{"../reporter":22,"./inject":16,"./run-tests":17,"clean-assert-util":33,"diff":52}],19:[function(require,module,exports){ -"use strict" +exports.speed = function (report) { + if (report.duration >= report.slow) return "slow" + if (report.duration >= report.slow / 2) return "medium" + if (report.duration >= 0) return "fast" + throw new RangeError("Duration must not be negative") +} -module.exports = function (Base, Super) { - var start = 2 +exports.formatTime = (function () { + var s = 1000 /* ms */ + var m = 60 * s + var h = 60 * m + var d = 24 * h - if (typeof Super === "function") { - Base.prototype = Object.create(Super.prototype) - Object.defineProperty(Base.prototype, "constructor", { - configurable: true, - writable: true, - enumerable: false, - value: Base, - }) - } else { - start = 1 + return function (ms) { + if (ms >= d) return Math.round(ms / d) + "d" + if (ms >= h) return Math.round(ms / h) + "h" + if (ms >= m) return Math.round(ms / m) + "m" + if (ms >= s) return Math.round(ms / s) + "s" + return ms + "ms" } +})() - for (var i = start; i < arguments.length; i++) { - var methods = arguments[i] - - if (methods != null) { - var keys = Object.keys(methods) - - for (var k = 0; k < keys.length; k++) { - var key = keys[k] - var desc = Object.getOwnPropertyDescriptor(methods, key) +exports.formatRest = function (report) { + if (!report.isHook) return "" + var path = " (" - desc.enumerable = false - Object.defineProperty(Base.prototype, key, desc) - } + if (report.rootPath.length) { + path += report.stage + if (report.name) path += " ‒ " + report.name + if (report.path.length > report.rootPath.length + 1) { + path += ", in " + joinPath(report.rootPath) } + } else { + path += "global " + report.stage + if (report.name) path += " ‒ " + report.name } + + return path + ")" } -},{}],20:[function(require,module,exports){ -(function (global){ +},{"../settings":25,"../util":26}],25:[function(require,module,exports){ "use strict" -/** - * This contains the browser console stuff. - */ - -exports.Symbols = Object.freeze({ - Pass: "✓", - Fail: "✖", - Dot: "․", - DotFail: "!", -}) +// General CLI and reporter settings. If something needs to -exports.windowWidth = 75 -exports.newline = "\n" +var Console = require("./replaced/console") -// Color support is unforced and unsupported, since you can only specify -// line-by-line colors via CSS, and even that isn't very portable. -exports.colorSupport = 0 +var windowWidth = Console.windowWidth +var newline = Console.newline +var Symbols = Console.Symbols +var defaultOpts = Console.defaultOpts -/** - * Since browsers don't have unbuffered output, this kind of simulates it. - */ +exports.windowWidth = function () { return windowWidth } +exports.newline = function () { return newline } +exports.symbols = function () { return Symbols } +exports.defaultOpts = function () { return defaultOpts } -var acc = "" +exports.setWindowWidth = function (value) { return windowWidth = value } +exports.setNewline = function (value) { return newline = value } +exports.setSymbols = function (value) { return Symbols = value } +exports.setDefaultOpts = function (value) { return defaultOpts = value } -exports.defaultOpts = { - write: function (str) { - acc += str +// Console.colorSupport is a mask with the following bits: +// 0x1 - if set, colors supported by default +// 0x2 - if set, force color support +// +// This is purely an implementation detail, and is invisible to the outside +// world. +var colorSupport = Console.colorSupport +var mask = colorSupport - var index = str.indexOf("\n") +exports.Colors = { + supported: function () { + return (mask & 0x1) !== 0 + }, - if (index >= 0) { - var lines = str.split("\n") + forced: function () { + return (mask & 0x2) !== 0 + }, - acc = lines.pop() + maybeSet: function (value) { + if ((mask & 0x2) === 0) mask = value ? 0x1 : 0 + }, - for (var i = 0; i < lines.length; i++) { - global.console.log(lines[i]) - } - } + maybeRestore: function () { + if ((mask & 0x2) === 0) mask = colorSupport & 0x1 }, - reset: function () { - if (acc !== "") { - global.console.log(acc) - acc = "" + // Only for debugging + forceSet: function (value) { + mask = value ? 0x3 : 0x2 + }, + + forceRestore: function () { + mask = colorSupport + }, + + getSupport: function () { + return { + supported: (colorSupport & 0x1) !== 0, + forced: (colorSupport & 0x2) !== 0, } }, -} -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + setSupport: function (opts) { + mask = colorSupport = + (opts.supported ? 0x1 : 0) | (opts.forced ? 0x2 : 0) + }, +} -},{}],21:[function(require,module,exports){ +},{"./replaced/console":19}],26:[function(require,module,exports){ "use strict" -var diff = require("diff") +var methods = require("./methods") -var methods = require("../methods") -var inspect = require("clean-assert-util").inspect -var peach = require("../util").peach -var Reporter = require("./reporter") -var Util = require("./util") -var Settings = require("../settings") +exports.getType = function (value) { + if (value == null) return "null" + if (Array.isArray(value)) return "array" + return typeof value +} -function printTime(_, p, str) { - if (!_.timePrinted) { - _.timePrinted = true - str += Util.color("light", " (" + Util.formatTime(_.duration) + ")") +// PhantomJS, IE, and possibly Edge don't set the stack trace until the error is +// thrown. Note that this prefers an existing stack first, since non-native +// errors likely already contain this. Note that this isn't necessary in the +// CLI - that only targets Node. +exports.getStack = function (e) { + var stack = e.stack + + if (!(e instanceof Error) || stack != null) return stack + + try { + throw e + } catch (e) { + return e.stack } +} - return p.then(function () { return _.print(str) }) +exports.pcall = function (func) { + return new Promise(function (resolve, reject) { + return func(function (e, value) { + return e != null ? reject(e) : resolve(value) + }) + }) } -function unifiedDiff(err) { - var actual = inspect(err.actual) - var expected = inspect(err.expected) - var msg = diff.createPatch("string", actual, expected) - var header = Settings.newline() + - Util.color("diff added", "+ expected") + " " + - Util.color("diff removed", "- actual") + - Settings.newline() + Settings.newline() +exports.peach = function (list, func) { + var len = list.length + var p = Promise.resolve() - return header + msg.split(/\r?\n|\r/g).slice(4) - .filter(function (line) { return !/^\@\@|^\\ No newline/.test(line) }) - .map(function (line) { - if (line[0] === "+") return Util.color("diff added", line.trimRight()) - if (line[0] === "-") return Util.color("diff removed", line.trimRight()) - return line.trimRight() - }) - .join(Settings.newline()) + for (var i = 0; i < len; i++) { + p = p.then(func.bind(undefined, list[i], i)) + } + + return p } -function formatFail(str) { - return str.trimRight() - .split(/\r?\n|\r/g) - .map(function (line) { return Util.color("fail", line.trimRight()) }) - .join(Settings.newline()) +/** + * A lazy accessor, complete with thrown error memoization and a decent amount + * of optimization, since it's used in a lot of code. + * + * Note that this uses reference indirection and direct mutation to keep only + * just the computation non-constant, so engines can avoid closure allocation. + * Also, `create` is intentionally kept *out* of any closure, so it can be more + * easily collected. + */ +function Lazy(create) { + this.value = create + this.get = this.init } -function getDiffStack(e) { - var description = formatFail(e.name + ": " + e.message) +methods(Lazy, { + recursive: function () { + throw new TypeError("Lazy functions must not be called recursively!") + }, - if (e.name === "AssertionError" && e.showDiff !== false) { - description += Settings.newline() + unifiedDiff(e) - } + return: function () { + return this.value + }, - var stripped = formatFail(Util.readStack(e)) + throw: function () { + throw this.value + }, - if (stripped === "") return description - return description + Settings.newline() + stripped -} + init: function () { + this.get = this.recursive -function inspectTrimmed(object) { - return inspect(object).trimRight() - .split(/\r?\n|\r/g) - .map(function (line) { return line.trimRight() }) - .join(Settings.newline()) -} + try { + this.value = (0, this.value)() + this.get = this.return + return this.value + } catch (e) { + this.value = e + this.get = this.throw + throw this.value + } + }, +}) -function printFailList(_, err) { - var str = err instanceof Error ? getDiffStack(err) : inspectTrimmed(err) - var parts = str.split(/\r?\n/g) +exports.lazy = function (create) { + var ref = new Lazy(create) - return _.print(" " + parts[0]).then(function () { - return peach(parts.slice(1), function (part) { - return _.print(part ? " " + part : "") - }) - }) + return function () { + return ref.get() + } } -module.exports = function (opts, methods) { - return new ConsoleReporter(opts, methods) -} +},{"./methods":18}],27:[function(require,module,exports){ +"use strict" /** - * Base class for most console reporters. - * - * Note: printing is asynchronous, because otherwise, if enough errors exist, - * Node will eventually start dropping lines sent to its buffer, especially when - * stack traces get involved. If Thallium's output is redirected, that can be a - * big problem for consumers, as they only have part of the output, and won't be - * able to see all the errors later. Also, if console warnings come up en-masse, - * that would also contribute. So, we have to wait for each line to flush before - * we can continue, so the full output makes its way to the console. - * - * Some test frameworks like Tape miss this, though. + * Backport wrapper to warn about most of the major breaking changes from the + * last major version, and to help me keep track of all the changes. * - * @param {Object} opts The options for the reporter. - * @param {Function} opts.write The unbufferred writer for the reporter. - * @param {Function} opts.reset A reset function for the printer + writer. - * @param {String[]} accepts The options accepted. - * @param {Function} init The init function for the subclass reporter's - * isolated state (created by factory). + * It consists of solely internal monkey patching to revive support of previous + * versions, although I tried to limit how much knowledge of the internals this + * requires. */ -function ConsoleReporter(opts, methods) { - Reporter.call(this, Util.Tree, opts, methods, true) - if (!Util.Colors.forced() && methods.accepts.indexOf("color") >= 0) { - this.opts.color = opts.color - } +// var Common = require("./common") +// var methods = require("../lib/methods") - Util.defaultify(this, opts, "write") - this.reset() -} +},{}],28:[function(require,module,exports){ +"use strict" -methods(ConsoleReporter, Reporter, { - print: function (str) { - if (str == null) str = "" - return Promise.resolve(this.opts.write(str + "\n")) - }, +},{}],29:[function(require,module,exports){ +module.exports = function (xs, f) { + if (xs.map) return xs.map(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = xs[i]; + if (hasOwn.call(xs, i)) res.push(f(x, i, xs)); + } + return res; +}; - write: function (str) { - if (str != null) { - return Promise.resolve(this.opts.write(str)) - } else { - return Promise.resolve() - } - }, +var hasOwn = Object.prototype.hasOwnProperty; - printResults: function () { - var self = this +},{}],30:[function(require,module,exports){ +var hasOwn = Object.prototype.hasOwnProperty; - if (!this.tests && !this.skip) { - return this.print( - Util.color("plain", " 0 tests") + - Util.color("light", " (0ms)")) - .then(function () { return self.print() }) +module.exports = function (xs, f, acc) { + var hasAcc = arguments.length >= 3; + if (hasAcc && xs.reduce) return xs.reduce(f, acc); + if (xs.reduce) return xs.reduce(f); + + for (var i = 0; i < xs.length; i++) { + if (!hasOwn.call(xs, i)) continue; + if (!hasAcc) { + acc = xs[i]; + hasAcc = true; + continue; } + acc = f(acc, xs[i], i); + } + return acc; +}; - return this.print().then(function () { - var p = Promise.resolve() +},{}],31:[function(require,module,exports){ +"use strict" - if (self.pass) { - p = printTime(self, p, - Util.color("bright pass", " ") + - Util.color("green", self.pass + " passing")) - } +// See https://github.com/substack/node-browserify/issues/1674 - if (self.skip) { - p = printTime(self, p, - Util.color("skip", " " + self.skip + " skipped")) - } +module.exports = require("util-inspect") - if (self.fail) { - p = printTime(self, p, - Util.color("bright fail", " ") + - Util.color("fail", self.fail + " failing")) - } +},{"util-inspect":63}],32:[function(require,module,exports){ +"use strict" - return p - }) - .then(function () { return self.print() }) - .then(function () { - return peach(self.errors, function (report, i) { - var name = i + 1 + ") " + Util.joinPath(report) + - Util.formatRest(report) - - return self.print(" " + Util.color("plain", name + ":")) - .then(function () { - return printFailList(self, report.error) - }) - .then(function () { return self.print() }) - }) - }) - }, - - printError: function (report) { - var self = this - var lines = report.error instanceof Error - ? Util.getStack(report.error) - : inspectTrimmed(report.error) - - return this.print().then(function () { - return peach(lines.split(/\r?\n/g), function (line) { - return self.print(line) - }) - }) - }, -}) - -},{"../methods":19,"../settings":26,"../util":27,"./reporter":24,"./util":25,"clean-assert-util":33,"diff":52}],22:[function(require,module,exports){ -"use strict" - -var Util = require("./util") - -exports.on = require("./on") -exports.consoleReporter = require("./console-reporter") -exports.Reporter = require("./reporter") -exports.color = Util.color -exports.Colors = Util.Colors -exports.formatRest = Util.formatRest -exports.formatTime = Util.formatTime -exports.getStack = Util.getStack -exports.joinPath = Util.joinPath -exports.newline = Util.newline -exports.readStack = Util.readStack -exports.setColor = Util.setColor -exports.speed = Util.speed -exports.Status = Util.Status -exports.symbols = Util.symbols -exports.unsetColor = Util.unsetColor -exports.windowWidth = Util.windowWidth +var inspect = exports.inspect = require("./inspect") +var hasOwn = Object.prototype.hasOwnProperty +var AssertionError -},{"./console-reporter":21,"./on":23,"./reporter":24,"./util":25}],23:[function(require,module,exports){ -"use strict" +// PhantomJS, IE, and possibly Edge don't set the stack trace until the error is +// thrown. Note that this prefers an existing stack first, since non-native +// errors likely already contain this. +function getStack(e) { + var stack = e.stack -var Status = require("./util").Status + if (!(e instanceof Error) || stack != null) return stack -// Because ES5 sucks. (And, it's breaking my PhantomJS builds) -function setName(reporter, name) { try { - Object.defineProperty(reporter, "name", {value: name}) + throw e } catch (e) { - // ignore + return e.stack } } -/** - * A macro of sorts, to simplify creating reporters. It accepts an object with - * the following parameters: - * - * `accepts: string[]` - The properties accepted. Everything else is ignored, - * and it's partially there for documentation. This parameter is required. - * - * `create(opts, methods)` - Create a new reporter instance. This parameter is - * required. Note that `methods` refers to the parameter object itself. - * - * `init(state, opts)` - Initialize extra reporter state, if applicable. - * - * `before(reporter)` - Do things before each event, returning a possible - * thenable when done. This defaults to a no-op. - * - * `after(reporter)` - Do things after each event, returning a possible - * thenable when done. This defaults to a no-op. - * - * `report(reporter, report)` - Handle a test report. This may return a possible - * thenable when done, and it is required. - */ -module.exports = function (name, methods) { - setName(reporter, name) - reporter[name] = reporter - return reporter - function reporter(opts) { - /** - * Instead of silently failing to work, let's error out when a report is - * passed in, and inform the user it needs initialized. Chances are, - * there's no legitimate reason to even pass a report, anyways. - */ - if (typeof opts === "object" && opts !== null && - typeof opts._ === "number") { - throw new TypeError( - "Options cannot be a report. Did you forget to call the " + - "factory first?") +try { + AssertionError = new Function([ // eslint-disable-line no-new-func + "'use strict';", + "class AssertionError extends Error {", + " constructor(message, expected, actual) {", + " super(message)", + " this.expected = expected", + " this.actual = actual", + " }", + "", + " get name() {", + " return 'AssertionError'", + " }", + "}", + // check native subclassing support + "new AssertionError('message', 1, 2)", + "return AssertionError", + ].join("\n"))() +} catch (e) { + AssertionError = typeof Error.captureStackTrace === "function" + ? function AssertionError(message, expected, actual) { + this.message = message || "" + this.expected = expected + this.actual = actual + Error.captureStackTrace(this, this.constructor) } + : function AssertionError(message, expected, actual) { + this.message = message || "" + this.expected = expected + this.actual = actual + var e = new Error(message) - var _ = methods.create(opts, methods) + e.name = "AssertionError" + this.stack = getStack(e) + } - return function (report) { - // Only some events have common steps. - if (report.isStart) { - _.running = true - } else if (report.isEnter || report.isPass) { - _.get(report.path).status = Status.Passing - _.duration += report.duration - _.tests++ - _.pass++ - } else if (report.isFail) { - _.get(report.path).status = Status.Failing - _.duration += report.duration - _.tests++ - _.fail++ - } else if (report.isHook) { - _.get(report.path).status = Status.Failing - _.get(report.rootPath).status = Status.Failing - _.fail++ - } else if (report.isSkip) { - _.get(report.path).status = Status.Skipped - // Skipped tests aren't counted in the total test count - _.skip++ - } + AssertionError.prototype = Object.create(Error.prototype) - return Promise.resolve( - typeof methods.before === "function" - ? methods.before(_) - : undefined) - .then(function () { return methods.report(_, report) }) - .then(function () { - return typeof methods.after === "function" - ? methods.after(_) - : undefined - }) - .then(function () { - if (report.isEnd || report.isError) { - _.reset() - if (typeof _.opts.reset === "function") { - return _.opts.reset() - } - } - return undefined - }) - } - } + Object.defineProperty(AssertionError.prototype, "constructor", { + configurable: true, + writable: true, + enumerable: false, + value: AssertionError, + }) + + Object.defineProperty(AssertionError.prototype, "name", { + configurable: true, + writable: true, + enumerable: false, + value: "AssertionError", + }) } -},{"./util":25}],24:[function(require,module,exports){ -"use strict" +exports.AssertionError = AssertionError -var methods = require("../methods") -var defaultify = require("./util").defaultify -var hasOwn = Object.prototype.hasOwnProperty +/* eslint-disable no-self-compare */ +// For better NaN handling +exports.strictIs = function (a, b) { + return a === b || a !== a && b !== b +} -function State(reporter) { - if (typeof reporter.methods.init === "function") { - (0, reporter.methods.init)(this, reporter.opts) - } +exports.looseIs = function (a, b) { + return a == b || a !== a && b !== b // eslint-disable-line eqeqeq } -/** - * This helps speed up getting previous trees, so a potentially expensive - * tree search doesn't have to be performed. - * - * (This does actually make a slight perf difference in the tests.) - */ -function isRepeat(cache, path) { - // Can't be a repeat the first time. - if (cache.path == null) return false - if (path.length !== cache.path.length) return false - if (path === cache.path) return true +/* eslint-enable no-self-compare */ - // It's unlikely the nesting will be consistently more than a few levels - // deep (>= 5), so this shouldn't bog anything down. - for (var i = 0; i < path.length; i++) { - if (path[i] !== cache.path[i]) { - return false - } - } +var templateRegexp = /(.?)\{(.+?)\}/g - cache.path = path - return true -} +exports.escape = function (string) { + if (typeof string !== "string") { + throw new TypeError("`string` must be a string") + } -/** - * Superclass for all reporters. This covers the state for pretty much every - * reporter. - * - * Note that if you delay the initial reset, you still must call it before the - * constructor finishes. - */ -module.exports = Reporter -function Reporter(Tree, opts, methods, delay) { - this.Tree = Tree - this.opts = {} - this.methods = methods - defaultify(this, opts, "reset") - if (!delay) this.reset() + return string.replace(templateRegexp, function (m, pre) { + return pre + "\\" + m.slice(1) + }) } -methods(Reporter, { - reset: function () { - this.running = false - this.timePrinted = false - this.tests = 0 - this.pass = 0 - this.fail = 0 - this.skip = 0 - this.duration = 0 - this.errors = [] - this.state = new State(this) - this.base = new this.Tree(undefined) - this.cache = {path: undefined, result: undefined, end: 0} - }, - - pushError: function (report) { - this.errors.push(report) - }, +// This formats the assertion error messages. +exports.format = function (message, args, prettify) { + if (prettify == null) prettify = inspect - get: function (path, end) { - if (end == null) end = path.length - if (end === 0) return this.base - if (isRepeat(this.cache, path, end)) { - return this.cache.result - } + if (typeof message !== "string") { + throw new TypeError("`message` must be a string") + } - var child = this.base + if (typeof args !== "object" || args === null) { + throw new TypeError("`args` must be an object") + } - for (var i = 0; i < end; i++) { - var entry = path[i] + if (typeof prettify !== "function") { + throw new TypeError("`prettify` must be a function if passed") + } - if (hasOwn.call(child.children, entry.index)) { - child = child.children[entry.index] - } else { - child = child.children[entry.index] = new this.Tree(entry.name) - } + return message.replace(templateRegexp, function (m, pre, prop) { + if (pre === "\\") { + return m.slice(1) + } else if (hasOwn.call(args, prop)) { + return pre + prettify(args[prop], {depth: 5}) + } else { + return pre + m } + }) +} - this.cache.end = end - return this.cache.result = child - }, -}) - -},{"../methods":19,"./util":25}],25:[function(require,module,exports){ -"use strict" +exports.fail = function (message, args, prettify) { + if (args == null) throw new AssertionError(message) + throw new AssertionError( + exports.format(message, args, prettify), + args.expected, + args.actual) +} -var Util = require("../util") -var Settings = require("../settings") +// The basic assert, like `assert.ok`, but gives you an optional message. +exports.assert = function (test, message) { + if (!test) throw new AssertionError(message) +} -exports.symbols = Settings.symbols -exports.windowWidth = Settings.windowWidth -exports.newline = Settings.newline +},{"./inspect":31}],33:[function(require,module,exports){ +"use strict" -/* - * Stack normalization +/** + * Core TDD-style assertions. These are done by a composition of DSLs, since + * there is *so* much repetition. Also, this is split into several namespaces to + * keep the file size manageable. */ -// Exported for debugging -exports.readStack = readStack -function readStack(e) { - var stack = Util.getStack(e) +var util = require("clean-assert-util") +var type = require("./lib/type") +var equal = require("./lib/equal") +var throws = require("./lib/throws") +var has = require("./lib/has") +var includes = require("./lib/includes") +var hasKeys = require("./lib/has-keys") - // If it doesn't start with the message, just return the stack. - // Firefox, Safari Chrome, IE - if (/^(@)?\S+\:\d+/.test(stack) || /^\s*at/.test(stack)) { - return formatLineBreaks(stack) - } +exports.AssertionError = util.AssertionError +exports.assert = util.assert +exports.fail = util.fail - var index = stack.indexOf(e.message) +exports.ok = type.ok +exports.notOk = type.notOk +exports.isBoolean = type.isBoolean +exports.notBoolean = type.notBoolean +exports.isFunction = type.isFunction +exports.notFunction = type.notFunction +exports.isNumber = type.isNumber +exports.notNumber = type.notNumber +exports.isObject = type.isObject +exports.notObject = type.notObject +exports.isString = type.isString +exports.notString = type.notString +exports.isSymbol = type.isSymbol +exports.notSymbol = type.notSymbol +exports.exists = type.exists +exports.notExists = type.notExists +exports.isArray = type.isArray +exports.notArray = type.notArray +exports.is = type.is +exports.not = type.not - if (index < 0) return formatLineBreaks(Util.getStack(e)) - var re = /\r?\n/g +exports.equal = equal.equal +exports.notEqual = equal.notEqual +exports.equalLoose = equal.equalLoose +exports.notEqualLoose = equal.notEqualLoose +exports.deepEqual = equal.deepEqual +exports.notDeepEqual = equal.notDeepEqual +exports.match = equal.match +exports.notMatch = equal.notMatch +exports.atLeast = equal.atLeast +exports.atMost = equal.atMost +exports.above = equal.above +exports.below = equal.below +exports.between = equal.between +exports.closeTo = equal.closeTo +exports.notCloseTo = equal.notCloseTo - re.lastIndex = index + e.message.length - if (!re.test(stack)) return "" - return formatLineBreaks(stack.slice(re.lastIndex)) -} +exports.throws = throws.throws +exports.throwsMatch = throws.throwsMatch -function formatLineBreaks(str) { - return str.replace(/^\s+|[^\r\n\S]+$/g, "") - .replace(/\s*(\r?\n|\r)\s*/g, Settings.newline()) -} +exports.hasOwn = has.hasOwn +exports.notHasOwn = has.notHasOwn +exports.hasOwnLoose = has.hasOwnLoose +exports.notHasOwnLoose = has.notHasOwnLoose +exports.hasKey = has.hasKey +exports.notHasKey = has.notHasKey +exports.hasKeyLoose = has.hasKeyLoose +exports.notHasKeyLoose = has.notHasKeyLoose +exports.has = has.has +exports.notHas = has.notHas +exports.hasLoose = has.hasLoose +exports.notHasLoose = has.notHasLoose -exports.getStack = function (e) { - if (!(e instanceof Error)) return formatLineBreaks(Util.getStack(e)) - var description = (e.name + ": " + e.message) - .replace(/\s+$/gm, "") - .replace(/\r?\n|\r/g, Settings.newline()) - var stripped = readStack(e) +/** + * There's 2 sets of 12 permutations here for `includes` and `hasKeys`, instead + * of N sets of 2 (which would fit the `foo`/`notFoo` idiom better), so it's + * easier to just make a couple separate DSLs and use that to define everything. + * + * Here's the top level: + * + * - shallow + * - strict deep + * - structural deep + * + * And the second level: + * + * - includes all/not missing some + * - includes some/not missing all + * - not including all/missing some + * - not including some/missing all + * + * Here's an example using the naming scheme for `hasKeys*` + * + * | shallow | strict deep | structural deep + * --------------|-----------------|---------------------|---------------------- + * includes all | `hasKeys` | `hasKeysDeep` | `hasKeysMatch` + * includes some | `hasKeysAny` | `hasKeysAnyDeep` | `hasKeysAnyMatch` + * missing some | `notHasKeysAll` | `notHasKeysAllDeep` | `notHasKeysAllMatch` + * missing all | `notHasKeys` | `notHasKeysDeep` | `notHasKeysMatch` + * + * Note that the `hasKeys` shallow comparison variants are also overloaded to + * consume either an array (in which it simply checks against a list of keys) or + * an object (where it does a full deep comparison). + */ - if (stripped === "") return description - return description + Settings.newline() + stripped -} +exports.includes = includes.includes +exports.includesDeep = includes.includesDeep +exports.includesMatch = includes.includesMatch +exports.includesAny = includes.includesAny +exports.includesAnyDeep = includes.includesAnyDeep +exports.includesAnyMatch = includes.includesAnyMatch +exports.notIncludesAll = includes.notIncludesAll +exports.notIncludesAllDeep = includes.notIncludesAllDeep +exports.notIncludesAllMatch = includes.notIncludesAllMatch +exports.notIncludes = includes.notIncludes +exports.notIncludesDeep = includes.notIncludesDeep +exports.notIncludesMatch = includes.notIncludesMatch -var Colors = exports.Colors = Settings.Colors +exports.hasKeys = hasKeys.hasKeys +exports.hasKeysDeep = hasKeys.hasKeysDeep +exports.hasKeysMatch = hasKeys.hasKeysMatch +exports.hasKeysAny = hasKeys.hasKeysAny +exports.hasKeysAnyDeep = hasKeys.hasKeysAnyDeep +exports.hasKeysAnyMatch = hasKeys.hasKeysAnyMatch +exports.notHasKeysAll = hasKeys.notHasKeysAll +exports.notHasKeysAllDeep = hasKeys.notHasKeysAllDeep +exports.notHasKeysAllMatch = hasKeys.notHasKeysAllMatch +exports.notHasKeys = hasKeys.notHasKeys +exports.notHasKeysDeep = hasKeys.notHasKeysDeep +exports.notHasKeysMatch = hasKeys.notHasKeysMatch -// Color palette pulled from Mocha -function colorToNumber(name) { - switch (name) { - case "pass": return 90 - case "fail": return 31 +},{"./lib/equal":34,"./lib/has":36,"./lib/has-keys":35,"./lib/includes":37,"./lib/throws":38,"./lib/type":39,"clean-assert-util":32}],34:[function(require,module,exports){ +"use strict" - case "bright pass": return 92 - case "bright fail": return 91 - case "bright yellow": return 93 +var match = require("clean-match") +var util = require("clean-assert-util") - case "skip": return 36 - case "suite": return 0 - case "plain": return 0 +function binary(numeric, comparator, message) { + return function (actual, expected) { + if (numeric) { + if (typeof actual !== "number") { + throw new TypeError("`actual` must be a number") + } - case "error title": return 0 - case "error message": return 31 - case "error stack": return 90 + if (typeof expected !== "number") { + throw new TypeError("`expected` must be a number") + } + } - case "checkmark": return 32 - case "fast": return 90 - case "medium": return 33 - case "slow": return 31 - case "green": return 32 - case "light": return 90 - - case "diff gutter": return 90 - case "diff added": return 32 - case "diff removed": return 31 - default: throw new TypeError("Invalid name: \"" + name + "\"") + if (!comparator(actual, expected)) { + util.fail(message, {actual: actual, expected: expected}) + } } } -exports.color = color -function color(name, str) { - if (Colors.supported()) { - return "\u001b[" + colorToNumber(name) + "m" + str + "\u001b[0m" - } else { - return str + "" - } -} +exports.equal = binary(false, + function (a, b) { return util.strictIs(a, b) }, + "Expected {actual} to equal {expected}") -exports.setColor = function (_) { - if (_.opts.color != null) Colors.maybeSet(_.opts.color) -} +exports.notEqual = binary(false, + function (a, b) { return !util.strictIs(a, b) }, + "Expected {actual} to not equal {expected}") -exports.unsetColor = function (_) { - if (_.opts.color != null) Colors.maybeRestore() -} +exports.equalLoose = binary(false, + function (a, b) { return util.looseIs(a, b) }, + "Expected {actual} to loosely equal {expected}") -var Status = exports.Status = Object.freeze({ - Unknown: 0, - Skipped: 1, - Passing: 2, - Failing: 3, -}) +exports.notEqualLoose = binary(false, + function (a, b) { return !util.looseIs(a, b) }, + "Expected {actual} to not loosely equal {expected}") -exports.Tree = function (value) { - this.value = value - this.status = Status.Unknown - this.children = Object.create(null) -} +exports.atLeast = binary(true, + function (a, b) { return a >= b }, + "Expected {actual} to be at least {expected}") -exports.defaultify = function (_, opts, prop) { - if (_.methods.accepts.indexOf(prop) >= 0) { - var used = opts != null && typeof opts[prop] === "function" - ? opts - : Settings.defaultOpts() +exports.atMost = binary(true, + function (a, b) { return a <= b }, + "Expected {actual} to be at most {expected}") - _.opts[prop] = function () { - return Promise.resolve(used[prop].apply(used, arguments)) - } +exports.above = binary(true, + function (a, b) { return a > b }, + "Expected {actual} to be above {expected}") + +exports.below = binary(true, + function (a, b) { return a < b }, + "Expected {actual} to be below {expected}") + +exports.between = function (actual, lower, upper) { + if (typeof actual !== "number") { + throw new TypeError("`actual` must be a number") } -} -function joinPath(reportPath) { - var path = "" + if (typeof lower !== "number") { + throw new TypeError("`lower` must be a number") + } - for (var i = 0; i < reportPath.length; i++) { - path += " " + reportPath[i].name + if (typeof upper !== "number") { + throw new TypeError("`upper` must be a number") } - return path.slice(1) + // The negation is to address NaNs as well, without writing a ton of special + // case boilerplate + if (!(actual >= lower && actual <= upper)) { + util.fail("Expected {actual} to be between {lower} and {upper}", { + actual: actual, + lower: lower, + upper: upper, + }) + } } -exports.joinPath = function (report) { - return joinPath(report.path) -} +exports.deepEqual = binary(false, + function (a, b) { return match.strict(a, b) }, + "Expected {actual} to deeply equal {expected}") -exports.speed = function (report) { - if (report.duration >= report.slow) return "slow" - if (report.duration >= report.slow / 2) return "medium" - if (report.duration >= 0) return "fast" - throw new RangeError("Duration must not be negative") +exports.notDeepEqual = binary(false, + function (a, b) { return !match.strict(a, b) }, + "Expected {actual} to not deeply equal {expected}") + +exports.match = binary(false, + function (a, b) { return match.loose(a, b) }, + "Expected {actual} to match {expected}") + +exports.notMatch = binary(false, + function (a, b) { return !match.loose(a, b) }, + "Expected {actual} to not match {expected}") + +// Uses division to allow for a more robust comparison of floats. Also, this +// handles near-zero comparisons correctly, as well as a zero tolerance (i.e. +// exact comparison). +function closeTo(expected, actual, tolerance) { + if (tolerance === Infinity || actual === expected) return true + if (tolerance === 0) return false + if (actual === 0) return Math.abs(expected) < tolerance + if (expected === 0) return Math.abs(actual) < tolerance + return Math.abs(expected / actual - 1) < tolerance } -exports.formatTime = (function () { - var s = 1000 /* ms */ - var m = 60 * s - var h = 60 * m - var d = 24 * h +// Note: these two always fail when dealing with NaNs. +exports.closeTo = function (expected, actual, tolerance) { + if (typeof actual !== "number") { + throw new TypeError("`actual` must be a number") + } - return function (ms) { - if (ms >= d) return Math.round(ms / d) + "d" - if (ms >= h) return Math.round(ms / h) + "h" - if (ms >= m) return Math.round(ms / m) + "m" - if (ms >= s) return Math.round(ms / s) + "s" - return ms + "ms" + if (typeof expected !== "number") { + throw new TypeError("`expected` must be a number") } -})() -exports.formatRest = function (report) { - if (!report.isHook) return "" - var path = " (" + if (tolerance == null) tolerance = 1e-10 - if (report.rootPath.length) { - path += report.stage - if (report.name) path += " ‒ " + report.name - if (report.path.length > report.rootPath.length + 1) { - path += ", in " + joinPath(report.rootPath) - } - } else { - path += "global " + report.stage - if (report.name) path += " ‒ " + report.name + if (typeof tolerance !== "number" || tolerance < 0) { + throw new TypeError( + "`tolerance` must be a non-negative number if given") } - return path + ")" + if (actual !== actual || expected !== expected || // eslint-disable-line no-self-compare, max-len + !closeTo(expected, actual, tolerance)) { + util.fail("Expected {actual} to be close to {expected}", { + actual: actual, + expected: expected, + }) + } } -},{"../settings":26,"../util":27}],26:[function(require,module,exports){ -"use strict" +exports.notCloseTo = function (expected, actual, tolerance) { + if (typeof actual !== "number") { + throw new TypeError("`actual` must be a number") + } -// General CLI and reporter settings. If something needs to + if (typeof expected !== "number") { + throw new TypeError("`expected` must be a number") + } -var Console = require("./replaced/console") + if (tolerance == null) tolerance = 1e-10 -var windowWidth = Console.windowWidth -var newline = Console.newline -var Symbols = Console.Symbols -var defaultOpts = Console.defaultOpts + if (typeof tolerance !== "number" || tolerance < 0) { + throw new TypeError( + "`tolerance` must be a non-negative number if given") + } -exports.windowWidth = function () { return windowWidth } -exports.newline = function () { return newline } -exports.symbols = function () { return Symbols } -exports.defaultOpts = function () { return defaultOpts } + if (expected !== expected || actual !== actual || // eslint-disable-line no-self-compare, max-len + closeTo(expected, actual, tolerance)) { + util.fail("Expected {actual} to not be close to {expected}", { + actual: actual, + expected: expected, + }) + } +} -exports.setWindowWidth = function (value) { return windowWidth = value } -exports.setNewline = function (value) { return newline = value } -exports.setSymbols = function (value) { return Symbols = value } -exports.setDefaultOpts = function (value) { return defaultOpts = value } +},{"clean-assert-util":32,"clean-match":40}],35:[function(require,module,exports){ +"use strict" -// Console.colorSupport is a mask with the following bits: -// 0x1 - if set, colors supported by default -// 0x2 - if set, force color support -// -// This is purely an implementation detail, and is invisible to the outside -// world. -var colorSupport = Console.colorSupport -var mask = colorSupport +var match = require("clean-match") +var util = require("clean-assert-util") +var hasOwn = Object.prototype.hasOwnProperty -exports.Colors = { - supported: function () { - return (mask & 0x1) !== 0 - }, +function hasKeys(all, object, keys) { + for (var i = 0; i < keys.length; i++) { + var test = hasOwn.call(object, keys[i]) - forced: function () { - return (mask & 0x2) !== 0 - }, + if (test !== all) return !all + } - maybeSet: function (value) { - if ((mask & 0x2) === 0) mask = value ? 0x1 : 0 - }, + return all +} - maybeRestore: function () { - if ((mask & 0x2) === 0) mask = colorSupport & 0x1 - }, +function hasValues(func, all, object, keys) { + if (object === keys) return true + var list = Object.keys(keys) - // Only for debugging - forceSet: function (value) { - mask = value ? 0x3 : 0x2 - }, + for (var i = 0; i < list.length; i++) { + var key = list[i] + var test = hasOwn.call(object, key) && func(keys[key], object[key]) - forceRestore: function () { - mask = colorSupport - }, + if (test !== all) return test + } - getSupport: function () { - return { - supported: (colorSupport & 0x1) !== 0, - forced: (colorSupport & 0x2) !== 0, - } - }, - - setSupport: function (opts) { - mask = colorSupport = - (opts.supported ? 0x1 : 0) | (opts.forced ? 0x2 : 0) - }, -} - -},{"./replaced/console":20}],27:[function(require,module,exports){ -"use strict" - -var methods = require("./methods") - -exports.getType = function (value) { - if (value == null) return "null" - if (Array.isArray(value)) return "array" - return typeof value + return all } -// PhantomJS, IE, and possibly Edge don't set the stack trace until the error is -// thrown. Note that this prefers an existing stack first, since non-native -// errors likely already contain this. Note that this isn't necessary in the -// CLI - that only targets Node. -exports.getStack = function (e) { - var stack = e.stack +function makeHasOverload(all, invert, message) { + return function (object, keys) { + if (typeof object !== "object" || object == null) { + throw new TypeError("`object` must be an object") + } - if (!(e instanceof Error) || stack != null) return stack + if (typeof keys !== "object" || keys == null) { + throw new TypeError("`keys` must be an object or array") + } - try { - throw e - } catch (e) { - return e.stack + if (Array.isArray(keys)) { + if (keys.length && hasKeys(all, object, keys) === invert) { + util.fail(message, {actual: object, keys: keys}) + } + } else if (Object.keys(keys).length) { + if (hasValues(util.strictIs, all, object, keys) === invert) { + util.fail(message, {actual: object, keys: keys}) + } + } } } -exports.pcall = function (func) { - return new Promise(function (resolve, reject) { - return func(function (e, value) { - return e != null ? reject(e) : resolve(value) - }) - }) -} +function makeHasKeys(func, all, invert, message) { + return function (object, keys) { + if (typeof object !== "object" || object == null) { + throw new TypeError("`object` must be an object") + } -exports.peach = function (list, func) { - var len = list.length - var p = Promise.resolve() + if (typeof keys !== "object" || keys == null) { + throw new TypeError("`keys` must be an object") + } - for (var i = 0; i < len; i++) { - p = p.then(func.bind(undefined, list[i], i)) + // exclusive or to invert the result if `invert` is true + if (Object.keys(keys).length) { + if (hasValues(func, all, object, keys) === invert) { + util.fail(message, {actual: object, keys: keys}) + } + } } - - return p -} - -/** - * A lazy accessor, complete with thrown error memoization and a decent amount - * of optimization, since it's used in a lot of code. - * - * Note that this uses reference indirection and direct mutation to keep only - * just the computation non-constant, so engines can avoid closure allocation. - * Also, `create` is intentionally kept *out* of any closure, so it can be more - * easily collected. - */ -function Lazy(create) { - this.value = create - this.get = this.init } -methods(Lazy, { - recursive: function () { - throw new TypeError("Lazy functions must not be called recursively!") - }, +/* eslint-disable max-len */ - return: function () { - return this.value - }, +exports.hasKeys = makeHasOverload(true, false, "Expected {actual} to have all keys in {keys}") +exports.hasKeysDeep = makeHasKeys(match.strict, true, false, "Expected {actual} to have all keys in {keys}") +exports.hasKeysMatch = makeHasKeys(match.loose, true, false, "Expected {actual} to match all keys in {keys}") +exports.hasKeysAny = makeHasOverload(false, false, "Expected {actual} to have any key in {keys}") +exports.hasKeysAnyDeep = makeHasKeys(match.strict, false, false, "Expected {actual} to have any key in {keys}") +exports.hasKeysAnyMatch = makeHasKeys(match.loose, false, false, "Expected {actual} to match any key in {keys}") +exports.notHasKeysAll = makeHasOverload(true, true, "Expected {actual} to not have all keys in {keys}") +exports.notHasKeysAllDeep = makeHasKeys(match.strict, true, true, "Expected {actual} to not have all keys in {keys}") +exports.notHasKeysAllMatch = makeHasKeys(match.loose, true, true, "Expected {actual} to not match all keys in {keys}") +exports.notHasKeys = makeHasOverload(false, true, "Expected {actual} to not have any key in {keys}") +exports.notHasKeysDeep = makeHasKeys(match.strict, false, true, "Expected {actual} to not have any key in {keys}") +exports.notHasKeysMatch = makeHasKeys(match.loose, false, true, "Expected {actual} to not match any key in {keys}") - throw: function () { - throw this.value - }, +},{"clean-assert-util":32,"clean-match":40}],36:[function(require,module,exports){ +"use strict" - init: function () { - this.get = this.recursive +var util = require("clean-assert-util") +var hasOwn = Object.prototype.hasOwnProperty - try { - this.value = (0, this.value)() - this.get = this.return - return this.value - } catch (e) { - this.value = e - this.get = this.throw - throw this.value +function has(_) { // eslint-disable-line max-len, max-params + return function (object, key, value) { + if (arguments.length >= 3) { + if (!_.has(object, key) || + !util.strictIs(_.get(object, key), value)) { + util.fail(_.messages[0], { + expected: value, + actual: object[key], + key: key, + object: object, + }) + } + } else if (!_.has(object, key)) { + util.fail(_.messages[1], { + expected: value, + actual: object[key], + key: key, + object: object, + }) } - }, -}) - -exports.lazy = function (create) { - var ref = new Lazy(create) - - return function () { - return ref.get() } } -},{"./methods":19}],28:[function(require,module,exports){ -(function (global){ -"use strict" - -// To suppress deprecation messages -var suppressDeprecation = true - -exports.showDeprecation = function () { - suppressDeprecation = false -} - -exports.hideDeprecation = function () { - suppressDeprecation = true -} - -var console = global.console -var shouldPrint = console != null && typeof console.warn === "function" && - !(global.process != null && global.process.env != null && - global.process.env.NO_MIGRATE_WARN) - -exports.warn = function () { - if (shouldPrint && !suppressDeprecation) { - console.warn.apply(console, arguments) +function hasLoose(_) { + return function (object, key, value) { + if (!_.has(object, key) || !util.looseIs(_.get(object, key), value)) { + util.fail(_.messages[0], { + expected: value, + actual: object[key], + key: key, + object: object, + }) + } } } -exports.deprecate = function (message, func) { - var printed = !shouldPrint - - /** @this */ - return function () { - if (!suppressDeprecation) { - if (!printed) { - printed = true - console.trace() - console.warn(message) +function notHas(_) { // eslint-disable-line max-len, max-params + return function (object, key, value) { + if (arguments.length >= 3) { + if (_.has(object, key) && + util.strictIs(_.get(object, key), value)) { + util.fail(_.messages[2], { + expected: value, + actual: object[key], + key: key, + object: object, + }) } - - message = undefined + } else if (_.has(object, key)) { + util.fail(_.messages[3], { + expected: value, + actual: object[key], + key: key, + object: object, + }) } + } +} - return func.apply(this, arguments) +function notHasLoose(_) { // eslint-disable-line max-len, max-params + return function (object, key, value) { + if (_.has(object, key) && util.looseIs(_.get(object, key), value)) { + util.fail(_.messages[2], { + expected: value, + actual: object[key], + key: key, + object: object, + }) + } } } -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +function hasOwnKey(object, key) { return hasOwn.call(object, key) } +function hasInKey(object, key) { return key in object } +function hasInColl(object, key) { return object.has(key) } +function hasObjectGet(object, key) { return object[key] } +function hasCollGet(object, key) { return object.get(key) } -},{}],29:[function(require,module,exports){ -"use strict" +function createHas(has, get, messages) { + return {has: has, get: get, messages: messages} +} -/** - * Backport wrapper to warn about most of the major breaking changes from the - * last major version, and to help me keep track of all the changes. - * - * It consists of solely internal monkey patching to revive support of previous - * versions, although I tried to limit how much knowledge of the internals this - * requires. - */ +var hasOwnMethods = createHas(hasOwnKey, hasObjectGet, [ + "Expected {object} to have own key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len + "Expected {actual} to have own key {expected}", + "Expected {object} to not have own key {key} equal to {actual}", + "Expected {actual} to not have own key {expected}", +]) -var Common = require("./common") -var Internal = require("../internal") -var methods = require("../lib/methods") -var Report = require("../lib/core/reports").Report -var Reflect = require("../lib/api/reflect") -var Thallium = require("../lib/api/thallium") - -var assert = require("clean-assert") - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - `reflect.checkInit()` is deprecated in favor of `reflect.locked` and * - * either complaining yourself or just using `reflect.current` to add * - * things. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -methods(Reflect, { - checkInit: Common.deprecate( - "`reflect.checkInit` is deprecated. Use `reflect.current` for the " + - "current test or use `reflect.locked` and create and throw the error " + - "yourself.", - /** @this */ function () { - if (this.locked) { - throw new ReferenceError("It is only safe to call test " + - "methods during initialization") - } - }), -}) +var hasKeyMethods = createHas(hasInKey, hasObjectGet, [ + "Expected {object} to have key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len + "Expected {actual} to have key {expected}", + "Expected {object} to not have key {key} equal to {actual}", + "Expected {actual} to not have key {expected}", +]) -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - `t.async` -> `t.test`, which now supports promises. * - * - All tests are now async. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +var hasMethods = createHas(hasInColl, hasCollGet, [ + "Expected {object} to have key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len + "Expected {actual} to have key {expected}", + "Expected {object} to not have key {key} equal to {actual}", + "Expected {actual} to not have key {expected}", +]) -var test = Thallium.prototype.test +exports.hasOwn = has(hasOwnMethods) +exports.notHasOwn = notHas(hasOwnMethods) +exports.hasOwnLoose = hasLoose(hasOwnMethods) +exports.notHasOwnLoose = notHasLoose(hasOwnMethods) -function runAsync(callback, t, resolve, reject) { - var resolved = false - var gen = callback.call(t, t, function (err) { - if (resolved) return - Common.warn("`t.async` is deprecated. " + - "Use `t.test` and return a promise instead.") +exports.hasKey = has(hasKeyMethods) +exports.notHasKey = notHas(hasKeyMethods) +exports.hasKeyLoose = hasLoose(hasKeyMethods) +exports.notHasKeyLoose = notHasLoose(hasKeyMethods) - resolved = true - if (err != null) reject(err) - else resolve() - }) +exports.has = has(hasMethods) +exports.notHas = notHas(hasMethods) +exports.hasLoose = hasLoose(hasMethods) +exports.notHasLoose = notHasLoose(hasMethods) - if (resolved) return +},{"clean-assert-util":32}],37:[function(require,module,exports){ +"use strict" - if (typeof gen.next !== "function") { - // Allow the migration path to standard thenables. - resolve(gen) - return - } +var match = require("clean-match") +var util = require("clean-assert-util") - Common.warn("`t.async` is deprecated. Use `t.test` and either return a " + - "promise or use `co`/ES2017 async functions instead.") +function includes(func, all, array, values) { + // Cheap cases first + if (!Array.isArray(array)) return false + if (array === values) return true + if (all && array.length < values.length) return false - // This is a modified version of the async-await official, non-normative - // desugaring helper, for better error checking and adapted to accept an - // already-instantiated iterator instead of a generator. - function iterate(next) { - // finished with success, resolve the promise - if (next.done) return Promise.resolve(next.value) + for (var i = 0; i < values.length; i++) { + var value = values[i] + var test = false - // not finished, chain off the yielded promise and step again - return Promise.resolve(next.value).then( - function (v) { return iterate(gen.next(v)) }, - function (e) { - if (typeof gen.throw === "function") { - return iterate(gen.throw(e)) - } else { - throw e - } - }) + for (var j = 0; j < array.length; j++) { + if (func(value, array[j])) { + test = true + break + } + } + + if (test !== all) return test } - iterate(gen.next(undefined)).then(resolve, reject) + return all } -methods(Thallium, { - async: function (name, callback) { - if (typeof callback !== "function") { - // Reuse the normal error handling. - return test.apply(this, arguments) - } else { - return test.call(this, name, function (t) { - return new Promise(function (resolve, reject) { - return runAsync(callback, t, resolve, reject) - }) - }) +function defineIncludes(func, all, invert, message) { + return function (array, values) { + if (!Array.isArray(array)) { + throw new TypeError("`array` must be an array") } - }, - - asyncSkip: Common.deprecate( - "`t.asyncSkip` is deprecated. Use `t.testSkip` instead.", - Thallium.prototype.testSkip), -}) - -methods(Reflect, { - get isAsync() { - Common.warn("Tests are now always async. You no longer need to " + - "handle the other case") - return true - }, -}) -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * `reflect.define`, `t.define`, `reflect.wrap`, and `reflect.add`, are all * - * removed. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + if (!Array.isArray(values)) values = [values] -function isLocked(method) { - return method === "_" || - method === "reflect" || - method === "only" || - method === "use" || - method === "reporter" || - method === "define" || - method === "timeout" || - method === "slow" || - method === "run" || - method === "test" || - method === "testSkip" || - method === "async" || - method === "asyncSkip" + if (values.length && includes(func, all, array, values) === invert) { + util.fail(message, {actual: array, values: values}) + } + } } -function getEnumerableSymbols(keys, object) { - var symbols = Object.getOwnPropertySymbols(object) - - for (var i = 0; i < symbols.length; i++) { - var sym = symbols[i] +/* eslint-disable max-len */ - if (Object.getOwnPropertyDescriptor(sym).enumerable) keys.push(sym) - } -} +exports.includes = defineIncludes(util.strictIs, true, false, "Expected {actual} to have all values in {values}") +exports.includesDeep = defineIncludes(match.strict, true, false, "Expected {actual} to match all values in {values}") +exports.includesMatch = defineIncludes(match.loose, true, false, "Expected {actual} to match all values in {values}") +exports.includesAny = defineIncludes(util.strictIs, false, false, "Expected {actual} to have any value in {values}") +exports.includesAnyDeep = defineIncludes(match.strict, false, false, "Expected {actual} to match any value in {values}") +exports.includesAnyMatch = defineIncludes(match.loose, false, false, "Expected {actual} to match any value in {values}") +exports.notIncludesAll = defineIncludes(util.strictIs, true, true, "Expected {actual} to not have all values in {values}") +exports.notIncludesAllDeep = defineIncludes(match.strict, true, true, "Expected {actual} to not match all values in {values}") +exports.notIncludesAllMatch = defineIncludes(match.loose, true, true, "Expected {actual} to not match all values in {values}") +exports.notIncludes = defineIncludes(util.strictIs, false, true, "Expected {actual} to not have any value in {values}") +exports.notIncludesDeep = defineIncludes(match.strict, false, true, "Expected {actual} to not match any value in {values}") +exports.notIncludesMatch = defineIncludes(match.loose, false, true, "Expected {actual} to not match any value in {values}") -// This handles name + func vs object with methods. -function iterateSetter(test, name, func, iterator) { - // Check both the name and function, so ES6 symbol polyfills (which use - // objects since it's impossible to fully polyfill primitives) work. - if (typeof name === "object" && name != null && func == null) { - var keys = Object.keys(name) +},{"clean-assert-util":32,"clean-match":40}],38:[function(require,module,exports){ +"use strict" - if (typeof Object.getOwnPropertySymbols === "function") { - getEnumerableSymbols(keys, name) - } +var util = require("clean-assert-util") - for (var i = 0; i < keys.length; i++) { - var key = keys[i] +function getName(func) { + var name = func.name - if (typeof name[key] !== "function") { - throw new TypeError("Expected body to be a function") - } + if (name == null) name = func.displayName + if (name) return util.escape(name) + return "" +} - test.methods[key] = iterator(test, key, name[key]) - } - } else { - if (typeof func !== "function") { - throw new TypeError("Expected body to be a function") - } +exports.throws = function (Type, callback) { + if (callback == null) { + callback = Type + Type = null + } - test.methods[name] = iterator(test, name, func) + if (Type != null && typeof Type !== "function") { + throw new TypeError("`Type` must be a function if passed") } -} -/** - * @this {State} - * Run `func` with `...args` when assertions are run, only if the test isn't - * skipped. This is immediately for block and async tests, but deferred for - * inline tests. It's useful for inline assertions. - */ -function attempt(func, a, b, c/* , ...args */) { - switch (arguments.length) { - case 0: throw new TypeError("unreachable") - case 1: func(); return - case 2: func(a); return - case 3: func(a, b); return - case 4: func(a, b, c); return - default: - var args = [] + if (typeof callback !== "function") { + throw new TypeError("`callback` must be a function") + } - for (var i = 1; i < arguments.length; i++) { - args.push(arguments[i]) + try { + callback() // eslint-disable-line callback-return + } catch (e) { + if (Type != null && !(e instanceof Type)) { + util.fail( + "Expected callback to throw an instance of " + getName(Type) + + ", but found {actual}", + {actual: e}) } - - func.apply(undefined, args) + return } + + throw new util.AssertionError("Expected callback to throw") } -function defineAssertion(test, name, func) { - // Don't let native methods get overridden by assertions - if (isLocked(name)) { - throw new RangeError("Method '" + name + "' is locked!") - } +function throwsMatchTest(matcher, e) { + if (typeof matcher === "string") return e.message === matcher + if (typeof matcher === "function") return !!matcher(e) + if (matcher instanceof RegExp) return !!matcher.test(e.message) - function run() { - var res = func.apply(undefined, arguments) + var keys = Object.keys(matcher) - if (typeof res !== "object" || res === null) { - throw new TypeError("Expected result to be an object") - } + for (var i = 0; i < keys.length; i++) { + var key = keys[i] - if (!res.test) { - assert.fail(res.message, res) - } + if (!(key in e) || !util.strictIs(matcher[key], e[key])) return false } - return /** @this */ function () { - var args = [run] + return true +} - args.push.apply(args, arguments) - attempt.apply(undefined, args) - return this - } +function isPlainObject(object) { + return object == null || Object.getPrototypeOf(object) === Object.prototype } -function wrapAssertion(test, name, func) { - // Don't let `reflect` and `_` change. - if (name === "reflect" || name === "_") { - throw new RangeError("Method '" + name + "' is locked!") +exports.throwsMatch = function (matcher, callback) { + if (typeof matcher !== "string" && + typeof matcher !== "function" && + !(matcher instanceof RegExp) && + !isPlainObject(matcher)) { + throw new TypeError( + "`matcher` must be a string, function, RegExp, or object") } - var old = test.methods[name] + if (typeof callback !== "function") { + throw new TypeError("`callback` must be a function") + } - if (typeof old !== "function") { - throw new TypeError( - "Expected t." + name + " to already be a function") + try { + callback() // eslint-disable-line callback-return + } catch (e) { + if (!throwsMatchTest(matcher, e)) { + util.fail( + "Expected callback to throw an error that matches " + + "{expected}, but found {actual}", + {expected: matcher, actual: e}) + } + return } - /** @this */ - function apply(a, b, c, d) { - switch (arguments.length) { - case 0: return func.call(this, old.bind(this)) - case 1: return func.call(this, old.bind(this), a) - case 2: return func.call(this, old.bind(this), a, b) - case 3: return func.call(this, old.bind(this), a, b, c) - case 4: return func.call(this, old.bind(this), a, b, c, d) - default: - var args = [old.bind(this)] + throw new util.AssertionError("Expected callback to throw.") +} - for (var i = 0; i < arguments.length; i++) { - args.push(arguments[i]) - } +},{"clean-assert-util":32}],39:[function(require,module,exports){ +"use strict" - return func.apply(this, args) - } - } +var util = require("clean-assert-util") - return /** @this */ function () { - var ret = apply.apply(this, arguments) +exports.ok = function (x) { + if (!x) util.fail("Expected {actual} to be truthy", {actual: x}) +} - return ret !== undefined ? ret : this - } +exports.notOk = function (x) { + if (x) util.fail("Expected {actual} to be falsy", {actual: x}) } -function addAssertion(test, name, func) { - if (typeof test.methods[name] !== "undefined") { - throw new TypeError("Method '" + name + "' already exists!") +exports.isBoolean = function (x) { + if (typeof x !== "boolean") { + util.fail("Expected {actual} to be a boolean", {actual: x}) } +} - /** @this */ - function apply(a, b, c, d) { - switch (arguments.length) { - case 0: return func.call(this, this) - case 1: return func.call(this, this, a) - case 2: return func.call(this, this, a, b) - case 3: return func.call(this, this, a, b, c) - case 4: return func.call(this, this, a, b, c, d) - default: - var args = [this] - - for (var i = 0; i < arguments.length; i++) { - args.push(arguments[i]) - } +exports.notBoolean = function (x) { + if (typeof x === "boolean") { + util.fail("Expected {actual} to not be a boolean", {actual: x}) + } +} - return func.apply(this, args) - } +exports.isFunction = function (x) { + if (typeof x !== "function") { + util.fail("Expected {actual} to be a function", {actual: x}) } +} - return /** @this */ function () { - var ret = apply.apply(this, arguments) +exports.notFunction = function (x) { + if (typeof x === "function") { + util.fail("Expected {actual} to not be a function", {actual: x}) + } +} - return ret !== undefined ? ret : this +exports.isNumber = function (x) { + if (typeof x !== "number") { + util.fail("Expected {actual} to be a number", {actual: x}) } } -methods(Reflect, { - define: Common.deprecate( - "`reflect.define` is deprecated. Use external methods or direct assignment instead.", // eslint-disable-line max-len - /** @this */ function (name, func) { - iterateSetter(this._.current.value, name, func, defineAssertion) - }), - - wrap: Common.deprecate( - "`reflect.wrap` is deprecated. Use external methods or direct assignment instead.", // eslint-disable-line max-len - /** @this */ function (name, func) { - iterateSetter(this._.current.value, name, func, wrapAssertion) - }), - - add: Common.deprecate( - "`reflect.add` is deprecated. Use external methods or direct assignment instead.", // eslint-disable-line max-len - /** @this */ function (name, func) { - iterateSetter(this._.current.value, name, func, addAssertion) - }), -}) +exports.notNumber = function (x) { + if (typeof x === "number") { + util.fail("Expected {actual} to not be a number", {actual: x}) + } +} -methods(Thallium, { - define: Common.deprecate( - "`t.define` is deprecated. Use external methods or direct assignment instead.", // eslint-disable-line max-len - /** @this */ function (name, func) { - iterateSetter(this._.current.value, name, func, defineAssertion) - return this - }), -}) +exports.isObject = function (x) { + if (typeof x !== "object" || x == null) { + util.fail("Expected {actual} to be an object", {actual: x}) + } +} -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - `reflect.do` is deprecated, with no replacement (inline tests are also * - * deprecated). * - * - `reflect.base` -> `internal.root` * - * - `reflect.AssertionError` -> `assert.AssertionError`. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +exports.notObject = function (x) { + if (typeof x === "object" && x != null) { + util.fail("Expected {actual} to not be an object", {actual: x}) + } +} -methods(Reflect, { - // Deprecated aliases - do: Common.deprecate( - "`reflect.do` is deprecated. Transition to block tests, if necessary, and run the code directly.", // eslint-disable-line max-len - /** @this */ function (func) { - if (typeof func !== "function") { - throw new TypeError("Expected callback to be a function") - } +exports.isString = function (x) { + if (typeof x !== "string") { + util.fail("Expected {actual} to be a string", {actual: x}) + } +} - attempt.apply(undefined, arguments) - return this - }), - base: Common.deprecate( - "`reflect.base` is deprecated. Use `internal.root` from `thallium/internal` instead.", // eslint-disable-line max-len - Internal.root), -}) +exports.notString = function (x) { + if (typeof x === "string") { + util.fail("Expected {actual} to not be a string", {actual: x}) + } +} -// ESLint oddly can't tell these are shadowed. -/* eslint-disable no-extend-native */ +exports.isSymbol = function (x) { + if (typeof x !== "symbol") { + util.fail("Expected {actual} to be a symbol", {actual: x}) + } +} -function lockError(AssertionError) { - Object.defineProperty(Reflect.prototype, "AssertionError", { - writable: true, - value: AssertionError, - }) - return AssertionError -} - -Object.defineProperty(Reflect.prototype, "AssertionError", { - configurable: true, - enumerable: false, - get: Common.deprecate( - "`reflect.AssertionError` is deprecated. Use `assert.AssertionError` from `thallium/assert` instead.", // eslint-disable-line max-len - function () { return lockError(assert.AssertionError) }), - set: Common.deprecate( - "`reflect.AssertionError` is deprecated. Use `assert.AssertionError` from `thallium/assert` instead.", // eslint-disable-line max-len - lockError), -}) +exports.notSymbol = function (x) { + if (typeof x === "symbol") { + util.fail("Expected {actual} to not be a symbol", {actual: x}) + } +} -/* eslint-enable no-extend-native */ +exports.exists = function (x) { + if (x == null) { + util.fail("Expected {actual} to exist", {actual: x}) + } +} -methods(Thallium, { - base: Common.deprecate( - "`t.base` is deprecated. Use `t.create` instead.", - function () { return new Thallium() }), -}) +exports.notExists = function (x) { + if (x != null) { + util.fail("Expected {actual} to not exist", {actual: x}) + } +} -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - assertions defined on main export * - * - `t.*` assertions -> `assert.*` (some renamed) from `thallium/assert` * - * - `t.true`/etc. are gone (except `t.undefined` -> `assert.isUndefined`) * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -Common.hideDeprecation() -require("../assertions")(require("../index")) -Common.showDeprecation() - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * `extra` events are no longer a thing. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -methods(Report, { - get isInline() { - Common.warn("`extra` events no longer exist. You no longer need to " + - "handle them") - return false - }, -}) +exports.isArray = function (x) { + if (!Array.isArray(x)) { + util.fail("Expected {actual} to be an array", {actual: x}) + } +} -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - `t.reflect` and `t.use` -> non-caching `t.call` * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -var call = Thallium.prototype.call +exports.notArray = function (x) { + if (Array.isArray(x)) { + util.fail("Expected {actual} to not be an array", {actual: x}) + } +} -function id(x) { return x } +exports.is = function (Type, object) { + if (typeof Type !== "function") { + throw new TypeError("`Type` must be a function") + } -methods(Thallium, { - reflect: Common.deprecate( - "`t.reflect` is deprecated. Use `t.call` instead.", - /** @this */ function () { return call.call(this, id) }), + if (!(object instanceof Type)) { + util.fail("Expected {object} to be an instance of {expected}", { + expected: Type, + actual: object.constructor, + object: object, + }) + } +} - use: Common.deprecate( - "`t.use` is deprecated. Use `t.call` instead.", - /** @this */ function () { - var reflect = call.call(this, id) +exports.not = function (Type, object) { + if (typeof Type !== "function") { + throw new TypeError("`Type` must be a function") + } - if (!reflect.skipped) { - var test = this._.current.value + if (object instanceof Type) { + util.fail("Expected {object} to not be an instance of {expected}", { + expected: Type, + object: object, + }) + } +} - for (var i = 0; i < arguments.length; i++) { - var plugin = arguments[i] +},{"clean-assert-util":32}],40:[function(require,module,exports){ +(function (global){ +/** + * @license + * clean-match + * + * A simple, fast ES2015+ aware deep matching utility. + * + * Copyright (c) 2016 and later, Isiah Meadows . + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ - if (typeof plugin !== "function") { - throw new TypeError( - "Expected `plugin` to be a function") - } +/* eslint-disable */ +;(function (global, factory) { + if (typeof exports === "object" && exports != null) { + factory(global, exports) + } else if (typeof define === "function") { + define("clean-match", ["exports"], function (exports) { + factory(global, exports) + }) + } else { + factory(global, global.match = {}) + } +})(typeof global === "object" && global !== null ? global + : typeof self === "object" && self !== null ? self + : typeof window === "object" && window !== null ? window + : this, +function (global, exports) { + /* eslint-enable */ + "use strict" - if (test.plugins == null) test.plugins = [] - if (test.plugins.indexOf(plugin) === -1) { - // Add plugin before calling it. - test.plugins.push(plugin) - plugin.call(this, this) - } - } - } + /* global Symbol, Uint8Array, DataView, ArrayBuffer, ArrayBufferView, Map, + Set */ - return this - }), -}) + /** + * Deep matching algorithm, with zero dependencies. Note the following: + * + * - This is relatively performance-tuned, although it prefers high + * correctness. Patch with care, since performance is a concern. + * - This does pack a *lot* of features, which should explain the length. + * - Some of the duplication is intentional. It's generally commented, but + * it's mainly for performance, since the engine needs its type info. + * - Polyfilled core-js Symbols from cross-origin contexts will never + * register as being actual Symbols. + * + * And in case you're wondering about the longer functions and occasional + * repetition, it's because V8's inliner isn't always intelligent enough to + * deal with the super highly polymorphic data this often deals with, and JS + * doesn't have compile-time macros. + */ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * - `reflect.report` -> `internal.report.*` * - * - `reflect.loc` -> `internal.location` * - * - `reflect.scheduler` obsoleted. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + var objectToString = Object.prototype.toString + var hasOwn = Object.prototype.hasOwnProperty -var reports = Internal.reports + var supportsUnicode = hasOwn.call(RegExp.prototype, "unicode") + var supportsSticky = hasOwn.call(RegExp.prototype, "sticky") -methods(Reflect, { - report: Common.deprecate( - "`reflect.report` is deprecated. Use `internal.report.*` from `thallium/internal` instead.", // eslint-disable-line max-len - function (type, path, value, duration, slow) { // eslint-disable-line max-params, max-len - if (typeof type !== "string") { - throw new TypeError("Expected `type` to be a string") - } + // Legacy engines have several issues when it comes to `typeof`. + var isFunction = (function () { + function SlowIsFunction(value) { + if (value == null) return false - switch (type) { - case "start": return reports.start() - case "enter": return reports.enter(path, duration, slow) - case "leave": return reports.leave(path) - case "pass": return reports.pass(path, duration, slow) - case "fail": return reports.fail(path, value, duration, slow) - case "skip": return reports.skip(path) - case "end": return reports.end() - case "error": return reports.error(value) - case "hook": return reports.hook(path, value) - default: throw new RangeError("Unknown report `type`: " + type) - } - }), + var tag = objectToString.call(value) + + return tag === "[object Function]" || + tag === "[object GeneratorFunction]" || + tag === "[object AsyncFunction]" || + tag === "[object Proxy]" + } - loc: Common.deprecate( - "`reflect.loc` is deprecated. Use `internal.location` from `thallium/internal` instead.", // eslint-disable-line max-len - Internal.location), + function isPoisoned(object) { + return object != null && typeof object !== "function" + } - scheduler: Common.deprecate( - "`reflect.scheduler` is deprecated. It is no longer useful to the library, and can be safely removed.", // eslint-disable-line max-len - function () {}), -}) + // In Safari 10, `typeof Proxy === "object"` + if (isPoisoned(global.Proxy)) return SlowIsFunction -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Inline tests are deprecated. This is "fixed" by just throwing, since it's * - * hard to patch back in and easy to fix on the user's end. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -methods(Thallium, { - test: function (name, func) { - if (func == null) { - // Catch this particular case, to throw with a more informative - // messsage. - throw new TypeError( - "Inline tests are deprecated. Use block tests instead.") + // In Safari 8, several typed array constructors are + // `typeof C === "object"` + if (isPoisoned(global.Int8Array)) return SlowIsFunction + + // In old V8, RegExps are callable + if (typeof /x/ === "function") return SlowIsFunction // eslint-disable-line + + // Leave this for normal things. It's easily inlined. + return function isFunction(value) { + return typeof value === "function" } + })() - return test.apply(this, arguments) - }, -}) + // Set up our own buffer check. We should always accept the polyfill, even + // in Node. Note that it uses `global.Buffer` to avoid including `buffer` in + // the bundle. -methods(Reflect, { - get isInline() { - Common.warn("Tests are now never inline. You no longer need to " + - "handle this case") - return false - }, -}) + var BufferNative = 0 + var BufferPolyfill = 1 + var BufferSafari = 2 -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * `reflect.methods` -> `reflect.current` and using new `reflect` methods * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -methods(Reflect, { - get methods() { - Common.warn("`reflect.methods` is deprecated. Use `reflect.current`, " + - "the return value of `t.call`, and the appropriate new `reflect` " + - "methods instead") - return this._.methods - }, -}) + var bufferSupport = (function () { + function FakeBuffer() {} + FakeBuffer.isBuffer = function () { return true } -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * `reflect.reporters` -> `reflect.hasReporter` * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -methods(Reflect, { - get reporters() { - Common.warn("`reflect.reporters` is deprecated. Use " + - "`reflect.hasReporter` instead to check for existence of a " + - "reporter.") - return this._.methods - }, -}) + // Only Safari 5-7 has ever had this issue. + if (new FakeBuffer().constructor !== FakeBuffer) return BufferSafari + if (!isFunction(global.Buffer)) return BufferPolyfill + if (!isFunction(global.Buffer.isBuffer)) return BufferPolyfill + // Avoid global polyfills + if (global.Buffer.isBuffer(new FakeBuffer())) return BufferPolyfill + return BufferNative + })() -},{"../assertions":2,"../index":4,"../internal":5,"../lib/api/reflect":7,"../lib/api/thallium":8,"../lib/core/reports":11,"../lib/methods":19,"./common":28,"clean-assert":34}],30:[function(require,module,exports){ -module.exports = function (xs, f) { - if (xs.map) return xs.map(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - var x = xs[i]; - if (hasOwn.call(xs, i)) res.push(f(x, i, xs)); + var globalIsBuffer = bufferSupport === BufferNative + ? global.Buffer.isBuffer + : undefined + + function isBuffer(object) { + if (bufferSupport === BufferNative && globalIsBuffer(object)) { + return true + } else if (bufferSupport === BufferSafari && object._isBuffer) { + return true + } + + var B = object.constructor + + if (!isFunction(B)) return false + if (!isFunction(B.isBuffer)) return false + return B.isBuffer(object) } - return res; -}; -var hasOwn = Object.prototype.hasOwnProperty; + // core-js' symbols are objects, and some old versions of V8 erroneously had + // `typeof Symbol() === "object"`. + var symbolsAreObjects = isFunction(global.Symbol) && + typeof Symbol() === "object" -},{}],31:[function(require,module,exports){ -var hasOwn = Object.prototype.hasOwnProperty; + // `context` is a bit field, with the following bits. This is not as much + // for performance than to just reduce the number of parameters I need to be + // throwing around. + var Strict = 1 + var Initial = 2 + var SameProto = 4 -module.exports = function (xs, f, acc) { - var hasAcc = arguments.length >= 3; - if (hasAcc && xs.reduce) return xs.reduce(f, acc); - if (xs.reduce) return xs.reduce(f); - - for (var i = 0; i < xs.length; i++) { - if (!hasOwn.call(xs, i)) continue; - if (!hasAcc) { - acc = xs[i]; - hasAcc = true; - continue; - } - acc = f(acc, xs[i], i); + exports.loose = function (a, b) { + return match(a, b, Initial, undefined, undefined) } - return acc; -}; -},{}],32:[function(require,module,exports){ -"use strict" + exports.strict = function (a, b) { + return match(a, b, Strict | Initial, undefined, undefined) + } -// See https://github.com/substack/node-browserify/issues/1674 + // Feature-test delayed stack additions and extra keys. PhantomJS and IE + // both wait until the error was actually thrown first, and assign them as + // own properties, which is unhelpful for assertions. This returns a + // function to speed up cases where `Object.keys` is sufficient (e.g. in + // Chrome/FF/Node). + // + // This wouldn't be necessary if those engines would make the stack a + // getter, and record it when the error was created, not when it was thrown. + // It specifically filters out errors and only checks existing descriptors, + // just to keep the mess from affecting everything (it's not fully correct, + // but it's necessary). + var requiresProxy = (function () { + var test = new Error() + var old = Object.create(null) -module.exports = require("util-inspect") + Object.keys(test).forEach(function (key) { old[key] = true }) -},{"util-inspect":65}],33:[function(require,module,exports){ -"use strict" + try { + throw test + } catch (_) { + // ignore + } -var inspect = exports.inspect = require("./inspect") -var hasOwn = Object.prototype.hasOwnProperty -var AssertionError + return Object.keys(test).some(function (key) { return !old[key] }) + })() -// PhantomJS, IE, and possibly Edge don't set the stack trace until the error is -// thrown. Note that this prefers an existing stack first, since non-native -// errors likely already contain this. -function getStack(e) { - var stack = e.stack + function isIgnored(object, key) { + switch (key) { + case "line": if (typeof object.line !== "number") return false; break + case "sourceURL": + if (typeof object.sourceURL !== "string") return false; break + case "stack": if (typeof object.stack !== "string") return false; break + default: return false + } - if (!(e instanceof Error) || stack != null) return stack + var desc = Object.getOwnPropertyDescriptor(object, key) - try { - throw e - } catch (e) { - return e.stack + return !desc.configurable && desc.enumerable && !desc.writable } -} -try { - AssertionError = new Function([ // eslint-disable-line no-new-func - "'use strict';", - "class AssertionError extends Error {", - " constructor(message, expected, actual) {", - " super(message)", - " this.expected = expected", - " this.actual = actual", - " }", - "", - " get name() {", - " return 'AssertionError'", - " }", - "}", - // check native subclassing support - "new AssertionError('message', 1, 2)", - "return AssertionError", - ].join("\n"))() -} catch (e) { - AssertionError = typeof Error.captureStackTrace === "function" - ? function AssertionError(message, expected, actual) { - this.message = message || "" - this.expected = expected - this.actual = actual - Error.captureStackTrace(this, this.constructor) - } - : function AssertionError(message, expected, actual) { - this.message = message || "" - this.expected = expected - this.actual = actual - var e = new Error(message) + // This is only invoked with errors, so it's not going to present a + // significant slow down. + function getKeysStripped(object) { + var keys = Object.keys(object) + var count = 0 - e.name = "AssertionError" - this.stack = getStack(e) + for (var i = 0; i < keys.length; i++) { + if (!isIgnored(object, keys[i])) keys[count++] = keys[i] } - AssertionError.prototype = Object.create(Error.prototype) + keys.length = count + return keys + } - Object.defineProperty(AssertionError.prototype, "constructor", { - configurable: true, - writable: true, - enumerable: false, - value: AssertionError, - }) + // Way faster, since typed array indices are always dense and contain + // numbers. - Object.defineProperty(AssertionError.prototype, "name", { - configurable: true, - writable: true, - enumerable: false, - value: "AssertionError", - }) -} + // Setup for `isBufferOrView` and `isView` + var ArrayBufferNone = 0 + var ArrayBufferLegacy = 1 + var ArrayBufferCurrent = 2 -exports.AssertionError = AssertionError + var arrayBufferSupport = (function () { + if (!isFunction(global.Uint8Array)) return ArrayBufferNone + if (!isFunction(global.DataView)) return ArrayBufferNone + if (!isFunction(global.ArrayBuffer)) return ArrayBufferNone + if (isFunction(global.ArrayBuffer.isView)) return ArrayBufferCurrent + if (isFunction(global.ArrayBufferView)) return ArrayBufferLegacy + return ArrayBufferNone + })() -/* eslint-disable no-self-compare */ -// For better NaN handling -exports.strictIs = function (a, b) { - return a === b || a !== a && b !== b -} + // If typed arrays aren't supported (they weren't technically part of + // ES5, but many engines implemented Khronos' spec before ES6), then + // just fall back to generic buffer detection. -exports.looseIs = function (a, b) { - return a == b || a !== a && b !== b // eslint-disable-line eqeqeq -} + function floatIs(a, b) { + // So NaNs are considered equal. + return a === b || a !== a && b !== b // eslint-disable-line no-self-compare, max-len + } -/* eslint-enable no-self-compare */ + function matchView(a, b) { + var count = a.length -var templateRegexp = /(.?)\{(.+?)\}/g + if (count !== b.length) return false -exports.escape = function (string) { - if (typeof string !== "string") { - throw new TypeError("`string` must be a string") + while (count) { + count-- + if (!floatIs(a[count], b[count])) return false + } + + return true } - return string.replace(templateRegexp, function (m, pre) { - return pre + "\\" + m.slice(1) - }) -} + var isView = (function () { + if (arrayBufferSupport === ArrayBufferNone) return undefined + // ES6 typed arrays + if (arrayBufferSupport === ArrayBufferCurrent) return ArrayBuffer.isView + // legacy typed arrays + return function isView(object) { + return object instanceof ArrayBufferView + } + })() -// This formats the assertion error messages. -exports.format = function (message, args, prettify) { - if (prettify == null) prettify = inspect + // Support checking maps and sets deeply. They are object-like enough to + // count, and are useful in their own right. The code is rather messy, but + // mainly to keep the order-independent checking from becoming insanely + // slow. + var supportsMap = isFunction(global.Map) + var supportsSet = isFunction(global.Set) - if (typeof message !== "string") { - throw new TypeError("`message` must be a string") - } + // One of the sets and both maps' keys are converted to arrays for faster + // handling. + function keyList(map) { + var list = new Array(map.size) + var i = 0 + var iter = map.keys() - if (typeof args !== "object" || args === null) { - throw new TypeError("`args` must be an object") - } + for (var next = iter.next(); !next.done; next = iter.next()) { + list[i++] = next.value + } - if (typeof prettify !== "function") { - throw new TypeError("`prettify` must be a function if passed") + return list } - return message.replace(templateRegexp, function (m, pre, prop) { - if (pre === "\\") { - return m.slice(1) - } else if (hasOwn.call(args, prop)) { - return pre + prettify(args[prop], {depth: 5}) - } else { - return pre + m + // The pair of arrays are aligned in a single O(n^2) operation (mod deep + // matching and rotation), adapting to O(n) when they're already aligned. + function matchKey(current, akeys, start, end, context, left, right) { // eslint-disable-line max-params, max-len + for (var i = start + 1; i < end; i++) { + var key = akeys[i] + + if (match(current, key, context, left, right)) { + // TODO: once engines actually optimize `copyWithin`, use that + // instead. It'll be much faster than this loop. + while (i > start) akeys[i] = akeys[--i] + akeys[i] = key + return true + } } - }) -} -exports.fail = function (message, args, prettify) { - if (args == null) throw new AssertionError(message) - throw new AssertionError( - exports.format(message, args, prettify), - args.expected, - args.actual) -} + return false + } -// The basic assert, like `assert.ok`, but gives you an optional message. -exports.assert = function (test, message) { - if (!test) throw new AssertionError(message) -} + function matchValues(a, b, akeys, bkeys, end, context, left, right) { // eslint-disable-line max-params, max-len + for (var i = 0; i < end; i++) { + if (!match(a.get(akeys[i]), b.get(bkeys[i]), + context, left, right)) { + return false + } + } -},{"./inspect":32}],34:[function(require,module,exports){ -"use strict" + return true + } -/** - * Core TDD-style assertions. These are done by a composition of DSLs, since - * there is *so* much repetition. Also, this is split into several namespaces to - * keep the file size manageable. - */ + // Possibly expensive order-independent key-value match. First, try to avoid + // it by conservatively assuming everything is in order - a cheap O(n) is + // always nicer than an expensive O(n^2). + function matchMap(a, b, context, left, right) { // eslint-disable-line max-params, max-len + var end = a.size + var akeys = keyList(a) + var bkeys = keyList(b) + var i = 0 -var util = require("clean-assert-util") -var type = require("./lib/type") -var equal = require("./lib/equal") -var throws = require("./lib/throws") -var has = require("./lib/has") -var includes = require("./lib/includes") -var hasKeys = require("./lib/has-keys") + while (i !== end && match(akeys[i], bkeys[i], context, left, right)) { + i++ + } -exports.AssertionError = util.AssertionError -exports.assert = util.assert -exports.fail = util.fail + if (i === end) { + return matchValues(a, b, akeys, bkeys, end, context, left, right) + } -exports.ok = type.ok -exports.notOk = type.notOk -exports.isBoolean = type.isBoolean -exports.notBoolean = type.notBoolean -exports.isFunction = type.isFunction -exports.notFunction = type.notFunction -exports.isNumber = type.isNumber -exports.notNumber = type.notNumber -exports.isObject = type.isObject -exports.notObject = type.notObject -exports.isString = type.isString -exports.notString = type.notString -exports.isSymbol = type.isSymbol -exports.notSymbol = type.notSymbol -exports.exists = type.exists -exports.notExists = type.notExists -exports.isArray = type.isArray -exports.notArray = type.notArray -exports.is = type.is -exports.not = type.not + // Don't compare the same key twice + if (!matchKey(bkeys[i], akeys, i, end, context, left, right)) { + return false + } -exports.equal = equal.equal -exports.notEqual = equal.notEqual -exports.equalLoose = equal.equalLoose -exports.notEqualLoose = equal.notEqualLoose -exports.deepEqual = equal.deepEqual -exports.notDeepEqual = equal.notDeepEqual -exports.match = equal.match -exports.notMatch = equal.notMatch -exports.atLeast = equal.atLeast -exports.atMost = equal.atMost -exports.above = equal.above -exports.below = equal.below -exports.between = equal.between -exports.closeTo = equal.closeTo -exports.notCloseTo = equal.notCloseTo + // If the above fails, while we're at it, let's sort them as we go, so + // the key order matches. + while (++i < end) { + var key = bkeys[i] -exports.throws = throws.throws -exports.throwsMatch = throws.throwsMatch - -exports.hasOwn = has.hasOwn -exports.notHasOwn = has.notHasOwn -exports.hasOwnLoose = has.hasOwnLoose -exports.notHasOwnLoose = has.notHasOwnLoose -exports.hasKey = has.hasKey -exports.notHasKey = has.notHasKey -exports.hasKeyLoose = has.hasKeyLoose -exports.notHasKeyLoose = has.notHasKeyLoose -exports.has = has.has -exports.notHas = has.notHas -exports.hasLoose = has.hasLoose -exports.notHasLoose = has.notHasLoose - -/** - * There's 2 sets of 12 permutations here for `includes` and `hasKeys`, instead - * of N sets of 2 (which would fit the `foo`/`notFoo` idiom better), so it's - * easier to just make a couple separate DSLs and use that to define everything. - * - * Here's the top level: - * - * - shallow - * - strict deep - * - structural deep - * - * And the second level: - * - * - includes all/not missing some - * - includes some/not missing all - * - not including all/missing some - * - not including some/missing all - * - * Here's an example using the naming scheme for `hasKeys*` - * - * | shallow | strict deep | structural deep - * --------------|-----------------|---------------------|---------------------- - * includes all | `hasKeys` | `hasKeysDeep` | `hasKeysMatch` - * includes some | `hasKeysAny` | `hasKeysAnyDeep` | `hasKeysAnyMatch` - * missing some | `notHasKeysAll` | `notHasKeysAllDeep` | `notHasKeysAllMatch` - * missing all | `notHasKeys` | `notHasKeysDeep` | `notHasKeysMatch` - * - * Note that the `hasKeys` shallow comparison variants are also overloaded to - * consume either an array (in which it simply checks against a list of keys) or - * an object (where it does a full deep comparison). - */ - -exports.includes = includes.includes -exports.includesDeep = includes.includesDeep -exports.includesMatch = includes.includesMatch -exports.includesAny = includes.includesAny -exports.includesAnyDeep = includes.includesAnyDeep -exports.includesAnyMatch = includes.includesAnyMatch -exports.notIncludesAll = includes.notIncludesAll -exports.notIncludesAllDeep = includes.notIncludesAllDeep -exports.notIncludesAllMatch = includes.notIncludesAllMatch -exports.notIncludes = includes.notIncludes -exports.notIncludesDeep = includes.notIncludesDeep -exports.notIncludesMatch = includes.notIncludesMatch - -exports.hasKeys = hasKeys.hasKeys -exports.hasKeysDeep = hasKeys.hasKeysDeep -exports.hasKeysMatch = hasKeys.hasKeysMatch -exports.hasKeysAny = hasKeys.hasKeysAny -exports.hasKeysAnyDeep = hasKeys.hasKeysAnyDeep -exports.hasKeysAnyMatch = hasKeys.hasKeysAnyMatch -exports.notHasKeysAll = hasKeys.notHasKeysAll -exports.notHasKeysAllDeep = hasKeys.notHasKeysAllDeep -exports.notHasKeysAllMatch = hasKeys.notHasKeysAllMatch -exports.notHasKeys = hasKeys.notHasKeys -exports.notHasKeysDeep = hasKeys.notHasKeysDeep -exports.notHasKeysMatch = hasKeys.notHasKeysMatch + // Adapt if the keys are already in order, which is frequently the + // case. + if (!match(key, akeys[i], context, left, right) && + !matchKey(key, akeys, i, end, context, left, right)) { + return false + } + } -},{"./lib/equal":35,"./lib/has":37,"./lib/has-keys":36,"./lib/includes":38,"./lib/throws":39,"./lib/type":40,"clean-assert-util":33}],35:[function(require,module,exports){ -"use strict" + return matchValues(a, b, akeys, bkeys, end, context, left, right) + } -var match = require("clean-match") -var util = require("clean-assert-util") + function hasAllIdentical(alist, b) { + for (var i = 0; i < alist.length; i++) { + if (!b.has(alist[i])) return false + } -function binary(numeric, comparator, message) { - return function (actual, expected) { - if (numeric) { - if (typeof actual !== "number") { - throw new TypeError("`actual` must be a number") - } + return true + } - if (typeof expected !== "number") { - throw new TypeError("`expected` must be a number") + // Compare the values structurally, and independent of order. + function searchFor(avalue, objects, context, left, right) { // eslint-disable-line max-params, max-len + for (var j in objects) { + if (hasOwn.call(objects, j)) { + if (match(avalue, objects[j], context, left, right)) { + delete objects[j] + return true + } } } - if (!comparator(actual, expected)) { - util.fail(message, {actual: actual, expected: expected}) - } + return false } -} -exports.equal = binary(false, - function (a, b) { return util.strictIs(a, b) }, - "Expected {actual} to equal {expected}") - -exports.notEqual = binary(false, - function (a, b) { return !util.strictIs(a, b) }, - "Expected {actual} to not equal {expected}") + function hasStructure(value, context) { + return typeof value === "object" && value !== null || + !(context & Strict) && typeof value === "symbol" + } -exports.equalLoose = binary(false, - function (a, b) { return util.looseIs(a, b) }, - "Expected {actual} to loosely equal {expected}") + // The set algorithm is structured a little differently. It takes one of the + // sets into an array, does a cheap identity check, then does the deep + // check. + function matchSet(a, b, context, left, right) { // eslint-disable-line max-params, max-len + // This is to try to avoid an expensive structural match on the keys. + // Test for identity first. + var alist = keyList(a) -exports.notEqualLoose = binary(false, - function (a, b) { return !util.looseIs(a, b) }, - "Expected {actual} to not loosely equal {expected}") + if (hasAllIdentical(alist, b)) return true -exports.atLeast = binary(true, - function (a, b) { return a >= b }, - "Expected {actual} to be at least {expected}") + var iter = b.values() + var count = 0 + var objects -exports.atMost = binary(true, - function (a, b) { return a <= b }, - "Expected {actual} to be at most {expected}") + // Gather all the objects + for (var next = iter.next(); !next.done; next = iter.next()) { + var bvalue = next.value -exports.above = binary(true, - function (a, b) { return a > b }, - "Expected {actual} to be above {expected}") + if (hasStructure(bvalue, context)) { + // Create the objects map lazily. Note that this also grabs + // Symbols when not strictly matching, since their description + // is compared. + if (count === 0) objects = Object.create(null) + objects[count++] = bvalue + } + } -exports.below = binary(true, - function (a, b) { return a < b }, - "Expected {actual} to be below {expected}") + // If everything is a primitive, then abort. + if (count === 0) return false -exports.between = function (actual, lower, upper) { - if (typeof actual !== "number") { - throw new TypeError("`actual` must be a number") - } + // Iterate the object, removing each one remaining when matched (and + // aborting if none can be). + for (var i = 0; i < count; i++) { + var avalue = alist[i] - if (typeof lower !== "number") { - throw new TypeError("`lower` must be a number") - } + if (hasStructure(avalue, context) && + !searchFor(avalue, objects, context, left, right)) { + return false + } + } - if (typeof upper !== "number") { - throw new TypeError("`upper` must be a number") + return true } - // The negation is to address NaNs as well, without writing a ton of special - // case boilerplate - if (!(actual >= lower && actual <= upper)) { - util.fail("Expected {actual} to be between {lower} and {upper}", { - actual: actual, - lower: lower, - upper: upper, - }) + function matchRegExp(a, b) { + return a.source === b.source && + a.global === b.global && + a.ignoreCase === b.ignoreCase && + a.multiline === b.multiline && + (!supportsUnicode || a.unicode === b.unicode) && + (!supportsSticky || a.sticky === b.sticky) } -} -exports.deepEqual = binary(false, - function (a, b) { return match.strict(a, b) }, - "Expected {actual} to deeply equal {expected}") - -exports.notDeepEqual = binary(false, - function (a, b) { return !match.strict(a, b) }, - "Expected {actual} to not deeply equal {expected}") + function matchPrepareDescend(a, b, context, left, right) { // eslint-disable-line max-params, max-len + // Check for circular references after the first level, where it's + // redundant. Note that they have to point to the same level to actually + // be considered deeply equal. + if (!(context & Initial)) { + var leftIndex = left.indexOf(a) + var rightIndex = right.indexOf(b) -exports.match = binary(false, - function (a, b) { return match.loose(a, b) }, - "Expected {actual} to match {expected}") + if (leftIndex !== rightIndex) return false + if (leftIndex >= 0) return true -exports.notMatch = binary(false, - function (a, b) { return !match.loose(a, b) }, - "Expected {actual} to not match {expected}") + left.push(a) + right.push(b) -// Uses division to allow for a more robust comparison of floats. Also, this -// handles near-zero comparisons correctly, as well as a zero tolerance (i.e. -// exact comparison). -function closeTo(expected, actual, tolerance) { - if (tolerance === Infinity || actual === expected) return true - if (tolerance === 0) return false - if (actual === 0) return Math.abs(expected) < tolerance - if (expected === 0) return Math.abs(actual) < tolerance - return Math.abs(expected / actual - 1) < tolerance -} + var result = matchInner(a, b, context, left, right) -// Note: these two always fail when dealing with NaNs. -exports.closeTo = function (expected, actual, tolerance) { - if (typeof actual !== "number") { - throw new TypeError("`actual` must be a number") - } + left.pop() + right.pop() - if (typeof expected !== "number") { - throw new TypeError("`expected` must be a number") + return result + } else { + return matchInner(a, b, context & ~Initial, [a], [b]) + } } - if (tolerance == null) tolerance = 1e-10 + function matchSameProto(a, b, context, left, right) { // eslint-disable-line max-params, max-len + if (symbolsAreObjects && a instanceof Symbol) { + return !(context & Strict) && a.toString() === b.toString() + } - if (typeof tolerance !== "number" || tolerance < 0) { - throw new TypeError( - "`tolerance` must be a non-negative number if given") - } - - if (actual !== actual || expected !== expected || // eslint-disable-line no-self-compare, max-len - !closeTo(expected, actual, tolerance)) { - util.fail("Expected {actual} to be close to {expected}", { - actual: actual, - expected: expected, - }) - } -} - -exports.notCloseTo = function (expected, actual, tolerance) { - if (typeof actual !== "number") { - throw new TypeError("`actual` must be a number") - } + if (a instanceof RegExp) return matchRegExp(a, b) + if (a instanceof Date) return a.valueOf() === b.valueOf() + if (arrayBufferSupport !== ArrayBufferNone) { + if (a instanceof DataView) { + return matchView( + new Uint8Array(a.buffer, a.byteOffset, a.byteLength), + new Uint8Array(b.buffer, b.byteOffset, b.byteLength)) + } + if (a instanceof ArrayBuffer) { + return matchView(new Uint8Array(a), new Uint8Array(b)) + } + if (isView(a)) return matchView(a, b) + } - if (typeof expected !== "number") { - throw new TypeError("`expected` must be a number") - } + if (isBuffer(a)) return matchView(a, b) - if (tolerance == null) tolerance = 1e-10 + if (Array.isArray(a)) { + if (a.length !== b.length) return false + if (a.length === 0) return true + } else if (supportsMap && a instanceof Map) { + if (a.size !== b.size) return false + if (a.size === 0) return true + } else if (supportsSet && a instanceof Set) { + if (a.size !== b.size) return false + if (a.size === 0) return true + } else if (objectToString.call(a) === "[object Arguments]") { + if (objectToString.call(b) !== "[object Arguments]") return false + if (a.length !== b.length) return false + if (a.length === 0) return true + } else if (objectToString.call(b) === "[object Arguments]") { + return false + } - if (typeof tolerance !== "number" || tolerance < 0) { - throw new TypeError( - "`tolerance` must be a non-negative number if given") + return matchPrepareDescend(a, b, context, left, right) } - if (expected !== expected || actual !== actual || // eslint-disable-line no-self-compare, max-len - closeTo(expected, actual, tolerance)) { - util.fail("Expected {actual} to not be close to {expected}", { - actual: actual, - expected: expected, - }) + // Most special cases require both types to match, and if only one of them + // are, the objects themselves don't match. + function matchDifferentProto(a, b, context, left, right) { // eslint-disable-line max-params, max-len + if (symbolsAreObjects) { + if (a instanceof Symbol || b instanceof Symbol) return false + } + if (context & Strict) return false + if (arrayBufferSupport !== ArrayBufferNone) { + if (a instanceof ArrayBuffer || b instanceof ArrayBuffer) { + return false + } + if (isView(a) || isView(b)) return false + } + if (Array.isArray(a) || Array.isArray(b)) return false + if (supportsMap && (a instanceof Map || b instanceof Map)) return false + if (supportsSet && (a instanceof Set || b instanceof Set)) return false + if (objectToString.call(a) === "[object Arguments]") { + if (objectToString.call(b) !== "[object Arguments]") return false + if (a.length !== b.length) return false + if (a.length === 0) return true + } + if (objectToString.call(b) === "[object Arguments]") return false + return matchPrepareDescend(a, b, context, left, right) } -} -},{"clean-assert-util":33,"clean-match":41}],36:[function(require,module,exports){ -"use strict" + function match(a, b, context, left, right) { // eslint-disable-line max-params, max-len + if (a === b) return true + // NaNs are equal + if (a !== a) return b !== b // eslint-disable-line no-self-compare + if (a === null || b === null) return false + if (typeof a === "symbol" && typeof b === "symbol") { + return !(context & Strict) && a.toString() === b.toString() + } + if (typeof a !== "object" || typeof b !== "object") return false -var match = require("clean-match") -var util = require("clean-assert-util") -var hasOwn = Object.prototype.hasOwnProperty + // Usually, both objects have identical prototypes, and that allows for + // half the type checking. + if (Object.getPrototypeOf(a) === Object.getPrototypeOf(b)) { + return matchSameProto(a, b, context | SameProto, left, right) + } else { + return matchDifferentProto(a, b, context, left, right) + } + } -function hasKeys(all, object, keys) { - for (var i = 0; i < keys.length; i++) { - var test = hasOwn.call(object, keys[i]) + function matchArrayLike(a, b, context, left, right) { // eslint-disable-line max-params, max-len + for (var i = 0; i < a.length; i++) { + if (!match(a[i], b[i], context, left, right)) return false + } - if (test !== all) return !all + return true } - return all -} + // PhantomJS and SlimerJS both have mysterious issues where `Error` is + // sometimes erroneously of a different `window`, and it shows up in the + // tests. This means I have to use a much slower algorithm to detect Errors. + // + // PhantomJS: https://github.com/petkaantonov/bluebird/issues/1146 + // SlimerJS: https://github.com/laurentj/slimerjs/issues/400 + // + // (Yes, the PhantomJS bug is detailed in the Bluebird issue tracker.) + var checkCrossOrigin = (function () { + if (global.window == null || global.window.navigator == null) { + return false + } + return /slimerjs|phantomjs/i.test(global.window.navigator.userAgent) + })() -function hasValues(func, all, object, keys) { - if (object === keys) return true - var list = Object.keys(keys) + var errorStringTypes = { + "[object Error]": true, + "[object EvalError]": true, + "[object RangeError]": true, + "[object ReferenceError]": true, + "[object SyntaxError]": true, + "[object TypeError]": true, + "[object URIError]": true, + } - for (var i = 0; i < list.length; i++) { - var key = list[i] - var test = hasOwn.call(object, key) && func(keys[key], object[key]) + function isProxiedError(object) { + while (object != null) { + if (errorStringTypes[objectToString.call(object)]) return true + object = Object.getPrototypeOf(object) + } - if (test !== all) return test + return false } - return all -} - -function makeHasOverload(all, invert, message) { - return function (object, keys) { - if (typeof object !== "object" || object == null) { - throw new TypeError("`object` must be an object") - } + function matchInner(a, b, context, left, right) { // eslint-disable-line max-statements, max-params, max-len + var akeys, bkeys + var isUnproxiedError = false - if (typeof keys !== "object" || keys == null) { - throw new TypeError("`keys` must be an object or array") - } + if (context & SameProto) { + if (Array.isArray(a)) { + return matchArrayLike(a, b, context, left, right) + } - if (Array.isArray(keys)) { - if (keys.length && hasKeys(all, object, keys) === invert) { - util.fail(message, {actual: object, keys: keys}) + if (supportsMap && a instanceof Map) { + return matchMap(a, b, context, left, right) } - } else if (Object.keys(keys).length) { - if (hasValues(util.strictIs, all, object, keys) === invert) { - util.fail(message, {actual: object, keys: keys}) + + if (supportsSet && a instanceof Set) { + return matchSet(a, b, context, left, right) } - } - } -} -function makeHasKeys(func, all, invert, message) { - return function (object, keys) { - if (typeof object !== "object" || object == null) { - throw new TypeError("`object` must be an object") - } + if (objectToString.call(a) === "[object Arguments]") { + return matchArrayLike(a, b, context, left, right) + } - if (typeof keys !== "object" || keys == null) { - throw new TypeError("`keys` must be an object") - } + if (requiresProxy && + (checkCrossOrigin ? isProxiedError(a) + : a instanceof Error)) { + akeys = getKeysStripped(a) + bkeys = getKeysStripped(b) + } else { + akeys = Object.keys(a) + bkeys = Object.keys(b) + isUnproxiedError = a instanceof Error + } + } else { + if (objectToString.call(a) === "[object Arguments]") { + return matchArrayLike(a, b, context, left, right) + } - // exclusive or to invert the result if `invert` is true - if (Object.keys(keys).length) { - if (hasValues(func, all, object, keys) === invert) { - util.fail(message, {actual: object, keys: keys}) + // If we require a proxy, be permissive and check the `toString` + // type. This is so it works cross-origin in PhantomJS in + // particular. + if (checkCrossOrigin ? isProxiedError(a) : a instanceof Error) { + return false } + akeys = Object.keys(a) + bkeys = Object.keys(b) } - } -} -/* eslint-disable max-len */ + var count = akeys.length -exports.hasKeys = makeHasOverload(true, false, "Expected {actual} to have all keys in {keys}") -exports.hasKeysDeep = makeHasKeys(match.strict, true, false, "Expected {actual} to have all keys in {keys}") -exports.hasKeysMatch = makeHasKeys(match.loose, true, false, "Expected {actual} to match all keys in {keys}") -exports.hasKeysAny = makeHasOverload(false, false, "Expected {actual} to have any key in {keys}") -exports.hasKeysAnyDeep = makeHasKeys(match.strict, false, false, "Expected {actual} to have any key in {keys}") -exports.hasKeysAnyMatch = makeHasKeys(match.loose, false, false, "Expected {actual} to match any key in {keys}") -exports.notHasKeysAll = makeHasOverload(true, true, "Expected {actual} to not have all keys in {keys}") -exports.notHasKeysAllDeep = makeHasKeys(match.strict, true, true, "Expected {actual} to not have all keys in {keys}") -exports.notHasKeysAllMatch = makeHasKeys(match.loose, true, true, "Expected {actual} to not match all keys in {keys}") -exports.notHasKeys = makeHasOverload(false, true, "Expected {actual} to not have any key in {keys}") -exports.notHasKeysDeep = makeHasKeys(match.strict, false, true, "Expected {actual} to not have any key in {keys}") -exports.notHasKeysMatch = makeHasKeys(match.loose, false, true, "Expected {actual} to not match any key in {keys}") + if (count !== bkeys.length) return false -},{"clean-assert-util":33,"clean-match":41}],37:[function(require,module,exports){ -"use strict" + // Shortcut if there's nothing to match + if (count === 0) return true -var util = require("clean-assert-util") -var hasOwn = Object.prototype.hasOwnProperty + var i -function has(_) { // eslint-disable-line max-len, max-params - return function (object, key, value) { - if (arguments.length >= 3) { - if (!_.has(object, key) || - !util.strictIs(_.get(object, key), value)) { - util.fail(_.messages[0], { - expected: value, - actual: object[key], - key: key, - object: object, - }) - } - } else if (!_.has(object, key)) { - util.fail(_.messages[1], { - expected: value, - actual: object[key], - key: key, - object: object, - }) - } - } -} + if (isUnproxiedError) { + // Shortcut if the properties are different. + for (i = 0; i < count; i++) { + if (akeys[i] !== "stack") { + if (!hasOwn.call(b, akeys[i])) return false + } + } -function hasLoose(_) { - return function (object, key, value) { - if (!_.has(object, key) || !util.looseIs(_.get(object, key), value)) { - util.fail(_.messages[0], { - expected: value, - actual: object[key], - key: key, - object: object, - }) - } - } -} + // Verify that all the akeys' values matched. + for (i = 0; i < count; i++) { + if (akeys[i] !== "stack" && + !match(a[akeys[i]], b[akeys[i]], + context, left, right)) { + return false + } + } + } else { + // Shortcut if the properties are different. + for (i = 0; i < count; i++) { + if (!hasOwn.call(b, akeys[i])) return false + } -function notHas(_) { // eslint-disable-line max-len, max-params - return function (object, key, value) { - if (arguments.length >= 3) { - if (_.has(object, key) && - util.strictIs(_.get(object, key), value)) { - util.fail(_.messages[2], { - expected: value, - actual: object[key], - key: key, - object: object, - }) + // Verify that all the akeys' values matched. + for (i = 0; i < count; i++) { + if (!match(a[akeys[i]], b[akeys[i]], context, left, right)) { + return false + } } - } else if (_.has(object, key)) { - util.fail(_.messages[3], { - expected: value, - actual: object[key], - key: key, - object: object, - }) } - } -} -function notHasLoose(_) { // eslint-disable-line max-len, max-params - return function (object, key, value) { - if (_.has(object, key) && util.looseIs(_.get(object, key), value)) { - util.fail(_.messages[2], { - expected: value, - actual: object[key], - key: key, - object: object, - }) - } + return true } -} - -function hasOwnKey(object, key) { return hasOwn.call(object, key) } -function hasInKey(object, key) { return key in object } -function hasInColl(object, key) { return object.has(key) } -function hasObjectGet(object, key) { return object[key] } -function hasCollGet(object, key) { return object.get(key) } +}); // eslint-disable-line semi -function createHas(has, get, messages) { - return {has: has, get: get, messages: messages} -} +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -var hasOwnMethods = createHas(hasOwnKey, hasObjectGet, [ - "Expected {object} to have own key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have own key {expected}", - "Expected {object} to not have own key {key} equal to {actual}", - "Expected {actual} to not have own key {expected}", -]) +},{}],41:[function(require,module,exports){ +/*istanbul ignore start*/"use strict"; -var hasKeyMethods = createHas(hasInKey, hasObjectGet, [ - "Expected {object} to have key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have key {expected}", - "Expected {object} to not have key {key} equal to {actual}", - "Expected {actual} to not have key {expected}", -]) +exports.__esModule = true; +exports. /*istanbul ignore end*/convertChangesToDMP = convertChangesToDMP; +// See: http://code.google.com/p/google-diff-match-patch/wiki/API +function convertChangesToDMP(changes) { + var ret = [], + change = /*istanbul ignore start*/void 0 /*istanbul ignore end*/, + operation = /*istanbul ignore start*/void 0 /*istanbul ignore end*/; + for (var i = 0; i < changes.length; i++) { + change = changes[i]; + if (change.added) { + operation = 1; + } else if (change.removed) { + operation = -1; + } else { + operation = 0; + } -var hasMethods = createHas(hasInColl, hasCollGet, [ - "Expected {object} to have key {key} equal to {expected}, but found {actual}", // eslint-disable-line max-len - "Expected {actual} to have key {expected}", - "Expected {object} to not have key {key} equal to {actual}", - "Expected {actual} to not have key {expected}", -]) + ret.push([operation, change.value]); + } + return ret; +} -exports.hasOwn = has(hasOwnMethods) -exports.notHasOwn = notHas(hasOwnMethods) -exports.hasOwnLoose = hasLoose(hasOwnMethods) -exports.notHasOwnLoose = notHasLoose(hasOwnMethods) -exports.hasKey = has(hasKeyMethods) -exports.notHasKey = notHas(hasKeyMethods) -exports.hasKeyLoose = hasLoose(hasKeyMethods) -exports.notHasKeyLoose = notHasLoose(hasKeyMethods) +},{}],42:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; -exports.has = has(hasMethods) -exports.notHas = notHas(hasMethods) -exports.hasLoose = hasLoose(hasMethods) -exports.notHasLoose = notHasLoose(hasMethods) +exports.__esModule = true; +exports. /*istanbul ignore end*/convertChangesToXML = convertChangesToXML; +function convertChangesToXML(changes) { + var ret = []; + for (var i = 0; i < changes.length; i++) { + var change = changes[i]; + if (change.added) { + ret.push(''); + } else if (change.removed) { + ret.push(''); + } -},{"clean-assert-util":33}],38:[function(require,module,exports){ -"use strict" + ret.push(escapeHTML(change.value)); -var match = require("clean-match") -var util = require("clean-assert-util") + if (change.added) { + ret.push(''); + } else if (change.removed) { + ret.push(''); + } + } + return ret.join(''); +} -function includes(func, all, array, values) { - // Cheap cases first - if (!Array.isArray(array)) return false - if (array === values) return true - if (all && array.length < values.length) return false +function escapeHTML(s) { + var n = s; + n = n.replace(/&/g, '&'); + n = n.replace(//g, '>'); + n = n.replace(/"/g, '"'); - for (var i = 0; i < values.length; i++) { - var value = values[i] - var test = false + return n; +} - for (var j = 0; j < array.length; j++) { - if (func(value, array[j])) { - test = true - break - } - } - if (test !== all) return test - } +},{}],43:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; - return all -} +exports.__esModule = true; +exports.arrayDiff = undefined; +exports. /*istanbul ignore end*/diffArrays = diffArrays; -function defineIncludes(func, all, invert, message) { - return function (array, values) { - if (!Array.isArray(array)) { - throw new TypeError("`array` must be an array") - } +var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; - if (!Array.isArray(values)) values = [values] +/*istanbul ignore start*/ +var _base2 = _interopRequireDefault(_base); - if (values.length && includes(func, all, array, values) === invert) { - util.fail(message, {actual: array, values: values}) - } - } -} +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } -/* eslint-disable max-len */ +/*istanbul ignore end*/var arrayDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/arrayDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; +arrayDiff.tokenize = arrayDiff.join = function (value) { + return value.slice(); +}; -exports.includes = defineIncludes(util.strictIs, true, false, "Expected {actual} to have all values in {values}") -exports.includesDeep = defineIncludes(match.strict, true, false, "Expected {actual} to match all values in {values}") -exports.includesMatch = defineIncludes(match.loose, true, false, "Expected {actual} to match all values in {values}") -exports.includesAny = defineIncludes(util.strictIs, false, false, "Expected {actual} to have any value in {values}") -exports.includesAnyDeep = defineIncludes(match.strict, false, false, "Expected {actual} to match any value in {values}") -exports.includesAnyMatch = defineIncludes(match.loose, false, false, "Expected {actual} to match any value in {values}") -exports.notIncludesAll = defineIncludes(util.strictIs, true, true, "Expected {actual} to not have all values in {values}") -exports.notIncludesAllDeep = defineIncludes(match.strict, true, true, "Expected {actual} to not match all values in {values}") -exports.notIncludesAllMatch = defineIncludes(match.loose, true, true, "Expected {actual} to not match all values in {values}") -exports.notIncludes = defineIncludes(util.strictIs, false, true, "Expected {actual} to not have any value in {values}") -exports.notIncludesDeep = defineIncludes(match.strict, false, true, "Expected {actual} to not match any value in {values}") -exports.notIncludesMatch = defineIncludes(match.loose, false, true, "Expected {actual} to not match any value in {values}") +function diffArrays(oldArr, newArr, callback) { + return arrayDiff.diff(oldArr, newArr, callback); +} -},{"clean-assert-util":33,"clean-match":41}],39:[function(require,module,exports){ -"use strict" -var util = require("clean-assert-util") +},{"./base":44}],44:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; -function getName(func) { - var name = func.name +exports.__esModule = true; +exports['default'] = /*istanbul ignore end*/Diff; +function Diff() {} - if (name == null) name = func.displayName - if (name) return util.escape(name) - return "" -} +Diff.prototype = { /*istanbul ignore start*/ + /*istanbul ignore end*/diff: function diff(oldString, newString) { + /*istanbul ignore start*/var /*istanbul ignore end*/options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; -exports.throws = function (Type, callback) { - if (callback == null) { - callback = Type - Type = null + var callback = options.callback; + if (typeof options === 'function') { + callback = options; + options = {}; } + this.options = options; - if (Type != null && typeof Type !== "function") { - throw new TypeError("`Type` must be a function if passed") + var self = this; + + function done(value) { + if (callback) { + setTimeout(function () { + callback(undefined, value); + }, 0); + return true; + } else { + return value; + } } - if (typeof callback !== "function") { - throw new TypeError("`callback` must be a function") + // Allow subclasses to massage the input prior to running + oldString = this.castInput(oldString); + newString = this.castInput(newString); + + oldString = this.removeEmpty(this.tokenize(oldString)); + newString = this.removeEmpty(this.tokenize(newString)); + + var newLen = newString.length, + oldLen = oldString.length; + var editLength = 1; + var maxEditLength = newLen + oldLen; + var bestPath = [{ newPos: -1, components: [] }]; + + // Seed editLength = 0, i.e. the content starts with the same values + var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); + if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { + // Identity per the equality and tokenizer + return done([{ value: this.join(newString), count: newString.length }]); } - try { - callback() // eslint-disable-line callback-return - } catch (e) { - if (Type != null && !(e instanceof Type)) { - util.fail( - "Expected callback to throw an instance of " + getName(Type) + - ", but found {actual}", - {actual: e}) + // Main worker method. checks all permutations of a given edit length for acceptance. + function execEditLength() { + for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { + var basePath = /*istanbul ignore start*/void 0 /*istanbul ignore end*/; + var addPath = bestPath[diagonalPath - 1], + removePath = bestPath[diagonalPath + 1], + _oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; + if (addPath) { + // No one else is going to attempt to use this value, clear it + bestPath[diagonalPath - 1] = undefined; } - return - } - throw new util.AssertionError("Expected callback to throw") -} + var canAdd = addPath && addPath.newPos + 1 < newLen, + canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen; + if (!canAdd && !canRemove) { + // If this path is a terminal then prune + bestPath[diagonalPath] = undefined; + continue; + } -function throwsMatchTest(matcher, e) { - if (typeof matcher === "string") return e.message === matcher - if (typeof matcher === "function") return !!matcher(e) - if (matcher instanceof RegExp) return !!matcher.test(e.message) + // Select the diagonal that we want to branch from. We select the prior + // path whose position in the new string is the farthest from the origin + // and does not pass the bounds of the diff graph + if (!canAdd || canRemove && addPath.newPos < removePath.newPos) { + basePath = clonePath(removePath); + self.pushComponent(basePath.components, undefined, true); + } else { + basePath = addPath; // No need to clone, we've pulled it from the list + basePath.newPos++; + self.pushComponent(basePath.components, true, undefined); + } - var keys = Object.keys(matcher) + _oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); - for (var i = 0; i < keys.length; i++) { - var key = keys[i] + // If we have hit the end of both strings, then we are done + if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) { + return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken)); + } else { + // Otherwise track this path as a potential candidate and continue. + bestPath[diagonalPath] = basePath; + } + } - if (!(key in e) || !util.strictIs(matcher[key], e[key])) return false + editLength++; } - return true -} - -function isPlainObject(object) { - return object == null || Object.getPrototypeOf(object) === Object.prototype -} + // Performs the length of edit iteration. Is a bit fugly as this has to support the + // sync and async mode which is never fun. Loops over execEditLength until a value + // is produced. + if (callback) { + (function exec() { + setTimeout(function () { + // This should not happen, but we want to be safe. + /* istanbul ignore next */ + if (editLength > maxEditLength) { + return callback(); + } -exports.throwsMatch = function (matcher, callback) { - if (typeof matcher !== "string" && - typeof matcher !== "function" && - !(matcher instanceof RegExp) && - !isPlainObject(matcher)) { - throw new TypeError( - "`matcher` must be a string, function, RegExp, or object") + if (!execEditLength()) { + exec(); + } + }, 0); + })(); + } else { + while (editLength <= maxEditLength) { + var ret = execEditLength(); + if (ret) { + return ret; + } + } } - - if (typeof callback !== "function") { - throw new TypeError("`callback` must be a function") + }, + /*istanbul ignore start*/ /*istanbul ignore end*/pushComponent: function pushComponent(components, added, removed) { + var last = components[components.length - 1]; + if (last && last.added === added && last.removed === removed) { + // We need to clone here as the component clone operation is just + // as shallow array clone + components[components.length - 1] = { count: last.count + 1, added: added, removed: removed }; + } else { + components.push({ count: 1, added: added, removed: removed }); + } + }, + /*istanbul ignore start*/ /*istanbul ignore end*/extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) { + var newLen = newString.length, + oldLen = oldString.length, + newPos = basePath.newPos, + oldPos = newPos - diagonalPath, + commonCount = 0; + while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { + newPos++; + oldPos++; + commonCount++; } - try { - callback() // eslint-disable-line callback-return - } catch (e) { - if (!throwsMatchTest(matcher, e)) { - util.fail( - "Expected callback to throw an error that matches " + - "{expected}, but found {actual}", - {expected: matcher, actual: e}) - } - return + if (commonCount) { + basePath.components.push({ count: commonCount }); } - throw new util.AssertionError("Expected callback to throw.") -} + basePath.newPos = newPos; + return oldPos; + }, + /*istanbul ignore start*/ /*istanbul ignore end*/equals: function equals(left, right) { + return left === right; + }, + /*istanbul ignore start*/ /*istanbul ignore end*/removeEmpty: function removeEmpty(array) { + var ret = []; + for (var i = 0; i < array.length; i++) { + if (array[i]) { + ret.push(array[i]); + } + } + return ret; + }, + /*istanbul ignore start*/ /*istanbul ignore end*/castInput: function castInput(value) { + return value; + }, + /*istanbul ignore start*/ /*istanbul ignore end*/tokenize: function tokenize(value) { + return value.split(''); + }, + /*istanbul ignore start*/ /*istanbul ignore end*/join: function join(chars) { + return chars.join(''); + } +}; -},{"clean-assert-util":33}],40:[function(require,module,exports){ -"use strict" +function buildValues(diff, components, newString, oldString, useLongestToken) { + var componentPos = 0, + componentLen = components.length, + newPos = 0, + oldPos = 0; -var util = require("clean-assert-util") + for (; componentPos < componentLen; componentPos++) { + var component = components[componentPos]; + if (!component.removed) { + if (!component.added && useLongestToken) { + var value = newString.slice(newPos, newPos + component.count); + value = value.map(function (value, i) { + var oldValue = oldString[oldPos + i]; + return oldValue.length > value.length ? oldValue : value; + }); -exports.ok = function (x) { - if (!x) util.fail("Expected {actual} to be truthy", {actual: x}) -} + component.value = diff.join(value); + } else { + component.value = diff.join(newString.slice(newPos, newPos + component.count)); + } + newPos += component.count; -exports.notOk = function (x) { - if (x) util.fail("Expected {actual} to be falsy", {actual: x}) -} + // Common case + if (!component.added) { + oldPos += component.count; + } + } else { + component.value = diff.join(oldString.slice(oldPos, oldPos + component.count)); + oldPos += component.count; -exports.isBoolean = function (x) { - if (typeof x !== "boolean") { - util.fail("Expected {actual} to be a boolean", {actual: x}) + // Reverse add and remove so removes are output first to match common convention + // The diffing algorithm is tied to add then remove output and this is the simplest + // route to get the desired output with minimal overhead. + if (componentPos && components[componentPos - 1].added) { + var tmp = components[componentPos - 1]; + components[componentPos - 1] = components[componentPos]; + components[componentPos] = tmp; + } } -} + } -exports.notBoolean = function (x) { - if (typeof x === "boolean") { - util.fail("Expected {actual} to not be a boolean", {actual: x}) - } + // Special case handle for when one terminal is ignored. For this case we merge the + // terminal into the prior string and drop the change. + var lastComponent = components[componentLen - 1]; + if (componentLen > 1 && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) { + components[componentLen - 2].value += lastComponent.value; + components.pop(); + } + + return components; } -exports.isFunction = function (x) { - if (typeof x !== "function") { - util.fail("Expected {actual} to be a function", {actual: x}) - } +function clonePath(path) { + return { newPos: path.newPos, components: path.components.slice(0) }; } -exports.notFunction = function (x) { - if (typeof x === "function") { - util.fail("Expected {actual} to not be a function", {actual: x}) - } -} -exports.isNumber = function (x) { - if (typeof x !== "number") { - util.fail("Expected {actual} to be a number", {actual: x}) - } -} +},{}],45:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; -exports.notNumber = function (x) { - if (typeof x === "number") { - util.fail("Expected {actual} to not be a number", {actual: x}) - } -} +exports.__esModule = true; +exports.characterDiff = undefined; +exports. /*istanbul ignore end*/diffChars = diffChars; -exports.isObject = function (x) { - if (typeof x !== "object" || x == null) { - util.fail("Expected {actual} to be an object", {actual: x}) - } -} +var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; -exports.notObject = function (x) { - if (typeof x === "object" && x != null) { - util.fail("Expected {actual} to not be an object", {actual: x}) - } -} +/*istanbul ignore start*/ +var _base2 = _interopRequireDefault(_base); -exports.isString = function (x) { - if (typeof x !== "string") { - util.fail("Expected {actual} to be a string", {actual: x}) - } -} +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } -exports.notString = function (x) { - if (typeof x === "string") { - util.fail("Expected {actual} to not be a string", {actual: x}) - } +/*istanbul ignore end*/var characterDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/characterDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; +function diffChars(oldStr, newStr, callback) { + return characterDiff.diff(oldStr, newStr, callback); } -exports.isSymbol = function (x) { - if (typeof x !== "symbol") { - util.fail("Expected {actual} to be a symbol", {actual: x}) - } -} -exports.notSymbol = function (x) { - if (typeof x === "symbol") { - util.fail("Expected {actual} to not be a symbol", {actual: x}) - } -} +},{"./base":44}],46:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; -exports.exists = function (x) { - if (x == null) { - util.fail("Expected {actual} to exist", {actual: x}) - } -} +exports.__esModule = true; +exports.cssDiff = undefined; +exports. /*istanbul ignore end*/diffCss = diffCss; -exports.notExists = function (x) { - if (x != null) { - util.fail("Expected {actual} to not exist", {actual: x}) - } -} +var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; -exports.isArray = function (x) { - if (!Array.isArray(x)) { - util.fail("Expected {actual} to be an array", {actual: x}) - } -} +/*istanbul ignore start*/ +var _base2 = _interopRequireDefault(_base); -exports.notArray = function (x) { - if (Array.isArray(x)) { - util.fail("Expected {actual} to not be an array", {actual: x}) - } -} +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } -exports.is = function (Type, object) { - if (typeof Type !== "function") { - throw new TypeError("`Type` must be a function") - } +/*istanbul ignore end*/var cssDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/cssDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; +cssDiff.tokenize = function (value) { + return value.split(/([{}:;,]|\s+)/); +}; - if (!(object instanceof Type)) { - util.fail("Expected {object} to be an instance of {expected}", { - expected: Type, - actual: object.constructor, - object: object, - }) - } +function diffCss(oldStr, newStr, callback) { + return cssDiff.diff(oldStr, newStr, callback); } -exports.not = function (Type, object) { - if (typeof Type !== "function") { - throw new TypeError("`Type` must be a function") - } - - if (object instanceof Type) { - util.fail("Expected {object} to not be an instance of {expected}", { - expected: Type, - object: object, - }) - } -} -},{"clean-assert-util":33}],41:[function(require,module,exports){ -(function (global){ -/** - * @license - * clean-match - * - * A simple, fast ES2015+ aware deep matching utility. - * - * Copyright (c) 2016 and later, Isiah Meadows . - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +},{"./base":44}],47:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; -/* eslint-disable */ -;(function (global, factory) { - if (typeof exports === "object" && exports != null) { - factory(global, exports) - } else if (typeof define === "function") { - define("clean-match", ["exports"], function (exports) { - factory(global, exports) - }) - } else { - factory(global, global.match = {}) - } -})(typeof global === "object" && global !== null ? global - : typeof self === "object" && self !== null ? self - : typeof window === "object" && window !== null ? window - : this, -function (global, exports) { - /* eslint-enable */ - "use strict" +exports.__esModule = true; +exports.jsonDiff = undefined; - /* global Symbol, Uint8Array, DataView, ArrayBuffer, ArrayBufferView, Map, - Set */ +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; - /** - * Deep matching algorithm, with zero dependencies. Note the following: - * - * - This is relatively performance-tuned, although it prefers high - * correctness. Patch with care, since performance is a concern. - * - This does pack a *lot* of features, which should explain the length. - * - Some of the duplication is intentional. It's generally commented, but - * it's mainly for performance, since the engine needs its type info. - * - Polyfilled core-js Symbols from cross-origin contexts will never - * register as being actual Symbols. - * - * And in case you're wondering about the longer functions and occasional - * repetition, it's because V8's inliner isn't always intelligent enough to - * deal with the super highly polymorphic data this often deals with, and JS - * doesn't have compile-time macros. - */ +exports. /*istanbul ignore end*/diffJson = diffJson; +/*istanbul ignore start*/exports. /*istanbul ignore end*/canonicalize = canonicalize; - var objectToString = Object.prototype.toString - var hasOwn = Object.prototype.hasOwnProperty +var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; - var supportsUnicode = hasOwn.call(RegExp.prototype, "unicode") - var supportsSticky = hasOwn.call(RegExp.prototype, "sticky") +/*istanbul ignore start*/ +var _base2 = _interopRequireDefault(_base); - // Legacy engines have several issues when it comes to `typeof`. - var isFunction = (function () { - function SlowIsFunction(value) { - if (value == null) return false +/*istanbul ignore end*/ +var /*istanbul ignore start*/_line = require('./line') /*istanbul ignore end*/; - var tag = objectToString.call(value) +/*istanbul ignore start*/ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - return tag === "[object Function]" || - tag === "[object GeneratorFunction]" || - tag === "[object AsyncFunction]" || - tag === "[object Proxy]" - } +/*istanbul ignore end*/ - function isPoisoned(object) { - return object != null && typeof object !== "function" - } +var objectPrototypeToString = Object.prototype.toString; - // In Safari 10, `typeof Proxy === "object"` - if (isPoisoned(global.Proxy)) return SlowIsFunction +var jsonDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/jsonDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; +// Discriminate between two lines of pretty-printed, serialized JSON where one of them has a +// dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: +jsonDiff.useLongestToken = true; - // In Safari 8, several typed array constructors are - // `typeof C === "object"` - if (isPoisoned(global.Int8Array)) return SlowIsFunction +jsonDiff.tokenize = /*istanbul ignore start*/_line.lineDiff. /*istanbul ignore end*/tokenize; +jsonDiff.castInput = function (value) { + /*istanbul ignore start*/var /*istanbul ignore end*/undefinedReplacement = this.options.undefinedReplacement; - // In old V8, RegExps are callable - if (typeof /x/ === "function") return SlowIsFunction // eslint-disable-line - // Leave this for normal things. It's easily inlined. - return function isFunction(value) { - return typeof value === "function" - } - })() + return typeof value === 'string' ? value : JSON.stringify(canonicalize(value), function (k, v) { + if (typeof v === 'undefined') { + return undefinedReplacement; + } - // Set up our own buffer check. We should always accept the polyfill, even - // in Node. Note that it uses `global.Buffer` to avoid including `buffer` in - // the bundle. + return v; + }, ' '); +}; +jsonDiff.equals = function (left, right) { + return (/*istanbul ignore start*/_base2['default']. /*istanbul ignore end*/prototype.equals(left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1')) + ); +}; - var BufferNative = 0 - var BufferPolyfill = 1 - var BufferSafari = 2 +function diffJson(oldObj, newObj, options) { + return jsonDiff.diff(oldObj, newObj, options); +} - var bufferSupport = (function () { - function FakeBuffer() {} - FakeBuffer.isBuffer = function () { return true } +// This function handles the presence of circular references by bailing out when encountering an +// object that is already on the "stack" of items being processed. +function canonicalize(obj, stack, replacementStack) { + stack = stack || []; + replacementStack = replacementStack || []; - // Only Safari 5-7 has ever had this issue. - if (new FakeBuffer().constructor !== FakeBuffer) return BufferSafari - if (!isFunction(global.Buffer)) return BufferPolyfill - if (!isFunction(global.Buffer.isBuffer)) return BufferPolyfill - // Avoid global polyfills - if (global.Buffer.isBuffer(new FakeBuffer())) return BufferPolyfill - return BufferNative - })() + var i = /*istanbul ignore start*/void 0 /*istanbul ignore end*/; - var globalIsBuffer = bufferSupport === BufferNative - ? global.Buffer.isBuffer - : undefined - - function isBuffer(object) { - if (bufferSupport === BufferNative && globalIsBuffer(object)) { - return true - } else if (bufferSupport === BufferSafari && object._isBuffer) { - return true - } + for (i = 0; i < stack.length; i += 1) { + if (stack[i] === obj) { + return replacementStack[i]; + } + } - var B = object.constructor + var canonicalizedObj = /*istanbul ignore start*/void 0 /*istanbul ignore end*/; - if (!isFunction(B)) return false - if (!isFunction(B.isBuffer)) return false - return B.isBuffer(object) + if ('[object Array]' === objectPrototypeToString.call(obj)) { + stack.push(obj); + canonicalizedObj = new Array(obj.length); + replacementStack.push(canonicalizedObj); + for (i = 0; i < obj.length; i += 1) { + canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack); } + stack.pop(); + replacementStack.pop(); + return canonicalizedObj; + } - // core-js' symbols are objects, and some old versions of V8 erroneously had - // `typeof Symbol() === "object"`. - var symbolsAreObjects = isFunction(global.Symbol) && - typeof Symbol() === "object" - - // `context` is a bit field, with the following bits. This is not as much - // for performance than to just reduce the number of parameters I need to be - // throwing around. - var Strict = 1 - var Initial = 2 - var SameProto = 4 + if (obj && obj.toJSON) { + obj = obj.toJSON(); + } - exports.loose = function (a, b) { - return match(a, b, Initial, undefined, undefined) + if ( /*istanbul ignore start*/(typeof /*istanbul ignore end*/obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj !== null) { + stack.push(obj); + canonicalizedObj = {}; + replacementStack.push(canonicalizedObj); + var sortedKeys = [], + key = /*istanbul ignore start*/void 0 /*istanbul ignore end*/; + for (key in obj) { + /* istanbul ignore else */ + if (obj.hasOwnProperty(key)) { + sortedKeys.push(key); + } } - - exports.strict = function (a, b) { - return match(a, b, Strict | Initial, undefined, undefined) + sortedKeys.sort(); + for (i = 0; i < sortedKeys.length; i += 1) { + key = sortedKeys[i]; + canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack); } + stack.pop(); + replacementStack.pop(); + } else { + canonicalizedObj = obj; + } + return canonicalizedObj; +} - // Feature-test delayed stack additions and extra keys. PhantomJS and IE - // both wait until the error was actually thrown first, and assign them as - // own properties, which is unhelpful for assertions. This returns a - // function to speed up cases where `Object.keys` is sufficient (e.g. in - // Chrome/FF/Node). - // - // This wouldn't be necessary if those engines would make the stack a - // getter, and record it when the error was created, not when it was thrown. - // It specifically filters out errors and only checks existing descriptors, - // just to keep the mess from affecting everything (it's not fully correct, - // but it's necessary). - var requiresProxy = (function () { - var test = new Error() - var old = Object.create(null) - Object.keys(test).forEach(function (key) { old[key] = true }) +},{"./base":44,"./line":48}],48:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; - try { - throw test - } catch (_) { - // ignore - } +exports.__esModule = true; +exports.lineDiff = undefined; +exports. /*istanbul ignore end*/diffLines = diffLines; +/*istanbul ignore start*/exports. /*istanbul ignore end*/diffTrimmedLines = diffTrimmedLines; - return Object.keys(test).some(function (key) { return !old[key] }) - })() +var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; - function isIgnored(object, key) { - switch (key) { - case "line": if (typeof object.line !== "number") return false; break - case "sourceURL": - if (typeof object.sourceURL !== "string") return false; break - case "stack": if (typeof object.stack !== "string") return false; break - default: return false - } +/*istanbul ignore start*/ +var _base2 = _interopRequireDefault(_base); - var desc = Object.getOwnPropertyDescriptor(object, key) +/*istanbul ignore end*/ +var /*istanbul ignore start*/_params = require('../util/params') /*istanbul ignore end*/; - return !desc.configurable && desc.enumerable && !desc.writable - } +/*istanbul ignore start*/ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - // This is only invoked with errors, so it's not going to present a - // significant slow down. - function getKeysStripped(object) { - var keys = Object.keys(object) - var count = 0 +/*istanbul ignore end*/var lineDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/lineDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; +lineDiff.tokenize = function (value) { + var retLines = [], + linesAndNewlines = value.split(/(\n|\r\n)/); - for (var i = 0; i < keys.length; i++) { - if (!isIgnored(object, keys[i])) keys[count++] = keys[i] - } + // Ignore the final empty token that occurs if the string ends with a new line + if (!linesAndNewlines[linesAndNewlines.length - 1]) { + linesAndNewlines.pop(); + } - keys.length = count - return keys + // Merge the content and line separators into single tokens + for (var i = 0; i < linesAndNewlines.length; i++) { + var line = linesAndNewlines[i]; + + if (i % 2 && !this.options.newlineIsToken) { + retLines[retLines.length - 1] += line; + } else { + if (this.options.ignoreWhitespace) { + line = line.trim(); + } + retLines.push(line); } + } - // Way faster, since typed array indices are always dense and contain - // numbers. + return retLines; +}; - // Setup for `isBufferOrView` and `isView` - var ArrayBufferNone = 0 - var ArrayBufferLegacy = 1 - var ArrayBufferCurrent = 2 +function diffLines(oldStr, newStr, callback) { + return lineDiff.diff(oldStr, newStr, callback); +} +function diffTrimmedLines(oldStr, newStr, callback) { + var options = /*istanbul ignore start*/(0, _params.generateOptions) /*istanbul ignore end*/(callback, { ignoreWhitespace: true }); + return lineDiff.diff(oldStr, newStr, options); +} - var arrayBufferSupport = (function () { - if (!isFunction(global.Uint8Array)) return ArrayBufferNone - if (!isFunction(global.DataView)) return ArrayBufferNone - if (!isFunction(global.ArrayBuffer)) return ArrayBufferNone - if (isFunction(global.ArrayBuffer.isView)) return ArrayBufferCurrent - if (isFunction(global.ArrayBufferView)) return ArrayBufferLegacy - return ArrayBufferNone - })() - // If typed arrays aren't supported (they weren't technically part of - // ES5, but many engines implemented Khronos' spec before ES6), then - // just fall back to generic buffer detection. +},{"../util/params":56,"./base":44}],49:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; - function floatIs(a, b) { - // So NaNs are considered equal. - return a === b || a !== a && b !== b // eslint-disable-line no-self-compare, max-len - } +exports.__esModule = true; +exports.sentenceDiff = undefined; +exports. /*istanbul ignore end*/diffSentences = diffSentences; - function matchView(a, b) { - var count = a.length +var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; - if (count !== b.length) return false +/*istanbul ignore start*/ +var _base2 = _interopRequireDefault(_base); - while (count) { - count-- - if (!floatIs(a[count], b[count])) return false - } +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - return true - } +/*istanbul ignore end*/var sentenceDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/sentenceDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; +sentenceDiff.tokenize = function (value) { + return value.split(/(\S.+?[.!?])(?=\s+|$)/); +}; - var isView = (function () { - if (arrayBufferSupport === ArrayBufferNone) return undefined - // ES6 typed arrays - if (arrayBufferSupport === ArrayBufferCurrent) return ArrayBuffer.isView - // legacy typed arrays - return function isView(object) { - return object instanceof ArrayBufferView - } - })() +function diffSentences(oldStr, newStr, callback) { + return sentenceDiff.diff(oldStr, newStr, callback); +} - // Support checking maps and sets deeply. They are object-like enough to - // count, and are useful in their own right. The code is rather messy, but - // mainly to keep the order-independent checking from becoming insanely - // slow. - var supportsMap = isFunction(global.Map) - var supportsSet = isFunction(global.Set) - // One of the sets and both maps' keys are converted to arrays for faster - // handling. - function keyList(map) { - var list = new Array(map.size) - var i = 0 - var iter = map.keys() +},{"./base":44}],50:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; - for (var next = iter.next(); !next.done; next = iter.next()) { - list[i++] = next.value - } +exports.__esModule = true; +exports.wordDiff = undefined; +exports. /*istanbul ignore end*/diffWords = diffWords; +/*istanbul ignore start*/exports. /*istanbul ignore end*/diffWordsWithSpace = diffWordsWithSpace; - return list - } +var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; - // The pair of arrays are aligned in a single O(n^2) operation (mod deep - // matching and rotation), adapting to O(n) when they're already aligned. - function matchKey(current, akeys, start, end, context, left, right) { // eslint-disable-line max-params, max-len - for (var i = start + 1; i < end; i++) { - var key = akeys[i] +/*istanbul ignore start*/ +var _base2 = _interopRequireDefault(_base); - if (match(current, key, context, left, right)) { - // TODO: once engines actually optimize `copyWithin`, use that - // instead. It'll be much faster than this loop. - while (i > start) akeys[i] = akeys[--i] - akeys[i] = key - return true - } - } +/*istanbul ignore end*/ +var /*istanbul ignore start*/_params = require('../util/params') /*istanbul ignore end*/; - return false - } +/*istanbul ignore start*/ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - function matchValues(a, b, akeys, bkeys, end, context, left, right) { // eslint-disable-line max-params, max-len - for (var i = 0; i < end; i++) { - if (!match(a.get(akeys[i]), b.get(bkeys[i]), - context, left, right)) { - return false - } - } +/*istanbul ignore end*/ - return true - } +// Based on https://en.wikipedia.org/wiki/Latin_script_in_Unicode +// +// Ranges and exceptions: +// Latin-1 Supplement, 0080–00FF +// - U+00D7 × Multiplication sign +// - U+00F7 ÷ Division sign +// Latin Extended-A, 0100–017F +// Latin Extended-B, 0180–024F +// IPA Extensions, 0250–02AF +// Spacing Modifier Letters, 02B0–02FF +// - U+02C7 ˇ ˇ Caron +// - U+02D8 ˘ ˘ Breve +// - U+02D9 ˙ ˙ Dot Above +// - U+02DA ˚ ˚ Ring Above +// - U+02DB ˛ ˛ Ogonek +// - U+02DC ˜ ˜ Small Tilde +// - U+02DD ˝ ˝ Double Acute Accent +// Latin Extended Additional, 1E00–1EFF +var extendedWordChars = /^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/; - // Possibly expensive order-independent key-value match. First, try to avoid - // it by conservatively assuming everything is in order - a cheap O(n) is - // always nicer than an expensive O(n^2). - function matchMap(a, b, context, left, right) { // eslint-disable-line max-params, max-len - var end = a.size - var akeys = keyList(a) - var bkeys = keyList(b) - var i = 0 +var reWhitespace = /\S/; - while (i !== end && match(akeys[i], bkeys[i], context, left, right)) { - i++ - } +var wordDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/wordDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; +wordDiff.equals = function (left, right) { + return left === right || this.options.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right); +}; +wordDiff.tokenize = function (value) { + var tokens = value.split(/(\s+|\b)/); - if (i === end) { - return matchValues(a, b, akeys, bkeys, end, context, left, right) - } + // Join the boundary splits that we do not consider to be boundaries. This is primarily the extended Latin character set. + for (var i = 0; i < tokens.length - 1; i++) { + // If we have an empty string in the next field and we have only word chars before and after, merge + if (!tokens[i + 1] && tokens[i + 2] && extendedWordChars.test(tokens[i]) && extendedWordChars.test(tokens[i + 2])) { + tokens[i] += tokens[i + 2]; + tokens.splice(i + 1, 2); + i--; + } + } - // Don't compare the same key twice - if (!matchKey(bkeys[i], akeys, i, end, context, left, right)) { - return false - } + return tokens; +}; - // If the above fails, while we're at it, let's sort them as we go, so - // the key order matches. - while (++i < end) { - var key = bkeys[i] +function diffWords(oldStr, newStr, callback) { + var options = /*istanbul ignore start*/(0, _params.generateOptions) /*istanbul ignore end*/(callback, { ignoreWhitespace: true }); + return wordDiff.diff(oldStr, newStr, options); +} +function diffWordsWithSpace(oldStr, newStr, callback) { + return wordDiff.diff(oldStr, newStr, callback); +} - // Adapt if the keys are already in order, which is frequently the - // case. - if (!match(key, akeys[i], context, left, right) && - !matchKey(key, akeys, i, end, context, left, right)) { - return false - } - } - return matchValues(a, b, akeys, bkeys, end, context, left, right) - } +},{"../util/params":56,"./base":44}],51:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; - function hasAllIdentical(alist, b) { - for (var i = 0; i < alist.length; i++) { - if (!b.has(alist[i])) return false - } +exports.__esModule = true; +exports.canonicalize = exports.convertChangesToXML = exports.convertChangesToDMP = exports.parsePatch = exports.applyPatches = exports.applyPatch = exports.createPatch = exports.createTwoFilesPatch = exports.structuredPatch = exports.diffArrays = exports.diffJson = exports.diffCss = exports.diffSentences = exports.diffTrimmedLines = exports.diffLines = exports.diffWordsWithSpace = exports.diffWords = exports.diffChars = exports.Diff = undefined; +/*istanbul ignore end*/ +var /*istanbul ignore start*/_base = require('./diff/base') /*istanbul ignore end*/; - return true - } +/*istanbul ignore start*/ +var _base2 = _interopRequireDefault(_base); - // Compare the values structurally, and independent of order. - function searchFor(avalue, objects, context, left, right) { // eslint-disable-line max-params, max-len - for (var j in objects) { - if (hasOwn.call(objects, j)) { - if (match(avalue, objects[j], context, left, right)) { - delete objects[j] - return true - } - } - } +/*istanbul ignore end*/ +var /*istanbul ignore start*/_character = require('./diff/character') /*istanbul ignore end*/; - return false - } +var /*istanbul ignore start*/_word = require('./diff/word') /*istanbul ignore end*/; - function hasStructure(value, context) { - return typeof value === "object" && value !== null || - !(context & Strict) && typeof value === "symbol" - } +var /*istanbul ignore start*/_line = require('./diff/line') /*istanbul ignore end*/; - // The set algorithm is structured a little differently. It takes one of the - // sets into an array, does a cheap identity check, then does the deep - // check. - function matchSet(a, b, context, left, right) { // eslint-disable-line max-params, max-len - // This is to try to avoid an expensive structural match on the keys. - // Test for identity first. - var alist = keyList(a) +var /*istanbul ignore start*/_sentence = require('./diff/sentence') /*istanbul ignore end*/; - if (hasAllIdentical(alist, b)) return true +var /*istanbul ignore start*/_css = require('./diff/css') /*istanbul ignore end*/; - var iter = b.values() - var count = 0 - var objects +var /*istanbul ignore start*/_json = require('./diff/json') /*istanbul ignore end*/; - // Gather all the objects - for (var next = iter.next(); !next.done; next = iter.next()) { - var bvalue = next.value +var /*istanbul ignore start*/_array = require('./diff/array') /*istanbul ignore end*/; - if (hasStructure(bvalue, context)) { - // Create the objects map lazily. Note that this also grabs - // Symbols when not strictly matching, since their description - // is compared. - if (count === 0) objects = Object.create(null) - objects[count++] = bvalue - } - } +var /*istanbul ignore start*/_apply = require('./patch/apply') /*istanbul ignore end*/; - // If everything is a primitive, then abort. - if (count === 0) return false +var /*istanbul ignore start*/_parse = require('./patch/parse') /*istanbul ignore end*/; - // Iterate the object, removing each one remaining when matched (and - // aborting if none can be). - for (var i = 0; i < count; i++) { - var avalue = alist[i] +var /*istanbul ignore start*/_create = require('./patch/create') /*istanbul ignore end*/; - if (hasStructure(avalue, context) && - !searchFor(avalue, objects, context, left, right)) { - return false - } - } +var /*istanbul ignore start*/_dmp = require('./convert/dmp') /*istanbul ignore end*/; - return true - } +var /*istanbul ignore start*/_xml = require('./convert/xml') /*istanbul ignore end*/; - function matchRegExp(a, b) { - return a.source === b.source && - a.global === b.global && - a.ignoreCase === b.ignoreCase && - a.multiline === b.multiline && - (!supportsUnicode || a.unicode === b.unicode) && - (!supportsSticky || a.sticky === b.sticky) - } +/*istanbul ignore start*/ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - function matchPrepareDescend(a, b, context, left, right) { // eslint-disable-line max-params, max-len - // Check for circular references after the first level, where it's - // redundant. Note that they have to point to the same level to actually - // be considered deeply equal. - if (!(context & Initial)) { - var leftIndex = left.indexOf(a) - var rightIndex = right.indexOf(b) +exports. /*istanbul ignore end*/Diff = _base2['default']; +/*istanbul ignore start*/exports. /*istanbul ignore end*/diffChars = _character.diffChars; +/*istanbul ignore start*/exports. /*istanbul ignore end*/diffWords = _word.diffWords; +/*istanbul ignore start*/exports. /*istanbul ignore end*/diffWordsWithSpace = _word.diffWordsWithSpace; +/*istanbul ignore start*/exports. /*istanbul ignore end*/diffLines = _line.diffLines; +/*istanbul ignore start*/exports. /*istanbul ignore end*/diffTrimmedLines = _line.diffTrimmedLines; +/*istanbul ignore start*/exports. /*istanbul ignore end*/diffSentences = _sentence.diffSentences; +/*istanbul ignore start*/exports. /*istanbul ignore end*/diffCss = _css.diffCss; +/*istanbul ignore start*/exports. /*istanbul ignore end*/diffJson = _json.diffJson; +/*istanbul ignore start*/exports. /*istanbul ignore end*/diffArrays = _array.diffArrays; +/*istanbul ignore start*/exports. /*istanbul ignore end*/structuredPatch = _create.structuredPatch; +/*istanbul ignore start*/exports. /*istanbul ignore end*/createTwoFilesPatch = _create.createTwoFilesPatch; +/*istanbul ignore start*/exports. /*istanbul ignore end*/createPatch = _create.createPatch; +/*istanbul ignore start*/exports. /*istanbul ignore end*/applyPatch = _apply.applyPatch; +/*istanbul ignore start*/exports. /*istanbul ignore end*/applyPatches = _apply.applyPatches; +/*istanbul ignore start*/exports. /*istanbul ignore end*/parsePatch = _parse.parsePatch; +/*istanbul ignore start*/exports. /*istanbul ignore end*/convertChangesToDMP = _dmp.convertChangesToDMP; +/*istanbul ignore start*/exports. /*istanbul ignore end*/convertChangesToXML = _xml.convertChangesToXML; +/*istanbul ignore start*/exports. /*istanbul ignore end*/canonicalize = _json.canonicalize; /* See LICENSE file for terms of use */ - if (leftIndex !== rightIndex) return false - if (leftIndex >= 0) return true +/* + * Text diff implementation. + * + * This library supports the following APIS: + * JsDiff.diffChars: Character by character diff + * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace + * JsDiff.diffLines: Line based diff + * + * JsDiff.diffCss: Diff targeted at CSS content + * + * These methods are based on the implementation proposed in + * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986). + * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927 + */ - left.push(a) - right.push(b) - var result = matchInner(a, b, context, left, right) +},{"./convert/dmp":41,"./convert/xml":42,"./diff/array":43,"./diff/base":44,"./diff/character":45,"./diff/css":46,"./diff/json":47,"./diff/line":48,"./diff/sentence":49,"./diff/word":50,"./patch/apply":52,"./patch/create":53,"./patch/parse":54}],52:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; - left.pop() - right.pop() +exports.__esModule = true; +exports. /*istanbul ignore end*/applyPatch = applyPatch; +/*istanbul ignore start*/exports. /*istanbul ignore end*/applyPatches = applyPatches; - return result - } else { - return matchInner(a, b, context & ~Initial, [a], [b]) - } - } +var /*istanbul ignore start*/_parse = require('./parse') /*istanbul ignore end*/; - function matchSameProto(a, b, context, left, right) { // eslint-disable-line max-params, max-len - if (symbolsAreObjects && a instanceof Symbol) { - return !(context & Strict) && a.toString() === b.toString() - } +var /*istanbul ignore start*/_distanceIterator = require('../util/distance-iterator') /*istanbul ignore end*/; - if (a instanceof RegExp) return matchRegExp(a, b) - if (a instanceof Date) return a.valueOf() === b.valueOf() - if (arrayBufferSupport !== ArrayBufferNone) { - if (a instanceof DataView) { - return matchView( - new Uint8Array(a.buffer, a.byteOffset, a.byteLength), - new Uint8Array(b.buffer, b.byteOffset, b.byteLength)) - } - if (a instanceof ArrayBuffer) { - return matchView(new Uint8Array(a), new Uint8Array(b)) - } - if (isView(a)) return matchView(a, b) - } +/*istanbul ignore start*/ +var _distanceIterator2 = _interopRequireDefault(_distanceIterator); - if (isBuffer(a)) return matchView(a, b) +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - if (Array.isArray(a)) { - if (a.length !== b.length) return false - if (a.length === 0) return true - } else if (supportsMap && a instanceof Map) { - if (a.size !== b.size) return false - if (a.size === 0) return true - } else if (supportsSet && a instanceof Set) { - if (a.size !== b.size) return false - if (a.size === 0) return true - } else if (objectToString.call(a) === "[object Arguments]") { - if (objectToString.call(b) !== "[object Arguments]") return false - if (a.length !== b.length) return false - if (a.length === 0) return true - } else if (objectToString.call(b) === "[object Arguments]") { - return false - } +/*istanbul ignore end*/function applyPatch(source, uniDiff) { + /*istanbul ignore start*/var /*istanbul ignore end*/options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; - return matchPrepareDescend(a, b, context, left, right) - } + if (typeof uniDiff === 'string') { + uniDiff = /*istanbul ignore start*/(0, _parse.parsePatch) /*istanbul ignore end*/(uniDiff); + } - // Most special cases require both types to match, and if only one of them - // are, the objects themselves don't match. - function matchDifferentProto(a, b, context, left, right) { // eslint-disable-line max-params, max-len - if (symbolsAreObjects) { - if (a instanceof Symbol || b instanceof Symbol) return false - } - if (context & Strict) return false - if (arrayBufferSupport !== ArrayBufferNone) { - if (a instanceof ArrayBuffer || b instanceof ArrayBuffer) { - return false - } - if (isView(a) || isView(b)) return false - } - if (Array.isArray(a) || Array.isArray(b)) return false - if (supportsMap && (a instanceof Map || b instanceof Map)) return false - if (supportsSet && (a instanceof Set || b instanceof Set)) return false - if (objectToString.call(a) === "[object Arguments]") { - if (objectToString.call(b) !== "[object Arguments]") return false - if (a.length !== b.length) return false - if (a.length === 0) return true - } - if (objectToString.call(b) === "[object Arguments]") return false - return matchPrepareDescend(a, b, context, left, right) + if (Array.isArray(uniDiff)) { + if (uniDiff.length > 1) { + throw new Error('applyPatch only works with a single input.'); } - function match(a, b, context, left, right) { // eslint-disable-line max-params, max-len - if (a === b) return true - // NaNs are equal - if (a !== a) return b !== b // eslint-disable-line no-self-compare - if (a === null || b === null) return false - if (typeof a === "symbol" && typeof b === "symbol") { - return !(context & Strict) && a.toString() === b.toString() - } - if (typeof a !== "object" || typeof b !== "object") return false + uniDiff = uniDiff[0]; + } - // Usually, both objects have identical prototypes, and that allows for - // half the type checking. - if (Object.getPrototypeOf(a) === Object.getPrototypeOf(b)) { - return matchSameProto(a, b, context | SameProto, left, right) - } else { - return matchDifferentProto(a, b, context, left, right) - } - } + // Apply the diff to the input + var lines = source.split(/\r\n|[\n\v\f\r\x85]/), + delimiters = source.match(/\r\n|[\n\v\f\r\x85]/g) || [], + hunks = uniDiff.hunks, + compareLine = options.compareLine || function (lineNumber, line, operation, patchContent) /*istanbul ignore start*/{ + return (/*istanbul ignore end*/line === patchContent + ); + }, + errorCount = 0, + fuzzFactor = options.fuzzFactor || 0, + minLine = 0, + offset = 0, + removeEOFNL = /*istanbul ignore start*/void 0 /*istanbul ignore end*/, + addEOFNL = /*istanbul ignore start*/void 0 /*istanbul ignore end*/; - function matchArrayLike(a, b, context, left, right) { // eslint-disable-line max-params, max-len - for (var i = 0; i < a.length; i++) { - if (!match(a[i], b[i], context, left, right)) return false - } + /** + * Checks if the hunk exactly fits on the provided location + */ + function hunkFits(hunk, toPos) { + for (var j = 0; j < hunk.lines.length; j++) { + var line = hunk.lines[j], + operation = line[0], + content = line.substr(1); - return true - } + if (operation === ' ' || operation === '-') { + // Context sanity check + if (!compareLine(toPos + 1, lines[toPos], operation, content)) { + errorCount++; - // PhantomJS and SlimerJS both have mysterious issues where `Error` is - // sometimes erroneously of a different `window`, and it shows up in the - // tests. This means I have to use a much slower algorithm to detect Errors. - // - // PhantomJS: https://github.com/petkaantonov/bluebird/issues/1146 - // SlimerJS: https://github.com/laurentj/slimerjs/issues/400 - // - // (Yes, the PhantomJS bug is detailed in the Bluebird issue tracker.) - var checkCrossOrigin = (function () { - if (global.window == null || global.window.navigator == null) { - return false + if (errorCount > fuzzFactor) { + return false; + } } - return /slimerjs|phantomjs/i.test(global.window.navigator.userAgent) - })() - - var errorStringTypes = { - "[object Error]": true, - "[object EvalError]": true, - "[object RangeError]": true, - "[object ReferenceError]": true, - "[object SyntaxError]": true, - "[object TypeError]": true, - "[object URIError]": true, + toPos++; + } } - function isProxiedError(object) { - while (object != null) { - if (errorStringTypes[objectToString.call(object)]) return true - object = Object.getPrototypeOf(object) - } + return true; + } - return false - } + // Search best fit offsets for each hunk based on the previous ones + for (var i = 0; i < hunks.length; i++) { + var hunk = hunks[i], + maxLine = lines.length - hunk.oldLines, + localOffset = 0, + toPos = offset + hunk.oldStart - 1; - function matchInner(a, b, context, left, right) { // eslint-disable-line max-statements, max-params, max-len - var akeys, bkeys - var isUnproxiedError = false + var iterator = /*istanbul ignore start*/(0, _distanceIterator2['default']) /*istanbul ignore end*/(toPos, minLine, maxLine); - if (context & SameProto) { - if (Array.isArray(a)) { - return matchArrayLike(a, b, context, left, right) - } + for (; localOffset !== undefined; localOffset = iterator()) { + if (hunkFits(hunk, toPos + localOffset)) { + hunk.offset = offset += localOffset; + break; + } + } - if (supportsMap && a instanceof Map) { - return matchMap(a, b, context, left, right) - } + if (localOffset === undefined) { + return false; + } - if (supportsSet && a instanceof Set) { - return matchSet(a, b, context, left, right) - } + // Set lower text limit to end of the current hunk, so next ones don't try + // to fit over already patched text + minLine = hunk.offset + hunk.oldStart + hunk.oldLines; + } - if (objectToString.call(a) === "[object Arguments]") { - return matchArrayLike(a, b, context, left, right) - } + // Apply patch hunks + for (var _i = 0; _i < hunks.length; _i++) { + var _hunk = hunks[_i], + _toPos = _hunk.offset + _hunk.newStart - 1; + if (_hunk.newLines == 0) { + _toPos++; + } - if (requiresProxy && - (checkCrossOrigin ? isProxiedError(a) - : a instanceof Error)) { - akeys = getKeysStripped(a) - bkeys = getKeysStripped(b) - } else { - akeys = Object.keys(a) - bkeys = Object.keys(b) - isUnproxiedError = a instanceof Error - } - } else { - if (objectToString.call(a) === "[object Arguments]") { - return matchArrayLike(a, b, context, left, right) - } + for (var j = 0; j < _hunk.lines.length; j++) { + var line = _hunk.lines[j], + operation = line[0], + content = line.substr(1), + delimiter = _hunk.linedelimiters[j]; - // If we require a proxy, be permissive and check the `toString` - // type. This is so it works cross-origin in PhantomJS in - // particular. - if (checkCrossOrigin ? isProxiedError(a) : a instanceof Error) { - return false - } - akeys = Object.keys(a) - bkeys = Object.keys(b) + if (operation === ' ') { + _toPos++; + } else if (operation === '-') { + lines.splice(_toPos, 1); + delimiters.splice(_toPos, 1); + /* istanbul ignore else */ + } else if (operation === '+') { + lines.splice(_toPos, 0, content); + delimiters.splice(_toPos, 0, delimiter); + _toPos++; + } else if (operation === '\\') { + var previousOperation = _hunk.lines[j - 1] ? _hunk.lines[j - 1][0] : null; + if (previousOperation === '+') { + removeEOFNL = true; + } else if (previousOperation === '-') { + addEOFNL = true; + } } + } + } - var count = akeys.length + // Handle EOFNL insertion/removal + if (removeEOFNL) { + while (!lines[lines.length - 1]) { + lines.pop(); + delimiters.pop(); + } + } else if (addEOFNL) { + lines.push(''); + delimiters.push('\n'); + } + for (var _k = 0; _k < lines.length - 1; _k++) { + lines[_k] = lines[_k] + delimiters[_k]; + } + return lines.join(''); +} - if (count !== bkeys.length) return false +// Wrapper that supports multiple file patches via callbacks. +function applyPatches(uniDiff, options) { + if (typeof uniDiff === 'string') { + uniDiff = /*istanbul ignore start*/(0, _parse.parsePatch) /*istanbul ignore end*/(uniDiff); + } - // Shortcut if there's nothing to match - if (count === 0) return true + var currentIndex = 0; + function processIndex() { + var index = uniDiff[currentIndex++]; + if (!index) { + return options.complete(); + } - var i + options.loadFile(index, function (err, data) { + if (err) { + return options.complete(err); + } - if (isUnproxiedError) { - // Shortcut if the properties are different. - for (i = 0; i < count; i++) { - if (akeys[i] !== "stack") { - if (!hasOwn.call(b, akeys[i])) return false - } - } - - // Verify that all the akeys' values matched. - for (i = 0; i < count; i++) { - if (akeys[i] !== "stack" && - !match(a[akeys[i]], b[akeys[i]], - context, left, right)) { - return false - } - } - } else { - // Shortcut if the properties are different. - for (i = 0; i < count; i++) { - if (!hasOwn.call(b, akeys[i])) return false - } - - // Verify that all the akeys' values matched. - for (i = 0; i < count; i++) { - if (!match(a[akeys[i]], b[akeys[i]], context, left, right)) { - return false - } - } + var updatedContent = applyPatch(data, index, options); + options.patched(index, updatedContent, function (err) { + if (err) { + return options.complete(err); } - return true - } -}); // eslint-disable-line semi - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],42:[function(require,module,exports){ -/*istanbul ignore start*/"use strict"; - -exports.__esModule = true; -exports. /*istanbul ignore end*/convertChangesToDMP = convertChangesToDMP; -// See: http://code.google.com/p/google-diff-match-patch/wiki/API -function convertChangesToDMP(changes) { - var ret = [], - change = /*istanbul ignore start*/void 0 /*istanbul ignore end*/, - operation = /*istanbul ignore start*/void 0 /*istanbul ignore end*/; - for (var i = 0; i < changes.length; i++) { - change = changes[i]; - if (change.added) { - operation = 1; - } else if (change.removed) { - operation = -1; - } else { - operation = 0; - } - - ret.push([operation, change.value]); + processIndex(); + }); + }); } - return ret; + processIndex(); } -},{}],43:[function(require,module,exports){ +},{"../util/distance-iterator":55,"./parse":54}],53:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; -exports. /*istanbul ignore end*/convertChangesToXML = convertChangesToXML; -function convertChangesToXML(changes) { - var ret = []; - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - if (change.added) { - ret.push(''); - } else if (change.removed) { - ret.push(''); - } +exports. /*istanbul ignore end*/structuredPatch = structuredPatch; +/*istanbul ignore start*/exports. /*istanbul ignore end*/createTwoFilesPatch = createTwoFilesPatch; +/*istanbul ignore start*/exports. /*istanbul ignore end*/createPatch = createPatch; - ret.push(escapeHTML(change.value)); +var /*istanbul ignore start*/_line = require('../diff/line') /*istanbul ignore end*/; - if (change.added) { - ret.push(''); - } else if (change.removed) { - ret.push(''); - } +/*istanbul ignore start*/ +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +/*istanbul ignore end*/function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { + if (!options) { + options = {}; + } + if (typeof options.context === 'undefined') { + options.context = 4; } - return ret.join(''); -} -function escapeHTML(s) { - var n = s; - n = n.replace(/&/g, '&'); - n = n.replace(//g, '>'); - n = n.replace(/"/g, '"'); + var diff = /*istanbul ignore start*/(0, _line.diffLines) /*istanbul ignore end*/(oldStr, newStr, options); + diff.push({ value: '', lines: [] }); // Append an empty value to make cleanup easier - return n; -} + function contextLines(lines) { + return lines.map(function (entry) { + return ' ' + entry; + }); + } + var hunks = []; + var oldRangeStart = 0, + newRangeStart = 0, + curRange = [], + oldLine = 1, + newLine = 1; + /*istanbul ignore start*/ + var _loop = function _loop( /*istanbul ignore end*/i) { + var current = diff[i], + lines = current.lines || current.value.replace(/\n$/, '').split('\n'); + current.lines = lines; -},{}],44:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; + if (current.added || current.removed) { + /*istanbul ignore start*/ + var _curRange; -exports.__esModule = true; -exports.arrayDiff = undefined; -exports. /*istanbul ignore end*/diffArrays = diffArrays; + /*istanbul ignore end*/ + // If we have previous context, start with that + if (!oldRangeStart) { + var prev = diff[i - 1]; + oldRangeStart = oldLine; + newRangeStart = newLine; -var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; + if (prev) { + curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : []; + oldRangeStart -= curRange.length; + newRangeStart -= curRange.length; + } + } -/*istanbul ignore start*/ -var _base2 = _interopRequireDefault(_base); + // Output our changes + /*istanbul ignore start*/(_curRange = /*istanbul ignore end*/curRange).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_curRange /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/lines.map(function (entry) { + return (current.added ? '+' : '-') + entry; + }))); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + // Track the updated file position + if (current.added) { + newLine += lines.length; + } else { + oldLine += lines.length; + } + } else { + // Identical context lines. Track line changes + if (oldRangeStart) { + // Close out any changes that have been output (or join overlapping) + if (lines.length <= options.context * 2 && i < diff.length - 2) { + /*istanbul ignore start*/ + var _curRange2; -/*istanbul ignore end*/var arrayDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/arrayDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; -arrayDiff.tokenize = arrayDiff.join = function (value) { - return value.slice(); -}; + /*istanbul ignore end*/ + // Overlapping + /*istanbul ignore start*/(_curRange2 = /*istanbul ignore end*/curRange).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_curRange2 /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/contextLines(lines))); + } else { + /*istanbul ignore start*/ + var _curRange3; -function diffArrays(oldArr, newArr, callback) { - return arrayDiff.diff(oldArr, newArr, callback); -} + /*istanbul ignore end*/ + // end the range and output + var contextSize = Math.min(lines.length, options.context); + /*istanbul ignore start*/(_curRange3 = /*istanbul ignore end*/curRange).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_curRange3 /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/contextLines(lines.slice(0, contextSize)))); + var hunk = { + oldStart: oldRangeStart, + oldLines: oldLine - oldRangeStart + contextSize, + newStart: newRangeStart, + newLines: newLine - newRangeStart + contextSize, + lines: curRange + }; + if (i >= diff.length - 2 && lines.length <= options.context) { + // EOF is inside this hunk + var oldEOFNewline = /\n$/.test(oldStr); + var newEOFNewline = /\n$/.test(newStr); + if (lines.length == 0 && !oldEOFNewline) { + // special case: old has no eol and no trailing context; no-nl can end up before adds + curRange.splice(hunk.oldLines, 0, '\\ No newline at end of file'); + } else if (!oldEOFNewline || !newEOFNewline) { + curRange.push('\\ No newline at end of file'); + } + } + hunks.push(hunk); -},{"./base":45}],45:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; + oldRangeStart = 0; + newRangeStart = 0; + curRange = []; + } + } + oldLine += lines.length; + newLine += lines.length; + } + }; -exports.__esModule = true; -exports['default'] = /*istanbul ignore end*/Diff; -function Diff() {} + for (var i = 0; i < diff.length; i++) { + /*istanbul ignore start*/ + _loop( /*istanbul ignore end*/i); + } -Diff.prototype = { /*istanbul ignore start*/ - /*istanbul ignore end*/diff: function diff(oldString, newString) { - /*istanbul ignore start*/var /*istanbul ignore end*/options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; + return { + oldFileName: oldFileName, newFileName: newFileName, + oldHeader: oldHeader, newHeader: newHeader, + hunks: hunks + }; +} - var callback = options.callback; - if (typeof options === 'function') { - callback = options; - options = {}; - } - this.options = options; +function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { + var diff = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options); - var self = this; + var ret = []; + if (oldFileName == newFileName) { + ret.push('Index: ' + oldFileName); + } + ret.push('==================================================================='); + ret.push('--- ' + diff.oldFileName + (typeof diff.oldHeader === 'undefined' ? '' : '\t' + diff.oldHeader)); + ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\t' + diff.newHeader)); - function done(value) { - if (callback) { - setTimeout(function () { - callback(undefined, value); - }, 0); - return true; - } else { - return value; - } - } + for (var i = 0; i < diff.hunks.length; i++) { + var hunk = diff.hunks[i]; + ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@'); + ret.push.apply(ret, hunk.lines); + } - // Allow subclasses to massage the input prior to running - oldString = this.castInput(oldString); - newString = this.castInput(newString); + return ret.join('\n') + '\n'; +} - oldString = this.removeEmpty(this.tokenize(oldString)); - newString = this.removeEmpty(this.tokenize(newString)); +function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { + return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options); +} - var newLen = newString.length, - oldLen = oldString.length; - var editLength = 1; - var maxEditLength = newLen + oldLen; - var bestPath = [{ newPos: -1, components: [] }]; - // Seed editLength = 0, i.e. the content starts with the same values - var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); - if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { - // Identity per the equality and tokenizer - return done([{ value: this.join(newString), count: newString.length }]); - } +},{"../diff/line":48}],54:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; - // Main worker method. checks all permutations of a given edit length for acceptance. - function execEditLength() { - for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { - var basePath = /*istanbul ignore start*/void 0 /*istanbul ignore end*/; - var addPath = bestPath[diagonalPath - 1], - removePath = bestPath[diagonalPath + 1], - _oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; - if (addPath) { - // No one else is going to attempt to use this value, clear it - bestPath[diagonalPath - 1] = undefined; - } +exports.__esModule = true; +exports. /*istanbul ignore end*/parsePatch = parsePatch; +function parsePatch(uniDiff) { + /*istanbul ignore start*/var /*istanbul ignore end*/options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; - var canAdd = addPath && addPath.newPos + 1 < newLen, - canRemove = removePath && 0 <= _oldPos && _oldPos < oldLen; - if (!canAdd && !canRemove) { - // If this path is a terminal then prune - bestPath[diagonalPath] = undefined; - continue; - } + var diffstr = uniDiff.split(/\r\n|[\n\v\f\r\x85]/), + delimiters = uniDiff.match(/\r\n|[\n\v\f\r\x85]/g) || [], + list = [], + i = 0; - // Select the diagonal that we want to branch from. We select the prior - // path whose position in the new string is the farthest from the origin - // and does not pass the bounds of the diff graph - if (!canAdd || canRemove && addPath.newPos < removePath.newPos) { - basePath = clonePath(removePath); - self.pushComponent(basePath.components, undefined, true); - } else { - basePath = addPath; // No need to clone, we've pulled it from the list - basePath.newPos++; - self.pushComponent(basePath.components, true, undefined); - } + function parseIndex() { + var index = {}; + list.push(index); - _oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); + // Parse diff metadata + while (i < diffstr.length) { + var line = diffstr[i]; - // If we have hit the end of both strings, then we are done - if (basePath.newPos + 1 >= newLen && _oldPos + 1 >= oldLen) { - return done(buildValues(self, basePath.components, newString, oldString, self.useLongestToken)); - } else { - // Otherwise track this path as a potential candidate and continue. - bestPath[diagonalPath] = basePath; - } + // File header found, end parsing diff metadata + if (/^(\-\-\-|\+\+\+|@@)\s/.test(line)) { + break; } - editLength++; - } - - // Performs the length of edit iteration. Is a bit fugly as this has to support the - // sync and async mode which is never fun. Loops over execEditLength until a value - // is produced. - if (callback) { - (function exec() { - setTimeout(function () { - // This should not happen, but we want to be safe. - /* istanbul ignore next */ - if (editLength > maxEditLength) { - return callback(); - } - - if (!execEditLength()) { - exec(); - } - }, 0); - })(); - } else { - while (editLength <= maxEditLength) { - var ret = execEditLength(); - if (ret) { - return ret; - } + // Diff index + var header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line); + if (header) { + index.index = header[1]; } - } - }, - /*istanbul ignore start*/ /*istanbul ignore end*/pushComponent: function pushComponent(components, added, removed) { - var last = components[components.length - 1]; - if (last && last.added === added && last.removed === removed) { - // We need to clone here as the component clone operation is just - // as shallow array clone - components[components.length - 1] = { count: last.count + 1, added: added, removed: removed }; - } else { - components.push({ count: 1, added: added, removed: removed }); - } - }, - /*istanbul ignore start*/ /*istanbul ignore end*/extractCommon: function extractCommon(basePath, newString, oldString, diagonalPath) { - var newLen = newString.length, - oldLen = oldString.length, - newPos = basePath.newPos, - oldPos = newPos - diagonalPath, - commonCount = 0; - while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { - newPos++; - oldPos++; - commonCount++; - } - if (commonCount) { - basePath.components.push({ count: commonCount }); + i++; } - basePath.newPos = newPos; - return oldPos; - }, - /*istanbul ignore start*/ /*istanbul ignore end*/equals: function equals(left, right) { - return left === right; - }, - /*istanbul ignore start*/ /*istanbul ignore end*/removeEmpty: function removeEmpty(array) { - var ret = []; - for (var i = 0; i < array.length; i++) { - if (array[i]) { - ret.push(array[i]); - } - } - return ret; - }, - /*istanbul ignore start*/ /*istanbul ignore end*/castInput: function castInput(value) { - return value; - }, - /*istanbul ignore start*/ /*istanbul ignore end*/tokenize: function tokenize(value) { - return value.split(''); - }, - /*istanbul ignore start*/ /*istanbul ignore end*/join: function join(chars) { - return chars.join(''); - } -}; + // Parse file headers if they are defined. Unified diff requires them, but + // there's no technical issues to have an isolated hunk without file header + parseFileHeader(index); + parseFileHeader(index); -function buildValues(diff, components, newString, oldString, useLongestToken) { - var componentPos = 0, - componentLen = components.length, - newPos = 0, - oldPos = 0; + // Parse hunks + index.hunks = []; - for (; componentPos < componentLen; componentPos++) { - var component = components[componentPos]; - if (!component.removed) { - if (!component.added && useLongestToken) { - var value = newString.slice(newPos, newPos + component.count); - value = value.map(function (value, i) { - var oldValue = oldString[oldPos + i]; - return oldValue.length > value.length ? oldValue : value; - }); + while (i < diffstr.length) { + var _line = diffstr[i]; - component.value = diff.join(value); + if (/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(_line)) { + break; + } else if (/^@@/.test(_line)) { + index.hunks.push(parseHunk()); + } else if (_line && options.strict) { + // Ignore unexpected content unless in strict mode + throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(_line)); } else { - component.value = diff.join(newString.slice(newPos, newPos + component.count)); - } - newPos += component.count; - - // Common case - if (!component.added) { - oldPos += component.count; - } - } else { - component.value = diff.join(oldString.slice(oldPos, oldPos + component.count)); - oldPos += component.count; - - // Reverse add and remove so removes are output first to match common convention - // The diffing algorithm is tied to add then remove output and this is the simplest - // route to get the desired output with minimal overhead. - if (componentPos && components[componentPos - 1].added) { - var tmp = components[componentPos - 1]; - components[componentPos - 1] = components[componentPos]; - components[componentPos] = tmp; + i++; } } } - // Special case handle for when one terminal is ignored. For this case we merge the - // terminal into the prior string and drop the change. - var lastComponent = components[componentLen - 1]; - if (componentLen > 1 && (lastComponent.added || lastComponent.removed) && diff.equals('', lastComponent.value)) { - components[componentLen - 2].value += lastComponent.value; - components.pop(); - } + // Parses the --- and +++ headers, if none are found, no lines + // are consumed. + function parseFileHeader(index) { + var headerPattern = /^(---|\+\+\+)\s+([\S ]*)(?:\t(.*?)\s*)?$/; + var fileHeader = headerPattern.exec(diffstr[i]); + if (fileHeader) { + var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new'; + index[keyPrefix + 'FileName'] = fileHeader[2]; + index[keyPrefix + 'Header'] = fileHeader[3]; - return components; -} + i++; + } + } -function clonePath(path) { - return { newPos: path.newPos, components: path.components.slice(0) }; -} + // Parses a hunk + // This assumes that we are at the start of a hunk. + function parseHunk() { + var chunkHeaderIndex = i, + chunkHeaderLine = diffstr[i++], + chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); + var hunk = { + oldStart: +chunkHeader[1], + oldLines: +chunkHeader[2] || 1, + newStart: +chunkHeader[3], + newLines: +chunkHeader[4] || 1, + lines: [], + linedelimiters: [] + }; -},{}],46:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; + var addCount = 0, + removeCount = 0; + for (; i < diffstr.length; i++) { + // Lines starting with '---' could be mistaken for the "remove line" operation + // But they could be the header for the next file. Therefore prune such cases out. + if (diffstr[i].indexOf('--- ') === 0 && i + 2 < diffstr.length && diffstr[i + 1].indexOf('+++ ') === 0 && diffstr[i + 2].indexOf('@@') === 0) { + break; + } + var operation = diffstr[i][0]; -exports.__esModule = true; -exports.characterDiff = undefined; -exports. /*istanbul ignore end*/diffChars = diffChars; + if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') { + hunk.lines.push(diffstr[i]); + hunk.linedelimiters.push(delimiters[i] || '\n'); -var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; - -/*istanbul ignore start*/ -var _base2 = _interopRequireDefault(_base); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -/*istanbul ignore end*/var characterDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/characterDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; -function diffChars(oldStr, newStr, callback) { - return characterDiff.diff(oldStr, newStr, callback); -} - - -},{"./base":45}],47:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; - -exports.__esModule = true; -exports.cssDiff = undefined; -exports. /*istanbul ignore end*/diffCss = diffCss; + if (operation === '+') { + addCount++; + } else if (operation === '-') { + removeCount++; + } else if (operation === ' ') { + addCount++; + removeCount++; + } + } else { + break; + } + } -var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; + // Handle the empty block count case + if (!addCount && hunk.newLines === 1) { + hunk.newLines = 0; + } + if (!removeCount && hunk.oldLines === 1) { + hunk.oldLines = 0; + } -/*istanbul ignore start*/ -var _base2 = _interopRequireDefault(_base); + // Perform optional sanity checking + if (options.strict) { + if (addCount !== hunk.newLines) { + throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); + } + if (removeCount !== hunk.oldLines) { + throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); + } + } -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + return hunk; + } -/*istanbul ignore end*/var cssDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/cssDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; -cssDiff.tokenize = function (value) { - return value.split(/([{}:;,]|\s+)/); -}; + while (i < diffstr.length) { + parseIndex(); + } -function diffCss(oldStr, newStr, callback) { - return cssDiff.diff(oldStr, newStr, callback); + return list; } -},{"./base":45}],48:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; +},{}],55:[function(require,module,exports){ +/*istanbul ignore start*/"use strict"; exports.__esModule = true; -exports.jsonDiff = undefined; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; - -exports. /*istanbul ignore end*/diffJson = diffJson; -/*istanbul ignore start*/exports. /*istanbul ignore end*/canonicalize = canonicalize; - -var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; - -/*istanbul ignore start*/ -var _base2 = _interopRequireDefault(_base); - -/*istanbul ignore end*/ -var /*istanbul ignore start*/_line = require('./line') /*istanbul ignore end*/; - -/*istanbul ignore start*/ -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -/*istanbul ignore end*/ - -var objectPrototypeToString = Object.prototype.toString; - -var jsonDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/jsonDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; -// Discriminate between two lines of pretty-printed, serialized JSON where one of them has a -// dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: -jsonDiff.useLongestToken = true; +exports["default"] = /*istanbul ignore end*/function (start, minLine, maxLine) { + var wantForward = true, + backwardExhausted = false, + forwardExhausted = false, + localOffset = 1; -jsonDiff.tokenize = /*istanbul ignore start*/_line.lineDiff. /*istanbul ignore end*/tokenize; -jsonDiff.castInput = function (value) { - /*istanbul ignore start*/var /*istanbul ignore end*/undefinedReplacement = this.options.undefinedReplacement; + return function iterator() { + if (wantForward && !forwardExhausted) { + if (backwardExhausted) { + localOffset++; + } else { + wantForward = false; + } + // Check if trying to fit beyond text length, and if not, check it fits + // after offset location (or desired location on first iteration) + if (start + localOffset <= maxLine) { + return localOffset; + } - return typeof value === 'string' ? value : JSON.stringify(canonicalize(value), function (k, v) { - if (typeof v === 'undefined') { - return undefinedReplacement; + forwardExhausted = true; } - return v; - }, ' '); -}; -jsonDiff.equals = function (left, right) { - return (/*istanbul ignore start*/_base2['default']. /*istanbul ignore end*/prototype.equals(left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1')) - ); -}; - -function diffJson(oldObj, newObj, options) { - return jsonDiff.diff(oldObj, newObj, options); -} - -// This function handles the presence of circular references by bailing out when encountering an -// object that is already on the "stack" of items being processed. -function canonicalize(obj, stack, replacementStack) { - stack = stack || []; - replacementStack = replacementStack || []; + if (!backwardExhausted) { + if (!forwardExhausted) { + wantForward = true; + } - var i = /*istanbul ignore start*/void 0 /*istanbul ignore end*/; + // Check if trying to fit before text beginning, and if not, check it fits + // before offset location + if (minLine <= start - localOffset) { + return -localOffset++; + } - for (i = 0; i < stack.length; i += 1) { - if (stack[i] === obj) { - return replacementStack[i]; + backwardExhausted = true; + return iterator(); } - } - var canonicalizedObj = /*istanbul ignore start*/void 0 /*istanbul ignore end*/; + // We tried to fit hunk before text beginning and beyond text lenght, then + // hunk can't fit on the text. Return undefined + }; +}; - if ('[object Array]' === objectPrototypeToString.call(obj)) { - stack.push(obj); - canonicalizedObj = new Array(obj.length); - replacementStack.push(canonicalizedObj); - for (i = 0; i < obj.length; i += 1) { - canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack); - } - stack.pop(); - replacementStack.pop(); - return canonicalizedObj; - } - if (obj && obj.toJSON) { - obj = obj.toJSON(); - } +},{}],56:[function(require,module,exports){ +/*istanbul ignore start*/'use strict'; - if ( /*istanbul ignore start*/(typeof /*istanbul ignore end*/obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj !== null) { - stack.push(obj); - canonicalizedObj = {}; - replacementStack.push(canonicalizedObj); - var sortedKeys = [], - key = /*istanbul ignore start*/void 0 /*istanbul ignore end*/; - for (key in obj) { +exports.__esModule = true; +exports. /*istanbul ignore end*/generateOptions = generateOptions; +function generateOptions(options, defaults) { + if (typeof options === 'function') { + defaults.callback = options; + } else if (options) { + for (var name in options) { /* istanbul ignore else */ - if (obj.hasOwnProperty(key)) { - sortedKeys.push(key); + if (options.hasOwnProperty(name)) { + defaults[name] = options[name]; } } - sortedKeys.sort(); - for (i = 0; i < sortedKeys.length; i += 1) { - key = sortedKeys[i]; - canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack); - } - stack.pop(); - replacementStack.pop(); - } else { - canonicalizedObj = obj; } - return canonicalizedObj; + return defaults; } -},{"./base":45,"./line":49}],49:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; - -exports.__esModule = true; -exports.lineDiff = undefined; -exports. /*istanbul ignore end*/diffLines = diffLines; -/*istanbul ignore start*/exports. /*istanbul ignore end*/diffTrimmedLines = diffTrimmedLines; +},{}],57:[function(require,module,exports){ -var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; +var hasOwn = Object.prototype.hasOwnProperty; +var toString = Object.prototype.toString; -/*istanbul ignore start*/ -var _base2 = _interopRequireDefault(_base); +module.exports = function forEach (obj, fn, ctx) { + if (toString.call(fn) !== '[object Function]') { + throw new TypeError('iterator must be a function'); + } + var l = obj.length; + if (l === +l) { + for (var i = 0; i < l; i++) { + fn.call(ctx, obj[i], i, obj); + } + } else { + for (var k in obj) { + if (hasOwn.call(obj, k)) { + fn.call(ctx, obj[k], k, obj); + } + } + } +}; -/*istanbul ignore end*/ -var /*istanbul ignore start*/_params = require('../util/params') /*istanbul ignore end*/; -/*istanbul ignore start*/ -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } +},{}],58:[function(require,module,exports){ -/*istanbul ignore end*/var lineDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/lineDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; -lineDiff.tokenize = function (value) { - var retLines = [], - linesAndNewlines = value.split(/(\n|\r\n)/); +var indexOf = [].indexOf; - // Ignore the final empty token that occurs if the string ends with a new line - if (!linesAndNewlines[linesAndNewlines.length - 1]) { - linesAndNewlines.pop(); +module.exports = function(arr, obj){ + if (indexOf) return arr.indexOf(obj); + for (var i = 0; i < arr.length; ++i) { + if (arr[i] === obj) return i; } + return -1; +}; +},{}],59:[function(require,module,exports){ +module.exports = Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]'; +}; - // Merge the content and line separators into single tokens - for (var i = 0; i < linesAndNewlines.length; i++) { - var line = linesAndNewlines[i]; +},{}],60:[function(require,module,exports){ +"use strict"; - if (i % 2 && !this.options.newlineIsToken) { - retLines[retLines.length - 1] += line; - } else { - if (this.options.ignoreWhitespace) { - line = line.trim(); - } - retLines.push(line); - } - } +var hasOwn = Object.prototype.hasOwnProperty; +var toString = Object.prototype.toString; - return retLines; +var isFunction = function (fn) { + return (typeof fn === 'function' && !(fn instanceof RegExp)) || toString.call(fn) === '[object Function]'; }; -function diffLines(oldStr, newStr, callback) { - return lineDiff.diff(oldStr, newStr, callback); -} -function diffTrimmedLines(oldStr, newStr, callback) { - var options = /*istanbul ignore start*/(0, _params.generateOptions) /*istanbul ignore end*/(callback, { ignoreWhitespace: true }); - return lineDiff.diff(oldStr, newStr, options); -} - - -},{"../util/params":57,"./base":45}],50:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; - -exports.__esModule = true; -exports.sentenceDiff = undefined; -exports. /*istanbul ignore end*/diffSentences = diffSentences; - -var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; - -/*istanbul ignore start*/ -var _base2 = _interopRequireDefault(_base); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - -/*istanbul ignore end*/var sentenceDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/sentenceDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; -sentenceDiff.tokenize = function (value) { - return value.split(/(\S.+?[.!?])(?=\s+|$)/); +module.exports = function forEach(obj, fn) { + if (!isFunction(fn)) { + throw new TypeError('iterator must be a function'); + } + var i, k, + isString = typeof obj === 'string', + l = obj.length, + context = arguments.length > 2 ? arguments[2] : null; + if (l === +l) { + for (i = 0; i < l; i++) { + if (context === null) { + fn(isString ? obj.charAt(i) : obj[i], i, obj); + } else { + fn.call(context, isString ? obj.charAt(i) : obj[i], i, obj); + } + } + } else { + for (k in obj) { + if (hasOwn.call(obj, k)) { + if (context === null) { + fn(obj[k], k, obj); + } else { + fn.call(context, obj[k], k, obj); + } + } + } + } }; -function diffSentences(oldStr, newStr, callback) { - return sentenceDiff.diff(oldStr, newStr, callback); -} - - -},{"./base":45}],51:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; - -exports.__esModule = true; -exports.wordDiff = undefined; -exports. /*istanbul ignore end*/diffWords = diffWords; -/*istanbul ignore start*/exports. /*istanbul ignore end*/diffWordsWithSpace = diffWordsWithSpace; -var /*istanbul ignore start*/_base = require('./base') /*istanbul ignore end*/; +},{}],61:[function(require,module,exports){ +"use strict"; -/*istanbul ignore start*/ -var _base2 = _interopRequireDefault(_base); +// modified from https://github.com/es-shims/es5-shim +var has = Object.prototype.hasOwnProperty, + toString = Object.prototype.toString, + forEach = require('./foreach'), + isArgs = require('./isArguments'), + hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'), + hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), + dontEnums = [ + "toString", + "toLocaleString", + "valueOf", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "constructor" + ]; -/*istanbul ignore end*/ -var /*istanbul ignore start*/_params = require('../util/params') /*istanbul ignore end*/; +var keysShim = function keys(object) { + var isObject = object !== null && typeof object === 'object', + isFunction = toString.call(object) === '[object Function]', + isArguments = isArgs(object), + theKeys = []; -/*istanbul ignore start*/ -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + if (!isObject && !isFunction && !isArguments) { + throw new TypeError("Object.keys called on a non-object"); + } -/*istanbul ignore end*/ + if (isArguments) { + forEach(object, function (value, index) { + theKeys.push(index); + }); + } else { + var name, + skipProto = hasProtoEnumBug && isFunction; -// Based on https://en.wikipedia.org/wiki/Latin_script_in_Unicode -// -// Ranges and exceptions: -// Latin-1 Supplement, 0080–00FF -// - U+00D7 × Multiplication sign -// - U+00F7 ÷ Division sign -// Latin Extended-A, 0100–017F -// Latin Extended-B, 0180–024F -// IPA Extensions, 0250–02AF -// Spacing Modifier Letters, 02B0–02FF -// - U+02C7 ˇ ˇ Caron -// - U+02D8 ˘ ˘ Breve -// - U+02D9 ˙ ˙ Dot Above -// - U+02DA ˚ ˚ Ring Above -// - U+02DB ˛ ˛ Ogonek -// - U+02DC ˜ ˜ Small Tilde -// - U+02DD ˝ ˝ Double Acute Accent -// Latin Extended Additional, 1E00–1EFF -var extendedWordChars = /^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/; + for (name in object) { + if (!(skipProto && name === 'prototype') && has.call(object, name)) { + theKeys.push(name); + } + } + } -var reWhitespace = /\S/; + if (hasDontEnumBug) { + var ctor = object.constructor, + skipConstructor = ctor && ctor.prototype === object; -var wordDiff = /*istanbul ignore start*/exports. /*istanbul ignore end*/wordDiff = new /*istanbul ignore start*/_base2['default']() /*istanbul ignore end*/; -wordDiff.equals = function (left, right) { - return left === right || this.options.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right); + forEach(dontEnums, function (dontEnum) { + if (!(skipConstructor && dontEnum === 'constructor') && has.call(object, dontEnum)) { + theKeys.push(dontEnum); + } + }); + } + return theKeys; }; -wordDiff.tokenize = function (value) { - var tokens = value.split(/(\s+|\b)/); - - // Join the boundary splits that we do not consider to be boundaries. This is primarily the extended Latin character set. - for (var i = 0; i < tokens.length - 1; i++) { - // If we have an empty string in the next field and we have only word chars before and after, merge - if (!tokens[i + 1] && tokens[i + 2] && extendedWordChars.test(tokens[i]) && extendedWordChars.test(tokens[i + 2])) { - tokens[i] += tokens[i + 2]; - tokens.splice(i + 1, 2); - i--; - } - } - return tokens; +keysShim.shim = function shimObjectKeys() { + if (!Object.keys) { + Object.keys = keysShim; + } + return Object.keys || keysShim; }; -function diffWords(oldStr, newStr, callback) { - var options = /*istanbul ignore start*/(0, _params.generateOptions) /*istanbul ignore end*/(callback, { ignoreWhitespace: true }); - return wordDiff.diff(oldStr, newStr, options); -} -function diffWordsWithSpace(oldStr, newStr, callback) { - return wordDiff.diff(oldStr, newStr, callback); -} - - -},{"../util/params":57,"./base":45}],52:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; - -exports.__esModule = true; -exports.canonicalize = exports.convertChangesToXML = exports.convertChangesToDMP = exports.parsePatch = exports.applyPatches = exports.applyPatch = exports.createPatch = exports.createTwoFilesPatch = exports.structuredPatch = exports.diffArrays = exports.diffJson = exports.diffCss = exports.diffSentences = exports.diffTrimmedLines = exports.diffLines = exports.diffWordsWithSpace = exports.diffWords = exports.diffChars = exports.Diff = undefined; -/*istanbul ignore end*/ -var /*istanbul ignore start*/_base = require('./diff/base') /*istanbul ignore end*/; - -/*istanbul ignore start*/ -var _base2 = _interopRequireDefault(_base); +module.exports = keysShim; -/*istanbul ignore end*/ -var /*istanbul ignore start*/_character = require('./diff/character') /*istanbul ignore end*/; -var /*istanbul ignore start*/_word = require('./diff/word') /*istanbul ignore end*/; +},{"./foreach":60,"./isArguments":62}],62:[function(require,module,exports){ +"use strict"; -var /*istanbul ignore start*/_line = require('./diff/line') /*istanbul ignore end*/; +var toString = Object.prototype.toString; -var /*istanbul ignore start*/_sentence = require('./diff/sentence') /*istanbul ignore end*/; +module.exports = function isArguments(value) { + var str = toString.call(value); + var isArguments = str === '[object Arguments]'; + if (!isArguments) { + isArguments = str !== '[object Array]' + && value !== null + && typeof value === 'object' + && typeof value.length === 'number' + && value.length >= 0 + && toString.call(value.callee) === '[object Function]'; + } + return isArguments; +}; -var /*istanbul ignore start*/_css = require('./diff/css') /*istanbul ignore end*/; -var /*istanbul ignore start*/_json = require('./diff/json') /*istanbul ignore end*/; +},{}],63:[function(require,module,exports){ -var /*istanbul ignore start*/_array = require('./diff/array') /*istanbul ignore end*/; +/** + * Module dependencies. + */ -var /*istanbul ignore start*/_apply = require('./patch/apply') /*istanbul ignore end*/; +var map = require('array-map'); +var indexOf = require('indexof'); +var isArray = require('isarray'); +var forEach = require('foreach'); +var reduce = require('array-reduce'); +var getObjectKeys = require('object-keys'); +var JSON = require('json3'); -var /*istanbul ignore start*/_parse = require('./patch/parse') /*istanbul ignore end*/; +/** + * Make sure `Object.keys` work for `undefined` + * values that are still there, like `document.all`. + * http://lists.w3.org/Archives/Public/public-html/2009Jun/0546.html + * + * @api private + */ -var /*istanbul ignore start*/_create = require('./patch/create') /*istanbul ignore end*/; +function objectKeys(val){ + if (Object.keys) return Object.keys(val); + return getObjectKeys(val); +} -var /*istanbul ignore start*/_dmp = require('./convert/dmp') /*istanbul ignore end*/; +/** + * Module exports. + */ -var /*istanbul ignore start*/_xml = require('./convert/xml') /*istanbul ignore end*/; +module.exports = inspect; -/*istanbul ignore start*/ -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + * @license MIT (© Joyent) + */ +/* legacy: obj, showHidden, depth, colors*/ -exports. /*istanbul ignore end*/Diff = _base2['default']; -/*istanbul ignore start*/exports. /*istanbul ignore end*/diffChars = _character.diffChars; -/*istanbul ignore start*/exports. /*istanbul ignore end*/diffWords = _word.diffWords; -/*istanbul ignore start*/exports. /*istanbul ignore end*/diffWordsWithSpace = _word.diffWordsWithSpace; -/*istanbul ignore start*/exports. /*istanbul ignore end*/diffLines = _line.diffLines; -/*istanbul ignore start*/exports. /*istanbul ignore end*/diffTrimmedLines = _line.diffTrimmedLines; -/*istanbul ignore start*/exports. /*istanbul ignore end*/diffSentences = _sentence.diffSentences; -/*istanbul ignore start*/exports. /*istanbul ignore end*/diffCss = _css.diffCss; -/*istanbul ignore start*/exports. /*istanbul ignore end*/diffJson = _json.diffJson; -/*istanbul ignore start*/exports. /*istanbul ignore end*/diffArrays = _array.diffArrays; -/*istanbul ignore start*/exports. /*istanbul ignore end*/structuredPatch = _create.structuredPatch; -/*istanbul ignore start*/exports. /*istanbul ignore end*/createTwoFilesPatch = _create.createTwoFilesPatch; -/*istanbul ignore start*/exports. /*istanbul ignore end*/createPatch = _create.createPatch; -/*istanbul ignore start*/exports. /*istanbul ignore end*/applyPatch = _apply.applyPatch; -/*istanbul ignore start*/exports. /*istanbul ignore end*/applyPatches = _apply.applyPatches; -/*istanbul ignore start*/exports. /*istanbul ignore end*/parsePatch = _parse.parsePatch; -/*istanbul ignore start*/exports. /*istanbul ignore end*/convertChangesToDMP = _dmp.convertChangesToDMP; -/*istanbul ignore start*/exports. /*istanbul ignore end*/convertChangesToXML = _xml.convertChangesToXML; -/*istanbul ignore start*/exports. /*istanbul ignore end*/canonicalize = _json.canonicalize; /* See LICENSE file for terms of use */ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + _extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} -/* - * Text diff implementation. - * - * This library supports the following APIS: - * JsDiff.diffChars: Character by character diff - * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace - * JsDiff.diffLines: Line based diff - * - * JsDiff.diffCss: Diff targeted at CSS content - * - * These methods are based on the implementation proposed in - * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986). - * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927 - */ +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; -},{"./convert/dmp":42,"./convert/xml":43,"./diff/array":44,"./diff/base":45,"./diff/character":46,"./diff/css":47,"./diff/json":48,"./diff/line":49,"./diff/sentence":50,"./diff/word":51,"./patch/apply":53,"./patch/create":54,"./patch/parse":55}],53:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; +function stylizeNoColor(str, styleType) { + return str; +} -exports.__esModule = true; -exports. /*istanbul ignore end*/applyPatch = applyPatch; -/*istanbul ignore start*/exports. /*istanbul ignore end*/applyPatches = applyPatches; +function isBoolean(arg) { + return typeof arg === 'boolean'; +} -var /*istanbul ignore start*/_parse = require('./parse') /*istanbul ignore end*/; +function isUndefined(arg) { + return arg === void 0; +} -var /*istanbul ignore start*/_distanceIterator = require('../util/distance-iterator') /*istanbul ignore end*/; +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; -/*istanbul ignore start*/ -var _distanceIterator2 = _interopRequireDefault(_distanceIterator); + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } +function isFunction(arg) { + return typeof arg === 'function'; +} -/*istanbul ignore end*/function applyPatch(source, uniDiff) { - /*istanbul ignore start*/var /*istanbul ignore end*/options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; +function isString(arg) { + return typeof arg === 'string'; +} - if (typeof uniDiff === 'string') { - uniDiff = /*istanbul ignore start*/(0, _parse.parsePatch) /*istanbul ignore end*/(uniDiff); - } +function isNumber(arg) { + return typeof arg === 'number'; +} - if (Array.isArray(uniDiff)) { - if (uniDiff.length > 1) { - throw new Error('applyPatch only works with a single input.'); - } +function isNull(arg) { + return arg === null; +} - uniDiff = uniDiff[0]; - } +function hasOwn(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} - // Apply the diff to the input - var lines = source.split(/\r\n|[\n\v\f\r\x85]/), - delimiters = source.match(/\r\n|[\n\v\f\r\x85]/g) || [], - hunks = uniDiff.hunks, - compareLine = options.compareLine || function (lineNumber, line, operation, patchContent) /*istanbul ignore start*/{ - return (/*istanbul ignore end*/line === patchContent - ); - }, - errorCount = 0, - fuzzFactor = options.fuzzFactor || 0, - minLine = 0, - offset = 0, - removeEOFNL = /*istanbul ignore start*/void 0 /*istanbul ignore end*/, - addEOFNL = /*istanbul ignore start*/void 0 /*istanbul ignore end*/; +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} - /** - * Checks if the hunk exactly fits on the provided location - */ - function hunkFits(hunk, toPos) { - for (var j = 0; j < hunk.lines.length; j++) { - var line = hunk.lines[j], - operation = line[0], - content = line.substr(1); +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} - if (operation === ' ' || operation === '-') { - // Context sanity check - if (!compareLine(toPos + 1, lines[toPos], operation, content)) { - errorCount++; +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} - if (errorCount > fuzzFactor) { - return false; - } - } - toPos++; - } - } +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} - return true; - } +function objectToString(o) { + return Object.prototype.toString.call(o); +} - // Search best fit offsets for each hunk based on the previous ones - for (var i = 0; i < hunks.length; i++) { - var hunk = hunks[i], - maxLine = lines.length - hunk.oldLines, - localOffset = 0, - toPos = offset + hunk.oldStart - 1; +function arrayToHash(array) { + var hash = {}; - var iterator = /*istanbul ignore start*/(0, _distanceIterator2['default']) /*istanbul ignore end*/(toPos, minLine, maxLine); + forEach(array, function(val, idx) { + hash[val] = true; + }); - for (; localOffset !== undefined; localOffset = iterator()) { - if (hunkFits(hunk, toPos + localOffset)) { - hunk.offset = offset += localOffset; - break; - } - } + return hash; +} - if (localOffset === undefined) { - return false; +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwn(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); } - - // Set lower text limit to end of the current hunk, so next ones don't try - // to fit over already patched text - minLine = hunk.offset + hunk.oldStart + hunk.oldLines; } - - // Apply patch hunks - for (var _i = 0; _i < hunks.length; _i++) { - var _hunk = hunks[_i], - _toPos = _hunk.offset + _hunk.newStart - 1; - if (_hunk.newLines == 0) { - _toPos++; + forEach(keys, function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); } + }); + return output; +} - for (var j = 0; j < _hunk.lines.length; j++) { - var line = _hunk.lines[j], - operation = line[0], - content = line.substr(1), - delimiter = _hunk.linedelimiters[j]; +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} - if (operation === ' ') { - _toPos++; - } else if (operation === '-') { - lines.splice(_toPos, 1); - delimiters.splice(_toPos, 1); - /* istanbul ignore else */ - } else if (operation === '+') { - lines.splice(_toPos, 0, content); - delimiters.splice(_toPos, 0, delimiter); - _toPos++; - } else if (operation === '\\') { - var previousOperation = _hunk.lines[j - 1] ? _hunk.lines[j - 1][0] : null; - if (previousOperation === '+') { - removeEOFNL = true; - } else if (previousOperation === '-') { - addEOFNL = true; - } - } +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); } + return ret; } - // Handle EOFNL insertion/removal - if (removeEOFNL) { - while (!lines[lines.length - 1]) { - lines.pop(); - delimiters.pop(); - } - } else if (addEOFNL) { - lines.push(''); - delimiters.push('\n'); + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; } - for (var _k = 0; _k < lines.length - 1; _k++) { - lines[_k] = lines[_k] + delimiters[_k]; + + // Look up the keys of the object. + var keys = objectKeys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden && Object.getOwnPropertyNames) { + keys = Object.getOwnPropertyNames(value); } - return lines.join(''); -} -// Wrapper that supports multiple file patches via callbacks. -function applyPatches(uniDiff, options) { - if (typeof uniDiff === 'string') { - uniDiff = /*istanbul ignore start*/(0, _parse.parsePatch) /*istanbul ignore end*/(uniDiff); + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (indexOf(keys, 'message') >= 0 || indexOf(keys, 'description') >= 0)) { + return formatError(value); } - var currentIndex = 0; - function processIndex() { - var index = uniDiff[currentIndex++]; - if (!index) { - return options.complete(); + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } - options.loadFile(index, function (err, data) { - if (err) { - return options.complete(err); - } - - var updatedContent = applyPatch(data, index, options); - options.patched(index, updatedContent, function (err) { - if (err) { - return options.complete(err); - } + var base = '', array = false, braces = ['{', '}']; - processIndex(); - }); - }); + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; } - processIndex(); -} - -},{"../util/distance-iterator":56,"./parse":55}],54:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } -exports.__esModule = true; -exports. /*istanbul ignore end*/structuredPatch = structuredPatch; -/*istanbul ignore start*/exports. /*istanbul ignore end*/createTwoFilesPatch = createTwoFilesPatch; -/*istanbul ignore start*/exports. /*istanbul ignore end*/createPatch = createPatch; + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } -var /*istanbul ignore start*/_line = require('../diff/line') /*istanbul ignore end*/; + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } -/*istanbul ignore start*/ -function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } -/*istanbul ignore end*/function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - if (!options) { - options = {}; + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; } - if (typeof options.context === 'undefined') { - options.context = 4; + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } } - var diff = /*istanbul ignore start*/(0, _line.diffLines) /*istanbul ignore end*/(oldStr, newStr, options); - diff.push({ value: '', lines: [] }); // Append an empty value to make cleanup easier + ctx.seen.push(value); - function contextLines(lines) { - return lines.map(function (entry) { - return ' ' + entry; + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = map(keys, function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); }); } - var hunks = []; - var oldRangeStart = 0, - newRangeStart = 0, - curRange = [], - oldLine = 1, - newLine = 1; - /*istanbul ignore start*/ - var _loop = function _loop( /*istanbul ignore end*/i) { - var current = diff[i], - lines = current.lines || current.value.replace(/\n$/, '').split('\n'); - current.lines = lines; - - if (current.added || current.removed) { - /*istanbul ignore start*/ - var _curRange; - - /*istanbul ignore end*/ - // If we have previous context, start with that - if (!oldRangeStart) { - var prev = diff[i - 1]; - oldRangeStart = oldLine; - newRangeStart = newLine; - - if (prev) { - curRange = options.context > 0 ? contextLines(prev.lines.slice(-options.context)) : []; - oldRangeStart -= curRange.length; - newRangeStart -= curRange.length; - } - } + ctx.seen.pop(); - // Output our changes - /*istanbul ignore start*/(_curRange = /*istanbul ignore end*/curRange).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_curRange /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/lines.map(function (entry) { - return (current.added ? '+' : '-') + entry; - }))); + return reduceToSingleString(output, base, braces); +} - // Track the updated file position - if (current.added) { - newLine += lines.length; +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = { value: value[key] }; + if (Object.getOwnPropertyDescriptor) { + desc = Object.getOwnPropertyDescriptor(value, key) || desc; + } + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwn(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (indexOf(ctx.seen, desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); } else { - oldLine += lines.length; + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = map(str.split('\n'), function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + map(str.split('\n'), function(line) { + return ' ' + line; + }).join('\n'); + } } } else { - // Identical context lines. Track line changes - if (oldRangeStart) { - // Close out any changes that have been output (or join overlapping) - if (lines.length <= options.context * 2 && i < diff.length - 2) { - /*istanbul ignore start*/ - var _curRange2; + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } - /*istanbul ignore end*/ - // Overlapping - /*istanbul ignore start*/(_curRange2 = /*istanbul ignore end*/curRange).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_curRange2 /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/contextLines(lines))); - } else { - /*istanbul ignore start*/ - var _curRange3; + return name + ': ' + str; +} - /*istanbul ignore end*/ - // end the range and output - var contextSize = Math.min(lines.length, options.context); - /*istanbul ignore start*/(_curRange3 = /*istanbul ignore end*/curRange).push. /*istanbul ignore start*/apply /*istanbul ignore end*/( /*istanbul ignore start*/_curRange3 /*istanbul ignore end*/, /*istanbul ignore start*/_toConsumableArray( /*istanbul ignore end*/contextLines(lines.slice(0, contextSize)))); - - var hunk = { - oldStart: oldRangeStart, - oldLines: oldLine - oldRangeStart + contextSize, - newStart: newRangeStart, - newLines: newLine - newRangeStart + contextSize, - lines: curRange - }; - if (i >= diff.length - 2 && lines.length <= options.context) { - // EOF is inside this hunk - var oldEOFNewline = /\n$/.test(oldStr); - var newEOFNewline = /\n$/.test(newStr); - if (lines.length == 0 && !oldEOFNewline) { - // special case: old has no eol and no trailing context; no-nl can end up before adds - curRange.splice(hunk.oldLines, 0, '\\ No newline at end of file'); - } else if (!oldEOFNewline || !newEOFNewline) { - curRange.push('\\ No newline at end of file'); - } - } - hunks.push(hunk); - - oldRangeStart = 0; - newRangeStart = 0; - curRange = []; - } - } - oldLine += lines.length; - newLine += lines.length; - } - }; - - for (var i = 0; i < diff.length; i++) { - /*istanbul ignore start*/ - _loop( /*istanbul ignore end*/i); +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); } - - return { - oldFileName: oldFileName, newFileName: newFileName, - oldHeader: oldHeader, newHeader: newHeader, - hunks: hunks - }; + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); } -function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) { - var diff = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options); - - var ret = []; - if (oldFileName == newFileName) { - ret.push('Index: ' + oldFileName); - } - ret.push('==================================================================='); - ret.push('--- ' + diff.oldFileName + (typeof diff.oldHeader === 'undefined' ? '' : '\t' + diff.oldHeader)); - ret.push('+++ ' + diff.newFileName + (typeof diff.newHeader === 'undefined' ? '' : '\t' + diff.newHeader)); +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = reduce(output, function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); - for (var i = 0; i < diff.hunks.length; i++) { - var hunk = diff.hunks[i]; - ret.push('@@ -' + hunk.oldStart + ',' + hunk.oldLines + ' +' + hunk.newStart + ',' + hunk.newLines + ' @@'); - ret.push.apply(ret, hunk.lines); + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; } - return ret.join('\n') + '\n'; -} - -function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { - return createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader, options); + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; } +function _extend(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; -},{"../diff/line":49}],55:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; - -exports.__esModule = true; -exports. /*istanbul ignore end*/parsePatch = parsePatch; -function parsePatch(uniDiff) { - /*istanbul ignore start*/var /*istanbul ignore end*/options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; - - var diffstr = uniDiff.split(/\r\n|[\n\v\f\r\x85]/), - delimiters = uniDiff.match(/\r\n|[\n\v\f\r\x85]/g) || [], - list = [], - i = 0; - - function parseIndex() { - var index = {}; - list.push(index); - - // Parse diff metadata - while (i < diffstr.length) { - var line = diffstr[i]; - - // File header found, end parsing diff metadata - if (/^(\-\-\-|\+\+\+|@@)\s/.test(line)) { - break; - } - - // Diff index - var header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line); - if (header) { - index.index = header[1]; - } - - i++; - } - - // Parse file headers if they are defined. Unified diff requires them, but - // there's no technical issues to have an isolated hunk without file header - parseFileHeader(index); - parseFileHeader(index); - - // Parse hunks - index.hunks = []; - - while (i < diffstr.length) { - var _line = diffstr[i]; - - if (/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(_line)) { - break; - } else if (/^@@/.test(_line)) { - index.hunks.push(parseHunk()); - } else if (_line && options.strict) { - // Ignore unexpected content unless in strict mode - throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(_line)); - } else { - i++; - } - } + var keys = objectKeys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; } + return origin; +} - // Parses the --- and +++ headers, if none are found, no lines - // are consumed. - function parseFileHeader(index) { - var headerPattern = /^(---|\+\+\+)\s+([\S ]*)(?:\t(.*?)\s*)?$/; - var fileHeader = headerPattern.exec(diffstr[i]); - if (fileHeader) { - var keyPrefix = fileHeader[1] === '---' ? 'old' : 'new'; - index[keyPrefix + 'FileName'] = fileHeader[2]; - index[keyPrefix + 'Header'] = fileHeader[3]; +},{"array-map":29,"array-reduce":30,"foreach":57,"indexof":58,"isarray":59,"json3":64,"object-keys":61}],64:[function(require,module,exports){ +(function (global){ +/*! JSON v3.3.0 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */ +;(function (root) { + // Detect the `define` function exposed by asynchronous module loaders. The + // strict `define` check is necessary for compatibility with `r.js`. + var isLoader = typeof define === "function" && define.amd; - i++; - } + // Use the `global` object exposed by Node (including Browserify via + // `insert-module-globals`), Narwhal, and Ringo as the default context. + // Rhino exports a `global` function instead. + var freeGlobal = typeof global == "object" && global; + if (freeGlobal && (freeGlobal["global"] === freeGlobal || freeGlobal["window"] === freeGlobal)) { + root = freeGlobal; } - // Parses a hunk - // This assumes that we are at the start of a hunk. - function parseHunk() { - var chunkHeaderIndex = i, - chunkHeaderLine = diffstr[i++], - chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); - - var hunk = { - oldStart: +chunkHeader[1], - oldLines: +chunkHeader[2] || 1, - newStart: +chunkHeader[3], - newLines: +chunkHeader[4] || 1, - lines: [], - linedelimiters: [] - }; - - var addCount = 0, - removeCount = 0; - for (; i < diffstr.length; i++) { - // Lines starting with '---' could be mistaken for the "remove line" operation - // But they could be the header for the next file. Therefore prune such cases out. - if (diffstr[i].indexOf('--- ') === 0 && i + 2 < diffstr.length && diffstr[i + 1].indexOf('+++ ') === 0 && diffstr[i + 2].indexOf('@@') === 0) { - break; - } - var operation = diffstr[i][0]; - - if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') { - hunk.lines.push(diffstr[i]); - hunk.linedelimiters.push(delimiters[i] || '\n'); + // Public: Initializes JSON 3 using the given `context` object, attaching the + // `stringify` and `parse` functions to the specified `exports` object. + function runInContext(context, exports) { + context || (context = root["Object"]()); + exports || (exports = root["Object"]()); - if (operation === '+') { - addCount++; - } else if (operation === '-') { - removeCount++; - } else if (operation === ' ') { - addCount++; - removeCount++; - } - } else { - break; - } - } + // Native constructor aliases. + var Number = context["Number"] || root["Number"], + String = context["String"] || root["String"], + Object = context["Object"] || root["Object"], + Date = context["Date"] || root["Date"], + SyntaxError = context["SyntaxError"] || root["SyntaxError"], + TypeError = context["TypeError"] || root["TypeError"], + Math = context["Math"] || root["Math"], + nativeJSON = context["JSON"] || root["JSON"]; - // Handle the empty block count case - if (!addCount && hunk.newLines === 1) { - hunk.newLines = 0; - } - if (!removeCount && hunk.oldLines === 1) { - hunk.oldLines = 0; + // Delegate to the native `stringify` and `parse` implementations. + if (typeof nativeJSON == "object" && nativeJSON) { + exports.stringify = nativeJSON.stringify; + exports.parse = nativeJSON.parse; } - // Perform optional sanity checking - if (options.strict) { - if (addCount !== hunk.newLines) { - throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); - } - if (removeCount !== hunk.oldLines) { - throw new Error('Removed line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); - } - } - - return hunk; - } - - while (i < diffstr.length) { - parseIndex(); - } - - return list; -} - - -},{}],56:[function(require,module,exports){ -/*istanbul ignore start*/"use strict"; - -exports.__esModule = true; - -exports["default"] = /*istanbul ignore end*/function (start, minLine, maxLine) { - var wantForward = true, - backwardExhausted = false, - forwardExhausted = false, - localOffset = 1; - - return function iterator() { - if (wantForward && !forwardExhausted) { - if (backwardExhausted) { - localOffset++; - } else { - wantForward = false; - } - - // Check if trying to fit beyond text length, and if not, check it fits - // after offset location (or desired location on first iteration) - if (start + localOffset <= maxLine) { - return localOffset; - } - - forwardExhausted = true; - } - - if (!backwardExhausted) { - if (!forwardExhausted) { - wantForward = true; - } - - // Check if trying to fit before text beginning, and if not, check it fits - // before offset location - if (minLine <= start - localOffset) { - return -localOffset++; - } - - backwardExhausted = true; - return iterator(); - } - - // We tried to fit hunk before text beginning and beyond text lenght, then - // hunk can't fit on the text. Return undefined - }; -}; - - -},{}],57:[function(require,module,exports){ -/*istanbul ignore start*/'use strict'; - -exports.__esModule = true; -exports. /*istanbul ignore end*/generateOptions = generateOptions; -function generateOptions(options, defaults) { - if (typeof options === 'function') { - defaults.callback = options; - } else if (options) { - for (var name in options) { - /* istanbul ignore else */ - if (options.hasOwnProperty(name)) { - defaults[name] = options[name]; - } - } - } - return defaults; -} - - -},{}],58:[function(require,module,exports){ - -var hasOwn = Object.prototype.hasOwnProperty; -var toString = Object.prototype.toString; - -module.exports = function forEach (obj, fn, ctx) { - if (toString.call(fn) !== '[object Function]') { - throw new TypeError('iterator must be a function'); - } - var l = obj.length; - if (l === +l) { - for (var i = 0; i < l; i++) { - fn.call(ctx, obj[i], i, obj); - } - } else { - for (var k in obj) { - if (hasOwn.call(obj, k)) { - fn.call(ctx, obj[k], k, obj); - } - } - } -}; - - -},{}],59:[function(require,module,exports){ - -var indexOf = [].indexOf; - -module.exports = function(arr, obj){ - if (indexOf) return arr.indexOf(obj); - for (var i = 0; i < arr.length; ++i) { - if (arr[i] === obj) return i; - } - return -1; -}; -},{}],60:[function(require,module,exports){ -module.exports = Array.isArray || function (arr) { - return Object.prototype.toString.call(arr) == '[object Array]'; -}; - -},{}],61:[function(require,module,exports){ -(function (global){ -/*! JSON v3.3.0 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */ -;(function (root) { - // Detect the `define` function exposed by asynchronous module loaders. The - // strict `define` check is necessary for compatibility with `r.js`. - var isLoader = typeof define === "function" && define.amd; - - // Use the `global` object exposed by Node (including Browserify via - // `insert-module-globals`), Narwhal, and Ringo as the default context. - // Rhino exports a `global` function instead. - var freeGlobal = typeof global == "object" && global; - if (freeGlobal && (freeGlobal["global"] === freeGlobal || freeGlobal["window"] === freeGlobal)) { - root = freeGlobal; - } - - // Public: Initializes JSON 3 using the given `context` object, attaching the - // `stringify` and `parse` functions to the specified `exports` object. - function runInContext(context, exports) { - context || (context = root["Object"]()); - exports || (exports = root["Object"]()); - - // Native constructor aliases. - var Number = context["Number"] || root["Number"], - String = context["String"] || root["String"], - Object = context["Object"] || root["Object"], - Date = context["Date"] || root["Date"], - SyntaxError = context["SyntaxError"] || root["SyntaxError"], - TypeError = context["TypeError"] || root["TypeError"], - Math = context["Math"] || root["Math"], - nativeJSON = context["JSON"] || root["JSON"]; - - // Delegate to the native `stringify` and `parse` implementations. - if (typeof nativeJSON == "object" && nativeJSON) { - exports.stringify = nativeJSON.stringify; - exports.parse = nativeJSON.parse; - } - - // Convenience aliases. - var objectProto = Object.prototype, - getClass = objectProto.toString, - isProperty, forEach, undef; + // Convenience aliases. + var objectProto = Object.prototype, + getClass = objectProto.toString, + isProperty, forEach, undef; // Test the `Date#getUTC*` methods. Based on work by @Yaffle. var isExtended = new Date(-3509827334573292); @@ -8838,691 +7917,145 @@ module.exports = Array.isArray || function (arr) { if (value == ",") { value = lex(); if (value == "]") { - // Unexpected trailing `,` in array literal. - abort(); - } - } else { - // A `,` must separate each array element. - abort(); - } - } - // Elisions and leading commas are not permitted. - if (value == ",") { - abort(); - } - results.push(get(value)); - } - return results; - } else if (value == "{") { - // Parses a JSON object, returning a new JavaScript object. - results = {}; - for (;; hasMembers || (hasMembers = true)) { - value = lex(); - // A closing curly brace marks the end of the object literal. - if (value == "}") { - break; - } - // If the object literal contains members, the current token - // should be a comma separator. - if (hasMembers) { - if (value == ",") { - value = lex(); - if (value == "}") { - // Unexpected trailing `,` in object literal. - abort(); - } - } else { - // A `,` must separate each object member. - abort(); - } - } - // Leading commas are not permitted, object property names must be - // double-quoted strings, and a `:` must separate each property - // name and value. - if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") { - abort(); - } - results[value.slice(1)] = get(lex()); - } - return results; - } - // Unexpected token encountered. - abort(); - } - return value; - }; - - // Internal: Updates a traversed object member. - var update = function (source, property, callback) { - var element = walk(source, property, callback); - if (element === undef) { - delete source[property]; - } else { - source[property] = element; - } - }; - - // Internal: Recursively traverses a parsed JSON object, invoking the - // `callback` function for each value. This is an implementation of the - // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2. - var walk = function (source, property, callback) { - var value = source[property], length; - if (typeof value == "object" && value) { - // `forEach` can't be used to traverse an array in Opera <= 8.54 - // because its `Object#hasOwnProperty` implementation returns `false` - // for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`). - if (getClass.call(value) == arrayClass) { - for (length = value.length; length--;) { - update(value, length, callback); - } - } else { - forEach(value, function (property) { - update(value, property, callback); - }); - } - } - return callback.call(source, property, value); - }; - - // Public: `JSON.parse`. See ES 5.1 section 15.12.2. - exports.parse = function (source, callback) { - var result, value; - Index = 0; - Source = "" + source; - result = get(lex()); - // If a JSON string contains multiple tokens, it is invalid. - if (lex() != "$") { - abort(); - } - // Reset the parser state. - Index = Source = null; - return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result; - }; - } - } - - exports["runInContext"] = runInContext; - return exports; - } - - if (typeof exports == "object" && exports && !exports.nodeType && !isLoader) { - // Export for CommonJS environments. - runInContext(root, exports); - } else { - // Export for web browsers and JavaScript engines. - var nativeJSON = root.JSON; - var JSON3 = runInContext(root, (root["JSON3"] = { - // Public: Restores the original value of the global `JSON` object and - // returns a reference to the `JSON3` object. - "noConflict": function () { - root.JSON = nativeJSON; - return JSON3; - } - })); - - root.JSON = { - "parse": JSON3.parse, - "stringify": JSON3.stringify - }; - } - - // Export for asynchronous module loaders. - if (isLoader) { - define(function () { - return JSON3; - }); - } -}(this)); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],62:[function(require,module,exports){ -"use strict"; - -var hasOwn = Object.prototype.hasOwnProperty; -var toString = Object.prototype.toString; - -var isFunction = function (fn) { - return (typeof fn === 'function' && !(fn instanceof RegExp)) || toString.call(fn) === '[object Function]'; -}; - -module.exports = function forEach(obj, fn) { - if (!isFunction(fn)) { - throw new TypeError('iterator must be a function'); - } - var i, k, - isString = typeof obj === 'string', - l = obj.length, - context = arguments.length > 2 ? arguments[2] : null; - if (l === +l) { - for (i = 0; i < l; i++) { - if (context === null) { - fn(isString ? obj.charAt(i) : obj[i], i, obj); - } else { - fn.call(context, isString ? obj.charAt(i) : obj[i], i, obj); - } - } - } else { - for (k in obj) { - if (hasOwn.call(obj, k)) { - if (context === null) { - fn(obj[k], k, obj); - } else { - fn.call(context, obj[k], k, obj); - } - } - } - } -}; - - -},{}],63:[function(require,module,exports){ -"use strict"; - -// modified from https://github.com/es-shims/es5-shim -var has = Object.prototype.hasOwnProperty, - toString = Object.prototype.toString, - forEach = require('./foreach'), - isArgs = require('./isArguments'), - hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'), - hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), - dontEnums = [ - "toString", - "toLocaleString", - "valueOf", - "hasOwnProperty", - "isPrototypeOf", - "propertyIsEnumerable", - "constructor" - ]; - -var keysShim = function keys(object) { - var isObject = object !== null && typeof object === 'object', - isFunction = toString.call(object) === '[object Function]', - isArguments = isArgs(object), - theKeys = []; - - if (!isObject && !isFunction && !isArguments) { - throw new TypeError("Object.keys called on a non-object"); - } - - if (isArguments) { - forEach(object, function (value, index) { - theKeys.push(index); - }); - } else { - var name, - skipProto = hasProtoEnumBug && isFunction; - - for (name in object) { - if (!(skipProto && name === 'prototype') && has.call(object, name)) { - theKeys.push(name); - } - } - } - - if (hasDontEnumBug) { - var ctor = object.constructor, - skipConstructor = ctor && ctor.prototype === object; - - forEach(dontEnums, function (dontEnum) { - if (!(skipConstructor && dontEnum === 'constructor') && has.call(object, dontEnum)) { - theKeys.push(dontEnum); - } - }); - } - return theKeys; -}; - -keysShim.shim = function shimObjectKeys() { - if (!Object.keys) { - Object.keys = keysShim; - } - return Object.keys || keysShim; -}; - -module.exports = keysShim; - - -},{"./foreach":62,"./isArguments":64}],64:[function(require,module,exports){ -"use strict"; - -var toString = Object.prototype.toString; - -module.exports = function isArguments(value) { - var str = toString.call(value); - var isArguments = str === '[object Arguments]'; - if (!isArguments) { - isArguments = str !== '[object Array]' - && value !== null - && typeof value === 'object' - && typeof value.length === 'number' - && value.length >= 0 - && toString.call(value.callee) === '[object Function]'; - } - return isArguments; -}; - - -},{}],65:[function(require,module,exports){ - -/** - * Module dependencies. - */ - -var map = require('array-map'); -var indexOf = require('indexof'); -var isArray = require('isarray'); -var forEach = require('foreach'); -var reduce = require('array-reduce'); -var getObjectKeys = require('object-keys'); -var JSON = require('json3'); - -/** - * Make sure `Object.keys` work for `undefined` - * values that are still there, like `document.all`. - * http://lists.w3.org/Archives/Public/public-html/2009Jun/0546.html - * - * @api private - */ - -function objectKeys(val){ - if (Object.keys) return Object.keys(val); - return getObjectKeys(val); -} - -/** - * Module exports. - */ - -module.exports = inspect; - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - * @license MIT (© Joyent) - */ -/* legacy: obj, showHidden, depth, colors*/ - -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - _extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; - -function stylizeNoColor(str, styleType) { - return str; -} - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} - -function isUndefined(arg) { - return arg === void 0; -} - -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; - - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} - -function isFunction(arg) { - return typeof arg === 'function'; -} - -function isString(arg) { - return typeof arg === 'string'; -} - -function isNumber(arg) { - return typeof arg === 'number'; -} - -function isNull(arg) { - return arg === null; -} - -function hasOwn(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} - -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} - -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - -function arrayToHash(array) { - var hash = {}; - - forEach(array, function(val, idx) { - hash[val] = true; - }); - - return hash; -} - -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwn(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - forEach(keys, function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} - -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} - -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // Look up the keys of the object. - var keys = objectKeys(value); - var visibleKeys = arrayToHash(keys); - - if (ctx.showHidden && Object.getOwnPropertyNames) { - keys = Object.getOwnPropertyNames(value); - } - - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (indexOf(keys, 'message') >= 0 || indexOf(keys, 'description') >= 0)) { - return formatError(value); - } - - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } + // Unexpected trailing `,` in array literal. + abort(); + } + } else { + // A `,` must separate each array element. + abort(); + } + } + // Elisions and leading commas are not permitted. + if (value == ",") { + abort(); + } + results.push(get(value)); + } + return results; + } else if (value == "{") { + // Parses a JSON object, returning a new JavaScript object. + results = {}; + for (;; hasMembers || (hasMembers = true)) { + value = lex(); + // A closing curly brace marks the end of the object literal. + if (value == "}") { + break; + } + // If the object literal contains members, the current token + // should be a comma separator. + if (hasMembers) { + if (value == ",") { + value = lex(); + if (value == "}") { + // Unexpected trailing `,` in object literal. + abort(); + } + } else { + // A `,` must separate each object member. + abort(); + } + } + // Leading commas are not permitted, object property names must be + // double-quoted strings, and a `:` must separate each property + // name and value. + if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") { + abort(); + } + results[value.slice(1)] = get(lex()); + } + return results; + } + // Unexpected token encountered. + abort(); + } + return value; + }; - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } + // Internal: Updates a traversed object member. + var update = function (source, property, callback) { + var element = walk(source, property, callback); + if (element === undef) { + delete source[property]; + } else { + source[property] = element; + } + }; - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } + // Internal: Recursively traverses a parsed JSON object, invoking the + // `callback` function for each value. This is an implementation of the + // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2. + var walk = function (source, property, callback) { + var value = source[property], length; + if (typeof value == "object" && value) { + // `forEach` can't be used to traverse an array in Opera <= 8.54 + // because its `Object#hasOwnProperty` implementation returns `false` + // for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`). + if (getClass.call(value) == arrayClass) { + for (length = value.length; length--;) { + update(value, length, callback); + } + } else { + forEach(value, function (property) { + update(value, property, callback); + }); + } + } + return callback.call(source, property, value); + }; - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); + // Public: `JSON.parse`. See ES 5.1 section 15.12.2. + exports.parse = function (source, callback) { + var result, value; + Index = 0; + Source = "" + source; + result = get(lex()); + // If a JSON string contains multiple tokens, it is invalid. + if (lex() != "$") { + abort(); + } + // Reset the parser state. + Index = Source = null; + return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result; + }; + } } - } - - ctx.seen.push(value); - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = map(keys, function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); + exports["runInContext"] = runInContext; + return exports; } - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -} - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = { value: value[key] }; - if (Object.getOwnPropertyDescriptor) { - desc = Object.getOwnPropertyDescriptor(value, key) || desc; - } - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } + if (typeof exports == "object" && exports && !exports.nodeType && !isLoader) { + // Export for CommonJS environments. + runInContext(root, exports); } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwn(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (indexOf(ctx.seen, desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = map(str.split('\n'), function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + map(str.split('\n'), function(line) { - return ' ' + line; - }).join('\n'); - } + // Export for web browsers and JavaScript engines. + var nativeJSON = root.JSON; + var JSON3 = runInContext(root, (root["JSON3"] = { + // Public: Restores the original value of the global `JSON` object and + // returns a reference to the `JSON3` object. + "noConflict": function () { + root.JSON = nativeJSON; + return JSON3; } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} + })); -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); + root.JSON = { + "parse": JSON3.parse, + "stringify": JSON3.stringify + }; } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = reduce(output, function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; + // Export for asynchronous module loaders. + if (isLoader) { + define(function () { + return JSON3; + }); } +}(this)); - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - -function _extend(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - - var keys = objectKeys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; -} +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"array-map":30,"array-reduce":31,"foreach":58,"indexof":59,"isarray":60,"json3":61,"object-keys":63}],66:[function(require,module,exports){ +},{}],65:[function(require,module,exports){ "use strict" // This is a reporter that mimics Mocha's `dot` reporter @@ -9576,14 +8109,14 @@ module.exports = R.on("dot", { }, }) -},{"../lib/reporter":22}],67:[function(require,module,exports){ +},{"../lib/reporter":21}],66:[function(require,module,exports){ "use strict" exports.dot = require("./dot") exports.spec = require("./spec") exports.tap = require("./tap") -},{"./dot":66,"./spec":68,"./tap":69}],68:[function(require,module,exports){ +},{"./dot":65,"./spec":67,"./tap":68}],67:[function(require,module,exports){ "use strict" // This is a reporter that mimics Mocha's `spec` reporter. @@ -9682,7 +8215,7 @@ module.exports = R.on("spec", { }, }) -},{"../lib/reporter":22}],69:[function(require,module,exports){ +},{"../lib/reporter":21}],68:[function(require,module,exports){ "use strict" // This is a basic TAP-generating reporter. @@ -9795,18 +8328,12 @@ module.exports = R.on("tap", { }, }) -},{"../lib/reporter":22,"../lib/util":27,"clean-assert-util":33}],"thallium":[function(require,module,exports){ +},{"../lib/reporter":21,"../lib/util":26,"clean-assert-util":32}],"thallium":[function(require,module,exports){ "use strict" module.exports = require("../lib/browser-bundle") +require("./index") +module.exports.support = require("./support") -require("../migrate/index") - -// Note: both of these are deprecated -module.exports.assertions = require("../assertions") -module.exports.create = require("../migrate/common").deprecate( - "`tl.create` is deprecated. Please use `tl.root` instead.", - module.exports.root) - -},{"../assertions":2,"../lib/browser-bundle":9,"../migrate/common":28,"../migrate/index":29}]},{},[]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJhc3NlcnQuanMiLCJhc3NlcnRpb25zLmpzIiwiZG9tLmpzIiwiaW5kZXguanMiLCJpbnRlcm5hbC5qcyIsImxpYi9hcGkvY29tbW9uLmpzIiwibGliL2FwaS9yZWZsZWN0LmpzIiwibGliL2FwaS90aGFsbGl1bS5qcyIsImxpYi9icm93c2VyLWJ1bmRsZS5qcyIsImxpYi9jb3JlL2ZpbHRlci5qcyIsImxpYi9jb3JlL3JlcG9ydHMuanMiLCJsaWIvY29yZS90ZXN0cy5qcyIsImxpYi9kb20vaW5kZXguanMiLCJsaWIvZG9tL2luaXRpYWxpemUuanMiLCJsaWIvZG9tL2luamVjdC1zdHlsZXMuanMiLCJsaWIvZG9tL2luamVjdC5qcyIsImxpYi9kb20vcnVuLXRlc3RzLmpzIiwibGliL2RvbS92aWV3LmpzIiwibGliL21ldGhvZHMuanMiLCJsaWIvcmVwbGFjZWQvY29uc29sZS1icm93c2VyLmpzIiwibGliL3JlcG9ydGVyL2NvbnNvbGUtcmVwb3J0ZXIuanMiLCJsaWIvcmVwb3J0ZXIvaW5kZXguanMiLCJsaWIvcmVwb3J0ZXIvb24uanMiLCJsaWIvcmVwb3J0ZXIvcmVwb3J0ZXIuanMiLCJsaWIvcmVwb3J0ZXIvdXRpbC5qcyIsImxpYi9zZXR0aW5ncy5qcyIsImxpYi91dGlsLmpzIiwibWlncmF0ZS9jb21tb24uanMiLCJtaWdyYXRlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2FycmF5LW1hcC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9hcnJheS1yZWR1Y2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvY2xlYW4tYXNzZXJ0LXV0aWwvYnJvd3Nlci1pbnNwZWN0LmpzIiwibm9kZV9tb2R1bGVzL2NsZWFuLWFzc2VydC11dGlsL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2NsZWFuLWFzc2VydC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1hc3NlcnQvbGliL2VxdWFsLmpzIiwibm9kZV9tb2R1bGVzL2NsZWFuLWFzc2VydC9saWIvaGFzLWtleXMuanMiLCJub2RlX21vZHVsZXMvY2xlYW4tYXNzZXJ0L2xpYi9oYXMuanMiLCJub2RlX21vZHVsZXMvY2xlYW4tYXNzZXJ0L2xpYi9pbmNsdWRlcy5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1hc3NlcnQvbGliL3Rocm93cy5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1hc3NlcnQvbGliL3R5cGUuanMiLCJub2RlX21vZHVsZXMvY2xlYW4tbWF0Y2gvY2xlYW4tbWF0Y2guanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvY29udmVydC9kbXAuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvY29udmVydC94bWwuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvZGlmZi9hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9kaWZmL2Jhc2UuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvZGlmZi9jaGFyYWN0ZXIuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvZGlmZi9jc3MuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvZGlmZi9qc29uLmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL2RpZmYvbGluZS5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9kaWZmL3NlbnRlbmNlLmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL2RpZmYvd29yZC5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9wYXRjaC9hcHBseS5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9wYXRjaC9jcmVhdGUuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvcGF0Y2gvcGFyc2UuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvdXRpbC9kaXN0YW5jZS1pdGVyYXRvci5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy91dGlsL3BhcmFtcy5qcyIsIm5vZGVfbW9kdWxlcy9mb3JlYWNoL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2luZGV4b2YvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9qc29uMy9saWIvanNvbjMuanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvZm9yZWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9pc0FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy91dGlsLWluc3BlY3QvaW5kZXguanMiLCJyL2RvdC5qcyIsInIvaW5kZXguanMiLCJyL3NwZWMuanMiLCJyL3RhcC5qcyIsIm1pZ3JhdGUvYnVuZGxlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDLzJCQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1V0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMvUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMva0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3ZYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3JRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2xEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDamhCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNqNEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaGFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIlwidXNlIHN0cmljdFwiXG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNsZWFuLWFzc2VydFwiKVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLyoqXG4gKiBDb3JlIFRERC1zdHlsZSBhc3NlcnRpb25zLiBUaGVzZSBhcmUgZG9uZSBieSBhIGNvbXBvc2l0aW9uIG9mIERTTHMsIHNpbmNlXG4gKiB0aGVyZSBpcyAqc28qIG11Y2ggcmVwZXRpdGlvbi5cbiAqL1xuXG52YXIgbWF0Y2ggPSByZXF1aXJlKFwiY2xlYW4tbWF0Y2hcIilcbnZhciBkZXByZWNhdGUgPSByZXF1aXJlKFwiLi9taWdyYXRlL2NvbW1vblwiKS5kZXByZWNhdGVcblxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ1xudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuLyogZXNsaW50LWRpc2FibGUgbm8tc2VsZi1jb21wYXJlICovXG4vLyBGb3IgYmV0dGVyIE5hTiBoYW5kbGluZ1xuZnVuY3Rpb24gc3RyaWN0SXMoYSwgYikge1xuICAgIHJldHVybiBhID09PSBiIHx8IGEgIT09IGEgJiYgYiAhPT0gYlxufVxuXG5mdW5jdGlvbiBsb29zZUlzKGEsIGIpIHtcbiAgICByZXR1cm4gYSA9PSBiIHx8IGEgIT09IGEgJiYgYiAhPT0gYiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxufVxuXG4vKiBlc2xpbnQtZW5hYmxlIG5vLXNlbGYtY29tcGFyZSAqL1xuXG52YXIgY2hlY2sgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIHByZWZpeCh0eXBlKSB7XG4gICAgICAgIHJldHVybiAoL15bYWVpb3VdLy50ZXN0KHR5cGUpID8gXCJhbiBcIiA6IFwiYSBcIikgKyB0eXBlXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2sodmFsdWUsIHR5cGUpIHtcbiAgICAgICAgaWYgKHR5cGUgPT09IFwiYXJyYXlcIikgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpXG4gICAgICAgIGlmICh0eXBlID09PSBcInJlZ2V4cFwiKSByZXR1cm4gdG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT09IFwiW29iamVjdCBSZWdFeHBdXCJcbiAgICAgICAgaWYgKHR5cGUgPT09IFwib2JqZWN0XCIpIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIlxuICAgICAgICBpZiAodHlwZSA9PT0gXCJudWxsXCIpIHJldHVybiB2YWx1ZSA9PT0gbnVsbFxuICAgICAgICBpZiAodHlwZSA9PT0gXCJub25lXCIpIHJldHVybiB2YWx1ZSA9PSBudWxsXG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IHR5cGVcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja0xpc3QodmFsdWUsIHR5cGVzKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdHlwZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChjaGVjayh2YWx1ZSwgdHlwZXNbaV0pKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2tTaW5nbGUodmFsdWUsIG5hbWUsIHR5cGUpIHtcbiAgICAgICAgaWYgKCFjaGVjayh2YWx1ZSwgdHlwZSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgXCIgKyBuYW1lICsgXCJgIG11c3QgYmUgXCIgKyBwcmVmaXgodHlwZSkpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja01hbnkodmFsdWUsIG5hbWUsIHR5cGVzKSB7XG4gICAgICAgIGlmICghY2hlY2tMaXN0KHZhbHVlLCB0eXBlcykpIHtcbiAgICAgICAgICAgIHZhciBzdHIgPSBcImBcIiArIG5hbWUgKyBcImAgbXVzdCBiZSBlaXRoZXJcIlxuXG4gICAgICAgICAgICBpZiAodHlwZXMubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICAgICAgc3RyICs9IHByZWZpeCh0eXBlc1swXSkgKyBcIiBvciBcIiArIHByZWZpeCh0eXBlc1sxXSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RyICs9IHByZWZpeCh0eXBlc1swXSlcblxuICAgICAgICAgICAgICAgIHZhciBlbmQgPSB0eXBlcy5sZW5ndGggLSAxXG5cbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0ciArPSBcIiwgXCIgKyBwcmVmaXgodHlwZXNbaV0pXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgc3RyICs9IFwiLCBvciBcIiArIHByZWZpeCh0eXBlc1tlbmRdKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHN0cilcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUsIG5hbWUsIHR5cGUpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHR5cGUpKSByZXR1cm4gY2hlY2tTaW5nbGUodmFsdWUsIG5hbWUsIHR5cGUpXG4gICAgICAgIGlmICh0eXBlLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGNoZWNrU2luZ2xlKHZhbHVlLCBuYW1lLCB0eXBlWzBdKVxuICAgICAgICByZXR1cm4gY2hlY2tNYW55KHZhbHVlLCBuYW1lLCB0eXBlKVxuICAgIH1cbn0pKClcblxuZnVuY3Rpb24gY2hlY2tUeXBlT2YodmFsdWUsIG5hbWUpIHtcbiAgICBpZiAodmFsdWUgPT09IFwiYm9vbGVhblwiIHx8IHZhbHVlID09PSBcImZ1bmN0aW9uXCIpIHJldHVyblxuICAgIGlmICh2YWx1ZSA9PT0gXCJudW1iZXJcIiB8fCB2YWx1ZSA9PT0gXCJvYmplY3RcIiB8fCB2YWx1ZSA9PT0gXCJzdHJpbmdcIikgcmV0dXJuXG4gICAgaWYgKHZhbHVlID09PSBcInN5bWJvbFwiIHx8IHZhbHVlID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm5cbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYFwiICsgbmFtZSArIFwiYCBtdXN0IGJlIGEgdmFsaWQgYHR5cGVvZmAgdmFsdWVcIilcbn1cblxuLy8gVGhpcyBob2xkcyBldmVyeXRoaW5nIHRvIGJlIGFkZGVkLlxudmFyIG1ldGhvZHMgPSBbXVxudmFyIGFsaWFzZXMgPSBbXVxuXG5mdW5jdGlvbiBnZXRBc3NlcnRpb25EZXByZWNhdGlvbihuYW1lKSB7XG4gICAgdmFyIHJlcGxhY2VtZW50ID0gbmFtZVxuXG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgY2FzZSBcImJvb2xlYW5cIjogcmVwbGFjZW1lbnQgPSBcImlzQm9vbGVhblwiOyBicmVha1xuICAgIGNhc2UgXCJmdW5jdGlvblwiOiByZXBsYWNlbWVudCA9IFwiaXNGdW5jdGlvblwiOyBicmVha1xuICAgIGNhc2UgXCJudW1iZXJcIjogcmVwbGFjZW1lbnQgPSBcImlzTnVtYmVyXCI7IGJyZWFrXG4gICAgY2FzZSBcIm9iamVjdFwiOiByZXBsYWNlbWVudCA9IFwiaXNPYmplY3RcIjsgYnJlYWtcbiAgICBjYXNlIFwic3RyaW5nXCI6IHJlcGxhY2VtZW50ID0gXCJpc1N0cmluZ1wiOyBicmVha1xuICAgIGNhc2UgXCJzeW1ib2xcIjogcmVwbGFjZW1lbnQgPSBcImlzU3ltYm9sXCI7IGJyZWFrXG4gICAgY2FzZSBcImluc3RhbmNlb2ZcIjogcmVwbGFjZW1lbnQgPSBcImlzXCI7IGJyZWFrXG4gICAgY2FzZSBcIm5vdEluc3RhbmNlb2ZcIjogcmVwbGFjZW1lbnQgPSBcIm5vdFwiOyBicmVha1xuICAgIGNhc2UgXCJoYXNMZW5ndGhcIjogcmVwbGFjZW1lbnQgPSBcImVxdWFsXCI7IGJyZWFrXG4gICAgY2FzZSBcIm5vdExlbmd0aFwiOiByZXBsYWNlbWVudCA9IFwibm90RXF1YWxcIjsgYnJlYWtcbiAgICBjYXNlIFwibGVuZ3RoQXRMZWFzdFwiOiByZXBsYWNlbWVudCA9IFwiYXRMZWFzdFwiOyBicmVha1xuICAgIGNhc2UgXCJsZW5ndGhBdE1vc3RcIjogcmVwbGFjZW1lbnQgPSBcImF0TW9zdFwiOyBicmVha1xuICAgIGNhc2UgXCJsZW5ndGhBYm92ZVwiOiByZXBsYWNlbWVudCA9IFwiYWJvdmVcIjsgYnJlYWtcbiAgICBjYXNlIFwibGVuZ3RoQmVsb3dcIjogcmVwbGFjZW1lbnQgPSBcImJlbG93XCI7IGJyZWFrXG4gICAgY2FzZSBcIm5vdEluY2x1ZGVzQWxsXCI6IHJlcGxhY2VtZW50ID0gXCJub3RJbmNsdWRlc0FsbFwiOyBicmVha1xuICAgIGNhc2UgXCJub3RJbmNsdWRlc0xvb3NlQWxsXCI6IHJlcGxhY2VtZW50ID0gXCJub3RJbmNsdWRlc0FsbFwiOyBicmVha1xuICAgIGNhc2UgXCJub3RJbmNsdWRlc0RlZXBBbGxcIjogcmVwbGFjZW1lbnQgPSBcIm5vdEluY2x1ZGVzQWxsRGVlcFwiOyBicmVha1xuICAgIGNhc2UgXCJub3RJbmNsdWRlc01hdGNoQWxsXCI6IHJlcGxhY2VtZW50ID0gXCJub3RJbmNsdWRlc0FsbE1hdGNoXCI7IGJyZWFrXG4gICAgY2FzZSBcImluY2x1ZGVzQW55XCI6IHJlcGxhY2VtZW50ID0gXCJpbmNsdWRlc0FueVwiOyBicmVha1xuICAgIGNhc2UgXCJpbmNsdWRlc0xvb3NlQW55XCI6IHJlcGxhY2VtZW50ID0gXCJpbmNsdWRlc0FueVwiOyBicmVha1xuICAgIGNhc2UgXCJpbmNsdWRlc0RlZXBBbnlcIjogcmVwbGFjZW1lbnQgPSBcImluY2x1ZGVzQW55RGVlcFwiOyBicmVha1xuICAgIGNhc2UgXCJpbmNsdWRlc01hdGNoQW55XCI6IHJlcGxhY2VtZW50ID0gXCJpbmNsdWRlc0FueU1hdGNoXCI7IGJyZWFrXG4gICAgY2FzZSBcInVuZGVmaW5lZFwiOlxuICAgICAgICByZXR1cm4gXCJgdC51bmRlZmluZWQoKWAgaXMgZGVwcmVjYXRlZC4gVXNlIFwiICtcbiAgICAgICAgICAgIFwiYGFzc2VydC5lcXVhbCh1bmRlZmluZWQsIHZhbHVlKWAuIGZyb20gYHRoYWxsaXVtL2Fzc2VydGAgaW5zdGVhZC5cIlxuICAgIGNhc2UgXCJ0eXBlXCI6XG4gICAgICAgIHJldHVybiBcImB0LnR5cGUoKWAgaXMgZGVwcmVjYXRlZC4gVXNlIGBhc3NlcnQuaXNCb29sZWFuKClgL2V0Yy4gZnJvbSBcIiArXG4gICAgICAgICAgICBcImB0aGFsbGl1bS9hc3NlcnRgIGluc3RlYWQuXCJcbiAgICBkZWZhdWx0OiAvLyBpZ25vcmVcbiAgICB9XG5cbiAgICByZXR1cm4gXCJgdC5cIiArIG5hbWUgKyBcIigpYCBpcyBkZXByZWNhdGVkLiBVc2UgYGFzc2VydC5cIiArIHJlcGxhY2VtZW50ICtcbiAgICAgICAgXCIoKWAgZnJvbSBgdGhhbGxpdW0vYXNzZXJ0YCBpbnN0ZWFkLlwiXG59XG5cbi8qKlxuICogVGhlIGNvcmUgYXNzZXJ0aW9ucyBleHBvcnQsIGFzIGEgcGx1Z2luLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0KSB7XG4gICAgbWV0aG9kcy5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgIHQuZGVmaW5lKG0ubmFtZSwgZGVwcmVjYXRlKGdldEFzc2VydGlvbkRlcHJlY2F0aW9uKG0ubmFtZSksIG0uY2FsbGJhY2spKVxuICAgIH0pXG4gICAgYWxpYXNlcy5mb3JFYWNoKGZ1bmN0aW9uIChhbGlhcykgeyB0W2FsaWFzLm5hbWVdID0gdFthbGlhcy5vcmlnaW5hbF0gfSlcbn1cblxuLy8gTGl0dGxlIGhlbHBlcnMgc28gdGhhdCB0aGVzZSBmdW5jdGlvbnMgb25seSBuZWVkIHRvIGJlIGNyZWF0ZWQgb25jZS5cbmZ1bmN0aW9uIGRlZmluZShuYW1lLCBjYWxsYmFjaykge1xuICAgIGNoZWNrKG5hbWUsIFwibmFtZVwiLCBcInN0cmluZ1wiKVxuICAgIGNoZWNrKGNhbGxiYWNrLCBcImNhbGxiYWNrXCIsIFwiZnVuY3Rpb25cIilcbiAgICBtZXRob2RzLnB1c2goe25hbWU6IG5hbWUsIGNhbGxiYWNrOiBjYWxsYmFja30pXG59XG5cbi8vIE11Y2ggZWFzaWVyIHRvIHR5cGVcbmZ1bmN0aW9uIG5lZ2F0ZShuYW1lKSB7XG4gICAgY2hlY2sobmFtZSwgXCJuYW1lXCIsIFwic3RyaW5nXCIpXG4gICAgcmV0dXJuIFwibm90XCIgKyBuYW1lWzBdLnRvVXBwZXJDYXNlKCkgKyBuYW1lLnNsaWNlKDEpXG59XG5cbi8vIFRoZSBiYXNpYyBhc3NlcnQuIEl0J3MgYWxtb3N0IHRoZXJlIGZvciBsb29rcywgZ2l2ZW4gaG93IGVhc3kgaXQgaXMgdG9cbi8vIGRlZmluZSB5b3VyIG93biBhc3NlcnRpb25zLlxuZnVuY3Rpb24gc2FuaXRpemUobWVzc2FnZSkge1xuICAgIHJldHVybiBtZXNzYWdlID8gU3RyaW5nKG1lc3NhZ2UpLnJlcGxhY2UoLyhcXHtcXHcrXFx9KS9nLCBcIlxcXFwkMVwiKSA6IFwiXCJcbn1cblxuZGVmaW5lKFwiYXNzZXJ0XCIsIGZ1bmN0aW9uICh0ZXN0LCBtZXNzYWdlKSB7XG4gICAgcmV0dXJuIHt0ZXN0OiB0ZXN0LCBtZXNzYWdlOiBzYW5pdGl6ZShtZXNzYWdlKX1cbn0pXG5cbmRlZmluZShcImZhaWxcIiwgZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICByZXR1cm4ge3Rlc3Q6IGZhbHNlLCBtZXNzYWdlOiBzYW5pdGl6ZShtZXNzYWdlKX1cbn0pXG5cbi8qKlxuICogVGhlc2UgbWFrZXMgbWFueSBvZiB0aGUgY29tbW9uIG9wZXJhdG9ycyBtdWNoIGVhc2llciB0byBkby5cbiAqL1xuZnVuY3Rpb24gdW5hcnkobmFtZSwgZnVuYywgbWVzc2FnZXMpIHtcbiAgICBkZWZpbmUobmFtZSwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0ZXN0OiBmdW5jKHZhbHVlKSxcbiAgICAgICAgICAgIGFjdHVhbDogdmFsdWUsXG4gICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlc1swXSxcbiAgICAgICAgfVxuICAgIH0pXG5cbiAgICBkZWZpbmUobmVnYXRlKG5hbWUpLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRlc3Q6ICFmdW5jKHZhbHVlKSxcbiAgICAgICAgICAgIGFjdHVhbDogdmFsdWUsXG4gICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlc1sxXSxcbiAgICAgICAgfVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIGJpbmFyeShuYW1lLCBmdW5jLCBtZXNzYWdlcykge1xuICAgIGRlZmluZShuYW1lLCBmdW5jdGlvbiAoYWN0dWFsLCBleHBlY3RlZCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGVzdDogZnVuYyhhY3R1YWwsIGV4cGVjdGVkKSxcbiAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuICAgICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZXNbMF0sXG4gICAgICAgIH1cbiAgICB9KVxuXG4gICAgZGVmaW5lKG5lZ2F0ZShuYW1lKSwgZnVuY3Rpb24gKGFjdHVhbCwgZXhwZWN0ZWQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRlc3Q6ICFmdW5jKGFjdHVhbCwgZXhwZWN0ZWQpLFxuICAgICAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgICAgICAgICBleHBlY3RlZDogZXhwZWN0ZWQsXG4gICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlc1sxXSxcbiAgICAgICAgfVxuICAgIH0pXG59XG5cbnVuYXJ5KFwib2tcIiwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuICEheCB9LCBbXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBva1wiLFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGJlIG9rXCIsXG5dKVxuXG5cImJvb2xlYW4gZnVuY3Rpb24gbnVtYmVyIG9iamVjdCBzdHJpbmcgc3ltYm9sXCIuc3BsaXQoXCIgXCIpXG4uZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICAgIHZhciBuYW1lID0gKHR5cGVbMF0gPT09IFwib1wiID8gXCJhbiBcIiA6IFwiYSBcIikgKyB0eXBlXG5cbiAgICB1bmFyeSh0eXBlLCBmdW5jdGlvbiAoeCkgeyByZXR1cm4gdHlwZW9mIHggPT09IHR5cGUgfSwgW1xuICAgICAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIFwiICsgbmFtZSxcbiAgICAgICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgYmUgXCIgKyBuYW1lLFxuICAgIF0pXG59KVxuXG47W3RydWUsIGZhbHNlLCBudWxsLCB1bmRlZmluZWRdLmZvckVhY2goZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdW5hcnkodmFsdWUgKyBcIlwiLCBmdW5jdGlvbiAoeCkgeyByZXR1cm4geCA9PT0gdmFsdWUgfSwgW1xuICAgICAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIFwiICsgdmFsdWUsXG4gICAgICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGJlIFwiICsgdmFsdWUsXG4gICAgXSlcbn0pXG5cbnVuYXJ5KFwiZXhpc3RzXCIsIGZ1bmN0aW9uICh4KSB7IHJldHVybiB4ICE9IG51bGwgfSwgW1xuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gZXhpc3RcIixcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBleGlzdFwiLFxuXSlcblxudW5hcnkoXCJhcnJheVwiLCBBcnJheS5pc0FycmF5LCBbXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhbiBhcnJheVwiLFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGJlIGFuIGFycmF5XCIsXG5dKVxuXG5kZWZpbmUoXCJ0eXBlXCIsIGZ1bmN0aW9uIChvYmplY3QsIHR5cGUpIHtcbiAgICBjaGVja1R5cGVPZih0eXBlLCBcInR5cGVcIilcblxuICAgIHJldHVybiB7XG4gICAgICAgIHRlc3Q6IHR5cGVvZiBvYmplY3QgPT09IHR5cGUsXG4gICAgICAgIGV4cGVjdGVkOiB0eXBlLFxuICAgICAgICBhY3R1YWw6IHR5cGVvZiBvYmplY3QsXG4gICAgICAgIG86IG9iamVjdCxcbiAgICAgICAgbWVzc2FnZTogXCJFeHBlY3RlZCB0eXBlb2Yge299IHRvIGJlIHtleHBlY3RlZH0sIGJ1dCBmb3VuZCB7YWN0dWFsfVwiLFxuICAgIH1cbn0pXG5cbmRlZmluZShcIm5vdFR5cGVcIiwgZnVuY3Rpb24gKG9iamVjdCwgdHlwZSkge1xuICAgIGNoZWNrVHlwZU9mKHR5cGUsIFwidHlwZVwiKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgdGVzdDogdHlwZW9mIG9iamVjdCAhPT0gdHlwZSxcbiAgICAgICAgZXhwZWN0ZWQ6IHR5cGUsXG4gICAgICAgIG86IG9iamVjdCxcbiAgICAgICAgbWVzc2FnZTogXCJFeHBlY3RlZCB0eXBlb2Yge299IHRvIG5vdCBiZSB7ZXhwZWN0ZWR9XCIsXG4gICAgfVxufSlcblxuZGVmaW5lKFwiaW5zdGFuY2VvZlwiLCBmdW5jdGlvbiAob2JqZWN0LCBUeXBlKSB7XG4gICAgY2hlY2soVHlwZSwgXCJUeXBlXCIsIFwiZnVuY3Rpb25cIilcblxuICAgIHJldHVybiB7XG4gICAgICAgIHRlc3Q6IG9iamVjdCBpbnN0YW5jZW9mIFR5cGUsXG4gICAgICAgIGV4cGVjdGVkOiBUeXBlLFxuICAgICAgICBhY3R1YWw6IG9iamVjdC5jb25zdHJ1Y3RvcixcbiAgICAgICAgbzogb2JqZWN0LFxuICAgICAgICBtZXNzYWdlOiBcIkV4cGVjdGVkIHtvfSB0byBiZSBhbiBpbnN0YW5jZSBvZiB7ZXhwZWN0ZWR9LCBidXQgZm91bmQge2FjdHVhbH1cIiwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgfVxufSlcblxuZGVmaW5lKFwibm90SW5zdGFuY2VvZlwiLCBmdW5jdGlvbiAob2JqZWN0LCBUeXBlKSB7XG4gICAgY2hlY2soVHlwZSwgXCJUeXBlXCIsIFwiZnVuY3Rpb25cIilcblxuICAgIHJldHVybiB7XG4gICAgICAgIHRlc3Q6ICEob2JqZWN0IGluc3RhbmNlb2YgVHlwZSksXG4gICAgICAgIGV4cGVjdGVkOiBUeXBlLFxuICAgICAgICBvOiBvYmplY3QsXG4gICAgICAgIG1lc3NhZ2U6IFwiRXhwZWN0ZWQge299IHRvIG5vdCBiZSBhbiBpbnN0YW5jZSBvZiB7ZXhwZWN0ZWR9XCIsXG4gICAgfVxufSlcblxuYmluYXJ5KFwiZXF1YWxcIiwgc3RyaWN0SXMsIFtcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGVxdWFsIHtleHBlY3RlZH1cIixcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBlcXVhbCB7ZXhwZWN0ZWR9XCIsXG5dKVxuXG5iaW5hcnkoXCJlcXVhbExvb3NlXCIsIGxvb3NlSXMsIFtcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGxvb3NlbHkgZXF1YWwge2V4cGVjdGVkfVwiLFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGxvb3NlbHkgZXF1YWwge2V4cGVjdGVkfVwiLFxuXSlcblxuZnVuY3Rpb24gY29tcChuYW1lLCBjb21wYXJlLCBtZXNzYWdlKSB7XG4gICAgZGVmaW5lKG5hbWUsIGZ1bmN0aW9uIChhY3R1YWwsIGV4cGVjdGVkKSB7XG4gICAgICAgIGNoZWNrKGFjdHVhbCwgXCJhY3R1YWxcIiwgXCJudW1iZXJcIilcbiAgICAgICAgY2hlY2soZXhwZWN0ZWQsIFwiZXhwZWN0ZWRcIiwgXCJudW1iZXJcIilcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGVzdDogY29tcGFyZShhY3R1YWwsIGV4cGVjdGVkKSxcbiAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuICAgICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgfVxuICAgIH0pXG59XG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxuY29tcChcImF0TGVhc3RcIiwgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEgPj0gYiB9LCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGF0IGxlYXN0IHtleHBlY3RlZH1cIilcbmNvbXAoXCJhdE1vc3RcIiwgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEgPD0gYiB9LCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGF0IG1vc3Qge2V4cGVjdGVkfVwiKVxuY29tcChcImFib3ZlXCIsIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhID4gYiB9LCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGFib3ZlIHtleHBlY3RlZH1cIilcbmNvbXAoXCJiZWxvd1wiLCBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYSA8IGIgfSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBiZWxvdyB7ZXhwZWN0ZWR9XCIpXG5cbmRlZmluZShcImJldHdlZW5cIiwgZnVuY3Rpb24gKGFjdHVhbCwgbG93ZXIsIHVwcGVyKSB7XG4gICAgY2hlY2soYWN0dWFsLCBcImFjdHVhbFwiLCBcIm51bWJlclwiKVxuICAgIGNoZWNrKGxvd2VyLCBcImxvd2VyXCIsIFwibnVtYmVyXCIpXG4gICAgY2hlY2sodXBwZXIsIFwidXBwZXJcIiwgXCJudW1iZXJcIilcblxuICAgIHJldHVybiB7XG4gICAgICAgIHRlc3Q6IGFjdHVhbCA+PSBsb3dlciAmJiBhY3R1YWwgPD0gdXBwZXIsXG4gICAgICAgIGFjdHVhbDogYWN0dWFsLFxuICAgICAgICBsb3dlcjogbG93ZXIsXG4gICAgICAgIHVwcGVyOiB1cHBlcixcbiAgICAgICAgbWVzc2FnZTogXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBiZXR3ZWVuIHtsb3dlcn0gYW5kIHt1cHBlcn1cIixcbiAgICB9XG59KVxuXG4vKiBlc2xpbnQtZW5hYmxlIG1heC1sZW4gKi9cblxuYmluYXJ5KFwiZGVlcEVxdWFsXCIsIG1hdGNoLnN0cmljdCwgW1xuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gZGVlcGx5IGVxdWFsIHtleHBlY3RlZH1cIixcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBkZWVwbHkgZXF1YWwge2V4cGVjdGVkfVwiLFxuXSlcblxuYmluYXJ5KFwibWF0Y2hcIiwgbWF0Y2gubG9vc2UsIFtcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIHtleHBlY3RlZH1cIixcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCB7ZXhwZWN0ZWR9XCIsXG5dKVxuXG5mdW5jdGlvbiBoYXMobmFtZSwgXykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW4sIG1heC1wYXJhbXNcbiAgICBpZiAoXy5lcXVhbHMgPT09IGxvb3NlSXMpIHtcbiAgICAgICAgZGVmaW5lKG5hbWUsIGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdGVzdDogXy5oYXMob2JqZWN0LCBrZXkpICYmIF8uaXMoXy5nZXQob2JqZWN0LCBrZXkpLCB2YWx1ZSksXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IHZhbHVlLFxuICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0W2tleV0sXG4gICAgICAgICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogXy5tZXNzYWdlc1swXSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICBkZWZpbmUobmVnYXRlKG5hbWUpLCBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHRlc3Q6ICFfLmhhcyhvYmplY3QsIGtleSkgfHwgIV8uaXMoXy5nZXQob2JqZWN0LCBrZXkpLCB2YWx1ZSksXG4gICAgICAgICAgICAgICAgYWN0dWFsOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBfLm1lc3NhZ2VzWzJdLFxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGRlZmluZShuYW1lLCBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICAgICAgICB2YXIgdGVzdCA9IF8uaGFzKG9iamVjdCwga2V5KVxuXG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdGVzdDogdGVzdCAmJiBfLmlzKF8uZ2V0KG9iamVjdCwga2V5KSwgdmFsdWUpLFxuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0W2tleV0sXG4gICAgICAgICAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogXy5tZXNzYWdlc1swXSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHRlc3Q6IHRlc3QsXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBrZXksXG4gICAgICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0LFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBfLm1lc3NhZ2VzWzFdLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICBkZWZpbmUobmVnYXRlKG5hbWUpLCBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICAgICAgICB2YXIgdGVzdCA9ICFfLmhhcyhvYmplY3QsIGtleSlcblxuICAgICAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHRlc3Q6IHRlc3QgfHwgIV8uaXMoXy5nZXQob2JqZWN0LCBrZXkpLCB2YWx1ZSksXG4gICAgICAgICAgICAgICAgICAgIGFjdHVhbDogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogXy5tZXNzYWdlc1syXSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHRlc3Q6IHRlc3QsXG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBrZXksXG4gICAgICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0LFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBfLm1lc3NhZ2VzWzNdLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGhhc093bktleShvYmplY3QsIGtleSkgeyByZXR1cm4gaGFzT3duLmNhbGwob2JqZWN0LCBrZXkpIH1cbmZ1bmN0aW9uIGhhc0luS2V5KG9iamVjdCwga2V5KSB7IHJldHVybiBrZXkgaW4gb2JqZWN0IH1cbmZ1bmN0aW9uIGhhc0luQ29sbChvYmplY3QsIGtleSkgeyByZXR1cm4gb2JqZWN0LmhhcyhrZXkpIH1cbmZ1bmN0aW9uIGhhc09iamVjdEdldChvYmplY3QsIGtleSkgeyByZXR1cm4gb2JqZWN0W2tleV0gfVxuZnVuY3Rpb24gaGFzQ29sbEdldChvYmplY3QsIGtleSkgeyByZXR1cm4gb2JqZWN0LmdldChrZXkpIH1cblxuaGFzKFwiaGFzT3duXCIsIHtcbiAgICBpczogc3RyaWN0SXMsXG4gICAgaGFzOiBoYXNPd25LZXksXG4gICAgZ2V0OiBoYXNPYmplY3RHZXQsXG4gICAgbWVzc2FnZXM6IFtcbiAgICAgICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBoYXZlIG93biBrZXkge2tleX0gZXF1YWwgdG8ge2V4cGVjdGVkfSwgYnV0IGZvdW5kIHthY3R1YWx9XCIsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgICAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUgb3duIGtleSB7ZXhwZWN0ZWR9XCIsXG4gICAgICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gbm90IGhhdmUgb3duIGtleSB7a2V5fSBlcXVhbCB0byB7YWN0dWFsfVwiLFxuICAgICAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIG93biBrZXkge2V4cGVjdGVkfVwiLFxuICAgIF0sXG59KVxuXG5oYXMoXCJoYXNPd25Mb29zZVwiLCB7XG4gICAgaXM6IGxvb3NlSXMsXG4gICAgaGFzOiBoYXNPd25LZXksXG4gICAgZ2V0OiBoYXNPYmplY3RHZXQsXG4gICAgbWVzc2FnZXM6IFtcbiAgICAgICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBoYXZlIG93biBrZXkge2tleX0gbG9vc2VseSBlcXVhbCB0byB7ZXhwZWN0ZWR9LCBidXQgZm91bmQge2FjdHVhbH1cIiwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBvd24ga2V5IHtleHBlY3RlZH1cIixcbiAgICAgICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBub3QgaGF2ZSBvd24ga2V5IHtrZXl9IGxvb3NlbHkgZXF1YWwgdG8ge2FjdHVhbH1cIixcbiAgICAgICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBvd24ga2V5IHtleHBlY3RlZH1cIixcbiAgICBdLFxufSlcblxuaGFzKFwiaGFzS2V5XCIsIHtcbiAgICBpczogc3RyaWN0SXMsXG4gICAgaGFzOiBoYXNJbktleSxcbiAgICBnZXQ6IGhhc09iamVjdEdldCxcbiAgICBtZXNzYWdlczogW1xuICAgICAgICBcIkV4cGVjdGVkIHtvYmplY3R9IHRvIGhhdmUga2V5IHtrZXl9IGVxdWFsIHRvIHtleHBlY3RlZH0sIGJ1dCBmb3VuZCB7YWN0dWFsfVwiLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW5cbiAgICAgICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGtleSB7ZXhwZWN0ZWR9XCIsXG4gICAgICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gbm90IGhhdmUga2V5IHtrZXl9IGVxdWFsIHRvIHthY3R1YWx9XCIsXG4gICAgICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUga2V5IHtleHBlY3RlZH1cIixcbiAgICBdLFxufSlcblxuaGFzKFwiaGFzS2V5TG9vc2VcIiwge1xuICAgIGlzOiBsb29zZUlzLFxuICAgIGhhczogaGFzSW5LZXksXG4gICAgZ2V0OiBoYXNPYmplY3RHZXQsXG4gICAgbWVzc2FnZXM6IFtcbiAgICAgICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBoYXZlIGtleSB7a2V5fSBsb29zZWx5IGVxdWFsIHRvIHtleHBlY3RlZH0sIGJ1dCBmb3VuZCB7YWN0dWFsfVwiLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW5cbiAgICAgICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGtleSB7ZXhwZWN0ZWR9XCIsXG4gICAgICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gbm90IGhhdmUga2V5IHtrZXl9IGxvb3NlbHkgZXF1YWwgdG8ge2FjdHVhbH1cIixcbiAgICAgICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBrZXkge2V4cGVjdGVkfVwiLFxuICAgIF0sXG59KVxuXG5oYXMoXCJoYXNcIiwge1xuICAgIGlzOiBzdHJpY3RJcyxcbiAgICBoYXM6IGhhc0luQ29sbCxcbiAgICBnZXQ6IGhhc0NvbGxHZXQsXG4gICAgbWVzc2FnZXM6IFtcbiAgICAgICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBoYXZlIGtleSB7a2V5fSBlcXVhbCB0byB7ZXhwZWN0ZWR9LCBidXQgZm91bmQge2FjdHVhbH1cIiwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBrZXkge2V4cGVjdGVkfVwiLFxuICAgICAgICBcIkV4cGVjdGVkIHtvYmplY3R9IHRvIG5vdCBoYXZlIGtleSB7a2V5fSBlcXVhbCB0byB7YWN0dWFsfVwiLFxuICAgICAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGtleSB7ZXhwZWN0ZWR9XCIsXG4gICAgXSxcbn0pXG5cbmhhcyhcImhhc0xvb3NlXCIsIHtcbiAgICBpczogbG9vc2VJcyxcbiAgICBoYXM6IGhhc0luQ29sbCxcbiAgICBnZXQ6IGhhc0NvbGxHZXQsXG4gICAgbWVzc2FnZXM6IFtcbiAgICAgICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBoYXZlIGtleSB7a2V5fSBlcXVhbCB0byB7ZXhwZWN0ZWR9LCBidXQgZm91bmQge2FjdHVhbH1cIiwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBrZXkge2V4cGVjdGVkfVwiLFxuICAgICAgICBcIkV4cGVjdGVkIHtvYmplY3R9IHRvIG5vdCBoYXZlIGtleSB7a2V5fSBlcXVhbCB0byB7YWN0dWFsfVwiLFxuICAgICAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGtleSB7ZXhwZWN0ZWR9XCIsXG4gICAgXSxcbn0pXG5cbmZ1bmN0aW9uIGdldE5hbWUoZnVuYykge1xuICAgIGlmIChmdW5jLm5hbWUgIT0gbnVsbCkgcmV0dXJuIGZ1bmMubmFtZSB8fCBcIjxhbm9ueW1vdXM+XCJcbiAgICBpZiAoZnVuYy5kaXNwbGF5TmFtZSAhPSBudWxsKSByZXR1cm4gZnVuYy5kaXNwbGF5TmFtZSB8fCBcIjxhbm9ueW1vdXM+XCJcbiAgICByZXR1cm4gXCI8YW5vbnltb3VzPlwiXG59XG5cbmZ1bmN0aW9uIHRocm93cyhuYW1lLCBfKSB7XG4gICAgZnVuY3Rpb24gcnVuKGludmVydCkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGZ1bmMsIG1hdGNoZXIpIHtcbiAgICAgICAgICAgIGNoZWNrKGZ1bmMsIFwiZnVuY1wiLCBcImZ1bmN0aW9uXCIpXG4gICAgICAgICAgICBfLmNoZWNrKG1hdGNoZXIpXG5cbiAgICAgICAgICAgIHZhciB0ZXN0LCBlcnJvclxuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGZ1bmMoKVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHRlc3QgPSBfLnRlc3QobWF0Y2hlciwgZXJyb3IgPSBlKVxuXG4gICAgICAgICAgICAgICAgLy8gUmV0aHJvdyB1bmtub3duIGVycm9ycyB0aGF0IGRvbid0IG1hdGNoIHdoZW4gYSBtYXRjaGVyIHdhc1xuICAgICAgICAgICAgICAgIC8vIHBhc3NlZCAtIGl0J3MgZWFzaWVyIHRvIGRlYnVnIHVuZXhwZWN0ZWQgZXJyb3JzIHdoZW4geW91IGhhdmVcbiAgICAgICAgICAgICAgICAvLyBhIHN0YWNrIHRyYWNlLiBEb24ndCByZXRocm93IG5vbi1lcnJvcnMsIHRob3VnaC5cbiAgICAgICAgICAgICAgICBpZiAoXy5yZXRocm93KG1hdGNoZXIsIGludmVydCwgdGVzdCwgZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0ZXN0OiAhIXRlc3QgXiBpbnZlcnQsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IG1hdGNoZXIsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IF8ubWVzc2FnZShtYXRjaGVyLCBpbnZlcnQsIHRlc3QpLFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGVmaW5lKG5hbWUsIHJ1bihmYWxzZSkpXG4gICAgZGVmaW5lKG5lZ2F0ZShuYW1lKSwgcnVuKHRydWUpKVxufVxuXG50aHJvd3MoXCJ0aHJvd3NcIiwge1xuICAgIHRlc3Q6IGZ1bmN0aW9uIChUeXBlLCBlKSB7IHJldHVybiBUeXBlID09IG51bGwgfHwgZSBpbnN0YW5jZW9mIFR5cGUgfSxcbiAgICBjaGVjazogZnVuY3Rpb24gKFR5cGUpIHsgY2hlY2soVHlwZSwgXCJUeXBlXCIsIFtcIm5vbmVcIiwgXCJmdW5jdGlvblwiXSkgfSxcblxuICAgIHJldGhyb3c6IGZ1bmN0aW9uIChtYXRjaGVyLCBpbnZlcnQsIHRlc3QsIGUpIHtcbiAgICAgICAgcmV0dXJuIG1hdGNoZXIgIT0gbnVsbCAmJiAhaW52ZXJ0ICYmICF0ZXN0ICYmIGUgaW5zdGFuY2VvZiBFcnJvclxuICAgIH0sXG5cbiAgICBtZXNzYWdlOiBmdW5jdGlvbiAoVHlwZSwgaW52ZXJ0LCB0ZXN0KSB7XG4gICAgICAgIHZhciBzdHIgPSBcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIFwiXG5cbiAgICAgICAgaWYgKGludmVydCkgc3RyICs9IFwibm90IFwiXG4gICAgICAgIHN0ciArPSBcInRocm93XCJcblxuICAgICAgICBpZiAoVHlwZSAhPSBudWxsKSB7XG4gICAgICAgICAgICBzdHIgKz0gXCIgYW4gaW5zdGFuY2Ugb2YgXCIgKyBnZXROYW1lKFR5cGUpXG4gICAgICAgICAgICBpZiAoIWludmVydCAmJiB0ZXN0ID09PSBmYWxzZSkgc3RyICs9IFwiLCBidXQgZm91bmQge2Vycm9yfVwiXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc3RyXG4gICAgfSxcbn0pXG5cbnRocm93cyhcInRocm93c01hdGNoXCIsIHtcbiAgICB0ZXN0OiBmdW5jdGlvbiAobWF0Y2hlciwgZSkge1xuICAgICAgICBpZiAodHlwZW9mIG1hdGNoZXIgPT09IFwic3RyaW5nXCIpIHJldHVybiBlLm1lc3NhZ2UgPT09IG1hdGNoZXJcbiAgICAgICAgaWYgKHR5cGVvZiBtYXRjaGVyID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiAhIW1hdGNoZXIoZSlcbiAgICAgICAgcmV0dXJuIG1hdGNoZXIudGVzdChlLm1lc3NhZ2UpXG4gICAgfSxcblxuICAgIGNoZWNrOiBmdW5jdGlvbiAobWF0Y2hlcikge1xuICAgICAgICAvLyBOb3QgYWNjZXB0aW5nIG9iamVjdHMgeWV0LlxuICAgICAgICBjaGVjayhtYXRjaGVyLCBcIm1hdGNoZXJcIiwgW1wic3RyaW5nXCIsIFwicmVnZXhwXCIsIFwiZnVuY3Rpb25cIl0pXG4gICAgfSxcblxuICAgIHJldGhyb3c6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGZhbHNlIH0sXG5cbiAgICBtZXNzYWdlOiBmdW5jdGlvbiAoXywgaW52ZXJ0LCB0ZXN0KSB7XG4gICAgICAgIGlmIChpbnZlcnQpIHtcbiAgICAgICAgICAgIHJldHVybiBcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIG5vdCB0aHJvdyBhbiBlcnJvciB0aGF0IG1hdGNoZXMge2V4cGVjdGVkfVwiIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgICAgICB9IGVsc2UgaWYgKHRlc3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gdGhyb3cgYW4gZXJyb3IgdGhhdCBtYXRjaGVzIHtleHBlY3RlZH0sIGJ1dCBmb3VuZCBubyBlcnJvclwiIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gdGhyb3cgYW4gZXJyb3IgdGhhdCBtYXRjaGVzIHtleHBlY3RlZH0sIGJ1dCBmb3VuZCB7ZXJyb3J9XCIgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgICAgIH1cbiAgICB9LFxufSlcblxuZnVuY3Rpb24gbGVuKG5hbWUsIGNvbXBhcmUsIG1lc3NhZ2UpIHtcbiAgICBkZWZpbmUobmFtZSwgZnVuY3Rpb24gKG9iamVjdCwgbGVuZ3RoKSB7XG4gICAgICAgIGNoZWNrKG9iamVjdCwgXCJvYmplY3RcIiwgXCJvYmplY3RcIilcbiAgICAgICAgY2hlY2sobGVuZ3RoLCBcImxlbmd0aFwiLCBcIm51bWJlclwiKVxuXG4gICAgICAgIHZhciBsZW4gPSBvYmplY3QubGVuZ3RoXG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRlc3Q6IGxlbiAhPSBudWxsICYmIGNvbXBhcmUobGVuLCArbGVuZ3RoKSxcbiAgICAgICAgICAgIGV4cGVjdGVkOiBsZW5ndGgsXG4gICAgICAgICAgICBhY3R1YWw6IGxlbixcbiAgICAgICAgICAgIG9iamVjdDogb2JqZWN0LFxuICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgfVxuICAgIH0pXG59XG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxuLy8gTm90ZTogdGhlc2UgYWx3YXlzIGZhaWwgd2l0aCBOYU5zLlxubGVuKFwibGVuZ3RoXCIsIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhID09PSBiIH0sIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gaGF2ZSBsZW5ndGgge2V4cGVjdGVkfSwgYnV0IGZvdW5kIHthY3R1YWx9XCIpXG5sZW4oXCJub3RMZW5ndGhcIiwgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEgIT09IGIgfSwgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBub3QgaGF2ZSBsZW5ndGgge2FjdHVhbH1cIilcbmxlbihcImxlbmd0aEF0TGVhc3RcIiwgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEgPj0gYiB9LCBcIkV4cGVjdGVkIHtvYmplY3R9IHRvIGhhdmUgbGVuZ3RoIGF0IGxlYXN0IHtleHBlY3RlZH0sIGJ1dCBmb3VuZCB7YWN0dWFsfVwiKVxubGVuKFwibGVuZ3RoQXRNb3N0XCIsIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhIDw9IGIgfSwgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBoYXZlIGxlbmd0aCBhdCBtb3N0IHtleHBlY3RlZH0sIGJ1dCBmb3VuZCB7YWN0dWFsfVwiKVxubGVuKFwibGVuZ3RoQWJvdmVcIiwgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEgPiBiIH0sIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gaGF2ZSBsZW5ndGggYWJvdmUge2V4cGVjdGVkfSwgYnV0IGZvdW5kIHthY3R1YWx9XCIpXG5sZW4oXCJsZW5ndGhCZWxvd1wiLCBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYSA8IGIgfSwgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBoYXZlIGxlbmd0aCBiZWxvdyB7ZXhwZWN0ZWR9LCBidXQgZm91bmQge2FjdHVhbH1cIilcblxuLyogZXNsaW50LWVuYWJsZSBtYXgtbGVuICovXG5cbi8vIE5vdGU6IHRoZXNlIHR3byBhbHdheXMgZmFpbCB3aGVuIGRlYWxpbmcgd2l0aCBOYU5zLlxuZGVmaW5lKFwiY2xvc2VUb1wiLCBmdW5jdGlvbiAoYWN0dWFsLCBleHBlY3RlZCwgZGVsdGEpIHtcbiAgICBjaGVjayhhY3R1YWwsIFwiYWN0dWFsXCIsIFwibnVtYmVyXCIpXG4gICAgY2hlY2soZXhwZWN0ZWQsIFwiZXhwZWN0ZWRcIiwgXCJudW1iZXJcIilcbiAgICBjaGVjayhkZWx0YSwgXCJkZWx0YVwiLCBcIm51bWJlclwiKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgdGVzdDogTWF0aC5hYnMoYWN0dWFsIC0gZXhwZWN0ZWQpIDw9IE1hdGguYWJzKGRlbHRhKSxcbiAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZCxcbiAgICAgICAgZGVsdGE6IGRlbHRhLFxuICAgICAgICBtZXNzYWdlOiBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIHdpdGhpbiB7ZGVsdGF9IG9mIHtleHBlY3RlZH1cIixcbiAgICB9XG59KVxuXG5kZWZpbmUoXCJub3RDbG9zZVRvXCIsIGZ1bmN0aW9uIChhY3R1YWwsIGV4cGVjdGVkLCBkZWx0YSkge1xuICAgIGNoZWNrKGFjdHVhbCwgXCJhY3R1YWxcIiwgXCJudW1iZXJcIilcbiAgICBjaGVjayhleHBlY3RlZCwgXCJleHBlY3RlZFwiLCBcIm51bWJlclwiKVxuICAgIGNoZWNrKGRlbHRhLCBcImRlbHRhXCIsIFwibnVtYmVyXCIpXG5cbiAgICByZXR1cm4ge1xuICAgICAgICB0ZXN0OiBNYXRoLmFicyhhY3R1YWwgLSBleHBlY3RlZCkgPiBNYXRoLmFicyhkZWx0YSksXG4gICAgICAgIGFjdHVhbDogYWN0dWFsLFxuICAgICAgICBleHBlY3RlZDogZXhwZWN0ZWQsXG4gICAgICAgIGRlbHRhOiBkZWx0YSxcbiAgICAgICAgbWVzc2FnZTogXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgYmUgd2l0aGluIHtkZWx0YX0gb2Yge2V4cGVjdGVkfVwiLFxuICAgIH1cbn0pXG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxuLyoqXG4gKiBUaGVyZSdzIDQgc2V0cyBvZiA0IHBlcm11dGF0aW9ucyBoZXJlIGZvciBgaW5jbHVkZXNgIGFuZCBgaGFzS2V5c2AsIGluc3RlYWRcbiAqIG9mIE4gc2V0cyBvZiAyICh3aGljaCB3b3VsZCBmaXQgdGhlIGBmb29gL2Bub3RGb29gIGlkaW9tIGJldHRlciksIHNvIGl0J3NcbiAqIGVhc2llciB0byBqdXN0IG1ha2UgYSBjb3VwbGUgc2VwYXJhdGUgRFNMcyBhbmQgdXNlIHRoYXQgdG8gZGVmaW5lIGV2ZXJ5dGhpbmcuXG4gKlxuICogSGVyZSdzIHRoZSB0b3AgbGV2ZWw6XG4gKlxuICogLSBzdHJpY3Qgc2hhbGxvd1xuICogLSBsb29zZSBzaGFsbG93XG4gKiAtIHN0cmljdCBkZWVwXG4gKiAtIHN0cnVjdHVyYWwgZGVlcFxuICpcbiAqIEFuZCB0aGUgc2Vjb25kIGxldmVsOlxuICpcbiAqIC0gaW5jbHVkZXMgYWxsL25vdCBtaXNzaW5nIHNvbWVcbiAqIC0gaW5jbHVkZXMgc29tZS9ub3QgbWlzc2luZyBhbGxcbiAqIC0gbm90IGluY2x1ZGluZyBhbGwvbWlzc2luZyBzb21lXG4gKiAtIG5vdCBpbmNsdWRpbmcgc29tZS9taXNzaW5nIGFsbFxuICpcbiAqIEhlcmUncyBhbiBleGFtcGxlIHVzaW5nIHRoZSBuYW1pbmcgc2NoZW1lIGZvciBgaGFzS2V5c2AsIGV0Yy5cbiAqXG4gKiAgICAgICAgICAgICAgIHwgc3RyaWN0IHNoYWxsb3cgIHwgICAgbG9vc2Ugc2hhbGxvdyAgICAgfCAgICAgc3RyaWN0IGRlZXAgICAgIHwgICAgIHN0cnVjdHVyYWwgZGVlcFxuICogLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogaW5jbHVkZXMgYWxsICB8IGBoYXNLZXlzYCAgICAgICB8IGBoYXNMb29zZUtleXNgICAgICAgIHwgYGhhc0RlZXBLZXlzYCAgICAgICB8IGBoYXNNYXRjaEtleXNgXG4gKiBpbmNsdWRlcyBzb21lIHwgYGhhc0FueUtleXNgICAgIHwgYGhhc0xvb3NlQW55S2V5c2AgICAgfCBgaGFzRGVlcEFueUtleXNgICAgIHwgYGhhc01hdGNoQW55S2V5c2BcbiAqIG1pc3Npbmcgc29tZSAgfCBgbm90SGFzQWxsS2V5c2AgfCBgbm90SGFzTG9vc2VBbGxLZXlzYCB8IGBub3RIYXNEZWVwQWxsS2V5c2AgfCBgbm90SGFzTWF0Y2hBbGxLZXlzYFxuICogbWlzc2luZyBhbGwgICB8IGBub3RIYXNLZXlzYCAgICB8IGBub3RIYXNMb29zZUtleXNgICAgIHwgYG5vdEhhc0RlZXBLZXlzYCAgICB8IGBub3RIYXNNYXRjaEtleXNgXG4gKlxuICogTm90ZSB0aGF0IHRoZSBgaGFzS2V5c2Agc2hhbGxvdyBjb21wYXJpc29uIHZhcmlhbnRzIGFyZSBhbHNvIG92ZXJsb2FkZWQgdG9cbiAqIGNvbnN1bWUgZWl0aGVyIGFuIGFycmF5IChpbiB3aGljaCBpdCBzaW1wbHkgY2hlY2tzIGFnYWluc3QgYSBsaXN0IG9mIGtleXMpIG9yXG4gKiBhbiBvYmplY3QgKHdoZXJlIGl0IGRvZXMgYSBmdWxsIGRlZXAgY29tcGFyaXNvbikuXG4gKi9cblxuLyogZXNsaW50LWVuYWJsZSBtYXgtbGVuICovXG5cbmZ1bmN0aW9uIG1ha2VJbmNsdWRlcyhhbGwsIGZ1bmMpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGFycmF5LCBrZXlzKSB7XG4gICAgICAgIGZ1bmN0aW9uIHRlc3Qoa2V5KSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZ1bmMoa2V5LCBhcnJheVtpXSkpIHJldHVybiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhbGwpIHtcbiAgICAgICAgICAgIGlmIChhcnJheS5sZW5ndGggPCBrZXlzLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghdGVzdChrZXlzW2ldKSkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBrZXlzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRlc3Qoa2V5c1tqXSkpIHJldHVybiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gZGVmaW5lSW5jbHVkZXMobmFtZSwgZnVuYywgaW52ZXJ0LCBtZXNzYWdlKSB7XG4gICAgZnVuY3Rpb24gYmFzZShhcnJheSwgdmFsdWVzKSB7XG4gICAgICAgIC8vIENoZWFwIGNhc2VzIGZpcnN0XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcnJheSkpIHJldHVybiBmYWxzZVxuICAgICAgICBpZiAoYXJyYXkgPT09IHZhbHVlcykgcmV0dXJuIHRydWVcbiAgICAgICAgcmV0dXJuIGZ1bmMoYXJyYXksIHZhbHVlcylcbiAgICB9XG5cbiAgICBkZWZpbmUobmFtZSwgZnVuY3Rpb24gKGFycmF5LCB2YWx1ZXMpIHtcbiAgICAgICAgY2hlY2soYXJyYXksIFwiYXJyYXlcIiwgXCJhcnJheVwiKVxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWVzKSkgdmFsdWVzID0gW3ZhbHVlc11cblxuICAgICAgICAvLyBleGNsdXNpdmUgb3IgdG8gaW52ZXJ0IHRoZSByZXN1bHQgaWYgYGludmVydGAgaXMgdHJ1ZVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGVzdDogIXZhbHVlcy5sZW5ndGggfHwgaW52ZXJ0IF4gYmFzZShhcnJheSwgdmFsdWVzKSxcbiAgICAgICAgICAgIGFjdHVhbDogYXJyYXksXG4gICAgICAgICAgICB2YWx1ZXM6IHZhbHVlcyxcbiAgICAgICAgICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgICAgIH1cbiAgICB9KVxufVxuXG52YXIgaW5jbHVkZXNBbGwgPSBtYWtlSW5jbHVkZXModHJ1ZSwgc3RyaWN0SXMpXG52YXIgaW5jbHVkZXNBbnkgPSBtYWtlSW5jbHVkZXMoZmFsc2UsIHN0cmljdElzKVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cbmRlZmluZUluY2x1ZGVzKFwiaW5jbHVkZXNcIiwgaW5jbHVkZXNBbGwsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUgYWxsIHZhbHVlcyBpbiB7dmFsdWVzfVwiKVxuZGVmaW5lSW5jbHVkZXMoXCJub3RJbmNsdWRlc0FsbFwiLCBpbmNsdWRlc0FsbCwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBhbGwgdmFsdWVzIGluIHt2YWx1ZXN9XCIpXG5kZWZpbmVJbmNsdWRlcyhcImluY2x1ZGVzQW55XCIsIGluY2x1ZGVzQW55LCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGFueSB2YWx1ZSBpbiB7dmFsdWVzfVwiKVxuZGVmaW5lSW5jbHVkZXMoXCJub3RJbmNsdWRlc1wiLCBpbmNsdWRlc0FueSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcblxudmFyIGluY2x1ZGVzTG9vc2VBbGwgPSBtYWtlSW5jbHVkZXModHJ1ZSwgbG9vc2VJcylcbnZhciBpbmNsdWRlc0xvb3NlQW55ID0gbWFrZUluY2x1ZGVzKGZhbHNlLCBsb29zZUlzKVxuXG5kZWZpbmVJbmNsdWRlcyhcImluY2x1ZGVzTG9vc2VcIiwgaW5jbHVkZXNMb29zZUFsbCwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbG9vc2VseSBoYXZlIGFsbCB2YWx1ZXMgaW4ge3ZhbHVlc31cIilcbmRlZmluZUluY2x1ZGVzKFwibm90SW5jbHVkZXNMb29zZUFsbFwiLCBpbmNsdWRlc0xvb3NlQWxsLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBsb29zZWx5IGhhdmUgYWxsIHZhbHVlcyBpbiB7dmFsdWVzfVwiKVxuZGVmaW5lSW5jbHVkZXMoXCJpbmNsdWRlc0xvb3NlQW55XCIsIGluY2x1ZGVzTG9vc2VBbnksIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGxvb3NlbHkgaGF2ZSBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcbmRlZmluZUluY2x1ZGVzKFwibm90SW5jbHVkZXNMb29zZVwiLCBpbmNsdWRlc0xvb3NlQW55LCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBsb29zZWx5IGhhdmUgYW55IHZhbHVlIGluIHt2YWx1ZXN9XCIpXG5cbnZhciBpbmNsdWRlc0RlZXBBbGwgPSBtYWtlSW5jbHVkZXModHJ1ZSwgbWF0Y2guc3RyaWN0KVxudmFyIGluY2x1ZGVzRGVlcEFueSA9IG1ha2VJbmNsdWRlcyhmYWxzZSwgbWF0Y2guc3RyaWN0KVxuXG5kZWZpbmVJbmNsdWRlcyhcImluY2x1ZGVzRGVlcFwiLCBpbmNsdWRlc0RlZXBBbGwsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFsbCB2YWx1ZXMgaW4ge3ZhbHVlc31cIilcbmRlZmluZUluY2x1ZGVzKFwibm90SW5jbHVkZXNEZWVwQWxsXCIsIGluY2x1ZGVzRGVlcEFsbCwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgbWF0Y2ggYWxsIHZhbHVlcyBpbiB7dmFsdWVzfVwiKVxuZGVmaW5lSW5jbHVkZXMoXCJpbmNsdWRlc0RlZXBBbnlcIiwgaW5jbHVkZXNEZWVwQW55LCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBtYXRjaCBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcbmRlZmluZUluY2x1ZGVzKFwibm90SW5jbHVkZXNEZWVwXCIsIGluY2x1ZGVzRGVlcEFueSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgbWF0Y2ggYW55IHZhbHVlIGluIHt2YWx1ZXN9XCIpXG5cbnZhciBpbmNsdWRlc01hdGNoQWxsID0gbWFrZUluY2x1ZGVzKHRydWUsIG1hdGNoLmxvb3NlKVxudmFyIGluY2x1ZGVzTWF0Y2hBbnkgPSBtYWtlSW5jbHVkZXMoZmFsc2UsIG1hdGNoLmxvb3NlKVxuXG5kZWZpbmVJbmNsdWRlcyhcImluY2x1ZGVzTWF0Y2hcIiwgaW5jbHVkZXNNYXRjaEFsbCwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbWF0Y2ggYWxsIHZhbHVlcyBpbiB7dmFsdWVzfVwiKVxuZGVmaW5lSW5jbHVkZXMoXCJub3RJbmNsdWRlc01hdGNoQWxsXCIsIGluY2x1ZGVzTWF0Y2hBbGwsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IG1hdGNoIGFsbCB2YWx1ZXMgaW4ge3ZhbHVlc31cIilcbmRlZmluZUluY2x1ZGVzKFwiaW5jbHVkZXNNYXRjaEFueVwiLCBpbmNsdWRlc01hdGNoQW55LCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBtYXRjaCBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcbmRlZmluZUluY2x1ZGVzKFwibm90SW5jbHVkZXNNYXRjaFwiLCBpbmNsdWRlc01hdGNoQW55LCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcblxuLyogZXNsaW50LWVuYWJsZSBtYXgtbGVuICovXG5cbmZ1bmN0aW9uIGlzRW1wdHkob2JqZWN0KSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkgcmV0dXJuIG9iamVjdC5sZW5ndGggPT09IDBcbiAgICBpZiAodHlwZW9mIG9iamVjdCAhPT0gXCJvYmplY3RcIiB8fCBvYmplY3QgPT09IG51bGwpIHJldHVybiB0cnVlXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKG9iamVjdCkubGVuZ3RoID09PSAwXG59XG5cbmZ1bmN0aW9uIG1ha2VIYXNPdmVybG9hZChuYW1lLCBtZXRob2RzLCBpbnZlcnQsIG1lc3NhZ2UpIHtcbiAgICBmdW5jdGlvbiBiYXNlKG9iamVjdCwga2V5cykge1xuICAgICAgICAvLyBDaGVhcCBjYXNlIGZpcnN0XG4gICAgICAgIGlmIChvYmplY3QgPT09IGtleXMpIHJldHVybiB0cnVlXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGtleXMpKSByZXR1cm4gbWV0aG9kcy5hcnJheShvYmplY3QsIGtleXMpXG4gICAgICAgIHJldHVybiBtZXRob2RzLm9iamVjdChvYmplY3QsIGtleXMpXG4gICAgfVxuXG4gICAgZGVmaW5lKG5hbWUsIGZ1bmN0aW9uIChvYmplY3QsIGtleXMpIHtcbiAgICAgICAgY2hlY2sob2JqZWN0LCBcIm9iamVjdFwiLCBcIm9iamVjdFwiKVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLy8gZXhjbHVzaXZlIG9yIHRvIGludmVydCB0aGUgcmVzdWx0IGlmIGBpbnZlcnRgIGlzIHRydWVcbiAgICAgICAgICAgIHRlc3Q6IGlzRW1wdHkoa2V5cykgfHwgaW52ZXJ0IF4gYmFzZShvYmplY3QsIGtleXMpLFxuICAgICAgICAgICAgYWN0dWFsOiBvYmplY3QsXG4gICAgICAgICAgICBrZXlzOiBrZXlzLFxuICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgfVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIG1ha2VIYXNLZXlzKG5hbWUsIGZ1bmMsIGludmVydCwgbWVzc2FnZSkge1xuICAgIGZ1bmN0aW9uIGJhc2Uob2JqZWN0LCBrZXlzKSB7XG4gICAgICAgIHJldHVybiBvYmplY3QgPT09IGtleXMgfHwgZnVuYyhvYmplY3QsIGtleXMpXG4gICAgfVxuXG4gICAgZGVmaW5lKG5hbWUsIGZ1bmN0aW9uIChvYmplY3QsIGtleXMpIHtcbiAgICAgICAgY2hlY2sob2JqZWN0LCBcIm9iamVjdFwiLCBcIm9iamVjdFwiKVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLy8gZXhjbHVzaXZlIG9yIHRvIGludmVydCB0aGUgcmVzdWx0IGlmIGBpbnZlcnRgIGlzIHRydWVcbiAgICAgICAgICAgIHRlc3Q6IGlzRW1wdHkoa2V5cykgfHwgaW52ZXJ0IF4gYmFzZShvYmplY3QsIGtleXMpLFxuICAgICAgICAgICAgYWN0dWFsOiBvYmplY3QsXG4gICAgICAgICAgICBrZXlzOiBrZXlzLFxuICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgfVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIGhhc0tleXNUeXBlKGFsbCwgZnVuYykge1xuICAgIHJldHVybiBmdW5jdGlvbiAob2JqZWN0LCBrZXlzKSB7XG4gICAgICAgIGlmICh0eXBlb2Yga2V5cyAhPT0gXCJvYmplY3RcIikgcmV0dXJuIHRydWVcbiAgICAgICAgaWYgKGtleXMgPT09IG51bGwpIHJldHVybiB0cnVlXG5cbiAgICAgICAgZnVuY3Rpb24gY2hlY2soa2V5KSB7XG4gICAgICAgICAgICByZXR1cm4gaGFzT3duLmNhbGwob2JqZWN0LCBrZXkpICYmIGZ1bmMoa2V5c1trZXldLCBvYmplY3Rba2V5XSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhbGwpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGtleTEgaW4ga2V5cykge1xuICAgICAgICAgICAgICAgIGlmIChoYXNPd24uY2FsbChrZXlzLCBrZXkxKSAmJiAhY2hlY2soa2V5MSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZvciAodmFyIGtleTIgaW4ga2V5cykge1xuICAgICAgICAgICAgICAgIGlmIChoYXNPd24uY2FsbChrZXlzLCBrZXkyKSAmJiBjaGVjayhrZXkyKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBoYXNPdmVybG9hZFR5cGUoYWxsLCBmdW5jKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgb2JqZWN0OiBoYXNLZXlzVHlwZShhbGwsIGZ1bmMpLFxuICAgICAgICBhcnJheTogZnVuY3Rpb24gKG9iamVjdCwga2V5cykge1xuICAgICAgICAgICAgaWYgKGFsbCkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWhhc093bi5jYWxsKG9iamVjdCwga2V5c1tpXSkpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKG9iamVjdCwga2V5c1tqXSkpIHJldHVybiB0cnVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgIH1cbn1cblxuLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuXG52YXIgaGFzQWxsS2V5cyA9IGhhc092ZXJsb2FkVHlwZSh0cnVlLCBzdHJpY3RJcylcbnZhciBoYXNBbnlLZXlzID0gaGFzT3ZlcmxvYWRUeXBlKGZhbHNlLCBzdHJpY3RJcylcblxubWFrZUhhc092ZXJsb2FkKFwiaGFzS2V5c1wiLCBoYXNBbGxLZXlzLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxubWFrZUhhc092ZXJsb2FkKFwibm90SGFzQWxsS2V5c1wiLCBoYXNBbGxLZXlzLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxubWFrZUhhc092ZXJsb2FkKFwiaGFzQW55S2V5c1wiLCBoYXNBbnlLZXlzLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGFueSBrZXkgaW4ge2tleXN9XCIpXG5tYWtlSGFzT3ZlcmxvYWQoXCJub3RIYXNLZXlzXCIsIGhhc0FueUtleXMsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUgYW55IGtleSBpbiB7a2V5c31cIilcblxudmFyIGhhc0xvb3NlQWxsS2V5cyA9IGhhc092ZXJsb2FkVHlwZSh0cnVlLCBsb29zZUlzKVxudmFyIGhhc0xvb3NlQW55S2V5cyA9IGhhc092ZXJsb2FkVHlwZShmYWxzZSwgbG9vc2VJcylcblxubWFrZUhhc092ZXJsb2FkKFwiaGFzTG9vc2VLZXlzXCIsIGhhc0xvb3NlQWxsS2V5cywgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbG9vc2VseSBoYXZlIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxubWFrZUhhc092ZXJsb2FkKFwibm90SGFzTG9vc2VBbGxLZXlzXCIsIGhhc0xvb3NlQWxsS2V5cywgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgbG9vc2VseSBoYXZlIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxubWFrZUhhc092ZXJsb2FkKFwiaGFzTG9vc2VBbnlLZXlzXCIsIGhhc0xvb3NlQW55S2V5cywgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbG9vc2VseSBoYXZlIGFueSBrZXkgaW4ge2tleXN9XCIpXG5tYWtlSGFzT3ZlcmxvYWQoXCJub3RIYXNMb29zZUtleXNcIiwgaGFzTG9vc2VBbnlLZXlzLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBsb29zZWx5IGhhdmUgYW55IGtleSBpbiB7a2V5c31cIilcblxudmFyIGhhc0RlZXBBbGxLZXlzID0gaGFzS2V5c1R5cGUodHJ1ZSwgbWF0Y2guc3RyaWN0KVxudmFyIGhhc0RlZXBBbnlLZXlzID0gaGFzS2V5c1R5cGUoZmFsc2UsIG1hdGNoLnN0cmljdClcblxubWFrZUhhc0tleXMoXCJoYXNEZWVwS2V5c1wiLCBoYXNEZWVwQWxsS2V5cywgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBhbGwga2V5cyBpbiB7a2V5c31cIilcbm1ha2VIYXNLZXlzKFwibm90SGFzRGVlcEFsbEtleXNcIiwgaGFzRGVlcEFsbEtleXMsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUgYWxsIGtleXMgaW4ge2tleXN9XCIpXG5tYWtlSGFzS2V5cyhcImhhc0RlZXBBbnlLZXlzXCIsIGhhc0RlZXBBbnlLZXlzLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGFueSBrZXkgaW4ge2tleXN9XCIpXG5tYWtlSGFzS2V5cyhcIm5vdEhhc0RlZXBLZXlzXCIsIGhhc0RlZXBBbnlLZXlzLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGFueSBrZXkgaW4ge2tleXN9XCIpXG5cbnZhciBoYXNNYXRjaEFsbEtleXMgPSBoYXNLZXlzVHlwZSh0cnVlLCBtYXRjaC5sb29zZSlcbnZhciBoYXNNYXRjaEFueUtleXMgPSBoYXNLZXlzVHlwZShmYWxzZSwgbWF0Y2gubG9vc2UpXG5cbm1ha2VIYXNLZXlzKFwiaGFzTWF0Y2hLZXlzXCIsIGhhc01hdGNoQWxsS2V5cywgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbWF0Y2ggYWxsIGtleXMgaW4ge2tleXN9XCIpXG5tYWtlSGFzS2V5cyhcIm5vdEhhc01hdGNoQWxsS2V5c1wiLCBoYXNNYXRjaEFsbEtleXMsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IG1hdGNoIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxubWFrZUhhc0tleXMoXCJoYXNNYXRjaEFueUtleXNcIiwgaGFzTWF0Y2hBbnlLZXlzLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBtYXRjaCBhbnkga2V5IGluIHtrZXlzfVwiKVxubWFrZUhhc0tleXMoXCJub3RIYXNNYXRjaEtleXNcIiwgaGFzTWF0Y2hBbnlLZXlzLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbnkga2V5IGluIHtrZXlzfVwiKVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9saWIvZG9tXCIpXG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vKipcbiAqIE1haW4gZW50cnkgcG9pbnQsIGZvciB0aG9zZSB3YW50aW5nIHRvIHVzZSB0aGlzIGZyYW1ld29yayB3aXRoIHRoZSBjb3JlXG4gKiBhc3NlcnRpb25zLlxuICovXG52YXIgVGhhbGxpdW0gPSByZXF1aXJlKFwiLi9saWIvYXBpL3RoYWxsaXVtXCIpXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFRoYWxsaXVtKClcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBUaGFsbGl1bSA9IHJlcXVpcmUoXCIuL2xpYi9hcGkvdGhhbGxpdW1cIilcbnZhciBSZXBvcnRzID0gcmVxdWlyZShcIi4vbGliL2NvcmUvcmVwb3J0c1wiKVxudmFyIFR5cGVzID0gUmVwb3J0cy5UeXBlc1xuXG5leHBvcnRzLnJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5ldyBUaGFsbGl1bSgpXG59XG5cbmZ1bmN0aW9uIGQoZHVyYXRpb24pIHtcbiAgICBpZiAoZHVyYXRpb24gPT0gbnVsbCkgcmV0dXJuIDEwXG4gICAgaWYgKHR5cGVvZiBkdXJhdGlvbiA9PT0gXCJudW1iZXJcIikgcmV0dXJuIGR1cmF0aW9ufDBcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYGR1cmF0aW9uYCB0byBiZSBhIG51bWJlciBpZiBpdCBleGlzdHNcIilcbn1cblxuZnVuY3Rpb24gcyhzbG93KSB7XG4gICAgaWYgKHNsb3cgPT0gbnVsbCkgcmV0dXJuIDc1XG4gICAgaWYgKHR5cGVvZiBzbG93ID09PSBcIm51bWJlclwiKSByZXR1cm4gc2xvd3wwXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBzbG93YCB0byBiZSBhIG51bWJlciBpZiBpdCBleGlzdHNcIilcbn1cblxuZnVuY3Rpb24gcChwYXRoKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocGF0aCkpIHJldHVybiBwYXRoXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBwYXRoYCB0byBiZSBhbiBhcnJheSBvZiBsb2NhdGlvbnNcIilcbn1cblxuZnVuY3Rpb24gaCh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIHR5cGVvZiB2YWx1ZS5fID09PSBcIm51bWJlclwiKSByZXR1cm4gdmFsdWVcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHZhbHVlYCB0byBiZSBhIGhvb2sgZXJyb3JcIilcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgcmVwb3J0LCBtYWlubHkgZm9yIHRlc3RpbmcgcmVwb3J0ZXJzLlxuICovXG5leHBvcnRzLnJlcG9ydHMgPSB7XG4gICAgc3RhcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBvcnRzLlN0YXJ0KClcbiAgICB9LFxuXG4gICAgZW50ZXI6IGZ1bmN0aW9uIChwYXRoLCBkdXJhdGlvbiwgc2xvdykge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuRW50ZXIocChwYXRoKSwgZChkdXJhdGlvbiksIHMoc2xvdykpXG4gICAgfSxcblxuICAgIGxlYXZlOiBmdW5jdGlvbiAocGF0aCkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuTGVhdmUocChwYXRoKSlcbiAgICB9LFxuXG4gICAgcGFzczogZnVuY3Rpb24gKHBhdGgsIGR1cmF0aW9uLCBzbG93KSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5QYXNzKHAocGF0aCksIGQoZHVyYXRpb24pLCBzKHNsb3cpKVxuICAgIH0sXG5cbiAgICBmYWlsOiBmdW5jdGlvbiAocGF0aCwgdmFsdWUsIGR1cmF0aW9uLCBzbG93LCBpc0ZhaWxhYmxlKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuRmFpbChcbiAgICAgICAgICAgIHAocGF0aCksIHZhbHVlLCBkKGR1cmF0aW9uKSwgcyhzbG93KSxcbiAgICAgICAgICAgICEhaXNGYWlsYWJsZSlcbiAgICB9LFxuXG4gICAgc2tpcDogZnVuY3Rpb24gKHBhdGgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBvcnRzLlNraXAocChwYXRoKSlcbiAgICB9LFxuXG4gICAgZW5kOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5FbmQoKVxuICAgIH0sXG5cbiAgICBlcnJvcjogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5FcnJvcih2YWx1ZSlcbiAgICB9LFxuXG4gICAgaG9vazogZnVuY3Rpb24gKHBhdGgsIHJvb3RQYXRoLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuSG9vayhwKHBhdGgpLCBwKHJvb3RQYXRoKSwgaCh2YWx1ZSkpXG4gICAgfSxcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgaG9vayBlcnJvciwgbWFpbmx5IGZvciB0ZXN0aW5nIHJlcG9ydGVycy5cbiAqL1xuZXhwb3J0cy5ob29rRXJyb3JzID0ge1xuICAgIGJlZm9yZUFsbDogZnVuY3Rpb24gKGZ1bmMsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5Ib29rRXJyb3IoVHlwZXMuQmVmb3JlQWxsLCBmdW5jLCB2YWx1ZSlcbiAgICB9LFxuXG4gICAgYmVmb3JlRWFjaDogZnVuY3Rpb24gKGZ1bmMsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5Ib29rRXJyb3IoVHlwZXMuQmVmb3JlRWFjaCwgZnVuYywgdmFsdWUpXG4gICAgfSxcblxuICAgIGFmdGVyRWFjaDogZnVuY3Rpb24gKGZ1bmMsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5Ib29rRXJyb3IoVHlwZXMuQWZ0ZXJFYWNoLCBmdW5jLCB2YWx1ZSlcbiAgICB9LFxuXG4gICAgYWZ0ZXJBbGw6IGZ1bmN0aW9uIChmdW5jLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuSG9va0Vycm9yKFR5cGVzLkFmdGVyQWxsLCBmdW5jLCB2YWx1ZSlcbiAgICB9LFxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgbG9jYXRpb24sIG1haW5seSBmb3IgdGVzdGluZyByZXBvcnRlcnMuXG4gKi9cbmV4cG9ydHMubG9jYXRpb24gPSBmdW5jdGlvbiAobmFtZSwgaW5kZXgpIHtcbiAgICBpZiAodHlwZW9mIG5hbWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBuYW1lYCB0byBiZSBhIHN0cmluZ1wiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5kZXggIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBpbmRleGAgdG8gYmUgYSBudW1iZXJcIilcbiAgICB9XG5cbiAgICByZXR1cm4ge25hbWU6IG5hbWUsIGluZGV4OiBpbmRleHwwfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuZXhwb3J0cy5hZGRIb29rID0gZnVuY3Rpb24gKGxpc3QsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGxpc3QgIT0gbnVsbCkge1xuICAgICAgICBsaXN0LnB1c2goY2FsbGJhY2spXG4gICAgICAgIHJldHVybiBsaXN0XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFtjYWxsYmFja11cbiAgICB9XG59XG5cbmV4cG9ydHMucmVtb3ZlSG9vayA9IGZ1bmN0aW9uIChsaXN0LCBjYWxsYmFjaykge1xuICAgIGlmIChsaXN0ID09IG51bGwpIHJldHVybiB1bmRlZmluZWRcbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgaWYgKGxpc3RbMF0gPT09IGNhbGxiYWNrKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGluZGV4ID0gbGlzdC5pbmRleE9mKGNhbGxiYWNrKVxuXG4gICAgICAgIGlmIChpbmRleCA+PSAwKSBsaXN0LnNwbGljZShpbmRleCwgMSlcbiAgICB9XG4gICAgcmV0dXJuIGxpc3Rcbn1cblxuZXhwb3J0cy5oYXNIb29rID0gZnVuY3Rpb24gKGxpc3QsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGxpc3QgPT0gbnVsbCkgcmV0dXJuIGZhbHNlXG4gICAgaWYgKGxpc3QubGVuZ3RoID4gMSkgcmV0dXJuIGxpc3QuaW5kZXhPZihjYWxsYmFjaykgPj0gMFxuICAgIHJldHVybiBsaXN0WzBdID09PSBjYWxsYmFja1xufVxuXG4vLyBUT0RPOiBjYWNoZSBhbmQgcmVtb3ZlIHRoZXNlIHRyYXZlcnNhbHMgZm9yIDAuNC5cbi8vIE5vdGUgdGhhdCBhIHRpbWVvdXQgb2YgMCBtZWFucyB0byBpbmhlcml0IHRoZSBwYXJlbnQuXG5leHBvcnRzLmdldFRpbWVvdXQgPSBmdW5jdGlvbiAodGVzdCkge1xuICAgIHdoaWxlICghdGVzdC50aW1lb3V0ICYmIHRlc3QucGFyZW50ICE9IG51bGwpIHtcbiAgICAgICAgdGVzdCA9IHRlc3QucGFyZW50XG4gICAgfVxuXG4gICAgcmV0dXJuIHRlc3QudGltZW91dCB8fCAyMDAwIC8vIG1zIC0gZGVmYXVsdCB0aW1lb3V0XG59XG5cbi8vIE5vdGUgdGhhdCBhIHNsb3duZXNzIHRocmVzaG9sZCBvZiAwIG1lYW5zIHRvIGluaGVyaXQgdGhlIHBhcmVudC5cbmV4cG9ydHMuZ2V0U2xvdyA9IGZ1bmN0aW9uICh0ZXN0KSB7XG4gICAgd2hpbGUgKCF0ZXN0LnNsb3cgJiYgdGVzdC5wYXJlbnQgIT0gbnVsbCkge1xuICAgICAgICB0ZXN0ID0gdGVzdC5wYXJlbnRcbiAgICB9XG5cbiAgICByZXR1cm4gdGVzdC5zbG93IHx8IDc1IC8vIG1zIC0gZGVmYXVsdCBzbG93IHRocmVzaG9sZFxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIG1ldGhvZHMgPSByZXF1aXJlKFwiLi4vbWV0aG9kc1wiKVxudmFyIFRlc3RzID0gcmVxdWlyZShcIi4uL2NvcmUvdGVzdHNcIilcbnZhciBDb21tb24gPSByZXF1aXJlKFwiLi9jb21tb25cIilcblxuLyoqXG4gKiBUaGlzIGNvbnRhaW5zIHRoZSBsb3cgbGV2ZWwsIG1vcmUgYXJjYW5lIHRoaW5ncyB0aGF0IGFyZSBnZW5lcmFsbHkgbm90XG4gKiBpbnRlcmVzdGluZyB0byBhbnlvbmUgb3RoZXIgdGhhbiBwbHVnaW4gZGV2ZWxvcGVycy5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBSZWZsZWN0XG5mdW5jdGlvbiBSZWZsZWN0KHRlc3QpIHtcbiAgICB2YXIgcmVmbGVjdCA9IHRlc3QucmVmbGVjdFxuXG4gICAgaWYgKHJlZmxlY3QgIT0gbnVsbCkgcmV0dXJuIHJlZmxlY3RcbiAgICBpZiAodGVzdC5yb290ICE9PSB0ZXN0KSByZXR1cm4gdGVzdC5yZWZsZWN0ID0gbmV3IFJlZmxlY3RDaGlsZCh0ZXN0KVxuICAgIHJldHVybiB0ZXN0LnJlZmxlY3QgPSBuZXcgUmVmbGVjdFJvb3QodGVzdClcbn1cblxubWV0aG9kcyhSZWZsZWN0LCB7XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50bHkgZXhlY3V0aW5nIHRlc3QuXG4gICAgICovXG4gICAgZ2V0IGN1cnJlbnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVmbGVjdCh0aGlzLl8ucm9vdC5jdXJyZW50KVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHJvb3QgdGVzdC5cbiAgICAgKi9cbiAgICBnZXQgcm9vdCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZWZsZWN0KHRoaXMuXy5yb290KVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgdG90YWwgdGVzdCBjb3VudC5cbiAgICAgKi9cbiAgICBnZXQgY291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8udGVzdHMgPT0gbnVsbCA/IDAgOiB0aGlzLl8udGVzdHMubGVuZ3RoXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgdGVzdCBsaXN0LCBhcyBhIFJlZmxlY3QgY29sbGVjdGlvbi4gVGhpcyBpc1xuICAgICAqIGludGVudGlvbmFsbHkgYSBzbGljZSwgc28geW91IGNhbid0IG11dGF0ZSB0aGUgcmVhbCBjaGlsZHJlbi5cbiAgICAgKi9cbiAgICBnZXQgY2hpbGRyZW4oKSB7XG4gICAgICAgIGlmICh0aGlzLl8udGVzdHMgPT0gbnVsbCkgcmV0dXJuIFtdXG4gICAgICAgIHJldHVybiB0aGlzLl8udGVzdHMubWFwKGZ1bmN0aW9uICh0ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlZmxlY3RDaGlsZCh0ZXN0KVxuICAgICAgICB9KVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBJcyB0aGlzIHRlc3QgdGhlIHJvb3QsIGkuZS4gdG9wIGxldmVsP1xuICAgICAqL1xuICAgIGdldCBpc1Jvb3QoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8ucGFyZW50ID09IG51bGxcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogSXMgdGhpcyBsb2NrZWQgKGkuZS4gdW5zYWZlIHRvIG1vZGlmeSk/XG4gICAgICovXG4gICAgZ2V0IGlzTG9ja2VkKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl8ubG9ja2VkXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgb3duLCBub3QgbmVjZXNzYXJpbHkgYWN0aXZlLCB0aW1lb3V0LiAwIG1lYW5zIGluaGVyaXQgdGhlXG4gICAgICogcGFyZW50J3MsIGFuZCBgSW5maW5pdHlgIG1lYW5zIGl0J3MgZGlzYWJsZWQuXG4gICAgICovXG4gICAgZ2V0IG93blRpbWVvdXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8udGltZW91dCB8fCAwXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgYWN0aXZlIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLCBub3QgbmVjZXNzYXJpbHkgb3duLCBvciB0aGVcbiAgICAgKiBmcmFtZXdvcmsgZGVmYXVsdCBvZiAyMDAwLCBpZiBub25lIHdhcyBzZXQuXG4gICAgICovXG4gICAgZ2V0IHRpbWVvdXQoKSB7XG4gICAgICAgIHJldHVybiBDb21tb24uZ2V0VGltZW91dCh0aGlzLl8pXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgb3duLCBub3QgbmVjZXNzYXJpbHkgYWN0aXZlLCBzbG93IHRocmVzaG9sZC4gMCBtZWFucyBpbmhlcml0IHRoZVxuICAgICAqIHBhcmVudCdzLCBhbmQgYEluZmluaXR5YCBtZWFucyBpdCdzIGRpc2FibGVkLlxuICAgICAqL1xuICAgIGdldCBvd25TbG93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnNsb3cgfHwgMFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGFjdGl2ZSBzbG93IHRocmVzaG9sZCBpbiBtaWxsaXNlY29uZHMsIG5vdCBuZWNlc3NhcmlseSBvd24sIG9yXG4gICAgICogdGhlIGZyYW1ld29yayBkZWZhdWx0IG9mIDc1LCBpZiBub25lIHdhcyBzZXQuXG4gICAgICovXG4gICAgZ2V0IHNsb3coKSB7XG4gICAgICAgIHJldHVybiBDb21tb24uZ2V0U2xvdyh0aGlzLl8pXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGVzdCdzIG93biBtYXggYXR0ZW1wdCBjb3VudC4gTm90ZSB0aGF0IHRoaXMgaXMgcGFyYXNpdGljYWxseVxuICAgICAqIGluaGVyaXRlZCBmcm9tIGl0cyBwYXJlbnQsIG5vdCBkZWxlZ2F0ZWQuXG4gICAgICovXG4gICAgZ2V0IGF0dGVtcHRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLmF0dGVtcHRzXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB3aGV0aGVyIHRoaXMgdGVzdCBpcyBmYWlsYWJsZS4gTm90ZSB0aGF0IHRoaXMgaXMgcGFyYXNpdGljYWxseVxuICAgICAqIGluaGVyaXRlZCBmcm9tIGl0cyBwYXJlbnQsIG5vdCBkZWxlZ2F0ZWQuXG4gICAgICovXG4gICAgZ2V0IGlzRmFpbGFibGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8uaXNGYWlsYWJsZVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBob29rIHRvIGJlIHJ1biBiZWZvcmUgZWFjaCBzdWJ0ZXN0LCBpbmNsdWRpbmcgdGhlaXIgc3VidGVzdHMgYW5kIHNvXG4gICAgICogb24uXG4gICAgICovXG4gICAgYmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5iZWZvcmVFYWNoID0gQ29tbW9uLmFkZEhvb2sodGhpcy5fLmJlZm9yZUVhY2gsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBob29rIHRvIGJlIHJ1biBvbmNlIGJlZm9yZSBhbGwgc3VidGVzdHMgYXJlIHJ1bi5cbiAgICAgKi9cbiAgICBiZWZvcmVBbGw6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fLmJlZm9yZUFsbCA9IENvbW1vbi5hZGRIb29rKHRoaXMuXy5iZWZvcmVBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgIC8qKlxuICAgICogQWRkIGEgaG9vayB0byBiZSBydW4gYWZ0ZXIgZWFjaCBzdWJ0ZXN0LCBpbmNsdWRpbmcgdGhlaXIgc3VidGVzdHMgYW5kIHNvXG4gICAgKiBvbi5cbiAgICAqL1xuICAgIGFmdGVyOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5hZnRlckVhY2ggPSBDb21tb24uYWRkSG9vayh0aGlzLl8uYWZ0ZXJFYWNoLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgaG9vayB0byBiZSBydW4gb25jZSBhZnRlciBhbGwgc3VidGVzdHMgYXJlIHJ1bi5cbiAgICAgKi9cbiAgICBhZnRlckFsbDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl8uYWZ0ZXJBbGwgPSBDb21tb24uYWRkSG9vayh0aGlzLl8uYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5iZWZvcmVgIG9yIGByZWZsZWN0LmJlZm9yZWAuXG4gICAgICovXG4gICAgaGFzQmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBDb21tb24uaGFzSG9vayh0aGlzLl8uYmVmb3JlRWFjaCwgY2FsbGJhY2spXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhIGhvb2sgcHJldmlvdXNseSBhZGRlZCB3aXRoIGB0LmJlZm9yZUFsbGAgb3IgYHJlZmxlY3QuYmVmb3JlQWxsYC5cbiAgICAgKi9cbiAgICBoYXNCZWZvcmVBbGw6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIENvbW1vbi5oYXNIb29rKHRoaXMuXy5iZWZvcmVBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5hZnRlcmAgb3JgcmVmbGVjdC5hZnRlcmAuXG4gICAgICovXG4gICAgaGFzQWZ0ZXI6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIENvbW1vbi5oYXNIb29rKHRoaXMuXy5hZnRlckVhY2gsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5hZnRlckFsbGAgb3IgYHJlZmxlY3QuYWZ0ZXJBbGxgLlxuICAgICAqL1xuICAgIGhhc0FmdGVyQWxsOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBDb21tb24uaGFzSG9vayh0aGlzLl8uYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5iZWZvcmVgIG9yIGByZWZsZWN0LmJlZm9yZWAuXG4gICAgICovXG4gICAgcmVtb3ZlQmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5iZWZvcmVFYWNoID0gQ29tbW9uLnJlbW92ZUhvb2sodGhpcy5fLmJlZm9yZUVhY2gsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5iZWZvcmVBbGxgIG9yIGByZWZsZWN0LmJlZm9yZUFsbGAuXG4gICAgICovXG4gICAgcmVtb3ZlQmVmb3JlQWxsOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5iZWZvcmVBbGwgPSBDb21tb24ucmVtb3ZlSG9vayh0aGlzLl8uYmVmb3JlQWxsLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgaG9vayBwcmV2aW91c2x5IGFkZGVkIHdpdGggYHQuYWZ0ZXJgIG9yYHJlZmxlY3QuYWZ0ZXJgLlxuICAgICAqL1xuICAgIHJlbW92ZUFmdGVyOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5hZnRlckVhY2ggPSBDb21tb24ucmVtb3ZlSG9vayh0aGlzLl8uYWZ0ZXJFYWNoLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgaG9vayBwcmV2aW91c2x5IGFkZGVkIHdpdGggYHQuYWZ0ZXJBbGxgIG9yIGByZWZsZWN0LmFmdGVyQWxsYC5cbiAgICAgKi9cbiAgICByZW1vdmVBZnRlckFsbDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl8uYWZ0ZXJBbGwgPSBDb21tb24ucmVtb3ZlSG9vayh0aGlzLl8uYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBibG9jayBvciBpbmxpbmUgdGVzdC5cbiAgICAgKi9cbiAgICB0ZXN0OiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYG5hbWVgIHRvIGJlIGEgc3RyaW5nXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgVGVzdHMuYWRkTm9ybWFsKHRoaXMuXy5yb290LmN1cnJlbnQsIG5hbWUsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBza2lwcGVkIGJsb2NrIG9yIGlubGluZSB0ZXN0LlxuICAgICAqL1xuICAgIHRlc3RTa2lwOiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYG5hbWVgIHRvIGJlIGEgc3RyaW5nXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgVGVzdHMuYWRkU2tpcHBlZCh0aGlzLl8ucm9vdC5jdXJyZW50LCBuYW1lKVxuICAgIH0sXG59KVxuXG5mdW5jdGlvbiBSZWZsZWN0Um9vdChyb290KSB7XG4gICAgdGhpcy5fID0gcm9vdFxufVxuXG5tZXRob2RzKFJlZmxlY3RSb290LCBSZWZsZWN0LCB7XG4gICAgLyoqXG4gICAgICogV2hldGhlciBhIHJlcG9ydGVyIHdhcyByZWdpc3RlcmVkLlxuICAgICAqL1xuICAgIGhhc1JlcG9ydGVyOiBmdW5jdGlvbiAocmVwb3J0ZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXBvcnRlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHJlcG9ydGVyYCB0byBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QucmVwb3J0ZXJJZHMuaW5kZXhPZihyZXBvcnRlcikgPj0gMFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSByZXBvcnRlci5cbiAgICAgKi9cbiAgICByZXBvcnRlcjogZnVuY3Rpb24gKHJlcG9ydGVyLCBhcmcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXBvcnRlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHJlcG9ydGVyYCB0byBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcm9vdCA9IHRoaXMuXy5yb290XG5cbiAgICAgICAgaWYgKHJvb3QuY3VycmVudCAhPT0gcm9vdCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmVwb3J0ZXJzIG1heSBvbmx5IGJlIGFkZGVkIHRvIHRoZSByb290XCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAocm9vdC5yZXBvcnRlcklkcy5pbmRleE9mKHJlcG9ydGVyKSA8IDApIHtcbiAgICAgICAgICAgIHJvb3QucmVwb3J0ZXJJZHMucHVzaChyZXBvcnRlcilcbiAgICAgICAgICAgIHJvb3QucmVwb3J0ZXJzLnB1c2gocmVwb3J0ZXIoYXJnKSlcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSByZXBvcnRlci5cbiAgICAgKi9cbiAgICByZW1vdmVSZXBvcnRlcjogZnVuY3Rpb24gKHJlcG9ydGVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVwb3J0ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGByZXBvcnRlcmAgdG8gYmUgYSBmdW5jdGlvblwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJvb3QgPSB0aGlzLl8ucm9vdFxuXG4gICAgICAgIGlmIChyb290LmN1cnJlbnQgIT09IHJvb3QpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlcG9ydGVycyBtYXkgb25seSBiZSBhZGRlZCB0byB0aGUgcm9vdFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGluZGV4ID0gcm9vdC5yZXBvcnRlcklkcy5pbmRleE9mKHJlcG9ydGVyKVxuXG4gICAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgICByb290LnJlcG9ydGVySWRzLnNwbGljZShpbmRleCwgMSlcbiAgICAgICAgICAgIHJvb3QucmVwb3J0ZXJzLnNwbGljZShpbmRleCwgMSlcbiAgICAgICAgfVxuICAgIH0sXG59KVxuXG5mdW5jdGlvbiBSZWZsZWN0Q2hpbGQocm9vdCkge1xuICAgIHRoaXMuXyA9IHJvb3Rcbn1cblxubWV0aG9kcyhSZWZsZWN0Q2hpbGQsIFJlZmxlY3QsIHtcbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRlc3QgbmFtZSwgb3IgYHVuZGVmaW5lZGAgaWYgaXQncyB0aGUgcm9vdCB0ZXN0LlxuICAgICAqL1xuICAgIGdldCBuYW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLm5hbWVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0ZXN0IGluZGV4LCBvciBgLTFgIGlmIGl0J3MgdGhlIHJvb3QgdGVzdC5cbiAgICAgKi9cbiAgICBnZXQgaW5kZXgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8uaW5kZXhcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBwYXJlbnQgdGVzdCBhcyBhIFJlZmxlY3QuXG4gICAgICovXG4gICAgZ2V0IHBhcmVudCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZWZsZWN0KHRoaXMuXy5wYXJlbnQpXG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgbWV0aG9kcyA9IHJlcXVpcmUoXCIuLi9tZXRob2RzXCIpXG52YXIgVGVzdHMgPSByZXF1aXJlKFwiLi4vY29yZS90ZXN0c1wiKVxudmFyIEZpbHRlciA9IHJlcXVpcmUoXCIuLi9jb3JlL2ZpbHRlclwiKVxudmFyIENvbW1vbiA9IHJlcXVpcmUoXCIuL2NvbW1vblwiKVxudmFyIFJlZmxlY3QgPSByZXF1aXJlKFwiLi9yZWZsZWN0XCIpXG5cbm1vZHVsZS5leHBvcnRzID0gVGhhbGxpdW1cbmZ1bmN0aW9uIFRoYWxsaXVtKCkge1xuICAgIHRoaXMuXyA9IFRlc3RzLmNyZWF0ZVJvb3QodGhpcylcbn1cblxubWV0aG9kcyhUaGFsbGl1bSwge1xuICAgIC8qKlxuICAgICAqIENhbGwgYSBwbHVnaW4gYW5kIHJldHVybiB0aGUgcmVzdWx0LiBUaGUgcGx1Z2luIGlzIGNhbGxlZCB3aXRoIGEgUmVmbGVjdFxuICAgICAqIGluc3RhbmNlIGZvciBhY2Nlc3MgdG8gcGxlbnR5IG9mIHBvdGVudGlhbGx5IHVzZWZ1bCBpbnRlcm5hbCBkZXRhaWxzLlxuICAgICAqL1xuICAgIGNhbGw6IGZ1bmN0aW9uIChwbHVnaW4sIGFyZykge1xuICAgICAgICB2YXIgcmVmbGVjdCA9IG5ldyBSZWZsZWN0KHRoaXMuXy5yb290LmN1cnJlbnQpXG5cbiAgICAgICAgcmV0dXJuIHBsdWdpbi5jYWxsKHJlZmxlY3QsIHJlZmxlY3QsIGFyZylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogV2hpdGVsaXN0IHNwZWNpZmljIHRlc3RzLCB1c2luZyBhcnJheS1iYXNlZCBzZWxlY3RvcnMgd2hlcmUgZWFjaCBlbnRyeVxuICAgICAqIGlzIGVpdGhlciBhIHN0cmluZyBvciByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICovXG4gICAgb25seTogZnVuY3Rpb24gKC8qIC4uLnNlbGVjdG9ycyAqLykge1xuICAgICAgICB0aGlzLl8ucm9vdC5jdXJyZW50Lm9ubHkgPSBGaWx0ZXIuY3JlYXRlLmFwcGx5KHVuZGVmaW5lZCwgYXJndW1lbnRzKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSByZXBvcnRlci5cbiAgICAgKi9cbiAgICByZXBvcnRlcjogZnVuY3Rpb24gKHJlcG9ydGVyLCBhcmcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXBvcnRlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHJlcG9ydGVyYCB0byBiZSBhIGZ1bmN0aW9uLlwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJvb3QgPSB0aGlzLl8ucm9vdFxuXG4gICAgICAgIGlmIChyb290LmN1cnJlbnQgIT09IHJvb3QpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlcG9ydGVycyBtYXkgb25seSBiZSBhZGRlZCB0byB0aGUgcm9vdC5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXN1bHQgPSByZXBvcnRlcihhcmcpXG5cbiAgICAgICAgLy8gRG9uJ3QgYXNzdW1lIGl0J3MgYSBmdW5jdGlvbi4gVmVyaWZ5IGl0IGFjdHVhbGx5IGlzLCBzbyB3ZSBkb24ndCBoYXZlXG4gICAgICAgIC8vIGluZXhwbGljYWJsZSB0eXBlIGVycm9ycyBpbnRlcm5hbGx5IGFmdGVyIGl0J3MgaW52b2tlZCwgYW5kIHNvIHVzZXJzXG4gICAgICAgIC8vIHdvbid0IGdldCB0b28gY29uZnVzZWQuXG4gICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJFeHBlY3RlZCBgcmVwb3J0ZXJgIHRvIHJldHVybiBhIGZ1bmN0aW9uLiBDaGVjayB3aXRoIHRoZSBcIiArXG4gICAgICAgICAgICAgICAgXCJyZXBvcnRlcidzIGF1dGhvciwgYW5kIGhhdmUgdGhlbSBmaXggdGhlaXIgcmVwb3J0ZXIuXCIpXG4gICAgICAgIH1cblxuICAgICAgICByb290LnJlcG9ydGVyID0gcmVzdWx0XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIHRoaXMgaGFzIGEgcmVwb3J0ZXIuXG4gICAgICovXG4gICAgZ2V0IGhhc1JlcG9ydGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QucmVwb3J0ZXIgIT0gbnVsbFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgdGltZW91dC4gMCBtZWFucyBpbmhlcml0IHRoZSBwYXJlbnQncywgYW5kIGBJbmZpbml0eWBcbiAgICAgKiBtZWFucyBpdCdzIGRpc2FibGVkLlxuICAgICAqL1xuICAgIGdldCB0aW1lb3V0KCkge1xuICAgICAgICByZXR1cm4gQ29tbW9uLmdldFRpbWVvdXQodGhpcy5fLnJvb3QuY3VycmVudClcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcywgcm91bmRpbmcgbmVnYXRpdmVzIHRvIDAuIFNldHRpbmcgdGhlXG4gICAgICogdGltZW91dCB0byAwIG1lYW5zIHRvIGluaGVyaXQgdGhlIHBhcmVudCB0aW1lb3V0LCBhbmQgc2V0dGluZyBpdCB0b1xuICAgICAqIGBJbmZpbml0eWAgZGlzYWJsZXMgaXQuXG4gICAgICovXG4gICAgc2V0IHRpbWVvdXQodGltZW91dCkge1xuICAgICAgICB0aGlzLl8ucm9vdC5jdXJyZW50LnRpbWVvdXQgPSBNYXRoLmZsb29yKE1hdGgubWF4KCt0aW1lb3V0LCAwKSlcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IHNsb3cgdGhyZXNob2xkLiAwIG1lYW5zIGluaGVyaXQgdGhlIHBhcmVudCdzLCBhbmRcbiAgICAgKiBgSW5maW5pdHlgIG1lYW5zIGl0J3MgZGlzYWJsZWQuXG4gICAgICovXG4gICAgZ2V0IHNsb3coKSB7XG4gICAgICAgIHJldHVybiBDb21tb24uZ2V0U2xvdyh0aGlzLl8ucm9vdC5jdXJyZW50KVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHNsb3cgdGhyZXNob2xkIGluIG1pbGxpc2Vjb25kcywgcm91bmRpbmcgbmVnYXRpdmVzIHRvIDAuIFNldHRpbmdcbiAgICAgKiB0aGUgdGltZW91dCB0byAwIG1lYW5zIHRvIGluaGVyaXQgdGhlIHBhcmVudCB0aHJlc2hvbGQsIGFuZCBzZXR0aW5nIGl0IHRvXG4gICAgICogYEluZmluaXR5YCBkaXNhYmxlcyBpdC5cbiAgICAgKi9cbiAgICBzZXQgc2xvdyhzbG93KSB7XG4gICAgICAgIHRoaXMuXy5yb290LmN1cnJlbnQuc2xvdyA9IE1hdGguZmxvb3IoTWF0aC5tYXgoK3Nsb3csIDApKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgYXR0ZW1wdCBjb3VudC4gYDBgIG1lYW5zIGluaGVyaXQgdGhlIHBhcmVudCdzLlxuICAgICAqL1xuICAgIGdldCBhdHRlbXB0cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuXy5yb290LmN1cnJlbnQuYXR0ZW1wdHNcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBudW1iZXIgb2YgYXR0ZW1wdHMgYWxsb3dlZCwgcm91bmRpbmcgbmVnYXRpdmVzIHRvIDAuIFNldHRpbmcgdGhlXG4gICAgICogY291bnQgdG8gYDBgIG1lYW5zIHRvIGluaGVyaXQgdGhlIHBhcmVudCByZXRyeSBjb3VudC5cbiAgICAgKi9cbiAgICBzZXQgYXR0ZW1wdHMoYXR0ZW1wdHMpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBkb25lIGRpZmZlcmVudGx5IHRvIGF2b2lkIGEgbWFzc2l2ZSBwZXJmb3JtYW5jZSBwZW5hbHR5LlxuICAgICAgICB2YXIgY2FsY3VsYXRlZCA9IE1hdGguZmxvb3IoTWF0aC5tYXgoYXR0ZW1wdHMsIDApKVxuICAgICAgICB2YXIgdGVzdCA9IHRoaXMuXy5yb290LmN1cnJlbnRcblxuICAgICAgICB0ZXN0LmF0dGVtcHRzID0gY2FsY3VsYXRlZCB8fCB0ZXN0LnBhcmVudC5hdHRlbXB0c1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgd2hldGhlciB0aGlzIHRlc3QgaXMgZmFpbGFibGUuXG4gICAgICovXG4gICAgZ2V0IGlzRmFpbGFibGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8ucm9vdC5jdXJyZW50LmlzRmFpbGFibGVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHdoZXRoZXIgdGhpcyB0ZXN0IGlzIGZhaWxhYmxlLlxuICAgICAqL1xuICAgIHNldCBpc0ZhaWxhYmxlKGlzRmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5fLnJvb3QuY3VycmVudC5pc0ZhaWxhYmxlID0gISFpc0ZhaWxhYmxlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFJ1biB0aGUgdGVzdHMgKG9yIHRoZSB0ZXN0J3MgdGVzdHMgaWYgaXQncyBub3QgYSBiYXNlIGluc3RhbmNlKS5cbiAgICAgKi9cbiAgICBydW46IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgICAgIGlmICh0aGlzLl8ucm9vdCAhPT0gdGhpcy5fKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJPbmx5IHRoZSByb290IHRlc3QgY2FuIGJlIHJ1biAtIElmIHlvdSBvbmx5IHdhbnQgdG8gcnVuIGEgXCIgK1xuICAgICAgICAgICAgICAgIFwic3VidGVzdCwgdXNlIGB0Lm9ubHkoW1xcXCJzZWxlY3RvcjFcXFwiLCAuLi5dKWAgaW5zdGVhZC5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl8ubG9ja2VkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCBydW4gd2hpbGUgdGVzdHMgYXJlIGFscmVhZHkgcnVubmluZy5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBUZXN0cy5ydW5UZXN0KHRoaXMuXywgb3B0cylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgdGVzdC5cbiAgICAgKi9cbiAgICB0ZXN0OiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYG5hbWVgIHRvIGJlIGEgc3RyaW5nXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgVGVzdHMuYWRkTm9ybWFsKHRoaXMuXy5yb290LmN1cnJlbnQsIG5hbWUsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBza2lwcGVkIHRlc3QuXG4gICAgICovXG4gICAgdGVzdFNraXA6IGZ1bmN0aW9uIChuYW1lLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBgbmFtZWAgdG8gYmUgYSBzdHJpbmdcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICBUZXN0cy5hZGRTa2lwcGVkKHRoaXMuXy5yb290LmN1cnJlbnQsIG5hbWUpXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENsZWFyIGFsbCBleGlzdGluZyB0ZXN0cy5cbiAgICAgKi9cbiAgICBjbGVhclRlc3RzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLl8ucm9vdCAhPT0gdGhpcy5fKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0cyBtYXkgb25seSBiZSBjbGVhcmVkIGF0IHRoZSByb290LlwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuXy5sb2NrZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IGNsZWFyIHRlc3RzIHdoaWxlIHRoZXkgYXJlIHJ1bm5pbmcuXCIpXG4gICAgICAgIH1cblxuICAgICAgICBUZXN0cy5jbGVhclRlc3RzKHRoaXMuXylcbiAgICB9LFxuXG4gICAgYmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0ZXN0ID0gdGhpcy5fLnJvb3QuY3VycmVudFxuXG4gICAgICAgIHRlc3QuYmVmb3JlRWFjaCA9IENvbW1vbi5hZGRIb29rKHRlc3QuYmVmb3JlRWFjaCwgY2FsbGJhY2spXG4gICAgfSxcblxuICAgIGJlZm9yZUFsbDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdGVzdCA9IHRoaXMuXy5yb290LmN1cnJlbnRcblxuICAgICAgICB0ZXN0LmJlZm9yZUFsbCA9IENvbW1vbi5hZGRIb29rKHRlc3QuYmVmb3JlQWxsLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgYWZ0ZXI6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHRlc3QgPSB0aGlzLl8ucm9vdC5jdXJyZW50XG5cbiAgICAgICAgdGVzdC5hZnRlckVhY2ggPSBDb21tb24uYWRkSG9vayh0ZXN0LmFmdGVyRWFjaCwgY2FsbGJhY2spXG4gICAgfSxcblxuICAgIGFmdGVyQWxsOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0ZXN0ID0gdGhpcy5fLnJvb3QuY3VycmVudFxuXG4gICAgICAgIHRlc3QuYWZ0ZXJBbGwgPSBDb21tb24uYWRkSG9vayh0ZXN0LmFmdGVyQWxsLCBjYWxsYmFjaylcbiAgICB9LFxufSlcbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogVGhpcyBpcyB0aGUgZW50cnkgcG9pbnQgZm9yIHRoZSBCcm93c2VyaWZ5IGJ1bmRsZS4gTm90ZSB0aGF0IGl0ICphbHNvKiB3aWxsXG4gKiBydW4gYXMgcGFydCBvZiB0aGUgdGVzdHMgaW4gTm9kZSAodW5idW5kbGVkKSwgYW5kIGl0IHRoZW9yZXRpY2FsbHkgY291bGQgYmVcbiAqIHJ1biBpbiBOb2RlIG9yIGEgcnVudGltZSBsaW1pdGVkIHRvIG9ubHkgRVM1IHN1cHBvcnQgKGUuZy4gUmhpbm8sIE5hc2hvcm4sIG9yXG4gKiBlbWJlZGRlZCBWOCksIHNvIGRvICpub3QqIGFzc3VtZSBicm93c2VyIGdsb2JhbHMgYXJlIHByZXNlbnQuXG4gKi9cblxuZXhwb3J0cy50ID0gcmVxdWlyZShcIi4uL2luZGV4XCIpXG5leHBvcnRzLmFzc2VydCA9IHJlcXVpcmUoXCIuLi9hc3NlcnRcIilcbmV4cG9ydHMuciA9IHJlcXVpcmUoXCIuLi9yXCIpXG52YXIgZG9tID0gcmVxdWlyZShcIi4uL2RvbVwiKVxuXG5leHBvcnRzLmRvbSA9IGRvbS5jcmVhdGVcbi8vIGlmIChnbG9iYWwuZG9jdW1lbnQgIT0gbnVsbCAmJiBnbG9iYWwuZG9jdW1lbnQuY3VycmVudFNjcmlwdCAhPSBudWxsKSB7XG4vLyAgICAgZG9tLmF1dG9sb2FkKGdsb2JhbC5kb2N1bWVudC5jdXJyZW50U2NyaXB0KVxuLy8gfVxuXG52YXIgSW50ZXJuYWwgPSByZXF1aXJlKFwiLi4vaW50ZXJuYWxcIilcblxuZXhwb3J0cy5yb290ID0gSW50ZXJuYWwucm9vdFxuZXhwb3J0cy5yZXBvcnRzID0gSW50ZXJuYWwucmVwb3J0c1xuZXhwb3J0cy5ob29rRXJyb3JzID0gSW50ZXJuYWwuaG9va0Vycm9yc1xuZXhwb3J0cy5sb2NhdGlvbiA9IEludGVybmFsLmxvY2F0aW9uXG5cbi8vIEluIGNhc2UgdGhlIHVzZXIgbmVlZHMgdG8gYWRqdXN0IHRoaXMgKGUuZy4gTmFzaG9ybiArIGNvbnNvbGUgb3V0cHV0KS5cbnZhciBTZXR0aW5ncyA9IHJlcXVpcmUoXCIuL3NldHRpbmdzXCIpXG5cbmV4cG9ydHMuc2V0dGluZ3MgPSB7XG4gICAgd2luZG93V2lkdGg6IHtcbiAgICAgICAgZ2V0OiBTZXR0aW5ncy53aW5kb3dXaWR0aCxcbiAgICAgICAgc2V0OiBTZXR0aW5ncy5zZXRXaW5kb3dXaWR0aCxcbiAgICB9LFxuXG4gICAgbmV3bGluZToge1xuICAgICAgICBnZXQ6IFNldHRpbmdzLm5ld2xpbmUsXG4gICAgICAgIHNldDogU2V0dGluZ3Muc2V0TmV3bGluZSxcbiAgICB9LFxuXG4gICAgc3ltYm9sczoge1xuICAgICAgICBnZXQ6IFNldHRpbmdzLnN5bWJvbHMsXG4gICAgICAgIHNldDogU2V0dGluZ3Muc2V0U3ltYm9scyxcbiAgICB9LFxuXG4gICAgZGVmYXVsdE9wdHM6IHtcbiAgICAgICAgZ2V0OiBTZXR0aW5ncy5kZWZhdWx0T3B0cyxcbiAgICAgICAgc2V0OiBTZXR0aW5ncy5zZXREZWZhdWx0T3B0cyxcbiAgICB9LFxuXG4gICAgY29sb3JTdXBwb3J0OiB7XG4gICAgICAgIGdldDogU2V0dGluZ3MuQ29sb3JzLmdldFN1cHBvcnQsXG4gICAgICAgIHNldDogU2V0dGluZ3MuQ29sb3JzLnNldFN1cHBvcnQsXG4gICAgfSxcbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogVGhlIGZpbHRlciBpcyBhY3R1YWxseSBzdG9yZWQgYXMgYSB0cmVlIGZvciBmYXN0ZXIgbG9va3VwIHRpbWVzIHdoZW4gdGhlcmVcbiAqIGFyZSBtdWx0aXBsZSBzZWxlY3RvcnMuIE9iamVjdHMgY2FuJ3QgYmUgdXNlZCBmb3IgdGhlIG5vZGVzLCB3aGVyZSBrZXlzXG4gKiByZXByZXNlbnQgdmFsdWVzIGFuZCB2YWx1ZXMgcmVwcmVzZW50IGNoaWxkcmVuLCBiZWNhdXNlIHJlZ3VsYXIgZXhwcmVzc2lvbnNcbiAqIGFyZW4ndCBwb3NzaWJsZSB0byB1c2UuXG4gKi9cblxuZnVuY3Rpb24gaXNFcXVpdmFsZW50KGVudHJ5LCBpdGVtKSB7XG4gICAgaWYgKHR5cGVvZiBlbnRyeSA9PT0gXCJzdHJpbmdcIiAmJiB0eXBlb2YgaXRlbSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICByZXR1cm4gZW50cnkgPT09IGl0ZW1cbiAgICB9IGVsc2UgaWYgKGVudHJ5IGluc3RhbmNlb2YgUmVnRXhwICYmIGl0ZW0gaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgcmV0dXJuIGVudHJ5LnRvU3RyaW5nKCkgPT09IGl0ZW0udG9TdHJpbmcoKVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbn1cblxuZnVuY3Rpb24gbWF0Y2hlcyhlbnRyeSwgaXRlbSkge1xuICAgIGlmICh0eXBlb2YgZW50cnkgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIGVudHJ5ID09PSBpdGVtXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGVudHJ5LnRlc3QoaXRlbSlcbiAgICB9XG59XG5cbmZ1bmN0aW9uIEZpbHRlcih2YWx1ZSkge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZVxuICAgIHRoaXMuY2hpbGRyZW4gPSB1bmRlZmluZWRcbn1cblxuZnVuY3Rpb24gZmluZEVxdWl2YWxlbnQobm9kZSwgZW50cnkpIHtcbiAgICBpZiAobm9kZS5jaGlsZHJlbiA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZHJlbltpXVxuXG4gICAgICAgIGlmIChpc0VxdWl2YWxlbnQoY2hpbGQudmFsdWUsIGVudHJ5KSkgcmV0dXJuIGNoaWxkXG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBmaW5kTWF0Y2hlcyhub2RlLCBlbnRyeSkge1xuICAgIGlmIChub2RlLmNoaWxkcmVuID09IG51bGwpIHJldHVybiB1bmRlZmluZWRcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY2hpbGQgPSBub2RlLmNoaWxkcmVuW2ldXG5cbiAgICAgICAgaWYgKG1hdGNoZXMoY2hpbGQudmFsdWUsIGVudHJ5KSkgcmV0dXJuIGNoaWxkXG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIENyZWF0ZSBhIGZpbHRlciBmcm9tIGEgbnVtYmVyIG9mIHNlbGVjdG9yc1xuICovXG5leHBvcnRzLmNyZWF0ZSA9IGZ1bmN0aW9uICgvKiAuLi5zZWxlY3RvcnMgKi8pIHtcbiAgICB2YXIgZmlsdGVyID0gbmV3IEZpbHRlcigpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgc2VsZWN0b3IgPSBhcmd1bWVudHNbaV1cblxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2VsZWN0b3IpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgICAgIFwiRXhwZWN0ZWQgc2VsZWN0b3IgXCIgKyBpICsgXCIgdG8gYmUgYW4gYXJyYXlcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGZpbHRlckFkZFNpbmdsZShmaWx0ZXIsIHNlbGVjdG9yLCBpKVxuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXJcbn1cblxuZnVuY3Rpb24gZmlsdGVyQWRkU2luZ2xlKG5vZGUsIHNlbGVjdG9yLCBpbmRleCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsZWN0b3IubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gc2VsZWN0b3JbaV1cblxuICAgICAgICAvLyBTdHJpbmdzIGFuZCByZWd1bGFyIGV4cHJlc3Npb25zIGFyZSB0aGUgb25seSB0aGluZ3MgYWxsb3dlZC5cbiAgICAgICAgaWYgKHR5cGVvZiBlbnRyeSAhPT0gXCJzdHJpbmdcIiAmJiAhKGVudHJ5IGluc3RhbmNlb2YgUmVnRXhwKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgICAgICBcIlNlbGVjdG9yIFwiICsgaW5kZXggKyBcIiBtdXN0IGNvbnNpc3Qgb2Ygb25seSBzdHJpbmdzIGFuZC9vciBcIiArXG4gICAgICAgICAgICAgICAgXCJyZWd1bGFyIGV4cHJlc3Npb25zXCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2hpbGQgPSBmaW5kRXF1aXZhbGVudChub2RlLCBlbnRyeSlcblxuICAgICAgICBpZiAoY2hpbGQgPT0gbnVsbCkge1xuICAgICAgICAgICAgY2hpbGQgPSBuZXcgRmlsdGVyKGVudHJ5KVxuICAgICAgICAgICAgaWYgKG5vZGUuY2hpbGRyZW4gPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4gPSBbY2hpbGRdXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4ucHVzaChjaGlsZClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIG5vZGUgPSBjaGlsZFxuICAgIH1cbn1cblxuZXhwb3J0cy50ZXN0ID0gZnVuY3Rpb24gKGZpbHRlciwgcGF0aCkge1xuICAgIHZhciBsZW5ndGggPSBwYXRoLmxlbmd0aFxuXG4gICAgd2hpbGUgKGxlbmd0aCAhPT0gMCkge1xuICAgICAgICBmaWx0ZXIgPSBmaW5kTWF0Y2hlcyhmaWx0ZXIsIHBhdGhbLS1sZW5ndGhdKVxuICAgICAgICBpZiAoZmlsdGVyID09IG51bGwpIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgbWV0aG9kcyA9IHJlcXVpcmUoXCIuLi9tZXRob2RzXCIpXG5cbi8qKlxuICogQWxsIHRoZSByZXBvcnQgdHlwZXMuIFRoZSBvbmx5IHJlYXNvbiB0aGVyZSBhcmUgbW9yZSB0aGFuIHR3byB0eXBlcyAobm9ybWFsXG4gKiBhbmQgaG9vaykgaXMgZm9yIHRoZSB1c2VyJ3MgYmVuZWZpdCAoZGV2IHRvb2xzLCBgdXRpbC5pbnNwZWN0YCwgZXRjLilcbiAqL1xuXG52YXIgVHlwZXMgPSBleHBvcnRzLlR5cGVzID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgU3RhcnQ6IDAsXG4gICAgRW50ZXI6IDEsXG4gICAgTGVhdmU6IDIsXG4gICAgUGFzczogMyxcbiAgICBGYWlsOiA0LFxuICAgIFNraXA6IDUsXG4gICAgRW5kOiA2LFxuICAgIEVycm9yOiA3LFxuXG4gICAgLy8gTm90ZSB0aGF0IGBIb29rYCBpcyBkZW5vdGVkIGJ5IHRoZSA0dGggYml0IHNldCwgdG8gc2F2ZSBzb21lIHNwYWNlIChhbmRcbiAgICAvLyB0byBzaW1wbGlmeSB0aGUgdHlwZSByZXByZXNlbnRhdGlvbikuXG4gICAgSG9vazogOCxcbiAgICBCZWZvcmVBbGw6IDggfCAwLFxuICAgIEJlZm9yZUVhY2g6IDggfCAxLFxuICAgIEFmdGVyRWFjaDogOCB8IDIsXG4gICAgQWZ0ZXJBbGw6IDggfCAzLFxufSlcblxuZXhwb3J0cy5SZXBvcnQgPSBSZXBvcnRcbmZ1bmN0aW9uIFJlcG9ydCh0eXBlKSB7XG4gICAgdGhpcy5fID0gdHlwZVxufVxuXG4vLyBBdm9pZCBhIHJlY3Vyc2l2ZSBjYWxsIHdoZW4gYGluc3BlY3RgaW5nIGEgcmVzdWx0IHdoaWxlIHN0aWxsIGtlZXBpbmcgaXRcbi8vIHN0eWxlZCBsaWtlIGl0IHdvdWxkIGJlIG5vcm1hbGx5LiBFYWNoIHR5cGUgdXNlcyBhIG5hbWVkIHNpbmdsZXRvbiBmYWN0b3J5IHRvXG4vLyBlbnN1cmUgZW5naW5lcyBzaG93IHRoZSBjb3JyZWN0IGBuYW1lYC9gZGlzcGxheU5hbWVgIGZvciB0aGUgdHlwZS5cbmZ1bmN0aW9uIGluaXRJbnNwZWN0KGluc3BlY3QsIHJlcG9ydCkge1xuICAgIHZhciB0eXBlID0gcmVwb3J0Ll9cblxuICAgIGlmICh0eXBlICYgVHlwZXMuSG9vaykge1xuICAgICAgICBpbnNwZWN0LnN0YWdlID0gcmVwb3J0LnN0YWdlXG4gICAgfVxuXG4gICAgaWYgKHR5cGUgIT09IFR5cGVzLlN0YXJ0ICYmXG4gICAgICAgICAgICB0eXBlICE9PSBUeXBlcy5FbmQgJiZcbiAgICAgICAgICAgIHR5cGUgIT09IFR5cGVzLkVycm9yKSB7XG4gICAgICAgIGluc3BlY3QucGF0aCA9IHJlcG9ydC5wYXRoXG4gICAgfVxuXG4gICAgaWYgKHR5cGUgJiBUeXBlcy5Ib29rKSB7XG4gICAgICAgIGluc3BlY3Qucm9vdFBhdGggPSByZXBvcnQucm9vdFBhdGhcbiAgICB9XG5cbiAgICAvLyBPbmx5IGFkZCB0aGUgcmVsZXZhbnQgcHJvcGVydGllc1xuICAgIGlmICh0eXBlID09PSBUeXBlcy5GYWlsIHx8XG4gICAgICAgICAgICB0eXBlID09PSBUeXBlcy5FcnJvciB8fFxuICAgICAgICAgICAgdHlwZSAmIFR5cGVzLkhvb2spIHtcbiAgICAgICAgaW5zcGVjdC52YWx1ZSA9IHJlcG9ydC52YWx1ZVxuICAgIH1cblxuICAgIGlmICh0eXBlID09PSBUeXBlcy5FbnRlciB8fFxuICAgICAgICAgICAgdHlwZSA9PT0gVHlwZXMuUGFzcyB8fFxuICAgICAgICAgICAgdHlwZSA9PT0gVHlwZXMuRmFpbCkge1xuICAgICAgICBpbnNwZWN0LmR1cmF0aW9uID0gcmVwb3J0LmR1cmF0aW9uXG4gICAgICAgIGluc3BlY3Quc2xvdyA9IHJlcG9ydC5zbG93XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09IFR5cGVzLkZhaWwpIHtcbiAgICAgICAgaW5zcGVjdC5pc0ZhaWxhYmxlID0gcmVwb3J0LmlzRmFpbGFibGVcbiAgICB9XG59XG5cbm1ldGhvZHMoUmVwb3J0LCB7XG4gICAgLy8gVGhlIHJlcG9ydCB0eXBlc1xuICAgIGdldCBpc1N0YXJ0KCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5TdGFydCB9LFxuICAgIGdldCBpc0VudGVyKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5FbnRlciB9LFxuICAgIGdldCBpc0xlYXZlKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5MZWF2ZSB9LFxuICAgIGdldCBpc1Bhc3MoKSB7IHJldHVybiB0aGlzLl8gPT09IFR5cGVzLlBhc3MgfSxcbiAgICBnZXQgaXNGYWlsKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5GYWlsIH0sXG4gICAgZ2V0IGlzU2tpcCgpIHsgcmV0dXJuIHRoaXMuXyA9PT0gVHlwZXMuU2tpcCB9LFxuICAgIGdldCBpc0VuZCgpIHsgcmV0dXJuIHRoaXMuXyA9PT0gVHlwZXMuRW5kIH0sXG4gICAgZ2V0IGlzRXJyb3IoKSB7IHJldHVybiB0aGlzLl8gPT09IFR5cGVzLkVycm9yIH0sXG4gICAgZ2V0IGlzSG9vaygpIHsgcmV0dXJuICh0aGlzLl8gJiBUeXBlcy5Ib29rKSAhPT0gMCB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IGEgc3RyaW5naWZpZWQgZGVzY3JpcHRpb24gb2YgdGhlIHR5cGUuXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHN3aXRjaCAodGhpcy5fKSB7XG4gICAgICAgIGNhc2UgVHlwZXMuU3RhcnQ6IHJldHVybiBcInN0YXJ0XCJcbiAgICAgICAgY2FzZSBUeXBlcy5FbnRlcjogcmV0dXJuIFwiZW50ZXJcIlxuICAgICAgICBjYXNlIFR5cGVzLkxlYXZlOiByZXR1cm4gXCJsZWF2ZVwiXG4gICAgICAgIGNhc2UgVHlwZXMuUGFzczogcmV0dXJuIFwicGFzc1wiXG4gICAgICAgIGNhc2UgVHlwZXMuRmFpbDogcmV0dXJuIFwiZmFpbFwiXG4gICAgICAgIGNhc2UgVHlwZXMuU2tpcDogcmV0dXJuIFwic2tpcFwiXG4gICAgICAgIGNhc2UgVHlwZXMuRW5kOiByZXR1cm4gXCJlbmRcIlxuICAgICAgICBjYXNlIFR5cGVzLkVycm9yOiByZXR1cm4gXCJlcnJvclwiXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAodGhpcy5fICYgVHlwZXMuSG9vaykgcmV0dXJuIFwiaG9va1wiXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnJlYWNoYWJsZVwiKVxuICAgICAgICB9XG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuU3RhcnQgPSBTdGFydFJlcG9ydFxuZnVuY3Rpb24gU3RhcnRSZXBvcnQoKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuU3RhcnQpXG59XG5tZXRob2RzKFN0YXJ0UmVwb3J0LCBSZXBvcnQsIHtcbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gUmVwb3J0KHJlcG9ydCkge1xuICAgICAgICAgICAgaW5pdEluc3BlY3QodGhpcywgcmVwb3J0KVxuICAgICAgICB9KHRoaXMpXG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuRW50ZXIgPSBFbnRlclJlcG9ydFxuZnVuY3Rpb24gRW50ZXJSZXBvcnQocGF0aCwgZHVyYXRpb24sIHNsb3cpIHtcbiAgICBSZXBvcnQuY2FsbCh0aGlzLCBUeXBlcy5FbnRlcilcbiAgICB0aGlzLnBhdGggPSBwYXRoXG4gICAgdGhpcy5kdXJhdGlvbiA9IGR1cmF0aW9uXG4gICAgdGhpcy5zbG93ID0gc2xvd1xufVxubWV0aG9kcyhFbnRlclJlcG9ydCwgUmVwb3J0LCB7XG4gICAgLyoqXG4gICAgICogU28gdXRpbC5pbnNwZWN0IHByb3ZpZGVzIG1vcmUgc2Vuc2libGUgb3V0cHV0IGZvciB0ZXN0aW5nL2V0Yy5cbiAgICAgKi9cbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gRW50ZXJSZXBvcnQocmVwb3J0KSB7XG4gICAgICAgICAgICBpbml0SW5zcGVjdCh0aGlzLCByZXBvcnQpXG4gICAgICAgIH0odGhpcylcbiAgICB9LFxufSlcblxuZXhwb3J0cy5MZWF2ZSA9IExlYXZlUmVwb3J0XG5mdW5jdGlvbiBMZWF2ZVJlcG9ydChwYXRoKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuTGVhdmUpXG4gICAgdGhpcy5wYXRoID0gcGF0aFxufVxubWV0aG9kcyhMZWF2ZVJlcG9ydCwgUmVwb3J0LCB7XG4gICAgLyoqXG4gICAgICogU28gdXRpbC5pbnNwZWN0IHByb3ZpZGVzIG1vcmUgc2Vuc2libGUgb3V0cHV0IGZvciB0ZXN0aW5nL2V0Yy5cbiAgICAgKi9cbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gTGVhdmVSZXBvcnQocmVwb3J0KSB7XG4gICAgICAgICAgICBpbml0SW5zcGVjdCh0aGlzLCByZXBvcnQpXG4gICAgICAgIH0odGhpcylcbiAgICB9LFxufSlcblxuZXhwb3J0cy5QYXNzID0gUGFzc1JlcG9ydFxuZnVuY3Rpb24gUGFzc1JlcG9ydChwYXRoLCBkdXJhdGlvbiwgc2xvdykge1xuICAgIFJlcG9ydC5jYWxsKHRoaXMsIFR5cGVzLlBhc3MpXG4gICAgdGhpcy5wYXRoID0gcGF0aFxuICAgIHRoaXMuZHVyYXRpb24gPSBkdXJhdGlvblxuICAgIHRoaXMuc2xvdyA9IHNsb3dcbn1cbm1ldGhvZHMoUGFzc1JlcG9ydCwgUmVwb3J0LCB7XG4gICAgLyoqXG4gICAgICogU28gdXRpbC5pbnNwZWN0IHByb3ZpZGVzIG1vcmUgc2Vuc2libGUgb3V0cHV0IGZvciB0ZXN0aW5nL2V0Yy5cbiAgICAgKi9cbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gUGFzc1JlcG9ydChyZXBvcnQpIHtcbiAgICAgICAgICAgIGluaXRJbnNwZWN0KHRoaXMsIHJlcG9ydClcbiAgICAgICAgfSh0aGlzKVxuICAgIH0sXG59KVxuXG5leHBvcnRzLkZhaWwgPSBGYWlsUmVwb3J0XG5mdW5jdGlvbiBGYWlsUmVwb3J0KHBhdGgsIGVycm9yLCBkdXJhdGlvbiwgc2xvdywgaXNGYWlsYWJsZSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICBSZXBvcnQuY2FsbCh0aGlzLCBUeXBlcy5GYWlsKVxuICAgIHRoaXMucGF0aCA9IHBhdGhcbiAgICB0aGlzLmVycm9yID0gZXJyb3JcbiAgICB0aGlzLmR1cmF0aW9uID0gZHVyYXRpb25cbiAgICB0aGlzLnNsb3cgPSBzbG93XG4gICAgdGhpcy5pc0ZhaWxhYmxlID0gaXNGYWlsYWJsZVxufVxubWV0aG9kcyhGYWlsUmVwb3J0LCBSZXBvcnQsIHtcbiAgICAvKipcbiAgICAgKiBTbyB1dGlsLmluc3BlY3QgcHJvdmlkZXMgbW9yZSBzZW5zaWJsZSBvdXRwdXQgZm9yIHRlc3RpbmcvZXRjLlxuICAgICAqL1xuICAgIGluc3BlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBmdW5jdGlvbiBGYWlsUmVwb3J0KHJlcG9ydCkge1xuICAgICAgICAgICAgaW5pdEluc3BlY3QodGhpcywgcmVwb3J0KVxuICAgICAgICB9KHRoaXMpXG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuU2tpcCA9IFNraXBSZXBvcnRcbmZ1bmN0aW9uIFNraXBSZXBvcnQocGF0aCkge1xuICAgIFJlcG9ydC5jYWxsKHRoaXMsIFR5cGVzLlNraXApXG4gICAgdGhpcy5wYXRoID0gcGF0aFxufVxubWV0aG9kcyhTa2lwUmVwb3J0LCBSZXBvcnQsIHtcbiAgICAvKipcbiAgICAgKiBTbyB1dGlsLmluc3BlY3QgcHJvdmlkZXMgbW9yZSBzZW5zaWJsZSBvdXRwdXQgZm9yIHRlc3RpbmcvZXRjLlxuICAgICAqL1xuICAgIGluc3BlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBmdW5jdGlvbiBTa2lwUmVwb3J0KHJlcG9ydCkge1xuICAgICAgICAgICAgaW5pdEluc3BlY3QodGhpcywgcmVwb3J0KVxuICAgICAgICB9KHRoaXMpXG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuRW5kID0gRW5kUmVwb3J0XG5mdW5jdGlvbiBFbmRSZXBvcnQoKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuRW5kKVxufVxubWV0aG9kcyhFbmRSZXBvcnQsIFJlcG9ydCwge1xuICAgIC8qKlxuICAgICAqIFNvIHV0aWwuaW5zcGVjdCBwcm92aWRlcyBtb3JlIHNlbnNpYmxlIG91dHB1dCBmb3IgdGVzdGluZy9ldGMuXG4gICAgICovXG4gICAgaW5zcGVjdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IGZ1bmN0aW9uIEVuZFJlcG9ydChyZXBvcnQpIHtcbiAgICAgICAgICAgIGluaXRJbnNwZWN0KHRoaXMsIHJlcG9ydClcbiAgICAgICAgfSh0aGlzKVxuICAgIH0sXG59KVxuXG5leHBvcnRzLkVycm9yID0gRXJyb3JSZXBvcnRcbmZ1bmN0aW9uIEVycm9yUmVwb3J0KGVycm9yKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuRXJyb3IpXG4gICAgdGhpcy5lcnJvciA9IGVycm9yXG59XG5tZXRob2RzKEVycm9yUmVwb3J0LCBSZXBvcnQsIHtcbiAgICAvKipcbiAgICAgKiBTbyB1dGlsLmluc3BlY3QgcHJvdmlkZXMgbW9yZSBzZW5zaWJsZSBvdXRwdXQgZm9yIHRlc3RpbmcvZXRjLlxuICAgICAqL1xuICAgIGluc3BlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBmdW5jdGlvbiBFcnJvclJlcG9ydChyZXBvcnQpIHtcbiAgICAgICAgICAgIGluaXRJbnNwZWN0KHRoaXMsIHJlcG9ydClcbiAgICAgICAgfSh0aGlzKVxuICAgIH0sXG59KVxuXG52YXIgSG9va01ldGhvZHMgPSB7XG4gICAgZ2V0IHN0YWdlKCkge1xuICAgICAgICBzd2l0Y2ggKHRoaXMuXykge1xuICAgICAgICBjYXNlIFR5cGVzLkJlZm9yZUFsbDogcmV0dXJuIFwiYmVmb3JlIGFsbFwiXG4gICAgICAgIGNhc2UgVHlwZXMuQmVmb3JlRWFjaDogcmV0dXJuIFwiYmVmb3JlIGVhY2hcIlxuICAgICAgICBjYXNlIFR5cGVzLkFmdGVyRWFjaDogcmV0dXJuIFwiYWZ0ZXIgZWFjaFwiXG4gICAgICAgIGNhc2UgVHlwZXMuQWZ0ZXJBbGw6IHJldHVybiBcImFmdGVyIGFsbFwiXG4gICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcihcInVucmVhY2hhYmxlXCIpXG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgZ2V0IGlzQmVmb3JlQWxsKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5CZWZvcmVBbGwgfSxcbiAgICBnZXQgaXNCZWZvcmVFYWNoKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5CZWZvcmVFYWNoIH0sXG4gICAgZ2V0IGlzQWZ0ZXJFYWNoKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5BZnRlckVhY2ggfSxcbiAgICBnZXQgaXNBZnRlckFsbCgpIHsgcmV0dXJuIHRoaXMuXyA9PT0gVHlwZXMuQWZ0ZXJBbGwgfSxcbn1cblxuZXhwb3J0cy5Ib29rRXJyb3IgPSBIb29rRXJyb3JcbmZ1bmN0aW9uIEhvb2tFcnJvcihzdGFnZSwgZnVuYywgZXJyb3IpIHtcbiAgICB0aGlzLl8gPSBzdGFnZVxuICAgIHRoaXMubmFtZSA9IGZ1bmMubmFtZSB8fCBmdW5jLmRpc3BsYXlOYW1lIHx8IFwiXCJcbiAgICB0aGlzLmVycm9yID0gZXJyb3Jcbn1cbm1ldGhvZHMoSG9va0Vycm9yLCBIb29rTWV0aG9kcylcblxuZXhwb3J0cy5Ib29rID0gSG9va1JlcG9ydFxuZnVuY3Rpb24gSG9va1JlcG9ydChwYXRoLCByb290UGF0aCwgaG9va0Vycm9yKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgaG9va0Vycm9yLl8pXG4gICAgdGhpcy5wYXRoID0gcGF0aFxuICAgIHRoaXMucm9vdFBhdGggPSByb290UGF0aFxuICAgIHRoaXMubmFtZSA9IGhvb2tFcnJvci5uYW1lXG4gICAgdGhpcy5lcnJvciA9IGhvb2tFcnJvci5lcnJvclxufVxubWV0aG9kcyhIb29rUmVwb3J0LCBSZXBvcnQsIEhvb2tNZXRob2RzLCB7XG4gICAgZ2V0IGhvb2tFcnJvcigpIHsgcmV0dXJuIG5ldyBIb29rRXJyb3IodGhpcy5fLCB0aGlzLCB0aGlzLmVycm9yKSB9LFxufSlcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcbnZhciBwZWFjaCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpLnBlYWNoXG52YXIgUmVwb3J0cyA9IHJlcXVpcmUoXCIuL3JlcG9ydHNcIilcbnZhciBGaWx0ZXIgPSByZXF1aXJlKFwiLi9maWx0ZXJcIilcbnZhciBUeXBlcyA9IFJlcG9ydHMuVHlwZXNcblxuLyoqXG4gKiBUaGUgdGVzdHMgYXJlIGxhaWQgb3V0IGluIGEgdmVyeSBkYXRhLWRyaXZlbiBkZXNpZ24uIFdpdGggZXhjZXB0aW9uIG9mIHRoZVxuICogcmVwb3J0cywgdGhlcmUgaXMgbWluaW1hbCBvYmplY3Qgb3JpZW50YXRpb24gYW5kIHplcm8gdmlydHVhbCBkaXNwYXRjaC5cbiAqIEhlcmUncyBhIHF1aWNrIG92ZXJ2aWV3OlxuICpcbiAqIC0gVGhlIHRlc3QgaGFuZGxpbmcgZGlzcGF0Y2hlcyBiYXNlZCBvbiB2YXJpb3VzIGF0dHJpYnV0ZXMgdGhlIHRlc3QgaGFzLiBGb3JcbiAqICAgZXhhbXBsZSwgcm9vdHMgYXJlIGtub3duIGJ5IGEgY2lyY3VsYXIgcm9vdCByZWZlcmVuY2UsIGFuZCBza2lwcGVkIHRlc3RzXG4gKiAgIGFyZSBrbm93biBieSBub3QgaGF2aW5nIGEgY2FsbGJhY2suXG4gKlxuICogLSBUaGUgdGVzdCBldmFsdWF0aW9uIGlzIHZlcnkgcHJvY2VkdXJhbC4gQWx0aG91Z2ggaXQncyB2ZXJ5IGhpZ2hseVxuICogICBhc3luY2hyb25vdXMsIHRoZSB1c2Ugb2YgcHJvbWlzZXMgbGluZWFyaXplIHRoZSBsb2dpYywgc28gaXQgcmVhZHMgdmVyeVxuICogICBtdWNoIGxpa2UgYSByZWN1cnNpdmUgc2V0IG9mIHN0ZXBzLlxuICpcbiAqIC0gVGhlIGRhdGEgdHlwZXMgYXJlIG1vc3RseSBlaXRoZXIgcGxhaW4gb2JqZWN0cyBvciBjbGFzc2VzIHdpdGggbm8gbWV0aG9kcyxcbiAqICAgdGhlIGxhdHRlciBtb3N0bHkgZm9yIGRlYnVnZ2luZyBoZWxwLiBUaGlzIGFsc28gYXZvaWRzIG1vc3Qgb2YgdGhlXG4gKiAgIGluZGlyZWN0aW9uIHJlcXVpcmVkIHRvIGFjY29tbW9kYXRlIGJyZWFraW5nIGFic3RyYWN0aW9ucywgd2hpY2ggdGhlIEFQSVxuICogICBtZXRob2RzIGZyZXF1ZW50bHkgbmVlZCB0byBkby5cbiAqL1xuXG4vLyBQcmV2ZW50IFNpbm9uIGludGVyZmVyZW5jZSB3aGVuIHRoZXkgaW5zdGFsbCB0aGVpciBtb2Nrc1xudmFyIHNldFRpbWVvdXQgPSBnbG9iYWwuc2V0VGltZW91dFxudmFyIGNsZWFyVGltZW91dCA9IGdsb2JhbC5jbGVhclRpbWVvdXRcbnZhciBub3cgPSBnbG9iYWwuRGF0ZS5ub3dcblxuLyoqXG4gKiBCYXNpYyBkYXRhIHR5cGVzXG4gKi9cbmZ1bmN0aW9uIFJlc3VsdCh0aW1lLCBhdHRlbXB0KSB7XG4gICAgdGhpcy50aW1lID0gdGltZVxuICAgIHRoaXMuY2F1Z2h0ID0gYXR0ZW1wdC5jYXVnaHRcbiAgICB0aGlzLnZhbHVlID0gYXR0ZW1wdC5jYXVnaHQgPyBhdHRlbXB0LnZhbHVlIDogdW5kZWZpbmVkXG59XG5cbi8qKlxuICogT3ZlcnZpZXcgb2YgdGhlIHRlc3QgcHJvcGVydGllczpcbiAqXG4gKiAtIGBtZXRob2RzYCAtIEEgZGVwcmVjYXRlZCByZWZlcmVuY2UgdG8gdGhlIEFQSSBtZXRob2RzXG4gKiAtIGByb290YCAtIFRoZSByb290IHRlc3RcbiAqIC0gYHJlcG9ydGVyc2AgLSBUaGUgbGlzdCBvZiByZXBvcnRlcnNcbiAqIC0gYGN1cnJlbnRgIC0gQSByZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnRseSBhY3RpdmUgdGVzdFxuICogLSBgdGltZW91dGAgLSBUaGUgdGVzdHMncyB0aW1lb3V0LCBvciAwIGlmIGluaGVyaXRlZFxuICogLSBgc2xvd2AgLSBUaGUgdGVzdHMncyBzbG93IHRocmVzaG9sZFxuICogLSBgbmFtZWAgLSBUaGUgdGVzdCdzIG5hbWVcbiAqIC0gYGluZGV4YCAtIFRoZSB0ZXN0J3MgaW5kZXhcbiAqIC0gYHBhcmVudGAgLSBUaGUgdGVzdCdzIHBhcmVudFxuICogLSBgY2FsbGJhY2tgIC0gVGhlIHRlc3QncyBjYWxsYmFja1xuICogLSBgdGVzdHNgIC0gVGhlIHRlc3QncyBjaGlsZCB0ZXN0c1xuICogLSBgYmVmb3JlQWxsYCwgYGJlZm9yZUVhY2hgLCBgYWZ0ZXJFYWNoYCwgYGFmdGVyQWxsYCAtIFRoZSB0ZXN0J3MgdmFyaW91c1xuICogICBzY2hlZHVsZWQgaG9va3NcbiAqXG4gKiBNYW55IG9mIHRoZXNlIHByb3BlcnRpZXMgYXJlbid0IHByZXNlbnQgb24gaW5pdGlhbGl6YXRpb24gdG8gc2F2ZSBtZW1vcnkuXG4gKi9cblxuLy8gVE9ETzogcmVtb3ZlIGB0ZXN0Lm1ldGhvZHNgIGluIDAuNFxuZnVuY3Rpb24gTm9ybWFsKG5hbWUsIGluZGV4LCBwYXJlbnQsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGNoaWxkID0gT2JqZWN0LmNyZWF0ZShwYXJlbnQubWV0aG9kcylcblxuICAgIGNoaWxkLl8gPSB0aGlzXG4gICAgdGhpcy5tZXRob2RzID0gY2hpbGRcbiAgICB0aGlzLmxvY2tlZCA9IHRydWVcbiAgICB0aGlzLnJvb3QgPSBwYXJlbnQucm9vdFxuICAgIHRoaXMubmFtZSA9IG5hbWVcbiAgICB0aGlzLmluZGV4ID0gaW5kZXh8MFxuICAgIHRoaXMucGFyZW50ID0gcGFyZW50XG4gICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrXG4gICAgdGhpcy5pc0ZhaWxhYmxlID0gcGFyZW50LmlzRmFpbGFibGVcbiAgICB0aGlzLmF0dGVtcHRzID0gcGFyZW50LmF0dGVtcHRzXG5cbiAgICB0aGlzLnRpbWVvdXQgPSAwXG4gICAgdGhpcy5zbG93ID0gMFxuICAgIHRoaXMudGVzdHMgPSB1bmRlZmluZWRcbiAgICB0aGlzLmJlZm9yZUFsbCA9IHVuZGVmaW5lZFxuICAgIHRoaXMuYmVmb3JlRWFjaCA9IHVuZGVmaW5lZFxuICAgIHRoaXMuYWZ0ZXJFYWNoID0gdW5kZWZpbmVkXG4gICAgdGhpcy5hZnRlckFsbCA9IHVuZGVmaW5lZFxuICAgIHRoaXMucmVwb3J0ZXIgPSB1bmRlZmluZWRcbiAgICB0aGlzLnJlZmxlY3QgPSB1bmRlZmluZWRcbn1cblxuZnVuY3Rpb24gU2tpcHBlZChuYW1lLCBpbmRleCwgcGFyZW50KSB7XG4gICAgdGhpcy5sb2NrZWQgPSB0cnVlXG4gICAgdGhpcy5yb290ID0gcGFyZW50LnJvb3RcbiAgICB0aGlzLm5hbWUgPSBuYW1lXG4gICAgdGhpcy5pbmRleCA9IGluZGV4fDBcbiAgICB0aGlzLnBhcmVudCA9IHBhcmVudFxuXG4gICAgLy8gT25seSBmb3IgcmVmbGVjdGlvbi5cbiAgICB0aGlzLmlzRmFpbGFibGUgPSBwYXJlbnQuaXNGYWlsYWJsZVxuICAgIHRoaXMuYXR0ZW1wdHMgPSBwYXJlbnQuYXR0ZW1wdHNcbiAgICB0aGlzLnJlcG9ydGVyID0gdW5kZWZpbmVkXG4gICAgdGhpcy5yZWZsZWN0ID0gdW5kZWZpbmVkXG59XG5cbi8vIFRPRE86IHJlbW92ZSBgdGVzdC5tZXRob2RzYCBpbiAwLjRcbmZ1bmN0aW9uIFJvb3QobWV0aG9kcykge1xuICAgIHRoaXMubG9ja2VkID0gZmFsc2VcbiAgICB0aGlzLm1ldGhvZHMgPSBtZXRob2RzXG4gICAgdGhpcy5yZXBvcnRlcklkcyA9IFtdXG4gICAgdGhpcy5yZXBvcnRlcnMgPSBbXVxuICAgIHRoaXMuY3VycmVudCA9IHRoaXNcbiAgICB0aGlzLnJvb3QgPSB0aGlzXG4gICAgdGhpcy50aW1lb3V0ID0gMFxuICAgIHRoaXMuc2xvdyA9IDBcbiAgICB0aGlzLmF0dGVtcHRzID0gMVxuICAgIHRoaXMuaXNGYWlsYWJsZSA9IGZhbHNlXG5cbiAgICB0aGlzLnRlc3RzID0gdW5kZWZpbmVkXG4gICAgdGhpcy5yZXBvcnRlciA9IHVuZGVmaW5lZFxuICAgIHRoaXMucmVmbGVjdCA9IHVuZGVmaW5lZFxuICAgIHRoaXMuYmVmb3JlQWxsID0gdW5kZWZpbmVkXG4gICAgdGhpcy5iZWZvcmVFYWNoID0gdW5kZWZpbmVkXG4gICAgdGhpcy5hZnRlckVhY2ggPSB1bmRlZmluZWRcbiAgICB0aGlzLmFmdGVyQWxsID0gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIENvbnRleHQocm9vdCkge1xuICAgIHRoaXMucm9vdCA9IHJvb3RcbiAgICB0aGlzLnRlc3RzID0gW11cbiAgICB0aGlzLmlzU3VjY2VzcyA9IHRydWVcbn1cblxuLyoqXG4gKiBCYXNlIHRlc3RzIChpLmUuIGRlZmF1bHQgZXhwb3J0LCByZXN1bHQgb2YgYGludGVybmFsLnJvb3QoKWApLlxuICovXG5cbmV4cG9ydHMuY3JlYXRlUm9vdCA9IGZ1bmN0aW9uIChtZXRob2RzKSB7XG4gICAgcmV0dXJuIG5ldyBSb290KG1ldGhvZHMpXG59XG5cbi8qKlxuICogU2V0IHVwIGVhY2ggdGVzdCB0eXBlLlxuICovXG5cbi8qKlxuICogQSBub3JtYWwgdGVzdCB0aHJvdWdoIGB0LnRlc3QoKWAuXG4gKi9cblxuZXhwb3J0cy5hZGROb3JtYWwgPSBmdW5jdGlvbiAocGFyZW50LCBuYW1lLCBjYWxsYmFjaykge1xuICAgIHZhciBpbmRleCA9IHBhcmVudC50ZXN0cyAhPSBudWxsID8gcGFyZW50LnRlc3RzLmxlbmd0aCA6IDBcbiAgICB2YXIgYmFzZSA9IG5ldyBOb3JtYWwobmFtZSwgaW5kZXgsIHBhcmVudCwgY2FsbGJhY2spXG5cbiAgICBpZiAoaW5kZXgpIHtcbiAgICAgICAgcGFyZW50LnRlc3RzLnB1c2goYmFzZSlcbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXJlbnQudGVzdHMgPSBbYmFzZV1cbiAgICB9XG59XG5cbi8qKlxuICogQSBza2lwcGVkIHRlc3QgdGhyb3VnaCBgdC50ZXN0U2tpcCgpYC5cbiAqL1xuZXhwb3J0cy5hZGRTa2lwcGVkID0gZnVuY3Rpb24gKHBhcmVudCwgbmFtZSkge1xuICAgIHZhciBpbmRleCA9IHBhcmVudC50ZXN0cyAhPSBudWxsID8gcGFyZW50LnRlc3RzLmxlbmd0aCA6IDBcbiAgICB2YXIgYmFzZSA9IG5ldyBTa2lwcGVkKG5hbWUsIGluZGV4LCBwYXJlbnQpXG5cbiAgICBpZiAoaW5kZXgpIHtcbiAgICAgICAgcGFyZW50LnRlc3RzLnB1c2goYmFzZSlcbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXJlbnQudGVzdHMgPSBbYmFzZV1cbiAgICB9XG59XG5cbi8qKlxuICogQ2xlYXIgdGhlIHRlc3RzIGluIHBsYWNlLlxuICovXG5leHBvcnRzLmNsZWFyVGVzdHMgPSBmdW5jdGlvbiAocGFyZW50KSB7XG4gICAgcGFyZW50LnRlc3RzID0gbnVsbFxufVxuXG4vKipcbiAqIEV4ZWN1dGUgdGhlIHRlc3RzXG4gKi9cblxuLy8gVE9ETzogY2FjaGUgYW5kIHJlbW92ZSB0aGVzZSB0cmF2ZXJzYWxzIGZvciAwLjQuXG4vLyBOb3RlIHRoYXQgYSB0aW1lb3V0IG9mIDAgbWVhbnMgdG8gaW5oZXJpdCB0aGUgcGFyZW50LlxuZnVuY3Rpb24gZmluZFRpbWVvdXQodGVzdHMpIHtcbiAgICBmb3IgKHZhciBpID0gdGVzdHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgaWYgKHRlc3RzW2ldLnRpbWVvdXQpIHJldHVybiB0ZXN0c1tpXS50aW1lb3V0XG4gICAgfVxuXG4gICAgcmV0dXJuIDIwMDAgLy8gbXMgLSBkZWZhdWx0IHRpbWVvdXRcbn1cblxuLy8gTm90ZSB0aGF0IGEgc2xvd25lc3MgdGhyZXNob2xkIG9mIDAgbWVhbnMgdG8gaW5oZXJpdCB0aGUgcGFyZW50LlxuZnVuY3Rpb24gZmluZFNsb3codGVzdHMpIHtcbiAgICBmb3IgKHZhciBpID0gdGVzdHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgaWYgKHRlc3RzW2ldLnNsb3cpIHJldHVybiB0ZXN0c1tpXS5zbG93XG4gICAgfVxuXG4gICAgcmV0dXJuIDc1IC8vIG1zIC0gZGVmYXVsdCBzbG93IHRocmVzaG9sZFxufVxuXG5mdW5jdGlvbiBtYWtlU2xpY2UodGVzdHMsIGxlbmd0aCkge1xuICAgIHZhciByZXQgPSBuZXcgQXJyYXkobGVuZ3RoKVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICByZXRbaV0gPSB7bmFtZTogdGVzdHNbaV0ubmFtZSwgaW5kZXg6IHRlc3RzW2ldLmluZGV4fVxuICAgIH1cblxuICAgIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gcmVwb3J0KGNvbnRleHQsIHR5cGUsIGFyZzEsIGFyZzIpIHtcbiAgICBmdW5jdGlvbiBpbnZva2VSZXBvcnRlcihyZXBvcnRlcikge1xuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSBUeXBlcy5TdGFydDpcbiAgICAgICAgICAgIHJldHVybiByZXBvcnRlcihuZXcgUmVwb3J0cy5TdGFydCgpKVxuXG4gICAgICAgIGNhc2UgVHlwZXMuRW50ZXI6XG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0ZXIoXG4gICAgICAgICAgICAgICAgbmV3IFJlcG9ydHMuRW50ZXIoXG4gICAgICAgICAgICAgICAgICAgIG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmxlbmd0aCksIGFyZzEsXG4gICAgICAgICAgICAgICAgICAgIGZpbmRTbG93KGNvbnRleHQudGVzdHMpKSlcblxuICAgICAgICBjYXNlIFR5cGVzLkxlYXZlOlxuICAgICAgICAgICAgcmV0dXJuIHJlcG9ydGVyKG5ldyBSZXBvcnRzLkxlYXZlKFxuICAgICAgICAgICAgICAgIG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmxlbmd0aCkpKVxuXG4gICAgICAgIGNhc2UgVHlwZXMuUGFzczpcbiAgICAgICAgICAgIHJldHVybiByZXBvcnRlcihcbiAgICAgICAgICAgICAgICBuZXcgUmVwb3J0cy5QYXNzKFxuICAgICAgICAgICAgICAgICAgICBtYWtlU2xpY2UoY29udGV4dC50ZXN0cywgY29udGV4dC50ZXN0cy5sZW5ndGgpLCBhcmcxLFxuICAgICAgICAgICAgICAgICAgICBmaW5kU2xvdyhjb250ZXh0LnRlc3RzKSkpXG5cbiAgICAgICAgY2FzZSBUeXBlcy5GYWlsOlxuICAgICAgICAgICAgcmV0dXJuIHJlcG9ydGVyKFxuICAgICAgICAgICAgICAgIG5ldyBSZXBvcnRzLkZhaWwoXG4gICAgICAgICAgICAgICAgICAgIG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmxlbmd0aCksIGFyZzEsIGFyZzIsXG4gICAgICAgICAgICAgICAgICAgIGZpbmRTbG93KGNvbnRleHQudGVzdHMpLFxuICAgICAgICAgICAgICAgICAgICAhIWNvbnRleHQucm9vdC5jdXJyZW50LmlzRmFpbGFibGUpKVxuXG4gICAgICAgIGNhc2UgVHlwZXMuU2tpcDpcbiAgICAgICAgICAgIHJldHVybiByZXBvcnRlcihuZXcgUmVwb3J0cy5Ta2lwKFxuICAgICAgICAgICAgICAgIG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmxlbmd0aCkpKVxuXG4gICAgICAgIGNhc2UgVHlwZXMuRW5kOlxuICAgICAgICAgICAgcmV0dXJuIHJlcG9ydGVyKG5ldyBSZXBvcnRzLkVuZCgpKVxuXG4gICAgICAgIGNhc2UgVHlwZXMuRXJyb3I6XG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0ZXIobmV3IFJlcG9ydHMuRXJyb3IoYXJnMSkpXG5cbiAgICAgICAgY2FzZSBUeXBlcy5Ib29rOlxuICAgICAgICAgICAgLy8gSW5jbHVkZSB0aGUgbGFzdCB0ZXN0LiBUaGlzIGFsc28gaW1wbGljaXRseSBzZXRzIHRoZSBlbmQgdG8gMCBmb3JcbiAgICAgICAgICAgIC8vIHJvb3QgdGVzdHMuXG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0ZXIobmV3IFJlcG9ydHMuSG9vayhcbiAgICAgICAgICAgICAgICBtYWtlU2xpY2UoY29udGV4dC50ZXN0cywgY29udGV4dC50ZXN0cy5sZW5ndGgpLFxuICAgICAgICAgICAgICAgIG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmluZGV4T2YoYXJnMSkgKyAxKSxcbiAgICAgICAgICAgICAgICBhcmcyKSlcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInVucmVhY2hhYmxlXCIpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjb250ZXh0LnJvb3QucmVwb3J0ZXIgPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICByZXR1cm4gaW52b2tlUmVwb3J0ZXIoY29udGV4dC5yb290LnJlcG9ydGVyKVxuICAgIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcmVwb3J0ZXJzID0gY29udGV4dC5yb290LnJlcG9ydGVyc1xuXG4gICAgICAgIC8vIFR3byBlYXN5IGNhc2VzLlxuICAgICAgICBpZiAocmVwb3J0ZXJzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICBpZiAocmVwb3J0ZXJzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGludm9rZVJlcG9ydGVyKHJlcG9ydGVyc1swXSlcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHJlcG9ydGVycy5tYXAoaW52b2tlUmVwb3J0ZXIpKVxuICAgIH0pXG59XG5cbi8qKlxuICogTm9ybWFsIHRlc3RzXG4gKi9cblxuLy8gUGhhbnRvbUpTIGFuZCBJRSBkb24ndCBhZGQgdGhlIHN0YWNrIHVudGlsIGl0J3MgdGhyb3duLiBJbiBmYWlsaW5nIGFzeW5jXG4vLyB0ZXN0cywgaXQncyBhbHJlYWR5IHRocm93biBpbiBhIHNlbnNlLCBzbyB0aGlzIHNob3VsZCBiZSBub3JtYWxpemVkIHdpdGhcbi8vIG90aGVyIHRlc3QgdHlwZXMuXG52YXIgYWRkU3RhY2sgPSB0eXBlb2YgbmV3IEVycm9yKCkuc3RhY2sgIT09IFwic3RyaW5nXCJcbiAgICA/IGZ1bmN0aW9uIGFkZFN0YWNrKGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgRXJyb3IgJiYgZS5zdGFjayA9PSBudWxsKSB0aHJvdyBlXG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICByZXR1cm4gZVxuICAgICAgICB9XG4gICAgfVxuICAgIDogZnVuY3Rpb24gKGUpIHsgcmV0dXJuIGUgfVxuXG5mdW5jdGlvbiBnZXRUaGVuKHJlcykge1xuICAgIGlmICh0eXBlb2YgcmVzID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiByZXMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gcmVzLnRoZW5cbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxufVxuXG5mdW5jdGlvbiBBc3luY1N0YXRlKGNvbnRleHQsIHN0YXJ0LCByZXNvbHZlLCBjb3VudCkge1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHRcbiAgICB0aGlzLnN0YXJ0ID0gc3RhcnRcbiAgICB0aGlzLnJlc29sdmUgPSByZXNvbHZlXG4gICAgdGhpcy5jb3VudCA9IGNvdW50XG4gICAgdGhpcy50aW1lciA9IHVuZGVmaW5lZFxufVxuXG52YXIgcCA9IFByb21pc2UucmVzb2x2ZSgpXG5cbmZ1bmN0aW9uIGFzeW5jRmluaXNoKHN0YXRlLCBhdHRlbXB0KSB7XG4gICAgLy8gQ2FwdHVyZSBpbW1lZGlhdGVseS4gV29yc3QgY2FzZSBzY2VuYXJpbywgaXQgZ2V0cyB0aHJvd24gYXdheS5cbiAgICB2YXIgZW5kID0gbm93KClcblxuICAgIGlmIChzdGF0ZS50aW1lcikge1xuICAgICAgICBjbGVhclRpbWVvdXQuY2FsbChnbG9iYWwsIHN0YXRlLnRpbWVyKVxuICAgICAgICBzdGF0ZS50aW1lciA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmIChhdHRlbXB0LmNhdWdodCAmJiBzdGF0ZS5jb3VudCA8IHN0YXRlLmNvbnRleHQucm9vdC5jdXJyZW50LmF0dGVtcHRzKSB7XG4gICAgICAgIC8vIERvbid0IHJlY3Vyc2Ugc3luY2hyb25vdXNseSwgc2luY2UgaXQgbWF5IGJlIHJlc29sdmVkIHN5bmNocm9ub3VzbHlcbiAgICAgICAgc3RhdGUucmVzb2x2ZShwLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGludm9rZUluaXQoc3RhdGUuY29udGV4dCwgc3RhdGUuY291bnQgKyAxKVxuICAgICAgICB9KSlcbiAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5yZXNvbHZlKG5ldyBSZXN1bHQoZW5kIC0gc3RhdGUuc3RhcnQsIGF0dGVtcHQpKVxuICAgIH1cbn1cblxuLy8gQXZvaWQgY3JlYXRpbmcgYSBjbG9zdXJlIGlmIHBvc3NpYmxlLCBpbiBjYXNlIGl0IGRvZXNuJ3QgcmV0dXJuIGEgdGhlbmFibGUuXG5mdW5jdGlvbiBpbnZva2VJbml0KGNvbnRleHQsIGNvdW50KSB7XG4gICAgdmFyIHRlc3QgPSBjb250ZXh0LnJvb3QuY3VycmVudFxuICAgIHZhciBzdGFydCA9IG5vdygpXG4gICAgdmFyIHRyeUJvZHkgPSB0cnkxKHRlc3QuY2FsbGJhY2ssIHRlc3QubWV0aG9kcywgdGVzdC5tZXRob2RzKVxuICAgIHZhciBzeW5jRW5kID0gbm93KClcblxuICAgIC8vIE5vdGU6IHN5bmNocm9ub3VzIGZhaWx1cmVzIGFyZSB0ZXN0IGZhaWx1cmVzLCBub3QgZmF0YWwgZXJyb3JzLlxuICAgIGlmICh0cnlCb2R5LmNhdWdodCkge1xuICAgICAgICBpZiAoY291bnQgPCB0ZXN0LmF0dGVtcHRzKSByZXR1cm4gaW52b2tlSW5pdChjb250ZXh0LCBjb3VudCArIDEpXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IFJlc3VsdChzeW5jRW5kIC0gc3RhcnQsIHRyeUJvZHkpKVxuICAgIH1cblxuICAgIHZhciB0cnlUaGVuID0gdHJ5MShnZXRUaGVuLCB1bmRlZmluZWQsIHRyeUJvZHkudmFsdWUpXG5cbiAgICBpZiAodHJ5VGhlbi5jYXVnaHQpIHtcbiAgICAgICAgaWYgKGNvdW50IDwgdGVzdC5hdHRlbXB0cykgcmV0dXJuIGludm9rZUluaXQoY29udGV4dCwgY291bnQgKyAxKVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBSZXN1bHQoc3luY0VuZCAtIHN0YXJ0LCB0cnlUaGVuKSlcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRyeVRoZW4udmFsdWUgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBSZXN1bHQoc3luY0VuZCAtIHN0YXJ0LCB0cnlUaGVuKSlcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgdmFyIHN0YXRlID0gbmV3IEFzeW5jU3RhdGUoY29udGV4dCwgc3RhcnQsIHJlc29sdmUsIGNvdW50KVxuICAgICAgICB2YXIgcmVzdWx0ID0gdHJ5Mih0cnlUaGVuLnZhbHVlLCB0cnlCb2R5LnZhbHVlLFxuICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZSA9PSBudWxsKSByZXR1cm5cbiAgICAgICAgICAgICAgICBhc3luY0ZpbmlzaChzdGF0ZSwgdHJ5UGFzcygpKVxuICAgICAgICAgICAgICAgIHN0YXRlID0gdW5kZWZpbmVkXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUgPT0gbnVsbCkgcmV0dXJuXG4gICAgICAgICAgICAgICAgYXN5bmNGaW5pc2goc3RhdGUsIHRyeUZhaWwoYWRkU3RhY2soZSkpKVxuICAgICAgICAgICAgICAgIHN0YXRlID0gdW5kZWZpbmVkXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIGlmIChzdGF0ZSA9PSBudWxsKSByZXR1cm5cbiAgICAgICAgaWYgKHJlc3VsdC5jYXVnaHQpIHtcbiAgICAgICAgICAgIGFzeW5jRmluaXNoKHN0YXRlLCByZXN1bHQpXG4gICAgICAgICAgICBzdGF0ZSA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgdGhlIHRpbWVvdXQgKmFmdGVyKiBpbml0aWFsaXphdGlvbi4gVGhlIHRpbWVvdXQgd2lsbCBsaWtlbHkgYmVcbiAgICAgICAgLy8gc3BlY2lmaWVkIGR1cmluZyBpbml0aWFsaXphdGlvbi5cbiAgICAgICAgdmFyIG1heFRpbWVvdXQgPSBmaW5kVGltZW91dChjb250ZXh0LnRlc3RzKVxuXG4gICAgICAgIC8vIFNldHRpbmcgYSB0aW1lb3V0IGlzIHBvaW50bGVzcyBpZiBpdCdzIGluZmluaXRlLlxuICAgICAgICBpZiAobWF4VGltZW91dCAhPT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgIHN0YXRlLnRpbWVyID0gc2V0VGltZW91dC5jYWxsKGdsb2JhbCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZSA9PSBudWxsKSByZXR1cm5cbiAgICAgICAgICAgICAgICBhc3luY0ZpbmlzaChzdGF0ZSwgdHJ5RmFpbChhZGRTdGFjayhcbiAgICAgICAgICAgICAgICAgICAgbmV3IEVycm9yKFwiVGltZW91dCBvZiBcIiArIG1heFRpbWVvdXQgKyBcIiByZWFjaGVkXCIpKSkpXG4gICAgICAgICAgICAgICAgc3RhdGUgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIH0sIG1heFRpbWVvdXQpXG4gICAgICAgIH1cbiAgICB9KVxufVxuXG5mdW5jdGlvbiBFcnJvcldyYXAodGVzdCwgZXJyb3IpIHtcbiAgICB0aGlzLnRlc3QgPSB0ZXN0XG4gICAgdGhpcy5lcnJvciA9IGVycm9yXG59XG5tZXRob2RzKEVycm9yV3JhcCwgRXJyb3IsIHtuYW1lOiBcIkVycm9yV3JhcFwifSlcblxuZnVuY3Rpb24gaW52b2tlSG9vayh0ZXN0LCBsaXN0LCBzdGFnZSkge1xuICAgIGlmIChsaXN0ID09IG51bGwpIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgIHJldHVybiBwZWFjaChsaXN0LCBmdW5jdGlvbiAoaG9vaykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGhvb2soKVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3JXcmFwKHRlc3QsIG5ldyBSZXBvcnRzLkhvb2tFcnJvcihzdGFnZSwgaG9vaywgZSkpXG4gICAgICAgIH1cbiAgICB9KVxufVxuXG5mdW5jdGlvbiBpbnZva2VCZWZvcmVFYWNoKHRlc3QpIHtcbiAgICBpZiAodGVzdC5yb290ID09PSB0ZXN0KSB7XG4gICAgICAgIHJldHVybiBpbnZva2VIb29rKHRlc3QsIHRlc3QuYmVmb3JlRWFjaCwgVHlwZXMuQmVmb3JlRWFjaClcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gaW52b2tlQmVmb3JlRWFjaCh0ZXN0LnBhcmVudCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gaW52b2tlSG9vayh0ZXN0LCB0ZXN0LmJlZm9yZUVhY2gsIFR5cGVzLkJlZm9yZUVhY2gpXG4gICAgICAgIH0pXG4gICAgfVxufVxuXG5mdW5jdGlvbiBpbnZva2VBZnRlckVhY2godGVzdCkge1xuICAgIGlmICh0ZXN0LnJvb3QgPT09IHRlc3QpIHtcbiAgICAgICAgcmV0dXJuIGludm9rZUhvb2sodGVzdCwgdGVzdC5hZnRlckVhY2gsIFR5cGVzLkFmdGVyRWFjaClcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gaW52b2tlSG9vayh0ZXN0LCB0ZXN0LmFmdGVyRWFjaCwgVHlwZXMuQWZ0ZXJFYWNoKVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBpbnZva2VBZnRlckVhY2godGVzdC5wYXJlbnQpIH0pXG4gICAgfVxufVxuXG4vKipcbiAqIFRoaXMgY2hlY2tzIGlmIHRoZSB0ZXN0IHdhcyB3aGl0ZWxpc3RlZCBpbiBhIGB0Lm9ubHkoKWAgY2FsbCwgb3IgZm9yXG4gKiBjb252ZW5pZW5jZSwgcmV0dXJucyBgdHJ1ZWAgaWYgYHQub25seSgpYCB3YXMgbmV2ZXIgY2FsbGVkLlxuICovXG5mdW5jdGlvbiBpc09ubHkodGVzdCkge1xuICAgIHZhciBwYXRoID0gW11cblxuICAgIHdoaWxlICh0ZXN0LnBhcmVudCAhPSBudWxsICYmIHRlc3Qub25seSA9PSBudWxsKSB7XG4gICAgICAgIHBhdGgucHVzaCh0ZXN0Lm5hbWUpXG4gICAgICAgIHRlc3QgPSB0ZXN0LnBhcmVudFxuICAgIH1cblxuICAgIC8vIElmIHRoZXJlIGlzbid0IGFueSBgb25seWAgYWN0aXZlLCB0aGVuIGxldCdzIHNraXAgdGhlIGNoZWNrIGFuZCByZXR1cm5cbiAgICAvLyBgdHJ1ZWAgZm9yIGNvbnZlbmllbmNlLlxuICAgIGlmICh0ZXN0Lm9ubHkgPT0gbnVsbCkgcmV0dXJuIHRydWVcbiAgICByZXR1cm4gRmlsdGVyLnRlc3QodGVzdC5vbmx5LCBwYXRoKVxufVxuXG5mdW5jdGlvbiBydW5DaGlsZFRlc3RzKHRlc3QsIGNvbnRleHQpIHtcbiAgICBpZiAodGVzdC50ZXN0cyA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgICBmdW5jdGlvbiBsZWF2ZSgpIHtcbiAgICAgICAgdGVzdC5yb290LmN1cnJlbnQgPSB0ZXN0XG4gICAgICAgIGNvbnRleHQudGVzdHMucG9wKClcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBydW5DaGlsZChjaGlsZCkge1xuICAgICAgICB0ZXN0LnJvb3QuY3VycmVudCA9IGNoaWxkXG4gICAgICAgIGNvbnRleHQudGVzdHMucHVzaChjaGlsZClcblxuICAgICAgICByZXR1cm4gaW52b2tlQmVmb3JlRWFjaCh0ZXN0KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBydW5Ob3JtYWxDaGlsZChjaGlsZCwgY29udGV4dCkgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gaW52b2tlQWZ0ZXJFYWNoKHRlc3QpIH0pXG4gICAgICAgIC5jYXRjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIEVycm9yV3JhcCkpIHRocm93IGVcbiAgICAgICAgICAgIHJldHVybiByZXBvcnQoY29udGV4dCwgVHlwZXMuSG9vaywgZS50ZXN0LCBlLmVycm9yKVxuICAgICAgICB9KVxuICAgICAgICAudGhlbihsZWF2ZSwgZnVuY3Rpb24gKGUpIHsgbGVhdmUoKTsgdGhyb3cgZSB9KVxuICAgIH1cblxuICAgIHZhciByYW4gPSBmYWxzZVxuXG4gICAgcmV0dXJuIHBlYWNoKHRlc3QudGVzdHMsIGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAvLyBPbmx5IHNraXBwZWQgdGVzdHMgaGF2ZSBubyBjYWxsYmFja1xuICAgICAgICBpZiAoY2hpbGQuY2FsbGJhY2sgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGVzdC5yb290LmN1cnJlbnQgPSBjaGlsZFxuICAgICAgICAgICAgY29udGV4dC50ZXN0cy5wdXNoKGNoaWxkKVxuXG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0KGNvbnRleHQsIFR5cGVzLlNraXApXG4gICAgICAgICAgICAudGhlbihsZWF2ZSwgZnVuY3Rpb24gKGUpIHsgbGVhdmUoKTsgdGhyb3cgZSB9KVxuICAgICAgICB9IGVsc2UgaWYgKCFpc09ubHkoY2hpbGQpKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgfSBlbHNlIGlmIChyYW4pIHtcbiAgICAgICAgICAgIHJldHVybiBydW5DaGlsZChjaGlsZClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJhbiA9IHRydWVcbiAgICAgICAgICAgIHJldHVybiBpbnZva2VIb29rKHRlc3QsIHRlc3QuYmVmb3JlQWxsLCBUeXBlcy5CZWZvcmVBbGwpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBydW5DaGlsZChjaGlsZCkgfSlcbiAgICAgICAgfVxuICAgIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gcmFuID8gaW52b2tlSG9vayh0ZXN0LCB0ZXN0LmFmdGVyQWxsLCBUeXBlcy5BZnRlckFsbCkgOiB1bmRlZmluZWRcbiAgICB9KVxufVxuXG5mdW5jdGlvbiBjbGVhckNoaWxkcmVuKHRlc3QpIHtcbiAgICBpZiAodGVzdC50ZXN0cyA9PSBudWxsKSByZXR1cm5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRlc3QudGVzdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGVzdC50ZXN0c1tpXS50ZXN0cyA9IHVuZGVmaW5lZFxuICAgIH1cbn1cblxuZnVuY3Rpb24gcnVuTm9ybWFsQ2hpbGQodGVzdCwgY29udGV4dCkge1xuICAgIHRlc3QubG9ja2VkID0gZmFsc2VcblxuICAgIHJldHVybiBpbnZva2VJbml0KGNvbnRleHQsIDEpXG4gICAgLnRoZW4oXG4gICAgICAgIGZ1bmN0aW9uIChyZXN1bHQpIHsgdGVzdC5sb2NrZWQgPSB0cnVlOyByZXR1cm4gcmVzdWx0IH0sXG4gICAgICAgIGZ1bmN0aW9uIChlcnJvcikgeyB0ZXN0LmxvY2tlZCA9IHRydWU7IHRocm93IGVycm9yIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICBpZiAocmVzdWx0LmNhdWdodCkge1xuICAgICAgICAgICAgaWYgKCF0ZXN0LmlzRmFpbGFibGUpIGNvbnRleHQuaXNTdWNjZXNzID0gZmFsc2VcbiAgICAgICAgICAgIHJldHVybiByZXBvcnQoY29udGV4dCwgVHlwZXMuRmFpbCwgcmVzdWx0LnZhbHVlLCByZXN1bHQudGltZSlcbiAgICAgICAgfSBlbHNlIGlmICh0ZXN0LnRlc3RzICE9IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFJlcG9ydCB0aGlzIGFzIGlmIGl0IHdhcyBhIHBhcmVudCB0ZXN0IGlmIGl0J3MgcGFzc2luZyBhbmQgaGFzXG4gICAgICAgICAgICAvLyBjaGlsZHJlbi5cbiAgICAgICAgICAgIHJldHVybiByZXBvcnQoY29udGV4dCwgVHlwZXMuRW50ZXIsIHJlc3VsdC50aW1lKVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcnVuQ2hpbGRUZXN0cyh0ZXN0LCBjb250ZXh0KSB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVwb3J0KGNvbnRleHQsIFR5cGVzLkxlYXZlKSB9KVxuICAgICAgICAgICAgLmNhdGNoKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIEVycm9yV3JhcCkpIHRocm93IGVcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVwb3J0KGNvbnRleHQsIFR5cGVzLkxlYXZlKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcG9ydChjb250ZXh0LCBUeXBlcy5Ib29rLCBlLnRlc3QsIGUuZXJyb3IpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0KGNvbnRleHQsIFR5cGVzLlBhc3MsIHJlc3VsdC50aW1lKVxuICAgICAgICB9XG4gICAgfSlcbiAgICAudGhlbihcbiAgICAgICAgZnVuY3Rpb24gKCkgeyBjbGVhckNoaWxkcmVuKHRlc3QpIH0sXG4gICAgICAgIGZ1bmN0aW9uIChlKSB7IGNsZWFyQ2hpbGRyZW4odGVzdCk7IHRocm93IGUgfSlcbn1cblxuLyoqXG4gKiBUaGlzIHJ1bnMgdGhlIHJvb3QgdGVzdCBhbmQgcmV0dXJucyBhIHByb21pc2UgcmVzb2x2ZWQgd2hlbiBpdCdzIGRvbmUuXG4gKi9cbmV4cG9ydHMucnVuVGVzdCA9IGZ1bmN0aW9uIChyb290LCBvcHRzKSB7XG4gICAgdmFyIGNvbnRleHQgPSBuZXcgQ29udGV4dChyb290LCBvcHRzKVxuXG4gICAgcm9vdC5sb2NrZWQgPSB0cnVlXG4gICAgcmV0dXJuIHJlcG9ydChjb250ZXh0LCBUeXBlcy5TdGFydClcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBydW5DaGlsZFRlc3RzKHJvb3QsIGNvbnRleHQpIH0pXG4gICAgLmNhdGNoKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBFcnJvcldyYXApKSB0aHJvdyBlXG4gICAgICAgIHJldHVybiByZXBvcnQoY29udGV4dCwgVHlwZXMuSG9vaywgZS50ZXN0LCBlLmVycm9yKVxuICAgIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVwb3J0KGNvbnRleHQsIFR5cGVzLkVuZCkgfSlcbiAgICAvLyBUZWxsIHRoZSByZXBvcnRlciBzb21ldGhpbmcgaGFwcGVuZWQuIE90aGVyd2lzZSwgaXQnbGwgaGF2ZSB0byB3cmFwIHRoaXNcbiAgICAvLyBtZXRob2QgaW4gYSBwbHVnaW4sIHdoaWNoIHNob3VsZG4ndCBiZSBuZWNlc3NhcnkuXG4gICAgLmNhdGNoKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHJldHVybiByZXBvcnQoY29udGV4dCwgVHlwZXMuRXJyb3IsIGUpLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyBlIH0pXG4gICAgfSlcbiAgICAudGhlbihcbiAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY2xlYXJDaGlsZHJlbihyb290KVxuICAgICAgICAgICAgcm9vdC5sb2NrZWQgPSBmYWxzZVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBpc1N1Y2Nlc3M6IGNvbnRleHQuaXNTdWNjZXNzLFxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgY2xlYXJDaGlsZHJlbihyb290KVxuICAgICAgICAgICAgcm9vdC5sb2NrZWQgPSBmYWxzZVxuICAgICAgICAgICAgdGhyb3cgZVxuICAgICAgICB9KVxufVxuXG4vLyBIZWxwIG9wdGltaXplIGZvciBpbmVmZmljaWVudCBleGNlcHRpb24gaGFuZGxpbmcgaW4gVjhcblxuZnVuY3Rpb24gdHJ5UGFzcyh2YWx1ZSkge1xuICAgIHJldHVybiB7Y2F1Z2h0OiBmYWxzZSwgdmFsdWU6IHZhbHVlfVxufVxuXG5mdW5jdGlvbiB0cnlGYWlsKGUpIHtcbiAgICByZXR1cm4ge2NhdWdodDogdHJ1ZSwgdmFsdWU6IGV9XG59XG5cbmZ1bmN0aW9uIHRyeTEoZiwgaW5zdCwgYXJnMCkge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB0cnlQYXNzKGYuY2FsbChpbnN0LCBhcmcwKSlcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiB0cnlGYWlsKGUpXG4gICAgfVxufVxuXG5mdW5jdGlvbiB0cnkyKGYsIGluc3QsIGFyZzAsIGFyZzEpIHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gdHJ5UGFzcyhmLmNhbGwoaW5zdCwgYXJnMCwgYXJnMSkpXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gdHJ5RmFpbChlKVxuICAgIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogVGhlIERPTSByZXBvcnRlciBhbmQgbG9hZGVyIGVudHJ5IHBvaW50LiBTZWUgdGhlIFJFQURNRS5tZCBmb3IgbW9yZSBkZXRhaWxzLlxuICovXG5cbnZhciBpbml0aWFsaXplID0gcmVxdWlyZShcIi4vaW5pdGlhbGl6ZVwiKVxuLy8gdmFyIHQgPSByZXF1aXJlKFwiLi4vLi4vaW5kZXhcIilcbi8vIHZhciBhc3NlcnQgPSByZXF1aXJlKFwiLi4vLi4vYXNzZXJ0XCIpXG5cbmV4cG9ydHMuY3JlYXRlID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgICBpZiAob3B0cyA9PSBudWxsKSByZXR1cm4gaW5pdGlhbGl6ZSh7fSlcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvcHRzKSkgcmV0dXJuIGluaXRpYWxpemUoe2ZpbGVzOiBvcHRzfSlcbiAgICBpZiAodHlwZW9mIG9wdHMgPT09IFwib2JqZWN0XCIpIHJldHVybiBpbml0aWFsaXplKG9wdHMpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBvcHRzYCBtdXN0IGJlIGFuIG9iamVjdCBvciBhcnJheSBvZiBmaWxlcyBpZiBwYXNzZWRcIilcbn1cblxuLy8gQ3VycmVudGx5IGJyb2tlbiwgYmVjYXVzZSB0aGlzIGlzbid0IGF1dG9sb2FkZWQgeWV0LlxuLy8gZXhwb3J0cy5hdXRvbG9hZCA9IGZ1bmN0aW9uIChzY3JpcHQpIHtcbi8vICAgICB2YXIgZmlsZXMgPSBzY3JpcHQuZ2V0QXR0cmlidXRlKFwiZGF0YS1maWxlc1wiKVxuLy9cbi8vICAgICBpZiAoIWZpbGVzKSByZXR1cm5cbi8vXG4vLyAgICAgZnVuY3Rpb24gc2V0KG9wdHMsIGF0dHIsIHRyYW5zZm9ybSkge1xuLy8gICAgICAgICB2YXIgdmFsdWUgPSBzY3JpcHQuZ2V0QXR0cmlidXRlKFwiZGF0YS1cIiArIGF0dHIpXG4vL1xuLy8gICAgICAgICBpZiAodmFsdWUpIG9wdHNbYXR0cl0gPSB0cmFuc2Zvcm0odmFsdWUpXG4vLyAgICAgfVxuLy9cbi8vICAgICB2YXIgb3B0cyA9IHtmaWxlczogZmlsZXMudHJpbSgpLnNwbGl0KC9cXHMrL2cpfVxuLy9cbi8vICAgICBzZXQob3B0cywgXCJ0aW1lb3V0XCIsIE51bWJlcilcbi8vICAgICBzZXQob3B0cywgXCJwcmVsb2FkXCIsIEZ1bmN0aW9uKVxuLy8gICAgIHNldChvcHRzLCBcInByZXJ1blwiLCBGdW5jdGlvbilcbi8vICAgICBzZXQob3B0cywgXCJwb3N0cnVuXCIsIEZ1bmN0aW9uKVxuLy8gICAgIHNldChvcHRzLCBcImVycm9yXCIsIGZ1bmN0aW9uIChhdHRyKSB7XG4vLyAgICAgICAgIHJldHVybiBuZXcgRnVuY3Rpb24oXCJlcnJcIiwgYXR0cikgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuLy8gICAgIH0pXG4vL1xuLy8gICAgIC8vIENvbnZlbmllbmNlLlxuLy8gICAgIGdsb2JhbC50ID0gdFxuLy8gICAgIGdsb2JhbC5hc3NlcnQgPSBhc3NlcnRcbi8vXG4vLyAgICAgaWYgKGdsb2JhbC5kb2N1bWVudC5yZWFkeVN0YXRlICE9PSBcImxvYWRpbmdcIikge1xuLy8gICAgICAgICBpbml0aWFsaXplKG9wdHMpLnJ1bigpXG4vLyAgICAgfSBlbHNlIHtcbi8vICAgICAgICAgZ2xvYmFsLmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uICgpIHtcbi8vICAgICAgICAgICAgIGluaXRpYWxpemUob3B0cykucnVuKClcbi8vICAgICAgICAgfSlcbi8vICAgICB9XG4vLyB9XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vKipcbiAqIFRoZSByZXBvcnRlciBhbmQgdGVzdCBpbml0aWFsaXphdGlvbiBzZXF1ZW5jZSwgYW5kIHNjcmlwdCBsb2FkaW5nLiBUaGlzXG4gKiBkb2Vzbid0IHVuZGVyc3RhbmQgYW55dGhpbmcgdmlldy13aXNlLlxuICovXG5cbnZhciBkZWZhdWx0VCA9IHJlcXVpcmUoXCIuLi8uLi9pbmRleFwiKVxudmFyIFIgPSByZXF1aXJlKFwiLi4vcmVwb3J0ZXJcIilcbnZhciBEID0gcmVxdWlyZShcIi4vaW5qZWN0XCIpXG52YXIgcnVuVGVzdHMgPSByZXF1aXJlKFwiLi9ydW4tdGVzdHNcIilcbnZhciBpbmplY3RTdHlsZXMgPSByZXF1aXJlKFwiLi9pbmplY3Qtc3R5bGVzXCIpXG52YXIgVmlldyA9IHJlcXVpcmUoXCIuL3ZpZXdcIilcbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcblxuZnVuY3Rpb24gVHJlZShuYW1lKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZVxuICAgIHRoaXMuc3RhdHVzID0gUi5TdGF0dXMuVW5rbm93blxuICAgIHRoaXMubm9kZSA9IG51bGxcbiAgICB0aGlzLmNoaWxkcmVuID0gT2JqZWN0LmNyZWF0ZShudWxsKVxufVxuXG52YXIgcmVwb3J0ZXIgPSBSLm9uKFwiZG9tXCIsIHtcbiAgICBhY2NlcHRzOiBbXSxcbiAgICBjcmVhdGU6IGZ1bmN0aW9uIChvcHRzLCBtZXRob2RzKSB7XG4gICAgICAgIHZhciByZXBvcnRlciA9IG5ldyBSLlJlcG9ydGVyKFRyZWUsIHVuZGVmaW5lZCwgbWV0aG9kcylcblxuICAgICAgICByZXBvcnRlci5vcHRzID0gb3B0c1xuICAgICAgICByZXR1cm4gcmVwb3J0ZXJcbiAgICB9LFxuXG4gICAgLy8gR2l2ZSB0aGUgYnJvd3NlciBhIGNoYW5jZSB0byByZXBhaW50IGJlZm9yZSBjb250aW51aW5nIChtaWNyb3Rhc2tzXG4gICAgLy8gbm9ybWFsbHkgYmxvY2sgcmVuZGVyaW5nKS5cbiAgICBhZnRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoVmlldy5uZXh0RnJhbWUpXG4gICAgfSxcblxuICAgIHJlcG9ydDogZnVuY3Rpb24gKF8sIHJlcG9ydCkge1xuICAgICAgICByZXR1cm4gVmlldy5yZXBvcnQoXywgcmVwb3J0KVxuICAgIH0sXG59KVxuXG5mdW5jdGlvbiBub29wKCkge31cblxuZnVuY3Rpb24gc2V0RGVmYXVsdHNDaGVja2VkKG9wdHMpIHtcbiAgICBpZiAob3B0cy50aXRsZSA9PSBudWxsKSBvcHRzLnRpdGxlID0gXCJUaGFsbGl1bSB0ZXN0c1wiXG4gICAgaWYgKG9wdHMudGltZW91dCA9PSBudWxsKSBvcHRzLnRpbWVvdXQgPSA1MDAwXG4gICAgaWYgKG9wdHMuZmlsZXMgPT0gbnVsbCkgb3B0cy5maWxlcyA9IFtdXG4gICAgaWYgKG9wdHMucHJlbG9hZCA9PSBudWxsKSBvcHRzLnByZWxvYWQgPSBub29wXG4gICAgaWYgKG9wdHMucHJlcnVuID09IG51bGwpIG9wdHMucHJlcnVuID0gbm9vcFxuICAgIGlmIChvcHRzLnBvc3RydW4gPT0gbnVsbCkgb3B0cy5wb3N0cnVuID0gbm9vcFxuICAgIGlmIChvcHRzLmVycm9yID09IG51bGwpIG9wdHMuZXJyb3IgPSBub29wXG4gICAgaWYgKG9wdHMudGhhbGxpdW0gPT0gbnVsbCkgb3B0cy50aGFsbGl1bSA9IGRlZmF1bHRUXG5cbiAgICBpZiAodHlwZW9mIG9wdHMudGl0bGUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBvcHRzLnRpdGxlYCBtdXN0IGJlIGEgc3RyaW5nIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy50aW1lb3V0ICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgb3B0cy50aW1lb3V0YCBtdXN0IGJlIGEgbnVtYmVyIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheShvcHRzLmZpbGVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMuZmlsZXNgIG11c3QgYmUgYW4gYXJyYXkgaWYgcGFzc2VkXCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLnByZWxvYWQgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMucHJlbG9hZGAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5wcmVydW4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMucHJlcnVuYCBtdXN0IGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLnBvc3RydW4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMucG9zdHJ1bmAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5lcnJvciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgb3B0cy5lcnJvcmAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy50aGFsbGl1bSAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgXCJgb3B0cy50aGFsbGl1bWAgbXVzdCBiZSBhIFRoYWxsaXVtIGluc3RhbmNlIGlmIHBhc3NlZFwiKVxuICAgIH1cbn1cblxuZnVuY3Rpb24gb25SZWFkeShpbml0KSB7XG4gICAgaWYgKEQuZG9jdW1lbnQuYm9keSAhPSBudWxsKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGluaXQoKSlcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgRC5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXNvbHZlKGluaXQoKSlcbiAgICAgICAgfSwgZmFsc2UpXG4gICAgfSlcbn1cblxuZnVuY3Rpb24gRE9NKG9wdHMpIHtcbiAgICB0aGlzLl9vcHRzID0gb3B0c1xuICAgIHRoaXMuX2Rlc3Ryb3lQcm9taXNlID0gdW5kZWZpbmVkXG4gICAgdGhpcy5fZGF0YSA9IG9uUmVhZHkoZnVuY3Rpb24gKCkge1xuICAgICAgICBzZXREZWZhdWx0c0NoZWNrZWQob3B0cylcbiAgICAgICAgaWYgKCFELmRvY3VtZW50LnRpdGxlKSBELmRvY3VtZW50LnRpdGxlID0gb3B0cy50aXRsZVxuICAgICAgICBpbmplY3RTdHlsZXMoKVxuICAgICAgICB2YXIgZGF0YSA9IFZpZXcuaW5pdChvcHRzKVxuXG4gICAgICAgIG9wdHMudGhhbGxpdW0ucmVwb3J0ZXIocmVwb3J0ZXIsIGRhdGEuc3RhdGUpXG4gICAgICAgIHJldHVybiBkYXRhXG4gICAgfSlcbn1cblxubWV0aG9kcyhET00sIHtcbiAgICBydW46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2Rlc3Ryb3lQcm9taXNlICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJUaGUgdGVzdCBzdWl0ZSBtdXN0IG5vdCBiZSBydW4gYWZ0ZXIgdGhlIHZpZXcgaGFzIGJlZW4gXCIgK1xuICAgICAgICAgICAgICAgIFwiZGV0YWNoZWQuXCJcbiAgICAgICAgICAgICkpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgb3B0cyA9IHRoaXMuX29wdHNcblxuICAgICAgICByZXR1cm4gdGhpcy5fZGF0YS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICByZXR1cm4gcnVuVGVzdHMob3B0cywgZGF0YS5zdGF0ZSlcbiAgICAgICAgfSlcbiAgICB9LFxuXG4gICAgZGV0YWNoOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kZXN0cm95UHJvbWlzZSAhPSBudWxsKSByZXR1cm4gdGhpcy5fZGVzdHJveVByb21pc2VcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rlc3Ryb3lQcm9taXNlID0gc2VsZi5fZGF0YS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICBkYXRhLnN0YXRlLmxvY2tlZCA9IHRydWVcbiAgICAgICAgICAgIGlmIChkYXRhLnN0YXRlLmN1cnJlbnRQcm9taXNlID09IG51bGwpIHJldHVybiBkYXRhXG4gICAgICAgICAgICByZXR1cm4gZGF0YS5zdGF0ZS5jdXJyZW50UHJvbWlzZS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRhdGEgfSlcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgIHNlbGYuX29wdHMgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIHNlbGYuX2RhdGEgPSBzZWxmLl9kZXN0cm95UHJvbWlzZVxuXG4gICAgICAgICAgICB3aGlsZSAoZGF0YS5yb290LmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBkYXRhLnJvb3QucmVtb3ZlQ2hpbGQoZGF0YS5yb290LmZpcnN0Q2hpbGQpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfSxcbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgICByZXR1cm4gbmV3IERPTShvcHRzKVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIFV0aWwgPSByZXF1aXJlKFwiLi4vdXRpbFwiKVxudmFyIEQgPSByZXF1aXJlKFwiLi9pbmplY3RcIilcblxuLyoqXG4gKiBUaGUgcmVwb3J0ZXIgc3R5bGVzaGVldC4gSGVyZSdzIHRoZSBmb3JtYXQ6XG4gKlxuICogLy8gU2luZ2xlIGl0ZW1cbiAqIFwiLnNlbGVjdG9yXCI6IHtcbiAqICAgICAvLyBwcm9wcy4uLlxuICogfVxuICpcbiAqIC8vIER1cGxpY2F0ZSBlbnRyaWVzXG4gKiBcIi5zZWxlY3RvclwiOiB7XG4gKiAgICAgXCJwcm9wXCI6IFtcbiAqICAgICAgICAgLy8gdmFsdWVzLi4uXG4gKiAgICAgXSxcbiAqIH1cbiAqXG4gKiAvLyBEdXBsaWNhdGUgc2VsZWN0b3JzXG4gKiBcIi5zZWxlY3RvclwiOiBbXG4gKiAgICAgLy8gdmFsdWVzLi4uXG4gKiBdXG4gKlxuICogLy8gTWVkaWEgcXVlcnlcbiAqIFwiQG1lZGlhIHNjcmVlblwiOiB7XG4gKiAgICAgLy8gc2VsZWN0b3JzLi4uXG4gKiB9XG4gKlxuICogTm90ZSB0aGF0IENTUyBzdHJpbmdzICptdXN0KiBiZSBxdW90ZWQgaW5zaWRlIHRoZSB2YWx1ZS5cbiAqL1xuXG52YXIgc3R5bGVzID0gVXRpbC5sYXp5KGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eVxuXG4gICAgLyoqXG4gICAgICogUGFydGlhbGx5IHRha2VuIGFuZCBhZGFwdGVkIGZyb20gbm9ybWFsaXplLmNzcyAobGljZW5zZWQgdW5kZXIgdGhlIE1JVFxuICAgICAqIExpY2Vuc2UpLlxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9uZWNvbGFzL25vcm1hbGl6ZS5jc3NcbiAgICAgKi9cbiAgICB2YXIgc3R5bGVPYmplY3QgPSB7XG4gICAgICAgIFwiI3RsXCI6IHtcbiAgICAgICAgICAgIFwiZm9udC1mYW1pbHlcIjogXCJzYW5zLXNlcmlmXCIsXG4gICAgICAgICAgICBcImxpbmUtaGVpZ2h0XCI6IFwiMS4xNVwiLFxuICAgICAgICAgICAgXCItbXMtdGV4dC1zaXplLWFkanVzdFwiOiBcIjEwMCVcIixcbiAgICAgICAgICAgIFwiLXdlYmtpdC10ZXh0LXNpemUtYWRqdXN0XCI6IFwiMTAwJVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIGJ1dHRvblwiOiB7XG4gICAgICAgICAgICBcImZvbnQtZmFtaWx5XCI6IFwic2Fucy1zZXJpZlwiLFxuICAgICAgICAgICAgXCJsaW5lLWhlaWdodFwiOiBcIjEuMTVcIixcbiAgICAgICAgICAgIFwib3ZlcmZsb3dcIjogXCJ2aXNpYmxlXCIsXG4gICAgICAgICAgICBcImZvbnQtc2l6ZVwiOiBcIjEwMCVcIixcbiAgICAgICAgICAgIFwibWFyZ2luXCI6IFwiMFwiLFxuICAgICAgICAgICAgXCJ0ZXh0LXRyYW5zZm9ybVwiOiBcIm5vbmVcIixcbiAgICAgICAgICAgIFwiLXdlYmtpdC1hcHBlYXJhbmNlXCI6IFwiYnV0dG9uXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgaDFcIjoge1xuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIyZW1cIixcbiAgICAgICAgICAgIFwibWFyZ2luXCI6IFwiMC42N2VtIDBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCBhXCI6IHtcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcInRyYW5zcGFyZW50XCIsXG4gICAgICAgICAgICBcIi13ZWJraXQtdGV4dC1kZWNvcmF0aW9uLXNraXBcIjogXCJvYmplY3RzXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgYTphY3RpdmUsICN0bCBhOmhvdmVyXCI6IHtcbiAgICAgICAgICAgIFwib3V0bGluZS13aWR0aFwiOiBcIjBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCBidXR0b246Oi1tb3otZm9jdXMtaW5uZXJcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItc3R5bGVcIjogXCJub25lXCIsXG4gICAgICAgICAgICBcInBhZGRpbmdcIjogXCIwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgYnV0dG9uOi1tb3otZm9jdXNyaW5nXCI6IHtcbiAgICAgICAgICAgIG91dGxpbmU6IFwiMXB4IGRvdHRlZCBCdXR0b25UZXh0XCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEJhc2Ugc3R5bGVzLiBOb3RlIHRoYXQgdGhpcyBDU1MgaXMgZGVzaWduZWQgdG8gaW50ZW50aW9uYWxseSBvdmVycmlkZVxuICAgICAgICAgKiBtb3N0IHRoaW5ncyB0aGF0IGNvdWxkIHByb3BhZ2F0ZS5cbiAgICAgICAgICovXG4gICAgICAgIFwiI3RsICpcIjogW1xuICAgICAgICAgICAge1widGV4dC1hbGlnblwiOiBcImxlZnRcIn0sXG4gICAgICAgICAgICB7XCJ0ZXh0LWFsaWduXCI6IFwic3RhcnRcIn0sXG4gICAgICAgIF0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydCwgI3RsIC50bC1yZXBvcnQgdWxcIjoge1xuICAgICAgICAgICAgXCJsaXN0LXN0eWxlLXR5cGVcIjogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgbGkgfiAudGwtc3VpdGVcIjoge1xuICAgICAgICAgICAgXCJwYWRkaW5nLXRvcFwiOiBcIjFlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1zdWl0ZSA+IGgyXCI6IHtcbiAgICAgICAgICAgIFwiY29sb3JcIjogXCJibGFja1wiLFxuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIxLjVlbVwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcImJvbGRcIixcbiAgICAgICAgICAgIFwibWFyZ2luLWJvdHRvbVwiOiBcIjAuNWVtXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXN1aXRlIC50bC1zdWl0ZSA+IGgyXCI6IHtcbiAgICAgICAgICAgIFwiZm9udC1zaXplXCI6IFwiMS4yZW1cIixcbiAgICAgICAgICAgIFwibWFyZ2luLWJvdHRvbVwiOiBcIjAuM2VtXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXN1aXRlIC50bC1zdWl0ZSAudGwtc3VpdGUgPiBoMlwiOiB7XG4gICAgICAgICAgICBcImZvbnQtc2l6ZVwiOiBcIjEuMmVtXCIsXG4gICAgICAgICAgICBcIm1hcmdpbi1ib3R0b21cIjogXCIwLjJlbVwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcIm5vcm1hbFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0ID4gaDJcIjoge1xuICAgICAgICAgICAgXCJjb2xvclwiOiBcImJsYWNrXCIsXG4gICAgICAgICAgICBcImZvbnQtc2l6ZVwiOiBcIjFlbVwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcIm5vcm1hbFwiLFxuICAgICAgICAgICAgXCJtYXJnaW5cIjogXCIwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRlc3QgPiA6Zmlyc3QtY2hpbGQ6OmJlZm9yZVwiOiB7XG4gICAgICAgICAgICBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgICAgICAgIFwiZm9udC13ZWlnaHRcIjogXCJib2xkXCIsXG4gICAgICAgICAgICBcIndpZHRoXCI6IFwiMS4yZW1cIixcbiAgICAgICAgICAgIFwidGV4dC1hbGlnblwiOiBcImNlbnRlclwiLFxuICAgICAgICAgICAgXCJmb250LWZhbWlseVwiOiBcInNhbnMtc2VyaWZcIixcbiAgICAgICAgICAgIFwidGV4dC1zaGFkb3dcIjogXCIwIDNweCAycHggIzk2OTY5NlwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0LnRsLWZhaWwgPiBoMiwgI3RsIC50bC10ZXN0LnRsLWVycm9yID4gaDJcIjoge1xuICAgICAgICAgICAgY29sb3I6IFwiI2MwMFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0LnRsLXNraXAgPiBoMlwiOiB7XG4gICAgICAgICAgICBjb2xvcjogXCIjMDhjXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRlc3QudGwtcGFzcyA+IDpmaXJzdC1jaGlsZDo6YmVmb3JlXCI6IHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFwiJ+KckydcIixcbiAgICAgICAgICAgIGNvbG9yOiBcIiMwYzBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdGVzdC50bC1mYWlsID4gOmZpcnN0LWNoaWxkOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCIn4pyWJ1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0LnRsLWVycm9yID4gOmZpcnN0LWNoaWxkOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCInISdcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdGVzdC50bC1za2lwID4gOmZpcnN0LWNoaWxkOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCIn4oiSJ1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1wcmUsICN0bCAudGwtZGlmZi1oZWFkZXJcIjoge1xuICAgICAgICAgICAgLy8gbm9ybWFsaXplLmNzczogQ29ycmVjdCB0aGUgaW5oZXJpdGFuY2UgYW5kIHNjYWxpbmcgb2YgZm9udCBzaXplXG4gICAgICAgICAgICAvLyBpbiBhbGwgYnJvd3NlcnNcbiAgICAgICAgICAgIFwiZm9udC1mYW1pbHlcIjogXCJtb25vc3BhY2UsIG1vbm9zcGFjZVwiLFxuICAgICAgICAgICAgXCJiYWNrZ3JvdW5kXCI6IFwiI2YwZjBmMFwiLFxuICAgICAgICAgICAgXCJ3aGl0ZS1zcGFjZVwiOiBcInByZVwiLFxuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIwLjg1ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtcHJlXCI6IHtcbiAgICAgICAgICAgIFwibWluLXdpZHRoXCI6IFwiMTAwJVwiLFxuICAgICAgICAgICAgXCJmbG9hdFwiOiBcImxlZnRcIixcbiAgICAgICAgICAgIFwiY2xlYXJcIjogXCJsZWZ0XCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLWxpbmVcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJibG9ja1wiLFxuICAgICAgICAgICAgbWFyZ2luOiBcIjAgMC4yNWVtXCIsXG4gICAgICAgICAgICB3aWR0aDogXCI5OSVcIiwgLy8gQmVjYXVzZSBGaXJlZm94IHN1Y2tzXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLWRpZmYtaGVhZGVyID4gKlwiOiB7XG4gICAgICAgICAgICBwYWRkaW5nOiBcIjAuMjVlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1kaWZmLWhlYWRlclwiOiB7XG4gICAgICAgICAgICBcInBhZGRpbmdcIjogXCIwLjI1ZW1cIixcbiAgICAgICAgICAgIFwibWFyZ2luLWJvdHRvbVwiOiBcIjAuNWVtXCIsXG4gICAgICAgICAgICBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtbGluZTpmaXJzdC1jaGlsZCwgI3RsIC50bC1kaWZmLWhlYWRlciB+IC50bC1saW5lXCI6IHtcbiAgICAgICAgICAgIFwicGFkZGluZy10b3BcIjogXCIwLjI1ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtbGluZTpsYXN0LWNoaWxkXCI6IHtcbiAgICAgICAgICAgIFwicGFkZGluZy1ib3R0b21cIjogXCIwLjI1ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZmFpbCAudGwtZGlzcGxheVwiOiB7XG4gICAgICAgICAgICBtYXJnaW46IFwiMC41ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZGlzcGxheSA+ICpcIjoge1xuICAgICAgICAgICAgb3ZlcmZsb3c6IFwiYXV0b1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1kaXNwbGF5ID4gOm5vdCg6bGFzdC1jaGlsZClcIjoge1xuICAgICAgICAgICAgXCJtYXJnaW4tYm90dG9tXCI6IFwiMC41ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZGlmZi1hZGRlZFwiOiB7XG4gICAgICAgICAgICBcImNvbG9yXCI6IFwiIzBjMFwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcImJvbGRcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZGlmZi1yZW1vdmVkXCI6IHtcbiAgICAgICAgICAgIFwiY29sb3JcIjogXCIjYzAwXCIsXG4gICAgICAgICAgICBcImZvbnQtd2VpZ2h0XCI6IFwiYm9sZFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1zdGFjayAudGwtbGluZVwiOiB7XG4gICAgICAgICAgICBjb2xvcjogXCIjODAwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLWRpZmY6OmJlZm9yZSwgI3RsIC50bC1zdGFjazo6YmVmb3JlXCI6IHtcbiAgICAgICAgICAgIFwiZm9udC13ZWlnaHRcIjogXCJub3JtYWxcIixcbiAgICAgICAgICAgIFwibWFyZ2luXCI6IFwiMC4yNWVtIDAuMjVlbSAwLjI1ZW0gMFwiLFxuICAgICAgICAgICAgXCJkaXNwbGF5XCI6IFwiYmxvY2tcIixcbiAgICAgICAgICAgIFwiZm9udC1zdHlsZVwiOiBcIml0YWxpY1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1kaWZmOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCInRGlmZjonXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXN0YWNrOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCInU3RhY2s6J1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1oZWFkZXJcIjoge1xuICAgICAgICAgICAgXCJ0ZXh0LWFsaWduXCI6IFwicmlnaHRcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtaGVhZGVyID4gKlwiOiB7XG4gICAgICAgICAgICBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgICAgICAgIFwidGV4dC1hbGlnblwiOiBcImNlbnRlclwiLFxuICAgICAgICAgICAgXCJwYWRkaW5nXCI6IFwiMC41ZW0gMC43NWVtXCIsXG4gICAgICAgICAgICBcImJvcmRlclwiOiBcIjJweCBzb2xpZCAjMDBjXCIsXG4gICAgICAgICAgICBcImJvcmRlci1yYWRpdXNcIjogXCIxZW1cIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcInRyYW5zcGFyZW50XCIsXG4gICAgICAgICAgICBcIm1hcmdpblwiOiBcIjAuMjVlbSAwLjVlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1oZWFkZXIgPiA6Zm9jdXNcIjoge1xuICAgICAgICAgICAgb3V0bGluZTogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJ1blwiOiB7XG4gICAgICAgICAgICBcImJvcmRlci1jb2xvclwiOiBcIiMwODBcIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcIiMwYzBcIixcbiAgICAgICAgICAgIFwiY29sb3JcIjogXCJ3aGl0ZVwiLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiBcIjZlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1ydW46aG92ZXJcIjoge1xuICAgICAgICAgICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCI6IFwiIzhjOFwiLFxuICAgICAgICAgICAgXCJjb2xvclwiOiBcIndoaXRlXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1wYXNzXCI6IHtcbiAgICAgICAgICAgIFwiYm9yZGVyLWNvbG9yXCI6IFwiIzBjMFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10b2dnbGUudGwtZmFpbFwiOiB7XG4gICAgICAgICAgICBcImJvcmRlci1jb2xvclwiOiBcIiNjMDBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdG9nZ2xlLnRsLXNraXBcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDhjXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1wYXNzLnRsLWFjdGl2ZSwgI3RsIC50bC10b2dnbGUudGwtcGFzczphY3RpdmVcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDgwXCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjMGMwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1mYWlsLnRsLWFjdGl2ZSwgI3RsIC50bC10b2dnbGUudGwtZmFpbDphY3RpdmVcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjODAwXCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjYzAwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1za2lwLnRsLWFjdGl2ZSwgI3RsIC50bC10b2dnbGUudGwtc2tpcDphY3RpdmVcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDU4XCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjMDhjXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1wYXNzOmhvdmVyXCI6IHtcbiAgICAgICAgICAgIFwiYm9yZGVyLWNvbG9yXCI6IFwiIzBjMFwiLFxuICAgICAgICAgICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCI6IFwiI2FmYVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10b2dnbGUudGwtZmFpbDpob3ZlclwiOiB7XG4gICAgICAgICAgICBcImJvcmRlci1jb2xvclwiOiBcIiNjMDBcIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcIiNmYWFcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdG9nZ2xlLnRsLXNraXA6aG92ZXJcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDhjXCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjYmRmXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydC50bC1wYXNzIC50bC10ZXN0Om5vdCgudGwtcGFzcylcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydC50bC1mYWlsIC50bC10ZXN0Om5vdCgudGwtZmFpbClcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydC50bC1za2lwIC50bC10ZXN0Om5vdCgudGwtc2tpcClcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJub25lXCIsXG4gICAgICAgIH0sXG4gICAgfVxuXG4gICAgdmFyIGNzcyA9IFwiXCJcblxuICAgIGZ1bmN0aW9uIGFwcGVuZEJhc2Uoc2VsZWN0b3IsIHByb3BzKSB7XG4gICAgICAgIGNzcyArPSBzZWxlY3RvciArIFwie1wiXG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocHJvcHMpKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgYXBwZW5kUHJvcHMocHJvcHNbaV0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhcHBlbmRQcm9wcyhwcm9wcylcbiAgICAgICAgfVxuXG4gICAgICAgIGNzcyArPSBcIn1cIlxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFwcGVuZFByb3BzKHByb3BzKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBwcm9wcykge1xuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKHByb3BzLCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwcm9wc1trZXldID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGFwcGVuZEJhc2Uoa2V5LCBwcm9wc1trZXldKVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNzcyArPSBrZXkgKyBcIjpcIiArIHByb3BzW2tleV0gKyBcIjtcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIHNlbGVjdG9yIGluIHN0eWxlT2JqZWN0KSB7XG4gICAgICAgIGlmIChoYXNPd24uY2FsbChzdHlsZU9iamVjdCwgc2VsZWN0b3IpKSB7XG4gICAgICAgICAgICBhcHBlbmRCYXNlKHNlbGVjdG9yLCBzdHlsZU9iamVjdFtzZWxlY3Rvcl0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY3NzLmNvbmNhdCgpIC8vIEhpbnQgdG8gZmxhdHRlbi5cbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICAgIGlmIChELmRvY3VtZW50LmhlYWQucXVlcnlTZWxlY3RvcihcInN0eWxlW2RhdGEtdGwtc3R5bGVdXCIpID09IG51bGwpIHtcbiAgICAgICAgdmFyIHN0eWxlID0gRC5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIilcblxuICAgICAgICBzdHlsZS50eXBlID0gXCJ0ZXh0L2Nzc1wiXG4gICAgICAgIHN0eWxlLnNldEF0dHJpYnV0ZShcImRhdGEtdGwtc3R5bGVcIiwgXCJcIilcbiAgICAgICAgaWYgKHN0eWxlLnN0eWxlU2hlZXQpIHtcbiAgICAgICAgICAgIHN0eWxlLnN0eWxlU2hlZXQuY3NzVGV4dCA9IHN0eWxlcygpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHlsZS5hcHBlbmRDaGlsZChELmRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN0eWxlcygpKSlcbiAgICAgICAgfVxuXG4gICAgICAgIEQuZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSlcbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vKipcbiAqIFRoZSBnbG9iYWwgaW5qZWN0aW9ucyBmb3IgdGhlIERPTS4gTWFpbmx5IGZvciBkZWJ1Z2dpbmcuXG4gKi9cblxuZXhwb3J0cy5kb2N1bWVudCA9IGdsb2JhbC5kb2N1bWVudFxuZXhwb3J0cy53aW5kb3cgPSBnbG9iYWwud2luZG93XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpXG52YXIgRCA9IHJlcXVpcmUoXCIuL2luamVjdFwiKVxudmFyIG5vdyA9IERhdGUubm93IC8vIEF2b2lkIFNpbm9uJ3MgbW9ja1xudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuLyoqXG4gKiBUZXN0IHJ1bm5lciBhbmQgc2NyaXB0IGxvYWRlclxuICovXG5cbmZ1bmN0aW9uIHVuY2FjaGVkKGZpbGUpIHtcbiAgICBpZiAoZmlsZS5pbmRleE9mKFwiP1wiKSA8IDApIHtcbiAgICAgICAgcmV0dXJuIGZpbGUgKyBcIj9sb2FkZWQ9XCIgKyBub3coKVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmaWxlICsgXCImbG9hZGVkPVwiICsgbm93KClcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxvYWRTY3JpcHQoZmlsZSwgdGltZW91dCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHZhciBzY3JpcHQgPSBELmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIilcbiAgICAgICAgdmFyIHRpbWVyID0gZ2xvYmFsLnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY2xlYXIoKVxuICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIlRpbWVvdXQgZXhjZWVkZWQgbG9hZGluZyAnXCIgKyBmaWxlICsgXCInXCIpKVxuICAgICAgICB9LCB0aW1lb3V0KVxuXG4gICAgICAgIGZ1bmN0aW9uIGNsZWFyKGV2KSB7XG4gICAgICAgICAgICBpZiAoZXYgIT0gbnVsbCkgZXYucHJldmVudERlZmF1bHQoKVxuICAgICAgICAgICAgaWYgKGV2ICE9IG51bGwpIGV2LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICAgICAgICBnbG9iYWwuY2xlYXJUaW1lb3V0KHRpbWVyKVxuICAgICAgICAgICAgc2NyaXB0Lm9ubG9hZCA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgc2NyaXB0Lm9uZXJyb3IgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIEQuZG9jdW1lbnQuaGVhZC5yZW1vdmVDaGlsZChzY3JpcHQpXG4gICAgICAgIH1cblxuICAgICAgICBzY3JpcHQuc3JjID0gdW5jYWNoZWQoZmlsZSlcbiAgICAgICAgc2NyaXB0LmFzeW5jID0gdHJ1ZVxuICAgICAgICBzY3JpcHQuZGVmZXIgPSB0cnVlXG4gICAgICAgIHNjcmlwdC5vbmxvYWQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIGNsZWFyKGV2KVxuICAgICAgICAgICAgcmVzb2x2ZSgpXG4gICAgICAgIH1cblxuICAgICAgICBzY3JpcHQub25lcnJvciA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgY2xlYXIoZXYpXG4gICAgICAgICAgICByZWplY3QoZXYpXG4gICAgICAgIH1cblxuICAgICAgICBELmRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIHRyeURlbGV0ZShrZXkpIHtcbiAgICB0cnkge1xuICAgICAgICBkZWxldGUgZ2xvYmFsW2tleV1cbiAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgIC8vIGlnbm9yZVxuICAgIH1cbn1cblxuZnVuY3Rpb24gZGVzY3JpcHRvckNoYW5nZWQoYSwgYikge1xuICAgIC8vIE5vdGU6IGlmIHRoZSBkZXNjcmlwdG9yIHdhcyByZW1vdmVkLCBpdCB3b3VsZCd2ZSBiZWVuIGRlbGV0ZWQsIGFueXdheXMuXG4gICAgaWYgKGEgPT0gbnVsbCkgcmV0dXJuIGZhbHNlXG4gICAgaWYgKGEuY29uZmlndXJhYmxlICE9PSBiLmNvbmZpZ3VyYWJsZSkgcmV0dXJuIHRydWVcbiAgICBpZiAoYS5lbnVtZXJhYmxlICE9PSBiLmVudW1lcmFibGUpIHJldHVybiB0cnVlXG4gICAgaWYgKGEud3JpdGFibGUgIT09IGIud3JpdGFibGUpIHJldHVybiB0cnVlXG4gICAgaWYgKGEuZ2V0ICE9PSBiLmdldCkgcmV0dXJuIHRydWVcbiAgICBpZiAoYS5zZXQgIT09IGIuc2V0KSByZXR1cm4gdHJ1ZVxuICAgIGlmIChhLnZhbHVlICE9PSBiLnZhbHVlKSByZXR1cm4gdHJ1ZVxuICAgIHJldHVybiBmYWxzZVxufVxuXG4vLyBUaGVzZSBmaXJlIGRlcHJlY2F0aW9uIHdhcm5pbmdzLCBhbmQgdGh1cyBzaG91bGQgYmUgYXZvaWRlZC5cbnZhciBibGFja2xpc3QgPSBPYmplY3QuZnJlZXplKHtcbiAgICB3ZWJraXRTdG9yYWdlSW5mbzogdHJ1ZSxcbiAgICB3ZWJraXRJbmRleGVkREI6IHRydWUsXG59KVxuXG5mdW5jdGlvbiBmaW5kR2xvYmFscygpIHtcbiAgICB2YXIgZm91bmQgPSBPYmplY3Qua2V5cyhnbG9iYWwpXG4gICAgdmFyIGdsb2JhbHMgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZvdW5kLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBmb3VuZFtpXVxuXG4gICAgICAgIGlmICghaGFzT3duLmNhbGwoYmxhY2tsaXN0LCBrZXkpKSB7XG4gICAgICAgICAgICBnbG9iYWxzW2tleV0gPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGdsb2JhbCwga2V5KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGdsb2JhbHNcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0cywgc3RhdGUpIHtcbiAgICBpZiAoc3RhdGUubG9ja2VkKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICBcIlRoZSB0ZXN0IHN1aXRlIG11c3Qgbm90IGJlIHJ1biBhZnRlciB0aGUgdmlldyBoYXMgYmVlbiBkZXRhY2hlZC5cIlxuICAgICAgICApKVxuICAgIH1cblxuICAgIGlmIChzdGF0ZS5jdXJyZW50UHJvbWlzZSAhPSBudWxsKSByZXR1cm4gc3RhdGUuY3VycmVudFByb21pc2VcblxuICAgIG9wdHMudGhhbGxpdW0uY2xlYXJUZXN0cygpXG5cbiAgICAvLyBEZXRlY3QgYW5kIHJlbW92ZSBnbG9iYWxzIGNyZWF0ZWQgYnkgbG9hZGVkIHNjcmlwdHMuXG4gICAgdmFyIGdsb2JhbHMgPSBmaW5kR2xvYmFscygpXG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgICAgICB2YXIgZm91bmQgPSBPYmplY3Qua2V5cyhnbG9iYWwpXG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmb3VuZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGtleSA9IGZvdW5kW2ldXG5cbiAgICAgICAgICAgIGlmICghaGFzT3duLmNhbGwoZ2xvYmFscywga2V5KSkge1xuICAgICAgICAgICAgICAgIHRyeURlbGV0ZShrZXkpXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGRlc2NyaXB0b3JDaGFuZ2VkKFxuICAgICAgICAgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZ2xvYmFsLCBrZXkpLFxuICAgICAgICAgICAgICAgIGdsb2JhbHNba2V5XVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgIHRyeURlbGV0ZShrZXkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5jdXJyZW50UHJvbWlzZSA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIHJldHVybiBzdGF0ZS5jdXJyZW50UHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICBzdGF0ZS5wYXNzLnRleHRDb250ZW50ID0gXCIwXCJcbiAgICAgICAgc3RhdGUuZmFpbC50ZXh0Q29udGVudCA9IFwiMFwiXG4gICAgICAgIHN0YXRlLnNraXAudGV4dENvbnRlbnQgPSBcIjBcIlxuICAgICAgICByZXR1cm4gb3B0cy5wcmVsb2FkKClcbiAgICB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFV0aWwucGVhY2gob3B0cy5maWxlcywgZnVuY3Rpb24gKGZpbGUpIHtcbiAgICAgICAgICAgIHJldHVybiBsb2FkU2NyaXB0KGZpbGUsIG9wdHMudGltZW91dClcbiAgICAgICAgfSlcbiAgICB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIG9wdHMucHJlcnVuKCkgfSlcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBvcHRzLnRoYWxsaXVtLnJ1bigpIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gb3B0cy5wb3N0cnVuKCkgfSlcbiAgICAuY2F0Y2goZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShvcHRzLmVycm9yKGUpKS50aGVuKGZ1bmN0aW9uICgpIHsgdGhyb3cgZSB9KVxuICAgIH0pXG4gICAgLnRoZW4oXG4gICAgICAgIGZ1bmN0aW9uICgpIHsgY2xlYW51cCgpIH0sXG4gICAgICAgIGZ1bmN0aW9uIChlKSB7IGNsZWFudXAoKTsgdGhyb3cgZSB9KVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIGRpZmYgPSByZXF1aXJlKFwiZGlmZlwiKVxudmFyIFIgPSByZXF1aXJlKFwiLi4vcmVwb3J0ZXJcIilcbnZhciBEID0gcmVxdWlyZShcIi4vaW5qZWN0XCIpXG52YXIgcnVuVGVzdHMgPSByZXF1aXJlKFwiLi9ydW4tdGVzdHNcIilcbnZhciBpbnNwZWN0ID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpLmluc3BlY3RcblxuLyoqXG4gKiBWaWV3IGxvZ2ljXG4gKi9cblxuZnVuY3Rpb24gdCh0ZXh0KSB7XG4gICAgcmV0dXJuIEQuZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dClcbn1cblxuZnVuY3Rpb24gaCh0eXBlLCBhdHRycywgY2hpbGRyZW4pIHtcbiAgICB2YXIgcGFydHMgPSB0eXBlLnNwbGl0KC9cXHMrL2cpXG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShhdHRycykpIHtcbiAgICAgICAgY2hpbGRyZW4gPSBhdHRyc1xuICAgICAgICBhdHRycyA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmIChhdHRycyA9PSBudWxsKSBhdHRycyA9IHt9XG4gICAgaWYgKGNoaWxkcmVuID09IG51bGwpIGNoaWxkcmVuID0gW11cblxuICAgIHR5cGUgPSBwYXJ0c1swXVxuICAgIGF0dHJzLmNsYXNzTmFtZSA9IHBhcnRzLnNsaWNlKDEpLmpvaW4oXCIgXCIpXG5cbiAgICB2YXIgZWxlbSA9IEQuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0eXBlKVxuXG4gICAgT2JqZWN0LmtleXMoYXR0cnMpLmZvckVhY2goZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgICAgZWxlbVthdHRyXSA9IGF0dHJzW2F0dHJdXG4gICAgfSlcblxuICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIGlmIChjaGlsZCAhPSBudWxsKSBlbGVtLmFwcGVuZENoaWxkKGNoaWxkKVxuICAgIH0pXG5cbiAgICByZXR1cm4gZWxlbVxufVxuXG5mdW5jdGlvbiB1bmlmaWVkRGlmZihlcnIpIHtcbiAgICB2YXIgYWN0dWFsID0gaW5zcGVjdChlcnIuYWN0dWFsKVxuICAgIHZhciBleHBlY3RlZCA9IGluc3BlY3QoZXJyLmV4cGVjdGVkKVxuICAgIHZhciBtc2cgPSBkaWZmLmNyZWF0ZVBhdGNoKFwic3RyaW5nXCIsIGFjdHVhbCwgZXhwZWN0ZWQpXG4gICAgICAgIC5zcGxpdCgvXFxyP1xcbnxcXHIvZykuc2xpY2UoNClcbiAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gIS9eXFxAXFxAfF5cXFxcIE5vIG5ld2xpbmUvLnRlc3QobGluZSkgfSlcbiAgICB2YXIgZW5kID0gbXNnLmxlbmd0aFxuXG4gICAgd2hpbGUgKGVuZCAhPT0gMCAmJiAvXlxccyokL2cudGVzdChtc2dbZW5kIC0gMV0pKSBlbmQtLVxuICAgIHJldHVybiBoKFwiZGl2IHRsLWRpZmZcIiwgW1xuICAgICAgICBoKFwiZGl2IHRsLWRpZmYtaGVhZGVyXCIsIFtcbiAgICAgICAgICAgIGgoXCJzcGFuIHRsLWRpZmYtYWRkZWRcIiwgW3QoXCIrIGV4cGVjdGVkXCIpXSksXG4gICAgICAgICAgICBoKFwic3BhbiB0bC1kaWZmLXJlbW92ZWRcIiwgW3QoXCItIGFjdHVhbFwiKV0pLFxuICAgICAgICBdKSxcbiAgICAgICAgaChcImRpdiB0bC1wcmVcIiwgIWVuZFxuICAgICAgICAgICAgPyBbaChcInNwYW4gdGwtbGluZSB0bC1kaWZmLWFkZGVkXCIsIFt0KFwiIChub25lKVwiKV0pXVxuICAgICAgICAgICAgOiBtc2cuc2xpY2UoMCwgZW5kKVxuICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gbGluZS50cmltUmlnaHQoKSB9KVxuICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAobGluZSkge1xuICAgICAgICAgICAgICAgIGlmIChsaW5lWzBdID09PSBcIitcIikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaChcInNwYW4gdGwtbGluZSB0bC1kaWZmLWFkZGVkXCIsIFt0KGxpbmUpXSlcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGxpbmVbMF0gPT09IFwiLVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBoKFwic3BhbiB0bC1saW5lIHRsLWRpZmYtcmVtb3ZlZFwiLCBbdChsaW5lKV0pXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGgoXCJzcGFuIHRsLWxpbmUgdGwtZGlmZi1ub25lXCIsIFt0KGxpbmUpXSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICApLFxuICAgIF0pXG59XG5cbmZ1bmN0aW9uIHRvTGluZXMoc3RyKSB7XG4gICAgcmV0dXJuIGgoXCJkaXYgdGwtcHJlXCIsIHN0ci5zcGxpdCgvXFxyP1xcbnxcXHIvZykubWFwKGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIHJldHVybiBoKFwic3BhbiB0bC1saW5lXCIsIFt0KGxpbmUudHJpbVJpZ2h0KCkpXSlcbiAgICB9KSlcbn1cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IoZSwgc2hvd0RpZmYpIHtcbiAgICB2YXIgc3RhY2sgPSBSLnJlYWRTdGFjayhlKVxuXG4gICAgcmV0dXJuIGgoXCJkaXYgdGwtZGlzcGxheVwiLCBbXG4gICAgICAgIGgoXCJkaXYgdGwtbWVzc2FnZVwiLCBbdG9MaW5lcyhlLm5hbWUgKyBcIjogXCIgKyBlLm1lc3NhZ2UpXSksXG4gICAgICAgIHNob3dEaWZmID8gdW5pZmllZERpZmYoZSkgOiB1bmRlZmluZWQsXG4gICAgICAgIHN0YWNrID8gaChcImRpdiB0bC1zdGFja1wiLCBbdG9MaW5lcyhzdGFjayldKSA6IHVuZGVmaW5lZCxcbiAgICBdKVxufVxuXG5mdW5jdGlvbiBzaG93VGVzdChfLCByZXBvcnQsIGNsYXNzTmFtZSwgY2hpbGQpIHtcbiAgICB2YXIgZW5kID0gcmVwb3J0LnBhdGgubGVuZ3RoIC0gMVxuICAgIHZhciBuYW1lID0gcmVwb3J0LnBhdGhbZW5kXS5uYW1lXG4gICAgdmFyIHBhcmVudCA9IF8uZ2V0KHJlcG9ydC5wYXRoLCBlbmQpXG4gICAgdmFyIHNwZWVkID0gUi5zcGVlZChyZXBvcnQpXG5cbiAgICBpZiAoc3BlZWQgPT09IFwiZmFzdFwiKSB7XG4gICAgICAgIHBhcmVudC5ub2RlLmFwcGVuZENoaWxkKGgoXCJsaSBcIiArIGNsYXNzTmFtZSArIFwiIHRsLWZhc3RcIiwgW1xuICAgICAgICAgICAgaChcImgyXCIsIFt0KG5hbWUpXSksXG4gICAgICAgICAgICBjaGlsZCxcbiAgICAgICAgXSkpXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcGFyZW50Lm5vZGUuYXBwZW5kQ2hpbGQoaChcImxpIFwiICsgY2xhc3NOYW1lICsgXCIgdGwtXCIgKyBzcGVlZCwgW1xuICAgICAgICAgICAgaChcImgyXCIsIFtcbiAgICAgICAgICAgICAgICB0KG5hbWUgKyBcIiAoXCIpLFxuICAgICAgICAgICAgICAgIGgoXCJzcGFuIHRsLWR1cmF0aW9uXCIsIFt0KFIuZm9ybWF0VGltZShyZXBvcnQuZHVyYXRpb24pKV0pLFxuICAgICAgICAgICAgICAgIHQoXCIpXCIpLFxuICAgICAgICAgICAgXSksXG4gICAgICAgICAgICBjaGlsZCxcbiAgICAgICAgXSkpXG4gICAgfVxuXG4gICAgXy5vcHRzLmR1cmF0aW9uLnRleHRDb250ZW50ID0gUi5mb3JtYXRUaW1lKF8uZHVyYXRpb24pXG59XG5cbmZ1bmN0aW9uIHNob3dTa2lwKF8sIHJlcG9ydCkge1xuICAgIHZhciBlbmQgPSByZXBvcnQucGF0aC5sZW5ndGggLSAxXG4gICAgdmFyIG5hbWUgPSByZXBvcnQucGF0aFtlbmRdLm5hbWVcbiAgICB2YXIgcGFyZW50ID0gXy5nZXQocmVwb3J0LnBhdGgsIGVuZClcblxuICAgIHBhcmVudC5ub2RlLmFwcGVuZENoaWxkKGgoXCJsaSB0bC10ZXN0IHRsLXNraXBcIiwgW1xuICAgICAgICBoKFwiaDJcIiwgW3QobmFtZSldKSxcbiAgICBdKSlcbn1cblxuZXhwb3J0cy5uZXh0RnJhbWUgPSBuZXh0RnJhbWVcbmZ1bmN0aW9uIG5leHRGcmFtZShmdW5jKSB7XG4gICAgaWYgKEQud2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSkge1xuICAgICAgICBELndpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuYylcbiAgICB9IGVsc2Uge1xuICAgICAgICBnbG9iYWwuc2V0VGltZW91dChmdW5jLCAwKVxuICAgIH1cbn1cblxuZXhwb3J0cy5yZXBvcnQgPSBmdW5jdGlvbiAoXywgcmVwb3J0KSB7XG4gICAgaWYgKHJlcG9ydC5pc1N0YXJ0KSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIGVsZW1lbnQgZmlyc3QsIGp1c3QgaW4gY2FzZS5cbiAgICAgICAgICAgIHdoaWxlIChfLm9wdHMucmVwb3J0LmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBfLm9wdHMucmVwb3J0LnJlbW92ZUNoaWxkKF8ub3B0cy5yZXBvcnQuZmlyc3RDaGlsZClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRGVmZXIgdGhlIG5leHQgZnJhbWUsIHNvIHRoZSBjdXJyZW50IGNoYW5nZXMgY2FuIGJlIHNlbnQsIGluIGNhc2VcbiAgICAgICAgICAgIC8vIGl0J3MgY2xlYXJpbmcgb2xkIHRlc3QgcmVzdWx0cyBmcm9tIGEgbGFyZ2Ugc3VpdGUuIChDaHJvbWUgZG9lc1xuICAgICAgICAgICAgLy8gYmV0dGVyIGJhdGNoaW5nIHRoaXMgd2F5LCBhdCBsZWFzdC4pXG4gICAgICAgICAgICBuZXh0RnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF8uZ2V0KHVuZGVmaW5lZCwgMCkubm9kZSA9IF8ub3B0cy5yZXBvcnRcbiAgICAgICAgICAgICAgICBfLm9wdHMuZHVyYXRpb24udGV4dENvbnRlbnQgPSBSLmZvcm1hdFRpbWUoMClcbiAgICAgICAgICAgICAgICBfLm9wdHMucGFzcy50ZXh0Q29udGVudCA9IFwiMFwiXG4gICAgICAgICAgICAgICAgXy5vcHRzLmZhaWwudGV4dENvbnRlbnQgPSBcIjBcIlxuICAgICAgICAgICAgICAgIF8ub3B0cy5za2lwLnRleHRDb250ZW50ID0gXCIwXCJcbiAgICAgICAgICAgICAgICByZXNvbHZlKClcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFbnRlcikge1xuICAgICAgICB2YXIgY2hpbGQgPSBoKFwidWxcIilcblxuICAgICAgICBfLmdldChyZXBvcnQucGF0aCkubm9kZSA9IGNoaWxkXG4gICAgICAgIHNob3dUZXN0KF8sIHJlcG9ydCwgXCJ0bC1zdWl0ZSB0bC1wYXNzXCIsIGNoaWxkKVxuICAgICAgICBfLm9wdHMucGFzcy50ZXh0Q29udGVudCA9IF8ucGFzc1xuICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzUGFzcykge1xuICAgICAgICBzaG93VGVzdChfLCByZXBvcnQsIFwidGwtdGVzdCB0bC1wYXNzXCIpXG4gICAgICAgIF8ub3B0cy5wYXNzLnRleHRDb250ZW50ID0gXy5wYXNzXG4gICAgfSBlbHNlIGlmIChyZXBvcnQuaXNGYWlsKSB7XG4gICAgICAgIHNob3dUZXN0KF8sIHJlcG9ydCwgXCJ0bC10ZXN0IHRsLWZhaWxcIiwgZm9ybWF0RXJyb3IocmVwb3J0LmVycm9yLFxuICAgICAgICAgICAgcmVwb3J0LmVycm9yLm5hbWUgPT09IFwiQXNzZXJ0aW9uRXJyb3JcIiAmJlxuICAgICAgICAgICAgICAgIHJlcG9ydC5lcnJvci5zaG93RGlmZiAhPT0gZmFsc2UpKVxuICAgICAgICBfLm9wdHMuZmFpbC50ZXh0Q29udGVudCA9IF8uZmFpbFxuICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzU2tpcCkge1xuICAgICAgICBzaG93U2tpcChfLCByZXBvcnQsIFwidGwtdGVzdCB0bC1za2lwXCIpXG4gICAgICAgIF8ub3B0cy5za2lwLnRleHRDb250ZW50ID0gXy5za2lwXG4gICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFcnJvcikge1xuICAgICAgICBfLm9wdHMucmVwb3J0LmFwcGVuZENoaWxkKGgoXCJsaSB0bC1lcnJvclwiLCBbXG4gICAgICAgICAgICBoKFwiaDJcIiwgW3QoXCJJbnRlcm5hbCBlcnJvclwiKV0pLFxuICAgICAgICAgICAgZm9ybWF0RXJyb3IocmVwb3J0LmVycm9yLCBmYWxzZSksXG4gICAgICAgIF0pKVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWRcbn1cblxuZnVuY3Rpb24gbWFrZUNvdW50ZXIoc3RhdGUsIGNoaWxkLCBsYWJlbCwgbmFtZSkge1xuICAgIHJldHVybiBoKFwiYnV0dG9uIHRsLXRvZ2dsZSBcIiArIG5hbWUsIHtcbiAgICAgICAgb25jbGljazogZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKVxuXG4gICAgICAgICAgICBpZiAoL1xcYnRsLWFjdGl2ZVxcYi8udGVzdCh0aGlzLmNsYXNzTmFtZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSA9IHRoaXMuY2xhc3NOYW1lXG4gICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXGJ0bC1hY3RpdmVcXGIvZywgXCJcIilcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xccysvZywgXCIgXCIpXG4gICAgICAgICAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgICAgICBzdGF0ZS5yZXBvcnQuY2xhc3NOYW1lID0gc3RhdGUucmVwb3J0LmNsYXNzTmFtZVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZShuZXcgUmVnRXhwKFwiXFxcXGJcIiArIG5hbWUgKyBcIlxcXFxiXCIsIFwiZ1wiKSwgXCJcIilcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xccysvZywgXCIgXCIpXG4gICAgICAgICAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmUgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLmFjdGl2ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmFjdGl2ZS5jbGFzc05hbWUgPSBzdGF0ZS5hY3RpdmUuY2xhc3NOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxidGwtYWN0aXZlXFxiL2csIFwiXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxzKy9nLCBcIiBcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmUgPSB0aGlzXG4gICAgICAgICAgICAgICAgdGhpcy5jbGFzc05hbWUgKz0gXCIgdGwtYWN0aXZlXCJcbiAgICAgICAgICAgICAgICBzdGF0ZS5yZXBvcnQuY2xhc3NOYW1lID0gc3RhdGUucmVwb3J0LmNsYXNzTmFtZVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxidGwtKHBhc3N8ZmFpbHxza2lwKVxcYi9nLCBcIlwiKVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxzKy9nLCBcIiBcIilcbiAgICAgICAgICAgICAgICAgICAgLnRyaW0oKSArIFwiIFwiICsgbmFtZVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgIH0sIFt0KGxhYmVsKSwgY2hpbGRdKVxufVxuXG5leHBvcnRzLmluaXQgPSBmdW5jdGlvbiAob3B0cykge1xuICAgIHZhciBzdGF0ZSA9IHtcbiAgICAgICAgY3VycmVudFByb21pc2U6IHVuZGVmaW5lZCxcbiAgICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICAgICAgZHVyYXRpb246IGgoXCJlbVwiLCBbdChSLmZvcm1hdFRpbWUoMCkpXSksXG4gICAgICAgIHBhc3M6IGgoXCJlbVwiLCBbdChcIjBcIildKSxcbiAgICAgICAgZmFpbDogaChcImVtXCIsIFt0KFwiMFwiKV0pLFxuICAgICAgICBza2lwOiBoKFwiZW1cIiwgW3QoXCIwXCIpXSksXG4gICAgICAgIHJlcG9ydDogaChcInVsIHRsLXJlcG9ydFwiKSxcbiAgICAgICAgYWN0aXZlOiB1bmRlZmluZWQsXG4gICAgfVxuXG4gICAgdmFyIGhlYWRlciA9IGgoXCJkaXYgdGwtaGVhZGVyXCIsIFtcbiAgICAgICAgaChcImRpdiB0bC1kdXJhdGlvblwiLCBbdChcIkR1cmF0aW9uOiBcIiksIHN0YXRlLmR1cmF0aW9uXSksXG4gICAgICAgIG1ha2VDb3VudGVyKHN0YXRlLCBzdGF0ZS5wYXNzLCBcIlBhc3NlczogXCIsIFwidGwtcGFzc1wiKSxcbiAgICAgICAgbWFrZUNvdW50ZXIoc3RhdGUsIHN0YXRlLmZhaWwsIFwiRmFpbHVyZXM6IFwiLCBcInRsLWZhaWxcIiksXG4gICAgICAgIG1ha2VDb3VudGVyKHN0YXRlLCBzdGF0ZS5za2lwLCBcIlNraXBwZWQ6IFwiLCBcInRsLXNraXBcIiksXG4gICAgICAgIGgoXCJidXR0b24gdGwtcnVuXCIsIHtcbiAgICAgICAgICAgIG9uY2xpY2s6IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgICAgIGV2LnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgICAgICAgICAgIHJ1blRlc3RzKG9wdHMsIHN0YXRlKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSwgW3QoXCJSdW5cIildKSxcbiAgICBdKVxuXG4gICAgdmFyIHJvb3QgPSBELmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwidGxcIilcblxuICAgIGlmIChyb290ID09IG51bGwpIHtcbiAgICAgICAgRC5kb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHJvb3QgPSBoKFwiZGl2XCIsIHtpZDogXCJ0bFwifSwgW1xuICAgICAgICAgICAgaGVhZGVyLFxuICAgICAgICAgICAgc3RhdGUucmVwb3J0LFxuICAgICAgICBdKSlcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDbGVhciB0aGUgZWxlbWVudCBmaXJzdCwganVzdCBpbiBjYXNlLlxuICAgICAgICB3aGlsZSAocm9vdC5maXJzdENoaWxkKSByb290LnJlbW92ZUNoaWxkKHJvb3QuZmlyc3RDaGlsZClcbiAgICAgICAgcm9vdC5hcHBlbmRDaGlsZChoZWFkZXIpXG4gICAgICAgIHJvb3QuYXBwZW5kQ2hpbGQoc3RhdGUucmVwb3J0KVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHJvb3Q6IHJvb3QsXG4gICAgICAgIHN0YXRlOiBzdGF0ZSxcbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChCYXNlLCBTdXBlcikge1xuICAgIHZhciBzdGFydCA9IDJcblxuICAgIGlmICh0eXBlb2YgU3VwZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBCYXNlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoU3VwZXIucHJvdG90eXBlKVxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQmFzZS5wcm90b3R5cGUsIFwiY29uc3RydWN0b3JcIiwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBCYXNlLFxuICAgICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXJ0ID0gMVxuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgbWV0aG9kcyA9IGFyZ3VtZW50c1tpXVxuXG4gICAgICAgIGlmIChtZXRob2RzICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMobWV0aG9kcylcblxuICAgICAgICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCBrZXlzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleSA9IGtleXNba11cbiAgICAgICAgICAgICAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobWV0aG9kcywga2V5KVxuXG4gICAgICAgICAgICAgICAgZGVzYy5lbnVtZXJhYmxlID0gZmFsc2VcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQmFzZS5wcm90b3R5cGUsIGtleSwgZGVzYylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogVGhpcyBjb250YWlucyB0aGUgYnJvd3NlciBjb25zb2xlIHN0dWZmLlxuICovXG5cbmV4cG9ydHMuU3ltYm9scyA9IE9iamVjdC5mcmVlemUoe1xuICAgIFBhc3M6IFwi4pyTXCIsXG4gICAgRmFpbDogXCLinJZcIixcbiAgICBEb3Q6IFwi4oCkXCIsXG4gICAgRG90RmFpbDogXCIhXCIsXG59KVxuXG5leHBvcnRzLndpbmRvd1dpZHRoID0gNzVcbmV4cG9ydHMubmV3bGluZSA9IFwiXFxuXCJcblxuLy8gQ29sb3Igc3VwcG9ydCBpcyB1bmZvcmNlZCBhbmQgdW5zdXBwb3J0ZWQsIHNpbmNlIHlvdSBjYW4gb25seSBzcGVjaWZ5XG4vLyBsaW5lLWJ5LWxpbmUgY29sb3JzIHZpYSBDU1MsIGFuZCBldmVuIHRoYXQgaXNuJ3QgdmVyeSBwb3J0YWJsZS5cbmV4cG9ydHMuY29sb3JTdXBwb3J0ID0gMFxuXG4vKipcbiAqIFNpbmNlIGJyb3dzZXJzIGRvbid0IGhhdmUgdW5idWZmZXJlZCBvdXRwdXQsIHRoaXMga2luZCBvZiBzaW11bGF0ZXMgaXQuXG4gKi9cblxudmFyIGFjYyA9IFwiXCJcblxuZXhwb3J0cy5kZWZhdWx0T3B0cyA9IHtcbiAgICB3cml0ZTogZnVuY3Rpb24gKHN0cikge1xuICAgICAgICBhY2MgKz0gc3RyXG5cbiAgICAgICAgdmFyIGluZGV4ID0gc3RyLmluZGV4T2YoXCJcXG5cIilcblxuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgdmFyIGxpbmVzID0gc3RyLnNwbGl0KFwiXFxuXCIpXG5cbiAgICAgICAgICAgIGFjYyA9IGxpbmVzLnBvcCgpXG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBnbG9iYWwuY29uc29sZS5sb2cobGluZXNbaV0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKGFjYyAhPT0gXCJcIikge1xuICAgICAgICAgICAgZ2xvYmFsLmNvbnNvbGUubG9nKGFjYylcbiAgICAgICAgICAgIGFjYyA9IFwiXCJcbiAgICAgICAgfVxuICAgIH0sXG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgZGlmZiA9IHJlcXVpcmUoXCJkaWZmXCIpXG5cbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcbnZhciBpbnNwZWN0ID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpLmluc3BlY3RcbnZhciBwZWFjaCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpLnBlYWNoXG52YXIgUmVwb3J0ZXIgPSByZXF1aXJlKFwiLi9yZXBvcnRlclwiKVxudmFyIFV0aWwgPSByZXF1aXJlKFwiLi91dGlsXCIpXG52YXIgU2V0dGluZ3MgPSByZXF1aXJlKFwiLi4vc2V0dGluZ3NcIilcblxuZnVuY3Rpb24gcHJpbnRUaW1lKF8sIHAsIHN0cikge1xuICAgIGlmICghXy50aW1lUHJpbnRlZCkge1xuICAgICAgICBfLnRpbWVQcmludGVkID0gdHJ1ZVxuICAgICAgICBzdHIgKz0gVXRpbC5jb2xvcihcImxpZ2h0XCIsIFwiIChcIiArIFV0aWwuZm9ybWF0VGltZShfLmR1cmF0aW9uKSArIFwiKVwiKVxuICAgIH1cblxuICAgIHJldHVybiBwLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChzdHIpIH0pXG59XG5cbmZ1bmN0aW9uIHVuaWZpZWREaWZmKGVycikge1xuICAgIHZhciBhY3R1YWwgPSBpbnNwZWN0KGVyci5hY3R1YWwpXG4gICAgdmFyIGV4cGVjdGVkID0gaW5zcGVjdChlcnIuZXhwZWN0ZWQpXG4gICAgdmFyIG1zZyA9IGRpZmYuY3JlYXRlUGF0Y2goXCJzdHJpbmdcIiwgYWN0dWFsLCBleHBlY3RlZClcbiAgICB2YXIgaGVhZGVyID0gU2V0dGluZ3MubmV3bGluZSgpICtcbiAgICAgICAgVXRpbC5jb2xvcihcImRpZmYgYWRkZWRcIiwgXCIrIGV4cGVjdGVkXCIpICsgXCIgXCIgK1xuICAgICAgICBVdGlsLmNvbG9yKFwiZGlmZiByZW1vdmVkXCIsIFwiLSBhY3R1YWxcIikgK1xuICAgICAgICBTZXR0aW5ncy5uZXdsaW5lKCkgKyBTZXR0aW5ncy5uZXdsaW5lKClcblxuICAgIHJldHVybiBoZWFkZXIgKyBtc2cuc3BsaXQoL1xccj9cXG58XFxyL2cpLnNsaWNlKDQpXG4gICAgLmZpbHRlcihmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gIS9eXFxAXFxAfF5cXFxcIE5vIG5ld2xpbmUvLnRlc3QobGluZSkgfSlcbiAgICAubWFwKGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIGlmIChsaW5lWzBdID09PSBcIitcIikgcmV0dXJuIFV0aWwuY29sb3IoXCJkaWZmIGFkZGVkXCIsIGxpbmUudHJpbVJpZ2h0KCkpXG4gICAgICAgIGlmIChsaW5lWzBdID09PSBcIi1cIikgcmV0dXJuIFV0aWwuY29sb3IoXCJkaWZmIHJlbW92ZWRcIiwgbGluZS50cmltUmlnaHQoKSlcbiAgICAgICAgcmV0dXJuIGxpbmUudHJpbVJpZ2h0KClcbiAgICB9KVxuICAgIC5qb2luKFNldHRpbmdzLm5ld2xpbmUoKSlcbn1cblxuZnVuY3Rpb24gZm9ybWF0RmFpbChzdHIpIHtcbiAgICByZXR1cm4gc3RyLnRyaW1SaWdodCgpXG4gICAgLnNwbGl0KC9cXHI/XFxufFxcci9nKVxuICAgIC5tYXAoZnVuY3Rpb24gKGxpbmUpIHsgcmV0dXJuIFV0aWwuY29sb3IoXCJmYWlsXCIsIGxpbmUudHJpbVJpZ2h0KCkpIH0pXG4gICAgLmpvaW4oU2V0dGluZ3MubmV3bGluZSgpKVxufVxuXG5mdW5jdGlvbiBnZXREaWZmU3RhY2soZSkge1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IGZvcm1hdEZhaWwoZS5uYW1lICsgXCI6IFwiICsgZS5tZXNzYWdlKVxuXG4gICAgaWYgKGUubmFtZSA9PT0gXCJBc3NlcnRpb25FcnJvclwiICYmIGUuc2hvd0RpZmYgIT09IGZhbHNlKSB7XG4gICAgICAgIGRlc2NyaXB0aW9uICs9IFNldHRpbmdzLm5ld2xpbmUoKSArIHVuaWZpZWREaWZmKGUpXG4gICAgfVxuXG4gICAgdmFyIHN0cmlwcGVkID0gZm9ybWF0RmFpbChVdGlsLnJlYWRTdGFjayhlKSlcblxuICAgIGlmIChzdHJpcHBlZCA9PT0gXCJcIikgcmV0dXJuIGRlc2NyaXB0aW9uXG4gICAgcmV0dXJuIGRlc2NyaXB0aW9uICsgU2V0dGluZ3MubmV3bGluZSgpICsgc3RyaXBwZWRcbn1cblxuZnVuY3Rpb24gaW5zcGVjdFRyaW1tZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuIGluc3BlY3Qob2JqZWN0KS50cmltUmlnaHQoKVxuICAgIC5zcGxpdCgvXFxyP1xcbnxcXHIvZylcbiAgICAubWFwKGZ1bmN0aW9uIChsaW5lKSB7IHJldHVybiBsaW5lLnRyaW1SaWdodCgpIH0pXG4gICAgLmpvaW4oU2V0dGluZ3MubmV3bGluZSgpKVxufVxuXG5mdW5jdGlvbiBwcmludEZhaWxMaXN0KF8sIGVycikge1xuICAgIHZhciBzdHIgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGdldERpZmZTdGFjayhlcnIpIDogaW5zcGVjdFRyaW1tZWQoZXJyKVxuICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdCgvXFxyP1xcbi9nKVxuXG4gICAgcmV0dXJuIF8ucHJpbnQoXCIgICAgXCIgKyBwYXJ0c1swXSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBwZWFjaChwYXJ0cy5zbGljZSgxKSwgZnVuY3Rpb24gKHBhcnQpIHtcbiAgICAgICAgICAgIHJldHVybiBfLnByaW50KHBhcnQgPyBcIiAgICAgIFwiICsgcGFydCA6IFwiXCIpXG4gICAgICAgIH0pXG4gICAgfSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0cywgbWV0aG9kcykge1xuICAgIHJldHVybiBuZXcgQ29uc29sZVJlcG9ydGVyKG9wdHMsIG1ldGhvZHMpXG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgbW9zdCBjb25zb2xlIHJlcG9ydGVycy5cbiAqXG4gKiBOb3RlOiBwcmludGluZyBpcyBhc3luY2hyb25vdXMsIGJlY2F1c2Ugb3RoZXJ3aXNlLCBpZiBlbm91Z2ggZXJyb3JzIGV4aXN0LFxuICogTm9kZSB3aWxsIGV2ZW50dWFsbHkgc3RhcnQgZHJvcHBpbmcgbGluZXMgc2VudCB0byBpdHMgYnVmZmVyLCBlc3BlY2lhbGx5IHdoZW5cbiAqIHN0YWNrIHRyYWNlcyBnZXQgaW52b2x2ZWQuIElmIFRoYWxsaXVtJ3Mgb3V0cHV0IGlzIHJlZGlyZWN0ZWQsIHRoYXQgY2FuIGJlIGFcbiAqIGJpZyBwcm9ibGVtIGZvciBjb25zdW1lcnMsIGFzIHRoZXkgb25seSBoYXZlIHBhcnQgb2YgdGhlIG91dHB1dCwgYW5kIHdvbid0IGJlXG4gKiBhYmxlIHRvIHNlZSBhbGwgdGhlIGVycm9ycyBsYXRlci4gQWxzbywgaWYgY29uc29sZSB3YXJuaW5ncyBjb21lIHVwIGVuLW1hc3NlLFxuICogdGhhdCB3b3VsZCBhbHNvIGNvbnRyaWJ1dGUuIFNvLCB3ZSBoYXZlIHRvIHdhaXQgZm9yIGVhY2ggbGluZSB0byBmbHVzaCBiZWZvcmVcbiAqIHdlIGNhbiBjb250aW51ZSwgc28gdGhlIGZ1bGwgb3V0cHV0IG1ha2VzIGl0cyB3YXkgdG8gdGhlIGNvbnNvbGUuXG4gKlxuICogU29tZSB0ZXN0IGZyYW1ld29ya3MgbGlrZSBUYXBlIG1pc3MgdGhpcywgdGhvdWdoLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIFRoZSBvcHRpb25zIGZvciB0aGUgcmVwb3J0ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBvcHRzLndyaXRlIFRoZSB1bmJ1ZmZlcnJlZCB3cml0ZXIgZm9yIHRoZSByZXBvcnRlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IG9wdHMucmVzZXQgQSByZXNldCBmdW5jdGlvbiBmb3IgdGhlIHByaW50ZXIgKyB3cml0ZXIuXG4gKiBAcGFyYW0ge1N0cmluZ1tdfSBhY2NlcHRzIFRoZSBvcHRpb25zIGFjY2VwdGVkLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaW5pdCBUaGUgaW5pdCBmdW5jdGlvbiBmb3IgdGhlIHN1YmNsYXNzIHJlcG9ydGVyJ3NcbiAqICAgICAgICAgICAgICAgICAgICAgICAgaXNvbGF0ZWQgc3RhdGUgKGNyZWF0ZWQgYnkgZmFjdG9yeSkuXG4gKi9cbmZ1bmN0aW9uIENvbnNvbGVSZXBvcnRlcihvcHRzLCBtZXRob2RzKSB7XG4gICAgUmVwb3J0ZXIuY2FsbCh0aGlzLCBVdGlsLlRyZWUsIG9wdHMsIG1ldGhvZHMsIHRydWUpXG5cbiAgICBpZiAoIVV0aWwuQ29sb3JzLmZvcmNlZCgpICYmIG1ldGhvZHMuYWNjZXB0cy5pbmRleE9mKFwiY29sb3JcIikgPj0gMCkge1xuICAgICAgICB0aGlzLm9wdHMuY29sb3IgPSBvcHRzLmNvbG9yXG4gICAgfVxuXG4gICAgVXRpbC5kZWZhdWx0aWZ5KHRoaXMsIG9wdHMsIFwid3JpdGVcIilcbiAgICB0aGlzLnJlc2V0KClcbn1cblxubWV0aG9kcyhDb25zb2xlUmVwb3J0ZXIsIFJlcG9ydGVyLCB7XG4gICAgcHJpbnQ6IGZ1bmN0aW9uIChzdHIpIHtcbiAgICAgICAgaWYgKHN0ciA9PSBudWxsKSBzdHIgPSBcIlwiXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5vcHRzLndyaXRlKHN0ciArIFwiXFxuXCIpKVxuICAgIH0sXG5cbiAgICB3cml0ZTogZnVuY3Rpb24gKHN0cikge1xuICAgICAgICBpZiAoc3RyICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5vcHRzLndyaXRlKHN0cikpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBwcmludFJlc3VsdHM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgICAgICAgaWYgKCF0aGlzLnRlc3RzICYmICF0aGlzLnNraXApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByaW50KFxuICAgICAgICAgICAgICAgIFV0aWwuY29sb3IoXCJwbGFpblwiLCBcIiAgMCB0ZXN0c1wiKSArXG4gICAgICAgICAgICAgICAgVXRpbC5jb2xvcihcImxpZ2h0XCIsIFwiICgwbXMpXCIpKVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5wcmludCgpIH0pXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5wcmludCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHAgPSBQcm9taXNlLnJlc29sdmUoKVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5wYXNzKSB7XG4gICAgICAgICAgICAgICAgcCA9IHByaW50VGltZShzZWxmLCBwLFxuICAgICAgICAgICAgICAgICAgICBVdGlsLmNvbG9yKFwiYnJpZ2h0IHBhc3NcIiwgXCIgIFwiKSArXG4gICAgICAgICAgICAgICAgICAgIFV0aWwuY29sb3IoXCJncmVlblwiLCBzZWxmLnBhc3MgKyBcIiBwYXNzaW5nXCIpKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5za2lwKSB7XG4gICAgICAgICAgICAgICAgcCA9IHByaW50VGltZShzZWxmLCBwLFxuICAgICAgICAgICAgICAgICAgICBVdGlsLmNvbG9yKFwic2tpcFwiLCBcIiAgXCIgKyBzZWxmLnNraXAgKyBcIiBza2lwcGVkXCIpKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5mYWlsKSB7XG4gICAgICAgICAgICAgICAgcCA9IHByaW50VGltZShzZWxmLCBwLFxuICAgICAgICAgICAgICAgICAgICBVdGlsLmNvbG9yKFwiYnJpZ2h0IGZhaWxcIiwgXCIgIFwiKSArXG4gICAgICAgICAgICAgICAgICAgIFV0aWwuY29sb3IoXCJmYWlsXCIsIHNlbGYuZmFpbCArIFwiIGZhaWxpbmdcIikpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBwXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGYucHJpbnQoKSB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcGVhY2goc2VsZi5lcnJvcnMsIGZ1bmN0aW9uIChyZXBvcnQsIGkpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IGkgKyAxICsgXCIpIFwiICsgVXRpbC5qb2luUGF0aChyZXBvcnQpICtcbiAgICAgICAgICAgICAgICAgICAgVXRpbC5mb3JtYXRSZXN0KHJlcG9ydClcblxuICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLnByaW50KFwiICBcIiArIFV0aWwuY29sb3IoXCJwbGFpblwiLCBuYW1lICsgXCI6XCIpKVxuICAgICAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByaW50RmFpbExpc3Qoc2VsZiwgcmVwb3J0LmVycm9yKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5wcmludCgpIH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgIH0sXG5cbiAgICBwcmludEVycm9yOiBmdW5jdGlvbiAocmVwb3J0KSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpc1xuICAgICAgICB2YXIgbGluZXMgPSByZXBvcnQuZXJyb3IgaW5zdGFuY2VvZiBFcnJvclxuICAgICAgICAgICAgPyBVdGlsLmdldFN0YWNrKHJlcG9ydC5lcnJvcilcbiAgICAgICAgICAgIDogaW5zcGVjdFRyaW1tZWQocmVwb3J0LmVycm9yKVxuXG4gICAgICAgIHJldHVybiB0aGlzLnByaW50KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcGVhY2gobGluZXMuc3BsaXQoL1xccj9cXG4vZyksIGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYucHJpbnQobGluZSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuL3V0aWxcIilcblxuZXhwb3J0cy5vbiA9IHJlcXVpcmUoXCIuL29uXCIpXG5leHBvcnRzLmNvbnNvbGVSZXBvcnRlciA9IHJlcXVpcmUoXCIuL2NvbnNvbGUtcmVwb3J0ZXJcIilcbmV4cG9ydHMuUmVwb3J0ZXIgPSByZXF1aXJlKFwiLi9yZXBvcnRlclwiKVxuZXhwb3J0cy5jb2xvciA9IFV0aWwuY29sb3JcbmV4cG9ydHMuQ29sb3JzID0gVXRpbC5Db2xvcnNcbmV4cG9ydHMuZm9ybWF0UmVzdCA9IFV0aWwuZm9ybWF0UmVzdFxuZXhwb3J0cy5mb3JtYXRUaW1lID0gVXRpbC5mb3JtYXRUaW1lXG5leHBvcnRzLmdldFN0YWNrID0gVXRpbC5nZXRTdGFja1xuZXhwb3J0cy5qb2luUGF0aCA9IFV0aWwuam9pblBhdGhcbmV4cG9ydHMubmV3bGluZSA9IFV0aWwubmV3bGluZVxuZXhwb3J0cy5yZWFkU3RhY2sgPSBVdGlsLnJlYWRTdGFja1xuZXhwb3J0cy5zZXRDb2xvciA9IFV0aWwuc2V0Q29sb3JcbmV4cG9ydHMuc3BlZWQgPSBVdGlsLnNwZWVkXG5leHBvcnRzLlN0YXR1cyA9IFV0aWwuU3RhdHVzXG5leHBvcnRzLnN5bWJvbHMgPSBVdGlsLnN5bWJvbHNcbmV4cG9ydHMudW5zZXRDb2xvciA9IFV0aWwudW5zZXRDb2xvclxuZXhwb3J0cy53aW5kb3dXaWR0aCA9IFV0aWwud2luZG93V2lkdGhcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBTdGF0dXMgPSByZXF1aXJlKFwiLi91dGlsXCIpLlN0YXR1c1xuXG4vLyBCZWNhdXNlIEVTNSBzdWNrcy4gKEFuZCwgaXQncyBicmVha2luZyBteSBQaGFudG9tSlMgYnVpbGRzKVxuZnVuY3Rpb24gc2V0TmFtZShyZXBvcnRlciwgbmFtZSkge1xuICAgIHRyeSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXBvcnRlciwgXCJuYW1lXCIsIHt2YWx1ZTogbmFtZX0pXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBpZ25vcmVcbiAgICB9XG59XG5cbi8qKlxuICogQSBtYWNybyBvZiBzb3J0cywgdG8gc2ltcGxpZnkgY3JlYXRpbmcgcmVwb3J0ZXJzLiBJdCBhY2NlcHRzIGFuIG9iamVjdCB3aXRoXG4gKiB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6XG4gKlxuICogYGFjY2VwdHM6IHN0cmluZ1tdYCAtIFRoZSBwcm9wZXJ0aWVzIGFjY2VwdGVkLiBFdmVyeXRoaW5nIGVsc2UgaXMgaWdub3JlZCxcbiAqIGFuZCBpdCdzIHBhcnRpYWxseSB0aGVyZSBmb3IgZG9jdW1lbnRhdGlvbi4gVGhpcyBwYXJhbWV0ZXIgaXMgcmVxdWlyZWQuXG4gKlxuICogYGNyZWF0ZShvcHRzLCBtZXRob2RzKWAgLSBDcmVhdGUgYSBuZXcgcmVwb3J0ZXIgaW5zdGFuY2UuICBUaGlzIHBhcmFtZXRlciBpc1xuICogcmVxdWlyZWQuIE5vdGUgdGhhdCBgbWV0aG9kc2AgcmVmZXJzIHRvIHRoZSBwYXJhbWV0ZXIgb2JqZWN0IGl0c2VsZi5cbiAqXG4gKiBgaW5pdChzdGF0ZSwgb3B0cylgIC0gSW5pdGlhbGl6ZSBleHRyYSByZXBvcnRlciBzdGF0ZSwgaWYgYXBwbGljYWJsZS5cbiAqXG4gKiBgYmVmb3JlKHJlcG9ydGVyKWAgLSBEbyB0aGluZ3MgYmVmb3JlIGVhY2ggZXZlbnQsIHJldHVybmluZyBhIHBvc3NpYmxlXG4gKiB0aGVuYWJsZSB3aGVuIGRvbmUuIFRoaXMgZGVmYXVsdHMgdG8gYSBuby1vcC5cbiAqXG4gKiBgYWZ0ZXIocmVwb3J0ZXIpYCAtIERvIHRoaW5ncyBhZnRlciBlYWNoIGV2ZW50LCByZXR1cm5pbmcgYSBwb3NzaWJsZVxuICogdGhlbmFibGUgd2hlbiBkb25lLiBUaGlzIGRlZmF1bHRzIHRvIGEgbm8tb3AuXG4gKlxuICogYHJlcG9ydChyZXBvcnRlciwgcmVwb3J0KWAgLSBIYW5kbGUgYSB0ZXN0IHJlcG9ydC4gVGhpcyBtYXkgcmV0dXJuIGEgcG9zc2libGVcbiAqIHRoZW5hYmxlIHdoZW4gZG9uZSwgYW5kIGl0IGlzIHJlcXVpcmVkLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChuYW1lLCBtZXRob2RzKSB7XG4gICAgc2V0TmFtZShyZXBvcnRlciwgbmFtZSlcbiAgICByZXBvcnRlcltuYW1lXSA9IHJlcG9ydGVyXG4gICAgcmV0dXJuIHJlcG9ydGVyXG4gICAgZnVuY3Rpb24gcmVwb3J0ZXIob3B0cykge1xuICAgICAgICAvKipcbiAgICAgICAgICogSW5zdGVhZCBvZiBzaWxlbnRseSBmYWlsaW5nIHRvIHdvcmssIGxldCdzIGVycm9yIG91dCB3aGVuIGEgcmVwb3J0IGlzXG4gICAgICAgICAqIHBhc3NlZCBpbiwgYW5kIGluZm9ybSB0aGUgdXNlciBpdCBuZWVkcyBpbml0aWFsaXplZC4gQ2hhbmNlcyBhcmUsXG4gICAgICAgICAqIHRoZXJlJ3Mgbm8gbGVnaXRpbWF0ZSByZWFzb24gdG8gZXZlbiBwYXNzIGEgcmVwb3J0LCBhbnl3YXlzLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKHR5cGVvZiBvcHRzID09PSBcIm9iamVjdFwiICYmIG9wdHMgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2Ygb3B0cy5fID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgICAgIFwiT3B0aW9ucyBjYW5ub3QgYmUgYSByZXBvcnQuIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgdGhlIFwiICtcbiAgICAgICAgICAgICAgICBcImZhY3RvcnkgZmlyc3Q/XCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgXyA9IG1ldGhvZHMuY3JlYXRlKG9wdHMsIG1ldGhvZHMpXG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChyZXBvcnQpIHtcbiAgICAgICAgICAgIC8vIE9ubHkgc29tZSBldmVudHMgaGF2ZSBjb21tb24gc3RlcHMuXG4gICAgICAgICAgICBpZiAocmVwb3J0LmlzU3RhcnQpIHtcbiAgICAgICAgICAgICAgICBfLnJ1bm5pbmcgPSB0cnVlXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0VudGVyIHx8IHJlcG9ydC5pc1Bhc3MpIHtcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucGF0aCkuc3RhdHVzID0gU3RhdHVzLlBhc3NpbmdcbiAgICAgICAgICAgICAgICBfLmR1cmF0aW9uICs9IHJlcG9ydC5kdXJhdGlvblxuICAgICAgICAgICAgICAgIF8udGVzdHMrK1xuICAgICAgICAgICAgICAgIF8ucGFzcysrXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0ZhaWwpIHtcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucGF0aCkuc3RhdHVzID0gU3RhdHVzLkZhaWxpbmdcbiAgICAgICAgICAgICAgICBfLmR1cmF0aW9uICs9IHJlcG9ydC5kdXJhdGlvblxuICAgICAgICAgICAgICAgIF8udGVzdHMrK1xuICAgICAgICAgICAgICAgIF8uZmFpbCsrXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0hvb2spIHtcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucGF0aCkuc3RhdHVzID0gU3RhdHVzLkZhaWxpbmdcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucm9vdFBhdGgpLnN0YXR1cyA9IFN0YXR1cy5GYWlsaW5nXG4gICAgICAgICAgICAgICAgXy5mYWlsKytcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzU2tpcCkge1xuICAgICAgICAgICAgICAgIF8uZ2V0KHJlcG9ydC5wYXRoKS5zdGF0dXMgPSBTdGF0dXMuU2tpcHBlZFxuICAgICAgICAgICAgICAgIC8vIFNraXBwZWQgdGVzdHMgYXJlbid0IGNvdW50ZWQgaW4gdGhlIHRvdGFsIHRlc3QgY291bnRcbiAgICAgICAgICAgICAgICBfLnNraXArK1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICAgICAgICAgIHR5cGVvZiBtZXRob2RzLmJlZm9yZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICAgICAgICAgID8gbWV0aG9kcy5iZWZvcmUoXylcbiAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBtZXRob2RzLnJlcG9ydChfLCByZXBvcnQpIH0pXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBtZXRob2RzLmFmdGVyID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgPyBtZXRob2RzLmFmdGVyKF8pXG4gICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChyZXBvcnQuaXNFbmQgfHwgcmVwb3J0LmlzRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgXy5yZXNldCgpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgXy5vcHRzLnJlc2V0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfLm9wdHMucmVzZXQoKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgbWV0aG9kcyA9IHJlcXVpcmUoXCIuLi9tZXRob2RzXCIpXG52YXIgZGVmYXVsdGlmeSA9IHJlcXVpcmUoXCIuL3V0aWxcIikuZGVmYXVsdGlmeVxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuZnVuY3Rpb24gU3RhdGUocmVwb3J0ZXIpIHtcbiAgICBpZiAodHlwZW9mIHJlcG9ydGVyLm1ldGhvZHMuaW5pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICgwLCByZXBvcnRlci5tZXRob2RzLmluaXQpKHRoaXMsIHJlcG9ydGVyLm9wdHMpXG4gICAgfVxufVxuXG4vKipcbiAqIFRoaXMgaGVscHMgc3BlZWQgdXAgZ2V0dGluZyBwcmV2aW91cyB0cmVlcywgc28gYSBwb3RlbnRpYWxseSBleHBlbnNpdmVcbiAqIHRyZWUgc2VhcmNoIGRvZXNuJ3QgaGF2ZSB0byBiZSBwZXJmb3JtZWQuXG4gKlxuICogKFRoaXMgZG9lcyBhY3R1YWxseSBtYWtlIGEgc2xpZ2h0IHBlcmYgZGlmZmVyZW5jZSBpbiB0aGUgdGVzdHMuKVxuICovXG5mdW5jdGlvbiBpc1JlcGVhdChjYWNoZSwgcGF0aCkge1xuICAgIC8vIENhbid0IGJlIGEgcmVwZWF0IHRoZSBmaXJzdCB0aW1lLlxuICAgIGlmIChjYWNoZS5wYXRoID09IG51bGwpIHJldHVybiBmYWxzZVxuICAgIGlmIChwYXRoLmxlbmd0aCAhPT0gY2FjaGUucGF0aC5sZW5ndGgpIHJldHVybiBmYWxzZVxuICAgIGlmIChwYXRoID09PSBjYWNoZS5wYXRoKSByZXR1cm4gdHJ1ZVxuXG4gICAgLy8gSXQncyB1bmxpa2VseSB0aGUgbmVzdGluZyB3aWxsIGJlIGNvbnNpc3RlbnRseSBtb3JlIHRoYW4gYSBmZXcgbGV2ZWxzXG4gICAgLy8gZGVlcCAoPj0gNSksIHNvIHRoaXMgc2hvdWxkbid0IGJvZyBhbnl0aGluZyBkb3duLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0aC5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAocGF0aFtpXSAhPT0gY2FjaGUucGF0aFtpXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjYWNoZS5wYXRoID0gcGF0aFxuICAgIHJldHVybiB0cnVlXG59XG5cbi8qKlxuICogU3VwZXJjbGFzcyBmb3IgYWxsIHJlcG9ydGVycy4gVGhpcyBjb3ZlcnMgdGhlIHN0YXRlIGZvciBwcmV0dHkgbXVjaCBldmVyeVxuICogcmVwb3J0ZXIuXG4gKlxuICogTm90ZSB0aGF0IGlmIHlvdSBkZWxheSB0aGUgaW5pdGlhbCByZXNldCwgeW91IHN0aWxsIG11c3QgY2FsbCBpdCBiZWZvcmUgdGhlXG4gKiBjb25zdHJ1Y3RvciBmaW5pc2hlcy5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBSZXBvcnRlclxuZnVuY3Rpb24gUmVwb3J0ZXIoVHJlZSwgb3B0cywgbWV0aG9kcywgZGVsYXkpIHtcbiAgICB0aGlzLlRyZWUgPSBUcmVlXG4gICAgdGhpcy5vcHRzID0ge31cbiAgICB0aGlzLm1ldGhvZHMgPSBtZXRob2RzXG4gICAgZGVmYXVsdGlmeSh0aGlzLCBvcHRzLCBcInJlc2V0XCIpXG4gICAgaWYgKCFkZWxheSkgdGhpcy5yZXNldCgpXG59XG5cbm1ldGhvZHMoUmVwb3J0ZXIsIHtcbiAgICByZXNldDogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZVxuICAgICAgICB0aGlzLnRpbWVQcmludGVkID0gZmFsc2VcbiAgICAgICAgdGhpcy50ZXN0cyA9IDBcbiAgICAgICAgdGhpcy5wYXNzID0gMFxuICAgICAgICB0aGlzLmZhaWwgPSAwXG4gICAgICAgIHRoaXMuc2tpcCA9IDBcbiAgICAgICAgdGhpcy5kdXJhdGlvbiA9IDBcbiAgICAgICAgdGhpcy5lcnJvcnMgPSBbXVxuICAgICAgICB0aGlzLnN0YXRlID0gbmV3IFN0YXRlKHRoaXMpXG4gICAgICAgIHRoaXMuYmFzZSA9IG5ldyB0aGlzLlRyZWUodW5kZWZpbmVkKVxuICAgICAgICB0aGlzLmNhY2hlID0ge3BhdGg6IHVuZGVmaW5lZCwgcmVzdWx0OiB1bmRlZmluZWQsIGVuZDogMH1cbiAgICB9LFxuXG4gICAgcHVzaEVycm9yOiBmdW5jdGlvbiAocmVwb3J0KSB7XG4gICAgICAgIHRoaXMuZXJyb3JzLnB1c2gocmVwb3J0KVxuICAgIH0sXG5cbiAgICBnZXQ6IGZ1bmN0aW9uIChwYXRoLCBlbmQpIHtcbiAgICAgICAgaWYgKGVuZCA9PSBudWxsKSBlbmQgPSBwYXRoLmxlbmd0aFxuICAgICAgICBpZiAoZW5kID09PSAwKSByZXR1cm4gdGhpcy5iYXNlXG4gICAgICAgIGlmIChpc1JlcGVhdCh0aGlzLmNhY2hlLCBwYXRoLCBlbmQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYWNoZS5yZXN1bHRcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjaGlsZCA9IHRoaXMuYmFzZVxuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW5kOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBlbnRyeSA9IHBhdGhbaV1cblxuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKGNoaWxkLmNoaWxkcmVuLCBlbnRyeS5pbmRleCkpIHtcbiAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmNoaWxkcmVuW2VudHJ5LmluZGV4XVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmNoaWxkcmVuW2VudHJ5LmluZGV4XSA9IG5ldyB0aGlzLlRyZWUoZW50cnkubmFtZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FjaGUuZW5kID0gZW5kXG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlLnJlc3VsdCA9IGNoaWxkXG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpXG52YXIgU2V0dGluZ3MgPSByZXF1aXJlKFwiLi4vc2V0dGluZ3NcIilcblxuZXhwb3J0cy5zeW1ib2xzID0gU2V0dGluZ3Muc3ltYm9sc1xuZXhwb3J0cy53aW5kb3dXaWR0aCA9IFNldHRpbmdzLndpbmRvd1dpZHRoXG5leHBvcnRzLm5ld2xpbmUgPSBTZXR0aW5ncy5uZXdsaW5lXG5cbi8qXG4gKiBTdGFjayBub3JtYWxpemF0aW9uXG4gKi9cblxuLy8gRXhwb3J0ZWQgZm9yIGRlYnVnZ2luZ1xuZXhwb3J0cy5yZWFkU3RhY2sgPSByZWFkU3RhY2tcbmZ1bmN0aW9uIHJlYWRTdGFjayhlKSB7XG4gICAgdmFyIHN0YWNrID0gVXRpbC5nZXRTdGFjayhlKVxuXG4gICAgLy8gSWYgaXQgZG9lc24ndCBzdGFydCB3aXRoIHRoZSBtZXNzYWdlLCBqdXN0IHJldHVybiB0aGUgc3RhY2suXG4gICAgLy8gIEZpcmVmb3gsIFNhZmFyaSAgICAgICAgICAgICAgICBDaHJvbWUsIElFXG4gICAgaWYgKC9eKEApP1xcUytcXDpcXGQrLy50ZXN0KHN0YWNrKSB8fCAvXlxccyphdC8udGVzdChzdGFjaykpIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdExpbmVCcmVha3Moc3RhY2spXG4gICAgfVxuXG4gICAgdmFyIGluZGV4ID0gc3RhY2suaW5kZXhPZihlLm1lc3NhZ2UpXG5cbiAgICBpZiAoaW5kZXggPCAwKSByZXR1cm4gZm9ybWF0TGluZUJyZWFrcyhVdGlsLmdldFN0YWNrKGUpKVxuICAgIHZhciByZSA9IC9cXHI/XFxuL2dcblxuICAgIHJlLmxhc3RJbmRleCA9IGluZGV4ICsgZS5tZXNzYWdlLmxlbmd0aFxuICAgIGlmICghcmUudGVzdChzdGFjaykpIHJldHVybiBcIlwiXG4gICAgcmV0dXJuIGZvcm1hdExpbmVCcmVha3Moc3RhY2suc2xpY2UocmUubGFzdEluZGV4KSlcbn1cblxuZnVuY3Rpb24gZm9ybWF0TGluZUJyZWFrcyhzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFteXFxyXFxuXFxTXSskL2csIFwiXCIpXG4gICAgICAgIC5yZXBsYWNlKC9cXHMqKFxccj9cXG58XFxyKVxccyovZywgU2V0dGluZ3MubmV3bGluZSgpKVxufVxuXG5leHBvcnRzLmdldFN0YWNrID0gZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAoIShlIGluc3RhbmNlb2YgRXJyb3IpKSByZXR1cm4gZm9ybWF0TGluZUJyZWFrcyhVdGlsLmdldFN0YWNrKGUpKVxuICAgIHZhciBkZXNjcmlwdGlvbiA9IChlLm5hbWUgKyBcIjogXCIgKyBlLm1lc3NhZ2UpXG4gICAgICAgIC5yZXBsYWNlKC9cXHMrJC9nbSwgXCJcIilcbiAgICAgICAgLnJlcGxhY2UoL1xccj9cXG58XFxyL2csIFNldHRpbmdzLm5ld2xpbmUoKSlcbiAgICB2YXIgc3RyaXBwZWQgPSByZWFkU3RhY2soZSlcblxuICAgIGlmIChzdHJpcHBlZCA9PT0gXCJcIikgcmV0dXJuIGRlc2NyaXB0aW9uXG4gICAgcmV0dXJuIGRlc2NyaXB0aW9uICsgU2V0dGluZ3MubmV3bGluZSgpICsgc3RyaXBwZWRcbn1cblxudmFyIENvbG9ycyA9IGV4cG9ydHMuQ29sb3JzID0gU2V0dGluZ3MuQ29sb3JzXG5cbi8vIENvbG9yIHBhbGV0dGUgcHVsbGVkIGZyb20gTW9jaGFcbmZ1bmN0aW9uIGNvbG9yVG9OdW1iZXIobmFtZSkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuICAgIGNhc2UgXCJwYXNzXCI6IHJldHVybiA5MFxuICAgIGNhc2UgXCJmYWlsXCI6IHJldHVybiAzMVxuXG4gICAgY2FzZSBcImJyaWdodCBwYXNzXCI6IHJldHVybiA5MlxuICAgIGNhc2UgXCJicmlnaHQgZmFpbFwiOiByZXR1cm4gOTFcbiAgICBjYXNlIFwiYnJpZ2h0IHllbGxvd1wiOiByZXR1cm4gOTNcblxuICAgIGNhc2UgXCJza2lwXCI6IHJldHVybiAzNlxuICAgIGNhc2UgXCJzdWl0ZVwiOiByZXR1cm4gMFxuICAgIGNhc2UgXCJwbGFpblwiOiByZXR1cm4gMFxuXG4gICAgY2FzZSBcImVycm9yIHRpdGxlXCI6IHJldHVybiAwXG4gICAgY2FzZSBcImVycm9yIG1lc3NhZ2VcIjogcmV0dXJuIDMxXG4gICAgY2FzZSBcImVycm9yIHN0YWNrXCI6IHJldHVybiA5MFxuXG4gICAgY2FzZSBcImNoZWNrbWFya1wiOiByZXR1cm4gMzJcbiAgICBjYXNlIFwiZmFzdFwiOiByZXR1cm4gOTBcbiAgICBjYXNlIFwibWVkaXVtXCI6IHJldHVybiAzM1xuICAgIGNhc2UgXCJzbG93XCI6IHJldHVybiAzMVxuICAgIGNhc2UgXCJncmVlblwiOiByZXR1cm4gMzJcbiAgICBjYXNlIFwibGlnaHRcIjogcmV0dXJuIDkwXG5cbiAgICBjYXNlIFwiZGlmZiBndXR0ZXJcIjogcmV0dXJuIDkwXG4gICAgY2FzZSBcImRpZmYgYWRkZWRcIjogcmV0dXJuIDMyXG4gICAgY2FzZSBcImRpZmYgcmVtb3ZlZFwiOiByZXR1cm4gMzFcbiAgICBkZWZhdWx0OiB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBuYW1lOiBcXFwiXCIgKyBuYW1lICsgXCJcXFwiXCIpXG4gICAgfVxufVxuXG5leHBvcnRzLmNvbG9yID0gY29sb3JcbmZ1bmN0aW9uIGNvbG9yKG5hbWUsIHN0cikge1xuICAgIGlmIChDb2xvcnMuc3VwcG9ydGVkKCkpIHtcbiAgICAgICAgcmV0dXJuIFwiXFx1MDAxYltcIiArIGNvbG9yVG9OdW1iZXIobmFtZSkgKyBcIm1cIiArIHN0ciArIFwiXFx1MDAxYlswbVwiXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHN0ciArIFwiXCJcbiAgICB9XG59XG5cbmV4cG9ydHMuc2V0Q29sb3IgPSBmdW5jdGlvbiAoXykge1xuICAgIGlmIChfLm9wdHMuY29sb3IgIT0gbnVsbCkgQ29sb3JzLm1heWJlU2V0KF8ub3B0cy5jb2xvcilcbn1cblxuZXhwb3J0cy51bnNldENvbG9yID0gZnVuY3Rpb24gKF8pIHtcbiAgICBpZiAoXy5vcHRzLmNvbG9yICE9IG51bGwpIENvbG9ycy5tYXliZVJlc3RvcmUoKVxufVxuXG52YXIgU3RhdHVzID0gZXhwb3J0cy5TdGF0dXMgPSBPYmplY3QuZnJlZXplKHtcbiAgICBVbmtub3duOiAwLFxuICAgIFNraXBwZWQ6IDEsXG4gICAgUGFzc2luZzogMixcbiAgICBGYWlsaW5nOiAzLFxufSlcblxuZXhwb3J0cy5UcmVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlXG4gICAgdGhpcy5zdGF0dXMgPSBTdGF0dXMuVW5rbm93blxuICAgIHRoaXMuY2hpbGRyZW4gPSBPYmplY3QuY3JlYXRlKG51bGwpXG59XG5cbmV4cG9ydHMuZGVmYXVsdGlmeSA9IGZ1bmN0aW9uIChfLCBvcHRzLCBwcm9wKSB7XG4gICAgaWYgKF8ubWV0aG9kcy5hY2NlcHRzLmluZGV4T2YocHJvcCkgPj0gMCkge1xuICAgICAgICB2YXIgdXNlZCA9IG9wdHMgIT0gbnVsbCAmJiB0eXBlb2Ygb3B0c1twcm9wXSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICA/IG9wdHNcbiAgICAgICAgICAgIDogU2V0dGluZ3MuZGVmYXVsdE9wdHMoKVxuXG4gICAgICAgIF8ub3B0c1twcm9wXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodXNlZFtwcm9wXS5hcHBseSh1c2VkLCBhcmd1bWVudHMpKVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBqb2luUGF0aChyZXBvcnRQYXRoKSB7XG4gICAgdmFyIHBhdGggPSBcIlwiXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcG9ydFBhdGgubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcGF0aCArPSBcIiBcIiArIHJlcG9ydFBhdGhbaV0ubmFtZVxuICAgIH1cblxuICAgIHJldHVybiBwYXRoLnNsaWNlKDEpXG59XG5cbmV4cG9ydHMuam9pblBhdGggPSBmdW5jdGlvbiAocmVwb3J0KSB7XG4gICAgcmV0dXJuIGpvaW5QYXRoKHJlcG9ydC5wYXRoKVxufVxuXG5leHBvcnRzLnNwZWVkID0gZnVuY3Rpb24gKHJlcG9ydCkge1xuICAgIGlmIChyZXBvcnQuZHVyYXRpb24gPj0gcmVwb3J0LnNsb3cpIHJldHVybiBcInNsb3dcIlxuICAgIGlmIChyZXBvcnQuZHVyYXRpb24gPj0gcmVwb3J0LnNsb3cgLyAyKSByZXR1cm4gXCJtZWRpdW1cIlxuICAgIGlmIChyZXBvcnQuZHVyYXRpb24gPj0gMCkgcmV0dXJuIFwiZmFzdFwiXG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJEdXJhdGlvbiBtdXN0IG5vdCBiZSBuZWdhdGl2ZVwiKVxufVxuXG5leHBvcnRzLmZvcm1hdFRpbWUgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBzID0gMTAwMCAvKiBtcyAqL1xuICAgIHZhciBtID0gNjAgKiBzXG4gICAgdmFyIGggPSA2MCAqIG1cbiAgICB2YXIgZCA9IDI0ICogaFxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChtcykge1xuICAgICAgICBpZiAobXMgPj0gZCkgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArIFwiZFwiXG4gICAgICAgIGlmIChtcyA+PSBoKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIGgpICsgXCJoXCJcbiAgICAgICAgaWYgKG1zID49IG0pIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gbSkgKyBcIm1cIlxuICAgICAgICBpZiAobXMgPj0gcykgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArIFwic1wiXG4gICAgICAgIHJldHVybiBtcyArIFwibXNcIlxuICAgIH1cbn0pKClcblxuZXhwb3J0cy5mb3JtYXRSZXN0ID0gZnVuY3Rpb24gKHJlcG9ydCkge1xuICAgIGlmICghcmVwb3J0LmlzSG9vaykgcmV0dXJuIFwiXCJcbiAgICB2YXIgcGF0aCA9IFwiIChcIlxuXG4gICAgaWYgKHJlcG9ydC5yb290UGF0aC5sZW5ndGgpIHtcbiAgICAgICAgcGF0aCArPSByZXBvcnQuc3RhZ2VcbiAgICAgICAgaWYgKHJlcG9ydC5uYW1lKSBwYXRoICs9IFwiIOKAkiBcIiArIHJlcG9ydC5uYW1lXG4gICAgICAgIGlmIChyZXBvcnQucGF0aC5sZW5ndGggPiByZXBvcnQucm9vdFBhdGgubGVuZ3RoICsgMSkge1xuICAgICAgICAgICAgcGF0aCArPSBcIiwgaW4gXCIgKyBqb2luUGF0aChyZXBvcnQucm9vdFBhdGgpXG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXRoICs9IFwiZ2xvYmFsIFwiICsgcmVwb3J0LnN0YWdlXG4gICAgICAgIGlmIChyZXBvcnQubmFtZSkgcGF0aCArPSBcIiDigJIgXCIgKyByZXBvcnQubmFtZVxuICAgIH1cblxuICAgIHJldHVybiBwYXRoICsgXCIpXCJcbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8vIEdlbmVyYWwgQ0xJIGFuZCByZXBvcnRlciBzZXR0aW5ncy4gSWYgc29tZXRoaW5nIG5lZWRzIHRvXG5cbnZhciBDb25zb2xlID0gcmVxdWlyZShcIi4vcmVwbGFjZWQvY29uc29sZVwiKVxuXG52YXIgd2luZG93V2lkdGggPSBDb25zb2xlLndpbmRvd1dpZHRoXG52YXIgbmV3bGluZSA9IENvbnNvbGUubmV3bGluZVxudmFyIFN5bWJvbHMgPSBDb25zb2xlLlN5bWJvbHNcbnZhciBkZWZhdWx0T3B0cyA9IENvbnNvbGUuZGVmYXVsdE9wdHNcblxuZXhwb3J0cy53aW5kb3dXaWR0aCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHdpbmRvd1dpZHRoIH1cbmV4cG9ydHMubmV3bGluZSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ld2xpbmUgfVxuZXhwb3J0cy5zeW1ib2xzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gU3ltYm9scyB9XG5leHBvcnRzLmRlZmF1bHRPcHRzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gZGVmYXVsdE9wdHMgfVxuXG5leHBvcnRzLnNldFdpbmRvd1dpZHRoID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiB3aW5kb3dXaWR0aCA9IHZhbHVlIH1cbmV4cG9ydHMuc2V0TmV3bGluZSA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gbmV3bGluZSA9IHZhbHVlIH1cbmV4cG9ydHMuc2V0U3ltYm9scyA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gU3ltYm9scyA9IHZhbHVlIH1cbmV4cG9ydHMuc2V0RGVmYXVsdE9wdHMgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIGRlZmF1bHRPcHRzID0gdmFsdWUgfVxuXG4vLyBDb25zb2xlLmNvbG9yU3VwcG9ydCBpcyBhIG1hc2sgd2l0aCB0aGUgZm9sbG93aW5nIGJpdHM6XG4vLyAweDEgLSBpZiBzZXQsIGNvbG9ycyBzdXBwb3J0ZWQgYnkgZGVmYXVsdFxuLy8gMHgyIC0gaWYgc2V0LCBmb3JjZSBjb2xvciBzdXBwb3J0XG4vL1xuLy8gVGhpcyBpcyBwdXJlbHkgYW4gaW1wbGVtZW50YXRpb24gZGV0YWlsLCBhbmQgaXMgaW52aXNpYmxlIHRvIHRoZSBvdXRzaWRlXG4vLyB3b3JsZC5cbnZhciBjb2xvclN1cHBvcnQgPSBDb25zb2xlLmNvbG9yU3VwcG9ydFxudmFyIG1hc2sgPSBjb2xvclN1cHBvcnRcblxuZXhwb3J0cy5Db2xvcnMgPSB7XG4gICAgc3VwcG9ydGVkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAobWFzayAmIDB4MSkgIT09IDBcbiAgICB9LFxuXG4gICAgZm9yY2VkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAobWFzayAmIDB4MikgIT09IDBcbiAgICB9LFxuXG4gICAgbWF5YmVTZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAoKG1hc2sgJiAweDIpID09PSAwKSBtYXNrID0gdmFsdWUgPyAweDEgOiAwXG4gICAgfSxcblxuICAgIG1heWJlUmVzdG9yZTogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoKG1hc2sgJiAweDIpID09PSAwKSBtYXNrID0gY29sb3JTdXBwb3J0ICYgMHgxXG4gICAgfSxcblxuICAgIC8vIE9ubHkgZm9yIGRlYnVnZ2luZ1xuICAgIGZvcmNlU2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgbWFzayA9IHZhbHVlID8gMHgzIDogMHgyXG4gICAgfSxcblxuICAgIGZvcmNlUmVzdG9yZTogZnVuY3Rpb24gKCkge1xuICAgICAgICBtYXNrID0gY29sb3JTdXBwb3J0XG4gICAgfSxcblxuICAgIGdldFN1cHBvcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1cHBvcnRlZDogKGNvbG9yU3VwcG9ydCAmIDB4MSkgIT09IDAsXG4gICAgICAgICAgICBmb3JjZWQ6IChjb2xvclN1cHBvcnQgJiAweDIpICE9PSAwLFxuICAgICAgICB9XG4gICAgfSxcblxuICAgIHNldFN1cHBvcnQ6IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgICAgIG1hc2sgPSBjb2xvclN1cHBvcnQgPVxuICAgICAgICAgICAgKG9wdHMuc3VwcG9ydGVkID8gMHgxIDogMCkgfCAob3B0cy5mb3JjZWQgPyAweDIgOiAwKVxuICAgIH0sXG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgbWV0aG9kcyA9IHJlcXVpcmUoXCIuL21ldGhvZHNcIilcblxuZXhwb3J0cy5nZXRUeXBlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBcIm51bGxcIlxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIFwiYXJyYXlcIlxuICAgIHJldHVybiB0eXBlb2YgdmFsdWVcbn1cblxuLy8gUGhhbnRvbUpTLCBJRSwgYW5kIHBvc3NpYmx5IEVkZ2UgZG9uJ3Qgc2V0IHRoZSBzdGFjayB0cmFjZSB1bnRpbCB0aGUgZXJyb3IgaXNcbi8vIHRocm93bi4gTm90ZSB0aGF0IHRoaXMgcHJlZmVycyBhbiBleGlzdGluZyBzdGFjayBmaXJzdCwgc2luY2Ugbm9uLW5hdGl2ZVxuLy8gZXJyb3JzIGxpa2VseSBhbHJlYWR5IGNvbnRhaW4gdGhpcy4gTm90ZSB0aGF0IHRoaXMgaXNuJ3QgbmVjZXNzYXJ5IGluIHRoZVxuLy8gQ0xJIC0gdGhhdCBvbmx5IHRhcmdldHMgTm9kZS5cbmV4cG9ydHMuZ2V0U3RhY2sgPSBmdW5jdGlvbiAoZSkge1xuICAgIHZhciBzdGFjayA9IGUuc3RhY2tcblxuICAgIGlmICghKGUgaW5zdGFuY2VvZiBFcnJvcikgfHwgc3RhY2sgIT0gbnVsbCkgcmV0dXJuIHN0YWNrXG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBlXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZS5zdGFja1xuICAgIH1cbn1cblxuZXhwb3J0cy5wY2FsbCA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmMoZnVuY3Rpb24gKGUsIHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gZSAhPSBudWxsID8gcmVqZWN0KGUpIDogcmVzb2x2ZSh2YWx1ZSlcbiAgICAgICAgfSlcbiAgICB9KVxufVxuXG5leHBvcnRzLnBlYWNoID0gZnVuY3Rpb24gKGxpc3QsIGZ1bmMpIHtcbiAgICB2YXIgbGVuID0gbGlzdC5sZW5ndGhcbiAgICB2YXIgcCA9IFByb21pc2UucmVzb2x2ZSgpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHAgPSBwLnRoZW4oZnVuYy5iaW5kKHVuZGVmaW5lZCwgbGlzdFtpXSwgaSkpXG4gICAgfVxuXG4gICAgcmV0dXJuIHBcbn1cblxuLyoqXG4gKiBBIGxhenkgYWNjZXNzb3IsIGNvbXBsZXRlIHdpdGggdGhyb3duIGVycm9yIG1lbW9pemF0aW9uIGFuZCBhIGRlY2VudCBhbW91bnRcbiAqIG9mIG9wdGltaXphdGlvbiwgc2luY2UgaXQncyB1c2VkIGluIGEgbG90IG9mIGNvZGUuXG4gKlxuICogTm90ZSB0aGF0IHRoaXMgdXNlcyByZWZlcmVuY2UgaW5kaXJlY3Rpb24gYW5kIGRpcmVjdCBtdXRhdGlvbiB0byBrZWVwIG9ubHlcbiAqIGp1c3QgdGhlIGNvbXB1dGF0aW9uIG5vbi1jb25zdGFudCwgc28gZW5naW5lcyBjYW4gYXZvaWQgY2xvc3VyZSBhbGxvY2F0aW9uLlxuICogQWxzbywgYGNyZWF0ZWAgaXMgaW50ZW50aW9uYWxseSBrZXB0ICpvdXQqIG9mIGFueSBjbG9zdXJlLCBzbyBpdCBjYW4gYmUgbW9yZVxuICogZWFzaWx5IGNvbGxlY3RlZC5cbiAqL1xuZnVuY3Rpb24gTGF6eShjcmVhdGUpIHtcbiAgICB0aGlzLnZhbHVlID0gY3JlYXRlXG4gICAgdGhpcy5nZXQgPSB0aGlzLmluaXRcbn1cblxubWV0aG9kcyhMYXp5LCB7XG4gICAgcmVjdXJzaXZlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJMYXp5IGZ1bmN0aW9ucyBtdXN0IG5vdCBiZSBjYWxsZWQgcmVjdXJzaXZlbHkhXCIpXG4gICAgfSxcblxuICAgIHJldHVybjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZVxuICAgIH0sXG5cbiAgICB0aHJvdzogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aHJvdyB0aGlzLnZhbHVlXG4gICAgfSxcblxuICAgIGluaXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5nZXQgPSB0aGlzLnJlY3Vyc2l2ZVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gKDAsIHRoaXMudmFsdWUpKClcbiAgICAgICAgICAgIHRoaXMuZ2V0ID0gdGhpcy5yZXR1cm5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBlXG4gICAgICAgICAgICB0aGlzLmdldCA9IHRoaXMudGhyb3dcbiAgICAgICAgICAgIHRocm93IHRoaXMudmFsdWVcbiAgICAgICAgfVxuICAgIH0sXG59KVxuXG5leHBvcnRzLmxhenkgPSBmdW5jdGlvbiAoY3JlYXRlKSB7XG4gICAgdmFyIHJlZiA9IG5ldyBMYXp5KGNyZWF0ZSlcblxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiByZWYuZ2V0KClcbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vLyBUbyBzdXBwcmVzcyBkZXByZWNhdGlvbiBtZXNzYWdlc1xudmFyIHN1cHByZXNzRGVwcmVjYXRpb24gPSB0cnVlXG5cbmV4cG9ydHMuc2hvd0RlcHJlY2F0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHN1cHByZXNzRGVwcmVjYXRpb24gPSBmYWxzZVxufVxuXG5leHBvcnRzLmhpZGVEZXByZWNhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICBzdXBwcmVzc0RlcHJlY2F0aW9uID0gdHJ1ZVxufVxuXG52YXIgY29uc29sZSA9IGdsb2JhbC5jb25zb2xlXG52YXIgc2hvdWxkUHJpbnQgPSBjb25zb2xlICE9IG51bGwgJiYgdHlwZW9mIGNvbnNvbGUud2FybiA9PT0gXCJmdW5jdGlvblwiICYmXG4gICAgIShnbG9iYWwucHJvY2VzcyAhPSBudWxsICYmIGdsb2JhbC5wcm9jZXNzLmVudiAhPSBudWxsICYmXG4gICAgICAgIGdsb2JhbC5wcm9jZXNzLmVudi5OT19NSUdSQVRFX1dBUk4pXG5cbmV4cG9ydHMud2FybiA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoc2hvdWxkUHJpbnQgJiYgIXN1cHByZXNzRGVwcmVjYXRpb24pIHtcbiAgICAgICAgY29uc29sZS53YXJuLmFwcGx5KGNvbnNvbGUsIGFyZ3VtZW50cylcbiAgICB9XG59XG5cbmV4cG9ydHMuZGVwcmVjYXRlID0gZnVuY3Rpb24gKG1lc3NhZ2UsIGZ1bmMpIHtcbiAgICB2YXIgcHJpbnRlZCA9ICFzaG91bGRQcmludFxuXG4gICAgLyoqIEB0aGlzICovXG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCFzdXBwcmVzc0RlcHJlY2F0aW9uKSB7XG4gICAgICAgICAgICBpZiAoIXByaW50ZWQpIHtcbiAgICAgICAgICAgICAgICBwcmludGVkID0gdHJ1ZVxuICAgICAgICAgICAgICAgIGNvbnNvbGUudHJhY2UoKVxuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihtZXNzYWdlKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBtZXNzYWdlID0gdW5kZWZpbmVkXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLyoqXG4gKiBCYWNrcG9ydCB3cmFwcGVyIHRvIHdhcm4gYWJvdXQgbW9zdCBvZiB0aGUgbWFqb3IgYnJlYWtpbmcgY2hhbmdlcyBmcm9tIHRoZVxuICogbGFzdCBtYWpvciB2ZXJzaW9uLCBhbmQgdG8gaGVscCBtZSBrZWVwIHRyYWNrIG9mIGFsbCB0aGUgY2hhbmdlcy5cbiAqXG4gKiBJdCBjb25zaXN0cyBvZiBzb2xlbHkgaW50ZXJuYWwgbW9ua2V5IHBhdGNoaW5nIHRvIHJldml2ZSBzdXBwb3J0IG9mIHByZXZpb3VzXG4gKiB2ZXJzaW9ucywgYWx0aG91Z2ggSSB0cmllZCB0byBsaW1pdCBob3cgbXVjaCBrbm93bGVkZ2Ugb2YgdGhlIGludGVybmFscyB0aGlzXG4gKiByZXF1aXJlcy5cbiAqL1xuXG52YXIgQ29tbW9uID0gcmVxdWlyZShcIi4vY29tbW9uXCIpXG52YXIgSW50ZXJuYWwgPSByZXF1aXJlKFwiLi4vaW50ZXJuYWxcIilcbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL2xpYi9tZXRob2RzXCIpXG52YXIgUmVwb3J0ID0gcmVxdWlyZShcIi4uL2xpYi9jb3JlL3JlcG9ydHNcIikuUmVwb3J0XG52YXIgUmVmbGVjdCA9IHJlcXVpcmUoXCIuLi9saWIvYXBpL3JlZmxlY3RcIilcbnZhciBUaGFsbGl1bSA9IHJlcXVpcmUoXCIuLi9saWIvYXBpL3RoYWxsaXVtXCIpXG5cbnZhciBhc3NlcnQgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0XCIpXG5cbi8qICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKlxuICogLSBgcmVmbGVjdC5jaGVja0luaXQoKWAgaXMgZGVwcmVjYXRlZCBpbiBmYXZvciBvZiBgcmVmbGVjdC5sb2NrZWRgIGFuZCAgICAqXG4gKiAgIGVpdGhlciBjb21wbGFpbmluZyB5b3Vyc2VsZiBvciBqdXN0IHVzaW5nIGByZWZsZWN0LmN1cnJlbnRgIHRvIGFkZCAgICAgICpcbiAqICAgdGhpbmdzLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqL1xubWV0aG9kcyhSZWZsZWN0LCB7XG4gICAgY2hlY2tJbml0OiBDb21tb24uZGVwcmVjYXRlKFxuICAgICAgICBcImByZWZsZWN0LmNoZWNrSW5pdGAgaXMgZGVwcmVjYXRlZC4gVXNlIGByZWZsZWN0LmN1cnJlbnRgIGZvciB0aGUgXCIgK1xuICAgICAgICBcImN1cnJlbnQgdGVzdCBvciB1c2UgYHJlZmxlY3QubG9ja2VkYCBhbmQgY3JlYXRlIGFuZCB0aHJvdyB0aGUgZXJyb3IgXCIgK1xuICAgICAgICBcInlvdXJzZWxmLlwiLFxuICAgICAgICAvKiogQHRoaXMgKi8gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMubG9ja2VkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwiSXQgaXMgb25seSBzYWZlIHRvIGNhbGwgdGVzdCBcIiArXG4gICAgICAgICAgICAgICAgICAgIFwibWV0aG9kcyBkdXJpbmcgaW5pdGlhbGl6YXRpb25cIilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSksXG59KVxuXG4vKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICpcbiAqIC0gYHQuYXN5bmNgIC0+IGB0LnRlc3RgLCB3aGljaCBub3cgc3VwcG9ydHMgcHJvbWlzZXMuICAgICAgICAgICAgICAgICAgICAgKlxuICogLSBBbGwgdGVzdHMgYXJlIG5vdyBhc3luYy4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICovXG5cbnZhciB0ZXN0ID0gVGhhbGxpdW0ucHJvdG90eXBlLnRlc3RcblxuZnVuY3Rpb24gcnVuQXN5bmMoY2FsbGJhY2ssIHQsIHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciByZXNvbHZlZCA9IGZhbHNlXG4gICAgdmFyIGdlbiA9IGNhbGxiYWNrLmNhbGwodCwgdCwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICBpZiAocmVzb2x2ZWQpIHJldHVyblxuICAgICAgICBDb21tb24ud2FybihcImB0LmFzeW5jYCBpcyBkZXByZWNhdGVkLiBcIiArXG4gICAgICAgICAgICBcIlVzZSBgdC50ZXN0YCBhbmQgcmV0dXJuIGEgcHJvbWlzZSBpbnN0ZWFkLlwiKVxuXG4gICAgICAgIHJlc29sdmVkID0gdHJ1ZVxuICAgICAgICBpZiAoZXJyICE9IG51bGwpIHJlamVjdChlcnIpXG4gICAgICAgIGVsc2UgcmVzb2x2ZSgpXG4gICAgfSlcblxuICAgIGlmIChyZXNvbHZlZCkgcmV0dXJuXG5cbiAgICBpZiAodHlwZW9mIGdlbi5uZXh0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgLy8gQWxsb3cgdGhlIG1pZ3JhdGlvbiBwYXRoIHRvIHN0YW5kYXJkIHRoZW5hYmxlcy5cbiAgICAgICAgcmVzb2x2ZShnZW4pXG4gICAgICAgIHJldHVyblxuICAgIH1cblxuICAgIENvbW1vbi53YXJuKFwiYHQuYXN5bmNgIGlzIGRlcHJlY2F0ZWQuIFVzZSBgdC50ZXN0YCBhbmQgZWl0aGVyIHJldHVybiBhIFwiICtcbiAgICAgICAgXCJwcm9taXNlIG9yIHVzZSBgY29gL0VTMjAxNyBhc3luYyBmdW5jdGlvbnMgaW5zdGVhZC5cIilcblxuICAgIC8vIFRoaXMgaXMgYSBtb2RpZmllZCB2ZXJzaW9uIG9mIHRoZSBhc3luYy1hd2FpdCBvZmZpY2lhbCwgbm9uLW5vcm1hdGl2ZVxuICAgIC8vIGRlc3VnYXJpbmcgaGVscGVyLCBmb3IgYmV0dGVyIGVycm9yIGNoZWNraW5nIGFuZCBhZGFwdGVkIHRvIGFjY2VwdCBhblxuICAgIC8vIGFscmVhZHktaW5zdGFudGlhdGVkIGl0ZXJhdG9yIGluc3RlYWQgb2YgYSBnZW5lcmF0b3IuXG4gICAgZnVuY3Rpb24gaXRlcmF0ZShuZXh0KSB7XG4gICAgICAgIC8vIGZpbmlzaGVkIHdpdGggc3VjY2VzcywgcmVzb2x2ZSB0aGUgcHJvbWlzZVxuICAgICAgICBpZiAobmV4dC5kb25lKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5leHQudmFsdWUpXG5cbiAgICAgICAgLy8gbm90IGZpbmlzaGVkLCBjaGFpbiBvZmYgdGhlIHlpZWxkZWQgcHJvbWlzZSBhbmQgc3RlcCBhZ2FpblxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5leHQudmFsdWUpLnRoZW4oXG4gICAgICAgICAgICBmdW5jdGlvbiAodikgeyByZXR1cm4gaXRlcmF0ZShnZW4ubmV4dCh2KSkgfSxcbiAgICAgICAgICAgIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBnZW4udGhyb3cgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaXRlcmF0ZShnZW4udGhyb3coZSkpXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgfVxuXG4gICAgaXRlcmF0ZShnZW4ubmV4dCh1bmRlZmluZWQpKS50aGVuKHJlc29sdmUsIHJlamVjdClcbn1cblxubWV0aG9kcyhUaGFsbGl1bSwge1xuICAgIGFzeW5jOiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAvLyBSZXVzZSB0aGUgbm9ybWFsIGVycm9yIGhhbmRsaW5nLlxuICAgICAgICAgICAgcmV0dXJuIHRlc3QuYXBwbHkodGhpcywgYXJndW1lbnRzKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRlc3QuY2FsbCh0aGlzLCBuYW1lLCBmdW5jdGlvbiAodCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBydW5Bc3luYyhjYWxsYmFjaywgdCwgcmVzb2x2ZSwgcmVqZWN0KVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfSxcblxuICAgIGFzeW5jU2tpcDogQ29tbW9uLmRlcHJlY2F0ZShcbiAgICAgICAgXCJgdC5hc3luY1NraXBgIGlzIGRlcHJlY2F0ZWQuIFVzZSBgdC50ZXN0U2tpcGAgaW5zdGVhZC5cIixcbiAgICAgICAgVGhhbGxpdW0ucHJvdG90eXBlLnRlc3RTa2lwKSxcbn0pXG5cbm1ldGhvZHMoUmVmbGVjdCwge1xuICAgIGdldCBpc0FzeW5jKCkge1xuICAgICAgICBDb21tb24ud2FybihcIlRlc3RzIGFyZSBub3cgYWx3YXlzIGFzeW5jLiBZb3Ugbm8gbG9uZ2VyIG5lZWQgdG8gXCIgK1xuICAgICAgICAgICAgXCJoYW5kbGUgdGhlIG90aGVyIGNhc2VcIilcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9LFxufSlcblxuLyogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqXG4gKiBgcmVmbGVjdC5kZWZpbmVgLCBgdC5kZWZpbmVgLCBgcmVmbGVjdC53cmFwYCwgYW5kIGByZWZsZWN0LmFkZGAsIGFyZSBhbGwgICpcbiAqIHJlbW92ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqL1xuXG5mdW5jdGlvbiBpc0xvY2tlZChtZXRob2QpIHtcbiAgICByZXR1cm4gbWV0aG9kID09PSBcIl9cIiB8fFxuICAgICAgICBtZXRob2QgPT09IFwicmVmbGVjdFwiIHx8XG4gICAgICAgIG1ldGhvZCA9PT0gXCJvbmx5XCIgfHxcbiAgICAgICAgbWV0aG9kID09PSBcInVzZVwiIHx8XG4gICAgICAgIG1ldGhvZCA9PT0gXCJyZXBvcnRlclwiIHx8XG4gICAgICAgIG1ldGhvZCA9PT0gXCJkZWZpbmVcIiB8fFxuICAgICAgICBtZXRob2QgPT09IFwidGltZW91dFwiIHx8XG4gICAgICAgIG1ldGhvZCA9PT0gXCJzbG93XCIgfHxcbiAgICAgICAgbWV0aG9kID09PSBcInJ1blwiIHx8XG4gICAgICAgIG1ldGhvZCA9PT0gXCJ0ZXN0XCIgfHxcbiAgICAgICAgbWV0aG9kID09PSBcInRlc3RTa2lwXCIgfHxcbiAgICAgICAgbWV0aG9kID09PSBcImFzeW5jXCIgfHxcbiAgICAgICAgbWV0aG9kID09PSBcImFzeW5jU2tpcFwiXG59XG5cbmZ1bmN0aW9uIGdldEVudW1lcmFibGVTeW1ib2xzKGtleXMsIG9iamVjdCkge1xuICAgIHZhciBzeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmplY3QpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHN5bWJvbHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHN5bSA9IHN5bWJvbHNbaV1cblxuICAgICAgICBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzeW0pLmVudW1lcmFibGUpIGtleXMucHVzaChzeW0pXG4gICAgfVxufVxuXG4vLyBUaGlzIGhhbmRsZXMgbmFtZSArIGZ1bmMgdnMgb2JqZWN0IHdpdGggbWV0aG9kcy5cbmZ1bmN0aW9uIGl0ZXJhdGVTZXR0ZXIodGVzdCwgbmFtZSwgZnVuYywgaXRlcmF0b3IpIHtcbiAgICAvLyBDaGVjayBib3RoIHRoZSBuYW1lIGFuZCBmdW5jdGlvbiwgc28gRVM2IHN5bWJvbCBwb2x5ZmlsbHMgKHdoaWNoIHVzZVxuICAgIC8vIG9iamVjdHMgc2luY2UgaXQncyBpbXBvc3NpYmxlIHRvIGZ1bGx5IHBvbHlmaWxsIHByaW1pdGl2ZXMpIHdvcmsuXG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSBcIm9iamVjdFwiICYmIG5hbWUgIT0gbnVsbCAmJiBmdW5jID09IG51bGwpIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhuYW1lKVxuXG4gICAgICAgIGlmICh0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICBnZXRFbnVtZXJhYmxlU3ltYm9scyhrZXlzLCBuYW1lKVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0ga2V5c1tpXVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG5hbWVba2V5XSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGJvZHkgdG8gYmUgYSBmdW5jdGlvblwiKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0ZXN0Lm1ldGhvZHNba2V5XSA9IGl0ZXJhdG9yKHRlc3QsIGtleSwgbmFtZVtrZXldKVxuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHR5cGVvZiBmdW5jICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBib2R5IHRvIGJlIGEgZnVuY3Rpb25cIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRlc3QubWV0aG9kc1tuYW1lXSA9IGl0ZXJhdG9yKHRlc3QsIG5hbWUsIGZ1bmMpXG4gICAgfVxufVxuXG4vKipcbiAqIEB0aGlzIHtTdGF0ZX1cbiAqIFJ1biBgZnVuY2Agd2l0aCBgLi4uYXJnc2Agd2hlbiBhc3NlcnRpb25zIGFyZSBydW4sIG9ubHkgaWYgdGhlIHRlc3QgaXNuJ3RcbiAqIHNraXBwZWQuIFRoaXMgaXMgaW1tZWRpYXRlbHkgZm9yIGJsb2NrIGFuZCBhc3luYyB0ZXN0cywgYnV0IGRlZmVycmVkIGZvclxuICogaW5saW5lIHRlc3RzLiBJdCdzIHVzZWZ1bCBmb3IgaW5saW5lIGFzc2VydGlvbnMuXG4gKi9cbmZ1bmN0aW9uIGF0dGVtcHQoZnVuYywgYSwgYiwgYy8qICwgLi4uYXJncyAqLykge1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIGNhc2UgMDogdGhyb3cgbmV3IFR5cGVFcnJvcihcInVucmVhY2hhYmxlXCIpXG4gICAgY2FzZSAxOiBmdW5jKCk7IHJldHVyblxuICAgIGNhc2UgMjogZnVuYyhhKTsgcmV0dXJuXG4gICAgY2FzZSAzOiBmdW5jKGEsIGIpOyByZXR1cm5cbiAgICBjYXNlIDQ6IGZ1bmMoYSwgYiwgYyk7IHJldHVyblxuICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhciBhcmdzID0gW11cblxuICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSlcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmMuYXBwbHkodW5kZWZpbmVkLCBhcmdzKVxuICAgIH1cbn1cblxuZnVuY3Rpb24gZGVmaW5lQXNzZXJ0aW9uKHRlc3QsIG5hbWUsIGZ1bmMpIHtcbiAgICAvLyBEb24ndCBsZXQgbmF0aXZlIG1ldGhvZHMgZ2V0IG92ZXJyaWRkZW4gYnkgYXNzZXJ0aW9uc1xuICAgIGlmIChpc0xvY2tlZChuYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIk1ldGhvZCAnXCIgKyBuYW1lICsgXCInIGlzIGxvY2tlZCFcIilcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBydW4oKSB7XG4gICAgICAgIHZhciByZXMgPSBmdW5jLmFwcGx5KHVuZGVmaW5lZCwgYXJndW1lbnRzKVxuXG4gICAgICAgIGlmICh0eXBlb2YgcmVzICE9PSBcIm9iamVjdFwiIHx8IHJlcyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIHJlc3VsdCB0byBiZSBhbiBvYmplY3RcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghcmVzLnRlc3QpIHtcbiAgICAgICAgICAgIGFzc2VydC5mYWlsKHJlcy5tZXNzYWdlLCByZXMpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gLyoqIEB0aGlzICovIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbcnVuXVxuXG4gICAgICAgIGFyZ3MucHVzaC5hcHBseShhcmdzLCBhcmd1bWVudHMpXG4gICAgICAgIGF0dGVtcHQuYXBwbHkodW5kZWZpbmVkLCBhcmdzKVxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cbn1cblxuZnVuY3Rpb24gd3JhcEFzc2VydGlvbih0ZXN0LCBuYW1lLCBmdW5jKSB7XG4gICAgLy8gRG9uJ3QgbGV0IGByZWZsZWN0YCBhbmQgYF9gIGNoYW5nZS5cbiAgICBpZiAobmFtZSA9PT0gXCJyZWZsZWN0XCIgfHwgbmFtZSA9PT0gXCJfXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJNZXRob2QgJ1wiICsgbmFtZSArIFwiJyBpcyBsb2NrZWQhXCIpXG4gICAgfVxuXG4gICAgdmFyIG9sZCA9IHRlc3QubWV0aG9kc1tuYW1lXVxuXG4gICAgaWYgKHR5cGVvZiBvbGQgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgXCJFeHBlY3RlZCB0LlwiICsgbmFtZSArIFwiIHRvIGFscmVhZHkgYmUgYSBmdW5jdGlvblwiKVxuICAgIH1cblxuICAgIC8qKiBAdGhpcyAqL1xuICAgIGZ1bmN0aW9uIGFwcGx5KGEsIGIsIGMsIGQpIHtcbiAgICAgICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgIGNhc2UgMDogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzLCBvbGQuYmluZCh0aGlzKSlcbiAgICAgICAgY2FzZSAxOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIG9sZC5iaW5kKHRoaXMpLCBhKVxuICAgICAgICBjYXNlIDI6IHJldHVybiBmdW5jLmNhbGwodGhpcywgb2xkLmJpbmQodGhpcyksIGEsIGIpXG4gICAgICAgIGNhc2UgMzogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzLCBvbGQuYmluZCh0aGlzKSwgYSwgYiwgYylcbiAgICAgICAgY2FzZSA0OiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIG9sZC5iaW5kKHRoaXMpLCBhLCBiLCBjLCBkKVxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdmFyIGFyZ3MgPSBbb2xkLmJpbmQodGhpcyldXG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJncylcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAvKiogQHRoaXMgKi8gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcmV0ID0gYXBwbHkuYXBwbHkodGhpcywgYXJndW1lbnRzKVxuXG4gICAgICAgIHJldHVybiByZXQgIT09IHVuZGVmaW5lZCA/IHJldCA6IHRoaXNcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGFkZEFzc2VydGlvbih0ZXN0LCBuYW1lLCBmdW5jKSB7XG4gICAgaWYgKHR5cGVvZiB0ZXN0Lm1ldGhvZHNbbmFtZV0gIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk1ldGhvZCAnXCIgKyBuYW1lICsgXCInIGFscmVhZHkgZXhpc3RzIVwiKVxuICAgIH1cblxuICAgIC8qKiBAdGhpcyAqL1xuICAgIGZ1bmN0aW9uIGFwcGx5KGEsIGIsIGMsIGQpIHtcbiAgICAgICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgIGNhc2UgMDogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzLCB0aGlzKVxuICAgICAgICBjYXNlIDE6IHJldHVybiBmdW5jLmNhbGwodGhpcywgdGhpcywgYSlcbiAgICAgICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIHRoaXMsIGEsIGIpXG4gICAgICAgIGNhc2UgMzogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzLCB0aGlzLCBhLCBiLCBjKVxuICAgICAgICBjYXNlIDQ6IHJldHVybiBmdW5jLmNhbGwodGhpcywgdGhpcywgYSwgYiwgYywgZClcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHZhciBhcmdzID0gW3RoaXNdXG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJncylcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAvKiogQHRoaXMgKi8gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcmV0ID0gYXBwbHkuYXBwbHkodGhpcywgYXJndW1lbnRzKVxuXG4gICAgICAgIHJldHVybiByZXQgIT09IHVuZGVmaW5lZCA/IHJldCA6IHRoaXNcbiAgICB9XG59XG5cbm1ldGhvZHMoUmVmbGVjdCwge1xuICAgIGRlZmluZTogQ29tbW9uLmRlcHJlY2F0ZShcbiAgICAgICAgXCJgcmVmbGVjdC5kZWZpbmVgIGlzIGRlcHJlY2F0ZWQuIFVzZSBleHRlcm5hbCBtZXRob2RzIG9yIGRpcmVjdCBhc3NpZ25tZW50IGluc3RlYWQuXCIsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgICAgICAvKiogQHRoaXMgKi8gZnVuY3Rpb24gKG5hbWUsIGZ1bmMpIHtcbiAgICAgICAgICAgIGl0ZXJhdGVTZXR0ZXIodGhpcy5fLmN1cnJlbnQudmFsdWUsIG5hbWUsIGZ1bmMsIGRlZmluZUFzc2VydGlvbilcbiAgICAgICAgfSksXG5cbiAgICB3cmFwOiBDb21tb24uZGVwcmVjYXRlKFxuICAgICAgICBcImByZWZsZWN0LndyYXBgIGlzIGRlcHJlY2F0ZWQuIFVzZSBleHRlcm5hbCBtZXRob2RzIG9yIGRpcmVjdCBhc3NpZ25tZW50IGluc3RlYWQuXCIsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgICAgICAvKiogQHRoaXMgKi8gZnVuY3Rpb24gKG5hbWUsIGZ1bmMpIHtcbiAgICAgICAgICAgIGl0ZXJhdGVTZXR0ZXIodGhpcy5fLmN1cnJlbnQudmFsdWUsIG5hbWUsIGZ1bmMsIHdyYXBBc3NlcnRpb24pXG4gICAgICAgIH0pLFxuXG4gICAgYWRkOiBDb21tb24uZGVwcmVjYXRlKFxuICAgICAgICBcImByZWZsZWN0LmFkZGAgaXMgZGVwcmVjYXRlZC4gVXNlIGV4dGVybmFsIG1ldGhvZHMgb3IgZGlyZWN0IGFzc2lnbm1lbnQgaW5zdGVhZC5cIiwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgICAgIC8qKiBAdGhpcyAqLyBmdW5jdGlvbiAobmFtZSwgZnVuYykge1xuICAgICAgICAgICAgaXRlcmF0ZVNldHRlcih0aGlzLl8uY3VycmVudC52YWx1ZSwgbmFtZSwgZnVuYywgYWRkQXNzZXJ0aW9uKVxuICAgICAgICB9KSxcbn0pXG5cbm1ldGhvZHMoVGhhbGxpdW0sIHtcbiAgICBkZWZpbmU6IENvbW1vbi5kZXByZWNhdGUoXG4gICAgICAgIFwiYHQuZGVmaW5lYCBpcyBkZXByZWNhdGVkLiBVc2UgZXh0ZXJuYWwgbWV0aG9kcyBvciBkaXJlY3QgYXNzaWdubWVudCBpbnN0ZWFkLlwiLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW5cbiAgICAgICAgLyoqIEB0aGlzICovIGZ1bmN0aW9uIChuYW1lLCBmdW5jKSB7XG4gICAgICAgICAgICBpdGVyYXRlU2V0dGVyKHRoaXMuXy5jdXJyZW50LnZhbHVlLCBuYW1lLCBmdW5jLCBkZWZpbmVBc3NlcnRpb24pXG4gICAgICAgICAgICByZXR1cm4gdGhpc1xuICAgICAgICB9KSxcbn0pXG5cbi8qICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKlxuICogLSBgcmVmbGVjdC5kb2AgaXMgZGVwcmVjYXRlZCwgd2l0aCBubyByZXBsYWNlbWVudCAoaW5saW5lIHRlc3RzIGFyZSBhbHNvICAqXG4gKiAgIGRlcHJlY2F0ZWQpLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqIC0gYHJlZmxlY3QuYmFzZWAgLT4gYGludGVybmFsLnJvb3RgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogLSBgcmVmbGVjdC5Bc3NlcnRpb25FcnJvcmAgLT4gYGFzc2VydC5Bc3NlcnRpb25FcnJvcmAuICAgICAgICAgICAgICAgICAgICAqXG4gKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICovXG5cbm1ldGhvZHMoUmVmbGVjdCwge1xuICAgIC8vIERlcHJlY2F0ZWQgYWxpYXNlc1xuICAgIGRvOiBDb21tb24uZGVwcmVjYXRlKFxuICAgICAgICBcImByZWZsZWN0LmRvYCBpcyBkZXByZWNhdGVkLiBUcmFuc2l0aW9uIHRvIGJsb2NrIHRlc3RzLCBpZiBuZWNlc3NhcnksIGFuZCBydW4gdGhlIGNvZGUgZGlyZWN0bHkuXCIsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgICAgICAvKiogQHRoaXMgKi8gZnVuY3Rpb24gKGZ1bmMpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZnVuYyAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb25cIilcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYXR0ZW1wdC5hcHBseSh1bmRlZmluZWQsIGFyZ3VtZW50cylcbiAgICAgICAgICAgIHJldHVybiB0aGlzXG4gICAgICAgIH0pLFxuICAgIGJhc2U6IENvbW1vbi5kZXByZWNhdGUoXG4gICAgICAgIFwiYHJlZmxlY3QuYmFzZWAgaXMgZGVwcmVjYXRlZC4gVXNlIGBpbnRlcm5hbC5yb290YCBmcm9tIGB0aGFsbGl1bS9pbnRlcm5hbGAgaW5zdGVhZC5cIiwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgICAgIEludGVybmFsLnJvb3QpLFxufSlcblxuLy8gRVNMaW50IG9kZGx5IGNhbid0IHRlbGwgdGhlc2UgYXJlIHNoYWRvd2VkLlxuLyogZXNsaW50LWRpc2FibGUgbm8tZXh0ZW5kLW5hdGl2ZSAqL1xuXG5mdW5jdGlvbiBsb2NrRXJyb3IoQXNzZXJ0aW9uRXJyb3IpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVmbGVjdC5wcm90b3R5cGUsIFwiQXNzZXJ0aW9uRXJyb3JcIiwge1xuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgdmFsdWU6IEFzc2VydGlvbkVycm9yLFxuICAgIH0pXG4gICAgcmV0dXJuIEFzc2VydGlvbkVycm9yXG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWZsZWN0LnByb3RvdHlwZSwgXCJBc3NlcnRpb25FcnJvclwiLCB7XG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIGdldDogQ29tbW9uLmRlcHJlY2F0ZShcbiAgICAgICAgXCJgcmVmbGVjdC5Bc3NlcnRpb25FcnJvcmAgaXMgZGVwcmVjYXRlZC4gVXNlIGBhc3NlcnQuQXNzZXJ0aW9uRXJyb3JgIGZyb20gYHRoYWxsaXVtL2Fzc2VydGAgaW5zdGVhZC5cIiwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgICAgIGZ1bmN0aW9uICgpIHsgcmV0dXJuIGxvY2tFcnJvcihhc3NlcnQuQXNzZXJ0aW9uRXJyb3IpIH0pLFxuICAgIHNldDogQ29tbW9uLmRlcHJlY2F0ZShcbiAgICAgICAgXCJgcmVmbGVjdC5Bc3NlcnRpb25FcnJvcmAgaXMgZGVwcmVjYXRlZC4gVXNlIGBhc3NlcnQuQXNzZXJ0aW9uRXJyb3JgIGZyb20gYHRoYWxsaXVtL2Fzc2VydGAgaW5zdGVhZC5cIiwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgICAgIGxvY2tFcnJvciksXG59KVxuXG4vKiBlc2xpbnQtZW5hYmxlIG5vLWV4dGVuZC1uYXRpdmUgKi9cblxubWV0aG9kcyhUaGFsbGl1bSwge1xuICAgIGJhc2U6IENvbW1vbi5kZXByZWNhdGUoXG4gICAgICAgIFwiYHQuYmFzZWAgaXMgZGVwcmVjYXRlZC4gVXNlIGB0LmNyZWF0ZWAgaW5zdGVhZC5cIixcbiAgICAgICAgZnVuY3Rpb24gKCkgeyByZXR1cm4gbmV3IFRoYWxsaXVtKCkgfSksXG59KVxuXG4vKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICpcbiAqIC0gYXNzZXJ0aW9ucyBkZWZpbmVkIG9uIG1haW4gZXhwb3J0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogLSBgdC4qYCBhc3NlcnRpb25zIC0+IGBhc3NlcnQuKmAgKHNvbWUgcmVuYW1lZCkgZnJvbSBgdGhhbGxpdW0vYXNzZXJ0YCAgICAqXG4gKiAtIGB0LnRydWVgL2V0Yy4gYXJlIGdvbmUgKGV4Y2VwdCBgdC51bmRlZmluZWRgIC0+IGBhc3NlcnQuaXNVbmRlZmluZWRgKSAgICpcbiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKi9cbkNvbW1vbi5oaWRlRGVwcmVjYXRpb24oKVxucmVxdWlyZShcIi4uL2Fzc2VydGlvbnNcIikocmVxdWlyZShcIi4uL2luZGV4XCIpKVxuQ29tbW9uLnNob3dEZXByZWNhdGlvbigpXG5cbi8qICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKlxuICogYGV4dHJhYCBldmVudHMgYXJlIG5vIGxvbmdlciBhIHRoaW5nLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICovXG5tZXRob2RzKFJlcG9ydCwge1xuICAgIGdldCBpc0lubGluZSgpIHtcbiAgICAgICAgQ29tbW9uLndhcm4oXCJgZXh0cmFgIGV2ZW50cyBubyBsb25nZXIgZXhpc3QuIFlvdSBubyBsb25nZXIgbmVlZCB0byBcIiArXG4gICAgICAgICAgICBcImhhbmRsZSB0aGVtXCIpXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH0sXG59KVxuXG4vKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICpcbiAqIC0gYHQucmVmbGVjdGAgYW5kIGB0LnVzZWAgLT4gbm9uLWNhY2hpbmcgYHQuY2FsbGAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqL1xudmFyIGNhbGwgPSBUaGFsbGl1bS5wcm90b3R5cGUuY2FsbFxuXG5mdW5jdGlvbiBpZCh4KSB7IHJldHVybiB4IH1cblxubWV0aG9kcyhUaGFsbGl1bSwge1xuICAgIHJlZmxlY3Q6IENvbW1vbi5kZXByZWNhdGUoXG4gICAgICAgIFwiYHQucmVmbGVjdGAgaXMgZGVwcmVjYXRlZC4gVXNlIGB0LmNhbGxgIGluc3RlYWQuXCIsXG4gICAgICAgIC8qKiBAdGhpcyAqLyBmdW5jdGlvbiAoKSB7IHJldHVybiBjYWxsLmNhbGwodGhpcywgaWQpIH0pLFxuXG4gICAgdXNlOiBDb21tb24uZGVwcmVjYXRlKFxuICAgICAgICBcImB0LnVzZWAgaXMgZGVwcmVjYXRlZC4gVXNlIGB0LmNhbGxgIGluc3RlYWQuXCIsXG4gICAgICAgIC8qKiBAdGhpcyAqLyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgcmVmbGVjdCA9IGNhbGwuY2FsbCh0aGlzLCBpZClcblxuICAgICAgICAgICAgaWYgKCFyZWZsZWN0LnNraXBwZWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgdGVzdCA9IHRoaXMuXy5jdXJyZW50LnZhbHVlXG5cbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcGx1Z2luID0gYXJndW1lbnRzW2ldXG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwbHVnaW4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIkV4cGVjdGVkIGBwbHVnaW5gIHRvIGJlIGEgZnVuY3Rpb25cIilcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ZXN0LnBsdWdpbnMgPT0gbnVsbCkgdGVzdC5wbHVnaW5zID0gW11cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRlc3QucGx1Z2lucy5pbmRleE9mKHBsdWdpbikgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBZGQgcGx1Z2luIGJlZm9yZSBjYWxsaW5nIGl0LlxuICAgICAgICAgICAgICAgICAgICAgICAgdGVzdC5wbHVnaW5zLnB1c2gocGx1Z2luKVxuICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2luLmNhbGwodGhpcywgdGhpcylcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXNcbiAgICAgICAgfSksXG59KVxuXG4vKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICpcbiAqIC0gYHJlZmxlY3QucmVwb3J0YCAtPiBgaW50ZXJuYWwucmVwb3J0LipgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogLSBgcmVmbGVjdC5sb2NgIC0+IGBpbnRlcm5hbC5sb2NhdGlvbmAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiAtIGByZWZsZWN0LnNjaGVkdWxlcmAgb2Jzb2xldGVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKi9cblxudmFyIHJlcG9ydHMgPSBJbnRlcm5hbC5yZXBvcnRzXG5cbm1ldGhvZHMoUmVmbGVjdCwge1xuICAgIHJlcG9ydDogQ29tbW9uLmRlcHJlY2F0ZShcbiAgICAgICAgXCJgcmVmbGVjdC5yZXBvcnRgIGlzIGRlcHJlY2F0ZWQuIFVzZSBgaW50ZXJuYWwucmVwb3J0LipgIGZyb20gYHRoYWxsaXVtL2ludGVybmFsYCBpbnN0ZWFkLlwiLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW5cbiAgICAgICAgZnVuY3Rpb24gKHR5cGUsIHBhdGgsIHZhbHVlLCBkdXJhdGlvbiwgc2xvdykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBgdHlwZWAgdG8gYmUgYSBzdHJpbmdcIilcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICBjYXNlIFwic3RhcnRcIjogcmV0dXJuIHJlcG9ydHMuc3RhcnQoKVxuICAgICAgICAgICAgY2FzZSBcImVudGVyXCI6IHJldHVybiByZXBvcnRzLmVudGVyKHBhdGgsIGR1cmF0aW9uLCBzbG93KVxuICAgICAgICAgICAgY2FzZSBcImxlYXZlXCI6IHJldHVybiByZXBvcnRzLmxlYXZlKHBhdGgpXG4gICAgICAgICAgICBjYXNlIFwicGFzc1wiOiByZXR1cm4gcmVwb3J0cy5wYXNzKHBhdGgsIGR1cmF0aW9uLCBzbG93KVxuICAgICAgICAgICAgY2FzZSBcImZhaWxcIjogcmV0dXJuIHJlcG9ydHMuZmFpbChwYXRoLCB2YWx1ZSwgZHVyYXRpb24sIHNsb3cpXG4gICAgICAgICAgICBjYXNlIFwic2tpcFwiOiByZXR1cm4gcmVwb3J0cy5za2lwKHBhdGgpXG4gICAgICAgICAgICBjYXNlIFwiZW5kXCI6IHJldHVybiByZXBvcnRzLmVuZCgpXG4gICAgICAgICAgICBjYXNlIFwiZXJyb3JcIjogcmV0dXJuIHJlcG9ydHMuZXJyb3IodmFsdWUpXG4gICAgICAgICAgICBjYXNlIFwiaG9va1wiOiByZXR1cm4gcmVwb3J0cy5ob29rKHBhdGgsIHZhbHVlKVxuICAgICAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJVbmtub3duIHJlcG9ydCBgdHlwZWA6IFwiICsgdHlwZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSksXG5cbiAgICBsb2M6IENvbW1vbi5kZXByZWNhdGUoXG4gICAgICAgIFwiYHJlZmxlY3QubG9jYCBpcyBkZXByZWNhdGVkLiBVc2UgYGludGVybmFsLmxvY2F0aW9uYCBmcm9tIGB0aGFsbGl1bS9pbnRlcm5hbGAgaW5zdGVhZC5cIiwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgICAgIEludGVybmFsLmxvY2F0aW9uKSxcblxuICAgIHNjaGVkdWxlcjogQ29tbW9uLmRlcHJlY2F0ZShcbiAgICAgICAgXCJgcmVmbGVjdC5zY2hlZHVsZXJgIGlzIGRlcHJlY2F0ZWQuIEl0IGlzIG5vIGxvbmdlciB1c2VmdWwgdG8gdGhlIGxpYnJhcnksIGFuZCBjYW4gYmUgc2FmZWx5IHJlbW92ZWQuXCIsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgICAgICBmdW5jdGlvbiAoKSB7fSksXG59KVxuXG4vKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICpcbiAqIElubGluZSB0ZXN0cyBhcmUgZGVwcmVjYXRlZC4gVGhpcyBpcyBcImZpeGVkXCIgYnkganVzdCB0aHJvd2luZywgc2luY2UgaXQncyAqXG4gKiBoYXJkIHRvIHBhdGNoIGJhY2sgaW4gYW5kIGVhc3kgdG8gZml4IG9uIHRoZSB1c2VyJ3MgZW5kLiAgICAgICAgICAgICAgICAgICpcbiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKi9cbm1ldGhvZHMoVGhhbGxpdW0sIHtcbiAgICB0ZXN0OiBmdW5jdGlvbiAobmFtZSwgZnVuYykge1xuICAgICAgICBpZiAoZnVuYyA9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBDYXRjaCB0aGlzIHBhcnRpY3VsYXIgY2FzZSwgdG8gdGhyb3cgd2l0aCBhIG1vcmUgaW5mb3JtYXRpdmVcbiAgICAgICAgICAgIC8vIG1lc3NzYWdlLlxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgICAgICBcIklubGluZSB0ZXN0cyBhcmUgZGVwcmVjYXRlZC4gVXNlIGJsb2NrIHRlc3RzIGluc3RlYWQuXCIpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGVzdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gICAgfSxcbn0pXG5cbm1ldGhvZHMoUmVmbGVjdCwge1xuICAgIGdldCBpc0lubGluZSgpIHtcbiAgICAgICAgQ29tbW9uLndhcm4oXCJUZXN0cyBhcmUgbm93IG5ldmVyIGlubGluZS4gWW91IG5vIGxvbmdlciBuZWVkIHRvIFwiICtcbiAgICAgICAgICAgIFwiaGFuZGxlIHRoaXMgY2FzZVwiKVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9LFxufSlcblxuLyogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqXG4gKiBgcmVmbGVjdC5tZXRob2RzYCAtPiBgcmVmbGVjdC5jdXJyZW50YCBhbmQgdXNpbmcgbmV3IGByZWZsZWN0YCBtZXRob2RzICAgICpcbiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKi9cbm1ldGhvZHMoUmVmbGVjdCwge1xuICAgIGdldCBtZXRob2RzKCkge1xuICAgICAgICBDb21tb24ud2FybihcImByZWZsZWN0Lm1ldGhvZHNgIGlzIGRlcHJlY2F0ZWQuIFVzZSBgcmVmbGVjdC5jdXJyZW50YCwgXCIgK1xuICAgICAgICAgICAgXCJ0aGUgcmV0dXJuIHZhbHVlIG9mIGB0LmNhbGxgLCBhbmQgdGhlIGFwcHJvcHJpYXRlIG5ldyBgcmVmbGVjdGAgXCIgK1xuICAgICAgICAgICAgXCJtZXRob2RzIGluc3RlYWRcIilcbiAgICAgICAgcmV0dXJuIHRoaXMuXy5tZXRob2RzXG4gICAgfSxcbn0pXG5cbi8qICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKlxuICogYHJlZmxlY3QucmVwb3J0ZXJzYCAtPiBgcmVmbGVjdC5oYXNSZXBvcnRlcmAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICogKiAqICovXG5tZXRob2RzKFJlZmxlY3QsIHtcbiAgICBnZXQgcmVwb3J0ZXJzKCkge1xuICAgICAgICBDb21tb24ud2FybihcImByZWZsZWN0LnJlcG9ydGVyc2AgaXMgZGVwcmVjYXRlZC4gVXNlIFwiICtcbiAgICAgICAgICAgIFwiYHJlZmxlY3QuaGFzUmVwb3J0ZXJgIGluc3RlYWQgdG8gY2hlY2sgZm9yIGV4aXN0ZW5jZSBvZiBhIFwiICtcbiAgICAgICAgICAgIFwicmVwb3J0ZXIuXCIpXG4gICAgICAgIHJldHVybiB0aGlzLl8ubWV0aG9kc1xuICAgIH0sXG59KVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoeHMsIGYpIHtcbiAgICBpZiAoeHMubWFwKSByZXR1cm4geHMubWFwKGYpO1xuICAgIHZhciByZXMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciB4ID0geHNbaV07XG4gICAgICAgIGlmIChoYXNPd24uY2FsbCh4cywgaSkpIHJlcy5wdXNoKGYoeCwgaSwgeHMpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn07XG5cbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuIiwidmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHhzLCBmLCBhY2MpIHtcbiAgICB2YXIgaGFzQWNjID0gYXJndW1lbnRzLmxlbmd0aCA+PSAzO1xuICAgIGlmIChoYXNBY2MgJiYgeHMucmVkdWNlKSByZXR1cm4geHMucmVkdWNlKGYsIGFjYyk7XG4gICAgaWYgKHhzLnJlZHVjZSkgcmV0dXJuIHhzLnJlZHVjZShmKTtcbiAgICBcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICghaGFzT3duLmNhbGwoeHMsIGkpKSBjb250aW51ZTtcbiAgICAgICAgaWYgKCFoYXNBY2MpIHtcbiAgICAgICAgICAgIGFjYyA9IHhzW2ldO1xuICAgICAgICAgICAgaGFzQWNjID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGFjYyA9IGYoYWNjLCB4c1tpXSwgaSk7XG4gICAgfVxuICAgIHJldHVybiBhY2M7XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9zdWJzdGFjay9ub2RlLWJyb3dzZXJpZnkvaXNzdWVzLzE2NzRcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwidXRpbC1pbnNwZWN0XCIpXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgaW5zcGVjdCA9IGV4cG9ydHMuaW5zcGVjdCA9IHJlcXVpcmUoXCIuL2luc3BlY3RcIilcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5XG52YXIgQXNzZXJ0aW9uRXJyb3JcblxuLy8gUGhhbnRvbUpTLCBJRSwgYW5kIHBvc3NpYmx5IEVkZ2UgZG9uJ3Qgc2V0IHRoZSBzdGFjayB0cmFjZSB1bnRpbCB0aGUgZXJyb3IgaXNcbi8vIHRocm93bi4gTm90ZSB0aGF0IHRoaXMgcHJlZmVycyBhbiBleGlzdGluZyBzdGFjayBmaXJzdCwgc2luY2Ugbm9uLW5hdGl2ZVxuLy8gZXJyb3JzIGxpa2VseSBhbHJlYWR5IGNvbnRhaW4gdGhpcy5cbmZ1bmN0aW9uIGdldFN0YWNrKGUpIHtcbiAgICB2YXIgc3RhY2sgPSBlLnN0YWNrXG5cbiAgICBpZiAoIShlIGluc3RhbmNlb2YgRXJyb3IpIHx8IHN0YWNrICE9IG51bGwpIHJldHVybiBzdGFja1xuXG4gICAgdHJ5IHtcbiAgICAgICAgdGhyb3cgZVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGUuc3RhY2tcbiAgICB9XG59XG5cbnRyeSB7XG4gICAgQXNzZXJ0aW9uRXJyb3IgPSBuZXcgRnVuY3Rpb24oWyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ldy1mdW5jXG4gICAgICAgIFwiJ3VzZSBzdHJpY3QnO1wiLFxuICAgICAgICBcImNsYXNzIEFzc2VydGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1wiLFxuICAgICAgICBcIiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsKSB7XCIsXG4gICAgICAgIFwiICAgICAgICBzdXBlcihtZXNzYWdlKVwiLFxuICAgICAgICBcIiAgICAgICAgdGhpcy5leHBlY3RlZCA9IGV4cGVjdGVkXCIsXG4gICAgICAgIFwiICAgICAgICB0aGlzLmFjdHVhbCA9IGFjdHVhbFwiLFxuICAgICAgICBcIiAgICB9XCIsXG4gICAgICAgIFwiXCIsXG4gICAgICAgIFwiICAgIGdldCBuYW1lKCkge1wiLFxuICAgICAgICBcIiAgICAgICAgcmV0dXJuICdBc3NlcnRpb25FcnJvcidcIixcbiAgICAgICAgXCIgICAgfVwiLFxuICAgICAgICBcIn1cIixcbiAgICAgICAgLy8gY2hlY2sgbmF0aXZlIHN1YmNsYXNzaW5nIHN1cHBvcnRcbiAgICAgICAgXCJuZXcgQXNzZXJ0aW9uRXJyb3IoJ21lc3NhZ2UnLCAxLCAyKVwiLFxuICAgICAgICBcInJldHVybiBBc3NlcnRpb25FcnJvclwiLFxuICAgIF0uam9pbihcIlxcblwiKSkoKVxufSBjYXRjaCAoZSkge1xuICAgIEFzc2VydGlvbkVycm9yID0gdHlwZW9mIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgPyBmdW5jdGlvbiBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsKSB7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlIHx8IFwiXCJcbiAgICAgICAgICAgIHRoaXMuZXhwZWN0ZWQgPSBleHBlY3RlZFxuICAgICAgICAgICAgdGhpcy5hY3R1YWwgPSBhY3R1YWxcbiAgICAgICAgICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHRoaXMuY29uc3RydWN0b3IpXG4gICAgICAgIH1cbiAgICAgICAgOiBmdW5jdGlvbiBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsKSB7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlIHx8IFwiXCJcbiAgICAgICAgICAgIHRoaXMuZXhwZWN0ZWQgPSBleHBlY3RlZFxuICAgICAgICAgICAgdGhpcy5hY3R1YWwgPSBhY3R1YWxcbiAgICAgICAgICAgIHZhciBlID0gbmV3IEVycm9yKG1lc3NhZ2UpXG5cbiAgICAgICAgICAgIGUubmFtZSA9IFwiQXNzZXJ0aW9uRXJyb3JcIlxuICAgICAgICAgICAgdGhpcy5zdGFjayA9IGdldFN0YWNrKGUpXG4gICAgICAgIH1cblxuICAgIEFzc2VydGlvbkVycm9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFzc2VydGlvbkVycm9yLnByb3RvdHlwZSwgXCJjb25zdHJ1Y3RvclwiLCB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogQXNzZXJ0aW9uRXJyb3IsXG4gICAgfSlcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBc3NlcnRpb25FcnJvci5wcm90b3R5cGUsIFwibmFtZVwiLCB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogXCJBc3NlcnRpb25FcnJvclwiLFxuICAgIH0pXG59XG5cbmV4cG9ydHMuQXNzZXJ0aW9uRXJyb3IgPSBBc3NlcnRpb25FcnJvclxuXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1zZWxmLWNvbXBhcmUgKi9cbi8vIEZvciBiZXR0ZXIgTmFOIGhhbmRsaW5nXG5leHBvcnRzLnN0cmljdElzID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gYSA9PT0gYiB8fCBhICE9PSBhICYmIGIgIT09IGJcbn1cblxuZXhwb3J0cy5sb29zZUlzID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gYSA9PSBiIHx8IGEgIT09IGEgJiYgYiAhPT0gYiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxufVxuXG4vKiBlc2xpbnQtZW5hYmxlIG5vLXNlbGYtY29tcGFyZSAqL1xuXG52YXIgdGVtcGxhdGVSZWdleHAgPSAvKC4/KVxceyguKz8pXFx9L2dcblxuZXhwb3J0cy5lc2NhcGUgPSBmdW5jdGlvbiAoc3RyaW5nKSB7XG4gICAgaWYgKHR5cGVvZiBzdHJpbmcgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBzdHJpbmdgIG11c3QgYmUgYSBzdHJpbmdcIilcbiAgICB9XG5cbiAgICByZXR1cm4gc3RyaW5nLnJlcGxhY2UodGVtcGxhdGVSZWdleHAsIGZ1bmN0aW9uIChtLCBwcmUpIHtcbiAgICAgICAgcmV0dXJuIHByZSArIFwiXFxcXFwiICsgbS5zbGljZSgxKVxuICAgIH0pXG59XG5cbi8vIFRoaXMgZm9ybWF0cyB0aGUgYXNzZXJ0aW9uIGVycm9yIG1lc3NhZ2VzLlxuZXhwb3J0cy5mb3JtYXQgPSBmdW5jdGlvbiAobWVzc2FnZSwgYXJncywgcHJldHRpZnkpIHtcbiAgICBpZiAocHJldHRpZnkgPT0gbnVsbCkgcHJldHRpZnkgPSBpbnNwZWN0XG5cbiAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBtZXNzYWdlYCBtdXN0IGJlIGEgc3RyaW5nXCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBhcmdzICE9PSBcIm9iamVjdFwiIHx8IGFyZ3MgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBhcmdzYCBtdXN0IGJlIGFuIG9iamVjdFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcHJldHRpZnkgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYHByZXR0aWZ5YCBtdXN0IGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIG1lc3NhZ2UucmVwbGFjZSh0ZW1wbGF0ZVJlZ2V4cCwgZnVuY3Rpb24gKG0sIHByZSwgcHJvcCkge1xuICAgICAgICBpZiAocHJlID09PSBcIlxcXFxcIikge1xuICAgICAgICAgICAgcmV0dXJuIG0uc2xpY2UoMSlcbiAgICAgICAgfSBlbHNlIGlmIChoYXNPd24uY2FsbChhcmdzLCBwcm9wKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByZSArIHByZXR0aWZ5KGFyZ3NbcHJvcF0sIHtkZXB0aDogNX0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gcHJlICsgbVxuICAgICAgICB9XG4gICAgfSlcbn1cblxuZXhwb3J0cy5mYWlsID0gZnVuY3Rpb24gKG1lc3NhZ2UsIGFyZ3MsIHByZXR0aWZ5KSB7XG4gICAgaWYgKGFyZ3MgPT0gbnVsbCkgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKG1lc3NhZ2UpXG4gICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKFxuICAgICAgICBleHBvcnRzLmZvcm1hdChtZXNzYWdlLCBhcmdzLCBwcmV0dGlmeSksXG4gICAgICAgIGFyZ3MuZXhwZWN0ZWQsXG4gICAgICAgIGFyZ3MuYWN0dWFsKVxufVxuXG4vLyBUaGUgYmFzaWMgYXNzZXJ0LCBsaWtlIGBhc3NlcnQub2tgLCBidXQgZ2l2ZXMgeW91IGFuIG9wdGlvbmFsIG1lc3NhZ2UuXG5leHBvcnRzLmFzc2VydCA9IGZ1bmN0aW9uICh0ZXN0LCBtZXNzYWdlKSB7XG4gICAgaWYgKCF0ZXN0KSB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobWVzc2FnZSlcbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogQ29yZSBUREQtc3R5bGUgYXNzZXJ0aW9ucy4gVGhlc2UgYXJlIGRvbmUgYnkgYSBjb21wb3NpdGlvbiBvZiBEU0xzLCBzaW5jZVxuICogdGhlcmUgaXMgKnNvKiBtdWNoIHJlcGV0aXRpb24uIEFsc28sIHRoaXMgaXMgc3BsaXQgaW50byBzZXZlcmFsIG5hbWVzcGFjZXMgdG9cbiAqIGtlZXAgdGhlIGZpbGUgc2l6ZSBtYW5hZ2VhYmxlLlxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpXG52YXIgdHlwZSA9IHJlcXVpcmUoXCIuL2xpYi90eXBlXCIpXG52YXIgZXF1YWwgPSByZXF1aXJlKFwiLi9saWIvZXF1YWxcIilcbnZhciB0aHJvd3MgPSByZXF1aXJlKFwiLi9saWIvdGhyb3dzXCIpXG52YXIgaGFzID0gcmVxdWlyZShcIi4vbGliL2hhc1wiKVxudmFyIGluY2x1ZGVzID0gcmVxdWlyZShcIi4vbGliL2luY2x1ZGVzXCIpXG52YXIgaGFzS2V5cyA9IHJlcXVpcmUoXCIuL2xpYi9oYXMta2V5c1wiKVxuXG5leHBvcnRzLkFzc2VydGlvbkVycm9yID0gdXRpbC5Bc3NlcnRpb25FcnJvclxuZXhwb3J0cy5hc3NlcnQgPSB1dGlsLmFzc2VydFxuZXhwb3J0cy5mYWlsID0gdXRpbC5mYWlsXG5cbmV4cG9ydHMub2sgPSB0eXBlLm9rXG5leHBvcnRzLm5vdE9rID0gdHlwZS5ub3RPa1xuZXhwb3J0cy5pc0Jvb2xlYW4gPSB0eXBlLmlzQm9vbGVhblxuZXhwb3J0cy5ub3RCb29sZWFuID0gdHlwZS5ub3RCb29sZWFuXG5leHBvcnRzLmlzRnVuY3Rpb24gPSB0eXBlLmlzRnVuY3Rpb25cbmV4cG9ydHMubm90RnVuY3Rpb24gPSB0eXBlLm5vdEZ1bmN0aW9uXG5leHBvcnRzLmlzTnVtYmVyID0gdHlwZS5pc051bWJlclxuZXhwb3J0cy5ub3ROdW1iZXIgPSB0eXBlLm5vdE51bWJlclxuZXhwb3J0cy5pc09iamVjdCA9IHR5cGUuaXNPYmplY3RcbmV4cG9ydHMubm90T2JqZWN0ID0gdHlwZS5ub3RPYmplY3RcbmV4cG9ydHMuaXNTdHJpbmcgPSB0eXBlLmlzU3RyaW5nXG5leHBvcnRzLm5vdFN0cmluZyA9IHR5cGUubm90U3RyaW5nXG5leHBvcnRzLmlzU3ltYm9sID0gdHlwZS5pc1N5bWJvbFxuZXhwb3J0cy5ub3RTeW1ib2wgPSB0eXBlLm5vdFN5bWJvbFxuZXhwb3J0cy5leGlzdHMgPSB0eXBlLmV4aXN0c1xuZXhwb3J0cy5ub3RFeGlzdHMgPSB0eXBlLm5vdEV4aXN0c1xuZXhwb3J0cy5pc0FycmF5ID0gdHlwZS5pc0FycmF5XG5leHBvcnRzLm5vdEFycmF5ID0gdHlwZS5ub3RBcnJheVxuZXhwb3J0cy5pcyA9IHR5cGUuaXNcbmV4cG9ydHMubm90ID0gdHlwZS5ub3RcblxuZXhwb3J0cy5lcXVhbCA9IGVxdWFsLmVxdWFsXG5leHBvcnRzLm5vdEVxdWFsID0gZXF1YWwubm90RXF1YWxcbmV4cG9ydHMuZXF1YWxMb29zZSA9IGVxdWFsLmVxdWFsTG9vc2VcbmV4cG9ydHMubm90RXF1YWxMb29zZSA9IGVxdWFsLm5vdEVxdWFsTG9vc2VcbmV4cG9ydHMuZGVlcEVxdWFsID0gZXF1YWwuZGVlcEVxdWFsXG5leHBvcnRzLm5vdERlZXBFcXVhbCA9IGVxdWFsLm5vdERlZXBFcXVhbFxuZXhwb3J0cy5tYXRjaCA9IGVxdWFsLm1hdGNoXG5leHBvcnRzLm5vdE1hdGNoID0gZXF1YWwubm90TWF0Y2hcbmV4cG9ydHMuYXRMZWFzdCA9IGVxdWFsLmF0TGVhc3RcbmV4cG9ydHMuYXRNb3N0ID0gZXF1YWwuYXRNb3N0XG5leHBvcnRzLmFib3ZlID0gZXF1YWwuYWJvdmVcbmV4cG9ydHMuYmVsb3cgPSBlcXVhbC5iZWxvd1xuZXhwb3J0cy5iZXR3ZWVuID0gZXF1YWwuYmV0d2VlblxuZXhwb3J0cy5jbG9zZVRvID0gZXF1YWwuY2xvc2VUb1xuZXhwb3J0cy5ub3RDbG9zZVRvID0gZXF1YWwubm90Q2xvc2VUb1xuXG5leHBvcnRzLnRocm93cyA9IHRocm93cy50aHJvd3NcbmV4cG9ydHMudGhyb3dzTWF0Y2ggPSB0aHJvd3MudGhyb3dzTWF0Y2hcblxuZXhwb3J0cy5oYXNPd24gPSBoYXMuaGFzT3duXG5leHBvcnRzLm5vdEhhc093biA9IGhhcy5ub3RIYXNPd25cbmV4cG9ydHMuaGFzT3duTG9vc2UgPSBoYXMuaGFzT3duTG9vc2VcbmV4cG9ydHMubm90SGFzT3duTG9vc2UgPSBoYXMubm90SGFzT3duTG9vc2VcbmV4cG9ydHMuaGFzS2V5ID0gaGFzLmhhc0tleVxuZXhwb3J0cy5ub3RIYXNLZXkgPSBoYXMubm90SGFzS2V5XG5leHBvcnRzLmhhc0tleUxvb3NlID0gaGFzLmhhc0tleUxvb3NlXG5leHBvcnRzLm5vdEhhc0tleUxvb3NlID0gaGFzLm5vdEhhc0tleUxvb3NlXG5leHBvcnRzLmhhcyA9IGhhcy5oYXNcbmV4cG9ydHMubm90SGFzID0gaGFzLm5vdEhhc1xuZXhwb3J0cy5oYXNMb29zZSA9IGhhcy5oYXNMb29zZVxuZXhwb3J0cy5ub3RIYXNMb29zZSA9IGhhcy5ub3RIYXNMb29zZVxuXG4vKipcbiAqIFRoZXJlJ3MgMiBzZXRzIG9mIDEyIHBlcm11dGF0aW9ucyBoZXJlIGZvciBgaW5jbHVkZXNgIGFuZCBgaGFzS2V5c2AsIGluc3RlYWRcbiAqIG9mIE4gc2V0cyBvZiAyICh3aGljaCB3b3VsZCBmaXQgdGhlIGBmb29gL2Bub3RGb29gIGlkaW9tIGJldHRlciksIHNvIGl0J3NcbiAqIGVhc2llciB0byBqdXN0IG1ha2UgYSBjb3VwbGUgc2VwYXJhdGUgRFNMcyBhbmQgdXNlIHRoYXQgdG8gZGVmaW5lIGV2ZXJ5dGhpbmcuXG4gKlxuICogSGVyZSdzIHRoZSB0b3AgbGV2ZWw6XG4gKlxuICogLSBzaGFsbG93XG4gKiAtIHN0cmljdCBkZWVwXG4gKiAtIHN0cnVjdHVyYWwgZGVlcFxuICpcbiAqIEFuZCB0aGUgc2Vjb25kIGxldmVsOlxuICpcbiAqIC0gaW5jbHVkZXMgYWxsL25vdCBtaXNzaW5nIHNvbWVcbiAqIC0gaW5jbHVkZXMgc29tZS9ub3QgbWlzc2luZyBhbGxcbiAqIC0gbm90IGluY2x1ZGluZyBhbGwvbWlzc2luZyBzb21lXG4gKiAtIG5vdCBpbmNsdWRpbmcgc29tZS9taXNzaW5nIGFsbFxuICpcbiAqIEhlcmUncyBhbiBleGFtcGxlIHVzaW5nIHRoZSBuYW1pbmcgc2NoZW1lIGZvciBgaGFzS2V5cypgXG4gKlxuICogICAgICAgICAgICAgICB8ICAgICBzaGFsbG93ICAgICB8ICAgIHN0cmljdCBkZWVwICAgICAgfCAgIHN0cnVjdHVyYWwgZGVlcFxuICogLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIGluY2x1ZGVzIGFsbCAgfCBgaGFzS2V5c2AgICAgICAgfCBgaGFzS2V5c0RlZXBgICAgICAgIHwgYGhhc0tleXNNYXRjaGBcbiAqIGluY2x1ZGVzIHNvbWUgfCBgaGFzS2V5c0FueWAgICAgfCBgaGFzS2V5c0FueURlZXBgICAgIHwgYGhhc0tleXNBbnlNYXRjaGBcbiAqIG1pc3Npbmcgc29tZSAgfCBgbm90SGFzS2V5c0FsbGAgfCBgbm90SGFzS2V5c0FsbERlZXBgIHwgYG5vdEhhc0tleXNBbGxNYXRjaGBcbiAqIG1pc3NpbmcgYWxsICAgfCBgbm90SGFzS2V5c2AgICAgfCBgbm90SGFzS2V5c0RlZXBgICAgIHwgYG5vdEhhc0tleXNNYXRjaGBcbiAqXG4gKiBOb3RlIHRoYXQgdGhlIGBoYXNLZXlzYCBzaGFsbG93IGNvbXBhcmlzb24gdmFyaWFudHMgYXJlIGFsc28gb3ZlcmxvYWRlZCB0b1xuICogY29uc3VtZSBlaXRoZXIgYW4gYXJyYXkgKGluIHdoaWNoIGl0IHNpbXBseSBjaGVja3MgYWdhaW5zdCBhIGxpc3Qgb2Yga2V5cykgb3JcbiAqIGFuIG9iamVjdCAod2hlcmUgaXQgZG9lcyBhIGZ1bGwgZGVlcCBjb21wYXJpc29uKS5cbiAqL1xuXG5leHBvcnRzLmluY2x1ZGVzID0gaW5jbHVkZXMuaW5jbHVkZXNcbmV4cG9ydHMuaW5jbHVkZXNEZWVwID0gaW5jbHVkZXMuaW5jbHVkZXNEZWVwXG5leHBvcnRzLmluY2x1ZGVzTWF0Y2ggPSBpbmNsdWRlcy5pbmNsdWRlc01hdGNoXG5leHBvcnRzLmluY2x1ZGVzQW55ID0gaW5jbHVkZXMuaW5jbHVkZXNBbnlcbmV4cG9ydHMuaW5jbHVkZXNBbnlEZWVwID0gaW5jbHVkZXMuaW5jbHVkZXNBbnlEZWVwXG5leHBvcnRzLmluY2x1ZGVzQW55TWF0Y2ggPSBpbmNsdWRlcy5pbmNsdWRlc0FueU1hdGNoXG5leHBvcnRzLm5vdEluY2x1ZGVzQWxsID0gaW5jbHVkZXMubm90SW5jbHVkZXNBbGxcbmV4cG9ydHMubm90SW5jbHVkZXNBbGxEZWVwID0gaW5jbHVkZXMubm90SW5jbHVkZXNBbGxEZWVwXG5leHBvcnRzLm5vdEluY2x1ZGVzQWxsTWF0Y2ggPSBpbmNsdWRlcy5ub3RJbmNsdWRlc0FsbE1hdGNoXG5leHBvcnRzLm5vdEluY2x1ZGVzID0gaW5jbHVkZXMubm90SW5jbHVkZXNcbmV4cG9ydHMubm90SW5jbHVkZXNEZWVwID0gaW5jbHVkZXMubm90SW5jbHVkZXNEZWVwXG5leHBvcnRzLm5vdEluY2x1ZGVzTWF0Y2ggPSBpbmNsdWRlcy5ub3RJbmNsdWRlc01hdGNoXG5cbmV4cG9ydHMuaGFzS2V5cyA9IGhhc0tleXMuaGFzS2V5c1xuZXhwb3J0cy5oYXNLZXlzRGVlcCA9IGhhc0tleXMuaGFzS2V5c0RlZXBcbmV4cG9ydHMuaGFzS2V5c01hdGNoID0gaGFzS2V5cy5oYXNLZXlzTWF0Y2hcbmV4cG9ydHMuaGFzS2V5c0FueSA9IGhhc0tleXMuaGFzS2V5c0FueVxuZXhwb3J0cy5oYXNLZXlzQW55RGVlcCA9IGhhc0tleXMuaGFzS2V5c0FueURlZXBcbmV4cG9ydHMuaGFzS2V5c0FueU1hdGNoID0gaGFzS2V5cy5oYXNLZXlzQW55TWF0Y2hcbmV4cG9ydHMubm90SGFzS2V5c0FsbCA9IGhhc0tleXMubm90SGFzS2V5c0FsbFxuZXhwb3J0cy5ub3RIYXNLZXlzQWxsRGVlcCA9IGhhc0tleXMubm90SGFzS2V5c0FsbERlZXBcbmV4cG9ydHMubm90SGFzS2V5c0FsbE1hdGNoID0gaGFzS2V5cy5ub3RIYXNLZXlzQWxsTWF0Y2hcbmV4cG9ydHMubm90SGFzS2V5cyA9IGhhc0tleXMubm90SGFzS2V5c1xuZXhwb3J0cy5ub3RIYXNLZXlzRGVlcCA9IGhhc0tleXMubm90SGFzS2V5c0RlZXBcbmV4cG9ydHMubm90SGFzS2V5c01hdGNoID0gaGFzS2V5cy5ub3RIYXNLZXlzTWF0Y2hcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBtYXRjaCA9IHJlcXVpcmUoXCJjbGVhbi1tYXRjaFwiKVxudmFyIHV0aWwgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0LXV0aWxcIilcblxuZnVuY3Rpb24gYmluYXJ5KG51bWVyaWMsIGNvbXBhcmF0b3IsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGFjdHVhbCwgZXhwZWN0ZWQpIHtcbiAgICAgICAgaWYgKG51bWVyaWMpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYWN0dWFsICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBhY3R1YWxgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBleHBlY3RlZCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgZXhwZWN0ZWRgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghY29tcGFyYXRvcihhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgICAgICAgICAgdXRpbC5mYWlsKG1lc3NhZ2UsIHthY3R1YWw6IGFjdHVhbCwgZXhwZWN0ZWQ6IGV4cGVjdGVkfSlcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0cy5lcXVhbCA9IGJpbmFyeShmYWxzZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gdXRpbC5zdHJpY3RJcyhhLCBiKSB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gZXF1YWwge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLm5vdEVxdWFsID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiAhdXRpbC5zdHJpY3RJcyhhLCBiKSB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGVxdWFsIHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5lcXVhbExvb3NlID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiB1dGlsLmxvb3NlSXMoYSwgYikgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGxvb3NlbHkgZXF1YWwge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLm5vdEVxdWFsTG9vc2UgPSBiaW5hcnkoZmFsc2UsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuICF1dGlsLmxvb3NlSXMoYSwgYikgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBsb29zZWx5IGVxdWFsIHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5hdExlYXN0ID0gYmluYXJ5KHRydWUsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEgPj0gYiB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYXQgbGVhc3Qge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLmF0TW9zdCA9IGJpbmFyeSh0cnVlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhIDw9IGIgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGF0IG1vc3Qge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLmFib3ZlID0gYmluYXJ5KHRydWUsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEgPiBiIH0sXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhYm92ZSB7ZXhwZWN0ZWR9XCIpXG5cbmV4cG9ydHMuYmVsb3cgPSBiaW5hcnkodHJ1ZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYSA8IGIgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGJlbG93IHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5iZXR3ZWVuID0gZnVuY3Rpb24gKGFjdHVhbCwgbG93ZXIsIHVwcGVyKSB7XG4gICAgaWYgKHR5cGVvZiBhY3R1YWwgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBhY3R1YWxgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGxvd2VyICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgbG93ZXJgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHVwcGVyICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgdXBwZXJgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICB9XG5cbiAgICAvLyBUaGUgbmVnYXRpb24gaXMgdG8gYWRkcmVzcyBOYU5zIGFzIHdlbGwsIHdpdGhvdXQgd3JpdGluZyBhIHRvbiBvZiBzcGVjaWFsXG4gICAgLy8gY2FzZSBib2lsZXJwbGF0ZVxuICAgIGlmICghKGFjdHVhbCA+PSBsb3dlciAmJiBhY3R1YWwgPD0gdXBwZXIpKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGJldHdlZW4ge2xvd2VyfSBhbmQge3VwcGVyfVwiLCB7XG4gICAgICAgICAgICBhY3R1YWw6IGFjdHVhbCxcbiAgICAgICAgICAgIGxvd2VyOiBsb3dlcixcbiAgICAgICAgICAgIHVwcGVyOiB1cHBlcixcbiAgICAgICAgfSlcbiAgICB9XG59XG5cbmV4cG9ydHMuZGVlcEVxdWFsID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBtYXRjaC5zdHJpY3QoYSwgYikgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGRlZXBseSBlcXVhbCB7ZXhwZWN0ZWR9XCIpXG5cbmV4cG9ydHMubm90RGVlcEVxdWFsID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiAhbWF0Y2guc3RyaWN0KGEsIGIpIH0sXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgZGVlcGx5IGVxdWFsIHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5tYXRjaCA9IGJpbmFyeShmYWxzZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gbWF0Y2gubG9vc2UoYSwgYikgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5ub3RNYXRjaCA9IGJpbmFyeShmYWxzZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gIW1hdGNoLmxvb3NlKGEsIGIpIH0sXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgbWF0Y2gge2V4cGVjdGVkfVwiKVxuXG4vLyBVc2VzIGRpdmlzaW9uIHRvIGFsbG93IGZvciBhIG1vcmUgcm9idXN0IGNvbXBhcmlzb24gb2YgZmxvYXRzLiBBbHNvLCB0aGlzXG4vLyBoYW5kbGVzIG5lYXItemVybyBjb21wYXJpc29ucyBjb3JyZWN0bHksIGFzIHdlbGwgYXMgYSB6ZXJvIHRvbGVyYW5jZSAoaS5lLlxuLy8gZXhhY3QgY29tcGFyaXNvbikuXG5mdW5jdGlvbiBjbG9zZVRvKGV4cGVjdGVkLCBhY3R1YWwsIHRvbGVyYW5jZSkge1xuICAgIGlmICh0b2xlcmFuY2UgPT09IEluZmluaXR5IHx8IGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHJldHVybiB0cnVlXG4gICAgaWYgKHRvbGVyYW5jZSA9PT0gMCkgcmV0dXJuIGZhbHNlXG4gICAgaWYgKGFjdHVhbCA9PT0gMCkgcmV0dXJuIE1hdGguYWJzKGV4cGVjdGVkKSA8IHRvbGVyYW5jZVxuICAgIGlmIChleHBlY3RlZCA9PT0gMCkgcmV0dXJuIE1hdGguYWJzKGFjdHVhbCkgPCB0b2xlcmFuY2VcbiAgICByZXR1cm4gTWF0aC5hYnMoZXhwZWN0ZWQgLyBhY3R1YWwgLSAxKSA8IHRvbGVyYW5jZVxufVxuXG4vLyBOb3RlOiB0aGVzZSB0d28gYWx3YXlzIGZhaWwgd2hlbiBkZWFsaW5nIHdpdGggTmFOcy5cbmV4cG9ydHMuY2xvc2VUbyA9IGZ1bmN0aW9uIChleHBlY3RlZCwgYWN0dWFsLCB0b2xlcmFuY2UpIHtcbiAgICBpZiAodHlwZW9mIGFjdHVhbCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGFjdHVhbGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZXhwZWN0ZWQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBleHBlY3RlZGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIGlmICh0b2xlcmFuY2UgPT0gbnVsbCkgdG9sZXJhbmNlID0gMWUtMTBcblxuICAgIGlmICh0eXBlb2YgdG9sZXJhbmNlICE9PSBcIm51bWJlclwiIHx8IHRvbGVyYW5jZSA8IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgIFwiYHRvbGVyYW5jZWAgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIgaWYgZ2l2ZW5cIilcbiAgICB9XG5cbiAgICBpZiAoYWN0dWFsICE9PSBhY3R1YWwgfHwgZXhwZWN0ZWQgIT09IGV4cGVjdGVkIHx8IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlLCBtYXgtbGVuXG4gICAgICAgICAgICAhY2xvc2VUbyhleHBlY3RlZCwgYWN0dWFsLCB0b2xlcmFuY2UpKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGNsb3NlIHRvIHtleHBlY3RlZH1cIiwge1xuICAgICAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgICAgICAgICBleHBlY3RlZDogZXhwZWN0ZWQsXG4gICAgICAgIH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdENsb3NlVG8gPSBmdW5jdGlvbiAoZXhwZWN0ZWQsIGFjdHVhbCwgdG9sZXJhbmNlKSB7XG4gICAgaWYgKHR5cGVvZiBhY3R1YWwgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBhY3R1YWxgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGV4cGVjdGVkICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgZXhwZWN0ZWRgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICB9XG5cbiAgICBpZiAodG9sZXJhbmNlID09IG51bGwpIHRvbGVyYW5jZSA9IDFlLTEwXG5cbiAgICBpZiAodHlwZW9mIHRvbGVyYW5jZSAhPT0gXCJudW1iZXJcIiB8fCB0b2xlcmFuY2UgPCAwKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICBcImB0b2xlcmFuY2VgIG11c3QgYmUgYSBub24tbmVnYXRpdmUgbnVtYmVyIGlmIGdpdmVuXCIpXG4gICAgfVxuXG4gICAgaWYgKGV4cGVjdGVkICE9PSBleHBlY3RlZCB8fCBhY3R1YWwgIT09IGFjdHVhbCB8fCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZSwgbWF4LWxlblxuICAgICAgICAgICAgY2xvc2VUbyhleHBlY3RlZCwgYWN0dWFsLCB0b2xlcmFuY2UpKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBjbG9zZSB0byB7ZXhwZWN0ZWR9XCIsIHtcbiAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuICAgICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgICAgICB9KVxuICAgIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBtYXRjaCA9IHJlcXVpcmUoXCJjbGVhbi1tYXRjaFwiKVxudmFyIHV0aWwgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0LXV0aWxcIilcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5XG5cbmZ1bmN0aW9uIGhhc0tleXMoYWxsLCBvYmplY3QsIGtleXMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHRlc3QgPSBoYXNPd24uY2FsbChvYmplY3QsIGtleXNbaV0pXG5cbiAgICAgICAgaWYgKHRlc3QgIT09IGFsbCkgcmV0dXJuICFhbGxcbiAgICB9XG5cbiAgICByZXR1cm4gYWxsXG59XG5cbmZ1bmN0aW9uIGhhc1ZhbHVlcyhmdW5jLCBhbGwsIG9iamVjdCwga2V5cykge1xuICAgIGlmIChvYmplY3QgPT09IGtleXMpIHJldHVybiB0cnVlXG4gICAgdmFyIGxpc3QgPSBPYmplY3Qua2V5cyhrZXlzKVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBsaXN0W2ldXG4gICAgICAgIHZhciB0ZXN0ID0gaGFzT3duLmNhbGwob2JqZWN0LCBrZXkpICYmIGZ1bmMoa2V5c1trZXldLCBvYmplY3Rba2V5XSlcblxuICAgICAgICBpZiAodGVzdCAhPT0gYWxsKSByZXR1cm4gdGVzdFxuICAgIH1cblxuICAgIHJldHVybiBhbGxcbn1cblxuZnVuY3Rpb24gbWFrZUhhc092ZXJsb2FkKGFsbCwgaW52ZXJ0LCBtZXNzYWdlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QsIGtleXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QgIT09IFwib2JqZWN0XCIgfHwgb2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgb2JqZWN0YCBtdXN0IGJlIGFuIG9iamVjdFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBrZXlzICE9PSBcIm9iamVjdFwiIHx8IGtleXMgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBrZXlzYCBtdXN0IGJlIGFuIG9iamVjdCBvciBhcnJheVwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoa2V5cykpIHtcbiAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCAmJiBoYXNLZXlzKGFsbCwgb2JqZWN0LCBrZXlzKSA9PT0gaW52ZXJ0KSB7XG4gICAgICAgICAgICAgICAgdXRpbC5mYWlsKG1lc3NhZ2UsIHthY3R1YWw6IG9iamVjdCwga2V5czoga2V5c30pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoT2JqZWN0LmtleXMoa2V5cykubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoaGFzVmFsdWVzKHV0aWwuc3RyaWN0SXMsIGFsbCwgb2JqZWN0LCBrZXlzKSA9PT0gaW52ZXJ0KSB7XG4gICAgICAgICAgICAgICAgdXRpbC5mYWlsKG1lc3NhZ2UsIHthY3R1YWw6IG9iamVjdCwga2V5czoga2V5c30pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIG1ha2VIYXNLZXlzKGZ1bmMsIGFsbCwgaW52ZXJ0LCBtZXNzYWdlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QsIGtleXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QgIT09IFwib2JqZWN0XCIgfHwgb2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgb2JqZWN0YCBtdXN0IGJlIGFuIG9iamVjdFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBrZXlzICE9PSBcIm9iamVjdFwiIHx8IGtleXMgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBrZXlzYCBtdXN0IGJlIGFuIG9iamVjdFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gZXhjbHVzaXZlIG9yIHRvIGludmVydCB0aGUgcmVzdWx0IGlmIGBpbnZlcnRgIGlzIHRydWVcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKGtleXMpLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKGhhc1ZhbHVlcyhmdW5jLCBhbGwsIG9iamVjdCwga2V5cykgPT09IGludmVydCkge1xuICAgICAgICAgICAgICAgIHV0aWwuZmFpbChtZXNzYWdlLCB7YWN0dWFsOiBvYmplY3QsIGtleXM6IGtleXN9KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cbmV4cG9ydHMuaGFzS2V5cyA9IG1ha2VIYXNPdmVybG9hZCh0cnVlLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxuZXhwb3J0cy5oYXNLZXlzRGVlcCA9IG1ha2VIYXNLZXlzKG1hdGNoLnN0cmljdCwgdHJ1ZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBhbGwga2V5cyBpbiB7a2V5c31cIilcbmV4cG9ydHMuaGFzS2V5c01hdGNoID0gbWFrZUhhc0tleXMobWF0Y2gubG9vc2UsIHRydWUsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxuZXhwb3J0cy5oYXNLZXlzQW55ID0gbWFrZUhhc092ZXJsb2FkKGZhbHNlLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGFueSBrZXkgaW4ge2tleXN9XCIpXG5leHBvcnRzLmhhc0tleXNBbnlEZWVwID0gbWFrZUhhc0tleXMobWF0Y2guc3RyaWN0LCBmYWxzZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBhbnkga2V5IGluIHtrZXlzfVwiKVxuZXhwb3J0cy5oYXNLZXlzQW55TWF0Y2ggPSBtYWtlSGFzS2V5cyhtYXRjaC5sb29zZSwgZmFsc2UsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFueSBrZXkgaW4ge2tleXN9XCIpXG5leHBvcnRzLm5vdEhhc0tleXNBbGwgPSBtYWtlSGFzT3ZlcmxvYWQodHJ1ZSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBhbGwga2V5cyBpbiB7a2V5c31cIilcbmV4cG9ydHMubm90SGFzS2V5c0FsbERlZXAgPSBtYWtlSGFzS2V5cyhtYXRjaC5zdHJpY3QsIHRydWUsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUgYWxsIGtleXMgaW4ge2tleXN9XCIpXG5leHBvcnRzLm5vdEhhc0tleXNBbGxNYXRjaCA9IG1ha2VIYXNLZXlzKG1hdGNoLmxvb3NlLCB0cnVlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbGwga2V5cyBpbiB7a2V5c31cIilcbmV4cG9ydHMubm90SGFzS2V5cyA9IG1ha2VIYXNPdmVybG9hZChmYWxzZSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBhbnkga2V5IGluIHtrZXlzfVwiKVxuZXhwb3J0cy5ub3RIYXNLZXlzRGVlcCA9IG1ha2VIYXNLZXlzKG1hdGNoLnN0cmljdCwgZmFsc2UsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUgYW55IGtleSBpbiB7a2V5c31cIilcbmV4cG9ydHMubm90SGFzS2V5c01hdGNoID0gbWFrZUhhc0tleXMobWF0Y2gubG9vc2UsIGZhbHNlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbnkga2V5IGluIHtrZXlzfVwiKVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIHV0aWwgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0LXV0aWxcIilcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5XG5cbmZ1bmN0aW9uIGhhcyhfKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlbiwgbWF4LXBhcmFtc1xuICAgIHJldHVybiBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIHtcbiAgICAgICAgICAgIGlmICghXy5oYXMob2JqZWN0LCBrZXkpIHx8XG4gICAgICAgICAgICAgICAgICAgICF1dGlsLnN0cmljdElzKF8uZ2V0KG9iamVjdCwga2V5KSwgdmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdXRpbC5mYWlsKF8ubWVzc2FnZXNbMF0sIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBhY3R1YWw6IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghXy5oYXMob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgICAgICB1dGlsLmZhaWwoXy5tZXNzYWdlc1sxXSwge1xuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICBhY3R1YWw6IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgICAgIG9iamVjdDogb2JqZWN0LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gaGFzTG9vc2UoXykge1xuICAgIHJldHVybiBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmICghXy5oYXMob2JqZWN0LCBrZXkpIHx8ICF1dGlsLmxvb3NlSXMoXy5nZXQob2JqZWN0LCBrZXkpLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgIHV0aWwuZmFpbChfLm1lc3NhZ2VzWzBdLCB7XG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IHZhbHVlLFxuICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0W2tleV0sXG4gICAgICAgICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBub3RIYXMoXykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW4sIG1heC1wYXJhbXNcbiAgICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSB7XG4gICAgICAgICAgICBpZiAoXy5oYXMob2JqZWN0LCBrZXkpICYmXG4gICAgICAgICAgICAgICAgICAgIHV0aWwuc3RyaWN0SXMoXy5nZXQob2JqZWN0LCBrZXkpLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB1dGlsLmZhaWwoXy5tZXNzYWdlc1syXSwge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0W2tleV0sXG4gICAgICAgICAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKF8uaGFzKG9iamVjdCwga2V5KSkge1xuICAgICAgICAgICAgdXRpbC5mYWlsKF8ubWVzc2FnZXNbM10sIHtcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogdmFsdWUsXG4gICAgICAgICAgICAgICAgYWN0dWFsOiBvYmplY3Rba2V5XSxcbiAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIG5vdEhhc0xvb3NlKF8pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuLCBtYXgtcGFyYW1zXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKF8uaGFzKG9iamVjdCwga2V5KSAmJiB1dGlsLmxvb3NlSXMoXy5nZXQob2JqZWN0LCBrZXkpLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgIHV0aWwuZmFpbChfLm1lc3NhZ2VzWzJdLCB7XG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IHZhbHVlLFxuICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0W2tleV0sXG4gICAgICAgICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBoYXNPd25LZXkob2JqZWN0LCBrZXkpIHsgcmV0dXJuIGhhc093bi5jYWxsKG9iamVjdCwga2V5KSB9XG5mdW5jdGlvbiBoYXNJbktleShvYmplY3QsIGtleSkgeyByZXR1cm4ga2V5IGluIG9iamVjdCB9XG5mdW5jdGlvbiBoYXNJbkNvbGwob2JqZWN0LCBrZXkpIHsgcmV0dXJuIG9iamVjdC5oYXMoa2V5KSB9XG5mdW5jdGlvbiBoYXNPYmplY3RHZXQob2JqZWN0LCBrZXkpIHsgcmV0dXJuIG9iamVjdFtrZXldIH1cbmZ1bmN0aW9uIGhhc0NvbGxHZXQob2JqZWN0LCBrZXkpIHsgcmV0dXJuIG9iamVjdC5nZXQoa2V5KSB9XG5cbmZ1bmN0aW9uIGNyZWF0ZUhhcyhoYXMsIGdldCwgbWVzc2FnZXMpIHtcbiAgICByZXR1cm4ge2hhczogaGFzLCBnZXQ6IGdldCwgbWVzc2FnZXM6IG1lc3NhZ2VzfVxufVxuXG52YXIgaGFzT3duTWV0aG9kcyA9IGNyZWF0ZUhhcyhoYXNPd25LZXksIGhhc09iamVjdEdldCwgW1xuICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gaGF2ZSBvd24ga2V5IHtrZXl9IGVxdWFsIHRvIHtleHBlY3RlZH0sIGJ1dCBmb3VuZCB7YWN0dWFsfVwiLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW5cbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUgb3duIGtleSB7ZXhwZWN0ZWR9XCIsXG4gICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBub3QgaGF2ZSBvd24ga2V5IHtrZXl9IGVxdWFsIHRvIHthY3R1YWx9XCIsXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBvd24ga2V5IHtleHBlY3RlZH1cIixcbl0pXG5cbnZhciBoYXNLZXlNZXRob2RzID0gY3JlYXRlSGFzKGhhc0luS2V5LCBoYXNPYmplY3RHZXQsIFtcbiAgICBcIkV4cGVjdGVkIHtvYmplY3R9IHRvIGhhdmUga2V5IHtrZXl9IGVxdWFsIHRvIHtleHBlY3RlZH0sIGJ1dCBmb3VuZCB7YWN0dWFsfVwiLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW5cbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUga2V5IHtleHBlY3RlZH1cIixcbiAgICBcIkV4cGVjdGVkIHtvYmplY3R9IHRvIG5vdCBoYXZlIGtleSB7a2V5fSBlcXVhbCB0byB7YWN0dWFsfVwiLFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUga2V5IHtleHBlY3RlZH1cIixcbl0pXG5cbnZhciBoYXNNZXRob2RzID0gY3JlYXRlSGFzKGhhc0luQ29sbCwgaGFzQ29sbEdldCwgW1xuICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gaGF2ZSBrZXkge2tleX0gZXF1YWwgdG8ge2V4cGVjdGVkfSwgYnV0IGZvdW5kIHthY3R1YWx9XCIsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBrZXkge2V4cGVjdGVkfVwiLFxuICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gbm90IGhhdmUga2V5IHtrZXl9IGVxdWFsIHRvIHthY3R1YWx9XCIsXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBrZXkge2V4cGVjdGVkfVwiLFxuXSlcblxuZXhwb3J0cy5oYXNPd24gPSBoYXMoaGFzT3duTWV0aG9kcylcbmV4cG9ydHMubm90SGFzT3duID0gbm90SGFzKGhhc093bk1ldGhvZHMpXG5leHBvcnRzLmhhc093bkxvb3NlID0gaGFzTG9vc2UoaGFzT3duTWV0aG9kcylcbmV4cG9ydHMubm90SGFzT3duTG9vc2UgPSBub3RIYXNMb29zZShoYXNPd25NZXRob2RzKVxuXG5leHBvcnRzLmhhc0tleSA9IGhhcyhoYXNLZXlNZXRob2RzKVxuZXhwb3J0cy5ub3RIYXNLZXkgPSBub3RIYXMoaGFzS2V5TWV0aG9kcylcbmV4cG9ydHMuaGFzS2V5TG9vc2UgPSBoYXNMb29zZShoYXNLZXlNZXRob2RzKVxuZXhwb3J0cy5ub3RIYXNLZXlMb29zZSA9IG5vdEhhc0xvb3NlKGhhc0tleU1ldGhvZHMpXG5cbmV4cG9ydHMuaGFzID0gaGFzKGhhc01ldGhvZHMpXG5leHBvcnRzLm5vdEhhcyA9IG5vdEhhcyhoYXNNZXRob2RzKVxuZXhwb3J0cy5oYXNMb29zZSA9IGhhc0xvb3NlKGhhc01ldGhvZHMpXG5leHBvcnRzLm5vdEhhc0xvb3NlID0gbm90SGFzTG9vc2UoaGFzTWV0aG9kcylcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBtYXRjaCA9IHJlcXVpcmUoXCJjbGVhbi1tYXRjaFwiKVxudmFyIHV0aWwgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0LXV0aWxcIilcblxuZnVuY3Rpb24gaW5jbHVkZXMoZnVuYywgYWxsLCBhcnJheSwgdmFsdWVzKSB7XG4gICAgLy8gQ2hlYXAgY2FzZXMgZmlyc3RcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyYXkpKSByZXR1cm4gZmFsc2VcbiAgICBpZiAoYXJyYXkgPT09IHZhbHVlcykgcmV0dXJuIHRydWVcbiAgICBpZiAoYWxsICYmIGFycmF5Lmxlbmd0aCA8IHZhbHVlcy5sZW5ndGgpIHJldHVybiBmYWxzZVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHZhbHVlID0gdmFsdWVzW2ldXG4gICAgICAgIHZhciB0ZXN0ID0gZmFsc2VcblxuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGFycmF5Lmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBpZiAoZnVuYyh2YWx1ZSwgYXJyYXlbal0pKSB7XG4gICAgICAgICAgICAgICAgdGVzdCA9IHRydWVcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRlc3QgIT09IGFsbCkgcmV0dXJuIHRlc3RcbiAgICB9XG5cbiAgICByZXR1cm4gYWxsXG59XG5cbmZ1bmN0aW9uIGRlZmluZUluY2x1ZGVzKGZ1bmMsIGFsbCwgaW52ZXJ0LCBtZXNzYWdlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChhcnJheSwgdmFsdWVzKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcnJheSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgYXJyYXlgIG11c3QgYmUgYW4gYXJyYXlcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZXMpKSB2YWx1ZXMgPSBbdmFsdWVzXVxuXG4gICAgICAgIGlmICh2YWx1ZXMubGVuZ3RoICYmIGluY2x1ZGVzKGZ1bmMsIGFsbCwgYXJyYXksIHZhbHVlcykgPT09IGludmVydCkge1xuICAgICAgICAgICAgdXRpbC5mYWlsKG1lc3NhZ2UsIHthY3R1YWw6IGFycmF5LCB2YWx1ZXM6IHZhbHVlc30pXG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxuZXhwb3J0cy5pbmNsdWRlcyA9IGRlZmluZUluY2x1ZGVzKHV0aWwuc3RyaWN0SXMsIHRydWUsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUgYWxsIHZhbHVlcyBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5pbmNsdWRlc0RlZXAgPSBkZWZpbmVJbmNsdWRlcyhtYXRjaC5zdHJpY3QsIHRydWUsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFsbCB2YWx1ZXMgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMuaW5jbHVkZXNNYXRjaCA9IGRlZmluZUluY2x1ZGVzKG1hdGNoLmxvb3NlLCB0cnVlLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBtYXRjaCBhbGwgdmFsdWVzIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLmluY2x1ZGVzQW55ID0gZGVmaW5lSW5jbHVkZXModXRpbC5zdHJpY3RJcywgZmFsc2UsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUgYW55IHZhbHVlIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLmluY2x1ZGVzQW55RGVlcCA9IGRlZmluZUluY2x1ZGVzKG1hdGNoLnN0cmljdCwgZmFsc2UsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFueSB2YWx1ZSBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5pbmNsdWRlc0FueU1hdGNoID0gZGVmaW5lSW5jbHVkZXMobWF0Y2gubG9vc2UsIGZhbHNlLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBtYXRjaCBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMubm90SW5jbHVkZXNBbGwgPSBkZWZpbmVJbmNsdWRlcyh1dGlsLnN0cmljdElzLCB0cnVlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGFsbCB2YWx1ZXMgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMubm90SW5jbHVkZXNBbGxEZWVwID0gZGVmaW5lSW5jbHVkZXMobWF0Y2guc3RyaWN0LCB0cnVlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbGwgdmFsdWVzIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLm5vdEluY2x1ZGVzQWxsTWF0Y2ggPSBkZWZpbmVJbmNsdWRlcyhtYXRjaC5sb29zZSwgdHJ1ZSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgbWF0Y2ggYWxsIHZhbHVlcyBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5ub3RJbmNsdWRlcyA9IGRlZmluZUluY2x1ZGVzKHV0aWwuc3RyaWN0SXMsIGZhbHNlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGFueSB2YWx1ZSBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5ub3RJbmNsdWRlc0RlZXAgPSBkZWZpbmVJbmNsdWRlcyhtYXRjaC5zdHJpY3QsIGZhbHNlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMubm90SW5jbHVkZXNNYXRjaCA9IGRlZmluZUluY2x1ZGVzKG1hdGNoLmxvb3NlLCBmYWxzZSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgbWF0Y2ggYW55IHZhbHVlIGluIHt2YWx1ZXN9XCIpXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKVxuXG5mdW5jdGlvbiBnZXROYW1lKGZ1bmMpIHtcbiAgICB2YXIgbmFtZSA9IGZ1bmMubmFtZVxuXG4gICAgaWYgKG5hbWUgPT0gbnVsbCkgbmFtZSA9IGZ1bmMuZGlzcGxheU5hbWVcbiAgICBpZiAobmFtZSkgcmV0dXJuIHV0aWwuZXNjYXBlKG5hbWUpXG4gICAgcmV0dXJuIFwiPGFub255bW91cz5cIlxufVxuXG5leHBvcnRzLnRocm93cyA9IGZ1bmN0aW9uIChUeXBlLCBjYWxsYmFjaykge1xuICAgIGlmIChjYWxsYmFjayA9PSBudWxsKSB7XG4gICAgICAgIGNhbGxiYWNrID0gVHlwZVxuICAgICAgICBUeXBlID0gbnVsbFxuICAgIH1cblxuICAgIGlmIChUeXBlICE9IG51bGwgJiYgdHlwZW9mIFR5cGUgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYFR5cGVgIG11c3QgYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBjYWxsYmFja2AgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgY2FsbGJhY2soKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGNhbGxiYWNrLXJldHVyblxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKFR5cGUgIT0gbnVsbCAmJiAhKGUgaW5zdGFuY2VvZiBUeXBlKSkge1xuICAgICAgICAgICAgdXRpbC5mYWlsKFxuICAgICAgICAgICAgICAgIFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gdGhyb3cgYW4gaW5zdGFuY2Ugb2YgXCIgKyBnZXROYW1lKFR5cGUpICtcbiAgICAgICAgICAgICAgICBcIiwgYnV0IGZvdW5kIHthY3R1YWx9XCIsXG4gICAgICAgICAgICAgICAge2FjdHVhbDogZX0pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IHV0aWwuQXNzZXJ0aW9uRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byB0aHJvd1wiKVxufVxuXG5mdW5jdGlvbiB0aHJvd3NNYXRjaFRlc3QobWF0Y2hlciwgZSkge1xuICAgIGlmICh0eXBlb2YgbWF0Y2hlciA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIGUubWVzc2FnZSA9PT0gbWF0Y2hlclxuICAgIGlmICh0eXBlb2YgbWF0Y2hlciA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gISFtYXRjaGVyKGUpXG4gICAgaWYgKG1hdGNoZXIgaW5zdGFuY2VvZiBSZWdFeHApIHJldHVybiAhIW1hdGNoZXIudGVzdChlLm1lc3NhZ2UpXG5cbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG1hdGNoZXIpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbaV1cblxuICAgICAgICBpZiAoIShrZXkgaW4gZSkgfHwgIXV0aWwuc3RyaWN0SXMobWF0Y2hlcltrZXldLCBlW2tleV0pKSByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZVxufVxuXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0KG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KSA9PT0gT2JqZWN0LnByb3RvdHlwZVxufVxuXG5leHBvcnRzLnRocm93c01hdGNoID0gZnVuY3Rpb24gKG1hdGNoZXIsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBtYXRjaGVyICE9PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICB0eXBlb2YgbWF0Y2hlciAhPT0gXCJmdW5jdGlvblwiICYmXG4gICAgICAgICAgICAhKG1hdGNoZXIgaW5zdGFuY2VvZiBSZWdFeHApICYmXG4gICAgICAgICAgICAhaXNQbGFpbk9iamVjdChtYXRjaGVyKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgXCJgbWF0Y2hlcmAgbXVzdCBiZSBhIHN0cmluZywgZnVuY3Rpb24sIFJlZ0V4cCwgb3Igb2JqZWN0XCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgY2FsbGJhY2tgIG11c3QgYmUgYSBmdW5jdGlvblwiKVxuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAgIGNhbGxiYWNrKCkgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjYWxsYmFjay1yZXR1cm5cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmICghdGhyb3dzTWF0Y2hUZXN0KG1hdGNoZXIsIGUpKSB7XG4gICAgICAgICAgICB1dGlsLmZhaWwoXG4gICAgICAgICAgICAgICAgXCJFeHBlY3RlZCBjYWxsYmFjayB0byAgdGhyb3cgYW4gZXJyb3IgdGhhdCBtYXRjaGVzIFwiICtcbiAgICAgICAgICAgICAgICBcIntleHBlY3RlZH0sIGJ1dCBmb3VuZCB7YWN0dWFsfVwiLFxuICAgICAgICAgICAgICAgIHtleHBlY3RlZDogbWF0Y2hlciwgYWN0dWFsOiBlfSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgdXRpbC5Bc3NlcnRpb25FcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIHRocm93LlwiKVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIHV0aWwgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0LXV0aWxcIilcblxuZXhwb3J0cy5vayA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKCF4KSB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSB0cnV0aHlcIiwge2FjdHVhbDogeH0pXG59XG5cbmV4cG9ydHMubm90T2sgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh4KSB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBmYWxzeVwiLCB7YWN0dWFsOiB4fSlcbn1cblxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCAhPT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYSBib29sZWFuXCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5ub3RCb29sZWFuID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBhIGJvb2xlYW5cIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLmlzRnVuY3Rpb24gPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGEgZnVuY3Rpb25cIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdEZ1bmN0aW9uID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgYmUgYSBmdW5jdGlvblwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMuaXNOdW1iZXIgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhIG51bWJlclwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90TnVtYmVyID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGJlIGEgbnVtYmVyXCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5pc09iamVjdCA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSBcIm9iamVjdFwiIHx8IHggPT0gbnVsbCkge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhbiBvYmplY3RcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdE9iamVjdCA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ID09PSBcIm9iamVjdFwiICYmIHggIT0gbnVsbCkge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgYmUgYW4gb2JqZWN0XCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5pc1N0cmluZyA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGEgc3RyaW5nXCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5ub3RTdHJpbmcgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgYmUgYSBzdHJpbmdcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLmlzU3ltYm9sID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggIT09IFwic3ltYm9sXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYSBzeW1ib2xcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdFN5bWJvbCA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ID09PSBcInN5bWJvbFwiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBhIHN5bWJvbFwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMuZXhpc3RzID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAoeCA9PSBudWxsKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGV4aXN0XCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5ub3RFeGlzdHMgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh4ICE9IG51bGwpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGV4aXN0XCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5pc0FycmF5ID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoeCkpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYW4gYXJyYXlcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdEFycmF5ID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh4KSkge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgYmUgYW4gYXJyYXlcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLmlzID0gZnVuY3Rpb24gKFR5cGUsIG9iamVjdCkge1xuICAgIGlmICh0eXBlb2YgVHlwZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgVHlwZWAgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgfVxuXG4gICAgaWYgKCEob2JqZWN0IGluc3RhbmNlb2YgVHlwZSkpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge29iamVjdH0gdG8gYmUgYW4gaW5zdGFuY2Ugb2Yge2V4cGVjdGVkfVwiLCB7XG4gICAgICAgICAgICBleHBlY3RlZDogVHlwZSxcbiAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgIH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdCA9IGZ1bmN0aW9uIChUeXBlLCBvYmplY3QpIHtcbiAgICBpZiAodHlwZW9mIFR5cGUgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYFR5cGVgIG11c3QgYmUgYSBmdW5jdGlvblwiKVxuICAgIH1cblxuICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBUeXBlKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHtvYmplY3R9IHRvIG5vdCBiZSBhbiBpbnN0YW5jZSBvZiB7ZXhwZWN0ZWR9XCIsIHtcbiAgICAgICAgICAgIGV4cGVjdGVkOiBUeXBlLFxuICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgIH0pXG4gICAgfVxufVxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogY2xlYW4tbWF0Y2hcbiAqXG4gKiBBIHNpbXBsZSwgZmFzdCBFUzIwMTUrIGF3YXJlIGRlZXAgbWF0Y2hpbmcgdXRpbGl0eS5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYgYW5kIGxhdGVyLCBJc2lhaCBNZWFkb3dzIDxtZUBpc2lhaG1lYWRvd3MuY29tPi5cbiAqXG4gKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcbiAqIHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmVcbiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxuICogUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXG4gKiBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXG4gKiBJTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cbiAqIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXG4gKiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXG4gKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxuICovXG5cbi8qIGVzbGludC1kaXNhYmxlICovXG47KGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIgJiYgZXhwb3J0cyAhPSBudWxsKSB7XG4gICAgICAgIGZhY3RvcnkoZ2xvYmFsLCBleHBvcnRzKVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGRlZmluZShcImNsZWFuLW1hdGNoXCIsIFtcImV4cG9ydHNcIl0sIGZ1bmN0aW9uIChleHBvcnRzKSB7XG4gICAgICAgICAgICBmYWN0b3J5KGdsb2JhbCwgZXhwb3J0cylcbiAgICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgICBmYWN0b3J5KGdsb2JhbCwgZ2xvYmFsLm1hdGNoID0ge30pXG4gICAgfVxufSkodHlwZW9mIGdsb2JhbCA9PT0gXCJvYmplY3RcIiAmJiBnbG9iYWwgIT09IG51bGwgPyBnbG9iYWxcbiAgICA6IHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiICYmIHNlbGYgIT09IG51bGwgPyBzZWxmXG4gICAgOiB0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiICYmIHdpbmRvdyAhPT0gbnVsbCA/IHdpbmRvd1xuICAgIDogdGhpcyxcbmZ1bmN0aW9uIChnbG9iYWwsIGV4cG9ydHMpIHtcbiAgICAvKiBlc2xpbnQtZW5hYmxlICovXG4gICAgXCJ1c2Ugc3RyaWN0XCJcblxuICAgIC8qIGdsb2JhbCBTeW1ib2wsIFVpbnQ4QXJyYXksIERhdGFWaWV3LCBBcnJheUJ1ZmZlciwgQXJyYXlCdWZmZXJWaWV3LCBNYXAsXG4gICAgU2V0ICovXG5cbiAgICAvKipcbiAgICAgKiBEZWVwIG1hdGNoaW5nIGFsZ29yaXRobSwgd2l0aCB6ZXJvIGRlcGVuZGVuY2llcy4gTm90ZSB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBUaGlzIGlzIHJlbGF0aXZlbHkgcGVyZm9ybWFuY2UtdHVuZWQsIGFsdGhvdWdoIGl0IHByZWZlcnMgaGlnaFxuICAgICAqICAgY29ycmVjdG5lc3MuIFBhdGNoIHdpdGggY2FyZSwgc2luY2UgcGVyZm9ybWFuY2UgaXMgYSBjb25jZXJuLlxuICAgICAqIC0gVGhpcyBkb2VzIHBhY2sgYSAqbG90KiBvZiBmZWF0dXJlcywgd2hpY2ggc2hvdWxkIGV4cGxhaW4gdGhlIGxlbmd0aC5cbiAgICAgKiAtIFNvbWUgb2YgdGhlIGR1cGxpY2F0aW9uIGlzIGludGVudGlvbmFsLiBJdCdzIGdlbmVyYWxseSBjb21tZW50ZWQsIGJ1dFxuICAgICAqICAgaXQncyBtYWlubHkgZm9yIHBlcmZvcm1hbmNlLCBzaW5jZSB0aGUgZW5naW5lIG5lZWRzIGl0cyB0eXBlIGluZm8uXG4gICAgICogLSBQb2x5ZmlsbGVkIGNvcmUtanMgU3ltYm9scyBmcm9tIGNyb3NzLW9yaWdpbiBjb250ZXh0cyB3aWxsIG5ldmVyXG4gICAgICogICByZWdpc3RlciBhcyBiZWluZyBhY3R1YWwgU3ltYm9scy5cbiAgICAgKlxuICAgICAqIEFuZCBpbiBjYXNlIHlvdSdyZSB3b25kZXJpbmcgYWJvdXQgdGhlIGxvbmdlciBmdW5jdGlvbnMgYW5kIG9jY2FzaW9uYWxcbiAgICAgKiByZXBldGl0aW9uLCBpdCdzIGJlY2F1c2UgVjgncyBpbmxpbmVyIGlzbid0IGFsd2F5cyBpbnRlbGxpZ2VudCBlbm91Z2ggdG9cbiAgICAgKiBkZWFsIHdpdGggdGhlIHN1cGVyIGhpZ2hseSBwb2x5bW9ycGhpYyBkYXRhIHRoaXMgb2Z0ZW4gZGVhbHMgd2l0aCwgYW5kIEpTXG4gICAgICogZG9lc24ndCBoYXZlIGNvbXBpbGUtdGltZSBtYWNyb3MuXG4gICAgICovXG5cbiAgICB2YXIgb2JqZWN0VG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nXG4gICAgdmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuICAgIHZhciBzdXBwb3J0c1VuaWNvZGUgPSBoYXNPd24uY2FsbChSZWdFeHAucHJvdG90eXBlLCBcInVuaWNvZGVcIilcbiAgICB2YXIgc3VwcG9ydHNTdGlja3kgPSBoYXNPd24uY2FsbChSZWdFeHAucHJvdG90eXBlLCBcInN0aWNreVwiKVxuXG4gICAgLy8gTGVnYWN5IGVuZ2luZXMgaGF2ZSBzZXZlcmFsIGlzc3VlcyB3aGVuIGl0IGNvbWVzIHRvIGB0eXBlb2ZgLlxuICAgIHZhciBpc0Z1bmN0aW9uID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZnVuY3Rpb24gU2xvd0lzRnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSByZXR1cm4gZmFsc2VcblxuICAgICAgICAgICAgdmFyIHRhZyA9IG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpXG5cbiAgICAgICAgICAgIHJldHVybiB0YWcgPT09IFwiW29iamVjdCBGdW5jdGlvbl1cIiB8fFxuICAgICAgICAgICAgICAgIHRhZyA9PT0gXCJbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXVwiIHx8XG4gICAgICAgICAgICAgICAgdGFnID09PSBcIltvYmplY3QgQXN5bmNGdW5jdGlvbl1cIiB8fFxuICAgICAgICAgICAgICAgIHRhZyA9PT0gXCJbb2JqZWN0IFByb3h5XVwiXG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBpc1BvaXNvbmVkKG9iamVjdCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIHR5cGVvZiBvYmplY3QgIT09IFwiZnVuY3Rpb25cIlxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSW4gU2FmYXJpIDEwLCBgdHlwZW9mIFByb3h5ID09PSBcIm9iamVjdFwiYFxuICAgICAgICBpZiAoaXNQb2lzb25lZChnbG9iYWwuUHJveHkpKSByZXR1cm4gU2xvd0lzRnVuY3Rpb25cblxuICAgICAgICAvLyBJbiBTYWZhcmkgOCwgc2V2ZXJhbCB0eXBlZCBhcnJheSBjb25zdHJ1Y3RvcnMgYXJlXG4gICAgICAgIC8vIGB0eXBlb2YgQyA9PT0gXCJvYmplY3RcImBcbiAgICAgICAgaWYgKGlzUG9pc29uZWQoZ2xvYmFsLkludDhBcnJheSkpIHJldHVybiBTbG93SXNGdW5jdGlvblxuXG4gICAgICAgIC8vIEluIG9sZCBWOCwgUmVnRXhwcyBhcmUgY2FsbGFibGVcbiAgICAgICAgaWYgKHR5cGVvZiAveC8gPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFNsb3dJc0Z1bmN0aW9uIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAgICAgICAvLyBMZWF2ZSB0aGlzIGZvciBub3JtYWwgdGhpbmdzLiBJdCdzIGVhc2lseSBpbmxpbmVkLlxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgIH1cbiAgICB9KSgpXG5cbiAgICAvLyBTZXQgdXAgb3VyIG93biBidWZmZXIgY2hlY2suIFdlIHNob3VsZCBhbHdheXMgYWNjZXB0IHRoZSBwb2x5ZmlsbCwgZXZlblxuICAgIC8vIGluIE5vZGUuIE5vdGUgdGhhdCBpdCB1c2VzIGBnbG9iYWwuQnVmZmVyYCB0byBhdm9pZCBpbmNsdWRpbmcgYGJ1ZmZlcmAgaW5cbiAgICAvLyB0aGUgYnVuZGxlLlxuXG4gICAgdmFyIEJ1ZmZlck5hdGl2ZSA9IDBcbiAgICB2YXIgQnVmZmVyUG9seWZpbGwgPSAxXG4gICAgdmFyIEJ1ZmZlclNhZmFyaSA9IDJcblxuICAgIHZhciBidWZmZXJTdXBwb3J0ID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZnVuY3Rpb24gRmFrZUJ1ZmZlcigpIHt9XG4gICAgICAgIEZha2VCdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlIH1cblxuICAgICAgICAvLyBPbmx5IFNhZmFyaSA1LTcgaGFzIGV2ZXIgaGFkIHRoaXMgaXNzdWUuXG4gICAgICAgIGlmIChuZXcgRmFrZUJ1ZmZlcigpLmNvbnN0cnVjdG9yICE9PSBGYWtlQnVmZmVyKSByZXR1cm4gQnVmZmVyU2FmYXJpXG4gICAgICAgIGlmICghaXNGdW5jdGlvbihnbG9iYWwuQnVmZmVyKSkgcmV0dXJuIEJ1ZmZlclBvbHlmaWxsXG4gICAgICAgIGlmICghaXNGdW5jdGlvbihnbG9iYWwuQnVmZmVyLmlzQnVmZmVyKSkgcmV0dXJuIEJ1ZmZlclBvbHlmaWxsXG4gICAgICAgIC8vIEF2b2lkIGdsb2JhbCBwb2x5ZmlsbHNcbiAgICAgICAgaWYgKGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIobmV3IEZha2VCdWZmZXIoKSkpIHJldHVybiBCdWZmZXJQb2x5ZmlsbFxuICAgICAgICByZXR1cm4gQnVmZmVyTmF0aXZlXG4gICAgfSkoKVxuXG4gICAgdmFyIGdsb2JhbElzQnVmZmVyID0gYnVmZmVyU3VwcG9ydCA9PT0gQnVmZmVyTmF0aXZlXG4gICAgICAgID8gZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlclxuICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgZnVuY3Rpb24gaXNCdWZmZXIob2JqZWN0KSB7XG4gICAgICAgIGlmIChidWZmZXJTdXBwb3J0ID09PSBCdWZmZXJOYXRpdmUgJiYgZ2xvYmFsSXNCdWZmZXIob2JqZWN0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSBlbHNlIGlmIChidWZmZXJTdXBwb3J0ID09PSBCdWZmZXJTYWZhcmkgJiYgb2JqZWN0Ll9pc0J1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBCID0gb2JqZWN0LmNvbnN0cnVjdG9yXG5cbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKEIpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKEIuaXNCdWZmZXIpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgcmV0dXJuIEIuaXNCdWZmZXIob2JqZWN0KVxuICAgIH1cblxuICAgIC8vIGNvcmUtanMnIHN5bWJvbHMgYXJlIG9iamVjdHMsIGFuZCBzb21lIG9sZCB2ZXJzaW9ucyBvZiBWOCBlcnJvbmVvdXNseSBoYWRcbiAgICAvLyBgdHlwZW9mIFN5bWJvbCgpID09PSBcIm9iamVjdFwiYC5cbiAgICB2YXIgc3ltYm9sc0FyZU9iamVjdHMgPSBpc0Z1bmN0aW9uKGdsb2JhbC5TeW1ib2wpICYmXG4gICAgICAgIHR5cGVvZiBTeW1ib2woKSA9PT0gXCJvYmplY3RcIlxuXG4gICAgLy8gYGNvbnRleHRgIGlzIGEgYml0IGZpZWxkLCB3aXRoIHRoZSBmb2xsb3dpbmcgYml0cy4gVGhpcyBpcyBub3QgYXMgbXVjaFxuICAgIC8vIGZvciBwZXJmb3JtYW5jZSB0aGFuIHRvIGp1c3QgcmVkdWNlIHRoZSBudW1iZXIgb2YgcGFyYW1ldGVycyBJIG5lZWQgdG8gYmVcbiAgICAvLyB0aHJvd2luZyBhcm91bmQuXG4gICAgdmFyIFN0cmljdCA9IDFcbiAgICB2YXIgSW5pdGlhbCA9IDJcbiAgICB2YXIgU2FtZVByb3RvID0gNFxuXG4gICAgZXhwb3J0cy5sb29zZSA9IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBtYXRjaChhLCBiLCBJbml0aWFsLCB1bmRlZmluZWQsIHVuZGVmaW5lZClcbiAgICB9XG5cbiAgICBleHBvcnRzLnN0cmljdCA9IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBtYXRjaChhLCBiLCBTdHJpY3QgfCBJbml0aWFsLCB1bmRlZmluZWQsIHVuZGVmaW5lZClcbiAgICB9XG5cbiAgICAvLyBGZWF0dXJlLXRlc3QgZGVsYXllZCBzdGFjayBhZGRpdGlvbnMgYW5kIGV4dHJhIGtleXMuIFBoYW50b21KUyBhbmQgSUVcbiAgICAvLyBib3RoIHdhaXQgdW50aWwgdGhlIGVycm9yIHdhcyBhY3R1YWxseSB0aHJvd24gZmlyc3QsIGFuZCBhc3NpZ24gdGhlbSBhc1xuICAgIC8vIG93biBwcm9wZXJ0aWVzLCB3aGljaCBpcyB1bmhlbHBmdWwgZm9yIGFzc2VydGlvbnMuIFRoaXMgcmV0dXJucyBhXG4gICAgLy8gZnVuY3Rpb24gdG8gc3BlZWQgdXAgY2FzZXMgd2hlcmUgYE9iamVjdC5rZXlzYCBpcyBzdWZmaWNpZW50IChlLmcuIGluXG4gICAgLy8gQ2hyb21lL0ZGL05vZGUpLlxuICAgIC8vXG4gICAgLy8gVGhpcyB3b3VsZG4ndCBiZSBuZWNlc3NhcnkgaWYgdGhvc2UgZW5naW5lcyB3b3VsZCBtYWtlIHRoZSBzdGFjayBhXG4gICAgLy8gZ2V0dGVyLCBhbmQgcmVjb3JkIGl0IHdoZW4gdGhlIGVycm9yIHdhcyBjcmVhdGVkLCBub3Qgd2hlbiBpdCB3YXMgdGhyb3duLlxuICAgIC8vIEl0IHNwZWNpZmljYWxseSBmaWx0ZXJzIG91dCBlcnJvcnMgYW5kIG9ubHkgY2hlY2tzIGV4aXN0aW5nIGRlc2NyaXB0b3JzLFxuICAgIC8vIGp1c3QgdG8ga2VlcCB0aGUgbWVzcyBmcm9tIGFmZmVjdGluZyBldmVyeXRoaW5nIChpdCdzIG5vdCBmdWxseSBjb3JyZWN0LFxuICAgIC8vIGJ1dCBpdCdzIG5lY2Vzc2FyeSkuXG4gICAgdmFyIHJlcXVpcmVzUHJveHkgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGVzdCA9IG5ldyBFcnJvcigpXG4gICAgICAgIHZhciBvbGQgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgICAgICAgT2JqZWN0LmtleXModGVzdCkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7IG9sZFtrZXldID0gdHJ1ZSB9KVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aHJvdyB0ZXN0XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICAgIC8vIGlnbm9yZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRlc3QpLnNvbWUoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gIW9sZFtrZXldIH0pXG4gICAgfSkoKVxuXG4gICAgZnVuY3Rpb24gaXNJZ25vcmVkKG9iamVjdCwga2V5KSB7XG4gICAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgIGNhc2UgXCJsaW5lXCI6IGlmICh0eXBlb2Ygb2JqZWN0LmxpbmUgIT09IFwibnVtYmVyXCIpIHJldHVybiBmYWxzZTsgYnJlYWtcbiAgICAgICAgY2FzZSBcInNvdXJjZVVSTFwiOlxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc291cmNlVVJMICE9PSBcInN0cmluZ1wiKSByZXR1cm4gZmFsc2U7IGJyZWFrXG4gICAgICAgIGNhc2UgXCJzdGFja1wiOiBpZiAodHlwZW9mIG9iamVjdC5zdGFjayAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIGZhbHNlOyBicmVha1xuICAgICAgICBkZWZhdWx0OiByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIGtleSlcblxuICAgICAgICByZXR1cm4gIWRlc2MuY29uZmlndXJhYmxlICYmIGRlc2MuZW51bWVyYWJsZSAmJiAhZGVzYy53cml0YWJsZVxuICAgIH1cblxuICAgIC8vIFRoaXMgaXMgb25seSBpbnZva2VkIHdpdGggZXJyb3JzLCBzbyBpdCdzIG5vdCBnb2luZyB0byBwcmVzZW50IGFcbiAgICAvLyBzaWduaWZpY2FudCBzbG93IGRvd24uXG4gICAgZnVuY3Rpb24gZ2V0S2V5c1N0cmlwcGVkKG9iamVjdCkge1xuICAgICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdClcbiAgICAgICAgdmFyIGNvdW50ID0gMFxuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKCFpc0lnbm9yZWQob2JqZWN0LCBrZXlzW2ldKSkga2V5c1tjb3VudCsrXSA9IGtleXNbaV1cbiAgICAgICAgfVxuXG4gICAgICAgIGtleXMubGVuZ3RoID0gY291bnRcbiAgICAgICAgcmV0dXJuIGtleXNcbiAgICB9XG5cbiAgICAvLyBXYXkgZmFzdGVyLCBzaW5jZSB0eXBlZCBhcnJheSBpbmRpY2VzIGFyZSBhbHdheXMgZGVuc2UgYW5kIGNvbnRhaW5cbiAgICAvLyBudW1iZXJzLlxuXG4gICAgLy8gU2V0dXAgZm9yIGBpc0J1ZmZlck9yVmlld2AgYW5kIGBpc1ZpZXdgXG4gICAgdmFyIEFycmF5QnVmZmVyTm9uZSA9IDBcbiAgICB2YXIgQXJyYXlCdWZmZXJMZWdhY3kgPSAxXG4gICAgdmFyIEFycmF5QnVmZmVyQ3VycmVudCA9IDJcblxuICAgIHZhciBhcnJheUJ1ZmZlclN1cHBvcnQgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWlzRnVuY3Rpb24oZ2xvYmFsLlVpbnQ4QXJyYXkpKSByZXR1cm4gQXJyYXlCdWZmZXJOb25lXG4gICAgICAgIGlmICghaXNGdW5jdGlvbihnbG9iYWwuRGF0YVZpZXcpKSByZXR1cm4gQXJyYXlCdWZmZXJOb25lXG4gICAgICAgIGlmICghaXNGdW5jdGlvbihnbG9iYWwuQXJyYXlCdWZmZXIpKSByZXR1cm4gQXJyYXlCdWZmZXJOb25lXG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKGdsb2JhbC5BcnJheUJ1ZmZlci5pc1ZpZXcpKSByZXR1cm4gQXJyYXlCdWZmZXJDdXJyZW50XG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKGdsb2JhbC5BcnJheUJ1ZmZlclZpZXcpKSByZXR1cm4gQXJyYXlCdWZmZXJMZWdhY3lcbiAgICAgICAgcmV0dXJuIEFycmF5QnVmZmVyTm9uZVxuICAgIH0pKClcblxuICAgIC8vIElmIHR5cGVkIGFycmF5cyBhcmVuJ3Qgc3VwcG9ydGVkICh0aGV5IHdlcmVuJ3QgdGVjaG5pY2FsbHkgcGFydCBvZlxuICAgIC8vIEVTNSwgYnV0IG1hbnkgZW5naW5lcyBpbXBsZW1lbnRlZCBLaHJvbm9zJyBzcGVjIGJlZm9yZSBFUzYpLCB0aGVuXG4gICAgLy8ganVzdCBmYWxsIGJhY2sgdG8gZ2VuZXJpYyBidWZmZXIgZGV0ZWN0aW9uLlxuXG4gICAgZnVuY3Rpb24gZmxvYXRJcyhhLCBiKSB7XG4gICAgICAgIC8vIFNvIE5hTnMgYXJlIGNvbnNpZGVyZWQgZXF1YWwuXG4gICAgICAgIHJldHVybiBhID09PSBiIHx8IGEgIT09IGEgJiYgYiAhPT0gYiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZSwgbWF4LWxlblxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoVmlldyhhLCBiKSB7XG4gICAgICAgIHZhciBjb3VudCA9IGEubGVuZ3RoXG5cbiAgICAgICAgaWYgKGNvdW50ICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG5cbiAgICAgICAgd2hpbGUgKGNvdW50KSB7XG4gICAgICAgICAgICBjb3VudC0tXG4gICAgICAgICAgICBpZiAoIWZsb2F0SXMoYVtjb3VudF0sIGJbY291bnRdKSkgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHZhciBpc1ZpZXcgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoYXJyYXlCdWZmZXJTdXBwb3J0ID09PSBBcnJheUJ1ZmZlck5vbmUpIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgLy8gRVM2IHR5cGVkIGFycmF5c1xuICAgICAgICBpZiAoYXJyYXlCdWZmZXJTdXBwb3J0ID09PSBBcnJheUJ1ZmZlckN1cnJlbnQpIHJldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXdcbiAgICAgICAgLy8gbGVnYWN5IHR5cGVkIGFycmF5c1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gaXNWaWV3KG9iamVjdCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyVmlld1xuICAgICAgICB9XG4gICAgfSkoKVxuXG4gICAgLy8gU3VwcG9ydCBjaGVja2luZyBtYXBzIGFuZCBzZXRzIGRlZXBseS4gVGhleSBhcmUgb2JqZWN0LWxpa2UgZW5vdWdoIHRvXG4gICAgLy8gY291bnQsIGFuZCBhcmUgdXNlZnVsIGluIHRoZWlyIG93biByaWdodC4gVGhlIGNvZGUgaXMgcmF0aGVyIG1lc3N5LCBidXRcbiAgICAvLyBtYWlubHkgdG8ga2VlcCB0aGUgb3JkZXItaW5kZXBlbmRlbnQgY2hlY2tpbmcgZnJvbSBiZWNvbWluZyBpbnNhbmVseVxuICAgIC8vIHNsb3cuXG4gICAgdmFyIHN1cHBvcnRzTWFwID0gaXNGdW5jdGlvbihnbG9iYWwuTWFwKVxuICAgIHZhciBzdXBwb3J0c1NldCA9IGlzRnVuY3Rpb24oZ2xvYmFsLlNldClcblxuICAgIC8vIE9uZSBvZiB0aGUgc2V0cyBhbmQgYm90aCBtYXBzJyBrZXlzIGFyZSBjb252ZXJ0ZWQgdG8gYXJyYXlzIGZvciBmYXN0ZXJcbiAgICAvLyBoYW5kbGluZy5cbiAgICBmdW5jdGlvbiBrZXlMaXN0KG1hcCkge1xuICAgICAgICB2YXIgbGlzdCA9IG5ldyBBcnJheShtYXAuc2l6ZSlcbiAgICAgICAgdmFyIGkgPSAwXG4gICAgICAgIHZhciBpdGVyID0gbWFwLmtleXMoKVxuXG4gICAgICAgIGZvciAodmFyIG5leHQgPSBpdGVyLm5leHQoKTsgIW5leHQuZG9uZTsgbmV4dCA9IGl0ZXIubmV4dCgpKSB7XG4gICAgICAgICAgICBsaXN0W2krK10gPSBuZXh0LnZhbHVlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbGlzdFxuICAgIH1cblxuICAgIC8vIFRoZSBwYWlyIG9mIGFycmF5cyBhcmUgYWxpZ25lZCBpbiBhIHNpbmdsZSBPKG5eMikgb3BlcmF0aW9uIChtb2QgZGVlcFxuICAgIC8vIG1hdGNoaW5nIGFuZCByb3RhdGlvbiksIGFkYXB0aW5nIHRvIE8obikgd2hlbiB0aGV5J3JlIGFscmVhZHkgYWxpZ25lZC5cbiAgICBmdW5jdGlvbiBtYXRjaEtleShjdXJyZW50LCBha2V5cywgc3RhcnQsIGVuZCwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIGZvciAodmFyIGkgPSBzdGFydCArIDE7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgICAgICAgdmFyIGtleSA9IGFrZXlzW2ldXG5cbiAgICAgICAgICAgIGlmIChtYXRjaChjdXJyZW50LCBrZXksIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgICAgIC8vIFRPRE86IG9uY2UgZW5naW5lcyBhY3R1YWxseSBvcHRpbWl6ZSBgY29weVdpdGhpbmAsIHVzZSB0aGF0XG4gICAgICAgICAgICAgICAgLy8gaW5zdGVhZC4gSXQnbGwgYmUgbXVjaCBmYXN0ZXIgdGhhbiB0aGlzIGxvb3AuXG4gICAgICAgICAgICAgICAgd2hpbGUgKGkgPiBzdGFydCkgYWtleXNbaV0gPSBha2V5c1stLWldXG4gICAgICAgICAgICAgICAgYWtleXNbaV0gPSBrZXlcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF0Y2hWYWx1ZXMoYSwgYiwgYWtleXMsIGJrZXlzLCBlbmQsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIW1hdGNoKGEuZ2V0KGFrZXlzW2ldKSwgYi5nZXQoYmtleXNbaV0pLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LCBsZWZ0LCByaWdodCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgLy8gUG9zc2libHkgZXhwZW5zaXZlIG9yZGVyLWluZGVwZW5kZW50IGtleS12YWx1ZSBtYXRjaC4gRmlyc3QsIHRyeSB0byBhdm9pZFxuICAgIC8vIGl0IGJ5IGNvbnNlcnZhdGl2ZWx5IGFzc3VtaW5nIGV2ZXJ5dGhpbmcgaXMgaW4gb3JkZXIgLSBhIGNoZWFwIE8obikgaXNcbiAgICAvLyBhbHdheXMgbmljZXIgdGhhbiBhbiBleHBlbnNpdmUgTyhuXjIpLlxuICAgIGZ1bmN0aW9uIG1hdGNoTWFwKGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICB2YXIgZW5kID0gYS5zaXplXG4gICAgICAgIHZhciBha2V5cyA9IGtleUxpc3QoYSlcbiAgICAgICAgdmFyIGJrZXlzID0ga2V5TGlzdChiKVxuICAgICAgICB2YXIgaSA9IDBcblxuICAgICAgICB3aGlsZSAoaSAhPT0gZW5kICYmIG1hdGNoKGFrZXlzW2ldLCBia2V5c1tpXSwgY29udGV4dCwgbGVmdCwgcmlnaHQpKSB7XG4gICAgICAgICAgICBpKytcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpID09PSBlbmQpIHtcbiAgICAgICAgICAgIHJldHVybiBtYXRjaFZhbHVlcyhhLCBiLCBha2V5cywgYmtleXMsIGVuZCwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBEb24ndCBjb21wYXJlIHRoZSBzYW1lIGtleSB0d2ljZVxuICAgICAgICBpZiAoIW1hdGNoS2V5KGJrZXlzW2ldLCBha2V5cywgaSwgZW5kLCBjb250ZXh0LCBsZWZ0LCByaWdodCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhlIGFib3ZlIGZhaWxzLCB3aGlsZSB3ZSdyZSBhdCBpdCwgbGV0J3Mgc29ydCB0aGVtIGFzIHdlIGdvLCBzb1xuICAgICAgICAvLyB0aGUga2V5IG9yZGVyIG1hdGNoZXMuXG4gICAgICAgIHdoaWxlICgrK2kgPCBlbmQpIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBia2V5c1tpXVxuXG4gICAgICAgICAgICAvLyBBZGFwdCBpZiB0aGUga2V5cyBhcmUgYWxyZWFkeSBpbiBvcmRlciwgd2hpY2ggaXMgZnJlcXVlbnRseSB0aGVcbiAgICAgICAgICAgIC8vIGNhc2UuXG4gICAgICAgICAgICBpZiAoIW1hdGNoKGtleSwgYWtleXNbaV0sIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSAmJlxuICAgICAgICAgICAgICAgICAgICAhbWF0Y2hLZXkoa2V5LCBha2V5cywgaSwgZW5kLCBjb250ZXh0LCBsZWZ0LCByaWdodCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtYXRjaFZhbHVlcyhhLCBiLCBha2V5cywgYmtleXMsIGVuZCwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzQWxsSWRlbnRpY2FsKGFsaXN0LCBiKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYWxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghYi5oYXMoYWxpc3RbaV0pKSByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgLy8gQ29tcGFyZSB0aGUgdmFsdWVzIHN0cnVjdHVyYWxseSwgYW5kIGluZGVwZW5kZW50IG9mIG9yZGVyLlxuICAgIGZ1bmN0aW9uIHNlYXJjaEZvcihhdmFsdWUsIG9iamVjdHMsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICBmb3IgKHZhciBqIGluIG9iamVjdHMpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd24uY2FsbChvYmplY3RzLCBqKSkge1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaChhdmFsdWUsIG9iamVjdHNbal0sIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgb2JqZWN0c1tqXVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhc1N0cnVjdHVyZSh2YWx1ZSwgY29udGV4dCkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHZhbHVlICE9PSBudWxsIHx8XG4gICAgICAgICAgICAgICAgIShjb250ZXh0ICYgU3RyaWN0KSAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3ltYm9sXCJcbiAgICB9XG5cbiAgICAvLyBUaGUgc2V0IGFsZ29yaXRobSBpcyBzdHJ1Y3R1cmVkIGEgbGl0dGxlIGRpZmZlcmVudGx5LiBJdCB0YWtlcyBvbmUgb2YgdGhlXG4gICAgLy8gc2V0cyBpbnRvIGFuIGFycmF5LCBkb2VzIGEgY2hlYXAgaWRlbnRpdHkgY2hlY2ssIHRoZW4gZG9lcyB0aGUgZGVlcFxuICAgIC8vIGNoZWNrLlxuICAgIGZ1bmN0aW9uIG1hdGNoU2V0KGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICAvLyBUaGlzIGlzIHRvIHRyeSB0byBhdm9pZCBhbiBleHBlbnNpdmUgc3RydWN0dXJhbCBtYXRjaCBvbiB0aGUga2V5cy5cbiAgICAgICAgLy8gVGVzdCBmb3IgaWRlbnRpdHkgZmlyc3QuXG4gICAgICAgIHZhciBhbGlzdCA9IGtleUxpc3QoYSlcblxuICAgICAgICBpZiAoaGFzQWxsSWRlbnRpY2FsKGFsaXN0LCBiKSkgcmV0dXJuIHRydWVcblxuICAgICAgICB2YXIgaXRlciA9IGIudmFsdWVzKClcbiAgICAgICAgdmFyIGNvdW50ID0gMFxuICAgICAgICB2YXIgb2JqZWN0c1xuXG4gICAgICAgIC8vIEdhdGhlciBhbGwgdGhlIG9iamVjdHNcbiAgICAgICAgZm9yICh2YXIgbmV4dCA9IGl0ZXIubmV4dCgpOyAhbmV4dC5kb25lOyBuZXh0ID0gaXRlci5uZXh0KCkpIHtcbiAgICAgICAgICAgIHZhciBidmFsdWUgPSBuZXh0LnZhbHVlXG5cbiAgICAgICAgICAgIGlmIChoYXNTdHJ1Y3R1cmUoYnZhbHVlLCBjb250ZXh0KSkge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgb2JqZWN0cyBtYXAgbGF6aWx5LiBOb3RlIHRoYXQgdGhpcyBhbHNvIGdyYWJzXG4gICAgICAgICAgICAgICAgLy8gU3ltYm9scyB3aGVuIG5vdCBzdHJpY3RseSBtYXRjaGluZywgc2luY2UgdGhlaXIgZGVzY3JpcHRpb25cbiAgICAgICAgICAgICAgICAvLyBpcyBjb21wYXJlZC5cbiAgICAgICAgICAgICAgICBpZiAoY291bnQgPT09IDApIG9iamVjdHMgPSBPYmplY3QuY3JlYXRlKG51bGwpXG4gICAgICAgICAgICAgICAgb2JqZWN0c1tjb3VudCsrXSA9IGJ2YWx1ZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgZXZlcnl0aGluZyBpcyBhIHByaW1pdGl2ZSwgdGhlbiBhYm9ydC5cbiAgICAgICAgaWYgKGNvdW50ID09PSAwKSByZXR1cm4gZmFsc2VcblxuICAgICAgICAvLyBJdGVyYXRlIHRoZSBvYmplY3QsIHJlbW92aW5nIGVhY2ggb25lIHJlbWFpbmluZyB3aGVuIG1hdGNoZWQgKGFuZFxuICAgICAgICAvLyBhYm9ydGluZyBpZiBub25lIGNhbiBiZSkuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICAgICAgdmFyIGF2YWx1ZSA9IGFsaXN0W2ldXG5cbiAgICAgICAgICAgIGlmIChoYXNTdHJ1Y3R1cmUoYXZhbHVlLCBjb250ZXh0KSAmJlxuICAgICAgICAgICAgICAgICAgICAhc2VhcmNoRm9yKGF2YWx1ZSwgb2JqZWN0cywgY29udGV4dCwgbGVmdCwgcmlnaHQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoUmVnRXhwKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIGEuc291cmNlID09PSBiLnNvdXJjZSAmJlxuICAgICAgICAgICAgYS5nbG9iYWwgPT09IGIuZ2xvYmFsICYmXG4gICAgICAgICAgICBhLmlnbm9yZUNhc2UgPT09IGIuaWdub3JlQ2FzZSAmJlxuICAgICAgICAgICAgYS5tdWx0aWxpbmUgPT09IGIubXVsdGlsaW5lICYmXG4gICAgICAgICAgICAoIXN1cHBvcnRzVW5pY29kZSB8fCBhLnVuaWNvZGUgPT09IGIudW5pY29kZSkgJiZcbiAgICAgICAgICAgICghc3VwcG9ydHNTdGlja3kgfHwgYS5zdGlja3kgPT09IGIuc3RpY2t5KVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoUHJlcGFyZURlc2NlbmQoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIC8vIENoZWNrIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIGFmdGVyIHRoZSBmaXJzdCBsZXZlbCwgd2hlcmUgaXQnc1xuICAgICAgICAvLyByZWR1bmRhbnQuIE5vdGUgdGhhdCB0aGV5IGhhdmUgdG8gcG9pbnQgdG8gdGhlIHNhbWUgbGV2ZWwgdG8gYWN0dWFsbHlcbiAgICAgICAgLy8gYmUgY29uc2lkZXJlZCBkZWVwbHkgZXF1YWwuXG4gICAgICAgIGlmICghKGNvbnRleHQgJiBJbml0aWFsKSkge1xuICAgICAgICAgICAgdmFyIGxlZnRJbmRleCA9IGxlZnQuaW5kZXhPZihhKVxuICAgICAgICAgICAgdmFyIHJpZ2h0SW5kZXggPSByaWdodC5pbmRleE9mKGIpXG5cbiAgICAgICAgICAgIGlmIChsZWZ0SW5kZXggIT09IHJpZ2h0SW5kZXgpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKGxlZnRJbmRleCA+PSAwKSByZXR1cm4gdHJ1ZVxuXG4gICAgICAgICAgICBsZWZ0LnB1c2goYSlcbiAgICAgICAgICAgIHJpZ2h0LnB1c2goYilcblxuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IG1hdGNoSW5uZXIoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG5cbiAgICAgICAgICAgIGxlZnQucG9wKClcbiAgICAgICAgICAgIHJpZ2h0LnBvcCgpXG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBtYXRjaElubmVyKGEsIGIsIGNvbnRleHQgJiB+SW5pdGlhbCwgW2FdLCBbYl0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXRjaFNhbWVQcm90byhhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgaWYgKHN5bWJvbHNBcmVPYmplY3RzICYmIGEgaW5zdGFuY2VvZiBTeW1ib2wpIHtcbiAgICAgICAgICAgIHJldHVybiAhKGNvbnRleHQgJiBTdHJpY3QpICYmIGEudG9TdHJpbmcoKSA9PT0gYi50b1N0cmluZygpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYSBpbnN0YW5jZW9mIFJlZ0V4cCkgcmV0dXJuIG1hdGNoUmVnRXhwKGEsIGIpXG4gICAgICAgIGlmIChhIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIGEudmFsdWVPZigpID09PSBiLnZhbHVlT2YoKVxuICAgICAgICBpZiAoYXJyYXlCdWZmZXJTdXBwb3J0ICE9PSBBcnJheUJ1ZmZlck5vbmUpIHtcbiAgICAgICAgICAgIGlmIChhIGluc3RhbmNlb2YgRGF0YVZpZXcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hWaWV3KFxuICAgICAgICAgICAgICAgICAgICBuZXcgVWludDhBcnJheShhLmJ1ZmZlciwgYS5ieXRlT2Zmc2V0LCBhLmJ5dGVMZW5ndGgpLFxuICAgICAgICAgICAgICAgICAgICBuZXcgVWludDhBcnJheShiLmJ1ZmZlciwgYi5ieXRlT2Zmc2V0LCBiLmJ5dGVMZW5ndGgpKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaFZpZXcobmV3IFVpbnQ4QXJyYXkoYSksIG5ldyBVaW50OEFycmF5KGIpKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzVmlldyhhKSkgcmV0dXJuIG1hdGNoVmlldyhhLCBiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQnVmZmVyKGEpKSByZXR1cm4gbWF0Y2hWaWV3KGEsIGIpXG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYSkpIHtcbiAgICAgICAgICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKGEubGVuZ3RoID09PSAwKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKHN1cHBvcnRzTWFwICYmIGEgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgICAgICAgIGlmIChhLnNpemUgIT09IGIuc2l6ZSkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICBpZiAoYS5zaXplID09PSAwKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKHN1cHBvcnRzU2V0ICYmIGEgaW5zdGFuY2VvZiBTZXQpIHtcbiAgICAgICAgICAgIGlmIChhLnNpemUgIT09IGIuc2l6ZSkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICBpZiAoYS5zaXplID09PSAwKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYSkgPT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3RUb1N0cmluZy5jYWxsKGIpICE9PSBcIltvYmplY3QgQXJndW1lbnRzXVwiKSByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKGEubGVuZ3RoID09PSAwKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYikgPT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1hdGNoUHJlcGFyZURlc2NlbmQoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgfVxuXG4gICAgLy8gTW9zdCBzcGVjaWFsIGNhc2VzIHJlcXVpcmUgYm90aCB0eXBlcyB0byBtYXRjaCwgYW5kIGlmIG9ubHkgb25lIG9mIHRoZW1cbiAgICAvLyBhcmUsIHRoZSBvYmplY3RzIHRoZW1zZWx2ZXMgZG9uJ3QgbWF0Y2guXG4gICAgZnVuY3Rpb24gbWF0Y2hEaWZmZXJlbnRQcm90byhhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgaWYgKHN5bWJvbHNBcmVPYmplY3RzKSB7XG4gICAgICAgICAgICBpZiAoYSBpbnN0YW5jZW9mIFN5bWJvbCB8fCBiIGluc3RhbmNlb2YgU3ltYm9sKSByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udGV4dCAmIFN0cmljdCkgcmV0dXJuIGZhbHNlXG4gICAgICAgIGlmIChhcnJheUJ1ZmZlclN1cHBvcnQgIT09IEFycmF5QnVmZmVyTm9uZSkge1xuICAgICAgICAgICAgaWYgKGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciB8fCBiIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1ZpZXcoYSkgfHwgaXNWaWV3KGIpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhKSB8fCBBcnJheS5pc0FycmF5KGIpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKHN1cHBvcnRzTWFwICYmIChhIGluc3RhbmNlb2YgTWFwIHx8IGIgaW5zdGFuY2VvZiBNYXApKSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKHN1cHBvcnRzU2V0ICYmIChhIGluc3RhbmNlb2YgU2V0IHx8IGIgaW5zdGFuY2VvZiBTZXQpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYSkgPT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3RUb1N0cmluZy5jYWxsKGIpICE9PSBcIltvYmplY3QgQXJndW1lbnRzXVwiKSByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKGEubGVuZ3RoID09PSAwKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG4gICAgICAgIGlmIChvYmplY3RUb1N0cmluZy5jYWxsKGIpID09PSBcIltvYmplY3QgQXJndW1lbnRzXVwiKSByZXR1cm4gZmFsc2VcbiAgICAgICAgcmV0dXJuIG1hdGNoUHJlcGFyZURlc2NlbmQoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF0Y2goYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIGlmIChhID09PSBiKSByZXR1cm4gdHJ1ZVxuICAgICAgICAvLyBOYU5zIGFyZSBlcXVhbFxuICAgICAgICBpZiAoYSAhPT0gYSkgcmV0dXJuIGIgIT09IGIgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICAgICAgaWYgKGEgPT09IG51bGwgfHwgYiA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlXG4gICAgICAgIGlmICh0eXBlb2YgYSA9PT0gXCJzeW1ib2xcIiAmJiB0eXBlb2YgYiA9PT0gXCJzeW1ib2xcIikge1xuICAgICAgICAgICAgcmV0dXJuICEoY29udGV4dCAmIFN0cmljdCkgJiYgYS50b1N0cmluZygpID09PSBiLnRvU3RyaW5nKClcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGEgIT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIGIgIT09IFwib2JqZWN0XCIpIHJldHVybiBmYWxzZVxuXG4gICAgICAgIC8vIFVzdWFsbHksIGJvdGggb2JqZWN0cyBoYXZlIGlkZW50aWNhbCBwcm90b3R5cGVzLCBhbmQgdGhhdCBhbGxvd3MgZm9yXG4gICAgICAgIC8vIGhhbGYgdGhlIHR5cGUgY2hlY2tpbmcuXG4gICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkgPT09IE9iamVjdC5nZXRQcm90b3R5cGVPZihiKSkge1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoU2FtZVByb3RvKGEsIGIsIGNvbnRleHQgfCBTYW1lUHJvdG8sIGxlZnQsIHJpZ2h0KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoRGlmZmVyZW50UHJvdG8oYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXRjaEFycmF5TGlrZShhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIW1hdGNoKGFbaV0sIGJbaV0sIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIC8vIFBoYW50b21KUyBhbmQgU2xpbWVySlMgYm90aCBoYXZlIG15c3RlcmlvdXMgaXNzdWVzIHdoZXJlIGBFcnJvcmAgaXNcbiAgICAvLyBzb21ldGltZXMgZXJyb25lb3VzbHkgb2YgYSBkaWZmZXJlbnQgYHdpbmRvd2AsIGFuZCBpdCBzaG93cyB1cCBpbiB0aGVcbiAgICAvLyB0ZXN0cy4gVGhpcyBtZWFucyBJIGhhdmUgdG8gdXNlIGEgbXVjaCBzbG93ZXIgYWxnb3JpdGhtIHRvIGRldGVjdCBFcnJvcnMuXG4gICAgLy9cbiAgICAvLyBQaGFudG9tSlM6IGh0dHBzOi8vZ2l0aHViLmNvbS9wZXRrYWFudG9ub3YvYmx1ZWJpcmQvaXNzdWVzLzExNDZcbiAgICAvLyBTbGltZXJKUzogaHR0cHM6Ly9naXRodWIuY29tL2xhdXJlbnRqL3NsaW1lcmpzL2lzc3Vlcy80MDBcbiAgICAvL1xuICAgIC8vIChZZXMsIHRoZSBQaGFudG9tSlMgYnVnIGlzIGRldGFpbGVkIGluIHRoZSBCbHVlYmlyZCBpc3N1ZSB0cmFja2VyLilcbiAgICB2YXIgY2hlY2tDcm9zc09yaWdpbiA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChnbG9iYWwud2luZG93ID09IG51bGwgfHwgZ2xvYmFsLndpbmRvdy5uYXZpZ2F0b3IgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIC9zbGltZXJqc3xwaGFudG9tanMvaS50ZXN0KGdsb2JhbC53aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudClcbiAgICB9KSgpXG5cbiAgICB2YXIgZXJyb3JTdHJpbmdUeXBlcyA9IHtcbiAgICAgICAgXCJbb2JqZWN0IEVycm9yXVwiOiB0cnVlLFxuICAgICAgICBcIltvYmplY3QgRXZhbEVycm9yXVwiOiB0cnVlLFxuICAgICAgICBcIltvYmplY3QgUmFuZ2VFcnJvcl1cIjogdHJ1ZSxcbiAgICAgICAgXCJbb2JqZWN0IFJlZmVyZW5jZUVycm9yXVwiOiB0cnVlLFxuICAgICAgICBcIltvYmplY3QgU3ludGF4RXJyb3JdXCI6IHRydWUsXG4gICAgICAgIFwiW29iamVjdCBUeXBlRXJyb3JdXCI6IHRydWUsXG4gICAgICAgIFwiW29iamVjdCBVUklFcnJvcl1cIjogdHJ1ZSxcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1Byb3hpZWRFcnJvcihvYmplY3QpIHtcbiAgICAgICAgd2hpbGUgKG9iamVjdCAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3JTdHJpbmdUeXBlc1tvYmplY3RUb1N0cmluZy5jYWxsKG9iamVjdCldKSByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgb2JqZWN0ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdClcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoSW5uZXIoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtc3RhdGVtZW50cywgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICB2YXIgYWtleXMsIGJrZXlzXG4gICAgICAgIHZhciBpc1VucHJveGllZEVycm9yID0gZmFsc2VcblxuICAgICAgICBpZiAoY29udGV4dCAmIFNhbWVQcm90bykge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hBcnJheUxpa2UoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdXBwb3J0c01hcCAmJiBhIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoTWFwKGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc3VwcG9ydHNTZXQgJiYgYSBpbnN0YW5jZW9mIFNldCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaFNldChhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYSkgPT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hBcnJheUxpa2UoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChyZXF1aXJlc1Byb3h5ICYmXG4gICAgICAgICAgICAgICAgICAgIChjaGVja0Nyb3NzT3JpZ2luID8gaXNQcm94aWVkRXJyb3IoYSlcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYSBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgICAgICAgICAgICAgIGFrZXlzID0gZ2V0S2V5c1N0cmlwcGVkKGEpXG4gICAgICAgICAgICAgICAgYmtleXMgPSBnZXRLZXlzU3RyaXBwZWQoYilcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYWtleXMgPSBPYmplY3Qua2V5cyhhKVxuICAgICAgICAgICAgICAgIGJrZXlzID0gT2JqZWN0LmtleXMoYilcbiAgICAgICAgICAgICAgICBpc1VucHJveGllZEVycm9yID0gYSBpbnN0YW5jZW9mIEVycm9yXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAob2JqZWN0VG9TdHJpbmcuY2FsbChhKSA9PT0gXCJbb2JqZWN0IEFyZ3VtZW50c11cIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaEFycmF5TGlrZShhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgd2UgcmVxdWlyZSBhIHByb3h5LCBiZSBwZXJtaXNzaXZlIGFuZCBjaGVjayB0aGUgYHRvU3RyaW5nYFxuICAgICAgICAgICAgLy8gdHlwZS4gVGhpcyBpcyBzbyBpdCB3b3JrcyBjcm9zcy1vcmlnaW4gaW4gUGhhbnRvbUpTIGluXG4gICAgICAgICAgICAvLyBwYXJ0aWN1bGFyLlxuICAgICAgICAgICAgaWYgKGNoZWNrQ3Jvc3NPcmlnaW4gPyBpc1Byb3hpZWRFcnJvcihhKSA6IGEgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWtleXMgPSBPYmplY3Qua2V5cyhhKVxuICAgICAgICAgICAgYmtleXMgPSBPYmplY3Qua2V5cyhiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNvdW50ID0gYWtleXMubGVuZ3RoXG5cbiAgICAgICAgaWYgKGNvdW50ICE9PSBia2V5cy5sZW5ndGgpIHJldHVybiBmYWxzZVxuXG4gICAgICAgIC8vIFNob3J0Y3V0IGlmIHRoZXJlJ3Mgbm90aGluZyB0byBtYXRjaFxuICAgICAgICBpZiAoY291bnQgPT09IDApIHJldHVybiB0cnVlXG5cbiAgICAgICAgdmFyIGlcblxuICAgICAgICBpZiAoaXNVbnByb3hpZWRFcnJvcikge1xuICAgICAgICAgICAgLy8gU2hvcnRjdXQgaWYgdGhlIHByb3BlcnRpZXMgYXJlIGRpZmZlcmVudC5cbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFrZXlzW2ldICE9PSBcInN0YWNrXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNPd24uY2FsbChiLCBha2V5c1tpXSkpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVmVyaWZ5IHRoYXQgYWxsIHRoZSBha2V5cycgdmFsdWVzIG1hdGNoZWQuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChha2V5c1tpXSAhPT0gXCJzdGFja1wiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAhbWF0Y2goYVtha2V5c1tpXV0sIGJbYWtleXNbaV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTaG9ydGN1dCBpZiB0aGUgcHJvcGVydGllcyBhcmUgZGlmZmVyZW50LlxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoIWhhc093bi5jYWxsKGIsIGFrZXlzW2ldKSkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFZlcmlmeSB0aGF0IGFsbCB0aGUgYWtleXMnIHZhbHVlcyBtYXRjaGVkLlxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoIW1hdGNoKGFbYWtleXNbaV1dLCBiW2FrZXlzW2ldXSwgY29udGV4dCwgbGVmdCwgcmlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxufSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgc2VtaVxuIiwiLy8gU2VlOiBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvZ29vZ2xlLWRpZmYtbWF0Y2gtcGF0Y2gvd2lraS9BUElcbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0Q2hhbmdlc1RvRE1QKGNoYW5nZXMpIHtcbiAgbGV0IHJldCA9IFtdLFxuICAgICAgY2hhbmdlLFxuICAgICAgb3BlcmF0aW9uO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGNoYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjaGFuZ2UgPSBjaGFuZ2VzW2ldO1xuICAgIGlmIChjaGFuZ2UuYWRkZWQpIHtcbiAgICAgIG9wZXJhdGlvbiA9IDE7XG4gICAgfSBlbHNlIGlmIChjaGFuZ2UucmVtb3ZlZCkge1xuICAgICAgb3BlcmF0aW9uID0gLTE7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wZXJhdGlvbiA9IDA7XG4gICAgfVxuXG4gICAgcmV0LnB1c2goW29wZXJhdGlvbiwgY2hhbmdlLnZhbHVlXSk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cbiIsImV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0Q2hhbmdlc1RvWE1MKGNoYW5nZXMpIHtcbiAgbGV0IHJldCA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGNoYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgY2hhbmdlID0gY2hhbmdlc1tpXTtcbiAgICBpZiAoY2hhbmdlLmFkZGVkKSB7XG4gICAgICByZXQucHVzaCgnPGlucz4nKTtcbiAgICB9IGVsc2UgaWYgKGNoYW5nZS5yZW1vdmVkKSB7XG4gICAgICByZXQucHVzaCgnPGRlbD4nKTtcbiAgICB9XG5cbiAgICByZXQucHVzaChlc2NhcGVIVE1MKGNoYW5nZS52YWx1ZSkpO1xuXG4gICAgaWYgKGNoYW5nZS5hZGRlZCkge1xuICAgICAgcmV0LnB1c2goJzwvaW5zPicpO1xuICAgIH0gZWxzZSBpZiAoY2hhbmdlLnJlbW92ZWQpIHtcbiAgICAgIHJldC5wdXNoKCc8L2RlbD4nKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJldC5qb2luKCcnKTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlSFRNTChzKSB7XG4gIGxldCBuID0gcztcbiAgbiA9IG4ucmVwbGFjZSgvJi9nLCAnJmFtcDsnKTtcbiAgbiA9IG4ucmVwbGFjZSgvPC9nLCAnJmx0OycpO1xuICBuID0gbi5yZXBsYWNlKC8+L2csICcmZ3Q7Jyk7XG4gIG4gPSBuLnJlcGxhY2UoL1wiL2csICcmcXVvdDsnKTtcblxuICByZXR1cm4gbjtcbn1cbiIsImltcG9ydCBEaWZmIGZyb20gJy4vYmFzZSc7XG5cbmV4cG9ydCBjb25zdCBhcnJheURpZmYgPSBuZXcgRGlmZigpO1xuYXJyYXlEaWZmLnRva2VuaXplID0gYXJyYXlEaWZmLmpvaW4gPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUuc2xpY2UoKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBkaWZmQXJyYXlzKG9sZEFyciwgbmV3QXJyLCBjYWxsYmFjaykgeyByZXR1cm4gYXJyYXlEaWZmLmRpZmYob2xkQXJyLCBuZXdBcnIsIGNhbGxiYWNrKTsgfVxuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRGlmZigpIHt9XG5cbkRpZmYucHJvdG90eXBlID0ge1xuICBkaWZmKG9sZFN0cmluZywgbmV3U3RyaW5nLCBvcHRpb25zID0ge30pIHtcbiAgICBsZXQgY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY2FsbGJhY2sgPSBvcHRpb25zO1xuICAgICAgb3B0aW9ucyA9IHt9O1xuICAgIH1cbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgbGV0IHNlbGYgPSB0aGlzO1xuXG4gICAgZnVuY3Rpb24gZG9uZSh2YWx1ZSkge1xuICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNhbGxiYWNrKHVuZGVmaW5lZCwgdmFsdWUpOyB9LCAwKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWxsb3cgc3ViY2xhc3NlcyB0byBtYXNzYWdlIHRoZSBpbnB1dCBwcmlvciB0byBydW5uaW5nXG4gICAgb2xkU3RyaW5nID0gdGhpcy5jYXN0SW5wdXQob2xkU3RyaW5nKTtcbiAgICBuZXdTdHJpbmcgPSB0aGlzLmNhc3RJbnB1dChuZXdTdHJpbmcpO1xuXG4gICAgb2xkU3RyaW5nID0gdGhpcy5yZW1vdmVFbXB0eSh0aGlzLnRva2VuaXplKG9sZFN0cmluZykpO1xuICAgIG5ld1N0cmluZyA9IHRoaXMucmVtb3ZlRW1wdHkodGhpcy50b2tlbml6ZShuZXdTdHJpbmcpKTtcblxuICAgIGxldCBuZXdMZW4gPSBuZXdTdHJpbmcubGVuZ3RoLCBvbGRMZW4gPSBvbGRTdHJpbmcubGVuZ3RoO1xuICAgIGxldCBlZGl0TGVuZ3RoID0gMTtcbiAgICBsZXQgbWF4RWRpdExlbmd0aCA9IG5ld0xlbiArIG9sZExlbjtcbiAgICBsZXQgYmVzdFBhdGggPSBbeyBuZXdQb3M6IC0xLCBjb21wb25lbnRzOiBbXSB9XTtcblxuICAgIC8vIFNlZWQgZWRpdExlbmd0aCA9IDAsIGkuZS4gdGhlIGNvbnRlbnQgc3RhcnRzIHdpdGggdGhlIHNhbWUgdmFsdWVzXG4gICAgbGV0IG9sZFBvcyA9IHRoaXMuZXh0cmFjdENvbW1vbihiZXN0UGF0aFswXSwgbmV3U3RyaW5nLCBvbGRTdHJpbmcsIDApO1xuICAgIGlmIChiZXN0UGF0aFswXS5uZXdQb3MgKyAxID49IG5ld0xlbiAmJiBvbGRQb3MgKyAxID49IG9sZExlbikge1xuICAgICAgLy8gSWRlbnRpdHkgcGVyIHRoZSBlcXVhbGl0eSBhbmQgdG9rZW5pemVyXG4gICAgICByZXR1cm4gZG9uZShbe3ZhbHVlOiB0aGlzLmpvaW4obmV3U3RyaW5nKSwgY291bnQ6IG5ld1N0cmluZy5sZW5ndGh9XSk7XG4gICAgfVxuXG4gICAgLy8gTWFpbiB3b3JrZXIgbWV0aG9kLiBjaGVja3MgYWxsIHBlcm11dGF0aW9ucyBvZiBhIGdpdmVuIGVkaXQgbGVuZ3RoIGZvciBhY2NlcHRhbmNlLlxuICAgIGZ1bmN0aW9uIGV4ZWNFZGl0TGVuZ3RoKCkge1xuICAgICAgZm9yIChsZXQgZGlhZ29uYWxQYXRoID0gLTEgKiBlZGl0TGVuZ3RoOyBkaWFnb25hbFBhdGggPD0gZWRpdExlbmd0aDsgZGlhZ29uYWxQYXRoICs9IDIpIHtcbiAgICAgICAgbGV0IGJhc2VQYXRoO1xuICAgICAgICBsZXQgYWRkUGF0aCA9IGJlc3RQYXRoW2RpYWdvbmFsUGF0aCAtIDFdLFxuICAgICAgICAgICAgcmVtb3ZlUGF0aCA9IGJlc3RQYXRoW2RpYWdvbmFsUGF0aCArIDFdLFxuICAgICAgICAgICAgb2xkUG9zID0gKHJlbW92ZVBhdGggPyByZW1vdmVQYXRoLm5ld1BvcyA6IDApIC0gZGlhZ29uYWxQYXRoO1xuICAgICAgICBpZiAoYWRkUGF0aCkge1xuICAgICAgICAgIC8vIE5vIG9uZSBlbHNlIGlzIGdvaW5nIHRvIGF0dGVtcHQgdG8gdXNlIHRoaXMgdmFsdWUsIGNsZWFyIGl0XG4gICAgICAgICAgYmVzdFBhdGhbZGlhZ29uYWxQYXRoIC0gMV0gPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgY2FuQWRkID0gYWRkUGF0aCAmJiBhZGRQYXRoLm5ld1BvcyArIDEgPCBuZXdMZW4sXG4gICAgICAgICAgICBjYW5SZW1vdmUgPSByZW1vdmVQYXRoICYmIDAgPD0gb2xkUG9zICYmIG9sZFBvcyA8IG9sZExlbjtcbiAgICAgICAgaWYgKCFjYW5BZGQgJiYgIWNhblJlbW92ZSkge1xuICAgICAgICAgIC8vIElmIHRoaXMgcGF0aCBpcyBhIHRlcm1pbmFsIHRoZW4gcHJ1bmVcbiAgICAgICAgICBiZXN0UGF0aFtkaWFnb25hbFBhdGhdID0gdW5kZWZpbmVkO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2VsZWN0IHRoZSBkaWFnb25hbCB0aGF0IHdlIHdhbnQgdG8gYnJhbmNoIGZyb20uIFdlIHNlbGVjdCB0aGUgcHJpb3JcbiAgICAgICAgLy8gcGF0aCB3aG9zZSBwb3NpdGlvbiBpbiB0aGUgbmV3IHN0cmluZyBpcyB0aGUgZmFydGhlc3QgZnJvbSB0aGUgb3JpZ2luXG4gICAgICAgIC8vIGFuZCBkb2VzIG5vdCBwYXNzIHRoZSBib3VuZHMgb2YgdGhlIGRpZmYgZ3JhcGhcbiAgICAgICAgaWYgKCFjYW5BZGQgfHwgKGNhblJlbW92ZSAmJiBhZGRQYXRoLm5ld1BvcyA8IHJlbW92ZVBhdGgubmV3UG9zKSkge1xuICAgICAgICAgIGJhc2VQYXRoID0gY2xvbmVQYXRoKHJlbW92ZVBhdGgpO1xuICAgICAgICAgIHNlbGYucHVzaENvbXBvbmVudChiYXNlUGF0aC5jb21wb25lbnRzLCB1bmRlZmluZWQsIHRydWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJhc2VQYXRoID0gYWRkUGF0aDsgICAvLyBObyBuZWVkIHRvIGNsb25lLCB3ZSd2ZSBwdWxsZWQgaXQgZnJvbSB0aGUgbGlzdFxuICAgICAgICAgIGJhc2VQYXRoLm5ld1BvcysrO1xuICAgICAgICAgIHNlbGYucHVzaENvbXBvbmVudChiYXNlUGF0aC5jb21wb25lbnRzLCB0cnVlLCB1bmRlZmluZWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgb2xkUG9zID0gc2VsZi5leHRyYWN0Q29tbW9uKGJhc2VQYXRoLCBuZXdTdHJpbmcsIG9sZFN0cmluZywgZGlhZ29uYWxQYXRoKTtcblxuICAgICAgICAvLyBJZiB3ZSBoYXZlIGhpdCB0aGUgZW5kIG9mIGJvdGggc3RyaW5ncywgdGhlbiB3ZSBhcmUgZG9uZVxuICAgICAgICBpZiAoYmFzZVBhdGgubmV3UG9zICsgMSA+PSBuZXdMZW4gJiYgb2xkUG9zICsgMSA+PSBvbGRMZW4pIHtcbiAgICAgICAgICByZXR1cm4gZG9uZShidWlsZFZhbHVlcyhzZWxmLCBiYXNlUGF0aC5jb21wb25lbnRzLCBuZXdTdHJpbmcsIG9sZFN0cmluZywgc2VsZi51c2VMb25nZXN0VG9rZW4pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBPdGhlcndpc2UgdHJhY2sgdGhpcyBwYXRoIGFzIGEgcG90ZW50aWFsIGNhbmRpZGF0ZSBhbmQgY29udGludWUuXG4gICAgICAgICAgYmVzdFBhdGhbZGlhZ29uYWxQYXRoXSA9IGJhc2VQYXRoO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGVkaXRMZW5ndGgrKztcbiAgICB9XG5cbiAgICAvLyBQZXJmb3JtcyB0aGUgbGVuZ3RoIG9mIGVkaXQgaXRlcmF0aW9uLiBJcyBhIGJpdCBmdWdseSBhcyB0aGlzIGhhcyB0byBzdXBwb3J0IHRoZVxuICAgIC8vIHN5bmMgYW5kIGFzeW5jIG1vZGUgd2hpY2ggaXMgbmV2ZXIgZnVuLiBMb29wcyBvdmVyIGV4ZWNFZGl0TGVuZ3RoIHVudGlsIGEgdmFsdWVcbiAgICAvLyBpcyBwcm9kdWNlZC5cbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgIChmdW5jdGlvbiBleGVjKCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIG5vdCBoYXBwZW4sIGJ1dCB3ZSB3YW50IHRvIGJlIHNhZmUuXG4gICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgICBpZiAoZWRpdExlbmd0aCA+IG1heEVkaXRMZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghZXhlY0VkaXRMZW5ndGgoKSkge1xuICAgICAgICAgICAgZXhlYygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgMCk7XG4gICAgICB9KCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aGlsZSAoZWRpdExlbmd0aCA8PSBtYXhFZGl0TGVuZ3RoKSB7XG4gICAgICAgIGxldCByZXQgPSBleGVjRWRpdExlbmd0aCgpO1xuICAgICAgICBpZiAocmV0KSB7XG4gICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBwdXNoQ29tcG9uZW50KGNvbXBvbmVudHMsIGFkZGVkLCByZW1vdmVkKSB7XG4gICAgbGV0IGxhc3QgPSBjb21wb25lbnRzW2NvbXBvbmVudHMubGVuZ3RoIC0gMV07XG4gICAgaWYgKGxhc3QgJiYgbGFzdC5hZGRlZCA9PT0gYWRkZWQgJiYgbGFzdC5yZW1vdmVkID09PSByZW1vdmVkKSB7XG4gICAgICAvLyBXZSBuZWVkIHRvIGNsb25lIGhlcmUgYXMgdGhlIGNvbXBvbmVudCBjbG9uZSBvcGVyYXRpb24gaXMganVzdFxuICAgICAgLy8gYXMgc2hhbGxvdyBhcnJheSBjbG9uZVxuICAgICAgY29tcG9uZW50c1tjb21wb25lbnRzLmxlbmd0aCAtIDFdID0ge2NvdW50OiBsYXN0LmNvdW50ICsgMSwgYWRkZWQ6IGFkZGVkLCByZW1vdmVkOiByZW1vdmVkIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbXBvbmVudHMucHVzaCh7Y291bnQ6IDEsIGFkZGVkOiBhZGRlZCwgcmVtb3ZlZDogcmVtb3ZlZCB9KTtcbiAgICB9XG4gIH0sXG4gIGV4dHJhY3RDb21tb24oYmFzZVBhdGgsIG5ld1N0cmluZywgb2xkU3RyaW5nLCBkaWFnb25hbFBhdGgpIHtcbiAgICBsZXQgbmV3TGVuID0gbmV3U3RyaW5nLmxlbmd0aCxcbiAgICAgICAgb2xkTGVuID0gb2xkU3RyaW5nLmxlbmd0aCxcbiAgICAgICAgbmV3UG9zID0gYmFzZVBhdGgubmV3UG9zLFxuICAgICAgICBvbGRQb3MgPSBuZXdQb3MgLSBkaWFnb25hbFBhdGgsXG5cbiAgICAgICAgY29tbW9uQ291bnQgPSAwO1xuICAgIHdoaWxlIChuZXdQb3MgKyAxIDwgbmV3TGVuICYmIG9sZFBvcyArIDEgPCBvbGRMZW4gJiYgdGhpcy5lcXVhbHMobmV3U3RyaW5nW25ld1BvcyArIDFdLCBvbGRTdHJpbmdbb2xkUG9zICsgMV0pKSB7XG4gICAgICBuZXdQb3MrKztcbiAgICAgIG9sZFBvcysrO1xuICAgICAgY29tbW9uQ291bnQrKztcbiAgICB9XG5cbiAgICBpZiAoY29tbW9uQ291bnQpIHtcbiAgICAgIGJhc2VQYXRoLmNvbXBvbmVudHMucHVzaCh7Y291bnQ6IGNvbW1vbkNvdW50fSk7XG4gICAgfVxuXG4gICAgYmFzZVBhdGgubmV3UG9zID0gbmV3UG9zO1xuICAgIHJldHVybiBvbGRQb3M7XG4gIH0sXG5cbiAgZXF1YWxzKGxlZnQsIHJpZ2h0KSB7XG4gICAgcmV0dXJuIGxlZnQgPT09IHJpZ2h0O1xuICB9LFxuICByZW1vdmVFbXB0eShhcnJheSkge1xuICAgIGxldCByZXQgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYXJyYXlbaV0pIHtcbiAgICAgICAgcmV0LnB1c2goYXJyYXlbaV0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9LFxuICBjYXN0SW5wdXQodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG4gIHRva2VuaXplKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlLnNwbGl0KCcnKTtcbiAgfSxcbiAgam9pbihjaGFycykge1xuICAgIHJldHVybiBjaGFycy5qb2luKCcnKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gYnVpbGRWYWx1ZXMoZGlmZiwgY29tcG9uZW50cywgbmV3U3RyaW5nLCBvbGRTdHJpbmcsIHVzZUxvbmdlc3RUb2tlbikge1xuICBsZXQgY29tcG9uZW50UG9zID0gMCxcbiAgICAgIGNvbXBvbmVudExlbiA9IGNvbXBvbmVudHMubGVuZ3RoLFxuICAgICAgbmV3UG9zID0gMCxcbiAgICAgIG9sZFBvcyA9IDA7XG5cbiAgZm9yICg7IGNvbXBvbmVudFBvcyA8IGNvbXBvbmVudExlbjsgY29tcG9uZW50UG9zKyspIHtcbiAgICBsZXQgY29tcG9uZW50ID0gY29tcG9uZW50c1tjb21wb25lbnRQb3NdO1xuICAgIGlmICghY29tcG9uZW50LnJlbW92ZWQpIHtcbiAgICAgIGlmICghY29tcG9uZW50LmFkZGVkICYmIHVzZUxvbmdlc3RUb2tlbikge1xuICAgICAgICBsZXQgdmFsdWUgPSBuZXdTdHJpbmcuc2xpY2UobmV3UG9zLCBuZXdQb3MgKyBjb21wb25lbnQuY291bnQpO1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLm1hcChmdW5jdGlvbih2YWx1ZSwgaSkge1xuICAgICAgICAgIGxldCBvbGRWYWx1ZSA9IG9sZFN0cmluZ1tvbGRQb3MgKyBpXTtcbiAgICAgICAgICByZXR1cm4gb2xkVmFsdWUubGVuZ3RoID4gdmFsdWUubGVuZ3RoID8gb2xkVmFsdWUgOiB2YWx1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29tcG9uZW50LnZhbHVlID0gZGlmZi5qb2luKHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbXBvbmVudC52YWx1ZSA9IGRpZmYuam9pbihuZXdTdHJpbmcuc2xpY2UobmV3UG9zLCBuZXdQb3MgKyBjb21wb25lbnQuY291bnQpKTtcbiAgICAgIH1cbiAgICAgIG5ld1BvcyArPSBjb21wb25lbnQuY291bnQ7XG5cbiAgICAgIC8vIENvbW1vbiBjYXNlXG4gICAgICBpZiAoIWNvbXBvbmVudC5hZGRlZCkge1xuICAgICAgICBvbGRQb3MgKz0gY29tcG9uZW50LmNvdW50O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb21wb25lbnQudmFsdWUgPSBkaWZmLmpvaW4ob2xkU3RyaW5nLnNsaWNlKG9sZFBvcywgb2xkUG9zICsgY29tcG9uZW50LmNvdW50KSk7XG4gICAgICBvbGRQb3MgKz0gY29tcG9uZW50LmNvdW50O1xuXG4gICAgICAvLyBSZXZlcnNlIGFkZCBhbmQgcmVtb3ZlIHNvIHJlbW92ZXMgYXJlIG91dHB1dCBmaXJzdCB0byBtYXRjaCBjb21tb24gY29udmVudGlvblxuICAgICAgLy8gVGhlIGRpZmZpbmcgYWxnb3JpdGhtIGlzIHRpZWQgdG8gYWRkIHRoZW4gcmVtb3ZlIG91dHB1dCBhbmQgdGhpcyBpcyB0aGUgc2ltcGxlc3RcbiAgICAgIC8vIHJvdXRlIHRvIGdldCB0aGUgZGVzaXJlZCBvdXRwdXQgd2l0aCBtaW5pbWFsIG92ZXJoZWFkLlxuICAgICAgaWYgKGNvbXBvbmVudFBvcyAmJiBjb21wb25lbnRzW2NvbXBvbmVudFBvcyAtIDFdLmFkZGVkKSB7XG4gICAgICAgIGxldCB0bXAgPSBjb21wb25lbnRzW2NvbXBvbmVudFBvcyAtIDFdO1xuICAgICAgICBjb21wb25lbnRzW2NvbXBvbmVudFBvcyAtIDFdID0gY29tcG9uZW50c1tjb21wb25lbnRQb3NdO1xuICAgICAgICBjb21wb25lbnRzW2NvbXBvbmVudFBvc10gPSB0bXA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gU3BlY2lhbCBjYXNlIGhhbmRsZSBmb3Igd2hlbiBvbmUgdGVybWluYWwgaXMgaWdub3JlZC4gRm9yIHRoaXMgY2FzZSB3ZSBtZXJnZSB0aGVcbiAgLy8gdGVybWluYWwgaW50byB0aGUgcHJpb3Igc3RyaW5nIGFuZCBkcm9wIHRoZSBjaGFuZ2UuXG4gIGxldCBsYXN0Q29tcG9uZW50ID0gY29tcG9uZW50c1tjb21wb25lbnRMZW4gLSAxXTtcbiAgaWYgKGNvbXBvbmVudExlbiA+IDFcbiAgICAgICYmIChsYXN0Q29tcG9uZW50LmFkZGVkIHx8IGxhc3RDb21wb25lbnQucmVtb3ZlZClcbiAgICAgICYmIGRpZmYuZXF1YWxzKCcnLCBsYXN0Q29tcG9uZW50LnZhbHVlKSkge1xuICAgIGNvbXBvbmVudHNbY29tcG9uZW50TGVuIC0gMl0udmFsdWUgKz0gbGFzdENvbXBvbmVudC52YWx1ZTtcbiAgICBjb21wb25lbnRzLnBvcCgpO1xuICB9XG5cbiAgcmV0dXJuIGNvbXBvbmVudHM7XG59XG5cbmZ1bmN0aW9uIGNsb25lUGF0aChwYXRoKSB7XG4gIHJldHVybiB7IG5ld1BvczogcGF0aC5uZXdQb3MsIGNvbXBvbmVudHM6IHBhdGguY29tcG9uZW50cy5zbGljZSgwKSB9O1xufVxuIiwiaW1wb3J0IERpZmYgZnJvbSAnLi9iYXNlJztcblxuZXhwb3J0IGNvbnN0IGNoYXJhY3RlckRpZmYgPSBuZXcgRGlmZigpO1xuZXhwb3J0IGZ1bmN0aW9uIGRpZmZDaGFycyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHsgcmV0dXJuIGNoYXJhY3RlckRpZmYuZGlmZihvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spOyB9XG4iLCJpbXBvcnQgRGlmZiBmcm9tICcuL2Jhc2UnO1xuXG5leHBvcnQgY29uc3QgY3NzRGlmZiA9IG5ldyBEaWZmKCk7XG5jc3NEaWZmLnRva2VuaXplID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlLnNwbGl0KC8oW3t9OjssXXxcXHMrKS8pO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZDc3Mob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKSB7IHJldHVybiBjc3NEaWZmLmRpZmYob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKTsgfVxuIiwiaW1wb3J0IERpZmYgZnJvbSAnLi9iYXNlJztcbmltcG9ydCB7bGluZURpZmZ9IGZyb20gJy4vbGluZSc7XG5cbmNvbnN0IG9iamVjdFByb3RvdHlwZVRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuXG5leHBvcnQgY29uc3QganNvbkRpZmYgPSBuZXcgRGlmZigpO1xuLy8gRGlzY3JpbWluYXRlIGJldHdlZW4gdHdvIGxpbmVzIG9mIHByZXR0eS1wcmludGVkLCBzZXJpYWxpemVkIEpTT04gd2hlcmUgb25lIG9mIHRoZW0gaGFzIGFcbi8vIGRhbmdsaW5nIGNvbW1hIGFuZCB0aGUgb3RoZXIgZG9lc24ndC4gVHVybnMgb3V0IGluY2x1ZGluZyB0aGUgZGFuZ2xpbmcgY29tbWEgeWllbGRzIHRoZSBuaWNlc3Qgb3V0cHV0OlxuanNvbkRpZmYudXNlTG9uZ2VzdFRva2VuID0gdHJ1ZTtcblxuanNvbkRpZmYudG9rZW5pemUgPSBsaW5lRGlmZi50b2tlbml6ZTtcbmpzb25EaWZmLmNhc3RJbnB1dCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIGNvbnN0IHt1bmRlZmluZWRSZXBsYWNlbWVudH0gPSB0aGlzLm9wdGlvbnM7XG5cbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgPyB2YWx1ZSA6IEpTT04uc3RyaW5naWZ5KGNhbm9uaWNhbGl6ZSh2YWx1ZSksIGZ1bmN0aW9uKGssIHYpIHtcbiAgICBpZiAodHlwZW9mIHYgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkUmVwbGFjZW1lbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHY7XG4gIH0sICcgICcpO1xufTtcbmpzb25EaWZmLmVxdWFscyA9IGZ1bmN0aW9uKGxlZnQsIHJpZ2h0KSB7XG4gIHJldHVybiBEaWZmLnByb3RvdHlwZS5lcXVhbHMobGVmdC5yZXBsYWNlKC8sKFtcXHJcXG5dKS9nLCAnJDEnKSwgcmlnaHQucmVwbGFjZSgvLChbXFxyXFxuXSkvZywgJyQxJykpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZKc29uKG9sZE9iaiwgbmV3T2JqLCBvcHRpb25zKSB7IHJldHVybiBqc29uRGlmZi5kaWZmKG9sZE9iaiwgbmV3T2JqLCBvcHRpb25zKTsgfVxuXG4vLyBUaGlzIGZ1bmN0aW9uIGhhbmRsZXMgdGhlIHByZXNlbmNlIG9mIGNpcmN1bGFyIHJlZmVyZW5jZXMgYnkgYmFpbGluZyBvdXQgd2hlbiBlbmNvdW50ZXJpbmcgYW5cbi8vIG9iamVjdCB0aGF0IGlzIGFscmVhZHkgb24gdGhlIFwic3RhY2tcIiBvZiBpdGVtcyBiZWluZyBwcm9jZXNzZWQuXG5leHBvcnQgZnVuY3Rpb24gY2Fub25pY2FsaXplKG9iaiwgc3RhY2ssIHJlcGxhY2VtZW50U3RhY2spIHtcbiAgc3RhY2sgPSBzdGFjayB8fCBbXTtcbiAgcmVwbGFjZW1lbnRTdGFjayA9IHJlcGxhY2VtZW50U3RhY2sgfHwgW107XG5cbiAgbGV0IGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IHN0YWNrLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgaWYgKHN0YWNrW2ldID09PSBvYmopIHtcbiAgICAgIHJldHVybiByZXBsYWNlbWVudFN0YWNrW2ldO1xuICAgIH1cbiAgfVxuXG4gIGxldCBjYW5vbmljYWxpemVkT2JqO1xuXG4gIGlmICgnW29iamVjdCBBcnJheV0nID09PSBvYmplY3RQcm90b3R5cGVUb1N0cmluZy5jYWxsKG9iaikpIHtcbiAgICBzdGFjay5wdXNoKG9iaik7XG4gICAgY2Fub25pY2FsaXplZE9iaiA9IG5ldyBBcnJheShvYmoubGVuZ3RoKTtcbiAgICByZXBsYWNlbWVudFN0YWNrLnB1c2goY2Fub25pY2FsaXplZE9iaik7XG4gICAgZm9yIChpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY2Fub25pY2FsaXplZE9ialtpXSA9IGNhbm9uaWNhbGl6ZShvYmpbaV0sIHN0YWNrLCByZXBsYWNlbWVudFN0YWNrKTtcbiAgICB9XG4gICAgc3RhY2sucG9wKCk7XG4gICAgcmVwbGFjZW1lbnRTdGFjay5wb3AoKTtcbiAgICByZXR1cm4gY2Fub25pY2FsaXplZE9iajtcbiAgfVxuXG4gIGlmIChvYmogJiYgb2JqLnRvSlNPTikge1xuICAgIG9iaiA9IG9iai50b0pTT04oKTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogIT09IG51bGwpIHtcbiAgICBzdGFjay5wdXNoKG9iaik7XG4gICAgY2Fub25pY2FsaXplZE9iaiA9IHt9O1xuICAgIHJlcGxhY2VtZW50U3RhY2sucHVzaChjYW5vbmljYWxpemVkT2JqKTtcbiAgICBsZXQgc29ydGVkS2V5cyA9IFtdLFxuICAgICAgICBrZXk7XG4gICAgZm9yIChrZXkgaW4gb2JqKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgIHNvcnRlZEtleXMucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgICBzb3J0ZWRLZXlzLnNvcnQoKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgc29ydGVkS2V5cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAga2V5ID0gc29ydGVkS2V5c1tpXTtcbiAgICAgIGNhbm9uaWNhbGl6ZWRPYmpba2V5XSA9IGNhbm9uaWNhbGl6ZShvYmpba2V5XSwgc3RhY2ssIHJlcGxhY2VtZW50U3RhY2spO1xuICAgIH1cbiAgICBzdGFjay5wb3AoKTtcbiAgICByZXBsYWNlbWVudFN0YWNrLnBvcCgpO1xuICB9IGVsc2Uge1xuICAgIGNhbm9uaWNhbGl6ZWRPYmogPSBvYmo7XG4gIH1cbiAgcmV0dXJuIGNhbm9uaWNhbGl6ZWRPYmo7XG59XG4iLCJpbXBvcnQgRGlmZiBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0IHtnZW5lcmF0ZU9wdGlvbnN9IGZyb20gJy4uL3V0aWwvcGFyYW1zJztcblxuZXhwb3J0IGNvbnN0IGxpbmVEaWZmID0gbmV3IERpZmYoKTtcbmxpbmVEaWZmLnRva2VuaXplID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgbGV0IHJldExpbmVzID0gW10sXG4gICAgICBsaW5lc0FuZE5ld2xpbmVzID0gdmFsdWUuc3BsaXQoLyhcXG58XFxyXFxuKS8pO1xuXG4gIC8vIElnbm9yZSB0aGUgZmluYWwgZW1wdHkgdG9rZW4gdGhhdCBvY2N1cnMgaWYgdGhlIHN0cmluZyBlbmRzIHdpdGggYSBuZXcgbGluZVxuICBpZiAoIWxpbmVzQW5kTmV3bGluZXNbbGluZXNBbmROZXdsaW5lcy5sZW5ndGggLSAxXSkge1xuICAgIGxpbmVzQW5kTmV3bGluZXMucG9wKCk7XG4gIH1cblxuICAvLyBNZXJnZSB0aGUgY29udGVudCBhbmQgbGluZSBzZXBhcmF0b3JzIGludG8gc2luZ2xlIHRva2Vuc1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzQW5kTmV3bGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgbGluZSA9IGxpbmVzQW5kTmV3bGluZXNbaV07XG5cbiAgICBpZiAoaSAlIDIgJiYgIXRoaXMub3B0aW9ucy5uZXdsaW5lSXNUb2tlbikge1xuICAgICAgcmV0TGluZXNbcmV0TGluZXMubGVuZ3RoIC0gMV0gKz0gbGluZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5pZ25vcmVXaGl0ZXNwYWNlKSB7XG4gICAgICAgIGxpbmUgPSBsaW5lLnRyaW0oKTtcbiAgICAgIH1cbiAgICAgIHJldExpbmVzLnB1c2gobGluZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJldExpbmVzO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZMaW5lcyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHsgcmV0dXJuIGxpbmVEaWZmLmRpZmYob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKTsgfVxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZUcmltbWVkTGluZXMob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKSB7XG4gIGxldCBvcHRpb25zID0gZ2VuZXJhdGVPcHRpb25zKGNhbGxiYWNrLCB7aWdub3JlV2hpdGVzcGFjZTogdHJ1ZX0pO1xuICByZXR1cm4gbGluZURpZmYuZGlmZihvbGRTdHIsIG5ld1N0ciwgb3B0aW9ucyk7XG59XG4iLCJpbXBvcnQgRGlmZiBmcm9tICcuL2Jhc2UnO1xuXG5cbmV4cG9ydCBjb25zdCBzZW50ZW5jZURpZmYgPSBuZXcgRGlmZigpO1xuc2VudGVuY2VEaWZmLnRva2VuaXplID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlLnNwbGl0KC8oXFxTLis/Wy4hP10pKD89XFxzK3wkKS8pO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZTZW50ZW5jZXMob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKSB7IHJldHVybiBzZW50ZW5jZURpZmYuZGlmZihvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spOyB9XG4iLCJpbXBvcnQgRGlmZiBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0IHtnZW5lcmF0ZU9wdGlvbnN9IGZyb20gJy4uL3V0aWwvcGFyYW1zJztcblxuLy8gQmFzZWQgb24gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGF0aW5fc2NyaXB0X2luX1VuaWNvZGVcbi8vXG4vLyBSYW5nZXMgYW5kIGV4Y2VwdGlvbnM6XG4vLyBMYXRpbi0xIFN1cHBsZW1lbnQsIDAwODDigJMwMEZGXG4vLyAgLSBVKzAwRDcgIMOXIE11bHRpcGxpY2F0aW9uIHNpZ25cbi8vICAtIFUrMDBGNyAgw7cgRGl2aXNpb24gc2lnblxuLy8gTGF0aW4gRXh0ZW5kZWQtQSwgMDEwMOKAkzAxN0Zcbi8vIExhdGluIEV4dGVuZGVkLUIsIDAxODDigJMwMjRGXG4vLyBJUEEgRXh0ZW5zaW9ucywgMDI1MOKAkzAyQUZcbi8vIFNwYWNpbmcgTW9kaWZpZXIgTGV0dGVycywgMDJCMOKAkzAyRkZcbi8vICAtIFUrMDJDNyAgy4cgJiM3MTE7ICBDYXJvblxuLy8gIC0gVSswMkQ4ICDLmCAmIzcyODsgIEJyZXZlXG4vLyAgLSBVKzAyRDkgIMuZICYjNzI5OyAgRG90IEFib3ZlXG4vLyAgLSBVKzAyREEgIMuaICYjNzMwOyAgUmluZyBBYm92ZVxuLy8gIC0gVSswMkRCICDLmyAmIzczMTsgIE9nb25la1xuLy8gIC0gVSswMkRDICDLnCAmIzczMjsgIFNtYWxsIFRpbGRlXG4vLyAgLSBVKzAyREQgIMudICYjNzMzOyAgRG91YmxlIEFjdXRlIEFjY2VudFxuLy8gTGF0aW4gRXh0ZW5kZWQgQWRkaXRpb25hbCwgMUUwMOKAkzFFRkZcbmNvbnN0IGV4dGVuZGVkV29yZENoYXJzID0gL15bYS16QS1aXFx1e0MwfS1cXHV7RkZ9XFx1e0Q4fS1cXHV7RjZ9XFx1e0Y4fS1cXHV7MkM2fVxcdXsyQzh9LVxcdXsyRDd9XFx1ezJERX0tXFx1ezJGRn1cXHV7MUUwMH0tXFx1ezFFRkZ9XSskL3U7XG5cbmNvbnN0IHJlV2hpdGVzcGFjZSA9IC9cXFMvO1xuXG5leHBvcnQgY29uc3Qgd29yZERpZmYgPSBuZXcgRGlmZigpO1xud29yZERpZmYuZXF1YWxzID0gZnVuY3Rpb24obGVmdCwgcmlnaHQpIHtcbiAgcmV0dXJuIGxlZnQgPT09IHJpZ2h0IHx8ICh0aGlzLm9wdGlvbnMuaWdub3JlV2hpdGVzcGFjZSAmJiAhcmVXaGl0ZXNwYWNlLnRlc3QobGVmdCkgJiYgIXJlV2hpdGVzcGFjZS50ZXN0KHJpZ2h0KSk7XG59O1xud29yZERpZmYudG9rZW5pemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICBsZXQgdG9rZW5zID0gdmFsdWUuc3BsaXQoLyhcXHMrfFxcYikvKTtcblxuICAvLyBKb2luIHRoZSBib3VuZGFyeSBzcGxpdHMgdGhhdCB3ZSBkbyBub3QgY29uc2lkZXIgdG8gYmUgYm91bmRhcmllcy4gVGhpcyBpcyBwcmltYXJpbHkgdGhlIGV4dGVuZGVkIExhdGluIGNoYXJhY3RlciBzZXQuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdG9rZW5zLmxlbmd0aCAtIDE7IGkrKykge1xuICAgIC8vIElmIHdlIGhhdmUgYW4gZW1wdHkgc3RyaW5nIGluIHRoZSBuZXh0IGZpZWxkIGFuZCB3ZSBoYXZlIG9ubHkgd29yZCBjaGFycyBiZWZvcmUgYW5kIGFmdGVyLCBtZXJnZVxuICAgIGlmICghdG9rZW5zW2kgKyAxXSAmJiB0b2tlbnNbaSArIDJdXG4gICAgICAgICAgJiYgZXh0ZW5kZWRXb3JkQ2hhcnMudGVzdCh0b2tlbnNbaV0pXG4gICAgICAgICAgJiYgZXh0ZW5kZWRXb3JkQ2hhcnMudGVzdCh0b2tlbnNbaSArIDJdKSkge1xuICAgICAgdG9rZW5zW2ldICs9IHRva2Vuc1tpICsgMl07XG4gICAgICB0b2tlbnMuc3BsaWNlKGkgKyAxLCAyKTtcbiAgICAgIGktLTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdG9rZW5zO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZXb3JkcyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHtcbiAgbGV0IG9wdGlvbnMgPSBnZW5lcmF0ZU9wdGlvbnMoY2FsbGJhY2ssIHtpZ25vcmVXaGl0ZXNwYWNlOiB0cnVlfSk7XG4gIHJldHVybiB3b3JkRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBvcHRpb25zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBkaWZmV29yZHNXaXRoU3BhY2Uob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKSB7XG4gIHJldHVybiB3b3JkRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjayk7XG59XG4iLCIvKiBTZWUgTElDRU5TRSBmaWxlIGZvciB0ZXJtcyBvZiB1c2UgKi9cblxuLypcbiAqIFRleHQgZGlmZiBpbXBsZW1lbnRhdGlvbi5cbiAqXG4gKiBUaGlzIGxpYnJhcnkgc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBBUElTOlxuICogSnNEaWZmLmRpZmZDaGFyczogQ2hhcmFjdGVyIGJ5IGNoYXJhY3RlciBkaWZmXG4gKiBKc0RpZmYuZGlmZldvcmRzOiBXb3JkIChhcyBkZWZpbmVkIGJ5IFxcYiByZWdleCkgZGlmZiB3aGljaCBpZ25vcmVzIHdoaXRlc3BhY2VcbiAqIEpzRGlmZi5kaWZmTGluZXM6IExpbmUgYmFzZWQgZGlmZlxuICpcbiAqIEpzRGlmZi5kaWZmQ3NzOiBEaWZmIHRhcmdldGVkIGF0IENTUyBjb250ZW50XG4gKlxuICogVGhlc2UgbWV0aG9kcyBhcmUgYmFzZWQgb24gdGhlIGltcGxlbWVudGF0aW9uIHByb3Bvc2VkIGluXG4gKiBcIkFuIE8oTkQpIERpZmZlcmVuY2UgQWxnb3JpdGhtIGFuZCBpdHMgVmFyaWF0aW9uc1wiIChNeWVycywgMTk4NikuXG4gKiBodHRwOi8vY2l0ZXNlZXJ4LmlzdC5wc3UuZWR1L3ZpZXdkb2Mvc3VtbWFyeT9kb2k9MTAuMS4xLjQuNjkyN1xuICovXG5pbXBvcnQgRGlmZiBmcm9tICcuL2RpZmYvYmFzZSc7XG5pbXBvcnQge2RpZmZDaGFyc30gZnJvbSAnLi9kaWZmL2NoYXJhY3Rlcic7XG5pbXBvcnQge2RpZmZXb3JkcywgZGlmZldvcmRzV2l0aFNwYWNlfSBmcm9tICcuL2RpZmYvd29yZCc7XG5pbXBvcnQge2RpZmZMaW5lcywgZGlmZlRyaW1tZWRMaW5lc30gZnJvbSAnLi9kaWZmL2xpbmUnO1xuaW1wb3J0IHtkaWZmU2VudGVuY2VzfSBmcm9tICcuL2RpZmYvc2VudGVuY2UnO1xuXG5pbXBvcnQge2RpZmZDc3N9IGZyb20gJy4vZGlmZi9jc3MnO1xuaW1wb3J0IHtkaWZmSnNvbiwgY2Fub25pY2FsaXplfSBmcm9tICcuL2RpZmYvanNvbic7XG5cbmltcG9ydCB7ZGlmZkFycmF5c30gZnJvbSAnLi9kaWZmL2FycmF5JztcblxuaW1wb3J0IHthcHBseVBhdGNoLCBhcHBseVBhdGNoZXN9IGZyb20gJy4vcGF0Y2gvYXBwbHknO1xuaW1wb3J0IHtwYXJzZVBhdGNofSBmcm9tICcuL3BhdGNoL3BhcnNlJztcbmltcG9ydCB7c3RydWN0dXJlZFBhdGNoLCBjcmVhdGVUd29GaWxlc1BhdGNoLCBjcmVhdGVQYXRjaH0gZnJvbSAnLi9wYXRjaC9jcmVhdGUnO1xuXG5pbXBvcnQge2NvbnZlcnRDaGFuZ2VzVG9ETVB9IGZyb20gJy4vY29udmVydC9kbXAnO1xuaW1wb3J0IHtjb252ZXJ0Q2hhbmdlc1RvWE1MfSBmcm9tICcuL2NvbnZlcnQveG1sJztcblxuZXhwb3J0IHtcbiAgRGlmZixcblxuICBkaWZmQ2hhcnMsXG4gIGRpZmZXb3JkcyxcbiAgZGlmZldvcmRzV2l0aFNwYWNlLFxuICBkaWZmTGluZXMsXG4gIGRpZmZUcmltbWVkTGluZXMsXG4gIGRpZmZTZW50ZW5jZXMsXG5cbiAgZGlmZkNzcyxcbiAgZGlmZkpzb24sXG5cbiAgZGlmZkFycmF5cyxcblxuICBzdHJ1Y3R1cmVkUGF0Y2gsXG4gIGNyZWF0ZVR3b0ZpbGVzUGF0Y2gsXG4gIGNyZWF0ZVBhdGNoLFxuICBhcHBseVBhdGNoLFxuICBhcHBseVBhdGNoZXMsXG4gIHBhcnNlUGF0Y2gsXG4gIGNvbnZlcnRDaGFuZ2VzVG9ETVAsXG4gIGNvbnZlcnRDaGFuZ2VzVG9YTUwsXG4gIGNhbm9uaWNhbGl6ZVxufTtcbiIsImltcG9ydCB7cGFyc2VQYXRjaH0gZnJvbSAnLi9wYXJzZSc7XG5pbXBvcnQgZGlzdGFuY2VJdGVyYXRvciBmcm9tICcuLi91dGlsL2Rpc3RhbmNlLWl0ZXJhdG9yJztcblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5UGF0Y2goc291cmNlLCB1bmlEaWZmLCBvcHRpb25zID0ge30pIHtcbiAgaWYgKHR5cGVvZiB1bmlEaWZmID09PSAnc3RyaW5nJykge1xuICAgIHVuaURpZmYgPSBwYXJzZVBhdGNoKHVuaURpZmYpO1xuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkodW5pRGlmZikpIHtcbiAgICBpZiAodW5pRGlmZi5sZW5ndGggPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FwcGx5UGF0Y2ggb25seSB3b3JrcyB3aXRoIGEgc2luZ2xlIGlucHV0LicpO1xuICAgIH1cblxuICAgIHVuaURpZmYgPSB1bmlEaWZmWzBdO1xuICB9XG5cbiAgLy8gQXBwbHkgdGhlIGRpZmYgdG8gdGhlIGlucHV0XG4gIGxldCBsaW5lcyA9IHNvdXJjZS5zcGxpdCgvXFxyXFxufFtcXG5cXHZcXGZcXHJcXHg4NV0vKSxcbiAgICAgIGRlbGltaXRlcnMgPSBzb3VyY2UubWF0Y2goL1xcclxcbnxbXFxuXFx2XFxmXFxyXFx4ODVdL2cpIHx8IFtdLFxuICAgICAgaHVua3MgPSB1bmlEaWZmLmh1bmtzLFxuXG4gICAgICBjb21wYXJlTGluZSA9IG9wdGlvbnMuY29tcGFyZUxpbmUgfHwgKChsaW5lTnVtYmVyLCBsaW5lLCBvcGVyYXRpb24sIHBhdGNoQ29udGVudCkgPT4gbGluZSA9PT0gcGF0Y2hDb250ZW50KSxcbiAgICAgIGVycm9yQ291bnQgPSAwLFxuICAgICAgZnV6ekZhY3RvciA9IG9wdGlvbnMuZnV6ekZhY3RvciB8fCAwLFxuICAgICAgbWluTGluZSA9IDAsXG4gICAgICBvZmZzZXQgPSAwLFxuXG4gICAgICByZW1vdmVFT0ZOTCxcbiAgICAgIGFkZEVPRk5MO1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGh1bmsgZXhhY3RseSBmaXRzIG9uIHRoZSBwcm92aWRlZCBsb2NhdGlvblxuICAgKi9cbiAgZnVuY3Rpb24gaHVua0ZpdHMoaHVuaywgdG9Qb3MpIHtcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGh1bmsubGluZXMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGxldCBsaW5lID0gaHVuay5saW5lc1tqXSxcbiAgICAgICAgICBvcGVyYXRpb24gPSBsaW5lWzBdLFxuICAgICAgICAgIGNvbnRlbnQgPSBsaW5lLnN1YnN0cigxKTtcblxuICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gJyAnIHx8IG9wZXJhdGlvbiA9PT0gJy0nKSB7XG4gICAgICAgIC8vIENvbnRleHQgc2FuaXR5IGNoZWNrXG4gICAgICAgIGlmICghY29tcGFyZUxpbmUodG9Qb3MgKyAxLCBsaW5lc1t0b1Bvc10sIG9wZXJhdGlvbiwgY29udGVudCkpIHtcbiAgICAgICAgICBlcnJvckNvdW50Kys7XG5cbiAgICAgICAgICBpZiAoZXJyb3JDb3VudCA+IGZ1enpGYWN0b3IpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdG9Qb3MrKztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIFNlYXJjaCBiZXN0IGZpdCBvZmZzZXRzIGZvciBlYWNoIGh1bmsgYmFzZWQgb24gdGhlIHByZXZpb3VzIG9uZXNcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBodW5rcy5sZW5ndGg7IGkrKykge1xuICAgIGxldCBodW5rID0gaHVua3NbaV0sXG4gICAgICAgIG1heExpbmUgPSBsaW5lcy5sZW5ndGggLSBodW5rLm9sZExpbmVzLFxuICAgICAgICBsb2NhbE9mZnNldCA9IDAsXG4gICAgICAgIHRvUG9zID0gb2Zmc2V0ICsgaHVuay5vbGRTdGFydCAtIDE7XG5cbiAgICBsZXQgaXRlcmF0b3IgPSBkaXN0YW5jZUl0ZXJhdG9yKHRvUG9zLCBtaW5MaW5lLCBtYXhMaW5lKTtcblxuICAgIGZvciAoOyBsb2NhbE9mZnNldCAhPT0gdW5kZWZpbmVkOyBsb2NhbE9mZnNldCA9IGl0ZXJhdG9yKCkpIHtcbiAgICAgIGlmIChodW5rRml0cyhodW5rLCB0b1BvcyArIGxvY2FsT2Zmc2V0KSkge1xuICAgICAgICBodW5rLm9mZnNldCA9IG9mZnNldCArPSBsb2NhbE9mZnNldDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGxvY2FsT2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBTZXQgbG93ZXIgdGV4dCBsaW1pdCB0byBlbmQgb2YgdGhlIGN1cnJlbnQgaHVuaywgc28gbmV4dCBvbmVzIGRvbid0IHRyeVxuICAgIC8vIHRvIGZpdCBvdmVyIGFscmVhZHkgcGF0Y2hlZCB0ZXh0XG4gICAgbWluTGluZSA9IGh1bmsub2Zmc2V0ICsgaHVuay5vbGRTdGFydCArIGh1bmsub2xkTGluZXM7XG4gIH1cblxuICAvLyBBcHBseSBwYXRjaCBodW5rc1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGh1bmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IGh1bmsgPSBodW5rc1tpXSxcbiAgICAgICAgdG9Qb3MgPSBodW5rLm9mZnNldCArIGh1bmsubmV3U3RhcnQgLSAxO1xuICAgIGlmIChodW5rLm5ld0xpbmVzID09IDApIHsgdG9Qb3MrKzsgfVxuXG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBodW5rLmxpbmVzLmxlbmd0aDsgaisrKSB7XG4gICAgICBsZXQgbGluZSA9IGh1bmsubGluZXNbal0sXG4gICAgICAgICAgb3BlcmF0aW9uID0gbGluZVswXSxcbiAgICAgICAgICBjb250ZW50ID0gbGluZS5zdWJzdHIoMSksXG4gICAgICAgICAgZGVsaW1pdGVyID0gaHVuay5saW5lZGVsaW1pdGVyc1tqXTtcblxuICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gJyAnKSB7XG4gICAgICAgIHRvUG9zKys7XG4gICAgICB9IGVsc2UgaWYgKG9wZXJhdGlvbiA9PT0gJy0nKSB7XG4gICAgICAgIGxpbmVzLnNwbGljZSh0b1BvcywgMSk7XG4gICAgICAgIGRlbGltaXRlcnMuc3BsaWNlKHRvUG9zLCAxKTtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICB9IGVsc2UgaWYgKG9wZXJhdGlvbiA9PT0gJysnKSB7XG4gICAgICAgIGxpbmVzLnNwbGljZSh0b1BvcywgMCwgY29udGVudCk7XG4gICAgICAgIGRlbGltaXRlcnMuc3BsaWNlKHRvUG9zLCAwLCBkZWxpbWl0ZXIpO1xuICAgICAgICB0b1BvcysrO1xuICAgICAgfSBlbHNlIGlmIChvcGVyYXRpb24gPT09ICdcXFxcJykge1xuICAgICAgICBsZXQgcHJldmlvdXNPcGVyYXRpb24gPSBodW5rLmxpbmVzW2ogLSAxXSA/IGh1bmsubGluZXNbaiAtIDFdWzBdIDogbnVsbDtcbiAgICAgICAgaWYgKHByZXZpb3VzT3BlcmF0aW9uID09PSAnKycpIHtcbiAgICAgICAgICByZW1vdmVFT0ZOTCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAocHJldmlvdXNPcGVyYXRpb24gPT09ICctJykge1xuICAgICAgICAgIGFkZEVPRk5MID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIEhhbmRsZSBFT0ZOTCBpbnNlcnRpb24vcmVtb3ZhbFxuICBpZiAocmVtb3ZlRU9GTkwpIHtcbiAgICB3aGlsZSAoIWxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdKSB7XG4gICAgICBsaW5lcy5wb3AoKTtcbiAgICAgIGRlbGltaXRlcnMucG9wKCk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGFkZEVPRk5MKSB7XG4gICAgbGluZXMucHVzaCgnJyk7XG4gICAgZGVsaW1pdGVycy5wdXNoKCdcXG4nKTtcbiAgfVxuICBmb3IgKGxldCBfayA9IDA7IF9rIDwgbGluZXMubGVuZ3RoIC0gMTsgX2srKykge1xuICAgIGxpbmVzW19rXSA9IGxpbmVzW19rXSArIGRlbGltaXRlcnNbX2tdO1xuICB9XG4gIHJldHVybiBsaW5lcy5qb2luKCcnKTtcbn1cblxuLy8gV3JhcHBlciB0aGF0IHN1cHBvcnRzIG11bHRpcGxlIGZpbGUgcGF0Y2hlcyB2aWEgY2FsbGJhY2tzLlxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5UGF0Y2hlcyh1bmlEaWZmLCBvcHRpb25zKSB7XG4gIGlmICh0eXBlb2YgdW5pRGlmZiA9PT0gJ3N0cmluZycpIHtcbiAgICB1bmlEaWZmID0gcGFyc2VQYXRjaCh1bmlEaWZmKTtcbiAgfVxuXG4gIGxldCBjdXJyZW50SW5kZXggPSAwO1xuICBmdW5jdGlvbiBwcm9jZXNzSW5kZXgoKSB7XG4gICAgbGV0IGluZGV4ID0gdW5pRGlmZltjdXJyZW50SW5kZXgrK107XG4gICAgaWYgKCFpbmRleCkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICBvcHRpb25zLmxvYWRGaWxlKGluZGV4LCBmdW5jdGlvbihlcnIsIGRhdGEpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMuY29tcGxldGUoZXJyKTtcbiAgICAgIH1cblxuICAgICAgbGV0IHVwZGF0ZWRDb250ZW50ID0gYXBwbHlQYXRjaChkYXRhLCBpbmRleCwgb3B0aW9ucyk7XG4gICAgICBvcHRpb25zLnBhdGNoZWQoaW5kZXgsIHVwZGF0ZWRDb250ZW50LCBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIHJldHVybiBvcHRpb25zLmNvbXBsZXRlKGVycik7XG4gICAgICAgIH1cblxuICAgICAgICBwcm9jZXNzSW5kZXgoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIHByb2Nlc3NJbmRleCgpO1xufVxuIiwiaW1wb3J0IHtkaWZmTGluZXN9IGZyb20gJy4uL2RpZmYvbGluZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBzdHJ1Y3R1cmVkUGF0Y2gob2xkRmlsZU5hbWUsIG5ld0ZpbGVOYW1lLCBvbGRTdHIsIG5ld1N0ciwgb2xkSGVhZGVyLCBuZXdIZWFkZXIsIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5jb250ZXh0ID09PSAndW5kZWZpbmVkJykge1xuICAgIG9wdGlvbnMuY29udGV4dCA9IDQ7XG4gIH1cblxuICBjb25zdCBkaWZmID0gZGlmZkxpbmVzKG9sZFN0ciwgbmV3U3RyLCBvcHRpb25zKTtcbiAgZGlmZi5wdXNoKHt2YWx1ZTogJycsIGxpbmVzOiBbXX0pOyAgIC8vIEFwcGVuZCBhbiBlbXB0eSB2YWx1ZSB0byBtYWtlIGNsZWFudXAgZWFzaWVyXG5cbiAgZnVuY3Rpb24gY29udGV4dExpbmVzKGxpbmVzKSB7XG4gICAgcmV0dXJuIGxpbmVzLm1hcChmdW5jdGlvbihlbnRyeSkgeyByZXR1cm4gJyAnICsgZW50cnk7IH0pO1xuICB9XG5cbiAgbGV0IGh1bmtzID0gW107XG4gIGxldCBvbGRSYW5nZVN0YXJ0ID0gMCwgbmV3UmFuZ2VTdGFydCA9IDAsIGN1clJhbmdlID0gW10sXG4gICAgICBvbGRMaW5lID0gMSwgbmV3TGluZSA9IDE7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGlmZi5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBkaWZmW2ldLFxuICAgICAgICAgIGxpbmVzID0gY3VycmVudC5saW5lcyB8fCBjdXJyZW50LnZhbHVlLnJlcGxhY2UoL1xcbiQvLCAnJykuc3BsaXQoJ1xcbicpO1xuICAgIGN1cnJlbnQubGluZXMgPSBsaW5lcztcblxuICAgIGlmIChjdXJyZW50LmFkZGVkIHx8IGN1cnJlbnQucmVtb3ZlZCkge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBwcmV2aW91cyBjb250ZXh0LCBzdGFydCB3aXRoIHRoYXRcbiAgICAgIGlmICghb2xkUmFuZ2VTdGFydCkge1xuICAgICAgICBjb25zdCBwcmV2ID0gZGlmZltpIC0gMV07XG4gICAgICAgIG9sZFJhbmdlU3RhcnQgPSBvbGRMaW5lO1xuICAgICAgICBuZXdSYW5nZVN0YXJ0ID0gbmV3TGluZTtcblxuICAgICAgICBpZiAocHJldikge1xuICAgICAgICAgIGN1clJhbmdlID0gb3B0aW9ucy5jb250ZXh0ID4gMCA/IGNvbnRleHRMaW5lcyhwcmV2LmxpbmVzLnNsaWNlKC1vcHRpb25zLmNvbnRleHQpKSA6IFtdO1xuICAgICAgICAgIG9sZFJhbmdlU3RhcnQgLT0gY3VyUmFuZ2UubGVuZ3RoO1xuICAgICAgICAgIG5ld1JhbmdlU3RhcnQgLT0gY3VyUmFuZ2UubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE91dHB1dCBvdXIgY2hhbmdlc1xuICAgICAgY3VyUmFuZ2UucHVzaCguLi4gbGluZXMubWFwKGZ1bmN0aW9uKGVudHJ5KSB7XG4gICAgICAgIHJldHVybiAoY3VycmVudC5hZGRlZCA/ICcrJyA6ICctJykgKyBlbnRyeTtcbiAgICAgIH0pKTtcblxuICAgICAgLy8gVHJhY2sgdGhlIHVwZGF0ZWQgZmlsZSBwb3NpdGlvblxuICAgICAgaWYgKGN1cnJlbnQuYWRkZWQpIHtcbiAgICAgICAgbmV3TGluZSArPSBsaW5lcy5sZW5ndGg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvbGRMaW5lICs9IGxpbmVzLmxlbmd0aDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWRlbnRpY2FsIGNvbnRleHQgbGluZXMuIFRyYWNrIGxpbmUgY2hhbmdlc1xuICAgICAgaWYgKG9sZFJhbmdlU3RhcnQpIHtcbiAgICAgICAgLy8gQ2xvc2Ugb3V0IGFueSBjaGFuZ2VzIHRoYXQgaGF2ZSBiZWVuIG91dHB1dCAob3Igam9pbiBvdmVybGFwcGluZylcbiAgICAgICAgaWYgKGxpbmVzLmxlbmd0aCA8PSBvcHRpb25zLmNvbnRleHQgKiAyICYmIGkgPCBkaWZmLmxlbmd0aCAtIDIpIHtcbiAgICAgICAgICAvLyBPdmVybGFwcGluZ1xuICAgICAgICAgIGN1clJhbmdlLnB1c2goLi4uIGNvbnRleHRMaW5lcyhsaW5lcykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGVuZCB0aGUgcmFuZ2UgYW5kIG91dHB1dFxuICAgICAgICAgIGxldCBjb250ZXh0U2l6ZSA9IE1hdGgubWluKGxpbmVzLmxlbmd0aCwgb3B0aW9ucy5jb250ZXh0KTtcbiAgICAgICAgICBjdXJSYW5nZS5wdXNoKC4uLiBjb250ZXh0TGluZXMobGluZXMuc2xpY2UoMCwgY29udGV4dFNpemUpKSk7XG5cbiAgICAgICAgICBsZXQgaHVuayA9IHtcbiAgICAgICAgICAgIG9sZFN0YXJ0OiBvbGRSYW5nZVN0YXJ0LFxuICAgICAgICAgICAgb2xkTGluZXM6IChvbGRMaW5lIC0gb2xkUmFuZ2VTdGFydCArIGNvbnRleHRTaXplKSxcbiAgICAgICAgICAgIG5ld1N0YXJ0OiBuZXdSYW5nZVN0YXJ0LFxuICAgICAgICAgICAgbmV3TGluZXM6IChuZXdMaW5lIC0gbmV3UmFuZ2VTdGFydCArIGNvbnRleHRTaXplKSxcbiAgICAgICAgICAgIGxpbmVzOiBjdXJSYW5nZVxuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKGkgPj0gZGlmZi5sZW5ndGggLSAyICYmIGxpbmVzLmxlbmd0aCA8PSBvcHRpb25zLmNvbnRleHQpIHtcbiAgICAgICAgICAgIC8vIEVPRiBpcyBpbnNpZGUgdGhpcyBodW5rXG4gICAgICAgICAgICBsZXQgb2xkRU9GTmV3bGluZSA9ICgvXFxuJC8udGVzdChvbGRTdHIpKTtcbiAgICAgICAgICAgIGxldCBuZXdFT0ZOZXdsaW5lID0gKC9cXG4kLy50ZXN0KG5ld1N0cikpO1xuICAgICAgICAgICAgaWYgKGxpbmVzLmxlbmd0aCA9PSAwICYmICFvbGRFT0ZOZXdsaW5lKSB7XG4gICAgICAgICAgICAgIC8vIHNwZWNpYWwgY2FzZTogb2xkIGhhcyBubyBlb2wgYW5kIG5vIHRyYWlsaW5nIGNvbnRleHQ7IG5vLW5sIGNhbiBlbmQgdXAgYmVmb3JlIGFkZHNcbiAgICAgICAgICAgICAgY3VyUmFuZ2Uuc3BsaWNlKGh1bmsub2xkTGluZXMsIDAsICdcXFxcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUnKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIW9sZEVPRk5ld2xpbmUgfHwgIW5ld0VPRk5ld2xpbmUpIHtcbiAgICAgICAgICAgICAgY3VyUmFuZ2UucHVzaCgnXFxcXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGh1bmtzLnB1c2goaHVuayk7XG5cbiAgICAgICAgICBvbGRSYW5nZVN0YXJ0ID0gMDtcbiAgICAgICAgICBuZXdSYW5nZVN0YXJ0ID0gMDtcbiAgICAgICAgICBjdXJSYW5nZSA9IFtdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBvbGRMaW5lICs9IGxpbmVzLmxlbmd0aDtcbiAgICAgIG5ld0xpbmUgKz0gbGluZXMubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgb2xkRmlsZU5hbWU6IG9sZEZpbGVOYW1lLCBuZXdGaWxlTmFtZTogbmV3RmlsZU5hbWUsXG4gICAgb2xkSGVhZGVyOiBvbGRIZWFkZXIsIG5ld0hlYWRlcjogbmV3SGVhZGVyLFxuICAgIGh1bmtzOiBodW5rc1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVHdvRmlsZXNQYXRjaChvbGRGaWxlTmFtZSwgbmV3RmlsZU5hbWUsIG9sZFN0ciwgbmV3U3RyLCBvbGRIZWFkZXIsIG5ld0hlYWRlciwgb3B0aW9ucykge1xuICBjb25zdCBkaWZmID0gc3RydWN0dXJlZFBhdGNoKG9sZEZpbGVOYW1lLCBuZXdGaWxlTmFtZSwgb2xkU3RyLCBuZXdTdHIsIG9sZEhlYWRlciwgbmV3SGVhZGVyLCBvcHRpb25zKTtcblxuICBjb25zdCByZXQgPSBbXTtcbiAgaWYgKG9sZEZpbGVOYW1lID09IG5ld0ZpbGVOYW1lKSB7XG4gICAgcmV0LnB1c2goJ0luZGV4OiAnICsgb2xkRmlsZU5hbWUpO1xuICB9XG4gIHJldC5wdXNoKCc9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Jyk7XG4gIHJldC5wdXNoKCctLS0gJyArIGRpZmYub2xkRmlsZU5hbWUgKyAodHlwZW9mIGRpZmYub2xkSGVhZGVyID09PSAndW5kZWZpbmVkJyA/ICcnIDogJ1xcdCcgKyBkaWZmLm9sZEhlYWRlcikpO1xuICByZXQucHVzaCgnKysrICcgKyBkaWZmLm5ld0ZpbGVOYW1lICsgKHR5cGVvZiBkaWZmLm5ld0hlYWRlciA9PT0gJ3VuZGVmaW5lZCcgPyAnJyA6ICdcXHQnICsgZGlmZi5uZXdIZWFkZXIpKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGRpZmYuaHVua3MubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBodW5rID0gZGlmZi5odW5rc1tpXTtcbiAgICByZXQucHVzaChcbiAgICAgICdAQCAtJyArIGh1bmsub2xkU3RhcnQgKyAnLCcgKyBodW5rLm9sZExpbmVzXG4gICAgICArICcgKycgKyBodW5rLm5ld1N0YXJ0ICsgJywnICsgaHVuay5uZXdMaW5lc1xuICAgICAgKyAnIEBAJ1xuICAgICk7XG4gICAgcmV0LnB1c2guYXBwbHkocmV0LCBodW5rLmxpbmVzKTtcbiAgfVxuXG4gIHJldHVybiByZXQuam9pbignXFxuJykgKyAnXFxuJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVBhdGNoKGZpbGVOYW1lLCBvbGRTdHIsIG5ld1N0ciwgb2xkSGVhZGVyLCBuZXdIZWFkZXIsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGNyZWF0ZVR3b0ZpbGVzUGF0Y2goZmlsZU5hbWUsIGZpbGVOYW1lLCBvbGRTdHIsIG5ld1N0ciwgb2xkSGVhZGVyLCBuZXdIZWFkZXIsIG9wdGlvbnMpO1xufVxuIiwiZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUGF0Y2godW5pRGlmZiwgb3B0aW9ucyA9IHt9KSB7XG4gIGxldCBkaWZmc3RyID0gdW5pRGlmZi5zcGxpdCgvXFxyXFxufFtcXG5cXHZcXGZcXHJcXHg4NV0vKSxcbiAgICAgIGRlbGltaXRlcnMgPSB1bmlEaWZmLm1hdGNoKC9cXHJcXG58W1xcblxcdlxcZlxcclxceDg1XS9nKSB8fCBbXSxcbiAgICAgIGxpc3QgPSBbXSxcbiAgICAgIGkgPSAwO1xuXG4gIGZ1bmN0aW9uIHBhcnNlSW5kZXgoKSB7XG4gICAgbGV0IGluZGV4ID0ge307XG4gICAgbGlzdC5wdXNoKGluZGV4KTtcblxuICAgIC8vIFBhcnNlIGRpZmYgbWV0YWRhdGFcbiAgICB3aGlsZSAoaSA8IGRpZmZzdHIubGVuZ3RoKSB7XG4gICAgICBsZXQgbGluZSA9IGRpZmZzdHJbaV07XG5cbiAgICAgIC8vIEZpbGUgaGVhZGVyIGZvdW5kLCBlbmQgcGFyc2luZyBkaWZmIG1ldGFkYXRhXG4gICAgICBpZiAoL14oXFwtXFwtXFwtfFxcK1xcK1xcK3xAQClcXHMvLnRlc3QobGluZSkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIC8vIERpZmYgaW5kZXhcbiAgICAgIGxldCBoZWFkZXIgPSAoL14oPzpJbmRleDp8ZGlmZig/OiAtciBcXHcrKSspXFxzKyguKz8pXFxzKiQvKS5leGVjKGxpbmUpO1xuICAgICAgaWYgKGhlYWRlcikge1xuICAgICAgICBpbmRleC5pbmRleCA9IGhlYWRlclsxXTtcbiAgICAgIH1cblxuICAgICAgaSsrO1xuICAgIH1cblxuICAgIC8vIFBhcnNlIGZpbGUgaGVhZGVycyBpZiB0aGV5IGFyZSBkZWZpbmVkLiBVbmlmaWVkIGRpZmYgcmVxdWlyZXMgdGhlbSwgYnV0XG4gICAgLy8gdGhlcmUncyBubyB0ZWNobmljYWwgaXNzdWVzIHRvIGhhdmUgYW4gaXNvbGF0ZWQgaHVuayB3aXRob3V0IGZpbGUgaGVhZGVyXG4gICAgcGFyc2VGaWxlSGVhZGVyKGluZGV4KTtcbiAgICBwYXJzZUZpbGVIZWFkZXIoaW5kZXgpO1xuXG4gICAgLy8gUGFyc2UgaHVua3NcbiAgICBpbmRleC5odW5rcyA9IFtdO1xuXG4gICAgd2hpbGUgKGkgPCBkaWZmc3RyLmxlbmd0aCkge1xuICAgICAgbGV0IGxpbmUgPSBkaWZmc3RyW2ldO1xuXG4gICAgICBpZiAoL14oSW5kZXg6fGRpZmZ8XFwtXFwtXFwtfFxcK1xcK1xcKylcXHMvLnRlc3QobGluZSkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IGVsc2UgaWYgKC9eQEAvLnRlc3QobGluZSkpIHtcbiAgICAgICAgaW5kZXguaHVua3MucHVzaChwYXJzZUh1bmsoKSk7XG4gICAgICB9IGVsc2UgaWYgKGxpbmUgJiYgb3B0aW9ucy5zdHJpY3QpIHtcbiAgICAgICAgLy8gSWdub3JlIHVuZXhwZWN0ZWQgY29udGVudCB1bmxlc3MgaW4gc3RyaWN0IG1vZGVcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGxpbmUgJyArIChpICsgMSkgKyAnICcgKyBKU09OLnN0cmluZ2lmeShsaW5lKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpKys7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gUGFyc2VzIHRoZSAtLS0gYW5kICsrKyBoZWFkZXJzLCBpZiBub25lIGFyZSBmb3VuZCwgbm8gbGluZXNcbiAgLy8gYXJlIGNvbnN1bWVkLlxuICBmdW5jdGlvbiBwYXJzZUZpbGVIZWFkZXIoaW5kZXgpIHtcbiAgICBjb25zdCBoZWFkZXJQYXR0ZXJuID0gL14oLS0tfFxcK1xcK1xcKylcXHMrKFtcXFMgXSopKD86XFx0KC4qPylcXHMqKT8kLztcbiAgICBjb25zdCBmaWxlSGVhZGVyID0gaGVhZGVyUGF0dGVybi5leGVjKGRpZmZzdHJbaV0pO1xuICAgIGlmIChmaWxlSGVhZGVyKSB7XG4gICAgICBsZXQga2V5UHJlZml4ID0gZmlsZUhlYWRlclsxXSA9PT0gJy0tLScgPyAnb2xkJyA6ICduZXcnO1xuICAgICAgaW5kZXhba2V5UHJlZml4ICsgJ0ZpbGVOYW1lJ10gPSBmaWxlSGVhZGVyWzJdO1xuICAgICAgaW5kZXhba2V5UHJlZml4ICsgJ0hlYWRlciddID0gZmlsZUhlYWRlclszXTtcblxuICAgICAgaSsrO1xuICAgIH1cbiAgfVxuXG4gIC8vIFBhcnNlcyBhIGh1bmtcbiAgLy8gVGhpcyBhc3N1bWVzIHRoYXQgd2UgYXJlIGF0IHRoZSBzdGFydCBvZiBhIGh1bmsuXG4gIGZ1bmN0aW9uIHBhcnNlSHVuaygpIHtcbiAgICBsZXQgY2h1bmtIZWFkZXJJbmRleCA9IGksXG4gICAgICAgIGNodW5rSGVhZGVyTGluZSA9IGRpZmZzdHJbaSsrXSxcbiAgICAgICAgY2h1bmtIZWFkZXIgPSBjaHVua0hlYWRlckxpbmUuc3BsaXQoL0BAIC0oXFxkKykoPzosKFxcZCspKT8gXFwrKFxcZCspKD86LChcXGQrKSk/IEBALyk7XG5cbiAgICBsZXQgaHVuayA9IHtcbiAgICAgIG9sZFN0YXJ0OiArY2h1bmtIZWFkZXJbMV0sXG4gICAgICBvbGRMaW5lczogK2NodW5rSGVhZGVyWzJdIHx8IDEsXG4gICAgICBuZXdTdGFydDogK2NodW5rSGVhZGVyWzNdLFxuICAgICAgbmV3TGluZXM6ICtjaHVua0hlYWRlcls0XSB8fCAxLFxuICAgICAgbGluZXM6IFtdLFxuICAgICAgbGluZWRlbGltaXRlcnM6IFtdXG4gICAgfTtcblxuICAgIGxldCBhZGRDb3VudCA9IDAsXG4gICAgICAgIHJlbW92ZUNvdW50ID0gMDtcbiAgICBmb3IgKDsgaSA8IGRpZmZzdHIubGVuZ3RoOyBpKyspIHtcbiAgICAgIC8vIExpbmVzIHN0YXJ0aW5nIHdpdGggJy0tLScgY291bGQgYmUgbWlzdGFrZW4gZm9yIHRoZSBcInJlbW92ZSBsaW5lXCIgb3BlcmF0aW9uXG4gICAgICAvLyBCdXQgdGhleSBjb3VsZCBiZSB0aGUgaGVhZGVyIGZvciB0aGUgbmV4dCBmaWxlLiBUaGVyZWZvcmUgcHJ1bmUgc3VjaCBjYXNlcyBvdXQuXG4gICAgICBpZiAoZGlmZnN0cltpXS5pbmRleE9mKCctLS0gJykgPT09IDBcbiAgICAgICAgICAgICYmIChpICsgMiA8IGRpZmZzdHIubGVuZ3RoKVxuICAgICAgICAgICAgJiYgZGlmZnN0cltpICsgMV0uaW5kZXhPZignKysrICcpID09PSAwXG4gICAgICAgICAgICAmJiBkaWZmc3RyW2kgKyAyXS5pbmRleE9mKCdAQCcpID09PSAwKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBsZXQgb3BlcmF0aW9uID0gZGlmZnN0cltpXVswXTtcblxuICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gJysnIHx8IG9wZXJhdGlvbiA9PT0gJy0nIHx8IG9wZXJhdGlvbiA9PT0gJyAnIHx8IG9wZXJhdGlvbiA9PT0gJ1xcXFwnKSB7XG4gICAgICAgIGh1bmsubGluZXMucHVzaChkaWZmc3RyW2ldKTtcbiAgICAgICAgaHVuay5saW5lZGVsaW1pdGVycy5wdXNoKGRlbGltaXRlcnNbaV0gfHwgJ1xcbicpO1xuXG4gICAgICAgIGlmIChvcGVyYXRpb24gPT09ICcrJykge1xuICAgICAgICAgIGFkZENvdW50Kys7XG4gICAgICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uID09PSAnLScpIHtcbiAgICAgICAgICByZW1vdmVDb3VudCsrO1xuICAgICAgICB9IGVsc2UgaWYgKG9wZXJhdGlvbiA9PT0gJyAnKSB7XG4gICAgICAgICAgYWRkQ291bnQrKztcbiAgICAgICAgICByZW1vdmVDb3VudCsrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgdGhlIGVtcHR5IGJsb2NrIGNvdW50IGNhc2VcbiAgICBpZiAoIWFkZENvdW50ICYmIGh1bmsubmV3TGluZXMgPT09IDEpIHtcbiAgICAgIGh1bmsubmV3TGluZXMgPSAwO1xuICAgIH1cbiAgICBpZiAoIXJlbW92ZUNvdW50ICYmIGh1bmsub2xkTGluZXMgPT09IDEpIHtcbiAgICAgIGh1bmsub2xkTGluZXMgPSAwO1xuICAgIH1cblxuICAgIC8vIFBlcmZvcm0gb3B0aW9uYWwgc2FuaXR5IGNoZWNraW5nXG4gICAgaWYgKG9wdGlvbnMuc3RyaWN0KSB7XG4gICAgICBpZiAoYWRkQ291bnQgIT09IGh1bmsubmV3TGluZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBZGRlZCBsaW5lIGNvdW50IGRpZCBub3QgbWF0Y2ggZm9yIGh1bmsgYXQgbGluZSAnICsgKGNodW5rSGVhZGVySW5kZXggKyAxKSk7XG4gICAgICB9XG4gICAgICBpZiAocmVtb3ZlQ291bnQgIT09IGh1bmsub2xkTGluZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZW1vdmVkIGxpbmUgY291bnQgZGlkIG5vdCBtYXRjaCBmb3IgaHVuayBhdCBsaW5lICcgKyAoY2h1bmtIZWFkZXJJbmRleCArIDEpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaHVuaztcbiAgfVxuXG4gIHdoaWxlIChpIDwgZGlmZnN0ci5sZW5ndGgpIHtcbiAgICBwYXJzZUluZGV4KCk7XG4gIH1cblxuICByZXR1cm4gbGlzdDtcbn1cbiIsIi8vIEl0ZXJhdG9yIHRoYXQgdHJhdmVyc2VzIGluIHRoZSByYW5nZSBvZiBbbWluLCBtYXhdLCBzdGVwcGluZ1xuLy8gYnkgZGlzdGFuY2UgZnJvbSBhIGdpdmVuIHN0YXJ0IHBvc2l0aW9uLiBJLmUuIGZvciBbMCwgNF0sIHdpdGhcbi8vIHN0YXJ0IG9mIDIsIHRoaXMgd2lsbCBpdGVyYXRlIDIsIDMsIDEsIDQsIDAuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihzdGFydCwgbWluTGluZSwgbWF4TGluZSkge1xuICBsZXQgd2FudEZvcndhcmQgPSB0cnVlLFxuICAgICAgYmFja3dhcmRFeGhhdXN0ZWQgPSBmYWxzZSxcbiAgICAgIGZvcndhcmRFeGhhdXN0ZWQgPSBmYWxzZSxcbiAgICAgIGxvY2FsT2Zmc2V0ID0gMTtcblxuICByZXR1cm4gZnVuY3Rpb24gaXRlcmF0b3IoKSB7XG4gICAgaWYgKHdhbnRGb3J3YXJkICYmICFmb3J3YXJkRXhoYXVzdGVkKSB7XG4gICAgICBpZiAoYmFja3dhcmRFeGhhdXN0ZWQpIHtcbiAgICAgICAgbG9jYWxPZmZzZXQrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdhbnRGb3J3YXJkID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGlmIHRyeWluZyB0byBmaXQgYmV5b25kIHRleHQgbGVuZ3RoLCBhbmQgaWYgbm90LCBjaGVjayBpdCBmaXRzXG4gICAgICAvLyBhZnRlciBvZmZzZXQgbG9jYXRpb24gKG9yIGRlc2lyZWQgbG9jYXRpb24gb24gZmlyc3QgaXRlcmF0aW9uKVxuICAgICAgaWYgKHN0YXJ0ICsgbG9jYWxPZmZzZXQgPD0gbWF4TGluZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxPZmZzZXQ7XG4gICAgICB9XG5cbiAgICAgIGZvcndhcmRFeGhhdXN0ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICghYmFja3dhcmRFeGhhdXN0ZWQpIHtcbiAgICAgIGlmICghZm9yd2FyZEV4aGF1c3RlZCkge1xuICAgICAgICB3YW50Rm9yd2FyZCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGlmIHRyeWluZyB0byBmaXQgYmVmb3JlIHRleHQgYmVnaW5uaW5nLCBhbmQgaWYgbm90LCBjaGVjayBpdCBmaXRzXG4gICAgICAvLyBiZWZvcmUgb2Zmc2V0IGxvY2F0aW9uXG4gICAgICBpZiAobWluTGluZSA8PSBzdGFydCAtIGxvY2FsT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiAtbG9jYWxPZmZzZXQrKztcbiAgICAgIH1cblxuICAgICAgYmFja3dhcmRFeGhhdXN0ZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIGl0ZXJhdG9yKCk7XG4gICAgfVxuXG4gICAgLy8gV2UgdHJpZWQgdG8gZml0IGh1bmsgYmVmb3JlIHRleHQgYmVnaW5uaW5nIGFuZCBiZXlvbmQgdGV4dCBsZW5naHQsIHRoZW5cbiAgICAvLyBodW5rIGNhbid0IGZpdCBvbiB0aGUgdGV4dC4gUmV0dXJuIHVuZGVmaW5lZFxuICB9O1xufVxuIiwiZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlT3B0aW9ucyhvcHRpb25zLCBkZWZhdWx0cykge1xuICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBkZWZhdWx0cy5jYWxsYmFjayA9IG9wdGlvbnM7XG4gIH0gZWxzZSBpZiAob3B0aW9ucykge1xuICAgIGZvciAobGV0IG5hbWUgaW4gb3B0aW9ucykge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgIGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgIGRlZmF1bHRzW25hbWVdID0gb3B0aW9uc1tuYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRlZmF1bHRzO1xufVxuIiwiXG52YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZm9yRWFjaCAob2JqLCBmbiwgY3R4KSB7XG4gICAgaWYgKHRvU3RyaW5nLmNhbGwoZm4pICE9PSAnW29iamVjdCBGdW5jdGlvbl0nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2l0ZXJhdG9yIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgIH1cbiAgICB2YXIgbCA9IG9iai5sZW5ndGg7XG4gICAgaWYgKGwgPT09ICtsKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICBmbi5jYWxsKGN0eCwgb2JqW2ldLCBpLCBvYmopO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZm9yICh2YXIgayBpbiBvYmopIHtcbiAgICAgICAgICAgIGlmIChoYXNPd24uY2FsbChvYmosIGspKSB7XG4gICAgICAgICAgICAgICAgZm4uY2FsbChjdHgsIG9ialtrXSwgaywgb2JqKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn07XG5cbiIsIlxudmFyIGluZGV4T2YgPSBbXS5pbmRleE9mO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGFyciwgb2JqKXtcbiAgaWYgKGluZGV4T2YpIHJldHVybiBhcnIuaW5kZXhPZihvYmopO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7ICsraSkge1xuICAgIGlmIChhcnJbaV0gPT09IG9iaikgcmV0dXJuIGk7XG4gIH1cbiAgcmV0dXJuIC0xO1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFycikgPT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG4iLCIvKiEgSlNPTiB2My4zLjAgfCBodHRwOi8vYmVzdGllanMuZ2l0aHViLmlvL2pzb24zIHwgQ29weXJpZ2h0IDIwMTItMjAxNCwgS2l0IENhbWJyaWRnZSB8IGh0dHA6Ly9raXQubWl0LWxpY2Vuc2Uub3JnICovXG47KGZ1bmN0aW9uIChyb290KSB7XG4gIC8vIERldGVjdCB0aGUgYGRlZmluZWAgZnVuY3Rpb24gZXhwb3NlZCBieSBhc3luY2hyb25vdXMgbW9kdWxlIGxvYWRlcnMuIFRoZVxuICAvLyBzdHJpY3QgYGRlZmluZWAgY2hlY2sgaXMgbmVjZXNzYXJ5IGZvciBjb21wYXRpYmlsaXR5IHdpdGggYHIuanNgLlxuICB2YXIgaXNMb2FkZXIgPSB0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZDtcblxuICAvLyBVc2UgdGhlIGBnbG9iYWxgIG9iamVjdCBleHBvc2VkIGJ5IE5vZGUgKGluY2x1ZGluZyBCcm93c2VyaWZ5IHZpYVxuICAvLyBgaW5zZXJ0LW1vZHVsZS1nbG9iYWxzYCksIE5hcndoYWwsIGFuZCBSaW5nbyBhcyB0aGUgZGVmYXVsdCBjb250ZXh0LlxuICAvLyBSaGlubyBleHBvcnRzIGEgYGdsb2JhbGAgZnVuY3Rpb24gaW5zdGVhZC5cbiAgdmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09IFwib2JqZWN0XCIgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbFtcImdsb2JhbFwiXSA9PT0gZnJlZUdsb2JhbCB8fCBmcmVlR2xvYmFsW1wid2luZG93XCJdID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLy8gUHVibGljOiBJbml0aWFsaXplcyBKU09OIDMgdXNpbmcgdGhlIGdpdmVuIGBjb250ZXh0YCBvYmplY3QsIGF0dGFjaGluZyB0aGVcbiAgLy8gYHN0cmluZ2lmeWAgYW5kIGBwYXJzZWAgZnVuY3Rpb25zIHRvIHRoZSBzcGVjaWZpZWQgYGV4cG9ydHNgIG9iamVjdC5cbiAgZnVuY3Rpb24gcnVuSW5Db250ZXh0KGNvbnRleHQsIGV4cG9ydHMpIHtcbiAgICBjb250ZXh0IHx8IChjb250ZXh0ID0gcm9vdFtcIk9iamVjdFwiXSgpKTtcbiAgICBleHBvcnRzIHx8IChleHBvcnRzID0gcm9vdFtcIk9iamVjdFwiXSgpKTtcblxuICAgIC8vIE5hdGl2ZSBjb25zdHJ1Y3RvciBhbGlhc2VzLlxuICAgIHZhciBOdW1iZXIgPSBjb250ZXh0W1wiTnVtYmVyXCJdIHx8IHJvb3RbXCJOdW1iZXJcIl0sXG4gICAgICAgIFN0cmluZyA9IGNvbnRleHRbXCJTdHJpbmdcIl0gfHwgcm9vdFtcIlN0cmluZ1wiXSxcbiAgICAgICAgT2JqZWN0ID0gY29udGV4dFtcIk9iamVjdFwiXSB8fCByb290W1wiT2JqZWN0XCJdLFxuICAgICAgICBEYXRlID0gY29udGV4dFtcIkRhdGVcIl0gfHwgcm9vdFtcIkRhdGVcIl0sXG4gICAgICAgIFN5bnRheEVycm9yID0gY29udGV4dFtcIlN5bnRheEVycm9yXCJdIHx8IHJvb3RbXCJTeW50YXhFcnJvclwiXSxcbiAgICAgICAgVHlwZUVycm9yID0gY29udGV4dFtcIlR5cGVFcnJvclwiXSB8fCByb290W1wiVHlwZUVycm9yXCJdLFxuICAgICAgICBNYXRoID0gY29udGV4dFtcIk1hdGhcIl0gfHwgcm9vdFtcIk1hdGhcIl0sXG4gICAgICAgIG5hdGl2ZUpTT04gPSBjb250ZXh0W1wiSlNPTlwiXSB8fCByb290W1wiSlNPTlwiXTtcblxuICAgIC8vIERlbGVnYXRlIHRvIHRoZSBuYXRpdmUgYHN0cmluZ2lmeWAgYW5kIGBwYXJzZWAgaW1wbGVtZW50YXRpb25zLlxuICAgIGlmICh0eXBlb2YgbmF0aXZlSlNPTiA9PSBcIm9iamVjdFwiICYmIG5hdGl2ZUpTT04pIHtcbiAgICAgIGV4cG9ydHMuc3RyaW5naWZ5ID0gbmF0aXZlSlNPTi5zdHJpbmdpZnk7XG4gICAgICBleHBvcnRzLnBhcnNlID0gbmF0aXZlSlNPTi5wYXJzZTtcbiAgICB9XG5cbiAgICAvLyBDb252ZW5pZW5jZSBhbGlhc2VzLlxuICAgIHZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGUsXG4gICAgICAgIGdldENsYXNzID0gb2JqZWN0UHJvdG8udG9TdHJpbmcsXG4gICAgICAgIGlzUHJvcGVydHksIGZvckVhY2gsIHVuZGVmO1xuXG4gICAgLy8gVGVzdCB0aGUgYERhdGUjZ2V0VVRDKmAgbWV0aG9kcy4gQmFzZWQgb24gd29yayBieSBAWWFmZmxlLlxuICAgIHZhciBpc0V4dGVuZGVkID0gbmV3IERhdGUoLTM1MDk4MjczMzQ1NzMyOTIpO1xuICAgIHRyeSB7XG4gICAgICAvLyBUaGUgYGdldFVUQ0Z1bGxZZWFyYCwgYE1vbnRoYCwgYW5kIGBEYXRlYCBtZXRob2RzIHJldHVybiBub25zZW5zaWNhbFxuICAgICAgLy8gcmVzdWx0cyBmb3IgY2VydGFpbiBkYXRlcyBpbiBPcGVyYSA+PSAxMC41My5cbiAgICAgIGlzRXh0ZW5kZWQgPSBpc0V4dGVuZGVkLmdldFVUQ0Z1bGxZZWFyKCkgPT0gLTEwOTI1MiAmJiBpc0V4dGVuZGVkLmdldFVUQ01vbnRoKCkgPT09IDAgJiYgaXNFeHRlbmRlZC5nZXRVVENEYXRlKCkgPT09IDEgJiZcbiAgICAgICAgLy8gU2FmYXJpIDwgMi4wLjIgc3RvcmVzIHRoZSBpbnRlcm5hbCBtaWxsaXNlY29uZCB0aW1lIHZhbHVlIGNvcnJlY3RseSxcbiAgICAgICAgLy8gYnV0IGNsaXBzIHRoZSB2YWx1ZXMgcmV0dXJuZWQgYnkgdGhlIGRhdGUgbWV0aG9kcyB0byB0aGUgcmFuZ2Ugb2ZcbiAgICAgICAgLy8gc2lnbmVkIDMyLWJpdCBpbnRlZ2VycyAoWy0yICoqIDMxLCAyICoqIDMxIC0gMV0pLlxuICAgICAgICBpc0V4dGVuZGVkLmdldFVUQ0hvdXJzKCkgPT0gMTAgJiYgaXNFeHRlbmRlZC5nZXRVVENNaW51dGVzKCkgPT0gMzcgJiYgaXNFeHRlbmRlZC5nZXRVVENTZWNvbmRzKCkgPT0gNiAmJiBpc0V4dGVuZGVkLmdldFVUQ01pbGxpc2Vjb25kcygpID09IDcwODtcbiAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG5cbiAgICAvLyBJbnRlcm5hbDogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBuYXRpdmUgYEpTT04uc3RyaW5naWZ5YCBhbmQgYHBhcnNlYFxuICAgIC8vIGltcGxlbWVudGF0aW9ucyBhcmUgc3BlYy1jb21wbGlhbnQuIEJhc2VkIG9uIHdvcmsgYnkgS2VuIFNueWRlci5cbiAgICBmdW5jdGlvbiBoYXMobmFtZSkge1xuICAgICAgaWYgKGhhc1tuYW1lXSAhPT0gdW5kZWYpIHtcbiAgICAgICAgLy8gUmV0dXJuIGNhY2hlZCBmZWF0dXJlIHRlc3QgcmVzdWx0LlxuICAgICAgICByZXR1cm4gaGFzW25hbWVdO1xuICAgICAgfVxuICAgICAgdmFyIGlzU3VwcG9ydGVkO1xuICAgICAgaWYgKG5hbWUgPT0gXCJidWctc3RyaW5nLWNoYXItaW5kZXhcIikge1xuICAgICAgICAvLyBJRSA8PSA3IGRvZXNuJ3Qgc3VwcG9ydCBhY2Nlc3Npbmcgc3RyaW5nIGNoYXJhY3RlcnMgdXNpbmcgc3F1YXJlXG4gICAgICAgIC8vIGJyYWNrZXQgbm90YXRpb24uIElFIDggb25seSBzdXBwb3J0cyB0aGlzIGZvciBwcmltaXRpdmVzLlxuICAgICAgICBpc1N1cHBvcnRlZCA9IFwiYVwiWzBdICE9IFwiYVwiO1xuICAgICAgfSBlbHNlIGlmIChuYW1lID09IFwianNvblwiKSB7XG4gICAgICAgIC8vIEluZGljYXRlcyB3aGV0aGVyIGJvdGggYEpTT04uc3RyaW5naWZ5YCBhbmQgYEpTT04ucGFyc2VgIGFyZVxuICAgICAgICAvLyBzdXBwb3J0ZWQuXG4gICAgICAgIGlzU3VwcG9ydGVkID0gaGFzKFwianNvbi1zdHJpbmdpZnlcIikgJiYgaGFzKFwianNvbi1wYXJzZVwiKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciB2YWx1ZSwgc2VyaWFsaXplZCA9ICd7XCJhXCI6WzEsdHJ1ZSxmYWxzZSxudWxsLFwiXFxcXHUwMDAwXFxcXGJcXFxcblxcXFxmXFxcXHJcXFxcdFwiXX0nO1xuICAgICAgICAvLyBUZXN0IGBKU09OLnN0cmluZ2lmeWAuXG4gICAgICAgIGlmIChuYW1lID09IFwianNvbi1zdHJpbmdpZnlcIikge1xuICAgICAgICAgIHZhciBzdHJpbmdpZnkgPSBleHBvcnRzLnN0cmluZ2lmeSwgc3RyaW5naWZ5U3VwcG9ydGVkID0gdHlwZW9mIHN0cmluZ2lmeSA9PSBcImZ1bmN0aW9uXCIgJiYgaXNFeHRlbmRlZDtcbiAgICAgICAgICBpZiAoc3RyaW5naWZ5U3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAvLyBBIHRlc3QgZnVuY3Rpb24gb2JqZWN0IHdpdGggYSBjdXN0b20gYHRvSlNPTmAgbWV0aG9kLlxuICAgICAgICAgICAgKHZhbHVlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgIH0pLnRvSlNPTiA9IHZhbHVlO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgc3RyaW5naWZ5U3VwcG9ydGVkID1cbiAgICAgICAgICAgICAgICAvLyBGaXJlZm94IDMuMWIxIGFuZCBiMiBzZXJpYWxpemUgc3RyaW5nLCBudW1iZXIsIGFuZCBib29sZWFuXG4gICAgICAgICAgICAgICAgLy8gcHJpbWl0aXZlcyBhcyBvYmplY3QgbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KDApID09PSBcIjBcIiAmJlxuICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCBiMiwgYW5kIEpTT04gMiBzZXJpYWxpemUgd3JhcHBlZCBwcmltaXRpdmVzIGFzIG9iamVjdFxuICAgICAgICAgICAgICAgIC8vIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgTnVtYmVyKCkpID09PSBcIjBcIiAmJlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgU3RyaW5nKCkpID09ICdcIlwiJyAmJlxuICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCAyIHRocm93IGFuIGVycm9yIGlmIHRoZSB2YWx1ZSBpcyBgbnVsbGAsIGB1bmRlZmluZWRgLCBvclxuICAgICAgICAgICAgICAgIC8vIGRvZXMgbm90IGRlZmluZSBhIGNhbm9uaWNhbCBKU09OIHJlcHJlc2VudGF0aW9uICh0aGlzIGFwcGxpZXMgdG9cbiAgICAgICAgICAgICAgICAvLyBvYmplY3RzIHdpdGggYHRvSlNPTmAgcHJvcGVydGllcyBhcyB3ZWxsLCAqdW5sZXNzKiB0aGV5IGFyZSBuZXN0ZWRcbiAgICAgICAgICAgICAgICAvLyB3aXRoaW4gYW4gb2JqZWN0IG9yIGFycmF5KS5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoZ2V0Q2xhc3MpID09PSB1bmRlZiAmJlxuICAgICAgICAgICAgICAgIC8vIElFIDggc2VyaWFsaXplcyBgdW5kZWZpbmVkYCBhcyBgXCJ1bmRlZmluZWRcImAuIFNhZmFyaSA8PSA1LjEuNyBhbmRcbiAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMyBwYXNzIHRoaXMgdGVzdC5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkodW5kZWYpID09PSB1bmRlZiAmJlxuICAgICAgICAgICAgICAgIC8vIFNhZmFyaSA8PSA1LjEuNyBhbmQgRkYgMy4xYjMgdGhyb3cgYEVycm9yYHMgYW5kIGBUeXBlRXJyb3JgcyxcbiAgICAgICAgICAgICAgICAvLyByZXNwZWN0aXZlbHksIGlmIHRoZSB2YWx1ZSBpcyBvbWl0dGVkIGVudGlyZWx5LlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeSgpID09PSB1bmRlZiAmJlxuICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCAyIHRocm93IGFuIGVycm9yIGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBub3QgYSBudW1iZXIsXG4gICAgICAgICAgICAgICAgLy8gc3RyaW5nLCBhcnJheSwgb2JqZWN0LCBCb29sZWFuLCBvciBgbnVsbGAgbGl0ZXJhbC4gVGhpcyBhcHBsaWVzIHRvXG4gICAgICAgICAgICAgICAgLy8gb2JqZWN0cyB3aXRoIGN1c3RvbSBgdG9KU09OYCBtZXRob2RzIGFzIHdlbGwsIHVubGVzcyB0aGV5IGFyZSBuZXN0ZWRcbiAgICAgICAgICAgICAgICAvLyBpbnNpZGUgb2JqZWN0IG9yIGFycmF5IGxpdGVyYWxzLiBZVUkgMy4wLjBiMSBpZ25vcmVzIGN1c3RvbSBgdG9KU09OYFxuICAgICAgICAgICAgICAgIC8vIG1ldGhvZHMgZW50aXJlbHkuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KHZhbHVlKSA9PT0gXCIxXCIgJiZcbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoW3ZhbHVlXSkgPT0gXCJbMV1cIiAmJlxuICAgICAgICAgICAgICAgIC8vIFByb3RvdHlwZSA8PSAxLjYuMSBzZXJpYWxpemVzIGBbdW5kZWZpbmVkXWAgYXMgYFwiW11cImAgaW5zdGVhZCBvZlxuICAgICAgICAgICAgICAgIC8vIGBcIltudWxsXVwiYC5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoW3VuZGVmXSkgPT0gXCJbbnVsbF1cIiAmJlxuICAgICAgICAgICAgICAgIC8vIFlVSSAzLjAuMGIxIGZhaWxzIHRvIHNlcmlhbGl6ZSBgbnVsbGAgbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG51bGwpID09IFwibnVsbFwiICYmXG4gICAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIDIgaGFsdHMgc2VyaWFsaXphdGlvbiBpZiBhbiBhcnJheSBjb250YWlucyBhIGZ1bmN0aW9uOlxuICAgICAgICAgICAgICAgIC8vIGBbMSwgdHJ1ZSwgZ2V0Q2xhc3MsIDFdYCBzZXJpYWxpemVzIGFzIFwiWzEsdHJ1ZSxdLFwiLiBGRiAzLjFiM1xuICAgICAgICAgICAgICAgIC8vIGVsaWRlcyBub24tSlNPTiB2YWx1ZXMgZnJvbSBvYmplY3RzIGFuZCBhcnJheXMsIHVubGVzcyB0aGV5XG4gICAgICAgICAgICAgICAgLy8gZGVmaW5lIGN1c3RvbSBgdG9KU09OYCBtZXRob2RzLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShbdW5kZWYsIGdldENsYXNzLCBudWxsXSkgPT0gXCJbbnVsbCxudWxsLG51bGxdXCIgJiZcbiAgICAgICAgICAgICAgICAvLyBTaW1wbGUgc2VyaWFsaXphdGlvbiB0ZXN0LiBGRiAzLjFiMSB1c2VzIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlc1xuICAgICAgICAgICAgICAgIC8vIHdoZXJlIGNoYXJhY3RlciBlc2NhcGUgY29kZXMgYXJlIGV4cGVjdGVkIChlLmcuLCBgXFxiYCA9PiBgXFx1MDAwOGApLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeSh7IFwiYVwiOiBbdmFsdWUsIHRydWUsIGZhbHNlLCBudWxsLCBcIlxceDAwXFxiXFxuXFxmXFxyXFx0XCJdIH0pID09IHNlcmlhbGl6ZWQgJiZcbiAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMSBhbmQgYjIgaWdub3JlIHRoZSBgZmlsdGVyYCBhbmQgYHdpZHRoYCBhcmd1bWVudHMuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG51bGwsIHZhbHVlKSA9PT0gXCIxXCIgJiZcbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoWzEsIDJdLCBudWxsLCAxKSA9PSBcIltcXG4gMSxcXG4gMlxcbl1cIiAmJlxuICAgICAgICAgICAgICAgIC8vIEpTT04gMiwgUHJvdG90eXBlIDw9IDEuNywgYW5kIG9sZGVyIFdlYktpdCBidWlsZHMgaW5jb3JyZWN0bHlcbiAgICAgICAgICAgICAgICAvLyBzZXJpYWxpemUgZXh0ZW5kZWQgeWVhcnMuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKC04LjY0ZTE1KSkgPT0gJ1wiLTI3MTgyMS0wNC0yMFQwMDowMDowMC4wMDBaXCInICYmXG4gICAgICAgICAgICAgICAgLy8gVGhlIG1pbGxpc2Vjb25kcyBhcmUgb3B0aW9uYWwgaW4gRVMgNSwgYnV0IHJlcXVpcmVkIGluIDUuMS5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoOC42NGUxNSkpID09ICdcIisyNzU3NjAtMDktMTNUMDA6MDA6MDAuMDAwWlwiJyAmJlxuICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggPD0gMTEuMCBpbmNvcnJlY3RseSBzZXJpYWxpemVzIHllYXJzIHByaW9yIHRvIDAgYXMgbmVnYXRpdmVcbiAgICAgICAgICAgICAgICAvLyBmb3VyLWRpZ2l0IHllYXJzIGluc3RlYWQgb2Ygc2l4LWRpZ2l0IHllYXJzLiBDcmVkaXRzOiBAWWFmZmxlLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgRGF0ZSgtNjIxOTg3NTUyZTUpKSA9PSAnXCItMDAwMDAxLTAxLTAxVDAwOjAwOjAwLjAwMFpcIicgJiZcbiAgICAgICAgICAgICAgICAvLyBTYWZhcmkgPD0gNS4xLjUgYW5kIE9wZXJhID49IDEwLjUzIGluY29ycmVjdGx5IHNlcmlhbGl6ZSBtaWxsaXNlY29uZFxuICAgICAgICAgICAgICAgIC8vIHZhbHVlcyBsZXNzIHRoYW4gMTAwMC4gQ3JlZGl0czogQFlhZmZsZS5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoLTEpKSA9PSAnXCIxOTY5LTEyLTMxVDIzOjU5OjU5Ljk5OVpcIic7XG4gICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgc3RyaW5naWZ5U3VwcG9ydGVkID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlzU3VwcG9ydGVkID0gc3RyaW5naWZ5U3VwcG9ydGVkO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRlc3QgYEpTT04ucGFyc2VgLlxuICAgICAgICBpZiAobmFtZSA9PSBcImpzb24tcGFyc2VcIikge1xuICAgICAgICAgIHZhciBwYXJzZSA9IGV4cG9ydHMucGFyc2U7XG4gICAgICAgICAgaWYgKHR5cGVvZiBwYXJzZSA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCBiMiB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiBhIGJhcmUgbGl0ZXJhbCBpcyBwcm92aWRlZC5cbiAgICAgICAgICAgICAgLy8gQ29uZm9ybWluZyBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIGFsc28gY29lcmNlIHRoZSBpbml0aWFsIGFyZ3VtZW50IHRvXG4gICAgICAgICAgICAgIC8vIGEgc3RyaW5nIHByaW9yIHRvIHBhcnNpbmcuXG4gICAgICAgICAgICAgIGlmIChwYXJzZShcIjBcIikgPT09IDAgJiYgIXBhcnNlKGZhbHNlKSkge1xuICAgICAgICAgICAgICAgIC8vIFNpbXBsZSBwYXJzaW5nIHRlc3QuXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZShzZXJpYWxpemVkKTtcbiAgICAgICAgICAgICAgICB2YXIgcGFyc2VTdXBwb3J0ZWQgPSB2YWx1ZVtcImFcIl0ubGVuZ3RoID09IDUgJiYgdmFsdWVbXCJhXCJdWzBdID09PSAxO1xuICAgICAgICAgICAgICAgIGlmIChwYXJzZVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIDw9IDUuMS4yIGFuZCBGRiAzLjFiMSBhbGxvdyB1bmVzY2FwZWQgdGFicyBpbiBzdHJpbmdzLlxuICAgICAgICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9ICFwYXJzZSgnXCJcXHRcIicpO1xuICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlU3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gRkYgNC4wIGFuZCA0LjAuMSBhbGxvdyBsZWFkaW5nIGArYCBzaWducyBhbmQgbGVhZGluZ1xuICAgICAgICAgICAgICAgICAgICAgIC8vIGRlY2ltYWwgcG9pbnRzLiBGRiA0LjAsIDQuMC4xLCBhbmQgSUUgOS0xMCBhbHNvIGFsbG93XG4gICAgICAgICAgICAgICAgICAgICAgLy8gY2VydGFpbiBvY3RhbCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9IHBhcnNlKFwiMDFcIikgIT09IDE7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGlmIChwYXJzZVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIEZGIDQuMCwgNC4wLjEsIGFuZCBSaGlubyAxLjdSMy1SNCBhbGxvdyB0cmFpbGluZyBkZWNpbWFsXG4gICAgICAgICAgICAgICAgICAgICAgLy8gcG9pbnRzLiBUaGVzZSBlbnZpcm9ubWVudHMsIGFsb25nIHdpdGggRkYgMy4xYjEgYW5kIDIsXG4gICAgICAgICAgICAgICAgICAgICAgLy8gYWxzbyBhbGxvdyB0cmFpbGluZyBjb21tYXMgaW4gSlNPTiBvYmplY3RzIGFuZCBhcnJheXMuXG4gICAgICAgICAgICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBwYXJzZShcIjEuXCIpICE9PSAxO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaXNTdXBwb3J0ZWQgPSBwYXJzZVN1cHBvcnRlZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc1tuYW1lXSA9ICEhaXNTdXBwb3J0ZWQ7XG4gICAgfVxuXG4gICAgaWYgKCFoYXMoXCJqc29uXCIpKSB7XG4gICAgICAvLyBDb21tb24gYFtbQ2xhc3NdXWAgbmFtZSBhbGlhc2VzLlxuICAgICAgdmFyIGZ1bmN0aW9uQ2xhc3MgPSBcIltvYmplY3QgRnVuY3Rpb25dXCIsXG4gICAgICAgICAgZGF0ZUNsYXNzID0gXCJbb2JqZWN0IERhdGVdXCIsXG4gICAgICAgICAgbnVtYmVyQ2xhc3MgPSBcIltvYmplY3QgTnVtYmVyXVwiLFxuICAgICAgICAgIHN0cmluZ0NsYXNzID0gXCJbb2JqZWN0IFN0cmluZ11cIixcbiAgICAgICAgICBhcnJheUNsYXNzID0gXCJbb2JqZWN0IEFycmF5XVwiLFxuICAgICAgICAgIGJvb2xlYW5DbGFzcyA9IFwiW29iamVjdCBCb29sZWFuXVwiO1xuXG4gICAgICAvLyBEZXRlY3QgaW5jb21wbGV0ZSBzdXBwb3J0IGZvciBhY2Nlc3Npbmcgc3RyaW5nIGNoYXJhY3RlcnMgYnkgaW5kZXguXG4gICAgICB2YXIgY2hhckluZGV4QnVnZ3kgPSBoYXMoXCJidWctc3RyaW5nLWNoYXItaW5kZXhcIik7XG5cbiAgICAgIC8vIERlZmluZSBhZGRpdGlvbmFsIHV0aWxpdHkgbWV0aG9kcyBpZiB0aGUgYERhdGVgIG1ldGhvZHMgYXJlIGJ1Z2d5LlxuICAgICAgaWYgKCFpc0V4dGVuZGVkKSB7XG4gICAgICAgIHZhciBmbG9vciA9IE1hdGguZmxvb3I7XG4gICAgICAgIC8vIEEgbWFwcGluZyBiZXR3ZWVuIHRoZSBtb250aHMgb2YgdGhlIHllYXIgYW5kIHRoZSBudW1iZXIgb2YgZGF5cyBiZXR3ZWVuXG4gICAgICAgIC8vIEphbnVhcnkgMXN0IGFuZCB0aGUgZmlyc3Qgb2YgdGhlIHJlc3BlY3RpdmUgbW9udGguXG4gICAgICAgIHZhciBNb250aHMgPSBbMCwgMzEsIDU5LCA5MCwgMTIwLCAxNTEsIDE4MSwgMjEyLCAyNDMsIDI3MywgMzA0LCAzMzRdO1xuICAgICAgICAvLyBJbnRlcm5hbDogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIGRheXMgYmV0d2VlbiB0aGUgVW5peCBlcG9jaCBhbmQgdGhlXG4gICAgICAgIC8vIGZpcnN0IGRheSBvZiB0aGUgZ2l2ZW4gbW9udGguXG4gICAgICAgIHZhciBnZXREYXkgPSBmdW5jdGlvbiAoeWVhciwgbW9udGgpIHtcbiAgICAgICAgICByZXR1cm4gTW9udGhzW21vbnRoXSArIDM2NSAqICh5ZWFyIC0gMTk3MCkgKyBmbG9vcigoeWVhciAtIDE5NjkgKyAobW9udGggPSArKG1vbnRoID4gMSkpKSAvIDQpIC0gZmxvb3IoKHllYXIgLSAxOTAxICsgbW9udGgpIC8gMTAwKSArIGZsb29yKCh5ZWFyIC0gMTYwMSArIG1vbnRoKSAvIDQwMCk7XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIC8vIEludGVybmFsOiBEZXRlcm1pbmVzIGlmIGEgcHJvcGVydHkgaXMgYSBkaXJlY3QgcHJvcGVydHkgb2YgdGhlIGdpdmVuXG4gICAgICAvLyBvYmplY3QuIERlbGVnYXRlcyB0byB0aGUgbmF0aXZlIGBPYmplY3QjaGFzT3duUHJvcGVydHlgIG1ldGhvZC5cbiAgICAgIGlmICghKGlzUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eSkpIHtcbiAgICAgICAgaXNQcm9wZXJ0eSA9IGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgICAgICAgIHZhciBtZW1iZXJzID0ge30sIGNvbnN0cnVjdG9yO1xuICAgICAgICAgIGlmICgobWVtYmVycy5fX3Byb3RvX18gPSBudWxsLCBtZW1iZXJzLl9fcHJvdG9fXyA9IHtcbiAgICAgICAgICAgIC8vIFRoZSAqcHJvdG8qIHByb3BlcnR5IGNhbm5vdCBiZSBzZXQgbXVsdGlwbGUgdGltZXMgaW4gcmVjZW50XG4gICAgICAgICAgICAvLyB2ZXJzaW9ucyBvZiBGaXJlZm94IGFuZCBTZWFNb25rZXkuXG4gICAgICAgICAgICBcInRvU3RyaW5nXCI6IDFcbiAgICAgICAgICB9LCBtZW1iZXJzKS50b1N0cmluZyAhPSBnZXRDbGFzcykge1xuICAgICAgICAgICAgLy8gU2FmYXJpIDw9IDIuMC4zIGRvZXNuJ3QgaW1wbGVtZW50IGBPYmplY3QjaGFzT3duUHJvcGVydHlgLCBidXRcbiAgICAgICAgICAgIC8vIHN1cHBvcnRzIHRoZSBtdXRhYmxlICpwcm90byogcHJvcGVydHkuXG4gICAgICAgICAgICBpc1Byb3BlcnR5ID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgIC8vIENhcHR1cmUgYW5kIGJyZWFrIHRoZSBvYmplY3RncyBwcm90b3R5cGUgY2hhaW4gKHNlZSBzZWN0aW9uIDguNi4yXG4gICAgICAgICAgICAgIC8vIG9mIHRoZSBFUyA1LjEgc3BlYykuIFRoZSBwYXJlbnRoZXNpemVkIGV4cHJlc3Npb24gcHJldmVudHMgYW5cbiAgICAgICAgICAgICAgLy8gdW5zYWZlIHRyYW5zZm9ybWF0aW9uIGJ5IHRoZSBDbG9zdXJlIENvbXBpbGVyLlxuICAgICAgICAgICAgICB2YXIgb3JpZ2luYWwgPSB0aGlzLl9fcHJvdG9fXywgcmVzdWx0ID0gcHJvcGVydHkgaW4gKHRoaXMuX19wcm90b19fID0gbnVsbCwgdGhpcyk7XG4gICAgICAgICAgICAgIC8vIFJlc3RvcmUgdGhlIG9yaWdpbmFsIHByb3RvdHlwZSBjaGFpbi5cbiAgICAgICAgICAgICAgdGhpcy5fX3Byb3RvX18gPSBvcmlnaW5hbDtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIENhcHR1cmUgYSByZWZlcmVuY2UgdG8gdGhlIHRvcC1sZXZlbCBgT2JqZWN0YCBjb25zdHJ1Y3Rvci5cbiAgICAgICAgICAgIGNvbnN0cnVjdG9yID0gbWVtYmVycy5jb25zdHJ1Y3RvcjtcbiAgICAgICAgICAgIC8vIFVzZSB0aGUgYGNvbnN0cnVjdG9yYCBwcm9wZXJ0eSB0byBzaW11bGF0ZSBgT2JqZWN0I2hhc093blByb3BlcnR5YCBpblxuICAgICAgICAgICAgLy8gb3RoZXIgZW52aXJvbm1lbnRzLlxuICAgICAgICAgICAgaXNQcm9wZXJ0eSA9IGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgICAgICAgICAgICB2YXIgcGFyZW50ID0gKHRoaXMuY29uc3RydWN0b3IgfHwgY29uc3RydWN0b3IpLnByb3RvdHlwZTtcbiAgICAgICAgICAgICAgcmV0dXJuIHByb3BlcnR5IGluIHRoaXMgJiYgIShwcm9wZXJ0eSBpbiBwYXJlbnQgJiYgdGhpc1twcm9wZXJ0eV0gPT09IHBhcmVudFtwcm9wZXJ0eV0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbWVtYmVycyA9IG51bGw7XG4gICAgICAgICAgcmV0dXJuIGlzUHJvcGVydHkuY2FsbCh0aGlzLCBwcm9wZXJ0eSk7XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIC8vIEludGVybmFsOiBBIHNldCBvZiBwcmltaXRpdmUgdHlwZXMgdXNlZCBieSBgaXNIb3N0VHlwZWAuXG4gICAgICB2YXIgUHJpbWl0aXZlVHlwZXMgPSB7XG4gICAgICAgIFwiYm9vbGVhblwiOiAxLFxuICAgICAgICBcIm51bWJlclwiOiAxLFxuICAgICAgICBcInN0cmluZ1wiOiAxLFxuICAgICAgICBcInVuZGVmaW5lZFwiOiAxXG4gICAgICB9O1xuXG4gICAgICAvLyBJbnRlcm5hbDogRGV0ZXJtaW5lcyBpZiB0aGUgZ2l2ZW4gb2JqZWN0IGBwcm9wZXJ0eWAgdmFsdWUgaXMgYVxuICAgICAgLy8gbm9uLXByaW1pdGl2ZS5cbiAgICAgIHZhciBpc0hvc3RUeXBlID0gZnVuY3Rpb24gKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlb2Ygb2JqZWN0W3Byb3BlcnR5XTtcbiAgICAgICAgcmV0dXJuIHR5cGUgPT0gXCJvYmplY3RcIiA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6ICFQcmltaXRpdmVUeXBlc1t0eXBlXTtcbiAgICAgIH07XG5cbiAgICAgIC8vIEludGVybmFsOiBOb3JtYWxpemVzIHRoZSBgZm9yLi4uaW5gIGl0ZXJhdGlvbiBhbGdvcml0aG0gYWNyb3NzXG4gICAgICAvLyBlbnZpcm9ubWVudHMuIEVhY2ggZW51bWVyYXRlZCBrZXkgaXMgeWllbGRlZCB0byBhIGBjYWxsYmFja2AgZnVuY3Rpb24uXG4gICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHNpemUgPSAwLCBQcm9wZXJ0aWVzLCBtZW1iZXJzLCBwcm9wZXJ0eTtcblxuICAgICAgICAvLyBUZXN0cyBmb3IgYnVncyBpbiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCdzIGBmb3IuLi5pbmAgYWxnb3JpdGhtLiBUaGVcbiAgICAgICAgLy8gYHZhbHVlT2ZgIHByb3BlcnR5IGluaGVyaXRzIHRoZSBub24tZW51bWVyYWJsZSBmbGFnIGZyb21cbiAgICAgICAgLy8gYE9iamVjdC5wcm90b3R5cGVgIGluIG9sZGVyIHZlcnNpb25zIG9mIElFLCBOZXRzY2FwZSwgYW5kIE1vemlsbGEuXG4gICAgICAgIChQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHRoaXMudmFsdWVPZiA9IDA7XG4gICAgICAgIH0pLnByb3RvdHlwZS52YWx1ZU9mID0gMDtcblxuICAgICAgICAvLyBJdGVyYXRlIG92ZXIgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGBQcm9wZXJ0aWVzYCBjbGFzcy5cbiAgICAgICAgbWVtYmVycyA9IG5ldyBQcm9wZXJ0aWVzKCk7XG4gICAgICAgIGZvciAocHJvcGVydHkgaW4gbWVtYmVycykge1xuICAgICAgICAgIC8vIElnbm9yZSBhbGwgcHJvcGVydGllcyBpbmhlcml0ZWQgZnJvbSBgT2JqZWN0LnByb3RvdHlwZWAuXG4gICAgICAgICAgaWYgKGlzUHJvcGVydHkuY2FsbChtZW1iZXJzLCBwcm9wZXJ0eSkpIHtcbiAgICAgICAgICAgIHNpemUrKztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgUHJvcGVydGllcyA9IG1lbWJlcnMgPSBudWxsO1xuXG4gICAgICAgIC8vIE5vcm1hbGl6ZSB0aGUgaXRlcmF0aW9uIGFsZ29yaXRobS5cbiAgICAgICAgaWYgKCFzaXplKSB7XG4gICAgICAgICAgLy8gQSBsaXN0IG9mIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgaW5oZXJpdGVkIGZyb20gYE9iamVjdC5wcm90b3R5cGVgLlxuICAgICAgICAgIG1lbWJlcnMgPSBbXCJ2YWx1ZU9mXCIsIFwidG9TdHJpbmdcIiwgXCJ0b0xvY2FsZVN0cmluZ1wiLCBcInByb3BlcnR5SXNFbnVtZXJhYmxlXCIsIFwiaXNQcm90b3R5cGVPZlwiLCBcImhhc093blByb3BlcnR5XCIsIFwiY29uc3RydWN0b3JcIl07XG4gICAgICAgICAgLy8gSUUgPD0gOCwgTW96aWxsYSAxLjAsIGFuZCBOZXRzY2FwZSA2LjIgaWdub3JlIHNoYWRvd2VkIG5vbi1lbnVtZXJhYmxlXG4gICAgICAgICAgLy8gcHJvcGVydGllcy5cbiAgICAgICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHZhciBpc0Z1bmN0aW9uID0gZ2V0Q2xhc3MuY2FsbChvYmplY3QpID09IGZ1bmN0aW9uQ2xhc3MsIHByb3BlcnR5LCBsZW5ndGg7XG4gICAgICAgICAgICB2YXIgaGFzUHJvcGVydHkgPSAhaXNGdW5jdGlvbiAmJiB0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yICE9IFwiZnVuY3Rpb25cIiAmJiBpc0hvc3RUeXBlKG9iamVjdCwgXCJoYXNPd25Qcm9wZXJ0eVwiKSA/IG9iamVjdC5oYXNPd25Qcm9wZXJ0eSA6IGlzUHJvcGVydHk7XG4gICAgICAgICAgICBmb3IgKHByb3BlcnR5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgICAvLyBHZWNrbyA8PSAxLjAgZW51bWVyYXRlcyB0aGUgYHByb3RvdHlwZWAgcHJvcGVydHkgb2YgZnVuY3Rpb25zIHVuZGVyXG4gICAgICAgICAgICAgIC8vIGNlcnRhaW4gY29uZGl0aW9uczsgSUUgZG9lcyBub3QuXG4gICAgICAgICAgICAgIGlmICghKGlzRnVuY3Rpb24gJiYgcHJvcGVydHkgPT0gXCJwcm90b3R5cGVcIikgJiYgaGFzUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gTWFudWFsbHkgaW52b2tlIHRoZSBjYWxsYmFjayBmb3IgZWFjaCBub24tZW51bWVyYWJsZSBwcm9wZXJ0eS5cbiAgICAgICAgICAgIGZvciAobGVuZ3RoID0gbWVtYmVycy5sZW5ndGg7IHByb3BlcnR5ID0gbWVtYmVyc1stLWxlbmd0aF07IGhhc1Byb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSkgJiYgY2FsbGJhY2socHJvcGVydHkpKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKHNpemUgPT0gMikge1xuICAgICAgICAgIC8vIFNhZmFyaSA8PSAyLjAuNCBlbnVtZXJhdGVzIHNoYWRvd2VkIHByb3BlcnRpZXMgdHdpY2UuXG4gICAgICAgICAgZm9yRWFjaCA9IGZ1bmN0aW9uIChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAvLyBDcmVhdGUgYSBzZXQgb2YgaXRlcmF0ZWQgcHJvcGVydGllcy5cbiAgICAgICAgICAgIHZhciBtZW1iZXJzID0ge30sIGlzRnVuY3Rpb24gPSBnZXRDbGFzcy5jYWxsKG9iamVjdCkgPT0gZnVuY3Rpb25DbGFzcywgcHJvcGVydHk7XG4gICAgICAgICAgICBmb3IgKHByb3BlcnR5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgICAvLyBTdG9yZSBlYWNoIHByb3BlcnR5IG5hbWUgdG8gcHJldmVudCBkb3VibGUgZW51bWVyYXRpb24uIFRoZVxuICAgICAgICAgICAgICAvLyBgcHJvdG90eXBlYCBwcm9wZXJ0eSBvZiBmdW5jdGlvbnMgaXMgbm90IGVudW1lcmF0ZWQgZHVlIHRvIGNyb3NzLVxuICAgICAgICAgICAgICAvLyBlbnZpcm9ubWVudCBpbmNvbnNpc3RlbmNpZXMuXG4gICAgICAgICAgICAgIGlmICghKGlzRnVuY3Rpb24gJiYgcHJvcGVydHkgPT0gXCJwcm90b3R5cGVcIikgJiYgIWlzUHJvcGVydHkuY2FsbChtZW1iZXJzLCBwcm9wZXJ0eSkgJiYgKG1lbWJlcnNbcHJvcGVydHldID0gMSkgJiYgaXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2socHJvcGVydHkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBObyBidWdzIGRldGVjdGVkOyB1c2UgdGhlIHN0YW5kYXJkIGBmb3IuLi5pbmAgYWxnb3JpdGhtLlxuICAgICAgICAgIGZvckVhY2ggPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgdmFyIGlzRnVuY3Rpb24gPSBnZXRDbGFzcy5jYWxsKG9iamVjdCkgPT0gZnVuY3Rpb25DbGFzcywgcHJvcGVydHksIGlzQ29uc3RydWN0b3I7XG4gICAgICAgICAgICBmb3IgKHByb3BlcnR5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgICBpZiAoIShpc0Z1bmN0aW9uICYmIHByb3BlcnR5ID09IFwicHJvdG90eXBlXCIpICYmIGlzUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSAmJiAhKGlzQ29uc3RydWN0b3IgPSBwcm9wZXJ0eSA9PT0gXCJjb25zdHJ1Y3RvclwiKSkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gTWFudWFsbHkgaW52b2tlIHRoZSBjYWxsYmFjayBmb3IgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgZHVlIHRvXG4gICAgICAgICAgICAvLyBjcm9zcy1lbnZpcm9ubWVudCBpbmNvbnNpc3RlbmNpZXMuXG4gICAgICAgICAgICBpZiAoaXNDb25zdHJ1Y3RvciB8fCBpc1Byb3BlcnR5LmNhbGwob2JqZWN0LCAocHJvcGVydHkgPSBcImNvbnN0cnVjdG9yXCIpKSkge1xuICAgICAgICAgICAgICBjYWxsYmFjayhwcm9wZXJ0eSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm9yRWFjaChvYmplY3QsIGNhbGxiYWNrKTtcbiAgICAgIH07XG5cbiAgICAgIC8vIFB1YmxpYzogU2VyaWFsaXplcyBhIEphdmFTY3JpcHQgYHZhbHVlYCBhcyBhIEpTT04gc3RyaW5nLiBUaGUgb3B0aW9uYWxcbiAgICAgIC8vIGBmaWx0ZXJgIGFyZ3VtZW50IG1heSBzcGVjaWZ5IGVpdGhlciBhIGZ1bmN0aW9uIHRoYXQgYWx0ZXJzIGhvdyBvYmplY3QgYW5kXG4gICAgICAvLyBhcnJheSBtZW1iZXJzIGFyZSBzZXJpYWxpemVkLCBvciBhbiBhcnJheSBvZiBzdHJpbmdzIGFuZCBudW1iZXJzIHRoYXRcbiAgICAgIC8vIGluZGljYXRlcyB3aGljaCBwcm9wZXJ0aWVzIHNob3VsZCBiZSBzZXJpYWxpemVkLiBUaGUgb3B0aW9uYWwgYHdpZHRoYFxuICAgICAgLy8gYXJndW1lbnQgbWF5IGJlIGVpdGhlciBhIHN0cmluZyBvciBudW1iZXIgdGhhdCBzcGVjaWZpZXMgdGhlIGluZGVudGF0aW9uXG4gICAgICAvLyBsZXZlbCBvZiB0aGUgb3V0cHV0LlxuICAgICAgaWYgKCFoYXMoXCJqc29uLXN0cmluZ2lmeVwiKSkge1xuICAgICAgICAvLyBJbnRlcm5hbDogQSBtYXAgb2YgY29udHJvbCBjaGFyYWN0ZXJzIGFuZCB0aGVpciBlc2NhcGVkIGVxdWl2YWxlbnRzLlxuICAgICAgICB2YXIgRXNjYXBlcyA9IHtcbiAgICAgICAgICA5MjogXCJcXFxcXFxcXFwiLFxuICAgICAgICAgIDM0OiAnXFxcXFwiJyxcbiAgICAgICAgICA4OiBcIlxcXFxiXCIsXG4gICAgICAgICAgMTI6IFwiXFxcXGZcIixcbiAgICAgICAgICAxMDogXCJcXFxcblwiLFxuICAgICAgICAgIDEzOiBcIlxcXFxyXCIsXG4gICAgICAgICAgOTogXCJcXFxcdFwiXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IENvbnZlcnRzIGB2YWx1ZWAgaW50byBhIHplcm8tcGFkZGVkIHN0cmluZyBzdWNoIHRoYXQgaXRzXG4gICAgICAgIC8vIGxlbmd0aCBpcyBhdCBsZWFzdCBlcXVhbCB0byBgd2lkdGhgLiBUaGUgYHdpZHRoYCBtdXN0IGJlIDw9IDYuXG4gICAgICAgIHZhciBsZWFkaW5nWmVyb2VzID0gXCIwMDAwMDBcIjtcbiAgICAgICAgdmFyIHRvUGFkZGVkU3RyaW5nID0gZnVuY3Rpb24gKHdpZHRoLCB2YWx1ZSkge1xuICAgICAgICAgIC8vIFRoZSBgfHwgMGAgZXhwcmVzc2lvbiBpcyBuZWNlc3NhcnkgdG8gd29yayBhcm91bmQgYSBidWcgaW5cbiAgICAgICAgICAvLyBPcGVyYSA8PSA3LjU0dTIgd2hlcmUgYDAgPT0gLTBgLCBidXQgYFN0cmluZygtMCkgIT09IFwiMFwiYC5cbiAgICAgICAgICByZXR1cm4gKGxlYWRpbmdaZXJvZXMgKyAodmFsdWUgfHwgMCkpLnNsaWNlKC13aWR0aCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IERvdWJsZS1xdW90ZXMgYSBzdHJpbmcgYHZhbHVlYCwgcmVwbGFjaW5nIGFsbCBBU0NJSSBjb250cm9sXG4gICAgICAgIC8vIGNoYXJhY3RlcnMgKGNoYXJhY3RlcnMgd2l0aCBjb2RlIHVuaXQgdmFsdWVzIGJldHdlZW4gMCBhbmQgMzEpIHdpdGhcbiAgICAgICAgLy8gdGhlaXIgZXNjYXBlZCBlcXVpdmFsZW50cy4gVGhpcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGVcbiAgICAgICAgLy8gYFF1b3RlKHZhbHVlKWAgb3BlcmF0aW9uIGRlZmluZWQgaW4gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMy5cbiAgICAgICAgdmFyIHVuaWNvZGVQcmVmaXggPSBcIlxcXFx1MDBcIjtcbiAgICAgICAgdmFyIHF1b3RlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9ICdcIicsIGluZGV4ID0gMCwgbGVuZ3RoID0gdmFsdWUubGVuZ3RoLCB1c2VDaGFySW5kZXggPSAhY2hhckluZGV4QnVnZ3kgfHwgbGVuZ3RoID4gMTA7XG4gICAgICAgICAgdmFyIHN5bWJvbHMgPSB1c2VDaGFySW5kZXggJiYgKGNoYXJJbmRleEJ1Z2d5ID8gdmFsdWUuc3BsaXQoXCJcIikgOiB2YWx1ZSk7XG4gICAgICAgICAgZm9yICg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICB2YXIgY2hhckNvZGUgPSB2YWx1ZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBjaGFyYWN0ZXIgaXMgYSBjb250cm9sIGNoYXJhY3RlciwgYXBwZW5kIGl0cyBVbmljb2RlIG9yXG4gICAgICAgICAgICAvLyBzaG9ydGhhbmQgZXNjYXBlIHNlcXVlbmNlOyBvdGhlcndpc2UsIGFwcGVuZCB0aGUgY2hhcmFjdGVyIGFzLWlzLlxuICAgICAgICAgICAgc3dpdGNoIChjaGFyQ29kZSkge1xuICAgICAgICAgICAgICBjYXNlIDg6IGNhc2UgOTogY2FzZSAxMDogY2FzZSAxMjogY2FzZSAxMzogY2FzZSAzNDogY2FzZSA5MjpcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gRXNjYXBlc1tjaGFyQ29kZV07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlIDwgMzIpIHtcbiAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSB1bmljb2RlUHJlZml4ICsgdG9QYWRkZWRTdHJpbmcoMiwgY2hhckNvZGUudG9TdHJpbmcoMTYpKTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gdXNlQ2hhckluZGV4ID8gc3ltYm9sc1tpbmRleF0gOiB2YWx1ZS5jaGFyQXQoaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcmVzdWx0ICsgJ1wiJztcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogUmVjdXJzaXZlbHkgc2VyaWFsaXplcyBhbiBvYmplY3QuIEltcGxlbWVudHMgdGhlXG4gICAgICAgIC8vIGBTdHIoa2V5LCBob2xkZXIpYCwgYEpPKHZhbHVlKWAsIGFuZCBgSkEodmFsdWUpYCBvcGVyYXRpb25zLlxuICAgICAgICB2YXIgc2VyaWFsaXplID0gZnVuY3Rpb24gKHByb3BlcnR5LCBvYmplY3QsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCB3aGl0ZXNwYWNlLCBpbmRlbnRhdGlvbiwgc3RhY2spIHtcbiAgICAgICAgICB2YXIgdmFsdWUsIGNsYXNzTmFtZSwgeWVhciwgbW9udGgsIGRhdGUsIHRpbWUsIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLCBtaWxsaXNlY29uZHMsIHJlc3VsdHMsIGVsZW1lbnQsIGluZGV4LCBsZW5ndGgsIHByZWZpeCwgcmVzdWx0O1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBOZWNlc3NhcnkgZm9yIGhvc3Qgb2JqZWN0IHN1cHBvcnQuXG4gICAgICAgICAgICB2YWx1ZSA9IG9iamVjdFtwcm9wZXJ0eV07XG4gICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIiAmJiB2YWx1ZSkge1xuICAgICAgICAgICAgY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbCh2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoY2xhc3NOYW1lID09IGRhdGVDbGFzcyAmJiAhaXNQcm9wZXJ0eS5jYWxsKHZhbHVlLCBcInRvSlNPTlwiKSkge1xuICAgICAgICAgICAgICBpZiAodmFsdWUgPiAtMSAvIDAgJiYgdmFsdWUgPCAxIC8gMCkge1xuICAgICAgICAgICAgICAgIC8vIERhdGVzIGFyZSBzZXJpYWxpemVkIGFjY29yZGluZyB0byB0aGUgYERhdGUjdG9KU09OYCBtZXRob2RcbiAgICAgICAgICAgICAgICAvLyBzcGVjaWZpZWQgaW4gRVMgNS4xIHNlY3Rpb24gMTUuOS41LjQ0LiBTZWUgc2VjdGlvbiAxNS45LjEuMTVcbiAgICAgICAgICAgICAgICAvLyBmb3IgdGhlIElTTyA4NjAxIGRhdGUgdGltZSBzdHJpbmcgZm9ybWF0LlxuICAgICAgICAgICAgICAgIGlmIChnZXREYXkpIHtcbiAgICAgICAgICAgICAgICAgIC8vIE1hbnVhbGx5IGNvbXB1dGUgdGhlIHllYXIsIG1vbnRoLCBkYXRlLCBob3VycywgbWludXRlcyxcbiAgICAgICAgICAgICAgICAgIC8vIHNlY29uZHMsIGFuZCBtaWxsaXNlY29uZHMgaWYgdGhlIGBnZXRVVEMqYCBtZXRob2RzIGFyZVxuICAgICAgICAgICAgICAgICAgLy8gYnVnZ3kuIEFkYXB0ZWQgZnJvbSBAWWFmZmxlJ3MgYGRhdGUtc2hpbWAgcHJvamVjdC5cbiAgICAgICAgICAgICAgICAgIGRhdGUgPSBmbG9vcih2YWx1ZSAvIDg2NGU1KTtcbiAgICAgICAgICAgICAgICAgIGZvciAoeWVhciA9IGZsb29yKGRhdGUgLyAzNjUuMjQyNSkgKyAxOTcwIC0gMTsgZ2V0RGF5KHllYXIgKyAxLCAwKSA8PSBkYXRlOyB5ZWFyKyspO1xuICAgICAgICAgICAgICAgICAgZm9yIChtb250aCA9IGZsb29yKChkYXRlIC0gZ2V0RGF5KHllYXIsIDApKSAvIDMwLjQyKTsgZ2V0RGF5KHllYXIsIG1vbnRoICsgMSkgPD0gZGF0ZTsgbW9udGgrKyk7XG4gICAgICAgICAgICAgICAgICBkYXRlID0gMSArIGRhdGUgLSBnZXREYXkoeWVhciwgbW9udGgpO1xuICAgICAgICAgICAgICAgICAgLy8gVGhlIGB0aW1lYCB2YWx1ZSBzcGVjaWZpZXMgdGhlIHRpbWUgd2l0aGluIHRoZSBkYXkgKHNlZSBFU1xuICAgICAgICAgICAgICAgICAgLy8gNS4xIHNlY3Rpb24gMTUuOS4xLjIpLiBUaGUgZm9ybXVsYSBgKEEgJSBCICsgQikgJSBCYCBpcyB1c2VkXG4gICAgICAgICAgICAgICAgICAvLyB0byBjb21wdXRlIGBBIG1vZHVsbyBCYCwgYXMgdGhlIGAlYCBvcGVyYXRvciBkb2VzIG5vdFxuICAgICAgICAgICAgICAgICAgLy8gY29ycmVzcG9uZCB0byB0aGUgYG1vZHVsb2Agb3BlcmF0aW9uIGZvciBuZWdhdGl2ZSBudW1iZXJzLlxuICAgICAgICAgICAgICAgICAgdGltZSA9ICh2YWx1ZSAlIDg2NGU1ICsgODY0ZTUpICUgODY0ZTU7XG4gICAgICAgICAgICAgICAgICAvLyBUaGUgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMsIGFuZCBtaWxsaXNlY29uZHMgYXJlIG9idGFpbmVkIGJ5XG4gICAgICAgICAgICAgICAgICAvLyBkZWNvbXBvc2luZyB0aGUgdGltZSB3aXRoaW4gdGhlIGRheS4gU2VlIHNlY3Rpb24gMTUuOS4xLjEwLlxuICAgICAgICAgICAgICAgICAgaG91cnMgPSBmbG9vcih0aW1lIC8gMzZlNSkgJSAyNDtcbiAgICAgICAgICAgICAgICAgIG1pbnV0ZXMgPSBmbG9vcih0aW1lIC8gNmU0KSAlIDYwO1xuICAgICAgICAgICAgICAgICAgc2Vjb25kcyA9IGZsb29yKHRpbWUgLyAxZTMpICUgNjA7XG4gICAgICAgICAgICAgICAgICBtaWxsaXNlY29uZHMgPSB0aW1lICUgMWUzO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB5ZWFyID0gdmFsdWUuZ2V0VVRDRnVsbFllYXIoKTtcbiAgICAgICAgICAgICAgICAgIG1vbnRoID0gdmFsdWUuZ2V0VVRDTW9udGgoKTtcbiAgICAgICAgICAgICAgICAgIGRhdGUgPSB2YWx1ZS5nZXRVVENEYXRlKCk7XG4gICAgICAgICAgICAgICAgICBob3VycyA9IHZhbHVlLmdldFVUQ0hvdXJzKCk7XG4gICAgICAgICAgICAgICAgICBtaW51dGVzID0gdmFsdWUuZ2V0VVRDTWludXRlcygpO1xuICAgICAgICAgICAgICAgICAgc2Vjb25kcyA9IHZhbHVlLmdldFVUQ1NlY29uZHMoKTtcbiAgICAgICAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IHZhbHVlLmdldFVUQ01pbGxpc2Vjb25kcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBTZXJpYWxpemUgZXh0ZW5kZWQgeWVhcnMgY29ycmVjdGx5LlxuICAgICAgICAgICAgICAgIHZhbHVlID0gKHllYXIgPD0gMCB8fCB5ZWFyID49IDFlNCA/ICh5ZWFyIDwgMCA/IFwiLVwiIDogXCIrXCIpICsgdG9QYWRkZWRTdHJpbmcoNiwgeWVhciA8IDAgPyAteWVhciA6IHllYXIpIDogdG9QYWRkZWRTdHJpbmcoNCwgeWVhcikpICtcbiAgICAgICAgICAgICAgICAgIFwiLVwiICsgdG9QYWRkZWRTdHJpbmcoMiwgbW9udGggKyAxKSArIFwiLVwiICsgdG9QYWRkZWRTdHJpbmcoMiwgZGF0ZSkgK1xuICAgICAgICAgICAgICAgICAgLy8gTW9udGhzLCBkYXRlcywgaG91cnMsIG1pbnV0ZXMsIGFuZCBzZWNvbmRzIHNob3VsZCBoYXZlIHR3b1xuICAgICAgICAgICAgICAgICAgLy8gZGlnaXRzOyBtaWxsaXNlY29uZHMgc2hvdWxkIGhhdmUgdGhyZWUuXG4gICAgICAgICAgICAgICAgICBcIlRcIiArIHRvUGFkZGVkU3RyaW5nKDIsIGhvdXJzKSArIFwiOlwiICsgdG9QYWRkZWRTdHJpbmcoMiwgbWludXRlcykgKyBcIjpcIiArIHRvUGFkZGVkU3RyaW5nKDIsIHNlY29uZHMpICtcbiAgICAgICAgICAgICAgICAgIC8vIE1pbGxpc2Vjb25kcyBhcmUgb3B0aW9uYWwgaW4gRVMgNS4wLCBidXQgcmVxdWlyZWQgaW4gNS4xLlxuICAgICAgICAgICAgICAgICAgXCIuXCIgKyB0b1BhZGRlZFN0cmluZygzLCBtaWxsaXNlY29uZHMpICsgXCJaXCI7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZS50b0pTT04gPT0gXCJmdW5jdGlvblwiICYmICgoY2xhc3NOYW1lICE9IG51bWJlckNsYXNzICYmIGNsYXNzTmFtZSAhPSBzdHJpbmdDbGFzcyAmJiBjbGFzc05hbWUgIT0gYXJyYXlDbGFzcykgfHwgaXNQcm9wZXJ0eS5jYWxsKHZhbHVlLCBcInRvSlNPTlwiKSkpIHtcbiAgICAgICAgICAgICAgLy8gUHJvdG90eXBlIDw9IDEuNi4xIGFkZHMgbm9uLXN0YW5kYXJkIGB0b0pTT05gIG1ldGhvZHMgdG8gdGhlXG4gICAgICAgICAgICAgIC8vIGBOdW1iZXJgLCBgU3RyaW5nYCwgYERhdGVgLCBhbmQgYEFycmF5YCBwcm90b3R5cGVzLiBKU09OIDNcbiAgICAgICAgICAgICAgLy8gaWdub3JlcyBhbGwgYHRvSlNPTmAgbWV0aG9kcyBvbiB0aGVzZSBvYmplY3RzIHVubGVzcyB0aGV5IGFyZVxuICAgICAgICAgICAgICAvLyBkZWZpbmVkIGRpcmVjdGx5IG9uIGFuIGluc3RhbmNlLlxuICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvSlNPTihwcm9wZXJ0eSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgLy8gSWYgYSByZXBsYWNlbWVudCBmdW5jdGlvbiB3YXMgcHJvdmlkZWQsIGNhbGwgaXQgdG8gb2J0YWluIHRoZSB2YWx1ZVxuICAgICAgICAgICAgLy8gZm9yIHNlcmlhbGl6YXRpb24uXG4gICAgICAgICAgICB2YWx1ZSA9IGNhbGxiYWNrLmNhbGwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBib29sZWFuQ2xhc3MpIHtcbiAgICAgICAgICAgIC8vIEJvb2xlYW5zIGFyZSByZXByZXNlbnRlZCBsaXRlcmFsbHkuXG4gICAgICAgICAgICByZXR1cm4gXCJcIiArIHZhbHVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IG51bWJlckNsYXNzKSB7XG4gICAgICAgICAgICAvLyBKU09OIG51bWJlcnMgbXVzdCBiZSBmaW5pdGUuIGBJbmZpbml0eWAgYW5kIGBOYU5gIGFyZSBzZXJpYWxpemVkIGFzXG4gICAgICAgICAgICAvLyBgXCJudWxsXCJgLlxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlID4gLTEgLyAwICYmIHZhbHVlIDwgMSAvIDAgPyBcIlwiICsgdmFsdWUgOiBcIm51bGxcIjtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTmFtZSA9PSBzdHJpbmdDbGFzcykge1xuICAgICAgICAgICAgLy8gU3RyaW5ncyBhcmUgZG91YmxlLXF1b3RlZCBhbmQgZXNjYXBlZC5cbiAgICAgICAgICAgIHJldHVybiBxdW90ZShcIlwiICsgdmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXJpYWxpemUgb2JqZWN0cyBhbmQgYXJyYXlzLlxuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGN5Y2xpYyBzdHJ1Y3R1cmVzLiBUaGlzIGlzIGEgbGluZWFyIHNlYXJjaDsgcGVyZm9ybWFuY2VcbiAgICAgICAgICAgIC8vIGlzIGludmVyc2VseSBwcm9wb3J0aW9uYWwgdG8gdGhlIG51bWJlciBvZiB1bmlxdWUgbmVzdGVkIG9iamVjdHMuXG4gICAgICAgICAgICBmb3IgKGxlbmd0aCA9IHN0YWNrLmxlbmd0aDsgbGVuZ3RoLS07KSB7XG4gICAgICAgICAgICAgIGlmIChzdGFja1tsZW5ndGhdID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEN5Y2xpYyBzdHJ1Y3R1cmVzIGNhbm5vdCBiZSBzZXJpYWxpemVkIGJ5IGBKU09OLnN0cmluZ2lmeWAuXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEFkZCB0aGUgb2JqZWN0IHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICAgICAgICAgIHN0YWNrLnB1c2godmFsdWUpO1xuICAgICAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgLy8gU2F2ZSB0aGUgY3VycmVudCBpbmRlbnRhdGlvbiBsZXZlbCBhbmQgaW5kZW50IG9uZSBhZGRpdGlvbmFsIGxldmVsLlxuICAgICAgICAgICAgcHJlZml4ID0gaW5kZW50YXRpb247XG4gICAgICAgICAgICBpbmRlbnRhdGlvbiArPSB3aGl0ZXNwYWNlO1xuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBhcnJheUNsYXNzKSB7XG4gICAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZSBhcnJheSBlbGVtZW50cy5cbiAgICAgICAgICAgICAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IHZhbHVlLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50ID0gc2VyaWFsaXplKGluZGV4LCB2YWx1ZSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIHdoaXRlc3BhY2UsIGluZGVudGF0aW9uLCBzdGFjayk7XG4gICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGVsZW1lbnQgPT09IHVuZGVmID8gXCJudWxsXCIgOiBlbGVtZW50KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHRzLmxlbmd0aCA/ICh3aGl0ZXNwYWNlID8gXCJbXFxuXCIgKyBpbmRlbnRhdGlvbiArIHJlc3VsdHMuam9pbihcIixcXG5cIiArIGluZGVudGF0aW9uKSArIFwiXFxuXCIgKyBwcmVmaXggKyBcIl1cIiA6IChcIltcIiArIHJlc3VsdHMuam9pbihcIixcIikgKyBcIl1cIikpIDogXCJbXVwiO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gUmVjdXJzaXZlbHkgc2VyaWFsaXplIG9iamVjdCBtZW1iZXJzLiBNZW1iZXJzIGFyZSBzZWxlY3RlZCBmcm9tXG4gICAgICAgICAgICAgIC8vIGVpdGhlciBhIHVzZXItc3BlY2lmaWVkIGxpc3Qgb2YgcHJvcGVydHkgbmFtZXMsIG9yIHRoZSBvYmplY3RcbiAgICAgICAgICAgICAgLy8gaXRzZWxmLlxuICAgICAgICAgICAgICBmb3JFYWNoKHByb3BlcnRpZXMgfHwgdmFsdWUsIGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gc2VyaWFsaXplKHByb3BlcnR5LCB2YWx1ZSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIHdoaXRlc3BhY2UsIGluZGVudGF0aW9uLCBzdGFjayk7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgIT09IHVuZGVmKSB7XG4gICAgICAgICAgICAgICAgICAvLyBBY2NvcmRpbmcgdG8gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMzogXCJJZiBgZ2FwYCB7d2hpdGVzcGFjZX1cbiAgICAgICAgICAgICAgICAgIC8vIGlzIG5vdCB0aGUgZW1wdHkgc3RyaW5nLCBsZXQgYG1lbWJlcmAge3F1b3RlKHByb3BlcnR5KSArIFwiOlwifVxuICAgICAgICAgICAgICAgICAgLy8gYmUgdGhlIGNvbmNhdGVuYXRpb24gb2YgYG1lbWJlcmAgYW5kIHRoZSBgc3BhY2VgIGNoYXJhY3Rlci5cIlxuICAgICAgICAgICAgICAgICAgLy8gVGhlIFwiYHNwYWNlYCBjaGFyYWN0ZXJcIiByZWZlcnMgdG8gdGhlIGxpdGVyYWwgc3BhY2VcbiAgICAgICAgICAgICAgICAgIC8vIGNoYXJhY3Rlciwgbm90IHRoZSBgc3BhY2VgIHt3aWR0aH0gYXJndW1lbnQgcHJvdmlkZWQgdG9cbiAgICAgICAgICAgICAgICAgIC8vIGBKU09OLnN0cmluZ2lmeWAuXG4gICAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2gocXVvdGUocHJvcGVydHkpICsgXCI6XCIgKyAod2hpdGVzcGFjZSA/IFwiIFwiIDogXCJcIikgKyBlbGVtZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHRzLmxlbmd0aCA/ICh3aGl0ZXNwYWNlID8gXCJ7XFxuXCIgKyBpbmRlbnRhdGlvbiArIHJlc3VsdHMuam9pbihcIixcXG5cIiArIGluZGVudGF0aW9uKSArIFwiXFxuXCIgKyBwcmVmaXggKyBcIn1cIiA6IChcIntcIiArIHJlc3VsdHMuam9pbihcIixcIikgKyBcIn1cIikpIDogXCJ7fVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBvYmplY3QgZnJvbSB0aGUgdHJhdmVyc2VkIG9iamVjdCBzdGFjay5cbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUHVibGljOiBgSlNPTi5zdHJpbmdpZnlgLiBTZWUgRVMgNS4xIHNlY3Rpb24gMTUuMTIuMy5cbiAgICAgICAgZXhwb3J0cy5zdHJpbmdpZnkgPSBmdW5jdGlvbiAoc291cmNlLCBmaWx0ZXIsIHdpZHRoKSB7XG4gICAgICAgICAgdmFyIHdoaXRlc3BhY2UsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCBjbGFzc05hbWU7XG4gICAgICAgICAgaWYgKHR5cGVvZiBmaWx0ZXIgPT0gXCJmdW5jdGlvblwiIHx8IHR5cGVvZiBmaWx0ZXIgPT0gXCJvYmplY3RcIiAmJiBmaWx0ZXIpIHtcbiAgICAgICAgICAgIGlmICgoY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbChmaWx0ZXIpKSA9PSBmdW5jdGlvbkNsYXNzKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrID0gZmlsdGVyO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gYXJyYXlDbGFzcykge1xuICAgICAgICAgICAgICAvLyBDb252ZXJ0IHRoZSBwcm9wZXJ0eSBuYW1lcyBhcnJheSBpbnRvIGEgbWFrZXNoaWZ0IHNldC5cbiAgICAgICAgICAgICAgcHJvcGVydGllcyA9IHt9O1xuICAgICAgICAgICAgICBmb3IgKHZhciBpbmRleCA9IDAsIGxlbmd0aCA9IGZpbHRlci5sZW5ndGgsIHZhbHVlOyBpbmRleCA8IGxlbmd0aDsgdmFsdWUgPSBmaWx0ZXJbaW5kZXgrK10sICgoY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbCh2YWx1ZSkpLCBjbGFzc05hbWUgPT0gc3RyaW5nQ2xhc3MgfHwgY2xhc3NOYW1lID09IG51bWJlckNsYXNzKSAmJiAocHJvcGVydGllc1t2YWx1ZV0gPSAxKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh3aWR0aCkge1xuICAgICAgICAgICAgaWYgKChjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKHdpZHRoKSkgPT0gbnVtYmVyQ2xhc3MpIHtcbiAgICAgICAgICAgICAgLy8gQ29udmVydCB0aGUgYHdpZHRoYCB0byBhbiBpbnRlZ2VyIGFuZCBjcmVhdGUgYSBzdHJpbmcgY29udGFpbmluZ1xuICAgICAgICAgICAgICAvLyBgd2lkdGhgIG51bWJlciBvZiBzcGFjZSBjaGFyYWN0ZXJzLlxuICAgICAgICAgICAgICBpZiAoKHdpZHRoIC09IHdpZHRoICUgMSkgPiAwKSB7XG4gICAgICAgICAgICAgICAgZm9yICh3aGl0ZXNwYWNlID0gXCJcIiwgd2lkdGggPiAxMCAmJiAod2lkdGggPSAxMCk7IHdoaXRlc3BhY2UubGVuZ3RoIDwgd2lkdGg7IHdoaXRlc3BhY2UgKz0gXCIgXCIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTmFtZSA9PSBzdHJpbmdDbGFzcykge1xuICAgICAgICAgICAgICB3aGl0ZXNwYWNlID0gd2lkdGgubGVuZ3RoIDw9IDEwID8gd2lkdGggOiB3aWR0aC5zbGljZSgwLCAxMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIE9wZXJhIDw9IDcuNTR1MiBkaXNjYXJkcyB0aGUgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBlbXB0eSBzdHJpbmcga2V5c1xuICAgICAgICAgIC8vIChgXCJcImApIG9ubHkgaWYgdGhleSBhcmUgdXNlZCBkaXJlY3RseSB3aXRoaW4gYW4gb2JqZWN0IG1lbWJlciBsaXN0XG4gICAgICAgICAgLy8gKGUuZy4sIGAhKFwiXCIgaW4geyBcIlwiOiAxfSlgKS5cbiAgICAgICAgICByZXR1cm4gc2VyaWFsaXplKFwiXCIsICh2YWx1ZSA9IHt9LCB2YWx1ZVtcIlwiXSA9IHNvdXJjZSwgdmFsdWUpLCBjYWxsYmFjaywgcHJvcGVydGllcywgd2hpdGVzcGFjZSwgXCJcIiwgW10pO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBQdWJsaWM6IFBhcnNlcyBhIEpTT04gc291cmNlIHN0cmluZy5cbiAgICAgIGlmICghaGFzKFwianNvbi1wYXJzZVwiKSkge1xuICAgICAgICB2YXIgZnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogQSBtYXAgb2YgZXNjYXBlZCBjb250cm9sIGNoYXJhY3RlcnMgYW5kIHRoZWlyIHVuZXNjYXBlZFxuICAgICAgICAvLyBlcXVpdmFsZW50cy5cbiAgICAgICAgdmFyIFVuZXNjYXBlcyA9IHtcbiAgICAgICAgICA5MjogXCJcXFxcXCIsXG4gICAgICAgICAgMzQ6ICdcIicsXG4gICAgICAgICAgNDc6IFwiL1wiLFxuICAgICAgICAgIDk4OiBcIlxcYlwiLFxuICAgICAgICAgIDExNjogXCJcXHRcIixcbiAgICAgICAgICAxMTA6IFwiXFxuXCIsXG4gICAgICAgICAgMTAyOiBcIlxcZlwiLFxuICAgICAgICAgIDExNDogXCJcXHJcIlxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBTdG9yZXMgdGhlIHBhcnNlciBzdGF0ZS5cbiAgICAgICAgdmFyIEluZGV4LCBTb3VyY2U7XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFJlc2V0cyB0aGUgcGFyc2VyIHN0YXRlIGFuZCB0aHJvd3MgYSBgU3ludGF4RXJyb3JgLlxuICAgICAgICB2YXIgYWJvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgSW5kZXggPSBTb3VyY2UgPSBudWxsO1xuICAgICAgICAgIHRocm93IFN5bnRheEVycm9yKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFJldHVybnMgdGhlIG5leHQgdG9rZW4sIG9yIGBcIiRcImAgaWYgdGhlIHBhcnNlciBoYXMgcmVhY2hlZFxuICAgICAgICAvLyB0aGUgZW5kIG9mIHRoZSBzb3VyY2Ugc3RyaW5nLiBBIHRva2VuIG1heSBiZSBhIHN0cmluZywgbnVtYmVyLCBgbnVsbGBcbiAgICAgICAgLy8gbGl0ZXJhbCwgb3IgQm9vbGVhbiBsaXRlcmFsLlxuICAgICAgICB2YXIgbGV4ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBzb3VyY2UgPSBTb3VyY2UsIGxlbmd0aCA9IHNvdXJjZS5sZW5ndGgsIHZhbHVlLCBiZWdpbiwgcG9zaXRpb24sIGlzU2lnbmVkLCBjaGFyQ29kZTtcbiAgICAgICAgICB3aGlsZSAoSW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpO1xuICAgICAgICAgICAgc3dpdGNoIChjaGFyQ29kZSkge1xuICAgICAgICAgICAgICBjYXNlIDk6IGNhc2UgMTA6IGNhc2UgMTM6IGNhc2UgMzI6XG4gICAgICAgICAgICAgICAgLy8gU2tpcCB3aGl0ZXNwYWNlIHRva2VucywgaW5jbHVkaW5nIHRhYnMsIGNhcnJpYWdlIHJldHVybnMsIGxpbmVcbiAgICAgICAgICAgICAgICAvLyBmZWVkcywgYW5kIHNwYWNlIGNoYXJhY3RlcnMuXG4gICAgICAgICAgICAgICAgSW5kZXgrKztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAxMjM6IGNhc2UgMTI1OiBjYXNlIDkxOiBjYXNlIDkzOiBjYXNlIDU4OiBjYXNlIDQ0OlxuICAgICAgICAgICAgICAgIC8vIFBhcnNlIGEgcHVuY3R1YXRvciB0b2tlbiAoYHtgLCBgfWAsIGBbYCwgYF1gLCBgOmAsIG9yIGAsYCkgYXRcbiAgICAgICAgICAgICAgICAvLyB0aGUgY3VycmVudCBwb3NpdGlvbi5cbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGNoYXJJbmRleEJ1Z2d5ID8gc291cmNlLmNoYXJBdChJbmRleCkgOiBzb3VyY2VbSW5kZXhdO1xuICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICBjYXNlIDM0OlxuICAgICAgICAgICAgICAgIC8vIGBcImAgZGVsaW1pdHMgYSBKU09OIHN0cmluZzsgYWR2YW5jZSB0byB0aGUgbmV4dCBjaGFyYWN0ZXIgYW5kXG4gICAgICAgICAgICAgICAgLy8gYmVnaW4gcGFyc2luZyB0aGUgc3RyaW5nLiBTdHJpbmcgdG9rZW5zIGFyZSBwcmVmaXhlZCB3aXRoIHRoZVxuICAgICAgICAgICAgICAgIC8vIHNlbnRpbmVsIGBAYCBjaGFyYWN0ZXIgdG8gZGlzdGluZ3Vpc2ggdGhlbSBmcm9tIHB1bmN0dWF0b3JzIGFuZFxuICAgICAgICAgICAgICAgIC8vIGVuZC1vZi1zdHJpbmcgdG9rZW5zLlxuICAgICAgICAgICAgICAgIGZvciAodmFsdWUgPSBcIkBcIiwgSW5kZXgrKzsgSW5kZXggPCBsZW5ndGg7KSB7XG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA8IDMyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFVuZXNjYXBlZCBBU0NJSSBjb250cm9sIGNoYXJhY3RlcnMgKHRob3NlIHdpdGggYSBjb2RlIHVuaXRcbiAgICAgICAgICAgICAgICAgICAgLy8gbGVzcyB0aGFuIHRoZSBzcGFjZSBjaGFyYWN0ZXIpIGFyZSBub3QgcGVybWl0dGVkLlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGFyQ29kZSA9PSA5Mikge1xuICAgICAgICAgICAgICAgICAgICAvLyBBIHJldmVyc2Ugc29saWR1cyAoYFxcYCkgbWFya3MgdGhlIGJlZ2lubmluZyBvZiBhbiBlc2NhcGVkXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnRyb2wgY2hhcmFjdGVyIChpbmNsdWRpbmcgYFwiYCwgYFxcYCwgYW5kIGAvYCkgb3IgVW5pY29kZVxuICAgICAgICAgICAgICAgICAgICAvLyBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoY2hhckNvZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjYXNlIDkyOiBjYXNlIDM0OiBjYXNlIDQ3OiBjYXNlIDk4OiBjYXNlIDExNjogY2FzZSAxMTA6IGNhc2UgMTAyOiBjYXNlIDExNDpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldml2ZSBlc2NhcGVkIGNvbnRyb2wgY2hhcmFjdGVycy5cbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlICs9IFVuZXNjYXBlc1tjaGFyQ29kZV07XG4gICAgICAgICAgICAgICAgICAgICAgICBJbmRleCsrO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMTc6XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBgXFx1YCBtYXJrcyB0aGUgYmVnaW5uaW5nIG9mIGEgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBZHZhbmNlIHRvIHRoZSBmaXJzdCBjaGFyYWN0ZXIgYW5kIHZhbGlkYXRlIHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm91ci1kaWdpdCBjb2RlIHBvaW50LlxuICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW4gPSArK0luZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwb3NpdGlvbiA9IEluZGV4ICsgNDsgSW5kZXggPCBwb3NpdGlvbjsgSW5kZXgrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSB2YWxpZCBzZXF1ZW5jZSBjb21wcmlzZXMgZm91ciBoZXhkaWdpdHMgKGNhc2UtXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluc2Vuc2l0aXZlKSB0aGF0IGZvcm0gYSBzaW5nbGUgaGV4YWRlY2ltYWwgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3IHx8IGNoYXJDb2RlID49IDk3ICYmIGNoYXJDb2RlIDw9IDEwMiB8fCBjaGFyQ29kZSA+PSA2NSAmJiBjaGFyQ29kZSA8PSA3MCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnZhbGlkIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldml2ZSB0aGUgZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSArPSBmcm9tQ2hhckNvZGUoXCIweFwiICsgc291cmNlLnNsaWNlKGJlZ2luLCBJbmRleCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEludmFsaWQgZXNjYXBlIHNlcXVlbmNlLlxuICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDM0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gQW4gdW5lc2NhcGVkIGRvdWJsZS1xdW90ZSBjaGFyYWN0ZXIgbWFya3MgdGhlIGVuZCBvZiB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAvLyBzdHJpbmcuXG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIGJlZ2luID0gSW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIC8vIE9wdGltaXplIGZvciB0aGUgY29tbW9uIGNhc2Ugd2hlcmUgYSBzdHJpbmcgaXMgdmFsaWQuXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaGFyQ29kZSA+PSAzMiAmJiBjaGFyQ29kZSAhPSA5MiAmJiBjaGFyQ29kZSAhPSAzNCkge1xuICAgICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gQXBwZW5kIHRoZSBzdHJpbmcgYXMtaXMuXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlICs9IHNvdXJjZS5zbGljZShiZWdpbiwgSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpID09IDM0KSB7XG4gICAgICAgICAgICAgICAgICAvLyBBZHZhbmNlIHRvIHRoZSBuZXh0IGNoYXJhY3RlciBhbmQgcmV0dXJuIHRoZSByZXZpdmVkIHN0cmluZy5cbiAgICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFVudGVybWluYXRlZCBzdHJpbmcuXG4gICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAvLyBQYXJzZSBudW1iZXJzIGFuZCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBiZWdpbiA9IEluZGV4O1xuICAgICAgICAgICAgICAgIC8vIEFkdmFuY2UgcGFzdCB0aGUgbmVnYXRpdmUgc2lnbiwgaWYgb25lIGlzIHNwZWNpZmllZC5cbiAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gNDUpIHtcbiAgICAgICAgICAgICAgICAgIGlzU2lnbmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFBhcnNlIGFuIGludGVnZXIgb3IgZmxvYXRpbmctcG9pbnQgdmFsdWUuXG4gICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KSB7XG4gICAgICAgICAgICAgICAgICAvLyBMZWFkaW5nIHplcm9lcyBhcmUgaW50ZXJwcmV0ZWQgYXMgb2N0YWwgbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gNDggJiYgKChjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4ICsgMSkpLCBjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1NykpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWxsZWdhbCBvY3RhbCBsaXRlcmFsLlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgaXNTaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBpbnRlZ2VyIGNvbXBvbmVudC5cbiAgICAgICAgICAgICAgICAgIGZvciAoOyBJbmRleCA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBJbmRleCsrKTtcbiAgICAgICAgICAgICAgICAgIC8vIEZsb2F0cyBjYW5ub3QgY29udGFpbiBhIGxlYWRpbmcgZGVjaW1hbCBwb2ludDsgaG93ZXZlciwgdGhpc1xuICAgICAgICAgICAgICAgICAgLy8gY2FzZSBpcyBhbHJlYWR5IGFjY291bnRlZCBmb3IgYnkgdGhlIHBhcnNlci5cbiAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuY2hhckNvZGVBdChJbmRleCkgPT0gNDYpIHtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSArK0luZGV4O1xuICAgICAgICAgICAgICAgICAgICAvLyBQYXJzZSB0aGUgZGVjaW1hbCBjb21wb25lbnQuXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBwb3NpdGlvbiA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQocG9zaXRpb24pKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBwb3NpdGlvbisrKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gSWxsZWdhbCB0cmFpbGluZyBkZWNpbWFsLlxuICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgSW5kZXggPSBwb3NpdGlvbjtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIGV4cG9uZW50cy4gVGhlIGBlYCBkZW5vdGluZyB0aGUgZXhwb25lbnQgaXNcbiAgICAgICAgICAgICAgICAgIC8vIGNhc2UtaW5zZW5zaXRpdmUuXG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSAxMDEgfHwgY2hhckNvZGUgPT0gNjkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdCgrK0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2tpcCBwYXN0IHRoZSBzaWduIGZvbGxvd2luZyB0aGUgZXhwb25lbnQsIGlmIG9uZSBpc1xuICAgICAgICAgICAgICAgICAgICAvLyBzcGVjaWZpZWQuXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSA0MyB8fCBjaGFyQ29kZSA9PSA0NSkge1xuICAgICAgICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgdGhlIGV4cG9uZW50aWFsIGNvbXBvbmVudC5cbiAgICAgICAgICAgICAgICAgICAgZm9yIChwb3NpdGlvbiA9IEluZGV4OyBwb3NpdGlvbiA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQocG9zaXRpb24pKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBwb3NpdGlvbisrKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gSWxsZWdhbCBlbXB0eSBleHBvbmVudC5cbiAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEluZGV4ID0gcG9zaXRpb247XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAvLyBDb2VyY2UgdGhlIHBhcnNlZCB2YWx1ZSB0byBhIEphdmFTY3JpcHQgbnVtYmVyLlxuICAgICAgICAgICAgICAgICAgcmV0dXJuICtzb3VyY2Uuc2xpY2UoYmVnaW4sIEluZGV4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gQSBuZWdhdGl2ZSBzaWduIG1heSBvbmx5IHByZWNlZGUgbnVtYmVycy5cbiAgICAgICAgICAgICAgICBpZiAoaXNTaWduZWQpIHtcbiAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIGB0cnVlYCwgYGZhbHNlYCwgYW5kIGBudWxsYCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09IFwidHJ1ZVwiKSB7XG4gICAgICAgICAgICAgICAgICBJbmRleCArPSA0O1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2Uuc2xpY2UoSW5kZXgsIEluZGV4ICsgNSkgPT0gXCJmYWxzZVwiKSB7XG4gICAgICAgICAgICAgICAgICBJbmRleCArPSA1O1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09IFwibnVsbFwiKSB7XG4gICAgICAgICAgICAgICAgICBJbmRleCArPSA0O1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFVucmVjb2duaXplZCB0b2tlbi5cbiAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBSZXR1cm4gdGhlIHNlbnRpbmVsIGAkYCBjaGFyYWN0ZXIgaWYgdGhlIHBhcnNlciBoYXMgcmVhY2hlZCB0aGUgZW5kXG4gICAgICAgICAgLy8gb2YgdGhlIHNvdXJjZSBzdHJpbmcuXG4gICAgICAgICAgcmV0dXJuIFwiJFwiO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBQYXJzZXMgYSBKU09OIGB2YWx1ZWAgdG9rZW4uXG4gICAgICAgIHZhciBnZXQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICB2YXIgcmVzdWx0cywgaGFzTWVtYmVycztcbiAgICAgICAgICBpZiAodmFsdWUgPT0gXCIkXCIpIHtcbiAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgZW5kIG9mIGlucHV0LlxuICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBpZiAoKGNoYXJJbmRleEJ1Z2d5ID8gdmFsdWUuY2hhckF0KDApIDogdmFsdWVbMF0pID09IFwiQFwiKSB7XG4gICAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgc2VudGluZWwgYEBgIGNoYXJhY3Rlci5cbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnNsaWNlKDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gUGFyc2Ugb2JqZWN0IGFuZCBhcnJheSBsaXRlcmFscy5cbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIltcIikge1xuICAgICAgICAgICAgICAvLyBQYXJzZXMgYSBKU09OIGFycmF5LCByZXR1cm5pbmcgYSBuZXcgSmF2YVNjcmlwdCBhcnJheS5cbiAgICAgICAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgICBmb3IgKDs7IGhhc01lbWJlcnMgfHwgKGhhc01lbWJlcnMgPSB0cnVlKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gbGV4KCk7XG4gICAgICAgICAgICAgICAgLy8gQSBjbG9zaW5nIHNxdWFyZSBicmFja2V0IG1hcmtzIHRoZSBlbmQgb2YgdGhlIGFycmF5IGxpdGVyYWwuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiXVwiKSB7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGFycmF5IGxpdGVyYWwgY29udGFpbnMgZWxlbWVudHMsIHRoZSBjdXJyZW50IHRva2VuXG4gICAgICAgICAgICAgICAgLy8gc2hvdWxkIGJlIGEgY29tbWEgc2VwYXJhdGluZyB0aGUgcHJldmlvdXMgZWxlbWVudCBmcm9tIHRoZVxuICAgICAgICAgICAgICAgIC8vIG5leHQuXG4gICAgICAgICAgICAgICAgaWYgKGhhc01lbWJlcnMpIHtcbiAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIixcIikge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJdXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBVbmV4cGVjdGVkIHRyYWlsaW5nIGAsYCBpbiBhcnJheSBsaXRlcmFsLlxuICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEEgYCxgIG11c3Qgc2VwYXJhdGUgZWFjaCBhcnJheSBlbGVtZW50LlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBFbGlzaW9ucyBhbmQgbGVhZGluZyBjb21tYXMgYXJlIG5vdCBwZXJtaXR0ZWQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiKSB7XG4gICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goZ2V0KHZhbHVlKSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID09IFwie1wiKSB7XG4gICAgICAgICAgICAgIC8vIFBhcnNlcyBhIEpTT04gb2JqZWN0LCByZXR1cm5pbmcgYSBuZXcgSmF2YVNjcmlwdCBvYmplY3QuXG4gICAgICAgICAgICAgIHJlc3VsdHMgPSB7fTtcbiAgICAgICAgICAgICAgZm9yICg7OyBoYXNNZW1iZXJzIHx8IChoYXNNZW1iZXJzID0gdHJ1ZSkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgIC8vIEEgY2xvc2luZyBjdXJseSBicmFjZSBtYXJrcyB0aGUgZW5kIG9mIHRoZSBvYmplY3QgbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJ9XCIpIHtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgb2JqZWN0IGxpdGVyYWwgY29udGFpbnMgbWVtYmVycywgdGhlIGN1cnJlbnQgdG9rZW5cbiAgICAgICAgICAgICAgICAvLyBzaG91bGQgYmUgYSBjb21tYSBzZXBhcmF0b3IuXG4gICAgICAgICAgICAgICAgaWYgKGhhc01lbWJlcnMpIHtcbiAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIixcIikge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJ9XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBVbmV4cGVjdGVkIHRyYWlsaW5nIGAsYCBpbiBvYmplY3QgbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBBIGAsYCBtdXN0IHNlcGFyYXRlIGVhY2ggb2JqZWN0IG1lbWJlci5cbiAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTGVhZGluZyBjb21tYXMgYXJlIG5vdCBwZXJtaXR0ZWQsIG9iamVjdCBwcm9wZXJ0eSBuYW1lcyBtdXN0IGJlXG4gICAgICAgICAgICAgICAgLy8gZG91YmxlLXF1b3RlZCBzdHJpbmdzLCBhbmQgYSBgOmAgbXVzdCBzZXBhcmF0ZSBlYWNoIHByb3BlcnR5XG4gICAgICAgICAgICAgICAgLy8gbmFtZSBhbmQgdmFsdWUuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiIHx8IHR5cGVvZiB2YWx1ZSAhPSBcInN0cmluZ1wiIHx8IChjaGFySW5kZXhCdWdneSA/IHZhbHVlLmNoYXJBdCgwKSA6IHZhbHVlWzBdKSAhPSBcIkBcIiB8fCBsZXgoKSAhPSBcIjpcIikge1xuICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzdWx0c1t2YWx1ZS5zbGljZSgxKV0gPSBnZXQobGV4KCkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gVW5leHBlY3RlZCB0b2tlbiBlbmNvdW50ZXJlZC5cbiAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogVXBkYXRlcyBhIHRyYXZlcnNlZCBvYmplY3QgbWVtYmVyLlxuICAgICAgICB2YXIgdXBkYXRlID0gZnVuY3Rpb24gKHNvdXJjZSwgcHJvcGVydHksIGNhbGxiYWNrKSB7XG4gICAgICAgICAgdmFyIGVsZW1lbnQgPSB3YWxrKHNvdXJjZSwgcHJvcGVydHksIGNhbGxiYWNrKTtcbiAgICAgICAgICBpZiAoZWxlbWVudCA9PT0gdW5kZWYpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBzb3VyY2VbcHJvcGVydHldO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzb3VyY2VbcHJvcGVydHldID0gZWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFJlY3Vyc2l2ZWx5IHRyYXZlcnNlcyBhIHBhcnNlZCBKU09OIG9iamVjdCwgaW52b2tpbmcgdGhlXG4gICAgICAgIC8vIGBjYWxsYmFja2AgZnVuY3Rpb24gZm9yIGVhY2ggdmFsdWUuIFRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlXG4gICAgICAgIC8vIGBXYWxrKGhvbGRlciwgbmFtZSlgIG9wZXJhdGlvbiBkZWZpbmVkIGluIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjIuXG4gICAgICAgIHZhciB3YWxrID0gZnVuY3Rpb24gKHNvdXJjZSwgcHJvcGVydHksIGNhbGxiYWNrKSB7XG4gICAgICAgICAgdmFyIHZhbHVlID0gc291cmNlW3Byb3BlcnR5XSwgbGVuZ3RoO1xuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIiAmJiB2YWx1ZSkge1xuICAgICAgICAgICAgLy8gYGZvckVhY2hgIGNhbid0IGJlIHVzZWQgdG8gdHJhdmVyc2UgYW4gYXJyYXkgaW4gT3BlcmEgPD0gOC41NFxuICAgICAgICAgICAgLy8gYmVjYXVzZSBpdHMgYE9iamVjdCNoYXNPd25Qcm9wZXJ0eWAgaW1wbGVtZW50YXRpb24gcmV0dXJucyBgZmFsc2VgXG4gICAgICAgICAgICAvLyBmb3IgYXJyYXkgaW5kaWNlcyAoZS5nLiwgYCFbMSwgMiwgM10uaGFzT3duUHJvcGVydHkoXCIwXCIpYCkuXG4gICAgICAgICAgICBpZiAoZ2V0Q2xhc3MuY2FsbCh2YWx1ZSkgPT0gYXJyYXlDbGFzcykge1xuICAgICAgICAgICAgICBmb3IgKGxlbmd0aCA9IHZhbHVlLmxlbmd0aDsgbGVuZ3RoLS07KSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlKHZhbHVlLCBsZW5ndGgsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZm9yRWFjaCh2YWx1ZSwgZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlKHZhbHVlLCBwcm9wZXJ0eSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmNhbGwoc291cmNlLCBwcm9wZXJ0eSwgdmFsdWUpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFB1YmxpYzogYEpTT04ucGFyc2VgLiBTZWUgRVMgNS4xIHNlY3Rpb24gMTUuMTIuMi5cbiAgICAgICAgZXhwb3J0cy5wYXJzZSA9IGZ1bmN0aW9uIChzb3VyY2UsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgdmFyIHJlc3VsdCwgdmFsdWU7XG4gICAgICAgICAgSW5kZXggPSAwO1xuICAgICAgICAgIFNvdXJjZSA9IFwiXCIgKyBzb3VyY2U7XG4gICAgICAgICAgcmVzdWx0ID0gZ2V0KGxleCgpKTtcbiAgICAgICAgICAvLyBJZiBhIEpTT04gc3RyaW5nIGNvbnRhaW5zIG11bHRpcGxlIHRva2VucywgaXQgaXMgaW52YWxpZC5cbiAgICAgICAgICBpZiAobGV4KCkgIT0gXCIkXCIpIHtcbiAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFJlc2V0IHRoZSBwYXJzZXIgc3RhdGUuXG4gICAgICAgICAgSW5kZXggPSBTb3VyY2UgPSBudWxsO1xuICAgICAgICAgIHJldHVybiBjYWxsYmFjayAmJiBnZXRDbGFzcy5jYWxsKGNhbGxiYWNrKSA9PSBmdW5jdGlvbkNsYXNzID8gd2FsaygodmFsdWUgPSB7fSwgdmFsdWVbXCJcIl0gPSByZXN1bHQsIHZhbHVlKSwgXCJcIiwgY2FsbGJhY2spIDogcmVzdWx0O1xuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIGV4cG9ydHNbXCJydW5JbkNvbnRleHRcIl0gPSBydW5JbkNvbnRleHQ7XG4gICAgcmV0dXJuIGV4cG9ydHM7XG4gIH1cblxuICBpZiAodHlwZW9mIGV4cG9ydHMgPT0gXCJvYmplY3RcIiAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmICFpc0xvYWRlcikge1xuICAgIC8vIEV4cG9ydCBmb3IgQ29tbW9uSlMgZW52aXJvbm1lbnRzLlxuICAgIHJ1bkluQ29udGV4dChyb290LCBleHBvcnRzKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBFeHBvcnQgZm9yIHdlYiBicm93c2VycyBhbmQgSmF2YVNjcmlwdCBlbmdpbmVzLlxuICAgIHZhciBuYXRpdmVKU09OID0gcm9vdC5KU09OO1xuICAgIHZhciBKU09OMyA9IHJ1bkluQ29udGV4dChyb290LCAocm9vdFtcIkpTT04zXCJdID0ge1xuICAgICAgLy8gUHVibGljOiBSZXN0b3JlcyB0aGUgb3JpZ2luYWwgdmFsdWUgb2YgdGhlIGdsb2JhbCBgSlNPTmAgb2JqZWN0IGFuZFxuICAgICAgLy8gcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgYEpTT04zYCBvYmplY3QuXG4gICAgICBcIm5vQ29uZmxpY3RcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICByb290LkpTT04gPSBuYXRpdmVKU09OO1xuICAgICAgICByZXR1cm4gSlNPTjM7XG4gICAgICB9XG4gICAgfSkpO1xuXG4gICAgcm9vdC5KU09OID0ge1xuICAgICAgXCJwYXJzZVwiOiBKU09OMy5wYXJzZSxcbiAgICAgIFwic3RyaW5naWZ5XCI6IEpTT04zLnN0cmluZ2lmeVxuICAgIH07XG4gIH1cblxuICAvLyBFeHBvcnQgZm9yIGFzeW5jaHJvbm91cyBtb2R1bGUgbG9hZGVycy5cbiAgaWYgKGlzTG9hZGVyKSB7XG4gICAgZGVmaW5lKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBKU09OMztcbiAgICB9KTtcbiAgfVxufSh0aGlzKSk7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG52YXIgaXNGdW5jdGlvbiA9IGZ1bmN0aW9uIChmbikge1xuXHRyZXR1cm4gKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJyAmJiAhKGZuIGluc3RhbmNlb2YgUmVnRXhwKSkgfHwgdG9TdHJpbmcuY2FsbChmbikgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZvckVhY2gob2JqLCBmbikge1xuXHRpZiAoIWlzRnVuY3Rpb24oZm4pKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignaXRlcmF0b3IgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdH1cblx0dmFyIGksIGssXG5cdFx0aXNTdHJpbmcgPSB0eXBlb2Ygb2JqID09PSAnc3RyaW5nJyxcblx0XHRsID0gb2JqLmxlbmd0aCxcblx0XHRjb250ZXh0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgPyBhcmd1bWVudHNbMl0gOiBudWxsO1xuXHRpZiAobCA9PT0gK2wpIHtcblx0XHRmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG5cdFx0XHRpZiAoY29udGV4dCA9PT0gbnVsbCkge1xuXHRcdFx0XHRmbihpc1N0cmluZyA/IG9iai5jaGFyQXQoaSkgOiBvYmpbaV0sIGksIG9iaik7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmbi5jYWxsKGNvbnRleHQsIGlzU3RyaW5nID8gb2JqLmNoYXJBdChpKSA6IG9ialtpXSwgaSwgb2JqKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0Zm9yIChrIGluIG9iaikge1xuXHRcdFx0aWYgKGhhc093bi5jYWxsKG9iaiwgaykpIHtcblx0XHRcdFx0aWYgKGNvbnRleHQgPT09IG51bGwpIHtcblx0XHRcdFx0XHRmbihvYmpba10sIGssIG9iaik7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Zm4uY2FsbChjb250ZXh0LCBvYmpba10sIGssIG9iaik7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbiIsIlwidXNlIHN0cmljdFwiO1xuXG4vLyBtb2RpZmllZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbVxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksXG5cdHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyxcblx0Zm9yRWFjaCA9IHJlcXVpcmUoJy4vZm9yZWFjaCcpLFxuXHRpc0FyZ3MgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyksXG5cdGhhc0RvbnRFbnVtQnVnID0gISh7J3RvU3RyaW5nJzogbnVsbH0pLnByb3BlcnR5SXNFbnVtZXJhYmxlKCd0b1N0cmluZycpLFxuXHRoYXNQcm90b0VudW1CdWcgPSAoZnVuY3Rpb24gKCkge30pLnByb3BlcnR5SXNFbnVtZXJhYmxlKCdwcm90b3R5cGUnKSxcblx0ZG9udEVudW1zID0gW1xuXHRcdFwidG9TdHJpbmdcIixcblx0XHRcInRvTG9jYWxlU3RyaW5nXCIsXG5cdFx0XCJ2YWx1ZU9mXCIsXG5cdFx0XCJoYXNPd25Qcm9wZXJ0eVwiLFxuXHRcdFwiaXNQcm90b3R5cGVPZlwiLFxuXHRcdFwicHJvcGVydHlJc0VudW1lcmFibGVcIixcblx0XHRcImNvbnN0cnVjdG9yXCJcblx0XTtcblxudmFyIGtleXNTaGltID0gZnVuY3Rpb24ga2V5cyhvYmplY3QpIHtcblx0dmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnLFxuXHRcdGlzRnVuY3Rpb24gPSB0b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG5cdFx0aXNBcmd1bWVudHMgPSBpc0FyZ3Mob2JqZWN0KSxcblx0XHR0aGVLZXlzID0gW107XG5cblx0aWYgKCFpc09iamVjdCAmJiAhaXNGdW5jdGlvbiAmJiAhaXNBcmd1bWVudHMpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0LmtleXMgY2FsbGVkIG9uIGEgbm9uLW9iamVjdFwiKTtcblx0fVxuXG5cdGlmIChpc0FyZ3VtZW50cykge1xuXHRcdGZvckVhY2gob2JqZWN0LCBmdW5jdGlvbiAodmFsdWUsIGluZGV4KSB7XG5cdFx0XHR0aGVLZXlzLnB1c2goaW5kZXgpO1xuXHRcdH0pO1xuXHR9IGVsc2Uge1xuXHRcdHZhciBuYW1lLFxuXHRcdFx0c2tpcFByb3RvID0gaGFzUHJvdG9FbnVtQnVnICYmIGlzRnVuY3Rpb247XG5cblx0XHRmb3IgKG5hbWUgaW4gb2JqZWN0KSB7XG5cdFx0XHRpZiAoIShza2lwUHJvdG8gJiYgbmFtZSA9PT0gJ3Byb3RvdHlwZScpICYmIGhhcy5jYWxsKG9iamVjdCwgbmFtZSkpIHtcblx0XHRcdFx0dGhlS2V5cy5wdXNoKG5hbWUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGlmIChoYXNEb250RW51bUJ1Zykge1xuXHRcdHZhciBjdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuXHRcdFx0c2tpcENvbnN0cnVjdG9yID0gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gb2JqZWN0O1xuXG5cdFx0Zm9yRWFjaChkb250RW51bXMsIGZ1bmN0aW9uIChkb250RW51bSkge1xuXHRcdFx0aWYgKCEoc2tpcENvbnN0cnVjdG9yICYmIGRvbnRFbnVtID09PSAnY29uc3RydWN0b3InKSAmJiBoYXMuY2FsbChvYmplY3QsIGRvbnRFbnVtKSkge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2goZG9udEVudW0pO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cdHJldHVybiB0aGVLZXlzO1xufTtcblxua2V5c1NoaW0uc2hpbSA9IGZ1bmN0aW9uIHNoaW1PYmplY3RLZXlzKCkge1xuXHRpZiAoIU9iamVjdC5rZXlzKSB7XG5cdFx0T2JqZWN0LmtleXMgPSBrZXlzU2hpbTtcblx0fVxuXHRyZXR1cm4gT2JqZWN0LmtleXMgfHwga2V5c1NoaW07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXNTaGltO1xuXG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0FyZ3VtZW50cyh2YWx1ZSkge1xuXHR2YXIgc3RyID0gdG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG5cdHZhciBpc0FyZ3VtZW50cyA9IHN0ciA9PT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG5cdGlmICghaXNBcmd1bWVudHMpIHtcblx0XHRpc0FyZ3VtZW50cyA9IHN0ciAhPT0gJ1tvYmplY3QgQXJyYXldJ1xuXHRcdFx0JiYgdmFsdWUgIT09IG51bGxcblx0XHRcdCYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCdcblx0XHRcdCYmIHR5cGVvZiB2YWx1ZS5sZW5ndGggPT09ICdudW1iZXInXG5cdFx0XHQmJiB2YWx1ZS5sZW5ndGggPj0gMFxuXHRcdFx0JiYgdG9TdHJpbmcuY2FsbCh2YWx1ZS5jYWxsZWUpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXHR9XG5cdHJldHVybiBpc0FyZ3VtZW50cztcbn07XG5cbiIsIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBtYXAgPSByZXF1aXJlKCdhcnJheS1tYXAnKTtcbnZhciBpbmRleE9mID0gcmVxdWlyZSgnaW5kZXhvZicpO1xudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5Jyk7XG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2ZvcmVhY2gnKTtcbnZhciByZWR1Y2UgPSByZXF1aXJlKCdhcnJheS1yZWR1Y2UnKTtcbnZhciBnZXRPYmplY3RLZXlzID0gcmVxdWlyZSgnb2JqZWN0LWtleXMnKTtcbnZhciBKU09OID0gcmVxdWlyZSgnanNvbjMnKTtcblxuLyoqXG4gKiBNYWtlIHN1cmUgYE9iamVjdC5rZXlzYCB3b3JrIGZvciBgdW5kZWZpbmVkYFxuICogdmFsdWVzIHRoYXQgYXJlIHN0aWxsIHRoZXJlLCBsaWtlIGBkb2N1bWVudC5hbGxgLlxuICogaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvcHVibGljLWh0bWwvMjAwOUp1bi8wNTQ2Lmh0bWxcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBvYmplY3RLZXlzKHZhbCl7XG4gIGlmIChPYmplY3Qua2V5cykgcmV0dXJuIE9iamVjdC5rZXlzKHZhbCk7XG4gIHJldHVybiBnZXRPYmplY3RLZXlzKHZhbCk7XG59XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBpbnNwZWN0O1xuXG4vKipcbiAqIEVjaG9zIHRoZSB2YWx1ZSBvZiBhIHZhbHVlLiBUcnlzIHRvIHByaW50IHRoZSB2YWx1ZSBvdXRcbiAqIGluIHRoZSBiZXN0IHdheSBwb3NzaWJsZSBnaXZlbiB0aGUgZGlmZmVyZW50IHR5cGVzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogVGhlIG9iamVjdCB0byBwcmludCBvdXQuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cyBPcHRpb25hbCBvcHRpb25zIG9iamVjdCB0aGF0IGFsdGVycyB0aGUgb3V0cHV0LlxuICogQGxpY2Vuc2UgTUlUICjCqSBKb3llbnQpXG4gKi9cbi8qIGxlZ2FjeTogb2JqLCBzaG93SGlkZGVuLCBkZXB0aCwgY29sb3JzKi9cblxuZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCBvcHRpb25zXG4gIHZhciBjdHggPSB7XG4gICAgc2VlbjogW10sXG4gICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3JcbiAgfTtcbiAgLy8gbGVnYWN5Li4uXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNCkgY3R4LmNvbG9ycyA9IGFyZ3VtZW50c1szXTtcbiAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuICAgIC8vIGxlZ2FjeS4uLlxuICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcbiAgfSBlbHNlIGlmIChvcHRzKSB7XG4gICAgLy8gZ290IGFuIFwib3B0aW9uc1wiIG9iamVjdFxuICAgIF9leHRlbmQoY3R4LCBvcHRzKTtcbiAgfVxuICAvLyBzZXQgZGVmYXVsdCBvcHRpb25zXG4gIGlmIChpc1VuZGVmaW5lZChjdHguc2hvd0hpZGRlbikpIGN0eC5zaG93SGlkZGVuID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguZGVwdGgpKSBjdHguZGVwdGggPSAyO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmNvbG9ycykpIGN0eC5jb2xvcnMgPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jdXN0b21JbnNwZWN0KSkgY3R4LmN1c3RvbUluc3BlY3QgPSB0cnVlO1xuICBpZiAoY3R4LmNvbG9ycykgY3R4LnN0eWxpemUgPSBzdHlsaXplV2l0aENvbG9yO1xuICByZXR1cm4gZm9ybWF0VmFsdWUoY3R4LCBvYmosIGN0eC5kZXB0aCk7XG59XG5cbi8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQU5TSV9lc2NhcGVfY29kZSNncmFwaGljc1xuaW5zcGVjdC5jb2xvcnMgPSB7XG4gICdib2xkJyA6IFsxLCAyMl0sXG4gICdpdGFsaWMnIDogWzMsIDIzXSxcbiAgJ3VuZGVybGluZScgOiBbNCwgMjRdLFxuICAnaW52ZXJzZScgOiBbNywgMjddLFxuICAnd2hpdGUnIDogWzM3LCAzOV0sXG4gICdncmV5JyA6IFs5MCwgMzldLFxuICAnYmxhY2snIDogWzMwLCAzOV0sXG4gICdibHVlJyA6IFszNCwgMzldLFxuICAnY3lhbicgOiBbMzYsIDM5XSxcbiAgJ2dyZWVuJyA6IFszMiwgMzldLFxuICAnbWFnZW50YScgOiBbMzUsIDM5XSxcbiAgJ3JlZCcgOiBbMzEsIDM5XSxcbiAgJ3llbGxvdycgOiBbMzMsIDM5XVxufTtcblxuLy8gRG9uJ3QgdXNlICdibHVlJyBub3QgdmlzaWJsZSBvbiBjbWQuZXhlXG5pbnNwZWN0LnN0eWxlcyA9IHtcbiAgJ3NwZWNpYWwnOiAnY3lhbicsXG4gICdudW1iZXInOiAneWVsbG93JyxcbiAgJ2Jvb2xlYW4nOiAneWVsbG93JyxcbiAgJ3VuZGVmaW5lZCc6ICdncmV5JyxcbiAgJ251bGwnOiAnYm9sZCcsXG4gICdzdHJpbmcnOiAnZ3JlZW4nLFxuICAnZGF0ZSc6ICdtYWdlbnRhJyxcbiAgLy8gXCJuYW1lXCI6IGludGVudGlvbmFsbHkgbm90IHN0eWxpbmdcbiAgJ3JlZ2V4cCc6ICdyZWQnXG59O1xuXG5mdW5jdGlvbiBzdHlsaXplTm9Db2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICByZXR1cm4gc3RyO1xufVxuXG5mdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnYm9vbGVhbic7XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG5cbmZ1bmN0aW9uIHN0eWxpemVXaXRoQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgdmFyIHN0eWxlID0gaW5zcGVjdC5zdHlsZXNbc3R5bGVUeXBlXTtcblxuICBpZiAoc3R5bGUpIHtcbiAgICByZXR1cm4gJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVswXSArICdtJyArIHN0ciArXG4gICAgICAgICAgICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMV0gKyAnbSc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gaXNOdWxsKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsO1xufVxuXG5mdW5jdGlvbiBoYXNPd24ob2JqLCBwcm9wKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKTtcbn1cblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHJlKSAmJiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiBpc09iamVjdChlKSAmJlxuICAgICAgKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBpc09iamVjdChkKSAmJiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG5cbmZ1bmN0aW9uIGFycmF5VG9IYXNoKGFycmF5KSB7XG4gIHZhciBoYXNoID0ge307XG5cbiAgZm9yRWFjaChhcnJheSwgZnVuY3Rpb24odmFsLCBpZHgpIHtcbiAgICBoYXNoW3ZhbF0gPSB0cnVlO1xuICB9KTtcblxuICByZXR1cm4gaGFzaDtcbn1cblxuZnVuY3Rpb24gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cykge1xuICB2YXIgb3V0cHV0ID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgaWYgKGhhc093bih2YWx1ZSwgU3RyaW5nKGkpKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBTdHJpbmcoaSksIHRydWUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0LnB1c2goJycpO1xuICAgIH1cbiAgfVxuICBmb3JFYWNoKGtleXMsIGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5mdW5jdGlvbiBmb3JtYXRFcnJvcih2YWx1ZSkge1xuICByZXR1cm4gJ1snICsgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpICsgJ10nO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKGN0eC5jdXN0b21JbnNwZWN0ICYmXG4gICAgICB2YWx1ZSAmJlxuICAgICAgaXNGdW5jdGlvbih2YWx1ZS5pbnNwZWN0KSAmJlxuICAgICAgLy8gRmlsdGVyIG91dCB0aGUgdXRpbCBtb2R1bGUsIGl0J3MgaW5zcGVjdCBmdW5jdGlvbiBpcyBzcGVjaWFsXG4gICAgICB2YWx1ZS5pbnNwZWN0ICE9PSBpbnNwZWN0ICYmXG4gICAgICAvLyBBbHNvIGZpbHRlciBvdXQgYW55IHByb3RvdHlwZSBvYmplY3RzIHVzaW5nIHRoZSBjaXJjdWxhciBjaGVjay5cbiAgICAgICEodmFsdWUuY29uc3RydWN0b3IgJiYgdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlID09PSB2YWx1ZSkpIHtcbiAgICB2YXIgcmV0ID0gdmFsdWUuaW5zcGVjdChyZWN1cnNlVGltZXMsIGN0eCk7XG4gICAgaWYgKCFpc1N0cmluZyhyZXQpKSB7XG4gICAgICByZXQgPSBmb3JtYXRWYWx1ZShjdHgsIHJldCwgcmVjdXJzZVRpbWVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIC8vIFByaW1pdGl2ZSB0eXBlcyBjYW5ub3QgaGF2ZSBwcm9wZXJ0aWVzXG4gIHZhciBwcmltaXRpdmUgPSBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSk7XG4gIGlmIChwcmltaXRpdmUpIHtcbiAgICByZXR1cm4gcHJpbWl0aXZlO1xuICB9XG5cbiAgLy8gTG9vayB1cCB0aGUga2V5cyBvZiB0aGUgb2JqZWN0LlxuICB2YXIga2V5cyA9IG9iamVjdEtleXModmFsdWUpO1xuICB2YXIgdmlzaWJsZUtleXMgPSBhcnJheVRvSGFzaChrZXlzKTtcblxuICBpZiAoY3R4LnNob3dIaWRkZW4gJiYgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMpIHtcbiAgICBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuICB9XG5cbiAgLy8gSUUgZG9lc24ndCBtYWtlIGVycm9yIGZpZWxkcyBub24tZW51bWVyYWJsZVxuICAvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvZHd3NTJzYnQodj12cy45NCkuYXNweFxuICBpZiAoaXNFcnJvcih2YWx1ZSlcbiAgICAgICYmIChpbmRleE9mKGtleXMsICdtZXNzYWdlJykgPj0gMCB8fCBpbmRleE9mKGtleXMsICdkZXNjcmlwdGlvbicpID49IDApKSB7XG4gICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIC8vIFNvbWUgdHlwZSBvZiBvYmplY3Qgd2l0aG91dCBwcm9wZXJ0aWVzIGNhbiBiZSBzaG9ydGN1dHRlZC5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgICB2YXIgbmFtZSA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbRnVuY3Rpb24nICsgbmFtZSArICddJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9XG4gICAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShEYXRlLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ2RhdGUnKTtcbiAgICB9XG4gICAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBiYXNlID0gJycsIGFycmF5ID0gZmFsc2UsIGJyYWNlcyA9IFsneycsICd9J107XG5cbiAgLy8gTWFrZSBBcnJheSBzYXkgdGhhdCB0aGV5IGFyZSBBcnJheVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBhcnJheSA9IHRydWU7XG4gICAgYnJhY2VzID0gWydbJywgJ10nXTtcbiAgfVxuXG4gIC8vIE1ha2UgZnVuY3Rpb25zIHNheSB0aGF0IHRoZXkgYXJlIGZ1bmN0aW9uc1xuICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICB2YXIgbiA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgIGJhc2UgPSAnIFtGdW5jdGlvbicgKyBuICsgJ10nO1xuICB9XG5cbiAgLy8gTWFrZSBSZWdFeHBzIHNheSB0aGF0IHRoZXkgYXJlIFJlZ0V4cHNcbiAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBkYXRlcyB3aXRoIHByb3BlcnRpZXMgZmlyc3Qgc2F5IHRoZSBkYXRlXG4gIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIERhdGUucHJvdG90eXBlLnRvVVRDU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBlcnJvciB3aXRoIG1lc3NhZ2UgZmlyc3Qgc2F5IHRoZSBlcnJvclxuICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwICYmICghYXJyYXkgfHwgdmFsdWUubGVuZ3RoID09IDApKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyBicmFjZXNbMV07XG4gIH1cblxuICBpZiAocmVjdXJzZVRpbWVzIDwgMCkge1xuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW09iamVjdF0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuXG4gIGN0eC5zZWVuLnB1c2godmFsdWUpO1xuXG4gIHZhciBvdXRwdXQ7XG4gIGlmIChhcnJheSkge1xuICAgIG91dHB1dCA9IGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpO1xuICB9IGVsc2Uge1xuICAgIG91dHB1dCA9IG1hcChrZXlzLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KTtcbiAgICB9KTtcbiAgfVxuXG4gIGN0eC5zZWVuLnBvcCgpO1xuXG4gIHJldHVybiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcyk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0ciwgZGVzYztcbiAgZGVzYyA9IHsgdmFsdWU6IHZhbHVlW2tleV0gfTtcbiAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IpIHtcbiAgICBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih2YWx1ZSwga2V5KSB8fCBkZXNjO1xuICB9XG4gIGlmIChkZXNjLmdldCkge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXIvU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tTZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFoYXNPd24odmlzaWJsZUtleXMsIGtleSkpIHtcbiAgICBuYW1lID0gJ1snICsga2V5ICsgJ10nO1xuICB9XG4gIGlmICghc3RyKSB7XG4gICAgaWYgKGluZGV4T2YoY3R4LnNlZW4sIGRlc2MudmFsdWUpIDwgMCkge1xuICAgICAgaWYgKGlzTnVsbChyZWN1cnNlVGltZXMpKSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgbnVsbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIHJlY3Vyc2VUaW1lcyAtIDEpO1xuICAgICAgfVxuICAgICAgaWYgKHN0ci5pbmRleE9mKCdcXG4nKSA+IC0xKSB7XG4gICAgICAgIGlmIChhcnJheSkge1xuICAgICAgICAgIHN0ciA9IG1hcChzdHIuc3BsaXQoJ1xcbicpLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJykuc3Vic3RyKDIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0ciA9ICdcXG4nICsgbWFwKHN0ci5zcGxpdCgnXFxuJyksIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKSB7XG4gIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCd1bmRlZmluZWQnLCAndW5kZWZpbmVkJyk7XG4gIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJykgKyAnXFwnJztcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG4gIH1cbiAgaWYgKGlzTnVtYmVyKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ251bWJlcicpO1xuICBpZiAoaXNCb29sZWFuKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgLy8gRm9yIHNvbWUgcmVhc29uIHR5cGVvZiBudWxsIGlzIFwib2JqZWN0XCIsIHNvIHNwZWNpYWwgY2FzZSBoZXJlLlxuICBpZiAoaXNOdWxsKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ251bGwnLCAnbnVsbCcpO1xufVxuXG5mdW5jdGlvbiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcykge1xuICB2YXIgbnVtTGluZXNFc3QgPSAwO1xuICB2YXIgbGVuZ3RoID0gcmVkdWNlKG91dHB1dCwgZnVuY3Rpb24ocHJldiwgY3VyKSB7XG4gICAgbnVtTGluZXNFc3QrKztcbiAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIG51bUxpbmVzRXN0Kys7XG4gICAgcmV0dXJuIHByZXYgKyBjdXIucmVwbGFjZSgvXFx1MDAxYlxcW1xcZFxcZD9tL2csICcnKS5sZW5ndGggKyAxO1xuICB9LCAwKTtcblxuICBpZiAobGVuZ3RoID4gNjApIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICtcbiAgICAgICAgICAgKGJhc2UgPT09ICcnID8gJycgOiBiYXNlICsgJ1xcbiAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIG91dHB1dC5qb2luKCcsXFxuICAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIGJyYWNlc1sxXTtcbiAgfVxuXG4gIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgJyAnICsgb3V0cHV0LmpvaW4oJywgJykgKyAnICcgKyBicmFjZXNbMV07XG59XG5cbmZ1bmN0aW9uIF9leHRlbmQob3JpZ2luLCBhZGQpIHtcbiAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgYWRkIGlzbid0IGFuIG9iamVjdFxuICBpZiAoIWFkZCB8fCAhaXNPYmplY3QoYWRkKSkgcmV0dXJuIG9yaWdpbjtcblxuICB2YXIga2V5cyA9IG9iamVjdEtleXMoYWRkKTtcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIG9yaWdpbltrZXlzW2ldXSA9IGFkZFtrZXlzW2ldXTtcbiAgfVxuICByZXR1cm4gb3JpZ2luO1xufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLy8gVGhpcyBpcyBhIHJlcG9ydGVyIHRoYXQgbWltaWNzIE1vY2hhJ3MgYGRvdGAgcmVwb3J0ZXJcblxudmFyIFIgPSByZXF1aXJlKFwiLi4vbGliL3JlcG9ydGVyXCIpXG5cbmZ1bmN0aW9uIHdpZHRoKCkge1xuICAgIHJldHVybiBSLndpbmRvd1dpZHRoKCkgKiA0IC8gMyB8IDBcbn1cblxuZnVuY3Rpb24gcHJpbnREb3QoXywgY29sb3IpIHtcbiAgICBmdW5jdGlvbiBlbWl0KCkge1xuICAgICAgICByZXR1cm4gXy53cml0ZShSLmNvbG9yKGNvbG9yLFxuICAgICAgICAgICAgY29sb3IgPT09IFwiZmFpbFwiID8gUi5zeW1ib2xzKCkuRG90RmFpbCA6IFIuc3ltYm9scygpLkRvdCkpXG4gICAgfVxuXG4gICAgaWYgKF8uc3RhdGUuY291bnRlcisrICUgd2lkdGgoKSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gXy53cml0ZShSLm5ld2xpbmUoKSArIFwiICBcIikudGhlbihlbWl0KVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBlbWl0KClcbiAgICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gUi5vbihcImRvdFwiLCB7XG4gICAgYWNjZXB0czogW1wid3JpdGVcIiwgXCJyZXNldFwiLCBcImNvbG9yc1wiXSxcbiAgICBjcmVhdGU6IFIuY29uc29sZVJlcG9ydGVyLFxuICAgIGJlZm9yZTogUi5zZXRDb2xvcixcbiAgICBhZnRlcjogUi51bnNldENvbG9yLFxuICAgIGluaXQ6IGZ1bmN0aW9uIChzdGF0ZSkgeyBzdGF0ZS5jb3VudGVyID0gMCB9LFxuXG4gICAgcmVwb3J0OiBmdW5jdGlvbiAoXywgcmVwb3J0KSB7XG4gICAgICAgIGlmIChyZXBvcnQuaXNFbnRlciB8fCByZXBvcnQuaXNQYXNzKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJpbnREb3QoXywgUi5zcGVlZChyZXBvcnQpKVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0hvb2sgfHwgcmVwb3J0LmlzRmFpbCkge1xuICAgICAgICAgICAgXy5wdXNoRXJyb3IocmVwb3J0KVxuICAgICAgICAgICAgLy8gUHJpbnQgYSBkb3QgcmVnYXJkbGVzcyBvZiBob29rIHN1Y2Nlc3NcbiAgICAgICAgICAgIHJldHVybiBwcmludERvdChfLCBcImZhaWxcIilcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNTa2lwKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJpbnREb3QoXywgXCJza2lwXCIpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzRW5kKSB7XG4gICAgICAgICAgICByZXR1cm4gXy5wcmludCgpLnRoZW4oXy5wcmludFJlc3VsdHMuYmluZChfKSlcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFcnJvcikge1xuICAgICAgICAgICAgaWYgKF8uc3RhdGUuY291bnRlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBfLnByaW50KCkudGhlbihfLnByaW50RXJyb3IuYmluZChfLCByZXBvcnQpKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXy5wcmludEVycm9yKHJlcG9ydClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgfVxuICAgIH0sXG59KVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuZXhwb3J0cy5kb3QgPSByZXF1aXJlKFwiLi9kb3RcIilcbmV4cG9ydHMuc3BlYyA9IHJlcXVpcmUoXCIuL3NwZWNcIilcbmV4cG9ydHMudGFwID0gcmVxdWlyZShcIi4vdGFwXCIpXG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vLyBUaGlzIGlzIGEgcmVwb3J0ZXIgdGhhdCBtaW1pY3MgTW9jaGEncyBgc3BlY2AgcmVwb3J0ZXIuXG5cbnZhciBSID0gcmVxdWlyZShcIi4uL2xpYi9yZXBvcnRlclwiKVxudmFyIGMgPSBSLmNvbG9yXG5cbmZ1bmN0aW9uIGluZGVudChsZXZlbCkge1xuICAgIHZhciByZXQgPSBcIlwiXG5cbiAgICB3aGlsZSAobGV2ZWwtLSkgcmV0ICs9IFwiICBcIlxuICAgIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gZ2V0TmFtZShsZXZlbCwgcmVwb3J0KSB7XG4gICAgcmV0dXJuIHJlcG9ydC5wYXRoW2xldmVsIC0gMV0ubmFtZVxufVxuXG5mdW5jdGlvbiBwcmludFJlcG9ydChfLCByZXBvcnQsIGluaXQpIHtcbiAgICBpZiAoXy5zdGF0ZS5sZWF2aW5nKSB7XG4gICAgICAgIF8uc3RhdGUubGVhdmluZyA9IGZhbHNlXG4gICAgICAgIHJldHVybiBfLnByaW50KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gXy5wcmludChpbmRlbnQoXy5zdGF0ZS5sZXZlbCkgKyBpbml0KCkpXG4gICAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIF8ucHJpbnQoaW5kZW50KF8uc3RhdGUubGV2ZWwpICsgaW5pdCgpKVxuICAgIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSLm9uKFwic3BlY1wiLCB7XG4gICAgYWNjZXB0czogW1wid3JpdGVcIiwgXCJyZXNldFwiLCBcImNvbG9yc1wiXSxcbiAgICBjcmVhdGU6IFIuY29uc29sZVJlcG9ydGVyLFxuICAgIGJlZm9yZTogUi5zZXRDb2xvcixcbiAgICBhZnRlcjogUi51bnNldENvbG9yLFxuXG4gICAgaW5pdDogZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgICAgIHN0YXRlLmxldmVsID0gMVxuICAgICAgICBzdGF0ZS5sZWF2aW5nID0gZmFsc2VcbiAgICB9LFxuXG4gICAgcmVwb3J0OiBmdW5jdGlvbiAoXywgcmVwb3J0KSB7XG4gICAgICAgIGlmIChyZXBvcnQuaXNTdGFydCkge1xuICAgICAgICAgICAgcmV0dXJuIF8ucHJpbnQoKVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0VudGVyKSB7XG4gICAgICAgICAgICB2YXIgbGV2ZWwgPSBfLnN0YXRlLmxldmVsKytcbiAgICAgICAgICAgIHZhciBsYXN0ID0gcmVwb3J0LnBhdGhbbGV2ZWwgLSAxXVxuXG4gICAgICAgICAgICBfLnN0YXRlLmxlYXZpbmcgPSBmYWxzZVxuICAgICAgICAgICAgaWYgKGxhc3QuaW5kZXgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXy5wcmludCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXy5wcmludChpbmRlbnQobGV2ZWwpICsgbGFzdC5uYW1lKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBfLnByaW50KGluZGVudChsZXZlbCkgKyBsYXN0Lm5hbWUpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzTGVhdmUpIHtcbiAgICAgICAgICAgIF8uc3RhdGUubGV2ZWwtLVxuICAgICAgICAgICAgXy5zdGF0ZS5sZWF2aW5nID0gdHJ1ZVxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc1Bhc3MpIHtcbiAgICAgICAgICAgIHJldHVybiBwcmludFJlcG9ydChfLCByZXBvcnQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgc3RyID1cbiAgICAgICAgICAgICAgICAgICAgYyhcImNoZWNrbWFya1wiLCBSLnN5bWJvbHMoKS5QYXNzICsgXCIgXCIpICtcbiAgICAgICAgICAgICAgICAgICAgYyhcInBhc3NcIiwgZ2V0TmFtZShfLnN0YXRlLmxldmVsLCByZXBvcnQpKVxuXG4gICAgICAgICAgICAgICAgdmFyIHNwZWVkID0gUi5zcGVlZChyZXBvcnQpXG5cbiAgICAgICAgICAgICAgICBpZiAoc3BlZWQgIT09IFwiZmFzdFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0ciArPSBjKHNwZWVkLCBcIiAoXCIgKyByZXBvcnQuZHVyYXRpb24gKyBcIm1zKVwiKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBzdHJcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzSG9vayB8fCByZXBvcnQuaXNGYWlsKSB7XG4gICAgICAgICAgICBfLnB1c2hFcnJvcihyZXBvcnQpXG5cbiAgICAgICAgICAgIC8vIERvbid0IHByaW50IHRoZSBkZXNjcmlwdGlvbiBsaW5lIG9uIGN1bXVsYXRpdmUgaG9va3NcbiAgICAgICAgICAgIGlmIChyZXBvcnQuaXNIb29rICYmIChyZXBvcnQuaXNCZWZvcmVBbGwgfHwgcmVwb3J0LmlzQWZ0ZXJBbGwpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcHJpbnRSZXBvcnQoXywgcmVwb3J0LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGMoXCJmYWlsXCIsXG4gICAgICAgICAgICAgICAgICAgIF8uZXJyb3JzLmxlbmd0aCArIFwiKSBcIiArIGdldE5hbWUoXy5zdGF0ZS5sZXZlbCwgcmVwb3J0KSArXG4gICAgICAgICAgICAgICAgICAgIFIuZm9ybWF0UmVzdChyZXBvcnQpKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNTa2lwKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJpbnRSZXBvcnQoXywgcmVwb3J0LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGMoXCJza2lwXCIsIFwiLSBcIiArIGdldE5hbWUoXy5zdGF0ZS5sZXZlbCwgcmVwb3J0KSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVwb3J0LmlzRW5kKSByZXR1cm4gXy5wcmludFJlc3VsdHMoKVxuICAgICAgICBpZiAocmVwb3J0LmlzRXJyb3IpIHJldHVybiBfLnByaW50RXJyb3IocmVwb3J0KVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vLyBUaGlzIGlzIGEgYmFzaWMgVEFQLWdlbmVyYXRpbmcgcmVwb3J0ZXIuXG5cbnZhciBwZWFjaCA9IHJlcXVpcmUoXCIuLi9saWIvdXRpbFwiKS5wZWFjaFxudmFyIFIgPSByZXF1aXJlKFwiLi4vbGliL3JlcG9ydGVyXCIpXG52YXIgaW5zcGVjdCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKS5pbnNwZWN0XG5cbmZ1bmN0aW9uIHNob3VsZEJyZWFrKG1pbkxlbmd0aCwgc3RyKSB7XG4gICAgcmV0dXJuIHN0ci5sZW5ndGggPiBSLndpbmRvd1dpZHRoKCkgLSBtaW5MZW5ndGggfHwgL1xccj9cXG58Wzo/LV0vLnRlc3Qoc3RyKVxufVxuXG5mdW5jdGlvbiB0ZW1wbGF0ZShfLCByZXBvcnQsIHRtcGwsIHNraXApIHtcbiAgICBpZiAoIXNraXApIF8uc3RhdGUuY291bnRlcisrXG4gICAgdmFyIHBhdGggPSBSLmpvaW5QYXRoKHJlcG9ydCkucmVwbGFjZSgvXFwkL2csIFwiJCQkJFwiKVxuXG4gICAgcmV0dXJuIF8ucHJpbnQoXG4gICAgICAgIHRtcGwucmVwbGFjZSgvJWMvZywgXy5zdGF0ZS5jb3VudGVyKVxuICAgICAgICAgICAgLnJlcGxhY2UoLyVwL2csIHBhdGggKyBSLmZvcm1hdFJlc3QocmVwb3J0KSkpXG59XG5cbmZ1bmN0aW9uIHByaW50TGluZXMoXywgdmFsdWUsIHNraXBGaXJzdCkge1xuICAgIHZhciBsaW5lcyA9IHZhbHVlLnNwbGl0KC9cXHI/XFxuL2cpXG5cbiAgICBpZiAoc2tpcEZpcnN0KSBsaW5lcy5zaGlmdCgpXG4gICAgcmV0dXJuIHBlYWNoKGxpbmVzLCBmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gXy5wcmludChcIiAgICBcIiArIGxpbmUpIH0pXG59XG5cbmZ1bmN0aW9uIHByaW50UmF3KF8sIGtleSwgc3RyKSB7XG4gICAgaWYgKHNob3VsZEJyZWFrKGtleS5sZW5ndGgsIHN0cikpIHtcbiAgICAgICAgcmV0dXJuIF8ucHJpbnQoXCIgIFwiICsga2V5ICsgXCI6IHwtXCIpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHByaW50TGluZXMoXywgc3RyLCBmYWxzZSkgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gXy5wcmludChcIiAgXCIgKyBrZXkgKyBcIjogXCIgKyBzdHIpXG4gICAgfVxufVxuXG5mdW5jdGlvbiBwcmludFZhbHVlKF8sIGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gcHJpbnRSYXcoXywga2V5LCBpbnNwZWN0KHZhbHVlKSlcbn1cblxuZnVuY3Rpb24gcHJpbnRMaW5lKHAsIF8sIGxpbmUpIHtcbiAgICByZXR1cm4gcC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIF8ucHJpbnQobGluZSkgfSlcbn1cblxuZnVuY3Rpb24gcHJpbnRFcnJvcihfLCByZXBvcnQpIHtcbiAgICB2YXIgZXJyID0gcmVwb3J0LmVycm9yXG5cbiAgICBpZiAoIShlcnIgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgcmV0dXJuIHByaW50VmFsdWUoXywgXCJ2YWx1ZVwiLCBlcnIpXG4gICAgfVxuXG4gICAgLy8gTGV0J3MgKm5vdCogZGVwZW5kIG9uIHRoZSBjb25zdHJ1Y3RvciBiZWluZyBUaGFsbGl1bSdzLi4uXG4gICAgaWYgKGVyci5uYW1lICE9PSBcIkFzc2VydGlvbkVycm9yXCIpIHtcbiAgICAgICAgcmV0dXJuIF8ucHJpbnQoXCIgIHN0YWNrOiB8LVwiKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBwcmludExpbmVzKF8sIFIuZ2V0U3RhY2soZXJyKSwgZmFsc2UpXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHByaW50VmFsdWUoXywgXCJleHBlY3RlZFwiLCBlcnIuZXhwZWN0ZWQpXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcHJpbnRWYWx1ZShfLCBcImFjdHVhbFwiLCBlcnIuYWN0dWFsKSB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHByaW50UmF3KF8sIFwibWVzc2FnZVwiLCBlcnIubWVzc2FnZSkgfSlcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBfLnByaW50KFwiICBzdGFjazogfC1cIikgfSlcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtZXNzYWdlID0gZXJyLm1lc3NhZ2VcblxuICAgICAgICBlcnIubWVzc2FnZSA9IFwiXCJcbiAgICAgICAgcmV0dXJuIHByaW50TGluZXMoXywgUi5nZXRTdGFjayhlcnIpLCB0cnVlKVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IGVyci5tZXNzYWdlID0gbWVzc2FnZSB9KVxuICAgIH0pXG59XG5cbm1vZHVsZS5leHBvcnRzID0gUi5vbihcInRhcFwiLCB7XG4gICAgYWNjZXB0czogW1wid3JpdGVcIiwgXCJyZXNldFwiXSxcbiAgICBjcmVhdGU6IFIuY29uc29sZVJlcG9ydGVyLFxuICAgIGluaXQ6IGZ1bmN0aW9uIChzdGF0ZSkgeyBzdGF0ZS5jb3VudGVyID0gMCB9LFxuXG4gICAgcmVwb3J0OiBmdW5jdGlvbiAoXywgcmVwb3J0KSB7XG4gICAgICAgIGlmIChyZXBvcnQuaXNTdGFydCkge1xuICAgICAgICAgICAgcmV0dXJuIF8ucHJpbnQoXCJUQVAgdmVyc2lvbiAxM1wiKVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0VudGVyKSB7XG4gICAgICAgICAgICAvLyBQcmludCBhIGxlYWRpbmcgY29tbWVudCwgdG8gbWFrZSBzb21lIFRBUCBmb3JtYXR0ZXJzIHByZXR0aWVyLlxuICAgICAgICAgICAgcmV0dXJuIHRlbXBsYXRlKF8sIHJlcG9ydCwgXCIjICVwXCIsIHRydWUpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiB0ZW1wbGF0ZShfLCByZXBvcnQsIFwib2sgJWNcIikgfSlcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNQYXNzKSB7XG4gICAgICAgICAgICByZXR1cm4gdGVtcGxhdGUoXywgcmVwb3J0LCBcIm9rICVjICVwXCIpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzRmFpbCB8fCByZXBvcnQuaXNIb29rKSB7XG4gICAgICAgICAgICByZXR1cm4gdGVtcGxhdGUoXywgcmVwb3J0LCBcIm5vdCBvayAlYyAlcFwiKVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChcIiAgLS0tXCIpIH0pXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBwcmludEVycm9yKF8sIHJlcG9ydCkgfSlcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIF8ucHJpbnQoXCIgIC4uLlwiKSB9KVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc1NraXApIHtcbiAgICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZShfLCByZXBvcnQsIFwib2sgJWMgIyBza2lwICVwXCIpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzRW5kKSB7XG4gICAgICAgICAgICB2YXIgcCA9IF8ucHJpbnQoXCIxLi5cIiArIF8uc3RhdGUuY291bnRlcilcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIF8ucHJpbnQoXCIjIHRlc3RzIFwiICsgXy50ZXN0cykgfSlcblxuICAgICAgICAgICAgaWYgKF8ucGFzcykgcCA9IHByaW50TGluZShwLCBfLCBcIiMgcGFzcyBcIiArIF8ucGFzcylcbiAgICAgICAgICAgIGlmIChfLmZhaWwpIHAgPSBwcmludExpbmUocCwgXywgXCIjIGZhaWwgXCIgKyBfLmZhaWwpXG4gICAgICAgICAgICBpZiAoXy5za2lwKSBwID0gcHJpbnRMaW5lKHAsIF8sIFwiIyBza2lwIFwiICsgXy5za2lwKVxuICAgICAgICAgICAgcmV0dXJuIHByaW50TGluZShwLCBfLCBcIiMgZHVyYXRpb24gXCIgKyBSLmZvcm1hdFRpbWUoXy5kdXJhdGlvbikpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzRXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBfLnByaW50KFwiQmFpbCBvdXQhXCIpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBfLnByaW50KFwiICAtLS1cIikgfSlcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHByaW50RXJyb3IoXywgcmVwb3J0KSB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChcIiAgLi4uXCIpIH0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIH1cbiAgICB9LFxufSlcbiIsIlwidXNlIHN0cmljdFwiXG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4uL2xpYi9icm93c2VyLWJ1bmRsZVwiKVxuXG5yZXF1aXJlKFwiLi4vbWlncmF0ZS9pbmRleFwiKVxuXG4vLyBOb3RlOiBib3RoIG9mIHRoZXNlIGFyZSBkZXByZWNhdGVkXG5tb2R1bGUuZXhwb3J0cy5hc3NlcnRpb25zID0gcmVxdWlyZShcIi4uL2Fzc2VydGlvbnNcIilcbm1vZHVsZS5leHBvcnRzLmNyZWF0ZSA9IHJlcXVpcmUoXCIuLi9taWdyYXRlL2NvbW1vblwiKS5kZXByZWNhdGUoXG4gICAgXCJgdGwuY3JlYXRlYCBpcyBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIGB0bC5yb290YCBpbnN0ZWFkLlwiLFxuICAgIG1vZHVsZS5leHBvcnRzLnJvb3QpXG4iXX0= +},{"../lib/browser-bundle":8,"./index":27,"./support":28}]},{},[]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJhc3NlcnQuanMiLCJkb20uanMiLCJpbmRleC5qcyIsImludGVybmFsLmpzIiwibGliL2FwaS9jb21tb24uanMiLCJsaWIvYXBpL3JlZmxlY3QuanMiLCJsaWIvYXBpL3RoYWxsaXVtLmpzIiwibGliL2Jyb3dzZXItYnVuZGxlLmpzIiwibGliL2NvcmUvZmlsdGVyLmpzIiwibGliL2NvcmUvcmVwb3J0cy5qcyIsImxpYi9jb3JlL3Rlc3RzLmpzIiwibGliL2RvbS9pbmRleC5qcyIsImxpYi9kb20vaW5pdGlhbGl6ZS5qcyIsImxpYi9kb20vaW5qZWN0LXN0eWxlcy5qcyIsImxpYi9kb20vaW5qZWN0LmpzIiwibGliL2RvbS9ydW4tdGVzdHMuanMiLCJsaWIvZG9tL3ZpZXcuanMiLCJsaWIvbWV0aG9kcy5qcyIsImxpYi9yZXBsYWNlZC9jb25zb2xlLWJyb3dzZXIuanMiLCJsaWIvcmVwb3J0ZXIvY29uc29sZS1yZXBvcnRlci5qcyIsImxpYi9yZXBvcnRlci9pbmRleC5qcyIsImxpYi9yZXBvcnRlci9vbi5qcyIsImxpYi9yZXBvcnRlci9yZXBvcnRlci5qcyIsImxpYi9yZXBvcnRlci91dGlsLmpzIiwibGliL3NldHRpbmdzLmpzIiwibGliL3V0aWwuanMiLCJtaWdyYXRlL2luZGV4LmpzIiwibWlncmF0ZS9zdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2FycmF5LW1hcC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9hcnJheS1yZWR1Y2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvY2xlYW4tYXNzZXJ0LXV0aWwvYnJvd3Nlci1pbnNwZWN0LmpzIiwibm9kZV9tb2R1bGVzL2NsZWFuLWFzc2VydC11dGlsL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2NsZWFuLWFzc2VydC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1hc3NlcnQvbGliL2VxdWFsLmpzIiwibm9kZV9tb2R1bGVzL2NsZWFuLWFzc2VydC9saWIvaGFzLWtleXMuanMiLCJub2RlX21vZHVsZXMvY2xlYW4tYXNzZXJ0L2xpYi9oYXMuanMiLCJub2RlX21vZHVsZXMvY2xlYW4tYXNzZXJ0L2xpYi9pbmNsdWRlcy5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1hc3NlcnQvbGliL3Rocm93cy5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1hc3NlcnQvbGliL3R5cGUuanMiLCJub2RlX21vZHVsZXMvY2xlYW4tbWF0Y2gvY2xlYW4tbWF0Y2guanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvY29udmVydC9kbXAuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvY29udmVydC94bWwuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvZGlmZi9hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9kaWZmL2Jhc2UuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvZGlmZi9jaGFyYWN0ZXIuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvZGlmZi9jc3MuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvZGlmZi9qc29uLmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL2RpZmYvbGluZS5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9kaWZmL3NlbnRlbmNlLmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL2RpZmYvd29yZC5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9wYXRjaC9hcHBseS5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9wYXRjaC9jcmVhdGUuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvcGF0Y2gvcGFyc2UuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvdXRpbC9kaXN0YW5jZS1pdGVyYXRvci5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy91dGlsL3BhcmFtcy5qcyIsIm5vZGVfbW9kdWxlcy9mb3JlYWNoL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2luZGV4b2YvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaXNhcnJheS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9mb3JlYWNoLmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2lzQXJndW1lbnRzLmpzIiwibm9kZV9tb2R1bGVzL3V0aWwtaW5zcGVjdC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy91dGlsLWluc3BlY3Qvbm9kZV9tb2R1bGVzL2pzb24zL2xpYi9qc29uMy5qcyIsInIvZG90LmpzIiwici9pbmRleC5qcyIsInIvc3BlYy5qcyIsInIvdGFwLmpzIiwibWlncmF0ZS9idW5kbGUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4VkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNsUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3psQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdlhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDckpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDclFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3RJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDaGFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDajRCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJcInVzZSBzdHJpY3RcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnRcIilcbiIsIlwidXNlIHN0cmljdFwiXG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vbGliL2RvbVwiKVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLyoqXG4gKiBNYWluIGVudHJ5IHBvaW50LCBmb3IgdGhvc2Ugd2FudGluZyB0byB1c2UgdGhpcyBmcmFtZXdvcmsgd2l0aCB0aGUgY29yZVxuICogYXNzZXJ0aW9ucy5cbiAqL1xudmFyIFRoYWxsaXVtID0gcmVxdWlyZShcIi4vbGliL2FwaS90aGFsbGl1bVwiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUaGFsbGl1bSgpXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVGhhbGxpdW0gPSByZXF1aXJlKFwiLi9saWIvYXBpL3RoYWxsaXVtXCIpXG52YXIgUmVwb3J0cyA9IHJlcXVpcmUoXCIuL2xpYi9jb3JlL3JlcG9ydHNcIilcbnZhciBIb29rU3RhZ2UgPSBSZXBvcnRzLkhvb2tTdGFnZVxuXG5leHBvcnRzLnJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5ldyBUaGFsbGl1bSgpXG59XG5cbmZ1bmN0aW9uIGQoZHVyYXRpb24pIHtcbiAgICBpZiAoZHVyYXRpb24gPT0gbnVsbCkgcmV0dXJuIDEwXG4gICAgaWYgKHR5cGVvZiBkdXJhdGlvbiA9PT0gXCJudW1iZXJcIikgcmV0dXJuIGR1cmF0aW9ufDBcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYGR1cmF0aW9uYCB0byBiZSBhIG51bWJlciBpZiBpdCBleGlzdHNcIilcbn1cblxuZnVuY3Rpb24gcyhzbG93KSB7XG4gICAgaWYgKHNsb3cgPT0gbnVsbCkgcmV0dXJuIDc1XG4gICAgaWYgKHR5cGVvZiBzbG93ID09PSBcIm51bWJlclwiKSByZXR1cm4gc2xvd3wwXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBzbG93YCB0byBiZSBhIG51bWJlciBpZiBpdCBleGlzdHNcIilcbn1cblxuZnVuY3Rpb24gcChwYXRoKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocGF0aCkpIHJldHVybiBwYXRoXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBwYXRoYCB0byBiZSBhbiBhcnJheSBvZiBsb2NhdGlvbnNcIilcbn1cblxuZnVuY3Rpb24gaCh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIHR5cGVvZiB2YWx1ZS5fID09PSBcIm51bWJlclwiKSByZXR1cm4gdmFsdWVcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHZhbHVlYCB0byBiZSBhIGhvb2sgZXJyb3JcIilcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgcmVwb3J0LCBtYWlubHkgZm9yIHRlc3RpbmcgcmVwb3J0ZXJzLlxuICovXG5leHBvcnRzLnJlcG9ydHMgPSB7XG4gICAgc3RhcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBvcnRzLlN0YXJ0KClcbiAgICB9LFxuXG4gICAgZW50ZXI6IGZ1bmN0aW9uIChwYXRoLCBkdXJhdGlvbiwgc2xvdykge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuRW50ZXIocChwYXRoKSwgZChkdXJhdGlvbiksIHMoc2xvdykpXG4gICAgfSxcblxuICAgIGxlYXZlOiBmdW5jdGlvbiAocGF0aCkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuTGVhdmUocChwYXRoKSlcbiAgICB9LFxuXG4gICAgcGFzczogZnVuY3Rpb24gKHBhdGgsIGR1cmF0aW9uLCBzbG93KSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5QYXNzKHAocGF0aCksIGQoZHVyYXRpb24pLCBzKHNsb3cpKVxuICAgIH0sXG5cbiAgICBmYWlsOiBmdW5jdGlvbiAocGF0aCwgdmFsdWUsIGR1cmF0aW9uLCBzbG93LCBpc0ZhaWxhYmxlKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuRmFpbChcbiAgICAgICAgICAgIHAocGF0aCksIHZhbHVlLCBkKGR1cmF0aW9uKSwgcyhzbG93KSxcbiAgICAgICAgICAgICEhaXNGYWlsYWJsZSlcbiAgICB9LFxuXG4gICAgc2tpcDogZnVuY3Rpb24gKHBhdGgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBvcnRzLlNraXAocChwYXRoKSlcbiAgICB9LFxuXG4gICAgZW5kOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5FbmQoKVxuICAgIH0sXG5cbiAgICBlcnJvcjogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5FcnJvcih2YWx1ZSlcbiAgICB9LFxuXG4gICAgaG9vazogZnVuY3Rpb24gKHBhdGgsIHJvb3RQYXRoLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuSG9vayhwKHBhdGgpLCBwKHJvb3RQYXRoKSwgaCh2YWx1ZSkpXG4gICAgfSxcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgaG9vayBlcnJvciwgbWFpbmx5IGZvciB0ZXN0aW5nIHJlcG9ydGVycy5cbiAqL1xuZXhwb3J0cy5ob29rRXJyb3JzID0ge1xuICAgIGJlZm9yZUFsbDogZnVuY3Rpb24gKGZ1bmMsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5Ib29rRXJyb3IoSG9va1N0YWdlLkJlZm9yZUFsbCwgZnVuYywgdmFsdWUpXG4gICAgfSxcblxuICAgIGJlZm9yZUVhY2g6IGZ1bmN0aW9uIChmdW5jLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuSG9va0Vycm9yKEhvb2tTdGFnZS5CZWZvcmVFYWNoLCBmdW5jLCB2YWx1ZSlcbiAgICB9LFxuXG4gICAgYWZ0ZXJFYWNoOiBmdW5jdGlvbiAoZnVuYywgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBvcnRzLkhvb2tFcnJvcihIb29rU3RhZ2UuQWZ0ZXJFYWNoLCBmdW5jLCB2YWx1ZSlcbiAgICB9LFxuXG4gICAgYWZ0ZXJBbGw6IGZ1bmN0aW9uIChmdW5jLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuSG9va0Vycm9yKEhvb2tTdGFnZS5BZnRlckFsbCwgZnVuYywgdmFsdWUpXG4gICAgfSxcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGxvY2F0aW9uLCBtYWlubHkgZm9yIHRlc3RpbmcgcmVwb3J0ZXJzLlxuICovXG5leHBvcnRzLmxvY2F0aW9uID0gZnVuY3Rpb24gKG5hbWUsIGluZGV4KSB7XG4gICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBgbmFtZWAgdG8gYmUgYSBzdHJpbmdcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluZGV4ICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBgaW5kZXhgIHRvIGJlIGEgbnVtYmVyXCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIHtuYW1lOiBuYW1lLCBpbmRleDogaW5kZXh8MH1cbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbmV4cG9ydHMuYWRkSG9vayA9IGZ1bmN0aW9uIChsaXN0LCBjYWxsYmFjaykge1xuICAgIGlmIChsaXN0ICE9IG51bGwpIHtcbiAgICAgICAgbGlzdC5wdXNoKGNhbGxiYWNrKVxuICAgICAgICByZXR1cm4gbGlzdFxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbY2FsbGJhY2tdXG4gICAgfVxufVxuXG5leHBvcnRzLnJlbW92ZUhvb2sgPSBmdW5jdGlvbiAobGlzdCwgY2FsbGJhY2spIHtcbiAgICBpZiAobGlzdCA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGlmIChsaXN0WzBdID09PSBjYWxsYmFjaykgcmV0dXJuIHVuZGVmaW5lZFxuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBpbmRleCA9IGxpc3QuaW5kZXhPZihjYWxsYmFjaylcblxuICAgICAgICBpZiAoaW5kZXggPj0gMCkgbGlzdC5zcGxpY2UoaW5kZXgsIDEpXG4gICAgfVxuICAgIHJldHVybiBsaXN0XG59XG5cbmV4cG9ydHMuaGFzSG9vayA9IGZ1bmN0aW9uIChsaXN0LCBjYWxsYmFjaykge1xuICAgIGlmIChsaXN0ID09IG51bGwpIHJldHVybiBmYWxzZVxuICAgIGlmIChsaXN0Lmxlbmd0aCA+IDEpIHJldHVybiBsaXN0LmluZGV4T2YoY2FsbGJhY2spID49IDBcbiAgICByZXR1cm4gbGlzdFswXSA9PT0gY2FsbGJhY2tcbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcbnZhciBUZXN0cyA9IHJlcXVpcmUoXCIuLi9jb3JlL3Rlc3RzXCIpXG52YXIgQ29tbW9uID0gcmVxdWlyZShcIi4vY29tbW9uXCIpXG5cbi8qKlxuICogVGhpcyBjb250YWlucyB0aGUgbG93IGxldmVsLCBtb3JlIGFyY2FuZSB0aGluZ3MgdGhhdCBhcmUgZ2VuZXJhbGx5IG5vdFxuICogaW50ZXJlc3RpbmcgdG8gYW55b25lIG90aGVyIHRoYW4gcGx1Z2luIGRldmVsb3BlcnMuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gUmVmbGVjdFxuZnVuY3Rpb24gUmVmbGVjdCh0ZXN0KSB7XG4gICAgdmFyIHJlZmxlY3QgPSB0ZXN0LnJlZmxlY3RcblxuICAgIGlmIChyZWZsZWN0ICE9IG51bGwpIHJldHVybiByZWZsZWN0XG4gICAgdGVzdC5yZWZsZWN0ID0gdGhpc1xuICAgIHRoaXMuXyA9IHRlc3Rcbn1cblxubWV0aG9kcyhSZWZsZWN0LCB7XG4gICAgLyoqXG4gICAgICogV2hldGhlciBhIHJlcG9ydGVyIHdhcyByZWdpc3RlcmVkLlxuICAgICAqL1xuICAgIGhhc1JlcG9ydGVyOiBmdW5jdGlvbiAocmVwb3J0ZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXBvcnRlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHJlcG9ydGVyYCB0byBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QucmVwb3J0ZXJJZHMuaW5kZXhPZihyZXBvcnRlcikgPj0gMFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSByZXBvcnRlci5cbiAgICAgKi9cbiAgICByZXBvcnRlcjogZnVuY3Rpb24gKHJlcG9ydGVyLCBhcmcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXBvcnRlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHJlcG9ydGVyYCB0byBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcm9vdCA9IHRoaXMuXy5yb290XG5cbiAgICAgICAgaWYgKHJvb3QuY3VycmVudCAhPT0gcm9vdCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmVwb3J0ZXJzIG1heSBvbmx5IGJlIGFkZGVkIHRvIHRoZSByb290XCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAocm9vdC5yZXBvcnRlcklkcy5pbmRleE9mKHJlcG9ydGVyKSA8IDApIHtcbiAgICAgICAgICAgIHJvb3QucmVwb3J0ZXJJZHMucHVzaChyZXBvcnRlcilcbiAgICAgICAgICAgIHJvb3QucmVwb3J0ZXJzLnB1c2gocmVwb3J0ZXIoYXJnKSlcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSByZXBvcnRlci5cbiAgICAgKi9cbiAgICByZW1vdmVSZXBvcnRlcjogZnVuY3Rpb24gKHJlcG9ydGVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVwb3J0ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGByZXBvcnRlcmAgdG8gYmUgYSBmdW5jdGlvblwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJvb3QgPSB0aGlzLl8ucm9vdFxuXG4gICAgICAgIGlmIChyb290LmN1cnJlbnQgIT09IHJvb3QpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlcG9ydGVycyBtYXkgb25seSBiZSBhZGRlZCB0byB0aGUgcm9vdFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGluZGV4ID0gcm9vdC5yZXBvcnRlcklkcy5pbmRleE9mKHJlcG9ydGVyKVxuXG4gICAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgICByb290LnJlcG9ydGVySWRzLnNwbGljZShpbmRleCwgMSlcbiAgICAgICAgICAgIHJvb3QucmVwb3J0ZXJzLnNwbGljZShpbmRleCwgMSlcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnRseSBleGVjdXRpbmcgdGVzdC5cbiAgICAgKi9cbiAgICBnZXQgY3VycmVudCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZWZsZWN0KHRoaXMuXy5yb290LmN1cnJlbnQpXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgcm9vdCB0ZXN0LlxuICAgICAqL1xuICAgIGdldCByb290KCkge1xuICAgICAgICByZXR1cm4gbmV3IFJlZmxlY3QodGhpcy5fLnJvb3QpXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VycmVudCB0b3RhbCB0ZXN0IGNvdW50LlxuICAgICAqL1xuICAgIGdldCBjb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuXy50ZXN0cyA9PSBudWxsID8gMCA6IHRoaXMuXy50ZXN0cy5sZW5ndGhcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IGEgY29weSBvZiB0aGUgY3VycmVudCB0ZXN0IGxpc3QsIGFzIGEgUmVmbGVjdCBjb2xsZWN0aW9uLiBUaGlzIGlzXG4gICAgICogaW50ZW50aW9uYWxseSBhIHNsaWNlLCBzbyB5b3UgY2FuJ3QgbXV0YXRlIHRoZSByZWFsIGNoaWxkcmVuLlxuICAgICAqL1xuICAgIGdldCBjaGlsZHJlbigpIHtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gW11cblxuICAgICAgICBpZiAodGhpcy5fLnRlc3RzICE9IG51bGwpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fLnRlc3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY2hpbGRyZW5baV0gPSBuZXcgUmVmbGVjdCh0aGlzLl8udGVzdHNbaV0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2hpbGRyZW5cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogSXMgdGhpcyB0ZXN0IHRoZSByb290LCBpLmUuIHRvcCBsZXZlbD9cbiAgICAgKi9cbiAgICBnZXQgaXNSb290KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnBhcmVudCA9PSBudWxsXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIElzIHRoaXMgbG9ja2VkIChpLmUuIHVuc2FmZSB0byBtb2RpZnkpP1xuICAgICAqL1xuICAgIGdldCBpc0xvY2tlZCgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fLmxvY2tlZFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGFjdGl2ZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcywgbm90IG5lY2Vzc2FyaWx5IG93biwgb3IgdGhlXG4gICAgICogZnJhbWV3b3JrIGRlZmF1bHQgb2YgMjAwMCwgaWYgbm9uZSB3YXMgc2V0LlxuICAgICAqL1xuICAgIGdldCB0aW1lb3V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnRpbWVvdXQgfHwgVGVzdHMuZGVmYXVsdFRpbWVvdXRcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBhY3RpdmUgc2xvdyB0aHJlc2hvbGQgaW4gbWlsbGlzZWNvbmRzLCBub3QgbmVjZXNzYXJpbHkgb3duLCBvclxuICAgICAqIHRoZSBmcmFtZXdvcmsgZGVmYXVsdCBvZiA3NSwgaWYgbm9uZSB3YXMgc2V0LlxuICAgICAqL1xuICAgIGdldCBzbG93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnNsb3cgfHwgVGVzdHMuZGVmYXVsdFNsb3dcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0ZXN0J3Mgb3duIG1heCBhdHRlbXB0IGNvdW50LiBOb3RlIHRoYXQgdGhpcyBpcyBwYXJhc2l0aWNhbGx5XG4gICAgICogaW5oZXJpdGVkIGZyb20gaXRzIHBhcmVudCwgbm90IGRlbGVnYXRlZC5cbiAgICAgKi9cbiAgICBnZXQgYXR0ZW1wdHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8uYXR0ZW1wdHNcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHdoZXRoZXIgdGhpcyB0ZXN0IGlzIGZhaWxhYmxlLiBOb3RlIHRoYXQgdGhpcyBpcyBwYXJhc2l0aWNhbGx5XG4gICAgICogaW5oZXJpdGVkIGZyb20gaXRzIHBhcmVudCwgbm90IGRlbGVnYXRlZC5cbiAgICAgKi9cbiAgICBnZXQgaXNGYWlsYWJsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuXy5pc0ZhaWxhYmxlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGVzdCBuYW1lLCBvciBgdW5kZWZpbmVkYCBpZiBpdCdzIHRoZSByb290IHRlc3QuXG4gICAgICovXG4gICAgZ2V0IG5hbWUoKSB7XG4gICAgICAgIGlmICh0aGlzLl8ucGFyZW50ID09IG51bGwpIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgcmV0dXJuIHRoaXMuXy5uYW1lXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGVzdCBpbmRleCwgb3IgYHVuZGVmaW5lZGAgaWYgaXQncyB0aGUgcm9vdCB0ZXN0LlxuICAgICAqL1xuICAgIGdldCBpbmRleCgpIHtcbiAgICAgICAgaWYgKHRoaXMuXy5wYXJlbnQgPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICByZXR1cm4gdGhpcy5fLmluZGV4XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGVzdCdzIHBhcmVudCBhcyBhIFJlZmxlY3QsIG9yIGB1bmRlZmluZWRgIGlmIGl0J3MgdGhlIHJvb3QgdGVzdC5cbiAgICAgKi9cbiAgICBnZXQgcGFyZW50KCkge1xuICAgICAgICBpZiAodGhpcy5fLnBhcmVudCA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIHJldHVybiBuZXcgUmVmbGVjdCh0aGlzLl8ucGFyZW50KVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBob29rIHRvIGJlIHJ1biBiZWZvcmUgZWFjaCBzdWJ0ZXN0LCBpbmNsdWRpbmcgdGhlaXIgc3VidGVzdHMgYW5kIHNvXG4gICAgICogb24uXG4gICAgICovXG4gICAgYmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5iZWZvcmVFYWNoID0gQ29tbW9uLmFkZEhvb2sodGhpcy5fLmJlZm9yZUVhY2gsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBob29rIHRvIGJlIHJ1biBvbmNlIGJlZm9yZSBhbGwgc3VidGVzdHMgYXJlIHJ1bi5cbiAgICAgKi9cbiAgICBiZWZvcmVBbGw6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fLmJlZm9yZUFsbCA9IENvbW1vbi5hZGRIb29rKHRoaXMuXy5iZWZvcmVBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgIC8qKlxuICAgICogQWRkIGEgaG9vayB0byBiZSBydW4gYWZ0ZXIgZWFjaCBzdWJ0ZXN0LCBpbmNsdWRpbmcgdGhlaXIgc3VidGVzdHMgYW5kIHNvXG4gICAgKiBvbi5cbiAgICAqL1xuICAgIGFmdGVyOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5hZnRlckVhY2ggPSBDb21tb24uYWRkSG9vayh0aGlzLl8uYWZ0ZXJFYWNoLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgaG9vayB0byBiZSBydW4gb25jZSBhZnRlciBhbGwgc3VidGVzdHMgYXJlIHJ1bi5cbiAgICAgKi9cbiAgICBhZnRlckFsbDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl8uYWZ0ZXJBbGwgPSBDb21tb24uYWRkSG9vayh0aGlzLl8uYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5iZWZvcmVgIG9yIGByZWZsZWN0LmJlZm9yZWAuXG4gICAgICovXG4gICAgaGFzQmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBDb21tb24uaGFzSG9vayh0aGlzLl8uYmVmb3JlRWFjaCwgY2FsbGJhY2spXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhIGhvb2sgcHJldmlvdXNseSBhZGRlZCB3aXRoIGB0LmJlZm9yZUFsbGAgb3IgYHJlZmxlY3QuYmVmb3JlQWxsYC5cbiAgICAgKi9cbiAgICBoYXNCZWZvcmVBbGw6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIENvbW1vbi5oYXNIb29rKHRoaXMuXy5iZWZvcmVBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5hZnRlcmAgb3JgcmVmbGVjdC5hZnRlcmAuXG4gICAgICovXG4gICAgaGFzQWZ0ZXI6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIENvbW1vbi5oYXNIb29rKHRoaXMuXy5hZnRlckVhY2gsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5hZnRlckFsbGAgb3IgYHJlZmxlY3QuYWZ0ZXJBbGxgLlxuICAgICAqL1xuICAgIGhhc0FmdGVyQWxsOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBDb21tb24uaGFzSG9vayh0aGlzLl8uYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5iZWZvcmVgIG9yIGByZWZsZWN0LmJlZm9yZWAuXG4gICAgICovXG4gICAgcmVtb3ZlQmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5iZWZvcmVFYWNoID0gQ29tbW9uLnJlbW92ZUhvb2sodGhpcy5fLmJlZm9yZUVhY2gsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5iZWZvcmVBbGxgIG9yIGByZWZsZWN0LmJlZm9yZUFsbGAuXG4gICAgICovXG4gICAgcmVtb3ZlQmVmb3JlQWxsOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5iZWZvcmVBbGwgPSBDb21tb24ucmVtb3ZlSG9vayh0aGlzLl8uYmVmb3JlQWxsLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgaG9vayBwcmV2aW91c2x5IGFkZGVkIHdpdGggYHQuYWZ0ZXJgIG9yYHJlZmxlY3QuYWZ0ZXJgLlxuICAgICAqL1xuICAgIHJlbW92ZUFmdGVyOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5hZnRlckVhY2ggPSBDb21tb24ucmVtb3ZlSG9vayh0aGlzLl8uYWZ0ZXJFYWNoLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgaG9vayBwcmV2aW91c2x5IGFkZGVkIHdpdGggYHQuYWZ0ZXJBbGxgIG9yIGByZWZsZWN0LmFmdGVyQWxsYC5cbiAgICAgKi9cbiAgICByZW1vdmVBZnRlckFsbDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl8uYWZ0ZXJBbGwgPSBDb21tb24ucmVtb3ZlSG9vayh0aGlzLl8uYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBibG9jayBvciBpbmxpbmUgdGVzdC5cbiAgICAgKi9cbiAgICB0ZXN0OiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYG5hbWVgIHRvIGJlIGEgc3RyaW5nXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgVGVzdHMuYWRkTm9ybWFsKHRoaXMuXy5yb290LmN1cnJlbnQsIG5hbWUsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBza2lwcGVkIGJsb2NrIG9yIGlubGluZSB0ZXN0LlxuICAgICAqL1xuICAgIHRlc3RTa2lwOiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYG5hbWVgIHRvIGJlIGEgc3RyaW5nXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgVGVzdHMuYWRkU2tpcHBlZCh0aGlzLl8ucm9vdC5jdXJyZW50LCBuYW1lKVxuICAgIH0sXG59KVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIG1ldGhvZHMgPSByZXF1aXJlKFwiLi4vbWV0aG9kc1wiKVxudmFyIFRlc3RzID0gcmVxdWlyZShcIi4uL2NvcmUvdGVzdHNcIilcbnZhciBGaWx0ZXIgPSByZXF1aXJlKFwiLi4vY29yZS9maWx0ZXJcIilcbnZhciBDb21tb24gPSByZXF1aXJlKFwiLi9jb21tb25cIilcbnZhciBSZWZsZWN0ID0gcmVxdWlyZShcIi4vcmVmbGVjdFwiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IFRoYWxsaXVtXG5mdW5jdGlvbiBUaGFsbGl1bSgpIHtcbiAgICB0aGlzLl8gPSBUZXN0cy5jcmVhdGVSb290KClcbn1cblxubWV0aG9kcyhUaGFsbGl1bSwge1xuICAgIC8qKlxuICAgICAqIENhbGwgYSBwbHVnaW4gYW5kIHJldHVybiB0aGUgcmVzdWx0LiBUaGUgcGx1Z2luIGlzIGNhbGxlZCB3aXRoIGEgUmVmbGVjdFxuICAgICAqIGluc3RhbmNlIGZvciBhY2Nlc3MgdG8gcGxlbnR5IG9mIHBvdGVudGlhbGx5IHVzZWZ1bCBpbnRlcm5hbCBkZXRhaWxzLlxuICAgICAqL1xuICAgIGNhbGw6IGZ1bmN0aW9uIChwbHVnaW4sIGFyZykge1xuICAgICAgICB2YXIgcmVmbGVjdCA9IG5ldyBSZWZsZWN0KHRoaXMuXy5yb290LmN1cnJlbnQpXG5cbiAgICAgICAgcmV0dXJuIHBsdWdpbi5jYWxsKHJlZmxlY3QsIHJlZmxlY3QsIGFyZylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogV2hpdGVsaXN0IHNwZWNpZmljIHRlc3RzLCB1c2luZyBhcnJheS1iYXNlZCBzZWxlY3RvcnMgd2hlcmUgZWFjaCBlbnRyeVxuICAgICAqIGlzIGVpdGhlciBhIHN0cmluZyBvciByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICovXG4gICAgb25seTogZnVuY3Rpb24gKC8qIC4uLnNlbGVjdG9ycyAqLykge1xuICAgICAgICB0aGlzLl8ucm9vdC5jdXJyZW50Lm9ubHkgPSBGaWx0ZXIuY3JlYXRlLmFwcGx5KHVuZGVmaW5lZCwgYXJndW1lbnRzKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSByZXBvcnRlci5cbiAgICAgKi9cbiAgICByZXBvcnRlcjogZnVuY3Rpb24gKHJlcG9ydGVyLCBhcmcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXBvcnRlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHJlcG9ydGVyYCB0byBiZSBhIGZ1bmN0aW9uLlwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJvb3QgPSB0aGlzLl8ucm9vdFxuXG4gICAgICAgIGlmIChyb290LmN1cnJlbnQgIT09IHJvb3QpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlcG9ydGVycyBtYXkgb25seSBiZSBhZGRlZCB0byB0aGUgcm9vdC5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXN1bHQgPSByZXBvcnRlcihhcmcpXG5cbiAgICAgICAgLy8gRG9uJ3QgYXNzdW1lIGl0J3MgYSBmdW5jdGlvbi4gVmVyaWZ5IGl0IGFjdHVhbGx5IGlzLCBzbyB3ZSBkb24ndCBoYXZlXG4gICAgICAgIC8vIGluZXhwbGljYWJsZSB0eXBlIGVycm9ycyBpbnRlcm5hbGx5IGFmdGVyIGl0J3MgaW52b2tlZCwgYW5kIHNvIHVzZXJzXG4gICAgICAgIC8vIHdvbid0IGdldCB0b28gY29uZnVzZWQuXG4gICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJFeHBlY3RlZCBgcmVwb3J0ZXJgIHRvIHJldHVybiBhIGZ1bmN0aW9uLiBDaGVjayB3aXRoIHRoZSBcIiArXG4gICAgICAgICAgICAgICAgXCJyZXBvcnRlcidzIGF1dGhvciwgYW5kIGhhdmUgdGhlbSBmaXggdGhlaXIgcmVwb3J0ZXIuXCIpXG4gICAgICAgIH1cblxuICAgICAgICByb290LnJlcG9ydGVyID0gcmVzdWx0XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIHRoaXMgaGFzIGEgcmVwb3J0ZXIuXG4gICAgICovXG4gICAgZ2V0IGhhc1JlcG9ydGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QucmVwb3J0ZXIgIT0gbnVsbFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgdGltZW91dC4gMCBtZWFucyBpbmhlcml0IHRoZSBwYXJlbnQncywgYW5kIGBJbmZpbml0eWBcbiAgICAgKiBtZWFucyBpdCdzIGRpc2FibGVkLlxuICAgICAqL1xuICAgIGdldCB0aW1lb3V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QuY3VycmVudC50aW1lb3V0IHx8IFRlc3RzLmRlZmF1bHRUaW1lb3V0XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgdGltZW91dCBpbiBtaWxsaXNlY29uZHMsIHJvdW5kaW5nIG5lZ2F0aXZlcyB0byAwLiBTZXR0aW5nIHRoZVxuICAgICAqIHRpbWVvdXQgdG8gMCBtZWFucyB0byBpbmhlcml0IHRoZSBwYXJlbnQgdGltZW91dCwgYW5kIHNldHRpbmcgaXQgdG9cbiAgICAgKiBgSW5maW5pdHlgIGRpc2FibGVzIGl0LlxuICAgICAqL1xuICAgIHNldCB0aW1lb3V0KHRpbWVvdXQpIHtcbiAgICAgICAgdGhpcy5fLnJvb3QuY3VycmVudC50aW1lb3V0ID0gTWF0aC5mbG9vcihNYXRoLm1heCgrdGltZW91dCwgMCkpXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VycmVudCBzbG93IHRocmVzaG9sZC4gMCBtZWFucyBpbmhlcml0IHRoZSBwYXJlbnQncywgYW5kXG4gICAgICogYEluZmluaXR5YCBtZWFucyBpdCdzIGRpc2FibGVkLlxuICAgICAqL1xuICAgIGdldCBzbG93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QuY3VycmVudC5zbG93IHx8IFRlc3RzLmRlZmF1bHRTbG93XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgc2xvdyB0aHJlc2hvbGQgaW4gbWlsbGlzZWNvbmRzLCByb3VuZGluZyBuZWdhdGl2ZXMgdG8gMC4gU2V0dGluZ1xuICAgICAqIHRoZSB0aW1lb3V0IHRvIDAgbWVhbnMgdG8gaW5oZXJpdCB0aGUgcGFyZW50IHRocmVzaG9sZCwgYW5kIHNldHRpbmcgaXQgdG9cbiAgICAgKiBgSW5maW5pdHlgIGRpc2FibGVzIGl0LlxuICAgICAqL1xuICAgIHNldCBzbG93KHNsb3cpIHtcbiAgICAgICAgdGhpcy5fLnJvb3QuY3VycmVudC5zbG93ID0gTWF0aC5mbG9vcihNYXRoLm1heCgrc2xvdywgMCkpXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VycmVudCBhdHRlbXB0IGNvdW50LiBgMGAgbWVhbnMgaW5oZXJpdCB0aGUgcGFyZW50J3MuXG4gICAgICovXG4gICAgZ2V0IGF0dGVtcHRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QuY3VycmVudC5hdHRlbXB0c1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIG51bWJlciBvZiBhdHRlbXB0cyBhbGxvd2VkLCByb3VuZGluZyBuZWdhdGl2ZXMgdG8gMC4gU2V0dGluZyB0aGVcbiAgICAgKiBjb3VudCB0byBgMGAgbWVhbnMgdG8gaW5oZXJpdCB0aGUgcGFyZW50IHJldHJ5IGNvdW50LlxuICAgICAqL1xuICAgIHNldCBhdHRlbXB0cyhhdHRlbXB0cykge1xuICAgICAgICAvLyBUaGlzIGlzIGRvbmUgZGlmZmVyZW50bHkgdG8gYXZvaWQgYSBtYXNzaXZlIHBlcmZvcm1hbmNlIHBlbmFsdHkuXG4gICAgICAgIHZhciBjYWxjdWxhdGVkID0gTWF0aC5mbG9vcihNYXRoLm1heChhdHRlbXB0cywgMCkpXG4gICAgICAgIHZhciB0ZXN0ID0gdGhpcy5fLnJvb3QuY3VycmVudFxuXG4gICAgICAgIHRlc3QuYXR0ZW1wdHMgPSBjYWxjdWxhdGVkIHx8IHRlc3QucGFyZW50LmF0dGVtcHRzXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB3aGV0aGVyIHRoaXMgdGVzdCBpcyBmYWlsYWJsZS5cbiAgICAgKi9cbiAgICBnZXQgaXNGYWlsYWJsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuXy5yb290LmN1cnJlbnQuaXNGYWlsYWJsZVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgd2hldGhlciB0aGlzIHRlc3QgaXMgZmFpbGFibGUuXG4gICAgICovXG4gICAgc2V0IGlzRmFpbGFibGUoaXNGYWlsYWJsZSkge1xuICAgICAgICB0aGlzLl8ucm9vdC5jdXJyZW50LmlzRmFpbGFibGUgPSAhIWlzRmFpbGFibGVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUnVuIHRoZSB0ZXN0cyAob3IgdGhlIHRlc3QncyB0ZXN0cyBpZiBpdCdzIG5vdCBhIGJhc2UgaW5zdGFuY2UpLlxuICAgICAqL1xuICAgIHJ1bjogZnVuY3Rpb24gKG9wdHMpIHtcbiAgICAgICAgaWYgKHRoaXMuXy5yb290ICE9PSB0aGlzLl8pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBcIk9ubHkgdGhlIHJvb3QgdGVzdCBjYW4gYmUgcnVuIC0gSWYgeW91IG9ubHkgd2FudCB0byBydW4gYSBcIiArXG4gICAgICAgICAgICAgICAgXCJzdWJ0ZXN0LCB1c2UgYHQub25seShbXFxcInNlbGVjdG9yMVxcXCIsIC4uLl0pYCBpbnN0ZWFkLlwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuXy5sb2NrZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IHJ1biB3aGlsZSB0ZXN0cyBhcmUgYWxyZWFkeSBydW5uaW5nLlwiKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFRlc3RzLnJ1blRlc3QodGhpcy5fLCBvcHRzKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSB0ZXN0LlxuICAgICAqL1xuICAgIHRlc3Q6IGZ1bmN0aW9uIChuYW1lLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBgbmFtZWAgdG8gYmUgYSBzdHJpbmdcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICBUZXN0cy5hZGROb3JtYWwodGhpcy5fLnJvb3QuY3VycmVudCwgbmFtZSwgY2FsbGJhY2spXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEFkZCBhIHNraXBwZWQgdGVzdC5cbiAgICAgKi9cbiAgICB0ZXN0U2tpcDogZnVuY3Rpb24gKG5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBuYW1lYCB0byBiZSBhIHN0cmluZ1wiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIFRlc3RzLmFkZFNraXBwZWQodGhpcy5fLnJvb3QuY3VycmVudCwgbmFtZSlcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2xlYXIgYWxsIGV4aXN0aW5nIHRlc3RzLlxuICAgICAqL1xuICAgIGNsZWFyVGVzdHM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuXy5yb290ICE9PSB0aGlzLl8pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRlc3RzIG1heSBvbmx5IGJlIGNsZWFyZWQgYXQgdGhlIHJvb3QuXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fLmxvY2tlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgY2xlYXIgdGVzdHMgd2hpbGUgdGhleSBhcmUgcnVubmluZy5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIFRlc3RzLmNsZWFyVGVzdHModGhpcy5fKVxuICAgIH0sXG5cbiAgICBiZWZvcmU6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHRlc3QgPSB0aGlzLl8ucm9vdC5jdXJyZW50XG5cbiAgICAgICAgdGVzdC5iZWZvcmVFYWNoID0gQ29tbW9uLmFkZEhvb2sodGVzdC5iZWZvcmVFYWNoLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgYmVmb3JlQWxsOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0ZXN0ID0gdGhpcy5fLnJvb3QuY3VycmVudFxuXG4gICAgICAgIHRlc3QuYmVmb3JlQWxsID0gQ29tbW9uLmFkZEhvb2sodGVzdC5iZWZvcmVBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICBhZnRlcjogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdGVzdCA9IHRoaXMuXy5yb290LmN1cnJlbnRcblxuICAgICAgICB0ZXN0LmFmdGVyRWFjaCA9IENvbW1vbi5hZGRIb29rKHRlc3QuYWZ0ZXJFYWNoLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgYWZ0ZXJBbGw6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHRlc3QgPSB0aGlzLl8ucm9vdC5jdXJyZW50XG5cbiAgICAgICAgdGVzdC5hZnRlckFsbCA9IENvbW1vbi5hZGRIb29rKHRlc3QuYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG59KVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLyoqXG4gKiBUaGlzIGlzIHRoZSBlbnRyeSBwb2ludCBmb3IgdGhlIEJyb3dzZXJpZnkgYnVuZGxlLiBOb3RlIHRoYXQgaXQgKmFsc28qIHdpbGxcbiAqIHJ1biBhcyBwYXJ0IG9mIHRoZSB0ZXN0cyBpbiBOb2RlICh1bmJ1bmRsZWQpLCBhbmQgaXQgdGhlb3JldGljYWxseSBjb3VsZCBiZVxuICogcnVuIGluIE5vZGUgb3IgYSBydW50aW1lIGxpbWl0ZWQgdG8gb25seSBFUzUgc3VwcG9ydCAoZS5nLiBSaGlubywgTmFzaG9ybiwgb3JcbiAqIGVtYmVkZGVkIFY4KSwgc28gZG8gKm5vdCogYXNzdW1lIGJyb3dzZXIgZ2xvYmFscyBhcmUgcHJlc2VudC5cbiAqL1xuXG5leHBvcnRzLnQgPSByZXF1aXJlKFwiLi4vaW5kZXhcIilcbmV4cG9ydHMuYXNzZXJ0ID0gcmVxdWlyZShcIi4uL2Fzc2VydFwiKVxuZXhwb3J0cy5yID0gcmVxdWlyZShcIi4uL3JcIilcbnZhciBkb20gPSByZXF1aXJlKFwiLi4vZG9tXCIpXG5cbmV4cG9ydHMuZG9tID0gZG9tLmNyZWF0ZVxuLy8gaWYgKGdsb2JhbC5kb2N1bWVudCAhPSBudWxsICYmIGdsb2JhbC5kb2N1bWVudC5jdXJyZW50U2NyaXB0ICE9IG51bGwpIHtcbi8vICAgICBkb20uYXV0b2xvYWQoZ2xvYmFsLmRvY3VtZW50LmN1cnJlbnRTY3JpcHQpXG4vLyB9XG5cbnZhciBJbnRlcm5hbCA9IHJlcXVpcmUoXCIuLi9pbnRlcm5hbFwiKVxuXG5leHBvcnRzLnJvb3QgPSBJbnRlcm5hbC5yb290XG5leHBvcnRzLnJlcG9ydHMgPSBJbnRlcm5hbC5yZXBvcnRzXG5leHBvcnRzLmhvb2tFcnJvcnMgPSBJbnRlcm5hbC5ob29rRXJyb3JzXG5leHBvcnRzLmxvY2F0aW9uID0gSW50ZXJuYWwubG9jYXRpb25cblxuLy8gSW4gY2FzZSB0aGUgdXNlciBuZWVkcyB0byBhZGp1c3QgdGhpcyAoZS5nLiBOYXNob3JuICsgY29uc29sZSBvdXRwdXQpLlxudmFyIFNldHRpbmdzID0gcmVxdWlyZShcIi4vc2V0dGluZ3NcIilcblxuZXhwb3J0cy5zZXR0aW5ncyA9IHtcbiAgICB3aW5kb3dXaWR0aDoge1xuICAgICAgICBnZXQ6IFNldHRpbmdzLndpbmRvd1dpZHRoLFxuICAgICAgICBzZXQ6IFNldHRpbmdzLnNldFdpbmRvd1dpZHRoLFxuICAgIH0sXG5cbiAgICBuZXdsaW5lOiB7XG4gICAgICAgIGdldDogU2V0dGluZ3MubmV3bGluZSxcbiAgICAgICAgc2V0OiBTZXR0aW5ncy5zZXROZXdsaW5lLFxuICAgIH0sXG5cbiAgICBzeW1ib2xzOiB7XG4gICAgICAgIGdldDogU2V0dGluZ3Muc3ltYm9scyxcbiAgICAgICAgc2V0OiBTZXR0aW5ncy5zZXRTeW1ib2xzLFxuICAgIH0sXG5cbiAgICBkZWZhdWx0T3B0czoge1xuICAgICAgICBnZXQ6IFNldHRpbmdzLmRlZmF1bHRPcHRzLFxuICAgICAgICBzZXQ6IFNldHRpbmdzLnNldERlZmF1bHRPcHRzLFxuICAgIH0sXG5cbiAgICBjb2xvclN1cHBvcnQ6IHtcbiAgICAgICAgZ2V0OiBTZXR0aW5ncy5Db2xvcnMuZ2V0U3VwcG9ydCxcbiAgICAgICAgc2V0OiBTZXR0aW5ncy5Db2xvcnMuc2V0U3VwcG9ydCxcbiAgICB9LFxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLyoqXG4gKiBUaGUgZmlsdGVyIGlzIGFjdHVhbGx5IHN0b3JlZCBhcyBhIHRyZWUgZm9yIGZhc3RlciBsb29rdXAgdGltZXMgd2hlbiB0aGVyZVxuICogYXJlIG11bHRpcGxlIHNlbGVjdG9ycy4gT2JqZWN0cyBjYW4ndCBiZSB1c2VkIGZvciB0aGUgbm9kZXMsIHdoZXJlIGtleXNcbiAqIHJlcHJlc2VudCB2YWx1ZXMgYW5kIHZhbHVlcyByZXByZXNlbnQgY2hpbGRyZW4sIGJlY2F1c2UgcmVndWxhciBleHByZXNzaW9uc1xuICogYXJlbid0IHBvc3NpYmxlIHRvIHVzZS5cbiAqL1xuXG5mdW5jdGlvbiBpc0VxdWl2YWxlbnQoZW50cnksIGl0ZW0pIHtcbiAgICBpZiAodHlwZW9mIGVudHJ5ID09PSBcInN0cmluZ1wiICYmIHR5cGVvZiBpdGVtID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHJldHVybiBlbnRyeSA9PT0gaXRlbVxuICAgIH0gZWxzZSBpZiAoZW50cnkgaW5zdGFuY2VvZiBSZWdFeHAgJiYgaXRlbSBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICByZXR1cm4gZW50cnkudG9TdHJpbmcoKSA9PT0gaXRlbS50b1N0cmluZygpXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYXRjaGVzKGVudHJ5LCBpdGVtKSB7XG4gICAgaWYgKHR5cGVvZiBlbnRyeSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICByZXR1cm4gZW50cnkgPT09IGl0ZW1cbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZW50cnkudGVzdChpdGVtKVxuICAgIH1cbn1cblxuZnVuY3Rpb24gRmlsdGVyKHZhbHVlKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlXG4gICAgdGhpcy5jaGlsZHJlbiA9IHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBmaW5kRXF1aXZhbGVudChub2RlLCBlbnRyeSkge1xuICAgIGlmIChub2RlLmNoaWxkcmVuID09IG51bGwpIHJldHVybiB1bmRlZmluZWRcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY2hpbGQgPSBub2RlLmNoaWxkcmVuW2ldXG5cbiAgICAgICAgaWYgKGlzRXF1aXZhbGVudChjaGlsZC52YWx1ZSwgZW50cnkpKSByZXR1cm4gY2hpbGRcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIGZpbmRNYXRjaGVzKG5vZGUsIGVudHJ5KSB7XG4gICAgaWYgKG5vZGUuY2hpbGRyZW4gPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjaGlsZCA9IG5vZGUuY2hpbGRyZW5baV1cblxuICAgICAgICBpZiAobWF0Y2hlcyhjaGlsZC52YWx1ZSwgZW50cnkpKSByZXR1cm4gY2hpbGRcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogQ3JlYXRlIGEgZmlsdGVyIGZyb20gYSBudW1iZXIgb2Ygc2VsZWN0b3JzXG4gKi9cbmV4cG9ydHMuY3JlYXRlID0gZnVuY3Rpb24gKC8qIC4uLnNlbGVjdG9ycyAqLykge1xuICAgIHZhciBmaWx0ZXIgPSBuZXcgRmlsdGVyKClcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBzZWxlY3RvciA9IGFyZ3VtZW50c1tpXVxuXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShzZWxlY3RvcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJFeHBlY3RlZCBzZWxlY3RvciBcIiArIGkgKyBcIiB0byBiZSBhbiBhcnJheVwiKVxuICAgICAgICB9XG5cbiAgICAgICAgZmlsdGVyQWRkU2luZ2xlKGZpbHRlciwgc2VsZWN0b3IsIGkpXG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbHRlclxufVxuXG5mdW5jdGlvbiBmaWx0ZXJBZGRTaW5nbGUobm9kZSwgc2VsZWN0b3IsIGluZGV4KSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWxlY3Rvci5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgZW50cnkgPSBzZWxlY3RvcltpXVxuXG4gICAgICAgIC8vIFN0cmluZ3MgYW5kIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYXJlIHRoZSBvbmx5IHRoaW5ncyBhbGxvd2VkLlxuICAgICAgICBpZiAodHlwZW9mIGVudHJ5ICE9PSBcInN0cmluZ1wiICYmICEoZW50cnkgaW5zdGFuY2VvZiBSZWdFeHApKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgICAgIFwiU2VsZWN0b3IgXCIgKyBpbmRleCArIFwiIG11c3QgY29uc2lzdCBvZiBvbmx5IHN0cmluZ3MgYW5kL29yIFwiICtcbiAgICAgICAgICAgICAgICBcInJlZ3VsYXIgZXhwcmVzc2lvbnNcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjaGlsZCA9IGZpbmRFcXVpdmFsZW50KG5vZGUsIGVudHJ5KVxuXG4gICAgICAgIGlmIChjaGlsZCA9PSBudWxsKSB7XG4gICAgICAgICAgICBjaGlsZCA9IG5ldyBGaWx0ZXIoZW50cnkpXG4gICAgICAgICAgICBpZiAobm9kZS5jaGlsZHJlbiA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IFtjaGlsZF1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbi5wdXNoKGNoaWxkKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbm9kZSA9IGNoaWxkXG4gICAgfVxufVxuXG5leHBvcnRzLnRlc3QgPSBmdW5jdGlvbiAoZmlsdGVyLCBwYXRoKSB7XG4gICAgdmFyIGxlbmd0aCA9IHBhdGgubGVuZ3RoXG5cbiAgICB3aGlsZSAobGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIGZpbHRlciA9IGZpbmRNYXRjaGVzKGZpbHRlciwgcGF0aFstLWxlbmd0aF0pXG4gICAgICAgIGlmIChmaWx0ZXIgPT0gbnVsbCkgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcblxuLyoqXG4gKiBBbGwgdGhlIHJlcG9ydCB0eXBlcy4gVGhlIG9ubHkgcmVhc29uIHRoZXJlIGFyZSBtb3JlIHRoYW4gdHdvIHR5cGVzIChub3JtYWxcbiAqIGFuZCBob29rKSBpcyBmb3IgdGhlIHVzZXIncyBiZW5lZml0IChkZXYgdG9vbHMsIGB1dGlsLmluc3BlY3RgLCBldGMuKVxuICovXG5cbnZhciBUeXBlcyA9IGV4cG9ydHMuVHlwZXMgPSBPYmplY3QuZnJlZXplKHtcbiAgICBTdGFydDogMCxcbiAgICBFbnRlcjogMSxcbiAgICBMZWF2ZTogMixcbiAgICBQYXNzOiAzLFxuICAgIEZhaWw6IDQsXG4gICAgU2tpcDogNSxcbiAgICBFbmQ6IDYsXG4gICAgRXJyb3I6IDcsXG5cbiAgICAvLyBOb3RlIHRoYXQgYEhvb2tgIGlzIGFjdHVhbGx5IGEgYml0IGZsYWcsIHRvIHNhdmUgc29tZSBzcGFjZSAoYW5kIHRvXG4gICAgLy8gc2ltcGxpZnkgdGhlIHR5cGUgcmVwcmVzZW50YXRpb24pLlxuICAgIEhvb2s6IDgsXG59KVxuXG52YXIgSG9va1N0YWdlID0gZXhwb3J0cy5Ib29rU3RhZ2UgPSBPYmplY3QuZnJlZXplKHtcbiAgICBCZWZvcmVBbGw6IFR5cGVzLkhvb2sgfCAwLFxuICAgIEJlZm9yZUVhY2g6IFR5cGVzLkhvb2sgfCAxLFxuICAgIEFmdGVyRWFjaDogVHlwZXMuSG9vayB8IDIsXG4gICAgQWZ0ZXJBbGw6IFR5cGVzLkhvb2sgfCAzLFxufSlcblxuZXhwb3J0cy5SZXBvcnQgPSBSZXBvcnRcbmZ1bmN0aW9uIFJlcG9ydCh0eXBlKSB7XG4gICAgdGhpcy5fID0gdHlwZVxufVxuXG4vLyBBdm9pZCBhIHJlY3Vyc2l2ZSBjYWxsIHdoZW4gYGluc3BlY3RgaW5nIGEgcmVzdWx0IHdoaWxlIHN0aWxsIGtlZXBpbmcgaXRcbi8vIHN0eWxlZCBsaWtlIGl0IHdvdWxkIGJlIG5vcm1hbGx5LiBFYWNoIHR5cGUgdXNlcyBhIG5hbWVkIHNpbmdsZXRvbiBmYWN0b3J5IHRvXG4vLyBlbnN1cmUgZW5naW5lcyBzaG93IHRoZSBjb3JyZWN0IGBuYW1lYC9gZGlzcGxheU5hbWVgIGZvciB0aGUgdHlwZS5cbmZ1bmN0aW9uIGluaXRJbnNwZWN0KGluc3BlY3QsIHJlcG9ydCkge1xuICAgIHZhciB0eXBlID0gcmVwb3J0Ll9cblxuICAgIGlmICh0eXBlICYgVHlwZXMuSG9vaykge1xuICAgICAgICBpbnNwZWN0LnN0YWdlID0gcmVwb3J0LnN0YWdlXG4gICAgfVxuXG4gICAgaWYgKHR5cGUgIT09IFR5cGVzLlN0YXJ0ICYmXG4gICAgICAgICAgICB0eXBlICE9PSBUeXBlcy5FbmQgJiZcbiAgICAgICAgICAgIHR5cGUgIT09IFR5cGVzLkVycm9yKSB7XG4gICAgICAgIGluc3BlY3QucGF0aCA9IHJlcG9ydC5wYXRoXG4gICAgfVxuXG4gICAgaWYgKHR5cGUgJiBUeXBlcy5Ib29rKSB7XG4gICAgICAgIGluc3BlY3Qucm9vdFBhdGggPSByZXBvcnQucm9vdFBhdGhcbiAgICB9XG5cbiAgICAvLyBPbmx5IGFkZCB0aGUgcmVsZXZhbnQgcHJvcGVydGllc1xuICAgIGlmICh0eXBlID09PSBUeXBlcy5GYWlsIHx8XG4gICAgICAgICAgICB0eXBlID09PSBUeXBlcy5FcnJvciB8fFxuICAgICAgICAgICAgdHlwZSAmIFR5cGVzLkhvb2spIHtcbiAgICAgICAgaW5zcGVjdC52YWx1ZSA9IHJlcG9ydC52YWx1ZVxuICAgIH1cblxuICAgIGlmICh0eXBlID09PSBUeXBlcy5FbnRlciB8fFxuICAgICAgICAgICAgdHlwZSA9PT0gVHlwZXMuUGFzcyB8fFxuICAgICAgICAgICAgdHlwZSA9PT0gVHlwZXMuRmFpbCkge1xuICAgICAgICBpbnNwZWN0LmR1cmF0aW9uID0gcmVwb3J0LmR1cmF0aW9uXG4gICAgICAgIGluc3BlY3Quc2xvdyA9IHJlcG9ydC5zbG93XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09IFR5cGVzLkZhaWwpIHtcbiAgICAgICAgaW5zcGVjdC5pc0ZhaWxhYmxlID0gcmVwb3J0LmlzRmFpbGFibGVcbiAgICB9XG59XG5cbm1ldGhvZHMoUmVwb3J0LCB7XG4gICAgLy8gVGhlIHJlcG9ydCB0eXBlc1xuICAgIGdldCBpc1N0YXJ0KCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5TdGFydCB9LFxuICAgIGdldCBpc0VudGVyKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5FbnRlciB9LFxuICAgIGdldCBpc0xlYXZlKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5MZWF2ZSB9LFxuICAgIGdldCBpc1Bhc3MoKSB7IHJldHVybiB0aGlzLl8gPT09IFR5cGVzLlBhc3MgfSxcbiAgICBnZXQgaXNGYWlsKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5GYWlsIH0sXG4gICAgZ2V0IGlzU2tpcCgpIHsgcmV0dXJuIHRoaXMuXyA9PT0gVHlwZXMuU2tpcCB9LFxuICAgIGdldCBpc0VuZCgpIHsgcmV0dXJuIHRoaXMuXyA9PT0gVHlwZXMuRW5kIH0sXG4gICAgZ2V0IGlzRXJyb3IoKSB7IHJldHVybiB0aGlzLl8gPT09IFR5cGVzLkVycm9yIH0sXG4gICAgZ2V0IGlzSG9vaygpIHsgcmV0dXJuICh0aGlzLl8gJiBUeXBlcy5Ib29rKSAhPT0gMCB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IGEgc3RyaW5naWZpZWQgZGVzY3JpcHRpb24gb2YgdGhlIHR5cGUuXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHN3aXRjaCAodGhpcy5fKSB7XG4gICAgICAgIGNhc2UgVHlwZXMuU3RhcnQ6IHJldHVybiBcInN0YXJ0XCJcbiAgICAgICAgY2FzZSBUeXBlcy5FbnRlcjogcmV0dXJuIFwiZW50ZXJcIlxuICAgICAgICBjYXNlIFR5cGVzLkxlYXZlOiByZXR1cm4gXCJsZWF2ZVwiXG4gICAgICAgIGNhc2UgVHlwZXMuUGFzczogcmV0dXJuIFwicGFzc1wiXG4gICAgICAgIGNhc2UgVHlwZXMuRmFpbDogcmV0dXJuIFwiZmFpbFwiXG4gICAgICAgIGNhc2UgVHlwZXMuU2tpcDogcmV0dXJuIFwic2tpcFwiXG4gICAgICAgIGNhc2UgVHlwZXMuRW5kOiByZXR1cm4gXCJlbmRcIlxuICAgICAgICBjYXNlIFR5cGVzLkVycm9yOiByZXR1cm4gXCJlcnJvclwiXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAodGhpcy5fICYgVHlwZXMuSG9vaykgcmV0dXJuIFwiaG9va1wiXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnJlYWNoYWJsZVwiKVxuICAgICAgICB9XG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuU3RhcnQgPSBTdGFydFJlcG9ydFxuZnVuY3Rpb24gU3RhcnRSZXBvcnQoKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuU3RhcnQpXG59XG5tZXRob2RzKFN0YXJ0UmVwb3J0LCBSZXBvcnQsIHtcbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gUmVwb3J0KHJlcG9ydCkge1xuICAgICAgICAgICAgaW5pdEluc3BlY3QodGhpcywgcmVwb3J0KVxuICAgICAgICB9KHRoaXMpXG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuRW50ZXIgPSBFbnRlclJlcG9ydFxuZnVuY3Rpb24gRW50ZXJSZXBvcnQocGF0aCwgZHVyYXRpb24sIHNsb3cpIHtcbiAgICBSZXBvcnQuY2FsbCh0aGlzLCBUeXBlcy5FbnRlcilcbiAgICB0aGlzLnBhdGggPSBwYXRoXG4gICAgdGhpcy5kdXJhdGlvbiA9IGR1cmF0aW9uXG4gICAgdGhpcy5zbG93ID0gc2xvd1xufVxubWV0aG9kcyhFbnRlclJlcG9ydCwgUmVwb3J0LCB7XG4gICAgLyoqXG4gICAgICogU28gdXRpbC5pbnNwZWN0IHByb3ZpZGVzIG1vcmUgc2Vuc2libGUgb3V0cHV0IGZvciB0ZXN0aW5nL2V0Yy5cbiAgICAgKi9cbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gRW50ZXJSZXBvcnQocmVwb3J0KSB7XG4gICAgICAgICAgICBpbml0SW5zcGVjdCh0aGlzLCByZXBvcnQpXG4gICAgICAgIH0odGhpcylcbiAgICB9LFxufSlcblxuZXhwb3J0cy5MZWF2ZSA9IExlYXZlUmVwb3J0XG5mdW5jdGlvbiBMZWF2ZVJlcG9ydChwYXRoKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuTGVhdmUpXG4gICAgdGhpcy5wYXRoID0gcGF0aFxufVxubWV0aG9kcyhMZWF2ZVJlcG9ydCwgUmVwb3J0LCB7XG4gICAgLyoqXG4gICAgICogU28gdXRpbC5pbnNwZWN0IHByb3ZpZGVzIG1vcmUgc2Vuc2libGUgb3V0cHV0IGZvciB0ZXN0aW5nL2V0Yy5cbiAgICAgKi9cbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gTGVhdmVSZXBvcnQocmVwb3J0KSB7XG4gICAgICAgICAgICBpbml0SW5zcGVjdCh0aGlzLCByZXBvcnQpXG4gICAgICAgIH0odGhpcylcbiAgICB9LFxufSlcblxuZXhwb3J0cy5QYXNzID0gUGFzc1JlcG9ydFxuZnVuY3Rpb24gUGFzc1JlcG9ydChwYXRoLCBkdXJhdGlvbiwgc2xvdykge1xuICAgIFJlcG9ydC5jYWxsKHRoaXMsIFR5cGVzLlBhc3MpXG4gICAgdGhpcy5wYXRoID0gcGF0aFxuICAgIHRoaXMuZHVyYXRpb24gPSBkdXJhdGlvblxuICAgIHRoaXMuc2xvdyA9IHNsb3dcbn1cbm1ldGhvZHMoUGFzc1JlcG9ydCwgUmVwb3J0LCB7XG4gICAgLyoqXG4gICAgICogU28gdXRpbC5pbnNwZWN0IHByb3ZpZGVzIG1vcmUgc2Vuc2libGUgb3V0cHV0IGZvciB0ZXN0aW5nL2V0Yy5cbiAgICAgKi9cbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gUGFzc1JlcG9ydChyZXBvcnQpIHtcbiAgICAgICAgICAgIGluaXRJbnNwZWN0KHRoaXMsIHJlcG9ydClcbiAgICAgICAgfSh0aGlzKVxuICAgIH0sXG59KVxuXG5leHBvcnRzLkZhaWwgPSBGYWlsUmVwb3J0XG5mdW5jdGlvbiBGYWlsUmVwb3J0KHBhdGgsIGVycm9yLCBkdXJhdGlvbiwgc2xvdywgaXNGYWlsYWJsZSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICBSZXBvcnQuY2FsbCh0aGlzLCBUeXBlcy5GYWlsKVxuICAgIHRoaXMucGF0aCA9IHBhdGhcbiAgICB0aGlzLmVycm9yID0gZXJyb3JcbiAgICB0aGlzLmR1cmF0aW9uID0gZHVyYXRpb25cbiAgICB0aGlzLnNsb3cgPSBzbG93XG4gICAgdGhpcy5pc0ZhaWxhYmxlID0gaXNGYWlsYWJsZVxufVxubWV0aG9kcyhGYWlsUmVwb3J0LCBSZXBvcnQsIHtcbiAgICAvKipcbiAgICAgKiBTbyB1dGlsLmluc3BlY3QgcHJvdmlkZXMgbW9yZSBzZW5zaWJsZSBvdXRwdXQgZm9yIHRlc3RpbmcvZXRjLlxuICAgICAqL1xuICAgIGluc3BlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBmdW5jdGlvbiBGYWlsUmVwb3J0KHJlcG9ydCkge1xuICAgICAgICAgICAgaW5pdEluc3BlY3QodGhpcywgcmVwb3J0KVxuICAgICAgICB9KHRoaXMpXG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuU2tpcCA9IFNraXBSZXBvcnRcbmZ1bmN0aW9uIFNraXBSZXBvcnQocGF0aCkge1xuICAgIFJlcG9ydC5jYWxsKHRoaXMsIFR5cGVzLlNraXApXG4gICAgdGhpcy5wYXRoID0gcGF0aFxufVxubWV0aG9kcyhTa2lwUmVwb3J0LCBSZXBvcnQsIHtcbiAgICAvKipcbiAgICAgKiBTbyB1dGlsLmluc3BlY3QgcHJvdmlkZXMgbW9yZSBzZW5zaWJsZSBvdXRwdXQgZm9yIHRlc3RpbmcvZXRjLlxuICAgICAqL1xuICAgIGluc3BlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBmdW5jdGlvbiBTa2lwUmVwb3J0KHJlcG9ydCkge1xuICAgICAgICAgICAgaW5pdEluc3BlY3QodGhpcywgcmVwb3J0KVxuICAgICAgICB9KHRoaXMpXG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuRW5kID0gRW5kUmVwb3J0XG5mdW5jdGlvbiBFbmRSZXBvcnQoKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuRW5kKVxufVxubWV0aG9kcyhFbmRSZXBvcnQsIFJlcG9ydCwge1xuICAgIC8qKlxuICAgICAqIFNvIHV0aWwuaW5zcGVjdCBwcm92aWRlcyBtb3JlIHNlbnNpYmxlIG91dHB1dCBmb3IgdGVzdGluZy9ldGMuXG4gICAgICovXG4gICAgaW5zcGVjdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IGZ1bmN0aW9uIEVuZFJlcG9ydChyZXBvcnQpIHtcbiAgICAgICAgICAgIGluaXRJbnNwZWN0KHRoaXMsIHJlcG9ydClcbiAgICAgICAgfSh0aGlzKVxuICAgIH0sXG59KVxuXG5leHBvcnRzLkVycm9yID0gRXJyb3JSZXBvcnRcbmZ1bmN0aW9uIEVycm9yUmVwb3J0KGVycm9yKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuRXJyb3IpXG4gICAgdGhpcy5lcnJvciA9IGVycm9yXG59XG5tZXRob2RzKEVycm9yUmVwb3J0LCBSZXBvcnQsIHtcbiAgICAvKipcbiAgICAgKiBTbyB1dGlsLmluc3BlY3QgcHJvdmlkZXMgbW9yZSBzZW5zaWJsZSBvdXRwdXQgZm9yIHRlc3RpbmcvZXRjLlxuICAgICAqL1xuICAgIGluc3BlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBmdW5jdGlvbiBFcnJvclJlcG9ydChyZXBvcnQpIHtcbiAgICAgICAgICAgIGluaXRJbnNwZWN0KHRoaXMsIHJlcG9ydClcbiAgICAgICAgfSh0aGlzKVxuICAgIH0sXG59KVxuXG52YXIgSG9va01ldGhvZHMgPSB7XG4gICAgZ2V0IHN0YWdlKCkge1xuICAgICAgICBzd2l0Y2ggKHRoaXMuXykge1xuICAgICAgICBjYXNlIEhvb2tTdGFnZS5CZWZvcmVBbGw6IHJldHVybiBcImJlZm9yZSBhbGxcIlxuICAgICAgICBjYXNlIEhvb2tTdGFnZS5CZWZvcmVFYWNoOiByZXR1cm4gXCJiZWZvcmUgZWFjaFwiXG4gICAgICAgIGNhc2UgSG9va1N0YWdlLkFmdGVyRWFjaDogcmV0dXJuIFwiYWZ0ZXIgZWFjaFwiXG4gICAgICAgIGNhc2UgSG9va1N0YWdlLkFmdGVyQWxsOiByZXR1cm4gXCJhZnRlciBhbGxcIlxuICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoXCJ1bnJlYWNoYWJsZVwiKVxuICAgICAgICB9XG4gICAgfSxcblxuICAgIGdldCBpc0JlZm9yZUFsbCgpIHsgcmV0dXJuIHRoaXMuXyA9PT0gSG9va1N0YWdlLkJlZm9yZUFsbCB9LFxuICAgIGdldCBpc0JlZm9yZUVhY2goKSB7IHJldHVybiB0aGlzLl8gPT09IEhvb2tTdGFnZS5CZWZvcmVFYWNoIH0sXG4gICAgZ2V0IGlzQWZ0ZXJFYWNoKCkgeyByZXR1cm4gdGhpcy5fID09PSBIb29rU3RhZ2UuQWZ0ZXJFYWNoIH0sXG4gICAgZ2V0IGlzQWZ0ZXJBbGwoKSB7IHJldHVybiB0aGlzLl8gPT09IEhvb2tTdGFnZS5BZnRlckFsbCB9LFxufVxuXG5leHBvcnRzLkhvb2tFcnJvciA9IEhvb2tFcnJvclxuZnVuY3Rpb24gSG9va0Vycm9yKHN0YWdlLCBmdW5jLCBlcnJvcikge1xuICAgIHRoaXMuXyA9IHN0YWdlXG4gICAgdGhpcy5uYW1lID0gZnVuYy5uYW1lIHx8IGZ1bmMuZGlzcGxheU5hbWUgfHwgXCJcIlxuICAgIHRoaXMuZXJyb3IgPSBlcnJvclxufVxubWV0aG9kcyhIb29rRXJyb3IsIEhvb2tNZXRob2RzKVxuXG5leHBvcnRzLkhvb2sgPSBIb29rUmVwb3J0XG5mdW5jdGlvbiBIb29rUmVwb3J0KHBhdGgsIHJvb3RQYXRoLCBob29rRXJyb3IpIHtcbiAgICBSZXBvcnQuY2FsbCh0aGlzLCBob29rRXJyb3IuXylcbiAgICB0aGlzLnBhdGggPSBwYXRoXG4gICAgdGhpcy5yb290UGF0aCA9IHJvb3RQYXRoXG4gICAgdGhpcy5uYW1lID0gaG9va0Vycm9yLm5hbWVcbiAgICB0aGlzLmVycm9yID0gaG9va0Vycm9yLmVycm9yXG59XG5tZXRob2RzKEhvb2tSZXBvcnQsIFJlcG9ydCwgSG9va01ldGhvZHMsIHtcbiAgICBnZXQgaG9va0Vycm9yKCkgeyByZXR1cm4gbmV3IEhvb2tFcnJvcih0aGlzLl8sIHRoaXMsIHRoaXMuZXJyb3IpIH0sXG59KVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIG1ldGhvZHMgPSByZXF1aXJlKFwiLi4vbWV0aG9kc1wiKVxudmFyIHBlYWNoID0gcmVxdWlyZShcIi4uL3V0aWxcIikucGVhY2hcbnZhciBSZXBvcnRzID0gcmVxdWlyZShcIi4vcmVwb3J0c1wiKVxudmFyIEZpbHRlciA9IHJlcXVpcmUoXCIuL2ZpbHRlclwiKVxudmFyIEhvb2tTdGFnZSA9IFJlcG9ydHMuSG9va1N0YWdlXG5cbi8qKlxuICogVGhlIHRlc3RzIGFyZSBsYWlkIG91dCBpbiBhIHZlcnkgZGF0YS1kcml2ZW4gZGVzaWduLiBXaXRoIGV4Y2VwdGlvbiBvZiB0aGVcbiAqIHJlcG9ydHMsIHRoZXJlIGlzIG1pbmltYWwgb2JqZWN0IG9yaWVudGF0aW9uIGFuZCB6ZXJvIHZpcnR1YWwgZGlzcGF0Y2guXG4gKiBIZXJlJ3MgYSBxdWljayBvdmVydmlldzpcbiAqXG4gKiAtIFRoZSB0ZXN0IGhhbmRsaW5nIGRpc3BhdGNoZXMgYmFzZWQgb24gdmFyaW91cyBhdHRyaWJ1dGVzIHRoZSB0ZXN0IGhhcy4gRm9yXG4gKiAgIGV4YW1wbGUsIHJvb3RzIGFyZSBrbm93biBieSBhIGNpcmN1bGFyIHJvb3QgcmVmZXJlbmNlLCBhbmQgc2tpcHBlZCB0ZXN0c1xuICogICBhcmUga25vd24gYnkgbm90IGhhdmluZyBhIGNhbGxiYWNrLlxuICpcbiAqIC0gVGhlIHRlc3QgZXZhbHVhdGlvbiBpcyB2ZXJ5IHByb2NlZHVyYWwuIEFsdGhvdWdoIGl0J3MgdmVyeSBoaWdobHlcbiAqICAgYXN5bmNocm9ub3VzLCB0aGUgdXNlIG9mIHByb21pc2VzIGxpbmVhcml6ZSB0aGUgbG9naWMsIHNvIGl0IHJlYWRzIHZlcnlcbiAqICAgbXVjaCBsaWtlIGEgcmVjdXJzaXZlIHNldCBvZiBzdGVwcy5cbiAqXG4gKiAtIFRoZSBkYXRhIHR5cGVzIGFyZSBtb3N0bHkgZWl0aGVyIHBsYWluIG9iamVjdHMgb3IgY2xhc3NlcyB3aXRoIG5vIG1ldGhvZHMsXG4gKiAgIHRoZSBsYXR0ZXIgbW9zdGx5IGZvciBkZWJ1Z2dpbmcgaGVscC4gVGhpcyBhbHNvIGF2b2lkcyBtb3N0IG9mIHRoZVxuICogICBpbmRpcmVjdGlvbiByZXF1aXJlZCB0byBhY2NvbW1vZGF0ZSBicmVha2luZyBhYnN0cmFjdGlvbnMsIHdoaWNoIHRoZSBBUElcbiAqICAgbWV0aG9kcyBmcmVxdWVudGx5IG5lZWQgdG8gZG8uXG4gKi9cblxuLy8gUHJldmVudCBTaW5vbiBpbnRlcmZlcmVuY2Ugd2hlbiB0aGV5IGluc3RhbGwgdGhlaXIgbW9ja3NcbnZhciBzZXRUaW1lb3V0ID0gZ2xvYmFsLnNldFRpbWVvdXRcbnZhciBjbGVhclRpbWVvdXQgPSBnbG9iYWwuY2xlYXJUaW1lb3V0XG52YXIgbm93ID0gZ2xvYmFsLkRhdGUubm93XG5cbi8qKlxuICogQmFzaWMgZGF0YSB0eXBlc1xuICovXG5mdW5jdGlvbiBSZXN1bHQodGltZSwgYXR0ZW1wdCkge1xuICAgIHRoaXMudGltZSA9IHRpbWVcbiAgICB0aGlzLmNhdWdodCA9IGF0dGVtcHQuY2F1Z2h0XG4gICAgdGhpcy52YWx1ZSA9IGF0dGVtcHQuY2F1Z2h0ID8gYXR0ZW1wdC52YWx1ZSA6IHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIE92ZXJ2aWV3IG9mIHRoZSB0ZXN0IHByb3BlcnRpZXM6XG4gKlxuICogLSBgcm9vdGAgLSBUaGUgcm9vdCB0ZXN0XG4gKiAtIGByZXBvcnRlcnNgIC0gVGhlIGxpc3Qgb2YgcmVwb3J0ZXJzXG4gKiAtIGBjdXJyZW50YCAtIEEgcmVmZXJlbmNlIHRvIHRoZSBjdXJyZW50bHkgYWN0aXZlIHRlc3RcbiAqIC0gYHRpbWVvdXRgIC0gVGhlIHRlc3RzJ3MgdGltZW91dCwgb3IgMCBpZiBpbmhlcml0ZWRcbiAqIC0gYHNsb3dgIC0gVGhlIHRlc3RzJ3Mgc2xvdyB0aHJlc2hvbGRcbiAqIC0gYG5hbWVgIC0gVGhlIHRlc3QncyBuYW1lXG4gKiAtIGBpbmRleGAgLSBUaGUgdGVzdCdzIGluZGV4XG4gKiAtIGBwYXJlbnRgIC0gVGhlIHRlc3QncyBwYXJlbnRcbiAqIC0gYGNhbGxiYWNrYCAtIFRoZSB0ZXN0J3MgY2FsbGJhY2tcbiAqIC0gYHRlc3RzYCAtIFRoZSB0ZXN0J3MgY2hpbGQgdGVzdHNcbiAqIC0gYGJlZm9yZUFsbGAsIGBiZWZvcmVFYWNoYCwgYGFmdGVyRWFjaGAsIGBhZnRlckFsbGAgLSBUaGUgdGVzdCdzIHZhcmlvdXNcbiAqICAgc2NoZWR1bGVkIGhvb2tzXG4gKlxuICogTWFueSBvZiB0aGVzZSBwcm9wZXJ0aWVzIGFyZW4ndCBwcmVzZW50IG9uIGluaXRpYWxpemF0aW9uIHRvIHNhdmUgbWVtb3J5LlxuICovXG5cbmZ1bmN0aW9uIE5vcm1hbChuYW1lLCBpbmRleCwgcGFyZW50LCBjYWxsYmFjaykge1xuICAgIHRoaXMubG9ja2VkID0gdHJ1ZVxuICAgIHRoaXMucm9vdCA9IHBhcmVudC5yb290XG4gICAgdGhpcy5uYW1lID0gbmFtZVxuICAgIHRoaXMuaW5kZXggPSBpbmRleHwwXG4gICAgdGhpcy5wYXJlbnQgPSBwYXJlbnRcbiAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2tcbiAgICB0aGlzLmlzRmFpbGFibGUgPSBwYXJlbnQuaXNGYWlsYWJsZVxuICAgIHRoaXMuYXR0ZW1wdHMgPSBwYXJlbnQuYXR0ZW1wdHNcblxuICAgIHRoaXMudGltZW91dCA9IHBhcmVudC50aW1lb3V0XG4gICAgdGhpcy5zbG93ID0gcGFyZW50LnNsb3dcbiAgICB0aGlzLnRlc3RzID0gdW5kZWZpbmVkXG4gICAgdGhpcy5iZWZvcmVBbGwgPSB1bmRlZmluZWRcbiAgICB0aGlzLmJlZm9yZUVhY2ggPSB1bmRlZmluZWRcbiAgICB0aGlzLmFmdGVyRWFjaCA9IHVuZGVmaW5lZFxuICAgIHRoaXMuYWZ0ZXJBbGwgPSB1bmRlZmluZWRcbiAgICB0aGlzLnJlcG9ydGVyID0gdW5kZWZpbmVkXG4gICAgdGhpcy5yZWZsZWN0ID0gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIFNraXBwZWQobmFtZSwgaW5kZXgsIHBhcmVudCkge1xuICAgIHRoaXMubG9ja2VkID0gdHJ1ZVxuICAgIHRoaXMucm9vdCA9IHBhcmVudC5yb290XG4gICAgdGhpcy5uYW1lID0gbmFtZVxuICAgIHRoaXMuaW5kZXggPSBpbmRleHwwXG4gICAgdGhpcy5wYXJlbnQgPSBwYXJlbnRcblxuICAgIC8vIE9ubHkgZm9yIHJlZmxlY3Rpb24uXG4gICAgdGhpcy5pc0ZhaWxhYmxlID0gcGFyZW50LmlzRmFpbGFibGVcbiAgICB0aGlzLmF0dGVtcHRzID0gcGFyZW50LmF0dGVtcHRzXG4gICAgdGhpcy5yZXBvcnRlciA9IHVuZGVmaW5lZFxuICAgIHRoaXMucmVmbGVjdCA9IHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBSb290KCkge1xuICAgIHRoaXMubG9ja2VkID0gZmFsc2VcbiAgICB0aGlzLnJlcG9ydGVySWRzID0gW11cbiAgICB0aGlzLnJlcG9ydGVycyA9IFtdXG4gICAgdGhpcy5jdXJyZW50ID0gdGhpc1xuICAgIHRoaXMucm9vdCA9IHRoaXNcbiAgICB0aGlzLnRpbWVvdXQgPSAwXG4gICAgdGhpcy5zbG93ID0gMFxuICAgIHRoaXMuYXR0ZW1wdHMgPSAxXG4gICAgdGhpcy5pc0ZhaWxhYmxlID0gZmFsc2VcblxuICAgIHRoaXMudGVzdHMgPSB1bmRlZmluZWRcbiAgICB0aGlzLnJlcG9ydGVyID0gdW5kZWZpbmVkXG4gICAgdGhpcy5yZWZsZWN0ID0gdW5kZWZpbmVkXG4gICAgdGhpcy5iZWZvcmVBbGwgPSB1bmRlZmluZWRcbiAgICB0aGlzLmJlZm9yZUVhY2ggPSB1bmRlZmluZWRcbiAgICB0aGlzLmFmdGVyRWFjaCA9IHVuZGVmaW5lZFxuICAgIHRoaXMuYWZ0ZXJBbGwgPSB1bmRlZmluZWRcbn1cblxuZnVuY3Rpb24gQ29udGV4dChyb290KSB7XG4gICAgdGhpcy5yb290ID0gcm9vdFxuICAgIHRoaXMudGVzdHMgPSBbXVxuICAgIHRoaXMuaXNTdWNjZXNzID0gdHJ1ZVxufVxuXG4vKipcbiAqIEJhc2UgdGVzdHMgKGkuZS4gZGVmYXVsdCBleHBvcnQsIHJlc3VsdCBvZiBgaW50ZXJuYWwucm9vdCgpYCkuXG4gKi9cblxuZXhwb3J0cy5jcmVhdGVSb290ID0gZnVuY3Rpb24gKG1ldGhvZHMpIHtcbiAgICByZXR1cm4gbmV3IFJvb3QobWV0aG9kcylcbn1cblxuLyoqXG4gKiBTZXQgdXAgZWFjaCB0ZXN0IHR5cGUuXG4gKi9cblxuLyoqXG4gKiBBIG5vcm1hbCB0ZXN0IHRocm91Z2ggYHQudGVzdCgpYC5cbiAqL1xuXG5leHBvcnRzLmFkZE5vcm1hbCA9IGZ1bmN0aW9uIChwYXJlbnQsIG5hbWUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGluZGV4ID0gcGFyZW50LnRlc3RzICE9IG51bGwgPyBwYXJlbnQudGVzdHMubGVuZ3RoIDogMFxuICAgIHZhciBiYXNlID0gbmV3IE5vcm1hbChuYW1lLCBpbmRleCwgcGFyZW50LCBjYWxsYmFjaylcblxuICAgIGlmIChpbmRleCkge1xuICAgICAgICBwYXJlbnQudGVzdHMucHVzaChiYXNlKVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcmVudC50ZXN0cyA9IFtiYXNlXVxuICAgIH1cbn1cblxuLyoqXG4gKiBBIHNraXBwZWQgdGVzdCB0aHJvdWdoIGB0LnRlc3RTa2lwKClgLlxuICovXG5leHBvcnRzLmFkZFNraXBwZWQgPSBmdW5jdGlvbiAocGFyZW50LCBuYW1lKSB7XG4gICAgdmFyIGluZGV4ID0gcGFyZW50LnRlc3RzICE9IG51bGwgPyBwYXJlbnQudGVzdHMubGVuZ3RoIDogMFxuICAgIHZhciBiYXNlID0gbmV3IFNraXBwZWQobmFtZSwgaW5kZXgsIHBhcmVudClcblxuICAgIGlmIChpbmRleCkge1xuICAgICAgICBwYXJlbnQudGVzdHMucHVzaChiYXNlKVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcmVudC50ZXN0cyA9IFtiYXNlXVxuICAgIH1cbn1cblxuLyoqXG4gKiBDbGVhciB0aGUgdGVzdHMgaW4gcGxhY2UuXG4gKi9cbmV4cG9ydHMuY2xlYXJUZXN0cyA9IGZ1bmN0aW9uIChwYXJlbnQpIHtcbiAgICBwYXJlbnQudGVzdHMgPSBudWxsXG59XG5cbi8qKlxuICogRXhlY3V0ZSB0aGUgdGVzdHNcbiAqL1xuXG5leHBvcnRzLmRlZmF1bHRUaW1lb3V0ID0gMjAwMCAvLyBtc1xuZXhwb3J0cy5kZWZhdWx0U2xvdyA9IDc1IC8vIG1zXG5cbmZ1bmN0aW9uIG1ha2VTbGljZSh0ZXN0cywgbGVuZ3RoKSB7XG4gICAgdmFyIHJldCA9IG5ldyBBcnJheShsZW5ndGgpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJldFtpXSA9IHtuYW1lOiB0ZXN0c1tpXS5uYW1lLCBpbmRleDogdGVzdHNbaV0uaW5kZXh9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiByZXBvcnRXaXRoKGNvbnRleHQsIGZ1bmMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjb250ZXh0LnJvb3QucmVwb3J0ZXIgPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICByZXR1cm4gZnVuYyhjb250ZXh0LnJvb3QucmVwb3J0ZXIpXG4gICAgfSlcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciByZXBvcnRlcnMgPSBjb250ZXh0LnJvb3QucmVwb3J0ZXJzXG5cbiAgICAgICAgLy8gVHdvIGVhc3kgY2FzZXMuXG4gICAgICAgIGlmIChyZXBvcnRlcnMubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIGlmIChyZXBvcnRlcnMubGVuZ3RoID09PSAxKSByZXR1cm4gZnVuYyhyZXBvcnRlcnNbMF0pXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChyZXBvcnRlcnMubWFwKGZ1bmMpKVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIHJlcG9ydFN0YXJ0KGNvbnRleHQpIHtcbiAgICByZXR1cm4gcmVwb3J0V2l0aChjb250ZXh0LCBmdW5jdGlvbiAocmVwb3J0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyKG5ldyBSZXBvcnRzLlN0YXJ0KCkpXG4gICAgfSlcbn1cblxuZnVuY3Rpb24gcmVwb3J0RW50ZXIoY29udGV4dCwgZHVyYXRpb24pIHtcbiAgICB2YXIgdGVzdCA9IGNvbnRleHQucm9vdC5jdXJyZW50XG4gICAgdmFyIHNsb3cgPSB0ZXN0LnNsb3cgfHwgZXhwb3J0cy5kZWZhdWx0U2xvd1xuXG4gICAgcmV0dXJuIHJlcG9ydFdpdGgoY29udGV4dCwgZnVuY3Rpb24gKHJlcG9ydGVyKSB7XG4gICAgICAgIHZhciBwYXRoID0gbWFrZVNsaWNlKGNvbnRleHQudGVzdHMsIGNvbnRleHQudGVzdHMubGVuZ3RoKVxuXG4gICAgICAgIHJldHVybiByZXBvcnRlcihuZXcgUmVwb3J0cy5FbnRlcihwYXRoLCBkdXJhdGlvbiwgc2xvdykpXG4gICAgfSlcbn1cblxuZnVuY3Rpb24gcmVwb3J0TGVhdmUoY29udGV4dCkge1xuICAgIHJldHVybiByZXBvcnRXaXRoKGNvbnRleHQsIGZ1bmN0aW9uIChyZXBvcnRlcikge1xuICAgICAgICByZXR1cm4gcmVwb3J0ZXIobmV3IFJlcG9ydHMuTGVhdmUoXG4gICAgICAgICAgICBtYWtlU2xpY2UoY29udGV4dC50ZXN0cywgY29udGV4dC50ZXN0cy5sZW5ndGgpKSlcbiAgICB9KVxufVxuXG5mdW5jdGlvbiByZXBvcnRQYXNzKGNvbnRleHQsIGR1cmF0aW9uKSB7XG4gICAgdmFyIHRlc3QgPSBjb250ZXh0LnJvb3QuY3VycmVudFxuICAgIHZhciBzbG93ID0gdGVzdC5zbG93IHx8IGV4cG9ydHMuZGVmYXVsdFNsb3dcblxuICAgIHJldHVybiByZXBvcnRXaXRoKGNvbnRleHQsIGZ1bmN0aW9uIChyZXBvcnRlcikge1xuICAgICAgICB2YXIgcGF0aCA9IG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmxlbmd0aClcblxuICAgICAgICByZXR1cm4gcmVwb3J0ZXIobmV3IFJlcG9ydHMuUGFzcyhwYXRoLCBkdXJhdGlvbiwgc2xvdykpXG4gICAgfSlcbn1cblxuZnVuY3Rpb24gcmVwb3J0RmFpbChjb250ZXh0LCBlcnJvciwgZHVyYXRpb24pIHtcbiAgICB2YXIgdGVzdCA9IGNvbnRleHQucm9vdC5jdXJyZW50XG4gICAgdmFyIHNsb3cgPSB0ZXN0LnNsb3cgfHwgZXhwb3J0cy5kZWZhdWx0U2xvd1xuICAgIHZhciBpc0ZhaWxhYmxlID0gdGVzdC5pc0ZhaWxhYmxlXG5cbiAgICByZXR1cm4gcmVwb3J0V2l0aChjb250ZXh0LCBmdW5jdGlvbiAocmVwb3J0ZXIpIHtcbiAgICAgICAgdmFyIHBhdGggPSBtYWtlU2xpY2UoY29udGV4dC50ZXN0cywgY29udGV4dC50ZXN0cy5sZW5ndGgpXG5cbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyKG5ldyBSZXBvcnRzLkZhaWwoXG4gICAgICAgICAgICBwYXRoLCBlcnJvciwgZHVyYXRpb24sIHNsb3csIGlzRmFpbGFibGUpKVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIHJlcG9ydFNraXAoY29udGV4dCkge1xuICAgIHJldHVybiByZXBvcnRXaXRoKGNvbnRleHQsIGZ1bmN0aW9uIChyZXBvcnRlcikge1xuICAgICAgICByZXR1cm4gcmVwb3J0ZXIobmV3IFJlcG9ydHMuU2tpcChcbiAgICAgICAgICAgIG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmxlbmd0aCkpKVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIHJlcG9ydEVuZChjb250ZXh0KSB7XG4gICAgcmV0dXJuIHJlcG9ydFdpdGgoY29udGV4dCwgZnVuY3Rpb24gKHJlcG9ydGVyKSB7XG4gICAgICAgIHJldHVybiByZXBvcnRlcihuZXcgUmVwb3J0cy5FbmQoKSlcbiAgICB9KVxufVxuXG5mdW5jdGlvbiByZXBvcnRFcnJvcihjb250ZXh0LCBlcnJvcikge1xuICAgIHJldHVybiByZXBvcnRXaXRoKGNvbnRleHQsIGZ1bmN0aW9uIChyZXBvcnRlcikge1xuICAgICAgICByZXR1cm4gcmVwb3J0ZXIobmV3IFJlcG9ydHMuRXJyb3IoZXJyb3IpKVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIHJlcG9ydEhvb2soY29udGV4dCwgdGVzdCwgZXJyb3IpIHtcbiAgICByZXR1cm4gcmVwb3J0V2l0aChjb250ZXh0LCBmdW5jdGlvbiAocmVwb3J0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyKG5ldyBSZXBvcnRzLkhvb2soXG4gICAgICAgICAgICBtYWtlU2xpY2UoY29udGV4dC50ZXN0cywgY29udGV4dC50ZXN0cy5sZW5ndGgpLFxuICAgICAgICAgICAgbWFrZVNsaWNlKGNvbnRleHQudGVzdHMsIGNvbnRleHQudGVzdHMuaW5kZXhPZih0ZXN0KSArIDEpLFxuICAgICAgICAgICAgZXJyb3IpKVxuICAgIH0pXG59XG5cbi8qKlxuICogTm9ybWFsIHRlc3RzXG4gKi9cblxuLy8gUGhhbnRvbUpTIGFuZCBJRSBkb24ndCBhZGQgdGhlIHN0YWNrIHVudGlsIGl0J3MgdGhyb3duLiBJbiBmYWlsaW5nIGFzeW5jXG4vLyB0ZXN0cywgaXQncyBhbHJlYWR5IHRocm93biBpbiBhIHNlbnNlLCBzbyB0aGlzIHNob3VsZCBiZSBub3JtYWxpemVkIHdpdGhcbi8vIG90aGVyIHRlc3QgdHlwZXMuXG52YXIgYWRkU3RhY2sgPSB0eXBlb2YgbmV3IEVycm9yKCkuc3RhY2sgIT09IFwic3RyaW5nXCJcbiAgICA/IGZ1bmN0aW9uIGFkZFN0YWNrKGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgRXJyb3IgJiYgZS5zdGFjayA9PSBudWxsKSB0aHJvdyBlXG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICByZXR1cm4gZVxuICAgICAgICB9XG4gICAgfVxuICAgIDogZnVuY3Rpb24gKGUpIHsgcmV0dXJuIGUgfVxuXG5mdW5jdGlvbiBnZXRUaGVuKHJlcykge1xuICAgIGlmICh0eXBlb2YgcmVzID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiByZXMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gcmVzLnRoZW5cbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxufVxuXG5mdW5jdGlvbiBBc3luY1N0YXRlKGNvbnRleHQsIHN0YXJ0LCByZXNvbHZlLCBjb3VudCkge1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHRcbiAgICB0aGlzLnN0YXJ0ID0gc3RhcnRcbiAgICB0aGlzLnJlc29sdmUgPSByZXNvbHZlXG4gICAgdGhpcy5jb3VudCA9IGNvdW50XG4gICAgdGhpcy50aW1lciA9IHVuZGVmaW5lZFxufVxuXG52YXIgcCA9IFByb21pc2UucmVzb2x2ZSgpXG5cbmZ1bmN0aW9uIGFzeW5jRmluaXNoKHN0YXRlLCBhdHRlbXB0KSB7XG4gICAgLy8gQ2FwdHVyZSBpbW1lZGlhdGVseS4gV29yc3QgY2FzZSBzY2VuYXJpbywgaXQgZ2V0cyB0aHJvd24gYXdheS5cbiAgICB2YXIgZW5kID0gbm93KClcblxuICAgIGlmIChzdGF0ZS50aW1lcikge1xuICAgICAgICBjbGVhclRpbWVvdXQuY2FsbChnbG9iYWwsIHN0YXRlLnRpbWVyKVxuICAgICAgICBzdGF0ZS50aW1lciA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmIChhdHRlbXB0LmNhdWdodCAmJiBzdGF0ZS5jb3VudCA8IHN0YXRlLmNvbnRleHQucm9vdC5jdXJyZW50LmF0dGVtcHRzKSB7XG4gICAgICAgIC8vIERvbid0IHJlY3Vyc2Ugc3luY2hyb25vdXNseSwgc2luY2UgaXQgbWF5IGJlIHJlc29sdmVkIHN5bmNocm9ub3VzbHlcbiAgICAgICAgc3RhdGUucmVzb2x2ZShwLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGludm9rZUluaXQoc3RhdGUuY29udGV4dCwgc3RhdGUuY291bnQgKyAxKVxuICAgICAgICB9KSlcbiAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5yZXNvbHZlKG5ldyBSZXN1bHQoZW5kIC0gc3RhdGUuc3RhcnQsIGF0dGVtcHQpKVxuICAgIH1cbn1cblxuLy8gQXZvaWQgY3JlYXRpbmcgYSBjbG9zdXJlIGlmIHBvc3NpYmxlLCBpbiBjYXNlIGl0IGRvZXNuJ3QgcmV0dXJuIGEgdGhlbmFibGUuXG5mdW5jdGlvbiBpbnZva2VJbml0KGNvbnRleHQsIGNvdW50KSB7XG4gICAgdmFyIHRlc3QgPSBjb250ZXh0LnJvb3QuY3VycmVudFxuICAgIHZhciBzdGFydCA9IG5vdygpXG4gICAgdmFyIHRyeUJvZHkgPSB0cnkwKHRlc3QuY2FsbGJhY2spXG4gICAgdmFyIHN5bmNFbmQgPSBub3coKVxuXG4gICAgLy8gTm90ZTogc3luY2hyb25vdXMgZmFpbHVyZXMgYXJlIHRlc3QgZmFpbHVyZXMsIG5vdCBmYXRhbCBlcnJvcnMuXG4gICAgaWYgKHRyeUJvZHkuY2F1Z2h0KSB7XG4gICAgICAgIGlmIChjb3VudCA8IHRlc3QuYXR0ZW1wdHMpIHJldHVybiBpbnZva2VJbml0KGNvbnRleHQsIGNvdW50ICsgMSlcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXcgUmVzdWx0KHN5bmNFbmQgLSBzdGFydCwgdHJ5Qm9keSkpXG4gICAgfVxuXG4gICAgdmFyIHRyeVRoZW4gPSB0cnkxKGdldFRoZW4sIHVuZGVmaW5lZCwgdHJ5Qm9keS52YWx1ZSlcblxuICAgIGlmICh0cnlUaGVuLmNhdWdodCkge1xuICAgICAgICBpZiAoY291bnQgPCB0ZXN0LmF0dGVtcHRzKSByZXR1cm4gaW52b2tlSW5pdChjb250ZXh0LCBjb3VudCArIDEpXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IFJlc3VsdChzeW5jRW5kIC0gc3RhcnQsIHRyeVRoZW4pKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdHJ5VGhlbi52YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IFJlc3VsdChzeW5jRW5kIC0gc3RhcnQsIHRyeVRoZW4pKVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICB2YXIgc3RhdGUgPSBuZXcgQXN5bmNTdGF0ZShjb250ZXh0LCBzdGFydCwgcmVzb2x2ZSwgY291bnQpXG4gICAgICAgIHZhciByZXN1bHQgPSB0cnkyKHRyeVRoZW4udmFsdWUsIHRyeUJvZHkudmFsdWUsXG4gICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlID09IG51bGwpIHJldHVyblxuICAgICAgICAgICAgICAgIGFzeW5jRmluaXNoKHN0YXRlLCB0cnlQYXNzKCkpXG4gICAgICAgICAgICAgICAgc3RhdGUgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZSA9PSBudWxsKSByZXR1cm5cbiAgICAgICAgICAgICAgICBhc3luY0ZpbmlzaChzdGF0ZSwgdHJ5RmFpbChhZGRTdGFjayhlKSkpXG4gICAgICAgICAgICAgICAgc3RhdGUgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgaWYgKHN0YXRlID09IG51bGwpIHJldHVyblxuICAgICAgICBpZiAocmVzdWx0LmNhdWdodCkge1xuICAgICAgICAgICAgYXN5bmNGaW5pc2goc3RhdGUsIHJlc3VsdClcbiAgICAgICAgICAgIHN0YXRlID0gdW5kZWZpbmVkXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCB0aGUgdGltZW91dCAqYWZ0ZXIqIGluaXRpYWxpemF0aW9uLiBUaGUgdGltZW91dCB3aWxsIGxpa2VseSBiZVxuICAgICAgICAvLyBzcGVjaWZpZWQgZHVyaW5nIGluaXRpYWxpemF0aW9uLlxuICAgICAgICB2YXIgbWF4VGltZW91dCA9IHRlc3QudGltZW91dCB8fCBleHBvcnRzLmRlZmF1bHRUaW1lb3V0XG5cbiAgICAgICAgLy8gU2V0dGluZyBhIHRpbWVvdXQgaXMgcG9pbnRsZXNzIGlmIGl0J3MgaW5maW5pdGUuXG4gICAgICAgIGlmIChtYXhUaW1lb3V0ICE9PSBJbmZpbml0eSkge1xuICAgICAgICAgICAgc3RhdGUudGltZXIgPSBzZXRUaW1lb3V0LmNhbGwoZ2xvYmFsLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlID09IG51bGwpIHJldHVyblxuICAgICAgICAgICAgICAgIGFzeW5jRmluaXNoKHN0YXRlLCB0cnlGYWlsKGFkZFN0YWNrKFxuICAgICAgICAgICAgICAgICAgICBuZXcgRXJyb3IoXCJUaW1lb3V0IG9mIFwiICsgbWF4VGltZW91dCArIFwiIHJlYWNoZWRcIikpKSlcbiAgICAgICAgICAgICAgICBzdGF0ZSA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgfSwgbWF4VGltZW91dClcbiAgICAgICAgfVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIEVycm9yV3JhcCh0ZXN0LCBlcnJvcikge1xuICAgIHRoaXMudGVzdCA9IHRlc3RcbiAgICB0aGlzLmVycm9yID0gZXJyb3Jcbn1cbm1ldGhvZHMoRXJyb3JXcmFwLCBFcnJvciwge25hbWU6IFwiRXJyb3JXcmFwXCJ9KVxuXG5mdW5jdGlvbiBpbnZva2VIb29rKHRlc3QsIGxpc3QsIHN0YWdlKSB7XG4gICAgaWYgKGxpc3QgPT0gbnVsbCkgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgcmV0dXJuIHBlYWNoKGxpc3QsIGZ1bmN0aW9uIChob29rKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gaG9vaygpXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcldyYXAodGVzdCwgbmV3IFJlcG9ydHMuSG9va0Vycm9yKHN0YWdlLCBob29rLCBlKSlcbiAgICAgICAgfVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIGludm9rZUJlZm9yZUVhY2godGVzdCkge1xuICAgIGlmICh0ZXN0LnJvb3QgPT09IHRlc3QpIHtcbiAgICAgICAgcmV0dXJuIGludm9rZUhvb2sodGVzdCwgdGVzdC5iZWZvcmVFYWNoLCBIb29rU3RhZ2UuQmVmb3JlRWFjaClcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gaW52b2tlQmVmb3JlRWFjaCh0ZXN0LnBhcmVudCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gaW52b2tlSG9vayh0ZXN0LCB0ZXN0LmJlZm9yZUVhY2gsIEhvb2tTdGFnZS5CZWZvcmVFYWNoKVxuICAgICAgICB9KVxuICAgIH1cbn1cblxuZnVuY3Rpb24gaW52b2tlQWZ0ZXJFYWNoKHRlc3QpIHtcbiAgICBpZiAodGVzdC5yb290ID09PSB0ZXN0KSB7XG4gICAgICAgIHJldHVybiBpbnZva2VIb29rKHRlc3QsIHRlc3QuYWZ0ZXJFYWNoLCBIb29rU3RhZ2UuQWZ0ZXJFYWNoKVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBpbnZva2VIb29rKHRlc3QsIHRlc3QuYWZ0ZXJFYWNoLCBIb29rU3RhZ2UuQWZ0ZXJFYWNoKVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBpbnZva2VBZnRlckVhY2godGVzdC5wYXJlbnQpIH0pXG4gICAgfVxufVxuXG4vKipcbiAqIFRoaXMgY2hlY2tzIGlmIHRoZSB0ZXN0IHdhcyB3aGl0ZWxpc3RlZCBpbiBhIGB0Lm9ubHkoKWAgY2FsbCwgb3IgZm9yXG4gKiBjb252ZW5pZW5jZSwgcmV0dXJucyBgdHJ1ZWAgaWYgYHQub25seSgpYCB3YXMgbmV2ZXIgY2FsbGVkLlxuICovXG5mdW5jdGlvbiBpc09ubHkodGVzdCkge1xuICAgIHZhciBwYXRoID0gW11cblxuICAgIHdoaWxlICh0ZXN0LnBhcmVudCAhPSBudWxsICYmIHRlc3Qub25seSA9PSBudWxsKSB7XG4gICAgICAgIHBhdGgucHVzaCh0ZXN0Lm5hbWUpXG4gICAgICAgIHRlc3QgPSB0ZXN0LnBhcmVudFxuICAgIH1cblxuICAgIC8vIElmIHRoZXJlIGlzbid0IGFueSBgb25seWAgYWN0aXZlLCB0aGVuIGxldCdzIHNraXAgdGhlIGNoZWNrIGFuZCByZXR1cm5cbiAgICAvLyBgdHJ1ZWAgZm9yIGNvbnZlbmllbmNlLlxuICAgIGlmICh0ZXN0Lm9ubHkgPT0gbnVsbCkgcmV0dXJuIHRydWVcbiAgICByZXR1cm4gRmlsdGVyLnRlc3QodGVzdC5vbmx5LCBwYXRoKVxufVxuXG5mdW5jdGlvbiBydW5DaGlsZFRlc3RzKHRlc3QsIGNvbnRleHQpIHtcbiAgICBpZiAodGVzdC50ZXN0cyA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgICBmdW5jdGlvbiBsZWF2ZSgpIHtcbiAgICAgICAgdGVzdC5yb290LmN1cnJlbnQgPSB0ZXN0XG4gICAgICAgIGNvbnRleHQudGVzdHMucG9wKClcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBydW5DaGlsZChjaGlsZCkge1xuICAgICAgICB0ZXN0LnJvb3QuY3VycmVudCA9IGNoaWxkXG4gICAgICAgIGNvbnRleHQudGVzdHMucHVzaChjaGlsZClcblxuICAgICAgICByZXR1cm4gaW52b2tlQmVmb3JlRWFjaCh0ZXN0KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBydW5Ob3JtYWxDaGlsZChjaGlsZCwgY29udGV4dCkgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gaW52b2tlQWZ0ZXJFYWNoKHRlc3QpIH0pXG4gICAgICAgIC5jYXRjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIEVycm9yV3JhcCkpIHRocm93IGVcbiAgICAgICAgICAgIHJldHVybiByZXBvcnRIb29rKGNvbnRleHQsIGUudGVzdCwgZS5lcnJvcilcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4obGVhdmUsIGZ1bmN0aW9uIChlKSB7IGxlYXZlKCk7IHRocm93IGUgfSlcbiAgICB9XG5cbiAgICB2YXIgcmFuID0gZmFsc2VcblxuICAgIHJldHVybiBwZWFjaCh0ZXN0LnRlc3RzLCBmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgLy8gT25seSBza2lwcGVkIHRlc3RzIGhhdmUgbm8gY2FsbGJhY2tcbiAgICAgICAgaWYgKGNoaWxkLmNhbGxiYWNrID09IG51bGwpIHtcbiAgICAgICAgICAgIHRlc3Qucm9vdC5jdXJyZW50ID0gY2hpbGRcbiAgICAgICAgICAgIGNvbnRleHQudGVzdHMucHVzaChjaGlsZClcblxuICAgICAgICAgICAgcmV0dXJuIHJlcG9ydFNraXAoY29udGV4dClcbiAgICAgICAgICAgIC50aGVuKGxlYXZlLCBmdW5jdGlvbiAoZSkgeyBsZWF2ZSgpOyB0aHJvdyBlIH0pXG4gICAgICAgIH0gZWxzZSBpZiAoIWlzT25seShjaGlsZCkpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICB9IGVsc2UgaWYgKHJhbikge1xuICAgICAgICAgICAgcmV0dXJuIHJ1bkNoaWxkKGNoaWxkKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmFuID0gdHJ1ZVxuICAgICAgICAgICAgcmV0dXJuIGludm9rZUhvb2sodGVzdCwgdGVzdC5iZWZvcmVBbGwsIEhvb2tTdGFnZS5CZWZvcmVBbGwpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBydW5DaGlsZChjaGlsZCkgfSlcbiAgICAgICAgfVxuICAgIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXJhbikgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICByZXR1cm4gaW52b2tlSG9vayh0ZXN0LCB0ZXN0LmFmdGVyQWxsLCBIb29rU3RhZ2UuQWZ0ZXJBbGwpXG4gICAgfSlcbn1cblxuZnVuY3Rpb24gY2xlYXJDaGlsZHJlbih0ZXN0KSB7XG4gICAgaWYgKHRlc3QudGVzdHMgPT0gbnVsbCkgcmV0dXJuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXN0LnRlc3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRlc3QudGVzdHNbaV0udGVzdHMgPSB1bmRlZmluZWRcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJ1bk5vcm1hbENoaWxkKHRlc3QsIGNvbnRleHQpIHtcbiAgICB0ZXN0LmxvY2tlZCA9IGZhbHNlXG5cbiAgICByZXR1cm4gaW52b2tlSW5pdChjb250ZXh0LCAxKVxuICAgIC50aGVuKFxuICAgICAgICBmdW5jdGlvbiAocmVzdWx0KSB7IHRlc3QubG9ja2VkID0gdHJ1ZTsgcmV0dXJuIHJlc3VsdCB9LFxuICAgICAgICBmdW5jdGlvbiAoZXJyb3IpIHsgdGVzdC5sb2NrZWQgPSB0cnVlOyB0aHJvdyBlcnJvciB9KVxuICAgIC50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgaWYgKHJlc3VsdC5jYXVnaHQpIHtcbiAgICAgICAgICAgIGlmICghdGVzdC5pc0ZhaWxhYmxlKSBjb250ZXh0LmlzU3VjY2VzcyA9IGZhbHNlXG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0RmFpbChjb250ZXh0LCByZXN1bHQudmFsdWUsIHJlc3VsdC50aW1lKVxuICAgICAgICB9IGVsc2UgaWYgKHRlc3QudGVzdHMgIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gUmVwb3J0IHRoaXMgYXMgaWYgaXQgd2FzIGEgcGFyZW50IHRlc3QgaWYgaXQncyBwYXNzaW5nIGFuZCBoYXNcbiAgICAgICAgICAgIC8vIGNoaWxkcmVuLlxuICAgICAgICAgICAgcmV0dXJuIHJlcG9ydEVudGVyKGNvbnRleHQsIHJlc3VsdC50aW1lKVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcnVuQ2hpbGRUZXN0cyh0ZXN0LCBjb250ZXh0KSB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVwb3J0TGVhdmUoY29udGV4dCkgfSlcbiAgICAgICAgICAgIC5jYXRjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBFcnJvcldyYXApKSB0aHJvdyBlXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcG9ydExlYXZlKGNvbnRleHQpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVwb3J0SG9vayhjb250ZXh0LCBlLnRlc3QsIGUuZXJyb3IpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0UGFzcyhjb250ZXh0LCByZXN1bHQudGltZSlcbiAgICAgICAgfVxuICAgIH0pXG4gICAgLnRoZW4oXG4gICAgICAgIGZ1bmN0aW9uICgpIHsgY2xlYXJDaGlsZHJlbih0ZXN0KSB9LFxuICAgICAgICBmdW5jdGlvbiAoZSkgeyBjbGVhckNoaWxkcmVuKHRlc3QpOyB0aHJvdyBlIH0pXG59XG5cbi8qKlxuICogVGhpcyBydW5zIHRoZSByb290IHRlc3QgYW5kIHJldHVybnMgYSBwcm9taXNlIHJlc29sdmVkIHdoZW4gaXQncyBkb25lLlxuICovXG5leHBvcnRzLnJ1blRlc3QgPSBmdW5jdGlvbiAocm9vdCwgb3B0cykge1xuICAgIHZhciBjb250ZXh0ID0gbmV3IENvbnRleHQocm9vdCwgb3B0cylcblxuICAgIHJvb3QubG9ja2VkID0gdHJ1ZVxuICAgIHJldHVybiByZXBvcnRTdGFydChjb250ZXh0KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHJ1bkNoaWxkVGVzdHMocm9vdCwgY29udGV4dCkgfSlcbiAgICAuY2F0Y2goZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIEVycm9yV3JhcCkpIHRocm93IGVcbiAgICAgICAgcmV0dXJuIHJlcG9ydEhvb2soY29udGV4dCwgZS50ZXN0LCBlLmVycm9yKVxuICAgIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVwb3J0RW5kKGNvbnRleHQpIH0pXG4gICAgLy8gVGVsbCB0aGUgcmVwb3J0ZXIgc29tZXRoaW5nIGhhcHBlbmVkLiBPdGhlcndpc2UsIGl0J2xsIGhhdmUgdG8gd3JhcCB0aGlzXG4gICAgLy8gbWV0aG9kIGluIGEgcGx1Z2luLCB3aGljaCBzaG91bGRuJ3QgYmUgbmVjZXNzYXJ5LlxuICAgIC5jYXRjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICByZXR1cm4gcmVwb3J0RXJyb3IoY29udGV4dCwgZSkudGhlbihmdW5jdGlvbiAoKSB7IHRocm93IGUgfSlcbiAgICB9KVxuICAgIC50aGVuKFxuICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjbGVhckNoaWxkcmVuKHJvb3QpXG4gICAgICAgICAgICByb290LmxvY2tlZCA9IGZhbHNlXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGlzU3VjY2VzczogY29udGV4dC5pc1N1Y2Nlc3MsXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBjbGVhckNoaWxkcmVuKHJvb3QpXG4gICAgICAgICAgICByb290LmxvY2tlZCA9IGZhbHNlXG4gICAgICAgICAgICB0aHJvdyBlXG4gICAgICAgIH0pXG59XG5cbi8vIEhlbHAgb3B0aW1pemUgZm9yIGluZWZmaWNpZW50IGV4Y2VwdGlvbiBoYW5kbGluZyBpbiBWOFxuXG5mdW5jdGlvbiB0cnlQYXNzKHZhbHVlKSB7XG4gICAgcmV0dXJuIHtjYXVnaHQ6IGZhbHNlLCB2YWx1ZTogdmFsdWV9XG59XG5cbmZ1bmN0aW9uIHRyeUZhaWwoZSkge1xuICAgIHJldHVybiB7Y2F1Z2h0OiB0cnVlLCB2YWx1ZTogZX1cbn1cblxuZnVuY3Rpb24gdHJ5MChmKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHRyeVBhc3MoZigpKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIHRyeUZhaWwoZSlcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRyeTEoZiwgaW5zdCwgYXJnMCkge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB0cnlQYXNzKGYuY2FsbChpbnN0LCBhcmcwKSlcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiB0cnlGYWlsKGUpXG4gICAgfVxufVxuXG5mdW5jdGlvbiB0cnkyKGYsIGluc3QsIGFyZzAsIGFyZzEpIHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gdHJ5UGFzcyhmLmNhbGwoaW5zdCwgYXJnMCwgYXJnMSkpXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gdHJ5RmFpbChlKVxuICAgIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogVGhlIERPTSByZXBvcnRlciBhbmQgbG9hZGVyIGVudHJ5IHBvaW50LiBTZWUgdGhlIFJFQURNRS5tZCBmb3IgbW9yZSBkZXRhaWxzLlxuICovXG5cbnZhciBpbml0aWFsaXplID0gcmVxdWlyZShcIi4vaW5pdGlhbGl6ZVwiKVxuLy8gdmFyIHQgPSByZXF1aXJlKFwiLi4vLi4vaW5kZXhcIilcbi8vIHZhciBhc3NlcnQgPSByZXF1aXJlKFwiLi4vLi4vYXNzZXJ0XCIpXG5cbmV4cG9ydHMuY3JlYXRlID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgICBpZiAob3B0cyA9PSBudWxsKSByZXR1cm4gaW5pdGlhbGl6ZSh7fSlcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvcHRzKSkgcmV0dXJuIGluaXRpYWxpemUoe2ZpbGVzOiBvcHRzfSlcbiAgICBpZiAodHlwZW9mIG9wdHMgPT09IFwib2JqZWN0XCIpIHJldHVybiBpbml0aWFsaXplKG9wdHMpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBvcHRzYCBtdXN0IGJlIGFuIG9iamVjdCBvciBhcnJheSBvZiBmaWxlcyBpZiBwYXNzZWRcIilcbn1cblxuLy8gQ3VycmVudGx5IGJyb2tlbiwgYmVjYXVzZSB0aGlzIGlzbid0IGF1dG9sb2FkZWQgeWV0LlxuLy8gZXhwb3J0cy5hdXRvbG9hZCA9IGZ1bmN0aW9uIChzY3JpcHQpIHtcbi8vICAgICB2YXIgZmlsZXMgPSBzY3JpcHQuZ2V0QXR0cmlidXRlKFwiZGF0YS1maWxlc1wiKVxuLy9cbi8vICAgICBpZiAoIWZpbGVzKSByZXR1cm5cbi8vXG4vLyAgICAgZnVuY3Rpb24gc2V0KG9wdHMsIGF0dHIsIHRyYW5zZm9ybSkge1xuLy8gICAgICAgICB2YXIgdmFsdWUgPSBzY3JpcHQuZ2V0QXR0cmlidXRlKFwiZGF0YS1cIiArIGF0dHIpXG4vL1xuLy8gICAgICAgICBpZiAodmFsdWUpIG9wdHNbYXR0cl0gPSB0cmFuc2Zvcm0odmFsdWUpXG4vLyAgICAgfVxuLy9cbi8vICAgICB2YXIgb3B0cyA9IHtmaWxlczogZmlsZXMudHJpbSgpLnNwbGl0KC9cXHMrL2cpfVxuLy9cbi8vICAgICBzZXQob3B0cywgXCJ0aW1lb3V0XCIsIE51bWJlcilcbi8vICAgICBzZXQob3B0cywgXCJwcmVsb2FkXCIsIEZ1bmN0aW9uKVxuLy8gICAgIHNldChvcHRzLCBcInByZXJ1blwiLCBGdW5jdGlvbilcbi8vICAgICBzZXQob3B0cywgXCJwb3N0cnVuXCIsIEZ1bmN0aW9uKVxuLy8gICAgIHNldChvcHRzLCBcImVycm9yXCIsIGZ1bmN0aW9uIChhdHRyKSB7XG4vLyAgICAgICAgIHJldHVybiBuZXcgRnVuY3Rpb24oXCJlcnJcIiwgYXR0cikgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuLy8gICAgIH0pXG4vL1xuLy8gICAgIC8vIENvbnZlbmllbmNlLlxuLy8gICAgIGdsb2JhbC50ID0gdFxuLy8gICAgIGdsb2JhbC5hc3NlcnQgPSBhc3NlcnRcbi8vXG4vLyAgICAgaWYgKGdsb2JhbC5kb2N1bWVudC5yZWFkeVN0YXRlICE9PSBcImxvYWRpbmdcIikge1xuLy8gICAgICAgICBpbml0aWFsaXplKG9wdHMpLnJ1bigpXG4vLyAgICAgfSBlbHNlIHtcbi8vICAgICAgICAgZ2xvYmFsLmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uICgpIHtcbi8vICAgICAgICAgICAgIGluaXRpYWxpemUob3B0cykucnVuKClcbi8vICAgICAgICAgfSlcbi8vICAgICB9XG4vLyB9XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vKipcbiAqIFRoZSByZXBvcnRlciBhbmQgdGVzdCBpbml0aWFsaXphdGlvbiBzZXF1ZW5jZSwgYW5kIHNjcmlwdCBsb2FkaW5nLiBUaGlzXG4gKiBkb2Vzbid0IHVuZGVyc3RhbmQgYW55dGhpbmcgdmlldy13aXNlLlxuICovXG5cbnZhciBkZWZhdWx0VCA9IHJlcXVpcmUoXCIuLi8uLi9pbmRleFwiKVxudmFyIFIgPSByZXF1aXJlKFwiLi4vcmVwb3J0ZXJcIilcbnZhciBEID0gcmVxdWlyZShcIi4vaW5qZWN0XCIpXG52YXIgcnVuVGVzdHMgPSByZXF1aXJlKFwiLi9ydW4tdGVzdHNcIilcbnZhciBpbmplY3RTdHlsZXMgPSByZXF1aXJlKFwiLi9pbmplY3Qtc3R5bGVzXCIpXG52YXIgVmlldyA9IHJlcXVpcmUoXCIuL3ZpZXdcIilcbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcblxuZnVuY3Rpb24gVHJlZShuYW1lKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZVxuICAgIHRoaXMuc3RhdHVzID0gUi5TdGF0dXMuVW5rbm93blxuICAgIHRoaXMubm9kZSA9IG51bGxcbiAgICB0aGlzLmNoaWxkcmVuID0gT2JqZWN0LmNyZWF0ZShudWxsKVxufVxuXG52YXIgcmVwb3J0ZXIgPSBSLm9uKFwiZG9tXCIsIHtcbiAgICBhY2NlcHRzOiBbXSxcbiAgICBjcmVhdGU6IGZ1bmN0aW9uIChvcHRzLCBtZXRob2RzKSB7XG4gICAgICAgIHZhciByZXBvcnRlciA9IG5ldyBSLlJlcG9ydGVyKFRyZWUsIHVuZGVmaW5lZCwgbWV0aG9kcylcblxuICAgICAgICByZXBvcnRlci5vcHRzID0gb3B0c1xuICAgICAgICByZXR1cm4gcmVwb3J0ZXJcbiAgICB9LFxuXG4gICAgLy8gR2l2ZSB0aGUgYnJvd3NlciBhIGNoYW5jZSB0byByZXBhaW50IGJlZm9yZSBjb250aW51aW5nIChtaWNyb3Rhc2tzXG4gICAgLy8gbm9ybWFsbHkgYmxvY2sgcmVuZGVyaW5nKS5cbiAgICBhZnRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoVmlldy5uZXh0RnJhbWUpXG4gICAgfSxcblxuICAgIHJlcG9ydDogZnVuY3Rpb24gKF8sIHJlcG9ydCkge1xuICAgICAgICByZXR1cm4gVmlldy5yZXBvcnQoXywgcmVwb3J0KVxuICAgIH0sXG59KVxuXG5mdW5jdGlvbiBub29wKCkge31cblxuZnVuY3Rpb24gc2V0RGVmYXVsdHNDaGVja2VkKG9wdHMpIHtcbiAgICBpZiAob3B0cy50aXRsZSA9PSBudWxsKSBvcHRzLnRpdGxlID0gXCJUaGFsbGl1bSB0ZXN0c1wiXG4gICAgaWYgKG9wdHMudGltZW91dCA9PSBudWxsKSBvcHRzLnRpbWVvdXQgPSA1MDAwXG4gICAgaWYgKG9wdHMuZmlsZXMgPT0gbnVsbCkgb3B0cy5maWxlcyA9IFtdXG4gICAgaWYgKG9wdHMucHJlbG9hZCA9PSBudWxsKSBvcHRzLnByZWxvYWQgPSBub29wXG4gICAgaWYgKG9wdHMucHJlcnVuID09IG51bGwpIG9wdHMucHJlcnVuID0gbm9vcFxuICAgIGlmIChvcHRzLnBvc3RydW4gPT0gbnVsbCkgb3B0cy5wb3N0cnVuID0gbm9vcFxuICAgIGlmIChvcHRzLmVycm9yID09IG51bGwpIG9wdHMuZXJyb3IgPSBub29wXG4gICAgaWYgKG9wdHMudGhhbGxpdW0gPT0gbnVsbCkgb3B0cy50aGFsbGl1bSA9IGRlZmF1bHRUXG5cbiAgICBpZiAodHlwZW9mIG9wdHMudGl0bGUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBvcHRzLnRpdGxlYCBtdXN0IGJlIGEgc3RyaW5nIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy50aW1lb3V0ICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgb3B0cy50aW1lb3V0YCBtdXN0IGJlIGEgbnVtYmVyIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheShvcHRzLmZpbGVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMuZmlsZXNgIG11c3QgYmUgYW4gYXJyYXkgaWYgcGFzc2VkXCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLnByZWxvYWQgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMucHJlbG9hZGAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5wcmVydW4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMucHJlcnVuYCBtdXN0IGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLnBvc3RydW4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMucG9zdHJ1bmAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5lcnJvciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgb3B0cy5lcnJvcmAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy50aGFsbGl1bSAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgXCJgb3B0cy50aGFsbGl1bWAgbXVzdCBiZSBhIFRoYWxsaXVtIGluc3RhbmNlIGlmIHBhc3NlZFwiKVxuICAgIH1cbn1cblxuZnVuY3Rpb24gb25SZWFkeShpbml0KSB7XG4gICAgaWYgKEQuZG9jdW1lbnQuYm9keSAhPSBudWxsKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGluaXQoKSlcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgRC5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXNvbHZlKGluaXQoKSlcbiAgICAgICAgfSwgZmFsc2UpXG4gICAgfSlcbn1cblxuZnVuY3Rpb24gRE9NKG9wdHMpIHtcbiAgICB0aGlzLl9vcHRzID0gb3B0c1xuICAgIHRoaXMuX2Rlc3Ryb3lQcm9taXNlID0gdW5kZWZpbmVkXG4gICAgdGhpcy5fZGF0YSA9IG9uUmVhZHkoZnVuY3Rpb24gKCkge1xuICAgICAgICBzZXREZWZhdWx0c0NoZWNrZWQob3B0cylcbiAgICAgICAgaWYgKCFELmRvY3VtZW50LnRpdGxlKSBELmRvY3VtZW50LnRpdGxlID0gb3B0cy50aXRsZVxuICAgICAgICBpbmplY3RTdHlsZXMoKVxuICAgICAgICB2YXIgZGF0YSA9IFZpZXcuaW5pdChvcHRzKVxuXG4gICAgICAgIG9wdHMudGhhbGxpdW0ucmVwb3J0ZXIocmVwb3J0ZXIsIGRhdGEuc3RhdGUpXG4gICAgICAgIHJldHVybiBkYXRhXG4gICAgfSlcbn1cblxubWV0aG9kcyhET00sIHtcbiAgICBydW46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2Rlc3Ryb3lQcm9taXNlICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJUaGUgdGVzdCBzdWl0ZSBtdXN0IG5vdCBiZSBydW4gYWZ0ZXIgdGhlIHZpZXcgaGFzIGJlZW4gXCIgK1xuICAgICAgICAgICAgICAgIFwiZGV0YWNoZWQuXCJcbiAgICAgICAgICAgICkpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgb3B0cyA9IHRoaXMuX29wdHNcblxuICAgICAgICByZXR1cm4gdGhpcy5fZGF0YS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICByZXR1cm4gcnVuVGVzdHMob3B0cywgZGF0YS5zdGF0ZSlcbiAgICAgICAgfSlcbiAgICB9LFxuXG4gICAgZGV0YWNoOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kZXN0cm95UHJvbWlzZSAhPSBudWxsKSByZXR1cm4gdGhpcy5fZGVzdHJveVByb21pc2VcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rlc3Ryb3lQcm9taXNlID0gc2VsZi5fZGF0YS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICBkYXRhLnN0YXRlLmxvY2tlZCA9IHRydWVcbiAgICAgICAgICAgIGlmIChkYXRhLnN0YXRlLmN1cnJlbnRQcm9taXNlID09IG51bGwpIHJldHVybiBkYXRhXG4gICAgICAgICAgICByZXR1cm4gZGF0YS5zdGF0ZS5jdXJyZW50UHJvbWlzZS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRhdGEgfSlcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgIHNlbGYuX29wdHMgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIHNlbGYuX2RhdGEgPSBzZWxmLl9kZXN0cm95UHJvbWlzZVxuXG4gICAgICAgICAgICB3aGlsZSAoZGF0YS5yb290LmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBkYXRhLnJvb3QucmVtb3ZlQ2hpbGQoZGF0YS5yb290LmZpcnN0Q2hpbGQpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfSxcbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgICByZXR1cm4gbmV3IERPTShvcHRzKVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIFV0aWwgPSByZXF1aXJlKFwiLi4vdXRpbFwiKVxudmFyIEQgPSByZXF1aXJlKFwiLi9pbmplY3RcIilcblxuLyoqXG4gKiBUaGUgcmVwb3J0ZXIgc3R5bGVzaGVldC4gSGVyZSdzIHRoZSBmb3JtYXQ6XG4gKlxuICogLy8gU2luZ2xlIGl0ZW1cbiAqIFwiLnNlbGVjdG9yXCI6IHtcbiAqICAgICAvLyBwcm9wcy4uLlxuICogfVxuICpcbiAqIC8vIER1cGxpY2F0ZSBlbnRyaWVzXG4gKiBcIi5zZWxlY3RvclwiOiB7XG4gKiAgICAgXCJwcm9wXCI6IFtcbiAqICAgICAgICAgLy8gdmFsdWVzLi4uXG4gKiAgICAgXSxcbiAqIH1cbiAqXG4gKiAvLyBEdXBsaWNhdGUgc2VsZWN0b3JzXG4gKiBcIi5zZWxlY3RvclwiOiBbXG4gKiAgICAgLy8gdmFsdWVzLi4uXG4gKiBdXG4gKlxuICogLy8gTWVkaWEgcXVlcnlcbiAqIFwiQG1lZGlhIHNjcmVlblwiOiB7XG4gKiAgICAgLy8gc2VsZWN0b3JzLi4uXG4gKiB9XG4gKlxuICogTm90ZSB0aGF0IENTUyBzdHJpbmdzICptdXN0KiBiZSBxdW90ZWQgaW5zaWRlIHRoZSB2YWx1ZS5cbiAqL1xuXG52YXIgc3R5bGVzID0gVXRpbC5sYXp5KGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eVxuXG4gICAgLyoqXG4gICAgICogUGFydGlhbGx5IHRha2VuIGFuZCBhZGFwdGVkIGZyb20gbm9ybWFsaXplLmNzcyAobGljZW5zZWQgdW5kZXIgdGhlIE1JVFxuICAgICAqIExpY2Vuc2UpLlxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9uZWNvbGFzL25vcm1hbGl6ZS5jc3NcbiAgICAgKi9cbiAgICB2YXIgc3R5bGVPYmplY3QgPSB7XG4gICAgICAgIFwiI3RsXCI6IHtcbiAgICAgICAgICAgIFwiZm9udC1mYW1pbHlcIjogXCJzYW5zLXNlcmlmXCIsXG4gICAgICAgICAgICBcImxpbmUtaGVpZ2h0XCI6IFwiMS4xNVwiLFxuICAgICAgICAgICAgXCItbXMtdGV4dC1zaXplLWFkanVzdFwiOiBcIjEwMCVcIixcbiAgICAgICAgICAgIFwiLXdlYmtpdC10ZXh0LXNpemUtYWRqdXN0XCI6IFwiMTAwJVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIGJ1dHRvblwiOiB7XG4gICAgICAgICAgICBcImZvbnQtZmFtaWx5XCI6IFwic2Fucy1zZXJpZlwiLFxuICAgICAgICAgICAgXCJsaW5lLWhlaWdodFwiOiBcIjEuMTVcIixcbiAgICAgICAgICAgIFwib3ZlcmZsb3dcIjogXCJ2aXNpYmxlXCIsXG4gICAgICAgICAgICBcImZvbnQtc2l6ZVwiOiBcIjEwMCVcIixcbiAgICAgICAgICAgIFwibWFyZ2luXCI6IFwiMFwiLFxuICAgICAgICAgICAgXCJ0ZXh0LXRyYW5zZm9ybVwiOiBcIm5vbmVcIixcbiAgICAgICAgICAgIFwiLXdlYmtpdC1hcHBlYXJhbmNlXCI6IFwiYnV0dG9uXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgaDFcIjoge1xuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIyZW1cIixcbiAgICAgICAgICAgIFwibWFyZ2luXCI6IFwiMC42N2VtIDBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCBhXCI6IHtcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcInRyYW5zcGFyZW50XCIsXG4gICAgICAgICAgICBcIi13ZWJraXQtdGV4dC1kZWNvcmF0aW9uLXNraXBcIjogXCJvYmplY3RzXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgYTphY3RpdmUsICN0bCBhOmhvdmVyXCI6IHtcbiAgICAgICAgICAgIFwib3V0bGluZS13aWR0aFwiOiBcIjBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCBidXR0b246Oi1tb3otZm9jdXMtaW5uZXJcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItc3R5bGVcIjogXCJub25lXCIsXG4gICAgICAgICAgICBcInBhZGRpbmdcIjogXCIwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgYnV0dG9uOi1tb3otZm9jdXNyaW5nXCI6IHtcbiAgICAgICAgICAgIG91dGxpbmU6IFwiMXB4IGRvdHRlZCBCdXR0b25UZXh0XCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEJhc2Ugc3R5bGVzLiBOb3RlIHRoYXQgdGhpcyBDU1MgaXMgZGVzaWduZWQgdG8gaW50ZW50aW9uYWxseSBvdmVycmlkZVxuICAgICAgICAgKiBtb3N0IHRoaW5ncyB0aGF0IGNvdWxkIHByb3BhZ2F0ZS5cbiAgICAgICAgICovXG4gICAgICAgIFwiI3RsICpcIjogW1xuICAgICAgICAgICAge1widGV4dC1hbGlnblwiOiBcImxlZnRcIn0sXG4gICAgICAgICAgICB7XCJ0ZXh0LWFsaWduXCI6IFwic3RhcnRcIn0sXG4gICAgICAgIF0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydCwgI3RsIC50bC1yZXBvcnQgdWxcIjoge1xuICAgICAgICAgICAgXCJsaXN0LXN0eWxlLXR5cGVcIjogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgbGkgfiAudGwtc3VpdGVcIjoge1xuICAgICAgICAgICAgXCJwYWRkaW5nLXRvcFwiOiBcIjFlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1zdWl0ZSA+IGgyXCI6IHtcbiAgICAgICAgICAgIFwiY29sb3JcIjogXCJibGFja1wiLFxuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIxLjVlbVwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcImJvbGRcIixcbiAgICAgICAgICAgIFwibWFyZ2luLWJvdHRvbVwiOiBcIjAuNWVtXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXN1aXRlIC50bC1zdWl0ZSA+IGgyXCI6IHtcbiAgICAgICAgICAgIFwiZm9udC1zaXplXCI6IFwiMS4yZW1cIixcbiAgICAgICAgICAgIFwibWFyZ2luLWJvdHRvbVwiOiBcIjAuM2VtXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXN1aXRlIC50bC1zdWl0ZSAudGwtc3VpdGUgPiBoMlwiOiB7XG4gICAgICAgICAgICBcImZvbnQtc2l6ZVwiOiBcIjEuMmVtXCIsXG4gICAgICAgICAgICBcIm1hcmdpbi1ib3R0b21cIjogXCIwLjJlbVwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcIm5vcm1hbFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0ID4gaDJcIjoge1xuICAgICAgICAgICAgXCJjb2xvclwiOiBcImJsYWNrXCIsXG4gICAgICAgICAgICBcImZvbnQtc2l6ZVwiOiBcIjFlbVwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcIm5vcm1hbFwiLFxuICAgICAgICAgICAgXCJtYXJnaW5cIjogXCIwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRlc3QgPiA6Zmlyc3QtY2hpbGQ6OmJlZm9yZVwiOiB7XG4gICAgICAgICAgICBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgICAgICAgIFwiZm9udC13ZWlnaHRcIjogXCJib2xkXCIsXG4gICAgICAgICAgICBcIndpZHRoXCI6IFwiMS4yZW1cIixcbiAgICAgICAgICAgIFwidGV4dC1hbGlnblwiOiBcImNlbnRlclwiLFxuICAgICAgICAgICAgXCJmb250LWZhbWlseVwiOiBcInNhbnMtc2VyaWZcIixcbiAgICAgICAgICAgIFwidGV4dC1zaGFkb3dcIjogXCIwIDNweCAycHggIzk2OTY5NlwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0LnRsLWZhaWwgPiBoMiwgI3RsIC50bC10ZXN0LnRsLWVycm9yID4gaDJcIjoge1xuICAgICAgICAgICAgY29sb3I6IFwiI2MwMFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0LnRsLXNraXAgPiBoMlwiOiB7XG4gICAgICAgICAgICBjb2xvcjogXCIjMDhjXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRlc3QudGwtcGFzcyA+IDpmaXJzdC1jaGlsZDo6YmVmb3JlXCI6IHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFwiJ+KckydcIixcbiAgICAgICAgICAgIGNvbG9yOiBcIiMwYzBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdGVzdC50bC1mYWlsID4gOmZpcnN0LWNoaWxkOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCIn4pyWJ1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0LnRsLWVycm9yID4gOmZpcnN0LWNoaWxkOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCInISdcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdGVzdC50bC1za2lwID4gOmZpcnN0LWNoaWxkOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCIn4oiSJ1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1wcmUsICN0bCAudGwtZGlmZi1oZWFkZXJcIjoge1xuICAgICAgICAgICAgLy8gbm9ybWFsaXplLmNzczogQ29ycmVjdCB0aGUgaW5oZXJpdGFuY2UgYW5kIHNjYWxpbmcgb2YgZm9udCBzaXplXG4gICAgICAgICAgICAvLyBpbiBhbGwgYnJvd3NlcnNcbiAgICAgICAgICAgIFwiZm9udC1mYW1pbHlcIjogXCJtb25vc3BhY2UsIG1vbm9zcGFjZVwiLFxuICAgICAgICAgICAgXCJiYWNrZ3JvdW5kXCI6IFwiI2YwZjBmMFwiLFxuICAgICAgICAgICAgXCJ3aGl0ZS1zcGFjZVwiOiBcInByZVwiLFxuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIwLjg1ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtcHJlXCI6IHtcbiAgICAgICAgICAgIFwibWluLXdpZHRoXCI6IFwiMTAwJVwiLFxuICAgICAgICAgICAgXCJmbG9hdFwiOiBcImxlZnRcIixcbiAgICAgICAgICAgIFwiY2xlYXJcIjogXCJsZWZ0XCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLWxpbmVcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJibG9ja1wiLFxuICAgICAgICAgICAgbWFyZ2luOiBcIjAgMC4yNWVtXCIsXG4gICAgICAgICAgICB3aWR0aDogXCI5OSVcIiwgLy8gQmVjYXVzZSBGaXJlZm94IHN1Y2tzXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLWRpZmYtaGVhZGVyID4gKlwiOiB7XG4gICAgICAgICAgICBwYWRkaW5nOiBcIjAuMjVlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1kaWZmLWhlYWRlclwiOiB7XG4gICAgICAgICAgICBcInBhZGRpbmdcIjogXCIwLjI1ZW1cIixcbiAgICAgICAgICAgIFwibWFyZ2luLWJvdHRvbVwiOiBcIjAuNWVtXCIsXG4gICAgICAgICAgICBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtbGluZTpmaXJzdC1jaGlsZCwgI3RsIC50bC1kaWZmLWhlYWRlciB+IC50bC1saW5lXCI6IHtcbiAgICAgICAgICAgIFwicGFkZGluZy10b3BcIjogXCIwLjI1ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtbGluZTpsYXN0LWNoaWxkXCI6IHtcbiAgICAgICAgICAgIFwicGFkZGluZy1ib3R0b21cIjogXCIwLjI1ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZmFpbCAudGwtZGlzcGxheVwiOiB7XG4gICAgICAgICAgICBtYXJnaW46IFwiMC41ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZGlzcGxheSA+ICpcIjoge1xuICAgICAgICAgICAgb3ZlcmZsb3c6IFwiYXV0b1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1kaXNwbGF5ID4gOm5vdCg6bGFzdC1jaGlsZClcIjoge1xuICAgICAgICAgICAgXCJtYXJnaW4tYm90dG9tXCI6IFwiMC41ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZGlmZi1hZGRlZFwiOiB7XG4gICAgICAgICAgICBcImNvbG9yXCI6IFwiIzBjMFwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcImJvbGRcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZGlmZi1yZW1vdmVkXCI6IHtcbiAgICAgICAgICAgIFwiY29sb3JcIjogXCIjYzAwXCIsXG4gICAgICAgICAgICBcImZvbnQtd2VpZ2h0XCI6IFwiYm9sZFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1zdGFjayAudGwtbGluZVwiOiB7XG4gICAgICAgICAgICBjb2xvcjogXCIjODAwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLWRpZmY6OmJlZm9yZSwgI3RsIC50bC1zdGFjazo6YmVmb3JlXCI6IHtcbiAgICAgICAgICAgIFwiZm9udC13ZWlnaHRcIjogXCJub3JtYWxcIixcbiAgICAgICAgICAgIFwibWFyZ2luXCI6IFwiMC4yNWVtIDAuMjVlbSAwLjI1ZW0gMFwiLFxuICAgICAgICAgICAgXCJkaXNwbGF5XCI6IFwiYmxvY2tcIixcbiAgICAgICAgICAgIFwiZm9udC1zdHlsZVwiOiBcIml0YWxpY1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1kaWZmOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCInRGlmZjonXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXN0YWNrOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCInU3RhY2s6J1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1oZWFkZXJcIjoge1xuICAgICAgICAgICAgXCJ0ZXh0LWFsaWduXCI6IFwicmlnaHRcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtaGVhZGVyID4gKlwiOiB7XG4gICAgICAgICAgICBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgICAgICAgIFwidGV4dC1hbGlnblwiOiBcImNlbnRlclwiLFxuICAgICAgICAgICAgXCJwYWRkaW5nXCI6IFwiMC41ZW0gMC43NWVtXCIsXG4gICAgICAgICAgICBcImJvcmRlclwiOiBcIjJweCBzb2xpZCAjMDBjXCIsXG4gICAgICAgICAgICBcImJvcmRlci1yYWRpdXNcIjogXCIxZW1cIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcInRyYW5zcGFyZW50XCIsXG4gICAgICAgICAgICBcIm1hcmdpblwiOiBcIjAuMjVlbSAwLjVlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1oZWFkZXIgPiA6Zm9jdXNcIjoge1xuICAgICAgICAgICAgb3V0bGluZTogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJ1blwiOiB7XG4gICAgICAgICAgICBcImJvcmRlci1jb2xvclwiOiBcIiMwODBcIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcIiMwYzBcIixcbiAgICAgICAgICAgIFwiY29sb3JcIjogXCJ3aGl0ZVwiLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiBcIjZlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1ydW46aG92ZXJcIjoge1xuICAgICAgICAgICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCI6IFwiIzhjOFwiLFxuICAgICAgICAgICAgXCJjb2xvclwiOiBcIndoaXRlXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1wYXNzXCI6IHtcbiAgICAgICAgICAgIFwiYm9yZGVyLWNvbG9yXCI6IFwiIzBjMFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10b2dnbGUudGwtZmFpbFwiOiB7XG4gICAgICAgICAgICBcImJvcmRlci1jb2xvclwiOiBcIiNjMDBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdG9nZ2xlLnRsLXNraXBcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDhjXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1wYXNzLnRsLWFjdGl2ZSwgI3RsIC50bC10b2dnbGUudGwtcGFzczphY3RpdmVcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDgwXCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjMGMwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1mYWlsLnRsLWFjdGl2ZSwgI3RsIC50bC10b2dnbGUudGwtZmFpbDphY3RpdmVcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjODAwXCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjYzAwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1za2lwLnRsLWFjdGl2ZSwgI3RsIC50bC10b2dnbGUudGwtc2tpcDphY3RpdmVcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDU4XCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjMDhjXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1wYXNzOmhvdmVyXCI6IHtcbiAgICAgICAgICAgIFwiYm9yZGVyLWNvbG9yXCI6IFwiIzBjMFwiLFxuICAgICAgICAgICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCI6IFwiI2FmYVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10b2dnbGUudGwtZmFpbDpob3ZlclwiOiB7XG4gICAgICAgICAgICBcImJvcmRlci1jb2xvclwiOiBcIiNjMDBcIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcIiNmYWFcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdG9nZ2xlLnRsLXNraXA6aG92ZXJcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDhjXCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjYmRmXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydC50bC1wYXNzIC50bC10ZXN0Om5vdCgudGwtcGFzcylcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydC50bC1mYWlsIC50bC10ZXN0Om5vdCgudGwtZmFpbClcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydC50bC1za2lwIC50bC10ZXN0Om5vdCgudGwtc2tpcClcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJub25lXCIsXG4gICAgICAgIH0sXG4gICAgfVxuXG4gICAgdmFyIGNzcyA9IFwiXCJcblxuICAgIGZ1bmN0aW9uIGFwcGVuZEJhc2Uoc2VsZWN0b3IsIHByb3BzKSB7XG4gICAgICAgIGNzcyArPSBzZWxlY3RvciArIFwie1wiXG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocHJvcHMpKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgYXBwZW5kUHJvcHMocHJvcHNbaV0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhcHBlbmRQcm9wcyhwcm9wcylcbiAgICAgICAgfVxuXG4gICAgICAgIGNzcyArPSBcIn1cIlxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFwcGVuZFByb3BzKHByb3BzKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBwcm9wcykge1xuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKHByb3BzLCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwcm9wc1trZXldID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGFwcGVuZEJhc2Uoa2V5LCBwcm9wc1trZXldKVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNzcyArPSBrZXkgKyBcIjpcIiArIHByb3BzW2tleV0gKyBcIjtcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIHNlbGVjdG9yIGluIHN0eWxlT2JqZWN0KSB7XG4gICAgICAgIGlmIChoYXNPd24uY2FsbChzdHlsZU9iamVjdCwgc2VsZWN0b3IpKSB7XG4gICAgICAgICAgICBhcHBlbmRCYXNlKHNlbGVjdG9yLCBzdHlsZU9iamVjdFtzZWxlY3Rvcl0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY3NzLmNvbmNhdCgpIC8vIEhpbnQgdG8gZmxhdHRlbi5cbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICAgIGlmIChELmRvY3VtZW50LmhlYWQucXVlcnlTZWxlY3RvcihcInN0eWxlW2RhdGEtdGwtc3R5bGVdXCIpID09IG51bGwpIHtcbiAgICAgICAgdmFyIHN0eWxlID0gRC5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIilcblxuICAgICAgICBzdHlsZS50eXBlID0gXCJ0ZXh0L2Nzc1wiXG4gICAgICAgIHN0eWxlLnNldEF0dHJpYnV0ZShcImRhdGEtdGwtc3R5bGVcIiwgXCJcIilcbiAgICAgICAgaWYgKHN0eWxlLnN0eWxlU2hlZXQpIHtcbiAgICAgICAgICAgIHN0eWxlLnN0eWxlU2hlZXQuY3NzVGV4dCA9IHN0eWxlcygpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHlsZS5hcHBlbmRDaGlsZChELmRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN0eWxlcygpKSlcbiAgICAgICAgfVxuXG4gICAgICAgIEQuZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSlcbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vKipcbiAqIFRoZSBnbG9iYWwgaW5qZWN0aW9ucyBmb3IgdGhlIERPTS4gTWFpbmx5IGZvciBkZWJ1Z2dpbmcuXG4gKi9cblxuZXhwb3J0cy5kb2N1bWVudCA9IGdsb2JhbC5kb2N1bWVudFxuZXhwb3J0cy53aW5kb3cgPSBnbG9iYWwud2luZG93XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpXG52YXIgRCA9IHJlcXVpcmUoXCIuL2luamVjdFwiKVxudmFyIG5vdyA9IERhdGUubm93IC8vIEF2b2lkIFNpbm9uJ3MgbW9ja1xudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuLyoqXG4gKiBUZXN0IHJ1bm5lciBhbmQgc2NyaXB0IGxvYWRlclxuICovXG5cbmZ1bmN0aW9uIHVuY2FjaGVkKGZpbGUpIHtcbiAgICBpZiAoZmlsZS5pbmRleE9mKFwiP1wiKSA8IDApIHtcbiAgICAgICAgcmV0dXJuIGZpbGUgKyBcIj9sb2FkZWQ9XCIgKyBub3coKVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmaWxlICsgXCImbG9hZGVkPVwiICsgbm93KClcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxvYWRTY3JpcHQoZmlsZSwgdGltZW91dCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHZhciBzY3JpcHQgPSBELmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIilcbiAgICAgICAgdmFyIHRpbWVyID0gZ2xvYmFsLnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY2xlYXIoKVxuICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIlRpbWVvdXQgZXhjZWVkZWQgbG9hZGluZyAnXCIgKyBmaWxlICsgXCInXCIpKVxuICAgICAgICB9LCB0aW1lb3V0KVxuXG4gICAgICAgIGZ1bmN0aW9uIGNsZWFyKGV2KSB7XG4gICAgICAgICAgICBpZiAoZXYgIT0gbnVsbCkgZXYucHJldmVudERlZmF1bHQoKVxuICAgICAgICAgICAgaWYgKGV2ICE9IG51bGwpIGV2LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICAgICAgICBnbG9iYWwuY2xlYXJUaW1lb3V0KHRpbWVyKVxuICAgICAgICAgICAgc2NyaXB0Lm9ubG9hZCA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgc2NyaXB0Lm9uZXJyb3IgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIEQuZG9jdW1lbnQuaGVhZC5yZW1vdmVDaGlsZChzY3JpcHQpXG4gICAgICAgIH1cblxuICAgICAgICBzY3JpcHQuc3JjID0gdW5jYWNoZWQoZmlsZSlcbiAgICAgICAgc2NyaXB0LmFzeW5jID0gdHJ1ZVxuICAgICAgICBzY3JpcHQuZGVmZXIgPSB0cnVlXG4gICAgICAgIHNjcmlwdC5vbmxvYWQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIGNsZWFyKGV2KVxuICAgICAgICAgICAgcmVzb2x2ZSgpXG4gICAgICAgIH1cblxuICAgICAgICBzY3JpcHQub25lcnJvciA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgY2xlYXIoZXYpXG4gICAgICAgICAgICByZWplY3QoZXYpXG4gICAgICAgIH1cblxuICAgICAgICBELmRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIHRyeURlbGV0ZShrZXkpIHtcbiAgICB0cnkge1xuICAgICAgICBkZWxldGUgZ2xvYmFsW2tleV1cbiAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgIC8vIGlnbm9yZVxuICAgIH1cbn1cblxuZnVuY3Rpb24gZGVzY3JpcHRvckNoYW5nZWQoYSwgYikge1xuICAgIC8vIE5vdGU6IGlmIHRoZSBkZXNjcmlwdG9yIHdhcyByZW1vdmVkLCBpdCB3b3VsZCd2ZSBiZWVuIGRlbGV0ZWQsIGFueXdheXMuXG4gICAgaWYgKGEgPT0gbnVsbCkgcmV0dXJuIGZhbHNlXG4gICAgaWYgKGEuY29uZmlndXJhYmxlICE9PSBiLmNvbmZpZ3VyYWJsZSkgcmV0dXJuIHRydWVcbiAgICBpZiAoYS5lbnVtZXJhYmxlICE9PSBiLmVudW1lcmFibGUpIHJldHVybiB0cnVlXG4gICAgaWYgKGEud3JpdGFibGUgIT09IGIud3JpdGFibGUpIHJldHVybiB0cnVlXG4gICAgaWYgKGEuZ2V0ICE9PSBiLmdldCkgcmV0dXJuIHRydWVcbiAgICBpZiAoYS5zZXQgIT09IGIuc2V0KSByZXR1cm4gdHJ1ZVxuICAgIGlmIChhLnZhbHVlICE9PSBiLnZhbHVlKSByZXR1cm4gdHJ1ZVxuICAgIHJldHVybiBmYWxzZVxufVxuXG4vLyBUaGVzZSBmaXJlIGRlcHJlY2F0aW9uIHdhcm5pbmdzLCBhbmQgdGh1cyBzaG91bGQgYmUgYXZvaWRlZC5cbnZhciBibGFja2xpc3QgPSBPYmplY3QuZnJlZXplKHtcbiAgICB3ZWJraXRTdG9yYWdlSW5mbzogdHJ1ZSxcbiAgICB3ZWJraXRJbmRleGVkREI6IHRydWUsXG59KVxuXG5mdW5jdGlvbiBmaW5kR2xvYmFscygpIHtcbiAgICB2YXIgZm91bmQgPSBPYmplY3Qua2V5cyhnbG9iYWwpXG4gICAgdmFyIGdsb2JhbHMgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZvdW5kLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBmb3VuZFtpXVxuXG4gICAgICAgIGlmICghaGFzT3duLmNhbGwoYmxhY2tsaXN0LCBrZXkpKSB7XG4gICAgICAgICAgICBnbG9iYWxzW2tleV0gPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGdsb2JhbCwga2V5KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGdsb2JhbHNcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0cywgc3RhdGUpIHtcbiAgICBpZiAoc3RhdGUubG9ja2VkKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICBcIlRoZSB0ZXN0IHN1aXRlIG11c3Qgbm90IGJlIHJ1biBhZnRlciB0aGUgdmlldyBoYXMgYmVlbiBkZXRhY2hlZC5cIlxuICAgICAgICApKVxuICAgIH1cblxuICAgIGlmIChzdGF0ZS5jdXJyZW50UHJvbWlzZSAhPSBudWxsKSByZXR1cm4gc3RhdGUuY3VycmVudFByb21pc2VcblxuICAgIG9wdHMudGhhbGxpdW0uY2xlYXJUZXN0cygpXG5cbiAgICAvLyBEZXRlY3QgYW5kIHJlbW92ZSBnbG9iYWxzIGNyZWF0ZWQgYnkgbG9hZGVkIHNjcmlwdHMuXG4gICAgdmFyIGdsb2JhbHMgPSBmaW5kR2xvYmFscygpXG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgICAgICB2YXIgZm91bmQgPSBPYmplY3Qua2V5cyhnbG9iYWwpXG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmb3VuZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGtleSA9IGZvdW5kW2ldXG5cbiAgICAgICAgICAgIGlmICghaGFzT3duLmNhbGwoZ2xvYmFscywga2V5KSkge1xuICAgICAgICAgICAgICAgIHRyeURlbGV0ZShrZXkpXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGRlc2NyaXB0b3JDaGFuZ2VkKFxuICAgICAgICAgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZ2xvYmFsLCBrZXkpLFxuICAgICAgICAgICAgICAgIGdsb2JhbHNba2V5XVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgIHRyeURlbGV0ZShrZXkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5jdXJyZW50UHJvbWlzZSA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIHJldHVybiBzdGF0ZS5jdXJyZW50UHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICBzdGF0ZS5wYXNzLnRleHRDb250ZW50ID0gXCIwXCJcbiAgICAgICAgc3RhdGUuZmFpbC50ZXh0Q29udGVudCA9IFwiMFwiXG4gICAgICAgIHN0YXRlLnNraXAudGV4dENvbnRlbnQgPSBcIjBcIlxuICAgICAgICByZXR1cm4gb3B0cy5wcmVsb2FkKClcbiAgICB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFV0aWwucGVhY2gob3B0cy5maWxlcywgZnVuY3Rpb24gKGZpbGUpIHtcbiAgICAgICAgICAgIHJldHVybiBsb2FkU2NyaXB0KGZpbGUsIG9wdHMudGltZW91dClcbiAgICAgICAgfSlcbiAgICB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIG9wdHMucHJlcnVuKCkgfSlcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBvcHRzLnRoYWxsaXVtLnJ1bigpIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gb3B0cy5wb3N0cnVuKCkgfSlcbiAgICAuY2F0Y2goZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShvcHRzLmVycm9yKGUpKS50aGVuKGZ1bmN0aW9uICgpIHsgdGhyb3cgZSB9KVxuICAgIH0pXG4gICAgLnRoZW4oXG4gICAgICAgIGZ1bmN0aW9uICgpIHsgY2xlYW51cCgpIH0sXG4gICAgICAgIGZ1bmN0aW9uIChlKSB7IGNsZWFudXAoKTsgdGhyb3cgZSB9KVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIGRpZmYgPSByZXF1aXJlKFwiZGlmZlwiKVxudmFyIFIgPSByZXF1aXJlKFwiLi4vcmVwb3J0ZXJcIilcbnZhciBEID0gcmVxdWlyZShcIi4vaW5qZWN0XCIpXG52YXIgcnVuVGVzdHMgPSByZXF1aXJlKFwiLi9ydW4tdGVzdHNcIilcbnZhciBpbnNwZWN0ID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpLmluc3BlY3RcblxuLyoqXG4gKiBWaWV3IGxvZ2ljXG4gKi9cblxuZnVuY3Rpb24gdCh0ZXh0KSB7XG4gICAgcmV0dXJuIEQuZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dClcbn1cblxuZnVuY3Rpb24gaCh0eXBlLCBhdHRycywgY2hpbGRyZW4pIHtcbiAgICB2YXIgcGFydHMgPSB0eXBlLnNwbGl0KC9cXHMrL2cpXG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShhdHRycykpIHtcbiAgICAgICAgY2hpbGRyZW4gPSBhdHRyc1xuICAgICAgICBhdHRycyA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmIChhdHRycyA9PSBudWxsKSBhdHRycyA9IHt9XG4gICAgaWYgKGNoaWxkcmVuID09IG51bGwpIGNoaWxkcmVuID0gW11cblxuICAgIHR5cGUgPSBwYXJ0c1swXVxuICAgIGF0dHJzLmNsYXNzTmFtZSA9IHBhcnRzLnNsaWNlKDEpLmpvaW4oXCIgXCIpXG5cbiAgICB2YXIgZWxlbSA9IEQuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0eXBlKVxuXG4gICAgT2JqZWN0LmtleXMoYXR0cnMpLmZvckVhY2goZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgICAgZWxlbVthdHRyXSA9IGF0dHJzW2F0dHJdXG4gICAgfSlcblxuICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIGlmIChjaGlsZCAhPSBudWxsKSBlbGVtLmFwcGVuZENoaWxkKGNoaWxkKVxuICAgIH0pXG5cbiAgICByZXR1cm4gZWxlbVxufVxuXG5mdW5jdGlvbiB1bmlmaWVkRGlmZihlcnIpIHtcbiAgICB2YXIgYWN0dWFsID0gaW5zcGVjdChlcnIuYWN0dWFsKVxuICAgIHZhciBleHBlY3RlZCA9IGluc3BlY3QoZXJyLmV4cGVjdGVkKVxuICAgIHZhciBtc2cgPSBkaWZmLmNyZWF0ZVBhdGNoKFwic3RyaW5nXCIsIGFjdHVhbCwgZXhwZWN0ZWQpXG4gICAgICAgIC5zcGxpdCgvXFxyP1xcbnxcXHIvZykuc2xpY2UoNClcbiAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gIS9eXFxAXFxAfF5cXFxcIE5vIG5ld2xpbmUvLnRlc3QobGluZSkgfSlcbiAgICB2YXIgZW5kID0gbXNnLmxlbmd0aFxuXG4gICAgd2hpbGUgKGVuZCAhPT0gMCAmJiAvXlxccyokL2cudGVzdChtc2dbZW5kIC0gMV0pKSBlbmQtLVxuICAgIHJldHVybiBoKFwiZGl2IHRsLWRpZmZcIiwgW1xuICAgICAgICBoKFwiZGl2IHRsLWRpZmYtaGVhZGVyXCIsIFtcbiAgICAgICAgICAgIGgoXCJzcGFuIHRsLWRpZmYtYWRkZWRcIiwgW3QoXCIrIGV4cGVjdGVkXCIpXSksXG4gICAgICAgICAgICBoKFwic3BhbiB0bC1kaWZmLXJlbW92ZWRcIiwgW3QoXCItIGFjdHVhbFwiKV0pLFxuICAgICAgICBdKSxcbiAgICAgICAgaChcImRpdiB0bC1wcmVcIiwgIWVuZFxuICAgICAgICAgICAgPyBbaChcInNwYW4gdGwtbGluZSB0bC1kaWZmLWFkZGVkXCIsIFt0KFwiIChub25lKVwiKV0pXVxuICAgICAgICAgICAgOiBtc2cuc2xpY2UoMCwgZW5kKVxuICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gbGluZS50cmltUmlnaHQoKSB9KVxuICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAobGluZSkge1xuICAgICAgICAgICAgICAgIGlmIChsaW5lWzBdID09PSBcIitcIikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaChcInNwYW4gdGwtbGluZSB0bC1kaWZmLWFkZGVkXCIsIFt0KGxpbmUpXSlcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGxpbmVbMF0gPT09IFwiLVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBoKFwic3BhbiB0bC1saW5lIHRsLWRpZmYtcmVtb3ZlZFwiLCBbdChsaW5lKV0pXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGgoXCJzcGFuIHRsLWxpbmUgdGwtZGlmZi1ub25lXCIsIFt0KGxpbmUpXSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICApLFxuICAgIF0pXG59XG5cbmZ1bmN0aW9uIHRvTGluZXMoc3RyKSB7XG4gICAgcmV0dXJuIGgoXCJkaXYgdGwtcHJlXCIsIHN0ci5zcGxpdCgvXFxyP1xcbnxcXHIvZykubWFwKGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIHJldHVybiBoKFwic3BhbiB0bC1saW5lXCIsIFt0KGxpbmUudHJpbVJpZ2h0KCkpXSlcbiAgICB9KSlcbn1cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IoZSwgc2hvd0RpZmYpIHtcbiAgICB2YXIgc3RhY2sgPSBSLnJlYWRTdGFjayhlKVxuXG4gICAgcmV0dXJuIGgoXCJkaXYgdGwtZGlzcGxheVwiLCBbXG4gICAgICAgIGgoXCJkaXYgdGwtbWVzc2FnZVwiLCBbdG9MaW5lcyhlLm5hbWUgKyBcIjogXCIgKyBlLm1lc3NhZ2UpXSksXG4gICAgICAgIHNob3dEaWZmID8gdW5pZmllZERpZmYoZSkgOiB1bmRlZmluZWQsXG4gICAgICAgIHN0YWNrID8gaChcImRpdiB0bC1zdGFja1wiLCBbdG9MaW5lcyhzdGFjayldKSA6IHVuZGVmaW5lZCxcbiAgICBdKVxufVxuXG5mdW5jdGlvbiBzaG93VGVzdChfLCByZXBvcnQsIGNsYXNzTmFtZSwgY2hpbGQpIHtcbiAgICB2YXIgZW5kID0gcmVwb3J0LnBhdGgubGVuZ3RoIC0gMVxuICAgIHZhciBuYW1lID0gcmVwb3J0LnBhdGhbZW5kXS5uYW1lXG4gICAgdmFyIHBhcmVudCA9IF8uZ2V0KHJlcG9ydC5wYXRoLCBlbmQpXG4gICAgdmFyIHNwZWVkID0gUi5zcGVlZChyZXBvcnQpXG5cbiAgICBpZiAoc3BlZWQgPT09IFwiZmFzdFwiKSB7XG4gICAgICAgIHBhcmVudC5ub2RlLmFwcGVuZENoaWxkKGgoXCJsaSBcIiArIGNsYXNzTmFtZSArIFwiIHRsLWZhc3RcIiwgW1xuICAgICAgICAgICAgaChcImgyXCIsIFt0KG5hbWUpXSksXG4gICAgICAgICAgICBjaGlsZCxcbiAgICAgICAgXSkpXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcGFyZW50Lm5vZGUuYXBwZW5kQ2hpbGQoaChcImxpIFwiICsgY2xhc3NOYW1lICsgXCIgdGwtXCIgKyBzcGVlZCwgW1xuICAgICAgICAgICAgaChcImgyXCIsIFtcbiAgICAgICAgICAgICAgICB0KG5hbWUgKyBcIiAoXCIpLFxuICAgICAgICAgICAgICAgIGgoXCJzcGFuIHRsLWR1cmF0aW9uXCIsIFt0KFIuZm9ybWF0VGltZShyZXBvcnQuZHVyYXRpb24pKV0pLFxuICAgICAgICAgICAgICAgIHQoXCIpXCIpLFxuICAgICAgICAgICAgXSksXG4gICAgICAgICAgICBjaGlsZCxcbiAgICAgICAgXSkpXG4gICAgfVxuXG4gICAgXy5vcHRzLmR1cmF0aW9uLnRleHRDb250ZW50ID0gUi5mb3JtYXRUaW1lKF8uZHVyYXRpb24pXG59XG5cbmZ1bmN0aW9uIHNob3dTa2lwKF8sIHJlcG9ydCkge1xuICAgIHZhciBlbmQgPSByZXBvcnQucGF0aC5sZW5ndGggLSAxXG4gICAgdmFyIG5hbWUgPSByZXBvcnQucGF0aFtlbmRdLm5hbWVcbiAgICB2YXIgcGFyZW50ID0gXy5nZXQocmVwb3J0LnBhdGgsIGVuZClcblxuICAgIHBhcmVudC5ub2RlLmFwcGVuZENoaWxkKGgoXCJsaSB0bC10ZXN0IHRsLXNraXBcIiwgW1xuICAgICAgICBoKFwiaDJcIiwgW3QobmFtZSldKSxcbiAgICBdKSlcbn1cblxuZXhwb3J0cy5uZXh0RnJhbWUgPSBuZXh0RnJhbWVcbmZ1bmN0aW9uIG5leHRGcmFtZShmdW5jKSB7XG4gICAgaWYgKEQud2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSkge1xuICAgICAgICBELndpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuYylcbiAgICB9IGVsc2Uge1xuICAgICAgICBnbG9iYWwuc2V0VGltZW91dChmdW5jLCAwKVxuICAgIH1cbn1cblxuZXhwb3J0cy5yZXBvcnQgPSBmdW5jdGlvbiAoXywgcmVwb3J0KSB7XG4gICAgaWYgKHJlcG9ydC5pc1N0YXJ0KSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIGVsZW1lbnQgZmlyc3QsIGp1c3QgaW4gY2FzZS5cbiAgICAgICAgICAgIHdoaWxlIChfLm9wdHMucmVwb3J0LmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBfLm9wdHMucmVwb3J0LnJlbW92ZUNoaWxkKF8ub3B0cy5yZXBvcnQuZmlyc3RDaGlsZClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRGVmZXIgdGhlIG5leHQgZnJhbWUsIHNvIHRoZSBjdXJyZW50IGNoYW5nZXMgY2FuIGJlIHNlbnQsIGluIGNhc2VcbiAgICAgICAgICAgIC8vIGl0J3MgY2xlYXJpbmcgb2xkIHRlc3QgcmVzdWx0cyBmcm9tIGEgbGFyZ2Ugc3VpdGUuIChDaHJvbWUgZG9lc1xuICAgICAgICAgICAgLy8gYmV0dGVyIGJhdGNoaW5nIHRoaXMgd2F5LCBhdCBsZWFzdC4pXG4gICAgICAgICAgICBuZXh0RnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF8uZ2V0KHVuZGVmaW5lZCwgMCkubm9kZSA9IF8ub3B0cy5yZXBvcnRcbiAgICAgICAgICAgICAgICBfLm9wdHMuZHVyYXRpb24udGV4dENvbnRlbnQgPSBSLmZvcm1hdFRpbWUoMClcbiAgICAgICAgICAgICAgICBfLm9wdHMucGFzcy50ZXh0Q29udGVudCA9IFwiMFwiXG4gICAgICAgICAgICAgICAgXy5vcHRzLmZhaWwudGV4dENvbnRlbnQgPSBcIjBcIlxuICAgICAgICAgICAgICAgIF8ub3B0cy5za2lwLnRleHRDb250ZW50ID0gXCIwXCJcbiAgICAgICAgICAgICAgICByZXNvbHZlKClcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFbnRlcikge1xuICAgICAgICB2YXIgY2hpbGQgPSBoKFwidWxcIilcblxuICAgICAgICBfLmdldChyZXBvcnQucGF0aCkubm9kZSA9IGNoaWxkXG4gICAgICAgIHNob3dUZXN0KF8sIHJlcG9ydCwgXCJ0bC1zdWl0ZSB0bC1wYXNzXCIsIGNoaWxkKVxuICAgICAgICBfLm9wdHMucGFzcy50ZXh0Q29udGVudCA9IF8ucGFzc1xuICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzUGFzcykge1xuICAgICAgICBzaG93VGVzdChfLCByZXBvcnQsIFwidGwtdGVzdCB0bC1wYXNzXCIpXG4gICAgICAgIF8ub3B0cy5wYXNzLnRleHRDb250ZW50ID0gXy5wYXNzXG4gICAgfSBlbHNlIGlmIChyZXBvcnQuaXNGYWlsKSB7XG4gICAgICAgIHNob3dUZXN0KF8sIHJlcG9ydCwgXCJ0bC10ZXN0IHRsLWZhaWxcIiwgZm9ybWF0RXJyb3IocmVwb3J0LmVycm9yLFxuICAgICAgICAgICAgcmVwb3J0LmVycm9yLm5hbWUgPT09IFwiQXNzZXJ0aW9uRXJyb3JcIiAmJlxuICAgICAgICAgICAgICAgIHJlcG9ydC5lcnJvci5zaG93RGlmZiAhPT0gZmFsc2UpKVxuICAgICAgICBfLm9wdHMuZmFpbC50ZXh0Q29udGVudCA9IF8uZmFpbFxuICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzU2tpcCkge1xuICAgICAgICBzaG93U2tpcChfLCByZXBvcnQsIFwidGwtdGVzdCB0bC1za2lwXCIpXG4gICAgICAgIF8ub3B0cy5za2lwLnRleHRDb250ZW50ID0gXy5za2lwXG4gICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFcnJvcikge1xuICAgICAgICBfLm9wdHMucmVwb3J0LmFwcGVuZENoaWxkKGgoXCJsaSB0bC1lcnJvclwiLCBbXG4gICAgICAgICAgICBoKFwiaDJcIiwgW3QoXCJJbnRlcm5hbCBlcnJvclwiKV0pLFxuICAgICAgICAgICAgZm9ybWF0RXJyb3IocmVwb3J0LmVycm9yLCBmYWxzZSksXG4gICAgICAgIF0pKVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWRcbn1cblxuZnVuY3Rpb24gbWFrZUNvdW50ZXIoc3RhdGUsIGNoaWxkLCBsYWJlbCwgbmFtZSkge1xuICAgIHJldHVybiBoKFwiYnV0dG9uIHRsLXRvZ2dsZSBcIiArIG5hbWUsIHtcbiAgICAgICAgb25jbGljazogZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKVxuXG4gICAgICAgICAgICBpZiAoL1xcYnRsLWFjdGl2ZVxcYi8udGVzdCh0aGlzLmNsYXNzTmFtZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSA9IHRoaXMuY2xhc3NOYW1lXG4gICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXGJ0bC1hY3RpdmVcXGIvZywgXCJcIilcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xccysvZywgXCIgXCIpXG4gICAgICAgICAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgICAgICBzdGF0ZS5yZXBvcnQuY2xhc3NOYW1lID0gc3RhdGUucmVwb3J0LmNsYXNzTmFtZVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZShuZXcgUmVnRXhwKFwiXFxcXGJcIiArIG5hbWUgKyBcIlxcXFxiXCIsIFwiZ1wiKSwgXCJcIilcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xccysvZywgXCIgXCIpXG4gICAgICAgICAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmUgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLmFjdGl2ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmFjdGl2ZS5jbGFzc05hbWUgPSBzdGF0ZS5hY3RpdmUuY2xhc3NOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxidGwtYWN0aXZlXFxiL2csIFwiXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxzKy9nLCBcIiBcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmUgPSB0aGlzXG4gICAgICAgICAgICAgICAgdGhpcy5jbGFzc05hbWUgKz0gXCIgdGwtYWN0aXZlXCJcbiAgICAgICAgICAgICAgICBzdGF0ZS5yZXBvcnQuY2xhc3NOYW1lID0gc3RhdGUucmVwb3J0LmNsYXNzTmFtZVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxidGwtKHBhc3N8ZmFpbHxza2lwKVxcYi9nLCBcIlwiKVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxzKy9nLCBcIiBcIilcbiAgICAgICAgICAgICAgICAgICAgLnRyaW0oKSArIFwiIFwiICsgbmFtZVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgIH0sIFt0KGxhYmVsKSwgY2hpbGRdKVxufVxuXG5leHBvcnRzLmluaXQgPSBmdW5jdGlvbiAob3B0cykge1xuICAgIHZhciBzdGF0ZSA9IHtcbiAgICAgICAgY3VycmVudFByb21pc2U6IHVuZGVmaW5lZCxcbiAgICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICAgICAgZHVyYXRpb246IGgoXCJlbVwiLCBbdChSLmZvcm1hdFRpbWUoMCkpXSksXG4gICAgICAgIHBhc3M6IGgoXCJlbVwiLCBbdChcIjBcIildKSxcbiAgICAgICAgZmFpbDogaChcImVtXCIsIFt0KFwiMFwiKV0pLFxuICAgICAgICBza2lwOiBoKFwiZW1cIiwgW3QoXCIwXCIpXSksXG4gICAgICAgIHJlcG9ydDogaChcInVsIHRsLXJlcG9ydFwiKSxcbiAgICAgICAgYWN0aXZlOiB1bmRlZmluZWQsXG4gICAgfVxuXG4gICAgdmFyIGhlYWRlciA9IGgoXCJkaXYgdGwtaGVhZGVyXCIsIFtcbiAgICAgICAgaChcImRpdiB0bC1kdXJhdGlvblwiLCBbdChcIkR1cmF0aW9uOiBcIiksIHN0YXRlLmR1cmF0aW9uXSksXG4gICAgICAgIG1ha2VDb3VudGVyKHN0YXRlLCBzdGF0ZS5wYXNzLCBcIlBhc3NlczogXCIsIFwidGwtcGFzc1wiKSxcbiAgICAgICAgbWFrZUNvdW50ZXIoc3RhdGUsIHN0YXRlLmZhaWwsIFwiRmFpbHVyZXM6IFwiLCBcInRsLWZhaWxcIiksXG4gICAgICAgIG1ha2VDb3VudGVyKHN0YXRlLCBzdGF0ZS5za2lwLCBcIlNraXBwZWQ6IFwiLCBcInRsLXNraXBcIiksXG4gICAgICAgIGgoXCJidXR0b24gdGwtcnVuXCIsIHtcbiAgICAgICAgICAgIG9uY2xpY2s6IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgICAgIGV2LnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgICAgICAgICAgIHJ1blRlc3RzKG9wdHMsIHN0YXRlKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSwgW3QoXCJSdW5cIildKSxcbiAgICBdKVxuXG4gICAgdmFyIHJvb3QgPSBELmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwidGxcIilcblxuICAgIGlmIChyb290ID09IG51bGwpIHtcbiAgICAgICAgRC5kb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHJvb3QgPSBoKFwiZGl2XCIsIHtpZDogXCJ0bFwifSwgW1xuICAgICAgICAgICAgaGVhZGVyLFxuICAgICAgICAgICAgc3RhdGUucmVwb3J0LFxuICAgICAgICBdKSlcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDbGVhciB0aGUgZWxlbWVudCBmaXJzdCwganVzdCBpbiBjYXNlLlxuICAgICAgICB3aGlsZSAocm9vdC5maXJzdENoaWxkKSByb290LnJlbW92ZUNoaWxkKHJvb3QuZmlyc3RDaGlsZClcbiAgICAgICAgcm9vdC5hcHBlbmRDaGlsZChoZWFkZXIpXG4gICAgICAgIHJvb3QuYXBwZW5kQ2hpbGQoc3RhdGUucmVwb3J0KVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHJvb3Q6IHJvb3QsXG4gICAgICAgIHN0YXRlOiBzdGF0ZSxcbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChCYXNlLCBTdXBlcikge1xuICAgIHZhciBzdGFydCA9IDJcblxuICAgIGlmICh0eXBlb2YgU3VwZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBCYXNlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoU3VwZXIucHJvdG90eXBlKVxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQmFzZS5wcm90b3R5cGUsIFwiY29uc3RydWN0b3JcIiwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBCYXNlLFxuICAgICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXJ0ID0gMVxuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgbWV0aG9kcyA9IGFyZ3VtZW50c1tpXVxuXG4gICAgICAgIGlmIChtZXRob2RzICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMobWV0aG9kcylcblxuICAgICAgICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCBrZXlzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleSA9IGtleXNba11cbiAgICAgICAgICAgICAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobWV0aG9kcywga2V5KVxuXG4gICAgICAgICAgICAgICAgZGVzYy5lbnVtZXJhYmxlID0gZmFsc2VcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQmFzZS5wcm90b3R5cGUsIGtleSwgZGVzYylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogVGhpcyBjb250YWlucyB0aGUgYnJvd3NlciBjb25zb2xlIHN0dWZmLlxuICovXG5cbmV4cG9ydHMuU3ltYm9scyA9IE9iamVjdC5mcmVlemUoe1xuICAgIFBhc3M6IFwi4pyTXCIsXG4gICAgRmFpbDogXCLinJZcIixcbiAgICBEb3Q6IFwi4oCkXCIsXG4gICAgRG90RmFpbDogXCIhXCIsXG59KVxuXG5leHBvcnRzLndpbmRvd1dpZHRoID0gNzVcbmV4cG9ydHMubmV3bGluZSA9IFwiXFxuXCJcblxuLy8gQ29sb3Igc3VwcG9ydCBpcyB1bmZvcmNlZCBhbmQgdW5zdXBwb3J0ZWQsIHNpbmNlIHlvdSBjYW4gb25seSBzcGVjaWZ5XG4vLyBsaW5lLWJ5LWxpbmUgY29sb3JzIHZpYSBDU1MsIGFuZCBldmVuIHRoYXQgaXNuJ3QgdmVyeSBwb3J0YWJsZS5cbmV4cG9ydHMuY29sb3JTdXBwb3J0ID0gMFxuXG4vKipcbiAqIFNpbmNlIGJyb3dzZXJzIGRvbid0IGhhdmUgdW5idWZmZXJlZCBvdXRwdXQsIHRoaXMga2luZCBvZiBzaW11bGF0ZXMgaXQuXG4gKi9cblxudmFyIGFjYyA9IFwiXCJcblxuZXhwb3J0cy5kZWZhdWx0T3B0cyA9IHtcbiAgICB3cml0ZTogZnVuY3Rpb24gKHN0cikge1xuICAgICAgICBhY2MgKz0gc3RyXG5cbiAgICAgICAgdmFyIGluZGV4ID0gc3RyLmluZGV4T2YoXCJcXG5cIilcblxuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgdmFyIGxpbmVzID0gc3RyLnNwbGl0KFwiXFxuXCIpXG5cbiAgICAgICAgICAgIGFjYyA9IGxpbmVzLnBvcCgpXG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBnbG9iYWwuY29uc29sZS5sb2cobGluZXNbaV0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKGFjYyAhPT0gXCJcIikge1xuICAgICAgICAgICAgZ2xvYmFsLmNvbnNvbGUubG9nKGFjYylcbiAgICAgICAgICAgIGFjYyA9IFwiXCJcbiAgICAgICAgfVxuICAgIH0sXG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgZGlmZiA9IHJlcXVpcmUoXCJkaWZmXCIpXG5cbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcbnZhciBpbnNwZWN0ID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpLmluc3BlY3RcbnZhciBwZWFjaCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpLnBlYWNoXG52YXIgUmVwb3J0ZXIgPSByZXF1aXJlKFwiLi9yZXBvcnRlclwiKVxudmFyIFV0aWwgPSByZXF1aXJlKFwiLi91dGlsXCIpXG52YXIgU2V0dGluZ3MgPSByZXF1aXJlKFwiLi4vc2V0dGluZ3NcIilcblxuZnVuY3Rpb24gcHJpbnRUaW1lKF8sIHAsIHN0cikge1xuICAgIGlmICghXy50aW1lUHJpbnRlZCkge1xuICAgICAgICBfLnRpbWVQcmludGVkID0gdHJ1ZVxuICAgICAgICBzdHIgKz0gVXRpbC5jb2xvcihcImxpZ2h0XCIsIFwiIChcIiArIFV0aWwuZm9ybWF0VGltZShfLmR1cmF0aW9uKSArIFwiKVwiKVxuICAgIH1cblxuICAgIHJldHVybiBwLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChzdHIpIH0pXG59XG5cbmZ1bmN0aW9uIHVuaWZpZWREaWZmKGVycikge1xuICAgIHZhciBhY3R1YWwgPSBpbnNwZWN0KGVyci5hY3R1YWwpXG4gICAgdmFyIGV4cGVjdGVkID0gaW5zcGVjdChlcnIuZXhwZWN0ZWQpXG4gICAgdmFyIG1zZyA9IGRpZmYuY3JlYXRlUGF0Y2goXCJzdHJpbmdcIiwgYWN0dWFsLCBleHBlY3RlZClcbiAgICB2YXIgaGVhZGVyID0gU2V0dGluZ3MubmV3bGluZSgpICtcbiAgICAgICAgVXRpbC5jb2xvcihcImRpZmYgYWRkZWRcIiwgXCIrIGV4cGVjdGVkXCIpICsgXCIgXCIgK1xuICAgICAgICBVdGlsLmNvbG9yKFwiZGlmZiByZW1vdmVkXCIsIFwiLSBhY3R1YWxcIikgK1xuICAgICAgICBTZXR0aW5ncy5uZXdsaW5lKCkgKyBTZXR0aW5ncy5uZXdsaW5lKClcblxuICAgIHJldHVybiBoZWFkZXIgKyBtc2cuc3BsaXQoL1xccj9cXG58XFxyL2cpLnNsaWNlKDQpXG4gICAgLmZpbHRlcihmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gIS9eXFxAXFxAfF5cXFxcIE5vIG5ld2xpbmUvLnRlc3QobGluZSkgfSlcbiAgICAubWFwKGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIGlmIChsaW5lWzBdID09PSBcIitcIikgcmV0dXJuIFV0aWwuY29sb3IoXCJkaWZmIGFkZGVkXCIsIGxpbmUudHJpbVJpZ2h0KCkpXG4gICAgICAgIGlmIChsaW5lWzBdID09PSBcIi1cIikgcmV0dXJuIFV0aWwuY29sb3IoXCJkaWZmIHJlbW92ZWRcIiwgbGluZS50cmltUmlnaHQoKSlcbiAgICAgICAgcmV0dXJuIGxpbmUudHJpbVJpZ2h0KClcbiAgICB9KVxuICAgIC5qb2luKFNldHRpbmdzLm5ld2xpbmUoKSlcbn1cblxuZnVuY3Rpb24gZm9ybWF0RmFpbChzdHIpIHtcbiAgICByZXR1cm4gc3RyLnRyaW1SaWdodCgpXG4gICAgLnNwbGl0KC9cXHI/XFxufFxcci9nKVxuICAgIC5tYXAoZnVuY3Rpb24gKGxpbmUpIHsgcmV0dXJuIFV0aWwuY29sb3IoXCJmYWlsXCIsIGxpbmUudHJpbVJpZ2h0KCkpIH0pXG4gICAgLmpvaW4oU2V0dGluZ3MubmV3bGluZSgpKVxufVxuXG5mdW5jdGlvbiBnZXREaWZmU3RhY2soZSkge1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IGZvcm1hdEZhaWwoZS5uYW1lICsgXCI6IFwiICsgZS5tZXNzYWdlKVxuXG4gICAgaWYgKGUubmFtZSA9PT0gXCJBc3NlcnRpb25FcnJvclwiICYmIGUuc2hvd0RpZmYgIT09IGZhbHNlKSB7XG4gICAgICAgIGRlc2NyaXB0aW9uICs9IFNldHRpbmdzLm5ld2xpbmUoKSArIHVuaWZpZWREaWZmKGUpXG4gICAgfVxuXG4gICAgdmFyIHN0cmlwcGVkID0gZm9ybWF0RmFpbChVdGlsLnJlYWRTdGFjayhlKSlcblxuICAgIGlmIChzdHJpcHBlZCA9PT0gXCJcIikgcmV0dXJuIGRlc2NyaXB0aW9uXG4gICAgcmV0dXJuIGRlc2NyaXB0aW9uICsgU2V0dGluZ3MubmV3bGluZSgpICsgc3RyaXBwZWRcbn1cblxuZnVuY3Rpb24gaW5zcGVjdFRyaW1tZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuIGluc3BlY3Qob2JqZWN0KS50cmltUmlnaHQoKVxuICAgIC5zcGxpdCgvXFxyP1xcbnxcXHIvZylcbiAgICAubWFwKGZ1bmN0aW9uIChsaW5lKSB7IHJldHVybiBsaW5lLnRyaW1SaWdodCgpIH0pXG4gICAgLmpvaW4oU2V0dGluZ3MubmV3bGluZSgpKVxufVxuXG5mdW5jdGlvbiBwcmludEZhaWxMaXN0KF8sIGVycikge1xuICAgIHZhciBzdHIgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGdldERpZmZTdGFjayhlcnIpIDogaW5zcGVjdFRyaW1tZWQoZXJyKVxuICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdCgvXFxyP1xcbi9nKVxuXG4gICAgcmV0dXJuIF8ucHJpbnQoXCIgICAgXCIgKyBwYXJ0c1swXSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBwZWFjaChwYXJ0cy5zbGljZSgxKSwgZnVuY3Rpb24gKHBhcnQpIHtcbiAgICAgICAgICAgIHJldHVybiBfLnByaW50KHBhcnQgPyBcIiAgICAgIFwiICsgcGFydCA6IFwiXCIpXG4gICAgICAgIH0pXG4gICAgfSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0cywgbWV0aG9kcykge1xuICAgIHJldHVybiBuZXcgQ29uc29sZVJlcG9ydGVyKG9wdHMsIG1ldGhvZHMpXG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgbW9zdCBjb25zb2xlIHJlcG9ydGVycy5cbiAqXG4gKiBOb3RlOiBwcmludGluZyBpcyBhc3luY2hyb25vdXMsIGJlY2F1c2Ugb3RoZXJ3aXNlLCBpZiBlbm91Z2ggZXJyb3JzIGV4aXN0LFxuICogTm9kZSB3aWxsIGV2ZW50dWFsbHkgc3RhcnQgZHJvcHBpbmcgbGluZXMgc2VudCB0byBpdHMgYnVmZmVyLCBlc3BlY2lhbGx5IHdoZW5cbiAqIHN0YWNrIHRyYWNlcyBnZXQgaW52b2x2ZWQuIElmIFRoYWxsaXVtJ3Mgb3V0cHV0IGlzIHJlZGlyZWN0ZWQsIHRoYXQgY2FuIGJlIGFcbiAqIGJpZyBwcm9ibGVtIGZvciBjb25zdW1lcnMsIGFzIHRoZXkgb25seSBoYXZlIHBhcnQgb2YgdGhlIG91dHB1dCwgYW5kIHdvbid0IGJlXG4gKiBhYmxlIHRvIHNlZSBhbGwgdGhlIGVycm9ycyBsYXRlci4gQWxzbywgaWYgY29uc29sZSB3YXJuaW5ncyBjb21lIHVwIGVuLW1hc3NlLFxuICogdGhhdCB3b3VsZCBhbHNvIGNvbnRyaWJ1dGUuIFNvLCB3ZSBoYXZlIHRvIHdhaXQgZm9yIGVhY2ggbGluZSB0byBmbHVzaCBiZWZvcmVcbiAqIHdlIGNhbiBjb250aW51ZSwgc28gdGhlIGZ1bGwgb3V0cHV0IG1ha2VzIGl0cyB3YXkgdG8gdGhlIGNvbnNvbGUuXG4gKlxuICogU29tZSB0ZXN0IGZyYW1ld29ya3MgbGlrZSBUYXBlIG1pc3MgdGhpcywgdGhvdWdoLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIFRoZSBvcHRpb25zIGZvciB0aGUgcmVwb3J0ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBvcHRzLndyaXRlIFRoZSB1bmJ1ZmZlcnJlZCB3cml0ZXIgZm9yIHRoZSByZXBvcnRlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IG9wdHMucmVzZXQgQSByZXNldCBmdW5jdGlvbiBmb3IgdGhlIHByaW50ZXIgKyB3cml0ZXIuXG4gKiBAcGFyYW0ge1N0cmluZ1tdfSBhY2NlcHRzIFRoZSBvcHRpb25zIGFjY2VwdGVkLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaW5pdCBUaGUgaW5pdCBmdW5jdGlvbiBmb3IgdGhlIHN1YmNsYXNzIHJlcG9ydGVyJ3NcbiAqICAgICAgICAgICAgICAgICAgICAgICAgaXNvbGF0ZWQgc3RhdGUgKGNyZWF0ZWQgYnkgZmFjdG9yeSkuXG4gKi9cbmZ1bmN0aW9uIENvbnNvbGVSZXBvcnRlcihvcHRzLCBtZXRob2RzKSB7XG4gICAgUmVwb3J0ZXIuY2FsbCh0aGlzLCBVdGlsLlRyZWUsIG9wdHMsIG1ldGhvZHMsIHRydWUpXG5cbiAgICBpZiAoIVV0aWwuQ29sb3JzLmZvcmNlZCgpICYmIG1ldGhvZHMuYWNjZXB0cy5pbmRleE9mKFwiY29sb3JcIikgPj0gMCkge1xuICAgICAgICB0aGlzLm9wdHMuY29sb3IgPSBvcHRzLmNvbG9yXG4gICAgfVxuXG4gICAgVXRpbC5kZWZhdWx0aWZ5KHRoaXMsIG9wdHMsIFwid3JpdGVcIilcbiAgICB0aGlzLnJlc2V0KClcbn1cblxubWV0aG9kcyhDb25zb2xlUmVwb3J0ZXIsIFJlcG9ydGVyLCB7XG4gICAgcHJpbnQ6IGZ1bmN0aW9uIChzdHIpIHtcbiAgICAgICAgaWYgKHN0ciA9PSBudWxsKSBzdHIgPSBcIlwiXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5vcHRzLndyaXRlKHN0ciArIFwiXFxuXCIpKVxuICAgIH0sXG5cbiAgICB3cml0ZTogZnVuY3Rpb24gKHN0cikge1xuICAgICAgICBpZiAoc3RyICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5vcHRzLndyaXRlKHN0cikpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBwcmludFJlc3VsdHM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgICAgICAgaWYgKCF0aGlzLnRlc3RzICYmICF0aGlzLnNraXApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByaW50KFxuICAgICAgICAgICAgICAgIFV0aWwuY29sb3IoXCJwbGFpblwiLCBcIiAgMCB0ZXN0c1wiKSArXG4gICAgICAgICAgICAgICAgVXRpbC5jb2xvcihcImxpZ2h0XCIsIFwiICgwbXMpXCIpKVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5wcmludCgpIH0pXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5wcmludCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHAgPSBQcm9taXNlLnJlc29sdmUoKVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5wYXNzKSB7XG4gICAgICAgICAgICAgICAgcCA9IHByaW50VGltZShzZWxmLCBwLFxuICAgICAgICAgICAgICAgICAgICBVdGlsLmNvbG9yKFwiYnJpZ2h0IHBhc3NcIiwgXCIgIFwiKSArXG4gICAgICAgICAgICAgICAgICAgIFV0aWwuY29sb3IoXCJncmVlblwiLCBzZWxmLnBhc3MgKyBcIiBwYXNzaW5nXCIpKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5za2lwKSB7XG4gICAgICAgICAgICAgICAgcCA9IHByaW50VGltZShzZWxmLCBwLFxuICAgICAgICAgICAgICAgICAgICBVdGlsLmNvbG9yKFwic2tpcFwiLCBcIiAgXCIgKyBzZWxmLnNraXAgKyBcIiBza2lwcGVkXCIpKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5mYWlsKSB7XG4gICAgICAgICAgICAgICAgcCA9IHByaW50VGltZShzZWxmLCBwLFxuICAgICAgICAgICAgICAgICAgICBVdGlsLmNvbG9yKFwiYnJpZ2h0IGZhaWxcIiwgXCIgIFwiKSArXG4gICAgICAgICAgICAgICAgICAgIFV0aWwuY29sb3IoXCJmYWlsXCIsIHNlbGYuZmFpbCArIFwiIGZhaWxpbmdcIikpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBwXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGYucHJpbnQoKSB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcGVhY2goc2VsZi5lcnJvcnMsIGZ1bmN0aW9uIChyZXBvcnQsIGkpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IGkgKyAxICsgXCIpIFwiICsgVXRpbC5qb2luUGF0aChyZXBvcnQpICtcbiAgICAgICAgICAgICAgICAgICAgVXRpbC5mb3JtYXRSZXN0KHJlcG9ydClcblxuICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLnByaW50KFwiICBcIiArIFV0aWwuY29sb3IoXCJwbGFpblwiLCBuYW1lICsgXCI6XCIpKVxuICAgICAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByaW50RmFpbExpc3Qoc2VsZiwgcmVwb3J0LmVycm9yKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5wcmludCgpIH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgIH0sXG5cbiAgICBwcmludEVycm9yOiBmdW5jdGlvbiAocmVwb3J0KSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpc1xuICAgICAgICB2YXIgbGluZXMgPSByZXBvcnQuZXJyb3IgaW5zdGFuY2VvZiBFcnJvclxuICAgICAgICAgICAgPyBVdGlsLmdldFN0YWNrKHJlcG9ydC5lcnJvcilcbiAgICAgICAgICAgIDogaW5zcGVjdFRyaW1tZWQocmVwb3J0LmVycm9yKVxuXG4gICAgICAgIHJldHVybiB0aGlzLnByaW50KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcGVhY2gobGluZXMuc3BsaXQoL1xccj9cXG4vZyksIGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYucHJpbnQobGluZSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuL3V0aWxcIilcblxuZXhwb3J0cy5vbiA9IHJlcXVpcmUoXCIuL29uXCIpXG5leHBvcnRzLmNvbnNvbGVSZXBvcnRlciA9IHJlcXVpcmUoXCIuL2NvbnNvbGUtcmVwb3J0ZXJcIilcbmV4cG9ydHMuUmVwb3J0ZXIgPSByZXF1aXJlKFwiLi9yZXBvcnRlclwiKVxuZXhwb3J0cy5jb2xvciA9IFV0aWwuY29sb3JcbmV4cG9ydHMuQ29sb3JzID0gVXRpbC5Db2xvcnNcbmV4cG9ydHMuZm9ybWF0UmVzdCA9IFV0aWwuZm9ybWF0UmVzdFxuZXhwb3J0cy5mb3JtYXRUaW1lID0gVXRpbC5mb3JtYXRUaW1lXG5leHBvcnRzLmdldFN0YWNrID0gVXRpbC5nZXRTdGFja1xuZXhwb3J0cy5qb2luUGF0aCA9IFV0aWwuam9pblBhdGhcbmV4cG9ydHMubmV3bGluZSA9IFV0aWwubmV3bGluZVxuZXhwb3J0cy5yZWFkU3RhY2sgPSBVdGlsLnJlYWRTdGFja1xuZXhwb3J0cy5zZXRDb2xvciA9IFV0aWwuc2V0Q29sb3JcbmV4cG9ydHMuc3BlZWQgPSBVdGlsLnNwZWVkXG5leHBvcnRzLlN0YXR1cyA9IFV0aWwuU3RhdHVzXG5leHBvcnRzLnN5bWJvbHMgPSBVdGlsLnN5bWJvbHNcbmV4cG9ydHMudW5zZXRDb2xvciA9IFV0aWwudW5zZXRDb2xvclxuZXhwb3J0cy53aW5kb3dXaWR0aCA9IFV0aWwud2luZG93V2lkdGhcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBTdGF0dXMgPSByZXF1aXJlKFwiLi91dGlsXCIpLlN0YXR1c1xuXG4vLyBCZWNhdXNlIEVTNSBzdWNrcy4gKEFuZCwgaXQncyBicmVha2luZyBteSBQaGFudG9tSlMgYnVpbGRzKVxuZnVuY3Rpb24gc2V0TmFtZShyZXBvcnRlciwgbmFtZSkge1xuICAgIHRyeSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXBvcnRlciwgXCJuYW1lXCIsIHt2YWx1ZTogbmFtZX0pXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBpZ25vcmVcbiAgICB9XG59XG5cbi8qKlxuICogQSBtYWNybyBvZiBzb3J0cywgdG8gc2ltcGxpZnkgY3JlYXRpbmcgcmVwb3J0ZXJzLiBJdCBhY2NlcHRzIGFuIG9iamVjdCB3aXRoXG4gKiB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6XG4gKlxuICogYGFjY2VwdHM6IHN0cmluZ1tdYCAtIFRoZSBwcm9wZXJ0aWVzIGFjY2VwdGVkLiBFdmVyeXRoaW5nIGVsc2UgaXMgaWdub3JlZCxcbiAqIGFuZCBpdCdzIHBhcnRpYWxseSB0aGVyZSBmb3IgZG9jdW1lbnRhdGlvbi4gVGhpcyBwYXJhbWV0ZXIgaXMgcmVxdWlyZWQuXG4gKlxuICogYGNyZWF0ZShvcHRzLCBtZXRob2RzKWAgLSBDcmVhdGUgYSBuZXcgcmVwb3J0ZXIgaW5zdGFuY2UuICBUaGlzIHBhcmFtZXRlciBpc1xuICogcmVxdWlyZWQuIE5vdGUgdGhhdCBgbWV0aG9kc2AgcmVmZXJzIHRvIHRoZSBwYXJhbWV0ZXIgb2JqZWN0IGl0c2VsZi5cbiAqXG4gKiBgaW5pdChzdGF0ZSwgb3B0cylgIC0gSW5pdGlhbGl6ZSBleHRyYSByZXBvcnRlciBzdGF0ZSwgaWYgYXBwbGljYWJsZS5cbiAqXG4gKiBgYmVmb3JlKHJlcG9ydGVyKWAgLSBEbyB0aGluZ3MgYmVmb3JlIGVhY2ggZXZlbnQsIHJldHVybmluZyBhIHBvc3NpYmxlXG4gKiB0aGVuYWJsZSB3aGVuIGRvbmUuIFRoaXMgZGVmYXVsdHMgdG8gYSBuby1vcC5cbiAqXG4gKiBgYWZ0ZXIocmVwb3J0ZXIpYCAtIERvIHRoaW5ncyBhZnRlciBlYWNoIGV2ZW50LCByZXR1cm5pbmcgYSBwb3NzaWJsZVxuICogdGhlbmFibGUgd2hlbiBkb25lLiBUaGlzIGRlZmF1bHRzIHRvIGEgbm8tb3AuXG4gKlxuICogYHJlcG9ydChyZXBvcnRlciwgcmVwb3J0KWAgLSBIYW5kbGUgYSB0ZXN0IHJlcG9ydC4gVGhpcyBtYXkgcmV0dXJuIGEgcG9zc2libGVcbiAqIHRoZW5hYmxlIHdoZW4gZG9uZSwgYW5kIGl0IGlzIHJlcXVpcmVkLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChuYW1lLCBtZXRob2RzKSB7XG4gICAgc2V0TmFtZShyZXBvcnRlciwgbmFtZSlcbiAgICByZXBvcnRlcltuYW1lXSA9IHJlcG9ydGVyXG4gICAgcmV0dXJuIHJlcG9ydGVyXG4gICAgZnVuY3Rpb24gcmVwb3J0ZXIob3B0cykge1xuICAgICAgICAvKipcbiAgICAgICAgICogSW5zdGVhZCBvZiBzaWxlbnRseSBmYWlsaW5nIHRvIHdvcmssIGxldCdzIGVycm9yIG91dCB3aGVuIGEgcmVwb3J0IGlzXG4gICAgICAgICAqIHBhc3NlZCBpbiwgYW5kIGluZm9ybSB0aGUgdXNlciBpdCBuZWVkcyBpbml0aWFsaXplZC4gQ2hhbmNlcyBhcmUsXG4gICAgICAgICAqIHRoZXJlJ3Mgbm8gbGVnaXRpbWF0ZSByZWFzb24gdG8gZXZlbiBwYXNzIGEgcmVwb3J0LCBhbnl3YXlzLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKHR5cGVvZiBvcHRzID09PSBcIm9iamVjdFwiICYmIG9wdHMgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2Ygb3B0cy5fID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgICAgIFwiT3B0aW9ucyBjYW5ub3QgYmUgYSByZXBvcnQuIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgdGhlIFwiICtcbiAgICAgICAgICAgICAgICBcImZhY3RvcnkgZmlyc3Q/XCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgXyA9IG1ldGhvZHMuY3JlYXRlKG9wdHMsIG1ldGhvZHMpXG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChyZXBvcnQpIHtcbiAgICAgICAgICAgIC8vIE9ubHkgc29tZSBldmVudHMgaGF2ZSBjb21tb24gc3RlcHMuXG4gICAgICAgICAgICBpZiAocmVwb3J0LmlzU3RhcnQpIHtcbiAgICAgICAgICAgICAgICBfLnJ1bm5pbmcgPSB0cnVlXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0VudGVyIHx8IHJlcG9ydC5pc1Bhc3MpIHtcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucGF0aCkuc3RhdHVzID0gU3RhdHVzLlBhc3NpbmdcbiAgICAgICAgICAgICAgICBfLmR1cmF0aW9uICs9IHJlcG9ydC5kdXJhdGlvblxuICAgICAgICAgICAgICAgIF8udGVzdHMrK1xuICAgICAgICAgICAgICAgIF8ucGFzcysrXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0ZhaWwpIHtcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucGF0aCkuc3RhdHVzID0gU3RhdHVzLkZhaWxpbmdcbiAgICAgICAgICAgICAgICBfLmR1cmF0aW9uICs9IHJlcG9ydC5kdXJhdGlvblxuICAgICAgICAgICAgICAgIF8udGVzdHMrK1xuICAgICAgICAgICAgICAgIF8uZmFpbCsrXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0hvb2spIHtcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucGF0aCkuc3RhdHVzID0gU3RhdHVzLkZhaWxpbmdcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucm9vdFBhdGgpLnN0YXR1cyA9IFN0YXR1cy5GYWlsaW5nXG4gICAgICAgICAgICAgICAgXy5mYWlsKytcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzU2tpcCkge1xuICAgICAgICAgICAgICAgIF8uZ2V0KHJlcG9ydC5wYXRoKS5zdGF0dXMgPSBTdGF0dXMuU2tpcHBlZFxuICAgICAgICAgICAgICAgIC8vIFNraXBwZWQgdGVzdHMgYXJlbid0IGNvdW50ZWQgaW4gdGhlIHRvdGFsIHRlc3QgY291bnRcbiAgICAgICAgICAgICAgICBfLnNraXArK1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICAgICAgICAgIHR5cGVvZiBtZXRob2RzLmJlZm9yZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICAgICAgICAgID8gbWV0aG9kcy5iZWZvcmUoXylcbiAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBtZXRob2RzLnJlcG9ydChfLCByZXBvcnQpIH0pXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBtZXRob2RzLmFmdGVyID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgPyBtZXRob2RzLmFmdGVyKF8pXG4gICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChyZXBvcnQuaXNFbmQgfHwgcmVwb3J0LmlzRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgXy5yZXNldCgpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgXy5vcHRzLnJlc2V0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfLm9wdHMucmVzZXQoKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgbWV0aG9kcyA9IHJlcXVpcmUoXCIuLi9tZXRob2RzXCIpXG52YXIgZGVmYXVsdGlmeSA9IHJlcXVpcmUoXCIuL3V0aWxcIikuZGVmYXVsdGlmeVxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuZnVuY3Rpb24gU3RhdGUocmVwb3J0ZXIpIHtcbiAgICBpZiAodHlwZW9mIHJlcG9ydGVyLm1ldGhvZHMuaW5pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICgwLCByZXBvcnRlci5tZXRob2RzLmluaXQpKHRoaXMsIHJlcG9ydGVyLm9wdHMpXG4gICAgfVxufVxuXG4vKipcbiAqIFRoaXMgaGVscHMgc3BlZWQgdXAgZ2V0dGluZyBwcmV2aW91cyB0cmVlcywgc28gYSBwb3RlbnRpYWxseSBleHBlbnNpdmVcbiAqIHRyZWUgc2VhcmNoIGRvZXNuJ3QgaGF2ZSB0byBiZSBwZXJmb3JtZWQuXG4gKlxuICogKFRoaXMgZG9lcyBhY3R1YWxseSBtYWtlIGEgc2xpZ2h0IHBlcmYgZGlmZmVyZW5jZSBpbiB0aGUgdGVzdHMuKVxuICovXG5mdW5jdGlvbiBpc1JlcGVhdChjYWNoZSwgcGF0aCkge1xuICAgIC8vIENhbid0IGJlIGEgcmVwZWF0IHRoZSBmaXJzdCB0aW1lLlxuICAgIGlmIChjYWNoZS5wYXRoID09IG51bGwpIHJldHVybiBmYWxzZVxuICAgIGlmIChwYXRoLmxlbmd0aCAhPT0gY2FjaGUucGF0aC5sZW5ndGgpIHJldHVybiBmYWxzZVxuICAgIGlmIChwYXRoID09PSBjYWNoZS5wYXRoKSByZXR1cm4gdHJ1ZVxuXG4gICAgLy8gSXQncyB1bmxpa2VseSB0aGUgbmVzdGluZyB3aWxsIGJlIGNvbnNpc3RlbnRseSBtb3JlIHRoYW4gYSBmZXcgbGV2ZWxzXG4gICAgLy8gZGVlcCAoPj0gNSksIHNvIHRoaXMgc2hvdWxkbid0IGJvZyBhbnl0aGluZyBkb3duLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0aC5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAocGF0aFtpXSAhPT0gY2FjaGUucGF0aFtpXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjYWNoZS5wYXRoID0gcGF0aFxuICAgIHJldHVybiB0cnVlXG59XG5cbi8qKlxuICogU3VwZXJjbGFzcyBmb3IgYWxsIHJlcG9ydGVycy4gVGhpcyBjb3ZlcnMgdGhlIHN0YXRlIGZvciBwcmV0dHkgbXVjaCBldmVyeVxuICogcmVwb3J0ZXIuXG4gKlxuICogTm90ZSB0aGF0IGlmIHlvdSBkZWxheSB0aGUgaW5pdGlhbCByZXNldCwgeW91IHN0aWxsIG11c3QgY2FsbCBpdCBiZWZvcmUgdGhlXG4gKiBjb25zdHJ1Y3RvciBmaW5pc2hlcy5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBSZXBvcnRlclxuZnVuY3Rpb24gUmVwb3J0ZXIoVHJlZSwgb3B0cywgbWV0aG9kcywgZGVsYXkpIHtcbiAgICB0aGlzLlRyZWUgPSBUcmVlXG4gICAgdGhpcy5vcHRzID0ge31cbiAgICB0aGlzLm1ldGhvZHMgPSBtZXRob2RzXG4gICAgZGVmYXVsdGlmeSh0aGlzLCBvcHRzLCBcInJlc2V0XCIpXG4gICAgaWYgKCFkZWxheSkgdGhpcy5yZXNldCgpXG59XG5cbm1ldGhvZHMoUmVwb3J0ZXIsIHtcbiAgICByZXNldDogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZVxuICAgICAgICB0aGlzLnRpbWVQcmludGVkID0gZmFsc2VcbiAgICAgICAgdGhpcy50ZXN0cyA9IDBcbiAgICAgICAgdGhpcy5wYXNzID0gMFxuICAgICAgICB0aGlzLmZhaWwgPSAwXG4gICAgICAgIHRoaXMuc2tpcCA9IDBcbiAgICAgICAgdGhpcy5kdXJhdGlvbiA9IDBcbiAgICAgICAgdGhpcy5lcnJvcnMgPSBbXVxuICAgICAgICB0aGlzLnN0YXRlID0gbmV3IFN0YXRlKHRoaXMpXG4gICAgICAgIHRoaXMuYmFzZSA9IG5ldyB0aGlzLlRyZWUodW5kZWZpbmVkKVxuICAgICAgICB0aGlzLmNhY2hlID0ge3BhdGg6IHVuZGVmaW5lZCwgcmVzdWx0OiB1bmRlZmluZWQsIGVuZDogMH1cbiAgICB9LFxuXG4gICAgcHVzaEVycm9yOiBmdW5jdGlvbiAocmVwb3J0KSB7XG4gICAgICAgIHRoaXMuZXJyb3JzLnB1c2gocmVwb3J0KVxuICAgIH0sXG5cbiAgICBnZXQ6IGZ1bmN0aW9uIChwYXRoLCBlbmQpIHtcbiAgICAgICAgaWYgKGVuZCA9PSBudWxsKSBlbmQgPSBwYXRoLmxlbmd0aFxuICAgICAgICBpZiAoZW5kID09PSAwKSByZXR1cm4gdGhpcy5iYXNlXG4gICAgICAgIGlmIChpc1JlcGVhdCh0aGlzLmNhY2hlLCBwYXRoLCBlbmQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYWNoZS5yZXN1bHRcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjaGlsZCA9IHRoaXMuYmFzZVxuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW5kOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBlbnRyeSA9IHBhdGhbaV1cblxuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKGNoaWxkLmNoaWxkcmVuLCBlbnRyeS5pbmRleCkpIHtcbiAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmNoaWxkcmVuW2VudHJ5LmluZGV4XVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmNoaWxkcmVuW2VudHJ5LmluZGV4XSA9IG5ldyB0aGlzLlRyZWUoZW50cnkubmFtZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FjaGUuZW5kID0gZW5kXG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlLnJlc3VsdCA9IGNoaWxkXG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpXG52YXIgU2V0dGluZ3MgPSByZXF1aXJlKFwiLi4vc2V0dGluZ3NcIilcblxuZXhwb3J0cy5zeW1ib2xzID0gU2V0dGluZ3Muc3ltYm9sc1xuZXhwb3J0cy53aW5kb3dXaWR0aCA9IFNldHRpbmdzLndpbmRvd1dpZHRoXG5leHBvcnRzLm5ld2xpbmUgPSBTZXR0aW5ncy5uZXdsaW5lXG5cbi8qXG4gKiBTdGFjayBub3JtYWxpemF0aW9uXG4gKi9cblxuLy8gRXhwb3J0ZWQgZm9yIGRlYnVnZ2luZ1xuZXhwb3J0cy5yZWFkU3RhY2sgPSByZWFkU3RhY2tcbmZ1bmN0aW9uIHJlYWRTdGFjayhlKSB7XG4gICAgdmFyIHN0YWNrID0gVXRpbC5nZXRTdGFjayhlKVxuXG4gICAgLy8gSWYgaXQgZG9lc24ndCBzdGFydCB3aXRoIHRoZSBtZXNzYWdlLCBqdXN0IHJldHVybiB0aGUgc3RhY2suXG4gICAgLy8gIEZpcmVmb3gsIFNhZmFyaSAgICAgICAgICAgICAgICBDaHJvbWUsIElFXG4gICAgaWYgKC9eKEApP1xcUytcXDpcXGQrLy50ZXN0KHN0YWNrKSB8fCAvXlxccyphdC8udGVzdChzdGFjaykpIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdExpbmVCcmVha3Moc3RhY2spXG4gICAgfVxuXG4gICAgdmFyIGluZGV4ID0gc3RhY2suaW5kZXhPZihlLm1lc3NhZ2UpXG5cbiAgICBpZiAoaW5kZXggPCAwKSByZXR1cm4gZm9ybWF0TGluZUJyZWFrcyhVdGlsLmdldFN0YWNrKGUpKVxuICAgIHZhciByZSA9IC9cXHI/XFxuL2dcblxuICAgIHJlLmxhc3RJbmRleCA9IGluZGV4ICsgZS5tZXNzYWdlLmxlbmd0aFxuICAgIGlmICghcmUudGVzdChzdGFjaykpIHJldHVybiBcIlwiXG4gICAgcmV0dXJuIGZvcm1hdExpbmVCcmVha3Moc3RhY2suc2xpY2UocmUubGFzdEluZGV4KSlcbn1cblxuZnVuY3Rpb24gZm9ybWF0TGluZUJyZWFrcyhzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFteXFxyXFxuXFxTXSskL2csIFwiXCIpXG4gICAgICAgIC5yZXBsYWNlKC9cXHMqKFxccj9cXG58XFxyKVxccyovZywgU2V0dGluZ3MubmV3bGluZSgpKVxufVxuXG5leHBvcnRzLmdldFN0YWNrID0gZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAoIShlIGluc3RhbmNlb2YgRXJyb3IpKSByZXR1cm4gZm9ybWF0TGluZUJyZWFrcyhVdGlsLmdldFN0YWNrKGUpKVxuICAgIHZhciBkZXNjcmlwdGlvbiA9IChlLm5hbWUgKyBcIjogXCIgKyBlLm1lc3NhZ2UpXG4gICAgICAgIC5yZXBsYWNlKC9cXHMrJC9nbSwgXCJcIilcbiAgICAgICAgLnJlcGxhY2UoL1xccj9cXG58XFxyL2csIFNldHRpbmdzLm5ld2xpbmUoKSlcbiAgICB2YXIgc3RyaXBwZWQgPSByZWFkU3RhY2soZSlcblxuICAgIGlmIChzdHJpcHBlZCA9PT0gXCJcIikgcmV0dXJuIGRlc2NyaXB0aW9uXG4gICAgcmV0dXJuIGRlc2NyaXB0aW9uICsgU2V0dGluZ3MubmV3bGluZSgpICsgc3RyaXBwZWRcbn1cblxudmFyIENvbG9ycyA9IGV4cG9ydHMuQ29sb3JzID0gU2V0dGluZ3MuQ29sb3JzXG5cbi8vIENvbG9yIHBhbGV0dGUgcHVsbGVkIGZyb20gTW9jaGFcbmZ1bmN0aW9uIGNvbG9yVG9OdW1iZXIobmFtZSkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuICAgIGNhc2UgXCJwYXNzXCI6IHJldHVybiA5MFxuICAgIGNhc2UgXCJmYWlsXCI6IHJldHVybiAzMVxuXG4gICAgY2FzZSBcImJyaWdodCBwYXNzXCI6IHJldHVybiA5MlxuICAgIGNhc2UgXCJicmlnaHQgZmFpbFwiOiByZXR1cm4gOTFcbiAgICBjYXNlIFwiYnJpZ2h0IHllbGxvd1wiOiByZXR1cm4gOTNcblxuICAgIGNhc2UgXCJza2lwXCI6IHJldHVybiAzNlxuICAgIGNhc2UgXCJzdWl0ZVwiOiByZXR1cm4gMFxuICAgIGNhc2UgXCJwbGFpblwiOiByZXR1cm4gMFxuXG4gICAgY2FzZSBcImVycm9yIHRpdGxlXCI6IHJldHVybiAwXG4gICAgY2FzZSBcImVycm9yIG1lc3NhZ2VcIjogcmV0dXJuIDMxXG4gICAgY2FzZSBcImVycm9yIHN0YWNrXCI6IHJldHVybiA5MFxuXG4gICAgY2FzZSBcImNoZWNrbWFya1wiOiByZXR1cm4gMzJcbiAgICBjYXNlIFwiZmFzdFwiOiByZXR1cm4gOTBcbiAgICBjYXNlIFwibWVkaXVtXCI6IHJldHVybiAzM1xuICAgIGNhc2UgXCJzbG93XCI6IHJldHVybiAzMVxuICAgIGNhc2UgXCJncmVlblwiOiByZXR1cm4gMzJcbiAgICBjYXNlIFwibGlnaHRcIjogcmV0dXJuIDkwXG5cbiAgICBjYXNlIFwiZGlmZiBndXR0ZXJcIjogcmV0dXJuIDkwXG4gICAgY2FzZSBcImRpZmYgYWRkZWRcIjogcmV0dXJuIDMyXG4gICAgY2FzZSBcImRpZmYgcmVtb3ZlZFwiOiByZXR1cm4gMzFcbiAgICBkZWZhdWx0OiB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBuYW1lOiBcXFwiXCIgKyBuYW1lICsgXCJcXFwiXCIpXG4gICAgfVxufVxuXG5leHBvcnRzLmNvbG9yID0gY29sb3JcbmZ1bmN0aW9uIGNvbG9yKG5hbWUsIHN0cikge1xuICAgIGlmIChDb2xvcnMuc3VwcG9ydGVkKCkpIHtcbiAgICAgICAgcmV0dXJuIFwiXFx1MDAxYltcIiArIGNvbG9yVG9OdW1iZXIobmFtZSkgKyBcIm1cIiArIHN0ciArIFwiXFx1MDAxYlswbVwiXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHN0ciArIFwiXCJcbiAgICB9XG59XG5cbmV4cG9ydHMuc2V0Q29sb3IgPSBmdW5jdGlvbiAoXykge1xuICAgIGlmIChfLm9wdHMuY29sb3IgIT0gbnVsbCkgQ29sb3JzLm1heWJlU2V0KF8ub3B0cy5jb2xvcilcbn1cblxuZXhwb3J0cy51bnNldENvbG9yID0gZnVuY3Rpb24gKF8pIHtcbiAgICBpZiAoXy5vcHRzLmNvbG9yICE9IG51bGwpIENvbG9ycy5tYXliZVJlc3RvcmUoKVxufVxuXG52YXIgU3RhdHVzID0gZXhwb3J0cy5TdGF0dXMgPSBPYmplY3QuZnJlZXplKHtcbiAgICBVbmtub3duOiAwLFxuICAgIFNraXBwZWQ6IDEsXG4gICAgUGFzc2luZzogMixcbiAgICBGYWlsaW5nOiAzLFxufSlcblxuZXhwb3J0cy5UcmVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlXG4gICAgdGhpcy5zdGF0dXMgPSBTdGF0dXMuVW5rbm93blxuICAgIHRoaXMuY2hpbGRyZW4gPSBPYmplY3QuY3JlYXRlKG51bGwpXG59XG5cbmV4cG9ydHMuZGVmYXVsdGlmeSA9IGZ1bmN0aW9uIChfLCBvcHRzLCBwcm9wKSB7XG4gICAgaWYgKF8ubWV0aG9kcy5hY2NlcHRzLmluZGV4T2YocHJvcCkgPj0gMCkge1xuICAgICAgICB2YXIgdXNlZCA9IG9wdHMgIT0gbnVsbCAmJiB0eXBlb2Ygb3B0c1twcm9wXSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICA/IG9wdHNcbiAgICAgICAgICAgIDogU2V0dGluZ3MuZGVmYXVsdE9wdHMoKVxuXG4gICAgICAgIF8ub3B0c1twcm9wXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodXNlZFtwcm9wXS5hcHBseSh1c2VkLCBhcmd1bWVudHMpKVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBqb2luUGF0aChyZXBvcnRQYXRoKSB7XG4gICAgdmFyIHBhdGggPSBcIlwiXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcG9ydFBhdGgubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcGF0aCArPSBcIiBcIiArIHJlcG9ydFBhdGhbaV0ubmFtZVxuICAgIH1cblxuICAgIHJldHVybiBwYXRoLnNsaWNlKDEpXG59XG5cbmV4cG9ydHMuam9pblBhdGggPSBmdW5jdGlvbiAocmVwb3J0KSB7XG4gICAgcmV0dXJuIGpvaW5QYXRoKHJlcG9ydC5wYXRoKVxufVxuXG5leHBvcnRzLnNwZWVkID0gZnVuY3Rpb24gKHJlcG9ydCkge1xuICAgIGlmIChyZXBvcnQuZHVyYXRpb24gPj0gcmVwb3J0LnNsb3cpIHJldHVybiBcInNsb3dcIlxuICAgIGlmIChyZXBvcnQuZHVyYXRpb24gPj0gcmVwb3J0LnNsb3cgLyAyKSByZXR1cm4gXCJtZWRpdW1cIlxuICAgIGlmIChyZXBvcnQuZHVyYXRpb24gPj0gMCkgcmV0dXJuIFwiZmFzdFwiXG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJEdXJhdGlvbiBtdXN0IG5vdCBiZSBuZWdhdGl2ZVwiKVxufVxuXG5leHBvcnRzLmZvcm1hdFRpbWUgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBzID0gMTAwMCAvKiBtcyAqL1xuICAgIHZhciBtID0gNjAgKiBzXG4gICAgdmFyIGggPSA2MCAqIG1cbiAgICB2YXIgZCA9IDI0ICogaFxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChtcykge1xuICAgICAgICBpZiAobXMgPj0gZCkgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArIFwiZFwiXG4gICAgICAgIGlmIChtcyA+PSBoKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIGgpICsgXCJoXCJcbiAgICAgICAgaWYgKG1zID49IG0pIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gbSkgKyBcIm1cIlxuICAgICAgICBpZiAobXMgPj0gcykgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArIFwic1wiXG4gICAgICAgIHJldHVybiBtcyArIFwibXNcIlxuICAgIH1cbn0pKClcblxuZXhwb3J0cy5mb3JtYXRSZXN0ID0gZnVuY3Rpb24gKHJlcG9ydCkge1xuICAgIGlmICghcmVwb3J0LmlzSG9vaykgcmV0dXJuIFwiXCJcbiAgICB2YXIgcGF0aCA9IFwiIChcIlxuXG4gICAgaWYgKHJlcG9ydC5yb290UGF0aC5sZW5ndGgpIHtcbiAgICAgICAgcGF0aCArPSByZXBvcnQuc3RhZ2VcbiAgICAgICAgaWYgKHJlcG9ydC5uYW1lKSBwYXRoICs9IFwiIOKAkiBcIiArIHJlcG9ydC5uYW1lXG4gICAgICAgIGlmIChyZXBvcnQucGF0aC5sZW5ndGggPiByZXBvcnQucm9vdFBhdGgubGVuZ3RoICsgMSkge1xuICAgICAgICAgICAgcGF0aCArPSBcIiwgaW4gXCIgKyBqb2luUGF0aChyZXBvcnQucm9vdFBhdGgpXG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXRoICs9IFwiZ2xvYmFsIFwiICsgcmVwb3J0LnN0YWdlXG4gICAgICAgIGlmIChyZXBvcnQubmFtZSkgcGF0aCArPSBcIiDigJIgXCIgKyByZXBvcnQubmFtZVxuICAgIH1cblxuICAgIHJldHVybiBwYXRoICsgXCIpXCJcbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8vIEdlbmVyYWwgQ0xJIGFuZCByZXBvcnRlciBzZXR0aW5ncy4gSWYgc29tZXRoaW5nIG5lZWRzIHRvXG5cbnZhciBDb25zb2xlID0gcmVxdWlyZShcIi4vcmVwbGFjZWQvY29uc29sZVwiKVxuXG52YXIgd2luZG93V2lkdGggPSBDb25zb2xlLndpbmRvd1dpZHRoXG52YXIgbmV3bGluZSA9IENvbnNvbGUubmV3bGluZVxudmFyIFN5bWJvbHMgPSBDb25zb2xlLlN5bWJvbHNcbnZhciBkZWZhdWx0T3B0cyA9IENvbnNvbGUuZGVmYXVsdE9wdHNcblxuZXhwb3J0cy53aW5kb3dXaWR0aCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHdpbmRvd1dpZHRoIH1cbmV4cG9ydHMubmV3bGluZSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ld2xpbmUgfVxuZXhwb3J0cy5zeW1ib2xzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gU3ltYm9scyB9XG5leHBvcnRzLmRlZmF1bHRPcHRzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gZGVmYXVsdE9wdHMgfVxuXG5leHBvcnRzLnNldFdpbmRvd1dpZHRoID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiB3aW5kb3dXaWR0aCA9IHZhbHVlIH1cbmV4cG9ydHMuc2V0TmV3bGluZSA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gbmV3bGluZSA9IHZhbHVlIH1cbmV4cG9ydHMuc2V0U3ltYm9scyA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gU3ltYm9scyA9IHZhbHVlIH1cbmV4cG9ydHMuc2V0RGVmYXVsdE9wdHMgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIGRlZmF1bHRPcHRzID0gdmFsdWUgfVxuXG4vLyBDb25zb2xlLmNvbG9yU3VwcG9ydCBpcyBhIG1hc2sgd2l0aCB0aGUgZm9sbG93aW5nIGJpdHM6XG4vLyAweDEgLSBpZiBzZXQsIGNvbG9ycyBzdXBwb3J0ZWQgYnkgZGVmYXVsdFxuLy8gMHgyIC0gaWYgc2V0LCBmb3JjZSBjb2xvciBzdXBwb3J0XG4vL1xuLy8gVGhpcyBpcyBwdXJlbHkgYW4gaW1wbGVtZW50YXRpb24gZGV0YWlsLCBhbmQgaXMgaW52aXNpYmxlIHRvIHRoZSBvdXRzaWRlXG4vLyB3b3JsZC5cbnZhciBjb2xvclN1cHBvcnQgPSBDb25zb2xlLmNvbG9yU3VwcG9ydFxudmFyIG1hc2sgPSBjb2xvclN1cHBvcnRcblxuZXhwb3J0cy5Db2xvcnMgPSB7XG4gICAgc3VwcG9ydGVkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAobWFzayAmIDB4MSkgIT09IDBcbiAgICB9LFxuXG4gICAgZm9yY2VkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAobWFzayAmIDB4MikgIT09IDBcbiAgICB9LFxuXG4gICAgbWF5YmVTZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAoKG1hc2sgJiAweDIpID09PSAwKSBtYXNrID0gdmFsdWUgPyAweDEgOiAwXG4gICAgfSxcblxuICAgIG1heWJlUmVzdG9yZTogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoKG1hc2sgJiAweDIpID09PSAwKSBtYXNrID0gY29sb3JTdXBwb3J0ICYgMHgxXG4gICAgfSxcblxuICAgIC8vIE9ubHkgZm9yIGRlYnVnZ2luZ1xuICAgIGZvcmNlU2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgbWFzayA9IHZhbHVlID8gMHgzIDogMHgyXG4gICAgfSxcblxuICAgIGZvcmNlUmVzdG9yZTogZnVuY3Rpb24gKCkge1xuICAgICAgICBtYXNrID0gY29sb3JTdXBwb3J0XG4gICAgfSxcblxuICAgIGdldFN1cHBvcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1cHBvcnRlZDogKGNvbG9yU3VwcG9ydCAmIDB4MSkgIT09IDAsXG4gICAgICAgICAgICBmb3JjZWQ6IChjb2xvclN1cHBvcnQgJiAweDIpICE9PSAwLFxuICAgICAgICB9XG4gICAgfSxcblxuICAgIHNldFN1cHBvcnQ6IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgICAgIG1hc2sgPSBjb2xvclN1cHBvcnQgPVxuICAgICAgICAgICAgKG9wdHMuc3VwcG9ydGVkID8gMHgxIDogMCkgfCAob3B0cy5mb3JjZWQgPyAweDIgOiAwKVxuICAgIH0sXG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgbWV0aG9kcyA9IHJlcXVpcmUoXCIuL21ldGhvZHNcIilcblxuZXhwb3J0cy5nZXRUeXBlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBcIm51bGxcIlxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIFwiYXJyYXlcIlxuICAgIHJldHVybiB0eXBlb2YgdmFsdWVcbn1cblxuLy8gUGhhbnRvbUpTLCBJRSwgYW5kIHBvc3NpYmx5IEVkZ2UgZG9uJ3Qgc2V0IHRoZSBzdGFjayB0cmFjZSB1bnRpbCB0aGUgZXJyb3IgaXNcbi8vIHRocm93bi4gTm90ZSB0aGF0IHRoaXMgcHJlZmVycyBhbiBleGlzdGluZyBzdGFjayBmaXJzdCwgc2luY2Ugbm9uLW5hdGl2ZVxuLy8gZXJyb3JzIGxpa2VseSBhbHJlYWR5IGNvbnRhaW4gdGhpcy4gTm90ZSB0aGF0IHRoaXMgaXNuJ3QgbmVjZXNzYXJ5IGluIHRoZVxuLy8gQ0xJIC0gdGhhdCBvbmx5IHRhcmdldHMgTm9kZS5cbmV4cG9ydHMuZ2V0U3RhY2sgPSBmdW5jdGlvbiAoZSkge1xuICAgIHZhciBzdGFjayA9IGUuc3RhY2tcblxuICAgIGlmICghKGUgaW5zdGFuY2VvZiBFcnJvcikgfHwgc3RhY2sgIT0gbnVsbCkgcmV0dXJuIHN0YWNrXG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBlXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZS5zdGFja1xuICAgIH1cbn1cblxuZXhwb3J0cy5wY2FsbCA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmMoZnVuY3Rpb24gKGUsIHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gZSAhPSBudWxsID8gcmVqZWN0KGUpIDogcmVzb2x2ZSh2YWx1ZSlcbiAgICAgICAgfSlcbiAgICB9KVxufVxuXG5leHBvcnRzLnBlYWNoID0gZnVuY3Rpb24gKGxpc3QsIGZ1bmMpIHtcbiAgICB2YXIgbGVuID0gbGlzdC5sZW5ndGhcbiAgICB2YXIgcCA9IFByb21pc2UucmVzb2x2ZSgpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHAgPSBwLnRoZW4oZnVuYy5iaW5kKHVuZGVmaW5lZCwgbGlzdFtpXSwgaSkpXG4gICAgfVxuXG4gICAgcmV0dXJuIHBcbn1cblxuLyoqXG4gKiBBIGxhenkgYWNjZXNzb3IsIGNvbXBsZXRlIHdpdGggdGhyb3duIGVycm9yIG1lbW9pemF0aW9uIGFuZCBhIGRlY2VudCBhbW91bnRcbiAqIG9mIG9wdGltaXphdGlvbiwgc2luY2UgaXQncyB1c2VkIGluIGEgbG90IG9mIGNvZGUuXG4gKlxuICogTm90ZSB0aGF0IHRoaXMgdXNlcyByZWZlcmVuY2UgaW5kaXJlY3Rpb24gYW5kIGRpcmVjdCBtdXRhdGlvbiB0byBrZWVwIG9ubHlcbiAqIGp1c3QgdGhlIGNvbXB1dGF0aW9uIG5vbi1jb25zdGFudCwgc28gZW5naW5lcyBjYW4gYXZvaWQgY2xvc3VyZSBhbGxvY2F0aW9uLlxuICogQWxzbywgYGNyZWF0ZWAgaXMgaW50ZW50aW9uYWxseSBrZXB0ICpvdXQqIG9mIGFueSBjbG9zdXJlLCBzbyBpdCBjYW4gYmUgbW9yZVxuICogZWFzaWx5IGNvbGxlY3RlZC5cbiAqL1xuZnVuY3Rpb24gTGF6eShjcmVhdGUpIHtcbiAgICB0aGlzLnZhbHVlID0gY3JlYXRlXG4gICAgdGhpcy5nZXQgPSB0aGlzLmluaXRcbn1cblxubWV0aG9kcyhMYXp5LCB7XG4gICAgcmVjdXJzaXZlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJMYXp5IGZ1bmN0aW9ucyBtdXN0IG5vdCBiZSBjYWxsZWQgcmVjdXJzaXZlbHkhXCIpXG4gICAgfSxcblxuICAgIHJldHVybjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZVxuICAgIH0sXG5cbiAgICB0aHJvdzogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aHJvdyB0aGlzLnZhbHVlXG4gICAgfSxcblxuICAgIGluaXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5nZXQgPSB0aGlzLnJlY3Vyc2l2ZVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gKDAsIHRoaXMudmFsdWUpKClcbiAgICAgICAgICAgIHRoaXMuZ2V0ID0gdGhpcy5yZXR1cm5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBlXG4gICAgICAgICAgICB0aGlzLmdldCA9IHRoaXMudGhyb3dcbiAgICAgICAgICAgIHRocm93IHRoaXMudmFsdWVcbiAgICAgICAgfVxuICAgIH0sXG59KVxuXG5leHBvcnRzLmxhenkgPSBmdW5jdGlvbiAoY3JlYXRlKSB7XG4gICAgdmFyIHJlZiA9IG5ldyBMYXp5KGNyZWF0ZSlcblxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiByZWYuZ2V0KClcbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vKipcbiAqIEJhY2twb3J0IHdyYXBwZXIgdG8gd2FybiBhYm91dCBtb3N0IG9mIHRoZSBtYWpvciBicmVha2luZyBjaGFuZ2VzIGZyb20gdGhlXG4gKiBsYXN0IG1ham9yIHZlcnNpb24sIGFuZCB0byBoZWxwIG1lIGtlZXAgdHJhY2sgb2YgYWxsIHRoZSBjaGFuZ2VzLlxuICpcbiAqIEl0IGNvbnNpc3RzIG9mIHNvbGVseSBpbnRlcm5hbCBtb25rZXkgcGF0Y2hpbmcgdG8gcmV2aXZlIHN1cHBvcnQgb2YgcHJldmlvdXNcbiAqIHZlcnNpb25zLCBhbHRob3VnaCBJIHRyaWVkIHRvIGxpbWl0IGhvdyBtdWNoIGtub3dsZWRnZSBvZiB0aGUgaW50ZXJuYWxzIHRoaXNcbiAqIHJlcXVpcmVzLlxuICovXG5cbi8vIHZhciBDb21tb24gPSByZXF1aXJlKFwiLi9jb21tb25cIilcbi8vIHZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL2xpYi9tZXRob2RzXCIpXG4iLCJcInVzZSBzdHJpY3RcIlxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoeHMsIGYpIHtcbiAgICBpZiAoeHMubWFwKSByZXR1cm4geHMubWFwKGYpO1xuICAgIHZhciByZXMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciB4ID0geHNbaV07XG4gICAgICAgIGlmIChoYXNPd24uY2FsbCh4cywgaSkpIHJlcy5wdXNoKGYoeCwgaSwgeHMpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn07XG5cbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuIiwidmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHhzLCBmLCBhY2MpIHtcbiAgICB2YXIgaGFzQWNjID0gYXJndW1lbnRzLmxlbmd0aCA+PSAzO1xuICAgIGlmIChoYXNBY2MgJiYgeHMucmVkdWNlKSByZXR1cm4geHMucmVkdWNlKGYsIGFjYyk7XG4gICAgaWYgKHhzLnJlZHVjZSkgcmV0dXJuIHhzLnJlZHVjZShmKTtcbiAgICBcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICghaGFzT3duLmNhbGwoeHMsIGkpKSBjb250aW51ZTtcbiAgICAgICAgaWYgKCFoYXNBY2MpIHtcbiAgICAgICAgICAgIGFjYyA9IHhzW2ldO1xuICAgICAgICAgICAgaGFzQWNjID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGFjYyA9IGYoYWNjLCB4c1tpXSwgaSk7XG4gICAgfVxuICAgIHJldHVybiBhY2M7XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9zdWJzdGFjay9ub2RlLWJyb3dzZXJpZnkvaXNzdWVzLzE2NzRcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwidXRpbC1pbnNwZWN0XCIpXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgaW5zcGVjdCA9IGV4cG9ydHMuaW5zcGVjdCA9IHJlcXVpcmUoXCIuL2luc3BlY3RcIilcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5XG52YXIgQXNzZXJ0aW9uRXJyb3JcblxuLy8gUGhhbnRvbUpTLCBJRSwgYW5kIHBvc3NpYmx5IEVkZ2UgZG9uJ3Qgc2V0IHRoZSBzdGFjayB0cmFjZSB1bnRpbCB0aGUgZXJyb3IgaXNcbi8vIHRocm93bi4gTm90ZSB0aGF0IHRoaXMgcHJlZmVycyBhbiBleGlzdGluZyBzdGFjayBmaXJzdCwgc2luY2Ugbm9uLW5hdGl2ZVxuLy8gZXJyb3JzIGxpa2VseSBhbHJlYWR5IGNvbnRhaW4gdGhpcy5cbmZ1bmN0aW9uIGdldFN0YWNrKGUpIHtcbiAgICB2YXIgc3RhY2sgPSBlLnN0YWNrXG5cbiAgICBpZiAoIShlIGluc3RhbmNlb2YgRXJyb3IpIHx8IHN0YWNrICE9IG51bGwpIHJldHVybiBzdGFja1xuXG4gICAgdHJ5IHtcbiAgICAgICAgdGhyb3cgZVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGUuc3RhY2tcbiAgICB9XG59XG5cbnRyeSB7XG4gICAgQXNzZXJ0aW9uRXJyb3IgPSBuZXcgRnVuY3Rpb24oWyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ldy1mdW5jXG4gICAgICAgIFwiJ3VzZSBzdHJpY3QnO1wiLFxuICAgICAgICBcImNsYXNzIEFzc2VydGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1wiLFxuICAgICAgICBcIiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsKSB7XCIsXG4gICAgICAgIFwiICAgICAgICBzdXBlcihtZXNzYWdlKVwiLFxuICAgICAgICBcIiAgICAgICAgdGhpcy5leHBlY3RlZCA9IGV4cGVjdGVkXCIsXG4gICAgICAgIFwiICAgICAgICB0aGlzLmFjdHVhbCA9IGFjdHVhbFwiLFxuICAgICAgICBcIiAgICB9XCIsXG4gICAgICAgIFwiXCIsXG4gICAgICAgIFwiICAgIGdldCBuYW1lKCkge1wiLFxuICAgICAgICBcIiAgICAgICAgcmV0dXJuICdBc3NlcnRpb25FcnJvcidcIixcbiAgICAgICAgXCIgICAgfVwiLFxuICAgICAgICBcIn1cIixcbiAgICAgICAgLy8gY2hlY2sgbmF0aXZlIHN1YmNsYXNzaW5nIHN1cHBvcnRcbiAgICAgICAgXCJuZXcgQXNzZXJ0aW9uRXJyb3IoJ21lc3NhZ2UnLCAxLCAyKVwiLFxuICAgICAgICBcInJldHVybiBBc3NlcnRpb25FcnJvclwiLFxuICAgIF0uam9pbihcIlxcblwiKSkoKVxufSBjYXRjaCAoZSkge1xuICAgIEFzc2VydGlvbkVycm9yID0gdHlwZW9mIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgPyBmdW5jdGlvbiBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsKSB7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlIHx8IFwiXCJcbiAgICAgICAgICAgIHRoaXMuZXhwZWN0ZWQgPSBleHBlY3RlZFxuICAgICAgICAgICAgdGhpcy5hY3R1YWwgPSBhY3R1YWxcbiAgICAgICAgICAgIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKHRoaXMsIHRoaXMuY29uc3RydWN0b3IpXG4gICAgICAgIH1cbiAgICAgICAgOiBmdW5jdGlvbiBBc3NlcnRpb25FcnJvcihtZXNzYWdlLCBleHBlY3RlZCwgYWN0dWFsKSB7XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlIHx8IFwiXCJcbiAgICAgICAgICAgIHRoaXMuZXhwZWN0ZWQgPSBleHBlY3RlZFxuICAgICAgICAgICAgdGhpcy5hY3R1YWwgPSBhY3R1YWxcbiAgICAgICAgICAgIHZhciBlID0gbmV3IEVycm9yKG1lc3NhZ2UpXG5cbiAgICAgICAgICAgIGUubmFtZSA9IFwiQXNzZXJ0aW9uRXJyb3JcIlxuICAgICAgICAgICAgdGhpcy5zdGFjayA9IGdldFN0YWNrKGUpXG4gICAgICAgIH1cblxuICAgIEFzc2VydGlvbkVycm9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFzc2VydGlvbkVycm9yLnByb3RvdHlwZSwgXCJjb25zdHJ1Y3RvclwiLCB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogQXNzZXJ0aW9uRXJyb3IsXG4gICAgfSlcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBc3NlcnRpb25FcnJvci5wcm90b3R5cGUsIFwibmFtZVwiLCB7XG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogXCJBc3NlcnRpb25FcnJvclwiLFxuICAgIH0pXG59XG5cbmV4cG9ydHMuQXNzZXJ0aW9uRXJyb3IgPSBBc3NlcnRpb25FcnJvclxuXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1zZWxmLWNvbXBhcmUgKi9cbi8vIEZvciBiZXR0ZXIgTmFOIGhhbmRsaW5nXG5leHBvcnRzLnN0cmljdElzID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gYSA9PT0gYiB8fCBhICE9PSBhICYmIGIgIT09IGJcbn1cblxuZXhwb3J0cy5sb29zZUlzID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gYSA9PSBiIHx8IGEgIT09IGEgJiYgYiAhPT0gYiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGVxZXFlcVxufVxuXG4vKiBlc2xpbnQtZW5hYmxlIG5vLXNlbGYtY29tcGFyZSAqL1xuXG52YXIgdGVtcGxhdGVSZWdleHAgPSAvKC4/KVxceyguKz8pXFx9L2dcblxuZXhwb3J0cy5lc2NhcGUgPSBmdW5jdGlvbiAoc3RyaW5nKSB7XG4gICAgaWYgKHR5cGVvZiBzdHJpbmcgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBzdHJpbmdgIG11c3QgYmUgYSBzdHJpbmdcIilcbiAgICB9XG5cbiAgICByZXR1cm4gc3RyaW5nLnJlcGxhY2UodGVtcGxhdGVSZWdleHAsIGZ1bmN0aW9uIChtLCBwcmUpIHtcbiAgICAgICAgcmV0dXJuIHByZSArIFwiXFxcXFwiICsgbS5zbGljZSgxKVxuICAgIH0pXG59XG5cbi8vIFRoaXMgZm9ybWF0cyB0aGUgYXNzZXJ0aW9uIGVycm9yIG1lc3NhZ2VzLlxuZXhwb3J0cy5mb3JtYXQgPSBmdW5jdGlvbiAobWVzc2FnZSwgYXJncywgcHJldHRpZnkpIHtcbiAgICBpZiAocHJldHRpZnkgPT0gbnVsbCkgcHJldHRpZnkgPSBpbnNwZWN0XG5cbiAgICBpZiAodHlwZW9mIG1lc3NhZ2UgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBtZXNzYWdlYCBtdXN0IGJlIGEgc3RyaW5nXCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBhcmdzICE9PSBcIm9iamVjdFwiIHx8IGFyZ3MgPT09IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBhcmdzYCBtdXN0IGJlIGFuIG9iamVjdFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcHJldHRpZnkgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYHByZXR0aWZ5YCBtdXN0IGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIG1lc3NhZ2UucmVwbGFjZSh0ZW1wbGF0ZVJlZ2V4cCwgZnVuY3Rpb24gKG0sIHByZSwgcHJvcCkge1xuICAgICAgICBpZiAocHJlID09PSBcIlxcXFxcIikge1xuICAgICAgICAgICAgcmV0dXJuIG0uc2xpY2UoMSlcbiAgICAgICAgfSBlbHNlIGlmIChoYXNPd24uY2FsbChhcmdzLCBwcm9wKSkge1xuICAgICAgICAgICAgcmV0dXJuIHByZSArIHByZXR0aWZ5KGFyZ3NbcHJvcF0sIHtkZXB0aDogNX0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gcHJlICsgbVxuICAgICAgICB9XG4gICAgfSlcbn1cblxuZXhwb3J0cy5mYWlsID0gZnVuY3Rpb24gKG1lc3NhZ2UsIGFyZ3MsIHByZXR0aWZ5KSB7XG4gICAgaWYgKGFyZ3MgPT0gbnVsbCkgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKG1lc3NhZ2UpXG4gICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKFxuICAgICAgICBleHBvcnRzLmZvcm1hdChtZXNzYWdlLCBhcmdzLCBwcmV0dGlmeSksXG4gICAgICAgIGFyZ3MuZXhwZWN0ZWQsXG4gICAgICAgIGFyZ3MuYWN0dWFsKVxufVxuXG4vLyBUaGUgYmFzaWMgYXNzZXJ0LCBsaWtlIGBhc3NlcnQub2tgLCBidXQgZ2l2ZXMgeW91IGFuIG9wdGlvbmFsIG1lc3NhZ2UuXG5leHBvcnRzLmFzc2VydCA9IGZ1bmN0aW9uICh0ZXN0LCBtZXNzYWdlKSB7XG4gICAgaWYgKCF0ZXN0KSB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobWVzc2FnZSlcbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogQ29yZSBUREQtc3R5bGUgYXNzZXJ0aW9ucy4gVGhlc2UgYXJlIGRvbmUgYnkgYSBjb21wb3NpdGlvbiBvZiBEU0xzLCBzaW5jZVxuICogdGhlcmUgaXMgKnNvKiBtdWNoIHJlcGV0aXRpb24uIEFsc28sIHRoaXMgaXMgc3BsaXQgaW50byBzZXZlcmFsIG5hbWVzcGFjZXMgdG9cbiAqIGtlZXAgdGhlIGZpbGUgc2l6ZSBtYW5hZ2VhYmxlLlxuICovXG5cbnZhciB1dGlsID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpXG52YXIgdHlwZSA9IHJlcXVpcmUoXCIuL2xpYi90eXBlXCIpXG52YXIgZXF1YWwgPSByZXF1aXJlKFwiLi9saWIvZXF1YWxcIilcbnZhciB0aHJvd3MgPSByZXF1aXJlKFwiLi9saWIvdGhyb3dzXCIpXG52YXIgaGFzID0gcmVxdWlyZShcIi4vbGliL2hhc1wiKVxudmFyIGluY2x1ZGVzID0gcmVxdWlyZShcIi4vbGliL2luY2x1ZGVzXCIpXG52YXIgaGFzS2V5cyA9IHJlcXVpcmUoXCIuL2xpYi9oYXMta2V5c1wiKVxuXG5leHBvcnRzLkFzc2VydGlvbkVycm9yID0gdXRpbC5Bc3NlcnRpb25FcnJvclxuZXhwb3J0cy5hc3NlcnQgPSB1dGlsLmFzc2VydFxuZXhwb3J0cy5mYWlsID0gdXRpbC5mYWlsXG5cbmV4cG9ydHMub2sgPSB0eXBlLm9rXG5leHBvcnRzLm5vdE9rID0gdHlwZS5ub3RPa1xuZXhwb3J0cy5pc0Jvb2xlYW4gPSB0eXBlLmlzQm9vbGVhblxuZXhwb3J0cy5ub3RCb29sZWFuID0gdHlwZS5ub3RCb29sZWFuXG5leHBvcnRzLmlzRnVuY3Rpb24gPSB0eXBlLmlzRnVuY3Rpb25cbmV4cG9ydHMubm90RnVuY3Rpb24gPSB0eXBlLm5vdEZ1bmN0aW9uXG5leHBvcnRzLmlzTnVtYmVyID0gdHlwZS5pc051bWJlclxuZXhwb3J0cy5ub3ROdW1iZXIgPSB0eXBlLm5vdE51bWJlclxuZXhwb3J0cy5pc09iamVjdCA9IHR5cGUuaXNPYmplY3RcbmV4cG9ydHMubm90T2JqZWN0ID0gdHlwZS5ub3RPYmplY3RcbmV4cG9ydHMuaXNTdHJpbmcgPSB0eXBlLmlzU3RyaW5nXG5leHBvcnRzLm5vdFN0cmluZyA9IHR5cGUubm90U3RyaW5nXG5leHBvcnRzLmlzU3ltYm9sID0gdHlwZS5pc1N5bWJvbFxuZXhwb3J0cy5ub3RTeW1ib2wgPSB0eXBlLm5vdFN5bWJvbFxuZXhwb3J0cy5leGlzdHMgPSB0eXBlLmV4aXN0c1xuZXhwb3J0cy5ub3RFeGlzdHMgPSB0eXBlLm5vdEV4aXN0c1xuZXhwb3J0cy5pc0FycmF5ID0gdHlwZS5pc0FycmF5XG5leHBvcnRzLm5vdEFycmF5ID0gdHlwZS5ub3RBcnJheVxuZXhwb3J0cy5pcyA9IHR5cGUuaXNcbmV4cG9ydHMubm90ID0gdHlwZS5ub3RcblxuZXhwb3J0cy5lcXVhbCA9IGVxdWFsLmVxdWFsXG5leHBvcnRzLm5vdEVxdWFsID0gZXF1YWwubm90RXF1YWxcbmV4cG9ydHMuZXF1YWxMb29zZSA9IGVxdWFsLmVxdWFsTG9vc2VcbmV4cG9ydHMubm90RXF1YWxMb29zZSA9IGVxdWFsLm5vdEVxdWFsTG9vc2VcbmV4cG9ydHMuZGVlcEVxdWFsID0gZXF1YWwuZGVlcEVxdWFsXG5leHBvcnRzLm5vdERlZXBFcXVhbCA9IGVxdWFsLm5vdERlZXBFcXVhbFxuZXhwb3J0cy5tYXRjaCA9IGVxdWFsLm1hdGNoXG5leHBvcnRzLm5vdE1hdGNoID0gZXF1YWwubm90TWF0Y2hcbmV4cG9ydHMuYXRMZWFzdCA9IGVxdWFsLmF0TGVhc3RcbmV4cG9ydHMuYXRNb3N0ID0gZXF1YWwuYXRNb3N0XG5leHBvcnRzLmFib3ZlID0gZXF1YWwuYWJvdmVcbmV4cG9ydHMuYmVsb3cgPSBlcXVhbC5iZWxvd1xuZXhwb3J0cy5iZXR3ZWVuID0gZXF1YWwuYmV0d2VlblxuZXhwb3J0cy5jbG9zZVRvID0gZXF1YWwuY2xvc2VUb1xuZXhwb3J0cy5ub3RDbG9zZVRvID0gZXF1YWwubm90Q2xvc2VUb1xuXG5leHBvcnRzLnRocm93cyA9IHRocm93cy50aHJvd3NcbmV4cG9ydHMudGhyb3dzTWF0Y2ggPSB0aHJvd3MudGhyb3dzTWF0Y2hcblxuZXhwb3J0cy5oYXNPd24gPSBoYXMuaGFzT3duXG5leHBvcnRzLm5vdEhhc093biA9IGhhcy5ub3RIYXNPd25cbmV4cG9ydHMuaGFzT3duTG9vc2UgPSBoYXMuaGFzT3duTG9vc2VcbmV4cG9ydHMubm90SGFzT3duTG9vc2UgPSBoYXMubm90SGFzT3duTG9vc2VcbmV4cG9ydHMuaGFzS2V5ID0gaGFzLmhhc0tleVxuZXhwb3J0cy5ub3RIYXNLZXkgPSBoYXMubm90SGFzS2V5XG5leHBvcnRzLmhhc0tleUxvb3NlID0gaGFzLmhhc0tleUxvb3NlXG5leHBvcnRzLm5vdEhhc0tleUxvb3NlID0gaGFzLm5vdEhhc0tleUxvb3NlXG5leHBvcnRzLmhhcyA9IGhhcy5oYXNcbmV4cG9ydHMubm90SGFzID0gaGFzLm5vdEhhc1xuZXhwb3J0cy5oYXNMb29zZSA9IGhhcy5oYXNMb29zZVxuZXhwb3J0cy5ub3RIYXNMb29zZSA9IGhhcy5ub3RIYXNMb29zZVxuXG4vKipcbiAqIFRoZXJlJ3MgMiBzZXRzIG9mIDEyIHBlcm11dGF0aW9ucyBoZXJlIGZvciBgaW5jbHVkZXNgIGFuZCBgaGFzS2V5c2AsIGluc3RlYWRcbiAqIG9mIE4gc2V0cyBvZiAyICh3aGljaCB3b3VsZCBmaXQgdGhlIGBmb29gL2Bub3RGb29gIGlkaW9tIGJldHRlciksIHNvIGl0J3NcbiAqIGVhc2llciB0byBqdXN0IG1ha2UgYSBjb3VwbGUgc2VwYXJhdGUgRFNMcyBhbmQgdXNlIHRoYXQgdG8gZGVmaW5lIGV2ZXJ5dGhpbmcuXG4gKlxuICogSGVyZSdzIHRoZSB0b3AgbGV2ZWw6XG4gKlxuICogLSBzaGFsbG93XG4gKiAtIHN0cmljdCBkZWVwXG4gKiAtIHN0cnVjdHVyYWwgZGVlcFxuICpcbiAqIEFuZCB0aGUgc2Vjb25kIGxldmVsOlxuICpcbiAqIC0gaW5jbHVkZXMgYWxsL25vdCBtaXNzaW5nIHNvbWVcbiAqIC0gaW5jbHVkZXMgc29tZS9ub3QgbWlzc2luZyBhbGxcbiAqIC0gbm90IGluY2x1ZGluZyBhbGwvbWlzc2luZyBzb21lXG4gKiAtIG5vdCBpbmNsdWRpbmcgc29tZS9taXNzaW5nIGFsbFxuICpcbiAqIEhlcmUncyBhbiBleGFtcGxlIHVzaW5nIHRoZSBuYW1pbmcgc2NoZW1lIGZvciBgaGFzS2V5cypgXG4gKlxuICogICAgICAgICAgICAgICB8ICAgICBzaGFsbG93ICAgICB8ICAgIHN0cmljdCBkZWVwICAgICAgfCAgIHN0cnVjdHVyYWwgZGVlcFxuICogLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIGluY2x1ZGVzIGFsbCAgfCBgaGFzS2V5c2AgICAgICAgfCBgaGFzS2V5c0RlZXBgICAgICAgIHwgYGhhc0tleXNNYXRjaGBcbiAqIGluY2x1ZGVzIHNvbWUgfCBgaGFzS2V5c0FueWAgICAgfCBgaGFzS2V5c0FueURlZXBgICAgIHwgYGhhc0tleXNBbnlNYXRjaGBcbiAqIG1pc3Npbmcgc29tZSAgfCBgbm90SGFzS2V5c0FsbGAgfCBgbm90SGFzS2V5c0FsbERlZXBgIHwgYG5vdEhhc0tleXNBbGxNYXRjaGBcbiAqIG1pc3NpbmcgYWxsICAgfCBgbm90SGFzS2V5c2AgICAgfCBgbm90SGFzS2V5c0RlZXBgICAgIHwgYG5vdEhhc0tleXNNYXRjaGBcbiAqXG4gKiBOb3RlIHRoYXQgdGhlIGBoYXNLZXlzYCBzaGFsbG93IGNvbXBhcmlzb24gdmFyaWFudHMgYXJlIGFsc28gb3ZlcmxvYWRlZCB0b1xuICogY29uc3VtZSBlaXRoZXIgYW4gYXJyYXkgKGluIHdoaWNoIGl0IHNpbXBseSBjaGVja3MgYWdhaW5zdCBhIGxpc3Qgb2Yga2V5cykgb3JcbiAqIGFuIG9iamVjdCAod2hlcmUgaXQgZG9lcyBhIGZ1bGwgZGVlcCBjb21wYXJpc29uKS5cbiAqL1xuXG5leHBvcnRzLmluY2x1ZGVzID0gaW5jbHVkZXMuaW5jbHVkZXNcbmV4cG9ydHMuaW5jbHVkZXNEZWVwID0gaW5jbHVkZXMuaW5jbHVkZXNEZWVwXG5leHBvcnRzLmluY2x1ZGVzTWF0Y2ggPSBpbmNsdWRlcy5pbmNsdWRlc01hdGNoXG5leHBvcnRzLmluY2x1ZGVzQW55ID0gaW5jbHVkZXMuaW5jbHVkZXNBbnlcbmV4cG9ydHMuaW5jbHVkZXNBbnlEZWVwID0gaW5jbHVkZXMuaW5jbHVkZXNBbnlEZWVwXG5leHBvcnRzLmluY2x1ZGVzQW55TWF0Y2ggPSBpbmNsdWRlcy5pbmNsdWRlc0FueU1hdGNoXG5leHBvcnRzLm5vdEluY2x1ZGVzQWxsID0gaW5jbHVkZXMubm90SW5jbHVkZXNBbGxcbmV4cG9ydHMubm90SW5jbHVkZXNBbGxEZWVwID0gaW5jbHVkZXMubm90SW5jbHVkZXNBbGxEZWVwXG5leHBvcnRzLm5vdEluY2x1ZGVzQWxsTWF0Y2ggPSBpbmNsdWRlcy5ub3RJbmNsdWRlc0FsbE1hdGNoXG5leHBvcnRzLm5vdEluY2x1ZGVzID0gaW5jbHVkZXMubm90SW5jbHVkZXNcbmV4cG9ydHMubm90SW5jbHVkZXNEZWVwID0gaW5jbHVkZXMubm90SW5jbHVkZXNEZWVwXG5leHBvcnRzLm5vdEluY2x1ZGVzTWF0Y2ggPSBpbmNsdWRlcy5ub3RJbmNsdWRlc01hdGNoXG5cbmV4cG9ydHMuaGFzS2V5cyA9IGhhc0tleXMuaGFzS2V5c1xuZXhwb3J0cy5oYXNLZXlzRGVlcCA9IGhhc0tleXMuaGFzS2V5c0RlZXBcbmV4cG9ydHMuaGFzS2V5c01hdGNoID0gaGFzS2V5cy5oYXNLZXlzTWF0Y2hcbmV4cG9ydHMuaGFzS2V5c0FueSA9IGhhc0tleXMuaGFzS2V5c0FueVxuZXhwb3J0cy5oYXNLZXlzQW55RGVlcCA9IGhhc0tleXMuaGFzS2V5c0FueURlZXBcbmV4cG9ydHMuaGFzS2V5c0FueU1hdGNoID0gaGFzS2V5cy5oYXNLZXlzQW55TWF0Y2hcbmV4cG9ydHMubm90SGFzS2V5c0FsbCA9IGhhc0tleXMubm90SGFzS2V5c0FsbFxuZXhwb3J0cy5ub3RIYXNLZXlzQWxsRGVlcCA9IGhhc0tleXMubm90SGFzS2V5c0FsbERlZXBcbmV4cG9ydHMubm90SGFzS2V5c0FsbE1hdGNoID0gaGFzS2V5cy5ub3RIYXNLZXlzQWxsTWF0Y2hcbmV4cG9ydHMubm90SGFzS2V5cyA9IGhhc0tleXMubm90SGFzS2V5c1xuZXhwb3J0cy5ub3RIYXNLZXlzRGVlcCA9IGhhc0tleXMubm90SGFzS2V5c0RlZXBcbmV4cG9ydHMubm90SGFzS2V5c01hdGNoID0gaGFzS2V5cy5ub3RIYXNLZXlzTWF0Y2hcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBtYXRjaCA9IHJlcXVpcmUoXCJjbGVhbi1tYXRjaFwiKVxudmFyIHV0aWwgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0LXV0aWxcIilcblxuZnVuY3Rpb24gYmluYXJ5KG51bWVyaWMsIGNvbXBhcmF0b3IsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGFjdHVhbCwgZXhwZWN0ZWQpIHtcbiAgICAgICAgaWYgKG51bWVyaWMpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYWN0dWFsICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBhY3R1YWxgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBleHBlY3RlZCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgZXhwZWN0ZWRgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghY29tcGFyYXRvcihhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgICAgICAgICAgdXRpbC5mYWlsKG1lc3NhZ2UsIHthY3R1YWw6IGFjdHVhbCwgZXhwZWN0ZWQ6IGV4cGVjdGVkfSlcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0cy5lcXVhbCA9IGJpbmFyeShmYWxzZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gdXRpbC5zdHJpY3RJcyhhLCBiKSB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gZXF1YWwge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLm5vdEVxdWFsID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiAhdXRpbC5zdHJpY3RJcyhhLCBiKSB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGVxdWFsIHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5lcXVhbExvb3NlID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiB1dGlsLmxvb3NlSXMoYSwgYikgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGxvb3NlbHkgZXF1YWwge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLm5vdEVxdWFsTG9vc2UgPSBiaW5hcnkoZmFsc2UsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuICF1dGlsLmxvb3NlSXMoYSwgYikgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBsb29zZWx5IGVxdWFsIHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5hdExlYXN0ID0gYmluYXJ5KHRydWUsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEgPj0gYiB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYXQgbGVhc3Qge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLmF0TW9zdCA9IGJpbmFyeSh0cnVlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhIDw9IGIgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGF0IG1vc3Qge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLmFib3ZlID0gYmluYXJ5KHRydWUsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEgPiBiIH0sXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhYm92ZSB7ZXhwZWN0ZWR9XCIpXG5cbmV4cG9ydHMuYmVsb3cgPSBiaW5hcnkodHJ1ZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYSA8IGIgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGJlbG93IHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5iZXR3ZWVuID0gZnVuY3Rpb24gKGFjdHVhbCwgbG93ZXIsIHVwcGVyKSB7XG4gICAgaWYgKHR5cGVvZiBhY3R1YWwgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBhY3R1YWxgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGxvd2VyICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgbG93ZXJgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHVwcGVyICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgdXBwZXJgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICB9XG5cbiAgICAvLyBUaGUgbmVnYXRpb24gaXMgdG8gYWRkcmVzcyBOYU5zIGFzIHdlbGwsIHdpdGhvdXQgd3JpdGluZyBhIHRvbiBvZiBzcGVjaWFsXG4gICAgLy8gY2FzZSBib2lsZXJwbGF0ZVxuICAgIGlmICghKGFjdHVhbCA+PSBsb3dlciAmJiBhY3R1YWwgPD0gdXBwZXIpKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGJldHdlZW4ge2xvd2VyfSBhbmQge3VwcGVyfVwiLCB7XG4gICAgICAgICAgICBhY3R1YWw6IGFjdHVhbCxcbiAgICAgICAgICAgIGxvd2VyOiBsb3dlcixcbiAgICAgICAgICAgIHVwcGVyOiB1cHBlcixcbiAgICAgICAgfSlcbiAgICB9XG59XG5cbmV4cG9ydHMuZGVlcEVxdWFsID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBtYXRjaC5zdHJpY3QoYSwgYikgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGRlZXBseSBlcXVhbCB7ZXhwZWN0ZWR9XCIpXG5cbmV4cG9ydHMubm90RGVlcEVxdWFsID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiAhbWF0Y2guc3RyaWN0KGEsIGIpIH0sXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgZGVlcGx5IGVxdWFsIHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5tYXRjaCA9IGJpbmFyeShmYWxzZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gbWF0Y2gubG9vc2UoYSwgYikgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5ub3RNYXRjaCA9IGJpbmFyeShmYWxzZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gIW1hdGNoLmxvb3NlKGEsIGIpIH0sXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgbWF0Y2gge2V4cGVjdGVkfVwiKVxuXG4vLyBVc2VzIGRpdmlzaW9uIHRvIGFsbG93IGZvciBhIG1vcmUgcm9idXN0IGNvbXBhcmlzb24gb2YgZmxvYXRzLiBBbHNvLCB0aGlzXG4vLyBoYW5kbGVzIG5lYXItemVybyBjb21wYXJpc29ucyBjb3JyZWN0bHksIGFzIHdlbGwgYXMgYSB6ZXJvIHRvbGVyYW5jZSAoaS5lLlxuLy8gZXhhY3QgY29tcGFyaXNvbikuXG5mdW5jdGlvbiBjbG9zZVRvKGV4cGVjdGVkLCBhY3R1YWwsIHRvbGVyYW5jZSkge1xuICAgIGlmICh0b2xlcmFuY2UgPT09IEluZmluaXR5IHx8IGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHJldHVybiB0cnVlXG4gICAgaWYgKHRvbGVyYW5jZSA9PT0gMCkgcmV0dXJuIGZhbHNlXG4gICAgaWYgKGFjdHVhbCA9PT0gMCkgcmV0dXJuIE1hdGguYWJzKGV4cGVjdGVkKSA8IHRvbGVyYW5jZVxuICAgIGlmIChleHBlY3RlZCA9PT0gMCkgcmV0dXJuIE1hdGguYWJzKGFjdHVhbCkgPCB0b2xlcmFuY2VcbiAgICByZXR1cm4gTWF0aC5hYnMoZXhwZWN0ZWQgLyBhY3R1YWwgLSAxKSA8IHRvbGVyYW5jZVxufVxuXG4vLyBOb3RlOiB0aGVzZSB0d28gYWx3YXlzIGZhaWwgd2hlbiBkZWFsaW5nIHdpdGggTmFOcy5cbmV4cG9ydHMuY2xvc2VUbyA9IGZ1bmN0aW9uIChleHBlY3RlZCwgYWN0dWFsLCB0b2xlcmFuY2UpIHtcbiAgICBpZiAodHlwZW9mIGFjdHVhbCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGFjdHVhbGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZXhwZWN0ZWQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBleHBlY3RlZGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIGlmICh0b2xlcmFuY2UgPT0gbnVsbCkgdG9sZXJhbmNlID0gMWUtMTBcblxuICAgIGlmICh0eXBlb2YgdG9sZXJhbmNlICE9PSBcIm51bWJlclwiIHx8IHRvbGVyYW5jZSA8IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgIFwiYHRvbGVyYW5jZWAgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIgaWYgZ2l2ZW5cIilcbiAgICB9XG5cbiAgICBpZiAoYWN0dWFsICE9PSBhY3R1YWwgfHwgZXhwZWN0ZWQgIT09IGV4cGVjdGVkIHx8IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlLCBtYXgtbGVuXG4gICAgICAgICAgICAhY2xvc2VUbyhleHBlY3RlZCwgYWN0dWFsLCB0b2xlcmFuY2UpKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGNsb3NlIHRvIHtleHBlY3RlZH1cIiwge1xuICAgICAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgICAgICAgICBleHBlY3RlZDogZXhwZWN0ZWQsXG4gICAgICAgIH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdENsb3NlVG8gPSBmdW5jdGlvbiAoZXhwZWN0ZWQsIGFjdHVhbCwgdG9sZXJhbmNlKSB7XG4gICAgaWYgKHR5cGVvZiBhY3R1YWwgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBhY3R1YWxgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGV4cGVjdGVkICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgZXhwZWN0ZWRgIG11c3QgYmUgYSBudW1iZXJcIilcbiAgICB9XG5cbiAgICBpZiAodG9sZXJhbmNlID09IG51bGwpIHRvbGVyYW5jZSA9IDFlLTEwXG5cbiAgICBpZiAodHlwZW9mIHRvbGVyYW5jZSAhPT0gXCJudW1iZXJcIiB8fCB0b2xlcmFuY2UgPCAwKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICBcImB0b2xlcmFuY2VgIG11c3QgYmUgYSBub24tbmVnYXRpdmUgbnVtYmVyIGlmIGdpdmVuXCIpXG4gICAgfVxuXG4gICAgaWYgKGV4cGVjdGVkICE9PSBleHBlY3RlZCB8fCBhY3R1YWwgIT09IGFjdHVhbCB8fCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZSwgbWF4LWxlblxuICAgICAgICAgICAgY2xvc2VUbyhleHBlY3RlZCwgYWN0dWFsLCB0b2xlcmFuY2UpKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBjbG9zZSB0byB7ZXhwZWN0ZWR9XCIsIHtcbiAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuICAgICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgICAgICB9KVxuICAgIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBtYXRjaCA9IHJlcXVpcmUoXCJjbGVhbi1tYXRjaFwiKVxudmFyIHV0aWwgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0LXV0aWxcIilcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5XG5cbmZ1bmN0aW9uIGhhc0tleXMoYWxsLCBvYmplY3QsIGtleXMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHRlc3QgPSBoYXNPd24uY2FsbChvYmplY3QsIGtleXNbaV0pXG5cbiAgICAgICAgaWYgKHRlc3QgIT09IGFsbCkgcmV0dXJuICFhbGxcbiAgICB9XG5cbiAgICByZXR1cm4gYWxsXG59XG5cbmZ1bmN0aW9uIGhhc1ZhbHVlcyhmdW5jLCBhbGwsIG9iamVjdCwga2V5cykge1xuICAgIGlmIChvYmplY3QgPT09IGtleXMpIHJldHVybiB0cnVlXG4gICAgdmFyIGxpc3QgPSBPYmplY3Qua2V5cyhrZXlzKVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBsaXN0W2ldXG4gICAgICAgIHZhciB0ZXN0ID0gaGFzT3duLmNhbGwob2JqZWN0LCBrZXkpICYmIGZ1bmMoa2V5c1trZXldLCBvYmplY3Rba2V5XSlcblxuICAgICAgICBpZiAodGVzdCAhPT0gYWxsKSByZXR1cm4gdGVzdFxuICAgIH1cblxuICAgIHJldHVybiBhbGxcbn1cblxuZnVuY3Rpb24gbWFrZUhhc092ZXJsb2FkKGFsbCwgaW52ZXJ0LCBtZXNzYWdlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QsIGtleXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QgIT09IFwib2JqZWN0XCIgfHwgb2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgb2JqZWN0YCBtdXN0IGJlIGFuIG9iamVjdFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBrZXlzICE9PSBcIm9iamVjdFwiIHx8IGtleXMgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBrZXlzYCBtdXN0IGJlIGFuIG9iamVjdCBvciBhcnJheVwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoa2V5cykpIHtcbiAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCAmJiBoYXNLZXlzKGFsbCwgb2JqZWN0LCBrZXlzKSA9PT0gaW52ZXJ0KSB7XG4gICAgICAgICAgICAgICAgdXRpbC5mYWlsKG1lc3NhZ2UsIHthY3R1YWw6IG9iamVjdCwga2V5czoga2V5c30pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoT2JqZWN0LmtleXMoa2V5cykubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoaGFzVmFsdWVzKHV0aWwuc3RyaWN0SXMsIGFsbCwgb2JqZWN0LCBrZXlzKSA9PT0gaW52ZXJ0KSB7XG4gICAgICAgICAgICAgICAgdXRpbC5mYWlsKG1lc3NhZ2UsIHthY3R1YWw6IG9iamVjdCwga2V5czoga2V5c30pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIG1ha2VIYXNLZXlzKGZ1bmMsIGFsbCwgaW52ZXJ0LCBtZXNzYWdlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QsIGtleXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmplY3QgIT09IFwib2JqZWN0XCIgfHwgb2JqZWN0ID09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgb2JqZWN0YCBtdXN0IGJlIGFuIG9iamVjdFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBrZXlzICE9PSBcIm9iamVjdFwiIHx8IGtleXMgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBrZXlzYCBtdXN0IGJlIGFuIG9iamVjdFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gZXhjbHVzaXZlIG9yIHRvIGludmVydCB0aGUgcmVzdWx0IGlmIGBpbnZlcnRgIGlzIHRydWVcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKGtleXMpLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKGhhc1ZhbHVlcyhmdW5jLCBhbGwsIG9iamVjdCwga2V5cykgPT09IGludmVydCkge1xuICAgICAgICAgICAgICAgIHV0aWwuZmFpbChtZXNzYWdlLCB7YWN0dWFsOiBvYmplY3QsIGtleXM6IGtleXN9KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cbmV4cG9ydHMuaGFzS2V5cyA9IG1ha2VIYXNPdmVybG9hZCh0cnVlLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxuZXhwb3J0cy5oYXNLZXlzRGVlcCA9IG1ha2VIYXNLZXlzKG1hdGNoLnN0cmljdCwgdHJ1ZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBhbGwga2V5cyBpbiB7a2V5c31cIilcbmV4cG9ydHMuaGFzS2V5c01hdGNoID0gbWFrZUhhc0tleXMobWF0Y2gubG9vc2UsIHRydWUsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxuZXhwb3J0cy5oYXNLZXlzQW55ID0gbWFrZUhhc092ZXJsb2FkKGZhbHNlLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGFueSBrZXkgaW4ge2tleXN9XCIpXG5leHBvcnRzLmhhc0tleXNBbnlEZWVwID0gbWFrZUhhc0tleXMobWF0Y2guc3RyaWN0LCBmYWxzZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBhbnkga2V5IGluIHtrZXlzfVwiKVxuZXhwb3J0cy5oYXNLZXlzQW55TWF0Y2ggPSBtYWtlSGFzS2V5cyhtYXRjaC5sb29zZSwgZmFsc2UsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFueSBrZXkgaW4ge2tleXN9XCIpXG5leHBvcnRzLm5vdEhhc0tleXNBbGwgPSBtYWtlSGFzT3ZlcmxvYWQodHJ1ZSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBhbGwga2V5cyBpbiB7a2V5c31cIilcbmV4cG9ydHMubm90SGFzS2V5c0FsbERlZXAgPSBtYWtlSGFzS2V5cyhtYXRjaC5zdHJpY3QsIHRydWUsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUgYWxsIGtleXMgaW4ge2tleXN9XCIpXG5leHBvcnRzLm5vdEhhc0tleXNBbGxNYXRjaCA9IG1ha2VIYXNLZXlzKG1hdGNoLmxvb3NlLCB0cnVlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbGwga2V5cyBpbiB7a2V5c31cIilcbmV4cG9ydHMubm90SGFzS2V5cyA9IG1ha2VIYXNPdmVybG9hZChmYWxzZSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBhbnkga2V5IGluIHtrZXlzfVwiKVxuZXhwb3J0cy5ub3RIYXNLZXlzRGVlcCA9IG1ha2VIYXNLZXlzKG1hdGNoLnN0cmljdCwgZmFsc2UsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUgYW55IGtleSBpbiB7a2V5c31cIilcbmV4cG9ydHMubm90SGFzS2V5c01hdGNoID0gbWFrZUhhc0tleXMobWF0Y2gubG9vc2UsIGZhbHNlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbnkga2V5IGluIHtrZXlzfVwiKVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIHV0aWwgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0LXV0aWxcIilcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5XG5cbmZ1bmN0aW9uIGhhcyhfKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlbiwgbWF4LXBhcmFtc1xuICAgIHJldHVybiBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIHtcbiAgICAgICAgICAgIGlmICghXy5oYXMob2JqZWN0LCBrZXkpIHx8XG4gICAgICAgICAgICAgICAgICAgICF1dGlsLnN0cmljdElzKF8uZ2V0KG9iamVjdCwga2V5KSwgdmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdXRpbC5mYWlsKF8ubWVzc2FnZXNbMF0sIHtcbiAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IHZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBhY3R1YWw6IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghXy5oYXMob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgICAgICB1dGlsLmZhaWwoXy5tZXNzYWdlc1sxXSwge1xuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICBhY3R1YWw6IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgICAgIG9iamVjdDogb2JqZWN0LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gaGFzTG9vc2UoXykge1xuICAgIHJldHVybiBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmICghXy5oYXMob2JqZWN0LCBrZXkpIHx8ICF1dGlsLmxvb3NlSXMoXy5nZXQob2JqZWN0LCBrZXkpLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgIHV0aWwuZmFpbChfLm1lc3NhZ2VzWzBdLCB7XG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IHZhbHVlLFxuICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0W2tleV0sXG4gICAgICAgICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBub3RIYXMoXykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW4sIG1heC1wYXJhbXNcbiAgICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSB7XG4gICAgICAgICAgICBpZiAoXy5oYXMob2JqZWN0LCBrZXkpICYmXG4gICAgICAgICAgICAgICAgICAgIHV0aWwuc3RyaWN0SXMoXy5nZXQob2JqZWN0LCBrZXkpLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB1dGlsLmZhaWwoXy5tZXNzYWdlc1syXSwge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0W2tleV0sXG4gICAgICAgICAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKF8uaGFzKG9iamVjdCwga2V5KSkge1xuICAgICAgICAgICAgdXRpbC5mYWlsKF8ubWVzc2FnZXNbM10sIHtcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogdmFsdWUsXG4gICAgICAgICAgICAgICAgYWN0dWFsOiBvYmplY3Rba2V5XSxcbiAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIG5vdEhhc0xvb3NlKF8pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuLCBtYXgtcGFyYW1zXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKF8uaGFzKG9iamVjdCwga2V5KSAmJiB1dGlsLmxvb3NlSXMoXy5nZXQob2JqZWN0LCBrZXkpLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgIHV0aWwuZmFpbChfLm1lc3NhZ2VzWzJdLCB7XG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IHZhbHVlLFxuICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0W2tleV0sXG4gICAgICAgICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBoYXNPd25LZXkob2JqZWN0LCBrZXkpIHsgcmV0dXJuIGhhc093bi5jYWxsKG9iamVjdCwga2V5KSB9XG5mdW5jdGlvbiBoYXNJbktleShvYmplY3QsIGtleSkgeyByZXR1cm4ga2V5IGluIG9iamVjdCB9XG5mdW5jdGlvbiBoYXNJbkNvbGwob2JqZWN0LCBrZXkpIHsgcmV0dXJuIG9iamVjdC5oYXMoa2V5KSB9XG5mdW5jdGlvbiBoYXNPYmplY3RHZXQob2JqZWN0LCBrZXkpIHsgcmV0dXJuIG9iamVjdFtrZXldIH1cbmZ1bmN0aW9uIGhhc0NvbGxHZXQob2JqZWN0LCBrZXkpIHsgcmV0dXJuIG9iamVjdC5nZXQoa2V5KSB9XG5cbmZ1bmN0aW9uIGNyZWF0ZUhhcyhoYXMsIGdldCwgbWVzc2FnZXMpIHtcbiAgICByZXR1cm4ge2hhczogaGFzLCBnZXQ6IGdldCwgbWVzc2FnZXM6IG1lc3NhZ2VzfVxufVxuXG52YXIgaGFzT3duTWV0aG9kcyA9IGNyZWF0ZUhhcyhoYXNPd25LZXksIGhhc09iamVjdEdldCwgW1xuICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gaGF2ZSBvd24ga2V5IHtrZXl9IGVxdWFsIHRvIHtleHBlY3RlZH0sIGJ1dCBmb3VuZCB7YWN0dWFsfVwiLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW5cbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUgb3duIGtleSB7ZXhwZWN0ZWR9XCIsXG4gICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBub3QgaGF2ZSBvd24ga2V5IHtrZXl9IGVxdWFsIHRvIHthY3R1YWx9XCIsXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBvd24ga2V5IHtleHBlY3RlZH1cIixcbl0pXG5cbnZhciBoYXNLZXlNZXRob2RzID0gY3JlYXRlSGFzKGhhc0luS2V5LCBoYXNPYmplY3RHZXQsIFtcbiAgICBcIkV4cGVjdGVkIHtvYmplY3R9IHRvIGhhdmUga2V5IHtrZXl9IGVxdWFsIHRvIHtleHBlY3RlZH0sIGJ1dCBmb3VuZCB7YWN0dWFsfVwiLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW5cbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUga2V5IHtleHBlY3RlZH1cIixcbiAgICBcIkV4cGVjdGVkIHtvYmplY3R9IHRvIG5vdCBoYXZlIGtleSB7a2V5fSBlcXVhbCB0byB7YWN0dWFsfVwiLFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUga2V5IHtleHBlY3RlZH1cIixcbl0pXG5cbnZhciBoYXNNZXRob2RzID0gY3JlYXRlSGFzKGhhc0luQ29sbCwgaGFzQ29sbEdldCwgW1xuICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gaGF2ZSBrZXkge2tleX0gZXF1YWwgdG8ge2V4cGVjdGVkfSwgYnV0IGZvdW5kIHthY3R1YWx9XCIsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBrZXkge2V4cGVjdGVkfVwiLFxuICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gbm90IGhhdmUga2V5IHtrZXl9IGVxdWFsIHRvIHthY3R1YWx9XCIsXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBrZXkge2V4cGVjdGVkfVwiLFxuXSlcblxuZXhwb3J0cy5oYXNPd24gPSBoYXMoaGFzT3duTWV0aG9kcylcbmV4cG9ydHMubm90SGFzT3duID0gbm90SGFzKGhhc093bk1ldGhvZHMpXG5leHBvcnRzLmhhc093bkxvb3NlID0gaGFzTG9vc2UoaGFzT3duTWV0aG9kcylcbmV4cG9ydHMubm90SGFzT3duTG9vc2UgPSBub3RIYXNMb29zZShoYXNPd25NZXRob2RzKVxuXG5leHBvcnRzLmhhc0tleSA9IGhhcyhoYXNLZXlNZXRob2RzKVxuZXhwb3J0cy5ub3RIYXNLZXkgPSBub3RIYXMoaGFzS2V5TWV0aG9kcylcbmV4cG9ydHMuaGFzS2V5TG9vc2UgPSBoYXNMb29zZShoYXNLZXlNZXRob2RzKVxuZXhwb3J0cy5ub3RIYXNLZXlMb29zZSA9IG5vdEhhc0xvb3NlKGhhc0tleU1ldGhvZHMpXG5cbmV4cG9ydHMuaGFzID0gaGFzKGhhc01ldGhvZHMpXG5leHBvcnRzLm5vdEhhcyA9IG5vdEhhcyhoYXNNZXRob2RzKVxuZXhwb3J0cy5oYXNMb29zZSA9IGhhc0xvb3NlKGhhc01ldGhvZHMpXG5leHBvcnRzLm5vdEhhc0xvb3NlID0gbm90SGFzTG9vc2UoaGFzTWV0aG9kcylcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBtYXRjaCA9IHJlcXVpcmUoXCJjbGVhbi1tYXRjaFwiKVxudmFyIHV0aWwgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0LXV0aWxcIilcblxuZnVuY3Rpb24gaW5jbHVkZXMoZnVuYywgYWxsLCBhcnJheSwgdmFsdWVzKSB7XG4gICAgLy8gQ2hlYXAgY2FzZXMgZmlyc3RcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyYXkpKSByZXR1cm4gZmFsc2VcbiAgICBpZiAoYXJyYXkgPT09IHZhbHVlcykgcmV0dXJuIHRydWVcbiAgICBpZiAoYWxsICYmIGFycmF5Lmxlbmd0aCA8IHZhbHVlcy5sZW5ndGgpIHJldHVybiBmYWxzZVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHZhbHVlID0gdmFsdWVzW2ldXG4gICAgICAgIHZhciB0ZXN0ID0gZmFsc2VcblxuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGFycmF5Lmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBpZiAoZnVuYyh2YWx1ZSwgYXJyYXlbal0pKSB7XG4gICAgICAgICAgICAgICAgdGVzdCA9IHRydWVcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRlc3QgIT09IGFsbCkgcmV0dXJuIHRlc3RcbiAgICB9XG5cbiAgICByZXR1cm4gYWxsXG59XG5cbmZ1bmN0aW9uIGRlZmluZUluY2x1ZGVzKGZ1bmMsIGFsbCwgaW52ZXJ0LCBtZXNzYWdlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChhcnJheSwgdmFsdWVzKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcnJheSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgYXJyYXlgIG11c3QgYmUgYW4gYXJyYXlcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZXMpKSB2YWx1ZXMgPSBbdmFsdWVzXVxuXG4gICAgICAgIGlmICh2YWx1ZXMubGVuZ3RoICYmIGluY2x1ZGVzKGZ1bmMsIGFsbCwgYXJyYXksIHZhbHVlcykgPT09IGludmVydCkge1xuICAgICAgICAgICAgdXRpbC5mYWlsKG1lc3NhZ2UsIHthY3R1YWw6IGFycmF5LCB2YWx1ZXM6IHZhbHVlc30pXG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxuZXhwb3J0cy5pbmNsdWRlcyA9IGRlZmluZUluY2x1ZGVzKHV0aWwuc3RyaWN0SXMsIHRydWUsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUgYWxsIHZhbHVlcyBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5pbmNsdWRlc0RlZXAgPSBkZWZpbmVJbmNsdWRlcyhtYXRjaC5zdHJpY3QsIHRydWUsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFsbCB2YWx1ZXMgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMuaW5jbHVkZXNNYXRjaCA9IGRlZmluZUluY2x1ZGVzKG1hdGNoLmxvb3NlLCB0cnVlLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBtYXRjaCBhbGwgdmFsdWVzIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLmluY2x1ZGVzQW55ID0gZGVmaW5lSW5jbHVkZXModXRpbC5zdHJpY3RJcywgZmFsc2UsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUgYW55IHZhbHVlIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLmluY2x1ZGVzQW55RGVlcCA9IGRlZmluZUluY2x1ZGVzKG1hdGNoLnN0cmljdCwgZmFsc2UsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFueSB2YWx1ZSBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5pbmNsdWRlc0FueU1hdGNoID0gZGVmaW5lSW5jbHVkZXMobWF0Y2gubG9vc2UsIGZhbHNlLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBtYXRjaCBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMubm90SW5jbHVkZXNBbGwgPSBkZWZpbmVJbmNsdWRlcyh1dGlsLnN0cmljdElzLCB0cnVlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGFsbCB2YWx1ZXMgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMubm90SW5jbHVkZXNBbGxEZWVwID0gZGVmaW5lSW5jbHVkZXMobWF0Y2guc3RyaWN0LCB0cnVlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbGwgdmFsdWVzIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLm5vdEluY2x1ZGVzQWxsTWF0Y2ggPSBkZWZpbmVJbmNsdWRlcyhtYXRjaC5sb29zZSwgdHJ1ZSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgbWF0Y2ggYWxsIHZhbHVlcyBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5ub3RJbmNsdWRlcyA9IGRlZmluZUluY2x1ZGVzKHV0aWwuc3RyaWN0SXMsIGZhbHNlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGFueSB2YWx1ZSBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5ub3RJbmNsdWRlc0RlZXAgPSBkZWZpbmVJbmNsdWRlcyhtYXRjaC5zdHJpY3QsIGZhbHNlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMubm90SW5jbHVkZXNNYXRjaCA9IGRlZmluZUluY2x1ZGVzKG1hdGNoLmxvb3NlLCBmYWxzZSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgbWF0Y2ggYW55IHZhbHVlIGluIHt2YWx1ZXN9XCIpXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKVxuXG5mdW5jdGlvbiBnZXROYW1lKGZ1bmMpIHtcbiAgICB2YXIgbmFtZSA9IGZ1bmMubmFtZVxuXG4gICAgaWYgKG5hbWUgPT0gbnVsbCkgbmFtZSA9IGZ1bmMuZGlzcGxheU5hbWVcbiAgICBpZiAobmFtZSkgcmV0dXJuIHV0aWwuZXNjYXBlKG5hbWUpXG4gICAgcmV0dXJuIFwiPGFub255bW91cz5cIlxufVxuXG5leHBvcnRzLnRocm93cyA9IGZ1bmN0aW9uIChUeXBlLCBjYWxsYmFjaykge1xuICAgIGlmIChjYWxsYmFjayA9PSBudWxsKSB7XG4gICAgICAgIGNhbGxiYWNrID0gVHlwZVxuICAgICAgICBUeXBlID0gbnVsbFxuICAgIH1cblxuICAgIGlmIChUeXBlICE9IG51bGwgJiYgdHlwZW9mIFR5cGUgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYFR5cGVgIG11c3QgYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBjYWxsYmFja2AgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgY2FsbGJhY2soKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGNhbGxiYWNrLXJldHVyblxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKFR5cGUgIT0gbnVsbCAmJiAhKGUgaW5zdGFuY2VvZiBUeXBlKSkge1xuICAgICAgICAgICAgdXRpbC5mYWlsKFxuICAgICAgICAgICAgICAgIFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gdGhyb3cgYW4gaW5zdGFuY2Ugb2YgXCIgKyBnZXROYW1lKFR5cGUpICtcbiAgICAgICAgICAgICAgICBcIiwgYnV0IGZvdW5kIHthY3R1YWx9XCIsXG4gICAgICAgICAgICAgICAge2FjdHVhbDogZX0pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IHV0aWwuQXNzZXJ0aW9uRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byB0aHJvd1wiKVxufVxuXG5mdW5jdGlvbiB0aHJvd3NNYXRjaFRlc3QobWF0Y2hlciwgZSkge1xuICAgIGlmICh0eXBlb2YgbWF0Y2hlciA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIGUubWVzc2FnZSA9PT0gbWF0Y2hlclxuICAgIGlmICh0eXBlb2YgbWF0Y2hlciA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gISFtYXRjaGVyKGUpXG4gICAgaWYgKG1hdGNoZXIgaW5zdGFuY2VvZiBSZWdFeHApIHJldHVybiAhIW1hdGNoZXIudGVzdChlLm1lc3NhZ2UpXG5cbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG1hdGNoZXIpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXNbaV1cblxuICAgICAgICBpZiAoIShrZXkgaW4gZSkgfHwgIXV0aWwuc3RyaWN0SXMobWF0Y2hlcltrZXldLCBlW2tleV0pKSByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZVxufVxuXG5mdW5jdGlvbiBpc1BsYWluT2JqZWN0KG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KSA9PT0gT2JqZWN0LnByb3RvdHlwZVxufVxuXG5leHBvcnRzLnRocm93c01hdGNoID0gZnVuY3Rpb24gKG1hdGNoZXIsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBtYXRjaGVyICE9PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICB0eXBlb2YgbWF0Y2hlciAhPT0gXCJmdW5jdGlvblwiICYmXG4gICAgICAgICAgICAhKG1hdGNoZXIgaW5zdGFuY2VvZiBSZWdFeHApICYmXG4gICAgICAgICAgICAhaXNQbGFpbk9iamVjdChtYXRjaGVyKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgXCJgbWF0Y2hlcmAgbXVzdCBiZSBhIHN0cmluZywgZnVuY3Rpb24sIFJlZ0V4cCwgb3Igb2JqZWN0XCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgY2FsbGJhY2tgIG11c3QgYmUgYSBmdW5jdGlvblwiKVxuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAgIGNhbGxiYWNrKCkgLy8gZXNsaW50LWRpc2FibGUtbGluZSBjYWxsYmFjay1yZXR1cm5cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmICghdGhyb3dzTWF0Y2hUZXN0KG1hdGNoZXIsIGUpKSB7XG4gICAgICAgICAgICB1dGlsLmZhaWwoXG4gICAgICAgICAgICAgICAgXCJFeHBlY3RlZCBjYWxsYmFjayB0byAgdGhyb3cgYW4gZXJyb3IgdGhhdCBtYXRjaGVzIFwiICtcbiAgICAgICAgICAgICAgICBcIntleHBlY3RlZH0sIGJ1dCBmb3VuZCB7YWN0dWFsfVwiLFxuICAgICAgICAgICAgICAgIHtleHBlY3RlZDogbWF0Y2hlciwgYWN0dWFsOiBlfSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgdXRpbC5Bc3NlcnRpb25FcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIHRocm93LlwiKVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIHV0aWwgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0LXV0aWxcIilcblxuZXhwb3J0cy5vayA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKCF4KSB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSB0cnV0aHlcIiwge2FjdHVhbDogeH0pXG59XG5cbmV4cG9ydHMubm90T2sgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh4KSB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBmYWxzeVwiLCB7YWN0dWFsOiB4fSlcbn1cblxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCAhPT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYSBib29sZWFuXCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5ub3RCb29sZWFuID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBhIGJvb2xlYW5cIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLmlzRnVuY3Rpb24gPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGEgZnVuY3Rpb25cIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdEZ1bmN0aW9uID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgYmUgYSBmdW5jdGlvblwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMuaXNOdW1iZXIgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhIG51bWJlclwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90TnVtYmVyID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGJlIGEgbnVtYmVyXCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5pc09iamVjdCA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSBcIm9iamVjdFwiIHx8IHggPT0gbnVsbCkge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhbiBvYmplY3RcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdE9iamVjdCA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ID09PSBcIm9iamVjdFwiICYmIHggIT0gbnVsbCkge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgYmUgYW4gb2JqZWN0XCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5pc1N0cmluZyA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGEgc3RyaW5nXCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5ub3RTdHJpbmcgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgYmUgYSBzdHJpbmdcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLmlzU3ltYm9sID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggIT09IFwic3ltYm9sXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYSBzeW1ib2xcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdFN5bWJvbCA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ID09PSBcInN5bWJvbFwiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBhIHN5bWJvbFwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMuZXhpc3RzID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAoeCA9PSBudWxsKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGV4aXN0XCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5ub3RFeGlzdHMgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh4ICE9IG51bGwpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGV4aXN0XCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5pc0FycmF5ID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoeCkpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYW4gYXJyYXlcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdEFycmF5ID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh4KSkge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgYmUgYW4gYXJyYXlcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLmlzID0gZnVuY3Rpb24gKFR5cGUsIG9iamVjdCkge1xuICAgIGlmICh0eXBlb2YgVHlwZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgVHlwZWAgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgfVxuXG4gICAgaWYgKCEob2JqZWN0IGluc3RhbmNlb2YgVHlwZSkpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge29iamVjdH0gdG8gYmUgYW4gaW5zdGFuY2Ugb2Yge2V4cGVjdGVkfVwiLCB7XG4gICAgICAgICAgICBleHBlY3RlZDogVHlwZSxcbiAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgIH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdCA9IGZ1bmN0aW9uIChUeXBlLCBvYmplY3QpIHtcbiAgICBpZiAodHlwZW9mIFR5cGUgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYFR5cGVgIG11c3QgYmUgYSBmdW5jdGlvblwiKVxuICAgIH1cblxuICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBUeXBlKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHtvYmplY3R9IHRvIG5vdCBiZSBhbiBpbnN0YW5jZSBvZiB7ZXhwZWN0ZWR9XCIsIHtcbiAgICAgICAgICAgIGV4cGVjdGVkOiBUeXBlLFxuICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgIH0pXG4gICAgfVxufVxuIiwiLyoqXG4gKiBAbGljZW5zZVxuICogY2xlYW4tbWF0Y2hcbiAqXG4gKiBBIHNpbXBsZSwgZmFzdCBFUzIwMTUrIGF3YXJlIGRlZXAgbWF0Y2hpbmcgdXRpbGl0eS5cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYgYW5kIGxhdGVyLCBJc2lhaCBNZWFkb3dzIDxtZUBpc2lhaG1lYWRvd3MuY29tPi5cbiAqXG4gKiBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcbiAqIHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmVcbiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxuICogUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXG4gKiBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXG4gKiBJTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cbiAqIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXG4gKiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXG4gKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxuICovXG5cbi8qIGVzbGludC1kaXNhYmxlICovXG47KGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICBpZiAodHlwZW9mIGV4cG9ydHMgPT09IFwib2JqZWN0XCIgJiYgZXhwb3J0cyAhPSBudWxsKSB7XG4gICAgICAgIGZhY3RvcnkoZ2xvYmFsLCBleHBvcnRzKVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGRlZmluZShcImNsZWFuLW1hdGNoXCIsIFtcImV4cG9ydHNcIl0sIGZ1bmN0aW9uIChleHBvcnRzKSB7XG4gICAgICAgICAgICBmYWN0b3J5KGdsb2JhbCwgZXhwb3J0cylcbiAgICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgICBmYWN0b3J5KGdsb2JhbCwgZ2xvYmFsLm1hdGNoID0ge30pXG4gICAgfVxufSkodHlwZW9mIGdsb2JhbCA9PT0gXCJvYmplY3RcIiAmJiBnbG9iYWwgIT09IG51bGwgPyBnbG9iYWxcbiAgICA6IHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiICYmIHNlbGYgIT09IG51bGwgPyBzZWxmXG4gICAgOiB0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiICYmIHdpbmRvdyAhPT0gbnVsbCA/IHdpbmRvd1xuICAgIDogdGhpcyxcbmZ1bmN0aW9uIChnbG9iYWwsIGV4cG9ydHMpIHtcbiAgICAvKiBlc2xpbnQtZW5hYmxlICovXG4gICAgXCJ1c2Ugc3RyaWN0XCJcblxuICAgIC8qIGdsb2JhbCBTeW1ib2wsIFVpbnQ4QXJyYXksIERhdGFWaWV3LCBBcnJheUJ1ZmZlciwgQXJyYXlCdWZmZXJWaWV3LCBNYXAsXG4gICAgU2V0ICovXG5cbiAgICAvKipcbiAgICAgKiBEZWVwIG1hdGNoaW5nIGFsZ29yaXRobSwgd2l0aCB6ZXJvIGRlcGVuZGVuY2llcy4gTm90ZSB0aGUgZm9sbG93aW5nOlxuICAgICAqXG4gICAgICogLSBUaGlzIGlzIHJlbGF0aXZlbHkgcGVyZm9ybWFuY2UtdHVuZWQsIGFsdGhvdWdoIGl0IHByZWZlcnMgaGlnaFxuICAgICAqICAgY29ycmVjdG5lc3MuIFBhdGNoIHdpdGggY2FyZSwgc2luY2UgcGVyZm9ybWFuY2UgaXMgYSBjb25jZXJuLlxuICAgICAqIC0gVGhpcyBkb2VzIHBhY2sgYSAqbG90KiBvZiBmZWF0dXJlcywgd2hpY2ggc2hvdWxkIGV4cGxhaW4gdGhlIGxlbmd0aC5cbiAgICAgKiAtIFNvbWUgb2YgdGhlIGR1cGxpY2F0aW9uIGlzIGludGVudGlvbmFsLiBJdCdzIGdlbmVyYWxseSBjb21tZW50ZWQsIGJ1dFxuICAgICAqICAgaXQncyBtYWlubHkgZm9yIHBlcmZvcm1hbmNlLCBzaW5jZSB0aGUgZW5naW5lIG5lZWRzIGl0cyB0eXBlIGluZm8uXG4gICAgICogLSBQb2x5ZmlsbGVkIGNvcmUtanMgU3ltYm9scyBmcm9tIGNyb3NzLW9yaWdpbiBjb250ZXh0cyB3aWxsIG5ldmVyXG4gICAgICogICByZWdpc3RlciBhcyBiZWluZyBhY3R1YWwgU3ltYm9scy5cbiAgICAgKlxuICAgICAqIEFuZCBpbiBjYXNlIHlvdSdyZSB3b25kZXJpbmcgYWJvdXQgdGhlIGxvbmdlciBmdW5jdGlvbnMgYW5kIG9jY2FzaW9uYWxcbiAgICAgKiByZXBldGl0aW9uLCBpdCdzIGJlY2F1c2UgVjgncyBpbmxpbmVyIGlzbid0IGFsd2F5cyBpbnRlbGxpZ2VudCBlbm91Z2ggdG9cbiAgICAgKiBkZWFsIHdpdGggdGhlIHN1cGVyIGhpZ2hseSBwb2x5bW9ycGhpYyBkYXRhIHRoaXMgb2Z0ZW4gZGVhbHMgd2l0aCwgYW5kIEpTXG4gICAgICogZG9lc24ndCBoYXZlIGNvbXBpbGUtdGltZSBtYWNyb3MuXG4gICAgICovXG5cbiAgICB2YXIgb2JqZWN0VG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nXG4gICAgdmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuICAgIHZhciBzdXBwb3J0c1VuaWNvZGUgPSBoYXNPd24uY2FsbChSZWdFeHAucHJvdG90eXBlLCBcInVuaWNvZGVcIilcbiAgICB2YXIgc3VwcG9ydHNTdGlja3kgPSBoYXNPd24uY2FsbChSZWdFeHAucHJvdG90eXBlLCBcInN0aWNreVwiKVxuXG4gICAgLy8gTGVnYWN5IGVuZ2luZXMgaGF2ZSBzZXZlcmFsIGlzc3VlcyB3aGVuIGl0IGNvbWVzIHRvIGB0eXBlb2ZgLlxuICAgIHZhciBpc0Z1bmN0aW9uID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZnVuY3Rpb24gU2xvd0lzRnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSByZXR1cm4gZmFsc2VcblxuICAgICAgICAgICAgdmFyIHRhZyA9IG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpXG5cbiAgICAgICAgICAgIHJldHVybiB0YWcgPT09IFwiW29iamVjdCBGdW5jdGlvbl1cIiB8fFxuICAgICAgICAgICAgICAgIHRhZyA9PT0gXCJbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXVwiIHx8XG4gICAgICAgICAgICAgICAgdGFnID09PSBcIltvYmplY3QgQXN5bmNGdW5jdGlvbl1cIiB8fFxuICAgICAgICAgICAgICAgIHRhZyA9PT0gXCJbb2JqZWN0IFByb3h5XVwiXG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBpc1BvaXNvbmVkKG9iamVjdCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIHR5cGVvZiBvYmplY3QgIT09IFwiZnVuY3Rpb25cIlxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSW4gU2FmYXJpIDEwLCBgdHlwZW9mIFByb3h5ID09PSBcIm9iamVjdFwiYFxuICAgICAgICBpZiAoaXNQb2lzb25lZChnbG9iYWwuUHJveHkpKSByZXR1cm4gU2xvd0lzRnVuY3Rpb25cblxuICAgICAgICAvLyBJbiBTYWZhcmkgOCwgc2V2ZXJhbCB0eXBlZCBhcnJheSBjb25zdHJ1Y3RvcnMgYXJlXG4gICAgICAgIC8vIGB0eXBlb2YgQyA9PT0gXCJvYmplY3RcImBcbiAgICAgICAgaWYgKGlzUG9pc29uZWQoZ2xvYmFsLkludDhBcnJheSkpIHJldHVybiBTbG93SXNGdW5jdGlvblxuXG4gICAgICAgIC8vIEluIG9sZCBWOCwgUmVnRXhwcyBhcmUgY2FsbGFibGVcbiAgICAgICAgaWYgKHR5cGVvZiAveC8gPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFNsb3dJc0Z1bmN0aW9uIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuICAgICAgICAvLyBMZWF2ZSB0aGlzIGZvciBub3JtYWwgdGhpbmdzLiBJdCdzIGVhc2lseSBpbmxpbmVkLlxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgIH1cbiAgICB9KSgpXG5cbiAgICAvLyBTZXQgdXAgb3VyIG93biBidWZmZXIgY2hlY2suIFdlIHNob3VsZCBhbHdheXMgYWNjZXB0IHRoZSBwb2x5ZmlsbCwgZXZlblxuICAgIC8vIGluIE5vZGUuIE5vdGUgdGhhdCBpdCB1c2VzIGBnbG9iYWwuQnVmZmVyYCB0byBhdm9pZCBpbmNsdWRpbmcgYGJ1ZmZlcmAgaW5cbiAgICAvLyB0aGUgYnVuZGxlLlxuXG4gICAgdmFyIEJ1ZmZlck5hdGl2ZSA9IDBcbiAgICB2YXIgQnVmZmVyUG9seWZpbGwgPSAxXG4gICAgdmFyIEJ1ZmZlclNhZmFyaSA9IDJcblxuICAgIHZhciBidWZmZXJTdXBwb3J0ID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZnVuY3Rpb24gRmFrZUJ1ZmZlcigpIHt9XG4gICAgICAgIEZha2VCdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlIH1cblxuICAgICAgICAvLyBPbmx5IFNhZmFyaSA1LTcgaGFzIGV2ZXIgaGFkIHRoaXMgaXNzdWUuXG4gICAgICAgIGlmIChuZXcgRmFrZUJ1ZmZlcigpLmNvbnN0cnVjdG9yICE9PSBGYWtlQnVmZmVyKSByZXR1cm4gQnVmZmVyU2FmYXJpXG4gICAgICAgIGlmICghaXNGdW5jdGlvbihnbG9iYWwuQnVmZmVyKSkgcmV0dXJuIEJ1ZmZlclBvbHlmaWxsXG4gICAgICAgIGlmICghaXNGdW5jdGlvbihnbG9iYWwuQnVmZmVyLmlzQnVmZmVyKSkgcmV0dXJuIEJ1ZmZlclBvbHlmaWxsXG4gICAgICAgIC8vIEF2b2lkIGdsb2JhbCBwb2x5ZmlsbHNcbiAgICAgICAgaWYgKGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIobmV3IEZha2VCdWZmZXIoKSkpIHJldHVybiBCdWZmZXJQb2x5ZmlsbFxuICAgICAgICByZXR1cm4gQnVmZmVyTmF0aXZlXG4gICAgfSkoKVxuXG4gICAgdmFyIGdsb2JhbElzQnVmZmVyID0gYnVmZmVyU3VwcG9ydCA9PT0gQnVmZmVyTmF0aXZlXG4gICAgICAgID8gZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlclxuICAgICAgICA6IHVuZGVmaW5lZFxuXG4gICAgZnVuY3Rpb24gaXNCdWZmZXIob2JqZWN0KSB7XG4gICAgICAgIGlmIChidWZmZXJTdXBwb3J0ID09PSBCdWZmZXJOYXRpdmUgJiYgZ2xvYmFsSXNCdWZmZXIob2JqZWN0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSBlbHNlIGlmIChidWZmZXJTdXBwb3J0ID09PSBCdWZmZXJTYWZhcmkgJiYgb2JqZWN0Ll9pc0J1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBCID0gb2JqZWN0LmNvbnN0cnVjdG9yXG5cbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKEIpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKEIuaXNCdWZmZXIpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgcmV0dXJuIEIuaXNCdWZmZXIob2JqZWN0KVxuICAgIH1cblxuICAgIC8vIGNvcmUtanMnIHN5bWJvbHMgYXJlIG9iamVjdHMsIGFuZCBzb21lIG9sZCB2ZXJzaW9ucyBvZiBWOCBlcnJvbmVvdXNseSBoYWRcbiAgICAvLyBgdHlwZW9mIFN5bWJvbCgpID09PSBcIm9iamVjdFwiYC5cbiAgICB2YXIgc3ltYm9sc0FyZU9iamVjdHMgPSBpc0Z1bmN0aW9uKGdsb2JhbC5TeW1ib2wpICYmXG4gICAgICAgIHR5cGVvZiBTeW1ib2woKSA9PT0gXCJvYmplY3RcIlxuXG4gICAgLy8gYGNvbnRleHRgIGlzIGEgYml0IGZpZWxkLCB3aXRoIHRoZSBmb2xsb3dpbmcgYml0cy4gVGhpcyBpcyBub3QgYXMgbXVjaFxuICAgIC8vIGZvciBwZXJmb3JtYW5jZSB0aGFuIHRvIGp1c3QgcmVkdWNlIHRoZSBudW1iZXIgb2YgcGFyYW1ldGVycyBJIG5lZWQgdG8gYmVcbiAgICAvLyB0aHJvd2luZyBhcm91bmQuXG4gICAgdmFyIFN0cmljdCA9IDFcbiAgICB2YXIgSW5pdGlhbCA9IDJcbiAgICB2YXIgU2FtZVByb3RvID0gNFxuXG4gICAgZXhwb3J0cy5sb29zZSA9IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBtYXRjaChhLCBiLCBJbml0aWFsLCB1bmRlZmluZWQsIHVuZGVmaW5lZClcbiAgICB9XG5cbiAgICBleHBvcnRzLnN0cmljdCA9IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBtYXRjaChhLCBiLCBTdHJpY3QgfCBJbml0aWFsLCB1bmRlZmluZWQsIHVuZGVmaW5lZClcbiAgICB9XG5cbiAgICAvLyBGZWF0dXJlLXRlc3QgZGVsYXllZCBzdGFjayBhZGRpdGlvbnMgYW5kIGV4dHJhIGtleXMuIFBoYW50b21KUyBhbmQgSUVcbiAgICAvLyBib3RoIHdhaXQgdW50aWwgdGhlIGVycm9yIHdhcyBhY3R1YWxseSB0aHJvd24gZmlyc3QsIGFuZCBhc3NpZ24gdGhlbSBhc1xuICAgIC8vIG93biBwcm9wZXJ0aWVzLCB3aGljaCBpcyB1bmhlbHBmdWwgZm9yIGFzc2VydGlvbnMuIFRoaXMgcmV0dXJucyBhXG4gICAgLy8gZnVuY3Rpb24gdG8gc3BlZWQgdXAgY2FzZXMgd2hlcmUgYE9iamVjdC5rZXlzYCBpcyBzdWZmaWNpZW50IChlLmcuIGluXG4gICAgLy8gQ2hyb21lL0ZGL05vZGUpLlxuICAgIC8vXG4gICAgLy8gVGhpcyB3b3VsZG4ndCBiZSBuZWNlc3NhcnkgaWYgdGhvc2UgZW5naW5lcyB3b3VsZCBtYWtlIHRoZSBzdGFjayBhXG4gICAgLy8gZ2V0dGVyLCBhbmQgcmVjb3JkIGl0IHdoZW4gdGhlIGVycm9yIHdhcyBjcmVhdGVkLCBub3Qgd2hlbiBpdCB3YXMgdGhyb3duLlxuICAgIC8vIEl0IHNwZWNpZmljYWxseSBmaWx0ZXJzIG91dCBlcnJvcnMgYW5kIG9ubHkgY2hlY2tzIGV4aXN0aW5nIGRlc2NyaXB0b3JzLFxuICAgIC8vIGp1c3QgdG8ga2VlcCB0aGUgbWVzcyBmcm9tIGFmZmVjdGluZyBldmVyeXRoaW5nIChpdCdzIG5vdCBmdWxseSBjb3JyZWN0LFxuICAgIC8vIGJ1dCBpdCdzIG5lY2Vzc2FyeSkuXG4gICAgdmFyIHJlcXVpcmVzUHJveHkgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdGVzdCA9IG5ldyBFcnJvcigpXG4gICAgICAgIHZhciBvbGQgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgICAgICAgT2JqZWN0LmtleXModGVzdCkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7IG9sZFtrZXldID0gdHJ1ZSB9KVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aHJvdyB0ZXN0XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICAgIC8vIGlnbm9yZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRlc3QpLnNvbWUoZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gIW9sZFtrZXldIH0pXG4gICAgfSkoKVxuXG4gICAgZnVuY3Rpb24gaXNJZ25vcmVkKG9iamVjdCwga2V5KSB7XG4gICAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgIGNhc2UgXCJsaW5lXCI6IGlmICh0eXBlb2Ygb2JqZWN0LmxpbmUgIT09IFwibnVtYmVyXCIpIHJldHVybiBmYWxzZTsgYnJlYWtcbiAgICAgICAgY2FzZSBcInNvdXJjZVVSTFwiOlxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmplY3Quc291cmNlVVJMICE9PSBcInN0cmluZ1wiKSByZXR1cm4gZmFsc2U7IGJyZWFrXG4gICAgICAgIGNhc2UgXCJzdGFja1wiOiBpZiAodHlwZW9mIG9iamVjdC5zdGFjayAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIGZhbHNlOyBicmVha1xuICAgICAgICBkZWZhdWx0OiByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmplY3QsIGtleSlcblxuICAgICAgICByZXR1cm4gIWRlc2MuY29uZmlndXJhYmxlICYmIGRlc2MuZW51bWVyYWJsZSAmJiAhZGVzYy53cml0YWJsZVxuICAgIH1cblxuICAgIC8vIFRoaXMgaXMgb25seSBpbnZva2VkIHdpdGggZXJyb3JzLCBzbyBpdCdzIG5vdCBnb2luZyB0byBwcmVzZW50IGFcbiAgICAvLyBzaWduaWZpY2FudCBzbG93IGRvd24uXG4gICAgZnVuY3Rpb24gZ2V0S2V5c1N0cmlwcGVkKG9iamVjdCkge1xuICAgICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iamVjdClcbiAgICAgICAgdmFyIGNvdW50ID0gMFxuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKCFpc0lnbm9yZWQob2JqZWN0LCBrZXlzW2ldKSkga2V5c1tjb3VudCsrXSA9IGtleXNbaV1cbiAgICAgICAgfVxuXG4gICAgICAgIGtleXMubGVuZ3RoID0gY291bnRcbiAgICAgICAgcmV0dXJuIGtleXNcbiAgICB9XG5cbiAgICAvLyBXYXkgZmFzdGVyLCBzaW5jZSB0eXBlZCBhcnJheSBpbmRpY2VzIGFyZSBhbHdheXMgZGVuc2UgYW5kIGNvbnRhaW5cbiAgICAvLyBudW1iZXJzLlxuXG4gICAgLy8gU2V0dXAgZm9yIGBpc0J1ZmZlck9yVmlld2AgYW5kIGBpc1ZpZXdgXG4gICAgdmFyIEFycmF5QnVmZmVyTm9uZSA9IDBcbiAgICB2YXIgQXJyYXlCdWZmZXJMZWdhY3kgPSAxXG4gICAgdmFyIEFycmF5QnVmZmVyQ3VycmVudCA9IDJcblxuICAgIHZhciBhcnJheUJ1ZmZlclN1cHBvcnQgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWlzRnVuY3Rpb24oZ2xvYmFsLlVpbnQ4QXJyYXkpKSByZXR1cm4gQXJyYXlCdWZmZXJOb25lXG4gICAgICAgIGlmICghaXNGdW5jdGlvbihnbG9iYWwuRGF0YVZpZXcpKSByZXR1cm4gQXJyYXlCdWZmZXJOb25lXG4gICAgICAgIGlmICghaXNGdW5jdGlvbihnbG9iYWwuQXJyYXlCdWZmZXIpKSByZXR1cm4gQXJyYXlCdWZmZXJOb25lXG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKGdsb2JhbC5BcnJheUJ1ZmZlci5pc1ZpZXcpKSByZXR1cm4gQXJyYXlCdWZmZXJDdXJyZW50XG4gICAgICAgIGlmIChpc0Z1bmN0aW9uKGdsb2JhbC5BcnJheUJ1ZmZlclZpZXcpKSByZXR1cm4gQXJyYXlCdWZmZXJMZWdhY3lcbiAgICAgICAgcmV0dXJuIEFycmF5QnVmZmVyTm9uZVxuICAgIH0pKClcblxuICAgIC8vIElmIHR5cGVkIGFycmF5cyBhcmVuJ3Qgc3VwcG9ydGVkICh0aGV5IHdlcmVuJ3QgdGVjaG5pY2FsbHkgcGFydCBvZlxuICAgIC8vIEVTNSwgYnV0IG1hbnkgZW5naW5lcyBpbXBsZW1lbnRlZCBLaHJvbm9zJyBzcGVjIGJlZm9yZSBFUzYpLCB0aGVuXG4gICAgLy8ganVzdCBmYWxsIGJhY2sgdG8gZ2VuZXJpYyBidWZmZXIgZGV0ZWN0aW9uLlxuXG4gICAgZnVuY3Rpb24gZmxvYXRJcyhhLCBiKSB7XG4gICAgICAgIC8vIFNvIE5hTnMgYXJlIGNvbnNpZGVyZWQgZXF1YWwuXG4gICAgICAgIHJldHVybiBhID09PSBiIHx8IGEgIT09IGEgJiYgYiAhPT0gYiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZSwgbWF4LWxlblxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoVmlldyhhLCBiKSB7XG4gICAgICAgIHZhciBjb3VudCA9IGEubGVuZ3RoXG5cbiAgICAgICAgaWYgKGNvdW50ICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG5cbiAgICAgICAgd2hpbGUgKGNvdW50KSB7XG4gICAgICAgICAgICBjb3VudC0tXG4gICAgICAgICAgICBpZiAoIWZsb2F0SXMoYVtjb3VudF0sIGJbY291bnRdKSkgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHZhciBpc1ZpZXcgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoYXJyYXlCdWZmZXJTdXBwb3J0ID09PSBBcnJheUJ1ZmZlck5vbmUpIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgLy8gRVM2IHR5cGVkIGFycmF5c1xuICAgICAgICBpZiAoYXJyYXlCdWZmZXJTdXBwb3J0ID09PSBBcnJheUJ1ZmZlckN1cnJlbnQpIHJldHVybiBBcnJheUJ1ZmZlci5pc1ZpZXdcbiAgICAgICAgLy8gbGVnYWN5IHR5cGVkIGFycmF5c1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gaXNWaWV3KG9iamVjdCkge1xuICAgICAgICAgICAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyVmlld1xuICAgICAgICB9XG4gICAgfSkoKVxuXG4gICAgLy8gU3VwcG9ydCBjaGVja2luZyBtYXBzIGFuZCBzZXRzIGRlZXBseS4gVGhleSBhcmUgb2JqZWN0LWxpa2UgZW5vdWdoIHRvXG4gICAgLy8gY291bnQsIGFuZCBhcmUgdXNlZnVsIGluIHRoZWlyIG93biByaWdodC4gVGhlIGNvZGUgaXMgcmF0aGVyIG1lc3N5LCBidXRcbiAgICAvLyBtYWlubHkgdG8ga2VlcCB0aGUgb3JkZXItaW5kZXBlbmRlbnQgY2hlY2tpbmcgZnJvbSBiZWNvbWluZyBpbnNhbmVseVxuICAgIC8vIHNsb3cuXG4gICAgdmFyIHN1cHBvcnRzTWFwID0gaXNGdW5jdGlvbihnbG9iYWwuTWFwKVxuICAgIHZhciBzdXBwb3J0c1NldCA9IGlzRnVuY3Rpb24oZ2xvYmFsLlNldClcblxuICAgIC8vIE9uZSBvZiB0aGUgc2V0cyBhbmQgYm90aCBtYXBzJyBrZXlzIGFyZSBjb252ZXJ0ZWQgdG8gYXJyYXlzIGZvciBmYXN0ZXJcbiAgICAvLyBoYW5kbGluZy5cbiAgICBmdW5jdGlvbiBrZXlMaXN0KG1hcCkge1xuICAgICAgICB2YXIgbGlzdCA9IG5ldyBBcnJheShtYXAuc2l6ZSlcbiAgICAgICAgdmFyIGkgPSAwXG4gICAgICAgIHZhciBpdGVyID0gbWFwLmtleXMoKVxuXG4gICAgICAgIGZvciAodmFyIG5leHQgPSBpdGVyLm5leHQoKTsgIW5leHQuZG9uZTsgbmV4dCA9IGl0ZXIubmV4dCgpKSB7XG4gICAgICAgICAgICBsaXN0W2krK10gPSBuZXh0LnZhbHVlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbGlzdFxuICAgIH1cblxuICAgIC8vIFRoZSBwYWlyIG9mIGFycmF5cyBhcmUgYWxpZ25lZCBpbiBhIHNpbmdsZSBPKG5eMikgb3BlcmF0aW9uIChtb2QgZGVlcFxuICAgIC8vIG1hdGNoaW5nIGFuZCByb3RhdGlvbiksIGFkYXB0aW5nIHRvIE8obikgd2hlbiB0aGV5J3JlIGFscmVhZHkgYWxpZ25lZC5cbiAgICBmdW5jdGlvbiBtYXRjaEtleShjdXJyZW50LCBha2V5cywgc3RhcnQsIGVuZCwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIGZvciAodmFyIGkgPSBzdGFydCArIDE7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgICAgICAgdmFyIGtleSA9IGFrZXlzW2ldXG5cbiAgICAgICAgICAgIGlmIChtYXRjaChjdXJyZW50LCBrZXksIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgICAgIC8vIFRPRE86IG9uY2UgZW5naW5lcyBhY3R1YWxseSBvcHRpbWl6ZSBgY29weVdpdGhpbmAsIHVzZSB0aGF0XG4gICAgICAgICAgICAgICAgLy8gaW5zdGVhZC4gSXQnbGwgYmUgbXVjaCBmYXN0ZXIgdGhhbiB0aGlzIGxvb3AuXG4gICAgICAgICAgICAgICAgd2hpbGUgKGkgPiBzdGFydCkgYWtleXNbaV0gPSBha2V5c1stLWldXG4gICAgICAgICAgICAgICAgYWtleXNbaV0gPSBrZXlcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF0Y2hWYWx1ZXMoYSwgYiwgYWtleXMsIGJrZXlzLCBlbmQsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIW1hdGNoKGEuZ2V0KGFrZXlzW2ldKSwgYi5nZXQoYmtleXNbaV0pLFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LCBsZWZ0LCByaWdodCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgLy8gUG9zc2libHkgZXhwZW5zaXZlIG9yZGVyLWluZGVwZW5kZW50IGtleS12YWx1ZSBtYXRjaC4gRmlyc3QsIHRyeSB0byBhdm9pZFxuICAgIC8vIGl0IGJ5IGNvbnNlcnZhdGl2ZWx5IGFzc3VtaW5nIGV2ZXJ5dGhpbmcgaXMgaW4gb3JkZXIgLSBhIGNoZWFwIE8obikgaXNcbiAgICAvLyBhbHdheXMgbmljZXIgdGhhbiBhbiBleHBlbnNpdmUgTyhuXjIpLlxuICAgIGZ1bmN0aW9uIG1hdGNoTWFwKGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICB2YXIgZW5kID0gYS5zaXplXG4gICAgICAgIHZhciBha2V5cyA9IGtleUxpc3QoYSlcbiAgICAgICAgdmFyIGJrZXlzID0ga2V5TGlzdChiKVxuICAgICAgICB2YXIgaSA9IDBcblxuICAgICAgICB3aGlsZSAoaSAhPT0gZW5kICYmIG1hdGNoKGFrZXlzW2ldLCBia2V5c1tpXSwgY29udGV4dCwgbGVmdCwgcmlnaHQpKSB7XG4gICAgICAgICAgICBpKytcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpID09PSBlbmQpIHtcbiAgICAgICAgICAgIHJldHVybiBtYXRjaFZhbHVlcyhhLCBiLCBha2V5cywgYmtleXMsIGVuZCwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBEb24ndCBjb21wYXJlIHRoZSBzYW1lIGtleSB0d2ljZVxuICAgICAgICBpZiAoIW1hdGNoS2V5KGJrZXlzW2ldLCBha2V5cywgaSwgZW5kLCBjb250ZXh0LCBsZWZ0LCByaWdodCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhlIGFib3ZlIGZhaWxzLCB3aGlsZSB3ZSdyZSBhdCBpdCwgbGV0J3Mgc29ydCB0aGVtIGFzIHdlIGdvLCBzb1xuICAgICAgICAvLyB0aGUga2V5IG9yZGVyIG1hdGNoZXMuXG4gICAgICAgIHdoaWxlICgrK2kgPCBlbmQpIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBia2V5c1tpXVxuXG4gICAgICAgICAgICAvLyBBZGFwdCBpZiB0aGUga2V5cyBhcmUgYWxyZWFkeSBpbiBvcmRlciwgd2hpY2ggaXMgZnJlcXVlbnRseSB0aGVcbiAgICAgICAgICAgIC8vIGNhc2UuXG4gICAgICAgICAgICBpZiAoIW1hdGNoKGtleSwgYWtleXNbaV0sIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSAmJlxuICAgICAgICAgICAgICAgICAgICAhbWF0Y2hLZXkoa2V5LCBha2V5cywgaSwgZW5kLCBjb250ZXh0LCBsZWZ0LCByaWdodCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtYXRjaFZhbHVlcyhhLCBiLCBha2V5cywgYmtleXMsIGVuZCwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzQWxsSWRlbnRpY2FsKGFsaXN0LCBiKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYWxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghYi5oYXMoYWxpc3RbaV0pKSByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgLy8gQ29tcGFyZSB0aGUgdmFsdWVzIHN0cnVjdHVyYWxseSwgYW5kIGluZGVwZW5kZW50IG9mIG9yZGVyLlxuICAgIGZ1bmN0aW9uIHNlYXJjaEZvcihhdmFsdWUsIG9iamVjdHMsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICBmb3IgKHZhciBqIGluIG9iamVjdHMpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd24uY2FsbChvYmplY3RzLCBqKSkge1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaChhdmFsdWUsIG9iamVjdHNbal0sIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgb2JqZWN0c1tqXVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhc1N0cnVjdHVyZSh2YWx1ZSwgY29udGV4dCkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHZhbHVlICE9PSBudWxsIHx8XG4gICAgICAgICAgICAgICAgIShjb250ZXh0ICYgU3RyaWN0KSAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3ltYm9sXCJcbiAgICB9XG5cbiAgICAvLyBUaGUgc2V0IGFsZ29yaXRobSBpcyBzdHJ1Y3R1cmVkIGEgbGl0dGxlIGRpZmZlcmVudGx5LiBJdCB0YWtlcyBvbmUgb2YgdGhlXG4gICAgLy8gc2V0cyBpbnRvIGFuIGFycmF5LCBkb2VzIGEgY2hlYXAgaWRlbnRpdHkgY2hlY2ssIHRoZW4gZG9lcyB0aGUgZGVlcFxuICAgIC8vIGNoZWNrLlxuICAgIGZ1bmN0aW9uIG1hdGNoU2V0KGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICAvLyBUaGlzIGlzIHRvIHRyeSB0byBhdm9pZCBhbiBleHBlbnNpdmUgc3RydWN0dXJhbCBtYXRjaCBvbiB0aGUga2V5cy5cbiAgICAgICAgLy8gVGVzdCBmb3IgaWRlbnRpdHkgZmlyc3QuXG4gICAgICAgIHZhciBhbGlzdCA9IGtleUxpc3QoYSlcblxuICAgICAgICBpZiAoaGFzQWxsSWRlbnRpY2FsKGFsaXN0LCBiKSkgcmV0dXJuIHRydWVcblxuICAgICAgICB2YXIgaXRlciA9IGIudmFsdWVzKClcbiAgICAgICAgdmFyIGNvdW50ID0gMFxuICAgICAgICB2YXIgb2JqZWN0c1xuXG4gICAgICAgIC8vIEdhdGhlciBhbGwgdGhlIG9iamVjdHNcbiAgICAgICAgZm9yICh2YXIgbmV4dCA9IGl0ZXIubmV4dCgpOyAhbmV4dC5kb25lOyBuZXh0ID0gaXRlci5uZXh0KCkpIHtcbiAgICAgICAgICAgIHZhciBidmFsdWUgPSBuZXh0LnZhbHVlXG5cbiAgICAgICAgICAgIGlmIChoYXNTdHJ1Y3R1cmUoYnZhbHVlLCBjb250ZXh0KSkge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgb2JqZWN0cyBtYXAgbGF6aWx5LiBOb3RlIHRoYXQgdGhpcyBhbHNvIGdyYWJzXG4gICAgICAgICAgICAgICAgLy8gU3ltYm9scyB3aGVuIG5vdCBzdHJpY3RseSBtYXRjaGluZywgc2luY2UgdGhlaXIgZGVzY3JpcHRpb25cbiAgICAgICAgICAgICAgICAvLyBpcyBjb21wYXJlZC5cbiAgICAgICAgICAgICAgICBpZiAoY291bnQgPT09IDApIG9iamVjdHMgPSBPYmplY3QuY3JlYXRlKG51bGwpXG4gICAgICAgICAgICAgICAgb2JqZWN0c1tjb3VudCsrXSA9IGJ2YWx1ZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgZXZlcnl0aGluZyBpcyBhIHByaW1pdGl2ZSwgdGhlbiBhYm9ydC5cbiAgICAgICAgaWYgKGNvdW50ID09PSAwKSByZXR1cm4gZmFsc2VcblxuICAgICAgICAvLyBJdGVyYXRlIHRoZSBvYmplY3QsIHJlbW92aW5nIGVhY2ggb25lIHJlbWFpbmluZyB3aGVuIG1hdGNoZWQgKGFuZFxuICAgICAgICAvLyBhYm9ydGluZyBpZiBub25lIGNhbiBiZSkuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICAgICAgdmFyIGF2YWx1ZSA9IGFsaXN0W2ldXG5cbiAgICAgICAgICAgIGlmIChoYXNTdHJ1Y3R1cmUoYXZhbHVlLCBjb250ZXh0KSAmJlxuICAgICAgICAgICAgICAgICAgICAhc2VhcmNoRm9yKGF2YWx1ZSwgb2JqZWN0cywgY29udGV4dCwgbGVmdCwgcmlnaHQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoUmVnRXhwKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIGEuc291cmNlID09PSBiLnNvdXJjZSAmJlxuICAgICAgICAgICAgYS5nbG9iYWwgPT09IGIuZ2xvYmFsICYmXG4gICAgICAgICAgICBhLmlnbm9yZUNhc2UgPT09IGIuaWdub3JlQ2FzZSAmJlxuICAgICAgICAgICAgYS5tdWx0aWxpbmUgPT09IGIubXVsdGlsaW5lICYmXG4gICAgICAgICAgICAoIXN1cHBvcnRzVW5pY29kZSB8fCBhLnVuaWNvZGUgPT09IGIudW5pY29kZSkgJiZcbiAgICAgICAgICAgICghc3VwcG9ydHNTdGlja3kgfHwgYS5zdGlja3kgPT09IGIuc3RpY2t5KVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoUHJlcGFyZURlc2NlbmQoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIC8vIENoZWNrIGZvciBjaXJjdWxhciByZWZlcmVuY2VzIGFmdGVyIHRoZSBmaXJzdCBsZXZlbCwgd2hlcmUgaXQnc1xuICAgICAgICAvLyByZWR1bmRhbnQuIE5vdGUgdGhhdCB0aGV5IGhhdmUgdG8gcG9pbnQgdG8gdGhlIHNhbWUgbGV2ZWwgdG8gYWN0dWFsbHlcbiAgICAgICAgLy8gYmUgY29uc2lkZXJlZCBkZWVwbHkgZXF1YWwuXG4gICAgICAgIGlmICghKGNvbnRleHQgJiBJbml0aWFsKSkge1xuICAgICAgICAgICAgdmFyIGxlZnRJbmRleCA9IGxlZnQuaW5kZXhPZihhKVxuICAgICAgICAgICAgdmFyIHJpZ2h0SW5kZXggPSByaWdodC5pbmRleE9mKGIpXG5cbiAgICAgICAgICAgIGlmIChsZWZ0SW5kZXggIT09IHJpZ2h0SW5kZXgpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKGxlZnRJbmRleCA+PSAwKSByZXR1cm4gdHJ1ZVxuXG4gICAgICAgICAgICBsZWZ0LnB1c2goYSlcbiAgICAgICAgICAgIHJpZ2h0LnB1c2goYilcblxuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IG1hdGNoSW5uZXIoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG5cbiAgICAgICAgICAgIGxlZnQucG9wKClcbiAgICAgICAgICAgIHJpZ2h0LnBvcCgpXG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBtYXRjaElubmVyKGEsIGIsIGNvbnRleHQgJiB+SW5pdGlhbCwgW2FdLCBbYl0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXRjaFNhbWVQcm90byhhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgaWYgKHN5bWJvbHNBcmVPYmplY3RzICYmIGEgaW5zdGFuY2VvZiBTeW1ib2wpIHtcbiAgICAgICAgICAgIHJldHVybiAhKGNvbnRleHQgJiBTdHJpY3QpICYmIGEudG9TdHJpbmcoKSA9PT0gYi50b1N0cmluZygpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYSBpbnN0YW5jZW9mIFJlZ0V4cCkgcmV0dXJuIG1hdGNoUmVnRXhwKGEsIGIpXG4gICAgICAgIGlmIChhIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIGEudmFsdWVPZigpID09PSBiLnZhbHVlT2YoKVxuICAgICAgICBpZiAoYXJyYXlCdWZmZXJTdXBwb3J0ICE9PSBBcnJheUJ1ZmZlck5vbmUpIHtcbiAgICAgICAgICAgIGlmIChhIGluc3RhbmNlb2YgRGF0YVZpZXcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hWaWV3KFxuICAgICAgICAgICAgICAgICAgICBuZXcgVWludDhBcnJheShhLmJ1ZmZlciwgYS5ieXRlT2Zmc2V0LCBhLmJ5dGVMZW5ndGgpLFxuICAgICAgICAgICAgICAgICAgICBuZXcgVWludDhBcnJheShiLmJ1ZmZlciwgYi5ieXRlT2Zmc2V0LCBiLmJ5dGVMZW5ndGgpKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaFZpZXcobmV3IFVpbnQ4QXJyYXkoYSksIG5ldyBVaW50OEFycmF5KGIpKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzVmlldyhhKSkgcmV0dXJuIG1hdGNoVmlldyhhLCBiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQnVmZmVyKGEpKSByZXR1cm4gbWF0Y2hWaWV3KGEsIGIpXG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYSkpIHtcbiAgICAgICAgICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKGEubGVuZ3RoID09PSAwKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKHN1cHBvcnRzTWFwICYmIGEgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgICAgICAgIGlmIChhLnNpemUgIT09IGIuc2l6ZSkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICBpZiAoYS5zaXplID09PSAwKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKHN1cHBvcnRzU2V0ICYmIGEgaW5zdGFuY2VvZiBTZXQpIHtcbiAgICAgICAgICAgIGlmIChhLnNpemUgIT09IGIuc2l6ZSkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICBpZiAoYS5zaXplID09PSAwKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYSkgPT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3RUb1N0cmluZy5jYWxsKGIpICE9PSBcIltvYmplY3QgQXJndW1lbnRzXVwiKSByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKGEubGVuZ3RoID09PSAwKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYikgPT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1hdGNoUHJlcGFyZURlc2NlbmQoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgfVxuXG4gICAgLy8gTW9zdCBzcGVjaWFsIGNhc2VzIHJlcXVpcmUgYm90aCB0eXBlcyB0byBtYXRjaCwgYW5kIGlmIG9ubHkgb25lIG9mIHRoZW1cbiAgICAvLyBhcmUsIHRoZSBvYmplY3RzIHRoZW1zZWx2ZXMgZG9uJ3QgbWF0Y2guXG4gICAgZnVuY3Rpb24gbWF0Y2hEaWZmZXJlbnRQcm90byhhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgaWYgKHN5bWJvbHNBcmVPYmplY3RzKSB7XG4gICAgICAgICAgICBpZiAoYSBpbnN0YW5jZW9mIFN5bWJvbCB8fCBiIGluc3RhbmNlb2YgU3ltYm9sKSByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udGV4dCAmIFN0cmljdCkgcmV0dXJuIGZhbHNlXG4gICAgICAgIGlmIChhcnJheUJ1ZmZlclN1cHBvcnQgIT09IEFycmF5QnVmZmVyTm9uZSkge1xuICAgICAgICAgICAgaWYgKGEgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciB8fCBiIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc1ZpZXcoYSkgfHwgaXNWaWV3KGIpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhKSB8fCBBcnJheS5pc0FycmF5KGIpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKHN1cHBvcnRzTWFwICYmIChhIGluc3RhbmNlb2YgTWFwIHx8IGIgaW5zdGFuY2VvZiBNYXApKSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKHN1cHBvcnRzU2V0ICYmIChhIGluc3RhbmNlb2YgU2V0IHx8IGIgaW5zdGFuY2VvZiBTZXQpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYSkgPT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHtcbiAgICAgICAgICAgIGlmIChvYmplY3RUb1N0cmluZy5jYWxsKGIpICE9PSBcIltvYmplY3QgQXJndW1lbnRzXVwiKSByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKGEubGVuZ3RoID09PSAwKSByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG4gICAgICAgIGlmIChvYmplY3RUb1N0cmluZy5jYWxsKGIpID09PSBcIltvYmplY3QgQXJndW1lbnRzXVwiKSByZXR1cm4gZmFsc2VcbiAgICAgICAgcmV0dXJuIG1hdGNoUHJlcGFyZURlc2NlbmQoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF0Y2goYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIGlmIChhID09PSBiKSByZXR1cm4gdHJ1ZVxuICAgICAgICAvLyBOYU5zIGFyZSBlcXVhbFxuICAgICAgICBpZiAoYSAhPT0gYSkgcmV0dXJuIGIgIT09IGIgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICAgICAgaWYgKGEgPT09IG51bGwgfHwgYiA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlXG4gICAgICAgIGlmICh0eXBlb2YgYSA9PT0gXCJzeW1ib2xcIiAmJiB0eXBlb2YgYiA9PT0gXCJzeW1ib2xcIikge1xuICAgICAgICAgICAgcmV0dXJuICEoY29udGV4dCAmIFN0cmljdCkgJiYgYS50b1N0cmluZygpID09PSBiLnRvU3RyaW5nKClcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGEgIT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIGIgIT09IFwib2JqZWN0XCIpIHJldHVybiBmYWxzZVxuXG4gICAgICAgIC8vIFVzdWFsbHksIGJvdGggb2JqZWN0cyBoYXZlIGlkZW50aWNhbCBwcm90b3R5cGVzLCBhbmQgdGhhdCBhbGxvd3MgZm9yXG4gICAgICAgIC8vIGhhbGYgdGhlIHR5cGUgY2hlY2tpbmcuXG4gICAgICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSkgPT09IE9iamVjdC5nZXRQcm90b3R5cGVPZihiKSkge1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoU2FtZVByb3RvKGEsIGIsIGNvbnRleHQgfCBTYW1lUHJvdG8sIGxlZnQsIHJpZ2h0KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoRGlmZmVyZW50UHJvdG8oYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXRjaEFycmF5TGlrZShhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIW1hdGNoKGFbaV0sIGJbaV0sIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIC8vIFBoYW50b21KUyBhbmQgU2xpbWVySlMgYm90aCBoYXZlIG15c3RlcmlvdXMgaXNzdWVzIHdoZXJlIGBFcnJvcmAgaXNcbiAgICAvLyBzb21ldGltZXMgZXJyb25lb3VzbHkgb2YgYSBkaWZmZXJlbnQgYHdpbmRvd2AsIGFuZCBpdCBzaG93cyB1cCBpbiB0aGVcbiAgICAvLyB0ZXN0cy4gVGhpcyBtZWFucyBJIGhhdmUgdG8gdXNlIGEgbXVjaCBzbG93ZXIgYWxnb3JpdGhtIHRvIGRldGVjdCBFcnJvcnMuXG4gICAgLy9cbiAgICAvLyBQaGFudG9tSlM6IGh0dHBzOi8vZ2l0aHViLmNvbS9wZXRrYWFudG9ub3YvYmx1ZWJpcmQvaXNzdWVzLzExNDZcbiAgICAvLyBTbGltZXJKUzogaHR0cHM6Ly9naXRodWIuY29tL2xhdXJlbnRqL3NsaW1lcmpzL2lzc3Vlcy80MDBcbiAgICAvL1xuICAgIC8vIChZZXMsIHRoZSBQaGFudG9tSlMgYnVnIGlzIGRldGFpbGVkIGluIHRoZSBCbHVlYmlyZCBpc3N1ZSB0cmFja2VyLilcbiAgICB2YXIgY2hlY2tDcm9zc09yaWdpbiA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChnbG9iYWwud2luZG93ID09IG51bGwgfHwgZ2xvYmFsLndpbmRvdy5uYXZpZ2F0b3IgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIC9zbGltZXJqc3xwaGFudG9tanMvaS50ZXN0KGdsb2JhbC53aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudClcbiAgICB9KSgpXG5cbiAgICB2YXIgZXJyb3JTdHJpbmdUeXBlcyA9IHtcbiAgICAgICAgXCJbb2JqZWN0IEVycm9yXVwiOiB0cnVlLFxuICAgICAgICBcIltvYmplY3QgRXZhbEVycm9yXVwiOiB0cnVlLFxuICAgICAgICBcIltvYmplY3QgUmFuZ2VFcnJvcl1cIjogdHJ1ZSxcbiAgICAgICAgXCJbb2JqZWN0IFJlZmVyZW5jZUVycm9yXVwiOiB0cnVlLFxuICAgICAgICBcIltvYmplY3QgU3ludGF4RXJyb3JdXCI6IHRydWUsXG4gICAgICAgIFwiW29iamVjdCBUeXBlRXJyb3JdXCI6IHRydWUsXG4gICAgICAgIFwiW29iamVjdCBVUklFcnJvcl1cIjogdHJ1ZSxcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1Byb3hpZWRFcnJvcihvYmplY3QpIHtcbiAgICAgICAgd2hpbGUgKG9iamVjdCAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3JTdHJpbmdUeXBlc1tvYmplY3RUb1N0cmluZy5jYWxsKG9iamVjdCldKSByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgb2JqZWN0ID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG9iamVjdClcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoSW5uZXIoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtc3RhdGVtZW50cywgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICB2YXIgYWtleXMsIGJrZXlzXG4gICAgICAgIHZhciBpc1VucHJveGllZEVycm9yID0gZmFsc2VcblxuICAgICAgICBpZiAoY29udGV4dCAmIFNhbWVQcm90bykge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hBcnJheUxpa2UoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdXBwb3J0c01hcCAmJiBhIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoTWFwKGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc3VwcG9ydHNTZXQgJiYgYSBpbnN0YW5jZW9mIFNldCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaFNldChhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYSkgPT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hBcnJheUxpa2UoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChyZXF1aXJlc1Byb3h5ICYmXG4gICAgICAgICAgICAgICAgICAgIChjaGVja0Nyb3NzT3JpZ2luID8gaXNQcm94aWVkRXJyb3IoYSlcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYSBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgICAgICAgICAgICAgIGFrZXlzID0gZ2V0S2V5c1N0cmlwcGVkKGEpXG4gICAgICAgICAgICAgICAgYmtleXMgPSBnZXRLZXlzU3RyaXBwZWQoYilcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYWtleXMgPSBPYmplY3Qua2V5cyhhKVxuICAgICAgICAgICAgICAgIGJrZXlzID0gT2JqZWN0LmtleXMoYilcbiAgICAgICAgICAgICAgICBpc1VucHJveGllZEVycm9yID0gYSBpbnN0YW5jZW9mIEVycm9yXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAob2JqZWN0VG9TdHJpbmcuY2FsbChhKSA9PT0gXCJbb2JqZWN0IEFyZ3VtZW50c11cIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaEFycmF5TGlrZShhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgd2UgcmVxdWlyZSBhIHByb3h5LCBiZSBwZXJtaXNzaXZlIGFuZCBjaGVjayB0aGUgYHRvU3RyaW5nYFxuICAgICAgICAgICAgLy8gdHlwZS4gVGhpcyBpcyBzbyBpdCB3b3JrcyBjcm9zcy1vcmlnaW4gaW4gUGhhbnRvbUpTIGluXG4gICAgICAgICAgICAvLyBwYXJ0aWN1bGFyLlxuICAgICAgICAgICAgaWYgKGNoZWNrQ3Jvc3NPcmlnaW4gPyBpc1Byb3hpZWRFcnJvcihhKSA6IGEgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWtleXMgPSBPYmplY3Qua2V5cyhhKVxuICAgICAgICAgICAgYmtleXMgPSBPYmplY3Qua2V5cyhiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNvdW50ID0gYWtleXMubGVuZ3RoXG5cbiAgICAgICAgaWYgKGNvdW50ICE9PSBia2V5cy5sZW5ndGgpIHJldHVybiBmYWxzZVxuXG4gICAgICAgIC8vIFNob3J0Y3V0IGlmIHRoZXJlJ3Mgbm90aGluZyB0byBtYXRjaFxuICAgICAgICBpZiAoY291bnQgPT09IDApIHJldHVybiB0cnVlXG5cbiAgICAgICAgdmFyIGlcblxuICAgICAgICBpZiAoaXNVbnByb3hpZWRFcnJvcikge1xuICAgICAgICAgICAgLy8gU2hvcnRjdXQgaWYgdGhlIHByb3BlcnRpZXMgYXJlIGRpZmZlcmVudC5cbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFrZXlzW2ldICE9PSBcInN0YWNrXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNPd24uY2FsbChiLCBha2V5c1tpXSkpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVmVyaWZ5IHRoYXQgYWxsIHRoZSBha2V5cycgdmFsdWVzIG1hdGNoZWQuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChha2V5c1tpXSAhPT0gXCJzdGFja1wiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAhbWF0Y2goYVtha2V5c1tpXV0sIGJbYWtleXNbaV1dLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTaG9ydGN1dCBpZiB0aGUgcHJvcGVydGllcyBhcmUgZGlmZmVyZW50LlxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoIWhhc093bi5jYWxsKGIsIGFrZXlzW2ldKSkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFZlcmlmeSB0aGF0IGFsbCB0aGUgYWtleXMnIHZhbHVlcyBtYXRjaGVkLlxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoIW1hdGNoKGFbYWtleXNbaV1dLCBiW2FrZXlzW2ldXSwgY29udGV4dCwgbGVmdCwgcmlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxufSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgc2VtaVxuIiwiLy8gU2VlOiBodHRwOi8vY29kZS5nb29nbGUuY29tL3AvZ29vZ2xlLWRpZmYtbWF0Y2gtcGF0Y2gvd2lraS9BUElcbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0Q2hhbmdlc1RvRE1QKGNoYW5nZXMpIHtcbiAgbGV0IHJldCA9IFtdLFxuICAgICAgY2hhbmdlLFxuICAgICAgb3BlcmF0aW9uO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGNoYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjaGFuZ2UgPSBjaGFuZ2VzW2ldO1xuICAgIGlmIChjaGFuZ2UuYWRkZWQpIHtcbiAgICAgIG9wZXJhdGlvbiA9IDE7XG4gICAgfSBlbHNlIGlmIChjaGFuZ2UucmVtb3ZlZCkge1xuICAgICAgb3BlcmF0aW9uID0gLTE7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wZXJhdGlvbiA9IDA7XG4gICAgfVxuXG4gICAgcmV0LnB1c2goW29wZXJhdGlvbiwgY2hhbmdlLnZhbHVlXSk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cbiIsImV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0Q2hhbmdlc1RvWE1MKGNoYW5nZXMpIHtcbiAgbGV0IHJldCA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGNoYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgY2hhbmdlID0gY2hhbmdlc1tpXTtcbiAgICBpZiAoY2hhbmdlLmFkZGVkKSB7XG4gICAgICByZXQucHVzaCgnPGlucz4nKTtcbiAgICB9IGVsc2UgaWYgKGNoYW5nZS5yZW1vdmVkKSB7XG4gICAgICByZXQucHVzaCgnPGRlbD4nKTtcbiAgICB9XG5cbiAgICByZXQucHVzaChlc2NhcGVIVE1MKGNoYW5nZS52YWx1ZSkpO1xuXG4gICAgaWYgKGNoYW5nZS5hZGRlZCkge1xuICAgICAgcmV0LnB1c2goJzwvaW5zPicpO1xuICAgIH0gZWxzZSBpZiAoY2hhbmdlLnJlbW92ZWQpIHtcbiAgICAgIHJldC5wdXNoKCc8L2RlbD4nKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJldC5qb2luKCcnKTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlSFRNTChzKSB7XG4gIGxldCBuID0gcztcbiAgbiA9IG4ucmVwbGFjZSgvJi9nLCAnJmFtcDsnKTtcbiAgbiA9IG4ucmVwbGFjZSgvPC9nLCAnJmx0OycpO1xuICBuID0gbi5yZXBsYWNlKC8+L2csICcmZ3Q7Jyk7XG4gIG4gPSBuLnJlcGxhY2UoL1wiL2csICcmcXVvdDsnKTtcblxuICByZXR1cm4gbjtcbn1cbiIsImltcG9ydCBEaWZmIGZyb20gJy4vYmFzZSc7XG5cbmV4cG9ydCBjb25zdCBhcnJheURpZmYgPSBuZXcgRGlmZigpO1xuYXJyYXlEaWZmLnRva2VuaXplID0gYXJyYXlEaWZmLmpvaW4gPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUuc2xpY2UoKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBkaWZmQXJyYXlzKG9sZEFyciwgbmV3QXJyLCBjYWxsYmFjaykgeyByZXR1cm4gYXJyYXlEaWZmLmRpZmYob2xkQXJyLCBuZXdBcnIsIGNhbGxiYWNrKTsgfVxuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRGlmZigpIHt9XG5cbkRpZmYucHJvdG90eXBlID0ge1xuICBkaWZmKG9sZFN0cmluZywgbmV3U3RyaW5nLCBvcHRpb25zID0ge30pIHtcbiAgICBsZXQgY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY2FsbGJhY2sgPSBvcHRpb25zO1xuICAgICAgb3B0aW9ucyA9IHt9O1xuICAgIH1cbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgbGV0IHNlbGYgPSB0aGlzO1xuXG4gICAgZnVuY3Rpb24gZG9uZSh2YWx1ZSkge1xuICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNhbGxiYWNrKHVuZGVmaW5lZCwgdmFsdWUpOyB9LCAwKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWxsb3cgc3ViY2xhc3NlcyB0byBtYXNzYWdlIHRoZSBpbnB1dCBwcmlvciB0byBydW5uaW5nXG4gICAgb2xkU3RyaW5nID0gdGhpcy5jYXN0SW5wdXQob2xkU3RyaW5nKTtcbiAgICBuZXdTdHJpbmcgPSB0aGlzLmNhc3RJbnB1dChuZXdTdHJpbmcpO1xuXG4gICAgb2xkU3RyaW5nID0gdGhpcy5yZW1vdmVFbXB0eSh0aGlzLnRva2VuaXplKG9sZFN0cmluZykpO1xuICAgIG5ld1N0cmluZyA9IHRoaXMucmVtb3ZlRW1wdHkodGhpcy50b2tlbml6ZShuZXdTdHJpbmcpKTtcblxuICAgIGxldCBuZXdMZW4gPSBuZXdTdHJpbmcubGVuZ3RoLCBvbGRMZW4gPSBvbGRTdHJpbmcubGVuZ3RoO1xuICAgIGxldCBlZGl0TGVuZ3RoID0gMTtcbiAgICBsZXQgbWF4RWRpdExlbmd0aCA9IG5ld0xlbiArIG9sZExlbjtcbiAgICBsZXQgYmVzdFBhdGggPSBbeyBuZXdQb3M6IC0xLCBjb21wb25lbnRzOiBbXSB9XTtcblxuICAgIC8vIFNlZWQgZWRpdExlbmd0aCA9IDAsIGkuZS4gdGhlIGNvbnRlbnQgc3RhcnRzIHdpdGggdGhlIHNhbWUgdmFsdWVzXG4gICAgbGV0IG9sZFBvcyA9IHRoaXMuZXh0cmFjdENvbW1vbihiZXN0UGF0aFswXSwgbmV3U3RyaW5nLCBvbGRTdHJpbmcsIDApO1xuICAgIGlmIChiZXN0UGF0aFswXS5uZXdQb3MgKyAxID49IG5ld0xlbiAmJiBvbGRQb3MgKyAxID49IG9sZExlbikge1xuICAgICAgLy8gSWRlbnRpdHkgcGVyIHRoZSBlcXVhbGl0eSBhbmQgdG9rZW5pemVyXG4gICAgICByZXR1cm4gZG9uZShbe3ZhbHVlOiB0aGlzLmpvaW4obmV3U3RyaW5nKSwgY291bnQ6IG5ld1N0cmluZy5sZW5ndGh9XSk7XG4gICAgfVxuXG4gICAgLy8gTWFpbiB3b3JrZXIgbWV0aG9kLiBjaGVja3MgYWxsIHBlcm11dGF0aW9ucyBvZiBhIGdpdmVuIGVkaXQgbGVuZ3RoIGZvciBhY2NlcHRhbmNlLlxuICAgIGZ1bmN0aW9uIGV4ZWNFZGl0TGVuZ3RoKCkge1xuICAgICAgZm9yIChsZXQgZGlhZ29uYWxQYXRoID0gLTEgKiBlZGl0TGVuZ3RoOyBkaWFnb25hbFBhdGggPD0gZWRpdExlbmd0aDsgZGlhZ29uYWxQYXRoICs9IDIpIHtcbiAgICAgICAgbGV0IGJhc2VQYXRoO1xuICAgICAgICBsZXQgYWRkUGF0aCA9IGJlc3RQYXRoW2RpYWdvbmFsUGF0aCAtIDFdLFxuICAgICAgICAgICAgcmVtb3ZlUGF0aCA9IGJlc3RQYXRoW2RpYWdvbmFsUGF0aCArIDFdLFxuICAgICAgICAgICAgb2xkUG9zID0gKHJlbW92ZVBhdGggPyByZW1vdmVQYXRoLm5ld1BvcyA6IDApIC0gZGlhZ29uYWxQYXRoO1xuICAgICAgICBpZiAoYWRkUGF0aCkge1xuICAgICAgICAgIC8vIE5vIG9uZSBlbHNlIGlzIGdvaW5nIHRvIGF0dGVtcHQgdG8gdXNlIHRoaXMgdmFsdWUsIGNsZWFyIGl0XG4gICAgICAgICAgYmVzdFBhdGhbZGlhZ29uYWxQYXRoIC0gMV0gPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgY2FuQWRkID0gYWRkUGF0aCAmJiBhZGRQYXRoLm5ld1BvcyArIDEgPCBuZXdMZW4sXG4gICAgICAgICAgICBjYW5SZW1vdmUgPSByZW1vdmVQYXRoICYmIDAgPD0gb2xkUG9zICYmIG9sZFBvcyA8IG9sZExlbjtcbiAgICAgICAgaWYgKCFjYW5BZGQgJiYgIWNhblJlbW92ZSkge1xuICAgICAgICAgIC8vIElmIHRoaXMgcGF0aCBpcyBhIHRlcm1pbmFsIHRoZW4gcHJ1bmVcbiAgICAgICAgICBiZXN0UGF0aFtkaWFnb25hbFBhdGhdID0gdW5kZWZpbmVkO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2VsZWN0IHRoZSBkaWFnb25hbCB0aGF0IHdlIHdhbnQgdG8gYnJhbmNoIGZyb20uIFdlIHNlbGVjdCB0aGUgcHJpb3JcbiAgICAgICAgLy8gcGF0aCB3aG9zZSBwb3NpdGlvbiBpbiB0aGUgbmV3IHN0cmluZyBpcyB0aGUgZmFydGhlc3QgZnJvbSB0aGUgb3JpZ2luXG4gICAgICAgIC8vIGFuZCBkb2VzIG5vdCBwYXNzIHRoZSBib3VuZHMgb2YgdGhlIGRpZmYgZ3JhcGhcbiAgICAgICAgaWYgKCFjYW5BZGQgfHwgKGNhblJlbW92ZSAmJiBhZGRQYXRoLm5ld1BvcyA8IHJlbW92ZVBhdGgubmV3UG9zKSkge1xuICAgICAgICAgIGJhc2VQYXRoID0gY2xvbmVQYXRoKHJlbW92ZVBhdGgpO1xuICAgICAgICAgIHNlbGYucHVzaENvbXBvbmVudChiYXNlUGF0aC5jb21wb25lbnRzLCB1bmRlZmluZWQsIHRydWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJhc2VQYXRoID0gYWRkUGF0aDsgICAvLyBObyBuZWVkIHRvIGNsb25lLCB3ZSd2ZSBwdWxsZWQgaXQgZnJvbSB0aGUgbGlzdFxuICAgICAgICAgIGJhc2VQYXRoLm5ld1BvcysrO1xuICAgICAgICAgIHNlbGYucHVzaENvbXBvbmVudChiYXNlUGF0aC5jb21wb25lbnRzLCB0cnVlLCB1bmRlZmluZWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgb2xkUG9zID0gc2VsZi5leHRyYWN0Q29tbW9uKGJhc2VQYXRoLCBuZXdTdHJpbmcsIG9sZFN0cmluZywgZGlhZ29uYWxQYXRoKTtcblxuICAgICAgICAvLyBJZiB3ZSBoYXZlIGhpdCB0aGUgZW5kIG9mIGJvdGggc3RyaW5ncywgdGhlbiB3ZSBhcmUgZG9uZVxuICAgICAgICBpZiAoYmFzZVBhdGgubmV3UG9zICsgMSA+PSBuZXdMZW4gJiYgb2xkUG9zICsgMSA+PSBvbGRMZW4pIHtcbiAgICAgICAgICByZXR1cm4gZG9uZShidWlsZFZhbHVlcyhzZWxmLCBiYXNlUGF0aC5jb21wb25lbnRzLCBuZXdTdHJpbmcsIG9sZFN0cmluZywgc2VsZi51c2VMb25nZXN0VG9rZW4pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBPdGhlcndpc2UgdHJhY2sgdGhpcyBwYXRoIGFzIGEgcG90ZW50aWFsIGNhbmRpZGF0ZSBhbmQgY29udGludWUuXG4gICAgICAgICAgYmVzdFBhdGhbZGlhZ29uYWxQYXRoXSA9IGJhc2VQYXRoO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGVkaXRMZW5ndGgrKztcbiAgICB9XG5cbiAgICAvLyBQZXJmb3JtcyB0aGUgbGVuZ3RoIG9mIGVkaXQgaXRlcmF0aW9uLiBJcyBhIGJpdCBmdWdseSBhcyB0aGlzIGhhcyB0byBzdXBwb3J0IHRoZVxuICAgIC8vIHN5bmMgYW5kIGFzeW5jIG1vZGUgd2hpY2ggaXMgbmV2ZXIgZnVuLiBMb29wcyBvdmVyIGV4ZWNFZGl0TGVuZ3RoIHVudGlsIGEgdmFsdWVcbiAgICAvLyBpcyBwcm9kdWNlZC5cbiAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgIChmdW5jdGlvbiBleGVjKCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgIC8vIFRoaXMgc2hvdWxkIG5vdCBoYXBwZW4sIGJ1dCB3ZSB3YW50IHRvIGJlIHNhZmUuXG4gICAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgICAgICBpZiAoZWRpdExlbmd0aCA+IG1heEVkaXRMZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghZXhlY0VkaXRMZW5ndGgoKSkge1xuICAgICAgICAgICAgZXhlYygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgMCk7XG4gICAgICB9KCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aGlsZSAoZWRpdExlbmd0aCA8PSBtYXhFZGl0TGVuZ3RoKSB7XG4gICAgICAgIGxldCByZXQgPSBleGVjRWRpdExlbmd0aCgpO1xuICAgICAgICBpZiAocmV0KSB7XG4gICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBwdXNoQ29tcG9uZW50KGNvbXBvbmVudHMsIGFkZGVkLCByZW1vdmVkKSB7XG4gICAgbGV0IGxhc3QgPSBjb21wb25lbnRzW2NvbXBvbmVudHMubGVuZ3RoIC0gMV07XG4gICAgaWYgKGxhc3QgJiYgbGFzdC5hZGRlZCA9PT0gYWRkZWQgJiYgbGFzdC5yZW1vdmVkID09PSByZW1vdmVkKSB7XG4gICAgICAvLyBXZSBuZWVkIHRvIGNsb25lIGhlcmUgYXMgdGhlIGNvbXBvbmVudCBjbG9uZSBvcGVyYXRpb24gaXMganVzdFxuICAgICAgLy8gYXMgc2hhbGxvdyBhcnJheSBjbG9uZVxuICAgICAgY29tcG9uZW50c1tjb21wb25lbnRzLmxlbmd0aCAtIDFdID0ge2NvdW50OiBsYXN0LmNvdW50ICsgMSwgYWRkZWQ6IGFkZGVkLCByZW1vdmVkOiByZW1vdmVkIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbXBvbmVudHMucHVzaCh7Y291bnQ6IDEsIGFkZGVkOiBhZGRlZCwgcmVtb3ZlZDogcmVtb3ZlZCB9KTtcbiAgICB9XG4gIH0sXG4gIGV4dHJhY3RDb21tb24oYmFzZVBhdGgsIG5ld1N0cmluZywgb2xkU3RyaW5nLCBkaWFnb25hbFBhdGgpIHtcbiAgICBsZXQgbmV3TGVuID0gbmV3U3RyaW5nLmxlbmd0aCxcbiAgICAgICAgb2xkTGVuID0gb2xkU3RyaW5nLmxlbmd0aCxcbiAgICAgICAgbmV3UG9zID0gYmFzZVBhdGgubmV3UG9zLFxuICAgICAgICBvbGRQb3MgPSBuZXdQb3MgLSBkaWFnb25hbFBhdGgsXG5cbiAgICAgICAgY29tbW9uQ291bnQgPSAwO1xuICAgIHdoaWxlIChuZXdQb3MgKyAxIDwgbmV3TGVuICYmIG9sZFBvcyArIDEgPCBvbGRMZW4gJiYgdGhpcy5lcXVhbHMobmV3U3RyaW5nW25ld1BvcyArIDFdLCBvbGRTdHJpbmdbb2xkUG9zICsgMV0pKSB7XG4gICAgICBuZXdQb3MrKztcbiAgICAgIG9sZFBvcysrO1xuICAgICAgY29tbW9uQ291bnQrKztcbiAgICB9XG5cbiAgICBpZiAoY29tbW9uQ291bnQpIHtcbiAgICAgIGJhc2VQYXRoLmNvbXBvbmVudHMucHVzaCh7Y291bnQ6IGNvbW1vbkNvdW50fSk7XG4gICAgfVxuXG4gICAgYmFzZVBhdGgubmV3UG9zID0gbmV3UG9zO1xuICAgIHJldHVybiBvbGRQb3M7XG4gIH0sXG5cbiAgZXF1YWxzKGxlZnQsIHJpZ2h0KSB7XG4gICAgcmV0dXJuIGxlZnQgPT09IHJpZ2h0O1xuICB9LFxuICByZW1vdmVFbXB0eShhcnJheSkge1xuICAgIGxldCByZXQgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYXJyYXlbaV0pIHtcbiAgICAgICAgcmV0LnB1c2goYXJyYXlbaV0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9LFxuICBjYXN0SW5wdXQodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH0sXG4gIHRva2VuaXplKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlLnNwbGl0KCcnKTtcbiAgfSxcbiAgam9pbihjaGFycykge1xuICAgIHJldHVybiBjaGFycy5qb2luKCcnKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gYnVpbGRWYWx1ZXMoZGlmZiwgY29tcG9uZW50cywgbmV3U3RyaW5nLCBvbGRTdHJpbmcsIHVzZUxvbmdlc3RUb2tlbikge1xuICBsZXQgY29tcG9uZW50UG9zID0gMCxcbiAgICAgIGNvbXBvbmVudExlbiA9IGNvbXBvbmVudHMubGVuZ3RoLFxuICAgICAgbmV3UG9zID0gMCxcbiAgICAgIG9sZFBvcyA9IDA7XG5cbiAgZm9yICg7IGNvbXBvbmVudFBvcyA8IGNvbXBvbmVudExlbjsgY29tcG9uZW50UG9zKyspIHtcbiAgICBsZXQgY29tcG9uZW50ID0gY29tcG9uZW50c1tjb21wb25lbnRQb3NdO1xuICAgIGlmICghY29tcG9uZW50LnJlbW92ZWQpIHtcbiAgICAgIGlmICghY29tcG9uZW50LmFkZGVkICYmIHVzZUxvbmdlc3RUb2tlbikge1xuICAgICAgICBsZXQgdmFsdWUgPSBuZXdTdHJpbmcuc2xpY2UobmV3UG9zLCBuZXdQb3MgKyBjb21wb25lbnQuY291bnQpO1xuICAgICAgICB2YWx1ZSA9IHZhbHVlLm1hcChmdW5jdGlvbih2YWx1ZSwgaSkge1xuICAgICAgICAgIGxldCBvbGRWYWx1ZSA9IG9sZFN0cmluZ1tvbGRQb3MgKyBpXTtcbiAgICAgICAgICByZXR1cm4gb2xkVmFsdWUubGVuZ3RoID4gdmFsdWUubGVuZ3RoID8gb2xkVmFsdWUgOiB2YWx1ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29tcG9uZW50LnZhbHVlID0gZGlmZi5qb2luKHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbXBvbmVudC52YWx1ZSA9IGRpZmYuam9pbihuZXdTdHJpbmcuc2xpY2UobmV3UG9zLCBuZXdQb3MgKyBjb21wb25lbnQuY291bnQpKTtcbiAgICAgIH1cbiAgICAgIG5ld1BvcyArPSBjb21wb25lbnQuY291bnQ7XG5cbiAgICAgIC8vIENvbW1vbiBjYXNlXG4gICAgICBpZiAoIWNvbXBvbmVudC5hZGRlZCkge1xuICAgICAgICBvbGRQb3MgKz0gY29tcG9uZW50LmNvdW50O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb21wb25lbnQudmFsdWUgPSBkaWZmLmpvaW4ob2xkU3RyaW5nLnNsaWNlKG9sZFBvcywgb2xkUG9zICsgY29tcG9uZW50LmNvdW50KSk7XG4gICAgICBvbGRQb3MgKz0gY29tcG9uZW50LmNvdW50O1xuXG4gICAgICAvLyBSZXZlcnNlIGFkZCBhbmQgcmVtb3ZlIHNvIHJlbW92ZXMgYXJlIG91dHB1dCBmaXJzdCB0byBtYXRjaCBjb21tb24gY29udmVudGlvblxuICAgICAgLy8gVGhlIGRpZmZpbmcgYWxnb3JpdGhtIGlzIHRpZWQgdG8gYWRkIHRoZW4gcmVtb3ZlIG91dHB1dCBhbmQgdGhpcyBpcyB0aGUgc2ltcGxlc3RcbiAgICAgIC8vIHJvdXRlIHRvIGdldCB0aGUgZGVzaXJlZCBvdXRwdXQgd2l0aCBtaW5pbWFsIG92ZXJoZWFkLlxuICAgICAgaWYgKGNvbXBvbmVudFBvcyAmJiBjb21wb25lbnRzW2NvbXBvbmVudFBvcyAtIDFdLmFkZGVkKSB7XG4gICAgICAgIGxldCB0bXAgPSBjb21wb25lbnRzW2NvbXBvbmVudFBvcyAtIDFdO1xuICAgICAgICBjb21wb25lbnRzW2NvbXBvbmVudFBvcyAtIDFdID0gY29tcG9uZW50c1tjb21wb25lbnRQb3NdO1xuICAgICAgICBjb21wb25lbnRzW2NvbXBvbmVudFBvc10gPSB0bXA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gU3BlY2lhbCBjYXNlIGhhbmRsZSBmb3Igd2hlbiBvbmUgdGVybWluYWwgaXMgaWdub3JlZC4gRm9yIHRoaXMgY2FzZSB3ZSBtZXJnZSB0aGVcbiAgLy8gdGVybWluYWwgaW50byB0aGUgcHJpb3Igc3RyaW5nIGFuZCBkcm9wIHRoZSBjaGFuZ2UuXG4gIGxldCBsYXN0Q29tcG9uZW50ID0gY29tcG9uZW50c1tjb21wb25lbnRMZW4gLSAxXTtcbiAgaWYgKGNvbXBvbmVudExlbiA+IDFcbiAgICAgICYmIChsYXN0Q29tcG9uZW50LmFkZGVkIHx8IGxhc3RDb21wb25lbnQucmVtb3ZlZClcbiAgICAgICYmIGRpZmYuZXF1YWxzKCcnLCBsYXN0Q29tcG9uZW50LnZhbHVlKSkge1xuICAgIGNvbXBvbmVudHNbY29tcG9uZW50TGVuIC0gMl0udmFsdWUgKz0gbGFzdENvbXBvbmVudC52YWx1ZTtcbiAgICBjb21wb25lbnRzLnBvcCgpO1xuICB9XG5cbiAgcmV0dXJuIGNvbXBvbmVudHM7XG59XG5cbmZ1bmN0aW9uIGNsb25lUGF0aChwYXRoKSB7XG4gIHJldHVybiB7IG5ld1BvczogcGF0aC5uZXdQb3MsIGNvbXBvbmVudHM6IHBhdGguY29tcG9uZW50cy5zbGljZSgwKSB9O1xufVxuIiwiaW1wb3J0IERpZmYgZnJvbSAnLi9iYXNlJztcblxuZXhwb3J0IGNvbnN0IGNoYXJhY3RlckRpZmYgPSBuZXcgRGlmZigpO1xuZXhwb3J0IGZ1bmN0aW9uIGRpZmZDaGFycyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHsgcmV0dXJuIGNoYXJhY3RlckRpZmYuZGlmZihvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spOyB9XG4iLCJpbXBvcnQgRGlmZiBmcm9tICcuL2Jhc2UnO1xuXG5leHBvcnQgY29uc3QgY3NzRGlmZiA9IG5ldyBEaWZmKCk7XG5jc3NEaWZmLnRva2VuaXplID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlLnNwbGl0KC8oW3t9OjssXXxcXHMrKS8pO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZDc3Mob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKSB7IHJldHVybiBjc3NEaWZmLmRpZmYob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKTsgfVxuIiwiaW1wb3J0IERpZmYgZnJvbSAnLi9iYXNlJztcbmltcG9ydCB7bGluZURpZmZ9IGZyb20gJy4vbGluZSc7XG5cbmNvbnN0IG9iamVjdFByb3RvdHlwZVRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuXG5leHBvcnQgY29uc3QganNvbkRpZmYgPSBuZXcgRGlmZigpO1xuLy8gRGlzY3JpbWluYXRlIGJldHdlZW4gdHdvIGxpbmVzIG9mIHByZXR0eS1wcmludGVkLCBzZXJpYWxpemVkIEpTT04gd2hlcmUgb25lIG9mIHRoZW0gaGFzIGFcbi8vIGRhbmdsaW5nIGNvbW1hIGFuZCB0aGUgb3RoZXIgZG9lc24ndC4gVHVybnMgb3V0IGluY2x1ZGluZyB0aGUgZGFuZ2xpbmcgY29tbWEgeWllbGRzIHRoZSBuaWNlc3Qgb3V0cHV0OlxuanNvbkRpZmYudXNlTG9uZ2VzdFRva2VuID0gdHJ1ZTtcblxuanNvbkRpZmYudG9rZW5pemUgPSBsaW5lRGlmZi50b2tlbml6ZTtcbmpzb25EaWZmLmNhc3RJbnB1dCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIGNvbnN0IHt1bmRlZmluZWRSZXBsYWNlbWVudH0gPSB0aGlzLm9wdGlvbnM7XG5cbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgPyB2YWx1ZSA6IEpTT04uc3RyaW5naWZ5KGNhbm9uaWNhbGl6ZSh2YWx1ZSksIGZ1bmN0aW9uKGssIHYpIHtcbiAgICBpZiAodHlwZW9mIHYgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkUmVwbGFjZW1lbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHY7XG4gIH0sICcgICcpO1xufTtcbmpzb25EaWZmLmVxdWFscyA9IGZ1bmN0aW9uKGxlZnQsIHJpZ2h0KSB7XG4gIHJldHVybiBEaWZmLnByb3RvdHlwZS5lcXVhbHMobGVmdC5yZXBsYWNlKC8sKFtcXHJcXG5dKS9nLCAnJDEnKSwgcmlnaHQucmVwbGFjZSgvLChbXFxyXFxuXSkvZywgJyQxJykpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZKc29uKG9sZE9iaiwgbmV3T2JqLCBvcHRpb25zKSB7IHJldHVybiBqc29uRGlmZi5kaWZmKG9sZE9iaiwgbmV3T2JqLCBvcHRpb25zKTsgfVxuXG4vLyBUaGlzIGZ1bmN0aW9uIGhhbmRsZXMgdGhlIHByZXNlbmNlIG9mIGNpcmN1bGFyIHJlZmVyZW5jZXMgYnkgYmFpbGluZyBvdXQgd2hlbiBlbmNvdW50ZXJpbmcgYW5cbi8vIG9iamVjdCB0aGF0IGlzIGFscmVhZHkgb24gdGhlIFwic3RhY2tcIiBvZiBpdGVtcyBiZWluZyBwcm9jZXNzZWQuXG5leHBvcnQgZnVuY3Rpb24gY2Fub25pY2FsaXplKG9iaiwgc3RhY2ssIHJlcGxhY2VtZW50U3RhY2spIHtcbiAgc3RhY2sgPSBzdGFjayB8fCBbXTtcbiAgcmVwbGFjZW1lbnRTdGFjayA9IHJlcGxhY2VtZW50U3RhY2sgfHwgW107XG5cbiAgbGV0IGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IHN0YWNrLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgaWYgKHN0YWNrW2ldID09PSBvYmopIHtcbiAgICAgIHJldHVybiByZXBsYWNlbWVudFN0YWNrW2ldO1xuICAgIH1cbiAgfVxuXG4gIGxldCBjYW5vbmljYWxpemVkT2JqO1xuXG4gIGlmICgnW29iamVjdCBBcnJheV0nID09PSBvYmplY3RQcm90b3R5cGVUb1N0cmluZy5jYWxsKG9iaikpIHtcbiAgICBzdGFjay5wdXNoKG9iaik7XG4gICAgY2Fub25pY2FsaXplZE9iaiA9IG5ldyBBcnJheShvYmoubGVuZ3RoKTtcbiAgICByZXBsYWNlbWVudFN0YWNrLnB1c2goY2Fub25pY2FsaXplZE9iaik7XG4gICAgZm9yIChpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY2Fub25pY2FsaXplZE9ialtpXSA9IGNhbm9uaWNhbGl6ZShvYmpbaV0sIHN0YWNrLCByZXBsYWNlbWVudFN0YWNrKTtcbiAgICB9XG4gICAgc3RhY2sucG9wKCk7XG4gICAgcmVwbGFjZW1lbnRTdGFjay5wb3AoKTtcbiAgICByZXR1cm4gY2Fub25pY2FsaXplZE9iajtcbiAgfVxuXG4gIGlmIChvYmogJiYgb2JqLnRvSlNPTikge1xuICAgIG9iaiA9IG9iai50b0pTT04oKTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogIT09IG51bGwpIHtcbiAgICBzdGFjay5wdXNoKG9iaik7XG4gICAgY2Fub25pY2FsaXplZE9iaiA9IHt9O1xuICAgIHJlcGxhY2VtZW50U3RhY2sucHVzaChjYW5vbmljYWxpemVkT2JqKTtcbiAgICBsZXQgc29ydGVkS2V5cyA9IFtdLFxuICAgICAgICBrZXk7XG4gICAgZm9yIChrZXkgaW4gb2JqKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgIHNvcnRlZEtleXMucHVzaChrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgICBzb3J0ZWRLZXlzLnNvcnQoKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgc29ydGVkS2V5cy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAga2V5ID0gc29ydGVkS2V5c1tpXTtcbiAgICAgIGNhbm9uaWNhbGl6ZWRPYmpba2V5XSA9IGNhbm9uaWNhbGl6ZShvYmpba2V5XSwgc3RhY2ssIHJlcGxhY2VtZW50U3RhY2spO1xuICAgIH1cbiAgICBzdGFjay5wb3AoKTtcbiAgICByZXBsYWNlbWVudFN0YWNrLnBvcCgpO1xuICB9IGVsc2Uge1xuICAgIGNhbm9uaWNhbGl6ZWRPYmogPSBvYmo7XG4gIH1cbiAgcmV0dXJuIGNhbm9uaWNhbGl6ZWRPYmo7XG59XG4iLCJpbXBvcnQgRGlmZiBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0IHtnZW5lcmF0ZU9wdGlvbnN9IGZyb20gJy4uL3V0aWwvcGFyYW1zJztcblxuZXhwb3J0IGNvbnN0IGxpbmVEaWZmID0gbmV3IERpZmYoKTtcbmxpbmVEaWZmLnRva2VuaXplID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgbGV0IHJldExpbmVzID0gW10sXG4gICAgICBsaW5lc0FuZE5ld2xpbmVzID0gdmFsdWUuc3BsaXQoLyhcXG58XFxyXFxuKS8pO1xuXG4gIC8vIElnbm9yZSB0aGUgZmluYWwgZW1wdHkgdG9rZW4gdGhhdCBvY2N1cnMgaWYgdGhlIHN0cmluZyBlbmRzIHdpdGggYSBuZXcgbGluZVxuICBpZiAoIWxpbmVzQW5kTmV3bGluZXNbbGluZXNBbmROZXdsaW5lcy5sZW5ndGggLSAxXSkge1xuICAgIGxpbmVzQW5kTmV3bGluZXMucG9wKCk7XG4gIH1cblxuICAvLyBNZXJnZSB0aGUgY29udGVudCBhbmQgbGluZSBzZXBhcmF0b3JzIGludG8gc2luZ2xlIHRva2Vuc1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzQW5kTmV3bGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgbGluZSA9IGxpbmVzQW5kTmV3bGluZXNbaV07XG5cbiAgICBpZiAoaSAlIDIgJiYgIXRoaXMub3B0aW9ucy5uZXdsaW5lSXNUb2tlbikge1xuICAgICAgcmV0TGluZXNbcmV0TGluZXMubGVuZ3RoIC0gMV0gKz0gbGluZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5pZ25vcmVXaGl0ZXNwYWNlKSB7XG4gICAgICAgIGxpbmUgPSBsaW5lLnRyaW0oKTtcbiAgICAgIH1cbiAgICAgIHJldExpbmVzLnB1c2gobGluZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJldExpbmVzO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZMaW5lcyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHsgcmV0dXJuIGxpbmVEaWZmLmRpZmYob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKTsgfVxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZUcmltbWVkTGluZXMob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKSB7XG4gIGxldCBvcHRpb25zID0gZ2VuZXJhdGVPcHRpb25zKGNhbGxiYWNrLCB7aWdub3JlV2hpdGVzcGFjZTogdHJ1ZX0pO1xuICByZXR1cm4gbGluZURpZmYuZGlmZihvbGRTdHIsIG5ld1N0ciwgb3B0aW9ucyk7XG59XG4iLCJpbXBvcnQgRGlmZiBmcm9tICcuL2Jhc2UnO1xuXG5cbmV4cG9ydCBjb25zdCBzZW50ZW5jZURpZmYgPSBuZXcgRGlmZigpO1xuc2VudGVuY2VEaWZmLnRva2VuaXplID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlLnNwbGl0KC8oXFxTLis/Wy4hP10pKD89XFxzK3wkKS8pO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZTZW50ZW5jZXMob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKSB7IHJldHVybiBzZW50ZW5jZURpZmYuZGlmZihvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spOyB9XG4iLCJpbXBvcnQgRGlmZiBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0IHtnZW5lcmF0ZU9wdGlvbnN9IGZyb20gJy4uL3V0aWwvcGFyYW1zJztcblxuLy8gQmFzZWQgb24gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGF0aW5fc2NyaXB0X2luX1VuaWNvZGVcbi8vXG4vLyBSYW5nZXMgYW5kIGV4Y2VwdGlvbnM6XG4vLyBMYXRpbi0xIFN1cHBsZW1lbnQsIDAwODDigJMwMEZGXG4vLyAgLSBVKzAwRDcgIMOXIE11bHRpcGxpY2F0aW9uIHNpZ25cbi8vICAtIFUrMDBGNyAgw7cgRGl2aXNpb24gc2lnblxuLy8gTGF0aW4gRXh0ZW5kZWQtQSwgMDEwMOKAkzAxN0Zcbi8vIExhdGluIEV4dGVuZGVkLUIsIDAxODDigJMwMjRGXG4vLyBJUEEgRXh0ZW5zaW9ucywgMDI1MOKAkzAyQUZcbi8vIFNwYWNpbmcgTW9kaWZpZXIgTGV0dGVycywgMDJCMOKAkzAyRkZcbi8vICAtIFUrMDJDNyAgy4cgJiM3MTE7ICBDYXJvblxuLy8gIC0gVSswMkQ4ICDLmCAmIzcyODsgIEJyZXZlXG4vLyAgLSBVKzAyRDkgIMuZICYjNzI5OyAgRG90IEFib3ZlXG4vLyAgLSBVKzAyREEgIMuaICYjNzMwOyAgUmluZyBBYm92ZVxuLy8gIC0gVSswMkRCICDLmyAmIzczMTsgIE9nb25la1xuLy8gIC0gVSswMkRDICDLnCAmIzczMjsgIFNtYWxsIFRpbGRlXG4vLyAgLSBVKzAyREQgIMudICYjNzMzOyAgRG91YmxlIEFjdXRlIEFjY2VudFxuLy8gTGF0aW4gRXh0ZW5kZWQgQWRkaXRpb25hbCwgMUUwMOKAkzFFRkZcbmNvbnN0IGV4dGVuZGVkV29yZENoYXJzID0gL15bYS16QS1aXFx1e0MwfS1cXHV7RkZ9XFx1e0Q4fS1cXHV7RjZ9XFx1e0Y4fS1cXHV7MkM2fVxcdXsyQzh9LVxcdXsyRDd9XFx1ezJERX0tXFx1ezJGRn1cXHV7MUUwMH0tXFx1ezFFRkZ9XSskL3U7XG5cbmNvbnN0IHJlV2hpdGVzcGFjZSA9IC9cXFMvO1xuXG5leHBvcnQgY29uc3Qgd29yZERpZmYgPSBuZXcgRGlmZigpO1xud29yZERpZmYuZXF1YWxzID0gZnVuY3Rpb24obGVmdCwgcmlnaHQpIHtcbiAgcmV0dXJuIGxlZnQgPT09IHJpZ2h0IHx8ICh0aGlzLm9wdGlvbnMuaWdub3JlV2hpdGVzcGFjZSAmJiAhcmVXaGl0ZXNwYWNlLnRlc3QobGVmdCkgJiYgIXJlV2hpdGVzcGFjZS50ZXN0KHJpZ2h0KSk7XG59O1xud29yZERpZmYudG9rZW5pemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICBsZXQgdG9rZW5zID0gdmFsdWUuc3BsaXQoLyhcXHMrfFxcYikvKTtcblxuICAvLyBKb2luIHRoZSBib3VuZGFyeSBzcGxpdHMgdGhhdCB3ZSBkbyBub3QgY29uc2lkZXIgdG8gYmUgYm91bmRhcmllcy4gVGhpcyBpcyBwcmltYXJpbHkgdGhlIGV4dGVuZGVkIExhdGluIGNoYXJhY3RlciBzZXQuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdG9rZW5zLmxlbmd0aCAtIDE7IGkrKykge1xuICAgIC8vIElmIHdlIGhhdmUgYW4gZW1wdHkgc3RyaW5nIGluIHRoZSBuZXh0IGZpZWxkIGFuZCB3ZSBoYXZlIG9ubHkgd29yZCBjaGFycyBiZWZvcmUgYW5kIGFmdGVyLCBtZXJnZVxuICAgIGlmICghdG9rZW5zW2kgKyAxXSAmJiB0b2tlbnNbaSArIDJdXG4gICAgICAgICAgJiYgZXh0ZW5kZWRXb3JkQ2hhcnMudGVzdCh0b2tlbnNbaV0pXG4gICAgICAgICAgJiYgZXh0ZW5kZWRXb3JkQ2hhcnMudGVzdCh0b2tlbnNbaSArIDJdKSkge1xuICAgICAgdG9rZW5zW2ldICs9IHRva2Vuc1tpICsgMl07XG4gICAgICB0b2tlbnMuc3BsaWNlKGkgKyAxLCAyKTtcbiAgICAgIGktLTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdG9rZW5zO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZXb3JkcyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHtcbiAgbGV0IG9wdGlvbnMgPSBnZW5lcmF0ZU9wdGlvbnMoY2FsbGJhY2ssIHtpZ25vcmVXaGl0ZXNwYWNlOiB0cnVlfSk7XG4gIHJldHVybiB3b3JkRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBvcHRpb25zKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBkaWZmV29yZHNXaXRoU3BhY2Uob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKSB7XG4gIHJldHVybiB3b3JkRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjayk7XG59XG4iLCIvKiBTZWUgTElDRU5TRSBmaWxlIGZvciB0ZXJtcyBvZiB1c2UgKi9cblxuLypcbiAqIFRleHQgZGlmZiBpbXBsZW1lbnRhdGlvbi5cbiAqXG4gKiBUaGlzIGxpYnJhcnkgc3VwcG9ydHMgdGhlIGZvbGxvd2luZyBBUElTOlxuICogSnNEaWZmLmRpZmZDaGFyczogQ2hhcmFjdGVyIGJ5IGNoYXJhY3RlciBkaWZmXG4gKiBKc0RpZmYuZGlmZldvcmRzOiBXb3JkIChhcyBkZWZpbmVkIGJ5IFxcYiByZWdleCkgZGlmZiB3aGljaCBpZ25vcmVzIHdoaXRlc3BhY2VcbiAqIEpzRGlmZi5kaWZmTGluZXM6IExpbmUgYmFzZWQgZGlmZlxuICpcbiAqIEpzRGlmZi5kaWZmQ3NzOiBEaWZmIHRhcmdldGVkIGF0IENTUyBjb250ZW50XG4gKlxuICogVGhlc2UgbWV0aG9kcyBhcmUgYmFzZWQgb24gdGhlIGltcGxlbWVudGF0aW9uIHByb3Bvc2VkIGluXG4gKiBcIkFuIE8oTkQpIERpZmZlcmVuY2UgQWxnb3JpdGhtIGFuZCBpdHMgVmFyaWF0aW9uc1wiIChNeWVycywgMTk4NikuXG4gKiBodHRwOi8vY2l0ZXNlZXJ4LmlzdC5wc3UuZWR1L3ZpZXdkb2Mvc3VtbWFyeT9kb2k9MTAuMS4xLjQuNjkyN1xuICovXG5pbXBvcnQgRGlmZiBmcm9tICcuL2RpZmYvYmFzZSc7XG5pbXBvcnQge2RpZmZDaGFyc30gZnJvbSAnLi9kaWZmL2NoYXJhY3Rlcic7XG5pbXBvcnQge2RpZmZXb3JkcywgZGlmZldvcmRzV2l0aFNwYWNlfSBmcm9tICcuL2RpZmYvd29yZCc7XG5pbXBvcnQge2RpZmZMaW5lcywgZGlmZlRyaW1tZWRMaW5lc30gZnJvbSAnLi9kaWZmL2xpbmUnO1xuaW1wb3J0IHtkaWZmU2VudGVuY2VzfSBmcm9tICcuL2RpZmYvc2VudGVuY2UnO1xuXG5pbXBvcnQge2RpZmZDc3N9IGZyb20gJy4vZGlmZi9jc3MnO1xuaW1wb3J0IHtkaWZmSnNvbiwgY2Fub25pY2FsaXplfSBmcm9tICcuL2RpZmYvanNvbic7XG5cbmltcG9ydCB7ZGlmZkFycmF5c30gZnJvbSAnLi9kaWZmL2FycmF5JztcblxuaW1wb3J0IHthcHBseVBhdGNoLCBhcHBseVBhdGNoZXN9IGZyb20gJy4vcGF0Y2gvYXBwbHknO1xuaW1wb3J0IHtwYXJzZVBhdGNofSBmcm9tICcuL3BhdGNoL3BhcnNlJztcbmltcG9ydCB7c3RydWN0dXJlZFBhdGNoLCBjcmVhdGVUd29GaWxlc1BhdGNoLCBjcmVhdGVQYXRjaH0gZnJvbSAnLi9wYXRjaC9jcmVhdGUnO1xuXG5pbXBvcnQge2NvbnZlcnRDaGFuZ2VzVG9ETVB9IGZyb20gJy4vY29udmVydC9kbXAnO1xuaW1wb3J0IHtjb252ZXJ0Q2hhbmdlc1RvWE1MfSBmcm9tICcuL2NvbnZlcnQveG1sJztcblxuZXhwb3J0IHtcbiAgRGlmZixcblxuICBkaWZmQ2hhcnMsXG4gIGRpZmZXb3JkcyxcbiAgZGlmZldvcmRzV2l0aFNwYWNlLFxuICBkaWZmTGluZXMsXG4gIGRpZmZUcmltbWVkTGluZXMsXG4gIGRpZmZTZW50ZW5jZXMsXG5cbiAgZGlmZkNzcyxcbiAgZGlmZkpzb24sXG5cbiAgZGlmZkFycmF5cyxcblxuICBzdHJ1Y3R1cmVkUGF0Y2gsXG4gIGNyZWF0ZVR3b0ZpbGVzUGF0Y2gsXG4gIGNyZWF0ZVBhdGNoLFxuICBhcHBseVBhdGNoLFxuICBhcHBseVBhdGNoZXMsXG4gIHBhcnNlUGF0Y2gsXG4gIGNvbnZlcnRDaGFuZ2VzVG9ETVAsXG4gIGNvbnZlcnRDaGFuZ2VzVG9YTUwsXG4gIGNhbm9uaWNhbGl6ZVxufTtcbiIsImltcG9ydCB7cGFyc2VQYXRjaH0gZnJvbSAnLi9wYXJzZSc7XG5pbXBvcnQgZGlzdGFuY2VJdGVyYXRvciBmcm9tICcuLi91dGlsL2Rpc3RhbmNlLWl0ZXJhdG9yJztcblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5UGF0Y2goc291cmNlLCB1bmlEaWZmLCBvcHRpb25zID0ge30pIHtcbiAgaWYgKHR5cGVvZiB1bmlEaWZmID09PSAnc3RyaW5nJykge1xuICAgIHVuaURpZmYgPSBwYXJzZVBhdGNoKHVuaURpZmYpO1xuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkodW5pRGlmZikpIHtcbiAgICBpZiAodW5pRGlmZi5sZW5ndGggPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FwcGx5UGF0Y2ggb25seSB3b3JrcyB3aXRoIGEgc2luZ2xlIGlucHV0LicpO1xuICAgIH1cblxuICAgIHVuaURpZmYgPSB1bmlEaWZmWzBdO1xuICB9XG5cbiAgLy8gQXBwbHkgdGhlIGRpZmYgdG8gdGhlIGlucHV0XG4gIGxldCBsaW5lcyA9IHNvdXJjZS5zcGxpdCgvXFxyXFxufFtcXG5cXHZcXGZcXHJcXHg4NV0vKSxcbiAgICAgIGRlbGltaXRlcnMgPSBzb3VyY2UubWF0Y2goL1xcclxcbnxbXFxuXFx2XFxmXFxyXFx4ODVdL2cpIHx8IFtdLFxuICAgICAgaHVua3MgPSB1bmlEaWZmLmh1bmtzLFxuXG4gICAgICBjb21wYXJlTGluZSA9IG9wdGlvbnMuY29tcGFyZUxpbmUgfHwgKChsaW5lTnVtYmVyLCBsaW5lLCBvcGVyYXRpb24sIHBhdGNoQ29udGVudCkgPT4gbGluZSA9PT0gcGF0Y2hDb250ZW50KSxcbiAgICAgIGVycm9yQ291bnQgPSAwLFxuICAgICAgZnV6ekZhY3RvciA9IG9wdGlvbnMuZnV6ekZhY3RvciB8fCAwLFxuICAgICAgbWluTGluZSA9IDAsXG4gICAgICBvZmZzZXQgPSAwLFxuXG4gICAgICByZW1vdmVFT0ZOTCxcbiAgICAgIGFkZEVPRk5MO1xuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGh1bmsgZXhhY3RseSBmaXRzIG9uIHRoZSBwcm92aWRlZCBsb2NhdGlvblxuICAgKi9cbiAgZnVuY3Rpb24gaHVua0ZpdHMoaHVuaywgdG9Qb3MpIHtcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGh1bmsubGluZXMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGxldCBsaW5lID0gaHVuay5saW5lc1tqXSxcbiAgICAgICAgICBvcGVyYXRpb24gPSBsaW5lWzBdLFxuICAgICAgICAgIGNvbnRlbnQgPSBsaW5lLnN1YnN0cigxKTtcblxuICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gJyAnIHx8IG9wZXJhdGlvbiA9PT0gJy0nKSB7XG4gICAgICAgIC8vIENvbnRleHQgc2FuaXR5IGNoZWNrXG4gICAgICAgIGlmICghY29tcGFyZUxpbmUodG9Qb3MgKyAxLCBsaW5lc1t0b1Bvc10sIG9wZXJhdGlvbiwgY29udGVudCkpIHtcbiAgICAgICAgICBlcnJvckNvdW50Kys7XG5cbiAgICAgICAgICBpZiAoZXJyb3JDb3VudCA+IGZ1enpGYWN0b3IpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdG9Qb3MrKztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIFNlYXJjaCBiZXN0IGZpdCBvZmZzZXRzIGZvciBlYWNoIGh1bmsgYmFzZWQgb24gdGhlIHByZXZpb3VzIG9uZXNcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBodW5rcy5sZW5ndGg7IGkrKykge1xuICAgIGxldCBodW5rID0gaHVua3NbaV0sXG4gICAgICAgIG1heExpbmUgPSBsaW5lcy5sZW5ndGggLSBodW5rLm9sZExpbmVzLFxuICAgICAgICBsb2NhbE9mZnNldCA9IDAsXG4gICAgICAgIHRvUG9zID0gb2Zmc2V0ICsgaHVuay5vbGRTdGFydCAtIDE7XG5cbiAgICBsZXQgaXRlcmF0b3IgPSBkaXN0YW5jZUl0ZXJhdG9yKHRvUG9zLCBtaW5MaW5lLCBtYXhMaW5lKTtcblxuICAgIGZvciAoOyBsb2NhbE9mZnNldCAhPT0gdW5kZWZpbmVkOyBsb2NhbE9mZnNldCA9IGl0ZXJhdG9yKCkpIHtcbiAgICAgIGlmIChodW5rRml0cyhodW5rLCB0b1BvcyArIGxvY2FsT2Zmc2V0KSkge1xuICAgICAgICBodW5rLm9mZnNldCA9IG9mZnNldCArPSBsb2NhbE9mZnNldDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGxvY2FsT2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBTZXQgbG93ZXIgdGV4dCBsaW1pdCB0byBlbmQgb2YgdGhlIGN1cnJlbnQgaHVuaywgc28gbmV4dCBvbmVzIGRvbid0IHRyeVxuICAgIC8vIHRvIGZpdCBvdmVyIGFscmVhZHkgcGF0Y2hlZCB0ZXh0XG4gICAgbWluTGluZSA9IGh1bmsub2Zmc2V0ICsgaHVuay5vbGRTdGFydCArIGh1bmsub2xkTGluZXM7XG4gIH1cblxuICAvLyBBcHBseSBwYXRjaCBodW5rc1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGh1bmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IGh1bmsgPSBodW5rc1tpXSxcbiAgICAgICAgdG9Qb3MgPSBodW5rLm9mZnNldCArIGh1bmsubmV3U3RhcnQgLSAxO1xuICAgIGlmIChodW5rLm5ld0xpbmVzID09IDApIHsgdG9Qb3MrKzsgfVxuXG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBodW5rLmxpbmVzLmxlbmd0aDsgaisrKSB7XG4gICAgICBsZXQgbGluZSA9IGh1bmsubGluZXNbal0sXG4gICAgICAgICAgb3BlcmF0aW9uID0gbGluZVswXSxcbiAgICAgICAgICBjb250ZW50ID0gbGluZS5zdWJzdHIoMSksXG4gICAgICAgICAgZGVsaW1pdGVyID0gaHVuay5saW5lZGVsaW1pdGVyc1tqXTtcblxuICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gJyAnKSB7XG4gICAgICAgIHRvUG9zKys7XG4gICAgICB9IGVsc2UgaWYgKG9wZXJhdGlvbiA9PT0gJy0nKSB7XG4gICAgICAgIGxpbmVzLnNwbGljZSh0b1BvcywgMSk7XG4gICAgICAgIGRlbGltaXRlcnMuc3BsaWNlKHRvUG9zLCAxKTtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICB9IGVsc2UgaWYgKG9wZXJhdGlvbiA9PT0gJysnKSB7XG4gICAgICAgIGxpbmVzLnNwbGljZSh0b1BvcywgMCwgY29udGVudCk7XG4gICAgICAgIGRlbGltaXRlcnMuc3BsaWNlKHRvUG9zLCAwLCBkZWxpbWl0ZXIpO1xuICAgICAgICB0b1BvcysrO1xuICAgICAgfSBlbHNlIGlmIChvcGVyYXRpb24gPT09ICdcXFxcJykge1xuICAgICAgICBsZXQgcHJldmlvdXNPcGVyYXRpb24gPSBodW5rLmxpbmVzW2ogLSAxXSA/IGh1bmsubGluZXNbaiAtIDFdWzBdIDogbnVsbDtcbiAgICAgICAgaWYgKHByZXZpb3VzT3BlcmF0aW9uID09PSAnKycpIHtcbiAgICAgICAgICByZW1vdmVFT0ZOTCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAocHJldmlvdXNPcGVyYXRpb24gPT09ICctJykge1xuICAgICAgICAgIGFkZEVPRk5MID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIEhhbmRsZSBFT0ZOTCBpbnNlcnRpb24vcmVtb3ZhbFxuICBpZiAocmVtb3ZlRU9GTkwpIHtcbiAgICB3aGlsZSAoIWxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdKSB7XG4gICAgICBsaW5lcy5wb3AoKTtcbiAgICAgIGRlbGltaXRlcnMucG9wKCk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGFkZEVPRk5MKSB7XG4gICAgbGluZXMucHVzaCgnJyk7XG4gICAgZGVsaW1pdGVycy5wdXNoKCdcXG4nKTtcbiAgfVxuICBmb3IgKGxldCBfayA9IDA7IF9rIDwgbGluZXMubGVuZ3RoIC0gMTsgX2srKykge1xuICAgIGxpbmVzW19rXSA9IGxpbmVzW19rXSArIGRlbGltaXRlcnNbX2tdO1xuICB9XG4gIHJldHVybiBsaW5lcy5qb2luKCcnKTtcbn1cblxuLy8gV3JhcHBlciB0aGF0IHN1cHBvcnRzIG11bHRpcGxlIGZpbGUgcGF0Y2hlcyB2aWEgY2FsbGJhY2tzLlxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5UGF0Y2hlcyh1bmlEaWZmLCBvcHRpb25zKSB7XG4gIGlmICh0eXBlb2YgdW5pRGlmZiA9PT0gJ3N0cmluZycpIHtcbiAgICB1bmlEaWZmID0gcGFyc2VQYXRjaCh1bmlEaWZmKTtcbiAgfVxuXG4gIGxldCBjdXJyZW50SW5kZXggPSAwO1xuICBmdW5jdGlvbiBwcm9jZXNzSW5kZXgoKSB7XG4gICAgbGV0IGluZGV4ID0gdW5pRGlmZltjdXJyZW50SW5kZXgrK107XG4gICAgaWYgKCFpbmRleCkge1xuICAgICAgcmV0dXJuIG9wdGlvbnMuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICBvcHRpb25zLmxvYWRGaWxlKGluZGV4LCBmdW5jdGlvbihlcnIsIGRhdGEpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMuY29tcGxldGUoZXJyKTtcbiAgICAgIH1cblxuICAgICAgbGV0IHVwZGF0ZWRDb250ZW50ID0gYXBwbHlQYXRjaChkYXRhLCBpbmRleCwgb3B0aW9ucyk7XG4gICAgICBvcHRpb25zLnBhdGNoZWQoaW5kZXgsIHVwZGF0ZWRDb250ZW50LCBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIHJldHVybiBvcHRpb25zLmNvbXBsZXRlKGVycik7XG4gICAgICAgIH1cblxuICAgICAgICBwcm9jZXNzSW5kZXgoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIHByb2Nlc3NJbmRleCgpO1xufVxuIiwiaW1wb3J0IHtkaWZmTGluZXN9IGZyb20gJy4uL2RpZmYvbGluZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBzdHJ1Y3R1cmVkUGF0Y2gob2xkRmlsZU5hbWUsIG5ld0ZpbGVOYW1lLCBvbGRTdHIsIG5ld1N0ciwgb2xkSGVhZGVyLCBuZXdIZWFkZXIsIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5jb250ZXh0ID09PSAndW5kZWZpbmVkJykge1xuICAgIG9wdGlvbnMuY29udGV4dCA9IDQ7XG4gIH1cblxuICBjb25zdCBkaWZmID0gZGlmZkxpbmVzKG9sZFN0ciwgbmV3U3RyLCBvcHRpb25zKTtcbiAgZGlmZi5wdXNoKHt2YWx1ZTogJycsIGxpbmVzOiBbXX0pOyAgIC8vIEFwcGVuZCBhbiBlbXB0eSB2YWx1ZSB0byBtYWtlIGNsZWFudXAgZWFzaWVyXG5cbiAgZnVuY3Rpb24gY29udGV4dExpbmVzKGxpbmVzKSB7XG4gICAgcmV0dXJuIGxpbmVzLm1hcChmdW5jdGlvbihlbnRyeSkgeyByZXR1cm4gJyAnICsgZW50cnk7IH0pO1xuICB9XG5cbiAgbGV0IGh1bmtzID0gW107XG4gIGxldCBvbGRSYW5nZVN0YXJ0ID0gMCwgbmV3UmFuZ2VTdGFydCA9IDAsIGN1clJhbmdlID0gW10sXG4gICAgICBvbGRMaW5lID0gMSwgbmV3TGluZSA9IDE7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGlmZi5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBkaWZmW2ldLFxuICAgICAgICAgIGxpbmVzID0gY3VycmVudC5saW5lcyB8fCBjdXJyZW50LnZhbHVlLnJlcGxhY2UoL1xcbiQvLCAnJykuc3BsaXQoJ1xcbicpO1xuICAgIGN1cnJlbnQubGluZXMgPSBsaW5lcztcblxuICAgIGlmIChjdXJyZW50LmFkZGVkIHx8IGN1cnJlbnQucmVtb3ZlZCkge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBwcmV2aW91cyBjb250ZXh0LCBzdGFydCB3aXRoIHRoYXRcbiAgICAgIGlmICghb2xkUmFuZ2VTdGFydCkge1xuICAgICAgICBjb25zdCBwcmV2ID0gZGlmZltpIC0gMV07XG4gICAgICAgIG9sZFJhbmdlU3RhcnQgPSBvbGRMaW5lO1xuICAgICAgICBuZXdSYW5nZVN0YXJ0ID0gbmV3TGluZTtcblxuICAgICAgICBpZiAocHJldikge1xuICAgICAgICAgIGN1clJhbmdlID0gb3B0aW9ucy5jb250ZXh0ID4gMCA/IGNvbnRleHRMaW5lcyhwcmV2LmxpbmVzLnNsaWNlKC1vcHRpb25zLmNvbnRleHQpKSA6IFtdO1xuICAgICAgICAgIG9sZFJhbmdlU3RhcnQgLT0gY3VyUmFuZ2UubGVuZ3RoO1xuICAgICAgICAgIG5ld1JhbmdlU3RhcnQgLT0gY3VyUmFuZ2UubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE91dHB1dCBvdXIgY2hhbmdlc1xuICAgICAgY3VyUmFuZ2UucHVzaCguLi4gbGluZXMubWFwKGZ1bmN0aW9uKGVudHJ5KSB7XG4gICAgICAgIHJldHVybiAoY3VycmVudC5hZGRlZCA/ICcrJyA6ICctJykgKyBlbnRyeTtcbiAgICAgIH0pKTtcblxuICAgICAgLy8gVHJhY2sgdGhlIHVwZGF0ZWQgZmlsZSBwb3NpdGlvblxuICAgICAgaWYgKGN1cnJlbnQuYWRkZWQpIHtcbiAgICAgICAgbmV3TGluZSArPSBsaW5lcy5sZW5ndGg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvbGRMaW5lICs9IGxpbmVzLmxlbmd0aDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWRlbnRpY2FsIGNvbnRleHQgbGluZXMuIFRyYWNrIGxpbmUgY2hhbmdlc1xuICAgICAgaWYgKG9sZFJhbmdlU3RhcnQpIHtcbiAgICAgICAgLy8gQ2xvc2Ugb3V0IGFueSBjaGFuZ2VzIHRoYXQgaGF2ZSBiZWVuIG91dHB1dCAob3Igam9pbiBvdmVybGFwcGluZylcbiAgICAgICAgaWYgKGxpbmVzLmxlbmd0aCA8PSBvcHRpb25zLmNvbnRleHQgKiAyICYmIGkgPCBkaWZmLmxlbmd0aCAtIDIpIHtcbiAgICAgICAgICAvLyBPdmVybGFwcGluZ1xuICAgICAgICAgIGN1clJhbmdlLnB1c2goLi4uIGNvbnRleHRMaW5lcyhsaW5lcykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGVuZCB0aGUgcmFuZ2UgYW5kIG91dHB1dFxuICAgICAgICAgIGxldCBjb250ZXh0U2l6ZSA9IE1hdGgubWluKGxpbmVzLmxlbmd0aCwgb3B0aW9ucy5jb250ZXh0KTtcbiAgICAgICAgICBjdXJSYW5nZS5wdXNoKC4uLiBjb250ZXh0TGluZXMobGluZXMuc2xpY2UoMCwgY29udGV4dFNpemUpKSk7XG5cbiAgICAgICAgICBsZXQgaHVuayA9IHtcbiAgICAgICAgICAgIG9sZFN0YXJ0OiBvbGRSYW5nZVN0YXJ0LFxuICAgICAgICAgICAgb2xkTGluZXM6IChvbGRMaW5lIC0gb2xkUmFuZ2VTdGFydCArIGNvbnRleHRTaXplKSxcbiAgICAgICAgICAgIG5ld1N0YXJ0OiBuZXdSYW5nZVN0YXJ0LFxuICAgICAgICAgICAgbmV3TGluZXM6IChuZXdMaW5lIC0gbmV3UmFuZ2VTdGFydCArIGNvbnRleHRTaXplKSxcbiAgICAgICAgICAgIGxpbmVzOiBjdXJSYW5nZVxuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKGkgPj0gZGlmZi5sZW5ndGggLSAyICYmIGxpbmVzLmxlbmd0aCA8PSBvcHRpb25zLmNvbnRleHQpIHtcbiAgICAgICAgICAgIC8vIEVPRiBpcyBpbnNpZGUgdGhpcyBodW5rXG4gICAgICAgICAgICBsZXQgb2xkRU9GTmV3bGluZSA9ICgvXFxuJC8udGVzdChvbGRTdHIpKTtcbiAgICAgICAgICAgIGxldCBuZXdFT0ZOZXdsaW5lID0gKC9cXG4kLy50ZXN0KG5ld1N0cikpO1xuICAgICAgICAgICAgaWYgKGxpbmVzLmxlbmd0aCA9PSAwICYmICFvbGRFT0ZOZXdsaW5lKSB7XG4gICAgICAgICAgICAgIC8vIHNwZWNpYWwgY2FzZTogb2xkIGhhcyBubyBlb2wgYW5kIG5vIHRyYWlsaW5nIGNvbnRleHQ7IG5vLW5sIGNhbiBlbmQgdXAgYmVmb3JlIGFkZHNcbiAgICAgICAgICAgICAgY3VyUmFuZ2Uuc3BsaWNlKGh1bmsub2xkTGluZXMsIDAsICdcXFxcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUnKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIW9sZEVPRk5ld2xpbmUgfHwgIW5ld0VPRk5ld2xpbmUpIHtcbiAgICAgICAgICAgICAgY3VyUmFuZ2UucHVzaCgnXFxcXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGh1bmtzLnB1c2goaHVuayk7XG5cbiAgICAgICAgICBvbGRSYW5nZVN0YXJ0ID0gMDtcbiAgICAgICAgICBuZXdSYW5nZVN0YXJ0ID0gMDtcbiAgICAgICAgICBjdXJSYW5nZSA9IFtdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBvbGRMaW5lICs9IGxpbmVzLmxlbmd0aDtcbiAgICAgIG5ld0xpbmUgKz0gbGluZXMubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgb2xkRmlsZU5hbWU6IG9sZEZpbGVOYW1lLCBuZXdGaWxlTmFtZTogbmV3RmlsZU5hbWUsXG4gICAgb2xkSGVhZGVyOiBvbGRIZWFkZXIsIG5ld0hlYWRlcjogbmV3SGVhZGVyLFxuICAgIGh1bmtzOiBodW5rc1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlVHdvRmlsZXNQYXRjaChvbGRGaWxlTmFtZSwgbmV3RmlsZU5hbWUsIG9sZFN0ciwgbmV3U3RyLCBvbGRIZWFkZXIsIG5ld0hlYWRlciwgb3B0aW9ucykge1xuICBjb25zdCBkaWZmID0gc3RydWN0dXJlZFBhdGNoKG9sZEZpbGVOYW1lLCBuZXdGaWxlTmFtZSwgb2xkU3RyLCBuZXdTdHIsIG9sZEhlYWRlciwgbmV3SGVhZGVyLCBvcHRpb25zKTtcblxuICBjb25zdCByZXQgPSBbXTtcbiAgaWYgKG9sZEZpbGVOYW1lID09IG5ld0ZpbGVOYW1lKSB7XG4gICAgcmV0LnB1c2goJ0luZGV4OiAnICsgb2xkRmlsZU5hbWUpO1xuICB9XG4gIHJldC5wdXNoKCc9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Jyk7XG4gIHJldC5wdXNoKCctLS0gJyArIGRpZmYub2xkRmlsZU5hbWUgKyAodHlwZW9mIGRpZmYub2xkSGVhZGVyID09PSAndW5kZWZpbmVkJyA/ICcnIDogJ1xcdCcgKyBkaWZmLm9sZEhlYWRlcikpO1xuICByZXQucHVzaCgnKysrICcgKyBkaWZmLm5ld0ZpbGVOYW1lICsgKHR5cGVvZiBkaWZmLm5ld0hlYWRlciA9PT0gJ3VuZGVmaW5lZCcgPyAnJyA6ICdcXHQnICsgZGlmZi5uZXdIZWFkZXIpKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGRpZmYuaHVua3MubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBodW5rID0gZGlmZi5odW5rc1tpXTtcbiAgICByZXQucHVzaChcbiAgICAgICdAQCAtJyArIGh1bmsub2xkU3RhcnQgKyAnLCcgKyBodW5rLm9sZExpbmVzXG4gICAgICArICcgKycgKyBodW5rLm5ld1N0YXJ0ICsgJywnICsgaHVuay5uZXdMaW5lc1xuICAgICAgKyAnIEBAJ1xuICAgICk7XG4gICAgcmV0LnB1c2guYXBwbHkocmV0LCBodW5rLmxpbmVzKTtcbiAgfVxuXG4gIHJldHVybiByZXQuam9pbignXFxuJykgKyAnXFxuJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVBhdGNoKGZpbGVOYW1lLCBvbGRTdHIsIG5ld1N0ciwgb2xkSGVhZGVyLCBuZXdIZWFkZXIsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGNyZWF0ZVR3b0ZpbGVzUGF0Y2goZmlsZU5hbWUsIGZpbGVOYW1lLCBvbGRTdHIsIG5ld1N0ciwgb2xkSGVhZGVyLCBuZXdIZWFkZXIsIG9wdGlvbnMpO1xufVxuIiwiZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUGF0Y2godW5pRGlmZiwgb3B0aW9ucyA9IHt9KSB7XG4gIGxldCBkaWZmc3RyID0gdW5pRGlmZi5zcGxpdCgvXFxyXFxufFtcXG5cXHZcXGZcXHJcXHg4NV0vKSxcbiAgICAgIGRlbGltaXRlcnMgPSB1bmlEaWZmLm1hdGNoKC9cXHJcXG58W1xcblxcdlxcZlxcclxceDg1XS9nKSB8fCBbXSxcbiAgICAgIGxpc3QgPSBbXSxcbiAgICAgIGkgPSAwO1xuXG4gIGZ1bmN0aW9uIHBhcnNlSW5kZXgoKSB7XG4gICAgbGV0IGluZGV4ID0ge307XG4gICAgbGlzdC5wdXNoKGluZGV4KTtcblxuICAgIC8vIFBhcnNlIGRpZmYgbWV0YWRhdGFcbiAgICB3aGlsZSAoaSA8IGRpZmZzdHIubGVuZ3RoKSB7XG4gICAgICBsZXQgbGluZSA9IGRpZmZzdHJbaV07XG5cbiAgICAgIC8vIEZpbGUgaGVhZGVyIGZvdW5kLCBlbmQgcGFyc2luZyBkaWZmIG1ldGFkYXRhXG4gICAgICBpZiAoL14oXFwtXFwtXFwtfFxcK1xcK1xcK3xAQClcXHMvLnRlc3QobGluZSkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIC8vIERpZmYgaW5kZXhcbiAgICAgIGxldCBoZWFkZXIgPSAoL14oPzpJbmRleDp8ZGlmZig/OiAtciBcXHcrKSspXFxzKyguKz8pXFxzKiQvKS5leGVjKGxpbmUpO1xuICAgICAgaWYgKGhlYWRlcikge1xuICAgICAgICBpbmRleC5pbmRleCA9IGhlYWRlclsxXTtcbiAgICAgIH1cblxuICAgICAgaSsrO1xuICAgIH1cblxuICAgIC8vIFBhcnNlIGZpbGUgaGVhZGVycyBpZiB0aGV5IGFyZSBkZWZpbmVkLiBVbmlmaWVkIGRpZmYgcmVxdWlyZXMgdGhlbSwgYnV0XG4gICAgLy8gdGhlcmUncyBubyB0ZWNobmljYWwgaXNzdWVzIHRvIGhhdmUgYW4gaXNvbGF0ZWQgaHVuayB3aXRob3V0IGZpbGUgaGVhZGVyXG4gICAgcGFyc2VGaWxlSGVhZGVyKGluZGV4KTtcbiAgICBwYXJzZUZpbGVIZWFkZXIoaW5kZXgpO1xuXG4gICAgLy8gUGFyc2UgaHVua3NcbiAgICBpbmRleC5odW5rcyA9IFtdO1xuXG4gICAgd2hpbGUgKGkgPCBkaWZmc3RyLmxlbmd0aCkge1xuICAgICAgbGV0IGxpbmUgPSBkaWZmc3RyW2ldO1xuXG4gICAgICBpZiAoL14oSW5kZXg6fGRpZmZ8XFwtXFwtXFwtfFxcK1xcK1xcKylcXHMvLnRlc3QobGluZSkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IGVsc2UgaWYgKC9eQEAvLnRlc3QobGluZSkpIHtcbiAgICAgICAgaW5kZXguaHVua3MucHVzaChwYXJzZUh1bmsoKSk7XG4gICAgICB9IGVsc2UgaWYgKGxpbmUgJiYgb3B0aW9ucy5zdHJpY3QpIHtcbiAgICAgICAgLy8gSWdub3JlIHVuZXhwZWN0ZWQgY29udGVudCB1bmxlc3MgaW4gc3RyaWN0IG1vZGVcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGxpbmUgJyArIChpICsgMSkgKyAnICcgKyBKU09OLnN0cmluZ2lmeShsaW5lKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpKys7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gUGFyc2VzIHRoZSAtLS0gYW5kICsrKyBoZWFkZXJzLCBpZiBub25lIGFyZSBmb3VuZCwgbm8gbGluZXNcbiAgLy8gYXJlIGNvbnN1bWVkLlxuICBmdW5jdGlvbiBwYXJzZUZpbGVIZWFkZXIoaW5kZXgpIHtcbiAgICBjb25zdCBoZWFkZXJQYXR0ZXJuID0gL14oLS0tfFxcK1xcK1xcKylcXHMrKFtcXFMgXSopKD86XFx0KC4qPylcXHMqKT8kLztcbiAgICBjb25zdCBmaWxlSGVhZGVyID0gaGVhZGVyUGF0dGVybi5leGVjKGRpZmZzdHJbaV0pO1xuICAgIGlmIChmaWxlSGVhZGVyKSB7XG4gICAgICBsZXQga2V5UHJlZml4ID0gZmlsZUhlYWRlclsxXSA9PT0gJy0tLScgPyAnb2xkJyA6ICduZXcnO1xuICAgICAgaW5kZXhba2V5UHJlZml4ICsgJ0ZpbGVOYW1lJ10gPSBmaWxlSGVhZGVyWzJdO1xuICAgICAgaW5kZXhba2V5UHJlZml4ICsgJ0hlYWRlciddID0gZmlsZUhlYWRlclszXTtcblxuICAgICAgaSsrO1xuICAgIH1cbiAgfVxuXG4gIC8vIFBhcnNlcyBhIGh1bmtcbiAgLy8gVGhpcyBhc3N1bWVzIHRoYXQgd2UgYXJlIGF0IHRoZSBzdGFydCBvZiBhIGh1bmsuXG4gIGZ1bmN0aW9uIHBhcnNlSHVuaygpIHtcbiAgICBsZXQgY2h1bmtIZWFkZXJJbmRleCA9IGksXG4gICAgICAgIGNodW5rSGVhZGVyTGluZSA9IGRpZmZzdHJbaSsrXSxcbiAgICAgICAgY2h1bmtIZWFkZXIgPSBjaHVua0hlYWRlckxpbmUuc3BsaXQoL0BAIC0oXFxkKykoPzosKFxcZCspKT8gXFwrKFxcZCspKD86LChcXGQrKSk/IEBALyk7XG5cbiAgICBsZXQgaHVuayA9IHtcbiAgICAgIG9sZFN0YXJ0OiArY2h1bmtIZWFkZXJbMV0sXG4gICAgICBvbGRMaW5lczogK2NodW5rSGVhZGVyWzJdIHx8IDEsXG4gICAgICBuZXdTdGFydDogK2NodW5rSGVhZGVyWzNdLFxuICAgICAgbmV3TGluZXM6ICtjaHVua0hlYWRlcls0XSB8fCAxLFxuICAgICAgbGluZXM6IFtdLFxuICAgICAgbGluZWRlbGltaXRlcnM6IFtdXG4gICAgfTtcblxuICAgIGxldCBhZGRDb3VudCA9IDAsXG4gICAgICAgIHJlbW92ZUNvdW50ID0gMDtcbiAgICBmb3IgKDsgaSA8IGRpZmZzdHIubGVuZ3RoOyBpKyspIHtcbiAgICAgIC8vIExpbmVzIHN0YXJ0aW5nIHdpdGggJy0tLScgY291bGQgYmUgbWlzdGFrZW4gZm9yIHRoZSBcInJlbW92ZSBsaW5lXCIgb3BlcmF0aW9uXG4gICAgICAvLyBCdXQgdGhleSBjb3VsZCBiZSB0aGUgaGVhZGVyIGZvciB0aGUgbmV4dCBmaWxlLiBUaGVyZWZvcmUgcHJ1bmUgc3VjaCBjYXNlcyBvdXQuXG4gICAgICBpZiAoZGlmZnN0cltpXS5pbmRleE9mKCctLS0gJykgPT09IDBcbiAgICAgICAgICAgICYmIChpICsgMiA8IGRpZmZzdHIubGVuZ3RoKVxuICAgICAgICAgICAgJiYgZGlmZnN0cltpICsgMV0uaW5kZXhPZignKysrICcpID09PSAwXG4gICAgICAgICAgICAmJiBkaWZmc3RyW2kgKyAyXS5pbmRleE9mKCdAQCcpID09PSAwKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBsZXQgb3BlcmF0aW9uID0gZGlmZnN0cltpXVswXTtcblxuICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gJysnIHx8IG9wZXJhdGlvbiA9PT0gJy0nIHx8IG9wZXJhdGlvbiA9PT0gJyAnIHx8IG9wZXJhdGlvbiA9PT0gJ1xcXFwnKSB7XG4gICAgICAgIGh1bmsubGluZXMucHVzaChkaWZmc3RyW2ldKTtcbiAgICAgICAgaHVuay5saW5lZGVsaW1pdGVycy5wdXNoKGRlbGltaXRlcnNbaV0gfHwgJ1xcbicpO1xuXG4gICAgICAgIGlmIChvcGVyYXRpb24gPT09ICcrJykge1xuICAgICAgICAgIGFkZENvdW50Kys7XG4gICAgICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uID09PSAnLScpIHtcbiAgICAgICAgICByZW1vdmVDb3VudCsrO1xuICAgICAgICB9IGVsc2UgaWYgKG9wZXJhdGlvbiA9PT0gJyAnKSB7XG4gICAgICAgICAgYWRkQ291bnQrKztcbiAgICAgICAgICByZW1vdmVDb3VudCsrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgdGhlIGVtcHR5IGJsb2NrIGNvdW50IGNhc2VcbiAgICBpZiAoIWFkZENvdW50ICYmIGh1bmsubmV3TGluZXMgPT09IDEpIHtcbiAgICAgIGh1bmsubmV3TGluZXMgPSAwO1xuICAgIH1cbiAgICBpZiAoIXJlbW92ZUNvdW50ICYmIGh1bmsub2xkTGluZXMgPT09IDEpIHtcbiAgICAgIGh1bmsub2xkTGluZXMgPSAwO1xuICAgIH1cblxuICAgIC8vIFBlcmZvcm0gb3B0aW9uYWwgc2FuaXR5IGNoZWNraW5nXG4gICAgaWYgKG9wdGlvbnMuc3RyaWN0KSB7XG4gICAgICBpZiAoYWRkQ291bnQgIT09IGh1bmsubmV3TGluZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBZGRlZCBsaW5lIGNvdW50IGRpZCBub3QgbWF0Y2ggZm9yIGh1bmsgYXQgbGluZSAnICsgKGNodW5rSGVhZGVySW5kZXggKyAxKSk7XG4gICAgICB9XG4gICAgICBpZiAocmVtb3ZlQ291bnQgIT09IGh1bmsub2xkTGluZXMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZW1vdmVkIGxpbmUgY291bnQgZGlkIG5vdCBtYXRjaCBmb3IgaHVuayBhdCBsaW5lICcgKyAoY2h1bmtIZWFkZXJJbmRleCArIDEpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaHVuaztcbiAgfVxuXG4gIHdoaWxlIChpIDwgZGlmZnN0ci5sZW5ndGgpIHtcbiAgICBwYXJzZUluZGV4KCk7XG4gIH1cblxuICByZXR1cm4gbGlzdDtcbn1cbiIsIi8vIEl0ZXJhdG9yIHRoYXQgdHJhdmVyc2VzIGluIHRoZSByYW5nZSBvZiBbbWluLCBtYXhdLCBzdGVwcGluZ1xuLy8gYnkgZGlzdGFuY2UgZnJvbSBhIGdpdmVuIHN0YXJ0IHBvc2l0aW9uLiBJLmUuIGZvciBbMCwgNF0sIHdpdGhcbi8vIHN0YXJ0IG9mIDIsIHRoaXMgd2lsbCBpdGVyYXRlIDIsIDMsIDEsIDQsIDAuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbihzdGFydCwgbWluTGluZSwgbWF4TGluZSkge1xuICBsZXQgd2FudEZvcndhcmQgPSB0cnVlLFxuICAgICAgYmFja3dhcmRFeGhhdXN0ZWQgPSBmYWxzZSxcbiAgICAgIGZvcndhcmRFeGhhdXN0ZWQgPSBmYWxzZSxcbiAgICAgIGxvY2FsT2Zmc2V0ID0gMTtcblxuICByZXR1cm4gZnVuY3Rpb24gaXRlcmF0b3IoKSB7XG4gICAgaWYgKHdhbnRGb3J3YXJkICYmICFmb3J3YXJkRXhoYXVzdGVkKSB7XG4gICAgICBpZiAoYmFja3dhcmRFeGhhdXN0ZWQpIHtcbiAgICAgICAgbG9jYWxPZmZzZXQrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdhbnRGb3J3YXJkID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGlmIHRyeWluZyB0byBmaXQgYmV5b25kIHRleHQgbGVuZ3RoLCBhbmQgaWYgbm90LCBjaGVjayBpdCBmaXRzXG4gICAgICAvLyBhZnRlciBvZmZzZXQgbG9jYXRpb24gKG9yIGRlc2lyZWQgbG9jYXRpb24gb24gZmlyc3QgaXRlcmF0aW9uKVxuICAgICAgaWYgKHN0YXJ0ICsgbG9jYWxPZmZzZXQgPD0gbWF4TGluZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxPZmZzZXQ7XG4gICAgICB9XG5cbiAgICAgIGZvcndhcmRFeGhhdXN0ZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICghYmFja3dhcmRFeGhhdXN0ZWQpIHtcbiAgICAgIGlmICghZm9yd2FyZEV4aGF1c3RlZCkge1xuICAgICAgICB3YW50Rm9yd2FyZCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGlmIHRyeWluZyB0byBmaXQgYmVmb3JlIHRleHQgYmVnaW5uaW5nLCBhbmQgaWYgbm90LCBjaGVjayBpdCBmaXRzXG4gICAgICAvLyBiZWZvcmUgb2Zmc2V0IGxvY2F0aW9uXG4gICAgICBpZiAobWluTGluZSA8PSBzdGFydCAtIGxvY2FsT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiAtbG9jYWxPZmZzZXQrKztcbiAgICAgIH1cblxuICAgICAgYmFja3dhcmRFeGhhdXN0ZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIGl0ZXJhdG9yKCk7XG4gICAgfVxuXG4gICAgLy8gV2UgdHJpZWQgdG8gZml0IGh1bmsgYmVmb3JlIHRleHQgYmVnaW5uaW5nIGFuZCBiZXlvbmQgdGV4dCBsZW5naHQsIHRoZW5cbiAgICAvLyBodW5rIGNhbid0IGZpdCBvbiB0aGUgdGV4dC4gUmV0dXJuIHVuZGVmaW5lZFxuICB9O1xufVxuIiwiZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlT3B0aW9ucyhvcHRpb25zLCBkZWZhdWx0cykge1xuICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBkZWZhdWx0cy5jYWxsYmFjayA9IG9wdGlvbnM7XG4gIH0gZWxzZSBpZiAob3B0aW9ucykge1xuICAgIGZvciAobGV0IG5hbWUgaW4gb3B0aW9ucykge1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgIGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgIGRlZmF1bHRzW25hbWVdID0gb3B0aW9uc1tuYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRlZmF1bHRzO1xufVxuIiwiXG52YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZm9yRWFjaCAob2JqLCBmbiwgY3R4KSB7XG4gICAgaWYgKHRvU3RyaW5nLmNhbGwoZm4pICE9PSAnW29iamVjdCBGdW5jdGlvbl0nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2l0ZXJhdG9yIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgIH1cbiAgICB2YXIgbCA9IG9iai5sZW5ndGg7XG4gICAgaWYgKGwgPT09ICtsKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICBmbi5jYWxsKGN0eCwgb2JqW2ldLCBpLCBvYmopO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZm9yICh2YXIgayBpbiBvYmopIHtcbiAgICAgICAgICAgIGlmIChoYXNPd24uY2FsbChvYmosIGspKSB7XG4gICAgICAgICAgICAgICAgZm4uY2FsbChjdHgsIG9ialtrXSwgaywgb2JqKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn07XG5cbiIsIlxudmFyIGluZGV4T2YgPSBbXS5pbmRleE9mO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGFyciwgb2JqKXtcbiAgaWYgKGluZGV4T2YpIHJldHVybiBhcnIuaW5kZXhPZihvYmopO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7ICsraSkge1xuICAgIGlmIChhcnJbaV0gPT09IG9iaikgcmV0dXJuIGk7XG4gIH1cbiAgcmV0dXJuIC0xO1xufTsiLCJtb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFycikgPT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG52YXIgaXNGdW5jdGlvbiA9IGZ1bmN0aW9uIChmbikge1xuXHRyZXR1cm4gKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJyAmJiAhKGZuIGluc3RhbmNlb2YgUmVnRXhwKSkgfHwgdG9TdHJpbmcuY2FsbChmbikgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZvckVhY2gob2JqLCBmbikge1xuXHRpZiAoIWlzRnVuY3Rpb24oZm4pKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignaXRlcmF0b3IgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdH1cblx0dmFyIGksIGssXG5cdFx0aXNTdHJpbmcgPSB0eXBlb2Ygb2JqID09PSAnc3RyaW5nJyxcblx0XHRsID0gb2JqLmxlbmd0aCxcblx0XHRjb250ZXh0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgPyBhcmd1bWVudHNbMl0gOiBudWxsO1xuXHRpZiAobCA9PT0gK2wpIHtcblx0XHRmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG5cdFx0XHRpZiAoY29udGV4dCA9PT0gbnVsbCkge1xuXHRcdFx0XHRmbihpc1N0cmluZyA/IG9iai5jaGFyQXQoaSkgOiBvYmpbaV0sIGksIG9iaik7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmbi5jYWxsKGNvbnRleHQsIGlzU3RyaW5nID8gb2JqLmNoYXJBdChpKSA6IG9ialtpXSwgaSwgb2JqKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0Zm9yIChrIGluIG9iaikge1xuXHRcdFx0aWYgKGhhc093bi5jYWxsKG9iaiwgaykpIHtcblx0XHRcdFx0aWYgKGNvbnRleHQgPT09IG51bGwpIHtcblx0XHRcdFx0XHRmbihvYmpba10sIGssIG9iaik7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Zm4uY2FsbChjb250ZXh0LCBvYmpba10sIGssIG9iaik7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbiIsIlwidXNlIHN0cmljdFwiO1xuXG4vLyBtb2RpZmllZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9lcy1zaGltcy9lczUtc2hpbVxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksXG5cdHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyxcblx0Zm9yRWFjaCA9IHJlcXVpcmUoJy4vZm9yZWFjaCcpLFxuXHRpc0FyZ3MgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyksXG5cdGhhc0RvbnRFbnVtQnVnID0gISh7J3RvU3RyaW5nJzogbnVsbH0pLnByb3BlcnR5SXNFbnVtZXJhYmxlKCd0b1N0cmluZycpLFxuXHRoYXNQcm90b0VudW1CdWcgPSAoZnVuY3Rpb24gKCkge30pLnByb3BlcnR5SXNFbnVtZXJhYmxlKCdwcm90b3R5cGUnKSxcblx0ZG9udEVudW1zID0gW1xuXHRcdFwidG9TdHJpbmdcIixcblx0XHRcInRvTG9jYWxlU3RyaW5nXCIsXG5cdFx0XCJ2YWx1ZU9mXCIsXG5cdFx0XCJoYXNPd25Qcm9wZXJ0eVwiLFxuXHRcdFwiaXNQcm90b3R5cGVPZlwiLFxuXHRcdFwicHJvcGVydHlJc0VudW1lcmFibGVcIixcblx0XHRcImNvbnN0cnVjdG9yXCJcblx0XTtcblxudmFyIGtleXNTaGltID0gZnVuY3Rpb24ga2V5cyhvYmplY3QpIHtcblx0dmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnLFxuXHRcdGlzRnVuY3Rpb24gPSB0b1N0cmluZy5jYWxsKG9iamVjdCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXScsXG5cdFx0aXNBcmd1bWVudHMgPSBpc0FyZ3Mob2JqZWN0KSxcblx0XHR0aGVLZXlzID0gW107XG5cblx0aWYgKCFpc09iamVjdCAmJiAhaXNGdW5jdGlvbiAmJiAhaXNBcmd1bWVudHMpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0LmtleXMgY2FsbGVkIG9uIGEgbm9uLW9iamVjdFwiKTtcblx0fVxuXG5cdGlmIChpc0FyZ3VtZW50cykge1xuXHRcdGZvckVhY2gob2JqZWN0LCBmdW5jdGlvbiAodmFsdWUsIGluZGV4KSB7XG5cdFx0XHR0aGVLZXlzLnB1c2goaW5kZXgpO1xuXHRcdH0pO1xuXHR9IGVsc2Uge1xuXHRcdHZhciBuYW1lLFxuXHRcdFx0c2tpcFByb3RvID0gaGFzUHJvdG9FbnVtQnVnICYmIGlzRnVuY3Rpb247XG5cblx0XHRmb3IgKG5hbWUgaW4gb2JqZWN0KSB7XG5cdFx0XHRpZiAoIShza2lwUHJvdG8gJiYgbmFtZSA9PT0gJ3Byb3RvdHlwZScpICYmIGhhcy5jYWxsKG9iamVjdCwgbmFtZSkpIHtcblx0XHRcdFx0dGhlS2V5cy5wdXNoKG5hbWUpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGlmIChoYXNEb250RW51bUJ1Zykge1xuXHRcdHZhciBjdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuXHRcdFx0c2tpcENvbnN0cnVjdG9yID0gY3RvciAmJiBjdG9yLnByb3RvdHlwZSA9PT0gb2JqZWN0O1xuXG5cdFx0Zm9yRWFjaChkb250RW51bXMsIGZ1bmN0aW9uIChkb250RW51bSkge1xuXHRcdFx0aWYgKCEoc2tpcENvbnN0cnVjdG9yICYmIGRvbnRFbnVtID09PSAnY29uc3RydWN0b3InKSAmJiBoYXMuY2FsbChvYmplY3QsIGRvbnRFbnVtKSkge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2goZG9udEVudW0pO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cdHJldHVybiB0aGVLZXlzO1xufTtcblxua2V5c1NoaW0uc2hpbSA9IGZ1bmN0aW9uIHNoaW1PYmplY3RLZXlzKCkge1xuXHRpZiAoIU9iamVjdC5rZXlzKSB7XG5cdFx0T2JqZWN0LmtleXMgPSBrZXlzU2hpbTtcblx0fVxuXHRyZXR1cm4gT2JqZWN0LmtleXMgfHwga2V5c1NoaW07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXNTaGltO1xuXG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0FyZ3VtZW50cyh2YWx1ZSkge1xuXHR2YXIgc3RyID0gdG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG5cdHZhciBpc0FyZ3VtZW50cyA9IHN0ciA9PT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG5cdGlmICghaXNBcmd1bWVudHMpIHtcblx0XHRpc0FyZ3VtZW50cyA9IHN0ciAhPT0gJ1tvYmplY3QgQXJyYXldJ1xuXHRcdFx0JiYgdmFsdWUgIT09IG51bGxcblx0XHRcdCYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCdcblx0XHRcdCYmIHR5cGVvZiB2YWx1ZS5sZW5ndGggPT09ICdudW1iZXInXG5cdFx0XHQmJiB2YWx1ZS5sZW5ndGggPj0gMFxuXHRcdFx0JiYgdG9TdHJpbmcuY2FsbCh2YWx1ZS5jYWxsZWUpID09PSAnW29iamVjdCBGdW5jdGlvbl0nO1xuXHR9XG5cdHJldHVybiBpc0FyZ3VtZW50cztcbn07XG5cbiIsIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBtYXAgPSByZXF1aXJlKCdhcnJheS1tYXAnKTtcbnZhciBpbmRleE9mID0gcmVxdWlyZSgnaW5kZXhvZicpO1xudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5Jyk7XG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2ZvcmVhY2gnKTtcbnZhciByZWR1Y2UgPSByZXF1aXJlKCdhcnJheS1yZWR1Y2UnKTtcbnZhciBnZXRPYmplY3RLZXlzID0gcmVxdWlyZSgnb2JqZWN0LWtleXMnKTtcbnZhciBKU09OID0gcmVxdWlyZSgnanNvbjMnKTtcblxuLyoqXG4gKiBNYWtlIHN1cmUgYE9iamVjdC5rZXlzYCB3b3JrIGZvciBgdW5kZWZpbmVkYFxuICogdmFsdWVzIHRoYXQgYXJlIHN0aWxsIHRoZXJlLCBsaWtlIGBkb2N1bWVudC5hbGxgLlxuICogaHR0cDovL2xpc3RzLnczLm9yZy9BcmNoaXZlcy9QdWJsaWMvcHVibGljLWh0bWwvMjAwOUp1bi8wNTQ2Lmh0bWxcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBvYmplY3RLZXlzKHZhbCl7XG4gIGlmIChPYmplY3Qua2V5cykgcmV0dXJuIE9iamVjdC5rZXlzKHZhbCk7XG4gIHJldHVybiBnZXRPYmplY3RLZXlzKHZhbCk7XG59XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBpbnNwZWN0O1xuXG4vKipcbiAqIEVjaG9zIHRoZSB2YWx1ZSBvZiBhIHZhbHVlLiBUcnlzIHRvIHByaW50IHRoZSB2YWx1ZSBvdXRcbiAqIGluIHRoZSBiZXN0IHdheSBwb3NzaWJsZSBnaXZlbiB0aGUgZGlmZmVyZW50IHR5cGVzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogVGhlIG9iamVjdCB0byBwcmludCBvdXQuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cyBPcHRpb25hbCBvcHRpb25zIG9iamVjdCB0aGF0IGFsdGVycyB0aGUgb3V0cHV0LlxuICogQGxpY2Vuc2UgTUlUICjCqSBKb3llbnQpXG4gKi9cbi8qIGxlZ2FjeTogb2JqLCBzaG93SGlkZGVuLCBkZXB0aCwgY29sb3JzKi9cblxuZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCBvcHRpb25zXG4gIHZhciBjdHggPSB7XG4gICAgc2VlbjogW10sXG4gICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3JcbiAgfTtcbiAgLy8gbGVnYWN5Li4uXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNCkgY3R4LmNvbG9ycyA9IGFyZ3VtZW50c1szXTtcbiAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuICAgIC8vIGxlZ2FjeS4uLlxuICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcbiAgfSBlbHNlIGlmIChvcHRzKSB7XG4gICAgLy8gZ290IGFuIFwib3B0aW9uc1wiIG9iamVjdFxuICAgIF9leHRlbmQoY3R4LCBvcHRzKTtcbiAgfVxuICAvLyBzZXQgZGVmYXVsdCBvcHRpb25zXG4gIGlmIChpc1VuZGVmaW5lZChjdHguc2hvd0hpZGRlbikpIGN0eC5zaG93SGlkZGVuID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguZGVwdGgpKSBjdHguZGVwdGggPSAyO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmNvbG9ycykpIGN0eC5jb2xvcnMgPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jdXN0b21JbnNwZWN0KSkgY3R4LmN1c3RvbUluc3BlY3QgPSB0cnVlO1xuICBpZiAoY3R4LmNvbG9ycykgY3R4LnN0eWxpemUgPSBzdHlsaXplV2l0aENvbG9yO1xuICByZXR1cm4gZm9ybWF0VmFsdWUoY3R4LCBvYmosIGN0eC5kZXB0aCk7XG59XG5cbi8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQU5TSV9lc2NhcGVfY29kZSNncmFwaGljc1xuaW5zcGVjdC5jb2xvcnMgPSB7XG4gICdib2xkJyA6IFsxLCAyMl0sXG4gICdpdGFsaWMnIDogWzMsIDIzXSxcbiAgJ3VuZGVybGluZScgOiBbNCwgMjRdLFxuICAnaW52ZXJzZScgOiBbNywgMjddLFxuICAnd2hpdGUnIDogWzM3LCAzOV0sXG4gICdncmV5JyA6IFs5MCwgMzldLFxuICAnYmxhY2snIDogWzMwLCAzOV0sXG4gICdibHVlJyA6IFszNCwgMzldLFxuICAnY3lhbicgOiBbMzYsIDM5XSxcbiAgJ2dyZWVuJyA6IFszMiwgMzldLFxuICAnbWFnZW50YScgOiBbMzUsIDM5XSxcbiAgJ3JlZCcgOiBbMzEsIDM5XSxcbiAgJ3llbGxvdycgOiBbMzMsIDM5XVxufTtcblxuLy8gRG9uJ3QgdXNlICdibHVlJyBub3QgdmlzaWJsZSBvbiBjbWQuZXhlXG5pbnNwZWN0LnN0eWxlcyA9IHtcbiAgJ3NwZWNpYWwnOiAnY3lhbicsXG4gICdudW1iZXInOiAneWVsbG93JyxcbiAgJ2Jvb2xlYW4nOiAneWVsbG93JyxcbiAgJ3VuZGVmaW5lZCc6ICdncmV5JyxcbiAgJ251bGwnOiAnYm9sZCcsXG4gICdzdHJpbmcnOiAnZ3JlZW4nLFxuICAnZGF0ZSc6ICdtYWdlbnRhJyxcbiAgLy8gXCJuYW1lXCI6IGludGVudGlvbmFsbHkgbm90IHN0eWxpbmdcbiAgJ3JlZ2V4cCc6ICdyZWQnXG59O1xuXG5mdW5jdGlvbiBzdHlsaXplTm9Db2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICByZXR1cm4gc3RyO1xufVxuXG5mdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnYm9vbGVhbic7XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG5cbmZ1bmN0aW9uIHN0eWxpemVXaXRoQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgdmFyIHN0eWxlID0gaW5zcGVjdC5zdHlsZXNbc3R5bGVUeXBlXTtcblxuICBpZiAoc3R5bGUpIHtcbiAgICByZXR1cm4gJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVswXSArICdtJyArIHN0ciArXG4gICAgICAgICAgICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMV0gKyAnbSc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gaXNOdWxsKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsO1xufVxuXG5mdW5jdGlvbiBoYXNPd24ob2JqLCBwcm9wKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKTtcbn1cblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHJlKSAmJiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiBpc09iamVjdChlKSAmJlxuICAgICAgKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBpc09iamVjdChkKSAmJiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG5cbmZ1bmN0aW9uIGFycmF5VG9IYXNoKGFycmF5KSB7XG4gIHZhciBoYXNoID0ge307XG5cbiAgZm9yRWFjaChhcnJheSwgZnVuY3Rpb24odmFsLCBpZHgpIHtcbiAgICBoYXNoW3ZhbF0gPSB0cnVlO1xuICB9KTtcblxuICByZXR1cm4gaGFzaDtcbn1cblxuZnVuY3Rpb24gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cykge1xuICB2YXIgb3V0cHV0ID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgaWYgKGhhc093bih2YWx1ZSwgU3RyaW5nKGkpKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBTdHJpbmcoaSksIHRydWUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0LnB1c2goJycpO1xuICAgIH1cbiAgfVxuICBmb3JFYWNoKGtleXMsIGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5mdW5jdGlvbiBmb3JtYXRFcnJvcih2YWx1ZSkge1xuICByZXR1cm4gJ1snICsgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpICsgJ10nO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKGN0eC5jdXN0b21JbnNwZWN0ICYmXG4gICAgICB2YWx1ZSAmJlxuICAgICAgaXNGdW5jdGlvbih2YWx1ZS5pbnNwZWN0KSAmJlxuICAgICAgLy8gRmlsdGVyIG91dCB0aGUgdXRpbCBtb2R1bGUsIGl0J3MgaW5zcGVjdCBmdW5jdGlvbiBpcyBzcGVjaWFsXG4gICAgICB2YWx1ZS5pbnNwZWN0ICE9PSBpbnNwZWN0ICYmXG4gICAgICAvLyBBbHNvIGZpbHRlciBvdXQgYW55IHByb3RvdHlwZSBvYmplY3RzIHVzaW5nIHRoZSBjaXJjdWxhciBjaGVjay5cbiAgICAgICEodmFsdWUuY29uc3RydWN0b3IgJiYgdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlID09PSB2YWx1ZSkpIHtcbiAgICB2YXIgcmV0ID0gdmFsdWUuaW5zcGVjdChyZWN1cnNlVGltZXMsIGN0eCk7XG4gICAgaWYgKCFpc1N0cmluZyhyZXQpKSB7XG4gICAgICByZXQgPSBmb3JtYXRWYWx1ZShjdHgsIHJldCwgcmVjdXJzZVRpbWVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIC8vIFByaW1pdGl2ZSB0eXBlcyBjYW5ub3QgaGF2ZSBwcm9wZXJ0aWVzXG4gIHZhciBwcmltaXRpdmUgPSBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSk7XG4gIGlmIChwcmltaXRpdmUpIHtcbiAgICByZXR1cm4gcHJpbWl0aXZlO1xuICB9XG5cbiAgLy8gTG9vayB1cCB0aGUga2V5cyBvZiB0aGUgb2JqZWN0LlxuICB2YXIga2V5cyA9IG9iamVjdEtleXModmFsdWUpO1xuICB2YXIgdmlzaWJsZUtleXMgPSBhcnJheVRvSGFzaChrZXlzKTtcblxuICBpZiAoY3R4LnNob3dIaWRkZW4gJiYgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMpIHtcbiAgICBrZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuICB9XG5cbiAgLy8gSUUgZG9lc24ndCBtYWtlIGVycm9yIGZpZWxkcyBub24tZW51bWVyYWJsZVxuICAvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvZHd3NTJzYnQodj12cy45NCkuYXNweFxuICBpZiAoaXNFcnJvcih2YWx1ZSlcbiAgICAgICYmIChpbmRleE9mKGtleXMsICdtZXNzYWdlJykgPj0gMCB8fCBpbmRleE9mKGtleXMsICdkZXNjcmlwdGlvbicpID49IDApKSB7XG4gICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIC8vIFNvbWUgdHlwZSBvZiBvYmplY3Qgd2l0aG91dCBwcm9wZXJ0aWVzIGNhbiBiZSBzaG9ydGN1dHRlZC5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgICB2YXIgbmFtZSA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbRnVuY3Rpb24nICsgbmFtZSArICddJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9XG4gICAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShEYXRlLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ2RhdGUnKTtcbiAgICB9XG4gICAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBiYXNlID0gJycsIGFycmF5ID0gZmFsc2UsIGJyYWNlcyA9IFsneycsICd9J107XG5cbiAgLy8gTWFrZSBBcnJheSBzYXkgdGhhdCB0aGV5IGFyZSBBcnJheVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBhcnJheSA9IHRydWU7XG4gICAgYnJhY2VzID0gWydbJywgJ10nXTtcbiAgfVxuXG4gIC8vIE1ha2UgZnVuY3Rpb25zIHNheSB0aGF0IHRoZXkgYXJlIGZ1bmN0aW9uc1xuICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICB2YXIgbiA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgIGJhc2UgPSAnIFtGdW5jdGlvbicgKyBuICsgJ10nO1xuICB9XG5cbiAgLy8gTWFrZSBSZWdFeHBzIHNheSB0aGF0IHRoZXkgYXJlIFJlZ0V4cHNcbiAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBkYXRlcyB3aXRoIHByb3BlcnRpZXMgZmlyc3Qgc2F5IHRoZSBkYXRlXG4gIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIERhdGUucHJvdG90eXBlLnRvVVRDU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBlcnJvciB3aXRoIG1lc3NhZ2UgZmlyc3Qgc2F5IHRoZSBlcnJvclxuICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwICYmICghYXJyYXkgfHwgdmFsdWUubGVuZ3RoID09IDApKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyBicmFjZXNbMV07XG4gIH1cblxuICBpZiAocmVjdXJzZVRpbWVzIDwgMCkge1xuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW09iamVjdF0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuXG4gIGN0eC5zZWVuLnB1c2godmFsdWUpO1xuXG4gIHZhciBvdXRwdXQ7XG4gIGlmIChhcnJheSkge1xuICAgIG91dHB1dCA9IGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpO1xuICB9IGVsc2Uge1xuICAgIG91dHB1dCA9IG1hcChrZXlzLCBmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KTtcbiAgICB9KTtcbiAgfVxuXG4gIGN0eC5zZWVuLnBvcCgpO1xuXG4gIHJldHVybiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcyk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0ciwgZGVzYztcbiAgZGVzYyA9IHsgdmFsdWU6IHZhbHVlW2tleV0gfTtcbiAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IpIHtcbiAgICBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih2YWx1ZSwga2V5KSB8fCBkZXNjO1xuICB9XG4gIGlmIChkZXNjLmdldCkge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXIvU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tTZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFoYXNPd24odmlzaWJsZUtleXMsIGtleSkpIHtcbiAgICBuYW1lID0gJ1snICsga2V5ICsgJ10nO1xuICB9XG4gIGlmICghc3RyKSB7XG4gICAgaWYgKGluZGV4T2YoY3R4LnNlZW4sIGRlc2MudmFsdWUpIDwgMCkge1xuICAgICAgaWYgKGlzTnVsbChyZWN1cnNlVGltZXMpKSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgbnVsbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIHJlY3Vyc2VUaW1lcyAtIDEpO1xuICAgICAgfVxuICAgICAgaWYgKHN0ci5pbmRleE9mKCdcXG4nKSA+IC0xKSB7XG4gICAgICAgIGlmIChhcnJheSkge1xuICAgICAgICAgIHN0ciA9IG1hcChzdHIuc3BsaXQoJ1xcbicpLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJykuc3Vic3RyKDIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0ciA9ICdcXG4nICsgbWFwKHN0ci5zcGxpdCgnXFxuJyksIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKSB7XG4gIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCd1bmRlZmluZWQnLCAndW5kZWZpbmVkJyk7XG4gIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJykgKyAnXFwnJztcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG4gIH1cbiAgaWYgKGlzTnVtYmVyKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ251bWJlcicpO1xuICBpZiAoaXNCb29sZWFuKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgLy8gRm9yIHNvbWUgcmVhc29uIHR5cGVvZiBudWxsIGlzIFwib2JqZWN0XCIsIHNvIHNwZWNpYWwgY2FzZSBoZXJlLlxuICBpZiAoaXNOdWxsKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ251bGwnLCAnbnVsbCcpO1xufVxuXG5mdW5jdGlvbiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcykge1xuICB2YXIgbnVtTGluZXNFc3QgPSAwO1xuICB2YXIgbGVuZ3RoID0gcmVkdWNlKG91dHB1dCwgZnVuY3Rpb24ocHJldiwgY3VyKSB7XG4gICAgbnVtTGluZXNFc3QrKztcbiAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIG51bUxpbmVzRXN0Kys7XG4gICAgcmV0dXJuIHByZXYgKyBjdXIucmVwbGFjZSgvXFx1MDAxYlxcW1xcZFxcZD9tL2csICcnKS5sZW5ndGggKyAxO1xuICB9LCAwKTtcblxuICBpZiAobGVuZ3RoID4gNjApIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICtcbiAgICAgICAgICAgKGJhc2UgPT09ICcnID8gJycgOiBiYXNlICsgJ1xcbiAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIG91dHB1dC5qb2luKCcsXFxuICAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIGJyYWNlc1sxXTtcbiAgfVxuXG4gIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgJyAnICsgb3V0cHV0LmpvaW4oJywgJykgKyAnICcgKyBicmFjZXNbMV07XG59XG5cbmZ1bmN0aW9uIF9leHRlbmQob3JpZ2luLCBhZGQpIHtcbiAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgYWRkIGlzbid0IGFuIG9iamVjdFxuICBpZiAoIWFkZCB8fCAhaXNPYmplY3QoYWRkKSkgcmV0dXJuIG9yaWdpbjtcblxuICB2YXIga2V5cyA9IG9iamVjdEtleXMoYWRkKTtcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIG9yaWdpbltrZXlzW2ldXSA9IGFkZFtrZXlzW2ldXTtcbiAgfVxuICByZXR1cm4gb3JpZ2luO1xufVxuIiwiLyohIEpTT04gdjMuMy4wIHwgaHR0cDovL2Jlc3RpZWpzLmdpdGh1Yi5pby9qc29uMyB8IENvcHlyaWdodCAyMDEyLTIwMTQsIEtpdCBDYW1icmlkZ2UgfCBodHRwOi8va2l0Lm1pdC1saWNlbnNlLm9yZyAqL1xuOyhmdW5jdGlvbiAocm9vdCkge1xuICAvLyBEZXRlY3QgdGhlIGBkZWZpbmVgIGZ1bmN0aW9uIGV4cG9zZWQgYnkgYXN5bmNocm9ub3VzIG1vZHVsZSBsb2FkZXJzLiBUaGVcbiAgLy8gc3RyaWN0IGBkZWZpbmVgIGNoZWNrIGlzIG5lY2Vzc2FyeSBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIGByLmpzYC5cbiAgdmFyIGlzTG9hZGVyID0gdHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQ7XG5cbiAgLy8gVXNlIHRoZSBgZ2xvYmFsYCBvYmplY3QgZXhwb3NlZCBieSBOb2RlIChpbmNsdWRpbmcgQnJvd3NlcmlmeSB2aWFcbiAgLy8gYGluc2VydC1tb2R1bGUtZ2xvYmFsc2ApLCBOYXJ3aGFsLCBhbmQgUmluZ28gYXMgdGhlIGRlZmF1bHQgY29udGV4dC5cbiAgLy8gUmhpbm8gZXhwb3J0cyBhIGBnbG9iYWxgIGZ1bmN0aW9uIGluc3RlYWQuXG4gIHZhciBmcmVlR2xvYmFsID0gdHlwZW9mIGdsb2JhbCA9PSBcIm9iamVjdFwiICYmIGdsb2JhbDtcbiAgaWYgKGZyZWVHbG9iYWwgJiYgKGZyZWVHbG9iYWxbXCJnbG9iYWxcIl0gPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbFtcIndpbmRvd1wiXSA9PT0gZnJlZUdsb2JhbCkpIHtcbiAgICByb290ID0gZnJlZUdsb2JhbDtcbiAgfVxuXG4gIC8vIFB1YmxpYzogSW5pdGlhbGl6ZXMgSlNPTiAzIHVzaW5nIHRoZSBnaXZlbiBgY29udGV4dGAgb2JqZWN0LCBhdHRhY2hpbmcgdGhlXG4gIC8vIGBzdHJpbmdpZnlgIGFuZCBgcGFyc2VgIGZ1bmN0aW9ucyB0byB0aGUgc3BlY2lmaWVkIGBleHBvcnRzYCBvYmplY3QuXG4gIGZ1bmN0aW9uIHJ1bkluQ29udGV4dChjb250ZXh0LCBleHBvcnRzKSB7XG4gICAgY29udGV4dCB8fCAoY29udGV4dCA9IHJvb3RbXCJPYmplY3RcIl0oKSk7XG4gICAgZXhwb3J0cyB8fCAoZXhwb3J0cyA9IHJvb3RbXCJPYmplY3RcIl0oKSk7XG5cbiAgICAvLyBOYXRpdmUgY29uc3RydWN0b3IgYWxpYXNlcy5cbiAgICB2YXIgTnVtYmVyID0gY29udGV4dFtcIk51bWJlclwiXSB8fCByb290W1wiTnVtYmVyXCJdLFxuICAgICAgICBTdHJpbmcgPSBjb250ZXh0W1wiU3RyaW5nXCJdIHx8IHJvb3RbXCJTdHJpbmdcIl0sXG4gICAgICAgIE9iamVjdCA9IGNvbnRleHRbXCJPYmplY3RcIl0gfHwgcm9vdFtcIk9iamVjdFwiXSxcbiAgICAgICAgRGF0ZSA9IGNvbnRleHRbXCJEYXRlXCJdIHx8IHJvb3RbXCJEYXRlXCJdLFxuICAgICAgICBTeW50YXhFcnJvciA9IGNvbnRleHRbXCJTeW50YXhFcnJvclwiXSB8fCByb290W1wiU3ludGF4RXJyb3JcIl0sXG4gICAgICAgIFR5cGVFcnJvciA9IGNvbnRleHRbXCJUeXBlRXJyb3JcIl0gfHwgcm9vdFtcIlR5cGVFcnJvclwiXSxcbiAgICAgICAgTWF0aCA9IGNvbnRleHRbXCJNYXRoXCJdIHx8IHJvb3RbXCJNYXRoXCJdLFxuICAgICAgICBuYXRpdmVKU09OID0gY29udGV4dFtcIkpTT05cIl0gfHwgcm9vdFtcIkpTT05cIl07XG5cbiAgICAvLyBEZWxlZ2F0ZSB0byB0aGUgbmF0aXZlIGBzdHJpbmdpZnlgIGFuZCBgcGFyc2VgIGltcGxlbWVudGF0aW9ucy5cbiAgICBpZiAodHlwZW9mIG5hdGl2ZUpTT04gPT0gXCJvYmplY3RcIiAmJiBuYXRpdmVKU09OKSB7XG4gICAgICBleHBvcnRzLnN0cmluZ2lmeSA9IG5hdGl2ZUpTT04uc3RyaW5naWZ5O1xuICAgICAgZXhwb3J0cy5wYXJzZSA9IG5hdGl2ZUpTT04ucGFyc2U7XG4gICAgfVxuXG4gICAgLy8gQ29udmVuaWVuY2UgYWxpYXNlcy5cbiAgICB2YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlLFxuICAgICAgICBnZXRDbGFzcyA9IG9iamVjdFByb3RvLnRvU3RyaW5nLFxuICAgICAgICBpc1Byb3BlcnR5LCBmb3JFYWNoLCB1bmRlZjtcblxuICAgIC8vIFRlc3QgdGhlIGBEYXRlI2dldFVUQypgIG1ldGhvZHMuIEJhc2VkIG9uIHdvcmsgYnkgQFlhZmZsZS5cbiAgICB2YXIgaXNFeHRlbmRlZCA9IG5ldyBEYXRlKC0zNTA5ODI3MzM0NTczMjkyKTtcbiAgICB0cnkge1xuICAgICAgLy8gVGhlIGBnZXRVVENGdWxsWWVhcmAsIGBNb250aGAsIGFuZCBgRGF0ZWAgbWV0aG9kcyByZXR1cm4gbm9uc2Vuc2ljYWxcbiAgICAgIC8vIHJlc3VsdHMgZm9yIGNlcnRhaW4gZGF0ZXMgaW4gT3BlcmEgPj0gMTAuNTMuXG4gICAgICBpc0V4dGVuZGVkID0gaXNFeHRlbmRlZC5nZXRVVENGdWxsWWVhcigpID09IC0xMDkyNTIgJiYgaXNFeHRlbmRlZC5nZXRVVENNb250aCgpID09PSAwICYmIGlzRXh0ZW5kZWQuZ2V0VVRDRGF0ZSgpID09PSAxICYmXG4gICAgICAgIC8vIFNhZmFyaSA8IDIuMC4yIHN0b3JlcyB0aGUgaW50ZXJuYWwgbWlsbGlzZWNvbmQgdGltZSB2YWx1ZSBjb3JyZWN0bHksXG4gICAgICAgIC8vIGJ1dCBjbGlwcyB0aGUgdmFsdWVzIHJldHVybmVkIGJ5IHRoZSBkYXRlIG1ldGhvZHMgdG8gdGhlIHJhbmdlIG9mXG4gICAgICAgIC8vIHNpZ25lZCAzMi1iaXQgaW50ZWdlcnMgKFstMiAqKiAzMSwgMiAqKiAzMSAtIDFdKS5cbiAgICAgICAgaXNFeHRlbmRlZC5nZXRVVENIb3VycygpID09IDEwICYmIGlzRXh0ZW5kZWQuZ2V0VVRDTWludXRlcygpID09IDM3ICYmIGlzRXh0ZW5kZWQuZ2V0VVRDU2Vjb25kcygpID09IDYgJiYgaXNFeHRlbmRlZC5nZXRVVENNaWxsaXNlY29uZHMoKSA9PSA3MDg7XG4gICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuXG4gICAgLy8gSW50ZXJuYWw6IERldGVybWluZXMgd2hldGhlciB0aGUgbmF0aXZlIGBKU09OLnN0cmluZ2lmeWAgYW5kIGBwYXJzZWBcbiAgICAvLyBpbXBsZW1lbnRhdGlvbnMgYXJlIHNwZWMtY29tcGxpYW50LiBCYXNlZCBvbiB3b3JrIGJ5IEtlbiBTbnlkZXIuXG4gICAgZnVuY3Rpb24gaGFzKG5hbWUpIHtcbiAgICAgIGlmIChoYXNbbmFtZV0gIT09IHVuZGVmKSB7XG4gICAgICAgIC8vIFJldHVybiBjYWNoZWQgZmVhdHVyZSB0ZXN0IHJlc3VsdC5cbiAgICAgICAgcmV0dXJuIGhhc1tuYW1lXTtcbiAgICAgIH1cbiAgICAgIHZhciBpc1N1cHBvcnRlZDtcbiAgICAgIGlmIChuYW1lID09IFwiYnVnLXN0cmluZy1jaGFyLWluZGV4XCIpIHtcbiAgICAgICAgLy8gSUUgPD0gNyBkb2Vzbid0IHN1cHBvcnQgYWNjZXNzaW5nIHN0cmluZyBjaGFyYWN0ZXJzIHVzaW5nIHNxdWFyZVxuICAgICAgICAvLyBicmFja2V0IG5vdGF0aW9uLiBJRSA4IG9ubHkgc3VwcG9ydHMgdGhpcyBmb3IgcHJpbWl0aXZlcy5cbiAgICAgICAgaXNTdXBwb3J0ZWQgPSBcImFcIlswXSAhPSBcImFcIjtcbiAgICAgIH0gZWxzZSBpZiAobmFtZSA9PSBcImpzb25cIikge1xuICAgICAgICAvLyBJbmRpY2F0ZXMgd2hldGhlciBib3RoIGBKU09OLnN0cmluZ2lmeWAgYW5kIGBKU09OLnBhcnNlYCBhcmVcbiAgICAgICAgLy8gc3VwcG9ydGVkLlxuICAgICAgICBpc1N1cHBvcnRlZCA9IGhhcyhcImpzb24tc3RyaW5naWZ5XCIpICYmIGhhcyhcImpzb24tcGFyc2VcIik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgdmFsdWUsIHNlcmlhbGl6ZWQgPSAne1wiYVwiOlsxLHRydWUsZmFsc2UsbnVsbCxcIlxcXFx1MDAwMFxcXFxiXFxcXG5cXFxcZlxcXFxyXFxcXHRcIl19JztcbiAgICAgICAgLy8gVGVzdCBgSlNPTi5zdHJpbmdpZnlgLlxuICAgICAgICBpZiAobmFtZSA9PSBcImpzb24tc3RyaW5naWZ5XCIpIHtcbiAgICAgICAgICB2YXIgc3RyaW5naWZ5ID0gZXhwb3J0cy5zdHJpbmdpZnksIHN0cmluZ2lmeVN1cHBvcnRlZCA9IHR5cGVvZiBzdHJpbmdpZnkgPT0gXCJmdW5jdGlvblwiICYmIGlzRXh0ZW5kZWQ7XG4gICAgICAgICAgaWYgKHN0cmluZ2lmeVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgLy8gQSB0ZXN0IGZ1bmN0aW9uIG9iamVjdCB3aXRoIGEgY3VzdG9tIGB0b0pTT05gIG1ldGhvZC5cbiAgICAgICAgICAgICh2YWx1ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICB9KS50b0pTT04gPSB2YWx1ZTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHN0cmluZ2lmeVN1cHBvcnRlZCA9XG4gICAgICAgICAgICAgICAgLy8gRmlyZWZveCAzLjFiMSBhbmQgYjIgc2VyaWFsaXplIHN0cmluZywgbnVtYmVyLCBhbmQgYm9vbGVhblxuICAgICAgICAgICAgICAgIC8vIHByaW1pdGl2ZXMgYXMgb2JqZWN0IGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeSgwKSA9PT0gXCIwXCIgJiZcbiAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgYjIsIGFuZCBKU09OIDIgc2VyaWFsaXplIHdyYXBwZWQgcHJpbWl0aXZlcyBhcyBvYmplY3RcbiAgICAgICAgICAgICAgICAvLyBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IE51bWJlcigpKSA9PT0gXCIwXCIgJiZcbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IFN0cmluZygpKSA9PSAnXCJcIicgJiZcbiAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgMiB0aHJvdyBhbiBlcnJvciBpZiB0aGUgdmFsdWUgaXMgYG51bGxgLCBgdW5kZWZpbmVkYCwgb3JcbiAgICAgICAgICAgICAgICAvLyBkb2VzIG5vdCBkZWZpbmUgYSBjYW5vbmljYWwgSlNPTiByZXByZXNlbnRhdGlvbiAodGhpcyBhcHBsaWVzIHRvXG4gICAgICAgICAgICAgICAgLy8gb2JqZWN0cyB3aXRoIGB0b0pTT05gIHByb3BlcnRpZXMgYXMgd2VsbCwgKnVubGVzcyogdGhleSBhcmUgbmVzdGVkXG4gICAgICAgICAgICAgICAgLy8gd2l0aGluIGFuIG9iamVjdCBvciBhcnJheSkuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KGdldENsYXNzKSA9PT0gdW5kZWYgJiZcbiAgICAgICAgICAgICAgICAvLyBJRSA4IHNlcmlhbGl6ZXMgYHVuZGVmaW5lZGAgYXMgYFwidW5kZWZpbmVkXCJgLiBTYWZhcmkgPD0gNS4xLjcgYW5kXG4gICAgICAgICAgICAgICAgLy8gRkYgMy4xYjMgcGFzcyB0aGlzIHRlc3QuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KHVuZGVmKSA9PT0gdW5kZWYgJiZcbiAgICAgICAgICAgICAgICAvLyBTYWZhcmkgPD0gNS4xLjcgYW5kIEZGIDMuMWIzIHRocm93IGBFcnJvcmBzIGFuZCBgVHlwZUVycm9yYHMsXG4gICAgICAgICAgICAgICAgLy8gcmVzcGVjdGl2ZWx5LCBpZiB0aGUgdmFsdWUgaXMgb21pdHRlZCBlbnRpcmVseS5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoKSA9PT0gdW5kZWYgJiZcbiAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgMiB0aHJvdyBhbiBlcnJvciBpZiB0aGUgZ2l2ZW4gdmFsdWUgaXMgbm90IGEgbnVtYmVyLFxuICAgICAgICAgICAgICAgIC8vIHN0cmluZywgYXJyYXksIG9iamVjdCwgQm9vbGVhbiwgb3IgYG51bGxgIGxpdGVyYWwuIFRoaXMgYXBwbGllcyB0b1xuICAgICAgICAgICAgICAgIC8vIG9iamVjdHMgd2l0aCBjdXN0b20gYHRvSlNPTmAgbWV0aG9kcyBhcyB3ZWxsLCB1bmxlc3MgdGhleSBhcmUgbmVzdGVkXG4gICAgICAgICAgICAgICAgLy8gaW5zaWRlIG9iamVjdCBvciBhcnJheSBsaXRlcmFscy4gWVVJIDMuMC4wYjEgaWdub3JlcyBjdXN0b20gYHRvSlNPTmBcbiAgICAgICAgICAgICAgICAvLyBtZXRob2RzIGVudGlyZWx5LlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeSh2YWx1ZSkgPT09IFwiMVwiICYmXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KFt2YWx1ZV0pID09IFwiWzFdXCIgJiZcbiAgICAgICAgICAgICAgICAvLyBQcm90b3R5cGUgPD0gMS42LjEgc2VyaWFsaXplcyBgW3VuZGVmaW5lZF1gIGFzIGBcIltdXCJgIGluc3RlYWQgb2ZcbiAgICAgICAgICAgICAgICAvLyBgXCJbbnVsbF1cImAuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KFt1bmRlZl0pID09IFwiW251bGxdXCIgJiZcbiAgICAgICAgICAgICAgICAvLyBZVUkgMy4wLjBiMSBmYWlscyB0byBzZXJpYWxpemUgYG51bGxgIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShudWxsKSA9PSBcIm51bGxcIiAmJlxuICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCAyIGhhbHRzIHNlcmlhbGl6YXRpb24gaWYgYW4gYXJyYXkgY29udGFpbnMgYSBmdW5jdGlvbjpcbiAgICAgICAgICAgICAgICAvLyBgWzEsIHRydWUsIGdldENsYXNzLCAxXWAgc2VyaWFsaXplcyBhcyBcIlsxLHRydWUsXSxcIi4gRkYgMy4xYjNcbiAgICAgICAgICAgICAgICAvLyBlbGlkZXMgbm9uLUpTT04gdmFsdWVzIGZyb20gb2JqZWN0cyBhbmQgYXJyYXlzLCB1bmxlc3MgdGhleVxuICAgICAgICAgICAgICAgIC8vIGRlZmluZSBjdXN0b20gYHRvSlNPTmAgbWV0aG9kcy5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoW3VuZGVmLCBnZXRDbGFzcywgbnVsbF0pID09IFwiW251bGwsbnVsbCxudWxsXVwiICYmXG4gICAgICAgICAgICAgICAgLy8gU2ltcGxlIHNlcmlhbGl6YXRpb24gdGVzdC4gRkYgMy4xYjEgdXNlcyBVbmljb2RlIGVzY2FwZSBzZXF1ZW5jZXNcbiAgICAgICAgICAgICAgICAvLyB3aGVyZSBjaGFyYWN0ZXIgZXNjYXBlIGNvZGVzIGFyZSBleHBlY3RlZCAoZS5nLiwgYFxcYmAgPT4gYFxcdTAwMDhgKS5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoeyBcImFcIjogW3ZhbHVlLCB0cnVlLCBmYWxzZSwgbnVsbCwgXCJcXHgwMFxcYlxcblxcZlxcclxcdFwiXSB9KSA9PSBzZXJpYWxpemVkICYmXG4gICAgICAgICAgICAgICAgLy8gRkYgMy4xYjEgYW5kIGIyIGlnbm9yZSB0aGUgYGZpbHRlcmAgYW5kIGB3aWR0aGAgYXJndW1lbnRzLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShudWxsLCB2YWx1ZSkgPT09IFwiMVwiICYmXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KFsxLCAyXSwgbnVsbCwgMSkgPT0gXCJbXFxuIDEsXFxuIDJcXG5dXCIgJiZcbiAgICAgICAgICAgICAgICAvLyBKU09OIDIsIFByb3RvdHlwZSA8PSAxLjcsIGFuZCBvbGRlciBXZWJLaXQgYnVpbGRzIGluY29ycmVjdGx5XG4gICAgICAgICAgICAgICAgLy8gc2VyaWFsaXplIGV4dGVuZGVkIHllYXJzLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgRGF0ZSgtOC42NGUxNSkpID09ICdcIi0yNzE4MjEtMDQtMjBUMDA6MDA6MDAuMDAwWlwiJyAmJlxuICAgICAgICAgICAgICAgIC8vIFRoZSBtaWxsaXNlY29uZHMgYXJlIG9wdGlvbmFsIGluIEVTIDUsIGJ1dCByZXF1aXJlZCBpbiA1LjEuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKDguNjRlMTUpKSA9PSAnXCIrMjc1NzYwLTA5LTEzVDAwOjAwOjAwLjAwMFpcIicgJiZcbiAgICAgICAgICAgICAgICAvLyBGaXJlZm94IDw9IDExLjAgaW5jb3JyZWN0bHkgc2VyaWFsaXplcyB5ZWFycyBwcmlvciB0byAwIGFzIG5lZ2F0aXZlXG4gICAgICAgICAgICAgICAgLy8gZm91ci1kaWdpdCB5ZWFycyBpbnN0ZWFkIG9mIHNpeC1kaWdpdCB5ZWFycy4gQ3JlZGl0czogQFlhZmZsZS5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoLTYyMTk4NzU1MmU1KSkgPT0gJ1wiLTAwMDAwMS0wMS0wMVQwMDowMDowMC4wMDBaXCInICYmXG4gICAgICAgICAgICAgICAgLy8gU2FmYXJpIDw9IDUuMS41IGFuZCBPcGVyYSA+PSAxMC41MyBpbmNvcnJlY3RseSBzZXJpYWxpemUgbWlsbGlzZWNvbmRcbiAgICAgICAgICAgICAgICAvLyB2YWx1ZXMgbGVzcyB0aGFuIDEwMDAuIENyZWRpdHM6IEBZYWZmbGUuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKC0xKSkgPT0gJ1wiMTk2OS0xMi0zMVQyMzo1OTo1OS45OTlaXCInO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgIHN0cmluZ2lmeVN1cHBvcnRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpc1N1cHBvcnRlZCA9IHN0cmluZ2lmeVN1cHBvcnRlZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBUZXN0IGBKU09OLnBhcnNlYC5cbiAgICAgICAgaWYgKG5hbWUgPT0gXCJqc29uLXBhcnNlXCIpIHtcbiAgICAgICAgICB2YXIgcGFyc2UgPSBleHBvcnRzLnBhcnNlO1xuICAgICAgICAgIGlmICh0eXBlb2YgcGFyc2UgPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgYjIgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24gaWYgYSBiYXJlIGxpdGVyYWwgaXMgcHJvdmlkZWQuXG4gICAgICAgICAgICAgIC8vIENvbmZvcm1pbmcgaW1wbGVtZW50YXRpb25zIHNob3VsZCBhbHNvIGNvZXJjZSB0aGUgaW5pdGlhbCBhcmd1bWVudCB0b1xuICAgICAgICAgICAgICAvLyBhIHN0cmluZyBwcmlvciB0byBwYXJzaW5nLlxuICAgICAgICAgICAgICBpZiAocGFyc2UoXCIwXCIpID09PSAwICYmICFwYXJzZShmYWxzZSkpIHtcbiAgICAgICAgICAgICAgICAvLyBTaW1wbGUgcGFyc2luZyB0ZXN0LlxuICAgICAgICAgICAgICAgIHZhbHVlID0gcGFyc2Uoc2VyaWFsaXplZCk7XG4gICAgICAgICAgICAgICAgdmFyIHBhcnNlU3VwcG9ydGVkID0gdmFsdWVbXCJhXCJdLmxlbmd0aCA9PSA1ICYmIHZhbHVlW1wiYVwiXVswXSA9PT0gMTtcbiAgICAgICAgICAgICAgICBpZiAocGFyc2VTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSA8PSA1LjEuMiBhbmQgRkYgMy4xYjEgYWxsb3cgdW5lc2NhcGVkIHRhYnMgaW4gc3RyaW5ncy5cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSAhcGFyc2UoJ1wiXFx0XCInKTtcbiAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cbiAgICAgICAgICAgICAgICAgIGlmIChwYXJzZVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIEZGIDQuMCBhbmQgNC4wLjEgYWxsb3cgbGVhZGluZyBgK2Agc2lnbnMgYW5kIGxlYWRpbmdcbiAgICAgICAgICAgICAgICAgICAgICAvLyBkZWNpbWFsIHBvaW50cy4gRkYgNC4wLCA0LjAuMSwgYW5kIElFIDktMTAgYWxzbyBhbGxvd1xuICAgICAgICAgICAgICAgICAgICAgIC8vIGNlcnRhaW4gb2N0YWwgbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBwYXJzZShcIjAxXCIpICE9PSAxO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBpZiAocGFyc2VTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBGRiA0LjAsIDQuMC4xLCBhbmQgUmhpbm8gMS43UjMtUjQgYWxsb3cgdHJhaWxpbmcgZGVjaW1hbFxuICAgICAgICAgICAgICAgICAgICAgIC8vIHBvaW50cy4gVGhlc2UgZW52aXJvbm1lbnRzLCBhbG9uZyB3aXRoIEZGIDMuMWIxIGFuZCAyLFxuICAgICAgICAgICAgICAgICAgICAgIC8vIGFsc28gYWxsb3cgdHJhaWxpbmcgY29tbWFzIGluIEpTT04gb2JqZWN0cyBhbmQgYXJyYXlzLlxuICAgICAgICAgICAgICAgICAgICAgIHBhcnNlU3VwcG9ydGVkID0gcGFyc2UoXCIxLlwiKSAhPT0gMTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgIHBhcnNlU3VwcG9ydGVkID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlzU3VwcG9ydGVkID0gcGFyc2VTdXBwb3J0ZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBoYXNbbmFtZV0gPSAhIWlzU3VwcG9ydGVkO1xuICAgIH1cblxuICAgIGlmICghaGFzKFwianNvblwiKSkge1xuICAgICAgLy8gQ29tbW9uIGBbW0NsYXNzXV1gIG5hbWUgYWxpYXNlcy5cbiAgICAgIHZhciBmdW5jdGlvbkNsYXNzID0gXCJbb2JqZWN0IEZ1bmN0aW9uXVwiLFxuICAgICAgICAgIGRhdGVDbGFzcyA9IFwiW29iamVjdCBEYXRlXVwiLFxuICAgICAgICAgIG51bWJlckNsYXNzID0gXCJbb2JqZWN0IE51bWJlcl1cIixcbiAgICAgICAgICBzdHJpbmdDbGFzcyA9IFwiW29iamVjdCBTdHJpbmddXCIsXG4gICAgICAgICAgYXJyYXlDbGFzcyA9IFwiW29iamVjdCBBcnJheV1cIixcbiAgICAgICAgICBib29sZWFuQ2xhc3MgPSBcIltvYmplY3QgQm9vbGVhbl1cIjtcblxuICAgICAgLy8gRGV0ZWN0IGluY29tcGxldGUgc3VwcG9ydCBmb3IgYWNjZXNzaW5nIHN0cmluZyBjaGFyYWN0ZXJzIGJ5IGluZGV4LlxuICAgICAgdmFyIGNoYXJJbmRleEJ1Z2d5ID0gaGFzKFwiYnVnLXN0cmluZy1jaGFyLWluZGV4XCIpO1xuXG4gICAgICAvLyBEZWZpbmUgYWRkaXRpb25hbCB1dGlsaXR5IG1ldGhvZHMgaWYgdGhlIGBEYXRlYCBtZXRob2RzIGFyZSBidWdneS5cbiAgICAgIGlmICghaXNFeHRlbmRlZCkge1xuICAgICAgICB2YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xuICAgICAgICAvLyBBIG1hcHBpbmcgYmV0d2VlbiB0aGUgbW9udGhzIG9mIHRoZSB5ZWFyIGFuZCB0aGUgbnVtYmVyIG9mIGRheXMgYmV0d2VlblxuICAgICAgICAvLyBKYW51YXJ5IDFzdCBhbmQgdGhlIGZpcnN0IG9mIHRoZSByZXNwZWN0aXZlIG1vbnRoLlxuICAgICAgICB2YXIgTW9udGhzID0gWzAsIDMxLCA1OSwgOTAsIDEyMCwgMTUxLCAxODEsIDIxMiwgMjQzLCAyNzMsIDMwNCwgMzM0XTtcbiAgICAgICAgLy8gSW50ZXJuYWw6IENhbGN1bGF0ZXMgdGhlIG51bWJlciBvZiBkYXlzIGJldHdlZW4gdGhlIFVuaXggZXBvY2ggYW5kIHRoZVxuICAgICAgICAvLyBmaXJzdCBkYXkgb2YgdGhlIGdpdmVuIG1vbnRoLlxuICAgICAgICB2YXIgZ2V0RGF5ID0gZnVuY3Rpb24gKHllYXIsIG1vbnRoKSB7XG4gICAgICAgICAgcmV0dXJuIE1vbnRoc1ttb250aF0gKyAzNjUgKiAoeWVhciAtIDE5NzApICsgZmxvb3IoKHllYXIgLSAxOTY5ICsgKG1vbnRoID0gKyhtb250aCA+IDEpKSkgLyA0KSAtIGZsb29yKCh5ZWFyIC0gMTkwMSArIG1vbnRoKSAvIDEwMCkgKyBmbG9vcigoeWVhciAtIDE2MDEgKyBtb250aCkgLyA0MDApO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBJbnRlcm5hbDogRGV0ZXJtaW5lcyBpZiBhIHByb3BlcnR5IGlzIGEgZGlyZWN0IHByb3BlcnR5IG9mIHRoZSBnaXZlblxuICAgICAgLy8gb2JqZWN0LiBEZWxlZ2F0ZXMgdG8gdGhlIG5hdGl2ZSBgT2JqZWN0I2hhc093blByb3BlcnR5YCBtZXRob2QuXG4gICAgICBpZiAoIShpc1Byb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHkpKSB7XG4gICAgICAgIGlzUHJvcGVydHkgPSBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgICB2YXIgbWVtYmVycyA9IHt9LCBjb25zdHJ1Y3RvcjtcbiAgICAgICAgICBpZiAoKG1lbWJlcnMuX19wcm90b19fID0gbnVsbCwgbWVtYmVycy5fX3Byb3RvX18gPSB7XG4gICAgICAgICAgICAvLyBUaGUgKnByb3RvKiBwcm9wZXJ0eSBjYW5ub3QgYmUgc2V0IG11bHRpcGxlIHRpbWVzIGluIHJlY2VudFxuICAgICAgICAgICAgLy8gdmVyc2lvbnMgb2YgRmlyZWZveCBhbmQgU2VhTW9ua2V5LlxuICAgICAgICAgICAgXCJ0b1N0cmluZ1wiOiAxXG4gICAgICAgICAgfSwgbWVtYmVycykudG9TdHJpbmcgIT0gZ2V0Q2xhc3MpIHtcbiAgICAgICAgICAgIC8vIFNhZmFyaSA8PSAyLjAuMyBkb2Vzbid0IGltcGxlbWVudCBgT2JqZWN0I2hhc093blByb3BlcnR5YCwgYnV0XG4gICAgICAgICAgICAvLyBzdXBwb3J0cyB0aGUgbXV0YWJsZSAqcHJvdG8qIHByb3BlcnR5LlxuICAgICAgICAgICAgaXNQcm9wZXJ0eSA9IGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgICAgICAgICAgICAvLyBDYXB0dXJlIGFuZCBicmVhayB0aGUgb2JqZWN0Z3MgcHJvdG90eXBlIGNoYWluIChzZWUgc2VjdGlvbiA4LjYuMlxuICAgICAgICAgICAgICAvLyBvZiB0aGUgRVMgNS4xIHNwZWMpLiBUaGUgcGFyZW50aGVzaXplZCBleHByZXNzaW9uIHByZXZlbnRzIGFuXG4gICAgICAgICAgICAgIC8vIHVuc2FmZSB0cmFuc2Zvcm1hdGlvbiBieSB0aGUgQ2xvc3VyZSBDb21waWxlci5cbiAgICAgICAgICAgICAgdmFyIG9yaWdpbmFsID0gdGhpcy5fX3Byb3RvX18sIHJlc3VsdCA9IHByb3BlcnR5IGluICh0aGlzLl9fcHJvdG9fXyA9IG51bGwsIHRoaXMpO1xuICAgICAgICAgICAgICAvLyBSZXN0b3JlIHRoZSBvcmlnaW5hbCBwcm90b3R5cGUgY2hhaW4uXG4gICAgICAgICAgICAgIHRoaXMuX19wcm90b19fID0gb3JpZ2luYWw7XG4gICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBDYXB0dXJlIGEgcmVmZXJlbmNlIHRvIHRoZSB0b3AtbGV2ZWwgYE9iamVjdGAgY29uc3RydWN0b3IuXG4gICAgICAgICAgICBjb25zdHJ1Y3RvciA9IG1lbWJlcnMuY29uc3RydWN0b3I7XG4gICAgICAgICAgICAvLyBVc2UgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgdG8gc2ltdWxhdGUgYE9iamVjdCNoYXNPd25Qcm9wZXJ0eWAgaW5cbiAgICAgICAgICAgIC8vIG90aGVyIGVudmlyb25tZW50cy5cbiAgICAgICAgICAgIGlzUHJvcGVydHkgPSBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgdmFyIHBhcmVudCA9ICh0aGlzLmNvbnN0cnVjdG9yIHx8IGNvbnN0cnVjdG9yKS5wcm90b3R5cGU7XG4gICAgICAgICAgICAgIHJldHVybiBwcm9wZXJ0eSBpbiB0aGlzICYmICEocHJvcGVydHkgaW4gcGFyZW50ICYmIHRoaXNbcHJvcGVydHldID09PSBwYXJlbnRbcHJvcGVydHldKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIG1lbWJlcnMgPSBudWxsO1xuICAgICAgICAgIHJldHVybiBpc1Byb3BlcnR5LmNhbGwodGhpcywgcHJvcGVydHkpO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBJbnRlcm5hbDogQSBzZXQgb2YgcHJpbWl0aXZlIHR5cGVzIHVzZWQgYnkgYGlzSG9zdFR5cGVgLlxuICAgICAgdmFyIFByaW1pdGl2ZVR5cGVzID0ge1xuICAgICAgICBcImJvb2xlYW5cIjogMSxcbiAgICAgICAgXCJudW1iZXJcIjogMSxcbiAgICAgICAgXCJzdHJpbmdcIjogMSxcbiAgICAgICAgXCJ1bmRlZmluZWRcIjogMVxuICAgICAgfTtcblxuICAgICAgLy8gSW50ZXJuYWw6IERldGVybWluZXMgaWYgdGhlIGdpdmVuIG9iamVjdCBgcHJvcGVydHlgIHZhbHVlIGlzIGFcbiAgICAgIC8vIG5vbi1wcmltaXRpdmUuXG4gICAgICB2YXIgaXNIb3N0VHlwZSA9IGZ1bmN0aW9uIChvYmplY3QsIHByb3BlcnR5KSB7XG4gICAgICAgIHZhciB0eXBlID0gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV07XG4gICAgICAgIHJldHVybiB0eXBlID09IFwib2JqZWN0XCIgPyAhIW9iamVjdFtwcm9wZXJ0eV0gOiAhUHJpbWl0aXZlVHlwZXNbdHlwZV07XG4gICAgICB9O1xuXG4gICAgICAvLyBJbnRlcm5hbDogTm9ybWFsaXplcyB0aGUgYGZvci4uLmluYCBpdGVyYXRpb24gYWxnb3JpdGhtIGFjcm9zc1xuICAgICAgLy8gZW52aXJvbm1lbnRzLiBFYWNoIGVudW1lcmF0ZWQga2V5IGlzIHlpZWxkZWQgdG8gYSBgY2FsbGJhY2tgIGZ1bmN0aW9uLlxuICAgICAgZm9yRWFjaCA9IGZ1bmN0aW9uIChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBzaXplID0gMCwgUHJvcGVydGllcywgbWVtYmVycywgcHJvcGVydHk7XG5cbiAgICAgICAgLy8gVGVzdHMgZm9yIGJ1Z3MgaW4gdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQncyBgZm9yLi4uaW5gIGFsZ29yaXRobS4gVGhlXG4gICAgICAgIC8vIGB2YWx1ZU9mYCBwcm9wZXJ0eSBpbmhlcml0cyB0aGUgbm9uLWVudW1lcmFibGUgZmxhZyBmcm9tXG4gICAgICAgIC8vIGBPYmplY3QucHJvdG90eXBlYCBpbiBvbGRlciB2ZXJzaW9ucyBvZiBJRSwgTmV0c2NhcGUsIGFuZCBNb3ppbGxhLlxuICAgICAgICAoUHJvcGVydGllcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB0aGlzLnZhbHVlT2YgPSAwO1xuICAgICAgICB9KS5wcm90b3R5cGUudmFsdWVPZiA9IDA7XG5cbiAgICAgICAgLy8gSXRlcmF0ZSBvdmVyIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBgUHJvcGVydGllc2AgY2xhc3MuXG4gICAgICAgIG1lbWJlcnMgPSBuZXcgUHJvcGVydGllcygpO1xuICAgICAgICBmb3IgKHByb3BlcnR5IGluIG1lbWJlcnMpIHtcbiAgICAgICAgICAvLyBJZ25vcmUgYWxsIHByb3BlcnRpZXMgaW5oZXJpdGVkIGZyb20gYE9iamVjdC5wcm90b3R5cGVgLlxuICAgICAgICAgIGlmIChpc1Byb3BlcnR5LmNhbGwobWVtYmVycywgcHJvcGVydHkpKSB7XG4gICAgICAgICAgICBzaXplKys7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIFByb3BlcnRpZXMgPSBtZW1iZXJzID0gbnVsbDtcblxuICAgICAgICAvLyBOb3JtYWxpemUgdGhlIGl0ZXJhdGlvbiBhbGdvcml0aG0uXG4gICAgICAgIGlmICghc2l6ZSkge1xuICAgICAgICAgIC8vIEEgbGlzdCBvZiBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzIGluaGVyaXRlZCBmcm9tIGBPYmplY3QucHJvdG90eXBlYC5cbiAgICAgICAgICBtZW1iZXJzID0gW1widmFsdWVPZlwiLCBcInRvU3RyaW5nXCIsIFwidG9Mb2NhbGVTdHJpbmdcIiwgXCJwcm9wZXJ0eUlzRW51bWVyYWJsZVwiLCBcImlzUHJvdG90eXBlT2ZcIiwgXCJoYXNPd25Qcm9wZXJ0eVwiLCBcImNvbnN0cnVjdG9yXCJdO1xuICAgICAgICAgIC8vIElFIDw9IDgsIE1vemlsbGEgMS4wLCBhbmQgTmV0c2NhcGUgNi4yIGlnbm9yZSBzaGFkb3dlZCBub24tZW51bWVyYWJsZVxuICAgICAgICAgIC8vIHByb3BlcnRpZXMuXG4gICAgICAgICAgZm9yRWFjaCA9IGZ1bmN0aW9uIChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICB2YXIgaXNGdW5jdGlvbiA9IGdldENsYXNzLmNhbGwob2JqZWN0KSA9PSBmdW5jdGlvbkNsYXNzLCBwcm9wZXJ0eSwgbGVuZ3RoO1xuICAgICAgICAgICAgdmFyIGhhc1Byb3BlcnR5ID0gIWlzRnVuY3Rpb24gJiYgdHlwZW9mIG9iamVjdC5jb25zdHJ1Y3RvciAhPSBcImZ1bmN0aW9uXCIgJiYgaXNIb3N0VHlwZShvYmplY3QsIFwiaGFzT3duUHJvcGVydHlcIikgPyBvYmplY3QuaGFzT3duUHJvcGVydHkgOiBpc1Byb3BlcnR5O1xuICAgICAgICAgICAgZm9yIChwcm9wZXJ0eSBpbiBvYmplY3QpIHtcbiAgICAgICAgICAgICAgLy8gR2Vja28gPD0gMS4wIGVudW1lcmF0ZXMgdGhlIGBwcm90b3R5cGVgIHByb3BlcnR5IG9mIGZ1bmN0aW9ucyB1bmRlclxuICAgICAgICAgICAgICAvLyBjZXJ0YWluIGNvbmRpdGlvbnM7IElFIGRvZXMgbm90LlxuICAgICAgICAgICAgICBpZiAoIShpc0Z1bmN0aW9uICYmIHByb3BlcnR5ID09IFwicHJvdG90eXBlXCIpICYmIGhhc1Byb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSkpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhwcm9wZXJ0eSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIE1hbnVhbGx5IGludm9rZSB0aGUgY2FsbGJhY2sgZm9yIGVhY2ggbm9uLWVudW1lcmFibGUgcHJvcGVydHkuXG4gICAgICAgICAgICBmb3IgKGxlbmd0aCA9IG1lbWJlcnMubGVuZ3RoOyBwcm9wZXJ0eSA9IG1lbWJlcnNbLS1sZW5ndGhdOyBoYXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpICYmIGNhbGxiYWNrKHByb3BlcnR5KSk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmIChzaXplID09IDIpIHtcbiAgICAgICAgICAvLyBTYWZhcmkgPD0gMi4wLjQgZW51bWVyYXRlcyBzaGFkb3dlZCBwcm9wZXJ0aWVzIHR3aWNlLlxuICAgICAgICAgIGZvckVhY2ggPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgLy8gQ3JlYXRlIGEgc2V0IG9mIGl0ZXJhdGVkIHByb3BlcnRpZXMuXG4gICAgICAgICAgICB2YXIgbWVtYmVycyA9IHt9LCBpc0Z1bmN0aW9uID0gZ2V0Q2xhc3MuY2FsbChvYmplY3QpID09IGZ1bmN0aW9uQ2xhc3MsIHByb3BlcnR5O1xuICAgICAgICAgICAgZm9yIChwcm9wZXJ0eSBpbiBvYmplY3QpIHtcbiAgICAgICAgICAgICAgLy8gU3RvcmUgZWFjaCBwcm9wZXJ0eSBuYW1lIHRvIHByZXZlbnQgZG91YmxlIGVudW1lcmF0aW9uLiBUaGVcbiAgICAgICAgICAgICAgLy8gYHByb3RvdHlwZWAgcHJvcGVydHkgb2YgZnVuY3Rpb25zIGlzIG5vdCBlbnVtZXJhdGVkIGR1ZSB0byBjcm9zcy1cbiAgICAgICAgICAgICAgLy8gZW52aXJvbm1lbnQgaW5jb25zaXN0ZW5jaWVzLlxuICAgICAgICAgICAgICBpZiAoIShpc0Z1bmN0aW9uICYmIHByb3BlcnR5ID09IFwicHJvdG90eXBlXCIpICYmICFpc1Byb3BlcnR5LmNhbGwobWVtYmVycywgcHJvcGVydHkpICYmIChtZW1iZXJzW3Byb3BlcnR5XSA9IDEpICYmIGlzUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gTm8gYnVncyBkZXRlY3RlZDsgdXNlIHRoZSBzdGFuZGFyZCBgZm9yLi4uaW5gIGFsZ29yaXRobS5cbiAgICAgICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHZhciBpc0Z1bmN0aW9uID0gZ2V0Q2xhc3MuY2FsbChvYmplY3QpID09IGZ1bmN0aW9uQ2xhc3MsIHByb3BlcnR5LCBpc0NvbnN0cnVjdG9yO1xuICAgICAgICAgICAgZm9yIChwcm9wZXJ0eSBpbiBvYmplY3QpIHtcbiAgICAgICAgICAgICAgaWYgKCEoaXNGdW5jdGlvbiAmJiBwcm9wZXJ0eSA9PSBcInByb3RvdHlwZVwiKSAmJiBpc1Byb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSkgJiYgIShpc0NvbnN0cnVjdG9yID0gcHJvcGVydHkgPT09IFwiY29uc3RydWN0b3JcIikpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhwcm9wZXJ0eSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIE1hbnVhbGx5IGludm9rZSB0aGUgY2FsbGJhY2sgZm9yIHRoZSBgY29uc3RydWN0b3JgIHByb3BlcnR5IGR1ZSB0b1xuICAgICAgICAgICAgLy8gY3Jvc3MtZW52aXJvbm1lbnQgaW5jb25zaXN0ZW5jaWVzLlxuICAgICAgICAgICAgaWYgKGlzQ29uc3RydWN0b3IgfHwgaXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgKHByb3BlcnR5ID0gXCJjb25zdHJ1Y3RvclwiKSkpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2socHJvcGVydHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvckVhY2gob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgICB9O1xuXG4gICAgICAvLyBQdWJsaWM6IFNlcmlhbGl6ZXMgYSBKYXZhU2NyaXB0IGB2YWx1ZWAgYXMgYSBKU09OIHN0cmluZy4gVGhlIG9wdGlvbmFsXG4gICAgICAvLyBgZmlsdGVyYCBhcmd1bWVudCBtYXkgc3BlY2lmeSBlaXRoZXIgYSBmdW5jdGlvbiB0aGF0IGFsdGVycyBob3cgb2JqZWN0IGFuZFxuICAgICAgLy8gYXJyYXkgbWVtYmVycyBhcmUgc2VyaWFsaXplZCwgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncyBhbmQgbnVtYmVycyB0aGF0XG4gICAgICAvLyBpbmRpY2F0ZXMgd2hpY2ggcHJvcGVydGllcyBzaG91bGQgYmUgc2VyaWFsaXplZC4gVGhlIG9wdGlvbmFsIGB3aWR0aGBcbiAgICAgIC8vIGFyZ3VtZW50IG1heSBiZSBlaXRoZXIgYSBzdHJpbmcgb3IgbnVtYmVyIHRoYXQgc3BlY2lmaWVzIHRoZSBpbmRlbnRhdGlvblxuICAgICAgLy8gbGV2ZWwgb2YgdGhlIG91dHB1dC5cbiAgICAgIGlmICghaGFzKFwianNvbi1zdHJpbmdpZnlcIikpIHtcbiAgICAgICAgLy8gSW50ZXJuYWw6IEEgbWFwIG9mIGNvbnRyb2wgY2hhcmFjdGVycyBhbmQgdGhlaXIgZXNjYXBlZCBlcXVpdmFsZW50cy5cbiAgICAgICAgdmFyIEVzY2FwZXMgPSB7XG4gICAgICAgICAgOTI6IFwiXFxcXFxcXFxcIixcbiAgICAgICAgICAzNDogJ1xcXFxcIicsXG4gICAgICAgICAgODogXCJcXFxcYlwiLFxuICAgICAgICAgIDEyOiBcIlxcXFxmXCIsXG4gICAgICAgICAgMTA6IFwiXFxcXG5cIixcbiAgICAgICAgICAxMzogXCJcXFxcclwiLFxuICAgICAgICAgIDk6IFwiXFxcXHRcIlxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBDb252ZXJ0cyBgdmFsdWVgIGludG8gYSB6ZXJvLXBhZGRlZCBzdHJpbmcgc3VjaCB0aGF0IGl0c1xuICAgICAgICAvLyBsZW5ndGggaXMgYXQgbGVhc3QgZXF1YWwgdG8gYHdpZHRoYC4gVGhlIGB3aWR0aGAgbXVzdCBiZSA8PSA2LlxuICAgICAgICB2YXIgbGVhZGluZ1plcm9lcyA9IFwiMDAwMDAwXCI7XG4gICAgICAgIHZhciB0b1BhZGRlZFN0cmluZyA9IGZ1bmN0aW9uICh3aWR0aCwgdmFsdWUpIHtcbiAgICAgICAgICAvLyBUaGUgYHx8IDBgIGV4cHJlc3Npb24gaXMgbmVjZXNzYXJ5IHRvIHdvcmsgYXJvdW5kIGEgYnVnIGluXG4gICAgICAgICAgLy8gT3BlcmEgPD0gNy41NHUyIHdoZXJlIGAwID09IC0wYCwgYnV0IGBTdHJpbmcoLTApICE9PSBcIjBcImAuXG4gICAgICAgICAgcmV0dXJuIChsZWFkaW5nWmVyb2VzICsgKHZhbHVlIHx8IDApKS5zbGljZSgtd2lkdGgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBEb3VibGUtcXVvdGVzIGEgc3RyaW5nIGB2YWx1ZWAsIHJlcGxhY2luZyBhbGwgQVNDSUkgY29udHJvbFxuICAgICAgICAvLyBjaGFyYWN0ZXJzIChjaGFyYWN0ZXJzIHdpdGggY29kZSB1bml0IHZhbHVlcyBiZXR3ZWVuIDAgYW5kIDMxKSB3aXRoXG4gICAgICAgIC8vIHRoZWlyIGVzY2FwZWQgZXF1aXZhbGVudHMuIFRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlXG4gICAgICAgIC8vIGBRdW90ZSh2YWx1ZSlgIG9wZXJhdGlvbiBkZWZpbmVkIGluIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjMuXG4gICAgICAgIHZhciB1bmljb2RlUHJlZml4ID0gXCJcXFxcdTAwXCI7XG4gICAgICAgIHZhciBxdW90ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgIHZhciByZXN1bHQgPSAnXCInLCBpbmRleCA9IDAsIGxlbmd0aCA9IHZhbHVlLmxlbmd0aCwgdXNlQ2hhckluZGV4ID0gIWNoYXJJbmRleEJ1Z2d5IHx8IGxlbmd0aCA+IDEwO1xuICAgICAgICAgIHZhciBzeW1ib2xzID0gdXNlQ2hhckluZGV4ICYmIChjaGFySW5kZXhCdWdneSA/IHZhbHVlLnNwbGl0KFwiXCIpIDogdmFsdWUpO1xuICAgICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgdmFyIGNoYXJDb2RlID0gdmFsdWUuY2hhckNvZGVBdChpbmRleCk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgY2hhcmFjdGVyIGlzIGEgY29udHJvbCBjaGFyYWN0ZXIsIGFwcGVuZCBpdHMgVW5pY29kZSBvclxuICAgICAgICAgICAgLy8gc2hvcnRoYW5kIGVzY2FwZSBzZXF1ZW5jZTsgb3RoZXJ3aXNlLCBhcHBlbmQgdGhlIGNoYXJhY3RlciBhcy1pcy5cbiAgICAgICAgICAgIHN3aXRjaCAoY2hhckNvZGUpIHtcbiAgICAgICAgICAgICAgY2FzZSA4OiBjYXNlIDk6IGNhc2UgMTA6IGNhc2UgMTI6IGNhc2UgMTM6IGNhc2UgMzQ6IGNhc2UgOTI6XG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IEVzY2FwZXNbY2hhckNvZGVdO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA8IDMyKSB7XG4gICAgICAgICAgICAgICAgICByZXN1bHQgKz0gdW5pY29kZVByZWZpeCArIHRvUGFkZGVkU3RyaW5nKDIsIGNoYXJDb2RlLnRvU3RyaW5nKDE2KSk7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IHVzZUNoYXJJbmRleCA/IHN5bWJvbHNbaW5kZXhdIDogdmFsdWUuY2hhckF0KGluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdCArICdcIic7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZXMgYW4gb2JqZWN0LiBJbXBsZW1lbnRzIHRoZVxuICAgICAgICAvLyBgU3RyKGtleSwgaG9sZGVyKWAsIGBKTyh2YWx1ZSlgLCBhbmQgYEpBKHZhbHVlKWAgb3BlcmF0aW9ucy5cbiAgICAgICAgdmFyIHNlcmlhbGl6ZSA9IGZ1bmN0aW9uIChwcm9wZXJ0eSwgb2JqZWN0LCBjYWxsYmFjaywgcHJvcGVydGllcywgd2hpdGVzcGFjZSwgaW5kZW50YXRpb24sIHN0YWNrKSB7XG4gICAgICAgICAgdmFyIHZhbHVlLCBjbGFzc05hbWUsIHllYXIsIG1vbnRoLCBkYXRlLCB0aW1lLCBob3VycywgbWludXRlcywgc2Vjb25kcywgbWlsbGlzZWNvbmRzLCByZXN1bHRzLCBlbGVtZW50LCBpbmRleCwgbGVuZ3RoLCBwcmVmaXgsIHJlc3VsdDtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gTmVjZXNzYXJ5IGZvciBob3N0IG9iamVjdCBzdXBwb3J0LlxuICAgICAgICAgICAgdmFsdWUgPSBvYmplY3RbcHJvcGVydHldO1xuICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09IFwib2JqZWN0XCIgJiYgdmFsdWUpIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBkYXRlQ2xhc3MgJiYgIWlzUHJvcGVydHkuY2FsbCh2YWx1ZSwgXCJ0b0pTT05cIikpIHtcbiAgICAgICAgICAgICAgaWYgKHZhbHVlID4gLTEgLyAwICYmIHZhbHVlIDwgMSAvIDApIHtcbiAgICAgICAgICAgICAgICAvLyBEYXRlcyBhcmUgc2VyaWFsaXplZCBhY2NvcmRpbmcgdG8gdGhlIGBEYXRlI3RvSlNPTmAgbWV0aG9kXG4gICAgICAgICAgICAgICAgLy8gc3BlY2lmaWVkIGluIEVTIDUuMSBzZWN0aW9uIDE1LjkuNS40NC4gU2VlIHNlY3Rpb24gMTUuOS4xLjE1XG4gICAgICAgICAgICAgICAgLy8gZm9yIHRoZSBJU08gODYwMSBkYXRlIHRpbWUgc3RyaW5nIGZvcm1hdC5cbiAgICAgICAgICAgICAgICBpZiAoZ2V0RGF5KSB7XG4gICAgICAgICAgICAgICAgICAvLyBNYW51YWxseSBjb21wdXRlIHRoZSB5ZWFyLCBtb250aCwgZGF0ZSwgaG91cnMsIG1pbnV0ZXMsXG4gICAgICAgICAgICAgICAgICAvLyBzZWNvbmRzLCBhbmQgbWlsbGlzZWNvbmRzIGlmIHRoZSBgZ2V0VVRDKmAgbWV0aG9kcyBhcmVcbiAgICAgICAgICAgICAgICAgIC8vIGJ1Z2d5LiBBZGFwdGVkIGZyb20gQFlhZmZsZSdzIGBkYXRlLXNoaW1gIHByb2plY3QuXG4gICAgICAgICAgICAgICAgICBkYXRlID0gZmxvb3IodmFsdWUgLyA4NjRlNSk7XG4gICAgICAgICAgICAgICAgICBmb3IgKHllYXIgPSBmbG9vcihkYXRlIC8gMzY1LjI0MjUpICsgMTk3MCAtIDE7IGdldERheSh5ZWFyICsgMSwgMCkgPD0gZGF0ZTsgeWVhcisrKTtcbiAgICAgICAgICAgICAgICAgIGZvciAobW9udGggPSBmbG9vcigoZGF0ZSAtIGdldERheSh5ZWFyLCAwKSkgLyAzMC40Mik7IGdldERheSh5ZWFyLCBtb250aCArIDEpIDw9IGRhdGU7IG1vbnRoKyspO1xuICAgICAgICAgICAgICAgICAgZGF0ZSA9IDEgKyBkYXRlIC0gZ2V0RGF5KHllYXIsIG1vbnRoKTtcbiAgICAgICAgICAgICAgICAgIC8vIFRoZSBgdGltZWAgdmFsdWUgc3BlY2lmaWVzIHRoZSB0aW1lIHdpdGhpbiB0aGUgZGF5IChzZWUgRVNcbiAgICAgICAgICAgICAgICAgIC8vIDUuMSBzZWN0aW9uIDE1LjkuMS4yKS4gVGhlIGZvcm11bGEgYChBICUgQiArIEIpICUgQmAgaXMgdXNlZFxuICAgICAgICAgICAgICAgICAgLy8gdG8gY29tcHV0ZSBgQSBtb2R1bG8gQmAsIGFzIHRoZSBgJWAgb3BlcmF0b3IgZG9lcyBub3RcbiAgICAgICAgICAgICAgICAgIC8vIGNvcnJlc3BvbmQgdG8gdGhlIGBtb2R1bG9gIG9wZXJhdGlvbiBmb3IgbmVnYXRpdmUgbnVtYmVycy5cbiAgICAgICAgICAgICAgICAgIHRpbWUgPSAodmFsdWUgJSA4NjRlNSArIDg2NGU1KSAlIDg2NGU1O1xuICAgICAgICAgICAgICAgICAgLy8gVGhlIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLCBhbmQgbWlsbGlzZWNvbmRzIGFyZSBvYnRhaW5lZCBieVxuICAgICAgICAgICAgICAgICAgLy8gZGVjb21wb3NpbmcgdGhlIHRpbWUgd2l0aGluIHRoZSBkYXkuIFNlZSBzZWN0aW9uIDE1LjkuMS4xMC5cbiAgICAgICAgICAgICAgICAgIGhvdXJzID0gZmxvb3IodGltZSAvIDM2ZTUpICUgMjQ7XG4gICAgICAgICAgICAgICAgICBtaW51dGVzID0gZmxvb3IodGltZSAvIDZlNCkgJSA2MDtcbiAgICAgICAgICAgICAgICAgIHNlY29uZHMgPSBmbG9vcih0aW1lIC8gMWUzKSAlIDYwO1xuICAgICAgICAgICAgICAgICAgbWlsbGlzZWNvbmRzID0gdGltZSAlIDFlMztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgeWVhciA9IHZhbHVlLmdldFVUQ0Z1bGxZZWFyKCk7XG4gICAgICAgICAgICAgICAgICBtb250aCA9IHZhbHVlLmdldFVUQ01vbnRoKCk7XG4gICAgICAgICAgICAgICAgICBkYXRlID0gdmFsdWUuZ2V0VVRDRGF0ZSgpO1xuICAgICAgICAgICAgICAgICAgaG91cnMgPSB2YWx1ZS5nZXRVVENIb3VycygpO1xuICAgICAgICAgICAgICAgICAgbWludXRlcyA9IHZhbHVlLmdldFVUQ01pbnV0ZXMoKTtcbiAgICAgICAgICAgICAgICAgIHNlY29uZHMgPSB2YWx1ZS5nZXRVVENTZWNvbmRzKCk7XG4gICAgICAgICAgICAgICAgICBtaWxsaXNlY29uZHMgPSB2YWx1ZS5nZXRVVENNaWxsaXNlY29uZHMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gU2VyaWFsaXplIGV4dGVuZGVkIHllYXJzIGNvcnJlY3RseS5cbiAgICAgICAgICAgICAgICB2YWx1ZSA9ICh5ZWFyIDw9IDAgfHwgeWVhciA+PSAxZTQgPyAoeWVhciA8IDAgPyBcIi1cIiA6IFwiK1wiKSArIHRvUGFkZGVkU3RyaW5nKDYsIHllYXIgPCAwID8gLXllYXIgOiB5ZWFyKSA6IHRvUGFkZGVkU3RyaW5nKDQsIHllYXIpKSArXG4gICAgICAgICAgICAgICAgICBcIi1cIiArIHRvUGFkZGVkU3RyaW5nKDIsIG1vbnRoICsgMSkgKyBcIi1cIiArIHRvUGFkZGVkU3RyaW5nKDIsIGRhdGUpICtcbiAgICAgICAgICAgICAgICAgIC8vIE1vbnRocywgZGF0ZXMsIGhvdXJzLCBtaW51dGVzLCBhbmQgc2Vjb25kcyBzaG91bGQgaGF2ZSB0d29cbiAgICAgICAgICAgICAgICAgIC8vIGRpZ2l0czsgbWlsbGlzZWNvbmRzIHNob3VsZCBoYXZlIHRocmVlLlxuICAgICAgICAgICAgICAgICAgXCJUXCIgKyB0b1BhZGRlZFN0cmluZygyLCBob3VycykgKyBcIjpcIiArIHRvUGFkZGVkU3RyaW5nKDIsIG1pbnV0ZXMpICsgXCI6XCIgKyB0b1BhZGRlZFN0cmluZygyLCBzZWNvbmRzKSArXG4gICAgICAgICAgICAgICAgICAvLyBNaWxsaXNlY29uZHMgYXJlIG9wdGlvbmFsIGluIEVTIDUuMCwgYnV0IHJlcXVpcmVkIGluIDUuMS5cbiAgICAgICAgICAgICAgICAgIFwiLlwiICsgdG9QYWRkZWRTdHJpbmcoMywgbWlsbGlzZWNvbmRzKSArIFwiWlwiO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUudG9KU09OID09IFwiZnVuY3Rpb25cIiAmJiAoKGNsYXNzTmFtZSAhPSBudW1iZXJDbGFzcyAmJiBjbGFzc05hbWUgIT0gc3RyaW5nQ2xhc3MgJiYgY2xhc3NOYW1lICE9IGFycmF5Q2xhc3MpIHx8IGlzUHJvcGVydHkuY2FsbCh2YWx1ZSwgXCJ0b0pTT05cIikpKSB7XG4gICAgICAgICAgICAgIC8vIFByb3RvdHlwZSA8PSAxLjYuMSBhZGRzIG5vbi1zdGFuZGFyZCBgdG9KU09OYCBtZXRob2RzIHRvIHRoZVxuICAgICAgICAgICAgICAvLyBgTnVtYmVyYCwgYFN0cmluZ2AsIGBEYXRlYCwgYW5kIGBBcnJheWAgcHJvdG90eXBlcy4gSlNPTiAzXG4gICAgICAgICAgICAgIC8vIGlnbm9yZXMgYWxsIGB0b0pTT05gIG1ldGhvZHMgb24gdGhlc2Ugb2JqZWN0cyB1bmxlc3MgdGhleSBhcmVcbiAgICAgICAgICAgICAgLy8gZGVmaW5lZCBkaXJlY3RseSBvbiBhbiBpbnN0YW5jZS5cbiAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS50b0pTT04ocHJvcGVydHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgIC8vIElmIGEgcmVwbGFjZW1lbnQgZnVuY3Rpb24gd2FzIHByb3ZpZGVkLCBjYWxsIGl0IHRvIG9idGFpbiB0aGUgdmFsdWVcbiAgICAgICAgICAgIC8vIGZvciBzZXJpYWxpemF0aW9uLlxuICAgICAgICAgICAgdmFsdWUgPSBjYWxsYmFjay5jYWxsKG9iamVjdCwgcHJvcGVydHksIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwodmFsdWUpO1xuICAgICAgICAgIGlmIChjbGFzc05hbWUgPT0gYm9vbGVhbkNsYXNzKSB7XG4gICAgICAgICAgICAvLyBCb29sZWFucyBhcmUgcmVwcmVzZW50ZWQgbGl0ZXJhbGx5LlxuICAgICAgICAgICAgcmV0dXJuIFwiXCIgKyB2YWx1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTmFtZSA9PSBudW1iZXJDbGFzcykge1xuICAgICAgICAgICAgLy8gSlNPTiBudW1iZXJzIG11c3QgYmUgZmluaXRlLiBgSW5maW5pdHlgIGFuZCBgTmFOYCBhcmUgc2VyaWFsaXplZCBhc1xuICAgICAgICAgICAgLy8gYFwibnVsbFwiYC5cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZSA+IC0xIC8gMCAmJiB2YWx1ZSA8IDEgLyAwID8gXCJcIiArIHZhbHVlIDogXCJudWxsXCI7XG4gICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gc3RyaW5nQ2xhc3MpIHtcbiAgICAgICAgICAgIC8vIFN0cmluZ3MgYXJlIGRvdWJsZS1xdW90ZWQgYW5kIGVzY2FwZWQuXG4gICAgICAgICAgICByZXR1cm4gcXVvdGUoXCJcIiArIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gUmVjdXJzaXZlbHkgc2VyaWFsaXplIG9iamVjdHMgYW5kIGFycmF5cy5cbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGZvciBjeWNsaWMgc3RydWN0dXJlcy4gVGhpcyBpcyBhIGxpbmVhciBzZWFyY2g7IHBlcmZvcm1hbmNlXG4gICAgICAgICAgICAvLyBpcyBpbnZlcnNlbHkgcHJvcG9ydGlvbmFsIHRvIHRoZSBudW1iZXIgb2YgdW5pcXVlIG5lc3RlZCBvYmplY3RzLlxuICAgICAgICAgICAgZm9yIChsZW5ndGggPSBzdGFjay5sZW5ndGg7IGxlbmd0aC0tOykge1xuICAgICAgICAgICAgICBpZiAoc3RhY2tbbGVuZ3RoXSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBDeWNsaWMgc3RydWN0dXJlcyBjYW5ub3QgYmUgc2VyaWFsaXplZCBieSBgSlNPTi5zdHJpbmdpZnlgLlxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBBZGQgdGhlIG9iamVjdCB0byB0aGUgc3RhY2sgb2YgdHJhdmVyc2VkIG9iamVjdHMuXG4gICAgICAgICAgICBzdGFjay5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIC8vIFNhdmUgdGhlIGN1cnJlbnQgaW5kZW50YXRpb24gbGV2ZWwgYW5kIGluZGVudCBvbmUgYWRkaXRpb25hbCBsZXZlbC5cbiAgICAgICAgICAgIHByZWZpeCA9IGluZGVudGF0aW9uO1xuICAgICAgICAgICAgaW5kZW50YXRpb24gKz0gd2hpdGVzcGFjZTtcbiAgICAgICAgICAgIGlmIChjbGFzc05hbWUgPT0gYXJyYXlDbGFzcykge1xuICAgICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXJpYWxpemUgYXJyYXkgZWxlbWVudHMuXG4gICAgICAgICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSB2YWx1ZS5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IHNlcmlhbGl6ZShpbmRleCwgdmFsdWUsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCB3aGl0ZXNwYWNlLCBpbmRlbnRhdGlvbiwgc3RhY2spO1xuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChlbGVtZW50ID09PSB1bmRlZiA/IFwibnVsbFwiIDogZWxlbWVudCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0cy5sZW5ndGggPyAod2hpdGVzcGFjZSA/IFwiW1xcblwiICsgaW5kZW50YXRpb24gKyByZXN1bHRzLmpvaW4oXCIsXFxuXCIgKyBpbmRlbnRhdGlvbikgKyBcIlxcblwiICsgcHJlZml4ICsgXCJdXCIgOiAoXCJbXCIgKyByZXN1bHRzLmpvaW4oXCIsXCIpICsgXCJdXCIpKSA6IFwiW11cIjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZSBvYmplY3QgbWVtYmVycy4gTWVtYmVycyBhcmUgc2VsZWN0ZWQgZnJvbVxuICAgICAgICAgICAgICAvLyBlaXRoZXIgYSB1c2VyLXNwZWNpZmllZCBsaXN0IG9mIHByb3BlcnR5IG5hbWVzLCBvciB0aGUgb2JqZWN0XG4gICAgICAgICAgICAgIC8vIGl0c2VsZi5cbiAgICAgICAgICAgICAgZm9yRWFjaChwcm9wZXJ0aWVzIHx8IHZhbHVlLCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IHNlcmlhbGl6ZShwcm9wZXJ0eSwgdmFsdWUsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCB3aGl0ZXNwYWNlLCBpbmRlbnRhdGlvbiwgc3RhY2spO1xuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50ICE9PSB1bmRlZikge1xuICAgICAgICAgICAgICAgICAgLy8gQWNjb3JkaW5nIHRvIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjM6IFwiSWYgYGdhcGAge3doaXRlc3BhY2V9XG4gICAgICAgICAgICAgICAgICAvLyBpcyBub3QgdGhlIGVtcHR5IHN0cmluZywgbGV0IGBtZW1iZXJgIHtxdW90ZShwcm9wZXJ0eSkgKyBcIjpcIn1cbiAgICAgICAgICAgICAgICAgIC8vIGJlIHRoZSBjb25jYXRlbmF0aW9uIG9mIGBtZW1iZXJgIGFuZCB0aGUgYHNwYWNlYCBjaGFyYWN0ZXIuXCJcbiAgICAgICAgICAgICAgICAgIC8vIFRoZSBcImBzcGFjZWAgY2hhcmFjdGVyXCIgcmVmZXJzIHRvIHRoZSBsaXRlcmFsIHNwYWNlXG4gICAgICAgICAgICAgICAgICAvLyBjaGFyYWN0ZXIsIG5vdCB0aGUgYHNwYWNlYCB7d2lkdGh9IGFyZ3VtZW50IHByb3ZpZGVkIHRvXG4gICAgICAgICAgICAgICAgICAvLyBgSlNPTi5zdHJpbmdpZnlgLlxuICAgICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHF1b3RlKHByb3BlcnR5KSArIFwiOlwiICsgKHdoaXRlc3BhY2UgPyBcIiBcIiA6IFwiXCIpICsgZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0cy5sZW5ndGggPyAod2hpdGVzcGFjZSA/IFwie1xcblwiICsgaW5kZW50YXRpb24gKyByZXN1bHRzLmpvaW4oXCIsXFxuXCIgKyBpbmRlbnRhdGlvbikgKyBcIlxcblwiICsgcHJlZml4ICsgXCJ9XCIgOiAoXCJ7XCIgKyByZXN1bHRzLmpvaW4oXCIsXCIpICsgXCJ9XCIpKSA6IFwie31cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgb2JqZWN0IGZyb20gdGhlIHRyYXZlcnNlZCBvYmplY3Qgc3RhY2suXG4gICAgICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFB1YmxpYzogYEpTT04uc3RyaW5naWZ5YC4gU2VlIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjMuXG4gICAgICAgIGV4cG9ydHMuc3RyaW5naWZ5ID0gZnVuY3Rpb24gKHNvdXJjZSwgZmlsdGVyLCB3aWR0aCkge1xuICAgICAgICAgIHZhciB3aGl0ZXNwYWNlLCBjYWxsYmFjaywgcHJvcGVydGllcywgY2xhc3NOYW1lO1xuICAgICAgICAgIGlmICh0eXBlb2YgZmlsdGVyID09IFwiZnVuY3Rpb25cIiB8fCB0eXBlb2YgZmlsdGVyID09IFwib2JqZWN0XCIgJiYgZmlsdGVyKSB7XG4gICAgICAgICAgICBpZiAoKGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwoZmlsdGVyKSkgPT0gZnVuY3Rpb25DbGFzcykge1xuICAgICAgICAgICAgICBjYWxsYmFjayA9IGZpbHRlcjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IGFycmF5Q2xhc3MpIHtcbiAgICAgICAgICAgICAgLy8gQ29udmVydCB0aGUgcHJvcGVydHkgbmFtZXMgYXJyYXkgaW50byBhIG1ha2VzaGlmdCBzZXQuXG4gICAgICAgICAgICAgIHByb3BlcnRpZXMgPSB7fTtcbiAgICAgICAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwLCBsZW5ndGggPSBmaWx0ZXIubGVuZ3RoLCB2YWx1ZTsgaW5kZXggPCBsZW5ndGg7IHZhbHVlID0gZmlsdGVyW2luZGV4KytdLCAoKGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwodmFsdWUpKSwgY2xhc3NOYW1lID09IHN0cmluZ0NsYXNzIHx8IGNsYXNzTmFtZSA9PSBudW1iZXJDbGFzcykgJiYgKHByb3BlcnRpZXNbdmFsdWVdID0gMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAod2lkdGgpIHtcbiAgICAgICAgICAgIGlmICgoY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbCh3aWR0aCkpID09IG51bWJlckNsYXNzKSB7XG4gICAgICAgICAgICAgIC8vIENvbnZlcnQgdGhlIGB3aWR0aGAgdG8gYW4gaW50ZWdlciBhbmQgY3JlYXRlIGEgc3RyaW5nIGNvbnRhaW5pbmdcbiAgICAgICAgICAgICAgLy8gYHdpZHRoYCBudW1iZXIgb2Ygc3BhY2UgY2hhcmFjdGVycy5cbiAgICAgICAgICAgICAgaWYgKCh3aWR0aCAtPSB3aWR0aCAlIDEpID4gMCkge1xuICAgICAgICAgICAgICAgIGZvciAod2hpdGVzcGFjZSA9IFwiXCIsIHdpZHRoID4gMTAgJiYgKHdpZHRoID0gMTApOyB3aGl0ZXNwYWNlLmxlbmd0aCA8IHdpZHRoOyB3aGl0ZXNwYWNlICs9IFwiIFwiKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gc3RyaW5nQ2xhc3MpIHtcbiAgICAgICAgICAgICAgd2hpdGVzcGFjZSA9IHdpZHRoLmxlbmd0aCA8PSAxMCA/IHdpZHRoIDogd2lkdGguc2xpY2UoMCwgMTApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBPcGVyYSA8PSA3LjU0dTIgZGlzY2FyZHMgdGhlIHZhbHVlcyBhc3NvY2lhdGVkIHdpdGggZW1wdHkgc3RyaW5nIGtleXNcbiAgICAgICAgICAvLyAoYFwiXCJgKSBvbmx5IGlmIHRoZXkgYXJlIHVzZWQgZGlyZWN0bHkgd2l0aGluIGFuIG9iamVjdCBtZW1iZXIgbGlzdFxuICAgICAgICAgIC8vIChlLmcuLCBgIShcIlwiIGluIHsgXCJcIjogMX0pYCkuXG4gICAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZShcIlwiLCAodmFsdWUgPSB7fSwgdmFsdWVbXCJcIl0gPSBzb3VyY2UsIHZhbHVlKSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIHdoaXRlc3BhY2UsIFwiXCIsIFtdKTtcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgLy8gUHVibGljOiBQYXJzZXMgYSBKU09OIHNvdXJjZSBzdHJpbmcuXG4gICAgICBpZiAoIWhhcyhcImpzb24tcGFyc2VcIikpIHtcbiAgICAgICAgdmFyIGZyb21DaGFyQ29kZSA9IFN0cmluZy5mcm9tQ2hhckNvZGU7XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IEEgbWFwIG9mIGVzY2FwZWQgY29udHJvbCBjaGFyYWN0ZXJzIGFuZCB0aGVpciB1bmVzY2FwZWRcbiAgICAgICAgLy8gZXF1aXZhbGVudHMuXG4gICAgICAgIHZhciBVbmVzY2FwZXMgPSB7XG4gICAgICAgICAgOTI6IFwiXFxcXFwiLFxuICAgICAgICAgIDM0OiAnXCInLFxuICAgICAgICAgIDQ3OiBcIi9cIixcbiAgICAgICAgICA5ODogXCJcXGJcIixcbiAgICAgICAgICAxMTY6IFwiXFx0XCIsXG4gICAgICAgICAgMTEwOiBcIlxcblwiLFxuICAgICAgICAgIDEwMjogXCJcXGZcIixcbiAgICAgICAgICAxMTQ6IFwiXFxyXCJcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogU3RvcmVzIHRoZSBwYXJzZXIgc3RhdGUuXG4gICAgICAgIHZhciBJbmRleCwgU291cmNlO1xuXG4gICAgICAgIC8vIEludGVybmFsOiBSZXNldHMgdGhlIHBhcnNlciBzdGF0ZSBhbmQgdGhyb3dzIGEgYFN5bnRheEVycm9yYC5cbiAgICAgICAgdmFyIGFib3J0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIEluZGV4ID0gU291cmNlID0gbnVsbDtcbiAgICAgICAgICB0aHJvdyBTeW50YXhFcnJvcigpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBSZXR1cm5zIHRoZSBuZXh0IHRva2VuLCBvciBgXCIkXCJgIGlmIHRoZSBwYXJzZXIgaGFzIHJlYWNoZWRcbiAgICAgICAgLy8gdGhlIGVuZCBvZiB0aGUgc291cmNlIHN0cmluZy4gQSB0b2tlbiBtYXkgYmUgYSBzdHJpbmcsIG51bWJlciwgYG51bGxgXG4gICAgICAgIC8vIGxpdGVyYWwsIG9yIEJvb2xlYW4gbGl0ZXJhbC5cbiAgICAgICAgdmFyIGxleCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB2YXIgc291cmNlID0gU291cmNlLCBsZW5ndGggPSBzb3VyY2UubGVuZ3RoLCB2YWx1ZSwgYmVnaW4sIHBvc2l0aW9uLCBpc1NpZ25lZCwgY2hhckNvZGU7XG4gICAgICAgICAgd2hpbGUgKEluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgIHN3aXRjaCAoY2hhckNvZGUpIHtcbiAgICAgICAgICAgICAgY2FzZSA5OiBjYXNlIDEwOiBjYXNlIDEzOiBjYXNlIDMyOlxuICAgICAgICAgICAgICAgIC8vIFNraXAgd2hpdGVzcGFjZSB0b2tlbnMsIGluY2x1ZGluZyB0YWJzLCBjYXJyaWFnZSByZXR1cm5zLCBsaW5lXG4gICAgICAgICAgICAgICAgLy8gZmVlZHMsIGFuZCBzcGFjZSBjaGFyYWN0ZXJzLlxuICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgMTIzOiBjYXNlIDEyNTogY2FzZSA5MTogY2FzZSA5MzogY2FzZSA1ODogY2FzZSA0NDpcbiAgICAgICAgICAgICAgICAvLyBQYXJzZSBhIHB1bmN0dWF0b3IgdG9rZW4gKGB7YCwgYH1gLCBgW2AsIGBdYCwgYDpgLCBvciBgLGApIGF0XG4gICAgICAgICAgICAgICAgLy8gdGhlIGN1cnJlbnQgcG9zaXRpb24uXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBjaGFySW5kZXhCdWdneSA/IHNvdXJjZS5jaGFyQXQoSW5kZXgpIDogc291cmNlW0luZGV4XTtcbiAgICAgICAgICAgICAgICBJbmRleCsrO1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgY2FzZSAzNDpcbiAgICAgICAgICAgICAgICAvLyBgXCJgIGRlbGltaXRzIGEgSlNPTiBzdHJpbmc7IGFkdmFuY2UgdG8gdGhlIG5leHQgY2hhcmFjdGVyIGFuZFxuICAgICAgICAgICAgICAgIC8vIGJlZ2luIHBhcnNpbmcgdGhlIHN0cmluZy4gU3RyaW5nIHRva2VucyBhcmUgcHJlZml4ZWQgd2l0aCB0aGVcbiAgICAgICAgICAgICAgICAvLyBzZW50aW5lbCBgQGAgY2hhcmFjdGVyIHRvIGRpc3Rpbmd1aXNoIHRoZW0gZnJvbSBwdW5jdHVhdG9ycyBhbmRcbiAgICAgICAgICAgICAgICAvLyBlbmQtb2Ytc3RyaW5nIHRva2Vucy5cbiAgICAgICAgICAgICAgICBmb3IgKHZhbHVlID0gXCJAXCIsIEluZGV4Kys7IEluZGV4IDwgbGVuZ3RoOykge1xuICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7XG4gICAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPCAzMikge1xuICAgICAgICAgICAgICAgICAgICAvLyBVbmVzY2FwZWQgQVNDSUkgY29udHJvbCBjaGFyYWN0ZXJzICh0aG9zZSB3aXRoIGEgY29kZSB1bml0XG4gICAgICAgICAgICAgICAgICAgIC8vIGxlc3MgdGhhbiB0aGUgc3BhY2UgY2hhcmFjdGVyKSBhcmUgbm90IHBlcm1pdHRlZC5cbiAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hhckNvZGUgPT0gOTIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQSByZXZlcnNlIHNvbGlkdXMgKGBcXGApIG1hcmtzIHRoZSBiZWdpbm5pbmcgb2YgYW4gZXNjYXBlZFxuICAgICAgICAgICAgICAgICAgICAvLyBjb250cm9sIGNoYXJhY3RlciAoaW5jbHVkaW5nIGBcImAsIGBcXGAsIGFuZCBgL2ApIG9yIFVuaWNvZGVcbiAgICAgICAgICAgICAgICAgICAgLy8gZXNjYXBlIHNlcXVlbmNlLlxuICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNoYXJDb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgY2FzZSA5MjogY2FzZSAzNDogY2FzZSA0NzogY2FzZSA5ODogY2FzZSAxMTY6IGNhc2UgMTEwOiBjYXNlIDEwMjogY2FzZSAxMTQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXZpdmUgZXNjYXBlZCBjb250cm9sIGNoYXJhY3RlcnMuXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSArPSBVbmVzY2FwZXNbY2hhckNvZGVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgSW5kZXgrKztcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTE3OlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gYFxcdWAgbWFya3MgdGhlIGJlZ2lubmluZyBvZiBhIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWR2YW5jZSB0byB0aGUgZmlyc3QgY2hhcmFjdGVyIGFuZCB2YWxpZGF0ZSB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvdXItZGlnaXQgY29kZSBwb2ludC5cbiAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luID0gKytJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAocG9zaXRpb24gPSBJbmRleCArIDQ7IEluZGV4IDwgcG9zaXRpb247IEluZGV4KyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgdmFsaWQgc2VxdWVuY2UgY29tcHJpc2VzIGZvdXIgaGV4ZGlnaXRzIChjYXNlLVxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnNlbnNpdGl2ZSkgdGhhdCBmb3JtIGEgc2luZ2xlIGhleGFkZWNpbWFsIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1NyB8fCBjaGFyQ29kZSA+PSA5NyAmJiBjaGFyQ29kZSA8PSAxMDIgfHwgY2hhckNvZGUgPj0gNjUgJiYgY2hhckNvZGUgPD0gNzApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW52YWxpZCBVbmljb2RlIGVzY2FwZSBzZXF1ZW5jZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXZpdmUgdGhlIGVzY2FwZWQgY2hhcmFjdGVyLlxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gZnJvbUNoYXJDb2RlKFwiMHhcIiArIHNvdXJjZS5zbGljZShiZWdpbiwgSW5kZXgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZS5cbiAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSAzNCkge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIEFuIHVuZXNjYXBlZCBkb3VibGUtcXVvdGUgY2hhcmFjdGVyIG1hcmtzIHRoZSBlbmQgb2YgdGhlXG4gICAgICAgICAgICAgICAgICAgICAgLy8gc3RyaW5nLlxuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICBiZWdpbiA9IEluZGV4O1xuICAgICAgICAgICAgICAgICAgICAvLyBPcHRpbWl6ZSBmb3IgdGhlIGNvbW1vbiBjYXNlIHdoZXJlIGEgc3RyaW5nIGlzIHZhbGlkLlxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hhckNvZGUgPj0gMzIgJiYgY2hhckNvZGUgIT0gOTIgJiYgY2hhckNvZGUgIT0gMzQpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIEFwcGVuZCB0aGUgc3RyaW5nIGFzLWlzLlxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSArPSBzb3VyY2Uuc2xpY2UoYmVnaW4sIEluZGV4KTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KSA9PSAzNCkge1xuICAgICAgICAgICAgICAgICAgLy8gQWR2YW5jZSB0byB0aGUgbmV4dCBjaGFyYWN0ZXIgYW5kIHJldHVybiB0aGUgcmV2aXZlZCBzdHJpbmcuXG4gICAgICAgICAgICAgICAgICBJbmRleCsrO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBVbnRlcm1pbmF0ZWQgc3RyaW5nLlxuICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgLy8gUGFyc2UgbnVtYmVycyBhbmQgbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgYmVnaW4gPSBJbmRleDtcbiAgICAgICAgICAgICAgICAvLyBBZHZhbmNlIHBhc3QgdGhlIG5lZ2F0aXZlIHNpZ24sIGlmIG9uZSBpcyBzcGVjaWZpZWQuXG4gICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDQ1KSB7XG4gICAgICAgICAgICAgICAgICBpc1NpZ25lZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBQYXJzZSBhbiBpbnRlZ2VyIG9yIGZsb2F0aW5nLXBvaW50IHZhbHVlLlxuICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1Nykge1xuICAgICAgICAgICAgICAgICAgLy8gTGVhZGluZyB6ZXJvZXMgYXJlIGludGVycHJldGVkIGFzIG9jdGFsIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDQ4ICYmICgoY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCArIDEpKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElsbGVnYWwgb2N0YWwgbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGlzU2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAvLyBQYXJzZSB0aGUgaW50ZWdlciBjb21wb25lbnQuXG4gICAgICAgICAgICAgICAgICBmb3IgKDsgSW5kZXggPCBsZW5ndGggJiYgKChjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KSksIGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KTsgSW5kZXgrKyk7XG4gICAgICAgICAgICAgICAgICAvLyBGbG9hdHMgY2Fubm90IGNvbnRhaW4gYSBsZWFkaW5nIGRlY2ltYWwgcG9pbnQ7IGhvd2V2ZXIsIHRoaXNcbiAgICAgICAgICAgICAgICAgIC8vIGNhc2UgaXMgYWxyZWFkeSBhY2NvdW50ZWQgZm9yIGJ5IHRoZSBwYXJzZXIuXG4gICAgICAgICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpID09IDQ2KSB7XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gKytJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgdGhlIGRlY2ltYWwgY29tcG9uZW50LlxuICAgICAgICAgICAgICAgICAgICBmb3IgKDsgcG9zaXRpb24gPCBsZW5ndGggJiYgKChjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KHBvc2l0aW9uKSksIGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KTsgcG9zaXRpb24rKyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PSBJbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIElsbGVnYWwgdHJhaWxpbmcgZGVjaW1hbC5cbiAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEluZGV4ID0gcG9zaXRpb247XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAvLyBQYXJzZSBleHBvbmVudHMuIFRoZSBgZWAgZGVub3RpbmcgdGhlIGV4cG9uZW50IGlzXG4gICAgICAgICAgICAgICAgICAvLyBjYXNlLWluc2Vuc2l0aXZlLlxuICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7XG4gICAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gMTAxIHx8IGNoYXJDb2RlID09IDY5KSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNraXAgcGFzdCB0aGUgc2lnbiBmb2xsb3dpbmcgdGhlIGV4cG9uZW50LCBpZiBvbmUgaXNcbiAgICAgICAgICAgICAgICAgICAgLy8gc3BlY2lmaWVkLlxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gNDMgfHwgY2hhckNvZGUgPT0gNDUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBJbmRleCsrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBleHBvbmVudGlhbCBjb21wb25lbnQuXG4gICAgICAgICAgICAgICAgICAgIGZvciAocG9zaXRpb24gPSBJbmRleDsgcG9zaXRpb24gPCBsZW5ndGggJiYgKChjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KHBvc2l0aW9uKSksIGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KTsgcG9zaXRpb24rKyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PSBJbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIElsbGVnYWwgZW1wdHkgZXhwb25lbnQuXG4gICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBJbmRleCA9IHBvc2l0aW9uO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgLy8gQ29lcmNlIHRoZSBwYXJzZWQgdmFsdWUgdG8gYSBKYXZhU2NyaXB0IG51bWJlci5cbiAgICAgICAgICAgICAgICAgIHJldHVybiArc291cmNlLnNsaWNlKGJlZ2luLCBJbmRleCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEEgbmVnYXRpdmUgc2lnbiBtYXkgb25seSBwcmVjZWRlIG51bWJlcnMuXG4gICAgICAgICAgICAgICAgaWYgKGlzU2lnbmVkKSB7XG4gICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBgdHJ1ZWAsIGBmYWxzZWAsIGFuZCBgbnVsbGAgbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgaWYgKHNvdXJjZS5zbGljZShJbmRleCwgSW5kZXggKyA0KSA9PSBcInRydWVcIikge1xuICAgICAgICAgICAgICAgICAgSW5kZXggKz0gNDtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDUpID09IFwiZmFsc2VcIikge1xuICAgICAgICAgICAgICAgICAgSW5kZXggKz0gNTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNvdXJjZS5zbGljZShJbmRleCwgSW5kZXggKyA0KSA9PSBcIm51bGxcIikge1xuICAgICAgICAgICAgICAgICAgSW5kZXggKz0gNDtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBVbnJlY29nbml6ZWQgdG9rZW4uXG4gICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gUmV0dXJuIHRoZSBzZW50aW5lbCBgJGAgY2hhcmFjdGVyIGlmIHRoZSBwYXJzZXIgaGFzIHJlYWNoZWQgdGhlIGVuZFxuICAgICAgICAgIC8vIG9mIHRoZSBzb3VyY2Ugc3RyaW5nLlxuICAgICAgICAgIHJldHVybiBcIiRcIjtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogUGFyc2VzIGEgSlNPTiBgdmFsdWVgIHRva2VuLlxuICAgICAgICB2YXIgZ2V0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgdmFyIHJlc3VsdHMsIGhhc01lbWJlcnM7XG4gICAgICAgICAgaWYgKHZhbHVlID09IFwiJFwiKSB7XG4gICAgICAgICAgICAvLyBVbmV4cGVjdGVkIGVuZCBvZiBpbnB1dC5cbiAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgaWYgKChjaGFySW5kZXhCdWdneSA/IHZhbHVlLmNoYXJBdCgwKSA6IHZhbHVlWzBdKSA9PSBcIkBcIikge1xuICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIHNlbnRpbmVsIGBAYCBjaGFyYWN0ZXIuXG4gICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5zbGljZSgxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFBhcnNlIG9iamVjdCBhbmQgYXJyYXkgbGl0ZXJhbHMuXG4gICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJbXCIpIHtcbiAgICAgICAgICAgICAgLy8gUGFyc2VzIGEgSlNPTiBhcnJheSwgcmV0dXJuaW5nIGEgbmV3IEphdmFTY3JpcHQgYXJyYXkuXG4gICAgICAgICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgICAgZm9yICg7OyBoYXNNZW1iZXJzIHx8IChoYXNNZW1iZXJzID0gdHJ1ZSkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgIC8vIEEgY2xvc2luZyBzcXVhcmUgYnJhY2tldCBtYXJrcyB0aGUgZW5kIG9mIHRoZSBhcnJheSBsaXRlcmFsLlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIl1cIikge1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBhcnJheSBsaXRlcmFsIGNvbnRhaW5zIGVsZW1lbnRzLCB0aGUgY3VycmVudCB0b2tlblxuICAgICAgICAgICAgICAgIC8vIHNob3VsZCBiZSBhIGNvbW1hIHNlcGFyYXRpbmcgdGhlIHByZXZpb3VzIGVsZW1lbnQgZnJvbSB0aGVcbiAgICAgICAgICAgICAgICAvLyBuZXh0LlxuICAgICAgICAgICAgICAgIGlmIChoYXNNZW1iZXJzKSB7XG4gICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCIsXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBsZXgoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiXVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gVW5leHBlY3RlZCB0cmFpbGluZyBgLGAgaW4gYXJyYXkgbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBBIGAsYCBtdXN0IHNlcGFyYXRlIGVhY2ggYXJyYXkgZWxlbWVudC5cbiAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gRWxpc2lvbnMgYW5kIGxlYWRpbmcgY29tbWFzIGFyZSBub3QgcGVybWl0dGVkLlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIixcIikge1xuICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGdldCh2YWx1ZSkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PSBcIntcIikge1xuICAgICAgICAgICAgICAvLyBQYXJzZXMgYSBKU09OIG9iamVjdCwgcmV0dXJuaW5nIGEgbmV3IEphdmFTY3JpcHQgb2JqZWN0LlxuICAgICAgICAgICAgICByZXN1bHRzID0ge307XG4gICAgICAgICAgICAgIGZvciAoOzsgaGFzTWVtYmVycyB8fCAoaGFzTWVtYmVycyA9IHRydWUpKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBsZXgoKTtcbiAgICAgICAgICAgICAgICAvLyBBIGNsb3NpbmcgY3VybHkgYnJhY2UgbWFya3MgdGhlIGVuZCBvZiB0aGUgb2JqZWN0IGxpdGVyYWwuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwifVwiKSB7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIG9iamVjdCBsaXRlcmFsIGNvbnRhaW5zIG1lbWJlcnMsIHRoZSBjdXJyZW50IHRva2VuXG4gICAgICAgICAgICAgICAgLy8gc2hvdWxkIGJlIGEgY29tbWEgc2VwYXJhdG9yLlxuICAgICAgICAgICAgICAgIGlmIChoYXNNZW1iZXJzKSB7XG4gICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCIsXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBsZXgoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwifVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gVW5leHBlY3RlZCB0cmFpbGluZyBgLGAgaW4gb2JqZWN0IGxpdGVyYWwuXG4gICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQSBgLGAgbXVzdCBzZXBhcmF0ZSBlYWNoIG9iamVjdCBtZW1iZXIuXG4gICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIExlYWRpbmcgY29tbWFzIGFyZSBub3QgcGVybWl0dGVkLCBvYmplY3QgcHJvcGVydHkgbmFtZXMgbXVzdCBiZVxuICAgICAgICAgICAgICAgIC8vIGRvdWJsZS1xdW90ZWQgc3RyaW5ncywgYW5kIGEgYDpgIG11c3Qgc2VwYXJhdGUgZWFjaCBwcm9wZXJ0eVxuICAgICAgICAgICAgICAgIC8vIG5hbWUgYW5kIHZhbHVlLlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIixcIiB8fCB0eXBlb2YgdmFsdWUgIT0gXCJzdHJpbmdcIiB8fCAoY2hhckluZGV4QnVnZ3kgPyB2YWx1ZS5jaGFyQXQoMCkgOiB2YWx1ZVswXSkgIT0gXCJAXCIgfHwgbGV4KCkgIT0gXCI6XCIpIHtcbiAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc3VsdHNbdmFsdWUuc2xpY2UoMSldID0gZ2V0KGxleCgpKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgdG9rZW4gZW5jb3VudGVyZWQuXG4gICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFVwZGF0ZXMgYSB0cmF2ZXJzZWQgb2JqZWN0IG1lbWJlci5cbiAgICAgICAgdmFyIHVwZGF0ZSA9IGZ1bmN0aW9uIChzb3VyY2UsIHByb3BlcnR5LCBjYWxsYmFjaykge1xuICAgICAgICAgIHZhciBlbGVtZW50ID0gd2Fsayhzb3VyY2UsIHByb3BlcnR5LCBjYWxsYmFjayk7XG4gICAgICAgICAgaWYgKGVsZW1lbnQgPT09IHVuZGVmKSB7XG4gICAgICAgICAgICBkZWxldGUgc291cmNlW3Byb3BlcnR5XTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc291cmNlW3Byb3BlcnR5XSA9IGVsZW1lbnQ7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBSZWN1cnNpdmVseSB0cmF2ZXJzZXMgYSBwYXJzZWQgSlNPTiBvYmplY3QsIGludm9raW5nIHRoZVxuICAgICAgICAvLyBgY2FsbGJhY2tgIGZ1bmN0aW9uIGZvciBlYWNoIHZhbHVlLiBUaGlzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZVxuICAgICAgICAvLyBgV2Fsayhob2xkZXIsIG5hbWUpYCBvcGVyYXRpb24gZGVmaW5lZCBpbiBFUyA1LjEgc2VjdGlvbiAxNS4xMi4yLlxuICAgICAgICB2YXIgd2FsayA9IGZ1bmN0aW9uIChzb3VyY2UsIHByb3BlcnR5LCBjYWxsYmFjaykge1xuICAgICAgICAgIHZhciB2YWx1ZSA9IHNvdXJjZVtwcm9wZXJ0eV0sIGxlbmd0aDtcbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09IFwib2JqZWN0XCIgJiYgdmFsdWUpIHtcbiAgICAgICAgICAgIC8vIGBmb3JFYWNoYCBjYW4ndCBiZSB1c2VkIHRvIHRyYXZlcnNlIGFuIGFycmF5IGluIE9wZXJhIDw9IDguNTRcbiAgICAgICAgICAgIC8vIGJlY2F1c2UgaXRzIGBPYmplY3QjaGFzT3duUHJvcGVydHlgIGltcGxlbWVudGF0aW9uIHJldHVybnMgYGZhbHNlYFxuICAgICAgICAgICAgLy8gZm9yIGFycmF5IGluZGljZXMgKGUuZy4sIGAhWzEsIDIsIDNdLmhhc093blByb3BlcnR5KFwiMFwiKWApLlxuICAgICAgICAgICAgaWYgKGdldENsYXNzLmNhbGwodmFsdWUpID09IGFycmF5Q2xhc3MpIHtcbiAgICAgICAgICAgICAgZm9yIChsZW5ndGggPSB2YWx1ZS5sZW5ndGg7IGxlbmd0aC0tOykge1xuICAgICAgICAgICAgICAgIHVwZGF0ZSh2YWx1ZSwgbGVuZ3RoLCBjYWxsYmFjayk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGZvckVhY2godmFsdWUsIGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgICAgICAgICAgICAgIHVwZGF0ZSh2YWx1ZSwgcHJvcGVydHksIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKHNvdXJjZSwgcHJvcGVydHksIHZhbHVlKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBQdWJsaWM6IGBKU09OLnBhcnNlYC4gU2VlIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjIuXG4gICAgICAgIGV4cG9ydHMucGFyc2UgPSBmdW5jdGlvbiAoc291cmNlLCBjYWxsYmFjaykge1xuICAgICAgICAgIHZhciByZXN1bHQsIHZhbHVlO1xuICAgICAgICAgIEluZGV4ID0gMDtcbiAgICAgICAgICBTb3VyY2UgPSBcIlwiICsgc291cmNlO1xuICAgICAgICAgIHJlc3VsdCA9IGdldChsZXgoKSk7XG4gICAgICAgICAgLy8gSWYgYSBKU09OIHN0cmluZyBjb250YWlucyBtdWx0aXBsZSB0b2tlbnMsIGl0IGlzIGludmFsaWQuXG4gICAgICAgICAgaWYgKGxleCgpICE9IFwiJFwiKSB7XG4gICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBSZXNldCB0aGUgcGFyc2VyIHN0YXRlLlxuICAgICAgICAgIEluZGV4ID0gU291cmNlID0gbnVsbDtcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sgJiYgZ2V0Q2xhc3MuY2FsbChjYWxsYmFjaykgPT0gZnVuY3Rpb25DbGFzcyA/IHdhbGsoKHZhbHVlID0ge30sIHZhbHVlW1wiXCJdID0gcmVzdWx0LCB2YWx1ZSksIFwiXCIsIGNhbGxiYWNrKSA6IHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBleHBvcnRzW1wicnVuSW5Db250ZXh0XCJdID0gcnVuSW5Db250ZXh0O1xuICAgIHJldHVybiBleHBvcnRzO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBleHBvcnRzID09IFwib2JqZWN0XCIgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiAhaXNMb2FkZXIpIHtcbiAgICAvLyBFeHBvcnQgZm9yIENvbW1vbkpTIGVudmlyb25tZW50cy5cbiAgICBydW5JbkNvbnRleHQocm9vdCwgZXhwb3J0cyk7XG4gIH0gZWxzZSB7XG4gICAgLy8gRXhwb3J0IGZvciB3ZWIgYnJvd3NlcnMgYW5kIEphdmFTY3JpcHQgZW5naW5lcy5cbiAgICB2YXIgbmF0aXZlSlNPTiA9IHJvb3QuSlNPTjtcbiAgICB2YXIgSlNPTjMgPSBydW5JbkNvbnRleHQocm9vdCwgKHJvb3RbXCJKU09OM1wiXSA9IHtcbiAgICAgIC8vIFB1YmxpYzogUmVzdG9yZXMgdGhlIG9yaWdpbmFsIHZhbHVlIG9mIHRoZSBnbG9iYWwgYEpTT05gIG9iamVjdCBhbmRcbiAgICAgIC8vIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIGBKU09OM2Agb2JqZWN0LlxuICAgICAgXCJub0NvbmZsaWN0XCI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcm9vdC5KU09OID0gbmF0aXZlSlNPTjtcbiAgICAgICAgcmV0dXJuIEpTT04zO1xuICAgICAgfVxuICAgIH0pKTtcblxuICAgIHJvb3QuSlNPTiA9IHtcbiAgICAgIFwicGFyc2VcIjogSlNPTjMucGFyc2UsXG4gICAgICBcInN0cmluZ2lmeVwiOiBKU09OMy5zdHJpbmdpZnlcbiAgICB9O1xuICB9XG5cbiAgLy8gRXhwb3J0IGZvciBhc3luY2hyb25vdXMgbW9kdWxlIGxvYWRlcnMuXG4gIGlmIChpc0xvYWRlcikge1xuICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gSlNPTjM7XG4gICAgfSk7XG4gIH1cbn0odGhpcykpO1xuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLy8gVGhpcyBpcyBhIHJlcG9ydGVyIHRoYXQgbWltaWNzIE1vY2hhJ3MgYGRvdGAgcmVwb3J0ZXJcblxudmFyIFIgPSByZXF1aXJlKFwiLi4vbGliL3JlcG9ydGVyXCIpXG5cbmZ1bmN0aW9uIHdpZHRoKCkge1xuICAgIHJldHVybiBSLndpbmRvd1dpZHRoKCkgKiA0IC8gMyB8IDBcbn1cblxuZnVuY3Rpb24gcHJpbnREb3QoXywgY29sb3IpIHtcbiAgICBmdW5jdGlvbiBlbWl0KCkge1xuICAgICAgICByZXR1cm4gXy53cml0ZShSLmNvbG9yKGNvbG9yLFxuICAgICAgICAgICAgY29sb3IgPT09IFwiZmFpbFwiID8gUi5zeW1ib2xzKCkuRG90RmFpbCA6IFIuc3ltYm9scygpLkRvdCkpXG4gICAgfVxuXG4gICAgaWYgKF8uc3RhdGUuY291bnRlcisrICUgd2lkdGgoKSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gXy53cml0ZShSLm5ld2xpbmUoKSArIFwiICBcIikudGhlbihlbWl0KVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBlbWl0KClcbiAgICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gUi5vbihcImRvdFwiLCB7XG4gICAgYWNjZXB0czogW1wid3JpdGVcIiwgXCJyZXNldFwiLCBcImNvbG9yc1wiXSxcbiAgICBjcmVhdGU6IFIuY29uc29sZVJlcG9ydGVyLFxuICAgIGJlZm9yZTogUi5zZXRDb2xvcixcbiAgICBhZnRlcjogUi51bnNldENvbG9yLFxuICAgIGluaXQ6IGZ1bmN0aW9uIChzdGF0ZSkgeyBzdGF0ZS5jb3VudGVyID0gMCB9LFxuXG4gICAgcmVwb3J0OiBmdW5jdGlvbiAoXywgcmVwb3J0KSB7XG4gICAgICAgIGlmIChyZXBvcnQuaXNFbnRlciB8fCByZXBvcnQuaXNQYXNzKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJpbnREb3QoXywgUi5zcGVlZChyZXBvcnQpKVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0hvb2sgfHwgcmVwb3J0LmlzRmFpbCkge1xuICAgICAgICAgICAgXy5wdXNoRXJyb3IocmVwb3J0KVxuICAgICAgICAgICAgLy8gUHJpbnQgYSBkb3QgcmVnYXJkbGVzcyBvZiBob29rIHN1Y2Nlc3NcbiAgICAgICAgICAgIHJldHVybiBwcmludERvdChfLCBcImZhaWxcIilcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNTa2lwKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJpbnREb3QoXywgXCJza2lwXCIpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzRW5kKSB7XG4gICAgICAgICAgICByZXR1cm4gXy5wcmludCgpLnRoZW4oXy5wcmludFJlc3VsdHMuYmluZChfKSlcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFcnJvcikge1xuICAgICAgICAgICAgaWYgKF8uc3RhdGUuY291bnRlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBfLnByaW50KCkudGhlbihfLnByaW50RXJyb3IuYmluZChfLCByZXBvcnQpKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXy5wcmludEVycm9yKHJlcG9ydClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgfVxuICAgIH0sXG59KVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuZXhwb3J0cy5kb3QgPSByZXF1aXJlKFwiLi9kb3RcIilcbmV4cG9ydHMuc3BlYyA9IHJlcXVpcmUoXCIuL3NwZWNcIilcbmV4cG9ydHMudGFwID0gcmVxdWlyZShcIi4vdGFwXCIpXG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vLyBUaGlzIGlzIGEgcmVwb3J0ZXIgdGhhdCBtaW1pY3MgTW9jaGEncyBgc3BlY2AgcmVwb3J0ZXIuXG5cbnZhciBSID0gcmVxdWlyZShcIi4uL2xpYi9yZXBvcnRlclwiKVxudmFyIGMgPSBSLmNvbG9yXG5cbmZ1bmN0aW9uIGluZGVudChsZXZlbCkge1xuICAgIHZhciByZXQgPSBcIlwiXG5cbiAgICB3aGlsZSAobGV2ZWwtLSkgcmV0ICs9IFwiICBcIlxuICAgIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gZ2V0TmFtZShsZXZlbCwgcmVwb3J0KSB7XG4gICAgcmV0dXJuIHJlcG9ydC5wYXRoW2xldmVsIC0gMV0ubmFtZVxufVxuXG5mdW5jdGlvbiBwcmludFJlcG9ydChfLCByZXBvcnQsIGluaXQpIHtcbiAgICBpZiAoXy5zdGF0ZS5sZWF2aW5nKSB7XG4gICAgICAgIF8uc3RhdGUubGVhdmluZyA9IGZhbHNlXG4gICAgICAgIHJldHVybiBfLnByaW50KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gXy5wcmludChpbmRlbnQoXy5zdGF0ZS5sZXZlbCkgKyBpbml0KCkpXG4gICAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIF8ucHJpbnQoaW5kZW50KF8uc3RhdGUubGV2ZWwpICsgaW5pdCgpKVxuICAgIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSLm9uKFwic3BlY1wiLCB7XG4gICAgYWNjZXB0czogW1wid3JpdGVcIiwgXCJyZXNldFwiLCBcImNvbG9yc1wiXSxcbiAgICBjcmVhdGU6IFIuY29uc29sZVJlcG9ydGVyLFxuICAgIGJlZm9yZTogUi5zZXRDb2xvcixcbiAgICBhZnRlcjogUi51bnNldENvbG9yLFxuXG4gICAgaW5pdDogZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgICAgIHN0YXRlLmxldmVsID0gMVxuICAgICAgICBzdGF0ZS5sZWF2aW5nID0gZmFsc2VcbiAgICB9LFxuXG4gICAgcmVwb3J0OiBmdW5jdGlvbiAoXywgcmVwb3J0KSB7XG4gICAgICAgIGlmIChyZXBvcnQuaXNTdGFydCkge1xuICAgICAgICAgICAgcmV0dXJuIF8ucHJpbnQoKVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0VudGVyKSB7XG4gICAgICAgICAgICB2YXIgbGV2ZWwgPSBfLnN0YXRlLmxldmVsKytcbiAgICAgICAgICAgIHZhciBsYXN0ID0gcmVwb3J0LnBhdGhbbGV2ZWwgLSAxXVxuXG4gICAgICAgICAgICBfLnN0YXRlLmxlYXZpbmcgPSBmYWxzZVxuICAgICAgICAgICAgaWYgKGxhc3QuaW5kZXgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXy5wcmludCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gXy5wcmludChpbmRlbnQobGV2ZWwpICsgbGFzdC5uYW1lKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBfLnByaW50KGluZGVudChsZXZlbCkgKyBsYXN0Lm5hbWUpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzTGVhdmUpIHtcbiAgICAgICAgICAgIF8uc3RhdGUubGV2ZWwtLVxuICAgICAgICAgICAgXy5zdGF0ZS5sZWF2aW5nID0gdHJ1ZVxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc1Bhc3MpIHtcbiAgICAgICAgICAgIHJldHVybiBwcmludFJlcG9ydChfLCByZXBvcnQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgc3RyID1cbiAgICAgICAgICAgICAgICAgICAgYyhcImNoZWNrbWFya1wiLCBSLnN5bWJvbHMoKS5QYXNzICsgXCIgXCIpICtcbiAgICAgICAgICAgICAgICAgICAgYyhcInBhc3NcIiwgZ2V0TmFtZShfLnN0YXRlLmxldmVsLCByZXBvcnQpKVxuXG4gICAgICAgICAgICAgICAgdmFyIHNwZWVkID0gUi5zcGVlZChyZXBvcnQpXG5cbiAgICAgICAgICAgICAgICBpZiAoc3BlZWQgIT09IFwiZmFzdFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0ciArPSBjKHNwZWVkLCBcIiAoXCIgKyByZXBvcnQuZHVyYXRpb24gKyBcIm1zKVwiKVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBzdHJcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzSG9vayB8fCByZXBvcnQuaXNGYWlsKSB7XG4gICAgICAgICAgICBfLnB1c2hFcnJvcihyZXBvcnQpXG5cbiAgICAgICAgICAgIC8vIERvbid0IHByaW50IHRoZSBkZXNjcmlwdGlvbiBsaW5lIG9uIGN1bXVsYXRpdmUgaG9va3NcbiAgICAgICAgICAgIGlmIChyZXBvcnQuaXNIb29rICYmIChyZXBvcnQuaXNCZWZvcmVBbGwgfHwgcmVwb3J0LmlzQWZ0ZXJBbGwpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcHJpbnRSZXBvcnQoXywgcmVwb3J0LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGMoXCJmYWlsXCIsXG4gICAgICAgICAgICAgICAgICAgIF8uZXJyb3JzLmxlbmd0aCArIFwiKSBcIiArIGdldE5hbWUoXy5zdGF0ZS5sZXZlbCwgcmVwb3J0KSArXG4gICAgICAgICAgICAgICAgICAgIFIuZm9ybWF0UmVzdChyZXBvcnQpKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNTa2lwKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJpbnRSZXBvcnQoXywgcmVwb3J0LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGMoXCJza2lwXCIsIFwiLSBcIiArIGdldE5hbWUoXy5zdGF0ZS5sZXZlbCwgcmVwb3J0KSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVwb3J0LmlzRW5kKSByZXR1cm4gXy5wcmludFJlc3VsdHMoKVxuICAgICAgICBpZiAocmVwb3J0LmlzRXJyb3IpIHJldHVybiBfLnByaW50RXJyb3IocmVwb3J0KVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vLyBUaGlzIGlzIGEgYmFzaWMgVEFQLWdlbmVyYXRpbmcgcmVwb3J0ZXIuXG5cbnZhciBwZWFjaCA9IHJlcXVpcmUoXCIuLi9saWIvdXRpbFwiKS5wZWFjaFxudmFyIFIgPSByZXF1aXJlKFwiLi4vbGliL3JlcG9ydGVyXCIpXG52YXIgaW5zcGVjdCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKS5pbnNwZWN0XG5cbmZ1bmN0aW9uIHNob3VsZEJyZWFrKG1pbkxlbmd0aCwgc3RyKSB7XG4gICAgcmV0dXJuIHN0ci5sZW5ndGggPiBSLndpbmRvd1dpZHRoKCkgLSBtaW5MZW5ndGggfHwgL1xccj9cXG58Wzo/LV0vLnRlc3Qoc3RyKVxufVxuXG5mdW5jdGlvbiB0ZW1wbGF0ZShfLCByZXBvcnQsIHRtcGwsIHNraXApIHtcbiAgICBpZiAoIXNraXApIF8uc3RhdGUuY291bnRlcisrXG4gICAgdmFyIHBhdGggPSBSLmpvaW5QYXRoKHJlcG9ydCkucmVwbGFjZSgvXFwkL2csIFwiJCQkJFwiKVxuXG4gICAgcmV0dXJuIF8ucHJpbnQoXG4gICAgICAgIHRtcGwucmVwbGFjZSgvJWMvZywgXy5zdGF0ZS5jb3VudGVyKVxuICAgICAgICAgICAgLnJlcGxhY2UoLyVwL2csIHBhdGggKyBSLmZvcm1hdFJlc3QocmVwb3J0KSkpXG59XG5cbmZ1bmN0aW9uIHByaW50TGluZXMoXywgdmFsdWUsIHNraXBGaXJzdCkge1xuICAgIHZhciBsaW5lcyA9IHZhbHVlLnNwbGl0KC9cXHI/XFxuL2cpXG5cbiAgICBpZiAoc2tpcEZpcnN0KSBsaW5lcy5zaGlmdCgpXG4gICAgcmV0dXJuIHBlYWNoKGxpbmVzLCBmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gXy5wcmludChcIiAgICBcIiArIGxpbmUpIH0pXG59XG5cbmZ1bmN0aW9uIHByaW50UmF3KF8sIGtleSwgc3RyKSB7XG4gICAgaWYgKHNob3VsZEJyZWFrKGtleS5sZW5ndGgsIHN0cikpIHtcbiAgICAgICAgcmV0dXJuIF8ucHJpbnQoXCIgIFwiICsga2V5ICsgXCI6IHwtXCIpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHByaW50TGluZXMoXywgc3RyLCBmYWxzZSkgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gXy5wcmludChcIiAgXCIgKyBrZXkgKyBcIjogXCIgKyBzdHIpXG4gICAgfVxufVxuXG5mdW5jdGlvbiBwcmludFZhbHVlKF8sIGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gcHJpbnRSYXcoXywga2V5LCBpbnNwZWN0KHZhbHVlKSlcbn1cblxuZnVuY3Rpb24gcHJpbnRMaW5lKHAsIF8sIGxpbmUpIHtcbiAgICByZXR1cm4gcC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIF8ucHJpbnQobGluZSkgfSlcbn1cblxuZnVuY3Rpb24gcHJpbnRFcnJvcihfLCByZXBvcnQpIHtcbiAgICB2YXIgZXJyID0gcmVwb3J0LmVycm9yXG5cbiAgICBpZiAoIShlcnIgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgcmV0dXJuIHByaW50VmFsdWUoXywgXCJ2YWx1ZVwiLCBlcnIpXG4gICAgfVxuXG4gICAgLy8gTGV0J3MgKm5vdCogZGVwZW5kIG9uIHRoZSBjb25zdHJ1Y3RvciBiZWluZyBUaGFsbGl1bSdzLi4uXG4gICAgaWYgKGVyci5uYW1lICE9PSBcIkFzc2VydGlvbkVycm9yXCIpIHtcbiAgICAgICAgcmV0dXJuIF8ucHJpbnQoXCIgIHN0YWNrOiB8LVwiKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBwcmludExpbmVzKF8sIFIuZ2V0U3RhY2soZXJyKSwgZmFsc2UpXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHByaW50VmFsdWUoXywgXCJleHBlY3RlZFwiLCBlcnIuZXhwZWN0ZWQpXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcHJpbnRWYWx1ZShfLCBcImFjdHVhbFwiLCBlcnIuYWN0dWFsKSB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHByaW50UmF3KF8sIFwibWVzc2FnZVwiLCBlcnIubWVzc2FnZSkgfSlcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBfLnByaW50KFwiICBzdGFjazogfC1cIikgfSlcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtZXNzYWdlID0gZXJyLm1lc3NhZ2VcblxuICAgICAgICBlcnIubWVzc2FnZSA9IFwiXCJcbiAgICAgICAgcmV0dXJuIHByaW50TGluZXMoXywgUi5nZXRTdGFjayhlcnIpLCB0cnVlKVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IGVyci5tZXNzYWdlID0gbWVzc2FnZSB9KVxuICAgIH0pXG59XG5cbm1vZHVsZS5leHBvcnRzID0gUi5vbihcInRhcFwiLCB7XG4gICAgYWNjZXB0czogW1wid3JpdGVcIiwgXCJyZXNldFwiXSxcbiAgICBjcmVhdGU6IFIuY29uc29sZVJlcG9ydGVyLFxuICAgIGluaXQ6IGZ1bmN0aW9uIChzdGF0ZSkgeyBzdGF0ZS5jb3VudGVyID0gMCB9LFxuXG4gICAgcmVwb3J0OiBmdW5jdGlvbiAoXywgcmVwb3J0KSB7XG4gICAgICAgIGlmIChyZXBvcnQuaXNTdGFydCkge1xuICAgICAgICAgICAgcmV0dXJuIF8ucHJpbnQoXCJUQVAgdmVyc2lvbiAxM1wiKVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0VudGVyKSB7XG4gICAgICAgICAgICAvLyBQcmludCBhIGxlYWRpbmcgY29tbWVudCwgdG8gbWFrZSBzb21lIFRBUCBmb3JtYXR0ZXJzIHByZXR0aWVyLlxuICAgICAgICAgICAgcmV0dXJuIHRlbXBsYXRlKF8sIHJlcG9ydCwgXCIjICVwXCIsIHRydWUpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiB0ZW1wbGF0ZShfLCByZXBvcnQsIFwib2sgJWNcIikgfSlcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNQYXNzKSB7XG4gICAgICAgICAgICByZXR1cm4gdGVtcGxhdGUoXywgcmVwb3J0LCBcIm9rICVjICVwXCIpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzRmFpbCB8fCByZXBvcnQuaXNIb29rKSB7XG4gICAgICAgICAgICByZXR1cm4gdGVtcGxhdGUoXywgcmVwb3J0LCBcIm5vdCBvayAlYyAlcFwiKVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChcIiAgLS0tXCIpIH0pXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBwcmludEVycm9yKF8sIHJlcG9ydCkgfSlcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIF8ucHJpbnQoXCIgIC4uLlwiKSB9KVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc1NraXApIHtcbiAgICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZShfLCByZXBvcnQsIFwib2sgJWMgIyBza2lwICVwXCIpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzRW5kKSB7XG4gICAgICAgICAgICB2YXIgcCA9IF8ucHJpbnQoXCIxLi5cIiArIF8uc3RhdGUuY291bnRlcilcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIF8ucHJpbnQoXCIjIHRlc3RzIFwiICsgXy50ZXN0cykgfSlcblxuICAgICAgICAgICAgaWYgKF8ucGFzcykgcCA9IHByaW50TGluZShwLCBfLCBcIiMgcGFzcyBcIiArIF8ucGFzcylcbiAgICAgICAgICAgIGlmIChfLmZhaWwpIHAgPSBwcmludExpbmUocCwgXywgXCIjIGZhaWwgXCIgKyBfLmZhaWwpXG4gICAgICAgICAgICBpZiAoXy5za2lwKSBwID0gcHJpbnRMaW5lKHAsIF8sIFwiIyBza2lwIFwiICsgXy5za2lwKVxuICAgICAgICAgICAgcmV0dXJuIHByaW50TGluZShwLCBfLCBcIiMgZHVyYXRpb24gXCIgKyBSLmZvcm1hdFRpbWUoXy5kdXJhdGlvbikpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzRXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBfLnByaW50KFwiQmFpbCBvdXQhXCIpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBfLnByaW50KFwiICAtLS1cIikgfSlcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHByaW50RXJyb3IoXywgcmVwb3J0KSB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChcIiAgLi4uXCIpIH0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIH1cbiAgICB9LFxufSlcbiIsIlwidXNlIHN0cmljdFwiXG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4uL2xpYi9icm93c2VyLWJ1bmRsZVwiKVxucmVxdWlyZShcIi4vaW5kZXhcIilcbm1vZHVsZS5leHBvcnRzLnN1cHBvcnQgPSByZXF1aXJlKFwiLi9zdXBwb3J0XCIpXG4iXX0= diff --git a/thallium.js b/thallium.js index 9a8f5ad..fb9e417 100644 --- a/thallium.js +++ b/thallium.js @@ -24,7 +24,7 @@ module.exports = new Thallium() var Thallium = require("./lib/api/thallium") var Reports = require("./lib/core/reports") -var Types = Reports.Types +var HookStage = Reports.HookStage exports.root = function () { return new Thallium() @@ -100,19 +100,19 @@ exports.reports = { */ exports.hookErrors = { beforeAll: function (func, value) { - return new Reports.HookError(Types.BeforeAll, func, value) + return new Reports.HookError(HookStage.BeforeAll, func, value) }, beforeEach: function (func, value) { - return new Reports.HookError(Types.BeforeEach, func, value) + return new Reports.HookError(HookStage.BeforeEach, func, value) }, afterEach: function (func, value) { - return new Reports.HookError(Types.AfterEach, func, value) + return new Reports.HookError(HookStage.AfterEach, func, value) }, afterAll: function (func, value) { - return new Reports.HookError(Types.AfterAll, func, value) + return new Reports.HookError(HookStage.AfterAll, func, value) }, } @@ -161,25 +161,6 @@ exports.hasHook = function (list, callback) { return list[0] === callback } -// TODO: cache and remove these traversals for 0.4. -// Note that a timeout of 0 means to inherit the parent. -exports.getTimeout = function (test) { - while (!test.timeout && test.parent != null) { - test = test.parent - } - - return test.timeout || 2000 // ms - default timeout -} - -// Note that a slowness threshold of 0 means to inherit the parent. -exports.getSlow = function (test) { - while (!test.slow && test.parent != null) { - test = test.parent - } - - return test.slow || 75 // ms - default slow threshold -} - },{}],6:[function(require,module,exports){ "use strict" @@ -196,11 +177,64 @@ function Reflect(test) { var reflect = test.reflect if (reflect != null) return reflect - if (test.root !== test) return test.reflect = new ReflectChild(test) - return test.reflect = new ReflectRoot(test) + test.reflect = this + this._ = test } methods(Reflect, { + /** + * Whether a reporter was registered. + */ + hasReporter: function (reporter) { + if (typeof reporter !== "function") { + throw new TypeError("Expected `reporter` to be a function") + } + + return this._.root.reporterIds.indexOf(reporter) >= 0 + }, + + /** + * Add a reporter. + */ + reporter: function (reporter, arg) { + if (typeof reporter !== "function") { + throw new TypeError("Expected `reporter` to be a function") + } + + var root = this._.root + + if (root.current !== root) { + throw new Error("Reporters may only be added to the root") + } + + if (root.reporterIds.indexOf(reporter) < 0) { + root.reporterIds.push(reporter) + root.reporters.push(reporter(arg)) + } + }, + + /** + * Remove a reporter. + */ + removeReporter: function (reporter) { + if (typeof reporter !== "function") { + throw new TypeError("Expected `reporter` to be a function") + } + + var root = this._.root + + if (root.current !== root) { + throw new Error("Reporters may only be added to the root") + } + + var index = root.reporterIds.indexOf(reporter) + + if (index >= 0) { + root.reporterIds.splice(index, 1) + root.reporters.splice(index, 1) + } + }, + /** * Get the currently executing test. */ @@ -227,10 +261,15 @@ methods(Reflect, { * intentionally a slice, so you can't mutate the real children. */ get children() { - if (this._.tests == null) return [] - return this._.tests.map(function (test) { - return new ReflectChild(test) - }) + var children = [] + + if (this._.tests != null) { + for (var i = 0; i < this._.tests.length; i++) { + children[i] = new Reflect(this._.tests[i]) + } + } + + return children }, /** @@ -247,28 +286,12 @@ methods(Reflect, { return !!this._.locked }, - /** - * Get the own, not necessarily active, timeout. 0 means inherit the - * parent's, and `Infinity` means it's disabled. - */ - get ownTimeout() { - return this._.timeout || 0 - }, - /** * Get the active timeout in milliseconds, not necessarily own, or the * framework default of 2000, if none was set. */ get timeout() { - return Common.getTimeout(this._) - }, - - /** - * Get the own, not necessarily active, slow threshold. 0 means inherit the - * parent's, and `Infinity` means it's disabled. - */ - get ownSlow() { - return this._.slow || 0 + return this._.timeout || Tests.defaultTimeout }, /** @@ -276,7 +299,7 @@ methods(Reflect, { * the framework default of 75, if none was set. */ get slow() { - return Common.getSlow(this._) + return this._.slow || Tests.defaultSlow }, /** @@ -295,6 +318,30 @@ methods(Reflect, { return this._.isFailable }, + /** + * Get the test name, or `undefined` if it's the root test. + */ + get name() { + if (this._.parent == null) return undefined + return this._.name + }, + + /** + * Get the test index, or `undefined` if it's the root test. + */ + get index() { + if (this._.parent == null) return undefined + return this._.index + }, + + /** + * Get the test's parent as a Reflect, or `undefined` if it's the root test. + */ + get parent() { + if (this._.parent == null) return undefined + return new Reflect(this._.parent) + }, + /** * Add a hook to be run before each subtest, including their subtests and so * on. @@ -460,92 +507,6 @@ methods(Reflect, { }, }) -function ReflectRoot(root) { - this._ = root -} - -methods(ReflectRoot, Reflect, { - /** - * Whether a reporter was registered. - */ - hasReporter: function (reporter) { - if (typeof reporter !== "function") { - throw new TypeError("Expected `reporter` to be a function") - } - - return this._.root.reporterIds.indexOf(reporter) >= 0 - }, - - /** - * Add a reporter. - */ - reporter: function (reporter, arg) { - if (typeof reporter !== "function") { - throw new TypeError("Expected `reporter` to be a function") - } - - var root = this._.root - - if (root.current !== root) { - throw new Error("Reporters may only be added to the root") - } - - if (root.reporterIds.indexOf(reporter) < 0) { - root.reporterIds.push(reporter) - root.reporters.push(reporter(arg)) - } - }, - - /** - * Remove a reporter. - */ - removeReporter: function (reporter) { - if (typeof reporter !== "function") { - throw new TypeError("Expected `reporter` to be a function") - } - - var root = this._.root - - if (root.current !== root) { - throw new Error("Reporters may only be added to the root") - } - - var index = root.reporterIds.indexOf(reporter) - - if (index >= 0) { - root.reporterIds.splice(index, 1) - root.reporters.splice(index, 1) - } - }, -}) - -function ReflectChild(root) { - this._ = root -} - -methods(ReflectChild, Reflect, { - /** - * Get the test name, or `undefined` if it's the root test. - */ - get name() { - return this._.name - }, - - /** - * Get the test index, or `-1` if it's the root test. - */ - get index() { - return this._.index - }, - - /** - * Get the parent test as a Reflect. - */ - get parent() { - return new Reflect(this._.parent) - }, -}) - },{"../core/tests":10,"../methods":17,"./common":5}],7:[function(require,module,exports){ "use strict" @@ -557,7 +518,7 @@ var Reflect = require("./reflect") module.exports = Thallium function Thallium() { - this._ = Tests.createRoot(this) + this._ = Tests.createRoot() } methods(Thallium, { @@ -619,7 +580,7 @@ methods(Thallium, { * means it's disabled. */ get timeout() { - return Common.getTimeout(this._.root.current) + return this._.root.current.timeout || Tests.defaultTimeout }, /** @@ -636,7 +597,7 @@ methods(Thallium, { * `Infinity` means it's disabled. */ get slow() { - return Common.getSlow(this._.root.current) + return this._.root.current.slow || Tests.defaultSlow }, /** @@ -918,13 +879,16 @@ var Types = exports.Types = Object.freeze({ End: 6, Error: 7, - // Note that `Hook` is denoted by the 4th bit set, to save some space (and - // to simplify the type representation). + // Note that `Hook` is actually a bit flag, to save some space (and to + // simplify the type representation). Hook: 8, - BeforeAll: 8 | 0, - BeforeEach: 8 | 1, - AfterEach: 8 | 2, - AfterAll: 8 | 3, +}) + +var HookStage = exports.HookStage = Object.freeze({ + BeforeAll: Types.Hook | 0, + BeforeEach: Types.Hook | 1, + AfterEach: Types.Hook | 2, + AfterAll: Types.Hook | 3, }) exports.Report = Report @@ -1137,18 +1101,18 @@ methods(ErrorReport, Report, { var HookMethods = { get stage() { switch (this._) { - case Types.BeforeAll: return "before all" - case Types.BeforeEach: return "before each" - case Types.AfterEach: return "after each" - case Types.AfterAll: return "after all" + case HookStage.BeforeAll: return "before all" + case HookStage.BeforeEach: return "before each" + case HookStage.AfterEach: return "after each" + case HookStage.AfterAll: return "after all" default: throw new Error("unreachable") } }, - get isBeforeAll() { return this._ === Types.BeforeAll }, - get isBeforeEach() { return this._ === Types.BeforeEach }, - get isAfterEach() { return this._ === Types.AfterEach }, - get isAfterAll() { return this._ === Types.AfterAll }, + get isBeforeAll() { return this._ === HookStage.BeforeAll }, + get isBeforeEach() { return this._ === HookStage.BeforeEach }, + get isAfterEach() { return this._ === HookStage.AfterEach }, + get isAfterAll() { return this._ === HookStage.AfterAll }, } exports.HookError = HookError @@ -1179,7 +1143,7 @@ var methods = require("../methods") var peach = require("../util").peach var Reports = require("./reports") var Filter = require("./filter") -var Types = Reports.Types +var HookStage = Reports.HookStage /** * The tests are laid out in a very data-driven design. With exception of the @@ -1217,7 +1181,6 @@ function Result(time, attempt) { /** * Overview of the test properties: * - * - `methods` - A deprecated reference to the API methods * - `root` - The root test * - `reporters` - The list of reporters * - `current` - A reference to the currently active test @@ -1234,12 +1197,7 @@ function Result(time, attempt) { * Many of these properties aren't present on initialization to save memory. */ -// TODO: remove `test.methods` in 0.4 function Normal(name, index, parent, callback) { - var child = Object.create(parent.methods) - - child._ = this - this.methods = child this.locked = true this.root = parent.root this.name = name @@ -1249,8 +1207,8 @@ function Normal(name, index, parent, callback) { this.isFailable = parent.isFailable this.attempts = parent.attempts - this.timeout = 0 - this.slow = 0 + this.timeout = parent.timeout + this.slow = parent.slow this.tests = undefined this.beforeAll = undefined this.beforeEach = undefined @@ -1274,10 +1232,8 @@ function Skipped(name, index, parent) { this.reflect = undefined } -// TODO: remove `test.methods` in 0.4 -function Root(methods) { +function Root() { this.locked = false - this.methods = methods this.reporterIds = [] this.reporters = [] this.current = this @@ -1354,24 +1310,8 @@ exports.clearTests = function (parent) { * Execute the tests */ -// TODO: cache and remove these traversals for 0.4. -// Note that a timeout of 0 means to inherit the parent. -function findTimeout(tests) { - for (var i = tests.length - 1; i >= 0; i--) { - if (tests[i].timeout) return tests[i].timeout - } - - return 2000 // ms - default timeout -} - -// Note that a slowness threshold of 0 means to inherit the parent. -function findSlow(tests) { - for (var i = tests.length - 1; i >= 0; i--) { - if (tests[i].slow) return tests[i].slow - } - - return 75 // ms - default slow threshold -} +exports.defaultTimeout = 2000 // ms +exports.defaultSlow = 75 // ms function makeSlice(tests, length) { var ret = new Array(length) @@ -1383,70 +1323,95 @@ function makeSlice(tests, length) { return ret } -function report(context, type, arg1, arg2) { - function invokeReporter(reporter) { - switch (type) { - case Types.Start: - return reporter(new Reports.Start()) - - case Types.Enter: - return reporter( - new Reports.Enter( - makeSlice(context.tests, context.tests.length), arg1, - findSlow(context.tests))) - - case Types.Leave: - return reporter(new Reports.Leave( - makeSlice(context.tests, context.tests.length))) - - case Types.Pass: - return reporter( - new Reports.Pass( - makeSlice(context.tests, context.tests.length), arg1, - findSlow(context.tests))) - - case Types.Fail: - return reporter( - new Reports.Fail( - makeSlice(context.tests, context.tests.length), arg1, arg2, - findSlow(context.tests), - !!context.root.current.isFailable)) - - case Types.Skip: - return reporter(new Reports.Skip( - makeSlice(context.tests, context.tests.length))) - - case Types.End: - return reporter(new Reports.End()) - - case Types.Error: - return reporter(new Reports.Error(arg1)) - - case Types.Hook: - // Include the last test. This also implicitly sets the end to 0 for - // root tests. - return reporter(new Reports.Hook( - makeSlice(context.tests, context.tests.length), - makeSlice(context.tests, context.tests.indexOf(arg1) + 1), - arg2)) - - default: - throw new TypeError("unreachable") - } - } - +function reportWith(context, func) { return Promise.resolve() .then(function () { if (context.root.reporter == null) return undefined - return invokeReporter(context.root.reporter) + return func(context.root.reporter) }) .then(function () { var reporters = context.root.reporters // Two easy cases. if (reporters.length === 0) return undefined - if (reporters.length === 1) return invokeReporter(reporters[0]) - return Promise.all(reporters.map(invokeReporter)) + if (reporters.length === 1) return func(reporters[0]) + return Promise.all(reporters.map(func)) + }) +} + +function reportStart(context) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Start()) + }) +} + +function reportEnter(context, duration) { + var test = context.root.current + var slow = test.slow || exports.defaultSlow + + return reportWith(context, function (reporter) { + var path = makeSlice(context.tests, context.tests.length) + + return reporter(new Reports.Enter(path, duration, slow)) + }) +} + +function reportLeave(context) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Leave( + makeSlice(context.tests, context.tests.length))) + }) +} + +function reportPass(context, duration) { + var test = context.root.current + var slow = test.slow || exports.defaultSlow + + return reportWith(context, function (reporter) { + var path = makeSlice(context.tests, context.tests.length) + + return reporter(new Reports.Pass(path, duration, slow)) + }) +} + +function reportFail(context, error, duration) { + var test = context.root.current + var slow = test.slow || exports.defaultSlow + var isFailable = test.isFailable + + return reportWith(context, function (reporter) { + var path = makeSlice(context.tests, context.tests.length) + + return reporter(new Reports.Fail( + path, error, duration, slow, isFailable)) + }) +} + +function reportSkip(context) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Skip( + makeSlice(context.tests, context.tests.length))) + }) +} + +function reportEnd(context) { + return reportWith(context, function (reporter) { + return reporter(new Reports.End()) + }) +} + +function reportError(context, error) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Error(error)) + }) +} + +function reportHook(context, test, error) { + return reportWith(context, function (reporter) { + return reporter(new Reports.Hook( + makeSlice(context.tests, context.tests.length), + makeSlice(context.tests, context.tests.indexOf(test) + 1), + error)) }) } @@ -1508,7 +1473,7 @@ function asyncFinish(state, attempt) { function invokeInit(context, count) { var test = context.root.current var start = now() - var tryBody = try1(test.callback, test.methods, test.methods) + var tryBody = try0(test.callback) var syncEnd = now() // Note: synchronous failures are test failures, not fatal errors. @@ -1551,7 +1516,7 @@ function invokeInit(context, count) { // Set the timeout *after* initialization. The timeout will likely be // specified during initialization. - var maxTimeout = findTimeout(context.tests) + var maxTimeout = test.timeout || exports.defaultTimeout // Setting a timeout is pointless if it's infinite. if (maxTimeout !== Infinity) { @@ -1584,19 +1549,19 @@ function invokeHook(test, list, stage) { function invokeBeforeEach(test) { if (test.root === test) { - return invokeHook(test, test.beforeEach, Types.BeforeEach) + return invokeHook(test, test.beforeEach, HookStage.BeforeEach) } else { return invokeBeforeEach(test.parent).then(function () { - return invokeHook(test, test.beforeEach, Types.BeforeEach) + return invokeHook(test, test.beforeEach, HookStage.BeforeEach) }) } } function invokeAfterEach(test) { if (test.root === test) { - return invokeHook(test, test.afterEach, Types.AfterEach) + return invokeHook(test, test.afterEach, HookStage.AfterEach) } else { - return invokeHook(test, test.afterEach, Types.AfterEach) + return invokeHook(test, test.afterEach, HookStage.AfterEach) .then(function () { return invokeAfterEach(test.parent) }) } } @@ -1636,7 +1601,7 @@ function runChildTests(test, context) { .then(function () { return invokeAfterEach(test) }) .catch(function (e) { if (!(e instanceof ErrorWrap)) throw e - return report(context, Types.Hook, e.test, e.error) + return reportHook(context, e.test, e.error) }) .then(leave, function (e) { leave(); throw e }) } @@ -1649,7 +1614,7 @@ function runChildTests(test, context) { test.root.current = child context.tests.push(child) - return report(context, Types.Skip) + return reportSkip(context) .then(leave, function (e) { leave(); throw e }) } else if (!isOnly(child)) { return Promise.resolve() @@ -1657,12 +1622,13 @@ function runChildTests(test, context) { return runChild(child) } else { ran = true - return invokeHook(test, test.beforeAll, Types.BeforeAll) + return invokeHook(test, test.beforeAll, HookStage.BeforeAll) .then(function () { return runChild(child) }) } }) .then(function () { - return ran ? invokeHook(test, test.afterAll, Types.AfterAll) : undefined + if (!ran) return undefined + return invokeHook(test, test.afterAll, HookStage.AfterAll) }) } @@ -1683,21 +1649,21 @@ function runNormalChild(test, context) { .then(function (result) { if (result.caught) { if (!test.isFailable) context.isSuccess = false - return report(context, Types.Fail, result.value, result.time) + return reportFail(context, result.value, result.time) } else if (test.tests != null) { // Report this as if it was a parent test if it's passing and has // children. - return report(context, Types.Enter, result.time) + return reportEnter(context, result.time) .then(function () { return runChildTests(test, context) }) - .then(function () { return report(context, Types.Leave) }) + .then(function () { return reportLeave(context) }) .catch(function (e) { if (!(e instanceof ErrorWrap)) throw e - return report(context, Types.Leave).then(function () { - return report(context, Types.Hook, e.test, e.error) + return reportLeave(context).then(function () { + return reportHook(context, e.test, e.error) }) }) } else { - return report(context, Types.Pass, result.time) + return reportPass(context, result.time) } }) .then( @@ -1712,17 +1678,17 @@ exports.runTest = function (root, opts) { var context = new Context(root, opts) root.locked = true - return report(context, Types.Start) + return reportStart(context) .then(function () { return runChildTests(root, context) }) .catch(function (e) { if (!(e instanceof ErrorWrap)) throw e - return report(context, Types.Hook, e.test, e.error) + return reportHook(context, e.test, e.error) }) - .then(function () { return report(context, Types.End) }) + .then(function () { return reportEnd(context) }) // Tell the reporter something happened. Otherwise, it'll have to wrap this // method in a plugin, which shouldn't be necessary. .catch(function (e) { - return report(context, Types.Error, e).then(function () { throw e }) + return reportError(context, e).then(function () { throw e }) }) .then( function () { @@ -1749,6 +1715,14 @@ function tryFail(e) { return {caught: true, value: e} } +function try0(f) { + try { + return tryPass(f()) + } catch (e) { + return tryFail(e) + } +} + function try1(f, inst, arg0) { try { return tryPass(f.call(inst, arg0)) @@ -3667,7 +3641,7 @@ module.exports = function (xs, f, acc) { module.exports = require("util-inspect") -},{"util-inspect":61}],29:[function(require,module,exports){ +},{"util-inspect":60}],29:[function(require,module,exports){ "use strict" var inspect = exports.inspect = require("./inspect") @@ -6559,1136 +6533,234 @@ module.exports = Array.isArray || function (arr) { }; },{}],57:[function(require,module,exports){ -(function (global){ -/*! JSON v3.3.0 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */ -;(function (root) { - // Detect the `define` function exposed by asynchronous module loaders. The - // strict `define` check is necessary for compatibility with `r.js`. - var isLoader = typeof define === "function" && define.amd; - - // Use the `global` object exposed by Node (including Browserify via - // `insert-module-globals`), Narwhal, and Ringo as the default context. - // Rhino exports a `global` function instead. - var freeGlobal = typeof global == "object" && global; - if (freeGlobal && (freeGlobal["global"] === freeGlobal || freeGlobal["window"] === freeGlobal)) { - root = freeGlobal; - } +"use strict"; - // Public: Initializes JSON 3 using the given `context` object, attaching the - // `stringify` and `parse` functions to the specified `exports` object. - function runInContext(context, exports) { - context || (context = root["Object"]()); - exports || (exports = root["Object"]()); +var hasOwn = Object.prototype.hasOwnProperty; +var toString = Object.prototype.toString; - // Native constructor aliases. - var Number = context["Number"] || root["Number"], - String = context["String"] || root["String"], - Object = context["Object"] || root["Object"], - Date = context["Date"] || root["Date"], - SyntaxError = context["SyntaxError"] || root["SyntaxError"], - TypeError = context["TypeError"] || root["TypeError"], - Math = context["Math"] || root["Math"], - nativeJSON = context["JSON"] || root["JSON"]; +var isFunction = function (fn) { + return (typeof fn === 'function' && !(fn instanceof RegExp)) || toString.call(fn) === '[object Function]'; +}; - // Delegate to the native `stringify` and `parse` implementations. - if (typeof nativeJSON == "object" && nativeJSON) { - exports.stringify = nativeJSON.stringify; - exports.parse = nativeJSON.parse; - } +module.exports = function forEach(obj, fn) { + if (!isFunction(fn)) { + throw new TypeError('iterator must be a function'); + } + var i, k, + isString = typeof obj === 'string', + l = obj.length, + context = arguments.length > 2 ? arguments[2] : null; + if (l === +l) { + for (i = 0; i < l; i++) { + if (context === null) { + fn(isString ? obj.charAt(i) : obj[i], i, obj); + } else { + fn.call(context, isString ? obj.charAt(i) : obj[i], i, obj); + } + } + } else { + for (k in obj) { + if (hasOwn.call(obj, k)) { + if (context === null) { + fn(obj[k], k, obj); + } else { + fn.call(context, obj[k], k, obj); + } + } + } + } +}; - // Convenience aliases. - var objectProto = Object.prototype, - getClass = objectProto.toString, - isProperty, forEach, undef; - // Test the `Date#getUTC*` methods. Based on work by @Yaffle. - var isExtended = new Date(-3509827334573292); - try { - // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical - // results for certain dates in Opera >= 10.53. - isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 && - // Safari < 2.0.2 stores the internal millisecond time value correctly, - // but clips the values returned by the date methods to the range of - // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]). - isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708; - } catch (exception) {} +},{}],58:[function(require,module,exports){ +"use strict"; - // Internal: Determines whether the native `JSON.stringify` and `parse` - // implementations are spec-compliant. Based on work by Ken Snyder. - function has(name) { - if (has[name] !== undef) { - // Return cached feature test result. - return has[name]; - } - var isSupported; - if (name == "bug-string-char-index") { - // IE <= 7 doesn't support accessing string characters using square - // bracket notation. IE 8 only supports this for primitives. - isSupported = "a"[0] != "a"; - } else if (name == "json") { - // Indicates whether both `JSON.stringify` and `JSON.parse` are - // supported. - isSupported = has("json-stringify") && has("json-parse"); - } else { - var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}'; - // Test `JSON.stringify`. - if (name == "json-stringify") { - var stringify = exports.stringify, stringifySupported = typeof stringify == "function" && isExtended; - if (stringifySupported) { - // A test function object with a custom `toJSON` method. - (value = function () { - return 1; - }).toJSON = value; - try { - stringifySupported = - // Firefox 3.1b1 and b2 serialize string, number, and boolean - // primitives as object literals. - stringify(0) === "0" && - // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object - // literals. - stringify(new Number()) === "0" && - stringify(new String()) == '""' && - // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or - // does not define a canonical JSON representation (this applies to - // objects with `toJSON` properties as well, *unless* they are nested - // within an object or array). - stringify(getClass) === undef && - // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and - // FF 3.1b3 pass this test. - stringify(undef) === undef && - // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s, - // respectively, if the value is omitted entirely. - stringify() === undef && - // FF 3.1b1, 2 throw an error if the given value is not a number, - // string, array, object, Boolean, or `null` literal. This applies to - // objects with custom `toJSON` methods as well, unless they are nested - // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON` - // methods entirely. - stringify(value) === "1" && - stringify([value]) == "[1]" && - // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of - // `"[null]"`. - stringify([undef]) == "[null]" && - // YUI 3.0.0b1 fails to serialize `null` literals. - stringify(null) == "null" && - // FF 3.1b1, 2 halts serialization if an array contains a function: - // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3 - // elides non-JSON values from objects and arrays, unless they - // define custom `toJSON` methods. - stringify([undef, getClass, null]) == "[null,null,null]" && - // Simple serialization test. FF 3.1b1 uses Unicode escape sequences - // where character escape codes are expected (e.g., `\b` => `\u0008`). - stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized && - // FF 3.1b1 and b2 ignore the `filter` and `width` arguments. - stringify(null, value) === "1" && - stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" && - // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly - // serialize extended years. - stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' && - // The milliseconds are optional in ES 5, but required in 5.1. - stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' && - // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative - // four-digit years instead of six-digit years. Credits: @Yaffle. - stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' && - // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond - // values less than 1000. Credits: @Yaffle. - stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"'; - } catch (exception) { - stringifySupported = false; - } - } - isSupported = stringifySupported; - } - // Test `JSON.parse`. - if (name == "json-parse") { - var parse = exports.parse; - if (typeof parse == "function") { - try { - // FF 3.1b1, b2 will throw an exception if a bare literal is provided. - // Conforming implementations should also coerce the initial argument to - // a string prior to parsing. - if (parse("0") === 0 && !parse(false)) { - // Simple parsing test. - value = parse(serialized); - var parseSupported = value["a"].length == 5 && value["a"][0] === 1; - if (parseSupported) { - try { - // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings. - parseSupported = !parse('"\t"'); - } catch (exception) {} - if (parseSupported) { - try { - // FF 4.0 and 4.0.1 allow leading `+` signs and leading - // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow - // certain octal literals. - parseSupported = parse("01") !== 1; - } catch (exception) {} - } - if (parseSupported) { - try { - // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal - // points. These environments, along with FF 3.1b1 and 2, - // also allow trailing commas in JSON objects and arrays. - parseSupported = parse("1.") !== 1; - } catch (exception) {} - } - } - } - } catch (exception) { - parseSupported = false; - } - } - isSupported = parseSupported; - } - } - return has[name] = !!isSupported; - } +// modified from https://github.com/es-shims/es5-shim +var has = Object.prototype.hasOwnProperty, + toString = Object.prototype.toString, + forEach = require('./foreach'), + isArgs = require('./isArguments'), + hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'), + hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), + dontEnums = [ + "toString", + "toLocaleString", + "valueOf", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "constructor" + ]; - if (!has("json")) { - // Common `[[Class]]` name aliases. - var functionClass = "[object Function]", - dateClass = "[object Date]", - numberClass = "[object Number]", - stringClass = "[object String]", - arrayClass = "[object Array]", - booleanClass = "[object Boolean]"; +var keysShim = function keys(object) { + var isObject = object !== null && typeof object === 'object', + isFunction = toString.call(object) === '[object Function]', + isArguments = isArgs(object), + theKeys = []; - // Detect incomplete support for accessing string characters by index. - var charIndexBuggy = has("bug-string-char-index"); + if (!isObject && !isFunction && !isArguments) { + throw new TypeError("Object.keys called on a non-object"); + } - // Define additional utility methods if the `Date` methods are buggy. - if (!isExtended) { - var floor = Math.floor; - // A mapping between the months of the year and the number of days between - // January 1st and the first of the respective month. - var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; - // Internal: Calculates the number of days between the Unix epoch and the - // first day of the given month. - var getDay = function (year, month) { - return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400); - }; - } + if (isArguments) { + forEach(object, function (value, index) { + theKeys.push(index); + }); + } else { + var name, + skipProto = hasProtoEnumBug && isFunction; - // Internal: Determines if a property is a direct property of the given - // object. Delegates to the native `Object#hasOwnProperty` method. - if (!(isProperty = objectProto.hasOwnProperty)) { - isProperty = function (property) { - var members = {}, constructor; - if ((members.__proto__ = null, members.__proto__ = { - // The *proto* property cannot be set multiple times in recent - // versions of Firefox and SeaMonkey. - "toString": 1 - }, members).toString != getClass) { - // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but - // supports the mutable *proto* property. - isProperty = function (property) { - // Capture and break the objectgs prototype chain (see section 8.6.2 - // of the ES 5.1 spec). The parenthesized expression prevents an - // unsafe transformation by the Closure Compiler. - var original = this.__proto__, result = property in (this.__proto__ = null, this); - // Restore the original prototype chain. - this.__proto__ = original; - return result; - }; - } else { - // Capture a reference to the top-level `Object` constructor. - constructor = members.constructor; - // Use the `constructor` property to simulate `Object#hasOwnProperty` in - // other environments. - isProperty = function (property) { - var parent = (this.constructor || constructor).prototype; - return property in this && !(property in parent && this[property] === parent[property]); - }; - } - members = null; - return isProperty.call(this, property); - }; - } + for (name in object) { + if (!(skipProto && name === 'prototype') && has.call(object, name)) { + theKeys.push(name); + } + } + } - // Internal: A set of primitive types used by `isHostType`. - var PrimitiveTypes = { - "boolean": 1, - "number": 1, - "string": 1, - "undefined": 1 - }; + if (hasDontEnumBug) { + var ctor = object.constructor, + skipConstructor = ctor && ctor.prototype === object; - // Internal: Determines if the given object `property` value is a - // non-primitive. - var isHostType = function (object, property) { - var type = typeof object[property]; - return type == "object" ? !!object[property] : !PrimitiveTypes[type]; - }; + forEach(dontEnums, function (dontEnum) { + if (!(skipConstructor && dontEnum === 'constructor') && has.call(object, dontEnum)) { + theKeys.push(dontEnum); + } + }); + } + return theKeys; +}; - // Internal: Normalizes the `for...in` iteration algorithm across - // environments. Each enumerated key is yielded to a `callback` function. - forEach = function (object, callback) { - var size = 0, Properties, members, property; +keysShim.shim = function shimObjectKeys() { + if (!Object.keys) { + Object.keys = keysShim; + } + return Object.keys || keysShim; +}; - // Tests for bugs in the current environment's `for...in` algorithm. The - // `valueOf` property inherits the non-enumerable flag from - // `Object.prototype` in older versions of IE, Netscape, and Mozilla. - (Properties = function () { - this.valueOf = 0; - }).prototype.valueOf = 0; +module.exports = keysShim; - // Iterate over a new instance of the `Properties` class. - members = new Properties(); - for (property in members) { - // Ignore all properties inherited from `Object.prototype`. - if (isProperty.call(members, property)) { - size++; - } - } - Properties = members = null; - // Normalize the iteration algorithm. - if (!size) { - // A list of non-enumerable properties inherited from `Object.prototype`. - members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"]; - // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable - // properties. - forEach = function (object, callback) { - var isFunction = getClass.call(object) == functionClass, property, length; - var hasProperty = !isFunction && typeof object.constructor != "function" && isHostType(object, "hasOwnProperty") ? object.hasOwnProperty : isProperty; - for (property in object) { - // Gecko <= 1.0 enumerates the `prototype` property of functions under - // certain conditions; IE does not. - if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) { - callback(property); - } - } - // Manually invoke the callback for each non-enumerable property. - for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property)); - }; - } else if (size == 2) { - // Safari <= 2.0.4 enumerates shadowed properties twice. - forEach = function (object, callback) { - // Create a set of iterated properties. - var members = {}, isFunction = getClass.call(object) == functionClass, property; - for (property in object) { - // Store each property name to prevent double enumeration. The - // `prototype` property of functions is not enumerated due to cross- - // environment inconsistencies. - if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) { - callback(property); - } - } - }; - } else { - // No bugs detected; use the standard `for...in` algorithm. - forEach = function (object, callback) { - var isFunction = getClass.call(object) == functionClass, property, isConstructor; - for (property in object) { - if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) { - callback(property); - } - } - // Manually invoke the callback for the `constructor` property due to - // cross-environment inconsistencies. - if (isConstructor || isProperty.call(object, (property = "constructor"))) { - callback(property); - } - }; - } - return forEach(object, callback); - }; +},{"./foreach":57,"./isArguments":59}],59:[function(require,module,exports){ +"use strict"; - // Public: Serializes a JavaScript `value` as a JSON string. The optional - // `filter` argument may specify either a function that alters how object and - // array members are serialized, or an array of strings and numbers that - // indicates which properties should be serialized. The optional `width` - // argument may be either a string or number that specifies the indentation - // level of the output. - if (!has("json-stringify")) { - // Internal: A map of control characters and their escaped equivalents. - var Escapes = { - 92: "\\\\", - 34: '\\"', - 8: "\\b", - 12: "\\f", - 10: "\\n", - 13: "\\r", - 9: "\\t" - }; +var toString = Object.prototype.toString; - // Internal: Converts `value` into a zero-padded string such that its - // length is at least equal to `width`. The `width` must be <= 6. - var leadingZeroes = "000000"; - var toPaddedString = function (width, value) { - // The `|| 0` expression is necessary to work around a bug in - // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`. - return (leadingZeroes + (value || 0)).slice(-width); - }; +module.exports = function isArguments(value) { + var str = toString.call(value); + var isArguments = str === '[object Arguments]'; + if (!isArguments) { + isArguments = str !== '[object Array]' + && value !== null + && typeof value === 'object' + && typeof value.length === 'number' + && value.length >= 0 + && toString.call(value.callee) === '[object Function]'; + } + return isArguments; +}; - // Internal: Double-quotes a string `value`, replacing all ASCII control - // characters (characters with code unit values between 0 and 31) with - // their escaped equivalents. This is an implementation of the - // `Quote(value)` operation defined in ES 5.1 section 15.12.3. - var unicodePrefix = "\\u00"; - var quote = function (value) { - var result = '"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10; - var symbols = useCharIndex && (charIndexBuggy ? value.split("") : value); - for (; index < length; index++) { - var charCode = value.charCodeAt(index); - // If the character is a control character, append its Unicode or - // shorthand escape sequence; otherwise, append the character as-is. - switch (charCode) { - case 8: case 9: case 10: case 12: case 13: case 34: case 92: - result += Escapes[charCode]; - break; - default: - if (charCode < 32) { - result += unicodePrefix + toPaddedString(2, charCode.toString(16)); - break; - } - result += useCharIndex ? symbols[index] : value.charAt(index); - } - } - return result + '"'; - }; - // Internal: Recursively serializes an object. Implements the - // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations. - var serialize = function (property, object, callback, properties, whitespace, indentation, stack) { - var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result; - try { - // Necessary for host object support. - value = object[property]; - } catch (exception) {} - if (typeof value == "object" && value) { - className = getClass.call(value); - if (className == dateClass && !isProperty.call(value, "toJSON")) { - if (value > -1 / 0 && value < 1 / 0) { - // Dates are serialized according to the `Date#toJSON` method - // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15 - // for the ISO 8601 date time string format. - if (getDay) { - // Manually compute the year, month, date, hours, minutes, - // seconds, and milliseconds if the `getUTC*` methods are - // buggy. Adapted from @Yaffle's `date-shim` project. - date = floor(value / 864e5); - for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++); - for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++); - date = 1 + date - getDay(year, month); - // The `time` value specifies the time within the day (see ES - // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used - // to compute `A modulo B`, as the `%` operator does not - // correspond to the `modulo` operation for negative numbers. - time = (value % 864e5 + 864e5) % 864e5; - // The hours, minutes, seconds, and milliseconds are obtained by - // decomposing the time within the day. See section 15.9.1.10. - hours = floor(time / 36e5) % 24; - minutes = floor(time / 6e4) % 60; - seconds = floor(time / 1e3) % 60; - milliseconds = time % 1e3; - } else { - year = value.getUTCFullYear(); - month = value.getUTCMonth(); - date = value.getUTCDate(); - hours = value.getUTCHours(); - minutes = value.getUTCMinutes(); - seconds = value.getUTCSeconds(); - milliseconds = value.getUTCMilliseconds(); - } - // Serialize extended years correctly. - value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) + - "-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) + - // Months, dates, hours, minutes, and seconds should have two - // digits; milliseconds should have three. - "T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) + - // Milliseconds are optional in ES 5.0, but required in 5.1. - "." + toPaddedString(3, milliseconds) + "Z"; - } else { - value = null; - } - } else if (typeof value.toJSON == "function" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, "toJSON"))) { - // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the - // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3 - // ignores all `toJSON` methods on these objects unless they are - // defined directly on an instance. - value = value.toJSON(property); - } - } - if (callback) { - // If a replacement function was provided, call it to obtain the value - // for serialization. - value = callback.call(object, property, value); - } - if (value === null) { - return "null"; - } - className = getClass.call(value); - if (className == booleanClass) { - // Booleans are represented literally. - return "" + value; - } else if (className == numberClass) { - // JSON numbers must be finite. `Infinity` and `NaN` are serialized as - // `"null"`. - return value > -1 / 0 && value < 1 / 0 ? "" + value : "null"; - } else if (className == stringClass) { - // Strings are double-quoted and escaped. - return quote("" + value); - } - // Recursively serialize objects and arrays. - if (typeof value == "object") { - // Check for cyclic structures. This is a linear search; performance - // is inversely proportional to the number of unique nested objects. - for (length = stack.length; length--;) { - if (stack[length] === value) { - // Cyclic structures cannot be serialized by `JSON.stringify`. - throw TypeError(); - } - } - // Add the object to the stack of traversed objects. - stack.push(value); - results = []; - // Save the current indentation level and indent one additional level. - prefix = indentation; - indentation += whitespace; - if (className == arrayClass) { - // Recursively serialize array elements. - for (index = 0, length = value.length; index < length; index++) { - element = serialize(index, value, callback, properties, whitespace, indentation, stack); - results.push(element === undef ? "null" : element); - } - result = results.length ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]"; - } else { - // Recursively serialize object members. Members are selected from - // either a user-specified list of property names, or the object - // itself. - forEach(properties || value, function (property) { - var element = serialize(property, value, callback, properties, whitespace, indentation, stack); - if (element !== undef) { - // According to ES 5.1 section 15.12.3: "If `gap` {whitespace} - // is not the empty string, let `member` {quote(property) + ":"} - // be the concatenation of `member` and the `space` character." - // The "`space` character" refers to the literal space - // character, not the `space` {width} argument provided to - // `JSON.stringify`. - results.push(quote(property) + ":" + (whitespace ? " " : "") + element); - } - }); - result = results.length ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}"; - } - // Remove the object from the traversed object stack. - stack.pop(); - return result; - } - }; +},{}],60:[function(require,module,exports){ - // Public: `JSON.stringify`. See ES 5.1 section 15.12.3. - exports.stringify = function (source, filter, width) { - var whitespace, callback, properties, className; - if (typeof filter == "function" || typeof filter == "object" && filter) { - if ((className = getClass.call(filter)) == functionClass) { - callback = filter; - } else if (className == arrayClass) { - // Convert the property names array into a makeshift set. - properties = {}; - for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1)); - } - } - if (width) { - if ((className = getClass.call(width)) == numberClass) { - // Convert the `width` to an integer and create a string containing - // `width` number of space characters. - if ((width -= width % 1) > 0) { - for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " "); - } - } else if (className == stringClass) { - whitespace = width.length <= 10 ? width : width.slice(0, 10); - } - } - // Opera <= 7.54u2 discards the values associated with empty string keys - // (`""`) only if they are used directly within an object member list - // (e.g., `!("" in { "": 1})`). - return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []); - }; - } +/** + * Module dependencies. + */ - // Public: Parses a JSON source string. - if (!has("json-parse")) { - var fromCharCode = String.fromCharCode; +var map = require('array-map'); +var indexOf = require('indexof'); +var isArray = require('isarray'); +var forEach = require('foreach'); +var reduce = require('array-reduce'); +var getObjectKeys = require('object-keys'); +var JSON = require('json3'); - // Internal: A map of escaped control characters and their unescaped - // equivalents. - var Unescapes = { - 92: "\\", - 34: '"', - 47: "/", - 98: "\b", - 116: "\t", - 110: "\n", - 102: "\f", - 114: "\r" - }; +/** + * Make sure `Object.keys` work for `undefined` + * values that are still there, like `document.all`. + * http://lists.w3.org/Archives/Public/public-html/2009Jun/0546.html + * + * @api private + */ - // Internal: Stores the parser state. - var Index, Source; +function objectKeys(val){ + if (Object.keys) return Object.keys(val); + return getObjectKeys(val); +} - // Internal: Resets the parser state and throws a `SyntaxError`. - var abort = function () { - Index = Source = null; - throw SyntaxError(); - }; +/** + * Module exports. + */ - // Internal: Returns the next token, or `"$"` if the parser has reached - // the end of the source string. A token may be a string, number, `null` - // literal, or Boolean literal. - var lex = function () { - var source = Source, length = source.length, value, begin, position, isSigned, charCode; - while (Index < length) { - charCode = source.charCodeAt(Index); - switch (charCode) { - case 9: case 10: case 13: case 32: - // Skip whitespace tokens, including tabs, carriage returns, line - // feeds, and space characters. - Index++; - break; - case 123: case 125: case 91: case 93: case 58: case 44: - // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at - // the current position. - value = charIndexBuggy ? source.charAt(Index) : source[Index]; - Index++; - return value; - case 34: - // `"` delimits a JSON string; advance to the next character and - // begin parsing the string. String tokens are prefixed with the - // sentinel `@` character to distinguish them from punctuators and - // end-of-string tokens. - for (value = "@", Index++; Index < length;) { - charCode = source.charCodeAt(Index); - if (charCode < 32) { - // Unescaped ASCII control characters (those with a code unit - // less than the space character) are not permitted. - abort(); - } else if (charCode == 92) { - // A reverse solidus (`\`) marks the beginning of an escaped - // control character (including `"`, `\`, and `/`) or Unicode - // escape sequence. - charCode = source.charCodeAt(++Index); - switch (charCode) { - case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114: - // Revive escaped control characters. - value += Unescapes[charCode]; - Index++; - break; - case 117: - // `\u` marks the beginning of a Unicode escape sequence. - // Advance to the first character and validate the - // four-digit code point. - begin = ++Index; - for (position = Index + 4; Index < position; Index++) { - charCode = source.charCodeAt(Index); - // A valid sequence comprises four hexdigits (case- - // insensitive) that form a single hexadecimal value. - if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) { - // Invalid Unicode escape sequence. - abort(); - } - } - // Revive the escaped character. - value += fromCharCode("0x" + source.slice(begin, Index)); - break; - default: - // Invalid escape sequence. - abort(); - } - } else { - if (charCode == 34) { - // An unescaped double-quote character marks the end of the - // string. - break; - } - charCode = source.charCodeAt(Index); - begin = Index; - // Optimize for the common case where a string is valid. - while (charCode >= 32 && charCode != 92 && charCode != 34) { - charCode = source.charCodeAt(++Index); - } - // Append the string as-is. - value += source.slice(begin, Index); - } - } - if (source.charCodeAt(Index) == 34) { - // Advance to the next character and return the revived string. - Index++; - return value; - } - // Unterminated string. - abort(); - default: - // Parse numbers and literals. - begin = Index; - // Advance past the negative sign, if one is specified. - if (charCode == 45) { - isSigned = true; - charCode = source.charCodeAt(++Index); - } - // Parse an integer or floating-point value. - if (charCode >= 48 && charCode <= 57) { - // Leading zeroes are interpreted as octal literals. - if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) { - // Illegal octal literal. - abort(); - } - isSigned = false; - // Parse the integer component. - for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++); - // Floats cannot contain a leading decimal point; however, this - // case is already accounted for by the parser. - if (source.charCodeAt(Index) == 46) { - position = ++Index; - // Parse the decimal component. - for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++); - if (position == Index) { - // Illegal trailing decimal. - abort(); - } - Index = position; - } - // Parse exponents. The `e` denoting the exponent is - // case-insensitive. - charCode = source.charCodeAt(Index); - if (charCode == 101 || charCode == 69) { - charCode = source.charCodeAt(++Index); - // Skip past the sign following the exponent, if one is - // specified. - if (charCode == 43 || charCode == 45) { - Index++; - } - // Parse the exponential component. - for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++); - if (position == Index) { - // Illegal empty exponent. - abort(); - } - Index = position; - } - // Coerce the parsed value to a JavaScript number. - return +source.slice(begin, Index); - } - // A negative sign may only precede numbers. - if (isSigned) { - abort(); - } - // `true`, `false`, and `null` literals. - if (source.slice(Index, Index + 4) == "true") { - Index += 4; - return true; - } else if (source.slice(Index, Index + 5) == "false") { - Index += 5; - return false; - } else if (source.slice(Index, Index + 4) == "null") { - Index += 4; - return null; - } - // Unrecognized token. - abort(); - } - } - // Return the sentinel `$` character if the parser has reached the end - // of the source string. - return "$"; - }; +module.exports = inspect; - // Internal: Parses a JSON `value` token. - var get = function (value) { - var results, hasMembers; - if (value == "$") { - // Unexpected end of input. - abort(); - } - if (typeof value == "string") { - if ((charIndexBuggy ? value.charAt(0) : value[0]) == "@") { - // Remove the sentinel `@` character. - return value.slice(1); - } - // Parse object and array literals. - if (value == "[") { - // Parses a JSON array, returning a new JavaScript array. - results = []; - for (;; hasMembers || (hasMembers = true)) { - value = lex(); - // A closing square bracket marks the end of the array literal. - if (value == "]") { - break; - } - // If the array literal contains elements, the current token - // should be a comma separating the previous element from the - // next. - if (hasMembers) { - if (value == ",") { - value = lex(); - if (value == "]") { - // Unexpected trailing `,` in array literal. - abort(); - } - } else { - // A `,` must separate each array element. - abort(); - } - } - // Elisions and leading commas are not permitted. - if (value == ",") { - abort(); - } - results.push(get(value)); - } - return results; - } else if (value == "{") { - // Parses a JSON object, returning a new JavaScript object. - results = {}; - for (;; hasMembers || (hasMembers = true)) { - value = lex(); - // A closing curly brace marks the end of the object literal. - if (value == "}") { - break; - } - // If the object literal contains members, the current token - // should be a comma separator. - if (hasMembers) { - if (value == ",") { - value = lex(); - if (value == "}") { - // Unexpected trailing `,` in object literal. - abort(); - } - } else { - // A `,` must separate each object member. - abort(); - } - } - // Leading commas are not permitted, object property names must be - // double-quoted strings, and a `:` must separate each property - // name and value. - if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") { - abort(); - } - results[value.slice(1)] = get(lex()); - } - return results; - } - // Unexpected token encountered. - abort(); - } - return value; - }; +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + * @license MIT (© Joyent) + */ +/* legacy: obj, showHidden, depth, colors*/ - // Internal: Updates a traversed object member. - var update = function (source, property, callback) { - var element = walk(source, property, callback); - if (element === undef) { - delete source[property]; - } else { - source[property] = element; - } - }; +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + _extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} - // Internal: Recursively traverses a parsed JSON object, invoking the - // `callback` function for each value. This is an implementation of the - // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2. - var walk = function (source, property, callback) { - var value = source[property], length; - if (typeof value == "object" && value) { - // `forEach` can't be used to traverse an array in Opera <= 8.54 - // because its `Object#hasOwnProperty` implementation returns `false` - // for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`). - if (getClass.call(value) == arrayClass) { - for (length = value.length; length--;) { - update(value, length, callback); - } - } else { - forEach(value, function (property) { - update(value, property, callback); - }); - } - } - return callback.call(source, property, value); - }; +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; - // Public: `JSON.parse`. See ES 5.1 section 15.12.2. - exports.parse = function (source, callback) { - var result, value; - Index = 0; - Source = "" + source; - result = get(lex()); - // If a JSON string contains multiple tokens, it is invalid. - if (lex() != "$") { - abort(); - } - // Reset the parser state. - Index = Source = null; - return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result; - }; - } - } +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; - exports["runInContext"] = runInContext; - return exports; - } - - if (typeof exports == "object" && exports && !exports.nodeType && !isLoader) { - // Export for CommonJS environments. - runInContext(root, exports); - } else { - // Export for web browsers and JavaScript engines. - var nativeJSON = root.JSON; - var JSON3 = runInContext(root, (root["JSON3"] = { - // Public: Restores the original value of the global `JSON` object and - // returns a reference to the `JSON3` object. - "noConflict": function () { - root.JSON = nativeJSON; - return JSON3; - } - })); - - root.JSON = { - "parse": JSON3.parse, - "stringify": JSON3.stringify - }; - } - - // Export for asynchronous module loaders. - if (isLoader) { - define(function () { - return JSON3; - }); - } -}(this)); - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],58:[function(require,module,exports){ -"use strict"; - -var hasOwn = Object.prototype.hasOwnProperty; -var toString = Object.prototype.toString; - -var isFunction = function (fn) { - return (typeof fn === 'function' && !(fn instanceof RegExp)) || toString.call(fn) === '[object Function]'; -}; - -module.exports = function forEach(obj, fn) { - if (!isFunction(fn)) { - throw new TypeError('iterator must be a function'); - } - var i, k, - isString = typeof obj === 'string', - l = obj.length, - context = arguments.length > 2 ? arguments[2] : null; - if (l === +l) { - for (i = 0; i < l; i++) { - if (context === null) { - fn(isString ? obj.charAt(i) : obj[i], i, obj); - } else { - fn.call(context, isString ? obj.charAt(i) : obj[i], i, obj); - } - } - } else { - for (k in obj) { - if (hasOwn.call(obj, k)) { - if (context === null) { - fn(obj[k], k, obj); - } else { - fn.call(context, obj[k], k, obj); - } - } - } - } -}; - - -},{}],59:[function(require,module,exports){ -"use strict"; - -// modified from https://github.com/es-shims/es5-shim -var has = Object.prototype.hasOwnProperty, - toString = Object.prototype.toString, - forEach = require('./foreach'), - isArgs = require('./isArguments'), - hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'), - hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), - dontEnums = [ - "toString", - "toLocaleString", - "valueOf", - "hasOwnProperty", - "isPrototypeOf", - "propertyIsEnumerable", - "constructor" - ]; - -var keysShim = function keys(object) { - var isObject = object !== null && typeof object === 'object', - isFunction = toString.call(object) === '[object Function]', - isArguments = isArgs(object), - theKeys = []; - - if (!isObject && !isFunction && !isArguments) { - throw new TypeError("Object.keys called on a non-object"); - } - - if (isArguments) { - forEach(object, function (value, index) { - theKeys.push(index); - }); - } else { - var name, - skipProto = hasProtoEnumBug && isFunction; - - for (name in object) { - if (!(skipProto && name === 'prototype') && has.call(object, name)) { - theKeys.push(name); - } - } - } - - if (hasDontEnumBug) { - var ctor = object.constructor, - skipConstructor = ctor && ctor.prototype === object; - - forEach(dontEnums, function (dontEnum) { - if (!(skipConstructor && dontEnum === 'constructor') && has.call(object, dontEnum)) { - theKeys.push(dontEnum); - } - }); - } - return theKeys; -}; - -keysShim.shim = function shimObjectKeys() { - if (!Object.keys) { - Object.keys = keysShim; - } - return Object.keys || keysShim; -}; - -module.exports = keysShim; - - -},{"./foreach":58,"./isArguments":60}],60:[function(require,module,exports){ -"use strict"; - -var toString = Object.prototype.toString; - -module.exports = function isArguments(value) { - var str = toString.call(value); - var isArguments = str === '[object Arguments]'; - if (!isArguments) { - isArguments = str !== '[object Array]' - && value !== null - && typeof value === 'object' - && typeof value.length === 'number' - && value.length >= 0 - && toString.call(value.callee) === '[object Function]'; - } - return isArguments; -}; - - -},{}],61:[function(require,module,exports){ - -/** - * Module dependencies. - */ - -var map = require('array-map'); -var indexOf = require('indexof'); -var isArray = require('isarray'); -var forEach = require('foreach'); -var reduce = require('array-reduce'); -var getObjectKeys = require('object-keys'); -var JSON = require('json3'); - -/** - * Make sure `Object.keys` work for `undefined` - * values that are still there, like `document.all`. - * http://lists.w3.org/Archives/Public/public-html/2009Jun/0546.html - * - * @api private - */ - -function objectKeys(val){ - if (Object.keys) return Object.keys(val); - return getObjectKeys(val); -} - -/** - * Module exports. - */ - -module.exports = inspect; - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - * @license MIT (© Joyent) - */ -/* legacy: obj, showHidden, depth, colors*/ - -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - _extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; - -function stylizeNoColor(str, styleType) { - return str; -} +function stylizeNoColor(str, styleType) { + return str; +} function isBoolean(arg) { return typeof arg === 'boolean'; @@ -7821,192 +6893,1094 @@ function formatValue(ctx, value, recurseTimes) { return formatError(value); } - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = map(keys, function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = { value: value[key] }; + if (Object.getOwnPropertyDescriptor) { + desc = Object.getOwnPropertyDescriptor(value, key) || desc; + } + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwn(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (indexOf(ctx.seen, desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = map(str.split('\n'), function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + map(str.split('\n'), function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = reduce(output, function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + +function _extend(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = objectKeys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +} + +},{"array-map":26,"array-reduce":27,"foreach":54,"indexof":55,"isarray":56,"json3":61,"object-keys":58}],61:[function(require,module,exports){ +(function (global){ +/*! JSON v3.3.0 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */ +;(function (root) { + // Detect the `define` function exposed by asynchronous module loaders. The + // strict `define` check is necessary for compatibility with `r.js`. + var isLoader = typeof define === "function" && define.amd; + + // Use the `global` object exposed by Node (including Browserify via + // `insert-module-globals`), Narwhal, and Ringo as the default context. + // Rhino exports a `global` function instead. + var freeGlobal = typeof global == "object" && global; + if (freeGlobal && (freeGlobal["global"] === freeGlobal || freeGlobal["window"] === freeGlobal)) { + root = freeGlobal; + } + + // Public: Initializes JSON 3 using the given `context` object, attaching the + // `stringify` and `parse` functions to the specified `exports` object. + function runInContext(context, exports) { + context || (context = root["Object"]()); + exports || (exports = root["Object"]()); + + // Native constructor aliases. + var Number = context["Number"] || root["Number"], + String = context["String"] || root["String"], + Object = context["Object"] || root["Object"], + Date = context["Date"] || root["Date"], + SyntaxError = context["SyntaxError"] || root["SyntaxError"], + TypeError = context["TypeError"] || root["TypeError"], + Math = context["Math"] || root["Math"], + nativeJSON = context["JSON"] || root["JSON"]; + + // Delegate to the native `stringify` and `parse` implementations. + if (typeof nativeJSON == "object" && nativeJSON) { + exports.stringify = nativeJSON.stringify; + exports.parse = nativeJSON.parse; + } + + // Convenience aliases. + var objectProto = Object.prototype, + getClass = objectProto.toString, + isProperty, forEach, undef; + + // Test the `Date#getUTC*` methods. Based on work by @Yaffle. + var isExtended = new Date(-3509827334573292); + try { + // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical + // results for certain dates in Opera >= 10.53. + isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 && + // Safari < 2.0.2 stores the internal millisecond time value correctly, + // but clips the values returned by the date methods to the range of + // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]). + isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708; + } catch (exception) {} + + // Internal: Determines whether the native `JSON.stringify` and `parse` + // implementations are spec-compliant. Based on work by Ken Snyder. + function has(name) { + if (has[name] !== undef) { + // Return cached feature test result. + return has[name]; + } + var isSupported; + if (name == "bug-string-char-index") { + // IE <= 7 doesn't support accessing string characters using square + // bracket notation. IE 8 only supports this for primitives. + isSupported = "a"[0] != "a"; + } else if (name == "json") { + // Indicates whether both `JSON.stringify` and `JSON.parse` are + // supported. + isSupported = has("json-stringify") && has("json-parse"); + } else { + var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}'; + // Test `JSON.stringify`. + if (name == "json-stringify") { + var stringify = exports.stringify, stringifySupported = typeof stringify == "function" && isExtended; + if (stringifySupported) { + // A test function object with a custom `toJSON` method. + (value = function () { + return 1; + }).toJSON = value; + try { + stringifySupported = + // Firefox 3.1b1 and b2 serialize string, number, and boolean + // primitives as object literals. + stringify(0) === "0" && + // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object + // literals. + stringify(new Number()) === "0" && + stringify(new String()) == '""' && + // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or + // does not define a canonical JSON representation (this applies to + // objects with `toJSON` properties as well, *unless* they are nested + // within an object or array). + stringify(getClass) === undef && + // IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and + // FF 3.1b3 pass this test. + stringify(undef) === undef && + // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s, + // respectively, if the value is omitted entirely. + stringify() === undef && + // FF 3.1b1, 2 throw an error if the given value is not a number, + // string, array, object, Boolean, or `null` literal. This applies to + // objects with custom `toJSON` methods as well, unless they are nested + // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON` + // methods entirely. + stringify(value) === "1" && + stringify([value]) == "[1]" && + // Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of + // `"[null]"`. + stringify([undef]) == "[null]" && + // YUI 3.0.0b1 fails to serialize `null` literals. + stringify(null) == "null" && + // FF 3.1b1, 2 halts serialization if an array contains a function: + // `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3 + // elides non-JSON values from objects and arrays, unless they + // define custom `toJSON` methods. + stringify([undef, getClass, null]) == "[null,null,null]" && + // Simple serialization test. FF 3.1b1 uses Unicode escape sequences + // where character escape codes are expected (e.g., `\b` => `\u0008`). + stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized && + // FF 3.1b1 and b2 ignore the `filter` and `width` arguments. + stringify(null, value) === "1" && + stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" && + // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly + // serialize extended years. + stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' && + // The milliseconds are optional in ES 5, but required in 5.1. + stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' && + // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative + // four-digit years instead of six-digit years. Credits: @Yaffle. + stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' && + // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond + // values less than 1000. Credits: @Yaffle. + stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"'; + } catch (exception) { + stringifySupported = false; + } + } + isSupported = stringifySupported; + } + // Test `JSON.parse`. + if (name == "json-parse") { + var parse = exports.parse; + if (typeof parse == "function") { + try { + // FF 3.1b1, b2 will throw an exception if a bare literal is provided. + // Conforming implementations should also coerce the initial argument to + // a string prior to parsing. + if (parse("0") === 0 && !parse(false)) { + // Simple parsing test. + value = parse(serialized); + var parseSupported = value["a"].length == 5 && value["a"][0] === 1; + if (parseSupported) { + try { + // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings. + parseSupported = !parse('"\t"'); + } catch (exception) {} + if (parseSupported) { + try { + // FF 4.0 and 4.0.1 allow leading `+` signs and leading + // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow + // certain octal literals. + parseSupported = parse("01") !== 1; + } catch (exception) {} + } + if (parseSupported) { + try { + // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal + // points. These environments, along with FF 3.1b1 and 2, + // also allow trailing commas in JSON objects and arrays. + parseSupported = parse("1.") !== 1; + } catch (exception) {} + } + } + } + } catch (exception) { + parseSupported = false; + } + } + isSupported = parseSupported; + } + } + return has[name] = !!isSupported; + } + + if (!has("json")) { + // Common `[[Class]]` name aliases. + var functionClass = "[object Function]", + dateClass = "[object Date]", + numberClass = "[object Number]", + stringClass = "[object String]", + arrayClass = "[object Array]", + booleanClass = "[object Boolean]"; + + // Detect incomplete support for accessing string characters by index. + var charIndexBuggy = has("bug-string-char-index"); + + // Define additional utility methods if the `Date` methods are buggy. + if (!isExtended) { + var floor = Math.floor; + // A mapping between the months of the year and the number of days between + // January 1st and the first of the respective month. + var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; + // Internal: Calculates the number of days between the Unix epoch and the + // first day of the given month. + var getDay = function (year, month) { + return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400); + }; + } + + // Internal: Determines if a property is a direct property of the given + // object. Delegates to the native `Object#hasOwnProperty` method. + if (!(isProperty = objectProto.hasOwnProperty)) { + isProperty = function (property) { + var members = {}, constructor; + if ((members.__proto__ = null, members.__proto__ = { + // The *proto* property cannot be set multiple times in recent + // versions of Firefox and SeaMonkey. + "toString": 1 + }, members).toString != getClass) { + // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but + // supports the mutable *proto* property. + isProperty = function (property) { + // Capture and break the objectgs prototype chain (see section 8.6.2 + // of the ES 5.1 spec). The parenthesized expression prevents an + // unsafe transformation by the Closure Compiler. + var original = this.__proto__, result = property in (this.__proto__ = null, this); + // Restore the original prototype chain. + this.__proto__ = original; + return result; + }; + } else { + // Capture a reference to the top-level `Object` constructor. + constructor = members.constructor; + // Use the `constructor` property to simulate `Object#hasOwnProperty` in + // other environments. + isProperty = function (property) { + var parent = (this.constructor || constructor).prototype; + return property in this && !(property in parent && this[property] === parent[property]); + }; + } + members = null; + return isProperty.call(this, property); + }; + } + + // Internal: A set of primitive types used by `isHostType`. + var PrimitiveTypes = { + "boolean": 1, + "number": 1, + "string": 1, + "undefined": 1 + }; + + // Internal: Determines if the given object `property` value is a + // non-primitive. + var isHostType = function (object, property) { + var type = typeof object[property]; + return type == "object" ? !!object[property] : !PrimitiveTypes[type]; + }; + + // Internal: Normalizes the `for...in` iteration algorithm across + // environments. Each enumerated key is yielded to a `callback` function. + forEach = function (object, callback) { + var size = 0, Properties, members, property; + + // Tests for bugs in the current environment's `for...in` algorithm. The + // `valueOf` property inherits the non-enumerable flag from + // `Object.prototype` in older versions of IE, Netscape, and Mozilla. + (Properties = function () { + this.valueOf = 0; + }).prototype.valueOf = 0; + + // Iterate over a new instance of the `Properties` class. + members = new Properties(); + for (property in members) { + // Ignore all properties inherited from `Object.prototype`. + if (isProperty.call(members, property)) { + size++; + } + } + Properties = members = null; + + // Normalize the iteration algorithm. + if (!size) { + // A list of non-enumerable properties inherited from `Object.prototype`. + members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"]; + // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable + // properties. + forEach = function (object, callback) { + var isFunction = getClass.call(object) == functionClass, property, length; + var hasProperty = !isFunction && typeof object.constructor != "function" && isHostType(object, "hasOwnProperty") ? object.hasOwnProperty : isProperty; + for (property in object) { + // Gecko <= 1.0 enumerates the `prototype` property of functions under + // certain conditions; IE does not. + if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) { + callback(property); + } + } + // Manually invoke the callback for each non-enumerable property. + for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property)); + }; + } else if (size == 2) { + // Safari <= 2.0.4 enumerates shadowed properties twice. + forEach = function (object, callback) { + // Create a set of iterated properties. + var members = {}, isFunction = getClass.call(object) == functionClass, property; + for (property in object) { + // Store each property name to prevent double enumeration. The + // `prototype` property of functions is not enumerated due to cross- + // environment inconsistencies. + if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) { + callback(property); + } + } + }; + } else { + // No bugs detected; use the standard `for...in` algorithm. + forEach = function (object, callback) { + var isFunction = getClass.call(object) == functionClass, property, isConstructor; + for (property in object) { + if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) { + callback(property); + } + } + // Manually invoke the callback for the `constructor` property due to + // cross-environment inconsistencies. + if (isConstructor || isProperty.call(object, (property = "constructor"))) { + callback(property); + } + }; + } + return forEach(object, callback); + }; + + // Public: Serializes a JavaScript `value` as a JSON string. The optional + // `filter` argument may specify either a function that alters how object and + // array members are serialized, or an array of strings and numbers that + // indicates which properties should be serialized. The optional `width` + // argument may be either a string or number that specifies the indentation + // level of the output. + if (!has("json-stringify")) { + // Internal: A map of control characters and their escaped equivalents. + var Escapes = { + 92: "\\\\", + 34: '\\"', + 8: "\\b", + 12: "\\f", + 10: "\\n", + 13: "\\r", + 9: "\\t" + }; + + // Internal: Converts `value` into a zero-padded string such that its + // length is at least equal to `width`. The `width` must be <= 6. + var leadingZeroes = "000000"; + var toPaddedString = function (width, value) { + // The `|| 0` expression is necessary to work around a bug in + // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`. + return (leadingZeroes + (value || 0)).slice(-width); + }; + + // Internal: Double-quotes a string `value`, replacing all ASCII control + // characters (characters with code unit values between 0 and 31) with + // their escaped equivalents. This is an implementation of the + // `Quote(value)` operation defined in ES 5.1 section 15.12.3. + var unicodePrefix = "\\u00"; + var quote = function (value) { + var result = '"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10; + var symbols = useCharIndex && (charIndexBuggy ? value.split("") : value); + for (; index < length; index++) { + var charCode = value.charCodeAt(index); + // If the character is a control character, append its Unicode or + // shorthand escape sequence; otherwise, append the character as-is. + switch (charCode) { + case 8: case 9: case 10: case 12: case 13: case 34: case 92: + result += Escapes[charCode]; + break; + default: + if (charCode < 32) { + result += unicodePrefix + toPaddedString(2, charCode.toString(16)); + break; + } + result += useCharIndex ? symbols[index] : value.charAt(index); + } + } + return result + '"'; + }; + + // Internal: Recursively serializes an object. Implements the + // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations. + var serialize = function (property, object, callback, properties, whitespace, indentation, stack) { + var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result; + try { + // Necessary for host object support. + value = object[property]; + } catch (exception) {} + if (typeof value == "object" && value) { + className = getClass.call(value); + if (className == dateClass && !isProperty.call(value, "toJSON")) { + if (value > -1 / 0 && value < 1 / 0) { + // Dates are serialized according to the `Date#toJSON` method + // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15 + // for the ISO 8601 date time string format. + if (getDay) { + // Manually compute the year, month, date, hours, minutes, + // seconds, and milliseconds if the `getUTC*` methods are + // buggy. Adapted from @Yaffle's `date-shim` project. + date = floor(value / 864e5); + for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++); + for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++); + date = 1 + date - getDay(year, month); + // The `time` value specifies the time within the day (see ES + // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used + // to compute `A modulo B`, as the `%` operator does not + // correspond to the `modulo` operation for negative numbers. + time = (value % 864e5 + 864e5) % 864e5; + // The hours, minutes, seconds, and milliseconds are obtained by + // decomposing the time within the day. See section 15.9.1.10. + hours = floor(time / 36e5) % 24; + minutes = floor(time / 6e4) % 60; + seconds = floor(time / 1e3) % 60; + milliseconds = time % 1e3; + } else { + year = value.getUTCFullYear(); + month = value.getUTCMonth(); + date = value.getUTCDate(); + hours = value.getUTCHours(); + minutes = value.getUTCMinutes(); + seconds = value.getUTCSeconds(); + milliseconds = value.getUTCMilliseconds(); + } + // Serialize extended years correctly. + value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) + + "-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) + + // Months, dates, hours, minutes, and seconds should have two + // digits; milliseconds should have three. + "T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) + + // Milliseconds are optional in ES 5.0, but required in 5.1. + "." + toPaddedString(3, milliseconds) + "Z"; + } else { + value = null; + } + } else if (typeof value.toJSON == "function" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, "toJSON"))) { + // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the + // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3 + // ignores all `toJSON` methods on these objects unless they are + // defined directly on an instance. + value = value.toJSON(property); + } + } + if (callback) { + // If a replacement function was provided, call it to obtain the value + // for serialization. + value = callback.call(object, property, value); + } + if (value === null) { + return "null"; + } + className = getClass.call(value); + if (className == booleanClass) { + // Booleans are represented literally. + return "" + value; + } else if (className == numberClass) { + // JSON numbers must be finite. `Infinity` and `NaN` are serialized as + // `"null"`. + return value > -1 / 0 && value < 1 / 0 ? "" + value : "null"; + } else if (className == stringClass) { + // Strings are double-quoted and escaped. + return quote("" + value); + } + // Recursively serialize objects and arrays. + if (typeof value == "object") { + // Check for cyclic structures. This is a linear search; performance + // is inversely proportional to the number of unique nested objects. + for (length = stack.length; length--;) { + if (stack[length] === value) { + // Cyclic structures cannot be serialized by `JSON.stringify`. + throw TypeError(); + } + } + // Add the object to the stack of traversed objects. + stack.push(value); + results = []; + // Save the current indentation level and indent one additional level. + prefix = indentation; + indentation += whitespace; + if (className == arrayClass) { + // Recursively serialize array elements. + for (index = 0, length = value.length; index < length; index++) { + element = serialize(index, value, callback, properties, whitespace, indentation, stack); + results.push(element === undef ? "null" : element); + } + result = results.length ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]"; + } else { + // Recursively serialize object members. Members are selected from + // either a user-specified list of property names, or the object + // itself. + forEach(properties || value, function (property) { + var element = serialize(property, value, callback, properties, whitespace, indentation, stack); + if (element !== undef) { + // According to ES 5.1 section 15.12.3: "If `gap` {whitespace} + // is not the empty string, let `member` {quote(property) + ":"} + // be the concatenation of `member` and the `space` character." + // The "`space` character" refers to the literal space + // character, not the `space` {width} argument provided to + // `JSON.stringify`. + results.push(quote(property) + ":" + (whitespace ? " " : "") + element); + } + }); + result = results.length ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}"; + } + // Remove the object from the traversed object stack. + stack.pop(); + return result; + } + }; + + // Public: `JSON.stringify`. See ES 5.1 section 15.12.3. + exports.stringify = function (source, filter, width) { + var whitespace, callback, properties, className; + if (typeof filter == "function" || typeof filter == "object" && filter) { + if ((className = getClass.call(filter)) == functionClass) { + callback = filter; + } else if (className == arrayClass) { + // Convert the property names array into a makeshift set. + properties = {}; + for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1)); + } + } + if (width) { + if ((className = getClass.call(width)) == numberClass) { + // Convert the `width` to an integer and create a string containing + // `width` number of space characters. + if ((width -= width % 1) > 0) { + for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " "); + } + } else if (className == stringClass) { + whitespace = width.length <= 10 ? width : width.slice(0, 10); + } + } + // Opera <= 7.54u2 discards the values associated with empty string keys + // (`""`) only if they are used directly within an object member list + // (e.g., `!("" in { "": 1})`). + return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []); + }; + } + + // Public: Parses a JSON source string. + if (!has("json-parse")) { + var fromCharCode = String.fromCharCode; - var base = '', array = false, braces = ['{', '}']; + // Internal: A map of escaped control characters and their unescaped + // equivalents. + var Unescapes = { + 92: "\\", + 34: '"', + 47: "/", + 98: "\b", + 116: "\t", + 110: "\n", + 102: "\f", + 114: "\r" + }; - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } + // Internal: Stores the parser state. + var Index, Source; - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } + // Internal: Resets the parser state and throws a `SyntaxError`. + var abort = function () { + Index = Source = null; + throw SyntaxError(); + }; - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } + // Internal: Returns the next token, or `"$"` if the parser has reached + // the end of the source string. A token may be a string, number, `null` + // literal, or Boolean literal. + var lex = function () { + var source = Source, length = source.length, value, begin, position, isSigned, charCode; + while (Index < length) { + charCode = source.charCodeAt(Index); + switch (charCode) { + case 9: case 10: case 13: case 32: + // Skip whitespace tokens, including tabs, carriage returns, line + // feeds, and space characters. + Index++; + break; + case 123: case 125: case 91: case 93: case 58: case 44: + // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at + // the current position. + value = charIndexBuggy ? source.charAt(Index) : source[Index]; + Index++; + return value; + case 34: + // `"` delimits a JSON string; advance to the next character and + // begin parsing the string. String tokens are prefixed with the + // sentinel `@` character to distinguish them from punctuators and + // end-of-string tokens. + for (value = "@", Index++; Index < length;) { + charCode = source.charCodeAt(Index); + if (charCode < 32) { + // Unescaped ASCII control characters (those with a code unit + // less than the space character) are not permitted. + abort(); + } else if (charCode == 92) { + // A reverse solidus (`\`) marks the beginning of an escaped + // control character (including `"`, `\`, and `/`) or Unicode + // escape sequence. + charCode = source.charCodeAt(++Index); + switch (charCode) { + case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114: + // Revive escaped control characters. + value += Unescapes[charCode]; + Index++; + break; + case 117: + // `\u` marks the beginning of a Unicode escape sequence. + // Advance to the first character and validate the + // four-digit code point. + begin = ++Index; + for (position = Index + 4; Index < position; Index++) { + charCode = source.charCodeAt(Index); + // A valid sequence comprises four hexdigits (case- + // insensitive) that form a single hexadecimal value. + if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) { + // Invalid Unicode escape sequence. + abort(); + } + } + // Revive the escaped character. + value += fromCharCode("0x" + source.slice(begin, Index)); + break; + default: + // Invalid escape sequence. + abort(); + } + } else { + if (charCode == 34) { + // An unescaped double-quote character marks the end of the + // string. + break; + } + charCode = source.charCodeAt(Index); + begin = Index; + // Optimize for the common case where a string is valid. + while (charCode >= 32 && charCode != 92 && charCode != 34) { + charCode = source.charCodeAt(++Index); + } + // Append the string as-is. + value += source.slice(begin, Index); + } + } + if (source.charCodeAt(Index) == 34) { + // Advance to the next character and return the revived string. + Index++; + return value; + } + // Unterminated string. + abort(); + default: + // Parse numbers and literals. + begin = Index; + // Advance past the negative sign, if one is specified. + if (charCode == 45) { + isSigned = true; + charCode = source.charCodeAt(++Index); + } + // Parse an integer or floating-point value. + if (charCode >= 48 && charCode <= 57) { + // Leading zeroes are interpreted as octal literals. + if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) { + // Illegal octal literal. + abort(); + } + isSigned = false; + // Parse the integer component. + for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++); + // Floats cannot contain a leading decimal point; however, this + // case is already accounted for by the parser. + if (source.charCodeAt(Index) == 46) { + position = ++Index; + // Parse the decimal component. + for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++); + if (position == Index) { + // Illegal trailing decimal. + abort(); + } + Index = position; + } + // Parse exponents. The `e` denoting the exponent is + // case-insensitive. + charCode = source.charCodeAt(Index); + if (charCode == 101 || charCode == 69) { + charCode = source.charCodeAt(++Index); + // Skip past the sign following the exponent, if one is + // specified. + if (charCode == 43 || charCode == 45) { + Index++; + } + // Parse the exponential component. + for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++); + if (position == Index) { + // Illegal empty exponent. + abort(); + } + Index = position; + } + // Coerce the parsed value to a JavaScript number. + return +source.slice(begin, Index); + } + // A negative sign may only precede numbers. + if (isSigned) { + abort(); + } + // `true`, `false`, and `null` literals. + if (source.slice(Index, Index + 4) == "true") { + Index += 4; + return true; + } else if (source.slice(Index, Index + 5) == "false") { + Index += 5; + return false; + } else if (source.slice(Index, Index + 4) == "null") { + Index += 4; + return null; + } + // Unrecognized token. + abort(); + } + } + // Return the sentinel `$` character if the parser has reached the end + // of the source string. + return "$"; + }; - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } + // Internal: Parses a JSON `value` token. + var get = function (value) { + var results, hasMembers; + if (value == "$") { + // Unexpected end of input. + abort(); + } + if (typeof value == "string") { + if ((charIndexBuggy ? value.charAt(0) : value[0]) == "@") { + // Remove the sentinel `@` character. + return value.slice(1); + } + // Parse object and array literals. + if (value == "[") { + // Parses a JSON array, returning a new JavaScript array. + results = []; + for (;; hasMembers || (hasMembers = true)) { + value = lex(); + // A closing square bracket marks the end of the array literal. + if (value == "]") { + break; + } + // If the array literal contains elements, the current token + // should be a comma separating the previous element from the + // next. + if (hasMembers) { + if (value == ",") { + value = lex(); + if (value == "]") { + // Unexpected trailing `,` in array literal. + abort(); + } + } else { + // A `,` must separate each array element. + abort(); + } + } + // Elisions and leading commas are not permitted. + if (value == ",") { + abort(); + } + results.push(get(value)); + } + return results; + } else if (value == "{") { + // Parses a JSON object, returning a new JavaScript object. + results = {}; + for (;; hasMembers || (hasMembers = true)) { + value = lex(); + // A closing curly brace marks the end of the object literal. + if (value == "}") { + break; + } + // If the object literal contains members, the current token + // should be a comma separator. + if (hasMembers) { + if (value == ",") { + value = lex(); + if (value == "}") { + // Unexpected trailing `,` in object literal. + abort(); + } + } else { + // A `,` must separate each object member. + abort(); + } + } + // Leading commas are not permitted, object property names must be + // double-quoted strings, and a `:` must separate each property + // name and value. + if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") { + abort(); + } + results[value.slice(1)] = get(lex()); + } + return results; + } + // Unexpected token encountered. + abort(); + } + return value; + }; - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } + // Internal: Updates a traversed object member. + var update = function (source, property, callback) { + var element = walk(source, property, callback); + if (element === undef) { + delete source[property]; + } else { + source[property] = element; + } + }; - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } + // Internal: Recursively traverses a parsed JSON object, invoking the + // `callback` function for each value. This is an implementation of the + // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2. + var walk = function (source, property, callback) { + var value = source[property], length; + if (typeof value == "object" && value) { + // `forEach` can't be used to traverse an array in Opera <= 8.54 + // because its `Object#hasOwnProperty` implementation returns `false` + // for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`). + if (getClass.call(value) == arrayClass) { + for (length = value.length; length--;) { + update(value, length, callback); + } + } else { + forEach(value, function (property) { + update(value, property, callback); + }); + } + } + return callback.call(source, property, value); + }; - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); + // Public: `JSON.parse`. See ES 5.1 section 15.12.2. + exports.parse = function (source, callback) { + var result, value; + Index = 0; + Source = "" + source; + result = get(lex()); + // If a JSON string contains multiple tokens, it is invalid. + if (lex() != "$") { + abort(); + } + // Reset the parser state. + Index = Source = null; + return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result; + }; + } } - } - - ctx.seen.push(value); - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = map(keys, function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); + exports["runInContext"] = runInContext; + return exports; } - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -} - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = { value: value[key] }; - if (Object.getOwnPropertyDescriptor) { - desc = Object.getOwnPropertyDescriptor(value, key) || desc; - } - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } + if (typeof exports == "object" && exports && !exports.nodeType && !isLoader) { + // Export for CommonJS environments. + runInContext(root, exports); } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwn(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (indexOf(ctx.seen, desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = map(str.split('\n'), function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + map(str.split('\n'), function(line) { - return ' ' + line; - }).join('\n'); - } + // Export for web browsers and JavaScript engines. + var nativeJSON = root.JSON; + var JSON3 = runInContext(root, (root["JSON3"] = { + // Public: Restores the original value of the global `JSON` object and + // returns a reference to the `JSON3` object. + "noConflict": function () { + root.JSON = nativeJSON; + return JSON3; } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} + })); -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); + root.JSON = { + "parse": JSON3.parse, + "stringify": JSON3.stringify + }; } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = reduce(output, function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; + // Export for asynchronous module loaders. + if (isLoader) { + define(function () { + return JSON3; + }); } +}(this)); - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - -function _extend(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - - var keys = objectKeys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; -} +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"array-map":26,"array-reduce":27,"foreach":54,"indexof":55,"isarray":56,"json3":57,"object-keys":59}],62:[function(require,module,exports){ +},{}],62:[function(require,module,exports){ "use strict" // This is a reporter that mimics Mocha's `dot` reporter @@ -8337,4 +8311,4 @@ exports.settings = { } },{"../assert":1,"../dom":2,"../index":3,"../internal":4,"../r":63,"./settings":24}]},{},[]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJhc3NlcnQuanMiLCJkb20uanMiLCJpbmRleC5qcyIsImludGVybmFsLmpzIiwibGliL2FwaS9jb21tb24uanMiLCJsaWIvYXBpL3JlZmxlY3QuanMiLCJsaWIvYXBpL3RoYWxsaXVtLmpzIiwibGliL2NvcmUvZmlsdGVyLmpzIiwibGliL2NvcmUvcmVwb3J0cy5qcyIsImxpYi9jb3JlL3Rlc3RzLmpzIiwibGliL2RvbS9pbmRleC5qcyIsImxpYi9kb20vaW5pdGlhbGl6ZS5qcyIsImxpYi9kb20vaW5qZWN0LXN0eWxlcy5qcyIsImxpYi9kb20vaW5qZWN0LmpzIiwibGliL2RvbS9ydW4tdGVzdHMuanMiLCJsaWIvZG9tL3ZpZXcuanMiLCJsaWIvbWV0aG9kcy5qcyIsImxpYi9yZXBsYWNlZC9jb25zb2xlLWJyb3dzZXIuanMiLCJsaWIvcmVwb3J0ZXIvY29uc29sZS1yZXBvcnRlci5qcyIsImxpYi9yZXBvcnRlci9pbmRleC5qcyIsImxpYi9yZXBvcnRlci9vbi5qcyIsImxpYi9yZXBvcnRlci9yZXBvcnRlci5qcyIsImxpYi9yZXBvcnRlci91dGlsLmpzIiwibGliL3NldHRpbmdzLmpzIiwibGliL3V0aWwuanMiLCJub2RlX21vZHVsZXMvYXJyYXktbWFwL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2FycmF5LXJlZHVjZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1hc3NlcnQtdXRpbC9icm93c2VyLWluc3BlY3QuanMiLCJub2RlX21vZHVsZXMvY2xlYW4tYXNzZXJ0LXV0aWwvaW5kZXguanMiLCJub2RlX21vZHVsZXMvY2xlYW4tYXNzZXJ0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2NsZWFuLWFzc2VydC9saWIvZXF1YWwuanMiLCJub2RlX21vZHVsZXMvY2xlYW4tYXNzZXJ0L2xpYi9oYXMta2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1hc3NlcnQvbGliL2hhcy5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1hc3NlcnQvbGliL2luY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2NsZWFuLWFzc2VydC9saWIvdGhyb3dzLmpzIiwibm9kZV9tb2R1bGVzL2NsZWFuLWFzc2VydC9saWIvdHlwZS5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1tYXRjaC9jbGVhbi1tYXRjaC5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9jb252ZXJ0L2RtcC5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9jb252ZXJ0L3htbC5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9kaWZmL2FycmF5LmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL2RpZmYvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9kaWZmL2NoYXJhY3Rlci5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9kaWZmL2Nzcy5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9kaWZmL2pzb24uanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvZGlmZi9saW5lLmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL2RpZmYvc2VudGVuY2UuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvZGlmZi93b3JkLmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL3BhdGNoL2FwcGx5LmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL3BhdGNoL2NyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9wYXRjaC9wYXJzZS5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy91dGlsL2Rpc3RhbmNlLWl0ZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL3V0aWwvcGFyYW1zLmpzIiwibm9kZV9tb2R1bGVzL2ZvcmVhY2gvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaW5kZXhvZi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2pzb24zL2xpYi9qc29uMy5qcyIsIm5vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9mb3JlYWNoLmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2lzQXJndW1lbnRzLmpzIiwibm9kZV9tb2R1bGVzL3V0aWwtaW5zcGVjdC9pbmRleC5qcyIsInIvZG90LmpzIiwici9pbmRleC5qcyIsInIvc3BlYy5qcyIsInIvdGFwLmpzIiwibGliL2Jyb3dzZXItYnVuZGxlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNVdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDL1FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDL2tCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN2WEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNySkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNyUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNsREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25MQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN0SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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O0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBOzs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2o0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoYUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIlwidXNlIHN0cmljdFwiXG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNsZWFuLWFzc2VydFwiKVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiLi9saWIvZG9tXCIpXG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vKipcbiAqIE1haW4gZW50cnkgcG9pbnQsIGZvciB0aG9zZSB3YW50aW5nIHRvIHVzZSB0aGlzIGZyYW1ld29yayB3aXRoIHRoZSBjb3JlXG4gKiBhc3NlcnRpb25zLlxuICovXG52YXIgVGhhbGxpdW0gPSByZXF1aXJlKFwiLi9saWIvYXBpL3RoYWxsaXVtXCIpXG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFRoYWxsaXVtKClcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBUaGFsbGl1bSA9IHJlcXVpcmUoXCIuL2xpYi9hcGkvdGhhbGxpdW1cIilcbnZhciBSZXBvcnRzID0gcmVxdWlyZShcIi4vbGliL2NvcmUvcmVwb3J0c1wiKVxudmFyIFR5cGVzID0gUmVwb3J0cy5UeXBlc1xuXG5leHBvcnRzLnJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5ldyBUaGFsbGl1bSgpXG59XG5cbmZ1bmN0aW9uIGQoZHVyYXRpb24pIHtcbiAgICBpZiAoZHVyYXRpb24gPT0gbnVsbCkgcmV0dXJuIDEwXG4gICAgaWYgKHR5cGVvZiBkdXJhdGlvbiA9PT0gXCJudW1iZXJcIikgcmV0dXJuIGR1cmF0aW9ufDBcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYGR1cmF0aW9uYCB0byBiZSBhIG51bWJlciBpZiBpdCBleGlzdHNcIilcbn1cblxuZnVuY3Rpb24gcyhzbG93KSB7XG4gICAgaWYgKHNsb3cgPT0gbnVsbCkgcmV0dXJuIDc1XG4gICAgaWYgKHR5cGVvZiBzbG93ID09PSBcIm51bWJlclwiKSByZXR1cm4gc2xvd3wwXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBzbG93YCB0byBiZSBhIG51bWJlciBpZiBpdCBleGlzdHNcIilcbn1cblxuZnVuY3Rpb24gcChwYXRoKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocGF0aCkpIHJldHVybiBwYXRoXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBwYXRoYCB0byBiZSBhbiBhcnJheSBvZiBsb2NhdGlvbnNcIilcbn1cblxuZnVuY3Rpb24gaCh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIHR5cGVvZiB2YWx1ZS5fID09PSBcIm51bWJlclwiKSByZXR1cm4gdmFsdWVcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHZhbHVlYCB0byBiZSBhIGhvb2sgZXJyb3JcIilcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgcmVwb3J0LCBtYWlubHkgZm9yIHRlc3RpbmcgcmVwb3J0ZXJzLlxuICovXG5leHBvcnRzLnJlcG9ydHMgPSB7XG4gICAgc3RhcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBvcnRzLlN0YXJ0KClcbiAgICB9LFxuXG4gICAgZW50ZXI6IGZ1bmN0aW9uIChwYXRoLCBkdXJhdGlvbiwgc2xvdykge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuRW50ZXIocChwYXRoKSwgZChkdXJhdGlvbiksIHMoc2xvdykpXG4gICAgfSxcblxuICAgIGxlYXZlOiBmdW5jdGlvbiAocGF0aCkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuTGVhdmUocChwYXRoKSlcbiAgICB9LFxuXG4gICAgcGFzczogZnVuY3Rpb24gKHBhdGgsIGR1cmF0aW9uLCBzbG93KSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5QYXNzKHAocGF0aCksIGQoZHVyYXRpb24pLCBzKHNsb3cpKVxuICAgIH0sXG5cbiAgICBmYWlsOiBmdW5jdGlvbiAocGF0aCwgdmFsdWUsIGR1cmF0aW9uLCBzbG93LCBpc0ZhaWxhYmxlKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuRmFpbChcbiAgICAgICAgICAgIHAocGF0aCksIHZhbHVlLCBkKGR1cmF0aW9uKSwgcyhzbG93KSxcbiAgICAgICAgICAgICEhaXNGYWlsYWJsZSlcbiAgICB9LFxuXG4gICAgc2tpcDogZnVuY3Rpb24gKHBhdGgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBvcnRzLlNraXAocChwYXRoKSlcbiAgICB9LFxuXG4gICAgZW5kOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5FbmQoKVxuICAgIH0sXG5cbiAgICBlcnJvcjogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5FcnJvcih2YWx1ZSlcbiAgICB9LFxuXG4gICAgaG9vazogZnVuY3Rpb24gKHBhdGgsIHJvb3RQYXRoLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuSG9vayhwKHBhdGgpLCBwKHJvb3RQYXRoKSwgaCh2YWx1ZSkpXG4gICAgfSxcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgaG9vayBlcnJvciwgbWFpbmx5IGZvciB0ZXN0aW5nIHJlcG9ydGVycy5cbiAqL1xuZXhwb3J0cy5ob29rRXJyb3JzID0ge1xuICAgIGJlZm9yZUFsbDogZnVuY3Rpb24gKGZ1bmMsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5Ib29rRXJyb3IoVHlwZXMuQmVmb3JlQWxsLCBmdW5jLCB2YWx1ZSlcbiAgICB9LFxuXG4gICAgYmVmb3JlRWFjaDogZnVuY3Rpb24gKGZ1bmMsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5Ib29rRXJyb3IoVHlwZXMuQmVmb3JlRWFjaCwgZnVuYywgdmFsdWUpXG4gICAgfSxcblxuICAgIGFmdGVyRWFjaDogZnVuY3Rpb24gKGZ1bmMsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5Ib29rRXJyb3IoVHlwZXMuQWZ0ZXJFYWNoLCBmdW5jLCB2YWx1ZSlcbiAgICB9LFxuXG4gICAgYWZ0ZXJBbGw6IGZ1bmN0aW9uIChmdW5jLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuSG9va0Vycm9yKFR5cGVzLkFmdGVyQWxsLCBmdW5jLCB2YWx1ZSlcbiAgICB9LFxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgbG9jYXRpb24sIG1haW5seSBmb3IgdGVzdGluZyByZXBvcnRlcnMuXG4gKi9cbmV4cG9ydHMubG9jYXRpb24gPSBmdW5jdGlvbiAobmFtZSwgaW5kZXgpIHtcbiAgICBpZiAodHlwZW9mIG5hbWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBuYW1lYCB0byBiZSBhIHN0cmluZ1wiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgaW5kZXggIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBpbmRleGAgdG8gYmUgYSBudW1iZXJcIilcbiAgICB9XG5cbiAgICByZXR1cm4ge25hbWU6IG5hbWUsIGluZGV4OiBpbmRleHwwfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuZXhwb3J0cy5hZGRIb29rID0gZnVuY3Rpb24gKGxpc3QsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGxpc3QgIT0gbnVsbCkge1xuICAgICAgICBsaXN0LnB1c2goY2FsbGJhY2spXG4gICAgICAgIHJldHVybiBsaXN0XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFtjYWxsYmFja11cbiAgICB9XG59XG5cbmV4cG9ydHMucmVtb3ZlSG9vayA9IGZ1bmN0aW9uIChsaXN0LCBjYWxsYmFjaykge1xuICAgIGlmIChsaXN0ID09IG51bGwpIHJldHVybiB1bmRlZmluZWRcbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgaWYgKGxpc3RbMF0gPT09IGNhbGxiYWNrKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIGluZGV4ID0gbGlzdC5pbmRleE9mKGNhbGxiYWNrKVxuXG4gICAgICAgIGlmIChpbmRleCA+PSAwKSBsaXN0LnNwbGljZShpbmRleCwgMSlcbiAgICB9XG4gICAgcmV0dXJuIGxpc3Rcbn1cblxuZXhwb3J0cy5oYXNIb29rID0gZnVuY3Rpb24gKGxpc3QsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGxpc3QgPT0gbnVsbCkgcmV0dXJuIGZhbHNlXG4gICAgaWYgKGxpc3QubGVuZ3RoID4gMSkgcmV0dXJuIGxpc3QuaW5kZXhPZihjYWxsYmFjaykgPj0gMFxuICAgIHJldHVybiBsaXN0WzBdID09PSBjYWxsYmFja1xufVxuXG4vLyBUT0RPOiBjYWNoZSBhbmQgcmVtb3ZlIHRoZXNlIHRyYXZlcnNhbHMgZm9yIDAuNC5cbi8vIE5vdGUgdGhhdCBhIHRpbWVvdXQgb2YgMCBtZWFucyB0byBpbmhlcml0IHRoZSBwYXJlbnQuXG5leHBvcnRzLmdldFRpbWVvdXQgPSBmdW5jdGlvbiAodGVzdCkge1xuICAgIHdoaWxlICghdGVzdC50aW1lb3V0ICYmIHRlc3QucGFyZW50ICE9IG51bGwpIHtcbiAgICAgICAgdGVzdCA9IHRlc3QucGFyZW50XG4gICAgfVxuXG4gICAgcmV0dXJuIHRlc3QudGltZW91dCB8fCAyMDAwIC8vIG1zIC0gZGVmYXVsdCB0aW1lb3V0XG59XG5cbi8vIE5vdGUgdGhhdCBhIHNsb3duZXNzIHRocmVzaG9sZCBvZiAwIG1lYW5zIHRvIGluaGVyaXQgdGhlIHBhcmVudC5cbmV4cG9ydHMuZ2V0U2xvdyA9IGZ1bmN0aW9uICh0ZXN0KSB7XG4gICAgd2hpbGUgKCF0ZXN0LnNsb3cgJiYgdGVzdC5wYXJlbnQgIT0gbnVsbCkge1xuICAgICAgICB0ZXN0ID0gdGVzdC5wYXJlbnRcbiAgICB9XG5cbiAgICByZXR1cm4gdGVzdC5zbG93IHx8IDc1IC8vIG1zIC0gZGVmYXVsdCBzbG93IHRocmVzaG9sZFxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIG1ldGhvZHMgPSByZXF1aXJlKFwiLi4vbWV0aG9kc1wiKVxudmFyIFRlc3RzID0gcmVxdWlyZShcIi4uL2NvcmUvdGVzdHNcIilcbnZhciBDb21tb24gPSByZXF1aXJlKFwiLi9jb21tb25cIilcblxuLyoqXG4gKiBUaGlzIGNvbnRhaW5zIHRoZSBsb3cgbGV2ZWwsIG1vcmUgYXJjYW5lIHRoaW5ncyB0aGF0IGFyZSBnZW5lcmFsbHkgbm90XG4gKiBpbnRlcmVzdGluZyB0byBhbnlvbmUgb3RoZXIgdGhhbiBwbHVnaW4gZGV2ZWxvcGVycy5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBSZWZsZWN0XG5mdW5jdGlvbiBSZWZsZWN0KHRlc3QpIHtcbiAgICB2YXIgcmVmbGVjdCA9IHRlc3QucmVmbGVjdFxuXG4gICAgaWYgKHJlZmxlY3QgIT0gbnVsbCkgcmV0dXJuIHJlZmxlY3RcbiAgICBpZiAodGVzdC5yb290ICE9PSB0ZXN0KSByZXR1cm4gdGVzdC5yZWZsZWN0ID0gbmV3IFJlZmxlY3RDaGlsZCh0ZXN0KVxuICAgIHJldHVybiB0ZXN0LnJlZmxlY3QgPSBuZXcgUmVmbGVjdFJvb3QodGVzdClcbn1cblxubWV0aG9kcyhSZWZsZWN0LCB7XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50bHkgZXhlY3V0aW5nIHRlc3QuXG4gICAgICovXG4gICAgZ2V0IGN1cnJlbnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVmbGVjdCh0aGlzLl8ucm9vdC5jdXJyZW50KVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHJvb3QgdGVzdC5cbiAgICAgKi9cbiAgICBnZXQgcm9vdCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZWZsZWN0KHRoaXMuXy5yb290KVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgdG90YWwgdGVzdCBjb3VudC5cbiAgICAgKi9cbiAgICBnZXQgY291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8udGVzdHMgPT0gbnVsbCA/IDAgOiB0aGlzLl8udGVzdHMubGVuZ3RoXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgdGVzdCBsaXN0LCBhcyBhIFJlZmxlY3QgY29sbGVjdGlvbi4gVGhpcyBpc1xuICAgICAqIGludGVudGlvbmFsbHkgYSBzbGljZSwgc28geW91IGNhbid0IG11dGF0ZSB0aGUgcmVhbCBjaGlsZHJlbi5cbiAgICAgKi9cbiAgICBnZXQgY2hpbGRyZW4oKSB7XG4gICAgICAgIGlmICh0aGlzLl8udGVzdHMgPT0gbnVsbCkgcmV0dXJuIFtdXG4gICAgICAgIHJldHVybiB0aGlzLl8udGVzdHMubWFwKGZ1bmN0aW9uICh0ZXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlZmxlY3RDaGlsZCh0ZXN0KVxuICAgICAgICB9KVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBJcyB0aGlzIHRlc3QgdGhlIHJvb3QsIGkuZS4gdG9wIGxldmVsP1xuICAgICAqL1xuICAgIGdldCBpc1Jvb3QoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8ucGFyZW50ID09IG51bGxcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogSXMgdGhpcyBsb2NrZWQgKGkuZS4gdW5zYWZlIHRvIG1vZGlmeSk/XG4gICAgICovXG4gICAgZ2V0IGlzTG9ja2VkKCkge1xuICAgICAgICByZXR1cm4gISF0aGlzLl8ubG9ja2VkXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgb3duLCBub3QgbmVjZXNzYXJpbHkgYWN0aXZlLCB0aW1lb3V0LiAwIG1lYW5zIGluaGVyaXQgdGhlXG4gICAgICogcGFyZW50J3MsIGFuZCBgSW5maW5pdHlgIG1lYW5zIGl0J3MgZGlzYWJsZWQuXG4gICAgICovXG4gICAgZ2V0IG93blRpbWVvdXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8udGltZW91dCB8fCAwXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgYWN0aXZlIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLCBub3QgbmVjZXNzYXJpbHkgb3duLCBvciB0aGVcbiAgICAgKiBmcmFtZXdvcmsgZGVmYXVsdCBvZiAyMDAwLCBpZiBub25lIHdhcyBzZXQuXG4gICAgICovXG4gICAgZ2V0IHRpbWVvdXQoKSB7XG4gICAgICAgIHJldHVybiBDb21tb24uZ2V0VGltZW91dCh0aGlzLl8pXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgb3duLCBub3QgbmVjZXNzYXJpbHkgYWN0aXZlLCBzbG93IHRocmVzaG9sZC4gMCBtZWFucyBpbmhlcml0IHRoZVxuICAgICAqIHBhcmVudCdzLCBhbmQgYEluZmluaXR5YCBtZWFucyBpdCdzIGRpc2FibGVkLlxuICAgICAqL1xuICAgIGdldCBvd25TbG93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnNsb3cgfHwgMFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGFjdGl2ZSBzbG93IHRocmVzaG9sZCBpbiBtaWxsaXNlY29uZHMsIG5vdCBuZWNlc3NhcmlseSBvd24sIG9yXG4gICAgICogdGhlIGZyYW1ld29yayBkZWZhdWx0IG9mIDc1LCBpZiBub25lIHdhcyBzZXQuXG4gICAgICovXG4gICAgZ2V0IHNsb3coKSB7XG4gICAgICAgIHJldHVybiBDb21tb24uZ2V0U2xvdyh0aGlzLl8pXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGVzdCdzIG93biBtYXggYXR0ZW1wdCBjb3VudC4gTm90ZSB0aGF0IHRoaXMgaXMgcGFyYXNpdGljYWxseVxuICAgICAqIGluaGVyaXRlZCBmcm9tIGl0cyBwYXJlbnQsIG5vdCBkZWxlZ2F0ZWQuXG4gICAgICovXG4gICAgZ2V0IGF0dGVtcHRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLmF0dGVtcHRzXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB3aGV0aGVyIHRoaXMgdGVzdCBpcyBmYWlsYWJsZS4gTm90ZSB0aGF0IHRoaXMgaXMgcGFyYXNpdGljYWxseVxuICAgICAqIGluaGVyaXRlZCBmcm9tIGl0cyBwYXJlbnQsIG5vdCBkZWxlZ2F0ZWQuXG4gICAgICovXG4gICAgZ2V0IGlzRmFpbGFibGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8uaXNGYWlsYWJsZVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBob29rIHRvIGJlIHJ1biBiZWZvcmUgZWFjaCBzdWJ0ZXN0LCBpbmNsdWRpbmcgdGhlaXIgc3VidGVzdHMgYW5kIHNvXG4gICAgICogb24uXG4gICAgICovXG4gICAgYmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5iZWZvcmVFYWNoID0gQ29tbW9uLmFkZEhvb2sodGhpcy5fLmJlZm9yZUVhY2gsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBob29rIHRvIGJlIHJ1biBvbmNlIGJlZm9yZSBhbGwgc3VidGVzdHMgYXJlIHJ1bi5cbiAgICAgKi9cbiAgICBiZWZvcmVBbGw6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fLmJlZm9yZUFsbCA9IENvbW1vbi5hZGRIb29rKHRoaXMuXy5iZWZvcmVBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgIC8qKlxuICAgICogQWRkIGEgaG9vayB0byBiZSBydW4gYWZ0ZXIgZWFjaCBzdWJ0ZXN0LCBpbmNsdWRpbmcgdGhlaXIgc3VidGVzdHMgYW5kIHNvXG4gICAgKiBvbi5cbiAgICAqL1xuICAgIGFmdGVyOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5hZnRlckVhY2ggPSBDb21tb24uYWRkSG9vayh0aGlzLl8uYWZ0ZXJFYWNoLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgaG9vayB0byBiZSBydW4gb25jZSBhZnRlciBhbGwgc3VidGVzdHMgYXJlIHJ1bi5cbiAgICAgKi9cbiAgICBhZnRlckFsbDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl8uYWZ0ZXJBbGwgPSBDb21tb24uYWRkSG9vayh0aGlzLl8uYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5iZWZvcmVgIG9yIGByZWZsZWN0LmJlZm9yZWAuXG4gICAgICovXG4gICAgaGFzQmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBDb21tb24uaGFzSG9vayh0aGlzLl8uYmVmb3JlRWFjaCwgY2FsbGJhY2spXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhIGhvb2sgcHJldmlvdXNseSBhZGRlZCB3aXRoIGB0LmJlZm9yZUFsbGAgb3IgYHJlZmxlY3QuYmVmb3JlQWxsYC5cbiAgICAgKi9cbiAgICBoYXNCZWZvcmVBbGw6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIENvbW1vbi5oYXNIb29rKHRoaXMuXy5iZWZvcmVBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5hZnRlcmAgb3JgcmVmbGVjdC5hZnRlcmAuXG4gICAgICovXG4gICAgaGFzQWZ0ZXI6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIENvbW1vbi5oYXNIb29rKHRoaXMuXy5hZnRlckVhY2gsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5hZnRlckFsbGAgb3IgYHJlZmxlY3QuYWZ0ZXJBbGxgLlxuICAgICAqL1xuICAgIGhhc0FmdGVyQWxsOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBDb21tb24uaGFzSG9vayh0aGlzLl8uYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5iZWZvcmVgIG9yIGByZWZsZWN0LmJlZm9yZWAuXG4gICAgICovXG4gICAgcmVtb3ZlQmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5iZWZvcmVFYWNoID0gQ29tbW9uLnJlbW92ZUhvb2sodGhpcy5fLmJlZm9yZUVhY2gsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5iZWZvcmVBbGxgIG9yIGByZWZsZWN0LmJlZm9yZUFsbGAuXG4gICAgICovXG4gICAgcmVtb3ZlQmVmb3JlQWxsOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5iZWZvcmVBbGwgPSBDb21tb24ucmVtb3ZlSG9vayh0aGlzLl8uYmVmb3JlQWxsLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgaG9vayBwcmV2aW91c2x5IGFkZGVkIHdpdGggYHQuYWZ0ZXJgIG9yYHJlZmxlY3QuYWZ0ZXJgLlxuICAgICAqL1xuICAgIHJlbW92ZUFmdGVyOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5hZnRlckVhY2ggPSBDb21tb24ucmVtb3ZlSG9vayh0aGlzLl8uYWZ0ZXJFYWNoLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgaG9vayBwcmV2aW91c2x5IGFkZGVkIHdpdGggYHQuYWZ0ZXJBbGxgIG9yIGByZWZsZWN0LmFmdGVyQWxsYC5cbiAgICAgKi9cbiAgICByZW1vdmVBZnRlckFsbDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl8uYWZ0ZXJBbGwgPSBDb21tb24ucmVtb3ZlSG9vayh0aGlzLl8uYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBibG9jayBvciBpbmxpbmUgdGVzdC5cbiAgICAgKi9cbiAgICB0ZXN0OiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYG5hbWVgIHRvIGJlIGEgc3RyaW5nXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgVGVzdHMuYWRkTm9ybWFsKHRoaXMuXy5yb290LmN1cnJlbnQsIG5hbWUsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBza2lwcGVkIGJsb2NrIG9yIGlubGluZSB0ZXN0LlxuICAgICAqL1xuICAgIHRlc3RTa2lwOiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYG5hbWVgIHRvIGJlIGEgc3RyaW5nXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgVGVzdHMuYWRkU2tpcHBlZCh0aGlzLl8ucm9vdC5jdXJyZW50LCBuYW1lKVxuICAgIH0sXG59KVxuXG5mdW5jdGlvbiBSZWZsZWN0Um9vdChyb290KSB7XG4gICAgdGhpcy5fID0gcm9vdFxufVxuXG5tZXRob2RzKFJlZmxlY3RSb290LCBSZWZsZWN0LCB7XG4gICAgLyoqXG4gICAgICogV2hldGhlciBhIHJlcG9ydGVyIHdhcyByZWdpc3RlcmVkLlxuICAgICAqL1xuICAgIGhhc1JlcG9ydGVyOiBmdW5jdGlvbiAocmVwb3J0ZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXBvcnRlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHJlcG9ydGVyYCB0byBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QucmVwb3J0ZXJJZHMuaW5kZXhPZihyZXBvcnRlcikgPj0gMFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSByZXBvcnRlci5cbiAgICAgKi9cbiAgICByZXBvcnRlcjogZnVuY3Rpb24gKHJlcG9ydGVyLCBhcmcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXBvcnRlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHJlcG9ydGVyYCB0byBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcm9vdCA9IHRoaXMuXy5yb290XG5cbiAgICAgICAgaWYgKHJvb3QuY3VycmVudCAhPT0gcm9vdCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmVwb3J0ZXJzIG1heSBvbmx5IGJlIGFkZGVkIHRvIHRoZSByb290XCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAocm9vdC5yZXBvcnRlcklkcy5pbmRleE9mKHJlcG9ydGVyKSA8IDApIHtcbiAgICAgICAgICAgIHJvb3QucmVwb3J0ZXJJZHMucHVzaChyZXBvcnRlcilcbiAgICAgICAgICAgIHJvb3QucmVwb3J0ZXJzLnB1c2gocmVwb3J0ZXIoYXJnKSlcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSByZXBvcnRlci5cbiAgICAgKi9cbiAgICByZW1vdmVSZXBvcnRlcjogZnVuY3Rpb24gKHJlcG9ydGVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVwb3J0ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGByZXBvcnRlcmAgdG8gYmUgYSBmdW5jdGlvblwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJvb3QgPSB0aGlzLl8ucm9vdFxuXG4gICAgICAgIGlmIChyb290LmN1cnJlbnQgIT09IHJvb3QpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlcG9ydGVycyBtYXkgb25seSBiZSBhZGRlZCB0byB0aGUgcm9vdFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGluZGV4ID0gcm9vdC5yZXBvcnRlcklkcy5pbmRleE9mKHJlcG9ydGVyKVxuXG4gICAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgICByb290LnJlcG9ydGVySWRzLnNwbGljZShpbmRleCwgMSlcbiAgICAgICAgICAgIHJvb3QucmVwb3J0ZXJzLnNwbGljZShpbmRleCwgMSlcbiAgICAgICAgfVxuICAgIH0sXG59KVxuXG5mdW5jdGlvbiBSZWZsZWN0Q2hpbGQocm9vdCkge1xuICAgIHRoaXMuXyA9IHJvb3Rcbn1cblxubWV0aG9kcyhSZWZsZWN0Q2hpbGQsIFJlZmxlY3QsIHtcbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRlc3QgbmFtZSwgb3IgYHVuZGVmaW5lZGAgaWYgaXQncyB0aGUgcm9vdCB0ZXN0LlxuICAgICAqL1xuICAgIGdldCBuYW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLm5hbWVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0ZXN0IGluZGV4LCBvciBgLTFgIGlmIGl0J3MgdGhlIHJvb3QgdGVzdC5cbiAgICAgKi9cbiAgICBnZXQgaW5kZXgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8uaW5kZXhcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBwYXJlbnQgdGVzdCBhcyBhIFJlZmxlY3QuXG4gICAgICovXG4gICAgZ2V0IHBhcmVudCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZWZsZWN0KHRoaXMuXy5wYXJlbnQpXG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgbWV0aG9kcyA9IHJlcXVpcmUoXCIuLi9tZXRob2RzXCIpXG52YXIgVGVzdHMgPSByZXF1aXJlKFwiLi4vY29yZS90ZXN0c1wiKVxudmFyIEZpbHRlciA9IHJlcXVpcmUoXCIuLi9jb3JlL2ZpbHRlclwiKVxudmFyIENvbW1vbiA9IHJlcXVpcmUoXCIuL2NvbW1vblwiKVxudmFyIFJlZmxlY3QgPSByZXF1aXJlKFwiLi9yZWZsZWN0XCIpXG5cbm1vZHVsZS5leHBvcnRzID0gVGhhbGxpdW1cbmZ1bmN0aW9uIFRoYWxsaXVtKCkge1xuICAgIHRoaXMuXyA9IFRlc3RzLmNyZWF0ZVJvb3QodGhpcylcbn1cblxubWV0aG9kcyhUaGFsbGl1bSwge1xuICAgIC8qKlxuICAgICAqIENhbGwgYSBwbHVnaW4gYW5kIHJldHVybiB0aGUgcmVzdWx0LiBUaGUgcGx1Z2luIGlzIGNhbGxlZCB3aXRoIGEgUmVmbGVjdFxuICAgICAqIGluc3RhbmNlIGZvciBhY2Nlc3MgdG8gcGxlbnR5IG9mIHBvdGVudGlhbGx5IHVzZWZ1bCBpbnRlcm5hbCBkZXRhaWxzLlxuICAgICAqL1xuICAgIGNhbGw6IGZ1bmN0aW9uIChwbHVnaW4sIGFyZykge1xuICAgICAgICB2YXIgcmVmbGVjdCA9IG5ldyBSZWZsZWN0KHRoaXMuXy5yb290LmN1cnJlbnQpXG5cbiAgICAgICAgcmV0dXJuIHBsdWdpbi5jYWxsKHJlZmxlY3QsIHJlZmxlY3QsIGFyZylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogV2hpdGVsaXN0IHNwZWNpZmljIHRlc3RzLCB1c2luZyBhcnJheS1iYXNlZCBzZWxlY3RvcnMgd2hlcmUgZWFjaCBlbnRyeVxuICAgICAqIGlzIGVpdGhlciBhIHN0cmluZyBvciByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICovXG4gICAgb25seTogZnVuY3Rpb24gKC8qIC4uLnNlbGVjdG9ycyAqLykge1xuICAgICAgICB0aGlzLl8ucm9vdC5jdXJyZW50Lm9ubHkgPSBGaWx0ZXIuY3JlYXRlLmFwcGx5KHVuZGVmaW5lZCwgYXJndW1lbnRzKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSByZXBvcnRlci5cbiAgICAgKi9cbiAgICByZXBvcnRlcjogZnVuY3Rpb24gKHJlcG9ydGVyLCBhcmcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXBvcnRlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHJlcG9ydGVyYCB0byBiZSBhIGZ1bmN0aW9uLlwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJvb3QgPSB0aGlzLl8ucm9vdFxuXG4gICAgICAgIGlmIChyb290LmN1cnJlbnQgIT09IHJvb3QpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlcG9ydGVycyBtYXkgb25seSBiZSBhZGRlZCB0byB0aGUgcm9vdC5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXN1bHQgPSByZXBvcnRlcihhcmcpXG5cbiAgICAgICAgLy8gRG9uJ3QgYXNzdW1lIGl0J3MgYSBmdW5jdGlvbi4gVmVyaWZ5IGl0IGFjdHVhbGx5IGlzLCBzbyB3ZSBkb24ndCBoYXZlXG4gICAgICAgIC8vIGluZXhwbGljYWJsZSB0eXBlIGVycm9ycyBpbnRlcm5hbGx5IGFmdGVyIGl0J3MgaW52b2tlZCwgYW5kIHNvIHVzZXJzXG4gICAgICAgIC8vIHdvbid0IGdldCB0b28gY29uZnVzZWQuXG4gICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJFeHBlY3RlZCBgcmVwb3J0ZXJgIHRvIHJldHVybiBhIGZ1bmN0aW9uLiBDaGVjayB3aXRoIHRoZSBcIiArXG4gICAgICAgICAgICAgICAgXCJyZXBvcnRlcidzIGF1dGhvciwgYW5kIGhhdmUgdGhlbSBmaXggdGhlaXIgcmVwb3J0ZXIuXCIpXG4gICAgICAgIH1cblxuICAgICAgICByb290LnJlcG9ydGVyID0gcmVzdWx0XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIHRoaXMgaGFzIGEgcmVwb3J0ZXIuXG4gICAgICovXG4gICAgZ2V0IGhhc1JlcG9ydGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QucmVwb3J0ZXIgIT0gbnVsbFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgdGltZW91dC4gMCBtZWFucyBpbmhlcml0IHRoZSBwYXJlbnQncywgYW5kIGBJbmZpbml0eWBcbiAgICAgKiBtZWFucyBpdCdzIGRpc2FibGVkLlxuICAgICAqL1xuICAgIGdldCB0aW1lb3V0KCkge1xuICAgICAgICByZXR1cm4gQ29tbW9uLmdldFRpbWVvdXQodGhpcy5fLnJvb3QuY3VycmVudClcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcywgcm91bmRpbmcgbmVnYXRpdmVzIHRvIDAuIFNldHRpbmcgdGhlXG4gICAgICogdGltZW91dCB0byAwIG1lYW5zIHRvIGluaGVyaXQgdGhlIHBhcmVudCB0aW1lb3V0LCBhbmQgc2V0dGluZyBpdCB0b1xuICAgICAqIGBJbmZpbml0eWAgZGlzYWJsZXMgaXQuXG4gICAgICovXG4gICAgc2V0IHRpbWVvdXQodGltZW91dCkge1xuICAgICAgICB0aGlzLl8ucm9vdC5jdXJyZW50LnRpbWVvdXQgPSBNYXRoLmZsb29yKE1hdGgubWF4KCt0aW1lb3V0LCAwKSlcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IHNsb3cgdGhyZXNob2xkLiAwIG1lYW5zIGluaGVyaXQgdGhlIHBhcmVudCdzLCBhbmRcbiAgICAgKiBgSW5maW5pdHlgIG1lYW5zIGl0J3MgZGlzYWJsZWQuXG4gICAgICovXG4gICAgZ2V0IHNsb3coKSB7XG4gICAgICAgIHJldHVybiBDb21tb24uZ2V0U2xvdyh0aGlzLl8ucm9vdC5jdXJyZW50KVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHNsb3cgdGhyZXNob2xkIGluIG1pbGxpc2Vjb25kcywgcm91bmRpbmcgbmVnYXRpdmVzIHRvIDAuIFNldHRpbmdcbiAgICAgKiB0aGUgdGltZW91dCB0byAwIG1lYW5zIHRvIGluaGVyaXQgdGhlIHBhcmVudCB0aHJlc2hvbGQsIGFuZCBzZXR0aW5nIGl0IHRvXG4gICAgICogYEluZmluaXR5YCBkaXNhYmxlcyBpdC5cbiAgICAgKi9cbiAgICBzZXQgc2xvdyhzbG93KSB7XG4gICAgICAgIHRoaXMuXy5yb290LmN1cnJlbnQuc2xvdyA9IE1hdGguZmxvb3IoTWF0aC5tYXgoK3Nsb3csIDApKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgYXR0ZW1wdCBjb3VudC4gYDBgIG1lYW5zIGluaGVyaXQgdGhlIHBhcmVudCdzLlxuICAgICAqL1xuICAgIGdldCBhdHRlbXB0cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuXy5yb290LmN1cnJlbnQuYXR0ZW1wdHNcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBudW1iZXIgb2YgYXR0ZW1wdHMgYWxsb3dlZCwgcm91bmRpbmcgbmVnYXRpdmVzIHRvIDAuIFNldHRpbmcgdGhlXG4gICAgICogY291bnQgdG8gYDBgIG1lYW5zIHRvIGluaGVyaXQgdGhlIHBhcmVudCByZXRyeSBjb3VudC5cbiAgICAgKi9cbiAgICBzZXQgYXR0ZW1wdHMoYXR0ZW1wdHMpIHtcbiAgICAgICAgLy8gVGhpcyBpcyBkb25lIGRpZmZlcmVudGx5IHRvIGF2b2lkIGEgbWFzc2l2ZSBwZXJmb3JtYW5jZSBwZW5hbHR5LlxuICAgICAgICB2YXIgY2FsY3VsYXRlZCA9IE1hdGguZmxvb3IoTWF0aC5tYXgoYXR0ZW1wdHMsIDApKVxuICAgICAgICB2YXIgdGVzdCA9IHRoaXMuXy5yb290LmN1cnJlbnRcblxuICAgICAgICB0ZXN0LmF0dGVtcHRzID0gY2FsY3VsYXRlZCB8fCB0ZXN0LnBhcmVudC5hdHRlbXB0c1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgd2hldGhlciB0aGlzIHRlc3QgaXMgZmFpbGFibGUuXG4gICAgICovXG4gICAgZ2V0IGlzRmFpbGFibGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8ucm9vdC5jdXJyZW50LmlzRmFpbGFibGVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHdoZXRoZXIgdGhpcyB0ZXN0IGlzIGZhaWxhYmxlLlxuICAgICAqL1xuICAgIHNldCBpc0ZhaWxhYmxlKGlzRmFpbGFibGUpIHtcbiAgICAgICAgdGhpcy5fLnJvb3QuY3VycmVudC5pc0ZhaWxhYmxlID0gISFpc0ZhaWxhYmxlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFJ1biB0aGUgdGVzdHMgKG9yIHRoZSB0ZXN0J3MgdGVzdHMgaWYgaXQncyBub3QgYSBiYXNlIGluc3RhbmNlKS5cbiAgICAgKi9cbiAgICBydW46IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgICAgIGlmICh0aGlzLl8ucm9vdCAhPT0gdGhpcy5fKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJPbmx5IHRoZSByb290IHRlc3QgY2FuIGJlIHJ1biAtIElmIHlvdSBvbmx5IHdhbnQgdG8gcnVuIGEgXCIgK1xuICAgICAgICAgICAgICAgIFwic3VidGVzdCwgdXNlIGB0Lm9ubHkoW1xcXCJzZWxlY3RvcjFcXFwiLCAuLi5dKWAgaW5zdGVhZC5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl8ubG9ja2VkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCBydW4gd2hpbGUgdGVzdHMgYXJlIGFscmVhZHkgcnVubmluZy5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBUZXN0cy5ydW5UZXN0KHRoaXMuXywgb3B0cylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgdGVzdC5cbiAgICAgKi9cbiAgICB0ZXN0OiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYG5hbWVgIHRvIGJlIGEgc3RyaW5nXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgVGVzdHMuYWRkTm9ybWFsKHRoaXMuXy5yb290LmN1cnJlbnQsIG5hbWUsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBza2lwcGVkIHRlc3QuXG4gICAgICovXG4gICAgdGVzdFNraXA6IGZ1bmN0aW9uIChuYW1lLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBgbmFtZWAgdG8gYmUgYSBzdHJpbmdcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICBUZXN0cy5hZGRTa2lwcGVkKHRoaXMuXy5yb290LmN1cnJlbnQsIG5hbWUpXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENsZWFyIGFsbCBleGlzdGluZyB0ZXN0cy5cbiAgICAgKi9cbiAgICBjbGVhclRlc3RzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLl8ucm9vdCAhPT0gdGhpcy5fKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUZXN0cyBtYXkgb25seSBiZSBjbGVhcmVkIGF0IHRoZSByb290LlwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuXy5sb2NrZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IGNsZWFyIHRlc3RzIHdoaWxlIHRoZXkgYXJlIHJ1bm5pbmcuXCIpXG4gICAgICAgIH1cblxuICAgICAgICBUZXN0cy5jbGVhclRlc3RzKHRoaXMuXylcbiAgICB9LFxuXG4gICAgYmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0ZXN0ID0gdGhpcy5fLnJvb3QuY3VycmVudFxuXG4gICAgICAgIHRlc3QuYmVmb3JlRWFjaCA9IENvbW1vbi5hZGRIb29rKHRlc3QuYmVmb3JlRWFjaCwgY2FsbGJhY2spXG4gICAgfSxcblxuICAgIGJlZm9yZUFsbDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdGVzdCA9IHRoaXMuXy5yb290LmN1cnJlbnRcblxuICAgICAgICB0ZXN0LmJlZm9yZUFsbCA9IENvbW1vbi5hZGRIb29rKHRlc3QuYmVmb3JlQWxsLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgYWZ0ZXI6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHRlc3QgPSB0aGlzLl8ucm9vdC5jdXJyZW50XG5cbiAgICAgICAgdGVzdC5hZnRlckVhY2ggPSBDb21tb24uYWRkSG9vayh0ZXN0LmFmdGVyRWFjaCwgY2FsbGJhY2spXG4gICAgfSxcblxuICAgIGFmdGVyQWxsOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0ZXN0ID0gdGhpcy5fLnJvb3QuY3VycmVudFxuXG4gICAgICAgIHRlc3QuYWZ0ZXJBbGwgPSBDb21tb24uYWRkSG9vayh0ZXN0LmFmdGVyQWxsLCBjYWxsYmFjaylcbiAgICB9LFxufSlcbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogVGhlIGZpbHRlciBpcyBhY3R1YWxseSBzdG9yZWQgYXMgYSB0cmVlIGZvciBmYXN0ZXIgbG9va3VwIHRpbWVzIHdoZW4gdGhlcmVcbiAqIGFyZSBtdWx0aXBsZSBzZWxlY3RvcnMuIE9iamVjdHMgY2FuJ3QgYmUgdXNlZCBmb3IgdGhlIG5vZGVzLCB3aGVyZSBrZXlzXG4gKiByZXByZXNlbnQgdmFsdWVzIGFuZCB2YWx1ZXMgcmVwcmVzZW50IGNoaWxkcmVuLCBiZWNhdXNlIHJlZ3VsYXIgZXhwcmVzc2lvbnNcbiAqIGFyZW4ndCBwb3NzaWJsZSB0byB1c2UuXG4gKi9cblxuZnVuY3Rpb24gaXNFcXVpdmFsZW50KGVudHJ5LCBpdGVtKSB7XG4gICAgaWYgKHR5cGVvZiBlbnRyeSA9PT0gXCJzdHJpbmdcIiAmJiB0eXBlb2YgaXRlbSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICByZXR1cm4gZW50cnkgPT09IGl0ZW1cbiAgICB9IGVsc2UgaWYgKGVudHJ5IGluc3RhbmNlb2YgUmVnRXhwICYmIGl0ZW0gaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgcmV0dXJuIGVudHJ5LnRvU3RyaW5nKCkgPT09IGl0ZW0udG9TdHJpbmcoKVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbn1cblxuZnVuY3Rpb24gbWF0Y2hlcyhlbnRyeSwgaXRlbSkge1xuICAgIGlmICh0eXBlb2YgZW50cnkgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIGVudHJ5ID09PSBpdGVtXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGVudHJ5LnRlc3QoaXRlbSlcbiAgICB9XG59XG5cbmZ1bmN0aW9uIEZpbHRlcih2YWx1ZSkge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZVxuICAgIHRoaXMuY2hpbGRyZW4gPSB1bmRlZmluZWRcbn1cblxuZnVuY3Rpb24gZmluZEVxdWl2YWxlbnQobm9kZSwgZW50cnkpIHtcbiAgICBpZiAobm9kZS5jaGlsZHJlbiA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGUuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkID0gbm9kZS5jaGlsZHJlbltpXVxuXG4gICAgICAgIGlmIChpc0VxdWl2YWxlbnQoY2hpbGQudmFsdWUsIGVudHJ5KSkgcmV0dXJuIGNoaWxkXG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBmaW5kTWF0Y2hlcyhub2RlLCBlbnRyeSkge1xuICAgIGlmIChub2RlLmNoaWxkcmVuID09IG51bGwpIHJldHVybiB1bmRlZmluZWRcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY2hpbGQgPSBub2RlLmNoaWxkcmVuW2ldXG5cbiAgICAgICAgaWYgKG1hdGNoZXMoY2hpbGQudmFsdWUsIGVudHJ5KSkgcmV0dXJuIGNoaWxkXG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIENyZWF0ZSBhIGZpbHRlciBmcm9tIGEgbnVtYmVyIG9mIHNlbGVjdG9yc1xuICovXG5leHBvcnRzLmNyZWF0ZSA9IGZ1bmN0aW9uICgvKiAuLi5zZWxlY3RvcnMgKi8pIHtcbiAgICB2YXIgZmlsdGVyID0gbmV3IEZpbHRlcigpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgc2VsZWN0b3IgPSBhcmd1bWVudHNbaV1cblxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2VsZWN0b3IpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgICAgIFwiRXhwZWN0ZWQgc2VsZWN0b3IgXCIgKyBpICsgXCIgdG8gYmUgYW4gYXJyYXlcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGZpbHRlckFkZFNpbmdsZShmaWx0ZXIsIHNlbGVjdG9yLCBpKVxuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXJcbn1cblxuZnVuY3Rpb24gZmlsdGVyQWRkU2luZ2xlKG5vZGUsIHNlbGVjdG9yLCBpbmRleCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsZWN0b3IubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gc2VsZWN0b3JbaV1cblxuICAgICAgICAvLyBTdHJpbmdzIGFuZCByZWd1bGFyIGV4cHJlc3Npb25zIGFyZSB0aGUgb25seSB0aGluZ3MgYWxsb3dlZC5cbiAgICAgICAgaWYgKHR5cGVvZiBlbnRyeSAhPT0gXCJzdHJpbmdcIiAmJiAhKGVudHJ5IGluc3RhbmNlb2YgUmVnRXhwKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgICAgICBcIlNlbGVjdG9yIFwiICsgaW5kZXggKyBcIiBtdXN0IGNvbnNpc3Qgb2Ygb25seSBzdHJpbmdzIGFuZC9vciBcIiArXG4gICAgICAgICAgICAgICAgXCJyZWd1bGFyIGV4cHJlc3Npb25zXCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY2hpbGQgPSBmaW5kRXF1aXZhbGVudChub2RlLCBlbnRyeSlcblxuICAgICAgICBpZiAoY2hpbGQgPT0gbnVsbCkge1xuICAgICAgICAgICAgY2hpbGQgPSBuZXcgRmlsdGVyKGVudHJ5KVxuICAgICAgICAgICAgaWYgKG5vZGUuY2hpbGRyZW4gPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4gPSBbY2hpbGRdXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4ucHVzaChjaGlsZClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIG5vZGUgPSBjaGlsZFxuICAgIH1cbn1cblxuZXhwb3J0cy50ZXN0ID0gZnVuY3Rpb24gKGZpbHRlciwgcGF0aCkge1xuICAgIHZhciBsZW5ndGggPSBwYXRoLmxlbmd0aFxuXG4gICAgd2hpbGUgKGxlbmd0aCAhPT0gMCkge1xuICAgICAgICBmaWx0ZXIgPSBmaW5kTWF0Y2hlcyhmaWx0ZXIsIHBhdGhbLS1sZW5ndGhdKVxuICAgICAgICBpZiAoZmlsdGVyID09IG51bGwpIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgbWV0aG9kcyA9IHJlcXVpcmUoXCIuLi9tZXRob2RzXCIpXG5cbi8qKlxuICogQWxsIHRoZSByZXBvcnQgdHlwZXMuIFRoZSBvbmx5IHJlYXNvbiB0aGVyZSBhcmUgbW9yZSB0aGFuIHR3byB0eXBlcyAobm9ybWFsXG4gKiBhbmQgaG9vaykgaXMgZm9yIHRoZSB1c2VyJ3MgYmVuZWZpdCAoZGV2IHRvb2xzLCBgdXRpbC5pbnNwZWN0YCwgZXRjLilcbiAqL1xuXG52YXIgVHlwZXMgPSBleHBvcnRzLlR5cGVzID0gT2JqZWN0LmZyZWV6ZSh7XG4gICAgU3RhcnQ6IDAsXG4gICAgRW50ZXI6IDEsXG4gICAgTGVhdmU6IDIsXG4gICAgUGFzczogMyxcbiAgICBGYWlsOiA0LFxuICAgIFNraXA6IDUsXG4gICAgRW5kOiA2LFxuICAgIEVycm9yOiA3LFxuXG4gICAgLy8gTm90ZSB0aGF0IGBIb29rYCBpcyBkZW5vdGVkIGJ5IHRoZSA0dGggYml0IHNldCwgdG8gc2F2ZSBzb21lIHNwYWNlIChhbmRcbiAgICAvLyB0byBzaW1wbGlmeSB0aGUgdHlwZSByZXByZXNlbnRhdGlvbikuXG4gICAgSG9vazogOCxcbiAgICBCZWZvcmVBbGw6IDggfCAwLFxuICAgIEJlZm9yZUVhY2g6IDggfCAxLFxuICAgIEFmdGVyRWFjaDogOCB8IDIsXG4gICAgQWZ0ZXJBbGw6IDggfCAzLFxufSlcblxuZXhwb3J0cy5SZXBvcnQgPSBSZXBvcnRcbmZ1bmN0aW9uIFJlcG9ydCh0eXBlKSB7XG4gICAgdGhpcy5fID0gdHlwZVxufVxuXG4vLyBBdm9pZCBhIHJlY3Vyc2l2ZSBjYWxsIHdoZW4gYGluc3BlY3RgaW5nIGEgcmVzdWx0IHdoaWxlIHN0aWxsIGtlZXBpbmcgaXRcbi8vIHN0eWxlZCBsaWtlIGl0IHdvdWxkIGJlIG5vcm1hbGx5LiBFYWNoIHR5cGUgdXNlcyBhIG5hbWVkIHNpbmdsZXRvbiBmYWN0b3J5IHRvXG4vLyBlbnN1cmUgZW5naW5lcyBzaG93IHRoZSBjb3JyZWN0IGBuYW1lYC9gZGlzcGxheU5hbWVgIGZvciB0aGUgdHlwZS5cbmZ1bmN0aW9uIGluaXRJbnNwZWN0KGluc3BlY3QsIHJlcG9ydCkge1xuICAgIHZhciB0eXBlID0gcmVwb3J0Ll9cblxuICAgIGlmICh0eXBlICYgVHlwZXMuSG9vaykge1xuICAgICAgICBpbnNwZWN0LnN0YWdlID0gcmVwb3J0LnN0YWdlXG4gICAgfVxuXG4gICAgaWYgKHR5cGUgIT09IFR5cGVzLlN0YXJ0ICYmXG4gICAgICAgICAgICB0eXBlICE9PSBUeXBlcy5FbmQgJiZcbiAgICAgICAgICAgIHR5cGUgIT09IFR5cGVzLkVycm9yKSB7XG4gICAgICAgIGluc3BlY3QucGF0aCA9IHJlcG9ydC5wYXRoXG4gICAgfVxuXG4gICAgaWYgKHR5cGUgJiBUeXBlcy5Ib29rKSB7XG4gICAgICAgIGluc3BlY3Qucm9vdFBhdGggPSByZXBvcnQucm9vdFBhdGhcbiAgICB9XG5cbiAgICAvLyBPbmx5IGFkZCB0aGUgcmVsZXZhbnQgcHJvcGVydGllc1xuICAgIGlmICh0eXBlID09PSBUeXBlcy5GYWlsIHx8XG4gICAgICAgICAgICB0eXBlID09PSBUeXBlcy5FcnJvciB8fFxuICAgICAgICAgICAgdHlwZSAmIFR5cGVzLkhvb2spIHtcbiAgICAgICAgaW5zcGVjdC52YWx1ZSA9IHJlcG9ydC52YWx1ZVxuICAgIH1cblxuICAgIGlmICh0eXBlID09PSBUeXBlcy5FbnRlciB8fFxuICAgICAgICAgICAgdHlwZSA9PT0gVHlwZXMuUGFzcyB8fFxuICAgICAgICAgICAgdHlwZSA9PT0gVHlwZXMuRmFpbCkge1xuICAgICAgICBpbnNwZWN0LmR1cmF0aW9uID0gcmVwb3J0LmR1cmF0aW9uXG4gICAgICAgIGluc3BlY3Quc2xvdyA9IHJlcG9ydC5zbG93XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09IFR5cGVzLkZhaWwpIHtcbiAgICAgICAgaW5zcGVjdC5pc0ZhaWxhYmxlID0gcmVwb3J0LmlzRmFpbGFibGVcbiAgICB9XG59XG5cbm1ldGhvZHMoUmVwb3J0LCB7XG4gICAgLy8gVGhlIHJlcG9ydCB0eXBlc1xuICAgIGdldCBpc1N0YXJ0KCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5TdGFydCB9LFxuICAgIGdldCBpc0VudGVyKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5FbnRlciB9LFxuICAgIGdldCBpc0xlYXZlKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5MZWF2ZSB9LFxuICAgIGdldCBpc1Bhc3MoKSB7IHJldHVybiB0aGlzLl8gPT09IFR5cGVzLlBhc3MgfSxcbiAgICBnZXQgaXNGYWlsKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5GYWlsIH0sXG4gICAgZ2V0IGlzU2tpcCgpIHsgcmV0dXJuIHRoaXMuXyA9PT0gVHlwZXMuU2tpcCB9LFxuICAgIGdldCBpc0VuZCgpIHsgcmV0dXJuIHRoaXMuXyA9PT0gVHlwZXMuRW5kIH0sXG4gICAgZ2V0IGlzRXJyb3IoKSB7IHJldHVybiB0aGlzLl8gPT09IFR5cGVzLkVycm9yIH0sXG4gICAgZ2V0IGlzSG9vaygpIHsgcmV0dXJuICh0aGlzLl8gJiBUeXBlcy5Ib29rKSAhPT0gMCB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IGEgc3RyaW5naWZpZWQgZGVzY3JpcHRpb24gb2YgdGhlIHR5cGUuXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHN3aXRjaCAodGhpcy5fKSB7XG4gICAgICAgIGNhc2UgVHlwZXMuU3RhcnQ6IHJldHVybiBcInN0YXJ0XCJcbiAgICAgICAgY2FzZSBUeXBlcy5FbnRlcjogcmV0dXJuIFwiZW50ZXJcIlxuICAgICAgICBjYXNlIFR5cGVzLkxlYXZlOiByZXR1cm4gXCJsZWF2ZVwiXG4gICAgICAgIGNhc2UgVHlwZXMuUGFzczogcmV0dXJuIFwicGFzc1wiXG4gICAgICAgIGNhc2UgVHlwZXMuRmFpbDogcmV0dXJuIFwiZmFpbFwiXG4gICAgICAgIGNhc2UgVHlwZXMuU2tpcDogcmV0dXJuIFwic2tpcFwiXG4gICAgICAgIGNhc2UgVHlwZXMuRW5kOiByZXR1cm4gXCJlbmRcIlxuICAgICAgICBjYXNlIFR5cGVzLkVycm9yOiByZXR1cm4gXCJlcnJvclwiXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAodGhpcy5fICYgVHlwZXMuSG9vaykgcmV0dXJuIFwiaG9va1wiXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnJlYWNoYWJsZVwiKVxuICAgICAgICB9XG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuU3RhcnQgPSBTdGFydFJlcG9ydFxuZnVuY3Rpb24gU3RhcnRSZXBvcnQoKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuU3RhcnQpXG59XG5tZXRob2RzKFN0YXJ0UmVwb3J0LCBSZXBvcnQsIHtcbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gUmVwb3J0KHJlcG9ydCkge1xuICAgICAgICAgICAgaW5pdEluc3BlY3QodGhpcywgcmVwb3J0KVxuICAgICAgICB9KHRoaXMpXG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuRW50ZXIgPSBFbnRlclJlcG9ydFxuZnVuY3Rpb24gRW50ZXJSZXBvcnQocGF0aCwgZHVyYXRpb24sIHNsb3cpIHtcbiAgICBSZXBvcnQuY2FsbCh0aGlzLCBUeXBlcy5FbnRlcilcbiAgICB0aGlzLnBhdGggPSBwYXRoXG4gICAgdGhpcy5kdXJhdGlvbiA9IGR1cmF0aW9uXG4gICAgdGhpcy5zbG93ID0gc2xvd1xufVxubWV0aG9kcyhFbnRlclJlcG9ydCwgUmVwb3J0LCB7XG4gICAgLyoqXG4gICAgICogU28gdXRpbC5pbnNwZWN0IHByb3ZpZGVzIG1vcmUgc2Vuc2libGUgb3V0cHV0IGZvciB0ZXN0aW5nL2V0Yy5cbiAgICAgKi9cbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gRW50ZXJSZXBvcnQocmVwb3J0KSB7XG4gICAgICAgICAgICBpbml0SW5zcGVjdCh0aGlzLCByZXBvcnQpXG4gICAgICAgIH0odGhpcylcbiAgICB9LFxufSlcblxuZXhwb3J0cy5MZWF2ZSA9IExlYXZlUmVwb3J0XG5mdW5jdGlvbiBMZWF2ZVJlcG9ydChwYXRoKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuTGVhdmUpXG4gICAgdGhpcy5wYXRoID0gcGF0aFxufVxubWV0aG9kcyhMZWF2ZVJlcG9ydCwgUmVwb3J0LCB7XG4gICAgLyoqXG4gICAgICogU28gdXRpbC5pbnNwZWN0IHByb3ZpZGVzIG1vcmUgc2Vuc2libGUgb3V0cHV0IGZvciB0ZXN0aW5nL2V0Yy5cbiAgICAgKi9cbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gTGVhdmVSZXBvcnQocmVwb3J0KSB7XG4gICAgICAgICAgICBpbml0SW5zcGVjdCh0aGlzLCByZXBvcnQpXG4gICAgICAgIH0odGhpcylcbiAgICB9LFxufSlcblxuZXhwb3J0cy5QYXNzID0gUGFzc1JlcG9ydFxuZnVuY3Rpb24gUGFzc1JlcG9ydChwYXRoLCBkdXJhdGlvbiwgc2xvdykge1xuICAgIFJlcG9ydC5jYWxsKHRoaXMsIFR5cGVzLlBhc3MpXG4gICAgdGhpcy5wYXRoID0gcGF0aFxuICAgIHRoaXMuZHVyYXRpb24gPSBkdXJhdGlvblxuICAgIHRoaXMuc2xvdyA9IHNsb3dcbn1cbm1ldGhvZHMoUGFzc1JlcG9ydCwgUmVwb3J0LCB7XG4gICAgLyoqXG4gICAgICogU28gdXRpbC5pbnNwZWN0IHByb3ZpZGVzIG1vcmUgc2Vuc2libGUgb3V0cHV0IGZvciB0ZXN0aW5nL2V0Yy5cbiAgICAgKi9cbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gUGFzc1JlcG9ydChyZXBvcnQpIHtcbiAgICAgICAgICAgIGluaXRJbnNwZWN0KHRoaXMsIHJlcG9ydClcbiAgICAgICAgfSh0aGlzKVxuICAgIH0sXG59KVxuXG5leHBvcnRzLkZhaWwgPSBGYWlsUmVwb3J0XG5mdW5jdGlvbiBGYWlsUmVwb3J0KHBhdGgsIGVycm9yLCBkdXJhdGlvbiwgc2xvdywgaXNGYWlsYWJsZSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICBSZXBvcnQuY2FsbCh0aGlzLCBUeXBlcy5GYWlsKVxuICAgIHRoaXMucGF0aCA9IHBhdGhcbiAgICB0aGlzLmVycm9yID0gZXJyb3JcbiAgICB0aGlzLmR1cmF0aW9uID0gZHVyYXRpb25cbiAgICB0aGlzLnNsb3cgPSBzbG93XG4gICAgdGhpcy5pc0ZhaWxhYmxlID0gaXNGYWlsYWJsZVxufVxubWV0aG9kcyhGYWlsUmVwb3J0LCBSZXBvcnQsIHtcbiAgICAvKipcbiAgICAgKiBTbyB1dGlsLmluc3BlY3QgcHJvdmlkZXMgbW9yZSBzZW5zaWJsZSBvdXRwdXQgZm9yIHRlc3RpbmcvZXRjLlxuICAgICAqL1xuICAgIGluc3BlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBmdW5jdGlvbiBGYWlsUmVwb3J0KHJlcG9ydCkge1xuICAgICAgICAgICAgaW5pdEluc3BlY3QodGhpcywgcmVwb3J0KVxuICAgICAgICB9KHRoaXMpXG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuU2tpcCA9IFNraXBSZXBvcnRcbmZ1bmN0aW9uIFNraXBSZXBvcnQocGF0aCkge1xuICAgIFJlcG9ydC5jYWxsKHRoaXMsIFR5cGVzLlNraXApXG4gICAgdGhpcy5wYXRoID0gcGF0aFxufVxubWV0aG9kcyhTa2lwUmVwb3J0LCBSZXBvcnQsIHtcbiAgICAvKipcbiAgICAgKiBTbyB1dGlsLmluc3BlY3QgcHJvdmlkZXMgbW9yZSBzZW5zaWJsZSBvdXRwdXQgZm9yIHRlc3RpbmcvZXRjLlxuICAgICAqL1xuICAgIGluc3BlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBmdW5jdGlvbiBTa2lwUmVwb3J0KHJlcG9ydCkge1xuICAgICAgICAgICAgaW5pdEluc3BlY3QodGhpcywgcmVwb3J0KVxuICAgICAgICB9KHRoaXMpXG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuRW5kID0gRW5kUmVwb3J0XG5mdW5jdGlvbiBFbmRSZXBvcnQoKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuRW5kKVxufVxubWV0aG9kcyhFbmRSZXBvcnQsIFJlcG9ydCwge1xuICAgIC8qKlxuICAgICAqIFNvIHV0aWwuaW5zcGVjdCBwcm92aWRlcyBtb3JlIHNlbnNpYmxlIG91dHB1dCBmb3IgdGVzdGluZy9ldGMuXG4gICAgICovXG4gICAgaW5zcGVjdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IGZ1bmN0aW9uIEVuZFJlcG9ydChyZXBvcnQpIHtcbiAgICAgICAgICAgIGluaXRJbnNwZWN0KHRoaXMsIHJlcG9ydClcbiAgICAgICAgfSh0aGlzKVxuICAgIH0sXG59KVxuXG5leHBvcnRzLkVycm9yID0gRXJyb3JSZXBvcnRcbmZ1bmN0aW9uIEVycm9yUmVwb3J0KGVycm9yKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuRXJyb3IpXG4gICAgdGhpcy5lcnJvciA9IGVycm9yXG59XG5tZXRob2RzKEVycm9yUmVwb3J0LCBSZXBvcnQsIHtcbiAgICAvKipcbiAgICAgKiBTbyB1dGlsLmluc3BlY3QgcHJvdmlkZXMgbW9yZSBzZW5zaWJsZSBvdXRwdXQgZm9yIHRlc3RpbmcvZXRjLlxuICAgICAqL1xuICAgIGluc3BlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBmdW5jdGlvbiBFcnJvclJlcG9ydChyZXBvcnQpIHtcbiAgICAgICAgICAgIGluaXRJbnNwZWN0KHRoaXMsIHJlcG9ydClcbiAgICAgICAgfSh0aGlzKVxuICAgIH0sXG59KVxuXG52YXIgSG9va01ldGhvZHMgPSB7XG4gICAgZ2V0IHN0YWdlKCkge1xuICAgICAgICBzd2l0Y2ggKHRoaXMuXykge1xuICAgICAgICBjYXNlIFR5cGVzLkJlZm9yZUFsbDogcmV0dXJuIFwiYmVmb3JlIGFsbFwiXG4gICAgICAgIGNhc2UgVHlwZXMuQmVmb3JlRWFjaDogcmV0dXJuIFwiYmVmb3JlIGVhY2hcIlxuICAgICAgICBjYXNlIFR5cGVzLkFmdGVyRWFjaDogcmV0dXJuIFwiYWZ0ZXIgZWFjaFwiXG4gICAgICAgIGNhc2UgVHlwZXMuQWZ0ZXJBbGw6IHJldHVybiBcImFmdGVyIGFsbFwiXG4gICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcihcInVucmVhY2hhYmxlXCIpXG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgZ2V0IGlzQmVmb3JlQWxsKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5CZWZvcmVBbGwgfSxcbiAgICBnZXQgaXNCZWZvcmVFYWNoKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5CZWZvcmVFYWNoIH0sXG4gICAgZ2V0IGlzQWZ0ZXJFYWNoKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5BZnRlckVhY2ggfSxcbiAgICBnZXQgaXNBZnRlckFsbCgpIHsgcmV0dXJuIHRoaXMuXyA9PT0gVHlwZXMuQWZ0ZXJBbGwgfSxcbn1cblxuZXhwb3J0cy5Ib29rRXJyb3IgPSBIb29rRXJyb3JcbmZ1bmN0aW9uIEhvb2tFcnJvcihzdGFnZSwgZnVuYywgZXJyb3IpIHtcbiAgICB0aGlzLl8gPSBzdGFnZVxuICAgIHRoaXMubmFtZSA9IGZ1bmMubmFtZSB8fCBmdW5jLmRpc3BsYXlOYW1lIHx8IFwiXCJcbiAgICB0aGlzLmVycm9yID0gZXJyb3Jcbn1cbm1ldGhvZHMoSG9va0Vycm9yLCBIb29rTWV0aG9kcylcblxuZXhwb3J0cy5Ib29rID0gSG9va1JlcG9ydFxuZnVuY3Rpb24gSG9va1JlcG9ydChwYXRoLCByb290UGF0aCwgaG9va0Vycm9yKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgaG9va0Vycm9yLl8pXG4gICAgdGhpcy5wYXRoID0gcGF0aFxuICAgIHRoaXMucm9vdFBhdGggPSByb290UGF0aFxuICAgIHRoaXMubmFtZSA9IGhvb2tFcnJvci5uYW1lXG4gICAgdGhpcy5lcnJvciA9IGhvb2tFcnJvci5lcnJvclxufVxubWV0aG9kcyhIb29rUmVwb3J0LCBSZXBvcnQsIEhvb2tNZXRob2RzLCB7XG4gICAgZ2V0IGhvb2tFcnJvcigpIHsgcmV0dXJuIG5ldyBIb29rRXJyb3IodGhpcy5fLCB0aGlzLCB0aGlzLmVycm9yKSB9LFxufSlcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcbnZhciBwZWFjaCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpLnBlYWNoXG52YXIgUmVwb3J0cyA9IHJlcXVpcmUoXCIuL3JlcG9ydHNcIilcbnZhciBGaWx0ZXIgPSByZXF1aXJlKFwiLi9maWx0ZXJcIilcbnZhciBUeXBlcyA9IFJlcG9ydHMuVHlwZXNcblxuLyoqXG4gKiBUaGUgdGVzdHMgYXJlIGxhaWQgb3V0IGluIGEgdmVyeSBkYXRhLWRyaXZlbiBkZXNpZ24uIFdpdGggZXhjZXB0aW9uIG9mIHRoZVxuICogcmVwb3J0cywgdGhlcmUgaXMgbWluaW1hbCBvYmplY3Qgb3JpZW50YXRpb24gYW5kIHplcm8gdmlydHVhbCBkaXNwYXRjaC5cbiAqIEhlcmUncyBhIHF1aWNrIG92ZXJ2aWV3OlxuICpcbiAqIC0gVGhlIHRlc3QgaGFuZGxpbmcgZGlzcGF0Y2hlcyBiYXNlZCBvbiB2YXJpb3VzIGF0dHJpYnV0ZXMgdGhlIHRlc3QgaGFzLiBGb3JcbiAqICAgZXhhbXBsZSwgcm9vdHMgYXJlIGtub3duIGJ5IGEgY2lyY3VsYXIgcm9vdCByZWZlcmVuY2UsIGFuZCBza2lwcGVkIHRlc3RzXG4gKiAgIGFyZSBrbm93biBieSBub3QgaGF2aW5nIGEgY2FsbGJhY2suXG4gKlxuICogLSBUaGUgdGVzdCBldmFsdWF0aW9uIGlzIHZlcnkgcHJvY2VkdXJhbC4gQWx0aG91Z2ggaXQncyB2ZXJ5IGhpZ2hseVxuICogICBhc3luY2hyb25vdXMsIHRoZSB1c2Ugb2YgcHJvbWlzZXMgbGluZWFyaXplIHRoZSBsb2dpYywgc28gaXQgcmVhZHMgdmVyeVxuICogICBtdWNoIGxpa2UgYSByZWN1cnNpdmUgc2V0IG9mIHN0ZXBzLlxuICpcbiAqIC0gVGhlIGRhdGEgdHlwZXMgYXJlIG1vc3RseSBlaXRoZXIgcGxhaW4gb2JqZWN0cyBvciBjbGFzc2VzIHdpdGggbm8gbWV0aG9kcyxcbiAqICAgdGhlIGxhdHRlciBtb3N0bHkgZm9yIGRlYnVnZ2luZyBoZWxwLiBUaGlzIGFsc28gYXZvaWRzIG1vc3Qgb2YgdGhlXG4gKiAgIGluZGlyZWN0aW9uIHJlcXVpcmVkIHRvIGFjY29tbW9kYXRlIGJyZWFraW5nIGFic3RyYWN0aW9ucywgd2hpY2ggdGhlIEFQSVxuICogICBtZXRob2RzIGZyZXF1ZW50bHkgbmVlZCB0byBkby5cbiAqL1xuXG4vLyBQcmV2ZW50IFNpbm9uIGludGVyZmVyZW5jZSB3aGVuIHRoZXkgaW5zdGFsbCB0aGVpciBtb2Nrc1xudmFyIHNldFRpbWVvdXQgPSBnbG9iYWwuc2V0VGltZW91dFxudmFyIGNsZWFyVGltZW91dCA9IGdsb2JhbC5jbGVhclRpbWVvdXRcbnZhciBub3cgPSBnbG9iYWwuRGF0ZS5ub3dcblxuLyoqXG4gKiBCYXNpYyBkYXRhIHR5cGVzXG4gKi9cbmZ1bmN0aW9uIFJlc3VsdCh0aW1lLCBhdHRlbXB0KSB7XG4gICAgdGhpcy50aW1lID0gdGltZVxuICAgIHRoaXMuY2F1Z2h0ID0gYXR0ZW1wdC5jYXVnaHRcbiAgICB0aGlzLnZhbHVlID0gYXR0ZW1wdC5jYXVnaHQgPyBhdHRlbXB0LnZhbHVlIDogdW5kZWZpbmVkXG59XG5cbi8qKlxuICogT3ZlcnZpZXcgb2YgdGhlIHRlc3QgcHJvcGVydGllczpcbiAqXG4gKiAtIGBtZXRob2RzYCAtIEEgZGVwcmVjYXRlZCByZWZlcmVuY2UgdG8gdGhlIEFQSSBtZXRob2RzXG4gKiAtIGByb290YCAtIFRoZSByb290IHRlc3RcbiAqIC0gYHJlcG9ydGVyc2AgLSBUaGUgbGlzdCBvZiByZXBvcnRlcnNcbiAqIC0gYGN1cnJlbnRgIC0gQSByZWZlcmVuY2UgdG8gdGhlIGN1cnJlbnRseSBhY3RpdmUgdGVzdFxuICogLSBgdGltZW91dGAgLSBUaGUgdGVzdHMncyB0aW1lb3V0LCBvciAwIGlmIGluaGVyaXRlZFxuICogLSBgc2xvd2AgLSBUaGUgdGVzdHMncyBzbG93IHRocmVzaG9sZFxuICogLSBgbmFtZWAgLSBUaGUgdGVzdCdzIG5hbWVcbiAqIC0gYGluZGV4YCAtIFRoZSB0ZXN0J3MgaW5kZXhcbiAqIC0gYHBhcmVudGAgLSBUaGUgdGVzdCdzIHBhcmVudFxuICogLSBgY2FsbGJhY2tgIC0gVGhlIHRlc3QncyBjYWxsYmFja1xuICogLSBgdGVzdHNgIC0gVGhlIHRlc3QncyBjaGlsZCB0ZXN0c1xuICogLSBgYmVmb3JlQWxsYCwgYGJlZm9yZUVhY2hgLCBgYWZ0ZXJFYWNoYCwgYGFmdGVyQWxsYCAtIFRoZSB0ZXN0J3MgdmFyaW91c1xuICogICBzY2hlZHVsZWQgaG9va3NcbiAqXG4gKiBNYW55IG9mIHRoZXNlIHByb3BlcnRpZXMgYXJlbid0IHByZXNlbnQgb24gaW5pdGlhbGl6YXRpb24gdG8gc2F2ZSBtZW1vcnkuXG4gKi9cblxuLy8gVE9ETzogcmVtb3ZlIGB0ZXN0Lm1ldGhvZHNgIGluIDAuNFxuZnVuY3Rpb24gTm9ybWFsKG5hbWUsIGluZGV4LCBwYXJlbnQsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGNoaWxkID0gT2JqZWN0LmNyZWF0ZShwYXJlbnQubWV0aG9kcylcblxuICAgIGNoaWxkLl8gPSB0aGlzXG4gICAgdGhpcy5tZXRob2RzID0gY2hpbGRcbiAgICB0aGlzLmxvY2tlZCA9IHRydWVcbiAgICB0aGlzLnJvb3QgPSBwYXJlbnQucm9vdFxuICAgIHRoaXMubmFtZSA9IG5hbWVcbiAgICB0aGlzLmluZGV4ID0gaW5kZXh8MFxuICAgIHRoaXMucGFyZW50ID0gcGFyZW50XG4gICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrXG4gICAgdGhpcy5pc0ZhaWxhYmxlID0gcGFyZW50LmlzRmFpbGFibGVcbiAgICB0aGlzLmF0dGVtcHRzID0gcGFyZW50LmF0dGVtcHRzXG5cbiAgICB0aGlzLnRpbWVvdXQgPSAwXG4gICAgdGhpcy5zbG93ID0gMFxuICAgIHRoaXMudGVzdHMgPSB1bmRlZmluZWRcbiAgICB0aGlzLmJlZm9yZUFsbCA9IHVuZGVmaW5lZFxuICAgIHRoaXMuYmVmb3JlRWFjaCA9IHVuZGVmaW5lZFxuICAgIHRoaXMuYWZ0ZXJFYWNoID0gdW5kZWZpbmVkXG4gICAgdGhpcy5hZnRlckFsbCA9IHVuZGVmaW5lZFxuICAgIHRoaXMucmVwb3J0ZXIgPSB1bmRlZmluZWRcbiAgICB0aGlzLnJlZmxlY3QgPSB1bmRlZmluZWRcbn1cblxuZnVuY3Rpb24gU2tpcHBlZChuYW1lLCBpbmRleCwgcGFyZW50KSB7XG4gICAgdGhpcy5sb2NrZWQgPSB0cnVlXG4gICAgdGhpcy5yb290ID0gcGFyZW50LnJvb3RcbiAgICB0aGlzLm5hbWUgPSBuYW1lXG4gICAgdGhpcy5pbmRleCA9IGluZGV4fDBcbiAgICB0aGlzLnBhcmVudCA9IHBhcmVudFxuXG4gICAgLy8gT25seSBmb3IgcmVmbGVjdGlvbi5cbiAgICB0aGlzLmlzRmFpbGFibGUgPSBwYXJlbnQuaXNGYWlsYWJsZVxuICAgIHRoaXMuYXR0ZW1wdHMgPSBwYXJlbnQuYXR0ZW1wdHNcbiAgICB0aGlzLnJlcG9ydGVyID0gdW5kZWZpbmVkXG4gICAgdGhpcy5yZWZsZWN0ID0gdW5kZWZpbmVkXG59XG5cbi8vIFRPRE86IHJlbW92ZSBgdGVzdC5tZXRob2RzYCBpbiAwLjRcbmZ1bmN0aW9uIFJvb3QobWV0aG9kcykge1xuICAgIHRoaXMubG9ja2VkID0gZmFsc2VcbiAgICB0aGlzLm1ldGhvZHMgPSBtZXRob2RzXG4gICAgdGhpcy5yZXBvcnRlcklkcyA9IFtdXG4gICAgdGhpcy5yZXBvcnRlcnMgPSBbXVxuICAgIHRoaXMuY3VycmVudCA9IHRoaXNcbiAgICB0aGlzLnJvb3QgPSB0aGlzXG4gICAgdGhpcy50aW1lb3V0ID0gMFxuICAgIHRoaXMuc2xvdyA9IDBcbiAgICB0aGlzLmF0dGVtcHRzID0gMVxuICAgIHRoaXMuaXNGYWlsYWJsZSA9IGZhbHNlXG5cbiAgICB0aGlzLnRlc3RzID0gdW5kZWZpbmVkXG4gICAgdGhpcy5yZXBvcnRlciA9IHVuZGVmaW5lZFxuICAgIHRoaXMucmVmbGVjdCA9IHVuZGVmaW5lZFxuICAgIHRoaXMuYmVmb3JlQWxsID0gdW5kZWZpbmVkXG4gICAgdGhpcy5iZWZvcmVFYWNoID0gdW5kZWZpbmVkXG4gICAgdGhpcy5hZnRlckVhY2ggPSB1bmRlZmluZWRcbiAgICB0aGlzLmFmdGVyQWxsID0gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIENvbnRleHQocm9vdCkge1xuICAgIHRoaXMucm9vdCA9IHJvb3RcbiAgICB0aGlzLnRlc3RzID0gW11cbiAgICB0aGlzLmlzU3VjY2VzcyA9IHRydWVcbn1cblxuLyoqXG4gKiBCYXNlIHRlc3RzIChpLmUuIGRlZmF1bHQgZXhwb3J0LCByZXN1bHQgb2YgYGludGVybmFsLnJvb3QoKWApLlxuICovXG5cbmV4cG9ydHMuY3JlYXRlUm9vdCA9IGZ1bmN0aW9uIChtZXRob2RzKSB7XG4gICAgcmV0dXJuIG5ldyBSb290KG1ldGhvZHMpXG59XG5cbi8qKlxuICogU2V0IHVwIGVhY2ggdGVzdCB0eXBlLlxuICovXG5cbi8qKlxuICogQSBub3JtYWwgdGVzdCB0aHJvdWdoIGB0LnRlc3QoKWAuXG4gKi9cblxuZXhwb3J0cy5hZGROb3JtYWwgPSBmdW5jdGlvbiAocGFyZW50LCBuYW1lLCBjYWxsYmFjaykge1xuICAgIHZhciBpbmRleCA9IHBhcmVudC50ZXN0cyAhPSBudWxsID8gcGFyZW50LnRlc3RzLmxlbmd0aCA6IDBcbiAgICB2YXIgYmFzZSA9IG5ldyBOb3JtYWwobmFtZSwgaW5kZXgsIHBhcmVudCwgY2FsbGJhY2spXG5cbiAgICBpZiAoaW5kZXgpIHtcbiAgICAgICAgcGFyZW50LnRlc3RzLnB1c2goYmFzZSlcbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXJlbnQudGVzdHMgPSBbYmFzZV1cbiAgICB9XG59XG5cbi8qKlxuICogQSBza2lwcGVkIHRlc3QgdGhyb3VnaCBgdC50ZXN0U2tpcCgpYC5cbiAqL1xuZXhwb3J0cy5hZGRTa2lwcGVkID0gZnVuY3Rpb24gKHBhcmVudCwgbmFtZSkge1xuICAgIHZhciBpbmRleCA9IHBhcmVudC50ZXN0cyAhPSBudWxsID8gcGFyZW50LnRlc3RzLmxlbmd0aCA6IDBcbiAgICB2YXIgYmFzZSA9IG5ldyBTa2lwcGVkKG5hbWUsIGluZGV4LCBwYXJlbnQpXG5cbiAgICBpZiAoaW5kZXgpIHtcbiAgICAgICAgcGFyZW50LnRlc3RzLnB1c2goYmFzZSlcbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXJlbnQudGVzdHMgPSBbYmFzZV1cbiAgICB9XG59XG5cbi8qKlxuICogQ2xlYXIgdGhlIHRlc3RzIGluIHBsYWNlLlxuICovXG5leHBvcnRzLmNsZWFyVGVzdHMgPSBmdW5jdGlvbiAocGFyZW50KSB7XG4gICAgcGFyZW50LnRlc3RzID0gbnVsbFxufVxuXG4vKipcbiAqIEV4ZWN1dGUgdGhlIHRlc3RzXG4gKi9cblxuLy8gVE9ETzogY2FjaGUgYW5kIHJlbW92ZSB0aGVzZSB0cmF2ZXJzYWxzIGZvciAwLjQuXG4vLyBOb3RlIHRoYXQgYSB0aW1lb3V0IG9mIDAgbWVhbnMgdG8gaW5oZXJpdCB0aGUgcGFyZW50LlxuZnVuY3Rpb24gZmluZFRpbWVvdXQodGVzdHMpIHtcbiAgICBmb3IgKHZhciBpID0gdGVzdHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgaWYgKHRlc3RzW2ldLnRpbWVvdXQpIHJldHVybiB0ZXN0c1tpXS50aW1lb3V0XG4gICAgfVxuXG4gICAgcmV0dXJuIDIwMDAgLy8gbXMgLSBkZWZhdWx0IHRpbWVvdXRcbn1cblxuLy8gTm90ZSB0aGF0IGEgc2xvd25lc3MgdGhyZXNob2xkIG9mIDAgbWVhbnMgdG8gaW5oZXJpdCB0aGUgcGFyZW50LlxuZnVuY3Rpb24gZmluZFNsb3codGVzdHMpIHtcbiAgICBmb3IgKHZhciBpID0gdGVzdHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgaWYgKHRlc3RzW2ldLnNsb3cpIHJldHVybiB0ZXN0c1tpXS5zbG93XG4gICAgfVxuXG4gICAgcmV0dXJuIDc1IC8vIG1zIC0gZGVmYXVsdCBzbG93IHRocmVzaG9sZFxufVxuXG5mdW5jdGlvbiBtYWtlU2xpY2UodGVzdHMsIGxlbmd0aCkge1xuICAgIHZhciByZXQgPSBuZXcgQXJyYXkobGVuZ3RoKVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICByZXRbaV0gPSB7bmFtZTogdGVzdHNbaV0ubmFtZSwgaW5kZXg6IHRlc3RzW2ldLmluZGV4fVxuICAgIH1cblxuICAgIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gcmVwb3J0KGNvbnRleHQsIHR5cGUsIGFyZzEsIGFyZzIpIHtcbiAgICBmdW5jdGlvbiBpbnZva2VSZXBvcnRlcihyZXBvcnRlcikge1xuICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSBUeXBlcy5TdGFydDpcbiAgICAgICAgICAgIHJldHVybiByZXBvcnRlcihuZXcgUmVwb3J0cy5TdGFydCgpKVxuXG4gICAgICAgIGNhc2UgVHlwZXMuRW50ZXI6XG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0ZXIoXG4gICAgICAgICAgICAgICAgbmV3IFJlcG9ydHMuRW50ZXIoXG4gICAgICAgICAgICAgICAgICAgIG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmxlbmd0aCksIGFyZzEsXG4gICAgICAgICAgICAgICAgICAgIGZpbmRTbG93KGNvbnRleHQudGVzdHMpKSlcblxuICAgICAgICBjYXNlIFR5cGVzLkxlYXZlOlxuICAgICAgICAgICAgcmV0dXJuIHJlcG9ydGVyKG5ldyBSZXBvcnRzLkxlYXZlKFxuICAgICAgICAgICAgICAgIG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmxlbmd0aCkpKVxuXG4gICAgICAgIGNhc2UgVHlwZXMuUGFzczpcbiAgICAgICAgICAgIHJldHVybiByZXBvcnRlcihcbiAgICAgICAgICAgICAgICBuZXcgUmVwb3J0cy5QYXNzKFxuICAgICAgICAgICAgICAgICAgICBtYWtlU2xpY2UoY29udGV4dC50ZXN0cywgY29udGV4dC50ZXN0cy5sZW5ndGgpLCBhcmcxLFxuICAgICAgICAgICAgICAgICAgICBmaW5kU2xvdyhjb250ZXh0LnRlc3RzKSkpXG5cbiAgICAgICAgY2FzZSBUeXBlcy5GYWlsOlxuICAgICAgICAgICAgcmV0dXJuIHJlcG9ydGVyKFxuICAgICAgICAgICAgICAgIG5ldyBSZXBvcnRzLkZhaWwoXG4gICAgICAgICAgICAgICAgICAgIG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmxlbmd0aCksIGFyZzEsIGFyZzIsXG4gICAgICAgICAgICAgICAgICAgIGZpbmRTbG93KGNvbnRleHQudGVzdHMpLFxuICAgICAgICAgICAgICAgICAgICAhIWNvbnRleHQucm9vdC5jdXJyZW50LmlzRmFpbGFibGUpKVxuXG4gICAgICAgIGNhc2UgVHlwZXMuU2tpcDpcbiAgICAgICAgICAgIHJldHVybiByZXBvcnRlcihuZXcgUmVwb3J0cy5Ta2lwKFxuICAgICAgICAgICAgICAgIG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmxlbmd0aCkpKVxuXG4gICAgICAgIGNhc2UgVHlwZXMuRW5kOlxuICAgICAgICAgICAgcmV0dXJuIHJlcG9ydGVyKG5ldyBSZXBvcnRzLkVuZCgpKVxuXG4gICAgICAgIGNhc2UgVHlwZXMuRXJyb3I6XG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0ZXIobmV3IFJlcG9ydHMuRXJyb3IoYXJnMSkpXG5cbiAgICAgICAgY2FzZSBUeXBlcy5Ib29rOlxuICAgICAgICAgICAgLy8gSW5jbHVkZSB0aGUgbGFzdCB0ZXN0LiBUaGlzIGFsc28gaW1wbGljaXRseSBzZXRzIHRoZSBlbmQgdG8gMCBmb3JcbiAgICAgICAgICAgIC8vIHJvb3QgdGVzdHMuXG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0ZXIobmV3IFJlcG9ydHMuSG9vayhcbiAgICAgICAgICAgICAgICBtYWtlU2xpY2UoY29udGV4dC50ZXN0cywgY29udGV4dC50ZXN0cy5sZW5ndGgpLFxuICAgICAgICAgICAgICAgIG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmluZGV4T2YoYXJnMSkgKyAxKSxcbiAgICAgICAgICAgICAgICBhcmcyKSlcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcInVucmVhY2hhYmxlXCIpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjb250ZXh0LnJvb3QucmVwb3J0ZXIgPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICByZXR1cm4gaW52b2tlUmVwb3J0ZXIoY29udGV4dC5yb290LnJlcG9ydGVyKVxuICAgIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcmVwb3J0ZXJzID0gY29udGV4dC5yb290LnJlcG9ydGVyc1xuXG4gICAgICAgIC8vIFR3byBlYXN5IGNhc2VzLlxuICAgICAgICBpZiAocmVwb3J0ZXJzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICBpZiAocmVwb3J0ZXJzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGludm9rZVJlcG9ydGVyKHJlcG9ydGVyc1swXSlcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHJlcG9ydGVycy5tYXAoaW52b2tlUmVwb3J0ZXIpKVxuICAgIH0pXG59XG5cbi8qKlxuICogTm9ybWFsIHRlc3RzXG4gKi9cblxuLy8gUGhhbnRvbUpTIGFuZCBJRSBkb24ndCBhZGQgdGhlIHN0YWNrIHVudGlsIGl0J3MgdGhyb3duLiBJbiBmYWlsaW5nIGFzeW5jXG4vLyB0ZXN0cywgaXQncyBhbHJlYWR5IHRocm93biBpbiBhIHNlbnNlLCBzbyB0aGlzIHNob3VsZCBiZSBub3JtYWxpemVkIHdpdGhcbi8vIG90aGVyIHRlc3QgdHlwZXMuXG52YXIgYWRkU3RhY2sgPSB0eXBlb2YgbmV3IEVycm9yKCkuc3RhY2sgIT09IFwic3RyaW5nXCJcbiAgICA/IGZ1bmN0aW9uIGFkZFN0YWNrKGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgRXJyb3IgJiYgZS5zdGFjayA9PSBudWxsKSB0aHJvdyBlXG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICByZXR1cm4gZVxuICAgICAgICB9XG4gICAgfVxuICAgIDogZnVuY3Rpb24gKGUpIHsgcmV0dXJuIGUgfVxuXG5mdW5jdGlvbiBnZXRUaGVuKHJlcykge1xuICAgIGlmICh0eXBlb2YgcmVzID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiByZXMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gcmVzLnRoZW5cbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxufVxuXG5mdW5jdGlvbiBBc3luY1N0YXRlKGNvbnRleHQsIHN0YXJ0LCByZXNvbHZlLCBjb3VudCkge1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHRcbiAgICB0aGlzLnN0YXJ0ID0gc3RhcnRcbiAgICB0aGlzLnJlc29sdmUgPSByZXNvbHZlXG4gICAgdGhpcy5jb3VudCA9IGNvdW50XG4gICAgdGhpcy50aW1lciA9IHVuZGVmaW5lZFxufVxuXG52YXIgcCA9IFByb21pc2UucmVzb2x2ZSgpXG5cbmZ1bmN0aW9uIGFzeW5jRmluaXNoKHN0YXRlLCBhdHRlbXB0KSB7XG4gICAgLy8gQ2FwdHVyZSBpbW1lZGlhdGVseS4gV29yc3QgY2FzZSBzY2VuYXJpbywgaXQgZ2V0cyB0aHJvd24gYXdheS5cbiAgICB2YXIgZW5kID0gbm93KClcblxuICAgIGlmIChzdGF0ZS50aW1lcikge1xuICAgICAgICBjbGVhclRpbWVvdXQuY2FsbChnbG9iYWwsIHN0YXRlLnRpbWVyKVxuICAgICAgICBzdGF0ZS50aW1lciA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmIChhdHRlbXB0LmNhdWdodCAmJiBzdGF0ZS5jb3VudCA8IHN0YXRlLmNvbnRleHQucm9vdC5jdXJyZW50LmF0dGVtcHRzKSB7XG4gICAgICAgIC8vIERvbid0IHJlY3Vyc2Ugc3luY2hyb25vdXNseSwgc2luY2UgaXQgbWF5IGJlIHJlc29sdmVkIHN5bmNocm9ub3VzbHlcbiAgICAgICAgc3RhdGUucmVzb2x2ZShwLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGludm9rZUluaXQoc3RhdGUuY29udGV4dCwgc3RhdGUuY291bnQgKyAxKVxuICAgICAgICB9KSlcbiAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5yZXNvbHZlKG5ldyBSZXN1bHQoZW5kIC0gc3RhdGUuc3RhcnQsIGF0dGVtcHQpKVxuICAgIH1cbn1cblxuLy8gQXZvaWQgY3JlYXRpbmcgYSBjbG9zdXJlIGlmIHBvc3NpYmxlLCBpbiBjYXNlIGl0IGRvZXNuJ3QgcmV0dXJuIGEgdGhlbmFibGUuXG5mdW5jdGlvbiBpbnZva2VJbml0KGNvbnRleHQsIGNvdW50KSB7XG4gICAgdmFyIHRlc3QgPSBjb250ZXh0LnJvb3QuY3VycmVudFxuICAgIHZhciBzdGFydCA9IG5vdygpXG4gICAgdmFyIHRyeUJvZHkgPSB0cnkxKHRlc3QuY2FsbGJhY2ssIHRlc3QubWV0aG9kcywgdGVzdC5tZXRob2RzKVxuICAgIHZhciBzeW5jRW5kID0gbm93KClcblxuICAgIC8vIE5vdGU6IHN5bmNocm9ub3VzIGZhaWx1cmVzIGFyZSB0ZXN0IGZhaWx1cmVzLCBub3QgZmF0YWwgZXJyb3JzLlxuICAgIGlmICh0cnlCb2R5LmNhdWdodCkge1xuICAgICAgICBpZiAoY291bnQgPCB0ZXN0LmF0dGVtcHRzKSByZXR1cm4gaW52b2tlSW5pdChjb250ZXh0LCBjb3VudCArIDEpXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IFJlc3VsdChzeW5jRW5kIC0gc3RhcnQsIHRyeUJvZHkpKVxuICAgIH1cblxuICAgIHZhciB0cnlUaGVuID0gdHJ5MShnZXRUaGVuLCB1bmRlZmluZWQsIHRyeUJvZHkudmFsdWUpXG5cbiAgICBpZiAodHJ5VGhlbi5jYXVnaHQpIHtcbiAgICAgICAgaWYgKGNvdW50IDwgdGVzdC5hdHRlbXB0cykgcmV0dXJuIGludm9rZUluaXQoY29udGV4dCwgY291bnQgKyAxKVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBSZXN1bHQoc3luY0VuZCAtIHN0YXJ0LCB0cnlUaGVuKSlcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRyeVRoZW4udmFsdWUgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBSZXN1bHQoc3luY0VuZCAtIHN0YXJ0LCB0cnlUaGVuKSlcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgdmFyIHN0YXRlID0gbmV3IEFzeW5jU3RhdGUoY29udGV4dCwgc3RhcnQsIHJlc29sdmUsIGNvdW50KVxuICAgICAgICB2YXIgcmVzdWx0ID0gdHJ5Mih0cnlUaGVuLnZhbHVlLCB0cnlCb2R5LnZhbHVlLFxuICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZSA9PSBudWxsKSByZXR1cm5cbiAgICAgICAgICAgICAgICBhc3luY0ZpbmlzaChzdGF0ZSwgdHJ5UGFzcygpKVxuICAgICAgICAgICAgICAgIHN0YXRlID0gdW5kZWZpbmVkXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUgPT0gbnVsbCkgcmV0dXJuXG4gICAgICAgICAgICAgICAgYXN5bmNGaW5pc2goc3RhdGUsIHRyeUZhaWwoYWRkU3RhY2soZSkpKVxuICAgICAgICAgICAgICAgIHN0YXRlID0gdW5kZWZpbmVkXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIGlmIChzdGF0ZSA9PSBudWxsKSByZXR1cm5cbiAgICAgICAgaWYgKHJlc3VsdC5jYXVnaHQpIHtcbiAgICAgICAgICAgIGFzeW5jRmluaXNoKHN0YXRlLCByZXN1bHQpXG4gICAgICAgICAgICBzdGF0ZSA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgdGhlIHRpbWVvdXQgKmFmdGVyKiBpbml0aWFsaXphdGlvbi4gVGhlIHRpbWVvdXQgd2lsbCBsaWtlbHkgYmVcbiAgICAgICAgLy8gc3BlY2lmaWVkIGR1cmluZyBpbml0aWFsaXphdGlvbi5cbiAgICAgICAgdmFyIG1heFRpbWVvdXQgPSBmaW5kVGltZW91dChjb250ZXh0LnRlc3RzKVxuXG4gICAgICAgIC8vIFNldHRpbmcgYSB0aW1lb3V0IGlzIHBvaW50bGVzcyBpZiBpdCdzIGluZmluaXRlLlxuICAgICAgICBpZiAobWF4VGltZW91dCAhPT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgIHN0YXRlLnRpbWVyID0gc2V0VGltZW91dC5jYWxsKGdsb2JhbCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZSA9PSBudWxsKSByZXR1cm5cbiAgICAgICAgICAgICAgICBhc3luY0ZpbmlzaChzdGF0ZSwgdHJ5RmFpbChhZGRTdGFjayhcbiAgICAgICAgICAgICAgICAgICAgbmV3IEVycm9yKFwiVGltZW91dCBvZiBcIiArIG1heFRpbWVvdXQgKyBcIiByZWFjaGVkXCIpKSkpXG4gICAgICAgICAgICAgICAgc3RhdGUgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIH0sIG1heFRpbWVvdXQpXG4gICAgICAgIH1cbiAgICB9KVxufVxuXG5mdW5jdGlvbiBFcnJvcldyYXAodGVzdCwgZXJyb3IpIHtcbiAgICB0aGlzLnRlc3QgPSB0ZXN0XG4gICAgdGhpcy5lcnJvciA9IGVycm9yXG59XG5tZXRob2RzKEVycm9yV3JhcCwgRXJyb3IsIHtuYW1lOiBcIkVycm9yV3JhcFwifSlcblxuZnVuY3Rpb24gaW52b2tlSG9vayh0ZXN0LCBsaXN0LCBzdGFnZSkge1xuICAgIGlmIChsaXN0ID09IG51bGwpIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgIHJldHVybiBwZWFjaChsaXN0LCBmdW5jdGlvbiAoaG9vaykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGhvb2soKVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3JXcmFwKHRlc3QsIG5ldyBSZXBvcnRzLkhvb2tFcnJvcihzdGFnZSwgaG9vaywgZSkpXG4gICAgICAgIH1cbiAgICB9KVxufVxuXG5mdW5jdGlvbiBpbnZva2VCZWZvcmVFYWNoKHRlc3QpIHtcbiAgICBpZiAodGVzdC5yb290ID09PSB0ZXN0KSB7XG4gICAgICAgIHJldHVybiBpbnZva2VIb29rKHRlc3QsIHRlc3QuYmVmb3JlRWFjaCwgVHlwZXMuQmVmb3JlRWFjaClcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gaW52b2tlQmVmb3JlRWFjaCh0ZXN0LnBhcmVudCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gaW52b2tlSG9vayh0ZXN0LCB0ZXN0LmJlZm9yZUVhY2gsIFR5cGVzLkJlZm9yZUVhY2gpXG4gICAgICAgIH0pXG4gICAgfVxufVxuXG5mdW5jdGlvbiBpbnZva2VBZnRlckVhY2godGVzdCkge1xuICAgIGlmICh0ZXN0LnJvb3QgPT09IHRlc3QpIHtcbiAgICAgICAgcmV0dXJuIGludm9rZUhvb2sodGVzdCwgdGVzdC5hZnRlckVhY2gsIFR5cGVzLkFmdGVyRWFjaClcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gaW52b2tlSG9vayh0ZXN0LCB0ZXN0LmFmdGVyRWFjaCwgVHlwZXMuQWZ0ZXJFYWNoKVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBpbnZva2VBZnRlckVhY2godGVzdC5wYXJlbnQpIH0pXG4gICAgfVxufVxuXG4vKipcbiAqIFRoaXMgY2hlY2tzIGlmIHRoZSB0ZXN0IHdhcyB3aGl0ZWxpc3RlZCBpbiBhIGB0Lm9ubHkoKWAgY2FsbCwgb3IgZm9yXG4gKiBjb252ZW5pZW5jZSwgcmV0dXJucyBgdHJ1ZWAgaWYgYHQub25seSgpYCB3YXMgbmV2ZXIgY2FsbGVkLlxuICovXG5mdW5jdGlvbiBpc09ubHkodGVzdCkge1xuICAgIHZhciBwYXRoID0gW11cblxuICAgIHdoaWxlICh0ZXN0LnBhcmVudCAhPSBudWxsICYmIHRlc3Qub25seSA9PSBudWxsKSB7XG4gICAgICAgIHBhdGgucHVzaCh0ZXN0Lm5hbWUpXG4gICAgICAgIHRlc3QgPSB0ZXN0LnBhcmVudFxuICAgIH1cblxuICAgIC8vIElmIHRoZXJlIGlzbid0IGFueSBgb25seWAgYWN0aXZlLCB0aGVuIGxldCdzIHNraXAgdGhlIGNoZWNrIGFuZCByZXR1cm5cbiAgICAvLyBgdHJ1ZWAgZm9yIGNvbnZlbmllbmNlLlxuICAgIGlmICh0ZXN0Lm9ubHkgPT0gbnVsbCkgcmV0dXJuIHRydWVcbiAgICByZXR1cm4gRmlsdGVyLnRlc3QodGVzdC5vbmx5LCBwYXRoKVxufVxuXG5mdW5jdGlvbiBydW5DaGlsZFRlc3RzKHRlc3QsIGNvbnRleHQpIHtcbiAgICBpZiAodGVzdC50ZXN0cyA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgICBmdW5jdGlvbiBsZWF2ZSgpIHtcbiAgICAgICAgdGVzdC5yb290LmN1cnJlbnQgPSB0ZXN0XG4gICAgICAgIGNvbnRleHQudGVzdHMucG9wKClcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBydW5DaGlsZChjaGlsZCkge1xuICAgICAgICB0ZXN0LnJvb3QuY3VycmVudCA9IGNoaWxkXG4gICAgICAgIGNvbnRleHQudGVzdHMucHVzaChjaGlsZClcblxuICAgICAgICByZXR1cm4gaW52b2tlQmVmb3JlRWFjaCh0ZXN0KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBydW5Ob3JtYWxDaGlsZChjaGlsZCwgY29udGV4dCkgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gaW52b2tlQWZ0ZXJFYWNoKHRlc3QpIH0pXG4gICAgICAgIC5jYXRjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIEVycm9yV3JhcCkpIHRocm93IGVcbiAgICAgICAgICAgIHJldHVybiByZXBvcnQoY29udGV4dCwgVHlwZXMuSG9vaywgZS50ZXN0LCBlLmVycm9yKVxuICAgICAgICB9KVxuICAgICAgICAudGhlbihsZWF2ZSwgZnVuY3Rpb24gKGUpIHsgbGVhdmUoKTsgdGhyb3cgZSB9KVxuICAgIH1cblxuICAgIHZhciByYW4gPSBmYWxzZVxuXG4gICAgcmV0dXJuIHBlYWNoKHRlc3QudGVzdHMsIGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAvLyBPbmx5IHNraXBwZWQgdGVzdHMgaGF2ZSBubyBjYWxsYmFja1xuICAgICAgICBpZiAoY2hpbGQuY2FsbGJhY2sgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGVzdC5yb290LmN1cnJlbnQgPSBjaGlsZFxuICAgICAgICAgICAgY29udGV4dC50ZXN0cy5wdXNoKGNoaWxkKVxuXG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0KGNvbnRleHQsIFR5cGVzLlNraXApXG4gICAgICAgICAgICAudGhlbihsZWF2ZSwgZnVuY3Rpb24gKGUpIHsgbGVhdmUoKTsgdGhyb3cgZSB9KVxuICAgICAgICB9IGVsc2UgaWYgKCFpc09ubHkoY2hpbGQpKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgfSBlbHNlIGlmIChyYW4pIHtcbiAgICAgICAgICAgIHJldHVybiBydW5DaGlsZChjaGlsZClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJhbiA9IHRydWVcbiAgICAgICAgICAgIHJldHVybiBpbnZva2VIb29rKHRlc3QsIHRlc3QuYmVmb3JlQWxsLCBUeXBlcy5CZWZvcmVBbGwpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBydW5DaGlsZChjaGlsZCkgfSlcbiAgICAgICAgfVxuICAgIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gcmFuID8gaW52b2tlSG9vayh0ZXN0LCB0ZXN0LmFmdGVyQWxsLCBUeXBlcy5BZnRlckFsbCkgOiB1bmRlZmluZWRcbiAgICB9KVxufVxuXG5mdW5jdGlvbiBjbGVhckNoaWxkcmVuKHRlc3QpIHtcbiAgICBpZiAodGVzdC50ZXN0cyA9PSBudWxsKSByZXR1cm5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRlc3QudGVzdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGVzdC50ZXN0c1tpXS50ZXN0cyA9IHVuZGVmaW5lZFxuICAgIH1cbn1cblxuZnVuY3Rpb24gcnVuTm9ybWFsQ2hpbGQodGVzdCwgY29udGV4dCkge1xuICAgIHRlc3QubG9ja2VkID0gZmFsc2VcblxuICAgIHJldHVybiBpbnZva2VJbml0KGNvbnRleHQsIDEpXG4gICAgLnRoZW4oXG4gICAgICAgIGZ1bmN0aW9uIChyZXN1bHQpIHsgdGVzdC5sb2NrZWQgPSB0cnVlOyByZXR1cm4gcmVzdWx0IH0sXG4gICAgICAgIGZ1bmN0aW9uIChlcnJvcikgeyB0ZXN0LmxvY2tlZCA9IHRydWU7IHRocm93IGVycm9yIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICBpZiAocmVzdWx0LmNhdWdodCkge1xuICAgICAgICAgICAgaWYgKCF0ZXN0LmlzRmFpbGFibGUpIGNvbnRleHQuaXNTdWNjZXNzID0gZmFsc2VcbiAgICAgICAgICAgIHJldHVybiByZXBvcnQoY29udGV4dCwgVHlwZXMuRmFpbCwgcmVzdWx0LnZhbHVlLCByZXN1bHQudGltZSlcbiAgICAgICAgfSBlbHNlIGlmICh0ZXN0LnRlc3RzICE9IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFJlcG9ydCB0aGlzIGFzIGlmIGl0IHdhcyBhIHBhcmVudCB0ZXN0IGlmIGl0J3MgcGFzc2luZyBhbmQgaGFzXG4gICAgICAgICAgICAvLyBjaGlsZHJlbi5cbiAgICAgICAgICAgIHJldHVybiByZXBvcnQoY29udGV4dCwgVHlwZXMuRW50ZXIsIHJlc3VsdC50aW1lKVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcnVuQ2hpbGRUZXN0cyh0ZXN0LCBjb250ZXh0KSB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVwb3J0KGNvbnRleHQsIFR5cGVzLkxlYXZlKSB9KVxuICAgICAgICAgICAgLmNhdGNoKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIEVycm9yV3JhcCkpIHRocm93IGVcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVwb3J0KGNvbnRleHQsIFR5cGVzLkxlYXZlKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcG9ydChjb250ZXh0LCBUeXBlcy5Ib29rLCBlLnRlc3QsIGUuZXJyb3IpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0KGNvbnRleHQsIFR5cGVzLlBhc3MsIHJlc3VsdC50aW1lKVxuICAgICAgICB9XG4gICAgfSlcbiAgICAudGhlbihcbiAgICAgICAgZnVuY3Rpb24gKCkgeyBjbGVhckNoaWxkcmVuKHRlc3QpIH0sXG4gICAgICAgIGZ1bmN0aW9uIChlKSB7IGNsZWFyQ2hpbGRyZW4odGVzdCk7IHRocm93IGUgfSlcbn1cblxuLyoqXG4gKiBUaGlzIHJ1bnMgdGhlIHJvb3QgdGVzdCBhbmQgcmV0dXJucyBhIHByb21pc2UgcmVzb2x2ZWQgd2hlbiBpdCdzIGRvbmUuXG4gKi9cbmV4cG9ydHMucnVuVGVzdCA9IGZ1bmN0aW9uIChyb290LCBvcHRzKSB7XG4gICAgdmFyIGNvbnRleHQgPSBuZXcgQ29udGV4dChyb290LCBvcHRzKVxuXG4gICAgcm9vdC5sb2NrZWQgPSB0cnVlXG4gICAgcmV0dXJuIHJlcG9ydChjb250ZXh0LCBUeXBlcy5TdGFydClcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBydW5DaGlsZFRlc3RzKHJvb3QsIGNvbnRleHQpIH0pXG4gICAgLmNhdGNoKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBFcnJvcldyYXApKSB0aHJvdyBlXG4gICAgICAgIHJldHVybiByZXBvcnQoY29udGV4dCwgVHlwZXMuSG9vaywgZS50ZXN0LCBlLmVycm9yKVxuICAgIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVwb3J0KGNvbnRleHQsIFR5cGVzLkVuZCkgfSlcbiAgICAvLyBUZWxsIHRoZSByZXBvcnRlciBzb21ldGhpbmcgaGFwcGVuZWQuIE90aGVyd2lzZSwgaXQnbGwgaGF2ZSB0byB3cmFwIHRoaXNcbiAgICAvLyBtZXRob2QgaW4gYSBwbHVnaW4sIHdoaWNoIHNob3VsZG4ndCBiZSBuZWNlc3NhcnkuXG4gICAgLmNhdGNoKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHJldHVybiByZXBvcnQoY29udGV4dCwgVHlwZXMuRXJyb3IsIGUpLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyBlIH0pXG4gICAgfSlcbiAgICAudGhlbihcbiAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY2xlYXJDaGlsZHJlbihyb290KVxuICAgICAgICAgICAgcm9vdC5sb2NrZWQgPSBmYWxzZVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBpc1N1Y2Nlc3M6IGNvbnRleHQuaXNTdWNjZXNzLFxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgY2xlYXJDaGlsZHJlbihyb290KVxuICAgICAgICAgICAgcm9vdC5sb2NrZWQgPSBmYWxzZVxuICAgICAgICAgICAgdGhyb3cgZVxuICAgICAgICB9KVxufVxuXG4vLyBIZWxwIG9wdGltaXplIGZvciBpbmVmZmljaWVudCBleGNlcHRpb24gaGFuZGxpbmcgaW4gVjhcblxuZnVuY3Rpb24gdHJ5UGFzcyh2YWx1ZSkge1xuICAgIHJldHVybiB7Y2F1Z2h0OiBmYWxzZSwgdmFsdWU6IHZhbHVlfVxufVxuXG5mdW5jdGlvbiB0cnlGYWlsKGUpIHtcbiAgICByZXR1cm4ge2NhdWdodDogdHJ1ZSwgdmFsdWU6IGV9XG59XG5cbmZ1bmN0aW9uIHRyeTEoZiwgaW5zdCwgYXJnMCkge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB0cnlQYXNzKGYuY2FsbChpbnN0LCBhcmcwKSlcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiB0cnlGYWlsKGUpXG4gICAgfVxufVxuXG5mdW5jdGlvbiB0cnkyKGYsIGluc3QsIGFyZzAsIGFyZzEpIHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gdHJ5UGFzcyhmLmNhbGwoaW5zdCwgYXJnMCwgYXJnMSkpXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gdHJ5RmFpbChlKVxuICAgIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogVGhlIERPTSByZXBvcnRlciBhbmQgbG9hZGVyIGVudHJ5IHBvaW50LiBTZWUgdGhlIFJFQURNRS5tZCBmb3IgbW9yZSBkZXRhaWxzLlxuICovXG5cbnZhciBpbml0aWFsaXplID0gcmVxdWlyZShcIi4vaW5pdGlhbGl6ZVwiKVxuLy8gdmFyIHQgPSByZXF1aXJlKFwiLi4vLi4vaW5kZXhcIilcbi8vIHZhciBhc3NlcnQgPSByZXF1aXJlKFwiLi4vLi4vYXNzZXJ0XCIpXG5cbmV4cG9ydHMuY3JlYXRlID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgICBpZiAob3B0cyA9PSBudWxsKSByZXR1cm4gaW5pdGlhbGl6ZSh7fSlcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvcHRzKSkgcmV0dXJuIGluaXRpYWxpemUoe2ZpbGVzOiBvcHRzfSlcbiAgICBpZiAodHlwZW9mIG9wdHMgPT09IFwib2JqZWN0XCIpIHJldHVybiBpbml0aWFsaXplKG9wdHMpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBvcHRzYCBtdXN0IGJlIGFuIG9iamVjdCBvciBhcnJheSBvZiBmaWxlcyBpZiBwYXNzZWRcIilcbn1cblxuLy8gQ3VycmVudGx5IGJyb2tlbiwgYmVjYXVzZSB0aGlzIGlzbid0IGF1dG9sb2FkZWQgeWV0LlxuLy8gZXhwb3J0cy5hdXRvbG9hZCA9IGZ1bmN0aW9uIChzY3JpcHQpIHtcbi8vICAgICB2YXIgZmlsZXMgPSBzY3JpcHQuZ2V0QXR0cmlidXRlKFwiZGF0YS1maWxlc1wiKVxuLy9cbi8vICAgICBpZiAoIWZpbGVzKSByZXR1cm5cbi8vXG4vLyAgICAgZnVuY3Rpb24gc2V0KG9wdHMsIGF0dHIsIHRyYW5zZm9ybSkge1xuLy8gICAgICAgICB2YXIgdmFsdWUgPSBzY3JpcHQuZ2V0QXR0cmlidXRlKFwiZGF0YS1cIiArIGF0dHIpXG4vL1xuLy8gICAgICAgICBpZiAodmFsdWUpIG9wdHNbYXR0cl0gPSB0cmFuc2Zvcm0odmFsdWUpXG4vLyAgICAgfVxuLy9cbi8vICAgICB2YXIgb3B0cyA9IHtmaWxlczogZmlsZXMudHJpbSgpLnNwbGl0KC9cXHMrL2cpfVxuLy9cbi8vICAgICBzZXQob3B0cywgXCJ0aW1lb3V0XCIsIE51bWJlcilcbi8vICAgICBzZXQob3B0cywgXCJwcmVsb2FkXCIsIEZ1bmN0aW9uKVxuLy8gICAgIHNldChvcHRzLCBcInByZXJ1blwiLCBGdW5jdGlvbilcbi8vICAgICBzZXQob3B0cywgXCJwb3N0cnVuXCIsIEZ1bmN0aW9uKVxuLy8gICAgIHNldChvcHRzLCBcImVycm9yXCIsIGZ1bmN0aW9uIChhdHRyKSB7XG4vLyAgICAgICAgIHJldHVybiBuZXcgRnVuY3Rpb24oXCJlcnJcIiwgYXR0cikgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuLy8gICAgIH0pXG4vL1xuLy8gICAgIC8vIENvbnZlbmllbmNlLlxuLy8gICAgIGdsb2JhbC50ID0gdFxuLy8gICAgIGdsb2JhbC5hc3NlcnQgPSBhc3NlcnRcbi8vXG4vLyAgICAgaWYgKGdsb2JhbC5kb2N1bWVudC5yZWFkeVN0YXRlICE9PSBcImxvYWRpbmdcIikge1xuLy8gICAgICAgICBpbml0aWFsaXplKG9wdHMpLnJ1bigpXG4vLyAgICAgfSBlbHNlIHtcbi8vICAgICAgICAgZ2xvYmFsLmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uICgpIHtcbi8vICAgICAgICAgICAgIGluaXRpYWxpemUob3B0cykucnVuKClcbi8vICAgICAgICAgfSlcbi8vICAgICB9XG4vLyB9XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vKipcbiAqIFRoZSByZXBvcnRlciBhbmQgdGVzdCBpbml0aWFsaXphdGlvbiBzZXF1ZW5jZSwgYW5kIHNjcmlwdCBsb2FkaW5nLiBUaGlzXG4gKiBkb2Vzbid0IHVuZGVyc3RhbmQgYW55dGhpbmcgdmlldy13aXNlLlxuICovXG5cbnZhciBkZWZhdWx0VCA9IHJlcXVpcmUoXCIuLi8uLi9pbmRleFwiKVxudmFyIFIgPSByZXF1aXJlKFwiLi4vcmVwb3J0ZXJcIilcbnZhciBEID0gcmVxdWlyZShcIi4vaW5qZWN0XCIpXG52YXIgcnVuVGVzdHMgPSByZXF1aXJlKFwiLi9ydW4tdGVzdHNcIilcbnZhciBpbmplY3RTdHlsZXMgPSByZXF1aXJlKFwiLi9pbmplY3Qtc3R5bGVzXCIpXG52YXIgVmlldyA9IHJlcXVpcmUoXCIuL3ZpZXdcIilcbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcblxuZnVuY3Rpb24gVHJlZShuYW1lKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZVxuICAgIHRoaXMuc3RhdHVzID0gUi5TdGF0dXMuVW5rbm93blxuICAgIHRoaXMubm9kZSA9IG51bGxcbiAgICB0aGlzLmNoaWxkcmVuID0gT2JqZWN0LmNyZWF0ZShudWxsKVxufVxuXG52YXIgcmVwb3J0ZXIgPSBSLm9uKFwiZG9tXCIsIHtcbiAgICBhY2NlcHRzOiBbXSxcbiAgICBjcmVhdGU6IGZ1bmN0aW9uIChvcHRzLCBtZXRob2RzKSB7XG4gICAgICAgIHZhciByZXBvcnRlciA9IG5ldyBSLlJlcG9ydGVyKFRyZWUsIHVuZGVmaW5lZCwgbWV0aG9kcylcblxuICAgICAgICByZXBvcnRlci5vcHRzID0gb3B0c1xuICAgICAgICByZXR1cm4gcmVwb3J0ZXJcbiAgICB9LFxuXG4gICAgLy8gR2l2ZSB0aGUgYnJvd3NlciBhIGNoYW5jZSB0byByZXBhaW50IGJlZm9yZSBjb250aW51aW5nIChtaWNyb3Rhc2tzXG4gICAgLy8gbm9ybWFsbHkgYmxvY2sgcmVuZGVyaW5nKS5cbiAgICBhZnRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoVmlldy5uZXh0RnJhbWUpXG4gICAgfSxcblxuICAgIHJlcG9ydDogZnVuY3Rpb24gKF8sIHJlcG9ydCkge1xuICAgICAgICByZXR1cm4gVmlldy5yZXBvcnQoXywgcmVwb3J0KVxuICAgIH0sXG59KVxuXG5mdW5jdGlvbiBub29wKCkge31cblxuZnVuY3Rpb24gc2V0RGVmYXVsdHNDaGVja2VkKG9wdHMpIHtcbiAgICBpZiAob3B0cy50aXRsZSA9PSBudWxsKSBvcHRzLnRpdGxlID0gXCJUaGFsbGl1bSB0ZXN0c1wiXG4gICAgaWYgKG9wdHMudGltZW91dCA9PSBudWxsKSBvcHRzLnRpbWVvdXQgPSA1MDAwXG4gICAgaWYgKG9wdHMuZmlsZXMgPT0gbnVsbCkgb3B0cy5maWxlcyA9IFtdXG4gICAgaWYgKG9wdHMucHJlbG9hZCA9PSBudWxsKSBvcHRzLnByZWxvYWQgPSBub29wXG4gICAgaWYgKG9wdHMucHJlcnVuID09IG51bGwpIG9wdHMucHJlcnVuID0gbm9vcFxuICAgIGlmIChvcHRzLnBvc3RydW4gPT0gbnVsbCkgb3B0cy5wb3N0cnVuID0gbm9vcFxuICAgIGlmIChvcHRzLmVycm9yID09IG51bGwpIG9wdHMuZXJyb3IgPSBub29wXG4gICAgaWYgKG9wdHMudGhhbGxpdW0gPT0gbnVsbCkgb3B0cy50aGFsbGl1bSA9IGRlZmF1bHRUXG5cbiAgICBpZiAodHlwZW9mIG9wdHMudGl0bGUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBvcHRzLnRpdGxlYCBtdXN0IGJlIGEgc3RyaW5nIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy50aW1lb3V0ICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgb3B0cy50aW1lb3V0YCBtdXN0IGJlIGEgbnVtYmVyIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheShvcHRzLmZpbGVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMuZmlsZXNgIG11c3QgYmUgYW4gYXJyYXkgaWYgcGFzc2VkXCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLnByZWxvYWQgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMucHJlbG9hZGAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5wcmVydW4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMucHJlcnVuYCBtdXN0IGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLnBvc3RydW4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMucG9zdHJ1bmAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5lcnJvciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgb3B0cy5lcnJvcmAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy50aGFsbGl1bSAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgXCJgb3B0cy50aGFsbGl1bWAgbXVzdCBiZSBhIFRoYWxsaXVtIGluc3RhbmNlIGlmIHBhc3NlZFwiKVxuICAgIH1cbn1cblxuZnVuY3Rpb24gb25SZWFkeShpbml0KSB7XG4gICAgaWYgKEQuZG9jdW1lbnQuYm9keSAhPSBudWxsKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGluaXQoKSlcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgRC5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXNvbHZlKGluaXQoKSlcbiAgICAgICAgfSwgZmFsc2UpXG4gICAgfSlcbn1cblxuZnVuY3Rpb24gRE9NKG9wdHMpIHtcbiAgICB0aGlzLl9vcHRzID0gb3B0c1xuICAgIHRoaXMuX2Rlc3Ryb3lQcm9taXNlID0gdW5kZWZpbmVkXG4gICAgdGhpcy5fZGF0YSA9IG9uUmVhZHkoZnVuY3Rpb24gKCkge1xuICAgICAgICBzZXREZWZhdWx0c0NoZWNrZWQob3B0cylcbiAgICAgICAgaWYgKCFELmRvY3VtZW50LnRpdGxlKSBELmRvY3VtZW50LnRpdGxlID0gb3B0cy50aXRsZVxuICAgICAgICBpbmplY3RTdHlsZXMoKVxuICAgICAgICB2YXIgZGF0YSA9IFZpZXcuaW5pdChvcHRzKVxuXG4gICAgICAgIG9wdHMudGhhbGxpdW0ucmVwb3J0ZXIocmVwb3J0ZXIsIGRhdGEuc3RhdGUpXG4gICAgICAgIHJldHVybiBkYXRhXG4gICAgfSlcbn1cblxubWV0aG9kcyhET00sIHtcbiAgICBydW46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2Rlc3Ryb3lQcm9taXNlICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJUaGUgdGVzdCBzdWl0ZSBtdXN0IG5vdCBiZSBydW4gYWZ0ZXIgdGhlIHZpZXcgaGFzIGJlZW4gXCIgK1xuICAgICAgICAgICAgICAgIFwiZGV0YWNoZWQuXCJcbiAgICAgICAgICAgICkpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgb3B0cyA9IHRoaXMuX29wdHNcblxuICAgICAgICByZXR1cm4gdGhpcy5fZGF0YS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICByZXR1cm4gcnVuVGVzdHMob3B0cywgZGF0YS5zdGF0ZSlcbiAgICAgICAgfSlcbiAgICB9LFxuXG4gICAgZGV0YWNoOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kZXN0cm95UHJvbWlzZSAhPSBudWxsKSByZXR1cm4gdGhpcy5fZGVzdHJveVByb21pc2VcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rlc3Ryb3lQcm9taXNlID0gc2VsZi5fZGF0YS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICBkYXRhLnN0YXRlLmxvY2tlZCA9IHRydWVcbiAgICAgICAgICAgIGlmIChkYXRhLnN0YXRlLmN1cnJlbnRQcm9taXNlID09IG51bGwpIHJldHVybiBkYXRhXG4gICAgICAgICAgICByZXR1cm4gZGF0YS5zdGF0ZS5jdXJyZW50UHJvbWlzZS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRhdGEgfSlcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgIHNlbGYuX29wdHMgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIHNlbGYuX2RhdGEgPSBzZWxmLl9kZXN0cm95UHJvbWlzZVxuXG4gICAgICAgICAgICB3aGlsZSAoZGF0YS5yb290LmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBkYXRhLnJvb3QucmVtb3ZlQ2hpbGQoZGF0YS5yb290LmZpcnN0Q2hpbGQpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfSxcbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgICByZXR1cm4gbmV3IERPTShvcHRzKVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIFV0aWwgPSByZXF1aXJlKFwiLi4vdXRpbFwiKVxudmFyIEQgPSByZXF1aXJlKFwiLi9pbmplY3RcIilcblxuLyoqXG4gKiBUaGUgcmVwb3J0ZXIgc3R5bGVzaGVldC4gSGVyZSdzIHRoZSBmb3JtYXQ6XG4gKlxuICogLy8gU2luZ2xlIGl0ZW1cbiAqIFwiLnNlbGVjdG9yXCI6IHtcbiAqICAgICAvLyBwcm9wcy4uLlxuICogfVxuICpcbiAqIC8vIER1cGxpY2F0ZSBlbnRyaWVzXG4gKiBcIi5zZWxlY3RvclwiOiB7XG4gKiAgICAgXCJwcm9wXCI6IFtcbiAqICAgICAgICAgLy8gdmFsdWVzLi4uXG4gKiAgICAgXSxcbiAqIH1cbiAqXG4gKiAvLyBEdXBsaWNhdGUgc2VsZWN0b3JzXG4gKiBcIi5zZWxlY3RvclwiOiBbXG4gKiAgICAgLy8gdmFsdWVzLi4uXG4gKiBdXG4gKlxuICogLy8gTWVkaWEgcXVlcnlcbiAqIFwiQG1lZGlhIHNjcmVlblwiOiB7XG4gKiAgICAgLy8gc2VsZWN0b3JzLi4uXG4gKiB9XG4gKlxuICogTm90ZSB0aGF0IENTUyBzdHJpbmdzICptdXN0KiBiZSBxdW90ZWQgaW5zaWRlIHRoZSB2YWx1ZS5cbiAqL1xuXG52YXIgc3R5bGVzID0gVXRpbC5sYXp5KGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eVxuXG4gICAgLyoqXG4gICAgICogUGFydGlhbGx5IHRha2VuIGFuZCBhZGFwdGVkIGZyb20gbm9ybWFsaXplLmNzcyAobGljZW5zZWQgdW5kZXIgdGhlIE1JVFxuICAgICAqIExpY2Vuc2UpLlxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9uZWNvbGFzL25vcm1hbGl6ZS5jc3NcbiAgICAgKi9cbiAgICB2YXIgc3R5bGVPYmplY3QgPSB7XG4gICAgICAgIFwiI3RsXCI6IHtcbiAgICAgICAgICAgIFwiZm9udC1mYW1pbHlcIjogXCJzYW5zLXNlcmlmXCIsXG4gICAgICAgICAgICBcImxpbmUtaGVpZ2h0XCI6IFwiMS4xNVwiLFxuICAgICAgICAgICAgXCItbXMtdGV4dC1zaXplLWFkanVzdFwiOiBcIjEwMCVcIixcbiAgICAgICAgICAgIFwiLXdlYmtpdC10ZXh0LXNpemUtYWRqdXN0XCI6IFwiMTAwJVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIGJ1dHRvblwiOiB7XG4gICAgICAgICAgICBcImZvbnQtZmFtaWx5XCI6IFwic2Fucy1zZXJpZlwiLFxuICAgICAgICAgICAgXCJsaW5lLWhlaWdodFwiOiBcIjEuMTVcIixcbiAgICAgICAgICAgIFwib3ZlcmZsb3dcIjogXCJ2aXNpYmxlXCIsXG4gICAgICAgICAgICBcImZvbnQtc2l6ZVwiOiBcIjEwMCVcIixcbiAgICAgICAgICAgIFwibWFyZ2luXCI6IFwiMFwiLFxuICAgICAgICAgICAgXCJ0ZXh0LXRyYW5zZm9ybVwiOiBcIm5vbmVcIixcbiAgICAgICAgICAgIFwiLXdlYmtpdC1hcHBlYXJhbmNlXCI6IFwiYnV0dG9uXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgaDFcIjoge1xuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIyZW1cIixcbiAgICAgICAgICAgIFwibWFyZ2luXCI6IFwiMC42N2VtIDBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCBhXCI6IHtcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcInRyYW5zcGFyZW50XCIsXG4gICAgICAgICAgICBcIi13ZWJraXQtdGV4dC1kZWNvcmF0aW9uLXNraXBcIjogXCJvYmplY3RzXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgYTphY3RpdmUsICN0bCBhOmhvdmVyXCI6IHtcbiAgICAgICAgICAgIFwib3V0bGluZS13aWR0aFwiOiBcIjBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCBidXR0b246Oi1tb3otZm9jdXMtaW5uZXJcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItc3R5bGVcIjogXCJub25lXCIsXG4gICAgICAgICAgICBcInBhZGRpbmdcIjogXCIwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgYnV0dG9uOi1tb3otZm9jdXNyaW5nXCI6IHtcbiAgICAgICAgICAgIG91dGxpbmU6IFwiMXB4IGRvdHRlZCBCdXR0b25UZXh0XCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEJhc2Ugc3R5bGVzLiBOb3RlIHRoYXQgdGhpcyBDU1MgaXMgZGVzaWduZWQgdG8gaW50ZW50aW9uYWxseSBvdmVycmlkZVxuICAgICAgICAgKiBtb3N0IHRoaW5ncyB0aGF0IGNvdWxkIHByb3BhZ2F0ZS5cbiAgICAgICAgICovXG4gICAgICAgIFwiI3RsICpcIjogW1xuICAgICAgICAgICAge1widGV4dC1hbGlnblwiOiBcImxlZnRcIn0sXG4gICAgICAgICAgICB7XCJ0ZXh0LWFsaWduXCI6IFwic3RhcnRcIn0sXG4gICAgICAgIF0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydCwgI3RsIC50bC1yZXBvcnQgdWxcIjoge1xuICAgICAgICAgICAgXCJsaXN0LXN0eWxlLXR5cGVcIjogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgbGkgfiAudGwtc3VpdGVcIjoge1xuICAgICAgICAgICAgXCJwYWRkaW5nLXRvcFwiOiBcIjFlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1zdWl0ZSA+IGgyXCI6IHtcbiAgICAgICAgICAgIFwiY29sb3JcIjogXCJibGFja1wiLFxuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIxLjVlbVwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcImJvbGRcIixcbiAgICAgICAgICAgIFwibWFyZ2luLWJvdHRvbVwiOiBcIjAuNWVtXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXN1aXRlIC50bC1zdWl0ZSA+IGgyXCI6IHtcbiAgICAgICAgICAgIFwiZm9udC1zaXplXCI6IFwiMS4yZW1cIixcbiAgICAgICAgICAgIFwibWFyZ2luLWJvdHRvbVwiOiBcIjAuM2VtXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXN1aXRlIC50bC1zdWl0ZSAudGwtc3VpdGUgPiBoMlwiOiB7XG4gICAgICAgICAgICBcImZvbnQtc2l6ZVwiOiBcIjEuMmVtXCIsXG4gICAgICAgICAgICBcIm1hcmdpbi1ib3R0b21cIjogXCIwLjJlbVwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcIm5vcm1hbFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0ID4gaDJcIjoge1xuICAgICAgICAgICAgXCJjb2xvclwiOiBcImJsYWNrXCIsXG4gICAgICAgICAgICBcImZvbnQtc2l6ZVwiOiBcIjFlbVwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcIm5vcm1hbFwiLFxuICAgICAgICAgICAgXCJtYXJnaW5cIjogXCIwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRlc3QgPiA6Zmlyc3QtY2hpbGQ6OmJlZm9yZVwiOiB7XG4gICAgICAgICAgICBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgICAgICAgIFwiZm9udC13ZWlnaHRcIjogXCJib2xkXCIsXG4gICAgICAgICAgICBcIndpZHRoXCI6IFwiMS4yZW1cIixcbiAgICAgICAgICAgIFwidGV4dC1hbGlnblwiOiBcImNlbnRlclwiLFxuICAgICAgICAgICAgXCJmb250LWZhbWlseVwiOiBcInNhbnMtc2VyaWZcIixcbiAgICAgICAgICAgIFwidGV4dC1zaGFkb3dcIjogXCIwIDNweCAycHggIzk2OTY5NlwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0LnRsLWZhaWwgPiBoMiwgI3RsIC50bC10ZXN0LnRsLWVycm9yID4gaDJcIjoge1xuICAgICAgICAgICAgY29sb3I6IFwiI2MwMFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0LnRsLXNraXAgPiBoMlwiOiB7XG4gICAgICAgICAgICBjb2xvcjogXCIjMDhjXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRlc3QudGwtcGFzcyA+IDpmaXJzdC1jaGlsZDo6YmVmb3JlXCI6IHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFwiJ+KckydcIixcbiAgICAgICAgICAgIGNvbG9yOiBcIiMwYzBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdGVzdC50bC1mYWlsID4gOmZpcnN0LWNoaWxkOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCIn4pyWJ1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0LnRsLWVycm9yID4gOmZpcnN0LWNoaWxkOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCInISdcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdGVzdC50bC1za2lwID4gOmZpcnN0LWNoaWxkOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCIn4oiSJ1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1wcmUsICN0bCAudGwtZGlmZi1oZWFkZXJcIjoge1xuICAgICAgICAgICAgLy8gbm9ybWFsaXplLmNzczogQ29ycmVjdCB0aGUgaW5oZXJpdGFuY2UgYW5kIHNjYWxpbmcgb2YgZm9udCBzaXplXG4gICAgICAgICAgICAvLyBpbiBhbGwgYnJvd3NlcnNcbiAgICAgICAgICAgIFwiZm9udC1mYW1pbHlcIjogXCJtb25vc3BhY2UsIG1vbm9zcGFjZVwiLFxuICAgICAgICAgICAgXCJiYWNrZ3JvdW5kXCI6IFwiI2YwZjBmMFwiLFxuICAgICAgICAgICAgXCJ3aGl0ZS1zcGFjZVwiOiBcInByZVwiLFxuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIwLjg1ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtcHJlXCI6IHtcbiAgICAgICAgICAgIFwibWluLXdpZHRoXCI6IFwiMTAwJVwiLFxuICAgICAgICAgICAgXCJmbG9hdFwiOiBcImxlZnRcIixcbiAgICAgICAgICAgIFwiY2xlYXJcIjogXCJsZWZ0XCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLWxpbmVcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJibG9ja1wiLFxuICAgICAgICAgICAgbWFyZ2luOiBcIjAgMC4yNWVtXCIsXG4gICAgICAgICAgICB3aWR0aDogXCI5OSVcIiwgLy8gQmVjYXVzZSBGaXJlZm94IHN1Y2tzXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLWRpZmYtaGVhZGVyID4gKlwiOiB7XG4gICAgICAgICAgICBwYWRkaW5nOiBcIjAuMjVlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1kaWZmLWhlYWRlclwiOiB7XG4gICAgICAgICAgICBcInBhZGRpbmdcIjogXCIwLjI1ZW1cIixcbiAgICAgICAgICAgIFwibWFyZ2luLWJvdHRvbVwiOiBcIjAuNWVtXCIsXG4gICAgICAgICAgICBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtbGluZTpmaXJzdC1jaGlsZCwgI3RsIC50bC1kaWZmLWhlYWRlciB+IC50bC1saW5lXCI6IHtcbiAgICAgICAgICAgIFwicGFkZGluZy10b3BcIjogXCIwLjI1ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtbGluZTpsYXN0LWNoaWxkXCI6IHtcbiAgICAgICAgICAgIFwicGFkZGluZy1ib3R0b21cIjogXCIwLjI1ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZmFpbCAudGwtZGlzcGxheVwiOiB7XG4gICAgICAgICAgICBtYXJnaW46IFwiMC41ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZGlzcGxheSA+ICpcIjoge1xuICAgICAgICAgICAgb3ZlcmZsb3c6IFwiYXV0b1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1kaXNwbGF5ID4gOm5vdCg6bGFzdC1jaGlsZClcIjoge1xuICAgICAgICAgICAgXCJtYXJnaW4tYm90dG9tXCI6IFwiMC41ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZGlmZi1hZGRlZFwiOiB7XG4gICAgICAgICAgICBcImNvbG9yXCI6IFwiIzBjMFwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcImJvbGRcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZGlmZi1yZW1vdmVkXCI6IHtcbiAgICAgICAgICAgIFwiY29sb3JcIjogXCIjYzAwXCIsXG4gICAgICAgICAgICBcImZvbnQtd2VpZ2h0XCI6IFwiYm9sZFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1zdGFjayAudGwtbGluZVwiOiB7XG4gICAgICAgICAgICBjb2xvcjogXCIjODAwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLWRpZmY6OmJlZm9yZSwgI3RsIC50bC1zdGFjazo6YmVmb3JlXCI6IHtcbiAgICAgICAgICAgIFwiZm9udC13ZWlnaHRcIjogXCJub3JtYWxcIixcbiAgICAgICAgICAgIFwibWFyZ2luXCI6IFwiMC4yNWVtIDAuMjVlbSAwLjI1ZW0gMFwiLFxuICAgICAgICAgICAgXCJkaXNwbGF5XCI6IFwiYmxvY2tcIixcbiAgICAgICAgICAgIFwiZm9udC1zdHlsZVwiOiBcIml0YWxpY1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1kaWZmOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCInRGlmZjonXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXN0YWNrOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCInU3RhY2s6J1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1oZWFkZXJcIjoge1xuICAgICAgICAgICAgXCJ0ZXh0LWFsaWduXCI6IFwicmlnaHRcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtaGVhZGVyID4gKlwiOiB7XG4gICAgICAgICAgICBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgICAgICAgIFwidGV4dC1hbGlnblwiOiBcImNlbnRlclwiLFxuICAgICAgICAgICAgXCJwYWRkaW5nXCI6IFwiMC41ZW0gMC43NWVtXCIsXG4gICAgICAgICAgICBcImJvcmRlclwiOiBcIjJweCBzb2xpZCAjMDBjXCIsXG4gICAgICAgICAgICBcImJvcmRlci1yYWRpdXNcIjogXCIxZW1cIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcInRyYW5zcGFyZW50XCIsXG4gICAgICAgICAgICBcIm1hcmdpblwiOiBcIjAuMjVlbSAwLjVlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1oZWFkZXIgPiA6Zm9jdXNcIjoge1xuICAgICAgICAgICAgb3V0bGluZTogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJ1blwiOiB7XG4gICAgICAgICAgICBcImJvcmRlci1jb2xvclwiOiBcIiMwODBcIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcIiMwYzBcIixcbiAgICAgICAgICAgIFwiY29sb3JcIjogXCJ3aGl0ZVwiLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiBcIjZlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1ydW46aG92ZXJcIjoge1xuICAgICAgICAgICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCI6IFwiIzhjOFwiLFxuICAgICAgICAgICAgXCJjb2xvclwiOiBcIndoaXRlXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1wYXNzXCI6IHtcbiAgICAgICAgICAgIFwiYm9yZGVyLWNvbG9yXCI6IFwiIzBjMFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10b2dnbGUudGwtZmFpbFwiOiB7XG4gICAgICAgICAgICBcImJvcmRlci1jb2xvclwiOiBcIiNjMDBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdG9nZ2xlLnRsLXNraXBcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDhjXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1wYXNzLnRsLWFjdGl2ZSwgI3RsIC50bC10b2dnbGUudGwtcGFzczphY3RpdmVcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDgwXCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjMGMwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1mYWlsLnRsLWFjdGl2ZSwgI3RsIC50bC10b2dnbGUudGwtZmFpbDphY3RpdmVcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjODAwXCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjYzAwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1za2lwLnRsLWFjdGl2ZSwgI3RsIC50bC10b2dnbGUudGwtc2tpcDphY3RpdmVcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDU4XCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjMDhjXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1wYXNzOmhvdmVyXCI6IHtcbiAgICAgICAgICAgIFwiYm9yZGVyLWNvbG9yXCI6IFwiIzBjMFwiLFxuICAgICAgICAgICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCI6IFwiI2FmYVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10b2dnbGUudGwtZmFpbDpob3ZlclwiOiB7XG4gICAgICAgICAgICBcImJvcmRlci1jb2xvclwiOiBcIiNjMDBcIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcIiNmYWFcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdG9nZ2xlLnRsLXNraXA6aG92ZXJcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDhjXCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjYmRmXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydC50bC1wYXNzIC50bC10ZXN0Om5vdCgudGwtcGFzcylcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydC50bC1mYWlsIC50bC10ZXN0Om5vdCgudGwtZmFpbClcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydC50bC1za2lwIC50bC10ZXN0Om5vdCgudGwtc2tpcClcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJub25lXCIsXG4gICAgICAgIH0sXG4gICAgfVxuXG4gICAgdmFyIGNzcyA9IFwiXCJcblxuICAgIGZ1bmN0aW9uIGFwcGVuZEJhc2Uoc2VsZWN0b3IsIHByb3BzKSB7XG4gICAgICAgIGNzcyArPSBzZWxlY3RvciArIFwie1wiXG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocHJvcHMpKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgYXBwZW5kUHJvcHMocHJvcHNbaV0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhcHBlbmRQcm9wcyhwcm9wcylcbiAgICAgICAgfVxuXG4gICAgICAgIGNzcyArPSBcIn1cIlxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFwcGVuZFByb3BzKHByb3BzKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBwcm9wcykge1xuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKHByb3BzLCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwcm9wc1trZXldID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGFwcGVuZEJhc2Uoa2V5LCBwcm9wc1trZXldKVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNzcyArPSBrZXkgKyBcIjpcIiArIHByb3BzW2tleV0gKyBcIjtcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIHNlbGVjdG9yIGluIHN0eWxlT2JqZWN0KSB7XG4gICAgICAgIGlmIChoYXNPd24uY2FsbChzdHlsZU9iamVjdCwgc2VsZWN0b3IpKSB7XG4gICAgICAgICAgICBhcHBlbmRCYXNlKHNlbGVjdG9yLCBzdHlsZU9iamVjdFtzZWxlY3Rvcl0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY3NzLmNvbmNhdCgpIC8vIEhpbnQgdG8gZmxhdHRlbi5cbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICAgIGlmIChELmRvY3VtZW50LmhlYWQucXVlcnlTZWxlY3RvcihcInN0eWxlW2RhdGEtdGwtc3R5bGVdXCIpID09IG51bGwpIHtcbiAgICAgICAgdmFyIHN0eWxlID0gRC5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIilcblxuICAgICAgICBzdHlsZS50eXBlID0gXCJ0ZXh0L2Nzc1wiXG4gICAgICAgIHN0eWxlLnNldEF0dHJpYnV0ZShcImRhdGEtdGwtc3R5bGVcIiwgXCJcIilcbiAgICAgICAgaWYgKHN0eWxlLnN0eWxlU2hlZXQpIHtcbiAgICAgICAgICAgIHN0eWxlLnN0eWxlU2hlZXQuY3NzVGV4dCA9IHN0eWxlcygpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHlsZS5hcHBlbmRDaGlsZChELmRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN0eWxlcygpKSlcbiAgICAgICAgfVxuXG4gICAgICAgIEQuZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSlcbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vKipcbiAqIFRoZSBnbG9iYWwgaW5qZWN0aW9ucyBmb3IgdGhlIERPTS4gTWFpbmx5IGZvciBkZWJ1Z2dpbmcuXG4gKi9cblxuZXhwb3J0cy5kb2N1bWVudCA9IGdsb2JhbC5kb2N1bWVudFxuZXhwb3J0cy53aW5kb3cgPSBnbG9iYWwud2luZG93XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpXG52YXIgRCA9IHJlcXVpcmUoXCIuL2luamVjdFwiKVxudmFyIG5vdyA9IERhdGUubm93IC8vIEF2b2lkIFNpbm9uJ3MgbW9ja1xudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuLyoqXG4gKiBUZXN0IHJ1bm5lciBhbmQgc2NyaXB0IGxvYWRlclxuICovXG5cbmZ1bmN0aW9uIHVuY2FjaGVkKGZpbGUpIHtcbiAgICBpZiAoZmlsZS5pbmRleE9mKFwiP1wiKSA8IDApIHtcbiAgICAgICAgcmV0dXJuIGZpbGUgKyBcIj9sb2FkZWQ9XCIgKyBub3coKVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmaWxlICsgXCImbG9hZGVkPVwiICsgbm93KClcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxvYWRTY3JpcHQoZmlsZSwgdGltZW91dCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHZhciBzY3JpcHQgPSBELmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIilcbiAgICAgICAgdmFyIHRpbWVyID0gZ2xvYmFsLnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY2xlYXIoKVxuICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIlRpbWVvdXQgZXhjZWVkZWQgbG9hZGluZyAnXCIgKyBmaWxlICsgXCInXCIpKVxuICAgICAgICB9LCB0aW1lb3V0KVxuXG4gICAgICAgIGZ1bmN0aW9uIGNsZWFyKGV2KSB7XG4gICAgICAgICAgICBpZiAoZXYgIT0gbnVsbCkgZXYucHJldmVudERlZmF1bHQoKVxuICAgICAgICAgICAgaWYgKGV2ICE9IG51bGwpIGV2LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICAgICAgICBnbG9iYWwuY2xlYXJUaW1lb3V0KHRpbWVyKVxuICAgICAgICAgICAgc2NyaXB0Lm9ubG9hZCA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgc2NyaXB0Lm9uZXJyb3IgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIEQuZG9jdW1lbnQuaGVhZC5yZW1vdmVDaGlsZChzY3JpcHQpXG4gICAgICAgIH1cblxuICAgICAgICBzY3JpcHQuc3JjID0gdW5jYWNoZWQoZmlsZSlcbiAgICAgICAgc2NyaXB0LmFzeW5jID0gdHJ1ZVxuICAgICAgICBzY3JpcHQuZGVmZXIgPSB0cnVlXG4gICAgICAgIHNjcmlwdC5vbmxvYWQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIGNsZWFyKGV2KVxuICAgICAgICAgICAgcmVzb2x2ZSgpXG4gICAgICAgIH1cblxuICAgICAgICBzY3JpcHQub25lcnJvciA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgY2xlYXIoZXYpXG4gICAgICAgICAgICByZWplY3QoZXYpXG4gICAgICAgIH1cblxuICAgICAgICBELmRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIHRyeURlbGV0ZShrZXkpIHtcbiAgICB0cnkge1xuICAgICAgICBkZWxldGUgZ2xvYmFsW2tleV1cbiAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgIC8vIGlnbm9yZVxuICAgIH1cbn1cblxuZnVuY3Rpb24gZGVzY3JpcHRvckNoYW5nZWQoYSwgYikge1xuICAgIC8vIE5vdGU6IGlmIHRoZSBkZXNjcmlwdG9yIHdhcyByZW1vdmVkLCBpdCB3b3VsZCd2ZSBiZWVuIGRlbGV0ZWQsIGFueXdheXMuXG4gICAgaWYgKGEgPT0gbnVsbCkgcmV0dXJuIGZhbHNlXG4gICAgaWYgKGEuY29uZmlndXJhYmxlICE9PSBiLmNvbmZpZ3VyYWJsZSkgcmV0dXJuIHRydWVcbiAgICBpZiAoYS5lbnVtZXJhYmxlICE9PSBiLmVudW1lcmFibGUpIHJldHVybiB0cnVlXG4gICAgaWYgKGEud3JpdGFibGUgIT09IGIud3JpdGFibGUpIHJldHVybiB0cnVlXG4gICAgaWYgKGEuZ2V0ICE9PSBiLmdldCkgcmV0dXJuIHRydWVcbiAgICBpZiAoYS5zZXQgIT09IGIuc2V0KSByZXR1cm4gdHJ1ZVxuICAgIGlmIChhLnZhbHVlICE9PSBiLnZhbHVlKSByZXR1cm4gdHJ1ZVxuICAgIHJldHVybiBmYWxzZVxufVxuXG4vLyBUaGVzZSBmaXJlIGRlcHJlY2F0aW9uIHdhcm5pbmdzLCBhbmQgdGh1cyBzaG91bGQgYmUgYXZvaWRlZC5cbnZhciBibGFja2xpc3QgPSBPYmplY3QuZnJlZXplKHtcbiAgICB3ZWJraXRTdG9yYWdlSW5mbzogdHJ1ZSxcbiAgICB3ZWJraXRJbmRleGVkREI6IHRydWUsXG59KVxuXG5mdW5jdGlvbiBmaW5kR2xvYmFscygpIHtcbiAgICB2YXIgZm91bmQgPSBPYmplY3Qua2V5cyhnbG9iYWwpXG4gICAgdmFyIGdsb2JhbHMgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZvdW5kLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBmb3VuZFtpXVxuXG4gICAgICAgIGlmICghaGFzT3duLmNhbGwoYmxhY2tsaXN0LCBrZXkpKSB7XG4gICAgICAgICAgICBnbG9iYWxzW2tleV0gPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGdsb2JhbCwga2V5KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGdsb2JhbHNcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0cywgc3RhdGUpIHtcbiAgICBpZiAoc3RhdGUubG9ja2VkKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICBcIlRoZSB0ZXN0IHN1aXRlIG11c3Qgbm90IGJlIHJ1biBhZnRlciB0aGUgdmlldyBoYXMgYmVlbiBkZXRhY2hlZC5cIlxuICAgICAgICApKVxuICAgIH1cblxuICAgIGlmIChzdGF0ZS5jdXJyZW50UHJvbWlzZSAhPSBudWxsKSByZXR1cm4gc3RhdGUuY3VycmVudFByb21pc2VcblxuICAgIG9wdHMudGhhbGxpdW0uY2xlYXJUZXN0cygpXG5cbiAgICAvLyBEZXRlY3QgYW5kIHJlbW92ZSBnbG9iYWxzIGNyZWF0ZWQgYnkgbG9hZGVkIHNjcmlwdHMuXG4gICAgdmFyIGdsb2JhbHMgPSBmaW5kR2xvYmFscygpXG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgICAgICB2YXIgZm91bmQgPSBPYmplY3Qua2V5cyhnbG9iYWwpXG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmb3VuZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGtleSA9IGZvdW5kW2ldXG5cbiAgICAgICAgICAgIGlmICghaGFzT3duLmNhbGwoZ2xvYmFscywga2V5KSkge1xuICAgICAgICAgICAgICAgIHRyeURlbGV0ZShrZXkpXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGRlc2NyaXB0b3JDaGFuZ2VkKFxuICAgICAgICAgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZ2xvYmFsLCBrZXkpLFxuICAgICAgICAgICAgICAgIGdsb2JhbHNba2V5XVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgIHRyeURlbGV0ZShrZXkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5jdXJyZW50UHJvbWlzZSA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIHJldHVybiBzdGF0ZS5jdXJyZW50UHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICBzdGF0ZS5wYXNzLnRleHRDb250ZW50ID0gXCIwXCJcbiAgICAgICAgc3RhdGUuZmFpbC50ZXh0Q29udGVudCA9IFwiMFwiXG4gICAgICAgIHN0YXRlLnNraXAudGV4dENvbnRlbnQgPSBcIjBcIlxuICAgICAgICByZXR1cm4gb3B0cy5wcmVsb2FkKClcbiAgICB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFV0aWwucGVhY2gob3B0cy5maWxlcywgZnVuY3Rpb24gKGZpbGUpIHtcbiAgICAgICAgICAgIHJldHVybiBsb2FkU2NyaXB0KGZpbGUsIG9wdHMudGltZW91dClcbiAgICAgICAgfSlcbiAgICB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIG9wdHMucHJlcnVuKCkgfSlcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBvcHRzLnRoYWxsaXVtLnJ1bigpIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gb3B0cy5wb3N0cnVuKCkgfSlcbiAgICAuY2F0Y2goZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShvcHRzLmVycm9yKGUpKS50aGVuKGZ1bmN0aW9uICgpIHsgdGhyb3cgZSB9KVxuICAgIH0pXG4gICAgLnRoZW4oXG4gICAgICAgIGZ1bmN0aW9uICgpIHsgY2xlYW51cCgpIH0sXG4gICAgICAgIGZ1bmN0aW9uIChlKSB7IGNsZWFudXAoKTsgdGhyb3cgZSB9KVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIGRpZmYgPSByZXF1aXJlKFwiZGlmZlwiKVxudmFyIFIgPSByZXF1aXJlKFwiLi4vcmVwb3J0ZXJcIilcbnZhciBEID0gcmVxdWlyZShcIi4vaW5qZWN0XCIpXG52YXIgcnVuVGVzdHMgPSByZXF1aXJlKFwiLi9ydW4tdGVzdHNcIilcbnZhciBpbnNwZWN0ID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpLmluc3BlY3RcblxuLyoqXG4gKiBWaWV3IGxvZ2ljXG4gKi9cblxuZnVuY3Rpb24gdCh0ZXh0KSB7XG4gICAgcmV0dXJuIEQuZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dClcbn1cblxuZnVuY3Rpb24gaCh0eXBlLCBhdHRycywgY2hpbGRyZW4pIHtcbiAgICB2YXIgcGFydHMgPSB0eXBlLnNwbGl0KC9cXHMrL2cpXG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShhdHRycykpIHtcbiAgICAgICAgY2hpbGRyZW4gPSBhdHRyc1xuICAgICAgICBhdHRycyA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmIChhdHRycyA9PSBudWxsKSBhdHRycyA9IHt9XG4gICAgaWYgKGNoaWxkcmVuID09IG51bGwpIGNoaWxkcmVuID0gW11cblxuICAgIHR5cGUgPSBwYXJ0c1swXVxuICAgIGF0dHJzLmNsYXNzTmFtZSA9IHBhcnRzLnNsaWNlKDEpLmpvaW4oXCIgXCIpXG5cbiAgICB2YXIgZWxlbSA9IEQuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0eXBlKVxuXG4gICAgT2JqZWN0LmtleXMoYXR0cnMpLmZvckVhY2goZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgICAgZWxlbVthdHRyXSA9IGF0dHJzW2F0dHJdXG4gICAgfSlcblxuICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIGlmIChjaGlsZCAhPSBudWxsKSBlbGVtLmFwcGVuZENoaWxkKGNoaWxkKVxuICAgIH0pXG5cbiAgICByZXR1cm4gZWxlbVxufVxuXG5mdW5jdGlvbiB1bmlmaWVkRGlmZihlcnIpIHtcbiAgICB2YXIgYWN0dWFsID0gaW5zcGVjdChlcnIuYWN0dWFsKVxuICAgIHZhciBleHBlY3RlZCA9IGluc3BlY3QoZXJyLmV4cGVjdGVkKVxuICAgIHZhciBtc2cgPSBkaWZmLmNyZWF0ZVBhdGNoKFwic3RyaW5nXCIsIGFjdHVhbCwgZXhwZWN0ZWQpXG4gICAgICAgIC5zcGxpdCgvXFxyP1xcbnxcXHIvZykuc2xpY2UoNClcbiAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gIS9eXFxAXFxAfF5cXFxcIE5vIG5ld2xpbmUvLnRlc3QobGluZSkgfSlcbiAgICB2YXIgZW5kID0gbXNnLmxlbmd0aFxuXG4gICAgd2hpbGUgKGVuZCAhPT0gMCAmJiAvXlxccyokL2cudGVzdChtc2dbZW5kIC0gMV0pKSBlbmQtLVxuICAgIHJldHVybiBoKFwiZGl2IHRsLWRpZmZcIiwgW1xuICAgICAgICBoKFwiZGl2IHRsLWRpZmYtaGVhZGVyXCIsIFtcbiAgICAgICAgICAgIGgoXCJzcGFuIHRsLWRpZmYtYWRkZWRcIiwgW3QoXCIrIGV4cGVjdGVkXCIpXSksXG4gICAgICAgICAgICBoKFwic3BhbiB0bC1kaWZmLXJlbW92ZWRcIiwgW3QoXCItIGFjdHVhbFwiKV0pLFxuICAgICAgICBdKSxcbiAgICAgICAgaChcImRpdiB0bC1wcmVcIiwgIWVuZFxuICAgICAgICAgICAgPyBbaChcInNwYW4gdGwtbGluZSB0bC1kaWZmLWFkZGVkXCIsIFt0KFwiIChub25lKVwiKV0pXVxuICAgICAgICAgICAgOiBtc2cuc2xpY2UoMCwgZW5kKVxuICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gbGluZS50cmltUmlnaHQoKSB9KVxuICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAobGluZSkge1xuICAgICAgICAgICAgICAgIGlmIChsaW5lWzBdID09PSBcIitcIikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaChcInNwYW4gdGwtbGluZSB0bC1kaWZmLWFkZGVkXCIsIFt0KGxpbmUpXSlcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGxpbmVbMF0gPT09IFwiLVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBoKFwic3BhbiB0bC1saW5lIHRsLWRpZmYtcmVtb3ZlZFwiLCBbdChsaW5lKV0pXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGgoXCJzcGFuIHRsLWxpbmUgdGwtZGlmZi1ub25lXCIsIFt0KGxpbmUpXSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICApLFxuICAgIF0pXG59XG5cbmZ1bmN0aW9uIHRvTGluZXMoc3RyKSB7XG4gICAgcmV0dXJuIGgoXCJkaXYgdGwtcHJlXCIsIHN0ci5zcGxpdCgvXFxyP1xcbnxcXHIvZykubWFwKGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIHJldHVybiBoKFwic3BhbiB0bC1saW5lXCIsIFt0KGxpbmUudHJpbVJpZ2h0KCkpXSlcbiAgICB9KSlcbn1cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IoZSwgc2hvd0RpZmYpIHtcbiAgICB2YXIgc3RhY2sgPSBSLnJlYWRTdGFjayhlKVxuXG4gICAgcmV0dXJuIGgoXCJkaXYgdGwtZGlzcGxheVwiLCBbXG4gICAgICAgIGgoXCJkaXYgdGwtbWVzc2FnZVwiLCBbdG9MaW5lcyhlLm5hbWUgKyBcIjogXCIgKyBlLm1lc3NhZ2UpXSksXG4gICAgICAgIHNob3dEaWZmID8gdW5pZmllZERpZmYoZSkgOiB1bmRlZmluZWQsXG4gICAgICAgIHN0YWNrID8gaChcImRpdiB0bC1zdGFja1wiLCBbdG9MaW5lcyhzdGFjayldKSA6IHVuZGVmaW5lZCxcbiAgICBdKVxufVxuXG5mdW5jdGlvbiBzaG93VGVzdChfLCByZXBvcnQsIGNsYXNzTmFtZSwgY2hpbGQpIHtcbiAgICB2YXIgZW5kID0gcmVwb3J0LnBhdGgubGVuZ3RoIC0gMVxuICAgIHZhciBuYW1lID0gcmVwb3J0LnBhdGhbZW5kXS5uYW1lXG4gICAgdmFyIHBhcmVudCA9IF8uZ2V0KHJlcG9ydC5wYXRoLCBlbmQpXG4gICAgdmFyIHNwZWVkID0gUi5zcGVlZChyZXBvcnQpXG5cbiAgICBpZiAoc3BlZWQgPT09IFwiZmFzdFwiKSB7XG4gICAgICAgIHBhcmVudC5ub2RlLmFwcGVuZENoaWxkKGgoXCJsaSBcIiArIGNsYXNzTmFtZSArIFwiIHRsLWZhc3RcIiwgW1xuICAgICAgICAgICAgaChcImgyXCIsIFt0KG5hbWUpXSksXG4gICAgICAgICAgICBjaGlsZCxcbiAgICAgICAgXSkpXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcGFyZW50Lm5vZGUuYXBwZW5kQ2hpbGQoaChcImxpIFwiICsgY2xhc3NOYW1lICsgXCIgdGwtXCIgKyBzcGVlZCwgW1xuICAgICAgICAgICAgaChcImgyXCIsIFtcbiAgICAgICAgICAgICAgICB0KG5hbWUgKyBcIiAoXCIpLFxuICAgICAgICAgICAgICAgIGgoXCJzcGFuIHRsLWR1cmF0aW9uXCIsIFt0KFIuZm9ybWF0VGltZShyZXBvcnQuZHVyYXRpb24pKV0pLFxuICAgICAgICAgICAgICAgIHQoXCIpXCIpLFxuICAgICAgICAgICAgXSksXG4gICAgICAgICAgICBjaGlsZCxcbiAgICAgICAgXSkpXG4gICAgfVxuXG4gICAgXy5vcHRzLmR1cmF0aW9uLnRleHRDb250ZW50ID0gUi5mb3JtYXRUaW1lKF8uZHVyYXRpb24pXG59XG5cbmZ1bmN0aW9uIHNob3dTa2lwKF8sIHJlcG9ydCkge1xuICAgIHZhciBlbmQgPSByZXBvcnQucGF0aC5sZW5ndGggLSAxXG4gICAgdmFyIG5hbWUgPSByZXBvcnQucGF0aFtlbmRdLm5hbWVcbiAgICB2YXIgcGFyZW50ID0gXy5nZXQocmVwb3J0LnBhdGgsIGVuZClcblxuICAgIHBhcmVudC5ub2RlLmFwcGVuZENoaWxkKGgoXCJsaSB0bC10ZXN0IHRsLXNraXBcIiwgW1xuICAgICAgICBoKFwiaDJcIiwgW3QobmFtZSldKSxcbiAgICBdKSlcbn1cblxuZXhwb3J0cy5uZXh0RnJhbWUgPSBuZXh0RnJhbWVcbmZ1bmN0aW9uIG5leHRGcmFtZShmdW5jKSB7XG4gICAgaWYgKEQud2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSkge1xuICAgICAgICBELndpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuYylcbiAgICB9IGVsc2Uge1xuICAgICAgICBnbG9iYWwuc2V0VGltZW91dChmdW5jLCAwKVxuICAgIH1cbn1cblxuZXhwb3J0cy5yZXBvcnQgPSBmdW5jdGlvbiAoXywgcmVwb3J0KSB7XG4gICAgaWYgKHJlcG9ydC5pc1N0YXJ0KSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIGVsZW1lbnQgZmlyc3QsIGp1c3QgaW4gY2FzZS5cbiAgICAgICAgICAgIHdoaWxlIChfLm9wdHMucmVwb3J0LmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBfLm9wdHMucmVwb3J0LnJlbW92ZUNoaWxkKF8ub3B0cy5yZXBvcnQuZmlyc3RDaGlsZClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRGVmZXIgdGhlIG5leHQgZnJhbWUsIHNvIHRoZSBjdXJyZW50IGNoYW5nZXMgY2FuIGJlIHNlbnQsIGluIGNhc2VcbiAgICAgICAgICAgIC8vIGl0J3MgY2xlYXJpbmcgb2xkIHRlc3QgcmVzdWx0cyBmcm9tIGEgbGFyZ2Ugc3VpdGUuIChDaHJvbWUgZG9lc1xuICAgICAgICAgICAgLy8gYmV0dGVyIGJhdGNoaW5nIHRoaXMgd2F5LCBhdCBsZWFzdC4pXG4gICAgICAgICAgICBuZXh0RnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF8uZ2V0KHVuZGVmaW5lZCwgMCkubm9kZSA9IF8ub3B0cy5yZXBvcnRcbiAgICAgICAgICAgICAgICBfLm9wdHMuZHVyYXRpb24udGV4dENvbnRlbnQgPSBSLmZvcm1hdFRpbWUoMClcbiAgICAgICAgICAgICAgICBfLm9wdHMucGFzcy50ZXh0Q29udGVudCA9IFwiMFwiXG4gICAgICAgICAgICAgICAgXy5vcHRzLmZhaWwudGV4dENvbnRlbnQgPSBcIjBcIlxuICAgICAgICAgICAgICAgIF8ub3B0cy5za2lwLnRleHRDb250ZW50ID0gXCIwXCJcbiAgICAgICAgICAgICAgICByZXNvbHZlKClcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFbnRlcikge1xuICAgICAgICB2YXIgY2hpbGQgPSBoKFwidWxcIilcblxuICAgICAgICBfLmdldChyZXBvcnQucGF0aCkubm9kZSA9IGNoaWxkXG4gICAgICAgIHNob3dUZXN0KF8sIHJlcG9ydCwgXCJ0bC1zdWl0ZSB0bC1wYXNzXCIsIGNoaWxkKVxuICAgICAgICBfLm9wdHMucGFzcy50ZXh0Q29udGVudCA9IF8ucGFzc1xuICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzUGFzcykge1xuICAgICAgICBzaG93VGVzdChfLCByZXBvcnQsIFwidGwtdGVzdCB0bC1wYXNzXCIpXG4gICAgICAgIF8ub3B0cy5wYXNzLnRleHRDb250ZW50ID0gXy5wYXNzXG4gICAgfSBlbHNlIGlmIChyZXBvcnQuaXNGYWlsKSB7XG4gICAgICAgIHNob3dUZXN0KF8sIHJlcG9ydCwgXCJ0bC10ZXN0IHRsLWZhaWxcIiwgZm9ybWF0RXJyb3IocmVwb3J0LmVycm9yLFxuICAgICAgICAgICAgcmVwb3J0LmVycm9yLm5hbWUgPT09IFwiQXNzZXJ0aW9uRXJyb3JcIiAmJlxuICAgICAgICAgICAgICAgIHJlcG9ydC5lcnJvci5zaG93RGlmZiAhPT0gZmFsc2UpKVxuICAgICAgICBfLm9wdHMuZmFpbC50ZXh0Q29udGVudCA9IF8uZmFpbFxuICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzU2tpcCkge1xuICAgICAgICBzaG93U2tpcChfLCByZXBvcnQsIFwidGwtdGVzdCB0bC1za2lwXCIpXG4gICAgICAgIF8ub3B0cy5za2lwLnRleHRDb250ZW50ID0gXy5za2lwXG4gICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFcnJvcikge1xuICAgICAgICBfLm9wdHMucmVwb3J0LmFwcGVuZENoaWxkKGgoXCJsaSB0bC1lcnJvclwiLCBbXG4gICAgICAgICAgICBoKFwiaDJcIiwgW3QoXCJJbnRlcm5hbCBlcnJvclwiKV0pLFxuICAgICAgICAgICAgZm9ybWF0RXJyb3IocmVwb3J0LmVycm9yLCBmYWxzZSksXG4gICAgICAgIF0pKVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWRcbn1cblxuZnVuY3Rpb24gbWFrZUNvdW50ZXIoc3RhdGUsIGNoaWxkLCBsYWJlbCwgbmFtZSkge1xuICAgIHJldHVybiBoKFwiYnV0dG9uIHRsLXRvZ2dsZSBcIiArIG5hbWUsIHtcbiAgICAgICAgb25jbGljazogZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKVxuXG4gICAgICAgICAgICBpZiAoL1xcYnRsLWFjdGl2ZVxcYi8udGVzdCh0aGlzLmNsYXNzTmFtZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSA9IHRoaXMuY2xhc3NOYW1lXG4gICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXGJ0bC1hY3RpdmVcXGIvZywgXCJcIilcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xccysvZywgXCIgXCIpXG4gICAgICAgICAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgICAgICBzdGF0ZS5yZXBvcnQuY2xhc3NOYW1lID0gc3RhdGUucmVwb3J0LmNsYXNzTmFtZVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZShuZXcgUmVnRXhwKFwiXFxcXGJcIiArIG5hbWUgKyBcIlxcXFxiXCIsIFwiZ1wiKSwgXCJcIilcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xccysvZywgXCIgXCIpXG4gICAgICAgICAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmUgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLmFjdGl2ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmFjdGl2ZS5jbGFzc05hbWUgPSBzdGF0ZS5hY3RpdmUuY2xhc3NOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxidGwtYWN0aXZlXFxiL2csIFwiXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxzKy9nLCBcIiBcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmUgPSB0aGlzXG4gICAgICAgICAgICAgICAgdGhpcy5jbGFzc05hbWUgKz0gXCIgdGwtYWN0aXZlXCJcbiAgICAgICAgICAgICAgICBzdGF0ZS5yZXBvcnQuY2xhc3NOYW1lID0gc3RhdGUucmVwb3J0LmNsYXNzTmFtZVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxidGwtKHBhc3N8ZmFpbHxza2lwKVxcYi9nLCBcIlwiKVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxzKy9nLCBcIiBcIilcbiAgICAgICAgICAgICAgICAgICAgLnRyaW0oKSArIFwiIFwiICsgbmFtZVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgIH0sIFt0KGxhYmVsKSwgY2hpbGRdKVxufVxuXG5leHBvcnRzLmluaXQgPSBmdW5jdGlvbiAob3B0cykge1xuICAgIHZhciBzdGF0ZSA9IHtcbiAgICAgICAgY3VycmVudFByb21pc2U6IHVuZGVmaW5lZCxcbiAgICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICAgICAgZHVyYXRpb246IGgoXCJlbVwiLCBbdChSLmZvcm1hdFRpbWUoMCkpXSksXG4gICAgICAgIHBhc3M6IGgoXCJlbVwiLCBbdChcIjBcIildKSxcbiAgICAgICAgZmFpbDogaChcImVtXCIsIFt0KFwiMFwiKV0pLFxuICAgICAgICBza2lwOiBoKFwiZW1cIiwgW3QoXCIwXCIpXSksXG4gICAgICAgIHJlcG9ydDogaChcInVsIHRsLXJlcG9ydFwiKSxcbiAgICAgICAgYWN0aXZlOiB1bmRlZmluZWQsXG4gICAgfVxuXG4gICAgdmFyIGhlYWRlciA9IGgoXCJkaXYgdGwtaGVhZGVyXCIsIFtcbiAgICAgICAgaChcImRpdiB0bC1kdXJhdGlvblwiLCBbdChcIkR1cmF0aW9uOiBcIiksIHN0YXRlLmR1cmF0aW9uXSksXG4gICAgICAgIG1ha2VDb3VudGVyKHN0YXRlLCBzdGF0ZS5wYXNzLCBcIlBhc3NlczogXCIsIFwidGwtcGFzc1wiKSxcbiAgICAgICAgbWFrZUNvdW50ZXIoc3RhdGUsIHN0YXRlLmZhaWwsIFwiRmFpbHVyZXM6IFwiLCBcInRsLWZhaWxcIiksXG4gICAgICAgIG1ha2VDb3VudGVyKHN0YXRlLCBzdGF0ZS5za2lwLCBcIlNraXBwZWQ6IFwiLCBcInRsLXNraXBcIiksXG4gICAgICAgIGgoXCJidXR0b24gdGwtcnVuXCIsIHtcbiAgICAgICAgICAgIG9uY2xpY2s6IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgICAgIGV2LnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgICAgICAgICAgIHJ1blRlc3RzKG9wdHMsIHN0YXRlKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSwgW3QoXCJSdW5cIildKSxcbiAgICBdKVxuXG4gICAgdmFyIHJvb3QgPSBELmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwidGxcIilcblxuICAgIGlmIChyb290ID09IG51bGwpIHtcbiAgICAgICAgRC5kb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHJvb3QgPSBoKFwiZGl2XCIsIHtpZDogXCJ0bFwifSwgW1xuICAgICAgICAgICAgaGVhZGVyLFxuICAgICAgICAgICAgc3RhdGUucmVwb3J0LFxuICAgICAgICBdKSlcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDbGVhciB0aGUgZWxlbWVudCBmaXJzdCwganVzdCBpbiBjYXNlLlxuICAgICAgICB3aGlsZSAocm9vdC5maXJzdENoaWxkKSByb290LnJlbW92ZUNoaWxkKHJvb3QuZmlyc3RDaGlsZClcbiAgICAgICAgcm9vdC5hcHBlbmRDaGlsZChoZWFkZXIpXG4gICAgICAgIHJvb3QuYXBwZW5kQ2hpbGQoc3RhdGUucmVwb3J0KVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHJvb3Q6IHJvb3QsXG4gICAgICAgIHN0YXRlOiBzdGF0ZSxcbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChCYXNlLCBTdXBlcikge1xuICAgIHZhciBzdGFydCA9IDJcblxuICAgIGlmICh0eXBlb2YgU3VwZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBCYXNlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoU3VwZXIucHJvdG90eXBlKVxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQmFzZS5wcm90b3R5cGUsIFwiY29uc3RydWN0b3JcIiwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBCYXNlLFxuICAgICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXJ0ID0gMVxuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgbWV0aG9kcyA9IGFyZ3VtZW50c1tpXVxuXG4gICAgICAgIGlmIChtZXRob2RzICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMobWV0aG9kcylcblxuICAgICAgICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCBrZXlzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleSA9IGtleXNba11cbiAgICAgICAgICAgICAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobWV0aG9kcywga2V5KVxuXG4gICAgICAgICAgICAgICAgZGVzYy5lbnVtZXJhYmxlID0gZmFsc2VcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQmFzZS5wcm90b3R5cGUsIGtleSwgZGVzYylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogVGhpcyBjb250YWlucyB0aGUgYnJvd3NlciBjb25zb2xlIHN0dWZmLlxuICovXG5cbmV4cG9ydHMuU3ltYm9scyA9IE9iamVjdC5mcmVlemUoe1xuICAgIFBhc3M6IFwi4pyTXCIsXG4gICAgRmFpbDogXCLinJZcIixcbiAgICBEb3Q6IFwi4oCkXCIsXG4gICAgRG90RmFpbDogXCIhXCIsXG59KVxuXG5leHBvcnRzLndpbmRvd1dpZHRoID0gNzVcbmV4cG9ydHMubmV3bGluZSA9IFwiXFxuXCJcblxuLy8gQ29sb3Igc3VwcG9ydCBpcyB1bmZvcmNlZCBhbmQgdW5zdXBwb3J0ZWQsIHNpbmNlIHlvdSBjYW4gb25seSBzcGVjaWZ5XG4vLyBsaW5lLWJ5LWxpbmUgY29sb3JzIHZpYSBDU1MsIGFuZCBldmVuIHRoYXQgaXNuJ3QgdmVyeSBwb3J0YWJsZS5cbmV4cG9ydHMuY29sb3JTdXBwb3J0ID0gMFxuXG4vKipcbiAqIFNpbmNlIGJyb3dzZXJzIGRvbid0IGhhdmUgdW5idWZmZXJlZCBvdXRwdXQsIHRoaXMga2luZCBvZiBzaW11bGF0ZXMgaXQuXG4gKi9cblxudmFyIGFjYyA9IFwiXCJcblxuZXhwb3J0cy5kZWZhdWx0T3B0cyA9IHtcbiAgICB3cml0ZTogZnVuY3Rpb24gKHN0cikge1xuICAgICAgICBhY2MgKz0gc3RyXG5cbiAgICAgICAgdmFyIGluZGV4ID0gc3RyLmluZGV4T2YoXCJcXG5cIilcblxuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgdmFyIGxpbmVzID0gc3RyLnNwbGl0KFwiXFxuXCIpXG5cbiAgICAgICAgICAgIGFjYyA9IGxpbmVzLnBvcCgpXG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBnbG9iYWwuY29uc29sZS5sb2cobGluZXNbaV0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKGFjYyAhPT0gXCJcIikge1xuICAgICAgICAgICAgZ2xvYmFsLmNvbnNvbGUubG9nKGFjYylcbiAgICAgICAgICAgIGFjYyA9IFwiXCJcbiAgICAgICAgfVxuICAgIH0sXG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgZGlmZiA9IHJlcXVpcmUoXCJkaWZmXCIpXG5cbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcbnZhciBpbnNwZWN0ID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpLmluc3BlY3RcbnZhciBwZWFjaCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpLnBlYWNoXG52YXIgUmVwb3J0ZXIgPSByZXF1aXJlKFwiLi9yZXBvcnRlclwiKVxudmFyIFV0aWwgPSByZXF1aXJlKFwiLi91dGlsXCIpXG52YXIgU2V0dGluZ3MgPSByZXF1aXJlKFwiLi4vc2V0dGluZ3NcIilcblxuZnVuY3Rpb24gcHJpbnRUaW1lKF8sIHAsIHN0cikge1xuICAgIGlmICghXy50aW1lUHJpbnRlZCkge1xuICAgICAgICBfLnRpbWVQcmludGVkID0gdHJ1ZVxuICAgICAgICBzdHIgKz0gVXRpbC5jb2xvcihcImxpZ2h0XCIsIFwiIChcIiArIFV0aWwuZm9ybWF0VGltZShfLmR1cmF0aW9uKSArIFwiKVwiKVxuICAgIH1cblxuICAgIHJldHVybiBwLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChzdHIpIH0pXG59XG5cbmZ1bmN0aW9uIHVuaWZpZWREaWZmKGVycikge1xuICAgIHZhciBhY3R1YWwgPSBpbnNwZWN0KGVyci5hY3R1YWwpXG4gICAgdmFyIGV4cGVjdGVkID0gaW5zcGVjdChlcnIuZXhwZWN0ZWQpXG4gICAgdmFyIG1zZyA9IGRpZmYuY3JlYXRlUGF0Y2goXCJzdHJpbmdcIiwgYWN0dWFsLCBleHBlY3RlZClcbiAgICB2YXIgaGVhZGVyID0gU2V0dGluZ3MubmV3bGluZSgpICtcbiAgICAgICAgVXRpbC5jb2xvcihcImRpZmYgYWRkZWRcIiwgXCIrIGV4cGVjdGVkXCIpICsgXCIgXCIgK1xuICAgICAgICBVdGlsLmNvbG9yKFwiZGlmZiByZW1vdmVkXCIsIFwiLSBhY3R1YWxcIikgK1xuICAgICAgICBTZXR0aW5ncy5uZXdsaW5lKCkgKyBTZXR0aW5ncy5uZXdsaW5lKClcblxuICAgIHJldHVybiBoZWFkZXIgKyBtc2cuc3BsaXQoL1xccj9cXG58XFxyL2cpLnNsaWNlKDQpXG4gICAgLmZpbHRlcihmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gIS9eXFxAXFxAfF5cXFxcIE5vIG5ld2xpbmUvLnRlc3QobGluZSkgfSlcbiAgICAubWFwKGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIGlmIChsaW5lWzBdID09PSBcIitcIikgcmV0dXJuIFV0aWwuY29sb3IoXCJkaWZmIGFkZGVkXCIsIGxpbmUudHJpbVJpZ2h0KCkpXG4gICAgICAgIGlmIChsaW5lWzBdID09PSBcIi1cIikgcmV0dXJuIFV0aWwuY29sb3IoXCJkaWZmIHJlbW92ZWRcIiwgbGluZS50cmltUmlnaHQoKSlcbiAgICAgICAgcmV0dXJuIGxpbmUudHJpbVJpZ2h0KClcbiAgICB9KVxuICAgIC5qb2luKFNldHRpbmdzLm5ld2xpbmUoKSlcbn1cblxuZnVuY3Rpb24gZm9ybWF0RmFpbChzdHIpIHtcbiAgICByZXR1cm4gc3RyLnRyaW1SaWdodCgpXG4gICAgLnNwbGl0KC9cXHI/XFxufFxcci9nKVxuICAgIC5tYXAoZnVuY3Rpb24gKGxpbmUpIHsgcmV0dXJuIFV0aWwuY29sb3IoXCJmYWlsXCIsIGxpbmUudHJpbVJpZ2h0KCkpIH0pXG4gICAgLmpvaW4oU2V0dGluZ3MubmV3bGluZSgpKVxufVxuXG5mdW5jdGlvbiBnZXREaWZmU3RhY2soZSkge1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IGZvcm1hdEZhaWwoZS5uYW1lICsgXCI6IFwiICsgZS5tZXNzYWdlKVxuXG4gICAgaWYgKGUubmFtZSA9PT0gXCJBc3NlcnRpb25FcnJvclwiICYmIGUuc2hvd0RpZmYgIT09IGZhbHNlKSB7XG4gICAgICAgIGRlc2NyaXB0aW9uICs9IFNldHRpbmdzLm5ld2xpbmUoKSArIHVuaWZpZWREaWZmKGUpXG4gICAgfVxuXG4gICAgdmFyIHN0cmlwcGVkID0gZm9ybWF0RmFpbChVdGlsLnJlYWRTdGFjayhlKSlcblxuICAgIGlmIChzdHJpcHBlZCA9PT0gXCJcIikgcmV0dXJuIGRlc2NyaXB0aW9uXG4gICAgcmV0dXJuIGRlc2NyaXB0aW9uICsgU2V0dGluZ3MubmV3bGluZSgpICsgc3RyaXBwZWRcbn1cblxuZnVuY3Rpb24gaW5zcGVjdFRyaW1tZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuIGluc3BlY3Qob2JqZWN0KS50cmltUmlnaHQoKVxuICAgIC5zcGxpdCgvXFxyP1xcbnxcXHIvZylcbiAgICAubWFwKGZ1bmN0aW9uIChsaW5lKSB7IHJldHVybiBsaW5lLnRyaW1SaWdodCgpIH0pXG4gICAgLmpvaW4oU2V0dGluZ3MubmV3bGluZSgpKVxufVxuXG5mdW5jdGlvbiBwcmludEZhaWxMaXN0KF8sIGVycikge1xuICAgIHZhciBzdHIgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGdldERpZmZTdGFjayhlcnIpIDogaW5zcGVjdFRyaW1tZWQoZXJyKVxuICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdCgvXFxyP1xcbi9nKVxuXG4gICAgcmV0dXJuIF8ucHJpbnQoXCIgICAgXCIgKyBwYXJ0c1swXSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBwZWFjaChwYXJ0cy5zbGljZSgxKSwgZnVuY3Rpb24gKHBhcnQpIHtcbiAgICAgICAgICAgIHJldHVybiBfLnByaW50KHBhcnQgPyBcIiAgICAgIFwiICsgcGFydCA6IFwiXCIpXG4gICAgICAgIH0pXG4gICAgfSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0cywgbWV0aG9kcykge1xuICAgIHJldHVybiBuZXcgQ29uc29sZVJlcG9ydGVyKG9wdHMsIG1ldGhvZHMpXG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgbW9zdCBjb25zb2xlIHJlcG9ydGVycy5cbiAqXG4gKiBOb3RlOiBwcmludGluZyBpcyBhc3luY2hyb25vdXMsIGJlY2F1c2Ugb3RoZXJ3aXNlLCBpZiBlbm91Z2ggZXJyb3JzIGV4aXN0LFxuICogTm9kZSB3aWxsIGV2ZW50dWFsbHkgc3RhcnQgZHJvcHBpbmcgbGluZXMgc2VudCB0byBpdHMgYnVmZmVyLCBlc3BlY2lhbGx5IHdoZW5cbiAqIHN0YWNrIHRyYWNlcyBnZXQgaW52b2x2ZWQuIElmIFRoYWxsaXVtJ3Mgb3V0cHV0IGlzIHJlZGlyZWN0ZWQsIHRoYXQgY2FuIGJlIGFcbiAqIGJpZyBwcm9ibGVtIGZvciBjb25zdW1lcnMsIGFzIHRoZXkgb25seSBoYXZlIHBhcnQgb2YgdGhlIG91dHB1dCwgYW5kIHdvbid0IGJlXG4gKiBhYmxlIHRvIHNlZSBhbGwgdGhlIGVycm9ycyBsYXRlci4gQWxzbywgaWYgY29uc29sZSB3YXJuaW5ncyBjb21lIHVwIGVuLW1hc3NlLFxuICogdGhhdCB3b3VsZCBhbHNvIGNvbnRyaWJ1dGUuIFNvLCB3ZSBoYXZlIHRvIHdhaXQgZm9yIGVhY2ggbGluZSB0byBmbHVzaCBiZWZvcmVcbiAqIHdlIGNhbiBjb250aW51ZSwgc28gdGhlIGZ1bGwgb3V0cHV0IG1ha2VzIGl0cyB3YXkgdG8gdGhlIGNvbnNvbGUuXG4gKlxuICogU29tZSB0ZXN0IGZyYW1ld29ya3MgbGlrZSBUYXBlIG1pc3MgdGhpcywgdGhvdWdoLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIFRoZSBvcHRpb25zIGZvciB0aGUgcmVwb3J0ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBvcHRzLndyaXRlIFRoZSB1bmJ1ZmZlcnJlZCB3cml0ZXIgZm9yIHRoZSByZXBvcnRlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IG9wdHMucmVzZXQgQSByZXNldCBmdW5jdGlvbiBmb3IgdGhlIHByaW50ZXIgKyB3cml0ZXIuXG4gKiBAcGFyYW0ge1N0cmluZ1tdfSBhY2NlcHRzIFRoZSBvcHRpb25zIGFjY2VwdGVkLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaW5pdCBUaGUgaW5pdCBmdW5jdGlvbiBmb3IgdGhlIHN1YmNsYXNzIHJlcG9ydGVyJ3NcbiAqICAgICAgICAgICAgICAgICAgICAgICAgaXNvbGF0ZWQgc3RhdGUgKGNyZWF0ZWQgYnkgZmFjdG9yeSkuXG4gKi9cbmZ1bmN0aW9uIENvbnNvbGVSZXBvcnRlcihvcHRzLCBtZXRob2RzKSB7XG4gICAgUmVwb3J0ZXIuY2FsbCh0aGlzLCBVdGlsLlRyZWUsIG9wdHMsIG1ldGhvZHMsIHRydWUpXG5cbiAgICBpZiAoIVV0aWwuQ29sb3JzLmZvcmNlZCgpICYmIG1ldGhvZHMuYWNjZXB0cy5pbmRleE9mKFwiY29sb3JcIikgPj0gMCkge1xuICAgICAgICB0aGlzLm9wdHMuY29sb3IgPSBvcHRzLmNvbG9yXG4gICAgfVxuXG4gICAgVXRpbC5kZWZhdWx0aWZ5KHRoaXMsIG9wdHMsIFwid3JpdGVcIilcbiAgICB0aGlzLnJlc2V0KClcbn1cblxubWV0aG9kcyhDb25zb2xlUmVwb3J0ZXIsIFJlcG9ydGVyLCB7XG4gICAgcHJpbnQ6IGZ1bmN0aW9uIChzdHIpIHtcbiAgICAgICAgaWYgKHN0ciA9PSBudWxsKSBzdHIgPSBcIlwiXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5vcHRzLndyaXRlKHN0ciArIFwiXFxuXCIpKVxuICAgIH0sXG5cbiAgICB3cml0ZTogZnVuY3Rpb24gKHN0cikge1xuICAgICAgICBpZiAoc3RyICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5vcHRzLndyaXRlKHN0cikpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBwcmludFJlc3VsdHM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgICAgICAgaWYgKCF0aGlzLnRlc3RzICYmICF0aGlzLnNraXApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByaW50KFxuICAgICAgICAgICAgICAgIFV0aWwuY29sb3IoXCJwbGFpblwiLCBcIiAgMCB0ZXN0c1wiKSArXG4gICAgICAgICAgICAgICAgVXRpbC5jb2xvcihcImxpZ2h0XCIsIFwiICgwbXMpXCIpKVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5wcmludCgpIH0pXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5wcmludCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHAgPSBQcm9taXNlLnJlc29sdmUoKVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5wYXNzKSB7XG4gICAgICAgICAgICAgICAgcCA9IHByaW50VGltZShzZWxmLCBwLFxuICAgICAgICAgICAgICAgICAgICBVdGlsLmNvbG9yKFwiYnJpZ2h0IHBhc3NcIiwgXCIgIFwiKSArXG4gICAgICAgICAgICAgICAgICAgIFV0aWwuY29sb3IoXCJncmVlblwiLCBzZWxmLnBhc3MgKyBcIiBwYXNzaW5nXCIpKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5za2lwKSB7XG4gICAgICAgICAgICAgICAgcCA9IHByaW50VGltZShzZWxmLCBwLFxuICAgICAgICAgICAgICAgICAgICBVdGlsLmNvbG9yKFwic2tpcFwiLCBcIiAgXCIgKyBzZWxmLnNraXAgKyBcIiBza2lwcGVkXCIpKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5mYWlsKSB7XG4gICAgICAgICAgICAgICAgcCA9IHByaW50VGltZShzZWxmLCBwLFxuICAgICAgICAgICAgICAgICAgICBVdGlsLmNvbG9yKFwiYnJpZ2h0IGZhaWxcIiwgXCIgIFwiKSArXG4gICAgICAgICAgICAgICAgICAgIFV0aWwuY29sb3IoXCJmYWlsXCIsIHNlbGYuZmFpbCArIFwiIGZhaWxpbmdcIikpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBwXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGYucHJpbnQoKSB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcGVhY2goc2VsZi5lcnJvcnMsIGZ1bmN0aW9uIChyZXBvcnQsIGkpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IGkgKyAxICsgXCIpIFwiICsgVXRpbC5qb2luUGF0aChyZXBvcnQpICtcbiAgICAgICAgICAgICAgICAgICAgVXRpbC5mb3JtYXRSZXN0KHJlcG9ydClcblxuICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLnByaW50KFwiICBcIiArIFV0aWwuY29sb3IoXCJwbGFpblwiLCBuYW1lICsgXCI6XCIpKVxuICAgICAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByaW50RmFpbExpc3Qoc2VsZiwgcmVwb3J0LmVycm9yKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5wcmludCgpIH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgIH0sXG5cbiAgICBwcmludEVycm9yOiBmdW5jdGlvbiAocmVwb3J0KSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpc1xuICAgICAgICB2YXIgbGluZXMgPSByZXBvcnQuZXJyb3IgaW5zdGFuY2VvZiBFcnJvclxuICAgICAgICAgICAgPyBVdGlsLmdldFN0YWNrKHJlcG9ydC5lcnJvcilcbiAgICAgICAgICAgIDogaW5zcGVjdFRyaW1tZWQocmVwb3J0LmVycm9yKVxuXG4gICAgICAgIHJldHVybiB0aGlzLnByaW50KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcGVhY2gobGluZXMuc3BsaXQoL1xccj9cXG4vZyksIGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYucHJpbnQobGluZSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuL3V0aWxcIilcblxuZXhwb3J0cy5vbiA9IHJlcXVpcmUoXCIuL29uXCIpXG5leHBvcnRzLmNvbnNvbGVSZXBvcnRlciA9IHJlcXVpcmUoXCIuL2NvbnNvbGUtcmVwb3J0ZXJcIilcbmV4cG9ydHMuUmVwb3J0ZXIgPSByZXF1aXJlKFwiLi9yZXBvcnRlclwiKVxuZXhwb3J0cy5jb2xvciA9IFV0aWwuY29sb3JcbmV4cG9ydHMuQ29sb3JzID0gVXRpbC5Db2xvcnNcbmV4cG9ydHMuZm9ybWF0UmVzdCA9IFV0aWwuZm9ybWF0UmVzdFxuZXhwb3J0cy5mb3JtYXRUaW1lID0gVXRpbC5mb3JtYXRUaW1lXG5leHBvcnRzLmdldFN0YWNrID0gVXRpbC5nZXRTdGFja1xuZXhwb3J0cy5qb2luUGF0aCA9IFV0aWwuam9pblBhdGhcbmV4cG9ydHMubmV3bGluZSA9IFV0aWwubmV3bGluZVxuZXhwb3J0cy5yZWFkU3RhY2sgPSBVdGlsLnJlYWRTdGFja1xuZXhwb3J0cy5zZXRDb2xvciA9IFV0aWwuc2V0Q29sb3JcbmV4cG9ydHMuc3BlZWQgPSBVdGlsLnNwZWVkXG5leHBvcnRzLlN0YXR1cyA9IFV0aWwuU3RhdHVzXG5leHBvcnRzLnN5bWJvbHMgPSBVdGlsLnN5bWJvbHNcbmV4cG9ydHMudW5zZXRDb2xvciA9IFV0aWwudW5zZXRDb2xvclxuZXhwb3J0cy53aW5kb3dXaWR0aCA9IFV0aWwud2luZG93V2lkdGhcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBTdGF0dXMgPSByZXF1aXJlKFwiLi91dGlsXCIpLlN0YXR1c1xuXG4vLyBCZWNhdXNlIEVTNSBzdWNrcy4gKEFuZCwgaXQncyBicmVha2luZyBteSBQaGFudG9tSlMgYnVpbGRzKVxuZnVuY3Rpb24gc2V0TmFtZShyZXBvcnRlciwgbmFtZSkge1xuICAgIHRyeSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXBvcnRlciwgXCJuYW1lXCIsIHt2YWx1ZTogbmFtZX0pXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBpZ25vcmVcbiAgICB9XG59XG5cbi8qKlxuICogQSBtYWNybyBvZiBzb3J0cywgdG8gc2ltcGxpZnkgY3JlYXRpbmcgcmVwb3J0ZXJzLiBJdCBhY2NlcHRzIGFuIG9iamVjdCB3aXRoXG4gKiB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6XG4gKlxuICogYGFjY2VwdHM6IHN0cmluZ1tdYCAtIFRoZSBwcm9wZXJ0aWVzIGFjY2VwdGVkLiBFdmVyeXRoaW5nIGVsc2UgaXMgaWdub3JlZCxcbiAqIGFuZCBpdCdzIHBhcnRpYWxseSB0aGVyZSBmb3IgZG9jdW1lbnRhdGlvbi4gVGhpcyBwYXJhbWV0ZXIgaXMgcmVxdWlyZWQuXG4gKlxuICogYGNyZWF0ZShvcHRzLCBtZXRob2RzKWAgLSBDcmVhdGUgYSBuZXcgcmVwb3J0ZXIgaW5zdGFuY2UuICBUaGlzIHBhcmFtZXRlciBpc1xuICogcmVxdWlyZWQuIE5vdGUgdGhhdCBgbWV0aG9kc2AgcmVmZXJzIHRvIHRoZSBwYXJhbWV0ZXIgb2JqZWN0IGl0c2VsZi5cbiAqXG4gKiBgaW5pdChzdGF0ZSwgb3B0cylgIC0gSW5pdGlhbGl6ZSBleHRyYSByZXBvcnRlciBzdGF0ZSwgaWYgYXBwbGljYWJsZS5cbiAqXG4gKiBgYmVmb3JlKHJlcG9ydGVyKWAgLSBEbyB0aGluZ3MgYmVmb3JlIGVhY2ggZXZlbnQsIHJldHVybmluZyBhIHBvc3NpYmxlXG4gKiB0aGVuYWJsZSB3aGVuIGRvbmUuIFRoaXMgZGVmYXVsdHMgdG8gYSBuby1vcC5cbiAqXG4gKiBgYWZ0ZXIocmVwb3J0ZXIpYCAtIERvIHRoaW5ncyBhZnRlciBlYWNoIGV2ZW50LCByZXR1cm5pbmcgYSBwb3NzaWJsZVxuICogdGhlbmFibGUgd2hlbiBkb25lLiBUaGlzIGRlZmF1bHRzIHRvIGEgbm8tb3AuXG4gKlxuICogYHJlcG9ydChyZXBvcnRlciwgcmVwb3J0KWAgLSBIYW5kbGUgYSB0ZXN0IHJlcG9ydC4gVGhpcyBtYXkgcmV0dXJuIGEgcG9zc2libGVcbiAqIHRoZW5hYmxlIHdoZW4gZG9uZSwgYW5kIGl0IGlzIHJlcXVpcmVkLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChuYW1lLCBtZXRob2RzKSB7XG4gICAgc2V0TmFtZShyZXBvcnRlciwgbmFtZSlcbiAgICByZXBvcnRlcltuYW1lXSA9IHJlcG9ydGVyXG4gICAgcmV0dXJuIHJlcG9ydGVyXG4gICAgZnVuY3Rpb24gcmVwb3J0ZXIob3B0cykge1xuICAgICAgICAvKipcbiAgICAgICAgICogSW5zdGVhZCBvZiBzaWxlbnRseSBmYWlsaW5nIHRvIHdvcmssIGxldCdzIGVycm9yIG91dCB3aGVuIGEgcmVwb3J0IGlzXG4gICAgICAgICAqIHBhc3NlZCBpbiwgYW5kIGluZm9ybSB0aGUgdXNlciBpdCBuZWVkcyBpbml0aWFsaXplZC4gQ2hhbmNlcyBhcmUsXG4gICAgICAgICAqIHRoZXJlJ3Mgbm8gbGVnaXRpbWF0ZSByZWFzb24gdG8gZXZlbiBwYXNzIGEgcmVwb3J0LCBhbnl3YXlzLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKHR5cGVvZiBvcHRzID09PSBcIm9iamVjdFwiICYmIG9wdHMgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2Ygb3B0cy5fID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgICAgIFwiT3B0aW9ucyBjYW5ub3QgYmUgYSByZXBvcnQuIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgdGhlIFwiICtcbiAgICAgICAgICAgICAgICBcImZhY3RvcnkgZmlyc3Q/XCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgXyA9IG1ldGhvZHMuY3JlYXRlKG9wdHMsIG1ldGhvZHMpXG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChyZXBvcnQpIHtcbiAgICAgICAgICAgIC8vIE9ubHkgc29tZSBldmVudHMgaGF2ZSBjb21tb24gc3RlcHMuXG4gICAgICAgICAgICBpZiAocmVwb3J0LmlzU3RhcnQpIHtcbiAgICAgICAgICAgICAgICBfLnJ1bm5pbmcgPSB0cnVlXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0VudGVyIHx8IHJlcG9ydC5pc1Bhc3MpIHtcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucGF0aCkuc3RhdHVzID0gU3RhdHVzLlBhc3NpbmdcbiAgICAgICAgICAgICAgICBfLmR1cmF0aW9uICs9IHJlcG9ydC5kdXJhdGlvblxuICAgICAgICAgICAgICAgIF8udGVzdHMrK1xuICAgICAgICAgICAgICAgIF8ucGFzcysrXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0ZhaWwpIHtcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucGF0aCkuc3RhdHVzID0gU3RhdHVzLkZhaWxpbmdcbiAgICAgICAgICAgICAgICBfLmR1cmF0aW9uICs9IHJlcG9ydC5kdXJhdGlvblxuICAgICAgICAgICAgICAgIF8udGVzdHMrK1xuICAgICAgICAgICAgICAgIF8uZmFpbCsrXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0hvb2spIHtcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucGF0aCkuc3RhdHVzID0gU3RhdHVzLkZhaWxpbmdcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucm9vdFBhdGgpLnN0YXR1cyA9IFN0YXR1cy5GYWlsaW5nXG4gICAgICAgICAgICAgICAgXy5mYWlsKytcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzU2tpcCkge1xuICAgICAgICAgICAgICAgIF8uZ2V0KHJlcG9ydC5wYXRoKS5zdGF0dXMgPSBTdGF0dXMuU2tpcHBlZFxuICAgICAgICAgICAgICAgIC8vIFNraXBwZWQgdGVzdHMgYXJlbid0IGNvdW50ZWQgaW4gdGhlIHRvdGFsIHRlc3QgY291bnRcbiAgICAgICAgICAgICAgICBfLnNraXArK1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICAgICAgICAgIHR5cGVvZiBtZXRob2RzLmJlZm9yZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICAgICAgICAgID8gbWV0aG9kcy5iZWZvcmUoXylcbiAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBtZXRob2RzLnJlcG9ydChfLCByZXBvcnQpIH0pXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBtZXRob2RzLmFmdGVyID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgPyBtZXRob2RzLmFmdGVyKF8pXG4gICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChyZXBvcnQuaXNFbmQgfHwgcmVwb3J0LmlzRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgXy5yZXNldCgpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgXy5vcHRzLnJlc2V0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfLm9wdHMucmVzZXQoKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgbWV0aG9kcyA9IHJlcXVpcmUoXCIuLi9tZXRob2RzXCIpXG52YXIgZGVmYXVsdGlmeSA9IHJlcXVpcmUoXCIuL3V0aWxcIikuZGVmYXVsdGlmeVxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuZnVuY3Rpb24gU3RhdGUocmVwb3J0ZXIpIHtcbiAgICBpZiAodHlwZW9mIHJlcG9ydGVyLm1ldGhvZHMuaW5pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICgwLCByZXBvcnRlci5tZXRob2RzLmluaXQpKHRoaXMsIHJlcG9ydGVyLm9wdHMpXG4gICAgfVxufVxuXG4vKipcbiAqIFRoaXMgaGVscHMgc3BlZWQgdXAgZ2V0dGluZyBwcmV2aW91cyB0cmVlcywgc28gYSBwb3RlbnRpYWxseSBleHBlbnNpdmVcbiAqIHRyZWUgc2VhcmNoIGRvZXNuJ3QgaGF2ZSB0byBiZSBwZXJmb3JtZWQuXG4gKlxuICogKFRoaXMgZG9lcyBhY3R1YWxseSBtYWtlIGEgc2xpZ2h0IHBlcmYgZGlmZmVyZW5jZSBpbiB0aGUgdGVzdHMuKVxuICovXG5mdW5jdGlvbiBpc1JlcGVhdChjYWNoZSwgcGF0aCkge1xuICAgIC8vIENhbid0IGJlIGEgcmVwZWF0IHRoZSBmaXJzdCB0aW1lLlxuICAgIGlmIChjYWNoZS5wYXRoID09IG51bGwpIHJldHVybiBmYWxzZVxuICAgIGlmIChwYXRoLmxlbmd0aCAhPT0gY2FjaGUucGF0aC5sZW5ndGgpIHJldHVybiBmYWxzZVxuICAgIGlmIChwYXRoID09PSBjYWNoZS5wYXRoKSByZXR1cm4gdHJ1ZVxuXG4gICAgLy8gSXQncyB1bmxpa2VseSB0aGUgbmVzdGluZyB3aWxsIGJlIGNvbnNpc3RlbnRseSBtb3JlIHRoYW4gYSBmZXcgbGV2ZWxzXG4gICAgLy8gZGVlcCAoPj0gNSksIHNvIHRoaXMgc2hvdWxkbid0IGJvZyBhbnl0aGluZyBkb3duLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0aC5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAocGF0aFtpXSAhPT0gY2FjaGUucGF0aFtpXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjYWNoZS5wYXRoID0gcGF0aFxuICAgIHJldHVybiB0cnVlXG59XG5cbi8qKlxuICogU3VwZXJjbGFzcyBmb3IgYWxsIHJlcG9ydGVycy4gVGhpcyBjb3ZlcnMgdGhlIHN0YXRlIGZvciBwcmV0dHkgbXVjaCBldmVyeVxuICogcmVwb3J0ZXIuXG4gKlxuICogTm90ZSB0aGF0IGlmIHlvdSBkZWxheSB0aGUgaW5pdGlhbCByZXNldCwgeW91IHN0aWxsIG11c3QgY2FsbCBpdCBiZWZvcmUgdGhlXG4gKiBjb25zdHJ1Y3RvciBmaW5pc2hlcy5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBSZXBvcnRlclxuZnVuY3Rpb24gUmVwb3J0ZXIoVHJlZSwgb3B0cywgbWV0aG9kcywgZGVsYXkpIHtcbiAgICB0aGlzLlRyZWUgPSBUcmVlXG4gICAgdGhpcy5vcHRzID0ge31cbiAgICB0aGlzLm1ldGhvZHMgPSBtZXRob2RzXG4gICAgZGVmYXVsdGlmeSh0aGlzLCBvcHRzLCBcInJlc2V0XCIpXG4gICAgaWYgKCFkZWxheSkgdGhpcy5yZXNldCgpXG59XG5cbm1ldGhvZHMoUmVwb3J0ZXIsIHtcbiAgICByZXNldDogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZVxuICAgICAgICB0aGlzLnRpbWVQcmludGVkID0gZmFsc2VcbiAgICAgICAgdGhpcy50ZXN0cyA9IDBcbiAgICAgICAgdGhpcy5wYXNzID0gMFxuICAgICAgICB0aGlzLmZhaWwgPSAwXG4gICAgICAgIHRoaXMuc2tpcCA9IDBcbiAgICAgICAgdGhpcy5kdXJhdGlvbiA9IDBcbiAgICAgICAgdGhpcy5lcnJvcnMgPSBbXVxuICAgICAgICB0aGlzLnN0YXRlID0gbmV3IFN0YXRlKHRoaXMpXG4gICAgICAgIHRoaXMuYmFzZSA9IG5ldyB0aGlzLlRyZWUodW5kZWZpbmVkKVxuICAgICAgICB0aGlzLmNhY2hlID0ge3BhdGg6IHVuZGVmaW5lZCwgcmVzdWx0OiB1bmRlZmluZWQsIGVuZDogMH1cbiAgICB9LFxuXG4gICAgcHVzaEVycm9yOiBmdW5jdGlvbiAocmVwb3J0KSB7XG4gICAgICAgIHRoaXMuZXJyb3JzLnB1c2gocmVwb3J0KVxuICAgIH0sXG5cbiAgICBnZXQ6IGZ1bmN0aW9uIChwYXRoLCBlbmQpIHtcbiAgICAgICAgaWYgKGVuZCA9PSBudWxsKSBlbmQgPSBwYXRoLmxlbmd0aFxuICAgICAgICBpZiAoZW5kID09PSAwKSByZXR1cm4gdGhpcy5iYXNlXG4gICAgICAgIGlmIChpc1JlcGVhdCh0aGlzLmNhY2hlLCBwYXRoLCBlbmQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYWNoZS5yZXN1bHRcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjaGlsZCA9IHRoaXMuYmFzZVxuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW5kOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBlbnRyeSA9IHBhdGhbaV1cblxuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKGNoaWxkLmNoaWxkcmVuLCBlbnRyeS5pbmRleCkpIHtcbiAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmNoaWxkcmVuW2VudHJ5LmluZGV4XVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmNoaWxkcmVuW2VudHJ5LmluZGV4XSA9IG5ldyB0aGlzLlRyZWUoZW50cnkubmFtZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FjaGUuZW5kID0gZW5kXG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlLnJlc3VsdCA9IGNoaWxkXG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpXG52YXIgU2V0dGluZ3MgPSByZXF1aXJlKFwiLi4vc2V0dGluZ3NcIilcblxuZXhwb3J0cy5zeW1ib2xzID0gU2V0dGluZ3Muc3ltYm9sc1xuZXhwb3J0cy53aW5kb3dXaWR0aCA9IFNldHRpbmdzLndpbmRvd1dpZHRoXG5leHBvcnRzLm5ld2xpbmUgPSBTZXR0aW5ncy5uZXdsaW5lXG5cbi8qXG4gKiBTdGFjayBub3JtYWxpemF0aW9uXG4gKi9cblxuLy8gRXhwb3J0ZWQgZm9yIGRlYnVnZ2luZ1xuZXhwb3J0cy5yZWFkU3RhY2sgPSByZWFkU3RhY2tcbmZ1bmN0aW9uIHJlYWRTdGFjayhlKSB7XG4gICAgdmFyIHN0YWNrID0gVXRpbC5nZXRTdGFjayhlKVxuXG4gICAgLy8gSWYgaXQgZG9lc24ndCBzdGFydCB3aXRoIHRoZSBtZXNzYWdlLCBqdXN0IHJldHVybiB0aGUgc3RhY2suXG4gICAgLy8gIEZpcmVmb3gsIFNhZmFyaSAgICAgICAgICAgICAgICBDaHJvbWUsIElFXG4gICAgaWYgKC9eKEApP1xcUytcXDpcXGQrLy50ZXN0KHN0YWNrKSB8fCAvXlxccyphdC8udGVzdChzdGFjaykpIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdExpbmVCcmVha3Moc3RhY2spXG4gICAgfVxuXG4gICAgdmFyIGluZGV4ID0gc3RhY2suaW5kZXhPZihlLm1lc3NhZ2UpXG5cbiAgICBpZiAoaW5kZXggPCAwKSByZXR1cm4gZm9ybWF0TGluZUJyZWFrcyhVdGlsLmdldFN0YWNrKGUpKVxuICAgIHZhciByZSA9IC9cXHI/XFxuL2dcblxuICAgIHJlLmxhc3RJbmRleCA9IGluZGV4ICsgZS5tZXNzYWdlLmxlbmd0aFxuICAgIGlmICghcmUudGVzdChzdGFjaykpIHJldHVybiBcIlwiXG4gICAgcmV0dXJuIGZvcm1hdExpbmVCcmVha3Moc3RhY2suc2xpY2UocmUubGFzdEluZGV4KSlcbn1cblxuZnVuY3Rpb24gZm9ybWF0TGluZUJyZWFrcyhzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFteXFxyXFxuXFxTXSskL2csIFwiXCIpXG4gICAgICAgIC5yZXBsYWNlKC9cXHMqKFxccj9cXG58XFxyKVxccyovZywgU2V0dGluZ3MubmV3bGluZSgpKVxufVxuXG5leHBvcnRzLmdldFN0YWNrID0gZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAoIShlIGluc3RhbmNlb2YgRXJyb3IpKSByZXR1cm4gZm9ybWF0TGluZUJyZWFrcyhVdGlsLmdldFN0YWNrKGUpKVxuICAgIHZhciBkZXNjcmlwdGlvbiA9IChlLm5hbWUgKyBcIjogXCIgKyBlLm1lc3NhZ2UpXG4gICAgICAgIC5yZXBsYWNlKC9cXHMrJC9nbSwgXCJcIilcbiAgICAgICAgLnJlcGxhY2UoL1xccj9cXG58XFxyL2csIFNldHRpbmdzLm5ld2xpbmUoKSlcbiAgICB2YXIgc3RyaXBwZWQgPSByZWFkU3RhY2soZSlcblxuICAgIGlmIChzdHJpcHBlZCA9PT0gXCJcIikgcmV0dXJuIGRlc2NyaXB0aW9uXG4gICAgcmV0dXJuIGRlc2NyaXB0aW9uICsgU2V0dGluZ3MubmV3bGluZSgpICsgc3RyaXBwZWRcbn1cblxudmFyIENvbG9ycyA9IGV4cG9ydHMuQ29sb3JzID0gU2V0dGluZ3MuQ29sb3JzXG5cbi8vIENvbG9yIHBhbGV0dGUgcHVsbGVkIGZyb20gTW9jaGFcbmZ1bmN0aW9uIGNvbG9yVG9OdW1iZXIobmFtZSkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuICAgIGNhc2UgXCJwYXNzXCI6IHJldHVybiA5MFxuICAgIGNhc2UgXCJmYWlsXCI6IHJldHVybiAzMVxuXG4gICAgY2FzZSBcImJyaWdodCBwYXNzXCI6IHJldHVybiA5MlxuICAgIGNhc2UgXCJicmlnaHQgZmFpbFwiOiByZXR1cm4gOTFcbiAgICBjYXNlIFwiYnJpZ2h0IHllbGxvd1wiOiByZXR1cm4gOTNcblxuICAgIGNhc2UgXCJza2lwXCI6IHJldHVybiAzNlxuICAgIGNhc2UgXCJzdWl0ZVwiOiByZXR1cm4gMFxuICAgIGNhc2UgXCJwbGFpblwiOiByZXR1cm4gMFxuXG4gICAgY2FzZSBcImVycm9yIHRpdGxlXCI6IHJldHVybiAwXG4gICAgY2FzZSBcImVycm9yIG1lc3NhZ2VcIjogcmV0dXJuIDMxXG4gICAgY2FzZSBcImVycm9yIHN0YWNrXCI6IHJldHVybiA5MFxuXG4gICAgY2FzZSBcImNoZWNrbWFya1wiOiByZXR1cm4gMzJcbiAgICBjYXNlIFwiZmFzdFwiOiByZXR1cm4gOTBcbiAgICBjYXNlIFwibWVkaXVtXCI6IHJldHVybiAzM1xuICAgIGNhc2UgXCJzbG93XCI6IHJldHVybiAzMVxuICAgIGNhc2UgXCJncmVlblwiOiByZXR1cm4gMzJcbiAgICBjYXNlIFwibGlnaHRcIjogcmV0dXJuIDkwXG5cbiAgICBjYXNlIFwiZGlmZiBndXR0ZXJcIjogcmV0dXJuIDkwXG4gICAgY2FzZSBcImRpZmYgYWRkZWRcIjogcmV0dXJuIDMyXG4gICAgY2FzZSBcImRpZmYgcmVtb3ZlZFwiOiByZXR1cm4gMzFcbiAgICBkZWZhdWx0OiB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBuYW1lOiBcXFwiXCIgKyBuYW1lICsgXCJcXFwiXCIpXG4gICAgfVxufVxuXG5leHBvcnRzLmNvbG9yID0gY29sb3JcbmZ1bmN0aW9uIGNvbG9yKG5hbWUsIHN0cikge1xuICAgIGlmIChDb2xvcnMuc3VwcG9ydGVkKCkpIHtcbiAgICAgICAgcmV0dXJuIFwiXFx1MDAxYltcIiArIGNvbG9yVG9OdW1iZXIobmFtZSkgKyBcIm1cIiArIHN0ciArIFwiXFx1MDAxYlswbVwiXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHN0ciArIFwiXCJcbiAgICB9XG59XG5cbmV4cG9ydHMuc2V0Q29sb3IgPSBmdW5jdGlvbiAoXykge1xuICAgIGlmIChfLm9wdHMuY29sb3IgIT0gbnVsbCkgQ29sb3JzLm1heWJlU2V0KF8ub3B0cy5jb2xvcilcbn1cblxuZXhwb3J0cy51bnNldENvbG9yID0gZnVuY3Rpb24gKF8pIHtcbiAgICBpZiAoXy5vcHRzLmNvbG9yICE9IG51bGwpIENvbG9ycy5tYXliZVJlc3RvcmUoKVxufVxuXG52YXIgU3RhdHVzID0gZXhwb3J0cy5TdGF0dXMgPSBPYmplY3QuZnJlZXplKHtcbiAgICBVbmtub3duOiAwLFxuICAgIFNraXBwZWQ6IDEsXG4gICAgUGFzc2luZzogMixcbiAgICBGYWlsaW5nOiAzLFxufSlcblxuZXhwb3J0cy5UcmVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlXG4gICAgdGhpcy5zdGF0dXMgPSBTdGF0dXMuVW5rbm93blxuICAgIHRoaXMuY2hpbGRyZW4gPSBPYmplY3QuY3JlYXRlKG51bGwpXG59XG5cbmV4cG9ydHMuZGVmYXVsdGlmeSA9IGZ1bmN0aW9uIChfLCBvcHRzLCBwcm9wKSB7XG4gICAgaWYgKF8ubWV0aG9kcy5hY2NlcHRzLmluZGV4T2YocHJvcCkgPj0gMCkge1xuICAgICAgICB2YXIgdXNlZCA9IG9wdHMgIT0gbnVsbCAmJiB0eXBlb2Ygb3B0c1twcm9wXSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICA/IG9wdHNcbiAgICAgICAgICAgIDogU2V0dGluZ3MuZGVmYXVsdE9wdHMoKVxuXG4gICAgICAgIF8ub3B0c1twcm9wXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodXNlZFtwcm9wXS5hcHBseSh1c2VkLCBhcmd1bWVudHMpKVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBqb2luUGF0aChyZXBvcnRQYXRoKSB7XG4gICAgdmFyIHBhdGggPSBcIlwiXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcG9ydFBhdGgubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcGF0aCArPSBcIiBcIiArIHJlcG9ydFBhdGhbaV0ubmFtZVxuICAgIH1cblxuICAgIHJldHVybiBwYXRoLnNsaWNlKDEpXG59XG5cbmV4cG9ydHMuam9pblBhdGggPSBmdW5jdGlvbiAocmVwb3J0KSB7XG4gICAgcmV0dXJuIGpvaW5QYXRoKHJlcG9ydC5wYXRoKVxufVxuXG5leHBvcnRzLnNwZWVkID0gZnVuY3Rpb24gKHJlcG9ydCkge1xuICAgIGlmIChyZXBvcnQuZHVyYXRpb24gPj0gcmVwb3J0LnNsb3cpIHJldHVybiBcInNsb3dcIlxuICAgIGlmIChyZXBvcnQuZHVyYXRpb24gPj0gcmVwb3J0LnNsb3cgLyAyKSByZXR1cm4gXCJtZWRpdW1cIlxuICAgIGlmIChyZXBvcnQuZHVyYXRpb24gPj0gMCkgcmV0dXJuIFwiZmFzdFwiXG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJEdXJhdGlvbiBtdXN0IG5vdCBiZSBuZWdhdGl2ZVwiKVxufVxuXG5leHBvcnRzLmZvcm1hdFRpbWUgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBzID0gMTAwMCAvKiBtcyAqL1xuICAgIHZhciBtID0gNjAgKiBzXG4gICAgdmFyIGggPSA2MCAqIG1cbiAgICB2YXIgZCA9IDI0ICogaFxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChtcykge1xuICAgICAgICBpZiAobXMgPj0gZCkgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArIFwiZFwiXG4gICAgICAgIGlmIChtcyA+PSBoKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIGgpICsgXCJoXCJcbiAgICAgICAgaWYgKG1zID49IG0pIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gbSkgKyBcIm1cIlxuICAgICAgICBpZiAobXMgPj0gcykgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArIFwic1wiXG4gICAgICAgIHJldHVybiBtcyArIFwibXNcIlxuICAgIH1cbn0pKClcblxuZXhwb3J0cy5mb3JtYXRSZXN0ID0gZnVuY3Rpb24gKHJlcG9ydCkge1xuICAgIGlmICghcmVwb3J0LmlzSG9vaykgcmV0dXJuIFwiXCJcbiAgICB2YXIgcGF0aCA9IFwiIChcIlxuXG4gICAgaWYgKHJlcG9ydC5yb290UGF0aC5sZW5ndGgpIHtcbiAgICAgICAgcGF0aCArPSByZXBvcnQuc3RhZ2VcbiAgICAgICAgaWYgKHJlcG9ydC5uYW1lKSBwYXRoICs9IFwiIOKAkiBcIiArIHJlcG9ydC5uYW1lXG4gICAgICAgIGlmIChyZXBvcnQucGF0aC5sZW5ndGggPiByZXBvcnQucm9vdFBhdGgubGVuZ3RoICsgMSkge1xuICAgICAgICAgICAgcGF0aCArPSBcIiwgaW4gXCIgKyBqb2luUGF0aChyZXBvcnQucm9vdFBhdGgpXG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXRoICs9IFwiZ2xvYmFsIFwiICsgcmVwb3J0LnN0YWdlXG4gICAgICAgIGlmIChyZXBvcnQubmFtZSkgcGF0aCArPSBcIiDigJIgXCIgKyByZXBvcnQubmFtZVxuICAgIH1cblxuICAgIHJldHVybiBwYXRoICsgXCIpXCJcbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8vIEdlbmVyYWwgQ0xJIGFuZCByZXBvcnRlciBzZXR0aW5ncy4gSWYgc29tZXRoaW5nIG5lZWRzIHRvXG5cbnZhciBDb25zb2xlID0gcmVxdWlyZShcIi4vcmVwbGFjZWQvY29uc29sZVwiKVxuXG52YXIgd2luZG93V2lkdGggPSBDb25zb2xlLndpbmRvd1dpZHRoXG52YXIgbmV3bGluZSA9IENvbnNvbGUubmV3bGluZVxudmFyIFN5bWJvbHMgPSBDb25zb2xlLlN5bWJvbHNcbnZhciBkZWZhdWx0T3B0cyA9IENvbnNvbGUuZGVmYXVsdE9wdHNcblxuZXhwb3J0cy53aW5kb3dXaWR0aCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHdpbmRvd1dpZHRoIH1cbmV4cG9ydHMubmV3bGluZSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ld2xpbmUgfVxuZXhwb3J0cy5zeW1ib2xzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gU3ltYm9scyB9XG5leHBvcnRzLmRlZmF1bHRPcHRzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gZGVmYXVsdE9wdHMgfVxuXG5leHBvcnRzLnNldFdpbmRvd1dpZHRoID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiB3aW5kb3dXaWR0aCA9IHZhbHVlIH1cbmV4cG9ydHMuc2V0TmV3bGluZSA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gbmV3bGluZSA9IHZhbHVlIH1cbmV4cG9ydHMuc2V0U3ltYm9scyA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gU3ltYm9scyA9IHZhbHVlIH1cbmV4cG9ydHMuc2V0RGVmYXVsdE9wdHMgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIGRlZmF1bHRPcHRzID0gdmFsdWUgfVxuXG4vLyBDb25zb2xlLmNvbG9yU3VwcG9ydCBpcyBhIG1hc2sgd2l0aCB0aGUgZm9sbG93aW5nIGJpdHM6XG4vLyAweDEgLSBpZiBzZXQsIGNvbG9ycyBzdXBwb3J0ZWQgYnkgZGVmYXVsdFxuLy8gMHgyIC0gaWYgc2V0LCBmb3JjZSBjb2xvciBzdXBwb3J0XG4vL1xuLy8gVGhpcyBpcyBwdXJlbHkgYW4gaW1wbGVtZW50YXRpb24gZGV0YWlsLCBhbmQgaXMgaW52aXNpYmxlIHRvIHRoZSBvdXRzaWRlXG4vLyB3b3JsZC5cbnZhciBjb2xvclN1cHBvcnQgPSBDb25zb2xlLmNvbG9yU3VwcG9ydFxudmFyIG1hc2sgPSBjb2xvclN1cHBvcnRcblxuZXhwb3J0cy5Db2xvcnMgPSB7XG4gICAgc3VwcG9ydGVkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAobWFzayAmIDB4MSkgIT09IDBcbiAgICB9LFxuXG4gICAgZm9yY2VkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAobWFzayAmIDB4MikgIT09IDBcbiAgICB9LFxuXG4gICAgbWF5YmVTZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAoKG1hc2sgJiAweDIpID09PSAwKSBtYXNrID0gdmFsdWUgPyAweDEgOiAwXG4gICAgfSxcblxuICAgIG1heWJlUmVzdG9yZTogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoKG1hc2sgJiAweDIpID09PSAwKSBtYXNrID0gY29sb3JTdXBwb3J0ICYgMHgxXG4gICAgfSxcblxuICAgIC8vIE9ubHkgZm9yIGRlYnVnZ2luZ1xuICAgIGZvcmNlU2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgbWFzayA9IHZhbHVlID8gMHgzIDogMHgyXG4gICAgfSxcblxuICAgIGZvcmNlUmVzdG9yZTogZnVuY3Rpb24gKCkge1xuICAgICAgICBtYXNrID0gY29sb3JTdXBwb3J0XG4gICAgfSxcblxuICAgIGdldFN1cHBvcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1cHBvcnRlZDogKGNvbG9yU3VwcG9ydCAmIDB4MSkgIT09IDAsXG4gICAgICAgICAgICBmb3JjZWQ6IChjb2xvclN1cHBvcnQgJiAweDIpICE9PSAwLFxuICAgICAgICB9XG4gICAgfSxcblxuICAgIHNldFN1cHBvcnQ6IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgICAgIG1hc2sgPSBjb2xvclN1cHBvcnQgPVxuICAgICAgICAgICAgKG9wdHMuc3VwcG9ydGVkID8gMHgxIDogMCkgfCAob3B0cy5mb3JjZWQgPyAweDIgOiAwKVxuICAgIH0sXG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgbWV0aG9kcyA9IHJlcXVpcmUoXCIuL21ldGhvZHNcIilcblxuZXhwb3J0cy5nZXRUeXBlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBcIm51bGxcIlxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIFwiYXJyYXlcIlxuICAgIHJldHVybiB0eXBlb2YgdmFsdWVcbn1cblxuLy8gUGhhbnRvbUpTLCBJRSwgYW5kIHBvc3NpYmx5IEVkZ2UgZG9uJ3Qgc2V0IHRoZSBzdGFjayB0cmFjZSB1bnRpbCB0aGUgZXJyb3IgaXNcbi8vIHRocm93bi4gTm90ZSB0aGF0IHRoaXMgcHJlZmVycyBhbiBleGlzdGluZyBzdGFjayBmaXJzdCwgc2luY2Ugbm9uLW5hdGl2ZVxuLy8gZXJyb3JzIGxpa2VseSBhbHJlYWR5IGNvbnRhaW4gdGhpcy4gTm90ZSB0aGF0IHRoaXMgaXNuJ3QgbmVjZXNzYXJ5IGluIHRoZVxuLy8gQ0xJIC0gdGhhdCBvbmx5IHRhcmdldHMgTm9kZS5cbmV4cG9ydHMuZ2V0U3RhY2sgPSBmdW5jdGlvbiAoZSkge1xuICAgIHZhciBzdGFjayA9IGUuc3RhY2tcblxuICAgIGlmICghKGUgaW5zdGFuY2VvZiBFcnJvcikgfHwgc3RhY2sgIT0gbnVsbCkgcmV0dXJuIHN0YWNrXG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBlXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZS5zdGFja1xuICAgIH1cbn1cblxuZXhwb3J0cy5wY2FsbCA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmMoZnVuY3Rpb24gKGUsIHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gZSAhPSBudWxsID8gcmVqZWN0KGUpIDogcmVzb2x2ZSh2YWx1ZSlcbiAgICAgICAgfSlcbiAgICB9KVxufVxuXG5leHBvcnRzLnBlYWNoID0gZnVuY3Rpb24gKGxpc3QsIGZ1bmMpIHtcbiAgICB2YXIgbGVuID0gbGlzdC5sZW5ndGhcbiAgICB2YXIgcCA9IFByb21pc2UucmVzb2x2ZSgpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHAgPSBwLnRoZW4oZnVuYy5iaW5kKHVuZGVmaW5lZCwgbGlzdFtpXSwgaSkpXG4gICAgfVxuXG4gICAgcmV0dXJuIHBcbn1cblxuLyoqXG4gKiBBIGxhenkgYWNjZXNzb3IsIGNvbXBsZXRlIHdpdGggdGhyb3duIGVycm9yIG1lbW9pemF0aW9uIGFuZCBhIGRlY2VudCBhbW91bnRcbiAqIG9mIG9wdGltaXphdGlvbiwgc2luY2UgaXQncyB1c2VkIGluIGEgbG90IG9mIGNvZGUuXG4gKlxuICogTm90ZSB0aGF0IHRoaXMgdXNlcyByZWZlcmVuY2UgaW5kaXJlY3Rpb24gYW5kIGRpcmVjdCBtdXRhdGlvbiB0byBrZWVwIG9ubHlcbiAqIGp1c3QgdGhlIGNvbXB1dGF0aW9uIG5vbi1jb25zdGFudCwgc28gZW5naW5lcyBjYW4gYXZvaWQgY2xvc3VyZSBhbGxvY2F0aW9uLlxuICogQWxzbywgYGNyZWF0ZWAgaXMgaW50ZW50aW9uYWxseSBrZXB0ICpvdXQqIG9mIGFueSBjbG9zdXJlLCBzbyBpdCBjYW4gYmUgbW9yZVxuICogZWFzaWx5IGNvbGxlY3RlZC5cbiAqL1xuZnVuY3Rpb24gTGF6eShjcmVhdGUpIHtcbiAgICB0aGlzLnZhbHVlID0gY3JlYXRlXG4gICAgdGhpcy5nZXQgPSB0aGlzLmluaXRcbn1cblxubWV0aG9kcyhMYXp5LCB7XG4gICAgcmVjdXJzaXZlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJMYXp5IGZ1bmN0aW9ucyBtdXN0IG5vdCBiZSBjYWxsZWQgcmVjdXJzaXZlbHkhXCIpXG4gICAgfSxcblxuICAgIHJldHVybjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZVxuICAgIH0sXG5cbiAgICB0aHJvdzogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aHJvdyB0aGlzLnZhbHVlXG4gICAgfSxcblxuICAgIGluaXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5nZXQgPSB0aGlzLnJlY3Vyc2l2ZVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gKDAsIHRoaXMudmFsdWUpKClcbiAgICAgICAgICAgIHRoaXMuZ2V0ID0gdGhpcy5yZXR1cm5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBlXG4gICAgICAgICAgICB0aGlzLmdldCA9IHRoaXMudGhyb3dcbiAgICAgICAgICAgIHRocm93IHRoaXMudmFsdWVcbiAgICAgICAgfVxuICAgIH0sXG59KVxuXG5leHBvcnRzLmxhenkgPSBmdW5jdGlvbiAoY3JlYXRlKSB7XG4gICAgdmFyIHJlZiA9IG5ldyBMYXp5KGNyZWF0ZSlcblxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiByZWYuZ2V0KClcbiAgICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh4cywgZikge1xuICAgIGlmICh4cy5tYXApIHJldHVybiB4cy5tYXAoZik7XG4gICAgdmFyIHJlcyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHggPSB4c1tpXTtcbiAgICAgICAgaWYgKGhhc093bi5jYWxsKHhzLCBpKSkgcmVzLnB1c2goZih4LCBpLCB4cykpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufTtcblxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG4iLCJ2YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoeHMsIGYsIGFjYykge1xuICAgIHZhciBoYXNBY2MgPSBhcmd1bWVudHMubGVuZ3RoID49IDM7XG4gICAgaWYgKGhhc0FjYyAmJiB4cy5yZWR1Y2UpIHJldHVybiB4cy5yZWR1Y2UoZiwgYWNjKTtcbiAgICBpZiAoeHMucmVkdWNlKSByZXR1cm4geHMucmVkdWNlKGYpO1xuICAgIFxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKCFoYXNPd24uY2FsbCh4cywgaSkpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIWhhc0FjYykge1xuICAgICAgICAgICAgYWNjID0geHNbaV07XG4gICAgICAgICAgICBoYXNBY2MgPSB0cnVlO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgYWNjID0gZihhY2MsIHhzW2ldLCBpKTtcbiAgICB9XG4gICAgcmV0dXJuIGFjYztcbn07XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3N1YnN0YWNrL25vZGUtYnJvd3NlcmlmeS9pc3N1ZXMvMTY3NFxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ1dGlsLWluc3BlY3RcIilcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBpbnNwZWN0ID0gZXhwb3J0cy5pbnNwZWN0ID0gcmVxdWlyZShcIi4vaW5zcGVjdFwiKVxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcbnZhciBBc3NlcnRpb25FcnJvclxuXG4vLyBQaGFudG9tSlMsIElFLCBhbmQgcG9zc2libHkgRWRnZSBkb24ndCBzZXQgdGhlIHN0YWNrIHRyYWNlIHVudGlsIHRoZSBlcnJvciBpc1xuLy8gdGhyb3duLiBOb3RlIHRoYXQgdGhpcyBwcmVmZXJzIGFuIGV4aXN0aW5nIHN0YWNrIGZpcnN0LCBzaW5jZSBub24tbmF0aXZlXG4vLyBlcnJvcnMgbGlrZWx5IGFscmVhZHkgY29udGFpbiB0aGlzLlxuZnVuY3Rpb24gZ2V0U3RhY2soZSkge1xuICAgIHZhciBzdGFjayA9IGUuc3RhY2tcblxuICAgIGlmICghKGUgaW5zdGFuY2VvZiBFcnJvcikgfHwgc3RhY2sgIT0gbnVsbCkgcmV0dXJuIHN0YWNrXG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBlXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZS5zdGFja1xuICAgIH1cbn1cblxudHJ5IHtcbiAgICBBc3NlcnRpb25FcnJvciA9IG5ldyBGdW5jdGlvbihbIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3LWZ1bmNcbiAgICAgICAgXCIndXNlIHN0cmljdCc7XCIsXG4gICAgICAgIFwiY2xhc3MgQXNzZXJ0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7XCIsXG4gICAgICAgIFwiICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIGV4cGVjdGVkLCBhY3R1YWwpIHtcIixcbiAgICAgICAgXCIgICAgICAgIHN1cGVyKG1lc3NhZ2UpXCIsXG4gICAgICAgIFwiICAgICAgICB0aGlzLmV4cGVjdGVkID0gZXhwZWN0ZWRcIixcbiAgICAgICAgXCIgICAgICAgIHRoaXMuYWN0dWFsID0gYWN0dWFsXCIsXG4gICAgICAgIFwiICAgIH1cIixcbiAgICAgICAgXCJcIixcbiAgICAgICAgXCIgICAgZ2V0IG5hbWUoKSB7XCIsXG4gICAgICAgIFwiICAgICAgICByZXR1cm4gJ0Fzc2VydGlvbkVycm9yJ1wiLFxuICAgICAgICBcIiAgICB9XCIsXG4gICAgICAgIFwifVwiLFxuICAgICAgICAvLyBjaGVjayBuYXRpdmUgc3ViY2xhc3Npbmcgc3VwcG9ydFxuICAgICAgICBcIm5ldyBBc3NlcnRpb25FcnJvcignbWVzc2FnZScsIDEsIDIpXCIsXG4gICAgICAgIFwicmV0dXJuIEFzc2VydGlvbkVycm9yXCIsXG4gICAgXS5qb2luKFwiXFxuXCIpKSgpXG59IGNhdGNoIChlKSB7XG4gICAgQXNzZXJ0aW9uRXJyb3IgPSB0eXBlb2YgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICA/IGZ1bmN0aW9uIEFzc2VydGlvbkVycm9yKG1lc3NhZ2UsIGV4cGVjdGVkLCBhY3R1YWwpIHtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgXCJcIlxuICAgICAgICAgICAgdGhpcy5leHBlY3RlZCA9IGV4cGVjdGVkXG4gICAgICAgICAgICB0aGlzLmFjdHVhbCA9IGFjdHVhbFxuICAgICAgICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3RvcilcbiAgICAgICAgfVxuICAgICAgICA6IGZ1bmN0aW9uIEFzc2VydGlvbkVycm9yKG1lc3NhZ2UsIGV4cGVjdGVkLCBhY3R1YWwpIHtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgXCJcIlxuICAgICAgICAgICAgdGhpcy5leHBlY3RlZCA9IGV4cGVjdGVkXG4gICAgICAgICAgICB0aGlzLmFjdHVhbCA9IGFjdHVhbFxuICAgICAgICAgICAgdmFyIGUgPSBuZXcgRXJyb3IobWVzc2FnZSlcblxuICAgICAgICAgICAgZS5uYW1lID0gXCJBc3NlcnRpb25FcnJvclwiXG4gICAgICAgICAgICB0aGlzLnN0YWNrID0gZ2V0U3RhY2soZSlcbiAgICAgICAgfVxuXG4gICAgQXNzZXJ0aW9uRXJyb3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShFcnJvci5wcm90b3R5cGUpXG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQXNzZXJ0aW9uRXJyb3IucHJvdG90eXBlLCBcImNvbnN0cnVjdG9yXCIsIHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHZhbHVlOiBBc3NlcnRpb25FcnJvcixcbiAgICB9KVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFzc2VydGlvbkVycm9yLnByb3RvdHlwZSwgXCJuYW1lXCIsIHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHZhbHVlOiBcIkFzc2VydGlvbkVycm9yXCIsXG4gICAgfSlcbn1cblxuZXhwb3J0cy5Bc3NlcnRpb25FcnJvciA9IEFzc2VydGlvbkVycm9yXG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXNlbGYtY29tcGFyZSAqL1xuLy8gRm9yIGJldHRlciBOYU4gaGFuZGxpbmdcbmV4cG9ydHMuc3RyaWN0SXMgPSBmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiBhID09PSBiIHx8IGEgIT09IGEgJiYgYiAhPT0gYlxufVxuXG5leHBvcnRzLmxvb3NlSXMgPSBmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiBhID09IGIgfHwgYSAhPT0gYSAmJiBiICE9PSBiIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG59XG5cbi8qIGVzbGludC1lbmFibGUgbm8tc2VsZi1jb21wYXJlICovXG5cbnZhciB0ZW1wbGF0ZVJlZ2V4cCA9IC8oLj8pXFx7KC4rPylcXH0vZ1xuXG5leHBvcnRzLmVzY2FwZSA9IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgICBpZiAodHlwZW9mIHN0cmluZyAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYHN0cmluZ2AgbXVzdCBiZSBhIHN0cmluZ1wiKVxuICAgIH1cblxuICAgIHJldHVybiBzdHJpbmcucmVwbGFjZSh0ZW1wbGF0ZVJlZ2V4cCwgZnVuY3Rpb24gKG0sIHByZSkge1xuICAgICAgICByZXR1cm4gcHJlICsgXCJcXFxcXCIgKyBtLnNsaWNlKDEpXG4gICAgfSlcbn1cblxuLy8gVGhpcyBmb3JtYXRzIHRoZSBhc3NlcnRpb24gZXJyb3IgbWVzc2FnZXMuXG5leHBvcnRzLmZvcm1hdCA9IGZ1bmN0aW9uIChtZXNzYWdlLCBhcmdzLCBwcmV0dGlmeSkge1xuICAgIGlmIChwcmV0dGlmeSA9PSBudWxsKSBwcmV0dGlmeSA9IGluc3BlY3RcblxuICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG1lc3NhZ2VgIG11c3QgYmUgYSBzdHJpbmdcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGFyZ3MgIT09IFwib2JqZWN0XCIgfHwgYXJncyA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGFyZ3NgIG11c3QgYmUgYW4gb2JqZWN0XCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBwcmV0dGlmeSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgcHJldHRpZnlgIG11c3QgYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICB9XG5cbiAgICByZXR1cm4gbWVzc2FnZS5yZXBsYWNlKHRlbXBsYXRlUmVnZXhwLCBmdW5jdGlvbiAobSwgcHJlLCBwcm9wKSB7XG4gICAgICAgIGlmIChwcmUgPT09IFwiXFxcXFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gbS5zbGljZSgxKVxuICAgICAgICB9IGVsc2UgaWYgKGhhc093bi5jYWxsKGFyZ3MsIHByb3ApKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJlICsgcHJldHRpZnkoYXJnc1twcm9wXSwge2RlcHRoOiA1fSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBwcmUgKyBtXG4gICAgICAgIH1cbiAgICB9KVxufVxuXG5leHBvcnRzLmZhaWwgPSBmdW5jdGlvbiAobWVzc2FnZSwgYXJncywgcHJldHRpZnkpIHtcbiAgICBpZiAoYXJncyA9PSBudWxsKSB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobWVzc2FnZSlcbiAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoXG4gICAgICAgIGV4cG9ydHMuZm9ybWF0KG1lc3NhZ2UsIGFyZ3MsIHByZXR0aWZ5KSxcbiAgICAgICAgYXJncy5leHBlY3RlZCxcbiAgICAgICAgYXJncy5hY3R1YWwpXG59XG5cbi8vIFRoZSBiYXNpYyBhc3NlcnQsIGxpa2UgYGFzc2VydC5va2AsIGJ1dCBnaXZlcyB5b3UgYW4gb3B0aW9uYWwgbWVzc2FnZS5cbmV4cG9ydHMuYXNzZXJ0ID0gZnVuY3Rpb24gKHRlc3QsIG1lc3NhZ2UpIHtcbiAgICBpZiAoIXRlc3QpIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtZXNzYWdlKVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLyoqXG4gKiBDb3JlIFRERC1zdHlsZSBhc3NlcnRpb25zLiBUaGVzZSBhcmUgZG9uZSBieSBhIGNvbXBvc2l0aW9uIG9mIERTTHMsIHNpbmNlXG4gKiB0aGVyZSBpcyAqc28qIG11Y2ggcmVwZXRpdGlvbi4gQWxzbywgdGhpcyBpcyBzcGxpdCBpbnRvIHNldmVyYWwgbmFtZXNwYWNlcyB0b1xuICoga2VlcCB0aGUgZmlsZSBzaXplIG1hbmFnZWFibGUuXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0LXV0aWxcIilcbnZhciB0eXBlID0gcmVxdWlyZShcIi4vbGliL3R5cGVcIilcbnZhciBlcXVhbCA9IHJlcXVpcmUoXCIuL2xpYi9lcXVhbFwiKVxudmFyIHRocm93cyA9IHJlcXVpcmUoXCIuL2xpYi90aHJvd3NcIilcbnZhciBoYXMgPSByZXF1aXJlKFwiLi9saWIvaGFzXCIpXG52YXIgaW5jbHVkZXMgPSByZXF1aXJlKFwiLi9saWIvaW5jbHVkZXNcIilcbnZhciBoYXNLZXlzID0gcmVxdWlyZShcIi4vbGliL2hhcy1rZXlzXCIpXG5cbmV4cG9ydHMuQXNzZXJ0aW9uRXJyb3IgPSB1dGlsLkFzc2VydGlvbkVycm9yXG5leHBvcnRzLmFzc2VydCA9IHV0aWwuYXNzZXJ0XG5leHBvcnRzLmZhaWwgPSB1dGlsLmZhaWxcblxuZXhwb3J0cy5vayA9IHR5cGUub2tcbmV4cG9ydHMubm90T2sgPSB0eXBlLm5vdE9rXG5leHBvcnRzLmlzQm9vbGVhbiA9IHR5cGUuaXNCb29sZWFuXG5leHBvcnRzLm5vdEJvb2xlYW4gPSB0eXBlLm5vdEJvb2xlYW5cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IHR5cGUuaXNGdW5jdGlvblxuZXhwb3J0cy5ub3RGdW5jdGlvbiA9IHR5cGUubm90RnVuY3Rpb25cbmV4cG9ydHMuaXNOdW1iZXIgPSB0eXBlLmlzTnVtYmVyXG5leHBvcnRzLm5vdE51bWJlciA9IHR5cGUubm90TnVtYmVyXG5leHBvcnRzLmlzT2JqZWN0ID0gdHlwZS5pc09iamVjdFxuZXhwb3J0cy5ub3RPYmplY3QgPSB0eXBlLm5vdE9iamVjdFxuZXhwb3J0cy5pc1N0cmluZyA9IHR5cGUuaXNTdHJpbmdcbmV4cG9ydHMubm90U3RyaW5nID0gdHlwZS5ub3RTdHJpbmdcbmV4cG9ydHMuaXNTeW1ib2wgPSB0eXBlLmlzU3ltYm9sXG5leHBvcnRzLm5vdFN5bWJvbCA9IHR5cGUubm90U3ltYm9sXG5leHBvcnRzLmV4aXN0cyA9IHR5cGUuZXhpc3RzXG5leHBvcnRzLm5vdEV4aXN0cyA9IHR5cGUubm90RXhpc3RzXG5leHBvcnRzLmlzQXJyYXkgPSB0eXBlLmlzQXJyYXlcbmV4cG9ydHMubm90QXJyYXkgPSB0eXBlLm5vdEFycmF5XG5leHBvcnRzLmlzID0gdHlwZS5pc1xuZXhwb3J0cy5ub3QgPSB0eXBlLm5vdFxuXG5leHBvcnRzLmVxdWFsID0gZXF1YWwuZXF1YWxcbmV4cG9ydHMubm90RXF1YWwgPSBlcXVhbC5ub3RFcXVhbFxuZXhwb3J0cy5lcXVhbExvb3NlID0gZXF1YWwuZXF1YWxMb29zZVxuZXhwb3J0cy5ub3RFcXVhbExvb3NlID0gZXF1YWwubm90RXF1YWxMb29zZVxuZXhwb3J0cy5kZWVwRXF1YWwgPSBlcXVhbC5kZWVwRXF1YWxcbmV4cG9ydHMubm90RGVlcEVxdWFsID0gZXF1YWwubm90RGVlcEVxdWFsXG5leHBvcnRzLm1hdGNoID0gZXF1YWwubWF0Y2hcbmV4cG9ydHMubm90TWF0Y2ggPSBlcXVhbC5ub3RNYXRjaFxuZXhwb3J0cy5hdExlYXN0ID0gZXF1YWwuYXRMZWFzdFxuZXhwb3J0cy5hdE1vc3QgPSBlcXVhbC5hdE1vc3RcbmV4cG9ydHMuYWJvdmUgPSBlcXVhbC5hYm92ZVxuZXhwb3J0cy5iZWxvdyA9IGVxdWFsLmJlbG93XG5leHBvcnRzLmJldHdlZW4gPSBlcXVhbC5iZXR3ZWVuXG5leHBvcnRzLmNsb3NlVG8gPSBlcXVhbC5jbG9zZVRvXG5leHBvcnRzLm5vdENsb3NlVG8gPSBlcXVhbC5ub3RDbG9zZVRvXG5cbmV4cG9ydHMudGhyb3dzID0gdGhyb3dzLnRocm93c1xuZXhwb3J0cy50aHJvd3NNYXRjaCA9IHRocm93cy50aHJvd3NNYXRjaFxuXG5leHBvcnRzLmhhc093biA9IGhhcy5oYXNPd25cbmV4cG9ydHMubm90SGFzT3duID0gaGFzLm5vdEhhc093blxuZXhwb3J0cy5oYXNPd25Mb29zZSA9IGhhcy5oYXNPd25Mb29zZVxuZXhwb3J0cy5ub3RIYXNPd25Mb29zZSA9IGhhcy5ub3RIYXNPd25Mb29zZVxuZXhwb3J0cy5oYXNLZXkgPSBoYXMuaGFzS2V5XG5leHBvcnRzLm5vdEhhc0tleSA9IGhhcy5ub3RIYXNLZXlcbmV4cG9ydHMuaGFzS2V5TG9vc2UgPSBoYXMuaGFzS2V5TG9vc2VcbmV4cG9ydHMubm90SGFzS2V5TG9vc2UgPSBoYXMubm90SGFzS2V5TG9vc2VcbmV4cG9ydHMuaGFzID0gaGFzLmhhc1xuZXhwb3J0cy5ub3RIYXMgPSBoYXMubm90SGFzXG5leHBvcnRzLmhhc0xvb3NlID0gaGFzLmhhc0xvb3NlXG5leHBvcnRzLm5vdEhhc0xvb3NlID0gaGFzLm5vdEhhc0xvb3NlXG5cbi8qKlxuICogVGhlcmUncyAyIHNldHMgb2YgMTIgcGVybXV0YXRpb25zIGhlcmUgZm9yIGBpbmNsdWRlc2AgYW5kIGBoYXNLZXlzYCwgaW5zdGVhZFxuICogb2YgTiBzZXRzIG9mIDIgKHdoaWNoIHdvdWxkIGZpdCB0aGUgYGZvb2AvYG5vdEZvb2AgaWRpb20gYmV0dGVyKSwgc28gaXQnc1xuICogZWFzaWVyIHRvIGp1c3QgbWFrZSBhIGNvdXBsZSBzZXBhcmF0ZSBEU0xzIGFuZCB1c2UgdGhhdCB0byBkZWZpbmUgZXZlcnl0aGluZy5cbiAqXG4gKiBIZXJlJ3MgdGhlIHRvcCBsZXZlbDpcbiAqXG4gKiAtIHNoYWxsb3dcbiAqIC0gc3RyaWN0IGRlZXBcbiAqIC0gc3RydWN0dXJhbCBkZWVwXG4gKlxuICogQW5kIHRoZSBzZWNvbmQgbGV2ZWw6XG4gKlxuICogLSBpbmNsdWRlcyBhbGwvbm90IG1pc3Npbmcgc29tZVxuICogLSBpbmNsdWRlcyBzb21lL25vdCBtaXNzaW5nIGFsbFxuICogLSBub3QgaW5jbHVkaW5nIGFsbC9taXNzaW5nIHNvbWVcbiAqIC0gbm90IGluY2x1ZGluZyBzb21lL21pc3NpbmcgYWxsXG4gKlxuICogSGVyZSdzIGFuIGV4YW1wbGUgdXNpbmcgdGhlIG5hbWluZyBzY2hlbWUgZm9yIGBoYXNLZXlzKmBcbiAqXG4gKiAgICAgICAgICAgICAgIHwgICAgIHNoYWxsb3cgICAgIHwgICAgc3RyaWN0IGRlZXAgICAgICB8ICAgc3RydWN0dXJhbCBkZWVwXG4gKiAtLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogaW5jbHVkZXMgYWxsICB8IGBoYXNLZXlzYCAgICAgICB8IGBoYXNLZXlzRGVlcGAgICAgICAgfCBgaGFzS2V5c01hdGNoYFxuICogaW5jbHVkZXMgc29tZSB8IGBoYXNLZXlzQW55YCAgICB8IGBoYXNLZXlzQW55RGVlcGAgICAgfCBgaGFzS2V5c0FueU1hdGNoYFxuICogbWlzc2luZyBzb21lICB8IGBub3RIYXNLZXlzQWxsYCB8IGBub3RIYXNLZXlzQWxsRGVlcGAgfCBgbm90SGFzS2V5c0FsbE1hdGNoYFxuICogbWlzc2luZyBhbGwgICB8IGBub3RIYXNLZXlzYCAgICB8IGBub3RIYXNLZXlzRGVlcGAgICAgfCBgbm90SGFzS2V5c01hdGNoYFxuICpcbiAqIE5vdGUgdGhhdCB0aGUgYGhhc0tleXNgIHNoYWxsb3cgY29tcGFyaXNvbiB2YXJpYW50cyBhcmUgYWxzbyBvdmVybG9hZGVkIHRvXG4gKiBjb25zdW1lIGVpdGhlciBhbiBhcnJheSAoaW4gd2hpY2ggaXQgc2ltcGx5IGNoZWNrcyBhZ2FpbnN0IGEgbGlzdCBvZiBrZXlzKSBvclxuICogYW4gb2JqZWN0ICh3aGVyZSBpdCBkb2VzIGEgZnVsbCBkZWVwIGNvbXBhcmlzb24pLlxuICovXG5cbmV4cG9ydHMuaW5jbHVkZXMgPSBpbmNsdWRlcy5pbmNsdWRlc1xuZXhwb3J0cy5pbmNsdWRlc0RlZXAgPSBpbmNsdWRlcy5pbmNsdWRlc0RlZXBcbmV4cG9ydHMuaW5jbHVkZXNNYXRjaCA9IGluY2x1ZGVzLmluY2x1ZGVzTWF0Y2hcbmV4cG9ydHMuaW5jbHVkZXNBbnkgPSBpbmNsdWRlcy5pbmNsdWRlc0FueVxuZXhwb3J0cy5pbmNsdWRlc0FueURlZXAgPSBpbmNsdWRlcy5pbmNsdWRlc0FueURlZXBcbmV4cG9ydHMuaW5jbHVkZXNBbnlNYXRjaCA9IGluY2x1ZGVzLmluY2x1ZGVzQW55TWF0Y2hcbmV4cG9ydHMubm90SW5jbHVkZXNBbGwgPSBpbmNsdWRlcy5ub3RJbmNsdWRlc0FsbFxuZXhwb3J0cy5ub3RJbmNsdWRlc0FsbERlZXAgPSBpbmNsdWRlcy5ub3RJbmNsdWRlc0FsbERlZXBcbmV4cG9ydHMubm90SW5jbHVkZXNBbGxNYXRjaCA9IGluY2x1ZGVzLm5vdEluY2x1ZGVzQWxsTWF0Y2hcbmV4cG9ydHMubm90SW5jbHVkZXMgPSBpbmNsdWRlcy5ub3RJbmNsdWRlc1xuZXhwb3J0cy5ub3RJbmNsdWRlc0RlZXAgPSBpbmNsdWRlcy5ub3RJbmNsdWRlc0RlZXBcbmV4cG9ydHMubm90SW5jbHVkZXNNYXRjaCA9IGluY2x1ZGVzLm5vdEluY2x1ZGVzTWF0Y2hcblxuZXhwb3J0cy5oYXNLZXlzID0gaGFzS2V5cy5oYXNLZXlzXG5leHBvcnRzLmhhc0tleXNEZWVwID0gaGFzS2V5cy5oYXNLZXlzRGVlcFxuZXhwb3J0cy5oYXNLZXlzTWF0Y2ggPSBoYXNLZXlzLmhhc0tleXNNYXRjaFxuZXhwb3J0cy5oYXNLZXlzQW55ID0gaGFzS2V5cy5oYXNLZXlzQW55XG5leHBvcnRzLmhhc0tleXNBbnlEZWVwID0gaGFzS2V5cy5oYXNLZXlzQW55RGVlcFxuZXhwb3J0cy5oYXNLZXlzQW55TWF0Y2ggPSBoYXNLZXlzLmhhc0tleXNBbnlNYXRjaFxuZXhwb3J0cy5ub3RIYXNLZXlzQWxsID0gaGFzS2V5cy5ub3RIYXNLZXlzQWxsXG5leHBvcnRzLm5vdEhhc0tleXNBbGxEZWVwID0gaGFzS2V5cy5ub3RIYXNLZXlzQWxsRGVlcFxuZXhwb3J0cy5ub3RIYXNLZXlzQWxsTWF0Y2ggPSBoYXNLZXlzLm5vdEhhc0tleXNBbGxNYXRjaFxuZXhwb3J0cy5ub3RIYXNLZXlzID0gaGFzS2V5cy5ub3RIYXNLZXlzXG5leHBvcnRzLm5vdEhhc0tleXNEZWVwID0gaGFzS2V5cy5ub3RIYXNLZXlzRGVlcFxuZXhwb3J0cy5ub3RIYXNLZXlzTWF0Y2ggPSBoYXNLZXlzLm5vdEhhc0tleXNNYXRjaFxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIG1hdGNoID0gcmVxdWlyZShcImNsZWFuLW1hdGNoXCIpXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKVxuXG5mdW5jdGlvbiBiaW5hcnkobnVtZXJpYywgY29tcGFyYXRvciwgbWVzc2FnZSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoYWN0dWFsLCBleHBlY3RlZCkge1xuICAgICAgICBpZiAobnVtZXJpYykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBhY3R1YWwgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGFjdHVhbGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGV4cGVjdGVkICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBleHBlY3RlZGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFjb21wYXJhdG9yKGFjdHVhbCwgZXhwZWN0ZWQpKSB7XG4gICAgICAgICAgICB1dGlsLmZhaWwobWVzc2FnZSwge2FjdHVhbDogYWN0dWFsLCBleHBlY3RlZDogZXhwZWN0ZWR9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnRzLmVxdWFsID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiB1dGlsLnN0cmljdElzKGEsIGIpIH0sXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBlcXVhbCB7ZXhwZWN0ZWR9XCIpXG5cbmV4cG9ydHMubm90RXF1YWwgPSBiaW5hcnkoZmFsc2UsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuICF1dGlsLnN0cmljdElzKGEsIGIpIH0sXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgZXF1YWwge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLmVxdWFsTG9vc2UgPSBiaW5hcnkoZmFsc2UsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIHV0aWwubG9vc2VJcyhhLCBiKSB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbG9vc2VseSBlcXVhbCB7ZXhwZWN0ZWR9XCIpXG5cbmV4cG9ydHMubm90RXF1YWxMb29zZSA9IGJpbmFyeShmYWxzZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gIXV0aWwubG9vc2VJcyhhLCBiKSB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGxvb3NlbHkgZXF1YWwge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLmF0TGVhc3QgPSBiaW5hcnkodHJ1ZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYSA+PSBiIH0sXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhdCBsZWFzdCB7ZXhwZWN0ZWR9XCIpXG5cbmV4cG9ydHMuYXRNb3N0ID0gYmluYXJ5KHRydWUsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEgPD0gYiB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYXQgbW9zdCB7ZXhwZWN0ZWR9XCIpXG5cbmV4cG9ydHMuYWJvdmUgPSBiaW5hcnkodHJ1ZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYSA+IGIgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGFib3ZlIHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5iZWxvdyA9IGJpbmFyeSh0cnVlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhIDwgYiB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYmVsb3cge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLmJldHdlZW4gPSBmdW5jdGlvbiAoYWN0dWFsLCBsb3dlciwgdXBwZXIpIHtcbiAgICBpZiAodHlwZW9mIGFjdHVhbCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGFjdHVhbGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbG93ZXIgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBsb3dlcmAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdXBwZXIgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImB1cHBlcmAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIC8vIFRoZSBuZWdhdGlvbiBpcyB0byBhZGRyZXNzIE5hTnMgYXMgd2VsbCwgd2l0aG91dCB3cml0aW5nIGEgdG9uIG9mIHNwZWNpYWxcbiAgICAvLyBjYXNlIGJvaWxlcnBsYXRlXG4gICAgaWYgKCEoYWN0dWFsID49IGxvd2VyICYmIGFjdHVhbCA8PSB1cHBlcikpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYmV0d2VlbiB7bG93ZXJ9IGFuZCB7dXBwZXJ9XCIsIHtcbiAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuICAgICAgICAgICAgbG93ZXI6IGxvd2VyLFxuICAgICAgICAgICAgdXBwZXI6IHVwcGVyLFxuICAgICAgICB9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5kZWVwRXF1YWwgPSBiaW5hcnkoZmFsc2UsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIG1hdGNoLnN0cmljdChhLCBiKSB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gZGVlcGx5IGVxdWFsIHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5ub3REZWVwRXF1YWwgPSBiaW5hcnkoZmFsc2UsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuICFtYXRjaC5zdHJpY3QoYSwgYikgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBkZWVwbHkgZXF1YWwge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLm1hdGNoID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBtYXRjaC5sb29zZShhLCBiKSB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbWF0Y2gge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLm5vdE1hdGNoID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiAhbWF0Y2gubG9vc2UoYSwgYikgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCB7ZXhwZWN0ZWR9XCIpXG5cbi8vIFVzZXMgZGl2aXNpb24gdG8gYWxsb3cgZm9yIGEgbW9yZSByb2J1c3QgY29tcGFyaXNvbiBvZiBmbG9hdHMuIEFsc28sIHRoaXNcbi8vIGhhbmRsZXMgbmVhci16ZXJvIGNvbXBhcmlzb25zIGNvcnJlY3RseSwgYXMgd2VsbCBhcyBhIHplcm8gdG9sZXJhbmNlIChpLmUuXG4vLyBleGFjdCBjb21wYXJpc29uKS5cbmZ1bmN0aW9uIGNsb3NlVG8oZXhwZWN0ZWQsIGFjdHVhbCwgdG9sZXJhbmNlKSB7XG4gICAgaWYgKHRvbGVyYW5jZSA9PT0gSW5maW5pdHkgfHwgYWN0dWFsID09PSBleHBlY3RlZCkgcmV0dXJuIHRydWVcbiAgICBpZiAodG9sZXJhbmNlID09PSAwKSByZXR1cm4gZmFsc2VcbiAgICBpZiAoYWN0dWFsID09PSAwKSByZXR1cm4gTWF0aC5hYnMoZXhwZWN0ZWQpIDwgdG9sZXJhbmNlXG4gICAgaWYgKGV4cGVjdGVkID09PSAwKSByZXR1cm4gTWF0aC5hYnMoYWN0dWFsKSA8IHRvbGVyYW5jZVxuICAgIHJldHVybiBNYXRoLmFicyhleHBlY3RlZCAvIGFjdHVhbCAtIDEpIDwgdG9sZXJhbmNlXG59XG5cbi8vIE5vdGU6IHRoZXNlIHR3byBhbHdheXMgZmFpbCB3aGVuIGRlYWxpbmcgd2l0aCBOYU5zLlxuZXhwb3J0cy5jbG9zZVRvID0gZnVuY3Rpb24gKGV4cGVjdGVkLCBhY3R1YWwsIHRvbGVyYW5jZSkge1xuICAgIGlmICh0eXBlb2YgYWN0dWFsICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgYWN0dWFsYCBtdXN0IGJlIGEgbnVtYmVyXCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBleHBlY3RlZCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGV4cGVjdGVkYCBtdXN0IGJlIGEgbnVtYmVyXCIpXG4gICAgfVxuXG4gICAgaWYgKHRvbGVyYW5jZSA9PSBudWxsKSB0b2xlcmFuY2UgPSAxZS0xMFxuXG4gICAgaWYgKHR5cGVvZiB0b2xlcmFuY2UgIT09IFwibnVtYmVyXCIgfHwgdG9sZXJhbmNlIDwgMCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgXCJgdG9sZXJhbmNlYCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIG51bWJlciBpZiBnaXZlblwiKVxuICAgIH1cblxuICAgIGlmIChhY3R1YWwgIT09IGFjdHVhbCB8fCBleHBlY3RlZCAhPT0gZXhwZWN0ZWQgfHwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmUsIG1heC1sZW5cbiAgICAgICAgICAgICFjbG9zZVRvKGV4cGVjdGVkLCBhY3R1YWwsIHRvbGVyYW5jZSkpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgY2xvc2UgdG8ge2V4cGVjdGVkfVwiLCB7XG4gICAgICAgICAgICBhY3R1YWw6IGFjdHVhbCxcbiAgICAgICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZCxcbiAgICAgICAgfSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90Q2xvc2VUbyA9IGZ1bmN0aW9uIChleHBlY3RlZCwgYWN0dWFsLCB0b2xlcmFuY2UpIHtcbiAgICBpZiAodHlwZW9mIGFjdHVhbCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGFjdHVhbGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZXhwZWN0ZWQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBleHBlY3RlZGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIGlmICh0b2xlcmFuY2UgPT0gbnVsbCkgdG9sZXJhbmNlID0gMWUtMTBcblxuICAgIGlmICh0eXBlb2YgdG9sZXJhbmNlICE9PSBcIm51bWJlclwiIHx8IHRvbGVyYW5jZSA8IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgIFwiYHRvbGVyYW5jZWAgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIgaWYgZ2l2ZW5cIilcbiAgICB9XG5cbiAgICBpZiAoZXhwZWN0ZWQgIT09IGV4cGVjdGVkIHx8IGFjdHVhbCAhPT0gYWN0dWFsIHx8IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlLCBtYXgtbGVuXG4gICAgICAgICAgICBjbG9zZVRvKGV4cGVjdGVkLCBhY3R1YWwsIHRvbGVyYW5jZSkpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGJlIGNsb3NlIHRvIHtleHBlY3RlZH1cIiwge1xuICAgICAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgICAgICAgICBleHBlY3RlZDogZXhwZWN0ZWQsXG4gICAgICAgIH0pXG4gICAgfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIG1hdGNoID0gcmVxdWlyZShcImNsZWFuLW1hdGNoXCIpXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKVxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuZnVuY3Rpb24gaGFzS2V5cyhhbGwsIG9iamVjdCwga2V5cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgdGVzdCA9IGhhc093bi5jYWxsKG9iamVjdCwga2V5c1tpXSlcblxuICAgICAgICBpZiAodGVzdCAhPT0gYWxsKSByZXR1cm4gIWFsbFxuICAgIH1cblxuICAgIHJldHVybiBhbGxcbn1cblxuZnVuY3Rpb24gaGFzVmFsdWVzKGZ1bmMsIGFsbCwgb2JqZWN0LCBrZXlzKSB7XG4gICAgaWYgKG9iamVjdCA9PT0ga2V5cykgcmV0dXJuIHRydWVcbiAgICB2YXIgbGlzdCA9IE9iamVjdC5rZXlzKGtleXMpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGtleSA9IGxpc3RbaV1cbiAgICAgICAgdmFyIHRlc3QgPSBoYXNPd24uY2FsbChvYmplY3QsIGtleSkgJiYgZnVuYyhrZXlzW2tleV0sIG9iamVjdFtrZXldKVxuXG4gICAgICAgIGlmICh0ZXN0ICE9PSBhbGwpIHJldHVybiB0ZXN0XG4gICAgfVxuXG4gICAgcmV0dXJuIGFsbFxufVxuXG5mdW5jdGlvbiBtYWtlSGFzT3ZlcmxvYWQoYWxsLCBpbnZlcnQsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCwga2V5cykge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdCAhPT0gXCJvYmplY3RcIiB8fCBvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBvYmplY3RgIG11c3QgYmUgYW4gb2JqZWN0XCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGtleXMgIT09IFwib2JqZWN0XCIgfHwga2V5cyA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGtleXNgIG11c3QgYmUgYW4gb2JqZWN0IG9yIGFycmF5XCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShrZXlzKSkge1xuICAgICAgICAgICAgaWYgKGtleXMubGVuZ3RoICYmIGhhc0tleXMoYWxsLCBvYmplY3QsIGtleXMpID09PSBpbnZlcnQpIHtcbiAgICAgICAgICAgICAgICB1dGlsLmZhaWwobWVzc2FnZSwge2FjdHVhbDogb2JqZWN0LCBrZXlzOiBrZXlzfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChPYmplY3Qua2V5cyhrZXlzKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChoYXNWYWx1ZXModXRpbC5zdHJpY3RJcywgYWxsLCBvYmplY3QsIGtleXMpID09PSBpbnZlcnQpIHtcbiAgICAgICAgICAgICAgICB1dGlsLmZhaWwobWVzc2FnZSwge2FjdHVhbDogb2JqZWN0LCBrZXlzOiBrZXlzfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gbWFrZUhhc0tleXMoZnVuYywgYWxsLCBpbnZlcnQsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCwga2V5cykge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdCAhPT0gXCJvYmplY3RcIiB8fCBvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBvYmplY3RgIG11c3QgYmUgYW4gb2JqZWN0XCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGtleXMgIT09IFwib2JqZWN0XCIgfHwga2V5cyA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGtleXNgIG11c3QgYmUgYW4gb2JqZWN0XCIpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBleGNsdXNpdmUgb3IgdG8gaW52ZXJ0IHRoZSByZXN1bHQgaWYgYGludmVydGAgaXMgdHJ1ZVxuICAgICAgICBpZiAoT2JqZWN0LmtleXMoa2V5cykubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoaGFzVmFsdWVzKGZ1bmMsIGFsbCwgb2JqZWN0LCBrZXlzKSA9PT0gaW52ZXJ0KSB7XG4gICAgICAgICAgICAgICAgdXRpbC5mYWlsKG1lc3NhZ2UsIHthY3R1YWw6IG9iamVjdCwga2V5czoga2V5c30pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxuZXhwb3J0cy5oYXNLZXlzID0gbWFrZUhhc092ZXJsb2FkKHRydWUsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUgYWxsIGtleXMgaW4ge2tleXN9XCIpXG5leHBvcnRzLmhhc0tleXNEZWVwID0gbWFrZUhhc0tleXMobWF0Y2guc3RyaWN0LCB0cnVlLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxuZXhwb3J0cy5oYXNLZXlzTWF0Y2ggPSBtYWtlSGFzS2V5cyhtYXRjaC5sb29zZSwgdHJ1ZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbWF0Y2ggYWxsIGtleXMgaW4ge2tleXN9XCIpXG5leHBvcnRzLmhhc0tleXNBbnkgPSBtYWtlSGFzT3ZlcmxvYWQoZmFsc2UsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUgYW55IGtleSBpbiB7a2V5c31cIilcbmV4cG9ydHMuaGFzS2V5c0FueURlZXAgPSBtYWtlSGFzS2V5cyhtYXRjaC5zdHJpY3QsIGZhbHNlLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGFueSBrZXkgaW4ge2tleXN9XCIpXG5leHBvcnRzLmhhc0tleXNBbnlNYXRjaCA9IG1ha2VIYXNLZXlzKG1hdGNoLmxvb3NlLCBmYWxzZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbWF0Y2ggYW55IGtleSBpbiB7a2V5c31cIilcbmV4cG9ydHMubm90SGFzS2V5c0FsbCA9IG1ha2VIYXNPdmVybG9hZCh0cnVlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxuZXhwb3J0cy5ub3RIYXNLZXlzQWxsRGVlcCA9IG1ha2VIYXNLZXlzKG1hdGNoLnN0cmljdCwgdHJ1ZSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBhbGwga2V5cyBpbiB7a2V5c31cIilcbmV4cG9ydHMubm90SGFzS2V5c0FsbE1hdGNoID0gbWFrZUhhc0tleXMobWF0Y2gubG9vc2UsIHRydWUsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IG1hdGNoIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxuZXhwb3J0cy5ub3RIYXNLZXlzID0gbWFrZUhhc092ZXJsb2FkKGZhbHNlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGFueSBrZXkgaW4ge2tleXN9XCIpXG5leHBvcnRzLm5vdEhhc0tleXNEZWVwID0gbWFrZUhhc0tleXMobWF0Y2guc3RyaWN0LCBmYWxzZSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBhbnkga2V5IGluIHtrZXlzfVwiKVxuZXhwb3J0cy5ub3RIYXNLZXlzTWF0Y2ggPSBtYWtlSGFzS2V5cyhtYXRjaC5sb29zZSwgZmFsc2UsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IG1hdGNoIGFueSBrZXkgaW4ge2tleXN9XCIpXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKVxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuZnVuY3Rpb24gaGFzKF8pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuLCBtYXgtcGFyYW1zXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykge1xuICAgICAgICAgICAgaWYgKCFfLmhhcyhvYmplY3QsIGtleSkgfHxcbiAgICAgICAgICAgICAgICAgICAgIXV0aWwuc3RyaWN0SXMoXy5nZXQob2JqZWN0LCBrZXkpLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB1dGlsLmZhaWwoXy5tZXNzYWdlc1swXSwge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0W2tleV0sXG4gICAgICAgICAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCFfLmhhcyhvYmplY3QsIGtleSkpIHtcbiAgICAgICAgICAgIHV0aWwuZmFpbChfLm1lc3NhZ2VzWzFdLCB7XG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IHZhbHVlLFxuICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0W2tleV0sXG4gICAgICAgICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBoYXNMb29zZShfKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKCFfLmhhcyhvYmplY3QsIGtleSkgfHwgIXV0aWwubG9vc2VJcyhfLmdldChvYmplY3QsIGtleSksIHZhbHVlKSkge1xuICAgICAgICAgICAgdXRpbC5mYWlsKF8ubWVzc2FnZXNbMF0sIHtcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogdmFsdWUsXG4gICAgICAgICAgICAgICAgYWN0dWFsOiBvYmplY3Rba2V5XSxcbiAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIG5vdEhhcyhfKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlbiwgbWF4LXBhcmFtc1xuICAgIHJldHVybiBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIHtcbiAgICAgICAgICAgIGlmIChfLmhhcyhvYmplY3QsIGtleSkgJiZcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5zdHJpY3RJcyhfLmdldChvYmplY3QsIGtleSksIHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHV0aWwuZmFpbChfLm1lc3NhZ2VzWzJdLCB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgYWN0dWFsOiBvYmplY3Rba2V5XSxcbiAgICAgICAgICAgICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdDogb2JqZWN0LFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoXy5oYXMob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgICAgICB1dGlsLmZhaWwoXy5tZXNzYWdlc1szXSwge1xuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICBhY3R1YWw6IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgICAgIG9iamVjdDogb2JqZWN0LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gbm90SGFzTG9vc2UoXykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW4sIG1heC1wYXJhbXNcbiAgICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICAgICAgICBpZiAoXy5oYXMob2JqZWN0LCBrZXkpICYmIHV0aWwubG9vc2VJcyhfLmdldChvYmplY3QsIGtleSksIHZhbHVlKSkge1xuICAgICAgICAgICAgdXRpbC5mYWlsKF8ubWVzc2FnZXNbMl0sIHtcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogdmFsdWUsXG4gICAgICAgICAgICAgICAgYWN0dWFsOiBvYmplY3Rba2V5XSxcbiAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGhhc093bktleShvYmplY3QsIGtleSkgeyByZXR1cm4gaGFzT3duLmNhbGwob2JqZWN0LCBrZXkpIH1cbmZ1bmN0aW9uIGhhc0luS2V5KG9iamVjdCwga2V5KSB7IHJldHVybiBrZXkgaW4gb2JqZWN0IH1cbmZ1bmN0aW9uIGhhc0luQ29sbChvYmplY3QsIGtleSkgeyByZXR1cm4gb2JqZWN0LmhhcyhrZXkpIH1cbmZ1bmN0aW9uIGhhc09iamVjdEdldChvYmplY3QsIGtleSkgeyByZXR1cm4gb2JqZWN0W2tleV0gfVxuZnVuY3Rpb24gaGFzQ29sbEdldChvYmplY3QsIGtleSkgeyByZXR1cm4gb2JqZWN0LmdldChrZXkpIH1cblxuZnVuY3Rpb24gY3JlYXRlSGFzKGhhcywgZ2V0LCBtZXNzYWdlcykge1xuICAgIHJldHVybiB7aGFzOiBoYXMsIGdldDogZ2V0LCBtZXNzYWdlczogbWVzc2FnZXN9XG59XG5cbnZhciBoYXNPd25NZXRob2RzID0gY3JlYXRlSGFzKGhhc093bktleSwgaGFzT2JqZWN0R2V0LCBbXG4gICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBoYXZlIG93biBrZXkge2tleX0gZXF1YWwgdG8ge2V4cGVjdGVkfSwgYnV0IGZvdW5kIHthY3R1YWx9XCIsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBvd24ga2V5IHtleHBlY3RlZH1cIixcbiAgICBcIkV4cGVjdGVkIHtvYmplY3R9IHRvIG5vdCBoYXZlIG93biBrZXkge2tleX0gZXF1YWwgdG8ge2FjdHVhbH1cIixcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIG93biBrZXkge2V4cGVjdGVkfVwiLFxuXSlcblxudmFyIGhhc0tleU1ldGhvZHMgPSBjcmVhdGVIYXMoaGFzSW5LZXksIGhhc09iamVjdEdldCwgW1xuICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gaGF2ZSBrZXkge2tleX0gZXF1YWwgdG8ge2V4cGVjdGVkfSwgYnV0IGZvdW5kIHthY3R1YWx9XCIsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBrZXkge2V4cGVjdGVkfVwiLFxuICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gbm90IGhhdmUga2V5IHtrZXl9IGVxdWFsIHRvIHthY3R1YWx9XCIsXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBrZXkge2V4cGVjdGVkfVwiLFxuXSlcblxudmFyIGhhc01ldGhvZHMgPSBjcmVhdGVIYXMoaGFzSW5Db2xsLCBoYXNDb2xsR2V0LCBbXG4gICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBoYXZlIGtleSB7a2V5fSBlcXVhbCB0byB7ZXhwZWN0ZWR9LCBidXQgZm91bmQge2FjdHVhbH1cIiwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGtleSB7ZXhwZWN0ZWR9XCIsXG4gICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBub3QgaGF2ZSBrZXkge2tleX0gZXF1YWwgdG8ge2FjdHVhbH1cIixcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGtleSB7ZXhwZWN0ZWR9XCIsXG5dKVxuXG5leHBvcnRzLmhhc093biA9IGhhcyhoYXNPd25NZXRob2RzKVxuZXhwb3J0cy5ub3RIYXNPd24gPSBub3RIYXMoaGFzT3duTWV0aG9kcylcbmV4cG9ydHMuaGFzT3duTG9vc2UgPSBoYXNMb29zZShoYXNPd25NZXRob2RzKVxuZXhwb3J0cy5ub3RIYXNPd25Mb29zZSA9IG5vdEhhc0xvb3NlKGhhc093bk1ldGhvZHMpXG5cbmV4cG9ydHMuaGFzS2V5ID0gaGFzKGhhc0tleU1ldGhvZHMpXG5leHBvcnRzLm5vdEhhc0tleSA9IG5vdEhhcyhoYXNLZXlNZXRob2RzKVxuZXhwb3J0cy5oYXNLZXlMb29zZSA9IGhhc0xvb3NlKGhhc0tleU1ldGhvZHMpXG5leHBvcnRzLm5vdEhhc0tleUxvb3NlID0gbm90SGFzTG9vc2UoaGFzS2V5TWV0aG9kcylcblxuZXhwb3J0cy5oYXMgPSBoYXMoaGFzTWV0aG9kcylcbmV4cG9ydHMubm90SGFzID0gbm90SGFzKGhhc01ldGhvZHMpXG5leHBvcnRzLmhhc0xvb3NlID0gaGFzTG9vc2UoaGFzTWV0aG9kcylcbmV4cG9ydHMubm90SGFzTG9vc2UgPSBub3RIYXNMb29zZShoYXNNZXRob2RzKVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIG1hdGNoID0gcmVxdWlyZShcImNsZWFuLW1hdGNoXCIpXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKVxuXG5mdW5jdGlvbiBpbmNsdWRlcyhmdW5jLCBhbGwsIGFycmF5LCB2YWx1ZXMpIHtcbiAgICAvLyBDaGVhcCBjYXNlcyBmaXJzdFxuICAgIGlmICghQXJyYXkuaXNBcnJheShhcnJheSkpIHJldHVybiBmYWxzZVxuICAgIGlmIChhcnJheSA9PT0gdmFsdWVzKSByZXR1cm4gdHJ1ZVxuICAgIGlmIChhbGwgJiYgYXJyYXkubGVuZ3RoIDwgdmFsdWVzLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgdmFsdWUgPSB2YWx1ZXNbaV1cbiAgICAgICAgdmFyIHRlc3QgPSBmYWxzZVxuXG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgYXJyYXkubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChmdW5jKHZhbHVlLCBhcnJheVtqXSkpIHtcbiAgICAgICAgICAgICAgICB0ZXN0ID0gdHJ1ZVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGVzdCAhPT0gYWxsKSByZXR1cm4gdGVzdFxuICAgIH1cblxuICAgIHJldHVybiBhbGxcbn1cblxuZnVuY3Rpb24gZGVmaW5lSW5jbHVkZXMoZnVuYywgYWxsLCBpbnZlcnQsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGFycmF5LCB2YWx1ZXMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFycmF5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBhcnJheWAgbXVzdCBiZSBhbiBhcnJheVwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlcykpIHZhbHVlcyA9IFt2YWx1ZXNdXG5cbiAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggJiYgaW5jbHVkZXMoZnVuYywgYWxsLCBhcnJheSwgdmFsdWVzKSA9PT0gaW52ZXJ0KSB7XG4gICAgICAgICAgICB1dGlsLmZhaWwobWVzc2FnZSwge2FjdHVhbDogYXJyYXksIHZhbHVlczogdmFsdWVzfSlcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuXG5leHBvcnRzLmluY2x1ZGVzID0gZGVmaW5lSW5jbHVkZXModXRpbC5zdHJpY3RJcywgdHJ1ZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBhbGwgdmFsdWVzIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLmluY2x1ZGVzRGVlcCA9IGRlZmluZUluY2x1ZGVzKG1hdGNoLnN0cmljdCwgdHJ1ZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbWF0Y2ggYWxsIHZhbHVlcyBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5pbmNsdWRlc01hdGNoID0gZGVmaW5lSW5jbHVkZXMobWF0Y2gubG9vc2UsIHRydWUsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFsbCB2YWx1ZXMgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMuaW5jbHVkZXNBbnkgPSBkZWZpbmVJbmNsdWRlcyh1dGlsLnN0cmljdElzLCBmYWxzZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMuaW5jbHVkZXNBbnlEZWVwID0gZGVmaW5lSW5jbHVkZXMobWF0Y2guc3RyaWN0LCBmYWxzZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbWF0Y2ggYW55IHZhbHVlIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLmluY2x1ZGVzQW55TWF0Y2ggPSBkZWZpbmVJbmNsdWRlcyhtYXRjaC5sb29zZSwgZmFsc2UsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFueSB2YWx1ZSBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5ub3RJbmNsdWRlc0FsbCA9IGRlZmluZUluY2x1ZGVzKHV0aWwuc3RyaWN0SXMsIHRydWUsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUgYWxsIHZhbHVlcyBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5ub3RJbmNsdWRlc0FsbERlZXAgPSBkZWZpbmVJbmNsdWRlcyhtYXRjaC5zdHJpY3QsIHRydWUsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IG1hdGNoIGFsbCB2YWx1ZXMgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMubm90SW5jbHVkZXNBbGxNYXRjaCA9IGRlZmluZUluY2x1ZGVzKG1hdGNoLmxvb3NlLCB0cnVlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbGwgdmFsdWVzIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLm5vdEluY2x1ZGVzID0gZGVmaW5lSW5jbHVkZXModXRpbC5zdHJpY3RJcywgZmFsc2UsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUgYW55IHZhbHVlIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLm5vdEluY2x1ZGVzRGVlcCA9IGRlZmluZUluY2x1ZGVzKG1hdGNoLnN0cmljdCwgZmFsc2UsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IG1hdGNoIGFueSB2YWx1ZSBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5ub3RJbmNsdWRlc01hdGNoID0gZGVmaW5lSW5jbHVkZXMobWF0Y2gubG9vc2UsIGZhbHNlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciB1dGlsID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpXG5cbmZ1bmN0aW9uIGdldE5hbWUoZnVuYykge1xuICAgIHZhciBuYW1lID0gZnVuYy5uYW1lXG5cbiAgICBpZiAobmFtZSA9PSBudWxsKSBuYW1lID0gZnVuYy5kaXNwbGF5TmFtZVxuICAgIGlmIChuYW1lKSByZXR1cm4gdXRpbC5lc2NhcGUobmFtZSlcbiAgICByZXR1cm4gXCI8YW5vbnltb3VzPlwiXG59XG5cbmV4cG9ydHMudGhyb3dzID0gZnVuY3Rpb24gKFR5cGUsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGNhbGxiYWNrID09IG51bGwpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBUeXBlXG4gICAgICAgIFR5cGUgPSBudWxsXG4gICAgfVxuXG4gICAgaWYgKFR5cGUgIT0gbnVsbCAmJiB0eXBlb2YgVHlwZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgVHlwZWAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGNhbGxiYWNrYCBtdXN0IGJlIGEgZnVuY3Rpb25cIilcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICBjYWxsYmFjaygpIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY2FsbGJhY2stcmV0dXJuXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoVHlwZSAhPSBudWxsICYmICEoZSBpbnN0YW5jZW9mIFR5cGUpKSB7XG4gICAgICAgICAgICB1dGlsLmZhaWwoXG4gICAgICAgICAgICAgICAgXCJFeHBlY3RlZCBjYWxsYmFjayB0byB0aHJvdyBhbiBpbnN0YW5jZSBvZiBcIiArIGdldE5hbWUoVHlwZSkgK1xuICAgICAgICAgICAgICAgIFwiLCBidXQgZm91bmQge2FjdHVhbH1cIixcbiAgICAgICAgICAgICAgICB7YWN0dWFsOiBlfSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgdXRpbC5Bc3NlcnRpb25FcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIHRocm93XCIpXG59XG5cbmZ1bmN0aW9uIHRocm93c01hdGNoVGVzdChtYXRjaGVyLCBlKSB7XG4gICAgaWYgKHR5cGVvZiBtYXRjaGVyID09PSBcInN0cmluZ1wiKSByZXR1cm4gZS5tZXNzYWdlID09PSBtYXRjaGVyXG4gICAgaWYgKHR5cGVvZiBtYXRjaGVyID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiAhIW1hdGNoZXIoZSlcbiAgICBpZiAobWF0Y2hlciBpbnN0YW5jZW9mIFJlZ0V4cCkgcmV0dXJuICEhbWF0Y2hlci50ZXN0KGUubWVzc2FnZSlcblxuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMobWF0Y2hlcilcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIga2V5ID0ga2V5c1tpXVxuXG4gICAgICAgIGlmICghKGtleSBpbiBlKSB8fCAhdXRpbC5zdHJpY3RJcyhtYXRjaGVyW2tleV0sIGVba2V5XSkpIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG59XG5cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3Qob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCA9PSBudWxsIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpID09PSBPYmplY3QucHJvdG90eXBlXG59XG5cbmV4cG9ydHMudGhyb3dzTWF0Y2ggPSBmdW5jdGlvbiAobWF0Y2hlciwgY2FsbGJhY2spIHtcbiAgICBpZiAodHlwZW9mIG1hdGNoZXIgIT09IFwic3RyaW5nXCIgJiZcbiAgICAgICAgICAgIHR5cGVvZiBtYXRjaGVyICE9PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgICAgICEobWF0Y2hlciBpbnN0YW5jZW9mIFJlZ0V4cCkgJiZcbiAgICAgICAgICAgICFpc1BsYWluT2JqZWN0KG1hdGNoZXIpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICBcImBtYXRjaGVyYCBtdXN0IGJlIGEgc3RyaW5nLCBmdW5jdGlvbiwgUmVnRXhwLCBvciBvYmplY3RcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBjYWxsYmFja2AgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgY2FsbGJhY2soKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGNhbGxiYWNrLXJldHVyblxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKCF0aHJvd3NNYXRjaFRlc3QobWF0Y2hlciwgZSkpIHtcbiAgICAgICAgICAgIHV0aWwuZmFpbChcbiAgICAgICAgICAgICAgICBcIkV4cGVjdGVkIGNhbGxiYWNrIHRvICB0aHJvdyBhbiBlcnJvciB0aGF0IG1hdGNoZXMgXCIgK1xuICAgICAgICAgICAgICAgIFwie2V4cGVjdGVkfSwgYnV0IGZvdW5kIHthY3R1YWx9XCIsXG4gICAgICAgICAgICAgICAge2V4cGVjdGVkOiBtYXRjaGVyLCBhY3R1YWw6IGV9KVxuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRocm93IG5ldyB1dGlsLkFzc2VydGlvbkVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gdGhyb3cuXCIpXG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKVxuXG5leHBvcnRzLm9rID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAoIXgpIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIHRydXRoeVwiLCB7YWN0dWFsOiB4fSlcbn1cblxuZXhwb3J0cy5ub3RPayA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHgpIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGZhbHN5XCIsIHthY3R1YWw6IHh9KVxufVxuXG5leHBvcnRzLmlzQm9vbGVhbiA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSBcImJvb2xlYW5cIikge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhIGJvb2xlYW5cIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdEJvb2xlYW4gPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCA9PT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGJlIGEgYm9vbGVhblwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYSBmdW5jdGlvblwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90RnVuY3Rpb24gPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBhIGZ1bmN0aW9uXCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5pc051bWJlciA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGEgbnVtYmVyXCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5ub3ROdW1iZXIgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgYmUgYSBudW1iZXJcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLmlzT2JqZWN0ID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggIT09IFwib2JqZWN0XCIgfHwgeCA9PSBudWxsKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGFuIG9iamVjdFwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90T2JqZWN0ID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggPT09IFwib2JqZWN0XCIgJiYgeCAhPSBudWxsKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBhbiBvYmplY3RcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLmlzU3RyaW5nID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYSBzdHJpbmdcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdFN0cmluZyA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBhIHN0cmluZ1wiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMuaXNTeW1ib2wgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCAhPT0gXCJzeW1ib2xcIikge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhIHN5bWJvbFwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90U3ltYm9sID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggPT09IFwic3ltYm9sXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGJlIGEgc3ltYm9sXCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5leGlzdHMgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh4ID09IG51bGwpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gZXhpc3RcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdEV4aXN0cyA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHggIT0gbnVsbCkge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgZXhpc3RcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLmlzQXJyYXkgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICghQXJyYXkuaXNBcnJheSh4KSkge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhbiBhcnJheVwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90QXJyYXkgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHgpKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBhbiBhcnJheVwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMuaXMgPSBmdW5jdGlvbiAoVHlwZSwgb2JqZWN0KSB7XG4gICAgaWYgKHR5cGVvZiBUeXBlICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBUeXBlYCBtdXN0IGJlIGEgZnVuY3Rpb25cIilcbiAgICB9XG5cbiAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBUeXBlKSkge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBiZSBhbiBpbnN0YW5jZSBvZiB7ZXhwZWN0ZWR9XCIsIHtcbiAgICAgICAgICAgIGV4cGVjdGVkOiBUeXBlLFxuICAgICAgICAgICAgYWN0dWFsOiBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgfSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90ID0gZnVuY3Rpb24gKFR5cGUsIG9iamVjdCkge1xuICAgIGlmICh0eXBlb2YgVHlwZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgVHlwZWAgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgfVxuXG4gICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIFR5cGUpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge29iamVjdH0gdG8gbm90IGJlIGFuIGluc3RhbmNlIG9mIHtleHBlY3RlZH1cIiwge1xuICAgICAgICAgICAgZXhwZWN0ZWQ6IFR5cGUsXG4gICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgfSlcbiAgICB9XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBjbGVhbi1tYXRjaFxuICpcbiAqIEEgc2ltcGxlLCBmYXN0IEVTMjAxNSsgYXdhcmUgZGVlcCBtYXRjaGluZyB1dGlsaXR5LlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxNiBhbmQgbGF0ZXIsIElzaWFoIE1lYWRvd3MgPG1lQGlzaWFobWVhZG93cy5jb20+LlxuICpcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxuICogcHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZVxuICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcy5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXG4gKiBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcbiAqIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcbiAqIElORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxuICogTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcbiAqIE9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcbiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXG4gKi9cblxuLyogZXNsaW50LWRpc2FibGUgKi9cbjsoZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuICAgIGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIiAmJiBleHBvcnRzICE9IG51bGwpIHtcbiAgICAgICAgZmFjdG9yeShnbG9iYWwsIGV4cG9ydHMpXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgZGVmaW5lKFwiY2xlYW4tbWF0Y2hcIiwgW1wiZXhwb3J0c1wiXSwgZnVuY3Rpb24gKGV4cG9ydHMpIHtcbiAgICAgICAgICAgIGZhY3RvcnkoZ2xvYmFsLCBleHBvcnRzKVxuICAgICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGZhY3RvcnkoZ2xvYmFsLCBnbG9iYWwubWF0Y2ggPSB7fSlcbiAgICB9XG59KSh0eXBlb2YgZ2xvYmFsID09PSBcIm9iamVjdFwiICYmIGdsb2JhbCAhPT0gbnVsbCA/IGdsb2JhbFxuICAgIDogdHlwZW9mIHNlbGYgPT09IFwib2JqZWN0XCIgJiYgc2VsZiAhPT0gbnVsbCA/IHNlbGZcbiAgICA6IHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIgJiYgd2luZG93ICE9PSBudWxsID8gd2luZG93XG4gICAgOiB0aGlzLFxuZnVuY3Rpb24gKGdsb2JhbCwgZXhwb3J0cykge1xuICAgIC8qIGVzbGludC1lbmFibGUgKi9cbiAgICBcInVzZSBzdHJpY3RcIlxuXG4gICAgLyogZ2xvYmFsIFN5bWJvbCwgVWludDhBcnJheSwgRGF0YVZpZXcsIEFycmF5QnVmZmVyLCBBcnJheUJ1ZmZlclZpZXcsIE1hcCxcbiAgICBTZXQgKi9cblxuICAgIC8qKlxuICAgICAqIERlZXAgbWF0Y2hpbmcgYWxnb3JpdGhtLCB3aXRoIHplcm8gZGVwZW5kZW5jaWVzLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIFRoaXMgaXMgcmVsYXRpdmVseSBwZXJmb3JtYW5jZS10dW5lZCwgYWx0aG91Z2ggaXQgcHJlZmVycyBoaWdoXG4gICAgICogICBjb3JyZWN0bmVzcy4gUGF0Y2ggd2l0aCBjYXJlLCBzaW5jZSBwZXJmb3JtYW5jZSBpcyBhIGNvbmNlcm4uXG4gICAgICogLSBUaGlzIGRvZXMgcGFjayBhICpsb3QqIG9mIGZlYXR1cmVzLCB3aGljaCBzaG91bGQgZXhwbGFpbiB0aGUgbGVuZ3RoLlxuICAgICAqIC0gU29tZSBvZiB0aGUgZHVwbGljYXRpb24gaXMgaW50ZW50aW9uYWwuIEl0J3MgZ2VuZXJhbGx5IGNvbW1lbnRlZCwgYnV0XG4gICAgICogICBpdCdzIG1haW5seSBmb3IgcGVyZm9ybWFuY2UsIHNpbmNlIHRoZSBlbmdpbmUgbmVlZHMgaXRzIHR5cGUgaW5mby5cbiAgICAgKiAtIFBvbHlmaWxsZWQgY29yZS1qcyBTeW1ib2xzIGZyb20gY3Jvc3Mtb3JpZ2luIGNvbnRleHRzIHdpbGwgbmV2ZXJcbiAgICAgKiAgIHJlZ2lzdGVyIGFzIGJlaW5nIGFjdHVhbCBTeW1ib2xzLlxuICAgICAqXG4gICAgICogQW5kIGluIGNhc2UgeW91J3JlIHdvbmRlcmluZyBhYm91dCB0aGUgbG9uZ2VyIGZ1bmN0aW9ucyBhbmQgb2NjYXNpb25hbFxuICAgICAqIHJlcGV0aXRpb24sIGl0J3MgYmVjYXVzZSBWOCdzIGlubGluZXIgaXNuJ3QgYWx3YXlzIGludGVsbGlnZW50IGVub3VnaCB0b1xuICAgICAqIGRlYWwgd2l0aCB0aGUgc3VwZXIgaGlnaGx5IHBvbHltb3JwaGljIGRhdGEgdGhpcyBvZnRlbiBkZWFscyB3aXRoLCBhbmQgSlNcbiAgICAgKiBkb2Vzbid0IGhhdmUgY29tcGlsZS10aW1lIG1hY3Jvcy5cbiAgICAgKi9cblxuICAgIHZhciBvYmplY3RUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdcbiAgICB2YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eVxuXG4gICAgdmFyIHN1cHBvcnRzVW5pY29kZSA9IGhhc093bi5jYWxsKFJlZ0V4cC5wcm90b3R5cGUsIFwidW5pY29kZVwiKVxuICAgIHZhciBzdXBwb3J0c1N0aWNreSA9IGhhc093bi5jYWxsKFJlZ0V4cC5wcm90b3R5cGUsIFwic3RpY2t5XCIpXG5cbiAgICAvLyBMZWdhY3kgZW5naW5lcyBoYXZlIHNldmVyYWwgaXNzdWVzIHdoZW4gaXQgY29tZXMgdG8gYHR5cGVvZmAuXG4gICAgdmFyIGlzRnVuY3Rpb24gPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICBmdW5jdGlvbiBTbG93SXNGdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBmYWxzZVxuXG4gICAgICAgICAgICB2YXIgdGFnID0gb2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSlcblxuICAgICAgICAgICAgcmV0dXJuIHRhZyA9PT0gXCJbb2JqZWN0IEZ1bmN0aW9uXVwiIHx8XG4gICAgICAgICAgICAgICAgdGFnID09PSBcIltvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dXCIgfHxcbiAgICAgICAgICAgICAgICB0YWcgPT09IFwiW29iamVjdCBBc3luY0Z1bmN0aW9uXVwiIHx8XG4gICAgICAgICAgICAgICAgdGFnID09PSBcIltvYmplY3QgUHJveHldXCJcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGlzUG9pc29uZWQob2JqZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYgdHlwZW9mIG9iamVjdCAhPT0gXCJmdW5jdGlvblwiXG4gICAgICAgIH1cblxuICAgICAgICAvLyBJbiBTYWZhcmkgMTAsIGB0eXBlb2YgUHJveHkgPT09IFwib2JqZWN0XCJgXG4gICAgICAgIGlmIChpc1BvaXNvbmVkKGdsb2JhbC5Qcm94eSkpIHJldHVybiBTbG93SXNGdW5jdGlvblxuXG4gICAgICAgIC8vIEluIFNhZmFyaSA4LCBzZXZlcmFsIHR5cGVkIGFycmF5IGNvbnN0cnVjdG9ycyBhcmVcbiAgICAgICAgLy8gYHR5cGVvZiBDID09PSBcIm9iamVjdFwiYFxuICAgICAgICBpZiAoaXNQb2lzb25lZChnbG9iYWwuSW50OEFycmF5KSkgcmV0dXJuIFNsb3dJc0Z1bmN0aW9uXG5cbiAgICAgICAgLy8gSW4gb2xkIFY4LCBSZWdFeHBzIGFyZSBjYWxsYWJsZVxuICAgICAgICBpZiAodHlwZW9mIC94LyA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gU2xvd0lzRnVuY3Rpb24gLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG4gICAgICAgIC8vIExlYXZlIHRoaXMgZm9yIG5vcm1hbCB0aGluZ3MuIEl0J3MgZWFzaWx5IGlubGluZWQuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgfVxuICAgIH0pKClcblxuICAgIC8vIFNldCB1cCBvdXIgb3duIGJ1ZmZlciBjaGVjay4gV2Ugc2hvdWxkIGFsd2F5cyBhY2NlcHQgdGhlIHBvbHlmaWxsLCBldmVuXG4gICAgLy8gaW4gTm9kZS4gTm90ZSB0aGF0IGl0IHVzZXMgYGdsb2JhbC5CdWZmZXJgIHRvIGF2b2lkIGluY2x1ZGluZyBgYnVmZmVyYCBpblxuICAgIC8vIHRoZSBidW5kbGUuXG5cbiAgICB2YXIgQnVmZmVyTmF0aXZlID0gMFxuICAgIHZhciBCdWZmZXJQb2x5ZmlsbCA9IDFcbiAgICB2YXIgQnVmZmVyU2FmYXJpID0gMlxuXG4gICAgdmFyIGJ1ZmZlclN1cHBvcnQgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICBmdW5jdGlvbiBGYWtlQnVmZmVyKCkge31cbiAgICAgICAgRmFrZUJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWUgfVxuXG4gICAgICAgIC8vIE9ubHkgU2FmYXJpIDUtNyBoYXMgZXZlciBoYWQgdGhpcyBpc3N1ZS5cbiAgICAgICAgaWYgKG5ldyBGYWtlQnVmZmVyKCkuY29uc3RydWN0b3IgIT09IEZha2VCdWZmZXIpIHJldHVybiBCdWZmZXJTYWZhcmlcbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKGdsb2JhbC5CdWZmZXIpKSByZXR1cm4gQnVmZmVyUG9seWZpbGxcbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIpKSByZXR1cm4gQnVmZmVyUG9seWZpbGxcbiAgICAgICAgLy8gQXZvaWQgZ2xvYmFsIHBvbHlmaWxsc1xuICAgICAgICBpZiAoZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlcihuZXcgRmFrZUJ1ZmZlcigpKSkgcmV0dXJuIEJ1ZmZlclBvbHlmaWxsXG4gICAgICAgIHJldHVybiBCdWZmZXJOYXRpdmVcbiAgICB9KSgpXG5cbiAgICB2YXIgZ2xvYmFsSXNCdWZmZXIgPSBidWZmZXJTdXBwb3J0ID09PSBCdWZmZXJOYXRpdmVcbiAgICAgICAgPyBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyXG4gICAgICAgIDogdW5kZWZpbmVkXG5cbiAgICBmdW5jdGlvbiBpc0J1ZmZlcihvYmplY3QpIHtcbiAgICAgICAgaWYgKGJ1ZmZlclN1cHBvcnQgPT09IEJ1ZmZlck5hdGl2ZSAmJiBnbG9iYWxJc0J1ZmZlcihvYmplY3QpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKGJ1ZmZlclN1cHBvcnQgPT09IEJ1ZmZlclNhZmFyaSAmJiBvYmplY3QuX2lzQnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIEIgPSBvYmplY3QuY29uc3RydWN0b3JcblxuICAgICAgICBpZiAoIWlzRnVuY3Rpb24oQikpIHJldHVybiBmYWxzZVxuICAgICAgICBpZiAoIWlzRnVuY3Rpb24oQi5pc0J1ZmZlcikpIHJldHVybiBmYWxzZVxuICAgICAgICByZXR1cm4gQi5pc0J1ZmZlcihvYmplY3QpXG4gICAgfVxuXG4gICAgLy8gY29yZS1qcycgc3ltYm9scyBhcmUgb2JqZWN0cywgYW5kIHNvbWUgb2xkIHZlcnNpb25zIG9mIFY4IGVycm9uZW91c2x5IGhhZFxuICAgIC8vIGB0eXBlb2YgU3ltYm9sKCkgPT09IFwib2JqZWN0XCJgLlxuICAgIHZhciBzeW1ib2xzQXJlT2JqZWN0cyA9IGlzRnVuY3Rpb24oZ2xvYmFsLlN5bWJvbCkgJiZcbiAgICAgICAgdHlwZW9mIFN5bWJvbCgpID09PSBcIm9iamVjdFwiXG5cbiAgICAvLyBgY29udGV4dGAgaXMgYSBiaXQgZmllbGQsIHdpdGggdGhlIGZvbGxvd2luZyBiaXRzLiBUaGlzIGlzIG5vdCBhcyBtdWNoXG4gICAgLy8gZm9yIHBlcmZvcm1hbmNlIHRoYW4gdG8ganVzdCByZWR1Y2UgdGhlIG51bWJlciBvZiBwYXJhbWV0ZXJzIEkgbmVlZCB0byBiZVxuICAgIC8vIHRocm93aW5nIGFyb3VuZC5cbiAgICB2YXIgU3RyaWN0ID0gMVxuICAgIHZhciBJbml0aWFsID0gMlxuICAgIHZhciBTYW1lUHJvdG8gPSA0XG5cbiAgICBleHBvcnRzLmxvb3NlID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIG1hdGNoKGEsIGIsIEluaXRpYWwsIHVuZGVmaW5lZCwgdW5kZWZpbmVkKVxuICAgIH1cblxuICAgIGV4cG9ydHMuc3RyaWN0ID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIG1hdGNoKGEsIGIsIFN0cmljdCB8IEluaXRpYWwsIHVuZGVmaW5lZCwgdW5kZWZpbmVkKVxuICAgIH1cblxuICAgIC8vIEZlYXR1cmUtdGVzdCBkZWxheWVkIHN0YWNrIGFkZGl0aW9ucyBhbmQgZXh0cmEga2V5cy4gUGhhbnRvbUpTIGFuZCBJRVxuICAgIC8vIGJvdGggd2FpdCB1bnRpbCB0aGUgZXJyb3Igd2FzIGFjdHVhbGx5IHRocm93biBmaXJzdCwgYW5kIGFzc2lnbiB0aGVtIGFzXG4gICAgLy8gb3duIHByb3BlcnRpZXMsIHdoaWNoIGlzIHVuaGVscGZ1bCBmb3IgYXNzZXJ0aW9ucy4gVGhpcyByZXR1cm5zIGFcbiAgICAvLyBmdW5jdGlvbiB0byBzcGVlZCB1cCBjYXNlcyB3aGVyZSBgT2JqZWN0LmtleXNgIGlzIHN1ZmZpY2llbnQgKGUuZy4gaW5cbiAgICAvLyBDaHJvbWUvRkYvTm9kZSkuXG4gICAgLy9cbiAgICAvLyBUaGlzIHdvdWxkbid0IGJlIG5lY2Vzc2FyeSBpZiB0aG9zZSBlbmdpbmVzIHdvdWxkIG1ha2UgdGhlIHN0YWNrIGFcbiAgICAvLyBnZXR0ZXIsIGFuZCByZWNvcmQgaXQgd2hlbiB0aGUgZXJyb3Igd2FzIGNyZWF0ZWQsIG5vdCB3aGVuIGl0IHdhcyB0aHJvd24uXG4gICAgLy8gSXQgc3BlY2lmaWNhbGx5IGZpbHRlcnMgb3V0IGVycm9ycyBhbmQgb25seSBjaGVja3MgZXhpc3RpbmcgZGVzY3JpcHRvcnMsXG4gICAgLy8ganVzdCB0byBrZWVwIHRoZSBtZXNzIGZyb20gYWZmZWN0aW5nIGV2ZXJ5dGhpbmcgKGl0J3Mgbm90IGZ1bGx5IGNvcnJlY3QsXG4gICAgLy8gYnV0IGl0J3MgbmVjZXNzYXJ5KS5cbiAgICB2YXIgcmVxdWlyZXNQcm94eSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0ZXN0ID0gbmV3IEVycm9yKClcbiAgICAgICAgdmFyIG9sZCA9IE9iamVjdC5jcmVhdGUobnVsbClcblxuICAgICAgICBPYmplY3Qua2V5cyh0ZXN0KS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsgb2xkW2tleV0gPSB0cnVlIH0pXG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRocm93IHRlc3RcbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgICAgLy8gaWdub3JlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGVzdCkuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiAhb2xkW2tleV0gfSlcbiAgICB9KSgpXG5cbiAgICBmdW5jdGlvbiBpc0lnbm9yZWQob2JqZWN0LCBrZXkpIHtcbiAgICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgY2FzZSBcImxpbmVcIjogaWYgKHR5cGVvZiBvYmplY3QubGluZSAhPT0gXCJudW1iZXJcIikgcmV0dXJuIGZhbHNlOyBicmVha1xuICAgICAgICBjYXNlIFwic291cmNlVVJMXCI6XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zb3VyY2VVUkwgIT09IFwic3RyaW5nXCIpIHJldHVybiBmYWxzZTsgYnJlYWtcbiAgICAgICAgY2FzZSBcInN0YWNrXCI6IGlmICh0eXBlb2Ygb2JqZWN0LnN0YWNrICE9PSBcInN0cmluZ1wiKSByZXR1cm4gZmFsc2U7IGJyZWFrXG4gICAgICAgIGRlZmF1bHQ6IHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwga2V5KVxuXG4gICAgICAgIHJldHVybiAhZGVzYy5jb25maWd1cmFibGUgJiYgZGVzYy5lbnVtZXJhYmxlICYmICFkZXNjLndyaXRhYmxlXG4gICAgfVxuXG4gICAgLy8gVGhpcyBpcyBvbmx5IGludm9rZWQgd2l0aCBlcnJvcnMsIHNvIGl0J3Mgbm90IGdvaW5nIHRvIHByZXNlbnQgYVxuICAgIC8vIHNpZ25pZmljYW50IHNsb3cgZG93bi5cbiAgICBmdW5jdGlvbiBnZXRLZXlzU3RyaXBwZWQob2JqZWN0KSB7XG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqZWN0KVxuICAgICAgICB2YXIgY291bnQgPSAwXG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIWlzSWdub3JlZChvYmplY3QsIGtleXNbaV0pKSBrZXlzW2NvdW50KytdID0ga2V5c1tpXVxuICAgICAgICB9XG5cbiAgICAgICAga2V5cy5sZW5ndGggPSBjb3VudFxuICAgICAgICByZXR1cm4ga2V5c1xuICAgIH1cblxuICAgIC8vIFdheSBmYXN0ZXIsIHNpbmNlIHR5cGVkIGFycmF5IGluZGljZXMgYXJlIGFsd2F5cyBkZW5zZSBhbmQgY29udGFpblxuICAgIC8vIG51bWJlcnMuXG5cbiAgICAvLyBTZXR1cCBmb3IgYGlzQnVmZmVyT3JWaWV3YCBhbmQgYGlzVmlld2BcbiAgICB2YXIgQXJyYXlCdWZmZXJOb25lID0gMFxuICAgIHZhciBBcnJheUJ1ZmZlckxlZ2FjeSA9IDFcbiAgICB2YXIgQXJyYXlCdWZmZXJDdXJyZW50ID0gMlxuXG4gICAgdmFyIGFycmF5QnVmZmVyU3VwcG9ydCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghaXNGdW5jdGlvbihnbG9iYWwuVWludDhBcnJheSkpIHJldHVybiBBcnJheUJ1ZmZlck5vbmVcbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKGdsb2JhbC5EYXRhVmlldykpIHJldHVybiBBcnJheUJ1ZmZlck5vbmVcbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKGdsb2JhbC5BcnJheUJ1ZmZlcikpIHJldHVybiBBcnJheUJ1ZmZlck5vbmVcbiAgICAgICAgaWYgKGlzRnVuY3Rpb24oZ2xvYmFsLkFycmF5QnVmZmVyLmlzVmlldykpIHJldHVybiBBcnJheUJ1ZmZlckN1cnJlbnRcbiAgICAgICAgaWYgKGlzRnVuY3Rpb24oZ2xvYmFsLkFycmF5QnVmZmVyVmlldykpIHJldHVybiBBcnJheUJ1ZmZlckxlZ2FjeVxuICAgICAgICByZXR1cm4gQXJyYXlCdWZmZXJOb25lXG4gICAgfSkoKVxuXG4gICAgLy8gSWYgdHlwZWQgYXJyYXlzIGFyZW4ndCBzdXBwb3J0ZWQgKHRoZXkgd2VyZW4ndCB0ZWNobmljYWxseSBwYXJ0IG9mXG4gICAgLy8gRVM1LCBidXQgbWFueSBlbmdpbmVzIGltcGxlbWVudGVkIEtocm9ub3MnIHNwZWMgYmVmb3JlIEVTNiksIHRoZW5cbiAgICAvLyBqdXN0IGZhbGwgYmFjayB0byBnZW5lcmljIGJ1ZmZlciBkZXRlY3Rpb24uXG5cbiAgICBmdW5jdGlvbiBmbG9hdElzKGEsIGIpIHtcbiAgICAgICAgLy8gU28gTmFOcyBhcmUgY29uc2lkZXJlZCBlcXVhbC5cbiAgICAgICAgcmV0dXJuIGEgPT09IGIgfHwgYSAhPT0gYSAmJiBiICE9PSBiIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlLCBtYXgtbGVuXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF0Y2hWaWV3KGEsIGIpIHtcbiAgICAgICAgdmFyIGNvdW50ID0gYS5sZW5ndGhcblxuICAgICAgICBpZiAoY291bnQgIT09IGIubGVuZ3RoKSByZXR1cm4gZmFsc2VcblxuICAgICAgICB3aGlsZSAoY291bnQpIHtcbiAgICAgICAgICAgIGNvdW50LS1cbiAgICAgICAgICAgIGlmICghZmxvYXRJcyhhW2NvdW50XSwgYltjb3VudF0pKSByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgdmFyIGlzVmlldyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChhcnJheUJ1ZmZlclN1cHBvcnQgPT09IEFycmF5QnVmZmVyTm9uZSkgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICAvLyBFUzYgdHlwZWQgYXJyYXlzXG4gICAgICAgIGlmIChhcnJheUJ1ZmZlclN1cHBvcnQgPT09IEFycmF5QnVmZmVyQ3VycmVudCkgcmV0dXJuIEFycmF5QnVmZmVyLmlzVmlld1xuICAgICAgICAvLyBsZWdhY3kgdHlwZWQgYXJyYXlzXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBpc1ZpZXcob2JqZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgQXJyYXlCdWZmZXJWaWV3XG4gICAgICAgIH1cbiAgICB9KSgpXG5cbiAgICAvLyBTdXBwb3J0IGNoZWNraW5nIG1hcHMgYW5kIHNldHMgZGVlcGx5LiBUaGV5IGFyZSBvYmplY3QtbGlrZSBlbm91Z2ggdG9cbiAgICAvLyBjb3VudCwgYW5kIGFyZSB1c2VmdWwgaW4gdGhlaXIgb3duIHJpZ2h0LiBUaGUgY29kZSBpcyByYXRoZXIgbWVzc3ksIGJ1dFxuICAgIC8vIG1haW5seSB0byBrZWVwIHRoZSBvcmRlci1pbmRlcGVuZGVudCBjaGVja2luZyBmcm9tIGJlY29taW5nIGluc2FuZWx5XG4gICAgLy8gc2xvdy5cbiAgICB2YXIgc3VwcG9ydHNNYXAgPSBpc0Z1bmN0aW9uKGdsb2JhbC5NYXApXG4gICAgdmFyIHN1cHBvcnRzU2V0ID0gaXNGdW5jdGlvbihnbG9iYWwuU2V0KVxuXG4gICAgLy8gT25lIG9mIHRoZSBzZXRzIGFuZCBib3RoIG1hcHMnIGtleXMgYXJlIGNvbnZlcnRlZCB0byBhcnJheXMgZm9yIGZhc3RlclxuICAgIC8vIGhhbmRsaW5nLlxuICAgIGZ1bmN0aW9uIGtleUxpc3QobWFwKSB7XG4gICAgICAgIHZhciBsaXN0ID0gbmV3IEFycmF5KG1hcC5zaXplKVxuICAgICAgICB2YXIgaSA9IDBcbiAgICAgICAgdmFyIGl0ZXIgPSBtYXAua2V5cygpXG5cbiAgICAgICAgZm9yICh2YXIgbmV4dCA9IGl0ZXIubmV4dCgpOyAhbmV4dC5kb25lOyBuZXh0ID0gaXRlci5uZXh0KCkpIHtcbiAgICAgICAgICAgIGxpc3RbaSsrXSA9IG5leHQudmFsdWVcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBsaXN0XG4gICAgfVxuXG4gICAgLy8gVGhlIHBhaXIgb2YgYXJyYXlzIGFyZSBhbGlnbmVkIGluIGEgc2luZ2xlIE8obl4yKSBvcGVyYXRpb24gKG1vZCBkZWVwXG4gICAgLy8gbWF0Y2hpbmcgYW5kIHJvdGF0aW9uKSwgYWRhcHRpbmcgdG8gTyhuKSB3aGVuIHRoZXkncmUgYWxyZWFkeSBhbGlnbmVkLlxuICAgIGZ1bmN0aW9uIG1hdGNoS2V5KGN1cnJlbnQsIGFrZXlzLCBzdGFydCwgZW5kLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0ICsgMTsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0gYWtleXNbaV1cblxuICAgICAgICAgICAgaWYgKG1hdGNoKGN1cnJlbnQsIGtleSwgY29udGV4dCwgbGVmdCwgcmlnaHQpKSB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogb25jZSBlbmdpbmVzIGFjdHVhbGx5IG9wdGltaXplIGBjb3B5V2l0aGluYCwgdXNlIHRoYXRcbiAgICAgICAgICAgICAgICAvLyBpbnN0ZWFkLiBJdCdsbCBiZSBtdWNoIGZhc3RlciB0aGFuIHRoaXMgbG9vcC5cbiAgICAgICAgICAgICAgICB3aGlsZSAoaSA+IHN0YXJ0KSBha2V5c1tpXSA9IGFrZXlzWy0taV1cbiAgICAgICAgICAgICAgICBha2V5c1tpXSA9IGtleVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXRjaFZhbHVlcyhhLCBiLCBha2V5cywgYmtleXMsIGVuZCwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW5kOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghbWF0Y2goYS5nZXQoYWtleXNbaV0pLCBiLmdldChia2V5c1tpXSksXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICAvLyBQb3NzaWJseSBleHBlbnNpdmUgb3JkZXItaW5kZXBlbmRlbnQga2V5LXZhbHVlIG1hdGNoLiBGaXJzdCwgdHJ5IHRvIGF2b2lkXG4gICAgLy8gaXQgYnkgY29uc2VydmF0aXZlbHkgYXNzdW1pbmcgZXZlcnl0aGluZyBpcyBpbiBvcmRlciAtIGEgY2hlYXAgTyhuKSBpc1xuICAgIC8vIGFsd2F5cyBuaWNlciB0aGFuIGFuIGV4cGVuc2l2ZSBPKG5eMikuXG4gICAgZnVuY3Rpb24gbWF0Y2hNYXAoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIHZhciBlbmQgPSBhLnNpemVcbiAgICAgICAgdmFyIGFrZXlzID0ga2V5TGlzdChhKVxuICAgICAgICB2YXIgYmtleXMgPSBrZXlMaXN0KGIpXG4gICAgICAgIHZhciBpID0gMFxuXG4gICAgICAgIHdoaWxlIChpICE9PSBlbmQgJiYgbWF0Y2goYWtleXNbaV0sIGJrZXlzW2ldLCBjb250ZXh0LCBsZWZ0LCByaWdodCkpIHtcbiAgICAgICAgICAgIGkrK1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGkgPT09IGVuZCkge1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoVmFsdWVzKGEsIGIsIGFrZXlzLCBia2V5cywgZW5kLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERvbid0IGNvbXBhcmUgdGhlIHNhbWUga2V5IHR3aWNlXG4gICAgICAgIGlmICghbWF0Y2hLZXkoYmtleXNbaV0sIGFrZXlzLCBpLCBlbmQsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGUgYWJvdmUgZmFpbHMsIHdoaWxlIHdlJ3JlIGF0IGl0LCBsZXQncyBzb3J0IHRoZW0gYXMgd2UgZ28sIHNvXG4gICAgICAgIC8vIHRoZSBrZXkgb3JkZXIgbWF0Y2hlcy5cbiAgICAgICAgd2hpbGUgKCsraSA8IGVuZCkge1xuICAgICAgICAgICAgdmFyIGtleSA9IGJrZXlzW2ldXG5cbiAgICAgICAgICAgIC8vIEFkYXB0IGlmIHRoZSBrZXlzIGFyZSBhbHJlYWR5IGluIG9yZGVyLCB3aGljaCBpcyBmcmVxdWVudGx5IHRoZVxuICAgICAgICAgICAgLy8gY2FzZS5cbiAgICAgICAgICAgIGlmICghbWF0Y2goa2V5LCBha2V5c1tpXSwgY29udGV4dCwgbGVmdCwgcmlnaHQpICYmXG4gICAgICAgICAgICAgICAgICAgICFtYXRjaEtleShrZXksIGFrZXlzLCBpLCBlbmQsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1hdGNoVmFsdWVzKGEsIGIsIGFrZXlzLCBia2V5cywgZW5kLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoYXNBbGxJZGVudGljYWwoYWxpc3QsIGIpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKCFiLmhhcyhhbGlzdFtpXSkpIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICAvLyBDb21wYXJlIHRoZSB2YWx1ZXMgc3RydWN0dXJhbGx5LCBhbmQgaW5kZXBlbmRlbnQgb2Ygb3JkZXIuXG4gICAgZnVuY3Rpb24gc2VhcmNoRm9yKGF2YWx1ZSwgb2JqZWN0cywgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIGZvciAodmFyIGogaW4gb2JqZWN0cykge1xuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKG9iamVjdHMsIGopKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKGF2YWx1ZSwgb2JqZWN0c1tqXSwgY29udGV4dCwgbGVmdCwgcmlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBvYmplY3RzW2pdXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzU3RydWN0dXJlKHZhbHVlLCBjb250ZXh0KSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwgfHxcbiAgICAgICAgICAgICAgICAhKGNvbnRleHQgJiBTdHJpY3QpICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJzeW1ib2xcIlxuICAgIH1cblxuICAgIC8vIFRoZSBzZXQgYWxnb3JpdGhtIGlzIHN0cnVjdHVyZWQgYSBsaXR0bGUgZGlmZmVyZW50bHkuIEl0IHRha2VzIG9uZSBvZiB0aGVcbiAgICAvLyBzZXRzIGludG8gYW4gYXJyYXksIGRvZXMgYSBjaGVhcCBpZGVudGl0eSBjaGVjaywgdGhlbiBkb2VzIHRoZSBkZWVwXG4gICAgLy8gY2hlY2suXG4gICAgZnVuY3Rpb24gbWF0Y2hTZXQoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIC8vIFRoaXMgaXMgdG8gdHJ5IHRvIGF2b2lkIGFuIGV4cGVuc2l2ZSBzdHJ1Y3R1cmFsIG1hdGNoIG9uIHRoZSBrZXlzLlxuICAgICAgICAvLyBUZXN0IGZvciBpZGVudGl0eSBmaXJzdC5cbiAgICAgICAgdmFyIGFsaXN0ID0ga2V5TGlzdChhKVxuXG4gICAgICAgIGlmIChoYXNBbGxJZGVudGljYWwoYWxpc3QsIGIpKSByZXR1cm4gdHJ1ZVxuXG4gICAgICAgIHZhciBpdGVyID0gYi52YWx1ZXMoKVxuICAgICAgICB2YXIgY291bnQgPSAwXG4gICAgICAgIHZhciBvYmplY3RzXG5cbiAgICAgICAgLy8gR2F0aGVyIGFsbCB0aGUgb2JqZWN0c1xuICAgICAgICBmb3IgKHZhciBuZXh0ID0gaXRlci5uZXh0KCk7ICFuZXh0LmRvbmU7IG5leHQgPSBpdGVyLm5leHQoKSkge1xuICAgICAgICAgICAgdmFyIGJ2YWx1ZSA9IG5leHQudmFsdWVcblxuICAgICAgICAgICAgaWYgKGhhc1N0cnVjdHVyZShidmFsdWUsIGNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIHRoZSBvYmplY3RzIG1hcCBsYXppbHkuIE5vdGUgdGhhdCB0aGlzIGFsc28gZ3JhYnNcbiAgICAgICAgICAgICAgICAvLyBTeW1ib2xzIHdoZW4gbm90IHN0cmljdGx5IG1hdGNoaW5nLCBzaW5jZSB0aGVpciBkZXNjcmlwdGlvblxuICAgICAgICAgICAgICAgIC8vIGlzIGNvbXBhcmVkLlxuICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PT0gMCkgb2JqZWN0cyA9IE9iamVjdC5jcmVhdGUobnVsbClcbiAgICAgICAgICAgICAgICBvYmplY3RzW2NvdW50KytdID0gYnZhbHVlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBldmVyeXRoaW5nIGlzIGEgcHJpbWl0aXZlLCB0aGVuIGFib3J0LlxuICAgICAgICBpZiAoY291bnQgPT09IDApIHJldHVybiBmYWxzZVxuXG4gICAgICAgIC8vIEl0ZXJhdGUgdGhlIG9iamVjdCwgcmVtb3ZpbmcgZWFjaCBvbmUgcmVtYWluaW5nIHdoZW4gbWF0Y2hlZCAoYW5kXG4gICAgICAgIC8vIGFib3J0aW5nIGlmIG5vbmUgY2FuIGJlKS5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgYXZhbHVlID0gYWxpc3RbaV1cblxuICAgICAgICAgICAgaWYgKGhhc1N0cnVjdHVyZShhdmFsdWUsIGNvbnRleHQpICYmXG4gICAgICAgICAgICAgICAgICAgICFzZWFyY2hGb3IoYXZhbHVlLCBvYmplY3RzLCBjb250ZXh0LCBsZWZ0LCByaWdodCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF0Y2hSZWdFeHAoYSwgYikge1xuICAgICAgICByZXR1cm4gYS5zb3VyY2UgPT09IGIuc291cmNlICYmXG4gICAgICAgICAgICBhLmdsb2JhbCA9PT0gYi5nbG9iYWwgJiZcbiAgICAgICAgICAgIGEuaWdub3JlQ2FzZSA9PT0gYi5pZ25vcmVDYXNlICYmXG4gICAgICAgICAgICBhLm11bHRpbGluZSA9PT0gYi5tdWx0aWxpbmUgJiZcbiAgICAgICAgICAgICghc3VwcG9ydHNVbmljb2RlIHx8IGEudW5pY29kZSA9PT0gYi51bmljb2RlKSAmJlxuICAgICAgICAgICAgKCFzdXBwb3J0c1N0aWNreSB8fCBhLnN0aWNreSA9PT0gYi5zdGlja3kpXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF0Y2hQcmVwYXJlRGVzY2VuZChhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgYWZ0ZXIgdGhlIGZpcnN0IGxldmVsLCB3aGVyZSBpdCdzXG4gICAgICAgIC8vIHJlZHVuZGFudC4gTm90ZSB0aGF0IHRoZXkgaGF2ZSB0byBwb2ludCB0byB0aGUgc2FtZSBsZXZlbCB0byBhY3R1YWxseVxuICAgICAgICAvLyBiZSBjb25zaWRlcmVkIGRlZXBseSBlcXVhbC5cbiAgICAgICAgaWYgKCEoY29udGV4dCAmIEluaXRpYWwpKSB7XG4gICAgICAgICAgICB2YXIgbGVmdEluZGV4ID0gbGVmdC5pbmRleE9mKGEpXG4gICAgICAgICAgICB2YXIgcmlnaHRJbmRleCA9IHJpZ2h0LmluZGV4T2YoYilcblxuICAgICAgICAgICAgaWYgKGxlZnRJbmRleCAhPT0gcmlnaHRJbmRleCkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICBpZiAobGVmdEluZGV4ID49IDApIHJldHVybiB0cnVlXG5cbiAgICAgICAgICAgIGxlZnQucHVzaChhKVxuICAgICAgICAgICAgcmlnaHQucHVzaChiKVxuXG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gbWF0Y2hJbm5lcihhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcblxuICAgICAgICAgICAgbGVmdC5wb3AoKVxuICAgICAgICAgICAgcmlnaHQucG9wKClcblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoSW5uZXIoYSwgYiwgY29udGV4dCAmIH5Jbml0aWFsLCBbYV0sIFtiXSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoU2FtZVByb3RvKGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICBpZiAoc3ltYm9sc0FyZU9iamVjdHMgJiYgYSBpbnN0YW5jZW9mIFN5bWJvbCkge1xuICAgICAgICAgICAgcmV0dXJuICEoY29udGV4dCAmIFN0cmljdCkgJiYgYS50b1N0cmluZygpID09PSBiLnRvU3RyaW5nKClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhIGluc3RhbmNlb2YgUmVnRXhwKSByZXR1cm4gbWF0Y2hSZWdFeHAoYSwgYilcbiAgICAgICAgaWYgKGEgaW5zdGFuY2VvZiBEYXRlKSByZXR1cm4gYS52YWx1ZU9mKCkgPT09IGIudmFsdWVPZigpXG4gICAgICAgIGlmIChhcnJheUJ1ZmZlclN1cHBvcnQgIT09IEFycmF5QnVmZmVyTm9uZSkge1xuICAgICAgICAgICAgaWYgKGEgaW5zdGFuY2VvZiBEYXRhVmlldykge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaFZpZXcoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVaW50OEFycmF5KGEuYnVmZmVyLCBhLmJ5dGVPZmZzZXQsIGEuYnl0ZUxlbmd0aCksXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVaW50OEFycmF5KGIuYnVmZmVyLCBiLmJ5dGVPZmZzZXQsIGIuYnl0ZUxlbmd0aCkpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoVmlldyhuZXcgVWludDhBcnJheShhKSwgbmV3IFVpbnQ4QXJyYXkoYikpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNWaWV3KGEpKSByZXR1cm4gbWF0Y2hWaWV3KGEsIGIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNCdWZmZXIoYSkpIHJldHVybiBtYXRjaFZpZXcoYSwgYilcblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgICAgICAgICAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICBpZiAoYS5sZW5ndGggPT09IDApIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydHNNYXAgJiYgYSBpbnN0YW5jZW9mIE1hcCkge1xuICAgICAgICAgICAgaWYgKGEuc2l6ZSAhPT0gYi5zaXplKSByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIGlmIChhLnNpemUgPT09IDApIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydHNTZXQgJiYgYSBpbnN0YW5jZW9mIFNldCkge1xuICAgICAgICAgICAgaWYgKGEuc2l6ZSAhPT0gYi5zaXplKSByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIGlmIChhLnNpemUgPT09IDApIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAob2JqZWN0VG9TdHJpbmcuY2FsbChhKSA9PT0gXCJbb2JqZWN0IEFyZ3VtZW50c11cIikge1xuICAgICAgICAgICAgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYikgIT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICBpZiAoYS5sZW5ndGggPT09IDApIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAob2JqZWN0VG9TdHJpbmcuY2FsbChiKSA9PT0gXCJbb2JqZWN0IEFyZ3VtZW50c11cIikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWF0Y2hQcmVwYXJlRGVzY2VuZChhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICB9XG5cbiAgICAvLyBNb3N0IHNwZWNpYWwgY2FzZXMgcmVxdWlyZSBib3RoIHR5cGVzIHRvIG1hdGNoLCBhbmQgaWYgb25seSBvbmUgb2YgdGhlbVxuICAgIC8vIGFyZSwgdGhlIG9iamVjdHMgdGhlbXNlbHZlcyBkb24ndCBtYXRjaC5cbiAgICBmdW5jdGlvbiBtYXRjaERpZmZlcmVudFByb3RvKGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICBpZiAoc3ltYm9sc0FyZU9iamVjdHMpIHtcbiAgICAgICAgICAgIGlmIChhIGluc3RhbmNlb2YgU3ltYm9sIHx8IGIgaW5zdGFuY2VvZiBTeW1ib2wpIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb250ZXh0ICYgU3RyaWN0KSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKGFycmF5QnVmZmVyU3VwcG9ydCAhPT0gQXJyYXlCdWZmZXJOb25lKSB7XG4gICAgICAgICAgICBpZiAoYSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IGIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzVmlldyhhKSB8fCBpc1ZpZXcoYikpIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGEpIHx8IEFycmF5LmlzQXJyYXkoYikpIHJldHVybiBmYWxzZVxuICAgICAgICBpZiAoc3VwcG9ydHNNYXAgJiYgKGEgaW5zdGFuY2VvZiBNYXAgfHwgYiBpbnN0YW5jZW9mIE1hcCkpIHJldHVybiBmYWxzZVxuICAgICAgICBpZiAoc3VwcG9ydHNTZXQgJiYgKGEgaW5zdGFuY2VvZiBTZXQgfHwgYiBpbnN0YW5jZW9mIFNldCkpIHJldHVybiBmYWxzZVxuICAgICAgICBpZiAob2JqZWN0VG9TdHJpbmcuY2FsbChhKSA9PT0gXCJbb2JqZWN0IEFyZ3VtZW50c11cIikge1xuICAgICAgICAgICAgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYikgIT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICBpZiAoYS5sZW5ndGggPT09IDApIHJldHVybiB0cnVlXG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYikgPT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHJldHVybiBmYWxzZVxuICAgICAgICByZXR1cm4gbWF0Y2hQcmVwYXJlRGVzY2VuZChhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXRjaChhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgaWYgKGEgPT09IGIpIHJldHVybiB0cnVlXG4gICAgICAgIC8vIE5hTnMgYXJlIGVxdWFsXG4gICAgICAgIGlmIChhICE9PSBhKSByZXR1cm4gYiAhPT0gYiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgICAgICBpZiAoYSA9PT0gbnVsbCB8fCBiID09PSBudWxsKSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKHR5cGVvZiBhID09PSBcInN5bWJvbFwiICYmIHR5cGVvZiBiID09PSBcInN5bWJvbFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gIShjb250ZXh0ICYgU3RyaWN0KSAmJiBhLnRvU3RyaW5nKCkgPT09IGIudG9TdHJpbmcoKVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgYSAhPT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgYiAhPT0gXCJvYmplY3RcIikgcmV0dXJuIGZhbHNlXG5cbiAgICAgICAgLy8gVXN1YWxseSwgYm90aCBvYmplY3RzIGhhdmUgaWRlbnRpY2FsIHByb3RvdHlwZXMsIGFuZCB0aGF0IGFsbG93cyBmb3JcbiAgICAgICAgLy8gaGFsZiB0aGUgdHlwZSBjaGVja2luZy5cbiAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihhKSA9PT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGIpKSB7XG4gICAgICAgICAgICByZXR1cm4gbWF0Y2hTYW1lUHJvdG8oYSwgYiwgY29udGV4dCB8IFNhbWVQcm90bywgbGVmdCwgcmlnaHQpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWF0Y2hEaWZmZXJlbnRQcm90byhhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoQXJyYXlMaWtlKGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghbWF0Y2goYVtpXSwgYltpXSwgY29udGV4dCwgbGVmdCwgcmlnaHQpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgLy8gUGhhbnRvbUpTIGFuZCBTbGltZXJKUyBib3RoIGhhdmUgbXlzdGVyaW91cyBpc3N1ZXMgd2hlcmUgYEVycm9yYCBpc1xuICAgIC8vIHNvbWV0aW1lcyBlcnJvbmVvdXNseSBvZiBhIGRpZmZlcmVudCBgd2luZG93YCwgYW5kIGl0IHNob3dzIHVwIGluIHRoZVxuICAgIC8vIHRlc3RzLiBUaGlzIG1lYW5zIEkgaGF2ZSB0byB1c2UgYSBtdWNoIHNsb3dlciBhbGdvcml0aG0gdG8gZGV0ZWN0IEVycm9ycy5cbiAgICAvL1xuICAgIC8vIFBoYW50b21KUzogaHR0cHM6Ly9naXRodWIuY29tL3BldGthYW50b25vdi9ibHVlYmlyZC9pc3N1ZXMvMTE0NlxuICAgIC8vIFNsaW1lckpTOiBodHRwczovL2dpdGh1Yi5jb20vbGF1cmVudGovc2xpbWVyanMvaXNzdWVzLzQwMFxuICAgIC8vXG4gICAgLy8gKFllcywgdGhlIFBoYW50b21KUyBidWcgaXMgZGV0YWlsZWQgaW4gdGhlIEJsdWViaXJkIGlzc3VlIHRyYWNrZXIuKVxuICAgIHZhciBjaGVja0Nyb3NzT3JpZ2luID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKGdsb2JhbC53aW5kb3cgPT0gbnVsbCB8fCBnbG9iYWwud2luZG93Lm5hdmlnYXRvciA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gL3NsaW1lcmpzfHBoYW50b21qcy9pLnRlc3QoZ2xvYmFsLndpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50KVxuICAgIH0pKClcblxuICAgIHZhciBlcnJvclN0cmluZ1R5cGVzID0ge1xuICAgICAgICBcIltvYmplY3QgRXJyb3JdXCI6IHRydWUsXG4gICAgICAgIFwiW29iamVjdCBFdmFsRXJyb3JdXCI6IHRydWUsXG4gICAgICAgIFwiW29iamVjdCBSYW5nZUVycm9yXVwiOiB0cnVlLFxuICAgICAgICBcIltvYmplY3QgUmVmZXJlbmNlRXJyb3JdXCI6IHRydWUsXG4gICAgICAgIFwiW29iamVjdCBTeW50YXhFcnJvcl1cIjogdHJ1ZSxcbiAgICAgICAgXCJbb2JqZWN0IFR5cGVFcnJvcl1cIjogdHJ1ZSxcbiAgICAgICAgXCJbb2JqZWN0IFVSSUVycm9yXVwiOiB0cnVlLFxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzUHJveGllZEVycm9yKG9iamVjdCkge1xuICAgICAgICB3aGlsZSAob2JqZWN0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChlcnJvclN0cmluZ1R5cGVzW29iamVjdFRvU3RyaW5nLmNhbGwob2JqZWN0KV0pIHJldHVybiB0cnVlXG4gICAgICAgICAgICBvYmplY3QgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF0Y2hJbm5lcihhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1zdGF0ZW1lbnRzLCBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIHZhciBha2V5cywgYmtleXNcbiAgICAgICAgdmFyIGlzVW5wcm94aWVkRXJyb3IgPSBmYWxzZVxuXG4gICAgICAgIGlmIChjb250ZXh0ICYgU2FtZVByb3RvKSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaEFycmF5TGlrZShhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN1cHBvcnRzTWFwICYmIGEgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hNYXAoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdXBwb3J0c1NldCAmJiBhIGluc3RhbmNlb2YgU2V0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoU2V0KGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAob2JqZWN0VG9TdHJpbmcuY2FsbChhKSA9PT0gXCJbb2JqZWN0IEFyZ3VtZW50c11cIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaEFycmF5TGlrZShhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlcXVpcmVzUHJveHkgJiZcbiAgICAgICAgICAgICAgICAgICAgKGNoZWNrQ3Jvc3NPcmlnaW4gPyBpc1Byb3hpZWRFcnJvcihhKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBhIGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgICAgICAgICAgICAgYWtleXMgPSBnZXRLZXlzU3RyaXBwZWQoYSlcbiAgICAgICAgICAgICAgICBia2V5cyA9IGdldEtleXNTdHJpcHBlZChiKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBha2V5cyA9IE9iamVjdC5rZXlzKGEpXG4gICAgICAgICAgICAgICAgYmtleXMgPSBPYmplY3Qua2V5cyhiKVxuICAgICAgICAgICAgICAgIGlzVW5wcm94aWVkRXJyb3IgPSBhIGluc3RhbmNlb2YgRXJyb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChvYmplY3RUb1N0cmluZy5jYWxsKGEpID09PSBcIltvYmplY3QgQXJndW1lbnRzXVwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoQXJyYXlMaWtlKGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiB3ZSByZXF1aXJlIGEgcHJveHksIGJlIHBlcm1pc3NpdmUgYW5kIGNoZWNrIHRoZSBgdG9TdHJpbmdgXG4gICAgICAgICAgICAvLyB0eXBlLiBUaGlzIGlzIHNvIGl0IHdvcmtzIGNyb3NzLW9yaWdpbiBpbiBQaGFudG9tSlMgaW5cbiAgICAgICAgICAgIC8vIHBhcnRpY3VsYXIuXG4gICAgICAgICAgICBpZiAoY2hlY2tDcm9zc09yaWdpbiA/IGlzUHJveGllZEVycm9yKGEpIDogYSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBha2V5cyA9IE9iamVjdC5rZXlzKGEpXG4gICAgICAgICAgICBia2V5cyA9IE9iamVjdC5rZXlzKGIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY291bnQgPSBha2V5cy5sZW5ndGhcblxuICAgICAgICBpZiAoY291bnQgIT09IGJrZXlzLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG5cbiAgICAgICAgLy8gU2hvcnRjdXQgaWYgdGhlcmUncyBub3RoaW5nIHRvIG1hdGNoXG4gICAgICAgIGlmIChjb3VudCA9PT0gMCkgcmV0dXJuIHRydWVcblxuICAgICAgICB2YXIgaVxuXG4gICAgICAgIGlmIChpc1VucHJveGllZEVycm9yKSB7XG4gICAgICAgICAgICAvLyBTaG9ydGN1dCBpZiB0aGUgcHJvcGVydGllcyBhcmUgZGlmZmVyZW50LlxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoYWtleXNbaV0gIT09IFwic3RhY2tcIikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWhhc093bi5jYWxsKGIsIGFrZXlzW2ldKSkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBWZXJpZnkgdGhhdCBhbGwgdGhlIGFrZXlzJyB2YWx1ZXMgbWF0Y2hlZC5cbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFrZXlzW2ldICE9PSBcInN0YWNrXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICFtYXRjaChhW2FrZXlzW2ldXSwgYltha2V5c1tpXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCwgbGVmdCwgcmlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNob3J0Y3V0IGlmIHRoZSBwcm9wZXJ0aWVzIGFyZSBkaWZmZXJlbnQuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghaGFzT3duLmNhbGwoYiwgYWtleXNbaV0pKSByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVmVyaWZ5IHRoYXQgYWxsIHRoZSBha2V5cycgdmFsdWVzIG1hdGNoZWQuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghbWF0Y2goYVtha2V5c1tpXV0sIGJbYWtleXNbaV1dLCBjb250ZXh0LCBsZWZ0LCByaWdodCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG59KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBzZW1pXG4iLCIvLyBTZWU6IGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9nb29nbGUtZGlmZi1tYXRjaC1wYXRjaC93aWtpL0FQSVxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRDaGFuZ2VzVG9ETVAoY2hhbmdlcykge1xuICBsZXQgcmV0ID0gW10sXG4gICAgICBjaGFuZ2UsXG4gICAgICBvcGVyYXRpb247XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY2hhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgIGNoYW5nZSA9IGNoYW5nZXNbaV07XG4gICAgaWYgKGNoYW5nZS5hZGRlZCkge1xuICAgICAgb3BlcmF0aW9uID0gMTtcbiAgICB9IGVsc2UgaWYgKGNoYW5nZS5yZW1vdmVkKSB7XG4gICAgICBvcGVyYXRpb24gPSAtMTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3BlcmF0aW9uID0gMDtcbiAgICB9XG5cbiAgICByZXQucHVzaChbb3BlcmF0aW9uLCBjaGFuZ2UudmFsdWVdKTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuIiwiZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRDaGFuZ2VzVG9YTUwoY2hhbmdlcykge1xuICBsZXQgcmV0ID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY2hhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgIGxldCBjaGFuZ2UgPSBjaGFuZ2VzW2ldO1xuICAgIGlmIChjaGFuZ2UuYWRkZWQpIHtcbiAgICAgIHJldC5wdXNoKCc8aW5zPicpO1xuICAgIH0gZWxzZSBpZiAoY2hhbmdlLnJlbW92ZWQpIHtcbiAgICAgIHJldC5wdXNoKCc8ZGVsPicpO1xuICAgIH1cblxuICAgIHJldC5wdXNoKGVzY2FwZUhUTUwoY2hhbmdlLnZhbHVlKSk7XG5cbiAgICBpZiAoY2hhbmdlLmFkZGVkKSB7XG4gICAgICByZXQucHVzaCgnPC9pbnM+Jyk7XG4gICAgfSBlbHNlIGlmIChjaGFuZ2UucmVtb3ZlZCkge1xuICAgICAgcmV0LnB1c2goJzwvZGVsPicpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmV0LmpvaW4oJycpO1xufVxuXG5mdW5jdGlvbiBlc2NhcGVIVE1MKHMpIHtcbiAgbGV0IG4gPSBzO1xuICBuID0gbi5yZXBsYWNlKC8mL2csICcmYW1wOycpO1xuICBuID0gbi5yZXBsYWNlKC88L2csICcmbHQ7Jyk7XG4gIG4gPSBuLnJlcGxhY2UoLz4vZywgJyZndDsnKTtcbiAgbiA9IG4ucmVwbGFjZSgvXCIvZywgJyZxdW90OycpO1xuXG4gIHJldHVybiBuO1xufVxuIiwiaW1wb3J0IERpZmYgZnJvbSAnLi9iYXNlJztcblxuZXhwb3J0IGNvbnN0IGFycmF5RGlmZiA9IG5ldyBEaWZmKCk7XG5hcnJheURpZmYudG9rZW5pemUgPSBhcnJheURpZmYuam9pbiA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZS5zbGljZSgpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZBcnJheXMob2xkQXJyLCBuZXdBcnIsIGNhbGxiYWNrKSB7IHJldHVybiBhcnJheURpZmYuZGlmZihvbGRBcnIsIG5ld0FyciwgY2FsbGJhY2spOyB9XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEaWZmKCkge31cblxuRGlmZi5wcm90b3R5cGUgPSB7XG4gIGRpZmYob2xkU3RyaW5nLCBuZXdTdHJpbmcsIG9wdGlvbnMgPSB7fSkge1xuICAgIGxldCBjYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjYWxsYmFjayA9IG9wdGlvbnM7XG4gICAgICBvcHRpb25zID0ge307XG4gICAgfVxuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cbiAgICBsZXQgc2VsZiA9IHRoaXM7XG5cbiAgICBmdW5jdGlvbiBkb25lKHZhbHVlKSB7XG4gICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsgY2FsbGJhY2sodW5kZWZpbmVkLCB2YWx1ZSk7IH0sIDApO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBbGxvdyBzdWJjbGFzc2VzIHRvIG1hc3NhZ2UgdGhlIGlucHV0IHByaW9yIHRvIHJ1bm5pbmdcbiAgICBvbGRTdHJpbmcgPSB0aGlzLmNhc3RJbnB1dChvbGRTdHJpbmcpO1xuICAgIG5ld1N0cmluZyA9IHRoaXMuY2FzdElucHV0KG5ld1N0cmluZyk7XG5cbiAgICBvbGRTdHJpbmcgPSB0aGlzLnJlbW92ZUVtcHR5KHRoaXMudG9rZW5pemUob2xkU3RyaW5nKSk7XG4gICAgbmV3U3RyaW5nID0gdGhpcy5yZW1vdmVFbXB0eSh0aGlzLnRva2VuaXplKG5ld1N0cmluZykpO1xuXG4gICAgbGV0IG5ld0xlbiA9IG5ld1N0cmluZy5sZW5ndGgsIG9sZExlbiA9IG9sZFN0cmluZy5sZW5ndGg7XG4gICAgbGV0IGVkaXRMZW5ndGggPSAxO1xuICAgIGxldCBtYXhFZGl0TGVuZ3RoID0gbmV3TGVuICsgb2xkTGVuO1xuICAgIGxldCBiZXN0UGF0aCA9IFt7IG5ld1BvczogLTEsIGNvbXBvbmVudHM6IFtdIH1dO1xuXG4gICAgLy8gU2VlZCBlZGl0TGVuZ3RoID0gMCwgaS5lLiB0aGUgY29udGVudCBzdGFydHMgd2l0aCB0aGUgc2FtZSB2YWx1ZXNcbiAgICBsZXQgb2xkUG9zID0gdGhpcy5leHRyYWN0Q29tbW9uKGJlc3RQYXRoWzBdLCBuZXdTdHJpbmcsIG9sZFN0cmluZywgMCk7XG4gICAgaWYgKGJlc3RQYXRoWzBdLm5ld1BvcyArIDEgPj0gbmV3TGVuICYmIG9sZFBvcyArIDEgPj0gb2xkTGVuKSB7XG4gICAgICAvLyBJZGVudGl0eSBwZXIgdGhlIGVxdWFsaXR5IGFuZCB0b2tlbml6ZXJcbiAgICAgIHJldHVybiBkb25lKFt7dmFsdWU6IHRoaXMuam9pbihuZXdTdHJpbmcpLCBjb3VudDogbmV3U3RyaW5nLmxlbmd0aH1dKTtcbiAgICB9XG5cbiAgICAvLyBNYWluIHdvcmtlciBtZXRob2QuIGNoZWNrcyBhbGwgcGVybXV0YXRpb25zIG9mIGEgZ2l2ZW4gZWRpdCBsZW5ndGggZm9yIGFjY2VwdGFuY2UuXG4gICAgZnVuY3Rpb24gZXhlY0VkaXRMZW5ndGgoKSB7XG4gICAgICBmb3IgKGxldCBkaWFnb25hbFBhdGggPSAtMSAqIGVkaXRMZW5ndGg7IGRpYWdvbmFsUGF0aCA8PSBlZGl0TGVuZ3RoOyBkaWFnb25hbFBhdGggKz0gMikge1xuICAgICAgICBsZXQgYmFzZVBhdGg7XG4gICAgICAgIGxldCBhZGRQYXRoID0gYmVzdFBhdGhbZGlhZ29uYWxQYXRoIC0gMV0sXG4gICAgICAgICAgICByZW1vdmVQYXRoID0gYmVzdFBhdGhbZGlhZ29uYWxQYXRoICsgMV0sXG4gICAgICAgICAgICBvbGRQb3MgPSAocmVtb3ZlUGF0aCA/IHJlbW92ZVBhdGgubmV3UG9zIDogMCkgLSBkaWFnb25hbFBhdGg7XG4gICAgICAgIGlmIChhZGRQYXRoKSB7XG4gICAgICAgICAgLy8gTm8gb25lIGVsc2UgaXMgZ29pbmcgdG8gYXR0ZW1wdCB0byB1c2UgdGhpcyB2YWx1ZSwgY2xlYXIgaXRcbiAgICAgICAgICBiZXN0UGF0aFtkaWFnb25hbFBhdGggLSAxXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjYW5BZGQgPSBhZGRQYXRoICYmIGFkZFBhdGgubmV3UG9zICsgMSA8IG5ld0xlbixcbiAgICAgICAgICAgIGNhblJlbW92ZSA9IHJlbW92ZVBhdGggJiYgMCA8PSBvbGRQb3MgJiYgb2xkUG9zIDwgb2xkTGVuO1xuICAgICAgICBpZiAoIWNhbkFkZCAmJiAhY2FuUmVtb3ZlKSB7XG4gICAgICAgICAgLy8gSWYgdGhpcyBwYXRoIGlzIGEgdGVybWluYWwgdGhlbiBwcnVuZVxuICAgICAgICAgIGJlc3RQYXRoW2RpYWdvbmFsUGF0aF0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZWxlY3QgdGhlIGRpYWdvbmFsIHRoYXQgd2Ugd2FudCB0byBicmFuY2ggZnJvbS4gV2Ugc2VsZWN0IHRoZSBwcmlvclxuICAgICAgICAvLyBwYXRoIHdob3NlIHBvc2l0aW9uIGluIHRoZSBuZXcgc3RyaW5nIGlzIHRoZSBmYXJ0aGVzdCBmcm9tIHRoZSBvcmlnaW5cbiAgICAgICAgLy8gYW5kIGRvZXMgbm90IHBhc3MgdGhlIGJvdW5kcyBvZiB0aGUgZGlmZiBncmFwaFxuICAgICAgICBpZiAoIWNhbkFkZCB8fCAoY2FuUmVtb3ZlICYmIGFkZFBhdGgubmV3UG9zIDwgcmVtb3ZlUGF0aC5uZXdQb3MpKSB7XG4gICAgICAgICAgYmFzZVBhdGggPSBjbG9uZVBhdGgocmVtb3ZlUGF0aCk7XG4gICAgICAgICAgc2VsZi5wdXNoQ29tcG9uZW50KGJhc2VQYXRoLmNvbXBvbmVudHMsIHVuZGVmaW5lZCwgdHJ1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYmFzZVBhdGggPSBhZGRQYXRoOyAgIC8vIE5vIG5lZWQgdG8gY2xvbmUsIHdlJ3ZlIHB1bGxlZCBpdCBmcm9tIHRoZSBsaXN0XG4gICAgICAgICAgYmFzZVBhdGgubmV3UG9zKys7XG4gICAgICAgICAgc2VsZi5wdXNoQ29tcG9uZW50KGJhc2VQYXRoLmNvbXBvbmVudHMsIHRydWUsIHVuZGVmaW5lZCk7XG4gICAgICAgIH1cblxuICAgICAgICBvbGRQb3MgPSBzZWxmLmV4dHJhY3RDb21tb24oYmFzZVBhdGgsIG5ld1N0cmluZywgb2xkU3RyaW5nLCBkaWFnb25hbFBhdGgpO1xuXG4gICAgICAgIC8vIElmIHdlIGhhdmUgaGl0IHRoZSBlbmQgb2YgYm90aCBzdHJpbmdzLCB0aGVuIHdlIGFyZSBkb25lXG4gICAgICAgIGlmIChiYXNlUGF0aC5uZXdQb3MgKyAxID49IG5ld0xlbiAmJiBvbGRQb3MgKyAxID49IG9sZExlbikge1xuICAgICAgICAgIHJldHVybiBkb25lKGJ1aWxkVmFsdWVzKHNlbGYsIGJhc2VQYXRoLmNvbXBvbmVudHMsIG5ld1N0cmluZywgb2xkU3RyaW5nLCBzZWxmLnVzZUxvbmdlc3RUb2tlbikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE90aGVyd2lzZSB0cmFjayB0aGlzIHBhdGggYXMgYSBwb3RlbnRpYWwgY2FuZGlkYXRlIGFuZCBjb250aW51ZS5cbiAgICAgICAgICBiZXN0UGF0aFtkaWFnb25hbFBhdGhdID0gYmFzZVBhdGg7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZWRpdExlbmd0aCsrO1xuICAgIH1cblxuICAgIC8vIFBlcmZvcm1zIHRoZSBsZW5ndGggb2YgZWRpdCBpdGVyYXRpb24uIElzIGEgYml0IGZ1Z2x5IGFzIHRoaXMgaGFzIHRvIHN1cHBvcnQgdGhlXG4gICAgLy8gc3luYyBhbmQgYXN5bmMgbW9kZSB3aGljaCBpcyBuZXZlciBmdW4uIExvb3BzIG92ZXIgZXhlY0VkaXRMZW5ndGggdW50aWwgYSB2YWx1ZVxuICAgIC8vIGlzIHByb2R1Y2VkLlxuICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgKGZ1bmN0aW9uIGV4ZWMoKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgLy8gVGhpcyBzaG91bGQgbm90IGhhcHBlbiwgYnV0IHdlIHdhbnQgdG8gYmUgc2FmZS5cbiAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAgIGlmIChlZGl0TGVuZ3RoID4gbWF4RWRpdExlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFleGVjRWRpdExlbmd0aCgpKSB7XG4gICAgICAgICAgICBleGVjKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCAwKTtcbiAgICAgIH0oKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdoaWxlIChlZGl0TGVuZ3RoIDw9IG1heEVkaXRMZW5ndGgpIHtcbiAgICAgICAgbGV0IHJldCA9IGV4ZWNFZGl0TGVuZ3RoKCk7XG4gICAgICAgIGlmIChyZXQpIHtcbiAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHB1c2hDb21wb25lbnQoY29tcG9uZW50cywgYWRkZWQsIHJlbW92ZWQpIHtcbiAgICBsZXQgbGFzdCA9IGNvbXBvbmVudHNbY29tcG9uZW50cy5sZW5ndGggLSAxXTtcbiAgICBpZiAobGFzdCAmJiBsYXN0LmFkZGVkID09PSBhZGRlZCAmJiBsYXN0LnJlbW92ZWQgPT09IHJlbW92ZWQpIHtcbiAgICAgIC8vIFdlIG5lZWQgdG8gY2xvbmUgaGVyZSBhcyB0aGUgY29tcG9uZW50IGNsb25lIG9wZXJhdGlvbiBpcyBqdXN0XG4gICAgICAvLyBhcyBzaGFsbG93IGFycmF5IGNsb25lXG4gICAgICBjb21wb25lbnRzW2NvbXBvbmVudHMubGVuZ3RoIC0gMV0gPSB7Y291bnQ6IGxhc3QuY291bnQgKyAxLCBhZGRlZDogYWRkZWQsIHJlbW92ZWQ6IHJlbW92ZWQgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tcG9uZW50cy5wdXNoKHtjb3VudDogMSwgYWRkZWQ6IGFkZGVkLCByZW1vdmVkOiByZW1vdmVkIH0pO1xuICAgIH1cbiAgfSxcbiAgZXh0cmFjdENvbW1vbihiYXNlUGF0aCwgbmV3U3RyaW5nLCBvbGRTdHJpbmcsIGRpYWdvbmFsUGF0aCkge1xuICAgIGxldCBuZXdMZW4gPSBuZXdTdHJpbmcubGVuZ3RoLFxuICAgICAgICBvbGRMZW4gPSBvbGRTdHJpbmcubGVuZ3RoLFxuICAgICAgICBuZXdQb3MgPSBiYXNlUGF0aC5uZXdQb3MsXG4gICAgICAgIG9sZFBvcyA9IG5ld1BvcyAtIGRpYWdvbmFsUGF0aCxcblxuICAgICAgICBjb21tb25Db3VudCA9IDA7XG4gICAgd2hpbGUgKG5ld1BvcyArIDEgPCBuZXdMZW4gJiYgb2xkUG9zICsgMSA8IG9sZExlbiAmJiB0aGlzLmVxdWFscyhuZXdTdHJpbmdbbmV3UG9zICsgMV0sIG9sZFN0cmluZ1tvbGRQb3MgKyAxXSkpIHtcbiAgICAgIG5ld1BvcysrO1xuICAgICAgb2xkUG9zKys7XG4gICAgICBjb21tb25Db3VudCsrO1xuICAgIH1cblxuICAgIGlmIChjb21tb25Db3VudCkge1xuICAgICAgYmFzZVBhdGguY29tcG9uZW50cy5wdXNoKHtjb3VudDogY29tbW9uQ291bnR9KTtcbiAgICB9XG5cbiAgICBiYXNlUGF0aC5uZXdQb3MgPSBuZXdQb3M7XG4gICAgcmV0dXJuIG9sZFBvcztcbiAgfSxcblxuICBlcXVhbHMobGVmdCwgcmlnaHQpIHtcbiAgICByZXR1cm4gbGVmdCA9PT0gcmlnaHQ7XG4gIH0sXG4gIHJlbW92ZUVtcHR5KGFycmF5KSB7XG4gICAgbGV0IHJldCA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhcnJheVtpXSkge1xuICAgICAgICByZXQucHVzaChhcnJheVtpXSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH0sXG4gIGNhc3RJbnB1dCh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfSxcbiAgdG9rZW5pemUodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUuc3BsaXQoJycpO1xuICB9LFxuICBqb2luKGNoYXJzKSB7XG4gICAgcmV0dXJuIGNoYXJzLmpvaW4oJycpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBidWlsZFZhbHVlcyhkaWZmLCBjb21wb25lbnRzLCBuZXdTdHJpbmcsIG9sZFN0cmluZywgdXNlTG9uZ2VzdFRva2VuKSB7XG4gIGxldCBjb21wb25lbnRQb3MgPSAwLFxuICAgICAgY29tcG9uZW50TGVuID0gY29tcG9uZW50cy5sZW5ndGgsXG4gICAgICBuZXdQb3MgPSAwLFxuICAgICAgb2xkUG9zID0gMDtcblxuICBmb3IgKDsgY29tcG9uZW50UG9zIDwgY29tcG9uZW50TGVuOyBjb21wb25lbnRQb3MrKykge1xuICAgIGxldCBjb21wb25lbnQgPSBjb21wb25lbnRzW2NvbXBvbmVudFBvc107XG4gICAgaWYgKCFjb21wb25lbnQucmVtb3ZlZCkge1xuICAgICAgaWYgKCFjb21wb25lbnQuYWRkZWQgJiYgdXNlTG9uZ2VzdFRva2VuKSB7XG4gICAgICAgIGxldCB2YWx1ZSA9IG5ld1N0cmluZy5zbGljZShuZXdQb3MsIG5ld1BvcyArIGNvbXBvbmVudC5jb3VudCk7XG4gICAgICAgIHZhbHVlID0gdmFsdWUubWFwKGZ1bmN0aW9uKHZhbHVlLCBpKSB7XG4gICAgICAgICAgbGV0IG9sZFZhbHVlID0gb2xkU3RyaW5nW29sZFBvcyArIGldO1xuICAgICAgICAgIHJldHVybiBvbGRWYWx1ZS5sZW5ndGggPiB2YWx1ZS5sZW5ndGggPyBvbGRWYWx1ZSA6IHZhbHVlO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb21wb25lbnQudmFsdWUgPSBkaWZmLmpvaW4odmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29tcG9uZW50LnZhbHVlID0gZGlmZi5qb2luKG5ld1N0cmluZy5zbGljZShuZXdQb3MsIG5ld1BvcyArIGNvbXBvbmVudC5jb3VudCkpO1xuICAgICAgfVxuICAgICAgbmV3UG9zICs9IGNvbXBvbmVudC5jb3VudDtcblxuICAgICAgLy8gQ29tbW9uIGNhc2VcbiAgICAgIGlmICghY29tcG9uZW50LmFkZGVkKSB7XG4gICAgICAgIG9sZFBvcyArPSBjb21wb25lbnQuY291bnQ7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbXBvbmVudC52YWx1ZSA9IGRpZmYuam9pbihvbGRTdHJpbmcuc2xpY2Uob2xkUG9zLCBvbGRQb3MgKyBjb21wb25lbnQuY291bnQpKTtcbiAgICAgIG9sZFBvcyArPSBjb21wb25lbnQuY291bnQ7XG5cbiAgICAgIC8vIFJldmVyc2UgYWRkIGFuZCByZW1vdmUgc28gcmVtb3ZlcyBhcmUgb3V0cHV0IGZpcnN0IHRvIG1hdGNoIGNvbW1vbiBjb252ZW50aW9uXG4gICAgICAvLyBUaGUgZGlmZmluZyBhbGdvcml0aG0gaXMgdGllZCB0byBhZGQgdGhlbiByZW1vdmUgb3V0cHV0IGFuZCB0aGlzIGlzIHRoZSBzaW1wbGVzdFxuICAgICAgLy8gcm91dGUgdG8gZ2V0IHRoZSBkZXNpcmVkIG91dHB1dCB3aXRoIG1pbmltYWwgb3ZlcmhlYWQuXG4gICAgICBpZiAoY29tcG9uZW50UG9zICYmIGNvbXBvbmVudHNbY29tcG9uZW50UG9zIC0gMV0uYWRkZWQpIHtcbiAgICAgICAgbGV0IHRtcCA9IGNvbXBvbmVudHNbY29tcG9uZW50UG9zIC0gMV07XG4gICAgICAgIGNvbXBvbmVudHNbY29tcG9uZW50UG9zIC0gMV0gPSBjb21wb25lbnRzW2NvbXBvbmVudFBvc107XG4gICAgICAgIGNvbXBvbmVudHNbY29tcG9uZW50UG9zXSA9IHRtcDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBTcGVjaWFsIGNhc2UgaGFuZGxlIGZvciB3aGVuIG9uZSB0ZXJtaW5hbCBpcyBpZ25vcmVkLiBGb3IgdGhpcyBjYXNlIHdlIG1lcmdlIHRoZVxuICAvLyB0ZXJtaW5hbCBpbnRvIHRoZSBwcmlvciBzdHJpbmcgYW5kIGRyb3AgdGhlIGNoYW5nZS5cbiAgbGV0IGxhc3RDb21wb25lbnQgPSBjb21wb25lbnRzW2NvbXBvbmVudExlbiAtIDFdO1xuICBpZiAoY29tcG9uZW50TGVuID4gMVxuICAgICAgJiYgKGxhc3RDb21wb25lbnQuYWRkZWQgfHwgbGFzdENvbXBvbmVudC5yZW1vdmVkKVxuICAgICAgJiYgZGlmZi5lcXVhbHMoJycsIGxhc3RDb21wb25lbnQudmFsdWUpKSB7XG4gICAgY29tcG9uZW50c1tjb21wb25lbnRMZW4gLSAyXS52YWx1ZSArPSBsYXN0Q29tcG9uZW50LnZhbHVlO1xuICAgIGNvbXBvbmVudHMucG9wKCk7XG4gIH1cblxuICByZXR1cm4gY29tcG9uZW50cztcbn1cblxuZnVuY3Rpb24gY2xvbmVQYXRoKHBhdGgpIHtcbiAgcmV0dXJuIHsgbmV3UG9zOiBwYXRoLm5ld1BvcywgY29tcG9uZW50czogcGF0aC5jb21wb25lbnRzLnNsaWNlKDApIH07XG59XG4iLCJpbXBvcnQgRGlmZiBmcm9tICcuL2Jhc2UnO1xuXG5leHBvcnQgY29uc3QgY2hhcmFjdGVyRGlmZiA9IG5ldyBEaWZmKCk7XG5leHBvcnQgZnVuY3Rpb24gZGlmZkNoYXJzKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjaykgeyByZXR1cm4gY2hhcmFjdGVyRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjayk7IH1cbiIsImltcG9ydCBEaWZmIGZyb20gJy4vYmFzZSc7XG5cbmV4cG9ydCBjb25zdCBjc3NEaWZmID0gbmV3IERpZmYoKTtcbmNzc0RpZmYudG9rZW5pemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUuc3BsaXQoLyhbe306OyxdfFxccyspLyk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGlmZkNzcyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHsgcmV0dXJuIGNzc0RpZmYuZGlmZihvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spOyB9XG4iLCJpbXBvcnQgRGlmZiBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0IHtsaW5lRGlmZn0gZnJvbSAnLi9saW5lJztcblxuY29uc3Qgb2JqZWN0UHJvdG90eXBlVG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5cbmV4cG9ydCBjb25zdCBqc29uRGlmZiA9IG5ldyBEaWZmKCk7XG4vLyBEaXNjcmltaW5hdGUgYmV0d2VlbiB0d28gbGluZXMgb2YgcHJldHR5LXByaW50ZWQsIHNlcmlhbGl6ZWQgSlNPTiB3aGVyZSBvbmUgb2YgdGhlbSBoYXMgYVxuLy8gZGFuZ2xpbmcgY29tbWEgYW5kIHRoZSBvdGhlciBkb2Vzbid0LiBUdXJucyBvdXQgaW5jbHVkaW5nIHRoZSBkYW5nbGluZyBjb21tYSB5aWVsZHMgdGhlIG5pY2VzdCBvdXRwdXQ6XG5qc29uRGlmZi51c2VMb25nZXN0VG9rZW4gPSB0cnVlO1xuXG5qc29uRGlmZi50b2tlbml6ZSA9IGxpbmVEaWZmLnRva2VuaXplO1xuanNvbkRpZmYuY2FzdElucHV0ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgY29uc3Qge3VuZGVmaW5lZFJlcGxhY2VtZW50fSA9IHRoaXMub3B0aW9ucztcblxuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHZhbHVlIDogSlNPTi5zdHJpbmdpZnkoY2Fub25pY2FsaXplKHZhbHVlKSwgZnVuY3Rpb24oaywgdikge1xuICAgIGlmICh0eXBlb2YgdiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWRSZXBsYWNlbWVudDtcbiAgICB9XG5cbiAgICByZXR1cm4gdjtcbiAgfSwgJyAgJyk7XG59O1xuanNvbkRpZmYuZXF1YWxzID0gZnVuY3Rpb24obGVmdCwgcmlnaHQpIHtcbiAgcmV0dXJuIERpZmYucHJvdG90eXBlLmVxdWFscyhsZWZ0LnJlcGxhY2UoLywoW1xcclxcbl0pL2csICckMScpLCByaWdodC5yZXBsYWNlKC8sKFtcXHJcXG5dKS9nLCAnJDEnKSk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGlmZkpzb24ob2xkT2JqLCBuZXdPYmosIG9wdGlvbnMpIHsgcmV0dXJuIGpzb25EaWZmLmRpZmYob2xkT2JqLCBuZXdPYmosIG9wdGlvbnMpOyB9XG5cbi8vIFRoaXMgZnVuY3Rpb24gaGFuZGxlcyB0aGUgcHJlc2VuY2Ugb2YgY2lyY3VsYXIgcmVmZXJlbmNlcyBieSBiYWlsaW5nIG91dCB3aGVuIGVuY291bnRlcmluZyBhblxuLy8gb2JqZWN0IHRoYXQgaXMgYWxyZWFkeSBvbiB0aGUgXCJzdGFja1wiIG9mIGl0ZW1zIGJlaW5nIHByb2Nlc3NlZC5cbmV4cG9ydCBmdW5jdGlvbiBjYW5vbmljYWxpemUob2JqLCBzdGFjaywgcmVwbGFjZW1lbnRTdGFjaykge1xuICBzdGFjayA9IHN0YWNrIHx8IFtdO1xuICByZXBsYWNlbWVudFN0YWNrID0gcmVwbGFjZW1lbnRTdGFjayB8fCBbXTtcblxuICBsZXQgaTtcblxuICBmb3IgKGkgPSAwOyBpIDwgc3RhY2subGVuZ3RoOyBpICs9IDEpIHtcbiAgICBpZiAoc3RhY2tbaV0gPT09IG9iaikge1xuICAgICAgcmV0dXJuIHJlcGxhY2VtZW50U3RhY2tbaV07XG4gICAgfVxuICB9XG5cbiAgbGV0IGNhbm9uaWNhbGl6ZWRPYmo7XG5cbiAgaWYgKCdbb2JqZWN0IEFycmF5XScgPT09IG9iamVjdFByb3RvdHlwZVRvU3RyaW5nLmNhbGwob2JqKSkge1xuICAgIHN0YWNrLnB1c2gob2JqKTtcbiAgICBjYW5vbmljYWxpemVkT2JqID0gbmV3IEFycmF5KG9iai5sZW5ndGgpO1xuICAgIHJlcGxhY2VtZW50U3RhY2sucHVzaChjYW5vbmljYWxpemVkT2JqKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjYW5vbmljYWxpemVkT2JqW2ldID0gY2Fub25pY2FsaXplKG9ialtpXSwgc3RhY2ssIHJlcGxhY2VtZW50U3RhY2spO1xuICAgIH1cbiAgICBzdGFjay5wb3AoKTtcbiAgICByZXBsYWNlbWVudFN0YWNrLnBvcCgpO1xuICAgIHJldHVybiBjYW5vbmljYWxpemVkT2JqO1xuICB9XG5cbiAgaWYgKG9iaiAmJiBvYmoudG9KU09OKSB7XG4gICAgb2JqID0gb2JqLnRvSlNPTigpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIG9iaiAhPT0gbnVsbCkge1xuICAgIHN0YWNrLnB1c2gob2JqKTtcbiAgICBjYW5vbmljYWxpemVkT2JqID0ge307XG4gICAgcmVwbGFjZW1lbnRTdGFjay5wdXNoKGNhbm9uaWNhbGl6ZWRPYmopO1xuICAgIGxldCBzb3J0ZWRLZXlzID0gW10sXG4gICAgICAgIGtleTtcbiAgICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgc29ydGVkS2V5cy5wdXNoKGtleSk7XG4gICAgICB9XG4gICAgfVxuICAgIHNvcnRlZEtleXMuc29ydCgpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBzb3J0ZWRLZXlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBrZXkgPSBzb3J0ZWRLZXlzW2ldO1xuICAgICAgY2Fub25pY2FsaXplZE9ialtrZXldID0gY2Fub25pY2FsaXplKG9ialtrZXldLCBzdGFjaywgcmVwbGFjZW1lbnRTdGFjayk7XG4gICAgfVxuICAgIHN0YWNrLnBvcCgpO1xuICAgIHJlcGxhY2VtZW50U3RhY2sucG9wKCk7XG4gIH0gZWxzZSB7XG4gICAgY2Fub25pY2FsaXplZE9iaiA9IG9iajtcbiAgfVxuICByZXR1cm4gY2Fub25pY2FsaXplZE9iajtcbn1cbiIsImltcG9ydCBEaWZmIGZyb20gJy4vYmFzZSc7XG5pbXBvcnQge2dlbmVyYXRlT3B0aW9uc30gZnJvbSAnLi4vdXRpbC9wYXJhbXMnO1xuXG5leHBvcnQgY29uc3QgbGluZURpZmYgPSBuZXcgRGlmZigpO1xubGluZURpZmYudG9rZW5pemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICBsZXQgcmV0TGluZXMgPSBbXSxcbiAgICAgIGxpbmVzQW5kTmV3bGluZXMgPSB2YWx1ZS5zcGxpdCgvKFxcbnxcXHJcXG4pLyk7XG5cbiAgLy8gSWdub3JlIHRoZSBmaW5hbCBlbXB0eSB0b2tlbiB0aGF0IG9jY3VycyBpZiB0aGUgc3RyaW5nIGVuZHMgd2l0aCBhIG5ldyBsaW5lXG4gIGlmICghbGluZXNBbmROZXdsaW5lc1tsaW5lc0FuZE5ld2xpbmVzLmxlbmd0aCAtIDFdKSB7XG4gICAgbGluZXNBbmROZXdsaW5lcy5wb3AoKTtcbiAgfVxuXG4gIC8vIE1lcmdlIHRoZSBjb250ZW50IGFuZCBsaW5lIHNlcGFyYXRvcnMgaW50byBzaW5nbGUgdG9rZW5zXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXNBbmROZXdsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIGxldCBsaW5lID0gbGluZXNBbmROZXdsaW5lc1tpXTtcblxuICAgIGlmIChpICUgMiAmJiAhdGhpcy5vcHRpb25zLm5ld2xpbmVJc1Rva2VuKSB7XG4gICAgICByZXRMaW5lc1tyZXRMaW5lcy5sZW5ndGggLSAxXSArPSBsaW5lO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmlnbm9yZVdoaXRlc3BhY2UpIHtcbiAgICAgICAgbGluZSA9IGxpbmUudHJpbSgpO1xuICAgICAgfVxuICAgICAgcmV0TGluZXMucHVzaChsaW5lKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmV0TGluZXM7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGlmZkxpbmVzKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjaykgeyByZXR1cm4gbGluZURpZmYuZGlmZihvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spOyB9XG5leHBvcnQgZnVuY3Rpb24gZGlmZlRyaW1tZWRMaW5lcyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHtcbiAgbGV0IG9wdGlvbnMgPSBnZW5lcmF0ZU9wdGlvbnMoY2FsbGJhY2ssIHtpZ25vcmVXaGl0ZXNwYWNlOiB0cnVlfSk7XG4gIHJldHVybiBsaW5lRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBvcHRpb25zKTtcbn1cbiIsImltcG9ydCBEaWZmIGZyb20gJy4vYmFzZSc7XG5cblxuZXhwb3J0IGNvbnN0IHNlbnRlbmNlRGlmZiA9IG5ldyBEaWZmKCk7XG5zZW50ZW5jZURpZmYudG9rZW5pemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUuc3BsaXQoLyhcXFMuKz9bLiE/XSkoPz1cXHMrfCQpLyk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGlmZlNlbnRlbmNlcyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHsgcmV0dXJuIHNlbnRlbmNlRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjayk7IH1cbiIsImltcG9ydCBEaWZmIGZyb20gJy4vYmFzZSc7XG5pbXBvcnQge2dlbmVyYXRlT3B0aW9uc30gZnJvbSAnLi4vdXRpbC9wYXJhbXMnO1xuXG4vLyBCYXNlZCBvbiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MYXRpbl9zY3JpcHRfaW5fVW5pY29kZVxuLy9cbi8vIFJhbmdlcyBhbmQgZXhjZXB0aW9uczpcbi8vIExhdGluLTEgU3VwcGxlbWVudCwgMDA4MOKAkzAwRkZcbi8vICAtIFUrMDBENyAgw5cgTXVsdGlwbGljYXRpb24gc2lnblxuLy8gIC0gVSswMEY3ICDDtyBEaXZpc2lvbiBzaWduXG4vLyBMYXRpbiBFeHRlbmRlZC1BLCAwMTAw4oCTMDE3RlxuLy8gTGF0aW4gRXh0ZW5kZWQtQiwgMDE4MOKAkzAyNEZcbi8vIElQQSBFeHRlbnNpb25zLCAwMjUw4oCTMDJBRlxuLy8gU3BhY2luZyBNb2RpZmllciBMZXR0ZXJzLCAwMkIw4oCTMDJGRlxuLy8gIC0gVSswMkM3ICDLhyAmIzcxMTsgIENhcm9uXG4vLyAgLSBVKzAyRDggIMuYICYjNzI4OyAgQnJldmVcbi8vICAtIFUrMDJEOSAgy5kgJiM3Mjk7ICBEb3QgQWJvdmVcbi8vICAtIFUrMDJEQSAgy5ogJiM3MzA7ICBSaW5nIEFib3ZlXG4vLyAgLSBVKzAyREIgIMubICYjNzMxOyAgT2dvbmVrXG4vLyAgLSBVKzAyREMgIMucICYjNzMyOyAgU21hbGwgVGlsZGVcbi8vICAtIFUrMDJERCAgy50gJiM3MzM7ICBEb3VibGUgQWN1dGUgQWNjZW50XG4vLyBMYXRpbiBFeHRlbmRlZCBBZGRpdGlvbmFsLCAxRTAw4oCTMUVGRlxuY29uc3QgZXh0ZW5kZWRXb3JkQ2hhcnMgPSAvXlthLXpBLVpcXHV7QzB9LVxcdXtGRn1cXHV7RDh9LVxcdXtGNn1cXHV7Rjh9LVxcdXsyQzZ9XFx1ezJDOH0tXFx1ezJEN31cXHV7MkRFfS1cXHV7MkZGfVxcdXsxRTAwfS1cXHV7MUVGRn1dKyQvdTtcblxuY29uc3QgcmVXaGl0ZXNwYWNlID0gL1xcUy87XG5cbmV4cG9ydCBjb25zdCB3b3JkRGlmZiA9IG5ldyBEaWZmKCk7XG53b3JkRGlmZi5lcXVhbHMgPSBmdW5jdGlvbihsZWZ0LCByaWdodCkge1xuICByZXR1cm4gbGVmdCA9PT0gcmlnaHQgfHwgKHRoaXMub3B0aW9ucy5pZ25vcmVXaGl0ZXNwYWNlICYmICFyZVdoaXRlc3BhY2UudGVzdChsZWZ0KSAmJiAhcmVXaGl0ZXNwYWNlLnRlc3QocmlnaHQpKTtcbn07XG53b3JkRGlmZi50b2tlbml6ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIGxldCB0b2tlbnMgPSB2YWx1ZS5zcGxpdCgvKFxccyt8XFxiKS8pO1xuXG4gIC8vIEpvaW4gdGhlIGJvdW5kYXJ5IHNwbGl0cyB0aGF0IHdlIGRvIG5vdCBjb25zaWRlciB0byBiZSBib3VuZGFyaWVzLiBUaGlzIGlzIHByaW1hcmlseSB0aGUgZXh0ZW5kZWQgTGF0aW4gY2hhcmFjdGVyIHNldC5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgLy8gSWYgd2UgaGF2ZSBhbiBlbXB0eSBzdHJpbmcgaW4gdGhlIG5leHQgZmllbGQgYW5kIHdlIGhhdmUgb25seSB3b3JkIGNoYXJzIGJlZm9yZSBhbmQgYWZ0ZXIsIG1lcmdlXG4gICAgaWYgKCF0b2tlbnNbaSArIDFdICYmIHRva2Vuc1tpICsgMl1cbiAgICAgICAgICAmJiBleHRlbmRlZFdvcmRDaGFycy50ZXN0KHRva2Vuc1tpXSlcbiAgICAgICAgICAmJiBleHRlbmRlZFdvcmRDaGFycy50ZXN0KHRva2Vuc1tpICsgMl0pKSB7XG4gICAgICB0b2tlbnNbaV0gKz0gdG9rZW5zW2kgKyAyXTtcbiAgICAgIHRva2Vucy5zcGxpY2UoaSArIDEsIDIpO1xuICAgICAgaS0tO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0b2tlbnM7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGlmZldvcmRzKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjaykge1xuICBsZXQgb3B0aW9ucyA9IGdlbmVyYXRlT3B0aW9ucyhjYWxsYmFjaywge2lnbm9yZVdoaXRlc3BhY2U6IHRydWV9KTtcbiAgcmV0dXJuIHdvcmREaWZmLmRpZmYob2xkU3RyLCBuZXdTdHIsIG9wdGlvbnMpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZXb3Jkc1dpdGhTcGFjZShvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHtcbiAgcmV0dXJuIHdvcmREaWZmLmRpZmYob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKTtcbn1cbiIsIi8qIFNlZSBMSUNFTlNFIGZpbGUgZm9yIHRlcm1zIG9mIHVzZSAqL1xuXG4vKlxuICogVGV4dCBkaWZmIGltcGxlbWVudGF0aW9uLlxuICpcbiAqIFRoaXMgbGlicmFyeSBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIEFQSVM6XG4gKiBKc0RpZmYuZGlmZkNoYXJzOiBDaGFyYWN0ZXIgYnkgY2hhcmFjdGVyIGRpZmZcbiAqIEpzRGlmZi5kaWZmV29yZHM6IFdvcmQgKGFzIGRlZmluZWQgYnkgXFxiIHJlZ2V4KSBkaWZmIHdoaWNoIGlnbm9yZXMgd2hpdGVzcGFjZVxuICogSnNEaWZmLmRpZmZMaW5lczogTGluZSBiYXNlZCBkaWZmXG4gKlxuICogSnNEaWZmLmRpZmZDc3M6IERpZmYgdGFyZ2V0ZWQgYXQgQ1NTIGNvbnRlbnRcbiAqXG4gKiBUaGVzZSBtZXRob2RzIGFyZSBiYXNlZCBvbiB0aGUgaW1wbGVtZW50YXRpb24gcHJvcG9zZWQgaW5cbiAqIFwiQW4gTyhORCkgRGlmZmVyZW5jZSBBbGdvcml0aG0gYW5kIGl0cyBWYXJpYXRpb25zXCIgKE15ZXJzLCAxOTg2KS5cbiAqIGh0dHA6Ly9jaXRlc2VlcnguaXN0LnBzdS5lZHUvdmlld2RvYy9zdW1tYXJ5P2RvaT0xMC4xLjEuNC42OTI3XG4gKi9cbmltcG9ydCBEaWZmIGZyb20gJy4vZGlmZi9iYXNlJztcbmltcG9ydCB7ZGlmZkNoYXJzfSBmcm9tICcuL2RpZmYvY2hhcmFjdGVyJztcbmltcG9ydCB7ZGlmZldvcmRzLCBkaWZmV29yZHNXaXRoU3BhY2V9IGZyb20gJy4vZGlmZi93b3JkJztcbmltcG9ydCB7ZGlmZkxpbmVzLCBkaWZmVHJpbW1lZExpbmVzfSBmcm9tICcuL2RpZmYvbGluZSc7XG5pbXBvcnQge2RpZmZTZW50ZW5jZXN9IGZyb20gJy4vZGlmZi9zZW50ZW5jZSc7XG5cbmltcG9ydCB7ZGlmZkNzc30gZnJvbSAnLi9kaWZmL2Nzcyc7XG5pbXBvcnQge2RpZmZKc29uLCBjYW5vbmljYWxpemV9IGZyb20gJy4vZGlmZi9qc29uJztcblxuaW1wb3J0IHtkaWZmQXJyYXlzfSBmcm9tICcuL2RpZmYvYXJyYXknO1xuXG5pbXBvcnQge2FwcGx5UGF0Y2gsIGFwcGx5UGF0Y2hlc30gZnJvbSAnLi9wYXRjaC9hcHBseSc7XG5pbXBvcnQge3BhcnNlUGF0Y2h9IGZyb20gJy4vcGF0Y2gvcGFyc2UnO1xuaW1wb3J0IHtzdHJ1Y3R1cmVkUGF0Y2gsIGNyZWF0ZVR3b0ZpbGVzUGF0Y2gsIGNyZWF0ZVBhdGNofSBmcm9tICcuL3BhdGNoL2NyZWF0ZSc7XG5cbmltcG9ydCB7Y29udmVydENoYW5nZXNUb0RNUH0gZnJvbSAnLi9jb252ZXJ0L2RtcCc7XG5pbXBvcnQge2NvbnZlcnRDaGFuZ2VzVG9YTUx9IGZyb20gJy4vY29udmVydC94bWwnO1xuXG5leHBvcnQge1xuICBEaWZmLFxuXG4gIGRpZmZDaGFycyxcbiAgZGlmZldvcmRzLFxuICBkaWZmV29yZHNXaXRoU3BhY2UsXG4gIGRpZmZMaW5lcyxcbiAgZGlmZlRyaW1tZWRMaW5lcyxcbiAgZGlmZlNlbnRlbmNlcyxcblxuICBkaWZmQ3NzLFxuICBkaWZmSnNvbixcblxuICBkaWZmQXJyYXlzLFxuXG4gIHN0cnVjdHVyZWRQYXRjaCxcbiAgY3JlYXRlVHdvRmlsZXNQYXRjaCxcbiAgY3JlYXRlUGF0Y2gsXG4gIGFwcGx5UGF0Y2gsXG4gIGFwcGx5UGF0Y2hlcyxcbiAgcGFyc2VQYXRjaCxcbiAgY29udmVydENoYW5nZXNUb0RNUCxcbiAgY29udmVydENoYW5nZXNUb1hNTCxcbiAgY2Fub25pY2FsaXplXG59O1xuIiwiaW1wb3J0IHtwYXJzZVBhdGNofSBmcm9tICcuL3BhcnNlJztcbmltcG9ydCBkaXN0YW5jZUl0ZXJhdG9yIGZyb20gJy4uL3V0aWwvZGlzdGFuY2UtaXRlcmF0b3InO1xuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlQYXRjaChzb3VyY2UsIHVuaURpZmYsIG9wdGlvbnMgPSB7fSkge1xuICBpZiAodHlwZW9mIHVuaURpZmYgPT09ICdzdHJpbmcnKSB7XG4gICAgdW5pRGlmZiA9IHBhcnNlUGF0Y2godW5pRGlmZik7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheSh1bmlEaWZmKSkge1xuICAgIGlmICh1bmlEaWZmLmxlbmd0aCA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYXBwbHlQYXRjaCBvbmx5IHdvcmtzIHdpdGggYSBzaW5nbGUgaW5wdXQuJyk7XG4gICAgfVxuXG4gICAgdW5pRGlmZiA9IHVuaURpZmZbMF07XG4gIH1cblxuICAvLyBBcHBseSB0aGUgZGlmZiB0byB0aGUgaW5wdXRcbiAgbGV0IGxpbmVzID0gc291cmNlLnNwbGl0KC9cXHJcXG58W1xcblxcdlxcZlxcclxceDg1XS8pLFxuICAgICAgZGVsaW1pdGVycyA9IHNvdXJjZS5tYXRjaCgvXFxyXFxufFtcXG5cXHZcXGZcXHJcXHg4NV0vZykgfHwgW10sXG4gICAgICBodW5rcyA9IHVuaURpZmYuaHVua3MsXG5cbiAgICAgIGNvbXBhcmVMaW5lID0gb3B0aW9ucy5jb21wYXJlTGluZSB8fCAoKGxpbmVOdW1iZXIsIGxpbmUsIG9wZXJhdGlvbiwgcGF0Y2hDb250ZW50KSA9PiBsaW5lID09PSBwYXRjaENvbnRlbnQpLFxuICAgICAgZXJyb3JDb3VudCA9IDAsXG4gICAgICBmdXp6RmFjdG9yID0gb3B0aW9ucy5mdXp6RmFjdG9yIHx8IDAsXG4gICAgICBtaW5MaW5lID0gMCxcbiAgICAgIG9mZnNldCA9IDAsXG5cbiAgICAgIHJlbW92ZUVPRk5MLFxuICAgICAgYWRkRU9GTkw7XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgaHVuayBleGFjdGx5IGZpdHMgb24gdGhlIHByb3ZpZGVkIGxvY2F0aW9uXG4gICAqL1xuICBmdW5jdGlvbiBodW5rRml0cyhodW5rLCB0b1Bvcykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaHVuay5saW5lcy5sZW5ndGg7IGorKykge1xuICAgICAgbGV0IGxpbmUgPSBodW5rLmxpbmVzW2pdLFxuICAgICAgICAgIG9wZXJhdGlvbiA9IGxpbmVbMF0sXG4gICAgICAgICAgY29udGVudCA9IGxpbmUuc3Vic3RyKDEpO1xuXG4gICAgICBpZiAob3BlcmF0aW9uID09PSAnICcgfHwgb3BlcmF0aW9uID09PSAnLScpIHtcbiAgICAgICAgLy8gQ29udGV4dCBzYW5pdHkgY2hlY2tcbiAgICAgICAgaWYgKCFjb21wYXJlTGluZSh0b1BvcyArIDEsIGxpbmVzW3RvUG9zXSwgb3BlcmF0aW9uLCBjb250ZW50KSkge1xuICAgICAgICAgIGVycm9yQ291bnQrKztcblxuICAgICAgICAgIGlmIChlcnJvckNvdW50ID4gZnV6ekZhY3Rvcikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0b1BvcysrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLy8gU2VhcmNoIGJlc3QgZml0IG9mZnNldHMgZm9yIGVhY2ggaHVuayBiYXNlZCBvbiB0aGUgcHJldmlvdXMgb25lc1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGh1bmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IGh1bmsgPSBodW5rc1tpXSxcbiAgICAgICAgbWF4TGluZSA9IGxpbmVzLmxlbmd0aCAtIGh1bmsub2xkTGluZXMsXG4gICAgICAgIGxvY2FsT2Zmc2V0ID0gMCxcbiAgICAgICAgdG9Qb3MgPSBvZmZzZXQgKyBodW5rLm9sZFN0YXJ0IC0gMTtcblxuICAgIGxldCBpdGVyYXRvciA9IGRpc3RhbmNlSXRlcmF0b3IodG9Qb3MsIG1pbkxpbmUsIG1heExpbmUpO1xuXG4gICAgZm9yICg7IGxvY2FsT2Zmc2V0ICE9PSB1bmRlZmluZWQ7IGxvY2FsT2Zmc2V0ID0gaXRlcmF0b3IoKSkge1xuICAgICAgaWYgKGh1bmtGaXRzKGh1bmssIHRvUG9zICsgbG9jYWxPZmZzZXQpKSB7XG4gICAgICAgIGh1bmsub2Zmc2V0ID0gb2Zmc2V0ICs9IGxvY2FsT2Zmc2V0O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobG9jYWxPZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFNldCBsb3dlciB0ZXh0IGxpbWl0IHRvIGVuZCBvZiB0aGUgY3VycmVudCBodW5rLCBzbyBuZXh0IG9uZXMgZG9uJ3QgdHJ5XG4gICAgLy8gdG8gZml0IG92ZXIgYWxyZWFkeSBwYXRjaGVkIHRleHRcbiAgICBtaW5MaW5lID0gaHVuay5vZmZzZXQgKyBodW5rLm9sZFN0YXJ0ICsgaHVuay5vbGRMaW5lcztcbiAgfVxuXG4gIC8vIEFwcGx5IHBhdGNoIGh1bmtzXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaHVua3MubGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgaHVuayA9IGh1bmtzW2ldLFxuICAgICAgICB0b1BvcyA9IGh1bmsub2Zmc2V0ICsgaHVuay5uZXdTdGFydCAtIDE7XG4gICAgaWYgKGh1bmsubmV3TGluZXMgPT0gMCkgeyB0b1BvcysrOyB9XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGh1bmsubGluZXMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGxldCBsaW5lID0gaHVuay5saW5lc1tqXSxcbiAgICAgICAgICBvcGVyYXRpb24gPSBsaW5lWzBdLFxuICAgICAgICAgIGNvbnRlbnQgPSBsaW5lLnN1YnN0cigxKSxcbiAgICAgICAgICBkZWxpbWl0ZXIgPSBodW5rLmxpbmVkZWxpbWl0ZXJzW2pdO1xuXG4gICAgICBpZiAob3BlcmF0aW9uID09PSAnICcpIHtcbiAgICAgICAgdG9Qb3MrKztcbiAgICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uID09PSAnLScpIHtcbiAgICAgICAgbGluZXMuc3BsaWNlKHRvUG9zLCAxKTtcbiAgICAgICAgZGVsaW1pdGVycy5zcGxpY2UodG9Qb3MsIDEpO1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uID09PSAnKycpIHtcbiAgICAgICAgbGluZXMuc3BsaWNlKHRvUG9zLCAwLCBjb250ZW50KTtcbiAgICAgICAgZGVsaW1pdGVycy5zcGxpY2UodG9Qb3MsIDAsIGRlbGltaXRlcik7XG4gICAgICAgIHRvUG9zKys7XG4gICAgICB9IGVsc2UgaWYgKG9wZXJhdGlvbiA9PT0gJ1xcXFwnKSB7XG4gICAgICAgIGxldCBwcmV2aW91c09wZXJhdGlvbiA9IGh1bmsubGluZXNbaiAtIDFdID8gaHVuay5saW5lc1tqIC0gMV1bMF0gOiBudWxsO1xuICAgICAgICBpZiAocHJldmlvdXNPcGVyYXRpb24gPT09ICcrJykge1xuICAgICAgICAgIHJlbW92ZUVPRk5MID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChwcmV2aW91c09wZXJhdGlvbiA9PT0gJy0nKSB7XG4gICAgICAgICAgYWRkRU9GTkwgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gSGFuZGxlIEVPRk5MIGluc2VydGlvbi9yZW1vdmFsXG4gIGlmIChyZW1vdmVFT0ZOTCkge1xuICAgIHdoaWxlICghbGluZXNbbGluZXMubGVuZ3RoIC0gMV0pIHtcbiAgICAgIGxpbmVzLnBvcCgpO1xuICAgICAgZGVsaW1pdGVycy5wb3AoKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoYWRkRU9GTkwpIHtcbiAgICBsaW5lcy5wdXNoKCcnKTtcbiAgICBkZWxpbWl0ZXJzLnB1c2goJ1xcbicpO1xuICB9XG4gIGZvciAobGV0IF9rID0gMDsgX2sgPCBsaW5lcy5sZW5ndGggLSAxOyBfaysrKSB7XG4gICAgbGluZXNbX2tdID0gbGluZXNbX2tdICsgZGVsaW1pdGVyc1tfa107XG4gIH1cbiAgcmV0dXJuIGxpbmVzLmpvaW4oJycpO1xufVxuXG4vLyBXcmFwcGVyIHRoYXQgc3VwcG9ydHMgbXVsdGlwbGUgZmlsZSBwYXRjaGVzIHZpYSBjYWxsYmFja3MuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlQYXRjaGVzKHVuaURpZmYsIG9wdGlvbnMpIHtcbiAgaWYgKHR5cGVvZiB1bmlEaWZmID09PSAnc3RyaW5nJykge1xuICAgIHVuaURpZmYgPSBwYXJzZVBhdGNoKHVuaURpZmYpO1xuICB9XG5cbiAgbGV0IGN1cnJlbnRJbmRleCA9IDA7XG4gIGZ1bmN0aW9uIHByb2Nlc3NJbmRleCgpIHtcbiAgICBsZXQgaW5kZXggPSB1bmlEaWZmW2N1cnJlbnRJbmRleCsrXTtcbiAgICBpZiAoIWluZGV4KSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIG9wdGlvbnMubG9hZEZpbGUoaW5kZXgsIGZ1bmN0aW9uKGVyciwgZGF0YSkge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICByZXR1cm4gb3B0aW9ucy5jb21wbGV0ZShlcnIpO1xuICAgICAgfVxuXG4gICAgICBsZXQgdXBkYXRlZENvbnRlbnQgPSBhcHBseVBhdGNoKGRhdGEsIGluZGV4LCBvcHRpb25zKTtcbiAgICAgIG9wdGlvbnMucGF0Y2hlZChpbmRleCwgdXBkYXRlZENvbnRlbnQsIGZ1bmN0aW9uKGVycikge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgcmV0dXJuIG9wdGlvbnMuY29tcGxldGUoZXJyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb2Nlc3NJbmRleCgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgcHJvY2Vzc0luZGV4KCk7XG59XG4iLCJpbXBvcnQge2RpZmZMaW5lc30gZnJvbSAnLi4vZGlmZi9saW5lJztcblxuZXhwb3J0IGZ1bmN0aW9uIHN0cnVjdHVyZWRQYXRjaChvbGRGaWxlTmFtZSwgbmV3RmlsZU5hbWUsIG9sZFN0ciwgbmV3U3RyLCBvbGRIZWFkZXIsIG5ld0hlYWRlciwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0ge307XG4gIH1cbiAgaWYgKHR5cGVvZiBvcHRpb25zLmNvbnRleHQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0aW9ucy5jb250ZXh0ID0gNDtcbiAgfVxuXG4gIGNvbnN0IGRpZmYgPSBkaWZmTGluZXMob2xkU3RyLCBuZXdTdHIsIG9wdGlvbnMpO1xuICBkaWZmLnB1c2goe3ZhbHVlOiAnJywgbGluZXM6IFtdfSk7ICAgLy8gQXBwZW5kIGFuIGVtcHR5IHZhbHVlIHRvIG1ha2UgY2xlYW51cCBlYXNpZXJcblxuICBmdW5jdGlvbiBjb250ZXh0TGluZXMobGluZXMpIHtcbiAgICByZXR1cm4gbGluZXMubWFwKGZ1bmN0aW9uKGVudHJ5KSB7IHJldHVybiAnICcgKyBlbnRyeTsgfSk7XG4gIH1cblxuICBsZXQgaHVua3MgPSBbXTtcbiAgbGV0IG9sZFJhbmdlU3RhcnQgPSAwLCBuZXdSYW5nZVN0YXJ0ID0gMCwgY3VyUmFuZ2UgPSBbXSxcbiAgICAgIG9sZExpbmUgPSAxLCBuZXdMaW5lID0gMTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaWZmLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY3VycmVudCA9IGRpZmZbaV0sXG4gICAgICAgICAgbGluZXMgPSBjdXJyZW50LmxpbmVzIHx8IGN1cnJlbnQudmFsdWUucmVwbGFjZSgvXFxuJC8sICcnKS5zcGxpdCgnXFxuJyk7XG4gICAgY3VycmVudC5saW5lcyA9IGxpbmVzO1xuXG4gICAgaWYgKGN1cnJlbnQuYWRkZWQgfHwgY3VycmVudC5yZW1vdmVkKSB7XG4gICAgICAvLyBJZiB3ZSBoYXZlIHByZXZpb3VzIGNvbnRleHQsIHN0YXJ0IHdpdGggdGhhdFxuICAgICAgaWYgKCFvbGRSYW5nZVN0YXJ0KSB7XG4gICAgICAgIGNvbnN0IHByZXYgPSBkaWZmW2kgLSAxXTtcbiAgICAgICAgb2xkUmFuZ2VTdGFydCA9IG9sZExpbmU7XG4gICAgICAgIG5ld1JhbmdlU3RhcnQgPSBuZXdMaW5lO1xuXG4gICAgICAgIGlmIChwcmV2KSB7XG4gICAgICAgICAgY3VyUmFuZ2UgPSBvcHRpb25zLmNvbnRleHQgPiAwID8gY29udGV4dExpbmVzKHByZXYubGluZXMuc2xpY2UoLW9wdGlvbnMuY29udGV4dCkpIDogW107XG4gICAgICAgICAgb2xkUmFuZ2VTdGFydCAtPSBjdXJSYW5nZS5sZW5ndGg7XG4gICAgICAgICAgbmV3UmFuZ2VTdGFydCAtPSBjdXJSYW5nZS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gT3V0cHV0IG91ciBjaGFuZ2VzXG4gICAgICBjdXJSYW5nZS5wdXNoKC4uLiBsaW5lcy5tYXAoZnVuY3Rpb24oZW50cnkpIHtcbiAgICAgICAgcmV0dXJuIChjdXJyZW50LmFkZGVkID8gJysnIDogJy0nKSArIGVudHJ5O1xuICAgICAgfSkpO1xuXG4gICAgICAvLyBUcmFjayB0aGUgdXBkYXRlZCBmaWxlIHBvc2l0aW9uXG4gICAgICBpZiAoY3VycmVudC5hZGRlZCkge1xuICAgICAgICBuZXdMaW5lICs9IGxpbmVzLmxlbmd0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9sZExpbmUgKz0gbGluZXMubGVuZ3RoO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZGVudGljYWwgY29udGV4dCBsaW5lcy4gVHJhY2sgbGluZSBjaGFuZ2VzXG4gICAgICBpZiAob2xkUmFuZ2VTdGFydCkge1xuICAgICAgICAvLyBDbG9zZSBvdXQgYW55IGNoYW5nZXMgdGhhdCBoYXZlIGJlZW4gb3V0cHV0IChvciBqb2luIG92ZXJsYXBwaW5nKVxuICAgICAgICBpZiAobGluZXMubGVuZ3RoIDw9IG9wdGlvbnMuY29udGV4dCAqIDIgJiYgaSA8IGRpZmYubGVuZ3RoIC0gMikge1xuICAgICAgICAgIC8vIE92ZXJsYXBwaW5nXG4gICAgICAgICAgY3VyUmFuZ2UucHVzaCguLi4gY29udGV4dExpbmVzKGxpbmVzKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gZW5kIHRoZSByYW5nZSBhbmQgb3V0cHV0XG4gICAgICAgICAgbGV0IGNvbnRleHRTaXplID0gTWF0aC5taW4obGluZXMubGVuZ3RoLCBvcHRpb25zLmNvbnRleHQpO1xuICAgICAgICAgIGN1clJhbmdlLnB1c2goLi4uIGNvbnRleHRMaW5lcyhsaW5lcy5zbGljZSgwLCBjb250ZXh0U2l6ZSkpKTtcblxuICAgICAgICAgIGxldCBodW5rID0ge1xuICAgICAgICAgICAgb2xkU3RhcnQ6IG9sZFJhbmdlU3RhcnQsXG4gICAgICAgICAgICBvbGRMaW5lczogKG9sZExpbmUgLSBvbGRSYW5nZVN0YXJ0ICsgY29udGV4dFNpemUpLFxuICAgICAgICAgICAgbmV3U3RhcnQ6IG5ld1JhbmdlU3RhcnQsXG4gICAgICAgICAgICBuZXdMaW5lczogKG5ld0xpbmUgLSBuZXdSYW5nZVN0YXJ0ICsgY29udGV4dFNpemUpLFxuICAgICAgICAgICAgbGluZXM6IGN1clJhbmdlXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAoaSA+PSBkaWZmLmxlbmd0aCAtIDIgJiYgbGluZXMubGVuZ3RoIDw9IG9wdGlvbnMuY29udGV4dCkge1xuICAgICAgICAgICAgLy8gRU9GIGlzIGluc2lkZSB0aGlzIGh1bmtcbiAgICAgICAgICAgIGxldCBvbGRFT0ZOZXdsaW5lID0gKC9cXG4kLy50ZXN0KG9sZFN0cikpO1xuICAgICAgICAgICAgbGV0IG5ld0VPRk5ld2xpbmUgPSAoL1xcbiQvLnRlc3QobmV3U3RyKSk7XG4gICAgICAgICAgICBpZiAobGluZXMubGVuZ3RoID09IDAgJiYgIW9sZEVPRk5ld2xpbmUpIHtcbiAgICAgICAgICAgICAgLy8gc3BlY2lhbCBjYXNlOiBvbGQgaGFzIG5vIGVvbCBhbmQgbm8gdHJhaWxpbmcgY29udGV4dDsgbm8tbmwgY2FuIGVuZCB1cCBiZWZvcmUgYWRkc1xuICAgICAgICAgICAgICBjdXJSYW5nZS5zcGxpY2UoaHVuay5vbGRMaW5lcywgMCwgJ1xcXFwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZScpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghb2xkRU9GTmV3bGluZSB8fCAhbmV3RU9GTmV3bGluZSkge1xuICAgICAgICAgICAgICBjdXJSYW5nZS5wdXNoKCdcXFxcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaHVua3MucHVzaChodW5rKTtcblxuICAgICAgICAgIG9sZFJhbmdlU3RhcnQgPSAwO1xuICAgICAgICAgIG5ld1JhbmdlU3RhcnQgPSAwO1xuICAgICAgICAgIGN1clJhbmdlID0gW107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG9sZExpbmUgKz0gbGluZXMubGVuZ3RoO1xuICAgICAgbmV3TGluZSArPSBsaW5lcy5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBvbGRGaWxlTmFtZTogb2xkRmlsZU5hbWUsIG5ld0ZpbGVOYW1lOiBuZXdGaWxlTmFtZSxcbiAgICBvbGRIZWFkZXI6IG9sZEhlYWRlciwgbmV3SGVhZGVyOiBuZXdIZWFkZXIsXG4gICAgaHVua3M6IGh1bmtzXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUd29GaWxlc1BhdGNoKG9sZEZpbGVOYW1lLCBuZXdGaWxlTmFtZSwgb2xkU3RyLCBuZXdTdHIsIG9sZEhlYWRlciwgbmV3SGVhZGVyLCBvcHRpb25zKSB7XG4gIGNvbnN0IGRpZmYgPSBzdHJ1Y3R1cmVkUGF0Y2gob2xkRmlsZU5hbWUsIG5ld0ZpbGVOYW1lLCBvbGRTdHIsIG5ld1N0ciwgb2xkSGVhZGVyLCBuZXdIZWFkZXIsIG9wdGlvbnMpO1xuXG4gIGNvbnN0IHJldCA9IFtdO1xuICBpZiAob2xkRmlsZU5hbWUgPT0gbmV3RmlsZU5hbWUpIHtcbiAgICByZXQucHVzaCgnSW5kZXg6ICcgKyBvbGRGaWxlTmFtZSk7XG4gIH1cbiAgcmV0LnB1c2goJz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0nKTtcbiAgcmV0LnB1c2goJy0tLSAnICsgZGlmZi5vbGRGaWxlTmFtZSArICh0eXBlb2YgZGlmZi5vbGRIZWFkZXIgPT09ICd1bmRlZmluZWQnID8gJycgOiAnXFx0JyArIGRpZmYub2xkSGVhZGVyKSk7XG4gIHJldC5wdXNoKCcrKysgJyArIGRpZmYubmV3RmlsZU5hbWUgKyAodHlwZW9mIGRpZmYubmV3SGVhZGVyID09PSAndW5kZWZpbmVkJyA/ICcnIDogJ1xcdCcgKyBkaWZmLm5ld0hlYWRlcikpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGlmZi5odW5rcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGh1bmsgPSBkaWZmLmh1bmtzW2ldO1xuICAgIHJldC5wdXNoKFxuICAgICAgJ0BAIC0nICsgaHVuay5vbGRTdGFydCArICcsJyArIGh1bmsub2xkTGluZXNcbiAgICAgICsgJyArJyArIGh1bmsubmV3U3RhcnQgKyAnLCcgKyBodW5rLm5ld0xpbmVzXG4gICAgICArICcgQEAnXG4gICAgKTtcbiAgICByZXQucHVzaC5hcHBseShyZXQsIGh1bmsubGluZXMpO1xuICB9XG5cbiAgcmV0dXJuIHJldC5qb2luKCdcXG4nKSArICdcXG4nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUGF0Y2goZmlsZU5hbWUsIG9sZFN0ciwgbmV3U3RyLCBvbGRIZWFkZXIsIG5ld0hlYWRlciwgb3B0aW9ucykge1xuICByZXR1cm4gY3JlYXRlVHdvRmlsZXNQYXRjaChmaWxlTmFtZSwgZmlsZU5hbWUsIG9sZFN0ciwgbmV3U3RyLCBvbGRIZWFkZXIsIG5ld0hlYWRlciwgb3B0aW9ucyk7XG59XG4iLCJleHBvcnQgZnVuY3Rpb24gcGFyc2VQYXRjaCh1bmlEaWZmLCBvcHRpb25zID0ge30pIHtcbiAgbGV0IGRpZmZzdHIgPSB1bmlEaWZmLnNwbGl0KC9cXHJcXG58W1xcblxcdlxcZlxcclxceDg1XS8pLFxuICAgICAgZGVsaW1pdGVycyA9IHVuaURpZmYubWF0Y2goL1xcclxcbnxbXFxuXFx2XFxmXFxyXFx4ODVdL2cpIHx8IFtdLFxuICAgICAgbGlzdCA9IFtdLFxuICAgICAgaSA9IDA7XG5cbiAgZnVuY3Rpb24gcGFyc2VJbmRleCgpIHtcbiAgICBsZXQgaW5kZXggPSB7fTtcbiAgICBsaXN0LnB1c2goaW5kZXgpO1xuXG4gICAgLy8gUGFyc2UgZGlmZiBtZXRhZGF0YVxuICAgIHdoaWxlIChpIDwgZGlmZnN0ci5sZW5ndGgpIHtcbiAgICAgIGxldCBsaW5lID0gZGlmZnN0cltpXTtcblxuICAgICAgLy8gRmlsZSBoZWFkZXIgZm91bmQsIGVuZCBwYXJzaW5nIGRpZmYgbWV0YWRhdGFcbiAgICAgIGlmICgvXihcXC1cXC1cXC18XFwrXFwrXFwrfEBAKVxccy8udGVzdChsaW5lKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgLy8gRGlmZiBpbmRleFxuICAgICAgbGV0IGhlYWRlciA9ICgvXig/OkluZGV4OnxkaWZmKD86IC1yIFxcdyspKylcXHMrKC4rPylcXHMqJC8pLmV4ZWMobGluZSk7XG4gICAgICBpZiAoaGVhZGVyKSB7XG4gICAgICAgIGluZGV4LmluZGV4ID0gaGVhZGVyWzFdO1xuICAgICAgfVxuXG4gICAgICBpKys7XG4gICAgfVxuXG4gICAgLy8gUGFyc2UgZmlsZSBoZWFkZXJzIGlmIHRoZXkgYXJlIGRlZmluZWQuIFVuaWZpZWQgZGlmZiByZXF1aXJlcyB0aGVtLCBidXRcbiAgICAvLyB0aGVyZSdzIG5vIHRlY2huaWNhbCBpc3N1ZXMgdG8gaGF2ZSBhbiBpc29sYXRlZCBodW5rIHdpdGhvdXQgZmlsZSBoZWFkZXJcbiAgICBwYXJzZUZpbGVIZWFkZXIoaW5kZXgpO1xuICAgIHBhcnNlRmlsZUhlYWRlcihpbmRleCk7XG5cbiAgICAvLyBQYXJzZSBodW5rc1xuICAgIGluZGV4Lmh1bmtzID0gW107XG5cbiAgICB3aGlsZSAoaSA8IGRpZmZzdHIubGVuZ3RoKSB7XG4gICAgICBsZXQgbGluZSA9IGRpZmZzdHJbaV07XG5cbiAgICAgIGlmICgvXihJbmRleDp8ZGlmZnxcXC1cXC1cXC18XFwrXFwrXFwrKVxccy8udGVzdChsaW5lKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH0gZWxzZSBpZiAoL15AQC8udGVzdChsaW5lKSkge1xuICAgICAgICBpbmRleC5odW5rcy5wdXNoKHBhcnNlSHVuaygpKTtcbiAgICAgIH0gZWxzZSBpZiAobGluZSAmJiBvcHRpb25zLnN0cmljdCkge1xuICAgICAgICAvLyBJZ25vcmUgdW5leHBlY3RlZCBjb250ZW50IHVubGVzcyBpbiBzdHJpY3QgbW9kZVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gbGluZSAnICsgKGkgKyAxKSArICcgJyArIEpTT04uc3RyaW5naWZ5KGxpbmUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGkrKztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBQYXJzZXMgdGhlIC0tLSBhbmQgKysrIGhlYWRlcnMsIGlmIG5vbmUgYXJlIGZvdW5kLCBubyBsaW5lc1xuICAvLyBhcmUgY29uc3VtZWQuXG4gIGZ1bmN0aW9uIHBhcnNlRmlsZUhlYWRlcihpbmRleCkge1xuICAgIGNvbnN0IGhlYWRlclBhdHRlcm4gPSAvXigtLS18XFwrXFwrXFwrKVxccysoW1xcUyBdKikoPzpcXHQoLio/KVxccyopPyQvO1xuICAgIGNvbnN0IGZpbGVIZWFkZXIgPSBoZWFkZXJQYXR0ZXJuLmV4ZWMoZGlmZnN0cltpXSk7XG4gICAgaWYgKGZpbGVIZWFkZXIpIHtcbiAgICAgIGxldCBrZXlQcmVmaXggPSBmaWxlSGVhZGVyWzFdID09PSAnLS0tJyA/ICdvbGQnIDogJ25ldyc7XG4gICAgICBpbmRleFtrZXlQcmVmaXggKyAnRmlsZU5hbWUnXSA9IGZpbGVIZWFkZXJbMl07XG4gICAgICBpbmRleFtrZXlQcmVmaXggKyAnSGVhZGVyJ10gPSBmaWxlSGVhZGVyWzNdO1xuXG4gICAgICBpKys7XG4gICAgfVxuICB9XG5cbiAgLy8gUGFyc2VzIGEgaHVua1xuICAvLyBUaGlzIGFzc3VtZXMgdGhhdCB3ZSBhcmUgYXQgdGhlIHN0YXJ0IG9mIGEgaHVuay5cbiAgZnVuY3Rpb24gcGFyc2VIdW5rKCkge1xuICAgIGxldCBjaHVua0hlYWRlckluZGV4ID0gaSxcbiAgICAgICAgY2h1bmtIZWFkZXJMaW5lID0gZGlmZnN0cltpKytdLFxuICAgICAgICBjaHVua0hlYWRlciA9IGNodW5rSGVhZGVyTGluZS5zcGxpdCgvQEAgLShcXGQrKSg/OiwoXFxkKykpPyBcXCsoXFxkKykoPzosKFxcZCspKT8gQEAvKTtcblxuICAgIGxldCBodW5rID0ge1xuICAgICAgb2xkU3RhcnQ6ICtjaHVua0hlYWRlclsxXSxcbiAgICAgIG9sZExpbmVzOiArY2h1bmtIZWFkZXJbMl0gfHwgMSxcbiAgICAgIG5ld1N0YXJ0OiArY2h1bmtIZWFkZXJbM10sXG4gICAgICBuZXdMaW5lczogK2NodW5rSGVhZGVyWzRdIHx8IDEsXG4gICAgICBsaW5lczogW10sXG4gICAgICBsaW5lZGVsaW1pdGVyczogW11cbiAgICB9O1xuXG4gICAgbGV0IGFkZENvdW50ID0gMCxcbiAgICAgICAgcmVtb3ZlQ291bnQgPSAwO1xuICAgIGZvciAoOyBpIDwgZGlmZnN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgLy8gTGluZXMgc3RhcnRpbmcgd2l0aCAnLS0tJyBjb3VsZCBiZSBtaXN0YWtlbiBmb3IgdGhlIFwicmVtb3ZlIGxpbmVcIiBvcGVyYXRpb25cbiAgICAgIC8vIEJ1dCB0aGV5IGNvdWxkIGJlIHRoZSBoZWFkZXIgZm9yIHRoZSBuZXh0IGZpbGUuIFRoZXJlZm9yZSBwcnVuZSBzdWNoIGNhc2VzIG91dC5cbiAgICAgIGlmIChkaWZmc3RyW2ldLmluZGV4T2YoJy0tLSAnKSA9PT0gMFxuICAgICAgICAgICAgJiYgKGkgKyAyIDwgZGlmZnN0ci5sZW5ndGgpXG4gICAgICAgICAgICAmJiBkaWZmc3RyW2kgKyAxXS5pbmRleE9mKCcrKysgJykgPT09IDBcbiAgICAgICAgICAgICYmIGRpZmZzdHJbaSArIDJdLmluZGV4T2YoJ0BAJykgPT09IDApIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGxldCBvcGVyYXRpb24gPSBkaWZmc3RyW2ldWzBdO1xuXG4gICAgICBpZiAob3BlcmF0aW9uID09PSAnKycgfHwgb3BlcmF0aW9uID09PSAnLScgfHwgb3BlcmF0aW9uID09PSAnICcgfHwgb3BlcmF0aW9uID09PSAnXFxcXCcpIHtcbiAgICAgICAgaHVuay5saW5lcy5wdXNoKGRpZmZzdHJbaV0pO1xuICAgICAgICBodW5rLmxpbmVkZWxpbWl0ZXJzLnB1c2goZGVsaW1pdGVyc1tpXSB8fCAnXFxuJyk7XG5cbiAgICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gJysnKSB7XG4gICAgICAgICAgYWRkQ291bnQrKztcbiAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRpb24gPT09ICctJykge1xuICAgICAgICAgIHJlbW92ZUNvdW50Kys7XG4gICAgICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uID09PSAnICcpIHtcbiAgICAgICAgICBhZGRDb3VudCsrO1xuICAgICAgICAgIHJlbW92ZUNvdW50Kys7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEhhbmRsZSB0aGUgZW1wdHkgYmxvY2sgY291bnQgY2FzZVxuICAgIGlmICghYWRkQ291bnQgJiYgaHVuay5uZXdMaW5lcyA9PT0gMSkge1xuICAgICAgaHVuay5uZXdMaW5lcyA9IDA7XG4gICAgfVxuICAgIGlmICghcmVtb3ZlQ291bnQgJiYgaHVuay5vbGRMaW5lcyA9PT0gMSkge1xuICAgICAgaHVuay5vbGRMaW5lcyA9IDA7XG4gICAgfVxuXG4gICAgLy8gUGVyZm9ybSBvcHRpb25hbCBzYW5pdHkgY2hlY2tpbmdcbiAgICBpZiAob3B0aW9ucy5zdHJpY3QpIHtcbiAgICAgIGlmIChhZGRDb3VudCAhPT0gaHVuay5uZXdMaW5lcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FkZGVkIGxpbmUgY291bnQgZGlkIG5vdCBtYXRjaCBmb3IgaHVuayBhdCBsaW5lICcgKyAoY2h1bmtIZWFkZXJJbmRleCArIDEpKTtcbiAgICAgIH1cbiAgICAgIGlmIChyZW1vdmVDb3VudCAhPT0gaHVuay5vbGRMaW5lcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlbW92ZWQgbGluZSBjb3VudCBkaWQgbm90IG1hdGNoIGZvciBodW5rIGF0IGxpbmUgJyArIChjaHVua0hlYWRlckluZGV4ICsgMSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBodW5rO1xuICB9XG5cbiAgd2hpbGUgKGkgPCBkaWZmc3RyLmxlbmd0aCkge1xuICAgIHBhcnNlSW5kZXgoKTtcbiAgfVxuXG4gIHJldHVybiBsaXN0O1xufVxuIiwiLy8gSXRlcmF0b3IgdGhhdCB0cmF2ZXJzZXMgaW4gdGhlIHJhbmdlIG9mIFttaW4sIG1heF0sIHN0ZXBwaW5nXG4vLyBieSBkaXN0YW5jZSBmcm9tIGEgZ2l2ZW4gc3RhcnQgcG9zaXRpb24uIEkuZS4gZm9yIFswLCA0XSwgd2l0aFxuLy8gc3RhcnQgb2YgMiwgdGhpcyB3aWxsIGl0ZXJhdGUgMiwgMywgMSwgNCwgMC5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKHN0YXJ0LCBtaW5MaW5lLCBtYXhMaW5lKSB7XG4gIGxldCB3YW50Rm9yd2FyZCA9IHRydWUsXG4gICAgICBiYWNrd2FyZEV4aGF1c3RlZCA9IGZhbHNlLFxuICAgICAgZm9yd2FyZEV4aGF1c3RlZCA9IGZhbHNlLFxuICAgICAgbG9jYWxPZmZzZXQgPSAxO1xuXG4gIHJldHVybiBmdW5jdGlvbiBpdGVyYXRvcigpIHtcbiAgICBpZiAod2FudEZvcndhcmQgJiYgIWZvcndhcmRFeGhhdXN0ZWQpIHtcbiAgICAgIGlmIChiYWNrd2FyZEV4aGF1c3RlZCkge1xuICAgICAgICBsb2NhbE9mZnNldCsrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2FudEZvcndhcmQgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgaWYgdHJ5aW5nIHRvIGZpdCBiZXlvbmQgdGV4dCBsZW5ndGgsIGFuZCBpZiBub3QsIGNoZWNrIGl0IGZpdHNcbiAgICAgIC8vIGFmdGVyIG9mZnNldCBsb2NhdGlvbiAob3IgZGVzaXJlZCBsb2NhdGlvbiBvbiBmaXJzdCBpdGVyYXRpb24pXG4gICAgICBpZiAoc3RhcnQgKyBsb2NhbE9mZnNldCA8PSBtYXhMaW5lKSB7XG4gICAgICAgIHJldHVybiBsb2NhbE9mZnNldDtcbiAgICAgIH1cblxuICAgICAgZm9yd2FyZEV4aGF1c3RlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKCFiYWNrd2FyZEV4aGF1c3RlZCkge1xuICAgICAgaWYgKCFmb3J3YXJkRXhoYXVzdGVkKSB7XG4gICAgICAgIHdhbnRGb3J3YXJkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgaWYgdHJ5aW5nIHRvIGZpdCBiZWZvcmUgdGV4dCBiZWdpbm5pbmcsIGFuZCBpZiBub3QsIGNoZWNrIGl0IGZpdHNcbiAgICAgIC8vIGJlZm9yZSBvZmZzZXQgbG9jYXRpb25cbiAgICAgIGlmIChtaW5MaW5lIDw9IHN0YXJ0IC0gbG9jYWxPZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIC1sb2NhbE9mZnNldCsrO1xuICAgICAgfVxuXG4gICAgICBiYWNrd2FyZEV4aGF1c3RlZCA9IHRydWU7XG4gICAgICByZXR1cm4gaXRlcmF0b3IoKTtcbiAgICB9XG5cbiAgICAvLyBXZSB0cmllZCB0byBmaXQgaHVuayBiZWZvcmUgdGV4dCBiZWdpbm5pbmcgYW5kIGJleW9uZCB0ZXh0IGxlbmdodCwgdGhlblxuICAgIC8vIGh1bmsgY2FuJ3QgZml0IG9uIHRoZSB0ZXh0LiBSZXR1cm4gdW5kZWZpbmVkXG4gIH07XG59XG4iLCJleHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVPcHRpb25zKG9wdGlvbnMsIGRlZmF1bHRzKSB7XG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGRlZmF1bHRzLmNhbGxiYWNrID0gb3B0aW9ucztcbiAgfSBlbHNlIGlmIChvcHRpb25zKSB7XG4gICAgZm9yIChsZXQgbmFtZSBpbiBvcHRpb25zKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgZGVmYXVsdHNbbmFtZV0gPSBvcHRpb25zW25hbWVdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZGVmYXVsdHM7XG59XG4iLCJcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmb3JFYWNoIChvYmosIGZuLCBjdHgpIHtcbiAgICBpZiAodG9TdHJpbmcuY2FsbChmbikgIT09ICdbb2JqZWN0IEZ1bmN0aW9uXScpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaXRlcmF0b3IgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgfVxuICAgIHZhciBsID0gb2JqLmxlbmd0aDtcbiAgICBpZiAobCA9PT0gK2wpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIGZuLmNhbGwoY3R4LCBvYmpbaV0sIGksIG9iaik7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKHZhciBrIGluIG9iaikge1xuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKG9iaiwgaykpIHtcbiAgICAgICAgICAgICAgICBmbi5jYWxsKGN0eCwgb2JqW2tdLCBrLCBvYmopO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufTtcblxuIiwiXG52YXIgaW5kZXhPZiA9IFtdLmluZGV4T2Y7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYXJyLCBvYmope1xuICBpZiAoaW5kZXhPZikgcmV0dXJuIGFyci5pbmRleE9mKG9iaik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGFycltpXSA9PT0gb2JqKSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59OyIsIm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiIsIi8qISBKU09OIHYzLjMuMCB8IGh0dHA6Ly9iZXN0aWVqcy5naXRodWIuaW8vanNvbjMgfCBDb3B5cmlnaHQgMjAxMi0yMDE0LCBLaXQgQ2FtYnJpZGdlIHwgaHR0cDovL2tpdC5taXQtbGljZW5zZS5vcmcgKi9cbjsoZnVuY3Rpb24gKHJvb3QpIHtcbiAgLy8gRGV0ZWN0IHRoZSBgZGVmaW5lYCBmdW5jdGlvbiBleHBvc2VkIGJ5IGFzeW5jaHJvbm91cyBtb2R1bGUgbG9hZGVycy4gVGhlXG4gIC8vIHN0cmljdCBgZGVmaW5lYCBjaGVjayBpcyBuZWNlc3NhcnkgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBgci5qc2AuXG4gIHZhciBpc0xvYWRlciA9IHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kO1xuXG4gIC8vIFVzZSB0aGUgYGdsb2JhbGAgb2JqZWN0IGV4cG9zZWQgYnkgTm9kZSAoaW5jbHVkaW5nIEJyb3dzZXJpZnkgdmlhXG4gIC8vIGBpbnNlcnQtbW9kdWxlLWdsb2JhbHNgKSwgTmFyd2hhbCwgYW5kIFJpbmdvIGFzIHRoZSBkZWZhdWx0IGNvbnRleHQuXG4gIC8vIFJoaW5vIGV4cG9ydHMgYSBgZ2xvYmFsYCBmdW5jdGlvbiBpbnN0ZWFkLlxuICB2YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gXCJvYmplY3RcIiAmJiBnbG9iYWw7XG4gIGlmIChmcmVlR2xvYmFsICYmIChmcmVlR2xvYmFsW1wiZ2xvYmFsXCJdID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWxbXCJ3aW5kb3dcIl0gPT09IGZyZWVHbG9iYWwpKSB7XG4gICAgcm9vdCA9IGZyZWVHbG9iYWw7XG4gIH1cblxuICAvLyBQdWJsaWM6IEluaXRpYWxpemVzIEpTT04gMyB1c2luZyB0aGUgZ2l2ZW4gYGNvbnRleHRgIG9iamVjdCwgYXR0YWNoaW5nIHRoZVxuICAvLyBgc3RyaW5naWZ5YCBhbmQgYHBhcnNlYCBmdW5jdGlvbnMgdG8gdGhlIHNwZWNpZmllZCBgZXhwb3J0c2Agb2JqZWN0LlxuICBmdW5jdGlvbiBydW5JbkNvbnRleHQoY29udGV4dCwgZXhwb3J0cykge1xuICAgIGNvbnRleHQgfHwgKGNvbnRleHQgPSByb290W1wiT2JqZWN0XCJdKCkpO1xuICAgIGV4cG9ydHMgfHwgKGV4cG9ydHMgPSByb290W1wiT2JqZWN0XCJdKCkpO1xuXG4gICAgLy8gTmF0aXZlIGNvbnN0cnVjdG9yIGFsaWFzZXMuXG4gICAgdmFyIE51bWJlciA9IGNvbnRleHRbXCJOdW1iZXJcIl0gfHwgcm9vdFtcIk51bWJlclwiXSxcbiAgICAgICAgU3RyaW5nID0gY29udGV4dFtcIlN0cmluZ1wiXSB8fCByb290W1wiU3RyaW5nXCJdLFxuICAgICAgICBPYmplY3QgPSBjb250ZXh0W1wiT2JqZWN0XCJdIHx8IHJvb3RbXCJPYmplY3RcIl0sXG4gICAgICAgIERhdGUgPSBjb250ZXh0W1wiRGF0ZVwiXSB8fCByb290W1wiRGF0ZVwiXSxcbiAgICAgICAgU3ludGF4RXJyb3IgPSBjb250ZXh0W1wiU3ludGF4RXJyb3JcIl0gfHwgcm9vdFtcIlN5bnRheEVycm9yXCJdLFxuICAgICAgICBUeXBlRXJyb3IgPSBjb250ZXh0W1wiVHlwZUVycm9yXCJdIHx8IHJvb3RbXCJUeXBlRXJyb3JcIl0sXG4gICAgICAgIE1hdGggPSBjb250ZXh0W1wiTWF0aFwiXSB8fCByb290W1wiTWF0aFwiXSxcbiAgICAgICAgbmF0aXZlSlNPTiA9IGNvbnRleHRbXCJKU09OXCJdIHx8IHJvb3RbXCJKU09OXCJdO1xuXG4gICAgLy8gRGVsZWdhdGUgdG8gdGhlIG5hdGl2ZSBgc3RyaW5naWZ5YCBhbmQgYHBhcnNlYCBpbXBsZW1lbnRhdGlvbnMuXG4gICAgaWYgKHR5cGVvZiBuYXRpdmVKU09OID09IFwib2JqZWN0XCIgJiYgbmF0aXZlSlNPTikge1xuICAgICAgZXhwb3J0cy5zdHJpbmdpZnkgPSBuYXRpdmVKU09OLnN0cmluZ2lmeTtcbiAgICAgIGV4cG9ydHMucGFyc2UgPSBuYXRpdmVKU09OLnBhcnNlO1xuICAgIH1cblxuICAgIC8vIENvbnZlbmllbmNlIGFsaWFzZXMuXG4gICAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZSxcbiAgICAgICAgZ2V0Q2xhc3MgPSBvYmplY3RQcm90by50b1N0cmluZyxcbiAgICAgICAgaXNQcm9wZXJ0eSwgZm9yRWFjaCwgdW5kZWY7XG5cbiAgICAvLyBUZXN0IHRoZSBgRGF0ZSNnZXRVVEMqYCBtZXRob2RzLiBCYXNlZCBvbiB3b3JrIGJ5IEBZYWZmbGUuXG4gICAgdmFyIGlzRXh0ZW5kZWQgPSBuZXcgRGF0ZSgtMzUwOTgyNzMzNDU3MzI5Mik7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFRoZSBgZ2V0VVRDRnVsbFllYXJgLCBgTW9udGhgLCBhbmQgYERhdGVgIG1ldGhvZHMgcmV0dXJuIG5vbnNlbnNpY2FsXG4gICAgICAvLyByZXN1bHRzIGZvciBjZXJ0YWluIGRhdGVzIGluIE9wZXJhID49IDEwLjUzLlxuICAgICAgaXNFeHRlbmRlZCA9IGlzRXh0ZW5kZWQuZ2V0VVRDRnVsbFllYXIoKSA9PSAtMTA5MjUyICYmIGlzRXh0ZW5kZWQuZ2V0VVRDTW9udGgoKSA9PT0gMCAmJiBpc0V4dGVuZGVkLmdldFVUQ0RhdGUoKSA9PT0gMSAmJlxuICAgICAgICAvLyBTYWZhcmkgPCAyLjAuMiBzdG9yZXMgdGhlIGludGVybmFsIG1pbGxpc2Vjb25kIHRpbWUgdmFsdWUgY29ycmVjdGx5LFxuICAgICAgICAvLyBidXQgY2xpcHMgdGhlIHZhbHVlcyByZXR1cm5lZCBieSB0aGUgZGF0ZSBtZXRob2RzIHRvIHRoZSByYW5nZSBvZlxuICAgICAgICAvLyBzaWduZWQgMzItYml0IGludGVnZXJzIChbLTIgKiogMzEsIDIgKiogMzEgLSAxXSkuXG4gICAgICAgIGlzRXh0ZW5kZWQuZ2V0VVRDSG91cnMoKSA9PSAxMCAmJiBpc0V4dGVuZGVkLmdldFVUQ01pbnV0ZXMoKSA9PSAzNyAmJiBpc0V4dGVuZGVkLmdldFVUQ1NlY29uZHMoKSA9PSA2ICYmIGlzRXh0ZW5kZWQuZ2V0VVRDTWlsbGlzZWNvbmRzKCkgPT0gNzA4O1xuICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cblxuICAgIC8vIEludGVybmFsOiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIG5hdGl2ZSBgSlNPTi5zdHJpbmdpZnlgIGFuZCBgcGFyc2VgXG4gICAgLy8gaW1wbGVtZW50YXRpb25zIGFyZSBzcGVjLWNvbXBsaWFudC4gQmFzZWQgb24gd29yayBieSBLZW4gU255ZGVyLlxuICAgIGZ1bmN0aW9uIGhhcyhuYW1lKSB7XG4gICAgICBpZiAoaGFzW25hbWVdICE9PSB1bmRlZikge1xuICAgICAgICAvLyBSZXR1cm4gY2FjaGVkIGZlYXR1cmUgdGVzdCByZXN1bHQuXG4gICAgICAgIHJldHVybiBoYXNbbmFtZV07XG4gICAgICB9XG4gICAgICB2YXIgaXNTdXBwb3J0ZWQ7XG4gICAgICBpZiAobmFtZSA9PSBcImJ1Zy1zdHJpbmctY2hhci1pbmRleFwiKSB7XG4gICAgICAgIC8vIElFIDw9IDcgZG9lc24ndCBzdXBwb3J0IGFjY2Vzc2luZyBzdHJpbmcgY2hhcmFjdGVycyB1c2luZyBzcXVhcmVcbiAgICAgICAgLy8gYnJhY2tldCBub3RhdGlvbi4gSUUgOCBvbmx5IHN1cHBvcnRzIHRoaXMgZm9yIHByaW1pdGl2ZXMuXG4gICAgICAgIGlzU3VwcG9ydGVkID0gXCJhXCJbMF0gIT0gXCJhXCI7XG4gICAgICB9IGVsc2UgaWYgKG5hbWUgPT0gXCJqc29uXCIpIHtcbiAgICAgICAgLy8gSW5kaWNhdGVzIHdoZXRoZXIgYm90aCBgSlNPTi5zdHJpbmdpZnlgIGFuZCBgSlNPTi5wYXJzZWAgYXJlXG4gICAgICAgIC8vIHN1cHBvcnRlZC5cbiAgICAgICAgaXNTdXBwb3J0ZWQgPSBoYXMoXCJqc29uLXN0cmluZ2lmeVwiKSAmJiBoYXMoXCJqc29uLXBhcnNlXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHZhbHVlLCBzZXJpYWxpemVkID0gJ3tcImFcIjpbMSx0cnVlLGZhbHNlLG51bGwsXCJcXFxcdTAwMDBcXFxcYlxcXFxuXFxcXGZcXFxcclxcXFx0XCJdfSc7XG4gICAgICAgIC8vIFRlc3QgYEpTT04uc3RyaW5naWZ5YC5cbiAgICAgICAgaWYgKG5hbWUgPT0gXCJqc29uLXN0cmluZ2lmeVwiKSB7XG4gICAgICAgICAgdmFyIHN0cmluZ2lmeSA9IGV4cG9ydHMuc3RyaW5naWZ5LCBzdHJpbmdpZnlTdXBwb3J0ZWQgPSB0eXBlb2Ygc3RyaW5naWZ5ID09IFwiZnVuY3Rpb25cIiAmJiBpc0V4dGVuZGVkO1xuICAgICAgICAgIGlmIChzdHJpbmdpZnlTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgIC8vIEEgdGVzdCBmdW5jdGlvbiBvYmplY3Qgd2l0aCBhIGN1c3RvbSBgdG9KU09OYCBtZXRob2QuXG4gICAgICAgICAgICAodmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfSkudG9KU09OID0gdmFsdWU7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzdHJpbmdpZnlTdXBwb3J0ZWQgPVxuICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggMy4xYjEgYW5kIGIyIHNlcmlhbGl6ZSBzdHJpbmcsIG51bWJlciwgYW5kIGJvb2xlYW5cbiAgICAgICAgICAgICAgICAvLyBwcmltaXRpdmVzIGFzIG9iamVjdCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoMCkgPT09IFwiMFwiICYmXG4gICAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIGIyLCBhbmQgSlNPTiAyIHNlcmlhbGl6ZSB3cmFwcGVkIHByaW1pdGl2ZXMgYXMgb2JqZWN0XG4gICAgICAgICAgICAgICAgLy8gbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBOdW1iZXIoKSkgPT09IFwiMFwiICYmXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBTdHJpbmcoKSkgPT0gJ1wiXCInICYmXG4gICAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIDIgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHZhbHVlIGlzIGBudWxsYCwgYHVuZGVmaW5lZGAsIG9yXG4gICAgICAgICAgICAgICAgLy8gZG9lcyBub3QgZGVmaW5lIGEgY2Fub25pY2FsIEpTT04gcmVwcmVzZW50YXRpb24gKHRoaXMgYXBwbGllcyB0b1xuICAgICAgICAgICAgICAgIC8vIG9iamVjdHMgd2l0aCBgdG9KU09OYCBwcm9wZXJ0aWVzIGFzIHdlbGwsICp1bmxlc3MqIHRoZXkgYXJlIG5lc3RlZFxuICAgICAgICAgICAgICAgIC8vIHdpdGhpbiBhbiBvYmplY3Qgb3IgYXJyYXkpLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShnZXRDbGFzcykgPT09IHVuZGVmICYmXG4gICAgICAgICAgICAgICAgLy8gSUUgOCBzZXJpYWxpemVzIGB1bmRlZmluZWRgIGFzIGBcInVuZGVmaW5lZFwiYC4gU2FmYXJpIDw9IDUuMS43IGFuZFxuICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIzIHBhc3MgdGhpcyB0ZXN0LlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeSh1bmRlZikgPT09IHVuZGVmICYmXG4gICAgICAgICAgICAgICAgLy8gU2FmYXJpIDw9IDUuMS43IGFuZCBGRiAzLjFiMyB0aHJvdyBgRXJyb3JgcyBhbmQgYFR5cGVFcnJvcmBzLFxuICAgICAgICAgICAgICAgIC8vIHJlc3BlY3RpdmVseSwgaWYgdGhlIHZhbHVlIGlzIG9taXR0ZWQgZW50aXJlbHkuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KCkgPT09IHVuZGVmICYmXG4gICAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIDIgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIG5vdCBhIG51bWJlcixcbiAgICAgICAgICAgICAgICAvLyBzdHJpbmcsIGFycmF5LCBvYmplY3QsIEJvb2xlYW4sIG9yIGBudWxsYCBsaXRlcmFsLiBUaGlzIGFwcGxpZXMgdG9cbiAgICAgICAgICAgICAgICAvLyBvYmplY3RzIHdpdGggY3VzdG9tIGB0b0pTT05gIG1ldGhvZHMgYXMgd2VsbCwgdW5sZXNzIHRoZXkgYXJlIG5lc3RlZFxuICAgICAgICAgICAgICAgIC8vIGluc2lkZSBvYmplY3Qgb3IgYXJyYXkgbGl0ZXJhbHMuIFlVSSAzLjAuMGIxIGlnbm9yZXMgY3VzdG9tIGB0b0pTT05gXG4gICAgICAgICAgICAgICAgLy8gbWV0aG9kcyBlbnRpcmVseS5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkodmFsdWUpID09PSBcIjFcIiAmJlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShbdmFsdWVdKSA9PSBcIlsxXVwiICYmXG4gICAgICAgICAgICAgICAgLy8gUHJvdG90eXBlIDw9IDEuNi4xIHNlcmlhbGl6ZXMgYFt1bmRlZmluZWRdYCBhcyBgXCJbXVwiYCBpbnN0ZWFkIG9mXG4gICAgICAgICAgICAgICAgLy8gYFwiW251bGxdXCJgLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShbdW5kZWZdKSA9PSBcIltudWxsXVwiICYmXG4gICAgICAgICAgICAgICAgLy8gWVVJIDMuMC4wYjEgZmFpbHMgdG8gc2VyaWFsaXplIGBudWxsYCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobnVsbCkgPT0gXCJudWxsXCIgJiZcbiAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgMiBoYWx0cyBzZXJpYWxpemF0aW9uIGlmIGFuIGFycmF5IGNvbnRhaW5zIGEgZnVuY3Rpb246XG4gICAgICAgICAgICAgICAgLy8gYFsxLCB0cnVlLCBnZXRDbGFzcywgMV1gIHNlcmlhbGl6ZXMgYXMgXCJbMSx0cnVlLF0sXCIuIEZGIDMuMWIzXG4gICAgICAgICAgICAgICAgLy8gZWxpZGVzIG5vbi1KU09OIHZhbHVlcyBmcm9tIG9iamVjdHMgYW5kIGFycmF5cywgdW5sZXNzIHRoZXlcbiAgICAgICAgICAgICAgICAvLyBkZWZpbmUgY3VzdG9tIGB0b0pTT05gIG1ldGhvZHMuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KFt1bmRlZiwgZ2V0Q2xhc3MsIG51bGxdKSA9PSBcIltudWxsLG51bGwsbnVsbF1cIiAmJlxuICAgICAgICAgICAgICAgIC8vIFNpbXBsZSBzZXJpYWxpemF0aW9uIHRlc3QuIEZGIDMuMWIxIHVzZXMgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2VzXG4gICAgICAgICAgICAgICAgLy8gd2hlcmUgY2hhcmFjdGVyIGVzY2FwZSBjb2RlcyBhcmUgZXhwZWN0ZWQgKGUuZy4sIGBcXGJgID0+IGBcXHUwMDA4YCkuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KHsgXCJhXCI6IFt2YWx1ZSwgdHJ1ZSwgZmFsc2UsIG51bGwsIFwiXFx4MDBcXGJcXG5cXGZcXHJcXHRcIl0gfSkgPT0gc2VyaWFsaXplZCAmJlxuICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIxIGFuZCBiMiBpZ25vcmUgdGhlIGBmaWx0ZXJgIGFuZCBgd2lkdGhgIGFyZ3VtZW50cy5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobnVsbCwgdmFsdWUpID09PSBcIjFcIiAmJlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShbMSwgMl0sIG51bGwsIDEpID09IFwiW1xcbiAxLFxcbiAyXFxuXVwiICYmXG4gICAgICAgICAgICAgICAgLy8gSlNPTiAyLCBQcm90b3R5cGUgPD0gMS43LCBhbmQgb2xkZXIgV2ViS2l0IGJ1aWxkcyBpbmNvcnJlY3RseVxuICAgICAgICAgICAgICAgIC8vIHNlcmlhbGl6ZSBleHRlbmRlZCB5ZWFycy5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoLTguNjRlMTUpKSA9PSAnXCItMjcxODIxLTA0LTIwVDAwOjAwOjAwLjAwMFpcIicgJiZcbiAgICAgICAgICAgICAgICAvLyBUaGUgbWlsbGlzZWNvbmRzIGFyZSBvcHRpb25hbCBpbiBFUyA1LCBidXQgcmVxdWlyZWQgaW4gNS4xLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgRGF0ZSg4LjY0ZTE1KSkgPT0gJ1wiKzI3NTc2MC0wOS0xM1QwMDowMDowMC4wMDBaXCInICYmXG4gICAgICAgICAgICAgICAgLy8gRmlyZWZveCA8PSAxMS4wIGluY29ycmVjdGx5IHNlcmlhbGl6ZXMgeWVhcnMgcHJpb3IgdG8gMCBhcyBuZWdhdGl2ZVxuICAgICAgICAgICAgICAgIC8vIGZvdXItZGlnaXQgeWVhcnMgaW5zdGVhZCBvZiBzaXgtZGlnaXQgeWVhcnMuIENyZWRpdHM6IEBZYWZmbGUuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKC02MjE5ODc1NTJlNSkpID09ICdcIi0wMDAwMDEtMDEtMDFUMDA6MDA6MDAuMDAwWlwiJyAmJlxuICAgICAgICAgICAgICAgIC8vIFNhZmFyaSA8PSA1LjEuNSBhbmQgT3BlcmEgPj0gMTAuNTMgaW5jb3JyZWN0bHkgc2VyaWFsaXplIG1pbGxpc2Vjb25kXG4gICAgICAgICAgICAgICAgLy8gdmFsdWVzIGxlc3MgdGhhbiAxMDAwLiBDcmVkaXRzOiBAWWFmZmxlLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgRGF0ZSgtMSkpID09ICdcIjE5NjktMTItMzFUMjM6NTk6NTkuOTk5WlwiJztcbiAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICBzdHJpbmdpZnlTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaXNTdXBwb3J0ZWQgPSBzdHJpbmdpZnlTdXBwb3J0ZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGVzdCBgSlNPTi5wYXJzZWAuXG4gICAgICAgIGlmIChuYW1lID09IFwianNvbi1wYXJzZVwiKSB7XG4gICAgICAgICAgdmFyIHBhcnNlID0gZXhwb3J0cy5wYXJzZTtcbiAgICAgICAgICBpZiAodHlwZW9mIHBhcnNlID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIGIyIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGEgYmFyZSBsaXRlcmFsIGlzIHByb3ZpZGVkLlxuICAgICAgICAgICAgICAvLyBDb25mb3JtaW5nIGltcGxlbWVudGF0aW9ucyBzaG91bGQgYWxzbyBjb2VyY2UgdGhlIGluaXRpYWwgYXJndW1lbnQgdG9cbiAgICAgICAgICAgICAgLy8gYSBzdHJpbmcgcHJpb3IgdG8gcGFyc2luZy5cbiAgICAgICAgICAgICAgaWYgKHBhcnNlKFwiMFwiKSA9PT0gMCAmJiAhcGFyc2UoZmFsc2UpKSB7XG4gICAgICAgICAgICAgICAgLy8gU2ltcGxlIHBhcnNpbmcgdGVzdC5cbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhcnNlKHNlcmlhbGl6ZWQpO1xuICAgICAgICAgICAgICAgIHZhciBwYXJzZVN1cHBvcnRlZCA9IHZhbHVlW1wiYVwiXS5sZW5ndGggPT0gNSAmJiB2YWx1ZVtcImFcIl1bMF0gPT09IDE7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnNlU3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgPD0gNS4xLjIgYW5kIEZGIDMuMWIxIGFsbG93IHVuZXNjYXBlZCB0YWJzIGluIHN0cmluZ3MuXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlU3VwcG9ydGVkID0gIXBhcnNlKCdcIlxcdFwiJyk7XG4gICAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG4gICAgICAgICAgICAgICAgICBpZiAocGFyc2VTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBGRiA0LjAgYW5kIDQuMC4xIGFsbG93IGxlYWRpbmcgYCtgIHNpZ25zIGFuZCBsZWFkaW5nXG4gICAgICAgICAgICAgICAgICAgICAgLy8gZGVjaW1hbCBwb2ludHMuIEZGIDQuMCwgNC4wLjEsIGFuZCBJRSA5LTEwIGFsc28gYWxsb3dcbiAgICAgICAgICAgICAgICAgICAgICAvLyBjZXJ0YWluIG9jdGFsIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgICAgICAgIHBhcnNlU3VwcG9ydGVkID0gcGFyc2UoXCIwMVwiKSAhPT0gMTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlU3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gRkYgNC4wLCA0LjAuMSwgYW5kIFJoaW5vIDEuN1IzLVI0IGFsbG93IHRyYWlsaW5nIGRlY2ltYWxcbiAgICAgICAgICAgICAgICAgICAgICAvLyBwb2ludHMuIFRoZXNlIGVudmlyb25tZW50cywgYWxvbmcgd2l0aCBGRiAzLjFiMSBhbmQgMixcbiAgICAgICAgICAgICAgICAgICAgICAvLyBhbHNvIGFsbG93IHRyYWlsaW5nIGNvbW1hcyBpbiBKU09OIG9iamVjdHMgYW5kIGFycmF5cy5cbiAgICAgICAgICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9IHBhcnNlKFwiMS5cIikgIT09IDE7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpc1N1cHBvcnRlZCA9IHBhcnNlU3VwcG9ydGVkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaGFzW25hbWVdID0gISFpc1N1cHBvcnRlZDtcbiAgICB9XG5cbiAgICBpZiAoIWhhcyhcImpzb25cIikpIHtcbiAgICAgIC8vIENvbW1vbiBgW1tDbGFzc11dYCBuYW1lIGFsaWFzZXMuXG4gICAgICB2YXIgZnVuY3Rpb25DbGFzcyA9IFwiW29iamVjdCBGdW5jdGlvbl1cIixcbiAgICAgICAgICBkYXRlQ2xhc3MgPSBcIltvYmplY3QgRGF0ZV1cIixcbiAgICAgICAgICBudW1iZXJDbGFzcyA9IFwiW29iamVjdCBOdW1iZXJdXCIsXG4gICAgICAgICAgc3RyaW5nQ2xhc3MgPSBcIltvYmplY3QgU3RyaW5nXVwiLFxuICAgICAgICAgIGFycmF5Q2xhc3MgPSBcIltvYmplY3QgQXJyYXldXCIsXG4gICAgICAgICAgYm9vbGVhbkNsYXNzID0gXCJbb2JqZWN0IEJvb2xlYW5dXCI7XG5cbiAgICAgIC8vIERldGVjdCBpbmNvbXBsZXRlIHN1cHBvcnQgZm9yIGFjY2Vzc2luZyBzdHJpbmcgY2hhcmFjdGVycyBieSBpbmRleC5cbiAgICAgIHZhciBjaGFySW5kZXhCdWdneSA9IGhhcyhcImJ1Zy1zdHJpbmctY2hhci1pbmRleFwiKTtcblxuICAgICAgLy8gRGVmaW5lIGFkZGl0aW9uYWwgdXRpbGl0eSBtZXRob2RzIGlmIHRoZSBgRGF0ZWAgbWV0aG9kcyBhcmUgYnVnZ3kuXG4gICAgICBpZiAoIWlzRXh0ZW5kZWQpIHtcbiAgICAgICAgdmFyIGZsb29yID0gTWF0aC5mbG9vcjtcbiAgICAgICAgLy8gQSBtYXBwaW5nIGJldHdlZW4gdGhlIG1vbnRocyBvZiB0aGUgeWVhciBhbmQgdGhlIG51bWJlciBvZiBkYXlzIGJldHdlZW5cbiAgICAgICAgLy8gSmFudWFyeSAxc3QgYW5kIHRoZSBmaXJzdCBvZiB0aGUgcmVzcGVjdGl2ZSBtb250aC5cbiAgICAgICAgdmFyIE1vbnRocyA9IFswLCAzMSwgNTksIDkwLCAxMjAsIDE1MSwgMTgxLCAyMTIsIDI0MywgMjczLCAzMDQsIDMzNF07XG4gICAgICAgIC8vIEludGVybmFsOiBDYWxjdWxhdGVzIHRoZSBudW1iZXIgb2YgZGF5cyBiZXR3ZWVuIHRoZSBVbml4IGVwb2NoIGFuZCB0aGVcbiAgICAgICAgLy8gZmlyc3QgZGF5IG9mIHRoZSBnaXZlbiBtb250aC5cbiAgICAgICAgdmFyIGdldERheSA9IGZ1bmN0aW9uICh5ZWFyLCBtb250aCkge1xuICAgICAgICAgIHJldHVybiBNb250aHNbbW9udGhdICsgMzY1ICogKHllYXIgLSAxOTcwKSArIGZsb29yKCh5ZWFyIC0gMTk2OSArIChtb250aCA9ICsobW9udGggPiAxKSkpIC8gNCkgLSBmbG9vcigoeWVhciAtIDE5MDEgKyBtb250aCkgLyAxMDApICsgZmxvb3IoKHllYXIgLSAxNjAxICsgbW9udGgpIC8gNDAwKTtcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgLy8gSW50ZXJuYWw6IERldGVybWluZXMgaWYgYSBwcm9wZXJ0eSBpcyBhIGRpcmVjdCBwcm9wZXJ0eSBvZiB0aGUgZ2l2ZW5cbiAgICAgIC8vIG9iamVjdC4gRGVsZWdhdGVzIHRvIHRoZSBuYXRpdmUgYE9iamVjdCNoYXNPd25Qcm9wZXJ0eWAgbWV0aG9kLlxuICAgICAgaWYgKCEoaXNQcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5KSkge1xuICAgICAgICBpc1Byb3BlcnR5ID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgdmFyIG1lbWJlcnMgPSB7fSwgY29uc3RydWN0b3I7XG4gICAgICAgICAgaWYgKChtZW1iZXJzLl9fcHJvdG9fXyA9IG51bGwsIG1lbWJlcnMuX19wcm90b19fID0ge1xuICAgICAgICAgICAgLy8gVGhlICpwcm90byogcHJvcGVydHkgY2Fubm90IGJlIHNldCBtdWx0aXBsZSB0aW1lcyBpbiByZWNlbnRcbiAgICAgICAgICAgIC8vIHZlcnNpb25zIG9mIEZpcmVmb3ggYW5kIFNlYU1vbmtleS5cbiAgICAgICAgICAgIFwidG9TdHJpbmdcIjogMVxuICAgICAgICAgIH0sIG1lbWJlcnMpLnRvU3RyaW5nICE9IGdldENsYXNzKSB7XG4gICAgICAgICAgICAvLyBTYWZhcmkgPD0gMi4wLjMgZG9lc24ndCBpbXBsZW1lbnQgYE9iamVjdCNoYXNPd25Qcm9wZXJ0eWAsIGJ1dFxuICAgICAgICAgICAgLy8gc3VwcG9ydHMgdGhlIG11dGFibGUgKnByb3RvKiBwcm9wZXJ0eS5cbiAgICAgICAgICAgIGlzUHJvcGVydHkgPSBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgLy8gQ2FwdHVyZSBhbmQgYnJlYWsgdGhlIG9iamVjdGdzIHByb3RvdHlwZSBjaGFpbiAoc2VlIHNlY3Rpb24gOC42LjJcbiAgICAgICAgICAgICAgLy8gb2YgdGhlIEVTIDUuMSBzcGVjKS4gVGhlIHBhcmVudGhlc2l6ZWQgZXhwcmVzc2lvbiBwcmV2ZW50cyBhblxuICAgICAgICAgICAgICAvLyB1bnNhZmUgdHJhbnNmb3JtYXRpb24gYnkgdGhlIENsb3N1cmUgQ29tcGlsZXIuXG4gICAgICAgICAgICAgIHZhciBvcmlnaW5hbCA9IHRoaXMuX19wcm90b19fLCByZXN1bHQgPSBwcm9wZXJ0eSBpbiAodGhpcy5fX3Byb3RvX18gPSBudWxsLCB0aGlzKTtcbiAgICAgICAgICAgICAgLy8gUmVzdG9yZSB0aGUgb3JpZ2luYWwgcHJvdG90eXBlIGNoYWluLlxuICAgICAgICAgICAgICB0aGlzLl9fcHJvdG9fXyA9IG9yaWdpbmFsO1xuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ2FwdHVyZSBhIHJlZmVyZW5jZSB0byB0aGUgdG9wLWxldmVsIGBPYmplY3RgIGNvbnN0cnVjdG9yLlxuICAgICAgICAgICAgY29uc3RydWN0b3IgPSBtZW1iZXJzLmNvbnN0cnVjdG9yO1xuICAgICAgICAgICAgLy8gVXNlIHRoZSBgY29uc3RydWN0b3JgIHByb3BlcnR5IHRvIHNpbXVsYXRlIGBPYmplY3QjaGFzT3duUHJvcGVydHlgIGluXG4gICAgICAgICAgICAvLyBvdGhlciBlbnZpcm9ubWVudHMuXG4gICAgICAgICAgICBpc1Byb3BlcnR5ID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgIHZhciBwYXJlbnQgPSAodGhpcy5jb25zdHJ1Y3RvciB8fCBjb25zdHJ1Y3RvcikucHJvdG90eXBlO1xuICAgICAgICAgICAgICByZXR1cm4gcHJvcGVydHkgaW4gdGhpcyAmJiAhKHByb3BlcnR5IGluIHBhcmVudCAmJiB0aGlzW3Byb3BlcnR5XSA9PT0gcGFyZW50W3Byb3BlcnR5XSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBtZW1iZXJzID0gbnVsbDtcbiAgICAgICAgICByZXR1cm4gaXNQcm9wZXJ0eS5jYWxsKHRoaXMsIHByb3BlcnR5KTtcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgLy8gSW50ZXJuYWw6IEEgc2V0IG9mIHByaW1pdGl2ZSB0eXBlcyB1c2VkIGJ5IGBpc0hvc3RUeXBlYC5cbiAgICAgIHZhciBQcmltaXRpdmVUeXBlcyA9IHtcbiAgICAgICAgXCJib29sZWFuXCI6IDEsXG4gICAgICAgIFwibnVtYmVyXCI6IDEsXG4gICAgICAgIFwic3RyaW5nXCI6IDEsXG4gICAgICAgIFwidW5kZWZpbmVkXCI6IDFcbiAgICAgIH07XG5cbiAgICAgIC8vIEludGVybmFsOiBEZXRlcm1pbmVzIGlmIHRoZSBnaXZlbiBvYmplY3QgYHByb3BlcnR5YCB2YWx1ZSBpcyBhXG4gICAgICAvLyBub24tcHJpbWl0aXZlLlxuICAgICAgdmFyIGlzSG9zdFR5cGUgPSBmdW5jdGlvbiAob2JqZWN0LCBwcm9wZXJ0eSkge1xuICAgICAgICB2YXIgdHlwZSA9IHR5cGVvZiBvYmplY3RbcHJvcGVydHldO1xuICAgICAgICByZXR1cm4gdHlwZSA9PSBcIm9iamVjdFwiID8gISFvYmplY3RbcHJvcGVydHldIDogIVByaW1pdGl2ZVR5cGVzW3R5cGVdO1xuICAgICAgfTtcblxuICAgICAgLy8gSW50ZXJuYWw6IE5vcm1hbGl6ZXMgdGhlIGBmb3IuLi5pbmAgaXRlcmF0aW9uIGFsZ29yaXRobSBhY3Jvc3NcbiAgICAgIC8vIGVudmlyb25tZW50cy4gRWFjaCBlbnVtZXJhdGVkIGtleSBpcyB5aWVsZGVkIHRvIGEgYGNhbGxiYWNrYCBmdW5jdGlvbi5cbiAgICAgIGZvckVhY2ggPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgc2l6ZSA9IDAsIFByb3BlcnRpZXMsIG1lbWJlcnMsIHByb3BlcnR5O1xuXG4gICAgICAgIC8vIFRlc3RzIGZvciBidWdzIGluIHRoZSBjdXJyZW50IGVudmlyb25tZW50J3MgYGZvci4uLmluYCBhbGdvcml0aG0uIFRoZVxuICAgICAgICAvLyBgdmFsdWVPZmAgcHJvcGVydHkgaW5oZXJpdHMgdGhlIG5vbi1lbnVtZXJhYmxlIGZsYWcgZnJvbVxuICAgICAgICAvLyBgT2JqZWN0LnByb3RvdHlwZWAgaW4gb2xkZXIgdmVyc2lvbnMgb2YgSUUsIE5ldHNjYXBlLCBhbmQgTW96aWxsYS5cbiAgICAgICAgKFByb3BlcnRpZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdGhpcy52YWx1ZU9mID0gMDtcbiAgICAgICAgfSkucHJvdG90eXBlLnZhbHVlT2YgPSAwO1xuXG4gICAgICAgIC8vIEl0ZXJhdGUgb3ZlciBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgYFByb3BlcnRpZXNgIGNsYXNzLlxuICAgICAgICBtZW1iZXJzID0gbmV3IFByb3BlcnRpZXMoKTtcbiAgICAgICAgZm9yIChwcm9wZXJ0eSBpbiBtZW1iZXJzKSB7XG4gICAgICAgICAgLy8gSWdub3JlIGFsbCBwcm9wZXJ0aWVzIGluaGVyaXRlZCBmcm9tIGBPYmplY3QucHJvdG90eXBlYC5cbiAgICAgICAgICBpZiAoaXNQcm9wZXJ0eS5jYWxsKG1lbWJlcnMsIHByb3BlcnR5KSkge1xuICAgICAgICAgICAgc2l6ZSsrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBQcm9wZXJ0aWVzID0gbWVtYmVycyA9IG51bGw7XG5cbiAgICAgICAgLy8gTm9ybWFsaXplIHRoZSBpdGVyYXRpb24gYWxnb3JpdGhtLlxuICAgICAgICBpZiAoIXNpemUpIHtcbiAgICAgICAgICAvLyBBIGxpc3Qgb2Ygbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyBpbmhlcml0ZWQgZnJvbSBgT2JqZWN0LnByb3RvdHlwZWAuXG4gICAgICAgICAgbWVtYmVycyA9IFtcInZhbHVlT2ZcIiwgXCJ0b1N0cmluZ1wiLCBcInRvTG9jYWxlU3RyaW5nXCIsIFwicHJvcGVydHlJc0VudW1lcmFibGVcIiwgXCJpc1Byb3RvdHlwZU9mXCIsIFwiaGFzT3duUHJvcGVydHlcIiwgXCJjb25zdHJ1Y3RvclwiXTtcbiAgICAgICAgICAvLyBJRSA8PSA4LCBNb3ppbGxhIDEuMCwgYW5kIE5ldHNjYXBlIDYuMiBpZ25vcmUgc2hhZG93ZWQgbm9uLWVudW1lcmFibGVcbiAgICAgICAgICAvLyBwcm9wZXJ0aWVzLlxuICAgICAgICAgIGZvckVhY2ggPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgdmFyIGlzRnVuY3Rpb24gPSBnZXRDbGFzcy5jYWxsKG9iamVjdCkgPT0gZnVuY3Rpb25DbGFzcywgcHJvcGVydHksIGxlbmd0aDtcbiAgICAgICAgICAgIHZhciBoYXNQcm9wZXJ0eSA9ICFpc0Z1bmN0aW9uICYmIHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IgIT0gXCJmdW5jdGlvblwiICYmIGlzSG9zdFR5cGUob2JqZWN0LCBcImhhc093blByb3BlcnR5XCIpID8gb2JqZWN0Lmhhc093blByb3BlcnR5IDogaXNQcm9wZXJ0eTtcbiAgICAgICAgICAgIGZvciAocHJvcGVydHkgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgICAgIC8vIEdlY2tvIDw9IDEuMCBlbnVtZXJhdGVzIHRoZSBgcHJvdG90eXBlYCBwcm9wZXJ0eSBvZiBmdW5jdGlvbnMgdW5kZXJcbiAgICAgICAgICAgICAgLy8gY2VydGFpbiBjb25kaXRpb25zOyBJRSBkb2VzIG5vdC5cbiAgICAgICAgICAgICAgaWYgKCEoaXNGdW5jdGlvbiAmJiBwcm9wZXJ0eSA9PSBcInByb3RvdHlwZVwiKSAmJiBoYXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2socHJvcGVydHkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBNYW51YWxseSBpbnZva2UgdGhlIGNhbGxiYWNrIGZvciBlYWNoIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5LlxuICAgICAgICAgICAgZm9yIChsZW5ndGggPSBtZW1iZXJzLmxlbmd0aDsgcHJvcGVydHkgPSBtZW1iZXJzWy0tbGVuZ3RoXTsgaGFzUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSAmJiBjYWxsYmFjayhwcm9wZXJ0eSkpO1xuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAoc2l6ZSA9PSAyKSB7XG4gICAgICAgICAgLy8gU2FmYXJpIDw9IDIuMC40IGVudW1lcmF0ZXMgc2hhZG93ZWQgcHJvcGVydGllcyB0d2ljZS5cbiAgICAgICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIC8vIENyZWF0ZSBhIHNldCBvZiBpdGVyYXRlZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgICAgdmFyIG1lbWJlcnMgPSB7fSwgaXNGdW5jdGlvbiA9IGdldENsYXNzLmNhbGwob2JqZWN0KSA9PSBmdW5jdGlvbkNsYXNzLCBwcm9wZXJ0eTtcbiAgICAgICAgICAgIGZvciAocHJvcGVydHkgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgICAgIC8vIFN0b3JlIGVhY2ggcHJvcGVydHkgbmFtZSB0byBwcmV2ZW50IGRvdWJsZSBlbnVtZXJhdGlvbi4gVGhlXG4gICAgICAgICAgICAgIC8vIGBwcm90b3R5cGVgIHByb3BlcnR5IG9mIGZ1bmN0aW9ucyBpcyBub3QgZW51bWVyYXRlZCBkdWUgdG8gY3Jvc3MtXG4gICAgICAgICAgICAgIC8vIGVudmlyb25tZW50IGluY29uc2lzdGVuY2llcy5cbiAgICAgICAgICAgICAgaWYgKCEoaXNGdW5jdGlvbiAmJiBwcm9wZXJ0eSA9PSBcInByb3RvdHlwZVwiKSAmJiAhaXNQcm9wZXJ0eS5jYWxsKG1lbWJlcnMsIHByb3BlcnR5KSAmJiAobWVtYmVyc1twcm9wZXJ0eV0gPSAxKSAmJiBpc1Byb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSkpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhwcm9wZXJ0eSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE5vIGJ1Z3MgZGV0ZWN0ZWQ7IHVzZSB0aGUgc3RhbmRhcmQgYGZvci4uLmluYCBhbGdvcml0aG0uXG4gICAgICAgICAgZm9yRWFjaCA9IGZ1bmN0aW9uIChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICB2YXIgaXNGdW5jdGlvbiA9IGdldENsYXNzLmNhbGwob2JqZWN0KSA9PSBmdW5jdGlvbkNsYXNzLCBwcm9wZXJ0eSwgaXNDb25zdHJ1Y3RvcjtcbiAgICAgICAgICAgIGZvciAocHJvcGVydHkgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgICAgIGlmICghKGlzRnVuY3Rpb24gJiYgcHJvcGVydHkgPT0gXCJwcm90b3R5cGVcIikgJiYgaXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpICYmICEoaXNDb25zdHJ1Y3RvciA9IHByb3BlcnR5ID09PSBcImNvbnN0cnVjdG9yXCIpKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2socHJvcGVydHkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBNYW51YWxseSBpbnZva2UgdGhlIGNhbGxiYWNrIGZvciB0aGUgYGNvbnN0cnVjdG9yYCBwcm9wZXJ0eSBkdWUgdG9cbiAgICAgICAgICAgIC8vIGNyb3NzLWVudmlyb25tZW50IGluY29uc2lzdGVuY2llcy5cbiAgICAgICAgICAgIGlmIChpc0NvbnN0cnVjdG9yIHx8IGlzUHJvcGVydHkuY2FsbChvYmplY3QsIChwcm9wZXJ0eSA9IFwiY29uc3RydWN0b3JcIikpKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmb3JFYWNoKG9iamVjdCwgY2FsbGJhY2spO1xuICAgICAgfTtcblxuICAgICAgLy8gUHVibGljOiBTZXJpYWxpemVzIGEgSmF2YVNjcmlwdCBgdmFsdWVgIGFzIGEgSlNPTiBzdHJpbmcuIFRoZSBvcHRpb25hbFxuICAgICAgLy8gYGZpbHRlcmAgYXJndW1lbnQgbWF5IHNwZWNpZnkgZWl0aGVyIGEgZnVuY3Rpb24gdGhhdCBhbHRlcnMgaG93IG9iamVjdCBhbmRcbiAgICAgIC8vIGFycmF5IG1lbWJlcnMgYXJlIHNlcmlhbGl6ZWQsIG9yIGFuIGFycmF5IG9mIHN0cmluZ3MgYW5kIG51bWJlcnMgdGhhdFxuICAgICAgLy8gaW5kaWNhdGVzIHdoaWNoIHByb3BlcnRpZXMgc2hvdWxkIGJlIHNlcmlhbGl6ZWQuIFRoZSBvcHRpb25hbCBgd2lkdGhgXG4gICAgICAvLyBhcmd1bWVudCBtYXkgYmUgZWl0aGVyIGEgc3RyaW5nIG9yIG51bWJlciB0aGF0IHNwZWNpZmllcyB0aGUgaW5kZW50YXRpb25cbiAgICAgIC8vIGxldmVsIG9mIHRoZSBvdXRwdXQuXG4gICAgICBpZiAoIWhhcyhcImpzb24tc3RyaW5naWZ5XCIpKSB7XG4gICAgICAgIC8vIEludGVybmFsOiBBIG1hcCBvZiBjb250cm9sIGNoYXJhY3RlcnMgYW5kIHRoZWlyIGVzY2FwZWQgZXF1aXZhbGVudHMuXG4gICAgICAgIHZhciBFc2NhcGVzID0ge1xuICAgICAgICAgIDkyOiBcIlxcXFxcXFxcXCIsXG4gICAgICAgICAgMzQ6ICdcXFxcXCInLFxuICAgICAgICAgIDg6IFwiXFxcXGJcIixcbiAgICAgICAgICAxMjogXCJcXFxcZlwiLFxuICAgICAgICAgIDEwOiBcIlxcXFxuXCIsXG4gICAgICAgICAgMTM6IFwiXFxcXHJcIixcbiAgICAgICAgICA5OiBcIlxcXFx0XCJcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogQ29udmVydHMgYHZhbHVlYCBpbnRvIGEgemVyby1wYWRkZWQgc3RyaW5nIHN1Y2ggdGhhdCBpdHNcbiAgICAgICAgLy8gbGVuZ3RoIGlzIGF0IGxlYXN0IGVxdWFsIHRvIGB3aWR0aGAuIFRoZSBgd2lkdGhgIG11c3QgYmUgPD0gNi5cbiAgICAgICAgdmFyIGxlYWRpbmdaZXJvZXMgPSBcIjAwMDAwMFwiO1xuICAgICAgICB2YXIgdG9QYWRkZWRTdHJpbmcgPSBmdW5jdGlvbiAod2lkdGgsIHZhbHVlKSB7XG4gICAgICAgICAgLy8gVGhlIGB8fCAwYCBleHByZXNzaW9uIGlzIG5lY2Vzc2FyeSB0byB3b3JrIGFyb3VuZCBhIGJ1ZyBpblxuICAgICAgICAgIC8vIE9wZXJhIDw9IDcuNTR1MiB3aGVyZSBgMCA9PSAtMGAsIGJ1dCBgU3RyaW5nKC0wKSAhPT0gXCIwXCJgLlxuICAgICAgICAgIHJldHVybiAobGVhZGluZ1plcm9lcyArICh2YWx1ZSB8fCAwKSkuc2xpY2UoLXdpZHRoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogRG91YmxlLXF1b3RlcyBhIHN0cmluZyBgdmFsdWVgLCByZXBsYWNpbmcgYWxsIEFTQ0lJIGNvbnRyb2xcbiAgICAgICAgLy8gY2hhcmFjdGVycyAoY2hhcmFjdGVycyB3aXRoIGNvZGUgdW5pdCB2YWx1ZXMgYmV0d2VlbiAwIGFuZCAzMSkgd2l0aFxuICAgICAgICAvLyB0aGVpciBlc2NhcGVkIGVxdWl2YWxlbnRzLiBUaGlzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZVxuICAgICAgICAvLyBgUXVvdGUodmFsdWUpYCBvcGVyYXRpb24gZGVmaW5lZCBpbiBFUyA1LjEgc2VjdGlvbiAxNS4xMi4zLlxuICAgICAgICB2YXIgdW5pY29kZVByZWZpeCA9IFwiXFxcXHUwMFwiO1xuICAgICAgICB2YXIgcXVvdGUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICB2YXIgcmVzdWx0ID0gJ1wiJywgaW5kZXggPSAwLCBsZW5ndGggPSB2YWx1ZS5sZW5ndGgsIHVzZUNoYXJJbmRleCA9ICFjaGFySW5kZXhCdWdneSB8fCBsZW5ndGggPiAxMDtcbiAgICAgICAgICB2YXIgc3ltYm9scyA9IHVzZUNoYXJJbmRleCAmJiAoY2hhckluZGV4QnVnZ3kgPyB2YWx1ZS5zcGxpdChcIlwiKSA6IHZhbHVlKTtcbiAgICAgICAgICBmb3IgKDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgIHZhciBjaGFyQ29kZSA9IHZhbHVlLmNoYXJDb2RlQXQoaW5kZXgpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGNoYXJhY3RlciBpcyBhIGNvbnRyb2wgY2hhcmFjdGVyLCBhcHBlbmQgaXRzIFVuaWNvZGUgb3JcbiAgICAgICAgICAgIC8vIHNob3J0aGFuZCBlc2NhcGUgc2VxdWVuY2U7IG90aGVyd2lzZSwgYXBwZW5kIHRoZSBjaGFyYWN0ZXIgYXMtaXMuXG4gICAgICAgICAgICBzd2l0Y2ggKGNoYXJDb2RlKSB7XG4gICAgICAgICAgICAgIGNhc2UgODogY2FzZSA5OiBjYXNlIDEwOiBjYXNlIDEyOiBjYXNlIDEzOiBjYXNlIDM0OiBjYXNlIDkyOlxuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBFc2NhcGVzW2NoYXJDb2RlXTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPCAzMikge1xuICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IHVuaWNvZGVQcmVmaXggKyB0b1BhZGRlZFN0cmluZygyLCBjaGFyQ29kZS50b1N0cmluZygxNikpO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc3VsdCArPSB1c2VDaGFySW5kZXggPyBzeW1ib2xzW2luZGV4XSA6IHZhbHVlLmNoYXJBdChpbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByZXN1bHQgKyAnXCInO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBSZWN1cnNpdmVseSBzZXJpYWxpemVzIGFuIG9iamVjdC4gSW1wbGVtZW50cyB0aGVcbiAgICAgICAgLy8gYFN0cihrZXksIGhvbGRlcilgLCBgSk8odmFsdWUpYCwgYW5kIGBKQSh2YWx1ZSlgIG9wZXJhdGlvbnMuXG4gICAgICAgIHZhciBzZXJpYWxpemUgPSBmdW5jdGlvbiAocHJvcGVydHksIG9iamVjdCwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIHdoaXRlc3BhY2UsIGluZGVudGF0aW9uLCBzdGFjaykge1xuICAgICAgICAgIHZhciB2YWx1ZSwgY2xhc3NOYW1lLCB5ZWFyLCBtb250aCwgZGF0ZSwgdGltZSwgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMsIG1pbGxpc2Vjb25kcywgcmVzdWx0cywgZWxlbWVudCwgaW5kZXgsIGxlbmd0aCwgcHJlZml4LCByZXN1bHQ7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIE5lY2Vzc2FyeSBmb3IgaG9zdCBvYmplY3Qgc3VwcG9ydC5cbiAgICAgICAgICAgIHZhbHVlID0gb2JqZWN0W3Byb3BlcnR5XTtcbiAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiICYmIHZhbHVlKSB7XG4gICAgICAgICAgICBjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKHZhbHVlKTtcbiAgICAgICAgICAgIGlmIChjbGFzc05hbWUgPT0gZGF0ZUNsYXNzICYmICFpc1Byb3BlcnR5LmNhbGwodmFsdWUsIFwidG9KU09OXCIpKSB7XG4gICAgICAgICAgICAgIGlmICh2YWx1ZSA+IC0xIC8gMCAmJiB2YWx1ZSA8IDEgLyAwKSB7XG4gICAgICAgICAgICAgICAgLy8gRGF0ZXMgYXJlIHNlcmlhbGl6ZWQgYWNjb3JkaW5nIHRvIHRoZSBgRGF0ZSN0b0pTT05gIG1ldGhvZFxuICAgICAgICAgICAgICAgIC8vIHNwZWNpZmllZCBpbiBFUyA1LjEgc2VjdGlvbiAxNS45LjUuNDQuIFNlZSBzZWN0aW9uIDE1LjkuMS4xNVxuICAgICAgICAgICAgICAgIC8vIGZvciB0aGUgSVNPIDg2MDEgZGF0ZSB0aW1lIHN0cmluZyBmb3JtYXQuXG4gICAgICAgICAgICAgICAgaWYgKGdldERheSkge1xuICAgICAgICAgICAgICAgICAgLy8gTWFudWFsbHkgY29tcHV0ZSB0aGUgeWVhciwgbW9udGgsIGRhdGUsIGhvdXJzLCBtaW51dGVzLFxuICAgICAgICAgICAgICAgICAgLy8gc2Vjb25kcywgYW5kIG1pbGxpc2Vjb25kcyBpZiB0aGUgYGdldFVUQypgIG1ldGhvZHMgYXJlXG4gICAgICAgICAgICAgICAgICAvLyBidWdneS4gQWRhcHRlZCBmcm9tIEBZYWZmbGUncyBgZGF0ZS1zaGltYCBwcm9qZWN0LlxuICAgICAgICAgICAgICAgICAgZGF0ZSA9IGZsb29yKHZhbHVlIC8gODY0ZTUpO1xuICAgICAgICAgICAgICAgICAgZm9yICh5ZWFyID0gZmxvb3IoZGF0ZSAvIDM2NS4yNDI1KSArIDE5NzAgLSAxOyBnZXREYXkoeWVhciArIDEsIDApIDw9IGRhdGU7IHllYXIrKyk7XG4gICAgICAgICAgICAgICAgICBmb3IgKG1vbnRoID0gZmxvb3IoKGRhdGUgLSBnZXREYXkoeWVhciwgMCkpIC8gMzAuNDIpOyBnZXREYXkoeWVhciwgbW9udGggKyAxKSA8PSBkYXRlOyBtb250aCsrKTtcbiAgICAgICAgICAgICAgICAgIGRhdGUgPSAxICsgZGF0ZSAtIGdldERheSh5ZWFyLCBtb250aCk7XG4gICAgICAgICAgICAgICAgICAvLyBUaGUgYHRpbWVgIHZhbHVlIHNwZWNpZmllcyB0aGUgdGltZSB3aXRoaW4gdGhlIGRheSAoc2VlIEVTXG4gICAgICAgICAgICAgICAgICAvLyA1LjEgc2VjdGlvbiAxNS45LjEuMikuIFRoZSBmb3JtdWxhIGAoQSAlIEIgKyBCKSAlIEJgIGlzIHVzZWRcbiAgICAgICAgICAgICAgICAgIC8vIHRvIGNvbXB1dGUgYEEgbW9kdWxvIEJgLCBhcyB0aGUgYCVgIG9wZXJhdG9yIGRvZXMgbm90XG4gICAgICAgICAgICAgICAgICAvLyBjb3JyZXNwb25kIHRvIHRoZSBgbW9kdWxvYCBvcGVyYXRpb24gZm9yIG5lZ2F0aXZlIG51bWJlcnMuXG4gICAgICAgICAgICAgICAgICB0aW1lID0gKHZhbHVlICUgODY0ZTUgKyA4NjRlNSkgJSA4NjRlNTtcbiAgICAgICAgICAgICAgICAgIC8vIFRoZSBob3VycywgbWludXRlcywgc2Vjb25kcywgYW5kIG1pbGxpc2Vjb25kcyBhcmUgb2J0YWluZWQgYnlcbiAgICAgICAgICAgICAgICAgIC8vIGRlY29tcG9zaW5nIHRoZSB0aW1lIHdpdGhpbiB0aGUgZGF5LiBTZWUgc2VjdGlvbiAxNS45LjEuMTAuXG4gICAgICAgICAgICAgICAgICBob3VycyA9IGZsb29yKHRpbWUgLyAzNmU1KSAlIDI0O1xuICAgICAgICAgICAgICAgICAgbWludXRlcyA9IGZsb29yKHRpbWUgLyA2ZTQpICUgNjA7XG4gICAgICAgICAgICAgICAgICBzZWNvbmRzID0gZmxvb3IodGltZSAvIDFlMykgJSA2MDtcbiAgICAgICAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IHRpbWUgJSAxZTM7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHllYXIgPSB2YWx1ZS5nZXRVVENGdWxsWWVhcigpO1xuICAgICAgICAgICAgICAgICAgbW9udGggPSB2YWx1ZS5nZXRVVENNb250aCgpO1xuICAgICAgICAgICAgICAgICAgZGF0ZSA9IHZhbHVlLmdldFVUQ0RhdGUoKTtcbiAgICAgICAgICAgICAgICAgIGhvdXJzID0gdmFsdWUuZ2V0VVRDSG91cnMoKTtcbiAgICAgICAgICAgICAgICAgIG1pbnV0ZXMgPSB2YWx1ZS5nZXRVVENNaW51dGVzKCk7XG4gICAgICAgICAgICAgICAgICBzZWNvbmRzID0gdmFsdWUuZ2V0VVRDU2Vjb25kcygpO1xuICAgICAgICAgICAgICAgICAgbWlsbGlzZWNvbmRzID0gdmFsdWUuZ2V0VVRDTWlsbGlzZWNvbmRzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFNlcmlhbGl6ZSBleHRlbmRlZCB5ZWFycyBjb3JyZWN0bHkuXG4gICAgICAgICAgICAgICAgdmFsdWUgPSAoeWVhciA8PSAwIHx8IHllYXIgPj0gMWU0ID8gKHllYXIgPCAwID8gXCItXCIgOiBcIitcIikgKyB0b1BhZGRlZFN0cmluZyg2LCB5ZWFyIDwgMCA/IC15ZWFyIDogeWVhcikgOiB0b1BhZGRlZFN0cmluZyg0LCB5ZWFyKSkgK1xuICAgICAgICAgICAgICAgICAgXCItXCIgKyB0b1BhZGRlZFN0cmluZygyLCBtb250aCArIDEpICsgXCItXCIgKyB0b1BhZGRlZFN0cmluZygyLCBkYXRlKSArXG4gICAgICAgICAgICAgICAgICAvLyBNb250aHMsIGRhdGVzLCBob3VycywgbWludXRlcywgYW5kIHNlY29uZHMgc2hvdWxkIGhhdmUgdHdvXG4gICAgICAgICAgICAgICAgICAvLyBkaWdpdHM7IG1pbGxpc2Vjb25kcyBzaG91bGQgaGF2ZSB0aHJlZS5cbiAgICAgICAgICAgICAgICAgIFwiVFwiICsgdG9QYWRkZWRTdHJpbmcoMiwgaG91cnMpICsgXCI6XCIgKyB0b1BhZGRlZFN0cmluZygyLCBtaW51dGVzKSArIFwiOlwiICsgdG9QYWRkZWRTdHJpbmcoMiwgc2Vjb25kcykgK1xuICAgICAgICAgICAgICAgICAgLy8gTWlsbGlzZWNvbmRzIGFyZSBvcHRpb25hbCBpbiBFUyA1LjAsIGJ1dCByZXF1aXJlZCBpbiA1LjEuXG4gICAgICAgICAgICAgICAgICBcIi5cIiArIHRvUGFkZGVkU3RyaW5nKDMsIG1pbGxpc2Vjb25kcykgKyBcIlpcIjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlLnRvSlNPTiA9PSBcImZ1bmN0aW9uXCIgJiYgKChjbGFzc05hbWUgIT0gbnVtYmVyQ2xhc3MgJiYgY2xhc3NOYW1lICE9IHN0cmluZ0NsYXNzICYmIGNsYXNzTmFtZSAhPSBhcnJheUNsYXNzKSB8fCBpc1Byb3BlcnR5LmNhbGwodmFsdWUsIFwidG9KU09OXCIpKSkge1xuICAgICAgICAgICAgICAvLyBQcm90b3R5cGUgPD0gMS42LjEgYWRkcyBub24tc3RhbmRhcmQgYHRvSlNPTmAgbWV0aG9kcyB0byB0aGVcbiAgICAgICAgICAgICAgLy8gYE51bWJlcmAsIGBTdHJpbmdgLCBgRGF0ZWAsIGFuZCBgQXJyYXlgIHByb3RvdHlwZXMuIEpTT04gM1xuICAgICAgICAgICAgICAvLyBpZ25vcmVzIGFsbCBgdG9KU09OYCBtZXRob2RzIG9uIHRoZXNlIG9iamVjdHMgdW5sZXNzIHRoZXkgYXJlXG4gICAgICAgICAgICAgIC8vIGRlZmluZWQgZGlyZWN0bHkgb24gYW4gaW5zdGFuY2UuXG4gICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUudG9KU09OKHByb3BlcnR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAvLyBJZiBhIHJlcGxhY2VtZW50IGZ1bmN0aW9uIHdhcyBwcm92aWRlZCwgY2FsbCBpdCB0byBvYnRhaW4gdGhlIHZhbHVlXG4gICAgICAgICAgICAvLyBmb3Igc2VyaWFsaXphdGlvbi5cbiAgICAgICAgICAgIHZhbHVlID0gY2FsbGJhY2suY2FsbChvYmplY3QsIHByb3BlcnR5LCB2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKHZhbHVlKTtcbiAgICAgICAgICBpZiAoY2xhc3NOYW1lID09IGJvb2xlYW5DbGFzcykge1xuICAgICAgICAgICAgLy8gQm9vbGVhbnMgYXJlIHJlcHJlc2VudGVkIGxpdGVyYWxseS5cbiAgICAgICAgICAgIHJldHVybiBcIlwiICsgdmFsdWU7XG4gICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gbnVtYmVyQ2xhc3MpIHtcbiAgICAgICAgICAgIC8vIEpTT04gbnVtYmVycyBtdXN0IGJlIGZpbml0ZS4gYEluZmluaXR5YCBhbmQgYE5hTmAgYXJlIHNlcmlhbGl6ZWQgYXNcbiAgICAgICAgICAgIC8vIGBcIm51bGxcImAuXG4gICAgICAgICAgICByZXR1cm4gdmFsdWUgPiAtMSAvIDAgJiYgdmFsdWUgPCAxIC8gMCA/IFwiXCIgKyB2YWx1ZSA6IFwibnVsbFwiO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IHN0cmluZ0NsYXNzKSB7XG4gICAgICAgICAgICAvLyBTdHJpbmdzIGFyZSBkb3VibGUtcXVvdGVkIGFuZCBlc2NhcGVkLlxuICAgICAgICAgICAgcmV0dXJuIHF1b3RlKFwiXCIgKyB2YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZSBvYmplY3RzIGFuZCBhcnJheXMuXG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAvLyBDaGVjayBmb3IgY3ljbGljIHN0cnVjdHVyZXMuIFRoaXMgaXMgYSBsaW5lYXIgc2VhcmNoOyBwZXJmb3JtYW5jZVxuICAgICAgICAgICAgLy8gaXMgaW52ZXJzZWx5IHByb3BvcnRpb25hbCB0byB0aGUgbnVtYmVyIG9mIHVuaXF1ZSBuZXN0ZWQgb2JqZWN0cy5cbiAgICAgICAgICAgIGZvciAobGVuZ3RoID0gc3RhY2subGVuZ3RoOyBsZW5ndGgtLTspIHtcbiAgICAgICAgICAgICAgaWYgKHN0YWNrW2xlbmd0aF0gPT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQ3ljbGljIHN0cnVjdHVyZXMgY2Fubm90IGJlIHNlcmlhbGl6ZWQgYnkgYEpTT04uc3RyaW5naWZ5YC5cbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQWRkIHRoZSBvYmplY3QgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzLlxuICAgICAgICAgICAgc3RhY2sucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICByZXN1bHRzID0gW107XG4gICAgICAgICAgICAvLyBTYXZlIHRoZSBjdXJyZW50IGluZGVudGF0aW9uIGxldmVsIGFuZCBpbmRlbnQgb25lIGFkZGl0aW9uYWwgbGV2ZWwuXG4gICAgICAgICAgICBwcmVmaXggPSBpbmRlbnRhdGlvbjtcbiAgICAgICAgICAgIGluZGVudGF0aW9uICs9IHdoaXRlc3BhY2U7XG4gICAgICAgICAgICBpZiAoY2xhc3NOYW1lID09IGFycmF5Q2xhc3MpIHtcbiAgICAgICAgICAgICAgLy8gUmVjdXJzaXZlbHkgc2VyaWFsaXplIGFycmF5IGVsZW1lbnRzLlxuICAgICAgICAgICAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gdmFsdWUubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBzZXJpYWxpemUoaW5kZXgsIHZhbHVlLCBjYWxsYmFjaywgcHJvcGVydGllcywgd2hpdGVzcGFjZSwgaW5kZW50YXRpb24sIHN0YWNrKTtcbiAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goZWxlbWVudCA9PT0gdW5kZWYgPyBcIm51bGxcIiA6IGVsZW1lbnQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdHMubGVuZ3RoID8gKHdoaXRlc3BhY2UgPyBcIltcXG5cIiArIGluZGVudGF0aW9uICsgcmVzdWx0cy5qb2luKFwiLFxcblwiICsgaW5kZW50YXRpb24pICsgXCJcXG5cIiArIHByZWZpeCArIFwiXVwiIDogKFwiW1wiICsgcmVzdWx0cy5qb2luKFwiLFwiKSArIFwiXVwiKSkgOiBcIltdXCI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXJpYWxpemUgb2JqZWN0IG1lbWJlcnMuIE1lbWJlcnMgYXJlIHNlbGVjdGVkIGZyb21cbiAgICAgICAgICAgICAgLy8gZWl0aGVyIGEgdXNlci1zcGVjaWZpZWQgbGlzdCBvZiBwcm9wZXJ0eSBuYW1lcywgb3IgdGhlIG9iamVjdFxuICAgICAgICAgICAgICAvLyBpdHNlbGYuXG4gICAgICAgICAgICAgIGZvckVhY2gocHJvcGVydGllcyB8fCB2YWx1ZSwgZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBzZXJpYWxpemUocHJvcGVydHksIHZhbHVlLCBjYWxsYmFjaywgcHJvcGVydGllcywgd2hpdGVzcGFjZSwgaW5kZW50YXRpb24sIHN0YWNrKTtcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudCAhPT0gdW5kZWYpIHtcbiAgICAgICAgICAgICAgICAgIC8vIEFjY29yZGluZyB0byBFUyA1LjEgc2VjdGlvbiAxNS4xMi4zOiBcIklmIGBnYXBgIHt3aGl0ZXNwYWNlfVxuICAgICAgICAgICAgICAgICAgLy8gaXMgbm90IHRoZSBlbXB0eSBzdHJpbmcsIGxldCBgbWVtYmVyYCB7cXVvdGUocHJvcGVydHkpICsgXCI6XCJ9XG4gICAgICAgICAgICAgICAgICAvLyBiZSB0aGUgY29uY2F0ZW5hdGlvbiBvZiBgbWVtYmVyYCBhbmQgdGhlIGBzcGFjZWAgY2hhcmFjdGVyLlwiXG4gICAgICAgICAgICAgICAgICAvLyBUaGUgXCJgc3BhY2VgIGNoYXJhY3RlclwiIHJlZmVycyB0byB0aGUgbGl0ZXJhbCBzcGFjZVxuICAgICAgICAgICAgICAgICAgLy8gY2hhcmFjdGVyLCBub3QgdGhlIGBzcGFjZWAge3dpZHRofSBhcmd1bWVudCBwcm92aWRlZCB0b1xuICAgICAgICAgICAgICAgICAgLy8gYEpTT04uc3RyaW5naWZ5YC5cbiAgICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChxdW90ZShwcm9wZXJ0eSkgKyBcIjpcIiArICh3aGl0ZXNwYWNlID8gXCIgXCIgOiBcIlwiKSArIGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdHMubGVuZ3RoID8gKHdoaXRlc3BhY2UgPyBcIntcXG5cIiArIGluZGVudGF0aW9uICsgcmVzdWx0cy5qb2luKFwiLFxcblwiICsgaW5kZW50YXRpb24pICsgXCJcXG5cIiArIHByZWZpeCArIFwifVwiIDogKFwie1wiICsgcmVzdWx0cy5qb2luKFwiLFwiKSArIFwifVwiKSkgOiBcInt9XCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBSZW1vdmUgdGhlIG9iamVjdCBmcm9tIHRoZSB0cmF2ZXJzZWQgb2JqZWN0IHN0YWNrLlxuICAgICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyBQdWJsaWM6IGBKU09OLnN0cmluZ2lmeWAuIFNlZSBFUyA1LjEgc2VjdGlvbiAxNS4xMi4zLlxuICAgICAgICBleHBvcnRzLnN0cmluZ2lmeSA9IGZ1bmN0aW9uIChzb3VyY2UsIGZpbHRlciwgd2lkdGgpIHtcbiAgICAgICAgICB2YXIgd2hpdGVzcGFjZSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIGNsYXNzTmFtZTtcbiAgICAgICAgICBpZiAodHlwZW9mIGZpbHRlciA9PSBcImZ1bmN0aW9uXCIgfHwgdHlwZW9mIGZpbHRlciA9PSBcIm9iamVjdFwiICYmIGZpbHRlcikge1xuICAgICAgICAgICAgaWYgKChjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKGZpbHRlcikpID09IGZ1bmN0aW9uQ2xhc3MpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2sgPSBmaWx0ZXI7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTmFtZSA9PSBhcnJheUNsYXNzKSB7XG4gICAgICAgICAgICAgIC8vIENvbnZlcnQgdGhlIHByb3BlcnR5IG5hbWVzIGFycmF5IGludG8gYSBtYWtlc2hpZnQgc2V0LlxuICAgICAgICAgICAgICBwcm9wZXJ0aWVzID0ge307XG4gICAgICAgICAgICAgIGZvciAodmFyIGluZGV4ID0gMCwgbGVuZ3RoID0gZmlsdGVyLmxlbmd0aCwgdmFsdWU7IGluZGV4IDwgbGVuZ3RoOyB2YWx1ZSA9IGZpbHRlcltpbmRleCsrXSwgKChjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKHZhbHVlKSksIGNsYXNzTmFtZSA9PSBzdHJpbmdDbGFzcyB8fCBjbGFzc05hbWUgPT0gbnVtYmVyQ2xhc3MpICYmIChwcm9wZXJ0aWVzW3ZhbHVlXSA9IDEpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHdpZHRoKSB7XG4gICAgICAgICAgICBpZiAoKGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwod2lkdGgpKSA9PSBudW1iZXJDbGFzcykge1xuICAgICAgICAgICAgICAvLyBDb252ZXJ0IHRoZSBgd2lkdGhgIHRvIGFuIGludGVnZXIgYW5kIGNyZWF0ZSBhIHN0cmluZyBjb250YWluaW5nXG4gICAgICAgICAgICAgIC8vIGB3aWR0aGAgbnVtYmVyIG9mIHNwYWNlIGNoYXJhY3RlcnMuXG4gICAgICAgICAgICAgIGlmICgod2lkdGggLT0gd2lkdGggJSAxKSA+IDApIHtcbiAgICAgICAgICAgICAgICBmb3IgKHdoaXRlc3BhY2UgPSBcIlwiLCB3aWR0aCA+IDEwICYmICh3aWR0aCA9IDEwKTsgd2hpdGVzcGFjZS5sZW5ndGggPCB3aWR0aDsgd2hpdGVzcGFjZSArPSBcIiBcIik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IHN0cmluZ0NsYXNzKSB7XG4gICAgICAgICAgICAgIHdoaXRlc3BhY2UgPSB3aWR0aC5sZW5ndGggPD0gMTAgPyB3aWR0aCA6IHdpZHRoLnNsaWNlKDAsIDEwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gT3BlcmEgPD0gNy41NHUyIGRpc2NhcmRzIHRoZSB2YWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGVtcHR5IHN0cmluZyBrZXlzXG4gICAgICAgICAgLy8gKGBcIlwiYCkgb25seSBpZiB0aGV5IGFyZSB1c2VkIGRpcmVjdGx5IHdpdGhpbiBhbiBvYmplY3QgbWVtYmVyIGxpc3RcbiAgICAgICAgICAvLyAoZS5nLiwgYCEoXCJcIiBpbiB7IFwiXCI6IDF9KWApLlxuICAgICAgICAgIHJldHVybiBzZXJpYWxpemUoXCJcIiwgKHZhbHVlID0ge30sIHZhbHVlW1wiXCJdID0gc291cmNlLCB2YWx1ZSksIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCB3aGl0ZXNwYWNlLCBcIlwiLCBbXSk7XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIC8vIFB1YmxpYzogUGFyc2VzIGEgSlNPTiBzb3VyY2Ugc3RyaW5nLlxuICAgICAgaWYgKCFoYXMoXCJqc29uLXBhcnNlXCIpKSB7XG4gICAgICAgIHZhciBmcm9tQ2hhckNvZGUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlO1xuXG4gICAgICAgIC8vIEludGVybmFsOiBBIG1hcCBvZiBlc2NhcGVkIGNvbnRyb2wgY2hhcmFjdGVycyBhbmQgdGhlaXIgdW5lc2NhcGVkXG4gICAgICAgIC8vIGVxdWl2YWxlbnRzLlxuICAgICAgICB2YXIgVW5lc2NhcGVzID0ge1xuICAgICAgICAgIDkyOiBcIlxcXFxcIixcbiAgICAgICAgICAzNDogJ1wiJyxcbiAgICAgICAgICA0NzogXCIvXCIsXG4gICAgICAgICAgOTg6IFwiXFxiXCIsXG4gICAgICAgICAgMTE2OiBcIlxcdFwiLFxuICAgICAgICAgIDExMDogXCJcXG5cIixcbiAgICAgICAgICAxMDI6IFwiXFxmXCIsXG4gICAgICAgICAgMTE0OiBcIlxcclwiXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFN0b3JlcyB0aGUgcGFyc2VyIHN0YXRlLlxuICAgICAgICB2YXIgSW5kZXgsIFNvdXJjZTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogUmVzZXRzIHRoZSBwYXJzZXIgc3RhdGUgYW5kIHRocm93cyBhIGBTeW50YXhFcnJvcmAuXG4gICAgICAgIHZhciBhYm9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBJbmRleCA9IFNvdXJjZSA9IG51bGw7XG4gICAgICAgICAgdGhyb3cgU3ludGF4RXJyb3IoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogUmV0dXJucyB0aGUgbmV4dCB0b2tlbiwgb3IgYFwiJFwiYCBpZiB0aGUgcGFyc2VyIGhhcyByZWFjaGVkXG4gICAgICAgIC8vIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBzdHJpbmcuIEEgdG9rZW4gbWF5IGJlIGEgc3RyaW5nLCBudW1iZXIsIGBudWxsYFxuICAgICAgICAvLyBsaXRlcmFsLCBvciBCb29sZWFuIGxpdGVyYWwuXG4gICAgICAgIHZhciBsZXggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdmFyIHNvdXJjZSA9IFNvdXJjZSwgbGVuZ3RoID0gc291cmNlLmxlbmd0aCwgdmFsdWUsIGJlZ2luLCBwb3NpdGlvbiwgaXNTaWduZWQsIGNoYXJDb2RlO1xuICAgICAgICAgIHdoaWxlIChJbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7XG4gICAgICAgICAgICBzd2l0Y2ggKGNoYXJDb2RlKSB7XG4gICAgICAgICAgICAgIGNhc2UgOTogY2FzZSAxMDogY2FzZSAxMzogY2FzZSAzMjpcbiAgICAgICAgICAgICAgICAvLyBTa2lwIHdoaXRlc3BhY2UgdG9rZW5zLCBpbmNsdWRpbmcgdGFicywgY2FycmlhZ2UgcmV0dXJucywgbGluZVxuICAgICAgICAgICAgICAgIC8vIGZlZWRzLCBhbmQgc3BhY2UgY2hhcmFjdGVycy5cbiAgICAgICAgICAgICAgICBJbmRleCsrO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlIDEyMzogY2FzZSAxMjU6IGNhc2UgOTE6IGNhc2UgOTM6IGNhc2UgNTg6IGNhc2UgNDQ6XG4gICAgICAgICAgICAgICAgLy8gUGFyc2UgYSBwdW5jdHVhdG9yIHRva2VuIChge2AsIGB9YCwgYFtgLCBgXWAsIGA6YCwgb3IgYCxgKSBhdFxuICAgICAgICAgICAgICAgIC8vIHRoZSBjdXJyZW50IHBvc2l0aW9uLlxuICAgICAgICAgICAgICAgIHZhbHVlID0gY2hhckluZGV4QnVnZ3kgPyBzb3VyY2UuY2hhckF0KEluZGV4KSA6IHNvdXJjZVtJbmRleF07XG4gICAgICAgICAgICAgICAgSW5kZXgrKztcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgIGNhc2UgMzQ6XG4gICAgICAgICAgICAgICAgLy8gYFwiYCBkZWxpbWl0cyBhIEpTT04gc3RyaW5nOyBhZHZhbmNlIHRvIHRoZSBuZXh0IGNoYXJhY3RlciBhbmRcbiAgICAgICAgICAgICAgICAvLyBiZWdpbiBwYXJzaW5nIHRoZSBzdHJpbmcuIFN0cmluZyB0b2tlbnMgYXJlIHByZWZpeGVkIHdpdGggdGhlXG4gICAgICAgICAgICAgICAgLy8gc2VudGluZWwgYEBgIGNoYXJhY3RlciB0byBkaXN0aW5ndWlzaCB0aGVtIGZyb20gcHVuY3R1YXRvcnMgYW5kXG4gICAgICAgICAgICAgICAgLy8gZW5kLW9mLXN0cmluZyB0b2tlbnMuXG4gICAgICAgICAgICAgICAgZm9yICh2YWx1ZSA9IFwiQFwiLCBJbmRleCsrOyBJbmRleCA8IGxlbmd0aDspIHtcbiAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlIDwgMzIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gVW5lc2NhcGVkIEFTQ0lJIGNvbnRyb2wgY2hhcmFjdGVycyAodGhvc2Ugd2l0aCBhIGNvZGUgdW5pdFxuICAgICAgICAgICAgICAgICAgICAvLyBsZXNzIHRoYW4gdGhlIHNwYWNlIGNoYXJhY3RlcikgYXJlIG5vdCBwZXJtaXR0ZWQuXG4gICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGNoYXJDb2RlID09IDkyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEEgcmV2ZXJzZSBzb2xpZHVzIChgXFxgKSBtYXJrcyB0aGUgYmVnaW5uaW5nIG9mIGFuIGVzY2FwZWRcbiAgICAgICAgICAgICAgICAgICAgLy8gY29udHJvbCBjaGFyYWN0ZXIgKGluY2x1ZGluZyBgXCJgLCBgXFxgLCBhbmQgYC9gKSBvciBVbmljb2RlXG4gICAgICAgICAgICAgICAgICAgIC8vIGVzY2FwZSBzZXF1ZW5jZS5cbiAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdCgrK0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjaGFyQ29kZSkge1xuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgOTI6IGNhc2UgMzQ6IGNhc2UgNDc6IGNhc2UgOTg6IGNhc2UgMTE2OiBjYXNlIDExMDogY2FzZSAxMDI6IGNhc2UgMTE0OlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmV2aXZlIGVzY2FwZWQgY29udHJvbCBjaGFyYWN0ZXJzLlxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gVW5lc2NhcGVzW2NoYXJDb2RlXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICBjYXNlIDExNzpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGBcXHVgIG1hcmtzIHRoZSBiZWdpbm5pbmcgb2YgYSBVbmljb2RlIGVzY2FwZSBzZXF1ZW5jZS5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkdmFuY2UgdG8gdGhlIGZpcnN0IGNoYXJhY3RlciBhbmQgdmFsaWRhdGUgdGhlXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3VyLWRpZ2l0IGNvZGUgcG9pbnQuXG4gICAgICAgICAgICAgICAgICAgICAgICBiZWdpbiA9ICsrSW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHBvc2l0aW9uID0gSW5kZXggKyA0OyBJbmRleCA8IHBvc2l0aW9uOyBJbmRleCsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBIHZhbGlkIHNlcXVlbmNlIGNvbXByaXNlcyBmb3VyIGhleGRpZ2l0cyAoY2FzZS1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5zZW5zaXRpdmUpIHRoYXQgZm9ybSBhIHNpbmdsZSBoZXhhZGVjaW1hbCB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcgfHwgY2hhckNvZGUgPj0gOTcgJiYgY2hhckNvZGUgPD0gMTAyIHx8IGNoYXJDb2RlID49IDY1ICYmIGNoYXJDb2RlIDw9IDcwKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEludmFsaWQgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmV2aXZlIHRoZSBlc2NhcGVkIGNoYXJhY3Rlci5cbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlICs9IGZyb21DaGFyQ29kZShcIjB4XCIgKyBzb3VyY2Uuc2xpY2UoYmVnaW4sIEluZGV4KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW52YWxpZCBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gMzQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBBbiB1bmVzY2FwZWQgZG91YmxlLXF1b3RlIGNoYXJhY3RlciBtYXJrcyB0aGUgZW5kIG9mIHRoZVxuICAgICAgICAgICAgICAgICAgICAgIC8vIHN0cmluZy5cbiAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgYmVnaW4gPSBJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgLy8gT3B0aW1pemUgZm9yIHRoZSBjb21tb24gY2FzZSB3aGVyZSBhIHN0cmluZyBpcyB2YWxpZC5cbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGNoYXJDb2RlID49IDMyICYmIGNoYXJDb2RlICE9IDkyICYmIGNoYXJDb2RlICE9IDM0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdCgrK0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBBcHBlbmQgdGhlIHN0cmluZyBhcy1pcy5cbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gc291cmNlLnNsaWNlKGJlZ2luLCBJbmRleCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuY2hhckNvZGVBdChJbmRleCkgPT0gMzQpIHtcbiAgICAgICAgICAgICAgICAgIC8vIEFkdmFuY2UgdG8gdGhlIG5leHQgY2hhcmFjdGVyIGFuZCByZXR1cm4gdGhlIHJldml2ZWQgc3RyaW5nLlxuICAgICAgICAgICAgICAgICAgSW5kZXgrKztcbiAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gVW50ZXJtaW5hdGVkIHN0cmluZy5cbiAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIC8vIFBhcnNlIG51bWJlcnMgYW5kIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgIGJlZ2luID0gSW5kZXg7XG4gICAgICAgICAgICAgICAgLy8gQWR2YW5jZSBwYXN0IHRoZSBuZWdhdGl2ZSBzaWduLCBpZiBvbmUgaXMgc3BlY2lmaWVkLlxuICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSA0NSkge1xuICAgICAgICAgICAgICAgICAgaXNTaWduZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdCgrK0luZGV4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gUGFyc2UgYW4gaW50ZWdlciBvciBmbG9hdGluZy1wb2ludCB2YWx1ZS5cbiAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpIHtcbiAgICAgICAgICAgICAgICAgIC8vIExlYWRpbmcgemVyb2VzIGFyZSBpbnRlcnByZXRlZCBhcyBvY3RhbCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSA0OCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXggKyAxKSksIGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBJbGxlZ2FsIG9jdGFsIGxpdGVyYWwuXG4gICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBpc1NpZ25lZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgdGhlIGludGVnZXIgY29tcG9uZW50LlxuICAgICAgICAgICAgICAgICAgZm9yICg7IEluZGV4IDwgbGVuZ3RoICYmICgoY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCkpLCBjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1Nyk7IEluZGV4KyspO1xuICAgICAgICAgICAgICAgICAgLy8gRmxvYXRzIGNhbm5vdCBjb250YWluIGEgbGVhZGluZyBkZWNpbWFsIHBvaW50OyBob3dldmVyLCB0aGlzXG4gICAgICAgICAgICAgICAgICAvLyBjYXNlIGlzIGFscmVhZHkgYWNjb3VudGVkIGZvciBieSB0aGUgcGFyc2VyLlxuICAgICAgICAgICAgICAgICAgaWYgKHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KSA9PSA0Nikge1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvbiA9ICsrSW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBkZWNpbWFsIGNvbXBvbmVudC5cbiAgICAgICAgICAgICAgICAgICAgZm9yICg7IHBvc2l0aW9uIDwgbGVuZ3RoICYmICgoY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChwb3NpdGlvbikpLCBjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1Nyk7IHBvc2l0aW9uKyspO1xuICAgICAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPT0gSW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBJbGxlZ2FsIHRyYWlsaW5nIGRlY2ltYWwuXG4gICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBJbmRleCA9IHBvc2l0aW9uO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgZXhwb25lbnRzLiBUaGUgYGVgIGRlbm90aW5nIHRoZSBleHBvbmVudCBpc1xuICAgICAgICAgICAgICAgICAgLy8gY2FzZS1pbnNlbnNpdGl2ZS5cbiAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDEwMSB8fCBjaGFyQ29kZSA9PSA2OSkge1xuICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAvLyBTa2lwIHBhc3QgdGhlIHNpZ24gZm9sbG93aW5nIHRoZSBleHBvbmVudCwgaWYgb25lIGlzXG4gICAgICAgICAgICAgICAgICAgIC8vIHNwZWNpZmllZC5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDQzIHx8IGNoYXJDb2RlID09IDQ1KSB7XG4gICAgICAgICAgICAgICAgICAgICAgSW5kZXgrKztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBQYXJzZSB0aGUgZXhwb25lbnRpYWwgY29tcG9uZW50LlxuICAgICAgICAgICAgICAgICAgICBmb3IgKHBvc2l0aW9uID0gSW5kZXg7IHBvc2l0aW9uIDwgbGVuZ3RoICYmICgoY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChwb3NpdGlvbikpLCBjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1Nyk7IHBvc2l0aW9uKyspO1xuICAgICAgICAgICAgICAgICAgICBpZiAocG9zaXRpb24gPT0gSW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBJbGxlZ2FsIGVtcHR5IGV4cG9uZW50LlxuICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgSW5kZXggPSBwb3NpdGlvbjtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIC8vIENvZXJjZSB0aGUgcGFyc2VkIHZhbHVlIHRvIGEgSmF2YVNjcmlwdCBudW1iZXIuXG4gICAgICAgICAgICAgICAgICByZXR1cm4gK3NvdXJjZS5zbGljZShiZWdpbiwgSW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBBIG5lZ2F0aXZlIHNpZ24gbWF5IG9ubHkgcHJlY2VkZSBudW1iZXJzLlxuICAgICAgICAgICAgICAgIGlmIChpc1NpZ25lZCkge1xuICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gYHRydWVgLCBgZmFsc2VgLCBhbmQgYG51bGxgIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgIGlmIChzb3VyY2Uuc2xpY2UoSW5kZXgsIEluZGV4ICsgNCkgPT0gXCJ0cnVlXCIpIHtcbiAgICAgICAgICAgICAgICAgIEluZGV4ICs9IDQ7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNvdXJjZS5zbGljZShJbmRleCwgSW5kZXggKyA1KSA9PSBcImZhbHNlXCIpIHtcbiAgICAgICAgICAgICAgICAgIEluZGV4ICs9IDU7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2Uuc2xpY2UoSW5kZXgsIEluZGV4ICsgNCkgPT0gXCJudWxsXCIpIHtcbiAgICAgICAgICAgICAgICAgIEluZGV4ICs9IDQ7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gVW5yZWNvZ25pemVkIHRva2VuLlxuICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFJldHVybiB0aGUgc2VudGluZWwgYCRgIGNoYXJhY3RlciBpZiB0aGUgcGFyc2VyIGhhcyByZWFjaGVkIHRoZSBlbmRcbiAgICAgICAgICAvLyBvZiB0aGUgc291cmNlIHN0cmluZy5cbiAgICAgICAgICByZXR1cm4gXCIkXCI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFBhcnNlcyBhIEpTT04gYHZhbHVlYCB0b2tlbi5cbiAgICAgICAgdmFyIGdldCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgIHZhciByZXN1bHRzLCBoYXNNZW1iZXJzO1xuICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIiRcIikge1xuICAgICAgICAgICAgLy8gVW5leHBlY3RlZCBlbmQgb2YgaW5wdXQuXG4gICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIGlmICgoY2hhckluZGV4QnVnZ3kgPyB2YWx1ZS5jaGFyQXQoMCkgOiB2YWx1ZVswXSkgPT0gXCJAXCIpIHtcbiAgICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBzZW50aW5lbCBgQGAgY2hhcmFjdGVyLlxuICAgICAgICAgICAgICByZXR1cm4gdmFsdWUuc2xpY2UoMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBQYXJzZSBvYmplY3QgYW5kIGFycmF5IGxpdGVyYWxzLlxuICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiW1wiKSB7XG4gICAgICAgICAgICAgIC8vIFBhcnNlcyBhIEpTT04gYXJyYXksIHJldHVybmluZyBhIG5ldyBKYXZhU2NyaXB0IGFycmF5LlxuICAgICAgICAgICAgICByZXN1bHRzID0gW107XG4gICAgICAgICAgICAgIGZvciAoOzsgaGFzTWVtYmVycyB8fCAoaGFzTWVtYmVycyA9IHRydWUpKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBsZXgoKTtcbiAgICAgICAgICAgICAgICAvLyBBIGNsb3Npbmcgc3F1YXJlIGJyYWNrZXQgbWFya3MgdGhlIGVuZCBvZiB0aGUgYXJyYXkgbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJdXCIpIHtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgYXJyYXkgbGl0ZXJhbCBjb250YWlucyBlbGVtZW50cywgdGhlIGN1cnJlbnQgdG9rZW5cbiAgICAgICAgICAgICAgICAvLyBzaG91bGQgYmUgYSBjb21tYSBzZXBhcmF0aW5nIHRoZSBwcmV2aW91cyBlbGVtZW50IGZyb20gdGhlXG4gICAgICAgICAgICAgICAgLy8gbmV4dC5cbiAgICAgICAgICAgICAgICBpZiAoaGFzTWVtYmVycykge1xuICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbGV4KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIl1cIikge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgdHJhaWxpbmcgYCxgIGluIGFycmF5IGxpdGVyYWwuXG4gICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQSBgLGAgbXVzdCBzZXBhcmF0ZSBlYWNoIGFycmF5IGVsZW1lbnQuXG4gICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEVsaXNpb25zIGFuZCBsZWFkaW5nIGNvbW1hcyBhcmUgbm90IHBlcm1pdHRlZC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCIsXCIpIHtcbiAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChnZXQodmFsdWUpKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gXCJ7XCIpIHtcbiAgICAgICAgICAgICAgLy8gUGFyc2VzIGEgSlNPTiBvYmplY3QsIHJldHVybmluZyBhIG5ldyBKYXZhU2NyaXB0IG9iamVjdC5cbiAgICAgICAgICAgICAgcmVzdWx0cyA9IHt9O1xuICAgICAgICAgICAgICBmb3IgKDs7IGhhc01lbWJlcnMgfHwgKGhhc01lbWJlcnMgPSB0cnVlKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gbGV4KCk7XG4gICAgICAgICAgICAgICAgLy8gQSBjbG9zaW5nIGN1cmx5IGJyYWNlIG1hcmtzIHRoZSBlbmQgb2YgdGhlIG9iamVjdCBsaXRlcmFsLlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIn1cIikge1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBvYmplY3QgbGl0ZXJhbCBjb250YWlucyBtZW1iZXJzLCB0aGUgY3VycmVudCB0b2tlblxuICAgICAgICAgICAgICAgIC8vIHNob3VsZCBiZSBhIGNvbW1hIHNlcGFyYXRvci5cbiAgICAgICAgICAgICAgICBpZiAoaGFzTWVtYmVycykge1xuICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbGV4KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIn1cIikge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgdHJhaWxpbmcgYCxgIGluIG9iamVjdCBsaXRlcmFsLlxuICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEEgYCxgIG11c3Qgc2VwYXJhdGUgZWFjaCBvYmplY3QgbWVtYmVyLlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBMZWFkaW5nIGNvbW1hcyBhcmUgbm90IHBlcm1pdHRlZCwgb2JqZWN0IHByb3BlcnR5IG5hbWVzIG11c3QgYmVcbiAgICAgICAgICAgICAgICAvLyBkb3VibGUtcXVvdGVkIHN0cmluZ3MsIGFuZCBhIGA6YCBtdXN0IHNlcGFyYXRlIGVhY2ggcHJvcGVydHlcbiAgICAgICAgICAgICAgICAvLyBuYW1lIGFuZCB2YWx1ZS5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCIsXCIgfHwgdHlwZW9mIHZhbHVlICE9IFwic3RyaW5nXCIgfHwgKGNoYXJJbmRleEJ1Z2d5ID8gdmFsdWUuY2hhckF0KDApIDogdmFsdWVbMF0pICE9IFwiQFwiIHx8IGxleCgpICE9IFwiOlwiKSB7XG4gICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXN1bHRzW3ZhbHVlLnNsaWNlKDEpXSA9IGdldChsZXgoKSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBVbmV4cGVjdGVkIHRva2VuIGVuY291bnRlcmVkLlxuICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBVcGRhdGVzIGEgdHJhdmVyc2VkIG9iamVjdCBtZW1iZXIuXG4gICAgICAgIHZhciB1cGRhdGUgPSBmdW5jdGlvbiAoc291cmNlLCBwcm9wZXJ0eSwgY2FsbGJhY2spIHtcbiAgICAgICAgICB2YXIgZWxlbWVudCA9IHdhbGsoc291cmNlLCBwcm9wZXJ0eSwgY2FsbGJhY2spO1xuICAgICAgICAgIGlmIChlbGVtZW50ID09PSB1bmRlZikge1xuICAgICAgICAgICAgZGVsZXRlIHNvdXJjZVtwcm9wZXJ0eV07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNvdXJjZVtwcm9wZXJ0eV0gPSBlbGVtZW50O1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogUmVjdXJzaXZlbHkgdHJhdmVyc2VzIGEgcGFyc2VkIEpTT04gb2JqZWN0LCBpbnZva2luZyB0aGVcbiAgICAgICAgLy8gYGNhbGxiYWNrYCBmdW5jdGlvbiBmb3IgZWFjaCB2YWx1ZS4gVGhpcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGVcbiAgICAgICAgLy8gYFdhbGsoaG9sZGVyLCBuYW1lKWAgb3BlcmF0aW9uIGRlZmluZWQgaW4gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMi5cbiAgICAgICAgdmFyIHdhbGsgPSBmdW5jdGlvbiAoc291cmNlLCBwcm9wZXJ0eSwgY2FsbGJhY2spIHtcbiAgICAgICAgICB2YXIgdmFsdWUgPSBzb3VyY2VbcHJvcGVydHldLCBsZW5ndGg7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiICYmIHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBgZm9yRWFjaGAgY2FuJ3QgYmUgdXNlZCB0byB0cmF2ZXJzZSBhbiBhcnJheSBpbiBPcGVyYSA8PSA4LjU0XG4gICAgICAgICAgICAvLyBiZWNhdXNlIGl0cyBgT2JqZWN0I2hhc093blByb3BlcnR5YCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIGBmYWxzZWBcbiAgICAgICAgICAgIC8vIGZvciBhcnJheSBpbmRpY2VzIChlLmcuLCBgIVsxLCAyLCAzXS5oYXNPd25Qcm9wZXJ0eShcIjBcIilgKS5cbiAgICAgICAgICAgIGlmIChnZXRDbGFzcy5jYWxsKHZhbHVlKSA9PSBhcnJheUNsYXNzKSB7XG4gICAgICAgICAgICAgIGZvciAobGVuZ3RoID0gdmFsdWUubGVuZ3RoOyBsZW5ndGgtLTspIHtcbiAgICAgICAgICAgICAgICB1cGRhdGUodmFsdWUsIGxlbmd0aCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBmb3JFYWNoKHZhbHVlLCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICB1cGRhdGUodmFsdWUsIHByb3BlcnR5LCBjYWxsYmFjayk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2suY2FsbChzb3VyY2UsIHByb3BlcnR5LCB2YWx1ZSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUHVibGljOiBgSlNPTi5wYXJzZWAuIFNlZSBFUyA1LjEgc2VjdGlvbiAxNS4xMi4yLlxuICAgICAgICBleHBvcnRzLnBhcnNlID0gZnVuY3Rpb24gKHNvdXJjZSwgY2FsbGJhY2spIHtcbiAgICAgICAgICB2YXIgcmVzdWx0LCB2YWx1ZTtcbiAgICAgICAgICBJbmRleCA9IDA7XG4gICAgICAgICAgU291cmNlID0gXCJcIiArIHNvdXJjZTtcbiAgICAgICAgICByZXN1bHQgPSBnZXQobGV4KCkpO1xuICAgICAgICAgIC8vIElmIGEgSlNPTiBzdHJpbmcgY29udGFpbnMgbXVsdGlwbGUgdG9rZW5zLCBpdCBpcyBpbnZhbGlkLlxuICAgICAgICAgIGlmIChsZXgoKSAhPSBcIiRcIikge1xuICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gUmVzZXQgdGhlIHBhcnNlciBzdGF0ZS5cbiAgICAgICAgICBJbmRleCA9IFNvdXJjZSA9IG51bGw7XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrICYmIGdldENsYXNzLmNhbGwoY2FsbGJhY2spID09IGZ1bmN0aW9uQ2xhc3MgPyB3YWxrKCh2YWx1ZSA9IHt9LCB2YWx1ZVtcIlwiXSA9IHJlc3VsdCwgdmFsdWUpLCBcIlwiLCBjYWxsYmFjaykgOiByZXN1bHQ7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgZXhwb3J0c1tcInJ1bkluQ29udGV4dFwiXSA9IHJ1bkluQ29udGV4dDtcbiAgICByZXR1cm4gZXhwb3J0cztcbiAgfVxuXG4gIGlmICh0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIGV4cG9ydHMgJiYgIWV4cG9ydHMubm9kZVR5cGUgJiYgIWlzTG9hZGVyKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBlbnZpcm9ubWVudHMuXG4gICAgcnVuSW5Db250ZXh0KHJvb3QsIGV4cG9ydHMpO1xuICB9IGVsc2Uge1xuICAgIC8vIEV4cG9ydCBmb3Igd2ViIGJyb3dzZXJzIGFuZCBKYXZhU2NyaXB0IGVuZ2luZXMuXG4gICAgdmFyIG5hdGl2ZUpTT04gPSByb290LkpTT047XG4gICAgdmFyIEpTT04zID0gcnVuSW5Db250ZXh0KHJvb3QsIChyb290W1wiSlNPTjNcIl0gPSB7XG4gICAgICAvLyBQdWJsaWM6IFJlc3RvcmVzIHRoZSBvcmlnaW5hbCB2YWx1ZSBvZiB0aGUgZ2xvYmFsIGBKU09OYCBvYmplY3QgYW5kXG4gICAgICAvLyByZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBgSlNPTjNgIG9iamVjdC5cbiAgICAgIFwibm9Db25mbGljdFwiOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJvb3QuSlNPTiA9IG5hdGl2ZUpTT047XG4gICAgICAgIHJldHVybiBKU09OMztcbiAgICAgIH1cbiAgICB9KSk7XG5cbiAgICByb290LkpTT04gPSB7XG4gICAgICBcInBhcnNlXCI6IEpTT04zLnBhcnNlLFxuICAgICAgXCJzdHJpbmdpZnlcIjogSlNPTjMuc3RyaW5naWZ5XG4gICAgfTtcbiAgfVxuXG4gIC8vIEV4cG9ydCBmb3IgYXN5bmNocm9ub3VzIG1vZHVsZSBsb2FkZXJzLlxuICBpZiAoaXNMb2FkZXIpIHtcbiAgICBkZWZpbmUoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIEpTT04zO1xuICAgIH0pO1xuICB9XG59KHRoaXMpKTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbnZhciBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gKGZuKSB7XG5cdHJldHVybiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nICYmICEoZm4gaW5zdGFuY2VvZiBSZWdFeHApKSB8fCB0b1N0cmluZy5jYWxsKGZuKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZm9yRWFjaChvYmosIGZuKSB7XG5cdGlmICghaXNGdW5jdGlvbihmbikpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdpdGVyYXRvciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblx0fVxuXHR2YXIgaSwgayxcblx0XHRpc1N0cmluZyA9IHR5cGVvZiBvYmogPT09ICdzdHJpbmcnLFxuXHRcdGwgPSBvYmoubGVuZ3RoLFxuXHRcdGNvbnRleHQgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IG51bGw7XG5cdGlmIChsID09PSArbCkge1xuXHRcdGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHtcblx0XHRcdGlmIChjb250ZXh0ID09PSBudWxsKSB7XG5cdFx0XHRcdGZuKGlzU3RyaW5nID8gb2JqLmNoYXJBdChpKSA6IG9ialtpXSwgaSwgb2JqKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZuLmNhbGwoY29udGV4dCwgaXNTdHJpbmcgPyBvYmouY2hhckF0KGkpIDogb2JqW2ldLCBpLCBvYmopO1xuXHRcdFx0fVxuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRmb3IgKGsgaW4gb2JqKSB7XG5cdFx0XHRpZiAoaGFzT3duLmNhbGwob2JqLCBrKSkge1xuXHRcdFx0XHRpZiAoY29udGV4dCA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdGZuKG9ialtrXSwgaywgb2JqKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRmbi5jYWxsKGNvbnRleHQsIG9ialtrXSwgaywgb2JqKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxufTtcblxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8vIG1vZGlmaWVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltXG52YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSxcblx0dG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLFxuXHRmb3JFYWNoID0gcmVxdWlyZSgnLi9mb3JlYWNoJyksXG5cdGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcblx0aGFzRG9udEVudW1CdWcgPSAhKHsndG9TdHJpbmcnOiBudWxsfSkucHJvcGVydHlJc0VudW1lcmFibGUoJ3RvU3RyaW5nJyksXG5cdGhhc1Byb3RvRW51bUJ1ZyA9IChmdW5jdGlvbiAoKSB7fSkucHJvcGVydHlJc0VudW1lcmFibGUoJ3Byb3RvdHlwZScpLFxuXHRkb250RW51bXMgPSBbXG5cdFx0XCJ0b1N0cmluZ1wiLFxuXHRcdFwidG9Mb2NhbGVTdHJpbmdcIixcblx0XHRcInZhbHVlT2ZcIixcblx0XHRcImhhc093blByb3BlcnR5XCIsXG5cdFx0XCJpc1Byb3RvdHlwZU9mXCIsXG5cdFx0XCJwcm9wZXJ0eUlzRW51bWVyYWJsZVwiLFxuXHRcdFwiY29uc3RydWN0b3JcIlxuXHRdO1xuXG52YXIga2V5c1NoaW0gPSBmdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuXHR2YXIgaXNPYmplY3QgPSBvYmplY3QgIT09IG51bGwgJiYgdHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcsXG5cdFx0aXNGdW5jdGlvbiA9IHRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcblx0XHRpc0FyZ3VtZW50cyA9IGlzQXJncyhvYmplY3QpLFxuXHRcdHRoZUtleXMgPSBbXTtcblxuXHRpZiAoIWlzT2JqZWN0ICYmICFpc0Z1bmN0aW9uICYmICFpc0FyZ3VtZW50cykge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0XCIpO1xuXHR9XG5cblx0aWYgKGlzQXJndW1lbnRzKSB7XG5cdFx0Zm9yRWFjaChvYmplY3QsIGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgpIHtcblx0XHRcdHRoZUtleXMucHVzaChpbmRleCk7XG5cdFx0fSk7XG5cdH0gZWxzZSB7XG5cdFx0dmFyIG5hbWUsXG5cdFx0XHRza2lwUHJvdG8gPSBoYXNQcm90b0VudW1CdWcgJiYgaXNGdW5jdGlvbjtcblxuXHRcdGZvciAobmFtZSBpbiBvYmplY3QpIHtcblx0XHRcdGlmICghKHNraXBQcm90byAmJiBuYW1lID09PSAncHJvdG90eXBlJykgJiYgaGFzLmNhbGwob2JqZWN0LCBuYW1lKSkge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2gobmFtZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0aWYgKGhhc0RvbnRFbnVtQnVnKSB7XG5cdFx0dmFyIGN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG5cdFx0XHRza2lwQ29uc3RydWN0b3IgPSBjdG9yICYmIGN0b3IucHJvdG90eXBlID09PSBvYmplY3Q7XG5cblx0XHRmb3JFYWNoKGRvbnRFbnVtcywgZnVuY3Rpb24gKGRvbnRFbnVtKSB7XG5cdFx0XHRpZiAoIShza2lwQ29uc3RydWN0b3IgJiYgZG9udEVudW0gPT09ICdjb25zdHJ1Y3RvcicpICYmIGhhcy5jYWxsKG9iamVjdCwgZG9udEVudW0pKSB7XG5cdFx0XHRcdHRoZUtleXMucHVzaChkb250RW51bSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblx0cmV0dXJuIHRoZUtleXM7XG59O1xuXG5rZXlzU2hpbS5zaGltID0gZnVuY3Rpb24gc2hpbU9iamVjdEtleXMoKSB7XG5cdGlmICghT2JqZWN0LmtleXMpIHtcblx0XHRPYmplY3Qua2V5cyA9IGtleXNTaGltO1xuXHR9XG5cdHJldHVybiBPYmplY3Qua2V5cyB8fCBrZXlzU2hpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG5cbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG5cdHZhciBzdHIgPSB0b1N0cmluZy5jYWxsKHZhbHVlKTtcblx0dmFyIGlzQXJndW1lbnRzID0gc3RyID09PSAnW29iamVjdCBBcmd1bWVudHNdJztcblx0aWYgKCFpc0FyZ3VtZW50cykge1xuXHRcdGlzQXJndW1lbnRzID0gc3RyICE9PSAnW29iamVjdCBBcnJheV0nXG5cdFx0XHQmJiB2YWx1ZSAhPT0gbnVsbFxuXHRcdFx0JiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0J1xuXHRcdFx0JiYgdHlwZW9mIHZhbHVlLmxlbmd0aCA9PT0gJ251bWJlcidcblx0XHRcdCYmIHZhbHVlLmxlbmd0aCA+PSAwXG5cdFx0XHQmJiB0b1N0cmluZy5jYWxsKHZhbHVlLmNhbGxlZSkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cdH1cblx0cmV0dXJuIGlzQXJndW1lbnRzO1xufTtcblxuIiwiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIG1hcCA9IHJlcXVpcmUoJ2FycmF5LW1hcCcpO1xudmFyIGluZGV4T2YgPSByZXF1aXJlKCdpbmRleG9mJyk7XG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKTtcbnZhciBmb3JFYWNoID0gcmVxdWlyZSgnZm9yZWFjaCcpO1xudmFyIHJlZHVjZSA9IHJlcXVpcmUoJ2FycmF5LXJlZHVjZScpO1xudmFyIGdldE9iamVjdEtleXMgPSByZXF1aXJlKCdvYmplY3Qta2V5cycpO1xudmFyIEpTT04gPSByZXF1aXJlKCdqc29uMycpO1xuXG4vKipcbiAqIE1ha2Ugc3VyZSBgT2JqZWN0LmtleXNgIHdvcmsgZm9yIGB1bmRlZmluZWRgXG4gKiB2YWx1ZXMgdGhhdCBhcmUgc3RpbGwgdGhlcmUsIGxpa2UgYGRvY3VtZW50LmFsbGAuXG4gKiBodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy9wdWJsaWMtaHRtbC8yMDA5SnVuLzA1NDYuaHRtbFxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIG9iamVjdEtleXModmFsKXtcbiAgaWYgKE9iamVjdC5rZXlzKSByZXR1cm4gT2JqZWN0LmtleXModmFsKTtcbiAgcmV0dXJuIGdldE9iamVjdEtleXModmFsKTtcbn1cblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGluc3BlY3Q7XG5cbi8qKlxuICogRWNob3MgdGhlIHZhbHVlIG9mIGEgdmFsdWUuIFRyeXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuICogaW4gdGhlIGJlc3Qgd2F5IHBvc3NpYmxlIGdpdmVuIHRoZSBkaWZmZXJlbnQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIE9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IHRoYXQgYWx0ZXJzIHRoZSBvdXRwdXQuXG4gKiBAbGljZW5zZSBNSVQgKMKpIEpveWVudClcbiAqL1xuLyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuXG5mdW5jdGlvbiBpbnNwZWN0KG9iaiwgb3B0cykge1xuICAvLyBkZWZhdWx0IG9wdGlvbnNcbiAgdmFyIGN0eCA9IHtcbiAgICBzZWVuOiBbXSxcbiAgICBzdHlsaXplOiBzdHlsaXplTm9Db2xvclxuICB9O1xuICAvLyBsZWdhY3kuLi5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykgY3R4LmRlcHRoID0gYXJndW1lbnRzWzJdO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA0KSBjdHguY29sb3JzID0gYXJndW1lbnRzWzNdO1xuICBpZiAoaXNCb29sZWFuKG9wdHMpKSB7XG4gICAgLy8gbGVnYWN5Li4uXG4gICAgY3R4LnNob3dIaWRkZW4gPSBvcHRzO1xuICB9IGVsc2UgaWYgKG9wdHMpIHtcbiAgICAvLyBnb3QgYW4gXCJvcHRpb25zXCIgb2JqZWN0XG4gICAgX2V4dGVuZChjdHgsIG9wdHMpO1xuICB9XG4gIC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY29sb3JzKSkgY3R4LmNvbG9ycyA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG4gIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG4gIHJldHVybiBmb3JtYXRWYWx1ZShjdHgsIG9iaiwgY3R4LmRlcHRoKTtcbn1cblxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5pbnNwZWN0LmNvbG9ycyA9IHtcbiAgJ2JvbGQnIDogWzEsIDIyXSxcbiAgJ2l0YWxpYycgOiBbMywgMjNdLFxuICAndW5kZXJsaW5lJyA6IFs0LCAyNF0sXG4gICdpbnZlcnNlJyA6IFs3LCAyN10sXG4gICd3aGl0ZScgOiBbMzcsIDM5XSxcbiAgJ2dyZXknIDogWzkwLCAzOV0sXG4gICdibGFjaycgOiBbMzAsIDM5XSxcbiAgJ2JsdWUnIDogWzM0LCAzOV0sXG4gICdjeWFuJyA6IFszNiwgMzldLFxuICAnZ3JlZW4nIDogWzMyLCAzOV0sXG4gICdtYWdlbnRhJyA6IFszNSwgMzldLFxuICAncmVkJyA6IFszMSwgMzldLFxuICAneWVsbG93JyA6IFszMywgMzldXG59O1xuXG4vLyBEb24ndCB1c2UgJ2JsdWUnIG5vdCB2aXNpYmxlIG9uIGNtZC5leGVcbmluc3BlY3Quc3R5bGVzID0ge1xuICAnc3BlY2lhbCc6ICdjeWFuJyxcbiAgJ251bWJlcic6ICd5ZWxsb3cnLFxuICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuICAndW5kZWZpbmVkJzogJ2dyZXknLFxuICAnbnVsbCc6ICdib2xkJyxcbiAgJ3N0cmluZyc6ICdncmVlbicsXG4gICdkYXRlJzogJ21hZ2VudGEnLFxuICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuICAncmVnZXhwJzogJ3JlZCdcbn07XG5cbmZ1bmN0aW9uIHN0eWxpemVOb0NvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHJldHVybiBzdHI7XG59XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cblxuZnVuY3Rpb24gc3R5bGl6ZVdpdGhDb2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG4gIGlmIChzdHlsZSkge1xuICAgIHJldHVybiAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzBdICsgJ20nICsgc3RyICtcbiAgICAgICAgICAgJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVsxXSArICdtJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGhhc093bihvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gaXNPYmplY3QocmUpICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGUpICYmXG4gICAgICAob2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXScgfHwgZSBpbnN0YW5jZW9mIEVycm9yKTtcbn1cblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGQpICYmIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cblxuZnVuY3Rpb24gYXJyYXlUb0hhc2goYXJyYXkpIHtcbiAgdmFyIGhhc2ggPSB7fTtcblxuICBmb3JFYWNoKGFycmF5LCBmdW5jdGlvbih2YWwsIGlkeCkge1xuICAgIGhhc2hbdmFsXSA9IHRydWU7XG4gIH0pO1xuXG4gIHJldHVybiBoYXNoO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKSB7XG4gIHZhciBvdXRwdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICBpZiAoaGFzT3duKHZhbHVlLCBTdHJpbmcoaSkpKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIFN0cmluZyhpKSwgdHJ1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgfVxuICB9XG4gIGZvckVhY2goa2V5cywgZnVuY3Rpb24oa2V5KSB7XG4gICAgaWYgKCFrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIGtleSwgdHJ1ZSkpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBvdXRwdXQ7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdEVycm9yKHZhbHVlKSB7XG4gIHJldHVybiAnWycgKyBFcnJvci5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgKyAnXSc7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFZhbHVlKGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcykge1xuICAvLyBQcm92aWRlIGEgaG9vayBmb3IgdXNlci1zcGVjaWZpZWQgaW5zcGVjdCBmdW5jdGlvbnMuXG4gIC8vIENoZWNrIHRoYXQgdmFsdWUgaXMgYW4gb2JqZWN0IHdpdGggYW4gaW5zcGVjdCBmdW5jdGlvbiBvbiBpdFxuICBpZiAoY3R4LmN1c3RvbUluc3BlY3QgJiZcbiAgICAgIHZhbHVlICYmXG4gICAgICBpc0Z1bmN0aW9uKHZhbHVlLmluc3BlY3QpICYmXG4gICAgICAvLyBGaWx0ZXIgb3V0IHRoZSB1dGlsIG1vZHVsZSwgaXQncyBpbnNwZWN0IGZ1bmN0aW9uIGlzIHNwZWNpYWxcbiAgICAgIHZhbHVlLmluc3BlY3QgIT09IGluc3BlY3QgJiZcbiAgICAgIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuICAgICAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcywgY3R4KTtcbiAgICBpZiAoIWlzU3RyaW5nKHJldCkpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG4gIHZhciBrZXlzID0gb2JqZWN0S2V5cyh2YWx1ZSk7XG4gIHZhciB2aXNpYmxlS2V5cyA9IGFycmF5VG9IYXNoKGtleXMpO1xuXG4gIGlmIChjdHguc2hvd0hpZGRlbiAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcykge1xuICAgIGtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh2YWx1ZSk7XG4gIH1cblxuICAvLyBJRSBkb2Vzbid0IG1ha2UgZXJyb3IgZmllbGRzIG5vbi1lbnVtZXJhYmxlXG4gIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9pZS9kd3c1MnNidCh2PXZzLjk0KS5hc3B4XG4gIGlmIChpc0Vycm9yKHZhbHVlKVxuICAgICAgJiYgKGluZGV4T2Yoa2V5cywgJ21lc3NhZ2UnKSA+PSAwIHx8IGluZGV4T2Yoa2V5cywgJ2Rlc2NyaXB0aW9uJykgPj0gMCkpIHtcbiAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgLy8gU29tZSB0eXBlIG9mIG9iamVjdCB3aXRob3V0IHByb3BlcnRpZXMgY2FuIGJlIHNob3J0Y3V0dGVkLlxuICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgIHZhciBuYW1lID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tGdW5jdGlvbicgKyBuYW1lICsgJ10nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH1cbiAgICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAnZGF0ZScpO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGJhc2UgPSAnJywgYXJyYXkgPSBmYWxzZSwgYnJhY2VzID0gWyd7JywgJ30nXTtcblxuICAvLyBNYWtlIEFycmF5IHNheSB0aGF0IHRoZXkgYXJlIEFycmF5XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIGFycmF5ID0gdHJ1ZTtcbiAgICBicmFjZXMgPSBbJ1snLCAnXSddO1xuICB9XG5cbiAgLy8gTWFrZSBmdW5jdGlvbnMgc2F5IHRoYXQgdGhleSBhcmUgZnVuY3Rpb25zXG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHZhciBuID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgYmFzZSA9ICcgW0Z1bmN0aW9uJyArIG4gKyAnXSc7XG4gIH1cblxuICAvLyBNYWtlIFJlZ0V4cHMgc2F5IHRoYXQgdGhleSBhcmUgUmVnRXhwc1xuICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGRhdGVzIHdpdGggcHJvcGVydGllcyBmaXJzdCBzYXkgdGhlIGRhdGVcbiAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGVycm9yIHdpdGggbWVzc2FnZSBmaXJzdCBzYXkgdGhlIGVycm9yXG4gIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICBpZiAoa2V5cy5sZW5ndGggPT09IDAgJiYgKCFhcnJheSB8fCB2YWx1ZS5sZW5ndGggPT0gMCkpIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArIGJyYWNlc1sxXTtcbiAgfVxuXG4gIGlmIChyZWN1cnNlVGltZXMgPCAwKSB7XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbT2JqZWN0XScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG5cbiAgY3R4LnNlZW4ucHVzaCh2YWx1ZSk7XG5cbiAgdmFyIG91dHB1dDtcbiAgaWYgKGFycmF5KSB7XG4gICAgb3V0cHV0ID0gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cyk7XG4gIH0gZWxzZSB7XG4gICAgb3V0cHV0ID0gbWFwKGtleXMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpO1xuICAgIH0pO1xuICB9XG5cbiAgY3R4LnNlZW4ucG9wKCk7XG5cbiAgcmV0dXJuIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSkge1xuICB2YXIgbmFtZSwgc3RyLCBkZXNjO1xuICBkZXNjID0geyB2YWx1ZTogdmFsdWVba2V5XSB9O1xuICBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcikge1xuICAgIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHZhbHVlLCBrZXkpIHx8IGRlc2M7XG4gIH1cbiAgaWYgKGRlc2MuZ2V0KSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlci9TZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoIWhhc093bih2aXNpYmxlS2V5cywga2V5KSkge1xuICAgIG5hbWUgPSAnWycgKyBrZXkgKyAnXSc7XG4gIH1cbiAgaWYgKCFzdHIpIHtcbiAgICBpZiAoaW5kZXhPZihjdHguc2VlbiwgZGVzYy52YWx1ZSkgPCAwKSB7XG4gICAgICBpZiAoaXNOdWxsKHJlY3Vyc2VUaW1lcykpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gbWFwKHN0ci5zcGxpdCgnXFxuJyksIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKS5zdWJzdHIoMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyID0gJ1xcbicgKyBtYXAoc3RyLnNwbGl0KCdcXG4nKSwgZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0NpcmN1bGFyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmIChpc1VuZGVmaW5lZChuYW1lKSkge1xuICAgIGlmIChhcnJheSAmJiBrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH1cbiAgICBuYW1lID0gSlNPTi5zdHJpbmdpZnkoJycgKyBrZXkpO1xuICAgIGlmIChuYW1lLm1hdGNoKC9eXCIoW2EtekEtWl9dW2EtekEtWl8wLTldKilcIiQvKSkge1xuICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyKDEsIG5hbWUubGVuZ3RoIC0gMik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ25hbWUnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmFtZSA9IG5hbWUucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJylcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLyheXCJ8XCIkKS9nLCBcIidcIik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ3N0cmluZycpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuYW1lICsgJzogJyArIHN0cjtcbn1cblxuZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBzaW1wbGUgPSAnXFwnJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC9eXCJ8XCIkL2csICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuICAgIHJldHVybiBjdHguc3R5bGl6ZShzaW1wbGUsICdzdHJpbmcnKTtcbiAgfVxuICBpZiAoaXNOdW1iZXIodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG4gIGlmIChpc0Jvb2xlYW4odmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpO1xuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmIChpc051bGwodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG59XG5cbmZ1bmN0aW9uIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKSB7XG4gIHZhciBudW1MaW5lc0VzdCA9IDA7XG4gIHZhciBsZW5ndGggPSByZWR1Y2Uob3V0cHV0LCBmdW5jdGlvbihwcmV2LCBjdXIpIHtcbiAgICBudW1MaW5lc0VzdCsrO1xuICAgIGlmIChjdXIuaW5kZXhPZignXFxuJykgPj0gMCkgbnVtTGluZXNFc3QrKztcbiAgICByZXR1cm4gcHJldiArIGN1ci5yZXBsYWNlKC9cXHUwMDFiXFxbXFxkXFxkP20vZywgJycpLmxlbmd0aCArIDE7XG4gIH0sIDApO1xuXG4gIGlmIChsZW5ndGggPiA2MCkge1xuICAgIHJldHVybiBicmFjZXNbMF0gK1xuICAgICAgICAgICAoYmFzZSA9PT0gJycgPyAnJyA6IGJhc2UgKyAnXFxuICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgb3V0cHV0LmpvaW4oJyxcXG4gICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgYnJhY2VzWzFdO1xuICB9XG5cbiAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyAnICcgKyBvdXRwdXQuam9pbignLCAnKSArICcgJyArIGJyYWNlc1sxXTtcbn1cblxuZnVuY3Rpb24gX2V4dGVuZChvcmlnaW4sIGFkZCkge1xuICAvLyBEb24ndCBkbyBhbnl0aGluZyBpZiBhZGQgaXNuJ3QgYW4gb2JqZWN0XG4gIGlmICghYWRkIHx8ICFpc09iamVjdChhZGQpKSByZXR1cm4gb3JpZ2luO1xuXG4gIHZhciBrZXlzID0gb2JqZWN0S2V5cyhhZGQpO1xuICB2YXIgaSA9IGtleXMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgb3JpZ2luW2tleXNbaV1dID0gYWRkW2tleXNbaV1dO1xuICB9XG4gIHJldHVybiBvcmlnaW47XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vLyBUaGlzIGlzIGEgcmVwb3J0ZXIgdGhhdCBtaW1pY3MgTW9jaGEncyBgZG90YCByZXBvcnRlclxuXG52YXIgUiA9IHJlcXVpcmUoXCIuLi9saWIvcmVwb3J0ZXJcIilcblxuZnVuY3Rpb24gd2lkdGgoKSB7XG4gICAgcmV0dXJuIFIud2luZG93V2lkdGgoKSAqIDQgLyAzIHwgMFxufVxuXG5mdW5jdGlvbiBwcmludERvdChfLCBjb2xvcikge1xuICAgIGZ1bmN0aW9uIGVtaXQoKSB7XG4gICAgICAgIHJldHVybiBfLndyaXRlKFIuY29sb3IoY29sb3IsXG4gICAgICAgICAgICBjb2xvciA9PT0gXCJmYWlsXCIgPyBSLnN5bWJvbHMoKS5Eb3RGYWlsIDogUi5zeW1ib2xzKCkuRG90KSlcbiAgICB9XG5cbiAgICBpZiAoXy5zdGF0ZS5jb3VudGVyKysgJSB3aWR0aCgpID09PSAwKSB7XG4gICAgICAgIHJldHVybiBfLndyaXRlKFIubmV3bGluZSgpICsgXCIgIFwiKS50aGVuKGVtaXQpXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGVtaXQoKVxuICAgIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSLm9uKFwiZG90XCIsIHtcbiAgICBhY2NlcHRzOiBbXCJ3cml0ZVwiLCBcInJlc2V0XCIsIFwiY29sb3JzXCJdLFxuICAgIGNyZWF0ZTogUi5jb25zb2xlUmVwb3J0ZXIsXG4gICAgYmVmb3JlOiBSLnNldENvbG9yLFxuICAgIGFmdGVyOiBSLnVuc2V0Q29sb3IsXG4gICAgaW5pdDogZnVuY3Rpb24gKHN0YXRlKSB7IHN0YXRlLmNvdW50ZXIgPSAwIH0sXG5cbiAgICByZXBvcnQ6IGZ1bmN0aW9uIChfLCByZXBvcnQpIHtcbiAgICAgICAgaWYgKHJlcG9ydC5pc0VudGVyIHx8IHJlcG9ydC5pc1Bhc3MpIHtcbiAgICAgICAgICAgIHJldHVybiBwcmludERvdChfLCBSLnNwZWVkKHJlcG9ydCkpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzSG9vayB8fCByZXBvcnQuaXNGYWlsKSB7XG4gICAgICAgICAgICBfLnB1c2hFcnJvcihyZXBvcnQpXG4gICAgICAgICAgICAvLyBQcmludCBhIGRvdCByZWdhcmRsZXNzIG9mIGhvb2sgc3VjY2Vzc1xuICAgICAgICAgICAgcmV0dXJuIHByaW50RG90KF8sIFwiZmFpbFwiKVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc1NraXApIHtcbiAgICAgICAgICAgIHJldHVybiBwcmludERvdChfLCBcInNraXBcIilcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFbmQpIHtcbiAgICAgICAgICAgIHJldHVybiBfLnByaW50KCkudGhlbihfLnByaW50UmVzdWx0cy5iaW5kKF8pKVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0Vycm9yKSB7XG4gICAgICAgICAgICBpZiAoXy5zdGF0ZS5jb3VudGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF8ucHJpbnQoKS50aGVuKF8ucHJpbnRFcnJvci5iaW5kKF8sIHJlcG9ydCkpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBfLnByaW50RXJyb3IocmVwb3J0KVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICB9XG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG5leHBvcnRzLmRvdCA9IHJlcXVpcmUoXCIuL2RvdFwiKVxuZXhwb3J0cy5zcGVjID0gcmVxdWlyZShcIi4vc3BlY1wiKVxuZXhwb3J0cy50YXAgPSByZXF1aXJlKFwiLi90YXBcIilcbiIsIlwidXNlIHN0cmljdFwiXG5cbi8vIFRoaXMgaXMgYSByZXBvcnRlciB0aGF0IG1pbWljcyBNb2NoYSdzIGBzcGVjYCByZXBvcnRlci5cblxudmFyIFIgPSByZXF1aXJlKFwiLi4vbGliL3JlcG9ydGVyXCIpXG52YXIgYyA9IFIuY29sb3JcblxuZnVuY3Rpb24gaW5kZW50KGxldmVsKSB7XG4gICAgdmFyIHJldCA9IFwiXCJcblxuICAgIHdoaWxlIChsZXZlbC0tKSByZXQgKz0gXCIgIFwiXG4gICAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBnZXROYW1lKGxldmVsLCByZXBvcnQpIHtcbiAgICByZXR1cm4gcmVwb3J0LnBhdGhbbGV2ZWwgLSAxXS5uYW1lXG59XG5cbmZ1bmN0aW9uIHByaW50UmVwb3J0KF8sIHJlcG9ydCwgaW5pdCkge1xuICAgIGlmIChfLnN0YXRlLmxlYXZpbmcpIHtcbiAgICAgICAgXy5zdGF0ZS5sZWF2aW5nID0gZmFsc2VcbiAgICAgICAgcmV0dXJuIF8ucHJpbnQoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBfLnByaW50KGluZGVudChfLnN0YXRlLmxldmVsKSArIGluaXQoKSlcbiAgICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gXy5wcmludChpbmRlbnQoXy5zdGF0ZS5sZXZlbCkgKyBpbml0KCkpXG4gICAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFIub24oXCJzcGVjXCIsIHtcbiAgICBhY2NlcHRzOiBbXCJ3cml0ZVwiLCBcInJlc2V0XCIsIFwiY29sb3JzXCJdLFxuICAgIGNyZWF0ZTogUi5jb25zb2xlUmVwb3J0ZXIsXG4gICAgYmVmb3JlOiBSLnNldENvbG9yLFxuICAgIGFmdGVyOiBSLnVuc2V0Q29sb3IsXG5cbiAgICBpbml0OiBmdW5jdGlvbiAoc3RhdGUpIHtcbiAgICAgICAgc3RhdGUubGV2ZWwgPSAxXG4gICAgICAgIHN0YXRlLmxlYXZpbmcgPSBmYWxzZVxuICAgIH0sXG5cbiAgICByZXBvcnQ6IGZ1bmN0aW9uIChfLCByZXBvcnQpIHtcbiAgICAgICAgaWYgKHJlcG9ydC5pc1N0YXJ0KSB7XG4gICAgICAgICAgICByZXR1cm4gXy5wcmludCgpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzRW50ZXIpIHtcbiAgICAgICAgICAgIHZhciBsZXZlbCA9IF8uc3RhdGUubGV2ZWwrK1xuICAgICAgICAgICAgdmFyIGxhc3QgPSByZXBvcnQucGF0aFtsZXZlbCAtIDFdXG5cbiAgICAgICAgICAgIF8uc3RhdGUubGVhdmluZyA9IGZhbHNlXG4gICAgICAgICAgICBpZiAobGFzdC5pbmRleCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBfLnByaW50KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfLnByaW50KGluZGVudChsZXZlbCkgKyBsYXN0Lm5hbWUpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF8ucHJpbnQoaW5kZW50KGxldmVsKSArIGxhc3QubmFtZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNMZWF2ZSkge1xuICAgICAgICAgICAgXy5zdGF0ZS5sZXZlbC0tXG4gICAgICAgICAgICBfLnN0YXRlLmxlYXZpbmcgPSB0cnVlXG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzUGFzcykge1xuICAgICAgICAgICAgcmV0dXJuIHByaW50UmVwb3J0KF8sIHJlcG9ydCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBzdHIgPVxuICAgICAgICAgICAgICAgICAgICBjKFwiY2hlY2ttYXJrXCIsIFIuc3ltYm9scygpLlBhc3MgKyBcIiBcIikgK1xuICAgICAgICAgICAgICAgICAgICBjKFwicGFzc1wiLCBnZXROYW1lKF8uc3RhdGUubGV2ZWwsIHJlcG9ydCkpXG5cbiAgICAgICAgICAgICAgICB2YXIgc3BlZWQgPSBSLnNwZWVkKHJlcG9ydClcblxuICAgICAgICAgICAgICAgIGlmIChzcGVlZCAhPT0gXCJmYXN0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyICs9IGMoc3BlZWQsIFwiIChcIiArIHJlcG9ydC5kdXJhdGlvbiArIFwibXMpXCIpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0clxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNIb29rIHx8IHJlcG9ydC5pc0ZhaWwpIHtcbiAgICAgICAgICAgIF8ucHVzaEVycm9yKHJlcG9ydClcblxuICAgICAgICAgICAgLy8gRG9uJ3QgcHJpbnQgdGhlIGRlc2NyaXB0aW9uIGxpbmUgb24gY3VtdWxhdGl2ZSBob29rc1xuICAgICAgICAgICAgaWYgKHJlcG9ydC5pc0hvb2sgJiYgKHJlcG9ydC5pc0JlZm9yZUFsbCB8fCByZXBvcnQuaXNBZnRlckFsbCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBwcmludFJlcG9ydChfLCByZXBvcnQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYyhcImZhaWxcIixcbiAgICAgICAgICAgICAgICAgICAgXy5lcnJvcnMubGVuZ3RoICsgXCIpIFwiICsgZ2V0TmFtZShfLnN0YXRlLmxldmVsLCByZXBvcnQpICtcbiAgICAgICAgICAgICAgICAgICAgUi5mb3JtYXRSZXN0KHJlcG9ydCkpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc1NraXApIHtcbiAgICAgICAgICAgIHJldHVybiBwcmludFJlcG9ydChfLCByZXBvcnQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYyhcInNraXBcIiwgXCItIFwiICsgZ2V0TmFtZShfLnN0YXRlLmxldmVsLCByZXBvcnQpKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyZXBvcnQuaXNFbmQpIHJldHVybiBfLnByaW50UmVzdWx0cygpXG4gICAgICAgIGlmIChyZXBvcnQuaXNFcnJvcikgcmV0dXJuIF8ucHJpbnRFcnJvcihyZXBvcnQpXG4gICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICB9LFxufSlcbiIsIlwidXNlIHN0cmljdFwiXG5cbi8vIFRoaXMgaXMgYSBiYXNpYyBUQVAtZ2VuZXJhdGluZyByZXBvcnRlci5cblxudmFyIHBlYWNoID0gcmVxdWlyZShcIi4uL2xpYi91dGlsXCIpLnBlYWNoXG52YXIgUiA9IHJlcXVpcmUoXCIuLi9saWIvcmVwb3J0ZXJcIilcbnZhciBpbnNwZWN0ID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpLmluc3BlY3RcblxuZnVuY3Rpb24gc2hvdWxkQnJlYWsobWluTGVuZ3RoLCBzdHIpIHtcbiAgICByZXR1cm4gc3RyLmxlbmd0aCA+IFIud2luZG93V2lkdGgoKSAtIG1pbkxlbmd0aCB8fCAvXFxyP1xcbnxbOj8tXS8udGVzdChzdHIpXG59XG5cbmZ1bmN0aW9uIHRlbXBsYXRlKF8sIHJlcG9ydCwgdG1wbCwgc2tpcCkge1xuICAgIGlmICghc2tpcCkgXy5zdGF0ZS5jb3VudGVyKytcbiAgICB2YXIgcGF0aCA9IFIuam9pblBhdGgocmVwb3J0KS5yZXBsYWNlKC9cXCQvZywgXCIkJCQkXCIpXG5cbiAgICByZXR1cm4gXy5wcmludChcbiAgICAgICAgdG1wbC5yZXBsYWNlKC8lYy9nLCBfLnN0YXRlLmNvdW50ZXIpXG4gICAgICAgICAgICAucmVwbGFjZSgvJXAvZywgcGF0aCArIFIuZm9ybWF0UmVzdChyZXBvcnQpKSlcbn1cblxuZnVuY3Rpb24gcHJpbnRMaW5lcyhfLCB2YWx1ZSwgc2tpcEZpcnN0KSB7XG4gICAgdmFyIGxpbmVzID0gdmFsdWUuc3BsaXQoL1xccj9cXG4vZylcblxuICAgIGlmIChza2lwRmlyc3QpIGxpbmVzLnNoaWZ0KClcbiAgICByZXR1cm4gcGVhY2gobGluZXMsIGZ1bmN0aW9uIChsaW5lKSB7IHJldHVybiBfLnByaW50KFwiICAgIFwiICsgbGluZSkgfSlcbn1cblxuZnVuY3Rpb24gcHJpbnRSYXcoXywga2V5LCBzdHIpIHtcbiAgICBpZiAoc2hvdWxkQnJlYWsoa2V5Lmxlbmd0aCwgc3RyKSkge1xuICAgICAgICByZXR1cm4gXy5wcmludChcIiAgXCIgKyBrZXkgKyBcIjogfC1cIilcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcHJpbnRMaW5lcyhfLCBzdHIsIGZhbHNlKSB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBfLnByaW50KFwiICBcIiArIGtleSArIFwiOiBcIiArIHN0cilcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHByaW50VmFsdWUoXywga2V5LCB2YWx1ZSkge1xuICAgIHJldHVybiBwcmludFJhdyhfLCBrZXksIGluc3BlY3QodmFsdWUpKVxufVxuXG5mdW5jdGlvbiBwcmludExpbmUocCwgXywgbGluZSkge1xuICAgIHJldHVybiBwLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChsaW5lKSB9KVxufVxuXG5mdW5jdGlvbiBwcmludEVycm9yKF8sIHJlcG9ydCkge1xuICAgIHZhciBlcnIgPSByZXBvcnQuZXJyb3JcblxuICAgIGlmICghKGVyciBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgICAgICByZXR1cm4gcHJpbnRWYWx1ZShfLCBcInZhbHVlXCIsIGVycilcbiAgICB9XG5cbiAgICAvLyBMZXQncyAqbm90KiBkZXBlbmQgb24gdGhlIGNvbnN0cnVjdG9yIGJlaW5nIFRoYWxsaXVtJ3MuLi5cbiAgICBpZiAoZXJyLm5hbWUgIT09IFwiQXNzZXJ0aW9uRXJyb3JcIikge1xuICAgICAgICByZXR1cm4gXy5wcmludChcIiAgc3RhY2s6IHwtXCIpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHByaW50TGluZXMoXywgUi5nZXRTdGFjayhlcnIpLCBmYWxzZSlcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICByZXR1cm4gcHJpbnRWYWx1ZShfLCBcImV4cGVjdGVkXCIsIGVyci5leHBlY3RlZClcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBwcmludFZhbHVlKF8sIFwiYWN0dWFsXCIsIGVyci5hY3R1YWwpIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcHJpbnRSYXcoXywgXCJtZXNzYWdlXCIsIGVyci5tZXNzYWdlKSB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIF8ucHJpbnQoXCIgIHN0YWNrOiB8LVwiKSB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBlcnIubWVzc2FnZVxuXG4gICAgICAgIGVyci5tZXNzYWdlID0gXCJcIlxuICAgICAgICByZXR1cm4gcHJpbnRMaW5lcyhfLCBSLmdldFN0YWNrKGVyciksIHRydWUpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgZXJyLm1lc3NhZ2UgPSBtZXNzYWdlIH0pXG4gICAgfSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSLm9uKFwidGFwXCIsIHtcbiAgICBhY2NlcHRzOiBbXCJ3cml0ZVwiLCBcInJlc2V0XCJdLFxuICAgIGNyZWF0ZTogUi5jb25zb2xlUmVwb3J0ZXIsXG4gICAgaW5pdDogZnVuY3Rpb24gKHN0YXRlKSB7IHN0YXRlLmNvdW50ZXIgPSAwIH0sXG5cbiAgICByZXBvcnQ6IGZ1bmN0aW9uIChfLCByZXBvcnQpIHtcbiAgICAgICAgaWYgKHJlcG9ydC5pc1N0YXJ0KSB7XG4gICAgICAgICAgICByZXR1cm4gXy5wcmludChcIlRBUCB2ZXJzaW9uIDEzXCIpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzRW50ZXIpIHtcbiAgICAgICAgICAgIC8vIFByaW50IGEgbGVhZGluZyBjb21tZW50LCB0byBtYWtlIHNvbWUgVEFQIGZvcm1hdHRlcnMgcHJldHRpZXIuXG4gICAgICAgICAgICByZXR1cm4gdGVtcGxhdGUoXywgcmVwb3J0LCBcIiMgJXBcIiwgdHJ1ZSlcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRlbXBsYXRlKF8sIHJlcG9ydCwgXCJvayAlY1wiKSB9KVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc1Bhc3MpIHtcbiAgICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZShfLCByZXBvcnQsIFwib2sgJWMgJXBcIilcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNGYWlsIHx8IHJlcG9ydC5pc0hvb2spIHtcbiAgICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZShfLCByZXBvcnQsIFwibm90IG9rICVjICVwXCIpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBfLnByaW50KFwiICAtLS1cIikgfSlcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHByaW50RXJyb3IoXywgcmVwb3J0KSB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChcIiAgLi4uXCIpIH0pXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzU2tpcCkge1xuICAgICAgICAgICAgcmV0dXJuIHRlbXBsYXRlKF8sIHJlcG9ydCwgXCJvayAlYyAjIHNraXAgJXBcIilcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFbmQpIHtcbiAgICAgICAgICAgIHZhciBwID0gXy5wcmludChcIjEuLlwiICsgXy5zdGF0ZS5jb3VudGVyKVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChcIiMgdGVzdHMgXCIgKyBfLnRlc3RzKSB9KVxuXG4gICAgICAgICAgICBpZiAoXy5wYXNzKSBwID0gcHJpbnRMaW5lKHAsIF8sIFwiIyBwYXNzIFwiICsgXy5wYXNzKVxuICAgICAgICAgICAgaWYgKF8uZmFpbCkgcCA9IHByaW50TGluZShwLCBfLCBcIiMgZmFpbCBcIiArIF8uZmFpbClcbiAgICAgICAgICAgIGlmIChfLnNraXApIHAgPSBwcmludExpbmUocCwgXywgXCIjIHNraXAgXCIgKyBfLnNraXApXG4gICAgICAgICAgICByZXR1cm4gcHJpbnRMaW5lKHAsIF8sIFwiIyBkdXJhdGlvbiBcIiArIFIuZm9ybWF0VGltZShfLmR1cmF0aW9uKSlcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIF8ucHJpbnQoXCJCYWlsIG91dCFcIilcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIF8ucHJpbnQoXCIgIC0tLVwiKSB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcHJpbnRFcnJvcihfLCByZXBvcnQpIH0pXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBfLnByaW50KFwiICAuLi5cIikgfSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgfVxuICAgIH0sXG59KVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLyoqXG4gKiBUaGlzIGlzIHRoZSBlbnRyeSBwb2ludCBmb3IgdGhlIEJyb3dzZXJpZnkgYnVuZGxlLiBOb3RlIHRoYXQgaXQgKmFsc28qIHdpbGxcbiAqIHJ1biBhcyBwYXJ0IG9mIHRoZSB0ZXN0cyBpbiBOb2RlICh1bmJ1bmRsZWQpLCBhbmQgaXQgdGhlb3JldGljYWxseSBjb3VsZCBiZVxuICogcnVuIGluIE5vZGUgb3IgYSBydW50aW1lIGxpbWl0ZWQgdG8gb25seSBFUzUgc3VwcG9ydCAoZS5nLiBSaGlubywgTmFzaG9ybiwgb3JcbiAqIGVtYmVkZGVkIFY4KSwgc28gZG8gKm5vdCogYXNzdW1lIGJyb3dzZXIgZ2xvYmFscyBhcmUgcHJlc2VudC5cbiAqL1xuXG5leHBvcnRzLnQgPSByZXF1aXJlKFwiLi4vaW5kZXhcIilcbmV4cG9ydHMuYXNzZXJ0ID0gcmVxdWlyZShcIi4uL2Fzc2VydFwiKVxuZXhwb3J0cy5yID0gcmVxdWlyZShcIi4uL3JcIilcbnZhciBkb20gPSByZXF1aXJlKFwiLi4vZG9tXCIpXG5cbmV4cG9ydHMuZG9tID0gZG9tLmNyZWF0ZVxuLy8gaWYgKGdsb2JhbC5kb2N1bWVudCAhPSBudWxsICYmIGdsb2JhbC5kb2N1bWVudC5jdXJyZW50U2NyaXB0ICE9IG51bGwpIHtcbi8vICAgICBkb20uYXV0b2xvYWQoZ2xvYmFsLmRvY3VtZW50LmN1cnJlbnRTY3JpcHQpXG4vLyB9XG5cbnZhciBJbnRlcm5hbCA9IHJlcXVpcmUoXCIuLi9pbnRlcm5hbFwiKVxuXG5leHBvcnRzLnJvb3QgPSBJbnRlcm5hbC5yb290XG5leHBvcnRzLnJlcG9ydHMgPSBJbnRlcm5hbC5yZXBvcnRzXG5leHBvcnRzLmhvb2tFcnJvcnMgPSBJbnRlcm5hbC5ob29rRXJyb3JzXG5leHBvcnRzLmxvY2F0aW9uID0gSW50ZXJuYWwubG9jYXRpb25cblxuLy8gSW4gY2FzZSB0aGUgdXNlciBuZWVkcyB0byBhZGp1c3QgdGhpcyAoZS5nLiBOYXNob3JuICsgY29uc29sZSBvdXRwdXQpLlxudmFyIFNldHRpbmdzID0gcmVxdWlyZShcIi4vc2V0dGluZ3NcIilcblxuZXhwb3J0cy5zZXR0aW5ncyA9IHtcbiAgICB3aW5kb3dXaWR0aDoge1xuICAgICAgICBnZXQ6IFNldHRpbmdzLndpbmRvd1dpZHRoLFxuICAgICAgICBzZXQ6IFNldHRpbmdzLnNldFdpbmRvd1dpZHRoLFxuICAgIH0sXG5cbiAgICBuZXdsaW5lOiB7XG4gICAgICAgIGdldDogU2V0dGluZ3MubmV3bGluZSxcbiAgICAgICAgc2V0OiBTZXR0aW5ncy5zZXROZXdsaW5lLFxuICAgIH0sXG5cbiAgICBzeW1ib2xzOiB7XG4gICAgICAgIGdldDogU2V0dGluZ3Muc3ltYm9scyxcbiAgICAgICAgc2V0OiBTZXR0aW5ncy5zZXRTeW1ib2xzLFxuICAgIH0sXG5cbiAgICBkZWZhdWx0T3B0czoge1xuICAgICAgICBnZXQ6IFNldHRpbmdzLmRlZmF1bHRPcHRzLFxuICAgICAgICBzZXQ6IFNldHRpbmdzLnNldERlZmF1bHRPcHRzLFxuICAgIH0sXG5cbiAgICBjb2xvclN1cHBvcnQ6IHtcbiAgICAgICAgZ2V0OiBTZXR0aW5ncy5Db2xvcnMuZ2V0U3VwcG9ydCxcbiAgICAgICAgc2V0OiBTZXR0aW5ncy5Db2xvcnMuc2V0U3VwcG9ydCxcbiAgICB9LFxufVxuIl19 +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJhc3NlcnQuanMiLCJkb20uanMiLCJpbmRleC5qcyIsImludGVybmFsLmpzIiwibGliL2FwaS9jb21tb24uanMiLCJsaWIvYXBpL3JlZmxlY3QuanMiLCJsaWIvYXBpL3RoYWxsaXVtLmpzIiwibGliL2NvcmUvZmlsdGVyLmpzIiwibGliL2NvcmUvcmVwb3J0cy5qcyIsImxpYi9jb3JlL3Rlc3RzLmpzIiwibGliL2RvbS9pbmRleC5qcyIsImxpYi9kb20vaW5pdGlhbGl6ZS5qcyIsImxpYi9kb20vaW5qZWN0LXN0eWxlcy5qcyIsImxpYi9kb20vaW5qZWN0LmpzIiwibGliL2RvbS9ydW4tdGVzdHMuanMiLCJsaWIvZG9tL3ZpZXcuanMiLCJsaWIvbWV0aG9kcy5qcyIsImxpYi9yZXBsYWNlZC9jb25zb2xlLWJyb3dzZXIuanMiLCJsaWIvcmVwb3J0ZXIvY29uc29sZS1yZXBvcnRlci5qcyIsImxpYi9yZXBvcnRlci9pbmRleC5qcyIsImxpYi9yZXBvcnRlci9vbi5qcyIsImxpYi9yZXBvcnRlci9yZXBvcnRlci5qcyIsImxpYi9yZXBvcnRlci91dGlsLmpzIiwibGliL3NldHRpbmdzLmpzIiwibGliL3V0aWwuanMiLCJub2RlX21vZHVsZXMvYXJyYXktbWFwL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2FycmF5LXJlZHVjZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1hc3NlcnQtdXRpbC9icm93c2VyLWluc3BlY3QuanMiLCJub2RlX21vZHVsZXMvY2xlYW4tYXNzZXJ0LXV0aWwvaW5kZXguanMiLCJub2RlX21vZHVsZXMvY2xlYW4tYXNzZXJ0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2NsZWFuLWFzc2VydC9saWIvZXF1YWwuanMiLCJub2RlX21vZHVsZXMvY2xlYW4tYXNzZXJ0L2xpYi9oYXMta2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1hc3NlcnQvbGliL2hhcy5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1hc3NlcnQvbGliL2luY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2NsZWFuLWFzc2VydC9saWIvdGhyb3dzLmpzIiwibm9kZV9tb2R1bGVzL2NsZWFuLWFzc2VydC9saWIvdHlwZS5qcyIsIm5vZGVfbW9kdWxlcy9jbGVhbi1tYXRjaC9jbGVhbi1tYXRjaC5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9jb252ZXJ0L2RtcC5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9jb252ZXJ0L3htbC5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9kaWZmL2FycmF5LmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL2RpZmYvYmFzZS5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9kaWZmL2NoYXJhY3Rlci5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9kaWZmL2Nzcy5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9kaWZmL2pzb24uanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvZGlmZi9saW5lLmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL2RpZmYvc2VudGVuY2UuanMiLCJub2RlX21vZHVsZXMvZGlmZi9zcmMvZGlmZi93b3JkLmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL3BhdGNoL2FwcGx5LmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL3BhdGNoL2NyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy9wYXRjaC9wYXJzZS5qcyIsIm5vZGVfbW9kdWxlcy9kaWZmL3NyYy91dGlsL2Rpc3RhbmNlLWl0ZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL2RpZmYvc3JjL3V0aWwvcGFyYW1zLmpzIiwibm9kZV9tb2R1bGVzL2ZvcmVhY2gvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaW5kZXhvZi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2ZvcmVhY2guanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaXNBcmd1bWVudHMuanMiLCJub2RlX21vZHVsZXMvdXRpbC1pbnNwZWN0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3V0aWwtaW5zcGVjdC9ub2RlX21vZHVsZXMvanNvbjMvbGliL2pzb24zLmpzIiwici9kb3QuanMiLCJyL2luZGV4LmpzIiwici9zcGVjLmpzIiwici90YXAuanMiLCJsaWIvYnJvd3Nlci1idW5kbGUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4VkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNsUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3psQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdlhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDckpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDclFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNoYUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNqNEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJcInVzZSBzdHJpY3RcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnRcIilcbiIsIlwidXNlIHN0cmljdFwiXG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4vbGliL2RvbVwiKVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLyoqXG4gKiBNYWluIGVudHJ5IHBvaW50LCBmb3IgdGhvc2Ugd2FudGluZyB0byB1c2UgdGhpcyBmcmFtZXdvcmsgd2l0aCB0aGUgY29yZVxuICogYXNzZXJ0aW9ucy5cbiAqL1xudmFyIFRoYWxsaXVtID0gcmVxdWlyZShcIi4vbGliL2FwaS90aGFsbGl1bVwiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBUaGFsbGl1bSgpXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVGhhbGxpdW0gPSByZXF1aXJlKFwiLi9saWIvYXBpL3RoYWxsaXVtXCIpXG52YXIgUmVwb3J0cyA9IHJlcXVpcmUoXCIuL2xpYi9jb3JlL3JlcG9ydHNcIilcbnZhciBIb29rU3RhZ2UgPSBSZXBvcnRzLkhvb2tTdGFnZVxuXG5leHBvcnRzLnJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIG5ldyBUaGFsbGl1bSgpXG59XG5cbmZ1bmN0aW9uIGQoZHVyYXRpb24pIHtcbiAgICBpZiAoZHVyYXRpb24gPT0gbnVsbCkgcmV0dXJuIDEwXG4gICAgaWYgKHR5cGVvZiBkdXJhdGlvbiA9PT0gXCJudW1iZXJcIikgcmV0dXJuIGR1cmF0aW9ufDBcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYGR1cmF0aW9uYCB0byBiZSBhIG51bWJlciBpZiBpdCBleGlzdHNcIilcbn1cblxuZnVuY3Rpb24gcyhzbG93KSB7XG4gICAgaWYgKHNsb3cgPT0gbnVsbCkgcmV0dXJuIDc1XG4gICAgaWYgKHR5cGVvZiBzbG93ID09PSBcIm51bWJlclwiKSByZXR1cm4gc2xvd3wwXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBzbG93YCB0byBiZSBhIG51bWJlciBpZiBpdCBleGlzdHNcIilcbn1cblxuZnVuY3Rpb24gcChwYXRoKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocGF0aCkpIHJldHVybiBwYXRoXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBwYXRoYCB0byBiZSBhbiBhcnJheSBvZiBsb2NhdGlvbnNcIilcbn1cblxuZnVuY3Rpb24gaCh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIHR5cGVvZiB2YWx1ZS5fID09PSBcIm51bWJlclwiKSByZXR1cm4gdmFsdWVcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHZhbHVlYCB0byBiZSBhIGhvb2sgZXJyb3JcIilcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgcmVwb3J0LCBtYWlubHkgZm9yIHRlc3RpbmcgcmVwb3J0ZXJzLlxuICovXG5leHBvcnRzLnJlcG9ydHMgPSB7XG4gICAgc3RhcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBvcnRzLlN0YXJ0KClcbiAgICB9LFxuXG4gICAgZW50ZXI6IGZ1bmN0aW9uIChwYXRoLCBkdXJhdGlvbiwgc2xvdykge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuRW50ZXIocChwYXRoKSwgZChkdXJhdGlvbiksIHMoc2xvdykpXG4gICAgfSxcblxuICAgIGxlYXZlOiBmdW5jdGlvbiAocGF0aCkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuTGVhdmUocChwYXRoKSlcbiAgICB9LFxuXG4gICAgcGFzczogZnVuY3Rpb24gKHBhdGgsIGR1cmF0aW9uLCBzbG93KSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5QYXNzKHAocGF0aCksIGQoZHVyYXRpb24pLCBzKHNsb3cpKVxuICAgIH0sXG5cbiAgICBmYWlsOiBmdW5jdGlvbiAocGF0aCwgdmFsdWUsIGR1cmF0aW9uLCBzbG93LCBpc0ZhaWxhYmxlKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuRmFpbChcbiAgICAgICAgICAgIHAocGF0aCksIHZhbHVlLCBkKGR1cmF0aW9uKSwgcyhzbG93KSxcbiAgICAgICAgICAgICEhaXNGYWlsYWJsZSlcbiAgICB9LFxuXG4gICAgc2tpcDogZnVuY3Rpb24gKHBhdGgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBvcnRzLlNraXAocChwYXRoKSlcbiAgICB9LFxuXG4gICAgZW5kOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5FbmQoKVxuICAgIH0sXG5cbiAgICBlcnJvcjogZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5FcnJvcih2YWx1ZSlcbiAgICB9LFxuXG4gICAgaG9vazogZnVuY3Rpb24gKHBhdGgsIHJvb3RQYXRoLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuSG9vayhwKHBhdGgpLCBwKHJvb3RQYXRoKSwgaCh2YWx1ZSkpXG4gICAgfSxcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgaG9vayBlcnJvciwgbWFpbmx5IGZvciB0ZXN0aW5nIHJlcG9ydGVycy5cbiAqL1xuZXhwb3J0cy5ob29rRXJyb3JzID0ge1xuICAgIGJlZm9yZUFsbDogZnVuY3Rpb24gKGZ1bmMsIHZhbHVlKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwb3J0cy5Ib29rRXJyb3IoSG9va1N0YWdlLkJlZm9yZUFsbCwgZnVuYywgdmFsdWUpXG4gICAgfSxcblxuICAgIGJlZm9yZUVhY2g6IGZ1bmN0aW9uIChmdW5jLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuSG9va0Vycm9yKEhvb2tTdGFnZS5CZWZvcmVFYWNoLCBmdW5jLCB2YWx1ZSlcbiAgICB9LFxuXG4gICAgYWZ0ZXJFYWNoOiBmdW5jdGlvbiAoZnVuYywgdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBvcnRzLkhvb2tFcnJvcihIb29rU3RhZ2UuQWZ0ZXJFYWNoLCBmdW5jLCB2YWx1ZSlcbiAgICB9LFxuXG4gICAgYWZ0ZXJBbGw6IGZ1bmN0aW9uIChmdW5jLCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gbmV3IFJlcG9ydHMuSG9va0Vycm9yKEhvb2tTdGFnZS5BZnRlckFsbCwgZnVuYywgdmFsdWUpXG4gICAgfSxcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGxvY2F0aW9uLCBtYWlubHkgZm9yIHRlc3RpbmcgcmVwb3J0ZXJzLlxuICovXG5leHBvcnRzLmxvY2F0aW9uID0gZnVuY3Rpb24gKG5hbWUsIGluZGV4KSB7XG4gICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBgbmFtZWAgdG8gYmUgYSBzdHJpbmdcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGluZGV4ICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBgaW5kZXhgIHRvIGJlIGEgbnVtYmVyXCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIHtuYW1lOiBuYW1lLCBpbmRleDogaW5kZXh8MH1cbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbmV4cG9ydHMuYWRkSG9vayA9IGZ1bmN0aW9uIChsaXN0LCBjYWxsYmFjaykge1xuICAgIGlmIChsaXN0ICE9IG51bGwpIHtcbiAgICAgICAgbGlzdC5wdXNoKGNhbGxiYWNrKVxuICAgICAgICByZXR1cm4gbGlzdFxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBbY2FsbGJhY2tdXG4gICAgfVxufVxuXG5leHBvcnRzLnJlbW92ZUhvb2sgPSBmdW5jdGlvbiAobGlzdCwgY2FsbGJhY2spIHtcbiAgICBpZiAobGlzdCA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGlmIChsaXN0WzBdID09PSBjYWxsYmFjaykgcmV0dXJuIHVuZGVmaW5lZFxuICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBpbmRleCA9IGxpc3QuaW5kZXhPZihjYWxsYmFjaylcblxuICAgICAgICBpZiAoaW5kZXggPj0gMCkgbGlzdC5zcGxpY2UoaW5kZXgsIDEpXG4gICAgfVxuICAgIHJldHVybiBsaXN0XG59XG5cbmV4cG9ydHMuaGFzSG9vayA9IGZ1bmN0aW9uIChsaXN0LCBjYWxsYmFjaykge1xuICAgIGlmIChsaXN0ID09IG51bGwpIHJldHVybiBmYWxzZVxuICAgIGlmIChsaXN0Lmxlbmd0aCA+IDEpIHJldHVybiBsaXN0LmluZGV4T2YoY2FsbGJhY2spID49IDBcbiAgICByZXR1cm4gbGlzdFswXSA9PT0gY2FsbGJhY2tcbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcbnZhciBUZXN0cyA9IHJlcXVpcmUoXCIuLi9jb3JlL3Rlc3RzXCIpXG52YXIgQ29tbW9uID0gcmVxdWlyZShcIi4vY29tbW9uXCIpXG5cbi8qKlxuICogVGhpcyBjb250YWlucyB0aGUgbG93IGxldmVsLCBtb3JlIGFyY2FuZSB0aGluZ3MgdGhhdCBhcmUgZ2VuZXJhbGx5IG5vdFxuICogaW50ZXJlc3RpbmcgdG8gYW55b25lIG90aGVyIHRoYW4gcGx1Z2luIGRldmVsb3BlcnMuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gUmVmbGVjdFxuZnVuY3Rpb24gUmVmbGVjdCh0ZXN0KSB7XG4gICAgdmFyIHJlZmxlY3QgPSB0ZXN0LnJlZmxlY3RcblxuICAgIGlmIChyZWZsZWN0ICE9IG51bGwpIHJldHVybiByZWZsZWN0XG4gICAgdGVzdC5yZWZsZWN0ID0gdGhpc1xuICAgIHRoaXMuXyA9IHRlc3Rcbn1cblxubWV0aG9kcyhSZWZsZWN0LCB7XG4gICAgLyoqXG4gICAgICogV2hldGhlciBhIHJlcG9ydGVyIHdhcyByZWdpc3RlcmVkLlxuICAgICAqL1xuICAgIGhhc1JlcG9ydGVyOiBmdW5jdGlvbiAocmVwb3J0ZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXBvcnRlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHJlcG9ydGVyYCB0byBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QucmVwb3J0ZXJJZHMuaW5kZXhPZihyZXBvcnRlcikgPj0gMFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSByZXBvcnRlci5cbiAgICAgKi9cbiAgICByZXBvcnRlcjogZnVuY3Rpb24gKHJlcG9ydGVyLCBhcmcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXBvcnRlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHJlcG9ydGVyYCB0byBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcm9vdCA9IHRoaXMuXy5yb290XG5cbiAgICAgICAgaWYgKHJvb3QuY3VycmVudCAhPT0gcm9vdCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmVwb3J0ZXJzIG1heSBvbmx5IGJlIGFkZGVkIHRvIHRoZSByb290XCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAocm9vdC5yZXBvcnRlcklkcy5pbmRleE9mKHJlcG9ydGVyKSA8IDApIHtcbiAgICAgICAgICAgIHJvb3QucmVwb3J0ZXJJZHMucHVzaChyZXBvcnRlcilcbiAgICAgICAgICAgIHJvb3QucmVwb3J0ZXJzLnB1c2gocmVwb3J0ZXIoYXJnKSlcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSByZXBvcnRlci5cbiAgICAgKi9cbiAgICByZW1vdmVSZXBvcnRlcjogZnVuY3Rpb24gKHJlcG9ydGVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcmVwb3J0ZXIgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGByZXBvcnRlcmAgdG8gYmUgYSBmdW5jdGlvblwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJvb3QgPSB0aGlzLl8ucm9vdFxuXG4gICAgICAgIGlmIChyb290LmN1cnJlbnQgIT09IHJvb3QpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlcG9ydGVycyBtYXkgb25seSBiZSBhZGRlZCB0byB0aGUgcm9vdFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGluZGV4ID0gcm9vdC5yZXBvcnRlcklkcy5pbmRleE9mKHJlcG9ydGVyKVxuXG4gICAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgICByb290LnJlcG9ydGVySWRzLnNwbGljZShpbmRleCwgMSlcbiAgICAgICAgICAgIHJvb3QucmVwb3J0ZXJzLnNwbGljZShpbmRleCwgMSlcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnRseSBleGVjdXRpbmcgdGVzdC5cbiAgICAgKi9cbiAgICBnZXQgY3VycmVudCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZWZsZWN0KHRoaXMuXy5yb290LmN1cnJlbnQpXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgcm9vdCB0ZXN0LlxuICAgICAqL1xuICAgIGdldCByb290KCkge1xuICAgICAgICByZXR1cm4gbmV3IFJlZmxlY3QodGhpcy5fLnJvb3QpXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VycmVudCB0b3RhbCB0ZXN0IGNvdW50LlxuICAgICAqL1xuICAgIGdldCBjb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuXy50ZXN0cyA9PSBudWxsID8gMCA6IHRoaXMuXy50ZXN0cy5sZW5ndGhcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IGEgY29weSBvZiB0aGUgY3VycmVudCB0ZXN0IGxpc3QsIGFzIGEgUmVmbGVjdCBjb2xsZWN0aW9uLiBUaGlzIGlzXG4gICAgICogaW50ZW50aW9uYWxseSBhIHNsaWNlLCBzbyB5b3UgY2FuJ3QgbXV0YXRlIHRoZSByZWFsIGNoaWxkcmVuLlxuICAgICAqL1xuICAgIGdldCBjaGlsZHJlbigpIHtcbiAgICAgICAgdmFyIGNoaWxkcmVuID0gW11cblxuICAgICAgICBpZiAodGhpcy5fLnRlc3RzICE9IG51bGwpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fLnRlc3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY2hpbGRyZW5baV0gPSBuZXcgUmVmbGVjdCh0aGlzLl8udGVzdHNbaV0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2hpbGRyZW5cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogSXMgdGhpcyB0ZXN0IHRoZSByb290LCBpLmUuIHRvcCBsZXZlbD9cbiAgICAgKi9cbiAgICBnZXQgaXNSb290KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnBhcmVudCA9PSBudWxsXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIElzIHRoaXMgbG9ja2VkIChpLmUuIHVuc2FmZSB0byBtb2RpZnkpP1xuICAgICAqL1xuICAgIGdldCBpc0xvY2tlZCgpIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fLmxvY2tlZFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGFjdGl2ZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcywgbm90IG5lY2Vzc2FyaWx5IG93biwgb3IgdGhlXG4gICAgICogZnJhbWV3b3JrIGRlZmF1bHQgb2YgMjAwMCwgaWYgbm9uZSB3YXMgc2V0LlxuICAgICAqL1xuICAgIGdldCB0aW1lb3V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnRpbWVvdXQgfHwgVGVzdHMuZGVmYXVsdFRpbWVvdXRcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBhY3RpdmUgc2xvdyB0aHJlc2hvbGQgaW4gbWlsbGlzZWNvbmRzLCBub3QgbmVjZXNzYXJpbHkgb3duLCBvclxuICAgICAqIHRoZSBmcmFtZXdvcmsgZGVmYXVsdCBvZiA3NSwgaWYgbm9uZSB3YXMgc2V0LlxuICAgICAqL1xuICAgIGdldCBzbG93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnNsb3cgfHwgVGVzdHMuZGVmYXVsdFNsb3dcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0ZXN0J3Mgb3duIG1heCBhdHRlbXB0IGNvdW50LiBOb3RlIHRoYXQgdGhpcyBpcyBwYXJhc2l0aWNhbGx5XG4gICAgICogaW5oZXJpdGVkIGZyb20gaXRzIHBhcmVudCwgbm90IGRlbGVnYXRlZC5cbiAgICAgKi9cbiAgICBnZXQgYXR0ZW1wdHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl8uYXR0ZW1wdHNcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHdoZXRoZXIgdGhpcyB0ZXN0IGlzIGZhaWxhYmxlLiBOb3RlIHRoYXQgdGhpcyBpcyBwYXJhc2l0aWNhbGx5XG4gICAgICogaW5oZXJpdGVkIGZyb20gaXRzIHBhcmVudCwgbm90IGRlbGVnYXRlZC5cbiAgICAgKi9cbiAgICBnZXQgaXNGYWlsYWJsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuXy5pc0ZhaWxhYmxlXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGVzdCBuYW1lLCBvciBgdW5kZWZpbmVkYCBpZiBpdCdzIHRoZSByb290IHRlc3QuXG4gICAgICovXG4gICAgZ2V0IG5hbWUoKSB7XG4gICAgICAgIGlmICh0aGlzLl8ucGFyZW50ID09IG51bGwpIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgcmV0dXJuIHRoaXMuXy5uYW1lXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGVzdCBpbmRleCwgb3IgYHVuZGVmaW5lZGAgaWYgaXQncyB0aGUgcm9vdCB0ZXN0LlxuICAgICAqL1xuICAgIGdldCBpbmRleCgpIHtcbiAgICAgICAgaWYgKHRoaXMuXy5wYXJlbnQgPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICByZXR1cm4gdGhpcy5fLmluZGV4XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGVzdCdzIHBhcmVudCBhcyBhIFJlZmxlY3QsIG9yIGB1bmRlZmluZWRgIGlmIGl0J3MgdGhlIHJvb3QgdGVzdC5cbiAgICAgKi9cbiAgICBnZXQgcGFyZW50KCkge1xuICAgICAgICBpZiAodGhpcy5fLnBhcmVudCA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIHJldHVybiBuZXcgUmVmbGVjdCh0aGlzLl8ucGFyZW50KVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBob29rIHRvIGJlIHJ1biBiZWZvcmUgZWFjaCBzdWJ0ZXN0LCBpbmNsdWRpbmcgdGhlaXIgc3VidGVzdHMgYW5kIHNvXG4gICAgICogb24uXG4gICAgICovXG4gICAgYmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5iZWZvcmVFYWNoID0gQ29tbW9uLmFkZEhvb2sodGhpcy5fLmJlZm9yZUVhY2gsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBob29rIHRvIGJlIHJ1biBvbmNlIGJlZm9yZSBhbGwgc3VidGVzdHMgYXJlIHJ1bi5cbiAgICAgKi9cbiAgICBiZWZvcmVBbGw6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fLmJlZm9yZUFsbCA9IENvbW1vbi5hZGRIb29rKHRoaXMuXy5iZWZvcmVBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgIC8qKlxuICAgICogQWRkIGEgaG9vayB0byBiZSBydW4gYWZ0ZXIgZWFjaCBzdWJ0ZXN0LCBpbmNsdWRpbmcgdGhlaXIgc3VidGVzdHMgYW5kIHNvXG4gICAgKiBvbi5cbiAgICAqL1xuICAgIGFmdGVyOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5hZnRlckVhY2ggPSBDb21tb24uYWRkSG9vayh0aGlzLl8uYWZ0ZXJFYWNoLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQWRkIGEgaG9vayB0byBiZSBydW4gb25jZSBhZnRlciBhbGwgc3VidGVzdHMgYXJlIHJ1bi5cbiAgICAgKi9cbiAgICBhZnRlckFsbDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl8uYWZ0ZXJBbGwgPSBDb21tb24uYWRkSG9vayh0aGlzLl8uYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5iZWZvcmVgIG9yIGByZWZsZWN0LmJlZm9yZWAuXG4gICAgICovXG4gICAgaGFzQmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBDb21tb24uaGFzSG9vayh0aGlzLl8uYmVmb3JlRWFjaCwgY2FsbGJhY2spXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhIGhvb2sgcHJldmlvdXNseSBhZGRlZCB3aXRoIGB0LmJlZm9yZUFsbGAgb3IgYHJlZmxlY3QuYmVmb3JlQWxsYC5cbiAgICAgKi9cbiAgICBoYXNCZWZvcmVBbGw6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIENvbW1vbi5oYXNIb29rKHRoaXMuXy5iZWZvcmVBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5hZnRlcmAgb3JgcmVmbGVjdC5hZnRlcmAuXG4gICAgICovXG4gICAgaGFzQWZ0ZXI6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIENvbW1vbi5oYXNIb29rKHRoaXMuXy5hZnRlckVhY2gsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5hZnRlckFsbGAgb3IgYHJlZmxlY3QuYWZ0ZXJBbGxgLlxuICAgICAqL1xuICAgIGhhc0FmdGVyQWxsOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBDb21tb24uaGFzSG9vayh0aGlzLl8uYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5iZWZvcmVgIG9yIGByZWZsZWN0LmJlZm9yZWAuXG4gICAgICovXG4gICAgcmVtb3ZlQmVmb3JlOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5iZWZvcmVFYWNoID0gQ29tbW9uLnJlbW92ZUhvb2sodGhpcy5fLmJlZm9yZUVhY2gsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYSBob29rIHByZXZpb3VzbHkgYWRkZWQgd2l0aCBgdC5iZWZvcmVBbGxgIG9yIGByZWZsZWN0LmJlZm9yZUFsbGAuXG4gICAgICovXG4gICAgcmVtb3ZlQmVmb3JlQWxsOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5iZWZvcmVBbGwgPSBDb21tb24ucmVtb3ZlSG9vayh0aGlzLl8uYmVmb3JlQWxsLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgaG9vayBwcmV2aW91c2x5IGFkZGVkIHdpdGggYHQuYWZ0ZXJgIG9yYHJlZmxlY3QuYWZ0ZXJgLlxuICAgICAqL1xuICAgIHJlbW92ZUFmdGVyOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuXy5hZnRlckVhY2ggPSBDb21tb24ucmVtb3ZlSG9vayh0aGlzLl8uYWZ0ZXJFYWNoLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgaG9vayBwcmV2aW91c2x5IGFkZGVkIHdpdGggYHQuYWZ0ZXJBbGxgIG9yIGByZWZsZWN0LmFmdGVyQWxsYC5cbiAgICAgKi9cbiAgICByZW1vdmVBZnRlckFsbDogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl8uYWZ0ZXJBbGwgPSBDb21tb24ucmVtb3ZlSG9vayh0aGlzLl8uYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBibG9jayBvciBpbmxpbmUgdGVzdC5cbiAgICAgKi9cbiAgICB0ZXN0OiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYG5hbWVgIHRvIGJlIGEgc3RyaW5nXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgVGVzdHMuYWRkTm9ybWFsKHRoaXMuXy5yb290LmN1cnJlbnQsIG5hbWUsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSBza2lwcGVkIGJsb2NrIG9yIGlubGluZSB0ZXN0LlxuICAgICAqL1xuICAgIHRlc3RTa2lwOiBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYG5hbWVgIHRvIGJlIGEgc3RyaW5nXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgVGVzdHMuYWRkU2tpcHBlZCh0aGlzLl8ucm9vdC5jdXJyZW50LCBuYW1lKVxuICAgIH0sXG59KVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIG1ldGhvZHMgPSByZXF1aXJlKFwiLi4vbWV0aG9kc1wiKVxudmFyIFRlc3RzID0gcmVxdWlyZShcIi4uL2NvcmUvdGVzdHNcIilcbnZhciBGaWx0ZXIgPSByZXF1aXJlKFwiLi4vY29yZS9maWx0ZXJcIilcbnZhciBDb21tb24gPSByZXF1aXJlKFwiLi9jb21tb25cIilcbnZhciBSZWZsZWN0ID0gcmVxdWlyZShcIi4vcmVmbGVjdFwiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IFRoYWxsaXVtXG5mdW5jdGlvbiBUaGFsbGl1bSgpIHtcbiAgICB0aGlzLl8gPSBUZXN0cy5jcmVhdGVSb290KClcbn1cblxubWV0aG9kcyhUaGFsbGl1bSwge1xuICAgIC8qKlxuICAgICAqIENhbGwgYSBwbHVnaW4gYW5kIHJldHVybiB0aGUgcmVzdWx0LiBUaGUgcGx1Z2luIGlzIGNhbGxlZCB3aXRoIGEgUmVmbGVjdFxuICAgICAqIGluc3RhbmNlIGZvciBhY2Nlc3MgdG8gcGxlbnR5IG9mIHBvdGVudGlhbGx5IHVzZWZ1bCBpbnRlcm5hbCBkZXRhaWxzLlxuICAgICAqL1xuICAgIGNhbGw6IGZ1bmN0aW9uIChwbHVnaW4sIGFyZykge1xuICAgICAgICB2YXIgcmVmbGVjdCA9IG5ldyBSZWZsZWN0KHRoaXMuXy5yb290LmN1cnJlbnQpXG5cbiAgICAgICAgcmV0dXJuIHBsdWdpbi5jYWxsKHJlZmxlY3QsIHJlZmxlY3QsIGFyZylcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogV2hpdGVsaXN0IHNwZWNpZmljIHRlc3RzLCB1c2luZyBhcnJheS1iYXNlZCBzZWxlY3RvcnMgd2hlcmUgZWFjaCBlbnRyeVxuICAgICAqIGlzIGVpdGhlciBhIHN0cmluZyBvciByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICovXG4gICAgb25seTogZnVuY3Rpb24gKC8qIC4uLnNlbGVjdG9ycyAqLykge1xuICAgICAgICB0aGlzLl8ucm9vdC5jdXJyZW50Lm9ubHkgPSBGaWx0ZXIuY3JlYXRlLmFwcGx5KHVuZGVmaW5lZCwgYXJndW1lbnRzKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSByZXBvcnRlci5cbiAgICAgKi9cbiAgICByZXBvcnRlcjogZnVuY3Rpb24gKHJlcG9ydGVyLCBhcmcpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXBvcnRlciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgYHJlcG9ydGVyYCB0byBiZSBhIGZ1bmN0aW9uLlwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJvb3QgPSB0aGlzLl8ucm9vdFxuXG4gICAgICAgIGlmIChyb290LmN1cnJlbnQgIT09IHJvb3QpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlcG9ydGVycyBtYXkgb25seSBiZSBhZGRlZCB0byB0aGUgcm9vdC5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXN1bHQgPSByZXBvcnRlcihhcmcpXG5cbiAgICAgICAgLy8gRG9uJ3QgYXNzdW1lIGl0J3MgYSBmdW5jdGlvbi4gVmVyaWZ5IGl0IGFjdHVhbGx5IGlzLCBzbyB3ZSBkb24ndCBoYXZlXG4gICAgICAgIC8vIGluZXhwbGljYWJsZSB0eXBlIGVycm9ycyBpbnRlcm5hbGx5IGFmdGVyIGl0J3MgaW52b2tlZCwgYW5kIHNvIHVzZXJzXG4gICAgICAgIC8vIHdvbid0IGdldCB0b28gY29uZnVzZWQuXG4gICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJFeHBlY3RlZCBgcmVwb3J0ZXJgIHRvIHJldHVybiBhIGZ1bmN0aW9uLiBDaGVjayB3aXRoIHRoZSBcIiArXG4gICAgICAgICAgICAgICAgXCJyZXBvcnRlcidzIGF1dGhvciwgYW5kIGhhdmUgdGhlbSBmaXggdGhlaXIgcmVwb3J0ZXIuXCIpXG4gICAgICAgIH1cblxuICAgICAgICByb290LnJlcG9ydGVyID0gcmVzdWx0XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIHRoaXMgaGFzIGEgcmVwb3J0ZXIuXG4gICAgICovXG4gICAgZ2V0IGhhc1JlcG9ydGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QucmVwb3J0ZXIgIT0gbnVsbFxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgdGltZW91dC4gMCBtZWFucyBpbmhlcml0IHRoZSBwYXJlbnQncywgYW5kIGBJbmZpbml0eWBcbiAgICAgKiBtZWFucyBpdCdzIGRpc2FibGVkLlxuICAgICAqL1xuICAgIGdldCB0aW1lb3V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QuY3VycmVudC50aW1lb3V0IHx8IFRlc3RzLmRlZmF1bHRUaW1lb3V0XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgdGltZW91dCBpbiBtaWxsaXNlY29uZHMsIHJvdW5kaW5nIG5lZ2F0aXZlcyB0byAwLiBTZXR0aW5nIHRoZVxuICAgICAqIHRpbWVvdXQgdG8gMCBtZWFucyB0byBpbmhlcml0IHRoZSBwYXJlbnQgdGltZW91dCwgYW5kIHNldHRpbmcgaXQgdG9cbiAgICAgKiBgSW5maW5pdHlgIGRpc2FibGVzIGl0LlxuICAgICAqL1xuICAgIHNldCB0aW1lb3V0KHRpbWVvdXQpIHtcbiAgICAgICAgdGhpcy5fLnJvb3QuY3VycmVudC50aW1lb3V0ID0gTWF0aC5mbG9vcihNYXRoLm1heCgrdGltZW91dCwgMCkpXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VycmVudCBzbG93IHRocmVzaG9sZC4gMCBtZWFucyBpbmhlcml0IHRoZSBwYXJlbnQncywgYW5kXG4gICAgICogYEluZmluaXR5YCBtZWFucyBpdCdzIGRpc2FibGVkLlxuICAgICAqL1xuICAgIGdldCBzbG93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QuY3VycmVudC5zbG93IHx8IFRlc3RzLmRlZmF1bHRTbG93XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgc2xvdyB0aHJlc2hvbGQgaW4gbWlsbGlzZWNvbmRzLCByb3VuZGluZyBuZWdhdGl2ZXMgdG8gMC4gU2V0dGluZ1xuICAgICAqIHRoZSB0aW1lb3V0IHRvIDAgbWVhbnMgdG8gaW5oZXJpdCB0aGUgcGFyZW50IHRocmVzaG9sZCwgYW5kIHNldHRpbmcgaXQgdG9cbiAgICAgKiBgSW5maW5pdHlgIGRpc2FibGVzIGl0LlxuICAgICAqL1xuICAgIHNldCBzbG93KHNsb3cpIHtcbiAgICAgICAgdGhpcy5fLnJvb3QuY3VycmVudC5zbG93ID0gTWF0aC5mbG9vcihNYXRoLm1heCgrc2xvdywgMCkpXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VycmVudCBhdHRlbXB0IGNvdW50LiBgMGAgbWVhbnMgaW5oZXJpdCB0aGUgcGFyZW50J3MuXG4gICAgICovXG4gICAgZ2V0IGF0dGVtcHRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fLnJvb3QuY3VycmVudC5hdHRlbXB0c1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIG51bWJlciBvZiBhdHRlbXB0cyBhbGxvd2VkLCByb3VuZGluZyBuZWdhdGl2ZXMgdG8gMC4gU2V0dGluZyB0aGVcbiAgICAgKiBjb3VudCB0byBgMGAgbWVhbnMgdG8gaW5oZXJpdCB0aGUgcGFyZW50IHJldHJ5IGNvdW50LlxuICAgICAqL1xuICAgIHNldCBhdHRlbXB0cyhhdHRlbXB0cykge1xuICAgICAgICAvLyBUaGlzIGlzIGRvbmUgZGlmZmVyZW50bHkgdG8gYXZvaWQgYSBtYXNzaXZlIHBlcmZvcm1hbmNlIHBlbmFsdHkuXG4gICAgICAgIHZhciBjYWxjdWxhdGVkID0gTWF0aC5mbG9vcihNYXRoLm1heChhdHRlbXB0cywgMCkpXG4gICAgICAgIHZhciB0ZXN0ID0gdGhpcy5fLnJvb3QuY3VycmVudFxuXG4gICAgICAgIHRlc3QuYXR0ZW1wdHMgPSBjYWxjdWxhdGVkIHx8IHRlc3QucGFyZW50LmF0dGVtcHRzXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEdldCB3aGV0aGVyIHRoaXMgdGVzdCBpcyBmYWlsYWJsZS5cbiAgICAgKi9cbiAgICBnZXQgaXNGYWlsYWJsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuXy5yb290LmN1cnJlbnQuaXNGYWlsYWJsZVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgd2hldGhlciB0aGlzIHRlc3QgaXMgZmFpbGFibGUuXG4gICAgICovXG4gICAgc2V0IGlzRmFpbGFibGUoaXNGYWlsYWJsZSkge1xuICAgICAgICB0aGlzLl8ucm9vdC5jdXJyZW50LmlzRmFpbGFibGUgPSAhIWlzRmFpbGFibGVcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUnVuIHRoZSB0ZXN0cyAob3IgdGhlIHRlc3QncyB0ZXN0cyBpZiBpdCdzIG5vdCBhIGJhc2UgaW5zdGFuY2UpLlxuICAgICAqL1xuICAgIHJ1bjogZnVuY3Rpb24gKG9wdHMpIHtcbiAgICAgICAgaWYgKHRoaXMuXy5yb290ICE9PSB0aGlzLl8pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBcIk9ubHkgdGhlIHJvb3QgdGVzdCBjYW4gYmUgcnVuIC0gSWYgeW91IG9ubHkgd2FudCB0byBydW4gYSBcIiArXG4gICAgICAgICAgICAgICAgXCJzdWJ0ZXN0LCB1c2UgYHQub25seShbXFxcInNlbGVjdG9yMVxcXCIsIC4uLl0pYCBpbnN0ZWFkLlwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuXy5sb2NrZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IHJ1biB3aGlsZSB0ZXN0cyBhcmUgYWxyZWFkeSBydW5uaW5nLlwiKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFRlc3RzLnJ1blRlc3QodGhpcy5fLCBvcHRzKVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYSB0ZXN0LlxuICAgICAqL1xuICAgIHRlc3Q6IGZ1bmN0aW9uIChuYW1lLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBgbmFtZWAgdG8gYmUgYSBzdHJpbmdcIilcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICBUZXN0cy5hZGROb3JtYWwodGhpcy5fLnJvb3QuY3VycmVudCwgbmFtZSwgY2FsbGJhY2spXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEFkZCBhIHNraXBwZWQgdGVzdC5cbiAgICAgKi9cbiAgICB0ZXN0U2tpcDogZnVuY3Rpb24gKG5hbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGBuYW1lYCB0byBiZSBhIHN0cmluZ1wiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIFRlc3RzLmFkZFNraXBwZWQodGhpcy5fLnJvb3QuY3VycmVudCwgbmFtZSlcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2xlYXIgYWxsIGV4aXN0aW5nIHRlc3RzLlxuICAgICAqL1xuICAgIGNsZWFyVGVzdHM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuXy5yb290ICE9PSB0aGlzLl8pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRlc3RzIG1heSBvbmx5IGJlIGNsZWFyZWQgYXQgdGhlIHJvb3QuXCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5fLmxvY2tlZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgY2xlYXIgdGVzdHMgd2hpbGUgdGhleSBhcmUgcnVubmluZy5cIilcbiAgICAgICAgfVxuXG4gICAgICAgIFRlc3RzLmNsZWFyVGVzdHModGhpcy5fKVxuICAgIH0sXG5cbiAgICBiZWZvcmU6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHRlc3QgPSB0aGlzLl8ucm9vdC5jdXJyZW50XG5cbiAgICAgICAgdGVzdC5iZWZvcmVFYWNoID0gQ29tbW9uLmFkZEhvb2sodGVzdC5iZWZvcmVFYWNoLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgYmVmb3JlQWxsOiBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0ZXN0ID0gdGhpcy5fLnJvb3QuY3VycmVudFxuXG4gICAgICAgIHRlc3QuYmVmb3JlQWxsID0gQ29tbW9uLmFkZEhvb2sodGVzdC5iZWZvcmVBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG5cbiAgICBhZnRlcjogZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgdGVzdCA9IHRoaXMuXy5yb290LmN1cnJlbnRcblxuICAgICAgICB0ZXN0LmFmdGVyRWFjaCA9IENvbW1vbi5hZGRIb29rKHRlc3QuYWZ0ZXJFYWNoLCBjYWxsYmFjaylcbiAgICB9LFxuXG4gICAgYWZ0ZXJBbGw6IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBjYWxsYmFjayB0byBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHRlc3QgPSB0aGlzLl8ucm9vdC5jdXJyZW50XG5cbiAgICAgICAgdGVzdC5hZnRlckFsbCA9IENvbW1vbi5hZGRIb29rKHRlc3QuYWZ0ZXJBbGwsIGNhbGxiYWNrKVxuICAgIH0sXG59KVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLyoqXG4gKiBUaGUgZmlsdGVyIGlzIGFjdHVhbGx5IHN0b3JlZCBhcyBhIHRyZWUgZm9yIGZhc3RlciBsb29rdXAgdGltZXMgd2hlbiB0aGVyZVxuICogYXJlIG11bHRpcGxlIHNlbGVjdG9ycy4gT2JqZWN0cyBjYW4ndCBiZSB1c2VkIGZvciB0aGUgbm9kZXMsIHdoZXJlIGtleXNcbiAqIHJlcHJlc2VudCB2YWx1ZXMgYW5kIHZhbHVlcyByZXByZXNlbnQgY2hpbGRyZW4sIGJlY2F1c2UgcmVndWxhciBleHByZXNzaW9uc1xuICogYXJlbid0IHBvc3NpYmxlIHRvIHVzZS5cbiAqL1xuXG5mdW5jdGlvbiBpc0VxdWl2YWxlbnQoZW50cnksIGl0ZW0pIHtcbiAgICBpZiAodHlwZW9mIGVudHJ5ID09PSBcInN0cmluZ1wiICYmIHR5cGVvZiBpdGVtID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHJldHVybiBlbnRyeSA9PT0gaXRlbVxuICAgIH0gZWxzZSBpZiAoZW50cnkgaW5zdGFuY2VvZiBSZWdFeHAgJiYgaXRlbSBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICByZXR1cm4gZW50cnkudG9TdHJpbmcoKSA9PT0gaXRlbS50b1N0cmluZygpXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYXRjaGVzKGVudHJ5LCBpdGVtKSB7XG4gICAgaWYgKHR5cGVvZiBlbnRyeSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICByZXR1cm4gZW50cnkgPT09IGl0ZW1cbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZW50cnkudGVzdChpdGVtKVxuICAgIH1cbn1cblxuZnVuY3Rpb24gRmlsdGVyKHZhbHVlKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlXG4gICAgdGhpcy5jaGlsZHJlbiA9IHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBmaW5kRXF1aXZhbGVudChub2RlLCBlbnRyeSkge1xuICAgIGlmIChub2RlLmNoaWxkcmVuID09IG51bGwpIHJldHVybiB1bmRlZmluZWRcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgY2hpbGQgPSBub2RlLmNoaWxkcmVuW2ldXG5cbiAgICAgICAgaWYgKGlzRXF1aXZhbGVudChjaGlsZC52YWx1ZSwgZW50cnkpKSByZXR1cm4gY2hpbGRcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIGZpbmRNYXRjaGVzKG5vZGUsIGVudHJ5KSB7XG4gICAgaWYgKG5vZGUuY2hpbGRyZW4gPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjaGlsZCA9IG5vZGUuY2hpbGRyZW5baV1cblxuICAgICAgICBpZiAobWF0Y2hlcyhjaGlsZC52YWx1ZSwgZW50cnkpKSByZXR1cm4gY2hpbGRcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogQ3JlYXRlIGEgZmlsdGVyIGZyb20gYSBudW1iZXIgb2Ygc2VsZWN0b3JzXG4gKi9cbmV4cG9ydHMuY3JlYXRlID0gZnVuY3Rpb24gKC8qIC4uLnNlbGVjdG9ycyAqLykge1xuICAgIHZhciBmaWx0ZXIgPSBuZXcgRmlsdGVyKClcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBzZWxlY3RvciA9IGFyZ3VtZW50c1tpXVxuXG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShzZWxlY3RvcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJFeHBlY3RlZCBzZWxlY3RvciBcIiArIGkgKyBcIiB0byBiZSBhbiBhcnJheVwiKVxuICAgICAgICB9XG5cbiAgICAgICAgZmlsdGVyQWRkU2luZ2xlKGZpbHRlciwgc2VsZWN0b3IsIGkpXG4gICAgfVxuXG4gICAgcmV0dXJuIGZpbHRlclxufVxuXG5mdW5jdGlvbiBmaWx0ZXJBZGRTaW5nbGUobm9kZSwgc2VsZWN0b3IsIGluZGV4KSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWxlY3Rvci5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgZW50cnkgPSBzZWxlY3RvcltpXVxuXG4gICAgICAgIC8vIFN0cmluZ3MgYW5kIHJlZ3VsYXIgZXhwcmVzc2lvbnMgYXJlIHRoZSBvbmx5IHRoaW5ncyBhbGxvd2VkLlxuICAgICAgICBpZiAodHlwZW9mIGVudHJ5ICE9PSBcInN0cmluZ1wiICYmICEoZW50cnkgaW5zdGFuY2VvZiBSZWdFeHApKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgICAgIFwiU2VsZWN0b3IgXCIgKyBpbmRleCArIFwiIG11c3QgY29uc2lzdCBvZiBvbmx5IHN0cmluZ3MgYW5kL29yIFwiICtcbiAgICAgICAgICAgICAgICBcInJlZ3VsYXIgZXhwcmVzc2lvbnNcIilcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjaGlsZCA9IGZpbmRFcXVpdmFsZW50KG5vZGUsIGVudHJ5KVxuXG4gICAgICAgIGlmIChjaGlsZCA9PSBudWxsKSB7XG4gICAgICAgICAgICBjaGlsZCA9IG5ldyBGaWx0ZXIoZW50cnkpXG4gICAgICAgICAgICBpZiAobm9kZS5jaGlsZHJlbiA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IFtjaGlsZF1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbi5wdXNoKGNoaWxkKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbm9kZSA9IGNoaWxkXG4gICAgfVxufVxuXG5leHBvcnRzLnRlc3QgPSBmdW5jdGlvbiAoZmlsdGVyLCBwYXRoKSB7XG4gICAgdmFyIGxlbmd0aCA9IHBhdGgubGVuZ3RoXG5cbiAgICB3aGlsZSAobGVuZ3RoICE9PSAwKSB7XG4gICAgICAgIGZpbHRlciA9IGZpbmRNYXRjaGVzKGZpbHRlciwgcGF0aFstLWxlbmd0aF0pXG4gICAgICAgIGlmIChmaWx0ZXIgPT0gbnVsbCkgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcblxuLyoqXG4gKiBBbGwgdGhlIHJlcG9ydCB0eXBlcy4gVGhlIG9ubHkgcmVhc29uIHRoZXJlIGFyZSBtb3JlIHRoYW4gdHdvIHR5cGVzIChub3JtYWxcbiAqIGFuZCBob29rKSBpcyBmb3IgdGhlIHVzZXIncyBiZW5lZml0IChkZXYgdG9vbHMsIGB1dGlsLmluc3BlY3RgLCBldGMuKVxuICovXG5cbnZhciBUeXBlcyA9IGV4cG9ydHMuVHlwZXMgPSBPYmplY3QuZnJlZXplKHtcbiAgICBTdGFydDogMCxcbiAgICBFbnRlcjogMSxcbiAgICBMZWF2ZTogMixcbiAgICBQYXNzOiAzLFxuICAgIEZhaWw6IDQsXG4gICAgU2tpcDogNSxcbiAgICBFbmQ6IDYsXG4gICAgRXJyb3I6IDcsXG5cbiAgICAvLyBOb3RlIHRoYXQgYEhvb2tgIGlzIGFjdHVhbGx5IGEgYml0IGZsYWcsIHRvIHNhdmUgc29tZSBzcGFjZSAoYW5kIHRvXG4gICAgLy8gc2ltcGxpZnkgdGhlIHR5cGUgcmVwcmVzZW50YXRpb24pLlxuICAgIEhvb2s6IDgsXG59KVxuXG52YXIgSG9va1N0YWdlID0gZXhwb3J0cy5Ib29rU3RhZ2UgPSBPYmplY3QuZnJlZXplKHtcbiAgICBCZWZvcmVBbGw6IFR5cGVzLkhvb2sgfCAwLFxuICAgIEJlZm9yZUVhY2g6IFR5cGVzLkhvb2sgfCAxLFxuICAgIEFmdGVyRWFjaDogVHlwZXMuSG9vayB8IDIsXG4gICAgQWZ0ZXJBbGw6IFR5cGVzLkhvb2sgfCAzLFxufSlcblxuZXhwb3J0cy5SZXBvcnQgPSBSZXBvcnRcbmZ1bmN0aW9uIFJlcG9ydCh0eXBlKSB7XG4gICAgdGhpcy5fID0gdHlwZVxufVxuXG4vLyBBdm9pZCBhIHJlY3Vyc2l2ZSBjYWxsIHdoZW4gYGluc3BlY3RgaW5nIGEgcmVzdWx0IHdoaWxlIHN0aWxsIGtlZXBpbmcgaXRcbi8vIHN0eWxlZCBsaWtlIGl0IHdvdWxkIGJlIG5vcm1hbGx5LiBFYWNoIHR5cGUgdXNlcyBhIG5hbWVkIHNpbmdsZXRvbiBmYWN0b3J5IHRvXG4vLyBlbnN1cmUgZW5naW5lcyBzaG93IHRoZSBjb3JyZWN0IGBuYW1lYC9gZGlzcGxheU5hbWVgIGZvciB0aGUgdHlwZS5cbmZ1bmN0aW9uIGluaXRJbnNwZWN0KGluc3BlY3QsIHJlcG9ydCkge1xuICAgIHZhciB0eXBlID0gcmVwb3J0Ll9cblxuICAgIGlmICh0eXBlICYgVHlwZXMuSG9vaykge1xuICAgICAgICBpbnNwZWN0LnN0YWdlID0gcmVwb3J0LnN0YWdlXG4gICAgfVxuXG4gICAgaWYgKHR5cGUgIT09IFR5cGVzLlN0YXJ0ICYmXG4gICAgICAgICAgICB0eXBlICE9PSBUeXBlcy5FbmQgJiZcbiAgICAgICAgICAgIHR5cGUgIT09IFR5cGVzLkVycm9yKSB7XG4gICAgICAgIGluc3BlY3QucGF0aCA9IHJlcG9ydC5wYXRoXG4gICAgfVxuXG4gICAgaWYgKHR5cGUgJiBUeXBlcy5Ib29rKSB7XG4gICAgICAgIGluc3BlY3Qucm9vdFBhdGggPSByZXBvcnQucm9vdFBhdGhcbiAgICB9XG5cbiAgICAvLyBPbmx5IGFkZCB0aGUgcmVsZXZhbnQgcHJvcGVydGllc1xuICAgIGlmICh0eXBlID09PSBUeXBlcy5GYWlsIHx8XG4gICAgICAgICAgICB0eXBlID09PSBUeXBlcy5FcnJvciB8fFxuICAgICAgICAgICAgdHlwZSAmIFR5cGVzLkhvb2spIHtcbiAgICAgICAgaW5zcGVjdC52YWx1ZSA9IHJlcG9ydC52YWx1ZVxuICAgIH1cblxuICAgIGlmICh0eXBlID09PSBUeXBlcy5FbnRlciB8fFxuICAgICAgICAgICAgdHlwZSA9PT0gVHlwZXMuUGFzcyB8fFxuICAgICAgICAgICAgdHlwZSA9PT0gVHlwZXMuRmFpbCkge1xuICAgICAgICBpbnNwZWN0LmR1cmF0aW9uID0gcmVwb3J0LmR1cmF0aW9uXG4gICAgICAgIGluc3BlY3Quc2xvdyA9IHJlcG9ydC5zbG93XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09IFR5cGVzLkZhaWwpIHtcbiAgICAgICAgaW5zcGVjdC5pc0ZhaWxhYmxlID0gcmVwb3J0LmlzRmFpbGFibGVcbiAgICB9XG59XG5cbm1ldGhvZHMoUmVwb3J0LCB7XG4gICAgLy8gVGhlIHJlcG9ydCB0eXBlc1xuICAgIGdldCBpc1N0YXJ0KCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5TdGFydCB9LFxuICAgIGdldCBpc0VudGVyKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5FbnRlciB9LFxuICAgIGdldCBpc0xlYXZlKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5MZWF2ZSB9LFxuICAgIGdldCBpc1Bhc3MoKSB7IHJldHVybiB0aGlzLl8gPT09IFR5cGVzLlBhc3MgfSxcbiAgICBnZXQgaXNGYWlsKCkgeyByZXR1cm4gdGhpcy5fID09PSBUeXBlcy5GYWlsIH0sXG4gICAgZ2V0IGlzU2tpcCgpIHsgcmV0dXJuIHRoaXMuXyA9PT0gVHlwZXMuU2tpcCB9LFxuICAgIGdldCBpc0VuZCgpIHsgcmV0dXJuIHRoaXMuXyA9PT0gVHlwZXMuRW5kIH0sXG4gICAgZ2V0IGlzRXJyb3IoKSB7IHJldHVybiB0aGlzLl8gPT09IFR5cGVzLkVycm9yIH0sXG4gICAgZ2V0IGlzSG9vaygpIHsgcmV0dXJuICh0aGlzLl8gJiBUeXBlcy5Ib29rKSAhPT0gMCB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IGEgc3RyaW5naWZpZWQgZGVzY3JpcHRpb24gb2YgdGhlIHR5cGUuXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHN3aXRjaCAodGhpcy5fKSB7XG4gICAgICAgIGNhc2UgVHlwZXMuU3RhcnQ6IHJldHVybiBcInN0YXJ0XCJcbiAgICAgICAgY2FzZSBUeXBlcy5FbnRlcjogcmV0dXJuIFwiZW50ZXJcIlxuICAgICAgICBjYXNlIFR5cGVzLkxlYXZlOiByZXR1cm4gXCJsZWF2ZVwiXG4gICAgICAgIGNhc2UgVHlwZXMuUGFzczogcmV0dXJuIFwicGFzc1wiXG4gICAgICAgIGNhc2UgVHlwZXMuRmFpbDogcmV0dXJuIFwiZmFpbFwiXG4gICAgICAgIGNhc2UgVHlwZXMuU2tpcDogcmV0dXJuIFwic2tpcFwiXG4gICAgICAgIGNhc2UgVHlwZXMuRW5kOiByZXR1cm4gXCJlbmRcIlxuICAgICAgICBjYXNlIFR5cGVzLkVycm9yOiByZXR1cm4gXCJlcnJvclwiXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAodGhpcy5fICYgVHlwZXMuSG9vaykgcmV0dXJuIFwiaG9va1wiXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ1bnJlYWNoYWJsZVwiKVxuICAgICAgICB9XG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuU3RhcnQgPSBTdGFydFJlcG9ydFxuZnVuY3Rpb24gU3RhcnRSZXBvcnQoKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuU3RhcnQpXG59XG5tZXRob2RzKFN0YXJ0UmVwb3J0LCBSZXBvcnQsIHtcbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gUmVwb3J0KHJlcG9ydCkge1xuICAgICAgICAgICAgaW5pdEluc3BlY3QodGhpcywgcmVwb3J0KVxuICAgICAgICB9KHRoaXMpXG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuRW50ZXIgPSBFbnRlclJlcG9ydFxuZnVuY3Rpb24gRW50ZXJSZXBvcnQocGF0aCwgZHVyYXRpb24sIHNsb3cpIHtcbiAgICBSZXBvcnQuY2FsbCh0aGlzLCBUeXBlcy5FbnRlcilcbiAgICB0aGlzLnBhdGggPSBwYXRoXG4gICAgdGhpcy5kdXJhdGlvbiA9IGR1cmF0aW9uXG4gICAgdGhpcy5zbG93ID0gc2xvd1xufVxubWV0aG9kcyhFbnRlclJlcG9ydCwgUmVwb3J0LCB7XG4gICAgLyoqXG4gICAgICogU28gdXRpbC5pbnNwZWN0IHByb3ZpZGVzIG1vcmUgc2Vuc2libGUgb3V0cHV0IGZvciB0ZXN0aW5nL2V0Yy5cbiAgICAgKi9cbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gRW50ZXJSZXBvcnQocmVwb3J0KSB7XG4gICAgICAgICAgICBpbml0SW5zcGVjdCh0aGlzLCByZXBvcnQpXG4gICAgICAgIH0odGhpcylcbiAgICB9LFxufSlcblxuZXhwb3J0cy5MZWF2ZSA9IExlYXZlUmVwb3J0XG5mdW5jdGlvbiBMZWF2ZVJlcG9ydChwYXRoKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuTGVhdmUpXG4gICAgdGhpcy5wYXRoID0gcGF0aFxufVxubWV0aG9kcyhMZWF2ZVJlcG9ydCwgUmVwb3J0LCB7XG4gICAgLyoqXG4gICAgICogU28gdXRpbC5pbnNwZWN0IHByb3ZpZGVzIG1vcmUgc2Vuc2libGUgb3V0cHV0IGZvciB0ZXN0aW5nL2V0Yy5cbiAgICAgKi9cbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gTGVhdmVSZXBvcnQocmVwb3J0KSB7XG4gICAgICAgICAgICBpbml0SW5zcGVjdCh0aGlzLCByZXBvcnQpXG4gICAgICAgIH0odGhpcylcbiAgICB9LFxufSlcblxuZXhwb3J0cy5QYXNzID0gUGFzc1JlcG9ydFxuZnVuY3Rpb24gUGFzc1JlcG9ydChwYXRoLCBkdXJhdGlvbiwgc2xvdykge1xuICAgIFJlcG9ydC5jYWxsKHRoaXMsIFR5cGVzLlBhc3MpXG4gICAgdGhpcy5wYXRoID0gcGF0aFxuICAgIHRoaXMuZHVyYXRpb24gPSBkdXJhdGlvblxuICAgIHRoaXMuc2xvdyA9IHNsb3dcbn1cbm1ldGhvZHMoUGFzc1JlcG9ydCwgUmVwb3J0LCB7XG4gICAgLyoqXG4gICAgICogU28gdXRpbC5pbnNwZWN0IHByb3ZpZGVzIG1vcmUgc2Vuc2libGUgb3V0cHV0IGZvciB0ZXN0aW5nL2V0Yy5cbiAgICAgKi9cbiAgICBpbnNwZWN0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgZnVuY3Rpb24gUGFzc1JlcG9ydChyZXBvcnQpIHtcbiAgICAgICAgICAgIGluaXRJbnNwZWN0KHRoaXMsIHJlcG9ydClcbiAgICAgICAgfSh0aGlzKVxuICAgIH0sXG59KVxuXG5leHBvcnRzLkZhaWwgPSBGYWlsUmVwb3J0XG5mdW5jdGlvbiBGYWlsUmVwb3J0KHBhdGgsIGVycm9yLCBkdXJhdGlvbiwgc2xvdywgaXNGYWlsYWJsZSkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICBSZXBvcnQuY2FsbCh0aGlzLCBUeXBlcy5GYWlsKVxuICAgIHRoaXMucGF0aCA9IHBhdGhcbiAgICB0aGlzLmVycm9yID0gZXJyb3JcbiAgICB0aGlzLmR1cmF0aW9uID0gZHVyYXRpb25cbiAgICB0aGlzLnNsb3cgPSBzbG93XG4gICAgdGhpcy5pc0ZhaWxhYmxlID0gaXNGYWlsYWJsZVxufVxubWV0aG9kcyhGYWlsUmVwb3J0LCBSZXBvcnQsIHtcbiAgICAvKipcbiAgICAgKiBTbyB1dGlsLmluc3BlY3QgcHJvdmlkZXMgbW9yZSBzZW5zaWJsZSBvdXRwdXQgZm9yIHRlc3RpbmcvZXRjLlxuICAgICAqL1xuICAgIGluc3BlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBmdW5jdGlvbiBGYWlsUmVwb3J0KHJlcG9ydCkge1xuICAgICAgICAgICAgaW5pdEluc3BlY3QodGhpcywgcmVwb3J0KVxuICAgICAgICB9KHRoaXMpXG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuU2tpcCA9IFNraXBSZXBvcnRcbmZ1bmN0aW9uIFNraXBSZXBvcnQocGF0aCkge1xuICAgIFJlcG9ydC5jYWxsKHRoaXMsIFR5cGVzLlNraXApXG4gICAgdGhpcy5wYXRoID0gcGF0aFxufVxubWV0aG9kcyhTa2lwUmVwb3J0LCBSZXBvcnQsIHtcbiAgICAvKipcbiAgICAgKiBTbyB1dGlsLmluc3BlY3QgcHJvdmlkZXMgbW9yZSBzZW5zaWJsZSBvdXRwdXQgZm9yIHRlc3RpbmcvZXRjLlxuICAgICAqL1xuICAgIGluc3BlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBmdW5jdGlvbiBTa2lwUmVwb3J0KHJlcG9ydCkge1xuICAgICAgICAgICAgaW5pdEluc3BlY3QodGhpcywgcmVwb3J0KVxuICAgICAgICB9KHRoaXMpXG4gICAgfSxcbn0pXG5cbmV4cG9ydHMuRW5kID0gRW5kUmVwb3J0XG5mdW5jdGlvbiBFbmRSZXBvcnQoKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuRW5kKVxufVxubWV0aG9kcyhFbmRSZXBvcnQsIFJlcG9ydCwge1xuICAgIC8qKlxuICAgICAqIFNvIHV0aWwuaW5zcGVjdCBwcm92aWRlcyBtb3JlIHNlbnNpYmxlIG91dHB1dCBmb3IgdGVzdGluZy9ldGMuXG4gICAgICovXG4gICAgaW5zcGVjdDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IGZ1bmN0aW9uIEVuZFJlcG9ydChyZXBvcnQpIHtcbiAgICAgICAgICAgIGluaXRJbnNwZWN0KHRoaXMsIHJlcG9ydClcbiAgICAgICAgfSh0aGlzKVxuICAgIH0sXG59KVxuXG5leHBvcnRzLkVycm9yID0gRXJyb3JSZXBvcnRcbmZ1bmN0aW9uIEVycm9yUmVwb3J0KGVycm9yKSB7XG4gICAgUmVwb3J0LmNhbGwodGhpcywgVHlwZXMuRXJyb3IpXG4gICAgdGhpcy5lcnJvciA9IGVycm9yXG59XG5tZXRob2RzKEVycm9yUmVwb3J0LCBSZXBvcnQsIHtcbiAgICAvKipcbiAgICAgKiBTbyB1dGlsLmluc3BlY3QgcHJvdmlkZXMgbW9yZSBzZW5zaWJsZSBvdXRwdXQgZm9yIHRlc3RpbmcvZXRjLlxuICAgICAqL1xuICAgIGluc3BlY3Q6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBmdW5jdGlvbiBFcnJvclJlcG9ydChyZXBvcnQpIHtcbiAgICAgICAgICAgIGluaXRJbnNwZWN0KHRoaXMsIHJlcG9ydClcbiAgICAgICAgfSh0aGlzKVxuICAgIH0sXG59KVxuXG52YXIgSG9va01ldGhvZHMgPSB7XG4gICAgZ2V0IHN0YWdlKCkge1xuICAgICAgICBzd2l0Y2ggKHRoaXMuXykge1xuICAgICAgICBjYXNlIEhvb2tTdGFnZS5CZWZvcmVBbGw6IHJldHVybiBcImJlZm9yZSBhbGxcIlxuICAgICAgICBjYXNlIEhvb2tTdGFnZS5CZWZvcmVFYWNoOiByZXR1cm4gXCJiZWZvcmUgZWFjaFwiXG4gICAgICAgIGNhc2UgSG9va1N0YWdlLkFmdGVyRWFjaDogcmV0dXJuIFwiYWZ0ZXIgZWFjaFwiXG4gICAgICAgIGNhc2UgSG9va1N0YWdlLkFmdGVyQWxsOiByZXR1cm4gXCJhZnRlciBhbGxcIlxuICAgICAgICBkZWZhdWx0OiB0aHJvdyBuZXcgRXJyb3IoXCJ1bnJlYWNoYWJsZVwiKVxuICAgICAgICB9XG4gICAgfSxcblxuICAgIGdldCBpc0JlZm9yZUFsbCgpIHsgcmV0dXJuIHRoaXMuXyA9PT0gSG9va1N0YWdlLkJlZm9yZUFsbCB9LFxuICAgIGdldCBpc0JlZm9yZUVhY2goKSB7IHJldHVybiB0aGlzLl8gPT09IEhvb2tTdGFnZS5CZWZvcmVFYWNoIH0sXG4gICAgZ2V0IGlzQWZ0ZXJFYWNoKCkgeyByZXR1cm4gdGhpcy5fID09PSBIb29rU3RhZ2UuQWZ0ZXJFYWNoIH0sXG4gICAgZ2V0IGlzQWZ0ZXJBbGwoKSB7IHJldHVybiB0aGlzLl8gPT09IEhvb2tTdGFnZS5BZnRlckFsbCB9LFxufVxuXG5leHBvcnRzLkhvb2tFcnJvciA9IEhvb2tFcnJvclxuZnVuY3Rpb24gSG9va0Vycm9yKHN0YWdlLCBmdW5jLCBlcnJvcikge1xuICAgIHRoaXMuXyA9IHN0YWdlXG4gICAgdGhpcy5uYW1lID0gZnVuYy5uYW1lIHx8IGZ1bmMuZGlzcGxheU5hbWUgfHwgXCJcIlxuICAgIHRoaXMuZXJyb3IgPSBlcnJvclxufVxubWV0aG9kcyhIb29rRXJyb3IsIEhvb2tNZXRob2RzKVxuXG5leHBvcnRzLkhvb2sgPSBIb29rUmVwb3J0XG5mdW5jdGlvbiBIb29rUmVwb3J0KHBhdGgsIHJvb3RQYXRoLCBob29rRXJyb3IpIHtcbiAgICBSZXBvcnQuY2FsbCh0aGlzLCBob29rRXJyb3IuXylcbiAgICB0aGlzLnBhdGggPSBwYXRoXG4gICAgdGhpcy5yb290UGF0aCA9IHJvb3RQYXRoXG4gICAgdGhpcy5uYW1lID0gaG9va0Vycm9yLm5hbWVcbiAgICB0aGlzLmVycm9yID0gaG9va0Vycm9yLmVycm9yXG59XG5tZXRob2RzKEhvb2tSZXBvcnQsIFJlcG9ydCwgSG9va01ldGhvZHMsIHtcbiAgICBnZXQgaG9va0Vycm9yKCkgeyByZXR1cm4gbmV3IEhvb2tFcnJvcih0aGlzLl8sIHRoaXMsIHRoaXMuZXJyb3IpIH0sXG59KVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIG1ldGhvZHMgPSByZXF1aXJlKFwiLi4vbWV0aG9kc1wiKVxudmFyIHBlYWNoID0gcmVxdWlyZShcIi4uL3V0aWxcIikucGVhY2hcbnZhciBSZXBvcnRzID0gcmVxdWlyZShcIi4vcmVwb3J0c1wiKVxudmFyIEZpbHRlciA9IHJlcXVpcmUoXCIuL2ZpbHRlclwiKVxudmFyIEhvb2tTdGFnZSA9IFJlcG9ydHMuSG9va1N0YWdlXG5cbi8qKlxuICogVGhlIHRlc3RzIGFyZSBsYWlkIG91dCBpbiBhIHZlcnkgZGF0YS1kcml2ZW4gZGVzaWduLiBXaXRoIGV4Y2VwdGlvbiBvZiB0aGVcbiAqIHJlcG9ydHMsIHRoZXJlIGlzIG1pbmltYWwgb2JqZWN0IG9yaWVudGF0aW9uIGFuZCB6ZXJvIHZpcnR1YWwgZGlzcGF0Y2guXG4gKiBIZXJlJ3MgYSBxdWljayBvdmVydmlldzpcbiAqXG4gKiAtIFRoZSB0ZXN0IGhhbmRsaW5nIGRpc3BhdGNoZXMgYmFzZWQgb24gdmFyaW91cyBhdHRyaWJ1dGVzIHRoZSB0ZXN0IGhhcy4gRm9yXG4gKiAgIGV4YW1wbGUsIHJvb3RzIGFyZSBrbm93biBieSBhIGNpcmN1bGFyIHJvb3QgcmVmZXJlbmNlLCBhbmQgc2tpcHBlZCB0ZXN0c1xuICogICBhcmUga25vd24gYnkgbm90IGhhdmluZyBhIGNhbGxiYWNrLlxuICpcbiAqIC0gVGhlIHRlc3QgZXZhbHVhdGlvbiBpcyB2ZXJ5IHByb2NlZHVyYWwuIEFsdGhvdWdoIGl0J3MgdmVyeSBoaWdobHlcbiAqICAgYXN5bmNocm9ub3VzLCB0aGUgdXNlIG9mIHByb21pc2VzIGxpbmVhcml6ZSB0aGUgbG9naWMsIHNvIGl0IHJlYWRzIHZlcnlcbiAqICAgbXVjaCBsaWtlIGEgcmVjdXJzaXZlIHNldCBvZiBzdGVwcy5cbiAqXG4gKiAtIFRoZSBkYXRhIHR5cGVzIGFyZSBtb3N0bHkgZWl0aGVyIHBsYWluIG9iamVjdHMgb3IgY2xhc3NlcyB3aXRoIG5vIG1ldGhvZHMsXG4gKiAgIHRoZSBsYXR0ZXIgbW9zdGx5IGZvciBkZWJ1Z2dpbmcgaGVscC4gVGhpcyBhbHNvIGF2b2lkcyBtb3N0IG9mIHRoZVxuICogICBpbmRpcmVjdGlvbiByZXF1aXJlZCB0byBhY2NvbW1vZGF0ZSBicmVha2luZyBhYnN0cmFjdGlvbnMsIHdoaWNoIHRoZSBBUElcbiAqICAgbWV0aG9kcyBmcmVxdWVudGx5IG5lZWQgdG8gZG8uXG4gKi9cblxuLy8gUHJldmVudCBTaW5vbiBpbnRlcmZlcmVuY2Ugd2hlbiB0aGV5IGluc3RhbGwgdGhlaXIgbW9ja3NcbnZhciBzZXRUaW1lb3V0ID0gZ2xvYmFsLnNldFRpbWVvdXRcbnZhciBjbGVhclRpbWVvdXQgPSBnbG9iYWwuY2xlYXJUaW1lb3V0XG52YXIgbm93ID0gZ2xvYmFsLkRhdGUubm93XG5cbi8qKlxuICogQmFzaWMgZGF0YSB0eXBlc1xuICovXG5mdW5jdGlvbiBSZXN1bHQodGltZSwgYXR0ZW1wdCkge1xuICAgIHRoaXMudGltZSA9IHRpbWVcbiAgICB0aGlzLmNhdWdodCA9IGF0dGVtcHQuY2F1Z2h0XG4gICAgdGhpcy52YWx1ZSA9IGF0dGVtcHQuY2F1Z2h0ID8gYXR0ZW1wdC52YWx1ZSA6IHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIE92ZXJ2aWV3IG9mIHRoZSB0ZXN0IHByb3BlcnRpZXM6XG4gKlxuICogLSBgcm9vdGAgLSBUaGUgcm9vdCB0ZXN0XG4gKiAtIGByZXBvcnRlcnNgIC0gVGhlIGxpc3Qgb2YgcmVwb3J0ZXJzXG4gKiAtIGBjdXJyZW50YCAtIEEgcmVmZXJlbmNlIHRvIHRoZSBjdXJyZW50bHkgYWN0aXZlIHRlc3RcbiAqIC0gYHRpbWVvdXRgIC0gVGhlIHRlc3RzJ3MgdGltZW91dCwgb3IgMCBpZiBpbmhlcml0ZWRcbiAqIC0gYHNsb3dgIC0gVGhlIHRlc3RzJ3Mgc2xvdyB0aHJlc2hvbGRcbiAqIC0gYG5hbWVgIC0gVGhlIHRlc3QncyBuYW1lXG4gKiAtIGBpbmRleGAgLSBUaGUgdGVzdCdzIGluZGV4XG4gKiAtIGBwYXJlbnRgIC0gVGhlIHRlc3QncyBwYXJlbnRcbiAqIC0gYGNhbGxiYWNrYCAtIFRoZSB0ZXN0J3MgY2FsbGJhY2tcbiAqIC0gYHRlc3RzYCAtIFRoZSB0ZXN0J3MgY2hpbGQgdGVzdHNcbiAqIC0gYGJlZm9yZUFsbGAsIGBiZWZvcmVFYWNoYCwgYGFmdGVyRWFjaGAsIGBhZnRlckFsbGAgLSBUaGUgdGVzdCdzIHZhcmlvdXNcbiAqICAgc2NoZWR1bGVkIGhvb2tzXG4gKlxuICogTWFueSBvZiB0aGVzZSBwcm9wZXJ0aWVzIGFyZW4ndCBwcmVzZW50IG9uIGluaXRpYWxpemF0aW9uIHRvIHNhdmUgbWVtb3J5LlxuICovXG5cbmZ1bmN0aW9uIE5vcm1hbChuYW1lLCBpbmRleCwgcGFyZW50LCBjYWxsYmFjaykge1xuICAgIHRoaXMubG9ja2VkID0gdHJ1ZVxuICAgIHRoaXMucm9vdCA9IHBhcmVudC5yb290XG4gICAgdGhpcy5uYW1lID0gbmFtZVxuICAgIHRoaXMuaW5kZXggPSBpbmRleHwwXG4gICAgdGhpcy5wYXJlbnQgPSBwYXJlbnRcbiAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2tcbiAgICB0aGlzLmlzRmFpbGFibGUgPSBwYXJlbnQuaXNGYWlsYWJsZVxuICAgIHRoaXMuYXR0ZW1wdHMgPSBwYXJlbnQuYXR0ZW1wdHNcblxuICAgIHRoaXMudGltZW91dCA9IHBhcmVudC50aW1lb3V0XG4gICAgdGhpcy5zbG93ID0gcGFyZW50LnNsb3dcbiAgICB0aGlzLnRlc3RzID0gdW5kZWZpbmVkXG4gICAgdGhpcy5iZWZvcmVBbGwgPSB1bmRlZmluZWRcbiAgICB0aGlzLmJlZm9yZUVhY2ggPSB1bmRlZmluZWRcbiAgICB0aGlzLmFmdGVyRWFjaCA9IHVuZGVmaW5lZFxuICAgIHRoaXMuYWZ0ZXJBbGwgPSB1bmRlZmluZWRcbiAgICB0aGlzLnJlcG9ydGVyID0gdW5kZWZpbmVkXG4gICAgdGhpcy5yZWZsZWN0ID0gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIFNraXBwZWQobmFtZSwgaW5kZXgsIHBhcmVudCkge1xuICAgIHRoaXMubG9ja2VkID0gdHJ1ZVxuICAgIHRoaXMucm9vdCA9IHBhcmVudC5yb290XG4gICAgdGhpcy5uYW1lID0gbmFtZVxuICAgIHRoaXMuaW5kZXggPSBpbmRleHwwXG4gICAgdGhpcy5wYXJlbnQgPSBwYXJlbnRcblxuICAgIC8vIE9ubHkgZm9yIHJlZmxlY3Rpb24uXG4gICAgdGhpcy5pc0ZhaWxhYmxlID0gcGFyZW50LmlzRmFpbGFibGVcbiAgICB0aGlzLmF0dGVtcHRzID0gcGFyZW50LmF0dGVtcHRzXG4gICAgdGhpcy5yZXBvcnRlciA9IHVuZGVmaW5lZFxuICAgIHRoaXMucmVmbGVjdCA9IHVuZGVmaW5lZFxufVxuXG5mdW5jdGlvbiBSb290KCkge1xuICAgIHRoaXMubG9ja2VkID0gZmFsc2VcbiAgICB0aGlzLnJlcG9ydGVySWRzID0gW11cbiAgICB0aGlzLnJlcG9ydGVycyA9IFtdXG4gICAgdGhpcy5jdXJyZW50ID0gdGhpc1xuICAgIHRoaXMucm9vdCA9IHRoaXNcbiAgICB0aGlzLnRpbWVvdXQgPSAwXG4gICAgdGhpcy5zbG93ID0gMFxuICAgIHRoaXMuYXR0ZW1wdHMgPSAxXG4gICAgdGhpcy5pc0ZhaWxhYmxlID0gZmFsc2VcblxuICAgIHRoaXMudGVzdHMgPSB1bmRlZmluZWRcbiAgICB0aGlzLnJlcG9ydGVyID0gdW5kZWZpbmVkXG4gICAgdGhpcy5yZWZsZWN0ID0gdW5kZWZpbmVkXG4gICAgdGhpcy5iZWZvcmVBbGwgPSB1bmRlZmluZWRcbiAgICB0aGlzLmJlZm9yZUVhY2ggPSB1bmRlZmluZWRcbiAgICB0aGlzLmFmdGVyRWFjaCA9IHVuZGVmaW5lZFxuICAgIHRoaXMuYWZ0ZXJBbGwgPSB1bmRlZmluZWRcbn1cblxuZnVuY3Rpb24gQ29udGV4dChyb290KSB7XG4gICAgdGhpcy5yb290ID0gcm9vdFxuICAgIHRoaXMudGVzdHMgPSBbXVxuICAgIHRoaXMuaXNTdWNjZXNzID0gdHJ1ZVxufVxuXG4vKipcbiAqIEJhc2UgdGVzdHMgKGkuZS4gZGVmYXVsdCBleHBvcnQsIHJlc3VsdCBvZiBgaW50ZXJuYWwucm9vdCgpYCkuXG4gKi9cblxuZXhwb3J0cy5jcmVhdGVSb290ID0gZnVuY3Rpb24gKG1ldGhvZHMpIHtcbiAgICByZXR1cm4gbmV3IFJvb3QobWV0aG9kcylcbn1cblxuLyoqXG4gKiBTZXQgdXAgZWFjaCB0ZXN0IHR5cGUuXG4gKi9cblxuLyoqXG4gKiBBIG5vcm1hbCB0ZXN0IHRocm91Z2ggYHQudGVzdCgpYC5cbiAqL1xuXG5leHBvcnRzLmFkZE5vcm1hbCA9IGZ1bmN0aW9uIChwYXJlbnQsIG5hbWUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGluZGV4ID0gcGFyZW50LnRlc3RzICE9IG51bGwgPyBwYXJlbnQudGVzdHMubGVuZ3RoIDogMFxuICAgIHZhciBiYXNlID0gbmV3IE5vcm1hbChuYW1lLCBpbmRleCwgcGFyZW50LCBjYWxsYmFjaylcblxuICAgIGlmIChpbmRleCkge1xuICAgICAgICBwYXJlbnQudGVzdHMucHVzaChiYXNlKVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcmVudC50ZXN0cyA9IFtiYXNlXVxuICAgIH1cbn1cblxuLyoqXG4gKiBBIHNraXBwZWQgdGVzdCB0aHJvdWdoIGB0LnRlc3RTa2lwKClgLlxuICovXG5leHBvcnRzLmFkZFNraXBwZWQgPSBmdW5jdGlvbiAocGFyZW50LCBuYW1lKSB7XG4gICAgdmFyIGluZGV4ID0gcGFyZW50LnRlc3RzICE9IG51bGwgPyBwYXJlbnQudGVzdHMubGVuZ3RoIDogMFxuICAgIHZhciBiYXNlID0gbmV3IFNraXBwZWQobmFtZSwgaW5kZXgsIHBhcmVudClcblxuICAgIGlmIChpbmRleCkge1xuICAgICAgICBwYXJlbnQudGVzdHMucHVzaChiYXNlKVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHBhcmVudC50ZXN0cyA9IFtiYXNlXVxuICAgIH1cbn1cblxuLyoqXG4gKiBDbGVhciB0aGUgdGVzdHMgaW4gcGxhY2UuXG4gKi9cbmV4cG9ydHMuY2xlYXJUZXN0cyA9IGZ1bmN0aW9uIChwYXJlbnQpIHtcbiAgICBwYXJlbnQudGVzdHMgPSBudWxsXG59XG5cbi8qKlxuICogRXhlY3V0ZSB0aGUgdGVzdHNcbiAqL1xuXG5leHBvcnRzLmRlZmF1bHRUaW1lb3V0ID0gMjAwMCAvLyBtc1xuZXhwb3J0cy5kZWZhdWx0U2xvdyA9IDc1IC8vIG1zXG5cbmZ1bmN0aW9uIG1ha2VTbGljZSh0ZXN0cywgbGVuZ3RoKSB7XG4gICAgdmFyIHJldCA9IG5ldyBBcnJheShsZW5ndGgpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJldFtpXSA9IHtuYW1lOiB0ZXN0c1tpXS5uYW1lLCBpbmRleDogdGVzdHNbaV0uaW5kZXh9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiByZXBvcnRXaXRoKGNvbnRleHQsIGZ1bmMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjb250ZXh0LnJvb3QucmVwb3J0ZXIgPT0gbnVsbCkgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICByZXR1cm4gZnVuYyhjb250ZXh0LnJvb3QucmVwb3J0ZXIpXG4gICAgfSlcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciByZXBvcnRlcnMgPSBjb250ZXh0LnJvb3QucmVwb3J0ZXJzXG5cbiAgICAgICAgLy8gVHdvIGVhc3kgY2FzZXMuXG4gICAgICAgIGlmIChyZXBvcnRlcnMubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIGlmIChyZXBvcnRlcnMubGVuZ3RoID09PSAxKSByZXR1cm4gZnVuYyhyZXBvcnRlcnNbMF0pXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChyZXBvcnRlcnMubWFwKGZ1bmMpKVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIHJlcG9ydFN0YXJ0KGNvbnRleHQpIHtcbiAgICByZXR1cm4gcmVwb3J0V2l0aChjb250ZXh0LCBmdW5jdGlvbiAocmVwb3J0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyKG5ldyBSZXBvcnRzLlN0YXJ0KCkpXG4gICAgfSlcbn1cblxuZnVuY3Rpb24gcmVwb3J0RW50ZXIoY29udGV4dCwgZHVyYXRpb24pIHtcbiAgICB2YXIgdGVzdCA9IGNvbnRleHQucm9vdC5jdXJyZW50XG4gICAgdmFyIHNsb3cgPSB0ZXN0LnNsb3cgfHwgZXhwb3J0cy5kZWZhdWx0U2xvd1xuXG4gICAgcmV0dXJuIHJlcG9ydFdpdGgoY29udGV4dCwgZnVuY3Rpb24gKHJlcG9ydGVyKSB7XG4gICAgICAgIHZhciBwYXRoID0gbWFrZVNsaWNlKGNvbnRleHQudGVzdHMsIGNvbnRleHQudGVzdHMubGVuZ3RoKVxuXG4gICAgICAgIHJldHVybiByZXBvcnRlcihuZXcgUmVwb3J0cy5FbnRlcihwYXRoLCBkdXJhdGlvbiwgc2xvdykpXG4gICAgfSlcbn1cblxuZnVuY3Rpb24gcmVwb3J0TGVhdmUoY29udGV4dCkge1xuICAgIHJldHVybiByZXBvcnRXaXRoKGNvbnRleHQsIGZ1bmN0aW9uIChyZXBvcnRlcikge1xuICAgICAgICByZXR1cm4gcmVwb3J0ZXIobmV3IFJlcG9ydHMuTGVhdmUoXG4gICAgICAgICAgICBtYWtlU2xpY2UoY29udGV4dC50ZXN0cywgY29udGV4dC50ZXN0cy5sZW5ndGgpKSlcbiAgICB9KVxufVxuXG5mdW5jdGlvbiByZXBvcnRQYXNzKGNvbnRleHQsIGR1cmF0aW9uKSB7XG4gICAgdmFyIHRlc3QgPSBjb250ZXh0LnJvb3QuY3VycmVudFxuICAgIHZhciBzbG93ID0gdGVzdC5zbG93IHx8IGV4cG9ydHMuZGVmYXVsdFNsb3dcblxuICAgIHJldHVybiByZXBvcnRXaXRoKGNvbnRleHQsIGZ1bmN0aW9uIChyZXBvcnRlcikge1xuICAgICAgICB2YXIgcGF0aCA9IG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmxlbmd0aClcblxuICAgICAgICByZXR1cm4gcmVwb3J0ZXIobmV3IFJlcG9ydHMuUGFzcyhwYXRoLCBkdXJhdGlvbiwgc2xvdykpXG4gICAgfSlcbn1cblxuZnVuY3Rpb24gcmVwb3J0RmFpbChjb250ZXh0LCBlcnJvciwgZHVyYXRpb24pIHtcbiAgICB2YXIgdGVzdCA9IGNvbnRleHQucm9vdC5jdXJyZW50XG4gICAgdmFyIHNsb3cgPSB0ZXN0LnNsb3cgfHwgZXhwb3J0cy5kZWZhdWx0U2xvd1xuICAgIHZhciBpc0ZhaWxhYmxlID0gdGVzdC5pc0ZhaWxhYmxlXG5cbiAgICByZXR1cm4gcmVwb3J0V2l0aChjb250ZXh0LCBmdW5jdGlvbiAocmVwb3J0ZXIpIHtcbiAgICAgICAgdmFyIHBhdGggPSBtYWtlU2xpY2UoY29udGV4dC50ZXN0cywgY29udGV4dC50ZXN0cy5sZW5ndGgpXG5cbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyKG5ldyBSZXBvcnRzLkZhaWwoXG4gICAgICAgICAgICBwYXRoLCBlcnJvciwgZHVyYXRpb24sIHNsb3csIGlzRmFpbGFibGUpKVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIHJlcG9ydFNraXAoY29udGV4dCkge1xuICAgIHJldHVybiByZXBvcnRXaXRoKGNvbnRleHQsIGZ1bmN0aW9uIChyZXBvcnRlcikge1xuICAgICAgICByZXR1cm4gcmVwb3J0ZXIobmV3IFJlcG9ydHMuU2tpcChcbiAgICAgICAgICAgIG1ha2VTbGljZShjb250ZXh0LnRlc3RzLCBjb250ZXh0LnRlc3RzLmxlbmd0aCkpKVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIHJlcG9ydEVuZChjb250ZXh0KSB7XG4gICAgcmV0dXJuIHJlcG9ydFdpdGgoY29udGV4dCwgZnVuY3Rpb24gKHJlcG9ydGVyKSB7XG4gICAgICAgIHJldHVybiByZXBvcnRlcihuZXcgUmVwb3J0cy5FbmQoKSlcbiAgICB9KVxufVxuXG5mdW5jdGlvbiByZXBvcnRFcnJvcihjb250ZXh0LCBlcnJvcikge1xuICAgIHJldHVybiByZXBvcnRXaXRoKGNvbnRleHQsIGZ1bmN0aW9uIChyZXBvcnRlcikge1xuICAgICAgICByZXR1cm4gcmVwb3J0ZXIobmV3IFJlcG9ydHMuRXJyb3IoZXJyb3IpKVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIHJlcG9ydEhvb2soY29udGV4dCwgdGVzdCwgZXJyb3IpIHtcbiAgICByZXR1cm4gcmVwb3J0V2l0aChjb250ZXh0LCBmdW5jdGlvbiAocmVwb3J0ZXIpIHtcbiAgICAgICAgcmV0dXJuIHJlcG9ydGVyKG5ldyBSZXBvcnRzLkhvb2soXG4gICAgICAgICAgICBtYWtlU2xpY2UoY29udGV4dC50ZXN0cywgY29udGV4dC50ZXN0cy5sZW5ndGgpLFxuICAgICAgICAgICAgbWFrZVNsaWNlKGNvbnRleHQudGVzdHMsIGNvbnRleHQudGVzdHMuaW5kZXhPZih0ZXN0KSArIDEpLFxuICAgICAgICAgICAgZXJyb3IpKVxuICAgIH0pXG59XG5cbi8qKlxuICogTm9ybWFsIHRlc3RzXG4gKi9cblxuLy8gUGhhbnRvbUpTIGFuZCBJRSBkb24ndCBhZGQgdGhlIHN0YWNrIHVudGlsIGl0J3MgdGhyb3duLiBJbiBmYWlsaW5nIGFzeW5jXG4vLyB0ZXN0cywgaXQncyBhbHJlYWR5IHRocm93biBpbiBhIHNlbnNlLCBzbyB0aGlzIHNob3VsZCBiZSBub3JtYWxpemVkIHdpdGhcbi8vIG90aGVyIHRlc3QgdHlwZXMuXG52YXIgYWRkU3RhY2sgPSB0eXBlb2YgbmV3IEVycm9yKCkuc3RhY2sgIT09IFwic3RyaW5nXCJcbiAgICA/IGZ1bmN0aW9uIGFkZFN0YWNrKGUpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgRXJyb3IgJiYgZS5zdGFjayA9PSBudWxsKSB0aHJvdyBlXG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICByZXR1cm4gZVxuICAgICAgICB9XG4gICAgfVxuICAgIDogZnVuY3Rpb24gKGUpIHsgcmV0dXJuIGUgfVxuXG5mdW5jdGlvbiBnZXRUaGVuKHJlcykge1xuICAgIGlmICh0eXBlb2YgcmVzID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiByZXMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gcmVzLnRoZW5cbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxufVxuXG5mdW5jdGlvbiBBc3luY1N0YXRlKGNvbnRleHQsIHN0YXJ0LCByZXNvbHZlLCBjb3VudCkge1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHRcbiAgICB0aGlzLnN0YXJ0ID0gc3RhcnRcbiAgICB0aGlzLnJlc29sdmUgPSByZXNvbHZlXG4gICAgdGhpcy5jb3VudCA9IGNvdW50XG4gICAgdGhpcy50aW1lciA9IHVuZGVmaW5lZFxufVxuXG52YXIgcCA9IFByb21pc2UucmVzb2x2ZSgpXG5cbmZ1bmN0aW9uIGFzeW5jRmluaXNoKHN0YXRlLCBhdHRlbXB0KSB7XG4gICAgLy8gQ2FwdHVyZSBpbW1lZGlhdGVseS4gV29yc3QgY2FzZSBzY2VuYXJpbywgaXQgZ2V0cyB0aHJvd24gYXdheS5cbiAgICB2YXIgZW5kID0gbm93KClcblxuICAgIGlmIChzdGF0ZS50aW1lcikge1xuICAgICAgICBjbGVhclRpbWVvdXQuY2FsbChnbG9iYWwsIHN0YXRlLnRpbWVyKVxuICAgICAgICBzdGF0ZS50aW1lciA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmIChhdHRlbXB0LmNhdWdodCAmJiBzdGF0ZS5jb3VudCA8IHN0YXRlLmNvbnRleHQucm9vdC5jdXJyZW50LmF0dGVtcHRzKSB7XG4gICAgICAgIC8vIERvbid0IHJlY3Vyc2Ugc3luY2hyb25vdXNseSwgc2luY2UgaXQgbWF5IGJlIHJlc29sdmVkIHN5bmNocm9ub3VzbHlcbiAgICAgICAgc3RhdGUucmVzb2x2ZShwLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGludm9rZUluaXQoc3RhdGUuY29udGV4dCwgc3RhdGUuY291bnQgKyAxKVxuICAgICAgICB9KSlcbiAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5yZXNvbHZlKG5ldyBSZXN1bHQoZW5kIC0gc3RhdGUuc3RhcnQsIGF0dGVtcHQpKVxuICAgIH1cbn1cblxuLy8gQXZvaWQgY3JlYXRpbmcgYSBjbG9zdXJlIGlmIHBvc3NpYmxlLCBpbiBjYXNlIGl0IGRvZXNuJ3QgcmV0dXJuIGEgdGhlbmFibGUuXG5mdW5jdGlvbiBpbnZva2VJbml0KGNvbnRleHQsIGNvdW50KSB7XG4gICAgdmFyIHRlc3QgPSBjb250ZXh0LnJvb3QuY3VycmVudFxuICAgIHZhciBzdGFydCA9IG5vdygpXG4gICAgdmFyIHRyeUJvZHkgPSB0cnkwKHRlc3QuY2FsbGJhY2spXG4gICAgdmFyIHN5bmNFbmQgPSBub3coKVxuXG4gICAgLy8gTm90ZTogc3luY2hyb25vdXMgZmFpbHVyZXMgYXJlIHRlc3QgZmFpbHVyZXMsIG5vdCBmYXRhbCBlcnJvcnMuXG4gICAgaWYgKHRyeUJvZHkuY2F1Z2h0KSB7XG4gICAgICAgIGlmIChjb3VudCA8IHRlc3QuYXR0ZW1wdHMpIHJldHVybiBpbnZva2VJbml0KGNvbnRleHQsIGNvdW50ICsgMSlcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXcgUmVzdWx0KHN5bmNFbmQgLSBzdGFydCwgdHJ5Qm9keSkpXG4gICAgfVxuXG4gICAgdmFyIHRyeVRoZW4gPSB0cnkxKGdldFRoZW4sIHVuZGVmaW5lZCwgdHJ5Qm9keS52YWx1ZSlcblxuICAgIGlmICh0cnlUaGVuLmNhdWdodCkge1xuICAgICAgICBpZiAoY291bnQgPCB0ZXN0LmF0dGVtcHRzKSByZXR1cm4gaW52b2tlSW5pdChjb250ZXh0LCBjb3VudCArIDEpXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IFJlc3VsdChzeW5jRW5kIC0gc3RhcnQsIHRyeVRoZW4pKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdHJ5VGhlbi52YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IFJlc3VsdChzeW5jRW5kIC0gc3RhcnQsIHRyeVRoZW4pKVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICB2YXIgc3RhdGUgPSBuZXcgQXN5bmNTdGF0ZShjb250ZXh0LCBzdGFydCwgcmVzb2x2ZSwgY291bnQpXG4gICAgICAgIHZhciByZXN1bHQgPSB0cnkyKHRyeVRoZW4udmFsdWUsIHRyeUJvZHkudmFsdWUsXG4gICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlID09IG51bGwpIHJldHVyblxuICAgICAgICAgICAgICAgIGFzeW5jRmluaXNoKHN0YXRlLCB0cnlQYXNzKCkpXG4gICAgICAgICAgICAgICAgc3RhdGUgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZSA9PSBudWxsKSByZXR1cm5cbiAgICAgICAgICAgICAgICBhc3luY0ZpbmlzaChzdGF0ZSwgdHJ5RmFpbChhZGRTdGFjayhlKSkpXG4gICAgICAgICAgICAgICAgc3RhdGUgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgaWYgKHN0YXRlID09IG51bGwpIHJldHVyblxuICAgICAgICBpZiAocmVzdWx0LmNhdWdodCkge1xuICAgICAgICAgICAgYXN5bmNGaW5pc2goc3RhdGUsIHJlc3VsdClcbiAgICAgICAgICAgIHN0YXRlID0gdW5kZWZpbmVkXG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCB0aGUgdGltZW91dCAqYWZ0ZXIqIGluaXRpYWxpemF0aW9uLiBUaGUgdGltZW91dCB3aWxsIGxpa2VseSBiZVxuICAgICAgICAvLyBzcGVjaWZpZWQgZHVyaW5nIGluaXRpYWxpemF0aW9uLlxuICAgICAgICB2YXIgbWF4VGltZW91dCA9IHRlc3QudGltZW91dCB8fCBleHBvcnRzLmRlZmF1bHRUaW1lb3V0XG5cbiAgICAgICAgLy8gU2V0dGluZyBhIHRpbWVvdXQgaXMgcG9pbnRsZXNzIGlmIGl0J3MgaW5maW5pdGUuXG4gICAgICAgIGlmIChtYXhUaW1lb3V0ICE9PSBJbmZpbml0eSkge1xuICAgICAgICAgICAgc3RhdGUudGltZXIgPSBzZXRUaW1lb3V0LmNhbGwoZ2xvYmFsLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlID09IG51bGwpIHJldHVyblxuICAgICAgICAgICAgICAgIGFzeW5jRmluaXNoKHN0YXRlLCB0cnlGYWlsKGFkZFN0YWNrKFxuICAgICAgICAgICAgICAgICAgICBuZXcgRXJyb3IoXCJUaW1lb3V0IG9mIFwiICsgbWF4VGltZW91dCArIFwiIHJlYWNoZWRcIikpKSlcbiAgICAgICAgICAgICAgICBzdGF0ZSA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgfSwgbWF4VGltZW91dClcbiAgICAgICAgfVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIEVycm9yV3JhcCh0ZXN0LCBlcnJvcikge1xuICAgIHRoaXMudGVzdCA9IHRlc3RcbiAgICB0aGlzLmVycm9yID0gZXJyb3Jcbn1cbm1ldGhvZHMoRXJyb3JXcmFwLCBFcnJvciwge25hbWU6IFwiRXJyb3JXcmFwXCJ9KVxuXG5mdW5jdGlvbiBpbnZva2VIb29rKHRlc3QsIGxpc3QsIHN0YWdlKSB7XG4gICAgaWYgKGxpc3QgPT0gbnVsbCkgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgcmV0dXJuIHBlYWNoKGxpc3QsIGZ1bmN0aW9uIChob29rKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gaG9vaygpXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcldyYXAodGVzdCwgbmV3IFJlcG9ydHMuSG9va0Vycm9yKHN0YWdlLCBob29rLCBlKSlcbiAgICAgICAgfVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIGludm9rZUJlZm9yZUVhY2godGVzdCkge1xuICAgIGlmICh0ZXN0LnJvb3QgPT09IHRlc3QpIHtcbiAgICAgICAgcmV0dXJuIGludm9rZUhvb2sodGVzdCwgdGVzdC5iZWZvcmVFYWNoLCBIb29rU3RhZ2UuQmVmb3JlRWFjaClcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gaW52b2tlQmVmb3JlRWFjaCh0ZXN0LnBhcmVudCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gaW52b2tlSG9vayh0ZXN0LCB0ZXN0LmJlZm9yZUVhY2gsIEhvb2tTdGFnZS5CZWZvcmVFYWNoKVxuICAgICAgICB9KVxuICAgIH1cbn1cblxuZnVuY3Rpb24gaW52b2tlQWZ0ZXJFYWNoKHRlc3QpIHtcbiAgICBpZiAodGVzdC5yb290ID09PSB0ZXN0KSB7XG4gICAgICAgIHJldHVybiBpbnZva2VIb29rKHRlc3QsIHRlc3QuYWZ0ZXJFYWNoLCBIb29rU3RhZ2UuQWZ0ZXJFYWNoKVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBpbnZva2VIb29rKHRlc3QsIHRlc3QuYWZ0ZXJFYWNoLCBIb29rU3RhZ2UuQWZ0ZXJFYWNoKVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBpbnZva2VBZnRlckVhY2godGVzdC5wYXJlbnQpIH0pXG4gICAgfVxufVxuXG4vKipcbiAqIFRoaXMgY2hlY2tzIGlmIHRoZSB0ZXN0IHdhcyB3aGl0ZWxpc3RlZCBpbiBhIGB0Lm9ubHkoKWAgY2FsbCwgb3IgZm9yXG4gKiBjb252ZW5pZW5jZSwgcmV0dXJucyBgdHJ1ZWAgaWYgYHQub25seSgpYCB3YXMgbmV2ZXIgY2FsbGVkLlxuICovXG5mdW5jdGlvbiBpc09ubHkodGVzdCkge1xuICAgIHZhciBwYXRoID0gW11cblxuICAgIHdoaWxlICh0ZXN0LnBhcmVudCAhPSBudWxsICYmIHRlc3Qub25seSA9PSBudWxsKSB7XG4gICAgICAgIHBhdGgucHVzaCh0ZXN0Lm5hbWUpXG4gICAgICAgIHRlc3QgPSB0ZXN0LnBhcmVudFxuICAgIH1cblxuICAgIC8vIElmIHRoZXJlIGlzbid0IGFueSBgb25seWAgYWN0aXZlLCB0aGVuIGxldCdzIHNraXAgdGhlIGNoZWNrIGFuZCByZXR1cm5cbiAgICAvLyBgdHJ1ZWAgZm9yIGNvbnZlbmllbmNlLlxuICAgIGlmICh0ZXN0Lm9ubHkgPT0gbnVsbCkgcmV0dXJuIHRydWVcbiAgICByZXR1cm4gRmlsdGVyLnRlc3QodGVzdC5vbmx5LCBwYXRoKVxufVxuXG5mdW5jdGlvbiBydW5DaGlsZFRlc3RzKHRlc3QsIGNvbnRleHQpIHtcbiAgICBpZiAodGVzdC50ZXN0cyA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgICBmdW5jdGlvbiBsZWF2ZSgpIHtcbiAgICAgICAgdGVzdC5yb290LmN1cnJlbnQgPSB0ZXN0XG4gICAgICAgIGNvbnRleHQudGVzdHMucG9wKClcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBydW5DaGlsZChjaGlsZCkge1xuICAgICAgICB0ZXN0LnJvb3QuY3VycmVudCA9IGNoaWxkXG4gICAgICAgIGNvbnRleHQudGVzdHMucHVzaChjaGlsZClcblxuICAgICAgICByZXR1cm4gaW52b2tlQmVmb3JlRWFjaCh0ZXN0KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBydW5Ob3JtYWxDaGlsZChjaGlsZCwgY29udGV4dCkgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gaW52b2tlQWZ0ZXJFYWNoKHRlc3QpIH0pXG4gICAgICAgIC5jYXRjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIEVycm9yV3JhcCkpIHRocm93IGVcbiAgICAgICAgICAgIHJldHVybiByZXBvcnRIb29rKGNvbnRleHQsIGUudGVzdCwgZS5lcnJvcilcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4obGVhdmUsIGZ1bmN0aW9uIChlKSB7IGxlYXZlKCk7IHRocm93IGUgfSlcbiAgICB9XG5cbiAgICB2YXIgcmFuID0gZmFsc2VcblxuICAgIHJldHVybiBwZWFjaCh0ZXN0LnRlc3RzLCBmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgLy8gT25seSBza2lwcGVkIHRlc3RzIGhhdmUgbm8gY2FsbGJhY2tcbiAgICAgICAgaWYgKGNoaWxkLmNhbGxiYWNrID09IG51bGwpIHtcbiAgICAgICAgICAgIHRlc3Qucm9vdC5jdXJyZW50ID0gY2hpbGRcbiAgICAgICAgICAgIGNvbnRleHQudGVzdHMucHVzaChjaGlsZClcblxuICAgICAgICAgICAgcmV0dXJuIHJlcG9ydFNraXAoY29udGV4dClcbiAgICAgICAgICAgIC50aGVuKGxlYXZlLCBmdW5jdGlvbiAoZSkgeyBsZWF2ZSgpOyB0aHJvdyBlIH0pXG4gICAgICAgIH0gZWxzZSBpZiAoIWlzT25seShjaGlsZCkpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICB9IGVsc2UgaWYgKHJhbikge1xuICAgICAgICAgICAgcmV0dXJuIHJ1bkNoaWxkKGNoaWxkKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmFuID0gdHJ1ZVxuICAgICAgICAgICAgcmV0dXJuIGludm9rZUhvb2sodGVzdCwgdGVzdC5iZWZvcmVBbGwsIEhvb2tTdGFnZS5CZWZvcmVBbGwpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBydW5DaGlsZChjaGlsZCkgfSlcbiAgICAgICAgfVxuICAgIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXJhbikgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICByZXR1cm4gaW52b2tlSG9vayh0ZXN0LCB0ZXN0LmFmdGVyQWxsLCBIb29rU3RhZ2UuQWZ0ZXJBbGwpXG4gICAgfSlcbn1cblxuZnVuY3Rpb24gY2xlYXJDaGlsZHJlbih0ZXN0KSB7XG4gICAgaWYgKHRlc3QudGVzdHMgPT0gbnVsbCkgcmV0dXJuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXN0LnRlc3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRlc3QudGVzdHNbaV0udGVzdHMgPSB1bmRlZmluZWRcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJ1bk5vcm1hbENoaWxkKHRlc3QsIGNvbnRleHQpIHtcbiAgICB0ZXN0LmxvY2tlZCA9IGZhbHNlXG5cbiAgICByZXR1cm4gaW52b2tlSW5pdChjb250ZXh0LCAxKVxuICAgIC50aGVuKFxuICAgICAgICBmdW5jdGlvbiAocmVzdWx0KSB7IHRlc3QubG9ja2VkID0gdHJ1ZTsgcmV0dXJuIHJlc3VsdCB9LFxuICAgICAgICBmdW5jdGlvbiAoZXJyb3IpIHsgdGVzdC5sb2NrZWQgPSB0cnVlOyB0aHJvdyBlcnJvciB9KVxuICAgIC50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgaWYgKHJlc3VsdC5jYXVnaHQpIHtcbiAgICAgICAgICAgIGlmICghdGVzdC5pc0ZhaWxhYmxlKSBjb250ZXh0LmlzU3VjY2VzcyA9IGZhbHNlXG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0RmFpbChjb250ZXh0LCByZXN1bHQudmFsdWUsIHJlc3VsdC50aW1lKVxuICAgICAgICB9IGVsc2UgaWYgKHRlc3QudGVzdHMgIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gUmVwb3J0IHRoaXMgYXMgaWYgaXQgd2FzIGEgcGFyZW50IHRlc3QgaWYgaXQncyBwYXNzaW5nIGFuZCBoYXNcbiAgICAgICAgICAgIC8vIGNoaWxkcmVuLlxuICAgICAgICAgICAgcmV0dXJuIHJlcG9ydEVudGVyKGNvbnRleHQsIHJlc3VsdC50aW1lKVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcnVuQ2hpbGRUZXN0cyh0ZXN0LCBjb250ZXh0KSB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVwb3J0TGVhdmUoY29udGV4dCkgfSlcbiAgICAgICAgICAgIC5jYXRjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBFcnJvcldyYXApKSB0aHJvdyBlXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcG9ydExlYXZlKGNvbnRleHQpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVwb3J0SG9vayhjb250ZXh0LCBlLnRlc3QsIGUuZXJyb3IpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0UGFzcyhjb250ZXh0LCByZXN1bHQudGltZSlcbiAgICAgICAgfVxuICAgIH0pXG4gICAgLnRoZW4oXG4gICAgICAgIGZ1bmN0aW9uICgpIHsgY2xlYXJDaGlsZHJlbih0ZXN0KSB9LFxuICAgICAgICBmdW5jdGlvbiAoZSkgeyBjbGVhckNoaWxkcmVuKHRlc3QpOyB0aHJvdyBlIH0pXG59XG5cbi8qKlxuICogVGhpcyBydW5zIHRoZSByb290IHRlc3QgYW5kIHJldHVybnMgYSBwcm9taXNlIHJlc29sdmVkIHdoZW4gaXQncyBkb25lLlxuICovXG5leHBvcnRzLnJ1blRlc3QgPSBmdW5jdGlvbiAocm9vdCwgb3B0cykge1xuICAgIHZhciBjb250ZXh0ID0gbmV3IENvbnRleHQocm9vdCwgb3B0cylcblxuICAgIHJvb3QubG9ja2VkID0gdHJ1ZVxuICAgIHJldHVybiByZXBvcnRTdGFydChjb250ZXh0KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHJ1bkNoaWxkVGVzdHMocm9vdCwgY29udGV4dCkgfSlcbiAgICAuY2F0Y2goZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIEVycm9yV3JhcCkpIHRocm93IGVcbiAgICAgICAgcmV0dXJuIHJlcG9ydEhvb2soY29udGV4dCwgZS50ZXN0LCBlLmVycm9yKVxuICAgIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcmVwb3J0RW5kKGNvbnRleHQpIH0pXG4gICAgLy8gVGVsbCB0aGUgcmVwb3J0ZXIgc29tZXRoaW5nIGhhcHBlbmVkLiBPdGhlcndpc2UsIGl0J2xsIGhhdmUgdG8gd3JhcCB0aGlzXG4gICAgLy8gbWV0aG9kIGluIGEgcGx1Z2luLCB3aGljaCBzaG91bGRuJ3QgYmUgbmVjZXNzYXJ5LlxuICAgIC5jYXRjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICByZXR1cm4gcmVwb3J0RXJyb3IoY29udGV4dCwgZSkudGhlbihmdW5jdGlvbiAoKSB7IHRocm93IGUgfSlcbiAgICB9KVxuICAgIC50aGVuKFxuICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjbGVhckNoaWxkcmVuKHJvb3QpXG4gICAgICAgICAgICByb290LmxvY2tlZCA9IGZhbHNlXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGlzU3VjY2VzczogY29udGV4dC5pc1N1Y2Nlc3MsXG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBjbGVhckNoaWxkcmVuKHJvb3QpXG4gICAgICAgICAgICByb290LmxvY2tlZCA9IGZhbHNlXG4gICAgICAgICAgICB0aHJvdyBlXG4gICAgICAgIH0pXG59XG5cbi8vIEhlbHAgb3B0aW1pemUgZm9yIGluZWZmaWNpZW50IGV4Y2VwdGlvbiBoYW5kbGluZyBpbiBWOFxuXG5mdW5jdGlvbiB0cnlQYXNzKHZhbHVlKSB7XG4gICAgcmV0dXJuIHtjYXVnaHQ6IGZhbHNlLCB2YWx1ZTogdmFsdWV9XG59XG5cbmZ1bmN0aW9uIHRyeUZhaWwoZSkge1xuICAgIHJldHVybiB7Y2F1Z2h0OiB0cnVlLCB2YWx1ZTogZX1cbn1cblxuZnVuY3Rpb24gdHJ5MChmKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHRyeVBhc3MoZigpKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIHRyeUZhaWwoZSlcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHRyeTEoZiwgaW5zdCwgYXJnMCkge1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiB0cnlQYXNzKGYuY2FsbChpbnN0LCBhcmcwKSlcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiB0cnlGYWlsKGUpXG4gICAgfVxufVxuXG5mdW5jdGlvbiB0cnkyKGYsIGluc3QsIGFyZzAsIGFyZzEpIHtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gdHJ5UGFzcyhmLmNhbGwoaW5zdCwgYXJnMCwgYXJnMSkpXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gdHJ5RmFpbChlKVxuICAgIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogVGhlIERPTSByZXBvcnRlciBhbmQgbG9hZGVyIGVudHJ5IHBvaW50LiBTZWUgdGhlIFJFQURNRS5tZCBmb3IgbW9yZSBkZXRhaWxzLlxuICovXG5cbnZhciBpbml0aWFsaXplID0gcmVxdWlyZShcIi4vaW5pdGlhbGl6ZVwiKVxuLy8gdmFyIHQgPSByZXF1aXJlKFwiLi4vLi4vaW5kZXhcIilcbi8vIHZhciBhc3NlcnQgPSByZXF1aXJlKFwiLi4vLi4vYXNzZXJ0XCIpXG5cbmV4cG9ydHMuY3JlYXRlID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgICBpZiAob3B0cyA9PSBudWxsKSByZXR1cm4gaW5pdGlhbGl6ZSh7fSlcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvcHRzKSkgcmV0dXJuIGluaXRpYWxpemUoe2ZpbGVzOiBvcHRzfSlcbiAgICBpZiAodHlwZW9mIG9wdHMgPT09IFwib2JqZWN0XCIpIHJldHVybiBpbml0aWFsaXplKG9wdHMpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBvcHRzYCBtdXN0IGJlIGFuIG9iamVjdCBvciBhcnJheSBvZiBmaWxlcyBpZiBwYXNzZWRcIilcbn1cblxuLy8gQ3VycmVudGx5IGJyb2tlbiwgYmVjYXVzZSB0aGlzIGlzbid0IGF1dG9sb2FkZWQgeWV0LlxuLy8gZXhwb3J0cy5hdXRvbG9hZCA9IGZ1bmN0aW9uIChzY3JpcHQpIHtcbi8vICAgICB2YXIgZmlsZXMgPSBzY3JpcHQuZ2V0QXR0cmlidXRlKFwiZGF0YS1maWxlc1wiKVxuLy9cbi8vICAgICBpZiAoIWZpbGVzKSByZXR1cm5cbi8vXG4vLyAgICAgZnVuY3Rpb24gc2V0KG9wdHMsIGF0dHIsIHRyYW5zZm9ybSkge1xuLy8gICAgICAgICB2YXIgdmFsdWUgPSBzY3JpcHQuZ2V0QXR0cmlidXRlKFwiZGF0YS1cIiArIGF0dHIpXG4vL1xuLy8gICAgICAgICBpZiAodmFsdWUpIG9wdHNbYXR0cl0gPSB0cmFuc2Zvcm0odmFsdWUpXG4vLyAgICAgfVxuLy9cbi8vICAgICB2YXIgb3B0cyA9IHtmaWxlczogZmlsZXMudHJpbSgpLnNwbGl0KC9cXHMrL2cpfVxuLy9cbi8vICAgICBzZXQob3B0cywgXCJ0aW1lb3V0XCIsIE51bWJlcilcbi8vICAgICBzZXQob3B0cywgXCJwcmVsb2FkXCIsIEZ1bmN0aW9uKVxuLy8gICAgIHNldChvcHRzLCBcInByZXJ1blwiLCBGdW5jdGlvbilcbi8vICAgICBzZXQob3B0cywgXCJwb3N0cnVuXCIsIEZ1bmN0aW9uKVxuLy8gICAgIHNldChvcHRzLCBcImVycm9yXCIsIGZ1bmN0aW9uIChhdHRyKSB7XG4vLyAgICAgICAgIHJldHVybiBuZXcgRnVuY3Rpb24oXCJlcnJcIiwgYXR0cikgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuLy8gICAgIH0pXG4vL1xuLy8gICAgIC8vIENvbnZlbmllbmNlLlxuLy8gICAgIGdsb2JhbC50ID0gdFxuLy8gICAgIGdsb2JhbC5hc3NlcnQgPSBhc3NlcnRcbi8vXG4vLyAgICAgaWYgKGdsb2JhbC5kb2N1bWVudC5yZWFkeVN0YXRlICE9PSBcImxvYWRpbmdcIikge1xuLy8gICAgICAgICBpbml0aWFsaXplKG9wdHMpLnJ1bigpXG4vLyAgICAgfSBlbHNlIHtcbi8vICAgICAgICAgZ2xvYmFsLmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uICgpIHtcbi8vICAgICAgICAgICAgIGluaXRpYWxpemUob3B0cykucnVuKClcbi8vICAgICAgICAgfSlcbi8vICAgICB9XG4vLyB9XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vKipcbiAqIFRoZSByZXBvcnRlciBhbmQgdGVzdCBpbml0aWFsaXphdGlvbiBzZXF1ZW5jZSwgYW5kIHNjcmlwdCBsb2FkaW5nLiBUaGlzXG4gKiBkb2Vzbid0IHVuZGVyc3RhbmQgYW55dGhpbmcgdmlldy13aXNlLlxuICovXG5cbnZhciBkZWZhdWx0VCA9IHJlcXVpcmUoXCIuLi8uLi9pbmRleFwiKVxudmFyIFIgPSByZXF1aXJlKFwiLi4vcmVwb3J0ZXJcIilcbnZhciBEID0gcmVxdWlyZShcIi4vaW5qZWN0XCIpXG52YXIgcnVuVGVzdHMgPSByZXF1aXJlKFwiLi9ydW4tdGVzdHNcIilcbnZhciBpbmplY3RTdHlsZXMgPSByZXF1aXJlKFwiLi9pbmplY3Qtc3R5bGVzXCIpXG52YXIgVmlldyA9IHJlcXVpcmUoXCIuL3ZpZXdcIilcbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcblxuZnVuY3Rpb24gVHJlZShuYW1lKSB7XG4gICAgdGhpcy5uYW1lID0gbmFtZVxuICAgIHRoaXMuc3RhdHVzID0gUi5TdGF0dXMuVW5rbm93blxuICAgIHRoaXMubm9kZSA9IG51bGxcbiAgICB0aGlzLmNoaWxkcmVuID0gT2JqZWN0LmNyZWF0ZShudWxsKVxufVxuXG52YXIgcmVwb3J0ZXIgPSBSLm9uKFwiZG9tXCIsIHtcbiAgICBhY2NlcHRzOiBbXSxcbiAgICBjcmVhdGU6IGZ1bmN0aW9uIChvcHRzLCBtZXRob2RzKSB7XG4gICAgICAgIHZhciByZXBvcnRlciA9IG5ldyBSLlJlcG9ydGVyKFRyZWUsIHVuZGVmaW5lZCwgbWV0aG9kcylcblxuICAgICAgICByZXBvcnRlci5vcHRzID0gb3B0c1xuICAgICAgICByZXR1cm4gcmVwb3J0ZXJcbiAgICB9LFxuXG4gICAgLy8gR2l2ZSB0aGUgYnJvd3NlciBhIGNoYW5jZSB0byByZXBhaW50IGJlZm9yZSBjb250aW51aW5nIChtaWNyb3Rhc2tzXG4gICAgLy8gbm9ybWFsbHkgYmxvY2sgcmVuZGVyaW5nKS5cbiAgICBhZnRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoVmlldy5uZXh0RnJhbWUpXG4gICAgfSxcblxuICAgIHJlcG9ydDogZnVuY3Rpb24gKF8sIHJlcG9ydCkge1xuICAgICAgICByZXR1cm4gVmlldy5yZXBvcnQoXywgcmVwb3J0KVxuICAgIH0sXG59KVxuXG5mdW5jdGlvbiBub29wKCkge31cblxuZnVuY3Rpb24gc2V0RGVmYXVsdHNDaGVja2VkKG9wdHMpIHtcbiAgICBpZiAob3B0cy50aXRsZSA9PSBudWxsKSBvcHRzLnRpdGxlID0gXCJUaGFsbGl1bSB0ZXN0c1wiXG4gICAgaWYgKG9wdHMudGltZW91dCA9PSBudWxsKSBvcHRzLnRpbWVvdXQgPSA1MDAwXG4gICAgaWYgKG9wdHMuZmlsZXMgPT0gbnVsbCkgb3B0cy5maWxlcyA9IFtdXG4gICAgaWYgKG9wdHMucHJlbG9hZCA9PSBudWxsKSBvcHRzLnByZWxvYWQgPSBub29wXG4gICAgaWYgKG9wdHMucHJlcnVuID09IG51bGwpIG9wdHMucHJlcnVuID0gbm9vcFxuICAgIGlmIChvcHRzLnBvc3RydW4gPT0gbnVsbCkgb3B0cy5wb3N0cnVuID0gbm9vcFxuICAgIGlmIChvcHRzLmVycm9yID09IG51bGwpIG9wdHMuZXJyb3IgPSBub29wXG4gICAgaWYgKG9wdHMudGhhbGxpdW0gPT0gbnVsbCkgb3B0cy50aGFsbGl1bSA9IGRlZmF1bHRUXG5cbiAgICBpZiAodHlwZW9mIG9wdHMudGl0bGUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBvcHRzLnRpdGxlYCBtdXN0IGJlIGEgc3RyaW5nIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy50aW1lb3V0ICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgb3B0cy50aW1lb3V0YCBtdXN0IGJlIGEgbnVtYmVyIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICghQXJyYXkuaXNBcnJheShvcHRzLmZpbGVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMuZmlsZXNgIG11c3QgYmUgYW4gYXJyYXkgaWYgcGFzc2VkXCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLnByZWxvYWQgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMucHJlbG9hZGAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5wcmVydW4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMucHJlcnVuYCBtdXN0IGJlIGEgZnVuY3Rpb24gaWYgcGFzc2VkXCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvcHRzLnBvc3RydW4gIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG9wdHMucG9zdHJ1bmAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy5lcnJvciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgb3B0cy5lcnJvcmAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0cy50aGFsbGl1bSAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgXCJgb3B0cy50aGFsbGl1bWAgbXVzdCBiZSBhIFRoYWxsaXVtIGluc3RhbmNlIGlmIHBhc3NlZFwiKVxuICAgIH1cbn1cblxuZnVuY3Rpb24gb25SZWFkeShpbml0KSB7XG4gICAgaWYgKEQuZG9jdW1lbnQuYm9keSAhPSBudWxsKSByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGluaXQoKSlcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgRC5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXNvbHZlKGluaXQoKSlcbiAgICAgICAgfSwgZmFsc2UpXG4gICAgfSlcbn1cblxuZnVuY3Rpb24gRE9NKG9wdHMpIHtcbiAgICB0aGlzLl9vcHRzID0gb3B0c1xuICAgIHRoaXMuX2Rlc3Ryb3lQcm9taXNlID0gdW5kZWZpbmVkXG4gICAgdGhpcy5fZGF0YSA9IG9uUmVhZHkoZnVuY3Rpb24gKCkge1xuICAgICAgICBzZXREZWZhdWx0c0NoZWNrZWQob3B0cylcbiAgICAgICAgaWYgKCFELmRvY3VtZW50LnRpdGxlKSBELmRvY3VtZW50LnRpdGxlID0gb3B0cy50aXRsZVxuICAgICAgICBpbmplY3RTdHlsZXMoKVxuICAgICAgICB2YXIgZGF0YSA9IFZpZXcuaW5pdChvcHRzKVxuXG4gICAgICAgIG9wdHMudGhhbGxpdW0ucmVwb3J0ZXIocmVwb3J0ZXIsIGRhdGEuc3RhdGUpXG4gICAgICAgIHJldHVybiBkYXRhXG4gICAgfSlcbn1cblxubWV0aG9kcyhET00sIHtcbiAgICBydW46IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2Rlc3Ryb3lQcm9taXNlICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJUaGUgdGVzdCBzdWl0ZSBtdXN0IG5vdCBiZSBydW4gYWZ0ZXIgdGhlIHZpZXcgaGFzIGJlZW4gXCIgK1xuICAgICAgICAgICAgICAgIFwiZGV0YWNoZWQuXCJcbiAgICAgICAgICAgICkpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgb3B0cyA9IHRoaXMuX29wdHNcblxuICAgICAgICByZXR1cm4gdGhpcy5fZGF0YS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICByZXR1cm4gcnVuVGVzdHMob3B0cywgZGF0YS5zdGF0ZSlcbiAgICAgICAgfSlcbiAgICB9LFxuXG4gICAgZGV0YWNoOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kZXN0cm95UHJvbWlzZSAhPSBudWxsKSByZXR1cm4gdGhpcy5fZGVzdHJveVByb21pc2VcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rlc3Ryb3lQcm9taXNlID0gc2VsZi5fZGF0YS50aGVuKGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICBkYXRhLnN0YXRlLmxvY2tlZCA9IHRydWVcbiAgICAgICAgICAgIGlmIChkYXRhLnN0YXRlLmN1cnJlbnRQcm9taXNlID09IG51bGwpIHJldHVybiBkYXRhXG4gICAgICAgICAgICByZXR1cm4gZGF0YS5zdGF0ZS5jdXJyZW50UHJvbWlzZS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIGRhdGEgfSlcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgIHNlbGYuX29wdHMgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIHNlbGYuX2RhdGEgPSBzZWxmLl9kZXN0cm95UHJvbWlzZVxuXG4gICAgICAgICAgICB3aGlsZSAoZGF0YS5yb290LmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBkYXRhLnJvb3QucmVtb3ZlQ2hpbGQoZGF0YS5yb290LmZpcnN0Q2hpbGQpXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgfSxcbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdHMpIHtcbiAgICByZXR1cm4gbmV3IERPTShvcHRzKVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIFV0aWwgPSByZXF1aXJlKFwiLi4vdXRpbFwiKVxudmFyIEQgPSByZXF1aXJlKFwiLi9pbmplY3RcIilcblxuLyoqXG4gKiBUaGUgcmVwb3J0ZXIgc3R5bGVzaGVldC4gSGVyZSdzIHRoZSBmb3JtYXQ6XG4gKlxuICogLy8gU2luZ2xlIGl0ZW1cbiAqIFwiLnNlbGVjdG9yXCI6IHtcbiAqICAgICAvLyBwcm9wcy4uLlxuICogfVxuICpcbiAqIC8vIER1cGxpY2F0ZSBlbnRyaWVzXG4gKiBcIi5zZWxlY3RvclwiOiB7XG4gKiAgICAgXCJwcm9wXCI6IFtcbiAqICAgICAgICAgLy8gdmFsdWVzLi4uXG4gKiAgICAgXSxcbiAqIH1cbiAqXG4gKiAvLyBEdXBsaWNhdGUgc2VsZWN0b3JzXG4gKiBcIi5zZWxlY3RvclwiOiBbXG4gKiAgICAgLy8gdmFsdWVzLi4uXG4gKiBdXG4gKlxuICogLy8gTWVkaWEgcXVlcnlcbiAqIFwiQG1lZGlhIHNjcmVlblwiOiB7XG4gKiAgICAgLy8gc2VsZWN0b3JzLi4uXG4gKiB9XG4gKlxuICogTm90ZSB0aGF0IENTUyBzdHJpbmdzICptdXN0KiBiZSBxdW90ZWQgaW5zaWRlIHRoZSB2YWx1ZS5cbiAqL1xuXG52YXIgc3R5bGVzID0gVXRpbC5sYXp5KGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eVxuXG4gICAgLyoqXG4gICAgICogUGFydGlhbGx5IHRha2VuIGFuZCBhZGFwdGVkIGZyb20gbm9ybWFsaXplLmNzcyAobGljZW5zZWQgdW5kZXIgdGhlIE1JVFxuICAgICAqIExpY2Vuc2UpLlxuICAgICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9uZWNvbGFzL25vcm1hbGl6ZS5jc3NcbiAgICAgKi9cbiAgICB2YXIgc3R5bGVPYmplY3QgPSB7XG4gICAgICAgIFwiI3RsXCI6IHtcbiAgICAgICAgICAgIFwiZm9udC1mYW1pbHlcIjogXCJzYW5zLXNlcmlmXCIsXG4gICAgICAgICAgICBcImxpbmUtaGVpZ2h0XCI6IFwiMS4xNVwiLFxuICAgICAgICAgICAgXCItbXMtdGV4dC1zaXplLWFkanVzdFwiOiBcIjEwMCVcIixcbiAgICAgICAgICAgIFwiLXdlYmtpdC10ZXh0LXNpemUtYWRqdXN0XCI6IFwiMTAwJVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIGJ1dHRvblwiOiB7XG4gICAgICAgICAgICBcImZvbnQtZmFtaWx5XCI6IFwic2Fucy1zZXJpZlwiLFxuICAgICAgICAgICAgXCJsaW5lLWhlaWdodFwiOiBcIjEuMTVcIixcbiAgICAgICAgICAgIFwib3ZlcmZsb3dcIjogXCJ2aXNpYmxlXCIsXG4gICAgICAgICAgICBcImZvbnQtc2l6ZVwiOiBcIjEwMCVcIixcbiAgICAgICAgICAgIFwibWFyZ2luXCI6IFwiMFwiLFxuICAgICAgICAgICAgXCJ0ZXh0LXRyYW5zZm9ybVwiOiBcIm5vbmVcIixcbiAgICAgICAgICAgIFwiLXdlYmtpdC1hcHBlYXJhbmNlXCI6IFwiYnV0dG9uXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgaDFcIjoge1xuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIyZW1cIixcbiAgICAgICAgICAgIFwibWFyZ2luXCI6IFwiMC42N2VtIDBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCBhXCI6IHtcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcInRyYW5zcGFyZW50XCIsXG4gICAgICAgICAgICBcIi13ZWJraXQtdGV4dC1kZWNvcmF0aW9uLXNraXBcIjogXCJvYmplY3RzXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgYTphY3RpdmUsICN0bCBhOmhvdmVyXCI6IHtcbiAgICAgICAgICAgIFwib3V0bGluZS13aWR0aFwiOiBcIjBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCBidXR0b246Oi1tb3otZm9jdXMtaW5uZXJcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItc3R5bGVcIjogXCJub25lXCIsXG4gICAgICAgICAgICBcInBhZGRpbmdcIjogXCIwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgYnV0dG9uOi1tb3otZm9jdXNyaW5nXCI6IHtcbiAgICAgICAgICAgIG91dGxpbmU6IFwiMXB4IGRvdHRlZCBCdXR0b25UZXh0XCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEJhc2Ugc3R5bGVzLiBOb3RlIHRoYXQgdGhpcyBDU1MgaXMgZGVzaWduZWQgdG8gaW50ZW50aW9uYWxseSBvdmVycmlkZVxuICAgICAgICAgKiBtb3N0IHRoaW5ncyB0aGF0IGNvdWxkIHByb3BhZ2F0ZS5cbiAgICAgICAgICovXG4gICAgICAgIFwiI3RsICpcIjogW1xuICAgICAgICAgICAge1widGV4dC1hbGlnblwiOiBcImxlZnRcIn0sXG4gICAgICAgICAgICB7XCJ0ZXh0LWFsaWduXCI6IFwic3RhcnRcIn0sXG4gICAgICAgIF0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydCwgI3RsIC50bC1yZXBvcnQgdWxcIjoge1xuICAgICAgICAgICAgXCJsaXN0LXN0eWxlLXR5cGVcIjogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgbGkgfiAudGwtc3VpdGVcIjoge1xuICAgICAgICAgICAgXCJwYWRkaW5nLXRvcFwiOiBcIjFlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1zdWl0ZSA+IGgyXCI6IHtcbiAgICAgICAgICAgIFwiY29sb3JcIjogXCJibGFja1wiLFxuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIxLjVlbVwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcImJvbGRcIixcbiAgICAgICAgICAgIFwibWFyZ2luLWJvdHRvbVwiOiBcIjAuNWVtXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXN1aXRlIC50bC1zdWl0ZSA+IGgyXCI6IHtcbiAgICAgICAgICAgIFwiZm9udC1zaXplXCI6IFwiMS4yZW1cIixcbiAgICAgICAgICAgIFwibWFyZ2luLWJvdHRvbVwiOiBcIjAuM2VtXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXN1aXRlIC50bC1zdWl0ZSAudGwtc3VpdGUgPiBoMlwiOiB7XG4gICAgICAgICAgICBcImZvbnQtc2l6ZVwiOiBcIjEuMmVtXCIsXG4gICAgICAgICAgICBcIm1hcmdpbi1ib3R0b21cIjogXCIwLjJlbVwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcIm5vcm1hbFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0ID4gaDJcIjoge1xuICAgICAgICAgICAgXCJjb2xvclwiOiBcImJsYWNrXCIsXG4gICAgICAgICAgICBcImZvbnQtc2l6ZVwiOiBcIjFlbVwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcIm5vcm1hbFwiLFxuICAgICAgICAgICAgXCJtYXJnaW5cIjogXCIwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRlc3QgPiA6Zmlyc3QtY2hpbGQ6OmJlZm9yZVwiOiB7XG4gICAgICAgICAgICBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgICAgICAgIFwiZm9udC13ZWlnaHRcIjogXCJib2xkXCIsXG4gICAgICAgICAgICBcIndpZHRoXCI6IFwiMS4yZW1cIixcbiAgICAgICAgICAgIFwidGV4dC1hbGlnblwiOiBcImNlbnRlclwiLFxuICAgICAgICAgICAgXCJmb250LWZhbWlseVwiOiBcInNhbnMtc2VyaWZcIixcbiAgICAgICAgICAgIFwidGV4dC1zaGFkb3dcIjogXCIwIDNweCAycHggIzk2OTY5NlwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0LnRsLWZhaWwgPiBoMiwgI3RsIC50bC10ZXN0LnRsLWVycm9yID4gaDJcIjoge1xuICAgICAgICAgICAgY29sb3I6IFwiI2MwMFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0LnRsLXNraXAgPiBoMlwiOiB7XG4gICAgICAgICAgICBjb2xvcjogXCIjMDhjXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRlc3QudGwtcGFzcyA+IDpmaXJzdC1jaGlsZDo6YmVmb3JlXCI6IHtcbiAgICAgICAgICAgIGNvbnRlbnQ6IFwiJ+KckydcIixcbiAgICAgICAgICAgIGNvbG9yOiBcIiMwYzBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdGVzdC50bC1mYWlsID4gOmZpcnN0LWNoaWxkOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCIn4pyWJ1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10ZXN0LnRsLWVycm9yID4gOmZpcnN0LWNoaWxkOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCInISdcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdGVzdC50bC1za2lwID4gOmZpcnN0LWNoaWxkOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCIn4oiSJ1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1wcmUsICN0bCAudGwtZGlmZi1oZWFkZXJcIjoge1xuICAgICAgICAgICAgLy8gbm9ybWFsaXplLmNzczogQ29ycmVjdCB0aGUgaW5oZXJpdGFuY2UgYW5kIHNjYWxpbmcgb2YgZm9udCBzaXplXG4gICAgICAgICAgICAvLyBpbiBhbGwgYnJvd3NlcnNcbiAgICAgICAgICAgIFwiZm9udC1mYW1pbHlcIjogXCJtb25vc3BhY2UsIG1vbm9zcGFjZVwiLFxuICAgICAgICAgICAgXCJiYWNrZ3JvdW5kXCI6IFwiI2YwZjBmMFwiLFxuICAgICAgICAgICAgXCJ3aGl0ZS1zcGFjZVwiOiBcInByZVwiLFxuICAgICAgICAgICAgXCJmb250LXNpemVcIjogXCIwLjg1ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtcHJlXCI6IHtcbiAgICAgICAgICAgIFwibWluLXdpZHRoXCI6IFwiMTAwJVwiLFxuICAgICAgICAgICAgXCJmbG9hdFwiOiBcImxlZnRcIixcbiAgICAgICAgICAgIFwiY2xlYXJcIjogXCJsZWZ0XCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLWxpbmVcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJibG9ja1wiLFxuICAgICAgICAgICAgbWFyZ2luOiBcIjAgMC4yNWVtXCIsXG4gICAgICAgICAgICB3aWR0aDogXCI5OSVcIiwgLy8gQmVjYXVzZSBGaXJlZm94IHN1Y2tzXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLWRpZmYtaGVhZGVyID4gKlwiOiB7XG4gICAgICAgICAgICBwYWRkaW5nOiBcIjAuMjVlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1kaWZmLWhlYWRlclwiOiB7XG4gICAgICAgICAgICBcInBhZGRpbmdcIjogXCIwLjI1ZW1cIixcbiAgICAgICAgICAgIFwibWFyZ2luLWJvdHRvbVwiOiBcIjAuNWVtXCIsXG4gICAgICAgICAgICBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtbGluZTpmaXJzdC1jaGlsZCwgI3RsIC50bC1kaWZmLWhlYWRlciB+IC50bC1saW5lXCI6IHtcbiAgICAgICAgICAgIFwicGFkZGluZy10b3BcIjogXCIwLjI1ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtbGluZTpsYXN0LWNoaWxkXCI6IHtcbiAgICAgICAgICAgIFwicGFkZGluZy1ib3R0b21cIjogXCIwLjI1ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZmFpbCAudGwtZGlzcGxheVwiOiB7XG4gICAgICAgICAgICBtYXJnaW46IFwiMC41ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZGlzcGxheSA+ICpcIjoge1xuICAgICAgICAgICAgb3ZlcmZsb3c6IFwiYXV0b1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1kaXNwbGF5ID4gOm5vdCg6bGFzdC1jaGlsZClcIjoge1xuICAgICAgICAgICAgXCJtYXJnaW4tYm90dG9tXCI6IFwiMC41ZW1cIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZGlmZi1hZGRlZFwiOiB7XG4gICAgICAgICAgICBcImNvbG9yXCI6IFwiIzBjMFwiLFxuICAgICAgICAgICAgXCJmb250LXdlaWdodFwiOiBcImJvbGRcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtZGlmZi1yZW1vdmVkXCI6IHtcbiAgICAgICAgICAgIFwiY29sb3JcIjogXCIjYzAwXCIsXG4gICAgICAgICAgICBcImZvbnQtd2VpZ2h0XCI6IFwiYm9sZFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1zdGFjayAudGwtbGluZVwiOiB7XG4gICAgICAgICAgICBjb2xvcjogXCIjODAwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLWRpZmY6OmJlZm9yZSwgI3RsIC50bC1zdGFjazo6YmVmb3JlXCI6IHtcbiAgICAgICAgICAgIFwiZm9udC13ZWlnaHRcIjogXCJub3JtYWxcIixcbiAgICAgICAgICAgIFwibWFyZ2luXCI6IFwiMC4yNWVtIDAuMjVlbSAwLjI1ZW0gMFwiLFxuICAgICAgICAgICAgXCJkaXNwbGF5XCI6IFwiYmxvY2tcIixcbiAgICAgICAgICAgIFwiZm9udC1zdHlsZVwiOiBcIml0YWxpY1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1kaWZmOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCInRGlmZjonXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXN0YWNrOjpiZWZvcmVcIjoge1xuICAgICAgICAgICAgY29udGVudDogXCInU3RhY2s6J1wiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1oZWFkZXJcIjoge1xuICAgICAgICAgICAgXCJ0ZXh0LWFsaWduXCI6IFwicmlnaHRcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtaGVhZGVyID4gKlwiOiB7XG4gICAgICAgICAgICBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgICAgICAgIFwidGV4dC1hbGlnblwiOiBcImNlbnRlclwiLFxuICAgICAgICAgICAgXCJwYWRkaW5nXCI6IFwiMC41ZW0gMC43NWVtXCIsXG4gICAgICAgICAgICBcImJvcmRlclwiOiBcIjJweCBzb2xpZCAjMDBjXCIsXG4gICAgICAgICAgICBcImJvcmRlci1yYWRpdXNcIjogXCIxZW1cIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcInRyYW5zcGFyZW50XCIsXG4gICAgICAgICAgICBcIm1hcmdpblwiOiBcIjAuMjVlbSAwLjVlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1oZWFkZXIgPiA6Zm9jdXNcIjoge1xuICAgICAgICAgICAgb3V0bGluZTogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJ1blwiOiB7XG4gICAgICAgICAgICBcImJvcmRlci1jb2xvclwiOiBcIiMwODBcIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcIiMwYzBcIixcbiAgICAgICAgICAgIFwiY29sb3JcIjogXCJ3aGl0ZVwiLFxuICAgICAgICAgICAgXCJ3aWR0aFwiOiBcIjZlbVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC1ydW46aG92ZXJcIjoge1xuICAgICAgICAgICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCI6IFwiIzhjOFwiLFxuICAgICAgICAgICAgXCJjb2xvclwiOiBcIndoaXRlXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1wYXNzXCI6IHtcbiAgICAgICAgICAgIFwiYm9yZGVyLWNvbG9yXCI6IFwiIzBjMFwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10b2dnbGUudGwtZmFpbFwiOiB7XG4gICAgICAgICAgICBcImJvcmRlci1jb2xvclwiOiBcIiNjMDBcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdG9nZ2xlLnRsLXNraXBcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDhjXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1wYXNzLnRsLWFjdGl2ZSwgI3RsIC50bC10b2dnbGUudGwtcGFzczphY3RpdmVcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDgwXCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjMGMwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1mYWlsLnRsLWFjdGl2ZSwgI3RsIC50bC10b2dnbGUudGwtZmFpbDphY3RpdmVcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjODAwXCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjYzAwXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1za2lwLnRsLWFjdGl2ZSwgI3RsIC50bC10b2dnbGUudGwtc2tpcDphY3RpdmVcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDU4XCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjMDhjXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXRvZ2dsZS50bC1wYXNzOmhvdmVyXCI6IHtcbiAgICAgICAgICAgIFwiYm9yZGVyLWNvbG9yXCI6IFwiIzBjMFwiLFxuICAgICAgICAgICAgXCJiYWNrZ3JvdW5kLWNvbG9yXCI6IFwiI2FmYVwiLFxuICAgICAgICB9LFxuXG4gICAgICAgIFwiI3RsIC50bC10b2dnbGUudGwtZmFpbDpob3ZlclwiOiB7XG4gICAgICAgICAgICBcImJvcmRlci1jb2xvclwiOiBcIiNjMDBcIixcbiAgICAgICAgICAgIFwiYmFja2dyb3VuZC1jb2xvclwiOiBcIiNmYWFcIixcbiAgICAgICAgfSxcblxuICAgICAgICBcIiN0bCAudGwtdG9nZ2xlLnRsLXNraXA6aG92ZXJcIjoge1xuICAgICAgICAgICAgXCJib3JkZXItY29sb3JcIjogXCIjMDhjXCIsXG4gICAgICAgICAgICBcImJhY2tncm91bmQtY29sb3JcIjogXCIjYmRmXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydC50bC1wYXNzIC50bC10ZXN0Om5vdCgudGwtcGFzcylcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydC50bC1mYWlsIC50bC10ZXN0Om5vdCgudGwtZmFpbClcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJub25lXCIsXG4gICAgICAgIH0sXG5cbiAgICAgICAgXCIjdGwgLnRsLXJlcG9ydC50bC1za2lwIC50bC10ZXN0Om5vdCgudGwtc2tpcClcIjoge1xuICAgICAgICAgICAgZGlzcGxheTogXCJub25lXCIsXG4gICAgICAgIH0sXG4gICAgfVxuXG4gICAgdmFyIGNzcyA9IFwiXCJcblxuICAgIGZ1bmN0aW9uIGFwcGVuZEJhc2Uoc2VsZWN0b3IsIHByb3BzKSB7XG4gICAgICAgIGNzcyArPSBzZWxlY3RvciArIFwie1wiXG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocHJvcHMpKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgYXBwZW5kUHJvcHMocHJvcHNbaV0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhcHBlbmRQcm9wcyhwcm9wcylcbiAgICAgICAgfVxuXG4gICAgICAgIGNzcyArPSBcIn1cIlxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFwcGVuZFByb3BzKHByb3BzKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBwcm9wcykge1xuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKHByb3BzLCBrZXkpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwcm9wc1trZXldID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGFwcGVuZEJhc2Uoa2V5LCBwcm9wc1trZXldKVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNzcyArPSBrZXkgKyBcIjpcIiArIHByb3BzW2tleV0gKyBcIjtcIlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIHNlbGVjdG9yIGluIHN0eWxlT2JqZWN0KSB7XG4gICAgICAgIGlmIChoYXNPd24uY2FsbChzdHlsZU9iamVjdCwgc2VsZWN0b3IpKSB7XG4gICAgICAgICAgICBhcHBlbmRCYXNlKHNlbGVjdG9yLCBzdHlsZU9iamVjdFtzZWxlY3Rvcl0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY3NzLmNvbmNhdCgpIC8vIEhpbnQgdG8gZmxhdHRlbi5cbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICAgIGlmIChELmRvY3VtZW50LmhlYWQucXVlcnlTZWxlY3RvcihcInN0eWxlW2RhdGEtdGwtc3R5bGVdXCIpID09IG51bGwpIHtcbiAgICAgICAgdmFyIHN0eWxlID0gRC5kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIilcblxuICAgICAgICBzdHlsZS50eXBlID0gXCJ0ZXh0L2Nzc1wiXG4gICAgICAgIHN0eWxlLnNldEF0dHJpYnV0ZShcImRhdGEtdGwtc3R5bGVcIiwgXCJcIilcbiAgICAgICAgaWYgKHN0eWxlLnN0eWxlU2hlZXQpIHtcbiAgICAgICAgICAgIHN0eWxlLnN0eWxlU2hlZXQuY3NzVGV4dCA9IHN0eWxlcygpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHlsZS5hcHBlbmRDaGlsZChELmRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHN0eWxlcygpKSlcbiAgICAgICAgfVxuXG4gICAgICAgIEQuZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZChzdHlsZSlcbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vKipcbiAqIFRoZSBnbG9iYWwgaW5qZWN0aW9ucyBmb3IgdGhlIERPTS4gTWFpbmx5IGZvciBkZWJ1Z2dpbmcuXG4gKi9cblxuZXhwb3J0cy5kb2N1bWVudCA9IGdsb2JhbC5kb2N1bWVudFxuZXhwb3J0cy53aW5kb3cgPSBnbG9iYWwud2luZG93XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpXG52YXIgRCA9IHJlcXVpcmUoXCIuL2luamVjdFwiKVxudmFyIG5vdyA9IERhdGUubm93IC8vIEF2b2lkIFNpbm9uJ3MgbW9ja1xudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuLyoqXG4gKiBUZXN0IHJ1bm5lciBhbmQgc2NyaXB0IGxvYWRlclxuICovXG5cbmZ1bmN0aW9uIHVuY2FjaGVkKGZpbGUpIHtcbiAgICBpZiAoZmlsZS5pbmRleE9mKFwiP1wiKSA8IDApIHtcbiAgICAgICAgcmV0dXJuIGZpbGUgKyBcIj9sb2FkZWQ9XCIgKyBub3coKVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmaWxlICsgXCImbG9hZGVkPVwiICsgbm93KClcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxvYWRTY3JpcHQoZmlsZSwgdGltZW91dCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIHZhciBzY3JpcHQgPSBELmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIilcbiAgICAgICAgdmFyIHRpbWVyID0gZ2xvYmFsLnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY2xlYXIoKVxuICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIlRpbWVvdXQgZXhjZWVkZWQgbG9hZGluZyAnXCIgKyBmaWxlICsgXCInXCIpKVxuICAgICAgICB9LCB0aW1lb3V0KVxuXG4gICAgICAgIGZ1bmN0aW9uIGNsZWFyKGV2KSB7XG4gICAgICAgICAgICBpZiAoZXYgIT0gbnVsbCkgZXYucHJldmVudERlZmF1bHQoKVxuICAgICAgICAgICAgaWYgKGV2ICE9IG51bGwpIGV2LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICAgICAgICBnbG9iYWwuY2xlYXJUaW1lb3V0KHRpbWVyKVxuICAgICAgICAgICAgc2NyaXB0Lm9ubG9hZCA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgc2NyaXB0Lm9uZXJyb3IgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIEQuZG9jdW1lbnQuaGVhZC5yZW1vdmVDaGlsZChzY3JpcHQpXG4gICAgICAgIH1cblxuICAgICAgICBzY3JpcHQuc3JjID0gdW5jYWNoZWQoZmlsZSlcbiAgICAgICAgc2NyaXB0LmFzeW5jID0gdHJ1ZVxuICAgICAgICBzY3JpcHQuZGVmZXIgPSB0cnVlXG4gICAgICAgIHNjcmlwdC5vbmxvYWQgPSBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIGNsZWFyKGV2KVxuICAgICAgICAgICAgcmVzb2x2ZSgpXG4gICAgICAgIH1cblxuICAgICAgICBzY3JpcHQub25lcnJvciA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgY2xlYXIoZXYpXG4gICAgICAgICAgICByZWplY3QoZXYpXG4gICAgICAgIH1cblxuICAgICAgICBELmRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KVxuICAgIH0pXG59XG5cbmZ1bmN0aW9uIHRyeURlbGV0ZShrZXkpIHtcbiAgICB0cnkge1xuICAgICAgICBkZWxldGUgZ2xvYmFsW2tleV1cbiAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgIC8vIGlnbm9yZVxuICAgIH1cbn1cblxuZnVuY3Rpb24gZGVzY3JpcHRvckNoYW5nZWQoYSwgYikge1xuICAgIC8vIE5vdGU6IGlmIHRoZSBkZXNjcmlwdG9yIHdhcyByZW1vdmVkLCBpdCB3b3VsZCd2ZSBiZWVuIGRlbGV0ZWQsIGFueXdheXMuXG4gICAgaWYgKGEgPT0gbnVsbCkgcmV0dXJuIGZhbHNlXG4gICAgaWYgKGEuY29uZmlndXJhYmxlICE9PSBiLmNvbmZpZ3VyYWJsZSkgcmV0dXJuIHRydWVcbiAgICBpZiAoYS5lbnVtZXJhYmxlICE9PSBiLmVudW1lcmFibGUpIHJldHVybiB0cnVlXG4gICAgaWYgKGEud3JpdGFibGUgIT09IGIud3JpdGFibGUpIHJldHVybiB0cnVlXG4gICAgaWYgKGEuZ2V0ICE9PSBiLmdldCkgcmV0dXJuIHRydWVcbiAgICBpZiAoYS5zZXQgIT09IGIuc2V0KSByZXR1cm4gdHJ1ZVxuICAgIGlmIChhLnZhbHVlICE9PSBiLnZhbHVlKSByZXR1cm4gdHJ1ZVxuICAgIHJldHVybiBmYWxzZVxufVxuXG4vLyBUaGVzZSBmaXJlIGRlcHJlY2F0aW9uIHdhcm5pbmdzLCBhbmQgdGh1cyBzaG91bGQgYmUgYXZvaWRlZC5cbnZhciBibGFja2xpc3QgPSBPYmplY3QuZnJlZXplKHtcbiAgICB3ZWJraXRTdG9yYWdlSW5mbzogdHJ1ZSxcbiAgICB3ZWJraXRJbmRleGVkREI6IHRydWUsXG59KVxuXG5mdW5jdGlvbiBmaW5kR2xvYmFscygpIHtcbiAgICB2YXIgZm91bmQgPSBPYmplY3Qua2V5cyhnbG9iYWwpXG4gICAgdmFyIGdsb2JhbHMgPSBPYmplY3QuY3JlYXRlKG51bGwpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZvdW5kLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBmb3VuZFtpXVxuXG4gICAgICAgIGlmICghaGFzT3duLmNhbGwoYmxhY2tsaXN0LCBrZXkpKSB7XG4gICAgICAgICAgICBnbG9iYWxzW2tleV0gPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGdsb2JhbCwga2V5KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGdsb2JhbHNcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0cywgc3RhdGUpIHtcbiAgICBpZiAoc3RhdGUubG9ja2VkKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoXG4gICAgICAgICAgICBcIlRoZSB0ZXN0IHN1aXRlIG11c3Qgbm90IGJlIHJ1biBhZnRlciB0aGUgdmlldyBoYXMgYmVlbiBkZXRhY2hlZC5cIlxuICAgICAgICApKVxuICAgIH1cblxuICAgIGlmIChzdGF0ZS5jdXJyZW50UHJvbWlzZSAhPSBudWxsKSByZXR1cm4gc3RhdGUuY3VycmVudFByb21pc2VcblxuICAgIG9wdHMudGhhbGxpdW0uY2xlYXJUZXN0cygpXG5cbiAgICAvLyBEZXRlY3QgYW5kIHJlbW92ZSBnbG9iYWxzIGNyZWF0ZWQgYnkgbG9hZGVkIHNjcmlwdHMuXG4gICAgdmFyIGdsb2JhbHMgPSBmaW5kR2xvYmFscygpXG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgICAgICB2YXIgZm91bmQgPSBPYmplY3Qua2V5cyhnbG9iYWwpXG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmb3VuZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGtleSA9IGZvdW5kW2ldXG5cbiAgICAgICAgICAgIGlmICghaGFzT3duLmNhbGwoZ2xvYmFscywga2V5KSkge1xuICAgICAgICAgICAgICAgIHRyeURlbGV0ZShrZXkpXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGRlc2NyaXB0b3JDaGFuZ2VkKFxuICAgICAgICAgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZ2xvYmFsLCBrZXkpLFxuICAgICAgICAgICAgICAgIGdsb2JhbHNba2V5XVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgICAgICAgIHRyeURlbGV0ZShrZXkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBzdGF0ZS5jdXJyZW50UHJvbWlzZSA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIHJldHVybiBzdGF0ZS5jdXJyZW50UHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICBzdGF0ZS5wYXNzLnRleHRDb250ZW50ID0gXCIwXCJcbiAgICAgICAgc3RhdGUuZmFpbC50ZXh0Q29udGVudCA9IFwiMFwiXG4gICAgICAgIHN0YXRlLnNraXAudGV4dENvbnRlbnQgPSBcIjBcIlxuICAgICAgICByZXR1cm4gb3B0cy5wcmVsb2FkKClcbiAgICB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFV0aWwucGVhY2gob3B0cy5maWxlcywgZnVuY3Rpb24gKGZpbGUpIHtcbiAgICAgICAgICAgIHJldHVybiBsb2FkU2NyaXB0KGZpbGUsIG9wdHMudGltZW91dClcbiAgICAgICAgfSlcbiAgICB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIG9wdHMucHJlcnVuKCkgfSlcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBvcHRzLnRoYWxsaXVtLnJ1bigpIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gb3B0cy5wb3N0cnVuKCkgfSlcbiAgICAuY2F0Y2goZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShvcHRzLmVycm9yKGUpKS50aGVuKGZ1bmN0aW9uICgpIHsgdGhyb3cgZSB9KVxuICAgIH0pXG4gICAgLnRoZW4oXG4gICAgICAgIGZ1bmN0aW9uICgpIHsgY2xlYW51cCgpIH0sXG4gICAgICAgIGZ1bmN0aW9uIChlKSB7IGNsZWFudXAoKTsgdGhyb3cgZSB9KVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIGRpZmYgPSByZXF1aXJlKFwiZGlmZlwiKVxudmFyIFIgPSByZXF1aXJlKFwiLi4vcmVwb3J0ZXJcIilcbnZhciBEID0gcmVxdWlyZShcIi4vaW5qZWN0XCIpXG52YXIgcnVuVGVzdHMgPSByZXF1aXJlKFwiLi9ydW4tdGVzdHNcIilcbnZhciBpbnNwZWN0ID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpLmluc3BlY3RcblxuLyoqXG4gKiBWaWV3IGxvZ2ljXG4gKi9cblxuZnVuY3Rpb24gdCh0ZXh0KSB7XG4gICAgcmV0dXJuIEQuZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dClcbn1cblxuZnVuY3Rpb24gaCh0eXBlLCBhdHRycywgY2hpbGRyZW4pIHtcbiAgICB2YXIgcGFydHMgPSB0eXBlLnNwbGl0KC9cXHMrL2cpXG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShhdHRycykpIHtcbiAgICAgICAgY2hpbGRyZW4gPSBhdHRyc1xuICAgICAgICBhdHRycyA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmIChhdHRycyA9PSBudWxsKSBhdHRycyA9IHt9XG4gICAgaWYgKGNoaWxkcmVuID09IG51bGwpIGNoaWxkcmVuID0gW11cblxuICAgIHR5cGUgPSBwYXJ0c1swXVxuICAgIGF0dHJzLmNsYXNzTmFtZSA9IHBhcnRzLnNsaWNlKDEpLmpvaW4oXCIgXCIpXG5cbiAgICB2YXIgZWxlbSA9IEQuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0eXBlKVxuXG4gICAgT2JqZWN0LmtleXMoYXR0cnMpLmZvckVhY2goZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgICAgZWxlbVthdHRyXSA9IGF0dHJzW2F0dHJdXG4gICAgfSlcblxuICAgIGNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgIGlmIChjaGlsZCAhPSBudWxsKSBlbGVtLmFwcGVuZENoaWxkKGNoaWxkKVxuICAgIH0pXG5cbiAgICByZXR1cm4gZWxlbVxufVxuXG5mdW5jdGlvbiB1bmlmaWVkRGlmZihlcnIpIHtcbiAgICB2YXIgYWN0dWFsID0gaW5zcGVjdChlcnIuYWN0dWFsKVxuICAgIHZhciBleHBlY3RlZCA9IGluc3BlY3QoZXJyLmV4cGVjdGVkKVxuICAgIHZhciBtc2cgPSBkaWZmLmNyZWF0ZVBhdGNoKFwic3RyaW5nXCIsIGFjdHVhbCwgZXhwZWN0ZWQpXG4gICAgICAgIC5zcGxpdCgvXFxyP1xcbnxcXHIvZykuc2xpY2UoNClcbiAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gIS9eXFxAXFxAfF5cXFxcIE5vIG5ld2xpbmUvLnRlc3QobGluZSkgfSlcbiAgICB2YXIgZW5kID0gbXNnLmxlbmd0aFxuXG4gICAgd2hpbGUgKGVuZCAhPT0gMCAmJiAvXlxccyokL2cudGVzdChtc2dbZW5kIC0gMV0pKSBlbmQtLVxuICAgIHJldHVybiBoKFwiZGl2IHRsLWRpZmZcIiwgW1xuICAgICAgICBoKFwiZGl2IHRsLWRpZmYtaGVhZGVyXCIsIFtcbiAgICAgICAgICAgIGgoXCJzcGFuIHRsLWRpZmYtYWRkZWRcIiwgW3QoXCIrIGV4cGVjdGVkXCIpXSksXG4gICAgICAgICAgICBoKFwic3BhbiB0bC1kaWZmLXJlbW92ZWRcIiwgW3QoXCItIGFjdHVhbFwiKV0pLFxuICAgICAgICBdKSxcbiAgICAgICAgaChcImRpdiB0bC1wcmVcIiwgIWVuZFxuICAgICAgICAgICAgPyBbaChcInNwYW4gdGwtbGluZSB0bC1kaWZmLWFkZGVkXCIsIFt0KFwiIChub25lKVwiKV0pXVxuICAgICAgICAgICAgOiBtc2cuc2xpY2UoMCwgZW5kKVxuICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gbGluZS50cmltUmlnaHQoKSB9KVxuICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAobGluZSkge1xuICAgICAgICAgICAgICAgIGlmIChsaW5lWzBdID09PSBcIitcIikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaChcInNwYW4gdGwtbGluZSB0bC1kaWZmLWFkZGVkXCIsIFt0KGxpbmUpXSlcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGxpbmVbMF0gPT09IFwiLVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBoKFwic3BhbiB0bC1saW5lIHRsLWRpZmYtcmVtb3ZlZFwiLCBbdChsaW5lKV0pXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGgoXCJzcGFuIHRsLWxpbmUgdGwtZGlmZi1ub25lXCIsIFt0KGxpbmUpXSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICApLFxuICAgIF0pXG59XG5cbmZ1bmN0aW9uIHRvTGluZXMoc3RyKSB7XG4gICAgcmV0dXJuIGgoXCJkaXYgdGwtcHJlXCIsIHN0ci5zcGxpdCgvXFxyP1xcbnxcXHIvZykubWFwKGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIHJldHVybiBoKFwic3BhbiB0bC1saW5lXCIsIFt0KGxpbmUudHJpbVJpZ2h0KCkpXSlcbiAgICB9KSlcbn1cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IoZSwgc2hvd0RpZmYpIHtcbiAgICB2YXIgc3RhY2sgPSBSLnJlYWRTdGFjayhlKVxuXG4gICAgcmV0dXJuIGgoXCJkaXYgdGwtZGlzcGxheVwiLCBbXG4gICAgICAgIGgoXCJkaXYgdGwtbWVzc2FnZVwiLCBbdG9MaW5lcyhlLm5hbWUgKyBcIjogXCIgKyBlLm1lc3NhZ2UpXSksXG4gICAgICAgIHNob3dEaWZmID8gdW5pZmllZERpZmYoZSkgOiB1bmRlZmluZWQsXG4gICAgICAgIHN0YWNrID8gaChcImRpdiB0bC1zdGFja1wiLCBbdG9MaW5lcyhzdGFjayldKSA6IHVuZGVmaW5lZCxcbiAgICBdKVxufVxuXG5mdW5jdGlvbiBzaG93VGVzdChfLCByZXBvcnQsIGNsYXNzTmFtZSwgY2hpbGQpIHtcbiAgICB2YXIgZW5kID0gcmVwb3J0LnBhdGgubGVuZ3RoIC0gMVxuICAgIHZhciBuYW1lID0gcmVwb3J0LnBhdGhbZW5kXS5uYW1lXG4gICAgdmFyIHBhcmVudCA9IF8uZ2V0KHJlcG9ydC5wYXRoLCBlbmQpXG4gICAgdmFyIHNwZWVkID0gUi5zcGVlZChyZXBvcnQpXG5cbiAgICBpZiAoc3BlZWQgPT09IFwiZmFzdFwiKSB7XG4gICAgICAgIHBhcmVudC5ub2RlLmFwcGVuZENoaWxkKGgoXCJsaSBcIiArIGNsYXNzTmFtZSArIFwiIHRsLWZhc3RcIiwgW1xuICAgICAgICAgICAgaChcImgyXCIsIFt0KG5hbWUpXSksXG4gICAgICAgICAgICBjaGlsZCxcbiAgICAgICAgXSkpXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcGFyZW50Lm5vZGUuYXBwZW5kQ2hpbGQoaChcImxpIFwiICsgY2xhc3NOYW1lICsgXCIgdGwtXCIgKyBzcGVlZCwgW1xuICAgICAgICAgICAgaChcImgyXCIsIFtcbiAgICAgICAgICAgICAgICB0KG5hbWUgKyBcIiAoXCIpLFxuICAgICAgICAgICAgICAgIGgoXCJzcGFuIHRsLWR1cmF0aW9uXCIsIFt0KFIuZm9ybWF0VGltZShyZXBvcnQuZHVyYXRpb24pKV0pLFxuICAgICAgICAgICAgICAgIHQoXCIpXCIpLFxuICAgICAgICAgICAgXSksXG4gICAgICAgICAgICBjaGlsZCxcbiAgICAgICAgXSkpXG4gICAgfVxuXG4gICAgXy5vcHRzLmR1cmF0aW9uLnRleHRDb250ZW50ID0gUi5mb3JtYXRUaW1lKF8uZHVyYXRpb24pXG59XG5cbmZ1bmN0aW9uIHNob3dTa2lwKF8sIHJlcG9ydCkge1xuICAgIHZhciBlbmQgPSByZXBvcnQucGF0aC5sZW5ndGggLSAxXG4gICAgdmFyIG5hbWUgPSByZXBvcnQucGF0aFtlbmRdLm5hbWVcbiAgICB2YXIgcGFyZW50ID0gXy5nZXQocmVwb3J0LnBhdGgsIGVuZClcblxuICAgIHBhcmVudC5ub2RlLmFwcGVuZENoaWxkKGgoXCJsaSB0bC10ZXN0IHRsLXNraXBcIiwgW1xuICAgICAgICBoKFwiaDJcIiwgW3QobmFtZSldKSxcbiAgICBdKSlcbn1cblxuZXhwb3J0cy5uZXh0RnJhbWUgPSBuZXh0RnJhbWVcbmZ1bmN0aW9uIG5leHRGcmFtZShmdW5jKSB7XG4gICAgaWYgKEQud2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSkge1xuICAgICAgICBELndpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuYylcbiAgICB9IGVsc2Uge1xuICAgICAgICBnbG9iYWwuc2V0VGltZW91dChmdW5jLCAwKVxuICAgIH1cbn1cblxuZXhwb3J0cy5yZXBvcnQgPSBmdW5jdGlvbiAoXywgcmVwb3J0KSB7XG4gICAgaWYgKHJlcG9ydC5pc1N0YXJ0KSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIGVsZW1lbnQgZmlyc3QsIGp1c3QgaW4gY2FzZS5cbiAgICAgICAgICAgIHdoaWxlIChfLm9wdHMucmVwb3J0LmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBfLm9wdHMucmVwb3J0LnJlbW92ZUNoaWxkKF8ub3B0cy5yZXBvcnQuZmlyc3RDaGlsZClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRGVmZXIgdGhlIG5leHQgZnJhbWUsIHNvIHRoZSBjdXJyZW50IGNoYW5nZXMgY2FuIGJlIHNlbnQsIGluIGNhc2VcbiAgICAgICAgICAgIC8vIGl0J3MgY2xlYXJpbmcgb2xkIHRlc3QgcmVzdWx0cyBmcm9tIGEgbGFyZ2Ugc3VpdGUuIChDaHJvbWUgZG9lc1xuICAgICAgICAgICAgLy8gYmV0dGVyIGJhdGNoaW5nIHRoaXMgd2F5LCBhdCBsZWFzdC4pXG4gICAgICAgICAgICBuZXh0RnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF8uZ2V0KHVuZGVmaW5lZCwgMCkubm9kZSA9IF8ub3B0cy5yZXBvcnRcbiAgICAgICAgICAgICAgICBfLm9wdHMuZHVyYXRpb24udGV4dENvbnRlbnQgPSBSLmZvcm1hdFRpbWUoMClcbiAgICAgICAgICAgICAgICBfLm9wdHMucGFzcy50ZXh0Q29udGVudCA9IFwiMFwiXG4gICAgICAgICAgICAgICAgXy5vcHRzLmZhaWwudGV4dENvbnRlbnQgPSBcIjBcIlxuICAgICAgICAgICAgICAgIF8ub3B0cy5za2lwLnRleHRDb250ZW50ID0gXCIwXCJcbiAgICAgICAgICAgICAgICByZXNvbHZlKClcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFbnRlcikge1xuICAgICAgICB2YXIgY2hpbGQgPSBoKFwidWxcIilcblxuICAgICAgICBfLmdldChyZXBvcnQucGF0aCkubm9kZSA9IGNoaWxkXG4gICAgICAgIHNob3dUZXN0KF8sIHJlcG9ydCwgXCJ0bC1zdWl0ZSB0bC1wYXNzXCIsIGNoaWxkKVxuICAgICAgICBfLm9wdHMucGFzcy50ZXh0Q29udGVudCA9IF8ucGFzc1xuICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzUGFzcykge1xuICAgICAgICBzaG93VGVzdChfLCByZXBvcnQsIFwidGwtdGVzdCB0bC1wYXNzXCIpXG4gICAgICAgIF8ub3B0cy5wYXNzLnRleHRDb250ZW50ID0gXy5wYXNzXG4gICAgfSBlbHNlIGlmIChyZXBvcnQuaXNGYWlsKSB7XG4gICAgICAgIHNob3dUZXN0KF8sIHJlcG9ydCwgXCJ0bC10ZXN0IHRsLWZhaWxcIiwgZm9ybWF0RXJyb3IocmVwb3J0LmVycm9yLFxuICAgICAgICAgICAgcmVwb3J0LmVycm9yLm5hbWUgPT09IFwiQXNzZXJ0aW9uRXJyb3JcIiAmJlxuICAgICAgICAgICAgICAgIHJlcG9ydC5lcnJvci5zaG93RGlmZiAhPT0gZmFsc2UpKVxuICAgICAgICBfLm9wdHMuZmFpbC50ZXh0Q29udGVudCA9IF8uZmFpbFxuICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzU2tpcCkge1xuICAgICAgICBzaG93U2tpcChfLCByZXBvcnQsIFwidGwtdGVzdCB0bC1za2lwXCIpXG4gICAgICAgIF8ub3B0cy5za2lwLnRleHRDb250ZW50ID0gXy5za2lwXG4gICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFcnJvcikge1xuICAgICAgICBfLm9wdHMucmVwb3J0LmFwcGVuZENoaWxkKGgoXCJsaSB0bC1lcnJvclwiLCBbXG4gICAgICAgICAgICBoKFwiaDJcIiwgW3QoXCJJbnRlcm5hbCBlcnJvclwiKV0pLFxuICAgICAgICAgICAgZm9ybWF0RXJyb3IocmVwb3J0LmVycm9yLCBmYWxzZSksXG4gICAgICAgIF0pKVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWRcbn1cblxuZnVuY3Rpb24gbWFrZUNvdW50ZXIoc3RhdGUsIGNoaWxkLCBsYWJlbCwgbmFtZSkge1xuICAgIHJldHVybiBoKFwiYnV0dG9uIHRsLXRvZ2dsZSBcIiArIG5hbWUsIHtcbiAgICAgICAgb25jbGljazogZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKVxuXG4gICAgICAgICAgICBpZiAoL1xcYnRsLWFjdGl2ZVxcYi8udGVzdCh0aGlzLmNsYXNzTmFtZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSA9IHRoaXMuY2xhc3NOYW1lXG4gICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXGJ0bC1hY3RpdmVcXGIvZywgXCJcIilcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xccysvZywgXCIgXCIpXG4gICAgICAgICAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgICAgICBzdGF0ZS5yZXBvcnQuY2xhc3NOYW1lID0gc3RhdGUucmVwb3J0LmNsYXNzTmFtZVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZShuZXcgUmVnRXhwKFwiXFxcXGJcIiArIG5hbWUgKyBcIlxcXFxiXCIsIFwiZ1wiKSwgXCJcIilcbiAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xccysvZywgXCIgXCIpXG4gICAgICAgICAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmUgPSB1bmRlZmluZWRcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlLmFjdGl2ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmFjdGl2ZS5jbGFzc05hbWUgPSBzdGF0ZS5hY3RpdmUuY2xhc3NOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxidGwtYWN0aXZlXFxiL2csIFwiXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxzKy9nLCBcIiBcIilcbiAgICAgICAgICAgICAgICAgICAgICAgIC50cmltKClcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBzdGF0ZS5hY3RpdmUgPSB0aGlzXG4gICAgICAgICAgICAgICAgdGhpcy5jbGFzc05hbWUgKz0gXCIgdGwtYWN0aXZlXCJcbiAgICAgICAgICAgICAgICBzdGF0ZS5yZXBvcnQuY2xhc3NOYW1lID0gc3RhdGUucmVwb3J0LmNsYXNzTmFtZVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxidGwtKHBhc3N8ZmFpbHxza2lwKVxcYi9nLCBcIlwiKVxuICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxzKy9nLCBcIiBcIilcbiAgICAgICAgICAgICAgICAgICAgLnRyaW0oKSArIFwiIFwiICsgbmFtZVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgIH0sIFt0KGxhYmVsKSwgY2hpbGRdKVxufVxuXG5leHBvcnRzLmluaXQgPSBmdW5jdGlvbiAob3B0cykge1xuICAgIHZhciBzdGF0ZSA9IHtcbiAgICAgICAgY3VycmVudFByb21pc2U6IHVuZGVmaW5lZCxcbiAgICAgICAgbG9ja2VkOiBmYWxzZSxcbiAgICAgICAgZHVyYXRpb246IGgoXCJlbVwiLCBbdChSLmZvcm1hdFRpbWUoMCkpXSksXG4gICAgICAgIHBhc3M6IGgoXCJlbVwiLCBbdChcIjBcIildKSxcbiAgICAgICAgZmFpbDogaChcImVtXCIsIFt0KFwiMFwiKV0pLFxuICAgICAgICBza2lwOiBoKFwiZW1cIiwgW3QoXCIwXCIpXSksXG4gICAgICAgIHJlcG9ydDogaChcInVsIHRsLXJlcG9ydFwiKSxcbiAgICAgICAgYWN0aXZlOiB1bmRlZmluZWQsXG4gICAgfVxuXG4gICAgdmFyIGhlYWRlciA9IGgoXCJkaXYgdGwtaGVhZGVyXCIsIFtcbiAgICAgICAgaChcImRpdiB0bC1kdXJhdGlvblwiLCBbdChcIkR1cmF0aW9uOiBcIiksIHN0YXRlLmR1cmF0aW9uXSksXG4gICAgICAgIG1ha2VDb3VudGVyKHN0YXRlLCBzdGF0ZS5wYXNzLCBcIlBhc3NlczogXCIsIFwidGwtcGFzc1wiKSxcbiAgICAgICAgbWFrZUNvdW50ZXIoc3RhdGUsIHN0YXRlLmZhaWwsIFwiRmFpbHVyZXM6IFwiLCBcInRsLWZhaWxcIiksXG4gICAgICAgIG1ha2VDb3VudGVyKHN0YXRlLCBzdGF0ZS5za2lwLCBcIlNraXBwZWQ6IFwiLCBcInRsLXNraXBcIiksXG4gICAgICAgIGgoXCJidXR0b24gdGwtcnVuXCIsIHtcbiAgICAgICAgICAgIG9uY2xpY2s6IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgICAgIGV2LnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKVxuICAgICAgICAgICAgICAgIHJ1blRlc3RzKG9wdHMsIHN0YXRlKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSwgW3QoXCJSdW5cIildKSxcbiAgICBdKVxuXG4gICAgdmFyIHJvb3QgPSBELmRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwidGxcIilcblxuICAgIGlmIChyb290ID09IG51bGwpIHtcbiAgICAgICAgRC5kb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHJvb3QgPSBoKFwiZGl2XCIsIHtpZDogXCJ0bFwifSwgW1xuICAgICAgICAgICAgaGVhZGVyLFxuICAgICAgICAgICAgc3RhdGUucmVwb3J0LFxuICAgICAgICBdKSlcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDbGVhciB0aGUgZWxlbWVudCBmaXJzdCwganVzdCBpbiBjYXNlLlxuICAgICAgICB3aGlsZSAocm9vdC5maXJzdENoaWxkKSByb290LnJlbW92ZUNoaWxkKHJvb3QuZmlyc3RDaGlsZClcbiAgICAgICAgcm9vdC5hcHBlbmRDaGlsZChoZWFkZXIpXG4gICAgICAgIHJvb3QuYXBwZW5kQ2hpbGQoc3RhdGUucmVwb3J0KVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHJvb3Q6IHJvb3QsXG4gICAgICAgIHN0YXRlOiBzdGF0ZSxcbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChCYXNlLCBTdXBlcikge1xuICAgIHZhciBzdGFydCA9IDJcblxuICAgIGlmICh0eXBlb2YgU3VwZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBCYXNlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoU3VwZXIucHJvdG90eXBlKVxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQmFzZS5wcm90b3R5cGUsIFwiY29uc3RydWN0b3JcIiwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBCYXNlLFxuICAgICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXJ0ID0gMVxuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgbWV0aG9kcyA9IGFyZ3VtZW50c1tpXVxuXG4gICAgICAgIGlmIChtZXRob2RzICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMobWV0aG9kcylcblxuICAgICAgICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCBrZXlzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGtleSA9IGtleXNba11cbiAgICAgICAgICAgICAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobWV0aG9kcywga2V5KVxuXG4gICAgICAgICAgICAgICAgZGVzYy5lbnVtZXJhYmxlID0gZmFsc2VcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQmFzZS5wcm90b3R5cGUsIGtleSwgZGVzYylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8qKlxuICogVGhpcyBjb250YWlucyB0aGUgYnJvd3NlciBjb25zb2xlIHN0dWZmLlxuICovXG5cbmV4cG9ydHMuU3ltYm9scyA9IE9iamVjdC5mcmVlemUoe1xuICAgIFBhc3M6IFwi4pyTXCIsXG4gICAgRmFpbDogXCLinJZcIixcbiAgICBEb3Q6IFwi4oCkXCIsXG4gICAgRG90RmFpbDogXCIhXCIsXG59KVxuXG5leHBvcnRzLndpbmRvd1dpZHRoID0gNzVcbmV4cG9ydHMubmV3bGluZSA9IFwiXFxuXCJcblxuLy8gQ29sb3Igc3VwcG9ydCBpcyB1bmZvcmNlZCBhbmQgdW5zdXBwb3J0ZWQsIHNpbmNlIHlvdSBjYW4gb25seSBzcGVjaWZ5XG4vLyBsaW5lLWJ5LWxpbmUgY29sb3JzIHZpYSBDU1MsIGFuZCBldmVuIHRoYXQgaXNuJ3QgdmVyeSBwb3J0YWJsZS5cbmV4cG9ydHMuY29sb3JTdXBwb3J0ID0gMFxuXG4vKipcbiAqIFNpbmNlIGJyb3dzZXJzIGRvbid0IGhhdmUgdW5idWZmZXJlZCBvdXRwdXQsIHRoaXMga2luZCBvZiBzaW11bGF0ZXMgaXQuXG4gKi9cblxudmFyIGFjYyA9IFwiXCJcblxuZXhwb3J0cy5kZWZhdWx0T3B0cyA9IHtcbiAgICB3cml0ZTogZnVuY3Rpb24gKHN0cikge1xuICAgICAgICBhY2MgKz0gc3RyXG5cbiAgICAgICAgdmFyIGluZGV4ID0gc3RyLmluZGV4T2YoXCJcXG5cIilcblxuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgdmFyIGxpbmVzID0gc3RyLnNwbGl0KFwiXFxuXCIpXG5cbiAgICAgICAgICAgIGFjYyA9IGxpbmVzLnBvcCgpXG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBnbG9iYWwuY29uc29sZS5sb2cobGluZXNbaV0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKGFjYyAhPT0gXCJcIikge1xuICAgICAgICAgICAgZ2xvYmFsLmNvbnNvbGUubG9nKGFjYylcbiAgICAgICAgICAgIGFjYyA9IFwiXCJcbiAgICAgICAgfVxuICAgIH0sXG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgZGlmZiA9IHJlcXVpcmUoXCJkaWZmXCIpXG5cbnZhciBtZXRob2RzID0gcmVxdWlyZShcIi4uL21ldGhvZHNcIilcbnZhciBpbnNwZWN0ID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpLmluc3BlY3RcbnZhciBwZWFjaCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpLnBlYWNoXG52YXIgUmVwb3J0ZXIgPSByZXF1aXJlKFwiLi9yZXBvcnRlclwiKVxudmFyIFV0aWwgPSByZXF1aXJlKFwiLi91dGlsXCIpXG52YXIgU2V0dGluZ3MgPSByZXF1aXJlKFwiLi4vc2V0dGluZ3NcIilcblxuZnVuY3Rpb24gcHJpbnRUaW1lKF8sIHAsIHN0cikge1xuICAgIGlmICghXy50aW1lUHJpbnRlZCkge1xuICAgICAgICBfLnRpbWVQcmludGVkID0gdHJ1ZVxuICAgICAgICBzdHIgKz0gVXRpbC5jb2xvcihcImxpZ2h0XCIsIFwiIChcIiArIFV0aWwuZm9ybWF0VGltZShfLmR1cmF0aW9uKSArIFwiKVwiKVxuICAgIH1cblxuICAgIHJldHVybiBwLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChzdHIpIH0pXG59XG5cbmZ1bmN0aW9uIHVuaWZpZWREaWZmKGVycikge1xuICAgIHZhciBhY3R1YWwgPSBpbnNwZWN0KGVyci5hY3R1YWwpXG4gICAgdmFyIGV4cGVjdGVkID0gaW5zcGVjdChlcnIuZXhwZWN0ZWQpXG4gICAgdmFyIG1zZyA9IGRpZmYuY3JlYXRlUGF0Y2goXCJzdHJpbmdcIiwgYWN0dWFsLCBleHBlY3RlZClcbiAgICB2YXIgaGVhZGVyID0gU2V0dGluZ3MubmV3bGluZSgpICtcbiAgICAgICAgVXRpbC5jb2xvcihcImRpZmYgYWRkZWRcIiwgXCIrIGV4cGVjdGVkXCIpICsgXCIgXCIgK1xuICAgICAgICBVdGlsLmNvbG9yKFwiZGlmZiByZW1vdmVkXCIsIFwiLSBhY3R1YWxcIikgK1xuICAgICAgICBTZXR0aW5ncy5uZXdsaW5lKCkgKyBTZXR0aW5ncy5uZXdsaW5lKClcblxuICAgIHJldHVybiBoZWFkZXIgKyBtc2cuc3BsaXQoL1xccj9cXG58XFxyL2cpLnNsaWNlKDQpXG4gICAgLmZpbHRlcihmdW5jdGlvbiAobGluZSkgeyByZXR1cm4gIS9eXFxAXFxAfF5cXFxcIE5vIG5ld2xpbmUvLnRlc3QobGluZSkgfSlcbiAgICAubWFwKGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIGlmIChsaW5lWzBdID09PSBcIitcIikgcmV0dXJuIFV0aWwuY29sb3IoXCJkaWZmIGFkZGVkXCIsIGxpbmUudHJpbVJpZ2h0KCkpXG4gICAgICAgIGlmIChsaW5lWzBdID09PSBcIi1cIikgcmV0dXJuIFV0aWwuY29sb3IoXCJkaWZmIHJlbW92ZWRcIiwgbGluZS50cmltUmlnaHQoKSlcbiAgICAgICAgcmV0dXJuIGxpbmUudHJpbVJpZ2h0KClcbiAgICB9KVxuICAgIC5qb2luKFNldHRpbmdzLm5ld2xpbmUoKSlcbn1cblxuZnVuY3Rpb24gZm9ybWF0RmFpbChzdHIpIHtcbiAgICByZXR1cm4gc3RyLnRyaW1SaWdodCgpXG4gICAgLnNwbGl0KC9cXHI/XFxufFxcci9nKVxuICAgIC5tYXAoZnVuY3Rpb24gKGxpbmUpIHsgcmV0dXJuIFV0aWwuY29sb3IoXCJmYWlsXCIsIGxpbmUudHJpbVJpZ2h0KCkpIH0pXG4gICAgLmpvaW4oU2V0dGluZ3MubmV3bGluZSgpKVxufVxuXG5mdW5jdGlvbiBnZXREaWZmU3RhY2soZSkge1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IGZvcm1hdEZhaWwoZS5uYW1lICsgXCI6IFwiICsgZS5tZXNzYWdlKVxuXG4gICAgaWYgKGUubmFtZSA9PT0gXCJBc3NlcnRpb25FcnJvclwiICYmIGUuc2hvd0RpZmYgIT09IGZhbHNlKSB7XG4gICAgICAgIGRlc2NyaXB0aW9uICs9IFNldHRpbmdzLm5ld2xpbmUoKSArIHVuaWZpZWREaWZmKGUpXG4gICAgfVxuXG4gICAgdmFyIHN0cmlwcGVkID0gZm9ybWF0RmFpbChVdGlsLnJlYWRTdGFjayhlKSlcblxuICAgIGlmIChzdHJpcHBlZCA9PT0gXCJcIikgcmV0dXJuIGRlc2NyaXB0aW9uXG4gICAgcmV0dXJuIGRlc2NyaXB0aW9uICsgU2V0dGluZ3MubmV3bGluZSgpICsgc3RyaXBwZWRcbn1cblxuZnVuY3Rpb24gaW5zcGVjdFRyaW1tZWQob2JqZWN0KSB7XG4gICAgcmV0dXJuIGluc3BlY3Qob2JqZWN0KS50cmltUmlnaHQoKVxuICAgIC5zcGxpdCgvXFxyP1xcbnxcXHIvZylcbiAgICAubWFwKGZ1bmN0aW9uIChsaW5lKSB7IHJldHVybiBsaW5lLnRyaW1SaWdodCgpIH0pXG4gICAgLmpvaW4oU2V0dGluZ3MubmV3bGluZSgpKVxufVxuXG5mdW5jdGlvbiBwcmludEZhaWxMaXN0KF8sIGVycikge1xuICAgIHZhciBzdHIgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGdldERpZmZTdGFjayhlcnIpIDogaW5zcGVjdFRyaW1tZWQoZXJyKVxuICAgIHZhciBwYXJ0cyA9IHN0ci5zcGxpdCgvXFxyP1xcbi9nKVxuXG4gICAgcmV0dXJuIF8ucHJpbnQoXCIgICAgXCIgKyBwYXJ0c1swXSkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBwZWFjaChwYXJ0cy5zbGljZSgxKSwgZnVuY3Rpb24gKHBhcnQpIHtcbiAgICAgICAgICAgIHJldHVybiBfLnByaW50KHBhcnQgPyBcIiAgICAgIFwiICsgcGFydCA6IFwiXCIpXG4gICAgICAgIH0pXG4gICAgfSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0cywgbWV0aG9kcykge1xuICAgIHJldHVybiBuZXcgQ29uc29sZVJlcG9ydGVyKG9wdHMsIG1ldGhvZHMpXG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgbW9zdCBjb25zb2xlIHJlcG9ydGVycy5cbiAqXG4gKiBOb3RlOiBwcmludGluZyBpcyBhc3luY2hyb25vdXMsIGJlY2F1c2Ugb3RoZXJ3aXNlLCBpZiBlbm91Z2ggZXJyb3JzIGV4aXN0LFxuICogTm9kZSB3aWxsIGV2ZW50dWFsbHkgc3RhcnQgZHJvcHBpbmcgbGluZXMgc2VudCB0byBpdHMgYnVmZmVyLCBlc3BlY2lhbGx5IHdoZW5cbiAqIHN0YWNrIHRyYWNlcyBnZXQgaW52b2x2ZWQuIElmIFRoYWxsaXVtJ3Mgb3V0cHV0IGlzIHJlZGlyZWN0ZWQsIHRoYXQgY2FuIGJlIGFcbiAqIGJpZyBwcm9ibGVtIGZvciBjb25zdW1lcnMsIGFzIHRoZXkgb25seSBoYXZlIHBhcnQgb2YgdGhlIG91dHB1dCwgYW5kIHdvbid0IGJlXG4gKiBhYmxlIHRvIHNlZSBhbGwgdGhlIGVycm9ycyBsYXRlci4gQWxzbywgaWYgY29uc29sZSB3YXJuaW5ncyBjb21lIHVwIGVuLW1hc3NlLFxuICogdGhhdCB3b3VsZCBhbHNvIGNvbnRyaWJ1dGUuIFNvLCB3ZSBoYXZlIHRvIHdhaXQgZm9yIGVhY2ggbGluZSB0byBmbHVzaCBiZWZvcmVcbiAqIHdlIGNhbiBjb250aW51ZSwgc28gdGhlIGZ1bGwgb3V0cHV0IG1ha2VzIGl0cyB3YXkgdG8gdGhlIGNvbnNvbGUuXG4gKlxuICogU29tZSB0ZXN0IGZyYW1ld29ya3MgbGlrZSBUYXBlIG1pc3MgdGhpcywgdGhvdWdoLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIFRoZSBvcHRpb25zIGZvciB0aGUgcmVwb3J0ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBvcHRzLndyaXRlIFRoZSB1bmJ1ZmZlcnJlZCB3cml0ZXIgZm9yIHRoZSByZXBvcnRlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IG9wdHMucmVzZXQgQSByZXNldCBmdW5jdGlvbiBmb3IgdGhlIHByaW50ZXIgKyB3cml0ZXIuXG4gKiBAcGFyYW0ge1N0cmluZ1tdfSBhY2NlcHRzIFRoZSBvcHRpb25zIGFjY2VwdGVkLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaW5pdCBUaGUgaW5pdCBmdW5jdGlvbiBmb3IgdGhlIHN1YmNsYXNzIHJlcG9ydGVyJ3NcbiAqICAgICAgICAgICAgICAgICAgICAgICAgaXNvbGF0ZWQgc3RhdGUgKGNyZWF0ZWQgYnkgZmFjdG9yeSkuXG4gKi9cbmZ1bmN0aW9uIENvbnNvbGVSZXBvcnRlcihvcHRzLCBtZXRob2RzKSB7XG4gICAgUmVwb3J0ZXIuY2FsbCh0aGlzLCBVdGlsLlRyZWUsIG9wdHMsIG1ldGhvZHMsIHRydWUpXG5cbiAgICBpZiAoIVV0aWwuQ29sb3JzLmZvcmNlZCgpICYmIG1ldGhvZHMuYWNjZXB0cy5pbmRleE9mKFwiY29sb3JcIikgPj0gMCkge1xuICAgICAgICB0aGlzLm9wdHMuY29sb3IgPSBvcHRzLmNvbG9yXG4gICAgfVxuXG4gICAgVXRpbC5kZWZhdWx0aWZ5KHRoaXMsIG9wdHMsIFwid3JpdGVcIilcbiAgICB0aGlzLnJlc2V0KClcbn1cblxubWV0aG9kcyhDb25zb2xlUmVwb3J0ZXIsIFJlcG9ydGVyLCB7XG4gICAgcHJpbnQ6IGZ1bmN0aW9uIChzdHIpIHtcbiAgICAgICAgaWYgKHN0ciA9PSBudWxsKSBzdHIgPSBcIlwiXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5vcHRzLndyaXRlKHN0ciArIFwiXFxuXCIpKVxuICAgIH0sXG5cbiAgICB3cml0ZTogZnVuY3Rpb24gKHN0cikge1xuICAgICAgICBpZiAoc3RyICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy5vcHRzLndyaXRlKHN0cikpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBwcmludFJlc3VsdHM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzXG5cbiAgICAgICAgaWYgKCF0aGlzLnRlc3RzICYmICF0aGlzLnNraXApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByaW50KFxuICAgICAgICAgICAgICAgIFV0aWwuY29sb3IoXCJwbGFpblwiLCBcIiAgMCB0ZXN0c1wiKSArXG4gICAgICAgICAgICAgICAgVXRpbC5jb2xvcihcImxpZ2h0XCIsIFwiICgwbXMpXCIpKVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5wcmludCgpIH0pXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5wcmludCgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHAgPSBQcm9taXNlLnJlc29sdmUoKVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5wYXNzKSB7XG4gICAgICAgICAgICAgICAgcCA9IHByaW50VGltZShzZWxmLCBwLFxuICAgICAgICAgICAgICAgICAgICBVdGlsLmNvbG9yKFwiYnJpZ2h0IHBhc3NcIiwgXCIgIFwiKSArXG4gICAgICAgICAgICAgICAgICAgIFV0aWwuY29sb3IoXCJncmVlblwiLCBzZWxmLnBhc3MgKyBcIiBwYXNzaW5nXCIpKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5za2lwKSB7XG4gICAgICAgICAgICAgICAgcCA9IHByaW50VGltZShzZWxmLCBwLFxuICAgICAgICAgICAgICAgICAgICBVdGlsLmNvbG9yKFwic2tpcFwiLCBcIiAgXCIgKyBzZWxmLnNraXAgKyBcIiBza2lwcGVkXCIpKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc2VsZi5mYWlsKSB7XG4gICAgICAgICAgICAgICAgcCA9IHByaW50VGltZShzZWxmLCBwLFxuICAgICAgICAgICAgICAgICAgICBVdGlsLmNvbG9yKFwiYnJpZ2h0IGZhaWxcIiwgXCIgIFwiKSArXG4gICAgICAgICAgICAgICAgICAgIFV0aWwuY29sb3IoXCJmYWlsXCIsIHNlbGYuZmFpbCArIFwiIGZhaWxpbmdcIikpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBwXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHNlbGYucHJpbnQoKSB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcGVhY2goc2VsZi5lcnJvcnMsIGZ1bmN0aW9uIChyZXBvcnQsIGkpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IGkgKyAxICsgXCIpIFwiICsgVXRpbC5qb2luUGF0aChyZXBvcnQpICtcbiAgICAgICAgICAgICAgICAgICAgVXRpbC5mb3JtYXRSZXN0KHJlcG9ydClcblxuICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLnByaW50KFwiICBcIiArIFV0aWwuY29sb3IoXCJwbGFpblwiLCBuYW1lICsgXCI6XCIpKVxuICAgICAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByaW50RmFpbExpc3Qoc2VsZiwgcmVwb3J0LmVycm9yKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gc2VsZi5wcmludCgpIH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgIH0sXG5cbiAgICBwcmludEVycm9yOiBmdW5jdGlvbiAocmVwb3J0KSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpc1xuICAgICAgICB2YXIgbGluZXMgPSByZXBvcnQuZXJyb3IgaW5zdGFuY2VvZiBFcnJvclxuICAgICAgICAgICAgPyBVdGlsLmdldFN0YWNrKHJlcG9ydC5lcnJvcilcbiAgICAgICAgICAgIDogaW5zcGVjdFRyaW1tZWQocmVwb3J0LmVycm9yKVxuXG4gICAgICAgIHJldHVybiB0aGlzLnByaW50KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcGVhY2gobGluZXMuc3BsaXQoL1xccj9cXG4vZyksIGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYucHJpbnQobGluZSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuL3V0aWxcIilcblxuZXhwb3J0cy5vbiA9IHJlcXVpcmUoXCIuL29uXCIpXG5leHBvcnRzLmNvbnNvbGVSZXBvcnRlciA9IHJlcXVpcmUoXCIuL2NvbnNvbGUtcmVwb3J0ZXJcIilcbmV4cG9ydHMuUmVwb3J0ZXIgPSByZXF1aXJlKFwiLi9yZXBvcnRlclwiKVxuZXhwb3J0cy5jb2xvciA9IFV0aWwuY29sb3JcbmV4cG9ydHMuQ29sb3JzID0gVXRpbC5Db2xvcnNcbmV4cG9ydHMuZm9ybWF0UmVzdCA9IFV0aWwuZm9ybWF0UmVzdFxuZXhwb3J0cy5mb3JtYXRUaW1lID0gVXRpbC5mb3JtYXRUaW1lXG5leHBvcnRzLmdldFN0YWNrID0gVXRpbC5nZXRTdGFja1xuZXhwb3J0cy5qb2luUGF0aCA9IFV0aWwuam9pblBhdGhcbmV4cG9ydHMubmV3bGluZSA9IFV0aWwubmV3bGluZVxuZXhwb3J0cy5yZWFkU3RhY2sgPSBVdGlsLnJlYWRTdGFja1xuZXhwb3J0cy5zZXRDb2xvciA9IFV0aWwuc2V0Q29sb3JcbmV4cG9ydHMuc3BlZWQgPSBVdGlsLnNwZWVkXG5leHBvcnRzLlN0YXR1cyA9IFV0aWwuU3RhdHVzXG5leHBvcnRzLnN5bWJvbHMgPSBVdGlsLnN5bWJvbHNcbmV4cG9ydHMudW5zZXRDb2xvciA9IFV0aWwudW5zZXRDb2xvclxuZXhwb3J0cy53aW5kb3dXaWR0aCA9IFV0aWwud2luZG93V2lkdGhcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBTdGF0dXMgPSByZXF1aXJlKFwiLi91dGlsXCIpLlN0YXR1c1xuXG4vLyBCZWNhdXNlIEVTNSBzdWNrcy4gKEFuZCwgaXQncyBicmVha2luZyBteSBQaGFudG9tSlMgYnVpbGRzKVxuZnVuY3Rpb24gc2V0TmFtZShyZXBvcnRlciwgbmFtZSkge1xuICAgIHRyeSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXBvcnRlciwgXCJuYW1lXCIsIHt2YWx1ZTogbmFtZX0pXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBpZ25vcmVcbiAgICB9XG59XG5cbi8qKlxuICogQSBtYWNybyBvZiBzb3J0cywgdG8gc2ltcGxpZnkgY3JlYXRpbmcgcmVwb3J0ZXJzLiBJdCBhY2NlcHRzIGFuIG9iamVjdCB3aXRoXG4gKiB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6XG4gKlxuICogYGFjY2VwdHM6IHN0cmluZ1tdYCAtIFRoZSBwcm9wZXJ0aWVzIGFjY2VwdGVkLiBFdmVyeXRoaW5nIGVsc2UgaXMgaWdub3JlZCxcbiAqIGFuZCBpdCdzIHBhcnRpYWxseSB0aGVyZSBmb3IgZG9jdW1lbnRhdGlvbi4gVGhpcyBwYXJhbWV0ZXIgaXMgcmVxdWlyZWQuXG4gKlxuICogYGNyZWF0ZShvcHRzLCBtZXRob2RzKWAgLSBDcmVhdGUgYSBuZXcgcmVwb3J0ZXIgaW5zdGFuY2UuICBUaGlzIHBhcmFtZXRlciBpc1xuICogcmVxdWlyZWQuIE5vdGUgdGhhdCBgbWV0aG9kc2AgcmVmZXJzIHRvIHRoZSBwYXJhbWV0ZXIgb2JqZWN0IGl0c2VsZi5cbiAqXG4gKiBgaW5pdChzdGF0ZSwgb3B0cylgIC0gSW5pdGlhbGl6ZSBleHRyYSByZXBvcnRlciBzdGF0ZSwgaWYgYXBwbGljYWJsZS5cbiAqXG4gKiBgYmVmb3JlKHJlcG9ydGVyKWAgLSBEbyB0aGluZ3MgYmVmb3JlIGVhY2ggZXZlbnQsIHJldHVybmluZyBhIHBvc3NpYmxlXG4gKiB0aGVuYWJsZSB3aGVuIGRvbmUuIFRoaXMgZGVmYXVsdHMgdG8gYSBuby1vcC5cbiAqXG4gKiBgYWZ0ZXIocmVwb3J0ZXIpYCAtIERvIHRoaW5ncyBhZnRlciBlYWNoIGV2ZW50LCByZXR1cm5pbmcgYSBwb3NzaWJsZVxuICogdGhlbmFibGUgd2hlbiBkb25lLiBUaGlzIGRlZmF1bHRzIHRvIGEgbm8tb3AuXG4gKlxuICogYHJlcG9ydChyZXBvcnRlciwgcmVwb3J0KWAgLSBIYW5kbGUgYSB0ZXN0IHJlcG9ydC4gVGhpcyBtYXkgcmV0dXJuIGEgcG9zc2libGVcbiAqIHRoZW5hYmxlIHdoZW4gZG9uZSwgYW5kIGl0IGlzIHJlcXVpcmVkLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChuYW1lLCBtZXRob2RzKSB7XG4gICAgc2V0TmFtZShyZXBvcnRlciwgbmFtZSlcbiAgICByZXBvcnRlcltuYW1lXSA9IHJlcG9ydGVyXG4gICAgcmV0dXJuIHJlcG9ydGVyXG4gICAgZnVuY3Rpb24gcmVwb3J0ZXIob3B0cykge1xuICAgICAgICAvKipcbiAgICAgICAgICogSW5zdGVhZCBvZiBzaWxlbnRseSBmYWlsaW5nIHRvIHdvcmssIGxldCdzIGVycm9yIG91dCB3aGVuIGEgcmVwb3J0IGlzXG4gICAgICAgICAqIHBhc3NlZCBpbiwgYW5kIGluZm9ybSB0aGUgdXNlciBpdCBuZWVkcyBpbml0aWFsaXplZC4gQ2hhbmNlcyBhcmUsXG4gICAgICAgICAqIHRoZXJlJ3Mgbm8gbGVnaXRpbWF0ZSByZWFzb24gdG8gZXZlbiBwYXNzIGEgcmVwb3J0LCBhbnl3YXlzLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKHR5cGVvZiBvcHRzID09PSBcIm9iamVjdFwiICYmIG9wdHMgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2Ygb3B0cy5fID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgICAgIFwiT3B0aW9ucyBjYW5ub3QgYmUgYSByZXBvcnQuIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgdGhlIFwiICtcbiAgICAgICAgICAgICAgICBcImZhY3RvcnkgZmlyc3Q/XCIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgXyA9IG1ldGhvZHMuY3JlYXRlKG9wdHMsIG1ldGhvZHMpXG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChyZXBvcnQpIHtcbiAgICAgICAgICAgIC8vIE9ubHkgc29tZSBldmVudHMgaGF2ZSBjb21tb24gc3RlcHMuXG4gICAgICAgICAgICBpZiAocmVwb3J0LmlzU3RhcnQpIHtcbiAgICAgICAgICAgICAgICBfLnJ1bm5pbmcgPSB0cnVlXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0VudGVyIHx8IHJlcG9ydC5pc1Bhc3MpIHtcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucGF0aCkuc3RhdHVzID0gU3RhdHVzLlBhc3NpbmdcbiAgICAgICAgICAgICAgICBfLmR1cmF0aW9uICs9IHJlcG9ydC5kdXJhdGlvblxuICAgICAgICAgICAgICAgIF8udGVzdHMrK1xuICAgICAgICAgICAgICAgIF8ucGFzcysrXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0ZhaWwpIHtcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucGF0aCkuc3RhdHVzID0gU3RhdHVzLkZhaWxpbmdcbiAgICAgICAgICAgICAgICBfLmR1cmF0aW9uICs9IHJlcG9ydC5kdXJhdGlvblxuICAgICAgICAgICAgICAgIF8udGVzdHMrK1xuICAgICAgICAgICAgICAgIF8uZmFpbCsrXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0hvb2spIHtcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucGF0aCkuc3RhdHVzID0gU3RhdHVzLkZhaWxpbmdcbiAgICAgICAgICAgICAgICBfLmdldChyZXBvcnQucm9vdFBhdGgpLnN0YXR1cyA9IFN0YXR1cy5GYWlsaW5nXG4gICAgICAgICAgICAgICAgXy5mYWlsKytcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzU2tpcCkge1xuICAgICAgICAgICAgICAgIF8uZ2V0KHJlcG9ydC5wYXRoKS5zdGF0dXMgPSBTdGF0dXMuU2tpcHBlZFxuICAgICAgICAgICAgICAgIC8vIFNraXBwZWQgdGVzdHMgYXJlbid0IGNvdW50ZWQgaW4gdGhlIHRvdGFsIHRlc3QgY291bnRcbiAgICAgICAgICAgICAgICBfLnNraXArK1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICAgICAgICAgIHR5cGVvZiBtZXRob2RzLmJlZm9yZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICAgICAgICAgID8gbWV0aG9kcy5iZWZvcmUoXylcbiAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBtZXRob2RzLnJlcG9ydChfLCByZXBvcnQpIH0pXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBtZXRob2RzLmFmdGVyID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgPyBtZXRob2RzLmFmdGVyKF8pXG4gICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChyZXBvcnQuaXNFbmQgfHwgcmVwb3J0LmlzRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgXy5yZXNldCgpXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgXy5vcHRzLnJlc2V0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfLm9wdHMucmVzZXQoKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgbWV0aG9kcyA9IHJlcXVpcmUoXCIuLi9tZXRob2RzXCIpXG52YXIgZGVmYXVsdGlmeSA9IHJlcXVpcmUoXCIuL3V0aWxcIikuZGVmYXVsdGlmeVxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuZnVuY3Rpb24gU3RhdGUocmVwb3J0ZXIpIHtcbiAgICBpZiAodHlwZW9mIHJlcG9ydGVyLm1ldGhvZHMuaW5pdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICgwLCByZXBvcnRlci5tZXRob2RzLmluaXQpKHRoaXMsIHJlcG9ydGVyLm9wdHMpXG4gICAgfVxufVxuXG4vKipcbiAqIFRoaXMgaGVscHMgc3BlZWQgdXAgZ2V0dGluZyBwcmV2aW91cyB0cmVlcywgc28gYSBwb3RlbnRpYWxseSBleHBlbnNpdmVcbiAqIHRyZWUgc2VhcmNoIGRvZXNuJ3QgaGF2ZSB0byBiZSBwZXJmb3JtZWQuXG4gKlxuICogKFRoaXMgZG9lcyBhY3R1YWxseSBtYWtlIGEgc2xpZ2h0IHBlcmYgZGlmZmVyZW5jZSBpbiB0aGUgdGVzdHMuKVxuICovXG5mdW5jdGlvbiBpc1JlcGVhdChjYWNoZSwgcGF0aCkge1xuICAgIC8vIENhbid0IGJlIGEgcmVwZWF0IHRoZSBmaXJzdCB0aW1lLlxuICAgIGlmIChjYWNoZS5wYXRoID09IG51bGwpIHJldHVybiBmYWxzZVxuICAgIGlmIChwYXRoLmxlbmd0aCAhPT0gY2FjaGUucGF0aC5sZW5ndGgpIHJldHVybiBmYWxzZVxuICAgIGlmIChwYXRoID09PSBjYWNoZS5wYXRoKSByZXR1cm4gdHJ1ZVxuXG4gICAgLy8gSXQncyB1bmxpa2VseSB0aGUgbmVzdGluZyB3aWxsIGJlIGNvbnNpc3RlbnRseSBtb3JlIHRoYW4gYSBmZXcgbGV2ZWxzXG4gICAgLy8gZGVlcCAoPj0gNSksIHNvIHRoaXMgc2hvdWxkbid0IGJvZyBhbnl0aGluZyBkb3duLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0aC5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAocGF0aFtpXSAhPT0gY2FjaGUucGF0aFtpXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjYWNoZS5wYXRoID0gcGF0aFxuICAgIHJldHVybiB0cnVlXG59XG5cbi8qKlxuICogU3VwZXJjbGFzcyBmb3IgYWxsIHJlcG9ydGVycy4gVGhpcyBjb3ZlcnMgdGhlIHN0YXRlIGZvciBwcmV0dHkgbXVjaCBldmVyeVxuICogcmVwb3J0ZXIuXG4gKlxuICogTm90ZSB0aGF0IGlmIHlvdSBkZWxheSB0aGUgaW5pdGlhbCByZXNldCwgeW91IHN0aWxsIG11c3QgY2FsbCBpdCBiZWZvcmUgdGhlXG4gKiBjb25zdHJ1Y3RvciBmaW5pc2hlcy5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBSZXBvcnRlclxuZnVuY3Rpb24gUmVwb3J0ZXIoVHJlZSwgb3B0cywgbWV0aG9kcywgZGVsYXkpIHtcbiAgICB0aGlzLlRyZWUgPSBUcmVlXG4gICAgdGhpcy5vcHRzID0ge31cbiAgICB0aGlzLm1ldGhvZHMgPSBtZXRob2RzXG4gICAgZGVmYXVsdGlmeSh0aGlzLCBvcHRzLCBcInJlc2V0XCIpXG4gICAgaWYgKCFkZWxheSkgdGhpcy5yZXNldCgpXG59XG5cbm1ldGhvZHMoUmVwb3J0ZXIsIHtcbiAgICByZXNldDogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZVxuICAgICAgICB0aGlzLnRpbWVQcmludGVkID0gZmFsc2VcbiAgICAgICAgdGhpcy50ZXN0cyA9IDBcbiAgICAgICAgdGhpcy5wYXNzID0gMFxuICAgICAgICB0aGlzLmZhaWwgPSAwXG4gICAgICAgIHRoaXMuc2tpcCA9IDBcbiAgICAgICAgdGhpcy5kdXJhdGlvbiA9IDBcbiAgICAgICAgdGhpcy5lcnJvcnMgPSBbXVxuICAgICAgICB0aGlzLnN0YXRlID0gbmV3IFN0YXRlKHRoaXMpXG4gICAgICAgIHRoaXMuYmFzZSA9IG5ldyB0aGlzLlRyZWUodW5kZWZpbmVkKVxuICAgICAgICB0aGlzLmNhY2hlID0ge3BhdGg6IHVuZGVmaW5lZCwgcmVzdWx0OiB1bmRlZmluZWQsIGVuZDogMH1cbiAgICB9LFxuXG4gICAgcHVzaEVycm9yOiBmdW5jdGlvbiAocmVwb3J0KSB7XG4gICAgICAgIHRoaXMuZXJyb3JzLnB1c2gocmVwb3J0KVxuICAgIH0sXG5cbiAgICBnZXQ6IGZ1bmN0aW9uIChwYXRoLCBlbmQpIHtcbiAgICAgICAgaWYgKGVuZCA9PSBudWxsKSBlbmQgPSBwYXRoLmxlbmd0aFxuICAgICAgICBpZiAoZW5kID09PSAwKSByZXR1cm4gdGhpcy5iYXNlXG4gICAgICAgIGlmIChpc1JlcGVhdCh0aGlzLmNhY2hlLCBwYXRoLCBlbmQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYWNoZS5yZXN1bHRcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjaGlsZCA9IHRoaXMuYmFzZVxuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW5kOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBlbnRyeSA9IHBhdGhbaV1cblxuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKGNoaWxkLmNoaWxkcmVuLCBlbnRyeS5pbmRleCkpIHtcbiAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmNoaWxkcmVuW2VudHJ5LmluZGV4XVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmNoaWxkcmVuW2VudHJ5LmluZGV4XSA9IG5ldyB0aGlzLlRyZWUoZW50cnkubmFtZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FjaGUuZW5kID0gZW5kXG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlLnJlc3VsdCA9IGNoaWxkXG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuLi91dGlsXCIpXG52YXIgU2V0dGluZ3MgPSByZXF1aXJlKFwiLi4vc2V0dGluZ3NcIilcblxuZXhwb3J0cy5zeW1ib2xzID0gU2V0dGluZ3Muc3ltYm9sc1xuZXhwb3J0cy53aW5kb3dXaWR0aCA9IFNldHRpbmdzLndpbmRvd1dpZHRoXG5leHBvcnRzLm5ld2xpbmUgPSBTZXR0aW5ncy5uZXdsaW5lXG5cbi8qXG4gKiBTdGFjayBub3JtYWxpemF0aW9uXG4gKi9cblxuLy8gRXhwb3J0ZWQgZm9yIGRlYnVnZ2luZ1xuZXhwb3J0cy5yZWFkU3RhY2sgPSByZWFkU3RhY2tcbmZ1bmN0aW9uIHJlYWRTdGFjayhlKSB7XG4gICAgdmFyIHN0YWNrID0gVXRpbC5nZXRTdGFjayhlKVxuXG4gICAgLy8gSWYgaXQgZG9lc24ndCBzdGFydCB3aXRoIHRoZSBtZXNzYWdlLCBqdXN0IHJldHVybiB0aGUgc3RhY2suXG4gICAgLy8gIEZpcmVmb3gsIFNhZmFyaSAgICAgICAgICAgICAgICBDaHJvbWUsIElFXG4gICAgaWYgKC9eKEApP1xcUytcXDpcXGQrLy50ZXN0KHN0YWNrKSB8fCAvXlxccyphdC8udGVzdChzdGFjaykpIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdExpbmVCcmVha3Moc3RhY2spXG4gICAgfVxuXG4gICAgdmFyIGluZGV4ID0gc3RhY2suaW5kZXhPZihlLm1lc3NhZ2UpXG5cbiAgICBpZiAoaW5kZXggPCAwKSByZXR1cm4gZm9ybWF0TGluZUJyZWFrcyhVdGlsLmdldFN0YWNrKGUpKVxuICAgIHZhciByZSA9IC9cXHI/XFxuL2dcblxuICAgIHJlLmxhc3RJbmRleCA9IGluZGV4ICsgZS5tZXNzYWdlLmxlbmd0aFxuICAgIGlmICghcmUudGVzdChzdGFjaykpIHJldHVybiBcIlwiXG4gICAgcmV0dXJuIGZvcm1hdExpbmVCcmVha3Moc3RhY2suc2xpY2UocmUubGFzdEluZGV4KSlcbn1cblxuZnVuY3Rpb24gZm9ybWF0TGluZUJyZWFrcyhzdHIpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFteXFxyXFxuXFxTXSskL2csIFwiXCIpXG4gICAgICAgIC5yZXBsYWNlKC9cXHMqKFxccj9cXG58XFxyKVxccyovZywgU2V0dGluZ3MubmV3bGluZSgpKVxufVxuXG5leHBvcnRzLmdldFN0YWNrID0gZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAoIShlIGluc3RhbmNlb2YgRXJyb3IpKSByZXR1cm4gZm9ybWF0TGluZUJyZWFrcyhVdGlsLmdldFN0YWNrKGUpKVxuICAgIHZhciBkZXNjcmlwdGlvbiA9IChlLm5hbWUgKyBcIjogXCIgKyBlLm1lc3NhZ2UpXG4gICAgICAgIC5yZXBsYWNlKC9cXHMrJC9nbSwgXCJcIilcbiAgICAgICAgLnJlcGxhY2UoL1xccj9cXG58XFxyL2csIFNldHRpbmdzLm5ld2xpbmUoKSlcbiAgICB2YXIgc3RyaXBwZWQgPSByZWFkU3RhY2soZSlcblxuICAgIGlmIChzdHJpcHBlZCA9PT0gXCJcIikgcmV0dXJuIGRlc2NyaXB0aW9uXG4gICAgcmV0dXJuIGRlc2NyaXB0aW9uICsgU2V0dGluZ3MubmV3bGluZSgpICsgc3RyaXBwZWRcbn1cblxudmFyIENvbG9ycyA9IGV4cG9ydHMuQ29sb3JzID0gU2V0dGluZ3MuQ29sb3JzXG5cbi8vIENvbG9yIHBhbGV0dGUgcHVsbGVkIGZyb20gTW9jaGFcbmZ1bmN0aW9uIGNvbG9yVG9OdW1iZXIobmFtZSkge1xuICAgIHN3aXRjaCAobmFtZSkge1xuICAgIGNhc2UgXCJwYXNzXCI6IHJldHVybiA5MFxuICAgIGNhc2UgXCJmYWlsXCI6IHJldHVybiAzMVxuXG4gICAgY2FzZSBcImJyaWdodCBwYXNzXCI6IHJldHVybiA5MlxuICAgIGNhc2UgXCJicmlnaHQgZmFpbFwiOiByZXR1cm4gOTFcbiAgICBjYXNlIFwiYnJpZ2h0IHllbGxvd1wiOiByZXR1cm4gOTNcblxuICAgIGNhc2UgXCJza2lwXCI6IHJldHVybiAzNlxuICAgIGNhc2UgXCJzdWl0ZVwiOiByZXR1cm4gMFxuICAgIGNhc2UgXCJwbGFpblwiOiByZXR1cm4gMFxuXG4gICAgY2FzZSBcImVycm9yIHRpdGxlXCI6IHJldHVybiAwXG4gICAgY2FzZSBcImVycm9yIG1lc3NhZ2VcIjogcmV0dXJuIDMxXG4gICAgY2FzZSBcImVycm9yIHN0YWNrXCI6IHJldHVybiA5MFxuXG4gICAgY2FzZSBcImNoZWNrbWFya1wiOiByZXR1cm4gMzJcbiAgICBjYXNlIFwiZmFzdFwiOiByZXR1cm4gOTBcbiAgICBjYXNlIFwibWVkaXVtXCI6IHJldHVybiAzM1xuICAgIGNhc2UgXCJzbG93XCI6IHJldHVybiAzMVxuICAgIGNhc2UgXCJncmVlblwiOiByZXR1cm4gMzJcbiAgICBjYXNlIFwibGlnaHRcIjogcmV0dXJuIDkwXG5cbiAgICBjYXNlIFwiZGlmZiBndXR0ZXJcIjogcmV0dXJuIDkwXG4gICAgY2FzZSBcImRpZmYgYWRkZWRcIjogcmV0dXJuIDMyXG4gICAgY2FzZSBcImRpZmYgcmVtb3ZlZFwiOiByZXR1cm4gMzFcbiAgICBkZWZhdWx0OiB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBuYW1lOiBcXFwiXCIgKyBuYW1lICsgXCJcXFwiXCIpXG4gICAgfVxufVxuXG5leHBvcnRzLmNvbG9yID0gY29sb3JcbmZ1bmN0aW9uIGNvbG9yKG5hbWUsIHN0cikge1xuICAgIGlmIChDb2xvcnMuc3VwcG9ydGVkKCkpIHtcbiAgICAgICAgcmV0dXJuIFwiXFx1MDAxYltcIiArIGNvbG9yVG9OdW1iZXIobmFtZSkgKyBcIm1cIiArIHN0ciArIFwiXFx1MDAxYlswbVwiXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHN0ciArIFwiXCJcbiAgICB9XG59XG5cbmV4cG9ydHMuc2V0Q29sb3IgPSBmdW5jdGlvbiAoXykge1xuICAgIGlmIChfLm9wdHMuY29sb3IgIT0gbnVsbCkgQ29sb3JzLm1heWJlU2V0KF8ub3B0cy5jb2xvcilcbn1cblxuZXhwb3J0cy51bnNldENvbG9yID0gZnVuY3Rpb24gKF8pIHtcbiAgICBpZiAoXy5vcHRzLmNvbG9yICE9IG51bGwpIENvbG9ycy5tYXliZVJlc3RvcmUoKVxufVxuXG52YXIgU3RhdHVzID0gZXhwb3J0cy5TdGF0dXMgPSBPYmplY3QuZnJlZXplKHtcbiAgICBVbmtub3duOiAwLFxuICAgIFNraXBwZWQ6IDEsXG4gICAgUGFzc2luZzogMixcbiAgICBGYWlsaW5nOiAzLFxufSlcblxuZXhwb3J0cy5UcmVlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlXG4gICAgdGhpcy5zdGF0dXMgPSBTdGF0dXMuVW5rbm93blxuICAgIHRoaXMuY2hpbGRyZW4gPSBPYmplY3QuY3JlYXRlKG51bGwpXG59XG5cbmV4cG9ydHMuZGVmYXVsdGlmeSA9IGZ1bmN0aW9uIChfLCBvcHRzLCBwcm9wKSB7XG4gICAgaWYgKF8ubWV0aG9kcy5hY2NlcHRzLmluZGV4T2YocHJvcCkgPj0gMCkge1xuICAgICAgICB2YXIgdXNlZCA9IG9wdHMgIT0gbnVsbCAmJiB0eXBlb2Ygb3B0c1twcm9wXSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICA/IG9wdHNcbiAgICAgICAgICAgIDogU2V0dGluZ3MuZGVmYXVsdE9wdHMoKVxuXG4gICAgICAgIF8ub3B0c1twcm9wXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodXNlZFtwcm9wXS5hcHBseSh1c2VkLCBhcmd1bWVudHMpKVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBqb2luUGF0aChyZXBvcnRQYXRoKSB7XG4gICAgdmFyIHBhdGggPSBcIlwiXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcG9ydFBhdGgubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcGF0aCArPSBcIiBcIiArIHJlcG9ydFBhdGhbaV0ubmFtZVxuICAgIH1cblxuICAgIHJldHVybiBwYXRoLnNsaWNlKDEpXG59XG5cbmV4cG9ydHMuam9pblBhdGggPSBmdW5jdGlvbiAocmVwb3J0KSB7XG4gICAgcmV0dXJuIGpvaW5QYXRoKHJlcG9ydC5wYXRoKVxufVxuXG5leHBvcnRzLnNwZWVkID0gZnVuY3Rpb24gKHJlcG9ydCkge1xuICAgIGlmIChyZXBvcnQuZHVyYXRpb24gPj0gcmVwb3J0LnNsb3cpIHJldHVybiBcInNsb3dcIlxuICAgIGlmIChyZXBvcnQuZHVyYXRpb24gPj0gcmVwb3J0LnNsb3cgLyAyKSByZXR1cm4gXCJtZWRpdW1cIlxuICAgIGlmIChyZXBvcnQuZHVyYXRpb24gPj0gMCkgcmV0dXJuIFwiZmFzdFwiXG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJEdXJhdGlvbiBtdXN0IG5vdCBiZSBuZWdhdGl2ZVwiKVxufVxuXG5leHBvcnRzLmZvcm1hdFRpbWUgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBzID0gMTAwMCAvKiBtcyAqL1xuICAgIHZhciBtID0gNjAgKiBzXG4gICAgdmFyIGggPSA2MCAqIG1cbiAgICB2YXIgZCA9IDI0ICogaFxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChtcykge1xuICAgICAgICBpZiAobXMgPj0gZCkgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArIFwiZFwiXG4gICAgICAgIGlmIChtcyA+PSBoKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIGgpICsgXCJoXCJcbiAgICAgICAgaWYgKG1zID49IG0pIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gbSkgKyBcIm1cIlxuICAgICAgICBpZiAobXMgPj0gcykgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArIFwic1wiXG4gICAgICAgIHJldHVybiBtcyArIFwibXNcIlxuICAgIH1cbn0pKClcblxuZXhwb3J0cy5mb3JtYXRSZXN0ID0gZnVuY3Rpb24gKHJlcG9ydCkge1xuICAgIGlmICghcmVwb3J0LmlzSG9vaykgcmV0dXJuIFwiXCJcbiAgICB2YXIgcGF0aCA9IFwiIChcIlxuXG4gICAgaWYgKHJlcG9ydC5yb290UGF0aC5sZW5ndGgpIHtcbiAgICAgICAgcGF0aCArPSByZXBvcnQuc3RhZ2VcbiAgICAgICAgaWYgKHJlcG9ydC5uYW1lKSBwYXRoICs9IFwiIOKAkiBcIiArIHJlcG9ydC5uYW1lXG4gICAgICAgIGlmIChyZXBvcnQucGF0aC5sZW5ndGggPiByZXBvcnQucm9vdFBhdGgubGVuZ3RoICsgMSkge1xuICAgICAgICAgICAgcGF0aCArPSBcIiwgaW4gXCIgKyBqb2luUGF0aChyZXBvcnQucm9vdFBhdGgpXG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBwYXRoICs9IFwiZ2xvYmFsIFwiICsgcmVwb3J0LnN0YWdlXG4gICAgICAgIGlmIChyZXBvcnQubmFtZSkgcGF0aCArPSBcIiDigJIgXCIgKyByZXBvcnQubmFtZVxuICAgIH1cblxuICAgIHJldHVybiBwYXRoICsgXCIpXCJcbn1cbiIsIlwidXNlIHN0cmljdFwiXG5cbi8vIEdlbmVyYWwgQ0xJIGFuZCByZXBvcnRlciBzZXR0aW5ncy4gSWYgc29tZXRoaW5nIG5lZWRzIHRvXG5cbnZhciBDb25zb2xlID0gcmVxdWlyZShcIi4vcmVwbGFjZWQvY29uc29sZVwiKVxuXG52YXIgd2luZG93V2lkdGggPSBDb25zb2xlLndpbmRvd1dpZHRoXG52YXIgbmV3bGluZSA9IENvbnNvbGUubmV3bGluZVxudmFyIFN5bWJvbHMgPSBDb25zb2xlLlN5bWJvbHNcbnZhciBkZWZhdWx0T3B0cyA9IENvbnNvbGUuZGVmYXVsdE9wdHNcblxuZXhwb3J0cy53aW5kb3dXaWR0aCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHdpbmRvd1dpZHRoIH1cbmV4cG9ydHMubmV3bGluZSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ld2xpbmUgfVxuZXhwb3J0cy5zeW1ib2xzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gU3ltYm9scyB9XG5leHBvcnRzLmRlZmF1bHRPcHRzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gZGVmYXVsdE9wdHMgfVxuXG5leHBvcnRzLnNldFdpbmRvd1dpZHRoID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiB3aW5kb3dXaWR0aCA9IHZhbHVlIH1cbmV4cG9ydHMuc2V0TmV3bGluZSA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gbmV3bGluZSA9IHZhbHVlIH1cbmV4cG9ydHMuc2V0U3ltYm9scyA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gU3ltYm9scyA9IHZhbHVlIH1cbmV4cG9ydHMuc2V0RGVmYXVsdE9wdHMgPSBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIGRlZmF1bHRPcHRzID0gdmFsdWUgfVxuXG4vLyBDb25zb2xlLmNvbG9yU3VwcG9ydCBpcyBhIG1hc2sgd2l0aCB0aGUgZm9sbG93aW5nIGJpdHM6XG4vLyAweDEgLSBpZiBzZXQsIGNvbG9ycyBzdXBwb3J0ZWQgYnkgZGVmYXVsdFxuLy8gMHgyIC0gaWYgc2V0LCBmb3JjZSBjb2xvciBzdXBwb3J0XG4vL1xuLy8gVGhpcyBpcyBwdXJlbHkgYW4gaW1wbGVtZW50YXRpb24gZGV0YWlsLCBhbmQgaXMgaW52aXNpYmxlIHRvIHRoZSBvdXRzaWRlXG4vLyB3b3JsZC5cbnZhciBjb2xvclN1cHBvcnQgPSBDb25zb2xlLmNvbG9yU3VwcG9ydFxudmFyIG1hc2sgPSBjb2xvclN1cHBvcnRcblxuZXhwb3J0cy5Db2xvcnMgPSB7XG4gICAgc3VwcG9ydGVkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAobWFzayAmIDB4MSkgIT09IDBcbiAgICB9LFxuXG4gICAgZm9yY2VkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiAobWFzayAmIDB4MikgIT09IDBcbiAgICB9LFxuXG4gICAgbWF5YmVTZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICBpZiAoKG1hc2sgJiAweDIpID09PSAwKSBtYXNrID0gdmFsdWUgPyAweDEgOiAwXG4gICAgfSxcblxuICAgIG1heWJlUmVzdG9yZTogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoKG1hc2sgJiAweDIpID09PSAwKSBtYXNrID0gY29sb3JTdXBwb3J0ICYgMHgxXG4gICAgfSxcblxuICAgIC8vIE9ubHkgZm9yIGRlYnVnZ2luZ1xuICAgIGZvcmNlU2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgbWFzayA9IHZhbHVlID8gMHgzIDogMHgyXG4gICAgfSxcblxuICAgIGZvcmNlUmVzdG9yZTogZnVuY3Rpb24gKCkge1xuICAgICAgICBtYXNrID0gY29sb3JTdXBwb3J0XG4gICAgfSxcblxuICAgIGdldFN1cHBvcnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1cHBvcnRlZDogKGNvbG9yU3VwcG9ydCAmIDB4MSkgIT09IDAsXG4gICAgICAgICAgICBmb3JjZWQ6IChjb2xvclN1cHBvcnQgJiAweDIpICE9PSAwLFxuICAgICAgICB9XG4gICAgfSxcblxuICAgIHNldFN1cHBvcnQ6IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgICAgIG1hc2sgPSBjb2xvclN1cHBvcnQgPVxuICAgICAgICAgICAgKG9wdHMuc3VwcG9ydGVkID8gMHgxIDogMCkgfCAob3B0cy5mb3JjZWQgPyAweDIgOiAwKVxuICAgIH0sXG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgbWV0aG9kcyA9IHJlcXVpcmUoXCIuL21ldGhvZHNcIilcblxuZXhwb3J0cy5nZXRUeXBlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBcIm51bGxcIlxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIFwiYXJyYXlcIlxuICAgIHJldHVybiB0eXBlb2YgdmFsdWVcbn1cblxuLy8gUGhhbnRvbUpTLCBJRSwgYW5kIHBvc3NpYmx5IEVkZ2UgZG9uJ3Qgc2V0IHRoZSBzdGFjayB0cmFjZSB1bnRpbCB0aGUgZXJyb3IgaXNcbi8vIHRocm93bi4gTm90ZSB0aGF0IHRoaXMgcHJlZmVycyBhbiBleGlzdGluZyBzdGFjayBmaXJzdCwgc2luY2Ugbm9uLW5hdGl2ZVxuLy8gZXJyb3JzIGxpa2VseSBhbHJlYWR5IGNvbnRhaW4gdGhpcy4gTm90ZSB0aGF0IHRoaXMgaXNuJ3QgbmVjZXNzYXJ5IGluIHRoZVxuLy8gQ0xJIC0gdGhhdCBvbmx5IHRhcmdldHMgTm9kZS5cbmV4cG9ydHMuZ2V0U3RhY2sgPSBmdW5jdGlvbiAoZSkge1xuICAgIHZhciBzdGFjayA9IGUuc3RhY2tcblxuICAgIGlmICghKGUgaW5zdGFuY2VvZiBFcnJvcikgfHwgc3RhY2sgIT0gbnVsbCkgcmV0dXJuIHN0YWNrXG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBlXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZS5zdGFja1xuICAgIH1cbn1cblxuZXhwb3J0cy5wY2FsbCA9IGZ1bmN0aW9uIChmdW5jKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmMoZnVuY3Rpb24gKGUsIHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gZSAhPSBudWxsID8gcmVqZWN0KGUpIDogcmVzb2x2ZSh2YWx1ZSlcbiAgICAgICAgfSlcbiAgICB9KVxufVxuXG5leHBvcnRzLnBlYWNoID0gZnVuY3Rpb24gKGxpc3QsIGZ1bmMpIHtcbiAgICB2YXIgbGVuID0gbGlzdC5sZW5ndGhcbiAgICB2YXIgcCA9IFByb21pc2UucmVzb2x2ZSgpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHAgPSBwLnRoZW4oZnVuYy5iaW5kKHVuZGVmaW5lZCwgbGlzdFtpXSwgaSkpXG4gICAgfVxuXG4gICAgcmV0dXJuIHBcbn1cblxuLyoqXG4gKiBBIGxhenkgYWNjZXNzb3IsIGNvbXBsZXRlIHdpdGggdGhyb3duIGVycm9yIG1lbW9pemF0aW9uIGFuZCBhIGRlY2VudCBhbW91bnRcbiAqIG9mIG9wdGltaXphdGlvbiwgc2luY2UgaXQncyB1c2VkIGluIGEgbG90IG9mIGNvZGUuXG4gKlxuICogTm90ZSB0aGF0IHRoaXMgdXNlcyByZWZlcmVuY2UgaW5kaXJlY3Rpb24gYW5kIGRpcmVjdCBtdXRhdGlvbiB0byBrZWVwIG9ubHlcbiAqIGp1c3QgdGhlIGNvbXB1dGF0aW9uIG5vbi1jb25zdGFudCwgc28gZW5naW5lcyBjYW4gYXZvaWQgY2xvc3VyZSBhbGxvY2F0aW9uLlxuICogQWxzbywgYGNyZWF0ZWAgaXMgaW50ZW50aW9uYWxseSBrZXB0ICpvdXQqIG9mIGFueSBjbG9zdXJlLCBzbyBpdCBjYW4gYmUgbW9yZVxuICogZWFzaWx5IGNvbGxlY3RlZC5cbiAqL1xuZnVuY3Rpb24gTGF6eShjcmVhdGUpIHtcbiAgICB0aGlzLnZhbHVlID0gY3JlYXRlXG4gICAgdGhpcy5nZXQgPSB0aGlzLmluaXRcbn1cblxubWV0aG9kcyhMYXp5LCB7XG4gICAgcmVjdXJzaXZlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJMYXp5IGZ1bmN0aW9ucyBtdXN0IG5vdCBiZSBjYWxsZWQgcmVjdXJzaXZlbHkhXCIpXG4gICAgfSxcblxuICAgIHJldHVybjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZVxuICAgIH0sXG5cbiAgICB0aHJvdzogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aHJvdyB0aGlzLnZhbHVlXG4gICAgfSxcblxuICAgIGluaXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5nZXQgPSB0aGlzLnJlY3Vyc2l2ZVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gKDAsIHRoaXMudmFsdWUpKClcbiAgICAgICAgICAgIHRoaXMuZ2V0ID0gdGhpcy5yZXR1cm5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLnZhbHVlXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSBlXG4gICAgICAgICAgICB0aGlzLmdldCA9IHRoaXMudGhyb3dcbiAgICAgICAgICAgIHRocm93IHRoaXMudmFsdWVcbiAgICAgICAgfVxuICAgIH0sXG59KVxuXG5leHBvcnRzLmxhenkgPSBmdW5jdGlvbiAoY3JlYXRlKSB7XG4gICAgdmFyIHJlZiA9IG5ldyBMYXp5KGNyZWF0ZSlcblxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiByZWYuZ2V0KClcbiAgICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh4cywgZikge1xuICAgIGlmICh4cy5tYXApIHJldHVybiB4cy5tYXAoZik7XG4gICAgdmFyIHJlcyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHggPSB4c1tpXTtcbiAgICAgICAgaWYgKGhhc093bi5jYWxsKHhzLCBpKSkgcmVzLnB1c2goZih4LCBpLCB4cykpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufTtcblxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG4iLCJ2YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoeHMsIGYsIGFjYykge1xuICAgIHZhciBoYXNBY2MgPSBhcmd1bWVudHMubGVuZ3RoID49IDM7XG4gICAgaWYgKGhhc0FjYyAmJiB4cy5yZWR1Y2UpIHJldHVybiB4cy5yZWR1Y2UoZiwgYWNjKTtcbiAgICBpZiAoeHMucmVkdWNlKSByZXR1cm4geHMucmVkdWNlKGYpO1xuICAgIFxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKCFoYXNPd24uY2FsbCh4cywgaSkpIGNvbnRpbnVlO1xuICAgICAgICBpZiAoIWhhc0FjYykge1xuICAgICAgICAgICAgYWNjID0geHNbaV07XG4gICAgICAgICAgICBoYXNBY2MgPSB0cnVlO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgYWNjID0gZihhY2MsIHhzW2ldLCBpKTtcbiAgICB9XG4gICAgcmV0dXJuIGFjYztcbn07XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3N1YnN0YWNrL25vZGUtYnJvd3NlcmlmeS9pc3N1ZXMvMTY3NFxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ1dGlsLWluc3BlY3RcIilcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciBpbnNwZWN0ID0gZXhwb3J0cy5pbnNwZWN0ID0gcmVxdWlyZShcIi4vaW5zcGVjdFwiKVxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcbnZhciBBc3NlcnRpb25FcnJvclxuXG4vLyBQaGFudG9tSlMsIElFLCBhbmQgcG9zc2libHkgRWRnZSBkb24ndCBzZXQgdGhlIHN0YWNrIHRyYWNlIHVudGlsIHRoZSBlcnJvciBpc1xuLy8gdGhyb3duLiBOb3RlIHRoYXQgdGhpcyBwcmVmZXJzIGFuIGV4aXN0aW5nIHN0YWNrIGZpcnN0LCBzaW5jZSBub24tbmF0aXZlXG4vLyBlcnJvcnMgbGlrZWx5IGFscmVhZHkgY29udGFpbiB0aGlzLlxuZnVuY3Rpb24gZ2V0U3RhY2soZSkge1xuICAgIHZhciBzdGFjayA9IGUuc3RhY2tcblxuICAgIGlmICghKGUgaW5zdGFuY2VvZiBFcnJvcikgfHwgc3RhY2sgIT0gbnVsbCkgcmV0dXJuIHN0YWNrXG5cbiAgICB0cnkge1xuICAgICAgICB0aHJvdyBlXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZS5zdGFja1xuICAgIH1cbn1cblxudHJ5IHtcbiAgICBBc3NlcnRpb25FcnJvciA9IG5ldyBGdW5jdGlvbihbIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3LWZ1bmNcbiAgICAgICAgXCIndXNlIHN0cmljdCc7XCIsXG4gICAgICAgIFwiY2xhc3MgQXNzZXJ0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7XCIsXG4gICAgICAgIFwiICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIGV4cGVjdGVkLCBhY3R1YWwpIHtcIixcbiAgICAgICAgXCIgICAgICAgIHN1cGVyKG1lc3NhZ2UpXCIsXG4gICAgICAgIFwiICAgICAgICB0aGlzLmV4cGVjdGVkID0gZXhwZWN0ZWRcIixcbiAgICAgICAgXCIgICAgICAgIHRoaXMuYWN0dWFsID0gYWN0dWFsXCIsXG4gICAgICAgIFwiICAgIH1cIixcbiAgICAgICAgXCJcIixcbiAgICAgICAgXCIgICAgZ2V0IG5hbWUoKSB7XCIsXG4gICAgICAgIFwiICAgICAgICByZXR1cm4gJ0Fzc2VydGlvbkVycm9yJ1wiLFxuICAgICAgICBcIiAgICB9XCIsXG4gICAgICAgIFwifVwiLFxuICAgICAgICAvLyBjaGVjayBuYXRpdmUgc3ViY2xhc3Npbmcgc3VwcG9ydFxuICAgICAgICBcIm5ldyBBc3NlcnRpb25FcnJvcignbWVzc2FnZScsIDEsIDIpXCIsXG4gICAgICAgIFwicmV0dXJuIEFzc2VydGlvbkVycm9yXCIsXG4gICAgXS5qb2luKFwiXFxuXCIpKSgpXG59IGNhdGNoIChlKSB7XG4gICAgQXNzZXJ0aW9uRXJyb3IgPSB0eXBlb2YgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICA/IGZ1bmN0aW9uIEFzc2VydGlvbkVycm9yKG1lc3NhZ2UsIGV4cGVjdGVkLCBhY3R1YWwpIHtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgXCJcIlxuICAgICAgICAgICAgdGhpcy5leHBlY3RlZCA9IGV4cGVjdGVkXG4gICAgICAgICAgICB0aGlzLmFjdHVhbCA9IGFjdHVhbFxuICAgICAgICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgdGhpcy5jb25zdHJ1Y3RvcilcbiAgICAgICAgfVxuICAgICAgICA6IGZ1bmN0aW9uIEFzc2VydGlvbkVycm9yKG1lc3NhZ2UsIGV4cGVjdGVkLCBhY3R1YWwpIHtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2UgfHwgXCJcIlxuICAgICAgICAgICAgdGhpcy5leHBlY3RlZCA9IGV4cGVjdGVkXG4gICAgICAgICAgICB0aGlzLmFjdHVhbCA9IGFjdHVhbFxuICAgICAgICAgICAgdmFyIGUgPSBuZXcgRXJyb3IobWVzc2FnZSlcblxuICAgICAgICAgICAgZS5uYW1lID0gXCJBc3NlcnRpb25FcnJvclwiXG4gICAgICAgICAgICB0aGlzLnN0YWNrID0gZ2V0U3RhY2soZSlcbiAgICAgICAgfVxuXG4gICAgQXNzZXJ0aW9uRXJyb3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShFcnJvci5wcm90b3R5cGUpXG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQXNzZXJ0aW9uRXJyb3IucHJvdG90eXBlLCBcImNvbnN0cnVjdG9yXCIsIHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHZhbHVlOiBBc3NlcnRpb25FcnJvcixcbiAgICB9KVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFzc2VydGlvbkVycm9yLnByb3RvdHlwZSwgXCJuYW1lXCIsIHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHZhbHVlOiBcIkFzc2VydGlvbkVycm9yXCIsXG4gICAgfSlcbn1cblxuZXhwb3J0cy5Bc3NlcnRpb25FcnJvciA9IEFzc2VydGlvbkVycm9yXG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLXNlbGYtY29tcGFyZSAqL1xuLy8gRm9yIGJldHRlciBOYU4gaGFuZGxpbmdcbmV4cG9ydHMuc3RyaWN0SXMgPSBmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiBhID09PSBiIHx8IGEgIT09IGEgJiYgYiAhPT0gYlxufVxuXG5leHBvcnRzLmxvb3NlSXMgPSBmdW5jdGlvbiAoYSwgYikge1xuICAgIHJldHVybiBhID09IGIgfHwgYSAhPT0gYSAmJiBiICE9PSBiIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgZXFlcWVxXG59XG5cbi8qIGVzbGludC1lbmFibGUgbm8tc2VsZi1jb21wYXJlICovXG5cbnZhciB0ZW1wbGF0ZVJlZ2V4cCA9IC8oLj8pXFx7KC4rPylcXH0vZ1xuXG5leHBvcnRzLmVzY2FwZSA9IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgICBpZiAodHlwZW9mIHN0cmluZyAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYHN0cmluZ2AgbXVzdCBiZSBhIHN0cmluZ1wiKVxuICAgIH1cblxuICAgIHJldHVybiBzdHJpbmcucmVwbGFjZSh0ZW1wbGF0ZVJlZ2V4cCwgZnVuY3Rpb24gKG0sIHByZSkge1xuICAgICAgICByZXR1cm4gcHJlICsgXCJcXFxcXCIgKyBtLnNsaWNlKDEpXG4gICAgfSlcbn1cblxuLy8gVGhpcyBmb3JtYXRzIHRoZSBhc3NlcnRpb24gZXJyb3IgbWVzc2FnZXMuXG5leHBvcnRzLmZvcm1hdCA9IGZ1bmN0aW9uIChtZXNzYWdlLCBhcmdzLCBwcmV0dGlmeSkge1xuICAgIGlmIChwcmV0dGlmeSA9PSBudWxsKSBwcmV0dGlmeSA9IGluc3BlY3RcblxuICAgIGlmICh0eXBlb2YgbWVzc2FnZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYG1lc3NhZ2VgIG11c3QgYmUgYSBzdHJpbmdcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGFyZ3MgIT09IFwib2JqZWN0XCIgfHwgYXJncyA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGFyZ3NgIG11c3QgYmUgYW4gb2JqZWN0XCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBwcmV0dGlmeSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgcHJldHRpZnlgIG11c3QgYmUgYSBmdW5jdGlvbiBpZiBwYXNzZWRcIilcbiAgICB9XG5cbiAgICByZXR1cm4gbWVzc2FnZS5yZXBsYWNlKHRlbXBsYXRlUmVnZXhwLCBmdW5jdGlvbiAobSwgcHJlLCBwcm9wKSB7XG4gICAgICAgIGlmIChwcmUgPT09IFwiXFxcXFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gbS5zbGljZSgxKVxuICAgICAgICB9IGVsc2UgaWYgKGhhc093bi5jYWxsKGFyZ3MsIHByb3ApKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJlICsgcHJldHRpZnkoYXJnc1twcm9wXSwge2RlcHRoOiA1fSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBwcmUgKyBtXG4gICAgICAgIH1cbiAgICB9KVxufVxuXG5leHBvcnRzLmZhaWwgPSBmdW5jdGlvbiAobWVzc2FnZSwgYXJncywgcHJldHRpZnkpIHtcbiAgICBpZiAoYXJncyA9PSBudWxsKSB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IobWVzc2FnZSlcbiAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoXG4gICAgICAgIGV4cG9ydHMuZm9ybWF0KG1lc3NhZ2UsIGFyZ3MsIHByZXR0aWZ5KSxcbiAgICAgICAgYXJncy5leHBlY3RlZCxcbiAgICAgICAgYXJncy5hY3R1YWwpXG59XG5cbi8vIFRoZSBiYXNpYyBhc3NlcnQsIGxpa2UgYGFzc2VydC5va2AsIGJ1dCBnaXZlcyB5b3UgYW4gb3B0aW9uYWwgbWVzc2FnZS5cbmV4cG9ydHMuYXNzZXJ0ID0gZnVuY3Rpb24gKHRlc3QsIG1lc3NhZ2UpIHtcbiAgICBpZiAoIXRlc3QpIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihtZXNzYWdlKVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLyoqXG4gKiBDb3JlIFRERC1zdHlsZSBhc3NlcnRpb25zLiBUaGVzZSBhcmUgZG9uZSBieSBhIGNvbXBvc2l0aW9uIG9mIERTTHMsIHNpbmNlXG4gKiB0aGVyZSBpcyAqc28qIG11Y2ggcmVwZXRpdGlvbi4gQWxzbywgdGhpcyBpcyBzcGxpdCBpbnRvIHNldmVyYWwgbmFtZXNwYWNlcyB0b1xuICoga2VlcCB0aGUgZmlsZSBzaXplIG1hbmFnZWFibGUuXG4gKi9cblxudmFyIHV0aWwgPSByZXF1aXJlKFwiY2xlYW4tYXNzZXJ0LXV0aWxcIilcbnZhciB0eXBlID0gcmVxdWlyZShcIi4vbGliL3R5cGVcIilcbnZhciBlcXVhbCA9IHJlcXVpcmUoXCIuL2xpYi9lcXVhbFwiKVxudmFyIHRocm93cyA9IHJlcXVpcmUoXCIuL2xpYi90aHJvd3NcIilcbnZhciBoYXMgPSByZXF1aXJlKFwiLi9saWIvaGFzXCIpXG52YXIgaW5jbHVkZXMgPSByZXF1aXJlKFwiLi9saWIvaW5jbHVkZXNcIilcbnZhciBoYXNLZXlzID0gcmVxdWlyZShcIi4vbGliL2hhcy1rZXlzXCIpXG5cbmV4cG9ydHMuQXNzZXJ0aW9uRXJyb3IgPSB1dGlsLkFzc2VydGlvbkVycm9yXG5leHBvcnRzLmFzc2VydCA9IHV0aWwuYXNzZXJ0XG5leHBvcnRzLmZhaWwgPSB1dGlsLmZhaWxcblxuZXhwb3J0cy5vayA9IHR5cGUub2tcbmV4cG9ydHMubm90T2sgPSB0eXBlLm5vdE9rXG5leHBvcnRzLmlzQm9vbGVhbiA9IHR5cGUuaXNCb29sZWFuXG5leHBvcnRzLm5vdEJvb2xlYW4gPSB0eXBlLm5vdEJvb2xlYW5cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IHR5cGUuaXNGdW5jdGlvblxuZXhwb3J0cy5ub3RGdW5jdGlvbiA9IHR5cGUubm90RnVuY3Rpb25cbmV4cG9ydHMuaXNOdW1iZXIgPSB0eXBlLmlzTnVtYmVyXG5leHBvcnRzLm5vdE51bWJlciA9IHR5cGUubm90TnVtYmVyXG5leHBvcnRzLmlzT2JqZWN0ID0gdHlwZS5pc09iamVjdFxuZXhwb3J0cy5ub3RPYmplY3QgPSB0eXBlLm5vdE9iamVjdFxuZXhwb3J0cy5pc1N0cmluZyA9IHR5cGUuaXNTdHJpbmdcbmV4cG9ydHMubm90U3RyaW5nID0gdHlwZS5ub3RTdHJpbmdcbmV4cG9ydHMuaXNTeW1ib2wgPSB0eXBlLmlzU3ltYm9sXG5leHBvcnRzLm5vdFN5bWJvbCA9IHR5cGUubm90U3ltYm9sXG5leHBvcnRzLmV4aXN0cyA9IHR5cGUuZXhpc3RzXG5leHBvcnRzLm5vdEV4aXN0cyA9IHR5cGUubm90RXhpc3RzXG5leHBvcnRzLmlzQXJyYXkgPSB0eXBlLmlzQXJyYXlcbmV4cG9ydHMubm90QXJyYXkgPSB0eXBlLm5vdEFycmF5XG5leHBvcnRzLmlzID0gdHlwZS5pc1xuZXhwb3J0cy5ub3QgPSB0eXBlLm5vdFxuXG5leHBvcnRzLmVxdWFsID0gZXF1YWwuZXF1YWxcbmV4cG9ydHMubm90RXF1YWwgPSBlcXVhbC5ub3RFcXVhbFxuZXhwb3J0cy5lcXVhbExvb3NlID0gZXF1YWwuZXF1YWxMb29zZVxuZXhwb3J0cy5ub3RFcXVhbExvb3NlID0gZXF1YWwubm90RXF1YWxMb29zZVxuZXhwb3J0cy5kZWVwRXF1YWwgPSBlcXVhbC5kZWVwRXF1YWxcbmV4cG9ydHMubm90RGVlcEVxdWFsID0gZXF1YWwubm90RGVlcEVxdWFsXG5leHBvcnRzLm1hdGNoID0gZXF1YWwubWF0Y2hcbmV4cG9ydHMubm90TWF0Y2ggPSBlcXVhbC5ub3RNYXRjaFxuZXhwb3J0cy5hdExlYXN0ID0gZXF1YWwuYXRMZWFzdFxuZXhwb3J0cy5hdE1vc3QgPSBlcXVhbC5hdE1vc3RcbmV4cG9ydHMuYWJvdmUgPSBlcXVhbC5hYm92ZVxuZXhwb3J0cy5iZWxvdyA9IGVxdWFsLmJlbG93XG5leHBvcnRzLmJldHdlZW4gPSBlcXVhbC5iZXR3ZWVuXG5leHBvcnRzLmNsb3NlVG8gPSBlcXVhbC5jbG9zZVRvXG5leHBvcnRzLm5vdENsb3NlVG8gPSBlcXVhbC5ub3RDbG9zZVRvXG5cbmV4cG9ydHMudGhyb3dzID0gdGhyb3dzLnRocm93c1xuZXhwb3J0cy50aHJvd3NNYXRjaCA9IHRocm93cy50aHJvd3NNYXRjaFxuXG5leHBvcnRzLmhhc093biA9IGhhcy5oYXNPd25cbmV4cG9ydHMubm90SGFzT3duID0gaGFzLm5vdEhhc093blxuZXhwb3J0cy5oYXNPd25Mb29zZSA9IGhhcy5oYXNPd25Mb29zZVxuZXhwb3J0cy5ub3RIYXNPd25Mb29zZSA9IGhhcy5ub3RIYXNPd25Mb29zZVxuZXhwb3J0cy5oYXNLZXkgPSBoYXMuaGFzS2V5XG5leHBvcnRzLm5vdEhhc0tleSA9IGhhcy5ub3RIYXNLZXlcbmV4cG9ydHMuaGFzS2V5TG9vc2UgPSBoYXMuaGFzS2V5TG9vc2VcbmV4cG9ydHMubm90SGFzS2V5TG9vc2UgPSBoYXMubm90SGFzS2V5TG9vc2VcbmV4cG9ydHMuaGFzID0gaGFzLmhhc1xuZXhwb3J0cy5ub3RIYXMgPSBoYXMubm90SGFzXG5leHBvcnRzLmhhc0xvb3NlID0gaGFzLmhhc0xvb3NlXG5leHBvcnRzLm5vdEhhc0xvb3NlID0gaGFzLm5vdEhhc0xvb3NlXG5cbi8qKlxuICogVGhlcmUncyAyIHNldHMgb2YgMTIgcGVybXV0YXRpb25zIGhlcmUgZm9yIGBpbmNsdWRlc2AgYW5kIGBoYXNLZXlzYCwgaW5zdGVhZFxuICogb2YgTiBzZXRzIG9mIDIgKHdoaWNoIHdvdWxkIGZpdCB0aGUgYGZvb2AvYG5vdEZvb2AgaWRpb20gYmV0dGVyKSwgc28gaXQnc1xuICogZWFzaWVyIHRvIGp1c3QgbWFrZSBhIGNvdXBsZSBzZXBhcmF0ZSBEU0xzIGFuZCB1c2UgdGhhdCB0byBkZWZpbmUgZXZlcnl0aGluZy5cbiAqXG4gKiBIZXJlJ3MgdGhlIHRvcCBsZXZlbDpcbiAqXG4gKiAtIHNoYWxsb3dcbiAqIC0gc3RyaWN0IGRlZXBcbiAqIC0gc3RydWN0dXJhbCBkZWVwXG4gKlxuICogQW5kIHRoZSBzZWNvbmQgbGV2ZWw6XG4gKlxuICogLSBpbmNsdWRlcyBhbGwvbm90IG1pc3Npbmcgc29tZVxuICogLSBpbmNsdWRlcyBzb21lL25vdCBtaXNzaW5nIGFsbFxuICogLSBub3QgaW5jbHVkaW5nIGFsbC9taXNzaW5nIHNvbWVcbiAqIC0gbm90IGluY2x1ZGluZyBzb21lL21pc3NpbmcgYWxsXG4gKlxuICogSGVyZSdzIGFuIGV4YW1wbGUgdXNpbmcgdGhlIG5hbWluZyBzY2hlbWUgZm9yIGBoYXNLZXlzKmBcbiAqXG4gKiAgICAgICAgICAgICAgIHwgICAgIHNoYWxsb3cgICAgIHwgICAgc3RyaWN0IGRlZXAgICAgICB8ICAgc3RydWN0dXJhbCBkZWVwXG4gKiAtLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogaW5jbHVkZXMgYWxsICB8IGBoYXNLZXlzYCAgICAgICB8IGBoYXNLZXlzRGVlcGAgICAgICAgfCBgaGFzS2V5c01hdGNoYFxuICogaW5jbHVkZXMgc29tZSB8IGBoYXNLZXlzQW55YCAgICB8IGBoYXNLZXlzQW55RGVlcGAgICAgfCBgaGFzS2V5c0FueU1hdGNoYFxuICogbWlzc2luZyBzb21lICB8IGBub3RIYXNLZXlzQWxsYCB8IGBub3RIYXNLZXlzQWxsRGVlcGAgfCBgbm90SGFzS2V5c0FsbE1hdGNoYFxuICogbWlzc2luZyBhbGwgICB8IGBub3RIYXNLZXlzYCAgICB8IGBub3RIYXNLZXlzRGVlcGAgICAgfCBgbm90SGFzS2V5c01hdGNoYFxuICpcbiAqIE5vdGUgdGhhdCB0aGUgYGhhc0tleXNgIHNoYWxsb3cgY29tcGFyaXNvbiB2YXJpYW50cyBhcmUgYWxzbyBvdmVybG9hZGVkIHRvXG4gKiBjb25zdW1lIGVpdGhlciBhbiBhcnJheSAoaW4gd2hpY2ggaXQgc2ltcGx5IGNoZWNrcyBhZ2FpbnN0IGEgbGlzdCBvZiBrZXlzKSBvclxuICogYW4gb2JqZWN0ICh3aGVyZSBpdCBkb2VzIGEgZnVsbCBkZWVwIGNvbXBhcmlzb24pLlxuICovXG5cbmV4cG9ydHMuaW5jbHVkZXMgPSBpbmNsdWRlcy5pbmNsdWRlc1xuZXhwb3J0cy5pbmNsdWRlc0RlZXAgPSBpbmNsdWRlcy5pbmNsdWRlc0RlZXBcbmV4cG9ydHMuaW5jbHVkZXNNYXRjaCA9IGluY2x1ZGVzLmluY2x1ZGVzTWF0Y2hcbmV4cG9ydHMuaW5jbHVkZXNBbnkgPSBpbmNsdWRlcy5pbmNsdWRlc0FueVxuZXhwb3J0cy5pbmNsdWRlc0FueURlZXAgPSBpbmNsdWRlcy5pbmNsdWRlc0FueURlZXBcbmV4cG9ydHMuaW5jbHVkZXNBbnlNYXRjaCA9IGluY2x1ZGVzLmluY2x1ZGVzQW55TWF0Y2hcbmV4cG9ydHMubm90SW5jbHVkZXNBbGwgPSBpbmNsdWRlcy5ub3RJbmNsdWRlc0FsbFxuZXhwb3J0cy5ub3RJbmNsdWRlc0FsbERlZXAgPSBpbmNsdWRlcy5ub3RJbmNsdWRlc0FsbERlZXBcbmV4cG9ydHMubm90SW5jbHVkZXNBbGxNYXRjaCA9IGluY2x1ZGVzLm5vdEluY2x1ZGVzQWxsTWF0Y2hcbmV4cG9ydHMubm90SW5jbHVkZXMgPSBpbmNsdWRlcy5ub3RJbmNsdWRlc1xuZXhwb3J0cy5ub3RJbmNsdWRlc0RlZXAgPSBpbmNsdWRlcy5ub3RJbmNsdWRlc0RlZXBcbmV4cG9ydHMubm90SW5jbHVkZXNNYXRjaCA9IGluY2x1ZGVzLm5vdEluY2x1ZGVzTWF0Y2hcblxuZXhwb3J0cy5oYXNLZXlzID0gaGFzS2V5cy5oYXNLZXlzXG5leHBvcnRzLmhhc0tleXNEZWVwID0gaGFzS2V5cy5oYXNLZXlzRGVlcFxuZXhwb3J0cy5oYXNLZXlzTWF0Y2ggPSBoYXNLZXlzLmhhc0tleXNNYXRjaFxuZXhwb3J0cy5oYXNLZXlzQW55ID0gaGFzS2V5cy5oYXNLZXlzQW55XG5leHBvcnRzLmhhc0tleXNBbnlEZWVwID0gaGFzS2V5cy5oYXNLZXlzQW55RGVlcFxuZXhwb3J0cy5oYXNLZXlzQW55TWF0Y2ggPSBoYXNLZXlzLmhhc0tleXNBbnlNYXRjaFxuZXhwb3J0cy5ub3RIYXNLZXlzQWxsID0gaGFzS2V5cy5ub3RIYXNLZXlzQWxsXG5leHBvcnRzLm5vdEhhc0tleXNBbGxEZWVwID0gaGFzS2V5cy5ub3RIYXNLZXlzQWxsRGVlcFxuZXhwb3J0cy5ub3RIYXNLZXlzQWxsTWF0Y2ggPSBoYXNLZXlzLm5vdEhhc0tleXNBbGxNYXRjaFxuZXhwb3J0cy5ub3RIYXNLZXlzID0gaGFzS2V5cy5ub3RIYXNLZXlzXG5leHBvcnRzLm5vdEhhc0tleXNEZWVwID0gaGFzS2V5cy5ub3RIYXNLZXlzRGVlcFxuZXhwb3J0cy5ub3RIYXNLZXlzTWF0Y2ggPSBoYXNLZXlzLm5vdEhhc0tleXNNYXRjaFxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIG1hdGNoID0gcmVxdWlyZShcImNsZWFuLW1hdGNoXCIpXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKVxuXG5mdW5jdGlvbiBiaW5hcnkobnVtZXJpYywgY29tcGFyYXRvciwgbWVzc2FnZSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoYWN0dWFsLCBleHBlY3RlZCkge1xuICAgICAgICBpZiAobnVtZXJpYykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBhY3R1YWwgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGFjdHVhbGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGV4cGVjdGVkICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBleHBlY3RlZGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFjb21wYXJhdG9yKGFjdHVhbCwgZXhwZWN0ZWQpKSB7XG4gICAgICAgICAgICB1dGlsLmZhaWwobWVzc2FnZSwge2FjdHVhbDogYWN0dWFsLCBleHBlY3RlZDogZXhwZWN0ZWR9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnRzLmVxdWFsID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiB1dGlsLnN0cmljdElzKGEsIGIpIH0sXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBlcXVhbCB7ZXhwZWN0ZWR9XCIpXG5cbmV4cG9ydHMubm90RXF1YWwgPSBiaW5hcnkoZmFsc2UsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuICF1dGlsLnN0cmljdElzKGEsIGIpIH0sXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgZXF1YWwge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLmVxdWFsTG9vc2UgPSBiaW5hcnkoZmFsc2UsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIHV0aWwubG9vc2VJcyhhLCBiKSB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbG9vc2VseSBlcXVhbCB7ZXhwZWN0ZWR9XCIpXG5cbmV4cG9ydHMubm90RXF1YWxMb29zZSA9IGJpbmFyeShmYWxzZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gIXV0aWwubG9vc2VJcyhhLCBiKSB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGxvb3NlbHkgZXF1YWwge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLmF0TGVhc3QgPSBiaW5hcnkodHJ1ZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYSA+PSBiIH0sXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhdCBsZWFzdCB7ZXhwZWN0ZWR9XCIpXG5cbmV4cG9ydHMuYXRNb3N0ID0gYmluYXJ5KHRydWUsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIGEgPD0gYiB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYXQgbW9zdCB7ZXhwZWN0ZWR9XCIpXG5cbmV4cG9ydHMuYWJvdmUgPSBiaW5hcnkodHJ1ZSxcbiAgICBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYSA+IGIgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGFib3ZlIHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5iZWxvdyA9IGJpbmFyeSh0cnVlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhIDwgYiB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYmVsb3cge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLmJldHdlZW4gPSBmdW5jdGlvbiAoYWN0dWFsLCBsb3dlciwgdXBwZXIpIHtcbiAgICBpZiAodHlwZW9mIGFjdHVhbCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGFjdHVhbGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbG93ZXIgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBsb3dlcmAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdXBwZXIgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImB1cHBlcmAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIC8vIFRoZSBuZWdhdGlvbiBpcyB0byBhZGRyZXNzIE5hTnMgYXMgd2VsbCwgd2l0aG91dCB3cml0aW5nIGEgdG9uIG9mIHNwZWNpYWxcbiAgICAvLyBjYXNlIGJvaWxlcnBsYXRlXG4gICAgaWYgKCEoYWN0dWFsID49IGxvd2VyICYmIGFjdHVhbCA8PSB1cHBlcikpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYmV0d2VlbiB7bG93ZXJ9IGFuZCB7dXBwZXJ9XCIsIHtcbiAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuICAgICAgICAgICAgbG93ZXI6IGxvd2VyLFxuICAgICAgICAgICAgdXBwZXI6IHVwcGVyLFxuICAgICAgICB9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5kZWVwRXF1YWwgPSBiaW5hcnkoZmFsc2UsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuIG1hdGNoLnN0cmljdChhLCBiKSB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gZGVlcGx5IGVxdWFsIHtleHBlY3RlZH1cIilcblxuZXhwb3J0cy5ub3REZWVwRXF1YWwgPSBiaW5hcnkoZmFsc2UsXG4gICAgZnVuY3Rpb24gKGEsIGIpIHsgcmV0dXJuICFtYXRjaC5zdHJpY3QoYSwgYikgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBkZWVwbHkgZXF1YWwge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLm1hdGNoID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBtYXRjaC5sb29zZShhLCBiKSB9LFxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbWF0Y2gge2V4cGVjdGVkfVwiKVxuXG5leHBvcnRzLm5vdE1hdGNoID0gYmluYXJ5KGZhbHNlLFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiAhbWF0Y2gubG9vc2UoYSwgYikgfSxcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCB7ZXhwZWN0ZWR9XCIpXG5cbi8vIFVzZXMgZGl2aXNpb24gdG8gYWxsb3cgZm9yIGEgbW9yZSByb2J1c3QgY29tcGFyaXNvbiBvZiBmbG9hdHMuIEFsc28sIHRoaXNcbi8vIGhhbmRsZXMgbmVhci16ZXJvIGNvbXBhcmlzb25zIGNvcnJlY3RseSwgYXMgd2VsbCBhcyBhIHplcm8gdG9sZXJhbmNlIChpLmUuXG4vLyBleGFjdCBjb21wYXJpc29uKS5cbmZ1bmN0aW9uIGNsb3NlVG8oZXhwZWN0ZWQsIGFjdHVhbCwgdG9sZXJhbmNlKSB7XG4gICAgaWYgKHRvbGVyYW5jZSA9PT0gSW5maW5pdHkgfHwgYWN0dWFsID09PSBleHBlY3RlZCkgcmV0dXJuIHRydWVcbiAgICBpZiAodG9sZXJhbmNlID09PSAwKSByZXR1cm4gZmFsc2VcbiAgICBpZiAoYWN0dWFsID09PSAwKSByZXR1cm4gTWF0aC5hYnMoZXhwZWN0ZWQpIDwgdG9sZXJhbmNlXG4gICAgaWYgKGV4cGVjdGVkID09PSAwKSByZXR1cm4gTWF0aC5hYnMoYWN0dWFsKSA8IHRvbGVyYW5jZVxuICAgIHJldHVybiBNYXRoLmFicyhleHBlY3RlZCAvIGFjdHVhbCAtIDEpIDwgdG9sZXJhbmNlXG59XG5cbi8vIE5vdGU6IHRoZXNlIHR3byBhbHdheXMgZmFpbCB3aGVuIGRlYWxpbmcgd2l0aCBOYU5zLlxuZXhwb3J0cy5jbG9zZVRvID0gZnVuY3Rpb24gKGV4cGVjdGVkLCBhY3R1YWwsIHRvbGVyYW5jZSkge1xuICAgIGlmICh0eXBlb2YgYWN0dWFsICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgYWN0dWFsYCBtdXN0IGJlIGEgbnVtYmVyXCIpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBleHBlY3RlZCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGV4cGVjdGVkYCBtdXN0IGJlIGEgbnVtYmVyXCIpXG4gICAgfVxuXG4gICAgaWYgKHRvbGVyYW5jZSA9PSBudWxsKSB0b2xlcmFuY2UgPSAxZS0xMFxuXG4gICAgaWYgKHR5cGVvZiB0b2xlcmFuY2UgIT09IFwibnVtYmVyXCIgfHwgdG9sZXJhbmNlIDwgMCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgICAgXCJgdG9sZXJhbmNlYCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIG51bWJlciBpZiBnaXZlblwiKVxuICAgIH1cblxuICAgIGlmIChhY3R1YWwgIT09IGFjdHVhbCB8fCBleHBlY3RlZCAhPT0gZXhwZWN0ZWQgfHwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zZWxmLWNvbXBhcmUsIG1heC1sZW5cbiAgICAgICAgICAgICFjbG9zZVRvKGV4cGVjdGVkLCBhY3R1YWwsIHRvbGVyYW5jZSkpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgY2xvc2UgdG8ge2V4cGVjdGVkfVwiLCB7XG4gICAgICAgICAgICBhY3R1YWw6IGFjdHVhbCxcbiAgICAgICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZCxcbiAgICAgICAgfSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90Q2xvc2VUbyA9IGZ1bmN0aW9uIChleHBlY3RlZCwgYWN0dWFsLCB0b2xlcmFuY2UpIHtcbiAgICBpZiAodHlwZW9mIGFjdHVhbCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGFjdHVhbGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZXhwZWN0ZWQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBleHBlY3RlZGAgbXVzdCBiZSBhIG51bWJlclwiKVxuICAgIH1cblxuICAgIGlmICh0b2xlcmFuY2UgPT0gbnVsbCkgdG9sZXJhbmNlID0gMWUtMTBcblxuICAgIGlmICh0eXBlb2YgdG9sZXJhbmNlICE9PSBcIm51bWJlclwiIHx8IHRvbGVyYW5jZSA8IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICAgIFwiYHRvbGVyYW5jZWAgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIgaWYgZ2l2ZW5cIilcbiAgICB9XG5cbiAgICBpZiAoZXhwZWN0ZWQgIT09IGV4cGVjdGVkIHx8IGFjdHVhbCAhPT0gYWN0dWFsIHx8IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlLCBtYXgtbGVuXG4gICAgICAgICAgICBjbG9zZVRvKGV4cGVjdGVkLCBhY3R1YWwsIHRvbGVyYW5jZSkpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGJlIGNsb3NlIHRvIHtleHBlY3RlZH1cIiwge1xuICAgICAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgICAgICAgICBleHBlY3RlZDogZXhwZWN0ZWQsXG4gICAgICAgIH0pXG4gICAgfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIG1hdGNoID0gcmVxdWlyZShcImNsZWFuLW1hdGNoXCIpXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKVxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuZnVuY3Rpb24gaGFzS2V5cyhhbGwsIG9iamVjdCwga2V5cykge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgdGVzdCA9IGhhc093bi5jYWxsKG9iamVjdCwga2V5c1tpXSlcblxuICAgICAgICBpZiAodGVzdCAhPT0gYWxsKSByZXR1cm4gIWFsbFxuICAgIH1cblxuICAgIHJldHVybiBhbGxcbn1cblxuZnVuY3Rpb24gaGFzVmFsdWVzKGZ1bmMsIGFsbCwgb2JqZWN0LCBrZXlzKSB7XG4gICAgaWYgKG9iamVjdCA9PT0ga2V5cykgcmV0dXJuIHRydWVcbiAgICB2YXIgbGlzdCA9IE9iamVjdC5rZXlzKGtleXMpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGtleSA9IGxpc3RbaV1cbiAgICAgICAgdmFyIHRlc3QgPSBoYXNPd24uY2FsbChvYmplY3QsIGtleSkgJiYgZnVuYyhrZXlzW2tleV0sIG9iamVjdFtrZXldKVxuXG4gICAgICAgIGlmICh0ZXN0ICE9PSBhbGwpIHJldHVybiB0ZXN0XG4gICAgfVxuXG4gICAgcmV0dXJuIGFsbFxufVxuXG5mdW5jdGlvbiBtYWtlSGFzT3ZlcmxvYWQoYWxsLCBpbnZlcnQsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCwga2V5cykge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdCAhPT0gXCJvYmplY3RcIiB8fCBvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBvYmplY3RgIG11c3QgYmUgYW4gb2JqZWN0XCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGtleXMgIT09IFwib2JqZWN0XCIgfHwga2V5cyA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGtleXNgIG11c3QgYmUgYW4gb2JqZWN0IG9yIGFycmF5XCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShrZXlzKSkge1xuICAgICAgICAgICAgaWYgKGtleXMubGVuZ3RoICYmIGhhc0tleXMoYWxsLCBvYmplY3QsIGtleXMpID09PSBpbnZlcnQpIHtcbiAgICAgICAgICAgICAgICB1dGlsLmZhaWwobWVzc2FnZSwge2FjdHVhbDogb2JqZWN0LCBrZXlzOiBrZXlzfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChPYmplY3Qua2V5cyhrZXlzKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChoYXNWYWx1ZXModXRpbC5zdHJpY3RJcywgYWxsLCBvYmplY3QsIGtleXMpID09PSBpbnZlcnQpIHtcbiAgICAgICAgICAgICAgICB1dGlsLmZhaWwobWVzc2FnZSwge2FjdHVhbDogb2JqZWN0LCBrZXlzOiBrZXlzfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gbWFrZUhhc0tleXMoZnVuYywgYWxsLCBpbnZlcnQsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCwga2V5cykge1xuICAgICAgICBpZiAodHlwZW9mIG9iamVjdCAhPT0gXCJvYmplY3RcIiB8fCBvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBvYmplY3RgIG11c3QgYmUgYW4gb2JqZWN0XCIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGtleXMgIT09IFwib2JqZWN0XCIgfHwga2V5cyA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGtleXNgIG11c3QgYmUgYW4gb2JqZWN0XCIpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBleGNsdXNpdmUgb3IgdG8gaW52ZXJ0IHRoZSByZXN1bHQgaWYgYGludmVydGAgaXMgdHJ1ZVxuICAgICAgICBpZiAoT2JqZWN0LmtleXMoa2V5cykubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAoaGFzVmFsdWVzKGZ1bmMsIGFsbCwgb2JqZWN0LCBrZXlzKSA9PT0gaW52ZXJ0KSB7XG4gICAgICAgICAgICAgICAgdXRpbC5mYWlsKG1lc3NhZ2UsIHthY3R1YWw6IG9iamVjdCwga2V5czoga2V5c30pXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qIGVzbGludC1kaXNhYmxlIG1heC1sZW4gKi9cblxuZXhwb3J0cy5oYXNLZXlzID0gbWFrZUhhc092ZXJsb2FkKHRydWUsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUgYWxsIGtleXMgaW4ge2tleXN9XCIpXG5leHBvcnRzLmhhc0tleXNEZWVwID0gbWFrZUhhc0tleXMobWF0Y2guc3RyaWN0LCB0cnVlLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxuZXhwb3J0cy5oYXNLZXlzTWF0Y2ggPSBtYWtlSGFzS2V5cyhtYXRjaC5sb29zZSwgdHJ1ZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbWF0Y2ggYWxsIGtleXMgaW4ge2tleXN9XCIpXG5leHBvcnRzLmhhc0tleXNBbnkgPSBtYWtlSGFzT3ZlcmxvYWQoZmFsc2UsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGhhdmUgYW55IGtleSBpbiB7a2V5c31cIilcbmV4cG9ydHMuaGFzS2V5c0FueURlZXAgPSBtYWtlSGFzS2V5cyhtYXRjaC5zdHJpY3QsIGZhbHNlLCBmYWxzZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGFueSBrZXkgaW4ge2tleXN9XCIpXG5leHBvcnRzLmhhc0tleXNBbnlNYXRjaCA9IG1ha2VIYXNLZXlzKG1hdGNoLmxvb3NlLCBmYWxzZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbWF0Y2ggYW55IGtleSBpbiB7a2V5c31cIilcbmV4cG9ydHMubm90SGFzS2V5c0FsbCA9IG1ha2VIYXNPdmVybG9hZCh0cnVlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxuZXhwb3J0cy5ub3RIYXNLZXlzQWxsRGVlcCA9IG1ha2VIYXNLZXlzKG1hdGNoLnN0cmljdCwgdHJ1ZSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBhbGwga2V5cyBpbiB7a2V5c31cIilcbmV4cG9ydHMubm90SGFzS2V5c0FsbE1hdGNoID0gbWFrZUhhc0tleXMobWF0Y2gubG9vc2UsIHRydWUsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IG1hdGNoIGFsbCBrZXlzIGluIHtrZXlzfVwiKVxuZXhwb3J0cy5ub3RIYXNLZXlzID0gbWFrZUhhc092ZXJsb2FkKGZhbHNlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGFueSBrZXkgaW4ge2tleXN9XCIpXG5leHBvcnRzLm5vdEhhc0tleXNEZWVwID0gbWFrZUhhc0tleXMobWF0Y2guc3RyaWN0LCBmYWxzZSwgdHJ1ZSwgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBhbnkga2V5IGluIHtrZXlzfVwiKVxuZXhwb3J0cy5ub3RIYXNLZXlzTWF0Y2ggPSBtYWtlSGFzS2V5cyhtYXRjaC5sb29zZSwgZmFsc2UsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IG1hdGNoIGFueSBrZXkgaW4ge2tleXN9XCIpXG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKVxudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcblxuZnVuY3Rpb24gaGFzKF8pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuLCBtYXgtcGFyYW1zXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykge1xuICAgICAgICAgICAgaWYgKCFfLmhhcyhvYmplY3QsIGtleSkgfHxcbiAgICAgICAgICAgICAgICAgICAgIXV0aWwuc3RyaWN0SXMoXy5nZXQob2JqZWN0LCBrZXkpLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB1dGlsLmZhaWwoXy5tZXNzYWdlc1swXSwge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0W2tleV0sXG4gICAgICAgICAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCFfLmhhcyhvYmplY3QsIGtleSkpIHtcbiAgICAgICAgICAgIHV0aWwuZmFpbChfLm1lc3NhZ2VzWzFdLCB7XG4gICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IHZhbHVlLFxuICAgICAgICAgICAgICAgIGFjdHVhbDogb2JqZWN0W2tleV0sXG4gICAgICAgICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgICAgICAgb2JqZWN0OiBvYmplY3QsXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBoYXNMb29zZShfKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKCFfLmhhcyhvYmplY3QsIGtleSkgfHwgIXV0aWwubG9vc2VJcyhfLmdldChvYmplY3QsIGtleSksIHZhbHVlKSkge1xuICAgICAgICAgICAgdXRpbC5mYWlsKF8ubWVzc2FnZXNbMF0sIHtcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogdmFsdWUsXG4gICAgICAgICAgICAgICAgYWN0dWFsOiBvYmplY3Rba2V5XSxcbiAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIG5vdEhhcyhfKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlbiwgbWF4LXBhcmFtc1xuICAgIHJldHVybiBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIHtcbiAgICAgICAgICAgIGlmIChfLmhhcyhvYmplY3QsIGtleSkgJiZcbiAgICAgICAgICAgICAgICAgICAgdXRpbC5zdHJpY3RJcyhfLmdldChvYmplY3QsIGtleSksIHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHV0aWwuZmFpbChfLm1lc3NhZ2VzWzJdLCB7XG4gICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgYWN0dWFsOiBvYmplY3Rba2V5XSxcbiAgICAgICAgICAgICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgICAgICAgICAgIG9iamVjdDogb2JqZWN0LFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoXy5oYXMob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgICAgICB1dGlsLmZhaWwoXy5tZXNzYWdlc1szXSwge1xuICAgICAgICAgICAgICAgIGV4cGVjdGVkOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICBhY3R1YWw6IG9iamVjdFtrZXldLFxuICAgICAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgICAgIG9iamVjdDogb2JqZWN0LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gbm90SGFzTG9vc2UoXykgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1sZW4sIG1heC1wYXJhbXNcbiAgICByZXR1cm4gZnVuY3Rpb24gKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICAgICAgICBpZiAoXy5oYXMob2JqZWN0LCBrZXkpICYmIHV0aWwubG9vc2VJcyhfLmdldChvYmplY3QsIGtleSksIHZhbHVlKSkge1xuICAgICAgICAgICAgdXRpbC5mYWlsKF8ubWVzc2FnZXNbMl0sIHtcbiAgICAgICAgICAgICAgICBleHBlY3RlZDogdmFsdWUsXG4gICAgICAgICAgICAgICAgYWN0dWFsOiBvYmplY3Rba2V5XSxcbiAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGhhc093bktleShvYmplY3QsIGtleSkgeyByZXR1cm4gaGFzT3duLmNhbGwob2JqZWN0LCBrZXkpIH1cbmZ1bmN0aW9uIGhhc0luS2V5KG9iamVjdCwga2V5KSB7IHJldHVybiBrZXkgaW4gb2JqZWN0IH1cbmZ1bmN0aW9uIGhhc0luQ29sbChvYmplY3QsIGtleSkgeyByZXR1cm4gb2JqZWN0LmhhcyhrZXkpIH1cbmZ1bmN0aW9uIGhhc09iamVjdEdldChvYmplY3QsIGtleSkgeyByZXR1cm4gb2JqZWN0W2tleV0gfVxuZnVuY3Rpb24gaGFzQ29sbEdldChvYmplY3QsIGtleSkgeyByZXR1cm4gb2JqZWN0LmdldChrZXkpIH1cblxuZnVuY3Rpb24gY3JlYXRlSGFzKGhhcywgZ2V0LCBtZXNzYWdlcykge1xuICAgIHJldHVybiB7aGFzOiBoYXMsIGdldDogZ2V0LCBtZXNzYWdlczogbWVzc2FnZXN9XG59XG5cbnZhciBoYXNPd25NZXRob2RzID0gY3JlYXRlSGFzKGhhc093bktleSwgaGFzT2JqZWN0R2V0LCBbXG4gICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBoYXZlIG93biBrZXkge2tleX0gZXF1YWwgdG8ge2V4cGVjdGVkfSwgYnV0IGZvdW5kIHthY3R1YWx9XCIsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBvd24ga2V5IHtleHBlY3RlZH1cIixcbiAgICBcIkV4cGVjdGVkIHtvYmplY3R9IHRvIG5vdCBoYXZlIG93biBrZXkge2tleX0gZXF1YWwgdG8ge2FjdHVhbH1cIixcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIG93biBrZXkge2V4cGVjdGVkfVwiLFxuXSlcblxudmFyIGhhc0tleU1ldGhvZHMgPSBjcmVhdGVIYXMoaGFzSW5LZXksIGhhc09iamVjdEdldCwgW1xuICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gaGF2ZSBrZXkge2tleX0gZXF1YWwgdG8ge2V4cGVjdGVkfSwgYnV0IGZvdW5kIHthY3R1YWx9XCIsIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LWxlblxuICAgIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBrZXkge2V4cGVjdGVkfVwiLFxuICAgIFwiRXhwZWN0ZWQge29iamVjdH0gdG8gbm90IGhhdmUga2V5IHtrZXl9IGVxdWFsIHRvIHthY3R1YWx9XCIsXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgaGF2ZSBrZXkge2V4cGVjdGVkfVwiLFxuXSlcblxudmFyIGhhc01ldGhvZHMgPSBjcmVhdGVIYXMoaGFzSW5Db2xsLCBoYXNDb2xsR2V0LCBbXG4gICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBoYXZlIGtleSB7a2V5fSBlcXVhbCB0byB7ZXhwZWN0ZWR9LCBidXQgZm91bmQge2FjdHVhbH1cIiwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtbGVuXG4gICAgXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBoYXZlIGtleSB7ZXhwZWN0ZWR9XCIsXG4gICAgXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBub3QgaGF2ZSBrZXkge2tleX0gZXF1YWwgdG8ge2FjdHVhbH1cIixcbiAgICBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBoYXZlIGtleSB7ZXhwZWN0ZWR9XCIsXG5dKVxuXG5leHBvcnRzLmhhc093biA9IGhhcyhoYXNPd25NZXRob2RzKVxuZXhwb3J0cy5ub3RIYXNPd24gPSBub3RIYXMoaGFzT3duTWV0aG9kcylcbmV4cG9ydHMuaGFzT3duTG9vc2UgPSBoYXNMb29zZShoYXNPd25NZXRob2RzKVxuZXhwb3J0cy5ub3RIYXNPd25Mb29zZSA9IG5vdEhhc0xvb3NlKGhhc093bk1ldGhvZHMpXG5cbmV4cG9ydHMuaGFzS2V5ID0gaGFzKGhhc0tleU1ldGhvZHMpXG5leHBvcnRzLm5vdEhhc0tleSA9IG5vdEhhcyhoYXNLZXlNZXRob2RzKVxuZXhwb3J0cy5oYXNLZXlMb29zZSA9IGhhc0xvb3NlKGhhc0tleU1ldGhvZHMpXG5leHBvcnRzLm5vdEhhc0tleUxvb3NlID0gbm90SGFzTG9vc2UoaGFzS2V5TWV0aG9kcylcblxuZXhwb3J0cy5oYXMgPSBoYXMoaGFzTWV0aG9kcylcbmV4cG9ydHMubm90SGFzID0gbm90SGFzKGhhc01ldGhvZHMpXG5leHBvcnRzLmhhc0xvb3NlID0gaGFzTG9vc2UoaGFzTWV0aG9kcylcbmV4cG9ydHMubm90SGFzTG9vc2UgPSBub3RIYXNMb29zZShoYXNNZXRob2RzKVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxudmFyIG1hdGNoID0gcmVxdWlyZShcImNsZWFuLW1hdGNoXCIpXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKVxuXG5mdW5jdGlvbiBpbmNsdWRlcyhmdW5jLCBhbGwsIGFycmF5LCB2YWx1ZXMpIHtcbiAgICAvLyBDaGVhcCBjYXNlcyBmaXJzdFxuICAgIGlmICghQXJyYXkuaXNBcnJheShhcnJheSkpIHJldHVybiBmYWxzZVxuICAgIGlmIChhcnJheSA9PT0gdmFsdWVzKSByZXR1cm4gdHJ1ZVxuICAgIGlmIChhbGwgJiYgYXJyYXkubGVuZ3RoIDwgdmFsdWVzLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgdmFsdWUgPSB2YWx1ZXNbaV1cbiAgICAgICAgdmFyIHRlc3QgPSBmYWxzZVxuXG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgYXJyYXkubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGlmIChmdW5jKHZhbHVlLCBhcnJheVtqXSkpIHtcbiAgICAgICAgICAgICAgICB0ZXN0ID0gdHJ1ZVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGVzdCAhPT0gYWxsKSByZXR1cm4gdGVzdFxuICAgIH1cblxuICAgIHJldHVybiBhbGxcbn1cblxuZnVuY3Rpb24gZGVmaW5lSW5jbHVkZXMoZnVuYywgYWxsLCBpbnZlcnQsIG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKGFycmF5LCB2YWx1ZXMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFycmF5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBhcnJheWAgbXVzdCBiZSBhbiBhcnJheVwiKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlcykpIHZhbHVlcyA9IFt2YWx1ZXNdXG5cbiAgICAgICAgaWYgKHZhbHVlcy5sZW5ndGggJiYgaW5jbHVkZXMoZnVuYywgYWxsLCBhcnJheSwgdmFsdWVzKSA9PT0gaW52ZXJ0KSB7XG4gICAgICAgICAgICB1dGlsLmZhaWwobWVzc2FnZSwge2FjdHVhbDogYXJyYXksIHZhbHVlczogdmFsdWVzfSlcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuXG5leHBvcnRzLmluY2x1ZGVzID0gZGVmaW5lSW5jbHVkZXModXRpbC5zdHJpY3RJcywgdHJ1ZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBhbGwgdmFsdWVzIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLmluY2x1ZGVzRGVlcCA9IGRlZmluZUluY2x1ZGVzKG1hdGNoLnN0cmljdCwgdHJ1ZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbWF0Y2ggYWxsIHZhbHVlcyBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5pbmNsdWRlc01hdGNoID0gZGVmaW5lSW5jbHVkZXMobWF0Y2gubG9vc2UsIHRydWUsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFsbCB2YWx1ZXMgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMuaW5jbHVkZXNBbnkgPSBkZWZpbmVJbmNsdWRlcyh1dGlsLnN0cmljdElzLCBmYWxzZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gaGF2ZSBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMuaW5jbHVkZXNBbnlEZWVwID0gZGVmaW5lSW5jbHVkZXMobWF0Y2guc3RyaWN0LCBmYWxzZSwgZmFsc2UsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbWF0Y2ggYW55IHZhbHVlIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLmluY2x1ZGVzQW55TWF0Y2ggPSBkZWZpbmVJbmNsdWRlcyhtYXRjaC5sb29zZSwgZmFsc2UsIGZhbHNlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG1hdGNoIGFueSB2YWx1ZSBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5ub3RJbmNsdWRlc0FsbCA9IGRlZmluZUluY2x1ZGVzKHV0aWwuc3RyaWN0SXMsIHRydWUsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUgYWxsIHZhbHVlcyBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5ub3RJbmNsdWRlc0FsbERlZXAgPSBkZWZpbmVJbmNsdWRlcyhtYXRjaC5zdHJpY3QsIHRydWUsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IG1hdGNoIGFsbCB2YWx1ZXMgaW4ge3ZhbHVlc31cIilcbmV4cG9ydHMubm90SW5jbHVkZXNBbGxNYXRjaCA9IGRlZmluZUluY2x1ZGVzKG1hdGNoLmxvb3NlLCB0cnVlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbGwgdmFsdWVzIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLm5vdEluY2x1ZGVzID0gZGVmaW5lSW5jbHVkZXModXRpbC5zdHJpY3RJcywgZmFsc2UsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGhhdmUgYW55IHZhbHVlIGluIHt2YWx1ZXN9XCIpXG5leHBvcnRzLm5vdEluY2x1ZGVzRGVlcCA9IGRlZmluZUluY2x1ZGVzKG1hdGNoLnN0cmljdCwgZmFsc2UsIHRydWUsIFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IG1hdGNoIGFueSB2YWx1ZSBpbiB7dmFsdWVzfVwiKVxuZXhwb3J0cy5ub3RJbmNsdWRlc01hdGNoID0gZGVmaW5lSW5jbHVkZXMobWF0Y2gubG9vc2UsIGZhbHNlLCB0cnVlLCBcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBtYXRjaCBhbnkgdmFsdWUgaW4ge3ZhbHVlc31cIilcbiIsIlwidXNlIHN0cmljdFwiXG5cbnZhciB1dGlsID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpXG5cbmZ1bmN0aW9uIGdldE5hbWUoZnVuYykge1xuICAgIHZhciBuYW1lID0gZnVuYy5uYW1lXG5cbiAgICBpZiAobmFtZSA9PSBudWxsKSBuYW1lID0gZnVuYy5kaXNwbGF5TmFtZVxuICAgIGlmIChuYW1lKSByZXR1cm4gdXRpbC5lc2NhcGUobmFtZSlcbiAgICByZXR1cm4gXCI8YW5vbnltb3VzPlwiXG59XG5cbmV4cG9ydHMudGhyb3dzID0gZnVuY3Rpb24gKFR5cGUsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGNhbGxiYWNrID09IG51bGwpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBUeXBlXG4gICAgICAgIFR5cGUgPSBudWxsXG4gICAgfVxuXG4gICAgaWYgKFR5cGUgIT0gbnVsbCAmJiB0eXBlb2YgVHlwZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgVHlwZWAgbXVzdCBiZSBhIGZ1bmN0aW9uIGlmIHBhc3NlZFwiKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYGNhbGxiYWNrYCBtdXN0IGJlIGEgZnVuY3Rpb25cIilcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICBjYWxsYmFjaygpIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgY2FsbGJhY2stcmV0dXJuXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoVHlwZSAhPSBudWxsICYmICEoZSBpbnN0YW5jZW9mIFR5cGUpKSB7XG4gICAgICAgICAgICB1dGlsLmZhaWwoXG4gICAgICAgICAgICAgICAgXCJFeHBlY3RlZCBjYWxsYmFjayB0byB0aHJvdyBhbiBpbnN0YW5jZSBvZiBcIiArIGdldE5hbWUoVHlwZSkgK1xuICAgICAgICAgICAgICAgIFwiLCBidXQgZm91bmQge2FjdHVhbH1cIixcbiAgICAgICAgICAgICAgICB7YWN0dWFsOiBlfSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgdXRpbC5Bc3NlcnRpb25FcnJvcihcIkV4cGVjdGVkIGNhbGxiYWNrIHRvIHRocm93XCIpXG59XG5cbmZ1bmN0aW9uIHRocm93c01hdGNoVGVzdChtYXRjaGVyLCBlKSB7XG4gICAgaWYgKHR5cGVvZiBtYXRjaGVyID09PSBcInN0cmluZ1wiKSByZXR1cm4gZS5tZXNzYWdlID09PSBtYXRjaGVyXG4gICAgaWYgKHR5cGVvZiBtYXRjaGVyID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiAhIW1hdGNoZXIoZSlcbiAgICBpZiAobWF0Y2hlciBpbnN0YW5jZW9mIFJlZ0V4cCkgcmV0dXJuICEhbWF0Y2hlci50ZXN0KGUubWVzc2FnZSlcblxuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMobWF0Y2hlcilcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIga2V5ID0ga2V5c1tpXVxuXG4gICAgICAgIGlmICghKGtleSBpbiBlKSB8fCAhdXRpbC5zdHJpY3RJcyhtYXRjaGVyW2tleV0sIGVba2V5XSkpIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG59XG5cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3Qob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCA9PSBudWxsIHx8IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpID09PSBPYmplY3QucHJvdG90eXBlXG59XG5cbmV4cG9ydHMudGhyb3dzTWF0Y2ggPSBmdW5jdGlvbiAobWF0Y2hlciwgY2FsbGJhY2spIHtcbiAgICBpZiAodHlwZW9mIG1hdGNoZXIgIT09IFwic3RyaW5nXCIgJiZcbiAgICAgICAgICAgIHR5cGVvZiBtYXRjaGVyICE9PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgICAgICEobWF0Y2hlciBpbnN0YW5jZW9mIFJlZ0V4cCkgJiZcbiAgICAgICAgICAgICFpc1BsYWluT2JqZWN0KG1hdGNoZXIpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICBcImBtYXRjaGVyYCBtdXN0IGJlIGEgc3RyaW5nLCBmdW5jdGlvbiwgUmVnRXhwLCBvciBvYmplY3RcIilcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBjYWxsYmFja2AgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICAgY2FsbGJhY2soKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGNhbGxiYWNrLXJldHVyblxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKCF0aHJvd3NNYXRjaFRlc3QobWF0Y2hlciwgZSkpIHtcbiAgICAgICAgICAgIHV0aWwuZmFpbChcbiAgICAgICAgICAgICAgICBcIkV4cGVjdGVkIGNhbGxiYWNrIHRvICB0aHJvdyBhbiBlcnJvciB0aGF0IG1hdGNoZXMgXCIgK1xuICAgICAgICAgICAgICAgIFwie2V4cGVjdGVkfSwgYnV0IGZvdW5kIHthY3R1YWx9XCIsXG4gICAgICAgICAgICAgICAge2V4cGVjdGVkOiBtYXRjaGVyLCBhY3R1YWw6IGV9KVxuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRocm93IG5ldyB1dGlsLkFzc2VydGlvbkVycm9yKFwiRXhwZWN0ZWQgY2FsbGJhY2sgdG8gdGhyb3cuXCIpXG59XG4iLCJcInVzZSBzdHJpY3RcIlxuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCJjbGVhbi1hc3NlcnQtdXRpbFwiKVxuXG5leHBvcnRzLm9rID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAoIXgpIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIHRydXRoeVwiLCB7YWN0dWFsOiB4fSlcbn1cblxuZXhwb3J0cy5ub3RPayA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHgpIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGZhbHN5XCIsIHthY3R1YWw6IHh9KVxufVxuXG5leHBvcnRzLmlzQm9vbGVhbiA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSBcImJvb2xlYW5cIikge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhIGJvb2xlYW5cIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdEJvb2xlYW4gPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCA9PT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGJlIGEgYm9vbGVhblwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYSBmdW5jdGlvblwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90RnVuY3Rpb24gPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBhIGZ1bmN0aW9uXCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5pc051bWJlciA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGEgbnVtYmVyXCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5ub3ROdW1iZXIgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgYmUgYSBudW1iZXJcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLmlzT2JqZWN0ID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggIT09IFwib2JqZWN0XCIgfHwgeCA9PSBudWxsKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIGJlIGFuIG9iamVjdFwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90T2JqZWN0ID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggPT09IFwib2JqZWN0XCIgJiYgeCAhPSBudWxsKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBhbiBvYmplY3RcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLmlzU3RyaW5nID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gYmUgYSBzdHJpbmdcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdFN0cmluZyA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHR5cGVvZiB4ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBhIHN0cmluZ1wiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMuaXNTeW1ib2wgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh0eXBlb2YgeCAhPT0gXCJzeW1ib2xcIikge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhIHN5bWJvbFwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90U3ltYm9sID0gZnVuY3Rpb24gKHgpIHtcbiAgICBpZiAodHlwZW9mIHggPT09IFwic3ltYm9sXCIpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gbm90IGJlIGEgc3ltYm9sXCIsIHthY3R1YWw6IHh9KVxuICAgIH1cbn1cblxuZXhwb3J0cy5leGlzdHMgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICh4ID09IG51bGwpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge2FjdHVhbH0gdG8gZXhpc3RcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLm5vdEV4aXN0cyA9IGZ1bmN0aW9uICh4KSB7XG4gICAgaWYgKHggIT0gbnVsbCkge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBub3QgZXhpc3RcIiwge2FjdHVhbDogeH0pXG4gICAgfVxufVxuXG5leHBvcnRzLmlzQXJyYXkgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmICghQXJyYXkuaXNBcnJheSh4KSkge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7YWN0dWFsfSB0byBiZSBhbiBhcnJheVwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90QXJyYXkgPSBmdW5jdGlvbiAoeCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHgpKSB7XG4gICAgICAgIHV0aWwuZmFpbChcIkV4cGVjdGVkIHthY3R1YWx9IHRvIG5vdCBiZSBhbiBhcnJheVwiLCB7YWN0dWFsOiB4fSlcbiAgICB9XG59XG5cbmV4cG9ydHMuaXMgPSBmdW5jdGlvbiAoVHlwZSwgb2JqZWN0KSB7XG4gICAgaWYgKHR5cGVvZiBUeXBlICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImBUeXBlYCBtdXN0IGJlIGEgZnVuY3Rpb25cIilcbiAgICB9XG5cbiAgICBpZiAoIShvYmplY3QgaW5zdGFuY2VvZiBUeXBlKSkge1xuICAgICAgICB1dGlsLmZhaWwoXCJFeHBlY3RlZCB7b2JqZWN0fSB0byBiZSBhbiBpbnN0YW5jZSBvZiB7ZXhwZWN0ZWR9XCIsIHtcbiAgICAgICAgICAgIGV4cGVjdGVkOiBUeXBlLFxuICAgICAgICAgICAgYWN0dWFsOiBvYmplY3QuY29uc3RydWN0b3IsXG4gICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgfSlcbiAgICB9XG59XG5cbmV4cG9ydHMubm90ID0gZnVuY3Rpb24gKFR5cGUsIG9iamVjdCkge1xuICAgIGlmICh0eXBlb2YgVHlwZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJgVHlwZWAgbXVzdCBiZSBhIGZ1bmN0aW9uXCIpXG4gICAgfVxuXG4gICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIFR5cGUpIHtcbiAgICAgICAgdXRpbC5mYWlsKFwiRXhwZWN0ZWQge29iamVjdH0gdG8gbm90IGJlIGFuIGluc3RhbmNlIG9mIHtleHBlY3RlZH1cIiwge1xuICAgICAgICAgICAgZXhwZWN0ZWQ6IFR5cGUsXG4gICAgICAgICAgICBvYmplY3Q6IG9iamVjdCxcbiAgICAgICAgfSlcbiAgICB9XG59XG4iLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBjbGVhbi1tYXRjaFxuICpcbiAqIEEgc2ltcGxlLCBmYXN0IEVTMjAxNSsgYXdhcmUgZGVlcCBtYXRjaGluZyB1dGlsaXR5LlxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxNiBhbmQgbGF0ZXIsIElzaWFoIE1lYWRvd3MgPG1lQGlzaWFobWVhZG93cy5jb20+LlxuICpcbiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxuICogcHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZVxuICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcy5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXG4gKiBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcbiAqIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcbiAqIElORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxuICogTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcbiAqIE9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcbiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXG4gKi9cblxuLyogZXNsaW50LWRpc2FibGUgKi9cbjsoZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuICAgIGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gXCJvYmplY3RcIiAmJiBleHBvcnRzICE9IG51bGwpIHtcbiAgICAgICAgZmFjdG9yeShnbG9iYWwsIGV4cG9ydHMpXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgZGVmaW5lKFwiY2xlYW4tbWF0Y2hcIiwgW1wiZXhwb3J0c1wiXSwgZnVuY3Rpb24gKGV4cG9ydHMpIHtcbiAgICAgICAgICAgIGZhY3RvcnkoZ2xvYmFsLCBleHBvcnRzKVxuICAgICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAgIGZhY3RvcnkoZ2xvYmFsLCBnbG9iYWwubWF0Y2ggPSB7fSlcbiAgICB9XG59KSh0eXBlb2YgZ2xvYmFsID09PSBcIm9iamVjdFwiICYmIGdsb2JhbCAhPT0gbnVsbCA/IGdsb2JhbFxuICAgIDogdHlwZW9mIHNlbGYgPT09IFwib2JqZWN0XCIgJiYgc2VsZiAhPT0gbnVsbCA/IHNlbGZcbiAgICA6IHR5cGVvZiB3aW5kb3cgPT09IFwib2JqZWN0XCIgJiYgd2luZG93ICE9PSBudWxsID8gd2luZG93XG4gICAgOiB0aGlzLFxuZnVuY3Rpb24gKGdsb2JhbCwgZXhwb3J0cykge1xuICAgIC8qIGVzbGludC1lbmFibGUgKi9cbiAgICBcInVzZSBzdHJpY3RcIlxuXG4gICAgLyogZ2xvYmFsIFN5bWJvbCwgVWludDhBcnJheSwgRGF0YVZpZXcsIEFycmF5QnVmZmVyLCBBcnJheUJ1ZmZlclZpZXcsIE1hcCxcbiAgICBTZXQgKi9cblxuICAgIC8qKlxuICAgICAqIERlZXAgbWF0Y2hpbmcgYWxnb3JpdGhtLCB3aXRoIHplcm8gZGVwZW5kZW5jaWVzLiBOb3RlIHRoZSBmb2xsb3dpbmc6XG4gICAgICpcbiAgICAgKiAtIFRoaXMgaXMgcmVsYXRpdmVseSBwZXJmb3JtYW5jZS10dW5lZCwgYWx0aG91Z2ggaXQgcHJlZmVycyBoaWdoXG4gICAgICogICBjb3JyZWN0bmVzcy4gUGF0Y2ggd2l0aCBjYXJlLCBzaW5jZSBwZXJmb3JtYW5jZSBpcyBhIGNvbmNlcm4uXG4gICAgICogLSBUaGlzIGRvZXMgcGFjayBhICpsb3QqIG9mIGZlYXR1cmVzLCB3aGljaCBzaG91bGQgZXhwbGFpbiB0aGUgbGVuZ3RoLlxuICAgICAqIC0gU29tZSBvZiB0aGUgZHVwbGljYXRpb24gaXMgaW50ZW50aW9uYWwuIEl0J3MgZ2VuZXJhbGx5IGNvbW1lbnRlZCwgYnV0XG4gICAgICogICBpdCdzIG1haW5seSBmb3IgcGVyZm9ybWFuY2UsIHNpbmNlIHRoZSBlbmdpbmUgbmVlZHMgaXRzIHR5cGUgaW5mby5cbiAgICAgKiAtIFBvbHlmaWxsZWQgY29yZS1qcyBTeW1ib2xzIGZyb20gY3Jvc3Mtb3JpZ2luIGNvbnRleHRzIHdpbGwgbmV2ZXJcbiAgICAgKiAgIHJlZ2lzdGVyIGFzIGJlaW5nIGFjdHVhbCBTeW1ib2xzLlxuICAgICAqXG4gICAgICogQW5kIGluIGNhc2UgeW91J3JlIHdvbmRlcmluZyBhYm91dCB0aGUgbG9uZ2VyIGZ1bmN0aW9ucyBhbmQgb2NjYXNpb25hbFxuICAgICAqIHJlcGV0aXRpb24sIGl0J3MgYmVjYXVzZSBWOCdzIGlubGluZXIgaXNuJ3QgYWx3YXlzIGludGVsbGlnZW50IGVub3VnaCB0b1xuICAgICAqIGRlYWwgd2l0aCB0aGUgc3VwZXIgaGlnaGx5IHBvbHltb3JwaGljIGRhdGEgdGhpcyBvZnRlbiBkZWFscyB3aXRoLCBhbmQgSlNcbiAgICAgKiBkb2Vzbid0IGhhdmUgY29tcGlsZS10aW1lIG1hY3Jvcy5cbiAgICAgKi9cblxuICAgIHZhciBvYmplY3RUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdcbiAgICB2YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eVxuXG4gICAgdmFyIHN1cHBvcnRzVW5pY29kZSA9IGhhc093bi5jYWxsKFJlZ0V4cC5wcm90b3R5cGUsIFwidW5pY29kZVwiKVxuICAgIHZhciBzdXBwb3J0c1N0aWNreSA9IGhhc093bi5jYWxsKFJlZ0V4cC5wcm90b3R5cGUsIFwic3RpY2t5XCIpXG5cbiAgICAvLyBMZWdhY3kgZW5naW5lcyBoYXZlIHNldmVyYWwgaXNzdWVzIHdoZW4gaXQgY29tZXMgdG8gYHR5cGVvZmAuXG4gICAgdmFyIGlzRnVuY3Rpb24gPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICBmdW5jdGlvbiBTbG93SXNGdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBmYWxzZVxuXG4gICAgICAgICAgICB2YXIgdGFnID0gb2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSlcblxuICAgICAgICAgICAgcmV0dXJuIHRhZyA9PT0gXCJbb2JqZWN0IEZ1bmN0aW9uXVwiIHx8XG4gICAgICAgICAgICAgICAgdGFnID09PSBcIltvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dXCIgfHxcbiAgICAgICAgICAgICAgICB0YWcgPT09IFwiW29iamVjdCBBc3luY0Z1bmN0aW9uXVwiIHx8XG4gICAgICAgICAgICAgICAgdGFnID09PSBcIltvYmplY3QgUHJveHldXCJcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGlzUG9pc29uZWQob2JqZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYgdHlwZW9mIG9iamVjdCAhPT0gXCJmdW5jdGlvblwiXG4gICAgICAgIH1cblxuICAgICAgICAvLyBJbiBTYWZhcmkgMTAsIGB0eXBlb2YgUHJveHkgPT09IFwib2JqZWN0XCJgXG4gICAgICAgIGlmIChpc1BvaXNvbmVkKGdsb2JhbC5Qcm94eSkpIHJldHVybiBTbG93SXNGdW5jdGlvblxuXG4gICAgICAgIC8vIEluIFNhZmFyaSA4LCBzZXZlcmFsIHR5cGVkIGFycmF5IGNvbnN0cnVjdG9ycyBhcmVcbiAgICAgICAgLy8gYHR5cGVvZiBDID09PSBcIm9iamVjdFwiYFxuICAgICAgICBpZiAoaXNQb2lzb25lZChnbG9iYWwuSW50OEFycmF5KSkgcmV0dXJuIFNsb3dJc0Z1bmN0aW9uXG5cbiAgICAgICAgLy8gSW4gb2xkIFY4LCBSZWdFeHBzIGFyZSBjYWxsYWJsZVxuICAgICAgICBpZiAodHlwZW9mIC94LyA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gU2xvd0lzRnVuY3Rpb24gLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG4gICAgICAgIC8vIExlYXZlIHRoaXMgZm9yIG5vcm1hbCB0aGluZ3MuIEl0J3MgZWFzaWx5IGlubGluZWQuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgfVxuICAgIH0pKClcblxuICAgIC8vIFNldCB1cCBvdXIgb3duIGJ1ZmZlciBjaGVjay4gV2Ugc2hvdWxkIGFsd2F5cyBhY2NlcHQgdGhlIHBvbHlmaWxsLCBldmVuXG4gICAgLy8gaW4gTm9kZS4gTm90ZSB0aGF0IGl0IHVzZXMgYGdsb2JhbC5CdWZmZXJgIHRvIGF2b2lkIGluY2x1ZGluZyBgYnVmZmVyYCBpblxuICAgIC8vIHRoZSBidW5kbGUuXG5cbiAgICB2YXIgQnVmZmVyTmF0aXZlID0gMFxuICAgIHZhciBCdWZmZXJQb2x5ZmlsbCA9IDFcbiAgICB2YXIgQnVmZmVyU2FmYXJpID0gMlxuXG4gICAgdmFyIGJ1ZmZlclN1cHBvcnQgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICBmdW5jdGlvbiBGYWtlQnVmZmVyKCkge31cbiAgICAgICAgRmFrZUJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWUgfVxuXG4gICAgICAgIC8vIE9ubHkgU2FmYXJpIDUtNyBoYXMgZXZlciBoYWQgdGhpcyBpc3N1ZS5cbiAgICAgICAgaWYgKG5ldyBGYWtlQnVmZmVyKCkuY29uc3RydWN0b3IgIT09IEZha2VCdWZmZXIpIHJldHVybiBCdWZmZXJTYWZhcmlcbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKGdsb2JhbC5CdWZmZXIpKSByZXR1cm4gQnVmZmVyUG9seWZpbGxcbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIpKSByZXR1cm4gQnVmZmVyUG9seWZpbGxcbiAgICAgICAgLy8gQXZvaWQgZ2xvYmFsIHBvbHlmaWxsc1xuICAgICAgICBpZiAoZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlcihuZXcgRmFrZUJ1ZmZlcigpKSkgcmV0dXJuIEJ1ZmZlclBvbHlmaWxsXG4gICAgICAgIHJldHVybiBCdWZmZXJOYXRpdmVcbiAgICB9KSgpXG5cbiAgICB2YXIgZ2xvYmFsSXNCdWZmZXIgPSBidWZmZXJTdXBwb3J0ID09PSBCdWZmZXJOYXRpdmVcbiAgICAgICAgPyBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyXG4gICAgICAgIDogdW5kZWZpbmVkXG5cbiAgICBmdW5jdGlvbiBpc0J1ZmZlcihvYmplY3QpIHtcbiAgICAgICAgaWYgKGJ1ZmZlclN1cHBvcnQgPT09IEJ1ZmZlck5hdGl2ZSAmJiBnbG9iYWxJc0J1ZmZlcihvYmplY3QpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9IGVsc2UgaWYgKGJ1ZmZlclN1cHBvcnQgPT09IEJ1ZmZlclNhZmFyaSAmJiBvYmplY3QuX2lzQnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIEIgPSBvYmplY3QuY29uc3RydWN0b3JcblxuICAgICAgICBpZiAoIWlzRnVuY3Rpb24oQikpIHJldHVybiBmYWxzZVxuICAgICAgICBpZiAoIWlzRnVuY3Rpb24oQi5pc0J1ZmZlcikpIHJldHVybiBmYWxzZVxuICAgICAgICByZXR1cm4gQi5pc0J1ZmZlcihvYmplY3QpXG4gICAgfVxuXG4gICAgLy8gY29yZS1qcycgc3ltYm9scyBhcmUgb2JqZWN0cywgYW5kIHNvbWUgb2xkIHZlcnNpb25zIG9mIFY4IGVycm9uZW91c2x5IGhhZFxuICAgIC8vIGB0eXBlb2YgU3ltYm9sKCkgPT09IFwib2JqZWN0XCJgLlxuICAgIHZhciBzeW1ib2xzQXJlT2JqZWN0cyA9IGlzRnVuY3Rpb24oZ2xvYmFsLlN5bWJvbCkgJiZcbiAgICAgICAgdHlwZW9mIFN5bWJvbCgpID09PSBcIm9iamVjdFwiXG5cbiAgICAvLyBgY29udGV4dGAgaXMgYSBiaXQgZmllbGQsIHdpdGggdGhlIGZvbGxvd2luZyBiaXRzLiBUaGlzIGlzIG5vdCBhcyBtdWNoXG4gICAgLy8gZm9yIHBlcmZvcm1hbmNlIHRoYW4gdG8ganVzdCByZWR1Y2UgdGhlIG51bWJlciBvZiBwYXJhbWV0ZXJzIEkgbmVlZCB0byBiZVxuICAgIC8vIHRocm93aW5nIGFyb3VuZC5cbiAgICB2YXIgU3RyaWN0ID0gMVxuICAgIHZhciBJbml0aWFsID0gMlxuICAgIHZhciBTYW1lUHJvdG8gPSA0XG5cbiAgICBleHBvcnRzLmxvb3NlID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIG1hdGNoKGEsIGIsIEluaXRpYWwsIHVuZGVmaW5lZCwgdW5kZWZpbmVkKVxuICAgIH1cblxuICAgIGV4cG9ydHMuc3RyaWN0ID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIG1hdGNoKGEsIGIsIFN0cmljdCB8IEluaXRpYWwsIHVuZGVmaW5lZCwgdW5kZWZpbmVkKVxuICAgIH1cblxuICAgIC8vIEZlYXR1cmUtdGVzdCBkZWxheWVkIHN0YWNrIGFkZGl0aW9ucyBhbmQgZXh0cmEga2V5cy4gUGhhbnRvbUpTIGFuZCBJRVxuICAgIC8vIGJvdGggd2FpdCB1bnRpbCB0aGUgZXJyb3Igd2FzIGFjdHVhbGx5IHRocm93biBmaXJzdCwgYW5kIGFzc2lnbiB0aGVtIGFzXG4gICAgLy8gb3duIHByb3BlcnRpZXMsIHdoaWNoIGlzIHVuaGVscGZ1bCBmb3IgYXNzZXJ0aW9ucy4gVGhpcyByZXR1cm5zIGFcbiAgICAvLyBmdW5jdGlvbiB0byBzcGVlZCB1cCBjYXNlcyB3aGVyZSBgT2JqZWN0LmtleXNgIGlzIHN1ZmZpY2llbnQgKGUuZy4gaW5cbiAgICAvLyBDaHJvbWUvRkYvTm9kZSkuXG4gICAgLy9cbiAgICAvLyBUaGlzIHdvdWxkbid0IGJlIG5lY2Vzc2FyeSBpZiB0aG9zZSBlbmdpbmVzIHdvdWxkIG1ha2UgdGhlIHN0YWNrIGFcbiAgICAvLyBnZXR0ZXIsIGFuZCByZWNvcmQgaXQgd2hlbiB0aGUgZXJyb3Igd2FzIGNyZWF0ZWQsIG5vdCB3aGVuIGl0IHdhcyB0aHJvd24uXG4gICAgLy8gSXQgc3BlY2lmaWNhbGx5IGZpbHRlcnMgb3V0IGVycm9ycyBhbmQgb25seSBjaGVja3MgZXhpc3RpbmcgZGVzY3JpcHRvcnMsXG4gICAgLy8ganVzdCB0byBrZWVwIHRoZSBtZXNzIGZyb20gYWZmZWN0aW5nIGV2ZXJ5dGhpbmcgKGl0J3Mgbm90IGZ1bGx5IGNvcnJlY3QsXG4gICAgLy8gYnV0IGl0J3MgbmVjZXNzYXJ5KS5cbiAgICB2YXIgcmVxdWlyZXNQcm94eSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB0ZXN0ID0gbmV3IEVycm9yKClcbiAgICAgICAgdmFyIG9sZCA9IE9iamVjdC5jcmVhdGUobnVsbClcblxuICAgICAgICBPYmplY3Qua2V5cyh0ZXN0KS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHsgb2xkW2tleV0gPSB0cnVlIH0pXG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRocm93IHRlc3RcbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgICAgLy8gaWdub3JlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGVzdCkuc29tZShmdW5jdGlvbiAoa2V5KSB7IHJldHVybiAhb2xkW2tleV0gfSlcbiAgICB9KSgpXG5cbiAgICBmdW5jdGlvbiBpc0lnbm9yZWQob2JqZWN0LCBrZXkpIHtcbiAgICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgY2FzZSBcImxpbmVcIjogaWYgKHR5cGVvZiBvYmplY3QubGluZSAhPT0gXCJudW1iZXJcIikgcmV0dXJuIGZhbHNlOyBicmVha1xuICAgICAgICBjYXNlIFwic291cmNlVVJMXCI6XG4gICAgICAgICAgICBpZiAodHlwZW9mIG9iamVjdC5zb3VyY2VVUkwgIT09IFwic3RyaW5nXCIpIHJldHVybiBmYWxzZTsgYnJlYWtcbiAgICAgICAgY2FzZSBcInN0YWNrXCI6IGlmICh0eXBlb2Ygb2JqZWN0LnN0YWNrICE9PSBcInN0cmluZ1wiKSByZXR1cm4gZmFsc2U7IGJyZWFrXG4gICAgICAgIGRlZmF1bHQ6IHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwga2V5KVxuXG4gICAgICAgIHJldHVybiAhZGVzYy5jb25maWd1cmFibGUgJiYgZGVzYy5lbnVtZXJhYmxlICYmICFkZXNjLndyaXRhYmxlXG4gICAgfVxuXG4gICAgLy8gVGhpcyBpcyBvbmx5IGludm9rZWQgd2l0aCBlcnJvcnMsIHNvIGl0J3Mgbm90IGdvaW5nIHRvIHByZXNlbnQgYVxuICAgIC8vIHNpZ25pZmljYW50IHNsb3cgZG93bi5cbiAgICBmdW5jdGlvbiBnZXRLZXlzU3RyaXBwZWQob2JqZWN0KSB7XG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqZWN0KVxuICAgICAgICB2YXIgY291bnQgPSAwXG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIWlzSWdub3JlZChvYmplY3QsIGtleXNbaV0pKSBrZXlzW2NvdW50KytdID0ga2V5c1tpXVxuICAgICAgICB9XG5cbiAgICAgICAga2V5cy5sZW5ndGggPSBjb3VudFxuICAgICAgICByZXR1cm4ga2V5c1xuICAgIH1cblxuICAgIC8vIFdheSBmYXN0ZXIsIHNpbmNlIHR5cGVkIGFycmF5IGluZGljZXMgYXJlIGFsd2F5cyBkZW5zZSBhbmQgY29udGFpblxuICAgIC8vIG51bWJlcnMuXG5cbiAgICAvLyBTZXR1cCBmb3IgYGlzQnVmZmVyT3JWaWV3YCBhbmQgYGlzVmlld2BcbiAgICB2YXIgQXJyYXlCdWZmZXJOb25lID0gMFxuICAgIHZhciBBcnJheUJ1ZmZlckxlZ2FjeSA9IDFcbiAgICB2YXIgQXJyYXlCdWZmZXJDdXJyZW50ID0gMlxuXG4gICAgdmFyIGFycmF5QnVmZmVyU3VwcG9ydCA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghaXNGdW5jdGlvbihnbG9iYWwuVWludDhBcnJheSkpIHJldHVybiBBcnJheUJ1ZmZlck5vbmVcbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKGdsb2JhbC5EYXRhVmlldykpIHJldHVybiBBcnJheUJ1ZmZlck5vbmVcbiAgICAgICAgaWYgKCFpc0Z1bmN0aW9uKGdsb2JhbC5BcnJheUJ1ZmZlcikpIHJldHVybiBBcnJheUJ1ZmZlck5vbmVcbiAgICAgICAgaWYgKGlzRnVuY3Rpb24oZ2xvYmFsLkFycmF5QnVmZmVyLmlzVmlldykpIHJldHVybiBBcnJheUJ1ZmZlckN1cnJlbnRcbiAgICAgICAgaWYgKGlzRnVuY3Rpb24oZ2xvYmFsLkFycmF5QnVmZmVyVmlldykpIHJldHVybiBBcnJheUJ1ZmZlckxlZ2FjeVxuICAgICAgICByZXR1cm4gQXJyYXlCdWZmZXJOb25lXG4gICAgfSkoKVxuXG4gICAgLy8gSWYgdHlwZWQgYXJyYXlzIGFyZW4ndCBzdXBwb3J0ZWQgKHRoZXkgd2VyZW4ndCB0ZWNobmljYWxseSBwYXJ0IG9mXG4gICAgLy8gRVM1LCBidXQgbWFueSBlbmdpbmVzIGltcGxlbWVudGVkIEtocm9ub3MnIHNwZWMgYmVmb3JlIEVTNiksIHRoZW5cbiAgICAvLyBqdXN0IGZhbGwgYmFjayB0byBnZW5lcmljIGJ1ZmZlciBkZXRlY3Rpb24uXG5cbiAgICBmdW5jdGlvbiBmbG9hdElzKGEsIGIpIHtcbiAgICAgICAgLy8gU28gTmFOcyBhcmUgY29uc2lkZXJlZCBlcXVhbC5cbiAgICAgICAgcmV0dXJuIGEgPT09IGIgfHwgYSAhPT0gYSAmJiBiICE9PSBiIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tc2VsZi1jb21wYXJlLCBtYXgtbGVuXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF0Y2hWaWV3KGEsIGIpIHtcbiAgICAgICAgdmFyIGNvdW50ID0gYS5sZW5ndGhcblxuICAgICAgICBpZiAoY291bnQgIT09IGIubGVuZ3RoKSByZXR1cm4gZmFsc2VcblxuICAgICAgICB3aGlsZSAoY291bnQpIHtcbiAgICAgICAgICAgIGNvdW50LS1cbiAgICAgICAgICAgIGlmICghZmxvYXRJcyhhW2NvdW50XSwgYltjb3VudF0pKSByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgdmFyIGlzVmlldyA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChhcnJheUJ1ZmZlclN1cHBvcnQgPT09IEFycmF5QnVmZmVyTm9uZSkgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICAvLyBFUzYgdHlwZWQgYXJyYXlzXG4gICAgICAgIGlmIChhcnJheUJ1ZmZlclN1cHBvcnQgPT09IEFycmF5QnVmZmVyQ3VycmVudCkgcmV0dXJuIEFycmF5QnVmZmVyLmlzVmlld1xuICAgICAgICAvLyBsZWdhY3kgdHlwZWQgYXJyYXlzXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBpc1ZpZXcob2JqZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgQXJyYXlCdWZmZXJWaWV3XG4gICAgICAgIH1cbiAgICB9KSgpXG5cbiAgICAvLyBTdXBwb3J0IGNoZWNraW5nIG1hcHMgYW5kIHNldHMgZGVlcGx5LiBUaGV5IGFyZSBvYmplY3QtbGlrZSBlbm91Z2ggdG9cbiAgICAvLyBjb3VudCwgYW5kIGFyZSB1c2VmdWwgaW4gdGhlaXIgb3duIHJpZ2h0LiBUaGUgY29kZSBpcyByYXRoZXIgbWVzc3ksIGJ1dFxuICAgIC8vIG1haW5seSB0byBrZWVwIHRoZSBvcmRlci1pbmRlcGVuZGVudCBjaGVja2luZyBmcm9tIGJlY29taW5nIGluc2FuZWx5XG4gICAgLy8gc2xvdy5cbiAgICB2YXIgc3VwcG9ydHNNYXAgPSBpc0Z1bmN0aW9uKGdsb2JhbC5NYXApXG4gICAgdmFyIHN1cHBvcnRzU2V0ID0gaXNGdW5jdGlvbihnbG9iYWwuU2V0KVxuXG4gICAgLy8gT25lIG9mIHRoZSBzZXRzIGFuZCBib3RoIG1hcHMnIGtleXMgYXJlIGNvbnZlcnRlZCB0byBhcnJheXMgZm9yIGZhc3RlclxuICAgIC8vIGhhbmRsaW5nLlxuICAgIGZ1bmN0aW9uIGtleUxpc3QobWFwKSB7XG4gICAgICAgIHZhciBsaXN0ID0gbmV3IEFycmF5KG1hcC5zaXplKVxuICAgICAgICB2YXIgaSA9IDBcbiAgICAgICAgdmFyIGl0ZXIgPSBtYXAua2V5cygpXG5cbiAgICAgICAgZm9yICh2YXIgbmV4dCA9IGl0ZXIubmV4dCgpOyAhbmV4dC5kb25lOyBuZXh0ID0gaXRlci5uZXh0KCkpIHtcbiAgICAgICAgICAgIGxpc3RbaSsrXSA9IG5leHQudmFsdWVcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBsaXN0XG4gICAgfVxuXG4gICAgLy8gVGhlIHBhaXIgb2YgYXJyYXlzIGFyZSBhbGlnbmVkIGluIGEgc2luZ2xlIE8obl4yKSBvcGVyYXRpb24gKG1vZCBkZWVwXG4gICAgLy8gbWF0Y2hpbmcgYW5kIHJvdGF0aW9uKSwgYWRhcHRpbmcgdG8gTyhuKSB3aGVuIHRoZXkncmUgYWxyZWFkeSBhbGlnbmVkLlxuICAgIGZ1bmN0aW9uIG1hdGNoS2V5KGN1cnJlbnQsIGFrZXlzLCBzdGFydCwgZW5kLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgZm9yICh2YXIgaSA9IHN0YXJ0ICsgMTsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0gYWtleXNbaV1cblxuICAgICAgICAgICAgaWYgKG1hdGNoKGN1cnJlbnQsIGtleSwgY29udGV4dCwgbGVmdCwgcmlnaHQpKSB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogb25jZSBlbmdpbmVzIGFjdHVhbGx5IG9wdGltaXplIGBjb3B5V2l0aGluYCwgdXNlIHRoYXRcbiAgICAgICAgICAgICAgICAvLyBpbnN0ZWFkLiBJdCdsbCBiZSBtdWNoIGZhc3RlciB0aGFuIHRoaXMgbG9vcC5cbiAgICAgICAgICAgICAgICB3aGlsZSAoaSA+IHN0YXJ0KSBha2V5c1tpXSA9IGFrZXlzWy0taV1cbiAgICAgICAgICAgICAgICBha2V5c1tpXSA9IGtleVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXRjaFZhbHVlcyhhLCBiLCBha2V5cywgYmtleXMsIGVuZCwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW5kOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghbWF0Y2goYS5nZXQoYWtleXNbaV0pLCBiLmdldChia2V5c1tpXSksXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICAvLyBQb3NzaWJseSBleHBlbnNpdmUgb3JkZXItaW5kZXBlbmRlbnQga2V5LXZhbHVlIG1hdGNoLiBGaXJzdCwgdHJ5IHRvIGF2b2lkXG4gICAgLy8gaXQgYnkgY29uc2VydmF0aXZlbHkgYXNzdW1pbmcgZXZlcnl0aGluZyBpcyBpbiBvcmRlciAtIGEgY2hlYXAgTyhuKSBpc1xuICAgIC8vIGFsd2F5cyBuaWNlciB0aGFuIGFuIGV4cGVuc2l2ZSBPKG5eMikuXG4gICAgZnVuY3Rpb24gbWF0Y2hNYXAoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIHZhciBlbmQgPSBhLnNpemVcbiAgICAgICAgdmFyIGFrZXlzID0ga2V5TGlzdChhKVxuICAgICAgICB2YXIgYmtleXMgPSBrZXlMaXN0KGIpXG4gICAgICAgIHZhciBpID0gMFxuXG4gICAgICAgIHdoaWxlIChpICE9PSBlbmQgJiYgbWF0Y2goYWtleXNbaV0sIGJrZXlzW2ldLCBjb250ZXh0LCBsZWZ0LCByaWdodCkpIHtcbiAgICAgICAgICAgIGkrK1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGkgPT09IGVuZCkge1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoVmFsdWVzKGEsIGIsIGFrZXlzLCBia2V5cywgZW5kLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERvbid0IGNvbXBhcmUgdGhlIHNhbWUga2V5IHR3aWNlXG4gICAgICAgIGlmICghbWF0Y2hLZXkoYmtleXNbaV0sIGFrZXlzLCBpLCBlbmQsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGUgYWJvdmUgZmFpbHMsIHdoaWxlIHdlJ3JlIGF0IGl0LCBsZXQncyBzb3J0IHRoZW0gYXMgd2UgZ28sIHNvXG4gICAgICAgIC8vIHRoZSBrZXkgb3JkZXIgbWF0Y2hlcy5cbiAgICAgICAgd2hpbGUgKCsraSA8IGVuZCkge1xuICAgICAgICAgICAgdmFyIGtleSA9IGJrZXlzW2ldXG5cbiAgICAgICAgICAgIC8vIEFkYXB0IGlmIHRoZSBrZXlzIGFyZSBhbHJlYWR5IGluIG9yZGVyLCB3aGljaCBpcyBmcmVxdWVudGx5IHRoZVxuICAgICAgICAgICAgLy8gY2FzZS5cbiAgICAgICAgICAgIGlmICghbWF0Y2goa2V5LCBha2V5c1tpXSwgY29udGV4dCwgbGVmdCwgcmlnaHQpICYmXG4gICAgICAgICAgICAgICAgICAgICFtYXRjaEtleShrZXksIGFrZXlzLCBpLCBlbmQsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1hdGNoVmFsdWVzKGEsIGIsIGFrZXlzLCBia2V5cywgZW5kLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoYXNBbGxJZGVudGljYWwoYWxpc3QsIGIpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKCFiLmhhcyhhbGlzdFtpXSkpIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICAvLyBDb21wYXJlIHRoZSB2YWx1ZXMgc3RydWN0dXJhbGx5LCBhbmQgaW5kZXBlbmRlbnQgb2Ygb3JkZXIuXG4gICAgZnVuY3Rpb24gc2VhcmNoRm9yKGF2YWx1ZSwgb2JqZWN0cywgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIGZvciAodmFyIGogaW4gb2JqZWN0cykge1xuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKG9iamVjdHMsIGopKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKGF2YWx1ZSwgb2JqZWN0c1tqXSwgY29udGV4dCwgbGVmdCwgcmlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBvYmplY3RzW2pdXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaGFzU3RydWN0dXJlKHZhbHVlLCBjb250ZXh0KSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwgfHxcbiAgICAgICAgICAgICAgICAhKGNvbnRleHQgJiBTdHJpY3QpICYmIHR5cGVvZiB2YWx1ZSA9PT0gXCJzeW1ib2xcIlxuICAgIH1cblxuICAgIC8vIFRoZSBzZXQgYWxnb3JpdGhtIGlzIHN0cnVjdHVyZWQgYSBsaXR0bGUgZGlmZmVyZW50bHkuIEl0IHRha2VzIG9uZSBvZiB0aGVcbiAgICAvLyBzZXRzIGludG8gYW4gYXJyYXksIGRvZXMgYSBjaGVhcCBpZGVudGl0eSBjaGVjaywgdGhlbiBkb2VzIHRoZSBkZWVwXG4gICAgLy8gY2hlY2suXG4gICAgZnVuY3Rpb24gbWF0Y2hTZXQoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIC8vIFRoaXMgaXMgdG8gdHJ5IHRvIGF2b2lkIGFuIGV4cGVuc2l2ZSBzdHJ1Y3R1cmFsIG1hdGNoIG9uIHRoZSBrZXlzLlxuICAgICAgICAvLyBUZXN0IGZvciBpZGVudGl0eSBmaXJzdC5cbiAgICAgICAgdmFyIGFsaXN0ID0ga2V5TGlzdChhKVxuXG4gICAgICAgIGlmIChoYXNBbGxJZGVudGljYWwoYWxpc3QsIGIpKSByZXR1cm4gdHJ1ZVxuXG4gICAgICAgIHZhciBpdGVyID0gYi52YWx1ZXMoKVxuICAgICAgICB2YXIgY291bnQgPSAwXG4gICAgICAgIHZhciBvYmplY3RzXG5cbiAgICAgICAgLy8gR2F0aGVyIGFsbCB0aGUgb2JqZWN0c1xuICAgICAgICBmb3IgKHZhciBuZXh0ID0gaXRlci5uZXh0KCk7ICFuZXh0LmRvbmU7IG5leHQgPSBpdGVyLm5leHQoKSkge1xuICAgICAgICAgICAgdmFyIGJ2YWx1ZSA9IG5leHQudmFsdWVcblxuICAgICAgICAgICAgaWYgKGhhc1N0cnVjdHVyZShidmFsdWUsIGNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIHRoZSBvYmplY3RzIG1hcCBsYXppbHkuIE5vdGUgdGhhdCB0aGlzIGFsc28gZ3JhYnNcbiAgICAgICAgICAgICAgICAvLyBTeW1ib2xzIHdoZW4gbm90IHN0cmljdGx5IG1hdGNoaW5nLCBzaW5jZSB0aGVpciBkZXNjcmlwdGlvblxuICAgICAgICAgICAgICAgIC8vIGlzIGNvbXBhcmVkLlxuICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PT0gMCkgb2JqZWN0cyA9IE9iamVjdC5jcmVhdGUobnVsbClcbiAgICAgICAgICAgICAgICBvYmplY3RzW2NvdW50KytdID0gYnZhbHVlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBldmVyeXRoaW5nIGlzIGEgcHJpbWl0aXZlLCB0aGVuIGFib3J0LlxuICAgICAgICBpZiAoY291bnQgPT09IDApIHJldHVybiBmYWxzZVxuXG4gICAgICAgIC8vIEl0ZXJhdGUgdGhlIG9iamVjdCwgcmVtb3ZpbmcgZWFjaCBvbmUgcmVtYWluaW5nIHdoZW4gbWF0Y2hlZCAoYW5kXG4gICAgICAgIC8vIGFib3J0aW5nIGlmIG5vbmUgY2FuIGJlKS5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgYXZhbHVlID0gYWxpc3RbaV1cblxuICAgICAgICAgICAgaWYgKGhhc1N0cnVjdHVyZShhdmFsdWUsIGNvbnRleHQpICYmXG4gICAgICAgICAgICAgICAgICAgICFzZWFyY2hGb3IoYXZhbHVlLCBvYmplY3RzLCBjb250ZXh0LCBsZWZ0LCByaWdodCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF0Y2hSZWdFeHAoYSwgYikge1xuICAgICAgICByZXR1cm4gYS5zb3VyY2UgPT09IGIuc291cmNlICYmXG4gICAgICAgICAgICBhLmdsb2JhbCA9PT0gYi5nbG9iYWwgJiZcbiAgICAgICAgICAgIGEuaWdub3JlQ2FzZSA9PT0gYi5pZ25vcmVDYXNlICYmXG4gICAgICAgICAgICBhLm11bHRpbGluZSA9PT0gYi5tdWx0aWxpbmUgJiZcbiAgICAgICAgICAgICghc3VwcG9ydHNVbmljb2RlIHx8IGEudW5pY29kZSA9PT0gYi51bmljb2RlKSAmJlxuICAgICAgICAgICAgKCFzdXBwb3J0c1N0aWNreSB8fCBhLnN0aWNreSA9PT0gYi5zdGlja3kpXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF0Y2hQcmVwYXJlRGVzY2VuZChhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIGNpcmN1bGFyIHJlZmVyZW5jZXMgYWZ0ZXIgdGhlIGZpcnN0IGxldmVsLCB3aGVyZSBpdCdzXG4gICAgICAgIC8vIHJlZHVuZGFudC4gTm90ZSB0aGF0IHRoZXkgaGF2ZSB0byBwb2ludCB0byB0aGUgc2FtZSBsZXZlbCB0byBhY3R1YWxseVxuICAgICAgICAvLyBiZSBjb25zaWRlcmVkIGRlZXBseSBlcXVhbC5cbiAgICAgICAgaWYgKCEoY29udGV4dCAmIEluaXRpYWwpKSB7XG4gICAgICAgICAgICB2YXIgbGVmdEluZGV4ID0gbGVmdC5pbmRleE9mKGEpXG4gICAgICAgICAgICB2YXIgcmlnaHRJbmRleCA9IHJpZ2h0LmluZGV4T2YoYilcblxuICAgICAgICAgICAgaWYgKGxlZnRJbmRleCAhPT0gcmlnaHRJbmRleCkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICBpZiAobGVmdEluZGV4ID49IDApIHJldHVybiB0cnVlXG5cbiAgICAgICAgICAgIGxlZnQucHVzaChhKVxuICAgICAgICAgICAgcmlnaHQucHVzaChiKVxuXG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gbWF0Y2hJbm5lcihhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcblxuICAgICAgICAgICAgbGVmdC5wb3AoKVxuICAgICAgICAgICAgcmlnaHQucG9wKClcblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG1hdGNoSW5uZXIoYSwgYiwgY29udGV4dCAmIH5Jbml0aWFsLCBbYV0sIFtiXSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoU2FtZVByb3RvKGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICBpZiAoc3ltYm9sc0FyZU9iamVjdHMgJiYgYSBpbnN0YW5jZW9mIFN5bWJvbCkge1xuICAgICAgICAgICAgcmV0dXJuICEoY29udGV4dCAmIFN0cmljdCkgJiYgYS50b1N0cmluZygpID09PSBiLnRvU3RyaW5nKClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhIGluc3RhbmNlb2YgUmVnRXhwKSByZXR1cm4gbWF0Y2hSZWdFeHAoYSwgYilcbiAgICAgICAgaWYgKGEgaW5zdGFuY2VvZiBEYXRlKSByZXR1cm4gYS52YWx1ZU9mKCkgPT09IGIudmFsdWVPZigpXG4gICAgICAgIGlmIChhcnJheUJ1ZmZlclN1cHBvcnQgIT09IEFycmF5QnVmZmVyTm9uZSkge1xuICAgICAgICAgICAgaWYgKGEgaW5zdGFuY2VvZiBEYXRhVmlldykge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaFZpZXcoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVaW50OEFycmF5KGEuYnVmZmVyLCBhLmJ5dGVPZmZzZXQsIGEuYnl0ZUxlbmd0aCksXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVaW50OEFycmF5KGIuYnVmZmVyLCBiLmJ5dGVPZmZzZXQsIGIuYnl0ZUxlbmd0aCkpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoVmlldyhuZXcgVWludDhBcnJheShhKSwgbmV3IFVpbnQ4QXJyYXkoYikpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNWaWV3KGEpKSByZXR1cm4gbWF0Y2hWaWV3KGEsIGIpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaXNCdWZmZXIoYSkpIHJldHVybiBtYXRjaFZpZXcoYSwgYilcblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgICAgICAgICAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICBpZiAoYS5sZW5ndGggPT09IDApIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydHNNYXAgJiYgYSBpbnN0YW5jZW9mIE1hcCkge1xuICAgICAgICAgICAgaWYgKGEuc2l6ZSAhPT0gYi5zaXplKSByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIGlmIChhLnNpemUgPT09IDApIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydHNTZXQgJiYgYSBpbnN0YW5jZW9mIFNldCkge1xuICAgICAgICAgICAgaWYgKGEuc2l6ZSAhPT0gYi5zaXplKSByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIGlmIChhLnNpemUgPT09IDApIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAob2JqZWN0VG9TdHJpbmcuY2FsbChhKSA9PT0gXCJbb2JqZWN0IEFyZ3VtZW50c11cIikge1xuICAgICAgICAgICAgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYikgIT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICBpZiAoYS5sZW5ndGggPT09IDApIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAob2JqZWN0VG9TdHJpbmcuY2FsbChiKSA9PT0gXCJbb2JqZWN0IEFyZ3VtZW50c11cIikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWF0Y2hQcmVwYXJlRGVzY2VuZChhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICB9XG5cbiAgICAvLyBNb3N0IHNwZWNpYWwgY2FzZXMgcmVxdWlyZSBib3RoIHR5cGVzIHRvIG1hdGNoLCBhbmQgaWYgb25seSBvbmUgb2YgdGhlbVxuICAgIC8vIGFyZSwgdGhlIG9iamVjdHMgdGhlbXNlbHZlcyBkb24ndCBtYXRjaC5cbiAgICBmdW5jdGlvbiBtYXRjaERpZmZlcmVudFByb3RvKGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICBpZiAoc3ltYm9sc0FyZU9iamVjdHMpIHtcbiAgICAgICAgICAgIGlmIChhIGluc3RhbmNlb2YgU3ltYm9sIHx8IGIgaW5zdGFuY2VvZiBTeW1ib2wpIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb250ZXh0ICYgU3RyaWN0KSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKGFycmF5QnVmZmVyU3VwcG9ydCAhPT0gQXJyYXlCdWZmZXJOb25lKSB7XG4gICAgICAgICAgICBpZiAoYSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IGIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzVmlldyhhKSB8fCBpc1ZpZXcoYikpIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGEpIHx8IEFycmF5LmlzQXJyYXkoYikpIHJldHVybiBmYWxzZVxuICAgICAgICBpZiAoc3VwcG9ydHNNYXAgJiYgKGEgaW5zdGFuY2VvZiBNYXAgfHwgYiBpbnN0YW5jZW9mIE1hcCkpIHJldHVybiBmYWxzZVxuICAgICAgICBpZiAoc3VwcG9ydHNTZXQgJiYgKGEgaW5zdGFuY2VvZiBTZXQgfHwgYiBpbnN0YW5jZW9mIFNldCkpIHJldHVybiBmYWxzZVxuICAgICAgICBpZiAob2JqZWN0VG9TdHJpbmcuY2FsbChhKSA9PT0gXCJbb2JqZWN0IEFyZ3VtZW50c11cIikge1xuICAgICAgICAgICAgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYikgIT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICBpZiAoYS5sZW5ndGggPT09IDApIHJldHVybiB0cnVlXG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9iamVjdFRvU3RyaW5nLmNhbGwoYikgPT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHJldHVybiBmYWxzZVxuICAgICAgICByZXR1cm4gbWF0Y2hQcmVwYXJlRGVzY2VuZChhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXRjaChhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1wYXJhbXMsIG1heC1sZW5cbiAgICAgICAgaWYgKGEgPT09IGIpIHJldHVybiB0cnVlXG4gICAgICAgIC8vIE5hTnMgYXJlIGVxdWFsXG4gICAgICAgIGlmIChhICE9PSBhKSByZXR1cm4gYiAhPT0gYiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNlbGYtY29tcGFyZVxuICAgICAgICBpZiAoYSA9PT0gbnVsbCB8fCBiID09PSBudWxsKSByZXR1cm4gZmFsc2VcbiAgICAgICAgaWYgKHR5cGVvZiBhID09PSBcInN5bWJvbFwiICYmIHR5cGVvZiBiID09PSBcInN5bWJvbFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gIShjb250ZXh0ICYgU3RyaWN0KSAmJiBhLnRvU3RyaW5nKCkgPT09IGIudG9TdHJpbmcoKVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgYSAhPT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgYiAhPT0gXCJvYmplY3RcIikgcmV0dXJuIGZhbHNlXG5cbiAgICAgICAgLy8gVXN1YWxseSwgYm90aCBvYmplY3RzIGhhdmUgaWRlbnRpY2FsIHByb3RvdHlwZXMsIGFuZCB0aGF0IGFsbG93cyBmb3JcbiAgICAgICAgLy8gaGFsZiB0aGUgdHlwZSBjaGVja2luZy5cbiAgICAgICAgaWYgKE9iamVjdC5nZXRQcm90b3R5cGVPZihhKSA9PT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGIpKSB7XG4gICAgICAgICAgICByZXR1cm4gbWF0Y2hTYW1lUHJvdG8oYSwgYiwgY29udGV4dCB8IFNhbWVQcm90bywgbGVmdCwgcmlnaHQpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbWF0Y2hEaWZmZXJlbnRQcm90byhhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hdGNoQXJyYXlMaWtlKGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbWF4LXBhcmFtcywgbWF4LWxlblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghbWF0Y2goYVtpXSwgYltpXSwgY29udGV4dCwgbGVmdCwgcmlnaHQpKSByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgLy8gUGhhbnRvbUpTIGFuZCBTbGltZXJKUyBib3RoIGhhdmUgbXlzdGVyaW91cyBpc3N1ZXMgd2hlcmUgYEVycm9yYCBpc1xuICAgIC8vIHNvbWV0aW1lcyBlcnJvbmVvdXNseSBvZiBhIGRpZmZlcmVudCBgd2luZG93YCwgYW5kIGl0IHNob3dzIHVwIGluIHRoZVxuICAgIC8vIHRlc3RzLiBUaGlzIG1lYW5zIEkgaGF2ZSB0byB1c2UgYSBtdWNoIHNsb3dlciBhbGdvcml0aG0gdG8gZGV0ZWN0IEVycm9ycy5cbiAgICAvL1xuICAgIC8vIFBoYW50b21KUzogaHR0cHM6Ly9naXRodWIuY29tL3BldGthYW50b25vdi9ibHVlYmlyZC9pc3N1ZXMvMTE0NlxuICAgIC8vIFNsaW1lckpTOiBodHRwczovL2dpdGh1Yi5jb20vbGF1cmVudGovc2xpbWVyanMvaXNzdWVzLzQwMFxuICAgIC8vXG4gICAgLy8gKFllcywgdGhlIFBoYW50b21KUyBidWcgaXMgZGV0YWlsZWQgaW4gdGhlIEJsdWViaXJkIGlzc3VlIHRyYWNrZXIuKVxuICAgIHZhciBjaGVja0Nyb3NzT3JpZ2luID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKGdsb2JhbC53aW5kb3cgPT0gbnVsbCB8fCBnbG9iYWwud2luZG93Lm5hdmlnYXRvciA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gL3NsaW1lcmpzfHBoYW50b21qcy9pLnRlc3QoZ2xvYmFsLndpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50KVxuICAgIH0pKClcblxuICAgIHZhciBlcnJvclN0cmluZ1R5cGVzID0ge1xuICAgICAgICBcIltvYmplY3QgRXJyb3JdXCI6IHRydWUsXG4gICAgICAgIFwiW29iamVjdCBFdmFsRXJyb3JdXCI6IHRydWUsXG4gICAgICAgIFwiW29iamVjdCBSYW5nZUVycm9yXVwiOiB0cnVlLFxuICAgICAgICBcIltvYmplY3QgUmVmZXJlbmNlRXJyb3JdXCI6IHRydWUsXG4gICAgICAgIFwiW29iamVjdCBTeW50YXhFcnJvcl1cIjogdHJ1ZSxcbiAgICAgICAgXCJbb2JqZWN0IFR5cGVFcnJvcl1cIjogdHJ1ZSxcbiAgICAgICAgXCJbb2JqZWN0IFVSSUVycm9yXVwiOiB0cnVlLFxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzUHJveGllZEVycm9yKG9iamVjdCkge1xuICAgICAgICB3aGlsZSAob2JqZWN0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChlcnJvclN0cmluZ1R5cGVzW29iamVjdFRvU3RyaW5nLmNhbGwob2JqZWN0KV0pIHJldHVybiB0cnVlXG4gICAgICAgICAgICBvYmplY3QgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWF0Y2hJbm5lcihhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG1heC1zdGF0ZW1lbnRzLCBtYXgtcGFyYW1zLCBtYXgtbGVuXG4gICAgICAgIHZhciBha2V5cywgYmtleXNcbiAgICAgICAgdmFyIGlzVW5wcm94aWVkRXJyb3IgPSBmYWxzZVxuXG4gICAgICAgIGlmIChjb250ZXh0ICYgU2FtZVByb3RvKSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaEFycmF5TGlrZShhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHN1cHBvcnRzTWFwICYmIGEgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF0Y2hNYXAoYSwgYiwgY29udGV4dCwgbGVmdCwgcmlnaHQpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChzdXBwb3J0c1NldCAmJiBhIGluc3RhbmNlb2YgU2V0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoU2V0KGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAob2JqZWN0VG9TdHJpbmcuY2FsbChhKSA9PT0gXCJbb2JqZWN0IEFyZ3VtZW50c11cIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXRjaEFycmF5TGlrZShhLCBiLCBjb250ZXh0LCBsZWZ0LCByaWdodClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlcXVpcmVzUHJveHkgJiZcbiAgICAgICAgICAgICAgICAgICAgKGNoZWNrQ3Jvc3NPcmlnaW4gPyBpc1Byb3hpZWRFcnJvcihhKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBhIGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgICAgICAgICAgICAgYWtleXMgPSBnZXRLZXlzU3RyaXBwZWQoYSlcbiAgICAgICAgICAgICAgICBia2V5cyA9IGdldEtleXNTdHJpcHBlZChiKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBha2V5cyA9IE9iamVjdC5rZXlzKGEpXG4gICAgICAgICAgICAgICAgYmtleXMgPSBPYmplY3Qua2V5cyhiKVxuICAgICAgICAgICAgICAgIGlzVW5wcm94aWVkRXJyb3IgPSBhIGluc3RhbmNlb2YgRXJyb3JcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChvYmplY3RUb1N0cmluZy5jYWxsKGEpID09PSBcIltvYmplY3QgQXJndW1lbnRzXVwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoQXJyYXlMaWtlKGEsIGIsIGNvbnRleHQsIGxlZnQsIHJpZ2h0KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiB3ZSByZXF1aXJlIGEgcHJveHksIGJlIHBlcm1pc3NpdmUgYW5kIGNoZWNrIHRoZSBgdG9TdHJpbmdgXG4gICAgICAgICAgICAvLyB0eXBlLiBUaGlzIGlzIHNvIGl0IHdvcmtzIGNyb3NzLW9yaWdpbiBpbiBQaGFudG9tSlMgaW5cbiAgICAgICAgICAgIC8vIHBhcnRpY3VsYXIuXG4gICAgICAgICAgICBpZiAoY2hlY2tDcm9zc09yaWdpbiA/IGlzUHJveGllZEVycm9yKGEpIDogYSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBha2V5cyA9IE9iamVjdC5rZXlzKGEpXG4gICAgICAgICAgICBia2V5cyA9IE9iamVjdC5rZXlzKGIpXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgY291bnQgPSBha2V5cy5sZW5ndGhcblxuICAgICAgICBpZiAoY291bnQgIT09IGJrZXlzLmxlbmd0aCkgcmV0dXJuIGZhbHNlXG5cbiAgICAgICAgLy8gU2hvcnRjdXQgaWYgdGhlcmUncyBub3RoaW5nIHRvIG1hdGNoXG4gICAgICAgIGlmIChjb3VudCA9PT0gMCkgcmV0dXJuIHRydWVcblxuICAgICAgICB2YXIgaVxuXG4gICAgICAgIGlmIChpc1VucHJveGllZEVycm9yKSB7XG4gICAgICAgICAgICAvLyBTaG9ydGN1dCBpZiB0aGUgcHJvcGVydGllcyBhcmUgZGlmZmVyZW50LlxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoYWtleXNbaV0gIT09IFwic3RhY2tcIikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWhhc093bi5jYWxsKGIsIGFrZXlzW2ldKSkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBWZXJpZnkgdGhhdCBhbGwgdGhlIGFrZXlzJyB2YWx1ZXMgbWF0Y2hlZC5cbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFrZXlzW2ldICE9PSBcInN0YWNrXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICFtYXRjaChhW2FrZXlzW2ldXSwgYltha2V5c1tpXV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCwgbGVmdCwgcmlnaHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNob3J0Y3V0IGlmIHRoZSBwcm9wZXJ0aWVzIGFyZSBkaWZmZXJlbnQuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghaGFzT3duLmNhbGwoYiwgYWtleXNbaV0pKSByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVmVyaWZ5IHRoYXQgYWxsIHRoZSBha2V5cycgdmFsdWVzIG1hdGNoZWQuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghbWF0Y2goYVtha2V5c1tpXV0sIGJbYWtleXNbaV1dLCBjb250ZXh0LCBsZWZ0LCByaWdodCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG59KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBzZW1pXG4iLCIvLyBTZWU6IGh0dHA6Ly9jb2RlLmdvb2dsZS5jb20vcC9nb29nbGUtZGlmZi1tYXRjaC1wYXRjaC93aWtpL0FQSVxuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRDaGFuZ2VzVG9ETVAoY2hhbmdlcykge1xuICBsZXQgcmV0ID0gW10sXG4gICAgICBjaGFuZ2UsXG4gICAgICBvcGVyYXRpb247XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY2hhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgIGNoYW5nZSA9IGNoYW5nZXNbaV07XG4gICAgaWYgKGNoYW5nZS5hZGRlZCkge1xuICAgICAgb3BlcmF0aW9uID0gMTtcbiAgICB9IGVsc2UgaWYgKGNoYW5nZS5yZW1vdmVkKSB7XG4gICAgICBvcGVyYXRpb24gPSAtMTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3BlcmF0aW9uID0gMDtcbiAgICB9XG5cbiAgICByZXQucHVzaChbb3BlcmF0aW9uLCBjaGFuZ2UudmFsdWVdKTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuIiwiZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRDaGFuZ2VzVG9YTUwoY2hhbmdlcykge1xuICBsZXQgcmV0ID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY2hhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgIGxldCBjaGFuZ2UgPSBjaGFuZ2VzW2ldO1xuICAgIGlmIChjaGFuZ2UuYWRkZWQpIHtcbiAgICAgIHJldC5wdXNoKCc8aW5zPicpO1xuICAgIH0gZWxzZSBpZiAoY2hhbmdlLnJlbW92ZWQpIHtcbiAgICAgIHJldC5wdXNoKCc8ZGVsPicpO1xuICAgIH1cblxuICAgIHJldC5wdXNoKGVzY2FwZUhUTUwoY2hhbmdlLnZhbHVlKSk7XG5cbiAgICBpZiAoY2hhbmdlLmFkZGVkKSB7XG4gICAgICByZXQucHVzaCgnPC9pbnM+Jyk7XG4gICAgfSBlbHNlIGlmIChjaGFuZ2UucmVtb3ZlZCkge1xuICAgICAgcmV0LnB1c2goJzwvZGVsPicpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmV0LmpvaW4oJycpO1xufVxuXG5mdW5jdGlvbiBlc2NhcGVIVE1MKHMpIHtcbiAgbGV0IG4gPSBzO1xuICBuID0gbi5yZXBsYWNlKC8mL2csICcmYW1wOycpO1xuICBuID0gbi5yZXBsYWNlKC88L2csICcmbHQ7Jyk7XG4gIG4gPSBuLnJlcGxhY2UoLz4vZywgJyZndDsnKTtcbiAgbiA9IG4ucmVwbGFjZSgvXCIvZywgJyZxdW90OycpO1xuXG4gIHJldHVybiBuO1xufVxuIiwiaW1wb3J0IERpZmYgZnJvbSAnLi9iYXNlJztcblxuZXhwb3J0IGNvbnN0IGFycmF5RGlmZiA9IG5ldyBEaWZmKCk7XG5hcnJheURpZmYudG9rZW5pemUgPSBhcnJheURpZmYuam9pbiA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZS5zbGljZSgpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZBcnJheXMob2xkQXJyLCBuZXdBcnIsIGNhbGxiYWNrKSB7IHJldHVybiBhcnJheURpZmYuZGlmZihvbGRBcnIsIG5ld0FyciwgY2FsbGJhY2spOyB9XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEaWZmKCkge31cblxuRGlmZi5wcm90b3R5cGUgPSB7XG4gIGRpZmYob2xkU3RyaW5nLCBuZXdTdHJpbmcsIG9wdGlvbnMgPSB7fSkge1xuICAgIGxldCBjYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjYWxsYmFjayA9IG9wdGlvbnM7XG4gICAgICBvcHRpb25zID0ge307XG4gICAgfVxuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cbiAgICBsZXQgc2VsZiA9IHRoaXM7XG5cbiAgICBmdW5jdGlvbiBkb25lKHZhbHVlKSB7XG4gICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHsgY2FsbGJhY2sodW5kZWZpbmVkLCB2YWx1ZSk7IH0sIDApO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBbGxvdyBzdWJjbGFzc2VzIHRvIG1hc3NhZ2UgdGhlIGlucHV0IHByaW9yIHRvIHJ1bm5pbmdcbiAgICBvbGRTdHJpbmcgPSB0aGlzLmNhc3RJbnB1dChvbGRTdHJpbmcpO1xuICAgIG5ld1N0cmluZyA9IHRoaXMuY2FzdElucHV0KG5ld1N0cmluZyk7XG5cbiAgICBvbGRTdHJpbmcgPSB0aGlzLnJlbW92ZUVtcHR5KHRoaXMudG9rZW5pemUob2xkU3RyaW5nKSk7XG4gICAgbmV3U3RyaW5nID0gdGhpcy5yZW1vdmVFbXB0eSh0aGlzLnRva2VuaXplKG5ld1N0cmluZykpO1xuXG4gICAgbGV0IG5ld0xlbiA9IG5ld1N0cmluZy5sZW5ndGgsIG9sZExlbiA9IG9sZFN0cmluZy5sZW5ndGg7XG4gICAgbGV0IGVkaXRMZW5ndGggPSAxO1xuICAgIGxldCBtYXhFZGl0TGVuZ3RoID0gbmV3TGVuICsgb2xkTGVuO1xuICAgIGxldCBiZXN0UGF0aCA9IFt7IG5ld1BvczogLTEsIGNvbXBvbmVudHM6IFtdIH1dO1xuXG4gICAgLy8gU2VlZCBlZGl0TGVuZ3RoID0gMCwgaS5lLiB0aGUgY29udGVudCBzdGFydHMgd2l0aCB0aGUgc2FtZSB2YWx1ZXNcbiAgICBsZXQgb2xkUG9zID0gdGhpcy5leHRyYWN0Q29tbW9uKGJlc3RQYXRoWzBdLCBuZXdTdHJpbmcsIG9sZFN0cmluZywgMCk7XG4gICAgaWYgKGJlc3RQYXRoWzBdLm5ld1BvcyArIDEgPj0gbmV3TGVuICYmIG9sZFBvcyArIDEgPj0gb2xkTGVuKSB7XG4gICAgICAvLyBJZGVudGl0eSBwZXIgdGhlIGVxdWFsaXR5IGFuZCB0b2tlbml6ZXJcbiAgICAgIHJldHVybiBkb25lKFt7dmFsdWU6IHRoaXMuam9pbihuZXdTdHJpbmcpLCBjb3VudDogbmV3U3RyaW5nLmxlbmd0aH1dKTtcbiAgICB9XG5cbiAgICAvLyBNYWluIHdvcmtlciBtZXRob2QuIGNoZWNrcyBhbGwgcGVybXV0YXRpb25zIG9mIGEgZ2l2ZW4gZWRpdCBsZW5ndGggZm9yIGFjY2VwdGFuY2UuXG4gICAgZnVuY3Rpb24gZXhlY0VkaXRMZW5ndGgoKSB7XG4gICAgICBmb3IgKGxldCBkaWFnb25hbFBhdGggPSAtMSAqIGVkaXRMZW5ndGg7IGRpYWdvbmFsUGF0aCA8PSBlZGl0TGVuZ3RoOyBkaWFnb25hbFBhdGggKz0gMikge1xuICAgICAgICBsZXQgYmFzZVBhdGg7XG4gICAgICAgIGxldCBhZGRQYXRoID0gYmVzdFBhdGhbZGlhZ29uYWxQYXRoIC0gMV0sXG4gICAgICAgICAgICByZW1vdmVQYXRoID0gYmVzdFBhdGhbZGlhZ29uYWxQYXRoICsgMV0sXG4gICAgICAgICAgICBvbGRQb3MgPSAocmVtb3ZlUGF0aCA/IHJlbW92ZVBhdGgubmV3UG9zIDogMCkgLSBkaWFnb25hbFBhdGg7XG4gICAgICAgIGlmIChhZGRQYXRoKSB7XG4gICAgICAgICAgLy8gTm8gb25lIGVsc2UgaXMgZ29pbmcgdG8gYXR0ZW1wdCB0byB1c2UgdGhpcyB2YWx1ZSwgY2xlYXIgaXRcbiAgICAgICAgICBiZXN0UGF0aFtkaWFnb25hbFBhdGggLSAxXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjYW5BZGQgPSBhZGRQYXRoICYmIGFkZFBhdGgubmV3UG9zICsgMSA8IG5ld0xlbixcbiAgICAgICAgICAgIGNhblJlbW92ZSA9IHJlbW92ZVBhdGggJiYgMCA8PSBvbGRQb3MgJiYgb2xkUG9zIDwgb2xkTGVuO1xuICAgICAgICBpZiAoIWNhbkFkZCAmJiAhY2FuUmVtb3ZlKSB7XG4gICAgICAgICAgLy8gSWYgdGhpcyBwYXRoIGlzIGEgdGVybWluYWwgdGhlbiBwcnVuZVxuICAgICAgICAgIGJlc3RQYXRoW2RpYWdvbmFsUGF0aF0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZWxlY3QgdGhlIGRpYWdvbmFsIHRoYXQgd2Ugd2FudCB0byBicmFuY2ggZnJvbS4gV2Ugc2VsZWN0IHRoZSBwcmlvclxuICAgICAgICAvLyBwYXRoIHdob3NlIHBvc2l0aW9uIGluIHRoZSBuZXcgc3RyaW5nIGlzIHRoZSBmYXJ0aGVzdCBmcm9tIHRoZSBvcmlnaW5cbiAgICAgICAgLy8gYW5kIGRvZXMgbm90IHBhc3MgdGhlIGJvdW5kcyBvZiB0aGUgZGlmZiBncmFwaFxuICAgICAgICBpZiAoIWNhbkFkZCB8fCAoY2FuUmVtb3ZlICYmIGFkZFBhdGgubmV3UG9zIDwgcmVtb3ZlUGF0aC5uZXdQb3MpKSB7XG4gICAgICAgICAgYmFzZVBhdGggPSBjbG9uZVBhdGgocmVtb3ZlUGF0aCk7XG4gICAgICAgICAgc2VsZi5wdXNoQ29tcG9uZW50KGJhc2VQYXRoLmNvbXBvbmVudHMsIHVuZGVmaW5lZCwgdHJ1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYmFzZVBhdGggPSBhZGRQYXRoOyAgIC8vIE5vIG5lZWQgdG8gY2xvbmUsIHdlJ3ZlIHB1bGxlZCBpdCBmcm9tIHRoZSBsaXN0XG4gICAgICAgICAgYmFzZVBhdGgubmV3UG9zKys7XG4gICAgICAgICAgc2VsZi5wdXNoQ29tcG9uZW50KGJhc2VQYXRoLmNvbXBvbmVudHMsIHRydWUsIHVuZGVmaW5lZCk7XG4gICAgICAgIH1cblxuICAgICAgICBvbGRQb3MgPSBzZWxmLmV4dHJhY3RDb21tb24oYmFzZVBhdGgsIG5ld1N0cmluZywgb2xkU3RyaW5nLCBkaWFnb25hbFBhdGgpO1xuXG4gICAgICAgIC8vIElmIHdlIGhhdmUgaGl0IHRoZSBlbmQgb2YgYm90aCBzdHJpbmdzLCB0aGVuIHdlIGFyZSBkb25lXG4gICAgICAgIGlmIChiYXNlUGF0aC5uZXdQb3MgKyAxID49IG5ld0xlbiAmJiBvbGRQb3MgKyAxID49IG9sZExlbikge1xuICAgICAgICAgIHJldHVybiBkb25lKGJ1aWxkVmFsdWVzKHNlbGYsIGJhc2VQYXRoLmNvbXBvbmVudHMsIG5ld1N0cmluZywgb2xkU3RyaW5nLCBzZWxmLnVzZUxvbmdlc3RUb2tlbikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE90aGVyd2lzZSB0cmFjayB0aGlzIHBhdGggYXMgYSBwb3RlbnRpYWwgY2FuZGlkYXRlIGFuZCBjb250aW51ZS5cbiAgICAgICAgICBiZXN0UGF0aFtkaWFnb25hbFBhdGhdID0gYmFzZVBhdGg7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZWRpdExlbmd0aCsrO1xuICAgIH1cblxuICAgIC8vIFBlcmZvcm1zIHRoZSBsZW5ndGggb2YgZWRpdCBpdGVyYXRpb24uIElzIGEgYml0IGZ1Z2x5IGFzIHRoaXMgaGFzIHRvIHN1cHBvcnQgdGhlXG4gICAgLy8gc3luYyBhbmQgYXN5bmMgbW9kZSB3aGljaCBpcyBuZXZlciBmdW4uIExvb3BzIG92ZXIgZXhlY0VkaXRMZW5ndGggdW50aWwgYSB2YWx1ZVxuICAgIC8vIGlzIHByb2R1Y2VkLlxuICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgKGZ1bmN0aW9uIGV4ZWMoKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgLy8gVGhpcyBzaG91bGQgbm90IGhhcHBlbiwgYnV0IHdlIHdhbnQgdG8gYmUgc2FmZS5cbiAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgICAgICAgIGlmIChlZGl0TGVuZ3RoID4gbWF4RWRpdExlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFleGVjRWRpdExlbmd0aCgpKSB7XG4gICAgICAgICAgICBleGVjKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCAwKTtcbiAgICAgIH0oKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdoaWxlIChlZGl0TGVuZ3RoIDw9IG1heEVkaXRMZW5ndGgpIHtcbiAgICAgICAgbGV0IHJldCA9IGV4ZWNFZGl0TGVuZ3RoKCk7XG4gICAgICAgIGlmIChyZXQpIHtcbiAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHB1c2hDb21wb25lbnQoY29tcG9uZW50cywgYWRkZWQsIHJlbW92ZWQpIHtcbiAgICBsZXQgbGFzdCA9IGNvbXBvbmVudHNbY29tcG9uZW50cy5sZW5ndGggLSAxXTtcbiAgICBpZiAobGFzdCAmJiBsYXN0LmFkZGVkID09PSBhZGRlZCAmJiBsYXN0LnJlbW92ZWQgPT09IHJlbW92ZWQpIHtcbiAgICAgIC8vIFdlIG5lZWQgdG8gY2xvbmUgaGVyZSBhcyB0aGUgY29tcG9uZW50IGNsb25lIG9wZXJhdGlvbiBpcyBqdXN0XG4gICAgICAvLyBhcyBzaGFsbG93IGFycmF5IGNsb25lXG4gICAgICBjb21wb25lbnRzW2NvbXBvbmVudHMubGVuZ3RoIC0gMV0gPSB7Y291bnQ6IGxhc3QuY291bnQgKyAxLCBhZGRlZDogYWRkZWQsIHJlbW92ZWQ6IHJlbW92ZWQgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29tcG9uZW50cy5wdXNoKHtjb3VudDogMSwgYWRkZWQ6IGFkZGVkLCByZW1vdmVkOiByZW1vdmVkIH0pO1xuICAgIH1cbiAgfSxcbiAgZXh0cmFjdENvbW1vbihiYXNlUGF0aCwgbmV3U3RyaW5nLCBvbGRTdHJpbmcsIGRpYWdvbmFsUGF0aCkge1xuICAgIGxldCBuZXdMZW4gPSBuZXdTdHJpbmcubGVuZ3RoLFxuICAgICAgICBvbGRMZW4gPSBvbGRTdHJpbmcubGVuZ3RoLFxuICAgICAgICBuZXdQb3MgPSBiYXNlUGF0aC5uZXdQb3MsXG4gICAgICAgIG9sZFBvcyA9IG5ld1BvcyAtIGRpYWdvbmFsUGF0aCxcblxuICAgICAgICBjb21tb25Db3VudCA9IDA7XG4gICAgd2hpbGUgKG5ld1BvcyArIDEgPCBuZXdMZW4gJiYgb2xkUG9zICsgMSA8IG9sZExlbiAmJiB0aGlzLmVxdWFscyhuZXdTdHJpbmdbbmV3UG9zICsgMV0sIG9sZFN0cmluZ1tvbGRQb3MgKyAxXSkpIHtcbiAgICAgIG5ld1BvcysrO1xuICAgICAgb2xkUG9zKys7XG4gICAgICBjb21tb25Db3VudCsrO1xuICAgIH1cblxuICAgIGlmIChjb21tb25Db3VudCkge1xuICAgICAgYmFzZVBhdGguY29tcG9uZW50cy5wdXNoKHtjb3VudDogY29tbW9uQ291bnR9KTtcbiAgICB9XG5cbiAgICBiYXNlUGF0aC5uZXdQb3MgPSBuZXdQb3M7XG4gICAgcmV0dXJuIG9sZFBvcztcbiAgfSxcblxuICBlcXVhbHMobGVmdCwgcmlnaHQpIHtcbiAgICByZXR1cm4gbGVmdCA9PT0gcmlnaHQ7XG4gIH0sXG4gIHJlbW92ZUVtcHR5KGFycmF5KSB7XG4gICAgbGV0IHJldCA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhcnJheVtpXSkge1xuICAgICAgICByZXQucHVzaChhcnJheVtpXSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH0sXG4gIGNhc3RJbnB1dCh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfSxcbiAgdG9rZW5pemUodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUuc3BsaXQoJycpO1xuICB9LFxuICBqb2luKGNoYXJzKSB7XG4gICAgcmV0dXJuIGNoYXJzLmpvaW4oJycpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBidWlsZFZhbHVlcyhkaWZmLCBjb21wb25lbnRzLCBuZXdTdHJpbmcsIG9sZFN0cmluZywgdXNlTG9uZ2VzdFRva2VuKSB7XG4gIGxldCBjb21wb25lbnRQb3MgPSAwLFxuICAgICAgY29tcG9uZW50TGVuID0gY29tcG9uZW50cy5sZW5ndGgsXG4gICAgICBuZXdQb3MgPSAwLFxuICAgICAgb2xkUG9zID0gMDtcblxuICBmb3IgKDsgY29tcG9uZW50UG9zIDwgY29tcG9uZW50TGVuOyBjb21wb25lbnRQb3MrKykge1xuICAgIGxldCBjb21wb25lbnQgPSBjb21wb25lbnRzW2NvbXBvbmVudFBvc107XG4gICAgaWYgKCFjb21wb25lbnQucmVtb3ZlZCkge1xuICAgICAgaWYgKCFjb21wb25lbnQuYWRkZWQgJiYgdXNlTG9uZ2VzdFRva2VuKSB7XG4gICAgICAgIGxldCB2YWx1ZSA9IG5ld1N0cmluZy5zbGljZShuZXdQb3MsIG5ld1BvcyArIGNvbXBvbmVudC5jb3VudCk7XG4gICAgICAgIHZhbHVlID0gdmFsdWUubWFwKGZ1bmN0aW9uKHZhbHVlLCBpKSB7XG4gICAgICAgICAgbGV0IG9sZFZhbHVlID0gb2xkU3RyaW5nW29sZFBvcyArIGldO1xuICAgICAgICAgIHJldHVybiBvbGRWYWx1ZS5sZW5ndGggPiB2YWx1ZS5sZW5ndGggPyBvbGRWYWx1ZSA6IHZhbHVlO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb21wb25lbnQudmFsdWUgPSBkaWZmLmpvaW4odmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29tcG9uZW50LnZhbHVlID0gZGlmZi5qb2luKG5ld1N0cmluZy5zbGljZShuZXdQb3MsIG5ld1BvcyArIGNvbXBvbmVudC5jb3VudCkpO1xuICAgICAgfVxuICAgICAgbmV3UG9zICs9IGNvbXBvbmVudC5jb3VudDtcblxuICAgICAgLy8gQ29tbW9uIGNhc2VcbiAgICAgIGlmICghY29tcG9uZW50LmFkZGVkKSB7XG4gICAgICAgIG9sZFBvcyArPSBjb21wb25lbnQuY291bnQ7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbXBvbmVudC52YWx1ZSA9IGRpZmYuam9pbihvbGRTdHJpbmcuc2xpY2Uob2xkUG9zLCBvbGRQb3MgKyBjb21wb25lbnQuY291bnQpKTtcbiAgICAgIG9sZFBvcyArPSBjb21wb25lbnQuY291bnQ7XG5cbiAgICAgIC8vIFJldmVyc2UgYWRkIGFuZCByZW1vdmUgc28gcmVtb3ZlcyBhcmUgb3V0cHV0IGZpcnN0IHRvIG1hdGNoIGNvbW1vbiBjb252ZW50aW9uXG4gICAgICAvLyBUaGUgZGlmZmluZyBhbGdvcml0aG0gaXMgdGllZCB0byBhZGQgdGhlbiByZW1vdmUgb3V0cHV0IGFuZCB0aGlzIGlzIHRoZSBzaW1wbGVzdFxuICAgICAgLy8gcm91dGUgdG8gZ2V0IHRoZSBkZXNpcmVkIG91dHB1dCB3aXRoIG1pbmltYWwgb3ZlcmhlYWQuXG4gICAgICBpZiAoY29tcG9uZW50UG9zICYmIGNvbXBvbmVudHNbY29tcG9uZW50UG9zIC0gMV0uYWRkZWQpIHtcbiAgICAgICAgbGV0IHRtcCA9IGNvbXBvbmVudHNbY29tcG9uZW50UG9zIC0gMV07XG4gICAgICAgIGNvbXBvbmVudHNbY29tcG9uZW50UG9zIC0gMV0gPSBjb21wb25lbnRzW2NvbXBvbmVudFBvc107XG4gICAgICAgIGNvbXBvbmVudHNbY29tcG9uZW50UG9zXSA9IHRtcDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBTcGVjaWFsIGNhc2UgaGFuZGxlIGZvciB3aGVuIG9uZSB0ZXJtaW5hbCBpcyBpZ25vcmVkLiBGb3IgdGhpcyBjYXNlIHdlIG1lcmdlIHRoZVxuICAvLyB0ZXJtaW5hbCBpbnRvIHRoZSBwcmlvciBzdHJpbmcgYW5kIGRyb3AgdGhlIGNoYW5nZS5cbiAgbGV0IGxhc3RDb21wb25lbnQgPSBjb21wb25lbnRzW2NvbXBvbmVudExlbiAtIDFdO1xuICBpZiAoY29tcG9uZW50TGVuID4gMVxuICAgICAgJiYgKGxhc3RDb21wb25lbnQuYWRkZWQgfHwgbGFzdENvbXBvbmVudC5yZW1vdmVkKVxuICAgICAgJiYgZGlmZi5lcXVhbHMoJycsIGxhc3RDb21wb25lbnQudmFsdWUpKSB7XG4gICAgY29tcG9uZW50c1tjb21wb25lbnRMZW4gLSAyXS52YWx1ZSArPSBsYXN0Q29tcG9uZW50LnZhbHVlO1xuICAgIGNvbXBvbmVudHMucG9wKCk7XG4gIH1cblxuICByZXR1cm4gY29tcG9uZW50cztcbn1cblxuZnVuY3Rpb24gY2xvbmVQYXRoKHBhdGgpIHtcbiAgcmV0dXJuIHsgbmV3UG9zOiBwYXRoLm5ld1BvcywgY29tcG9uZW50czogcGF0aC5jb21wb25lbnRzLnNsaWNlKDApIH07XG59XG4iLCJpbXBvcnQgRGlmZiBmcm9tICcuL2Jhc2UnO1xuXG5leHBvcnQgY29uc3QgY2hhcmFjdGVyRGlmZiA9IG5ldyBEaWZmKCk7XG5leHBvcnQgZnVuY3Rpb24gZGlmZkNoYXJzKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjaykgeyByZXR1cm4gY2hhcmFjdGVyRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjayk7IH1cbiIsImltcG9ydCBEaWZmIGZyb20gJy4vYmFzZSc7XG5cbmV4cG9ydCBjb25zdCBjc3NEaWZmID0gbmV3IERpZmYoKTtcbmNzc0RpZmYudG9rZW5pemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUuc3BsaXQoLyhbe306OyxdfFxccyspLyk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGlmZkNzcyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHsgcmV0dXJuIGNzc0RpZmYuZGlmZihvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spOyB9XG4iLCJpbXBvcnQgRGlmZiBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0IHtsaW5lRGlmZn0gZnJvbSAnLi9saW5lJztcblxuY29uc3Qgb2JqZWN0UHJvdG90eXBlVG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5cbmV4cG9ydCBjb25zdCBqc29uRGlmZiA9IG5ldyBEaWZmKCk7XG4vLyBEaXNjcmltaW5hdGUgYmV0d2VlbiB0d28gbGluZXMgb2YgcHJldHR5LXByaW50ZWQsIHNlcmlhbGl6ZWQgSlNPTiB3aGVyZSBvbmUgb2YgdGhlbSBoYXMgYVxuLy8gZGFuZ2xpbmcgY29tbWEgYW5kIHRoZSBvdGhlciBkb2Vzbid0LiBUdXJucyBvdXQgaW5jbHVkaW5nIHRoZSBkYW5nbGluZyBjb21tYSB5aWVsZHMgdGhlIG5pY2VzdCBvdXRwdXQ6XG5qc29uRGlmZi51c2VMb25nZXN0VG9rZW4gPSB0cnVlO1xuXG5qc29uRGlmZi50b2tlbml6ZSA9IGxpbmVEaWZmLnRva2VuaXplO1xuanNvbkRpZmYuY2FzdElucHV0ID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgY29uc3Qge3VuZGVmaW5lZFJlcGxhY2VtZW50fSA9IHRoaXMub3B0aW9ucztcblxuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHZhbHVlIDogSlNPTi5zdHJpbmdpZnkoY2Fub25pY2FsaXplKHZhbHVlKSwgZnVuY3Rpb24oaywgdikge1xuICAgIGlmICh0eXBlb2YgdiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWRSZXBsYWNlbWVudDtcbiAgICB9XG5cbiAgICByZXR1cm4gdjtcbiAgfSwgJyAgJyk7XG59O1xuanNvbkRpZmYuZXF1YWxzID0gZnVuY3Rpb24obGVmdCwgcmlnaHQpIHtcbiAgcmV0dXJuIERpZmYucHJvdG90eXBlLmVxdWFscyhsZWZ0LnJlcGxhY2UoLywoW1xcclxcbl0pL2csICckMScpLCByaWdodC5yZXBsYWNlKC8sKFtcXHJcXG5dKS9nLCAnJDEnKSk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGlmZkpzb24ob2xkT2JqLCBuZXdPYmosIG9wdGlvbnMpIHsgcmV0dXJuIGpzb25EaWZmLmRpZmYob2xkT2JqLCBuZXdPYmosIG9wdGlvbnMpOyB9XG5cbi8vIFRoaXMgZnVuY3Rpb24gaGFuZGxlcyB0aGUgcHJlc2VuY2Ugb2YgY2lyY3VsYXIgcmVmZXJlbmNlcyBieSBiYWlsaW5nIG91dCB3aGVuIGVuY291bnRlcmluZyBhblxuLy8gb2JqZWN0IHRoYXQgaXMgYWxyZWFkeSBvbiB0aGUgXCJzdGFja1wiIG9mIGl0ZW1zIGJlaW5nIHByb2Nlc3NlZC5cbmV4cG9ydCBmdW5jdGlvbiBjYW5vbmljYWxpemUob2JqLCBzdGFjaywgcmVwbGFjZW1lbnRTdGFjaykge1xuICBzdGFjayA9IHN0YWNrIHx8IFtdO1xuICByZXBsYWNlbWVudFN0YWNrID0gcmVwbGFjZW1lbnRTdGFjayB8fCBbXTtcblxuICBsZXQgaTtcblxuICBmb3IgKGkgPSAwOyBpIDwgc3RhY2subGVuZ3RoOyBpICs9IDEpIHtcbiAgICBpZiAoc3RhY2tbaV0gPT09IG9iaikge1xuICAgICAgcmV0dXJuIHJlcGxhY2VtZW50U3RhY2tbaV07XG4gICAgfVxuICB9XG5cbiAgbGV0IGNhbm9uaWNhbGl6ZWRPYmo7XG5cbiAgaWYgKCdbb2JqZWN0IEFycmF5XScgPT09IG9iamVjdFByb3RvdHlwZVRvU3RyaW5nLmNhbGwob2JqKSkge1xuICAgIHN0YWNrLnB1c2gob2JqKTtcbiAgICBjYW5vbmljYWxpemVkT2JqID0gbmV3IEFycmF5KG9iai5sZW5ndGgpO1xuICAgIHJlcGxhY2VtZW50U3RhY2sucHVzaChjYW5vbmljYWxpemVkT2JqKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjYW5vbmljYWxpemVkT2JqW2ldID0gY2Fub25pY2FsaXplKG9ialtpXSwgc3RhY2ssIHJlcGxhY2VtZW50U3RhY2spO1xuICAgIH1cbiAgICBzdGFjay5wb3AoKTtcbiAgICByZXBsYWNlbWVudFN0YWNrLnBvcCgpO1xuICAgIHJldHVybiBjYW5vbmljYWxpemVkT2JqO1xuICB9XG5cbiAgaWYgKG9iaiAmJiBvYmoudG9KU09OKSB7XG4gICAgb2JqID0gb2JqLnRvSlNPTigpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIG9iaiAhPT0gbnVsbCkge1xuICAgIHN0YWNrLnB1c2gob2JqKTtcbiAgICBjYW5vbmljYWxpemVkT2JqID0ge307XG4gICAgcmVwbGFjZW1lbnRTdGFjay5wdXNoKGNhbm9uaWNhbGl6ZWRPYmopO1xuICAgIGxldCBzb3J0ZWRLZXlzID0gW10sXG4gICAgICAgIGtleTtcbiAgICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgc29ydGVkS2V5cy5wdXNoKGtleSk7XG4gICAgICB9XG4gICAgfVxuICAgIHNvcnRlZEtleXMuc29ydCgpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBzb3J0ZWRLZXlzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBrZXkgPSBzb3J0ZWRLZXlzW2ldO1xuICAgICAgY2Fub25pY2FsaXplZE9ialtrZXldID0gY2Fub25pY2FsaXplKG9ialtrZXldLCBzdGFjaywgcmVwbGFjZW1lbnRTdGFjayk7XG4gICAgfVxuICAgIHN0YWNrLnBvcCgpO1xuICAgIHJlcGxhY2VtZW50U3RhY2sucG9wKCk7XG4gIH0gZWxzZSB7XG4gICAgY2Fub25pY2FsaXplZE9iaiA9IG9iajtcbiAgfVxuICByZXR1cm4gY2Fub25pY2FsaXplZE9iajtcbn1cbiIsImltcG9ydCBEaWZmIGZyb20gJy4vYmFzZSc7XG5pbXBvcnQge2dlbmVyYXRlT3B0aW9uc30gZnJvbSAnLi4vdXRpbC9wYXJhbXMnO1xuXG5leHBvcnQgY29uc3QgbGluZURpZmYgPSBuZXcgRGlmZigpO1xubGluZURpZmYudG9rZW5pemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICBsZXQgcmV0TGluZXMgPSBbXSxcbiAgICAgIGxpbmVzQW5kTmV3bGluZXMgPSB2YWx1ZS5zcGxpdCgvKFxcbnxcXHJcXG4pLyk7XG5cbiAgLy8gSWdub3JlIHRoZSBmaW5hbCBlbXB0eSB0b2tlbiB0aGF0IG9jY3VycyBpZiB0aGUgc3RyaW5nIGVuZHMgd2l0aCBhIG5ldyBsaW5lXG4gIGlmICghbGluZXNBbmROZXdsaW5lc1tsaW5lc0FuZE5ld2xpbmVzLmxlbmd0aCAtIDFdKSB7XG4gICAgbGluZXNBbmROZXdsaW5lcy5wb3AoKTtcbiAgfVxuXG4gIC8vIE1lcmdlIHRoZSBjb250ZW50IGFuZCBsaW5lIHNlcGFyYXRvcnMgaW50byBzaW5nbGUgdG9rZW5zXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXNBbmROZXdsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgIGxldCBsaW5lID0gbGluZXNBbmROZXdsaW5lc1tpXTtcblxuICAgIGlmIChpICUgMiAmJiAhdGhpcy5vcHRpb25zLm5ld2xpbmVJc1Rva2VuKSB7XG4gICAgICByZXRMaW5lc1tyZXRMaW5lcy5sZW5ndGggLSAxXSArPSBsaW5lO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmlnbm9yZVdoaXRlc3BhY2UpIHtcbiAgICAgICAgbGluZSA9IGxpbmUudHJpbSgpO1xuICAgICAgfVxuICAgICAgcmV0TGluZXMucHVzaChsaW5lKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmV0TGluZXM7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGlmZkxpbmVzKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjaykgeyByZXR1cm4gbGluZURpZmYuZGlmZihvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spOyB9XG5leHBvcnQgZnVuY3Rpb24gZGlmZlRyaW1tZWRMaW5lcyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHtcbiAgbGV0IG9wdGlvbnMgPSBnZW5lcmF0ZU9wdGlvbnMoY2FsbGJhY2ssIHtpZ25vcmVXaGl0ZXNwYWNlOiB0cnVlfSk7XG4gIHJldHVybiBsaW5lRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBvcHRpb25zKTtcbn1cbiIsImltcG9ydCBEaWZmIGZyb20gJy4vYmFzZSc7XG5cblxuZXhwb3J0IGNvbnN0IHNlbnRlbmNlRGlmZiA9IG5ldyBEaWZmKCk7XG5zZW50ZW5jZURpZmYudG9rZW5pemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUuc3BsaXQoLyhcXFMuKz9bLiE/XSkoPz1cXHMrfCQpLyk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGlmZlNlbnRlbmNlcyhvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHsgcmV0dXJuIHNlbnRlbmNlRGlmZi5kaWZmKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjayk7IH1cbiIsImltcG9ydCBEaWZmIGZyb20gJy4vYmFzZSc7XG5pbXBvcnQge2dlbmVyYXRlT3B0aW9uc30gZnJvbSAnLi4vdXRpbC9wYXJhbXMnO1xuXG4vLyBCYXNlZCBvbiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MYXRpbl9zY3JpcHRfaW5fVW5pY29kZVxuLy9cbi8vIFJhbmdlcyBhbmQgZXhjZXB0aW9uczpcbi8vIExhdGluLTEgU3VwcGxlbWVudCwgMDA4MOKAkzAwRkZcbi8vICAtIFUrMDBENyAgw5cgTXVsdGlwbGljYXRpb24gc2lnblxuLy8gIC0gVSswMEY3ICDDtyBEaXZpc2lvbiBzaWduXG4vLyBMYXRpbiBFeHRlbmRlZC1BLCAwMTAw4oCTMDE3RlxuLy8gTGF0aW4gRXh0ZW5kZWQtQiwgMDE4MOKAkzAyNEZcbi8vIElQQSBFeHRlbnNpb25zLCAwMjUw4oCTMDJBRlxuLy8gU3BhY2luZyBNb2RpZmllciBMZXR0ZXJzLCAwMkIw4oCTMDJGRlxuLy8gIC0gVSswMkM3ICDLhyAmIzcxMTsgIENhcm9uXG4vLyAgLSBVKzAyRDggIMuYICYjNzI4OyAgQnJldmVcbi8vICAtIFUrMDJEOSAgy5kgJiM3Mjk7ICBEb3QgQWJvdmVcbi8vICAtIFUrMDJEQSAgy5ogJiM3MzA7ICBSaW5nIEFib3ZlXG4vLyAgLSBVKzAyREIgIMubICYjNzMxOyAgT2dvbmVrXG4vLyAgLSBVKzAyREMgIMucICYjNzMyOyAgU21hbGwgVGlsZGVcbi8vICAtIFUrMDJERCAgy50gJiM3MzM7ICBEb3VibGUgQWN1dGUgQWNjZW50XG4vLyBMYXRpbiBFeHRlbmRlZCBBZGRpdGlvbmFsLCAxRTAw4oCTMUVGRlxuY29uc3QgZXh0ZW5kZWRXb3JkQ2hhcnMgPSAvXlthLXpBLVpcXHV7QzB9LVxcdXtGRn1cXHV7RDh9LVxcdXtGNn1cXHV7Rjh9LVxcdXsyQzZ9XFx1ezJDOH0tXFx1ezJEN31cXHV7MkRFfS1cXHV7MkZGfVxcdXsxRTAwfS1cXHV7MUVGRn1dKyQvdTtcblxuY29uc3QgcmVXaGl0ZXNwYWNlID0gL1xcUy87XG5cbmV4cG9ydCBjb25zdCB3b3JkRGlmZiA9IG5ldyBEaWZmKCk7XG53b3JkRGlmZi5lcXVhbHMgPSBmdW5jdGlvbihsZWZ0LCByaWdodCkge1xuICByZXR1cm4gbGVmdCA9PT0gcmlnaHQgfHwgKHRoaXMub3B0aW9ucy5pZ25vcmVXaGl0ZXNwYWNlICYmICFyZVdoaXRlc3BhY2UudGVzdChsZWZ0KSAmJiAhcmVXaGl0ZXNwYWNlLnRlc3QocmlnaHQpKTtcbn07XG53b3JkRGlmZi50b2tlbml6ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIGxldCB0b2tlbnMgPSB2YWx1ZS5zcGxpdCgvKFxccyt8XFxiKS8pO1xuXG4gIC8vIEpvaW4gdGhlIGJvdW5kYXJ5IHNwbGl0cyB0aGF0IHdlIGRvIG5vdCBjb25zaWRlciB0byBiZSBib3VuZGFyaWVzLiBUaGlzIGlzIHByaW1hcmlseSB0aGUgZXh0ZW5kZWQgTGF0aW4gY2hhcmFjdGVyIHNldC5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgLy8gSWYgd2UgaGF2ZSBhbiBlbXB0eSBzdHJpbmcgaW4gdGhlIG5leHQgZmllbGQgYW5kIHdlIGhhdmUgb25seSB3b3JkIGNoYXJzIGJlZm9yZSBhbmQgYWZ0ZXIsIG1lcmdlXG4gICAgaWYgKCF0b2tlbnNbaSArIDFdICYmIHRva2Vuc1tpICsgMl1cbiAgICAgICAgICAmJiBleHRlbmRlZFdvcmRDaGFycy50ZXN0KHRva2Vuc1tpXSlcbiAgICAgICAgICAmJiBleHRlbmRlZFdvcmRDaGFycy50ZXN0KHRva2Vuc1tpICsgMl0pKSB7XG4gICAgICB0b2tlbnNbaV0gKz0gdG9rZW5zW2kgKyAyXTtcbiAgICAgIHRva2Vucy5zcGxpY2UoaSArIDEsIDIpO1xuICAgICAgaS0tO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0b2tlbnM7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZGlmZldvcmRzKG9sZFN0ciwgbmV3U3RyLCBjYWxsYmFjaykge1xuICBsZXQgb3B0aW9ucyA9IGdlbmVyYXRlT3B0aW9ucyhjYWxsYmFjaywge2lnbm9yZVdoaXRlc3BhY2U6IHRydWV9KTtcbiAgcmV0dXJuIHdvcmREaWZmLmRpZmYob2xkU3RyLCBuZXdTdHIsIG9wdGlvbnMpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGRpZmZXb3Jkc1dpdGhTcGFjZShvbGRTdHIsIG5ld1N0ciwgY2FsbGJhY2spIHtcbiAgcmV0dXJuIHdvcmREaWZmLmRpZmYob2xkU3RyLCBuZXdTdHIsIGNhbGxiYWNrKTtcbn1cbiIsIi8qIFNlZSBMSUNFTlNFIGZpbGUgZm9yIHRlcm1zIG9mIHVzZSAqL1xuXG4vKlxuICogVGV4dCBkaWZmIGltcGxlbWVudGF0aW9uLlxuICpcbiAqIFRoaXMgbGlicmFyeSBzdXBwb3J0cyB0aGUgZm9sbG93aW5nIEFQSVM6XG4gKiBKc0RpZmYuZGlmZkNoYXJzOiBDaGFyYWN0ZXIgYnkgY2hhcmFjdGVyIGRpZmZcbiAqIEpzRGlmZi5kaWZmV29yZHM6IFdvcmQgKGFzIGRlZmluZWQgYnkgXFxiIHJlZ2V4KSBkaWZmIHdoaWNoIGlnbm9yZXMgd2hpdGVzcGFjZVxuICogSnNEaWZmLmRpZmZMaW5lczogTGluZSBiYXNlZCBkaWZmXG4gKlxuICogSnNEaWZmLmRpZmZDc3M6IERpZmYgdGFyZ2V0ZWQgYXQgQ1NTIGNvbnRlbnRcbiAqXG4gKiBUaGVzZSBtZXRob2RzIGFyZSBiYXNlZCBvbiB0aGUgaW1wbGVtZW50YXRpb24gcHJvcG9zZWQgaW5cbiAqIFwiQW4gTyhORCkgRGlmZmVyZW5jZSBBbGdvcml0aG0gYW5kIGl0cyBWYXJpYXRpb25zXCIgKE15ZXJzLCAxOTg2KS5cbiAqIGh0dHA6Ly9jaXRlc2VlcnguaXN0LnBzdS5lZHUvdmlld2RvYy9zdW1tYXJ5P2RvaT0xMC4xLjEuNC42OTI3XG4gKi9cbmltcG9ydCBEaWZmIGZyb20gJy4vZGlmZi9iYXNlJztcbmltcG9ydCB7ZGlmZkNoYXJzfSBmcm9tICcuL2RpZmYvY2hhcmFjdGVyJztcbmltcG9ydCB7ZGlmZldvcmRzLCBkaWZmV29yZHNXaXRoU3BhY2V9IGZyb20gJy4vZGlmZi93b3JkJztcbmltcG9ydCB7ZGlmZkxpbmVzLCBkaWZmVHJpbW1lZExpbmVzfSBmcm9tICcuL2RpZmYvbGluZSc7XG5pbXBvcnQge2RpZmZTZW50ZW5jZXN9IGZyb20gJy4vZGlmZi9zZW50ZW5jZSc7XG5cbmltcG9ydCB7ZGlmZkNzc30gZnJvbSAnLi9kaWZmL2Nzcyc7XG5pbXBvcnQge2RpZmZKc29uLCBjYW5vbmljYWxpemV9IGZyb20gJy4vZGlmZi9qc29uJztcblxuaW1wb3J0IHtkaWZmQXJyYXlzfSBmcm9tICcuL2RpZmYvYXJyYXknO1xuXG5pbXBvcnQge2FwcGx5UGF0Y2gsIGFwcGx5UGF0Y2hlc30gZnJvbSAnLi9wYXRjaC9hcHBseSc7XG5pbXBvcnQge3BhcnNlUGF0Y2h9IGZyb20gJy4vcGF0Y2gvcGFyc2UnO1xuaW1wb3J0IHtzdHJ1Y3R1cmVkUGF0Y2gsIGNyZWF0ZVR3b0ZpbGVzUGF0Y2gsIGNyZWF0ZVBhdGNofSBmcm9tICcuL3BhdGNoL2NyZWF0ZSc7XG5cbmltcG9ydCB7Y29udmVydENoYW5nZXNUb0RNUH0gZnJvbSAnLi9jb252ZXJ0L2RtcCc7XG5pbXBvcnQge2NvbnZlcnRDaGFuZ2VzVG9YTUx9IGZyb20gJy4vY29udmVydC94bWwnO1xuXG5leHBvcnQge1xuICBEaWZmLFxuXG4gIGRpZmZDaGFycyxcbiAgZGlmZldvcmRzLFxuICBkaWZmV29yZHNXaXRoU3BhY2UsXG4gIGRpZmZMaW5lcyxcbiAgZGlmZlRyaW1tZWRMaW5lcyxcbiAgZGlmZlNlbnRlbmNlcyxcblxuICBkaWZmQ3NzLFxuICBkaWZmSnNvbixcblxuICBkaWZmQXJyYXlzLFxuXG4gIHN0cnVjdHVyZWRQYXRjaCxcbiAgY3JlYXRlVHdvRmlsZXNQYXRjaCxcbiAgY3JlYXRlUGF0Y2gsXG4gIGFwcGx5UGF0Y2gsXG4gIGFwcGx5UGF0Y2hlcyxcbiAgcGFyc2VQYXRjaCxcbiAgY29udmVydENoYW5nZXNUb0RNUCxcbiAgY29udmVydENoYW5nZXNUb1hNTCxcbiAgY2Fub25pY2FsaXplXG59O1xuIiwiaW1wb3J0IHtwYXJzZVBhdGNofSBmcm9tICcuL3BhcnNlJztcbmltcG9ydCBkaXN0YW5jZUl0ZXJhdG9yIGZyb20gJy4uL3V0aWwvZGlzdGFuY2UtaXRlcmF0b3InO1xuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlQYXRjaChzb3VyY2UsIHVuaURpZmYsIG9wdGlvbnMgPSB7fSkge1xuICBpZiAodHlwZW9mIHVuaURpZmYgPT09ICdzdHJpbmcnKSB7XG4gICAgdW5pRGlmZiA9IHBhcnNlUGF0Y2godW5pRGlmZik7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheSh1bmlEaWZmKSkge1xuICAgIGlmICh1bmlEaWZmLmxlbmd0aCA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYXBwbHlQYXRjaCBvbmx5IHdvcmtzIHdpdGggYSBzaW5nbGUgaW5wdXQuJyk7XG4gICAgfVxuXG4gICAgdW5pRGlmZiA9IHVuaURpZmZbMF07XG4gIH1cblxuICAvLyBBcHBseSB0aGUgZGlmZiB0byB0aGUgaW5wdXRcbiAgbGV0IGxpbmVzID0gc291cmNlLnNwbGl0KC9cXHJcXG58W1xcblxcdlxcZlxcclxceDg1XS8pLFxuICAgICAgZGVsaW1pdGVycyA9IHNvdXJjZS5tYXRjaCgvXFxyXFxufFtcXG5cXHZcXGZcXHJcXHg4NV0vZykgfHwgW10sXG4gICAgICBodW5rcyA9IHVuaURpZmYuaHVua3MsXG5cbiAgICAgIGNvbXBhcmVMaW5lID0gb3B0aW9ucy5jb21wYXJlTGluZSB8fCAoKGxpbmVOdW1iZXIsIGxpbmUsIG9wZXJhdGlvbiwgcGF0Y2hDb250ZW50KSA9PiBsaW5lID09PSBwYXRjaENvbnRlbnQpLFxuICAgICAgZXJyb3JDb3VudCA9IDAsXG4gICAgICBmdXp6RmFjdG9yID0gb3B0aW9ucy5mdXp6RmFjdG9yIHx8IDAsXG4gICAgICBtaW5MaW5lID0gMCxcbiAgICAgIG9mZnNldCA9IDAsXG5cbiAgICAgIHJlbW92ZUVPRk5MLFxuICAgICAgYWRkRU9GTkw7XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiB0aGUgaHVuayBleGFjdGx5IGZpdHMgb24gdGhlIHByb3ZpZGVkIGxvY2F0aW9uXG4gICAqL1xuICBmdW5jdGlvbiBodW5rRml0cyhodW5rLCB0b1Bvcykge1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaHVuay5saW5lcy5sZW5ndGg7IGorKykge1xuICAgICAgbGV0IGxpbmUgPSBodW5rLmxpbmVzW2pdLFxuICAgICAgICAgIG9wZXJhdGlvbiA9IGxpbmVbMF0sXG4gICAgICAgICAgY29udGVudCA9IGxpbmUuc3Vic3RyKDEpO1xuXG4gICAgICBpZiAob3BlcmF0aW9uID09PSAnICcgfHwgb3BlcmF0aW9uID09PSAnLScpIHtcbiAgICAgICAgLy8gQ29udGV4dCBzYW5pdHkgY2hlY2tcbiAgICAgICAgaWYgKCFjb21wYXJlTGluZSh0b1BvcyArIDEsIGxpbmVzW3RvUG9zXSwgb3BlcmF0aW9uLCBjb250ZW50KSkge1xuICAgICAgICAgIGVycm9yQ291bnQrKztcblxuICAgICAgICAgIGlmIChlcnJvckNvdW50ID4gZnV6ekZhY3Rvcikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0b1BvcysrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLy8gU2VhcmNoIGJlc3QgZml0IG9mZnNldHMgZm9yIGVhY2ggaHVuayBiYXNlZCBvbiB0aGUgcHJldmlvdXMgb25lc1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGh1bmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IGh1bmsgPSBodW5rc1tpXSxcbiAgICAgICAgbWF4TGluZSA9IGxpbmVzLmxlbmd0aCAtIGh1bmsub2xkTGluZXMsXG4gICAgICAgIGxvY2FsT2Zmc2V0ID0gMCxcbiAgICAgICAgdG9Qb3MgPSBvZmZzZXQgKyBodW5rLm9sZFN0YXJ0IC0gMTtcblxuICAgIGxldCBpdGVyYXRvciA9IGRpc3RhbmNlSXRlcmF0b3IodG9Qb3MsIG1pbkxpbmUsIG1heExpbmUpO1xuXG4gICAgZm9yICg7IGxvY2FsT2Zmc2V0ICE9PSB1bmRlZmluZWQ7IGxvY2FsT2Zmc2V0ID0gaXRlcmF0b3IoKSkge1xuICAgICAgaWYgKGh1bmtGaXRzKGh1bmssIHRvUG9zICsgbG9jYWxPZmZzZXQpKSB7XG4gICAgICAgIGh1bmsub2Zmc2V0ID0gb2Zmc2V0ICs9IGxvY2FsT2Zmc2V0O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobG9jYWxPZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFNldCBsb3dlciB0ZXh0IGxpbWl0IHRvIGVuZCBvZiB0aGUgY3VycmVudCBodW5rLCBzbyBuZXh0IG9uZXMgZG9uJ3QgdHJ5XG4gICAgLy8gdG8gZml0IG92ZXIgYWxyZWFkeSBwYXRjaGVkIHRleHRcbiAgICBtaW5MaW5lID0gaHVuay5vZmZzZXQgKyBodW5rLm9sZFN0YXJ0ICsgaHVuay5vbGRMaW5lcztcbiAgfVxuXG4gIC8vIEFwcGx5IHBhdGNoIGh1bmtzXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaHVua3MubGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgaHVuayA9IGh1bmtzW2ldLFxuICAgICAgICB0b1BvcyA9IGh1bmsub2Zmc2V0ICsgaHVuay5uZXdTdGFydCAtIDE7XG4gICAgaWYgKGh1bmsubmV3TGluZXMgPT0gMCkgeyB0b1BvcysrOyB9XG5cbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGh1bmsubGluZXMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGxldCBsaW5lID0gaHVuay5saW5lc1tqXSxcbiAgICAgICAgICBvcGVyYXRpb24gPSBsaW5lWzBdLFxuICAgICAgICAgIGNvbnRlbnQgPSBsaW5lLnN1YnN0cigxKSxcbiAgICAgICAgICBkZWxpbWl0ZXIgPSBodW5rLmxpbmVkZWxpbWl0ZXJzW2pdO1xuXG4gICAgICBpZiAob3BlcmF0aW9uID09PSAnICcpIHtcbiAgICAgICAgdG9Qb3MrKztcbiAgICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uID09PSAnLScpIHtcbiAgICAgICAgbGluZXMuc3BsaWNlKHRvUG9zLCAxKTtcbiAgICAgICAgZGVsaW1pdGVycy5zcGxpY2UodG9Qb3MsIDEpO1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uID09PSAnKycpIHtcbiAgICAgICAgbGluZXMuc3BsaWNlKHRvUG9zLCAwLCBjb250ZW50KTtcbiAgICAgICAgZGVsaW1pdGVycy5zcGxpY2UodG9Qb3MsIDAsIGRlbGltaXRlcik7XG4gICAgICAgIHRvUG9zKys7XG4gICAgICB9IGVsc2UgaWYgKG9wZXJhdGlvbiA9PT0gJ1xcXFwnKSB7XG4gICAgICAgIGxldCBwcmV2aW91c09wZXJhdGlvbiA9IGh1bmsubGluZXNbaiAtIDFdID8gaHVuay5saW5lc1tqIC0gMV1bMF0gOiBudWxsO1xuICAgICAgICBpZiAocHJldmlvdXNPcGVyYXRpb24gPT09ICcrJykge1xuICAgICAgICAgIHJlbW92ZUVPRk5MID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChwcmV2aW91c09wZXJhdGlvbiA9PT0gJy0nKSB7XG4gICAgICAgICAgYWRkRU9GTkwgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gSGFuZGxlIEVPRk5MIGluc2VydGlvbi9yZW1vdmFsXG4gIGlmIChyZW1vdmVFT0ZOTCkge1xuICAgIHdoaWxlICghbGluZXNbbGluZXMubGVuZ3RoIC0gMV0pIHtcbiAgICAgIGxpbmVzLnBvcCgpO1xuICAgICAgZGVsaW1pdGVycy5wb3AoKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoYWRkRU9GTkwpIHtcbiAgICBsaW5lcy5wdXNoKCcnKTtcbiAgICBkZWxpbWl0ZXJzLnB1c2goJ1xcbicpO1xuICB9XG4gIGZvciAobGV0IF9rID0gMDsgX2sgPCBsaW5lcy5sZW5ndGggLSAxOyBfaysrKSB7XG4gICAgbGluZXNbX2tdID0gbGluZXNbX2tdICsgZGVsaW1pdGVyc1tfa107XG4gIH1cbiAgcmV0dXJuIGxpbmVzLmpvaW4oJycpO1xufVxuXG4vLyBXcmFwcGVyIHRoYXQgc3VwcG9ydHMgbXVsdGlwbGUgZmlsZSBwYXRjaGVzIHZpYSBjYWxsYmFja3MuXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlQYXRjaGVzKHVuaURpZmYsIG9wdGlvbnMpIHtcbiAgaWYgKHR5cGVvZiB1bmlEaWZmID09PSAnc3RyaW5nJykge1xuICAgIHVuaURpZmYgPSBwYXJzZVBhdGNoKHVuaURpZmYpO1xuICB9XG5cbiAgbGV0IGN1cnJlbnRJbmRleCA9IDA7XG4gIGZ1bmN0aW9uIHByb2Nlc3NJbmRleCgpIHtcbiAgICBsZXQgaW5kZXggPSB1bmlEaWZmW2N1cnJlbnRJbmRleCsrXTtcbiAgICBpZiAoIWluZGV4KSB7XG4gICAgICByZXR1cm4gb3B0aW9ucy5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIG9wdGlvbnMubG9hZEZpbGUoaW5kZXgsIGZ1bmN0aW9uKGVyciwgZGF0YSkge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICByZXR1cm4gb3B0aW9ucy5jb21wbGV0ZShlcnIpO1xuICAgICAgfVxuXG4gICAgICBsZXQgdXBkYXRlZENvbnRlbnQgPSBhcHBseVBhdGNoKGRhdGEsIGluZGV4LCBvcHRpb25zKTtcbiAgICAgIG9wdGlvbnMucGF0Y2hlZChpbmRleCwgdXBkYXRlZENvbnRlbnQsIGZ1bmN0aW9uKGVycikge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgcmV0dXJuIG9wdGlvbnMuY29tcGxldGUoZXJyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHByb2Nlc3NJbmRleCgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgcHJvY2Vzc0luZGV4KCk7XG59XG4iLCJpbXBvcnQge2RpZmZMaW5lc30gZnJvbSAnLi4vZGlmZi9saW5lJztcblxuZXhwb3J0IGZ1bmN0aW9uIHN0cnVjdHVyZWRQYXRjaChvbGRGaWxlTmFtZSwgbmV3RmlsZU5hbWUsIG9sZFN0ciwgbmV3U3RyLCBvbGRIZWFkZXIsIG5ld0hlYWRlciwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0ge307XG4gIH1cbiAgaWYgKHR5cGVvZiBvcHRpb25zLmNvbnRleHQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgb3B0aW9ucy5jb250ZXh0ID0gNDtcbiAgfVxuXG4gIGNvbnN0IGRpZmYgPSBkaWZmTGluZXMob2xkU3RyLCBuZXdTdHIsIG9wdGlvbnMpO1xuICBkaWZmLnB1c2goe3ZhbHVlOiAnJywgbGluZXM6IFtdfSk7ICAgLy8gQXBwZW5kIGFuIGVtcHR5IHZhbHVlIHRvIG1ha2UgY2xlYW51cCBlYXNpZXJcblxuICBmdW5jdGlvbiBjb250ZXh0TGluZXMobGluZXMpIHtcbiAgICByZXR1cm4gbGluZXMubWFwKGZ1bmN0aW9uKGVudHJ5KSB7IHJldHVybiAnICcgKyBlbnRyeTsgfSk7XG4gIH1cblxuICBsZXQgaHVua3MgPSBbXTtcbiAgbGV0IG9sZFJhbmdlU3RhcnQgPSAwLCBuZXdSYW5nZVN0YXJ0ID0gMCwgY3VyUmFuZ2UgPSBbXSxcbiAgICAgIG9sZExpbmUgPSAxLCBuZXdMaW5lID0gMTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkaWZmLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY3VycmVudCA9IGRpZmZbaV0sXG4gICAgICAgICAgbGluZXMgPSBjdXJyZW50LmxpbmVzIHx8IGN1cnJlbnQudmFsdWUucmVwbGFjZSgvXFxuJC8sICcnKS5zcGxpdCgnXFxuJyk7XG4gICAgY3VycmVudC5saW5lcyA9IGxpbmVzO1xuXG4gICAgaWYgKGN1cnJlbnQuYWRkZWQgfHwgY3VycmVudC5yZW1vdmVkKSB7XG4gICAgICAvLyBJZiB3ZSBoYXZlIHByZXZpb3VzIGNvbnRleHQsIHN0YXJ0IHdpdGggdGhhdFxuICAgICAgaWYgKCFvbGRSYW5nZVN0YXJ0KSB7XG4gICAgICAgIGNvbnN0IHByZXYgPSBkaWZmW2kgLSAxXTtcbiAgICAgICAgb2xkUmFuZ2VTdGFydCA9IG9sZExpbmU7XG4gICAgICAgIG5ld1JhbmdlU3RhcnQgPSBuZXdMaW5lO1xuXG4gICAgICAgIGlmIChwcmV2KSB7XG4gICAgICAgICAgY3VyUmFuZ2UgPSBvcHRpb25zLmNvbnRleHQgPiAwID8gY29udGV4dExpbmVzKHByZXYubGluZXMuc2xpY2UoLW9wdGlvbnMuY29udGV4dCkpIDogW107XG4gICAgICAgICAgb2xkUmFuZ2VTdGFydCAtPSBjdXJSYW5nZS5sZW5ndGg7XG4gICAgICAgICAgbmV3UmFuZ2VTdGFydCAtPSBjdXJSYW5nZS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gT3V0cHV0IG91ciBjaGFuZ2VzXG4gICAgICBjdXJSYW5nZS5wdXNoKC4uLiBsaW5lcy5tYXAoZnVuY3Rpb24oZW50cnkpIHtcbiAgICAgICAgcmV0dXJuIChjdXJyZW50LmFkZGVkID8gJysnIDogJy0nKSArIGVudHJ5O1xuICAgICAgfSkpO1xuXG4gICAgICAvLyBUcmFjayB0aGUgdXBkYXRlZCBmaWxlIHBvc2l0aW9uXG4gICAgICBpZiAoY3VycmVudC5hZGRlZCkge1xuICAgICAgICBuZXdMaW5lICs9IGxpbmVzLmxlbmd0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9sZExpbmUgKz0gbGluZXMubGVuZ3RoO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZGVudGljYWwgY29udGV4dCBsaW5lcy4gVHJhY2sgbGluZSBjaGFuZ2VzXG4gICAgICBpZiAob2xkUmFuZ2VTdGFydCkge1xuICAgICAgICAvLyBDbG9zZSBvdXQgYW55IGNoYW5nZXMgdGhhdCBoYXZlIGJlZW4gb3V0cHV0IChvciBqb2luIG92ZXJsYXBwaW5nKVxuICAgICAgICBpZiAobGluZXMubGVuZ3RoIDw9IG9wdGlvbnMuY29udGV4dCAqIDIgJiYgaSA8IGRpZmYubGVuZ3RoIC0gMikge1xuICAgICAgICAgIC8vIE92ZXJsYXBwaW5nXG4gICAgICAgICAgY3VyUmFuZ2UucHVzaCguLi4gY29udGV4dExpbmVzKGxpbmVzKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gZW5kIHRoZSByYW5nZSBhbmQgb3V0cHV0XG4gICAgICAgICAgbGV0IGNvbnRleHRTaXplID0gTWF0aC5taW4obGluZXMubGVuZ3RoLCBvcHRpb25zLmNvbnRleHQpO1xuICAgICAgICAgIGN1clJhbmdlLnB1c2goLi4uIGNvbnRleHRMaW5lcyhsaW5lcy5zbGljZSgwLCBjb250ZXh0U2l6ZSkpKTtcblxuICAgICAgICAgIGxldCBodW5rID0ge1xuICAgICAgICAgICAgb2xkU3RhcnQ6IG9sZFJhbmdlU3RhcnQsXG4gICAgICAgICAgICBvbGRMaW5lczogKG9sZExpbmUgLSBvbGRSYW5nZVN0YXJ0ICsgY29udGV4dFNpemUpLFxuICAgICAgICAgICAgbmV3U3RhcnQ6IG5ld1JhbmdlU3RhcnQsXG4gICAgICAgICAgICBuZXdMaW5lczogKG5ld0xpbmUgLSBuZXdSYW5nZVN0YXJ0ICsgY29udGV4dFNpemUpLFxuICAgICAgICAgICAgbGluZXM6IGN1clJhbmdlXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAoaSA+PSBkaWZmLmxlbmd0aCAtIDIgJiYgbGluZXMubGVuZ3RoIDw9IG9wdGlvbnMuY29udGV4dCkge1xuICAgICAgICAgICAgLy8gRU9GIGlzIGluc2lkZSB0aGlzIGh1bmtcbiAgICAgICAgICAgIGxldCBvbGRFT0ZOZXdsaW5lID0gKC9cXG4kLy50ZXN0KG9sZFN0cikpO1xuICAgICAgICAgICAgbGV0IG5ld0VPRk5ld2xpbmUgPSAoL1xcbiQvLnRlc3QobmV3U3RyKSk7XG4gICAgICAgICAgICBpZiAobGluZXMubGVuZ3RoID09IDAgJiYgIW9sZEVPRk5ld2xpbmUpIHtcbiAgICAgICAgICAgICAgLy8gc3BlY2lhbCBjYXNlOiBvbGQgaGFzIG5vIGVvbCBhbmQgbm8gdHJhaWxpbmcgY29udGV4dDsgbm8tbmwgY2FuIGVuZCB1cCBiZWZvcmUgYWRkc1xuICAgICAgICAgICAgICBjdXJSYW5nZS5zcGxpY2UoaHVuay5vbGRMaW5lcywgMCwgJ1xcXFwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZScpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghb2xkRU9GTmV3bGluZSB8fCAhbmV3RU9GTmV3bGluZSkge1xuICAgICAgICAgICAgICBjdXJSYW5nZS5wdXNoKCdcXFxcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaHVua3MucHVzaChodW5rKTtcblxuICAgICAgICAgIG9sZFJhbmdlU3RhcnQgPSAwO1xuICAgICAgICAgIG5ld1JhbmdlU3RhcnQgPSAwO1xuICAgICAgICAgIGN1clJhbmdlID0gW107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG9sZExpbmUgKz0gbGluZXMubGVuZ3RoO1xuICAgICAgbmV3TGluZSArPSBsaW5lcy5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBvbGRGaWxlTmFtZTogb2xkRmlsZU5hbWUsIG5ld0ZpbGVOYW1lOiBuZXdGaWxlTmFtZSxcbiAgICBvbGRIZWFkZXI6IG9sZEhlYWRlciwgbmV3SGVhZGVyOiBuZXdIZWFkZXIsXG4gICAgaHVua3M6IGh1bmtzXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVUd29GaWxlc1BhdGNoKG9sZEZpbGVOYW1lLCBuZXdGaWxlTmFtZSwgb2xkU3RyLCBuZXdTdHIsIG9sZEhlYWRlciwgbmV3SGVhZGVyLCBvcHRpb25zKSB7XG4gIGNvbnN0IGRpZmYgPSBzdHJ1Y3R1cmVkUGF0Y2gob2xkRmlsZU5hbWUsIG5ld0ZpbGVOYW1lLCBvbGRTdHIsIG5ld1N0ciwgb2xkSGVhZGVyLCBuZXdIZWFkZXIsIG9wdGlvbnMpO1xuXG4gIGNvbnN0IHJldCA9IFtdO1xuICBpZiAob2xkRmlsZU5hbWUgPT0gbmV3RmlsZU5hbWUpIHtcbiAgICByZXQucHVzaCgnSW5kZXg6ICcgKyBvbGRGaWxlTmFtZSk7XG4gIH1cbiAgcmV0LnB1c2goJz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0nKTtcbiAgcmV0LnB1c2goJy0tLSAnICsgZGlmZi5vbGRGaWxlTmFtZSArICh0eXBlb2YgZGlmZi5vbGRIZWFkZXIgPT09ICd1bmRlZmluZWQnID8gJycgOiAnXFx0JyArIGRpZmYub2xkSGVhZGVyKSk7XG4gIHJldC5wdXNoKCcrKysgJyArIGRpZmYubmV3RmlsZU5hbWUgKyAodHlwZW9mIGRpZmYubmV3SGVhZGVyID09PSAndW5kZWZpbmVkJyA/ICcnIDogJ1xcdCcgKyBkaWZmLm5ld0hlYWRlcikpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGlmZi5odW5rcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGh1bmsgPSBkaWZmLmh1bmtzW2ldO1xuICAgIHJldC5wdXNoKFxuICAgICAgJ0BAIC0nICsgaHVuay5vbGRTdGFydCArICcsJyArIGh1bmsub2xkTGluZXNcbiAgICAgICsgJyArJyArIGh1bmsubmV3U3RhcnQgKyAnLCcgKyBodW5rLm5ld0xpbmVzXG4gICAgICArICcgQEAnXG4gICAgKTtcbiAgICByZXQucHVzaC5hcHBseShyZXQsIGh1bmsubGluZXMpO1xuICB9XG5cbiAgcmV0dXJuIHJldC5qb2luKCdcXG4nKSArICdcXG4nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUGF0Y2goZmlsZU5hbWUsIG9sZFN0ciwgbmV3U3RyLCBvbGRIZWFkZXIsIG5ld0hlYWRlciwgb3B0aW9ucykge1xuICByZXR1cm4gY3JlYXRlVHdvRmlsZXNQYXRjaChmaWxlTmFtZSwgZmlsZU5hbWUsIG9sZFN0ciwgbmV3U3RyLCBvbGRIZWFkZXIsIG5ld0hlYWRlciwgb3B0aW9ucyk7XG59XG4iLCJleHBvcnQgZnVuY3Rpb24gcGFyc2VQYXRjaCh1bmlEaWZmLCBvcHRpb25zID0ge30pIHtcbiAgbGV0IGRpZmZzdHIgPSB1bmlEaWZmLnNwbGl0KC9cXHJcXG58W1xcblxcdlxcZlxcclxceDg1XS8pLFxuICAgICAgZGVsaW1pdGVycyA9IHVuaURpZmYubWF0Y2goL1xcclxcbnxbXFxuXFx2XFxmXFxyXFx4ODVdL2cpIHx8IFtdLFxuICAgICAgbGlzdCA9IFtdLFxuICAgICAgaSA9IDA7XG5cbiAgZnVuY3Rpb24gcGFyc2VJbmRleCgpIHtcbiAgICBsZXQgaW5kZXggPSB7fTtcbiAgICBsaXN0LnB1c2goaW5kZXgpO1xuXG4gICAgLy8gUGFyc2UgZGlmZiBtZXRhZGF0YVxuICAgIHdoaWxlIChpIDwgZGlmZnN0ci5sZW5ndGgpIHtcbiAgICAgIGxldCBsaW5lID0gZGlmZnN0cltpXTtcblxuICAgICAgLy8gRmlsZSBoZWFkZXIgZm91bmQsIGVuZCBwYXJzaW5nIGRpZmYgbWV0YWRhdGFcbiAgICAgIGlmICgvXihcXC1cXC1cXC18XFwrXFwrXFwrfEBAKVxccy8udGVzdChsaW5lKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgLy8gRGlmZiBpbmRleFxuICAgICAgbGV0IGhlYWRlciA9ICgvXig/OkluZGV4OnxkaWZmKD86IC1yIFxcdyspKylcXHMrKC4rPylcXHMqJC8pLmV4ZWMobGluZSk7XG4gICAgICBpZiAoaGVhZGVyKSB7XG4gICAgICAgIGluZGV4LmluZGV4ID0gaGVhZGVyWzFdO1xuICAgICAgfVxuXG4gICAgICBpKys7XG4gICAgfVxuXG4gICAgLy8gUGFyc2UgZmlsZSBoZWFkZXJzIGlmIHRoZXkgYXJlIGRlZmluZWQuIFVuaWZpZWQgZGlmZiByZXF1aXJlcyB0aGVtLCBidXRcbiAgICAvLyB0aGVyZSdzIG5vIHRlY2huaWNhbCBpc3N1ZXMgdG8gaGF2ZSBhbiBpc29sYXRlZCBodW5rIHdpdGhvdXQgZmlsZSBoZWFkZXJcbiAgICBwYXJzZUZpbGVIZWFkZXIoaW5kZXgpO1xuICAgIHBhcnNlRmlsZUhlYWRlcihpbmRleCk7XG5cbiAgICAvLyBQYXJzZSBodW5rc1xuICAgIGluZGV4Lmh1bmtzID0gW107XG5cbiAgICB3aGlsZSAoaSA8IGRpZmZzdHIubGVuZ3RoKSB7XG4gICAgICBsZXQgbGluZSA9IGRpZmZzdHJbaV07XG5cbiAgICAgIGlmICgvXihJbmRleDp8ZGlmZnxcXC1cXC1cXC18XFwrXFwrXFwrKVxccy8udGVzdChsaW5lKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH0gZWxzZSBpZiAoL15AQC8udGVzdChsaW5lKSkge1xuICAgICAgICBpbmRleC5odW5rcy5wdXNoKHBhcnNlSHVuaygpKTtcbiAgICAgIH0gZWxzZSBpZiAobGluZSAmJiBvcHRpb25zLnN0cmljdCkge1xuICAgICAgICAvLyBJZ25vcmUgdW5leHBlY3RlZCBjb250ZW50IHVubGVzcyBpbiBzdHJpY3QgbW9kZVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gbGluZSAnICsgKGkgKyAxKSArICcgJyArIEpTT04uc3RyaW5naWZ5KGxpbmUpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGkrKztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBQYXJzZXMgdGhlIC0tLSBhbmQgKysrIGhlYWRlcnMsIGlmIG5vbmUgYXJlIGZvdW5kLCBubyBsaW5lc1xuICAvLyBhcmUgY29uc3VtZWQuXG4gIGZ1bmN0aW9uIHBhcnNlRmlsZUhlYWRlcihpbmRleCkge1xuICAgIGNvbnN0IGhlYWRlclBhdHRlcm4gPSAvXigtLS18XFwrXFwrXFwrKVxccysoW1xcUyBdKikoPzpcXHQoLio/KVxccyopPyQvO1xuICAgIGNvbnN0IGZpbGVIZWFkZXIgPSBoZWFkZXJQYXR0ZXJuLmV4ZWMoZGlmZnN0cltpXSk7XG4gICAgaWYgKGZpbGVIZWFkZXIpIHtcbiAgICAgIGxldCBrZXlQcmVmaXggPSBmaWxlSGVhZGVyWzFdID09PSAnLS0tJyA/ICdvbGQnIDogJ25ldyc7XG4gICAgICBpbmRleFtrZXlQcmVmaXggKyAnRmlsZU5hbWUnXSA9IGZpbGVIZWFkZXJbMl07XG4gICAgICBpbmRleFtrZXlQcmVmaXggKyAnSGVhZGVyJ10gPSBmaWxlSGVhZGVyWzNdO1xuXG4gICAgICBpKys7XG4gICAgfVxuICB9XG5cbiAgLy8gUGFyc2VzIGEgaHVua1xuICAvLyBUaGlzIGFzc3VtZXMgdGhhdCB3ZSBhcmUgYXQgdGhlIHN0YXJ0IG9mIGEgaHVuay5cbiAgZnVuY3Rpb24gcGFyc2VIdW5rKCkge1xuICAgIGxldCBjaHVua0hlYWRlckluZGV4ID0gaSxcbiAgICAgICAgY2h1bmtIZWFkZXJMaW5lID0gZGlmZnN0cltpKytdLFxuICAgICAgICBjaHVua0hlYWRlciA9IGNodW5rSGVhZGVyTGluZS5zcGxpdCgvQEAgLShcXGQrKSg/OiwoXFxkKykpPyBcXCsoXFxkKykoPzosKFxcZCspKT8gQEAvKTtcblxuICAgIGxldCBodW5rID0ge1xuICAgICAgb2xkU3RhcnQ6ICtjaHVua0hlYWRlclsxXSxcbiAgICAgIG9sZExpbmVzOiArY2h1bmtIZWFkZXJbMl0gfHwgMSxcbiAgICAgIG5ld1N0YXJ0OiArY2h1bmtIZWFkZXJbM10sXG4gICAgICBuZXdMaW5lczogK2NodW5rSGVhZGVyWzRdIHx8IDEsXG4gICAgICBsaW5lczogW10sXG4gICAgICBsaW5lZGVsaW1pdGVyczogW11cbiAgICB9O1xuXG4gICAgbGV0IGFkZENvdW50ID0gMCxcbiAgICAgICAgcmVtb3ZlQ291bnQgPSAwO1xuICAgIGZvciAoOyBpIDwgZGlmZnN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgLy8gTGluZXMgc3RhcnRpbmcgd2l0aCAnLS0tJyBjb3VsZCBiZSBtaXN0YWtlbiBmb3IgdGhlIFwicmVtb3ZlIGxpbmVcIiBvcGVyYXRpb25cbiAgICAgIC8vIEJ1dCB0aGV5IGNvdWxkIGJlIHRoZSBoZWFkZXIgZm9yIHRoZSBuZXh0IGZpbGUuIFRoZXJlZm9yZSBwcnVuZSBzdWNoIGNhc2VzIG91dC5cbiAgICAgIGlmIChkaWZmc3RyW2ldLmluZGV4T2YoJy0tLSAnKSA9PT0gMFxuICAgICAgICAgICAgJiYgKGkgKyAyIDwgZGlmZnN0ci5sZW5ndGgpXG4gICAgICAgICAgICAmJiBkaWZmc3RyW2kgKyAxXS5pbmRleE9mKCcrKysgJykgPT09IDBcbiAgICAgICAgICAgICYmIGRpZmZzdHJbaSArIDJdLmluZGV4T2YoJ0BAJykgPT09IDApIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGxldCBvcGVyYXRpb24gPSBkaWZmc3RyW2ldWzBdO1xuXG4gICAgICBpZiAob3BlcmF0aW9uID09PSAnKycgfHwgb3BlcmF0aW9uID09PSAnLScgfHwgb3BlcmF0aW9uID09PSAnICcgfHwgb3BlcmF0aW9uID09PSAnXFxcXCcpIHtcbiAgICAgICAgaHVuay5saW5lcy5wdXNoKGRpZmZzdHJbaV0pO1xuICAgICAgICBodW5rLmxpbmVkZWxpbWl0ZXJzLnB1c2goZGVsaW1pdGVyc1tpXSB8fCAnXFxuJyk7XG5cbiAgICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gJysnKSB7XG4gICAgICAgICAgYWRkQ291bnQrKztcbiAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRpb24gPT09ICctJykge1xuICAgICAgICAgIHJlbW92ZUNvdW50Kys7XG4gICAgICAgIH0gZWxzZSBpZiAob3BlcmF0aW9uID09PSAnICcpIHtcbiAgICAgICAgICBhZGRDb3VudCsrO1xuICAgICAgICAgIHJlbW92ZUNvdW50Kys7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEhhbmRsZSB0aGUgZW1wdHkgYmxvY2sgY291bnQgY2FzZVxuICAgIGlmICghYWRkQ291bnQgJiYgaHVuay5uZXdMaW5lcyA9PT0gMSkge1xuICAgICAgaHVuay5uZXdMaW5lcyA9IDA7XG4gICAgfVxuICAgIGlmICghcmVtb3ZlQ291bnQgJiYgaHVuay5vbGRMaW5lcyA9PT0gMSkge1xuICAgICAgaHVuay5vbGRMaW5lcyA9IDA7XG4gICAgfVxuXG4gICAgLy8gUGVyZm9ybSBvcHRpb25hbCBzYW5pdHkgY2hlY2tpbmdcbiAgICBpZiAob3B0aW9ucy5zdHJpY3QpIHtcbiAgICAgIGlmIChhZGRDb3VudCAhPT0gaHVuay5uZXdMaW5lcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FkZGVkIGxpbmUgY291bnQgZGlkIG5vdCBtYXRjaCBmb3IgaHVuayBhdCBsaW5lICcgKyAoY2h1bmtIZWFkZXJJbmRleCArIDEpKTtcbiAgICAgIH1cbiAgICAgIGlmIChyZW1vdmVDb3VudCAhPT0gaHVuay5vbGRMaW5lcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlbW92ZWQgbGluZSBjb3VudCBkaWQgbm90IG1hdGNoIGZvciBodW5rIGF0IGxpbmUgJyArIChjaHVua0hlYWRlckluZGV4ICsgMSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBodW5rO1xuICB9XG5cbiAgd2hpbGUgKGkgPCBkaWZmc3RyLmxlbmd0aCkge1xuICAgIHBhcnNlSW5kZXgoKTtcbiAgfVxuXG4gIHJldHVybiBsaXN0O1xufVxuIiwiLy8gSXRlcmF0b3IgdGhhdCB0cmF2ZXJzZXMgaW4gdGhlIHJhbmdlIG9mIFttaW4sIG1heF0sIHN0ZXBwaW5nXG4vLyBieSBkaXN0YW5jZSBmcm9tIGEgZ2l2ZW4gc3RhcnQgcG9zaXRpb24uIEkuZS4gZm9yIFswLCA0XSwgd2l0aFxuLy8gc3RhcnQgb2YgMiwgdGhpcyB3aWxsIGl0ZXJhdGUgMiwgMywgMSwgNCwgMC5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKHN0YXJ0LCBtaW5MaW5lLCBtYXhMaW5lKSB7XG4gIGxldCB3YW50Rm9yd2FyZCA9IHRydWUsXG4gICAgICBiYWNrd2FyZEV4aGF1c3RlZCA9IGZhbHNlLFxuICAgICAgZm9yd2FyZEV4aGF1c3RlZCA9IGZhbHNlLFxuICAgICAgbG9jYWxPZmZzZXQgPSAxO1xuXG4gIHJldHVybiBmdW5jdGlvbiBpdGVyYXRvcigpIHtcbiAgICBpZiAod2FudEZvcndhcmQgJiYgIWZvcndhcmRFeGhhdXN0ZWQpIHtcbiAgICAgIGlmIChiYWNrd2FyZEV4aGF1c3RlZCkge1xuICAgICAgICBsb2NhbE9mZnNldCsrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2FudEZvcndhcmQgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgaWYgdHJ5aW5nIHRvIGZpdCBiZXlvbmQgdGV4dCBsZW5ndGgsIGFuZCBpZiBub3QsIGNoZWNrIGl0IGZpdHNcbiAgICAgIC8vIGFmdGVyIG9mZnNldCBsb2NhdGlvbiAob3IgZGVzaXJlZCBsb2NhdGlvbiBvbiBmaXJzdCBpdGVyYXRpb24pXG4gICAgICBpZiAoc3RhcnQgKyBsb2NhbE9mZnNldCA8PSBtYXhMaW5lKSB7XG4gICAgICAgIHJldHVybiBsb2NhbE9mZnNldDtcbiAgICAgIH1cblxuICAgICAgZm9yd2FyZEV4aGF1c3RlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKCFiYWNrd2FyZEV4aGF1c3RlZCkge1xuICAgICAgaWYgKCFmb3J3YXJkRXhoYXVzdGVkKSB7XG4gICAgICAgIHdhbnRGb3J3YXJkID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgLy8gQ2hlY2sgaWYgdHJ5aW5nIHRvIGZpdCBiZWZvcmUgdGV4dCBiZWdpbm5pbmcsIGFuZCBpZiBub3QsIGNoZWNrIGl0IGZpdHNcbiAgICAgIC8vIGJlZm9yZSBvZmZzZXQgbG9jYXRpb25cbiAgICAgIGlmIChtaW5MaW5lIDw9IHN0YXJ0IC0gbG9jYWxPZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIC1sb2NhbE9mZnNldCsrO1xuICAgICAgfVxuXG4gICAgICBiYWNrd2FyZEV4aGF1c3RlZCA9IHRydWU7XG4gICAgICByZXR1cm4gaXRlcmF0b3IoKTtcbiAgICB9XG5cbiAgICAvLyBXZSB0cmllZCB0byBmaXQgaHVuayBiZWZvcmUgdGV4dCBiZWdpbm5pbmcgYW5kIGJleW9uZCB0ZXh0IGxlbmdodCwgdGhlblxuICAgIC8vIGh1bmsgY2FuJ3QgZml0IG9uIHRoZSB0ZXh0LiBSZXR1cm4gdW5kZWZpbmVkXG4gIH07XG59XG4iLCJleHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVPcHRpb25zKG9wdGlvbnMsIGRlZmF1bHRzKSB7XG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGRlZmF1bHRzLmNhbGxiYWNrID0gb3B0aW9ucztcbiAgfSBlbHNlIGlmIChvcHRpb25zKSB7XG4gICAgZm9yIChsZXQgbmFtZSBpbiBvcHRpb25zKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgZGVmYXVsdHNbbmFtZV0gPSBvcHRpb25zW25hbWVdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZGVmYXVsdHM7XG59XG4iLCJcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBmb3JFYWNoIChvYmosIGZuLCBjdHgpIHtcbiAgICBpZiAodG9TdHJpbmcuY2FsbChmbikgIT09ICdbb2JqZWN0IEZ1bmN0aW9uXScpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignaXRlcmF0b3IgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgfVxuICAgIHZhciBsID0gb2JqLmxlbmd0aDtcbiAgICBpZiAobCA9PT0gK2wpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIGZuLmNhbGwoY3R4LCBvYmpbaV0sIGksIG9iaik7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKHZhciBrIGluIG9iaikge1xuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKG9iaiwgaykpIHtcbiAgICAgICAgICAgICAgICBmbi5jYWxsKGN0eCwgb2JqW2tdLCBrLCBvYmopO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufTtcblxuIiwiXG52YXIgaW5kZXhPZiA9IFtdLmluZGV4T2Y7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYXJyLCBvYmope1xuICBpZiAoaW5kZXhPZikgcmV0dXJuIGFyci5pbmRleE9mKG9iaik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGFycltpXSA9PT0gb2JqKSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59OyIsIm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgaGFzT3duID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbnZhciBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gKGZuKSB7XG5cdHJldHVybiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nICYmICEoZm4gaW5zdGFuY2VvZiBSZWdFeHApKSB8fCB0b1N0cmluZy5jYWxsKGZuKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZm9yRWFjaChvYmosIGZuKSB7XG5cdGlmICghaXNGdW5jdGlvbihmbikpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdpdGVyYXRvciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblx0fVxuXHR2YXIgaSwgayxcblx0XHRpc1N0cmluZyA9IHR5cGVvZiBvYmogPT09ICdzdHJpbmcnLFxuXHRcdGwgPSBvYmoubGVuZ3RoLFxuXHRcdGNvbnRleHQgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IG51bGw7XG5cdGlmIChsID09PSArbCkge1xuXHRcdGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHtcblx0XHRcdGlmIChjb250ZXh0ID09PSBudWxsKSB7XG5cdFx0XHRcdGZuKGlzU3RyaW5nID8gb2JqLmNoYXJBdChpKSA6IG9ialtpXSwgaSwgb2JqKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZuLmNhbGwoY29udGV4dCwgaXNTdHJpbmcgPyBvYmouY2hhckF0KGkpIDogb2JqW2ldLCBpLCBvYmopO1xuXHRcdFx0fVxuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRmb3IgKGsgaW4gb2JqKSB7XG5cdFx0XHRpZiAoaGFzT3duLmNhbGwob2JqLCBrKSkge1xuXHRcdFx0XHRpZiAoY29udGV4dCA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdGZuKG9ialtrXSwgaywgb2JqKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRmbi5jYWxsKGNvbnRleHQsIG9ialtrXSwgaywgb2JqKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxufTtcblxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8vIG1vZGlmaWVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2VzLXNoaW1zL2VzNS1zaGltXG52YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSxcblx0dG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLFxuXHRmb3JFYWNoID0gcmVxdWlyZSgnLi9mb3JlYWNoJyksXG5cdGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcblx0aGFzRG9udEVudW1CdWcgPSAhKHsndG9TdHJpbmcnOiBudWxsfSkucHJvcGVydHlJc0VudW1lcmFibGUoJ3RvU3RyaW5nJyksXG5cdGhhc1Byb3RvRW51bUJ1ZyA9IChmdW5jdGlvbiAoKSB7fSkucHJvcGVydHlJc0VudW1lcmFibGUoJ3Byb3RvdHlwZScpLFxuXHRkb250RW51bXMgPSBbXG5cdFx0XCJ0b1N0cmluZ1wiLFxuXHRcdFwidG9Mb2NhbGVTdHJpbmdcIixcblx0XHRcInZhbHVlT2ZcIixcblx0XHRcImhhc093blByb3BlcnR5XCIsXG5cdFx0XCJpc1Byb3RvdHlwZU9mXCIsXG5cdFx0XCJwcm9wZXJ0eUlzRW51bWVyYWJsZVwiLFxuXHRcdFwiY29uc3RydWN0b3JcIlxuXHRdO1xuXG52YXIga2V5c1NoaW0gPSBmdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuXHR2YXIgaXNPYmplY3QgPSBvYmplY3QgIT09IG51bGwgJiYgdHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcsXG5cdFx0aXNGdW5jdGlvbiA9IHRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcblx0XHRpc0FyZ3VtZW50cyA9IGlzQXJncyhvYmplY3QpLFxuXHRcdHRoZUtleXMgPSBbXTtcblxuXHRpZiAoIWlzT2JqZWN0ICYmICFpc0Z1bmN0aW9uICYmICFpc0FyZ3VtZW50cykge1xuXHRcdHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0XCIpO1xuXHR9XG5cblx0aWYgKGlzQXJndW1lbnRzKSB7XG5cdFx0Zm9yRWFjaChvYmplY3QsIGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgpIHtcblx0XHRcdHRoZUtleXMucHVzaChpbmRleCk7XG5cdFx0fSk7XG5cdH0gZWxzZSB7XG5cdFx0dmFyIG5hbWUsXG5cdFx0XHRza2lwUHJvdG8gPSBoYXNQcm90b0VudW1CdWcgJiYgaXNGdW5jdGlvbjtcblxuXHRcdGZvciAobmFtZSBpbiBvYmplY3QpIHtcblx0XHRcdGlmICghKHNraXBQcm90byAmJiBuYW1lID09PSAncHJvdG90eXBlJykgJiYgaGFzLmNhbGwob2JqZWN0LCBuYW1lKSkge1xuXHRcdFx0XHR0aGVLZXlzLnB1c2gobmFtZSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0aWYgKGhhc0RvbnRFbnVtQnVnKSB7XG5cdFx0dmFyIGN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG5cdFx0XHRza2lwQ29uc3RydWN0b3IgPSBjdG9yICYmIGN0b3IucHJvdG90eXBlID09PSBvYmplY3Q7XG5cblx0XHRmb3JFYWNoKGRvbnRFbnVtcywgZnVuY3Rpb24gKGRvbnRFbnVtKSB7XG5cdFx0XHRpZiAoIShza2lwQ29uc3RydWN0b3IgJiYgZG9udEVudW0gPT09ICdjb25zdHJ1Y3RvcicpICYmIGhhcy5jYWxsKG9iamVjdCwgZG9udEVudW0pKSB7XG5cdFx0XHRcdHRoZUtleXMucHVzaChkb250RW51bSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblx0cmV0dXJuIHRoZUtleXM7XG59O1xuXG5rZXlzU2hpbS5zaGltID0gZnVuY3Rpb24gc2hpbU9iamVjdEtleXMoKSB7XG5cdGlmICghT2JqZWN0LmtleXMpIHtcblx0XHRPYmplY3Qua2V5cyA9IGtleXNTaGltO1xuXHR9XG5cdHJldHVybiBPYmplY3Qua2V5cyB8fCBrZXlzU2hpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG5cbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG5cdHZhciBzdHIgPSB0b1N0cmluZy5jYWxsKHZhbHVlKTtcblx0dmFyIGlzQXJndW1lbnRzID0gc3RyID09PSAnW29iamVjdCBBcmd1bWVudHNdJztcblx0aWYgKCFpc0FyZ3VtZW50cykge1xuXHRcdGlzQXJndW1lbnRzID0gc3RyICE9PSAnW29iamVjdCBBcnJheV0nXG5cdFx0XHQmJiB2YWx1ZSAhPT0gbnVsbFxuXHRcdFx0JiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0J1xuXHRcdFx0JiYgdHlwZW9mIHZhbHVlLmxlbmd0aCA9PT0gJ251bWJlcidcblx0XHRcdCYmIHZhbHVlLmxlbmd0aCA+PSAwXG5cdFx0XHQmJiB0b1N0cmluZy5jYWxsKHZhbHVlLmNhbGxlZSkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cdH1cblx0cmV0dXJuIGlzQXJndW1lbnRzO1xufTtcblxuIiwiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIG1hcCA9IHJlcXVpcmUoJ2FycmF5LW1hcCcpO1xudmFyIGluZGV4T2YgPSByZXF1aXJlKCdpbmRleG9mJyk7XG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKTtcbnZhciBmb3JFYWNoID0gcmVxdWlyZSgnZm9yZWFjaCcpO1xudmFyIHJlZHVjZSA9IHJlcXVpcmUoJ2FycmF5LXJlZHVjZScpO1xudmFyIGdldE9iamVjdEtleXMgPSByZXF1aXJlKCdvYmplY3Qta2V5cycpO1xudmFyIEpTT04gPSByZXF1aXJlKCdqc29uMycpO1xuXG4vKipcbiAqIE1ha2Ugc3VyZSBgT2JqZWN0LmtleXNgIHdvcmsgZm9yIGB1bmRlZmluZWRgXG4gKiB2YWx1ZXMgdGhhdCBhcmUgc3RpbGwgdGhlcmUsIGxpa2UgYGRvY3VtZW50LmFsbGAuXG4gKiBodHRwOi8vbGlzdHMudzMub3JnL0FyY2hpdmVzL1B1YmxpYy9wdWJsaWMtaHRtbC8yMDA5SnVuLzA1NDYuaHRtbFxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIG9iamVjdEtleXModmFsKXtcbiAgaWYgKE9iamVjdC5rZXlzKSByZXR1cm4gT2JqZWN0LmtleXModmFsKTtcbiAgcmV0dXJuIGdldE9iamVjdEtleXModmFsKTtcbn1cblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGluc3BlY3Q7XG5cbi8qKlxuICogRWNob3MgdGhlIHZhbHVlIG9mIGEgdmFsdWUuIFRyeXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuICogaW4gdGhlIGJlc3Qgd2F5IHBvc3NpYmxlIGdpdmVuIHRoZSBkaWZmZXJlbnQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIE9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IHRoYXQgYWx0ZXJzIHRoZSBvdXRwdXQuXG4gKiBAbGljZW5zZSBNSVQgKMKpIEpveWVudClcbiAqL1xuLyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuXG5mdW5jdGlvbiBpbnNwZWN0KG9iaiwgb3B0cykge1xuICAvLyBkZWZhdWx0IG9wdGlvbnNcbiAgdmFyIGN0eCA9IHtcbiAgICBzZWVuOiBbXSxcbiAgICBzdHlsaXplOiBzdHlsaXplTm9Db2xvclxuICB9O1xuICAvLyBsZWdhY3kuLi5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykgY3R4LmRlcHRoID0gYXJndW1lbnRzWzJdO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA0KSBjdHguY29sb3JzID0gYXJndW1lbnRzWzNdO1xuICBpZiAoaXNCb29sZWFuKG9wdHMpKSB7XG4gICAgLy8gbGVnYWN5Li4uXG4gICAgY3R4LnNob3dIaWRkZW4gPSBvcHRzO1xuICB9IGVsc2UgaWYgKG9wdHMpIHtcbiAgICAvLyBnb3QgYW4gXCJvcHRpb25zXCIgb2JqZWN0XG4gICAgX2V4dGVuZChjdHgsIG9wdHMpO1xuICB9XG4gIC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY29sb3JzKSkgY3R4LmNvbG9ycyA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG4gIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG4gIHJldHVybiBmb3JtYXRWYWx1ZShjdHgsIG9iaiwgY3R4LmRlcHRoKTtcbn1cblxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5pbnNwZWN0LmNvbG9ycyA9IHtcbiAgJ2JvbGQnIDogWzEsIDIyXSxcbiAgJ2l0YWxpYycgOiBbMywgMjNdLFxuICAndW5kZXJsaW5lJyA6IFs0LCAyNF0sXG4gICdpbnZlcnNlJyA6IFs3LCAyN10sXG4gICd3aGl0ZScgOiBbMzcsIDM5XSxcbiAgJ2dyZXknIDogWzkwLCAzOV0sXG4gICdibGFjaycgOiBbMzAsIDM5XSxcbiAgJ2JsdWUnIDogWzM0LCAzOV0sXG4gICdjeWFuJyA6IFszNiwgMzldLFxuICAnZ3JlZW4nIDogWzMyLCAzOV0sXG4gICdtYWdlbnRhJyA6IFszNSwgMzldLFxuICAncmVkJyA6IFszMSwgMzldLFxuICAneWVsbG93JyA6IFszMywgMzldXG59O1xuXG4vLyBEb24ndCB1c2UgJ2JsdWUnIG5vdCB2aXNpYmxlIG9uIGNtZC5leGVcbmluc3BlY3Quc3R5bGVzID0ge1xuICAnc3BlY2lhbCc6ICdjeWFuJyxcbiAgJ251bWJlcic6ICd5ZWxsb3cnLFxuICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuICAndW5kZWZpbmVkJzogJ2dyZXknLFxuICAnbnVsbCc6ICdib2xkJyxcbiAgJ3N0cmluZyc6ICdncmVlbicsXG4gICdkYXRlJzogJ21hZ2VudGEnLFxuICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuICAncmVnZXhwJzogJ3JlZCdcbn07XG5cbmZ1bmN0aW9uIHN0eWxpemVOb0NvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHJldHVybiBzdHI7XG59XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cblxuZnVuY3Rpb24gc3R5bGl6ZVdpdGhDb2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG4gIGlmIChzdHlsZSkge1xuICAgIHJldHVybiAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzBdICsgJ20nICsgc3RyICtcbiAgICAgICAgICAgJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVsxXSArICdtJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGhhc093bihvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gaXNPYmplY3QocmUpICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnICE9PSBudWxsO1xufVxuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGUpICYmXG4gICAgICAob2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXScgfHwgZSBpbnN0YW5jZW9mIEVycm9yKTtcbn1cblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGQpICYmIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cblxuZnVuY3Rpb24gYXJyYXlUb0hhc2goYXJyYXkpIHtcbiAgdmFyIGhhc2ggPSB7fTtcblxuICBmb3JFYWNoKGFycmF5LCBmdW5jdGlvbih2YWwsIGlkeCkge1xuICAgIGhhc2hbdmFsXSA9IHRydWU7XG4gIH0pO1xuXG4gIHJldHVybiBoYXNoO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKSB7XG4gIHZhciBvdXRwdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICBpZiAoaGFzT3duKHZhbHVlLCBTdHJpbmcoaSkpKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIFN0cmluZyhpKSwgdHJ1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgfVxuICB9XG4gIGZvckVhY2goa2V5cywgZnVuY3Rpb24oa2V5KSB7XG4gICAgaWYgKCFrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIGtleSwgdHJ1ZSkpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBvdXRwdXQ7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdEVycm9yKHZhbHVlKSB7XG4gIHJldHVybiAnWycgKyBFcnJvci5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgKyAnXSc7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFZhbHVlKGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcykge1xuICAvLyBQcm92aWRlIGEgaG9vayBmb3IgdXNlci1zcGVjaWZpZWQgaW5zcGVjdCBmdW5jdGlvbnMuXG4gIC8vIENoZWNrIHRoYXQgdmFsdWUgaXMgYW4gb2JqZWN0IHdpdGggYW4gaW5zcGVjdCBmdW5jdGlvbiBvbiBpdFxuICBpZiAoY3R4LmN1c3RvbUluc3BlY3QgJiZcbiAgICAgIHZhbHVlICYmXG4gICAgICBpc0Z1bmN0aW9uKHZhbHVlLmluc3BlY3QpICYmXG4gICAgICAvLyBGaWx0ZXIgb3V0IHRoZSB1dGlsIG1vZHVsZSwgaXQncyBpbnNwZWN0IGZ1bmN0aW9uIGlzIHNwZWNpYWxcbiAgICAgIHZhbHVlLmluc3BlY3QgIT09IGluc3BlY3QgJiZcbiAgICAgIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuICAgICAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcywgY3R4KTtcbiAgICBpZiAoIWlzU3RyaW5nKHJldCkpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG4gIHZhciBrZXlzID0gb2JqZWN0S2V5cyh2YWx1ZSk7XG4gIHZhciB2aXNpYmxlS2V5cyA9IGFycmF5VG9IYXNoKGtleXMpO1xuXG4gIGlmIChjdHguc2hvd0hpZGRlbiAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcykge1xuICAgIGtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh2YWx1ZSk7XG4gIH1cblxuICAvLyBJRSBkb2Vzbid0IG1ha2UgZXJyb3IgZmllbGRzIG5vbi1lbnVtZXJhYmxlXG4gIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9pZS9kd3c1MnNidCh2PXZzLjk0KS5hc3B4XG4gIGlmIChpc0Vycm9yKHZhbHVlKVxuICAgICAgJiYgKGluZGV4T2Yoa2V5cywgJ21lc3NhZ2UnKSA+PSAwIHx8IGluZGV4T2Yoa2V5cywgJ2Rlc2NyaXB0aW9uJykgPj0gMCkpIHtcbiAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgLy8gU29tZSB0eXBlIG9mIG9iamVjdCB3aXRob3V0IHByb3BlcnRpZXMgY2FuIGJlIHNob3J0Y3V0dGVkLlxuICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgIHZhciBuYW1lID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tGdW5jdGlvbicgKyBuYW1lICsgJ10nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH1cbiAgICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAnZGF0ZScpO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGJhc2UgPSAnJywgYXJyYXkgPSBmYWxzZSwgYnJhY2VzID0gWyd7JywgJ30nXTtcblxuICAvLyBNYWtlIEFycmF5IHNheSB0aGF0IHRoZXkgYXJlIEFycmF5XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIGFycmF5ID0gdHJ1ZTtcbiAgICBicmFjZXMgPSBbJ1snLCAnXSddO1xuICB9XG5cbiAgLy8gTWFrZSBmdW5jdGlvbnMgc2F5IHRoYXQgdGhleSBhcmUgZnVuY3Rpb25zXG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHZhciBuID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgYmFzZSA9ICcgW0Z1bmN0aW9uJyArIG4gKyAnXSc7XG4gIH1cblxuICAvLyBNYWtlIFJlZ0V4cHMgc2F5IHRoYXQgdGhleSBhcmUgUmVnRXhwc1xuICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGRhdGVzIHdpdGggcHJvcGVydGllcyBmaXJzdCBzYXkgdGhlIGRhdGVcbiAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGVycm9yIHdpdGggbWVzc2FnZSBmaXJzdCBzYXkgdGhlIGVycm9yXG4gIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICBpZiAoa2V5cy5sZW5ndGggPT09IDAgJiYgKCFhcnJheSB8fCB2YWx1ZS5sZW5ndGggPT0gMCkpIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArIGJyYWNlc1sxXTtcbiAgfVxuXG4gIGlmIChyZWN1cnNlVGltZXMgPCAwKSB7XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbT2JqZWN0XScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG5cbiAgY3R4LnNlZW4ucHVzaCh2YWx1ZSk7XG5cbiAgdmFyIG91dHB1dDtcbiAgaWYgKGFycmF5KSB7XG4gICAgb3V0cHV0ID0gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cyk7XG4gIH0gZWxzZSB7XG4gICAgb3V0cHV0ID0gbWFwKGtleXMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpO1xuICAgIH0pO1xuICB9XG5cbiAgY3R4LnNlZW4ucG9wKCk7XG5cbiAgcmV0dXJuIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSkge1xuICB2YXIgbmFtZSwgc3RyLCBkZXNjO1xuICBkZXNjID0geyB2YWx1ZTogdmFsdWVba2V5XSB9O1xuICBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcikge1xuICAgIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHZhbHVlLCBrZXkpIHx8IGRlc2M7XG4gIH1cbiAgaWYgKGRlc2MuZ2V0KSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlci9TZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoIWhhc093bih2aXNpYmxlS2V5cywga2V5KSkge1xuICAgIG5hbWUgPSAnWycgKyBrZXkgKyAnXSc7XG4gIH1cbiAgaWYgKCFzdHIpIHtcbiAgICBpZiAoaW5kZXhPZihjdHguc2VlbiwgZGVzYy52YWx1ZSkgPCAwKSB7XG4gICAgICBpZiAoaXNOdWxsKHJlY3Vyc2VUaW1lcykpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gbWFwKHN0ci5zcGxpdCgnXFxuJyksIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKS5zdWJzdHIoMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyID0gJ1xcbicgKyBtYXAoc3RyLnNwbGl0KCdcXG4nKSwgZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0NpcmN1bGFyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmIChpc1VuZGVmaW5lZChuYW1lKSkge1xuICAgIGlmIChhcnJheSAmJiBrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH1cbiAgICBuYW1lID0gSlNPTi5zdHJpbmdpZnkoJycgKyBrZXkpO1xuICAgIGlmIChuYW1lLm1hdGNoKC9eXCIoW2EtekEtWl9dW2EtekEtWl8wLTldKilcIiQvKSkge1xuICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyKDEsIG5hbWUubGVuZ3RoIC0gMik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ25hbWUnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmFtZSA9IG5hbWUucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJylcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLyheXCJ8XCIkKS9nLCBcIidcIik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ3N0cmluZycpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuYW1lICsgJzogJyArIHN0cjtcbn1cblxuZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBzaW1wbGUgPSAnXFwnJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC9eXCJ8XCIkL2csICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuICAgIHJldHVybiBjdHguc3R5bGl6ZShzaW1wbGUsICdzdHJpbmcnKTtcbiAgfVxuICBpZiAoaXNOdW1iZXIodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG4gIGlmIChpc0Jvb2xlYW4odmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpO1xuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmIChpc051bGwodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG59XG5cbmZ1bmN0aW9uIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKSB7XG4gIHZhciBudW1MaW5lc0VzdCA9IDA7XG4gIHZhciBsZW5ndGggPSByZWR1Y2Uob3V0cHV0LCBmdW5jdGlvbihwcmV2LCBjdXIpIHtcbiAgICBudW1MaW5lc0VzdCsrO1xuICAgIGlmIChjdXIuaW5kZXhPZignXFxuJykgPj0gMCkgbnVtTGluZXNFc3QrKztcbiAgICByZXR1cm4gcHJldiArIGN1ci5yZXBsYWNlKC9cXHUwMDFiXFxbXFxkXFxkP20vZywgJycpLmxlbmd0aCArIDE7XG4gIH0sIDApO1xuXG4gIGlmIChsZW5ndGggPiA2MCkge1xuICAgIHJldHVybiBicmFjZXNbMF0gK1xuICAgICAgICAgICAoYmFzZSA9PT0gJycgPyAnJyA6IGJhc2UgKyAnXFxuICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgb3V0cHV0LmpvaW4oJyxcXG4gICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgYnJhY2VzWzFdO1xuICB9XG5cbiAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyAnICcgKyBvdXRwdXQuam9pbignLCAnKSArICcgJyArIGJyYWNlc1sxXTtcbn1cblxuZnVuY3Rpb24gX2V4dGVuZChvcmlnaW4sIGFkZCkge1xuICAvLyBEb24ndCBkbyBhbnl0aGluZyBpZiBhZGQgaXNuJ3QgYW4gb2JqZWN0XG4gIGlmICghYWRkIHx8ICFpc09iamVjdChhZGQpKSByZXR1cm4gb3JpZ2luO1xuXG4gIHZhciBrZXlzID0gb2JqZWN0S2V5cyhhZGQpO1xuICB2YXIgaSA9IGtleXMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgb3JpZ2luW2tleXNbaV1dID0gYWRkW2tleXNbaV1dO1xuICB9XG4gIHJldHVybiBvcmlnaW47XG59XG4iLCIvKiEgSlNPTiB2My4zLjAgfCBodHRwOi8vYmVzdGllanMuZ2l0aHViLmlvL2pzb24zIHwgQ29weXJpZ2h0IDIwMTItMjAxNCwgS2l0IENhbWJyaWRnZSB8IGh0dHA6Ly9raXQubWl0LWxpY2Vuc2Uub3JnICovXG47KGZ1bmN0aW9uIChyb290KSB7XG4gIC8vIERldGVjdCB0aGUgYGRlZmluZWAgZnVuY3Rpb24gZXhwb3NlZCBieSBhc3luY2hyb25vdXMgbW9kdWxlIGxvYWRlcnMuIFRoZVxuICAvLyBzdHJpY3QgYGRlZmluZWAgY2hlY2sgaXMgbmVjZXNzYXJ5IGZvciBjb21wYXRpYmlsaXR5IHdpdGggYHIuanNgLlxuICB2YXIgaXNMb2FkZXIgPSB0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZDtcblxuICAvLyBVc2UgdGhlIGBnbG9iYWxgIG9iamVjdCBleHBvc2VkIGJ5IE5vZGUgKGluY2x1ZGluZyBCcm93c2VyaWZ5IHZpYVxuICAvLyBgaW5zZXJ0LW1vZHVsZS1nbG9iYWxzYCksIE5hcndoYWwsIGFuZCBSaW5nbyBhcyB0aGUgZGVmYXVsdCBjb250ZXh0LlxuICAvLyBSaGlubyBleHBvcnRzIGEgYGdsb2JhbGAgZnVuY3Rpb24gaW5zdGVhZC5cbiAgdmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09IFwib2JqZWN0XCIgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbFtcImdsb2JhbFwiXSA9PT0gZnJlZUdsb2JhbCB8fCBmcmVlR2xvYmFsW1wid2luZG93XCJdID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLy8gUHVibGljOiBJbml0aWFsaXplcyBKU09OIDMgdXNpbmcgdGhlIGdpdmVuIGBjb250ZXh0YCBvYmplY3QsIGF0dGFjaGluZyB0aGVcbiAgLy8gYHN0cmluZ2lmeWAgYW5kIGBwYXJzZWAgZnVuY3Rpb25zIHRvIHRoZSBzcGVjaWZpZWQgYGV4cG9ydHNgIG9iamVjdC5cbiAgZnVuY3Rpb24gcnVuSW5Db250ZXh0KGNvbnRleHQsIGV4cG9ydHMpIHtcbiAgICBjb250ZXh0IHx8IChjb250ZXh0ID0gcm9vdFtcIk9iamVjdFwiXSgpKTtcbiAgICBleHBvcnRzIHx8IChleHBvcnRzID0gcm9vdFtcIk9iamVjdFwiXSgpKTtcblxuICAgIC8vIE5hdGl2ZSBjb25zdHJ1Y3RvciBhbGlhc2VzLlxuICAgIHZhciBOdW1iZXIgPSBjb250ZXh0W1wiTnVtYmVyXCJdIHx8IHJvb3RbXCJOdW1iZXJcIl0sXG4gICAgICAgIFN0cmluZyA9IGNvbnRleHRbXCJTdHJpbmdcIl0gfHwgcm9vdFtcIlN0cmluZ1wiXSxcbiAgICAgICAgT2JqZWN0ID0gY29udGV4dFtcIk9iamVjdFwiXSB8fCByb290W1wiT2JqZWN0XCJdLFxuICAgICAgICBEYXRlID0gY29udGV4dFtcIkRhdGVcIl0gfHwgcm9vdFtcIkRhdGVcIl0sXG4gICAgICAgIFN5bnRheEVycm9yID0gY29udGV4dFtcIlN5bnRheEVycm9yXCJdIHx8IHJvb3RbXCJTeW50YXhFcnJvclwiXSxcbiAgICAgICAgVHlwZUVycm9yID0gY29udGV4dFtcIlR5cGVFcnJvclwiXSB8fCByb290W1wiVHlwZUVycm9yXCJdLFxuICAgICAgICBNYXRoID0gY29udGV4dFtcIk1hdGhcIl0gfHwgcm9vdFtcIk1hdGhcIl0sXG4gICAgICAgIG5hdGl2ZUpTT04gPSBjb250ZXh0W1wiSlNPTlwiXSB8fCByb290W1wiSlNPTlwiXTtcblxuICAgIC8vIERlbGVnYXRlIHRvIHRoZSBuYXRpdmUgYHN0cmluZ2lmeWAgYW5kIGBwYXJzZWAgaW1wbGVtZW50YXRpb25zLlxuICAgIGlmICh0eXBlb2YgbmF0aXZlSlNPTiA9PSBcIm9iamVjdFwiICYmIG5hdGl2ZUpTT04pIHtcbiAgICAgIGV4cG9ydHMuc3RyaW5naWZ5ID0gbmF0aXZlSlNPTi5zdHJpbmdpZnk7XG4gICAgICBleHBvcnRzLnBhcnNlID0gbmF0aXZlSlNPTi5wYXJzZTtcbiAgICB9XG5cbiAgICAvLyBDb252ZW5pZW5jZSBhbGlhc2VzLlxuICAgIHZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGUsXG4gICAgICAgIGdldENsYXNzID0gb2JqZWN0UHJvdG8udG9TdHJpbmcsXG4gICAgICAgIGlzUHJvcGVydHksIGZvckVhY2gsIHVuZGVmO1xuXG4gICAgLy8gVGVzdCB0aGUgYERhdGUjZ2V0VVRDKmAgbWV0aG9kcy4gQmFzZWQgb24gd29yayBieSBAWWFmZmxlLlxuICAgIHZhciBpc0V4dGVuZGVkID0gbmV3IERhdGUoLTM1MDk4MjczMzQ1NzMyOTIpO1xuICAgIHRyeSB7XG4gICAgICAvLyBUaGUgYGdldFVUQ0Z1bGxZZWFyYCwgYE1vbnRoYCwgYW5kIGBEYXRlYCBtZXRob2RzIHJldHVybiBub25zZW5zaWNhbFxuICAgICAgLy8gcmVzdWx0cyBmb3IgY2VydGFpbiBkYXRlcyBpbiBPcGVyYSA+PSAxMC41My5cbiAgICAgIGlzRXh0ZW5kZWQgPSBpc0V4dGVuZGVkLmdldFVUQ0Z1bGxZZWFyKCkgPT0gLTEwOTI1MiAmJiBpc0V4dGVuZGVkLmdldFVUQ01vbnRoKCkgPT09IDAgJiYgaXNFeHRlbmRlZC5nZXRVVENEYXRlKCkgPT09IDEgJiZcbiAgICAgICAgLy8gU2FmYXJpIDwgMi4wLjIgc3RvcmVzIHRoZSBpbnRlcm5hbCBtaWxsaXNlY29uZCB0aW1lIHZhbHVlIGNvcnJlY3RseSxcbiAgICAgICAgLy8gYnV0IGNsaXBzIHRoZSB2YWx1ZXMgcmV0dXJuZWQgYnkgdGhlIGRhdGUgbWV0aG9kcyB0byB0aGUgcmFuZ2Ugb2ZcbiAgICAgICAgLy8gc2lnbmVkIDMyLWJpdCBpbnRlZ2VycyAoWy0yICoqIDMxLCAyICoqIDMxIC0gMV0pLlxuICAgICAgICBpc0V4dGVuZGVkLmdldFVUQ0hvdXJzKCkgPT0gMTAgJiYgaXNFeHRlbmRlZC5nZXRVVENNaW51dGVzKCkgPT0gMzcgJiYgaXNFeHRlbmRlZC5nZXRVVENTZWNvbmRzKCkgPT0gNiAmJiBpc0V4dGVuZGVkLmdldFVUQ01pbGxpc2Vjb25kcygpID09IDcwODtcbiAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG5cbiAgICAvLyBJbnRlcm5hbDogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBuYXRpdmUgYEpTT04uc3RyaW5naWZ5YCBhbmQgYHBhcnNlYFxuICAgIC8vIGltcGxlbWVudGF0aW9ucyBhcmUgc3BlYy1jb21wbGlhbnQuIEJhc2VkIG9uIHdvcmsgYnkgS2VuIFNueWRlci5cbiAgICBmdW5jdGlvbiBoYXMobmFtZSkge1xuICAgICAgaWYgKGhhc1tuYW1lXSAhPT0gdW5kZWYpIHtcbiAgICAgICAgLy8gUmV0dXJuIGNhY2hlZCBmZWF0dXJlIHRlc3QgcmVzdWx0LlxuICAgICAgICByZXR1cm4gaGFzW25hbWVdO1xuICAgICAgfVxuICAgICAgdmFyIGlzU3VwcG9ydGVkO1xuICAgICAgaWYgKG5hbWUgPT0gXCJidWctc3RyaW5nLWNoYXItaW5kZXhcIikge1xuICAgICAgICAvLyBJRSA8PSA3IGRvZXNuJ3Qgc3VwcG9ydCBhY2Nlc3Npbmcgc3RyaW5nIGNoYXJhY3RlcnMgdXNpbmcgc3F1YXJlXG4gICAgICAgIC8vIGJyYWNrZXQgbm90YXRpb24uIElFIDggb25seSBzdXBwb3J0cyB0aGlzIGZvciBwcmltaXRpdmVzLlxuICAgICAgICBpc1N1cHBvcnRlZCA9IFwiYVwiWzBdICE9IFwiYVwiO1xuICAgICAgfSBlbHNlIGlmIChuYW1lID09IFwianNvblwiKSB7XG4gICAgICAgIC8vIEluZGljYXRlcyB3aGV0aGVyIGJvdGggYEpTT04uc3RyaW5naWZ5YCBhbmQgYEpTT04ucGFyc2VgIGFyZVxuICAgICAgICAvLyBzdXBwb3J0ZWQuXG4gICAgICAgIGlzU3VwcG9ydGVkID0gaGFzKFwianNvbi1zdHJpbmdpZnlcIikgJiYgaGFzKFwianNvbi1wYXJzZVwiKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciB2YWx1ZSwgc2VyaWFsaXplZCA9ICd7XCJhXCI6WzEsdHJ1ZSxmYWxzZSxudWxsLFwiXFxcXHUwMDAwXFxcXGJcXFxcblxcXFxmXFxcXHJcXFxcdFwiXX0nO1xuICAgICAgICAvLyBUZXN0IGBKU09OLnN0cmluZ2lmeWAuXG4gICAgICAgIGlmIChuYW1lID09IFwianNvbi1zdHJpbmdpZnlcIikge1xuICAgICAgICAgIHZhciBzdHJpbmdpZnkgPSBleHBvcnRzLnN0cmluZ2lmeSwgc3RyaW5naWZ5U3VwcG9ydGVkID0gdHlwZW9mIHN0cmluZ2lmeSA9PSBcImZ1bmN0aW9uXCIgJiYgaXNFeHRlbmRlZDtcbiAgICAgICAgICBpZiAoc3RyaW5naWZ5U3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAvLyBBIHRlc3QgZnVuY3Rpb24gb2JqZWN0IHdpdGggYSBjdXN0b20gYHRvSlNPTmAgbWV0aG9kLlxuICAgICAgICAgICAgKHZhbHVlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgIH0pLnRvSlNPTiA9IHZhbHVlO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgc3RyaW5naWZ5U3VwcG9ydGVkID1cbiAgICAgICAgICAgICAgICAvLyBGaXJlZm94IDMuMWIxIGFuZCBiMiBzZXJpYWxpemUgc3RyaW5nLCBudW1iZXIsIGFuZCBib29sZWFuXG4gICAgICAgICAgICAgICAgLy8gcHJpbWl0aXZlcyBhcyBvYmplY3QgbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KDApID09PSBcIjBcIiAmJlxuICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCBiMiwgYW5kIEpTT04gMiBzZXJpYWxpemUgd3JhcHBlZCBwcmltaXRpdmVzIGFzIG9iamVjdFxuICAgICAgICAgICAgICAgIC8vIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgTnVtYmVyKCkpID09PSBcIjBcIiAmJlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgU3RyaW5nKCkpID09ICdcIlwiJyAmJlxuICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCAyIHRocm93IGFuIGVycm9yIGlmIHRoZSB2YWx1ZSBpcyBgbnVsbGAsIGB1bmRlZmluZWRgLCBvclxuICAgICAgICAgICAgICAgIC8vIGRvZXMgbm90IGRlZmluZSBhIGNhbm9uaWNhbCBKU09OIHJlcHJlc2VudGF0aW9uICh0aGlzIGFwcGxpZXMgdG9cbiAgICAgICAgICAgICAgICAvLyBvYmplY3RzIHdpdGggYHRvSlNPTmAgcHJvcGVydGllcyBhcyB3ZWxsLCAqdW5sZXNzKiB0aGV5IGFyZSBuZXN0ZWRcbiAgICAgICAgICAgICAgICAvLyB3aXRoaW4gYW4gb2JqZWN0IG9yIGFycmF5KS5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoZ2V0Q2xhc3MpID09PSB1bmRlZiAmJlxuICAgICAgICAgICAgICAgIC8vIElFIDggc2VyaWFsaXplcyBgdW5kZWZpbmVkYCBhcyBgXCJ1bmRlZmluZWRcImAuIFNhZmFyaSA8PSA1LjEuNyBhbmRcbiAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMyBwYXNzIHRoaXMgdGVzdC5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkodW5kZWYpID09PSB1bmRlZiAmJlxuICAgICAgICAgICAgICAgIC8vIFNhZmFyaSA8PSA1LjEuNyBhbmQgRkYgMy4xYjMgdGhyb3cgYEVycm9yYHMgYW5kIGBUeXBlRXJyb3JgcyxcbiAgICAgICAgICAgICAgICAvLyByZXNwZWN0aXZlbHksIGlmIHRoZSB2YWx1ZSBpcyBvbWl0dGVkIGVudGlyZWx5LlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeSgpID09PSB1bmRlZiAmJlxuICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCAyIHRocm93IGFuIGVycm9yIGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBub3QgYSBudW1iZXIsXG4gICAgICAgICAgICAgICAgLy8gc3RyaW5nLCBhcnJheSwgb2JqZWN0LCBCb29sZWFuLCBvciBgbnVsbGAgbGl0ZXJhbC4gVGhpcyBhcHBsaWVzIHRvXG4gICAgICAgICAgICAgICAgLy8gb2JqZWN0cyB3aXRoIGN1c3RvbSBgdG9KU09OYCBtZXRob2RzIGFzIHdlbGwsIHVubGVzcyB0aGV5IGFyZSBuZXN0ZWRcbiAgICAgICAgICAgICAgICAvLyBpbnNpZGUgb2JqZWN0IG9yIGFycmF5IGxpdGVyYWxzLiBZVUkgMy4wLjBiMSBpZ25vcmVzIGN1c3RvbSBgdG9KU09OYFxuICAgICAgICAgICAgICAgIC8vIG1ldGhvZHMgZW50aXJlbHkuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KHZhbHVlKSA9PT0gXCIxXCIgJiZcbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoW3ZhbHVlXSkgPT0gXCJbMV1cIiAmJlxuICAgICAgICAgICAgICAgIC8vIFByb3RvdHlwZSA8PSAxLjYuMSBzZXJpYWxpemVzIGBbdW5kZWZpbmVkXWAgYXMgYFwiW11cImAgaW5zdGVhZCBvZlxuICAgICAgICAgICAgICAgIC8vIGBcIltudWxsXVwiYC5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoW3VuZGVmXSkgPT0gXCJbbnVsbF1cIiAmJlxuICAgICAgICAgICAgICAgIC8vIFlVSSAzLjAuMGIxIGZhaWxzIHRvIHNlcmlhbGl6ZSBgbnVsbGAgbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG51bGwpID09IFwibnVsbFwiICYmXG4gICAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIDIgaGFsdHMgc2VyaWFsaXphdGlvbiBpZiBhbiBhcnJheSBjb250YWlucyBhIGZ1bmN0aW9uOlxuICAgICAgICAgICAgICAgIC8vIGBbMSwgdHJ1ZSwgZ2V0Q2xhc3MsIDFdYCBzZXJpYWxpemVzIGFzIFwiWzEsdHJ1ZSxdLFwiLiBGRiAzLjFiM1xuICAgICAgICAgICAgICAgIC8vIGVsaWRlcyBub24tSlNPTiB2YWx1ZXMgZnJvbSBvYmplY3RzIGFuZCBhcnJheXMsIHVubGVzcyB0aGV5XG4gICAgICAgICAgICAgICAgLy8gZGVmaW5lIGN1c3RvbSBgdG9KU09OYCBtZXRob2RzLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShbdW5kZWYsIGdldENsYXNzLCBudWxsXSkgPT0gXCJbbnVsbCxudWxsLG51bGxdXCIgJiZcbiAgICAgICAgICAgICAgICAvLyBTaW1wbGUgc2VyaWFsaXphdGlvbiB0ZXN0LiBGRiAzLjFiMSB1c2VzIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlc1xuICAgICAgICAgICAgICAgIC8vIHdoZXJlIGNoYXJhY3RlciBlc2NhcGUgY29kZXMgYXJlIGV4cGVjdGVkIChlLmcuLCBgXFxiYCA9PiBgXFx1MDAwOGApLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeSh7IFwiYVwiOiBbdmFsdWUsIHRydWUsIGZhbHNlLCBudWxsLCBcIlxceDAwXFxiXFxuXFxmXFxyXFx0XCJdIH0pID09IHNlcmlhbGl6ZWQgJiZcbiAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMSBhbmQgYjIgaWdub3JlIHRoZSBgZmlsdGVyYCBhbmQgYHdpZHRoYCBhcmd1bWVudHMuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG51bGwsIHZhbHVlKSA9PT0gXCIxXCIgJiZcbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoWzEsIDJdLCBudWxsLCAxKSA9PSBcIltcXG4gMSxcXG4gMlxcbl1cIiAmJlxuICAgICAgICAgICAgICAgIC8vIEpTT04gMiwgUHJvdG90eXBlIDw9IDEuNywgYW5kIG9sZGVyIFdlYktpdCBidWlsZHMgaW5jb3JyZWN0bHlcbiAgICAgICAgICAgICAgICAvLyBzZXJpYWxpemUgZXh0ZW5kZWQgeWVhcnMuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKC04LjY0ZTE1KSkgPT0gJ1wiLTI3MTgyMS0wNC0yMFQwMDowMDowMC4wMDBaXCInICYmXG4gICAgICAgICAgICAgICAgLy8gVGhlIG1pbGxpc2Vjb25kcyBhcmUgb3B0aW9uYWwgaW4gRVMgNSwgYnV0IHJlcXVpcmVkIGluIDUuMS5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoOC42NGUxNSkpID09ICdcIisyNzU3NjAtMDktMTNUMDA6MDA6MDAuMDAwWlwiJyAmJlxuICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggPD0gMTEuMCBpbmNvcnJlY3RseSBzZXJpYWxpemVzIHllYXJzIHByaW9yIHRvIDAgYXMgbmVnYXRpdmVcbiAgICAgICAgICAgICAgICAvLyBmb3VyLWRpZ2l0IHllYXJzIGluc3RlYWQgb2Ygc2l4LWRpZ2l0IHllYXJzLiBDcmVkaXRzOiBAWWFmZmxlLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgRGF0ZSgtNjIxOTg3NTUyZTUpKSA9PSAnXCItMDAwMDAxLTAxLTAxVDAwOjAwOjAwLjAwMFpcIicgJiZcbiAgICAgICAgICAgICAgICAvLyBTYWZhcmkgPD0gNS4xLjUgYW5kIE9wZXJhID49IDEwLjUzIGluY29ycmVjdGx5IHNlcmlhbGl6ZSBtaWxsaXNlY29uZFxuICAgICAgICAgICAgICAgIC8vIHZhbHVlcyBsZXNzIHRoYW4gMTAwMC4gQ3JlZGl0czogQFlhZmZsZS5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoLTEpKSA9PSAnXCIxOTY5LTEyLTMxVDIzOjU5OjU5Ljk5OVpcIic7XG4gICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgc3RyaW5naWZ5U3VwcG9ydGVkID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlzU3VwcG9ydGVkID0gc3RyaW5naWZ5U3VwcG9ydGVkO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRlc3QgYEpTT04ucGFyc2VgLlxuICAgICAgICBpZiAobmFtZSA9PSBcImpzb24tcGFyc2VcIikge1xuICAgICAgICAgIHZhciBwYXJzZSA9IGV4cG9ydHMucGFyc2U7XG4gICAgICAgICAgaWYgKHR5cGVvZiBwYXJzZSA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCBiMiB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiBhIGJhcmUgbGl0ZXJhbCBpcyBwcm92aWRlZC5cbiAgICAgICAgICAgICAgLy8gQ29uZm9ybWluZyBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIGFsc28gY29lcmNlIHRoZSBpbml0aWFsIGFyZ3VtZW50IHRvXG4gICAgICAgICAgICAgIC8vIGEgc3RyaW5nIHByaW9yIHRvIHBhcnNpbmcuXG4gICAgICAgICAgICAgIGlmIChwYXJzZShcIjBcIikgPT09IDAgJiYgIXBhcnNlKGZhbHNlKSkge1xuICAgICAgICAgICAgICAgIC8vIFNpbXBsZSBwYXJzaW5nIHRlc3QuXG4gICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZShzZXJpYWxpemVkKTtcbiAgICAgICAgICAgICAgICB2YXIgcGFyc2VTdXBwb3J0ZWQgPSB2YWx1ZVtcImFcIl0ubGVuZ3RoID09IDUgJiYgdmFsdWVbXCJhXCJdWzBdID09PSAxO1xuICAgICAgICAgICAgICAgIGlmIChwYXJzZVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIDw9IDUuMS4yIGFuZCBGRiAzLjFiMSBhbGxvdyB1bmVzY2FwZWQgdGFicyBpbiBzdHJpbmdzLlxuICAgICAgICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9ICFwYXJzZSgnXCJcXHRcIicpO1xuICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlU3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gRkYgNC4wIGFuZCA0LjAuMSBhbGxvdyBsZWFkaW5nIGArYCBzaWducyBhbmQgbGVhZGluZ1xuICAgICAgICAgICAgICAgICAgICAgIC8vIGRlY2ltYWwgcG9pbnRzLiBGRiA0LjAsIDQuMC4xLCBhbmQgSUUgOS0xMCBhbHNvIGFsbG93XG4gICAgICAgICAgICAgICAgICAgICAgLy8gY2VydGFpbiBvY3RhbCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9IHBhcnNlKFwiMDFcIikgIT09IDE7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGlmIChwYXJzZVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIEZGIDQuMCwgNC4wLjEsIGFuZCBSaGlubyAxLjdSMy1SNCBhbGxvdyB0cmFpbGluZyBkZWNpbWFsXG4gICAgICAgICAgICAgICAgICAgICAgLy8gcG9pbnRzLiBUaGVzZSBlbnZpcm9ubWVudHMsIGFsb25nIHdpdGggRkYgMy4xYjEgYW5kIDIsXG4gICAgICAgICAgICAgICAgICAgICAgLy8gYWxzbyBhbGxvdyB0cmFpbGluZyBjb21tYXMgaW4gSlNPTiBvYmplY3RzIGFuZCBhcnJheXMuXG4gICAgICAgICAgICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBwYXJzZShcIjEuXCIpICE9PSAxO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaXNTdXBwb3J0ZWQgPSBwYXJzZVN1cHBvcnRlZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGhhc1tuYW1lXSA9ICEhaXNTdXBwb3J0ZWQ7XG4gICAgfVxuXG4gICAgaWYgKCFoYXMoXCJqc29uXCIpKSB7XG4gICAgICAvLyBDb21tb24gYFtbQ2xhc3NdXWAgbmFtZSBhbGlhc2VzLlxuICAgICAgdmFyIGZ1bmN0aW9uQ2xhc3MgPSBcIltvYmplY3QgRnVuY3Rpb25dXCIsXG4gICAgICAgICAgZGF0ZUNsYXNzID0gXCJbb2JqZWN0IERhdGVdXCIsXG4gICAgICAgICAgbnVtYmVyQ2xhc3MgPSBcIltvYmplY3QgTnVtYmVyXVwiLFxuICAgICAgICAgIHN0cmluZ0NsYXNzID0gXCJbb2JqZWN0IFN0cmluZ11cIixcbiAgICAgICAgICBhcnJheUNsYXNzID0gXCJbb2JqZWN0IEFycmF5XVwiLFxuICAgICAgICAgIGJvb2xlYW5DbGFzcyA9IFwiW29iamVjdCBCb29sZWFuXVwiO1xuXG4gICAgICAvLyBEZXRlY3QgaW5jb21wbGV0ZSBzdXBwb3J0IGZvciBhY2Nlc3Npbmcgc3RyaW5nIGNoYXJhY3RlcnMgYnkgaW5kZXguXG4gICAgICB2YXIgY2hhckluZGV4QnVnZ3kgPSBoYXMoXCJidWctc3RyaW5nLWNoYXItaW5kZXhcIik7XG5cbiAgICAgIC8vIERlZmluZSBhZGRpdGlvbmFsIHV0aWxpdHkgbWV0aG9kcyBpZiB0aGUgYERhdGVgIG1ldGhvZHMgYXJlIGJ1Z2d5LlxuICAgICAgaWYgKCFpc0V4dGVuZGVkKSB7XG4gICAgICAgIHZhciBmbG9vciA9IE1hdGguZmxvb3I7XG4gICAgICAgIC8vIEEgbWFwcGluZyBiZXR3ZWVuIHRoZSBtb250aHMgb2YgdGhlIHllYXIgYW5kIHRoZSBudW1iZXIgb2YgZGF5cyBiZXR3ZWVuXG4gICAgICAgIC8vIEphbnVhcnkgMXN0IGFuZCB0aGUgZmlyc3Qgb2YgdGhlIHJlc3BlY3RpdmUgbW9udGguXG4gICAgICAgIHZhciBNb250aHMgPSBbMCwgMzEsIDU5LCA5MCwgMTIwLCAxNTEsIDE4MSwgMjEyLCAyNDMsIDI3MywgMzA0LCAzMzRdO1xuICAgICAgICAvLyBJbnRlcm5hbDogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIGRheXMgYmV0d2VlbiB0aGUgVW5peCBlcG9jaCBhbmQgdGhlXG4gICAgICAgIC8vIGZpcnN0IGRheSBvZiB0aGUgZ2l2ZW4gbW9udGguXG4gICAgICAgIHZhciBnZXREYXkgPSBmdW5jdGlvbiAoeWVhciwgbW9udGgpIHtcbiAgICAgICAgICByZXR1cm4gTW9udGhzW21vbnRoXSArIDM2NSAqICh5ZWFyIC0gMTk3MCkgKyBmbG9vcigoeWVhciAtIDE5NjkgKyAobW9udGggPSArKG1vbnRoID4gMSkpKSAvIDQpIC0gZmxvb3IoKHllYXIgLSAxOTAxICsgbW9udGgpIC8gMTAwKSArIGZsb29yKCh5ZWFyIC0gMTYwMSArIG1vbnRoKSAvIDQwMCk7XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIC8vIEludGVybmFsOiBEZXRlcm1pbmVzIGlmIGEgcHJvcGVydHkgaXMgYSBkaXJlY3QgcHJvcGVydHkgb2YgdGhlIGdpdmVuXG4gICAgICAvLyBvYmplY3QuIERlbGVnYXRlcyB0byB0aGUgbmF0aXZlIGBPYmplY3QjaGFzT3duUHJvcGVydHlgIG1ldGhvZC5cbiAgICAgIGlmICghKGlzUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eSkpIHtcbiAgICAgICAgaXNQcm9wZXJ0eSA9IGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgICAgICAgIHZhciBtZW1iZXJzID0ge30sIGNvbnN0cnVjdG9yO1xuICAgICAgICAgIGlmICgobWVtYmVycy5fX3Byb3RvX18gPSBudWxsLCBtZW1iZXJzLl9fcHJvdG9fXyA9IHtcbiAgICAgICAgICAgIC8vIFRoZSAqcHJvdG8qIHByb3BlcnR5IGNhbm5vdCBiZSBzZXQgbXVsdGlwbGUgdGltZXMgaW4gcmVjZW50XG4gICAgICAgICAgICAvLyB2ZXJzaW9ucyBvZiBGaXJlZm94IGFuZCBTZWFNb25rZXkuXG4gICAgICAgICAgICBcInRvU3RyaW5nXCI6IDFcbiAgICAgICAgICB9LCBtZW1iZXJzKS50b1N0cmluZyAhPSBnZXRDbGFzcykge1xuICAgICAgICAgICAgLy8gU2FmYXJpIDw9IDIuMC4zIGRvZXNuJ3QgaW1wbGVtZW50IGBPYmplY3QjaGFzT3duUHJvcGVydHlgLCBidXRcbiAgICAgICAgICAgIC8vIHN1cHBvcnRzIHRoZSBtdXRhYmxlICpwcm90byogcHJvcGVydHkuXG4gICAgICAgICAgICBpc1Byb3BlcnR5ID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgIC8vIENhcHR1cmUgYW5kIGJyZWFrIHRoZSBvYmplY3RncyBwcm90b3R5cGUgY2hhaW4gKHNlZSBzZWN0aW9uIDguNi4yXG4gICAgICAgICAgICAgIC8vIG9mIHRoZSBFUyA1LjEgc3BlYykuIFRoZSBwYXJlbnRoZXNpemVkIGV4cHJlc3Npb24gcHJldmVudHMgYW5cbiAgICAgICAgICAgICAgLy8gdW5zYWZlIHRyYW5zZm9ybWF0aW9uIGJ5IHRoZSBDbG9zdXJlIENvbXBpbGVyLlxuICAgICAgICAgICAgICB2YXIgb3JpZ2luYWwgPSB0aGlzLl9fcHJvdG9fXywgcmVzdWx0ID0gcHJvcGVydHkgaW4gKHRoaXMuX19wcm90b19fID0gbnVsbCwgdGhpcyk7XG4gICAgICAgICAgICAgIC8vIFJlc3RvcmUgdGhlIG9yaWdpbmFsIHByb3RvdHlwZSBjaGFpbi5cbiAgICAgICAgICAgICAgdGhpcy5fX3Byb3RvX18gPSBvcmlnaW5hbDtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIENhcHR1cmUgYSByZWZlcmVuY2UgdG8gdGhlIHRvcC1sZXZlbCBgT2JqZWN0YCBjb25zdHJ1Y3Rvci5cbiAgICAgICAgICAgIGNvbnN0cnVjdG9yID0gbWVtYmVycy5jb25zdHJ1Y3RvcjtcbiAgICAgICAgICAgIC8vIFVzZSB0aGUgYGNvbnN0cnVjdG9yYCBwcm9wZXJ0eSB0byBzaW11bGF0ZSBgT2JqZWN0I2hhc093blByb3BlcnR5YCBpblxuICAgICAgICAgICAgLy8gb3RoZXIgZW52aXJvbm1lbnRzLlxuICAgICAgICAgICAgaXNQcm9wZXJ0eSA9IGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgICAgICAgICAgICB2YXIgcGFyZW50ID0gKHRoaXMuY29uc3RydWN0b3IgfHwgY29uc3RydWN0b3IpLnByb3RvdHlwZTtcbiAgICAgICAgICAgICAgcmV0dXJuIHByb3BlcnR5IGluIHRoaXMgJiYgIShwcm9wZXJ0eSBpbiBwYXJlbnQgJiYgdGhpc1twcm9wZXJ0eV0gPT09IHBhcmVudFtwcm9wZXJ0eV0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbWVtYmVycyA9IG51bGw7XG4gICAgICAgICAgcmV0dXJuIGlzUHJvcGVydHkuY2FsbCh0aGlzLCBwcm9wZXJ0eSk7XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIC8vIEludGVybmFsOiBBIHNldCBvZiBwcmltaXRpdmUgdHlwZXMgdXNlZCBieSBgaXNIb3N0VHlwZWAuXG4gICAgICB2YXIgUHJpbWl0aXZlVHlwZXMgPSB7XG4gICAgICAgIFwiYm9vbGVhblwiOiAxLFxuICAgICAgICBcIm51bWJlclwiOiAxLFxuICAgICAgICBcInN0cmluZ1wiOiAxLFxuICAgICAgICBcInVuZGVmaW5lZFwiOiAxXG4gICAgICB9O1xuXG4gICAgICAvLyBJbnRlcm5hbDogRGV0ZXJtaW5lcyBpZiB0aGUgZ2l2ZW4gb2JqZWN0IGBwcm9wZXJ0eWAgdmFsdWUgaXMgYVxuICAgICAgLy8gbm9uLXByaW1pdGl2ZS5cbiAgICAgIHZhciBpc0hvc3RUeXBlID0gZnVuY3Rpb24gKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlb2Ygb2JqZWN0W3Byb3BlcnR5XTtcbiAgICAgICAgcmV0dXJuIHR5cGUgPT0gXCJvYmplY3RcIiA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6ICFQcmltaXRpdmVUeXBlc1t0eXBlXTtcbiAgICAgIH07XG5cbiAgICAgIC8vIEludGVybmFsOiBOb3JtYWxpemVzIHRoZSBgZm9yLi4uaW5gIGl0ZXJhdGlvbiBhbGdvcml0aG0gYWNyb3NzXG4gICAgICAvLyBlbnZpcm9ubWVudHMuIEVhY2ggZW51bWVyYXRlZCBrZXkgaXMgeWllbGRlZCB0byBhIGBjYWxsYmFja2AgZnVuY3Rpb24uXG4gICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHNpemUgPSAwLCBQcm9wZXJ0aWVzLCBtZW1iZXJzLCBwcm9wZXJ0eTtcblxuICAgICAgICAvLyBUZXN0cyBmb3IgYnVncyBpbiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCdzIGBmb3IuLi5pbmAgYWxnb3JpdGhtLiBUaGVcbiAgICAgICAgLy8gYHZhbHVlT2ZgIHByb3BlcnR5IGluaGVyaXRzIHRoZSBub24tZW51bWVyYWJsZSBmbGFnIGZyb21cbiAgICAgICAgLy8gYE9iamVjdC5wcm90b3R5cGVgIGluIG9sZGVyIHZlcnNpb25zIG9mIElFLCBOZXRzY2FwZSwgYW5kIE1vemlsbGEuXG4gICAgICAgIChQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHRoaXMudmFsdWVPZiA9IDA7XG4gICAgICAgIH0pLnByb3RvdHlwZS52YWx1ZU9mID0gMDtcblxuICAgICAgICAvLyBJdGVyYXRlIG92ZXIgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGBQcm9wZXJ0aWVzYCBjbGFzcy5cbiAgICAgICAgbWVtYmVycyA9IG5ldyBQcm9wZXJ0aWVzKCk7XG4gICAgICAgIGZvciAocHJvcGVydHkgaW4gbWVtYmVycykge1xuICAgICAgICAgIC8vIElnbm9yZSBhbGwgcHJvcGVydGllcyBpbmhlcml0ZWQgZnJvbSBgT2JqZWN0LnByb3RvdHlwZWAuXG4gICAgICAgICAgaWYgKGlzUHJvcGVydHkuY2FsbChtZW1iZXJzLCBwcm9wZXJ0eSkpIHtcbiAgICAgICAgICAgIHNpemUrKztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgUHJvcGVydGllcyA9IG1lbWJlcnMgPSBudWxsO1xuXG4gICAgICAgIC8vIE5vcm1hbGl6ZSB0aGUgaXRlcmF0aW9uIGFsZ29yaXRobS5cbiAgICAgICAgaWYgKCFzaXplKSB7XG4gICAgICAgICAgLy8gQSBsaXN0IG9mIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgaW5oZXJpdGVkIGZyb20gYE9iamVjdC5wcm90b3R5cGVgLlxuICAgICAgICAgIG1lbWJlcnMgPSBbXCJ2YWx1ZU9mXCIsIFwidG9TdHJpbmdcIiwgXCJ0b0xvY2FsZVN0cmluZ1wiLCBcInByb3BlcnR5SXNFbnVtZXJhYmxlXCIsIFwiaXNQcm90b3R5cGVPZlwiLCBcImhhc093blByb3BlcnR5XCIsIFwiY29uc3RydWN0b3JcIl07XG4gICAgICAgICAgLy8gSUUgPD0gOCwgTW96aWxsYSAxLjAsIGFuZCBOZXRzY2FwZSA2LjIgaWdub3JlIHNoYWRvd2VkIG5vbi1lbnVtZXJhYmxlXG4gICAgICAgICAgLy8gcHJvcGVydGllcy5cbiAgICAgICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHZhciBpc0Z1bmN0aW9uID0gZ2V0Q2xhc3MuY2FsbChvYmplY3QpID09IGZ1bmN0aW9uQ2xhc3MsIHByb3BlcnR5LCBsZW5ndGg7XG4gICAgICAgICAgICB2YXIgaGFzUHJvcGVydHkgPSAhaXNGdW5jdGlvbiAmJiB0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yICE9IFwiZnVuY3Rpb25cIiAmJiBpc0hvc3RUeXBlKG9iamVjdCwgXCJoYXNPd25Qcm9wZXJ0eVwiKSA/IG9iamVjdC5oYXNPd25Qcm9wZXJ0eSA6IGlzUHJvcGVydHk7XG4gICAgICAgICAgICBmb3IgKHByb3BlcnR5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgICAvLyBHZWNrbyA8PSAxLjAgZW51bWVyYXRlcyB0aGUgYHByb3RvdHlwZWAgcHJvcGVydHkgb2YgZnVuY3Rpb25zIHVuZGVyXG4gICAgICAgICAgICAgIC8vIGNlcnRhaW4gY29uZGl0aW9uczsgSUUgZG9lcyBub3QuXG4gICAgICAgICAgICAgIGlmICghKGlzRnVuY3Rpb24gJiYgcHJvcGVydHkgPT0gXCJwcm90b3R5cGVcIikgJiYgaGFzUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gTWFudWFsbHkgaW52b2tlIHRoZSBjYWxsYmFjayBmb3IgZWFjaCBub24tZW51bWVyYWJsZSBwcm9wZXJ0eS5cbiAgICAgICAgICAgIGZvciAobGVuZ3RoID0gbWVtYmVycy5sZW5ndGg7IHByb3BlcnR5ID0gbWVtYmVyc1stLWxlbmd0aF07IGhhc1Byb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSkgJiYgY2FsbGJhY2socHJvcGVydHkpKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKHNpemUgPT0gMikge1xuICAgICAgICAgIC8vIFNhZmFyaSA8PSAyLjAuNCBlbnVtZXJhdGVzIHNoYWRvd2VkIHByb3BlcnRpZXMgdHdpY2UuXG4gICAgICAgICAgZm9yRWFjaCA9IGZ1bmN0aW9uIChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAvLyBDcmVhdGUgYSBzZXQgb2YgaXRlcmF0ZWQgcHJvcGVydGllcy5cbiAgICAgICAgICAgIHZhciBtZW1iZXJzID0ge30sIGlzRnVuY3Rpb24gPSBnZXRDbGFzcy5jYWxsKG9iamVjdCkgPT0gZnVuY3Rpb25DbGFzcywgcHJvcGVydHk7XG4gICAgICAgICAgICBmb3IgKHByb3BlcnR5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgICAvLyBTdG9yZSBlYWNoIHByb3BlcnR5IG5hbWUgdG8gcHJldmVudCBkb3VibGUgZW51bWVyYXRpb24uIFRoZVxuICAgICAgICAgICAgICAvLyBgcHJvdG90eXBlYCBwcm9wZXJ0eSBvZiBmdW5jdGlvbnMgaXMgbm90IGVudW1lcmF0ZWQgZHVlIHRvIGNyb3NzLVxuICAgICAgICAgICAgICAvLyBlbnZpcm9ubWVudCBpbmNvbnNpc3RlbmNpZXMuXG4gICAgICAgICAgICAgIGlmICghKGlzRnVuY3Rpb24gJiYgcHJvcGVydHkgPT0gXCJwcm90b3R5cGVcIikgJiYgIWlzUHJvcGVydHkuY2FsbChtZW1iZXJzLCBwcm9wZXJ0eSkgJiYgKG1lbWJlcnNbcHJvcGVydHldID0gMSkgJiYgaXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2socHJvcGVydHkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBObyBidWdzIGRldGVjdGVkOyB1c2UgdGhlIHN0YW5kYXJkIGBmb3IuLi5pbmAgYWxnb3JpdGhtLlxuICAgICAgICAgIGZvckVhY2ggPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgdmFyIGlzRnVuY3Rpb24gPSBnZXRDbGFzcy5jYWxsKG9iamVjdCkgPT0gZnVuY3Rpb25DbGFzcywgcHJvcGVydHksIGlzQ29uc3RydWN0b3I7XG4gICAgICAgICAgICBmb3IgKHByb3BlcnR5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgICBpZiAoIShpc0Z1bmN0aW9uICYmIHByb3BlcnR5ID09IFwicHJvdG90eXBlXCIpICYmIGlzUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSAmJiAhKGlzQ29uc3RydWN0b3IgPSBwcm9wZXJ0eSA9PT0gXCJjb25zdHJ1Y3RvclwiKSkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gTWFudWFsbHkgaW52b2tlIHRoZSBjYWxsYmFjayBmb3IgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgZHVlIHRvXG4gICAgICAgICAgICAvLyBjcm9zcy1lbnZpcm9ubWVudCBpbmNvbnNpc3RlbmNpZXMuXG4gICAgICAgICAgICBpZiAoaXNDb25zdHJ1Y3RvciB8fCBpc1Byb3BlcnR5LmNhbGwob2JqZWN0LCAocHJvcGVydHkgPSBcImNvbnN0cnVjdG9yXCIpKSkge1xuICAgICAgICAgICAgICBjYWxsYmFjayhwcm9wZXJ0eSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm9yRWFjaChvYmplY3QsIGNhbGxiYWNrKTtcbiAgICAgIH07XG5cbiAgICAgIC8vIFB1YmxpYzogU2VyaWFsaXplcyBhIEphdmFTY3JpcHQgYHZhbHVlYCBhcyBhIEpTT04gc3RyaW5nLiBUaGUgb3B0aW9uYWxcbiAgICAgIC8vIGBmaWx0ZXJgIGFyZ3VtZW50IG1heSBzcGVjaWZ5IGVpdGhlciBhIGZ1bmN0aW9uIHRoYXQgYWx0ZXJzIGhvdyBvYmplY3QgYW5kXG4gICAgICAvLyBhcnJheSBtZW1iZXJzIGFyZSBzZXJpYWxpemVkLCBvciBhbiBhcnJheSBvZiBzdHJpbmdzIGFuZCBudW1iZXJzIHRoYXRcbiAgICAgIC8vIGluZGljYXRlcyB3aGljaCBwcm9wZXJ0aWVzIHNob3VsZCBiZSBzZXJpYWxpemVkLiBUaGUgb3B0aW9uYWwgYHdpZHRoYFxuICAgICAgLy8gYXJndW1lbnQgbWF5IGJlIGVpdGhlciBhIHN0cmluZyBvciBudW1iZXIgdGhhdCBzcGVjaWZpZXMgdGhlIGluZGVudGF0aW9uXG4gICAgICAvLyBsZXZlbCBvZiB0aGUgb3V0cHV0LlxuICAgICAgaWYgKCFoYXMoXCJqc29uLXN0cmluZ2lmeVwiKSkge1xuICAgICAgICAvLyBJbnRlcm5hbDogQSBtYXAgb2YgY29udHJvbCBjaGFyYWN0ZXJzIGFuZCB0aGVpciBlc2NhcGVkIGVxdWl2YWxlbnRzLlxuICAgICAgICB2YXIgRXNjYXBlcyA9IHtcbiAgICAgICAgICA5MjogXCJcXFxcXFxcXFwiLFxuICAgICAgICAgIDM0OiAnXFxcXFwiJyxcbiAgICAgICAgICA4OiBcIlxcXFxiXCIsXG4gICAgICAgICAgMTI6IFwiXFxcXGZcIixcbiAgICAgICAgICAxMDogXCJcXFxcblwiLFxuICAgICAgICAgIDEzOiBcIlxcXFxyXCIsXG4gICAgICAgICAgOTogXCJcXFxcdFwiXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IENvbnZlcnRzIGB2YWx1ZWAgaW50byBhIHplcm8tcGFkZGVkIHN0cmluZyBzdWNoIHRoYXQgaXRzXG4gICAgICAgIC8vIGxlbmd0aCBpcyBhdCBsZWFzdCBlcXVhbCB0byBgd2lkdGhgLiBUaGUgYHdpZHRoYCBtdXN0IGJlIDw9IDYuXG4gICAgICAgIHZhciBsZWFkaW5nWmVyb2VzID0gXCIwMDAwMDBcIjtcbiAgICAgICAgdmFyIHRvUGFkZGVkU3RyaW5nID0gZnVuY3Rpb24gKHdpZHRoLCB2YWx1ZSkge1xuICAgICAgICAgIC8vIFRoZSBgfHwgMGAgZXhwcmVzc2lvbiBpcyBuZWNlc3NhcnkgdG8gd29yayBhcm91bmQgYSBidWcgaW5cbiAgICAgICAgICAvLyBPcGVyYSA8PSA3LjU0dTIgd2hlcmUgYDAgPT0gLTBgLCBidXQgYFN0cmluZygtMCkgIT09IFwiMFwiYC5cbiAgICAgICAgICByZXR1cm4gKGxlYWRpbmdaZXJvZXMgKyAodmFsdWUgfHwgMCkpLnNsaWNlKC13aWR0aCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IERvdWJsZS1xdW90ZXMgYSBzdHJpbmcgYHZhbHVlYCwgcmVwbGFjaW5nIGFsbCBBU0NJSSBjb250cm9sXG4gICAgICAgIC8vIGNoYXJhY3RlcnMgKGNoYXJhY3RlcnMgd2l0aCBjb2RlIHVuaXQgdmFsdWVzIGJldHdlZW4gMCBhbmQgMzEpIHdpdGhcbiAgICAgICAgLy8gdGhlaXIgZXNjYXBlZCBlcXVpdmFsZW50cy4gVGhpcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGVcbiAgICAgICAgLy8gYFF1b3RlKHZhbHVlKWAgb3BlcmF0aW9uIGRlZmluZWQgaW4gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMy5cbiAgICAgICAgdmFyIHVuaWNvZGVQcmVmaXggPSBcIlxcXFx1MDBcIjtcbiAgICAgICAgdmFyIHF1b3RlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9ICdcIicsIGluZGV4ID0gMCwgbGVuZ3RoID0gdmFsdWUubGVuZ3RoLCB1c2VDaGFySW5kZXggPSAhY2hhckluZGV4QnVnZ3kgfHwgbGVuZ3RoID4gMTA7XG4gICAgICAgICAgdmFyIHN5bWJvbHMgPSB1c2VDaGFySW5kZXggJiYgKGNoYXJJbmRleEJ1Z2d5ID8gdmFsdWUuc3BsaXQoXCJcIikgOiB2YWx1ZSk7XG4gICAgICAgICAgZm9yICg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICB2YXIgY2hhckNvZGUgPSB2YWx1ZS5jaGFyQ29kZUF0KGluZGV4KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBjaGFyYWN0ZXIgaXMgYSBjb250cm9sIGNoYXJhY3RlciwgYXBwZW5kIGl0cyBVbmljb2RlIG9yXG4gICAgICAgICAgICAvLyBzaG9ydGhhbmQgZXNjYXBlIHNlcXVlbmNlOyBvdGhlcndpc2UsIGFwcGVuZCB0aGUgY2hhcmFjdGVyIGFzLWlzLlxuICAgICAgICAgICAgc3dpdGNoIChjaGFyQ29kZSkge1xuICAgICAgICAgICAgICBjYXNlIDg6IGNhc2UgOTogY2FzZSAxMDogY2FzZSAxMjogY2FzZSAxMzogY2FzZSAzNDogY2FzZSA5MjpcbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gRXNjYXBlc1tjaGFyQ29kZV07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlIDwgMzIpIHtcbiAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSB1bmljb2RlUHJlZml4ICsgdG9QYWRkZWRTdHJpbmcoMiwgY2hhckNvZGUudG9TdHJpbmcoMTYpKTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXN1bHQgKz0gdXNlQ2hhckluZGV4ID8gc3ltYm9sc1tpbmRleF0gOiB2YWx1ZS5jaGFyQXQoaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcmVzdWx0ICsgJ1wiJztcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogUmVjdXJzaXZlbHkgc2VyaWFsaXplcyBhbiBvYmplY3QuIEltcGxlbWVudHMgdGhlXG4gICAgICAgIC8vIGBTdHIoa2V5LCBob2xkZXIpYCwgYEpPKHZhbHVlKWAsIGFuZCBgSkEodmFsdWUpYCBvcGVyYXRpb25zLlxuICAgICAgICB2YXIgc2VyaWFsaXplID0gZnVuY3Rpb24gKHByb3BlcnR5LCBvYmplY3QsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCB3aGl0ZXNwYWNlLCBpbmRlbnRhdGlvbiwgc3RhY2spIHtcbiAgICAgICAgICB2YXIgdmFsdWUsIGNsYXNzTmFtZSwgeWVhciwgbW9udGgsIGRhdGUsIHRpbWUsIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLCBtaWxsaXNlY29uZHMsIHJlc3VsdHMsIGVsZW1lbnQsIGluZGV4LCBsZW5ndGgsIHByZWZpeCwgcmVzdWx0O1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBOZWNlc3NhcnkgZm9yIGhvc3Qgb2JqZWN0IHN1cHBvcnQuXG4gICAgICAgICAgICB2YWx1ZSA9IG9iamVjdFtwcm9wZXJ0eV07XG4gICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIiAmJiB2YWx1ZSkge1xuICAgICAgICAgICAgY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbCh2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoY2xhc3NOYW1lID09IGRhdGVDbGFzcyAmJiAhaXNQcm9wZXJ0eS5jYWxsKHZhbHVlLCBcInRvSlNPTlwiKSkge1xuICAgICAgICAgICAgICBpZiAodmFsdWUgPiAtMSAvIDAgJiYgdmFsdWUgPCAxIC8gMCkge1xuICAgICAgICAgICAgICAgIC8vIERhdGVzIGFyZSBzZXJpYWxpemVkIGFjY29yZGluZyB0byB0aGUgYERhdGUjdG9KU09OYCBtZXRob2RcbiAgICAgICAgICAgICAgICAvLyBzcGVjaWZpZWQgaW4gRVMgNS4xIHNlY3Rpb24gMTUuOS41LjQ0LiBTZWUgc2VjdGlvbiAxNS45LjEuMTVcbiAgICAgICAgICAgICAgICAvLyBmb3IgdGhlIElTTyA4NjAxIGRhdGUgdGltZSBzdHJpbmcgZm9ybWF0LlxuICAgICAgICAgICAgICAgIGlmIChnZXREYXkpIHtcbiAgICAgICAgICAgICAgICAgIC8vIE1hbnVhbGx5IGNvbXB1dGUgdGhlIHllYXIsIG1vbnRoLCBkYXRlLCBob3VycywgbWludXRlcyxcbiAgICAgICAgICAgICAgICAgIC8vIHNlY29uZHMsIGFuZCBtaWxsaXNlY29uZHMgaWYgdGhlIGBnZXRVVEMqYCBtZXRob2RzIGFyZVxuICAgICAgICAgICAgICAgICAgLy8gYnVnZ3kuIEFkYXB0ZWQgZnJvbSBAWWFmZmxlJ3MgYGRhdGUtc2hpbWAgcHJvamVjdC5cbiAgICAgICAgICAgICAgICAgIGRhdGUgPSBmbG9vcih2YWx1ZSAvIDg2NGU1KTtcbiAgICAgICAgICAgICAgICAgIGZvciAoeWVhciA9IGZsb29yKGRhdGUgLyAzNjUuMjQyNSkgKyAxOTcwIC0gMTsgZ2V0RGF5KHllYXIgKyAxLCAwKSA8PSBkYXRlOyB5ZWFyKyspO1xuICAgICAgICAgICAgICAgICAgZm9yIChtb250aCA9IGZsb29yKChkYXRlIC0gZ2V0RGF5KHllYXIsIDApKSAvIDMwLjQyKTsgZ2V0RGF5KHllYXIsIG1vbnRoICsgMSkgPD0gZGF0ZTsgbW9udGgrKyk7XG4gICAgICAgICAgICAgICAgICBkYXRlID0gMSArIGRhdGUgLSBnZXREYXkoeWVhciwgbW9udGgpO1xuICAgICAgICAgICAgICAgICAgLy8gVGhlIGB0aW1lYCB2YWx1ZSBzcGVjaWZpZXMgdGhlIHRpbWUgd2l0aGluIHRoZSBkYXkgKHNlZSBFU1xuICAgICAgICAgICAgICAgICAgLy8gNS4xIHNlY3Rpb24gMTUuOS4xLjIpLiBUaGUgZm9ybXVsYSBgKEEgJSBCICsgQikgJSBCYCBpcyB1c2VkXG4gICAgICAgICAgICAgICAgICAvLyB0byBjb21wdXRlIGBBIG1vZHVsbyBCYCwgYXMgdGhlIGAlYCBvcGVyYXRvciBkb2VzIG5vdFxuICAgICAgICAgICAgICAgICAgLy8gY29ycmVzcG9uZCB0byB0aGUgYG1vZHVsb2Agb3BlcmF0aW9uIGZvciBuZWdhdGl2ZSBudW1iZXJzLlxuICAgICAgICAgICAgICAgICAgdGltZSA9ICh2YWx1ZSAlIDg2NGU1ICsgODY0ZTUpICUgODY0ZTU7XG4gICAgICAgICAgICAgICAgICAvLyBUaGUgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMsIGFuZCBtaWxsaXNlY29uZHMgYXJlIG9idGFpbmVkIGJ5XG4gICAgICAgICAgICAgICAgICAvLyBkZWNvbXBvc2luZyB0aGUgdGltZSB3aXRoaW4gdGhlIGRheS4gU2VlIHNlY3Rpb24gMTUuOS4xLjEwLlxuICAgICAgICAgICAgICAgICAgaG91cnMgPSBmbG9vcih0aW1lIC8gMzZlNSkgJSAyNDtcbiAgICAgICAgICAgICAgICAgIG1pbnV0ZXMgPSBmbG9vcih0aW1lIC8gNmU0KSAlIDYwO1xuICAgICAgICAgICAgICAgICAgc2Vjb25kcyA9IGZsb29yKHRpbWUgLyAxZTMpICUgNjA7XG4gICAgICAgICAgICAgICAgICBtaWxsaXNlY29uZHMgPSB0aW1lICUgMWUzO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB5ZWFyID0gdmFsdWUuZ2V0VVRDRnVsbFllYXIoKTtcbiAgICAgICAgICAgICAgICAgIG1vbnRoID0gdmFsdWUuZ2V0VVRDTW9udGgoKTtcbiAgICAgICAgICAgICAgICAgIGRhdGUgPSB2YWx1ZS5nZXRVVENEYXRlKCk7XG4gICAgICAgICAgICAgICAgICBob3VycyA9IHZhbHVlLmdldFVUQ0hvdXJzKCk7XG4gICAgICAgICAgICAgICAgICBtaW51dGVzID0gdmFsdWUuZ2V0VVRDTWludXRlcygpO1xuICAgICAgICAgICAgICAgICAgc2Vjb25kcyA9IHZhbHVlLmdldFVUQ1NlY29uZHMoKTtcbiAgICAgICAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IHZhbHVlLmdldFVUQ01pbGxpc2Vjb25kcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBTZXJpYWxpemUgZXh0ZW5kZWQgeWVhcnMgY29ycmVjdGx5LlxuICAgICAgICAgICAgICAgIHZhbHVlID0gKHllYXIgPD0gMCB8fCB5ZWFyID49IDFlNCA/ICh5ZWFyIDwgMCA/IFwiLVwiIDogXCIrXCIpICsgdG9QYWRkZWRTdHJpbmcoNiwgeWVhciA8IDAgPyAteWVhciA6IHllYXIpIDogdG9QYWRkZWRTdHJpbmcoNCwgeWVhcikpICtcbiAgICAgICAgICAgICAgICAgIFwiLVwiICsgdG9QYWRkZWRTdHJpbmcoMiwgbW9udGggKyAxKSArIFwiLVwiICsgdG9QYWRkZWRTdHJpbmcoMiwgZGF0ZSkgK1xuICAgICAgICAgICAgICAgICAgLy8gTW9udGhzLCBkYXRlcywgaG91cnMsIG1pbnV0ZXMsIGFuZCBzZWNvbmRzIHNob3VsZCBoYXZlIHR3b1xuICAgICAgICAgICAgICAgICAgLy8gZGlnaXRzOyBtaWxsaXNlY29uZHMgc2hvdWxkIGhhdmUgdGhyZWUuXG4gICAgICAgICAgICAgICAgICBcIlRcIiArIHRvUGFkZGVkU3RyaW5nKDIsIGhvdXJzKSArIFwiOlwiICsgdG9QYWRkZWRTdHJpbmcoMiwgbWludXRlcykgKyBcIjpcIiArIHRvUGFkZGVkU3RyaW5nKDIsIHNlY29uZHMpICtcbiAgICAgICAgICAgICAgICAgIC8vIE1pbGxpc2Vjb25kcyBhcmUgb3B0aW9uYWwgaW4gRVMgNS4wLCBidXQgcmVxdWlyZWQgaW4gNS4xLlxuICAgICAgICAgICAgICAgICAgXCIuXCIgKyB0b1BhZGRlZFN0cmluZygzLCBtaWxsaXNlY29uZHMpICsgXCJaXCI7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZS50b0pTT04gPT0gXCJmdW5jdGlvblwiICYmICgoY2xhc3NOYW1lICE9IG51bWJlckNsYXNzICYmIGNsYXNzTmFtZSAhPSBzdHJpbmdDbGFzcyAmJiBjbGFzc05hbWUgIT0gYXJyYXlDbGFzcykgfHwgaXNQcm9wZXJ0eS5jYWxsKHZhbHVlLCBcInRvSlNPTlwiKSkpIHtcbiAgICAgICAgICAgICAgLy8gUHJvdG90eXBlIDw9IDEuNi4xIGFkZHMgbm9uLXN0YW5kYXJkIGB0b0pTT05gIG1ldGhvZHMgdG8gdGhlXG4gICAgICAgICAgICAgIC8vIGBOdW1iZXJgLCBgU3RyaW5nYCwgYERhdGVgLCBhbmQgYEFycmF5YCBwcm90b3R5cGVzLiBKU09OIDNcbiAgICAgICAgICAgICAgLy8gaWdub3JlcyBhbGwgYHRvSlNPTmAgbWV0aG9kcyBvbiB0aGVzZSBvYmplY3RzIHVubGVzcyB0aGV5IGFyZVxuICAgICAgICAgICAgICAvLyBkZWZpbmVkIGRpcmVjdGx5IG9uIGFuIGluc3RhbmNlLlxuICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvSlNPTihwcm9wZXJ0eSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgLy8gSWYgYSByZXBsYWNlbWVudCBmdW5jdGlvbiB3YXMgcHJvdmlkZWQsIGNhbGwgaXQgdG8gb2J0YWluIHRoZSB2YWx1ZVxuICAgICAgICAgICAgLy8gZm9yIHNlcmlhbGl6YXRpb24uXG4gICAgICAgICAgICB2YWx1ZSA9IGNhbGxiYWNrLmNhbGwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbCh2YWx1ZSk7XG4gICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBib29sZWFuQ2xhc3MpIHtcbiAgICAgICAgICAgIC8vIEJvb2xlYW5zIGFyZSByZXByZXNlbnRlZCBsaXRlcmFsbHkuXG4gICAgICAgICAgICByZXR1cm4gXCJcIiArIHZhbHVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IG51bWJlckNsYXNzKSB7XG4gICAgICAgICAgICAvLyBKU09OIG51bWJlcnMgbXVzdCBiZSBmaW5pdGUuIGBJbmZpbml0eWAgYW5kIGBOYU5gIGFyZSBzZXJpYWxpemVkIGFzXG4gICAgICAgICAgICAvLyBgXCJudWxsXCJgLlxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlID4gLTEgLyAwICYmIHZhbHVlIDwgMSAvIDAgPyBcIlwiICsgdmFsdWUgOiBcIm51bGxcIjtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTmFtZSA9PSBzdHJpbmdDbGFzcykge1xuICAgICAgICAgICAgLy8gU3RyaW5ncyBhcmUgZG91YmxlLXF1b3RlZCBhbmQgZXNjYXBlZC5cbiAgICAgICAgICAgIHJldHVybiBxdW90ZShcIlwiICsgdmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXJpYWxpemUgb2JqZWN0cyBhbmQgYXJyYXlzLlxuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGN5Y2xpYyBzdHJ1Y3R1cmVzLiBUaGlzIGlzIGEgbGluZWFyIHNlYXJjaDsgcGVyZm9ybWFuY2VcbiAgICAgICAgICAgIC8vIGlzIGludmVyc2VseSBwcm9wb3J0aW9uYWwgdG8gdGhlIG51bWJlciBvZiB1bmlxdWUgbmVzdGVkIG9iamVjdHMuXG4gICAgICAgICAgICBmb3IgKGxlbmd0aCA9IHN0YWNrLmxlbmd0aDsgbGVuZ3RoLS07KSB7XG4gICAgICAgICAgICAgIGlmIChzdGFja1tsZW5ndGhdID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEN5Y2xpYyBzdHJ1Y3R1cmVzIGNhbm5vdCBiZSBzZXJpYWxpemVkIGJ5IGBKU09OLnN0cmluZ2lmeWAuXG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEFkZCB0aGUgb2JqZWN0IHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICAgICAgICAgIHN0YWNrLnB1c2godmFsdWUpO1xuICAgICAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgLy8gU2F2ZSB0aGUgY3VycmVudCBpbmRlbnRhdGlvbiBsZXZlbCBhbmQgaW5kZW50IG9uZSBhZGRpdGlvbmFsIGxldmVsLlxuICAgICAgICAgICAgcHJlZml4ID0gaW5kZW50YXRpb247XG4gICAgICAgICAgICBpbmRlbnRhdGlvbiArPSB3aGl0ZXNwYWNlO1xuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBhcnJheUNsYXNzKSB7XG4gICAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZSBhcnJheSBlbGVtZW50cy5cbiAgICAgICAgICAgICAgZm9yIChpbmRleCA9IDAsIGxlbmd0aCA9IHZhbHVlLmxlbmd0aDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50ID0gc2VyaWFsaXplKGluZGV4LCB2YWx1ZSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIHdoaXRlc3BhY2UsIGluZGVudGF0aW9uLCBzdGFjayk7XG4gICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGVsZW1lbnQgPT09IHVuZGVmID8gXCJudWxsXCIgOiBlbGVtZW50KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHRzLmxlbmd0aCA/ICh3aGl0ZXNwYWNlID8gXCJbXFxuXCIgKyBpbmRlbnRhdGlvbiArIHJlc3VsdHMuam9pbihcIixcXG5cIiArIGluZGVudGF0aW9uKSArIFwiXFxuXCIgKyBwcmVmaXggKyBcIl1cIiA6IChcIltcIiArIHJlc3VsdHMuam9pbihcIixcIikgKyBcIl1cIikpIDogXCJbXVwiO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gUmVjdXJzaXZlbHkgc2VyaWFsaXplIG9iamVjdCBtZW1iZXJzLiBNZW1iZXJzIGFyZSBzZWxlY3RlZCBmcm9tXG4gICAgICAgICAgICAgIC8vIGVpdGhlciBhIHVzZXItc3BlY2lmaWVkIGxpc3Qgb2YgcHJvcGVydHkgbmFtZXMsIG9yIHRoZSBvYmplY3RcbiAgICAgICAgICAgICAgLy8gaXRzZWxmLlxuICAgICAgICAgICAgICBmb3JFYWNoKHByb3BlcnRpZXMgfHwgdmFsdWUsIGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gc2VyaWFsaXplKHByb3BlcnR5LCB2YWx1ZSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIHdoaXRlc3BhY2UsIGluZGVudGF0aW9uLCBzdGFjayk7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgIT09IHVuZGVmKSB7XG4gICAgICAgICAgICAgICAgICAvLyBBY2NvcmRpbmcgdG8gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMzogXCJJZiBgZ2FwYCB7d2hpdGVzcGFjZX1cbiAgICAgICAgICAgICAgICAgIC8vIGlzIG5vdCB0aGUgZW1wdHkgc3RyaW5nLCBsZXQgYG1lbWJlcmAge3F1b3RlKHByb3BlcnR5KSArIFwiOlwifVxuICAgICAgICAgICAgICAgICAgLy8gYmUgdGhlIGNvbmNhdGVuYXRpb24gb2YgYG1lbWJlcmAgYW5kIHRoZSBgc3BhY2VgIGNoYXJhY3Rlci5cIlxuICAgICAgICAgICAgICAgICAgLy8gVGhlIFwiYHNwYWNlYCBjaGFyYWN0ZXJcIiByZWZlcnMgdG8gdGhlIGxpdGVyYWwgc3BhY2VcbiAgICAgICAgICAgICAgICAgIC8vIGNoYXJhY3Rlciwgbm90IHRoZSBgc3BhY2VgIHt3aWR0aH0gYXJndW1lbnQgcHJvdmlkZWQgdG9cbiAgICAgICAgICAgICAgICAgIC8vIGBKU09OLnN0cmluZ2lmeWAuXG4gICAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2gocXVvdGUocHJvcGVydHkpICsgXCI6XCIgKyAod2hpdGVzcGFjZSA/IFwiIFwiIDogXCJcIikgKyBlbGVtZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHRzLmxlbmd0aCA/ICh3aGl0ZXNwYWNlID8gXCJ7XFxuXCIgKyBpbmRlbnRhdGlvbiArIHJlc3VsdHMuam9pbihcIixcXG5cIiArIGluZGVudGF0aW9uKSArIFwiXFxuXCIgKyBwcmVmaXggKyBcIn1cIiA6IChcIntcIiArIHJlc3VsdHMuam9pbihcIixcIikgKyBcIn1cIikpIDogXCJ7fVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBvYmplY3QgZnJvbSB0aGUgdHJhdmVyc2VkIG9iamVjdCBzdGFjay5cbiAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUHVibGljOiBgSlNPTi5zdHJpbmdpZnlgLiBTZWUgRVMgNS4xIHNlY3Rpb24gMTUuMTIuMy5cbiAgICAgICAgZXhwb3J0cy5zdHJpbmdpZnkgPSBmdW5jdGlvbiAoc291cmNlLCBmaWx0ZXIsIHdpZHRoKSB7XG4gICAgICAgICAgdmFyIHdoaXRlc3BhY2UsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCBjbGFzc05hbWU7XG4gICAgICAgICAgaWYgKHR5cGVvZiBmaWx0ZXIgPT0gXCJmdW5jdGlvblwiIHx8IHR5cGVvZiBmaWx0ZXIgPT0gXCJvYmplY3RcIiAmJiBmaWx0ZXIpIHtcbiAgICAgICAgICAgIGlmICgoY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbChmaWx0ZXIpKSA9PSBmdW5jdGlvbkNsYXNzKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrID0gZmlsdGVyO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gYXJyYXlDbGFzcykge1xuICAgICAgICAgICAgICAvLyBDb252ZXJ0IHRoZSBwcm9wZXJ0eSBuYW1lcyBhcnJheSBpbnRvIGEgbWFrZXNoaWZ0IHNldC5cbiAgICAgICAgICAgICAgcHJvcGVydGllcyA9IHt9O1xuICAgICAgICAgICAgICBmb3IgKHZhciBpbmRleCA9IDAsIGxlbmd0aCA9IGZpbHRlci5sZW5ndGgsIHZhbHVlOyBpbmRleCA8IGxlbmd0aDsgdmFsdWUgPSBmaWx0ZXJbaW5kZXgrK10sICgoY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbCh2YWx1ZSkpLCBjbGFzc05hbWUgPT0gc3RyaW5nQ2xhc3MgfHwgY2xhc3NOYW1lID09IG51bWJlckNsYXNzKSAmJiAocHJvcGVydGllc1t2YWx1ZV0gPSAxKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh3aWR0aCkge1xuICAgICAgICAgICAgaWYgKChjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKHdpZHRoKSkgPT0gbnVtYmVyQ2xhc3MpIHtcbiAgICAgICAgICAgICAgLy8gQ29udmVydCB0aGUgYHdpZHRoYCB0byBhbiBpbnRlZ2VyIGFuZCBjcmVhdGUgYSBzdHJpbmcgY29udGFpbmluZ1xuICAgICAgICAgICAgICAvLyBgd2lkdGhgIG51bWJlciBvZiBzcGFjZSBjaGFyYWN0ZXJzLlxuICAgICAgICAgICAgICBpZiAoKHdpZHRoIC09IHdpZHRoICUgMSkgPiAwKSB7XG4gICAgICAgICAgICAgICAgZm9yICh3aGl0ZXNwYWNlID0gXCJcIiwgd2lkdGggPiAxMCAmJiAod2lkdGggPSAxMCk7IHdoaXRlc3BhY2UubGVuZ3RoIDwgd2lkdGg7IHdoaXRlc3BhY2UgKz0gXCIgXCIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTmFtZSA9PSBzdHJpbmdDbGFzcykge1xuICAgICAgICAgICAgICB3aGl0ZXNwYWNlID0gd2lkdGgubGVuZ3RoIDw9IDEwID8gd2lkdGggOiB3aWR0aC5zbGljZSgwLCAxMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIE9wZXJhIDw9IDcuNTR1MiBkaXNjYXJkcyB0aGUgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBlbXB0eSBzdHJpbmcga2V5c1xuICAgICAgICAgIC8vIChgXCJcImApIG9ubHkgaWYgdGhleSBhcmUgdXNlZCBkaXJlY3RseSB3aXRoaW4gYW4gb2JqZWN0IG1lbWJlciBsaXN0XG4gICAgICAgICAgLy8gKGUuZy4sIGAhKFwiXCIgaW4geyBcIlwiOiAxfSlgKS5cbiAgICAgICAgICByZXR1cm4gc2VyaWFsaXplKFwiXCIsICh2YWx1ZSA9IHt9LCB2YWx1ZVtcIlwiXSA9IHNvdXJjZSwgdmFsdWUpLCBjYWxsYmFjaywgcHJvcGVydGllcywgd2hpdGVzcGFjZSwgXCJcIiwgW10pO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBQdWJsaWM6IFBhcnNlcyBhIEpTT04gc291cmNlIHN0cmluZy5cbiAgICAgIGlmICghaGFzKFwianNvbi1wYXJzZVwiKSkge1xuICAgICAgICB2YXIgZnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogQSBtYXAgb2YgZXNjYXBlZCBjb250cm9sIGNoYXJhY3RlcnMgYW5kIHRoZWlyIHVuZXNjYXBlZFxuICAgICAgICAvLyBlcXVpdmFsZW50cy5cbiAgICAgICAgdmFyIFVuZXNjYXBlcyA9IHtcbiAgICAgICAgICA5MjogXCJcXFxcXCIsXG4gICAgICAgICAgMzQ6ICdcIicsXG4gICAgICAgICAgNDc6IFwiL1wiLFxuICAgICAgICAgIDk4OiBcIlxcYlwiLFxuICAgICAgICAgIDExNjogXCJcXHRcIixcbiAgICAgICAgICAxMTA6IFwiXFxuXCIsXG4gICAgICAgICAgMTAyOiBcIlxcZlwiLFxuICAgICAgICAgIDExNDogXCJcXHJcIlxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBTdG9yZXMgdGhlIHBhcnNlciBzdGF0ZS5cbiAgICAgICAgdmFyIEluZGV4LCBTb3VyY2U7XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFJlc2V0cyB0aGUgcGFyc2VyIHN0YXRlIGFuZCB0aHJvd3MgYSBgU3ludGF4RXJyb3JgLlxuICAgICAgICB2YXIgYWJvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgSW5kZXggPSBTb3VyY2UgPSBudWxsO1xuICAgICAgICAgIHRocm93IFN5bnRheEVycm9yKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFJldHVybnMgdGhlIG5leHQgdG9rZW4sIG9yIGBcIiRcImAgaWYgdGhlIHBhcnNlciBoYXMgcmVhY2hlZFxuICAgICAgICAvLyB0aGUgZW5kIG9mIHRoZSBzb3VyY2Ugc3RyaW5nLiBBIHRva2VuIG1heSBiZSBhIHN0cmluZywgbnVtYmVyLCBgbnVsbGBcbiAgICAgICAgLy8gbGl0ZXJhbCwgb3IgQm9vbGVhbiBsaXRlcmFsLlxuICAgICAgICB2YXIgbGV4ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBzb3VyY2UgPSBTb3VyY2UsIGxlbmd0aCA9IHNvdXJjZS5sZW5ndGgsIHZhbHVlLCBiZWdpbiwgcG9zaXRpb24sIGlzU2lnbmVkLCBjaGFyQ29kZTtcbiAgICAgICAgICB3aGlsZSAoSW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpO1xuICAgICAgICAgICAgc3dpdGNoIChjaGFyQ29kZSkge1xuICAgICAgICAgICAgICBjYXNlIDk6IGNhc2UgMTA6IGNhc2UgMTM6IGNhc2UgMzI6XG4gICAgICAgICAgICAgICAgLy8gU2tpcCB3aGl0ZXNwYWNlIHRva2VucywgaW5jbHVkaW5nIHRhYnMsIGNhcnJpYWdlIHJldHVybnMsIGxpbmVcbiAgICAgICAgICAgICAgICAvLyBmZWVkcywgYW5kIHNwYWNlIGNoYXJhY3RlcnMuXG4gICAgICAgICAgICAgICAgSW5kZXgrKztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAxMjM6IGNhc2UgMTI1OiBjYXNlIDkxOiBjYXNlIDkzOiBjYXNlIDU4OiBjYXNlIDQ0OlxuICAgICAgICAgICAgICAgIC8vIFBhcnNlIGEgcHVuY3R1YXRvciB0b2tlbiAoYHtgLCBgfWAsIGBbYCwgYF1gLCBgOmAsIG9yIGAsYCkgYXRcbiAgICAgICAgICAgICAgICAvLyB0aGUgY3VycmVudCBwb3NpdGlvbi5cbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGNoYXJJbmRleEJ1Z2d5ID8gc291cmNlLmNoYXJBdChJbmRleCkgOiBzb3VyY2VbSW5kZXhdO1xuICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICBjYXNlIDM0OlxuICAgICAgICAgICAgICAgIC8vIGBcImAgZGVsaW1pdHMgYSBKU09OIHN0cmluZzsgYWR2YW5jZSB0byB0aGUgbmV4dCBjaGFyYWN0ZXIgYW5kXG4gICAgICAgICAgICAgICAgLy8gYmVnaW4gcGFyc2luZyB0aGUgc3RyaW5nLiBTdHJpbmcgdG9rZW5zIGFyZSBwcmVmaXhlZCB3aXRoIHRoZVxuICAgICAgICAgICAgICAgIC8vIHNlbnRpbmVsIGBAYCBjaGFyYWN0ZXIgdG8gZGlzdGluZ3Vpc2ggdGhlbSBmcm9tIHB1bmN0dWF0b3JzIGFuZFxuICAgICAgICAgICAgICAgIC8vIGVuZC1vZi1zdHJpbmcgdG9rZW5zLlxuICAgICAgICAgICAgICAgIGZvciAodmFsdWUgPSBcIkBcIiwgSW5kZXgrKzsgSW5kZXggPCBsZW5ndGg7KSB7XG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA8IDMyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFVuZXNjYXBlZCBBU0NJSSBjb250cm9sIGNoYXJhY3RlcnMgKHRob3NlIHdpdGggYSBjb2RlIHVuaXRcbiAgICAgICAgICAgICAgICAgICAgLy8gbGVzcyB0aGFuIHRoZSBzcGFjZSBjaGFyYWN0ZXIpIGFyZSBub3QgcGVybWl0dGVkLlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGFyQ29kZSA9PSA5Mikge1xuICAgICAgICAgICAgICAgICAgICAvLyBBIHJldmVyc2Ugc29saWR1cyAoYFxcYCkgbWFya3MgdGhlIGJlZ2lubmluZyBvZiBhbiBlc2NhcGVkXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnRyb2wgY2hhcmFjdGVyIChpbmNsdWRpbmcgYFwiYCwgYFxcYCwgYW5kIGAvYCkgb3IgVW5pY29kZVxuICAgICAgICAgICAgICAgICAgICAvLyBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoY2hhckNvZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjYXNlIDkyOiBjYXNlIDM0OiBjYXNlIDQ3OiBjYXNlIDk4OiBjYXNlIDExNjogY2FzZSAxMTA6IGNhc2UgMTAyOiBjYXNlIDExNDpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldml2ZSBlc2NhcGVkIGNvbnRyb2wgY2hhcmFjdGVycy5cbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlICs9IFVuZXNjYXBlc1tjaGFyQ29kZV07XG4gICAgICAgICAgICAgICAgICAgICAgICBJbmRleCsrO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMTc6XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBgXFx1YCBtYXJrcyB0aGUgYmVnaW5uaW5nIG9mIGEgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBZHZhbmNlIHRvIHRoZSBmaXJzdCBjaGFyYWN0ZXIgYW5kIHZhbGlkYXRlIHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm91ci1kaWdpdCBjb2RlIHBvaW50LlxuICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW4gPSArK0luZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwb3NpdGlvbiA9IEluZGV4ICsgNDsgSW5kZXggPCBwb3NpdGlvbjsgSW5kZXgrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSB2YWxpZCBzZXF1ZW5jZSBjb21wcmlzZXMgZm91ciBoZXhkaWdpdHMgKGNhc2UtXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluc2Vuc2l0aXZlKSB0aGF0IGZvcm0gYSBzaW5nbGUgaGV4YWRlY2ltYWwgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3IHx8IGNoYXJDb2RlID49IDk3ICYmIGNoYXJDb2RlIDw9IDEwMiB8fCBjaGFyQ29kZSA+PSA2NSAmJiBjaGFyQ29kZSA8PSA3MCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnZhbGlkIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldml2ZSB0aGUgZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSArPSBmcm9tQ2hhckNvZGUoXCIweFwiICsgc291cmNlLnNsaWNlKGJlZ2luLCBJbmRleCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEludmFsaWQgZXNjYXBlIHNlcXVlbmNlLlxuICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDM0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gQW4gdW5lc2NhcGVkIGRvdWJsZS1xdW90ZSBjaGFyYWN0ZXIgbWFya3MgdGhlIGVuZCBvZiB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAvLyBzdHJpbmcuXG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIGJlZ2luID0gSW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIC8vIE9wdGltaXplIGZvciB0aGUgY29tbW9uIGNhc2Ugd2hlcmUgYSBzdHJpbmcgaXMgdmFsaWQuXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaGFyQ29kZSA+PSAzMiAmJiBjaGFyQ29kZSAhPSA5MiAmJiBjaGFyQ29kZSAhPSAzNCkge1xuICAgICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gQXBwZW5kIHRoZSBzdHJpbmcgYXMtaXMuXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlICs9IHNvdXJjZS5zbGljZShiZWdpbiwgSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpID09IDM0KSB7XG4gICAgICAgICAgICAgICAgICAvLyBBZHZhbmNlIHRvIHRoZSBuZXh0IGNoYXJhY3RlciBhbmQgcmV0dXJuIHRoZSByZXZpdmVkIHN0cmluZy5cbiAgICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFVudGVybWluYXRlZCBzdHJpbmcuXG4gICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAvLyBQYXJzZSBudW1iZXJzIGFuZCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBiZWdpbiA9IEluZGV4O1xuICAgICAgICAgICAgICAgIC8vIEFkdmFuY2UgcGFzdCB0aGUgbmVnYXRpdmUgc2lnbiwgaWYgb25lIGlzIHNwZWNpZmllZC5cbiAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gNDUpIHtcbiAgICAgICAgICAgICAgICAgIGlzU2lnbmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFBhcnNlIGFuIGludGVnZXIgb3IgZmxvYXRpbmctcG9pbnQgdmFsdWUuXG4gICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KSB7XG4gICAgICAgICAgICAgICAgICAvLyBMZWFkaW5nIHplcm9lcyBhcmUgaW50ZXJwcmV0ZWQgYXMgb2N0YWwgbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gNDggJiYgKChjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4ICsgMSkpLCBjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1NykpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWxsZWdhbCBvY3RhbCBsaXRlcmFsLlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgaXNTaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBpbnRlZ2VyIGNvbXBvbmVudC5cbiAgICAgICAgICAgICAgICAgIGZvciAoOyBJbmRleCA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBJbmRleCsrKTtcbiAgICAgICAgICAgICAgICAgIC8vIEZsb2F0cyBjYW5ub3QgY29udGFpbiBhIGxlYWRpbmcgZGVjaW1hbCBwb2ludDsgaG93ZXZlciwgdGhpc1xuICAgICAgICAgICAgICAgICAgLy8gY2FzZSBpcyBhbHJlYWR5IGFjY291bnRlZCBmb3IgYnkgdGhlIHBhcnNlci5cbiAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuY2hhckNvZGVBdChJbmRleCkgPT0gNDYpIHtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSArK0luZGV4O1xuICAgICAgICAgICAgICAgICAgICAvLyBQYXJzZSB0aGUgZGVjaW1hbCBjb21wb25lbnQuXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBwb3NpdGlvbiA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQocG9zaXRpb24pKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBwb3NpdGlvbisrKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gSWxsZWdhbCB0cmFpbGluZyBkZWNpbWFsLlxuICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgSW5kZXggPSBwb3NpdGlvbjtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIGV4cG9uZW50cy4gVGhlIGBlYCBkZW5vdGluZyB0aGUgZXhwb25lbnQgaXNcbiAgICAgICAgICAgICAgICAgIC8vIGNhc2UtaW5zZW5zaXRpdmUuXG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSAxMDEgfHwgY2hhckNvZGUgPT0gNjkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdCgrK0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2tpcCBwYXN0IHRoZSBzaWduIGZvbGxvd2luZyB0aGUgZXhwb25lbnQsIGlmIG9uZSBpc1xuICAgICAgICAgICAgICAgICAgICAvLyBzcGVjaWZpZWQuXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSA0MyB8fCBjaGFyQ29kZSA9PSA0NSkge1xuICAgICAgICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgdGhlIGV4cG9uZW50aWFsIGNvbXBvbmVudC5cbiAgICAgICAgICAgICAgICAgICAgZm9yIChwb3NpdGlvbiA9IEluZGV4OyBwb3NpdGlvbiA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQocG9zaXRpb24pKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBwb3NpdGlvbisrKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gSWxsZWdhbCBlbXB0eSBleHBvbmVudC5cbiAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEluZGV4ID0gcG9zaXRpb247XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAvLyBDb2VyY2UgdGhlIHBhcnNlZCB2YWx1ZSB0byBhIEphdmFTY3JpcHQgbnVtYmVyLlxuICAgICAgICAgICAgICAgICAgcmV0dXJuICtzb3VyY2Uuc2xpY2UoYmVnaW4sIEluZGV4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gQSBuZWdhdGl2ZSBzaWduIG1heSBvbmx5IHByZWNlZGUgbnVtYmVycy5cbiAgICAgICAgICAgICAgICBpZiAoaXNTaWduZWQpIHtcbiAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIGB0cnVlYCwgYGZhbHNlYCwgYW5kIGBudWxsYCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09IFwidHJ1ZVwiKSB7XG4gICAgICAgICAgICAgICAgICBJbmRleCArPSA0O1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2Uuc2xpY2UoSW5kZXgsIEluZGV4ICsgNSkgPT0gXCJmYWxzZVwiKSB7XG4gICAgICAgICAgICAgICAgICBJbmRleCArPSA1O1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09IFwibnVsbFwiKSB7XG4gICAgICAgICAgICAgICAgICBJbmRleCArPSA0O1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFVucmVjb2duaXplZCB0b2tlbi5cbiAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBSZXR1cm4gdGhlIHNlbnRpbmVsIGAkYCBjaGFyYWN0ZXIgaWYgdGhlIHBhcnNlciBoYXMgcmVhY2hlZCB0aGUgZW5kXG4gICAgICAgICAgLy8gb2YgdGhlIHNvdXJjZSBzdHJpbmcuXG4gICAgICAgICAgcmV0dXJuIFwiJFwiO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBQYXJzZXMgYSBKU09OIGB2YWx1ZWAgdG9rZW4uXG4gICAgICAgIHZhciBnZXQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICB2YXIgcmVzdWx0cywgaGFzTWVtYmVycztcbiAgICAgICAgICBpZiAodmFsdWUgPT0gXCIkXCIpIHtcbiAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgZW5kIG9mIGlucHV0LlxuICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBpZiAoKGNoYXJJbmRleEJ1Z2d5ID8gdmFsdWUuY2hhckF0KDApIDogdmFsdWVbMF0pID09IFwiQFwiKSB7XG4gICAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgc2VudGluZWwgYEBgIGNoYXJhY3Rlci5cbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnNsaWNlKDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gUGFyc2Ugb2JqZWN0IGFuZCBhcnJheSBsaXRlcmFscy5cbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIltcIikge1xuICAgICAgICAgICAgICAvLyBQYXJzZXMgYSBKU09OIGFycmF5LCByZXR1cm5pbmcgYSBuZXcgSmF2YVNjcmlwdCBhcnJheS5cbiAgICAgICAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgICBmb3IgKDs7IGhhc01lbWJlcnMgfHwgKGhhc01lbWJlcnMgPSB0cnVlKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gbGV4KCk7XG4gICAgICAgICAgICAgICAgLy8gQSBjbG9zaW5nIHNxdWFyZSBicmFja2V0IG1hcmtzIHRoZSBlbmQgb2YgdGhlIGFycmF5IGxpdGVyYWwuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiXVwiKSB7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGFycmF5IGxpdGVyYWwgY29udGFpbnMgZWxlbWVudHMsIHRoZSBjdXJyZW50IHRva2VuXG4gICAgICAgICAgICAgICAgLy8gc2hvdWxkIGJlIGEgY29tbWEgc2VwYXJhdGluZyB0aGUgcHJldmlvdXMgZWxlbWVudCBmcm9tIHRoZVxuICAgICAgICAgICAgICAgIC8vIG5leHQuXG4gICAgICAgICAgICAgICAgaWYgKGhhc01lbWJlcnMpIHtcbiAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIixcIikge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJdXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBVbmV4cGVjdGVkIHRyYWlsaW5nIGAsYCBpbiBhcnJheSBsaXRlcmFsLlxuICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEEgYCxgIG11c3Qgc2VwYXJhdGUgZWFjaCBhcnJheSBlbGVtZW50LlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBFbGlzaW9ucyBhbmQgbGVhZGluZyBjb21tYXMgYXJlIG5vdCBwZXJtaXR0ZWQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiKSB7XG4gICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goZ2V0KHZhbHVlKSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID09IFwie1wiKSB7XG4gICAgICAgICAgICAgIC8vIFBhcnNlcyBhIEpTT04gb2JqZWN0LCByZXR1cm5pbmcgYSBuZXcgSmF2YVNjcmlwdCBvYmplY3QuXG4gICAgICAgICAgICAgIHJlc3VsdHMgPSB7fTtcbiAgICAgICAgICAgICAgZm9yICg7OyBoYXNNZW1iZXJzIHx8IChoYXNNZW1iZXJzID0gdHJ1ZSkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgIC8vIEEgY2xvc2luZyBjdXJseSBicmFjZSBtYXJrcyB0aGUgZW5kIG9mIHRoZSBvYmplY3QgbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJ9XCIpIHtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgb2JqZWN0IGxpdGVyYWwgY29udGFpbnMgbWVtYmVycywgdGhlIGN1cnJlbnQgdG9rZW5cbiAgICAgICAgICAgICAgICAvLyBzaG91bGQgYmUgYSBjb21tYSBzZXBhcmF0b3IuXG4gICAgICAgICAgICAgICAgaWYgKGhhc01lbWJlcnMpIHtcbiAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIixcIikge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJ9XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBVbmV4cGVjdGVkIHRyYWlsaW5nIGAsYCBpbiBvYmplY3QgbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBBIGAsYCBtdXN0IHNlcGFyYXRlIGVhY2ggb2JqZWN0IG1lbWJlci5cbiAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTGVhZGluZyBjb21tYXMgYXJlIG5vdCBwZXJtaXR0ZWQsIG9iamVjdCBwcm9wZXJ0eSBuYW1lcyBtdXN0IGJlXG4gICAgICAgICAgICAgICAgLy8gZG91YmxlLXF1b3RlZCBzdHJpbmdzLCBhbmQgYSBgOmAgbXVzdCBzZXBhcmF0ZSBlYWNoIHByb3BlcnR5XG4gICAgICAgICAgICAgICAgLy8gbmFtZSBhbmQgdmFsdWUuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiIHx8IHR5cGVvZiB2YWx1ZSAhPSBcInN0cmluZ1wiIHx8IChjaGFySW5kZXhCdWdneSA/IHZhbHVlLmNoYXJBdCgwKSA6IHZhbHVlWzBdKSAhPSBcIkBcIiB8fCBsZXgoKSAhPSBcIjpcIikge1xuICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzdWx0c1t2YWx1ZS5zbGljZSgxKV0gPSBnZXQobGV4KCkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gVW5leHBlY3RlZCB0b2tlbiBlbmNvdW50ZXJlZC5cbiAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogVXBkYXRlcyBhIHRyYXZlcnNlZCBvYmplY3QgbWVtYmVyLlxuICAgICAgICB2YXIgdXBkYXRlID0gZnVuY3Rpb24gKHNvdXJjZSwgcHJvcGVydHksIGNhbGxiYWNrKSB7XG4gICAgICAgICAgdmFyIGVsZW1lbnQgPSB3YWxrKHNvdXJjZSwgcHJvcGVydHksIGNhbGxiYWNrKTtcbiAgICAgICAgICBpZiAoZWxlbWVudCA9PT0gdW5kZWYpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBzb3VyY2VbcHJvcGVydHldO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzb3VyY2VbcHJvcGVydHldID0gZWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFJlY3Vyc2l2ZWx5IHRyYXZlcnNlcyBhIHBhcnNlZCBKU09OIG9iamVjdCwgaW52b2tpbmcgdGhlXG4gICAgICAgIC8vIGBjYWxsYmFja2AgZnVuY3Rpb24gZm9yIGVhY2ggdmFsdWUuIFRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlXG4gICAgICAgIC8vIGBXYWxrKGhvbGRlciwgbmFtZSlgIG9wZXJhdGlvbiBkZWZpbmVkIGluIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjIuXG4gICAgICAgIHZhciB3YWxrID0gZnVuY3Rpb24gKHNvdXJjZSwgcHJvcGVydHksIGNhbGxiYWNrKSB7XG4gICAgICAgICAgdmFyIHZhbHVlID0gc291cmNlW3Byb3BlcnR5XSwgbGVuZ3RoO1xuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIiAmJiB2YWx1ZSkge1xuICAgICAgICAgICAgLy8gYGZvckVhY2hgIGNhbid0IGJlIHVzZWQgdG8gdHJhdmVyc2UgYW4gYXJyYXkgaW4gT3BlcmEgPD0gOC41NFxuICAgICAgICAgICAgLy8gYmVjYXVzZSBpdHMgYE9iamVjdCNoYXNPd25Qcm9wZXJ0eWAgaW1wbGVtZW50YXRpb24gcmV0dXJucyBgZmFsc2VgXG4gICAgICAgICAgICAvLyBmb3IgYXJyYXkgaW5kaWNlcyAoZS5nLiwgYCFbMSwgMiwgM10uaGFzT3duUHJvcGVydHkoXCIwXCIpYCkuXG4gICAgICAgICAgICBpZiAoZ2V0Q2xhc3MuY2FsbCh2YWx1ZSkgPT0gYXJyYXlDbGFzcykge1xuICAgICAgICAgICAgICBmb3IgKGxlbmd0aCA9IHZhbHVlLmxlbmd0aDsgbGVuZ3RoLS07KSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlKHZhbHVlLCBsZW5ndGgsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZm9yRWFjaCh2YWx1ZSwgZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlKHZhbHVlLCBwcm9wZXJ0eSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmNhbGwoc291cmNlLCBwcm9wZXJ0eSwgdmFsdWUpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFB1YmxpYzogYEpTT04ucGFyc2VgLiBTZWUgRVMgNS4xIHNlY3Rpb24gMTUuMTIuMi5cbiAgICAgICAgZXhwb3J0cy5wYXJzZSA9IGZ1bmN0aW9uIChzb3VyY2UsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgdmFyIHJlc3VsdCwgdmFsdWU7XG4gICAgICAgICAgSW5kZXggPSAwO1xuICAgICAgICAgIFNvdXJjZSA9IFwiXCIgKyBzb3VyY2U7XG4gICAgICAgICAgcmVzdWx0ID0gZ2V0KGxleCgpKTtcbiAgICAgICAgICAvLyBJZiBhIEpTT04gc3RyaW5nIGNvbnRhaW5zIG11bHRpcGxlIHRva2VucywgaXQgaXMgaW52YWxpZC5cbiAgICAgICAgICBpZiAobGV4KCkgIT0gXCIkXCIpIHtcbiAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFJlc2V0IHRoZSBwYXJzZXIgc3RhdGUuXG4gICAgICAgICAgSW5kZXggPSBTb3VyY2UgPSBudWxsO1xuICAgICAgICAgIHJldHVybiBjYWxsYmFjayAmJiBnZXRDbGFzcy5jYWxsKGNhbGxiYWNrKSA9PSBmdW5jdGlvbkNsYXNzID8gd2FsaygodmFsdWUgPSB7fSwgdmFsdWVbXCJcIl0gPSByZXN1bHQsIHZhbHVlKSwgXCJcIiwgY2FsbGJhY2spIDogcmVzdWx0O1xuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIGV4cG9ydHNbXCJydW5JbkNvbnRleHRcIl0gPSBydW5JbkNvbnRleHQ7XG4gICAgcmV0dXJuIGV4cG9ydHM7XG4gIH1cblxuICBpZiAodHlwZW9mIGV4cG9ydHMgPT0gXCJvYmplY3RcIiAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmICFpc0xvYWRlcikge1xuICAgIC8vIEV4cG9ydCBmb3IgQ29tbW9uSlMgZW52aXJvbm1lbnRzLlxuICAgIHJ1bkluQ29udGV4dChyb290LCBleHBvcnRzKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBFeHBvcnQgZm9yIHdlYiBicm93c2VycyBhbmQgSmF2YVNjcmlwdCBlbmdpbmVzLlxuICAgIHZhciBuYXRpdmVKU09OID0gcm9vdC5KU09OO1xuICAgIHZhciBKU09OMyA9IHJ1bkluQ29udGV4dChyb290LCAocm9vdFtcIkpTT04zXCJdID0ge1xuICAgICAgLy8gUHVibGljOiBSZXN0b3JlcyB0aGUgb3JpZ2luYWwgdmFsdWUgb2YgdGhlIGdsb2JhbCBgSlNPTmAgb2JqZWN0IGFuZFxuICAgICAgLy8gcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgYEpTT04zYCBvYmplY3QuXG4gICAgICBcIm5vQ29uZmxpY3RcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICByb290LkpTT04gPSBuYXRpdmVKU09OO1xuICAgICAgICByZXR1cm4gSlNPTjM7XG4gICAgICB9XG4gICAgfSkpO1xuXG4gICAgcm9vdC5KU09OID0ge1xuICAgICAgXCJwYXJzZVwiOiBKU09OMy5wYXJzZSxcbiAgICAgIFwic3RyaW5naWZ5XCI6IEpTT04zLnN0cmluZ2lmeVxuICAgIH07XG4gIH1cblxuICAvLyBFeHBvcnQgZm9yIGFzeW5jaHJvbm91cyBtb2R1bGUgbG9hZGVycy5cbiAgaWYgKGlzTG9hZGVyKSB7XG4gICAgZGVmaW5lKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBKU09OMztcbiAgICB9KTtcbiAgfVxufSh0aGlzKSk7XG4iLCJcInVzZSBzdHJpY3RcIlxuXG4vLyBUaGlzIGlzIGEgcmVwb3J0ZXIgdGhhdCBtaW1pY3MgTW9jaGEncyBgZG90YCByZXBvcnRlclxuXG52YXIgUiA9IHJlcXVpcmUoXCIuLi9saWIvcmVwb3J0ZXJcIilcblxuZnVuY3Rpb24gd2lkdGgoKSB7XG4gICAgcmV0dXJuIFIud2luZG93V2lkdGgoKSAqIDQgLyAzIHwgMFxufVxuXG5mdW5jdGlvbiBwcmludERvdChfLCBjb2xvcikge1xuICAgIGZ1bmN0aW9uIGVtaXQoKSB7XG4gICAgICAgIHJldHVybiBfLndyaXRlKFIuY29sb3IoY29sb3IsXG4gICAgICAgICAgICBjb2xvciA9PT0gXCJmYWlsXCIgPyBSLnN5bWJvbHMoKS5Eb3RGYWlsIDogUi5zeW1ib2xzKCkuRG90KSlcbiAgICB9XG5cbiAgICBpZiAoXy5zdGF0ZS5jb3VudGVyKysgJSB3aWR0aCgpID09PSAwKSB7XG4gICAgICAgIHJldHVybiBfLndyaXRlKFIubmV3bGluZSgpICsgXCIgIFwiKS50aGVuKGVtaXQpXG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGVtaXQoKVxuICAgIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSLm9uKFwiZG90XCIsIHtcbiAgICBhY2NlcHRzOiBbXCJ3cml0ZVwiLCBcInJlc2V0XCIsIFwiY29sb3JzXCJdLFxuICAgIGNyZWF0ZTogUi5jb25zb2xlUmVwb3J0ZXIsXG4gICAgYmVmb3JlOiBSLnNldENvbG9yLFxuICAgIGFmdGVyOiBSLnVuc2V0Q29sb3IsXG4gICAgaW5pdDogZnVuY3Rpb24gKHN0YXRlKSB7IHN0YXRlLmNvdW50ZXIgPSAwIH0sXG5cbiAgICByZXBvcnQ6IGZ1bmN0aW9uIChfLCByZXBvcnQpIHtcbiAgICAgICAgaWYgKHJlcG9ydC5pc0VudGVyIHx8IHJlcG9ydC5pc1Bhc3MpIHtcbiAgICAgICAgICAgIHJldHVybiBwcmludERvdChfLCBSLnNwZWVkKHJlcG9ydCkpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzSG9vayB8fCByZXBvcnQuaXNGYWlsKSB7XG4gICAgICAgICAgICBfLnB1c2hFcnJvcihyZXBvcnQpXG4gICAgICAgICAgICAvLyBQcmludCBhIGRvdCByZWdhcmRsZXNzIG9mIGhvb2sgc3VjY2Vzc1xuICAgICAgICAgICAgcmV0dXJuIHByaW50RG90KF8sIFwiZmFpbFwiKVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc1NraXApIHtcbiAgICAgICAgICAgIHJldHVybiBwcmludERvdChfLCBcInNraXBcIilcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFbmQpIHtcbiAgICAgICAgICAgIHJldHVybiBfLnByaW50KCkudGhlbihfLnByaW50UmVzdWx0cy5iaW5kKF8pKVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc0Vycm9yKSB7XG4gICAgICAgICAgICBpZiAoXy5zdGF0ZS5jb3VudGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF8ucHJpbnQoKS50aGVuKF8ucHJpbnRFcnJvci5iaW5kKF8sIHJlcG9ydCkpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBfLnByaW50RXJyb3IocmVwb3J0KVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICB9XG4gICAgfSxcbn0pXG4iLCJcInVzZSBzdHJpY3RcIlxuXG5leHBvcnRzLmRvdCA9IHJlcXVpcmUoXCIuL2RvdFwiKVxuZXhwb3J0cy5zcGVjID0gcmVxdWlyZShcIi4vc3BlY1wiKVxuZXhwb3J0cy50YXAgPSByZXF1aXJlKFwiLi90YXBcIilcbiIsIlwidXNlIHN0cmljdFwiXG5cbi8vIFRoaXMgaXMgYSByZXBvcnRlciB0aGF0IG1pbWljcyBNb2NoYSdzIGBzcGVjYCByZXBvcnRlci5cblxudmFyIFIgPSByZXF1aXJlKFwiLi4vbGliL3JlcG9ydGVyXCIpXG52YXIgYyA9IFIuY29sb3JcblxuZnVuY3Rpb24gaW5kZW50KGxldmVsKSB7XG4gICAgdmFyIHJldCA9IFwiXCJcblxuICAgIHdoaWxlIChsZXZlbC0tKSByZXQgKz0gXCIgIFwiXG4gICAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBnZXROYW1lKGxldmVsLCByZXBvcnQpIHtcbiAgICByZXR1cm4gcmVwb3J0LnBhdGhbbGV2ZWwgLSAxXS5uYW1lXG59XG5cbmZ1bmN0aW9uIHByaW50UmVwb3J0KF8sIHJlcG9ydCwgaW5pdCkge1xuICAgIGlmIChfLnN0YXRlLmxlYXZpbmcpIHtcbiAgICAgICAgXy5zdGF0ZS5sZWF2aW5nID0gZmFsc2VcbiAgICAgICAgcmV0dXJuIF8ucHJpbnQoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBfLnByaW50KGluZGVudChfLnN0YXRlLmxldmVsKSArIGluaXQoKSlcbiAgICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gXy5wcmludChpbmRlbnQoXy5zdGF0ZS5sZXZlbCkgKyBpbml0KCkpXG4gICAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFIub24oXCJzcGVjXCIsIHtcbiAgICBhY2NlcHRzOiBbXCJ3cml0ZVwiLCBcInJlc2V0XCIsIFwiY29sb3JzXCJdLFxuICAgIGNyZWF0ZTogUi5jb25zb2xlUmVwb3J0ZXIsXG4gICAgYmVmb3JlOiBSLnNldENvbG9yLFxuICAgIGFmdGVyOiBSLnVuc2V0Q29sb3IsXG5cbiAgICBpbml0OiBmdW5jdGlvbiAoc3RhdGUpIHtcbiAgICAgICAgc3RhdGUubGV2ZWwgPSAxXG4gICAgICAgIHN0YXRlLmxlYXZpbmcgPSBmYWxzZVxuICAgIH0sXG5cbiAgICByZXBvcnQ6IGZ1bmN0aW9uIChfLCByZXBvcnQpIHtcbiAgICAgICAgaWYgKHJlcG9ydC5pc1N0YXJ0KSB7XG4gICAgICAgICAgICByZXR1cm4gXy5wcmludCgpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzRW50ZXIpIHtcbiAgICAgICAgICAgIHZhciBsZXZlbCA9IF8uc3RhdGUubGV2ZWwrK1xuICAgICAgICAgICAgdmFyIGxhc3QgPSByZXBvcnQucGF0aFtsZXZlbCAtIDFdXG5cbiAgICAgICAgICAgIF8uc3RhdGUubGVhdmluZyA9IGZhbHNlXG4gICAgICAgICAgICBpZiAobGFzdC5pbmRleCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBfLnByaW50KCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfLnByaW50KGluZGVudChsZXZlbCkgKyBsYXN0Lm5hbWUpXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF8ucHJpbnQoaW5kZW50KGxldmVsKSArIGxhc3QubmFtZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNMZWF2ZSkge1xuICAgICAgICAgICAgXy5zdGF0ZS5sZXZlbC0tXG4gICAgICAgICAgICBfLnN0YXRlLmxlYXZpbmcgPSB0cnVlXG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzUGFzcykge1xuICAgICAgICAgICAgcmV0dXJuIHByaW50UmVwb3J0KF8sIHJlcG9ydCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBzdHIgPVxuICAgICAgICAgICAgICAgICAgICBjKFwiY2hlY2ttYXJrXCIsIFIuc3ltYm9scygpLlBhc3MgKyBcIiBcIikgK1xuICAgICAgICAgICAgICAgICAgICBjKFwicGFzc1wiLCBnZXROYW1lKF8uc3RhdGUubGV2ZWwsIHJlcG9ydCkpXG5cbiAgICAgICAgICAgICAgICB2YXIgc3BlZWQgPSBSLnNwZWVkKHJlcG9ydClcblxuICAgICAgICAgICAgICAgIGlmIChzcGVlZCAhPT0gXCJmYXN0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyICs9IGMoc3BlZWQsIFwiIChcIiArIHJlcG9ydC5kdXJhdGlvbiArIFwibXMpXCIpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0clxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNIb29rIHx8IHJlcG9ydC5pc0ZhaWwpIHtcbiAgICAgICAgICAgIF8ucHVzaEVycm9yKHJlcG9ydClcblxuICAgICAgICAgICAgLy8gRG9uJ3QgcHJpbnQgdGhlIGRlc2NyaXB0aW9uIGxpbmUgb24gY3VtdWxhdGl2ZSBob29rc1xuICAgICAgICAgICAgaWYgKHJlcG9ydC5pc0hvb2sgJiYgKHJlcG9ydC5pc0JlZm9yZUFsbCB8fCByZXBvcnQuaXNBZnRlckFsbCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBwcmludFJlcG9ydChfLCByZXBvcnQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYyhcImZhaWxcIixcbiAgICAgICAgICAgICAgICAgICAgXy5lcnJvcnMubGVuZ3RoICsgXCIpIFwiICsgZ2V0TmFtZShfLnN0YXRlLmxldmVsLCByZXBvcnQpICtcbiAgICAgICAgICAgICAgICAgICAgUi5mb3JtYXRSZXN0KHJlcG9ydCkpXG4gICAgICAgICAgICB9KVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc1NraXApIHtcbiAgICAgICAgICAgIHJldHVybiBwcmludFJlcG9ydChfLCByZXBvcnQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYyhcInNraXBcIiwgXCItIFwiICsgZ2V0TmFtZShfLnN0YXRlLmxldmVsLCByZXBvcnQpKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyZXBvcnQuaXNFbmQpIHJldHVybiBfLnByaW50UmVzdWx0cygpXG4gICAgICAgIGlmIChyZXBvcnQuaXNFcnJvcikgcmV0dXJuIF8ucHJpbnRFcnJvcihyZXBvcnQpXG4gICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICB9LFxufSlcbiIsIlwidXNlIHN0cmljdFwiXG5cbi8vIFRoaXMgaXMgYSBiYXNpYyBUQVAtZ2VuZXJhdGluZyByZXBvcnRlci5cblxudmFyIHBlYWNoID0gcmVxdWlyZShcIi4uL2xpYi91dGlsXCIpLnBlYWNoXG52YXIgUiA9IHJlcXVpcmUoXCIuLi9saWIvcmVwb3J0ZXJcIilcbnZhciBpbnNwZWN0ID0gcmVxdWlyZShcImNsZWFuLWFzc2VydC11dGlsXCIpLmluc3BlY3RcblxuZnVuY3Rpb24gc2hvdWxkQnJlYWsobWluTGVuZ3RoLCBzdHIpIHtcbiAgICByZXR1cm4gc3RyLmxlbmd0aCA+IFIud2luZG93V2lkdGgoKSAtIG1pbkxlbmd0aCB8fCAvXFxyP1xcbnxbOj8tXS8udGVzdChzdHIpXG59XG5cbmZ1bmN0aW9uIHRlbXBsYXRlKF8sIHJlcG9ydCwgdG1wbCwgc2tpcCkge1xuICAgIGlmICghc2tpcCkgXy5zdGF0ZS5jb3VudGVyKytcbiAgICB2YXIgcGF0aCA9IFIuam9pblBhdGgocmVwb3J0KS5yZXBsYWNlKC9cXCQvZywgXCIkJCQkXCIpXG5cbiAgICByZXR1cm4gXy5wcmludChcbiAgICAgICAgdG1wbC5yZXBsYWNlKC8lYy9nLCBfLnN0YXRlLmNvdW50ZXIpXG4gICAgICAgICAgICAucmVwbGFjZSgvJXAvZywgcGF0aCArIFIuZm9ybWF0UmVzdChyZXBvcnQpKSlcbn1cblxuZnVuY3Rpb24gcHJpbnRMaW5lcyhfLCB2YWx1ZSwgc2tpcEZpcnN0KSB7XG4gICAgdmFyIGxpbmVzID0gdmFsdWUuc3BsaXQoL1xccj9cXG4vZylcblxuICAgIGlmIChza2lwRmlyc3QpIGxpbmVzLnNoaWZ0KClcbiAgICByZXR1cm4gcGVhY2gobGluZXMsIGZ1bmN0aW9uIChsaW5lKSB7IHJldHVybiBfLnByaW50KFwiICAgIFwiICsgbGluZSkgfSlcbn1cblxuZnVuY3Rpb24gcHJpbnRSYXcoXywga2V5LCBzdHIpIHtcbiAgICBpZiAoc2hvdWxkQnJlYWsoa2V5Lmxlbmd0aCwgc3RyKSkge1xuICAgICAgICByZXR1cm4gXy5wcmludChcIiAgXCIgKyBrZXkgKyBcIjogfC1cIilcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcHJpbnRMaW5lcyhfLCBzdHIsIGZhbHNlKSB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBfLnByaW50KFwiICBcIiArIGtleSArIFwiOiBcIiArIHN0cilcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHByaW50VmFsdWUoXywga2V5LCB2YWx1ZSkge1xuICAgIHJldHVybiBwcmludFJhdyhfLCBrZXksIGluc3BlY3QodmFsdWUpKVxufVxuXG5mdW5jdGlvbiBwcmludExpbmUocCwgXywgbGluZSkge1xuICAgIHJldHVybiBwLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChsaW5lKSB9KVxufVxuXG5mdW5jdGlvbiBwcmludEVycm9yKF8sIHJlcG9ydCkge1xuICAgIHZhciBlcnIgPSByZXBvcnQuZXJyb3JcblxuICAgIGlmICghKGVyciBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgICAgICByZXR1cm4gcHJpbnRWYWx1ZShfLCBcInZhbHVlXCIsIGVycilcbiAgICB9XG5cbiAgICAvLyBMZXQncyAqbm90KiBkZXBlbmQgb24gdGhlIGNvbnN0cnVjdG9yIGJlaW5nIFRoYWxsaXVtJ3MuLi5cbiAgICBpZiAoZXJyLm5hbWUgIT09IFwiQXNzZXJ0aW9uRXJyb3JcIikge1xuICAgICAgICByZXR1cm4gXy5wcmludChcIiAgc3RhY2s6IHwtXCIpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHByaW50TGluZXMoXywgUi5nZXRTdGFjayhlcnIpLCBmYWxzZSlcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICByZXR1cm4gcHJpbnRWYWx1ZShfLCBcImV4cGVjdGVkXCIsIGVyci5leHBlY3RlZClcbiAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBwcmludFZhbHVlKF8sIFwiYWN0dWFsXCIsIGVyci5hY3R1YWwpIH0pXG4gICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcHJpbnRSYXcoXywgXCJtZXNzYWdlXCIsIGVyci5tZXNzYWdlKSB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIF8ucHJpbnQoXCIgIHN0YWNrOiB8LVwiKSB9KVxuICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSBlcnIubWVzc2FnZVxuXG4gICAgICAgIGVyci5tZXNzYWdlID0gXCJcIlxuICAgICAgICByZXR1cm4gcHJpbnRMaW5lcyhfLCBSLmdldFN0YWNrKGVyciksIHRydWUpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgZXJyLm1lc3NhZ2UgPSBtZXNzYWdlIH0pXG4gICAgfSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBSLm9uKFwidGFwXCIsIHtcbiAgICBhY2NlcHRzOiBbXCJ3cml0ZVwiLCBcInJlc2V0XCJdLFxuICAgIGNyZWF0ZTogUi5jb25zb2xlUmVwb3J0ZXIsXG4gICAgaW5pdDogZnVuY3Rpb24gKHN0YXRlKSB7IHN0YXRlLmNvdW50ZXIgPSAwIH0sXG5cbiAgICByZXBvcnQ6IGZ1bmN0aW9uIChfLCByZXBvcnQpIHtcbiAgICAgICAgaWYgKHJlcG9ydC5pc1N0YXJ0KSB7XG4gICAgICAgICAgICByZXR1cm4gXy5wcmludChcIlRBUCB2ZXJzaW9uIDEzXCIpXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzRW50ZXIpIHtcbiAgICAgICAgICAgIC8vIFByaW50IGEgbGVhZGluZyBjb21tZW50LCB0byBtYWtlIHNvbWUgVEFQIGZvcm1hdHRlcnMgcHJldHRpZXIuXG4gICAgICAgICAgICByZXR1cm4gdGVtcGxhdGUoXywgcmVwb3J0LCBcIiMgJXBcIiwgdHJ1ZSlcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRlbXBsYXRlKF8sIHJlcG9ydCwgXCJvayAlY1wiKSB9KVxuICAgICAgICB9IGVsc2UgaWYgKHJlcG9ydC5pc1Bhc3MpIHtcbiAgICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZShfLCByZXBvcnQsIFwib2sgJWMgJXBcIilcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNGYWlsIHx8IHJlcG9ydC5pc0hvb2spIHtcbiAgICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZShfLCByZXBvcnQsIFwibm90IG9rICVjICVwXCIpXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBfLnByaW50KFwiICAtLS1cIikgfSlcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHByaW50RXJyb3IoXywgcmVwb3J0KSB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChcIiAgLi4uXCIpIH0pXG4gICAgICAgIH0gZWxzZSBpZiAocmVwb3J0LmlzU2tpcCkge1xuICAgICAgICAgICAgcmV0dXJuIHRlbXBsYXRlKF8sIHJlcG9ydCwgXCJvayAlYyAjIHNraXAgJXBcIilcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFbmQpIHtcbiAgICAgICAgICAgIHZhciBwID0gXy5wcmludChcIjEuLlwiICsgXy5zdGF0ZS5jb3VudGVyKVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gXy5wcmludChcIiMgdGVzdHMgXCIgKyBfLnRlc3RzKSB9KVxuXG4gICAgICAgICAgICBpZiAoXy5wYXNzKSBwID0gcHJpbnRMaW5lKHAsIF8sIFwiIyBwYXNzIFwiICsgXy5wYXNzKVxuICAgICAgICAgICAgaWYgKF8uZmFpbCkgcCA9IHByaW50TGluZShwLCBfLCBcIiMgZmFpbCBcIiArIF8uZmFpbClcbiAgICAgICAgICAgIGlmIChfLnNraXApIHAgPSBwcmludExpbmUocCwgXywgXCIjIHNraXAgXCIgKyBfLnNraXApXG4gICAgICAgICAgICByZXR1cm4gcHJpbnRMaW5lKHAsIF8sIFwiIyBkdXJhdGlvbiBcIiArIFIuZm9ybWF0VGltZShfLmR1cmF0aW9uKSlcbiAgICAgICAgfSBlbHNlIGlmIChyZXBvcnQuaXNFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIF8ucHJpbnQoXCJCYWlsIG91dCFcIilcbiAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIF8ucHJpbnQoXCIgIC0tLVwiKSB9KVxuICAgICAgICAgICAgLnRoZW4oZnVuY3Rpb24gKCkgeyByZXR1cm4gcHJpbnRFcnJvcihfLCByZXBvcnQpIH0pXG4gICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7IHJldHVybiBfLnByaW50KFwiICAuLi5cIikgfSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgfVxuICAgIH0sXG59KVxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuLyoqXG4gKiBUaGlzIGlzIHRoZSBlbnRyeSBwb2ludCBmb3IgdGhlIEJyb3dzZXJpZnkgYnVuZGxlLiBOb3RlIHRoYXQgaXQgKmFsc28qIHdpbGxcbiAqIHJ1biBhcyBwYXJ0IG9mIHRoZSB0ZXN0cyBpbiBOb2RlICh1bmJ1bmRsZWQpLCBhbmQgaXQgdGhlb3JldGljYWxseSBjb3VsZCBiZVxuICogcnVuIGluIE5vZGUgb3IgYSBydW50aW1lIGxpbWl0ZWQgdG8gb25seSBFUzUgc3VwcG9ydCAoZS5nLiBSaGlubywgTmFzaG9ybiwgb3JcbiAqIGVtYmVkZGVkIFY4KSwgc28gZG8gKm5vdCogYXNzdW1lIGJyb3dzZXIgZ2xvYmFscyBhcmUgcHJlc2VudC5cbiAqL1xuXG5leHBvcnRzLnQgPSByZXF1aXJlKFwiLi4vaW5kZXhcIilcbmV4cG9ydHMuYXNzZXJ0ID0gcmVxdWlyZShcIi4uL2Fzc2VydFwiKVxuZXhwb3J0cy5yID0gcmVxdWlyZShcIi4uL3JcIilcbnZhciBkb20gPSByZXF1aXJlKFwiLi4vZG9tXCIpXG5cbmV4cG9ydHMuZG9tID0gZG9tLmNyZWF0ZVxuLy8gaWYgKGdsb2JhbC5kb2N1bWVudCAhPSBudWxsICYmIGdsb2JhbC5kb2N1bWVudC5jdXJyZW50U2NyaXB0ICE9IG51bGwpIHtcbi8vICAgICBkb20uYXV0b2xvYWQoZ2xvYmFsLmRvY3VtZW50LmN1cnJlbnRTY3JpcHQpXG4vLyB9XG5cbnZhciBJbnRlcm5hbCA9IHJlcXVpcmUoXCIuLi9pbnRlcm5hbFwiKVxuXG5leHBvcnRzLnJvb3QgPSBJbnRlcm5hbC5yb290XG5leHBvcnRzLnJlcG9ydHMgPSBJbnRlcm5hbC5yZXBvcnRzXG5leHBvcnRzLmhvb2tFcnJvcnMgPSBJbnRlcm5hbC5ob29rRXJyb3JzXG5leHBvcnRzLmxvY2F0aW9uID0gSW50ZXJuYWwubG9jYXRpb25cblxuLy8gSW4gY2FzZSB0aGUgdXNlciBuZWVkcyB0byBhZGp1c3QgdGhpcyAoZS5nLiBOYXNob3JuICsgY29uc29sZSBvdXRwdXQpLlxudmFyIFNldHRpbmdzID0gcmVxdWlyZShcIi4vc2V0dGluZ3NcIilcblxuZXhwb3J0cy5zZXR0aW5ncyA9IHtcbiAgICB3aW5kb3dXaWR0aDoge1xuICAgICAgICBnZXQ6IFNldHRpbmdzLndpbmRvd1dpZHRoLFxuICAgICAgICBzZXQ6IFNldHRpbmdzLnNldFdpbmRvd1dpZHRoLFxuICAgIH0sXG5cbiAgICBuZXdsaW5lOiB7XG4gICAgICAgIGdldDogU2V0dGluZ3MubmV3bGluZSxcbiAgICAgICAgc2V0OiBTZXR0aW5ncy5zZXROZXdsaW5lLFxuICAgIH0sXG5cbiAgICBzeW1ib2xzOiB7XG4gICAgICAgIGdldDogU2V0dGluZ3Muc3ltYm9scyxcbiAgICAgICAgc2V0OiBTZXR0aW5ncy5zZXRTeW1ib2xzLFxuICAgIH0sXG5cbiAgICBkZWZhdWx0T3B0czoge1xuICAgICAgICBnZXQ6IFNldHRpbmdzLmRlZmF1bHRPcHRzLFxuICAgICAgICBzZXQ6IFNldHRpbmdzLnNldERlZmF1bHRPcHRzLFxuICAgIH0sXG5cbiAgICBjb2xvclN1cHBvcnQ6IHtcbiAgICAgICAgZ2V0OiBTZXR0aW5ncy5Db2xvcnMuZ2V0U3VwcG9ydCxcbiAgICAgICAgc2V0OiBTZXR0aW5ncy5Db2xvcnMuc2V0U3VwcG9ydCxcbiAgICB9LFxufVxuIl19