ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
478 lines (391 loc) • 43.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Environment = exports.Program = exports.Heap = exports.Opcode = exports.Scope = undefined;
var _functions = require("./syntax/functions");
var _constants = require("./environment/constants");
var _references = require("./references");
var _attributeManagers = require("./dom/attribute-managers");
var _util = require("@glimmer/util");
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);
}
}return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;
};
}();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var Scope = exports.Scope = function () {
function Scope(
// the 0th slot is `self`
slots, callerScope,
// named arguments and blocks passed to a layout that uses eval
evalScope,
// locals in scope when the partial was invoked
partialMap) {
_classCallCheck(this, Scope);
this.slots = slots;
this.callerScope = callerScope;
this.evalScope = evalScope;
this.partialMap = partialMap;
}
Scope.root = function root(self) {
var size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var refs = new Array(size + 1);
for (var i = 0; i <= size; i++) {
refs[i] = _references.UNDEFINED_REFERENCE;
}
return new Scope(refs, null, null, null).init({ self: self });
};
Scope.sized = function sized() {
var size = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var refs = new Array(size + 1);
for (var i = 0; i <= size; i++) {
refs[i] = _references.UNDEFINED_REFERENCE;
}
return new Scope(refs, null, null, null);
};
Scope.prototype.init = function init(_ref) {
var self = _ref.self;
this.slots[0] = self;
return this;
};
Scope.prototype.getSelf = function getSelf() {
return this.get(0);
};
Scope.prototype.getSymbol = function getSymbol(symbol) {
return this.get(symbol);
};
Scope.prototype.getBlock = function getBlock(symbol) {
return this.get(symbol);
};
Scope.prototype.getEvalScope = function getEvalScope() {
return this.evalScope;
};
Scope.prototype.getPartialMap = function getPartialMap() {
return this.partialMap;
};
Scope.prototype.bind = function bind(symbol, value) {
this.set(symbol, value);
};
Scope.prototype.bindSelf = function bindSelf(self) {
this.set(0, self);
};
Scope.prototype.bindSymbol = function bindSymbol(symbol, value) {
this.set(symbol, value);
};
Scope.prototype.bindBlock = function bindBlock(symbol, value) {
this.set(symbol, value);
};
Scope.prototype.bindEvalScope = function bindEvalScope(map) {
this.evalScope = map;
};
Scope.prototype.bindPartialMap = function bindPartialMap(map) {
this.partialMap = map;
};
Scope.prototype.bindCallerScope = function bindCallerScope(scope) {
this.callerScope = scope;
};
Scope.prototype.getCallerScope = function getCallerScope() {
return this.callerScope;
};
Scope.prototype.child = function child() {
return new Scope(this.slots.slice(), this.callerScope, this.evalScope, this.partialMap);
};
Scope.prototype.get = function get(index) {
if (index >= this.slots.length) {
throw new RangeError('BUG: cannot get $' + index + ' from scope; length=' + this.slots.length);
}
return this.slots[index];
};
Scope.prototype.set = function set(index, value) {
if (index >= this.slots.length) {
throw new RangeError('BUG: cannot get $' + index + ' from scope; length=' + this.slots.length);
}
this.slots[index] = value;
};
return Scope;
}();
var Transaction = function () {
function Transaction() {
_classCallCheck(this, Transaction);
this.scheduledInstallManagers = [];
this.scheduledInstallModifiers = [];
this.scheduledUpdateModifierManagers = [];
this.scheduledUpdateModifiers = [];
this.createdComponents = [];
this.createdManagers = [];
this.updatedComponents = [];
this.updatedManagers = [];
this.destructors = [];
}
Transaction.prototype.didCreate = function didCreate(component, manager) {
this.createdComponents.push(component);
this.createdManagers.push(manager);
};
Transaction.prototype.didUpdate = function didUpdate(component, manager) {
this.updatedComponents.push(component);
this.updatedManagers.push(manager);
};
Transaction.prototype.scheduleInstallModifier = function scheduleInstallModifier(modifier, manager) {
this.scheduledInstallManagers.push(manager);
this.scheduledInstallModifiers.push(modifier);
};
Transaction.prototype.scheduleUpdateModifier = function scheduleUpdateModifier(modifier, manager) {
this.scheduledUpdateModifierManagers.push(manager);
this.scheduledUpdateModifiers.push(modifier);
};
Transaction.prototype.didDestroy = function didDestroy(d) {
this.destructors.push(d);
};
Transaction.prototype.commit = function commit() {
var createdComponents = this.createdComponents,
createdManagers = this.createdManagers;
for (var i = 0; i < createdComponents.length; i++) {
var component = createdComponents[i];
var manager = createdManagers[i];
manager.didCreate(component);
}
var updatedComponents = this.updatedComponents,
updatedManagers = this.updatedManagers;
for (var _i = 0; _i < updatedComponents.length; _i++) {
var _component = updatedComponents[_i];
var _manager = updatedManagers[_i];
_manager.didUpdate(_component);
}
var destructors = this.destructors;
for (var _i2 = 0; _i2 < destructors.length; _i2++) {
destructors[_i2].destroy();
}
var scheduledInstallManagers = this.scheduledInstallManagers,
scheduledInstallModifiers = this.scheduledInstallModifiers;
for (var _i3 = 0; _i3 < scheduledInstallManagers.length; _i3++) {
var _manager2 = scheduledInstallManagers[_i3];
var modifier = scheduledInstallModifiers[_i3];
_manager2.install(modifier);
}
var scheduledUpdateModifierManagers = this.scheduledUpdateModifierManagers,
scheduledUpdateModifiers = this.scheduledUpdateModifiers;
for (var _i4 = 0; _i4 < scheduledUpdateModifierManagers.length; _i4++) {
var _manager3 = scheduledUpdateModifierManagers[_i4];
var _modifier = scheduledUpdateModifiers[_i4];
_manager3.update(_modifier);
}
};
return Transaction;
}();
var Opcode = exports.Opcode = function () {
function Opcode(heap) {
_classCallCheck(this, Opcode);
this.heap = heap;
this.offset = 0;
}
_createClass(Opcode, [{
key: 'type',
get: function () {
return this.heap.getbyaddr(this.offset);
}
}, {
key: 'op1',
get: function () {
return this.heap.getbyaddr(this.offset + 1);
}
}, {
key: 'op2',
get: function () {
return this.heap.getbyaddr(this.offset + 2);
}
}, {
key: 'op3',
get: function () {
return this.heap.getbyaddr(this.offset + 3);
}
}]);
return Opcode;
}();
var TableSlotState;
(function (TableSlotState) {
TableSlotState[TableSlotState["Allocated"] = 0] = "Allocated";
TableSlotState[TableSlotState["Freed"] = 1] = "Freed";
TableSlotState[TableSlotState["Purged"] = 2] = "Purged";
TableSlotState[TableSlotState["Pointer"] = 3] = "Pointer";
})(TableSlotState || (TableSlotState = {}));
var Heap = exports.Heap = function () {
function Heap() {
_classCallCheck(this, Heap);
this.heap = [];
this.offset = 0;
this.handle = 0;
/**
* layout:
*
* - pointer into heap
* - size
* - freed (0 or 1)
*/
this.table = [];
}
Heap.prototype.push = function push(item) {
this.heap[this.offset++] = item;
};
Heap.prototype.getbyaddr = function getbyaddr(address) {
return this.heap[address];
};
Heap.prototype.setbyaddr = function setbyaddr(address, value) {
this.heap[address] = value;
};
Heap.prototype.malloc = function malloc() {
this.table.push(this.offset, 0, 0);
var handle = this.handle;
this.handle += 3;
return handle;
};
Heap.prototype.finishMalloc = function finishMalloc(handle) {
var start = this.table[handle];
var finish = this.offset;
this.table[handle + 1] = finish - start;
};
Heap.prototype.size = function size() {
return this.offset;
};
// It is illegal to close over this address, as compaction
// may move it. However, it is legal to use this address
// multiple times between compactions.
Heap.prototype.getaddr = function getaddr(handle) {
return this.table[handle];
};
Heap.prototype.gethandle = function gethandle(address) {
this.table.push(address, 0, TableSlotState.Pointer);
var handle = this.handle;
this.handle += 3;
return handle;
};
Heap.prototype.sizeof = function sizeof(handle) {
if (false) {
return this.table[handle + 1];
}
return -1;
};
Heap.prototype.free = function free(handle) {
this.table[handle + 2] = 1;
};
Heap.prototype.compact = function compact() {
var compactedSize = 0;
var table = this.table,
length = this.table.length,
heap = this.heap;
for (var i = 0; i < length; i += 3) {
var offset = table[i];
var size = table[i + 1];
var state = table[i + 2];
if (state === TableSlotState.Purged) {
continue;
} else if (state === TableSlotState.Freed) {
// transition to "already freed"
// a good improvement would be to reuse
// these slots
table[i + 2] = 2;
compactedSize += size;
} else if (state === TableSlotState.Allocated) {
for (var j = offset; j <= i + size; j++) {
heap[j - compactedSize] = heap[j];
}
table[i] = offset - compactedSize;
} else if (state === TableSlotState.Pointer) {
table[i] = offset - compactedSize;
}
}
this.offset = this.offset - compactedSize;
};
return Heap;
}();
var Program = exports.Program = function () {
function Program() {
_classCallCheck(this, Program);
this.heap = new Heap();
this._opcode = new Opcode(this.heap);
this.constants = new _constants.Constants();
}
Program.prototype.opcode = function opcode(offset) {
this._opcode.offset = offset;
return this._opcode;
};
return Program;
}();
var Environment = exports.Environment = function () {
function Environment(_ref2) {
var appendOperations = _ref2.appendOperations,
updateOperations = _ref2.updateOperations;
_classCallCheck(this, Environment);
this._macros = null;
this._transaction = null;
this.program = new Program();
this.appendOperations = appendOperations;
this.updateOperations = updateOperations;
}
Environment.prototype.toConditionalReference = function toConditionalReference(reference) {
return new _references.ConditionalReference(reference);
};
Environment.prototype.getAppendOperations = function getAppendOperations() {
return this.appendOperations;
};
Environment.prototype.getDOM = function getDOM() {
return this.updateOperations;
};
Environment.prototype.getIdentity = function getIdentity(object) {
return (0, _util.ensureGuid)(object) + '';
};
Environment.prototype.begin = function begin() {
(0, _util.assert)(!this._transaction, 'a glimmer transaction was begun, but one already exists. You may have a nested transaction');
this._transaction = new Transaction();
};
Environment.prototype.didCreate = function didCreate(component, manager) {
this.transaction.didCreate(component, manager);
};
Environment.prototype.didUpdate = function didUpdate(component, manager) {
this.transaction.didUpdate(component, manager);
};
Environment.prototype.scheduleInstallModifier = function scheduleInstallModifier(modifier, manager) {
this.transaction.scheduleInstallModifier(modifier, manager);
};
Environment.prototype.scheduleUpdateModifier = function scheduleUpdateModifier(modifier, manager) {
this.transaction.scheduleUpdateModifier(modifier, manager);
};
Environment.prototype.didDestroy = function didDestroy(d) {
this.transaction.didDestroy(d);
};
Environment.prototype.commit = function commit() {
var transaction = this.transaction;
this._transaction = null;
transaction.commit();
};
Environment.prototype.attributeFor = function attributeFor(element, attr, isTrusting, namespace) {
return (0, _attributeManagers.defaultManagers)(element, attr, isTrusting, namespace === undefined ? null : namespace);
};
Environment.prototype.macros = function macros() {
var macros = this._macros;
if (!macros) {
this._macros = macros = this.populateBuiltins();
}
return macros;
};
Environment.prototype.populateBuiltins = function populateBuiltins() {
return (0, _functions.populateBuiltins)();
};
_createClass(Environment, [{
key: 'transaction',
get: function () {
return this._transaction;
}
}]);
return Environment;
}();
exports.default = Environment;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9lbnZpcm9ubWVudC5qcyJdLCJuYW1lcyI6WyJwb3B1bGF0ZUJ1aWx0aW5zIiwiQ29uc3RhbnRzIiwiVU5ERUZJTkVEX1JFRkVSRU5DRSIsIkNvbmRpdGlvbmFsUmVmZXJlbmNlIiwiZGVmYXVsdE1hbmFnZXJzIiwiYXNzZXJ0IiwiZW5zdXJlR3VpZCIsIlNjb3BlIiwic2xvdHMiLCJjYWxsZXJTY29wZSIsImV2YWxTY29wZSIsInBhcnRpYWxNYXAiLCJyb290Iiwic2VsZiIsInNpemUiLCJyZWZzIiwiQXJyYXkiLCJpIiwiaW5pdCIsInNpemVkIiwiZ2V0U2VsZiIsImdldCIsImdldFN5bWJvbCIsInN5bWJvbCIsImdldEJsb2NrIiwiZ2V0RXZhbFNjb3BlIiwiZ2V0UGFydGlhbE1hcCIsImJpbmQiLCJ2YWx1ZSIsInNldCIsImJpbmRTZWxmIiwiYmluZFN5bWJvbCIsImJpbmRCbG9jayIsImJpbmRFdmFsU2NvcGUiLCJtYXAiLCJiaW5kUGFydGlhbE1hcCIsImJpbmRDYWxsZXJTY29wZSIsInNjb3BlIiwiZ2V0Q2FsbGVyU2NvcGUiLCJjaGlsZCIsInNsaWNlIiwiaW5kZXgiLCJsZW5ndGgiLCJSYW5nZUVycm9yIiwiVHJhbnNhY3Rpb24iLCJzY2hlZHVsZWRJbnN0YWxsTWFuYWdlcnMiLCJzY2hlZHVsZWRJbnN0YWxsTW9kaWZpZXJzIiwic2NoZWR1bGVkVXBkYXRlTW9kaWZpZXJNYW5hZ2VycyIsInNjaGVkdWxlZFVwZGF0ZU1vZGlmaWVycyIsImNyZWF0ZWRDb21wb25lbnRzIiwiY3JlYXRlZE1hbmFnZXJzIiwidXBkYXRlZENvbXBvbmVudHMiLCJ1cGRhdGVkTWFuYWdlcnMiLCJkZXN0cnVjdG9ycyIsImRpZENyZWF0ZSIsImNvbXBvbmVudCIsIm1hbmFnZXIiLCJwdXNoIiwiZGlkVXBkYXRlIiwic2NoZWR1bGVJbnN0YWxsTW9kaWZpZXIiLCJtb2RpZmllciIsInNjaGVkdWxlVXBkYXRlTW9kaWZpZXIiLCJkaWREZXN0cm95IiwiZCIsImNvbW1pdCIsImRlc3Ryb3kiLCJpbnN0YWxsIiwidXBkYXRlIiwiT3Bjb2RlIiwiaGVhcCIsIm9mZnNldCIsImdldGJ5YWRkciIsIlRhYmxlU2xvdFN0YXRlIiwiSGVhcCIsImhhbmRsZSIsInRhYmxlIiwiaXRlbSIsImFkZHJlc3MiLCJzZXRieWFkZHIiLCJtYWxsb2MiLCJmaW5pc2hNYWxsb2MiLCJzdGFydCIsImZpbmlzaCIsImdldGFkZHIiLCJnZXRoYW5kbGUiLCJQb2ludGVyIiwic2l6ZW9mIiwiZnJlZSIsImNvbXBhY3QiLCJjb21wYWN0ZWRTaXplIiwic3RhdGUiLCJQdXJnZWQiLCJGcmVlZCIsIkFsbG9jYXRlZCIsImoiLCJQcm9ncmFtIiwiX29wY29kZSIsImNvbnN0YW50cyIsIm9wY29kZSIsIkVudmlyb25tZW50IiwiYXBwZW5kT3BlcmF0aW9ucyIsInVwZGF0ZU9wZXJhdGlvbnMiLCJfbWFjcm9zIiwiX3RyYW5zYWN0aW9uIiwicHJvZ3JhbSIsInRvQ29uZGl0aW9uYWxSZWZlcmVuY2UiLCJyZWZlcmVuY2UiLCJnZXRBcHBlbmRPcGVyYXRpb25zIiwiZ2V0RE9NIiwiZ2V0SWRlbnRpdHkiLCJvYmplY3QiLCJiZWdpbiIsInRyYW5zYWN0aW9uIiwiYXR0cmlidXRlRm9yIiwiZWxlbWVudCIsImF0dHIiLCJpc1RydXN0aW5nIiwibmFtZXNwYWNlIiwidW5kZWZpbmVkIiwibWFjcm9zIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUEsQUFBUyxBQUF3Qjs7QUFDakMsQUFBUyxBQUFpQjs7QUFDMUIsQUFBUyxBQUFxQixBQUE0Qjs7QUFDMUQsQUFBUyxBQUF1Qjs7QUFDaEMsQUFBUyxBQUFRLEFBQTBCLEFBRTNDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFBQSxBQUFhLG9DQUNUO2FBQ0E7QUFDQTtBQUZBLFdBQUEsQUFFTyxBQUNQO0FBQ0E7QUFKQSxBQUtBO0FBQ0E7QUFOQSxnQkFNWTs4QkFDUjs7YUFBQSxBQUFLLFFBQUwsQUFBYSxBQUNiO2FBQUEsQUFBSyxjQUFMLEFBQW1CLEFBQ25CO2FBQUEs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QUFpQ3NDLFNBQVMsQUFDdkM7YUFBQSxBQUFLLFlBQUwsQUFBaUIsd0JBQWpCLEFBQXlDLFVBQXpDLEFBQW1ELEFBQ3REO0FBbkNMOzswQkFBQSxBQW9DSSx5REFwQ0osQUFvQzJCLFVBcEMzQixBQW9DcUMsU0FBUyxBQUN0QzthQUFBLEFBQUssWUFBTCxBQUFpQix1QkFBakIsQUFBd0MsVUFBeEMsQUFBa0QsQUFDckQ7QUF0Q0w7OzBCQUFBLEFBdUNJLGlDQXZDSixBQXVDZSxHQUFHLEFBQ1Y7YUFBQSxBQUFLLFlBQUwsQUFBaUIsV0FBakIsQUFBNEIsQUFDL0I7QUF6Q0w7OzBCQUFBLEFBMENJLDJCQUFTLEFBQ0w7WUFBSSxjQUFjLEtBQWxCLEFBQXVCLEFBQ3ZCO2FBQUEsQUFBSyxlQUFMLEFBQW9CLEFBQ3BCO29CQUFBLEFBQVksQUFDZjtBQTlDTDs7MEJBQUEsQUErQ0kscUNBL0NKLEFBK0NpQixTQS9DakIsQUErQzBCLE1BL0MxQixBQStDZ0MsWUEvQ2hDLEFBK0M0QyxXQUFXLEFBQy9DO2VBQU8sd0NBQUEsQUFBZ0IsU0FBaEIsQUFBeUIsTUFBekIsQUFBK0IsWUFBWSxjQUFBLEFBQWMsWUFBZCxBQUEwQixPQUE1RSxBQUFPLEFBQTRFLEFBQ3RGO0FBakRMOzswQkFBQSxBQWtESSwyQkFBUyxBQUNMO1lBQUksU0FBUyxLQUFiLEFBQWtCLEFBQ2xCO1lBQUksQ0FBSixBQUFLLFFBQVEsQUFDVDtpQkFBQSxBQUFLLFVBQVUsU0FBUyxLQUF4QixBQUF3QixBQUFLLEFBQ2hDO0FBQ0Q7ZUFBQSxBQUFPLEFBQ1Y7QUF4REw7OzBCQUFBLEFBeURJLCtDQUFtQixBQUNmO2VBQUEsQUFBTyxBQUNWO0FBM0RMOzs7YUFBQTt5QkF3QnNCLEFBQ2Q7bUJBQWMsS0FBZCxBQUFtQixBQUN0QjtBQTFCTDtBQUFBOztXQUFBO0FBNkRBO2tCQUFBLEFBQWUiLCJmaWxlIjoibGliL2Vudmlyb25tZW50LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcG9wdWxhdGVCdWlsdGlucyB9IGZyb20gJy4vc3ludGF4L2Z1bmN0aW9ucyc7XG5pbXBvcnQgeyBDb25zdGFudHMgfSBmcm9tICcuL2Vudmlyb25tZW50L2NvbnN0YW50cyc7XG5pbXBvcnQgeyBVTkRFRklORURfUkVGRVJFTkNFLCBDb25kaXRpb25hbFJlZmVyZW5jZSB9IGZyb20gJy4vcmVmZXJlbmNlcyc7XG5pbXBvcnQgeyBkZWZhdWx0TWFuYWdlcnMgfSBmcm9tICcuL2RvbS9hdHRyaWJ1dGUtbWFuYWdlcnMnO1xuaW1wb3J0IHsgYXNzZXJ0LCBlbnN1cmVHdWlkLCBleHBlY3QgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcblxuZXhwb3J0IGNsYXNzIFNjb3BlIHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvLyB0aGUgMHRoIHNsb3QgaXMgYHNlbGZgXG4gICAgc2xvdHMsIGNhbGxlclNjb3BlLFxuICAgIC8vIG5hbWVkIGFyZ3VtZW50cyBhbmQgYmxvY2tzIHBhc3NlZCB0byBhIGxheW91dCB0aGF0IHVzZXMgZXZhbFxuICAgIGV2YWxTY29wZSxcbiAgICAvLyBsb2NhbHMgaW4gc2NvcGUgd2hlbiB0aGUgcGFydGlhbCB3YXMgaW52b2tlZFxuICAgIHBhcnRpYWxNYXApIHtcbiAgICAgICAgdGhpcy5zbG90cyA9IHNsb3RzO1xuICAgICAgICB0aGlzLmNhbGxlclNjb3BlID0gY2FsbGVyU2NvcGU7XG4gICAgICAgIHRoaXMuZXZhbFNjb3BlID0gZXZhbFNjb3BlO1xuICAgICAgICB0aGlzLnBhcnRpYWxNYXAgPSBwYXJ0aWFsTWFwO1xuICAgIH1cbiAgICBzdGF0aWMgcm9vdChzZWxmLCBzaXplID0gMCkge1xuICAgICAgICBsZXQgcmVmcyA9IG5ldyBBcnJheShzaXplICsgMSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IHNpemU7IGkrKykge1xuICAgICAgICAgICAgcmVmc1tpXSA9IFVOREVGSU5FRF9SRUZFUkVOQ0U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBTY29wZShyZWZzLCBudWxsLCBudWxsLCBudWxsKS5pbml0KHsgc2VsZiB9KTtcbiAgICB9XG4gICAgc3RhdGljIHNpemVkKHNpemUgPSAwKSB7XG4gICAgICAgIGxldCByZWZzID0gbmV3IEFycmF5KHNpemUgKyAxKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gc2l6ZTsgaSsrKSB7XG4gICAgICAgICAgICByZWZzW2ldID0gVU5ERUZJTkVEX1JFRkVSRU5DRTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFNjb3BlKHJlZnMsIG51bGwsIG51bGwsIG51bGwpO1xuICAgIH1cbiAgICBpbml0KHsgc2VsZiB9KSB7XG4gICAgICAgIHRoaXMuc2xvdHNbMF0gPSBzZWxmO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0U2VsZigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KDApO1xuICAgIH1cbiAgICBnZXRTeW1ib2woc3ltYm9sKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldChzeW1ib2wpO1xuICAgIH1cbiAgICBnZXRCbG9jayhzeW1ib2wpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KHN5bWJvbCk7XG4gICAgfVxuICAgIGdldEV2YWxTY29wZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZXZhbFNjb3BlO1xuICAgIH1cbiAgICBnZXRQYXJ0aWFsTWFwKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJ0aWFsTWFwO1xuICAgIH1cbiAgICBiaW5kKHN5bWJvbCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5zZXQoc3ltYm9sLCB2YWx1ZSk7XG4gICAgfVxuICAgIGJpbmRTZWxmKHNlbGYpIHtcbiAgICAgICAgdGhpcy5zZXQoMCwgc2VsZik7XG4gICAgfVxuICAgIGJpbmRTeW1ib2woc3ltYm9sLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLnNldChzeW1ib2wsIHZhbHVlKTtcbiAgICB9XG4gICAgYmluZEJsb2NrKHN5bWJvbCwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5zZXQoc3ltYm9sLCB2YWx1ZSk7XG4gICAgfVxuICAgIGJpbmRFdmFsU2NvcGUobWFwKSB7XG4gICAgICAgIHRoaXMuZXZhbFNjb3BlID0gbWFwO1xuICAgIH1cbiAgICBiaW5kUGFydGlhbE1hcChtYXApIHtcbiAgICAgICAgdGhpcy5wYXJ0aWFsTWFwID0gbWFwO1xuICAgIH1cbiAgICBiaW5kQ2FsbGVyU2NvcGUoc2NvcGUpIHtcbiAgICAgICAgdGhpcy5jYWxsZXJTY29wZSA9IHNjb3BlO1xuICAgIH1cbiAgICBnZXRDYWxsZXJTY29wZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FsbGVyU2NvcGU7XG4gICAgfVxuICAgIGNoaWxkKCkge1xuICAgICAgICByZXR1cm4gbmV3IFNjb3BlKHRoaXMuc2xvdHMuc2xpY2UoKSwgdGhpcy5jYWxsZXJTY29wZSwgdGhpcy5ldmFsU2NvcGUsIHRoaXMucGFydGlhbE1hcCk7XG4gICAgfVxuICAgIGdldChpbmRleCkge1xuICAgICAgICBpZiAoaW5kZXggPj0gdGhpcy5zbG90cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBCVUc6IGNhbm5vdCBnZXQgJCR7aW5kZXh9IGZyb20gc2NvcGU7IGxlbmd0aD0ke3RoaXMuc2xvdHMubGVuZ3RofWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnNsb3RzW2luZGV4XTtcbiAgICB9XG4gICAgc2V0KGluZGV4LCB2YWx1ZSkge1xuICAgICAgICBpZiAoaW5kZXggPj0gdGhpcy5zbG90cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBCVUc6IGNhbm5vdCBnZXQgJCR7aW5kZXh9IGZyb20gc2NvcGU7IGxlbmd0aD0ke3RoaXMuc2xvdHMubGVuZ3RofWApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2xvdHNbaW5kZXhdID0gdmFsdWU7XG4gICAgfVxufVxuY2xhc3MgVHJhbnNhY3Rpb24ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnNjaGVkdWxlZEluc3RhbGxNYW5hZ2VycyA9IFtdO1xuICAgICAgICB0aGlzLnNjaGVkdWxlZEluc3RhbGxNb2RpZmllcnMgPSBbXTtcbiAgICAgICAgdGhpcy5zY2hlZHVsZWRVcGRhdGVNb2RpZmllck1hbmFnZXJzID0gW107XG4gICAgICAgIHRoaXMuc2NoZWR1bGVkVXBkYXRlTW9kaWZpZXJzID0gW107XG4gICAgICAgIHRoaXMuY3JlYXRlZENvbXBvbmVudHMgPSBbXTtcbiAgICAgICAgdGhpcy5jcmVhdGVkTWFuYWdlcnMgPSBbXTtcbiAgICAgICAgdGhpcy51cGRhdGVkQ29tcG9uZW50cyA9IFtdO1xuICAgICAgICB0aGlzLnVwZGF0ZWRNYW5hZ2VycyA9IFtdO1xuICAgICAgICB0aGlzLmRlc3RydWN0b3JzID0gW107XG4gICAgfVxuICAgIGRpZENyZWF0ZShjb21wb25lbnQsIG1hbmFnZXIpIHtcbiAgICAgICAgdGhpcy5jcmVhdGVkQ29tcG9uZW50cy5wdXNoKGNvbXBvbmVudCk7XG4gICAgICAgIHRoaXMuY3JlYXRlZE1hbmFnZXJzLnB1c2gobWFuYWdlcik7XG4gICAgfVxuICAgIGRpZFVwZGF0ZShjb21wb25lbnQsIG1hbmFnZXIpIHtcbiAgICAgICAgdGhpcy51cGRhdGVkQ29tcG9uZW50cy5wdXNoKGNvbXBvbmVudCk7XG4gICAgICAgIHRoaXMudXBkYXRlZE1hbmFnZXJzLnB1c2gobWFuYWdlcik7XG4gICAgfVxuICAgIHNjaGVkdWxlSW5zdGFsbE1vZGlmaWVyKG1vZGlmaWVyLCBtYW5hZ2VyKSB7XG4gICAgICAgIHRoaXMuc2NoZWR1bGVkSW5zdGFsbE1hbmFnZXJzLnB1c2gobWFuYWdlcik7XG4gICAgICAgIHRoaXMuc2NoZWR1bGVkSW5zdGFsbE1vZGlmaWVycy5wdXNoKG1vZGlmaWVyKTtcbiAgICB9XG4gICAgc2NoZWR1bGVVcGRhdGVNb2RpZmllcihtb2RpZmllciwgbWFuYWdlcikge1xuICAgICAgICB0aGlzLnNjaGVkdWxlZFVwZGF0ZU1vZGlmaWVyTWFuYWdlcnMucHVzaChtYW5hZ2VyKTtcbiAgICAgICAgdGhpcy5zY2hlZHVsZWRVcGRhdGVNb2RpZmllcnMucHVzaChtb2RpZmllcik7XG4gICAgfVxuICAgIGRpZERlc3Ryb3koZCkge1xuICAgICAgICB0aGlzLmRlc3RydWN0b3JzLnB1c2goZCk7XG4gICAgfVxuICAgIGNvbW1pdCgpIHtcbiAgICAgICAgbGV0IHsgY3JlYXRlZENvbXBvbmVudHMsIGNyZWF0ZWRNYW5hZ2VycyB9ID0gdGhpcztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjcmVhdGVkQ29tcG9uZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IGNvbXBvbmVudCA9IGNyZWF0ZWRDb21wb25lbnRzW2ldO1xuICAgICAgICAgICAgbGV0IG1hbmFnZXIgPSBjcmVhdGVkTWFuYWdlcnNbaV07XG4gICAgICAgICAgICBtYW5hZ2VyLmRpZENyZWF0ZShjb21wb25lbnQpO1xuICAgICAgICB9XG4gICAgICAgIGxldCB7IHVwZGF0ZWRDb21wb25lbnRzLCB1cGRhdGVkTWFuYWdlcnMgfSA9IHRoaXM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdXBkYXRlZENvbXBvbmVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBjb21wb25lbnQgPSB1cGRhdGVkQ29tcG9uZW50c1tpXTtcbiAgICAgICAgICAgIGxldCBtYW5hZ2VyID0gdXBkYXRlZE1hbmFnZXJzW2ldO1xuICAgICAgICAgICAgbWFuYWdlci5kaWRVcGRhdGUoY29tcG9uZW50KTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgeyBkZXN0cnVjdG9ycyB9ID0gdGhpcztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkZXN0cnVjdG9ycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgZGVzdHJ1Y3RvcnNbaV0uZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIGxldCB7IHNjaGVkdWxlZEluc3RhbGxNYW5hZ2Vycywgc2NoZWR1bGVkSW5zdGFsbE1vZGlmaWVycyB9ID0gdGhpcztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzY2hlZHVsZWRJbnN0YWxsTWFuYWdlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBtYW5hZ2VyID0gc2NoZWR1bGVkSW5zdGFsbE1hbmFnZXJzW2ldO1xuICAgICAgICAgICAgbGV0IG1vZGlmaWVyID0gc2NoZWR1bGVkSW5zdGFsbE1vZGlmaWVyc1tpXTtcbiAgICAgICAgICAgIG1hbmFnZXIuaW5zdGFsbChtb2RpZmllcik7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHsgc2NoZWR1bGVkVXBkYXRlTW9kaWZpZXJNYW5hZ2Vycywgc2NoZWR1bGVkVXBkYXRlTW9kaWZpZXJzIH0gPSB0aGlzO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNjaGVkdWxlZFVwZGF0ZU1vZGlmaWVyTWFuYWdlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBtYW5hZ2VyID0gc2NoZWR1bGVkVXBkYXRlTW9kaWZpZXJNYW5hZ2Vyc1tpXTtcbiAgICAgICAgICAgIGxldCBtb2RpZmllciA9IHNjaGVkdWxlZFVwZGF0ZU1vZGlmaWVyc1tpXTtcbiAgICAgICAgICAgIG1hbmFnZXIudXBkYXRlKG1vZGlmaWVyKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmV4cG9ydCBjbGFzcyBPcGNvZGUge1xuICAgIGNvbnN0cnVjdG9yKGhlYXApIHtcbiAgICAgICAgdGhpcy5oZWFwID0gaGVhcDtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSAwO1xuICAgIH1cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGVhcC5nZXRieWFkZHIodGhpcy5vZmZzZXQpO1xuICAgIH1cbiAgICBnZXQgb3AxKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oZWFwLmdldGJ5YWRkcih0aGlzLm9mZnNldCArIDEpO1xuICAgIH1cbiAgICBnZXQgb3AyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oZWFwLmdldGJ5YWRkcih0aGlzLm9mZnNldCArIDIpO1xuICAgIH1cbiAgICBnZXQgb3AzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5oZWFwLmdldGJ5YWRkcih0aGlzLm9mZnNldCArIDMpO1xuICAgIH1cbn1cbnZhciBUYWJsZVNsb3RTdGF0ZTtcbihmdW5jdGlvbiAoVGFibGVTbG90U3RhdGUpIHtcbiAgICBUYWJsZVNsb3RTdGF0ZVtUYWJsZVNsb3RTdGF0ZVtcIkFsbG9jYXRlZFwiXSA9IDBdID0gXCJBbGxvY2F0ZWRcIjtcbiAgICBUYWJsZVNsb3RTdGF0ZVtUYWJsZVNsb3RTdGF0ZVtcIkZyZWVkXCJdID0gMV0gPSBcIkZyZWVkXCI7XG4gICAgVGFibGVTbG90U3RhdGVbVGFibGVTbG90U3RhdGVbXCJQdXJnZWRcIl0gPSAyXSA9IFwiUHVyZ2VkXCI7XG4gICAgVGFibGVTbG90U3RhdGVbVGFibGVTbG90U3RhdGVbXCJQb2ludGVyXCJdID0gM10gPSBcIlBvaW50ZXJcIjtcbn0pKFRhYmxlU2xvdFN0YXRlIHx8IChUYWJsZVNsb3RTdGF0ZSA9IHt9KSk7XG5leHBvcnQgY2xhc3MgSGVhcCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuaGVhcCA9IFtdO1xuICAgICAgICB0aGlzLm9mZnNldCA9IDA7XG4gICAgICAgIHRoaXMuaGFuZGxlID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGxheW91dDpcbiAgICAgICAgICpcbiAgICAgICAgICogLSBwb2ludGVyIGludG8gaGVhcFxuICAgICAgICAgKiAtIHNpemVcbiAgICAgICAgICogLSBmcmVlZCAoMCBvciAxKVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy50YWJsZSA9IFtdO1xuICAgIH1cbiAgICBwdXNoKGl0ZW0pIHtcbiAgICAgICAgdGhpcy5oZWFwW3RoaXMub2Zmc2V0KytdID0gaXRlbTtcbiAgICB9XG4gICAgZ2V0YnlhZGRyKGFkZHJlc3MpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGVhcFthZGRyZXNzXTtcbiAgICB9XG4gICAgc2V0YnlhZGRyKGFkZHJlc3MsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuaGVhcFthZGRyZXNzXSA9IHZhbHVlO1xuICAgIH1cbiAgICBtYWxsb2MoKSB7XG4gICAgICAgIHRoaXMudGFibGUucHVzaCh0aGlzLm9mZnNldCwgMCwgMCk7XG4gICAgICAgIGxldCBoYW5kbGUgPSB0aGlzLmhhbmRsZTtcbiAgICAgICAgdGhpcy5oYW5kbGUgKz0gMztcbiAgICAgICAgcmV0dXJuIGhhbmRsZTtcbiAgICB9XG4gICAgZmluaXNoTWFsbG9jKGhhbmRsZSkge1xuICAgICAgICBsZXQgc3RhcnQgPSB0aGlzLnRhYmxlW2hhbmRsZV07XG4gICAgICAgIGxldCBmaW5pc2ggPSB0aGlzLm9mZnNldDtcbiAgICAgICAgdGhpcy50YWJsZVtoYW5kbGUgKyAxXSA9IGZpbmlzaCAtIHN0YXJ0O1xuICAgIH1cbiAgICBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vZmZzZXQ7XG4gICAgfVxuICAgIC8vIEl0IGlzIGlsbGVnYWwgdG8gY2xvc2Ugb3ZlciB0aGlzIGFkZHJlc3MsIGFzIGNvbXBhY3Rpb25cbiAgICAvLyBtYXkgbW92ZSBpdC4gSG93ZXZlciwgaXQgaXMgbGVnYWwgdG8gdXNlIHRoaXMgYWRkcmVzc1xuICAgIC8vIG11bHRpcGxlIHRpbWVzIGJldHdlZW4gY29tcGFjdGlvbnMuXG4gICAgZ2V0YWRkcihoYW5kbGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGFibGVbaGFuZGxlXTtcbiAgICB9XG4gICAgZ2V0aGFuZGxlKGFkZHJlc3MpIHtcbiAgICAgICAgdGhpcy50YWJsZS5wdXNoKGFkZHJlc3MsIDAsIFRhYmxlU2xvdFN0YXRlLlBvaW50ZXIpO1xuICAgICAgICBsZXQgaGFuZGxlID0gdGhpcy5oYW5kbGU7XG4gICAgICAgIHRoaXMuaGFuZGxlICs9IDM7XG4gICAgICAgIHJldHVybiBoYW5kbGU7XG4gICAgfVxuICAgIHNpemVvZihoYW5kbGUpIHtcbiAgICAgICAgaWYgKGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50YWJsZVtoYW5kbGUgKyAxXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIGZyZWUoaGFuZGxlKSB7XG4gICAgICAgIHRoaXMudGFibGVbaGFuZGxlICsgMl0gPSAxO1xuICAgIH1cbiAgICBjb21wYWN0KCkge1xuICAgICAgICBsZXQgY29tcGFjdGVkU2l6ZSA9IDA7XG4gICAgICAgIGxldCB7IHRhYmxlLCB0YWJsZTogeyBsZW5ndGggfSwgaGVhcCB9ID0gdGhpcztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMykge1xuICAgICAgICAgICAgbGV0IG9mZnNldCA9IHRhYmxlW2ldO1xuICAgICAgICAgICAgbGV0IHNpemUgPSB0YWJsZVtpICsgMV07XG4gICAgICAgICAgICBsZXQgc3RhdGUgPSB0YWJsZVtpICsgMl07XG4gICAgICAgICAgICBpZiAoc3RhdGUgPT09IFRhYmxlU2xvdFN0YXRlLlB1cmdlZCkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzdGF0ZSA9PT0gVGFibGVTbG90U3RhdGUuRnJlZWQpIHtcbiAgICAgICAgICAgICAgICAvLyB0cmFuc2l0aW9uIHRvIFwiYWxyZWFkeSBmcmVlZFwiXG4gICAgICAgICAgICAgICAgLy8gYSBnb29kIGltcHJvdmVtZW50IHdvdWxkIGJlIHRvIHJldXNlXG4gICAgICAgICAgICAgICAgLy8gdGhlc2Ugc2xvdHNcbiAgICAgICAgICAgICAgICB0YWJsZVtpICsgMl0gPSAyO1xuICAgICAgICAgICAgICAgIGNvbXBhY3RlZFNpemUgKz0gc2l6ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT09IFRhYmxlU2xvdFN0YXRlLkFsbG9jYXRlZCkge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSBvZmZzZXQ7IGogPD0gaSArIHNpemU7IGorKykge1xuICAgICAgICAgICAgICAgICAgICBoZWFwW2ogLSBjb21wYWN0ZWRTaXplXSA9IGhlYXBbal07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRhYmxlW2ldID0gb2Zmc2V0IC0gY29tcGFjdGVkU2l6ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT09IFRhYmxlU2xvdFN0YXRlLlBvaW50ZXIpIHtcbiAgICAgICAgICAgICAgICB0YWJsZVtpXSA9IG9mZnNldCAtIGNvbXBhY3RlZFNpemU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vZmZzZXQgPSB0aGlzLm9mZnNldCAtIGNvbXBhY3RlZFNpemU7XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIFByb2dyYW0ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmhlYXAgPSBuZXcgSGVhcCgpO1xuICAgICAgICB0aGlzLl9vcGNvZGUgPSBuZXcgT3Bjb2RlKHRoaXMuaGVhcCk7XG4gICAgICAgIHRoaXMuY29uc3RhbnRzID0gbmV3IENvbnN0YW50cygpO1xuICAgIH1cbiAgICBvcGNvZGUob2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuX29wY29kZS5vZmZzZXQgPSBvZmZzZXQ7XG4gICAgICAgIHJldHVybiB0aGlzLl9vcGNvZGU7XG4gICAgfVxufVxuZXhwb3J0IGNsYXNzIEVudmlyb25tZW50IHtcbiAgICBjb25zdHJ1Y3Rvcih7IGFwcGVuZE9wZXJhdGlvbnMsIHVwZGF0ZU9wZXJhdGlvbnMgfSkge1xuICAgICAgICB0aGlzLl9tYWNyb3MgPSBudWxsO1xuICAgICAgICB0aGlzLl90cmFuc2FjdGlvbiA9IG51bGw7XG4gICAgICAgIHRoaXMucHJvZ3JhbSA9IG5ldyBQcm9ncmFtKCk7XG4gICAgICAgIHRoaXMuYXBwZW5kT3BlcmF0aW9ucyA9IGFwcGVuZE9wZXJhdGlvbnM7XG4gICAgICAgIHRoaXMudXBkYXRlT3BlcmF0aW9ucyA9IHVwZGF0ZU9wZXJhdGlvbnM7XG4gICAgfVxuICAgIHRvQ29uZGl0aW9uYWxSZWZlcmVuY2UocmVmZXJlbmNlKSB7XG4gICAgICAgIHJldHVybiBuZXcgQ29uZGl0aW9uYWxSZWZlcmVuY2UocmVmZXJlbmNlKTtcbiAgICB9XG4gICAgZ2V0QXBwZW5kT3BlcmF0aW9ucygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwZW5kT3BlcmF0aW9ucztcbiAgICB9XG4gICAgZ2V0RE9NKCkge1xuICAgICAgICByZXR1cm4gdGhpcy51cGRhdGVPcGVyYXRpb25zO1xuICAgIH1cbiAgICBnZXRJZGVudGl0eShvYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGVuc3VyZUd1aWQob2JqZWN0KSArICcnO1xuICAgIH1cbiAgICBiZWdpbigpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl90cmFuc2FjdGlvbiwgJ2EgZ2xpbW1lciB0cmFuc2FjdGlvbiB3YXMgYmVndW4sIGJ1dCBvbmUgYWxyZWFkeSBleGlzdHMuIFlvdSBtYXkgaGF2ZSBhIG5lc3RlZCB0cmFuc2FjdGlvbicpO1xuICAgICAgICB0aGlzLl90cmFuc2FjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbigpO1xuICAgIH1cbiAgICBnZXQgdHJhbnNhY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBleHBlY3QodGhpcy5fdHJhbnNhY3Rpb24sICdtdXN0IGJlIGluIGEgdHJhbnNhY3Rpb24nKTtcbiAgICB9XG4gICAgZGlkQ3JlYXRlKGNvbXBvbmVudCwgbWFuYWdlcikge1xuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLmRpZENyZWF0ZShjb21wb25lbnQsIG1hbmFnZXIpO1xuICAgIH1cbiAgICBkaWRVcGRhdGUoY29tcG9uZW50LCBtYW5hZ2VyKSB7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb24uZGlkVXBkYXRlKGNvbXBvbmVudCwgbWFuYWdlcik7XG4gICAgfVxuICAgIHNjaGVkdWxlSW5zdGFsbE1vZGlmaWVyKG1vZGlmaWVyLCBtYW5hZ2VyKSB7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb24uc2NoZWR1bGVJbnN0YWxsTW9kaWZpZXIobW9kaWZpZXIsIG1hbmFnZXIpO1xuICAgIH1cbiAgICBzY2hlZHVsZVVwZGF0ZU1vZGlmaWVyKG1vZGlmaWVyLCBtYW5hZ2VyKSB7XG4gICAgICAgIHRoaXMudHJhbnNhY3Rpb24uc2NoZWR1bGVVcGRhdGVNb2RpZmllcihtb2RpZmllciwgbWFuYWdlcik7XG4gICAgfVxuICAgIGRpZERlc3Ryb3koZCkge1xuICAgICAgICB0aGlzLnRyYW5zYWN0aW9uLmRpZERlc3Ryb3koZCk7XG4gICAgfVxuICAgIGNvbW1pdCgpIHtcbiAgICAgICAgbGV0IHRyYW5zYWN0aW9uID0gdGhpcy50cmFuc2FjdGlvbjtcbiAgICAgICAgdGhpcy5fdHJhbnNhY3Rpb24gPSBudWxsO1xuICAgICAgICB0cmFuc2FjdGlvbi5jb21taXQoKTtcbiAgICB9XG4gICAgYXR0cmlidXRlRm9yKGVsZW1lbnQsIGF0dHIsIGlzVHJ1c3RpbmcsIG5hbWVzcGFjZSkge1xuICAgICAgICByZXR1cm4gZGVmYXVsdE1hbmFnZXJzKGVsZW1lbnQsIGF0dHIsIGlzVHJ1c3RpbmcsIG5hbWVzcGFjZSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IG5hbWVzcGFjZSk7XG4gICAgfVxuICAgIG1hY3JvcygpIHtcbiAgICAgICAgbGV0IG1hY3JvcyA9IHRoaXMuX21hY3JvcztcbiAgICAgICAgaWYgKCFtYWNyb3MpIHtcbiAgICAgICAgICAgIHRoaXMuX21hY3JvcyA9IG1hY3JvcyA9IHRoaXMucG9wdWxhdGVCdWlsdGlucygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYWNyb3M7XG4gICAgfVxuICAgIHBvcHVsYXRlQnVpbHRpbnMoKSB7XG4gICAgICAgIHJldHVybiBwb3B1bGF0ZUJ1aWx0aW5zKCk7XG4gICAgfVxufVxuZXhwb3J0IGRlZmF1bHQgRW52aXJvbm1lbnQ7Il19