UNPKG

@harmowatch/ngx-redux-core

Version:

[![Join the chat at https://gitter.im/harmowatch/ngx-redux-core](https://badges.gitter.im/harmowatch/ngx-redux-core.svg)](https://gitter.im/harmowatch/ngx-redux-core?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

711 lines (694 loc) 62.6 kB
import { __extends, __spread, __assign, __decorate } from 'tslib'; import { InjectionToken, Inject, Injectable, NgZone, Injector, Pipe, isDevMode, NgModule, Optional } from '@angular/core'; import { ReduxActionDispatcher, ReduxStateDecorator, ReduxReducerDecorator, ReduxStateDecoratorForClass } from '@harmowatch/redux-decorators'; export { ReduxActionContextDecoratorForClass as ReduxActionContext, ReduxActionDecoratorForMethod as ReduxAction, ReduxReducerDecoratorForMethod as ReduxReducer, ReduxStateDecoratorForClass as ReduxState } from '@harmowatch/redux-decorators'; import { AsyncSubject, Observable, ReplaySubject, BehaviorSubject } from 'rxjs'; import { distinctUntilChanged, takeWhile } from 'rxjs/operators'; import { applyMiddleware, compose, createStore } from 'redux'; import { CommonModule } from '@angular/common'; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var ReduxStateDefinitionToken = /** @class */ (function (_super) { __extends(ReduxStateDefinitionToken, _super); function ReduxStateDefinitionToken() { return _super.call(this, 'ReduxStateDefinitionToken') || this; } return ReduxStateDefinitionToken; }(InjectionToken)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var ReduxStore = /** @class */ (function (_super) { __extends(ReduxStore, _super); function ReduxStore() { return _super.call(this, 'ReduxStore') || this; } return ReduxStore; }(InjectionToken)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var ReduxRegistry = /** @class */ (function () { function ReduxRegistry(store) { if (store === void 0) { store = null; } ReduxRegistry.reset(); ReduxRegistry.registerStore(store); } /** * @return {?} */ ReduxRegistry.reset = /** * @return {?} */ function () { ReduxRegistry._store = new AsyncSubject(); }; /** * @param {?} store * @return {?} */ ReduxRegistry.registerStore = /** * @param {?} store * @return {?} */ function (store) { ReduxRegistry.reset(); ReduxRegistry._store.next(store); ReduxRegistry._store.complete(); ReduxActionDispatcher.dispatchedActions.subscribe(function (action) { /** @type {?} */ var reduxAction = { type: action.type, payload: action.payload, }; store.dispatch(reduxAction); if (action.onDispatchSuccess) { action.onDispatchSuccess(); } }); }; /** * @param {?} state * @return {?} */ ReduxRegistry.registerState = /** * @param {?} state * @return {?} */ function (state) { ReduxRegistry.getStore().then(function (store) { /** @type {?} */ var stateConfig = ReduxStateDecorator.get(state.constructor); /** @type {?} */ var initialState = state.getInitialState(); Promise .resolve(initialState instanceof Observable ? initialState.toPromise() : initialState) .then(function (initialValue) { store.dispatch({ payload: { initialValue: initialValue, name: stateConfig.name, }, type: ReduxRegistry.ACTION_REGISTER_STATE, }); }); }); }; /** * @return {?} */ ReduxRegistry.getStore = /** * @return {?} */ function () { return new Promise(ReduxRegistry._store.subscribe.bind(ReduxRegistry._store)); }; ReduxRegistry.ACTION_REGISTER_STATE = "@harmowatch/ngx-redux-core/registerState"; ReduxRegistry._store = new AsyncSubject(); ReduxRegistry.decorators = [ { type: Injectable } ]; /** @nocollapse */ ReduxRegistry.ctorParameters = function () { return [ { type: undefined, decorators: [{ type: Inject, args: [ReduxStore,] }] } ]; }; return ReduxRegistry; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @template T */ var ReduxSelector = /** @class */ (function (_super) { __extends(ReduxSelector, _super); function ReduxSelector(zone, selector, stateProvider) { if (selector === void 0) { selector = '/'; } var _this = this; if (!selector.startsWith(ReduxSelector.DELIMITER) && !stateProvider) { throw new Error('You need to provide a state provider, if you use relative selectors'); } _this = _super.call(this, 1) || this; ReduxRegistry.getStore().then(function (store) { /** @type {?} */ var next = function () { zone.run(function () { _this.next(ReduxSelector.getValueByState(store.getState(), selector, stateProvider)); }); }; store.subscribe(function () { return next(); }); next(); // we need to trigger a initial value, otherwise we've to wait until the first state change }); return _this; } /** * @param {?} selector * @param {?=} stateProvider * @return {?} */ ReduxSelector.normalize = /** * @param {?} selector * @param {?=} stateProvider * @return {?} */ function (selector, stateProvider) { if (!selector.startsWith(ReduxSelector.DELIMITER)) { /** @type {?} */ var stateName = ReduxStateDecorator.get(stateProvider).name; return "" + ReduxSelector.DELIMITER + stateName + ReduxSelector.DELIMITER + selector; } return selector; }; /** * @template S * @param {?} state * @param {?} selector * @param {?=} stateProvider * @return {?} */ ReduxSelector.getValueByState = /** * @template S * @param {?} state * @param {?} selector * @param {?=} stateProvider * @return {?} */ function (state, selector, stateProvider) { /** @type {?} */ var value = ReduxSelector.normalize(selector, stateProvider).split(ReduxSelector.DELIMITER) .filter(function (propertyKey) { return propertyKey !== ''; }) .reduce(function (previousValue, propertyKey) { if (!previousValue || !previousValue.hasOwnProperty(propertyKey)) { return null; } return previousValue[propertyKey]; }, /** @type {?} */ (state)); return value; }; ReduxSelector.DELIMITER = '/'; return ReduxSelector; }(ReplaySubject)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @abstract * @template S */ var ReduxStateProvider = /** @class */ (function () { function ReduxStateProvider(stateDefs, zone) { if (stateDefs === void 0) { stateDefs = []; } var _this = this; this.zone = zone; this.selectorCache = {}; var _a = (ReduxStateDecorator.get(this.constructor) || {}).name, name = _a === void 0 ? null : _a; if (!name) { throw new Error('Unable to resolve state name! Make sure you\'ve decorated the provider by "@ReduxState"!'); } this.name = ReduxStateDecorator.get(this.constructor).name; this.stateDef = stateDefs.find(function (def) { return ReduxStateDecorator.get(def.provider).name === name; }); if (!this.stateDef) { throw new Error('Unable to resolve state definition! Make sure you\'ve registered the provider to ReduxModule!'); } this.reducerMethodsByType = (this.stateDef.reducers || []) .map(function (clazz) { return _this.getReducerMethods(new clazz()); }) .reduce(function (all, curr) { return [].concat(curr, all); }, []) // [].concat keeps the order, all.concat(curr) destroys the order // .reduce((all, curr) => [curr, ...all], []) // [].concat keeps the order, all.concat(curr) destroys the order .reduce(function (methodsByType, reducer) { var _a; /** @type {?} */ var type = ReduxActionDispatcher.getType(reducer.type); return __assign({}, methodsByType, (_a = {}, _a[type] = [reducer.method].concat(methodsByType[type] || []), _a)); }, {}); ReduxStateProvider.instancesByName[this.name] = this; } /** * @return {?} */ ReduxStateProvider.prototype.getInitialState = /** * @return {?} */ function () { throw new Error('Method "getInitialState" not implemented.'); }; /** * @template T * @param {?=} selector * @return {?} */ ReduxStateProvider.prototype.select = /** * @template T * @param {?=} selector * @return {?} */ function (selector) { if (selector === void 0) { selector = ''; } /** @type {?} */ var stateType = /** @type {?} */ (this.constructor); selector = ReduxSelector.normalize(selector, stateType); if (!this.selectorCache[selector]) { this.selectorCache[selector] = new ReduxSelector(this.zone, selector, stateType).pipe(distinctUntilChanged()); } return /** @type {?} */ (this.selectorCache[selector]); }; /** * @return {?} */ ReduxStateProvider.prototype.getState = /** * @return {?} */ function () { var _this = this; return ReduxRegistry.getStore().then(function (store) { return ReduxSelector.getValueByState(store.getState(), '/' + _this.name); }); }; /** * @template P * @param {?} state * @param {?} action * @return {?} */ ReduxStateProvider.prototype.reduce = /** * @template P * @param {?} state * @param {?} action * @return {?} */ function (state, action) { /** @type {?} */ var reducerMethods = this.reducerMethodsByType[action.type] || []; return reducerMethods.reduce(function (stateToReduce, method) { return method(stateToReduce, action); }, state); }; /** * @param {?} reducerClassInstance * @return {?} */ ReduxStateProvider.prototype.getReducerMethods = /** * @param {?} reducerClassInstance * @return {?} */ function (reducerClassInstance) { return Object.values(Object.getPrototypeOf(reducerClassInstance)) .map(function (method) { return { method: (/** @type {?} */ (method)).bind(reducerClassInstance), type: ReduxReducerDecorator.get(method), }; }) .filter(function (reducer) { return reducer && reducer.type; }) // convert array of types to multiple method entries .reduce(function (all, curr) { return all.concat([].concat(curr.type).map(function (type) { return (__assign({}, curr, { type: type })); })); }, []); }; ReduxStateProvider.instancesByName = {}; /** @nocollapse */ ReduxStateProvider.ctorParameters = function () { return [ { type: Array, decorators: [{ type: Inject, args: [ReduxStateDefinitionToken,] }] }, { type: NgZone } ]; }; return ReduxStateProvider; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @template S * @param {?} expression * @param {?=} context * @return {?} */ function ReduxSelect(expression, context) { return function (target, propertyKey) { /** @type {?} */ var stateName = ReduxStateDecorator.get(context).name; Object.defineProperty(target, propertyKey, { get: function () { return ReduxStateProvider.instancesByName[stateName].select(expression); } }); }; } /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var ReduxReducerProvider = /** @class */ (function () { function ReduxReducerProvider() { this.stateProviders = {}; } Object.defineProperty(ReduxReducerProvider.prototype, "rootReducer", { get: /** * @return {?} */ function () { return this.reduce.bind(this); }, enumerable: true, configurable: true }); /** * @param {?} provider * @return {?} */ ReduxReducerProvider.prototype.addStateProvider = /** * @param {?} provider * @return {?} */ function (provider) { if (!this.stateProviders[provider.name]) { ReduxRegistry.registerState(provider); this.stateProviders[provider.name] = provider; } else { throw new Error("State \"" + provider.name + "\" is registered twice! Make sure your state name is unique!"); } }; /** * @param {?} rootState * @param {?} action * @return {?} */ ReduxReducerProvider.prototype.reduce = /** * @param {?} rootState * @param {?} action * @return {?} */ function (rootState, action) { var _a; if (action.type === ReduxRegistry.ACTION_REGISTER_STATE) { /** @type {?} */ var regAction = (/** @type {?} */ ((action))); return __assign({}, rootState, (_a = {}, _a[regAction.payload.name] = regAction.payload.initialValue, _a)); } return Object.values(this.stateProviders).reduce(function (stateToReduce, provider) { var _a; return Object.assign({}, stateToReduce, (_a = {}, _a[provider.name] = provider.reduce(stateToReduce[provider.name], action), _a)); }, rootState); }; ReduxReducerProvider.decorators = [ { type: Injectable } ]; return ReduxReducerProvider; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var ReduxSelectPipe = /** @class */ (function () { function ReduxSelectPipe(stateDefs, injector) { if (stateDefs === void 0) { stateDefs = []; } this.provider = /** @type {?} */ (injector.get(stateDefs[0].provider)); } /** * @param {?} selector * @return {?} */ ReduxSelectPipe.prototype.transform = /** * @param {?} selector * @return {?} */ function (selector) { return this.provider.select(selector); }; ReduxSelectPipe.decorators = [ { type: Pipe, args: [{ name: 'reduxSelect' },] } ]; /** @nocollapse */ ReduxSelectPipe.ctorParameters = function () { return [ { type: Array, decorators: [{ type: Inject, args: [ReduxStateDefinitionToken,] }] }, { type: Injector } ]; }; return ReduxSelectPipe; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var ReduxTestingStore = /** @class */ (function () { function ReduxTestingStore() { this.state = new BehaviorSubject(null); } /** * @return {?} */ ReduxTestingStore.factory = /** * @return {?} */ function () { return new ReduxTestingStore(); }; /** * @template S * @param {?} state * @param {?} value * @return {?} */ ReduxTestingStore.prototype.setState = /** * @template S * @param {?} state * @param {?} value * @return {?} */ function (state, value) { var _this = this; var _a; var name = ReduxStateDecorator.get(state).name; /** @type {?} */ var nextState = Object.assign({}, this.state.getValue(), (_a = {}, _a[name] = value, _a)); this.state.next(nextState); return this.state .pipe(takeWhile(function (currentState) { return currentState !== nextState; })) .toPromise().then(function () { return _this.state.getValue(); }); }; /** * @return {?} */ ReduxTestingStore.prototype.getState = /** * @return {?} */ function () { return this.state.getValue(); }; /** * @param {?} listener * @return {?} */ ReduxTestingStore.prototype.subscribe = /** * @param {?} listener * @return {?} */ function (listener) { return this.state.subscribe.call(this.state, listener); }; /** * @return {?} */ ReduxTestingStore.prototype.replaceReducer = /** * @return {?} */ function () { }; /** * @template T * @param {?} action * @return {?} */ ReduxTestingStore.prototype.dispatch = /** * @template T * @param {?} action * @return {?} */ function (action) { return action; }; ReduxTestingStore.decorators = [ { type: Injectable } ]; return ReduxTestingStore; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var TestingStateProvider = /** @class */ (function (_super) { __extends(TestingStateProvider, _super); function TestingStateProvider() { return _super !== null && _super.apply(this, arguments) || this; } TestingStateProvider_1 = TestingStateProvider; /** * @return {?} */ TestingStateProvider.prototype.getInitialState = /** * @return {?} */ function () { return TestingStateProvider_1.INITIAL_STATE; }; var TestingStateProvider_1; TestingStateProvider.NAME = 'testing-7c66b613-20bd-4d35-8611-5181ca4a0b72'; TestingStateProvider.INITIAL_STATE = { todo: { isFetching: false, items: ['Item 1', 'Item 2'], }, }; TestingStateProvider = TestingStateProvider_1 = __decorate([ ReduxStateDecoratorForClass({ name: TestingStateProvider_1.NAME }) ], TestingStateProvider); return TestingStateProvider; }(ReduxStateProvider)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var ReduxMiddlewares = /** @class */ (function (_super) { __extends(ReduxMiddlewares, _super); function ReduxMiddlewares() { return _super.call(this, 'ReduxMiddlewares') || this; } return ReduxMiddlewares; }(InjectionToken)); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ var ReduxModule = /** @class */ (function () { function ReduxModule(injector, reducerProvider, stateDefs) { if (stateDefs === void 0) { stateDefs = []; } injector.get(ReduxRegistry); // just make sure the provider is instantiated if (Array.isArray(stateDefs)) { stateDefs .filter(function (def) { return def && def.provider; }) .map(function (def) { return injector.get(def.provider); }) .forEach(function (provider) { return reducerProvider.addStateProvider(provider); }); } } /** * @template S * @param {?=} config * @return {?} */ ReduxModule.forChild = /** * @template S * @param {?=} config * @return {?} */ function (config) { if (config === void 0) { config = {}; } return { ngModule: ReduxModule, providers: [ { provide: ReduxStateDefinitionToken, useValue: config.state || null, multi: true }, ], }; }; /** * @template S * @param {?=} config * @return {?} */ ReduxModule.forRoot = /** * @template S * @param {?=} config * @return {?} */ function (config) { if (config === void 0) { config = {}; } return { ngModule: ReduxModule, providers: [ ReduxReducerProvider, ReduxRegistry, { provide: ReduxStore, useFactory: config.storeFactory || ReduxModule.defaultStoreFactory, deps: [ReduxReducerProvider, ReduxMiddlewares] }, { provide: ReduxStateDefinitionToken, useValue: config.state || null, multi: true }, { provide: ReduxMiddlewares, useValue: config.middlewareFunctions || [], multi: false }, ], }; }; /** * @param {?} reduxReducerProvider * @param {?} middlewareFunctions * @param {?=} devMode * @return {?} */ ReduxModule.defaultStoreFactory = /** * @param {?} reduxReducerProvider * @param {?} middlewareFunctions * @param {?=} devMode * @return {?} */ function (reduxReducerProvider, middlewareFunctions, devMode) { if (devMode === void 0) { devMode = isDevMode(); } return createStore(reduxReducerProvider.rootReducer, {}, ReduxModule.defaultEnhancerFactory(middlewareFunctions, devMode)); }; /** * @param {?} middlewareFunctions * @param {?} devMode * @return {?} */ ReduxModule.defaultEnhancerFactory = /** * @param {?} middlewareFunctions * @param {?} devMode * @return {?} */ function (middlewareFunctions, devMode) { /** @type {?} */ var composeEnhancers = compose; if (devMode && window['__REDUX_DEVTOOLS_EXTENSION_COMPOSE__']) { composeEnhancers = window['__REDUX_DEVTOOLS_EXTENSION_COMPOSE__']; } return composeEnhancers(applyMiddleware.apply(void 0, __spread(middlewareFunctions))); }; ReduxModule.decorators = [ { type: NgModule, args: [{ declarations: [ ReduxSelectPipe, ], exports: [ ReduxSelectPipe, ], imports: [ CommonModule, ], },] } ]; /** @nocollapse */ ReduxModule.ctorParameters = function () { return [ { type: Injector }, { type: ReduxReducerProvider }, { type: Array, decorators: [{ type: Optional }, { type: Inject, args: [ReduxStateDefinitionToken,] }] } ]; }; return ReduxModule; }()); /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** @type {?} */ var getActionType = ReduxActionDispatcher.getType; /** @type {?} */ var dispatch = ReduxActionDispatcher.dispatch; /** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ export { ReduxModule, getActionType, dispatch, ReduxSelect, ReduxReducerProvider, ReduxSelectPipe, ReduxSelector, ReduxStateDefinitionToken, ReduxStateProvider, ReduxStore, ReduxTestingStore, TestingStateProvider, ReduxRegistry, ReduxMiddlewares as ɵa }; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFybW93YXRjaC1uZ3gtcmVkdXgtY29yZS5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vQGhhcm1vd2F0Y2gvbmd4LXJlZHV4LWNvcmUvdG9rZW5zL3JlZHV4LXN0YXRlLWRlZmluaXRpb24udG9rZW4udHMiLCJuZzovL0BoYXJtb3dhdGNoL25neC1yZWR1eC1jb3JlL3Rva2Vucy9yZWR1eC1zdG9yZS50b2tlbi50cyIsIm5nOi8vQGhhcm1vd2F0Y2gvbmd4LXJlZHV4LWNvcmUvcHJvdmlkZXJzL3JlZHV4LXJlZ2lzdHJ5LnRzIiwibmc6Ly9AaGFybW93YXRjaC9uZ3gtcmVkdXgtY29yZS9yZWR1eC1zZWxlY3Rvci50cyIsIm5nOi8vQGhhcm1vd2F0Y2gvbmd4LXJlZHV4LWNvcmUvcHJvdmlkZXJzL3JlZHV4LXN0YXRlLnByb3ZpZGVyLnRzIiwibmc6Ly9AaGFybW93YXRjaC9uZ3gtcmVkdXgtY29yZS9kZWNvcmF0b3JzL3JlZHV4LXNlbGVjdC5kZWNvcmF0b3IudHMiLCJuZzovL0BoYXJtb3dhdGNoL25neC1yZWR1eC1jb3JlL3Byb3ZpZGVycy9yZWR1eC1yZWR1Y2VyLnByb3ZpZGVyLnRzIiwibmc6Ly9AaGFybW93YXRjaC9uZ3gtcmVkdXgtY29yZS9waXBlcy9yZWR1eC1zZWxlY3QucGlwZS50cyIsIm5nOi8vQGhhcm1vd2F0Y2gvbmd4LXJlZHV4LWNvcmUvdGVzdGluZy9zdG9yZS50cyIsIm5nOi8vQGhhcm1vd2F0Y2gvbmd4LXJlZHV4LWNvcmUvdGVzdGluZy9zdGF0ZS50cyIsIm5nOi8vQGhhcm1vd2F0Y2gvbmd4LXJlZHV4LWNvcmUvdG9rZW5zL3JlZHV4LW1pZGRsZXdhcmVzLnRva2VuLnRzIiwibmc6Ly9AaGFybW93YXRjaC9uZ3gtcmVkdXgtY29yZS9yZWR1eC5tb2R1bGUudHMiLCJuZzovL0BoYXJtb3dhdGNoL25neC1yZWR1eC1jb3JlL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN0b3JlIH0gZnJvbSAncmVkdXgnO1xuaW1wb3J0IHsgSW5qZWN0aW9uVG9rZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuZXhwb3J0IGNsYXNzIFJlZHV4U3RhdGVEZWZpbml0aW9uVG9rZW4gZXh0ZW5kcyBJbmplY3Rpb25Ub2tlbjxTdG9yZTx7fT4+IHtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcignUmVkdXhTdGF0ZURlZmluaXRpb25Ub2tlbicpO1xuICB9XG5cbn1cbiIsImltcG9ydCB7IEluamVjdGlvblRva2VuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTdG9yZSB9IGZyb20gJ3JlZHV4JztcblxuZXhwb3J0IGNsYXNzIFJlZHV4U3RvcmUgZXh0ZW5kcyBJbmplY3Rpb25Ub2tlbjxTdG9yZTx7fT4+IHtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcignUmVkdXhTdG9yZScpO1xuICB9XG5cbn1cbiIsImltcG9ydCB7IFJlZHV4QWN0aW9uRGlzcGF0Y2hlciwgUmVkdXhTdGF0ZURlY29yYXRvciB9IGZyb20gJ0BoYXJtb3dhdGNoL3JlZHV4LWRlY29yYXRvcnMnO1xuXG5pbXBvcnQgeyBTdG9yZSB9IGZyb20gJ3JlZHV4JztcbmltcG9ydCB7IEFzeW5jU3ViamVjdCwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJlZHV4U3RvcmUgfSBmcm9tICcuLi90b2tlbnMvcmVkdXgtc3RvcmUudG9rZW4nO1xuaW1wb3J0IHsgUmVkdXhBY3Rpb25XaXRoUGF5bG9hZCB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVkdXgtYWN0aW9uLXdpdGgtcGF5bG9hZC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVkdXhTdGF0ZVByb3ZpZGVyIH0gZnJvbSAnLi9yZWR1eC1zdGF0ZS5wcm92aWRlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVJlZ2lzdGVyU3RhdGVQYXlsb2FkIHtcbiAgaW5pdGlhbFZhbHVlOiB7fTtcbiAgbmFtZTogc3RyaW5nO1xufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUmVkdXhSZWdpc3RyeSB7XG5cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBBQ1RJT05fUkVHSVNURVJfU1RBVEUgPSBgQGhhcm1vd2F0Y2gvbmd4LXJlZHV4LWNvcmUvcmVnaXN0ZXJTdGF0ZWA7XG5cbiAgcHJpdmF0ZSBzdGF0aWMgX3N0b3JlID0gbmV3IEFzeW5jU3ViamVjdDxTdG9yZTx7fT4+KCk7XG5cbiAgY29uc3RydWN0b3IoQEluamVjdChSZWR1eFN0b3JlKSBzdG9yZTogU3RvcmU8e30+ID0gbnVsbCkge1xuICAgIFJlZHV4UmVnaXN0cnkucmVzZXQoKTtcbiAgICBSZWR1eFJlZ2lzdHJ5LnJlZ2lzdGVyU3RvcmUoc3RvcmUpO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyByZXNldCgpIHtcbiAgICBSZWR1eFJlZ2lzdHJ5Ll9zdG9yZSA9IG5ldyBBc3luY1N1YmplY3Q8U3RvcmU8e30+PigpO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyByZWdpc3RlclN0b3JlKHN0b3JlOiBTdG9yZTx7fT4pIHtcbiAgICBSZWR1eFJlZ2lzdHJ5LnJlc2V0KCk7XG4gICAgUmVkdXhSZWdpc3RyeS5fc3RvcmUubmV4dChzdG9yZSk7XG4gICAgUmVkdXhSZWdpc3RyeS5fc3RvcmUuY29tcGxldGUoKTtcblxuICAgIFJlZHV4QWN0aW9uRGlzcGF0Y2hlci5kaXNwYXRjaGVkQWN0aW9ucy5zdWJzY3JpYmUoYWN0aW9uID0+IHtcblxuICAgICAgY29uc3QgcmVkdXhBY3Rpb246IFJlZHV4QWN0aW9uV2l0aFBheWxvYWQgPSB7XG4gICAgICAgIHR5cGU6IGFjdGlvbi50eXBlLFxuICAgICAgICBwYXlsb2FkOiBhY3Rpb24ucGF5bG9hZCxcbiAgICAgIH07XG5cbiAgICAgIHN0b3JlLmRpc3BhdGNoKHJlZHV4QWN0aW9uKTtcblxuICAgICAgaWYgKGFjdGlvbi5vbkRpc3BhdGNoU3VjY2Vzcykge1xuICAgICAgICBhY3Rpb24ub25EaXNwYXRjaFN1Y2Nlc3MoKTtcbiAgICAgIH1cblxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyByZWdpc3RlclN0YXRlKHN0YXRlOiBSZWR1eFN0YXRlUHJvdmlkZXIpIHtcbiAgICBSZWR1eFJlZ2lzdHJ5LmdldFN0b3JlKCkudGhlbigoc3RvcmUpID0+IHtcblxuICAgICAgY29uc3Qgc3RhdGVDb25maWcgPSBSZWR1eFN0YXRlRGVjb3JhdG9yLmdldChzdGF0ZS5jb25zdHJ1Y3Rvcik7XG4gICAgICBjb25zdCBpbml0aWFsU3RhdGUgPSBzdGF0ZS5nZXRJbml0aWFsU3RhdGUoKTtcblxuICAgICAgUHJvbWlzZVxuICAgICAgICAucmVzb2x2ZShpbml0aWFsU3RhdGUgaW5zdGFuY2VvZiBPYnNlcnZhYmxlID8gaW5pdGlhbFN0YXRlLnRvUHJvbWlzZSgpIDogaW5pdGlhbFN0YXRlKVxuICAgICAgICAudGhlbihpbml0aWFsVmFsdWUgPT4ge1xuICAgICAgICAgIHN0b3JlLmRpc3BhdGNoPFJlZHV4QWN0aW9uV2l0aFBheWxvYWQ8SVJlZ2lzdGVyU3RhdGVQYXlsb2FkPj4oe1xuICAgICAgICAgICAgcGF5bG9hZDoge1xuICAgICAgICAgICAgICBpbml0aWFsVmFsdWUsXG4gICAgICAgICAgICAgIG5hbWU6IHN0YXRlQ29uZmlnLm5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHlwZTogUmVkdXhSZWdpc3RyeS5BQ1RJT05fUkVHSVNURVJfU1RBVEUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGdldFN0b3JlKCk6IFByb21pc2U8U3RvcmU8e30+PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKFJlZHV4UmVnaXN0cnkuX3N0b3JlLnN1YnNjcmliZS5iaW5kKFJlZHV4UmVnaXN0cnkuX3N0b3JlKSk7XG4gIH1cblxufVxuIiwiaW1wb3J0IHsgTmdab25lLCBUeXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBSZWR1eFN0YXRlRGVjb3JhdG9yIH0gZnJvbSAnQGhhcm1vd2F0Y2gvcmVkdXgtZGVjb3JhdG9ycyc7XG5cbmltcG9ydCB7IFJlZHV4UmVnaXN0cnkgfSBmcm9tICcuL3Byb3ZpZGVycy9yZWR1eC1yZWdpc3RyeSc7XG5pbXBvcnQgeyBSZWR1eFJvb3RTdGF0ZSB9IGZyb20gJy4vaW50ZXJmYWNlcy9yZWR1eC1yb290LXN0YXRlLmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZWR1eFN0YXRlUHJvdmlkZXIgfSBmcm9tICcuL3Byb3ZpZGVycy9yZWR1eC1zdGF0ZS5wcm92aWRlcic7XG5cbmV4cG9ydCBjbGFzcyBSZWR1eFNlbGVjdG9yPFQ+IGV4dGVuZHMgUmVwbGF5U3ViamVjdDxUPiB7XG5cbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgREVMSU1JVEVSID0gJy8nO1xuXG4gIGNvbnN0cnVjdG9yKHpvbmU6IE5nWm9uZSxcbiAgICAgICAgICAgICAgc2VsZWN0b3IgPSAnLycsXG4gICAgICAgICAgICAgIHN0YXRlUHJvdmlkZXI/OiBUeXBlPFJlZHV4U3RhdGVQcm92aWRlcj4pIHtcblxuICAgIGlmICghc2VsZWN0b3Iuc3RhcnRzV2l0aChSZWR1eFNlbGVjdG9yLkRFTElNSVRFUikgJiYgIXN0YXRlUHJvdmlkZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignWW91IG5lZWQgdG8gcHJvdmlkZSBhIHN0YXRlIHByb3ZpZGVyLCBpZiB5b3UgdXNlIHJlbGF0aXZlIHNlbGVjdG9ycycpO1xuICAgIH1cblxuICAgIHN1cGVyKDEpO1xuXG4gICAgUmVkdXhSZWdpc3RyeS5nZXRTdG9yZSgpLnRoZW4oc3RvcmUgPT4ge1xuICAgICAgY29uc3QgbmV4dCA9ICgpID0+IHtcbiAgICAgICAgem9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgIHRoaXMubmV4dChSZWR1eFNlbGVjdG9yLmdldFZhbHVlQnlTdGF0ZShzdG9yZS5nZXRTdGF0ZSgpLCBzZWxlY3Rvciwgc3RhdGVQcm92aWRlcikpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG5cbiAgICAgIHN0b3JlLnN1YnNjcmliZSgoKSA9PiBuZXh0KCkpO1xuICAgICAgbmV4dCgpOyAvLyB3ZSBuZWVkIHRvIHRyaWdnZXIgYSBpbml0aWFsIHZhbHVlLCBvdGhlcndpc2Ugd2UndmUgdG8gd2FpdCB1bnRpbCB0aGUgZmlyc3Qgc3RhdGUgY2hhbmdlXG4gICAgfSk7XG5cbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgbm9ybWFsaXplKHNlbGVjdG9yOiBzdHJpbmcsIHN0YXRlUHJvdmlkZXI/OiBUeXBlPFJlZHV4U3RhdGVQcm92aWRlcj4pOiBzdHJpbmcge1xuICAgIGlmICghc2VsZWN0b3Iuc3RhcnRzV2l0aChSZWR1eFNlbGVjdG9yLkRFTElNSVRFUikpIHtcbiAgICAgIGNvbnN0IHN0YXRlTmFtZSA9IFJlZHV4U3RhdGVEZWNvcmF0b3IuZ2V0KHN0YXRlUHJvdmlkZXIpLm5hbWU7XG4gICAgICByZXR1cm4gYCR7UmVkdXhTZWxlY3Rvci5ERUxJTUlURVJ9JHtzdGF0ZU5hbWV9JHtSZWR1eFNlbGVjdG9yLkRFTElNSVRFUn0ke3NlbGVjdG9yfWA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbGVjdG9yO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBnZXRWYWx1ZUJ5U3RhdGU8Uz4oc3RhdGU6IFJlZHV4Um9vdFN0YXRlPFM+LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3Rvcjogc3RyaW5nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZVByb3ZpZGVyPzogVHlwZTxSZWR1eFN0YXRlUHJvdmlkZXI+KTogUyB7XG5cbiAgICAvKiBzYXZlIHRoZSByZXR1cm4gdmFsdWUgaW4gYSBjb25zdGFudCB0byBwcmV2ZW50XG4gICAgICogXCJNZXRhZGF0YSBjb2xsZWN0ZWQgY29udGFpbnMgYW4gZXJyb3IgdGhhdCB3aWxsIGJlIHJlcG9ydGVkIGF0IHJ1bnRpbWU6IExhbWJkYSBub3Qgc3VwcG9ydGVkLlwiXG4gICAgICogZXJyb3JcbiAgICAgKi9cbiAgICBjb25zdCB2YWx1ZTogUyA9IFJlZHV4U2VsZWN0b3Iubm9ybWFsaXplKHNlbGVjdG9yLCBzdGF0ZVByb3ZpZGVyKS5zcGxpdChSZWR1eFNlbGVjdG9yLkRFTElNSVRFUilcbiAgICAgIC5maWx0ZXIocHJvcGVydHlLZXkgPT4gcHJvcGVydHlLZXkgIT09ICcnKVxuICAgICAgLnJlZHVjZSgocHJldmlvdXNWYWx1ZSwgcHJvcGVydHlLZXkpID0+IHtcbiAgICAgICAgaWYgKCFwcmV2aW91c1ZhbHVlIHx8ICFwcmV2aW91c1ZhbHVlLmhhc093blByb3BlcnR5KHByb3BlcnR5S2V5KSkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHByZXZpb3VzVmFsdWVbIHByb3BlcnR5S2V5IF07XG4gICAgICB9LCBzdGF0ZSBhcyB7fSk7XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxufVxuIiwiaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBJbmplY3QsIE5nWm9uZSwgVHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVkdXhBY3Rpb25EaXNwYXRjaGVyLCBSZWR1eFJlZHVjZXJEZWNvcmF0b3IsIFJlZHV4U3RhdGVEZWNvcmF0b3IgfSBmcm9tICdAaGFybW93YXRjaC9yZWR1eC1kZWNvcmF0b3JzJztcblxuaW1wb3J0IHsgUmVkdXhTdGF0ZURlZmluaXRpb24gfSBmcm9tICcuLi9pbnRlcmZhY2VzL3JlZHV4LXN0YXRlLWRlZmluaXRpb24uaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlZHV4QWN0aW9uV2l0aFBheWxvYWQgfSBmcm9tICcuLi9pbnRlcmZhY2VzL3JlZHV4LWFjdGlvbi13aXRoLXBheWxvYWQuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlZHV4U3RhdGVEZWZpbml0aW9uVG9rZW4gfSBmcm9tICcuLi90b2tlbnMvcmVkdXgtc3RhdGUtZGVmaW5pdGlvbi50b2tlbic7XG5cbmltcG9ydCB7IFJlZHV4U2VsZWN0b3IgfSBmcm9tICcuLi9yZWR1eC1zZWxlY3Rvcic7XG5pbXBvcnQgeyBSZWR1eFJlZ2lzdHJ5IH0gZnJvbSAnLi9yZWR1eC1yZWdpc3RyeSc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBSZWR1eFN0YXRlUHJvdmlkZXI8UyA9IHt9PiB7XG5cbiAgcHVibGljIHN0YXRpYyBpbnN0YW5jZXNCeU5hbWU6IHsgW3N0YXRlTmFtZTogc3RyaW5nXTogUmVkdXhTdGF0ZVByb3ZpZGVyIH0gPSB7fTtcblxuICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgc3RhdGVEZWY6IFJlZHV4U3RhdGVEZWZpbml0aW9uO1xuXG4gIHByb3RlY3RlZCBzZWxlY3RvckNhY2hlOiB7IFtzZWxlY3Rvcjogc3RyaW5nXTogT2JzZXJ2YWJsZTx7fT4gfSA9IHt9O1xuICBwcm90ZWN0ZWQgcmVkdWNlck1ldGhvZHNCeVR5cGU6IHsgW2FjdGlvblR5cGU6IHN0cmluZ106IEZ1bmN0aW9uW10gfTtcblxuICBjb25zdHJ1Y3RvcihASW5qZWN0KFJlZHV4U3RhdGVEZWZpbml0aW9uVG9rZW4pIHN0YXRlRGVmczogUmVkdXhTdGF0ZURlZmluaXRpb25bXSA9IFtdLFxuICAgICAgICAgICAgICBwcml2YXRlIHpvbmU6IE5nWm9uZSkge1xuXG4gICAgY29uc3Qge25hbWUgPSBudWxsfSA9IFJlZHV4U3RhdGVEZWNvcmF0b3IuZ2V0KHRoaXMuY29uc3RydWN0b3IpIHx8IHt9O1xuXG4gICAgaWYgKCFuYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdVbmFibGUgdG8gcmVzb2x2ZSBzdGF0ZSBuYW1lISBNYWtlIHN1cmUgeW91XFwndmUgZGVjb3JhdGVkIHRoZSBwcm92aWRlciBieSBcIkBSZWR1eFN0YXRlXCIhJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLm5hbWUgPSBSZWR1eFN0YXRlRGVjb3JhdG9yLmdldCh0aGlzLmNvbnN0cnVjdG9yKS5uYW1lO1xuICAgIHRoaXMuc3RhdGVEZWYgPSBzdGF0ZURlZnMuZmluZChkZWYgPT4gUmVkdXhTdGF0ZURlY29yYXRvci5nZXQoZGVmLnByb3ZpZGVyKS5uYW1lID09PSBuYW1lKTtcblxuICAgIGlmICghdGhpcy5zdGF0ZURlZikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnVW5hYmxlIHRvIHJlc29sdmUgc3RhdGUgZGVmaW5pdGlvbiEgTWFrZSBzdXJlIHlvdVxcJ3ZlIHJlZ2lzdGVyZWQgdGhlIHByb3ZpZGVyIHRvIFJlZHV4TW9kdWxlISdcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5yZWR1Y2VyTWV0aG9kc0J5VHlwZSA9ICh0aGlzLnN0YXRlRGVmLnJlZHVjZXJzIHx8IFtdKVxuICAgICAgLm1hcChjbGF6eiA9PiB0aGlzLmdldFJlZHVjZXJNZXRob2RzKG5ldyBjbGF6eigpKSlcbiAgICAgIC5yZWR1Y2UoKGFsbCwgY3VycikgPT4gW10uY29uY2F0KGN1cnIsIGFsbCksIFtdKSAvLyBbXS5jb25jYXQga2VlcHMgdGhlIG9yZGVyLCBhbGwuY29uY2F0KGN1cnIpIGRlc3Ryb3lzIHRoZSBvcmRlclxuICAgICAgLy8gLnJlZHVjZSgoYWxsLCBjdXJyKSA9PiBbY3VyciwgLi4uYWxsXSwgW10pIC8vIFtdLmNvbmNhdCBrZWVwcyB0aGUgb3JkZXIsIGFsbC5jb25jYXQoY3VycikgZGVzdHJveXMgdGhlIG9yZGVyXG4gICAgICAucmVkdWNlKChtZXRob2RzQnlUeXBlLCByZWR1Y2VyKSA9PiB7XG4gICAgICAgIGNvbnN0IHR5cGUgPSBSZWR1eEFjdGlvbkRpc3BhdGNoZXIuZ2V0VHlwZShyZWR1Y2VyLnR5cGUpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4ubWV0aG9kc0J5VHlwZSxcbiAgICAgICAgICBbIHR5cGUgXTogWyByZWR1Y2VyLm1ldGhvZCBdLmNvbmNhdChtZXRob2RzQnlUeXBlWyB0eXBlIF0gfHwgW10pXG4gICAgICAgIH07XG4gICAgICB9LCB7fSk7XG5cbiAgICBSZWR1eFN0YXRlUHJvdmlkZXIuaW5zdGFuY2VzQnlOYW1lWyB0aGlzLm5hbWUgXSA9IHRoaXM7XG4gIH1cblxuICBnZXRJbml0aWFsU3RhdGUoKTogUyB8IFByb21pc2U8Uz4gfCBPYnNlcnZhYmxlPFM+IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBcImdldEluaXRpYWxTdGF0ZVwiIG5vdCBpbXBsZW1lbnRlZC4nKTtcbiAgfVxuXG4gIHNlbGVjdDxUPihzZWxlY3RvciA9ICcnKTogT2JzZXJ2YWJsZTxUPiB7XG5cbiAgICBjb25zdCBzdGF0ZVR5cGUgPSB0aGlzLmNvbnN0cnVjdG9yIGFzIFR5cGU8UmVkdXhTdGF0ZVByb3ZpZGVyPFM+PjtcbiAgICBzZWxlY3RvciA9IFJlZHV4U2VsZWN0b3Iubm9ybWFsaXplKHNlbGVjdG9yLCBzdGF0ZVR5cGUpO1xuXG4gICAgaWYgKCF0aGlzLnNlbGVjdG9yQ2FjaGVbIHNlbGVjdG9yIF0pIHtcbiAgICAgIHRoaXMuc2VsZWN0b3JDYWNoZVsgc2VsZWN0b3IgXSA9IG5ldyBSZWR1eFNlbGVjdG9yPFQ+KHRoaXMuem9uZSwgc2VsZWN0b3IsIHN0YXRlVHlwZSkucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zZWxlY3RvckNhY2hlWyBzZWxlY3RvciBdIGFzIFJlZHV4U2VsZWN0b3I8VD47XG4gIH1cblxuICBnZXRTdGF0ZSgpOiBQcm9taXNlPFM+IHtcbiAgICByZXR1cm4gUmVkdXhSZWdpc3RyeS5nZXRTdG9yZSgpLnRoZW4oc3RvcmUgPT4ge1xuICAgICAgcmV0dXJuIFJlZHV4U2VsZWN0b3IuZ2V0VmFsdWVCeVN0YXRlPFM+KHN0b3JlLmdldFN0YXRlKCksICcvJyArIHRoaXMubmFtZSk7XG4gICAgfSk7XG4gIH1cblxuICByZWR1Y2U8UD4oc3RhdGU6IFMsIGFjdGlvbjogUmVkdXhBY3Rpb25XaXRoUGF5bG9hZDxQPik6IFMge1xuICAgIGNvbnN0IHJlZHVjZXJNZXRob2RzID0gdGhpcy5yZWR1Y2VyTWV0aG9kc0J5VHlwZVsgYWN0aW9uLnR5cGUgXSB8fCBbXTtcbiAgICByZXR1cm4gcmVkdWNlck1ldGhvZHMucmVkdWNlKChzdGF0ZVRvUmVkdWNlLCBtZXRob2QpID0+IG1ldGhvZChzdGF0ZVRvUmVkdWNlLCBhY3Rpb24pLCBzdGF0ZSk7XG4gIH1cblxuICBwcml2YXRlIGdldFJlZHVjZXJNZXRob2RzKHJlZHVjZXJDbGFzc0luc3RhbmNlOiBhbnkpIHtcbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyhPYmplY3QuZ2V0UHJvdG90eXBlT2YocmVkdWNlckNsYXNzSW5zdGFuY2UpKVxuICAgICAgLm1hcChtZXRob2QgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG1ldGhvZDogKG1ldGhvZCBhcyBGdW5jdGlvbikuYmluZChyZWR1Y2VyQ2xhc3NJbnN0YW5jZSksXG4gICAgICAgICAgdHlwZTogUmVkdXhSZWR1Y2VyRGVjb3JhdG9yLmdldChtZXRob2QpLFxuICAgICAgICB9O1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIocmVkdWNlciA9PiByZWR1Y2VyICYmIHJlZHVjZXIudHlwZSlcbiAgICAgIC8vIGNvbnZlcnQgYXJyYXkgb2YgdHlwZXMgdG8gbXVsdGlwbGUgbWV0aG9kIGVudHJpZXNcbiAgICAgIC5yZWR1Y2UoKGFsbCwgY3VycikgPT4gYWxsLmNvbmNhdChbXS5jb25jYXQoY3Vyci50eXBlKS5tYXAodHlwZSA9PiAoey4uLmN1cnIsIHR5cGV9KSkpLCBbXSk7XG4gIH1cblxufVxuIiwiaW1wb3J0IHsgVHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVkdXhTdGF0ZURlY29yYXRvciB9IGZyb20gJ0BoYXJtb3dhdGNoL3JlZHV4LWRlY29yYXRvcnMnO1xuXG5pbXBvcnQgeyBSZWR1eFN0YXRlUHJvdmlkZXIgfSBmcm9tICcuLi9wcm92aWRlcnMvcmVkdXgtc3RhdGUucHJvdmlkZXInO1xuXG5leHBvcnQgZnVuY3Rpb24gUmVkdXhTZWxlY3Q8UyA9IHt9PihleHByZXNzaW9uOiBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0PzogVHlwZTxSZWR1eFN0YXRlUHJvdmlkZXI+KTogUHJvcGVydHlEZWNvcmF0b3Ige1xuXG4gIHJldHVybiAodGFyZ2V0OiB7fSwgcHJvcGVydHlLZXk6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IHN0YXRlTmFtZSA9IFJlZHV4U3RhdGVEZWNvcmF0b3IuZ2V0KGNvbnRleHQpLm5hbWU7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwge1xuICAgICAgZ2V0OiAoKSA9PiBSZWR1eFN0YXRlUHJvdmlkZXIuaW5zdGFuY2VzQnlOYW1lWyBzdGF0ZU5hbWUgXS5zZWxlY3QoZXhwcmVzc2lvbilcbiAgICB9KTtcblxuICB9O1xufVxuIiwiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBSZWR1Y2VyIH0gZnJvbSAncmVkdXgnO1xuaW1wb3J0IHsgUmVkdXhTdGF0ZVByb3ZpZGVyIH0gZnJvbSAnLi9yZWR1eC1zdGF0ZS5wcm92aWRlcic7XG5pbXBvcnQgeyBJUmVnaXN0ZXJTdGF0ZVBheWxvYWQsIFJlZHV4UmVnaXN0cnkgfSBmcm9tICcuL3JlZHV4LXJlZ2lzdHJ5JztcbmltcG9ydCB7IFJlZHV4Um9vdFN0YXRlIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZWR1eC1yb290LXN0YXRlLmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZWR1eEFjdGlvbldpdGhQYXlsb2FkIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZWR1eC1hY3Rpb24td2l0aC1wYXlsb2FkLmludGVyZmFjZSc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBSZWR1eFJlZHVjZXJQcm92aWRlciB7XG5cbiAgcHJpdmF0ZSBzdGF0ZVByb3ZpZGVyczoge1xuICAgIFtuYW1lOiBzdHJpbmddOiBSZWR1eFN0YXRlUHJvdmlkZXIsXG4gIH0gPSB7fTtcblxuICBwdWJsaWMgZ2V0IHJvb3RSZWR1Y2VyKCk6IFJlZHVjZXI8UmVkdXhSb290U3RhdGU+IHtcbiAgICByZXR1cm4gdGhpcy5yZWR1Y2UuYmluZCh0aGlzKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRTdGF0ZVByb3ZpZGVyKHByb3ZpZGVyOiBSZWR1eFN0YXRlUHJvdmlkZXIpIHtcbiAgICBpZiAoIXRoaXMuc3RhdGVQcm92aWRlcnNbIHByb3ZpZGVyLm5hbWUgXSkge1xuICAgICAgUmVkdXhSZWdpc3RyeS5yZWdpc3RlclN0YXRlKHByb3ZpZGVyKTtcbiAgICAgIHRoaXMuc3RhdGVQcm92aWRlcnNbIHByb3ZpZGVyLm5hbWUgXSA9IHByb3ZpZGVyO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFN0YXRlIFwiJHtwcm92aWRlci5uYW1lfVwiIGlzIHJlZ2lzdGVyZWQgdHdpY2UhIE1ha2Ugc3VyZSB5b3VyIHN0YXRlIG5hbWUgaXMgdW5pcXVlIWApO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyByZWR1Y2Uocm9vdFN0YXRlOiBSZWR1eFJvb3RTdGF0ZSwgYWN0aW9uOiBSZWR1eEFjdGlvbldpdGhQYXlsb2FkPGFueT4pOiBSZWR1eFJvb3RTdGF0ZSB7XG5cbiAgICBpZiAoYWN0aW9uLnR5cGUgPT09IFJlZHV4UmVnaXN0cnkuQUNUSU9OX1JFR0lTVEVSX1NUQVRFKSB7XG4gICAgICBjb25zdCByZWdBY3Rpb24gPSAoYWN0aW9uIGFzIHt9IGFzIFJlZHV4QWN0aW9uV2l0aFBheWxvYWQ8SVJlZ2lzdGVyU3RhdGVQYXlsb2FkPik7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnJvb3RTdGF0ZSxcbiAgICAgICAgWyByZWdBY3Rpb24ucGF5bG9hZC5uYW1lIF06IHJlZ0FjdGlvbi5wYXlsb2FkLmluaXRpYWxWYWx1ZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcy5zdGF0ZVByb3ZpZGVycykucmVkdWNlKChzdGF0ZVRvUmVkdWNlLCBwcm92aWRlcikgPT4ge1xuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlVG9SZWR1Y2UsIHtcbiAgICAgICAgWyBwcm92aWRlci5uYW1lIF06IHByb3ZpZGVyLnJlZHVjZShzdGF0ZVRvUmVkdWNlWyBwcm92aWRlci5uYW1lIF0sIGFjdGlvbiksXG4gICAgICB9KTtcbiAgICB9LCByb290U3RhdGUpO1xuICB9XG5cbn1cbiIsImltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEluamVjdCwgSW5qZWN0b3IsIFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgUmVkdXhTdGF0ZVByb3ZpZGVyIH0gZnJvbSAnLi4vcHJvdmlkZXJzL3JlZHV4LXN0YXRlLnByb3ZpZGVyJztcbmltcG9ydCB7IFJlZHV4U3RhdGVEZWZpbml0aW9uVG9rZW4gfSBmcm9tICcuLi90b2tlbnMvcmVkdXgtc3RhdGUtZGVmaW5pdGlvbi50b2tlbic7XG5pbXBvcnQgeyBSZWR1eFN0YXRlRGVmaW5pdGlvbiB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVkdXgtc3RhdGUtZGVmaW5pdGlvbi5pbnRlcmZhY2UnO1xuXG5AUGlwZSh7bmFtZTogJ3JlZHV4U2VsZWN0J30pXG5leHBvcnQgY2xhc3MgUmVkdXhTZWxlY3RQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cbiAgcHJpdmF0ZSBwcm92aWRlcjogUmVkdXhTdGF0ZVByb3ZpZGVyO1xuXG4gIGNvbnN0cnVjdG9yKEBJbmplY3QoUmVkdXhTdGF0ZURlZmluaXRpb25Ub2tlbikgc3RhdGVEZWZzOiBSZWR1eFN0YXRlRGVmaW5pdGlvbltdID0gW10sIGluamVjdG9yOiBJbmplY3Rvcikge1xuICAgIHRoaXMucHJvdmlkZXIgPSBpbmplY3Rvci5nZXQoc3RhdGVEZWZzWyAwIF0ucHJvdmlkZXIpIGFzIFJlZHV4U3RhdGVQcm92aWRlcjtcbiAgfVxuXG4gIHRyYW5zZm9ybShzZWxlY3Rvcjogc3RyaW5nKTogT2JzZXJ2YWJsZTx7fT4ge1xuICAgIHJldHVybiB0aGlzLnByb3ZpZGVyLnNlbGVjdChzZWxlY3Rvcik7XG4gIH1cblxufVxuIiwiaW1wb3J0IHsgQWN0aW9uLCBTdG9yZSwgVW5zdWJzY3JpYmUgfSBmcm9tICdyZWR1eCc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VXaGlsZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEluamVjdGFibGUsIFR5cGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFJlZHV4Um9vdFN0YXRlIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZWR1eC1yb290LXN0YXRlLmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZWR1eFN0YXRlRGVjb3JhdG9yIH0gZnJvbSAnQGhhcm1vd2F0Y2gvcmVkdXgtZGVjb3JhdG9ycyc7XG5pbXBvcnQgeyBSZWR1eFN0YXRlUHJvdmlkZXIgfSBmcm9tICcuLi9wcm92aWRlcnMvcmVkdXgtc3RhdGUucHJvdmlkZXInO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUmVkdXhUZXN0aW5nU3RvcmUgaW1wbGVtZW50cyBTdG9yZTx7fT4ge1xuXG4gIHByaXZhdGUgc3RhdGUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KG51bGwpO1xuXG4gIHB1YmxpYyBzdGF0aWMgZmFjdG9yeSgpOiBSZWR1eFRlc3RpbmdTdG9yZSB7XG4gICAgcmV0dXJuIG5ldyBSZWR1eFRlc3RpbmdTdG9yZSgpO1xuICB9XG5cbiAgcHVibGljIHNldFN0YXRlPFM+KHN0YXRlOiBUeXBlPFJlZHV4U3RhdGVQcm92aWRlcj4sIHZhbHVlOiBTKTogUHJvbWlzZTxSZWR1eFJvb3RTdGF0ZT4ge1xuICAgIGNvbnN0IHtuYW1lfSA9IFJlZHV4U3RhdGVEZWNvcmF0b3IuZ2V0KHN0YXRlKTtcblxuICAgIGNvbnN0IG5leHRTdGF0ZSA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMuc3RhdGUuZ2V0VmFsdWUoKSwge1xuICAgICAgWyBuYW1lIF06IHZhbHVlLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zdGF0ZS5uZXh0KG5leHRTdGF0ZSk7XG5cbiAgICByZXR1cm4gdGhpcy5zdGF0ZVxuICAgICAgLnBpcGUodGFrZVdoaWxlKGN1cnJlbnRTdGF0ZSA9PiBjdXJyZW50U3RhdGUgIT09IG5leHRTdGF0ZSkpXG4gICAgICAudG9Qcm9taXNlKCkudGhlbigoKSA9PiB0aGlzLnN0YXRlLmdldFZhbHVlKCkpO1xuICB9XG5cbiAgcHVibGljIGdldFN0YXRlKCk6IHt9IHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5nZXRWYWx1ZSgpO1xuICB9XG5cbiAgcHVibGljIHN1YnNjcmliZShsaXN0ZW5lcjogKCkgPT4gdm9pZCk6IFVuc3Vic2NyaWJlIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5zdWJzY3JpYmUuY2FsbCh0aGlzLnN0YXRlLCBsaXN0ZW5lcik7XG4gIH1cblxuICBwdWJsaWMgcmVwbGFjZVJlZHVjZXIoKSB7XG4gIH1cblxuICBwdWJsaWMgZGlzcGF0Y2g8VCBleHRlbmRzIEFjdGlvbj4oYWN0aW9uOiBUKTogVCB7XG4gICAgcmV0dXJuIGFjdGlvbjtcbiAgfVxuXG59XG4iLCJpbXBvcnQgeyBSZWR1eFN0YXRlIH0gZnJvbSAnLi4vZGVjb3JhdG9ycy9pbmRleCc7XG5pbXBvcnQgeyBSZWR1eFN0YXRlUHJvdmlkZXIgfSBmcm9tICcuLi9wcm92aWRlcnMvcmVkdXgtc3RhdGUucHJvdmlkZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRlc3RpbmdTdGF0ZSB7XG4gIHRvZG86IHtcbiAgICBpc0ZldGNoaW5nOiBib29sZWFuO1xuICAgIGl0ZW1zOiBzdHJpbmdbXTtcbiAgfTtcbn1cblxuQFJlZHV4U3RhdGUoe25hbWU6IFRlc3RpbmdTdGF0ZVByb3ZpZGVyLk5BTUV9KVxuZXhwb3J0IGNsYXNzIFRlc3RpbmdTdGF0ZVByb3ZpZGVyIGV4dGVuZHMgUmVkdXhTdGF0ZVByb3ZpZGVyPFRlc3RpbmdTdGF0ZT4ge1xuXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgTkFNRSA9ICd0ZXN0aW5nLTdjNjZiNjEzLTIwYmQtNGQzNS04NjExLTUxODFjYTRhMGI3Mic7XG5cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBJTklUSUFMX1NUQVRFOiBUZXN0aW5nU3RhdGUgPSB7XG4gICAgdG9kbzoge1xuICAgICAgaXNGZXRjaGluZzogZmFsc2UsXG4gICAgICBpdGVtczogWyAnSXRlbSAxJywgJ0l0ZW0gMicgXSxcbiAgICB9LFxuICB9O1xuXG4gIGdldEluaXRpYWxTdGF0ZSgpOiBUZXN0aW5nU3RhdGUge1xuICAgIHJldHVybiBUZXN0aW5nU3RhdGVQcm92aWRlci5JTklUSUFMX1NUQVRFO1xuICB9XG5cbn1cbiIsImltcG9ydCB7IEluamVjdGlvblRva2VuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmV4cG9ydCBjbGFzcyBSZWR1eE1pZGRsZXdhcmVzIGV4dGVuZHMgSW5qZWN0aW9uVG9rZW48RnVuY3Rpb25bXT4ge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCdSZWR1eE1pZGRsZXdhcmVzJyk7XG4gIH1cblxufVxuIiwiaW1wb3J0IHsgYXBwbHlNaWRkbGV3YXJlLCBjb21wb3NlLCBjcmVhdGVTdG9yZSwgTWlkZGxld2FyZSwgU3RvcmUsIFN0b3JlRW5oYW5jZXIgfSBmcm9tICdyZWR1eCc7XG5cbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBJbmplY3QsIEluamVjdG9yLCBpc0Rldk1vZGUsIE1vZHVsZVdpdGhQcm92aWRlcnMsIE5nTW9kdWxlLCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUmVkdXhTZWxlY3RQaXBlIH0gZnJvbSAnLi9waXBlcy9yZWR1eC1zZWxlY3QucGlwZSc7XG5pbXBvcnQgeyBSZWR1eFJlZHVjZXJQcm92aWRlciB9IGZyb20gJy4vcHJvdmlkZXJzL3JlZHV4LXJlZHVjZXIucHJvdmlkZXInO1xuaW1wb3J0IHsgUmVkdXhTdGF0ZURlZmluaXRpb25Ub2tlbiB9IGZyb20gJy4vdG9rZW5zL3JlZHV4LXN0YXRlLWRlZmluaXRpb24udG9rZW4nO1xuaW1wb3J0IHsgUmVkdXhTdGF0ZURlZmluaXRpb24gfSBmcm9tICcuL2ludGVyZmFjZXMvcmVkdXgtc3RhdGUtZGVmaW5pdGlvbi5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVkdXhSZWdpc3RyeSB9IGZyb20gJy4vcHJvdmlkZXJzL3JlZHV4LXJlZ2lzdHJ5JztcbmltcG9ydCB7IFJlZHV4Q2hpbGRNb2R1bGVDb25maWcgfSBmcm9tICcuL2ludGVyZmFjZXMvcmVkdXgtY2hpbGQtbW9kdWxlLWNvbmZpZy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVkdXhSb290TW9kdWxlQ29uZmlnIH0gZnJvbSAnLi9pbnRlcmZhY2VzL3JlZHV4LXJvb3QtbW9kdWxlLWNvbmZpZy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVkdXhTdG9yZSB9IGZyb20gJy4vdG9rZW5zL3JlZHV4LXN0b3JlLnRva2VuJztcbmltcG9ydCB7IFJlZHV4TWlkZGxld2FyZXMgfSBmcm9tICcuL3Rva2Vucy9yZWR1eC1taWRkbGV3YXJlcy50b2tlbic7XG5cbkBOZ01vZHVsZSh7XG4gIGRlY2xhcmF0aW9uczogW1xuICAgIFJlZHV4U2VsZWN0UGlwZSxcbiAgXSxcbiAgZXhwb3J0czogW1xuICAgIFJlZHV4U2VsZWN0UGlwZSxcbiAgXSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgUmVkdXhNb2R1bGUge1xuXG4gIGNvbnN0cnVjdG9yKGluamVjdG9yOiBJbmplY3RvcixcbiAgICAgICAgICAgICAgcmVkdWNlclByb3ZpZGVyOiBSZWR1eFJlZHVjZXJQcm92aWRlcixcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChSZWR1eFN0YXRlRGVmaW5pdGlvblRva2VuKSBzdGF0ZURlZnM6IFJlZHV4U3RhdGVEZWZpbml0aW9uW10gPSBbXSkge1xuXG4gICAgaW5qZWN0b3IuZ2V0KFJlZHV4UmVnaXN0cnkpOyAvLyBqdXN0IG1ha2Ugc3VyZSB0aGUgcHJvdmlkZXIgaXMgaW5zdGFudGlhdGVkXG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShzdGF0ZURlZnMpKSB7XG4gICAgICBzdGF0ZURlZnNcbiAgICAgICAgLmZpbHRlcihkZWYgPT4gZGVmICYmIGRlZi5wcm92aWRlcilcbiAgICAgICAgLm1hcChkZWYgPT4gaW5qZWN0b3IuZ2V0KGRlZi5wcm92aWRlcikpXG4gICAgICAgIC5mb3JFYWNoKHByb3ZpZGVyID0+IHJlZHVjZXJQcm92aWRlci5hZGRTdGF0ZVByb3ZpZGVyKHByb3ZpZGVyKSk7XG4gICAgfVxuXG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGZvckNoaWxkPFMgPSB7fT4oY29uZmlnOiBSZWR1eENoaWxkTW9kdWxlQ29uZmlnPFM+ID0ge30pOiBNb2R1bGVXaXRoUHJvdmlkZXJzIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmdNb2R1bGU6IFJlZHV4TW9kdWxlLFxuICAgICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIHtwcm92aWRlOiBSZWR1eFN0YXRlRGVmaW5pdGlvblRva2VuLCB1c2VWYWx1ZTogY29uZmlnLnN0YXRlIHx8IG51bGwsIG11bHRpOiB0cnVlfSxcbiAgICAgIF0sXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgZm9yUm9vdDxTID0ge30+KGNvbmZpZzogUmVkdXhSb290TW9kdWxlQ29uZmlnPFM+ID0ge30pOiBNb2R1bGVXaXRoUHJvdmlkZXJzIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmdNb2R1bGU6IFJlZHV4TW9kdWxlLFxuICAgICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIFJlZHV4UmVkdWNlclByb3ZpZGVyLFxuICAgICAgICBSZWR1eFJlZ2lzdHJ5LFxuICAgICAgICB7XG4gICAgICAgICAgcHJvdmlkZTogUmVkdXhTdG9yZSxcbiAgICAgICAgICB1c2VGYWN0b3J5OiBjb25maWcuc3RvcmVGYWN0b3J5IHx8IFJlZHV4TW9kdWxlLmRlZmF1bHRTdG9yZUZhY3RvcnksXG4gICAgICAgICAgZGVwczogW1JlZHV4UmVkdWNlclByb3ZpZGVyLCBSZWR1eE1pZGRsZXdhcmVzXVxuICAgICAgICB9LFxuICAgICAgICB7cHJvdmlkZTogUmVkdXhTdGF0ZURlZmluaXRpb25Ub2tlbiwgdXNlVmFsdWU6IGNvbmZpZy5zdGF0ZSB8fCBudWxsLCBtdWx0aTogdHJ1ZX0sXG4gICAgICAgIHtwcm92aWRlOiBSZWR1eE1pZGRsZXdhcmVzLCB1c2VWYWx1ZTogY29uZmlnLm1pZGRsZXdhcmVGdW5jdGlvbnMgfHwgW10sIG11bHRpOiBmYWxzZX0sXG4gICAgICBdLFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGRlZmF1bHRTdG9yZUZhY3RvcnkocmVkdXhSZWR1Y2VyUHJvdmlkZXI6IFJlZHV4UmVkdWNlclByb3ZpZGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWlkZGxld2FyZUZ1bmN0aW9uczogTWlkZGxld2FyZVtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2TW9kZSA9IGlzRGV2TW9kZSgpKTogU3RvcmU8e30+IHtcblxuICAgIHJldHVybiBjcmVhdGVTdG9yZShcbiAgICAgIHJlZHV4UmVkdWNlclByb3ZpZGVyLnJvb3RSZWR1Y2VyLFxuICAgICAge30sXG4gICAgICBSZWR1eE1vZHVsZS5kZWZhdWx0RW5oYW5jZXJGYWN0b3J5KG1pZGRsZXdhcmVGdW5jdGlvbnMsIGRldk1vZGUpLFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGRlZmF1bHRFbmhhbmNlckZhY3RvcnkobWlkZGxld2FyZUZ1bmN0aW9uczogTWlkZGxld2FyZVtdLCBkZXZNb2RlOiBib29sZWFuKTogU3RvcmVFbmhhbmNlcjx7fT4ge1xuXG4gICAgbGV0IGNvbXBvc2VFbmhhbmNlcnMgPSBjb21wb3NlO1xuXG4gICAgaWYgKGRldk1vZGUgJiYgd2luZG93WydfX1JFRFVYX0RFVlRPT0xTX0VYVEVOU0lPTl9DT01QT1NFX18nXSkge1xuICAgICAgY29tcG9zZUVuaGFuY2VycyA9IHdpbmRvd1snX19SRURVWF9ERVZUT09MU19FWFRFTlNJT05fQ09NUE9TRV9fJ107XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbXBvc2VFbmhhbmNlcnMoYXBwbHlNaWRkbGV3YXJlKC4uLm1pZGRsZXdhcmVGdW5jdGlvbnMpKTtcbiAgfVxuXG59XG4iLCJleHBvcnQgKiBmcm9tICcuL2ludGVyZmFjZXMvcmVkdXgtYWN0aW9uLXdpdGgtcGF5bG9hZC5pbnRlcmZhY2UnO1xuXG5leHBvcnQgKiBmcm9tICcuL2RlY29yYXRvcnMnO1xuZXhwb3J0ICogZnJvbSAnLi9pbnRlcmZhY2VzL3JlZHV4LWNoaWxkLW1vZHVsZS1jb25maWcuaW50ZXJmYWNlJztcbmV4cG9ydCAqIGZyb20gJy4vaW50ZXJmYWNlcy9yZWR1eC1yb290LW1vZHVsZS1jb25maWcuaW50ZXJmYWNlJztcbmV4cG9ydCAqIGZyb20gJy4vaW50ZXJmYWNlcy9yZWR1eC1yb290LXN0YXRlLmludGVyZmFjZSc7XG5leHBvcnQgKiBmcm9tICcuL3Byb3ZpZGVycy9yZWR1eC1yZWR1Y2VyLnByb3ZpZGVyJztcbmV4cG9ydCAqIGZyb20gJy4vZGVjb3JhdG9ycy9yZWR1eC1zZWxlY3QuZGVjb3JhdG9yJztcbmV4cG9ydCAqIGZyb20gJy4vcGlwZXMvcmVkdXgtc2VsZWN0LnBpcGUnO1xuZXhwb3J0ICogZnJvbSAnLi9yZWR1eC1zZWxlY3Rvcic7XG5leHBvcnQgKiBmcm9tICcuL3Rva2Vucy9yZWR1eC1zdGF0ZS1kZWZpbml0aW9uLnRva2VuJztcbmV4cG9ydCAqIGZyb20gJy4vaW50ZXJmYWNlcy9yZWR1eC1zdGF0ZS1kZWZpbml0aW9uLmludGVyZmFjZSc7XG5leHBvcnQgKiBmcm9tICcuL3Byb3ZpZGVycy9yZWR1eC1zdGF0ZS5wcm92aWRlcic7XG5leHBvcnQgKiBmcm9tICcuL3Rva2Vucy9yZWR1eC1zdG9yZS50b2tlbic7XG5leHBvcnQgKiBmcm9tICcuL3Rlc3Rpbmcvc3RvcmUnO1xuZXhwb3J0ICogZnJvbSAnLi90ZXN0aW5nL3N0YXRlJztcbmV4cG9ydCAqIGZyb20gJy4vcHJvdmlkZXJzL3JlZHV4LXJlZ2lzdHJ5JztcblxuZXhwb3J0IHsgUmVkdXhNb2R1bGUgfSBmcm9tICcuL3JlZHV4Lm1vZHVsZSc7XG5pbXBvcnQgeyBSZWR1eEFjdGlvbkRpc3BhdGNoZXIgfSBmcm9tICdAaGFybW93YXRjaC9yZWR1eC1kZWNvcmF0b3JzJztcblxuZXhwb3J0IGNvbnN0IGdldEFjdGlvblR5cGUgPSBSZWR1eEFjdGlvbkRpc3BhdGNoZXIuZ2V0VHlwZTtcbmV4cG9ydCBjb25zdCBkaXNwYXRjaCA9IFJlZHV4QWN0aW9uRGlzcGF0Y2hlci5kaXNwYXRjaDtcbiJdLCJuYW1lcyI6WyJ0c2xpYl8xLl9fZXh0ZW5kcyIsIlJlZHV4U3RhdGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7SUFHQTtJQUErQ0EsNkNBQXlCO0lBRXRFO2VBQ0Usa0JBQU0sMkJBQTJCLENBQUM7S0FDbkM7b0NBUEg7RUFHK0MsY0FBYyxFQU01RDs7Ozs7O0lDTkQ7SUFBZ0NBLDhCQUF5QjtJQUV2RDtlQUNFLGtCQUFNLFlBQVksQ0FBQztLQUNwQjtxQkFQSDtFQUdnQyxjQUFjLEVBTTdDOzs7Ozs7QUNURDtJQXNCRSx1QkFBZ0MsS0FBdUI7UUFBM0Msc0JBQUEsRUFBQSxZQUEyQztRQUNyRCxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdEIsYUFBYSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUNwQzs7OztJQUVhLG1CQUFLOzs7O1FBQ2pCLGFBQWEsQ0FBQyxNQUFNLEdBQUcsSUFBSSxZQUFZLEVBQWEsQ0FBQzs7Ozs7O0lBR3pDLDJCQUFhOzs7O2NBQUMsS0FBZ0I7UUFDMUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3RCLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLGFBQWEsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7UUFFaEMscUJBQXFCLENBQUMsaUJ