@neo-one/smart-contract-compiler
Version:
NEO•ONE TypeScript smart contract compiler.
477 lines (476 loc) • 75 kB
JavaScript
"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