UNPKG

ember-legacy-class-transform

Version:
278 lines (272 loc) 37 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.AccessorBlueprint = exports.DataBlueprint = exports.Mixin = exports.Blueprint = exports.Descriptor = exports.BLUEPRINT = exports.DESCRIPTOR = undefined; exports.extend = extend; exports.relinkSubclasses = relinkSubclasses; exports.toMixin = toMixin; exports.wrapMethod = wrapMethod; var _objectReference = require('@glimmer/object-reference'); var _util = require('@glimmer/util'); var _object = require('./object'); var _utils = require('./utils'); const { isArray } = Array; const DESCRIPTOR = exports.DESCRIPTOR = "5d90f84f-908e-4a42-9749-3d0f523c262c"; const BLUEPRINT = exports.BLUEPRINT = "8d97cf5f-db9e-48d8-a6b2-7a75b7170805"; class Descriptor { constructor() { this["5d90f84f-908e-4a42-9749-3d0f523c262c"] = true; } } exports.Descriptor = Descriptor; class Blueprint { constructor() { this["8d97cf5f-db9e-48d8-a6b2-7a75b7170805"] = true; } } exports.Blueprint = Blueprint; class Mixin { constructor(extensions, mixins) { this.extensions = null; this.concatenatedProperties = []; this.mergedProperties = []; this.dependencies = []; this.reopen(extensions); this.dependencies.push(...mixins); } static create(...args) { let extensions = args[args.length - 1]; if (args.length === 0) { return new this({}, []); } else if (extensions instanceof Mixin) { return new this({}, args); } else { let deps = args.slice(0, -1).map(toMixin); return new this(extensions, deps); } } static mixins(obj) { if (typeof obj !== 'object' || obj === null) return []; let meta = _object.ClassMeta.for(obj); if (!meta) return []; return meta.getAppliedMixins(); } detect(obj) { if (typeof obj !== 'object' || obj === null) return false; if (obj instanceof Mixin) { return obj.dependencies.indexOf(this) !== -1; } let meta = _object.ClassMeta.for(obj); return !!meta && meta.hasAppliedMixin(this); } reopen(extensions) { if (this.extensions) { this.dependencies.push(toMixin(this.extensions)); } if (typeof extensions === 'object' && 'concatenatedProperties' in extensions) { let concat; let rawConcat = extensions.concatenatedProperties; if (isArray(rawConcat)) { concat = rawConcat.slice(); } else if (rawConcat === null || rawConcat === undefined) { concat = []; } else { concat = [rawConcat]; } delete extensions.concatenatedProperties; this.concatenatedProperties = concat; } if (typeof extensions === 'object' && 'mergedProperties' in extensions) { let merged; let rawMerged = extensions.mergedProperties; if (isArray(rawMerged)) { merged = rawMerged.slice(); } else if (rawMerged === null || rawMerged === undefined) { merged = []; } else { merged = [rawMerged]; } delete extensions.mergedProperties; this.mergedProperties = merged; } let normalized = Object.keys(extensions).reduce((obj, key) => { let value = extensions[key]; switch (typeof value) { case 'function': obj[key] = new MethodBlueprint({ value }); break; case 'object': if (value && BLUEPRINT in value) { obj[key] = value; break; } /* falls through */ default: obj[key] = new DataBlueprint({ value }); } return obj; }, (0, _util.dict)()); this.extensions = (0, _util.dict)(); (0, _util.assign)(this.extensions, (0, _object.turbocharge)(normalized)); } apply(target) { let meta = target[_objectReference.CLASS_META] = target[_objectReference.CLASS_META] || new _object.ClassMeta(); this.dependencies.forEach(m => m.apply(target)); this.mergeProperties(target, target, meta); meta.addMixin(this); meta.seal(); meta.reseal(target); return target; } extendPrototype(Original) { Original.prototype = Object.create(Original.prototype); this.dependencies.forEach(m => m.extendPrototype(Original)); this.extendPrototypeOnto(Original, Original); } extendPrototypeOnto(Subclass, Parent) { this.dependencies.forEach(m => m.extendPrototypeOnto(Subclass, Parent)); this.mergeProperties(Subclass.prototype, Parent.prototype, Subclass[_objectReference.CLASS_META]); Subclass[_objectReference.CLASS_META].addMixin(this); } extendStatic(Target) { this.dependencies.forEach(m => m.extendStatic(Target)); this.mergeProperties(Target, Object.getPrototypeOf(Target), Target[_objectReference.CLASS_META][_objectReference.CLASS_META]); Target[_objectReference.CLASS_META].addStaticMixin(this); } mergeProperties(target, parent, meta) { if (meta.hasAppliedMixin(this)) return; meta.addAppliedMixin(this); this.mergedProperties.forEach(k => meta.addMergedProperty(k, parent[k])); this.concatenatedProperties.forEach(k => meta.addConcatenatedProperty(k, [])); new ValueDescriptor({ value: meta.getConcatenatedProperties() }).define(target, 'concatenatedProperties'); new ValueDescriptor({ value: meta.getMergedProperties() }).define(target, 'mergedProperties'); Object.keys(this.extensions).forEach(key => { let extension = this.extensions[key]; let desc = extension.descriptor(target, key, meta); desc.define(target, key, parent); }); new ValueDescriptor({ value: _utils.ROOT }).define(target, '_super'); } } exports.Mixin = Mixin; function extend(Parent, ...extensions) { let Super = Parent; let Subclass = class extends Super {}; Subclass[_objectReference.CLASS_META] = _object.InstanceMeta.fromParent(Parent[_objectReference.CLASS_META]); let mixins = extensions.map(toMixin); Parent[_objectReference.CLASS_META].addSubclass(Subclass); mixins.forEach(m => Subclass[_objectReference.CLASS_META].addMixin(m)); _object.ClassMeta.applyAllMixins(Subclass, Parent); return Subclass; } function relinkSubclasses(Parent) { Parent[_objectReference.CLASS_META].getSubclasses().forEach(Subclass => { Subclass[_objectReference.CLASS_META].reset(Parent[_objectReference.CLASS_META]); Subclass.prototype = Object.create(Parent.prototype); _object.ClassMeta.applyAllMixins(Subclass, Parent); // recurse into sub-subclasses relinkSubclasses(Subclass); }); } function toMixin(extension) { if (extension instanceof Mixin) return extension;else return new Mixin(extension, []); } class ValueDescriptor extends Descriptor { constructor({ enumerable = true, configurable = true, writable = true, value }) { super(); this.enumerable = enumerable; this.configurable = configurable; this.writable = writable; this.value = value; } define(target, key, _home) { Object.defineProperty(target, key, { enumerable: this.enumerable, configurable: this.configurable, writable: this.writable, value: this.value }); } } class DataBlueprint extends Blueprint { constructor({ enumerable = true, configurable = true, writable = true, value }) { super(); this.enumerable = enumerable; this.configurable = configurable; this.value = value; this.writable = writable; } descriptor(_target, key, classMeta) { let { enumerable, configurable, writable, value } = this; if (classMeta.hasConcatenatedProperty(key)) { classMeta.addConcatenatedProperty(key, value); value = classMeta.getConcatenatedProperty(key); } else if (classMeta.hasMergedProperty(key)) { classMeta.addMergedProperty(key, value); value = classMeta.getMergedProperty(key); } return new ValueDescriptor({ enumerable, configurable, writable, value }); } } exports.DataBlueprint = DataBlueprint; class AccessorBlueprint extends Blueprint { constructor({ enumerable = true, configurable = true, get, set }) { super(); this.enumerable = enumerable; this.configurable = configurable; this.get = get; this.set = set; } descriptor(_target, _key, _classMeta) { return new ValueDescriptor({ enumerable: this.enumerable, configurable: this.configurable, get: this.get, set: this.set }); } } exports.AccessorBlueprint = AccessorBlueprint; class MethodDescriptor extends ValueDescriptor { define(target, key, home) { this.value = wrapMethod(home, key, this.value); super.define(target, key, home); } } class MethodBlueprint extends DataBlueprint { descriptor(target, key, classMeta) { let desc = super.descriptor(target, key, classMeta); return new MethodDescriptor(desc); } } function wrapMethod(home, methodName, original) { if (!(methodName in home)) return maybeWrap(original); let superMethod = home[methodName]; let func = function (...args) { if (!this) return original.apply(this, args); let lastSuper = this._super; this._super = superMethod; try { return original.apply(this, args); } finally { this._super = lastSuper; } }; func.__wrapped = true; return func; } function maybeWrap(original) { if ('__wrapped' in original) return original; return function (...args) { if (!this) return original.apply(this, args); let lastSuper = this._super; this._super = _utils.ROOT; try { return original.apply(this, args); } finally { this._super = lastSuper; } }; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9taXhpbi5qcyJdLCJuYW1lcyI6WyJleHRlbmQiLCJyZWxpbmtTdWJjbGFzc2VzIiwidG9NaXhpbiIsIndyYXBNZXRob2QiLCJpc0FycmF5IiwiQXJyYXkiLCJERVNDUklQVE9SIiwiQkxVRVBSSU5UIiwiRGVzY3JpcHRvciIsImNvbnN0cnVjdG9yIiwiQmx1ZXByaW50IiwiTWl4aW4iLCJleHRlbnNpb25zIiwibWl4aW5zIiwiY29uY2F0ZW5hdGVkUHJvcGVydGllcyIsIm1lcmdlZFByb3BlcnRpZXMiLCJkZXBlbmRlbmNpZXMiLCJyZW9wZW4iLCJwdXNoIiwiY3JlYXRlIiwiYXJncyIsImxlbmd0aCIsImRlcHMiLCJzbGljZSIsIm1hcCIsIm9iaiIsIm1ldGEiLCJmb3IiLCJnZXRBcHBsaWVkTWl4aW5zIiwiZGV0ZWN0IiwiaW5kZXhPZiIsImhhc0FwcGxpZWRNaXhpbiIsImNvbmNhdCIsInJhd0NvbmNhdCIsInVuZGVmaW5lZCIsIm1lcmdlZCIsInJhd01lcmdlZCIsIm5vcm1hbGl6ZWQiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwia2V5IiwidmFsdWUiLCJNZXRob2RCbHVlcHJpbnQiLCJEYXRhQmx1ZXByaW50IiwiYXBwbHkiLCJ0YXJnZXQiLCJmb3JFYWNoIiwibSIsIm1lcmdlUHJvcGVydGllcyIsImFkZE1peGluIiwic2VhbCIsInJlc2VhbCIsImV4dGVuZFByb3RvdHlwZSIsIk9yaWdpbmFsIiwicHJvdG90eXBlIiwiZXh0ZW5kUHJvdG90eXBlT250byIsIlN1YmNsYXNzIiwiUGFyZW50IiwiZXh0ZW5kU3RhdGljIiwiVGFyZ2V0IiwiZ2V0UHJvdG90eXBlT2YiLCJhZGRTdGF0aWNNaXhpbiIsInBhcmVudCIsImFkZEFwcGxpZWRNaXhpbiIsImsiLCJhZGRNZXJnZWRQcm9wZXJ0eSIsImFkZENvbmNhdGVuYXRlZFByb3BlcnR5IiwiVmFsdWVEZXNjcmlwdG9yIiwiZ2V0Q29uY2F0ZW5hdGVkUHJvcGVydGllcyIsImRlZmluZSIsImdldE1lcmdlZFByb3BlcnRpZXMiLCJleHRlbnNpb24iLCJkZXNjIiwiZGVzY3JpcHRvciIsIlN1cGVyIiwiZnJvbVBhcmVudCIsImFkZFN1YmNsYXNzIiwiYXBwbHlBbGxNaXhpbnMiLCJnZXRTdWJjbGFzc2VzIiwicmVzZXQiLCJlbnVtZXJhYmxlIiwiY29uZmlndXJhYmxlIiwid3JpdGFibGUiLCJfaG9tZSIsImRlZmluZVByb3BlcnR5IiwiX3RhcmdldCIsImNsYXNzTWV0YSIsImhhc0NvbmNhdGVuYXRlZFByb3BlcnR5IiwiZ2V0Q29uY2F0ZW5hdGVkUHJvcGVydHkiLCJoYXNNZXJnZWRQcm9wZXJ0eSIsImdldE1lcmdlZFByb3BlcnR5IiwiQWNjZXNzb3JCbHVlcHJpbnQiLCJnZXQiLCJzZXQiLCJfa2V5IiwiX2NsYXNzTWV0YSIsIk1ldGhvZERlc2NyaXB0b3IiLCJob21lIiwibWV0aG9kTmFtZSIsIm9yaWdpbmFsIiwibWF5YmVXcmFwIiwic3VwZXJNZXRob2QiLCJmdW5jIiwibGFzdFN1cGVyIiwiX3N1cGVyIiwiX193cmFwcGVkIl0sIm1hcHBpbmdzIjoiOzs7Ozs7UUE0SWdCQSxNLEdBQUFBLE07UUFVQUMsZ0IsR0FBQUEsZ0I7UUFTQUMsTyxHQUFBQSxPO1FBcUVBQyxVLEdBQUFBLFU7O0FBcE9oQjs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQSxNQUFNLEVBQUVDLE9BQUYsS0FBY0MsS0FBcEI7QUFDTyxNQUFNQyxrQ0FBYSxzQ0FBbkI7QUFDQSxNQUFNQyxnQ0FBWSxzQ0FBbEI7QUFDQSxNQUFNQyxVQUFOLENBQWlCO0FBQ3BCQyxrQkFBYztBQUNWLGFBQUssc0NBQUwsSUFBK0MsSUFBL0M7QUFDSDtBQUhtQjtRQUFYRCxVLEdBQUFBLFU7QUFLTixNQUFNRSxTQUFOLENBQWdCO0FBQ25CRCxrQkFBYztBQUNWLGFBQUssc0NBQUwsSUFBK0MsSUFBL0M7QUFDSDtBQUhrQjtRQUFWQyxTLEdBQUFBLFM7QUFLTixNQUFNQyxLQUFOLENBQVk7QUFDZkYsZ0JBQVlHLFVBQVosRUFBd0JDLE1BQXhCLEVBQWdDO0FBQzVCLGFBQUtELFVBQUwsR0FBa0IsSUFBbEI7QUFDQSxhQUFLRSxzQkFBTCxHQUE4QixFQUE5QjtBQUNBLGFBQUtDLGdCQUFMLEdBQXdCLEVBQXhCO0FBQ0EsYUFBS0MsWUFBTCxHQUFvQixFQUFwQjtBQUNBLGFBQUtDLE1BQUwsQ0FBWUwsVUFBWjtBQUNBLGFBQUtJLFlBQUwsQ0FBa0JFLElBQWxCLENBQXVCLEdBQUdMLE1BQTFCO0FBQ0g7QUFDRCxXQUFPTSxNQUFQLENBQWMsR0FBR0MsSUFBakIsRUFBdUI7QUFDbkIsWUFBSVIsYUFBYVEsS0FBS0EsS0FBS0MsTUFBTCxHQUFjLENBQW5CLENBQWpCO0FBQ0EsWUFBSUQsS0FBS0MsTUFBTCxLQUFnQixDQUFwQixFQUF1QjtBQUNuQixtQkFBTyxJQUFJLElBQUosQ0FBUyxFQUFULEVBQWEsRUFBYixDQUFQO0FBQ0gsU0FGRCxNQUVPLElBQUlULHNCQUFzQkQsS0FBMUIsRUFBaUM7QUFDcEMsbUJBQU8sSUFBSSxJQUFKLENBQVMsRUFBVCxFQUFhUyxJQUFiLENBQVA7QUFDSCxTQUZNLE1BRUE7QUFDSCxnQkFBSUUsT0FBT0YsS0FBS0csS0FBTCxDQUFXLENBQVgsRUFBYyxDQUFDLENBQWYsRUFBa0JDLEdBQWxCLENBQXNCdEIsT0FBdEIsQ0FBWDtBQUNBLG1CQUFPLElBQUksSUFBSixDQUFTVSxVQUFULEVBQXFCVSxJQUFyQixDQUFQO0FBQ0g7QUFDSjtBQUNELFdBQU9ULE1BQVAsQ0FBY1ksR0FBZCxFQUFtQjtBQUNmLFlBQUksT0FBT0EsR0FBUCxLQUFlLFFBQWYsSUFBMkJBLFFBQVEsSUFBdkMsRUFBNkMsT0FBTyxFQUFQO0FBQzdDLFlBQUlDLE9BQU8sa0JBQVVDLEdBQVYsQ0FBY0YsR0FBZCxDQUFYO0FBQ0EsWUFBSSxDQUFDQyxJQUFMLEVBQVcsT0FBTyxFQUFQO0FBQ1gsZUFBT0EsS0FBS0UsZ0JBQUwsRUFBUDtBQUNIO0FBQ0RDLFdBQU9KLEdBQVAsRUFBWTtBQUNSLFlBQUksT0FBT0EsR0FBUCxLQUFlLFFBQWYsSUFBMkJBLFFBQVEsSUFBdkMsRUFBNkMsT0FBTyxLQUFQO0FBQzdDLFlBQUlBLGVBQWVkLEtBQW5CLEVBQTBCO0FBQ3RCLG1CQUFPYyxJQUFJVCxZQUFKLENBQWlCYyxPQUFqQixDQUF5QixJQUF6QixNQUFtQyxDQUFDLENBQTNDO0FBQ0g7QUFDRCxZQUFJSixPQUFPLGtCQUFVQyxHQUFWLENBQWNGLEdBQWQsQ0FBWDtBQUNBLGVBQU8sQ0FBQyxDQUFDQyxJQUFGLElBQVVBLEtBQUtLLGVBQUwsQ0FBcUIsSUFBckIsQ0FBakI7QUFDSDtBQUNEZCxXQUFPTCxVQUFQLEVBQW1CO0FBQ2YsWUFBSSxLQUFLQSxVQUFULEVBQXFCO0FBQ2pCLGlCQUFLSSxZQUFMLENBQWtCRSxJQUFsQixDQUF1QmhCLFFBQVEsS0FBS1UsVUFBYixDQUF2QjtBQUNIO0FBQ0QsWUFBSSxPQUFPQSxVQUFQLEtBQXNCLFFBQXRCLElBQWtDLDRCQUE0QkEsVUFBbEUsRUFBOEU7QUFDMUUsZ0JBQUlvQixNQUFKO0FBQ0EsZ0JBQUlDLFlBQVlyQixXQUFXRSxzQkFBM0I7QUFDQSxnQkFBSVYsUUFBUTZCLFNBQVIsQ0FBSixFQUF3QjtBQUNwQkQseUJBQVNDLFVBQVVWLEtBQVYsRUFBVDtBQUNILGFBRkQsTUFFTyxJQUFJVSxjQUFjLElBQWQsSUFBc0JBLGNBQWNDLFNBQXhDLEVBQW1EO0FBQ3RERix5QkFBUyxFQUFUO0FBQ0gsYUFGTSxNQUVBO0FBQ0hBLHlCQUFTLENBQUNDLFNBQUQsQ0FBVDtBQUNIO0FBQ0QsbUJBQU9yQixXQUFXRSxzQkFBbEI7QUFDQSxpQkFBS0Esc0JBQUwsR0FBOEJrQixNQUE5QjtBQUNIO0FBQ0QsWUFBSSxPQUFPcEIsVUFBUCxLQUFzQixRQUF0QixJQUFrQyxzQkFBc0JBLFVBQTVELEVBQXdFO0FBQ3BFLGdCQUFJdUIsTUFBSjtBQUNBLGdCQUFJQyxZQUFZeEIsV0FBV0csZ0JBQTNCO0FBQ0EsZ0JBQUlYLFFBQVFnQyxTQUFSLENBQUosRUFBd0I7QUFDcEJELHlCQUFTQyxVQUFVYixLQUFWLEVBQVQ7QUFDSCxhQUZELE1BRU8sSUFBSWEsY0FBYyxJQUFkLElBQXNCQSxjQUFjRixTQUF4QyxFQUFtRDtBQUN0REMseUJBQVMsRUFBVDtBQUNILGFBRk0sTUFFQTtBQUNIQSx5QkFBUyxDQUFDQyxTQUFELENBQVQ7QUFDSDtBQUNELG1CQUFPeEIsV0FBV0csZ0JBQWxCO0FBQ0EsaUJBQUtBLGdCQUFMLEdBQXdCb0IsTUFBeEI7QUFDSDtBQUNELFlBQUlFLGFBQWFDLE9BQU9DLElBQVAsQ0FBWTNCLFVBQVosRUFBd0I0QixNQUF4QixDQUErQixDQUFDZixHQUFELEVBQU1nQixHQUFOLEtBQWM7QUFDMUQsZ0JBQUlDLFFBQVE5QixXQUFXNkIsR0FBWCxDQUFaO0FBQ0Esb0JBQVEsT0FBT0MsS0FBZjtBQUNJLHFCQUFLLFVBQUw7QUFDSWpCLHdCQUFJZ0IsR0FBSixJQUFXLElBQUlFLGVBQUosQ0FBb0IsRUFBRUQsS0FBRixFQUFwQixDQUFYO0FBQ0E7QUFDSixxQkFBSyxRQUFMO0FBQ0ksd0JBQUlBLFNBQVNuQyxhQUFhbUMsS0FBMUIsRUFBaUM7QUFDN0JqQiw0QkFBSWdCLEdBQUosSUFBV0MsS0FBWDtBQUNBO0FBQ0g7QUFDTDtBQUNBO0FBQ0lqQix3QkFBSWdCLEdBQUosSUFBVyxJQUFJRyxhQUFKLENBQWtCLEVBQUVGLEtBQUYsRUFBbEIsQ0FBWDtBQVhSO0FBYUEsbUJBQU9qQixHQUFQO0FBQ0gsU0FoQmdCLEVBZ0JkLGlCQWhCYyxDQUFqQjtBQWlCQSxhQUFLYixVQUFMLEdBQWtCLGlCQUFsQjtBQUNBLDBCQUFPLEtBQUtBLFVBQVosRUFBd0IseUJBQVl5QixVQUFaLENBQXhCO0FBQ0g7QUFDRFEsVUFBTUMsTUFBTixFQUFjO0FBQ1YsWUFBSXBCLE9BQU9vQixzQ0FBcUJBLHVDQUFzQix1QkFBdEQ7QUFDQSxhQUFLOUIsWUFBTCxDQUFrQitCLE9BQWxCLENBQTBCQyxLQUFLQSxFQUFFSCxLQUFGLENBQVFDLE1BQVIsQ0FBL0I7QUFDQSxhQUFLRyxlQUFMLENBQXFCSCxNQUFyQixFQUE2QkEsTUFBN0IsRUFBcUNwQixJQUFyQztBQUNBQSxhQUFLd0IsUUFBTCxDQUFjLElBQWQ7QUFDQXhCLGFBQUt5QixJQUFMO0FBQ0F6QixhQUFLMEIsTUFBTCxDQUFZTixNQUFaO0FBQ0EsZUFBT0EsTUFBUDtBQUNIO0FBQ0RPLG9CQUFnQkMsUUFBaEIsRUFBMEI7QUFDdEJBLGlCQUFTQyxTQUFULEdBQXFCakIsT0FBT25CLE1BQVAsQ0FBY21DLFNBQVNDLFNBQXZCLENBQXJCO0FBQ0EsYUFBS3ZDLFlBQUwsQ0FBa0IrQixPQUFsQixDQUEwQkMsS0FBS0EsRUFBRUssZUFBRixDQUFrQkMsUUFBbEIsQ0FBL0I7QUFDQSxhQUFLRSxtQkFBTCxDQUF5QkYsUUFBekIsRUFBbUNBLFFBQW5DO0FBQ0g7QUFDREUsd0JBQW9CQyxRQUFwQixFQUE4QkMsTUFBOUIsRUFBc0M7QUFDbEMsYUFBSzFDLFlBQUwsQ0FBa0IrQixPQUFsQixDQUEwQkMsS0FBS0EsRUFBRVEsbUJBQUYsQ0FBc0JDLFFBQXRCLEVBQWdDQyxNQUFoQyxDQUEvQjtBQUNBLGFBQUtULGVBQUwsQ0FBcUJRLFNBQVNGLFNBQTlCLEVBQXlDRyxPQUFPSCxTQUFoRCxFQUEyREUscUNBQTNEO0FBQ0FBLDhDQUFxQlAsUUFBckIsQ0FBOEIsSUFBOUI7QUFDSDtBQUNEUyxpQkFBYUMsTUFBYixFQUFxQjtBQUNqQixhQUFLNUMsWUFBTCxDQUFrQitCLE9BQWxCLENBQTBCQyxLQUFLQSxFQUFFVyxZQUFGLENBQWVDLE1BQWYsQ0FBL0I7QUFDQSxhQUFLWCxlQUFMLENBQXFCVyxNQUFyQixFQUE2QnRCLE9BQU91QixjQUFQLENBQXNCRCxNQUF0QixDQUE3QixFQUE0REEsZ0VBQTVEO0FBQ0FBLDRDQUFtQkUsY0FBbkIsQ0FBa0MsSUFBbEM7QUFDSDtBQUNEYixvQkFBZ0JILE1BQWhCLEVBQXdCaUIsTUFBeEIsRUFBZ0NyQyxJQUFoQyxFQUFzQztBQUNsQyxZQUFJQSxLQUFLSyxlQUFMLENBQXFCLElBQXJCLENBQUosRUFBZ0M7QUFDaENMLGFBQUtzQyxlQUFMLENBQXFCLElBQXJCO0FBQ0EsYUFBS2pELGdCQUFMLENBQXNCZ0MsT0FBdEIsQ0FBOEJrQixLQUFLdkMsS0FBS3dDLGlCQUFMLENBQXVCRCxDQUF2QixFQUEwQkYsT0FBT0UsQ0FBUCxDQUExQixDQUFuQztBQUNBLGFBQUtuRCxzQkFBTCxDQUE0QmlDLE9BQTVCLENBQW9Da0IsS0FBS3ZDLEtBQUt5Qyx1QkFBTCxDQUE2QkYsQ0FBN0IsRUFBZ0MsRUFBaEMsQ0FBekM7QUFDQSxZQUFJRyxlQUFKLENBQW9CLEVBQUUxQixPQUFPaEIsS0FBSzJDLHlCQUFMLEVBQVQsRUFBcEIsRUFBaUVDLE1BQWpFLENBQXdFeEIsTUFBeEUsRUFBZ0Ysd0JBQWhGO0FBQ0EsWUFBSXNCLGVBQUosQ0FBb0IsRUFBRTFCLE9BQU9oQixLQUFLNkMsbUJBQUwsRUFBVCxFQUFwQixFQUEyREQsTUFBM0QsQ0FBa0V4QixNQUFsRSxFQUEwRSxrQkFBMUU7QUFDQVIsZUFBT0MsSUFBUCxDQUFZLEtBQUszQixVQUFqQixFQUE2Qm1DLE9BQTdCLENBQXFDTixPQUFPO0FBQ3hDLGdCQUFJK0IsWUFBWSxLQUFLNUQsVUFBTCxDQUFnQjZCLEdBQWhCLENBQWhCO0FBQ0EsZ0JBQUlnQyxPQUFPRCxVQUFVRSxVQUFWLENBQXFCNUIsTUFBckIsRUFBNkJMLEdBQTdCLEVBQWtDZixJQUFsQyxDQUFYO0FBQ0ErQyxpQkFBS0gsTUFBTCxDQUFZeEIsTUFBWixFQUFvQkwsR0FBcEIsRUFBeUJzQixNQUF6QjtBQUNILFNBSkQ7QUFLQSxZQUFJSyxlQUFKLENBQW9CLEVBQUUxQixrQkFBRixFQUFwQixFQUFxQzRCLE1BQXJDLENBQTRDeEIsTUFBNUMsRUFBb0QsUUFBcEQ7QUFDSDtBQXpIYztRQUFObkMsSyxHQUFBQSxLO0FBMkhOLFNBQVNYLE1BQVQsQ0FBZ0IwRCxNQUFoQixFQUF3QixHQUFHOUMsVUFBM0IsRUFBdUM7QUFDMUMsUUFBSStELFFBQVFqQixNQUFaO0FBQ0EsUUFBSUQsV0FBVyxjQUFja0IsS0FBZCxDQUFvQixFQUFuQztBQUNBbEIsNENBQXVCLHFCQUFhbUIsVUFBYixDQUF3QmxCLG1DQUF4QixDQUF2QjtBQUNBLFFBQUk3QyxTQUFTRCxXQUFXWSxHQUFYLENBQWV0QixPQUFmLENBQWI7QUFDQXdELHdDQUFtQm1CLFdBQW5CLENBQStCcEIsUUFBL0I7QUFDQTVDLFdBQU9rQyxPQUFQLENBQWVDLEtBQUtTLHNDQUFxQlAsUUFBckIsQ0FBOEJGLENBQTlCLENBQXBCO0FBQ0Esc0JBQVU4QixjQUFWLENBQXlCckIsUUFBekIsRUFBbUNDLE1BQW5DO0FBQ0EsV0FBT0QsUUFBUDtBQUNIO0FBQ00sU0FBU3hELGdCQUFULENBQTBCeUQsTUFBMUIsRUFBa0M7QUFDckNBLHdDQUFtQnFCLGFBQW5CLEdBQW1DaEMsT0FBbkMsQ0FBMkNVLFlBQVk7QUFDbkRBLDhDQUFxQnVCLEtBQXJCLENBQTJCdEIsbUNBQTNCO0FBQ0FELGlCQUFTRixTQUFULEdBQXFCakIsT0FBT25CLE1BQVAsQ0FBY3VDLE9BQU9ILFNBQXJCLENBQXJCO0FBQ0EsMEJBQVV1QixjQUFWLENBQXlCckIsUUFBekIsRUFBbUNDLE1BQW5DO0FBQ0E7QUFDQXpELHlCQUFpQndELFFBQWpCO0FBQ0gsS0FORDtBQU9IO0FBQ00sU0FBU3ZELE9BQVQsQ0FBaUJzRSxTQUFqQixFQUE0QjtBQUMvQixRQUFJQSxxQkFBcUI3RCxLQUF6QixFQUFnQyxPQUFPNkQsU0FBUCxDQUFoQyxLQUFzRCxPQUFPLElBQUk3RCxLQUFKLENBQVU2RCxTQUFWLEVBQXFCLEVBQXJCLENBQVA7QUFDekQ7QUFDRCxNQUFNSixlQUFOLFNBQThCNUQsVUFBOUIsQ0FBeUM7QUFDckNDLGdCQUFZLEVBQUV3RSxhQUFhLElBQWYsRUFBcUJDLGVBQWUsSUFBcEMsRUFBMENDLFdBQVcsSUFBckQsRUFBMkR6QyxLQUEzRCxFQUFaLEVBQWdGO0FBQzVFO0FBQ0EsYUFBS3VDLFVBQUwsR0FBa0JBLFVBQWxCO0FBQ0EsYUFBS0MsWUFBTCxHQUFvQkEsWUFBcEI7QUFDQSxhQUFLQyxRQUFMLEdBQWdCQSxRQUFoQjtBQUNBLGFBQUt6QyxLQUFMLEdBQWFBLEtBQWI7QUFDSDtBQUNENEIsV0FBT3hCLE1BQVAsRUFBZUwsR0FBZixFQUFvQjJDLEtBQXBCLEVBQTJCO0FBQ3ZCOUMsZUFBTytDLGNBQVAsQ0FBc0J2QyxNQUF0QixFQUE4QkwsR0FBOUIsRUFBbUM7QUFDL0J3Qyx3QkFBWSxLQUFLQSxVQURjO0FBRS9CQywwQkFBYyxLQUFLQSxZQUZZO0FBRy9CQyxzQkFBVSxLQUFLQSxRQUhnQjtBQUkvQnpDLG1CQUFPLEtBQUtBO0FBSm1CLFNBQW5DO0FBTUg7QUFmb0M7QUFpQmxDLE1BQU1FLGFBQU4sU0FBNEJsQyxTQUE1QixDQUFzQztBQUN6Q0QsZ0JBQVksRUFBRXdFLGFBQWEsSUFBZixFQUFxQkMsZUFBZSxJQUFwQyxFQUEwQ0MsV0FBVyxJQUFyRCxFQUEyRHpDLEtBQTNELEVBQVosRUFBZ0Y7QUFDNUU7QUFDQSxhQUFLdUMsVUFBTCxHQUFrQkEsVUFBbEI7QUFDQSxhQUFLQyxZQUFMLEdBQW9CQSxZQUFwQjtBQUNBLGFBQUt4QyxLQUFMLEdBQWFBLEtBQWI7QUFDQSxhQUFLeUMsUUFBTCxHQUFnQkEsUUFBaEI7QUFDSDtBQUNEVCxlQUFXWSxPQUFYLEVBQW9CN0MsR0FBcEIsRUFBeUI4QyxTQUF6QixFQUFvQztBQUNoQyxZQUFJLEVBQUVOLFVBQUYsRUFBY0MsWUFBZCxFQUE0QkMsUUFBNUIsRUFBc0N6QyxLQUF0QyxLQUFnRCxJQUFwRDtBQUNBLFlBQUk2QyxVQUFVQyx1QkFBVixDQUFrQy9DLEdBQWxDLENBQUosRUFBNEM7QUFDeEM4QyxzQkFBVXBCLHVCQUFWLENBQWtDMUIsR0FBbEMsRUFBdUNDLEtBQXZDO0FBQ0FBLG9CQUFRNkMsVUFBVUUsdUJBQVYsQ0FBa0NoRCxHQUFsQyxDQUFSO0FBQ0gsU0FIRCxNQUdPLElBQUk4QyxVQUFVRyxpQkFBVixDQUE0QmpELEdBQTVCLENBQUosRUFBc0M7QUFDekM4QyxzQkFBVXJCLGlCQUFWLENBQTRCekIsR0FBNUIsRUFBaUNDLEtBQWpDO0FBQ0FBLG9CQUFRNkMsVUFBVUksaUJBQVYsQ0FBNEJsRCxHQUE1QixDQUFSO0FBQ0g7QUFDRCxlQUFPLElBQUkyQixlQUFKLENBQW9CLEVBQUVhLFVBQUYsRUFBY0MsWUFBZCxFQUE0QkMsUUFBNUIsRUFBc0N6QyxLQUF0QyxFQUFwQixDQUFQO0FBQ0g7QUFsQndDO1FBQWhDRSxhLEdBQUFBLGE7QUFvQk4sTUFBTWdELGlCQUFOLFNBQWdDbEYsU0FBaEMsQ0FBMEM7QUFDN0NELGdCQUFZLEVBQUV3RSxhQUFhLElBQWYsRUFBcUJDLGVBQWUsSUFBcEMsRUFBMENXLEdBQTFDLEVBQStDQyxHQUEvQyxFQUFaLEVBQWtFO0FBQzlEO0FBQ0EsYUFBS2IsVUFBTCxHQUFrQkEsVUFBbEI7QUFDQSxhQUFLQyxZQUFMLEdBQW9CQSxZQUFwQjtBQUNBLGFBQUtXLEdBQUwsR0FBV0EsR0FBWDtBQUNBLGFBQUtDLEdBQUwsR0FBV0EsR0FBWDtBQUNIO0FBQ0RwQixlQUFXWSxPQUFYLEVBQW9CUyxJQUFwQixFQUEwQkMsVUFBMUIsRUFBc0M7QUFDbEMsZUFBTyxJQUFJNUIsZUFBSixDQUFvQjtBQUN2QmEsd0JBQVksS0FBS0EsVUFETTtBQUV2QkMsMEJBQWMsS0FBS0EsWUFGSTtBQUd2QlcsaUJBQUssS0FBS0EsR0FIYTtBQUl2QkMsaUJBQUssS0FBS0E7QUFKYSxTQUFwQixDQUFQO0FBTUg7QUFmNEM7UUFBcENGLGlCLEdBQUFBLGlCO0FBaUJiLE1BQU1LLGdCQUFOLFNBQStCN0IsZUFBL0IsQ0FBK0M7QUFDM0NFLFdBQU94QixNQUFQLEVBQWVMLEdBQWYsRUFBb0J5RCxJQUFwQixFQUEwQjtBQUN0QixhQUFLeEQsS0FBTCxHQUFhdkMsV0FBVytGLElBQVgsRUFBaUJ6RCxHQUFqQixFQUFzQixLQUFLQyxLQUEzQixDQUFiO0FBQ0EsY0FBTTRCLE1BQU4sQ0FBYXhCLE1BQWIsRUFBcUJMLEdBQXJCLEVBQTBCeUQsSUFBMUI7QUFDSDtBQUowQztBQU0vQyxNQUFNdkQsZUFBTixTQUE4QkMsYUFBOUIsQ0FBNEM7QUFDeEM4QixlQUFXNUIsTUFBWCxFQUFtQkwsR0FBbkIsRUFBd0I4QyxTQUF4QixFQUFtQztBQUMvQixZQUFJZCxPQUFPLE1BQU1DLFVBQU4sQ0FBaUI1QixNQUFqQixFQUF5QkwsR0FBekIsRUFBOEI4QyxTQUE5QixDQUFYO0FBQ0EsZUFBTyxJQUFJVSxnQkFBSixDQUFxQnhCLElBQXJCLENBQVA7QUFDSDtBQUp1QztBQU1yQyxTQUFTdEUsVUFBVCxDQUFvQitGLElBQXBCLEVBQTBCQyxVQUExQixFQUFzQ0MsUUFBdEMsRUFBZ0Q7QUFDbkQsUUFBSSxFQUFFRCxjQUFjRCxJQUFoQixDQUFKLEVBQTJCLE9BQU9HLFVBQVVELFFBQVYsQ0FBUDtBQUMzQixRQUFJRSxjQUFjSixLQUFLQyxVQUFMLENBQWxCO0FBQ0EsUUFBSUksT0FBTyxVQUFVLEdBQUduRixJQUFiLEVBQW1CO0FBQzFCLFlBQUksQ0FBQyxJQUFMLEVBQVcsT0FBT2dGLFNBQVN2RCxLQUFULENBQWUsSUFBZixFQUFxQnpCLElBQXJCLENBQVA7QUFDWCxZQUFJb0YsWUFBWSxLQUFLQyxNQUFyQjtBQUNBLGFBQUtBLE1BQUwsR0FBY0gsV0FBZDtBQUNBLFlBQUk7QUFDQSxtQkFBT0YsU0FBU3ZELEtBQVQsQ0FBZSxJQUFmLEVBQXFCekIsSUFBckIsQ0FBUDtBQUNILFNBRkQsU0FFVTtBQUNOLGlCQUFLcUYsTUFBTCxHQUFjRCxTQUFkO0FBQ0g7QUFDSixLQVREO0FBVUFELFNBQUtHLFNBQUwsR0FBaUIsSUFBakI7QUFDQSxXQUFPSCxJQUFQO0FBQ0g7QUFDRCxTQUFTRixTQUFULENBQW1CRCxRQUFuQixFQUE2QjtBQUN6QixRQUFJLGVBQWVBLFFBQW5CLEVBQTZCLE9BQU9BLFFBQVA7QUFDN0IsV0FBTyxVQUFVLEdBQUdoRixJQUFiLEVBQW1CO0FBQ3RCLFlBQUksQ0FBQyxJQUFMLEVBQVcsT0FBT2dGLFNBQVN2RCxLQUFULENBQWUsSUFBZixFQUFxQnpCLElBQXJCLENBQVA7QUFDWCxZQUFJb0YsWUFBWSxLQUFLQyxNQUFyQjtBQUNBLGFBQUtBLE1BQUw7QUFDQSxZQUFJO0FBQ0EsbUJBQU9MLFNBQVN2RCxLQUFULENBQWUsSUFBZixFQUFxQnpCLElBQXJCLENBQVA7QUFDSCxTQUZELFNBRVU7QUFDTixpQkFBS3FGLE1BQUwsR0FBY0QsU0FBZDtBQUNIO0FBQ0osS0FURDtBQVVIIiwiZmlsZSI6ImxpYi9taXhpbi5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENMQVNTX01FVEEgfSBmcm9tICdAZ2xpbW1lci9vYmplY3QtcmVmZXJlbmNlJztcbmltcG9ydCB7IGRpY3QsIGFzc2lnbiB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuaW1wb3J0IHsgQ2xhc3NNZXRhLCBJbnN0YW5jZU1ldGEsIHR1cmJvY2hhcmdlIH0gZnJvbSAnLi9vYmplY3QnO1xuaW1wb3J0IHsgUk9PVCB9IGZyb20gJy4vdXRpbHMnO1xuY29uc3QgeyBpc0FycmF5IH0gPSBBcnJheTtcbmV4cG9ydCBjb25zdCBERVNDUklQVE9SID0gXCI1ZDkwZjg0Zi05MDhlLTRhNDItOTc0OS0zZDBmNTIzYzI2MmNcIjtcbmV4cG9ydCBjb25zdCBCTFVFUFJJTlQgPSBcIjhkOTdjZjVmLWRiOWUtNDhkOC1hNmIyLTdhNzViNzE3MDgwNVwiO1xuZXhwb3J0IGNsYXNzIERlc2NyaXB0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzW1wiNWQ5MGY4NGYtOTA4ZS00YTQyLTk3NDktM2QwZjUyM2MyNjJjXCJdID0gdHJ1ZTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgQmx1ZXByaW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpc1tcIjhkOTdjZjVmLWRiOWUtNDhkOC1hNmIyLTdhNzViNzE3MDgwNVwiXSA9IHRydWU7XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIE1peGluIHtcbiAgICBjb25zdHJ1Y3RvcihleHRlbnNpb25zLCBtaXhpbnMpIHtcbiAgICAgICAgdGhpcy5leHRlbnNpb25zID0gbnVsbDtcbiAgICAgICAgdGhpcy5jb25jYXRlbmF0ZWRQcm9wZXJ0aWVzID0gW107XG4gICAgICAgIHRoaXMubWVyZ2VkUHJvcGVydGllcyA9IFtdO1xuICAgICAgICB0aGlzLmRlcGVuZGVuY2llcyA9IFtdO1xuICAgICAgICB0aGlzLnJlb3BlbihleHRlbnNpb25zKTtcbiAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXMucHVzaCguLi5taXhpbnMpO1xuICAgIH1cbiAgICBzdGF0aWMgY3JlYXRlKC4uLmFyZ3MpIHtcbiAgICAgICAgbGV0IGV4dGVuc2lvbnMgPSBhcmdzW2FyZ3MubGVuZ3RoIC0gMV07XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyB0aGlzKHt9LCBbXSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXh0ZW5zaW9ucyBpbnN0YW5jZW9mIE1peGluKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHRoaXMoe30sIGFyZ3MpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGRlcHMgPSBhcmdzLnNsaWNlKDAsIC0xKS5tYXAodG9NaXhpbik7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHRoaXMoZXh0ZW5zaW9ucywgZGVwcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIG1peGlucyhvYmopIHtcbiAgICAgICAgaWYgKHR5cGVvZiBvYmogIT09ICdvYmplY3QnIHx8IG9iaiA9PT0gbnVsbCkgcmV0dXJuIFtdO1xuICAgICAgICBsZXQgbWV0YSA9IENsYXNzTWV0YS5mb3Iob2JqKTtcbiAgICAgICAgaWYgKCFtZXRhKSByZXR1cm4gW107XG4gICAgICAgIHJldHVybiBtZXRhLmdldEFwcGxpZWRNaXhpbnMoKTtcbiAgICB9XG4gICAgZGV0ZWN0KG9iaikge1xuICAgICAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcgfHwgb2JqID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChvYmogaW5zdGFuY2VvZiBNaXhpbikge1xuICAgICAgICAgICAgcmV0dXJuIG9iai5kZXBlbmRlbmNpZXMuaW5kZXhPZih0aGlzKSAhPT0gLTE7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG1ldGEgPSBDbGFzc01ldGEuZm9yKG9iaik7XG4gICAgICAgIHJldHVybiAhIW1ldGEgJiYgbWV0YS5oYXNBcHBsaWVkTWl4aW4odGhpcyk7XG4gICAgfVxuICAgIHJlb3BlbihleHRlbnNpb25zKSB7XG4gICAgICAgIGlmICh0aGlzLmV4dGVuc2lvbnMpIHtcbiAgICAgICAgICAgIHRoaXMuZGVwZW5kZW5jaWVzLnB1c2godG9NaXhpbih0aGlzLmV4dGVuc2lvbnMpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGV4dGVuc2lvbnMgPT09ICdvYmplY3QnICYmICdjb25jYXRlbmF0ZWRQcm9wZXJ0aWVzJyBpbiBleHRlbnNpb25zKSB7XG4gICAgICAgICAgICBsZXQgY29uY2F0O1xuICAgICAgICAgICAgbGV0IHJhd0NvbmNhdCA9IGV4dGVuc2lvbnMuY29uY2F0ZW5hdGVkUHJvcGVydGllcztcbiAgICAgICAgICAgIGlmIChpc0FycmF5KHJhd0NvbmNhdCkpIHtcbiAgICAgICAgICAgICAgICBjb25jYXQgPSByYXdDb25jYXQuc2xpY2UoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmF3Q29uY2F0ID09PSBudWxsIHx8IHJhd0NvbmNhdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uY2F0ID0gW107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbmNhdCA9IFtyYXdDb25jYXRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIGV4dGVuc2lvbnMuY29uY2F0ZW5hdGVkUHJvcGVydGllcztcbiAgICAgICAgICAgIHRoaXMuY29uY2F0ZW5hdGVkUHJvcGVydGllcyA9IGNvbmNhdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGV4dGVuc2lvbnMgPT09ICdvYmplY3QnICYmICdtZXJnZWRQcm9wZXJ0aWVzJyBpbiBleHRlbnNpb25zKSB7XG4gICAgICAgICAgICBsZXQgbWVyZ2VkO1xuICAgICAgICAgICAgbGV0IHJhd01lcmdlZCA9IGV4dGVuc2lvbnMubWVyZ2VkUHJvcGVydGllcztcbiAgICAgICAgICAgIGlmIChpc0FycmF5KHJhd01lcmdlZCkpIHtcbiAgICAgICAgICAgICAgICBtZXJnZWQgPSByYXdNZXJnZWQuc2xpY2UoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmF3TWVyZ2VkID09PSBudWxsIHx8IHJhd01lcmdlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgbWVyZ2VkID0gW107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1lcmdlZCA9IFtyYXdNZXJnZWRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZXRlIGV4dGVuc2lvbnMubWVyZ2VkUHJvcGVydGllcztcbiAgICAgICAgICAgIHRoaXMubWVyZ2VkUHJvcGVydGllcyA9IG1lcmdlZDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbm9ybWFsaXplZCA9IE9iamVjdC5rZXlzKGV4dGVuc2lvbnMpLnJlZHVjZSgob2JqLCBrZXkpID0+IHtcbiAgICAgICAgICAgIGxldCB2YWx1ZSA9IGV4dGVuc2lvbnNba2V5XTtcbiAgICAgICAgICAgIHN3aXRjaCAodHlwZW9mIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgICAgICAgICAgICAgICAgICBvYmpba2V5XSA9IG5ldyBNZXRob2RCbHVlcHJpbnQoeyB2YWx1ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlICYmIEJMVUVQUklOVCBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb2JqW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIG9ialtrZXldID0gbmV3IERhdGFCbHVlcHJpbnQoeyB2YWx1ZSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0sIGRpY3QoKSk7XG4gICAgICAgIHRoaXMuZXh0ZW5zaW9ucyA9IGRpY3QoKTtcbiAgICAgICAgYXNzaWduKHRoaXMuZXh0ZW5zaW9ucywgdHVyYm9jaGFyZ2Uobm9ybWFsaXplZCkpO1xuICAgIH1cbiAgICBhcHBseSh0YXJnZXQpIHtcbiAgICAgICAgbGV0IG1ldGEgPSB0YXJnZXRbQ0xBU1NfTUVUQV0gPSB0YXJnZXRbQ0xBU1NfTUVUQV0gfHwgbmV3IENsYXNzTWV0YSgpO1xuICAgICAgICB0aGlzLmRlcGVuZGVuY2llcy5mb3JFYWNoKG0gPT4gbS5hcHBseSh0YXJnZXQpKTtcbiAgICAgICAgdGhpcy5tZXJnZVByb3BlcnRpZXModGFyZ2V0LCB0YXJnZXQsIG1ldGEpO1xuICAgICAgICBtZXRhLmFkZE1peGluKHRoaXMpO1xuICAgICAgICBtZXRhLnNlYWwoKTtcbiAgICAgICAgbWV0YS5yZXNlYWwodGFyZ2V0KTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG4gICAgZXh0ZW5kUHJvdG90eXBlKE9yaWdpbmFsKSB7XG4gICAgICAgIE9yaWdpbmFsLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoT3JpZ2luYWwucHJvdG90eXBlKTtcbiAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXMuZm9yRWFjaChtID0+IG0uZXh0ZW5kUHJvdG90eXBlKE9yaWdpbmFsKSk7XG4gICAgICAgIHRoaXMuZXh0ZW5kUHJvdG90eXBlT250byhPcmlnaW5hbCwgT3JpZ2luYWwpO1xuICAgIH1cbiAgICBleHRlbmRQcm90b3R5cGVPbnRvKFN1YmNsYXNzLCBQYXJlbnQpIHtcbiAgICAgICAgdGhpcy5kZXBlbmRlbmNpZXMuZm9yRWFjaChtID0+IG0uZXh0ZW5kUHJvdG90eXBlT250byhTdWJjbGFzcywgUGFyZW50KSk7XG4gICAgICAgIHRoaXMubWVyZ2VQcm9wZXJ0aWVzKFN1YmNsYXNzLnByb3RvdHlwZSwgUGFyZW50LnByb3RvdHlwZSwgU3ViY2xhc3NbQ0xBU1NfTUVUQV0pO1xuICAgICAgICBTdWJjbGFzc1tDTEFTU19NRVRBXS5hZGRNaXhpbih0aGlzKTtcbiAgICB9XG4gICAgZXh0ZW5kU3RhdGljKFRhcmdldCkge1xuICAgICAgICB0aGlzLmRlcGVuZGVuY2llcy5mb3JFYWNoKG0gPT4gbS5leHRlbmRTdGF0aWMoVGFyZ2V0KSk7XG4gICAgICAgIHRoaXMubWVyZ2VQcm9wZXJ0aWVzKFRhcmdldCwgT2JqZWN0LmdldFByb3RvdHlwZU9mKFRhcmdldCksIFRhcmdldFtDTEFTU19NRVRBXVtDTEFTU19NRVRBXSk7XG4gICAgICAgIFRhcmdldFtDTEFTU19NRVRBXS5hZGRTdGF0aWNNaXhpbih0aGlzKTtcbiAgICB9XG4gICAgbWVyZ2VQcm9wZXJ0aWVzKHRhcmdldCwgcGFyZW50LCBtZXRhKSB7XG4gICAgICAgIGlmIChtZXRhLmhhc0FwcGxpZWRNaXhpbih0aGlzKSkgcmV0dXJuO1xuICAgICAgICBtZXRhLmFkZEFwcGxpZWRNaXhpbih0aGlzKTtcbiAgICAgICAgdGhpcy5tZXJnZWRQcm9wZXJ0aWVzLmZvckVhY2goayA9PiBtZXRhLmFkZE1lcmdlZFByb3BlcnR5KGssIHBhcmVudFtrXSkpO1xuICAgICAgICB0aGlzLmNvbmNhdGVuYXRlZFByb3BlcnRpZXMuZm9yRWFjaChrID0+IG1ldGEuYWRkQ29uY2F0ZW5hdGVkUHJvcGVydHkoaywgW10pKTtcbiAgICAgICAgbmV3IFZhbHVlRGVzY3JpcHRvcih7IHZhbHVlOiBtZXRhLmdldENvbmNhdGVuYXRlZFByb3BlcnRpZXMoKSB9KS5kZWZpbmUodGFyZ2V0LCAnY29uY2F0ZW5hdGVkUHJvcGVydGllcycpO1xuICAgICAgICBuZXcgVmFsdWVEZXNjcmlwdG9yKHsgdmFsdWU6IG1ldGEuZ2V0TWVyZ2VkUHJvcGVydGllcygpIH0pLmRlZmluZSh0YXJnZXQsICdtZXJnZWRQcm9wZXJ0aWVzJyk7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuZXh0ZW5zaW9ucykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgbGV0IGV4dGVuc2lvbiA9IHRoaXMuZXh0ZW5zaW9uc1trZXldO1xuICAgICAgICAgICAgbGV0IGRlc2MgPSBleHRlbnNpb24uZGVzY3JpcHRvcih0YXJnZXQsIGtleSwgbWV0YSk7XG4gICAgICAgICAgICBkZXNjLmRlZmluZSh0YXJnZXQsIGtleSwgcGFyZW50KTtcbiAgICAgICAgfSk7XG4gICAgICAgIG5ldyBWYWx1ZURlc2NyaXB0b3IoeyB2YWx1ZTogUk9PVCB9KS5kZWZpbmUodGFyZ2V0LCAnX3N1cGVyJyk7XG4gICAgfVxufVxuZXhwb3J0IGZ1bmN0aW9uIGV4dGVuZChQYXJlbnQsIC4uLmV4dGVuc2lvbnMpIHtcbiAgICBsZXQgU3VwZXIgPSBQYXJlbnQ7XG4gICAgbGV0IFN1YmNsYXNzID0gY2xhc3MgZXh0ZW5kcyBTdXBlciB7fTtcbiAgICBTdWJjbGFzc1tDTEFTU19NRVRBXSA9IEluc3RhbmNlTWV0YS5mcm9tUGFyZW50KFBhcmVudFtDTEFTU19NRVRBXSk7XG4gICAgbGV0IG1peGlucyA9IGV4dGVuc2lvbnMubWFwKHRvTWl4aW4pO1xuICAgIFBhcmVudFtDTEFTU19NRVRBXS5hZGRTdWJjbGFzcyhTdWJjbGFzcyk7XG4gICAgbWl4aW5zLmZvckVhY2gobSA9PiBTdWJjbGFzc1tDTEFTU19NRVRBXS5hZGRNaXhpbihtKSk7XG4gICAgQ2xhc3NNZXRhLmFwcGx5QWxsTWl4aW5zKFN1YmNsYXNzLCBQYXJlbnQpO1xuICAgIHJldHVybiBTdWJjbGFzcztcbn1cbmV4cG9ydCBmdW5jdGlvbiByZWxpbmtTdWJjbGFzc2VzKFBhcmVudCkge1xuICAgIFBhcmVudFtDTEFTU19NRVRBXS5nZXRTdWJjbGFzc2VzKCkuZm9yRWFjaChTdWJjbGFzcyA9PiB7XG4gICAgICAgIFN1YmNsYXNzW0NMQVNTX01FVEFdLnJlc2V0KFBhcmVudFtDTEFTU19NRVRBXSk7XG4gICAgICAgIFN1YmNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoUGFyZW50LnByb3RvdHlwZSk7XG4gICAgICAgIENsYXNzTWV0YS5hcHBseUFsbE1peGlucyhTdWJjbGFzcywgUGFyZW50KTtcbiAgICAgICAgLy8gcmVjdXJzZSBpbnRvIHN1Yi1zdWJjbGFzc2VzXG4gICAgICAgIHJlbGlua1N1YmNsYXNzZXMoU3ViY2xhc3MpO1xuICAgIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHRvTWl4aW4oZXh0ZW5zaW9uKSB7XG4gICAgaWYgKGV4dGVuc2lvbiBpbnN0YW5jZW9mIE1peGluKSByZXR1cm4gZXh0ZW5zaW9uO2Vsc2UgcmV0dXJuIG5ldyBNaXhpbihleHRlbnNpb24sIFtdKTtcbn1cbmNsYXNzIFZhbHVlRGVzY3JpcHRvciBleHRlbmRzIERlc2NyaXB0b3Ige1xuICAgIGNvbnN0cnVjdG9yKHsgZW51bWVyYWJsZSA9IHRydWUsIGNvbmZpZ3VyYWJsZSA9IHRydWUsIHdyaXRhYmxlID0gdHJ1ZSwgdmFsdWUgfSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmVudW1lcmFibGUgPSBlbnVtZXJhYmxlO1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYWJsZSA9IGNvbmZpZ3VyYWJsZTtcbiAgICAgICAgdGhpcy53cml0YWJsZSA9IHdyaXRhYmxlO1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuICAgIGRlZmluZSh0YXJnZXQsIGtleSwgX2hvbWUpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0aGlzLmVudW1lcmFibGUsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRoaXMuY29uZmlndXJhYmxlLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRoaXMud3JpdGFibGUsXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZVxuICAgICAgICB9KTtcbiAgICB9XG59XG5leHBvcnQgY2xhc3MgRGF0YUJsdWVwcmludCBleHRlbmRzIEJsdWVwcmludCB7XG4gICAgY29uc3RydWN0b3IoeyBlbnVtZXJhYmxlID0gdHJ1ZSwgY29uZmlndXJhYmxlID0gdHJ1ZSwgd3JpdGFibGUgPSB0cnVlLCB2YWx1ZSB9KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuZW51bWVyYWJsZSA9IGVudW1lcmFibGU7XG4gICAgICAgIHRoaXMuY29uZmlndXJhYmxlID0gY29uZmlndXJhYmxlO1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIHRoaXMud3JpdGFibGUgPSB3cml0YWJsZTtcbiAgICB9XG4gICAgZGVzY3JpcHRvcihfdGFyZ2V0LCBrZXksIGNsYXNzTWV0YSkge1xuICAgICAgICBsZXQgeyBlbnVtZXJhYmxlLCBjb25maWd1cmFibGUsIHdyaXRhYmxlLCB2YWx1ZSB9ID0gdGhpcztcbiAgICAgICAgaWYgKGNsYXNzTWV0YS5oYXNDb25jYXRlbmF0ZWRQcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICBjbGFzc01ldGEuYWRkQ29uY2F0ZW5hdGVkUHJvcGVydHkoa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICB2YWx1ZSA9IGNsYXNzTWV0YS5nZXRDb25jYXRlbmF0ZWRQcm9wZXJ0eShrZXkpO1xuICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTWV0YS5oYXNNZXJnZWRQcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICBjbGFzc01ldGEuYWRkTWVyZ2VkUHJvcGVydHkoa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICB2YWx1ZSA9IGNsYXNzTWV0YS5nZXRNZXJnZWRQcm9wZXJ0eShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVmFsdWVEZXNjcmlwdG9yKHsgZW51bWVyYWJsZSwgY29uZmlndXJhYmxlLCB3cml0YWJsZSwgdmFsdWUgfSk7XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIEFjY2Vzc29yQmx1ZXByaW50IGV4dGVuZHMgQmx1ZXByaW50IHtcbiAgICBjb25zdHJ1Y3Rvcih7IGVudW1lcmFibGUgPSB0cnVlLCBjb25maWd1cmFibGUgPSB0cnVlLCBnZXQsIHNldCB9KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuZW51bWVyYWJsZSA9IGVudW1lcmFibGU7XG4gICAgICAgIHRoaXMuY29uZmlndXJhYmxlID0gY29uZmlndXJhYmxlO1xuICAgICAgICB0aGlzLmdldCA9IGdldDtcbiAgICAgICAgdGhpcy5zZXQgPSBzZXQ7XG4gICAgfVxuICAgIGRlc2NyaXB0b3IoX3RhcmdldCwgX2tleSwgX2NsYXNzTWV0YSkge1xuICAgICAgICByZXR1cm4gbmV3IFZhbHVlRGVzY3JpcHRvcih7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0aGlzLmVudW1lcmFibGUsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRoaXMuY29uZmlndXJhYmxlLFxuICAgICAgICAgICAgZ2V0OiB0aGlzLmdldCxcbiAgICAgICAgICAgIHNldDogdGhpcy5zZXRcbiAgICAgICAgfSk7XG4gICAgfVxufVxuY2xhc3MgTWV0aG9kRGVzY3JpcHRvciBleHRlbmRzIFZhbHVlRGVzY3JpcHRvciB7XG4gICAgZGVmaW5lKHRhcmdldCwga2V5LCBob21lKSB7XG4gICAgICAgIHRoaXMudmFsdWUgPSB3cmFwTWV0aG9kKGhvbWUsIGtleSwgdGhpcy52YWx1ZSk7XG4gICAgICAgIHN1cGVyLmRlZmluZSh0YXJnZXQsIGtleSwgaG9tZSk7XG4gICAgfVxufVxuY2xhc3MgTWV0aG9kQmx1ZXByaW50IGV4dGVuZHMgRGF0YUJsdWVwcmludCB7XG4gICAgZGVzY3JpcHRvcih0YXJnZXQsIGtleSwgY2xhc3NNZXRhKSB7XG4gICAgICAgIGxldCBkZXNjID0gc3VwZXIuZGVzY3JpcHRvcih0YXJnZXQsIGtleSwgY2xhc3NNZXRhKTtcbiAgICAgICAgcmV0dXJuIG5ldyBNZXRob2REZXNjcmlwdG9yKGRlc2MpO1xuICAgIH1cbn1cbmV4cG9ydCBmdW5jdGlvbiB3cmFwTWV0aG9kKGhvbWUsIG1ldGhvZE5hbWUsIG9yaWdpbmFsKSB7XG4gICAgaWYgKCEobWV0aG9kTmFtZSBpbiBob21lKSkgcmV0dXJuIG1heWJlV3JhcChvcmlnaW5hbCk7XG4gICAgbGV0IHN1cGVyTWV0aG9kID0gaG9tZVttZXRob2ROYW1lXTtcbiAgICBsZXQgZnVuYyA9IGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgIGlmICghdGhpcykgcmV0dXJuIG9yaWdpbmFsLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICBsZXQgbGFzdFN1cGVyID0gdGhpcy5fc3VwZXI7XG4gICAgICAgIHRoaXMuX3N1cGVyID0gc3VwZXJNZXRob2Q7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gb3JpZ2luYWwuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICB0aGlzLl9zdXBlciA9IGxhc3RTdXBlcjtcbiAgICAgICAgfVxuICAgIH07XG4gICAgZnVuYy5fX3dyYXBwZWQgPSB0cnVlO1xuICAgIHJldHVybiBmdW5jO1xufVxuZnVuY3Rpb24gbWF5YmVXcmFwKG9yaWdpbmFsKSB7XG4gICAgaWYgKCdfX3dyYXBwZWQnIGluIG9yaWdpbmFsKSByZXR1cm4gb3JpZ2luYWw7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgIGlmICghdGhpcykgcmV0dXJuIG9yaWdpbmFsLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICBsZXQgbGFzdFN1cGVyID0gdGhpcy5fc3VwZXI7XG4gICAgICAgIHRoaXMuX3N1cGVyID0gUk9PVDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHRoaXMuX3N1cGVyID0gbGFzdFN1cGVyO1xuICAgICAgICB9XG4gICAgfTtcbn0iXX0=