@neo-one/smart-contract-compiler
Version:
NEO•ONE TypeScript smart contract compiler.
351 lines (350 loc) • 61.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const ts_utils_1 = require("@neo-one/ts-utils");
const typescript_1 = tslib_1.__importDefault(require("typescript"));
const DiagnosticCode_1 = require("../../DiagnosticCode");
const DiagnosticMessage_1 = require("../../DiagnosticMessage");
const builtins_1 = require("../builtins");
const constants_1 = require("../constants");
const NodeCompiler_1 = require("../NodeCompiler");
class ElementAccessExpressionCompiler extends NodeCompiler_1.NodeCompiler {
constructor() {
super(...arguments);
this.kind = typescript_1.default.SyntaxKind.ElementAccessExpression;
}
visitNode(sb, expr, optionsIn) {
const value = ts_utils_1.tsUtils.expression.getExpression(expr);
const valueType = sb.context.analysis.getType(value);
const prop = ts_utils_1.tsUtils.expression.getArgumentExpressionOrThrow(expr);
const propType = sb.context.analysis.getType(prop);
const handleBuiltin = (member, visited) => {
if (builtins_1.isBuiltinInstanceMemberValue(member)) {
member.emitValue(sb, expr, optionsIn, visited);
return;
}
if (builtins_1.isBuiltinMemberValue(member)) {
member.emitValue(sb, expr, optionsIn);
return;
}
if (optionsIn.setValue) {
sb.context.reportError(prop, DiagnosticCode_1.DiagnosticCode.InvalidBuiltinModify, DiagnosticMessage_1.DiagnosticMessage.CannotModifyBuiltin);
}
else {
sb.context.reportError(prop, DiagnosticCode_1.DiagnosticCode.InvalidBuiltinReference, DiagnosticMessage_1.DiagnosticMessage.CannotReferenceBuiltinProperty);
}
};
const builtinProp = sb.context.builtins.getMember(value, prop);
if (builtinProp !== undefined) {
handleBuiltin(builtinProp, false);
return;
}
const getValueCases = (name, useSymbol = false) => sb.context.builtins
.getMembers(name, builtins_1.isBuiltinInstanceMemberValue, () => true, useSymbol)
.map(([propName, builtin]) => ({
condition: () => {
sb.emitOp(prop, 'DUP');
sb.emitPushString(prop, propName);
sb.emitOp(prop, 'EQUAL');
},
whenTrue: () => {
sb.emitOp(expr, 'DROP');
handleBuiltin(builtin, true);
},
}));
const throwTypeError = (innerOptions) => {
sb.emitOp(expr, 'DROP');
sb.emitHelper(expr, innerOptions, sb.helpers.throwTypeError);
};
const throwInnerTypeError = (innerOptions) => {
sb.emitOp(expr, 'DROP');
throwTypeError(innerOptions);
};
const createHandleProp = (handleString, handleNumber, handleSymbol) => (innerOptions) => {
sb.visit(prop, innerOptions);
sb.emitHelper(prop, innerOptions, sb.helpers.forBuiltinType({
type: propType,
array: throwInnerTypeError,
arrayStorage: throwInnerTypeError,
boolean: throwInnerTypeError,
buffer: throwInnerTypeError,
null: throwInnerTypeError,
number: handleNumber,
object: throwInnerTypeError,
string: handleString,
symbol: handleSymbol,
undefined: throwInnerTypeError,
map: throwInnerTypeError,
mapStorage: throwInnerTypeError,
set: throwInnerTypeError,
setStorage: throwInnerTypeError,
error: throwInnerTypeError,
forwardValue: throwInnerTypeError,
iteratorResult: throwInnerTypeError,
iterable: throwInnerTypeError,
iterableIterator: throwInnerTypeError,
transaction: throwInnerTypeError,
output: throwInnerTypeError,
attribute: throwInnerTypeError,
input: throwInnerTypeError,
account: throwInnerTypeError,
asset: throwInnerTypeError,
contract: throwInnerTypeError,
header: throwInnerTypeError,
block: throwInnerTypeError,
}));
};
const createProcessBuiltin = (name) => {
const handleStringBase = (innerInnerOptions) => {
sb.emitHelper(expr, innerInnerOptions, sb.helpers.case(getValueCases(name, false), () => {
throwInnerTypeError(innerInnerOptions);
}));
};
const handleString = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapString);
handleStringBase(innerInnerOptions);
};
const handleNumber = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.toString({ type: propType, knownType: constants_1.Types.Number }));
handleStringBase(innerInnerOptions);
};
const handleSymbol = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapSymbol);
sb.emitHelper(expr, innerInnerOptions, sb.helpers.case(getValueCases(name, true), () => {
throwInnerTypeError(innerInnerOptions);
}));
};
return createHandleProp(handleString, handleNumber, handleSymbol);
};
const createProcessArray = () => {
const handleNumberBase = (innerInnerOptions) => {
if (optionsIn.pushValue && optionsIn.setValue) {
sb.emitPushInt(expr, 2);
sb.emitOp(expr, 'PICK');
sb.emitHelper(expr, innerInnerOptions, sb.helpers.setArrayIndex);
}
else if (optionsIn.pushValue) {
sb.emitHelper(expr, innerInnerOptions, sb.helpers.getArrayIndex);
}
else if (optionsIn.setValue) {
sb.emitOp(expr, 'ROT');
sb.emitHelper(expr, innerInnerOptions, sb.helpers.setArrayIndex);
}
else {
sb.emitOp(expr, 'DROP');
sb.emitOp(expr, 'DROP');
}
};
const handleString = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapString);
sb.emitHelper(expr, innerInnerOptions, sb.helpers.case(getValueCases('Array', false), () => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.wrapString);
sb.emitHelper(prop, innerInnerOptions, sb.helpers.toNumber({ type: propType, knownType: constants_1.Types.String }));
handleNumberBase(innerInnerOptions);
}));
};
const handleNumber = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapNumber);
handleNumberBase(innerInnerOptions);
};
const handleSymbol = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapSymbol);
sb.emitHelper(expr, innerInnerOptions, sb.helpers.case(getValueCases('Array', true), () => {
throwInnerTypeError(innerInnerOptions);
}));
};
return createHandleProp(handleString, handleNumber, handleSymbol);
};
const createProcessArrayStorage = () => {
const handleNumberBase = (innerInnerOptions) => {
if (optionsIn.pushValue && optionsIn.setValue) {
sb.emitPushInt(expr, 2);
sb.emitOp(expr, 'PICK');
sb.emitHelper(expr, innerInnerOptions, sb.helpers.setArrayStorage);
}
else if (optionsIn.pushValue) {
sb.emitHelper(expr, options, sb.helpers.wrapNumber);
sb.emitHelper(expr, innerInnerOptions, sb.helpers.getStructuredStorage({
type: constants_1.Types.ArrayStorage,
keyType: undefined,
knownKeyType: constants_1.Types.Number,
}));
}
else if (optionsIn.setValue) {
sb.emitOp(expr, 'ROT');
sb.emitHelper(expr, innerInnerOptions, sb.helpers.setArrayStorage);
}
else {
sb.emitOp(expr, 'DROP');
sb.emitOp(expr, 'DROP');
}
};
const handleString = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapString);
sb.emitHelper(expr, innerInnerOptions, sb.helpers.case(getValueCases('ArrayStorage', false), () => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.wrapString);
sb.emitHelper(prop, innerInnerOptions, sb.helpers.toNumber({ type: propType, knownType: constants_1.Types.String }));
handleNumberBase(innerInnerOptions);
}));
};
const handleNumber = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapNumber);
handleNumberBase(innerInnerOptions);
};
const handleSymbol = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapSymbol);
sb.emitHelper(expr, innerInnerOptions, sb.helpers.case(getValueCases('ArrayStorage', true), () => {
throwInnerTypeError(innerInnerOptions);
}));
};
return createHandleProp(handleString, handleNumber, handleSymbol);
};
const createProcessBuffer = () => {
const handleNumberBase = (innerInnerOptions) => {
if (optionsIn.pushValue) {
sb.emitHelper(expr, innerInnerOptions, sb.helpers.getBufferIndex);
}
else {
sb.emitOp(expr, 'DROP');
sb.emitOp(expr, 'DROP');
}
};
const handleString = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapString);
sb.emitHelper(expr, innerInnerOptions, sb.helpers.case(getValueCases('Buffer', false), () => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.wrapString);
sb.emitHelper(prop, innerInnerOptions, sb.helpers.toNumber({ type: propType, knownType: constants_1.Types.String }));
handleNumberBase(innerInnerOptions);
}));
};
const handleNumber = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapNumber);
handleNumberBase(innerInnerOptions);
};
const handleSymbol = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapSymbol);
sb.emitHelper(expr, innerInnerOptions, sb.helpers.case(getValueCases('Buffer', true), () => {
throwInnerTypeError(innerInnerOptions);
}));
};
return createHandleProp(handleString, handleNumber, handleSymbol);
};
const processObject = (innerOptions) => {
const handleStringBase = (innerInnerOptions) => {
if (optionsIn.pushValue && optionsIn.setValue) {
sb.emitOp(expr, 'OVER');
sb.emitOp(expr, 'OVER');
sb.emitPushInt(expr, 4);
sb.emitOp(expr, 'ROLL');
sb.emitHelper(expr, innerInnerOptions, sb.helpers.setPropertyObjectProperty);
sb.emitHelper(expr, innerInnerOptions, sb.helpers.getPropertyObjectProperty);
}
else if (optionsIn.pushValue) {
sb.emitHelper(expr, innerInnerOptions, sb.helpers.getPropertyObjectProperty);
}
else if (optionsIn.setValue) {
sb.emitOp(expr, 'ROT');
sb.emitHelper(expr, innerInnerOptions, sb.helpers.setPropertyObjectProperty);
}
};
const handleNumber = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.toString({ type: propType, knownType: constants_1.Types.Number }));
handleStringBase(innerInnerOptions);
};
const handleString = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapString);
handleStringBase(innerInnerOptions);
};
const handleSymbol = (innerInnerOptions) => {
sb.emitHelper(prop, innerInnerOptions, sb.helpers.unwrapSymbol);
if (optionsIn.pushValue && optionsIn.setValue) {
sb.emitOp(expr, 'OVER');
sb.emitOp(expr, 'OVER');
sb.emitPushInt(expr, 4);
sb.emitOp(expr, 'ROLL');
sb.emitHelper(expr, innerInnerOptions, sb.helpers.setSymbolObjectProperty);
sb.emitHelper(expr, innerInnerOptions, sb.helpers.getSymbolObjectProperty);
}
else if (optionsIn.pushValue) {
sb.emitHelper(expr, innerInnerOptions, sb.helpers.getSymbolObjectProperty);
}
else if (optionsIn.setValue) {
sb.emitOp(expr, 'ROT');
sb.emitHelper(expr, innerInnerOptions, sb.helpers.setSymbolObjectProperty);
}
};
sb.visit(prop, innerOptions);
if (!optionsIn.pushValue && !optionsIn.setValue) {
sb.emitOp(expr, 'DROP');
sb.emitOp(expr, 'DROP');
return;
}
sb.emitHelper(prop, innerOptions, sb.helpers.forBuiltinType({
type: propType,
array: throwInnerTypeError,
arrayStorage: throwInnerTypeError,
boolean: throwInnerTypeError,
buffer: throwInnerTypeError,
null: throwInnerTypeError,
number: handleNumber,
object: throwInnerTypeError,
string: handleString,
symbol: handleSymbol,
undefined: throwInnerTypeError,
map: throwInnerTypeError,
mapStorage: throwInnerTypeError,
set: throwInnerTypeError,
setStorage: throwInnerTypeError,
error: throwInnerTypeError,
forwardValue: throwInnerTypeError,
iteratorResult: throwInnerTypeError,
iterable: throwInnerTypeError,
iterableIterator: throwInnerTypeError,
transaction: throwInnerTypeError,
output: throwInnerTypeError,
attribute: throwInnerTypeError,
input: throwInnerTypeError,
account: throwInnerTypeError,
asset: throwInnerTypeError,
contract: throwInnerTypeError,
header: throwInnerTypeError,
block: throwInnerTypeError,
}));
};
const options = sb.pushValueOptions(sb.noSetValueOptions(optionsIn));
sb.visit(value, options);
sb.emitHelper(value, options, sb.helpers.forBuiltinType({
type: valueType,
array: createProcessArray(),
arrayStorage: createProcessArrayStorage(),
boolean: createProcessBuiltin('Boolean'),
buffer: createProcessBuffer(),
null: throwTypeError,
number: createProcessBuiltin('Number'),
object: processObject,
string: createProcessBuiltin('String'),
symbol: createProcessBuiltin('Symbol'),
undefined: throwTypeError,
map: createProcessBuiltin('Map'),
mapStorage: createProcessBuiltin('MapStorage'),
set: createProcessBuiltin('Set'),
setStorage: createProcessBuiltin('SetStorage'),
error: createProcessBuiltin('Error'),
forwardValue: createProcessBuiltin('ForwardValue'),
iteratorResult: createProcessBuiltin('IteratorResult'),
iterable: createProcessBuiltin('Iterable'),
iterableIterator: createProcessBuiltin('IterableIterator'),
transaction: createProcessBuiltin('TransactionBase'),
output: createProcessBuiltin('Output'),
attribute: createProcessBuiltin('AttributeBase'),
input: createProcessBuiltin('Input'),
account: createProcessBuiltin('Account'),
asset: createProcessBuiltin('Asset'),
contract: createProcessBuiltin('Contract'),
header: createProcessBuiltin('Header'),
block: createProcessBuiltin('Block'),
}));
}
}
exports.ElementAccessExpressionCompiler = ElementAccessExpressionCompiler;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkVsZW1lbnRBY2Nlc3NFeHByZXNzaW9uQ29tcGlsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0RBQTRDO0FBQzVDLG9FQUE0QjtBQUM1Qix5REFBc0Q7QUFDdEQsK0RBQTREO0FBQzVELDBDQUEwRjtBQUMxRiw0Q0FBcUM7QUFDckMsa0RBQStDO0FBSS9DLE1BQWEsK0JBQWdDLFNBQVEsMkJBQXdDO0lBQTdGOztRQUNrQixTQUFJLEdBQUcsb0JBQUUsQ0FBQyxVQUFVLENBQUMsdUJBQXVCLENBQUM7SUF1ZS9ELENBQUM7SUFyZVEsU0FBUyxDQUFDLEVBQWlCLEVBQUUsSUFBZ0MsRUFBRSxTQUF1QjtRQUMzRixNQUFNLEtBQUssR0FBRyxrQkFBTyxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckQsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JELE1BQU0sSUFBSSxHQUFHLGtCQUFPLENBQUMsVUFBVSxDQUFDLDRCQUE0QixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25FLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVuRCxNQUFNLGFBQWEsR0FBRyxDQUFDLE1BQWUsRUFBRSxPQUFnQixFQUFFLEVBQUU7WUFDMUQsSUFBSSx1Q0FBNEIsQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDeEMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFFL0MsT0FBTzthQUNSO1lBRUQsSUFBSSwrQkFBb0IsQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDaEMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUV0QyxPQUFPO2FB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QUFVLEVBQUUsb0JBQW9CLENBQUMsWUFBWSxDQUFDO1lBQzlDLEdBQUcsRUFBRSxvQkFBb0IsQ0FBQyxLQUFLLENBQUM7WUFDaEMsVUFBVSxFQUFFLG9CQUFvQixDQUFDLFlBQVksQ0FBQztZQUM5QyxLQUFLLEVBQUUsb0JBQW9CLENBQUMsT0FBTyxDQUFDO1lBQ3BDLFlBQVksRUFBRSxvQkFBb0IsQ0FBQyxjQUFjLENBQUM7WUFDbEQsY0FBYyxFQUFFLG9CQUFvQixDQUFDLGdCQUFnQixDQUFDO1lBQ3RELFFBQVEsRUFBRSxvQkFBb0IsQ0FBQyxVQUFVLENBQUM7WUFDMUMsZ0JBQWdCLEVBQUUsb0JBQW9CLENBQUMsa0JBQWtCLENBQUM7WUFDMUQsV0FBVyxFQUFFLG9CQUFvQixDQUFDLGlCQUFpQixDQUFDO1lBQ3BELE1BQU0sRUFBRSxvQkFBb0IsQ0FBQyxRQUFRLENBQUM7WUFDdEMsU0FBUyxFQUFFLG9CQUFvQixDQUFDLGVBQWUsQ0FBQztZQUNoRCxLQUFLLEVBQUUsb0JBQW9CLENBQUMsT0FBTyxDQUFDO1lBQ3BDLE9BQU8sRUFBRSxvQkFBb0IsQ0FBQyxTQUFTLENBQUM7WUFDeEMsS0FBSyxFQUFFLG9CQUFvQixDQUFDLE9BQU8sQ0FBQztZQUNwQyxRQUFRLEVBQUUsb0JBQW9CLENBQUMsVUFBVSxDQUFDO1lBQzFDLE1BQU0sRUFBRSxvQkFBb0IsQ0FBQyxRQUFRLENBQUM7WUFDdEMsS0FBSyxFQUFFLG9CQUFvQixDQUFDLE9BQU8sQ0FBQztTQUNyQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQXhlRCwwRUF3ZUMiLCJmaWxlIjoibmVvLW9uZS1zbWFydC1jb250cmFjdC1jb21waWxlci9zcmMvY29tcGlsZS9leHByZXNzaW9uL0VsZW1lbnRBY2Nlc3NFeHByZXNzaW9uQ29tcGlsZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0c1V0aWxzIH0gZnJvbSAnQG5lby1vbmUvdHMtdXRpbHMnO1xuaW1wb3J0IHRzIGZyb20gJ3R5cGVzY3JpcHQnO1xuaW1wb3J0IHsgRGlhZ25vc3RpY0NvZGUgfSBmcm9tICcuLi8uLi9EaWFnbm9zdGljQ29kZSc7XG5pbXBvcnQgeyBEaWFnbm9zdGljTWVzc2FnZSB9IGZyb20gJy4uLy4uL0RpYWdub3N0aWNNZXNzYWdlJztcbmltcG9ydCB7IEJ1aWx0aW4sIGlzQnVpbHRpbkluc3RhbmNlTWVtYmVyVmFsdWUsIGlzQnVpbHRpbk1lbWJlclZhbHVlIH0gZnJvbSAnLi4vYnVpbHRpbnMnO1xuaW1wb3J0IHsgVHlwZXMgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgTm9kZUNvbXBpbGVyIH0gZnJvbSAnLi4vTm9kZUNvbXBpbGVyJztcbmltcG9ydCB7IFNjcmlwdEJ1aWxkZXIgfSBmcm9tICcuLi9zYic7XG5pbXBvcnQgeyBWaXNpdE9wdGlvbnMgfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBFbGVtZW50QWNjZXNzRXhwcmVzc2lvbkNvbXBpbGVyIGV4dGVuZHMgTm9kZUNvbXBpbGVyPHRzLkVsZW1lbnRBY2Nlc3NFeHByZXNzaW9uPiB7XG4gIHB1YmxpYyByZWFkb25seSBraW5kID0gdHMuU3ludGF4S2luZC5FbGVtZW50QWNjZXNzRXhwcmVzc2lvbjtcblxuICBwdWJsaWMgdmlzaXROb2RlKHNiOiBTY3JpcHRCdWlsZGVyLCBleHByOiB0cy5FbGVtZW50QWNjZXNzRXhwcmVzc2lvbiwgb3B0aW9uc0luOiBWaXNpdE9wdGlvbnMpOiB2b2lkIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRzVXRpbHMuZXhwcmVzc2lvbi5nZXRFeHByZXNzaW9uKGV4cHIpO1xuICAgIGNvbnN0IHZhbHVlVHlwZSA9IHNiLmNvbnRleHQuYW5hbHlzaXMuZ2V0VHlwZSh2YWx1ZSk7XG4gICAgY29uc3QgcHJvcCA9IHRzVXRpbHMuZXhwcmVzc2lvbi5nZXRBcmd1bWVudEV4cHJlc3Npb25PclRocm93KGV4cHIpO1xuICAgIGNvbnN0IHByb3BUeXBlID0gc2IuY29udGV4dC5hbmFseXNpcy5nZXRUeXBlKHByb3ApO1xuXG4gICAgY29uc3QgaGFuZGxlQnVpbHRpbiA9IChtZW1iZXI6IEJ1aWx0aW4sIHZpc2l0ZWQ6IGJvb2xlYW4pID0+IHtcbiAgICAgIGlmIChpc0J1aWx0aW5JbnN0YW5jZU1lbWJlclZhbHVlKG1lbWJlcikpIHtcbiAgICAgICAgbWVtYmVyLmVtaXRWYWx1ZShzYiwgZXhwciwgb3B0aW9uc0luLCB2aXNpdGVkKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChpc0J1aWx0aW5NZW1iZXJWYWx1ZShtZW1iZXIpKSB7XG4gICAgICAgIG1lbWJlci5lbWl0VmFsdWUoc2IsIGV4cHIsIG9wdGlvbnNJbik7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9uc0luLnNldFZhbHVlKSB7XG4gICAgICAgIHNiLmNvbnRleHQucmVwb3J0RXJyb3IocHJvcCwgRGlhZ25vc3RpY0NvZGUuSW52YWxpZEJ1aWx0aW5Nb2RpZnksIERpYWdub3N0aWNNZXNzYWdlLkNhbm5vdE1vZGlmeUJ1aWx0aW4pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2IuY29udGV4dC5yZXBvcnRFcnJvcihcbiAgICAgICAgICBwcm9wLFxuICAgICAgICAgIERpYWdub3N0aWNDb2RlLkludmFsaWRCdWlsdGluUmVmZXJlbmNlLFxuICAgICAgICAgIERpYWdub3N0aWNNZXNzYWdlLkNhbm5vdFJlZmVyZW5jZUJ1aWx0aW5Qcm9wZXJ0eSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgYnVpbHRpblByb3AgPSBzYi5jb250ZXh0LmJ1aWx0aW5zLmdldE1lbWJlcih2YWx1ZSwgcHJvcCk7XG4gICAgaWYgKGJ1aWx0aW5Qcm9wICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGhhbmRsZUJ1aWx0aW4oYnVpbHRpblByb3AsIGZhbHNlKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGdldFZhbHVlQ2FzZXMgPSAobmFtZTogc3RyaW5nLCB1c2VTeW1ib2wgPSBmYWxzZSkgPT5cbiAgICAgIHNiLmNvbnRleHQuYnVpbHRpbnNcbiAgICAgICAgLmdldE1lbWJlcnMobmFtZSwgaXNCdWlsdGluSW5zdGFuY2VNZW1iZXJWYWx1ZSwgKCkgPT4gdHJ1ZSwgdXNlU3ltYm9sKVxuICAgICAgICAubWFwKChbcHJvcE5hbWUsIGJ1aWx0aW5dKSA9PiAoe1xuICAgICAgICAgIGNvbmRpdGlvbjogKCkgPT4ge1xuICAgICAgICAgICAgLy8gW3N0cmluZywgc3RyaW5nLCBvYmplY3RWYWxdXG4gICAgICAgICAgICBzYi5lbWl0T3AocHJvcCwgJ0RVUCcpO1xuICAgICAgICAgICAgLy8gW3N0cmluZywgc3RyaW5nLCBzdHJpbmcsIG9iamVjdFZhbF1cbiAgICAgICAgICAgIHNiLmVtaXRQdXNoU3RyaW5nKHByb3AsIHByb3BOYW1lKTtcbiAgICAgICAgICAgIC8vIFtib29sZWFuLCBzdHJpbmcsIG9iamVjdFZhbF1cbiAgICAgICAgICAgIHNiLmVtaXRPcChwcm9wLCAnRVFVQUwnKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHdoZW5UcnVlOiAoKSA9PiB7XG4gICAgICAgICAgICAvLyBbb2JqZWN0VmFsXVxuICAgICAgICAgICAgc2IuZW1pdE9wKGV4cHIsICdEUk9QJyk7XG4gICAgICAgICAgICBoYW5kbGVCdWlsdGluKGJ1aWx0aW4sIHRydWUpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pKTtcblxuICAgIGNvbnN0IHRocm93VHlwZUVycm9yID0gKGlubmVyT3B0aW9uczogVmlzaXRPcHRpb25zKSA9PiB7XG4gICAgICAvLyBbXVxuICAgICAgc2IuZW1pdE9wKGV4cHIsICdEUk9QJyk7XG4gICAgICBzYi5lbWl0SGVscGVyKGV4cHIsIGlubmVyT3B0aW9ucywgc2IuaGVscGVycy50aHJvd1R5cGVFcnJvcik7XG4gICAgfTtcblxuICAgIGNvbnN0IHRocm93SW5uZXJUeXBlRXJyb3IgPSAoaW5uZXJPcHRpb25zOiBWaXNpdE9wdGlvbnMpID0+IHtcbiAgICAgIC8vIFtvYmplY3RWYWxdXG4gICAgICBzYi5lbWl0T3AoZXhwciwgJ0RST1AnKTtcbiAgICAgIHRocm93VHlwZUVycm9yKGlubmVyT3B0aW9ucyk7XG4gICAgfTtcblxuICAgIGNvbnN0IGNyZWF0ZUhhbmRsZVByb3AgPSAoXG4gICAgICBoYW5kbGVTdHJpbmc6IChvcHRpb25zOiBWaXNpdE9wdGlvbnMpID0+IHZvaWQsXG4gICAgICBoYW5kbGVOdW1iZXI6IChvcHRpb25zOiBWaXNpdE9wdGlvbnMpID0+IHZvaWQsXG4gICAgICBoYW5kbGVTeW1ib2w6IChvcHRpb25zOiBWaXNpdE9wdGlvbnMpID0+IHZvaWQsXG4gICAgKSA9PiAoaW5uZXJPcHRpb25zOiBWaXNpdE9wdGlvbnMpID0+IHtcbiAgICAgIC8vIFtwcm9wVmFsLCBvYmplY3RWYWxdXG4gICAgICBzYi52aXNpdChwcm9wLCBpbm5lck9wdGlvbnMpO1xuICAgICAgc2IuZW1pdEhlbHBlcihcbiAgICAgICAgcHJvcCxcbiAgICAgICAgaW5uZXJPcHRpb25zLFxuICAgICAgICBzYi5oZWxwZXJzLmZvckJ1aWx0aW5UeXBlKHtcbiAgICAgICAgICB0eXBlOiBwcm9wVHlwZSxcbiAgICAgICAgICBhcnJheTogdGhyb3dJbm5lclR5cGVFcnJvcixcbiAgICAgICAgICBhcnJheVN0b3JhZ2U6IHRocm93SW5uZXJUeXBlRXJyb3IsXG4gICAgICAgICAgYm9vbGVhbjogdGhyb3dJbm5lclR5cGVFcnJvcixcbiAgICAgICAgICBidWZmZXI6IHRocm93SW5uZXJUeXBlRXJyb3IsXG4gICAgICAgICAgbnVsbDogdGhyb3dJbm5lclR5cGVFcnJvcixcbiAgICAgICAgICBudW1iZXI6IGhhbmRsZU51bWJlcixcbiAgICAgICAgICBvYmplY3Q6IHRocm93SW5uZXJUeXBlRXJyb3IsXG4gICAgICAgICAgc3RyaW5nOiBoYW5kbGVTdHJpbmcsXG4gICAgICAgICAgc3ltYm9sOiBoYW5kbGVTeW1ib2wsXG4gICAgICAgICAgdW5kZWZpbmVkOiB0aHJvd0lubmVyVHlwZUVycm9yLFxuICAgICAgICAgIG1hcDogdGhyb3dJbm5lclR5cGVFcnJvcixcbiAgICAgICAgICBtYXBTdG9yYWdlOiB0aHJvd0lubmVyVHlwZUVycm9yLFxuICAgICAgICAgIHNldDogdGhyb3dJbm5lclR5cGVFcnJvcixcbiAgICAgICAgICBzZXRTdG9yYWdlOiB0aHJvd0lubmVyVHlwZUVycm9yLFxuICAgICAgICAgIGVycm9yOiB0aHJvd0lubmVyVHlwZUVycm9yLFxuICAgICAgICAgIGZvcndhcmRWYWx1ZTogdGhyb3dJbm5lclR5cGVFcnJvcixcbiAgICAgICAgICBpdGVyYXRvclJlc3VsdDogdGhyb3dJbm5lclR5cGVFcnJvcixcbiAgICAgICAgICBpdGVyYWJsZTogdGhyb3dJbm5lclR5cGVFcnJvcixcbiAgICAgICAgICBpdGVyYWJsZUl0ZXJhdG9yOiB0aHJvd0lubmVyVHlwZUVycm9yLFxuICAgICAgICAgIHRyYW5zYWN0aW9uOiB0aHJvd0lubmVyVHlwZUVycm9yLFxuICAgICAgICAgIG91dHB1dDogdGhyb3dJbm5lclR5cGVFcnJvcixcbiAgICAgICAgICBhdHRyaWJ1dGU6IHRocm93SW5uZXJUeXBlRXJyb3IsXG4gICAgICAgICAgaW5wdXQ6IHRocm93SW5uZXJUeXBlRXJyb3IsXG4gICAgICAgICAgYWNjb3VudDogdGhyb3dJbm5lclR5cGVFcnJvcixcbiAgICAgICAgICBhc3NldDogdGhyb3dJbm5lclR5cGVFcnJvcixcbiAgICAgICAgICBjb250cmFjdDogdGhyb3dJbm5lclR5cGVFcnJvcixcbiAgICAgICAgICBoZWFkZXI6IHRocm93SW5uZXJUeXBlRXJyb3IsXG4gICAgICAgICAgYmxvY2s6IHRocm93SW5uZXJUeXBlRXJyb3IsXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgY29uc3QgY3JlYXRlUHJvY2Vzc0J1aWx0aW4gPSAobmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBoYW5kbGVTdHJpbmdCYXNlID0gKGlubmVySW5uZXJPcHRpb25zOiBWaXNpdE9wdGlvbnMpID0+IHtcbiAgICAgICAgc2IuZW1pdEhlbHBlcihcbiAgICAgICAgICBleHByLFxuICAgICAgICAgIGlubmVySW5uZXJPcHRpb25zLFxuICAgICAgICAgIHNiLmhlbHBlcnMuY2FzZShnZXRWYWx1ZUNhc2VzKG5hbWUsIGZhbHNlKSwgKCkgPT4ge1xuICAgICAgICAgICAgdGhyb3dJbm5lclR5cGVFcnJvcihpbm5lcklubmVyT3B0aW9ucyk7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBoYW5kbGVTdHJpbmcgPSAoaW5uZXJJbm5lck9wdGlvbnM6IFZpc2l0T3B0aW9ucykgPT4ge1xuICAgICAgICAvLyBbc3RyaW5nLCBvYmplY3RWYWxdXG4gICAgICAgIHNiLmVtaXRIZWxwZXIocHJvcCwgaW5uZXJJbm5lck9wdGlvbnMsIHNiLmhlbHBlcnMudW53cmFwU3RyaW5nKTtcbiAgICAgICAgaGFuZGxlU3RyaW5nQmFzZShpbm5lcklubmVyT3B0aW9ucyk7XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBoYW5kbGVOdW1iZXIgPSAoaW5uZXJJbm5lck9wdGlvbnM6IFZpc2l0T3B0aW9ucykgPT4ge1xuICAgICAgICAvLyBbc3RyaW5nLCBvYmplY3RWYWxdXG4gICAgICAgIHNiLmVtaXRIZWxwZXIocHJvcCwgaW5uZXJJbm5lck9wdGlvbnMsIHNiLmhlbHBlcnMudG9TdHJpbmcoeyB0eXBlOiBwcm9wVHlwZSwga25vd25UeXBlOiBUeXBlcy5OdW1iZXIgfSkpO1xuICAgICAgICBoYW5kbGVTdHJpbmdCYXNlKGlubmVySW5uZXJPcHRpb25zKTtcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGhhbmRsZVN5bWJvbCA9IChpbm5lcklubmVyT3B0aW9uczogVmlzaXRPcHRpb25zKSA9PiB7XG4gICAgICAgIC8vIFtzdHJpbmcsIG9iamVjdFZhbF1cbiAgICAgICAgc2IuZW1pdEhlbHBlcihwcm9wLCBpbm5lcklubmVyT3B0aW9ucywgc2IuaGVscGVycy51bndyYXBTeW1ib2wpO1xuICAgICAgICBzYi5lbWl0SGVscGVyKFxuICAgICAgICAgIGV4cHIsXG4gICAgICAgICAgaW5uZXJJbm5lck9wdGlvbnMsXG4gICAgICAgICAgc2IuaGVscGVycy5jYXNlKGdldFZhbHVlQ2FzZXMobmFtZSwgdHJ1ZSksICgpID0+IHtcbiAgICAgICAgICAgIHRocm93SW5uZXJUeXBlRXJyb3IoaW5uZXJJbm5lck9wdGlvbnMpO1xuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIGNyZWF0ZUhhbmRsZVByb3AoaGFuZGxlU3RyaW5nLCBoYW5kbGVOdW1iZXIsIGhhbmRsZVN5bWJvbCk7XG4gICAgfTtcblxuICAgIGNvbnN0IGNyZWF0ZVByb2Nlc3NBcnJheSA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGhhbmRsZU51bWJlckJhc2UgPSAoaW5uZXJJbm5lck9wdGlvbnM6IFZpc2l0T3B0aW9ucykgPT4ge1xuICAgICAgICBpZiAob3B0aW9uc0luLnB1c2hWYWx1ZSAmJiBvcHRpb25zSW4uc2V0VmFsdWUpIHtcbiAgICAgICAgICAvLyBbbnVtYmVyLCBudW1iZXIsIG9iamVjdFZhbCwgdmFsXVxuICAgICAgICAgIHNiLmVtaXRQdXNoSW50KGV4cHIsIDIpO1xuICAgICAgICAgIC8vIFt2YWwsIG51bWJlciwgb2JqZWN0VmFsLCB2YWxdXG4gICAgICAgICAgc2IuZW1pdE9wKGV4cHIsICdQSUNLJyk7XG4gICAgICAgICAgLy8gW3ZhbF1cbiAgICAgICAgICBzYi5lbWl0SGVscGVyKGV4cHIsIGlubmVySW5uZXJPcHRpb25zLCBzYi5oZWxwZXJzLnNldEFycmF5SW5kZXgpO1xuICAgICAgICB9IGVsc2UgaWYgKG9wdGlvbnNJbi5wdXNoVmFsdWUpIHtcbiAgICAgICAgICAvLyBbdmFsXVxuICAgICAgICAgIHNiLmVtaXRIZWxwZXIoZXhwciwgaW5uZXJJbm5lck9wdGlvbnMsIHNiLmhlbHBlcnMuZ2V0QXJyYXlJbmRleCk7XG4gICAgICAgIH0gZWxzZSBpZiAob3B0aW9uc0luLnNldFZhbHVlKSB7XG4gICAgICAgICAgLy8gW3ZhbCwgbnVtYmVyLCBvYmplY3RWYWxdXG4gICAgICAgICAgc2IuZW1pdE9wKGV4cHIsICdST1QnKTtcbiAgICAgICAgICAvLyBbXVxuICAgICAgICAgIHNiLmVtaXRIZWxwZXIoZXhwciwgaW5uZXJJbm5lck9wdGlvbnMsIHNiLmhlbHBlcnMuc2V0QXJyYXlJbmRleCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gW29iamVjdFZhbF1cbiAgICAgICAgICBzYi5lbWl0T3AoZXhwciwgJ0RST1AnKTtcbiAgICAgICAgICAvLyBbXVxuICAgICAgICAgIHNiLmVtaXRPcChleHByLCAnRFJPUCcpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBoYW5kbGVTdHJpbmcgPSAoaW5uZXJJbm5lck9wdGlvbnM6IFZpc2l0T3B0aW9ucykgPT4ge1xuICAgICAgICAvLyBbc3RyaW5nLCBvYmplY3RWYWxdXG4gICAgICAgIHNiLmVtaXRIZWxwZXIocHJvcCwgaW5uZXJJbm5lck9wdGlvbnMsIHNiLmhlbHBlcnMudW53cmFwU3RyaW5nKTtcbiAgICAgICAgc2IuZW1pdEhlbHBlcihcbiAgICAgICAgICBleHByLFxuICAgICAgICAgIGlubmVySW5uZXJPcHRpb25zLFxuICAgICAgICAgIHNiLmhlbHBlcnMuY2FzZShnZXRWYWx1ZUNhc2VzKCdBcnJheScsIGZhbHNlKSwgKCkgPT4ge1xuICAgICAgICAgICAgLy8gW3N0cmluZ1ZhbCwgb2JqZWN0VmFsXVxuICAgICAgICAgICAgc2IuZW1pdEhlbHBlcihwcm9wLCBpbm5lcklubmVyT3B0aW9ucywgc2IuaGVscGVycy53cmFwU3RyaW5nKTtcbiAgICAgICAgICAgIC8vIFtudW1iZXIsIG9iamVjdFZhbF1cbiAgICAgICAgICAgIHNiLmVtaXRIZWxwZXIocHJvcCwgaW5uZXJJbm5lck9wdGlvbnMsIHNiLmhlbHBlcnMudG9OdW1iZXIoeyB0eXBlOiBwcm9wVHlwZSwga25vd25UeXBlOiBUeXBlcy5TdHJpbmcgfSkpO1xuICAgICAgICAgICAgaGFuZGxlTnVtYmVyQmFzZShpbm5lcklubmVyT3B0aW9ucyk7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBoYW5kbGVOdW1iZXIgPSAoaW5uZXJJbm5lck9wdGlvbnM6IFZpc2l0T3B0aW9ucykgPT4ge1xuICAgICAgICAvLyBbbnVtYmVyLCBvYmplY3RWYWxdXG4gICAgICAgIHNiLmVtaXRIZWxwZXIocHJvcCwgaW5uZXJJbm5lck9wdGlvbnMsIHNiLmhlbHBlcnMudW53cmFwTnVtYmVyKTtcbiAgICAgICAgaGFuZGxlTnVtYmVyQmFzZShpbm5lcklubmVyT3B0aW9ucyk7XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBoYW5kbGVTeW1ib2wgPSAoaW5uZXJJbm5lck9wdGlvbnM6IFZpc2l0T3B0aW9ucykgPT4ge1xuICAgICAgICAvLyBbc3RyaW5nLCBvYmplY3RWYWxdXG4gICAgICAgIHNiLmVtaXRIZWxwZXIocHJvcCwgaW5uZXJJbm5lck9wdGlvbnMsIHNiLmhlbHBlcnMudW53cmFwU3ltYm9sKTtcbiAgICAgICAgc2IuZW1pdEhlbHBlcihcbiAgICAgICAgICBleHByLFxuICAgICAgICAgIGlubmVySW5uZXJPcHRpb25zLFxuICAgICAgICAgIHNiLmhlbHBlcnMuY2FzZShnZXRWYWx1ZUNhc2VzKCdBcnJheScsIHRydWUpLCAoKSA9PiB7XG4gICAgICAgICAgICB0aHJvd0lubmVyVHlwZUVycm9yKGlubmVySW5uZXJPcHRpb25zKTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBjcmVhdGVIYW5kbGVQcm9wKGhhbmRsZVN0cmluZywgaGFuZGxlTnVtYmVyLCBoYW5kbGVTeW1ib2wpO1xuICAgIH07XG5cbiAgICBjb25zdCBjcmVhdGVQcm9jZXNzQXJyYXlTdG9yYWdlID0gKCkgPT4ge1xuICAgICAgY29uc3QgaGFuZGxlTnVtYmVyQmFzZSA9IChpbm5lcklubmVyT3B0aW9uczogVmlzaXRPcHRpb25zKSA9PiB7XG4gICAgICAgIGlmIChvcHRpb25zSW4ucHVzaFZhbHVlICYmIG9wdGlvbnNJbi5zZXRWYWx1ZSkge1xuICAgICAgICAgIC8vIFtudW1iZXIsIG51bWJlciwgb2JqZWN0VmFsLCB2YWxdXG4gICAgICAgICAgc2IuZW1pdFB1c2hJbnQoZXhwciwgMik7XG4gICAgICAgICAgLy8gW3ZhbCwgbnVtYmVyLCBvYmplY3RWYWwsIHZhbF1cbiAgICAgICAgICBzYi5lbWl0T3AoZXhwciwgJ1BJQ0snKTtcbiAgICAgICAgICAvLyBbdmFsXVxuICAgICAgICAgIHNiLmVtaXRIZWxwZXIoZXhwciwgaW5uZXJJbm5lck9wdGlvbnMsIHNiLmhlbHBlcnMuc2V0QXJyYXlTdG9yYWdlKTtcbiAgICAgICAgfSBlbHNlIGlmIChvcHRpb25zSW4ucHVzaFZhbHVlKSB7XG4gICAgICAgICAgLy8gW251bWJlclZhbCwgdmFsXVxuICAgICAgICAgIHNiLmVtaXRIZWxwZXIoZXhwciwgb3B0aW9ucywgc2IuaGVscGVycy53cmFwTnVtYmVyKTtcbiAgICAgICAgICAvLyBbdmFsXVxuICAgICAgICAgIHNiLmVtaXRIZWxwZXIoXG4gICAgICAgICAgICBleHByLFxuICAgICAgICAgICAgaW5uZXJJbm5lck9wdGlvbnMsXG4gICAgICAgICAgICBzYi5oZWxwZXJzLmdldFN0cnVjdHVyZWRTdG9yYWdlKHtcbiAgICAgICAgICAgICAgdHlwZTogVHlwZXMuQXJyYXlTdG9yYWdlLFxuICAgICAgICAgICAgICBrZXlUeXBlOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGtub3duS2V5VHlwZTogVHlwZXMuTnVtYmVyLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChvcHRpb25zSW4uc2V0VmFsdWUpIHtcbiAgICAgICAgICAvLyBbdmFsLCBudW1iZXIsIG9iamVjdFZhbF1cbiAgICAgICAgICBzYi5lbWl0T3AoZXhwciwgJ1JPVCcpO1xuICAgICAgICAgIC8vIFtdXG4gICAgICAgICAgc2IuZW1pdEhlbHBlcihleHByLCBpbm5lcklubmVyT3B0aW9ucywgc2IuaGVscGVycy5zZXRBcnJheVN0b3JhZ2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFtvYmplY3RWYWxdXG4gICAgICAgICAgc2IuZW1pdE9wKGV4cHIsICdEUk9QJyk7XG4gICAgICAgICAgLy8gW11cbiAgICAgICAgICBzYi5lbWl0T3AoZXhwciwgJ0RST1AnKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgY29uc3QgaGFuZGxlU3RyaW5nID0gKGlubmVySW5uZXJPcHRpb25zOiBWaXNpdE9wdGlvbnMpID0+IHtcbiAgICAgICAgLy8gW3N0cmluZywgb2JqZWN0VmFsXVxuICAgICAgICBzYi5lbWl0SGVscGVyKHByb3AsIGlubmVySW5uZXJPcHRpb25zLCBzYi5oZWxwZXJzLnVud3JhcFN0cmluZyk7XG4gICAgICAgIHNiLmVtaXRIZWxwZXIoXG4gICAgICAgICAgZXhwcixcbiAgICAgICAgICBpbm5lcklubmVyT3B0aW9ucyxcbiAgICAgICAgICBzYi5oZWxwZXJzLmNhc2UoZ2V0VmFsdWVDYXNlcygnQXJyYXlTdG9yYWdlJywgZmFsc2UpLCAoKSA9PiB7XG4gICAgICAgICAgICAvLyBbc3RyaW5nVmFsLCBvYmplY3RWYWxdXG4gICAgICAgICAgICBzYi5lbWl0SGVscGVyKHByb3AsIGlubmVySW5uZXJPcHRpb25zLCBzYi5oZWxwZXJzLndyYXBTdHJpbmcpO1xuICAgICAgICAgICAgLy8gW251bWJlciwgb2JqZWN0VmFsXVxuICAgICAgICAgICAgc2IuZW1pdEhlbHBlcihwcm9wLCBpbm5lcklubmVyT3B0aW9ucywgc2IuaGVscGVycy50b051bWJlcih7IHR5cGU6IHByb3BUeXBlLCBrbm93blR5cGU6IFR5cGVzLlN0cmluZyB9KSk7XG4gICAgICAgICAgICBoYW5kbGVOdW1iZXJCYXNlKGlubmVySW5uZXJPcHRpb25zKTtcbiAgICAgICAgICB9