UNPKG

@neo-one/smart-contract-compiler

Version:

NEO•ONE TypeScript smart contract compiler.

477 lines (476 loc) 75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const client_common_1 = require("@neo-one/client-common"); const ts_utils_1 = require("@neo-one/ts-utils"); const utils_1 = require("@neo-one/utils"); const bn_js_1 = require("bn.js"); const source_map_1 = require("source-map"); const DiagnosticCode_1 = require("../../DiagnosticCode"); const DiagnosticMessage_1 = require("../../DiagnosticMessage"); const declaration_1 = require("../declaration"); const expression_1 = require("../expression"); const file_1 = require("../file"); const pc_1 = require("../pc"); const statement_1 = require("../statement"); const JumpTable_1 = require("./JumpTable"); const resolveJumps_1 = require("./resolveJumps"); const compilers = [declaration_1.declarations, expression_1.expressions, file_1.files, statement_1.statements]; class BaseScriptBuilder { constructor(context, helpers, sourceFile, contractInfo, linked = {}, allHelpers = []) { this.context = context; this.helpers = helpers; this.sourceFile = sourceFile; this.contractInfo = contractInfo; this.linked = linked; this.allHelpers = allHelpers; this.jumpTable = new JumpTable_1.JumpTable(); this.mutableBytecode = []; this.mutablePC = 0; this.jumpTablePC = new pc_1.DeferredProgramCounter(); this.mutableProcessedByteCode = []; this.mutableCurrentTags = []; this.nodes = new Map(); this.mutableModuleMap = {}; this.mutableReverseModuleMap = {}; this.mutableExportMap = {}; this.mutableNextModuleIndex = 0; this.mutableCurrentModuleIndex = 0; this.mutableFeatures = { storage: false, dynamicInvoke: false }; this.compilers = compilers .reduce((acc, kindCompilers) => acc.concat(kindCompilers), []) .reduce((acc, kindCompilerClass) => { const kindCompiler = new kindCompilerClass(); if (acc[kindCompiler.kind] !== undefined) { throw new Error(`Found duplicate compiler for kind ${kindCompiler.kind}`); } acc[kindCompiler.kind] = kindCompiler; return acc; }, {}); } get scope() { if (this.mutableCurrentScope === undefined) { throw new Error('Scope has not been set'); } return this.mutableCurrentScope; } get moduleIndex() { return this.mutableCurrentModuleIndex; } process() { const sourceFile = this.sourceFile; const { bytecode } = this.capture(() => { const sourceFilePath = ts_utils_1.tsUtils.file.getFilePath(sourceFile); this.mutableModuleMap[sourceFilePath] = this.mutableNextModuleIndex; this.mutableReverseModuleMap[this.mutableNextModuleIndex] = sourceFilePath; this.mutableCurrentModuleIndex = this.mutableNextModuleIndex; this.mutableNextModuleIndex += 1; this.mutableCurrentScope = this.createScope(sourceFile, 0, undefined); this.nodes.set(sourceFile, 0); const options = {}; this.mutableCurrentScope.emit(this, sourceFile, options, (innerOptions) => { this.emitHelper(sourceFile, this.pushValueOptions(innerOptions), this.helpers.createGlobalObject); this.emitOp(sourceFile, 'DUP'); this.scope.setGlobal(this, sourceFile, this.pushValueOptions(innerOptions)); this.emitOp(sourceFile, 'DUP'); this.emitHelper(sourceFile, this.pushValueOptions(innerOptions), this.helpers.addEmptyModule); this.allHelpers.forEach((helper) => { if (helper.needsGlobal) { this.emitOp(sourceFile, 'DUP'); } helper.emitGlobal(this, sourceFile, innerOptions); }); this.emitOp(sourceFile, 'DROP'); this.visit(sourceFile, innerOptions); const contractInfo = this.contractInfo; if (contractInfo !== undefined) { this.emitHelper(contractInfo.smartContract, innerOptions, this.helpers.invokeSmartContract({ contractInfo, })); } this.scope.getGlobal(this, sourceFile, options); this.allHelpers.forEach((helper) => { if (helper.needsGlobalOut) { this.emitOp(sourceFile, 'DUP'); } helper.emitGlobalOut(this, sourceFile, innerOptions); }); this.emitOp(sourceFile, 'DROP'); }); }); this.mutableProcessedByteCode = bytecode; } getFinalResult(sourceMaps) { this.withProgramCounter((programCounter) => { this.emitJmp(this.sourceFile, 'JMP', programCounter.getLast()); this.jumpTablePC.setPC(programCounter.getCurrent()); this.jumpTable.emitTable(this, this.sourceFile); }); this.emitBytecode(this.mutableProcessedByteCode); const bytecode = resolveJumps_1.resolveJumps(this.mutableBytecode); let pc = 0; const sourceMapGenerator = new source_map_1.SourceMapGenerator(); const addedFiles = new Set(); const mutableTagToLength = {}; const buffers = bytecode.map(([node, tags, value], idx) => { let finalValue; if (value instanceof pc_1.Jump) { let jumpPCBuffer = Buffer.alloc(2, 0); const offsetPC = new bn_js_1.BN(value.pc.getPC()).sub(new bn_js_1.BN(pc)); const jumpPC = offsetPC.toTwos(16); try { if (jumpPC.fromTwos(16).toNumber() !== value.pc.getPC() - pc) { throw new Error(`Something went wrong, expected 2's complement of ${value.pc.getPC() - pc}, found: ${jumpPC .fromTwos(16) .toNumber()}`); } jumpPCBuffer = jumpPC.toArrayLike(Buffer, 'le', 2); } catch (_a) { this.context.reportError(node, DiagnosticCode_1.DiagnosticCode.SomethingWentWrong, DiagnosticMessage_1.DiagnosticMessage.CompilationFailedPleaseReport); } const byteCodeBuffer = client_common_1.ByteBuffer[client_common_1.Op[value.op]]; if (byteCodeBuffer === undefined) { throw new Error('Something went wrong, could not find bytecode buffer'); } finalValue = Buffer.concat([byteCodeBuffer, jumpPCBuffer]); } else if (value instanceof pc_1.Line) { const currentLine = new bn_js_1.BN(idx + 1); const byteCodeBuffer = client_common_1.ByteBuffer[client_common_1.Op.PUSHBYTES4]; finalValue = Buffer.concat([byteCodeBuffer, currentLine.toArrayLike(Buffer, 'le', 4)]); } else { finalValue = value; } const sourceFile = ts_utils_1.tsUtils.node.getSourceFile(node); const filePath = ts_utils_1.tsUtils.file.getFilePath(sourceFile); const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart()); sourceMapGenerator.addMapping({ generated: { line: idx + 1, column: 0 }, original: { line: line + 1, column: character }, source: filePath, }); if (!addedFiles.has(filePath)) { addedFiles.add(filePath); sourceMapGenerator.setSourceContent(filePath, node.getSourceFile().getFullText()); } const tag = tags[0]; if (tag !== undefined) { const currentLength = mutableTagToLength[tag]; mutableTagToLength[tag] = currentLength === undefined ? finalValue.length : currentLength + finalValue.length; } pc += finalValue.length; return finalValue; }); const sourceMap = (async () => { await Promise.all(Object.entries(sourceMaps).map(async ([filePath, srcMap]) => { await source_map_1.SourceMapConsumer.with(srcMap, undefined, async (consumer) => { sourceMapGenerator.applySourceMap(consumer, filePath); }); })); return sourceMapGenerator.toJSON(); })(); return { code: Buffer.concat(buffers), sourceMap, features: this.mutableFeatures, }; } visit(node, options) { const compiler = this.compilers[node.kind]; if (compiler === undefined) { this.context.reportUnsupported(node); } else { compiler.visitNode(this, node, options); } } withScope(node, options, func) { let index = this.nodes.get(node); if (index === undefined) { index = 0; } else { index += 1; } this.nodes.set(node, index); const currentScope = this.mutableCurrentScope; this.mutableCurrentScope = this.createScope(node, index, currentScope); this.mutableCurrentScope.emit(this, node, options, func); this.mutableCurrentScope = currentScope; } withProgramCounter(func) { const pc = new pc_1.ProgramCounterHelper(() => this.mutablePC); func(pc); pc.setLast(); } emitOp(node, code, buffer) { if (((code === 'APPCALL' || code === 'TAILCALL') && buffer !== undefined && buffer.equals(Buffer.alloc(20, 0))) || code === 'CALL_ED') { this.mutableFeatures = Object.assign({}, this.mutableFeatures, { dynamicInvoke: true }); } const bytecode = client_common_1.Op[code]; if (bytecode === undefined) { throw new client_common_1.UnknownOpError(code); } this.emitOpByte(node, bytecode, buffer); } emitPushInt(node, valueIn) { const value = new bn_js_1.BN(valueIn); if (value.eq(client_common_1.utils.NEGATIVE_ONE)) { this.emitOp(node, 'PUSHM1'); } else if (value.eq(client_common_1.utils.ZERO)) { this.emitPush(node, client_common_1.utils.toSignedBuffer(value)); } else if (value.gt(client_common_1.utils.ZERO) && value.lt(client_common_1.utils.SIXTEEN)) { this.emitOpByte(node, client_common_1.Op.PUSH1 - 1 + value.toNumber()); } else { this.emitPush(node, client_common_1.utils.toSignedBuffer(value)); } } emitPushBoolean(node, value) { this.emitOp(node, value ? 'PUSH1' : 'PUSH0'); } emitPushString(node, value) { this.emitPush(node, this.toBuffer(value)); } emitPushBuffer(node, value) { this.emitPush(node, value); } emitJmp(node, code, pc) { this.emitJump(node, new pc_1.Jmp(code, pc)); } emitHelper(node, options, helper) { const prevTags = this.mutableCurrentTags; this.mutableCurrentTags = [helper.constructor.name]; helper.emit(this, node, options); this.mutableCurrentTags = prevTags; } emitBytecode(bytecode) { const pc = this.mutablePC; bytecode.forEach(([node, tags, code]) => { if (code instanceof pc_1.Call) { this.emitJump(node, code, tags); } else if (code instanceof pc_1.Jmp) { this.emitJump(node, code.plus(pc), tags); } else { if (code instanceof pc_1.Jump) { throw new Error('Something went wrong.'); } if (code instanceof pc_1.Line) { this.emitLineRaw(node, code, tags); } else { this.emitRaw(node, code, tags); } } }); } emitCall(node) { this.emitJump(node, new pc_1.Call(this.jumpTablePC)); } emitSysCall(node, name) { if (name === 'Neo.Storage.Put' || name === 'Neo.Storage.Delete') { this.mutableFeatures = Object.assign({}, this.mutableFeatures, { storage: true }); } const sysCallBuffer = Buffer.allocUnsafe(4); sysCallBuffer.writeUInt32LE(client_common_1.toSysCallHash(client_common_1.assertSysCall(name)), 0); const writer = new client_common_1.BinaryWriter(); writer.writeVarBytesLE(sysCallBuffer); this.emitOp(node, 'SYSCALL', writer.toBuffer()); } emitLine(node) { this.emitLineRaw(node, new pc_1.Line()); } isCurrentSmartContract(node) { if (this.contractInfo === undefined) { return false; } const symbol = this.context.analysis.getSymbol(node); if (symbol === undefined) { return false; } const symbols = this.context.analysis.getSymbolAndAllInheritedSymbols(this.contractInfo.smartContract); if (symbols.some((smartContractSymbol) => smartContractSymbol === symbol)) { return true; } const typeSymbol = this.context.analysis.getTypeSymbol(node); return typeSymbol !== undefined && symbols.some((smartContractSymbol) => smartContractSymbol === typeSymbol); } loadModule(sourceFile) { const options = {}; let moduleIndex = this.mutableModuleMap[ts_utils_1.tsUtils.file.getFilePath(sourceFile)]; if (moduleIndex === undefined) { moduleIndex = this.mutableNextModuleIndex; this.mutableNextModuleIndex += 1; this.mutableModuleMap[ts_utils_1.tsUtils.file.getFilePath(sourceFile)] = moduleIndex; this.mutableReverseModuleMap[moduleIndex] = ts_utils_1.tsUtils.file.getFilePath(sourceFile); const currentScope = this.mutableCurrentScope; this.mutableCurrentScope = this.createScope(sourceFile, 0, undefined); const currentModuleIndex = this.mutableCurrentModuleIndex; this.mutableCurrentModuleIndex = moduleIndex; this.scope.getGlobal(this, sourceFile, this.pushValueOptions(options)); this.emitOp(sourceFile, 'DUP'); this.emitHelper(sourceFile, this.pushValueOptions(options), this.helpers.addEmptyModule); this.mutableCurrentScope.emit(this, sourceFile, options, (innerOptions) => { this.scope.setGlobal(this, sourceFile, options); this.visit(sourceFile, innerOptions); }); this.mutableCurrentScope = currentScope; this.mutableCurrentModuleIndex = currentModuleIndex; } this.scope.getGlobal(this, sourceFile, this.pushValueOptions(options)); this.emitHelper(sourceFile, this.pushValueOptions(options), this.helpers.getModule({ moduleIndex })); } capture(func) { const originalCapturedBytecode = this.mutableCapturedBytecode; this.mutableCapturedBytecode = []; const originalPC = this.mutablePC; this.mutablePC = 0; func(); const capturedBytecode = this.mutableCapturedBytecode; this.mutableCapturedBytecode = originalCapturedBytecode; const capturedLength = this.mutablePC; this.mutablePC = originalPC; return { length: capturedLength, bytecode: capturedBytecode }; } getLinkedScriptHash(node, filePath, smartContractClass) { const reportError = () => { this.context.reportError(node, DiagnosticCode_1.DiagnosticCode.InvalidLinkedSmartContract, DiagnosticMessage_1.DiagnosticMessage.InvalidLinkedSmartContractMissing, smartContractClass); }; const fileLinked = this.linked[filePath]; if (fileLinked === undefined) { reportError(); return undefined; } const address = fileLinked[smartContractClass]; if (address === undefined) { reportError(); return undefined; } return client_common_1.crypto.addressToScriptHash({ addressVersion: client_common_1.common.NEO_ADDRESS_VERSION, address, }); } pushValueOptions(options) { return Object.assign({}, options, { pushValue: true }); } noPushValueOptions(options) { return Object.assign({}, options, { pushValue: false }); } setValueOptions(options) { return Object.assign({}, options, { setValue: true }); } noSetValueOptions(options) { return Object.assign({}, options, { setValue: false }); } noValueOptions(options) { return Object.assign({}, options, { pushValue: false, setValue: false }); } breakPCOptions(options, pc) { return Object.assign({}, options, { breakPC: pc }); } continuePCOptions(options, pc) { return Object.assign({}, options, { continuePC: pc }); } catchPCOptions(options, pc) { return Object.assign({}, options, { catchPC: pc }); } noCatchPCOptions(options) { return Object.assign({}, options, { catchPC: undefined }); } finallyPCOptions(options, pc) { return Object.assign({}, options, { finallyPC: pc }); } handleSuperConstructOptions(options, handleSuperConstruct) { return Object.assign({}, options, { handleSuperConstruct }); } castOptions(options, cast) { return Object.assign({}, options, { cast }); } noCastOptions(options) { return Object.assign({}, options, { cast: undefined }); } superClassOptions(options, superClass) { return Object.assign({}, options, { superClass }); } noSuperClassOptions(options) { return Object.assign({}, options, { superClass: undefined }); } hasExport(sourceFile, name) { const exported = this.mutableExportMap[ts_utils_1.tsUtils.file.getFilePath(sourceFile)]; return exported !== undefined && exported.has(name); } addExport(name) { const filePath = utils_1.utils.nullthrows(this.mutableReverseModuleMap[this.mutableCurrentModuleIndex]); let fileExports = this.mutableExportMap[filePath]; if (fileExports === undefined) { this.mutableExportMap[filePath] = fileExports = new Set(); } fileExports.add(name); } toBuffer(value) { return Buffer.from(value, 'utf8'); } emitPush(node, value) { if (value.length <= client_common_1.Op.PUSHBYTES75) { this.emitOpByte(node, value.length, value); } else if (value.length < 0x100) { this.emitOp(node, 'PUSHDATA1', new client_common_1.ScriptBuilder() .emitUInt8(value.length) .emit(value) .build()); } else if (value.length < 0x10000) { this.emitOp(node, 'PUSHDATA2', new client_common_1.ScriptBuilder() .emitUInt16LE(value.length) .emit(value) .build()); } else if (value.length < 0x100000000) { this.emitOp(node, 'PUSHDATA4', new client_common_1.ScriptBuilder() .emitUInt32LE(value.length) .emit(value) .build()); } else { throw new Error('Value too large.'); } } emitOpByte(node, byteCode, buffer) { const byteCodeBuffer = client_common_1.ByteBuffer[byteCode]; let value = byteCodeBuffer; if (buffer !== undefined) { value = Buffer.concat([byteCodeBuffer, buffer]); } this.emitRaw(node, value); } emitRaw(node, value, tags = this.mutableCurrentTags) { this.push(node, tags, value); this.mutablePC += value.length; } emitJump(node, jump, tags = this.mutableCurrentTags) { this.push(node, tags, jump); this.mutablePC += 3; } emitLineRaw(node, line, tags = this.mutableCurrentTags) { this.push(node, tags, line); this.mutablePC += 5; } push(node, tags, value) { if (this.mutableCapturedBytecode !== undefined) { this.mutableCapturedBytecode.push([node, tags, value]); } else { this.mutableBytecode.push([node, tags, value]); } } } exports.BaseScriptBuilder = BaseScriptBuilder; //# sourceMappingURL=data:application/json;charset=utf8;base64,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QUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFVLENBQUMsQ0FBQztTQUNqRTthQUFNO1lBQ0wsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBVSxDQUFDLENBQUM7U0FDekQ7SUFDSCxDQUFDO0NBQ0Y7QUE3a0JELDhDQTZrQkMiLCJmaWxlIjoibmVvLW9uZS1zbWFydC1jb250cmFjdC1jb21waWxlci9zcmMvY29tcGlsZS9zYi9CYXNlU2NyaXB0QnVpbGRlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGFzc2VydFN5c0NhbGwsXG4gIEJpbmFyeVdyaXRlcixcbiAgQnl0ZUJ1ZmZlcixcbiAgQnl0ZUNvZGUsXG4gIGNvbW1vbixcbiAgY3J5cHRvLFxuICBPcCxcbiAgT3BDb2RlLFxuICBTY3JpcHRCdWlsZGVyIGFzIENsaWVudFNjcmlwdEJ1aWxkZXIsXG4gIFN5c0NhbGxOYW1lLFxuICB0b1N5c0NhbGxIYXNoLFxuICBVSW50MTYwLFxuICBVbmtub3duT3BFcnJvcixcbiAgdXRpbHMsXG59IGZyb20gJ0BuZW8tb25lL2NsaWVudC1jb21tb24nO1xuaW1wb3J0IHsgdHNVdGlscyB9IGZyb20gJ0BuZW8tb25lL3RzLXV0aWxzJztcbmltcG9ydCB7IHV0aWxzIGFzIGNvbW1vblV0aWxzIH0gZnJvbSAnQG5lby1vbmUvdXRpbHMnO1xuaW1wb3J0IHsgQk4gfSBmcm9tICdibi5qcyc7XG5pbXBvcnQgeyBSYXdTb3VyY2VNYXAsIFNvdXJjZU1hcENvbnN1bWVyLCBTb3VyY2VNYXBHZW5lcmF0b3IgfSBmcm9tICdzb3VyY2UtbWFwJztcbmltcG9ydCB0cyBmcm9tICd0eXBlc2NyaXB0JztcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICcuLi8uLi9Db250ZXh0JztcbmltcG9ydCB7IENvbnRyYWN0SW5mbyB9IGZyb20gJy4uLy4uL2NvbnRyYWN0JztcbmltcG9ydCB7IERpYWdub3N0aWNDb2RlIH0gZnJvbSAnLi4vLi4vRGlhZ25vc3RpY0NvZGUnO1xuaW1wb3J0IHsgRGlhZ25vc3RpY01lc3NhZ2UgfSBmcm9tICcuLi8uLi9EaWFnbm9zdGljTWVzc2FnZSc7XG5pbXBvcnQgeyBkZWNsYXJhdGlvbnMgfSBmcm9tICcuLi9kZWNsYXJhdGlvbic7XG5pbXBvcnQgeyBleHByZXNzaW9ucyB9IGZyb20gJy4uL2V4cHJlc3Npb24nO1xuaW1wb3J0IHsgZmlsZXMgfSBmcm9tICcuLi9maWxlJztcbmltcG9ydCB7IEhlbHBlciwgSGVscGVycyB9IGZyb20gJy4uL2hlbHBlcic7XG5pbXBvcnQgeyBOb2RlQ29tcGlsZXIgfSBmcm9tICcuLi9Ob2RlQ29tcGlsZXInO1xuaW1wb3J0IHsgQ2FsbCwgRGVmZXJyZWRQcm9ncmFtQ291bnRlciwgSm1wLCBKdW1wLCBMaW5lLCBQcm9ncmFtQ291bnRlciwgUHJvZ3JhbUNvdW50ZXJIZWxwZXIgfSBmcm9tICcuLi9wYyc7XG5pbXBvcnQgeyBOYW1lLCBTY29wZSB9IGZyb20gJy4uL3Njb3BlJztcbmltcG9ydCB7IHN0YXRlbWVudHMgfSBmcm9tICcuLi9zdGF0ZW1lbnQnO1xuaW1wb3J0IHsgRmVhdHVyZXMsIEhhbmRsZVN1cGVyQ29uc3RydWN0LCBMaW5rZWRDb250cmFjdHMsIFNjcmlwdEJ1aWxkZXJSZXN1bHQsIFZpc2l0T3B0aW9ucyB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IEp1bXBUYWJsZSB9IGZyb20gJy4vSnVtcFRhYmxlJztcbmltcG9ydCB7IHJlc29sdmVKdW1wcyB9IGZyb20gJy4vcmVzb2x2ZUp1bXBzJztcbmltcG9ydCB7IEJ5dGVjb2RlLCBDYXB0dXJlUmVzdWx0LCBTY3JpcHRCdWlsZGVyLCBTaW5nbGVCeXRlY29kZSwgU2luZ2xlQnl0ZWNvZGVWYWx1ZSwgVGFncyB9IGZyb20gJy4vU2NyaXB0QnVpbGRlcic7XG5cbmNvbnN0IGNvbXBpbGVyczogUmVhZG9ubHlBcnJheTxSZWFkb25seUFycmF5PG5ldyAoKSA9PiBOb2RlQ29tcGlsZXI+PiA9IFtkZWNsYXJhdGlvbnMsIGV4cHJlc3Npb25zLCBmaWxlcywgc3RhdGVtZW50c107XG5cbnR5cGUgQ29tcGlsZXJzID0geyBbSyBpbiBudW1iZXJdPzogTm9kZUNvbXBpbGVyIH07XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlU2NyaXB0QnVpbGRlcjxUU2NvcGUgZXh0ZW5kcyBTY29wZT4gaW1wbGVtZW50cyBTY3JpcHRCdWlsZGVyIHtcbiAgcHVibGljIHJlYWRvbmx5IGp1bXBUYWJsZTogSnVtcFRhYmxlID0gbmV3IEp1bXBUYWJsZSgpO1xuICBwcml2YXRlIG11dGFibGVDdXJyZW50U2NvcGU6IFRTY29wZSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBjb21waWxlcnM6IENvbXBpbGVycztcbiAgcHJpdmF0ZSByZWFkb25seSBtdXRhYmxlQnl0ZWNvZGU6IFNpbmdsZUJ5dGVjb2RlW10gPSBbXTtcbiAgcHJpdmF0ZSBtdXRhYmxlUEMgPSAwO1xuICBwcml2YXRlIHJlYWRvbmx5IGp1bXBUYWJsZVBDOiBEZWZlcnJlZFByb2dyYW1Db3VudGVyID0gbmV3IERlZmVycmVkUHJvZ3JhbUNvdW50ZXIoKTtcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIHJlYWRvbmx5LWFycmF5XG4gIHByaXZhdGUgbXV0YWJsZUNhcHR1cmVkQnl0ZWNvZGU6IFNpbmdsZUJ5dGVjb2RlW10gfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgbXV0YWJsZVByb2Nlc3NlZEJ5dGVDb2RlOiBSZWFkb25seUFycmF5PFNpbmdsZUJ5dGVjb2RlPiA9IFtdO1xuICBwcml2YXRlIG11dGFibGVDdXJyZW50VGFnczogVGFncyA9IFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IG5vZGVzOiBNYXA8dHMuTm9kZSwgbnVtYmVyPiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSByZWFkb25seSBtdXRhYmxlTW9kdWxlTWFwOiB7IFtLIGluIHN0cmluZ10/OiBudW1iZXIgfSA9IHt9O1xuICBwcml2YXRlIHJlYWRvbmx5IG11dGFibGVSZXZlcnNlTW9kdWxlTWFwOiB7IFtLIGluIG51bWJlcl0/OiBzdHJpbmcgfSA9IHt9O1xuICBwcml2YXRlIHJlYWRvbmx5IG11dGFibGVFeHBvcnRNYXA6IHsgW0sgaW4gc3RyaW5nXT86IFNldDxzdHJpbmc+IH0gPSB7fTtcbiAgcHJpdmF0ZSBtdXRhYmxlTmV4dE1vZHVsZUluZGV4ID0gMDtcbiAgcHJpdmF0ZSBtdXRhYmxlQ3VycmVudE1vZHVsZUluZGV4ID0gMDtcbiAgcHJpdmF0ZSBtdXRhYmxlRmVhdHVyZXM6IEZlYXR1cmVzID0geyBzdG9yYWdlOiBmYWxzZSwgZHluYW1pY0ludm9rZTogZmFsc2UgfTtcblxuICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGNvbnRleHQ6IENvbnRleHQsXG4gICAgcHVibGljIHJlYWRvbmx5IGhlbHBlcnM6IEhlbHBlcnMsXG4gICAgcHJpdmF0ZSByZWFkb25seSBzb3VyY2VGaWxlOiB0cy5Tb3VyY2VGaWxlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY29udHJhY3RJbmZvPzogQ29udHJhY3RJbmZvLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbGlua2VkOiBMaW5rZWRDb250cmFjdHMgPSB7fSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGFsbEhlbHBlcnM6IFJlYWRvbmx5QXJyYXk8SGVscGVyPiA9IFtdLFxuICApIHtcbiAgICB0aGlzLmNvbXBpbGVycyA9IGNvbXBpbGVyc1xuICAgICAgLnJlZHVjZTxSZWFkb25seUFycmF5PG5ldyAoKSA9PiBOb2RlQ29tcGlsZXI+PigoYWNjLCBraW5kQ29tcGlsZXJzKSA9PiBhY2MuY29uY2F0KGtpbmRDb21waWxlcnMpLCBbXSlcbiAgICAgIC5yZWR1Y2U8Q29tcGlsZXJzPigoYWNjLCBraW5kQ29tcGlsZXJDbGFzcykgPT4ge1xuICAgICAgICBjb25zdCBraW5kQ29tcGlsZXIgPSBuZXcga2luZENvbXBpbGVyQ2xhc3MoKTtcbiAgICAgICAgaWYgKGFjY1traW5kQ29tcGlsZXIua2luZF0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGb3VuZCBkdXBsaWNhdGUgY29tcGlsZXIgZm9yIGtpbmQgJHtraW5kQ29tcGlsZXIua2luZH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGFjY1traW5kQ29tcGlsZXIua2luZF0gPSBraW5kQ29tcGlsZXI7XG5cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sIHt9KTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgc2NvcGUoKTogVFNjb3BlIHtcbiAgICBpZiAodGhpcy5tdXRhYmxlQ3VycmVudFNjb3BlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Njb3BlIGhhcyBub3QgYmVlbiBzZXQnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5tdXRhYmxlQ3VycmVudFNjb3BlO1xuICB9XG5cbiAgcHVibGljIGdldCBtb2