UNPKG

angular2

Version:

Angular 2 - a web framework for modern web apps

235 lines 34.8 kB
import { RegExpWrapper, StringWrapper, isPresent, isBlank } from 'angular2/src/facade/lang'; import { BaseException } from 'angular2/src/facade/exceptions'; import { StringMapWrapper } from 'angular2/src/facade/collection'; import { RootUrl, serializeParams } from './url_parser'; class TouchMap { constructor(map) { this.map = {}; this.keys = {}; if (isPresent(map)) { StringMapWrapper.forEach(map, (value, key) => { this.map[key] = isPresent(value) ? value.toString() : null; this.keys[key] = true; }); } } get(key) { StringMapWrapper.delete(this.keys, key); return this.map[key]; } getUnused() { var unused = {}; var keys = StringMapWrapper.keys(this.keys); keys.forEach(key => unused[key] = StringMapWrapper.get(this.map, key)); return unused; } } function normalizeString(obj) { if (isBlank(obj)) { return null; } else { return obj.toString(); } } class ContinuationSegment { constructor() { this.name = ''; } generate(params) { return ''; } match(path) { return true; } } class StaticSegment { constructor(path) { this.path = path; this.name = ''; } match(path) { return path == this.path; } generate(params) { return this.path; } } class DynamicSegment { constructor(name) { this.name = name; } match(path) { return path.length > 0; } generate(params) { if (!StringMapWrapper.contains(params.map, this.name)) { throw new BaseException(`Route generator for '${this.name}' was not included in parameters passed.`); } return normalizeString(params.get(this.name)); } } class StarSegment { constructor(name) { this.name = name; } match(path) { return true; } generate(params) { return normalizeString(params.get(this.name)); } } var paramMatcher = /^:([^\/]+)$/g; var wildcardMatcher = /^\*([^\/]+)$/g; function parsePathString(route) { // normalize route as not starting with a "/". Recognition will // also normalize. if (route.startsWith("/")) { route = route.substring(1); } var segments = splitBySlash(route); var results = []; var specificity = 0; // The "specificity" of a path is used to determine which route is used when multiple routes match // a URL. // Static segments (like "/foo") are the most specific, followed by dynamic segments (like // "/:id"). Star segments // add no specificity. Segments at the start of the path are more specific than proceeding ones. // The code below uses place values to combine the different types of segments into a single // integer that we can // sort later. Each static segment is worth hundreds of points of specificity (10000, 9900, ..., // 200), and each // dynamic segment is worth single points of specificity (100, 99, ... 2). if (segments.length > 98) { throw new BaseException(`'${route}' has more than the maximum supported number of segments.`); } var limit = segments.length - 1; for (var i = 0; i <= limit; i++) { var segment = segments[i], match; if (isPresent(match = RegExpWrapper.firstMatch(paramMatcher, segment))) { results.push(new DynamicSegment(match[1])); specificity += (100 - i); } else if (isPresent(match = RegExpWrapper.firstMatch(wildcardMatcher, segment))) { results.push(new StarSegment(match[1])); } else if (segment == '...') { if (i < limit) { throw new BaseException(`Unexpected "..." before the end of the path for "${route}".`); } results.push(new ContinuationSegment()); } else { results.push(new StaticSegment(segment)); specificity += 100 * (100 - i); } } var result = StringMapWrapper.create(); StringMapWrapper.set(result, 'segments', results); StringMapWrapper.set(result, 'specificity', specificity); return result; } // this function is used to determine whether a route config path like `/foo/:id` collides with // `/foo/:name` function pathDslHash(segments) { return segments.map((segment) => { if (segment instanceof StarSegment) { return '*'; } else if (segment instanceof ContinuationSegment) { return '...'; } else if (segment instanceof DynamicSegment) { return ':'; } else if (segment instanceof StaticSegment) { return segment.path; } }) .join('/'); } function splitBySlash(url) { return url.split('/'); } var RESERVED_CHARS = RegExpWrapper.create('//|\\(|\\)|;|\\?|='); function assertPath(path) { if (StringWrapper.contains(path, '#')) { throw new BaseException(`Path "${path}" should not include "#". Use "HashLocationStrategy" instead.`); } var illegalCharacter = RegExpWrapper.firstMatch(RESERVED_CHARS, path); if (isPresent(illegalCharacter)) { throw new BaseException(`Path "${path}" contains "${illegalCharacter[0]}" which is not allowed in a route config.`); } } /** * Parses a URL string using a given matcher DSL, and generates URLs from param maps */ export class PathRecognizer { constructor(path) { this.path = path; this.terminal = true; assertPath(path); var parsed = parsePathString(path); this._segments = parsed['segments']; this.specificity = parsed['specificity']; this.hash = pathDslHash(this._segments); var lastSegment = this._segments[this._segments.length - 1]; this.terminal = !(lastSegment instanceof ContinuationSegment); } recognize(beginningSegment) { var nextSegment = beginningSegment; var currentSegment; var positionalParams = {}; var captured = []; for (var i = 0; i < this._segments.length; i += 1) { var segment = this._segments[i]; currentSegment = nextSegment; if (segment instanceof ContinuationSegment) { break; } if (isPresent(currentSegment)) { captured.push(currentSegment.path); // the star segment consumes all of the remaining URL, including matrix params if (segment instanceof StarSegment) { positionalParams[segment.name] = currentSegment.toString(); nextSegment = null; break; } if (segment instanceof DynamicSegment) { positionalParams[segment.name] = currentSegment.path; } else if (!segment.match(currentSegment.path)) { return null; } nextSegment = currentSegment.child; } else if (!segment.match('')) { return null; } } if (this.terminal && isPresent(nextSegment)) { return null; } var urlPath = captured.join('/'); var auxiliary; var urlParams; var allParams; if (isPresent(currentSegment)) { // If this is the root component, read query params. Otherwise, read matrix params. var paramsSegment = beginningSegment instanceof RootUrl ? beginningSegment : currentSegment; allParams = isPresent(paramsSegment.params) ? StringMapWrapper.merge(paramsSegment.params, positionalParams) : positionalParams; urlParams = serializeParams(paramsSegment.params); auxiliary = currentSegment.auxiliary; } else { allParams = positionalParams; auxiliary = []; urlParams = []; } return { urlPath, urlParams, allParams, auxiliary, nextSegment }; } generate(params) { var paramTokens = new TouchMap(params); var path = []; for (var i = 0; i < this._segments.length; i++) { let segment = this._segments[i]; if (!(segment instanceof ContinuationSegment)) { path.push(segment.generate(paramTokens)); } } var urlPath = path.join('/'); var nonPositionalParams = paramTokens.getUnused(); var urlParams = serializeParams(nonPositionalParams); return { urlPath, urlParams }; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aF9yZWNvZ25pemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYW5ndWxhcjIvc3JjL3JvdXRlci9wYXRoX3JlY29nbml6ZXIudHMiXSwibmFtZXMiOlsiVG91Y2hNYXAiLCJUb3VjaE1hcC5jb25zdHJ1Y3RvciIsIlRvdWNoTWFwLmdldCIsIlRvdWNoTWFwLmdldFVudXNlZCIsIm5vcm1hbGl6ZVN0cmluZyIsIkNvbnRpbnVhdGlvblNlZ21lbnQiLCJDb250aW51YXRpb25TZWdtZW50LmNvbnN0cnVjdG9yIiwiQ29udGludWF0aW9uU2VnbWVudC5nZW5lcmF0ZSIsIkNvbnRpbnVhdGlvblNlZ21lbnQubWF0Y2giLCJTdGF0aWNTZWdtZW50IiwiU3RhdGljU2VnbWVudC5jb25zdHJ1Y3RvciIsIlN0YXRpY1NlZ21lbnQubWF0Y2giLCJTdGF0aWNTZWdtZW50LmdlbmVyYXRlIiwiRHluYW1pY1NlZ21lbnQiLCJEeW5hbWljU2VnbWVudC5jb25zdHJ1Y3RvciIsIkR5bmFtaWNTZWdtZW50Lm1hdGNoIiwiRHluYW1pY1NlZ21lbnQuZ2VuZXJhdGUiLCJTdGFyU2VnbWVudCIsIlN0YXJTZWdtZW50LmNvbnN0cnVjdG9yIiwiU3RhclNlZ21lbnQubWF0Y2giLCJTdGFyU2VnbWVudC5nZW5lcmF0ZSIsInBhcnNlUGF0aFN0cmluZyIsInBhdGhEc2xIYXNoIiwic3BsaXRCeVNsYXNoIiwiYXNzZXJ0UGF0aCIsIlBhdGhSZWNvZ25pemVyIiwiUGF0aFJlY29nbml6ZXIuY29uc3RydWN0b3IiLCJQYXRoUmVjb2duaXplci5yZWNvZ25pemUiLCJQYXRoUmVjb2duaXplci5nZW5lcmF0ZSJdLCJtYXBwaW5ncyI6Ik9BQU8sRUFFTCxhQUFhLEVBRWIsYUFBYSxFQUNiLFNBQVMsRUFDVCxPQUFPLEVBQ1IsTUFBTSwwQkFBMEI7T0FDMUIsRUFBQyxhQUFhLEVBQW1CLE1BQU0sZ0NBQWdDO09BQ3ZFLEVBQWtCLGdCQUFnQixFQUFDLE1BQU0sZ0NBQWdDO09BRXpF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QUFDQTtZQUMvQ0EsSUFBSUEsT0FBT0EsR0FBR0EsSUFBSUEsQ0FBQ0EsU0FBU0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7WUFDaENBLEVBQUVBLENBQUNBLENBQUNBLENBQUNBLENBQUNBLE9BQU9BLFlBQVlBLG1CQUFtQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7Z0JBQzlDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxPQUFPQSxDQUFDQSxRQUFRQSxDQUFDQSxXQUFXQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUMzQ0EsQ0FBQ0E7UUFDSEEsQ0FBQ0E7UUFDREEsSUFBSUEsT0FBT0EsR0FBR0EsSUFBSUEsQ0FBQ0EsSUFBSUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsQ0FBQ0E7UUFFN0JBLElBQUlBLG1CQUFtQkEsR0FBR0EsV0FBV0EsQ0FBQ0EsU0FBU0EsRUFBRUEsQ0FBQ0E7UUFDbERBLElBQUlBLFNBQVNBLEdBQUdBLGVBQWVBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsQ0FBQ0E7UUFFckRBLE1BQU1BLENBQUNBLEVBQUNBLE9BQU9BLEVBQUVBLFNBQVNBLEVBQUNBLENBQUNBO0lBQzlCQSxDQUFDQTtBQUNISCxDQUFDQTtBQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgUmVnRXhwLFxuICBSZWdFeHBXcmFwcGVyLFxuICBSZWdFeHBNYXRjaGVyV3JhcHBlcixcbiAgU3RyaW5nV3JhcHBlcixcbiAgaXNQcmVzZW50LFxuICBpc0JsYW5rXG59IGZyb20gJ2FuZ3VsYXIyL3NyYy9mYWNhZGUvbGFuZyc7XG5pbXBvcnQge0Jhc2VFeGNlcHRpb24sIFdyYXBwZWRFeGNlcHRpb259IGZyb20gJ2FuZ3VsYXIyL3NyYy9mYWNhZGUvZXhjZXB0aW9ucyc7XG5pbXBvcnQge01hcCwgTWFwV3JhcHBlciwgU3RyaW5nTWFwV3JhcHBlcn0gZnJvbSAnYW5ndWxhcjIvc3JjL2ZhY2FkZS9jb2xsZWN0aW9uJztcblxuaW1wb3J0IHtVcmwsIFJvb3RVcmwsIHNlcmlhbGl6ZVBhcmFtc30gZnJvbSAnLi91cmxfcGFyc2VyJztcblxuY2xhc3MgVG91Y2hNYXAge1xuICBtYXA6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9ID0ge307XG4gIGtleXM6IHtba2V5OiBzdHJpbmddOiBib29sZWFufSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKG1hcDoge1trZXk6IHN0cmluZ106IGFueX0pIHtcbiAgICBpZiAoaXNQcmVzZW50KG1hcCkpIHtcbiAgICAgIFN0cmluZ01hcFdyYXBwZXIuZm9yRWFjaChtYXAsICh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgIHRoaXMubWFwW2tleV0gPSBpc1ByZXNlbnQodmFsdWUpID8gdmFsdWUudG9TdHJpbmcoKSA6IG51bGw7XG4gICAgICAgIHRoaXMua2V5c1trZXldID0gdHJ1ZTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGdldChrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgU3RyaW5nTWFwV3JhcHBlci5kZWxldGUodGhpcy5rZXlzLCBrZXkpO1xuICAgIHJldHVybiB0aGlzLm1hcFtrZXldO1xuICB9XG5cbiAgZ2V0VW51c2VkKCk6IHtba2V5OiBzdHJpbmddOiBhbnl9IHtcbiAgICB2YXIgdW51c2VkOiB7W2tleTogc3RyaW5nXTogYW55fSA9IHt9O1xuICAgIHZhciBrZXlzID0gU3RyaW5nTWFwV3JhcHBlci5rZXlzKHRoaXMua2V5cyk7XG4gICAga2V5cy5mb3JFYWNoKGtleSA9PiB1bnVzZWRba2V5XSA9IFN0cmluZ01hcFdyYXBwZXIuZ2V0KHRoaXMubWFwLCBrZXkpKTtcbiAgICByZXR1cm4gdW51c2VkO1xuICB9XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVN0cmluZyhvYmo6IGFueSk6IHN0cmluZyB7XG4gIGlmIChpc0JsYW5rKG9iaikpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gb2JqLnRvU3RyaW5nKCk7XG4gIH1cbn1cblxuaW50ZXJmYWNlIFNlZ21lbnQge1xuICBuYW1lOiBzdHJpbmc7XG4gIGdlbmVyYXRlKHBhcmFtczogVG91Y2hNYXApOiBzdHJpbmc7XG4gIG1hdGNoKHBhdGg6IHN0cmluZyk6IGJvb2xlYW47XG59XG5cbmNsYXNzIENvbnRpbnVhdGlvblNlZ21lbnQgaW1wbGVtZW50cyBTZWdtZW50IHtcbiAgbmFtZTogc3RyaW5nID0gJyc7XG4gIGdlbmVyYXRlKHBhcmFtczogVG91Y2hNYXApOiBzdHJpbmcgeyByZXR1cm4gJyc7IH1cbiAgbWF0Y2gocGF0aDogc3RyaW5nKTogYm9vbGVhbiB7IHJldHVybiB0cnVlOyB9XG59XG5cbmNsYXNzIFN0YXRpY1NlZ21lbnQgaW1wbGVtZW50cyBTZWdtZW50IHtcbiAgbmFtZTogc3RyaW5nID0gJyc7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBwYXRoOiBzdHJpbmcpIHt9XG4gIG1hdGNoKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4geyByZXR1cm4gcGF0aCA9PSB0aGlzLnBhdGg7IH1cbiAgZ2VuZXJhdGUocGFyYW1zOiBUb3VjaE1hcCk6IHN0cmluZyB7IHJldHVybiB0aGlzLnBhdGg7IH1cbn1cblxuY2xhc3MgRHluYW1pY1NlZ21lbnQgaW1wbGVtZW50cyBTZWdtZW50IHtcbiAgY29uc3RydWN0b3IocHVibGljIG5hbWU6IHN0cmluZykge31cbiAgbWF0Y2gocGF0aDogc3RyaW5nKTogYm9vbGVhbiB7IHJldHVybiBwYXRoLmxlbmd0aCA+IDA7IH1cbiAgZ2VuZXJhdGUocGFyYW1zOiBUb3VjaE1hcCk6IHN0cmluZyB7XG4gICAgaWYgKCFTdHJpbmdNYXBXcmFwcGVyLmNvbnRhaW5zKHBhcmFtcy5tYXAsIHRoaXMubmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBCYXNlRXhjZXB0aW9uKFxuICAgICAgICAgIGBSb3V0ZSBnZW5lcmF0b3IgZm9yICcke3RoaXMubmFtZX0nIHdhcyBub3QgaW5jbHVkZWQgaW4gcGFyYW1ldGVycyBwYXNzZWQuYCk7XG4gICAgfVxuICAgIHJldHVybiBub3JtYWxpemVTdHJpbmcocGFyYW1zLmdldCh0aGlzLm5hbWUpKTtcbiAgfVxufVxuXG5cbmNsYXNzIFN0YXJTZWdtZW50IGltcGxlbWVudHMgU2VnbWVudCB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBuYW1lOiBzdHJpbmcpIHt9XG4gIG1hdGNoKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4geyByZXR1cm4gdHJ1ZTsgfVxuICBnZW5lcmF0ZShwYXJhbXM6IFRvdWNoTWFwKTogc3RyaW5nIHsgcmV0dXJuIG5vcm1hbGl6ZVN0cmluZyhwYXJhbXMuZ2V0KHRoaXMubmFtZSkpOyB9XG59XG5cblxudmFyIHBhcmFtTWF0Y2hlciA9IC9eOihbXlxcL10rKSQvZztcbnZhciB3aWxkY2FyZE1hdGNoZXIgPSAvXlxcKihbXlxcL10rKSQvZztcblxuZnVuY3Rpb24gcGFyc2VQYXRoU3RyaW5nKHJvdXRlOiBzdHJpbmcpOiB7W2tleTogc3RyaW5nXTogYW55fSB7XG4gIC8vIG5vcm1hbGl6ZSByb3V0ZSBhcyBub3Qgc3RhcnRpbmcgd2l0aCBhIFwiL1wiLiBSZWNvZ25pdGlvbiB3aWxsXG4gIC8vIGFsc28gbm9ybWFsaXplLlxuICBpZiAocm91dGUuc3RhcnRzV2l0aChcIi9cIikpIHtcbiAgICByb3V0ZSA9IHJvdXRlLnN1YnN0cmluZygxKTtcbiAgfVxuXG4gIHZhciBzZWdtZW50cyA9IHNwbGl0QnlTbGFzaChyb3V0ZSk7XG4gIHZhciByZXN1bHRzID0gW107XG4gIHZhciBzcGVjaWZpY2l0eSA9IDA7XG5cbiAgLy8gVGhlIFwic3BlY2lmaWNpdHlcIiBvZiBhIHBhdGggaXMgdXNlZCB0byBkZXRlcm1pbmUgd2hpY2ggcm91dGUgaXMgdXNlZCB3aGVuIG11bHRpcGxlIHJvdXRlcyBtYXRjaFxuICAvLyBhIFVSTC5cbiAgLy8gU3RhdGljIHNlZ21lbnRzIChsaWtlIFwiL2Zvb1wiKSBhcmUgdGhlIG1vc3Qgc3BlY2lmaWMsIGZvbGxvd2VkIGJ5IGR5bmFtaWMgc2VnbWVudHMgKGxpa2VcbiAgLy8gXCIvOmlkXCIpLiBTdGFyIHNlZ21lbnRzXG4gIC8vIGFkZCBubyBzcGVjaWZpY2l0eS4gU2VnbWVudHMgYXQgdGhlIHN0YXJ0IG9mIHRoZSBwYXRoIGFyZSBtb3JlIHNwZWNpZmljIHRoYW4gcHJvY2VlZGluZyBvbmVzLlxuICAvLyBUaGUgY29kZSBiZWxvdyB1c2VzIHBsYWNlIHZhbHVlcyB0byBjb21iaW5lIHRoZSBkaWZmZXJlbnQgdHlwZXMgb2Ygc2VnbWVudHMgaW50byBhIHNpbmdsZVxuICAvLyBpbnRlZ2VyIHRoYXQgd2UgY2FuXG4gIC8vIHNvcnQgbGF0ZXIuIEVhY2ggc3RhdGljIHNlZ21lbnQgaXMgd29ydGggaHVuZHJlZHMgb2YgcG9pbnRzIG9mIHNwZWNpZmljaXR5ICgxMDAwMCwgOTkwMCwgLi4uLFxuICAvLyAyMDApLCBhbmQgZWFjaFxuICAvLyBkeW5hbWljIHNlZ21lbnQgaXMgd29ydGggc2luZ2xlIHBvaW50cyBvZiBzcGVjaWZpY2l0eSAoMTAwLCA5OSwgLi4uIDIpLlxuICBpZiAoc2VnbWVudHMubGVuZ3RoID4gOTgpIHtcbiAgICB0aHJvdyBuZXcgQmFzZUV4Y2VwdGlvbihgJyR7cm91dGV9JyBoYXMgbW9yZSB0aGFuIHRoZSBtYXhpbXVtIHN1cHBvcnRlZCBudW1iZXIgb2Ygc2VnbWVudHMuYCk7XG4gIH1cblxuICB2YXIgbGltaXQgPSBzZWdtZW50cy5sZW5ndGggLSAxO1xuICBmb3IgKHZhciBpID0gMDsgaSA8PSBsaW1pdDsgaSsrKSB7XG4gICAgdmFyIHNlZ21lbnQgPSBzZWdtZW50c1tpXSwgbWF0Y2g7XG5cbiAgICBpZiAoaXNQcmVzZW50KG1hdGNoID0gUmVnRXhwV3JhcHBlci5maXJzdE1hdGNoKHBhcmFtTWF0Y2hlciwgc2VnbWVudCkpKSB7XG4gICAgICByZXN1bHRzLnB1c2gobmV3IER5bmFtaWNTZWdtZW50KG1hdGNoWzFdKSk7XG4gICAgICBzcGVjaWZpY2l0eSArPSAoMTAwIC0gaSk7XG4gICAgfSBlbHNlIGlmIChpc1ByZXNlbnQobWF0Y2ggPSBSZWdFeHBXcmFwcGVyLmZpcnN0TWF0Y2god2lsZGNhcmRNYXRjaGVyLCBzZWdtZW50KSkpIHtcbiAgICAgIHJlc3VsdHMucHVzaChuZXcgU3RhclNlZ21lbnQobWF0Y2hbMV0pKTtcbiAgICB9IGVsc2UgaWYgKHNlZ21lbnQgPT0gJy4uLicpIHtcbiAgICAgIGlmIChpIDwgbGltaXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEJhc2VFeGNlcHRpb24oYFVuZXhwZWN0ZWQgXCIuLi5cIiBiZWZvcmUgdGhlIGVuZCBvZiB0aGUgcGF0aCBmb3IgXCIke3JvdXRlfVwiLmApO1xuICAgICAgfVxuICAgICAgcmVzdWx0cy5wdXNoKG5ldyBDb250aW51YXRpb25TZWdtZW50KCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHRzLnB1c2gobmV3IFN0YXRpY1NlZ21lbnQoc2VnbWVudCkpO1xuICAgICAgc3BlY2lmaWNpdHkgKz0gMTAwICogKDEwMCAtIGkpO1xuICAgIH1cbiAgfVxuICB2YXIgcmVzdWx0ID0gU3RyaW5nTWFwV3JhcHBlci5jcmVhdGUoKTtcbiAgU3RyaW5nTWFwV3JhcHBlci5zZXQocmVzdWx0LCAnc2VnbWVudHMnLCByZXN1bHRzKTtcbiAgU3RyaW5nTWFwV3JhcHBlci5zZXQocmVzdWx0LCAnc3BlY2lmaWNpdHknLCBzcGVjaWZpY2l0eSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gaXMgdXNlZCB0byBkZXRlcm1pbmUgd2hldGhlciBhIHJvdXRlIGNvbmZpZyBwYXRoIGxpa2UgYC9mb28vOmlkYCBjb2xsaWRlcyB3aXRoXG4vLyBgL2Zvby86bmFtZWBcbmZ1bmN0aW9uIHBhdGhEc2xIYXNoKHNlZ21lbnRzOiBTZWdtZW50W10pOiBzdHJpbmcge1xuICByZXR1cm4gc2VnbWVudHMubWFwKChzZWdtZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgaWYgKHNlZ21lbnQgaW5zdGFuY2VvZiBTdGFyU2VnbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICcqJztcbiAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNlZ21lbnQgaW5zdGFuY2VvZiBDb250aW51YXRpb25TZWdtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICByZXR1cm4gJy4uLic7XG4gICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzZWdtZW50IGluc3RhbmNlb2YgRHluYW1pY1NlZ21lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnOic7XG4gICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzZWdtZW50IGluc3RhbmNlb2YgU3RhdGljU2VnbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlZ21lbnQucGF0aDtcbiAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgIH0pXG4gICAgICAuam9pbignLycpO1xufVxuXG5mdW5jdGlvbiBzcGxpdEJ5U2xhc2godXJsOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIHJldHVybiB1cmwuc3BsaXQoJy8nKTtcbn1cblxudmFyIFJFU0VSVkVEX0NIQVJTID0gUmVnRXhwV3JhcHBlci5jcmVhdGUoJy8vfFxcXFwofFxcXFwpfDt8XFxcXD98PScpO1xuZnVuY3Rpb24gYXNzZXJ0UGF0aChwYXRoOiBzdHJpbmcpIHtcbiAgaWYgKFN0cmluZ1dyYXBwZXIuY29udGFpbnMocGF0aCwgJyMnKSkge1xuICAgIHRocm93IG5ldyBCYXNlRXhjZXB0aW9uKFxuICAgICAgICBgUGF0aCBcIiR7cGF0aH1cIiBzaG91bGQgbm90IGluY2x1ZGUgXCIjXCIuIFVzZSBcIkhhc2hMb2NhdGlvblN0cmF0ZWd5XCIgaW5zdGVhZC5gKTtcbiAgfVxuICB2YXIgaWxsZWdhbENoYXJhY3RlciA9IFJlZ0V4cFdyYXBwZXIuZmlyc3RNYXRjaChSRVNFUlZFRF9DSEFSUywgcGF0aCk7XG4gIGlmIChpc1ByZXNlbnQoaWxsZWdhbENoYXJhY3RlcikpIHtcbiAgICB0aHJvdyBuZXcgQmFzZUV4Y2VwdGlvbihcbiAgICAgICAgYFBhdGggXCIke3BhdGh9XCIgY29udGFpbnMgXCIke2lsbGVnYWxDaGFyYWN0ZXJbMF19XCIgd2hpY2ggaXMgbm90IGFsbG93ZWQgaW4gYSByb3V0ZSBjb25maWcuYCk7XG4gIH1cbn1cblxuXG4vKipcbiAqIFBhcnNlcyBhIFVSTCBzdHJpbmcgdXNpbmcgYSBnaXZlbiBtYXRjaGVyIERTTCwgYW5kIGdlbmVyYXRlcyBVUkxzIGZyb20gcGFyYW0gbWFwc1xuICovXG5leHBvcnQgY2xhc3MgUGF0aFJlY29nbml6ZXIge1xuICBwcml2YXRlIF9zZWdtZW50czogU2VnbWVudFtdO1xuICBzcGVjaWZpY2l0eTogbnVtYmVyO1xuICB0ZXJtaW5hbDogYm9vbGVhbiA9IHRydWU7XG4gIGhhc2g6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgcGF0aDogc3RyaW5nKSB7XG4gICAgYXNzZXJ0UGF0aChwYXRoKTtcbiAgICB2YXIgcGFyc2VkID0gcGFyc2VQYXRoU3RyaW5nKHBhdGgpO1xuXG4gICAgdGhpcy5fc2VnbWVudHMgPSBwYXJzZWRbJ3NlZ21lbnRzJ107XG4gICAgdGhpcy5zcGVjaWZpY2l0eSA9IHBhcnNlZFsnc3BlY2lmaWNpdHknXTtcbiAgICB0aGlzLmhhc2ggPSBwYXRoRHNsSGFzaCh0aGlzLl9zZWdtZW50cyk7XG5cbiAgICB2YXIgbGFzdFNlZ21lbnQgPSB0aGlzLl9zZWdtZW50c1t0aGlzLl9zZWdtZW50cy5sZW5ndGggLSAxXTtcbiAgICB0aGlzLnRlcm1pbmFsID0gIShsYXN0U2VnbWVudCBpbnN0YW5jZW9mIENvbnRpbnVhdGlvblNlZ21lbnQpO1xuICB9XG5cbiAgcmVjb2duaXplKGJlZ2lubmluZ1NlZ21lbnQ6IFVybCk6IHtba2V5OiBzdHJpbmddOiBhbnl9IHtcbiAgICB2YXIgbmV4dFNlZ21lbnQgPSBiZWdpbm5pbmdTZWdtZW50O1xuICAgIHZhciBjdXJyZW50U2VnbWVudDogVXJsO1xuICAgIHZhciBwb3NpdGlvbmFsUGFyYW1zID0ge307XG4gICAgdmFyIGNhcHR1cmVkID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX3NlZ21lbnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICB2YXIgc2VnbWVudCA9IHRoaXMuX3NlZ21lbnRzW2ldO1xuXG4gICAgICBjdXJyZW50U2VnbWVudCA9IG5leHRTZWdtZW50O1xuICAgICAgaWYgKHNlZ21lbnQgaW5zdGFuY2VvZiBDb250aW51YXRpb25TZWdtZW50KSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNQcmVzZW50KGN1cnJlbnRTZWdtZW50KSkge1xuICAgICAgICBjYXB0dXJlZC5wdXNoKGN1cnJlbnRTZWdtZW50LnBhdGgpO1xuXG4gICAgICAgIC8vIHRoZSBzdGFyIHNlZ21lbnQgY29uc3VtZXMgYWxsIG9mIHRoZSByZW1haW5pbmcgVVJMLCBpbmNsdWRpbmcgbWF0cml4IHBhcmFtc1xuICAgICAgICBpZiAoc2VnbWVudCBpbnN0YW5jZW9mIFN0YXJTZWdtZW50KSB7XG4gICAgICAgICAgcG9zaXRpb25hbFBhcmFtc1tzZWdtZW50Lm5hbWVdID0gY3VycmVudFNlZ21lbnQudG9TdHJpbmcoKTtcbiAgICAgICAgICBuZXh0U2VnbWVudCA9IG51bGw7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2VnbWVudCBpbnN0YW5jZW9mIER5bmFtaWNTZWdtZW50KSB7XG4gICAgICAgICAgcG9zaXRpb25hbFBhcmFtc1tzZWdtZW50Lm5hbWVdID0gY3VycmVudFNlZ21lbnQucGF0aDtcbiAgICAgICAgfSBlbHNlIGlmICghc2VnbWVudC5tYXRjaChjdXJyZW50U2VnbWVudC5wYXRoKSkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgbmV4dFNlZ21lbnQgPSBjdXJyZW50U2VnbWVudC5jaGlsZDtcbiAgICAgIH0gZWxzZSBpZiAoIXNlZ21lbnQubWF0Y2goJycpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnRlcm1pbmFsICYmIGlzUHJlc2VudChuZXh0U2VnbWVudCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHZhciB1cmxQYXRoID0gY2FwdHVyZWQuam9pbignLycpO1xuXG4gICAgdmFyIGF1eGlsaWFyeTtcbiAgICB2YXIgdXJsUGFyYW1zO1xuICAgIHZhciBhbGxQYXJhbXM7XG4gICAgaWYgKGlzUHJlc2VudChjdXJyZW50U2VnbWVudCkpIHtcbiAgICAgIC8vIElmIHRoaXMgaXMgdGhlIHJvb3QgY29tcG9uZW50LCByZWFkIHF1ZXJ5IHBhcmFtcy4gT3RoZXJ3aXNlLCByZWFkIG1hdHJpeCBwYXJhbXMuXG4gICAgICB2YXIgcGFyYW1zU2VnbWVudCA9IGJlZ2lubmluZ1NlZ21lbnQgaW5zdGFuY2VvZiBSb290VXJsID8gYmVnaW5uaW5nU2VnbWVudCA6IGN1cnJlbnRTZWdtZW50O1xuXG4gICAgICBhbGxQYXJhbXMgPSBpc1ByZXNlbnQocGFyYW1zU2VnbWVudC5wYXJhbXMpID9cbiAgICAgICAgICAgICAgICAgICAgICBTdHJpbmdNYXBXcmFwcGVyLm1lcmdlKHBhcmFtc1NlZ21lbnQucGFyYW1zLCBwb3NpdGlvbmFsUGFyYW1zKSA6XG4gICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25hbFBhcmFtcztcblxuICAgICAgdXJsUGFyYW1zID0gc2VyaWFsaXplUGFyYW1zKHBhcmFtc1NlZ21lbnQucGFyYW1zKTtcblxuXG4gICAgICBhdXhpbGlhcnkgPSBjdXJyZW50U2VnbWVudC5hdXhpbGlhcnk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFsbFBhcmFtcyA9IHBvc2l0aW9uYWxQYXJhbXM7XG4gICAgICBhdXhpbGlhcnkgPSBbXTtcbiAgICAgIHVybFBhcmFtcyA9IFtdO1xuICAgIH1cbiAgICByZXR1cm4ge3VybFBhdGgsIHVybFBhcmFtcywgYWxsUGFyYW1zLCBhdXhpbGlhcnksIG5leHRTZWdtZW50fTtcbiAgfVxuXG5cbiAgZ2VuZXJhdGUocGFyYW1zOiB7W2tleTogc3RyaW5nXTogYW55fSk6IHtba2V5OiBzdHJpbmddOiBhbnl9IHtcbiAgICB2YXIgcGFyYW1Ub2tlbnMgPSBuZXcgVG91Y2hNYXAocGFyYW1zKTtcblxuICAgIHZhciBwYXRoID0gW107XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuX3NlZ21lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgc2VnbWVudCA9IHRoaXMuX3NlZ21lbnRzW2ldO1xuICAgICAgaWYgKCEoc2VnbWVudCBpbnN0YW5jZW9mIENvbnRpbnVhdGlvblNlZ21lbnQpKSB7XG4gICAgICAgIHBhdGgucHVzaChzZWdtZW50LmdlbmVyYXRlKHBhcmFtVG9rZW5zKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHZhciB1cmxQYXRoID0gcGF0aC5qb2luKCcvJyk7XG5cbiAgICB2YXIgbm9uUG9zaXRpb25hbFBhcmFtcyA9IHBhcmFtVG9rZW5zLmdldFVudXNlZCgpO1xuICAgIHZhciB1cmxQYXJhbXMgPSBzZXJpYWxpemVQYXJhbXMobm9uUG9zaXRpb25hbFBhcmFtcyk7XG5cbiAgICByZXR1cm4ge3VybFBhdGgsIHVybFBhcmFtc307XG4gIH1cbn1cbiJdfQ==