UNPKG

ineedthis

Version:
440 lines 50.2 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); // eslint-disable-next-line @typescript-eslint/no-var-requires var _a = require('../package'), pkgName = _a.name, version = _a.version; // Persist registry across multiple instances of this module. Terrible // hack, but needed to support a truly 'global' registry in // environments such as lerna or old npm verisons var registrySym = Symbol.for("Global registry for " + pkgName + "@" + version); if (!global[registrySym]) { global[registrySym] = {}; } var registry = global[registrySym]; function isFunction(o) { return typeof o === 'function'; } function isArray(o) { return typeof o === 'object' && o instanceof Array; } function isService(o) { return isFunction(o) && isFunction(o.start) && isFunction(o.stop) && isArray(o.dependencies); } function getPath(o, ks) { if (ks === void 0) { ks = []; } if (ks.length === 0) { return o; } else { return getPath(o[ks[0]], ks.slice(1)); } } function parsePackage(s) { var parts = s.split('.'); return { path: parts.slice(1), package: parts[0], __isPackageSpec: true }; } var notFound = Symbol('Package not found'); function tryRequire(p) { if (typeof p === 'string') { p = parsePackage(p); } try { // eslint-disable-next-line @typescript-eslint/no-var-requires var service = getPath(require(p.package), (p.path || [])); return service; } catch (e) { return notFound; } } function requireOrThrow(p) { var required = tryRequire(p); if (required === notFound) { throw new Error("Couldn't resolve dependency: \"" + p + "\""); } else if (!isService(required)) { throw new Error("Resolved \"" + p + "\" but expected a Service, not \"" + String(required) + "\""); } else { return required; } } function dependencyOrService(input) { if (typeof input === 'string') { return input; } else if (Object.prototype.hasOwnProperty.call(input, '__isPackageSpec')) { return requireOrThrow(input).serviceName; } return input.serviceName; } function dangerouslyResetRegistry() { for (var _i = 0, _a = Object.keys(registry); _i < _a.length; _i++) { var serviceName = _a[_i]; delete registry[serviceName]; } } exports.dangerouslyResetRegistry = dangerouslyResetRegistry; function cloneFn(fn) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return fn.apply(void 0, args); }; } /** * Create a service named `name` with start, stop, etc as defined in * `description`. * * Leave `name` undefined to create an anonymous service. */ function createService(name, description) { var defaultedDescription = __assign({}, description); if (!Array.isArray(defaultedDescription.dependencies)) { defaultedDescription.dependencies = []; } if (!defaultedDescription.stop) { defaultedDescription.stop = function () { return undefined; }; } var start = cloneFn(defaultedDescription.start), service = Object.assign(start, { dependencies: defaultedDescription.dependencies, serviceName: name, start: start, stop: defaultedDescription.stop, }); if (name) { registry[name] = service; } return service; } exports.createService = createService; function flatten(ll) { var _a; return (_a = []).concat.apply(_a, ll.map(function (it) { return Array.from(it); })); } /** * Creates a service that, when used, is loaded from the given node * packageName (eg @scope/some-cool-package/path/inside/package) and a * lodash get-style path (eg "abc.0.hi" to get "x" from {abc:[{hi:"x"}]}). */ function fromPackage(packageName, path) { return { path: path, package: packageName, __isPackageSpec: true }; } exports.fromPackage = fromPackage; // TODO: Can get rid of 'any' once Variadic Kinds lands (TS issue #5453) function start(namesOrServices, overridesIn) { if (overridesIn === void 0) { overridesIn = {}; } return __awaiter(this, void 0, void 0, function () { function resolve(serviceName) { if (overrides && overrides[serviceName]) { return overrides[serviceName]; } else if (registry[serviceName]) { return registry[serviceName]; } else { return requireOrThrow(serviceName); } } function load(name) { return __awaiter(this, void 0, void 0, function () { var service; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, resolve(name)()(__assign({}, system))]; case 1: service = _a.sent(); delete outstandingLoads[name]; Object.values(outstandingDeps).forEach(function (deps) { return deps.delete(name); }); // We duplicate the `system` object, so services can't mutate our // master copy of the system. Thus, the possible race condition // that eslint detects here is a false positive. // eslint-disable-next-line require-atomic-updates system[name] = service; return [2 /*return*/, service]; } }); }); } var overrides, services, _i, services_1, s, outstandingDeps, toProcess, system, outstandingLoads, _a, _b, _c, name, deps; return __generator(this, function (_d) { switch (_d.label) { case 0: if (!Array.isArray(namesOrServices)) { namesOrServices = [namesOrServices]; } overrides = {}; Object.assign(overrides, overridesIn); services = namesOrServices.map(function (nameOrService) { if (typeof nameOrService === 'string') { if (registry[nameOrService]) { return registry[nameOrService]; } else { throw new Error("Couldn't find: \"" + nameOrService + "\""); } } else if (Object.prototype.hasOwnProperty.call(nameOrService, '__isPackageSpec')) { return requireOrThrow(nameOrService); } else { return nameOrService; } }); for (_i = 0, services_1 = services; _i < services_1.length; _i++) { s = services_1[_i]; if (!overrides[s.serviceName]) { overrides[s.serviceName] = s; } } outstandingDeps = {}; toProcess = new Set(services.map(function (s) { return s.serviceName; })); do { toProcess.forEach(function (s) { outstandingDeps[s] = new Set(resolve(s).dependencies.map(dependencyOrService)); }); toProcess = new Set(flatten(Object.values(outstandingDeps))); Object.keys(outstandingDeps).forEach(function (k) { return toProcess.delete(k); }); } while (toProcess.size > 0); system = {}; outstandingLoads = {}; _d.label = 1; case 1: if (!(Object.keys(outstandingDeps).length > 0 || Object.keys(outstandingLoads).length > 0)) return [3 /*break*/, 3]; // Start loading any deps that are no longer waiting for another dep for (_a = 0, _b = Object.entries(outstandingDeps); _a < _b.length; _a++) { _c = _b[_a], name = _c[0], deps = _c[1]; if (deps.size === 0) { outstandingLoads[name] = load(name); delete outstandingDeps[name]; } } if (Object.keys(outstandingLoads).length === 0 && Object.keys(outstandingDeps).length > 0) { throw new Error('Cycle detected'); } // Wait for the next dep to finish starting return [4 /*yield*/, Promise.race(Object.values(outstandingLoads))]; case 2: // Wait for the next dep to finish starting _d.sent(); return [3 /*break*/, 1]; case 3: return [2 /*return*/, system]; } }); }); } exports.start = start; /** * Stop system. If a spec of systems `partial` is supplied, stop only * those systems and any "higher" systems that rely on them, but * others will be left alone. */ function stop(system) { return __awaiter(this, void 0, void 0, function () { var countDependents, _i, _a, s, _b, _c, s, _d, _e, d, outstandingShutdowns, finishedShutdowns, _loop_1, _f, _g, _h, s, remainingDependents; var _this = this; return __generator(this, function (_j) { switch (_j.label) { case 0: countDependents = {}; for (_i = 0, _a = Object.keys(system); _i < _a.length; _i++) { s = _a[_i]; countDependents[s] = 0; } for (_b = 0, _c = Object.keys(system); _b < _c.length; _b++) { s = _c[_b]; for (_d = 0, _e = registry[s].dependencies.map(dependencyOrService); _d < _e.length; _d++) { d = _e[_d]; countDependents[d]++; } } outstandingShutdowns = {}, finishedShutdowns = {}; _j.label = 1; case 1: _loop_1 = function (s, remainingDependents) { if (remainingDependents === 0 && !outstandingShutdowns[s] && !finishedShutdowns[s]) { outstandingShutdowns[s] = (function () { return __awaiter(_this, void 0, void 0, function () { var service, _i, _a, d; return __generator(this, function (_b) { switch (_b.label) { case 0: service = registry[s]; return [4 /*yield*/, service.stop(system[s])]; case 1: _b.sent(); finishedShutdowns[s] = true; delete outstandingShutdowns[s]; for (_i = 0, _a = service.dependencies.map(dependencyOrService); _i < _a.length; _i++) { d = _a[_i]; countDependents[d]--; } return [2 /*return*/]; } }); }); })(); } }; for (_f = 0, _g = Object.entries(countDependents); _f < _g.length; _f++) { _h = _g[_f], s = _h[0], remainingDependents = _h[1]; _loop_1(s, remainingDependents); } return [4 /*yield*/, Promise.race(Object.values(outstandingShutdowns))]; case 2: _j.sent(); _j.label = 3; case 3: if (Object.keys(finishedShutdowns).length < Object.keys(system).length) return [3 /*break*/, 1]; _j.label = 4; case 4: return [2 /*return*/]; } }); }); } exports.stop = stop; /** * Stop system. If a spec of systems `partial` is supplied, stop only * those systems and any "higher" systems that rely on them, but * others will be left alone. * * Returns the list of services names that were shutdown */ function stopPartial(system, partial) { return __awaiter(this, void 0, void 0, function () { var dependents, _i, _a, s, _b, _c, s, _d, _e, d, toShutdown, toVisit, visited, visiting, _f, _g, s, partialSystem, output; return __generator(this, function (_h) { switch (_h.label) { case 0: dependents = {}; for (_i = 0, _a = Object.keys(system); _i < _a.length; _i++) { s = _a[_i]; dependents[s] = []; } for (_b = 0, _c = Object.keys(system); _b < _c.length; _b++) { s = _c[_b]; for (_d = 0, _e = registry[s].dependencies.map(dependencyOrService); _d < _e.length; _d++) { d = _e[_d]; if (system[d]) { dependents[d].push(s); } } } toShutdown = new Set(), toVisit = partial.slice(), visited = new Set(); while (visiting = toVisit.pop()) { visited.add(visiting); toShutdown.add(visiting); for (_f = 0, _g = dependents[visiting]; _f < _g.length; _f++) { s = _g[_f]; if (!visited.has(s)) { toVisit.push(s); } } } partialSystem = {}, output = []; toShutdown.forEach(function (s) { partialSystem[s] = system[s]; output.push(s); }); return [4 /*yield*/, stop(partialSystem)]; case 1: _h.sent(); return [2 /*return*/, output]; } }); }); } exports.stopPartial = stopPartial; var noopService = function (x) { return createService(undefined, { start: function () { return function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, x]; }); }); }; }, }); }; /** * Restart services named in `partial` using the existing `system` */ function startPartial(system, partial) { return __awaiter(this, void 0, void 0, function () { var mocks, _i, _a, s, newServices, finalSystem, _b, _c, s; return __generator(this, function (_d) { switch (_d.label) { case 0: mocks = {}; for (_i = 0, _a = Object.keys(system); _i < _a.length; _i++) { s = _a[_i]; if (!partial.includes(s)) { mocks[s] = noopService(system[s]); } } return [4 /*yield*/, start(partial, mocks)]; case 1: newServices = _d.sent(); finalSystem = {}; for (_b = 0, _c = Object.keys(newServices); _b < _c.length; _b++) { s = _c[_b]; if (Object.prototype.hasOwnProperty.call(mocks, s)) { finalSystem[s] = system[s]; } else { finalSystem[s] = newServices[s]; } } return [2 /*return*/, finalSystem]; } }); }); } exports.startPartial = startPartial; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDhEQUE4RDtBQUN4RCxJQUFBLDBCQUFpRixFQUFoRixpQkFBYSxFQUFFLG9CQUFpRSxDQUFDO0FBdUN4RixzRUFBc0U7QUFDdEUsMkRBQTJEO0FBQzNELGlEQUFpRDtBQUNqRCxJQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLHlCQUF1QixPQUFPLFNBQUksT0FBUyxDQUFDLENBQUM7QUFDNUUsSUFBSSxDQUFFLE1BQWMsQ0FBQyxXQUFXLENBQUMsRUFBRTtJQUNoQyxNQUFjLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDO0NBQ25DO0FBQ0QsSUFBTSxRQUFRLEdBQXFCLE1BQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUUvRCxTQUFTLFVBQVUsQ0FBQyxDQUFNO0lBQ3hCLE9BQU8sT0FBTyxDQUFDLEtBQUssVUFBVSxDQUFDO0FBQ2pDLENBQUM7QUFFRCxTQUFTLE9BQU8sQ0FBQyxDQUFNO0lBQ3JCLE9BQU8sT0FBTyxDQUFDLEtBQUssUUFBUSxJQUFJLENBQUMsWUFBWSxLQUFLLENBQUM7QUFDckQsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLENBQU07SUFDdkIsT0FBTyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDL0YsQ0FBQztBQUVELFNBQVMsT0FBTyxDQUFDLENBQU0sRUFBRSxFQUE0QjtJQUE1QixtQkFBQSxFQUFBLE9BQTRCO0lBQ25ELElBQUksRUFBRSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7UUFD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VyxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQzt5QkFDNUI7NkJBQU07NEJBQ0wsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQzt5QkFDakM7cUJBQ0Y7b0JBRUQsc0JBQU8sV0FBVyxFQUFDOzs7O0NBQ3BCO0FBNUJELG9DQTRCQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdmFyLXJlcXVpcmVzXG5jb25zdCB7bmFtZTogcGtnTmFtZSwgdmVyc2lvbn06IHtuYW1lOiBzdHJpbmc7IHZlcnNpb246IHN0cmluZ30gPSByZXF1aXJlKCcuLi9wYWNrYWdlJyk7XG5cbmV4cG9ydCB0eXBlIFN0YXJ0Rm5UPFQ+ID0gKCguLi5hcmdzOiBhbnlbXSkgPT4gKHBhcnRpYWxTeXN0ZW06IFN5c3RlbSkgPT4gUHJvbWlzZTxUPik7XG5cbmV4cG9ydCB0eXBlIFNlcnZpY2VOYW1lID0gc3RyaW5nO1xuZXhwb3J0IHR5cGUgQWxpYXNlZFNlcnZpY2VOYW1lID0ge3R5cGU6IHN0cmluZzsgYXM6IHN0cmluZ307XG5leHBvcnQgdHlwZSBTZXJ2aWNlPFQsIFN0YXJ0Rm4gZXh0ZW5kcyBTdGFydEZuVDxUPj4gPSB7XG4gICguLi5hcmdzOiBhbnlbXSk6IChwYXJ0aWFsU3lzdGVtOiBTeXN0ZW0pID0+IFByb21pc2U8VD47XG4gIC8vIERvbid0IGNvbmZsaWN0IHdpdGggRnVuY3Rpb24ucHJvdG90eXBlLm5hbWVcbiAgZGVwZW5kZW5jaWVzOiBTZXJ2aWNlTmFtZVtdO1xuICBzZXJ2aWNlTmFtZTogU2VydmljZU5hbWU7XG4gIHN0YXJ0OiBTdGFydEZuO1xuICBzdG9wOiAoKGluc3RhbmNlOiBUKSA9PiB2b2lkKTtcbiAgW2V4dHJhUHJvcHM6IHN0cmluZ106IGFueTtcbn07XG5leHBvcnQgdHlwZSBTZXJ2aWNlSW5zdGFuY2U8VCwgU3RhcnRGbiBleHRlbmRzIFN0YXJ0Rm5UPFQ+PiA9IHtcbiAgKC4uLmFyZ3M6IGFueVtdKTogKHBhcnRpYWxTeXN0ZW06IFN5c3RlbSkgPT4gUHJvbWlzZTxUPjtcbiAgLy8gRG9uJ3QgY29uZmxpY3Qgd2l0aCBGdW5jdGlvbi5wcm90b3R5cGUubmFtZVxuICBkZXBlbmRlbmNpZXM6IFNlcnZpY2VOYW1lW107XG4gIHNlcnZpY2VOYW1lOiBTZXJ2aWNlTmFtZTtcbiAgc3RhcnQ6IChwYXJ0aWFsU3lzdGVtOiBTeXN0ZW0pID0+IFByb21pc2U8VD47XG4gIHN0b3A6ICgoaW5zdGFuY2U6IFQpID0+IHZvaWQpO1xuICBbZXh0cmFQcm9wczogc3RyaW5nXTogYW55O1xufTtcblxuZXhwb3J0IHR5cGUgU3lzdGVtID0ge1trZXkgaW4gU2VydmljZU5hbWVdOiBhbnl9O1xuZXhwb3J0IHR5cGUgU3lzdGVtTWFwID0ge1trZXkgaW4gU2VydmljZU5hbWVdOiBTZXJ2aWNlSW5zdGFuY2U8YW55LCBhbnk+fTtcblxuZXhwb3J0IGludGVyZmFjZSBTZXJ2aWNlRGVzY3JpcHRpb248VCwgU3RhcnRGbiBleHRlbmRzIFN0YXJ0Rm5UPFQ+PiB7XG4gIGRlcGVuZGVuY2llcz86IChTZXJ2aWNlTmFtZSB8IEFsaWFzZWRTZXJ2aWNlTmFtZSB8IFNlcnZpY2U8YW55LCBhbnk+KVtdO1xuICBzdGFydDogU3RhcnRGbjtcbiAgc3RvcD86ICgoaW5zdGFuY2U6IFQpID0+IHZvaWQpO1xufVxuXG5leHBvcnQgdHlwZSBQYWNrYWdlU3BlYyA9IHtwYXRoPzogc3RyaW5nW107IHBhY2thZ2U6IHN0cmluZzsgX19pc1BhY2thZ2VTcGVjOiB0cnVlfTtcbnR5cGUgRnJpZW5kbHlQYWNrYWdlU3BlYyA9IHN0cmluZyB8IFBhY2thZ2VTcGVjIHwgU2VydmljZU5hbWUgfCBTZXJ2aWNlPGFueSwgYW55PjtcblxudHlwZSBTZXJ2aWNlUmVnaXN0cnkgPSB7W3NlcnZpY2UgaW4gU2VydmljZU5hbWVdOiBTZXJ2aWNlPGFueSwgYW55Pn07XG5cbi8vIFBlcnNpc3QgcmVnaXN0cnkgYWNyb3NzIG11bHRpcGxlIGluc3RhbmNlcyBvZiB0aGlzIG1vZHVsZS4gVGVycmlibGVcbi8vIGhhY2ssIGJ1dCBuZWVkZWQgdG8gc3VwcG9ydCBhIHRydWx5ICdnbG9iYWwnIHJlZ2lzdHJ5IGluXG4vLyBlbnZpcm9ubWVudHMgc3VjaCBhcyBsZXJuYSBvciBvbGQgbnBtIHZlcmlzb25zXG5jb25zdCByZWdpc3RyeVN5bSA9IFN5bWJvbC5mb3IoYEdsb2JhbCByZWdpc3RyeSBmb3IgJHtwa2dOYW1lfUAke3ZlcnNpb259YCk7XG5pZiAoIShnbG9iYWwgYXMgYW55KVtyZWdpc3RyeVN5bV0pIHtcbiAgKGdsb2JhbCBhcyBhbnkpW3JlZ2lzdHJ5U3ltXSA9IHt9O1xufVxuY29uc3QgcmVnaXN0cnk6IFNlcnZpY2VSZWdpc3RyeSA9IChnbG9iYWwgYXMgYW55KVtyZWdpc3RyeVN5bV07XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24obzogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiB0eXBlb2YgbyA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNBcnJheShvOiBhbnkpOiBib29sZWFuIHtcbiAgcmV0dXJuIHR5cGVvZiBvID09PSAnb2JqZWN0JyAmJiBvIGluc3RhbmNlb2YgQXJyYXk7XG59XG5cbmZ1bmN0aW9uIGlzU2VydmljZShvOiBhbnkpOiBib29sZWFuIHtcbiAgcmV0dXJuIGlzRnVuY3Rpb24obykgJiYgaXNGdW5jdGlvbihvLnN0YXJ0KSAmJiBpc0Z1bmN0aW9uKG8uc3RvcCkgJiYgaXNBcnJheShvLmRlcGVuZGVuY2llcyk7XG59XG5cbmZ1bmN0aW9uIGdldFBhdGgobzogYW55LCBrczogKHN0cmluZyB8IG51bWJlcilbXSA9IFtdKTogYW55IHtcbiAgaWYgKGtzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBvO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBnZXRQYXRoKG9ba3NbMF1dLCBrcy5zbGljZSgxKSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcGFyc2VQYWNrYWdlKHM6IHN0cmluZyk6IFBhY2thZ2VTcGVjIHtcbiAgY29uc3QgcGFydHMgPSBzLnNwbGl0KCcuJyk7XG4gIHJldHVybiB7cGF0aDogcGFydHMuc2xpY2UoMSksIHBhY2thZ2U6IHBhcnRzWzBdLCBfX2lzUGFja2FnZVNwZWM6IHRydWV9O1xufVxuXG5jb25zdCBub3RGb3VuZCA9IFN5bWJvbCgnUGFja2FnZSBub3QgZm91bmQnKTtcbmZ1bmN0aW9uIHRyeVJlcXVpcmUocDogc3RyaW5nIHwgUGFja2FnZVNwZWMpOiBTZXJ2aWNlPGFueSwgYW55PiB8IHN5bWJvbCB7XG4gIGlmICh0eXBlb2YgcCA9PT0gJ3N0cmluZycpIHtcbiAgICBwID0gcGFyc2VQYWNrYWdlKHApO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXZhci1yZXF1aXJlc1xuICAgIGNvbnN0IHNlcnZpY2UgPSBnZXRQYXRoKHJlcXVpcmUocC5wYWNrYWdlKSwgKHAucGF0aCB8fCBbXSkpO1xuICAgIHJldHVybiBzZXJ2aWNlO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIG5vdEZvdW5kO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlcXVpcmVPclRocm93KHA6IHN0cmluZyB8IFBhY2thZ2VTcGVjKTogU2VydmljZTxhbnksIGFueT4ge1xuICBjb25zdCByZXF1aXJlZCA9IHRyeVJlcXVpcmUocCk7XG4gIGlmIChyZXF1aXJlZCA9PT0gbm90Rm91bmQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkbid0IHJlc29sdmUgZGVwZW5kZW5jeTogXCIke3B9XCJgKTtcbiAgfSBlbHNlIGlmICghaXNTZXJ2aWNlKHJlcXVpcmVkKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgUmVzb2x2ZWQgXCIke3B9XCIgYnV0IGV4cGVjdGVkIGEgU2VydmljZSwgbm90IFwiJHtTdHJpbmcocmVxdWlyZWQpfVwiYCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIChyZXF1aXJlZCBhcyBTZXJ2aWNlPGFueSwgYW55Pik7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVwZW5kZW5jeU9yU2VydmljZShpbnB1dDogRnJpZW5kbHlQYWNrYWdlU3BlYyk6IHN0cmluZyB8IGtleW9mIFBhY2thZ2VTcGVjIHtcbiAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH0gZWxzZSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGlucHV0LCAnX19pc1BhY2thZ2VTcGVjJykpIHtcbiAgICByZXR1cm4gcmVxdWlyZU9yVGhyb3coKGlucHV0IGFzIFBhY2thZ2VTcGVjKSkuc2VydmljZU5hbWU7XG4gIH1cbiAgcmV0dXJuIChpbnB1dCBhcyBTZXJ2aWNlPGFueSwgYW55Pikuc2VydmljZU5hbWU7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkYW5nZXJvdXNseVJlc2V0UmVnaXN0cnkoKTogdm9pZCB7XG4gIGZvciAoY29uc3Qgc2VydmljZU5hbWUgb2YgT2JqZWN0LmtleXMocmVnaXN0cnkpKSB7XG4gICAgZGVsZXRlIHJlZ2lzdHJ5W3NlcnZpY2VOYW1lXTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjbG9uZUZuPFQ+KGZuOiAoKC4uLmFyZ3M6IGFueVtdKSA9PiBUKSk6ICgoLi4uYXJnczogYW55W10pID0+IFQpIHtcbiAgcmV0dXJuICguLi5hcmdzOiBhbnlbXSk6IFQgPT4gZm4oLi4uYXJncyk7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgc2VydmljZSBuYW1lZCBgbmFtZWAgd2l0aCBzdGFydCwgc3RvcCwgZXRjIGFzIGRlZmluZWQgaW5cbiAqIGBkZXNjcmlwdGlvbmAuXG4gKlxuICogTGVhdmUgYG5hbWVgIHVuZGVmaW5lZCB0byBjcmVhdGUgYW4gYW5vbnltb3VzIHNlcnZpY2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTZXJ2aWNlPFQsIFN0YXJ0Rm4gZXh0ZW5kcyBTdGFydEZuVDxUPj4oXG4gIG5hbWU6IFNlcnZpY2VOYW1lIHwgdW5kZWZpbmVkLFxuICBkZXNjcmlwdGlvbjogU2VydmljZURlc2NyaXB0aW9uPFQsIFN0YXJ0Rm4+LFxuKTogU2VydmljZTxULCBTdGFydEZuPiB7XG4gIGNvbnN0IGRlZmF1bHRlZERlc2NyaXB0aW9uID0gey4uLmRlc2NyaXB0aW9ufTtcbiAgaWYgKCFBcnJheS5pc0FycmF5KGRlZmF1bHRlZERlc2NyaXB0aW9uLmRlcGVuZGVuY2llcykpIHtcbiAgICBkZWZhdWx0ZWREZXNjcmlwdGlvbi5kZXBlbmRlbmNpZXMgPSBbXTtcbiAgfVxuXG4gIGlmICghZGVmYXVsdGVkRGVzY3JpcHRpb24uc3RvcCkge1xuICAgIGRlZmF1bHRlZERlc2NyaXB0aW9uLnN0b3AgPSAoKTogdm9pZCA9PiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBzdGFydDogU3RhcnRGbiA9IChjbG9uZUZuKGRlZmF1bHRlZERlc2NyaXB0aW9uLnN0YXJ0KSBhcyBhbnkpLFxuICAgIHNlcnZpY2U6IFNlcnZpY2U8VCwgU3RhcnRGbj4gPSAoT2JqZWN0LmFzc2lnbihzdGFydCwge1xuICAgICAgZGVwZW5kZW5jaWVzOiBkZWZhdWx0ZWREZXNjcmlwdGlvbi5kZXBlbmRlbmNpZXMsXG4gICAgICBzZXJ2aWNlTmFtZTogbmFtZSxcbiAgICAgIHN0YXJ0LFxuICAgICAgc3RvcDogZGVmYXVsdGVkRGVzY3JpcHRpb24uc3RvcCxcbiAgICB9KSBhcyBhbnkpO1xuXG4gIGlmIChuYW1lKSB7XG4gICAgcmVnaXN0cnlbbmFtZV0gPSBzZXJ2aWNlO1xuICB9XG4gIHJldHVybiBzZXJ2aWNlO1xufVxuXG5mdW5jdGlvbiBmbGF0dGVuPFQ+KGxsOiBJdGVyYWJsZTxUPltdKTogVFtdIHtcbiAgcmV0dXJuIChbXSBhcyBUW10pLmNvbmNhdCguLi5sbC5tYXAoaXQgPT4gQXJyYXkuZnJvbShpdCkpKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgc2VydmljZSB0aGF0LCB3aGVuIHVzZWQsIGlzIGxvYWRlZCBmcm9tIHRoZSBnaXZlbiBub2RlXG4gKiBwYWNrYWdlTmFtZSAoZWcgQHNjb3BlL3NvbWUtY29vbC1wYWNrYWdlL3BhdGgvaW5zaWRlL3BhY2thZ2UpIGFuZCBhXG4gKiBsb2Rhc2ggZ2V0LXN0eWxlIHBhdGggKGVnIFwiYWJjLjAuaGlcIiB0byBnZXQgXCJ4XCIgZnJvbSB7YWJjOlt7aGk6XCJ4XCJ9XX0pLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZnJvbVBhY2thZ2UocGFja2FnZU5hbWU6IHN0cmluZywgcGF0aD86IHN0cmluZ1tdKTogUGFja2FnZVNwZWMge1xuICByZXR1cm4ge3BhdGgsIHBhY2thZ2U6IHBhY2thZ2VOYW1lLCBfX2lzUGFja2FnZVNwZWM6IHRydWV9O1xufVxuXG4vLyBUT0RPOiBDYW4gZ2V0IHJpZCBvZiAnYW55JyBvbmNlIFZhcmlhZGljIEtpbmRzIGxhbmRzIChUUyBpc3N1ZSAjNTQ1MylcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGFydChcbiAgbmFtZXNPclNlcnZpY2VzOiAoU2VydmljZU5hbWUgfCBQYWNrYWdlU3BlYyB8IFNlcnZpY2U8YW55LCBhbnk+IHwgKFBhY2thZ2VTcGVjIHwgU2VydmljZTxhbnksIGFueT4gfCBTZXJ2aWNlTmFtZSlbXSksXG4gIG92ZXJyaWRlc0luOiBTeXN0ZW0gPSB7fSxcbik6IFByb21pc2U8U3lzdGVtPiB7XG4gIGlmICghQXJyYXkuaXNBcnJheShuYW1lc09yU2VydmljZXMpKSB7XG4gICAgbmFtZXNPclNlcnZpY2VzID0gW25hbWVzT3JTZXJ2aWNlc107XG4gIH1cblxuICAvLyBDbG9uZSwgc28gd2UgZG9uJ3Qgb3ZlcnJpZGUgdGhlIGlucHV0XG4gIGNvbnN0IG92ZXJyaWRlczogU3lzdGVtID0ge307XG4gIE9iamVjdC5hc3NpZ24ob3ZlcnJpZGVzLCBvdmVycmlkZXNJbik7XG5cbiAgZnVuY3Rpb24gcmVzb2x2ZShzZXJ2aWNlTmFtZTogU2VydmljZU5hbWUpOiBTZXJ2aWNlPGFueSwgYW55PiB7XG4gICAgaWYgKG92ZXJyaWRlcyAmJiBvdmVycmlkZXNbc2VydmljZU5hbWVdKSB7XG4gICAgICByZXR1cm4gb3ZlcnJpZGVzW3NlcnZpY2VOYW1lXTtcbiAgICB9IGVsc2UgaWYgKHJlZ2lzdHJ5W3NlcnZpY2VOYW1lXSkge1xuICAgICAgcmV0dXJuIHJlZ2lzdHJ5W3NlcnZpY2VOYW1lXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlcXVpcmVPclRocm93KHNlcnZpY2VOYW1lKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBzZXJ2aWNlczogU2VydmljZTxhbnksIGFueT5bXSA9IG5hbWVzT3JTZXJ2aWNlcy5tYXAobmFtZU9yU2VydmljZSA9PiB7XG4gICAgaWYgKHR5cGVvZiBuYW1lT3JTZXJ2aWNlID09PSAnc3RyaW5nJykge1xuICAgICAgaWYgKHJlZ2lzdHJ5W25hbWVPclNlcnZpY2VdKSB7XG4gICAgICAgIHJldHVybiByZWdpc3RyeVtuYW1lT3JTZXJ2aWNlXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ291bGRuJ3QgZmluZDogXCIke25hbWVPclNlcnZpY2V9XCJgKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChuYW1lT3JTZXJ2aWNlLCAnX19pc1BhY2thZ2VTcGVjJykpIHtcbiAgICAgIHJldHVybiByZXF1aXJlT3JUaHJvdyhuYW1lT3JTZXJ2aWNlIGFzIFBhY2thZ2VTcGVjKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIChuYW1lT3JTZXJ2aWNlIGFzIFNlcnZpY2U8YW55LCBhbnk+KTtcbiAgICB9XG4gIH0pO1xuXG4gIGZvciAoY29uc3QgcyBvZiBzZXJ2aWNlcykge1xuICAgIGlmICghb3ZlcnJpZGVzW3Muc2VydmljZU5hbWVdKSB7XG4gICAgICBvdmVycmlkZXNbcy5zZXJ2aWNlTmFtZV0gPSBzO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJlc29sdmUgYWxsIHJlcXVpcmVkIGRlcGVuZGVuY2llcywgYnVpbGRpbmcgb2YgYSBtYXAgb2ZcbiAgLy8gc2VydmljZU5hbWVzIC0+IHN0aWxsIHJlcXVpcmVkIGRlcGVuZGVuY2llc1xuICBjb25zdCBvdXRzdGFuZGluZ0RlcHM6IHtbcyBpbiBTZXJ2aWNlTmFtZV06IFNldDxTZXJ2aWNlTmFtZT59ID0ge307XG4gIGxldCB0b1Byb2Nlc3MgPSBuZXcgU2V0KHNlcnZpY2VzLm1hcChzID0+IHMuc2VydmljZU5hbWUpKTtcbiAgZG8ge1xuICAgIHRvUHJvY2Vzcy5mb3JFYWNoKHMgPT4ge1xuICAgICAgb3V0c3RhbmRpbmdEZXBzW3NdID0gbmV3IFNldChyZXNvbHZlKHMpLmRlcGVuZGVuY2llcy5tYXAoZGVwZW5kZW5jeU9yU2VydmljZSkpO1xuICAgIH0pO1xuXG4gICAgdG9Qcm9jZXNzID0gbmV3IFNldChmbGF0dGVuKE9iamVjdC52YWx1ZXMob3V0c3RhbmRpbmdEZXBzKSkpO1xuICAgIE9iamVjdC5rZXlzKG91dHN0YW5kaW5nRGVwcykuZm9yRWFjaChrID0+IHRvUHJvY2Vzcy5kZWxldGUoaykpO1xuICB9IHdoaWxlICh0b1Byb2Nlc3Muc2l6ZSA+IDApO1xuXG4gIC8vIEZpbmFsIG91dHB1dCBzeXN0ZW0gd2UnbGwgYnVpbGQgdXBcbiAgY29uc3Qgc3lzdGVtOiB7W2tleSBpbiBTZXJ2aWNlTmFtZV06IGFueX0gPSB7fTtcblxuICBjb25zdCBvdXRzdGFuZGluZ0xvYWRzOiB7W25hbWUgaW4gU2VydmljZU5hbWVdOiBQcm9taXNlPFNlcnZpY2U8YW55LCBhbnk+Pn0gPSB7fTtcbiAgYXN5bmMgZnVuY3Rpb24gbG9hZChuYW1lOiBTZXJ2aWNlTmFtZSk6IFByb21pc2U8U2VydmljZTxhbnksIGFueT4+IHtcbiAgICBjb25zdCBzZXJ2aWNlID0gYXdhaXQgcmVzb2x2ZShuYW1lKSgpKHsuLi5zeXN0ZW19KTtcblxuICAgIGRlbGV0ZSBvdXRzdGFuZGluZ0xvYWRzW25hbWVdO1xuICAgIE9iamVjdC52YWx1ZXMob3V0c3RhbmRpbmdEZXBzKS5mb3JFYWNoKGRlcHMgPT4gZGVwcy5kZWxldGUobmFtZSkpO1xuXG4gICAgLy8gV2UgZHVwbGljYXRlIHRoZSBgc3lzdGVtYCBvYmplY3QsIHNvIHNlcnZpY2VzIGNhbid0IG11dGF0ZSBvdXJcbiAgICAvLyBtYXN0ZXIgY29weSBvZiB0aGUgc3lzdGVtLiBUaHVzLCB0aGUgcG9zc2libGUgcmFjZSBjb25kaXRpb25cbiAgICAvLyB0aGF0IGVzbGludCBkZXRlY3RzIGhlcmUgaXMgYSBmYWxzZSBwb3NpdGl2ZS5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVxdWlyZS1hdG9taWMtdXBkYXRlc1xuICAgIHN5c3RlbVtuYW1lXSA9IHNlcnZpY2U7XG5cbiAgICByZXR1cm4gc2VydmljZTtcbiAgfVxuXG4gIHdoaWxlIChPYmplY3Qua2V5cyhvdXRzdGFuZGluZ0RlcHMpLmxlbmd0aCA+IDAgfHxcbiAgICAgICAgT2JqZWN0LmtleXMob3V0c3RhbmRpbmdMb2FkcykubGVuZ3RoID4gMCkge1xuICAgIC8vIFN0YXJ0IGxvYWRpbmcgYW55IGRlcHMgdGhhdCBhcmUgbm8gbG9uZ2VyIHdhaXRpbmcgZm9yIGFub3RoZXIgZGVwXG4gICAgZm9yIChjb25zdCBbbmFtZSwgZGVwc10gb2YgT2JqZWN0LmVudHJpZXMob3V0c3RhbmRpbmdEZXBzKSkge1xuICAgICAgaWYgKGRlcHMuc2l6ZSA9PT0gMCkge1xuICAgICAgICBvdXRzdGFuZGluZ0xvYWRzW25hbWVdID0gbG9hZChuYW1lKTtcbiAgICAgICAgZGVsZXRlIG91dHN0YW5kaW5nRGVwc1tuYW1lXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoT2JqZWN0LmtleXMob3V0c3RhbmRpbmdMb2FkcykubGVuZ3RoID09PSAwICYmXG4gICAgICAgIE9iamVjdC5rZXlzKG91dHN0YW5kaW5nRGVwcykubGVuZ3RoID4gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDeWNsZSBkZXRlY3RlZCcpO1xuICAgIH1cblxuICAgIC8vIFdhaXQgZm9yIHRoZSBuZXh0IGRlcCB0byBmaW5pc2ggc3RhcnRpbmdcbiAgICBhd2FpdCBQcm9taXNlLnJhY2UoT2JqZWN0LnZhbHVlcyhvdXRzdGFuZGluZ0xvYWRzKSk7XG4gIH1cblxuICByZXR1cm4gc3lzdGVtO1xufVxuXG4vKipcbiAqIFN0b3Agc3lzdGVtLiBJZiBhIHNwZWMgb2Ygc3lzdGVtcyBgcGFydGlhbGAgaXMgc3VwcGxpZWQsIHN0b3Agb25seVxuICogdGhvc2Ugc3lzdGVtcyBhbmQgYW55IFwiaGlnaGVyXCIgc3lzdGVtcyB0aGF0IHJlbHkgb24gdGhlbSwgYnV0XG4gKiBvdGhlcnMgd2lsbCBiZSBsZWZ0IGFsb25lLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RvcChcbiAgc3lzdGVtOiBTeXN0ZW0sXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgY291bnREZXBlbmRlbnRzOiB7W3MgaW4gU2VydmljZU5hbWVdOiBudW1iZXJ9ID0ge307XG4gIGZvciAoY29uc3QgcyBvZiBPYmplY3Qua2V5cyhzeXN0ZW0pKSB7XG4gICAgY291bnREZXBlbmRlbnRzW3NdID0gMDtcbiAgfVxuXG4gIGZvciAoY29uc3QgcyBvZiBPYmplY3Qua2V5cyhzeXN0ZW0pKSB7XG4gICAgZm9yIChjb25zdCBkIG9mIHJlZ2lzdHJ5W3NdLmRlcGVuZGVuY2llcy5tYXAoZGVwZW5kZW5jeU9yU2VydmljZSkpIHtcbiAgICAgIGNvdW50RGVwZW5kZW50c1tkXSsrO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG91dHN0YW5kaW5nU2h1dGRvd25zOiB7W3MgaW4gU2VydmljZU5hbWVdOiBQcm9taXNlPHZvaWQ+fSA9IHt9LFxuICAgIGZpbmlzaGVkU2h1dGRvd25zOiB7W3MgaW4gU2VydmljZU5hbWVdOiBib29sZWFufSA9IHt9O1xuICBkbyB7XG4gICAgZm9yIChjb25zdCBbcywgcmVtYWluaW5nRGVwZW5kZW50c10gb2YgT2JqZWN0LmVudHJpZXMoY291bnREZXBlbmRlbnRzKSkge1xuICAgICAgaWYgKHJlbWFpbmluZ0RlcGVuZGVudHMgPT09IDAgJiZcbiAgICAgICAgICAhb3V0c3RhbmRpbmdTaHV0ZG93bnNbc10gJiZcbiAgICAgICAgICAhZmluaXNoZWRTaHV0ZG93bnNbc10pIHtcblxuICAgICAgICBvdXRzdGFuZGluZ1NodXRkb3duc1tzXSA9IChhc3luYyAoKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgICAgY29uc3Qgc2VydmljZSA9IHJlZ2lzdHJ5W3NdO1xuICAgICAgICAgIGF3YWl0IHNlcnZpY2Uuc3RvcChzeXN0ZW1bc10pO1xuICAgICAgICAgIGZpbmlzaGVkU2h1dGRvd25zW3NdID0gdHJ1ZTtcbiAgICAgICAgICBkZWxldGUgb3V0c3RhbmRpbmdTaHV0ZG93bnNbc107XG4gICAgICAgICAgZm9yIChjb25zdCBkIG9mIHNlcnZpY2UuZGVwZW5kZW5jaWVzLm1hcChkZXBlbmRlbmN5T3JTZXJ2aWNlKSkge1xuICAgICAgICAgICAgY291bnREZXBlbmRlbnRzW2RdLS07XG4gICAgICAgICAgfVxuICAgICAgICB9KSgpO1xuXG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgUHJvbWlzZS5yYWNlKE9iamVjdC52YWx1ZXMob3V0c3RhbmRpbmdTaHV0ZG93bnMpKTtcbiAgfSB3aGlsZSAoT2JqZWN0LmtleXMoZmluaXNoZWRTaHV0ZG93bnMpLmxlbmd0aCA8IE9iamVjdC5rZXlzKHN5c3RlbSkubGVuZ3RoKTtcbn1cblxuLyoqXG4gKiBTdG9wIHN5c3RlbS4gSWYgYSBzcGVjIG9mIHN5c3RlbXMgYHBhcnRpYWxgIGlzIHN1cHBsaWVkLCBzdG9wIG9ubHlcbiAqIHRob3NlIHN5c3RlbXMgYW5kIGFueSBcImhpZ2hlclwiIHN5c3RlbXMgdGhhdCByZWx5IG9uIHRoZW0sIGJ1dFxuICogb3RoZXJzIHdpbGwgYmUgbGVmdCBhbG9uZS5cbiAqXG4gKiBSZXR1cm5zIHRoZSBsaXN0IG9mIHNlcnZpY2VzIG5hbWVzIHRoYXQgd2VyZSBzaHV0ZG93blxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RvcFBhcnRpYWwoXG4gIHN5c3RlbTogU3lzdGVtLFxuICBwYXJ0aWFsOiBTZXJ2aWNlTmFtZVtdLFxuKTogUHJvbWlzZTxTZXJ2aWNlTmFtZVtdPiB7XG4gIC8vIFJldmVyc2UgdGhlIHNlcnZpY2UgZ3JhcGggdG8gZ2V0IGEgbWFwIG9mIGRlcGVuZGVudHMsIGluc3RlYWQgb2ZcbiAgLy8gZGVwZW5kZW5jaWVzXG4gIGNvbnN0IGRlcGVuZGVudHM6IHtbcyBpbiBTZXJ2aWNlTmFtZV06IFNlcnZpY2VOYW1lW119ID0ge307XG4gIGZvciAoY29uc3QgcyBvZiBPYmplY3Qua2V5cyhzeXN0ZW0pKSB7XG4gICAgZGVwZW5kZW50c1tzXSA9IFtdO1xuICB9XG4gIGZvciAoY29uc3QgcyBvZiBPYmplY3Qua2V5cyhzeXN0ZW0pKSB7XG4gICAgZm9yIChjb25zdCBkIG9mIHJlZ2lzdHJ5W3NdLmRlcGVuZGVuY2llcy5tYXAoZGVwZW5kZW5jeU9yU2VydmljZSkpIHtcbiAgICAgIGlmIChzeXN0ZW1bZF0pIHtcbiAgICAgICAgZGVwZW5kZW50c1tkXS5wdXNoKHMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIEZvbGxvdyBhbGwgZGVwZW5kZW50IHJlbGF0aW9uc2hpcHMgZnJvbSB0aGUgdGFyZ2V0IFwicGFydGlhbFwiXG4gIC8vIHN1YmdyYXBoIHRvIGJlIHNodXRkb3duXG4gIGNvbnN0IHRvU2h1dGRvd24gPSBuZXcgU2V0PHN0cmluZz4oKSxcbiAgICB0b1Zpc2l0ID0gcGFydGlhbC5zbGljZSgpLFxuICAgIHZpc2l0ZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgbGV0IHZpc2l0aW5nO1xuICB3aGlsZSAodmlzaXRpbmcgPSB0b1Zpc2l0LnBvcCgpKSB7XG4gICAgdmlzaXRlZC5hZGQodmlzaXRpbmcpO1xuICAgIHRvU2h1dGRvd24uYWRkKHZpc2l0aW5nKTtcblxuICAgIGZvciAoY29uc3QgcyBvZiBkZXBlbmRlbnRzW3Zpc2l0aW5nXSkge1xuICAgICAgaWYgKCF2aXNpdGVkLmhhcyhzKSkge1xuICAgICAgICB0b1Zpc2l0LnB1c2gocyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcGFydGlhbFN5c3RlbTogU3lzdGVtID0ge30sXG4gICAgb3V0cHV0OiBzdHJpbmdbXSA9IFtdO1xuICB0b1NodXRkb3duLmZvckVhY2gocyA9PiB7XG4gICAgcGFydGlhbFN5c3RlbVtzXSA9IHN5c3RlbVtzXTtcbiAgICBvdXRwdXQucHVzaChzKTtcbiAgfSk7XG5cbiAgYXdhaXQgc3RvcChwYXJ0aWFsU3lzdGVtKTtcblxuICByZXR1cm4gb3V0cHV0O1xufVxuXG5jb25zdCBub29wU2VydmljZTogKCh4OiBhbnkpID0+IFNlcnZpY2VEZXNjcmlwdGlvbjxhbnksIGFueT4pID0geCA9PlxuICBjcmVhdGVTZXJ2aWNlKFxuICAgIHVuZGVmaW5lZCwge1xuICAgICAgc3RhcnQ6ICgpID0+IGFzeW5jICgpOiBQcm9taXNlPGFueT4gPT4geCxcbiAgICB9LFxuICApO1xuXG4vKipcbiAqIFJlc3RhcnQgc2VydmljZXMgbmFtZWQgaW4gYHBhcnRpYWxgIHVzaW5nIHRoZSBleGlzdGluZyBgc3lzdGVtYFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3RhcnRQYXJ0aWFsKFxuICBzeXN0ZW06IFN5c3RlbSxcbiAgcGFydGlhbDogU2VydmljZU5hbWVbXSxcbik6IFByb21pc2U8U3lzdGVtPiB7XG4gIC8vIE1vY2sgb3V0IGV4aXN0aW5nIHNlcnZpY2VzIHdpdGggYG5vb3BTZXJ2aWNlYCwgdGhlbiByZWxhdW5jaCB0aGVcbiAgLy8gZnVsbCBzeXN0ZW0gd2l0aCB0aG9zZSBtb2NrcyB0byByZWNyZWF0ZSB0aGUgc2VydmljZXMgcmVxdWVzdGVkXG4gIC8vIGluIGBwYXJ0aWFsYCwgYW5kIGZpbmFsbHkgbWVyZ2UgdGhvc2UgbmV3bHkgbGF1bmNoZWQgc2VydmljZXNcbiAgLy8gYmFjayBpbnRvIHRoZSBleGlzdGluZyBzeXN0ZW0uXG5cbiAgY29uc3QgbW9ja3M6IFN5c3RlbSA9IHt9O1xuICBmb3IgKGNvbnN0IHMgb2YgT2JqZWN0LmtleXMoc3lzdGVtKSkge1xuICAgIGlmICghcGFydGlhbC5pbmNsdWRlcyhzKSkge1xuICAgICAgbW9ja3Nbc10gPSBub29wU2VydmljZShzeXN0ZW1bc10pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG5ld1NlcnZpY2VzID0gYXdhaXQgc3RhcnQocGFydGlhbCwgbW9ja3MpO1xuXG4gIGNvbnN0IGZpbmFsU3lzdGVtOiBTeXN0ZW0gPSB7fTtcbiAgZm9yIChjb25zdCBzIG9mIE9iamVjdC5rZXlzKG5ld1NlcnZpY2VzKSkge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3