UNPKG

@glimmer/syntax

Version:
168 lines (133 loc) 15.3 kB
import { dict } from '@glimmer/util'; import { isUpperCase } from './utils'; export class SymbolTable { static top(locals, customizeComponentName) { return new ProgramSymbolTable(locals, customizeComponentName); } child(locals) { let symbols = locals.map(name => this.allocate(name)); return new BlockSymbolTable(this, locals, symbols); } } export class ProgramSymbolTable extends SymbolTable { constructor(templateLocals, customizeComponentName) { super(); this.templateLocals = templateLocals; this.customizeComponentName = customizeComponentName; this.symbols = []; this.upvars = []; this.size = 1; this.named = dict(); this.blocks = dict(); this.usedTemplateLocals = []; this._hasEval = false; } getUsedTemplateLocals() { return this.usedTemplateLocals; } setHasEval() { this._hasEval = true; } get hasEval() { return this._hasEval; } has(name) { return this.templateLocals.indexOf(name) !== -1; } get(name) { let index = this.usedTemplateLocals.indexOf(name); if (index !== -1) { return [index, true]; } index = this.usedTemplateLocals.length; this.usedTemplateLocals.push(name); return [index, true]; } getLocalsMap() { return dict(); } getEvalInfo() { let locals = this.getLocalsMap(); return Object.keys(locals).map(symbol => locals[symbol]); } allocateFree(name, resolution) { // If the name in question is an uppercase (i.e. angle-bracket) component invocation, run // the optional `customizeComponentName` function provided to the precompiler. if (resolution.resolution() === 39 /* GetFreeAsComponentHead */ && resolution.isAngleBracket && isUpperCase(name)) { name = this.customizeComponentName(name); } let index = this.upvars.indexOf(name); if (index !== -1) { return index; } index = this.upvars.length; this.upvars.push(name); return index; } allocateNamed(name) { let named = this.named[name]; if (!named) { named = this.named[name] = this.allocate(name); } return named; } allocateBlock(name) { if (name === 'inverse') { name = 'else'; } let block = this.blocks[name]; if (!block) { block = this.blocks[name] = this.allocate(`&${name}`); } return block; } allocate(identifier) { this.symbols.push(identifier); return this.size++; } } export class BlockSymbolTable extends SymbolTable { constructor(parent, symbols, slots) { super(); this.parent = parent; this.symbols = symbols; this.slots = slots; } get locals() { return this.symbols; } has(name) { return this.symbols.indexOf(name) !== -1 || this.parent.has(name); } get(name) { let slot = this.symbols.indexOf(name); return slot === -1 ? this.parent.get(name) : [this.slots[slot], false]; } getLocalsMap() { let dict = this.parent.getLocalsMap(); this.symbols.forEach(symbol => dict[symbol] = this.get(symbol)[0]); return dict; } getEvalInfo() { let locals = this.getLocalsMap(); return Object.keys(locals).map(symbol => locals[symbol]); } setHasEval() { this.parent.setHasEval(); } allocateFree(name, resolution) { return this.parent.allocateFree(name, resolution); } allocateNamed(name) { return this.parent.allocateNamed(name); } allocateBlock(name) { return this.parent.allocateBlock(name); } allocate(identifier) { return this.parent.allocate(identifier); } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3N5bnRheC9saWIvc3ltYm9sLXRhYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLFNBQVMsSUFBVCxRQUFxQixlQUFyQjtBQUdBLFNBQVMsV0FBVCxRQUE0QixTQUE1QjtBQUVBLE9BQU0sTUFBZ0IsV0FBaEIsQ0FBMkI7QUFDL0IsU0FBTyxHQUFQLENBQ0UsTUFERixFQUVFLHNCQUZGLEVBRW1EO0FBRWpELFdBQU8sSUFBSSxrQkFBSixDQUF1QixNQUF2QixFQUErQixzQkFBL0IsQ0FBUDtBQUNEOztBQWVELEVBQUEsS0FBSyxDQUFDLE1BQUQsRUFBaUI7QUFDcEIsUUFBSSxPQUFPLEdBQUcsTUFBTSxDQUFDLEdBQVAsQ0FBWSxJQUFELElBQVUsS0FBSyxRQUFMLENBQWMsSUFBZCxDQUFyQixDQUFkO0FBQ0EsV0FBTyxJQUFJLGdCQUFKLENBQXFCLElBQXJCLEVBQTJCLE1BQTNCLEVBQW1DLE9BQW5DLENBQVA7QUFDRDs7QUF4QjhCO0FBMkJqQyxPQUFNLE1BQU8sa0JBQVAsU0FBa0MsV0FBbEMsQ0FBNkM7QUFDakQsRUFBQSxXQUFBLENBQ1UsY0FEVixFQUVVLHNCQUZWLEVBRTJEO0FBRXpEO0FBSFEsU0FBQSxjQUFBLEdBQUEsY0FBQTtBQUNBLFNBQUEsc0JBQUEsR0FBQSxzQkFBQTtBQUtILFNBQUEsT0FBQSxHQUFvQixFQUFwQjtBQUNBLFNBQUEsTUFBQSxHQUFtQixFQUFuQjtBQUVDLFNBQUEsSUFBQSxHQUFPLENBQVA7QUFDQSxTQUFBLEtBQUEsR0FBUSxJQUFJLEVBQVo7QUFDQSxTQUFBLE1BQUEsR0FBUyxJQUFJLEVBQWI7QUFDQSxTQUFBLGtCQUFBLEdBQStCLEVBQS9CO0FBRVIsU0FBQSxRQUFBLEdBQVcsS0FBWDtBQVZDOztBQVlELEVBQUEscUJBQXFCLEdBQUE7QUFDbkIsV0FBTyxLQUFLLGtCQUFaO0FBQ0Q7O0FBRUQsRUFBQSxVQUFVLEdBQUE7QUFDUixTQUFLLFFBQUwsR0FBZ0IsSUFBaEI7QUFDRDs7QUFFRCxNQUFJLE9BQUosR0FBVztBQUNULFdBQU8sS0FBSyxRQUFaO0FBQ0Q7O0FBRUQsRUFBQSxHQUFHLENBQUMsSUFBRCxFQUFhO0FBQ2QsV0FBTyxLQUFLLGNBQUwsQ0FBb0IsT0FBcEIsQ0FBNEIsSUFBNUIsTUFBc0MsQ0FBQyxDQUE5QztBQUNEOztBQUVELEVBQUEsR0FBRyxDQUFDLElBQUQsRUFBYTtBQUNkLFFBQUksS0FBSyxHQUFHLEtBQUssa0JBQUwsQ0FBd0IsT0FBeEIsQ0FBZ0MsSUFBaEMsQ0FBWjs7QUFFQSxRQUFJLEtBQUssS0FBSyxDQUFDLENBQWYsRUFBa0I7QUFDaEIsYUFBTyxDQUFDLEtBQUQsRUFBUSxJQUFSLENBQVA7QUFDRDs7QUFFRCxJQUFBLEtBQUssR0FBRyxLQUFLLGtCQUFMLENBQXdCLE1BQWhDO0FBQ0EsU0FBSyxrQkFBTCxDQUF3QixJQUF4QixDQUE2QixJQUE3QjtBQUNBLFdBQU8sQ0FBQyxLQUFELEVBQVEsSUFBUixDQUFQO0FBQ0Q7O0FBRUQsRUFBQSxZQUFZLEdBQUE7QUFDVixXQUFPLElBQUksRUFBWDtBQUNEOztBQUVELEVBQUEsV0FBVyxHQUFBO0FBQ1QsUUFBSSxNQUFNLEdBQUcsS0FBSyxZQUFMLEVBQWI7QUFDQSxXQUFPLE1BQU0sQ0FBQyxJQUFQLENBQVksTUFBWixFQUFvQixHQUFwQixDQUF5QixNQUFELElBQVksTUFBTSxDQUFDLE1BQUQsQ0FBMUMsQ0FBUDtBQUNEOztBQUVELEVBQUEsWUFBWSxDQUFDLElBQUQsRUFBZSxVQUFmLEVBQWtEO0FBQzVEO0FBQ0E7QUFDQSxRQUNFLFVBQVUsQ0FBQyxVQUFYLE9BQXVCO0FBQUE7QUFBdkIsT0FDQSxVQUFVLENBQUMsY0FEWCxJQUVBLFdBQVcsQ0FBQyxJQUFELENBSGIsRUFJRTtBQUNBLE1BQUEsSUFBSSxHQUFHLEtBQUssc0JBQUwsQ0FBNEIsSUFBNUIsQ0FBUDtBQUNEOztBQUVELFFBQUksS0FBSyxHQUFHLEtBQUssTUFBTCxDQUFZLE9BQVosQ0FBb0IsSUFBcEIsQ0FBWjs7QUFFQSxRQUFJLEtBQUssS0FBSyxDQUFDLENBQWYsRUFBa0I7QUFDaEIsYUFBTyxLQUFQO0FBQ0Q7O0FBRUQsSUFBQSxLQUFLLEdBQUcsS0FBSyxNQUFMLENBQVksTUFBcEI7QUFDQSxTQUFLLE1BQUwsQ0FBWSxJQUFaLENBQWlCLElBQWpCO0FBQ0EsV0FBTyxLQUFQO0FBQ0Q7O0FBRUQsRUFBQSxhQUFhLENBQUMsSUFBRCxFQUFhO0FBQ3hCLFFBQUksS0FBSyxHQUFHLEtBQUssS0FBTCxDQUFXLElBQVgsQ0FBWjs7QUFFQSxRQUFJLENBQUMsS0FBTCxFQUFZO0FBQ1YsTUFBQSxLQUFLLEdBQUcsS0FBSyxLQUFMLENBQVcsSUFBWCxJQUFtQixLQUFLLFFBQUwsQ0FBYyxJQUFkLENBQTNCO0FBQ0Q7O0FBRUQsV0FBTyxLQUFQO0FBQ0Q7O0FBRUQsRUFBQSxhQUFhLENBQUMsSUFBRCxFQUFhO0FBQ3hCLFFBQUksSUFBSSxLQUFLLFNBQWIsRUFBd0I7QUFDdEIsTUFBQSxJQUFJLEdBQUcsTUFBUDtBQUNEOztBQUVELFFBQUksS0FBSyxHQUFHLEtBQUssTUFBTCxDQUFZLElBQVosQ0FBWjs7QUFFQSxRQUFJLENBQUMsS0FBTCxFQUFZO0FBQ1YsTUFBQSxLQUFLLEdBQUcsS0FBSyxNQUFMLENBQVksSUFBWixJQUFvQixLQUFLLFFBQUwsQ0FBYyxJQUFJLElBQUksRUFBdEIsQ0FBNUI7QUFDRDs7QUFFRCxXQUFPLEtBQVA7QUFDRDs7QUFFRCxFQUFBLFFBQVEsQ0FBQyxVQUFELEVBQW1CO0FBQ3pCLFNBQUssT0FBTCxDQUFhLElBQWIsQ0FBa0IsVUFBbEI7QUFDQSxXQUFPLEtBQUssSUFBTCxFQUFQO0FBQ0Q7O0FBeEdnRDtBQTJHbkQsT0FBTSxNQUFPLGdCQUFQLFNBQWdDLFdBQWhDLENBQTJDO0FBQy9DLEVBQUEsV0FBQSxDQUFvQixNQUFwQixFQUFnRCxPQUFoRCxFQUEwRSxLQUExRSxFQUF5RjtBQUN2RjtBQURrQixTQUFBLE1BQUEsR0FBQSxNQUFBO0FBQTRCLFNBQUEsT0FBQSxHQUFBLE9BQUE7QUFBMEIsU0FBQSxLQUFBLEdBQUEsS0FBQTtBQUV6RTs7QUFFRCxNQUFJLE1BQUosR0FBVTtBQUNSLFdBQU8sS0FBSyxPQUFaO0FBQ0Q7O0FBRUQsRUFBQSxHQUFHLENBQUMsSUFBRCxFQUFhO0FBQ2QsV0FBTyxLQUFLLE9BQUwsQ0FBYSxPQUFiLENBQXFCLElBQXJCLE1BQStCLENBQUMsQ0FBaEMsSUFBcUMsS0FBSyxNQUFMLENBQVksR0FBWixDQUFnQixJQUFoQixDQUE1QztBQUNEOztBQUVELEVBQUEsR0FBRyxDQUFDLElBQUQsRUFBYTtBQUNkLFFBQUksSUFBSSxHQUFHLEtBQUssT0FBTCxDQUFhLE9BQWIsQ0FBcUIsSUFBckIsQ0FBWDtBQUNBLFdBQU8sSUFBSSxLQUFLLENBQUMsQ0FBVixHQUFjLEtBQUssTUFBTCxDQUFZLEdBQVosQ0FBZ0IsSUFBaEIsQ0FBZCxHQUFzQyxDQUFDLEtBQUssS0FBTCxDQUFXLElBQVgsQ0FBRCxFQUFtQixLQUFuQixDQUE3QztBQUNEOztBQUVELEVBQUEsWUFBWSxHQUFBO0FBQ1YsUUFBSSxJQUFJLEdBQUcsS0FBSyxNQUFMLENBQVksWUFBWixFQUFYO0FBQ0EsU0FBSyxPQUFMLENBQWEsT0FBYixDQUFzQixNQUFELElBQWEsSUFBSSxDQUFDLE1BQUQsQ0FBSixHQUFlLEtBQUssR0FBTCxDQUFTLE1BQVQsRUFBaUIsQ0FBakIsQ0FBakQ7QUFDQSxXQUFPLElBQVA7QUFDRDs7QUFFRCxFQUFBLFdBQVcsR0FBQTtBQUNULFFBQUksTUFBTSxHQUFHLEtBQUssWUFBTCxFQUFiO0FBQ0EsV0FBTyxNQUFNLENBQUMsSUFBUCxDQUFZLE1BQVosRUFBb0IsR0FBcEIsQ0FBeUIsTUFBRCxJQUFZLE1BQU0sQ0FBQyxNQUFELENBQTFDLENBQVA7QUFDRDs7QUFFRCxFQUFBLFVBQVUsR0FBQTtBQUNSLFNBQUssTUFBTCxDQUFZLFVBQVo7QUFDRDs7QUFFRCxFQUFBLFlBQVksQ0FBQyxJQUFELEVBQWUsVUFBZixFQUFrRDtBQUM1RCxXQUFPLEtBQUssTUFBTCxDQUFZLFlBQVosQ0FBeUIsSUFBekIsRUFBK0IsVUFBL0IsQ0FBUDtBQUNEOztBQUVELEVBQUEsYUFBYSxDQUFDLElBQUQsRUFBYTtBQUN4QixXQUFPLEtBQUssTUFBTCxDQUFZLGFBQVosQ0FBMEIsSUFBMUIsQ0FBUDtBQUNEOztBQUVELEVBQUEsYUFBYSxDQUFDLElBQUQsRUFBYTtBQUN4QixXQUFPLEtBQUssTUFBTCxDQUFZLGFBQVosQ0FBMEIsSUFBMUIsQ0FBUDtBQUNEOztBQUVELEVBQUEsUUFBUSxDQUFDLFVBQUQsRUFBbUI7QUFDekIsV0FBTyxLQUFLLE1BQUwsQ0FBWSxRQUFaLENBQXFCLFVBQXJCLENBQVA7QUFDRDs7QUEvQzhDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29yZSwgRGljdCwgU2V4cE9wY29kZXMgfSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7IGRpY3QgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcblxuaW1wb3J0IHsgQVNUdjIgfSBmcm9tICcuLic7XG5pbXBvcnQgeyBpc1VwcGVyQ2FzZSB9IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgU3ltYm9sVGFibGUge1xuICBzdGF0aWMgdG9wKFxuICAgIGxvY2Fsczogc3RyaW5nW10sXG4gICAgY3VzdG9taXplQ29tcG9uZW50TmFtZTogKGlucHV0OiBzdHJpbmcpID0+IHN0cmluZ1xuICApOiBQcm9ncmFtU3ltYm9sVGFibGUge1xuICAgIHJldHVybiBuZXcgUHJvZ3JhbVN5bWJvbFRhYmxlKGxvY2FscywgY3VzdG9taXplQ29tcG9uZW50TmFtZSk7XG4gIH1cblxuICBhYnN0cmFjdCBoYXMobmFtZTogc3RyaW5nKTogYm9vbGVhbjtcbiAgYWJzdHJhY3QgZ2V0KG5hbWU6IHN0cmluZyk6IFtzeW1ib2w6IG51bWJlciwgaXNSb290OiBib29sZWFuXTtcblxuICBhYnN0cmFjdCBnZXRMb2NhbHNNYXAoKTogRGljdDxudW1iZXI+O1xuICBhYnN0cmFjdCBnZXRFdmFsSW5mbygpOiBDb3JlLkV2YWxJbmZvO1xuXG4gIGFic3RyYWN0IGFsbG9jYXRlRnJlZShuYW1lOiBzdHJpbmcsIHJlc29sdXRpb246IEFTVHYyLkZyZWVWYXJSZXNvbHV0aW9uKTogbnVtYmVyO1xuICBhYnN0cmFjdCBhbGxvY2F0ZU5hbWVkKG5hbWU6IHN0cmluZyk6IG51bWJlcjtcbiAgYWJzdHJhY3QgYWxsb2NhdGVCbG9jayhuYW1lOiBzdHJpbmcpOiBudW1iZXI7XG4gIGFic3RyYWN0IGFsbG9jYXRlKGlkZW50aWZpZXI6IHN0cmluZyk6IG51bWJlcjtcblxuICBhYnN0cmFjdCBzZXRIYXNFdmFsKCk6IHZvaWQ7XG5cbiAgY2hpbGQobG9jYWxzOiBzdHJpbmdbXSk6IEJsb2NrU3ltYm9sVGFibGUge1xuICAgIGxldCBzeW1ib2xzID0gbG9jYWxzLm1hcCgobmFtZSkgPT4gdGhpcy5hbGxvY2F0ZShuYW1lKSk7XG4gICAgcmV0dXJuIG5ldyBCbG9ja1N5bWJvbFRhYmxlKHRoaXMsIGxvY2Fscywgc3ltYm9scyk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFByb2dyYW1TeW1ib2xUYWJsZSBleHRlbmRzIFN5bWJvbFRhYmxlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSB0ZW1wbGF0ZUxvY2Fsczogc3RyaW5nW10sXG4gICAgcHJpdmF0ZSBjdXN0b21pemVDb21wb25lbnROYW1lOiAoaW5wdXQ6IHN0cmluZykgPT4gc3RyaW5nXG4gICkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBwdWJsaWMgc3ltYm9sczogc3RyaW5nW10gPSBbXTtcbiAgcHVibGljIHVwdmFyczogc3RyaW5nW10gPSBbXTtcblxuICBwcml2YXRlIHNpemUgPSAxO1xuICBwcml2YXRlIG5hbWVkID0gZGljdDxudW1iZXI+KCk7XG4gIHByaXZhdGUgYmxvY2tzID0gZGljdDxudW1iZXI+KCk7XG4gIHByaXZhdGUgdXNlZFRlbXBsYXRlTG9jYWxzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIF9oYXNFdmFsID0gZmFsc2U7XG5cbiAgZ2V0VXNlZFRlbXBsYXRlTG9jYWxzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy51c2VkVGVtcGxhdGVMb2NhbHM7XG4gIH1cblxuICBzZXRIYXNFdmFsKCk6IHZvaWQge1xuICAgIHRoaXMuX2hhc0V2YWwgPSB0cnVlO1xuICB9XG5cbiAgZ2V0IGhhc0V2YWwoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2hhc0V2YWw7XG4gIH1cblxuICBoYXMobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMudGVtcGxhdGVMb2NhbHMuaW5kZXhPZihuYW1lKSAhPT0gLTE7XG4gIH1cblxuICBnZXQobmFtZTogc3RyaW5nKTogW251bWJlciwgYm9vbGVhbl0ge1xuICAgIGxldCBpbmRleCA9IHRoaXMudXNlZFRlbXBsYXRlTG9jYWxzLmluZGV4T2YobmFtZSk7XG5cbiAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICByZXR1cm4gW2luZGV4LCB0cnVlXTtcbiAgICB9XG5cbiAgICBpbmRleCA9IHRoaXMudXNlZFRlbXBsYXRlTG9jYWxzLmxlbmd0aDtcbiAgICB0aGlzLnVzZWRUZW1wbGF0ZUxvY2Fscy5wdXNoKG5hbWUpO1xuICAgIHJldHVybiBbaW5kZXgsIHRydWVdO1xuICB9XG5cbiAgZ2V0TG9jYWxzTWFwKCk6IERpY3Q8bnVtYmVyPiB7XG4gICAgcmV0dXJuIGRpY3QoKTtcbiAgfVxuXG4gIGdldEV2YWxJbmZvKCk6IENvcmUuRXZhbEluZm8ge1xuICAgIGxldCBsb2NhbHMgPSB0aGlzLmdldExvY2Fsc01hcCgpO1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhsb2NhbHMpLm1hcCgoc3ltYm9sKSA9PiBsb2NhbHNbc3ltYm9sXSk7XG4gIH1cblxuICBhbGxvY2F0ZUZyZWUobmFtZTogc3RyaW5nLCByZXNvbHV0aW9uOiBBU1R2Mi5GcmVlVmFyUmVzb2x1dGlvbik6IG51bWJlciB7XG4gICAgLy8gSWYgdGhlIG5hbWUgaW4gcXVlc3Rpb24gaXMgYW4gdXBwZXJjYXNlIChpLmUuIGFuZ2xlLWJyYWNrZXQpIGNvbXBvbmVudCBpbnZvY2F0aW9uLCBydW5cbiAgICAvLyB0aGUgb3B0aW9uYWwgYGN1c3RvbWl6ZUNvbXBvbmVudE5hbWVgIGZ1bmN0aW9uIHByb3ZpZGVkIHRvIHRoZSBwcmVjb21waWxlci5cbiAgICBpZiAoXG4gICAgICByZXNvbHV0aW9uLnJlc29sdXRpb24oKSA9PT0gU2V4cE9wY29kZXMuR2V0RnJlZUFzQ29tcG9uZW50SGVhZCAmJlxuICAgICAgcmVzb2x1dGlvbi5pc0FuZ2xlQnJhY2tldCAmJlxuICAgICAgaXNVcHBlckNhc2UobmFtZSlcbiAgICApIHtcbiAgICAgIG5hbWUgPSB0aGlzLmN1c3RvbWl6ZUNvbXBvbmVudE5hbWUobmFtZSk7XG4gICAgfVxuXG4gICAgbGV0IGluZGV4ID0gdGhpcy51cHZhcnMuaW5kZXhPZihuYW1lKTtcblxuICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG5cbiAgICBpbmRleCA9IHRoaXMudXB2YXJzLmxlbmd0aDtcbiAgICB0aGlzLnVwdmFycy5wdXNoKG5hbWUpO1xuICAgIHJldHVybiBpbmRleDtcbiAgfVxuXG4gIGFsbG9jYXRlTmFtZWQobmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICBsZXQgbmFtZWQgPSB0aGlzLm5hbWVkW25hbWVdO1xuXG4gICAgaWYgKCFuYW1lZCkge1xuICAgICAgbmFtZWQgPSB0aGlzLm5hbWVkW25hbWVdID0gdGhpcy5hbGxvY2F0ZShuYW1lKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmFtZWQ7XG4gIH1cblxuICBhbGxvY2F0ZUJsb2NrKG5hbWU6IHN0cmluZyk6IG51bWJlciB7XG4gICAgaWYgKG5hbWUgPT09ICdpbnZlcnNlJykge1xuICAgICAgbmFtZSA9ICdlbHNlJztcbiAgICB9XG5cbiAgICBsZXQgYmxvY2sgPSB0aGlzLmJsb2Nrc1tuYW1lXTtcblxuICAgIGlmICghYmxvY2spIHtcbiAgICAgIGJsb2NrID0gdGhpcy5ibG9ja3NbbmFtZV0gPSB0aGlzLmFsbG9jYXRlKGAmJHtuYW1lfWApO1xuICAgIH1cblxuICAgIHJldHVybiBibG9jaztcbiAgfVxuXG4gIGFsbG9jYXRlKGlkZW50aWZpZXI6IHN0cmluZyk6IG51bWJlciB7XG4gICAgdGhpcy5zeW1ib2xzLnB1c2goaWRlbnRpZmllcik7XG4gICAgcmV0dXJuIHRoaXMuc2l6ZSsrO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBCbG9ja1N5bWJvbFRhYmxlIGV4dGVuZHMgU3ltYm9sVGFibGUge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHBhcmVudDogU3ltYm9sVGFibGUsIHB1YmxpYyBzeW1ib2xzOiBzdHJpbmdbXSwgcHVibGljIHNsb3RzOiBudW1iZXJbXSkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICBnZXQgbG9jYWxzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5zeW1ib2xzO1xuICB9XG5cbiAgaGFzKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN5bWJvbHMuaW5kZXhPZihuYW1lKSAhPT0gLTEgfHwgdGhpcy5wYXJlbnQuaGFzKG5hbWUpO1xuICB9XG5cbiAgZ2V0KG5hbWU6IHN0cmluZyk6IFtudW1iZXIsIGJvb2xlYW5dIHtcbiAgICBsZXQgc2xvdCA9IHRoaXMuc3ltYm9scy5pbmRleE9mKG5hbWUpO1xuICAgIHJldHVybiBzbG90ID09PSAtMSA/IHRoaXMucGFyZW50LmdldChuYW1lKSA6IFt0aGlzLnNsb3RzW3Nsb3RdLCBmYWxzZV07XG4gIH1cblxuICBnZXRMb2NhbHNNYXAoKTogRGljdDxudW1iZXI+IHtcbiAgICBsZXQgZGljdCA9IHRoaXMucGFyZW50LmdldExvY2Fsc01hcCgpO1xuICAgIHRoaXMuc3ltYm9scy5mb3JFYWNoKChzeW1ib2wpID0+IChkaWN0W3N5bWJvbF0gPSB0aGlzLmdldChzeW1ib2wpWzBdKSk7XG4gICAgcmV0dXJuIGRpY3Q7XG4gIH1cblxuICBnZXRFdmFsSW5mbygpOiBDb3JlLkV2YWxJbmZvIHtcbiAgICBsZXQgbG9jYWxzID0gdGhpcy5nZXRMb2NhbHNNYXAoKTtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMobG9jYWxzKS5tYXAoKHN5bWJvbCkgPT4gbG9jYWxzW3N5bWJvbF0pO1xuICB9XG5cbiAgc2V0SGFzRXZhbCgpOiB2b2lkIHtcbiAgICB0aGlzLnBhcmVudC5zZXRIYXNFdmFsKCk7XG4gIH1cblxuICBhbGxvY2F0ZUZyZWUobmFtZTogc3RyaW5nLCByZXNvbHV0aW9uOiBBU1R2Mi5GcmVlVmFyUmVzb2x1dGlvbik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGFyZW50LmFsbG9jYXRlRnJlZShuYW1lLCByZXNvbHV0aW9uKTtcbiAgfVxuXG4gIGFsbG9jYXRlTmFtZWQobmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQuYWxsb2NhdGVOYW1lZChuYW1lKTtcbiAgfVxuXG4gIGFsbG9jYXRlQmxvY2sobmFtZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQuYWxsb2NhdGVCbG9jayhuYW1lKTtcbiAgfVxuXG4gIGFsbG9jYXRlKGlkZW50aWZpZXI6IHN0cmluZyk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGFyZW50LmFsbG9jYXRlKGlkZW50aWZpZXIpO1xuICB9XG59XG4iXSwic291cmNlUm9vdCI6IiJ9