UNPKG

ember-legacy-class-transform

Version:
419 lines (340 loc) 42.4 kB
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"); } } import { Register } from '../opcodes'; import { Scope } from '../environment'; import { Stack, LinkedList, ListSlice, typePos } from '@glimmer/util'; import { combineSlice } from '@glimmer/reference'; import { LabelOpcode, JumpIfNotModifiedOpcode, DidModifyOpcode } from '../compiled/opcodes/vm'; import { ListBlockOpcode, TryOpcode } from './update'; import RenderResult from './render-result'; import { APPEND_OPCODES } from '../opcodes'; export var EvaluationStack = function () { function EvaluationStack(stack, fp, sp) { _classCallCheck(this, EvaluationStack); this.stack = stack; this.fp = fp; this.sp = sp; if (false) { Object.seal(this); } } EvaluationStack.empty = function empty() { return new this([], 0, -1); }; EvaluationStack.restore = function restore(snapshot) { return new this(snapshot.slice(), 0, snapshot.length - 1); }; EvaluationStack.prototype.isEmpty = function isEmpty() { return this.sp === -1; }; EvaluationStack.prototype.push = function push(value) { this.stack[++this.sp] = value; }; EvaluationStack.prototype.dup = function dup() { var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.sp; this.push(this.stack[position]); }; EvaluationStack.prototype.pop = function pop() { var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; var top = this.stack[this.sp]; this.sp -= n; return top; }; EvaluationStack.prototype.peek = function peek() { return this.stack[this.sp]; }; EvaluationStack.prototype.fromBase = function fromBase(offset) { return this.stack[this.fp - offset]; }; EvaluationStack.prototype.fromTop = function fromTop(offset) { return this.stack[this.sp - offset]; }; EvaluationStack.prototype.capture = function capture(items) { var end = this.sp + 1; var start = end - items; return this.stack.slice(start, end); }; EvaluationStack.prototype.reset = function reset() { this.stack.length = 0; }; EvaluationStack.prototype.toArray = function toArray() { return this.stack.slice(this.fp, this.sp + 1); }; return EvaluationStack; }(); var VM = function () { function VM(env, scope, dynamicScope, elementStack) { _classCallCheck(this, VM); this.env = env; this.elementStack = elementStack; this.dynamicScopeStack = new Stack(); this.scopeStack = new Stack(); this.updatingOpcodeStack = new Stack(); this.cacheGroups = new Stack(); this.listBlockStack = new Stack(); this.stack = EvaluationStack.empty(); /* Registers */ this.pc = -1; this.ra = -1; this.s0 = null; this.s1 = null; this.t0 = null; this.t1 = null; this.env = env; this.heap = env.program.heap; this.constants = env.program.constants; this.elementStack = elementStack; this.scopeStack.push(scope); this.dynamicScopeStack.push(dynamicScope); } // Fetch a value from a register onto the stack VM.prototype.fetch = function fetch(register) { this.stack.push(this[Register[register]]); }; // Load a value from the stack into a register VM.prototype.load = function load(register) { this[Register[register]] = this.stack.pop(); }; // Fetch a value from a register VM.prototype.fetchValue = function fetchValue(register) { return this[Register[register]]; }; // Load a value into a register VM.prototype.loadValue = function loadValue(register, value) { this[Register[register]] = value; }; // Start a new frame and save $ra and $fp on the stack VM.prototype.pushFrame = function pushFrame() { this.stack.push(this.ra); this.stack.push(this.fp); this.fp = this.sp - 1; }; // Restore $ra, $sp and $fp VM.prototype.popFrame = function popFrame() { this.sp = this.fp - 1; this.ra = this.stack.fromBase(0); this.fp = this.stack.fromBase(-1); }; // Jump to an address in `program` VM.prototype.goto = function goto(offset) { this.pc = typePos(this.pc + offset); }; // Save $pc into $ra, then jump to a new address in `program` (jal in MIPS) VM.prototype.call = function call(handle) { var pc = this.heap.getaddr(handle); this.ra = this.pc; this.pc = pc; }; // Put a specific `program` address in $ra VM.prototype.returnTo = function returnTo(offset) { this.ra = typePos(this.pc + offset); }; // Return to the `program` address stored in $ra VM.prototype.return = function _return() { this.pc = this.ra; }; VM.initial = function initial(env, self, dynamicScope, elementStack, program) { var scope = Scope.root(self, program.symbolTable.symbols.length); var vm = new VM(env, scope, dynamicScope, elementStack); vm.pc = vm.heap.getaddr(program.handle); vm.updatingOpcodeStack.push(new LinkedList()); return vm; }; VM.prototype.capture = function capture(args) { return { dynamicScope: this.dynamicScope(), env: this.env, scope: this.scope(), stack: this.stack.capture(args) }; }; VM.prototype.beginCacheGroup = function beginCacheGroup() { this.cacheGroups.push(this.updating().tail()); }; VM.prototype.commitCacheGroup = function commitCacheGroup() { // JumpIfNotModified(END) // (head) // (....) // (tail) // DidModify // END: Noop var END = new LabelOpcode("END"); var opcodes = this.updating(); var marker = this.cacheGroups.pop(); var head = marker ? opcodes.nextNode(marker) : opcodes.head(); var tail = opcodes.tail(); var tag = combineSlice(new ListSlice(head, tail)); var guard = new JumpIfNotModifiedOpcode(tag, END); opcodes.insertBefore(guard, head); opcodes.append(new DidModifyOpcode(guard)); opcodes.append(END); }; VM.prototype.enter = function enter(args) { var updating = new LinkedList(); var state = this.capture(args); var tracker = this.elements().pushUpdatableBlock(); var tryOpcode = new TryOpcode(this.heap.gethandle(this.pc), state, tracker, updating); this.didEnter(tryOpcode); }; VM.prototype.iterate = function iterate(memo, value) { var stack = this.stack; stack.push(value); stack.push(memo); var state = this.capture(2); var tracker = this.elements().pushUpdatableBlock(); // let ip = this.ip; // this.ip = end + 4; // this.frames.push(ip); return new TryOpcode(this.heap.gethandle(this.pc), state, tracker, new LinkedList()); }; VM.prototype.enterItem = function enterItem(key, opcode) { this.listBlock().map[key] = opcode; this.didEnter(opcode); }; VM.prototype.enterList = function enterList(relativeStart) { var updating = new LinkedList(); var state = this.capture(0); var tracker = this.elements().pushBlockList(updating); var artifacts = this.stack.peek().artifacts; var start = this.heap.gethandle(typePos(this.pc + relativeStart)); var opcode = new ListBlockOpcode(start, state, tracker, updating, artifacts); this.listBlockStack.push(opcode); this.didEnter(opcode); }; VM.prototype.didEnter = function didEnter(opcode) { this.updateWith(opcode); this.updatingOpcodeStack.push(opcode.children); }; VM.prototype.exit = function exit() { this.elements().popBlock(); this.updatingOpcodeStack.pop(); var parent = this.updating().tail(); parent.didInitializeChildren(); }; VM.prototype.exitList = function exitList() { this.exit(); this.listBlockStack.pop(); }; VM.prototype.updateWith = function updateWith(opcode) { this.updating().append(opcode); }; VM.prototype.listBlock = function listBlock() { return this.listBlockStack.current; }; VM.prototype.updating = function updating() { return this.updatingOpcodeStack.current; }; VM.prototype.elements = function elements() { return this.elementStack; }; VM.prototype.scope = function scope() { return this.scopeStack.current; }; VM.prototype.dynamicScope = function dynamicScope() { return this.dynamicScopeStack.current; }; VM.prototype.pushChildScope = function pushChildScope() { this.scopeStack.push(this.scope().child()); }; VM.prototype.pushCallerScope = function pushCallerScope() { var childScope = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; var callerScope = this.scope().getCallerScope(); this.scopeStack.push(childScope ? callerScope.child() : callerScope); }; VM.prototype.pushDynamicScope = function pushDynamicScope() { var child = this.dynamicScope().child(); this.dynamicScopeStack.push(child); return child; }; VM.prototype.pushRootScope = function pushRootScope(size, bindCaller) { var scope = Scope.sized(size); if (bindCaller) scope.bindCallerScope(this.scope()); this.scopeStack.push(scope); return scope; }; VM.prototype.popScope = function popScope() { this.scopeStack.pop(); }; VM.prototype.popDynamicScope = function popDynamicScope() { this.dynamicScopeStack.pop(); }; VM.prototype.newDestroyable = function newDestroyable(d) { this.elements().newDestroyable(d); }; /// SCOPE HELPERS VM.prototype.getSelf = function getSelf() { return this.scope().getSelf(); }; VM.prototype.referenceForSymbol = function referenceForSymbol(symbol) { return this.scope().getSymbol(symbol); }; /// EXECUTION VM.prototype.execute = function execute(start, initialize) { this.pc = this.heap.getaddr(start); if (initialize) initialize(this); var result = void 0; while (true) { result = this.next(); if (result.done) break; } return result.value; }; VM.prototype.next = function next() { var env = this.env, updatingOpcodeStack = this.updatingOpcodeStack, elementStack = this.elementStack; var opcode = this.nextStatement(env); var result = void 0; if (opcode !== null) { APPEND_OPCODES.evaluate(this, opcode, opcode.type); result = { done: false, value: null }; } else { // Unload the stack this.stack.reset(); result = { done: true, value: new RenderResult(env, updatingOpcodeStack.pop(), elementStack.popBlock()) }; } return result; }; VM.prototype.nextStatement = function nextStatement(env) { var pc = this.pc; if (pc === -1) { return null; } var program = env.program; this.pc += 4; return program.opcode(pc); }; VM.prototype.evaluateOpcode = function evaluateOpcode(opcode) { APPEND_OPCODES.evaluate(this, opcode, opcode.type); }; VM.prototype.bindDynamicScope = function bindDynamicScope(names) { var scope = this.dynamicScope(); for (var i = names.length - 1; i >= 0; i--) { var name = this.constants.getString(names[i]); scope.set(name, this.stack.pop()); } }; _createClass(VM, [{ key: 'fp', get: function () { return this.stack.fp; }, set: function (fp) { this.stack.fp = fp; } }, { key: 'sp', get: function () { return this.stack.sp; }, set: function (sp) { this.stack.sp = sp; } }]); return VM; }(); export default VM; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi92bS9hcHBlbmQuanMiXSwibmFtZXMiOlsiUmVnaXN0ZXIiLCJTY29wZSIsIlN0YWNrIiwiTGlua2VkTGlzdCIsIkxpc3RTbGljZSIsInR5cGVQb3MiLCJjb21iaW5lU2xpY2UiLCJMYWJlbE9wY29kZSIsIkp1bXBJZk5vdE1vZGlmaWVkT3Bjb2RlIiwiRGlkTW9kaWZ5T3Bjb2RlIiwiTGlzdEJsb2NrT3Bjb2RlIiwiVHJ5T3Bjb2RlIiwiUmVuZGVyUmVzdWx0IiwiQVBQRU5EX09QQ09ERVMiLCJFdmFsdWF0aW9uU3RhY2siLCJzdGFjayIsImZwIiwic3AiLCJPYmplY3QiLCJzZWFsIiwiZW1wdHkiLCJyZXN0b3JlIiwic25hcHNob3QiLCJzbGljZSIsImxlbmd0aCIsImlzRW1wdHkiLCJwdXNoIiwidmFsdWUiLCJkdXAiLCJwb3NpdGlvbiIsInBvcCIsIm4iLCJ0b3AiLCJwZWVrIiwiZnJvbUJhc2UiLCJvZmZzZXQiLCJmcm9tVG9wIiwiY2FwdHVyZSIsIml0ZW1zIiwiZW5kIiwic3RhcnQiLCJyZXNldCIsInRvQXJyYXkiLCJWTSIsImVudiIsInNjb3BlIiwiZHluYW1pY1Njb3BlIiwiZWxlbWVudFN0YWNrIiwiZHluYW1pY1Njb3BlU3RhY2siLCJzY29wZVN0YWNrIiwidXBkYXRpbmdPcGNvZGVTdGFjayIsImNhY2hlR3JvdXBzIiwibGlzdEJsb2NrU3RhY2siLCJwYyIsInJhIiwiczAiLCJzMSIsInQwIiwidDEiLCJoZWFwIiwicHJvZ3JhbSIsImNvbnN0YW50cyIsImZldGNoIiwicmVnaXN0ZXIiLCJsb2FkIiwiZmV0Y2hWYWx1ZSIsImxvYWRWYWx1ZSIsInB1c2hGcmFtZSIsInBvcEZyYW1lIiwiZ290byIsImNhbGwiLCJoYW5kbGUiLCJnZXRhZGRyIiwicmV0dXJuVG8iLCJyZXR1cm4iLCJpbml0aWFsIiwic2VsZiIsInJvb3QiLCJzeW1ib2xUYWJsZSIsInN5bWJvbHMiLCJ2bSIsImFyZ3MiLCJiZWdpbkNhY2hlR3JvdXAiLCJ1cGRhdGluZyIsInRhaWwiLCJjb21taXRDYWNoZUdyb3VwIiwiRU5EIiwib3Bjb2RlcyIsIm1hcmtlciIsImhlYWQiLCJuZXh0Tm9kZSIsInRhZyIsImd1YXJkIiwiaW5zZXJ0QmVmb3JlIiwiYXBwZW5kIiwiZW50ZXIiLCJzdGF0ZSIsInRyYWNrZXIiLCJlbGVtZW50cyIsInB1c2hVcGRhdGFibGVCbG9jayIsInRyeU9wY29kZSIsImdldGhhbmRsZSIsImRpZEVudGVyIiwiaXRlcmF0ZSIsIm1lbW8iLCJlbnRlckl0ZW0iLCJrZXkiLCJvcGNvZGUiLCJsaXN0QmxvY2siLCJtYXAiLCJlbnRlckxpc3QiLCJyZWxhdGl2ZVN0YXJ0IiwicHVzaEJsb2NrTGlzdCIsImFydGlmYWN0cyIsInVwZGF0ZVdpdGgiLCJjaGlsZHJlbiIsImV4aXQiLCJwb3BCbG9jayIsInBhcmVudCIsImRpZEluaXRpYWxpemVDaGlsZHJlbiIsImV4aXRMaXN0IiwiY3VycmVudCIsInB1c2hDaGlsZFNjb3BlIiwiY2hpbGQiLCJwdXNoQ2FsbGVyU2NvcGUiLCJjaGlsZFNjb3BlIiwiY2FsbGVyU2NvcGUiLCJnZXRDYWxsZXJTY29wZSIsInB1c2hEeW5hbWljU2NvcGUiLCJwdXNoUm9vdFNjb3BlIiwic2l6ZSIsImJpbmRDYWxsZXIiLCJzaXplZCIsImJpbmRDYWxsZXJTY29wZSIsInBvcFNjb3BlIiwicG9wRHluYW1pY1Njb3BlIiwibmV3RGVzdHJveWFibGUiLCJkIiwiZ2V0U2VsZiIsInJlZmVyZW5jZUZvclN5bWJvbCIsInN5bWJvbCIsImdldFN5bWJvbCIsImV4ZWN1dGUiLCJpbml0aWFsaXplIiwicmVzdWx0IiwibmV4dCIsImRvbmUiLCJuZXh0U3RhdGVtZW50IiwiZXZhbHVhdGUiLCJ0eXBlIiwiZXZhbHVhdGVPcGNvZGUiLCJiaW5kRHluYW1pY1Njb3BlIiwibmFtZXMiLCJpIiwibmFtZSIsImdldFN0cmluZyIsInNldCJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLFNBQVNBLFFBQVQsUUFBeUIsWUFBekI7QUFDQSxTQUFTQyxLQUFU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QUFQO0FBQ0gsSzs7aUJBQ0RpRyxjLDJCQUFlM0MsTSxFQUFRO0FBQ25COUYsdUJBQWV1SSxRQUFmLENBQXdCLElBQXhCLEVBQThCekMsTUFBOUIsRUFBc0NBLE9BQU8wQyxJQUE3QztBQUNILEs7O2lCQUNERSxnQiw2QkFBaUJDLEssRUFBTztBQUNwQixZQUFJM0csUUFBUSxLQUFLQyxZQUFMLEVBQVo7QUFDQSxhQUFLLElBQUkyRyxJQUFJRCxNQUFNaEksTUFBTixHQUFlLENBQTVCLEVBQStCaUksS0FBSyxDQUFwQyxFQUF1Q0EsR0FBdkMsRUFBNEM7QUFDeEMsZ0JBQUlDLE9BQU8sS0FBSzdGLFNBQUwsQ0FBZThGLFNBQWYsQ0FBeUJILE1BQU1DLENBQU4sQ0FBekIsQ0FBWDtBQUNBNUcsa0JBQU0rRyxHQUFOLENBQVVGLElBQVYsRUFBZ0IsS0FBSzNJLEtBQUwsQ0FBV2UsR0FBWCxFQUFoQjtBQUNIO0FBQ0osSzs7Ozt5QkE5T1E7QUFDTCxtQkFBTyxLQUFLZixLQUFMLENBQVdDLEVBQWxCO0FBQ0gsUzt1QkFDTUEsRSxFQUFJO0FBQ1AsaUJBQUtELEtBQUwsQ0FBV0MsRUFBWCxHQUFnQkEsRUFBaEI7QUFDSDs7O3lCQUNRO0FBQ0wsbUJBQU8sS0FBS0QsS0FBTCxDQUFXRSxFQUFsQjtBQUNILFM7dUJBQ01BLEUsRUFBSTtBQUNQLGlCQUFLRixLQUFMLENBQVdFLEVBQVgsR0FBZ0JBLEVBQWhCO0FBQ0g7Ozs7OztlQW5DZ0IwQixFIiwiZmlsZSI6ImxpYi92bS9hcHBlbmQuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZWdpc3RlciB9IGZyb20gJy4uL29wY29kZXMnO1xuaW1wb3J0IHsgU2NvcGUgfSBmcm9tICcuLi9lbnZpcm9ubWVudCc7XG5pbXBvcnQgeyBTdGFjaywgTGlua2VkTGlzdCwgTGlzdFNsaWNlLCBleHBlY3QsIHR5cGVQb3MgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcbmltcG9ydCB7IGNvbWJpbmVTbGljZSB9IGZyb20gJ0BnbGltbWVyL3JlZmVyZW5jZSc7XG5pbXBvcnQgeyBMYWJlbE9wY29kZSwgSnVtcElmTm90TW9kaWZpZWRPcGNvZGUsIERpZE1vZGlmeU9wY29kZSB9IGZyb20gJy4uL2NvbXBpbGVkL29wY29kZXMvdm0nO1xuaW1wb3J0IHsgTGlzdEJsb2NrT3Bjb2RlLCBUcnlPcGNvZGUgfSBmcm9tICcuL3VwZGF0ZSc7XG5pbXBvcnQgUmVuZGVyUmVzdWx0IGZyb20gJy4vcmVuZGVyLXJlc3VsdCc7XG5cbmltcG9ydCB7IEFQUEVORF9PUENPREVTIH0gZnJvbSAnLi4vb3Bjb2Rlcyc7XG5leHBvcnQgY2xhc3MgRXZhbHVhdGlvblN0YWNrIHtcbiAgICBjb25zdHJ1Y3RvcihzdGFjaywgZnAsIHNwKSB7XG4gICAgICAgIHRoaXMuc3RhY2sgPSBzdGFjaztcbiAgICAgICAgdGhpcy5mcCA9IGZwO1xuICAgICAgICB0aGlzLnNwID0gc3A7XG4gICAgICAgIGlmIChmYWxzZSkge1xuICAgICAgICAgICAgT2JqZWN0LnNlYWwodGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGVtcHR5KCkge1xuICAgICAgICByZXR1cm4gbmV3IHRoaXMoW10sIDAsIC0xKTtcbiAgICB9XG4gICAgc3RhdGljIHJlc3RvcmUoc25hcHNob3QpIHtcbiAgICAgICAgcmV0dXJuIG5ldyB0aGlzKHNuYXBzaG90LnNsaWNlKCksIDAsIHNuYXBzaG90Lmxlbmd0aCAtIDEpO1xuICAgIH1cbiAgICBpc0VtcHR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zcCA9PT0gLTE7XG4gICAgfVxuICAgIHB1c2godmFsdWUpIHtcbiAgICAgICAgdGhpcy5zdGFja1srK3RoaXMuc3BdID0gdmFsdWU7XG4gICAgfVxuICAgIGR1cChwb3NpdGlvbiA9IHRoaXMuc3ApIHtcbiAgICAgICAgdGhpcy5wdXNoKHRoaXMuc3RhY2tbcG9zaXRpb25dKTtcbiAgICB9XG4gICAgcG9wKG4gPSAxKSB7XG4gICAgICAgIGxldCB0b3AgPSB0aGlzLnN0YWNrW3RoaXMuc3BdO1xuICAgICAgICB0aGlzLnNwIC09IG47XG4gICAgICAgIHJldHVybiB0b3A7XG4gICAgfVxuICAgIHBlZWsoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YWNrW3RoaXMuc3BdO1xuICAgIH1cbiAgICBmcm9tQmFzZShvZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhY2tbdGhpcy5mcCAtIG9mZnNldF07XG4gICAgfVxuICAgIGZyb21Ub3Aob2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YWNrW3RoaXMuc3AgLSBvZmZzZXRdO1xuICAgIH1cbiAgICBjYXB0dXJlKGl0ZW1zKSB7XG4gICAgICAgIGxldCBlbmQgPSB0aGlzLnNwICsgMTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gZW5kIC0gaXRlbXM7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YWNrLnNsaWNlKHN0YXJ0LCBlbmQpO1xuICAgIH1cbiAgICByZXNldCgpIHtcbiAgICAgICAgdGhpcy5zdGFjay5sZW5ndGggPSAwO1xuICAgIH1cbiAgICB0b0FycmF5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGFjay5zbGljZSh0aGlzLmZwLCB0aGlzLnNwICsgMSk7XG4gICAgfVxufVxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVk0ge1xuICAgIGNvbnN0cnVjdG9yKGVudiwgc2NvcGUsIGR5bmFtaWNTY29wZSwgZWxlbWVudFN0YWNrKSB7XG4gICAgICAgIHRoaXMuZW52ID0gZW52O1xuICAgICAgICB0aGlzLmVsZW1lbnRTdGFjayA9IGVsZW1lbnRTdGFjaztcbiAgICAgICAgdGhpcy5keW5hbWljU2NvcGVTdGFjayA9IG5ldyBTdGFjaygpO1xuICAgICAgICB0aGlzLnNjb3BlU3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgICAgICAgdGhpcy51cGRhdGluZ09wY29kZVN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgICAgIHRoaXMuY2FjaGVHcm91cHMgPSBuZXcgU3RhY2soKTtcbiAgICAgICAgdGhpcy5saXN0QmxvY2tTdGFjayA9IG5ldyBTdGFjaygpO1xuICAgICAgICB0aGlzLnN0YWNrID0gRXZhbHVhdGlvblN0YWNrLmVtcHR5KCk7XG4gICAgICAgIC8qIFJlZ2lzdGVycyAqL1xuICAgICAgICB0aGlzLnBjID0gLTE7XG4gICAgICAgIHRoaXMucmEgPSAtMTtcbiAgICAgICAgdGhpcy5zMCA9IG51bGw7XG4gICAgICAgIHRoaXMuczEgPSBudWxsO1xuICAgICAgICB0aGlzLnQwID0gbnVsbDtcbiAgICAgICAgdGhpcy50MSA9IG51bGw7XG4gICAgICAgIHRoaXMuZW52ID0gZW52O1xuICAgICAgICB0aGlzLmhlYXAgPSBlbnYucHJvZ3JhbS5oZWFwO1xuICAgICAgICB0aGlzLmNvbnN0YW50cyA9IGVudi5wcm9ncmFtLmNvbnN0YW50cztcbiAgICAgICAgdGhpcy5lbGVtZW50U3RhY2sgPSBlbGVtZW50U3RhY2s7XG4gICAgICAgIHRoaXMuc2NvcGVTdGFjay5wdXNoKHNjb3BlKTtcbiAgICAgICAgdGhpcy5keW5hbWljU2NvcGVTdGFjay5wdXNoKGR5bmFtaWNTY29wZSk7XG4gICAgfVxuICAgIGdldCBmcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhY2suZnA7XG4gICAgfVxuICAgIHNldCBmcChmcCkge1xuICAgICAgICB0aGlzLnN0YWNrLmZwID0gZnA7XG4gICAgfVxuICAgIGdldCBzcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhY2suc3A7XG4gICAgfVxuICAgIHNldCBzcChzcCkge1xuICAgICAgICB0aGlzLnN0YWNrLnNwID0gc3A7XG4gICAgfVxuICAgIC8vIEZldGNoIGEgdmFsdWUgZnJvbSBhIHJlZ2lzdGVyIG9udG8gdGhlIHN0YWNrXG4gICAgZmV0Y2gocmVnaXN0ZXIpIHtcbiAgICAgICAgdGhpcy5zdGFjay5wdXNoKHRoaXNbUmVnaXN0ZXJbcmVnaXN0ZXJdXSk7XG4gICAgfVxuICAgIC8vIExvYWQgYSB2YWx1ZSBmcm9tIHRoZSBzdGFjayBpbnRvIGEgcmVnaXN0ZXJcbiAgICBsb2FkKHJlZ2lzdGVyKSB7XG4gICAgICAgIHRoaXNbUmVnaXN0ZXJbcmVnaXN0ZXJdXSA9IHRoaXMuc3RhY2sucG9wKCk7XG4gICAgfVxuICAgIC8vIEZldGNoIGEgdmFsdWUgZnJvbSBhIHJlZ2lzdGVyXG4gICAgZmV0Y2hWYWx1ZShyZWdpc3Rlcikge1xuICAgICAgICByZXR1cm4gdGhpc1tSZWdpc3RlcltyZWdpc3Rlcl1dO1xuICAgIH1cbiAgICAvLyBMb2FkIGEgdmFsdWUgaW50byBhIHJlZ2lzdGVyXG4gICAgbG9hZFZhbHVlKHJlZ2lzdGVyLCB2YWx1ZSkge1xuICAgICAgICB0aGlzW1JlZ2lzdGVyW3JlZ2lzdGVyXV0gPSB2YWx1ZTtcbiAgICB9XG4gICAgLy8gU3RhcnQgYSBuZXcgZnJhbWUgYW5kIHNhdmUgJHJhIGFuZCAkZnAgb24gdGhlIHN0YWNrXG4gICAgcHVzaEZyYW1lKCkge1xuICAgICAgICB0aGlzLnN0YWNrLnB1c2godGhpcy5yYSk7XG4gICAgICAgIHRoaXMuc3RhY2sucHVzaCh0aGlzLmZwKTtcbiAgICAgICAgdGhpcy5mcCA9IHRoaXMuc3AgLSAxO1xuICAgIH1cbiAgICAvLyBSZXN0b3JlICRyYSwgJHNwIGFuZCAkZnBcbiAgICBwb3BGcmFtZSgpIHtcbiAgICAgICAgdGhpcy5zcCA9IHRoaXMuZnAgLSAxO1xuICAgICAgICB0aGlzLnJhID0gdGhpcy5zdGFjay5mcm9tQmFzZSgwKTtcbiAgICAgICAgdGhpcy5mcCA9IHRoaXMuc3RhY2suZnJvbUJhc2UoLTEpO1xuICAgIH1cbiAgICAvLyBKdW1wIHRvIGFuIGFkZHJlc3MgaW4gYHByb2dyYW1gXG4gICAgZ290byhvZmZzZXQpIHtcbiAgICAgICAgdGhpcy5wYyA9IHR5cGVQb3ModGhpcy5wYyArIG9mZnNldCk7XG4gICAgfVxuICAgIC8vIFNhdmUgJHBjIGludG8gJHJhLCB0aGVuIGp1bXAgdG8gYSBuZXcgYWRkcmVzcyBpbiBgcHJvZ3JhbWAgKGphbCBpbiBNSVBTKVxuICAgIGNhbGwoaGFuZGxlKSB7XG4gICAgICAgIGxldCBwYyA9IHRoaXMuaGVhcC5nZXRhZGRyKGhhbmRsZSk7XG4gICAgICAgIHRoaXMucmEgPSB0aGlzLnBjO1xuICAgICAgICB0aGlzLnBjID0gcGM7XG4gICAgfVxuICAgIC8vIFB1dCBhIHNwZWNpZmljIGBwcm9ncmFtYCBhZGRyZXNzIGluICRyYVxuICAgIHJldHVyblRvKG9mZnNldCkge1xuICAgICAgICB0aGlzLnJhID0gdHlwZVBvcyh0aGlzLnBjICsgb2Zmc2V0KTtcbiAgICB9XG4gICAgLy8gUmV0dXJuIHRvIHRoZSBgcHJvZ3JhbWAgYWRkcmVzcyBzdG9yZWQgaW4gJHJhXG4gICAgcmV0dXJuKCkge1xuICAgICAgICB0aGlzLnBjID0gdGhpcy5yYTtcbiAgICB9XG4gICAgc3RhdGljIGluaXRpYWwoZW52LCBzZWxmLCBkeW5hbWljU2NvcGUsIGVsZW1lbnRTdGFjaywgcHJvZ3JhbSkge1xuICAgICAgICBsZXQgc2NvcGUgPSBTY29wZS5yb290KHNlbGYsIHByb2dyYW0uc3ltYm9sVGFibGUuc3ltYm9scy5sZW5ndGgpO1xuICAgICAgICBsZXQgdm0gPSBuZXcgVk0oZW52LCBzY29wZSwgZHluYW1pY1Njb3BlLCBlbGVtZW50U3RhY2spO1xuICAgICAgICB2bS5wYyA9IHZtLmhlYXAuZ2V0YWRkcihwcm9ncmFtLmhhbmRsZSk7XG4gICAgICAgIHZtLnVwZGF0aW5nT3Bjb2RlU3RhY2sucHVzaChuZXcgTGlua2VkTGlzdCgpKTtcbiAgICAgICAgcmV0dXJuIHZtO1xuICAgIH1cbiAgICBjYXB0dXJlKGFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGR5bmFtaWNTY29wZTogdGhpcy5keW5hbWljU2NvcGUoKSxcbiAgICAgICAgICAgIGVudjogdGhpcy5lbnYsXG4gICAgICAgICAgICBzY29wZTogdGhpcy5zY29wZSgpLFxuICAgICAgICAgICAgc3RhY2s6IHRoaXMuc3RhY2suY2FwdHVyZShhcmdzKVxuICAgICAgICB9O1xuICAgIH1cbiAgICBiZWdpbkNhY2hlR3JvdXAoKSB7XG4gICAgICAgIHRoaXMuY2FjaGVHcm91cHMucHVzaCh0aGlzLnVwZGF0aW5nKCkudGFpbCgpKTtcbiAgICB9XG4gICAgY29tbWl0Q2FjaGVHcm91cCgpIHtcbiAgICAgICAgLy8gICAgICAgIEp1bXBJZk5vdE1vZGlmaWVkKEVORClcbiAgICAgICAgLy8gICAgICAgIChoZWFkKVxuICAgICAgICAvLyAgICAgICAgKC4uLi4pXG4gICAgICAgIC8vICAgICAgICAodGFpbClcbiAgICAgICAgLy8gICAgICAgIERpZE1vZGlmeVxuICAgICAgICAvLyBFTkQ6ICAgTm9vcFxuICAgICAgICBsZXQgRU5EID0gbmV3IExhYmVsT3Bjb2RlKFwiRU5EXCIpO1xuICAgICAgICBsZXQgb3Bjb2RlcyA9IHRoaXMudXBkYXRpbmcoKTtcbiAgICAgICAgbGV0IG1hcmtlciA9IHRoaXMuY2FjaGVHcm91cHMucG9wKCk7XG4gICAgICAgIGxldCBoZWFkID0gbWFya2VyID8gb3Bjb2Rlcy5uZXh0Tm9kZShtYXJrZXIpIDogb3Bjb2Rlcy5oZWFkKCk7XG4gICAgICAgIGxldCB0YWlsID0gb3Bjb2Rlcy50YWlsKCk7XG4gICAgICAgIGxldCB0YWcgPSBjb21iaW5lU2xpY2UobmV3IExpc3RTbGljZShoZWFkLCB0YWlsKSk7XG4gICAgICAgIGxldCBndWFyZCA9IG5ldyBKdW1wSWZOb3RNb2RpZmllZE9wY29kZSh0YWcsIEVORCk7XG4gICAgICAgIG9wY29kZXMuaW5zZXJ0QmVmb3JlKGd1YXJkLCBoZWFkKTtcbiAgICAgICAgb3Bjb2Rlcy5hcHBlbmQobmV3IERpZE1vZGlmeU9wY29kZShndWFyZCkpO1xuICAgICAgICBvcGNvZGVzLmFwcGVuZChFTkQpO1xuICAgIH1cbiAgICBlbnRlcihhcmdzKSB7XG4gICAgICAgIGxldCB1cGRhdGluZyA9IG5ldyBMaW5rZWRMaXN0KCk7XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuY2FwdHVyZShhcmdzKTtcbiAgICAgICAgbGV0IHRyYWNrZXIgPSB0aGlzLmVsZW1lbnRzKCkucHVzaFVwZGF0YWJsZUJsb2NrKCk7XG4gICAgICAgIGxldCB0cnlPcGNvZGUgPSBuZXcgVHJ5T3Bjb2RlKHRoaXMuaGVhcC5nZXRoYW5kbGUodGhpcy5wYyksIHN0YXRlLCB0cmFja2VyLCB1cGRhdGluZyk7XG4gICAgICAgIHRoaXMuZGlkRW50ZXIodHJ5T3Bjb2RlKTtcbiAgICB9XG4gICAgaXRlcmF0ZShtZW1vLCB2YWx1ZSkge1xuICAgICAgICBsZXQgc3RhY2sgPSB0aGlzLnN0YWNrO1xuICAgICAgICBzdGFjay5wdXNoKHZhbHVlKTtcbiAgICAgICAgc3RhY2sucHVzaChtZW1vKTtcbiAgICAgICAgbGV0IHN0YXRlID0gdGhpcy5jYXB0dXJlKDIpO1xuICAgICAgICBsZXQgdHJhY2tlciA9IHRoaXMuZWxlbWVudHMoKS5wdXNoVXBkYXRhYmxlQmxvY2soKTtcbiAgICAgICAgLy8gbGV0IGlwID0gdGhpcy5pcDtcbiAgICAgICAgLy8gdGhpcy5pcCA9IGVuZCArIDQ7XG4gICAgICAgIC8vIHRoaXMuZnJhbWVzLnB1c2goaXApO1xuICAgICAgICByZXR1cm4gbmV3IFRyeU9wY29kZSh0aGlzLmhlYXAuZ2V0aGFuZGxlKHRoaXMucGMpLCBzdGF0ZSwgdHJhY2tlciwgbmV3IExpbmtlZExpc3QoKSk7XG4gICAgfVxuICAgIGVudGVySXRlbShrZXksIG9wY29kZSkge1xuICAgICAgICB0aGlzLmxpc3RCbG9jaygpLm1hcFtrZXldID0gb3Bjb2RlO1xuICAgICAgICB0aGlzLmRpZEVudGVyKG9wY29kZSk7XG4gICAgfVxuICAgIGVudGVyTGlzdChyZWxhdGl2ZVN0YXJ0KSB7XG4gICAgICAgIGxldCB1cGRhdGluZyA9IG5ldyBMaW5rZWRMaXN0KCk7XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuY2FwdHVyZSgwKTtcbiAgICAgICAgbGV0IHRyYWNrZXIgPSB0aGlzLmVsZW1lbnRzKCkucHVzaEJsb2NrTGlzdCh1cGRhdGluZyk7XG4gICAgICAgIGxldCBhcnRpZmFjdHMgPSB0aGlzLnN0YWNrLnBlZWsoKS5hcnRpZmFjdHM7XG4gICAgICAgIGxldCBzdGFydCA9IHRoaXMuaGVhcC5nZXRoYW5kbGUodHlwZVBvcyh0aGlzLnBjICsgcmVsYXRpdmVTdGFydCkpO1xuICAgICAgICBsZXQgb3Bjb2RlID0gbmV3IExpc3RCbG9ja09wY29kZShzdGFydCwgc3RhdGUsIHRyYWNrZXIsIHVwZGF0aW5nLCBhcnRpZmFjdHMpO1xuICAgICAgICB0aGlzLmxpc3RCbG9ja1N0YWNrLnB1c2gob3Bjb2RlKTtcbiAgICAgICAgdGhpcy5kaWRFbnRlcihvcGNvZGUpO1xuICAgIH1cbiAgICBkaWRFbnRlcihvcGNvZGUpIHtcbiAgICAgICAgdGhpcy51cGRhdGVXaXRoKG9wY29kZSk7XG4gICAgICAgIHRoaXMudXBkYXRpbmdPcGNvZGVTdGFjay5wdXNoKG9wY29kZS5jaGlsZHJlbik7XG4gICAgfVxuICAgIGV4aXQoKSB7XG4gICAgICAgIHRoaXMuZWxlbWVudHMoKS5wb3BCbG9jaygpO1xuICAgICAgICB0aGlzLnVwZGF0aW5nT3Bjb2RlU3RhY2sucG9wKCk7XG4gICAgICAgIGxldCBwYXJlbnQgPSB0aGlzLnVwZGF0aW5nKCkudGFpbCgpO1xuICAgICAgICBwYXJlbnQuZGlkSW5pdGlhbGl6ZUNoaWxkcmVuKCk7XG4gICAgfVxuICAgIGV4aXRMaXN0KCkge1xuICAgICAgICB0aGlzLmV4aXQoKTtcbiAgICAgICAgdGhpcy5saXN0QmxvY2tTdGFjay5wb3AoKTtcbiAgICB9XG4gICAgdXBkYXRlV2l0aChvcGNvZGUpIHtcbiAgICAgICAgdGhpcy51cGRhdGluZygpLmFwcGVuZChvcGNvZGUpO1xuICAgIH1cbiAgICBsaXN0QmxvY2soKSB7XG4gICAgICAgIHJldHVybiBleHBlY3QodGhpcy5saXN0QmxvY2tTdGFjay5jdXJyZW50LCAnZXhwZWN0ZWQgYSBsaXN0IGJsb2NrJyk7XG4gICAgfVxuICAgIHVwZGF0aW5nKCkge1xuICAgICAgICByZXR1cm4gZXhwZWN0KHRoaXMudXBkYXRpbmdPcGNvZGVTdGFjay5jdXJyZW50LCAnZXhwZWN0ZWQgdXBkYXRpbmcgb3Bjb2RlIG9uIHRoZSB1cGRhdGluZyBvcGNvZGUgc3RhY2snKTtcbiAgICB9XG4gICAgZWxlbWVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRTdGFjaztcbiAgICB9XG4gICAgc2NvcGUoKSB7XG4gICAgICAgIHJldHVybiBleHBlY3QodGhpcy5zY29wZVN0YWNrLmN1cnJlbnQsICdleHBlY3RlZCBzY29wZSBvbiB0aGUgc2NvcGUgc3RhY2snKTtcbiAgICB9XG4gICAgZHluYW1pY1Njb3BlKCkge1xuICAgICAgICByZXR1cm4gZXhwZWN0KHRoaXMuZHluYW1pY1Njb3BlU3RhY2suY3VycmVudCwgJ2V4cGVjdGVkIGR5bmFtaWMgc2NvcGUgb24gdGhlIGR5bmFtaWMgc2NvcGUgc3RhY2snKTtcbiAgICB9XG4gICAgcHVzaENoaWxkU2NvcGUoKSB7XG4gICAgICAgIHRoaXMuc2NvcGVTdGFjay5wdXNoKHRoaXMuc2NvcGUoKS5jaGlsZCgpKTtcbiAgICB9XG4gICAgcHVzaENhbGxlclNjb3BlKGNoaWxkU2NvcGUgPSBmYWxzZSkge1xuICAgICAgICBsZXQgY2FsbGVyU2NvcGUgPSBleHBlY3QodGhpcy5zY29wZSgpLmdldENhbGxlclNjb3BlKCksICdwdXNoQ2FsbGVyU2NvcGUgaXMgY2FsbGVkIHdoZW4gYSBjYWxsZXIgc2NvcGUgaXMgcHJlc2VudCcpO1xuICAgICAgICB0aGlzLnNjb3BlU3RhY2sucHVzaChjaGlsZFNjb3BlID8gY2FsbGVyU2NvcGUuY2hpbGQoKSA6IGNhbGxlclNjb3BlKTtcbiAgICB9XG4gICAgcHVzaER5bmFtaWNTY29wZSgpIHtcbiAgICAgICAgbGV0IGNoaWxkID0gdGhpcy5keW5hbWljU2NvcGUoKS5jaGlsZCgpO1xuICAgICAgICB0aGlzLmR5bmFtaWNTY29wZVN0YWNrLnB1c2goY2hpbGQpO1xuICAgICAgICByZXR1cm4gY2hpbGQ7XG4gICAgfVxuICAgIHB1c2hSb290U2NvcGUoc2l6ZSwgYmluZENhbGxlcikge1xuICAgICAgICBsZXQgc2NvcGUgPSBTY29wZS5zaXplZChzaXplKTtcbiAgICAgICAgaWYgKGJpbmRDYWxsZXIpIHNjb3BlLmJpbmRDYWxsZXJTY29wZSh0aGlzLnNjb3BlKCkpO1xuICAgICAgICB0aGlzLnNjb3BlU3RhY2sucHVzaChzY29wZSk7XG4gICAgICAgIHJldHVybiBzY29wZTtcbiAgICB9XG4gICAgcG9wU2NvcGUoKSB7XG4gICAgICAgIHRoaXMuc2NvcGVTdGFjay5wb3AoKTtcbiAgICB9XG4gICAgcG9wRHluYW1pY1Njb3BlKCkge1xuICAgICAgICB0aGlzLmR5bmFtaWNTY29wZVN0YWNrLnBvcCgpO1xuICAgIH1cbiAgICBuZXdEZXN0cm95YWJsZShkKSB7XG4gICAgICAgIHRoaXMuZWxlbWVudHMoKS5uZXdEZXN0cm95YWJsZShkKTtcbiAgICB9XG4gICAgLy8vIFNDT1BFIEhFTFBFUlNcbiAgICBnZXRTZWxmKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zY29wZSgpLmdldFNlbGYoKTtcbiAgICB9XG4gICAgcmVmZXJlbmNlRm9yU3ltYm9sKHN5bWJvbCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zY29wZSgpLmdldFN5bWJvbChzeW1ib2wpO1xuICAgIH1cbiAgICAvLy8gRVhFQ1VUSU9OXG4gICAgZXhlY3V0ZShzdGFydCwgaW5pdGlhbGl6ZSkge1xuICAgICAgICB0aGlzLnBjID0gdGhpcy5oZWFwLmdldGFkZHIoc3RhcnQpO1xuICAgICAgICBpZiAoaW5pdGlhbGl6ZSkgaW5pdGlhbGl6ZSh0aGlzKTtcbiAgICAgICAgbGV0IHJlc3VsdDtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IHRoaXMubmV4dCgpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdC5kb25lKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0LnZhbHVlO1xuICAgIH1cbiAgICBuZXh0KCkge1xuICAgICAgICBsZXQgeyBlbnYsIHVwZGF0aW5nT3Bjb2RlU3RhY2ssIGVsZW1lbnRTdGFjayB9ID0gdGhpcztcbiAgICAgICAgbGV0IG9wY29kZSA9IHRoaXMubmV4dFN0YXRlbWVudChlbnYpO1xuICAgICAgICBsZXQgcmVzdWx0O1xuICAgICAgICBpZiAob3Bjb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBBUFBFTkRfT1BDT0RFUy5ldmFsdWF0ZSh0aGlzLCBvcGNvZGUsIG9wY29kZS50eXBlKTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHsgZG9uZTogZmFsc2UsIHZhbHVlOiBudWxsIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBVbmxvYWQgdGhlIHN0YWNrXG4gICAgICAgICAgICB0aGlzLnN0YWNrLnJlc2V0KCk7XG4gICAgICAgICAgICByZXN1bHQgPSB7XG4gICAgICAgICAgICAgICAgZG9uZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogbmV3IFJlbmRlclJlc3VsdChlbnYsIGV4cGVjdCh1cGRhdGluZ09wY29kZVN0YWNrLnBvcCgpLCAndGhlcmUgc2hvdWxkIGJlIGEgZmluYWwgdXBkYXRpbmcgb3Bjb2RlIHN0YWNrJyksIGVsZW1lbnRTdGFjay5wb3BCbG9jaygpKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBuZXh0U3RhdGVtZW50KGVudikge1xuICAgICAgICBsZXQgeyBwYyB9ID0gdGhpcztcbiAgICAgICAgaWYgKHBjID09PSAtMSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHByb2dyYW0gPSBlbnYucHJvZ3JhbTtcbiAgICAgICAgdGhpcy5wYyArPSA0O1xuICAgICAgICByZXR1cm4gcHJvZ3JhbS5vcGNvZGUocGMpO1xuICAgIH1cbiAgICBldmFsdWF0ZU9wY29kZShvcGNvZGUpIHtcbiAgICAgICAgQVBQRU5EX09QQ09ERVMuZXZhbHVhdGUodGhpcywgb3Bjb2RlLCBvcGNvZGUudHlwZSk7XG4gICAgfVxuICAgIGJpbmREeW5hbWljU2NvcGUobmFtZXMpIHtcbiAgICAgICAgbGV0IHNjb3BlID0gdGhpcy5keW5hbWljU2NvcGUoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IG5hbWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBsZXQgbmFtZSA9IHRoaXMuY29uc3RhbnRzLmdldFN0cmluZyhuYW1lc1tpXSk7XG4gICAgICAgICAgICBzY29wZS5zZXQobmFtZSwgdGhpcy5zdGFjay5wb3AoKSk7XG4gICAgICAgIH1cbiAgICB9XG59Il19