UNPKG

angular2

Version:

Angular 2 - a web framework for modern web apps

455 lines 70.6 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; import { ListWrapper, Map, StringMapWrapper } from 'angular2/src/facade/collection'; import { PromiseWrapper } from 'angular2/src/facade/async'; import { isPresent, isArray, isBlank, isType, isString, isStringMap, Type, StringWrapper, Math, getTypeNameForDebugging, CONST_EXPR } from 'angular2/src/facade/lang'; import { BaseException } from 'angular2/src/facade/exceptions'; import { reflector } from 'angular2/src/core/reflection/reflection'; import { Injectable, Inject, OpaqueToken } from 'angular2/core'; import { RouteConfig, Route, AuxRoute } from './route_config/route_config_impl'; import { PathMatch, RedirectMatch } from './rules/rules'; import { RuleSet } from './rules/rule_set'; import { ResolvedInstruction, RedirectInstruction, UnresolvedInstruction, DefaultInstruction } from './instruction'; import { normalizeRouteConfig, assertComponentExists } from './route_config/route_config_normalizer'; import { parser, convertUrlParamsToArray } from './url_parser'; var _resolveToNull = PromiseWrapper.resolve(null); // A LinkItemArray is an array, which describes a set of routes // The items in the array are found in groups: // - the first item is the name of the route // - the next items are: // - an object containing parameters // - or an array describing an aux route // export type LinkRouteItem = string | Object; // export type LinkItem = LinkRouteItem | Array<LinkRouteItem>; // export type LinkItemArray = Array<LinkItem>; /** * Token used to bind the component with the top-level {@link RouteConfig}s for the * application. * * ### Example ([live demo](http://plnkr.co/edit/iRUP8B5OUbxCWQ3AcIDm)) * * ``` * import {Component} from 'angular2/core'; * import { * ROUTER_DIRECTIVES, * ROUTER_PROVIDERS, * RouteConfig * } from 'angular2/router'; * * @Component({directives: [ROUTER_DIRECTIVES]}) * @RouteConfig([ * {...}, * ]) * class AppCmp { * // ... * } * * bootstrap(AppCmp, [ROUTER_PROVIDERS]); * ``` */ export const ROUTER_PRIMARY_COMPONENT = CONST_EXPR(new OpaqueToken('RouterPrimaryComponent')); /** * The RouteRegistry holds route configurations for each component in an Angular app. * It is responsible for creating Instructions from URLs, and generating URLs based on route and * parameters. */ export let RouteRegistry = class RouteRegistry { constructor(_rootComponent) { this._rootComponent = _rootComponent; this._rules = new Map(); } /** * Given a component and a configuration object, add the route to this registry */ config(parentComponent, config) { config = normalizeRouteConfig(config, this); // this is here because Dart type guard reasons if (config instanceof Route) { assertComponentExists(config.component, config.path); } else if (config instanceof AuxRoute) { assertComponentExists(config.component, config.path); } var rules = this._rules.get(parentComponent); if (isBlank(rules)) { rules = new RuleSet(); this._rules.set(parentComponent, rules); } var terminal = rules.config(config); if (config instanceof Route) { if (terminal) { assertTerminalComponent(config.component, config.path); } else { this.configFromComponent(config.component); } } } /** * Reads the annotations of a component and configures the registry based on them */ configFromComponent(component) { if (!isType(component)) { return; } // Don't read the annotations from a type more than once – // this prevents an infinite loop if a component routes recursively. if (this._rules.has(component)) { return; } var annotations = reflector.annotations(component); if (isPresent(annotations)) { for (var i = 0; i < annotations.length; i++) { var annotation = annotations[i]; if (annotation instanceof RouteConfig) { let routeCfgs = annotation.configs; routeCfgs.forEach(config => this.config(component, config)); } } } } /** * Given a URL and a parent component, return the most specific instruction for navigating * the application into the state specified by the url */ recognize(url, ancestorInstructions) { var parsedUrl = parser.parse(url); return this._recognize(parsedUrl, []); } /** * Recognizes all parent-child routes, but creates unresolved auxiliary routes */ _recognize(parsedUrl, ancestorInstructions, _aux = false) { var parentInstruction = ListWrapper.last(ancestorInstructions); var parentComponent = isPresent(parentInstruction) ? parentInstruction.component.componentType : this._rootComponent; var rules = this._rules.get(parentComponent); if (isBlank(rules)) { return _resolveToNull; } // Matches some beginning part of the given URL var possibleMatches = _aux ? rules.recognizeAuxiliary(parsedUrl) : rules.recognize(parsedUrl); var matchPromises = possibleMatches.map((candidate) => candidate.then((candidate) => { if (candidate instanceof PathMatch) { var auxParentInstructions = ancestorInstructions.length > 0 ? [ListWrapper.last(ancestorInstructions)] : []; var auxInstructions = this._auxRoutesToUnresolved(candidate.remainingAux, auxParentInstructions); var instruction = new ResolvedInstruction(candidate.instruction, null, auxInstructions); if (isBlank(candidate.instruction) || candidate.instruction.terminal) { return instruction; } var newAncestorInstructions = ancestorInstructions.concat([instruction]); return this._recognize(candidate.remaining, newAncestorInstructions) .then((childInstruction) => { if (isBlank(childInstruction)) { return null; } // redirect instructions are already absolute if (childInstruction instanceof RedirectInstruction) { return childInstruction; } instruction.child = childInstruction; return instruction; }); } if (candidate instanceof RedirectMatch) { var instruction = this.generate(candidate.redirectTo, ancestorInstructions.concat([null])); return new RedirectInstruction(instruction.component, instruction.child, instruction.auxInstruction, candidate.specificity); } })); if ((isBlank(parsedUrl) || parsedUrl.path == '') && possibleMatches.length == 0) { return PromiseWrapper.resolve(this.generateDefault(parentComponent)); } return PromiseWrapper.all(matchPromises).then(mostSpecific); } _auxRoutesToUnresolved(auxRoutes, parentInstructions) { var unresolvedAuxInstructions = {}; auxRoutes.forEach((auxUrl) => { unresolvedAuxInstructions[auxUrl.path] = new UnresolvedInstruction(() => { return this._recognize(auxUrl, parentInstructions, true); }); }); return unresolvedAuxInstructions; } /** * Given a normalized list with component names and params like: `['user', {id: 3 }]` * generates a url with a leading slash relative to the provided `parentComponent`. * * If the optional param `_aux` is `true`, then we generate starting at an auxiliary * route boundary. */ generate(linkParams, ancestorInstructions, _aux = false) { var params = splitAndFlattenLinkParams(linkParams); var prevInstruction; // The first segment should be either '.' (generate from parent) or '' (generate from root). // When we normalize above, we strip all the slashes, './' becomes '.' and '/' becomes ''. if (ListWrapper.first(params) == '') { params.shift(); prevInstruction = ListWrapper.first(ancestorInstructions); ancestorInstructions = []; } else { prevInstruction = ancestorInstructions.length > 0 ? ancestorInstructions.pop() : null; if (ListWrapper.first(params) == '.') { params.shift(); } else if (ListWrapper.first(params) == '..') { while (ListWrapper.first(params) == '..') { if (ancestorInstructions.length <= 0) { throw new BaseException(`Link "${ListWrapper.toJSON(linkParams)}" has too many "../" segments.`); } prevInstruction = ancestorInstructions.pop(); params = ListWrapper.slice(params, 1); } } else { // we must only peak at the link param, and not consume it let routeName = ListWrapper.first(params); let parentComponentType = this._rootComponent; let grandparentComponentType = null; if (ancestorInstructions.length > 1) { let parentComponentInstruction = ancestorInstructions[ancestorInstructions.length - 1]; let grandComponentInstruction = ancestorInstructions[ancestorInstructions.length - 2]; parentComponentType = parentComponentInstruction.component.componentType; grandparentComponentType = grandComponentInstruction.component.componentType; } else if (ancestorInstructions.length == 1) { parentComponentType = ancestorInstructions[0].component.componentType; grandparentComponentType = this._rootComponent; } // For a link with no leading `./`, `/`, or `../`, we look for a sibling and child. // If both exist, we throw. Otherwise, we prefer whichever exists. var childRouteExists = this.hasRoute(routeName, parentComponentType); var parentRouteExists = isPresent(grandparentComponentType) && this.hasRoute(routeName, grandparentComponentType); if (parentRouteExists && childRouteExists) { let msg = `Link "${ListWrapper.toJSON(linkParams)}" is ambiguous, use "./" or "../" to disambiguate.`; throw new BaseException(msg); } if (parentRouteExists) { prevInstruction = ancestorInstructions.pop(); } } } if (params[params.length - 1] == '') { params.pop(); } if (params.length > 0 && params[0] == '') { params.shift(); } if (params.length < 1) { let msg = `Link "${ListWrapper.toJSON(linkParams)}" must include a route name.`; throw new BaseException(msg); } var generatedInstruction = this._generate(params, ancestorInstructions, prevInstruction, _aux, linkParams); // we don't clone the first (root) element for (var i = ancestorInstructions.length - 1; i >= 0; i--) { let ancestorInstruction = ancestorInstructions[i]; if (isBlank(ancestorInstruction)) { break; } generatedInstruction = ancestorInstruction.replaceChild(generatedInstruction); } return generatedInstruction; } /* * Internal helper that does not make any assertions about the beginning of the link DSL. * `ancestorInstructions` are parents that will be cloned. * `prevInstruction` is the existing instruction that would be replaced, but which might have * aux routes that need to be cloned. */ _generate(linkParams, ancestorInstructions, prevInstruction, _aux = false, _originalLink) { let parentComponentType = this._rootComponent; let componentInstruction = null; let auxInstructions = {}; let parentInstruction = ListWrapper.last(ancestorInstructions); if (isPresent(parentInstruction) && isPresent(parentInstruction.component)) { parentComponentType = parentInstruction.component.componentType; } if (linkParams.length == 0) { let defaultInstruction = this.generateDefault(parentComponentType); if (isBlank(defaultInstruction)) { throw new BaseException(`Link "${ListWrapper.toJSON(_originalLink)}" does not resolve to a terminal instruction.`); } return defaultInstruction; } // for non-aux routes, we want to reuse the predecessor's existing primary and aux routes // and only override routes for which the given link DSL provides if (isPresent(prevInstruction) && !_aux) { auxInstructions = StringMapWrapper.merge(prevInstruction.auxInstruction, auxInstructions); componentInstruction = prevInstruction.component; } var rules = this._rules.get(parentComponentType); if (isBlank(rules)) { throw new BaseException(`Component "${getTypeNameForDebugging(parentComponentType)}" has no route config.`); } let linkParamIndex = 0; let routeParams = {}; // first, recognize the primary route if one is provided if (linkParamIndex < linkParams.length && isString(linkParams[linkParamIndex])) { let routeName = linkParams[linkParamIndex]; if (routeName == '' || routeName == '.' || routeName == '..') { throw new BaseException(`"${routeName}/" is only allowed at the beginning of a link DSL.`); } linkParamIndex += 1; if (linkParamIndex < linkParams.length) { let linkParam = linkParams[linkParamIndex]; if (isStringMap(linkParam) && !isArray(linkParam)) { routeParams = linkParam; linkParamIndex += 1; } } var routeRecognizer = (_aux ? rules.auxRulesByName : rules.rulesByName).get(routeName); if (isBlank(routeRecognizer)) { throw new BaseException(`Component "${getTypeNameForDebugging(parentComponentType)}" has no route named "${routeName}".`); } // Create an "unresolved instruction" for async routes // we'll figure out the rest of the route when we resolve the instruction and // perform a navigation if (isBlank(routeRecognizer.handler.componentType)) { var generatedUrl = routeRecognizer.generateComponentPathValues(routeParams); return new UnresolvedInstruction(() => { return routeRecognizer.handler.resolveComponentType().then((_) => { return this._generate(linkParams, ancestorInstructions, prevInstruction, _aux, _originalLink); }); }, generatedUrl.urlPath, convertUrlParamsToArray(generatedUrl.urlParams)); } componentInstruction = _aux ? rules.generateAuxiliary(routeName, routeParams) : rules.generate(routeName, routeParams); } // Next, recognize auxiliary instructions. // If we have an ancestor instruction, we preserve whatever aux routes are active from it. while (linkParamIndex < linkParams.length && isArray(linkParams[linkParamIndex])) { let auxParentInstruction = [parentInstruction]; let auxInstruction = this._generate(linkParams[linkParamIndex], auxParentInstruction, null, true, _originalLink); // TODO: this will not work for aux routes with parameters or multiple segments auxInstructions[auxInstruction.component.urlPath] = auxInstruction; linkParamIndex += 1; } var instruction = new ResolvedInstruction(componentInstruction, null, auxInstructions); // If the component is sync, we can generate resolved child route instructions // If not, we'll resolve the instructions at navigation time if (isPresent(componentInstruction) && isPresent(componentInstruction.componentType)) { let childInstruction = null; if (componentInstruction.terminal) { if (linkParamIndex >= linkParams.length) { } } else { let childAncestorComponents = ancestorInstructions.concat([instruction]); let remainingLinkParams = linkParams.slice(linkParamIndex); childInstruction = this._generate(remainingLinkParams, childAncestorComponents, null, false, _originalLink); } instruction.child = childInstruction; } return instruction; } hasRoute(name, parentComponent) { var rules = this._rules.get(parentComponent); if (isBlank(rules)) { return false; } return rules.hasRoute(name); } generateDefault(componentCursor) { if (isBlank(componentCursor)) { return null; } var rules = this._rules.get(componentCursor); if (isBlank(rules) || isBlank(rules.defaultRule)) { return null; } var defaultChild = null; if (isPresent(rules.defaultRule.handler.componentType)) { var componentInstruction = rules.defaultRule.generate({}); if (!rules.defaultRule.terminal) { defaultChild = this.generateDefault(rules.defaultRule.handler.componentType); } return new DefaultInstruction(componentInstruction, defaultChild); } return new UnresolvedInstruction(() => { return rules.defaultRule.handler.resolveComponentType().then((_) => this.generateDefault(componentCursor)); }); } }; RouteRegistry = __decorate([ Injectable(), __param(0, Inject(ROUTER_PRIMARY_COMPONENT)), __metadata('design:paramtypes', [Type]) ], RouteRegistry); /* * Given: ['/a/b', {c: 2}] * Returns: ['', 'a', 'b', {c: 2}] */ function splitAndFlattenLinkParams(linkParams) { var accumulation = []; linkParams.forEach(function (item) { if (isString(item)) { var strItem = item; accumulation = accumulation.concat(strItem.split('/')); } else { accumulation.push(item); } }); return accumulation; } /* * Given a list of instructions, returns the most specific instruction */ function mostSpecific(instructions) { instructions = instructions.filter((instruction) => isPresent(instruction)); if (instructions.length == 0) { return null; } if (instructions.length == 1) { return instructions[0]; } var first = instructions[0]; var rest = instructions.slice(1); return rest.reduce((instruction, contender) => { if (compareSpecificityStrings(contender.specificity, instruction.specificity) == -1) { return contender; } return instruction; }, first); } /* * Expects strings to be in the form of "[0-2]+" * Returns -1 if string A should be sorted above string B, 1 if it should be sorted after, * or 0 if they are the same. */ function compareSpecificityStrings(a, b) { var l = Math.min(a.length, b.length); for (var i = 0; i < l; i += 1) { var ai = StringWrapper.charCodeAt(a, i); var bi = StringWrapper.charCodeAt(b, i); var difference = bi - ai; if (difference != 0) { return difference; } } return a.length - b.length; } function assertTerminalComponent(component, path) { if (!isType(component)) { return; } var annotations = reflector.annotations(component); if (isPresent(annotations)) { for (var i = 0; i < annotations.length; i++) { var annotation = annotations[i]; if (annotation instanceof RouteConfig) { throw new BaseException(`Child routes are not allowed for "${path}". Use "..." on the parent's route path.`); } } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVfcmVnaXN0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkaWZmaW5nX3BsdWdpbl93cmFwcGVyLW91dHB1dF9wYXRoLXhCTElCclZSLnRtcC9hbmd1bGFyMi9zcmMvcm91dGVyL3JvdXRlX3JlZ2lzdHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztPQUFPLEVBQUMsV0FBVyxFQUFFLEdBQUcsRUFBYyxnQkFBZ0IsRUFBQyxNQUFNLGdDQUFnQztPQUN0RixFQUFDLGNBQWMsRUFBQyxNQUFNLDJCQUEyQjtPQUNqRCxFQUNMLFNBQVMsRUFDVCxPQUFPLEVBQ1AsT0FBTyxFQUNQLE1BQU0sRUFDTixRQUFRLEVBQ1IsV0FBVyxFQUNYLElBQUksRUFDSixhQUFhLEVBQ2IsSUFBSSxFQUNKLHVCQUF1QixFQUN2QixVQUFVLEVBQ1gsTUFBTSwwQkFBMEI7T0FDMUIsRUFBQyxhQUFhLEVBQW1CLE1BQU0sZ0NBQWdDO09BQ3ZFLEVBQUMsU0FBUyxFQUFDLE1BQU0seUNBQXlDO09BQzFELEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUMsTUFBTSxlQUFlO09BRXRELEVBQ0wsV0FBVyxFQUVYLEtBQUssRUFDTCxRQUFRLEVBR1QsTUFBTSxrQ0FBa0M7T0FDbEMsRUFBQyxTQUFTLEVBQUUsYUFBYSxFQUFhLE1BQU0sZUFBZTtPQUMzRCxFQUFDLE9BQU8sRUFBQyxNQUFNLGtCQUFrQjtPQUNqQyxFQUVMLG1CQUFtQixFQUNuQixtQkFBbUIsRUFDbkIscUJBQXFCLEVBQ3JCLGtCQUFrQixFQUNuQixNQUFNLGVBQWU7T0FFZixFQUFDLG9CQUFvQixFQUFFLHFCQUFxQixFQUFDLE1BQU0sd0NBQXdDO09BQzNGLEVBQUMsTUFBTSxFQUFPLHVCQUF1QixFQUFvQixNQUFNLGNBQWM7QUFHcEYsSUFBSSxjQUFjLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBYyxJQUFJLENBQUMsQ0FBQztBQUUvRCwrREFBK0Q7QUFDL0QsOENB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QyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQztJQUNULENBQUM7SUFFRCxJQUFJLFdBQVcsR0FBRyxTQUFTLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ25ELEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0IsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDNUMsSUFBSSxVQUFVLEdBQUcsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRWhDLEVBQUUsQ0FBQyxDQUFDLFVBQVUsWUFBWSxXQUFXLENBQUMsQ0FBQyxDQUFDO2dCQUN0QyxNQUFNLElBQUksYUFBYSxDQUNuQixxQ0FBcUMsSUFBSSwwQ0FBMEMsQ0FBQyxDQUFDO1lBQzNGLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0xpc3RXcmFwcGVyLCBNYXAsIE1hcFdyYXBwZXIsIFN0cmluZ01hcFdyYXBwZXJ9IGZyb20gJ2FuZ3VsYXIyL3NyYy9mYWNhZGUvY29sbGVjdGlvbic7XG5pbXBvcnQge1Byb21pc2VXcmFwcGVyfSBmcm9tICdhbmd1bGFyMi9zcmMvZmFjYWRlL2FzeW5jJztcbmltcG9ydCB7XG4gIGlzUHJlc2VudCxcbiAgaXNBcnJheSxcbiAgaXNCbGFuayxcbiAgaXNUeXBlLFxuICBpc1N0cmluZyxcbiAgaXNTdHJpbmdNYXAsXG4gIFR5cGUsXG4gIFN0cmluZ1dyYXBwZXIsXG4gIE1hdGgsXG4gIGdldFR5cGVOYW1lRm9yRGVidWdnaW5nLFxuICBDT05TVF9FWFBSXG59IGZyb20gJ2FuZ3VsYXIyL3NyYy9mYWNhZGUvbGFuZyc7XG5pbXBvcnQge0Jhc2VFeGNlcHRpb24sIFdyYXBwZWRFeGNlcHRpb259IGZyb20gJ2FuZ3VsYXIyL3NyYy9mYWNhZGUvZXhjZXB0aW9ucyc7XG5pbXBvcnQge3JlZmxlY3Rvcn0gZnJvbSAnYW5ndWxhcjIvc3JjL2NvcmUvcmVmbGVjdGlvbi9yZWZsZWN0aW9uJztcbmltcG9ydCB7SW5qZWN0YWJsZSwgSW5qZWN0LCBPcGFxdWVUb2tlbn0gZnJvbSAnYW5ndWxhcjIvY29yZSc7XG5cbmltcG9ydCB7XG4gIFJvdXRlQ29uZmlnLFxuICBBc3luY1JvdXRlLFxuICBSb3V0ZSxcbiAgQXV4Um91dGUsXG4gIFJlZGlyZWN0LFxuICBSb3V0ZURlZmluaXRpb25cbn0gZnJvbSAnLi9yb3V0ZV9jb25maWcvcm91dGVfY29uZmlnX2ltcGwnO1xuaW1wb3J0IHtQYXRoTWF0Y2gsIFJlZGlyZWN0TWF0Y2gsIFJvdXRlTWF0Y2h9IGZyb20gJy4vcnVsZXMvcnVsZXMnO1xuaW1wb3J0IHtSdWxlU2V0fSBmcm9tICcuL3J1bGVzL3J1bGVfc2V0JztcbmltcG9ydCB7XG4gIEluc3RydWN0aW9uLFxuICBSZXNvbHZlZEluc3RydWN0aW9uLFxuICBSZWRpcmVjdEluc3RydWN0aW9uLFxuICBVbnJlc29sdmVkSW5zdHJ1Y3Rpb24sXG4gIERlZmF1bHRJbnN0cnVjdGlvblxufSBmcm9tICcuL2luc3RydWN0aW9uJztcblxuaW1wb3J0IHtub3JtYWxpemVSb3V0ZUNvbmZpZywgYXNzZXJ0Q29tcG9uZW50RXhpc3RzfSBmcm9tICcuL3JvdXRlX2NvbmZpZy9yb3V0ZV9jb25maWdfbm9ybWFsaXplcic7XG5pbXBvcnQge3BhcnNlciwgVXJsLCBjb252ZXJ0VXJsUGFyYW1zVG9BcnJheSwgcGF0aFNlZ21lbnRzVG9Vcmx9IGZyb20gJy4vdXJsX3BhcnNlcic7XG5pbXBvcnQge0dlbmVyYXRlZFVybH0gZnJvbSAnLi9ydWxlcy9yb3V0ZV9wYXRocy9yb3V0ZV9wYXRoJztcblxudmFyIF9yZXNvbHZlVG9OdWxsID0gUHJvbWlzZVdyYXBwZXIucmVzb2x2ZTxJbnN0cnVjdGlvbj4obnVsbCk7XG5cbi8vIEEgTGlua0l0ZW1BcnJheSBpcyBhbiBhcnJheSwgd2hpY2ggZGVzY3JpYmVzIGEgc2V0IG9mIHJvdXRlc1xuLy8gVGhlIGl0ZW1zIGluIHRoZSBhcnJheSBhcmUgZm91bmQgaW4gZ3JvdXBzOlxuLy8gLSB0aGUgZmlyc3QgaXRlbSBpcyB0aGUgbmFtZSBvZiB0aGUgcm91dGVcbi8vIC0gdGhlIG5leHQgaXRlbXMgYXJlOlxuLy8gICAtIGFuIG9iamVjdCBjb250YWluaW5nIHBhcmFtZXRlcnNcbi8vICAgLSBvciBhbiBhcnJheSBkZXNjcmliaW5nIGFuIGF1eCByb3V0ZVxuLy8gZXhwb3J0IHR5cGUgTGlua1JvdXRlSXRlbSA9IHN0cmluZyB8IE9iamVjdDtcbi8vIGV4cG9ydCB0eXBlIExpbmtJdGVtID0gTGlua1JvdXRlSXRlbSB8IEFycmF5PExpbmtSb3V0ZUl0ZW0+O1xuLy8gZXhwb3J0IHR5cGUgTGlua0l0ZW1BcnJheSA9IEFycmF5PExpbmtJdGVtPjtcblxuLyoqXG4gKiBUb2tlbiB1c2VkIHRvIGJpbmQgdGhlIGNvbXBvbmVudCB3aXRoIHRoZSB0b3AtbGV2ZWwge0BsaW5rIFJvdXRlQ29uZmlnfXMgZm9yIHRoZVxuICogYXBwbGljYXRpb24uXG4gKlxuICogIyMjIEV4YW1wbGUgKFtsaXZlIGRlbW9dKGh0dHA6Ly9wbG5rci5jby9lZGl0L2lSVVA4QjVPVWJ4Q1dRM0FjSURtKSlcbiAqXG4gKiBgYGBcbiAqIGltcG9ydCB7Q29tcG9uZW50fSBmcm9tICdhbmd1bGFyMi9jb3JlJztcbiAqIGltcG9ydCB7XG4gKiAgIFJPVVRFUl9ESVJFQ1RJVkVTLFxuICogICBST1VURVJfUFJPVklERVJTLFxuICogICBSb3V0ZUNvbmZpZ1xuICogfSBmcm9tICdhbmd1bGFyMi9yb3V0ZXInO1xuICpcbiAqIEBDb21wb25lbnQoe2RpcmVjdGl2ZXM6IFtST1VURVJfRElSRUNUSVZFU119KVxuICogQFJvdXRlQ29uZmlnKFtcbiAqICB7Li4ufSxcbiAqIF0pXG4gKiBjbGFzcyBBcHBDbXAge1xuICogICAvLyAuLi5cbiAqIH1cbiAqXG4gKiBib290c3RyYXAoQXBwQ21wLCBbUk9VVEVSX1BST1ZJREVSU10pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjb25zdCBST1VURVJfUFJJTUFSWV9DT01QT05FTlQ6IE9wYXF1ZVRva2VuID1cbiAgICBDT05TVF9FWFBSKG5ldyBPcGFxdWVUb2tlbignUm91dGVyUHJpbWFyeUNvbXBvbmVudCcpKTtcblxuXG4vKipcbiAqIFRoZSBSb3V0ZVJlZ2lzdHJ5IGhvbGRzIHJvdXRlIGNvbmZpZ3VyYXRpb25zIGZvciBlYWNoIGNvbXBvbmVudCBpbiBhbiBBbmd1bGFyIGFwcC5cbiAqIEl0IGlzIHJlc3BvbnNpYmxlIGZvciBjcmVhdGluZyBJbnN0cnVjdGlvbnMgZnJvbSBVUkxzLCBhbmQgZ2VuZXJhdGluZyBVUkxzIGJhc2VkIG9uIHJvdXRlIGFuZFxuICogcGFyYW1ldGVycy5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFJvdXRlUmVnaXN0cnkge1xuICBwcml2YXRlIF9ydWxlcyA9IG5ldyBNYXA8YW55LCBSdWxlU2V0PigpO1xuXG4gIGNvbnN0cnVjdG9yKEBJbmplY3QoUk9VVEVSX1BSSU1BUllfQ09NUE9ORU5UKSBwcml2YXRlIF9yb290Q29tcG9uZW50OiBUeXBlKSB7fVxuXG4gIC8qKlxuICAgKiBHaXZlbiBhIGNvbXBvbmVudCBhbmQgYSBjb25maWd1cmF0aW9uIG9iamVjdCwgYWRkIHRoZSByb3V0ZSB0byB0aGlzIHJlZ2lzdHJ5XG4gICAqL1xuICBjb25maWcocGFyZW50Q29tcG9uZW50OiBhbnksIGNvbmZpZzogUm91dGVEZWZpbml0aW9uKTogdm9pZCB7XG4gICAgY29uZmlnID0gbm9ybWFsaXplUm91dGVDb25maWcoY29uZmlnLCB0aGlzKTtcblxuICAgIC8vIHRoaXMgaXMgaGVyZSBiZWNhdXNlIERhcnQgdHlwZSBndWFyZCByZWFzb25zXG4gICAgaWYgKGNvbmZpZyBpbnN0YW5jZW9mIFJvdXRlKSB7XG4gICAgICBhc3NlcnRDb21wb25lbnRFeGlzdHMoY29uZmlnLmNvbXBvbmVudCwgY29uZmlnLnBhdGgpO1xuICAgIH0gZWxzZSBpZiAoY29uZmlnIGluc3RhbmNlb2YgQXV4Um91dGUpIHtcbiAgICAgIGFzc2VydENvbXBvbmVudEV4aXN0cyhjb25maWcuY29tcG9uZW50LCBjb25maWcucGF0aCk7XG4gICAgfVxuXG4gICAgdmFyIHJ1bGVzID0gdGhpcy5fcnVsZXMuZ2V0KHBhcmVudENvbXBvbmVudCk7XG5cbiAgICBpZiAoaXNCbGFuayhydWxlcykpIHtcbiAgICAgIHJ1bGVzID0gbmV3IFJ1bGVTZXQoKTtcbiAgICAgIHRoaXMuX3J1bGVzLnNldChwYXJlbnRDb21wb25lbnQsIHJ1bGVzKTtcbiAgICB9XG5cbiAgICB2YXIgdGVybWluYWwgPSBydWxlcy5jb25maWcoY29uZmlnKTtcblxuICAgIGlmIChjb25maWcgaW5zdGFuY2VvZiBSb3V0ZSkge1xuICAgICAgaWYgKHRlcm1pbmFsKSB7XG4gICAgICAgIGFzc2VydFRlcm1pbmFsQ29tcG9uZW50KGNvbmZpZy5jb21wb25lbnQsIGNvbmZpZy5wYXRoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY29uZmlnRnJvbUNvbXBvbmVudChjb25maWcuY29tcG9uZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVhZHMgdGhlIGFubm90YXRpb25zIG9mIGEgY29tcG9uZW50IGFuZCBjb25maWd1cmVzIHRoZSByZWdpc3RyeSBiYXNlZCBvbiB0aGVtXG4gICAqL1xuICBjb25maWdGcm9tQ29tcG9uZW50KGNvbXBvbmVudDogYW55KTogdm9pZCB7XG4gICAgaWYgKCFpc1R5cGUoY29tcG9uZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIERvbid0IHJlYWQgdGhlIGFubm90YXRpb25zIGZyb20gYSB0eXBlIG1vcmUgdGhhbiBvbmNlIOKAk1xuICAgIC8vIHRoaXMgcHJldmVudHMgYW4gaW5maW5pdGUgbG9vcCBpZiBhIGNvbXBvbmVudCByb3V0ZXMgcmVjdXJzaXZlbHkuXG4gICAgaWYgKHRoaXMuX3J1bGVzLmhhcyhjb21wb25lbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBhbm5vdGF0aW9ucyA9IHJlZmxlY3Rvci5hbm5vdGF0aW9ucyhjb21wb25lbnQpO1xuICAgIGlmIChpc1ByZXNlbnQoYW5ub3RhdGlvbnMpKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFubm90YXRpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBhbm5vdGF0aW9uID0gYW5ub3RhdGlvbnNbaV07XG5cbiAgICAgICAgaWYgKGFubm90YXRpb24gaW5zdGFuY2VvZiBSb3V0ZUNvbmZpZykge1xuICAgICAgICAgIGxldCByb3V0ZUNmZ3M6IFJvdXRlRGVmaW5pdGlvbltdID0gYW5ub3RhdGlvbi5jb25maWdzO1xuICAgICAgICAgIHJvdXRlQ2Zncy5mb3JFYWNoKGNvbmZpZyA9PiB0aGlzLmNvbmZpZyhjb21wb25lbnQsIGNvbmZpZykpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogR2l2ZW4gYSBVUkwgYW5kIGEgcGFyZW50IGNvbXBvbmVudCwgcmV0dXJuIHRoZSBtb3N0IHNwZWNpZmljIGluc3RydWN0aW9uIGZvciBuYXZpZ2F0aW5nXG4gICAqIHRoZSBhcHBsaWNhdGlvbiBpbnRvIHRoZSBzdGF0ZSBzcGVjaWZpZWQgYnkgdGhlIHVybFxuICAgKi9cbiAgcmVjb2duaXplKHVybDogc3RyaW5nLCBhbmNlc3Rvckluc3RydWN0aW9uczogSW5zdHJ1Y3Rpb25bXSk6IFByb21pc2U8SW5zdHJ1Y3Rpb24+IHtcbiAgICB2YXIgcGFyc2VkVXJsID0gcGFyc2VyLnBhcnNlKHVybCk7XG4gICAgcmV0dXJuIHRoaXMuX3JlY29nbml6ZShwYXJzZWRVcmwsIFtdKTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIFJlY29nbml6ZXMgYWxsIHBhcmVudC1jaGlsZCByb3V0ZXMsIGJ1dCBjcmVhdGVzIHVucmVzb2x2ZWQgYXV4aWxpYXJ5IHJvdXRlc1xuICAgKi9cbiAgcHJpdmF0ZSBfcmVjb2duaXplKHBhcnNlZFVybDogVXJsLCBhbmNlc3Rvckluc3RydWN0aW9uczogSW5zdHJ1Y3Rpb25bXSxcbiAgICAgICAgICAgICAgICAgICAgIF9hdXggPSBmYWxzZSk6IFByb21pc2U8SW5zdHJ1Y3Rpb24+IHtcbiAgICB2YXIgcGFyZW50SW5zdHJ1Y3Rpb24gPSBMaXN0V3JhcHBlci5sYXN0KGFuY2VzdG9ySW5zdHJ1Y3Rpb25zKTtcbiAgICB2YXIgcGFyZW50Q29tcG9uZW50ID0gaXNQcmVzZW50KHBhcmVudEluc3RydWN0aW9uKSA/IHBhcmVudEluc3RydWN0aW9uLmNvbXBvbmVudC5jb21wb25lbnRUeXBlIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3Jvb3RDb21wb25lbnQ7XG5cbiAgICB2YXIgcnVsZ