@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
486 lines (402 loc) • 42.4 kB
JavaScript
import { DEBUG } from '@glimmer/env';
import { createDebugAliasRef, UNDEFINED_REFERENCE, valueForRef } from '@glimmer/reference';
import { dict, emptyArray, EMPTY_STRING_ARRAY } from '@glimmer/util';
import { CONSTANT_TAG } from '@glimmer/validator';
import { $sp } from '@glimmer/vm';
import { REGISTERS } from '../symbols';
/*
The calling convention is:
* 0-N block arguments at the bottom
* 0-N positional arguments next (left-to-right)
* 0-N named arguments next
*/
export class VMArgumentsImpl {
constructor() {
this.stack = null;
this.positional = new PositionalArgumentsImpl();
this.named = new NamedArgumentsImpl();
this.blocks = new BlockArgumentsImpl();
}
empty(stack) {
let base = stack[REGISTERS][$sp] + 1;
this.named.empty(stack, base);
this.positional.empty(stack, base);
this.blocks.empty(stack, base);
return this;
}
setup(stack, names, blockNames, positionalCount, atNames) {
this.stack = stack;
/*
| ... | blocks | positional | named |
| ... | b0 b1 | p0 p1 p2 p3 | n0 n1 |
index | ... | 4/5/6 7/8/9 | 10 11 12 13 | 14 15 |
^ ^ ^ ^
bbase pbase nbase sp
*/
let named = this.named;
let namedCount = names.length;
let namedBase = stack[REGISTERS][$sp] - namedCount + 1;
named.setup(stack, namedBase, namedCount, names, atNames);
let positional = this.positional;
let positionalBase = namedBase - positionalCount;
positional.setup(stack, positionalBase, positionalCount);
let blocks = this.blocks;
let blocksCount = blockNames.length;
let blocksBase = positionalBase - blocksCount * 3;
blocks.setup(stack, blocksBase, blocksCount, blockNames);
}
get base() {
return this.blocks.base;
}
get length() {
return this.positional.length + this.named.length + this.blocks.length * 3;
}
at(pos) {
return this.positional.at(pos);
}
realloc(offset) {
let {
stack
} = this;
if (offset > 0 && stack !== null) {
let {
positional,
named
} = this;
let newBase = positional.base + offset;
let length = positional.length + named.length;
for (let i = length - 1; i >= 0; i--) {
stack.copy(i + positional.base, i + newBase);
}
positional.base += offset;
named.base += offset;
stack[REGISTERS][$sp] += offset;
}
}
capture() {
let positional = this.positional.length === 0 ? EMPTY_POSITIONAL : this.positional.capture();
let named = this.named.length === 0 ? EMPTY_NAMED : this.named.capture();
return {
named,
positional
};
}
clear() {
let {
stack,
length
} = this;
if (length > 0 && stack !== null) stack.pop(length);
}
}
const EMPTY_REFERENCES = emptyArray();
export class PositionalArgumentsImpl {
constructor() {
this.base = 0;
this.length = 0;
this.stack = null;
this._references = null;
}
empty(stack, base) {
this.stack = stack;
this.base = base;
this.length = 0;
this._references = EMPTY_REFERENCES;
}
setup(stack, base, length) {
this.stack = stack;
this.base = base;
this.length = length;
if (length === 0) {
this._references = EMPTY_REFERENCES;
} else {
this._references = null;
}
}
at(position) {
let {
base,
length,
stack
} = this;
if (position < 0 || position >= length) {
return UNDEFINED_REFERENCE;
}
return stack.get(position, base);
}
capture() {
return this.references;
}
prepend(other) {
let additions = other.length;
if (additions > 0) {
let {
base,
length,
stack
} = this;
this.base = base = base - additions;
this.length = length + additions;
for (let i = 0; i < additions; i++) {
stack.set(other[i], i, base);
}
this._references = null;
}
}
get references() {
let references = this._references;
if (!references) {
let {
stack,
base,
length
} = this;
references = this._references = stack.slice(base, base + length);
}
return references;
}
}
export class NamedArgumentsImpl {
constructor() {
this.base = 0;
this.length = 0;
this._references = null;
this._names = EMPTY_STRING_ARRAY;
this._atNames = EMPTY_STRING_ARRAY;
}
empty(stack, base) {
this.stack = stack;
this.base = base;
this.length = 0;
this._references = EMPTY_REFERENCES;
this._names = EMPTY_STRING_ARRAY;
this._atNames = EMPTY_STRING_ARRAY;
}
setup(stack, base, length, names, atNames) {
this.stack = stack;
this.base = base;
this.length = length;
if (length === 0) {
this._references = EMPTY_REFERENCES;
this._names = EMPTY_STRING_ARRAY;
this._atNames = EMPTY_STRING_ARRAY;
} else {
this._references = null;
if (atNames) {
this._names = null;
this._atNames = names;
} else {
this._names = names;
this._atNames = null;
}
}
}
get names() {
let names = this._names;
if (!names) {
names = this._names = this._atNames.map(this.toSyntheticName);
}
return names;
}
get atNames() {
let atNames = this._atNames;
if (!atNames) {
atNames = this._atNames = this._names.map(this.toAtName);
}
return atNames;
}
has(name) {
return this.names.indexOf(name) !== -1;
}
get(name, atNames = false) {
let {
base,
stack
} = this;
let names = atNames ? this.atNames : this.names;
let idx = names.indexOf(name);
if (idx === -1) {
return UNDEFINED_REFERENCE;
}
let ref = stack.get(idx, base);
if (DEBUG) {
return createDebugAliasRef(atNames ? name : `@${name}`, ref);
} else {
return ref;
}
}
capture() {
let {
names,
references
} = this;
let map = dict();
for (let i = 0; i < names.length; i++) {
let name = names[i];
if (DEBUG) {
map[name] = createDebugAliasRef(`@${name}`, references[i]);
} else {
map[name] = references[i];
}
}
return map;
}
merge(other) {
let keys = Object.keys(other);
if (keys.length > 0) {
let {
names,
length,
stack
} = this;
let newNames = names.slice();
for (let i = 0; i < keys.length; i++) {
let name = keys[i];
let idx = newNames.indexOf(name);
if (idx === -1) {
length = newNames.push(name);
stack.push(other[name]);
}
}
this.length = length;
this._references = null;
this._names = newNames;
this._atNames = null;
}
}
get references() {
let references = this._references;
if (!references) {
let {
base,
length,
stack
} = this;
references = this._references = stack.slice(base, base + length);
}
return references;
}
toSyntheticName(name) {
return name.slice(1);
}
toAtName(name) {
return `@${name}`;
}
}
function toSymbolName(name) {
return `&${name}`;
}
const EMPTY_BLOCK_VALUES = emptyArray();
export class BlockArgumentsImpl {
constructor() {
this.internalValues = null;
this._symbolNames = null;
this.internalTag = null;
this.names = EMPTY_STRING_ARRAY;
this.length = 0;
this.base = 0;
}
empty(stack, base) {
this.stack = stack;
this.names = EMPTY_STRING_ARRAY;
this.base = base;
this.length = 0;
this._symbolNames = null;
this.internalTag = CONSTANT_TAG;
this.internalValues = EMPTY_BLOCK_VALUES;
}
setup(stack, base, length, names) {
this.stack = stack;
this.names = names;
this.base = base;
this.length = length;
this._symbolNames = null;
if (length === 0) {
this.internalTag = CONSTANT_TAG;
this.internalValues = EMPTY_BLOCK_VALUES;
} else {
this.internalTag = null;
this.internalValues = null;
}
}
get values() {
let values = this.internalValues;
if (!values) {
let {
base,
length,
stack
} = this;
values = this.internalValues = stack.slice(base, base + length * 3);
}
return values;
}
has(name) {
return this.names.indexOf(name) !== -1;
}
get(name) {
let idx = this.names.indexOf(name);
if (idx === -1) {
return null;
}
let {
base,
stack
} = this;
let table = stack.get(idx * 3, base);
let scope = stack.get(idx * 3 + 1, base);
let handle = stack.get(idx * 3 + 2, base);
return handle === null ? null : [handle, scope, table];
}
capture() {
return new CapturedBlockArgumentsImpl(this.names, this.values);
}
get symbolNames() {
let symbolNames = this._symbolNames;
if (symbolNames === null) {
symbolNames = this._symbolNames = this.names.map(toSymbolName);
}
return symbolNames;
}
}
class CapturedBlockArgumentsImpl {
constructor(names, values) {
this.names = names;
this.values = values;
this.length = names.length;
}
has(name) {
return this.names.indexOf(name) !== -1;
}
get(name) {
let idx = this.names.indexOf(name);
if (idx === -1) return null;
return [this.values[idx * 3 + 2], this.values[idx * 3 + 1], this.values[idx * 3]];
}
}
export function createCapturedArgs(named, positional) {
return {
named,
positional
};
}
export function reifyNamed(named) {
let reified = dict();
for (let key in named) {
reified[key] = valueForRef(named[key]);
}
return reified;
}
export function reifyPositional(positional) {
return positional.map(valueForRef);
}
export function reifyArgs(args) {
return {
named: reifyNamed(args.named),
positional: reifyPositional(args.positional)
};
}
export const EMPTY_NAMED = Object.freeze(Object.create(null));
export const EMPTY_POSITIONAL = EMPTY_REFERENCES;
export const EMPTY_ARGS = createCapturedArgs(EMPTY_NAMED, EMPTY_POSITIONAL);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL2FyZ3VtZW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxTQUFTLEtBQVQsUUFBc0IsY0FBdEI7QUFrQkEsU0FDRSxtQkFERixFQUdFLG1CQUhGLEVBSUUsV0FKRixRQUtPLG9CQUxQO0FBTUEsU0FBUyxJQUFULEVBQWUsVUFBZixFQUEyQixrQkFBM0IsUUFBcUQsZUFBckQ7QUFDQSxTQUFTLFlBQVQsUUFBa0Msb0JBQWxDO0FBQ0EsU0FBUyxHQUFULFFBQW9CLGFBQXBCO0FBRUEsU0FBUyxTQUFULFFBQTBCLFlBQTFCO0FBR0E7Ozs7Ozs7O0FBUUEsT0FBTSxNQUFPLGVBQVAsQ0FBc0I7QUFBNUIsRUFBQSxXQUFBLEdBQUE7QUFDVSxTQUFBLEtBQUEsR0FBaUMsSUFBakM7QUFDRCxTQUFBLFVBQUEsR0FBYSxJQUFJLHVCQUFKLEVBQWI7QUFDQSxTQUFBLEtBQUEsR0FBUSxJQUFJLGtCQUFKLEVBQVI7QUFDQSxTQUFBLE1BQUEsR0FBUyxJQUFJLGtCQUFKLEVBQVQ7QUF1RlI7O0FBckZDLEVBQUEsS0FBSyxDQUFDLEtBQUQsRUFBdUI7QUFDMUIsUUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFDLFNBQUQsQ0FBTCxDQUFpQixHQUFqQixJQUF3QixDQUFuQztBQUVBLFNBQUssS0FBTCxDQUFXLEtBQVgsQ0FBaUIsS0FBakIsRUFBd0IsSUFBeEI7QUFDQSxTQUFLLFVBQUwsQ0FBZ0IsS0FBaEIsQ0FBc0IsS0FBdEIsRUFBNkIsSUFBN0I7QUFDQSxTQUFLLE1BQUwsQ0FBWSxLQUFaLENBQWtCLEtBQWxCLEVBQXlCLElBQXpCO0FBRUEsV0FBTyxJQUFQO0FBQ0Q7O0FBRUQsRUFBQSxLQUFLLENBQ0gsS0FERyxFQUVILEtBRkcsRUFHSCxVQUhHLEVBSUgsZUFKRyxFQUtILE9BTEcsRUFLYTtBQUVoQixTQUFLLEtBQUwsR0FBYSxLQUFiO0FBRUE7Ozs7Ozs7O0FBUUEs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LFVBQVUsRUFBRSxlQUFlLENBQUMsSUFBSSxDQUFDLFVBQU47QUFGdEIsR0FBUDtBQUlEO0FBRUQsT0FBTyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsTUFBUCxDQUFjLE1BQU0sQ0FBQyxNQUFQLENBQWMsSUFBZCxDQUFkLENBQXBCO0FBQ1AsT0FBTyxNQUFNLGdCQUFnQixHQUFHLGdCQUF6QjtBQUNQLE9BQU8sTUFBTSxVQUFVLEdBQUcsa0JBQWtCLENBQUMsV0FBRCxFQUFjLGdCQUFkLENBQXJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY2hlY2ssIENoZWNrQmxvY2tTeW1ib2xUYWJsZSwgQ2hlY2tIYW5kbGUsIENoZWNrT3B0aW9uLCBDaGVja09yIH0gZnJvbSAnQGdsaW1tZXIvZGVidWcnO1xuaW1wb3J0IHsgREVCVUcgfSBmcm9tICdAZ2xpbW1lci9lbnYnO1xuaW1wb3J0IHtcbiAgQmxvY2tBcmd1bWVudHMsXG4gIEJsb2NrU3ltYm9sVGFibGUsXG4gIEJsb2NrVmFsdWUsXG4gIENhcHR1cmVkQXJndW1lbnRzLFxuICBDYXB0dXJlZEJsb2NrQXJndW1lbnRzLFxuICBDYXB0dXJlZE5hbWVkQXJndW1lbnRzLFxuICBDYXB0dXJlZFBvc2l0aW9uYWxBcmd1bWVudHMsXG4gIENvbXBpbGFibGVCbG9jayxcbiAgRGljdCxcbiAgTmFtZWRBcmd1bWVudHMsXG4gIE9wdGlvbixcbiAgUG9zaXRpb25hbEFyZ3VtZW50cyxcbiAgU2NvcGUsXG4gIFNjb3BlQmxvY2ssXG4gIFZNQXJndW1lbnRzLFxufSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7XG4gIGNyZWF0ZURlYnVnQWxpYXNSZWYsXG4gIFJlZmVyZW5jZSxcbiAgVU5ERUZJTkVEX1JFRkVSRU5DRSxcbiAgdmFsdWVGb3JSZWYsXG59IGZyb20gJ0BnbGltbWVyL3JlZmVyZW5jZSc7XG5pbXBvcnQgeyBkaWN0LCBlbXB0eUFycmF5LCBFTVBUWV9TVFJJTkdfQVJSQVkgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcbmltcG9ydCB7IENPTlNUQU5UX1RBRywgVGFnIH0gZnJvbSAnQGdsaW1tZXIvdmFsaWRhdG9yJztcbmltcG9ydCB7ICRzcCB9IGZyb20gJ0BnbGltbWVyL3ZtJztcbmltcG9ydCB7IENoZWNrQ29tcGlsYWJsZUJsb2NrLCBDaGVja1JlZmVyZW5jZSwgQ2hlY2tTY29wZSB9IGZyb20gJy4uL2NvbXBpbGVkL29wY29kZXMvLWRlYnVnLXN0cmlwJztcbmltcG9ydCB7IFJFR0lTVEVSUyB9IGZyb20gJy4uL3N5bWJvbHMnO1xuaW1wb3J0IHsgRXZhbHVhdGlvblN0YWNrIH0gZnJvbSAnLi9zdGFjayc7XG5cbi8qXG4gIFRoZSBjYWxsaW5nIGNvbnZlbnRpb24gaXM6XG5cbiAgKiAwLU4gYmxvY2sgYXJndW1lbnRzIGF0IHRoZSBib3R0b21cbiAgKiAwLU4gcG9zaXRpb25hbCBhcmd1bWVudHMgbmV4dCAobGVmdC10by1yaWdodClcbiAgKiAwLU4gbmFtZWQgYXJndW1lbnRzIG5leHRcbiovXG5cbmV4cG9ydCBjbGFzcyBWTUFyZ3VtZW50c0ltcGwgaW1wbGVtZW50cyBWTUFyZ3VtZW50cyB7XG4gIHByaXZhdGUgc3RhY2s6IE9wdGlvbjxFdmFsdWF0aW9uU3RhY2s+ID0gbnVsbDtcbiAgcHVibGljIHBvc2l0aW9uYWwgPSBuZXcgUG9zaXRpb25hbEFyZ3VtZW50c0ltcGwoKTtcbiAgcHVibGljIG5hbWVkID0gbmV3IE5hbWVkQXJndW1lbnRzSW1wbCgpO1xuICBwdWJsaWMgYmxvY2tzID0gbmV3IEJsb2NrQXJndW1lbnRzSW1wbCgpO1xuXG4gIGVtcHR5KHN0YWNrOiBFdmFsdWF0aW9uU3RhY2spOiB0aGlzIHtcbiAgICBsZXQgYmFzZSA9IHN0YWNrW1JFR0lTVEVSU11bJHNwXSArIDE7XG5cbiAgICB0aGlzLm5hbWVkLmVtcHR5KHN0YWNrLCBiYXNlKTtcbiAgICB0aGlzLnBvc2l0aW9uYWwuZW1wdHkoc3RhY2ssIGJhc2UpO1xuICAgIHRoaXMuYmxvY2tzLmVtcHR5KHN0YWNrLCBiYXNlKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc2V0dXAoXG4gICAgc3RhY2s6IEV2YWx1YXRpb25TdGFjayxcbiAgICBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgYmxvY2tOYW1lczogcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgcG9zaXRpb25hbENvdW50OiBudW1iZXIsXG4gICAgYXROYW1lczogYm9vbGVhblxuICApIHtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG5cbiAgICAvKlxuICAgICAgICAgICB8IC4uLiB8IGJsb2NrcyAgICAgIHwgcG9zaXRpb25hbCAgfCBuYW1lZCB8XG4gICAgICAgICAgIHwgLi4uIHwgYjAgICAgYjEgICAgfCBwMCBwMSBwMiBwMyB8IG4wIG4xIHxcbiAgICAgaW5kZXggfCAuLi4gfCA0LzUvNiA3LzgvOSB8IDEwIDExIDEyIDEzIHwgMTQgMTUgfFxuICAgICAgICAgICAgICAgICAgIF4gICAgICAgICAgICAgXiAgICAgICAgICAgICBeICBeXG4gICAgICAgICAgICAgICAgIGJiYXNlICAgICAgICAgcGJhc2UgICAgICAgbmJhc2UgIHNwXG4gICAgKi9cblxuICAgIGxldCBuYW1lZCA9IHRoaXMubmFtZWQ7XG4gICAgbGV0IG5hbWVkQ291bnQgPSBuYW1lcy5sZW5ndGg7XG4gICAgbGV0IG5hbWVkQmFzZSA9IHN0YWNrW1JFR0lTVEVSU11bJHNwXSAtIG5hbWVkQ291bnQgKyAxO1xuXG4gICAgbmFtZWQuc2V0dXAoc3RhY2ssIG5hbWVkQmFzZSwgbmFtZWRDb3VudCwgbmFtZXMsIGF0TmFtZXMpO1xuXG4gICAgbGV0IHBvc2l0aW9uYWwgPSB0aGlzLnBvc2l0aW9uYWw7XG4gICAgbGV0IHBvc2l0aW9uYWxCYXNlID0gbmFtZWRCYXNlIC0gcG9zaXRpb25hbENvdW50O1xuXG4gICAgcG9zaXRpb25hbC5zZXR1cChzdGFjaywgcG9zaXRpb25hbEJhc2UsIHBvc2l0aW9uYWxDb3VudCk7XG5cbiAgICBsZXQgYmxvY2tzID0gdGhpcy5ibG9ja3M7XG4gICAgbGV0IGJsb2Nrc0NvdW50ID0gYmxvY2tOYW1lcy5sZW5ndGg7XG4gICAgbGV0IGJsb2Nrc0Jhc2UgPSBwb3NpdGlvbmFsQmFzZSAtIGJsb2Nrc0NvdW50ICogMztcblxuICAgIGJsb2Nrcy5zZXR1cChzdGFjaywgYmxvY2tzQmFzZSwgYmxvY2tzQ291bnQsIGJsb2NrTmFtZXMpO1xuICB9XG5cbiAgZ2V0IGJhc2UoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5ibG9ja3MuYmFzZTtcbiAgfVxuXG4gIGdldCBsZW5ndGgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbmFsLmxlbmd0aCArIHRoaXMubmFtZWQubGVuZ3RoICsgdGhpcy5ibG9ja3MubGVuZ3RoICogMztcbiAgfVxuXG4gIGF0KHBvczogbnVtYmVyKTogUmVmZXJlbmNlIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbmFsLmF0KHBvcyk7XG4gIH1cblxuICByZWFsbG9jKG9mZnNldDogbnVtYmVyKSB7XG4gICAgbGV0IHsgc3RhY2sgfSA9IHRoaXM7XG4gICAgaWYgKG9mZnNldCA+IDAgJiYgc3RhY2sgIT09IG51bGwpIHtcbiAgICAgIGxldCB7IHBvc2l0aW9uYWwsIG5hbWVkIH0gPSB0aGlzO1xuICAgICAgbGV0IG5ld0Jhc2UgPSBwb3NpdGlvbmFsLmJhc2UgKyBvZmZzZXQ7XG4gICAgICBsZXQgbGVuZ3RoID0gcG9zaXRpb25hbC5sZW5ndGggKyBuYW1lZC5sZW5ndGg7XG5cbiAgICAgIGZvciAobGV0IGkgPSBsZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBzdGFjay5jb3B5KGkgKyBwb3NpdGlvbmFsLmJhc2UsIGkgKyBuZXdCYXNlKTtcbiAgICAgIH1cblxuICAgICAgcG9zaXRpb25hbC5iYXNlICs9IG9mZnNldDtcbiAgICAgIG5hbWVkLmJhc2UgKz0gb2Zmc2V0O1xuICAgICAgc3RhY2tbUkVHSVNURVJTXVskc3BdICs9IG9mZnNldDtcbiAgICB9XG4gIH1cblxuICBjYXB0dXJlKCk6IENhcHR1cmVkQXJndW1lbnRzIHtcbiAgICBsZXQgcG9zaXRpb25hbCA9IHRoaXMucG9zaXRpb25hbC5sZW5ndGggPT09IDAgPyBFTVBUWV9QT1NJVElPTkFMIDogdGhpcy5wb3NpdGlvbmFsLmNhcHR1cmUoKTtcbiAgICBsZXQgbmFtZWQgPSB0aGlzLm5hbWVkLmxlbmd0aCA9PT0gMCA/IEVNUFRZX05BTUVEIDogdGhpcy5uYW1lZC5jYXB0dXJlKCk7XG5cbiAgICByZXR1cm4geyBuYW1lZCwgcG9zaXRpb25hbCB9IGFzIENhcHR1cmVkQXJndW1lbnRzO1xuICB9XG5cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgbGV0IHsgc3RhY2ssIGxlbmd0aCB9ID0gdGhpcztcbiAgICBpZiAobGVuZ3RoID4gMCAmJiBzdGFjayAhPT0gbnVsbCkgc3RhY2sucG9wKGxlbmd0aCk7XG4gIH1cbn1cblxuY29uc3QgRU1QVFlfUkVGRVJFTkNFUyA9IGVtcHR5QXJyYXk8UmVmZXJlbmNlPigpO1xuXG5leHBvcnQgY2xhc3MgUG9zaXRpb25hbEFyZ3VtZW50c0ltcGwgaW1wbGVtZW50cyBQb3NpdGlvbmFsQXJndW1lbnRzIHtcbiAgcHVibGljIGJhc2UgPSAwO1xuICBwdWJsaWMgbGVuZ3RoID0gMDtcblxuICBwcml2YXRlIHN0YWNrOiBFdmFsdWF0aW9uU3RhY2sgPSBudWxsIGFzIGFueTtcblxuICBwcml2YXRlIF9yZWZlcmVuY2VzOiBPcHRpb248cmVhZG9ubHkgUmVmZXJlbmNlW10+ID0gbnVsbDtcblxuICBlbXB0eShzdGFjazogRXZhbHVhdGlvblN0YWNrLCBiYXNlOiBudW1iZXIpIHtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5iYXNlID0gYmFzZTtcbiAgICB0aGlzLmxlbmd0aCA9IDA7XG5cbiAgICB0aGlzLl9yZWZlcmVuY2VzID0gRU1QVFlfUkVGRVJFTkNFUztcbiAgfVxuXG4gIHNldHVwKHN0YWNrOiBFdmFsdWF0aW9uU3RhY2ssIGJhc2U6IG51bWJlciwgbGVuZ3RoOiBudW1iZXIpIHtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5iYXNlID0gYmFzZTtcbiAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcblxuICAgIGlmIChsZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuX3JlZmVyZW5jZXMgPSBFTVBUWV9SRUZFUkVOQ0VTO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9yZWZlcmVuY2VzID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBhdChwb3NpdGlvbjogbnVtYmVyKTogUmVmZXJlbmNlIHtcbiAgICBsZXQgeyBiYXNlLCBsZW5ndGgsIHN0YWNrIH0gPSB0aGlzO1xuXG4gICAgaWYgKHBvc2l0aW9uIDwgMCB8fCBwb3NpdGlvbiA+PSBsZW5ndGgpIHtcbiAgICAgIHJldHVybiBVTkRFRklORURfUkVGRVJFTkNFO1xuICAgIH1cblxuICAgIHJldHVybiBjaGVjayhzdGFjay5nZXQocG9zaXRpb24sIGJhc2UpLCBDaGVja1JlZmVyZW5jZSk7XG4gIH1cblxuICBjYXB0dXJlKCk6IENhcHR1cmVkUG9zaXRpb25hbEFyZ3VtZW50cyB7XG4gICAgcmV0dXJuIHRoaXMucmVmZXJlbmNlcyBhcyBDYXB0dXJlZFBvc2l0aW9uYWxBcmd1bWVudHM7XG4gIH1cblxuICBwcmVwZW5kKG90aGVyOiBSZWZlcmVuY2VbXSkge1xuICAgIGxldCBhZGRpdGlvbnMgPSBvdGhlci5sZW5ndGg7XG5cbiAgICBpZiAoYWRkaXRpb25zID4gMCkge1xuICAgICAgbGV0IHsgYmFzZSwgbGVuZ3RoLCBzdGFjayB9ID0gdGhpcztcblxuICAgICAgdGhpcy5iYXNlID0gYmFzZSA9IGJhc2UgLSBhZGRpdGlvbnM7XG4gICAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aCArIGFkZGl0aW9ucztcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhZGRpdGlvbnM7IGkrKykge1xuICAgICAgICBzdGFjay5zZXQob3RoZXJbaV0sIGksIGJhc2UpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl9yZWZlcmVuY2VzID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldCByZWZlcmVuY2VzKCk6IHJlYWRvbmx5IFJlZmVyZW5jZVtdIHtcbiAgICBsZXQgcmVmZXJlbmNlcyA9IHRoaXMuX3JlZmVyZW5jZXM7XG5cbiAgICBpZiAoIXJlZmVyZW5jZXMpIHtcbiAgICAgIGxldCB7IHN0YWNrLCBiYXNlLCBsZW5ndGggfSA9IHRoaXM7XG4gICAgICByZWZlcmVuY2VzID0gdGhpcy5fcmVmZXJlbmNlcyA9IHN0YWNrLnNsaWNlPFJlZmVyZW5jZT4oYmFzZSwgYmFzZSArIGxlbmd0aCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlZmVyZW5jZXM7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIE5hbWVkQXJndW1lbnRzSW1wbCBpbXBsZW1lbnRzIE5hbWVkQXJndW1lbnRzIHtcbiAgcHVibGljIGJhc2UgPSAwO1xuICBwdWJsaWMgbGVuZ3RoID0gMDtcblxuICBwcml2YXRlIHN0YWNrITogRXZhbHVhdGlvblN0YWNrO1xuXG4gIHByaXZhdGUgX3JlZmVyZW5jZXM6IE9wdGlvbjxyZWFkb25seSBSZWZlcmVuY2VbXT4gPSBudWxsO1xuXG4gIHByaXZhdGUgX25hbWVzOiBPcHRpb248cmVhZG9ubHkgc3RyaW5nW10+ID0gRU1QVFlfU1RSSU5HX0FSUkFZO1xuICBwcml2YXRlIF9hdE5hbWVzOiBPcHRpb248cmVhZG9ubHkgc3RyaW5nW10+ID0gRU1QVFlfU1RSSU5HX0FSUkFZO1xuXG4gIGVtcHR5KHN0YWNrOiBFdmFsdWF0aW9uU3RhY2ssIGJhc2U6IG51bWJlcikge1xuICAgIHRoaXMuc3RhY2sgPSBzdGFjaztcbiAgICB0aGlzLmJhc2UgPSBiYXNlO1xuICAgIHRoaXMubGVuZ3RoID0gMDtcblxuICAgIHRoaXMuX3JlZmVyZW5jZXMgPSBFTVBUWV9SRUZFUkVOQ0VTO1xuICAgIHRoaXMuX25hbWVzID0gRU1QVFlfU1RSSU5HX0FSUkFZO1xuICAgIHRoaXMuX2F0TmFtZXMgPSBFTVBUWV9TVFJJTkdfQVJSQVk7XG4gIH1cblxuICBzZXR1cChcbiAgICBzdGFjazogRXZhbHVhdGlvblN0YWNrLFxuICAgIGJhc2U6IG51bWJlcixcbiAgICBsZW5ndGg6IG51bWJlcixcbiAgICBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgYXROYW1lczogYm9vbGVhblxuICApIHtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5iYXNlID0gYmFzZTtcbiAgICB0aGlzLmxlbmd0aCA9IGxlbmd0aDtcblxuICAgIGlmIChsZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuX3JlZmVyZW5jZXMgPSBFTVBUWV9SRUZFUkVOQ0VTO1xuICAgICAgdGhpcy5fbmFtZXMgPSBFTVBUWV9TVFJJTkdfQVJSQVk7XG4gICAgICB0aGlzLl9hdE5hbWVzID0gRU1QVFlfU1RSSU5HX0FSUkFZO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9yZWZlcmVuY2VzID0gbnVsbDtcblxuICAgICAgaWYgKGF0TmFtZXMpIHtcbiAgICAgICAgdGhpcy5fbmFtZXMgPSBudWxsO1xuICAgICAgICB0aGlzLl9hdE5hbWVzID0gbmFtZXM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9uYW1lcyA9IG5hbWVzO1xuICAgICAgICB0aGlzLl9hdE5hbWVzID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZXQgbmFtZXMoKTogcmVhZG9ubHkgc3RyaW5nW10ge1xuICAgIGxldCBuYW1lcyA9IHRoaXMuX25hbWVzO1xuXG4gICAgaWYgKCFuYW1lcykge1xuICAgICAgbmFtZXMgPSB0aGlzLl9uYW1lcyA9IHRoaXMuX2F0TmFtZXMhLm1hcCh0aGlzLnRvU3ludGhldGljTmFtZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5hbWVzITtcbiAgfVxuXG4gIGdldCBhdE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICBsZXQgYXROYW1lcyA9IHRoaXMuX2F0TmFtZXM7XG5cbiAgICBpZiAoIWF0TmFtZXMpIHtcbiAgICAgIGF0TmFtZXMgPSB0aGlzLl9hdE5hbWVzID0gdGhpcy5fbmFtZXMhLm1hcCh0aGlzLnRvQXROYW1lKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXROYW1lcyE7XG4gIH1cblxuICBoYXMobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubmFtZXMuaW5kZXhPZihuYW1lKSAhPT0gLTE7XG4gIH1cblxuICBnZXQobmFtZTogc3RyaW5nLCBhdE5hbWVzID0gZmFsc2UpOiBSZWZlcmVuY2Uge1xuICAgIGxldCB7IGJhc2UsIHN0YWNrIH0gPSB0aGlzO1xuXG4gICAgbGV0IG5hbWVzID0gYXROYW1lcyA/IHRoaXMuYXROYW1lcyA6IHRoaXMubmFtZXM7XG5cbiAgICBsZXQgaWR4ID0gbmFtZXMuaW5kZXhPZihuYW1lKTtcblxuICAgIGlmIChpZHggPT09IC0xKSB7XG4gICAgICByZXR1cm4gVU5ERUZJTkVEX1JFRkVSRU5DRTtcbiAgICB9XG5cbiAgICBsZXQgcmVmID0gc3RhY2suZ2V0PFJlZmVyZW5jZT4oaWR4LCBiYXNlKTtcblxuICAgIGlmIChERUJVRykge1xuICAgICAgcmV0dXJuIGNyZWF0ZURlYnVnQWxpYXNSZWYhKGF0TmFtZXMgPyBuYW1lIDogYEAke25hbWV9YCwgcmVmKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlZjtcbiAgICB9XG4gIH1cblxuICBjYXB0dXJlKCk6IENhcHR1cmVkTmFtZWRBcmd1bWVudHMge1xuICAgIGxldCB7IG5hbWVzLCByZWZlcmVuY2VzIH0gPSB0aGlzO1xuICAgIGxldCBtYXAgPSBkaWN0PFJlZmVyZW5jZT4oKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmFtZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBuYW1lID0gbmFtZXNbaV07XG5cbiAgICAgIGlmIChERUJVRykge1xuICAgICAgICBtYXBbbmFtZV0gPSBjcmVhdGVEZWJ1Z0FsaWFzUmVmIShgQCR7bmFtZX1gLCByZWZlcmVuY2VzW2ldKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1hcFtuYW1lXSA9IHJlZmVyZW5jZXNbaV07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hcCBhcyBDYXB0dXJlZE5hbWVkQXJndW1lbnRzO1xuICB9XG5cbiAgbWVyZ2Uob3RoZXI6IFJlY29yZDxzdHJpbmcsIFJlZmVyZW5jZT4pIHtcbiAgICBsZXQga2V5cyA9IE9iamVjdC5rZXlzKG90aGVyKTtcblxuICAgIGlmIChrZXlzLmxlbmd0aCA+IDApIHtcbiAgICAgIGxldCB7IG5hbWVzLCBsZW5ndGgsIHN0YWNrIH0gPSB0aGlzO1xuICAgICAgbGV0IG5ld05hbWVzID0gbmFtZXMuc2xpY2UoKTtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBuYW1lID0ga2V5c1tpXTtcbiAgICAgICAgbGV0IGlkeCA9IG5ld05hbWVzLmluZGV4T2YobmFtZSk7XG5cbiAgICAgICAgaWYgKGlkeCA9PT0gLTEpIHtcbiAgICAgICAgICBsZW5ndGggPSBuZXdOYW1lcy5wdXNoKG5hbWUpO1xuICAgICAgICAgIHN0YWNrLnB1c2gob3RoZXJbbmFtZV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoO1xuICAgICAgdGhpcy5fcmVmZXJlbmNlcyA9IG51bGw7XG4gICAgICB0aGlzLl9uYW1lcyA9IG5ld05hbWVzO1xuICAgICAgdGhpcy5fYXROYW1lcyA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXQgcmVmZXJlbmNlcygpOiByZWFkb25seSBSZWZlcmVuY2VbXSB7XG4gICAgbGV0IHJlZmVyZW5jZXMgPSB0aGlzLl9yZWZlcmVuY2VzO1xuXG4gICAgaWYgKCFyZWZlcmVuY2VzKSB7XG4gICAgICBsZXQgeyBiYXNlLCBsZW5ndGgsIHN0YWNrIH0gPSB0aGlzO1xuICAgICAgcmVmZXJlbmNlcyA9IHRoaXMuX3JlZmVyZW5jZXMgPSBzdGFjay5zbGljZTxSZWZlcmVuY2U+KGJhc2UsIGJhc2UgKyBsZW5ndGgpO1xuICAgIH1cblxuICAgIHJldHVybiByZWZlcmVuY2VzO1xuICB9XG5cbiAgcHJpdmF0ZSB0b1N5bnRoZXRpY05hbWUodGhpczogdm9pZCwgbmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gbmFtZS5zbGljZSgxKTtcbiAgfVxuXG4gIHByaXZhdGUgdG9BdE5hbWUodGhpczogdm9pZCwgbmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYEAke25hbWV9YDtcbiAgfVxufVxuXG5mdW5jdGlvbiB0b1N5bWJvbE5hbWUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAmJHtuYW1lfWA7XG59XG5cbmNvbnN0IEVNUFRZX0JMT0NLX1ZBTFVFUyA9IGVtcHR5QXJyYXk8QmxvY2tWYWx1ZT4oKTtcblxuZXhwb3J0IGNsYXNzIEJsb2NrQXJndW1lbnRzSW1wbCBpbXBsZW1lbnRzIEJsb2NrQXJndW1lbnRzIHtcbiAgcHJpdmF0ZSBzdGFjayE6IEV2YWx1YXRpb25TdGFjaztcbiAgcHJpdmF0ZSBpbnRlcm5hbFZhbHVlczogT3B0aW9uPHJlYWRvbmx5IEJsb2NrVmFsdWVbXT4gPSBudWxsO1xuICBwcml2YXRlIF9zeW1ib2xOYW1lczogT3B0aW9uPHJlYWRvbmx5IHN0cmluZ1tdPiA9IG51bGw7XG5cbiAgcHVibGljIGludGVybmFsVGFnOiBPcHRpb248VGFnPiA9IG51bGw7XG4gIHB1YmxpYyBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10gPSBFTVBUWV9TVFJJTkdfQVJSQVk7XG5cbiAgcHVibGljIGxlbmd0aCA9IDA7XG4gIHB1YmxpYyBiYXNlID0gMDtcblxuICBlbXB0eShzdGFjazogRXZhbHVhdGlvblN0YWNrLCBiYXNlOiBudW1iZXIpIHtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5uYW1lcyA9IEVNUFRZX1NUUklOR19BUlJBWTtcbiAgICB0aGlzLmJhc2UgPSBiYXNlO1xuICAgIHRoaXMubGVuZ3RoID0gMDtcbiAgICB0aGlzLl9zeW1ib2xOYW1lcyA9IG51bGw7XG5cbiAgICB0aGlzLmludGVybmFsVGFnID0gQ09OU1RBTlRfVEFHO1xuICAgIHRoaXMuaW50ZXJuYWxWYWx1ZXMgPSBFTVBUWV9CTE9DS19WQUxVRVM7XG4gIH1cblxuICBzZXR1cChzdGFjazogRXZhbHVhdGlvblN0YWNrLCBiYXNlOiBudW1iZXIsIGxlbmd0aDogbnVtYmVyLCBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10pIHtcbiAgICB0aGlzLnN0YWNrID0gc3RhY2s7XG4gICAgdGhpcy5uYW1lcyA9IG5hbWVzO1xuICAgIHRoaXMuYmFzZSA9IGJhc2U7XG4gICAgdGhpcy5sZW5ndGggPSBsZW5ndGg7XG4gICAgdGhpcy5fc3ltYm9sTmFtZXMgPSBudWxsO1xuXG4gICAgaWYgKGxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5pbnRlcm5hbFRhZyA9IENPTlNUQU5UX1RBRztcbiAgICAgIHRoaXMuaW50ZXJuYWxWYWx1ZXMgPSBFTVBUWV9CTE9DS19WQUxVRVM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaW50ZXJuYWxUYWcgPSBudWxsO1xuICAgICAgdGhpcy5pbnRlcm5hbFZhbHVlcyA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHZhbHVlcygpOiByZWFkb25seSBCbG9ja1ZhbHVlW10ge1xuICAgIGxldCB2YWx1ZXMgPSB0aGlzLmludGVybmFsVmFsdWVzO1xuXG4gICAgaWYgKCF2YWx1ZXMpIHtcbiAgICAgIGxldCB7IGJhc2UsIGxlbmd0aCwgc3RhY2sgfSA9IHRoaXM7XG4gICAgICB2YWx1ZXMgPSB0aGlzLmludGVybmFsVmFsdWVzID0gc3RhY2suc2xpY2U8QmxvY2tWYWx1ZT4oYmFzZSwgYmFzZSArIGxlbmd0aCAqIDMpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZXM7XG4gIH1cblxuICBoYXMobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubmFtZXMhLmluZGV4T2YobmFtZSkgIT09IC0xO1xuICB9XG5cbiAgZ2V0KG5hbWU6IHN0cmluZyk6IE9wdGlvbjxTY29wZUJsb2NrPiB7XG4gICAgbGV0IGlkeCA9IHRoaXMubmFtZXMhLmluZGV4T2YobmFtZSk7XG5cbiAgICBpZiAoaWR4ID09PSAtMSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgbGV0IHsgYmFzZSwgc3RhY2sgfSA9IHRoaXM7XG5cbiAgICBsZXQgdGFibGUgPSBjaGVjayhzdGFjay5nZXQoaWR4ICogMywgYmFzZSksIENoZWNrT3B0aW9uKENoZWNrQmxvY2tTeW1ib2xUYWJsZSkpO1xuICAgIGxldCBzY29wZSA9IGNoZWNrKHN0YWNrLmdldChpZHggKiAzICsgMSwgYmFzZSksIENoZWNrT3B0aW9uKENoZWNrU2NvcGUpKTtcbiAgICBsZXQgaGFuZGxlID0gY2hlY2soXG4gICAgICBzdGFjay5nZXQoaWR4ICogMyArIDIsIGJhc2UpLFxuICAgICAgQ2hlY2tPcHRpb24oQ2hlY2tPcihDaGVja0hhbmRsZSwgQ2hlY2tDb21waWxhYmxlQmxvY2spKVxuICAgICk7XG5cbiAgICByZXR1cm4gaGFuZGxlID09PSBudWxsID8gbnVsbCA6IChbaGFuZGxlLCBzY29wZSEsIHRhYmxlIV0gYXMgU2NvcGVCbG9jayk7XG4gIH1cblxuICBjYXB0dXJlKCk6IENhcHR1cmVkQmxvY2tBcmd1bWVudHMge1xuICAgIHJldHVybiBuZXcgQ2FwdHVyZWRCbG9ja0FyZ3VtZW50c0ltcGwodGhpcy5uYW1lcywgdGhpcy52YWx1ZXMpO1xuICB9XG5cbiAgZ2V0IHN5bWJvbE5hbWVzKCk6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICBsZXQgc3ltYm9sTmFtZXMgPSB0aGlzLl9zeW1ib2xOYW1lcztcblxuICAgIGlmIChzeW1ib2xOYW1lcyA9PT0gbnVsbCkge1xuICAgICAgc3ltYm9sTmFtZXMgPSB0aGlzLl9zeW1ib2xOYW1lcyA9IHRoaXMubmFtZXMubWFwKHRvU3ltYm9sTmFtZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN5bWJvbE5hbWVzO1xuICB9XG59XG5cbmNsYXNzIENhcHR1cmVkQmxvY2tBcmd1bWVudHNJbXBsIGltcGxlbWVudHMgQ2FwdHVyZWRCbG9ja0FyZ3VtZW50cyB7XG4gIHB1YmxpYyBsZW5ndGg6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgbmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdLCBwdWJsaWMgdmFsdWVzOiByZWFkb25seSBPcHRpb248QmxvY2tWYWx1ZT5bXSkge1xuICAgIHRoaXMubGVuZ3RoID0gbmFtZXMubGVuZ3RoO1xuICB9XG5cbiAgaGFzKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm5hbWVzLmluZGV4T2YobmFtZSkgIT09IC0xO1xuICB9XG5cbiAgZ2V0KG5hbWU6IHN0cmluZyk6IE9wdGlvbjxTY29wZUJsb2NrPiB7XG4gICAgbGV0IGlkeCA9IHRoaXMubmFtZXMuaW5kZXhPZihuYW1lKTtcblxuICAgIGlmIChpZHggPT09IC0xKSByZXR1cm4gbnVsbDtcblxuICAgIHJldHVybiBbXG4gICAgICB0aGlzLnZhbHVlc1tpZHggKiAzICsgMl0gYXMgQ29tcGlsYWJsZUJsb2NrLFxuICAgICAgdGhpcy52YWx1ZXNbaWR4ICogMyArIDFdIGFzIFNjb3BlLFxuICAgICAgdGhpcy52YWx1ZXNbaWR4ICogM10gYXMgQmxvY2tTeW1ib2xUYWJsZSxcbiAgICBdO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDYXB0dXJlZEFyZ3MobmFtZWQ6IERpY3Q8UmVmZXJlbmNlPiwgcG9zaXRpb25hbDogUmVmZXJlbmNlW10pIHtcbiAgcmV0dXJuIHtcbiAgICBuYW1lZCxcbiAgICBwb3NpdGlvbmFsLFxuICB9IGFzIENhcHR1cmVkQXJndW1lbnRzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVpZnlOYW1lZChuYW1lZDogQ2FwdHVyZWROYW1lZEFyZ3VtZW50cykge1xuICBsZXQgcmVpZmllZCA9IGRpY3QoKTtcblxuICBmb3IgKGxldCBrZXkgaW4gbmFtZWQpIHtcbiAgICByZWlmaWVkW2tleV0gPSB2YWx1ZUZvclJlZihuYW1lZFtrZXldKTtcbiAgfVxuXG4gIHJldHVybiByZWlmaWVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVpZnlQb3NpdGlvbmFsKHBvc2l0aW9uYWw6IENhcHR1cmVkUG9zaXRpb25hbEFyZ3VtZW50cykge1xuICByZXR1cm4gcG9zaXRpb25hbC5tYXAodmFsdWVGb3JSZWYpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVpZnlBcmdzKGFyZ3M6IENhcHR1cmVkQXJndW1lbnRzKSB7XG4gIHJldHVybiB7XG4gICAgbmFtZWQ6IHJlaWZ5TmFtZWQoYXJncy5uYW1lZCksXG4gICAgcG9zaXRpb25hbDogcmVpZnlQb3NpdGlvbmFsKGFyZ3MucG9zaXRpb25hbCksXG4gIH07XG59XG5cbmV4cG9ydCBjb25zdCBFTVBUWV9OQU1FRCA9IE9iamVjdC5mcmVlemUoT2JqZWN0LmNyZWF0ZShudWxsKSkgYXMgQ2FwdHVyZWROYW1lZEFyZ3VtZW50cztcbmV4cG9ydCBjb25zdCBFTVBUWV9QT1NJVElPTkFMID0gRU1QVFlfUkVGRVJFTkNFUyBhcyBDYXB0dXJlZFBvc2l0aW9uYWxBcmd1bWVudHM7XG5leHBvcnQgY29uc3QgRU1QVFlfQVJHUyA9IGNyZWF0ZUNhcHR1cmVkQXJncyhFTVBUWV9OQU1FRCwgRU1QVFlfUE9TSVRJT05BTCk7XG4iXSwic291cmNlUm9vdCI6IiJ9