UNPKG

@angular/router

Version:
269 lines (268 loc) • 30.3 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ /** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { map } from 'rxjs/operators'; import { ActivationEnd, ChildActivationEnd } from '../events'; import { advanceActivatedRoute } from '../router_state'; import { forEach } from '../utils/collection'; import { nodeChildrenAsMap } from '../utils/tree'; /** @type {?} */ export const activateRoutes = (rootContexts, routeReuseStrategy, forwardEvent) => map(t => { new ActivateRoutes(routeReuseStrategy, /** @type {?} */ ((t.targetRouterState)), t.currentRouterState, forwardEvent) .activate(rootContexts); return t; }); export class ActivateRoutes { /** * @param {?} routeReuseStrategy * @param {?} futureState * @param {?} currState * @param {?} forwardEvent */ constructor(routeReuseStrategy, futureState, currState, forwardEvent) { this.routeReuseStrategy = routeReuseStrategy; this.futureState = futureState; this.currState = currState; this.forwardEvent = forwardEvent; } /** * @param {?} parentContexts * @return {?} */ activate(parentContexts) { /** @type {?} */ const futureRoot = this.futureState._root; /** @type {?} */ const currRoot = this.currState ? this.currState._root : null; this.deactivateChildRoutes(futureRoot, currRoot, parentContexts); advanceActivatedRoute(this.futureState.root); this.activateChildRoutes(futureRoot, currRoot, parentContexts); } /** * @param {?} futureNode * @param {?} currNode * @param {?} contexts * @return {?} */ deactivateChildRoutes(futureNode, currNode, contexts) { /** @type {?} */ const children = nodeChildrenAsMap(currNode); // Recurse on the routes active in the future state to de-activate deeper children futureNode.children.forEach(futureChild => { /** @type {?} */ const childOutletName = futureChild.value.outlet; this.deactivateRoutes(futureChild, children[childOutletName], contexts); delete children[childOutletName]; }); // De-activate the routes that will not be re-used forEach(children, (v, childName) => { this.deactivateRouteAndItsChildren(v, contexts); }); } /** * @param {?} futureNode * @param {?} currNode * @param {?} parentContext * @return {?} */ deactivateRoutes(futureNode, currNode, parentContext) { /** @type {?} */ const future = futureNode.value; /** @type {?} */ const curr = currNode ? currNode.value : null; if (future === curr) { // Reusing the node, check to see if the children need to be de-activated if (future.component) { /** @type {?} */ const context = parentContext.getContext(future.outlet); if (context) { this.deactivateChildRoutes(futureNode, currNode, context.children); } } else { // if we have a componentless route, we recurse but keep the same outlet map. this.deactivateChildRoutes(futureNode, currNode, parentContext); } } else { if (curr) { // Deactivate the current route which will not be re-used this.deactivateRouteAndItsChildren(currNode, parentContext); } } } /** * @param {?} route * @param {?} parentContexts * @return {?} */ deactivateRouteAndItsChildren(route, parentContexts) { if (this.routeReuseStrategy.shouldDetach(route.value.snapshot)) { this.detachAndStoreRouteSubtree(route, parentContexts); } else { this.deactivateRouteAndOutlet(route, parentContexts); } } /** * @param {?} route * @param {?} parentContexts * @return {?} */ detachAndStoreRouteSubtree(route, parentContexts) { /** @type {?} */ const context = parentContexts.getContext(route.value.outlet); if (context && context.outlet) { /** @type {?} */ const componentRef = context.outlet.detach(); /** @type {?} */ const contexts = context.children.onOutletDeactivated(); this.routeReuseStrategy.store(route.value.snapshot, { componentRef, route, contexts }); } } /** * @param {?} route * @param {?} parentContexts * @return {?} */ deactivateRouteAndOutlet(route, parentContexts) { /** @type {?} */ const context = parentContexts.getContext(route.value.outlet); if (context) { /** @type {?} */ const children = nodeChildrenAsMap(route); /** @type {?} */ const contexts = route.value.component ? context.children : parentContexts; forEach(children, (v, k) => this.deactivateRouteAndItsChildren(v, contexts)); if (context.outlet) { // Destroy the component context.outlet.deactivate(); // Destroy the contexts for all the outlets that were in the component context.children.onOutletDeactivated(); } } } /** * @param {?} futureNode * @param {?} currNode * @param {?} contexts * @return {?} */ activateChildRoutes(futureNode, currNode, contexts) { /** @type {?} */ const children = nodeChildrenAsMap(currNode); futureNode.children.forEach(c => { this.activateRoutes(c, children[c.value.outlet], contexts); this.forwardEvent(new ActivationEnd(c.value.snapshot)); }); if (futureNode.children.length) { this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot)); } } /** * @param {?} futureNode * @param {?} currNode * @param {?} parentContexts * @return {?} */ activateRoutes(futureNode, currNode, parentContexts) { /** @type {?} */ const future = futureNode.value; /** @type {?} */ const curr = currNode ? currNode.value : null; advanceActivatedRoute(future); // reusing the node if (future === curr) { if (future.component) { /** @type {?} */ const context = parentContexts.getOrCreateContext(future.outlet); this.activateChildRoutes(futureNode, currNode, context.children); } else { // if we have a componentless route, we recurse but keep the same outlet map. this.activateChildRoutes(futureNode, currNode, parentContexts); } } else { if (future.component) { /** @type {?} */ const context = parentContexts.getOrCreateContext(future.outlet); if (this.routeReuseStrategy.shouldAttach(future.snapshot)) { /** @type {?} */ const stored = (/** @type {?} */ (this.routeReuseStrategy.retrieve(future.snapshot))); this.routeReuseStrategy.store(future.snapshot, null); context.children.onOutletReAttached(stored.contexts); context.attachRef = stored.componentRef; context.route = stored.route.value; if (context.outlet) { // Attach right away when the outlet has already been instantiated // Otherwise attach from `RouterOutlet.ngOnInit` when it is instantiated context.outlet.attach(stored.componentRef, stored.route.value); } advanceActivatedRouteNodeAndItsChildren(stored.route); } else { /** @type {?} */ const config = parentLoadedConfig(future.snapshot); /** @type {?} */ const cmpFactoryResolver = config ? config.module.componentFactoryResolver : null; context.attachRef = null; context.route = future; context.resolver = cmpFactoryResolver; if (context.outlet) { // Activate the outlet when it has already been instantiated // Otherwise it will get activated from its `ngOnInit` when instantiated context.outlet.activateWith(future, cmpFactoryResolver); } this.activateChildRoutes(futureNode, null, context.children); } } else { // if we have a componentless route, we recurse but keep the same outlet map. this.activateChildRoutes(futureNode, null, parentContexts); } } } } if (false) { /** @type {?} */ ActivateRoutes.prototype.routeReuseStrategy; /** @type {?} */ ActivateRoutes.prototype.futureState; /** @type {?} */ ActivateRoutes.prototype.currState; /** @type {?} */ ActivateRoutes.prototype.forwardEvent; } /** * @param {?} node * @return {?} */ function advanceActivatedRouteNodeAndItsChildren(node) { advanceActivatedRoute(node.value); node.children.forEach(advanceActivatedRouteNodeAndItsChildren); } /** * @param {?} snapshot * @return {?} */ function parentLoadedConfig(snapshot) { for (let s = snapshot.parent; s; s = s.parent) { /** @type {?} */ const route = s.routeConfig; if (route && route._loadedConfig) return route._loadedConfig; if (route && route.component) return null; } return null; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aXZhdGVfcm91dGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcm91dGVyL3NyYy9vcGVyYXRvcnMvYWN0aXZhdGVfcm91dGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBU0EsT0FBTyxFQUFDLEdBQUcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBR25DLE9BQU8sRUFBQyxhQUFhLEVBQUUsa0JBQWtCLEVBQVEsTUFBTSxXQUFXLENBQUM7QUFJbkUsT0FBTyxFQUFzRCxxQkFBcUIsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQzNHLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUM1QyxPQUFPLEVBQVcsaUJBQWlCLEVBQUMsTUFBTSxlQUFlLENBQUM7O0FBRTFELGFBQWEsY0FBYyxHQUN2QixDQUFDLFlBQW9DLEVBQUUsa0JBQXNDLEVBQzVFLFlBQWtDLEVBQWtELEVBQUUsQ0FDbkYsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO0lBQ04sSUFBSSxjQUFjLENBQ2Qsa0JBQWtCLHFCQUFFLENBQUMsQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLENBQUMsa0JBQWtCLEVBQUUsWUFBWSxDQUFDO1NBQzdFLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUM1QixPQUFPLENBQUMsQ0FBQztDQUNWLENBQUMsQ0FBQztBQUVYLE1BQU0sT0FBTyxjQUFjOzs7Ozs7O0lBQ3pCLFlBQ1ksb0JBQWdELFdBQXdCLEVBQ3hFLFdBQWdDLFlBQWtDO1FBRGxFLHVCQUFrQixHQUFsQixrQkFBa0I7UUFBOEIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEUsY0FBUyxHQUFULFNBQVM7UUFBdUIsaUJBQVksR0FBWixZQUFZLENBQXNCO0tBQUk7Ozs7O0lBRWxGLFFBQVEsQ0FBQyxjQUFzQzs7UUFDN0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxL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QixPQUFPLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztxQkFDekQ7b0JBRUQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2lCQUM5RDthQUNGO2lCQUFNOztnQkFFTCxJQUFJLENBQUMsbUJBQW1CLENBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQzthQUM1RDtTQUNGOztDQUVKOzs7Ozs7Ozs7Ozs7Ozs7QUFFRCxTQUFTLHVDQUF1QyxDQUFDLElBQThCO0lBQzdFLHFCQUFxQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO0NBQ2hFOzs7OztBQUVELFNBQVMsa0JBQWtCLENBQUMsUUFBZ0M7SUFDMUQsS0FBSyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRTs7UUFDN0MsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLFdBQVcsQ0FBQztRQUM1QixJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsYUFBYTtZQUFFLE9BQU8sS0FBSyxDQUFDLGFBQWEsQ0FBQztRQUM3RCxJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsU0FBUztZQUFFLE9BQU8sSUFBSSxDQUFDO0tBQzNDO0lBRUQsT0FBTyxJQUFJLENBQUM7Q0FDYiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtNb25vVHlwZU9wZXJhdG9yRnVuY3Rpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IHttYXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtMb2FkZWRSb3V0ZXJDb25maWd9IGZyb20gJy4uL2NvbmZpZyc7XG5pbXBvcnQge0FjdGl2YXRpb25FbmQsIENoaWxkQWN0aXZhdGlvbkVuZCwgRXZlbnR9IGZyb20gJy4uL2V2ZW50cyc7XG5pbXBvcnQge0RldGFjaGVkUm91dGVIYW5kbGVJbnRlcm5hbCwgUm91dGVSZXVzZVN0cmF0ZWd5fSBmcm9tICcuLi9yb3V0ZV9yZXVzZV9zdHJhdGVneSc7XG5pbXBvcnQge05hdmlnYXRpb25UcmFuc2l0aW9ufSBmcm9tICcuLi9yb3V0ZXInO1xuaW1wb3J0IHtDaGlsZHJlbk91dGxldENvbnRleHRzfSBmcm9tICcuLi9yb3V0ZXJfb3V0bGV0X2NvbnRleHQnO1xuaW1wb3J0IHtBY3RpdmF0ZWRSb3V0ZSwgQWN0aXZhdGVkUm91dGVTbmFwc2hvdCwgUm91dGVyU3RhdGUsIGFkdmFuY2VBY3RpdmF0ZWRSb3V0ZX0gZnJvbSAnLi4vcm91dGVyX3N0YXRlJztcbmltcG9ydCB7Zm9yRWFjaH0gZnJvbSAnLi4vdXRpbHMvY29sbGVjdGlvbic7XG5pbXBvcnQge1RyZWVOb2RlLCBub2RlQ2hpbGRyZW5Bc01hcH0gZnJvbSAnLi4vdXRpbHMvdHJlZSc7XG5cbmV4cG9ydCBjb25zdCBhY3RpdmF0ZVJvdXRlcyA9XG4gICAgKHJvb3RDb250ZXh0czogQ2hpbGRyZW5PdXRsZXRDb250ZXh0cywgcm91dGVSZXVzZVN0cmF0ZWd5OiBSb3V0ZVJldXNlU3RyYXRlZ3ksXG4gICAgIGZvcndhcmRFdmVudDogKGV2dDogRXZlbnQpID0+IHZvaWQpOiBNb25vVHlwZU9wZXJhdG9yRnVuY3Rpb248TmF2aWdhdGlvblRyYW5zaXRpb24+ID0+XG4gICAgICAgIG1hcCh0ID0+IHtcbiAgICAgICAgICBuZXcgQWN0aXZhdGVSb3V0ZXMoXG4gICAgICAgICAgICAgIHJvdXRlUmV1c2VTdHJhdGVneSwgdC50YXJnZXRSb3V0ZXJTdGF0ZSAhLCB0LmN1cnJlbnRSb3V0ZXJTdGF0ZSwgZm9yd2FyZEV2ZW50KVxuICAgICAgICAgICAgICAuYWN0aXZhdGUocm9vdENvbnRleHRzKTtcbiAgICAgICAgICByZXR1cm4gdDtcbiAgICAgICAgfSk7XG5cbmV4cG9ydCBjbGFzcyBBY3RpdmF0ZVJvdXRlcyB7XG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHJpdmF0ZSByb3V0ZVJldXNlU3RyYXRlZ3k6IFJvdXRlUmV1c2VTdHJhdGVneSwgcHJpdmF0ZSBmdXR1cmVTdGF0ZTogUm91dGVyU3RhdGUsXG4gICAgICBwcml2YXRlIGN1cnJTdGF0ZTogUm91dGVyU3RhdGUsIHByaXZhdGUgZm9yd2FyZEV2ZW50OiAoZXZ0OiBFdmVudCkgPT4gdm9pZCkge31cblxuICBhY3RpdmF0ZShwYXJlbnRDb250ZXh0czogQ2hpbGRyZW5PdXRsZXRDb250ZXh0cyk6IHZvaWQge1xuICAgIGNvbnN0IGZ1dHVyZVJvb3QgPSB0aGlzLmZ1dHVyZVN0YXRlLl9yb290O1xuICAgIGNvbnN0IGN1cnJSb290ID0gdGhpcy5jdXJyU3RhdGUgPyB0aGlzLmN1cnJTdGF0ZS5fcm9vdCA6IG51bGw7XG5cbiAgICB0aGlzLmRlYWN0aXZhdGVDaGlsZFJvdXRlcyhmdXR1cmVSb290LCBjdXJyUm9vdCwgcGFyZW50Q29udGV4dHMpO1xuICAgIGFkdmFuY2VBY3RpdmF0ZWRSb3V0ZSh0aGlzLmZ1dHVyZVN0YXRlLnJvb3QpO1xuICAgIHRoaXMuYWN0aXZhdGVDaGlsZFJvdXRlcyhmdXR1cmVSb290LCBjdXJyUm9vdCwgcGFyZW50Q29udGV4dHMpO1xuICB9XG5cbiAgLy8gRGUtYWN0aXZhdGUgdGhlIGNoaWxkIHJvdXRlIHRoYXQgYXJlIG5vdCByZS11c2VkIGZvciB0aGUgZnV0dXJlIHN0YXRlXG4gIHByaXZhdGUgZGVhY3RpdmF0ZUNoaWxkUm91dGVzKFxuICAgICAgZnV0dXJlTm9kZTogVHJlZU5vZGU8QWN0aXZhdGVkUm91dGU+LCBjdXJyTm9kZTogVHJlZU5vZGU8QWN0aXZhdGVkUm91dGU+fG51bGwsXG4gICAgICBjb250ZXh0czogQ2hpbGRyZW5PdXRsZXRDb250ZXh0cyk6IHZvaWQge1xuICAgIGNvbnN0IGNoaWxkcmVuOiB7W291dGxldE5hbWU6IHN0cmluZ106IFRyZWVOb2RlPEFjdGl2YXRlZFJvdXRlPn0gPSBub2RlQ2hpbGRyZW5Bc01hcChjdXJyTm9kZSk7XG5cbiAgICAvLyBSZWN1cnNlIG9uIHRoZSByb3V0ZXMgYWN0aXZlIGluIHRoZSBmdXR1cmUgc3RhdGUgdG8gZGUtYWN0aXZhdGUgZGVlcGVyIGNoaWxkcmVuXG4gICAgZnV0dXJlTm9kZS5jaGlsZHJlbi5mb3JFYWNoKGZ1dHVyZUNoaWxkID0+IHtcbiAgICAgIGNvbnN0IGNoaWxkT3V0bGV0TmFtZSA9IGZ1dHVyZUNoaWxkLnZhbHVlLm91dGxldDtcbiAgICAgIHRoaXMuZGVhY3RpdmF0ZVJvdXRlcyhmdXR1cmVDaGlsZCwgY2hpbGRyZW5bY2hpbGRPdXRsZXROYW1lXSwgY29udGV4dHMpO1xuICAgICAgZGVsZXRlIGNoaWxkcmVuW2NoaWxkT3V0bGV0TmFtZV07XG4gICAgfSk7XG5cbiAgICAvLyBEZS1hY3RpdmF0ZSB0aGUgcm91dGVzIHRoYXQgd2lsbCBub3QgYmUgcmUtdXNlZFxuICAgIGZvckVhY2goY2hpbGRyZW4sICh2OiBUcmVlTm9kZTxBY3RpdmF0ZWRSb3V0ZT4sIGNoaWxkTmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICB0aGlzLmRlYWN0aXZhdGVSb3V0ZUFuZEl0c0NoaWxkcmVuKHYsIGNvbnRleHRzKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZGVhY3RpdmF0ZVJvdXRlcyhcbiAgICAgIGZ1dHVyZU5vZGU6IFRyZWVOb2RlPEFjdGl2YXRlZFJvdXRlPiwgY3Vyck5vZGU6IFRyZWVOb2RlPEFjdGl2YXRlZFJvdXRlPixcbiAgICAgIHBhcmVudENvbnRleHQ6IENoaWxkcmVuT3V0bGV0Q29udGV4dHMpOiB2b2lkIHtcbiAgICBjb25zdCBmdXR1cmUgPSBmdXR1cmVOb2RlLnZhbHVlO1xuICAgIGNvbnN0IGN1cnIgPSBjdXJyTm9kZSA/IGN1cnJOb2RlLnZhbHVlIDogbnVsbDtcblxuICAgIGlmIChmdXR1cmUgPT09IGN1cnIpIHtcbiAgICAgIC8vIFJldXNpbmcgdGhlIG5vZGUsIGNoZWNrIHRvIHNlZSBpZiB0aGUgY2hpbGRyZW4gbmVlZCB0byBiZSBkZS1hY3RpdmF0ZWRcbiAgICAgIGlmIChmdXR1cmUuY29tcG9uZW50KSB7XG4gICAgICAgIC8vIElmIHdlIGhhdmUgYSBub3JtYWwgcm91dGUsIHdlIG5lZWQgdG8gZ28gdGhyb3VnaCBhbiBvdXRsZXQuXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBwYXJlbnRDb250ZXh0LmdldENvbnRleHQoZnV0dXJlLm91dGxldCk7XG4gICAgICAgIGlmIChjb250ZXh0KSB7XG4gICAgICAgICAgdGhpcy5kZWFjdGl2YXRlQ2hpbGRSb3V0ZXMoZnV0dXJlTm9kZSwgY3Vyck5vZGUsIGNvbnRleHQuY2hpbGRyZW4pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBpZiB3ZSBoYXZlIGEgY29tcG9uZW50bGVzcyByb3V0ZSwgd2UgcmVjdXJzZSBidXQga2VlcCB0aGUgc2FtZSBvdXRsZXQgbWFwLlxuICAgICAgICB0aGlzLmRlYWN0aXZhdGVDaGlsZFJvdXRlcyhmdXR1cmVOb2RlLCBjdXJyTm9kZSwgcGFyZW50Q29udGV4dCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChjdXJyKSB7XG4gICAgICAgIC8vIERlYWN0aXZhdGUgdGhlIGN1cnJlbnQgcm91dGUgd2hpY2ggd2lsbCBub3QgYmUgcmUtdXNlZFxuICAgICAgICB0aGlzLmRlYWN0aXZhdGVSb3V0ZUFuZEl0c0NoaWxkcmVuKGN1cnJOb2RlLCBwYXJlbnRDb250ZXh0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRlYWN0aXZhdGVSb3V0ZUFuZEl0c0NoaWxkcmVuKFxuICAgICAgcm91dGU6IFRyZWVOb2RlPEFjdGl2YXRlZFJvdXRlPiwgcGFyZW50Q29udGV4dHM6IENoaWxkcmVuT3V0bGV0Q29udGV4dHMpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5yb3V0ZVJldXNlU3RyYXRlZ3kuc2hvdWxkRGV0YWNoKHJvdXRlLnZhbHVlLnNuYXBzaG90KSkge1xuICAgICAgdGhpcy5kZXRhY2hBbmRTdG9yZVJvdXRlU3VidHJlZShyb3V0ZSwgcGFyZW50Q29udGV4dHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlYWN0aXZhdGVSb3V0ZUFuZE91dGxldChyb3V0ZSwgcGFyZW50Q29udGV4dHMpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGV0YWNoQW5kU3RvcmVSb3V0ZVN1YnRyZWUoXG4gICAgICByb3V0ZTogVHJlZU5vZGU8QWN0aXZhdGVkUm91dGU+LCBwYXJlbnRDb250ZXh0czogQ2hpbGRyZW5PdXRsZXRDb250ZXh0cyk6IHZvaWQge1xuICAgIGNvbnN0IGNvbnRleHQgPSBwYXJlbnRDb250ZXh0cy5nZXRDb250ZXh0KHJvdXRlLnZhbHVlLm91dGxldCk7XG4gICAgaWYgKGNvbnRleHQgJiYgY29udGV4dC5vdXRsZXQpIHtcbiAgICAgIGNvbnN0IGNvbXBvbmVudFJlZiA9IGNvbnRleHQub3V0bGV0LmRldGFjaCgpO1xuICAgICAgY29uc3QgY29udGV4dHMgPSBjb250ZXh0LmNoaWxkcmVuLm9uT3V0bGV0RGVhY3RpdmF0ZWQoKTtcbiAgICAgIHRoaXMucm91dGVSZXVzZVN0cmF0ZWd5LnN0b3JlKHJvdXRlLnZhbHVlLnNuYXBzaG90LCB7Y29tcG9uZW50UmVmLCByb3V0ZSwgY29udGV4dHN9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRlYWN0aXZhdGVSb3V0ZUFuZE91dGxldChcbiAgICAgIHJvdXRlOiBUcmVlTm9kZTxBY3RpdmF0ZWRSb3V0ZT4sIHBhcmVudENvbnRleHRzOiBDaGlsZHJlbk91dGxldENvbnRleHRzKTogdm9pZCB7XG4gICAgY29uc3QgY29udGV4dCA9IHBhcmVudENvbnRleHRzLmdldENvbnRleHQocm91dGUudmFsdWUub3V0bGV0KTtcblxuICAgIGlmIChjb250ZXh0KSB7XG4gICAgICBjb25zdCBjaGlsZHJlbjoge1tvdXRsZXROYW1lOiBzdHJpbmddOiBhbnl9ID0gbm9kZUNoaWxkcmVuQXNNYXAocm91dGUpO1xuICAgICAgY29uc3QgY29udGV4dHMgPSByb3V0ZS52YWx1ZS5jb21wb25lbnQgPyBjb250ZXh0LmNoaWxkcmVuIDogcGFyZW50Q29udGV4dHM7XG5cbiAgICAgIGZvckVhY2goY2hpbGRyZW4sICh2OiBhbnksIGs6IHN0cmluZykgPT4gdGhpcy5kZWFjdGl2YXRlUm91dGVBbmRJdHNDaGlsZHJlbih2LCBjb250ZXh0cykpO1xuXG4gICAgICBpZiAoY29udGV4dC5vdXRsZXQpIHtcbiAgICAgICAgLy8gRGVzdHJveSB0aGUgY29tcG9uZW50XG4gICAgICAgIGNvbnRleHQub3V0bGV0LmRlYWN0aXZhdGUoKTtcbiAgICAgICAgLy8gRGVzdHJveSB0aGUgY29udGV4dHMgZm9yIGFsbCB0aGUgb3V0bGV0cyB0aGF0IHdlcmUgaW4gdGhlIGNvbXBvbmVudFxuICAgICAgICBjb250ZXh0LmNoaWxkcmVuLm9uT3V0bGV0RGVhY3RpdmF0ZWQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFjdGl2YXRlQ2hpbGRSb3V0ZXMoXG4gICAgICBmdXR1cmVOb2RlOiBUcmVlTm9kZTxBY3RpdmF0ZWRSb3V0ZT4sIGN1cnJOb2RlOiBUcmVlTm9kZTxBY3RpdmF0ZWRSb3V0ZT58bnVsbCxcbiAgICAgIGNvbnRleHRzOiBDaGlsZHJlbk91dGxldENvbnRleHRzKTogdm9pZCB7XG4gICAgY29uc3QgY2hpbGRyZW46IHtbb3V0bGV0OiBzdHJpbmddOiBhbnl9ID0gbm9kZUNoaWxkcmVuQXNNYXAoY3Vyck5vZGUpO1xuICAgIGZ1dHVyZU5vZGUuY2hpbGRyZW4uZm9yRWFjaChjID0+IHtcbiAgICAgIHRoaXMuYWN0aXZhdGVSb3V0ZXMoYywgY2hpbGRyZW5bYy52YWx1ZS5vdXRsZXRdLCBjb250ZXh0cyk7XG4gICAgICB0aGlzLmZvcndhcmRFdmVudChuZXcgQWN0aXZhdGlvbkVuZChjLnZhbHVlLnNuYXBzaG90KSk7XG4gICAgfSk7XG4gICAgaWYgKGZ1dHVyZU5vZGUuY2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICB0aGlzLmZvcndhcmRFdmVudChuZXcgQ2hpbGRBY3RpdmF0aW9uRW5kKGZ1dHVyZU5vZGUudmFsdWUuc25hcHNob3QpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFjdGl2YXRlUm91dGVzKFxuICAgICAgZnV0dXJlTm9kZTogVHJlZU5vZGU8QWN0aXZhdGVkUm91dGU+LCBjdXJyTm9kZTogVHJlZU5vZGU8QWN0aXZhdGVkUm91dGU+LFxuICAgICAgcGFyZW50Q29udGV4dHM6IENoaWxkcmVuT3V0bGV0Q29udGV4dHMpOiB2b2lkIHtcbiAgICBjb25zdCBmdXR1cmUgPSBmdXR1cmVOb2RlLnZhbHVlO1xuICAgIGNvbnN0IGN1cnIgPSBjdXJyTm9kZSA/IGN1cnJOb2RlLnZhbHVlIDogbnVsbDtcblxuICAgIGFkdmFuY2VBY3RpdmF0ZWRSb3V0ZShmdXR1cmUpO1xuXG4gICAgLy8gcmV1c2luZyB0aGUgbm9kZVxuICAgIGlmIChmdXR1cmUgPT09IGN1cnIpIHtcbiAgICAgIGlmIChmdXR1cmUuY29tcG9uZW50KSB7XG4gICAgICAgIC8vIElmIHdlIGhhdmUgYSBub3JtYWwgcm91dGUsIHdlIG5lZWQgdG8gZ28gdGhyb3VnaCBhbiBvdXRsZXQuXG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBwYXJlbnRDb250ZXh0cy5nZXRPckNyZWF0ZUNvbnRleHQoZnV0dXJlLm91dGxldCk7XG4gICAgICAgIHRoaXMuYWN0aXZhdGVDaGlsZFJvdXRlcyhmdXR1cmVOb2RlLCBjdXJyTm9kZSwgY29udGV4dC5jaGlsZHJlbik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBpZiB3ZSBoYXZlIGEgY29tcG9uZW50bGVzcyByb3V0ZSwgd2UgcmVjdXJzZSBidXQga2VlcCB0aGUgc2FtZSBvdXRsZXQgbWFwLlxuICAgICAgICB0aGlzLmFjdGl2YXRlQ2hpbGRSb3V0ZXMoZnV0dXJlTm9kZSwgY3Vyck5vZGUsIHBhcmVudENvbnRleHRzKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGZ1dHVyZS5jb21wb25lbnQpIHtcbiAgICAgICAgLy8gaWYgd2UgaGF2ZSBhIG5vcm1hbCByb3V0ZSwgd2UgbmVlZCB0byBwbGFjZSB0aGUgY29tcG9uZW50IGludG8gdGhlIG91dGxldCBhbmQgcmVjdXJzZS5cbiAgICAgICAgY29uc3QgY29udGV4dCA9IHBhcmVudENvbnRleHRzLmdldE9yQ3JlYXRlQ29udGV4dChmdXR1cmUub3V0bGV0KTtcblxuICAgICAgICBpZiAodGhpcy5yb3V0ZVJldXNlU3RyYXRlZ3kuc2hvdWxkQXR0YWNoKGZ1dHVyZS5zbmFwc2hvdCkpIHtcbiAgICAgICAgICBjb25zdCBzdG9yZWQgPVxuICAgICAgICAgICAgICAoPERldGFjaGVkUm91dGVIYW5kbGVJbnRlcm5hbD50aGlzLnJvdXRlUmV1c2VTdHJhdGVneS5yZXRyaWV2ZShmdXR1cmUuc25hcHNob3QpKTtcbiAgICAgICAgICB0aGlzLnJvdXRlUmV1c2VTdHJhdGVneS5zdG9yZShmdXR1cmUuc25hcHNob3QsIG51bGwpO1xuICAgICAgICAgIGNvbnRleHQuY2hpbGRyZW4ub25PdXRsZXRSZUF0dGFjaGVkKHN0b3JlZC5jb250ZXh0cyk7XG4gICAgICAgICAgY29udGV4dC5hdHRhY2hSZWYgPSBzdG9yZWQuY29tcG9uZW50UmVmO1xuICAgICAgICAgIGNvbnRleHQucm91dGUgPSBzdG9yZWQucm91dGUudmFsdWU7XG4gICAgICAgICAgaWYgKGNvbnRleHQub3V0bGV0KSB7XG4gICAgICAgICAgICAvLyBBdHRhY2ggcmlnaHQgYXdheSB3aGVuIHRoZSBvdXRsZXQgaGFzIGFscmVhZHkgYmVlbiBpbnN0YW50aWF0ZWRcbiAgICAgICAgICAgIC8vIE90aGVyd2lzZSBhdHRhY2ggZnJvbSBgUm91dGVyT3V0bGV0Lm5nT25Jbml0YCB3aGVuIGl0IGlzIGluc3RhbnRpYXRlZFxuICAgICAgICAgICAgY29udGV4dC5vdXRsZXQuYXR0YWNoKHN0b3JlZC5jb21wb25lbnRSZWYsIHN0b3JlZC5yb3V0ZS52YWx1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFkdmFuY2VBY3RpdmF0ZWRSb3V0ZU5vZGVBbmRJdHNDaGlsZHJlbihzdG9yZWQucm91dGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IHBhcmVudExvYWRlZENvbmZpZyhmdXR1cmUuc25hcHNob3QpO1xuICAgICAgICAgIGNvbnN0IGNtcEZhY3RvcnlSZXNvbHZlciA9IGNvbmZpZyA/IGNvbmZpZy5tb2R1bGUuY29tcG9uZW50RmFjdG9yeVJlc29sdmVyIDogbnVsbDtcblxuICAgICAgICAgIGNvbnRleHQuYXR0YWNoUmVmID0gbnVsbDtcbiAgICAgICAgICBjb250ZXh0LnJvdXRlID0gZnV0dXJlO1xuICAgICAgICAgIGNvbnRleHQucmVzb2x2ZXIgPSBjbXBGYWN0b3J5UmVzb2x2ZXI7XG4gICAgICAgICAgaWYgKGNvbnRleHQub3V0bGV0KSB7XG4gICAgICAgICAgICAvLyBBY3RpdmF0ZSB0aGUgb3V0bGV0IHdoZW4gaXQgaGFzIGFscmVhZHkgYmVlbiBpbnN0YW50aWF0ZWRcbiAgICAgICAgICAgIC8vIE90aGVyd2lzZSBpdCB3aWxsIGdldCBhY3RpdmF0ZWQgZnJvbSBpdHMgYG5nT25Jbml0YCB3aGVuIGluc3RhbnRpYXRlZFxuICAgICAgICAgICAgY29udGV4dC5vdXRsZXQuYWN0aXZhdGVXaXRoKGZ1dHVyZSwgY21wRmFjdG9yeVJlc29sdmVyKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmFjdGl2YXRlQ2hpbGRSb3V0ZXMoZnV0dXJlTm9kZSwgbnVsbCwgY29udGV4dC5jaGlsZHJlbik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGlmIHdlIGhhdmUgYSBjb21wb25lbnRsZXNzIHJvdXRlLCB3ZSByZWN1cnNlIGJ1dCBrZWVwIHRoZSBzYW1lIG91dGxldCBtYXAuXG4gICAgICAgIHRoaXMuYWN0aXZhdGVDaGlsZFJvdXRlcyhmdXR1cmVOb2RlLCBudWxsLCBwYXJlbnRDb250ZXh0cyk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFkdmFuY2VBY3RpdmF0ZWRSb3V0ZU5vZGVBbmRJdHNDaGlsZHJlbihub2RlOiBUcmVlTm9kZTxBY3RpdmF0ZWRSb3V0ZT4pOiB2b2lkIHtcbiAgYWR2YW5jZUFjdGl2YXRlZFJvdXRlKG5vZGUudmFsdWUpO1xuICBub2RlLmNoaWxkcmVuLmZvckVhY2goYWR2YW5jZUFjdGl2YXRlZFJvdXRlTm9kZUFuZEl0c0NoaWxkcmVuKTtcbn1cblxuZnVuY3Rpb24gcGFyZW50TG9hZGVkQ29uZmlnKHNuYXBzaG90OiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90KTogTG9hZGVkUm91dGVyQ29uZmlnfG51bGwge1xuICBmb3IgKGxldCBzID0gc25hcHNob3QucGFyZW50OyBzOyBzID0gcy5wYXJlbnQpIHtcbiAgICBjb25zdCByb3V0ZSA9IHMucm91dGVDb25maWc7XG4gICAgaWYgKHJvdXRlICYmIHJvdXRlLl9sb2FkZWRDb25maWcpIHJldHVybiByb3V0ZS5fbG9hZGVkQ29uZmlnO1xuICAgIGlmIChyb3V0ZSAmJiByb3V0ZS5jb21wb25lbnQpIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59Il19