angular2
Version:
Angular 2 - a web framework for modern web apps
242 lines • 36 kB
JavaScript
'use strict';var lang_1 = require('angular2/src/facade/lang');
var exceptions_1 = require('angular2/src/facade/exceptions');
var collection_1 = require('angular2/src/facade/collection');
var url_parser_1 = require('./url_parser');
var TouchMap = (function () {
function TouchMap(map) {
var _this = this;
this.map = {};
this.keys = {};
if (lang_1.isPresent(map)) {
collection_1.StringMapWrapper.forEach(map, function (value, key) {
_this.map[key] = lang_1.isPresent(value) ? value.toString() : null;
_this.keys[key] = true;
});
}
}
TouchMap.prototype.get = function (key) {
collection_1.StringMapWrapper.delete(this.keys, key);
return this.map[key];
};
TouchMap.prototype.getUnused = function () {
var _this = this;
var unused = {};
var keys = collection_1.StringMapWrapper.keys(this.keys);
keys.forEach(function (key) { return unused[key] = collection_1.StringMapWrapper.get(_this.map, key); });
return unused;
};
return TouchMap;
})();
function normalizeString(obj) {
if (lang_1.isBlank(obj)) {
return null;
}
else {
return obj.toString();
}
}
var ContinuationSegment = (function () {
function ContinuationSegment() {
this.name = '';
}
ContinuationSegment.prototype.generate = function (params) { return ''; };
ContinuationSegment.prototype.match = function (path) { return true; };
return ContinuationSegment;
})();
var StaticSegment = (function () {
function StaticSegment(path) {
this.path = path;
this.name = '';
}
StaticSegment.prototype.match = function (path) { return path == this.path; };
StaticSegment.prototype.generate = function (params) { return this.path; };
return StaticSegment;
})();
var DynamicSegment = (function () {
function DynamicSegment(name) {
this.name = name;
}
DynamicSegment.prototype.match = function (path) { return path.length > 0; };
DynamicSegment.prototype.generate = function (params) {
if (!collection_1.StringMapWrapper.contains(params.map, this.name)) {
throw new exceptions_1.BaseException("Route generator for '" + this.name + "' was not included in parameters passed.");
}
return normalizeString(params.get(this.name));
};
return DynamicSegment;
})();
var StarSegment = (function () {
function StarSegment(name) {
this.name = name;
}
StarSegment.prototype.match = function (path) { return true; };
StarSegment.prototype.generate = function (params) { return normalizeString(params.get(this.name)); };
return StarSegment;
})();
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 = '';
// a single slash (or "empty segment" is as specific as a static segment
if (segments.length == 0) {
specificity += '2';
}
// 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
// string that we can sort later. Each static segment is marked as a specificity of "2," each
// dynamic segment is worth "1" specificity, and stars are worth "0" specificity.
var limit = segments.length - 1;
for (var i = 0; i <= limit; i++) {
var segment = segments[i], match;
if (lang_1.isPresent(match = lang_1.RegExpWrapper.firstMatch(paramMatcher, segment))) {
results.push(new DynamicSegment(match[1]));
specificity += '1';
}
else if (lang_1.isPresent(match = lang_1.RegExpWrapper.firstMatch(wildcardMatcher, segment))) {
results.push(new StarSegment(match[1]));
specificity += '0';
}
else if (segment == '...') {
if (i < limit) {
throw new exceptions_1.BaseException("Unexpected \"...\" before the end of the path for \"" + route + "\".");
}
results.push(new ContinuationSegment());
}
else {
results.push(new StaticSegment(segment));
specificity += '2';
}
}
return { 'segments': results, 'specificity': specificity };
}
// this function is used to determine whether a route config path like `/foo/:id` collides with
// `/foo/:name`
function pathDslHash(segments) {
return segments.map(function (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 = lang_1.RegExpWrapper.create('//|\\(|\\)|;|\\?|=');
function assertPath(path) {
if (lang_1.StringWrapper.contains(path, '#')) {
throw new exceptions_1.BaseException("Path \"" + path + "\" should not include \"#\". Use \"HashLocationStrategy\" instead.");
}
var illegalCharacter = lang_1.RegExpWrapper.firstMatch(RESERVED_CHARS, path);
if (lang_1.isPresent(illegalCharacter)) {
throw new exceptions_1.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
*/
var PathRecognizer = (function () {
function PathRecognizer(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);
}
PathRecognizer.prototype.recognize = function (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 (lang_1.isPresent(currentSegment)) {
// the star segment consumes all of the remaining URL, including matrix params
if (segment instanceof StarSegment) {
positionalParams[segment.name] = currentSegment.toString();
captured.push(currentSegment.toString());
nextSegment = null;
break;
}
captured.push(currentSegment.path);
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 && lang_1.isPresent(nextSegment)) {
return null;
}
var urlPath = captured.join('/');
var auxiliary;
var urlParams;
var allParams;
if (lang_1.isPresent(currentSegment)) {
// If this is the root component, read query params. Otherwise, read matrix params.
var paramsSegment = beginningSegment instanceof url_parser_1.RootUrl ? beginningSegment : currentSegment;
allParams = lang_1.isPresent(paramsSegment.params) ?
collection_1.StringMapWrapper.merge(paramsSegment.params, positionalParams) :
positionalParams;
urlParams = url_parser_1.serializeParams(paramsSegment.params);
auxiliary = currentSegment.auxiliary;
}
else {
allParams = positionalParams;
auxiliary = [];
urlParams = [];
}
return { urlPath: urlPath, urlParams: urlParams, allParams: allParams, auxiliary: auxiliary, nextSegment: nextSegment };
};
PathRecognizer.prototype.generate = function (params) {
var paramTokens = new TouchMap(params);
var path = [];
for (var i = 0; i < this._segments.length; i++) {
var segment = this._segments[i];
if (!(segment instanceof ContinuationSegment)) {
path.push(segment.generate(paramTokens));
}
}
var urlPath = path.join('/');
var nonPositionalParams = paramTokens.getUnused();
var urlParams = url_parser_1.serializeParams(nonPositionalParams);
return { urlPath: urlPath, urlParams: urlParams };
};
return PathRecognizer;
})();
exports.PathRecognizer = PathRecognizer;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aF9yZWNvZ25pemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYW5ndWxhcjIvc3JjL3JvdXRlci9wYXRoX3JlY29nbml6ZXIudHMiXSwibmFtZXMiOlsiVG91Y2hNYXAiLCJUb3VjaE1hcC5jb25zdHJ1Y3RvciIsIlRvdWNoTWFwLmdldCIsIlRvdWNoTWFwLmdldFVudXNlZCIsIm5vcm1hbGl6ZVN0cmluZyIsIkNvbnRpbnVhdGlvblNlZ21lbnQiLCJDb250aW51YXRpb25TZWdtZW50LmNvbnN0cnVjdG9yIiwiQ29udGludWF0aW9uU2VnbWVudC5nZW5lcmF0ZSIsIkNvbnRpbnVhdGlvblNlZ21lbnQubWF0Y2giLCJTdGF0aWNTZWdtZW50IiwiU3RhdGljU2VnbWVudC5jb25zdHJ1Y3RvciIsIlN0YXRpY1NlZ21lbnQubWF0Y2giLCJTdGF0aWNTZWdtZW50LmdlbmVyYXRlIiwiRHluYW1pY1NlZ21lbnQiLCJEeW5hbWljU2VnbWVudC5jb25zdHJ1Y3RvciIsIkR5bmFtaWNTZWdtZW50Lm1hdGNoIiwiRHluYW1pY1NlZ21lbnQuZ2VuZXJhdGUiLCJTdGFyU2VnbWVudCIsIlN0YXJTZWdtZW50LmNvbnN0cnVjdG9yIiwiU3RhclNlZ21lbnQubWF0Y2giLCJTdGFyU2VnbWVudC5nZW5lcmF0ZSIsInBhcnNlUGF0aFN0cmluZyIsInBhdGhEc2xIYXNoIiwic3BsaXRCeVNsYXNoIiwiYXNzZXJ0UGF0aCIsIlBhdGhSZWNvZ25pemVyIiwiUGF0aFJlY29nbml6ZXIuY29uc3RydWN0b3IiLCJQYXRoUmVjb2duaXplci5yZWNvZ25pemUiLCJQYXRoUmVjb2duaXplci5nZW5lcmF0ZSJdLCJtYXBwaW5ncyI6IkFBQUEscUJBT08sMEJBQTBCLENBQUMsQ0FBQTtBQUNsQywyQkFBOEMsZ0NBQWdDLENBQUMsQ0FBQTtBQUMvRSwyQkFBZ0QsZ0NBQWdDLENBQUMsQ0FBQTtBQUVqRiwyQkFBNEMsY0FBYyxDQUFDLENBQUE7QUFFM0Q7SUFJRUEsa0JBQVlBLEdB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LEdBQUdBLENBQUNBLEVBQUVBLENBQUNBLEdBQUdBLElBQUlBLENBQUNBLFNBQVNBLENBQUNBLE1BQU1BLEVBQUVBLENBQUNBLEVBQUVBLEVBQUVBLENBQUNBO1lBQy9DQSxJQUFJQSxPQUFPQSxHQUFHQSxJQUFJQSxDQUFDQSxTQUFTQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtZQUNoQ0EsRUFBRUEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsQ0FBQ0EsT0FBT0EsWUFBWUEsbUJBQW1CQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtnQkFDOUNBLElBQUlBLENBQUNBLElBQUlBLENBQUNBLE9BQU9BLENBQUNBLFFBQVFBLENBQUNBLFdBQVdBLENBQUNBLENBQUNBLENBQUNBO1lBQzNDQSxDQUFDQTtRQUNIQSxDQUFDQTtRQUNEQSxJQUFJQSxPQUFPQSxHQUFHQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQTtRQUU3QkEsSUFBSUEsbUJBQW1CQSxHQUFHQSxXQUFXQSxDQUFDQSxTQUFTQSxFQUFFQSxDQUFDQTtRQUNsREEsSUFBSUEsU0FBU0EsR0FBR0EsNEJBQWVBLENBQUNBLG1CQUFtQkEsQ0FBQ0EsQ0FBQ0E7UUFFckRBLE1BQU1BLENBQUNBLEVBQUNBLFNBQUFBLE9BQU9BLEVBQUVBLFdBQUFBLFNBQVNBLEVBQUNBLENBQUNBO0lBQzlCQSxDQUFDQTtJQUNISCxxQkFBQ0E7QUFBREEsQ0FBQ0EsQUF2R0QsSUF1R0M7QUF2R1ksc0JBQWMsaUJBdUcxQixDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgUmVnRXhwLFxuICBSZWdFeHBXcmFwcGVyLFxuICBSZWdFeHBNYXRjaGVyV3JhcHBlcixcbiAgU3RyaW5nV3JhcHBlcixcbiAgaXNQcmVzZW50LFxuICBpc0JsYW5rXG59IGZyb20gJ2FuZ3VsYXIyL3NyYy9mYWNhZGUvbGFuZyc7XG5pbXBvcnQge0Jhc2VFeGNlcHRpb24sIFdyYXBwZWRFeGNlcHRpb259IGZyb20gJ2FuZ3VsYXIyL3NyYy9mYWNhZGUvZXhjZXB0aW9ucyc7XG5pbXBvcnQge01hcCwgTWFwV3JhcHBlciwgU3RyaW5nTWFwV3JhcHBlcn0gZnJvbSAnYW5ndWxhcjIvc3JjL2ZhY2FkZS9jb2xsZWN0aW9uJztcblxuaW1wb3J0IHtVcmwsIFJvb3RVcmwsIHNlcmlhbGl6ZVBhcmFtc30gZnJvbSAnLi91cmxfcGFyc2VyJztcblxuY2xhc3MgVG91Y2hNYXAge1xuICBtYXA6IHtba2V5OiBzdHJpbmddOiBzdHJpbmd9ID0ge307XG4gIGtleXM6IHtba2V5OiBzdHJpbmddOiBib29sZWFufSA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKG1hcDoge1trZXk6IHN0cmluZ106IGFueX0pIHtcbiAgICBpZiAoaXNQcmVzZW50KG1hcCkpIHtcbiAgICAgIFN0cmluZ01hcFdyYXBwZXIuZm9yRWFjaChtYXAsICh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgIHRoaXMubWFwW2tleV0gPSBpc1ByZXNlbnQodmFsdWUpID8gdmFsdWUudG9TdHJpbmcoKSA6IG51bGw7XG4gICAgICAgIHRoaXMua2V5c1trZXldID0gdHJ1ZTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGdldChrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgU3RyaW5nTWFwV3JhcHBlci5kZWxldGUodGhpcy5rZXlzLCBrZXkpO1xuICAgIHJldHVybiB0aGlzLm1hcFtrZXldO1xuICB9XG5cbiAgZ2V0VW51c2VkKCk6IHtba2V5OiBzdHJpbmddOiBhbnl9IHtcbiAgICB2YXIgdW51c2VkOiB7W2tleTogc3RyaW5nXTogYW55fSA9IHt9O1xuICAgIHZhciBrZXlzID0gU3RyaW5nTWFwV3JhcHBlci5rZXlzKHRoaXMua2V5cyk7XG4gICAga2V5cy5mb3JFYWNoKGtleSA9PiB1bnVzZWRba2V5XSA9IFN0cmluZ01hcFdyYXBwZXIuZ2V0KHRoaXMubWFwLCBrZXkpKTtcbiAgICByZXR1cm4gdW51c2VkO1xuICB9XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVN0cmluZyhvYmo6IGFueSk6IHN0cmluZyB7XG4gIGlmIChpc0JsYW5rKG9iaikpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gb2JqLnRvU3RyaW5nKCk7XG4gIH1cbn1cblxuaW50ZXJmYWNlIFNlZ21lbnQge1xuICBuYW1lOiBzdHJpbmc7XG4gIGdlbmVyYXRlKHBhcmFtczogVG91Y2hNYXApOiBzdHJpbmc7XG4gIG1hdGNoKHBhdGg6IHN0cmluZyk6IGJvb2xlYW47XG59XG5cbmNsYXNzIENvbnRpbnVhdGlvblNlZ21lbnQgaW1wbGVtZW50cyBTZWdtZW50IHtcbiAgbmFtZTogc3RyaW5nID0gJyc7XG4gIGdlbmVyYXRlKHBhcmFtczogVG91Y2hNYXApOiBzdHJpbmcgeyByZXR1cm4gJyc7IH1cbiAgbWF0Y2gocGF0aDogc3RyaW5nKTogYm9vbGVhbiB7IHJldHVybiB0cnVlOyB9XG59XG5cbmNsYXNzIFN0YXRpY1NlZ21lbnQgaW1wbGVtZW50cyBTZWdtZW50IHtcbiAgbmFtZTogc3RyaW5nID0gJyc7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBwYXRoOiBzdHJpbmcpIHt9XG4gIG1hdGNoKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4geyByZXR1cm4gcGF0aCA9PSB0aGlzLnBhdGg7IH1cbiAgZ2VuZXJhdGUocGFyYW1zOiBUb3VjaE1hcCk6IHN0cmluZyB7IHJldHVybiB0aGlzLnBhdGg7IH1cbn1cblxuY2xhc3MgRHluYW1pY1NlZ21lbnQgaW1wbGVtZW50cyBTZWdtZW50IHtcbiAgY29uc3RydWN0b3IocHVibGljIG5hbWU6IHN0cmluZykge31cbiAgbWF0Y2gocGF0aDogc3RyaW5nKTogYm9vbGVhbiB7IHJldHVybiBwYXRoLmxlbmd0aCA+IDA7IH1cbiAgZ2VuZXJhdGUocGFyYW1zOiBUb3VjaE1hcCk6IHN0cmluZyB7XG4gICAgaWYgKCFTdHJpbmdNYXBXcmFwcGVyLmNvbnRhaW5zKHBhcmFtcy5tYXAsIHRoaXMubmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBCYXNlRXhjZXB0aW9uKFxuICAgICAgICAgIGBSb3V0ZSBnZW5lcmF0b3IgZm9yICcke3RoaXMubmFtZX0nIHdhcyBub3QgaW5jbHVkZWQgaW4gcGFyYW1ldGVycyBwYXNzZWQuYCk7XG4gICAgfVxuICAgIHJldHVybiBub3JtYWxpemVTdHJpbmcocGFyYW1zLmdldCh0aGlzLm5hbWUpKTtcbiAgfVxufVxuXG5cbmNsYXNzIFN0YXJTZWdtZW50IGltcGxlbWVudHMgU2VnbWVudCB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBuYW1lOiBzdHJpbmcpIHt9XG4gIG1hdGNoKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4geyByZXR1cm4gdHJ1ZTsgfVxuICBnZW5lcmF0ZShwYXJhbXM6IFRvdWNoTWFwKTogc3RyaW5nIHsgcmV0dXJuIG5vcm1hbGl6ZVN0cmluZyhwYXJhbXMuZ2V0KHRoaXMubmFtZSkpOyB9XG59XG5cblxudmFyIHBhcmFtTWF0Y2hlciA9IC9eOihbXlxcL10rKSQvZztcbnZhciB3aWxkY2FyZE1hdGNoZXIgPSAvXlxcKihbXlxcL10rKSQvZztcblxuZnVuY3Rpb24gcGFyc2VQYXRoU3RyaW5nKHJvdXRlOiBzdHJpbmcpOiB7W2tleTogc3RyaW5nXTogYW55fSB7XG4gIC8vIG5vcm1hbGl6ZSByb3V0ZSBhcyBub3Qgc3RhcnRpbmcgd2l0aCBhIFwiL1wiLiBSZWNvZ25pdGlvbiB3aWxsXG4gIC8vIGFsc28gbm9ybWFsaXplLlxuICBpZiAocm91dGUuc3RhcnRzV2l0aChcIi9cIikpIHtcbiAgICByb3V0ZSA9IHJvdXRlLnN1YnN0cmluZygxKTtcbiAgfVxuXG4gIHZhciBzZWdtZW50cyA9IHNwbGl0QnlTbGFzaChyb3V0ZSk7XG4gIHZhciByZXN1bHRzID0gW107XG5cbiAgdmFyIHNwZWNpZmljaXR5ID0gJyc7XG5cbiAgLy8gYSBzaW5nbGUgc2xhc2ggKG9yIFwiZW1wdHkgc2VnbWVudFwiIGlzIGFzIHNwZWNpZmljIGFzIGEgc3RhdGljIHNlZ21lbnRcbiAgaWYgKHNlZ21lbnRzLmxlbmd0aCA9PSAwKSB7XG4gICAgc3BlY2lmaWNpdHkgKz0gJzInO1xuICB9XG5cbiAgLy8gVGhlIFwic3BlY2lmaWNpdHlcIiBvZiBhIHBhdGggaXMgdXNlZCB0byBkZXRlcm1pbmUgd2hpY2ggcm91dGUgaXMgdXNlZCB3aGVuIG11bHRpcGxlIHJvdXRlcyBtYXRjaFxuICAvLyBhIFVSTC4gU3RhdGljIHNlZ21lbnRzIChsaWtlIFwiL2Zvb1wiKSBhcmUgdGhlIG1vc3Qgc3BlY2lmaWMsIGZvbGxvd2VkIGJ5IGR5bmFtaWMgc2VnbWVudHMgKGxpa2VcbiAgLy8gXCIvOmlkXCIpLiBTdGFyIHNlZ21lbnRzIGFkZCBubyBzcGVjaWZpY2l0eS4gU2VnbWVudHMgYXQgdGhlIHN0YXJ0IG9mIHRoZSBwYXRoIGFyZSBtb3JlIHNwZWNpZmljXG4gIC8vIHRoYW4gcHJvY2VlZGluZyBvbmVzLlxuICAvL1xuICAvLyBUaGUgY29kZSBiZWxvdyB1c2VzIHBsYWNlIHZhbHVlcyB0byBjb21iaW5lIHRoZSBkaWZmZXJlbnQgdHlwZXMgb2Ygc2VnbWVudHMgaW50byBhIHNpbmdsZVxuICAvLyBzdHJpbmcgdGhhdCB3ZSBjYW4gc29ydCBsYXRlci4gRWFjaCBzdGF0aWMgc2VnbWVudCBpcyBtYXJrZWQgYXMgYSBzcGVjaWZpY2l0eSBvZiBcIjIsXCIgZWFjaFxuICAvLyBkeW5hbWljIHNlZ21lbnQgaXMgd29ydGggXCIxXCIgc3BlY2lmaWNpdHksIGFuZCBzdGFycyBhcmUgd29ydGggXCIwXCIgc3BlY2lmaWNpdHkuXG5cbiAgdmFyIGxpbWl0ID0gc2VnbWVudHMubGVuZ3RoIC0gMTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPD0gbGltaXQ7IGkrKykge1xuICAgIHZhciBzZWdtZW50ID0gc2VnbWVudHNbaV0sIG1hdGNoO1xuXG4gICAgaWYgKGlzUHJlc2VudChtYXRjaCA9IFJlZ0V4cFdyYXBwZXIuZmlyc3RNYXRjaChwYXJhbU1hdGNoZXIsIHNlZ21lbnQpKSkge1xuICAgICAgcmVzdWx0cy5wdXNoKG5ldyBEeW5hbWljU2VnbWVudChtYXRjaFsxXSkpO1xuICAgICAgc3BlY2lmaWNpdHkgKz0gJzEnO1xuICAgIH0gZWxzZSBpZiAoaXNQcmVzZW50KG1hdGNoID0gUmVnRXhwV3JhcHBlci5maXJzdE1hdGNoKHdpbGRjYXJkTWF0Y2hlciwgc2VnbWVudCkpKSB7XG4gICAgICByZXN1bHRzLnB1c2gobmV3IFN0YXJTZWdtZW50KG1hdGNoWzFdKSk7XG4gICAgICBzcGVjaWZpY2l0eSArPSAnMCc7XG4gICAgfSBlbHNlIGlmIChzZWdtZW50ID09ICcuLi4nKSB7XG4gICAgICBpZiAoaSA8IGxpbWl0KSB7XG4gICAgICAgIHRocm93IG5ldyBCYXNlRXhjZXB0aW9uKGBVbmV4cGVjdGVkIFwiLi4uXCIgYmVmb3JlIHRoZSBlbmQgb2YgdGhlIHBhdGggZm9yIFwiJHtyb3V0ZX1cIi5gKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdHMucHVzaChuZXcgQ29udGludWF0aW9uU2VnbWVudCgpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0cy5wdXNoKG5ldyBTdGF0aWNTZWdtZW50KHNlZ21lbnQpKTtcbiAgICAgIHNwZWNpZmljaXR5ICs9ICcyJztcbiAgICB9XG4gIH1cblxuICByZXR1cm4geydzZWdtZW50cyc6IHJlc3VsdHMsICdzcGVjaWZpY2l0eSc6IHNwZWNpZmljaXR5fTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGRldGVybWluZSB3aGV0aGVyIGEgcm91dGUgY29uZmlnIHBhdGggbGlrZSBgL2Zvby86aWRgIGNvbGxpZGVzIHdpdGhcbi8vIGAvZm9vLzpuYW1lYFxuZnVuY3Rpb24gcGF0aERzbEhhc2goc2VnbWVudHM6IFNlZ21lbnRbXSk6IHN0cmluZyB7XG4gIHJldHVybiBzZWdtZW50cy5tYXAoKHNlZ21lbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICBpZiAoc2VnbWVudCBpbnN0YW5jZW9mIFN0YXJTZWdtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICByZXR1cm4gJyonO1xuICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc2VnbWVudCBpbnN0YW5jZW9mIENvbnRpbnVhdGlvblNlZ21lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnLi4uJztcbiAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNlZ21lbnQgaW5zdGFuY2VvZiBEeW5hbWljU2VnbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICc6JztcbiAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNlZ21lbnQgaW5zdGFuY2VvZiBTdGF0aWNTZWdtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VnbWVudC5wYXRoO1xuICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgfSlcbiAgICAgIC5qb2luKCcvJyk7XG59XG5cbmZ1bmN0aW9uIHNwbGl0QnlTbGFzaCh1cmw6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIHVybC5zcGxpdCgnLycpO1xufVxuXG52YXIgUkVTRVJWRURfQ0hBUlMgPSBSZWdFeHBXcmFwcGVyLmNyZWF0ZSgnLy98XFxcXCh8XFxcXCl8O3xcXFxcP3w9Jyk7XG5mdW5jdGlvbiBhc3NlcnRQYXRoKHBhdGg6IHN0cmluZykge1xuICBpZiAoU3RyaW5nV3JhcHBlci5jb250YWlucyhwYXRoLCAnIycpKSB7XG4gICAgdGhyb3cgbmV3IEJhc2VFeGNlcHRpb24oXG4gICAgICAgIGBQYXRoIFwiJHtwYXRofVwiIHNob3VsZCBub3QgaW5jbHVkZSBcIiNcIi4gVXNlIFwiSGFzaExvY2F0aW9uU3RyYXRlZ3lcIiBpbnN0ZWFkLmApO1xuICB9XG4gIHZhciBpbGxlZ2FsQ2hhcmFjdGVyID0gUmVnRXhwV3JhcHBlci5maXJzdE1hdGNoKFJFU0VSVkVEX0NIQVJTLCBwYXRoKTtcbiAgaWYgKGlzUHJlc2VudChpbGxlZ2FsQ2hhcmFjdGVyKSkge1xuICAgIHRocm93IG5ldyBCYXNlRXhjZXB0aW9uKFxuICAgICAgICBgUGF0aCBcIiR7cGF0aH1cIiBjb250YWlucyBcIiR7aWxsZWdhbENoYXJhY3RlclswXX1cIiB3aGljaCBpcyBub3QgYWxsb3dlZCBpbiBhIHJvdXRlIGNvbmZpZy5gKTtcbiAgfVxufVxuXG5cbi8qKlxuICogUGFyc2VzIGEgVVJMIHN0cmluZyB1c2luZyBhIGdpdmVuIG1hdGNoZXIgRFNMLCBhbmQgZ2VuZXJhdGVzIFVSTHMgZnJvbSBwYXJhbSBtYXBzXG4gKi9cbmV4cG9ydCBjbGFzcyBQYXRoUmVjb2duaXplciB7XG4gIHByaXZhdGUgX3NlZ21lbnRzOiBTZWdtZW50W107XG4gIHNwZWNpZmljaXR5OiBzdHJpbmc7XG4gIHRlcm1pbmFsOiBib29sZWFuID0gdHJ1ZTtcbiAgaGFzaDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBwYXRoOiBzdHJpbmcpIHtcbiAgICBhc3NlcnRQYXRoKHBhdGgpO1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZVBhdGhTdHJpbmcocGF0aCk7XG5cbiAgICB0aGlzLl9zZWdtZW50cyA9IHBhcnNlZFsnc2VnbWVudHMnXTtcbiAgICB0aGlzLnNwZWNpZmljaXR5ID0gcGFyc2VkWydzcGVjaWZpY2l0eSddO1xuICAgIHRoaXMuaGFzaCA9IHBhdGhEc2xIYXNoKHRoaXMuX3NlZ21lbnRzKTtcblxuICAgIHZhciBsYXN0U2VnbWVudCA9IHRoaXMuX3NlZ21lbnRzW3RoaXMuX3NlZ21lbnRzLmxlbmd0aCAtIDFdO1xuICAgIHRoaXMudGVybWluYWwgPSAhKGxhc3RTZWdtZW50IGluc3RhbmNlb2YgQ29udGludWF0aW9uU2VnbWVudCk7XG4gIH1cblxuICByZWNvZ25pemUoYmVnaW5uaW5nU2VnbWVudDogVXJsKToge1trZXk6IHN0cmluZ106IGFueX0ge1xuICAgIHZhciBuZXh0U2VnbWVudCA9IGJlZ2lubmluZ1NlZ21lbnQ7XG4gICAgdmFyIGN1cnJlbnRTZWdtZW50OiBVcmw7XG4gICAgdmFyIHBvc2l0aW9uYWxQYXJhbXMgPSB7fTtcbiAgICB2YXIgY2FwdHVyZWQgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fc2VnbWVudHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIHZhciBzZWdtZW50ID0gdGhpcy5fc2VnbWVudHNbaV07XG5cbiAgICAgIGN1cnJlbnRTZWdtZW50ID0gbmV4dFNlZ21lbnQ7XG4gICAgICBpZiAoc2VnbWVudCBpbnN0YW5jZW9mIENvbnRpbnVhdGlvblNlZ21lbnQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChpc1ByZXNlbnQoY3VycmVudFNlZ21lbnQpKSB7XG4gICAgICAgIC8vIHRoZSBzdGFyIHNlZ21lbnQgY29uc3VtZXMgYWxsIG9mIHRoZSByZW1haW5pbmcgVVJMLCBpbmNsdWRpbmcgbWF0cml4IHBhcmFtc1xuICAgICAgICBpZiAoc2VnbWVudCBpbnN0YW5jZW9mIFN0YXJTZWdtZW50KSB7XG4gICAgICAgICAgcG9zaXRpb25hbFBhcmFtc1tzZWdtZW50Lm5hbWVdID0gY3VycmVudFNlZ21lbnQudG9TdHJpbmcoKTtcbiAgICAgICAgICBjYXB0dXJlZC5wdXNoKGN1cnJlbnRTZWdtZW50LnRvU3RyaW5nKCkpO1xuICAgICAgICAgIG5leHRTZWdtZW50ID0gbnVsbDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNhcHR1cmVkLnB1c2goY3VycmVudFNlZ21lbnQucGF0aCk7XG5cbiAgICAgICAgaWYgKHNlZ21lbnQgaW5zdGFuY2VvZiBEeW5hbWljU2VnbWVudCkge1xuICAgICAgICAgIHBvc2l0aW9uYWxQYXJhbXNbc2VnbWVudC5uYW1lXSA9IGN1cnJlbnRTZWdtZW50LnBhdGg7XG4gICAgICAgIH0gZWxzZSBpZiAoIXNlZ21lbnQubWF0Y2goY3VycmVudFNlZ21lbnQucGF0aCkpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIG5leHRTZWdtZW50ID0gY3VycmVudFNlZ21lbnQuY2hpbGQ7XG4gICAgICB9IGVsc2UgaWYgKCFzZWdtZW50Lm1hdGNoKCcnKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy50ZXJtaW5hbCAmJiBpc1ByZXNlbnQobmV4dFNlZ21lbnQpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgdXJsUGF0aCA9IGNhcHR1cmVkLmpvaW4oJy8nKTtcblxuICAgIHZhciBhdXhpbGlhcnk7XG4gICAgdmFyIHVybFBhcmFtcztcbiAgICB2YXIgYWxsUGFyYW1zO1xuICAgIGlmIChpc1ByZXNlbnQoY3VycmVudFNlZ21lbnQpKSB7XG4gICAgICAvLyBJZiB0aGlzIGlzIHRoZSByb290IGNvbXBvbmVudCwgcmVhZCBxdWVyeSBwYXJhbXMuIE90aGVyd2lzZSwgcmVhZCBtYXRyaXggcGFyYW1zLlxuICAgICAgdmFyIHBhcmFtc1NlZ21lbnQgPSBiZWdpbm5pbmdTZWdtZW50IGluc3RhbmNlb2YgUm9vdFVybCA/IGJlZ2lubmluZ1NlZ21lbnQgOiBjdXJyZW50U2VnbWVudDtcblxuICAgICAgYWxsUGFyYW1zID0gaXNQcmVzZW50KHBhcmFtc1NlZ21lbnQucGFyYW1zKSA/XG4gICAgICAgICAgICAgICAgICAgICAgU3RyaW5nTWFwV3JhcHBlci5tZXJnZShwYXJhbXNTZWdtZW50LnBhcmFtcywgcG9zaXRpb25hbFBhcmFtcykgOlxuICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uYWxQYXJhbXM7XG5cbiAgICAgIHVybFBhcmFtcyA9IHNlcmlhbGl6ZVBhcmFtcyhwYXJhbXNTZWdtZW50LnBhcmFtcyk7XG5cblxuICAgICAgYXV4aWxpYXJ5ID0gY3VycmVudFNlZ21lbnQuYXV4aWxpYXJ5O1xuICAgIH0gZWxzZSB7XG4gICAgICBhbGxQYXJhbXMgPSBwb3NpdGlvbmFsUGFyYW1zO1xuICAgICAgYXV4aWxpYXJ5ID0gW107XG4gICAgICB1cmxQYXJhbXMgPSBbXTtcbiAgICB9XG4gICAgcmV0dXJuIHt1cmxQYXRoLCB1cmxQYXJhbXMsIGFsbFBhcmFtcywgYXV4aWxpYXJ5LCBuZXh0U2VnbWVudH07XG4gIH1cblxuXG4gIGdlbmVyYXRlKHBhcmFtczoge1trZXk6IHN0cmluZ106IGFueX0pOiB7W2tleTogc3RyaW5nXTogYW55fSB7XG4gICAgdmFyIHBhcmFtVG9rZW5zID0gbmV3IFRvdWNoTWFwKHBhcmFtcyk7XG5cbiAgICB2YXIgcGF0aCA9IFtdO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLl9zZWdtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgbGV0IHNlZ21lbnQgPSB0aGlzLl9zZWdtZW50c1tpXTtcbiAgICAgIGlmICghKHNlZ21lbnQgaW5zdGFuY2VvZiBDb250aW51YXRpb25TZWdtZW50KSkge1xuICAgICAgICBwYXRoLnB1c2goc2VnbWVudC5nZW5lcmF0ZShwYXJhbVRva2VucykpO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgdXJsUGF0aCA9IHBhdGguam9pbignLycpO1xuXG4gICAgdmFyIG5vblBvc2l0aW9uYWxQYXJhbXMgPSBwYXJhbVRva2Vucy5nZXRVbnVzZWQoKTtcbiAgICB2YXIgdXJsUGFyYW1zID0gc2VyaWFsaXplUGFyYW1zKG5vblBvc2l0aW9uYWxQYXJhbXMpO1xuXG4gICAgcmV0dXJuIHt1cmxQYXRoLCB1cmxQYXJhbXN9O1xuICB9XG59XG4iXX0=