UNPKG

@loona/core

Version:

App State Management done with GraphQL (core package)

935 lines (903 loc) 70.4 kB
import { __spread, __extends, __assign, __values, __awaiter, __generator, __read } from 'tslib'; import produce from 'immer'; import { ApolloLink } from 'apollo-link'; import { withClientState } from 'apollo-link-state'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @template T */ var /** * @template T */ Store = /** @class */ (function () { function Store(data) { if (data === void 0) { data = {}; } this.store = new Map(Object.entries(data)); } /** * @param {?} key * @return {?} */ Store.prototype.get = /** * @param {?} key * @return {?} */ function (key) { return this.store.get(key); }; /** * @param {?} key * @param {?} value * @return {?} */ Store.prototype.set = /** * @param {?} key * @param {?} value * @return {?} */ function (key, value) { this.store.set(key, value); }; /** * @param {?} fn * @return {?} */ Store.prototype.forEach = /** * @param {?} fn * @return {?} */ function (fn) { this.store.forEach(fn); }; return Store; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} doc * @return {?} */ function getMutationDefinition(doc) { /** @type {?} */ var isMutation = function (def) { return def.kind === 'OperationDefinition' && def.operation === 'mutation'; }; /** @type {?} */ var defs = doc.definitions.filter(isMutation); if (!defs || !defs[0]) { throw new Error('Must contain a mutation definition.'); } return defs[0]; } /** * @param {?} def * @return {?} */ function getFirstField(def) { return (/** @type {?} */ (def.selectionSet.selections[0])); } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} context * @param {?} client * @return {?} */ function buildContext(context, client) { return __assign({}, context, { patchQuery: patchQuery(client), patchFragment: patchFragment(context, client), writeData: /** * @param {?} options * @return {?} */ function (options) { return client.writeData(options); } }); } /** * @param {?} cache * @return {?} */ function buildGetCacheKey(cache) { return function (obj) { if (((/** @type {?} */ (cache))).config) { return ((/** @type {?} */ (cache))).config.dataIdFromObject(obj); } else { throw new Error('To use context.getCacheKey, you need to use a cache that has a configurable dataIdFromObject, like apollo-cache-inmemory.'); } }; } /** * @param {?} fragment * @return {?} */ function getFragmentTypename(fragment) { /** @type {?} */ var def = (/** @type {?} */ (fragment.definitions.find(function (def) { return def.kind === 'FragmentDefinition'; }))); return def.typeCondition.name.value; } /** * @param {?} client * @return {?} */ function patchQuery(client) { return function (query, patchFn) { /** @type {?} */ var options = isDocument(query) ? { query: query } : query; /** @type {?} */ var obj = client.readQuery(options); /** @type {?} */ var data = produce(obj, patchFn); client.writeQuery(__assign({}, options, { data: data })); return data; }; } /** * @param {?} context * @param {?} client * @return {?} */ function patchFragment(context, client) { return function (fragment, obj, patchFn) { /** @type {?} */ var __typename = getFragmentTypename(fragment); /** @type {?} */ var id = context.getCacheKey(__assign({}, obj, { __typename: __typename })); /** @type {?} */ var frgmt = client.readFragment({ fragment: fragment, id: id, }); /** @type {?} */ var data = produce(frgmt, patchFn); client.writeFragment({ fragment: fragment, id: id, data: __assign({}, data, { __typename: __typename }), }); return data; }; } /** * @param {?} doc * @return {?} */ function isDocument(doc) { return doc && doc.kind === 'Document'; } /** * @param {?} action * @return {?} */ function isMutationAsAction(action) { return action.type === 'mutation'; } /** * @param {?} action * @return {?} */ function getActionType(action) { if (action.constructor && action.constructor.type) { return action.constructor.type; } return action.type; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var MutationManager = /** @class */ (function (_super) { __extends(MutationManager, _super); function MutationManager(defs) { var _this = _super.call(this) || this; if (defs) { defs.forEach(function (def) { _this.set(def.mutation, def); }); } return _this; } /** * @param {?} defs * @return {?} */ MutationManager.prototype.add = /** * @param {?} defs * @return {?} */ function (defs) { var _this = this; defs.forEach(function (def) { _this.set(def.mutation, def); }); }; return MutationManager; }(Store)); /** * @param {?} action * @return {?} */ function mutationToType(action) { /** @type {?} */ var mutation = getMutation(action); /** @type {?} */ var name = getNameOfMutation(mutation); return name; } /** * @param {?} action * @return {?} */ function getMutation(action) { if (action.constructor && action.constructor.mutation) { return action.constructor.mutation; } return action.mutation; } /** * @param {?} action * @return {?} */ function isMutation(action) { return typeof getMutation(action) !== 'undefined'; } /** * @param {?} mutation * @return {?} */ function getNameOfMutation(mutation) { /** @type {?} */ var def = getMutationDefinition(mutation); /** @type {?} */ var field = getFirstField(def); return field.name.value; } /** * @template T, V * @param {?} config * @param {?} manager * @return {?} */ function withUpdates(config, manager) { /** @type {?} */ var orgUpdate = config.update; return __assign({}, config, { update: function (proxy, mutationResult) { /** @type {?} */ var name = getNameOfMutation(config.mutation); /** @type {?} */ var result = mutationResult.data && mutationResult.data[name]; /** @type {?} */ var cache = manager.cache; /** @type {?} */ var context = buildContext({ cache: proxy, getCacheKey: buildGetCacheKey(cache), }, manager.getClient()); /** @type {?} */ var updates = manager.updates.get(name); if (updates) { /** @type {?} */ var info_1 = { name: name, variables: config.variables, result: result, }; updates.forEach(function (def) { return def.resolve(info_1, context); }); } if (orgUpdate) { orgUpdate(proxy, mutationResult); } } }); } /** * @template T, V * @param {?} config * @param {?} result * @return {?} */ function buildActionFromResult(config, result) { return __assign({ type: 'mutation', options: config, ok: true }, result); } /** * @template T, V * @param {?} config * @param {?} error * @return {?} */ function buildActionFromError(config, error) { return { type: 'mutation', options: config, ok: false, error: error, }; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var UpdateManager = /** @class */ (function (_super) { __extends(UpdateManager, _super); function UpdateManager(defs) { var _this = _super.call(this) || this; if (defs) { _this.add(defs); } return _this; } /** * @param {?} defs * @return {?} */ UpdateManager.prototype.add = /** * @param {?} defs * @return {?} */ function (defs) { var _this = this; if (!Array.isArray(defs)) { defs = [defs]; } defs.forEach(function (def) { /** @type {?} */ var all = _this.get(def.mutation) || []; all.push(def); _super.prototype.set.call(_this, def.mutation, all); }); }; /** * @return {?} */ UpdateManager.prototype.set = /** * @return {?} */ function () { console.error('Use add() instead'); }; return UpdateManager; }(Store)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var ResolversManager = /** @class */ (function (_super) { __extends(ResolversManager, _super); function ResolversManager(defs) { var _this = _super.call(this) || this; if (defs) { _this.add(defs); } return _this; } /** * @param {?} defs * @return {?} */ ResolversManager.prototype.add = /** * @param {?} defs * @return {?} */ function (defs) { var _this = this; defs.forEach(function (def) { _this.set(def.path, def); }); }; return ResolversManager; }(Store)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** @type {?} */ var METADATA_KEY = '@@loona'; /** * @param {?} target * @return {?} */ function readMetadata(target) { /** @type {?} */ var constructor = target.constructor; return constructor[METADATA_KEY]; } /** * @param {?} target * @return {?} */ function ensureMetadata(target) { if (!target.hasOwnProperty(METADATA_KEY)) { /** @type {?} */ var defaultValue = { defaults: {}, mutations: [], resolvers: [], updates: [], typeDefs: [], effects: {}, }; Object.defineProperty(target, METADATA_KEY, { value: defaultValue, }); } return target[METADATA_KEY]; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} proto * @param {?} propName * @param {?} mutation * @return {?} */ function setMutationMetadata(proto, propName, mutation) { /** @type {?} */ var constructor = proto.constructor; /** @type {?} */ var meta = ensureMetadata(constructor); meta.mutations.push({ propName: propName, mutation: mutation, }); } /** * @param {?} target * @param {?} propName * @return {?} */ function hasMutation(target, propName) { /** @type {?} */ var meta = readMetadata(target); if (meta) { return meta.mutations.some(function (def) { return def.propName === propName; }); } return false; } /** * @param {?} instance * @param {?} meta * @param {?=} transformFn * @return {?} */ function transformMutations(instance, meta, transformFn) { if (transformFn === void 0) { transformFn = function (resolver) { return resolver; }; } return meta.mutations.map(function (_a) { var propName = _a.propName, mutation = _a.mutation; return ({ mutation: typeof mutation === 'string' ? mutation : getNameOfMutation(mutation), resolve: transformFn(instance[propName].bind(instance)), }); }); } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} proto * @param {?} propName * @param {?} mutation * @return {?} */ function setUpdateMetadata(proto, propName, mutation) { /** @type {?} */ var constructor = proto.constructor; /** @type {?} */ var meta = ensureMetadata(constructor); meta.updates.push({ propName: propName, mutation: mutation, }); } /** * @param {?} instance * @param {?} meta * @param {?=} transformFn * @return {?} */ function transformUpdates(instance, meta, transformFn) { if (transformFn === void 0) { transformFn = function (resolver) { return resolver; }; } if (meta.updates) { return meta.updates.map(function (_a) { var propName = _a.propName, mutation = _a.mutation; return ({ mutation: mutation, resolve: transformFn(instance[propName].bind(instance)), }); }); } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} proto * @param {?} propName * @param {?} path * @return {?} */ function setResolveMetadata(proto, propName, path) { /** @type {?} */ var constructor = proto.constructor; /** @type {?} */ var meta = ensureMetadata(constructor); meta.resolvers.push({ propName: propName, path: path }); } /** * @param {?} instance * @param {?} meta * @param {?=} transformFn * @return {?} */ function transformResolvers(instance, meta, transformFn) { if (transformFn === void 0) { transformFn = function (resolver) { return resolver; }; } return meta.resolvers.map(function (_a) { var propName = _a.propName, path = _a.path; return ({ name: propName, path: path, resolve: transformFn(instance[propName].bind(instance)), }); }); } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ var Manager = /** @class */ (function () { function Manager(options) { this.getClient = function () { throw new Error('Manager requires ApolloClient'); }; this.cache = options.cache; this.defaults = options.defaults; this.typeDefs = options.typeDefs; this.resolvers = new ResolversManager(options.resolvers); this.updates = new UpdateManager(options.updates); this.mutations = new MutationManager(options.mutations); if (options.getClient) { this.getClient = options.getClient; } } /** * @param {?} instance * @param {?} meta * @param {?=} transformFn * @return {?} */ Manager.prototype.addState = /** * @param {?} instance * @param {?} meta * @param {?=} transformFn * @return {?} */ function (instance, meta, transformFn) { var _a; this.mutations.add(transformMutations(instance, meta, transformFn)); this.updates.add(transformUpdates(instance, meta, transformFn) || []); this.resolvers.add(transformResolvers(instance, meta, transformFn) || []); if (meta.defaults) { this.cache.writeData({ data: meta.defaults, }); } if (meta.typeDefs) { if (!this.typeDefs) { this.typeDefs = []; } if (typeof this.typeDefs === 'string') { this.typeDefs = [this.typeDefs]; } (_a = this.typeDefs).push.apply(_a, __spread((typeof meta.typeDefs === 'string' ? [meta.typeDefs] : meta.typeDefs))); } }; return Manager; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} manager * @return {?} */ function createMutationSchema(manager) { /** @type {?} */ var schema = {}; manager.mutations.forEach(function (def, name) { schema[name] = createMutationResolver(def, manager); }); return schema; } /** * @param {?} def * @param {?} manager * @return {?} */ function createMutationResolver(def, manager) { var _this = this; return function (_, args, context) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, def.resolve(args, buildContext(context, manager.getClient()))]; }); }); }; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} manager * @return {?} */ function createResolvers(manager) { /** @type {?} */ var schema = {}; manager.resolvers.forEach(function (def) { var _a = __read(def.path.split('.'), 2), typeName = _a[0], fieldName = _a[1]; if (!schema[typeName]) { schema[typeName] = {}; } schema[typeName][fieldName] = createResolver(def, manager); }); return schema; } /** * @param {?} def * @param {?} manager * @return {?} */ function createResolver(def, manager) { return function (parent, args, context) { return def.resolve(parent, args, buildContext(context, manager.getClient())); }; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} obj * @return {?} */ function isManager(obj) { return obj instanceof Manager; } var LoonaLink = /** @class */ (function (_super) { __extends(LoonaLink, _super); function LoonaLink(optionsOrManager) { var _this = _super.call(this) || this; if (isManager(optionsOrManager)) { _this.manager = optionsOrManager; } else { _this.manager = new Manager(optionsOrManager); } _this.stateLink = withClientState({ cache: _this.manager.cache, resolvers: function () { return __assign({ Mutation: createMutationSchema(_this.manager) }, createResolvers(_this.manager)); }, defaults: _this.manager.defaults, typeDefs: _this.manager.typeDefs, }); return _this; } /** * @param {?} operation * @param {?} forward * @return {?} */ LoonaLink.prototype.request = /** * @param {?} operation * @param {?} forward * @return {?} */ function (operation, forward) { return (/** @type {?} */ (this.stateLink.request(operation, forward))); }; return LoonaLink; }(ApolloLink)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} mutation * @return {?} */ function Mutation(mutation) { return function (target, name, _descriptor) { setMutationMetadata(target, name, getMutation(mutation) || ((/** @type {?} */ (mutation)))); }; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} path * @return {?} */ function Resolve(path) { return function (target, name, _descriptor) { setResolveMetadata(target, name, path); }; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} target * @param {?=} options * @return {?} */ function setStateMetadata(target, options) { /** @type {?} */ var meta = ensureMetadata(target); if (typeof options !== 'undefined') { meta.defaults = options.defaults; meta.typeDefs = options.typeDefs; } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @template T * @param {?=} options * @return {?} */ function State(options) { return function (target) { setStateMetadata(target, options); return target; }; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} mutation * @return {?} */ function Update(mutation) { return function (target, name, _descriptor) { /** @type {?} */ var mutationName; if (isMutation(mutation)) { /** @type {?} */ var document_1 = getMutation(mutation); if (!document_1) { throw new Error("Mutation " + ((/** @type {?} */ (mutation))).name + " is missing a static property 'mutation'"); } mutationName = getNameOfMutation(document_1); } else if (typeof mutation === 'string') { mutationName = mutation; } else { mutationName = getNameOfMutation(mutation); } setUpdateMetadata(target, name, mutationName); }; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} proto * @param {?} propName * @param {?} effects * @return {?} */ function setEffectMetadata(proto, propName, effects) { var e_1, _a; /** @type {?} */ var constructor = proto.constructor; /** @type {?} */ var meta = ensureMetadata(constructor); try { for (var effects_1 = __values(effects), effects_1_1 = effects_1.next(); !effects_1_1.done; effects_1_1 = effects_1.next()) { var action = effects_1_1.value; /** @type {?} */ var type = undefined; if (typeof action === 'string') { type = action; } else if (isMutation(action)) { type = mutationToType(action); } else if (isDocument(action)) { type = getNameOfMutation(action); } else if (typeof action.type === 'string') { type = action.type; } if (!type) { throw new Error("Loona couldn't figure out the type of the action"); } if (!meta.effects[type]) { meta.effects[type] = []; } meta.effects[type].push({ propName: propName, type: type, }); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (effects_1_1 && !effects_1_1.done && (_a = effects_1.return)) _a.call(effects_1); } finally { if (e_1) throw e_1.error; } } } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @param {?} effects * @return {?} */ function Effect(effects) { return function (target, name, _descriptor) { setEffectMetadata(target, name, Array.isArray(effects) ? effects : [effects]); }; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc */ export { LoonaLink, Manager, Mutation, Resolve, State, Update, Effect, buildContext, buildGetCacheKey, getFragmentTypename, patchQuery, patchFragment, isDocument, isMutationAsAction, getActionType, readMetadata, ensureMetadata, METADATA_KEY, setMutationMetadata, hasMutation, transformMutations, setResolveMetadata, transformResolvers, setStateMetadata, setUpdateMetadata, transformUpdates, setEffectMetadata, mutationToType, getMutation, isMutation, getNameOfMutation, withUpdates, buildActionFromResult, buildActionFromError, MutationManager, Store as ɵb }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9vbmEuY29yZS5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQGxvb25hL2NvcmUvaW50ZXJuYWwvc3RvcmUudHMiLCJuZzovL0Bsb29uYS9jb3JlL2ludGVybmFsL3V0aWxzLnRzIiwibmc6Ly9AbG9vbmEvY29yZS9oZWxwZXJzLnRzIiwibmc6Ly9AbG9vbmEvY29yZS9tdXRhdGlvbi50cyIsIm5nOi8vQGxvb25hL2NvcmUvdXBkYXRlLnRzIiwibmc6Ly9AbG9vbmEvY29yZS9yZXNvbHZlcnMudHMiLCJuZzovL0Bsb29uYS9jb3JlL21ldGFkYXRhL21ldGFkYXRhLnRzIiwibmc6Ly9AbG9vbmEvY29yZS9tZXRhZGF0YS9tdXRhdGlvbi50cyIsIm5nOi8vQGxvb25hL2NvcmUvbWV0YWRhdGEvdXBkYXRlLnRzIiwibmc6Ly9AbG9vbmEvY29yZS9tZXRhZGF0YS9yZXNvbHZlLnRzIiwibmc6Ly9AbG9vbmEvY29yZS9tYW5hZ2VyLnRzIiwibmc6Ly9AbG9vbmEvY29yZS9pbnRlcm5hbC9tdXRhdGlvbi50cyIsIm5nOi8vQGxvb25hL2NvcmUvaW50ZXJuYWwvcmVzb2x2ZXJzLnRzIiwibmc6Ly9AbG9vbmEvY29yZS9saW5rLnRzIiwibmc6Ly9AbG9vbmEvY29yZS9kZWNvcmF0b3JzL211dGF0aW9uLnRzIiwibmc6Ly9AbG9vbmEvY29yZS9kZWNvcmF0b3JzL3Jlc29sdmUudHMiLCJuZzovL0Bsb29uYS9jb3JlL21ldGFkYXRhL3N0YXRlLnRzIiwibmc6Ly9AbG9vbmEvY29yZS9kZWNvcmF0b3JzL3N0YXRlLnRzIiwibmc6Ly9AbG9vbmEvY29yZS9kZWNvcmF0b3JzL3VwZGF0ZS50cyIsIm5nOi8vQGxvb25hL2NvcmUvbWV0YWRhdGEvZWZmZWN0LnRzIiwibmc6Ly9AbG9vbmEvY29yZS9kZWNvcmF0b3JzL2VmZmVjdC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgU3RvcmU8VD4ge1xuICBzdG9yZTogTWFwPHN0cmluZywgVD47XG5cbiAgY29uc3RydWN0b3IoZGF0YTogUmVjb3JkPHN0cmluZywgVD4gPSB7fSkge1xuICAgIHRoaXMuc3RvcmUgPSBuZXcgTWFwKE9iamVjdC5lbnRyaWVzKGRhdGEpKTtcbiAgfVxuXG4gIGdldChrZXk6IHN0cmluZyk6IFQgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnN0b3JlLmdldChrZXkpO1xuICB9XG5cbiAgc2V0KGtleTogc3RyaW5nLCB2YWx1ZTogVCk6IHZvaWQge1xuICAgIHRoaXMuc3RvcmUuc2V0KGtleSwgdmFsdWUpO1xuICB9XG5cbiAgZm9yRWFjaChmbjogKHZhbHVlOiBULCBrZXk6IHN0cmluZykgPT4gdm9pZCkge1xuICAgIHRoaXMuc3RvcmUuZm9yRWFjaChmbik7XG4gIH1cbn1cbiIsImltcG9ydCB7RG9jdW1lbnROb2RlLCBPcGVyYXRpb25EZWZpbml0aW9uTm9kZSwgRmllbGROb2RlfSBmcm9tICdncmFwaHFsJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE11dGF0aW9uRGVmaW5pdGlvbihcbiAgZG9jOiBEb2N1bWVudE5vZGUsXG4pOiBPcGVyYXRpb25EZWZpbml0aW9uTm9kZSB7XG4gIGNvbnN0IGlzTXV0YXRpb24gPSAoZGVmOiBhbnkpOiBkZWYgaXMgT3BlcmF0aW9uRGVmaW5pdGlvbk5vZGUgPT5cbiAgICBkZWYua2luZCA9PT0gJ09wZXJhdGlvbkRlZmluaXRpb24nICYmIGRlZi5vcGVyYXRpb24gPT09ICdtdXRhdGlvbic7XG4gIGNvbnN0IGRlZnMgPSBkb2MuZGVmaW5pdGlvbnMuZmlsdGVyKGlzTXV0YXRpb24pO1xuXG4gIGlmICghZGVmcyB8fCAhZGVmc1swXSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTXVzdCBjb250YWluIGEgbXV0YXRpb24gZGVmaW5pdGlvbi4nKTtcbiAgfVxuXG4gIHJldHVybiBkZWZzWzBdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rmlyc3RGaWVsZChkZWY6IE9wZXJhdGlvbkRlZmluaXRpb25Ob2RlKTogRmllbGROb2RlIHtcbiAgcmV0dXJuIGRlZi5zZWxlY3Rpb25TZXQuc2VsZWN0aW9uc1swXSBhcyBGaWVsZE5vZGU7XG59XG4iLCJpbXBvcnQge0RvY3VtZW50Tm9kZSwgRnJhZ21lbnREZWZpbml0aW9uTm9kZX0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQge0Fwb2xsb0NsaWVudH0gZnJvbSAnYXBvbGxvLWNsaWVudCc7XG5pbXBvcnQge0RhdGFQcm94eX0gZnJvbSAnYXBvbGxvLWNhY2hlJztcbmltcG9ydCBwcm9kdWNlIGZyb20gJ2ltbWVyJztcblxuaW1wb3J0IHtSZWNlaXZlZENvbnRleHQsIENvbnRleHR9IGZyb20gJy4vdHlwZXMvY29tbW9uJztcbmltcG9ydCB7QWN0aW9uLCBNdXRhdGlvbkFzQWN0aW9ufSBmcm9tICcuL3R5cGVzL2VmZmVjdCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZENvbnRleHQoXG4gIGNvbnRleHQ6IFJlY2VpdmVkQ29udGV4dCxcbiAgY2xpZW50OiBBcG9sbG9DbGllbnQ8YW55Pixcbik6IENvbnRleHQge1xuICByZXR1cm4ge1xuICAgIC4uLmNvbnRleHQsXG4gICAgcGF0Y2hRdWVyeTogcGF0Y2hRdWVyeShjbGllbnQpLFxuICAgIHBhdGNoRnJhZ21lbnQ6IHBhdGNoRnJhZ21lbnQoY29udGV4dCwgY2xpZW50KSxcbiAgICB3cml0ZURhdGEob3B0aW9uczogRGF0YVByb3h5LldyaXRlRGF0YU9wdGlvbnM8YW55Pikge1xuICAgICAgcmV0dXJuIGNsaWVudC53cml0ZURhdGEob3B0aW9ucyk7XG4gICAgfSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkR2V0Q2FjaGVLZXkoY2FjaGU6IGFueSkge1xuICByZXR1cm4gKG9iajoge19fdHlwZW5hbWU6IHN0cmluZzsgaWQ6IHN0cmluZyB8IG51bWJlcn0pID0+IHtcbiAgICBpZiAoKGNhY2hlIGFzIGFueSkuY29uZmlnKSB7XG4gICAgICByZXR1cm4gKGNhY2hlIGFzIGFueSkuY29uZmlnLmRhdGFJZEZyb21PYmplY3Qob2JqKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnVG8gdXNlIGNvbnRleHQuZ2V0Q2FjaGVLZXksIHlvdSBuZWVkIHRvIHVzZSBhIGNhY2hlIHRoYXQgaGFzIGEgY29uZmlndXJhYmxlIGRhdGFJZEZyb21PYmplY3QsIGxpa2UgYXBvbGxvLWNhY2hlLWlubWVtb3J5LicsXG4gICAgICApO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZyYWdtZW50VHlwZW5hbWUoZnJhZ21lbnQ6IERvY3VtZW50Tm9kZSk6IHN0cmluZyB7XG4gIGNvbnN0IGRlZiA9IGZyYWdtZW50LmRlZmluaXRpb25zLmZpbmQoXG4gICAgZGVmID0+IGRlZi5raW5kID09PSAnRnJhZ21lbnREZWZpbml0aW9uJyxcbiAgKSBhcyBGcmFnbWVudERlZmluaXRpb25Ob2RlO1xuXG4gIHJldHVybiBkZWYudHlwZUNvbmRpdGlvbi5uYW1lLnZhbHVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGF0Y2hRdWVyeShjbGllbnQ6IEFwb2xsb0NsaWVudDxhbnk+KSB7XG4gIHJldHVybiA8UiA9IGFueT4oXG4gICAgcXVlcnk6XG4gICAgICB8IERvY3VtZW50Tm9kZVxuICAgICAgfCB7XG4gICAgICAgICAgcXVlcnk6IERvY3VtZW50Tm9kZTtcbiAgICAgICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgICAgIFtrZXk6IHN0cmluZ106IGFueTtcbiAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgIHBhdGNoRm46IChkYXRhOiBSKSA9PiBhbnksXG4gICk6IFIgPT4ge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBpc0RvY3VtZW50KHF1ZXJ5KSA/IHtxdWVyeX0gOiBxdWVyeTtcbiAgICBjb25zdCBvYmo6IGFueSA9IGNsaWVudC5yZWFkUXVlcnkob3B0aW9ucyk7XG4gICAgY29uc3QgZGF0YSA9IHByb2R1Y2Uob2JqLCBwYXRjaEZuKTtcblxuICAgIGNsaWVudC53cml0ZVF1ZXJ5KHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBkYXRhLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXRjaEZyYWdtZW50KFxuICBjb250ZXh0OiBSZWNlaXZlZENvbnRleHQsXG4gIGNsaWVudDogQXBvbGxvQ2xpZW50PGFueT4sXG4pIHtcbiAgcmV0dXJuIDxSID0gYW55PihcbiAgICBmcmFnbWVudDogRG9jdW1lbnROb2RlLFxuICAgIG9iajogYW55LFxuICAgIHBhdGNoRm46IChkYXRhOiBSKSA9PiBhbnksXG4gICk6IFIgPT4ge1xuICAgIGNvbnN0IF9fdHlwZW5hbWUgPSBnZXRGcmFnbWVudFR5cGVuYW1lKGZyYWdtZW50KTtcbiAgICBjb25zdCBpZCA9IGNvbnRleHQuZ2V0Q2FjaGVLZXkoe1xuICAgICAgLi4ub2JqLFxuICAgICAgX190eXBlbmFtZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGZyZ210OiBhbnkgPSBjbGllbnQucmVhZEZyYWdtZW50KHtcbiAgICAgIGZyYWdtZW50LFxuICAgICAgaWQsXG4gICAgfSk7XG4gICAgY29uc3QgZGF0YSA9IHByb2R1Y2UoZnJnbXQsIHBhdGNoRm4pO1xuXG4gICAgY2xpZW50LndyaXRlRnJhZ21lbnQoe1xuICAgICAgZnJhZ21lbnQsXG4gICAgICBpZCxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgLi4uZGF0YSxcbiAgICAgICAgX190eXBlbmFtZSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICByZXR1cm4gZGF0YTtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRG9jdW1lbnQoZG9jOiBhbnkpOiBkb2MgaXMgRG9jdW1lbnROb2RlIHtcbiAgcmV0dXJuIGRvYyAmJiBkb2Mua2luZCA9PT0gJ0RvY3VtZW50Jztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTXV0YXRpb25Bc0FjdGlvbihhY3Rpb246IEFjdGlvbik6IGFjdGlvbiBpcyBNdXRhdGlvbkFzQWN0aW9uIHtcbiAgcmV0dXJuIGFjdGlvbi50eXBlID09PSAnbXV0YXRpb24nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWN0aW9uVHlwZShhY3Rpb246IGFueSk6IHN0cmluZyB7XG4gIGlmIChhY3Rpb24uY29uc3RydWN0b3IgJiYgYWN0aW9uLmNvbnN0cnVjdG9yLnR5cGUpIHtcbiAgICByZXR1cm4gYWN0aW9uLmNvbnN0cnVjdG9yLnR5cGU7XG4gIH1cblxuICByZXR1cm4gYWN0aW9uLnR5cGU7XG59XG4iLCJpbXBvcnQge0RvY3VtZW50Tm9kZSwgR3JhcGhRTEVycm9yfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7TXV0YXRpb25PcHRpb25zfSBmcm9tICdhcG9sbG8tY2xpZW50JztcbmltcG9ydCB7RmV0Y2hSZXN1bHR9IGZyb20gJ2Fwb2xsby1saW5rJztcblxuaW1wb3J0IHtNdXRhdGlvbkRlZiwgTXV0YXRpb25PYmplY3R9IGZyb20gJy4vdHlwZXMvbXV0YXRpb24nO1xuaW1wb3J0IHtTdG9yZX0gZnJvbSAnLi9pbnRlcm5hbC9zdG9yZSc7XG5pbXBvcnQge2dldE11dGF0aW9uRGVmaW5pdGlvbiwgZ2V0Rmlyc3RGaWVsZH0gZnJvbSAnLi9pbnRlcm5hbC91dGlscyc7XG5pbXBvcnQge01hbmFnZXJ9IGZyb20gJy4vbWFuYWdlcic7XG5pbXBvcnQge2J1aWxkQ29udGV4dCwgYnVpbGRHZXRDYWNoZUtleX0gZnJvbSAnLi9oZWxwZXJzJztcblxuZXhwb3J0IGNsYXNzIE11dGF0aW9uTWFuYWdlciBleHRlbmRzIFN0b3JlPE11dGF0aW9uRGVmPiB7XG4gIGNvbnN0cnVjdG9yKGRlZnM/OiBNdXRhdGlvbkRlZltdKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGlmIChkZWZzKSB7XG4gICAgICBkZWZzLmZvckVhY2goZGVmID0+IHtcbiAgICAgICAgdGhpcy5zZXQoZGVmLm11dGF0aW9uLCBkZWYpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgYWRkKGRlZnM6IE11dGF0aW9uRGVmW10pOiB2b2lkIHtcbiAgICBkZWZzLmZvckVhY2goZGVmID0+IHtcbiAgICAgIHRoaXMuc2V0KGRlZi5tdXRhdGlvbiwgZGVmKTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbXV0YXRpb25Ub1R5cGUoYWN0aW9uOiBNdXRhdGlvbk9iamVjdCk6IHN0cmluZyB7XG4gIGNvbnN0IG11dGF0aW9uID0gZ2V0TXV0YXRpb24oYWN0aW9uKTtcbiAgY29uc3QgbmFtZSA9IGdldE5hbWVPZk11dGF0aW9uKG11dGF0aW9uKTtcblxuICByZXR1cm4gbmFtZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE11dGF0aW9uKGFjdGlvbjogYW55KTogRG9jdW1lbnROb2RlIHtcbiAgaWYgKGFjdGlvbi5jb25zdHJ1Y3RvciAmJiBhY3Rpb24uY29uc3RydWN0b3IubXV0YXRpb24pIHtcbiAgICByZXR1cm4gYWN0aW9uLmNvbnN0cnVjdG9yLm11dGF0aW9uO1xuICB9XG5cbiAgcmV0dXJuIGFjdGlvbi5tdXRhdGlvbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTXV0YXRpb24oYWN0aW9uOiBhbnkpOiBhY3Rpb24gaXMgTXV0YXRpb25PYmplY3Qge1xuICByZXR1cm4gdHlwZW9mIGdldE11dGF0aW9uKGFjdGlvbikgIT09ICd1bmRlZmluZWQnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmFtZU9mTXV0YXRpb24obXV0YXRpb246IERvY3VtZW50Tm9kZSk6IHN0cmluZyB7XG4gIGNvbnN0IGRlZiA9IGdldE11dGF0aW9uRGVmaW5pdGlvbihtdXRhdGlvbik7XG4gIGNvbnN0IGZpZWxkID0gZ2V0Rmlyc3RGaWVsZChkZWYpO1xuXG4gIHJldHVybiBmaWVsZC5uYW1lLnZhbHVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aFVwZGF0ZXM8VCwgVj4oXG4gIGNvbmZpZzogTXV0YXRpb25PcHRpb25zPGFueSwgVj4sXG4gIG1hbmFnZXI6IE1hbmFnZXIsXG4pOiBNdXRhdGlvbk9wdGlvbnM8YW55LCBWPiB7XG4gIGNvbnN0IG9yZ1VwZGF0ZSA9IGNvbmZpZy51cGRhdGU7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5jb25maWcsXG4gICAgdXBkYXRlOiAocHJveHksIG11dGF0aW9uUmVzdWx0OiBGZXRjaFJlc3VsdDxUPikgPT4ge1xuICAgICAgY29uc3QgbmFtZSA9IGdldE5hbWVPZk11dGF0aW9uKGNvbmZpZy5tdXRhdGlvbik7XG4gICAgICBjb25zdCByZXN1bHQ6IFQgPSBtdXRhdGlvblJlc3VsdC5kYXRhICYmIG11dGF0aW9uUmVzdWx0LmRhdGFbbmFtZV07XG4gICAgICBjb25zdCBjYWNoZSA9IG1hbmFnZXIuY2FjaGU7XG5cbiAgICAgIGNvbnN0IGNvbnRleHQgPSBidWlsZENvbnRleHQoXG4gICAgICAgIHtcbiAgICAgICAgICBjYWNoZTogcHJveHksXG4gICAgICAgICAgZ2V0Q2FjaGVLZXk6IGJ1aWxkR2V0Q2FjaGVLZXkoY2FjaGUpLFxuICAgICAgICB9LFxuICAgICAgICBtYW5hZ2VyLmdldENsaWVudCgpLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgdXBkYXRlcyA9IG1hbmFnZXIudXBkYXRlcy5nZXQobmFtZSk7XG5cbiAgICAgIGlmICh1cGRhdGVzKSB7XG4gICAgICAgIGNvbnN0IGluZm8gPSB7XG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICB2YXJpYWJsZXM6IGNvbmZpZy52YXJpYWJsZXMsXG4gICAgICAgICAgcmVzdWx0LFxuICAgICAgICB9O1xuXG4gICAgICAgIHVwZGF0ZXMuZm9yRWFjaChkZWYgPT4gZGVmLnJlc29sdmUoaW5mbywgY29udGV4dCkpO1xuICAgICAgfVxuXG4gICAgICBpZiAob3JnVXBkYXRlKSB7XG4gICAgICAgIG9yZ1VwZGF0ZShwcm94eSwgbXV0YXRpb25SZXN1bHQpO1xuICAgICAgfVxuICAgIH0sXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEFjdGlvbkZyb21SZXN1bHQ8VCwgVj4oXG4gIGNvbmZpZzogTXV0YXRpb25PcHRpb25zPFQsIFY+LFxuICByZXN1bHQ6IEZldGNoUmVzdWx0PFQ+LFxuKToge1xuICB0eXBlOiBzdHJpbmc7XG4gIG9wdGlvbnM6IE11dGF0aW9uT3B0aW9uczxULCBWPjtcbiAgb2s6IGJvb2xlYW47XG4gIGVycm9ycz86IFJlYWRvbmx5QXJyYXk8R3JhcGhRTEVycm9yPjtcbiAgZGF0YT86IFQgfCB7W2tleTogc3RyaW5nXTogYW55fTtcbiAgZXh0ZW5zaW9ucz86IFJlY29yZDxzdHJpbmcsIGFueT47XG4gIGNvbnRleHQ/OiBhbnk7XG59IHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnbXV0YXRpb24nLFxuICAgIG9wdGlvbnM6IGNvbmZpZyxcbiAgICBvazogdHJ1ZSxcbiAgICAuLi5yZXN1bHQsXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEFjdGlvbkZyb21FcnJvcjxULCBWPihcbiAgY29uZmlnOiBNdXRhdGlvbk9wdGlvbnM8VCwgVj4sXG4gIGVycm9yOiBhbnksXG4pIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAnbXV0YXRpb24nLFxuICAgIG9wdGlvbnM6IGNvbmZpZyxcbiAgICBvazogZmFsc2UsXG4gICAgZXJyb3IsXG4gIH07XG59XG4iLCJpbXBvcnQge1N0b3JlfSBmcm9tICcuL2ludGVybmFsL3N0b3JlJztcbmltcG9ydCB7VXBkYXRlRGVmfSBmcm9tICcuL3R5cGVzL3VwZGF0ZSc7XG5cbmV4cG9ydCBjbGFzcyBVcGRhdGVNYW5hZ2VyIGV4dGVuZHMgU3RvcmU8VXBkYXRlRGVmW10+IHtcbiAgY29uc3RydWN0b3IoZGVmcz86IFVwZGF0ZURlZltdKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGlmIChkZWZzKSB7XG4gICAgICB0aGlzLmFkZChkZWZzKTtcbiAgICB9XG4gIH1cblxuICBhZGQoZGVmczogVXBkYXRlRGVmW10gfCBVcGRhdGVEZWYpOiB2b2lkIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZGVmcykpIHtcbiAgICAgIGRlZnMgPSBbZGVmc107XG4gICAgfVxuXG4gICAgZGVmcy5mb3JFYWNoKGRlZiA9PiB7XG4gICAgICBjb25zdCBhbGwgPSB0aGlzLmdldChkZWYubXV0YXRpb24pIHx8IFtdO1xuXG4gICAgICBhbGwucHVzaChkZWYpO1xuXG4gICAgICBzdXBlci5zZXQoZGVmLm11dGF0aW9uLCBhbGwpO1xuICAgIH0pO1xuICB9XG5cbiAgc2V0KCkge1xuICAgIGNvbnNvbGUuZXJyb3IoJ1VzZSBhZGQoKSBpbnN0ZWFkJyk7XG4gIH1cbn1cbiIsImltcG9ydCB7U3RvcmV9IGZyb20gJy4vaW50ZXJuYWwvc3RvcmUnO1xuaW1wb3J0IHtSZXNvbHZlckRlZn0gZnJvbSAnLi90eXBlcy9yZXNvbHZlcic7XG5cbmV4cG9ydCBjbGFzcyBSZXNvbHZlcnNNYW5hZ2VyIGV4dGVuZHMgU3RvcmU8UmVzb2x2ZXJEZWY+IHtcbiAgY29uc3RydWN0b3IoZGVmcz86IFJlc29sdmVyRGVmW10pIHtcbiAgICBzdXBlcigpO1xuXG4gICAgaWYgKGRlZnMpIHtcbiAgICAgIHRoaXMuYWRkKGRlZnMpO1xuICAgIH1cbiAgfVxuXG4gIGFkZChkZWZzOiBSZXNvbHZlckRlZltdKTogdm9pZCB7XG4gICAgZGVmcy5mb3JFYWNoKGRlZiA9PiB7XG4gICAgICB0aGlzLnNldChkZWYucGF0aCwgZGVmKTtcbiAgICB9KTtcbiAgfVxufVxuIiwiaW1wb3J0IHtNZXRhZGF0YX0gZnJvbSAnLi4vdHlwZXMvbWV0YWRhdGEnO1xuXG5leHBvcnQgY29uc3QgTUVUQURBVEFfS0VZID0gJ0BAbG9vbmEnO1xuXG5leHBvcnQgZnVuY3Rpb24gcmVhZE1ldGFkYXRhKHRhcmdldDogYW55KTogTWV0YWRhdGEge1xuICBjb25zdCBjb25zdHJ1Y3RvciA9IHRhcmdldC5jb25zdHJ1Y3RvcjtcblxuICByZXR1cm4gY29uc3RydWN0b3JbTUVUQURBVEFfS0VZXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVuc3VyZU1ldGFkYXRhKHRhcmdldDogYW55KTogTWV0YWRhdGEge1xuICBpZiAoIXRhcmdldC5oYXNPd25Qcm9wZXJ0eShNRVRBREFUQV9LRVkpKSB7XG4gICAgY29uc3QgZGVmYXVsdFZhbHVlOiBNZXRhZGF0YSA9IHtcbiAgICAgIGRlZmF1bHRzOiB7fSxcbiAgICAgIG11dGF0aW9uczogW10sXG4gICAgICByZXNvbHZlcnM6IFtdLFxuICAgICAgdXBkYXRlczogW10sXG4gICAgICB0eXBlRGVmczogW10sXG4gICAgICBlZmZlY3RzOiB7fSxcbiAgICB9O1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgTUVUQURBVEFfS0VZLCB7XG4gICAgICB2YWx1ZTogZGVmYXVsdFZhbHVlLFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHRhcmdldFtNRVRBREFUQV9LRVldO1xufVxuIiwiaW1wb3J0IHtEb2N1bWVudE5vZGV9IGZyb20gJ2dyYXBocWwnO1xuXG5pbXBvcnQge2Vuc3VyZU1ldGFkYXRhLCByZWFkTWV0YWRhdGF9IGZyb20gJy4vbWV0YWRhdGEnO1xuaW1wb3J0IHtNZXRhZGF0YX0gZnJvbSAnLi4vdHlwZXMvbWV0YWRhdGEnO1xuaW1wb3J0IHtNdXRhdGlvbkRlZiwgTXV0YXRpb25SZXNvbHZlRm59IGZyb20gJy4uL3R5cGVzL211dGF0aW9uJztcbmltcG9ydCB7Z2V0TmFtZU9mTXV0YXRpb259IGZyb20gJy4uL211dGF0aW9uJztcblxuZXhwb3J0IGZ1bmN0aW9uIHNldE11dGF0aW9uTWV0YWRhdGEoXG4gIHByb3RvOiBhbnksXG4gIHByb3BOYW1lOiBzdHJpbmcsXG4gIG11dGF0aW9uOiBEb2N1bWVudE5vZGUgfCBzdHJpbmcsXG4pIHtcbiAgY29uc3QgY29uc3RydWN0b3IgPSBwcm90by5jb25zdHJ1Y3RvcjtcbiAgY29uc3QgbWV0YSA9IGVuc3VyZU1ldGFkYXRhKGNvbnN0cnVjdG9yKTtcblxuICBtZXRhLm11dGF0aW9ucy5wdXNoKHtcbiAgICBwcm9wTmFtZSxcbiAgICBtdXRhdGlvbixcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNNdXRhdGlvbih0YXJnZXQ6IGFueSwgcHJvcE5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBtZXRhID0gcmVhZE1ldGFkYXRhKHRhcmdldCk7XG5cbiAgaWYgKG1ldGEpIHtcbiAgICByZXR1cm4gbWV0YS5tdXRhdGlvbnMuc29tZShkZWYgPT4ge1xuICAgICAgcmV0dXJuIGRlZi5wcm9wTmFtZSA9PT0gcHJvcE5hbWU7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1NdXRhdGlvbnMoXG4gIGluc3RhbmNlOiBhbnksXG4gIG1ldGE6IE1ldGFkYXRhLFxuICB0cmFuc2Zvcm1GbjogKChyZXNvbHZlcjogYW55KSA9PiBNdXRhdGlvblJlc29sdmVGbikgPSByZXNvbHZlciA9PiByZXNvbHZlcixcbik6IE11dGF0aW9uRGVmW10ge1xuICByZXR1cm4gbWV0YS5tdXRhdGlvbnMubWFwKCh7cHJvcE5hbWUsIG11dGF0aW9ufSkgPT4gKHtcbiAgICBtdXRhdGlvbjpcbiAgICAgIHR5cGVvZiBtdXRhdGlvbiA9PT0gJ3N0cmluZycgPyBtdXRhdGlvbiA6IGdldE5hbWVPZk11dGF0aW9uKG11dGF0aW9uKSxcbiAgICByZXNvbHZlOiB0cmFuc2Zvcm1GbihpbnN0YW5jZVtwcm9wTmFtZV0uYmluZChpbnN0YW5jZSkpLFxuICB9KSk7XG59XG4iLCJpbXBvcnQge1VwZGF0ZURlZiwgVXBkYXRlUmVzb2x2ZUZufSBmcm9tICcuLi90eXBlcy91cGRhdGUnO1xuaW1wb3J0IHtNZXRhZGF0YX0gZnJvbSAnLi4vdHlwZXMvbWV0YWRhdGEnO1xuaW1wb3J0IHtlbnN1cmVNZXRhZGF0YX0gZnJvbSAnLi9tZXRhZGF0YSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRVcGRhdGVNZXRhZGF0YShcbiAgcHJvdG86IGFueSxcbiAgcHJvcE5hbWU6IHN0cmluZyxcbiAgbXV0YXRpb246IHN0cmluZyxcbikge1xuICBjb25zdCBjb25zdHJ1Y3RvciA9IHByb3RvLmNvbnN0cnVjdG9yO1xuICBjb25zdCBtZXRhID0gZW5zdXJlTWV0YWRhdGEoY29uc3RydWN0b3IpO1xuXG4gIG1ldGEudXBkYXRlcy5wdXNoKHtcbiAgICBwcm9wTmFtZSxcbiAgICBtdXRhdGlvbixcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1VcGRhdGVzKFxuICBpbnN0YW5jZTogYW55LFxuICBtZXRhOiBNZXRhZGF0YSxcbiAgdHJhbnNmb3JtRm46ICgocmVzb2x2ZXI6IGFueSkgPT4gVXBkYXRlUmVzb2x2ZUZuKSA9IHJlc29sdmVyID0+IHJlc29sdmVyLFxuKTogVXBkYXRlRGVmW10gfCB1bmRlZmluZWQge1xuICBpZiAobWV0YS51cGRhdGVzKSB7XG4gICAgcmV0dXJuIG1ldGEudXBkYXRlcy5tYXAoKHtwcm9wTmFtZSwgbXV0YXRpb259KSA9PiAoe1xuICAgICAgbXV0YXRpb24sXG4gICAgICByZXNvbHZlOiB0cmFuc2Zvcm1GbihpbnN0YW5jZVtwcm9wTmFtZV0uYmluZChpbnN0YW5jZSkpLFxuICAgIH0pKTtcbiAgfVxufVxuIiwiaW1wb3J0IHtlbnN1cmVNZXRhZGF0YX0gZnJvbSAnLi9tZXRhZGF0YSc7XG5pbXBvcnQge01ldGFkYXRhfSBmcm9tICcuLi90eXBlcy9tZXRhZGF0YSc7XG5pbXBvcnQge1Jlc29sdmVyRGVmfSBmcm9tICcuLi90eXBlcy9yZXNvbHZlcic7XG5pbXBvcnQge1Jlc29sdmVGbn0gZnJvbSAnLi4vdHlwZXMvY29tbW9uJztcblxuZXhwb3J0IGZ1bmN0aW9uIHNldFJlc29sdmVNZXRhZGF0YShwcm90bzogYW55LCBwcm9wTmFtZTogc3RyaW5nLCBwYXRoOiBzdHJpbmcpIHtcbiAgY29uc3QgY29uc3RydWN0b3IgPSBwcm90by5jb25zdHJ1Y3RvcjtcbiAgY29uc3QgbWV0YSA9IGVuc3VyZU1ldGFkYXRhKGNvbnN0cnVjdG9yKTtcblxuICBtZXRhLnJlc29sdmVycy5wdXNoKHtwcm9wTmFtZSwgcGF0aH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmb3JtUmVzb2x2ZXJzKFxuICBpbnN0YW5jZTogYW55LFxuICBtZXRhOiBNZXRhZGF0YSxcbiAgdHJhbnNmb3JtRm46ICgocmVzb2x2ZXI6IGFueSkgPT4gUmVzb2x2ZUZuKSA9IHJlc29sdmVyID0+IHJlc29sdmVyLFxuKTogUmVzb2x2ZXJEZWZbXSB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBtZXRhLnJlc29sdmVycy5tYXAoKHtwcm9wTmFtZSwgcGF0aH0pID0+ICh7XG4gICAgbmFtZTogcHJvcE5hbWUsXG4gICAgcGF0aCxcbiAgICByZXNvbHZlOiB0cmFuc2Zvcm1GbihpbnN0YW5jZVtwcm9wTmFtZV0uYmluZChpbnN0YW5jZSkpLFxuICB9KSk7XG59XG4iLCJpbXBvcnQge0Fwb2xsb0NsaWVudH0gZnJvbSAnYXBvbGxvLWNsaWVudCc7XG5pbXBvcnQge0Fwb2xsb0NhY2hlfSBmcm9tICdhcG9sbG8tY2FjaGUnO1xuXG5pbXBvcnQge011dGF0aW9uTWFuYWdlcn0gZnJvbSAnLi9tdXRhdGlvbic7XG5pbXBvcnQge1VwZGF0ZU1hbmFnZXJ9IGZyb20gJy4vdXBkYXRlJztcbmltcG9ydCB7UmVzb2x2ZXJzTWFuYWdlcn0gZnJvbSAnLi9yZXNvbHZlcnMnO1xuaW1wb3J0IHtPcHRpb25zfSBmcm9tICcuL3R5cGVzL29wdGlvbnMnO1xuaW1wb3J0IHtNZXRhZGF0YX0gZnJvbSAnLi90eXBlcy9tZXRhZGF0YSc7XG5pbXBvcnQge3RyYW5zZm9ybU11dGF0aW9uc30gZnJvbSAnLi9tZXRhZGF0YS9tdXRhdGlvbic7XG5pbXBvcnQge3RyYW5zZm9ybVVwZGF0ZXN9IGZyb20gJy4vbWV0YWRhdGEvdXBkYXRlJztcbmltcG9ydCB7dHJhbnNmb3JtUmVzb2x2ZXJzfSBmcm9tICcuL21ldGFkYXRhL3Jlc29sdmUnO1xuXG5leHBvcnQgY2xhc3MgTWFuYWdlciB7XG4gIGNhY2hlOiBBcG9sbG9DYWNoZTxhbnk+O1xuICBtdXRhdGlvbnM6IE11dGF0aW9uTWFuYWdlcjtcbiAgdXBkYXRlczogVXBkYXRlTWFuYWdlcjtcbiAgcmVzb2x2ZXJzOiBSZXNvbHZlcnNNYW5hZ2VyO1xuICBkZWZhdWx0czogYW55O1xuICB0eXBlRGVmczogc3RyaW5nIHwgc3RyaW5nW10gfCB1bmRlZmluZWQ7XG4gIGdldENsaWVudDogKCkgPT4gQXBvbGxvQ2xpZW50PGFueT4gfCBuZXZlciA9ICgpID0+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01hbmFnZXIgcmVxdWlyZXMgQXBvbGxvQ2xpZW50Jyk7XG4gIH07XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogT3B0aW9ucykge1xuICAgIHRoaXMuY2FjaGUgPSBvcHRpb25zLmNhY2hlO1xuICAgIHRoaXMuZGVmYXVsdHMgPSBvcHRpb25zLmRlZmF1bHRzO1xuICAgIHRoaXMudHlwZURlZnMgPSBvcHRpb25zLnR5cGVEZWZzO1xuICAgIHRoaXMucmVzb2x2ZXJzID0gbmV3IFJlc29sdmVyc01hbmFnZXIob3B0aW9ucy5yZXNvbHZlcnMpO1xuICAgIHRoaXMudXBkYXRlcyA9IG5ldyBVcGRhdGVNYW5hZ2VyKG9wdGlvbnMudXBkYXRlcyk7XG4gICAgdGhpcy5tdXRhdGlvbnMgPSBuZXcgTXV0YXRpb25NYW5hZ2VyKG9wdGlvbnMubXV0YXRpb25zKTtcblxuICAgIGlmIChvcHRpb25zLmdldENsaWVudCkge1xuICAgICAgdGhpcy5nZXRDbGllbnQgPSBvcHRpb25zLmdldENsaWVudDtcbiAgICB9XG4gIH1cblxuICBhZGRTdGF0ZShcbiAgICBpbnN0YW5jZTogYW55LFxuICAgIG1ldGE6IE1ldGFkYXRhLFxuICAgIHRyYW5zZm9ybUZuPzogKChyZXNvbHZlcjogYW55KSA9PiBhbnkpLFxuICApIHtcbiAgICB0aGlzLm11dGF0aW9ucy5hZGQodHJhbnNmb3JtTXV0YXRpb25zKGluc3RhbmNlLCBtZXRhLCB0cmFuc2Zvcm1GbikpO1xuICAgIHRoaXMudXBkYXRlcy5hZGQodHJhbnNmb3JtVXBkYXRlcyhpbnN0YW5jZSwgbWV0YSwgdHJhbnNmb3JtRm4pIHx8IFtdKTtcbiAgICB0aGlzLnJlc29sdmVycy5hZGQodHJhbnNmb3JtUmVzb2x2ZXJzKGluc3RhbmNlLCBtZXRhLCB0cmFuc2Zvcm1GbikgfHwgW10pO1xuXG4gICAgaWYgKG1ldGEuZGVmYXVsdHMpIHtcbiAgICAgIHRoaXMuY2FjaGUud3JpdGVEYXRhKHtcbiAgICAgICAgZGF0YTogbWV0YS5kZWZhdWx0cyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChtZXRhLnR5cGVEZWZzKSB7XG4gICAgICBpZiAoIXRoaXMudHlwZURlZnMpIHtcbiAgICAgICAgdGhpcy50eXBlRGVmcyA9IFtdO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHRoaXMudHlwZURlZnMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMudHlwZURlZnMgPSBbdGhpcy50eXBlRGVmc107XG4gICAgICB9XG5cbiAgICAgIHRoaXMudHlwZURlZnMucHVzaChcbiAgICAgICAgLi4uKHR5cGVvZiBtZXRhLnR5cGVEZWZzID09PSAnc3RyaW5nJ1xuICAgICAgICAgID8gW21ldGEudHlwZURlZnNdXG4gICAgICAgICAgOiBtZXRhLnR5cGVEZWZzKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQge011dGF0aW9uU2NoZW1hLCBNdXRhdGlvbkRlZn0gZnJvbSAnLi4vdHlwZXMvbXV0YXRpb24nO1xuaW1wb3J0IHtSZXNvbHZlRm59IGZyb20gJy4uL3R5cGVzL2NvbW1vbic7XG5pbXBvcnQge01hbmFnZXJ9IGZyb20gJy4uL21hbmFnZXInO1xuaW1wb3J0IHtidWlsZENvbnRleHR9IGZyb20gJy4uL2hlbHBlcnMnO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTXV0YXRpb25TY2hlbWEobWFuYWdlcjogTWFuYWdlcik6IE11dGF0aW9uU2NoZW1hIHtcbiAgY29uc3Qgc2NoZW1hOiBNdXRhdGlvblNjaGVtYSA9IHt9O1xuXG4gIG1hbmFnZXIubXV0YXRpb25zLmZvckVhY2goKGRlZiwgbmFtZSkgPT4ge1xuICAgIHNjaGVtYVtuYW1lXSA9IGNyZWF0ZU11dGF0aW9uUmVzb2x2ZXIoZGVmLCBtYW5hZ2VyKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHNjaGVtYTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlTXV0YXRpb25SZXNvbHZlcihkZWY6IE11dGF0aW9uRGVmLCBtYW5hZ2VyOiBNYW5hZ2VyKTogUmVzb2x2ZUZuIHtcbiAgcmV0dXJuIGFzeW5jIChfLCBhcmdzLCBjb250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGRlZi5yZXNvbHZlKGFyZ3MsIGJ1aWxkQ29udGV4dChjb250ZXh0LCBtYW5hZ2VyLmdldENsaWVudCgpKSk7XG4gIH07XG59XG4iLCJpbXBvcnQge1Jlc29sdmVycywgUmVzb2x2ZXJEZWZ9IGZyb20gJy4uL3R5cGVzL3Jlc29sdmVyJztcbmltcG9ydCB7TWFuYWdlcn0gZnJvbSAnLi4vbWFuYWdlcic7XG5pbXBvcnQge1Jlc29sdmVGbn0gZnJvbSAnLi4vdHlwZXMvY29tbW9uJztcbmltcG9ydCB7YnVpbGRDb250ZXh0fSBmcm9tICcuLi9oZWxwZXJzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVJlc29sdmVycyhtYW5hZ2VyOiBNYW5hZ2VyKTogUmVzb2x2ZXJzIHtcbiAgY29uc3Qgc2NoZW1hOiBSZXNvbHZlcnMgPSB7fTtcblxuICBtYW5hZ2VyLnJlc29sdmVycy5mb3JFYWNoKGRlZiA9PiB7XG4gICAgY29uc3QgW3R5cGVOYW1lLCBmaWVsZE5hbWVdID0gZGVmLnBhdGguc3BsaXQoJy4nKTtcblxuICAgIGlmICghc2NoZW1hW3R5cGVOYW1lXSkge1xuICAgICAgc2NoZW1hW3R5cGVOYW1lXSA9IHt9O1xuICAgIH1cblxuICAgIHNjaGVtYVt0eXBlTmFtZV1bZmllbGROYW1lXSA9IGNyZWF0ZVJlc29sdmVyKGRlZiwgbWFuYWdlcik7XG4gIH0pO1xuXG4gIHJldHVybiBzY2hlbWE7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVJlc29sdmVyKGRlZjogUmVzb2x2ZXJEZWYsIG1hbmFnZXI6IE1hbmFnZXIpOiBSZXNvbHZlRm4ge1xuICByZXR1cm4gKHBhcmVudCwgYXJncywgY29udGV4dCkgPT5cbiAgICBkZWYucmVzb2x2ZShwYXJlbnQsIGFyZ3MsIGJ1aWxkQ29udGV4dChjb250ZXh0LCBtYW5hZ2VyLmdldENsaWVudCgpKSk7XG59XG4iLCJpbXBvcnQge1xuICBBcG9sbG9MaW5rLFxuICBPcGVyYXRpb24sXG4gIE5leHRMaW5rLFxuICBPYnNlcnZhYmxlLFxuICBGZXRjaFJlc3VsdCxcbn0gZnJvbSAnYXBvbGxvLWxpbmsnO1xuaW1wb3J0IHt3aXRoQ2xpZW50U3RhdGV9IGZyb20gJ2Fwb2xsby1saW5rLXN0YXRlJztcblxuaW1wb3J0IHtNYW5hZ2VyfSBmcm9tICcuL21hbmFnZXInO1xuaW1wb3J0IHtjcmVhdGVNdXRhdGlvblNjaGVtYX0gZnJvbSAnLi9pbnRlcm5hbC9tdXRhdGlvbic7XG5pbXBvcnQge2NyZWF0ZVJlc29sdmVyc30gZnJvbSAnLi9pbnRlcm5hbC9yZXNvbHZlcnMnO1xuaW1wb3J0IHtPcHRpb25zfSBmcm9tICcuL3R5cGVzL29wdGlvbnMnO1xuXG5mdW5jdGlvbiBpc01hbmFnZXIob2JqOiBhbnkpOiBvYmogaXMgTWFuYWdlciB7XG4gIHJldHVybiBvYmogaW5zdGFuY2VvZiBNYW5hZ2VyO1xufVxuXG5leHBvcnQgY2xhc3MgTG9vbmFMaW5rIGV4dGVuZHMgQXBvbGxvTGluayB7XG4gIHB1YmxpYyBtYW5hZ2VyOiBNYW5hZ2VyO1xuICBwcml2YXRlIHN0YXRlTGluazogQXBvbGxvTGluaztcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zT3JNYW5hZ2VyOiBPcHRpb25zIHwgTWFuYWdlcikge1xuICAgIHN1cGVyKCk7XG5cbiAgICBpZiAoaXNNYW5hZ2VyKG9wdGlvbnNPck1hbmFnZXIpKSB7XG4gICAgICB0aGlzLm1hbmFnZXIgPSBvcHRpb25zT3JNYW5hZ2VyO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1hbmFnZXIgPSBuZXcgTWFuYWdlcihvcHRpb25zT3JNYW5hZ2VyKTtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXRlTGluayA9IHdpdGhDbGllbnRTdGF0ZSh7XG4gICAgICBjYWNoZTogdGhpcy5tYW5hZ2VyLmNhY2hlLFxuICAgICAgcmVzb2x2ZXJzOiAoKSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgTXV0YXRpb246IGNyZWF0ZU11dGF0aW9uU2NoZW1hKHRoaXMubWFuYWdlciksXG4gICAgICAgICAgLi4uY3JlYXRlUmVzb2x2ZXJzKHRoaXMubWFuYWdlciksXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgZGVmYXVsdHM6IHRoaXMubWFuYWdlci5kZWZhdWx0cyxcbiAgICAgIHR5cGVEZWZzOiB0aGlzLm1hbmFnZXIudHlwZURlZnMsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgcmVxdWVzdChcbiAgICBvcGVyYXRpb246IE9wZXJhdGlvbixcbiAgICBmb3J3YXJkOiBOZXh0TGluayxcbiAgKTogT2JzZXJ2YWJsZTxGZXRjaFJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnN0YXRlTGluay5yZXF1ZXN0KG9wZXJhdGlvbiwgZm9yd2FyZCkgYXMgT2JzZXJ2YWJsZTxcbiAgICAgIEZldGNoUmVzdWx0XG4gICAgPjtcbiAgfVxufVxuIiwiaW1wb3J0IHtEb2N1bWVudE5vZGV9IGZyb20gJ2dyYXBocWwnO1xuXG5pbXBvcnQge3NldE11dGF0aW9uTWV0YWRhdGF9IGZyb20gJy4uL21ldGFkYXRhL211dGF0aW9uJztcbmltcG9ydCB7Z2V0TXV0YXRpb259IGZyb20gJy4uL211dGF0aW9uJztcbmltcG9ydCB7TXV0YXRpb25NZXRob2QsIE11dGF0aW9uT2JqZWN0fSBmcm9tICcuLi90eXBlcy9tdXRhdGlvbic7XG5cbmV4cG9ydCBmdW5jdGlvbiBNdXRhdGlvbihtdXRhdGlvbjogTXV0YXRpb25PYmplY3QgfCBEb2N1bWVudE5vZGUgfCBzdHJpbmcpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKFxuICAgIHRhcmdldDogYW55LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBfZGVzY3JpcHRvcjogVHlwZWRQcm9wZXJ0eURlc2NyaXB0b3I8TXV0YXRpb25NZXRob2Q+LFxuICApIHtcbiAgICBzZXRNdXRhdGlvbk1ldGFkYXRhKFxuICAgICAgdGFyZ2V0LFxuICAgICAgbmFtZSxcbiAgICAgIGdldE11dGF0aW9uKG11dGF0aW9uKSB8fCAobXV0YXRpb24gYXMgc3RyaW5nKSxcbiAgICApO1xuICB9O1xufVxuIiwiaW1wb3J0IHtzZXRSZXNvbHZlTWV0YWRhdGF9IGZyb20gJy4uL21ldGFkYXRhL3Jlc29sdmUnO1xuaW1wb3J0IHtSZXNvbHZlTWV0aG9kfSBmcm9tICcuLi90eXBlcy9yZXNvbHZlcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBSZXNvbHZlKHBhdGg6IHN0cmluZykge1xuICByZXR1cm4gZnVuY3Rpb24oXG4gICAgdGFyZ2V0OiBhbnksXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIF9kZXNjcmlwdG9yOiBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjxSZXNvbHZlTWV0aG9kPixcbiAgKSB7XG4gICAgc2V0UmVzb2x2ZU1ldGFkYXRhKHRhcmdldCwgbmFtZSwgcGF0aCk7XG4gIH07XG59XG4iLCJpbXBvcnQge2Vuc3VyZU1ldGFkYXRhfSBmcm9tICcuL21ldGFkYXRhJztcbmltcG9ydCB7U3RhdGVPcHRpb25zfSBmcm9tICcuLi90eXBlcy9zdGF0ZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRTdGF0ZU1ldGFkYXRhKHRhcmdldDogYW55LCBvcHRpb25zPzogU3RhdGVPcHRpb25zPGFueT4pIHtcbiAgY29uc3QgbWV0YSA9IGVuc3VyZU1ldGFkYXRhKHRhcmdldCk7XG5cbiAgaWYgKHR5cGVvZiBvcHRpb25zICE9PSAndW5kZWZpbmVkJykge1xuICAgIG1ldGEuZGVmYXVsdHMgPSBvcHRpb25zLmRlZmF1bHRzO1xuICAgIG1ldGEudHlwZURlZnMgPSBvcHRpb25zLnR5cGVEZWZzO1xuICB9XG59XG4iLCJpbXBvcnQge3NldFN0YXRlTWV0YWRhdGF9IGZyb20gJy4uL21ldGFkYXRhL3N0YXRlJztcbmltcG9ydCB7U3RhdGVPcHRpb25zfSBmcm9tICcuLi90eXBlcy9zdGF0ZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBTdGF0ZTxUPihvcHRpb25zPzogU3RhdGVPcHRpb25zPFQ+KSB7XG4gIHJldHVybiAodGFyZ2V0OiBhbnkpID0+IHtcbiAgICBzZXRTdGF0ZU1ldGFkYXRhKHRhcmdldCwgb3B0aW9ucyk7XG5cbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9O1xufVxuIiwiaW1wb3J0IHtEb2N1bWVudE5vZGV9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHtzZXRVcGRhdGVNZXRhZGF0YX0gZnJvbSAnLi4vbWV0YWRhdGEvdXBkYXRlJztcbmltcG9ydCB7Z2V0TmFtZU9mTXV0YXRpb24sIGdldE11dGF0aW9uLCBpc011dGF0aW9ufSBmcm9tICcuLi9tdXRhdGlvbic7XG5pbXBvcnQge1VwZGF0ZU1ldGhvZH0gZnJvbSAnLi4vdHlwZXMvdXBkYXRlJztcbmltcG9ydCB7TXV0YXRpb25PYmplY3R9IGZyb20gJy4uL3R5cGVzL211dGF0aW9uJztcblxuZXhwb3J0IGZ1bmN0aW9uIFVwZGF0ZShtdXRhdGlvbjogTXV0YXRpb25PYmplY3QgfCBEb2N1bWVudE5vZGUgfCBzdHJpbmcpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKFxuICAgIHRhcmdldDogYW55LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBfZGVzY3JpcHRvcjogVHlwZWRQcm9wZXJ0eURlc2NyaXB0b3I8VXBkYXRlTWV0aG9kPixcbiAgKSB7XG4gICAgbGV0IG11dGF0aW9uTmFtZTogc3RyaW5nO1xuXG4gICAgaWYgKGlzTXV0YXRpb24obXV0YXRpb24pKSB7XG4gICAgICBjb25zdCBkb2N1bWVudCA9IGdldE11dGF0aW9uKG11dGF0aW9uKTtcblxuICAgICAgaWYgKCFkb2N1bWVudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYE11dGF0aW9uICR7XG4gICAgICAgICAg