UNPKG

@neo-one/smart-contract-compiler

Version:

NEO•ONE TypeScript smart contract compiler.

351 lines (350 loc) 61.5 kB
"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