UNPKG

breeze-client

Version:

Breeze data management for JavaScript clients

330 lines 38 kB
import { core } from './core'; /** @hidden @internal */ export class Param { // The %1 parameter // is required // must be a %2 // must be an instance of %2 // must be an instance of the %2 enumeration // must have a %2 property // must be an array where each element // is optional or v; name; defaultValue; parent; /** @hidden @internal */ _context; /** @hidden @internal */ _contexts; constructor(v, name) { this.v = v; this.name = name; this._contexts = [null]; } isObject() { return this.isTypeOf('object'); } isBoolean() { return this.isTypeOf('boolean'); } isString() { return this.isTypeOf('string'); } isNumber() { return this.isTypeOf('number'); } isFunction() { return this.isTypeOf('function'); } isNonEmptyString() { return addContext(this, { fn: isNonEmptyString, msg: "must be a nonEmpty string" }); } isTypeOf(typeName) { return addContext(this, { fn: isTypeOf, typeName: typeName, msg: "must be a '" + typeName + "'" }); } isInstanceOf(type, typeName) { typeName = typeName || type.prototype._$typeName; return addContext(this, { fn: isInstanceOf, type: type, typeName: typeName, msg: "must be an instance of '" + typeName + "'" }); } hasProperty(propertyName) { return addContext(this, { fn: hasProperty, propertyName: propertyName, msg: "must have a '" + propertyName + "' property" }); } isEnumOf(enumType) { return addContext(this, { fn: isEnumOf, enumType: enumType, msg: "must be an instance of the '" + (enumType.name || 'unknown') + "' enumeration" }); } isRequired(allowNull = false) { return addContext(this, { fn: isRequired, allowNull: allowNull, msg: "is required" }); } isOptional() { let context = { fn: isOptional, prevContext: null, msg: isOptionalMessage }; return addContext(this, context); } isNonEmptyArray() { return this.isArray(true); } isArray(mustNotBeEmpty) { let context = { fn: isArray, mustNotBeEmpty: mustNotBeEmpty, prevContext: null, msg: isArrayMessage }; return addContext(this, context); } or() { this._contexts.push(null); this._context = null; return this; } check(defaultValue) { let ok = exec(this); if (ok === undefined) return; if (!ok) { throw new Error(this.getMessage()); } if (this.v !== undefined) { return this.v; } else { return defaultValue; } } /** @hidden @internal */ // called from outside this file. _addContext(context) { return addContext(this, context); } getMessage() { let that = this; let message = this._contexts.map(function (context) { return getMessage(context, that.v); }).join(", or it "); return core.formatString(this.MESSAGE_PREFIX, this.name) + " " + message; } withDefault(defaultValue) { this.defaultValue = defaultValue; return this; } whereParam(propName) { return this.parent.whereParam(propName); } applyAll(instance, checkOnly = false) { let parentTypeName = instance._$typeName; let allowUnknownProperty = (parentTypeName && this.parent.config._$typeName === parentTypeName); let clone = core.extend({}, this.parent.config); this.parent.params.forEach(function (p) { if (!allowUnknownProperty) delete clone[p.name]; try { p.check(); } catch (e) { throwConfigError(instance, e.message); } (!checkOnly) && p._applyOne(instance); }); // should be no properties left in the clone if (!allowUnknownProperty) { for (let key in clone) { // allow props with an undefined value if (clone[key] !== undefined) { throwConfigError(instance, core.formatString("Unknown property: '%1'.", key)); } } } } /** @hidden @internal */ _applyOne = function (instance) { if (this.v !== undefined) { instance[this.name] = this.v; } else { if (this.defaultValue !== undefined) { instance[this.name] = this.defaultValue; } } }; MESSAGE_PREFIX = "The '%1' parameter "; } /** @hidden @internal */ export let assertParam = function (v, name) { return new Param(v, name); }; function isTypeOf(context, v) { if (v == null) return false; if (typeof (v) === context.typeName) return true; return false; } function isNonEmptyString(context, v) { if (v == null) return false; return (typeof (v) === 'string') && v.length > 0; } function isInstanceOf(context, v) { if (v == null || context.type == null) return false; return (v instanceof context.type); } function isEnumOf(context, v) { if (v == null || context.enumType == null) return false; return context.enumType.contains(v); } function hasProperty(context, v) { if (v == null || context.propertyName == null) return false; return (v[context.propertyName] !== undefined); } function isRequired(context, v) { if (context.allowNull) { return v !== undefined; } else { return v != null; } } function isOptional(context, v) { if (v == null) return true; let prevContext = context.prevContext; if (prevContext && prevContext.fn) { return prevContext.fn(prevContext, v); } else { return true; } } function isOptionalMessage(context, v) { let prevContext = context.prevContext; let element = prevContext ? " or it " + getMessage(prevContext, v) : ""; return "is optional" + element; } function isArray(context, v) { if (!Array.isArray(v)) { return false; } if (context.mustNotBeEmpty) { if (v.length === 0) return false; } // allow standalone is array call. let prevContext = context.prevContext; if (!prevContext) return true; let pc = prevContext; return v.every(function (v1) { return pc.fn && pc.fn(pc, v1); }); } function isArrayMessage(context, v) { let arrayDescr = context.mustNotBeEmpty ? "a nonEmpty array" : "an array"; let prevContext = context.prevContext; let element = prevContext ? " where each element " + getMessage(prevContext, v) : ""; return " must be " + arrayDescr + element; } function getMessage(context, v) { let msg = context.msg; if (typeof (msg) === "function") { msg = msg(context, v); } return msg; } function addContext(that, context) { if (that._context) { let curContext = that._context; while (curContext.prevContext != null) { curContext = curContext.prevContext; } if (curContext.prevContext === null) { curContext.prevContext = context; // just update the prevContext but don't change the curContext. return that; } else if (context.prevContext == null) { context.prevContext = that._context; } else { throw new Error("Illegal construction - use 'or' to combine checks"); } } return setContext(that, context); } function setContext(that, context) { that._contexts[that._contexts.length - 1] = context; that._context = context; return that; } function exec(self) { // clear off last one if null let contexts = self._contexts; if (contexts[contexts.length - 1] == null) { contexts.pop(); } if (contexts.length === 0) { return undefined; } return contexts.some(function (context) { return context.fn ? context.fn(context, self.v) : false; }); } function throwConfigError(instance, message) { throw new Error(core.formatString("Error configuring an instance of '%1'. %2", (instance && instance._$typeName) || "object", message)); } class ConfigParam { config; params; constructor(config) { if (typeof (config) !== "object") { throw new Error("Configuration parameter should be an object, instead it is a: " + typeof (config)); } this.config = config; this.params = []; } whereParam(propName) { let param = new Param(this.config[propName], propName); param.parent = this; this.params.push(param); return param; } } /** @hidden @internal */ export let assertConfig = function (config) { return new ConfigParam(config); }; // Param is exposed so that additional 'is' methods can be added to the prototype. core.Param = Param; core.assertParam = assertParam; core.assertConfig = assertConfig; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXJ0LXBhcmFtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Fzc2VydC1wYXJhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsSUFBSSxFQUFHLE1BQU0sUUFBUSxDQUFDO0FBc0IvQix3QkFBd0I7QUFDeEIsTUFBTSxPQUFPLEtBQUs7SUFDZCxtQkFBbUI7SUFDbkIsY0FBYztJQUNkLGVBQWU7SUFDZiw0QkFBNEI7SUFDNUIsNENBQTRDO0lBQzVDLDBCQUEwQjtJQUMxQixzQ0FBc0M7SUFDdEMsaUJBQWlCO0lBRWpCLENBQUMsQ0FBTTtJQUNQLElBQUksQ0FBUztJQUNiLFlBQVksQ0FBTTtJQUNsQixNQUFNLENBQWU7SUFDckIsd0JBQXdCO0lBQ3hCLFFBQVEsQ0FBZ0I7SUFDeEIsd0JBQXdCO0lBQ3hCLFNBQVMsQ0FBa0I7SUFFM0IsWUFBWSxDQUFNLEVBQUUsSUFBWTtRQUM1QixJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNYLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBTSxJQUFJLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsUUFBUTtRQUNKLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsU0FBUztRQUNMLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQsUUFBUTtRQUNKLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsUUFBUTtRQUNKLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsVUFBVTtRQUNOLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lB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LENBQUM7Q0FDSjtBQUVELHdCQUF3QjtBQUN4QixNQUFNLENBQUMsSUFBSSxZQUFZLEdBQUcsVUFBVSxNQUFjO0lBQzlDLE9BQU8sSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFpQixDQUFDO0FBQ25ELENBQUMsQ0FBQztBQUdGLGtGQUFrRjtBQUNqRixJQUFZLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztBQUMzQixJQUFZLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztBQUN2QyxJQUFZLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJyZWV6ZUVudW0gfSBmcm9tICcuL2VudW0nO1xyXG5pbXBvcnQgeyBjb3JlICB9IGZyb20gJy4vY29yZSc7XHJcblxyXG4vKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGludGVyZmFjZSBJUGFyYW1Db250ZXh0IHtcclxuICAgIHR5cGVOYW1lPzogc3RyaW5nO1xyXG4gICAgdHlwZT86IEZ1bmN0aW9uO1xyXG4gICAgcHJldkNvbnRleHQ/OiBJUGFyYW1Db250ZXh0O1xyXG4gICAgbXNnPzogc3RyaW5nIHwgKChjb250ZXh0OiBJUGFyYW1Db250ZXh0LCB2OiBhbnkpID0+IHN0cmluZyk7XHJcbiAgICBtdXN0Tm90QmVFbXB0eT86IGJvb2xlYW47XHJcbiAgICBlbnVtVHlwZT86IEJyZWV6ZUVudW07XHJcbiAgICBwcm9wZXJ0eU5hbWU/OiBzdHJpbmc7XHJcbiAgICBhbGxvd051bGw/OiBib29sZWFuO1xyXG4gICAgZm4/KGNvbnRleHQ6IElQYXJhbUNvbnRleHQsIHY6IGFueSk6IGJvb2xlYW47XHJcbn1cclxuXHJcbi8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElDb25maWdQYXJhbSB7XHJcbiAgICBjb25maWc6IGFueTtcclxuICAgIHBhcmFtczogUGFyYW1bXTtcclxuICAgIHdoZXJlUGFyYW06IChwcm9wTmFtZTogc3RyaW5nKSA9PiBQYXJhbTtcclxufVxyXG5cclxuLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbmV4cG9ydCBjbGFzcyBQYXJhbSB7XHJcbiAgICAvLyBUaGUgJTEgcGFyYW1ldGVyXHJcbiAgICAvLyBpcyByZXF1aXJlZFxyXG4gICAgLy8gbXVzdCBiZSBhICUyXHJcbiAgICAvLyBtdXN0IGJlIGFuIGluc3RhbmNlIG9mICUyXHJcbiAgICAvLyBtdXN0IGJlIGFuIGluc3RhbmNlIG9mIHRoZSAlMiBlbnVtZXJhdGlvblxyXG4gICAgLy8gbXVzdCBoYXZlIGEgJTIgcHJvcGVydHlcclxuICAgIC8vIG11c3QgYmUgYW4gYXJyYXkgd2hlcmUgZWFjaCBlbGVtZW50XHJcbiAgICAvLyBpcyBvcHRpb25hbCBvclxyXG5cclxuICAgIHY6IGFueTtcclxuICAgIG5hbWU6IHN0cmluZztcclxuICAgIGRlZmF1bHRWYWx1ZTogYW55O1xyXG4gICAgcGFyZW50OiBJQ29uZmlnUGFyYW07XHJcbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICAgIF9jb250ZXh0OiBJUGFyYW1Db250ZXh0O1xyXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgICBfY29udGV4dHM6IElQYXJhbUNvbnRleHRbXTtcclxuXHJcbiAgICBjb25zdHJ1Y3Rvcih2OiBhbnksIG5hbWU6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMudiA9IHY7XHJcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcclxuICAgICAgICB0aGlzLl9jb250ZXh0cyA9IFs8YW55Pm51bGxdO1xyXG4gICAgfVxyXG5cclxuICAgIGlzT2JqZWN0KCk6IFBhcmFtIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pc1R5cGVPZignb2JqZWN0Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgaXNCb29sZWFuKCk6IFBhcmFtIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pc1R5cGVPZignYm9vbGVhbicpO1xyXG4gICAgfVxyXG5cclxuICAgIGlzU3RyaW5nKCk6IFBhcmFtIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pc1R5cGVPZignc3RyaW5nJyk7XHJcbiAgICB9XHJcblxyXG4gICAgaXNOdW1iZXIoKTogUGFyYW0ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmlzVHlwZU9mKCdudW1iZXInKTtcclxuICAgIH1cclxuXHJcbiAgICBpc0Z1bmN0aW9uKCk6IFBhcmFtIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pc1R5cGVPZignZnVuY3Rpb24nKTtcclxuICAgIH1cclxuXHJcbiAgICBpc05vbkVtcHR5U3RyaW5nKCk6IFBhcmFtIHtcclxuICAgICAgICByZXR1cm4gYWRkQ29udGV4dCh0aGlzLCB7XHJcbiAgICAgICAgICAgIGZuOiBpc05vbkVtcHR5U3RyaW5nLFxyXG4gICAgICAgICAgICBtc2c6IFwibXVzdCBiZSBhIG5vbkVtcHR5IHN0cmluZ1wiXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIGlzVHlwZU9mKHR5cGVOYW1lOiBzdHJpbmcpOiBQYXJhbSB7XHJcbiAgICAgICAgcmV0dXJuIGFkZENvbnRleHQodGhpcywge1xyXG4gICAgICAgICAgICBmbjogaXNUeXBlT2YsXHJcbiAgICAgICAgICAgIHR5cGVOYW1lOiB0eXBlTmFtZSxcclxuICAgICAgICAgICAgbXNnOiBcIm11c3QgYmUgYSAnXCIgKyB0eXBlTmFtZSArIFwiJ1wiXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIGlzSW5zdGFuY2VPZih0eXBlOiBGdW5jdGlvbiwgdHlwZU5hbWU/OiBzdHJpbmcpOiBQYXJhbSB7XHJcbiAgICAgICAgdHlwZU5hbWUgPSB0eXBlTmFtZSB8fCB0eXBlLnByb3RvdHlwZS5fJHR5cGVOYW1lO1xyXG4gICAgICAgIHJldHVybiBhZGRDb250ZXh0KHRoaXMsIHtcclxuICAgICAgICAgICAgZm46IGlzSW5zdGFuY2VPZixcclxuICAgICAgICAgICAgdHlwZTogdHlwZSxcclxuICAgICAgICAgICAgdHlwZU5hbWU6IHR5cGVOYW1lLFxyXG4gICAgICAgICAgICBtc2c6IFwibXVzdCBiZSBhbiBpbnN0YW5jZSBvZiAnXCIgKyB0eXBlTmFtZSArIFwiJ1wiXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIGhhc1Byb3BlcnR5KHByb3BlcnR5TmFtZTogc3RyaW5nKTogUGFyYW0ge1xyXG4gICAgICAgIHJldHVybiBhZGRDb250ZXh0KHRoaXMsIHtcclxuICAgICAgICAgICAgZm46IGhhc1Byb3BlcnR5LFxyXG4gICAgICAgICAgICBwcm9wZXJ0eU5hbWU6IHByb3BlcnR5TmFtZSxcclxuICAgICAgICAgICAgbXNnOiBcIm11c3QgaGF2ZSBhICdcIiArIHByb3BlcnR5TmFtZSArIFwiJyBwcm9wZXJ0eVwiXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG5cclxuICAgIGlzRW51bU9mKGVudW1UeXBlOiBhbnkpOiBQYXJhbSB7XHJcbiAgICAgICAgcmV0dXJuIGFkZENvbnRleHQodGhpcywge1xyXG4gICAgICAgICAgICBmbjogaXNFbnVtT2YsXHJcbiAgICAgICAgICAgIGVudW1UeXBlOiBlbnVtVHlwZSxcclxuICAgICAgICAgICAgbXNnOiBcIm11c3QgYmUgYW4gaW5zdGFuY2Ugb2YgdGhlICdcIiArIChlbnVtVHlwZS5uYW1lIHx8ICd1bmtub3duJykgKyBcIicgZW51bWVyYXRpb25cIlxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGlzUmVxdWlyZWQoYWxsb3dOdWxsOiBib29sZWFuID0gZmFsc2UpOiBQYXJhbSB7XHJcbiAgICAgICAgcmV0dXJuIGFkZENvbnRleHQodGhpcywge1xyXG4gICAgICAgICAgICBmbjogaXNSZXF1aXJlZCxcclxuICAgICAgICAgICAgYWxsb3dOdWxsOiBhbGxvd051bGwsXHJcbiAgICAgICAgICAgIG1zZzogXCJpcyByZXF1aXJlZFwiXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaXNPcHRpb25hbCgpOiBQYXJhbSB7XHJcbiAgICAgICAgbGV0IGNvbnRleHQgPSB7XHJcbiAgICAgICAgICAgIGZuOiBpc09wdGlvbmFsLFxyXG4gICAgICAgICAgICBwcmV2Q29udGV4dDogPGFueT5udWxsLFxyXG4gICAgICAgICAgICBtc2c6IGlzT3B0aW9uYWxNZXNzYWdlXHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gYWRkQ29udGV4dCh0aGlzLCBjb250ZXh0KTtcclxuICAgIH1cclxuXHJcbiAgICBpc05vbkVtcHR5QXJyYXkoKTogUGFyYW0ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmlzQXJyYXkodHJ1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgaXNBcnJheShtdXN0Tm90QmVFbXB0eT86IGJvb2xlYW4pOiBQYXJhbSB7XHJcbiAgICAgICAgbGV0IGNvbnRleHQgPSB7XHJcbiAgICAgICAgICAgIGZuOiBpc0FycmF5LFxyXG4gICAgICAgICAgICBtdXN0Tm90QmVFbXB0eTogbXVzdE5vdEJlRW1wdHksXHJcbiAgICAgICAgICAgIHByZXZDb250ZXh0OiA8YW55Pm51bGwsXHJcbiAgICAgICAgICAgIG1zZzogaXNBcnJheU1lc3NhZ2VcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiBhZGRDb250ZXh0KHRoaXMsIGNvbnRleHQpO1xyXG4gICAgfVxyXG5cclxuICAgIG9yKCkge1xyXG4gICAgICAgIHRoaXMuX2NvbnRleHRzLnB1c2goPGFueT5udWxsKTtcclxuICAgICAgICB0aGlzLl9jb250ZXh0ID0gPGFueT5udWxsO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIGNoZWNrKGRlZmF1bHRWYWx1ZT86IGFueSkge1xyXG4gICAgICAgIGxldCBvayA9IGV4ZWModGhpcyk7XHJcbiAgICAgICAgaWYgKG9rID09PSB1bmRlZmluZWQpIHJldHVybjtcclxuICAgICAgICBpZiAoIW9rKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcih0aGlzLmdldE1lc3NhZ2UoKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy52ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICAgIC8vIGNhbGxlZCBmcm9tIG91dHNpZGUgdGhpcyBmaWxlLlxyXG4gICAgX2FkZENvbnRleHQoY29udGV4dDogSVBhcmFtQ29udGV4dCkge1xyXG4gICAgICAgIHJldHVybiBhZGRDb250ZXh0KHRoaXMsIGNvbnRleHQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldE1lc3NhZ2UoKSB7XHJcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xyXG4gICAgICAgIGxldCBtZXNzYWdlID0gdGhpcy5fY29udGV4dHMubWFwKGZ1bmN0aW9uIChjb250ZXh0KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBnZXRNZXNzYWdlKGNvbnRleHQsIHRoYXQudik7XHJcbiAgICAgICAgfSkuam9pbihcIiwgb3IgaXQgXCIpO1xyXG4gICAgICAgIHJldHVybiBjb3JlLmZvcm1hdFN0cmluZyh0aGlzLk1FU1NBR0VfUFJFRklYLCB0aGlzLm5hbWUpICsgXCIgXCIgKyBtZXNzYWdlO1xyXG4gICAgfVxyXG5cclxuICAgIHdpdGhEZWZhdWx0KGRlZmF1bHRWYWx1ZTogYW55KSB7XHJcbiAgICAgICAgdGhpcy5kZWZhdWx0VmFsdWUgPSBkZWZhdWx0VmFsdWU7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgd2hlcmVQYXJhbShwcm9wTmFtZTogc3RyaW5nKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LndoZXJlUGFyYW0ocHJvcE5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGFwcGx5QWxsKGluc3RhbmNlOiBhbnksIGNoZWNrT25seTogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgICAgICAgbGV0IHBhcmVudFR5cGVOYW1lID0gaW5zdGFuY2UuXyR0eXBlTmFtZTtcclxuICAgICAgICBsZXQgYWxsb3dVbmtub3duUHJvcGVydHkgPSAocGFyZW50VHlwZU5hbWUgJiYgdGhpcy5wYXJlbnQuY29uZmlnLl8kdHlwZU5hbWUgPT09IHBhcmVudFR5cGVOYW1lKTtcclxuXHJcbiAgICAgICAgbGV0IGNsb25lID0gY29yZS5leHRlbmQoe30sIHRoaXMucGFyZW50LmNvbmZpZyk7XHJcbiAgICAgICAgdGhpcy5wYXJlbnQucGFyYW1zLmZvckVhY2goZnVuY3Rpb24gKHApIHtcclxuICAgICAgICAgICAgaWYgKCFhbGxvd1Vua25vd25Qcm9wZXJ0eSkgZGVsZXRlIGNsb25lW3AubmFtZV07XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBwLmNoZWNrKCk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIHRocm93Q29uZmlnRXJyb3IoaW5zdGFuY2UsIGUubWVzc2FnZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKCFjaGVja09ubHkpICYmIHAuX2FwcGx5T25lKGluc3RhbmNlKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBzaG91bGQgYmUgbm8gcHJvcGVydGllcyBsZWZ0IGluIHRoZSBjbG9uZVxyXG4gICAgICAgIGlmICghYWxsb3dVbmtub3duUHJvcGVydHkpIHtcclxuICAgICAgICAgICAgZm9yIChsZXQga2V5IGluIGNsb25lKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBhbGxvdyBwcm9wcyB3aXRoIGFuIHVuZGVmaW5lZCB2YWx1ZVxyXG4gICAgICAgICAgICAgICAgaWYgKGNsb25lW2tleV0gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93Q29uZmlnRXJyb3IoaW5zdGFuY2UsIGNvcmUuZm9ybWF0U3RyaW5nKFwiVW5rbm93biBwcm9wZXJ0eTogJyUxJy5cIiwga2V5KSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgICBfYXBwbHlPbmUgPSBmdW5jdGlvbiAodGhpczogUGFyYW0sIGluc3RhbmNlOiBhbnkpIHtcclxuICAgICAgICBpZiAodGhpcy52ICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgaW5zdGFuY2VbdGhpcy5uYW1lXSA9IHRoaXMudjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5kZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgaW5zdGFuY2VbdGhpcy5uYW1lXSA9IHRoaXMuZGVmYXVsdFZhbHVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBNRVNTQUdFX1BSRUZJWCA9IFwiVGhlICclMScgcGFyYW1ldGVyIFwiO1xyXG5cclxufVxyXG5cclxuLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbmV4cG9ydCBsZXQgYXNzZXJ0UGFyYW0gPSBmdW5jdGlvbiAodjogYW55LCBuYW1lOiBzdHJpbmcpIHtcclxuICAgIHJldHVybiBuZXcgUGFyYW0odiwgbmFtZSk7XHJcbn07XHJcblxyXG5mdW5jdGlvbiBpc1R5cGVPZihjb250ZXh0OiBJUGFyYW1Db250ZXh0LCB2OiBhbnkpIHtcclxuICAgIGlmICh2ID09IG51bGwpIHJldHVybiBmYWxzZTtcclxuICAgIGlmICh0eXBlb2YgKHYpID09PSBjb250ZXh0LnR5cGVOYW1lKSByZXR1cm4gdHJ1ZTtcclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNOb25FbXB0eVN0cmluZyhjb250ZXh0OiBJUGFyYW1Db250ZXh0LCB2OiBhbnkpIHtcclxuICAgIGlmICh2ID09IG51bGwpIHJldHVybiBmYWxzZTtcclxuICAgIHJldHVybiAodHlwZW9mICh2KSA9PT0gJ3N0cmluZycpICYmIHYubGVuZ3RoID4gMDtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNJbnN0YW5jZU9mKGNvbnRleHQ6IElQYXJhbUNvbnRleHQsIHY6IGFueSkge1xyXG4gICAgaWYgKHYgPT0gbnVsbCB8fCBjb250ZXh0LnR5cGUgPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xyXG4gICAgcmV0dXJuICh2IGluc3RhbmNlb2YgY29udGV4dC50eXBlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNFbnVtT2YoY29udGV4dDogSVBhcmFtQ29udGV4dCwgdjogYW55KSB7XHJcbiAgICBpZiAodiA9PSBudWxsIHx8IGNvbnRleHQuZW51bVR5cGUgPT0gbnVsbCApIHJldHVybiBmYWxzZTtcclxuICAgIHJldHVybiAoY29udGV4dC5lbnVtVHlwZSBhcyBhbnkpLmNvbnRhaW5zKHYpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBoYXNQcm9wZXJ0eShjb250ZXh0OiBJUGFyYW1Db250ZXh0LCB2OiBhbnkpIHtcclxuICAgIGlmICh2ID09IG51bGwgfHwgY29udGV4dC5wcm9wZXJ0eU5hbWUgPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xyXG4gICAgcmV0dXJuICh2W2NvbnRleHQucHJvcGVydHlOYW1lXSAhPT0gdW5kZWZpbmVkKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNSZXF1aXJlZChjb250ZXh0OiBJUGFyYW1Db250ZXh0LCB2OiBhbnkpIHtcclxuICAgIGlmIChjb250ZXh0LmFsbG93TnVsbCkge1xyXG4gICAgICAgIHJldHVybiB2ICE9PSB1bmRlZmluZWQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiB2ICE9IG51bGw7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzT3B0aW9uYWwoY29udGV4dDogSVBhcmFtQ29udGV4dCwgdjogYW55KSB7XHJcbiAgICBpZiAodiA9PSBudWxsKSByZXR1cm4gdHJ1ZTtcclxuICAgIGxldCBwcmV2Q29udGV4dCA9IGNvbnRleHQucHJldkNvbnRleHQ7XHJcbiAgICBpZiAocHJldkNvbnRleHQgJiYgcHJldkNvbnRleHQuZm4pIHtcclxuICAgICAgICByZXR1cm4gcHJldkNvbnRleHQuZm4ocHJldkNvbnRleHQsIHYpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxufVxyXG5cclxuZnVuY3Rpb24gaXNPcHRpb25hbE1lc3NhZ2UoY29udGV4dDogSVBhcmFtQ29udGV4dCwgdjogYW55KSB7XHJcbiAgICBsZXQgcHJldkNvbnRleHQgPSBjb250ZXh0LnByZXZDb250ZXh0O1xyXG4gICAgbGV0IGVsZW1lbnQgPSBwcmV2Q29udGV4dCA/IFwiIG9yIGl0IFwiICsgZ2V0TWVzc2FnZShwcmV2Q29udGV4dCwgdikgOiBcIlwiO1xyXG4gICAgcmV0dXJuIFwiaXMgb3B0aW9uYWxcIiArIGVsZW1lbnQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzQXJyYXkoY29udGV4dDogSVBhcmFtQ29udGV4dCwgdjogYW55KSB7XHJcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodikpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICBpZiAoY29udGV4dC5tdXN0Tm90QmVFbXB0eSkge1xyXG4gICAgICAgIGlmICh2Lmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgLy8gYWxsb3cgc3RhbmRhbG9uZSBpcyBhcnJheSBjYWxsLlxyXG4gICAgbGV0IHByZXZDb250ZXh0ID0gY29udGV4dC5wcmV2Q29udGV4dDtcclxuICAgIGlmICghcHJldkNvbnRleHQpIHJldHVybiB0cnVlO1xyXG5cclxuICAgIGxldCBwYyA9IDxhbnk+cHJldkNvbnRleHQ7XHJcbiAgICByZXR1cm4gdi5ldmVyeShmdW5jdGlvbiAodjE6IGFueSkge1xyXG4gICAgICAgIHJldHVybiBwYy5mbiAmJiBwYy5mbihwYywgdjEpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzQXJyYXlNZXNzYWdlKGNvbnRleHQ6IElQYXJhbUNvbnRleHQsIHY6IGFueSkge1xyXG4gICAgbGV0IGFycmF5RGVzY3IgPSBjb250ZXh0Lm11c3ROb3RCZUVtcHR5ID8gXCJhIG5vbkVtcHR5IGFycmF5XCIgOiBcImFuIGFycmF5XCI7XHJcbiAgICBsZXQgcHJldkNvbnRleHQgPSBjb250ZXh0LnByZXZDb250ZXh0O1xyXG4gICAgbGV0IGVsZW1lbnQgPSBwcmV2Q29udGV4dCA/IFwiIHdoZXJlIGVhY2ggZWxlbWVudCBcIiArIGdldE1lc3NhZ2UocHJldkNvbnRleHQsIHYpIDogXCJcIjtcclxuICAgIHJldHVybiBcIiBtdXN0IGJlIFwiICsgYXJyYXlEZXNjciArIGVsZW1lbnQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldE1lc3NhZ2UoY29udGV4dDogSVBhcmFtQ29udGV4dCwgdjogYW55KSB7XHJcbiAgICBsZXQgbXNnID0gY29udGV4dC5tc2c7XHJcbiAgICBpZiAodHlwZW9mIChtc2cpID09PSBcImZ1bmN0aW9uXCIpIHtcclxuICAgICAgICBtc2cgPSAoPGFueT5tc2cpKGNvbnRleHQsIHYpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG1zZztcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkQ29udGV4dCh0aGF0OiBQYXJhbSwgY29udGV4dDogSVBhcmFtQ29udGV4dCkge1xyXG4gICAgaWYgKHRoYXQuX2NvbnRleHQpIHtcclxuICAgICAgICBsZXQgY3VyQ29udGV4dCA9IHRoYXQuX2NvbnRleHQ7XHJcblxyXG4gICAgICAgIHdoaWxlIChjdXJDb250ZXh0LnByZXZDb250ZXh0ICE9IG51bGwpIHtcclxuICAgICAgICAgICAgY3VyQ29udGV4dCA9IGN1ckNvbnRleHQucHJldkNvbnRleHQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoY3VyQ29udGV4dC5wcmV2Q29udGV4dCA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICBjdXJDb250ZXh0LnByZXZDb250ZXh0ID0gY29udGV4dDtcclxuICAgICAgICAgICAgLy8ganVzdCB1cGRhdGUgdGhlIHByZXZDb250ZXh0IGJ1dCBkb24ndCBjaGFuZ2UgdGhlIGN1ckNvbnRleHQuXHJcbiAgICAgICAgICAgIHJldHVybiB0aGF0O1xyXG4gICAgICAgIH0gZWxzZSBpZiAoY29udGV4dC5wcmV2Q29udGV4dCA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIGNvbnRleHQucHJldkNvbnRleHQgPSB0aGF0Ll9jb250ZXh0O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIklsbGVnYWwgY29uc3RydWN0aW9uIC0gdXNlICdvcicgdG8gY29tYmluZSBjaGVja3NcIik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHNldENvbnRleHQodGhhdCwgY29udGV4dCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNldENvbnRleHQodGhhdDogUGFyYW0sIGNvbnRleHQ6IElQYXJhbUNvbnRleHQpIHtcclxuICAgIHRoYXQuX2NvbnRleHRzW3RoYXQuX2NvbnRleHRzLmxlbmd0aCAtIDFdID0gY29udGV4dDtcclxuICAgIHRoYXQuX2NvbnRleHQgPSBjb250ZXh0O1xyXG4gICAgcmV0dXJuIHRoYXQ7XHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiBleGVjKHNlbGY6IFBhcmFtKSB7XHJcbiAgICAvLyBjbGVhciBvZmYgbGFzdCBvbmUgaWYgbnVsbFxyXG4gICAgbGV0IGNvbnRleHRzID0gc2VsZi5fY29udGV4dHM7XHJcbiAgICBpZiAoY29udGV4dHNbY29udGV4dHMubGVuZ3RoIC0gMV0gPT0gbnVsbCkge1xyXG4gICAgICAgIGNvbnRleHRzLnBvcCgpO1xyXG4gICAgfVxyXG4gICAgaWYgKGNvbnRleHRzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY29udGV4dHMuc29tZShmdW5jdGlvbiAoY29udGV4dDogSVBhcmFtQ29udGV4dCkge1xyXG4gICAgICAgIHJldHVybiBjb250ZXh0LmZuID8gY29udGV4dC5mbihjb250ZXh0LCBzZWxmLnYpIDogZmFsc2U7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gdGhyb3dDb25maWdFcnJvcihpbnN0YW5jZTogYW55LCBtZXNzYWdlOiBzdHJpbmcpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcihjb3JlLmZvcm1hdFN0cmluZyhcIkVycm9yIGNvbmZpZ3VyaW5nIGFuIGluc3RhbmNlIG9mICclMScuICUyXCIsIChpbnN0YW5jZSAmJiBpbnN0YW5jZS5fJHR5cGVOYW1lKSB8fCBcIm9iamVjdFwiLCBtZXNzYWdlKSk7XHJcbn1cclxuXHJcbmNsYXNzIENvbmZpZ1BhcmFtIHtcclxuICAgIGNvbmZpZzogYW55O1xyXG4gICAgcGFyYW1zOiBQYXJhbVtdO1xyXG4gICAgY29uc3RydWN0b3IoY29uZmlnOiBPYmplY3QpIHtcclxuICAgICAgICBpZiAodHlwZW9mIChjb25maWcpICE9PSBcIm9iamVjdFwiKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyIHNob3VsZCBiZSBhbiBvYmplY3QsIGluc3RlYWQgaXQgaXMgYTogXCIgKyB0eXBlb2YgKGNvbmZpZykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcclxuICAgICAgICB0aGlzLnBhcmFtcyA9IFtdO1xyXG4gICAgfVxyXG5cclxuICAgIHdoZXJlUGFyYW0ocHJvcE5hbWU6IHN0cmluZykge1xyXG4gICAgICAgIGxldCBwYXJhbSA9IG5ldyBQYXJhbSh0aGlzLmNvbmZpZ1twcm9wTmFtZV0sIHByb3BOYW1lKTtcclxuICAgICAgICBwYXJhbS5wYXJlbnQgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMucGFyYW1zLnB1c2gocGFyYW0pO1xyXG4gICAgICAgIHJldHVybiBwYXJhbTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbmV4cG9ydCBsZXQgYXNzZXJ0Q29uZmlnID0gZnVuY3Rpb24gKGNvbmZpZzogT2JqZWN0KSB7XHJcbiAgICByZXR1cm4gbmV3IENvbmZpZ1BhcmFtKGNvbmZpZykgYXMgSUNvbmZpZ1BhcmFtO1xyXG59O1xyXG5cclxuXHJcbi8vIFBhcmFtIGlzIGV4cG9zZWQgc28gdGhhdCBhZGRpdGlvbmFsICdpcycgbWV0aG9kcyBjYW4gYmUgYWRkZWQgdG8gdGhlIHByb3RvdHlwZS5cclxuKGNvcmUgYXMgYW55KS5QYXJhbSA9IFBhcmFtO1xyXG4oY29yZSBhcyBhbnkpLmFzc2VydFBhcmFtID0gYXNzZXJ0UGFyYW07XHJcbihjb3JlIGFzIGFueSkuYXNzZXJ0Q29uZmlnID0gYXNzZXJ0Q29uZmlnO1xyXG4iXX0=